From c55177e3e1e8a89d9d810d95ac18cb104865322c Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Mon, 2 Apr 2012 15:13:36 -0700 Subject: [PATCH 0001/6849] openvswitch: Enable retrieval of TCP flags from IPv6 traffic. We currently check that a packet is IPv4 and TCP before fetching the TCP flags. This enables fetching from IPv6 packets as well. Reported-by: Michael Mao Signed-off-by: Jesse Gross --- net/openvswitch/flow.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 2a11ec2383ee..c6e1dae8a5ee 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -182,7 +182,8 @@ void ovs_flow_used(struct sw_flow *flow, struct sk_buff *skb) { u8 tcp_flags = 0; - if (flow->key.eth.type == htons(ETH_P_IP) && + if ((flow->key.eth.type == htons(ETH_P_IP) || + flow->key.eth.type == htons(ETH_P_IPV6)) && flow->key.ip.proto == IPPROTO_TCP && likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) { u8 *tcp = (u8 *)tcp_hdr(skb); -- GitLab From 03fbf8b38792448370343f240131d9fde19d0387 Mon Sep 17 00:00:00 2001 From: Ansis Atteka Date: Mon, 9 Apr 2012 12:12:12 -0700 Subject: [PATCH 0002/6849] openvswitch: Do not send notification if ovs_vport_set_options() failed There is no need to send a notification if ovs_vport_set_options() failed and ovs_vport_cmd_set() did not change anything. Signed-off-by: Ansis Atteka Signed-off-by: Jesse Gross --- net/openvswitch/datapath.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e44e631ea952..4813d953d8f2 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1635,7 +1635,9 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) if (!err && a[OVS_VPORT_ATTR_OPTIONS]) err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]); - if (!err && a[OVS_VPORT_ATTR_UPCALL_PID]) + if (err) + goto exit_unlock; + if (a[OVS_VPORT_ATTR_UPCALL_PID]) vport->upcall_pid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, -- GitLab From caf2ee14bbc2c6bd73cf0decf576007e0239a482 Mon Sep 17 00:00:00 2001 From: Raju Subramanian Date: Thu, 3 May 2012 18:55:23 -0700 Subject: [PATCH 0003/6849] openvswitch: Replace Nicira Networks. Replaced all instances of Nicira Networks(, Inc) to Nicira, Inc. Signed-off-by: Raju Subramanian Signed-off-by: Ben Pfaff Signed-off-by: Jesse Gross --- net/openvswitch/actions.c | 2 +- net/openvswitch/datapath.c | 2 +- net/openvswitch/datapath.h | 2 +- net/openvswitch/dp_notify.c | 2 +- net/openvswitch/flow.c | 2 +- net/openvswitch/flow.h | 2 +- net/openvswitch/vport-internal_dev.c | 2 +- net/openvswitch/vport-internal_dev.h | 2 +- net/openvswitch/vport-netdev.c | 2 +- net/openvswitch/vport-netdev.h | 2 +- net/openvswitch/vport.c | 2 +- net/openvswitch/vport.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 48badffaafc1..f3f96badf5aa 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2012 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 4813d953d8f2..b512cb8cdc87 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2012 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index c73370cc1f02..c1105c147531 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c index 46736518c453..36dcee8fc84a 100644 --- a/net/openvswitch/dp_notify.c +++ b/net/openvswitch/dp_notify.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index c6e1dae8a5ee..1115dcf70362 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2011 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 2747dc2c4ac1..9b75617ca4e0 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2011 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index b6b1d7daa3cb..de509d347112 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/vport-internal_dev.h b/net/openvswitch/vport-internal_dev.h index 3454447c5f11..9a7d30ecc6a2 100644 --- a/net/openvswitch/vport-internal_dev.h +++ b/net/openvswitch/vport-internal_dev.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2011 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index c1068aed03d1..54a456d0b407 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h index fd9b008a0e6e..f7072a25c604 100644 --- a/net/openvswitch/vport-netdev.h +++ b/net/openvswitch/vport-netdev.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2011 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 6c066ba25dc7..6140336e79d7 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index 19609629dabd..aac680ca2b06 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public -- GitLab From 8ab5415d6c701a59dd6fc2bc93cf476ecc03ada5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 9 May 2012 22:14:51 +0300 Subject: [PATCH 0004/6849] ath6kl: Use correct max-scan-SSIDs limit The currently used firmware images support 16 SSIDs in the scan request (indexes 0..15), so update the host driver to use the same limit to allow some more SSIDs to be scanned per request. In addition, change the max-index to max-SSIDs to make it easier to understand the implementation and fix couple of off-by-one checks that could limit the maximum number of entries too strictly. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 ++++---- drivers/net/wireless/ath/ath6kl/wmi.c | 2 +- drivers/net/wireless/ath/ath6kl/wmi.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index b869a358ce43..a6bebc20fd18 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -888,7 +888,7 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar, { u8 i; - if (n_ssids > MAX_PROBED_SSID_INDEX) + if (n_ssids > MAX_PROBED_SSIDS) return -EINVAL; for (i = 0; i < n_ssids; i++) { @@ -900,7 +900,7 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar, } /* Make sure no old entries are left behind */ - for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) { + for (i = n_ssids; i < MAX_PROBED_SSIDS; i++) { ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, DISABLE_SSID_FLAG, 0, NULL); } @@ -3470,7 +3470,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) } /* max num of ssids that can be probed during scanning */ - wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; + wiphy->max_scan_ssids = MAX_PROBED_SSIDS; wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ switch (ar->hw.cap) { case WMI_11AN_CAP: @@ -3527,7 +3527,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->wowlan.pattern_min_len = 1; wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; - wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX; + wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS; ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | WIPHY_FLAG_HAVE_AP_SME | diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index ee8ec2394c2c..bdd3b2c55637 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1995,7 +1995,7 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, struct wmi_probed_ssid_cmd *cmd; int ret; - if (index > MAX_PROBED_SSID_INDEX) + if (index >= MAX_PROBED_SSIDS) return -EINVAL; if (ssid_len > sizeof(cmd->ssid)) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 9076bec3a2ba..3518550e3504 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -978,7 +978,7 @@ struct wmi_bss_filter_cmd { } __packed; /* WMI_SET_PROBED_SSID_CMDID */ -#define MAX_PROBED_SSID_INDEX 9 +#define MAX_PROBED_SSIDS 16 enum wmi_ssid_flag { /* disables entry */ @@ -992,7 +992,7 @@ enum wmi_ssid_flag { }; struct wmi_probed_ssid_cmd { - /* 0 to MAX_PROBED_SSID_INDEX */ + /* 0 to MAX_PROBED_SSIDS - 1 */ u8 entry_index; /* see, enum wmi_ssid_flg */ -- GitLab From e3c83c2db458f1e040c5b4bb19773c458e0240a8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 25 Apr 2012 13:05:24 +1000 Subject: [PATCH 0005/6849] ARM: OMAP2+: INTC: fix suspend abort, set IRQCHIP_SKIP_SET_WAKE Without an ->irq_set_wake() method in an irq_chip, calls to enable_irq_wake() will fail. This also causes these interrupts to not be able to abort suspend (via check_wakeup_irqs() in late suspend.) Currently, we don't implement ->irq_set_wake() for INTC interrupts because they default to be wakeup enabled by setting the GRPSEL bits in PM init. Even though there is no ->irq_set_wake(), we want enable_irq_wake() to succeed so these interrupts can abort suspend when necessary. To fix, set IRQCHIP_SKIP_SET_WAKE flag for all the INTC interrupts which avoids trying to check irq_chip->irq_set_wake() and failing when it doesn't exist. Longer term, we need to implement ->irq_set_wake() for the INTC which can manage the appropriate GRPSEL bits. Signed-off-by: NeilBrown [khilman@ti.com: rework changelog] Acked-by: Santosh Shilimkar Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/irq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 65f0d2571c9a..b0790a995dc9 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -148,6 +148,7 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) ct->chip.irq_ack = omap_mask_ack_irq; ct->chip.irq_mask = irq_gc_mask_disable_reg; ct->chip.irq_unmask = irq_gc_unmask_enable_reg; + ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE; ct->regs.ack = INTC_CONTROL; ct->regs.enable = INTC_MIR_CLEAR0; -- GitLab From 99b59df04899a048d1a3ed8bc2b1263779816868 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 27 Apr 2012 16:05:51 -0700 Subject: [PATCH 0006/6849] ARM: OMAP3: PM: fix shared PRCM interrupts: leave disabled at boot By default, request_irq() will auto-enable the requested IRQ. For PRCM interrupts, we may want to avoid that until the PM core code is fully ready to handle the interrupts. This is particularily true for IO pad interrupts on OMAP3, which are shared between the hwmod core and the PRM core. In order to avoid PRCM IO-chain interrupts until the PM core is ready to handle them, ready, set the IRQ_NOAUTOEN flag for the PRCM IO-chain interrupt, which means it will remain disabled after request_irq(). Then, explicitly enable the PRCM interrupts after the request_irq() in the PM core (but not in the hwmod core.) Special thanks to Tero Kristo for suggesting to isolate the fix to only the IO-chain interrupt on OMAP3 instead of all PRCM interrupts. Cc: Tero Kristo Acked-by: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 1 + arch/arm/mach-omap2/prm2xxx_3xxx.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 703bd1099259..4f44ee517f78 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -729,6 +729,7 @@ static int __init omap3_pm_init(void) ret = request_irq(omap_prcm_event_to_irq("io"), _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io", omap3_pm_init); + enable_irq(omap_prcm_event_to_irq("io")); if (ret) { pr_err("pm: Failed to request pm_io irq\n"); diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 9ce765407ad5..21cb74003a56 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "common.h" #include @@ -303,8 +304,15 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask) static int __init omap3xxx_prcm_init(void) { - if (cpu_is_omap34xx()) - return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); - return 0; + int ret = 0; + + if (cpu_is_omap34xx()) { + ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + if (!ret) + irq_set_status_flags(omap_prcm_event_to_irq("io"), + IRQ_NOAUTOEN); + } + + return ret; } subsys_initcall(omap3xxx_prcm_init); -- GitLab From 1ce029968718477149e7f1fb245a8e82c690cc4a Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 30 Apr 2012 16:57:09 -0700 Subject: [PATCH 0007/6849] arm: omap3: am35x: Don't mark missing features as present The Chip Identification register on the am35x family of SoCs has bits 12, 7:5, and 3:2 marked as reserved and are read as zeroes. Unfortunately, on other omap SoCs, a 0 bit means a feature is "Full Use" so the OMAP3_CHECK_FEATURE() macro called by omap3_check_features() will incorrectly interpret those zeroes to mean that a feature is present even though it isn't. To fix that, the feature bits that are incorrectly set (namely, OMAP3_HAS_IVA and OMAP3_HAS_ISP) need to be cleared after all of the calls to OMAP3_CHECK_FEATURE() in omap3_check_features() are made. Signed-off-by: Mark A. Greer [khilman@ti.com: use soc_is_am35xx() instead of cpu_is_am35xx()] Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/id.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index f611e3097157..38ae74f8e77a 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -246,6 +246,17 @@ void __init omap3xxx_check_features(void) omap_features |= OMAP3_HAS_SDRC; + /* + * am35x fixups: + * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as + * reserved and therefore return 0 when read. Unfortunately, + * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to + * mean that a feature is present even though it isn't so clear + * the incorrectly set feature bits. + */ + if (soc_is_am35xx()) + omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP); + /* * TODO: Get additional info (where applicable) * e.g. Size of L2 cache. -- GitLab From 1d8a0e963ac532e038d93ab0d30bbfad072f3bf8 Mon Sep 17 00:00:00 2001 From: Juan Gutierrez Date: Sun, 13 May 2012 15:33:04 +0300 Subject: [PATCH 0008/6849] ARM: OMAP: enable mailbox irq per instance The machine-specific omap2_mbox_startup is called only once to initialize the whole mbox module, and as a result, enabling the mbox irq at that point only works for the very first mailbox instance opened. Instead, this patch makes sure enable_irq() is called every time a new mbox instance is opened. In addition, we're now enabling the mbox's irq only after its notifier_block is registered, to avoid possible race of receiving an interrupt without invoking the user's notifier callback. Signed-off-by: Juan Gutierrez Signed-off-by: Suman Anna [ohad@wizery.com: slightly reworded the commit log] Signed-off-by: Ohad Ben-Cohen --- arch/arm/mach-omap2/mailbox.c | 2 -- arch/arm/plat-omap/mailbox.c | 13 +++++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 415a6f1cf419..f727034216a7 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -83,8 +83,6 @@ static int omap2_mbox_startup(struct omap_mbox *mbox) l = mbox_read_reg(MAILBOX_REVISION); pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); - omap2_mbox_enable_irq(mbox, IRQ_RX); - return 0; } diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ad32621aa52e..5e13c3884aa4 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -282,6 +282,8 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } mbox->rxq = mq; mq->mbox = mbox; + + omap_mbox_enable_irq(mbox, IRQ_RX); } mutex_unlock(&mbox_configured_lock); return 0; @@ -305,6 +307,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox) mutex_lock(&mbox_configured_lock); if (!--mbox->use_count) { + omap_mbox_disable_irq(mbox, IRQ_RX); free_irq(mbox->irq, mbox); tasklet_kill(&mbox->txq->tasklet); flush_work_sync(&mbox->rxq->work); @@ -338,13 +341,15 @@ struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb) if (!mbox) return ERR_PTR(-ENOENT); - ret = omap_mbox_startup(mbox); - if (ret) - return ERR_PTR(-ENODEV); - if (nb) blocking_notifier_chain_register(&mbox->notifier, nb); + ret = omap_mbox_startup(mbox); + if (ret) { + blocking_notifier_chain_unregister(&mbox->notifier, nb); + return ERR_PTR(-ENODEV); + } + return mbox; } EXPORT_SYMBOL(omap_mbox_get); -- GitLab From 778d02e9b3b7188ce37ff542e54ff5df723659e6 Mon Sep 17 00:00:00 2001 From: Juan Gutierrez Date: Sun, 13 May 2012 15:33:07 +0300 Subject: [PATCH 0009/6849] ARM: OMAP4: fix irq and clock name for dsp-iommu Irq and clock names were wrong for dsp iommu configuration for omap4. - Renamed tesla_ick to dsp_fck: This is required because the new naming convention introduced by: commit 0e43327 "OMAP4 clock: Fix clock names and align with hwmod names" - Renamed INT_44XX_DSP_MMU to OMAP44XX_IRQ_TESLA_MMU. Naming convention adopted since: commit e927f8d "omap4: Add auto-generated irq and dma headers" - dsp-iommu is enabled by default. Signed-off-by: Juan Gutierrez Signed-off-by: Ohad Ben-Cohen --- arch/arm/mach-omap2/omap-iommu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index ac49384d0285..1be8bcb52e93 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -73,19 +73,17 @@ static struct iommu_device omap4_devices[] = { .da_end = 0xFFFFF000, }, }, -#if defined(CONFIG_MPU_TESLA_IOMMU) { .base = OMAP4_MMU2_BASE, - .irq = INT_44XX_DSP_MMU, + .irq = OMAP44XX_IRQ_TESLA_MMU, .pdata = { .name = "tesla", .nr_tlb_entries = 32, - .clk_name = "tesla_ick", + .clk_name = "dsp_fck", .da_start = 0x0, .da_end = 0xFFFFF000, }, }, -#endif }; #define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices) static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES]; -- GitLab From 7548c09a475039b5e9179615ac4c1c58b930cdb5 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Wed, 4 Apr 2012 15:44:38 +0300 Subject: [PATCH 0010/6849] ARM: OMAP4: hwspinlocks_init() should be static Sparse found out that hwspinlocks_init() wasn't marked static, and it should've been. Signed-off-by: Ohad Ben-Cohen --- arch/arm/mach-omap2/hwspinlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c index 454dfce125ca..8763c8520dc2 100644 --- a/arch/arm/mach-omap2/hwspinlock.c +++ b/arch/arm/mach-omap2/hwspinlock.c @@ -28,7 +28,7 @@ static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = { .base_id = 0, }; -int __init hwspinlocks_init(void) +static int __init hwspinlocks_init(void) { int retval = 0; struct omap_hwmod *oh; -- GitLab From 6821d4f08dcdc7d8c21a3280f57f53a080f19840 Mon Sep 17 00:00:00 2001 From: Naveen Gangadharan Date: Fri, 11 May 2012 14:19:09 -0700 Subject: [PATCH 0011/6849] ath6kl: Add wow multicast firmware capability support Infrastructure to enable Multicast WOW support based on firmware capability added to the driver.This enables different customers or chips to control this feature based on firmware capability. kvalo: Firmware capability infrastructure for multicast wow feature, indetation fixes. Signed-off-by: Naveen Gangadharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 ++++++-- drivers/net/wireless/ath/ath6kl/core.h | 7 +++++++ drivers/net/wireless/ath/ath6kl/main.c | 5 ++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index a6bebc20fd18..22843a1b9f21 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2074,7 +2074,9 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) return -EINVAL; - if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) { + if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) && + test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, + ar->fw_capabilities)) { ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, false); if (ret) @@ -2209,7 +2211,9 @@ static int ath6kl_wow_resume(struct ath6kl *ar) ar->state = ATH6KL_STATE_ON; - if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) { + if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) && + test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, + ar->fw_capabilities)) { ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, true); if (ret) diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 4d9c6f142698..79c7055674bd 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -100,6 +100,13 @@ enum ath6kl_fw_capability { /* Firmware has support to override rsn cap of rsn ie */ ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, + /* + * Multicast support in WOW and host awake mode. + * Allow all multicast in host awake mode. + * Apply multicast filter in WOW mode. + */ + ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, + /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index e5524470529c..3e6768ae80af 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1167,7 +1167,10 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) else clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags); - mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); + if (test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, + vif->ar->fw_capabilities)) { + mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); + } if (!(ndev->flags & IFF_MULTICAST)) { mc_all_on = false; -- GitLab From c040be003f16a1bdd7997cc4ab7fc5fd43acb03b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 May 2012 12:01:40 +0200 Subject: [PATCH 0012/6849] ARM i.MX5: fix gpt peripheral clock path - The gpt peripheral clk parent is per_root, not ipg - The register for selectin per_lp_apm and per_root is MXC_CCM_CBCMR, not MXC_CCM_CBCDR Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx51-imx53.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index b8a382defb23..1e7828d6be95 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -94,12 +94,12 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, main_bus_sel, ARRAY_SIZE(main_bus_sel)); - clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCDR, 1, 1, + clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); - clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCDR, 1, 0, + clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, per_root_sel, ARRAY_SIZE(per_root_sel)); clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); @@ -162,7 +162,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12); clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16); - clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", MXC_CCM_CCGR2, 18); + clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per_root", MXC_CCM_CCGR2, 18); clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); -- GitLab From 1f152b48eaaf4918047e84777b01a6d687f066e9 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Tue, 15 May 2012 15:34:40 +0800 Subject: [PATCH 0013/6849] ARM: i.MX: change timer clock from ipg to perclk Contrary to the ipg clock the perclk rate is not changed or gated in low power mode, so we choose perclk for gpt. With the port to the common clock framework as a side effect the timer used the rate returned from the peripheral clock but the hardware was still programmed to use the ipg clock, so this patch only changes the hardware to really use the clock it already assumed. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 99f958ca6cb8..d865f7960baf 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -58,6 +58,7 @@ /* MX31, MX35, MX25, MX5 */ #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ #define V2_TCTL_CLK_IPG (1 << 6) +#define V2_TCTL_CLK_PER (2 << 6) #define V2_TCTL_FRR (1 << 9) #define V2_IR 0x0c #define V2_TSTAT 0x08 @@ -309,7 +310,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ if (timer_is_v2()) - tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; + tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; else tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; -- GitLab From 2cfb45188a997ba4c3348e98a999b36663a4646f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 May 2012 12:29:53 +0200 Subject: [PATCH 0014/6849] ARM i.MX: remove now unnecessary argument from mxc_timer_init As the timer code now does a clk_get to get its clock we don't need the struct clk argument anymore. This also changes the alternative EPIT timer to do a clk_get. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx1.c | 3 +-- arch/arm/mach-imx/clk-imx21.c | 4 ++-- arch/arm/mach-imx/clk-imx25.c | 2 +- arch/arm/mach-imx/clk-imx27.c | 3 +-- arch/arm/mach-imx/clk-imx31.c | 3 +-- arch/arm/mach-imx/clk-imx35.c | 6 ++---- arch/arm/mach-imx/clk-imx51-imx53.c | 6 ++---- arch/arm/mach-imx/clk-imx6q.c | 2 +- arch/arm/plat-mxc/epit.c | 11 ++++++++++- arch/arm/plat-mxc/include/mach/common.h | 4 ++-- arch/arm/plat-mxc/time.c | 21 ++++++++++----------- 11 files changed, 33 insertions(+), 32 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index 0f0beb580b73..516ddee1948e 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -108,8 +108,7 @@ int __init mx1_clocks_init(unsigned long fref) clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0"); clk_register_clkdev(clk[clko], "clko", NULL); - mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), - MX1_TIM1_INT); + mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); return 0; } diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index 4e4f384ee8dd..ea13e61bd5f3 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -180,7 +180,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL); clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL); - mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), - MX21_INT_GPT1); + mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); + return 0; } diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index d9833bb5fd61..fdd8cc87c9fe 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -243,6 +243,6 @@ int __init mx25_clocks_init(void) clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma"); clk_register_clkdev(clk[iim_ipg], "iim", NULL); - mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); + mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); return 0; } diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 50a7ebd8d1b2..295cbd7c08dc 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -263,8 +263,7 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0"); clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1"); - mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), - MX27_INT_GPT1); + mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); clk_prepare_enable(clk[emi_ahb_gate]); diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index a854b9cae5ea..c9a06d800f8e 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -175,8 +175,7 @@ int __init mx31_clocks_init(unsigned long fref) mx31_revision(); clk_disable_unprepare(clk[iim_gate]); - mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), - MX31_INT_GPT); + mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); return 0; } diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index a9e60bf7dd75..920a8cc42726 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -267,11 +267,9 @@ int __init mx35_clocks_init() imx_print_silicon_rev("i.MX35", mx35_revision()); #ifdef CONFIG_MXC_USE_EPIT - epit_timer_init(&epit1_clk, - MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); + epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); #else - mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), - MX35_INT_GPT); + mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); #endif return 0; diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 1e7828d6be95..c1739f6078d5 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -329,8 +329,7 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_b_podf], 166250000); /* System timer */ - mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), - MX51_INT_GPT); + mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT); clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX51", mx51_revision()); @@ -412,8 +411,7 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_b_podf], 200000000); /* System timer */ - mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), - MX53_INT_GPT); + mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT); clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX53", mx53_revision()); diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index f40a35da2e5c..24324f2dac95 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -433,7 +433,7 @@ int __init mx6q_clocks_init(void) base = of_iomap(np, 0); WARN_ON(!base); irq = irq_of_parse_and_map(np, 0); - mxc_timer_init(NULL, base, irq); + mxc_timer_init(base, irq); return 0; } diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c index 9129c9e7d532..88726f4dbbfa 100644 --- a/arch/arm/plat-mxc/epit.c +++ b/arch/arm/plat-mxc/epit.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -201,8 +202,16 @@ static int __init epit_clockevent_init(struct clk *timer_clk) return 0; } -void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +void __init epit_timer_init(void __iomem *base, int irq) { + struct clk *timer_clk; + + timer_clk = clk_get_sys("imx-epit.0", NULL); + if (IS_ERR(timer_clk)) { + pr_err("i.MX epit: unable to get clk\n"); + return; + } + clk_prepare_enable(timer_clk); timer_base = base; diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 0319c4a0cafa..da02540f4bd4 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -53,8 +53,8 @@ extern void imx35_soc_init(void); extern void imx50_soc_init(void); extern void imx51_soc_init(void); extern void imx53_soc_init(void); -extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); -extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); +extern void epit_timer_init(void __iomem *base, int irq); +extern void mxc_timer_init(void __iomem *, int); extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx25_clocks_init(void); diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index d865f7960baf..00e8e659e667 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -281,23 +281,22 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) return 0; } -void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +void __init mxc_timer_init(void __iomem *base, int irq) { uint32_t tctl_val; + struct clk *timer_clk; struct clk *timer_ipg_clk; - if (!timer_clk) { - timer_clk = clk_get_sys("imx-gpt.0", "per"); - if (IS_ERR(timer_clk)) { - pr_err("i.MX timer: unable to get clk\n"); - return; - } - - timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg"); - if (!IS_ERR(timer_ipg_clk)) - clk_prepare_enable(timer_ipg_clk); + timer_clk = clk_get_sys("imx-gpt.0", "per"); + if (IS_ERR(timer_clk)) { + pr_err("i.MX timer: unable to get clk\n"); + return; } + timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg"); + if (!IS_ERR(timer_ipg_clk)) + clk_prepare_enable(timer_ipg_clk); + clk_prepare_enable(timer_clk); timer_base = base; -- GitLab From b0286f20c36d0c1e7537489daddaf574abf403dd Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Mon, 14 May 2012 13:04:47 +0800 Subject: [PATCH 0015/6849] ARM: imx6q: prepare and enable init on clks directly instead of clk_get first This also removes the usboh3 clk from the initially turned on clocks which leaked in from an internal development tree. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx6q.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 24324f2dac95..7b4751dbe749 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -122,10 +122,6 @@ static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; -static const char * const clks_init_on[] __initconst = { - "mmdc_ch0_axi", "mmdc_ch1_axi", "usboh3", -}; - enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, pll3_pfd0_720m, pll3_pfd1_540m, pll3_pfd2_508m, pll3_pfd3_454m, @@ -160,11 +156,14 @@ enum mx6q_clks { static struct clk *clk[clk_max]; +static enum mx6q_clks const clks_init_on[] __initconst = { + mmdc_ch0_axi, mmdc_ch1_axi, +}; + int __init mx6q_clocks_init(void) { struct device_node *np; void __iomem *base; - struct clk *c; int i, irq; clk[dummy] = imx_clk_fixed("dummy", 0); @@ -419,15 +418,8 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[dummy], NULL, "20bc000.wdog"); clk_register_clkdev(clk[dummy], NULL, "20c0000.wdog"); - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) { - c = clk_get_sys(clks_init_on[i], NULL); - if (IS_ERR(c)) { - pr_err("%s: failed to get clk %s", __func__, - clks_init_on[i]); - return PTR_ERR(c); - } - clk_prepare_enable(c); - } + for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) + clk_prepare_enable(clk[clks_init_on[i]]); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); -- GitLab From c422d52d0450988ce9a1ffdddb78807538396749 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Tue, 15 May 2012 00:09:23 -0700 Subject: [PATCH 0016/6849] ath6kl: enable enhanced bmiss detection Enable enhanced bmiss detection if the firmware supports it. This feature is only enabled on some firmwares since it comes with a power cost. Also add a few missing command ids to keep the enums straight. kvalo: fix a compiler with ath6kl_err(), add few empty lines Signed-off-by: Thomas Pedersen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 30 ++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/cfg80211.h | 2 ++ drivers/net/wireless/ath/ath6kl/core.h | 3 +++ drivers/net/wireless/ath/ath6kl/init.c | 3 +++ drivers/net/wireless/ath/ath6kl/wmi.c | 19 ++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 11 ++++++++ 6 files changed, 68 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 22843a1b9f21..e68b1077816a 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -576,6 +576,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, vif->nw_type = vif->next_mode; + /* enable enhanced bmiss detection if applicable */ + ath6kl_cfg80211_sta_bmiss_enhance(vif, true); + if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) nw_subtype = SUBTYPE_P2PCLIENT; @@ -1512,6 +1515,9 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy, } } + /* need to clean up enhanced bmiss detection fw state */ + ath6kl_cfg80211_sta_bmiss_enhance(vif, false); + set_iface_type: switch (type) { case NL80211_IFTYPE_STATION: @@ -2618,6 +2624,30 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, return 0; } +void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable) +{ + int err; + + if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag))) + return; + + if (vif->nw_type != INFRA_NETWORK) + return; + + if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, + vif->ar->fw_capabilities)) + return; + + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n", + enable ? "enable" : "disable"); + + err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi, + vif->fw_vif_idx, enable); + if (err) + ath6kl_err("failed to %s enhanced bmiss detection: %d\n", + enable ? "enable" : "disable", err); +} + static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, u8 *rsn_capab) { diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 5ea8cbb79f43..b992046a1b0e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -62,5 +62,7 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar); struct ath6kl *ath6kl_cfg80211_create(void); void ath6kl_cfg80211_destroy(struct ath6kl *ar); +/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */ +void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable); #endif /* ATH6KL_CFG80211_H */ diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 79c7055674bd..99169794ff3a 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -107,6 +107,9 @@ enum ath6kl_fw_capability { */ ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, + /* Firmware supports enhanced bmiss detection */ + ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, + /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7eb0515f458a..10de1322e702 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1659,6 +1659,9 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) cfg80211_scan_done(vif->scan_req, true); vif->scan_req = NULL; } + + /* need to clean up enhanced bmiss detection fw state */ + ath6kl_cfg80211_sta_bmiss_enhance(vif, false); } void ath6kl_stop_txrx(struct ath6kl *ar) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index bdd3b2c55637..6ad762daa425 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2997,6 +2997,25 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, return ret; } +int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance) +{ + struct sk_buff *skb; + struct wmi_sta_bmiss_enhance_cmd *cmd; + int ret; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_sta_bmiss_enhance_cmd *) skb->data; + cmd->enable = enhance ? 1 : 0; + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_STA_BMISS_ENHANCE_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} + s32 ath6kl_wmi_get_rate(s8 rate_index) { if (rate_index == RATE_AUTO) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 3518550e3504..8c07e3858b11 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -624,6 +624,10 @@ enum wmi_cmd_id { WMI_SEND_MGMT_CMDID, WMI_BEGIN_SCAN_CMDID, + WMI_SET_BLACK_LIST, + WMI_SET_MCASTRATE, + + WMI_STA_BMISS_ENHANCE_CMDID, }; enum wmi_mgmt_frame_type { @@ -1017,6 +1021,11 @@ struct wmi_bmiss_time_cmd { __le16 num_beacons; }; +/* WMI_STA_ENHANCE_BMISS_CMDID */ +struct wmi_sta_bmiss_enhance_cmd { + u8 enable; +} __packed; + /* WMI_SET_POWER_MODE_CMDID */ enum wmi_power_mode { REC_POWER = 0x01, @@ -2547,6 +2556,8 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, u8 *filter, bool add_filter); +int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); + /* AP mode uAPSD */ int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); -- GitLab From dd45b7598f1c52933f276ba7ce175fa1305b8ba0 Mon Sep 17 00:00:00 2001 From: Naveen Singh Date: Wed, 16 May 2012 13:29:00 +0300 Subject: [PATCH 0017/6849] ath6kl: Include match ssid list in scheduled scan Scheduled scan implementation was only taking probed list into consideration. The matched list was dropped. This would cause FW not to report the AP as the list never had that AP's SSID populated. This was causing long connection time when supplicant would just issue a wild card SSID in probed list. As a part of this implementation, ath6kl driver would create a complete list by taking both probed and matched list and pass it to FW. FW would probe for the SSID that it needs to and would match against the relevant SSIDS that is been configured. kvalo: whitespace changes, less indentation in the for loop, use ++ Signed-off-by: Naveen Singh Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 98 +++++++++++++++++++--- drivers/net/wireless/ath/ath6kl/core.h | 5 ++ drivers/net/wireless/ath/ath6kl/wmi.h | 6 ++ 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index e68b1077816a..f3a6cfc0ddc8 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -53,6 +53,11 @@ #define DEFAULT_BG_SCAN_PERIOD 60 +struct ath6kl_cfg80211_match_probe_ssid { + struct cfg80211_ssid ssid; + u8 flag; +}; + static struct ieee80211_rate ath6kl_rates[] = { RATETAB_ENT(10, 0x1, 0), RATETAB_ENT(20, 0x2, 0), @@ -887,23 +892,76 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, static int ath6kl_set_probed_ssids(struct ath6kl *ar, struct ath6kl_vif *vif, - struct cfg80211_ssid *ssids, int n_ssids) + struct cfg80211_ssid *ssids, int n_ssids, + struct cfg80211_match_set *match_set, + int n_match_ssid) { - u8 i; + u8 i, j, index_to_add, ssid_found = false; + struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS]; + + memset(ssid_list, 0, sizeof(ssid_list)); - if (n_ssids > MAX_PROBED_SSIDS) + if (n_ssids > MAX_PROBED_SSIDS || + n_match_ssid > MAX_PROBED_SSIDS) return -EINVAL; for (i = 0; i < n_ssids; i++) { + memcpy(ssid_list[i].ssid.ssid, + ssids[i].ssid, + ssids[i].ssid_len); + ssid_list[i].ssid.ssid_len = ssids[i].ssid_len; + + if (ssids[i].ssid_len) + ssid_list[i].flag = SPECIFIC_SSID_FLAG; + else + ssid_list[i].flag = ANY_SSID_FLAG; + + if (n_match_ssid == 0) + ssid_list[i].flag |= MATCH_SSID_FLAG; + } + + index_to_add = i; + + for (i = 0; i < n_match_ssid; i++) { + ssid_found = false; + + for (j = 0; j < n_ssids; j++) { + if ((match_set[i].ssid.ssid_len == + ssid_list[j].ssid.ssid_len) && + (!memcmp(ssid_list[j].ssid.ssid, + match_set[i].ssid.ssid, + match_set[i].ssid.ssid_len))) { + ssid_list[j].flag |= MATCH_SSID_FLAG; + ssid_found = true; + break; + } + } + + if (ssid_found) + continue; + + if (index_to_add >= MAX_PROBED_SSIDS) + continue; + + ssid_list[index_to_add].ssid.ssid_len = + match_set[i].ssid.ssid_len; + memcpy(ssid_list[index_to_add].ssid.ssid, + match_set[i].ssid.ssid, + match_set[i].ssid.ssid_len); + ssid_list[index_to_add].flag |= MATCH_SSID_FLAG; + index_to_add++; + } + + for (i = 0; i < index_to_add; i++) { ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, - ssids[i].ssid_len ? - SPECIFIC_SSID_FLAG : ANY_SSID_FLAG, - ssids[i].ssid_len, - ssids[i].ssid); + ssid_list[i].flag, + ssid_list[i].ssid.ssid_len, + ssid_list[i].ssid.ssid); + } /* Make sure no old entries are left behind */ - for (i = n_ssids; i < MAX_PROBED_SSIDS; i++) { + for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) { ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, DISABLE_SSID_FLAG, 0, NULL); } @@ -937,7 +995,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, - request->n_ssids); + request->n_ssids, NULL, 0); if (ret < 0) return ret; @@ -3194,10 +3252,24 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, ath6kl_cfg80211_scan_complete_event(vif, true); ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, - request->n_ssids); + request->n_ssids, + request->match_sets, + request->n_match_sets); if (ret < 0) return ret; + if (!request->n_match_sets) { + ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, + ALL_BSS_FILTER, 0); + if (ret < 0) + return ret; + } else { + ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, + MATCHED_SSID_FILTER, 0); + if (ret < 0) + return ret; + } + /* fw uses seconds, also make sure that it's >0 */ interval = max_t(u16, 1, request->interval / 1000); @@ -3505,6 +3577,12 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) /* max num of ssids that can be probed during scanning */ wiphy->max_scan_ssids = MAX_PROBED_SSIDS; + + /* max num of ssids that can be matched after scan */ + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, + ar->fw_capabilities)) + wiphy->max_match_sets = MAX_PROBED_SSIDS; + wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ switch (ar->hw.cap) { case WMI_11AN_CAP: diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 99169794ff3a..991bd96f7cf6 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -110,6 +110,11 @@ enum ath6kl_fw_capability { /* Firmware supports enhanced bmiss detection */ ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, + /* + * FW supports matching of ssid in schedule scan + */ + ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, + /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 8c07e3858b11..47756795a26c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -964,6 +964,9 @@ enum wmi_bss_filter { /* beacons matching probed ssid */ PROBED_SSID_FILTER, + /* beacons matching matched ssid */ + MATCHED_SSID_FILTER, + /* marker only */ LAST_BSS_FILTER, }; @@ -993,6 +996,9 @@ enum wmi_ssid_flag { /* probes for any ssid */ ANY_SSID_FLAG = 0x02, + + /* match for ssid */ + MATCH_SSID_FLAG = 0x08, }; struct wmi_probed_ssid_cmd { -- GitLab From 33a6664a6e4b45814ef6e3129842f3fd7e5d1117 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Wed, 16 May 2012 13:41:13 -0700 Subject: [PATCH 0018/6849] ath6kl: issue wmi disconnect after notifying cfg80211 ath6kl would issue a wmi disconnect command in response to a remote disconnect and return early without notifying cfg80211, only sending a cfg80211_disconnected (with reason code always 3) in response to the second disconnect firmware event. Pass the right reason code to cfg80211 on the first disconnect instead. This fixes at least one bug where a p2p client would stop trying to connect after receiving a stale RSN deauth which was reported to cfg80211 as GO leaving BSS. Signed-off-by: Thomas Pedersen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 27 ++++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f3a6cfc0ddc8..7845d33deed9 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -860,20 +860,6 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, } } - /* - * Send a disconnect command to target when a disconnect event is - * received with reason code other than 3 (DISCONNECT_CMD - disconnect - * request from host) to make the firmware stop trying to connect even - * after giving disconnect event. There will be one more disconnect - * event for this disconnect command with reason code DISCONNECT_CMD - * which will be notified to cfg80211. - */ - - if (reason != DISCONNECT_CMD) { - ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); - return; - } - clear_bit(CONNECT_PEND, &vif->flags); if (vif->sme_state == SME_CONNECTING) { @@ -883,11 +869,22 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); } else if (vif->sme_state == SME_CONNECTED) { - cfg80211_disconnected(vif->ndev, reason, + cfg80211_disconnected(vif->ndev, proto_reason, NULL, 0, GFP_KERNEL); } vif->sme_state = SME_DISCONNECTED; + + /* + * Send a disconnect command to target when a disconnect event is + * received with reason code other than 3 (DISCONNECT_CMD - disconnect + * request from host) to make the firmware stop trying to connect even + * after giving disconnect event. There will be one more disconnect + * event for this disconnect command with reason code DISCONNECT_CMD + * which won't be notified to cfg80211. + */ + if (reason != DISCONNECT_CMD) + ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); } static int ath6kl_set_probed_ssids(struct ath6kl *ar, -- GitLab From d0e05bb3d611c7c3d37cadd8c1016ee2e22beefa Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 May 2012 10:20:33 +0900 Subject: [PATCH 0019/6849] sh: mach-se: Migrate 7724SE off of deprecated dynamic IRQ API. The generic hardirq layer provides all of the routines that we need these days, so we don't require any of the dynamic IRQ API wrapping, and can call in to irq_alloc_descs() directly. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/irq.c | 36 +++++++++++-------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c index c6342ce7768d..5d1d3ec9a6cd 100644 --- a/arch/sh/boards/mach-se/7724/irq.c +++ b/arch/sh/boards/mach-se/7724/irq.c @@ -17,8 +17,10 @@ #include #include #include -#include -#include +#include +#include +#include +#include #include struct fpga_irq { @@ -111,7 +113,7 @@ static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) */ void __init init_se7724_IRQ(void) { - int i, nid = cpu_to_node(boot_cpu_data); + int irq_base, i; __raw_writew(0xffff, IRQ0_MR); /* mask all */ __raw_writew(0xffff, IRQ1_MR); /* mask all */ @@ -121,28 +123,16 @@ void __init init_se7724_IRQ(void) __raw_writew(0x0000, IRQ2_SR); /* clear irq */ __raw_writew(0x002a, IRQ_MODE); /* set irq type */ - for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) { - int irq, wanted; - - wanted = SE7724_FPGA_IRQ_BASE + i; - - irq = create_irq_nr(wanted, nid); - if (unlikely(irq == 0)) { - pr_err("%s: failed hooking irq %d for FPGA\n", - __func__, wanted); - return; - } - - if (unlikely(irq != wanted)) { - pr_err("%s: got irq %d but wanted %d, bailing.\n", - __func__, irq, wanted); - destroy_irq(irq); - return; - } + irq_base = irq_alloc_descs(SE7724_FPGA_IRQ_BASE, SE7724_FPGA_IRQ_BASE, + SE7724_FPGA_IRQ_NR, numa_node_id()); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: failed hooking irqs for FPGA\n", __func__); + return; + } - irq_set_chip_and_handler_name(irq, &se7724_irq_chip, + for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) + irq_set_chip_and_handler_name(irq_base + i, &se7724_irq_chip, handle_level_irq, "level"); - } irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux); irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); -- GitLab From 051f923d922d105f4d32e64cba1ed6f5a749d530 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 May 2012 23:20:09 +0900 Subject: [PATCH 0020/6849] sh: hd64461: Migrate off of deprecated dynamic IRQ API. Switches from create_irq_nr() to irq_alloc_descs(). Signed-off-by: Paul Mundt --- arch/sh/cchips/hd6446x/hd64461.c | 33 +++++++++----------------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index eb4ea4d44d59..e9735616bdc8 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -73,10 +73,7 @@ static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) int __init setup_hd64461(void) { - int i, nid = cpu_to_node(boot_cpu_data); - - if (!MACH_HD64461) - return 0; + int irq_base, i; printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n", @@ -89,28 +86,16 @@ int __init setup_hd64461(void) #endif __raw_writew(0xffff, HD64461_NIMR); - /* IRQ 80 -> 95 belongs to HD64461 */ - for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { - unsigned int irq; - - irq = create_irq_nr(i, nid); - if (unlikely(irq == 0)) { - pr_err("%s: failed hooking irq %d for HD64461\n", - __func__, i); - return -EBUSY; - } - - if (unlikely(irq != i)) { - pr_err("%s: got irq %d but wanted %d, bailing.\n", - __func__, irq, i); - destroy_irq(irq); - return -EINVAL; - } - - irq_set_chip_and_handler(i, &hd64461_irq_chip, - handle_level_irq); + irq_base = irq_alloc_descs(HD64461_IRQBASE, HD64461_IRQBASE, 16, -1); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: failed hooking irqs for HD64461\n", __func__); + return irq_base; } + for (i = 0; i < 16; i++) + irq_set_chip_and_handler(irq_base + i, &hd64461_irq_chip, + handle_level_irq); + irq_set_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); irq_set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); -- GitLab From 3b1267b90f6b7c080024101696c0454f455761f4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 May 2012 23:36:44 +0900 Subject: [PATCH 0021/6849] sh: dreamcast: Migrate off of deprecated dynamic IRQ API. Switches from create_irq_nr() to irq_alloc_descs(). Signed-off-by: Paul Mundt --- arch/sh/boards/mach-dreamcast/irq.c | 32 ++++++++++------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c index f63d323f411f..2789647abebe 100644 --- a/arch/sh/boards/mach-dreamcast/irq.c +++ b/arch/sh/boards/mach-dreamcast/irq.c @@ -8,10 +8,11 @@ * This file is part of the LinuxDC project (www.linuxdc.org) * Released under the terms of the GNU GPL v2.0 */ - #include #include -#include +#include +#include +#include #include /* @@ -141,26 +142,15 @@ int systemasic_irq_demux(int irq) void systemasic_irq_init(void) { - int i, nid = cpu_to_node(boot_cpu_data); - - /* Assign all virtual IRQs to the System ASIC int. handler */ - for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) { - unsigned int irq; - - irq = create_irq_nr(i, nid); - if (unlikely(irq == 0)) { - pr_err("%s: failed hooking irq %d for systemasic\n", - __func__, i); - return; - } + int irq_base, i; - if (unlikely(irq != i)) { - pr_err("%s: got irq %d but wanted %d, bailing.\n", - __func__, irq, i); - destroy_irq(irq); - return; - } + irq_base = irq_alloc_descs(HW_EVENT_IRQ_BASE, HW_EVENT_IRQ_BASE, + HW_EVENT_IRQ_MAX - HW_EVENT_IRQ_BASE, -1); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: failed hooking irqs\n", __func__); + return; + } + for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq); - } } -- GitLab From d8e328b3bd65fdefc9c49a27ee80c28e0a44b653 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sun, 20 May 2012 00:08:13 -0600 Subject: [PATCH 0022/6849] spi: Add "spi:" prefix to modalias attribute of spi devices The modalias attribute of spi devices doesn't have the "spi:" prefix that is used in the UEVENT and in spi device drivers. This patch adds the prefix so the modprobe can correctly match modules to devices. Reported-by: David Daney Signed-off-by: Grant Likely --- drivers/spi/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1041cb83d67a..84c2861d6f4d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -53,7 +53,7 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) { const struct spi_device *spi = to_spi_device(dev); - return sprintf(buf, "%s\n", spi->modalias); + return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); } static struct device_attribute spi_dev_attrs[] = { -- GitLab From 8b5e218d8caa7592d26e68157bd71f50426bb7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 8 May 2012 17:12:17 +0200 Subject: [PATCH 0023/6849] can: flexcan: add PM support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tested on an i.MX257 Signed-off-by: Eric Bénard Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 1efb08386c61..0d058b0a3cb6 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1050,6 +1050,42 @@ static struct of_device_id flexcan_of_match[] = { {}, }; +#ifdef CONFIG_PM +static int flexcan_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct flexcan_priv *priv = netdev_priv(dev); + + flexcan_chip_disable(priv); + + if (netif_running(dev)) { + netif_stop_queue(dev); + netif_device_detach(dev); + } + priv->can.state = CAN_STATE_SLEEPING; + + return 0; +} + +static int flexcan_resume(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct flexcan_priv *priv = netdev_priv(dev); + + priv->can.state = CAN_STATE_ERROR_ACTIVE; + if (netif_running(dev)) { + netif_device_attach(dev); + netif_start_queue(dev); + } + flexcan_chip_enable(priv); + + return 0; +} +#else +#define flexcan_suspend NULL +#define flexcan_resume NULL +#endif + static struct platform_driver flexcan_driver = { .driver = { .name = DRV_NAME, @@ -1058,6 +1094,8 @@ static struct platform_driver flexcan_driver = { }, .probe = flexcan_probe, .remove = __devexit_p(flexcan_remove), + .suspend = flexcan_suspend, + .resume = flexcan_resume, }; module_platform_driver(flexcan_driver); -- GitLab From d6e640f9766e2fb9aa3853b4ff19e4d7d5d7e373 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 8 May 2012 22:20:33 +0200 Subject: [PATCH 0024/6849] can: update documentation wording error frames -> error messages As Heinz-Juergen Oertel pointed out 'CAN error frames' are a already defined term for the CAN protocol violation indication on the wire. To avoid confusion with the error messages created by CAN drivers available via CAN RAW sockets update the documentation and change the naming from 'error frames' to 'error messages' or 'error message frames'. Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- Documentation/networking/can.txt | 32 ++++++++++++++++---------------- include/linux/can.h | 8 ++++---- include/linux/can/error.h | 4 ++-- net/can/af_can.c | 10 +++++----- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index 56ca3b75376e..28d9b14c34ec 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -232,16 +232,16 @@ solution for a couple of reasons: arbitration problems and error frames caused by the different ECUs. The occurrence of detected errors are important for diagnosis and have to be logged together with the exact timestamp. For this - reason the CAN interface driver can generate so called Error Frames - that can optionally be passed to the user application in the same - way as other CAN frames. Whenever an error on the physical layer + reason the CAN interface driver can generate so called Error Message + Frames that can optionally be passed to the user application in the + same way as other CAN frames. Whenever an error on the physical layer or the MAC layer is detected (e.g. by the CAN controller) the driver - creates an appropriate error frame. Error frames can be requested by - the user application using the common CAN filter mechanisms. Inside - this filter definition the (interested) type of errors may be - selected. The reception of error frames is disabled by default. - The format of the CAN error frame is briefly described in the Linux - header file "include/linux/can/error.h". + creates an appropriate error message frame. Error messages frames can + be requested by the user application using the common CAN filter + mechanisms. Inside this filter definition the (interested) type of + errors may be selected. The reception of error messages is disabled + by default. The format of the CAN error message frame is briefly + described in the Linux header file "include/linux/can/error.h". 4. How to use Socket CAN ------------------------ @@ -383,7 +383,7 @@ solution for a couple of reasons: defaults are set at RAW socket binding time: - The filters are set to exactly one filter receiving everything - - The socket only receives valid data frames (=> no error frames) + - The socket only receives valid data frames (=> no error message frames) - The loopback of sent CAN frames is enabled (see chapter 3.2) - The socket does not receive its own sent frames (in loopback mode) @@ -434,7 +434,7 @@ solution for a couple of reasons: 4.1.2 RAW socket option CAN_RAW_ERR_FILTER As described in chapter 3.4 the CAN interface driver can generate so - called Error Frames that can optionally be passed to the user + called Error Message Frames that can optionally be passed to the user application in the same way as other CAN frames. The possible errors are divided into different error classes that may be filtered using the appropriate error mask. To register for every possible @@ -527,7 +527,7 @@ solution for a couple of reasons: rcvlist_all - list for unfiltered entries (no filter operations) rcvlist_eff - list for single extended frame (EFF) entries - rcvlist_err - list for error frames masks + rcvlist_err - list for error message frames masks rcvlist_fil - list for mask/value filters rcvlist_inv - list for mask/value filters (inverse semantic) rcvlist_sff - list for single standard frame (SFF) entries @@ -784,13 +784,13 @@ solution for a couple of reasons: $ ip link set canX type can restart-ms 100 Alternatively, the application may realize the "bus-off" condition - by monitoring CAN error frames and do a restart when appropriate with - the command: + by monitoring CAN error message frames and do a restart when + appropriate with the command: $ ip link set canX type can restart - Note that a restart will also create a CAN error frame (see also - chapter 3.4). + Note that a restart will also create a CAN error message frame (see + also chapter 3.4). 6.6 Supported CAN hardware diff --git a/include/linux/can.h b/include/linux/can.h index 9a19bcb3eeaf..17334c09bd93 100644 --- a/include/linux/can.h +++ b/include/linux/can.h @@ -21,7 +21,7 @@ /* special address description flags for the CAN_ID */ #define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */ #define CAN_RTR_FLAG 0x40000000U /* remote transmission request */ -#define CAN_ERR_FLAG 0x20000000U /* error frame */ +#define CAN_ERR_FLAG 0x20000000U /* error message frame */ /* valid bits in CAN ID for frame formats */ #define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */ @@ -32,14 +32,14 @@ * Controller Area Network Identifier structure * * bit 0-28 : CAN identifier (11/29 bit) - * bit 29 : error frame flag (0 = data frame, 1 = error frame) + * bit 29 : error message frame flag (0 = data frame, 1 = error message) * bit 30 : remote transmission request flag (1 = rtr frame) * bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit) */ typedef __u32 canid_t; /* - * Controller Area Network Error Frame Mask structure + * Controller Area Network Error Message Frame Mask structure * * bit 0-28 : error class mask (see include/linux/can/error.h) * bit 29-31 : set to zero @@ -97,7 +97,7 @@ struct sockaddr_can { * & mask == can_id & mask * * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can - * filter for error frames (CAN_ERR_FLAG bit set in mask). + * filter for error message frames (CAN_ERR_FLAG bit set in mask). */ struct can_filter { canid_t can_id; diff --git a/include/linux/can/error.h b/include/linux/can/error.h index 63e855ea6b84..7b7148bded71 100644 --- a/include/linux/can/error.h +++ b/include/linux/can/error.h @@ -1,7 +1,7 @@ /* * linux/can/error.h * - * Definitions of the CAN error frame to be filtered and passed to the user. + * Definitions of the CAN error messages to be filtered and passed to the user. * * Author: Oliver Hartkopp * Copyright (c) 2002-2007 Volkswagen Group Electronic Research @@ -12,7 +12,7 @@ #ifndef CAN_ERROR_H #define CAN_ERROR_H -#define CAN_ERR_DLC 8 /* dlc for error frames */ +#define CAN_ERR_DLC 8 /* dlc for error message frames */ /* error class (mask) in can_id */ #define CAN_ERR_TX_TIMEOUT 0x00000001U /* TX timeout (by netdevice driver) */ diff --git a/net/can/af_can.c b/net/can/af_can.c index 0ce2ad0696da..6efcd37b4bd0 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -334,8 +334,8 @@ static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev) * relevant bits for the filter. * * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can - * filter for error frames (CAN_ERR_FLAG bit set in mask). For error frames - * there is a special filterlist and a special rx path filter handling. + * filter for error messages (CAN_ERR_FLAG bit set in mask). For error msg + * frames there is a special filterlist and a special rx path filter handling. * * Return: * Pointer to optimal filterlist for the given can_id/mask pair. @@ -347,7 +347,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, { canid_t inv = *can_id & CAN_INV_FILTER; /* save flag before masking */ - /* filter for error frames in extra filterlist */ + /* filter for error message frames in extra filterlist */ if (*mask & CAN_ERR_FLAG) { /* clear CAN_ERR_FLAG in filter entry */ *mask &= CAN_ERR_MASK; @@ -408,7 +408,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, * & mask == can_id & mask * * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can - * filter for error frames (CAN_ERR_FLAG bit set in mask). + * filter for error message frames (CAN_ERR_FLAG bit set in mask). * * The provided pointer to the sk_buff is guaranteed to be valid as long as * the callback function is running. The callback function must *not* free @@ -578,7 +578,7 @@ static int can_rcv_filter(struct dev_rcv_lists *d, struct sk_buff *skb) return 0; if (can_id & CAN_ERR_FLAG) { - /* check for error frame entries only */ + /* check for error message frame entries only */ hlist_for_each_entry_rcu(r, n, &d->rx[RX_ERR], list) { if (can_id & r->mask) { deliver(skb, r); -- GitLab From 76b386624576eb00a7c7cad0e713952121708598 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 13:59:35 +0900 Subject: [PATCH 0025/6849] sh: Kill off now unused arch_probe_nr_irqs(). Now that legacy pre-allocation is done away with, we can just use the generic stub in kernel/softirq.c. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index dadce735f746..063af10ff3c1 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -231,16 +231,6 @@ void __init init_IRQ(void) irq_ctx_init(smp_processor_id()); } -#ifdef CONFIG_SPARSE_IRQ -int __init arch_probe_nr_irqs(void) -{ - /* - * No pre-allocated IRQs. - */ - return 0; -} -#endif - #ifdef CONFIG_HOTPLUG_CPU static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu) { -- GitLab From 49453264997f232008efae457553d82381f9614f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 15:03:46 +0900 Subject: [PATCH 0026/6849] sh64: Convert to unwinder API. This switches over to use the sh unwinder API which brings it all in line with the general sh routines (which we shuffle around at the same time), and lets us kill off more sh64-specific cruft. Signed-off-by: Paul Mundt --- arch/sh/include/asm/kdebug.h | 2 ++ arch/sh/kernel/cpu/sh5/unwind.c | 63 +++++++++++++++++++++------------ arch/sh/kernel/dumpstack.c | 58 ++++++++++++++++++++++++++++++ arch/sh/kernel/traps_32.c | 50 -------------------------- arch/sh/kernel/traps_64.c | 26 -------------- 5 files changed, 101 insertions(+), 98 deletions(-) diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h index a6201f10c273..8d6a831e7ba1 100644 --- a/arch/sh/include/asm/kdebug.h +++ b/arch/sh/include/asm/kdebug.h @@ -10,6 +10,8 @@ enum die_val { DIE_SSTEP, }; +/* arch/sh/kernel/dumpstack.c */ extern void printk_address(unsigned long address, int reliable); +extern void dump_mem(const char *str, unsigned long bottom, unsigned long top); #endif /* __ASM_SH_KDEBUG_H */ diff --git a/arch/sh/kernel/cpu/sh5/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c index b205b25eaf45..10aed41757fc 100644 --- a/arch/sh/kernel/cpu/sh5/unwind.c +++ b/arch/sh/kernel/cpu/sh5/unwind.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include static u8 regcache[63]; @@ -199,8 +201,11 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc, return 0; } -/* Don't put this on the stack since we'll want to call sh64_unwind - * when we're close to underflowing the stack anyway. */ +/* + * Don't put this on the stack since we'll want to call in to + * sh64_unwinder_dump() when we're close to underflowing the stack + * anyway. + */ static struct pt_regs here_regs; extern const char syscall_ret; @@ -208,17 +213,19 @@ extern const char ret_from_syscall; extern const char ret_from_exception; extern const char ret_from_irq; -static void sh64_unwind_inner(struct pt_regs *regs); +static void sh64_unwind_inner(const struct stacktrace_ops *ops, + void *data, struct pt_regs *regs); -static void unwind_nested (unsigned long pc, unsigned long fp) +static inline void unwind_nested(const struct stacktrace_ops *ops, void *data, + unsigned long pc, unsigned long fp) { if ((fp >= __MEMORY_START) && - ((fp & 7) == 0)) { - sh64_unwind_inner((struct pt_regs *) fp); - } + ((fp & 7) == 0)) + sh64_unwind_inner(ops, data, (struct pt_regs *)fp); } -static void sh64_unwind_inner(struct pt_regs *regs) +static void sh64_unwind_inner(const struct stacktrace_ops *ops, + void *data, struct pt_regs *regs) { unsigned long pc, fp; int ofs = 0; @@ -232,29 +239,29 @@ static void sh64_unwind_inner(struct pt_regs *regs) int cond; unsigned long next_fp, next_pc; - if (pc == ((unsigned long) &syscall_ret & ~1)) { + if (pc == ((unsigned long)&syscall_ret & ~1)) { printk("SYSCALL\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } - if (pc == ((unsigned long) &ret_from_syscall & ~1)) { + if (pc == ((unsigned long)&ret_from_syscall & ~1)) { printk("SYSCALL (PREEMPTED)\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } /* In this case, the PC is discovered by lookup_prev_stack_frame but it has 4 taken off it to look like the 'caller' */ - if (pc == ((unsigned long) &ret_from_exception & ~1)) { + if (pc == ((unsigned long)&ret_from_exception & ~1)) { printk("EXCEPTION\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } - if (pc == ((unsigned long) &ret_from_irq & ~1)) { + if (pc == ((unsigned long)&ret_from_irq & ~1)) { printk("IRQ\n"); - unwind_nested(pc,fp); + unwind_nested(ops, data, pc, fp); return; } @@ -263,8 +270,7 @@ static void sh64_unwind_inner(struct pt_regs *regs) pc -= ofs; - printk("[<%08lx>] ", pc); - print_symbol("%s\n", pc); + ops->address(data, pc, 1); if (first_pass) { /* If the innermost frame is a leaf function, it's @@ -287,10 +293,13 @@ static void sh64_unwind_inner(struct pt_regs *regs) } printk("\n"); - } -void sh64_unwind(struct pt_regs *regs) +static void sh64_unwinder_dump(struct task_struct *task, + struct pt_regs *regs, + unsigned long *sp, + const struct stacktrace_ops *ops, + void *data) { if (!regs) { /* @@ -320,7 +329,17 @@ void sh64_unwind(struct pt_regs *regs) ); } - printk("\nCall Trace:\n"); - sh64_unwind_inner(regs); + sh64_unwind_inner(ops, data, regs); } +static struct unwinder sh64_unwinder = { + .name = "sh64-unwinder", + .dump = sh64_unwinder_dump, + .rating = 150, +}; + +static int __init sh64_unwinder_init(void) +{ + return unwinder_register(&sh64_unwinder); +} +early_initcall(sh64_unwinder_init); diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c index 694158b9a50f..7617dc4129ac 100644 --- a/arch/sh/kernel/dumpstack.c +++ b/arch/sh/kernel/dumpstack.c @@ -2,13 +2,48 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs * Copyright (C) 2009 Matt Fleming + * Copyright (C) 2002 - 2012 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ #include #include #include +#include +#include +#include #include #include +void dump_mem(const char *str, unsigned long bottom, unsigned long top) +{ + unsigned long p; + int i; + + printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); + + for (p = bottom & ~31; p < top; ) { + printk("%04lx: ", p & 0xffff); + + for (i = 0; i < 8; i++, p += 4) { + unsigned int val; + + if (p < bottom || p >= top) + printk(" "); + else { + if (__get_user(val, (unsigned int __user *)p)) { + printk("\n"); + return; + } + printk("%08x ", val); + } + } + printk("\n"); + } +} + void printk_address(unsigned long address, int reliable) { printk(" [<%p>] %s%pS\n", (void *) address, @@ -106,3 +141,26 @@ void show_trace(struct task_struct *tsk, unsigned long *sp, debug_show_held_locks(tsk); } + +void show_stack(struct task_struct *tsk, unsigned long *sp) +{ + unsigned long stack; + + if (!tsk) + tsk = current; + if (tsk == current) + sp = (unsigned long *)current_stack_pointer; + else + sp = (unsigned long *)tsk->thread.sp; + + stack = (unsigned long)sp; + dump_mem("Stack: ", stack, THREAD_SIZE + + (unsigned long)task_stack_page(tsk)); + show_trace(tsk, sp, NULL); +} + +void dump_stack(void) +{ + show_stack(NULL, NULL); +} +EXPORT_SYMBOL(dump_stack); diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index a37175deb73f..b8f5a51841ec 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -48,33 +48,6 @@ #define TRAP_ILLEGAL_SLOT_INST 13 #endif -static void dump_mem(const char *str, unsigned long bottom, unsigned long top) -{ - unsigned long p; - int i; - - printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); - - for (p = bottom & ~31; p < top; ) { - printk("%04lx: ", p & 0xffff); - - for (i = 0; i < 8; i++, p += 4) { - unsigned int val; - - if (p < bottom || p >= top) - printk(" "); - else { - if (__get_user(val, (unsigned int __user *)p)) { - printk("\n"); - return; - } - printk("%08x ", val); - } - } - printk("\n"); - } -} - static DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) @@ -900,26 +873,3 @@ void __init trap_init(void) set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler); #endif } - -void show_stack(struct task_struct *tsk, unsigned long *sp) -{ - unsigned long stack; - - if (!tsk) - tsk = current; - if (tsk == current) - sp = (unsigned long *)current_stack_pointer; - else - sp = (unsigned long *)tsk->thread.sp; - - stack = (unsigned long)sp; - dump_mem("Stack: ", stack, THREAD_SIZE + - (unsigned long)task_stack_page(tsk)); - show_trace(tsk, sp, NULL); -} - -void dump_stack(void) -{ - show_stack(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index 8dae93ed8aff..ba95d63e623d 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -253,32 +253,6 @@ int do_unknown_trapa(unsigned long scId, struct pt_regs *regs) return -ENOSYS; } -void show_stack(struct task_struct *tsk, unsigned long *sp) -{ -#ifdef CONFIG_KALLSYMS - extern void sh64_unwind(struct pt_regs *regs); - struct pt_regs *regs; - - regs = tsk ? tsk->thread.kregs : NULL; - - sh64_unwind(regs); -#else - printk(KERN_ERR "Can't backtrace on sh64 without CONFIG_KALLSYMS\n"); -#endif -} - -void show_task(unsigned long *sp) -{ - show_stack(NULL, sp); -} - -void dump_stack(void) -{ - show_task(NULL); -} -/* Needed by any user of WARN_ON in view of the defn in include/asm-sh/bug.h */ -EXPORT_SYMBOL(dump_stack); - static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_name, unsigned long error_code, struct pt_regs *regs, struct task_struct *tsk) { -- GitLab From 3a898c0f36f9fe312cb6e98865a6833110e67cb2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 15:05:29 +0900 Subject: [PATCH 0027/6849] sh64: Ensure KALLSYMS is enabled for unwinder use. Since sh64 depends on kallsyms unconditionally for its stack unwinding to be of any use, make sure it's selected. In practice we don't have any case where it's disabled anyways, so moving to this to a select is fine. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 3e723aaa5e18..931310b49bce 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -55,6 +55,7 @@ config SUPERH32 config SUPERH64 def_bool ARCH = "sh64" + select KALLSYMS config ARCH_DEFCONFIG string -- GitLab From b98b35815f40f01337e25e3f0d10d57b7cec5126 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 15:24:39 +0900 Subject: [PATCH 0028/6849] sh: mach-x3proto: Migrate to linear irq domain. In the interest of getting off of the create_irq() API we can get all of the functionality we're interested in through a linear IRQ domain. Fairly straightforward conversion utilizing a single linear domain. Signed-off-by: Paul Mundt --- arch/sh/boards/Kconfig | 1 + arch/sh/boards/mach-x3proto/gpio.c | 57 ++++++++++++++++-------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index d893411022d5..f2024a91319f 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -292,6 +292,7 @@ config SH_X3PROTO bool "SH-X3 Prototype board" depends on CPU_SUBTYPE_SHX3 select NO_IOPORT if !PCI + select IRQ_DOMAIN config SH_MAGIC_PANEL_R2 bool "Magic Panel R2" diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c index f33b2b57019c..3ea65e9b56e8 100644 --- a/arch/sh/boards/mach-x3proto/gpio.c +++ b/arch/sh/boards/mach-x3proto/gpio.c @@ -3,7 +3,7 @@ * * Renesas SH-X3 Prototype Baseboard GPIO Support. * - * Copyright (C) 2010 Paul Mundt + * Copyright (C) 2010 - 2012 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ #define KEYDETR 0xb81c0004 static DEFINE_SPINLOCK(x3proto_gpio_lock); -static unsigned int x3proto_gpio_irq_map[NR_BASEBOARD_GPIOS] = { 0, }; +static struct irq_domain *x3proto_irq_domain; static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { @@ -49,7 +50,14 @@ static int x3proto_gpio_get(struct gpio_chip *chip, unsigned gpio) static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) { - return x3proto_gpio_irq_map[gpio]; + int virq; + + if (gpio < chip->ngpio) + virq = irq_create_mapping(x3proto_irq_domain, gpio); + else + virq = -ENXIO; + + return virq; } static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) @@ -62,9 +70,8 @@ static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) chip->irq_mask_ack(data); mask = __raw_readw(KEYDETR); - for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS) - generic_handle_irq(x3proto_gpio_to_irq(NULL, pin)); + generic_handle_irq(irq_linear_revmap(x3proto_irq_domain, pin)); chip->irq_unmask(data); } @@ -78,10 +85,23 @@ struct gpio_chip x3proto_gpio_chip = { .ngpio = NR_BASEBOARD_GPIOS, }; +static int x3proto_gpio_irq_map(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler_name(virq, &dummy_irq_chip, handle_simple_irq, + "gpio"); + + return 0; +} + +static struct irq_domain_ops x3proto_gpio_irq_ops = { + .map = x3proto_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + int __init x3proto_gpio_setup(void) { - int ilsel; - int ret, i; + int ilsel, ret; ilsel = ilsel_enable(ILSEL_KEY); if (unlikely(ilsel < 0)) @@ -91,21 +111,10 @@ int __init x3proto_gpio_setup(void) if (unlikely(ret)) goto err_gpio; - for (i = 0; i < NR_BASEBOARD_GPIOS; i++) { - unsigned long flags; - int irq = create_irq(); - - if (unlikely(irq < 0)) { - ret = -EINVAL; - goto err_irq; - } - - spin_lock_irqsave(&x3proto_gpio_lock, flags); - x3proto_gpio_irq_map[i] = irq; - irq_set_chip_and_handler_name(irq, &dummy_irq_chip, - handle_simple_irq, "gpio"); - spin_unlock_irqrestore(&x3proto_gpio_lock, flags); - } + x3proto_irq_domain = irq_domain_add_linear(NULL, NR_BASEBOARD_GPIOS, + &x3proto_gpio_irq_ops, NULL); + if (unlikely(!x3proto_irq_domain)) + goto err_irq; pr_info("registering '%s' support, handling GPIOs %u -> %u, " "bound to IRQ %u\n", @@ -119,10 +128,6 @@ int __init x3proto_gpio_setup(void) return 0; err_irq: - for (; i >= 0; --i) - if (x3proto_gpio_irq_map[i]) - destroy_irq(x3proto_gpio_irq_map[i]); - ret = gpiochip_remove(&x3proto_gpio_chip); if (unlikely(ret)) pr_err("Failed deregistering GPIO\n"); -- GitLab From fa338be062e31141a8dadd822a98f558785c8818 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 22 May 2012 12:52:48 +0530 Subject: [PATCH 0029/6849] ath6kl: Fix missing gpio pin 9 configuration GPIO pin 9 also needs to be configured along with other gpio pins to avoid sdio crc errors. I've not experienced any issue with missing this particular gpio pin configuration, found dunring code review. This can potentially improve rx performance. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 6 ++++++ drivers/net/wireless/ath/ath6kl/target.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 10de1322e702..241febcd7f7c 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1392,6 +1392,12 @@ static int ath6kl_init_upload(struct ath6kl *ar) ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { ath6kl_err("temporary war to avoid sdio crc error\n"); + param = 0x28; + address = GPIO_BASE_ADDRESS + GPIO_PIN9_ADDRESS; + status = ath6kl_bmi_reg_write(ar, address, param); + if (status) + return status; + param = 0x20; address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS; diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index 78e0ef4567a5..a98c12ba70c1 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h @@ -45,6 +45,7 @@ #define LPO_CAL_ENABLE_S 20 #define LPO_CAL_ENABLE 0x00100000 +#define GPIO_PIN9_ADDRESS 0x0000004c #define GPIO_PIN10_ADDRESS 0x00000050 #define GPIO_PIN11_ADDRESS 0x00000054 #define GPIO_PIN12_ADDRESS 0x00000058 -- GitLab From 06e360ace9434bf37164fd87941b797cc0f3cb7e Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Date: Tue, 22 May 2012 13:23:12 +0530 Subject: [PATCH 0030/6849] ath6kl: Add support for setting tx rateset. Tx legacy and mcs rateset can configured using iw for 2.4 and 5 bands. Add support for the same in driver. kvalo: add an enum for the hw flags and rename the flag accordingly, rename ath6kl_cfg80211_set_bitrate_mask() to a shorter version to make it easier to indent Signed-off-by: Bala Shanmugam Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 24 +++++ drivers/net/wireless/ath/ath6kl/core.h | 6 ++ drivers/net/wireless/ath/ath6kl/init.c | 5 + drivers/net/wireless/ath/ath6kl/wmi.c | 109 +++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 32 ++++++ 5 files changed, 176 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7845d33deed9..6a934e16ae83 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -3320,6 +3320,18 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, return 0; } +static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, + struct net_device *dev, + const u8 *addr, + const struct cfg80211_bitrate_mask *mask) +{ + struct ath6kl *ar = ath6kl_priv(dev); + struct ath6kl_vif *vif = netdev_priv(dev); + + return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx, + mask); +} + static const struct ieee80211_txrx_stypes ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_STATION] = { @@ -3386,6 +3398,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .mgmt_frame_register = ath6kl_mgmt_frame_register, .sched_scan_start = ath6kl_cfg80211_sscan_start, .sched_scan_stop = ath6kl_cfg80211_sscan_stop, + .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, }; void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) @@ -3616,6 +3629,17 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) ath6kl_band_5ghz.ht_cap.cap = 0; ath6kl_band_5ghz.ht_cap.ht_supported = false; } + + if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) { + ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; + ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; + ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; + ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff; + } else { + ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; + ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; + } + if (band_2gig) wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; if (band_5gig) diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 991bd96f7cf6..b1bc6bc69f2a 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -127,6 +127,10 @@ struct ath6kl_fw_ie { u8 data[0]; }; +enum ath6kl_hw_flags { + ATH6KL_HW_FLAG_64BIT_RATES = BIT(0), +}; + #define ATH6KL_FW_API2_FILE "fw-2.bin" #define ATH6KL_FW_API3_FILE "fw-3.bin" @@ -702,6 +706,8 @@ struct ath6kl { u32 testscript_addr; enum wmi_phy_cap cap; + u32 flags; + struct ath6kl_hw_fw { const char *dir; const char *otp; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 241febcd7f7c..daf24ee9d28a 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -42,6 +42,7 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 6912, .refclk_hz = 26000000, .uarttx_pin = 8, + .flags = 0, /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, @@ -67,6 +68,7 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 8, .testscript_addr = 0x57ef74, + .flags = 0, .fw = { .dir = AR6003_HW_2_1_1_FW_DIR, @@ -91,6 +93,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x433900, .refclk_hz = 26000000, .uarttx_pin = 11, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_0_FW_DIR, @@ -110,6 +113,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x43d400, .refclk_hz = 40000000, .uarttx_pin = 11, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_1_FW_DIR, @@ -129,6 +133,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x435c00, .refclk_hz = 40000000, .uarttx_pin = 11, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_2_FW_DIR, diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 6ad762daa425..63dc4fd73c4c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2599,6 +2599,115 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi) spin_unlock_bh(&wmi->lock); } +static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx, + const struct cfg80211_bitrate_mask *mask) +{ + struct sk_buff *skb; + int ret, mode, band; + u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; + struct wmi_set_tx_select_rates64_cmd *cmd; + + memset(&ratemask, 0, sizeof(ratemask)); + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + /* copy legacy rate mask */ + ratemask[band] = mask->control[band].legacy; + if (band == IEEE80211_BAND_5GHZ) + ratemask[band] = + mask->control[band].legacy << 4; + + /* copy mcs rate mask */ + mcsrate = mask->control[band].mcs[1]; + mcsrate <<= 8; + mcsrate |= mask->control[band].mcs[0]; + ratemask[band] |= mcsrate << 12; + ratemask[band] |= mcsrate << 28; + } + + ath6kl_dbg(ATH6KL_DBG_WMI, + "Ratemask 64 bit: 2.4:%llx 5:%llx\n", + ratemask[0], ratemask[1]); + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_set_tx_select_rates64_cmd *) skb->data; + for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) { + /* A mode operate in 5GHZ band */ + if (mode == WMI_RATES_MODE_11A || + mode == WMI_RATES_MODE_11A_HT20 || + mode == WMI_RATES_MODE_11A_HT40) + band = IEEE80211_BAND_5GHZ; + else + band = IEEE80211_BAND_2GHZ; + cmd->ratemask[mode] = cpu_to_le64(ratemask[band]); + } + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_SET_TX_SELECT_RATES_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} + +static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx, + const struct cfg80211_bitrate_mask *mask) +{ + struct sk_buff *skb; + int ret, mode, band; + u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; + struct wmi_set_tx_select_rates32_cmd *cmd; + + memset(&ratemask, 0, sizeof(ratemask)); + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + /* copy legacy rate mask */ + ratemask[band] = mask->control[band].legacy; + if (band == IEEE80211_BAND_5GHZ) + ratemask[band] = + mask->control[band].legacy << 4; + + /* copy mcs rate mask */ + mcsrate = mask->control[band].mcs[0]; + ratemask[band] |= mcsrate << 12; + ratemask[band] |= mcsrate << 20; + } + + ath6kl_dbg(ATH6KL_DBG_WMI, + "Ratemask 32 bit: 2.4:%x 5:%x\n", + ratemask[0], ratemask[1]); + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_set_tx_select_rates32_cmd *) skb->data; + for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) { + /* A mode operate in 5GHZ band */ + if (mode == WMI_RATES_MODE_11A || + mode == WMI_RATES_MODE_11A_HT20 || + mode == WMI_RATES_MODE_11A_HT40) + band = IEEE80211_BAND_5GHZ; + else + band = IEEE80211_BAND_2GHZ; + cmd->ratemask[mode] = cpu_to_le32(ratemask[band]); + } + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_SET_TX_SELECT_RATES_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} + +int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, + const struct cfg80211_bitrate_mask *mask) +{ + struct ath6kl *ar = wmi->parent_dev; + + if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) + return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); + else + return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); +} + int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode) { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 47756795a26c..7c94fe3e9e6d 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1063,6 +1063,36 @@ struct wmi_power_params_cmd { __le16 ps_fail_event_policy; } __packed; +/* + * Ratemask for below modes should be passed + * to WMI_SET_TX_SELECT_RATES_CMDID. + * AR6003 has 32 bit mask for each modes. + * First 12 bits for legacy rates, 13 to 20 + * bits for HT 20 rates and 21 to 28 bits for + * HT 40 rates + */ +enum wmi_mode_phy { + WMI_RATES_MODE_11A = 0, + WMI_RATES_MODE_11G, + WMI_RATES_MODE_11B, + WMI_RATES_MODE_11GONLY, + WMI_RATES_MODE_11A_HT20, + WMI_RATES_MODE_11G_HT20, + WMI_RATES_MODE_11A_HT40, + WMI_RATES_MODE_11G_HT40, + WMI_RATES_MODE_MAX +}; + +/* WMI_SET_TX_SELECT_RATES_CMDID */ +struct wmi_set_tx_select_rates32_cmd { + __le32 ratemask[WMI_RATES_MODE_MAX]; +} __packed; + +/* WMI_SET_TX_SELECT_RATES_CMDID */ +struct wmi_set_tx_select_rates64_cmd { + __le64 ratemask[WMI_RATES_MODE_MAX]; +} __packed; + /* WMI_SET_DISC_TIMEOUT_CMDID */ struct wmi_disc_timeout_cmd { /* seconds */ @@ -2547,6 +2577,8 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, __be32 ips0, __be32 ips1); int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode); +int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, + const struct cfg80211_bitrate_mask *mask); int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_wow_mode wow_mode, u32 filter, u16 host_req_delay); -- GitLab From 5df38b9b7676e4e46c5c13e75f023ffb82542980 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 18:24:32 +0900 Subject: [PATCH 0031/6849] sh: se722: Move FPGA IRQs to irqdomain and generic irq chip. This implements a total rewrite of the rather buggy SE7722 FPGA IRQ code, utilizing a linear irq domain as well as the generic irq chip type. While the interaction between the two APIs is a bit clunky (ie, revmap lookup for gc irq_base), they work well enough together that it's easy enough to work with going forward. While we're at it, deal with irq_mask_ack/unmask of the chained IRQ in the demux handler to prevent smc91x screaming about spurious interrupts. There's also some more improvement that can be made to the irqdomain code to create backing irqdescs for the entire linear range in one bang instead of iterating over the number of hwirqs and doing it irq-at-a-time. This is easily dealt with at a later point, though. Signed-off-by: Paul Mundt --- arch/sh/boards/Kconfig | 2 + arch/sh/boards/mach-se/7722/irq.c | 131 +++++++++++++++++--------- arch/sh/boards/mach-se/7722/setup.c | 6 +- arch/sh/include/mach-se/mach/se7722.h | 10 +- 4 files changed, 94 insertions(+), 55 deletions(-) diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index f2024a91319f..525b9e32cd14 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -44,6 +44,8 @@ config SH_7721_SOLUTION_ENGINE config SH_7722_SOLUTION_ENGINE bool "SolutionEngine7722" select SOLUTION_ENGINE + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN depends on CPU_SUBTYPE_SH7722 help Select 7722 SolutionEngine if configuring for a Hitachi SH772 diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c index aac92f21ebd2..f5e2af1bf040 100644 --- a/arch/sh/boards/mach-se/7722/irq.c +++ b/arch/sh/boards/mach-se/7722/irq.c @@ -1,79 +1,96 @@ /* - * linux/arch/sh/boards/se/7722/irq.c + * Hitachi UL SolutionEngine 7722 FPGA IRQ Support. * * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * Hitachi UL SolutionEngine 7722 Support. + * Copyright (C) 2012 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#define DRV_NAME "SE7722-FPGA" +#define pr_fmt(fmt) DRV_NAME ": " fmt + +#define irq_reg_readl ioread16 +#define irq_reg_writel iowrite16 + #include #include #include -#include -#include +#include +#include +#include +#include #include -unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; +#define IRQ01_BASE_ADDR 0x11800000 +#define IRQ01_MODE_REG 0 +#define IRQ01_STS_REG 4 +#define IRQ01_MASK_REG 8 -static void disable_se7722_irq(struct irq_data *data) -{ - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); -} +static void __iomem *se7722_irq_regs; +struct irq_domain *se7722_irq_domain; -static void enable_se7722_irq(struct irq_data *data) +static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); -} + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); + unsigned long mask; + int bit; -static struct irq_chip se7722_irq_chip __read_mostly = { - .name = "SE7722-FPGA", - .irq_mask = disable_se7722_irq, - .irq_unmask = enable_se7722_irq, -}; + chip->irq_mask_ack(data); -static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) + mask = ioread16(se7722_irq_regs + IRQ01_STS_REG); + + for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR) + generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit)); + + chip->irq_unmask(data); +} + +static void __init se7722_domain_init(void) { - unsigned short intv = __raw_readw(IRQ01_STS); - unsigned int ext_irq = 0; + int i; - intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; + se7722_irq_domain = irq_domain_add_linear(NULL, SE7722_FPGA_IRQ_NR, + &irq_domain_simple_ops, NULL); + if (unlikely(!se7722_irq_domain)) { + printk("Failed to get IRQ domain\n"); + return; + } - for (; intv; intv >>= 1, ext_irq++) { - if (!(intv & 1)) - continue; + for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { + int irq = irq_create_mapping(se7722_irq_domain, i); - generic_handle_irq(se7722_fpga_irq[ext_irq]); + if (unlikely(irq == 0)) { + printk("Failed to allocate IRQ %d\n", i); + return; + } } } -/* - * Initialize IRQ setting - */ -void __init init_se7722_IRQ(void) +static void __init se7722_gc_init(void) { - int i, irq; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + unsigned int irq_base; - __raw_writew(0, IRQ01_MASK); /* disable all irqs */ - __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + irq_base = irq_linear_revmap(se7722_irq_domain, 0); - for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { - irq = create_irq(); - if (irq < 0) - return; - se7722_fpga_irq[i] = irq; + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs, + handle_level_irq); + if (unlikely(!gc)) + return; - irq_set_chip_and_handler_name(se7722_fpga_irq[i], - &se7722_irq_chip, - handle_level_irq, - "level"); + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; - irq_set_chip_data(se7722_fpga_irq[i], (void *)i); - } + ct->regs.mask = IRQ01_MASK_REG; + + irq_setup_generic_chip(gc, IRQ_MSK(SE7722_FPGA_IRQ_NR), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux); irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); @@ -81,3 +98,25 @@ void __init init_se7722_IRQ(void) irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux); irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); } + +/* + * Initialize FPGA IRQs + */ +void __init init_se7722_IRQ(void) +{ + se7722_irq_regs = ioremap(IRQ01_BASE_ADDR, SZ_16); + if (unlikely(!se7722_irq_regs)) { + printk("Failed to remap IRQ01 regs\n"); + return; + } + + /* + * All FPGA IRQs disabled by default + */ + iowrite16(0, se7722_irq_regs + IRQ01_MASK_REG); + + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + + se7722_domain_init(); + se7722_gc_init(); +} diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index e1963fecd761..2ec0111fdf9b 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -2,6 +2,7 @@ * linux/arch/sh/boards/se/7722/setup.c * * Copyright (C) 2007 Nobuhiro Iwamatsu + * Copyright (C) 2012 Paul Mundt * * Hitachi UL SolutionEngine 7722 Support. * @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -142,10 +144,10 @@ static int __init se7722_devices_setup(void) /* Wire-up dynamic vectors */ cf_ide_resources[2].start = cf_ide_resources[2].end = - se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0]; + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_MRSHPC0); smc91x_eth_resources[1].start = smc91x_eth_resources[1].end = - se7722_fpga_irq[SE7722_FPGA_IRQ_SMC]; + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_SMC); return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); } diff --git a/arch/sh/include/mach-se/mach/se7722.h b/arch/sh/include/mach-se/mach/se7722.h index 16505bfb8a9e..5508dc42e4d2 100644 --- a/arch/sh/include/mach-se/mach/se7722.h +++ b/arch/sh/include/mach-se/mach/se7722.h @@ -80,12 +80,6 @@ #define IRQ0_IRQ 32 #define IRQ1_IRQ 33 -#define IRQ01_MODE 0xb1800000 -#define IRQ01_STS 0xb1800004 -#define IRQ01_MASK 0xb1800008 - -/* Bits in IRQ01_* registers */ - #define SE7722_FPGA_IRQ_USB 0 /* IRQ0 */ #define SE7722_FPGA_IRQ_SMC 1 /* IRQ0 */ #define SE7722_FPGA_IRQ_MRSHPC0 2 /* IRQ1 */ @@ -94,8 +88,10 @@ #define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ #define SE7722_FPGA_IRQ_NR 6 +struct irq_domain; + /* arch/sh/boards/se/7722/irq.c */ -extern unsigned int se7722_fpga_irq[]; +extern struct irq_domain *se7722_irq_domain; void init_se7722_IRQ(void); -- GitLab From 197b58e6651426bec8b2582013258b52cd15a444 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 19:07:18 +0900 Subject: [PATCH 0032/6849] sh: se7343: Move CPLD IRQs to irqdomain and generic irq chip. Follows the se7722 change, see there for more information. Signed-off-by: Paul Mundt --- arch/sh/boards/Kconfig | 2 + arch/sh/boards/mach-se/7343/irq.c | 129 +++++++++++++++++--------- arch/sh/boards/mach-se/7343/setup.c | 10 +- arch/sh/include/mach-se/mach/se7343.h | 7 +- 4 files changed, 97 insertions(+), 51 deletions(-) diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 525b9e32cd14..1a280048e2c3 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -81,6 +81,8 @@ config SH_7780_SOLUTION_ENGINE config SH_7343_SOLUTION_ENGINE bool "SolutionEngine7343" select SOLUTION_ENGINE + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN depends on CPU_SUBTYPE_SH7343 help Select 7343 SolutionEngine if configuring for a Hitachi diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index fd45ffc48340..7646bf0486c2 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c @@ -1,86 +1,129 @@ /* - * linux/arch/sh/boards/se/7343/irq.c + * Hitachi UL SolutionEngine 7343 FPGA IRQ Support. * * Copyright (C) 2008 Yoshihiro Shimoda + * Copyright (C) 2012 Paul Mundt * - * Based on linux/arch/sh/boards/se/7722/irq.c + * Based on linux/arch/sh/boards/se/7343/irq.c * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#define DRV_NAME "SE7343-FPGA" +#define pr_fmt(fmt) DRV_NAME ": " fmt + +#define irq_reg_readl ioread16 +#define irq_reg_writel iowrite16 + #include #include #include +#include #include +#include #include -unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, }; +#define PA_CPLD_BASE_ADDR 0x11400000 +#define PA_CPLD_ST_REG 0x08 /* CPLD Interrupt status register */ +#define PA_CPLD_IMSK_REG 0x0a /* CPLD Interrupt mask register */ -static void disable_se7343_irq(struct irq_data *data) -{ - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); -} +static void __iomem *se7343_irq_regs; +struct irq_domain *se7343_irq_domain; -static void enable_se7343_irq(struct irq_data *data) +static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); - __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); -} + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); + unsigned long mask; + int bit; -static struct irq_chip se7343_irq_chip __read_mostly = { - .name = "SE7343-FPGA", - .irq_mask = disable_se7343_irq, - .irq_unmask = enable_se7343_irq, -}; + chip->irq_mask_ack(data); -static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) + mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG); + + for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR) + generic_handle_irq(irq_linear_revmap(se7343_irq_domain, bit)); + + chip->irq_unmask(data); +} + +static void __init se7343_domain_init(void) { - unsigned short intv = __raw_readw(PA_CPLD_ST); - unsigned int ext_irq = 0; + int i; - intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; + se7343_irq_domain = irq_domain_add_linear(NULL, SE7343_FPGA_IRQ_NR, + &irq_domain_simple_ops, NULL); + if (unlikely(!se7343_irq_domain)) { + printk("Failed to get IRQ domain\n"); + return; + } - for (; intv; intv >>= 1, ext_irq++) { - if (!(intv & 1)) - continue; + for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { + int irq = irq_create_mapping(se7343_irq_domain, i); - generic_handle_irq(se7343_fpga_irq[ext_irq]); + if (unlikely(irq == 0)) { + printk("Failed to allocate IRQ %d\n", i); + return; + } } } -/* - * Initialize IRQ setting - */ -void __init init_7343se_IRQ(void) +static void __init se7343_gc_init(void) { - int i, irq; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + unsigned int irq_base; - __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */ - __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + irq_base = irq_linear_revmap(se7343_irq_domain, 0); - for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { - irq = create_irq(); - if (irq < 0) - return; - se7343_fpga_irq[i] = irq; + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7343_irq_regs, + handle_level_irq); + if (unlikely(!gc)) + return; - irq_set_chip_and_handler_name(se7343_fpga_irq[i], - &se7343_irq_chip, - handle_level_irq, - "level"); + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; - irq_set_chip_data(se7343_fpga_irq[i], (void *)i); - } + ct->regs.mask = PA_CPLD_IMSK_REG; + + irq_setup_generic_chip(gc, IRQ_MSK(SE7343_FPGA_IRQ_NR), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); + irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); + irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW); + irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux); irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW); } + +/* + * Initialize IRQ setting + */ +void __init init_7343se_IRQ(void) +{ + se7343_irq_regs = ioremap(PA_CPLD_BASE_ADDR, SZ_16); + if (unlikely(!se7343_irq_regs)) { + pr_err("Failed to remap CPLD\n"); + return; + } + + /* + * All FPGA IRQs disabled by default + */ + iowrite16(0, se7343_irq_regs + PA_CPLD_IMSK_REG); + + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + + se7343_domain_init(); + se7343_gc_init(); +} diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index d2370af56d77..8ce4f2a202a8 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -145,11 +146,12 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = { static int __init sh7343se_devices_setup(void) { /* Wire-up dynamic vectors */ - serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA]; - serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB]; - + serial_platform_data[0].irq = irq_find_mapping(se7343_irq_domain, + SE7343_FPGA_IRQ_UARTA); + serial_platform_data[1].irq = irq_find_mapping(se7343_irq_domain, + SE7343_FPGA_IRQ_UARTB); usb_resources[2].start = usb_resources[2].end = - se7343_fpga_irq[SE7343_FPGA_IRQ_USB]; + irq_find_mapping(se7343_irq_domain, SE7343_FPGA_IRQ_USB); return platform_add_devices(sh7343se_platform_devices, ARRAY_SIZE(sh7343se_platform_devices)); diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h index 8d8170d6cc43..2ec6f75a44de 100644 --- a/arch/sh/include/mach-se/mach/se7343.h +++ b/arch/sh/include/mach-se/mach/se7343.h @@ -49,9 +49,6 @@ #define PA_LED 0xb0C00000 /* LED */ #define LED_SHIFT 0 #define PA_DIPSW 0xb0900000 /* Dip switch 31 */ -#define PA_CPLD_MODESET 0xb1400004 /* CPLD Mode set register */ -#define PA_CPLD_ST 0xb1400008 /* CPLD Interrupt status register */ -#define PA_CPLD_IMSK 0xb140000a /* CPLD Interrupt mask register */ /* Area 5 */ #define PA_EXT5 0x14000000 #define PA_EXT5_SIZE 0x04000000 @@ -134,8 +131,10 @@ #define SE7343_FPGA_IRQ_NR 12 +struct irq_domain; + /* arch/sh/boards/se/7343/irq.c */ -extern unsigned int se7343_fpga_irq[]; +extern struct irq_domain *se7343_irq_domain; void init_7343se_IRQ(void); -- GitLab From be9c00295b34760ea2f9667929049f094116b5a8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 19:10:45 +0900 Subject: [PATCH 0033/6849] sh: intc: Kill off deprecated dynamic IRQ API. Now that all of the users have been converted away, kill off the remnants of the old API. Signed-off-by: Paul Mundt --- drivers/sh/intc/Makefile | 2 +- drivers/sh/intc/dynamic.c | 65 --------------------------------------- 2 files changed, 1 insertion(+), 66 deletions(-) delete mode 100644 drivers/sh/intc/dynamic.c diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile index bb5df868d77a..44f006d09471 100644 --- a/drivers/sh/intc/Makefile +++ b/drivers/sh/intc/Makefile @@ -1,4 +1,4 @@ -obj-y := access.o chip.o core.o dynamic.o handle.o virq.o +obj-y := access.o chip.o core.o handle.o virq.o obj-$(CONFIG_INTC_BALANCING) += balancing.o obj-$(CONFIG_INTC_USERIMASK) += userimask.o diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c deleted file mode 100644 index 5fea1ee8799a..000000000000 --- a/drivers/sh/intc/dynamic.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Dynamic IRQ management - * - * Copyright (C) 2010 Paul Mundt - * - * Modelled after arch/x86/kernel/apic/io_apic.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "intc: " fmt - -#include -#include -#include -#include -#include "internals.h" /* only for activate_irq() damage.. */ - -/* - * The IRQ bitmap provides a global map of bound IRQ vectors for a - * given platform. Allocation of IRQs are either static through the CPU - * vector map, or dynamic in the case of board mux vectors or MSI. - * - * As this is a central point for all IRQ controllers on the system, - * each of the available sources are mapped out here. This combined with - * sparseirq makes it quite trivial to keep the vector map tightly packed - * when dynamically creating IRQs, as well as tying in to otherwise - * unused irq_desc positions in the sparse array. - */ - -/* - * Dynamic IRQ allocation and deallocation - */ -unsigned int create_irq_nr(unsigned int irq_want, int node) -{ - int irq = irq_alloc_desc_at(irq_want, node); - if (irq < 0) - return 0; - - activate_irq(irq); - return irq; -} - -int create_irq(void) -{ - int irq = irq_alloc_desc(numa_node_id()); - if (irq >= 0) - activate_irq(irq); - - return irq; -} - -void destroy_irq(unsigned int irq) -{ - irq_free_desc(irq); -} - -void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) -{ - int i; - - for (i = 0; i < nr_vecs; i++) - irq_reserve_irq(evt2irq(vectors[i].vect)); -} -- GitLab From 151766fce8bee0e3e6076c8b829f9fcc0a2412ae Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Sat, 28 Apr 2012 14:30:40 +0800 Subject: [PATCH 0034/6849] Revert "x86/platform: Add a wallclock_init func to x86_platforms ops" This reverts commit cf8ff6b6ab0e99dd3058852f4ec76a6140abadec. Just found this commit is a function duplicatation of commit 6b617e22 "x86/platform: Add a wallclock_init func to x86_init.timers ops". Let's revert it and sorry for the noise. Signed-off-by: Feng Tang Cc: Ingo Molnar Cc: H. Peter Anvin Cc: Jacob Pan Cc: Alan Cox Cc: Dirk Brandewie Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/x86_init.h | 2 -- arch/x86/kernel/setup.c | 2 -- arch/x86/kernel/x86_init.c | 2 -- 3 files changed, 6 deletions(-) diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index c090af10ac7d..42d2ae18dab2 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -156,7 +156,6 @@ struct x86_cpuinit_ops { /** * struct x86_platform_ops - platform specific runtime functions * @calibrate_tsc: calibrate TSC - * @wallclock_init: init the wallclock device * @get_wallclock: get time from HW clock like RTC etc. * @set_wallclock: set time back to HW clock * @is_untracked_pat_range exclude from PAT logic @@ -167,7 +166,6 @@ struct x86_cpuinit_ops { */ struct x86_platform_ops { unsigned long (*calibrate_tsc)(void); - void (*wallclock_init)(void); unsigned long (*get_wallclock)(void); int (*set_wallclock)(unsigned long nowtime); void (*iommu_shutdown)(void); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 366c688d619e..58a07b10812c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1027,8 +1027,6 @@ void __init setup_arch(char **cmdline_p) x86_init.timers.wallclock_init(); - x86_platform.wallclock_init(); - mcheck_init(); arch_init_ideal_nops(); diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 35c5e543f550..9f3167e891ef 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -29,7 +29,6 @@ void __init x86_init_uint_noop(unsigned int unused) { } void __init x86_init_pgd_noop(pgd_t *unused) { } int __init iommu_init_noop(void) { return 0; } void iommu_shutdown_noop(void) { } -void wallclock_init_noop(void) { } /* * The platform setup functions are preset with the default functions @@ -101,7 +100,6 @@ static int default_i8042_detect(void) { return 1; }; struct x86_platform_ops x86_platform = { .calibrate_tsc = native_calibrate_tsc, - .wallclock_init = wallclock_init_noop, .get_wallclock = mach_get_cmos_time, .set_wallclock = mach_set_rtc_mmss, .iommu_shutdown = iommu_shutdown_noop, -- GitLab From f841d792e38f75f5e25b0b66f7b5d235d180a735 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 30 Mar 2012 23:11:35 +0800 Subject: [PATCH 0035/6849] x86: Return IRQ_SET_MASK_OK_NOCOPY from irq affinity functions The interrupt chip irq_set_affinity() functions copy the affinity mask to irq_data->affinity but return 0, i.e. IRQ_SET_MASK_OK. IRQ_SET_MASK_OK causes the core code to do another redundant copy. Return IRQ_SET_MASK_OK_NOCOPY to avoid this. Signed-off-by: Jiang Liu Cc: Suresh Siddha Cc: Yinghai Lu Cc: Naga Chumbalkar Cc: Jacob Pan Cc: Cliff Wickman Cc: Jiang Liu Cc: Keping Chen Link: http://lkml.kernel.org/r/1333120296-13563-4-git-send-email-jiang.liu@huawei.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/apic/io_apic.c | 9 +++++---- arch/x86/platform/uv/uv_irq.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ac96561d1a99..bce2001b2644 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2270,6 +2270,7 @@ ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, /* Only the high 8 bits are valid. */ dest = SET_APIC_LOGICAL_ID(dest); __target_IO_APIC_irq(irq, dest, data->chip_data); + ret = IRQ_SET_MASK_OK_NOCOPY; } raw_spin_unlock_irqrestore(&ioapic_lock, flags); return ret; @@ -3092,7 +3093,7 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) __write_msi_msg(data->msi_desc, &msg); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif /* CONFIG_SMP */ @@ -3214,7 +3215,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, dmar_msi_write(irq, &msg); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif /* CONFIG_SMP */ @@ -3267,7 +3268,7 @@ static int hpet_msi_set_affinity(struct irq_data *data, hpet_msi_write(data->handler_data, &msg); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif /* CONFIG_SMP */ @@ -3340,7 +3341,7 @@ ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) return -1; target_ht_irq(data->irq, dest, cfg->vector); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c index f25c2765a5c9..a22c41656b52 100644 --- a/arch/x86/platform/uv/uv_irq.c +++ b/arch/x86/platform/uv/uv_irq.c @@ -222,7 +222,7 @@ uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask, if (cfg->move_in_progress) send_cleanup_vector(cfg); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } /* -- GitLab From a60977a51333a8108f0574aa26094d66b7fedf34 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 14:59:26 +0900 Subject: [PATCH 0036/6849] sh: clkfwk: Move to common clk_div_table accessors for div4/div6. This plugs in a generic clk_div_table, based on the div4 version. div6 is then adopted to use it for encapsulating its div table, which permits us to start div6/4 unification, as well as preparation for other div types. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 46 ++++++++++++++++++++++++++++++++---------- include/linux/sh_clk.h | 5 +++-- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index f0d015dd0fef..9dea32907795 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -71,6 +71,22 @@ static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) return clk_rate_table_round(clk, clk->freq_table, rate); } +/* + * Div/mult table lookup helpers + */ +static inline struct clk_div_table *clk_to_div_table(struct clk *clk) +{ + return clk->priv; +} + +static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk) +{ + return clk_to_div_table(clk)->div_mult_table; +} + +/* + * div6 support + */ static int sh_clk_div6_divisors[64] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -78,14 +94,18 @@ static int sh_clk_div6_divisors[64] = { 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 }; -static struct clk_div_mult_table sh_clk_div6_table = { +static struct clk_div_mult_table div6_div_mult_table = { .divisors = sh_clk_div6_divisors, .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), }; +static struct clk_div_table sh_clk_div6_table = { + .div_mult_table = &div6_div_mult_table, +}; + static unsigned long sh_clk_div6_recalc(struct clk *clk) { - struct clk_div_mult_table *table = &sh_clk_div6_table; + struct clk_div_mult_table *table = clk_to_div_mult_table(clk); unsigned int idx; clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, @@ -98,7 +118,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) { - struct clk_div_mult_table *table = &sh_clk_div6_table; + struct clk_div_mult_table *table = clk_to_div_mult_table(clk); u32 value; int ret, i; @@ -223,7 +243,8 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, { struct clk *clkp; void *freq_table; - int nr_divs = sh_clk_div6_table.nr_divisors; + struct clk_div_table *table = &sh_clk_div6_table; + int nr_divs = table->div_mult_table->nr_divisors; int freq_table_size = sizeof(struct cpufreq_frequency_table); int ret = 0; int k; @@ -239,6 +260,7 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, clkp = clks + k; clkp->ops = ops; + clkp->priv = table; clkp->freq_table = freq_table + (k * freq_table_size); clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; ret = clk_register(clkp); @@ -262,10 +284,12 @@ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) &sh_clk_div6_reparent_clk_ops); } +/* + * div4 support + */ static unsigned long sh_clk_div4_recalc(struct clk *clk) { - struct clk_div4_table *d4t = clk->priv; - struct clk_div_mult_table *table = d4t->div_mult_table; + struct clk_div_mult_table *table = clk_to_div_mult_table(clk); unsigned int idx; clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, @@ -278,8 +302,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) { - struct clk_div4_table *d4t = clk->priv; - struct clk_div_mult_table *table = d4t->div_mult_table; + struct clk_div_mult_table *table = clk_to_div_mult_table(clk); u32 value; int ret; @@ -308,7 +331,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) { - struct clk_div4_table *d4t = clk->priv; + struct clk_div_table *dt = clk_to_div_table(clk); unsigned long value; int idx = clk_rate_table_find(clk, clk->freq_table, rate); if (idx < 0) @@ -319,8 +342,9 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) value |= (idx << clk->enable_bit); sh_clk_write(value, clk); - if (d4t->kick) - d4t->kick(clk); + /* XXX: Should use a post-change notifier */ + if (dt->kick) + dt->kick(clk); return 0; } diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index c513b73cd7cb..706b803df7b7 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -18,7 +18,6 @@ struct clk_mapping { struct kref ref; }; - struct sh_clk_ops { #ifdef CONFIG_SH_CLK_CPG_LEGACY void (*init)(struct clk *clk); @@ -149,11 +148,13 @@ static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr) .flags = _flags, \ } -struct clk_div4_table { +struct clk_div_table { struct clk_div_mult_table *div_mult_table; void (*kick)(struct clk *clk); }; +#define clk_div4_table clk_div_table + int sh_clk_div4_register(struct clk *clks, int nr, struct clk_div4_table *table); int sh_clk_div4_enable_register(struct clk *clks, int nr, -- GitLab From 1111cc1e8080b5ff46f5b945acb2f99d6176b2d1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 15:21:43 +0900 Subject: [PATCH 0037/6849] sh: clkfwk: Introduce a div_mask for variable div types. This plugs in a div_mask for the clock and sets it up for the existing div6/4 cases. This will make it possible to support other div types, as well as share more div6/4 infrastructure. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 10 +++++----- include/linux/sh_clk.h | 8 ++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 9dea32907795..9386bd21c003 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -111,7 +111,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, table, NULL); - idx = sh_clk_read(clk) & 0x003f; + idx = sh_clk_read(clk) & clk->div_mask; return clk->freq_table[idx].frequency; } @@ -159,7 +159,7 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) return idx; value = sh_clk_read(clk); - value &= ~0x3f; + value &= ~clk->div_mask; value |= idx; sh_clk_write(value, clk); return 0; @@ -185,7 +185,7 @@ static void sh_clk_div6_disable(struct clk *clk) value = sh_clk_read(clk); value |= 0x100; /* stop clock */ - value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ + value |= clk->div_mask; /* VDIV bits must be non-zero, overwrite divider */ sh_clk_write(value, clk); } @@ -295,7 +295,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, table, &clk->arch_flags); - idx = (sh_clk_read(clk) >> clk->enable_bit) & 0x000f; + idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask; return clk->freq_table[idx].frequency; } @@ -338,7 +338,7 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) return idx; value = sh_clk_read(clk); - value &= ~(0xf << clk->enable_bit); + value &= ~(clk->div_mask << clk->enable_bit); value |= (idx << clk->enable_bit); sh_clk_write(value, clk); diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 706b803df7b7..d540b8153178 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -30,6 +30,10 @@ struct sh_clk_ops { long (*round_rate)(struct clk *clk, unsigned long rate); }; +#define SH_CLK_DIV_MSK(div) ((1 << (div)) - 1) +#define SH_CLK_DIV4_MSK SH_CLK_DIV_MSK(4) +#define SH_CLK_DIV6_MSK SH_CLK_DIV_MSK(6) + struct clk { struct list_head node; struct clk *parent; @@ -51,6 +55,7 @@ struct clk { unsigned int enable_bit; void __iomem *mapped_reg; + unsigned int div_mask; unsigned long arch_flags; void *priv; struct clk_mapping *mapping; @@ -145,6 +150,7 @@ static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr) .enable_reg = (void __iomem *)_reg, \ .enable_bit = _shift, \ .arch_flags = _div_bitmap, \ + .div_mask = SH_CLK_DIV4_MSK, \ .flags = _flags, \ } @@ -167,6 +173,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, { \ .enable_reg = (void __iomem *)_reg, \ .flags = _flags, \ + .div_mask = SH_CLK_DIV6_MSK, \ .parent_table = _parents, \ .parent_num = _num_parents, \ .src_shift = _src_shift, \ @@ -177,6 +184,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, { \ .parent = _parent, \ .enable_reg = (void __iomem *)_reg, \ + .div_mask = SH_CLK_DIV6_MSK, \ .flags = _flags, \ } -- GitLab From 75f5f8a56e0fdf6d32b3ae9c44c10bc0acd3857c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 15:26:01 +0900 Subject: [PATCH 0038/6849] sh: clkfwk: Use shared sh_clk_div_recalc(). This generalizes the div4 recalc routine for use by div6 and others, then makes it the default. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 62 ++++++++++++++++++------------------------ include/linux/sh_clk.h | 2 ++ 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 9386bd21c003..84aeeb8fe013 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -66,11 +66,6 @@ int __init sh_clk_mstp_register(struct clk *clks, int nr) return ret; } -static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) -{ - return clk_rate_table_round(clk, clk->freq_table, rate); -} - /* * Div/mult table lookup helpers */ @@ -84,6 +79,27 @@ static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk) return clk_to_div_table(clk)->div_mult_table; } +/* + * Common div ops + */ +static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) +{ + return clk_rate_table_round(clk, clk->freq_table, rate); +} + +static unsigned long sh_clk_div_recalc(struct clk *clk) +{ + struct clk_div_mult_table *table = clk_to_div_mult_table(clk); + unsigned int idx; + + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, + table, clk->arch_flags ? &clk->arch_flags : NULL); + + idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask; + + return clk->freq_table[idx].frequency; +} + /* * div6 support */ @@ -103,19 +119,6 @@ static struct clk_div_table sh_clk_div6_table = { .div_mult_table = &div6_div_mult_table, }; -static unsigned long sh_clk_div6_recalc(struct clk *clk) -{ - struct clk_div_mult_table *table = clk_to_div_mult_table(clk); - unsigned int idx; - - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, NULL); - - idx = sh_clk_read(clk) & clk->div_mask; - - return clk->freq_table[idx].frequency; -} - static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) { struct clk_div_mult_table *table = clk_to_div_mult_table(clk); @@ -190,7 +193,7 @@ static void sh_clk_div6_disable(struct clk *clk) } static struct sh_clk_ops sh_clk_div6_clk_ops = { - .recalc = sh_clk_div6_recalc, + .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, .set_rate = sh_clk_div6_set_rate, .enable = sh_clk_div6_enable, @@ -198,7 +201,7 @@ static struct sh_clk_ops sh_clk_div6_clk_ops = { }; static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { - .recalc = sh_clk_div6_recalc, + .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, .set_rate = sh_clk_div6_set_rate, .enable = sh_clk_div6_enable, @@ -287,19 +290,6 @@ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) /* * div4 support */ -static unsigned long sh_clk_div4_recalc(struct clk *clk) -{ - struct clk_div_mult_table *table = clk_to_div_mult_table(clk); - unsigned int idx; - - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, &clk->arch_flags); - - idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask; - - return clk->freq_table[idx].frequency; -} - static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) { struct clk_div_mult_table *table = clk_to_div_mult_table(clk); @@ -361,13 +351,13 @@ static void sh_clk_div4_disable(struct clk *clk) } static struct sh_clk_ops sh_clk_div4_clk_ops = { - .recalc = sh_clk_div4_recalc, + .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div4_set_rate, .round_rate = sh_clk_div_round_rate, }; static struct sh_clk_ops sh_clk_div4_enable_clk_ops = { - .recalc = sh_clk_div4_recalc, + .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div4_set_rate, .round_rate = sh_clk_div_round_rate, .enable = sh_clk_div4_enable, @@ -375,7 +365,7 @@ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = { }; static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { - .recalc = sh_clk_div4_recalc, + .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div4_set_rate, .round_rate = sh_clk_div_round_rate, .enable = sh_clk_div4_enable, diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index d540b8153178..35a04f19fb53 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -172,6 +172,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, _num_parents, _src_shift, _src_width) \ { \ .enable_reg = (void __iomem *)_reg, \ + .enable_bit = 0, /* unused */ \ .flags = _flags, \ .div_mask = SH_CLK_DIV6_MSK, \ .parent_table = _parents, \ @@ -184,6 +185,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, { \ .parent = _parent, \ .enable_reg = (void __iomem *)_reg, \ + .enable_bit = 0, /* unused */ \ .div_mask = SH_CLK_DIV6_MSK, \ .flags = _flags, \ } -- GitLab From 0fa22168e00106797f28b2655aaefd0d16a6e67b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 15:52:10 +0900 Subject: [PATCH 0039/6849] sh: clkfwk: Use shared sh_clk_div_set_rate() Follows the sh_clk_div_recalc() change. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 70 ++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 84aeeb8fe013..29ee5f7072a4 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -100,6 +100,28 @@ static unsigned long sh_clk_div_recalc(struct clk *clk) return clk->freq_table[idx].frequency; } +static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk_div_table *dt = clk_to_div_table(clk); + unsigned long value; + int idx; + + idx = clk_rate_table_find(clk, clk->freq_table, rate); + if (idx < 0) + return idx; + + value = sh_clk_read(clk); + value &= ~(clk->div_mask << clk->enable_bit); + value |= (idx << clk->enable_bit); + sh_clk_write(value, clk); + + /* XXX: Should use a post-change notifier */ + if (dt->kick) + dt->kick(clk); + + return 0; +} + /* * div6 support */ @@ -152,28 +174,12 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) return 0; } -static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long value; - int idx; - - idx = clk_rate_table_find(clk, clk->freq_table, rate); - if (idx < 0) - return idx; - - value = sh_clk_read(clk); - value &= ~clk->div_mask; - value |= idx; - sh_clk_write(value, clk); - return 0; -} - static int sh_clk_div6_enable(struct clk *clk) { unsigned long value; int ret; - ret = sh_clk_div6_set_rate(clk, clk->rate); + ret = sh_clk_div_set_rate(clk, clk->rate); if (ret == 0) { value = sh_clk_read(clk); value &= ~0x100; /* clear stop bit to enable clock */ @@ -195,7 +201,7 @@ static void sh_clk_div6_disable(struct clk *clk) static struct sh_clk_ops sh_clk_div6_clk_ops = { .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, - .set_rate = sh_clk_div6_set_rate, + .set_rate = sh_clk_div_set_rate, .enable = sh_clk_div6_enable, .disable = sh_clk_div6_disable, }; @@ -203,7 +209,7 @@ static struct sh_clk_ops sh_clk_div6_clk_ops = { static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, - .set_rate = sh_clk_div6_set_rate, + .set_rate = sh_clk_div_set_rate, .enable = sh_clk_div6_enable, .disable = sh_clk_div6_disable, .set_parent = sh_clk_div6_set_parent, @@ -319,26 +325,6 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) return 0; } -static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) -{ - struct clk_div_table *dt = clk_to_div_table(clk); - unsigned long value; - int idx = clk_rate_table_find(clk, clk->freq_table, rate); - if (idx < 0) - return idx; - - value = sh_clk_read(clk); - value &= ~(clk->div_mask << clk->enable_bit); - value |= (idx << clk->enable_bit); - sh_clk_write(value, clk); - - /* XXX: Should use a post-change notifier */ - if (dt->kick) - dt->kick(clk); - - return 0; -} - static int sh_clk_div4_enable(struct clk *clk) { sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk); @@ -352,13 +338,13 @@ static void sh_clk_div4_disable(struct clk *clk) static struct sh_clk_ops sh_clk_div4_clk_ops = { .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div4_set_rate, + .set_rate = sh_clk_div_set_rate, .round_rate = sh_clk_div_round_rate, }; static struct sh_clk_ops sh_clk_div4_enable_clk_ops = { .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div4_set_rate, + .set_rate = sh_clk_div_set_rate, .round_rate = sh_clk_div_round_rate, .enable = sh_clk_div4_enable, .disable = sh_clk_div4_disable, @@ -366,7 +352,7 @@ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = { static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div4_set_rate, + .set_rate = sh_clk_div_set_rate, .round_rate = sh_clk_div_round_rate, .enable = sh_clk_div4_enable, .disable = sh_clk_div4_disable, -- GitLab From 764f4e4e33d18cde4dcaf8a0d860b749c6d6d08b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 16:34:48 +0900 Subject: [PATCH 0040/6849] sh: clkfwk: Use shared sh_clk_div_enable/disable(). This introduces a new flag for clocks that need to have their divisor ratio set back to their initial mask at disable time to prevent interactivity problems with the clock stop bit (presently div6 only). With this in place it's possible to handle the corner case on top of the div4 op without any particular need for leaving things split out. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 77 +++++++++++++++++++----------------------- include/linux/sh_clk.h | 6 ++-- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 29ee5f7072a4..06537f2b2fb8 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -14,6 +14,8 @@ #include #include +#define CPG_CKSTP_BIT BIT(8) + static unsigned int sh_clk_read(struct clk *clk) { if (clk->flags & CLK_ENABLE_REG_8BIT) @@ -122,6 +124,30 @@ static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate) return 0; } +static int sh_clk_div_enable(struct clk *clk) +{ + sh_clk_write(sh_clk_read(clk) & ~CPG_CKSTP_BIT, clk); + return 0; +} + +static void sh_clk_div_disable(struct clk *clk) +{ + unsigned int val; + + val = sh_clk_read(clk); + val |= CPG_CKSTP_BIT; + + /* + * div6 clocks require the divisor field to be non-zero or the + * above CKSTP toggle silently fails. Ensure that the divisor + * array is reset to its initial state on disable. + */ + if (clk->flags & CLK_MASK_DIV_ON_DISABLE) + val |= clk->div_mask; + + sh_clk_write(val, clk); +} + /* * div6 support */ @@ -174,44 +200,20 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) return 0; } -static int sh_clk_div6_enable(struct clk *clk) -{ - unsigned long value; - int ret; - - ret = sh_clk_div_set_rate(clk, clk->rate); - if (ret == 0) { - value = sh_clk_read(clk); - value &= ~0x100; /* clear stop bit to enable clock */ - sh_clk_write(value, clk); - } - return ret; -} - -static void sh_clk_div6_disable(struct clk *clk) -{ - unsigned long value; - - value = sh_clk_read(clk); - value |= 0x100; /* stop clock */ - value |= clk->div_mask; /* VDIV bits must be non-zero, overwrite divider */ - sh_clk_write(value, clk); -} - static struct sh_clk_ops sh_clk_div6_clk_ops = { .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, .set_rate = sh_clk_div_set_rate, - .enable = sh_clk_div6_enable, - .disable = sh_clk_div6_disable, + .enable = sh_clk_div_enable, + .disable = sh_clk_div_disable, }; static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, .set_rate = sh_clk_div_set_rate, - .enable = sh_clk_div6_enable, - .disable = sh_clk_div6_disable, + .enable = sh_clk_div_enable, + .disable = sh_clk_div_disable, .set_parent = sh_clk_div6_set_parent, }; @@ -325,17 +327,6 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) return 0; } -static int sh_clk_div4_enable(struct clk *clk) -{ - sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk); - return 0; -} - -static void sh_clk_div4_disable(struct clk *clk) -{ - sh_clk_write(sh_clk_read(clk) | (1 << 8), clk); -} - static struct sh_clk_ops sh_clk_div4_clk_ops = { .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div_set_rate, @@ -346,16 +337,16 @@ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = { .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div_set_rate, .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div4_enable, - .disable = sh_clk_div4_disable, + .enable = sh_clk_div_enable, + .disable = sh_clk_div_disable, }; static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div_set_rate, .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div4_enable, - .disable = sh_clk_div4_disable, + .enable = sh_clk_div_enable, + .disable = sh_clk_div_disable, .set_parent = sh_clk_div4_set_parent, }; diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 35a04f19fb53..50910913b268 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -69,6 +69,8 @@ struct clk { #define CLK_ENABLE_REG_16BIT BIT(2) #define CLK_ENABLE_REG_8BIT BIT(3) +#define CLK_MASK_DIV_ON_DISABLE BIT(4) + #define CLK_ENABLE_REG_MASK (CLK_ENABLE_REG_32BIT | \ CLK_ENABLE_REG_16BIT | \ CLK_ENABLE_REG_8BIT) @@ -173,7 +175,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, { \ .enable_reg = (void __iomem *)_reg, \ .enable_bit = 0, /* unused */ \ - .flags = _flags, \ + .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ .div_mask = SH_CLK_DIV6_MSK, \ .parent_table = _parents, \ .parent_num = _num_parents, \ @@ -187,7 +189,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr, .enable_reg = (void __iomem *)_reg, \ .enable_bit = 0, /* unused */ \ .div_mask = SH_CLK_DIV6_MSK, \ - .flags = _flags, \ + .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ } int sh_clk_div6_register(struct clk *clks, int nr); -- GitLab From e3c87607731e1a8937567e92a52eedee1bec622d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 16:43:42 +0900 Subject: [PATCH 0041/6849] sh: clkfwk: Consolidate div6/div4 clk_ops definitions. Everything with the exception of the _reparent ops are now shared, so switch everything over to common types. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 06537f2b2fb8..eeaec796a395 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -148,6 +148,20 @@ static void sh_clk_div_disable(struct clk *clk) sh_clk_write(val, clk); } +static struct sh_clk_ops sh_clk_div_clk_ops = { + .recalc = sh_clk_div_recalc, + .set_rate = sh_clk_div_set_rate, + .round_rate = sh_clk_div_round_rate, +}; + +static struct sh_clk_ops sh_clk_div_enable_clk_ops = { + .recalc = sh_clk_div_recalc, + .set_rate = sh_clk_div_set_rate, + .round_rate = sh_clk_div_round_rate, + .enable = sh_clk_div_enable, + .disable = sh_clk_div_disable, +}; + /* * div6 support */ @@ -200,14 +214,6 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) return 0; } -static struct sh_clk_ops sh_clk_div6_clk_ops = { - .recalc = sh_clk_div_recalc, - .round_rate = sh_clk_div_round_rate, - .set_rate = sh_clk_div_set_rate, - .enable = sh_clk_div_enable, - .disable = sh_clk_div_disable, -}; - static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { .recalc = sh_clk_div_recalc, .round_rate = sh_clk_div_round_rate, @@ -286,7 +292,7 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, int __init sh_clk_div6_register(struct clk *clks, int nr) { - return sh_clk_div6_register_ops(clks, nr, &sh_clk_div6_clk_ops); + return sh_clk_div6_register_ops(clks, nr, &sh_clk_div_enable_clk_ops); } int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) @@ -327,20 +333,6 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) return 0; } -static struct sh_clk_ops sh_clk_div4_clk_ops = { - .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div_set_rate, - .round_rate = sh_clk_div_round_rate, -}; - -static struct sh_clk_ops sh_clk_div4_enable_clk_ops = { - .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div_set_rate, - .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div_enable, - .disable = sh_clk_div_disable, -}; - static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { .recalc = sh_clk_div_recalc, .set_rate = sh_clk_div_set_rate, @@ -385,14 +377,14 @@ static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, int __init sh_clk_div4_register(struct clk *clks, int nr, struct clk_div4_table *table) { - return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops); + return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div_clk_ops); } int __init sh_clk_div4_enable_register(struct clk *clks, int nr, struct clk_div4_table *table) { return sh_clk_div4_register_ops(clks, nr, table, - &sh_clk_div4_enable_clk_ops); + &sh_clk_div_enable_clk_ops); } int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, -- GitLab From 609d7558f232e583a31951c65a6ee43d81c65720 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 16:55:05 +0900 Subject: [PATCH 0042/6849] sh: clkfwk: Consolidate div clk registration helper. This consolidates the div6/4 versions of the clk registration wrapper. The existing wrappers with their own sh_clk_ops are maintained for API compatability, though in the future it should be possible to be rid of them entirely. Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 182 ++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 107 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index eeaec796a395..07e9fb4f8041 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -162,6 +162,72 @@ static struct sh_clk_ops sh_clk_div_enable_clk_ops = { .disable = sh_clk_div_disable, }; +static int __init sh_clk_init_parent(struct clk *clk) +{ + u32 val; + + if (clk->parent) + return 0; + + if (!clk->parent_table || !clk->parent_num) + return 0; + + if (!clk->src_width) { + pr_err("sh_clk_init_parent: cannot select parent clock\n"); + return -EINVAL; + } + + val = (sh_clk_read(clk) >> clk->src_shift); + val &= (1 << clk->src_width) - 1; + + if (val >= clk->parent_num) { + pr_err("sh_clk_init_parent: parent table size failed\n"); + return -EINVAL; + } + + clk_reparent(clk, clk->parent_table[val]); + if (!clk->parent) { + pr_err("sh_clk_init_parent: unable to set parent"); + return -EINVAL; + } + + return 0; +} + +static int __init sh_clk_div_register_ops(struct clk *clks, int nr, + struct clk_div_table *table, struct sh_clk_ops *ops) +{ + struct clk *clkp; + void *freq_table; + int nr_divs = table->div_mult_table->nr_divisors; + int freq_table_size = sizeof(struct cpufreq_frequency_table); + int ret = 0; + int k; + + freq_table_size *= (nr_divs + 1); + freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); + if (!freq_table) { + pr_err("%s: unable to alloc memory\n", __func__); + return -ENOMEM; + } + + for (k = 0; !ret && (k < nr); k++) { + clkp = clks + k; + + clkp->ops = ops; + clkp->priv = table; + + clkp->freq_table = freq_table + (k * freq_table_size); + clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; + + ret = clk_register(clkp); + if (ret == 0) + ret = sh_clk_init_parent(clkp); + } + + return ret; +} + /* * div6 support */ @@ -223,82 +289,16 @@ static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { .set_parent = sh_clk_div6_set_parent, }; -static int __init sh_clk_init_parent(struct clk *clk) -{ - u32 val; - - if (clk->parent) - return 0; - - if (!clk->parent_table || !clk->parent_num) - return 0; - - if (!clk->src_width) { - pr_err("sh_clk_init_parent: cannot select parent clock\n"); - return -EINVAL; - } - - val = (sh_clk_read(clk) >> clk->src_shift); - val &= (1 << clk->src_width) - 1; - - if (val >= clk->parent_num) { - pr_err("sh_clk_init_parent: parent table size failed\n"); - return -EINVAL; - } - - clk_reparent(clk, clk->parent_table[val]); - if (!clk->parent) { - pr_err("sh_clk_init_parent: unable to set parent"); - return -EINVAL; - } - - return 0; -} - -static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, - struct sh_clk_ops *ops) -{ - struct clk *clkp; - void *freq_table; - struct clk_div_table *table = &sh_clk_div6_table; - int nr_divs = table->div_mult_table->nr_divisors; - int freq_table_size = sizeof(struct cpufreq_frequency_table); - int ret = 0; - int k; - - freq_table_size *= (nr_divs + 1); - freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); - if (!freq_table) { - pr_err("sh_clk_div6_register: unable to alloc memory\n"); - return -ENOMEM; - } - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - - clkp->ops = ops; - clkp->priv = table; - clkp->freq_table = freq_table + (k * freq_table_size); - clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; - ret = clk_register(clkp); - if (ret < 0) - break; - - ret = sh_clk_init_parent(clkp); - } - - return ret; -} - int __init sh_clk_div6_register(struct clk *clks, int nr) { - return sh_clk_div6_register_ops(clks, nr, &sh_clk_div_enable_clk_ops); + return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, + &sh_clk_div_enable_clk_ops); } int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) { - return sh_clk_div6_register_ops(clks, nr, - &sh_clk_div6_reparent_clk_ops); + return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, + &sh_clk_div6_reparent_clk_ops); } /* @@ -342,54 +342,22 @@ static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { .set_parent = sh_clk_div4_set_parent, }; -static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, - struct clk_div4_table *table, struct sh_clk_ops *ops) -{ - struct clk *clkp; - void *freq_table; - int nr_divs = table->div_mult_table->nr_divisors; - int freq_table_size = sizeof(struct cpufreq_frequency_table); - int ret = 0; - int k; - - freq_table_size *= (nr_divs + 1); - freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); - if (!freq_table) { - pr_err("sh_clk_div4_register: unable to alloc memory\n"); - return -ENOMEM; - } - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - - clkp->ops = ops; - clkp->priv = table; - - clkp->freq_table = freq_table + (k * freq_table_size); - clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; - - ret = clk_register(clkp); - } - - return ret; -} - int __init sh_clk_div4_register(struct clk *clks, int nr, struct clk_div4_table *table) { - return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div_clk_ops); + return sh_clk_div_register_ops(clks, nr, table, &sh_clk_div_clk_ops); } int __init sh_clk_div4_enable_register(struct clk *clks, int nr, struct clk_div4_table *table) { - return sh_clk_div4_register_ops(clks, nr, table, - &sh_clk_div_enable_clk_ops); + return sh_clk_div_register_ops(clks, nr, table, + &sh_clk_div_enable_clk_ops); } int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, struct clk_div4_table *table) { - return sh_clk_div4_register_ops(clks, nr, table, - &sh_clk_div4_reparent_clk_ops); + return sh_clk_div_register_ops(clks, nr, table, + &sh_clk_div4_reparent_clk_ops); } -- GitLab From 423b9788023263364ea5de04189f02bd9b6a12db Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 21 May 2012 12:32:13 +0100 Subject: [PATCH 0043/6849] KEYS: Fix some sparse warnings Fix some sparse warnings in the keyrings code: (1) compat_keyctl_instantiate_key_iov() should be static. (2) There were a couple of places where a pointer was being compared against integer 0 rather than NULL. (3) keyctl_instantiate_key_common() should not take a __user-labelled iovec pointer as the caller must have copied the iovec to kernel space. (4) __key_link_begin() takes and __key_link_end() releases keyring_serialise_link_sem under some circumstances and so this should be declared. Note that adding __acquires() and __releases() for this doesn't help cure the warnings messages - something only commenting out both helps. Signed-off-by: David Howells Signed-off-by: James Morris --- security/keys/compat.c | 4 ++-- security/keys/internal.h | 2 +- security/keys/keyctl.c | 2 +- security/keys/keyring.c | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/security/keys/compat.c b/security/keys/compat.c index fab4f8dda6c6..e35ae1d208a8 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c @@ -24,7 +24,7 @@ * * If successful, 0 will be returned. */ -long compat_keyctl_instantiate_key_iov( +static long compat_keyctl_instantiate_key_iov( key_serial_t id, const struct compat_iovec __user *_payload_iov, unsigned ioc, @@ -33,7 +33,7 @@ long compat_keyctl_instantiate_key_iov( struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; long ret; - if (_payload_iov == 0 || ioc == 0) + if (!_payload_iov || !ioc) goto no_payload; ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, diff --git a/security/keys/internal.h b/security/keys/internal.h index f711b094ed41..f173be2ce3ea 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -240,7 +240,7 @@ extern long keyctl_instantiate_key_iov(key_serial_t, extern long keyctl_invalidate_key(key_serial_t); extern long keyctl_instantiate_key_common(key_serial_t, - const struct iovec __user *, + const struct iovec *, unsigned, size_t, key_serial_t); /* diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index ddb3e05bc5fc..b61c063888b9 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1106,7 +1106,7 @@ long keyctl_instantiate_key_iov(key_serial_t id, struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; long ret; - if (_payload_iov == 0 || ioc == 0) + if (!_payload_iov || !ioc) goto no_payload; ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 7445875f6818..81e7852d281d 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -751,6 +751,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) int __key_link_begin(struct key *keyring, const struct key_type *type, const char *description, unsigned long *_prealloc) __acquires(&keyring->sem) + __acquires(&keyring_serialise_link_sem) { struct keyring_list *klist, *nklist; unsigned long prealloc; @@ -960,6 +961,7 @@ void __key_link(struct key *keyring, struct key *key, void __key_link_end(struct key *keyring, struct key_type *type, unsigned long prealloc) __releases(&keyring->sem) + __releases(&keyring_serialise_link_sem) { BUG_ON(type == NULL); BUG_ON(type->name == NULL); -- GitLab From 7fe99e2d434eafeac0c57b279a77e5de39212636 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 25 May 2012 11:29:30 -0700 Subject: [PATCH 0044/6849] openvswitch: Reset upper layer protocol info on internal devices. It's possible that packets that are sent on internal devices (from the OVS perspective) have already traversed the local IP stack. After they go through the internal device, they will again travel through the IP stack which may get confused by the presence of existing information in the skb. The problem can be observed when switching between namespaces. This clears out that information to avoid problems but deliberately leaves other metadata alone. This is to provide maximum flexibility in chaining together OVS and other Linux components. Signed-off-by: Jesse Gross --- net/openvswitch/vport-internal_dev.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index de509d347112..4061b9ee07f7 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -24,6 +24,9 @@ #include #include +#include +#include + #include "datapath.h" #include "vport-internal_dev.h" #include "vport-netdev.h" @@ -209,6 +212,11 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) int len; len = skb->len; + + skb_dst_drop(skb); + nf_reset(skb); + secpath_reset(skb); + skb->dev = netdev; skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, netdev); -- GitLab From 00633d7c7a0243940fc616bee573bcf497db79b9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 4 Jan 2012 15:33:17 -0800 Subject: [PATCH 0045/6849] ARM: OMAP3: clock data: cleanup AM3[35]x SoC detection Use the more generic SoC family soc_is_am35xx() instead of the specific cpu_is_omap3517() (which is being removed.) Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Tested-by: Mark A. Greer Cc: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 4e1a3b0e8cc8..1efdec236ae8 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3514,7 +3514,7 @@ int __init omap3xxx_clk_init(void) struct omap_clk *c; u32 cpu_clkflg = 0; - if (cpu_is_omap3517()) { + if (soc_is_am35xx()) { cpu_mask = RATE_IN_34XX; cpu_clkflg = CK_AM35XX; } else if (cpu_is_omap3630()) { -- GitLab From 96f3994929c05a21d757a83613d2710b780ea2b4 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 11 May 2012 16:38:11 -0700 Subject: [PATCH 0046/6849] ARM: OMAP: SoC detection: remove unused cpu_is macros Remove multiple unused cpu_is_omap35xx macros. In particular, the cpu_is_omap35* macros for 3503, 3515, 3525 are removed because they are using omap_has_* feature checks and we want to remove specific feature detection from SoC family detection. There are no longer any cpu_is_* checks that depend on specific IP detection. Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Tested-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/include/plat/cpu.h | 33 --------------------------- 1 file changed, 33 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 4bdf14ec6747..0f8a201cee68 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -250,8 +250,6 @@ IS_AM_SUBCLASS(335x, 0x335) * cpu_is_omap2423(): True for OMAP2423 * cpu_is_omap2430(): True for OMAP2430 * cpu_is_omap3430(): True for OMAP3430 - * cpu_is_omap3505(): True for OMAP3505 - * cpu_is_omap3517(): True for OMAP3517 */ #define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff) @@ -275,8 +273,6 @@ IS_OMAP_TYPE(2422, 0x2422) IS_OMAP_TYPE(2423, 0x2423) IS_OMAP_TYPE(2430, 0x2430) IS_OMAP_TYPE(3430, 0x3430) -IS_OMAP_TYPE(3505, 0x3517) -IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap310() 0 #define cpu_is_omap730() 0 @@ -291,12 +287,6 @@ IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap2422() 0 #define cpu_is_omap2423() 0 #define cpu_is_omap2430() 0 -#define cpu_is_omap3503() 0 -#define cpu_is_omap3515() 0 -#define cpu_is_omap3525() 0 -#define cpu_is_omap3530() 0 -#define cpu_is_omap3505() 0 -#define cpu_is_omap3517() 0 #define cpu_is_omap3430() 0 #define cpu_is_omap3630() 0 @@ -348,31 +338,12 @@ IS_OMAP_TYPE(3517, 0x3517) #if defined(CONFIG_ARCH_OMAP3) # undef cpu_is_omap3430 -# undef cpu_is_omap3503 -# undef cpu_is_omap3515 -# undef cpu_is_omap3525 -# undef cpu_is_omap3530 -# undef cpu_is_omap3505 -# undef cpu_is_omap3517 # undef cpu_is_ti81xx # undef cpu_is_ti816x # undef cpu_is_ti814x # undef cpu_is_am33xx # undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() -# define cpu_is_omap3503() (cpu_is_omap3430() && \ - (!omap3_has_iva()) && \ - (!omap3_has_sgx())) -# define cpu_is_omap3515() (cpu_is_omap3430() && \ - (!omap3_has_iva()) && \ - (omap3_has_sgx())) -# define cpu_is_omap3525() (cpu_is_omap3430() && \ - (!omap3_has_sgx()) && \ - (omap3_has_iva())) -# define cpu_is_omap3530() (cpu_is_omap3430()) -# define cpu_is_omap3517() is_omap3517() -# define cpu_is_omap3505() (cpu_is_omap3517() && \ - !omap3_has_sgx()) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti81xx() is_ti81xx() @@ -420,10 +391,6 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8)) #define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8)) -#define OMAP3517_CLASS 0x35170034 -#define OMAP3517_REV_ES1_0 OMAP3517_CLASS -#define OMAP3517_REV_ES1_1 (OMAP3517_CLASS | (0x1 << 8)) - #define TI816X_CLASS 0x81600034 #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) -- GitLab From 9e235dcaf4f63d88a7e9ce5735ba5c2eb2719603 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 9 May 2012 17:37:55 +0300 Subject: [PATCH 0047/6849] Revert "crypto: GnuPG based MPI lib - additional sources (part 4)" This reverts commit 7e8dec918ef8e0f68b4937c3c50fa57002077a4d. RSA verification implementation does not use this code. James Morris has asked to remove that. Signed-off-by: Dmitry Kasatkin Requested-by: James Morris Signed-off-by: James Morris --- lib/Kconfig | 8 - lib/mpi/Makefile | 11 -- lib/mpi/generic_mpi-asm-defs.h | 4 - lib/mpi/mpi-add.c | 234 ----------------------- lib/mpi/mpi-cmp.c | 68 ------- lib/mpi/mpi-div.c | 338 --------------------------------- lib/mpi/mpi-gcd.c | 59 ------ lib/mpi/mpi-inline.c | 31 --- lib/mpi/mpi-inv.c | 187 ------------------ lib/mpi/mpi-mpow.c | 134 ------------- lib/mpi/mpi-mul.c | 194 ------------------- lib/mpi/mpi-scan.c | 136 ------------- 12 files changed, 1404 deletions(-) delete mode 100644 lib/mpi/generic_mpi-asm-defs.h delete mode 100644 lib/mpi/mpi-add.c delete mode 100644 lib/mpi/mpi-cmp.c delete mode 100644 lib/mpi/mpi-div.c delete mode 100644 lib/mpi/mpi-gcd.c delete mode 100644 lib/mpi/mpi-inline.c delete mode 100644 lib/mpi/mpi-inv.c delete mode 100644 lib/mpi/mpi-mpow.c delete mode 100644 lib/mpi/mpi-mul.c delete mode 100644 lib/mpi/mpi-scan.c diff --git a/lib/Kconfig b/lib/Kconfig index 4a8aba2e5cc0..ac9d8d31c4a6 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -361,14 +361,6 @@ config MPILIB It is used to implement RSA digital signature verification, which is used by IMA/EVM digital signature extension. -config MPILIB_EXTRA - bool - depends on MPILIB - help - Additional sources of multiprecision maths library from GnuPG. - This code is unnecessary for RSA digital signature verification, - but can be compiled if needed. - config SIGNATURE tristate depends on KEYS && CRYPTO diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile index 567d52e74d77..45ca90a8639c 100644 --- a/lib/mpi/Makefile +++ b/lib/mpi/Makefile @@ -19,14 +19,3 @@ mpi-y = \ mpih-mul.o \ mpi-pow.o \ mpiutil.o - -mpi-$(CONFIG_MPILIB_EXTRA) += \ - mpi-add.o \ - mpi-div.o \ - mpi-cmp.o \ - mpi-gcd.o \ - mpi-inline.o \ - mpi-inv.o \ - mpi-mpow.o \ - mpi-mul.o \ - mpi-scan.o diff --git a/lib/mpi/generic_mpi-asm-defs.h b/lib/mpi/generic_mpi-asm-defs.h deleted file mode 100644 index 047d1f5a7249..000000000000 --- a/lib/mpi/generic_mpi-asm-defs.h +++ /dev/null @@ -1,4 +0,0 @@ -/* This file defines some basic constants for the MPI machinery. We - * need to define the types on a per-CPU basis, so it is done with - * this file here. */ -#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG) diff --git a/lib/mpi/mpi-add.c b/lib/mpi/mpi-add.c deleted file mode 100644 index f56b9ba295e6..000000000000 --- a/lib/mpi/mpi-add.c +++ /dev/null @@ -1,234 +0,0 @@ -/* mpi-add.c - MPI functions - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * Copyright (C) 1994, 1996 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - * The GNU MP Library itself is published under the LGPL; - * however I decided to publish this code under the plain GPL. - */ - -#include "mpi-internal.h" - -/**************** - * Add the unsigned integer V to the mpi-integer U and store the - * result in W. U and V may be the same. - */ -int mpi_add_ui(MPI w, const MPI u, unsigned long v) -{ - mpi_ptr_t wp, up; - mpi_size_t usize, wsize; - int usign, wsign; - - usize = u->nlimbs; - usign = u->sign; - wsign = 0; - - /* If not space for W (and possible carry), increase space. */ - wsize = usize + 1; - if (w->alloced < wsize) - if (mpi_resize(w, wsize) < 0) - return -ENOMEM; - - /* These must be after realloc (U may be the same as W). */ - up = u->d; - wp = w->d; - - if (!usize) { /* simple */ - wp[0] = v; - wsize = v ? 1 : 0; - } else if (!usign) { /* mpi is not negative */ - mpi_limb_t cy; - cy = mpihelp_add_1(wp, up, usize, v); - wp[usize] = cy; - wsize = usize + cy; - } else { /* The signs are different. Need exact comparison to determine - * which operand to subtract from which. */ - if (usize == 1 && up[0] < v) { - wp[0] = v - up[0]; - wsize = 1; - } else { - mpihelp_sub_1(wp, up, usize, v); - /* Size can decrease with at most one limb. */ - wsize = usize - (wp[usize - 1] == 0); - wsign = 1; - } - } - - w->nlimbs = wsize; - w->sign = wsign; - return 0; -} - -int mpi_add(MPI w, MPI u, MPI v) -{ - mpi_ptr_t wp, up, vp; - mpi_size_t usize, vsize, wsize; - int usign, vsign, wsign; - - if (u->nlimbs < v->nlimbs) { /* Swap U and V. */ - usize = v->nlimbs; - usign = v->sign; - vsize = u->nlimbs; - vsign = u->sign; - wsize = usize + 1; - if (RESIZE_IF_NEEDED(w, wsize) < 0) - return -ENOMEM; - /* These must be after realloc (u or v may be the same as w). */ - up = v->d; - vp = u->d; - } else { - usize = u->nlimbs; - usign = u->sign; - vsize = v->nlimbs; - vsign = v->sign; - wsize = usize + 1; - if (RESIZE_IF_NEEDED(w, wsize) < 0) - return -ENOMEM; - /* These must be after realloc (u or v may be the same as w). */ - up = u->d; - vp = v->d; - } - wp = w->d; - wsign = 0; - - if (!vsize) { /* simple */ - MPN_COPY(wp, up, usize); - wsize = usize; - wsign = usign; - } else if (usign != vsign) { /* different sign */ - /* This test is right since USIZE >= VSIZE */ - if (usize != vsize) { - mpihelp_sub(wp, up, usize, vp, vsize); - wsize = usize; - MPN_NORMALIZE(wp, wsize); - wsign = usign; - } else if (mpihelp_cmp(up, vp, usize) < 0) { - mpihelp_sub_n(wp, vp, up, usize); - wsize = usize; - MPN_NORMALIZE(wp, wsize); - if (!usign) - wsign = 1; - } else { - mpihelp_sub_n(wp, up, vp, usize); - wsize = usize; - MPN_NORMALIZE(wp, wsize); - if (usign) - wsign = 1; - } - } else { /* U and V have same sign. Add them. */ - mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize); - wp[usize] = cy; - wsize = usize + cy; - if (usign) - wsign = 1; - } - - w->nlimbs = wsize; - w->sign = wsign; - return 0; -} - -/**************** - * Subtract the unsigned integer V from the mpi-integer U and store the - * result in W. - */ -int mpi_sub_ui(MPI w, MPI u, unsigned long v) -{ - mpi_ptr_t wp, up; - mpi_size_t usize, wsize; - int usign, wsign; - - usize = u->nlimbs; - usign = u->sign; - wsign = 0; - - /* If not space for W (and possible carry), increase space. */ - wsize = usize + 1; - if (w->alloced < wsize) - if (mpi_resize(w, wsize) < 0) - return -ENOMEM; - - /* These must be after realloc (U may be the same as W). */ - up = u->d; - wp = w->d; - - if (!usize) { /* simple */ - wp[0] = v; - wsize = v ? 1 : 0; - wsign = 1; - } else if (usign) { /* mpi and v are negative */ - mpi_limb_t cy; - cy = mpihelp_add_1(wp, up, usize, v); - wp[usize] = cy; - wsize = usize + cy; - } else { /* The signs are different. Need exact comparison to determine - * which operand to subtract from which. */ - if (usize == 1 && up[0] < v) { - wp[0] = v - up[0]; - wsize = 1; - wsign = 1; - } else { - mpihelp_sub_1(wp, up, usize, v); - /* Size can decrease with at most one limb. */ - wsize = usize - (wp[usize - 1] == 0); - } - } - - w->nlimbs = wsize; - w->sign = wsign; - return 0; -} - -int mpi_sub(MPI w, MPI u, MPI v) -{ - int rc; - - if (w == v) { - MPI vv; - if (mpi_copy(&vv, v) < 0) - return -ENOMEM; - vv->sign = !vv->sign; - rc = mpi_add(w, u, vv); - mpi_free(vv); - } else { - /* fixme: this is not thread-save (we temp. modify v) */ - v->sign = !v->sign; - rc = mpi_add(w, u, v); - v->sign = !v->sign; - } - return rc; -} - -int mpi_addm(MPI w, MPI u, MPI v, MPI m) -{ - if (mpi_add(w, u, v) < 0 || mpi_fdiv_r(w, w, m) < 0) - return -ENOMEM; - return 0; -} - -int mpi_subm(MPI w, MPI u, MPI v, MPI m) -{ - if (mpi_sub(w, u, v) < 0 || mpi_fdiv_r(w, w, m) < 0) - return -ENOMEM; - return 0; -} diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c deleted file mode 100644 index 914bc42a8a80..000000000000 --- a/lib/mpi/mpi-cmp.c +++ /dev/null @@ -1,68 +0,0 @@ -/* mpi-cmp.c - MPI functions - * Copyright (C) 1998, 1999 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "mpi-internal.h" - -int mpi_cmp_ui(MPI u, unsigned long v) -{ - mpi_limb_t limb = v; - - mpi_normalize(u); - if (!u->nlimbs && !limb) - return 0; - if (u->sign) - return -1; - if (u->nlimbs > 1) - return 1; - - if (u->d[0] == limb) - return 0; - else if (u->d[0] > limb) - return 1; - else - return -1; -} - -int mpi_cmp(MPI u, MPI v) -{ - mpi_size_t usize, vsize; - int cmp; - - mpi_normalize(u); - mpi_normalize(v); - usize = u->nlimbs; - vsize = v->nlimbs; - if (!u->sign && v->sign) - return 1; - if (u->sign && !v->sign) - return -1; - if (usize != vsize && !u->sign && !v->sign) - return usize - vsize; - if (usize != vsize && u->sign && v->sign) - return vsize + usize; - if (!usize) - return 0; - cmp = mpihelp_cmp(u->d, v->d, usize); - if (!cmp) - return 0; - if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0)) - return 1; - return -1; -} diff --git a/lib/mpi/mpi-div.c b/lib/mpi/mpi-div.c deleted file mode 100644 index f68cbbb4d4a4..000000000000 --- a/lib/mpi/mpi-div.c +++ /dev/null @@ -1,338 +0,0 @@ -/* mpi-div.c - MPI functions - * Copyright (C) 1994, 1996 Free Software Foundation, Inc. - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - * The GNU MP Library itself is published under the LGPL; - * however I decided to publish this code under the plain GPL. - */ - -#include -#include "mpi-internal.h" -#include "longlong.h" - -int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor) -{ - int rc = -ENOMEM; - int divisor_sign = divisor->sign; - MPI temp_divisor = NULL; - - /* We need the original value of the divisor after the remainder has been - * preliminary calculated. We have to copy it to temporary space if it's - * the same variable as REM. */ - if (rem == divisor) { - if (mpi_copy(&temp_divisor, divisor) < 0) - goto nomem; - divisor = temp_divisor; - } - - if (mpi_tdiv_qr(NULL, rem, dividend, divisor) < 0) - goto nomem; - if (((divisor_sign ? 1 : 0) ^ (dividend->sign ? 1 : 0)) && rem->nlimbs) - if (mpi_add(rem, rem, divisor) < 0) - goto nomem; - - rc = 0; - -nomem: - if (temp_divisor) - mpi_free(temp_divisor); - return rc; -} - -/**************** - * Division rounding the quotient towards -infinity. - * The remainder gets the same sign as the denominator. - * rem is optional - */ - -ulong mpi_fdiv_r_ui(MPI rem, MPI dividend, ulong divisor) -{ - mpi_limb_t rlimb; - - rlimb = mpihelp_mod_1(dividend->d, dividend->nlimbs, divisor); - if (rlimb && dividend->sign) - rlimb = divisor - rlimb; - - if (rem) { - rem->d[0] = rlimb; - rem->nlimbs = rlimb ? 1 : 0; - } - return rlimb; -} - -int mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor) -{ - MPI tmp = mpi_alloc(mpi_get_nlimbs(quot)); - if (!tmp) - return -ENOMEM; - mpi_fdiv_qr(quot, tmp, dividend, divisor); - mpi_free(tmp); - return 0; -} - -int mpi_fdiv_qr(MPI quot, MPI rem, MPI dividend, MPI divisor) -{ - int divisor_sign = divisor->sign; - MPI temp_divisor = NULL; - - if (quot == divisor || rem == divisor) { - if (mpi_copy(&temp_divisor, divisor) < 0) - return -ENOMEM; - divisor = temp_divisor; - } - - if (mpi_tdiv_qr(quot, rem, dividend, divisor) < 0) - goto nomem; - - if ((divisor_sign ^ dividend->sign) && rem->nlimbs) { - if (mpi_sub_ui(quot, quot, 1) < 0) - goto nomem; - if (mpi_add(rem, rem, divisor) < 0) - goto nomem; - } - - if (temp_divisor) - mpi_free(temp_divisor); - - return 0; - -nomem: - mpi_free(temp_divisor); - return -ENOMEM; -} - -/* If den == quot, den needs temporary storage. - * If den == rem, den needs temporary storage. - * If num == quot, num needs temporary storage. - * If den has temporary storage, it can be normalized while being copied, - * i.e no extra storage should be allocated. - */ - -int mpi_tdiv_r(MPI rem, MPI num, MPI den) -{ - return mpi_tdiv_qr(NULL, rem, num, den); -} - -int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) -{ - int rc = -ENOMEM; - mpi_ptr_t np, dp; - mpi_ptr_t qp, rp; - mpi_size_t nsize = num->nlimbs; - mpi_size_t dsize = den->nlimbs; - mpi_size_t qsize, rsize; - mpi_size_t sign_remainder = num->sign; - mpi_size_t sign_quotient = num->sign ^ den->sign; - unsigned normalization_steps; - mpi_limb_t q_limb; - mpi_ptr_t marker[5]; - int markidx = 0; - - if (!dsize) - return -EINVAL; - - memset(marker, 0, sizeof(marker)); - - /* Ensure space is enough for quotient and remainder. - * We need space for an extra limb in the remainder, because it's - * up-shifted (normalized) below. */ - rsize = nsize + 1; - if (mpi_resize(rem, rsize) < 0) - goto nomem; - - qsize = rsize - dsize; /* qsize cannot be bigger than this. */ - if (qsize <= 0) { - if (num != rem) { - rem->nlimbs = num->nlimbs; - rem->sign = num->sign; - MPN_COPY(rem->d, num->d, nsize); - } - if (quot) { - /* This needs to follow the assignment to rem, in case the - * numerator and quotient are the same. */ - quot->nlimbs = 0; - quot->sign = 0; - } - return 0; - } - - if (quot) - if (mpi_resize(quot, qsize) < 0) - goto nomem; - - /* Read pointers here, when reallocation is finished. */ - np = num->d; - dp = den->d; - rp = rem->d; - - /* Optimize division by a single-limb divisor. */ - if (dsize == 1) { - mpi_limb_t rlimb; - if (quot) { - qp = quot->d; - rlimb = mpihelp_divmod_1(qp, np, nsize, dp[0]); - qsize -= qp[qsize - 1] == 0; - quot->nlimbs = qsize; - quot->sign = sign_quotient; - } else - rlimb = mpihelp_mod_1(np, nsize, dp[0]); - rp[0] = rlimb; - rsize = rlimb != 0 ? 1 : 0; - rem->nlimbs = rsize; - rem->sign = sign_remainder; - return 0; - } - - if (quot) { - qp = quot->d; - /* Make sure QP and NP point to different objects. Otherwise the - * numerator would be gradually overwritten by the quotient limbs. */ - if (qp == np) { /* Copy NP object to temporary space. */ - np = marker[markidx++] = mpi_alloc_limb_space(nsize); - if (!np) - goto nomem; - MPN_COPY(np, qp, nsize); - } - } else /* Put quotient at top of remainder. */ - qp = rp + dsize; - - count_leading_zeros(normalization_steps, dp[dsize - 1]); - - /* Normalize the denominator, i.e. make its most significant bit set by - * shifting it NORMALIZATION_STEPS bits to the left. Also shift the - * numerator the same number of steps (to keep the quotient the same!). - */ - if (normalization_steps) { - mpi_ptr_t tp; - mpi_limb_t nlimb; - - /* Shift up the denominator setting the most significant bit of - * the most significant word. Use temporary storage not to clobber - * the original contents of the denominator. */ - tp = marker[markidx++] = mpi_alloc_limb_space(dsize); - if (!tp) - goto nomem; - mpihelp_lshift(tp, dp, dsize, normalization_steps); - dp = tp; - - /* Shift up the numerator, possibly introducing a new most - * significant word. Move the shifted numerator in the remainder - * meanwhile. */ - nlimb = mpihelp_lshift(rp, np, nsize, normalization_steps); - if (nlimb) { - rp[nsize] = nlimb; - rsize = nsize + 1; - } else - rsize = nsize; - } else { - /* The denominator is already normalized, as required. Copy it to - * temporary space if it overlaps with the quotient or remainder. */ - if (dp == rp || (quot && (dp == qp))) { - mpi_ptr_t tp; - - tp = marker[markidx++] = mpi_alloc_limb_space(dsize); - if (!tp) - goto nomem; - MPN_COPY(tp, dp, dsize); - dp = tp; - } - - /* Move the numerator to the remainder. */ - if (rp != np) - MPN_COPY(rp, np, nsize); - - rsize = nsize; - } - - q_limb = mpihelp_divrem(qp, 0, rp, rsize, dp, dsize); - - if (quot) { - qsize = rsize - dsize; - if (q_limb) { - qp[qsize] = q_limb; - qsize += 1; - } - - quot->nlimbs = qsize; - quot->sign = sign_quotient; - } - - rsize = dsize; - MPN_NORMALIZE(rp, rsize); - - if (normalization_steps && rsize) { - mpihelp_rshift(rp, rp, rsize, normalization_steps); - rsize -= rp[rsize - 1] == 0 ? 1 : 0; - } - - rem->nlimbs = rsize; - rem->sign = sign_remainder; - - rc = 0; -nomem: - while (markidx) - mpi_free_limb_space(marker[--markidx]); - return rc; -} - -int mpi_tdiv_q_2exp(MPI w, MPI u, unsigned count) -{ - mpi_size_t usize, wsize; - mpi_size_t limb_cnt; - - usize = u->nlimbs; - limb_cnt = count / BITS_PER_MPI_LIMB; - wsize = usize - limb_cnt; - if (limb_cnt >= usize) - w->nlimbs = 0; - else { - mpi_ptr_t wp; - mpi_ptr_t up; - - if (RESIZE_IF_NEEDED(w, wsize) < 0) - return -ENOMEM; - wp = w->d; - up = u->d; - - count %= BITS_PER_MPI_LIMB; - if (count) { - mpihelp_rshift(wp, up + limb_cnt, wsize, count); - wsize -= !wp[wsize - 1]; - } else { - MPN_COPY_INCR(wp, up + limb_cnt, wsize); - } - - w->nlimbs = wsize; - } - return 0; -} - -/**************** - * Check whether dividend is divisible by divisor - * (note: divisor must fit into a limb) - */ -int mpi_divisible_ui(MPI dividend, ulong divisor) -{ - return !mpihelp_mod_1(dividend->d, dividend->nlimbs, divisor); -} diff --git a/lib/mpi/mpi-gcd.c b/lib/mpi/mpi-gcd.c deleted file mode 100644 index 13c48aef9c4e..000000000000 --- a/lib/mpi/mpi-gcd.c +++ /dev/null @@ -1,59 +0,0 @@ -/* mpi-gcd.c - MPI functions - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "mpi-internal.h" - -/**************** - * Find the greatest common divisor G of A and B. - * Return: true if this 1, false in all other cases - */ -int mpi_gcd(MPI g, const MPI xa, const MPI xb) -{ - MPI a = NULL, b = NULL; - - if (mpi_copy(&a, xa) < 0) - goto nomem; - - if (mpi_copy(&b, xb) < 0) - goto nomem; - - /* TAOCP Vol II, 4.5.2, Algorithm A */ - a->sign = 0; - b->sign = 0; - while (mpi_cmp_ui(b, 0)) { - if (mpi_fdiv_r(g, a, b) < 0) /* g used as temorary variable */ - goto nomem; - if (mpi_set(a, b) < 0) - goto nomem; - if (mpi_set(b, g) < 0) - goto nomem; - } - if (mpi_set(g, a) < 0) - goto nomem; - - mpi_free(a); - mpi_free(b); - return !mpi_cmp_ui(g, 1); - -nomem: - mpi_free(a); - mpi_free(b); - return -ENOMEM; -} diff --git a/lib/mpi/mpi-inline.c b/lib/mpi/mpi-inline.c deleted file mode 100644 index 654f68aeed8b..000000000000 --- a/lib/mpi/mpi-inline.c +++ /dev/null @@ -1,31 +0,0 @@ -/* mpi-inline.c - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* put the inline functions as real functions into the lib */ -#define G10_MPI_INLINE_DECL - -#include "mpi-internal.h" - -/* always include the header becuase it is only - * included by mpi-internal if __GCC__ is defined but we - * need it here in all cases and the above definition of - * of the macro allows us to do so - */ -#include "mpi-inline.h" diff --git a/lib/mpi/mpi-inv.c b/lib/mpi/mpi-inv.c deleted file mode 100644 index 0951f9847745..000000000000 --- a/lib/mpi/mpi-inv.c +++ /dev/null @@ -1,187 +0,0 @@ -/* mpi-inv.c - MPI functions - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "mpi-internal.h" - -/**************** - * Calculate the multiplicative inverse X of A mod N - * That is: Find the solution x for - * 1 = (a*x) mod n - */ -int mpi_invm(MPI x, const MPI a, const MPI n) -{ - /* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X) - * modified according to Michael Penk's solution for Exercice 35 - * with further enhancement */ - MPI u = NULL, v = NULL; - MPI u1 = NULL, u2 = NULL, u3 = NULL; - MPI v1 = NULL, v2 = NULL, v3 = NULL; - MPI t1 = NULL, t2 = NULL, t3 = NULL; - unsigned k; - int sign; - int odd = 0; - int rc = -ENOMEM; - - if (mpi_copy(&u, a) < 0) - goto cleanup; - if (mpi_copy(&v, n) < 0) - goto cleanup; - - for (k = 0; !mpi_test_bit(u, 0) && !mpi_test_bit(v, 0); k++) { - if (mpi_rshift(u, u, 1) < 0) - goto cleanup; - if (mpi_rshift(v, v, 1) < 0) - goto cleanup; - } - odd = mpi_test_bit(v, 0); - - u1 = mpi_alloc_set_ui(1); - if (!u1) - goto cleanup; - if (!odd) { - u2 = mpi_alloc_set_ui(0); - if (!u2) - goto cleanup; - } - if (mpi_copy(&u3, u) < 0) - goto cleanup; - if (mpi_copy(&v1, v) < 0) - goto cleanup; - if (!odd) { - v2 = mpi_alloc(mpi_get_nlimbs(u)); - if (!v2) - goto cleanup; - if (mpi_sub(v2, u1, u) < 0) - goto cleanup; /* U is used as const 1 */ - } - if (mpi_copy(&v3, v) < 0) - goto cleanup; - if (mpi_test_bit(u, 0)) { /* u is odd */ - t1 = mpi_alloc_set_ui(0); - if (!t1) - goto cleanup; - if (!odd) { - t2 = mpi_alloc_set_ui(1); - if (!t2) - goto cleanup; - t2->sign = 1; - } - if (mpi_copy(&t3, v) < 0) - goto cleanup; - t3->sign = !t3->sign; - goto Y4; - } else { - t1 = mpi_alloc_set_ui(1); - if (!t1) - goto cleanup; - if (!odd) { - t2 = mpi_alloc_set_ui(0); - if (!t2) - goto cleanup; - } - if (mpi_copy(&t3, u) < 0) - goto cleanup; - } - do { - do { - if (!odd) { - if (mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0)) { /* one is odd */ - if (mpi_add(t1, t1, v) < 0) - goto cleanup; - if (mpi_sub(t2, t2, u) < 0) - goto cleanup; - } - if (mpi_rshift(t1, t1, 1) < 0) - goto cleanup; - if (mpi_rshift(t2, t2, 1) < 0) - goto cleanup; - if (mpi_rshift(t3, t3, 1) < 0) - goto cleanup; - } else { - if (mpi_test_bit(t1, 0)) - if (mpi_add(t1, t1, v) < 0) - goto cleanup; - if (mpi_rshift(t1, t1, 1) < 0) - goto cleanup; - if (mpi_rshift(t3, t3, 1) < 0) - goto cleanup; - } -Y4: - ; - } while (!mpi_test_bit(t3, 0)); /* while t3 is even */ - - if (!t3->sign) { - if (mpi_set(u1, t1) < 0) - goto cleanup; - if (!odd) - if (mpi_set(u2, t2) < 0) - goto cleanup; - if (mpi_set(u3, t3) < 0) - goto cleanup; - } else { - if (mpi_sub(v1, v, t1) < 0) - goto cleanup; - sign = u->sign; - u->sign = !u->sign; - if (!odd) - if (mpi_sub(v2, u, t2) < 0) - goto cleanup; - u->sign = sign; - sign = t3->sign; - t3->sign = !t3->sign; - if (mpi_set(v3, t3) < 0) - goto cleanup; - t3->sign = sign; - } - if (mpi_sub(t1, u1, v1) < 0) - goto cleanup; - if (!odd) - if (mpi_sub(t2, u2, v2) < 0) - goto cleanup; - if (mpi_sub(t3, u3, v3) < 0) - goto cleanup; - if (t1->sign) { - if (mpi_add(t1, t1, v) < 0) - goto cleanup; - if (!odd) - if (mpi_sub(t2, t2, u) < 0) - goto cleanup; - } - } while (mpi_cmp_ui(t3, 0)); /* while t3 != 0 */ - /* mpi_lshift( u3, k ); */ - rc = mpi_set(x, u1); - -cleanup: - mpi_free(u1); - mpi_free(v1); - mpi_free(t1); - if (!odd) { - mpi_free(u2); - mpi_free(v2); - mpi_free(t2); - } - mpi_free(u3); - mpi_free(v3); - mpi_free(t3); - - mpi_free(u); - mpi_free(v); - return rc; -} diff --git a/lib/mpi/mpi-mpow.c b/lib/mpi/mpi-mpow.c deleted file mode 100644 index 7328d0d6c748..000000000000 --- a/lib/mpi/mpi-mpow.c +++ /dev/null @@ -1,134 +0,0 @@ -/* mpi-mpow.c - MPI functions - * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "mpi-internal.h" -#include "longlong.h" - -static int build_index(const MPI *exparray, int k, int i, int t) -{ - int j, bitno; - int index = 0; - - bitno = t - i; - for (j = k - 1; j >= 0; j--) { - index <<= 1; - if (mpi_test_bit(exparray[j], bitno)) - index |= 1; - } - return index; -} - -/**************** - * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M - */ -int mpi_mulpowm(MPI res, MPI *basearray, MPI *exparray, MPI m) -{ - int rc = -ENOMEM; - int k; /* number of elements */ - int t; /* bit size of largest exponent */ - int i, j, idx; - MPI *G = NULL; /* table with precomputed values of size 2^k */ - MPI tmp = NULL; - - for (k = 0; basearray[k]; k++) - ; - if (!k) { - pr_emerg("mpi_mulpowm: assert(k) failed\n"); - BUG(); - } - for (t = 0, i = 0; (tmp = exparray[i]); i++) { - j = mpi_get_nbits(tmp); - if (j > t) - t = j; - } - if (i != k) { - pr_emerg("mpi_mulpowm: assert(i==k) failed\n"); - BUG(); - } - if (!t) { - pr_emerg("mpi_mulpowm: assert(t) failed\n"); - BUG(); - } - if (k >= 10) { - pr_emerg("mpi_mulpowm: assert(k<10) failed\n"); - BUG(); - } - - G = kzalloc((1 << k) * sizeof *G, GFP_KERNEL); - if (!G) - goto err_out; - - /* and calculate */ - tmp = mpi_alloc(mpi_get_nlimbs(m) + 1); - if (!tmp) - goto nomem; - if (mpi_set_ui(res, 1) < 0) - goto nomem; - for (i = 1; i <= t; i++) { - if (mpi_mulm(tmp, res, res, m) < 0) - goto nomem; - idx = build_index(exparray, k, i, t); - if (!(idx >= 0 && idx < (1 << k))) { - pr_emerg("mpi_mulpowm: assert(idx >= 0 && idx < (1<nlimbs; - sign = mult->sign; - - if (!size || !small_mult) { - prod->nlimbs = 0; - prod->sign = 0; - return 0; - } - - prod_size = size + 1; - if (prod->alloced < prod_size) - if (mpi_resize(prod, prod_size) < 0) - return -ENOMEM; - prod_ptr = prod->d; - - cy = mpihelp_mul_1(prod_ptr, mult->d, size, (mpi_limb_t) small_mult); - if (cy) - prod_ptr[size++] = cy; - prod->nlimbs = size; - prod->sign = sign; - return 0; -} - -int mpi_mul_2exp(MPI w, MPI u, unsigned long cnt) -{ - mpi_size_t usize, wsize, limb_cnt; - mpi_ptr_t wp; - mpi_limb_t wlimb; - int usign, wsign; - - usize = u->nlimbs; - usign = u->sign; - - if (!usize) { - w->nlimbs = 0; - w->sign = 0; - return 0; - } - - limb_cnt = cnt / BITS_PER_MPI_LIMB; - wsize = usize + limb_cnt + 1; - if (w->alloced < wsize) - if (mpi_resize(w, wsize) < 0) - return -ENOMEM; - wp = w->d; - wsize = usize + limb_cnt; - wsign = usign; - - cnt %= BITS_PER_MPI_LIMB; - if (cnt) { - wlimb = mpihelp_lshift(wp + limb_cnt, u->d, usize, cnt); - if (wlimb) { - wp[wsize] = wlimb; - wsize++; - } - } else { - MPN_COPY_DECR(wp + limb_cnt, u->d, usize); - } - - /* Zero all whole limbs at low end. Do it here and not before calling - * mpn_lshift, not to lose for U == W. */ - MPN_ZERO(wp, limb_cnt); - - w->nlimbs = wsize; - w->sign = wsign; - return 0; -} - -int mpi_mul(MPI w, MPI u, MPI v) -{ - int rc = -ENOMEM; - mpi_size_t usize, vsize, wsize; - mpi_ptr_t up, vp, wp; - mpi_limb_t cy; - int usign, vsign, sign_product; - int assign_wp = 0; - mpi_ptr_t tmp_limb = NULL; - - if (u->nlimbs < v->nlimbs) { /* Swap U and V. */ - usize = v->nlimbs; - usign = v->sign; - up = v->d; - vsize = u->nlimbs; - vsign = u->sign; - vp = u->d; - } else { - usize = u->nlimbs; - usign = u->sign; - up = u->d; - vsize = v->nlimbs; - vsign = v->sign; - vp = v->d; - } - sign_product = usign ^ vsign; - wp = w->d; - - /* Ensure W has space enough to store the result. */ - wsize = usize + vsize; - if (w->alloced < (size_t) wsize) { - if (wp == up || wp == vp) { - wp = mpi_alloc_limb_space(wsize); - if (!wp) - goto nomem; - assign_wp = 1; - } else { - if (mpi_resize(w, wsize) < 0) - goto nomem; - wp = w->d; - } - } else { /* Make U and V not overlap with W. */ - if (wp == up) { - /* W and U are identical. Allocate temporary space for U. */ - up = tmp_limb = mpi_alloc_limb_space(usize); - if (!up) - goto nomem; - /* Is V identical too? Keep it identical with U. */ - if (wp == vp) - vp = up; - /* Copy to the temporary space. */ - MPN_COPY(up, wp, usize); - } else if (wp == vp) { - /* W and V are identical. Allocate temporary space for V. */ - vp = tmp_limb = mpi_alloc_limb_space(vsize); - if (!vp) - goto nomem; - /* Copy to the temporary space. */ - MPN_COPY(vp, wp, vsize); - } - } - - if (!vsize) - wsize = 0; - else { - if (mpihelp_mul(wp, up, usize, vp, vsize, &cy) < 0) - goto nomem; - wsize -= cy ? 0 : 1; - } - - if (assign_wp) - mpi_assign_limb_space(w, wp, wsize); - - w->nlimbs = wsize; - w->sign = sign_product; - rc = 0; -nomem: - if (tmp_limb) - mpi_free_limb_space(tmp_limb); - return rc; -} - -int mpi_mulm(MPI w, MPI u, MPI v, MPI m) -{ - if (mpi_mul(w, u, v) < 0) - return -ENOMEM; - return mpi_fdiv_r(w, w, m); -} diff --git a/lib/mpi/mpi-scan.c b/lib/mpi/mpi-scan.c deleted file mode 100644 index b2da5ad96199..000000000000 --- a/lib/mpi/mpi-scan.c +++ /dev/null @@ -1,136 +0,0 @@ -/* mpi-scan.c - MPI functions - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "mpi-internal.h" -#include "longlong.h" - -/**************** - * Scan through an mpi and return byte for byte. a -1 is returned to indicate - * the end of the mpi. Scanning is done from the lsb to the msb, returned - * values are in the range of 0 .. 255. - * - * FIXME: This code is VERY ugly! - */ -int mpi_getbyte(const MPI a, unsigned idx) -{ - int i, j; - unsigned n; - mpi_ptr_t ap; - mpi_limb_t limb; - - ap = a->d; - for (n = 0, i = 0; i < a->nlimbs; i++) { - limb = ap[i]; - for (j = 0; j < BYTES_PER_MPI_LIMB; j++, n++) - if (n == idx) - return (limb >> j * 8) & 0xff; - } - return -1; -} - -/**************** - * Put a value at position IDX into A. idx counts from lsb to msb - */ -void mpi_putbyte(MPI a, unsigned idx, int xc) -{ - int i, j; - unsigned n; - mpi_ptr_t ap; - mpi_limb_t limb, c; - - c = xc & 0xff; - ap = a->d; - for (n = 0, i = 0; i < a->alloced; i++) { - limb = ap[i]; - for (j = 0; j < BYTES_PER_MPI_LIMB; j++, n++) - if (n == idx) { -#if BYTES_PER_MPI_LIMB == 4 - if (j == 0) - limb = (limb & 0xffffff00) | c; - else if (j == 1) - limb = (limb & 0xffff00ff) | (c << 8); - else if (j == 2) - limb = (limb & 0xff00ffff) | (c << 16); - else - limb = (limb & 0x00ffffff) | (c << 24); -#elif BYTES_PER_MPI_LIMB == 8 - if (j == 0) - limb = (limb & 0xffffffffffffff00) | c; - else if (j == 1) - limb = - (limb & 0xffffffffffff00ff) | (c << - 8); - else if (j == 2) - limb = - (limb & 0xffffffffff00ffff) | (c << - 16); - else if (j == 3) - limb = - (limb & 0xffffffff00ffffff) | (c << - 24); - else if (j == 4) - limb = - (limb & 0xffffff00ffffffff) | (c << - 32); - else if (j == 5) - limb = - (limb & 0xffff00ffffffffff) | (c << - 40); - else if (j == 6) - limb = - (limb & 0xff00ffffffffffff) | (c << - 48); - else - limb = - (limb & 0x00ffffffffffffff) | (c << - 56); -#else -#error please enhance this function, its ugly - i know. -#endif - if (a->nlimbs <= i) - a->nlimbs = i + 1; - ap[i] = limb; - return; - } - } - log_bug("index out of range\n"); -} - -/**************** - * Count the number of zerobits at the low end of A - */ -unsigned mpi_trailing_zeros(const MPI a) -{ - unsigned n, count = 0; - - for (n = 0; n < a->nlimbs; n++) { - if (a->d[n]) { - unsigned nn; - mpi_limb_t alimb = a->d[n]; - - count_trailing_zeros(nn, alimb); - count += nn; - break; - } - count += BITS_PER_MPI_LIMB; - } - return count; - -} -- GitLab From 7cf4206a99d1b3e61bdbc7cbbf4a7bf6a9dfcc68 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 9 May 2012 17:37:56 +0300 Subject: [PATCH 0048/6849] Remove unused code from MPI library MPI library is used by RSA verification implementation. Few files contains functions which are never called. James Morris has asked to remove all of them. Signed-off-by: Dmitry Kasatkin Requested-by: James Morris Signed-off-by: James Morris --- lib/mpi/mpi-bit.c | 162 ------------------------ lib/mpi/mpicoder.c | 75 ----------- lib/mpi/mpih-div.c | 309 --------------------------------------------- lib/mpi/mpih-mul.c | 30 ----- lib/mpi/mpiutil.c | 88 ------------- 5 files changed, 664 deletions(-) diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c index 0c505361da19..568724804f29 100644 --- a/lib/mpi/mpi-bit.c +++ b/lib/mpi/mpi-bit.c @@ -54,165 +54,3 @@ unsigned mpi_get_nbits(MPI a) return n; } EXPORT_SYMBOL_GPL(mpi_get_nbits); - -/**************** - * Test whether bit N is set. - */ -int mpi_test_bit(MPI a, unsigned n) -{ - unsigned limbno, bitno; - mpi_limb_t limb; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if (limbno >= a->nlimbs) - return 0; /* too far left: this is a 0 */ - limb = a->d[limbno]; - return (limb & (A_LIMB_1 << bitno)) ? 1 : 0; -} - -/**************** - * Set bit N of A. - */ -int mpi_set_bit(MPI a, unsigned n) -{ - unsigned limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if (limbno >= a->nlimbs) { /* resize */ - if (a->alloced >= limbno) - if (mpi_resize(a, limbno + 1) < 0) - return -ENOMEM; - a->nlimbs = limbno + 1; - } - a->d[limbno] |= (A_LIMB_1 << bitno); - return 0; -} - -/**************** - * Set bit N of A. and clear all bits above - */ -int mpi_set_highbit(MPI a, unsigned n) -{ - unsigned limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if (limbno >= a->nlimbs) { /* resize */ - if (a->alloced >= limbno) - if (mpi_resize(a, limbno + 1) < 0) - return -ENOMEM; - a->nlimbs = limbno + 1; - } - a->d[limbno] |= (A_LIMB_1 << bitno); - for (bitno++; bitno < BITS_PER_MPI_LIMB; bitno++) - a->d[limbno] &= ~(A_LIMB_1 << bitno); - a->nlimbs = limbno + 1; - return 0; -} - -/**************** - * clear bit N of A and all bits above - */ -void mpi_clear_highbit(MPI a, unsigned n) -{ - unsigned limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if (limbno >= a->nlimbs) - return; /* not allocated, so need to clear bits :-) */ - - for (; bitno < BITS_PER_MPI_LIMB; bitno++) - a->d[limbno] &= ~(A_LIMB_1 << bitno); - a->nlimbs = limbno + 1; -} - -/**************** - * Clear bit N of A. - */ -void mpi_clear_bit(MPI a, unsigned n) -{ - unsigned limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if (limbno >= a->nlimbs) - return; /* don't need to clear this bit, it's to far to left */ - a->d[limbno] &= ~(A_LIMB_1 << bitno); -} - -/**************** - * Shift A by N bits to the right - * FIXME: should use alloc_limb if X and A are same. - */ -int mpi_rshift(MPI x, MPI a, unsigned n) -{ - mpi_ptr_t xp; - mpi_size_t xsize; - - xsize = a->nlimbs; - x->sign = a->sign; - if (RESIZE_IF_NEEDED(x, (size_t) xsize) < 0) - return -ENOMEM; - xp = x->d; - - if (xsize) { - mpihelp_rshift(xp, a->d, xsize, n); - MPN_NORMALIZE(xp, xsize); - } - x->nlimbs = xsize; - return 0; -} - -/**************** - * Shift A by COUNT limbs to the left - * This is used only within the MPI library - */ -int mpi_lshift_limbs(MPI a, unsigned int count) -{ - const int n = a->nlimbs; - mpi_ptr_t ap; - int i; - - if (!count || !n) - return 0; - - if (RESIZE_IF_NEEDED(a, n + count) < 0) - return -ENOMEM; - - ap = a->d; - for (i = n - 1; i >= 0; i--) - ap[i + count] = ap[i]; - for (i = 0; i < count; i++) - ap[i] = 0; - a->nlimbs += count; - return 0; -} - -/**************** - * Shift A by COUNT limbs to the right - * This is used only within the MPI library - */ -void mpi_rshift_limbs(MPI a, unsigned int count) -{ - mpi_ptr_t ap = a->d; - mpi_size_t n = a->nlimbs; - unsigned int i; - - if (count >= n) { - a->nlimbs = 0; - return; - } - - for (i = 0; i < n - count; i++) - ap[i] = ap[i + count]; - ap[i] = 0; - a->nlimbs -= count; -} diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index f26b41fcb48c..f0fa65995800 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c @@ -73,81 +73,6 @@ leave: } EXPORT_SYMBOL_GPL(mpi_read_from_buffer); -/**************** - * Make an mpi from a character string. - */ -int mpi_fromstr(MPI val, const char *str) -{ - int hexmode = 0, sign = 0, prepend_zero = 0, i, j, c, c1, c2; - unsigned nbits, nbytes, nlimbs; - mpi_limb_t a; - - if (*str == '-') { - sign = 1; - str++; - } - if (*str == '0' && str[1] == 'x') - hexmode = 1; - else - return -EINVAL; /* other bases are not yet supported */ - str += 2; - - nbits = strlen(str) * 4; - if (nbits % 8) - prepend_zero = 1; - nbytes = (nbits + 7) / 8; - nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; - if (val->alloced < nlimbs) - if (!mpi_resize(val, nlimbs)) - return -ENOMEM; - i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; - i %= BYTES_PER_MPI_LIMB; - j = val->nlimbs = nlimbs; - val->sign = sign; - for (; j > 0; j--) { - a = 0; - for (; i < BYTES_PER_MPI_LIMB; i++) { - if (prepend_zero) { - c1 = '0'; - prepend_zero = 0; - } else - c1 = *str++; - assert(c1); - c2 = *str++; - assert(c2); - if (c1 >= '0' && c1 <= '9') - c = c1 - '0'; - else if (c1 >= 'a' && c1 <= 'f') - c = c1 - 'a' + 10; - else if (c1 >= 'A' && c1 <= 'F') - c = c1 - 'A' + 10; - else { - mpi_clear(val); - return 1; - } - c <<= 4; - if (c2 >= '0' && c2 <= '9') - c |= c2 - '0'; - else if (c2 >= 'a' && c2 <= 'f') - c |= c2 - 'a' + 10; - else if (c2 >= 'A' && c2 <= 'F') - c |= c2 - 'A' + 10; - else { - mpi_clear(val); - return 1; - } - a <<= 8; - a |= c; - } - i = 0; - - val->d[j - 1] = a; - } - - return 0; -} -EXPORT_SYMBOL_GPL(mpi_fromstr); - /**************** * Return an allocated buffer with the MPI (msb first). * NBYTES receives the length of this buffer. Caller must free the diff --git a/lib/mpi/mpih-div.c b/lib/mpi/mpih-div.c index cde1aaec18da..c57d1d46295e 100644 --- a/lib/mpi/mpih-div.c +++ b/lib/mpi/mpih-div.c @@ -37,159 +37,6 @@ #define UDIV_TIME UMUL_TIME #endif -/* FIXME: We should be using invert_limb (or invert_normalized_limb) - * here (not udiv_qrnnd). - */ - -mpi_limb_t -mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, - mpi_limb_t divisor_limb) -{ - mpi_size_t i; - mpi_limb_t n1, n0, r; - int dummy; - - /* Botch: Should this be handled at all? Rely on callers? */ - if (!dividend_size) - return 0; - - /* If multiplication is much faster than division, and the - * dividend is large, pre-invert the divisor, and use - * only multiplications in the inner loop. - * - * This test should be read: - * Does it ever help to use udiv_qrnnd_preinv? - * && Does what we save compensate for the inversion overhead? - */ - if (UDIV_TIME > (2 * UMUL_TIME + 6) - && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) { - int normalization_steps; - - count_leading_zeros(normalization_steps, divisor_limb); - if (normalization_steps) { - mpi_limb_t divisor_limb_inverted; - - divisor_limb <<= normalization_steps; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - * - * Special case for DIVISOR_LIMB == 100...000. - */ - if (!(divisor_limb << 1)) - divisor_limb_inverted = ~(mpi_limb_t) 0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for (i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV(dummy, r, r, - ((n1 << normalization_steps) - | (n0 >> - (BITS_PER_MPI_LIMB - - normalization_steps))), - divisor_limb, - divisor_limb_inverted); - n1 = n0; - } - UDIV_QRNND_PREINV(dummy, r, r, - n1 << normalization_steps, - divisor_limb, divisor_limb_inverted); - return r >> normalization_steps; - } else { - mpi_limb_t divisor_limb_inverted; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - * - * Special case for DIVISOR_LIMB == 100...000. - */ - if (!(divisor_limb << 1)) - divisor_limb_inverted = ~(mpi_limb_t) 0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - i = dividend_size - 1; - r = dividend_ptr[i]; - - if (r >= divisor_limb) - r = 0; - else - i--; - - for (; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV(dummy, r, r, - n0, divisor_limb, - divisor_limb_inverted); - } - return r; - } - } else { - if (UDIV_NEEDS_NORMALIZATION) { - int normalization_steps; - - count_leading_zeros(normalization_steps, divisor_limb); - if (normalization_steps) { - divisor_limb <<= normalization_steps; - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for (i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd(dummy, r, r, - ((n1 << normalization_steps) - | (n0 >> - (BITS_PER_MPI_LIMB - - normalization_steps))), - divisor_limb); - n1 = n0; - } - udiv_qrnnd(dummy, r, r, - n1 << normalization_steps, - divisor_limb); - return r >> normalization_steps; - } - } - /* No normalization needed, either because udiv_qrnnd doesn't require - * it, or because DIVISOR_LIMB is already normalized. */ - i = dividend_size - 1; - r = dividend_ptr[i]; - - if (r >= divisor_limb) - r = 0; - else - i--; - - for (; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd(dummy, r, r, n0, divisor_limb); - } - return r; - } -} - /* Divide num (NP/NSIZE) by den (DP/DSIZE) and write * the NSIZE-DSIZE least significant quotient limbs at QP * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is @@ -387,159 +234,3 @@ q_test: return most_significant_q_limb; } - -/**************** - * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB. - * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR. - * Return the single-limb remainder. - * There are no constraints on the value of the divisor. - * - * QUOT_PTR and DIVIDEND_PTR might point to the same limb. - */ - -mpi_limb_t -mpihelp_divmod_1(mpi_ptr_t quot_ptr, - mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, - mpi_limb_t divisor_limb) -{ - mpi_size_t i; - mpi_limb_t n1, n0, r; - int dummy; - - if (!dividend_size) - return 0; - - /* If multiplication is much faster than division, and the - * dividend is large, pre-invert the divisor, and use - * only multiplications in the inner loop. - * - * This test should be read: - * Does it ever help to use udiv_qrnnd_preinv? - * && Does what we save compensate for the inversion overhead? - */ - if (UDIV_TIME > (2 * UMUL_TIME + 6) - && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) { - int normalization_steps; - - count_leading_zeros(normalization_steps, divisor_limb); - if (normalization_steps) { - mpi_limb_t divisor_limb_inverted; - - divisor_limb <<= normalization_steps; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - */ - /* Special case for DIVISOR_LIMB == 100...000. */ - if (!(divisor_limb << 1)) - divisor_limb_inverted = ~(mpi_limb_t) 0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for (i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV(quot_ptr[i + 1], r, r, - ((n1 << normalization_steps) - | (n0 >> - (BITS_PER_MPI_LIMB - - normalization_steps))), - divisor_limb, - divisor_limb_inverted); - n1 = n0; - } - UDIV_QRNND_PREINV(quot_ptr[0], r, r, - n1 << normalization_steps, - divisor_limb, divisor_limb_inverted); - return r >> normalization_steps; - } else { - mpi_limb_t divisor_limb_inverted; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - */ - /* Special case for DIVISOR_LIMB == 100...000. */ - if (!(divisor_limb << 1)) - divisor_limb_inverted = ~(mpi_limb_t) 0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - i = dividend_size - 1; - r = dividend_ptr[i]; - - if (r >= divisor_limb) - r = 0; - else - quot_ptr[i--] = 0; - - for (; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV(quot_ptr[i], r, r, - n0, divisor_limb, - divisor_limb_inverted); - } - return r; - } - } else { - if (UDIV_NEEDS_NORMALIZATION) { - int normalization_steps; - - count_leading_zeros(normalization_steps, divisor_limb); - if (normalization_steps) { - divisor_limb <<= normalization_steps; - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for (i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd(quot_ptr[i + 1], r, r, - ((n1 << normalization_steps) - | (n0 >> - (BITS_PER_MPI_LIMB - - normalization_steps))), - divisor_limb); - n1 = n0; - } - udiv_qrnnd(quot_ptr[0], r, r, - n1 << normalization_steps, - divisor_limb); - return r >> normalization_steps; - } - } - /* No normalization needed, either because udiv_qrnnd doesn't require - * it, or because DIVISOR_LIMB is already normalized. */ - i = dividend_size - 1; - r = dividend_ptr[i]; - - if (r >= divisor_limb) - r = 0; - else - quot_ptr[i--] = 0; - - for (; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd(quot_ptr[i], r, r, n0, divisor_limb); - } - return r; - } -} diff --git a/lib/mpi/mpih-mul.c b/lib/mpi/mpih-mul.c index c69c5eef233b..7c841719fdfb 100644 --- a/lib/mpi/mpih-mul.c +++ b/lib/mpi/mpih-mul.c @@ -330,36 +330,6 @@ mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace) } } -/* This should be made into an inline function in gmp.h. */ -int mpihelp_mul_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size) -{ - if (up == vp) { - if (size < KARATSUBA_THRESHOLD) - mpih_sqr_n_basecase(prodp, up, size); - else { - mpi_ptr_t tspace; - tspace = mpi_alloc_limb_space(2 * size); - if (!tspace) - return -ENOMEM; - mpih_sqr_n(prodp, up, size, tspace); - mpi_free_limb_space(tspace); - } - } else { - if (size < KARATSUBA_THRESHOLD) - mul_n_basecase(prodp, up, vp, size); - else { - mpi_ptr_t tspace; - tspace = mpi_alloc_limb_space(2 * size); - if (!tspace) - return -ENOMEM; - mul_n(prodp, up, vp, size, tspace); - mpi_free_limb_space(tspace); - } - } - - return 0; -} - int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c index 26e4ed31e256..657979f71bef 100644 --- a/lib/mpi/mpiutil.c +++ b/lib/mpi/mpiutil.c @@ -106,13 +106,6 @@ int mpi_resize(MPI a, unsigned nlimbs) return 0; } -void mpi_clear(MPI a) -{ - a->nlimbs = 0; - a->nbits = 0; - a->flags = 0; -} - void mpi_free(MPI a) { if (!a) @@ -128,84 +121,3 @@ void mpi_free(MPI a) kfree(a); } EXPORT_SYMBOL_GPL(mpi_free); - -/**************** - * Note: This copy function should not interpret the MPI - * but copy it transparently. - */ -int mpi_copy(MPI *copied, const MPI a) -{ - size_t i; - MPI b; - - *copied = NULL; - - if (a) { - b = mpi_alloc(a->nlimbs); - if (!b) - return -ENOMEM; - - b->nlimbs = a->nlimbs; - b->sign = a->sign; - b->flags = a->flags; - b->nbits = a->nbits; - - for (i = 0; i < b->nlimbs; i++) - b->d[i] = a->d[i]; - - *copied = b; - } - - return 0; -} - -int mpi_set(MPI w, const MPI u) -{ - mpi_ptr_t wp, up; - mpi_size_t usize = u->nlimbs; - int usign = u->sign; - - if (RESIZE_IF_NEEDED(w, (size_t) usize) < 0) - return -ENOMEM; - - wp = w->d; - up = u->d; - MPN_COPY(wp, up, usize); - w->nlimbs = usize; - w->nbits = u->nbits; - w->flags = u->flags; - w->sign = usign; - return 0; -} - -int mpi_set_ui(MPI w, unsigned long u) -{ - if (RESIZE_IF_NEEDED(w, 1) < 0) - return -ENOMEM; - w->d[0] = u; - w->nlimbs = u ? 1 : 0; - w->sign = 0; - w->nbits = 0; - w->flags = 0; - return 0; -} - -MPI mpi_alloc_set_ui(unsigned long u) -{ - MPI w = mpi_alloc(1); - if (!w) - return w; - w->d[0] = u; - w->nlimbs = u ? 1 : 0; - w->sign = 0; - return w; -} - -void mpi_swap(MPI a, MPI b) -{ - struct gcry_mpi tmp; - - tmp = *a; - *a = *b; - *b = tmp; -} -- GitLab From 3ef7cf1839061b275ee1fc59c042194dc452b7e2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 May 2012 16:09:06 -0300 Subject: [PATCH 0049/6849] ARM: mx31_3ds: Fix build due to missing IMX_HAVE_PLATFORM_IMX_SSI commit 5fb86e5 (ARM: mx31_3ds: Add sound support) missed to select IMX_HAVE_PLATFORM_IMX_SSI, which causes the following build error when only mx31_3ds is selected: arch/arm/mach-imx/built-in.o: In function `mx31_3ds_init': mach-mx31_3ds.c:(.init.text+0x15dc): undefined reference to `imx_add_imx_ssi' mach-mx31_3ds.c:(.init.text+0x16b8): undefined reference to `imx31_imx_ssi_data' Select IMX_HAVE_PLATFORM_IMX_SSI to fix it. Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 7561eca131b0..8abcee3c34d0 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -467,6 +467,7 @@ config MACH_MX31_3DS select IMX_HAVE_PLATFORM_IMX2_WDT select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_KEYPAD + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_IPU_CORE select IMX_HAVE_PLATFORM_MXC_EHCI -- GitLab From 824174c3b5a962ff706738e36317451a2343355c Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 28 May 2012 11:51:12 +0530 Subject: [PATCH 0050/6849] ath6kl: Remove unneeded memset in roam related config func No need to clear requested memory after allocating new SKB with help of ath6kl_wmi_get_new_buf(). This clear part is already taken care in ath6kl_wmi_get_new_buf(). Found this on code review. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/wmi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 63dc4fd73c4c..43bce9c8a86f 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -743,7 +743,6 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) return -ENOMEM; cmd = (struct roam_ctrl_cmd *) skb->data; - memset(cmd, 0, sizeof(*cmd)); memcpy(cmd->info.bssid, bssid, ETH_ALEN); cmd->roam_ctrl = WMI_FORCE_ROAM; @@ -763,7 +762,6 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) return -ENOMEM; cmd = (struct roam_ctrl_cmd *) skb->data; - memset(cmd, 0, sizeof(*cmd)); cmd->info.roam_mode = mode; cmd->roam_ctrl = WMI_SET_ROAM_MODE; -- GitLab From df6a7072ac3213229c788913f25779e8ab93c9b5 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 28 May 2012 11:51:13 +0530 Subject: [PATCH 0051/6849] ath6kl: Fix typo in htc mbox debug print msg Add missing ZERO (x%x to 0x%x) in the format specifier while printing hex value in htc module. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc_mbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index 2798624d3a9d..cd0e1ba410d6 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -1309,7 +1309,7 @@ static int ath6kl_htc_rx_packet(struct htc_target *target, } ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx 0x%p hdr x%x len %d mbox 0x%x\n", + "htc rx 0x%p hdr 0x%x len %d mbox 0x%x\n", packet, packet->info.rx.exp_hdr, padded_len, dev->ar->mbox_info.htc_addr); -- GitLab From 1064f8893ee1d16178d983928912057352362dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 2 May 2012 22:08:07 +0200 Subject: [PATCH 0052/6849] ARM: imx: only specify i2c device type once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first argument of I2C_BOARD_INFO is used to assign .type, so drop second assignment. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mach-cpuimx35.c | 1 - arch/arm/mach-imx/mach-cpuimx51sd.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 8ecc872b2547..b1a4796548b5 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -70,7 +70,6 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x48), - .type = "tsc2007", .platform_data = &tsc2007_info, .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), }, diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index 9fbe923c8b08..89eb93cec601 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -124,7 +124,6 @@ static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x49), - .type = "tsc2007", .platform_data = &tsc2007_info, .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), }, -- GitLab From f90da3c7a52ac0c8f07f4d6cd0a7f7677e831916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 18 May 2012 16:58:03 +0200 Subject: [PATCH 0053/6849] ARM: imx: only call l2x0_init if it's available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a build failure with CONFIG_CACHE_L2X0=n: arch/arm/mach-imx/built-in.o: In function `imx3_init_l2x0': imx53-dt.c:(.init.text+0x190): undefined reference to `l2x0_init' make[2]: *** [.tmp_vmlinux1] Error 1 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 When the l2 cache isn't enabled the quirk introduced in 9524705 (MX35: Fix bogus L2 cache settings) doesn't need to be done either. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mm-imx3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 74127389e7ab..6a80496d72dc 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -81,6 +81,7 @@ static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size, void __init imx3_init_l2x0(void) { +#ifdef CONFIG_CACHE_L2X0 void __iomem *l2x0_base; void __iomem *clkctl_base; @@ -110,6 +111,7 @@ void __init imx3_init_l2x0(void) } l2x0_init(l2x0_base, 0x00030024, 0x00000000); +#endif } #ifdef CONFIG_SOC_IMX31 -- GitLab From 67b3f1299ab73259aed5871488188a9c59025a54 Mon Sep 17 00:00:00 2001 From: Kiran Reddy Date: Tue, 29 May 2012 11:12:50 -0700 Subject: [PATCH 0054/6849] ath6kl: separate ht cap for each band In virtual interface structure, for each band separate ht cap is needed. so that one can disable or enable ht capability band wise. This will fix the following issue: 1) Disable 11n from supplicant and start a P2P GO. 2) In beacon frames no HT-CAP IE is seen which is expected. 3) Now remove the P2P GO and kill the supplicant. 4) Beacon stops 5) Now using iw associate to an external AP in 5 GHZ 6) In 5 GHZ no HT IE going in assoc request but when associated in 2.4 GHZ can see HT IES over the air in assoc request. In the code for del_beacon in cfg80211.c,set_ht_cap is being called first for 2.4 GHZ and then for 5 GHZ. When called for the first time for 2.4 GHZ the enable flag will be set to true and so when called for the second time for 5 GHZ it just returns after checking the flag. Also using this one can have different HT capabilities per band (for example one may decide not to use 20/40 in 2.4 GHZ but use it in 5 GHZ). So maintaining a single context is not ok. it is true for even the enable/disable flag and other HT capabilities as well Signed-off-by: Kiran Reddy Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 5 +++-- drivers/net/wireless/ath/ath6kl/core.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 6a934e16ae83..6f20998beceb 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2540,7 +2540,7 @@ void ath6kl_check_wow_status(struct ath6kl *ar) static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band, bool ht_enable) { - struct ath6kl_htcap *htcap = &vif->htcap; + struct ath6kl_htcap *htcap = &vif->htcap[band]; if (htcap->ht_enable == ht_enable) return 0; @@ -3526,7 +3526,8 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; vif->bg_scan_period = 0; - vif->htcap.ht_enable = true; + vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true; + vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); if (fw_vif_idx != 0) diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index b1bc6bc69f2a..17a44fad859b 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -560,7 +560,7 @@ struct ath6kl_vif { struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1]; struct aggr_info *aggr_cntxt; - struct ath6kl_htcap htcap; + struct ath6kl_htcap htcap[IEEE80211_NUM_BANDS]; struct timer_list disconnect_timer; struct timer_list sched_scan_timer; -- GitLab From 2e1ae9c07df5956ebab19144aa0da58ea37c9f69 Mon Sep 17 00:00:00 2001 From: Liu Yu-B13201 Date: Thu, 15 Mar 2012 10:52:13 +0000 Subject: [PATCH 0055/6849] KVM: PPC: Factor out guest epapr initialization epapr paravirtualization support is now a Kconfig selectable option Signed-off-by: Liu Yu [stuart.yoder@freescale.com: misc minor fixes, description update] Signed-off-by: Stuart Yoder Signed-off-by: Alexander Graf --- arch/powerpc/include/asm/epapr_hcalls.h | 2 + arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/epapr_hcalls.S | 25 ++++++++++++ arch/powerpc/kernel/epapr_paravirt.c | 52 +++++++++++++++++++++++++ arch/powerpc/kernel/kvm.c | 28 ++----------- arch/powerpc/kernel/kvm_emul.S | 10 ----- arch/powerpc/platforms/Kconfig | 9 +++++ 7 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 arch/powerpc/kernel/epapr_hcalls.S create mode 100644 arch/powerpc/kernel/epapr_paravirt.c diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h index 976835d8f22e..bf2c06c33871 100644 --- a/arch/powerpc/include/asm/epapr_hcalls.h +++ b/arch/powerpc/include/asm/epapr_hcalls.h @@ -153,6 +153,8 @@ #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4" +extern bool epapr_paravirt_enabled; +extern u32 epapr_hypercall_start[]; /* * We use "uintptr_t" to define a register because it's guaranteed to be a diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 83afacd3ba7b..bb282dd81612 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -128,6 +128,7 @@ ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),) obj-y += ppc_save_regs.o endif +obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o # Disable GCOV in odd or sensitive code diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S new file mode 100644 index 000000000000..697b390ebfd8 --- /dev/null +++ b/arch/powerpc/kernel/epapr_hcalls.S @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Hypercall entry point. Will be patched with device tree instructions. */ +.global epapr_hypercall_start +epapr_hypercall_start: + li r3, -1 + nop + nop + nop + blr diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c new file mode 100644 index 000000000000..028aeae370b6 --- /dev/null +++ b/arch/powerpc/kernel/epapr_paravirt.c @@ -0,0 +1,52 @@ +/* + * ePAPR para-virtualization support. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) 2012 Freescale Semiconductor, Inc. + */ + +#include +#include +#include +#include + +bool epapr_paravirt_enabled; + +static int __init epapr_paravirt_init(void) +{ + struct device_node *hyper_node; + const u32 *insts; + int len, i; + + hyper_node = of_find_node_by_path("/hypervisor"); + if (!hyper_node) + return -ENODEV; + + insts = of_get_property(hyper_node, "hcall-instructions", &len); + if (!insts) + return -ENODEV; + + if (len % 4 || len > (4 * 4)) + return -ENODEV; + + for (i = 0; i < (len / 4); i++) + patch_instruction(epapr_hypercall_start + i, insts[i]); + + epapr_paravirt_enabled = true; + + return 0; +} + +early_initcall(epapr_paravirt_init); diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 62bdf2389669..1c13307e0308 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -31,6 +31,7 @@ #include #include #include +#include #define KVM_MAGIC_PAGE (-4096L) #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x) @@ -726,7 +727,7 @@ unsigned long kvm_hypercall(unsigned long *in, unsigned long register r11 asm("r11") = nr; unsigned long register r12 asm("r12"); - asm volatile("bl kvm_hypercall_start" + asm volatile("bl epapr_hypercall_start" : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), "=r"(r12) @@ -747,29 +748,6 @@ unsigned long kvm_hypercall(unsigned long *in, } EXPORT_SYMBOL_GPL(kvm_hypercall); -static int kvm_para_setup(void) -{ - extern u32 kvm_hypercall_start; - struct device_node *hyper_node; - u32 *insts; - int len, i; - - hyper_node = of_find_node_by_path("/hypervisor"); - if (!hyper_node) - return -1; - - insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len); - if (len % 4) - return -1; - if (len > (4 * 4)) - return -1; - - for (i = 0; i < (len / 4); i++) - kvm_patch_ins(&(&kvm_hypercall_start)[i], insts[i]); - - return 0; -} - static __init void kvm_free_tmp(void) { unsigned long start, end; @@ -791,7 +769,7 @@ static int __init kvm_guest_init(void) if (!kvm_para_available()) goto free_tmp; - if (kvm_para_setup()) + if (!epapr_paravirt_enabled) goto free_tmp; if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE)) diff --git a/arch/powerpc/kernel/kvm_emul.S b/arch/powerpc/kernel/kvm_emul.S index e291cf3cf954..62ceb2ac82cf 100644 --- a/arch/powerpc/kernel/kvm_emul.S +++ b/arch/powerpc/kernel/kvm_emul.S @@ -24,16 +24,6 @@ #include #include -/* Hypercall entry point. Will be patched with device tree instructions. */ - -.global kvm_hypercall_start -kvm_hypercall_start: - li r3, -1 - nop - nop - nop - blr - #define KVM_MAGIC_PAGE (-4096) #ifdef CONFIG_64BIT diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index a35ca44ade66..e7a896acd982 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -25,6 +25,7 @@ source "arch/powerpc/platforms/wsp/Kconfig" config KVM_GUEST bool "KVM Guest support" default n + select EPAPR_PARAVIRT ---help--- This option enables various optimizations for running under the KVM hypervisor. Overhead for the kernel when not running inside KVM should @@ -32,6 +33,14 @@ config KVM_GUEST In case of doubt, say Y +config EPAPR_PARAVIRT + bool "ePAPR para-virtualization support" + default n + help + Enables ePAPR para-virtualization support for guests. + + In case of doubt, say Y + config PPC_NATIVE bool depends on 6xx || PPC64 -- GitLab From 32fad281c0680ed0ccade7dda85a2121cf9b1d06 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 4 May 2012 02:32:53 +0000 Subject: [PATCH 0056/6849] KVM: PPC: Book3S HV: Make the guest hash table size configurable This adds a new ioctl to enable userspace to control the size of the guest hashed page table (HPT) and to clear it out when resetting the guest. The KVM_PPC_ALLOCATE_HTAB ioctl is a VM ioctl and takes as its parameter a pointer to a u32 containing the desired order of the HPT (log base 2 of the size in bytes), which is updated on successful return to the actual order of the HPT which was allocated. There must be no vcpus running at the time of this ioctl. To enforce this, we now keep a count of the number of vcpus running in kvm->arch.vcpus_running. If the ioctl is called when a HPT has already been allocated, we don't reallocate the HPT but just clear it out. We first clear the kvm->arch.rma_setup_done flag, which has two effects: (a) since we hold the kvm->lock mutex, it will prevent any vcpus from starting to run until we're done, and (b) it means that the first vcpu to run after we're done will re-establish the VRMA if necessary. If userspace doesn't call this ioctl before running the first vcpu, the kernel will allocate a default-sized HPT at that point. We do it then rather than when creating the VM, as the code did previously, so that userspace has a chance to do the ioctl if it wants. When allocating the HPT, we can allocate either from the kernel page allocator, or from the preallocated pool. If userspace is asking for a different size from the preallocated HPTs, we first try to allocate using the kernel page allocator. Then we try to allocate from the preallocated pool, and then if that fails, we try allocating decreasing sizes from the kernel page allocator, down to the minimum size allowed (256kB). Note that the kernel page allocator limits allocations to 1 << CONFIG_FORCE_MAX_ZONEORDER pages, which by default corresponds to 16MB (on 64-bit powerpc, at least). Signed-off-by: Paul Mackerras [agraf: fix module compilation] Signed-off-by: Alexander Graf --- Documentation/virtual/kvm/api.txt | 36 +++++++ arch/powerpc/include/asm/kvm_book3s_64.h | 7 +- arch/powerpc/include/asm/kvm_host.h | 4 + arch/powerpc/include/asm/kvm_ppc.h | 3 +- arch/powerpc/kvm/book3s_64_mmu_hv.c | 123 +++++++++++++++++------ arch/powerpc/kvm/book3s_hv.c | 40 +++++--- arch/powerpc/kvm/book3s_hv_builtin.c | 5 +- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 15 +-- arch/powerpc/kvm/powerpc.c | 18 ++++ include/linux/kvm.h | 3 + 10 files changed, 200 insertions(+), 54 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 930126698a0f..310fe508d9cd 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1930,6 +1930,42 @@ The "pte_enc" field provides a value that can OR'ed into the hash PTE's RPN field (ie, it needs to be shifted left by 12 to OR it into the hash PTE second double word). + +4.75 KVM_PPC_ALLOCATE_HTAB + +Capability: KVM_CAP_PPC_ALLOC_HTAB +Architectures: powerpc +Type: vm ioctl +Parameters: Pointer to u32 containing hash table order (in/out) +Returns: 0 on success, -1 on error + +This requests the host kernel to allocate an MMU hash table for a +guest using the PAPR paravirtualization interface. This only does +anything if the kernel is configured to use the Book 3S HV style of +virtualization. Otherwise the capability doesn't exist and the ioctl +returns an ENOTTY error. The rest of this description assumes Book 3S +HV. + +There must be no vcpus running when this ioctl is called; if there +are, it will do nothing and return an EBUSY error. + +The parameter is a pointer to a 32-bit unsigned integer variable +containing the order (log base 2) of the desired size of the hash +table, which must be between 18 and 46. On successful return from the +ioctl, it will have been updated with the order of the hash table that +was allocated. + +If no hash table has been allocated when any vcpu is asked to run +(with the KVM_RUN ioctl), the host kernel will allocate a +default-sized hash table (16 MB). + +If this ioctl is called when a hash table has already been allocated, +the kernel will clear out the existing hash table (zero all HPTEs) and +return the hash table order in the parameter. (If the guest is using +the virtualized real-mode area (VRMA) facility, the kernel will +re-create the VMRA HPTEs on the next KVM_RUN of any vcpu.) + + 5. The kvm_run structure ------------------------ diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index b0c08b142770..0dd1d86d3e31 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -36,11 +36,8 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) #define SPAPR_TCE_SHIFT 12 #ifdef CONFIG_KVM_BOOK3S_64_HV -/* For now use fixed-size 16MB page table */ -#define HPT_ORDER 24 -#define HPT_NPTEG (1ul << (HPT_ORDER - 7)) /* 128B per pteg */ -#define HPT_NPTE (HPT_NPTEG << 3) /* 8 PTEs per PTEG */ -#define HPT_HASH_MASK (HPT_NPTEG - 1) +#define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ +extern int kvm_hpt_order; /* order of preallocated HPTs */ #endif #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index d848cdc49715..dd783beb88b3 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -237,6 +237,10 @@ struct kvm_arch { unsigned long vrma_slb_v; int rma_setup_done; int using_mmu_notifiers; + u32 hpt_order; + atomic_t vcpus_running; + unsigned long hpt_npte; + unsigned long hpt_mask; spinlock_t slot_phys_lock; unsigned long *slot_phys[KVM_MEM_SLOTS_NUM]; int slot_npages[KVM_MEM_SLOTS_NUM]; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index f68c22fa2fce..0124937a23b9 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -119,7 +119,8 @@ extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu); extern void kvmppc_map_magic(struct kvm_vcpu *vcpu); -extern long kvmppc_alloc_hpt(struct kvm *kvm); +extern long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp); +extern long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp); extern void kvmppc_free_hpt(struct kvm *kvm); extern long kvmppc_prepare_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem); diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 80a577517584..d03eb6f7b058 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -37,56 +37,121 @@ /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ #define MAX_LPID_970 63 -long kvmppc_alloc_hpt(struct kvm *kvm) +/* Power architecture requires HPT is at least 256kB */ +#define PPC_MIN_HPT_ORDER 18 + +long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) { unsigned long hpt; - long lpid; struct revmap_entry *rev; struct kvmppc_linear_info *li; + long order = kvm_hpt_order; - /* Allocate guest's hashed page table */ - li = kvm_alloc_hpt(); - if (li) { - /* using preallocated memory */ - hpt = (ulong)li->base_virt; - kvm->arch.hpt_li = li; - } else { - /* using dynamic memory */ + if (htab_orderp) { + order = *htab_orderp; + if (order < PPC_MIN_HPT_ORDER) + order = PPC_MIN_HPT_ORDER; + } + + /* + * If the user wants a different size from default, + * try first to allocate it from the kernel page allocator. + */ + hpt = 0; + if (order != kvm_hpt_order) { hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| - __GFP_NOWARN, HPT_ORDER - PAGE_SHIFT); + __GFP_NOWARN, order - PAGE_SHIFT); + if (!hpt) + --order; } + /* Next try to allocate from the preallocated pool */ if (!hpt) { - pr_err("kvm_alloc_hpt: Couldn't alloc HPT\n"); - return -ENOMEM; + li = kvm_alloc_hpt(); + if (li) { + hpt = (ulong)li->base_virt; + kvm->arch.hpt_li = li; + order = kvm_hpt_order; + } } + + /* Lastly try successively smaller sizes from the page allocator */ + while (!hpt && order > PPC_MIN_HPT_ORDER) { + hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| + __GFP_NOWARN, order - PAGE_SHIFT); + if (!hpt) + --order; + } + + if (!hpt) + return -ENOMEM; + kvm->arch.hpt_virt = hpt; + kvm->arch.hpt_order = order; + /* HPTEs are 2**4 bytes long */ + kvm->arch.hpt_npte = 1ul << (order - 4); + /* 128 (2**7) bytes in each HPTEG */ + kvm->arch.hpt_mask = (1ul << (order - 7)) - 1; /* Allocate reverse map array */ - rev = vmalloc(sizeof(struct revmap_entry) * HPT_NPTE); + rev = vmalloc(sizeof(struct revmap_entry) * kvm->arch.hpt_npte); if (!rev) { pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n"); goto out_freehpt; } kvm->arch.revmap = rev; + kvm->arch.sdr1 = __pa(hpt) | (order - 18); - lpid = kvmppc_alloc_lpid(); - if (lpid < 0) - goto out_freeboth; + pr_info("KVM guest htab at %lx (order %ld), LPID %x\n", + hpt, order, kvm->arch.lpid); - kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); - kvm->arch.lpid = lpid; - - pr_info("KVM guest htab at %lx, LPID %lx\n", hpt, lpid); + if (htab_orderp) + *htab_orderp = order; return 0; - out_freeboth: - vfree(rev); out_freehpt: - free_pages(hpt, HPT_ORDER - PAGE_SHIFT); + if (kvm->arch.hpt_li) + kvm_release_hpt(kvm->arch.hpt_li); + else + free_pages(hpt, order - PAGE_SHIFT); return -ENOMEM; } +long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp) +{ + long err = -EBUSY; + long order; + + mutex_lock(&kvm->lock); + if (kvm->arch.rma_setup_done) { + kvm->arch.rma_setup_done = 0; + /* order rma_setup_done vs. vcpus_running */ + smp_mb(); + if (atomic_read(&kvm->arch.vcpus_running)) { + kvm->arch.rma_setup_done = 1; + goto out; + } + } + if (kvm->arch.hpt_virt) { + order = kvm->arch.hpt_order; + /* Set the entire HPT to 0, i.e. invalid HPTEs */ + memset((void *)kvm->arch.hpt_virt, 0, 1ul << order); + /* + * Set the whole last_vcpu array to an invalid vcpu number. + * This ensures that each vcpu will flush its TLB on next entry. + */ + memset(kvm->arch.last_vcpu, 0xff, sizeof(kvm->arch.last_vcpu)); + *htab_orderp = order; + err = 0; + } else { + err = kvmppc_alloc_hpt(kvm, htab_orderp); + order = *htab_orderp; + } + out: + mutex_unlock(&kvm->lock); + return err; +} + void kvmppc_free_hpt(struct kvm *kvm) { kvmppc_free_lpid(kvm->arch.lpid); @@ -94,7 +159,8 @@ void kvmppc_free_hpt(struct kvm *kvm) if (kvm->arch.hpt_li) kvm_release_hpt(kvm->arch.hpt_li); else - free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); + free_pages(kvm->arch.hpt_virt, + kvm->arch.hpt_order - PAGE_SHIFT); } /* Bits in first HPTE dword for pagesize 4k, 64k or 16M */ @@ -119,6 +185,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, unsigned long psize; unsigned long hp0, hp1; long ret; + struct kvm *kvm = vcpu->kvm; psize = 1ul << porder; npages = memslot->npages >> (porder - PAGE_SHIFT); @@ -127,8 +194,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, if (npages > 1ul << (40 - porder)) npages = 1ul << (40 - porder); /* Can't use more than 1 HPTE per HPTEG */ - if (npages > HPT_NPTEG) - npages = HPT_NPTEG; + if (npages > kvm->arch.hpt_mask + 1) + npages = kvm->arch.hpt_mask + 1; hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | HPTE_V_BOLTED | hpte0_pgsize_encoding(psize); @@ -138,7 +205,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, for (i = 0; i < npages; ++i) { addr = i << porder; /* can't use hpt_hash since va > 64 bits */ - hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & HPT_HASH_MASK; + hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & kvm->arch.hpt_mask; /* * We assume that the hash table is empty and no * vcpus are using it at this stage. Since we create diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index c6af1d623839..d084e412b3c5 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -56,7 +56,7 @@ /* #define EXIT_DEBUG_INT */ static void kvmppc_end_cede(struct kvm_vcpu *vcpu); -static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu); +static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { @@ -1068,11 +1068,15 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) return -EINTR; } - /* On the first time here, set up VRMA or RMA */ + atomic_inc(&vcpu->kvm->arch.vcpus_running); + /* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */ + smp_mb(); + + /* On the first time here, set up HTAB and VRMA or RMA */ if (!vcpu->kvm->arch.rma_setup_done) { - r = kvmppc_hv_setup_rma(vcpu); + r = kvmppc_hv_setup_htab_rma(vcpu); if (r) - return r; + goto out; } flush_fp_to_thread(current); @@ -1090,6 +1094,9 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) kvmppc_core_prepare_to_enter(vcpu); } } while (r == RESUME_GUEST); + + out: + atomic_dec(&vcpu->kvm->arch.vcpus_running); return r; } @@ -1305,7 +1312,7 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm, { } -static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) +static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) { int err = 0; struct kvm *kvm = vcpu->kvm; @@ -1324,6 +1331,15 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) if (kvm->arch.rma_setup_done) goto out; /* another vcpu beat us to it */ + /* Allocate hashed page table (if not done already) and reset it */ + if (!kvm->arch.hpt_virt) { + err = kvmppc_alloc_hpt(kvm, NULL); + if (err) { + pr_err("KVM: Couldn't alloc HPT\n"); + goto out; + } + } + /* Look up the memslot for guest physical address 0 */ memslot = gfn_to_memslot(kvm, 0); @@ -1435,13 +1451,14 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) int kvmppc_core_init_vm(struct kvm *kvm) { - long r; - unsigned long lpcr; + unsigned long lpcr, lpid; - /* Allocate hashed page table */ - r = kvmppc_alloc_hpt(kvm); - if (r) - return r; + /* Allocate the guest's logical partition ID */ + + lpid = kvmppc_alloc_lpid(); + if (lpid < 0) + return -ENOMEM; + kvm->arch.lpid = lpid; INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); @@ -1451,7 +1468,6 @@ int kvmppc_core_init_vm(struct kvm *kvm) if (cpu_has_feature(CPU_FTR_ARCH_201)) { /* PPC970; HID4 is effectively the LPCR */ - unsigned long lpid = kvm->arch.lpid; kvm->arch.host_lpid = 0; kvm->arch.host_lpcr = lpcr = mfspr(SPRN_HID4); lpcr &= ~((3 << HID4_LPID1_SH) | (0xful << HID4_LPID5_SH)); diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index e1b60f56f2a1..fb4eac290fef 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -25,6 +25,9 @@ static void __init kvm_linear_init_one(ulong size, int count, int type); static struct kvmppc_linear_info *kvm_alloc_linear(int type); static void kvm_release_linear(struct kvmppc_linear_info *ri); +int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; +EXPORT_SYMBOL_GPL(kvm_hpt_order); + /*************** RMA *************/ /* @@ -209,7 +212,7 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri) void __init kvm_linear_init(void) { /* HPT */ - kvm_linear_init_one(1 << HPT_ORDER, kvm_hpt_count, KVM_LINEAR_HPT); + kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT); /* RMA */ /* Only do this on PPC970 in HV mode */ diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index cec4daddbf31..5c70d19494f9 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -237,7 +237,7 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags, /* Find and lock the HPTEG slot to use */ do_insert: - if (pte_index >= HPT_NPTE) + if (pte_index >= kvm->arch.hpt_npte) return H_PARAMETER; if (likely((flags & H_EXACT) == 0)) { pte_index &= ~7UL; @@ -352,7 +352,7 @@ long kvmppc_h_remove(struct kvm_vcpu *vcpu, unsigned long flags, unsigned long v, r, rb; struct revmap_entry *rev; - if (pte_index >= HPT_NPTE) + if (pte_index >= kvm->arch.hpt_npte) return H_PARAMETER; hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) @@ -419,7 +419,8 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) i = 4; break; } - if (req != 1 || flags == 3 || pte_index >= HPT_NPTE) { + if (req != 1 || flags == 3 || + pte_index >= kvm->arch.hpt_npte) { /* parameter error */ args[j] = ((0xa0 | flags) << 56) + pte_index; ret = H_PARAMETER; @@ -521,7 +522,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, struct revmap_entry *rev; unsigned long v, r, rb, mask, bits; - if (pte_index >= HPT_NPTE) + if (pte_index >= kvm->arch.hpt_npte) return H_PARAMETER; hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); @@ -583,7 +584,7 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, int i, n = 1; struct revmap_entry *rev = NULL; - if (pte_index >= HPT_NPTE) + if (pte_index >= kvm->arch.hpt_npte) return H_PARAMETER; if (flags & H_READ_4) { pte_index &= ~3; @@ -678,7 +679,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, somask = (1UL << 28) - 1; vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; } - hash = (vsid ^ ((eaddr & somask) >> pshift)) & HPT_HASH_MASK; + hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvm->arch.hpt_mask; avpn = slb_v & ~(somask >> 16); /* also includes B */ avpn |= (eaddr & somask) >> 16; @@ -723,7 +724,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, if (val & HPTE_V_SECONDARY) break; val |= HPTE_V_SECONDARY; - hash = hash ^ HPT_HASH_MASK; + hash = hash ^ kvm->arch.hpt_mask; } return -1; } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1493c8de947b..87f4dc886076 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -246,6 +246,7 @@ int kvm_dev_ioctl_check_extension(long ext) #endif #ifdef CONFIG_PPC_BOOK3S_64 case KVM_CAP_SPAPR_TCE: + case KVM_CAP_PPC_ALLOC_HTAB: r = 1; break; #endif /* CONFIG_PPC_BOOK3S_64 */ @@ -802,6 +803,23 @@ long kvm_arch_vm_ioctl(struct file *filp, r = -EFAULT; break; } + + case KVM_PPC_ALLOCATE_HTAB: { + struct kvm *kvm = filp->private_data; + u32 htab_order; + + r = -EFAULT; + if (get_user(htab_order, (u32 __user *)argp)) + break; + r = kvmppc_alloc_reset_hpt(kvm, &htab_order); + if (r) + break; + r = -EFAULT; + if (put_user(htab_order, (u32 __user *)argp)) + break; + r = 0; + break; + } #endif /* CONFIG_KVM_BOOK3S_64_HV */ #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 09f2b3aa2da7..2ce09aa7d3b3 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -617,6 +617,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_SIGNAL_MSI 77 #define KVM_CAP_PPC_GET_SMMU_INFO 78 #define KVM_CAP_S390_COW 79 +#define KVM_CAP_PPC_ALLOC_HTAB 80 #ifdef KVM_CAP_IRQ_ROUTING @@ -828,6 +829,8 @@ struct kvm_s390_ucas_mapping { #define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi) /* Available with KVM_CAP_PPC_GET_SMMU_INFO */ #define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info) +/* Available with KVM_CAP_PPC_ALLOC_HTAB */ +#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32) /* * ioctls for vcpu fds -- GitLab From 21bd000abff7d587229dbbee6f8c17f3aad9f9d8 Mon Sep 17 00:00:00 2001 From: Bharat Bhushan Date: Sun, 20 May 2012 23:21:23 +0000 Subject: [PATCH 0057/6849] KVM: PPC: booke: Added DECAR support Added the decrementer auto-reload support. DECAR is readable on e500v2/e500mc and later cpus. Signed-off-by: Bharat Bhushan Signed-off-by: Alexander Graf --- arch/powerpc/include/asm/kvm_host.h | 2 ++ arch/powerpc/kvm/booke.c | 5 +++++ arch/powerpc/kvm/booke_emulate.c | 3 +++ arch/powerpc/kvm/e500_emulate.c | 3 +++ 4 files changed, 13 insertions(+) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index dd783beb88b3..50ea12fd7bf5 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -418,7 +418,9 @@ struct kvm_vcpu_arch { ulong mcsrr1; ulong mcsr; u32 dec; +#ifdef CONFIG_BOOKE u32 decar; +#endif u32 tbl; u32 tbu; u32 tcr; diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 72f13f4a06e0..86681eec60b1 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -1267,6 +1267,11 @@ void kvmppc_decrementer_func(unsigned long data) { struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; + if (vcpu->arch.tcr & TCR_ARE) { + vcpu->arch.dec = vcpu->arch.decar; + kvmppc_emulate_dec(vcpu); + } + kvmppc_set_tsr_bits(vcpu, TSR_DIS); } diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index 6c76397f2af4..9eb9809eb13e 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c @@ -129,6 +129,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) kvmppc_set_tcr(vcpu, spr_val); break; + case SPRN_DECAR: + vcpu->arch.decar = spr_val; + break; /* * Note: SPRG4-7 are user-readable. * These values are loaded into the real SPRGs when resuming the diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 8b99e076dc81..e04b0ef55ce0 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -269,6 +269,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) *spr_val = vcpu->arch.shared->mas7_3 >> 32; break; #endif + case SPRN_DECAR: + *spr_val = vcpu->arch.decar; + break; case SPRN_TLB0CFG: *spr_val = vcpu->arch.tlbcfg[0]; break; -- GitLab From d35b1075afc0172caa44b57b56a2b9b57e06d32e Mon Sep 17 00:00:00 2001 From: Bharat Bhushan Date: Sun, 20 May 2012 23:21:53 +0000 Subject: [PATCH 0058/6849] KVM: PPC: Not optimizing MSR_CE and MSR_ME with paravirt. If there is pending critical or machine check interrupt then guest would like to capture it when guest enable MSR.CE and MSR_ME respectively. Also as mostly MSR_CE and MSR_ME are updated with rfi/rfci/rfmii which anyway traps so removing the the paravirt optimization for MSR.CE and MSR.ME. Signed-off-by: Bharat Bhushan Signed-off-by: Alexander Graf --- Documentation/virtual/kvm/ppc-pv.txt | 2 -- arch/powerpc/kernel/kvm_emul.S | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/virtual/kvm/ppc-pv.txt b/Documentation/virtual/kvm/ppc-pv.txt index 6e7c37050930..4911cf95c67e 100644 --- a/Documentation/virtual/kvm/ppc-pv.txt +++ b/Documentation/virtual/kvm/ppc-pv.txt @@ -109,8 +109,6 @@ The following bits are safe to be set inside the guest: MSR_EE MSR_RI - MSR_CR - MSR_ME If any other bit changes in the MSR, please still use mtmsr(d). diff --git a/arch/powerpc/kernel/kvm_emul.S b/arch/powerpc/kernel/kvm_emul.S index 62ceb2ac82cf..e100ff324a85 100644 --- a/arch/powerpc/kernel/kvm_emul.S +++ b/arch/powerpc/kernel/kvm_emul.S @@ -122,7 +122,7 @@ kvm_emulate_mtmsrd_len: .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4 -#define MSR_SAFE_BITS (MSR_EE | MSR_CE | MSR_ME | MSR_RI) +#define MSR_SAFE_BITS (MSR_EE | MSR_RI) #define MSR_CRITICAL_BITS ~MSR_SAFE_BITS .global kvm_emulate_mtmsr -- GitLab From 8c9ce606a60e4a0cb447bdc082ce383b96b227b4 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 25 May 2012 16:11:09 -0400 Subject: [PATCH 0059/6849] xen/blkback: Copy id field when doing BLKIF_DISCARD. We weren't copying the id field so when we sent the response back to the frontend (especially with a 64-bit host and 32-bit guest), we ended up using a random value. This lead to the frontend crashing as it would try to pass to __blk_end_request_all a NULL 'struct request' (b/c it would use the 'id' to find the proper 'struct request' in its shadow array) and end up crashing: BUG: unable to handle kernel NULL pointer dereference at 000000e4 IP: [] __blk_end_request_all+0xc/0x40 .. snip.. EIP is at __blk_end_request_all+0xc/0x40 .. snip.. [] blkif_interrupt+0x172/0x330 [xen_blkfront] This fixes the bug by passing in the proper id for the response. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=824641 CC: stable@kernel.org Tested-by: William Dauchy Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 773cf27dc23f..9ad3b5ec1dc1 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -257,6 +257,7 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; + dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; @@ -287,6 +288,7 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; + dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; -- GitLab From b86aeafc766b71f6d55e54ed2c77fdf7f56ec1ba Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Wed, 25 Apr 2012 16:06:20 +0530 Subject: [PATCH 0060/6849] ARM: OMAP2+: SmartReflex: move the smartreflex header to include/linux/power Move the smartreflex header file (arch/arm/mach-omap2/smartreflex.h) in a new header file include/linux/power/smartreflex.h. This change makes the SmartReflex implementation ready for the move to drivers/. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 4 ++-- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 +-- arch/arm/mach-omap2/smartreflex-class3.c | 3 ++- arch/arm/mach-omap2/smartreflex.c | 3 +-- arch/arm/mach-omap2/sr_device.c | 2 +- {arch/arm/mach-omap2 => include/linux/power}/smartreflex.h | 7 ++++--- 6 files changed, 11 insertions(+), 11 deletions(-) rename {arch/arm/mach-omap2 => include/linux/power}/smartreflex.h (98%) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index fd48797fa95a..8c7241b7279c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -14,6 +14,8 @@ * * XXX these should be marked initdata for multi-OMAP kernels */ +#include + #include #include #include @@ -29,8 +31,6 @@ #include #include "omap_hwmod_common_data.h" - -#include "smartreflex.h" #include "prm-regbits-34xx.h" #include "cm-regbits-34xx.h" #include "wd_timer.h" diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 950454a3fa31..0b3af8233f21 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -32,8 +33,6 @@ #include #include "omap_hwmod_common_data.h" - -#include "smartreflex.h" #include "cm1_44xx.h" #include "cm2_44xx.h" #include "prm44xx.h" diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index 955566eefac4..ab8cf83e853e 100644 --- a/arch/arm/mach-omap2/smartreflex-class3.c +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -11,7 +11,8 @@ * published by the Free Software Foundation. */ -#include "smartreflex.h" +#include +#include "voltage.h" static int sr_class3_enable(struct voltagedomain *voltdm) { diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 008fbd7b9352..98309d32ba98 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -25,11 +25,10 @@ #include #include #include +#include #include "common.h" - #include "pm.h" -#include "smartreflex.h" #define SMARTREFLEX_NAME_LEN 16 #define NVALUE_NAME_LEN 40 diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index a503e1e8358c..86e438e75105 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -17,6 +17,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include @@ -24,7 +25,6 @@ #include -#include "smartreflex.h" #include "voltage.h" #include "control.h" #include "pm.h" diff --git a/arch/arm/mach-omap2/smartreflex.h b/include/linux/power/smartreflex.h similarity index 98% rename from arch/arm/mach-omap2/smartreflex.h rename to include/linux/power/smartreflex.h index 5809141171f8..69eb270c6297 100644 --- a/arch/arm/mach-omap2/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -17,12 +17,13 @@ * published by the Free Software Foundation. */ -#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H -#define __ASM_ARM_OMAP_SMARTREFLEX_H +#ifndef __POWER_SMARTREFLEX_H +#define __POWER_SMARTREFLEX_H +#include #include -#include "voltage.h" +#include /* * Different Smartreflex IPs version. The v1 is the 65nm version used in -- GitLab From 80821c9c90427dd0f9274a82f9d69e43300d10bb Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Tue, 24 Apr 2012 10:22:12 +0530 Subject: [PATCH 0061/6849] ARM: OMAP3+: SmartReflex: class drivers should use struct omap_sr * Convert SmartReflex "class" functions to take a struct omap_sr *, rather than a struct voltagedomain *. SmartReflex code should be driver code and not tightly coupled to OMAP subarchitecture-specific structures. Based on Paul's original code for the SmartReflex driver conversion. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex-class3.c | 24 +++++++-------- arch/arm/mach-omap2/smartreflex.c | 37 +++++------------------- include/linux/power/smartreflex.h | 31 +++++++++++++++++--- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index ab8cf83e853e..9381654e869b 100644 --- a/arch/arm/mach-omap2/smartreflex-class3.c +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -14,34 +14,34 @@ #include #include "voltage.h" -static int sr_class3_enable(struct voltagedomain *voltdm) +static int sr_class3_enable(struct omap_sr *sr) { - unsigned long volt = voltdm_get_voltage(voltdm); + unsigned long volt = voltdm_get_voltage(sr->voltdm); if (!volt) { pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", - __func__, voltdm->name); + __func__, sr->voltdm->name); return -ENODATA; } - omap_vp_enable(voltdm); - return sr_enable(voltdm, volt); + omap_vp_enable(sr->voltdm); + return sr_enable(sr->voltdm, volt); } -static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) +static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset) { - sr_disable_errgen(voltdm); - omap_vp_disable(voltdm); - sr_disable(voltdm); + sr_disable_errgen(sr->voltdm); + omap_vp_disable(sr->voltdm); + sr_disable(sr->voltdm); if (is_volt_reset) - voltdm_reset(voltdm); + voltdm_reset(sr->voltdm); return 0; } -static int sr_class3_configure(struct voltagedomain *voltdm) +static int sr_class3_configure(struct omap_sr *sr) { - return sr_configure_errgen(voltdm); + return sr_configure_errgen(sr->voltdm); } /* SR class3 structure */ diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 98309d32ba98..82bdd2838a17 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -34,29 +34,6 @@ #define NVALUE_NAME_LEN 40 #define SR_DISABLE_TIMEOUT 200 -struct omap_sr { - struct list_head node; - struct platform_device *pdev; - struct omap_sr_nvalue_table *nvalue_table; - struct voltagedomain *voltdm; - struct dentry *dbg_dir; - unsigned int irq; - int srid; - int ip_type; - int nvalue_count; - bool autocomp_active; - u32 clk_length; - u32 err_weight; - u32 err_minlimit; - u32 err_maxlimit; - u32 accum_data; - u32 senn_avgweight; - u32 senp_avgweight; - u32 senp_mod; - u32 senn_mod; - void __iomem *base; -}; - /* sr_list contains all the instances of smartreflex module */ static LIST_HEAD(sr_list); @@ -147,7 +124,7 @@ static irqreturn_t sr_interrupt(int irq, void *data) } if (sr_class->notify) - sr_class->notify(sr_info->voltdm, status); + sr_class->notify(sr_info, status); return IRQ_HANDLED; } @@ -225,7 +202,7 @@ static void sr_start_vddautocomp(struct omap_sr *sr) return; } - if (!sr_class->enable(sr->voltdm)) + if (!sr_class->enable(sr)) sr->autocomp_active = true; } @@ -239,7 +216,7 @@ static void sr_stop_vddautocomp(struct omap_sr *sr) } if (sr->autocomp_active) { - sr_class->disable(sr->voltdm, 1); + sr_class->disable(sr, 1); sr->autocomp_active = false; } } @@ -654,7 +631,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) return 0; /* Configure SR */ - ret = sr_class->configure(voltdm); + ret = sr_class->configure(sr); if (ret) return ret; @@ -772,7 +749,7 @@ void omap_sr_enable(struct voltagedomain *voltdm) return; } - sr_class->enable(voltdm); + sr_class->enable(sr); } /** @@ -805,7 +782,7 @@ void omap_sr_disable(struct voltagedomain *voltdm) return; } - sr_class->disable(voltdm, 0); + sr_class->disable(sr, 0); } /** @@ -838,7 +815,7 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm) return; } - sr_class->disable(voltdm, 1); + sr_class->disable(sr, 1); } /** diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index 69eb270c6297..4224698cf8bd 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -143,6 +143,29 @@ #define OMAP3430_SR_ERRWEIGHT 0x04 #define OMAP3430_SR_ERRMAXLIMIT 0x02 +struct omap_sr { + struct list_head node; + struct platform_device *pdev; + struct omap_sr_nvalue_table *nvalue_table; + struct voltagedomain *voltdm; + struct dentry *dbg_dir; + unsigned int irq; + int srid; + int ip_type; + int nvalue_count; + bool autocomp_active; + u32 clk_length; + u32 err_weight; + u32 err_minlimit; + u32 err_maxlimit; + u32 accum_data; + u32 senn_avgweight; + u32 senp_avgweight; + u32 senp_mod; + u32 senn_mod; + void __iomem *base; +}; + /** * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass * pmic specific info to smartreflex driver @@ -187,10 +210,10 @@ struct omap_smartreflex_dev_attr { * based decisions. */ struct omap_sr_class_data { - int (*enable)(struct voltagedomain *voltdm); - int (*disable)(struct voltagedomain *voltdm, int is_volt_reset); - int (*configure)(struct voltagedomain *voltdm); - int (*notify)(struct voltagedomain *voltdm, u32 status); + int (*enable)(struct omap_sr *sr); + int (*disable)(struct omap_sr *sr, int is_volt_reset); + int (*configure)(struct omap_sr *sr); + int (*notify)(struct omap_sr *sr, u32 status); u8 notify_flags; u8 class_type; }; -- GitLab From 8b765d727d711650ab3521411fd48a0d8f62a84c Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Tue, 24 Apr 2012 10:41:27 +0530 Subject: [PATCH 0062/6849] ARM: OMAP2+: smartreflex: Use the names from hwmod data instead of voltage domains. Associate a name with each SmartReflex instance from the hwmod data, rather than attempting to reuse the name of a voltage domain. The name from hwmod better reflects the smartreflex integration in the system. Also have the name passed to the drivers using pdata, which helps to remove any dependencies on SoC-specific structures. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex-class3.c | 4 +- arch/arm/mach-omap2/smartreflex.c | 65 ++++++++++-------------- arch/arm/mach-omap2/sr_device.c | 1 + include/linux/power/smartreflex.h | 3 ++ 4 files changed, 32 insertions(+), 41 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index 9381654e869b..1da8f03c479e 100644 --- a/arch/arm/mach-omap2/smartreflex-class3.c +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -19,8 +19,8 @@ static int sr_class3_enable(struct omap_sr *sr) unsigned long volt = voltdm_get_voltage(sr->voltdm); if (!volt) { - pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", - __func__, sr->voltdm->name); + pr_warning("%s: Curr voltage unknown. Cannot enable %s\n", + __func__, sr->name); return -ENODATA; } diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 82bdd2838a17..2edd1e2e4622 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -183,7 +183,7 @@ static void sr_set_regfields(struct omap_sr *sr) sr->err_weight = OMAP3430_SR_ERRWEIGHT; sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; sr->accum_data = OMAP3430_SR_ACCUMDATA; - if (!(strcmp(sr->voltdm->name, "mpu"))) { + if (!(strcmp(sr->name, "sr1"))) { sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; } else { @@ -234,19 +234,13 @@ static void sr_stop_vddautocomp(struct omap_sr *sr) */ static int sr_late_init(struct omap_sr *sr_info) { - char *name; struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; struct resource *mem; int ret = 0; if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { - name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); - if (name == NULL) { - ret = -ENOMEM; - goto error; - } ret = request_irq(sr_info->irq, sr_interrupt, - 0, name, sr_info); + 0, sr_info->name, sr_info); if (ret) goto error; disable_irq(sr_info->irq); @@ -265,7 +259,6 @@ error: dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" "interrupt handler. Smartreflex will" "not function as desired\n", __func__); - kfree(name); kfree(sr_info); return ret; @@ -395,8 +388,7 @@ int sr_configure_errgen(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return PTR_ERR(sr); } @@ -463,8 +455,7 @@ int sr_disable_errgen(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return PTR_ERR(sr); } @@ -514,8 +505,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return PTR_ERR(sr); } @@ -600,8 +590,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) int ret; if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return PTR_ERR(sr); } @@ -654,8 +643,7 @@ void sr_disable(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return; } @@ -735,8 +723,7 @@ void omap_sr_enable(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return; } @@ -768,8 +755,7 @@ void omap_sr_disable(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return; } @@ -801,8 +787,7 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm) struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { - pr_warning("%s: omap_sr struct for sr_%s not found\n", - __func__, voltdm->name); + pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); return; } @@ -889,7 +874,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) struct dentry *nvalue_dir; struct omap_volt_data *volt_data; int i, ret = 0; - char *name; sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); if (!sr_info) { @@ -926,6 +910,14 @@ static int __init omap_sr_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_irq_safe(&pdev->dev); + sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name); + if (!sr_info->name) { + dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n", + __func__); + ret = -ENOMEM; + goto err_release_region; + } + sr_info->pdev = pdev; sr_info->srid = pdev->id; sr_info->voltdm = pdata->voltdm; @@ -973,20 +965,12 @@ static int __init omap_sr_probe(struct platform_device *pdev) } } - name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); - if (!name) { - dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n", - __func__); - ret = -ENOMEM; - goto err_iounmap; - } - sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); - kfree(name); + sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir); if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); ret = PTR_ERR(sr_info->dbg_dir); - goto err_iounmap; + goto err_free_name; } (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, @@ -1008,10 +992,10 @@ static int __init omap_sr_probe(struct platform_device *pdev) omap_voltage_get_volttable(sr_info->voltdm, &volt_data); if (!volt_data) { - dev_warn(&pdev->dev, "%s: No Voltage table for the" - " corresponding vdd vdd_%s. Cannot create debugfs" + dev_warn(&pdev->dev, "%s: %s: No Voltage table for the" + " corresponding vdd. Cannot create debugfs" "entries for n-values\n", - __func__, sr_info->voltdm->name); + __func__, sr_info->name); ret = -ENODATA; goto err_debugfs; } @@ -1029,6 +1013,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) err_debugfs: debugfs_remove_recursive(sr_info->dbg_dir); +err_free_name: + kfree(sr_info->name); err_iounmap: list_del(&sr_info->node); iounmap(sr_info->base); @@ -1065,6 +1051,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) list_del(&sr_info->node); iounmap(sr_info->base); + kfree(sr_info->name); kfree(sr_info); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, resource_size(mem)); diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 86e438e75105..e081174f28af 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -93,6 +93,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) goto exit; } + sr_data->name = oh->name; sr_data->ip_type = oh->class->rev; sr_data->senn_mod = 0x1; sr_data->senp_mod = 0x1; diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index 4224698cf8bd..884eaeea96be 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -144,6 +144,7 @@ #define OMAP3430_SR_ERRMAXLIMIT 0x02 struct omap_sr { + char *name; struct list_head node; struct platform_device *pdev; struct omap_sr_nvalue_table *nvalue_table; @@ -232,6 +233,7 @@ struct omap_sr_nvalue_table { /** * struct omap_sr_data - Smartreflex platform data. * + * @name: instance name * @ip_type: Smartreflex IP type. * @senp_mod: SENPENABLE value for the sr * @senn_mod: SENNENABLE value for sr @@ -243,6 +245,7 @@ struct omap_sr_nvalue_table { * @voltdm: Pointer to the voltage domain associated with the SR */ struct omap_sr_data { + const char *name; int ip_type; u32 senp_mod; u32 senn_mod; -- GitLab From 1fcd3069d4944ad0532f41fbc4957ba24552a92f Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Tue, 24 Apr 2012 10:47:14 +0530 Subject: [PATCH 0063/6849] ARM: OMAP3: hwmod: rename the smartreflex entries Change the name field value to better reflect the smartreflex integration in the system. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 8 ++++---- arch/arm/mach-omap2/smartreflex.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8c7241b7279c..0d611d3d0d03 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1325,7 +1325,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = { }; static struct omap_hwmod omap34xx_sr1_hwmod = { - .name = "sr1", + .name = "smartreflex_mpu_iva", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", .prcm = { @@ -1343,7 +1343,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { }; static struct omap_hwmod omap36xx_sr1_hwmod = { - .name = "sr1", + .name = "smartreflex_mpu_iva", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", .prcm = { @@ -1370,7 +1370,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = { }; static struct omap_hwmod omap34xx_sr2_hwmod = { - .name = "sr2", + .name = "smartreflex_core", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", .prcm = { @@ -1388,7 +1388,7 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { }; static struct omap_hwmod omap36xx_sr2_hwmod = { - .name = "sr2", + .name = "smartreflex_core", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", .prcm = { diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 2edd1e2e4622..d8592771838f 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -183,7 +183,7 @@ static void sr_set_regfields(struct omap_sr *sr) sr->err_weight = OMAP3430_SR_ERRWEIGHT; sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; sr->accum_data = OMAP3430_SR_ACCUMDATA; - if (!(strcmp(sr->name, "sr1"))) { + if (!(strcmp(sr->name, "smartreflex_mpu_iva"))) { sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; } else { -- GitLab From 50e4a7d0b26c86628300edf4625cc5ff16a7a227 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Tue, 24 Apr 2012 10:56:40 +0530 Subject: [PATCH 0064/6849] ARM: OMAP2+: SmartReflex: introduce a busy loop condition test macro Now that omap_test_timeout is only accessible from mach-omap2/, introduce a similar function for SR. This change makes the SmartReflex implementation ready for the move to drivers/. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 12 ++++++------ include/linux/power/smartreflex.h | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index d8592771838f..acef08d837cc 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -289,9 +289,9 @@ static void sr_v1_disable(struct omap_sr *sr) * Wait for SR to be disabled. * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us. */ - omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) & - ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT, - timeout); + sr_test_cond_timeout((sr_read_reg(sr, ERRCONFIG_V1) & + ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT, + timeout); if (timeout >= SR_DISABLE_TIMEOUT) dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", @@ -334,9 +334,9 @@ static void sr_v2_disable(struct omap_sr *sr) * Wait for SR to be disabled. * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us. */ - omap_test_timeout((sr_read_reg(sr, IRQSTATUS) & - IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT, - timeout); + sr_test_cond_timeout((sr_read_reg(sr, IRQSTATUS) & + IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT, + timeout); if (timeout >= SR_DISABLE_TIMEOUT) dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index 884eaeea96be..78b795ea2709 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -22,7 +22,7 @@ #include #include - +#include #include /* @@ -167,6 +167,27 @@ struct omap_sr { void __iomem *base; }; +/** + * test_cond_timeout - busy-loop, testing a condition + * @cond: condition to test until it evaluates to true + * @timeout: maximum number of microseconds in the timeout + * @index: loop index (integer) + * + * Loop waiting for @cond to become true or until at least @timeout + * microseconds have passed. To use, define some integer @index in the + * calling code. After running, if @index == @timeout, then the loop has + * timed out. + * + * Copied from omap_test_timeout */ +#define sr_test_cond_timeout(cond, timeout, index) \ +({ \ + for (index = 0; index < timeout; index++) { \ + if (cond) \ + break; \ + udelay(1); \ + } \ +}) + /** * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass * pmic specific info to smartreflex driver -- GitLab From fa60be6e3f9362bd841e26b9366f0db7b761a042 Mon Sep 17 00:00:00 2001 From: J Keerthy Date: Wed, 25 Apr 2012 11:14:31 +0530 Subject: [PATCH 0065/6849] ARM: OMAP2+: Voltage: Move the omap_volt_data structure to plat Move the omap_volt_data structure from mach-omap2/ directory to arch/arm/plat-omap/include/plat/ so that it is accessible from both mach-omap2 and drivers directories. Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/voltage.h | 21 ++------------------- arch/arm/plat-omap/include/plat/voltage.h | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index 16a1b092cf36..34ef504adafd 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h @@ -16,6 +16,8 @@ #include +#include + #include "vc.h" #include "vp.h" @@ -90,25 +92,6 @@ struct voltagedomain { struct omap_volt_data *volt_data; }; -/** - * struct omap_volt_data - Omap voltage specific data. - * @voltage_nominal: The possible voltage value in uV - * @sr_efuse_offs: The offset of the efuse register(from system - * control module base address) from where to read - * the n-target value for the smartreflex module. - * @sr_errminlimit: Error min limit value for smartreflex. This value - * differs at differnet opp and thus is linked - * with voltage. - * @vp_errorgain: Error gain value for the voltage processor. This - * field also differs according to the voltage/opp. - */ -struct omap_volt_data { - u32 volt_nominal; - u32 sr_efuse_offs; - u8 sr_errminlimit; - u8 vp_errgain; -}; - /** * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. * @slew_rate: PMIC slew rate (in uv/us) diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h index 0a6a482ec014..5be4d5def427 100644 --- a/arch/arm/plat-omap/include/plat/voltage.h +++ b/arch/arm/plat-omap/include/plat/voltage.h @@ -11,10 +11,29 @@ #ifndef __ARCH_ARM_OMAP_VOLTAGE_H #define __ARCH_ARM_OMAP_VOLTAGE_H +/** + * struct omap_volt_data - Omap voltage specific data. + * @voltage_nominal: The possible voltage value in uV + * @sr_efuse_offs: The offset of the efuse register(from system + * control module base address) from where to read + * the n-target value for the smartreflex module. + * @sr_errminlimit: Error min limit value for smartreflex. This value + * differs at differnet opp and thus is linked + * with voltage. + * @vp_errorgain: Error gain value for the voltage processor. This + * field also differs according to the voltage/opp. + */ +struct omap_volt_data { + u32 volt_nominal; + u32 sr_efuse_offs; + u8 sr_errminlimit; + u8 vp_errgain; +}; struct voltagedomain; struct voltagedomain *voltdm_lookup(const char *name); int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt); unsigned long voltdm_get_voltage(struct voltagedomain *voltdm); - +struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, + unsigned long volt); #endif -- GitLab From 5e7f2e12e4ea14a34fb9b5941d60a4464fc8d40a Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Wed, 25 Apr 2012 11:19:44 +0530 Subject: [PATCH 0066/6849] ARM: OMAP2+: SmartReflex: Use per-OPP data structure The SmartReflex driver incorrectly treats some per-OPP data as data common to all OPPs (e.g., ERRMINLIMIT). Move this data into a per-OPP data structure. Furthermore, in order to make the SmartReflex implementation ready for the move to drivers/, remove the dependency from the SR driver code to the voltage layer by querying the data tables only from the SR device init code. Based on Paul's original code for the SmartReflex driver conversion. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 38 +++++++++++++++---------------- arch/arm/mach-omap2/sr_device.c | 36 ++++++++++++++++++++++++----- include/linux/power/smartreflex.h | 8 +++++-- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index acef08d837cc..20075de13868 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -347,22 +347,23 @@ static void sr_v2_disable(struct omap_sr *sr) sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT); } -static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) +static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row( + struct omap_sr *sr, u32 efuse_offs) { int i; if (!sr->nvalue_table) { dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n", __func__); - return 0; + return NULL; } for (i = 0; i < sr->nvalue_count; i++) { if (sr->nvalue_table[i].efuse_offs == efuse_offs) - return sr->nvalue_table[i].nvalue; + return &sr->nvalue_table[i]; } - return 0; + return NULL; } /* Public Functions */ @@ -586,7 +587,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) { struct omap_volt_data *volt_data; struct omap_sr *sr = _sr_lookup(voltdm); - u32 nvalue_reciprocal; + struct omap_sr_nvalue_table *nvalue_row; int ret; if (IS_ERR(sr)) { @@ -602,16 +603,16 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) return PTR_ERR(volt_data); } - nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); + nvalue_row = sr_retrieve_nvalue_row(sr, volt_data->sr_efuse_offs); - if (!nvalue_reciprocal) { - dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n", - __func__, volt); + if (!nvalue_row) { + dev_warn(&sr->pdev->dev, "%s: failure getting SR data for this voltage %ld\n", + __func__, volt); return -ENODATA; } /* errminlimit is opp dependent and hence linked to voltage */ - sr->err_minlimit = volt_data->sr_errminlimit; + sr->err_minlimit = nvalue_row->errminlimit; pm_runtime_get_sync(&sr->pdev->dev); @@ -624,7 +625,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) if (ret) return ret; - sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal); + sr_write_reg(sr, NVALUERECIPROCAL, nvalue_row->nvalue); /* SRCONFIG - enable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE); @@ -872,7 +873,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; struct dentry *nvalue_dir; - struct omap_volt_data *volt_data; int i, ret = 0; sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); @@ -990,12 +990,10 @@ static int __init omap_sr_probe(struct platform_device *pdev) goto err_debugfs; } - omap_voltage_get_volttable(sr_info->voltdm, &volt_data); - if (!volt_data) { - dev_warn(&pdev->dev, "%s: %s: No Voltage table for the" - " corresponding vdd. Cannot create debugfs" - "entries for n-values\n", - __func__, sr_info->name); + if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) { + dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n", + __func__, sr_info->name); + ret = -ENODATA; goto err_debugfs; } @@ -1003,8 +1001,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) for (i = 0; i < sr_info->nvalue_count; i++) { char name[NVALUE_NAME_LEN + 1]; - snprintf(name, sizeof(name), "volt_%d", - volt_data[i].volt_nominal); + snprintf(name, sizeof(name), "volt_%lu", + sr_info->nvalue_table[i].volt_nominal); (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, &(sr_info->nvalue_table[i].nvalue)); } diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index e081174f28af..e107e3915a8a 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -36,7 +36,10 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, struct omap_sr_data *sr_data) { struct omap_sr_nvalue_table *nvalue_table; - int i, count = 0; + int i, j, count = 0; + + sr_data->nvalue_count = 0; + sr_data->nvalue_table = NULL; while (volt_data[count].volt_nominal) count++; @@ -44,8 +47,14 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, GFP_KERNEL); - for (i = 0; i < count; i++) { + if (!nvalue_table) { + pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n"); + return; + } + + for (i = 0, j = 0; i < count; i++) { u32 v; + /* * In OMAP4 the efuse registers are 24 bit aligned. * A __raw_readl will fail for non-32 bit aligned address @@ -58,15 +67,30 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, omap_ctrl_readb(offset + 1) << 8 | omap_ctrl_readb(offset + 2) << 16; } else { - v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); + v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); } - nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; - nvalue_table[i].nvalue = v; + /* + * Many OMAP SoCs don't have the eFuse values set. + * For example, pretty much all OMAP3xxx before + * ES3.something. + * + * XXX There needs to be some way for board files or + * userspace to add these in. + */ + if (v == 0) + continue; + + nvalue_table[j].nvalue = v; + nvalue_table[j].efuse_offs = volt_data[i].sr_efuse_offs; + nvalue_table[j].errminlimit = volt_data[i].sr_errminlimit; + nvalue_table[j].volt_nominal = volt_data[i].volt_nominal; + + j++; } sr_data->nvalue_table = nvalue_table; - sr_data->nvalue_count = count; + sr_data->nvalue_count = j; } static int __init sr_dev_init(struct omap_hwmod *oh, void *user) diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index 78b795ea2709..222f90183712 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -243,12 +243,16 @@ struct omap_sr_class_data { /** * struct omap_sr_nvalue_table - Smartreflex n-target value info * - * @efuse_offs: The offset of the efuse where n-target values are stored. - * @nvalue: The n-target value. + * @efuse_offs: The offset of the efuse where n-target values are stored. + * @nvalue: The n-target value. + * @errminlimit: The value of the ERRMINLIMIT bitfield for this n-target + * @volt_nominal: microvolts DC that the VDD is initially programmed to */ struct omap_sr_nvalue_table { u32 efuse_offs; u32 nvalue; + u32 errminlimit; + unsigned long volt_nominal; }; /** -- GitLab From 308d1bd0a7e6fedafacc389b134ef54458e39f4d Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Tue, 24 Apr 2012 23:41:54 +0530 Subject: [PATCH 0067/6849] ARM: OMAP2+: SmartReflex: Create per-opp debugfs node for errminlimit Remove the global errminlimit debugfs entry and create per-voltage entries from the data tables. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 20075de13868..515041ccccb8 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -979,8 +979,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) &sr_info->err_weight); (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, &sr_info->err_maxlimit); - (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir, - &sr_info->err_minlimit); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); if (IS_ERR_OR_NULL(nvalue_dir)) { @@ -1005,6 +1003,11 @@ static int __init omap_sr_probe(struct platform_device *pdev) sr_info->nvalue_table[i].volt_nominal); (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, &(sr_info->nvalue_table[i].nvalue)); + snprintf(name, sizeof(name), "errminlimit_%lu", + sr_info->nvalue_table[i].volt_nominal); + (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, + &(sr_info->nvalue_table[i].errminlimit)); + } return ret; -- GitLab From 7fb149ffe357d6ad672cf9325181530b4c478a81 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Tue, 24 Apr 2012 11:38:50 +0530 Subject: [PATCH 0068/6849] ARM: OMAP2+: SmartReflex: add POWER_AVS Kconfig options Add a Kconfig menu (POWER_AVS) and rename the Kconfig options for the OMAP SmartReflex implementation: CONFIG_OMAP_SMARTREFLEX renames to CONFIG_POWER_AVS_OMAP CONFIG_OMAP_SMARTREFLEX_CLASS3 renames to CONFIG_POWER_AVS_OMAP_CLASS3 This change makes the SmartReflex implementation ready for the move to drivers/. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Makefile | 5 ++-- arch/arm/mach-omap2/pm.h | 2 +- arch/arm/plat-omap/Kconfig | 45 ++++++++++++++++++++----------- include/linux/power/smartreflex.h | 2 +- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 385c083d24b2..518444acc90f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -69,8 +69,9 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \ cpuidle44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o -obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o -obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o + +obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o smartreflex.o +obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 78564895e914..9fac67d6c985 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -88,7 +88,7 @@ extern void enable_omap3630_toggle_l2_on_restore(void); static inline void enable_omap3630_toggle_l2_on_restore(void) { } #endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ -#ifdef CONFIG_OMAP_SMARTREFLEX +#ifdef CONFIG_POWER_AVS_OMAP extern int omap_devinit_smartreflex(void); extern void omap_enable_smartreflex_on_init(void); #else diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index ad95c7a5d009..bba384dfbcf6 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -45,37 +45,52 @@ config OMAP_DEBUG_LEDS depends on OMAP_DEBUG_DEVICES default y if LEDS_CLASS -config OMAP_SMARTREFLEX - bool "SmartReflex support" - depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM +menuconfig POWER_AVS + tristate "Adaptive Voltage Scaling class support" help - Say Y if you want to enable SmartReflex. + AVS(Adaptive Voltage Scaling) is a power management technique which + finely controls the operating voltage of a device in order to optimize + (i.e. reduce) its power consumption. + At a given operating point the voltage is adapted depending on + static factors (chip manufacturing process) and dynamic factors + (temperature depending performance). + AVS is also called SmartReflex on OMAP devices. + + Say Y here to enable Adaptive Voltage Scaling class support. + +if POWER_AVS - SmartReflex can perform continuous dynamic voltage - scaling around the nominal operating point voltage - according to silicon characteristics and operating - conditions. Enabling SmartReflex reduces power - consumption. +config POWER_AVS_OMAP + bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2" + depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM + help + Say Y to enable AVS support on OMAP containing the version 1 or + version 2 of the SmartReflex IP. + V1 is the 65nm version used in OMAP3430. + V2 is the update for the 45nm version of the IP used in OMAP3630 + and OMAP4430 Please note, that by default SmartReflex is only - initialized. To enable the automatic voltage - compensation for vdd mpu and vdd core from user space, + initialized and not enabled. To enable the automatic voltage + compensation for vdd mpu and vdd core from user space, user must write 1 to - /debug/voltage/vdd_/smartreflex/autocomp, - where X is mpu or core for OMAP3. + /debug/smartreflex/sr_/autocomp, + where X is mpu_iva or core for OMAP3. Optionally autocompensation can be enabled in the kernel by default during system init via the enable_on_init flag which an be passed as platform data to the smartreflex driver. -config OMAP_SMARTREFLEX_CLASS3 +config POWER_AVS_OMAP_CLASS3 bool "Class 3 mode of Smartreflex Implementation" - depends on OMAP_SMARTREFLEX && TWL4030_CORE + depends on POWER_AVS_OMAP && TWL4030_CORE help Say Y to enable Class 3 implementation of Smartreflex Class 3 implementation of Smartreflex employs continuous hardware voltage calibration. +endif # POWER_AVS + config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAP diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index 222f90183712..3101e62a1213 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -207,7 +207,7 @@ struct omap_smartreflex_dev_attr { const char *sensor_voltdm_name; }; -#ifdef CONFIG_OMAP_SMARTREFLEX +#ifdef CONFIG_POWER_AVS_OMAP /* * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. * The smartreflex class driver should pass the class type. -- GitLab From 21ff63ad131218048525fbd37d065ce61f03bcbd Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Wed, 25 Apr 2012 16:43:17 +0530 Subject: [PATCH 0069/6849] ARM: OMAP: SmartReflex: Move smartreflex driver to drivers/ After a clean-up of the interfaces the OMAP Smartreflex IP driver is now a generic driver. Move it to drivers/power/avs/. The build is controlled by the following Kconfig options: . CONFIG_POWER_AVS: general knob for Adaptive Voltage Scaling support, . CONFIG_POWER_AVS_OMAP: AVS(Adaptive Voltage Scaling) support on OMAP containing the version 1 or version 2 of the SmartReflex IP, . CONFIG_POWER_AVS_OMAP_CLASS3: Class 3 implementation of Smartreflex. Signed-off-by: Jean Pihet Signed-off-by: J Keerthy Acked-by: Rafael J. Wysocki Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Makefile | 4 ++-- arch/arm/plat-omap/Kconfig | 22 +++---------------- drivers/power/Kconfig | 2 ++ drivers/power/Makefile | 1 + drivers/power/avs/Kconfig | 12 ++++++++++ drivers/power/avs/Makefile | 1 + .../power/avs}/smartreflex.c | 5 +---- 7 files changed, 22 insertions(+), 25 deletions(-) create mode 100644 drivers/power/avs/Kconfig create mode 100644 drivers/power/avs/Makefile rename {arch/arm/mach-omap2 => drivers/power/avs}/smartreflex.c (99%) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 518444acc90f..f8ee10a06f46 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -70,8 +70,8 @@ obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \ cpuidle44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o -obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o smartreflex.o -obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o +obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o +obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index bba384dfbcf6..816dec062f3c 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -45,26 +45,12 @@ config OMAP_DEBUG_LEDS depends on OMAP_DEBUG_DEVICES default y if LEDS_CLASS -menuconfig POWER_AVS - tristate "Adaptive Voltage Scaling class support" - help - AVS(Adaptive Voltage Scaling) is a power management technique which - finely controls the operating voltage of a device in order to optimize - (i.e. reduce) its power consumption. - At a given operating point the voltage is adapted depending on - static factors (chip manufacturing process) and dynamic factors - (temperature depending performance). - AVS is also called SmartReflex on OMAP devices. - - Say Y here to enable Adaptive Voltage Scaling class support. - -if POWER_AVS - config POWER_AVS_OMAP bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2" - depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM + depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM help - Say Y to enable AVS support on OMAP containing the version 1 or + Say Y to enable AVS(Adaptive Voltage Scaling) + support on OMAP containing the version 1 or version 2 of the SmartReflex IP. V1 is the 65nm version used in OMAP3430. V2 is the update for the 45nm version of the IP used in OMAP3630 @@ -89,8 +75,6 @@ config POWER_AVS_OMAP_CLASS3 Class 3 implementation of Smartreflex employs continuous hardware voltage calibration. -endif # POWER_AVS - config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAP diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 99dc29f2f2f2..d416773771ef 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -308,3 +308,5 @@ config AB8500_BATTERY_THERM_ON_BATCTRL Say Y to enable battery temperature measurements using thermistor connected on BATCTRL ADC. endif # POWER_SUPPLY + +source "drivers/power/avs/Kconfig" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index b6b243416c0e..ee58afb1e71f 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -43,4 +43,5 @@ obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o +obj-$(CONFIG_POWER_AVS) += avs/ obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig new file mode 100644 index 000000000000..18493f7a8f6f --- /dev/null +++ b/drivers/power/avs/Kconfig @@ -0,0 +1,12 @@ +menuconfig POWER_AVS + tristate "Adaptive Voltage Scaling class support" + help + AVS is a power management technique which finely controls the + operating voltage of a device in order to optimize (i.e. reduce) + its power consumption. + At a given operating point the voltage is adapted depending on + static factors (chip manufacturing process) and dynamic factors + (temperature depending performance). + AVS is also called SmartReflex on OMAP devices. + + Say Y here to enable Adaptive Voltage Scaling class support. diff --git a/drivers/power/avs/Makefile b/drivers/power/avs/Makefile new file mode 100644 index 000000000000..0843386a6c19 --- /dev/null +++ b/drivers/power/avs/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_POWER_AVS_OMAP) += smartreflex.o diff --git a/arch/arm/mach-omap2/smartreflex.c b/drivers/power/avs/smartreflex.c similarity index 99% rename from arch/arm/mach-omap2/smartreflex.c rename to drivers/power/avs/smartreflex.c index 515041ccccb8..44efc6e202af 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/drivers/power/avs/smartreflex.c @@ -3,7 +3,7 @@ * * Author: Thara Gopinath * - * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2012 Texas Instruments, Inc. * Thara Gopinath * * Copyright (C) 2008 Nokia Corporation @@ -27,9 +27,6 @@ #include #include -#include "common.h" -#include "pm.h" - #define SMARTREFLEX_NAME_LEN 16 #define NVALUE_NAME_LEN 40 #define SR_DISABLE_TIMEOUT 200 -- GitLab From 92a9f14b8b8e5ade5b49bcd6b95fc05f85a39e90 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 30 May 2012 21:16:16 +0100 Subject: [PATCH 0070/6849] Fix comment typo multipy -> multiply Signed-off-by: Ralf Baechle Signed-off-by: Jiri Kosina --- drivers/input/misc/cma3000_d0x.c | 2 +- sound/oss/vwsnd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index a3735a01e9fd..df9b756594f8 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c @@ -58,7 +58,7 @@ /* * Bit weights in mg for bit 0, other bits need - * multipy factor 2^n. Eight bit is the sign bit. + * multiply factor 2^n. Eight bit is the sign bit. */ #define BIT_TO_2G 18 #define BIT_TO_8G 71 diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index 643f1113b1d8..7e814a5c3677 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -438,7 +438,7 @@ static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val) * * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)). * As long as mask is constant, we trust the compiler will change the - * multipy and divide into shifts. + * multiply and divide into shifts. */ #define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask)) -- GitLab From d2582a7afcf732cf234adbf14aa7d11a08e30e09 Mon Sep 17 00:00:00 2001 From: Kazuo Moriwaka Date: Mon, 28 May 2012 12:06:44 +0900 Subject: [PATCH 0071/6849] Doc: document max raw dev number Documenting description about max minor number of raw devices. Signed-off-by: Kazuo Moriwaka Signed-off-by: Jiri Kosina --- Documentation/devices.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 47a154f30290..b6251cca9263 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -2416,6 +2416,8 @@ Your cooperation is appreciated. 1 = /dev/raw/raw1 First raw I/O device 2 = /dev/raw/raw2 Second raw I/O device ... + max minor number of raw device is set by kernel config + MAX_RAW_DEVS or raw module parameter 'max_raw_devs' 163 char -- GitLab From 0bf79ef2c303cc70d036c9fb355aeb468e8efb62 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:08:52 -0600 Subject: [PATCH 0072/6849] ASoC: wm8903: init GPIOs during I2C probe not codec probe This allows the GPIOs to be available as soon as the I2C device has probed, which in turn enables machine drivers to request the GPIOs in their probe(), rather than deferring this to their ASoC machine init function, i.e. after the whole sound card has been constructed, and hence the WM8903 codec is available. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 48 ++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 86b8a2926591..f6a3fc5f09c0 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -2,7 +2,7 @@ * wm8903.c -- WM8903 ALSA SoC Audio driver * * Copyright 2008 Wolfson Microelectronics - * Copyright 2011 NVIDIA, Inc. + * Copyright 2011-2012 NVIDIA, Inc. * * Author: Mark Brown * @@ -116,6 +116,7 @@ static const struct reg_default wm8903_reg_defaults[] = { struct wm8903_priv { struct wm8903_platform_data *pdata; + struct device *dev; struct snd_soc_codec *codec; struct regmap *regmap; @@ -1774,7 +1775,6 @@ static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset) static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); - struct snd_soc_codec *codec = wm8903->codec; unsigned int mask, val; int ret; @@ -1782,8 +1782,8 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | WM8903_GP1_DIR; - ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, - mask, val); + ret = regmap_update_bits(wm8903->regmap, + WM8903_GPIO_CONTROL_1 + offset, mask, val); if (ret < 0) return ret; @@ -1793,10 +1793,9 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) { struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); - struct snd_soc_codec *codec = wm8903->codec; - int reg; + unsigned int reg; - reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset); + regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, ®); return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; } @@ -1805,7 +1804,6 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, unsigned offset, int value) { struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); - struct snd_soc_codec *codec = wm8903->codec; unsigned int mask, val; int ret; @@ -1813,8 +1811,8 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | (value << WM8903_GP2_LVL_SHIFT); - ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, - mask, val); + ret = regmap_update_bits(wm8903->regmap, + WM8903_GPIO_CONTROL_1 + offset, mask, val); if (ret < 0) return ret; @@ -1824,11 +1822,10 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); - struct snd_soc_codec *codec = wm8903->codec; - snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, - WM8903_GP1_LVL_MASK, - !!value << WM8903_GP1_LVL_SHIFT); + regmap_update_bits(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, + WM8903_GP1_LVL_MASK, + !!value << WM8903_GP1_LVL_SHIFT); } static struct gpio_chip wm8903_template_chip = { @@ -1842,15 +1839,14 @@ static struct gpio_chip wm8903_template_chip = { .can_sleep = 1, }; -static void wm8903_init_gpio(struct snd_soc_codec *codec) +static void wm8903_init_gpio(struct wm8903_priv *wm8903) { - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); struct wm8903_platform_data *pdata = wm8903->pdata; int ret; wm8903->gpio_chip = wm8903_template_chip; wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; - wm8903->gpio_chip.dev = codec->dev; + wm8903->gpio_chip.dev = wm8903->dev; if (pdata->gpio_base) wm8903->gpio_chip.base = pdata->gpio_base; @@ -1859,24 +1855,23 @@ static void wm8903_init_gpio(struct snd_soc_codec *codec) ret = gpiochip_add(&wm8903->gpio_chip); if (ret != 0) - dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); + dev_err(wm8903->dev, "Failed to add GPIOs: %d\n", ret); } -static void wm8903_free_gpio(struct snd_soc_codec *codec) +static void wm8903_free_gpio(struct wm8903_priv *wm8903) { - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); int ret; ret = gpiochip_remove(&wm8903->gpio_chip); if (ret != 0) - dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); + dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret); } #else -static void wm8903_init_gpio(struct snd_soc_codec *codec) +static void wm8903_init_gpio(struct wm8903_priv *wm8903) { } -static void wm8903_free_gpio(struct snd_soc_codec *codec) +static void wm8903_free_gpio(struct wm8903_priv *wm8903) { } #endif @@ -2000,8 +1995,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); - wm8903_init_gpio(codec); - return ret; } @@ -2010,7 +2003,6 @@ static int wm8903_remove(struct snd_soc_codec *codec) { struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - wm8903_free_gpio(codec); wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); if (wm8903->irq) free_irq(wm8903->irq, codec); @@ -2130,6 +2122,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, GFP_KERNEL); if (wm8903 == NULL) return -ENOMEM; + wm8903->dev = &i2c->dev; wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); if (IS_ERR(wm8903->regmap)) { @@ -2189,6 +2182,8 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, /* Reset the device */ regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); + wm8903_init_gpio(wm8903); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8903, &wm8903_dai, 1); if (ret != 0) @@ -2204,6 +2199,7 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client) { struct wm8903_priv *wm8903 = i2c_get_clientdata(client); + wm8903_free_gpio(wm8903); regmap_exit(wm8903->regmap); snd_soc_unregister_codec(&client->dev); -- GitLab From f51022f1aedc4d1a02d0dfa8fde47f6a8291f618 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:08:54 -0600 Subject: [PATCH 0073/6849] ASoC: tegra+wm8903: move all GPIO setup into probe Now that deferred probe exists, we can parse device tree and request GPIOs from probe(), rather than deferring this to the DAI link's init(). Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 162 +++++++++++++++++---------------- 1 file changed, 83 insertions(+), 79 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0b0df49d9d33..a8a3103ab4cb 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -245,80 +245,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = &machine->pdata; - struct device_node *np = card->dev->of_node; - int ret; - - if (card->dev->platform_data) { - memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); - } else if (np) { - /* - * This part must be in init() rather than probe() in order to - * guarantee that the WM8903 has been probed, and hence its - * GPIO controller registered, which is a pre-condition for - * of_get_named_gpio() to be able to map the phandles in the - * properties to the controller node. Given this, all - * pdata handling is in init() for consistency. - */ - pdata->gpio_spkr_en = of_get_named_gpio(np, - "nvidia,spkr-en-gpios", 0); - pdata->gpio_hp_mute = of_get_named_gpio(np, - "nvidia,hp-mute-gpios", 0); - pdata->gpio_hp_det = of_get_named_gpio(np, - "nvidia,hp-det-gpios", 0); - pdata->gpio_int_mic_en = of_get_named_gpio(np, - "nvidia,int-mic-en-gpios", 0); - pdata->gpio_ext_mic_en = of_get_named_gpio(np, - "nvidia,ext-mic-en-gpios", 0); - } else { - dev_err(card->dev, "No platform data supplied\n"); - return -EINVAL; - } - - if (gpio_is_valid(pdata->gpio_spkr_en)) { - ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); - if (ret) { - dev_err(card->dev, "cannot get spkr_en gpio\n"); - return ret; - } - machine->gpio_requested |= GPIO_SPKR_EN; - - gpio_direction_output(pdata->gpio_spkr_en, 0); - } - - if (gpio_is_valid(pdata->gpio_hp_mute)) { - ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); - if (ret) { - dev_err(card->dev, "cannot get hp_mute gpio\n"); - return ret; - } - machine->gpio_requested |= GPIO_HP_MUTE; - - gpio_direction_output(pdata->gpio_hp_mute, 1); - } - - if (gpio_is_valid(pdata->gpio_int_mic_en)) { - ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); - if (ret) { - dev_err(card->dev, "cannot get int_mic_en gpio\n"); - return ret; - } - machine->gpio_requested |= GPIO_INT_MIC_EN; - - /* Disable int mic; enable signal is active-high */ - gpio_direction_output(pdata->gpio_int_mic_en, 0); - } - - if (gpio_is_valid(pdata->gpio_ext_mic_en)) { - ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); - if (ret) { - dev_err(card->dev, "cannot get ext_mic_en gpio\n"); - return ret; - } - machine->gpio_requested |= GPIO_EXT_MIC_EN; - - /* Enable ext mic; enable signal is active-low */ - gpio_direction_output(pdata->gpio_ext_mic_en, 0); - } if (gpio_is_valid(pdata->gpio_hp_det)) { tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; @@ -372,8 +298,10 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_tegra_wm8903; struct tegra_wm8903 *machine; + struct tegra_wm8903_platform_data *pdata; int ret; if (!pdev->dev.platform_data && !pdev->dev.of_node) { @@ -388,12 +316,42 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) ret = -ENOMEM; goto err; } + pdata = &machine->pdata; card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); - if (pdev->dev.of_node) { + if (pdev->dev.platform_data) { + memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); + } else if (np) { + pdata->gpio_spkr_en = of_get_named_gpio(np, + "nvidia,spkr-en-gpios", 0); + if (pdata->gpio_spkr_en == -ENODEV) + return -EPROBE_DEFER; + + pdata->gpio_hp_mute = of_get_named_gpio(np, + "nvidia,hp-mute-gpios", 0); + if (pdata->gpio_hp_mute == -ENODEV) + return -EPROBE_DEFER; + + pdata->gpio_hp_det = of_get_named_gpio(np, + "nvidia,hp-det-gpios", 0); + if (pdata->gpio_hp_det == -ENODEV) + return -EPROBE_DEFER; + + pdata->gpio_int_mic_en = of_get_named_gpio(np, + "nvidia,int-mic-en-gpios", 0); + if (pdata->gpio_int_mic_en == -ENODEV) + return -EPROBE_DEFER; + + pdata->gpio_ext_mic_en = of_get_named_gpio(np, + "nvidia,ext-mic-en-gpios", 0); + if (pdata->gpio_ext_mic_en == -ENODEV) + return -EPROBE_DEFER; + } + + if (np) { ret = snd_soc_of_parse_card_name(card, "nvidia,model"); if (ret) goto err; @@ -404,8 +362,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) goto err; tegra_wm8903_dai.codec_name = NULL; - tegra_wm8903_dai.codec_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,audio-codec", 0); + tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, + "nvidia,audio-codec", 0); if (!tegra_wm8903_dai.codec_of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); @@ -414,8 +372,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) } tegra_wm8903_dai.cpu_dai_name = NULL; - tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,i2s-controller", 0); + tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); if (!tegra_wm8903_dai.cpu_dai_of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); @@ -442,6 +400,52 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) } } + if (gpio_is_valid(pdata->gpio_spkr_en)) { + ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); + if (ret) { + dev_err(card->dev, "cannot get spkr_en gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_SPKR_EN; + + gpio_direction_output(pdata->gpio_spkr_en, 0); + } + + if (gpio_is_valid(pdata->gpio_hp_mute)) { + ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); + if (ret) { + dev_err(card->dev, "cannot get hp_mute gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_HP_MUTE; + + gpio_direction_output(pdata->gpio_hp_mute, 1); + } + + if (gpio_is_valid(pdata->gpio_int_mic_en)) { + ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); + if (ret) { + dev_err(card->dev, "cannot get int_mic_en gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_INT_MIC_EN; + + /* Disable int mic; enable signal is active-high */ + gpio_direction_output(pdata->gpio_int_mic_en, 0); + } + + if (gpio_is_valid(pdata->gpio_ext_mic_en)) { + ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); + if (ret) { + dev_err(card->dev, "cannot get ext_mic_en gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_EXT_MIC_EN; + + /* Enable ext mic; enable signal is active-low */ + gpio_direction_output(pdata->gpio_ext_mic_en, 0); + } + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) goto err; -- GitLab From e2d287c179a12a6069bc3b746e2e34edcddf81b3 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:08:55 -0600 Subject: [PATCH 0074/6849] ASoC: tegra+wm8903: Use devm_gpio_request_one By using this function, the driver no longer needs to explicitly free the GPIOs. Hence, we can also remove the flags we use to track whether we allocated these GPIOs. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 42 ++++++++-------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index a8a3103ab4cb..5ef2063e0ab1 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -50,10 +50,6 @@ #define DRV_NAME "tegra-snd-wm8903" -#define GPIO_SPKR_EN BIT(0) -#define GPIO_HP_MUTE BIT(1) -#define GPIO_INT_MIC_EN BIT(2) -#define GPIO_EXT_MIC_EN BIT(3) #define GPIO_HP_DET BIT(4) struct tegra_wm8903 { @@ -401,49 +397,41 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) } if (gpio_is_valid(pdata->gpio_spkr_en)) { - ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); + ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en, + GPIOF_OUT_INIT_LOW, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } - machine->gpio_requested |= GPIO_SPKR_EN; - - gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { - ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); + ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute, + GPIOF_OUT_INIT_HIGH, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } - machine->gpio_requested |= GPIO_HP_MUTE; - - gpio_direction_output(pdata->gpio_hp_mute, 1); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { - ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); + /* Disable int mic; enable signal is active-high */ + ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en, + GPIOF_OUT_INIT_LOW, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } - machine->gpio_requested |= GPIO_INT_MIC_EN; - - /* Disable int mic; enable signal is active-high */ - gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { - ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); + /* Enable ext mic; enable signal is active-low */ + ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en, + GPIOF_OUT_INIT_LOW, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } - machine->gpio_requested |= GPIO_EXT_MIC_EN; - - /* Enable ext mic; enable signal is active-low */ - gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); @@ -469,21 +457,11 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = &machine->pdata; if (machine->gpio_requested & GPIO_HP_DET) snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1, &tegra_wm8903_hp_jack_gpio); - if (machine->gpio_requested & GPIO_EXT_MIC_EN) - gpio_free(pdata->gpio_ext_mic_en); - if (machine->gpio_requested & GPIO_INT_MIC_EN) - gpio_free(pdata->gpio_int_mic_en); - if (machine->gpio_requested & GPIO_HP_MUTE) - gpio_free(pdata->gpio_hp_mute); - if (machine->gpio_requested & GPIO_SPKR_EN) - gpio_free(pdata->gpio_spkr_en); - machine->gpio_requested = 0; snd_soc_unregister_card(card); -- GitLab From e44fbbd45896e684d44391aaf881dd3e36bd1a16 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:08:56 -0600 Subject: [PATCH 0075/6849] ASoC: tegra+wm8903: unconditionally free jack GPIOs in remove The headphone jack GPIOs are added/initialized in the DAI link's init() method, and hence in theory may not always have been added before remove() is called in some unusual cases. In order to prevent calling snd_soc_jack_free_gpios() if snd_soc_jack_add_gpios() had not been, the code kept track of the initialization state to avoid the free call when necessary. However, it appears that snd_soc_jack_free_gpios() is robust in the face of being called without snd_soc_jack_add_gpios() first succeeding, so there is little point manually tracking this information. Hence, remove the tracking code. Almost all other machine drivers already operate this way. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 5ef2063e0ab1..9059525f3b08 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -50,12 +50,9 @@ #define DRV_NAME "tegra-snd-wm8903" -#define GPIO_HP_DET BIT(4) - struct tegra_wm8903 { struct tegra_wm8903_platform_data pdata; struct tegra_asoc_utils_data util_data; - int gpio_requested; }; static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, @@ -252,7 +249,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 1, &tegra_wm8903_hp_jack_gpio); - machine->gpio_requested |= GPIO_HP_DET; } snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, @@ -458,10 +454,8 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - if (machine->gpio_requested & GPIO_HP_DET) - snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, - 1, - &tegra_wm8903_hp_jack_gpio); + snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1, + &tegra_wm8903_hp_jack_gpio); snd_soc_unregister_card(card); -- GitLab From aef9a37c01a63a132d43d65d231dfe515d0f918a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:09:51 -0600 Subject: [PATCH 0076/6849] ASoC: tegra+alc5632: move all GPIO setup into probe Now that deferred probe exists, we can parse device tree and request GPIOs from probe(), rather than deferring this to the DAI link's init(). Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_alc5632.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 32de7006daf0..facf6f00c6b0 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -1,5 +1,5 @@ /* - * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver +* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver * * Copyright (C) 2011 The AC100 Kernel Team * Copyright (C) 2012 - NVIDIA, Inc. @@ -110,7 +110,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - struct device_node *np = codec->card->dev->of_node; struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, @@ -119,8 +118,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(tegra_alc5632_hs_jack_pins), tegra_alc5632_hs_jack_pins); - machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); - if (gpio_is_valid(machine->gpio_hp_det)) { tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, @@ -159,6 +156,7 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = { static __devinit int tegra_alc5632_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_tegra_alc5632; struct tegra_alc5632 *alc5632; int ret; @@ -181,6 +179,10 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) goto err; } + alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); + if (alc5632->gpio_hp_det == -ENODEV) + return -EPROBE_DEFER; + ret = snd_soc_of_parse_card_name(card, "nvidia,model"); if (ret) goto err; -- GitLab From 9f6328d910ef8df8176ed433aa2de037eba1f656 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:09:52 -0600 Subject: [PATCH 0077/6849] ASoC: tegra+alc5632: unconditionally free jack GPIOs in remove The headphone jack GPIOs are added/initialized in the DAI link's init() method, and hence in theory may not always have been added before remove() is called in some unusual cases. In order to prevent calling snd_soc_jack_free_gpios() if snd_soc_jack_add_gpios() had not been, the code kept track of the initialization state to avoid the free call when necessary. However, it appears that snd_soc_jack_free_gpios() is robust in the face of being called without snd_soc_jack_add_gpios() first succeeding, so there is little point manually tracking this information. Hence, remove the tracking code. All other machine drivers already operate this way. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_alc5632.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index facf6f00c6b0..15669570ae31 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -33,11 +33,8 @@ #define DRV_NAME "tegra-alc5632" -#define GPIO_HP_DET BIT(0) - struct tegra_alc5632 { struct tegra_asoc_utils_data util_data; - int gpio_requested; int gpio_hp_det; }; @@ -123,7 +120,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, 1, &tegra_alc5632_hp_jack_gpio); - machine->gpio_requested |= GPIO_HP_DET; } snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); @@ -236,11 +232,8 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); - if (machine->gpio_requested & GPIO_HP_DET) - snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, - 1, - &tegra_alc5632_hp_jack_gpio); - machine->gpio_requested = 0; + snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1, + &tegra_alc5632_hp_jack_gpio); snd_soc_unregister_card(card); -- GitLab From 14df415a38234aa483219335bc6c1ee899b85e10 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:08:53 -0600 Subject: [PATCH 0078/6849] ASoC: tegra+wm8903: simplify gpio tests in widget callbacks By the time any widget callbacks could be called, if the GPIO ID they will manipulate is valid, it must have already been requested, or the card would have failed to probe or initialize. So, testing for GPIO validity is equivalent to testing whether the GPIO was successfully requested at this point in the code. Making this change will allow later patches to remove the gpio_requested variable. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 9059525f3b08..1fd6a41b9162 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -153,7 +153,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = &machine->pdata; - if (!(machine->gpio_requested & GPIO_SPKR_EN)) + if (!gpio_is_valid(pdata->gpio_spkr_en)) return 0; gpio_set_value_cansleep(pdata->gpio_spkr_en, @@ -170,7 +170,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = &machine->pdata; - if (!(machine->gpio_requested & GPIO_HP_MUTE)) + if (!gpio_is_valid(pdata->gpio_hp_mute)) return 0; gpio_set_value_cansleep(pdata->gpio_hp_mute, -- GitLab From b350ecbe4c2e4639ed3a716ec67accb744e4417d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 22 May 2012 16:11:19 -0600 Subject: [PATCH 0079/6849] ASoC: tegra+wm8903: remove non-DT support for Seaboard In kernel 3.6, Seaboard will only be supported when booting using device tree; the board files are being removed. Hence, remove the non-DT support for Seaboard and derivatives Kaen and Aebl from the audio driver. Harmony is the only remaining board supported by this driver when not using DT. This support is currently scheduled for removal in 3.7. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 48 ++-------------------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 1fd6a41b9162..b75e0e8db1d0 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -28,8 +28,6 @@ * */ -#include - #include #include #include @@ -196,37 +194,6 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = { {"IN1L", NULL, "Mic Jack"}, }; -static const struct snd_soc_dapm_route seaboard_audio_map[] = { - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "HPOUTL"}, - {"Int Spk", NULL, "ROP"}, - {"Int Spk", NULL, "RON"}, - {"Int Spk", NULL, "LOP"}, - {"Int Spk", NULL, "LON"}, - {"Mic Jack", NULL, "MICBIAS"}, - {"IN1R", NULL, "Mic Jack"}, -}; - -static const struct snd_soc_dapm_route kaen_audio_map[] = { - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "HPOUTL"}, - {"Int Spk", NULL, "ROP"}, - {"Int Spk", NULL, "RON"}, - {"Int Spk", NULL, "LOP"}, - {"Int Spk", NULL, "LON"}, - {"Mic Jack", NULL, "MICBIAS"}, - {"IN2R", NULL, "Mic Jack"}, -}; - -static const struct snd_soc_dapm_route aebl_audio_map[] = { - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "HPOUTL"}, - {"Int Spk", NULL, "LINEOUTR"}, - {"Int Spk", NULL, "LINEOUTL"}, - {"Mic Jack", NULL, "MICBIAS"}, - {"IN1R", NULL, "Mic Jack"}, -}; - static const struct snd_kcontrol_new tegra_wm8903_controls[] = { SOC_DAPM_PIN_SWITCH("Int Spk"), }; @@ -377,19 +344,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) tegra_wm8903_dai.platform_of_node = tegra_wm8903_dai.cpu_dai_of_node; } else { - if (machine_is_harmony()) { - card->dapm_routes = harmony_audio_map; - card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); - } else if (machine_is_seaboard()) { - card->dapm_routes = seaboard_audio_map; - card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); - } else if (machine_is_kaen()) { - card->dapm_routes = kaen_audio_map; - card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); - } else { - card->dapm_routes = aebl_audio_map; - card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); - } + card->dapm_routes = harmony_audio_map; + card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); } if (gpio_is_valid(pdata->gpio_spkr_en)) { -- GitLab From 656baaebf92ae9b16644c7e10a273d8dfe1ba1f6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 23 May 2012 12:39:07 +0100 Subject: [PATCH 0080/6849] ASoC: codecs: Refresh copyrights for Wolfson drivers Signed-off-by: Mark Brown --- sound/soc/codecs/wm2000.c | 2 +- sound/soc/codecs/wm5100-tables.c | 2 +- sound/soc/codecs/wm5100.c | 2 +- sound/soc/codecs/wm8350.c | 2 +- sound/soc/codecs/wm8400.c | 2 +- sound/soc/codecs/wm8580.c | 2 +- sound/soc/codecs/wm8731.c | 1 + sound/soc/codecs/wm8741.c | 2 +- sound/soc/codecs/wm8753.c | 2 +- sound/soc/codecs/wm8776.c | 2 +- sound/soc/codecs/wm8804.c | 2 +- sound/soc/codecs/wm8903.c | 2 +- sound/soc/codecs/wm8904.c | 2 +- sound/soc/codecs/wm8960.c | 2 ++ sound/soc/codecs/wm8961.c | 2 ++ sound/soc/codecs/wm8962.c | 2 +- sound/soc/codecs/wm8993.c | 2 +- sound/soc/codecs/wm8994.c | 2 +- sound/soc/codecs/wm8996.c | 2 +- sound/soc/codecs/wm9081.c | 2 +- sound/soc/codecs/wm9090.c | 2 +- sound/soc/codecs/wm9712.c | 2 +- sound/soc/codecs/wm9713.c | 2 +- sound/soc/codecs/wm_hubs.c | 2 +- 24 files changed, 26 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index a75c3766aede..52f0a19217c4 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -1,7 +1,7 @@ /* * wm2000.c -- WM2000 ALSA Soc Audio driver * - * Copyright 2008-2010 Wolfson Microelectronics PLC. + * Copyright 2008-2011 Wolfson Microelectronics PLC. * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c index e167207a19cc..e239f4bf2460 100644 --- a/sound/soc/codecs/wm5100-tables.c +++ b/sound/soc/codecs/wm5100-tables.c @@ -1,7 +1,7 @@ /* * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data * - * Copyright 2011 Wolfson Microelectronics plc + * Copyright 2011-2 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index cb6d5372103a..3823af362912 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -1,7 +1,7 @@ /* * wm5100.c -- WM5100 ALSA SoC Audio driver * - * Copyright 2011 Wolfson Microelectronics plc + * Copyright 2011-2 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 555ee146ae0d..e782a5aa2a31 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1,7 +1,7 @@ /* * wm8350.c -- WM8350 ALSA SoC audio driver * - * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. + * Copyright (C) 2007-12 Wolfson Microelectronics PLC. * * Author: Liam Girdwood * diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 5dc31ebcd0e7..5d277a915f81 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1,7 +1,7 @@ /* * wm8400.c -- WM8400 ALSA Soc Audio driver * - * Copyright 2008, 2009 Wolfson Microelectronics PLC. + * Copyright 2008-11 Wolfson Microelectronics PLC. * Author: Mark Brown * * This program is free software; you can redistribute it and/or modify it diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 211285164d70..7c68226376e4 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -1,7 +1,7 @@ /* * wm8580.c -- WM8580 ALSA Soc Audio driver * - * Copyright 2008, 2009 Wolfson Microelectronics PLC. + * Copyright 2008-11 Wolfson Microelectronics PLC. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 9d1b9b0271f1..bb1d26919b10 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -2,6 +2,7 @@ * wm8731.c -- WM8731 ALSA SoC Audio driver * * Copyright 2005 Openedhand Ltd. + * Copyright 2006-12 Wolfson Microelectronics, plc * * Author: Richard Purdie * diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 6e849cb04243..35f3d23200e0 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -1,7 +1,7 @@ /* * wm8741.c -- WM8741 ALSA SoC Audio driver * - * Copyright 2010 Wolfson Microelectronics plc + * Copyright 2010-1 Wolfson Microelectronics plc * * Author: Ian Lartey * diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index a26482cd7654..13bff87ddcf5 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1,7 +1,7 @@ /* * wm8753.c -- WM8753 ALSA Soc Audio driver * - * Copyright 2003 Wolfson Microelectronics PLC. + * Copyright 2003-11 Wolfson Microelectronics PLC. * Author: Liam Girdwood * * This program is free software; you can redistribute it and/or modify it diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index a19db5a0a17a..879c356a9045 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -1,7 +1,7 @@ /* * wm8776.c -- WM8776 ALSA SoC Audio driver * - * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2009-12 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 6bd1b767b138..c088020172ab 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -1,7 +1,7 @@ /* * wm8804.c -- WM8804 S/PDIF transceiver driver * - * Copyright 2010 Wolfson Microelectronics plc + * Copyright 2010-11 Wolfson Microelectronics plc * * Author: Dimitris Papastamos * diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index f6a3fc5f09c0..304b5cff3482 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1,7 +1,7 @@ /* * wm8903.c -- WM8903 ALSA SoC Audio driver * - * Copyright 2008 Wolfson Microelectronics + * Copyright 2008-11 Wolfson Microelectronics * Copyright 2011-2012 NVIDIA, Inc. * * Author: Mark Brown diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 65d525d74c54..db94d10b5c1a 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1,7 +1,7 @@ /* * wm8904.c -- WM8904 ALSA SoC Audio driver * - * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2009-12 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8bc659d8dd2e..96518ac8e24c 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -1,6 +1,8 @@ /* * wm8960.c -- WM8960 ALSA SoC Audio driver * + * Copyright 2007-11 Wolfson Microelectronics, plc + * * Author: Liam Girdwood * * This program is free software; you can redistribute it and/or modify diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 05ea7c274093..01edbcc754d2 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -1,6 +1,8 @@ /* * wm8961.c -- WM8961 ALSA SoC Audio driver * + * Copyright 2009-10 Wolfson Microelectronics, plc + * * Author: Mark Brown * * This program is free software; you can redistribute it and/or modify diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 0cfce9999c89..27da4d722edc 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1,7 +1,7 @@ /* * wm8962.c -- WM8962 ALSA SoC Audio driver * - * Copyright 2010 Wolfson Microelectronics plc + * Copyright 2010-2 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 36acfccab999..9fd80d688979 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1,7 +1,7 @@ /* * wm8993.c -- WM8993 ALSA SoC audio driver * - * Copyright 2009, 2010 Wolfson Microelectronics plc + * Copyright 2009-12 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 993639d694ce..5d4d7df8d339 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1,7 +1,7 @@ /* * wm8994.c -- WM8994 ALSA SoC Audio driver * - * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2009-12 Wolfson Microelectronics plc * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 8af422e38fd0..efc4e9d0903b 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -1,7 +1,7 @@ /* * wm8996.c - WM8996 audio codec interface * - * Copyright 2011 Wolfson Microelectronics PLC. + * Copyright 2011-2 Wolfson Microelectronics PLC. * Author: Mark Brown * * This program is free software; you can redistribute it and/or modify it diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 9328270df16c..2de74e1ea225 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -3,7 +3,7 @@ * * Author: Mark Brown * - * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2009-12 Wolfson Microelectronics plc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 4b263b6edf13..2c2346fdd637 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -1,7 +1,7 @@ /* * ALSA SoC WM9090 driver * - * Copyright 2009, 2010 Wolfson Microelectronics + * Copyright 2009-12 Wolfson Microelectronics * * Author: Mark Brown * diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index a1541414d904..099e6ec32125 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -1,7 +1,7 @@ /* * wm9712.c -- ALSA Soc WM9712 codec support * - * Copyright 2006 Wolfson Microelectronics PLC. + * Copyright 2006-12 Wolfson Microelectronics PLC. * Author: Liam Girdwood * * This program is free software; you can redistribute it and/or modify it diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 2d22cc70d536..3eb19fb71d17 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1,7 +1,7 @@ /* * wm9713.c -- ALSA Soc WM9713 codec support * - * Copyright 2006 Wolfson Microelectronics PLC. + * Copyright 2006-10 Wolfson Microelectronics PLC. * Author: Liam Girdwood * * This program is free software; you can redistribute it and/or modify it diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index dfe957a47f29..61baa48823cb 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -1,7 +1,7 @@ /* * wm_hubs.c -- WM8993/4 common code * - * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2009-12 Wolfson Microelectronics plc * * Author: Mark Brown * -- GitLab From 1aad779fccdbb4d79af7b9de93dfd2bfe807e052 Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Thu, 24 May 2012 15:26:03 +0200 Subject: [PATCH 0081/6849] ALSA: pcm: Add debug-print helper function Adds a function getting the stream-name as a string for a specific stream. Signed-off-by: Ola Lilja Reviewed-by: Takashi Iwai Signed-off-by: Mark Brown --- include/sound/pcm.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 0d1112815be3..a55d5db7eb5a 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1073,4 +1073,15 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) const char *snd_pcm_format_name(snd_pcm_format_t format); +/** + * Get a string naming the direction of a stream + */ +static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) +{ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return "Playback"; + else + return "Capture"; +} + #endif /* __SOUND_PCM_H */ -- GitLab From d7e7eb91551ad99244b989d71d092cb0375648fa Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Thu, 24 May 2012 15:26:25 +0200 Subject: [PATCH 0082/6849] ASoC: core: Add widget SND_SOC_DAPM_CLOCK_SUPPLY Adds a supply-widget variant for connection to the clock-framework. This widget-type corresponds to the variant for regulators. Signed-off-by: Ola Lilja Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 10 ++++++++++ sound/soc/soc-dapm.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index e3833d9f1914..05559e571d44 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -229,6 +229,10 @@ struct device; { .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ .shift = wshift, .invert = winvert, \ .event = wevent, .event_flags = wflags} +#define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \ +{ .id = snd_soc_dapm_clock_supply, .name = wname, \ + .reg = SND_SOC_NOPM, .event = dapm_clock_event, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } /* generic widgets */ #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ @@ -245,6 +249,7 @@ struct device; .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } + /* dapm kcontrol types */ #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ @@ -327,6 +332,8 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); int dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); +int dapm_clock_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); /* dapm controls */ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, @@ -432,6 +439,7 @@ enum snd_soc_dapm_type { snd_soc_dapm_post, /* machine specific post widget - exec last */ snd_soc_dapm_supply, /* power/clock supply */ snd_soc_dapm_regulator_supply, /* external regulator */ + snd_soc_dapm_clock_supply, /* external clock */ snd_soc_dapm_aif_in, /* audio interface input */ snd_soc_dapm_aif_out, /* audio interface output */ snd_soc_dapm_siggen, /* signal generator */ @@ -537,6 +545,8 @@ struct snd_soc_dapm_widget { struct list_head dirty; int inputs; int outputs; + + struct clk *clk; }; struct snd_soc_dapm_update { diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 90ee77d2409d..3bb7a6f058d0 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ static int dapm_up_seq[] = { [snd_soc_dapm_pre] = 0, [snd_soc_dapm_supply] = 1, [snd_soc_dapm_regulator_supply] = 1, + [snd_soc_dapm_clock_supply] = 1, [snd_soc_dapm_micbias] = 2, [snd_soc_dapm_dai_link] = 2, [snd_soc_dapm_dai] = 3, @@ -92,6 +94,7 @@ static int dapm_down_seq[] = { [snd_soc_dapm_aif_out] = 10, [snd_soc_dapm_dai] = 10, [snd_soc_dapm_dai_link] = 11, + [snd_soc_dapm_clock_supply] = 12, [snd_soc_dapm_regulator_supply] = 12, [snd_soc_dapm_supply] = 12, [snd_soc_dapm_post] = 13, @@ -391,6 +394,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, case snd_soc_dapm_vmid: case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: case snd_soc_dapm_dai: @@ -764,6 +768,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, switch (widget->id) { case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: return 0; default: break; @@ -850,6 +855,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, switch (widget->id) { case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: return 0; default: break; @@ -996,6 +1002,24 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(dapm_regulator_event); +/* + * Handler for clock supply widget. + */ +int dapm_clock_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + if (!w->clk) + return -EIO; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + return clk_enable(w->clk); + } else { + clk_disable(w->clk); + return 0; + } +} +EXPORT_SYMBOL_GPL(dapm_clock_event); + static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) { if (w->power_checked) @@ -1487,6 +1511,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, switch (w->id) { case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: /* Supplies can't affect their outputs, only their inputs */ break; default: @@ -1587,6 +1612,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) break; case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: case snd_soc_dapm_micbias: if (d->target_bias_level < SND_SOC_BIAS_STANDBY) d->target_bias_level = SND_SOC_BIAS_STANDBY; @@ -1941,6 +1967,7 @@ static ssize_t dapm_widget_show(struct device *dev, case snd_soc_dapm_mixer_named_ctl: case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: if (w->name) count += sprintf(buf + count, "%s: %s\n", w->name, w->power ? "On":"Off"); @@ -2187,6 +2214,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_post: case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: case snd_soc_dapm_dai: @@ -2873,6 +2901,15 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, return NULL; } break; + case snd_soc_dapm_clock_supply: + w->clk = clk_get(dapm->dev, w->name); + if (IS_ERR(w->clk)) { + ret = PTR_ERR(w->clk); + dev_err(dapm->dev, "Failed to request %s: %d\n", + w->name, ret); + return NULL; + } + break; default: break; } @@ -2924,6 +2961,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, break; case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_clock_supply: w->power_check = dapm_supply_check_power; break; case snd_soc_dapm_dai: -- GitLab From 01a0c1139c2bd075d005253093e7060022c5d0cb Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Thu, 24 May 2012 15:26:32 +0200 Subject: [PATCH 0083/6849] ASoC: Ux500: Add platform-driver Add platform-driver handling all DMA-activities. Signed-off-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/Kconfig | 7 + sound/soc/ux500/Makefile | 3 + sound/soc/ux500/ux500_pcm.c | 318 ++++++++++++++++++++++++++++++++++++ sound/soc/ux500/ux500_pcm.h | 35 ++++ 4 files changed, 363 insertions(+) create mode 100644 sound/soc/ux500/ux500_pcm.c create mode 100644 sound/soc/ux500/ux500_pcm.h diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig index 44cf43404cd9..1d385150064f 100644 --- a/sound/soc/ux500/Kconfig +++ b/sound/soc/ux500/Kconfig @@ -12,3 +12,10 @@ menuconfig SND_SOC_UX500 config SND_SOC_UX500_PLAT_MSP_I2S tristate depends on SND_SOC_UX500 + +config SND_SOC_UX500_PLAT_DMA + tristate "Platform - DB8500 (DMA)" + depends on SND_SOC_UX500 + select SND_SOC_DMAENGINE_PCM + help + Say Y if you want to enable the Ux500 platform-driver. diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile index 19974c5a2ea1..4634bf015f62 100644 --- a/sound/soc/ux500/Makefile +++ b/sound/soc/ux500/Makefile @@ -2,3 +2,6 @@ snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o + +snd-soc-ux500-plat-dma-objs := ux500_pcm.o +obj-$(CONFIG_SND_SOC_UX500_PLAT_DMA) += snd-soc-ux500-plat-dma.o diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c new file mode 100644 index 000000000000..66b080e5de96 --- /dev/null +++ b/sound/soc/ux500/ux500_pcm.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja , + * Roger Nilsson + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "ux500_msp_i2s.h" +#include "ux500_pcm.h" + +static struct snd_pcm_hardware ux500_pcm_hw_playback = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_PAUSE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_S16_BE | + SNDRV_PCM_FMTBIT_U16_BE, + .rates = SNDRV_PCM_RATE_KNOT, + .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK, + .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK, + .channels_min = UX500_PLATFORM_MIN_CHANNELS, + .channels_max = UX500_PLATFORM_MAX_CHANNELS, + .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, + .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, + .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, + .periods_min = UX500_PLATFORM_PERIODS_MIN, + .periods_max = UX500_PLATFORM_PERIODS_MAX, +}; + +static struct snd_pcm_hardware ux500_pcm_hw_capture = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_PAUSE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_S16_BE | + SNDRV_PCM_FMTBIT_U16_BE, + .rates = SNDRV_PCM_RATE_KNOT, + .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE, + .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE, + .channels_min = UX500_PLATFORM_MIN_CHANNELS, + .channels_max = UX500_PLATFORM_MAX_CHANNELS, + .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, + .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, + .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, + .periods_min = UX500_PLATFORM_PERIODS_MIN, + .periods_max = UX500_PLATFORM_PERIODS_MAX, +}; + +static void ux500_pcm_dma_hw_free(struct device *dev, + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *buf = runtime->dma_buffer_p; + + if (runtime->dma_area == NULL) + return; + + if (buf != &substream->dma_buffer) { + dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, + buf->addr); + kfree(runtime->dma_buffer_p); + } + + snd_pcm_set_runtime_buffer(substream, NULL); +} + +static int ux500_pcm_open(struct snd_pcm_substream *substream) +{ + int stream_id = substream->pstr->stream; + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *dai = rtd->cpu_dai; + struct device *dev = dai->dev; + int ret; + struct ux500_msp_dma_params *dma_params; + u16 per_data_width, mem_data_width; + struct stedma40_chan_cfg *dma_cfg; + + dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, + snd_pcm_stream_str(substream)); + + dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_set_runtime_hwparams(substream, + &ux500_pcm_hw_playback); + else + snd_soc_set_runtime_hwparams(substream, + &ux500_pcm_hw_capture); + + /* ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", + __func__, ret); + return ret; + } + + dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, + snd_pcm_stream_str(substream)); + runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? + ux500_pcm_hw_playback : ux500_pcm_hw_capture; + + mem_data_width = STEDMA40_HALFWORD_WIDTH; + + dma_params = snd_soc_dai_get_dma_data(dai, substream); + switch (dma_params->data_size) { + case 32: + per_data_width = STEDMA40_WORD_WIDTH; + break; + case 16: + per_data_width = STEDMA40_HALFWORD_WIDTH; + break; + case 8: + per_data_width = STEDMA40_BYTE_WIDTH; + break; + default: + per_data_width = STEDMA40_WORD_WIDTH; + dev_warn(rtd->platform->dev, + "%s: Unknown data-size (%d)! Assuming 32 bits.\n", + __func__, dma_params->data_size); + } + + dma_cfg = dma_params->dma_cfg; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + dma_cfg->src_info.data_width = mem_data_width; + dma_cfg->dst_info.data_width = per_data_width; + } else { + dma_cfg->src_info.data_width = per_data_width; + dma_cfg->dst_info.data_width = mem_data_width; + } + + + ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg); + if (ret) { + dev_dbg(dai->dev, + "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n", + __func__, ret); + return ret; + } + + snd_dmaengine_pcm_set_data(substream, dma_cfg); + + return 0; +} + +static int ux500_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *dai = rtd->cpu_dai; + + dev_dbg(dai->dev, "%s: Enter\n", __func__); + + snd_dmaengine_pcm_close(substream); + + return 0; +} + +static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *buf = runtime->dma_buffer_p; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0; + int size; + + dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); + + size = params_buffer_bytes(hw_params); + + if (buf) { + if (buf->bytes >= size) + goto out; + ux500_pcm_dma_hw_free(NULL, substream); + } + + if (substream->dma_buffer.area != NULL && + substream->dma_buffer.bytes >= size) { + buf = &substream->dma_buffer; + } else { + buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL); + if (!buf) + goto nomem; + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = NULL; + buf->area = dma_alloc_coherent(NULL, size, &buf->addr, + GFP_KERNEL); + buf->bytes = size; + buf->private_data = NULL; + + if (!buf->area) + goto free; + } + snd_pcm_set_runtime_buffer(substream, buf); + ret = 1; + out: + runtime->dma_bytes = size; + return ret; + + free: + kfree(buf); + nomem: + return -ENOMEM; +} + +static int ux500_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); + + ux500_pcm_dma_hw_free(NULL, substream); + + return 0; +} + +static int ux500_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__); + + return dma_mmap_coherent(NULL, vma, runtime->dma_area, + runtime->dma_addr, runtime->dma_bytes); +} + +static struct snd_pcm_ops ux500_pcm_ops = { + .open = ux500_pcm_open, + .close = ux500_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = ux500_pcm_hw_params, + .hw_free = ux500_pcm_hw_free, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, + .mmap = ux500_pcm_mmap +}; + +int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + + dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__, + pcm->id); + + pcm->info_flags = 0; + + return 0; +} + +static struct snd_soc_platform_driver ux500_pcm_soc_drv = { + .ops = &ux500_pcm_ops, + .pcm_new = ux500_pcm_new, +}; + +static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) +{ + int ret; + + ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv); + if (ret < 0) { + dev_err(&pdev->dev, + "%s: ERROR: Failed to register platform '%s' (%d)!\n", + __func__, pdev->name, ret); + return ret; + } + + return 0; +} + +static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + + return 0; +} + +static struct platform_driver ux500_pcm_driver = { + .driver = { + .name = "ux500-pcm", + .owner = THIS_MODULE, + }, + + .probe = ux500_pcm_drv_probe, + .remove = __devexit_p(ux500_pcm_drv_remove), +}; +module_platform_driver(ux500_pcm_driver); + +MODULE_LICENSE("GPLv2"); diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h new file mode 100644 index 000000000000..77ed44d371e9 --- /dev/null +++ b/sound/soc/ux500/ux500_pcm.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja , + * Roger Nilsson + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#ifndef UX500_PCM_H +#define UX500_PCM_H + +#include + +#include + +#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000 +#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000 +#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000 +#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000 + +#define UX500_PLATFORM_MIN_CHANNELS 1 +#define UX500_PLATFORM_MAX_CHANNELS 8 + +#define UX500_PLATFORM_PERIODS_BYTES_MIN 128 +#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) +#define UX500_PLATFORM_PERIODS_MIN 2 +#define UX500_PLATFORM_PERIODS_MAX 48 +#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) + +#endif -- GitLab From 5514efdfe0384576ef38c66b1672b6826696fbf3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 28 May 2012 23:29:36 -0700 Subject: [PATCH 0084/6849] ASoC: fsi: use dmaengine helper functions This patch used dmaengine helper functions instead of using hand setting. And reduced local variables Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 2ef98536f1da..fcaa6b8abb0c 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1089,13 +1089,10 @@ static void fsi_dma_do_tasklet(unsigned long data) { struct fsi_stream *io = (struct fsi_stream *)data; struct fsi_priv *fsi = fsi_stream_to_priv(io); - struct dma_chan *chan; struct snd_soc_dai *dai; struct dma_async_tx_descriptor *desc; - struct scatterlist sg; struct snd_pcm_runtime *runtime; enum dma_data_direction dir; - dma_cookie_t cookie; int is_play = fsi_stream_is_play(fsi, io); int len; dma_addr_t buf; @@ -1104,7 +1101,6 @@ static void fsi_dma_do_tasklet(unsigned long data) return; dai = fsi_get_dai(io->substream); - chan = io->chan; runtime = io->substream->runtime; dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; len = samples_to_bytes(runtime, io->period_samples); @@ -1112,14 +1108,8 @@ static void fsi_dma_do_tasklet(unsigned long data) dma_sync_single_for_device(dai->dev, buf, len, dir); - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), - len , offset_in_page(buf)); - sg_dma_address(&sg) = buf; - sg_dma_len(&sg) = len; - - desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); return; @@ -1128,13 +1118,12 @@ static void fsi_dma_do_tasklet(unsigned long data) desc->callback = fsi_dma_complete; desc->callback_param = io; - cookie = desc->tx_submit(desc); - if (cookie < 0) { + if (dmaengine_submit(desc) < 0) { dev_err(dai->dev, "tx_submit() fail\n"); return; } - dma_async_issue_pending(chan); + dma_async_issue_pending(io->chan); /* * FIXME -- GitLab From b1226dc59d55ecde7fc9a338d8cb2a313821fac0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 24 May 2012 23:56:19 -0700 Subject: [PATCH 0085/6849] ASoC: fsi: use PIO handler if DMA handler was invalid PIO handler is not good performance, but works on all platform. So, switch to PIO handler if DMA handler was invalid case. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index fcaa6b8abb0c..53486ff9c2af 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -247,7 +247,7 @@ struct fsi_priv { struct fsi_stream_handler { int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); - int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io); + int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev); int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, @@ -571,16 +571,16 @@ static int fsi_stream_transfer(struct fsi_stream *io) #define fsi_stream_stop(fsi, io)\ fsi_stream_handler_call(io, start_stop, fsi, io, 0) -static int fsi_stream_probe(struct fsi_priv *fsi) +static int fsi_stream_probe(struct fsi_priv *fsi, struct device *dev) { struct fsi_stream *io; int ret1, ret2; io = &fsi->playback; - ret1 = fsi_stream_handler_call(io, probe, fsi, io); + ret1 = fsi_stream_handler_call(io, probe, fsi, io, dev); io = &fsi->capture; - ret2 = fsi_stream_handler_call(io, probe, fsi, io); + ret2 = fsi_stream_handler_call(io, probe, fsi, io, dev); if (ret1 < 0) return ret1; @@ -1173,7 +1173,7 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); } -static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) +static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) { dma_cap_mask_t mask; @@ -1181,8 +1181,19 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) dma_cap_set(DMA_SLAVE, mask); io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); - if (!io->chan) - return -EIO; + if (!io->chan) { + + /* switch to PIO handler */ + if (fsi_stream_is_play(fsi, io)) + fsi->playback.handler = &fsi_pio_push_handler; + else + fsi->capture.handler = &fsi_pio_pop_handler; + + dev_info(dev, "switch handler (dma => pio)\n"); + + /* probe again */ + return fsi_stream_probe(fsi, dev); + } tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); @@ -1672,7 +1683,7 @@ static int fsi_probe(struct platform_device *pdev) master->fsia.master = master; master->fsia.info = &info->port_a; fsi_handler_init(&master->fsia); - ret = fsi_stream_probe(&master->fsia); + ret = fsi_stream_probe(&master->fsia, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIA stream probe failed\n"); goto exit_iounmap; @@ -1683,7 +1694,7 @@ static int fsi_probe(struct platform_device *pdev) master->fsib.master = master; master->fsib.info = &info->port_b; fsi_handler_init(&master->fsib); - ret = fsi_stream_probe(&master->fsib); + ret = fsi_stream_probe(&master->fsib, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIB stream probe failed\n"); goto exit_fsia; -- GitLab From 14a95fe865c0b2ede6f386f52413f6396c010833 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 28 May 2012 22:09:02 +0300 Subject: [PATCH 0086/6849] ASoC: tlv320aic3x: Change Class-D amplifier gain control name ALSA mixers cannot classify this "Class-D Amplifier Gain" speaker output gain control as a playback control. Fix this by changing the name as "Class-D Playback Volume". Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64d2a4fa34b2..58ef59dfbae9 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -368,7 +368,7 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0); static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl = - SOC_DOUBLE_TLV("Class-D Amplifier Gain", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv); + SOC_DOUBLE_TLV("Class-D Playback Volume", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv); /* Left DAC Mux */ static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = -- GitLab From 0561c1bf354c4a8230a1e0ada43362f54e60b2f0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 30 May 2012 13:20:17 +0100 Subject: [PATCH 0087/6849] ASoC: ac97: Remove empty remove() function Signed-off-by: Mark Brown --- sound/soc/codecs/ac97.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 2023c749f232..ea06b834a7de 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -91,11 +91,6 @@ static int ac97_soc_probe(struct snd_soc_codec *codec) return 0; } -static int ac97_soc_remove(struct snd_soc_codec *codec) -{ - return 0; -} - #ifdef CONFIG_PM static int ac97_soc_suspend(struct snd_soc_codec *codec) { @@ -119,7 +114,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = { .write = ac97_write, .read = ac97_read, .probe = ac97_soc_probe, - .remove = ac97_soc_remove, .suspend = ac97_soc_suspend, .resume = ac97_soc_resume, }; -- GitLab From 51cc7ed3e378a60a3413a7e424f536e4dec3f39d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 31 May 2012 14:48:07 +0100 Subject: [PATCH 0088/6849] ASoC: wm2000: Add register readability information Signed-off-by: Mark Brown --- sound/soc/codecs/wm2000.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 52f0a19217c4..78a148f0a8ef 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -691,9 +691,39 @@ static int wm2000_resume(struct snd_soc_codec *codec) #define wm2000_resume NULL #endif +static bool wm2000_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM2000_REG_SYS_START: + case WM2000_REG_SPEECH_CLARITY: + case WM2000_REG_SYS_WATCHDOG: + case WM2000_REG_ANA_VMID_PD_TIME: + case WM2000_REG_ANA_VMID_PU_TIME: + case WM2000_REG_CAT_FLTR_INDX: + case WM2000_REG_CAT_GAIN_0: + case WM2000_REG_SYS_STATUS: + case WM2000_REG_SYS_MODE_CNTRL: + case WM2000_REG_SYS_START0: + case WM2000_REG_SYS_START1: + case WM2000_REG_ID1: + case WM2000_REG_ID2: + case WM2000_REG_REVISON: + case WM2000_REG_SYS_CTL1: + case WM2000_REG_SYS_CTL2: + case WM2000_REG_ANC_STAT: + case WM2000_REG_IF_CTL: + return true; + default: + return false; + } +} + static const struct regmap_config wm2000_regmap = { .reg_bits = 8, .val_bits = 8, + + .max_register = WM2000_REG_IF_CTL, + .readable_reg = wm2000_readable_reg, }; static int wm2000_probe(struct snd_soc_codec *codec) -- GitLab From 210cb67cb5b9f9a23b7ce91de50bab357440ba9d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 8 May 2012 17:46:36 +0100 Subject: [PATCH 0089/6849] ASoC: io: Use dev_get_regmap() if driver doesn't provide a regmap Less error prone and one less line of code in drivers. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-io.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 4d8dc6a27d4d..44d0174b4d97 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -142,6 +142,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, case SND_SOC_REGMAP: /* Device has made its own regmap arrangements */ codec->using_regmap = true; + if (!codec->control_data) + codec->control_data = dev_get_regmap(codec->dev, NULL); ret = regmap_get_val_bytes(codec->control_data); /* Errors are legitimate for non-integer byte multiples */ -- GitLab From bc92657a11c0982783979bbb84ceaf58ba222124 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 25 May 2012 18:22:11 -0600 Subject: [PATCH 0090/6849] ASoC: make snd_soc_dai_link more symmetrical Prior to this patch, the CPU side of a DAI link was specified using a single name. Often, this was the result of calling dev_name() on the device providing the DAI, but in the case of a CPU DAI driver that provided multiple DAIs, it needed to mix together both the device name and some device-relative name, in order to form a single globally unique name. However, the CODEC side of the DAI link was specified using separate fields for device (name or OF node) and device-relative DAI name. This patch allows the CPU side of a DAI link to be specified in the same way as the CODEC side, separating concepts of device and device-relative DAI name. I believe this will be important in multi-codec and/or dynamic PCM scenarios, where a single CPU driver provides multiple DAIs, while also booting using device tree, with accompanying desire not to hard-code the CPU side device's name into the original .cpu_dai_name field. Ideally, both the CPU DAI and CODEC DAI loops in soc_bind_dai_link() would now be identical. However, two things prevent that at present: 1) The need to save rtd->codec for the CODEC side, which means we have to search for the CODEC explicitly, and not just the CODEC side DAI. 2) Since we know the CODEC side DAI is part of a codec, and not just a standalone DAI, it's slightly more efficient to convert .codec_name/ .codec_of_node into a codec first, and then compare each DAI's .codec field, since this avoids strcmp() on each DAI's CODEC's name within the loop. However, the two loops are essentially semantically equivalent. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- include/sound/soc.h | 33 ++++++++++++++++++++++---- sound/soc/mxs/mxs-sgtl5000.c | 2 +- sound/soc/soc-core.c | 42 ++++++++++++++++++++++++--------- sound/soc/tegra/tegra_alc5632.c | 6 ++--- sound/soc/tegra/tegra_wm8753.c | 6 ++--- sound/soc/tegra/tegra_wm8903.c | 6 ++--- sound/soc/tegra/trimslice.c | 6 ++--- 7 files changed, 72 insertions(+), 29 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index c703871f5f65..23c4efbe13a6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -785,13 +785,36 @@ struct snd_soc_dai_link { /* config - must be set by machine driver */ const char *name; /* Codec name */ const char *stream_name; /* Stream name */ - const char *codec_name; /* for multi-codec */ - const struct device_node *codec_of_node; - const char *platform_name; /* for multi-platform */ - const struct device_node *platform_of_node; + /* + * You MAY specify the link's CPU-side device, either by device name, + * or by DT/OF node, but not both. If this information is omitted, + * the CPU-side DAI is matched using .cpu_dai_name only, which hence + * must be globally unique. These fields are currently typically used + * only for codec to codec links, or systems using device tree. + */ + const char *cpu_name; + const struct device_node *cpu_of_node; + /* + * You MAY specify the DAI name of the CPU DAI. If this information is + * omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node + * only, which only works well when that device exposes a single DAI. + */ const char *cpu_dai_name; - const struct device_node *cpu_dai_of_node; + /* + * You MUST specify the link's codec, either by device name, or by + * DT/OF node, but not both. + */ + const char *codec_name; + const struct device_node *codec_of_node; + /* You MUST specify the DAI name within the codec */ const char *codec_dai_name; + /* + * You MAY specify the link's platform/PCM/DMA driver, either by + * device name, or by DT/OF node, but not both. Some forms of link + * do not need a platform. + */ + const char *platform_name; + const struct device_node *platform_of_node; int be_id; /* optional ID for machine driver BE identification */ const struct snd_soc_pcm_stream *params; diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 3e6e8764b2e6..215113b05f7d 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -133,7 +133,7 @@ static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev) mxs_sgtl5000_dai[i].codec_name = NULL; mxs_sgtl5000_dai[i].codec_of_node = codec_np; mxs_sgtl5000_dai[i].cpu_dai_name = NULL; - mxs_sgtl5000_dai[i].cpu_dai_of_node = saif_np[i]; + mxs_sgtl5000_dai[i].cpu_of_node = saif_np[i]; mxs_sgtl5000_dai[i].platform_name = NULL; mxs_sgtl5000_dai[i].platform_of_node = saif_np[i]; } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b37ee8077ed1..ec8350570346 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -812,13 +812,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) /* Find CPU DAI from registered DAIs*/ list_for_each_entry(cpu_dai, &dai_list, list) { - if (dai_link->cpu_dai_of_node) { - if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) - continue; - } else { - if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) - continue; - } + if (dai_link->cpu_of_node && + (cpu_dai->dev->of_node != dai_link->cpu_of_node)) + continue; + if (dai_link->cpu_name && + strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name)) + continue; + if (dai_link->cpu_dai_name && + strcmp(cpu_dai->name, dai_link->cpu_dai_name)) + continue; rtd->cpu_dai = cpu_dai; } @@ -3346,6 +3348,12 @@ int snd_soc_register_card(struct snd_soc_card *card) link->name); return -EINVAL; } + /* Codec DAI name must be specified */ + if (!link->codec_dai_name) { + dev_err(card->dev, "codec_dai_name not set for %s\n", + link->name); + return -EINVAL; + } /* * Platform may be specified by either name or OF node, but @@ -3358,12 +3366,24 @@ int snd_soc_register_card(struct snd_soc_card *card) } /* - * CPU DAI must be specified by 1 of name or OF node, - * not both or neither. + * CPU device may be specified by either name or OF node, but + * can be left unspecified, and will be matched based on DAI + * name alone.. + */ + if (link->cpu_name && link->cpu_of_node) { + dev_err(card->dev, + "Neither/both cpu name/of_node are set for %s\n", + link->name); + return -EINVAL; + } + /* + * At least one of CPU DAI name or CPU device name/node must be + * specified */ - if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { + if (!link->cpu_dai_name && + !(link->cpu_name || link->cpu_of_node)) { dev_err(card->dev, - "Neither/both cpu_dai name/of_node are set for %s\n", + "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", link->name); return -EINVAL; } diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 15669570ae31..417b09b83fdf 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -197,16 +197,16 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) goto err; } - tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( + tegra_alc5632_dai.cpu_of_node = of_parse_phandle( pdev->dev.of_node, "nvidia,i2s-controller", 0); - if (!tegra_alc5632_dai.cpu_dai_of_node) { + if (!tegra_alc5632_dai.cpu_of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); ret = -EINVAL; goto err; } - tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node; + tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node; ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); if (ret) diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 4e77026807a2..02bd5a8e8544 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -157,9 +157,9 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) goto err; } - tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle( + tegra_wm8753_dai.cpu_of_node = of_parse_phandle( pdev->dev.of_node, "nvidia,i2s-controller", 0); - if (!tegra_wm8753_dai.cpu_dai_of_node) { + if (!tegra_wm8753_dai.cpu_of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); ret = -EINVAL; @@ -167,7 +167,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) } tegra_wm8753_dai.platform_of_node = - tegra_wm8753_dai.cpu_dai_of_node; + tegra_wm8753_dai.cpu_of_node; ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index b75e0e8db1d0..1fd71e5a9eb9 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -331,9 +331,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) } tegra_wm8903_dai.cpu_dai_name = NULL; - tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(np, + tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, "nvidia,i2s-controller", 0); - if (!tegra_wm8903_dai.cpu_dai_of_node) { + if (!tegra_wm8903_dai.cpu_of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); ret = -EINVAL; @@ -342,7 +342,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) tegra_wm8903_dai.platform_name = NULL; tegra_wm8903_dai.platform_of_node = - tegra_wm8903_dai.cpu_dai_of_node; + tegra_wm8903_dai.cpu_of_node; } else { card->dapm_routes = harmony_audio_map; card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 4a8d5b672c9f..5815430e8521 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -162,9 +162,9 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) } trimslice_tlv320aic23_dai.cpu_dai_name = NULL; - trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle( + trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle( pdev->dev.of_node, "nvidia,i2s-controller", 0); - if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) { + if (!trimslice_tlv320aic23_dai.cpu_of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); ret = -EINVAL; @@ -173,7 +173,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) trimslice_tlv320aic23_dai.platform_name = NULL; trimslice_tlv320aic23_dai.platform_of_node = - trimslice_tlv320aic23_dai.cpu_dai_of_node; + trimslice_tlv320aic23_dai.cpu_of_node; } ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); -- GitLab From 6c9d8cf6372ed2995a3d982f5c1f966e842101cc Mon Sep 17 00:00:00 2001 From: Adam Thomson Date: Thu, 31 May 2012 15:18:01 +0100 Subject: [PATCH 0091/6849] ASoC: core: Add single controls with specified range of values Control type added for cases where a specific range of values within a register are required for control. Added convenience macros: SOC_SINGLE_RANGE SOC_SINGLE_RANGE_TLV Added accessor implementations: snd_soc_info_volsw_range snd_soc_put_volsw_range snd_soc_get_volsw_range Signed-off-by: Michal Hajduk Signed-off-by: Adam Thomson Signed-off-by: Mark Brown --- include/sound/soc.h | 23 +++++++++++ sound/soc/soc-core.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 23c4efbe13a6..e4348d25fca3 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -47,6 +47,13 @@ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ .put = snd_soc_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } +#define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \ + .put = snd_soc_put_volsw_range, \ + .private_value = (unsigned long)&(struct soc_mixer_control) \ + {.reg = xreg, .shift = xshift, .min = xmin,\ + .max = xmax, .platform_max = xmax, .invert = xinvert} } #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -67,6 +74,16 @@ {.reg = xreg, .rreg = xreg, \ .shift = xshift, .rshift = xshift, \ .max = xmax, .min = xmin} } +#define SOC_SINGLE_RANGE_TLV(xname, xreg, xshift, xmin, xmax, xinvert, tlv_array) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ + SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .tlv.p = (tlv_array), \ + .info = snd_soc_info_volsw_range, \ + .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ + .private_value = (unsigned long)&(struct soc_mixer_control) \ + {.reg = xreg, .shift = xshift, .min = xmin,\ + .max = xmax, .platform_max = xmax, .invert = xinvert} } #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ @@ -460,6 +477,12 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); int snd_soc_limit_volume(struct snd_soc_codec *codec, const char *name, int max); int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ec8350570346..3d803f3cd272 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2791,6 +2791,104 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); +/** + * snd_soc_info_volsw_range - single mixer info callback with range. + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to provide information, within a range, about a single + * mixer control. + * + * returns 0 for success. + */ +int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int platform_max; + int min = mc->min; + + if (!mc->platform_max) + mc->platform_max = mc->max; + platform_max = mc->platform_max; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = platform_max - min; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); + +/** + * snd_soc_put_volsw_range - single mixer put value callback with range. + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to set the value, within a range, for a single mixer control. + * + * Returns 0 for success. + */ +int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + int min = mc->min; + int max = mc->max; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; + unsigned int val, val_mask; + + val = ((ucontrol->value.integer.value[0] + min) & mask); + if (invert) + val = max - val; + val_mask = mask << shift; + val = val << shift; + + return snd_soc_update_bits_locked(codec, reg, val_mask, val); +} +EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); + +/** + * snd_soc_get_volsw_range - single mixer get callback with range + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to get the value, within a range, of a single mixer control. + * + * Returns 0 for success. + */ +int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + int min = mc->min; + int max = mc->max; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; + + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, reg) >> shift) & mask; + if (invert) + ucontrol->value.integer.value[0] = + max - ucontrol->value.integer.value[0]; + ucontrol->value.integer.value[0] = + ucontrol->value.integer.value[0] - min; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); + /** * snd_soc_limit_volume - Set new limit to an existing volume control. * -- GitLab From 141eba2e006dd8145bed2e49fae3de5af65ab9b0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 24 May 2012 10:47:26 -0600 Subject: [PATCH 0092/6849] regmap: allow busses to request formatting with specific endianness Add a field to struct regmap_bus that allows bus drivers to request that register addresses and values be formatted with a specific endianness. The default endianness is unchanged from current operation: Big. Implement native endian formatting/parsing for 16- and 32-bit values. This will be enough to support regmap-mmio.c. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 101 +++++++++++++++++++++++++++++++---- include/linux/regmap.h | 25 +++++++++ 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 0bcda488f11c..1cf721421bec 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -119,13 +119,19 @@ static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) b[0] = val << shift; } -static void regmap_format_16(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) { __be16 *b = buf; b[0] = cpu_to_be16(val << shift); } +static void regmap_format_16_native(void *buf, unsigned int val, + unsigned int shift) +{ + *(u16 *)buf = val << shift; +} + static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) { u8 *b = buf; @@ -137,13 +143,19 @@ static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) b[2] = val; } -static void regmap_format_32(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) { __be32 *b = buf; b[0] = cpu_to_be32(val << shift); } +static void regmap_format_32_native(void *buf, unsigned int val, + unsigned int shift) +{ + *(u32 *)buf = val << shift; +} + static unsigned int regmap_parse_8(void *buf) { u8 *b = buf; @@ -151,7 +163,7 @@ static unsigned int regmap_parse_8(void *buf) return b[0]; } -static unsigned int regmap_parse_16(void *buf) +static unsigned int regmap_parse_16_be(void *buf) { __be16 *b = buf; @@ -160,6 +172,11 @@ static unsigned int regmap_parse_16(void *buf) return b[0]; } +static unsigned int regmap_parse_16_native(void *buf) +{ + return *(u16 *)buf; +} + static unsigned int regmap_parse_24(void *buf) { u8 *b = buf; @@ -170,7 +187,7 @@ static unsigned int regmap_parse_24(void *buf) return ret; } -static unsigned int regmap_parse_32(void *buf) +static unsigned int regmap_parse_32_be(void *buf) { __be32 *b = buf; @@ -179,6 +196,11 @@ static unsigned int regmap_parse_32(void *buf) return b[0]; } +static unsigned int regmap_parse_32_native(void *buf) +{ + return *(u32 *)buf; +} + static void regmap_lock_mutex(struct regmap *map) { mutex_lock(&map->mutex); @@ -227,6 +249,7 @@ struct regmap *regmap_init(struct device *dev, { struct regmap *map, **m; int ret = -EINVAL; + enum regmap_endian reg_endian, val_endian; if (!bus || !config) goto err; @@ -275,6 +298,18 @@ struct regmap *regmap_init(struct device *dev, map->read_flag_mask = bus->read_flag_mask; } + reg_endian = config->reg_format_endian; + if (reg_endian == REGMAP_ENDIAN_DEFAULT) + reg_endian = bus->reg_format_endian_default; + if (reg_endian == REGMAP_ENDIAN_DEFAULT) + reg_endian = REGMAP_ENDIAN_BIG; + + val_endian = config->val_format_endian; + if (val_endian == REGMAP_ENDIAN_DEFAULT) + val_endian = bus->val_format_endian_default; + if (val_endian == REGMAP_ENDIAN_DEFAULT) + val_endian = REGMAP_ENDIAN_BIG; + switch (config->reg_bits + map->reg_shift) { case 2: switch (config->val_bits) { @@ -321,11 +356,29 @@ struct regmap *regmap_init(struct device *dev, break; case 16: - map->format.format_reg = regmap_format_16; + switch (reg_endian) { + case REGMAP_ENDIAN_BIG: + map->format.format_reg = regmap_format_16_be; + break; + case REGMAP_ENDIAN_NATIVE: + map->format.format_reg = regmap_format_16_native; + break; + default: + goto err_map; + } break; case 32: - map->format.format_reg = regmap_format_32; + switch (reg_endian) { + case REGMAP_ENDIAN_BIG: + map->format.format_reg = regmap_format_32_be; + break; + case REGMAP_ENDIAN_NATIVE: + map->format.format_reg = regmap_format_32_native; + break; + default: + goto err_map; + } break; default: @@ -338,21 +391,47 @@ struct regmap *regmap_init(struct device *dev, map->format.parse_val = regmap_parse_8; break; case 16: - map->format.format_val = regmap_format_16; - map->format.parse_val = regmap_parse_16; + switch (val_endian) { + case REGMAP_ENDIAN_BIG: + map->format.format_val = regmap_format_16_be; + map->format.parse_val = regmap_parse_16_be; + break; + case REGMAP_ENDIAN_NATIVE: + map->format.format_val = regmap_format_16_native; + map->format.parse_val = regmap_parse_16_native; + break; + default: + goto err_map; + } break; case 24: + if (val_endian != REGMAP_ENDIAN_BIG) + goto err_map; map->format.format_val = regmap_format_24; map->format.parse_val = regmap_parse_24; break; case 32: - map->format.format_val = regmap_format_32; - map->format.parse_val = regmap_parse_32; + switch (val_endian) { + case REGMAP_ENDIAN_BIG: + map->format.format_val = regmap_format_32_be; + map->format.parse_val = regmap_parse_32_be; + break; + case REGMAP_ENDIAN_NATIVE: + map->format.format_val = regmap_format_32_native; + map->format.parse_val = regmap_parse_32_native; + break; + default: + goto err_map; + } break; } - if (map->format.format_write) + if (map->format.format_write) { + if ((reg_endian != REGMAP_ENDIAN_BIG) || + (val_endian != REGMAP_ENDIAN_BIG)) + goto err_map; map->use_single_rw = true; + } if (!map->format.format_write && !(map->format.format_reg && map->format.format_val)) diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 56af22ec9aba..26136b577009 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -43,6 +43,14 @@ struct reg_default { #ifdef CONFIG_REGMAP +enum regmap_endian { + /* Unspecified -> 0 -> Backwards compatible default */ + REGMAP_ENDIAN_DEFAULT = 0, + REGMAP_ENDIAN_BIG, + REGMAP_ENDIAN_LITTLE, + REGMAP_ENDIAN_NATIVE, +}; + /** * Configuration for the register map of a device. * @@ -84,6 +92,12 @@ struct reg_default { * @reg_defaults_raw: Power on reset values for registers (for use with * register cache support). * @num_reg_defaults_raw: Number of elements in reg_defaults_raw. + * @reg_format_endian: Endianness for formatted register addresses. If this is + * DEFAULT, the @reg_format_endian_default value from the + * regmap bus is used. + * @val_format_endian: Endianness for formatted register values. If this is + * DEFAULT, the @reg_format_endian_default value from the + * regmap bus is used. */ struct regmap_config { const char *name; @@ -109,6 +123,9 @@ struct regmap_config { u8 write_flag_mask; bool use_single_rw; + + enum regmap_endian reg_format_endian; + enum regmap_endian val_format_endian; }; typedef int (*regmap_hw_write)(void *context, const void *data, @@ -133,6 +150,12 @@ typedef void (*regmap_hw_free_context)(void *context); * data. * @read_flag_mask: Mask to be set in the top byte of the register when doing * a read. + * @reg_format_endian_default: Default endianness for formatted register + * addresses. Used when the regmap_config specifies DEFAULT. If this is + * DEFAULT, BIG is assumed. + * @val_format_endian_default: Default endianness for formatted register + * values. Used when the regmap_config specifies DEFAULT. If this is + * DEFAULT, BIG is assumed. */ struct regmap_bus { bool fast_io; @@ -141,6 +164,8 @@ struct regmap_bus { regmap_hw_read read; regmap_hw_free_context free_context; u8 read_flag_mask; + enum regmap_endian reg_format_endian_default; + enum regmap_endian val_format_endian_default; }; struct regmap *regmap_init(struct device *dev, -- GitLab From 6a55244e897d32952832a67cb35cfbfa3f722c50 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 24 May 2012 10:47:27 -0600 Subject: [PATCH 0093/6849] regmap: mmio: request native endian formatting This will avoid the regmap core converting all addresses and values into big endian, only for the mmio bus driver to have to convert them back to native endian. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-mmio.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index febd6de6c8ac..eec86639cac4 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c @@ -37,7 +37,7 @@ static int regmap_mmio_gather_write(void *context, BUG_ON(reg_size != 4); - offset = be32_to_cpup(reg); + offset = *(u32 *)reg; while (val_size) { switch (ctx->val_bytes) { @@ -45,14 +45,14 @@ static int regmap_mmio_gather_write(void *context, writeb(*(u8 *)val, ctx->regs + offset); break; case 2: - writew(be16_to_cpup(val), ctx->regs + offset); + writew(*(u16 *)val, ctx->regs + offset); break; case 4: - writel(be32_to_cpup(val), ctx->regs + offset); + writel(*(u32 *)val, ctx->regs + offset); break; #ifdef CONFIG_64BIT case 8: - writeq(be64_to_cpup(val), ctx->regs + offset); + writeq(*(u64 *)val, ctx->regs + offset); break; #endif default: @@ -83,7 +83,7 @@ static int regmap_mmio_read(void *context, BUG_ON(reg_size != 4); - offset = be32_to_cpup(reg); + offset = *(u32 *)reg; while (val_size) { switch (ctx->val_bytes) { @@ -91,14 +91,14 @@ static int regmap_mmio_read(void *context, *(u8 *)val = readb(ctx->regs + offset); break; case 2: - *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset)); + *(u16 *)val = readw(ctx->regs + offset); break; case 4: - *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset)); + *(u32 *)val = readl(ctx->regs + offset); break; #ifdef CONFIG_64BIT case 8: - *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset)); + *(u64 *)val = readq(ctx->regs + offset); break; #endif default: @@ -124,6 +124,8 @@ static struct regmap_bus regmap_mmio = { .gather_write = regmap_mmio_gather_write, .read = regmap_mmio_read, .free_context = regmap_mmio_free_context, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, }; struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, @@ -162,6 +164,14 @@ struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, if (config->reg_stride < min_stride) return ERR_PTR(-EINVAL); + switch (config->reg_format_endian) { + case REGMAP_ENDIAN_DEFAULT: + case REGMAP_ENDIAN_NATIVE: + break; + default: + return ERR_PTR(-EINVAL); + } + ctx = kzalloc(GFP_KERNEL, sizeof(*ctx)); if (!ctx) return ERR_PTR(-ENOMEM); -- GitLab From b026ddbbd25e3560c8d69beb96a5980d96c59b43 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 31 May 2012 21:01:46 +0100 Subject: [PATCH 0094/6849] regmap: Constify regmap_irq_chip We should never be modifying it and it lets drivers declare it const. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-irq.c | 6 +++--- include/linux/regmap.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 4fac4b9be88f..c190229daa59 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -24,7 +24,7 @@ struct regmap_irq_chip_data { struct mutex lock; struct regmap *map; - struct regmap_irq_chip *chip; + const struct regmap_irq_chip *chip; int irq_base; struct irq_domain *domain; @@ -103,7 +103,7 @@ static struct irq_chip regmap_irq_chip = { static irqreturn_t regmap_irq_thread(int irq, void *d) { struct regmap_irq_chip_data *data = d; - struct regmap_irq_chip *chip = data->chip; + const struct regmap_irq_chip *chip = data->chip; struct regmap *map = data->map; int ret, i; bool handled = false; @@ -195,7 +195,7 @@ static struct irq_domain_ops regmap_domain_ops = { * register values used by the IRQ controller over suspend and resume. */ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, - int irq_base, struct regmap_irq_chip *chip, + int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { struct regmap_irq_chip_data *d; diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 26136b577009..f9b624c83464 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -268,7 +268,7 @@ struct regmap_irq_chip { struct regmap_irq_chip_data; int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, - int irq_base, struct regmap_irq_chip *chip, + int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data); -- GitLab From cffc9592fde309deafce12362e0a285108cfa3c8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 10:30:21 +0800 Subject: [PATCH 0095/6849] regulator: core: Allow drivers to set voltage mapping table in regulator_desc Some regulator hardware use table based mapping can set volt_table in regulator_desc and use regulator_list_voltage_table() for their list_voltage callback. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- drivers/regulator/core.c | 25 +++++++++++++++++++++++++ include/linux/regulator/driver.h | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7584a74eec8a..333b7ebe7cae 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1882,6 +1882,31 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev, } EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); +/** + * regulator_list_voltage_table - List voltages with table based mapping + * + * @rdev: Regulator device + * @selector: Selector to convert into a voltage + * + * Regulators with table based mapping between voltages and + * selectors can set volt_table in the regulator descriptor + * and then use this function as their list_voltage() operation. + */ +int regulator_list_voltage_table(struct regulator_dev *rdev, + unsigned int selector) +{ + if (!rdev->desc->volt_table) { + BUG_ON(!rdev->desc->volt_table); + return -EINVAL; + } + + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + + return rdev->desc->volt_table[selector]; +} +EXPORT_SYMBOL_GPL(regulator_list_voltage_table); + /** * regulator_list_voltage - enumerate supported voltages * @regulator: regulator source diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index b0432cc2b169..80226383e561 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -170,6 +170,7 @@ enum regulator_type { * * @min_uV: Voltage given by the lowest selector (if linear mapping) * @uV_step: Voltage increase with each selector (if linear mapping) + * @volt_table: Voltage mapping table (if table based mapping) * * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_ * @vsel_mask: Mask for register bitfield used for selector @@ -189,6 +190,8 @@ struct regulator_desc { unsigned int min_uV; unsigned int uV_step; + const unsigned int *volt_table; + unsigned int vsel_reg; unsigned int vsel_mask; unsigned int enable_reg; @@ -271,6 +274,8 @@ int regulator_mode_to_status(unsigned int); int regulator_list_voltage_linear(struct regulator_dev *rdev, unsigned int selector); +int regulator_list_voltage_table(struct regulator_dev *rdev, + unsigned int selector); int regulator_map_voltage_linear(struct regulator_dev *rdev, int min_uV, int max_uV); int regulator_map_voltage_iterate(struct regulator_dev *rdev, -- GitLab From 8b7485ef623b9171e5a58c67eef5912a27db5822 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 21 May 2012 09:37:52 +0800 Subject: [PATCH 0096/6849] regulator: core: Call set_voltage_time_sel() only when the regulator is on If the regulator is not on, it won't take time setting new voltage. So only call set_voltage_time_sel() to get the necessary delay when the regulator is on. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 333b7ebe7cae..58a4749c6347 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2106,7 +2106,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, * If we can't obtain the old selector there is not enough * info to call set_voltage_time_sel(). */ - if (rdev->desc->ops->set_voltage_time_sel && + if (_regulator_is_enabled(rdev) && + rdev->desc->ops->set_voltage_time_sel && rdev->desc->ops->get_voltage_sel) { old_selector = rdev->desc->ops->get_voltage_sel(rdev); if (old_selector < 0) @@ -2138,7 +2139,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, best_val = -1; /* Call set_voltage_time_sel if successfully obtained old_selector */ - if (ret == 0 && old_selector >= 0 && + if (_regulator_is_enabled(rdev) && ret == 0 && old_selector >= 0 && rdev->desc->ops->set_voltage_time_sel) { delay = rdev->desc->ops->set_voltage_time_sel(rdev, -- GitLab From 361ff5017446605dca8b0a084c826e3d2a0d0a99 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 May 2012 14:14:30 +0100 Subject: [PATCH 0097/6849] regulator: Use newly added devres_release() rather than open coding devres_release() will call the destructor for the resource as well as freeing the devres data. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 58a4749c6347..7965e86a3fbb 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1459,7 +1459,7 @@ void devm_regulator_put(struct regulator *regulator) { int rc; - rc = devres_destroy(regulator->dev, devm_regulator_release, + rc = devres_release(regulator->dev, devm_regulator_release, devm_regulator_match, regulator); if (rc == 0) regulator_put(regulator); -- GitLab From 3a4b0a07fa69cbfbdd4bc2ebe769cf789949db46 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 8 May 2012 18:10:45 +0100 Subject: [PATCH 0098/6849] regulator: core: Use dev_get_regmap() to find the regmap If no regmap is explicitly specified then use dev_get_regmap() to obtain one. The driver must explicitly enable any actual usage of the regmap so there's no concern with unwanted usage. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/regulator/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7965e86a3fbb..8521e0d6b3bc 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3128,7 +3128,10 @@ regulator_register(const struct regulator_desc *regulator_desc, rdev->reg_data = config->driver_data; rdev->owner = regulator_desc->owner; rdev->desc = regulator_desc; - rdev->regmap = config->regmap; + if (config->regmap) + rdev->regmap = config->regmap; + else + rdev->regmap = dev_get_regmap(dev, NULL); INIT_LIST_HEAD(&rdev->consumer_list); INIT_LIST_HEAD(&rdev->list); BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); -- GitLab From a3beb74261f26142019847128b2441b0301797ac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 10:31:58 +0800 Subject: [PATCH 0099/6849] regulator: ab3100: Use regulator_list_voltage_table() Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab3100.c | 50 +++++++++++--------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 03f4d9c604ec..b088b6c228c8 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -45,9 +45,6 @@ * @regreg: regulator register number in the AB3100 * @fixed_voltage: a fixed voltage for this regulator, if this * 0 the voltages array is used instead. - * @typ_voltages: an array of available typical voltages for - * this regulator - * @voltages_len: length of the array of available voltages */ struct ab3100_regulator { struct regulator_dev *rdev; @@ -55,8 +52,6 @@ struct ab3100_regulator { struct ab3100_platform_data *plfdata; u8 regreg; int fixed_voltage; - int const *typ_voltages; - u8 voltages_len; }; /* The order in which registers are initialized */ @@ -80,7 +75,7 @@ static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = { #define LDO_C_VOLTAGE 2650000 #define LDO_D_VOLTAGE 2650000 -static const int ldo_e_buck_typ_voltages[] = { +static const unsigned int ldo_e_buck_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -90,7 +85,7 @@ static const int ldo_e_buck_typ_voltages[] = { 900000, }; -static const int ldo_f_typ_voltages[] = { +static const unsigned int ldo_f_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -101,21 +96,21 @@ static const int ldo_f_typ_voltages[] = { 2650000, }; -static const int ldo_g_typ_voltages[] = { +static const unsigned int ldo_g_typ_voltages[] = { 2850000, 2750000, 1800000, 1500000, }; -static const int ldo_h_typ_voltages[] = { +static const unsigned int ldo_h_typ_voltages[] = { 2750000, 1800000, 1500000, 1200000, }; -static const int ldo_k_typ_voltages[] = { +static const unsigned int ldo_k_typ_voltages[] = { 2750000, 1800000, }; @@ -138,28 +133,18 @@ ab3100_regulators[AB3100_NUM_REGULATORS] = { }, { .regreg = AB3100_LDO_E, - .typ_voltages = ldo_e_buck_typ_voltages, - .voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages), }, { .regreg = AB3100_LDO_F, - .typ_voltages = ldo_f_typ_voltages, - .voltages_len = ARRAY_SIZE(ldo_f_typ_voltages), }, { .regreg = AB3100_LDO_G, - .typ_voltages = ldo_g_typ_voltages, - .voltages_len = ARRAY_SIZE(ldo_g_typ_voltages), }, { .regreg = AB3100_LDO_H, - .typ_voltages = ldo_h_typ_voltages, - .voltages_len = ARRAY_SIZE(ldo_h_typ_voltages), }, { .regreg = AB3100_LDO_K, - .typ_voltages = ldo_k_typ_voltages, - .voltages_len = ARRAY_SIZE(ldo_k_typ_voltages), }, { .regreg = AB3100_LDO_EXT, @@ -167,8 +152,6 @@ ab3100_regulators[AB3100_NUM_REGULATORS] = { }, { .regreg = AB3100_BUCK, - .typ_voltages = ldo_e_buck_typ_voltages, - .voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages), }, }; @@ -257,16 +240,6 @@ static int ab3100_is_enabled_regulator(struct regulator_dev *reg) return regval & AB3100_REG_ON_MASK; } -static int ab3100_list_voltage_regulator(struct regulator_dev *reg, - unsigned selector) -{ - struct ab3100_regulator *abreg = reg->reg_data; - - if (selector >= abreg->voltages_len) - return -EINVAL; - return abreg->typ_voltages[selector]; -} - static int ab3100_get_voltage_regulator(struct regulator_dev *reg) { struct ab3100_regulator *abreg = reg->reg_data; @@ -294,14 +267,14 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg) regval &= 0xE0; regval >>= 5; - if (regval >= abreg->voltages_len) { + if (regval >= reg->desc->n_voltages) { dev_err(®->dev, "regulator register %02x contains an illegal voltage setting\n", abreg->regreg); return -EINVAL; } - return abreg->typ_voltages[regval]; + return reg->desc->volt_table[regval]; } static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg, @@ -423,7 +396,7 @@ static struct regulator_ops regulator_ops_variable = { .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator, .set_voltage_sel = ab3100_set_voltage_regulator_sel, - .list_voltage = ab3100_list_voltage_regulator, + .list_voltage = regulator_list_voltage_table, .enable_time = ab3100_enable_time_regulator, }; @@ -434,7 +407,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = { .get_voltage = ab3100_get_voltage_regulator, .set_voltage_sel = ab3100_set_voltage_regulator_sel, .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, - .list_voltage = ab3100_list_voltage_regulator, + .list_voltage = regulator_list_voltage_table, .enable_time = ab3100_enable_time_regulator, }; @@ -479,6 +452,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_E, .ops = ®ulator_ops_variable_sleepable, .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), + .volt_table = ldo_e_buck_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -487,6 +461,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_F, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), + .volt_table = ldo_f_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -495,6 +470,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_G, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), + .volt_table = ldo_g_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -503,6 +479,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_H, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), + .volt_table = ldo_h_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -511,6 +488,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_K, .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), + .volt_table = ldo_k_typ_voltages, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, -- GitLab From ec1cc4d9da39b58764fdb6f3d1aebcfe709a688f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 10:33:35 +0800 Subject: [PATCH 0100/6849] regulator: ab8500: Use regulator_list_voltage_table() Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 64 ++++++++++++++------------------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e1b8c54ace5a..da883e661b38 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -40,8 +40,6 @@ * @voltage_bank: bank to control regulator voltage * @voltage_reg: register to control regulator voltage * @voltage_mask: mask to control regulator voltage - * @voltages: supported voltage table - * @voltages_len: number of supported voltages for the regulator * @delay: startup/set voltage delay in us */ struct ab8500_regulator_info { @@ -58,13 +56,11 @@ struct ab8500_regulator_info { u8 voltage_bank; u8 voltage_reg; u8 voltage_mask; - int const *voltages; - int voltages_len; unsigned int delay; }; /* voltage tables for the vauxn/vintcore supplies */ -static const int ldo_vauxn_voltages[] = { +static const unsigned int ldo_vauxn_voltages[] = { 1100000, 1200000, 1300000, @@ -83,7 +79,7 @@ static const int ldo_vauxn_voltages[] = { 3300000, }; -static const int ldo_vaux3_voltages[] = { +static const unsigned int ldo_vaux3_voltages[] = { 1200000, 1500000, 1800000, @@ -94,7 +90,7 @@ static const int ldo_vaux3_voltages[] = { 2910000, }; -static const int ldo_vintcore_voltages[] = { +static const unsigned int ldo_vintcore_voltages[] = { 1200000, 1225000, 1250000, @@ -185,25 +181,6 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) return false; } -static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) -{ - struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - - if (info == NULL) { - dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); - return -EINVAL; - } - - /* return the uV for the fixed regulators */ - if (info->fixed_uV) - return info->fixed_uV; - - if (selector >= info->voltages_len) - return -EINVAL; - - return info->voltages[selector]; -} - static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) { int ret, val; @@ -296,11 +273,24 @@ static struct regulator_ops ab8500_regulator_ops = { .is_enabled = ab8500_regulator_is_enabled, .get_voltage_sel = ab8500_regulator_get_voltage_sel, .set_voltage_sel = ab8500_regulator_set_voltage_sel, - .list_voltage = ab8500_list_voltage, + .list_voltage = regulator_list_voltage_table, .enable_time = ab8500_regulator_enable_time, .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; +static int ab8500_fixed_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + return info->fixed_uV; +} + static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) { struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); @@ -318,7 +308,7 @@ static struct regulator_ops ab8500_regulator_fixed_ops = { .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .get_voltage = ab8500_fixed_get_voltage, - .list_voltage = ab8500_list_voltage, + .list_voltage = ab8500_fixed_list_voltage, .enable_time = ab8500_regulator_enable_time, .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; @@ -329,7 +319,7 @@ static struct ab8500_regulator_info * Variable Voltage Regulators * name, min mV, max mV, * update bank, reg, mask, enable val - * volt bank, reg, mask, table, table length + * volt bank, reg, mask */ [AB8500_LDO_AUX1] = { .desc = { @@ -339,6 +329,7 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUX1, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + .volt_table = ldo_vauxn_voltages, }, .min_uV = 1100000, .max_uV = 3300000, @@ -349,8 +340,6 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x1f, .voltage_mask = 0x0f, - .voltages = ldo_vauxn_voltages, - .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), }, [AB8500_LDO_AUX2] = { .desc = { @@ -360,6 +349,7 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUX2, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + .volt_table = ldo_vauxn_voltages, }, .min_uV = 1100000, .max_uV = 3300000, @@ -370,8 +360,6 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x20, .voltage_mask = 0x0f, - .voltages = ldo_vauxn_voltages, - .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), }, [AB8500_LDO_AUX3] = { .desc = { @@ -381,6 +369,7 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUX3, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), + .volt_table = ldo_vaux3_voltages, }, .min_uV = 1100000, .max_uV = 3300000, @@ -391,8 +380,6 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x21, .voltage_mask = 0x07, - .voltages = ldo_vaux3_voltages, - .voltages_len = ARRAY_SIZE(ldo_vaux3_voltages), }, [AB8500_LDO_INTCORE] = { .desc = { @@ -402,6 +389,7 @@ static struct ab8500_regulator_info .id = AB8500_LDO_INTCORE, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), + .volt_table = ldo_vintcore_voltages, }, .min_uV = 1100000, .max_uV = 3300000, @@ -412,8 +400,6 @@ static struct ab8500_regulator_info .voltage_bank = 0x03, .voltage_reg = 0x80, .voltage_mask = 0x38, - .voltages = ldo_vintcore_voltages, - .voltages_len = ARRAY_SIZE(ldo_vintcore_voltages), }, /* @@ -769,9 +755,7 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, if (info->desc.id == AB8500_LDO_AUX3) { info->desc.n_voltages = ARRAY_SIZE(ldo_vauxn_voltages); - info->voltages = ldo_vauxn_voltages; - info->voltages_len = - ARRAY_SIZE(ldo_vauxn_voltages); + info->desc.volt_table = ldo_vauxn_voltages; info->voltage_mask = 0xf; } } -- GitLab From 4f73ccad5ca0ce25d0fd73cf3b65975e93a45ce4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 10:36:17 +0800 Subject: [PATCH 0101/6849] regulator: lp3972: Use regulator_list_voltage_table() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/lp3972.c | 102 +++++++++++++------------------------ 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index de073df7d344..3cdc755d9b22 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -74,54 +74,40 @@ struct lp3972 { #define LP3972_OVER2_LDO4_EN BIT(4) #define LP3972_OVER1_S_EN BIT(2) -static const int ldo1_voltage_map[] = { - 1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875, - 1900, 1925, 1950, 1975, 2000, +static const unsigned int ldo1_voltage_map[] = { + 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000, + 1900000, 1925000, 1950000, 1975000, 2000000, }; -static const int ldo23_voltage_map[] = { - 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, - 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, +static const unsigned int ldo23_voltage_map[] = { + 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, + 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, }; -static const int ldo4_voltage_map[] = { - 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, - 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300, +static const unsigned int ldo4_voltage_map[] = { + 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, + 1400000, 1500000, 1800000, 1900000, 2500000, 2800000, 3000000, 3300000, }; -static const int ldo5_voltage_map[] = { - 0, 0, 0, 0, 0, 850, 875, 900, - 925, 950, 975, 1000, 1025, 1050, 1075, 1100, - 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, - 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, +static const unsigned int ldo5_voltage_map[] = { + 0, 0, 0, 0, 0, 850000, 875000, 900000, + 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, + 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, + 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, }; -static const int buck1_voltage_map[] = { - 725, 750, 775, 800, 825, 850, 875, 900, - 925, 950, 975, 1000, 1025, 1050, 1075, 1100, - 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, - 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, +static const unsigned int buck1_voltage_map[] = { + 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, + 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, + 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, + 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, }; -static const int buck23_voltage_map[] = { - 0, 800, 850, 900, 950, 1000, 1050, 1100, - 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, - 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800, - 3000, 3300, -}; - -static const int *ldo_voltage_map[] = { - ldo1_voltage_map, - ldo23_voltage_map, - ldo23_voltage_map, - ldo4_voltage_map, - ldo5_voltage_map, -}; - -static const int *buck_voltage_map[] = { - buck1_voltage_map, - buck23_voltage_map, - buck23_voltage_map, +static const unsigned int buck23_voltage_map[] = { + 0, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, + 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, + 1550000, 1600000, 1650000, 1700000, 1800000, 1900000, 2500000, 2800000, + 3000000, 3300000, }; static const int ldo_output_enable_mask[] = { @@ -160,7 +146,6 @@ static const int buck_base_addr[] = { LP3972_B3TV_REG, }; -#define LP3972_LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[x]) #define LP3972_LDO_OUTPUT_ENABLE_MASK(x) (ldo_output_enable_mask[x]) #define LP3972_LDO_OUTPUT_ENABLE_REG(x) (ldo_output_enable_addr[x]) @@ -177,7 +162,6 @@ static const int buck_base_addr[] = { #define LP3972_LDO_VOL_MIN_IDX(x) (((x) == 4) ? 0x05 : 0x00) #define LP3972_LDO_VOL_MAX_IDX(x) ((x) ? (((x) == 4) ? 0x1f : 0x0f) : 0x0c) -#define LP3972_BUCK_VOL_VALUE_MAP(x) (buck_voltage_map[x]) #define LP3972_BUCK_VOL_ENABLE_REG(x) (buck_vol_enable_addr[x]) #define LP3972_BUCK_VOL1_REG(x) (buck_base_addr[x]) #define LP3972_BUCK_VOL_MASK 0x1f @@ -242,17 +226,6 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val) return ret; } -static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index) -{ - int ldo = rdev_get_id(dev) - LP3972_LDO1; - - if (index < LP3972_LDO_VOL_MIN_IDX(ldo) || - index > LP3972_LDO_VOL_MAX_IDX(ldo)) - return -EINVAL; - - return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index]; -} - static int lp3972_ldo_is_enabled(struct regulator_dev *dev) { struct lp3972 *lp3972 = rdev_get_drvdata(dev); @@ -294,7 +267,7 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev) reg = lp3972_reg_read(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo)); val = (reg >> LP3972_LDO_VOL_CONTR_SHIFT(ldo)) & mask; - return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val]; + return dev->desc->volt_table[val]; } static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev, @@ -337,7 +310,7 @@ static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3972_ldo_ops = { - .list_voltage = lp3972_ldo_list_voltage, + .list_voltage = regulator_list_voltage_table, .is_enabled = lp3972_ldo_is_enabled, .enable = lp3972_ldo_enable, .disable = lp3972_ldo_disable, @@ -345,17 +318,6 @@ static struct regulator_ops lp3972_ldo_ops = { .set_voltage_sel = lp3972_ldo_set_voltage_sel, }; -static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index) -{ - int buck = rdev_get_id(dev) - LP3972_DCDC1; - - if (index < LP3972_BUCK_VOL_MIN_IDX(buck) || - index > LP3972_BUCK_VOL_MAX_IDX(buck)) - return -EINVAL; - - return 1000 * buck_voltage_map[buck][index]; -} - static int lp3972_dcdc_is_enabled(struct regulator_dev *dev) { struct lp3972 *lp3972 = rdev_get_drvdata(dev); @@ -401,7 +363,7 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev) reg = lp3972_reg_read(lp3972, LP3972_BUCK_VOL1_REG(buck)); reg &= LP3972_BUCK_VOL_MASK; if (reg <= LP3972_BUCK_VOL_MAX_IDX(buck)) - val = 1000 * buck_voltage_map[buck][reg]; + val = dev->desc->volt_table[reg]; else { val = 0; dev_warn(&dev->dev, "chip reported incorrect voltage value." @@ -436,7 +398,7 @@ static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3972_dcdc_ops = { - .list_voltage = lp3972_dcdc_list_voltage, + .list_voltage = regulator_list_voltage_table, .is_enabled = lp3972_dcdc_is_enabled, .enable = lp3972_dcdc_enable, .disable = lp3972_dcdc_disable, @@ -450,6 +412,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO1, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo1_voltage_map), + .volt_table = ldo1_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -458,6 +421,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO2, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo23_voltage_map), + .volt_table = ldo23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -466,6 +430,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO3, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo23_voltage_map), + .volt_table = ldo23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -474,6 +439,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO4, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo4_voltage_map), + .volt_table = ldo4_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -482,6 +448,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_LDO5, .ops = &lp3972_ldo_ops, .n_voltages = ARRAY_SIZE(ldo5_voltage_map), + .volt_table = ldo5_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -490,6 +457,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_DCDC1, .ops = &lp3972_dcdc_ops, .n_voltages = ARRAY_SIZE(buck1_voltage_map), + .volt_table = buck1_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -498,6 +466,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_DCDC2, .ops = &lp3972_dcdc_ops, .n_voltages = ARRAY_SIZE(buck23_voltage_map), + .volt_table = buck23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -506,6 +475,7 @@ static const struct regulator_desc regulators[] = { .id = LP3972_DCDC3, .ops = &lp3972_dcdc_ops, .n_voltages = ARRAY_SIZE(buck23_voltage_map), + .volt_table = buck23_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, -- GitLab From c55979b7bd78b8ee7999bcf5211bf0243260c675 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 10:37:33 +0800 Subject: [PATCH 0102/6849] regulator: tps6105x: Use regulator_list_voltage_table() Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/tps6105x-regulator.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index d840d8440a91..1378409efaec 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -20,7 +20,7 @@ #include #include -static const int tps6105x_voltages[] = { +static const unsigned int tps6105x_voltages[] = { 4500000, 5000000, 5250000, @@ -105,22 +105,13 @@ static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev, return 0; } -static int tps6105x_regulator_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector >= ARRAY_SIZE(tps6105x_voltages)) - return -EINVAL; - - return tps6105x_voltages[selector]; -} - static struct regulator_ops tps6105x_regulator_ops = { .enable = tps6105x_regulator_enable, .disable = tps6105x_regulator_disable, .is_enabled = tps6105x_regulator_is_enabled, .get_voltage_sel = tps6105x_regulator_get_voltage_sel, .set_voltage_sel = tps6105x_regulator_set_voltage_sel, - .list_voltage = tps6105x_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, }; static const struct regulator_desc tps6105x_regulator_desc = { @@ -130,6 +121,7 @@ static const struct regulator_desc tps6105x_regulator_desc = { .id = 0, .owner = THIS_MODULE, .n_voltages = ARRAY_SIZE(tps6105x_voltages), + .volt_table = tps6105x_voltages, }; /* -- GitLab From 055917ac560a4185b75511b512f2db941b984672 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 10:39:12 +0800 Subject: [PATCH 0103/6849] regulator: tps6507x: Use regulator_list_voltage_table() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6507x-regulator.c | 100 +++++++++++-------------- 1 file changed, 43 insertions(+), 57 deletions(-) diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index da38be1016aa..c771e1077cc1 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -43,50 +43,50 @@ /* Number of total regulators available */ #define TPS6507X_NUM_REGULATOR (TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO) -/* Supported voltage values for regulators (in milliVolts) */ -static const u16 VDCDCx_VSEL_table[] = { - 725, 750, 775, 800, - 825, 850, 875, 900, - 925, 950, 975, 1000, - 1025, 1050, 1075, 1100, - 1125, 1150, 1175, 1200, - 1225, 1250, 1275, 1300, - 1325, 1350, 1375, 1400, - 1425, 1450, 1475, 1500, - 1550, 1600, 1650, 1700, - 1750, 1800, 1850, 1900, - 1950, 2000, 2050, 2100, - 2150, 2200, 2250, 2300, - 2350, 2400, 2450, 2500, - 2550, 2600, 2650, 2700, - 2750, 2800, 2850, 2900, - 3000, 3100, 3200, 3300, +/* Supported voltage values for regulators (in microVolts) */ +static const unsigned int VDCDCx_VSEL_table[] = { + 725000, 750000, 775000, 800000, + 825000, 850000, 875000, 900000, + 925000, 950000, 975000, 1000000, + 1025000, 1050000, 1075000, 1100000, + 1125000, 1150000, 1175000, 1200000, + 1225000, 1250000, 1275000, 1300000, + 1325000, 1350000, 1375000, 1400000, + 1425000, 1450000, 1475000, 1500000, + 1550000, 1600000, 1650000, 1700000, + 1750000, 1800000, 1850000, 1900000, + 1950000, 2000000, 2050000, 2100000, + 2150000, 2200000, 2250000, 2300000, + 2350000, 2400000, 2450000, 2500000, + 2550000, 2600000, 2650000, 2700000, + 2750000, 2800000, 2850000, 2900000, + 3000000, 3100000, 3200000, 3300000, }; -static const u16 LDO1_VSEL_table[] = { - 1000, 1100, 1200, 1250, - 1300, 1350, 1400, 1500, - 1600, 1800, 2500, 2750, - 2800, 3000, 3100, 3300, +static const unsigned int LDO1_VSEL_table[] = { + 1000000, 1100000, 1200000, 1250000, + 1300000, 1350000, 1400000, 1500000, + 1600000, 1800000, 2500000, 2750000, + 2800000, 3000000, 3100000, 3300000, }; -static const u16 LDO2_VSEL_table[] = { - 725, 750, 775, 800, - 825, 850, 875, 900, - 925, 950, 975, 1000, - 1025, 1050, 1075, 1100, - 1125, 1150, 1175, 1200, - 1225, 1250, 1275, 1300, - 1325, 1350, 1375, 1400, - 1425, 1450, 1475, 1500, - 1550, 1600, 1650, 1700, - 1750, 1800, 1850, 1900, - 1950, 2000, 2050, 2100, - 2150, 2200, 2250, 2300, - 2350, 2400, 2450, 2500, - 2550, 2600, 2650, 2700, - 2750, 2800, 2850, 2900, - 3000, 3100, 3200, 3300, +static const unsigned int LDO2_VSEL_table[] = { + 725000, 750000, 775000, 800000, + 825000, 850000, 875000, 900000, + 925000, 950000, 975000, 1000000, + 1025000, 1050000, 1075000, 1100000, + 1125000, 1150000, 1175000, 1200000, + 1225000, 1250000, 1275000, 1300000, + 1325000, 1350000, 1375000, 1400000, + 1425000, 1450000, 1475000, 1500000, + 1550000, 1600000, 1650000, 1700000, + 1750000, 1800000, 1850000, 1900000, + 1950000, 2000000, 2050000, 2100000, + 2150000, 2200000, 2250000, 2300000, + 2350000, 2400000, 2450000, 2500000, + 2550000, 2600000, 2650000, 2700000, + 2750000, 2800000, 2850000, 2900000, + 3000000, 3100000, 3200000, 3300000, }; struct tps_info { @@ -94,7 +94,7 @@ struct tps_info { unsigned min_uV; unsigned max_uV; u8 table_len; - const u16 *table; + const unsigned int *table; /* Does DCDC high or the low register defines output voltage? */ bool defdcdc_default; @@ -375,28 +375,13 @@ static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, return tps6507x_pmic_reg_write(tps, reg, data); } -static int tps6507x_pmic_list_voltage(struct regulator_dev *dev, - unsigned selector) -{ - struct tps6507x_pmic *tps = rdev_get_drvdata(dev); - int rid = rdev_get_id(dev); - - if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2) - return -EINVAL; - - if (selector >= tps->info[rid]->table_len) - return -EINVAL; - else - return tps->info[rid]->table[selector] * 1000; -} - static struct regulator_ops tps6507x_pmic_ops = { .is_enabled = tps6507x_pmic_is_enabled, .enable = tps6507x_pmic_enable, .disable = tps6507x_pmic_disable, .get_voltage_sel = tps6507x_pmic_get_voltage_sel, .set_voltage_sel = tps6507x_pmic_set_voltage_sel, - .list_voltage = tps6507x_pmic_list_voltage, + .list_voltage = regulator_list_voltage_table, }; static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) @@ -449,6 +434,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) tps->desc[i].name = info->name; tps->desc[i].id = i; tps->desc[i].n_voltages = info->table_len; + tps->desc[i].volt_table = info->table; tps->desc[i].ops = &tps6507x_pmic_ops; tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; -- GitLab From cad8d76e20eda5ccfcfbccdd711b91e053b4ab05 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 May 2012 13:30:28 +0800 Subject: [PATCH 0104/6849] regulator: lp3971: Use regulator_list_voltage_table() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/lp3971.c | 66 +++++++++++++------------------------- 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 981bea9cb9d7..7c6e3b8ff484 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -65,11 +65,11 @@ static const int buck_base_addr[] = { #define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x]) #define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1) -static const int buck_voltage_map[] = { - 0, 800, 850, 900, 950, 1000, 1050, 1100, - 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, - 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800, - 3000, 3300, +static const unsigned int buck_voltage_map[] = { + 0, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, + 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, + 1550000, 1600000, 1650000, 1700000, 1800000, 1900000, 2500000, 2800000, + 3000000, 3300000, }; #define BUCK_TARGET_VOL_MASK 0x3f @@ -98,39 +98,19 @@ static const int buck_voltage_map[] = { #define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2) #define LDO_VOL_CONTR_MASK 0x0f -static const int ldo45_voltage_map[] = { - 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, - 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300, +static const unsigned int ldo45_voltage_map[] = { + 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, + 1400000, 1500000, 1800000, 1900000, 2500000, 2800000, 3000000, 3300000, }; -static const int ldo123_voltage_map[] = { - 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, - 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, +static const unsigned int ldo123_voltage_map[] = { + 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, + 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, }; -static const int *ldo_voltage_map[] = { - ldo123_voltage_map, /* LDO1 */ - ldo123_voltage_map, /* LDO2 */ - ldo123_voltage_map, /* LDO3 */ - ldo45_voltage_map, /* LDO4 */ - ldo45_voltage_map, /* LDO5 */ -}; - -#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)]) - #define LDO_VOL_MIN_IDX 0x00 #define LDO_VOL_MAX_IDX 0x0f -static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index) -{ - int ldo = rdev_get_id(dev) - LP3971_LDO1; - - if (index > LDO_VOL_MAX_IDX) - return -EINVAL; - - return 1000 * LDO_VOL_VALUE_MAP(ldo)[index]; -} - static int lp3971_ldo_is_enabled(struct regulator_dev *dev) { struct lp3971 *lp3971 = rdev_get_drvdata(dev); @@ -169,7 +149,7 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev) reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo)); val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK; - return 1000 * LDO_VOL_VALUE_MAP(ldo)[val]; + return dev->desc->volt_table[val]; } static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev, @@ -184,7 +164,7 @@ static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3971_ldo_ops = { - .list_voltage = lp3971_ldo_list_voltage, + .list_voltage = regulator_list_voltage_table, .is_enabled = lp3971_ldo_is_enabled, .enable = lp3971_ldo_enable, .disable = lp3971_ldo_disable, @@ -192,14 +172,6 @@ static struct regulator_ops lp3971_ldo_ops = { .set_voltage_sel = lp3971_ldo_set_voltage_sel, }; -static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index) -{ - if (index < BUCK_TARGET_VOL_MIN_IDX || index > BUCK_TARGET_VOL_MAX_IDX) - return -EINVAL; - - return 1000 * buck_voltage_map[index]; -} - static int lp3971_dcdc_is_enabled(struct regulator_dev *dev) { struct lp3971 *lp3971 = rdev_get_drvdata(dev); @@ -240,7 +212,7 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev) reg &= BUCK_TARGET_VOL_MASK; if (reg <= BUCK_TARGET_VOL_MAX_IDX) - val = 1000 * buck_voltage_map[reg]; + val = buck_voltage_map[reg]; else { val = 0; dev_warn(&dev->dev, "chip reported incorrect voltage value.\n"); @@ -273,7 +245,7 @@ static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev, } static struct regulator_ops lp3971_dcdc_ops = { - .list_voltage = lp3971_dcdc_list_voltage, + .list_voltage = regulator_list_voltage_table, .is_enabled = lp3971_dcdc_is_enabled, .enable = lp3971_dcdc_enable, .disable = lp3971_dcdc_disable, @@ -287,6 +259,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO1, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo123_voltage_map), + .volt_table = ldo123_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -295,6 +268,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO2, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo123_voltage_map), + .volt_table = ldo123_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -303,6 +277,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO3, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo123_voltage_map), + .volt_table = ldo123_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -311,6 +286,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO4, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo45_voltage_map), + .volt_table = ldo45_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -319,6 +295,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_LDO5, .ops = &lp3971_ldo_ops, .n_voltages = ARRAY_SIZE(ldo45_voltage_map), + .volt_table = ldo45_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -327,6 +304,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_DCDC1, .ops = &lp3971_dcdc_ops, .n_voltages = ARRAY_SIZE(buck_voltage_map), + .volt_table = buck_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -335,6 +313,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_DCDC2, .ops = &lp3971_dcdc_ops, .n_voltages = ARRAY_SIZE(buck_voltage_map), + .volt_table = buck_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -343,6 +322,7 @@ static const struct regulator_desc regulators[] = { .id = LP3971_DCDC3, .ops = &lp3971_dcdc_ops, .n_voltages = ARRAY_SIZE(buck_voltage_map), + .volt_table = buck_voltage_map, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, -- GitLab From 6333e9ddf4787ec42cbb4cbb482168094e54b337 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 21 May 2012 09:39:08 +0800 Subject: [PATCH 0105/6849] regulator: ab8500: Let regulator core handle the case no delay for setting new voltage if regulator is off Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index da883e661b38..f15807449011 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -256,14 +256,7 @@ static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int new_sel) { struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - int ret; - /* If the regulator isn't on, it won't take time here */ - ret = ab8500_regulator_is_enabled(rdev); - if (ret < 0) - return ret; - if (!ret) - return 0; return info->delay; } -- GitLab From b4ec87aedbdae602dbc232915ff5a8c1fad89b36 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 30 Apr 2012 21:00:10 +0100 Subject: [PATCH 0106/6849] regulator: wm8350: Convert to use core regmap vsel readback Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 75 +++++++--------------------- 1 file changed, 19 insertions(+), 56 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 94e550dc70b6..5ccab371b408 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -405,34 +405,6 @@ static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, return 0; } -static int wm8350_dcdc_get_voltage_sel(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, dcdc = rdev_get_id(rdev); - - switch (dcdc) { - case WM8350_DCDC_1: - volt_reg = WM8350_DCDC1_CONTROL; - break; - case WM8350_DCDC_3: - volt_reg = WM8350_DCDC3_CONTROL; - break; - case WM8350_DCDC_4: - volt_reg = WM8350_DCDC4_CONTROL; - break; - case WM8350_DCDC_6: - volt_reg = WM8350_DCDC6_CONTROL; - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - /* all DCDCs have same mV bits */ - return wm8350_reg_read(wm8350, volt_reg) & WM8350_DC1_VSEL_MASK; -} - static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev, unsigned selector) { @@ -805,32 +777,6 @@ static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, return 0; } -static int wm8350_ldo_get_voltage_sel(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, ldo = rdev_get_id(rdev); - - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_CONTROL; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_CONTROL; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_CONTROL; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_CONTROL; - break; - default: - return -EINVAL; - } - - /* all LDOs have same mV bits */ - return wm8350_reg_read(wm8350, volt_reg) & WM8350_LDO1_VSEL_MASK; -} - static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, unsigned selector) { @@ -1225,7 +1171,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev) static struct regulator_ops wm8350_dcdc_ops = { .set_voltage = wm8350_dcdc_set_voltage, - .get_voltage_sel = wm8350_dcdc_get_voltage_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = wm8350_dcdc_list_voltage, .enable = wm8350_dcdc_enable, .disable = wm8350_dcdc_disable, @@ -1249,7 +1195,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = { static struct regulator_ops wm8350_ldo_ops = { .set_voltage = wm8350_ldo_set_voltage, - .get_voltage_sel = wm8350_ldo_get_voltage_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = wm8350_ldo_list_voltage, .enable = wm8350_ldo_enable, .disable = wm8350_ldo_disable, @@ -1277,6 +1223,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC1, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .vsel_reg = WM8350_DCDC1_CONTROL, + .vsel_mask = WM8350_DC1_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1294,6 +1242,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC3, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .vsel_reg = WM8350_DCDC3_CONTROL, + .vsel_mask = WM8350_DC3_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1303,6 +1253,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC4, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .vsel_reg = WM8350_DCDC4_CONTROL, + .vsel_mask = WM8350_DC4_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1320,6 +1272,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC6, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .vsel_reg = WM8350_DCDC6_CONTROL, + .vsel_mask = WM8350_DC6_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1329,6 +1283,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO1, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO1_VSEL_MASK + 1, + .vsel_reg = WM8350_LDO1_CONTROL, + .vsel_mask = WM8350_LDO1_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1338,6 +1294,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO2, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO2_VSEL_MASK + 1, + .vsel_reg = WM8350_LDO2_CONTROL, + .vsel_mask = WM8350_LDO2_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1347,6 +1305,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO3, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO3_VSEL_MASK + 1, + .vsel_reg = WM8350_LDO3_CONTROL, + .vsel_mask = WM8350_LDO3_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1356,6 +1316,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_LDO4, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_LDO4_VSEL_MASK + 1, + .vsel_reg = WM8350_LDO4_CONTROL, + .vsel_mask = WM8350_LDO4_VSEL_MASK, .owner = THIS_MODULE, }, { @@ -1429,6 +1391,7 @@ static int wm8350_regulator_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.init_data = pdev->dev.platform_data; config.driver_data = dev_get_drvdata(&pdev->dev); + config.regmap = wm8350->regmap; /* register regulator */ rdev = regulator_register(&wm8350_reg[pdev->id], &config); -- GitLab From a540f682860b3ce11fbfd36118bf64d5d4152bc1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 30 Apr 2012 21:08:59 +0100 Subject: [PATCH 0107/6849] regulator: wm8350: Convert to core regmap-based enable operations Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 121 +++++++-------------------- 1 file changed, 29 insertions(+), 92 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 5ccab371b408..12ecaec770a1 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -905,63 +905,6 @@ int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode, } EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode); -static int wm8350_dcdc_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 shift; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - shift = dcdc - WM8350_DCDC_1; - wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - return 0; -} - -static int wm8350_dcdc_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 shift; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - shift = dcdc - WM8350_DCDC_1; - wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - - return 0; -} - -static int wm8350_ldo_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int ldo = rdev_get_id(rdev); - u16 shift; - - if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) - return -EINVAL; - - shift = (ldo - WM8350_LDO_1) + 8; - wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - return 0; -} - -static int wm8350_ldo_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int ldo = rdev_get_id(rdev); - u16 shift; - - if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) - return -EINVAL; - - shift = (ldo - WM8350_LDO_1) + 8; - wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - return 0; -} - static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable) { int reg = 0, ret; @@ -1143,42 +1086,16 @@ static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev, return mode; } -static int wm8350_dcdc_is_enabled(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev), shift; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - shift = dcdc - WM8350_DCDC_1; - return wm8350_reg_read(wm8350, WM8350_DCDC_LDO_REQUESTED) - & (1 << shift); -} - -static int wm8350_ldo_is_enabled(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int ldo = rdev_get_id(rdev), shift; - - if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) - return -EINVAL; - - shift = (ldo - WM8350_LDO_1) + 8; - return wm8350_reg_read(wm8350, WM8350_DCDC_LDO_REQUESTED) - & (1 << shift); -} - static struct regulator_ops wm8350_dcdc_ops = { .set_voltage = wm8350_dcdc_set_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = wm8350_dcdc_list_voltage, - .enable = wm8350_dcdc_enable, - .disable = wm8350_dcdc_disable, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .get_mode = wm8350_dcdc_get_mode, .set_mode = wm8350_dcdc_set_mode, .get_optimum_mode = wm8350_dcdc_get_optimum_mode, - .is_enabled = wm8350_dcdc_is_enabled, .set_suspend_voltage = wm8350_dcdc_set_suspend_voltage, .set_suspend_enable = wm8350_dcdc_set_suspend_enable, .set_suspend_disable = wm8350_dcdc_set_suspend_disable, @@ -1186,9 +1103,9 @@ static struct regulator_ops wm8350_dcdc_ops = { }; static struct regulator_ops wm8350_dcdc2_5_ops = { - .enable = wm8350_dcdc_enable, - .disable = wm8350_dcdc_disable, - .is_enabled = wm8350_dcdc_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .set_suspend_enable = wm8350_dcdc25_set_suspend_enable, .set_suspend_disable = wm8350_dcdc25_set_suspend_disable, }; @@ -1197,9 +1114,9 @@ static struct regulator_ops wm8350_ldo_ops = { .set_voltage = wm8350_ldo_set_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = wm8350_ldo_list_voltage, - .enable = wm8350_ldo_enable, - .disable = wm8350_ldo_disable, - .is_enabled = wm8350_ldo_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .get_mode = wm8350_ldo_get_mode, .set_suspend_voltage = wm8350_ldo_set_suspend_voltage, .set_suspend_enable = wm8350_ldo_set_suspend_enable, @@ -1225,6 +1142,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_DCDC_MAX_VSEL + 1, .vsel_reg = WM8350_DCDC1_CONTROL, .vsel_mask = WM8350_DC1_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_DC1_ENA, .owner = THIS_MODULE, }, { @@ -1233,6 +1152,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .ops = &wm8350_dcdc2_5_ops, .irq = WM8350_IRQ_UV_DC2, .type = REGULATOR_VOLTAGE, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_DC2_ENA, .owner = THIS_MODULE, }, { @@ -1244,6 +1165,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_DCDC_MAX_VSEL + 1, .vsel_reg = WM8350_DCDC3_CONTROL, .vsel_mask = WM8350_DC3_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_DC3_ENA, .owner = THIS_MODULE, }, { @@ -1255,6 +1178,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_DCDC_MAX_VSEL + 1, .vsel_reg = WM8350_DCDC4_CONTROL, .vsel_mask = WM8350_DC4_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_DC4_ENA, .owner = THIS_MODULE, }, { @@ -1263,6 +1188,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .ops = &wm8350_dcdc2_5_ops, .irq = WM8350_IRQ_UV_DC5, .type = REGULATOR_VOLTAGE, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_DC5_ENA, .owner = THIS_MODULE, }, { @@ -1274,6 +1201,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_DCDC_MAX_VSEL + 1, .vsel_reg = WM8350_DCDC6_CONTROL, .vsel_mask = WM8350_DC6_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_DC6_ENA, .owner = THIS_MODULE, }, { @@ -1285,6 +1214,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_LDO1_VSEL_MASK + 1, .vsel_reg = WM8350_LDO1_CONTROL, .vsel_mask = WM8350_LDO1_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_LDO1_ENA, .owner = THIS_MODULE, }, { @@ -1296,6 +1227,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_LDO2_VSEL_MASK + 1, .vsel_reg = WM8350_LDO2_CONTROL, .vsel_mask = WM8350_LDO2_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_LDO2_ENA, .owner = THIS_MODULE, }, { @@ -1307,6 +1240,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_LDO3_VSEL_MASK + 1, .vsel_reg = WM8350_LDO3_CONTROL, .vsel_mask = WM8350_LDO3_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_LDO3_ENA, .owner = THIS_MODULE, }, { @@ -1318,6 +1253,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .n_voltages = WM8350_LDO4_VSEL_MASK + 1, .vsel_reg = WM8350_LDO4_CONTROL, .vsel_mask = WM8350_LDO4_VSEL_MASK, + .enable_reg = WM8350_DCDC_LDO_REQUESTED, + .enable_mask = WM8350_LDO4_ENA, .owner = THIS_MODULE, }, { -- GitLab From 107a3967a814d99e700ff3788f6c66568ab914db Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 9 May 2012 22:22:30 +0100 Subject: [PATCH 0108/6849] regulator: wm8350: Convert DCDCs to set_voltage_sel() and linear voltages The WM8350 DCDCs have a simple linear mapping from selectors to voltages so can be converted very simply to use the new infrastructure for a nice reduction in code size. Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 64 ++++------------------------ 1 file changed, 8 insertions(+), 56 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 12ecaec770a1..a618284fc45e 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -359,60 +359,6 @@ int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode, } EXPORT_SYMBOL_GPL(wm8350_isink_set_flash); -static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV, unsigned *selector) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, dcdc = rdev_get_id(rdev), mV, - min_mV = min_uV / 1000, max_mV = max_uV / 1000; - u16 val; - - if (min_mV < 850 || min_mV > 4025) - return -EINVAL; - if (max_mV < 850 || max_mV > 4025) - return -EINVAL; - - /* step size is 25mV */ - mV = (min_mV - 826) / 25; - if (wm8350_dcdc_val_to_mvolts(mV) > max_mV) - return -EINVAL; - BUG_ON(wm8350_dcdc_val_to_mvolts(mV) < min_mV); - - switch (dcdc) { - case WM8350_DCDC_1: - volt_reg = WM8350_DCDC1_CONTROL; - break; - case WM8350_DCDC_3: - volt_reg = WM8350_DCDC3_CONTROL; - break; - case WM8350_DCDC_4: - volt_reg = WM8350_DCDC4_CONTROL; - break; - case WM8350_DCDC_6: - volt_reg = WM8350_DCDC6_CONTROL; - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - *selector = mV; - - /* all DCDCs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, val | mV); - return 0; -} - -static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector > WM8350_DCDC_MAX_VSEL) - return -EINVAL; - return wm8350_dcdc_val_to_mvolts(selector) * 1000; -} - static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm8350 *wm8350 = rdev_get_drvdata(rdev); @@ -1087,9 +1033,9 @@ static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev, } static struct regulator_ops wm8350_dcdc_ops = { - .set_voltage = wm8350_dcdc_set_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .list_voltage = wm8350_dcdc_list_voltage, + .list_voltage = regulator_list_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1140,6 +1086,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC1, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .min_uV = 850000, + .uV_step = 25000, .vsel_reg = WM8350_DCDC1_CONTROL, .vsel_mask = WM8350_DC1_VSEL_MASK, .enable_reg = WM8350_DCDC_LDO_REQUESTED, @@ -1163,6 +1111,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC3, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .min_uV = 850000, + .uV_step = 25000, .vsel_reg = WM8350_DCDC3_CONTROL, .vsel_mask = WM8350_DC3_VSEL_MASK, .enable_reg = WM8350_DCDC_LDO_REQUESTED, @@ -1199,6 +1149,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC6, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .min_uV = 850000, + .uV_step = 25000, .vsel_reg = WM8350_DCDC6_CONTROL, .vsel_mask = WM8350_DC6_VSEL_MASK, .enable_reg = WM8350_DCDC_LDO_REQUESTED, -- GitLab From 8029a00686e396919b9adb2a6df07d68ef96cf3d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 22 May 2012 12:26:42 +0800 Subject: [PATCH 0109/6849] regulator: palmas: Use regulator_[list|map]_voltage_linear() for palmas_ops_smps10 Signed-off-by: Axel Lin Acked-by: Graeme Gregory Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index c4435f608df7..b4e10b0b36d4 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -400,19 +400,14 @@ static struct regulator_ops palmas_ops_smps = { .map_voltage = palmas_map_voltage_smps, }; -static int palmas_list_voltage_smps10(struct regulator_dev *dev, - unsigned selector) -{ - return 3750000 + (selector * 1250000); -} - static struct regulator_ops palmas_ops_smps10 = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = palmas_list_voltage_smps10, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, }; static int palmas_is_enabled_ldo(struct regulator_dev *dev) @@ -675,6 +670,8 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].vsel_mask = SMPS10_VSEL; pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS; pmic->desc[id].enable_mask = SMPS10_BOOST_EN; + pmic->desc[id].min_uV = 3750000; + pmic->desc[id].uV_step = 1250000; } pmic->desc[id].type = REGULATOR_VOLTAGE; -- GitLab From 0713e6abf398327b6813398d3583e0907953e457 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 14 May 2012 11:06:44 +0800 Subject: [PATCH 0110/6849] regulator: anatop: Convert to regulator_list_voltage_linear() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 3660bace123c..d04cf2113245 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -94,21 +94,10 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg) return val - anatop_reg->min_bit_val; } -static int anatop_list_voltage(struct regulator_dev *reg, unsigned selector) -{ - struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - int uv; - - uv = anatop_reg->min_voltage + selector * 25000; - dev_dbg(®->dev, "vddio = %d, selector = %u\n", uv, selector); - - return uv; -} - static struct regulator_ops anatop_rops = { .set_voltage = anatop_set_voltage, .get_voltage_sel = anatop_get_voltage_sel, - .list_voltage = anatop_list_voltage, + .list_voltage = regulator_list_voltage_linear, }; static int __devinit anatop_regulator_probe(struct platform_device *pdev) @@ -176,6 +165,8 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1; + rdesc->min_uV = sreg->min_voltage; + rdesc->uV_step = 25000; config.dev = &pdev->dev; config.init_data = initdata; -- GitLab From f2d103add158af4c95223a1b576cc0cc6a41a18b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 23 May 2012 22:40:58 +0800 Subject: [PATCH 0111/6849] regulator: wm8994: Convert wm8994_ldo1_ops to regulator_[list|map]_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8994-regulator.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 9a994316e63c..0e2028b74d1a 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -77,22 +77,14 @@ static int wm8994_ldo_enable_time(struct regulator_dev *rdev) return 3000; } -static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev, - unsigned int selector) -{ - if (selector > WM8994_LDO1_MAX_SELECTOR) - return -EINVAL; - - return (selector * 100000) + 2400000; -} - static struct regulator_ops wm8994_ldo1_ops = { .enable = wm8994_ldo_enable, .disable = wm8994_ldo_disable, .is_enabled = wm8994_ldo_is_enabled, .enable_time = wm8994_ldo_enable_time, - .list_voltage = wm8994_ldo1_list_voltage, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, }; @@ -143,6 +135,8 @@ static const struct regulator_desc wm8994_ldo_desc[] = { .vsel_reg = WM8994_LDO_1, .vsel_mask = WM8994_LDO1_VSEL_MASK, .ops = &wm8994_ldo1_ops, + .min_uV = 2400000, + .uV_step = 100000, .owner = THIS_MODULE, }, { -- GitLab From c2543b5f6c3e13996776079cda1007ef6e7a0bbb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 31 May 2012 17:39:00 +0800 Subject: [PATCH 0112/6849] regulator: wm831x-ldo: Use regulator_map_voltage_linear for wm831x_alive_ldo_ops wm831x_alive_ldo_ops uses simple linear voltage maps. Thus use regulator_map_voltage_linear is more efficient than using the default regulator_map_voltage_iterate. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-ldo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index a9a28d8ac185..f23d020e9503 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -690,6 +690,7 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) static struct regulator_ops wm831x_alive_ldo_ops = { .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage = wm831x_alive_ldo_set_voltage, .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage, -- GitLab From 27eeabb7a1000de974e45cd007b3f5324dcee490 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 31 May 2012 17:40:22 +0800 Subject: [PATCH 0113/6849] regulator: wm8400: Use regulator_map_voltage_linear for wm8400_dcdc_ops wm8400_dcdc_ops uses simple linear voltage maps. Thus use regulator_map_voltage_linear is more efficient than using the default regulator_map_voltage_iterate. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8400-regulator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 69a2b7ce5e4a..f365795d51c2 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -152,6 +152,7 @@ static struct regulator_ops wm8400_dcdc_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_mode = wm8400_dcdc_get_mode, -- GitLab From 133d4016f1783b21e9458430fa7c0c610c010037 Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Fri, 1 Jun 2012 13:17:14 +0900 Subject: [PATCH 0114/6849] regulator: MAX77686: Add Maxim 77686 regulator driver Add driver for support max77686 regulator. MAX77686 provides LDOs[1~26] and BUCKs[1~9]. It support to set or get the volatege of regulator on max77686 chip with using regmap. Signed-off-by: Chiwoong Byun Signed-off-by: Jonghwa Lee Signed-off-by: Myungjoo Ham Signed-off-by: Kyungmin Park Reviewed-by: Yadwinder Singh Brar Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/max77686.c | 337 +++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 drivers/regulator/max77686.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c86b8864e411..00ffe05d8026 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -195,6 +195,14 @@ config REGULATOR_MAX8998 via I2C bus. The provided regulator is suitable for S3C6410 and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. +config REGULATOR_MAX77686 + tristate "Maxim 77686 regulator" + depends on MFD_MAX77686 + help + This driver controls a Maxim 77686 regulator + via I2C bus. The provided regulator is suitable for + Exynos-4 chips to control VARM and VINT voltages. + config REGULATOR_PCAP tristate "Motorola PCAP2 regulator driver" depends on EZX_PCAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 977fd46909ab..d8544539efec 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o +obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c new file mode 100644 index 000000000000..70046f8032fd --- /dev/null +++ b/drivers/regulator/max77686.c @@ -0,0 +1,337 @@ +/* + * max77686.c - Regulator driver for the Maxim 77686 + * + * Copyright (C) 2012 Samsung Electronics + * Chiwoong Byun + * Jonghwa Lee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This driver is based on max8997.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX77686_LDO_MINUV 800000 +#define MAX77686_LDO_UVSTEP 50000 +#define MAX77686_LDO_LOW_MINUV 800000 +#define MAX77686_LDO_LOW_UVSTEP 25000 +#define MAX77686_BUCK_MINUV 750000 +#define MAX77686_BUCK_UVSTEP 50000 +#define MAX77686_DVS_MINUV 600000 +#define MAX77686_DVS_UVSTEP 12500 + +#define MAX77686_OPMODE_SHIFT 6 +#define MAX77686_OPMODE_BUCK234_SHIFT 4 +#define MAX77686_OPMODE_MASK 0x3 + +#define MAX77686_VSEL_MASK 0x3F +#define MAX77686_DVS_VSEL_MASK 0xFF + +#define MAX77686_RAMP_RATE_MASK 0xC0 + +#define MAX77686_REGULATORS MAX77686_REG_MAX +#define MAX77686_LDOS 26 + +enum max77686_ramp_rate { + RAMP_RATE_13P75MV, + RAMP_RATE_27P5MV, + RAMP_RATE_55MV, + RAMP_RATE_NO_CTRL, /* 100mV/us */ +}; + +struct max77686_data { + struct device *dev; + struct max77686_dev *iodev; + int num_regulators; + struct regulator_dev **rdev; + int ramp_delay; /* in mV/us */ +}; + +static int max77686_set_dvs_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, unsigned int new_selector) +{ + struct max77686_data *max77686 = rdev_get_drvdata(rdev); + int ramp_rate[] = {13, 27, 55, 100}; + return (DIV_ROUND_UP(rdev->desc->uV_step + * abs(new_selector - old_selector), + ramp_rate[max77686->ramp_delay])); +} + +static int max77686_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, unsigned int new_selector) +{ + /* Unconditionally 100 mV/us */ + return (DIV_ROUND_UP(rdev->desc->uV_step + * abs(new_selector - old_selector), 100)); +} + +static struct regulator_ops max77686_ops = { + .list_voltage = regulator_list_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = max77686_set_voltage_time_sel, +}; + +static struct regulator_ops max77686_buck_dvs_ops = { + .list_voltage = regulator_list_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = max77686_set_dvs_voltage_time_sel, +}; + +#define regulator_desc_ldo(num) { \ + .name = "LDO"#num, \ + .id = MAX77686_LDO##num, \ + .ops = &max77686_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_LDO_MINUV, \ + .uV_step = MAX77686_LDO_UVSTEP, \ + .n_voltages = MAX77686_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .vsel_mask = MAX77686_VSEL_MASK, \ + .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .enable_mask = MAX77686_OPMODE_MASK \ + << MAX77686_OPMODE_SHIFT, \ +} +#define regulator_desc_ldo_low(num) { \ + .name = "LDO"#num, \ + .id = MAX77686_LDO##num, \ + .ops = &max77686_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_LDO_LOW_MINUV, \ + .uV_step = MAX77686_LDO_LOW_UVSTEP, \ + .n_voltages = MAX77686_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .vsel_mask = MAX77686_VSEL_MASK, \ + .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .enable_mask = MAX77686_OPMODE_MASK \ + << MAX77686_OPMODE_SHIFT, \ +} +#define regulator_desc_buck(num) { \ + .name = "BUCK"#num, \ + .id = MAX77686_BUCK##num, \ + .ops = &max77686_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_BUCK_MINUV, \ + .uV_step = MAX77686_BUCK_UVSTEP, \ + .n_voltages = MAX77686_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_BUCK5OUT + (num - 5) * 2, \ + .vsel_mask = MAX77686_VSEL_MASK, \ + .enable_reg = MAX77686_REG_BUCK5CTRL + (num - 5) * 2, \ + .enable_mask = MAX77686_OPMODE_MASK, \ +} +#define regulator_desc_buck1(num) { \ + .name = "BUCK"#num, \ + .id = MAX77686_BUCK##num, \ + .ops = &max77686_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_BUCK_MINUV, \ + .uV_step = MAX77686_BUCK_UVSTEP, \ + .n_voltages = MAX77686_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_BUCK1OUT, \ + .vsel_mask = MAX77686_VSEL_MASK, \ + .enable_reg = MAX77686_REG_BUCK1CTRL, \ + .enable_mask = MAX77686_OPMODE_MASK, \ +} +#define regulator_desc_buck_dvs(num) { \ + .name = "BUCK"#num, \ + .id = MAX77686_BUCK##num, \ + .ops = &max77686_buck_dvs_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_DVS_MINUV, \ + .uV_step = MAX77686_DVS_UVSTEP, \ + .n_voltages = MAX77686_DVS_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_BUCK2DVS1 + (num - 2) * 10, \ + .vsel_mask = MAX77686_DVS_VSEL_MASK, \ + .enable_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \ + .enable_mask = MAX77686_OPMODE_MASK \ + << MAX77686_OPMODE_BUCK234_SHIFT, \ +} + +static struct regulator_desc regulators[] = { + regulator_desc_ldo_low(1), + regulator_desc_ldo_low(2), + regulator_desc_ldo(3), + regulator_desc_ldo(4), + regulator_desc_ldo(5), + regulator_desc_ldo_low(6), + regulator_desc_ldo_low(7), + regulator_desc_ldo_low(8), + regulator_desc_ldo(9), + regulator_desc_ldo(10), + regulator_desc_ldo(11), + regulator_desc_ldo(12), + regulator_desc_ldo(13), + regulator_desc_ldo(14), + regulator_desc_ldo_low(15), + regulator_desc_ldo(16), + regulator_desc_ldo(17), + regulator_desc_ldo(18), + regulator_desc_ldo(19), + regulator_desc_ldo(20), + regulator_desc_ldo(21), + regulator_desc_ldo(22), + regulator_desc_ldo(23), + regulator_desc_ldo(24), + regulator_desc_ldo(25), + regulator_desc_ldo(26), + regulator_desc_buck1(1), + regulator_desc_buck_dvs(2), + regulator_desc_buck_dvs(3), + regulator_desc_buck_dvs(4), + regulator_desc_buck(5), + regulator_desc_buck(6), + regulator_desc_buck(7), + regulator_desc_buck(8), + regulator_desc_buck(9), +}; + +static __devinit int max77686_pmic_probe(struct platform_device *pdev) +{ + struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); + struct regulator_dev **rdev; + struct max77686_data *max77686; + int i, size; + int ret = 0; + struct regulator_config config; + + dev_dbg(&pdev->dev, "%s\n", __func__); + + max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data), + GFP_KERNEL); + if (!max77686) + return -ENOMEM; + + size = sizeof(struct regulator_dev *) * MAX77686_REGULATORS; + max77686->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!max77686->rdev) + return -ENOMEM; + + rdev = max77686->rdev; + max77686->dev = &pdev->dev; + max77686->iodev = iodev; + if (pdata) + max77686->num_regulators = pdata->num_regulators; + platform_set_drvdata(pdev, max77686); + + max77686->ramp_delay = RAMP_RATE_NO_CTRL; /* Set 0x3 for RAMP */ + regmap_update_bits(max77686->iodev->regmap, + MAX77686_REG_BUCK2CTRL1, MAX77686_RAMP_RATE_MASK, + max77686->ramp_delay << 6); + regmap_update_bits(max77686->iodev->regmap, + MAX77686_REG_BUCK3CTRL1, MAX77686_RAMP_RATE_MASK, + max77686->ramp_delay << 6); + regmap_update_bits(max77686->iodev->regmap, + MAX77686_REG_BUCK4CTRL1, MAX77686_RAMP_RATE_MASK, + max77686->ramp_delay << 6); + + if (pdata->num_regulators == MAX77686_REGULATORS) { + for (i = 0; i < MAX77686_REGULATORS; i++) { + config.dev = max77686->dev; + config.regmap = iodev->regmap; + config.driver_data = max77686; + config.init_data = pdata->regulators[i].initdata; + + rdev[i] = regulator_register(®ulators[i], &config); + + if (IS_ERR(rdev[i])) { + ret = PTR_ERR(rdev[i]); + dev_err(max77686->dev, + "regulator init failed for %d\n", i); + rdev[i] = NULL; + goto err; + } + } + } else { + dev_err(max77686->dev, + "Lack of initial data for regulator's initialiation\n"); + return -EINVAL; + } + return 0; +err: + for (i = 0; i < MAX77686_REGULATORS; i++) { + if (rdev[i]) + regulator_unregister(rdev[i]); + } + return ret; +} + +static int __devexit max77686_pmic_remove(struct platform_device *pdev) +{ + struct max77686_data *max77686 = platform_get_drvdata(pdev); + struct regulator_dev **rdev = max77686->rdev; + int i; + + for (i = 0; i < MAX77686_REGULATORS; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + + return 0; +} + +static const struct platform_device_id max77686_pmic_id[] = { + {"max77686-pmic", 0}, + { }, +}; +MODULE_DEVICE_TABLE(platform, max77686_pmic_id); + +static struct platform_driver max77686_pmic_driver = { + .driver = { + .name = "max77686-pmic", + .owner = THIS_MODULE, + }, + .probe = max77686_pmic_probe, + .remove = __devexit_p(max77686_pmic_remove), + .id_table = max77686_pmic_id, +}; + +static int __init max77686_pmic_init(void) +{ + return platform_driver_register(&max77686_pmic_driver); +} +subsys_initcall(max77686_pmic_init); + +static void __exit max77686_pmic_cleanup(void) +{ + platform_driver_unregister(&max77686_pmic_driver); +} +module_exit(max77686_pmic_cleanup); + +MODULE_DESCRIPTION("MAXIM 77686 Regulator Driver"); +MODULE_AUTHOR("Chiwoong Byun "); +MODULE_LICENSE("GPL"); -- GitLab From abcfaf23c7d8494bd3b3266f7a78e9efe6206ca4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 1 Jun 2012 12:16:25 +0800 Subject: [PATCH 0115/6849] regulator: fixed: Use of_match_ptr() for of_match_table entry Use the new of_match_ptr() macro for the of_match_table pointer entry to avoid having to #define match NULL. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/fixed.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index f09fe7b20e82..8bda3654ae51 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -296,8 +296,6 @@ static const struct of_device_id fixed_of_match[] __devinitconst = { {}, }; MODULE_DEVICE_TABLE(of, fixed_of_match); -#else -#define fixed_of_match NULL #endif static struct platform_driver regulator_fixed_voltage_driver = { @@ -306,7 +304,7 @@ static struct platform_driver regulator_fixed_voltage_driver = { .driver = { .name = "reg-fixed-voltage", .owner = THIS_MODULE, - .of_match_table = fixed_of_match, + .of_match_table = of_match_ptr(fixed_of_match), }, }; -- GitLab From 7e715b954a78debf021c8ad33a2cb4f462c245e3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 30 May 2012 12:47:26 +0800 Subject: [PATCH 0116/6849] regulator: Change ab8500 match names to reflect Device Tree The 'name' field in 'struct of_regulator_match' expects to match with its corresponding regulator device node in the Device Tree. This patch renames each of the regulators in the ab8500 regulator driver so this is true. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index f15807449011..290c289a653d 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -771,17 +771,17 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, + { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, + { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; static __devinit int -- GitLab From 392b309644c7223b5320b939aedf09b5a4f5a325 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 30 May 2012 12:47:27 +0800 Subject: [PATCH 0117/6849] regulator: Change db8500-prcmu match names to reflect Device Tree The 'name' field in 'struct of_regulator_match' expects to match with its corresponding regulator device node in the Device Tree. This patch renames each of the regulators in the db8500-prcum regulator driver so this is true. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/db8500-prcmu.c | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 968f97f3cb3d..9dbb491b6efa 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -452,26 +452,26 @@ static __devinit int db8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, + { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, + { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, + { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, + { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, + { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, + { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, + { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, + { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, + { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, + { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, + { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, + { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, + { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, + { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, + { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, + { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, + { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, + { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, + { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, + { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; static __devinit int -- GitLab From f59fef441753cdd07ffe7268b0801ec48cac7b1d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 30 Apr 2012 20:26:41 +0100 Subject: [PATCH 0118/6849] ASoC: wm8350: Convert to direct regmap API usage Signed-off-by: Mark Brown --- sound/soc/codecs/wm8350.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index e782a5aa2a31..d26c8ae4e6d9 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -71,20 +71,6 @@ struct wm8350_data { int fll_freq_in; }; -static unsigned int wm8350_codec_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct wm8350 *wm8350 = codec->control_data; - return wm8350_reg_read(wm8350, reg); -} - -static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - struct wm8350 *wm8350 = codec->control_data; - return wm8350_reg_write(wm8350, reg, value); -} - /* * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. */ @@ -1519,7 +1505,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; - codec->control_data = wm8350; + codec->control_data = wm8350->regmap; + + snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); /* Put the codec into reset if it wasn't already */ wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); @@ -1629,8 +1617,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { .remove = wm8350_codec_remove, .suspend = wm8350_suspend, .resume = wm8350_resume, - .read = wm8350_codec_read, - .write = wm8350_codec_write, .set_bias_level = wm8350_set_bias_level, .controls = wm8350_snd_controls, -- GitLab From d8dc3494f77a5cc3b274bae36f7e74e85cf8a407 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Fri, 1 Jun 2012 18:12:14 -0400 Subject: [PATCH 0119/6849] HID: logitech: don't use stack based dj_report structures On a system with a logitech wireless keyboard/mouse and DMA-API debugging enabled, this warning appears at boot: kernel: WARNING: at lib/dma-debug.c:929 check_for_stack.part.12+0x70/0xa7() kernel: Hardware name: MS-7593 kernel: uhci_hcd 0000:00:1d.1: DMA-API: device driver maps memory fromstack [addr=ffff8801b0079c29] Make logi_dj_recv_query_paired_devices and logi_dj_recv_switch_to_dj_mode use a structure allocated with kzalloc rather than a stack based one. Signed-off-by: Marc Dionne Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 38 ++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 5e8a7ed42344..0f9c146fc00d 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -436,27 +436,37 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) { - struct dj_report dj_report; + struct dj_report *dj_report; + int retval; - memset(&dj_report, 0, sizeof(dj_report)); - dj_report.report_id = REPORT_ID_DJ_SHORT; - dj_report.device_index = 0xFF; - dj_report.report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; - return logi_dj_recv_send_report(djrcv_dev, &dj_report); + dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); + if (!dj_report) + return -ENOMEM; + dj_report->report_id = REPORT_ID_DJ_SHORT; + dj_report->device_index = 0xFF; + dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; + retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + kfree(dj_report); + return retval; } static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, unsigned timeout) { - struct dj_report dj_report; + struct dj_report *dj_report; + int retval; - memset(&dj_report, 0, sizeof(dj_report)); - dj_report.report_id = REPORT_ID_DJ_SHORT; - dj_report.device_index = 0xFF; - dj_report.report_type = REPORT_TYPE_CMD_SWITCH; - dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; - dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; - return logi_dj_recv_send_report(djrcv_dev, &dj_report); + dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); + if (!dj_report) + return -ENOMEM; + dj_report->report_id = REPORT_ID_DJ_SHORT; + dj_report->device_index = 0xFF; + dj_report->report_type = REPORT_TYPE_CMD_SWITCH; + dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; + dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; + retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + kfree(dj_report); + return retval; } -- GitLab From fcbb71f6f8084b74fef54e40c9e515105ccc4e6e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 3 Jun 2012 23:12:16 +0800 Subject: [PATCH 0120/6849] regulator: wm8350: Use regulator_map_voltage_linear for wm8350_dcdc_ops wm8350_dcdc_ops uses simple linear voltage maps. Thus use regulator_map_voltage_linear is more efficient than using the default regulator_map_voltage_iterate. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index a618284fc45e..33c37f9c0e41 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1036,6 +1036,7 @@ static struct regulator_ops wm8350_dcdc_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, -- GitLab From 2e3f7f26e1323fb302921c4575a499710636d531 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 3 Jun 2012 22:46:14 +0800 Subject: [PATCH 0121/6849] regulator: max77686: Use regulator_map_voltage_linear for simple linear mappings Both max77686_ops and max77686_buck_dvs_ops use simple linear voltage maps. Thus use regulator_map_voltage_linear is more efficient than using the defult regulator_map_voltage_iterate. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 70046f8032fd..4e9f4f3f062b 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -90,6 +90,7 @@ static int max77686_set_voltage_time_sel(struct regulator_dev *rdev, static struct regulator_ops max77686_ops = { .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -100,6 +101,7 @@ static struct regulator_ops max77686_ops = { static struct regulator_ops max77686_buck_dvs_ops = { .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, -- GitLab From 4552a0ca61cb2133bc77dc432ea20538ea28638a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 May 2012 09:19:31 +0300 Subject: [PATCH 0122/6849] usb: dwc3: fix a WARN and a comment we're now have DWC3_EP0_BOUNCE_SIZE to tell us the actual size of the bufer. Let's use that instead of ep0 wMaxPacketSize. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9e8a3dce69fd..e6ca218ef130 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -821,14 +821,14 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, return; } - WARN_ON(req->request.length > dep->endpoint.maxpacket); + WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE); dwc->ep0_bounced = true; /* - * REVISIT in case request length is bigger than EP0 - * wMaxPacketSize, we will need two chained TRBs to handle - * the transfer. + * REVISIT in case request length is bigger than + * DWC3_EP0_BOUNCE_SIZE we will need two chained + * TRBs to handle the transfer. */ ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, dwc->ep0_bounce_addr, dep->endpoint.maxpacket, -- GitLab From a0807881af93646b5d94b5594119df609e756945 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 4 May 2012 13:03:54 +0300 Subject: [PATCH 0123/6849] usb: dwc3: handle pending unaligned Control OUT data phase correctly When DWC3_EP_PENDING_REQUEST flag is set for a Control OUT Data phase transfer, we would be missing the proper handling for unaligned OUT requests, thus hanging a transfer. Since proper handling is already done on dwc3_ep0_do_control_data(), we simply re-factor that function so it can be re-used from __dwc3_gadget_ep0_queue(). Reported-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 72 +++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index e6ca218ef130..15ec36eb461b 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -55,6 +55,8 @@ #include "io.h" static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum); +static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, + struct dwc3_ep *dep, struct dwc3_request *req); static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) { @@ -150,9 +152,8 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, return 0; } - ret = dwc3_ep0_start_trans(dwc, direction, - req->request.dma, req->request.length, - DWC3_TRBCTL_CONTROL_DATA); + __dwc3_ep0_do_control_data(dwc, dwc->eps[direction], req); + dep->flags &= ~(DWC3_EP_PENDING_REQUEST | DWC3_EP0_DIR_IN); } else if (dwc->delayed_status) { @@ -787,35 +788,23 @@ static void dwc3_ep0_do_control_setup(struct dwc3 *dwc, dwc3_ep0_out_start(dwc); } -static void dwc3_ep0_do_control_data(struct dwc3 *dwc, - const struct dwc3_event_depevt *event) +static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, + struct dwc3_ep *dep, struct dwc3_request *req) { - struct dwc3_ep *dep; - struct dwc3_request *req; int ret; - dep = dwc->eps[0]; - - if (list_empty(&dep->request_list)) { - dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n"); - dep->flags |= DWC3_EP_PENDING_REQUEST; - - if (event->endpoint_number) - dep->flags |= DWC3_EP0_DIR_IN; - return; - } - - req = next_request(&dep->request_list); - req->direction = !!event->endpoint_number; + req->direction = !!dep->number; if (req->request.length == 0) { - ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, + ret = dwc3_ep0_start_trans(dwc, dep->number, dwc->ctrl_req_addr, 0, DWC3_TRBCTL_CONTROL_DATA); } else if ((req->request.length % dep->endpoint.maxpacket) - && (event->endpoint_number == 0)) { + && (dep->number == 0)) { + u32 transfer_size; + ret = usb_gadget_map_request(&dwc->gadget, &req->request, - event->endpoint_number); + dep->number); if (ret) { dev_dbg(dwc->dev, "failed to map request\n"); return; @@ -823,6 +812,9 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE); + transfer_size = roundup(req->request.length, + (u32) dep->endpoint.maxpacket); + dwc->ep0_bounced = true; /* @@ -830,25 +822,47 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, * DWC3_EP0_BOUNCE_SIZE we will need two chained * TRBs to handle the transfer. */ - ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, - dwc->ep0_bounce_addr, dep->endpoint.maxpacket, + ret = dwc3_ep0_start_trans(dwc, dep->number, + dwc->ep0_bounce_addr, transfer_size, DWC3_TRBCTL_CONTROL_DATA); } else { ret = usb_gadget_map_request(&dwc->gadget, &req->request, - event->endpoint_number); + dep->number); if (ret) { dev_dbg(dwc->dev, "failed to map request\n"); return; } - ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, - req->request.dma, req->request.length, - DWC3_TRBCTL_CONTROL_DATA); + ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma, + req->request.length, DWC3_TRBCTL_CONTROL_DATA); } WARN_ON(ret < 0); } +static void dwc3_ep0_do_control_data(struct dwc3 *dwc, + const struct dwc3_event_depevt *event) +{ + struct dwc3_ep *dep; + struct dwc3_request *req; + + dep = dwc->eps[0]; + + if (list_empty(&dep->request_list)) { + dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n"); + dep->flags |= DWC3_EP_PENDING_REQUEST; + + if (event->endpoint_number) + dep->flags |= DWC3_EP0_DIR_IN; + return; + } + + req = next_request(&dep->request_list); + dep = dwc->eps[event->endpoint_number]; + + __dwc3_ep0_do_control_data(dwc, dep, req); +} + static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; -- GitLab From c74c6d4a024d95e81283ee4c38be6fa7baee27f9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 4 May 2012 13:08:22 +0300 Subject: [PATCH 0124/6849] usb: dwc3: ep0: switch over to IS_ALIGNED IS_ALIGNED provides a much faster operation for checking proper size alignment then a modulo operation. Let's use it. Reported-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 15ec36eb461b..477127aecb98 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -799,7 +799,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, ret = dwc3_ep0_start_trans(dwc, dep->number, dwc->ctrl_req_addr, 0, DWC3_TRBCTL_CONTROL_DATA); - } else if ((req->request.length % dep->endpoint.maxpacket) + } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && (dep->number == 0)) { u32 transfer_size; -- GitLab From 788a23f49686d82fa95b83ac7752d6322f1dad44 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 May 2012 14:22:41 +0300 Subject: [PATCH 0125/6849] usb: dwc3: ep0: align on function signature On our Transfer Not Ready handlers, only dwc3_ep0_do_control_status() had a different list of parameters. Align on the parameters in order to keep consistency. No functional changes. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 477127aecb98..75d5722db93b 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -54,7 +54,7 @@ #include "gadget.h" #include "io.h" -static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum); +static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep); static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_request *req); @@ -160,7 +160,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, dwc->delayed_status = false; if (dwc->ep0state == EP0_STATUS_PHASE) - dwc3_ep0_do_control_status(dwc, 1); + __dwc3_ep0_do_control_status(dwc, dwc->eps[1]); else dev_dbg(dwc->dev, "too early for delayed status\n"); } @@ -875,10 +875,8 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) dwc->ctrl_req_addr, 0, type); } -static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) +static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) { - struct dwc3_ep *dep = dwc->eps[epnum]; - if (dwc->resize_fifos) { dev_dbg(dwc->dev, "starting to resize fifos\n"); dwc3_gadget_resize_tx_fifos(dwc); @@ -888,6 +886,14 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) WARN_ON(dwc3_ep0_start_control_status(dep)); } +static void dwc3_ep0_do_control_status(struct dwc3 *dwc, + const struct dwc3_event_depevt *event) +{ + struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; + + __dwc3_ep0_do_control_status(dwc, dep); +} + static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { @@ -988,7 +994,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, return; } - dwc3_ep0_do_control_status(dwc, event->endpoint_number); + dwc3_ep0_do_control_status(dwc, event); } } -- GitLab From 33b84c2c06d25a3321326d91438e106b4fd5ad9f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 May 2012 14:35:17 +0300 Subject: [PATCH 0126/6849] usb: dwc3: ep0: fix a typo in comment s/has/have. No functional changes, just a typo fix on a code comment. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 75d5722db93b..e31bcd65e7ec 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -900,7 +900,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, dwc->setup_packet_pending = true; /* - * This part is very tricky: If we has just handled + * This part is very tricky: If we have just handled * XferNotReady(Setup) and we're now expecting a * XferComplete but, instead, we receive another * XferNotReady(Setup), we should STALL and restart -- GitLab From a092532483e3200a53c8b1170b3988cc668c07ef Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 22 May 2012 10:24:11 +0300 Subject: [PATCH 0127/6849] usb: dwc3: gadget: remove trailing semicolon That semicolon doesn't do anything, it's not needed and should be removed. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3df1a1973b05..045799356a29 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1032,7 +1032,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) dev_dbg(dwc->dev, "%s: failed to kick transfers\n", dep->name); } - }; + } return 0; } -- GitLab From 2c61a8efce75951148fa07f2cd7ec53ad9d9fbb3 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Wed, 15 Feb 2012 18:56:58 -0800 Subject: [PATCH 0128/6849] usb: dwc3: add definitions for new registers This patch adds definitions for some new registers that have been added to later versions of the controller, up to v2.10a. Signed-off-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 94 +++++++++++++++++++++++++++++++-------- drivers/usb/dwc3/gadget.h | 5 +++ 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f69c877add09..4d5c63dae14d 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -67,6 +67,7 @@ #define DWC3_DEVICE_EVENT_CONNECT_DONE 2 #define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE 3 #define DWC3_DEVICE_EVENT_WAKEUP 4 +#define DWC3_DEVICE_EVENT_HIBER_REQ 5 #define DWC3_DEVICE_EVENT_EOPF 6 #define DWC3_DEVICE_EVENT_SOF 7 #define DWC3_DEVICE_EVENT_ERRATIC_ERROR 9 @@ -171,28 +172,36 @@ #define DWC3_GCTL_PRTCAP_DEVICE 2 #define DWC3_GCTL_PRTCAP_OTG 3 -#define DWC3_GCTL_CORESOFTRESET (1 << 11) -#define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) -#define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) -#define DWC3_GCTL_DISSCRAMBLE (1 << 3) -#define DWC3_GCTL_DSBLCLKGTNG (1 << 0) +#define DWC3_GCTL_CORESOFTRESET (1 << 11) +#define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) +#define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) +#define DWC3_GCTL_DISSCRAMBLE (1 << 3) +#define DWC3_GCTL_GBLHIBERNATIONEN (1 << 1) +#define DWC3_GCTL_DSBLCLKGTNG (1 << 0) /* Global USB2 PHY Configuration Register */ -#define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) -#define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) +#define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) +#define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) /* Global USB3 PIPE Control Register */ -#define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) -#define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) +#define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) +#define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ -#define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) -#define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000) +#define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) +#define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000) /* Global HWPARAMS1 Register */ #define DWC3_GHWPARAMS1_EN_PWROPT(n) (((n) & (3 << 24)) >> 24) #define DWC3_GHWPARAMS1_EN_PWROPT_NO 0 #define DWC3_GHWPARAMS1_EN_PWROPT_CLK 1 +#define DWC3_GHWPARAMS1_EN_PWROPT_HIB 2 +#define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) +#define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) + +/* Global HWPARAMS4 Register */ +#define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) +#define DWC3_MAX_HIBER_SCRATCHBUFS 15 /* Device Configuration Register */ #define DWC3_DCFG_LPM_CAP (1 << 22) @@ -206,6 +215,8 @@ #define DWC3_DCFG_LOWSPEED (2 << 0) #define DWC3_DCFG_FULLSPEED1 (3 << 0) +#define DWC3_DCFG_LPM_CAP (1 << 22) + /* Device Control Register */ #define DWC3_DCTL_RUN_STOP (1 << 31) #define DWC3_DCTL_CSFTRST (1 << 30) @@ -216,14 +227,20 @@ #define DWC3_DCTL_APPL1RES (1 << 23) -#define DWC3_DCTL_TRGTULST_MASK (0x0f << 17) -#define DWC3_DCTL_TRGTULST(n) ((n) << 17) - -#define DWC3_DCTL_TRGTULST_U2 (DWC3_DCTL_TRGTULST(2)) -#define DWC3_DCTL_TRGTULST_U3 (DWC3_DCTL_TRGTULST(3)) -#define DWC3_DCTL_TRGTULST_SS_DIS (DWC3_DCTL_TRGTULST(4)) -#define DWC3_DCTL_TRGTULST_RX_DET (DWC3_DCTL_TRGTULST(5)) -#define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) +/* These apply for core versions 1.87a and earlier */ +#define DWC3_DCTL_TRGTULST_MASK (0x0f << 17) +#define DWC3_DCTL_TRGTULST(n) ((n) << 17) +#define DWC3_DCTL_TRGTULST_U2 (DWC3_DCTL_TRGTULST(2)) +#define DWC3_DCTL_TRGTULST_U3 (DWC3_DCTL_TRGTULST(3)) +#define DWC3_DCTL_TRGTULST_SS_DIS (DWC3_DCTL_TRGTULST(4)) +#define DWC3_DCTL_TRGTULST_RX_DET (DWC3_DCTL_TRGTULST(5)) +#define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) + +/* These apply for core versions 1.94a and later */ +#define DWC3_DCTL_KEEP_CONNECT (1 << 19) +#define DWC3_DCTL_L1_HIBER_EN (1 << 18) +#define DWC3_DCTL_CRS (1 << 17) +#define DWC3_DCTL_CSS (1 << 16) #define DWC3_DCTL_INITU2ENA (1 << 12) #define DWC3_DCTL_ACCEPTU2ENA (1 << 11) @@ -249,6 +266,7 @@ #define DWC3_DEVTEN_ERRTICERREN (1 << 9) #define DWC3_DEVTEN_SOFEN (1 << 7) #define DWC3_DEVTEN_EOPFEN (1 << 6) +#define DWC3_DEVTEN_HIBERNATIONREQEVTEN (1 << 5) #define DWC3_DEVTEN_WKUPEVTEN (1 << 4) #define DWC3_DEVTEN_ULSTCNGEN (1 << 3) #define DWC3_DEVTEN_CONNECTDONEEN (1 << 2) @@ -256,7 +274,15 @@ #define DWC3_DEVTEN_DISCONNEVTEN (1 << 0) /* Device Status Register */ +#define DWC3_DSTS_DCNRD (1 << 29) + +/* This applies for core versions 1.87a and earlier */ #define DWC3_DSTS_PWRUPREQ (1 << 24) + +/* These apply for core versions 1.94a and later */ +#define DWC3_DSTS_RSS (1 << 25) +#define DWC3_DSTS_SSS (1 << 24) + #define DWC3_DSTS_COREIDLE (1 << 23) #define DWC3_DSTS_DEVCTRLHLT (1 << 22) @@ -280,6 +306,11 @@ #define DWC3_DGCMD_SET_LMP 0x01 #define DWC3_DGCMD_SET_PERIODIC_PAR 0x02 #define DWC3_DGCMD_XMIT_FUNCTION 0x03 + +/* These apply for core versions 1.94a and later */ +#define DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO 0x04 +#define DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI 0x05 + #define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09 #define DWC3_DGCMD_ALL_FIFO_FLUSH 0x0a #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c @@ -287,6 +318,15 @@ #define DWC3_DGCMD_STATUS(n) (((n) >> 15) & 1) #define DWC3_DGCMD_CMDACT (1 << 10) +#define DWC3_DGCMD_CMDIOC (1 << 8) + +/* Device Generic Command Parameter Register */ +#define DWC3_DGCMDPAR_FORCE_LINKPM_ACCEPT (1 << 0) +#define DWC3_DGCMDPAR_FIFO_NUM(n) ((n) << 0) +#define DWC3_DGCMDPAR_RX_FIFO (0 << 5) +#define DWC3_DGCMDPAR_TX_FIFO (1 << 5) +#define DWC3_DGCMDPAR_LOOPBACK_DIS (0 << 0) +#define DWC3_DGCMDPAR_LOOPBACK_ENA (1 << 0) /* Device Endpoint Command Register */ #define DWC3_DEPCMD_PARAM_SHIFT 16 @@ -303,7 +343,10 @@ #define DWC3_DEPCMD_STARTTRANSFER (0x06 << 0) #define DWC3_DEPCMD_CLEARSTALL (0x05 << 0) #define DWC3_DEPCMD_SETSTALL (0x04 << 0) +/* This applies for core versions 1.90a and earlier */ #define DWC3_DEPCMD_GETSEQNUMBER (0x03 << 0) +/* This applies for core versions 1.94a and later */ +#define DWC3_DEPCMD_GETEPSTATE (0x03 << 0) #define DWC3_DEPCMD_SETTRANSFRESOURCE (0x02 << 0) #define DWC3_DEPCMD_SETEPCONFIG (0x01 << 0) @@ -437,6 +480,8 @@ enum dwc3_link_state { DWC3_LINK_STATE_HRESET = 0x09, DWC3_LINK_STATE_CMPLY = 0x0a, DWC3_LINK_STATE_LPBK = 0x0b, + DWC3_LINK_STATE_RESET = 0x0e, + DWC3_LINK_STATE_RESUME = 0x0f, DWC3_LINK_STATE_MASK = 0x0f, }; @@ -455,6 +500,7 @@ enum dwc3_device_state { #define DWC3_TRBSTS_OK 0 #define DWC3_TRBSTS_MISSED_ISOC 1 #define DWC3_TRBSTS_SETUP_PENDING 2 +#define DWC3_TRB_STS_XFER_IN_PROG 4 /* TRB Control */ #define DWC3_TRB_CTRL_HWO (1 << 0) @@ -543,6 +589,14 @@ struct dwc3_request { unsigned queued:1; }; +/* + * struct dwc3_scratchpad_array - hibernation scratchpad array + * (format defined by hw) + */ +struct dwc3_scratchpad_array { + __le64 dma_adr[DWC3_MAX_HIBER_SCRATCHBUFS]; +}; + /** * struct dwc3 - representation of our controller * @ctrl_req: usb control request which is used for ep0 @@ -624,8 +678,10 @@ struct dwc3 { #define DWC3_REVISION_180A 0x5533180a #define DWC3_REVISION_183A 0x5533183a #define DWC3_REVISION_185A 0x5533185a +#define DWC3_REVISION_187A 0x5533187a #define DWC3_REVISION_188A 0x5533188a #define DWC3_REVISION_190A 0x5533190a +#define DWC3_REVISION_194A 0x5533194a #define DWC3_REVISION_200A 0x5533200a #define DWC3_REVISION_202A 0x5533202a #define DWC3_REVISION_210A 0x5533210a diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 95ef6a2f7764..39ced0b08515 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -66,7 +66,12 @@ struct dwc3; #define DWC3_DEPCFG_FIFO_NUMBER(n) ((n) << 17) #define DWC3_DEPCFG_BURST_SIZE(n) ((n) << 22) #define DWC3_DEPCFG_DATA_SEQ_NUM(n) ((n) << 26) +/* This applies for core versions earlier than 1.94a */ #define DWC3_DEPCFG_IGN_SEQ_NUM (1 << 31) +/* These apply for core versions 1.94a and later */ +#define DWC3_DEPCFG_ACTION_INIT (0 << 30) +#define DWC3_DEPCFG_ACTION_RESTORE (1 << 30) +#define DWC3_DEPCFG_ACTION_MODIFY (2 << 30) /* DEPXFERCFG parameter 0 */ #define DWC3_DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff) -- GitLab From aed430e5139af3e2c251f52db7fc6c5e2ce2b714 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Fri, 27 Apr 2012 12:52:01 +0300 Subject: [PATCH 0129/6849] usb: dwc3: gadget: reinitialize retries retries is used twice without being reinitialized. Signed-off-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 045799356a29..c21516aef5e4 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -108,6 +108,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) dwc3_writel(dwc->regs, DWC3_DCTL, reg); /* wait for a change in DSTS */ + retries = 10000; while (--retries) { reg = dwc3_readl(dwc->regs, DWC3_DSTS); -- GitLab From d7a46a8dfc45191b39daa19c05d3ff74d1881f15 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Fri, 27 Apr 2012 12:54:05 +0300 Subject: [PATCH 0130/6849] usb: dwc3: gadget: rename phy_power() to phy_suspend() those two functions don't power PHYs, they simply put them in suspend state. Rename to reflect better what functions actually do. Signed-off-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c21516aef5e4..852bde5cc139 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1894,30 +1894,30 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc->setup_packet_pending = false; } -static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) +static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend) { u32 reg; reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); - if (on) - reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; - else + if (suspend) reg |= DWC3_GUSB3PIPECTL_SUSPHY; + else + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); } -static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on) +static void dwc3_gadget_usb2_phy_suspend(struct dwc3 *dwc, int suspend) { u32 reg; reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); - if (on) - reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; - else + if (suspend) reg |= DWC3_GUSB2PHYCFG_SUSPHY; + else + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); } @@ -1962,9 +1962,9 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) /* after reset -> Default State */ dwc->dev_state = DWC3_DEFAULT_STATE; - /* Enable PHYs */ - dwc3_gadget_usb2_phy_power(dwc, true); - dwc3_gadget_usb3_phy_power(dwc, true); + /* Resume PHYs */ + dwc3_gadget_usb2_phy_suspend(dwc, false); + dwc3_gadget_usb3_phy_suspend(dwc, false); if (dwc->gadget.speed != USB_SPEED_UNKNOWN) dwc3_disconnect_gadget(dwc); @@ -2010,16 +2010,16 @@ static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed) dwc3_writel(dwc->regs, DWC3_GCTL, reg); } -static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed) +static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed) { switch (speed) { case USB_SPEED_SUPER: - dwc3_gadget_usb2_phy_power(dwc, false); + dwc3_gadget_usb2_phy_suspend(dwc, true); break; case USB_SPEED_HIGH: case USB_SPEED_FULL: case USB_SPEED_LOW: - dwc3_gadget_usb3_phy_power(dwc, false); + dwc3_gadget_usb3_phy_suspend(dwc, true); break; } } @@ -2082,8 +2082,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) break; } - /* Disable unneded PHY */ - dwc3_gadget_disable_phy(dwc, dwc->gadget.speed); + /* Suspend unneded PHY */ + dwc3_gadget_phy_suspend(dwc, dwc->gadget.speed); dep = dwc->eps[0]; ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); -- GitLab From 802fde983e8a3391e059bd41fc272993ae642816 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Fri, 27 Apr 2012 13:10:52 +0300 Subject: [PATCH 0131/6849] usb: dwc3: support new revisions of DWC3 core Recent cores (>= 1.94a) have a set of new features, commands and a slightly different programming model. This patch aims to support those changes. Signed-off-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 83 +++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 852bde5cc139..04048333ec1a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -100,6 +100,23 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) int retries = 10000; u32 reg; + /* + * Wait until device controller is ready. Only applies to 1.94a and + * later RTL. + */ + if (dwc->revision >= DWC3_REVISION_194A) { + while (--retries) { + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + if (reg & DWC3_DSTS_DCNRD) + udelay(5); + else + break; + } + + if (retries <= 0) + return -ETIMEDOUT; + } + reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; @@ -107,6 +124,13 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) reg |= DWC3_DCTL_ULSTCHNGREQ(state); dwc3_writel(dwc->regs, DWC3_DCTL, reg); + /* + * The following code is racy when called from dwc3_gadget_wakeup, + * and is not needed, at least on newer versions + */ + if (dwc->revision >= DWC3_REVISION_194A) + return 0; + /* wait for a change in DSTS */ retries = 10000; while (--retries) { @@ -266,8 +290,8 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd) return "Clear Stall"; case DWC3_DEPCMD_SETSTALL: return "Set Stall"; - case DWC3_DEPCMD_GETSEQNUMBER: - return "Get Data Sequence Number"; + case DWC3_DEPCMD_GETEPSTATE: + return "Get Endpoint State"; case DWC3_DEPCMD_SETTRANSFRESOURCE: return "Set Endpoint Transfer Resource"; case DWC3_DEPCMD_SETEPCONFIG: @@ -1280,9 +1304,12 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g) goto out; } - /* write zeroes to Link Change Request */ - reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + /* Recent versions do this automatically */ + if (dwc->revision < DWC3_REVISION_194A) { + /* write zeroes to Link Change Request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; + dwc3_writel(dwc->regs, DWC3_DCTL, reg); + } /* poll until Link State changes to ON */ timeout = jiffies + msecs_to_jiffies(100); @@ -1326,9 +1353,14 @@ static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) reg = dwc3_readl(dwc->regs, DWC3_DCTL); if (is_on) { - reg &= ~DWC3_DCTL_TRGTULST_MASK; - reg |= (DWC3_DCTL_RUN_STOP - | DWC3_DCTL_TRGTULST_RX_DET); + if (dwc->revision <= DWC3_REVISION_187A) { + reg &= ~DWC3_DCTL_TRGTULST_MASK; + reg |= DWC3_DCTL_TRGTULST_RX_DET; + } + + if (dwc->revision >= DWC3_REVISION_194A) + reg &= ~DWC3_DCTL_KEEP_CONNECT; + reg |= DWC3_DCTL_RUN_STOP; } else { reg &= ~DWC3_DCTL_RUN_STOP; } @@ -1468,6 +1500,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g, return 0; } + static const struct usb_gadget_ops dwc3_gadget_ops = { .get_frame = dwc3_gadget_get_frame, .wakeup = dwc3_gadget_wakeup, @@ -1962,9 +1995,12 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) /* after reset -> Default State */ dwc->dev_state = DWC3_DEFAULT_STATE; - /* Resume PHYs */ - dwc3_gadget_usb2_phy_suspend(dwc, false); - dwc3_gadget_usb3_phy_suspend(dwc, false); + /* Recent versions support automatic phy suspend and don't need this */ + if (dwc->revision < DWC3_REVISION_194A) { + /* Resume PHYs */ + dwc3_gadget_usb2_phy_suspend(dwc, false); + dwc3_gadget_usb3_phy_suspend(dwc, false); + } if (dwc->gadget.speed != USB_SPEED_UNKNOWN) dwc3_disconnect_gadget(dwc); @@ -2082,8 +2118,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) break; } - /* Suspend unneded PHY */ - dwc3_gadget_phy_suspend(dwc, dwc->gadget.speed); + /* Recent versions support automatic phy suspend and don't need this */ + if (dwc->revision < DWC3_REVISION_194A) { + /* Suspend unneeded PHY */ + dwc3_gadget_phy_suspend(dwc, dwc->gadget.speed); + } dep = dwc->eps[0]; ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); @@ -2389,6 +2428,24 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) DWC3_DEVTEN_DISCONNEVTEN); dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); + /* Enable USB2 LPM and automatic phy suspend only on recent versions */ + if (dwc->revision >= DWC3_REVISION_194A) { + reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg |= DWC3_DCFG_LPM_CAP; + dwc3_writel(dwc->regs, DWC3_DCFG, reg); + + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); + + /* TODO: This should be configurable */ + reg |= DWC3_DCTL_HIRD_THRES(31); + + dwc3_writel(dwc->regs, DWC3_DCTL, reg); + + dwc3_gadget_usb2_phy_suspend(dwc, true); + dwc3_gadget_usb3_phy_suspend(dwc, true); + } + ret = device_register(&dwc->gadget.dev); if (ret) { dev_err(dwc->dev, "failed to register gadget device\n"); -- GitLab From 7acd85e0eb2ed300edf123178445237059b35fb9 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Fri, 27 Apr 2012 14:28:02 +0300 Subject: [PATCH 0132/6849] usb: dwc3: core: make sure evt->lpos is correctly initialized The same event buffers will be reused when coming out of hibernation, so we must reinitialize them properly to avoid any mistakes. While at that, also take dwc3_event_buffers_setup() out of __devinit section. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 1040bdb8dc88..49c060205c9a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -255,7 +255,7 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) * * Returns 0 on success otherwise negative errno. */ -static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc) +static int dwc3_event_buffers_setup(struct dwc3 *dwc) { struct dwc3_event_buffer *evt; int n; @@ -266,6 +266,8 @@ static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc) evt->buf, (unsigned long long) evt->dma, evt->length); + evt->lpos = 0; + dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), lower_32_bits(evt->dma)); dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), @@ -285,6 +287,9 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) for (n = 0; n < dwc->num_event_buffers; n++) { evt = dwc->ev_buffs[n]; + + evt->lpos = 0; + dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0); dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0); -- GitLab From fcc023c726b5879d8f3f0f0f48c45d09055272c4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 May 2012 10:27:56 +0300 Subject: [PATCH 0133/6849] usb: dwc3: gadget: prevent DCTL register corruption If we don't read out the contents of the register (in order to reinitialize 'reg' variable) we will be writing unknown contents to the DCTL register whenever we try to use dwc3_gadget_wakeup() function. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 04048333ec1a..867c476853ec 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1307,6 +1307,7 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g) /* Recent versions do this automatically */ if (dwc->revision < DWC3_REVISION_194A) { /* write zeroes to Link Change Request */ + reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; dwc3_writel(dwc->regs, DWC3_DCTL, reg); } -- GitLab From c4430a26948b84c0d820e83f8c640229f960d3b6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 May 2012 10:30:01 +0300 Subject: [PATCH 0134/6849] usb: dwc3: gadget: disable U1/U2 on disconnect If we get a disconnect IRQ, we should take the core out of low power mode so we can reconnect afterwards. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 867c476853ec..054ee5ec5c13 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1906,11 +1906,9 @@ static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) { + int reg; + dev_vdbg(dwc->dev, "%s\n", __func__); -#if 0 - XXX - U1/U2 is powersave optimization. Skip it for now. Anyway we need to - enable it before we can disable it. reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_INITU1ENA; @@ -1918,7 +1916,6 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) reg &= ~DWC3_DCTL_INITU2ENA; dwc3_writel(dwc->regs, DWC3_DCTL, reg); -#endif dwc3_stop_active_transfers(dwc); dwc3_disconnect_gadget(dwc); -- GitLab From 5cbe8c220c1e126dd0855ad57fe4491b267132b9 Mon Sep 17 00:00:00 2001 From: Gerard CAUVY Date: Thu, 24 May 2012 12:47:36 +0300 Subject: [PATCH 0135/6849] usb: dwc3: gadget: move AcceptU1Ena and AcceptU2Ena to Reset IRQ According to the databook, the DWC3 Core will reset those bits to 0 on USB Bus Reset. This means we must re-enable those bits on every reset interrupt. Because we will always get a Reset interrupt after loading a gadget driver, we can, instead of re-enabling something that was just lost, move the handling of those bits to the Reset Interrupt. This patch fixes USB30CV U1/U2 Test. Signed-off-by: Gerard CAUVY Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 054ee5ec5c13..a9fc7c4a5a20 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2006,6 +2006,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_TSTCTRL_MASK; reg &= ~(DWC3_DCTL_INITU1ENA | DWC3_DCTL_INITU2ENA); + reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); dwc3_writel(dwc->regs, DWC3_DCTL, reg); dwc->test_mode = false; @@ -2410,10 +2411,6 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) reg |= DWC3_DCFG_LPM_CAP; dwc3_writel(dwc->regs, DWC3_DCFG, reg); - reg = dwc3_readl(dwc->regs, DWC3_DCTL); - reg |= DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); - /* Enable all but Start and End of Frame IRQs */ reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | DWC3_DEVTEN_EVNTOVERFLOWEN | -- GitLab From ef21ede65ee3e0dfd8f2cb37de8892816e2f1257 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 31 May 2012 10:29:49 +0300 Subject: [PATCH 0136/6849] usb: dwc3: ep0: simplify error handling on dwc3_ep0_inspect_setup There's no need for returning early. Instead, we can call dwc3_ep0_stall_and_restart() conditionally. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index e31bcd65e7ec..83fcf392dda7 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -641,11 +641,11 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { struct usb_ctrlrequest *ctrl = dwc->ctrl_req; - int ret; + int ret = -EINVAL; u32 len; if (!dwc->gadget_driver) - goto err; + goto out; len = le16_to_cpu(ctrl->wLength); if (!len) { @@ -666,11 +666,9 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, if (ret == USB_GADGET_DELAYED_STATUS) dwc->delayed_status = true; - if (ret >= 0) - return; - -err: - dwc3_ep0_stall_and_restart(dwc); +out: + if (ret < 0) + dwc3_ep0_stall_and_restart(dwc); } static void dwc3_ep0_complete_data(struct dwc3 *dwc, -- GitLab From c8cf7af452ad2eb49cad13450090cdc432b5a06d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 31 May 2012 11:00:28 +0300 Subject: [PATCH 0137/6849] usb: dwc3: ep0: be careful with endianness on SetSEL command USB is always little endian, but this driver could run on non little endian cpus. Let's be carefull with that. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 83fcf392dda7..3185fe14591b 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -515,8 +515,8 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req) dwc->u1sel = timing.u1sel; dwc->u1pel = timing.u1pel; - dwc->u2sel = timing.u2sel; - dwc->u2pel = timing.u2pel; + dwc->u2sel = le16_to_cpu(timing.u2sel); + dwc->u2pel = le16_to_cpu(timing.u2pel); reg = dwc3_readl(dwc->regs, DWC3_DCTL); if (reg & DWC3_DCTL_INITU2ENA) -- GitLab From 85a781019b9b4b935f6b1792a1f48f1a3aee988f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 31 May 2012 12:32:37 +0300 Subject: [PATCH 0138/6849] usb: dwc3: ep0: rename dwc3_ep0_complete_req to dwc3_ep0_complete_status That's a much more intuitive name as that function is only called at the completion of a Status Phase. It also matches dwc3_ep0_complete_data() for the completion of Data Phase. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 3185fe14591b..90eb1ba65454 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -722,7 +722,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, } } -static void dwc3_ep0_complete_req(struct dwc3 *dwc, +static void dwc3_ep0_complete_status(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { struct dwc3_request *r; @@ -773,7 +773,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, case EP0_STATUS_PHASE: dev_vdbg(dwc->dev, "Status Phase\n"); - dwc3_ep0_complete_req(dwc, event); + dwc3_ep0_complete_status(dwc, event); break; default: WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state); -- GitLab From ae3725716edf5a73ab66831c0808542c21fa3bba Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 21 May 2012 12:01:11 -0700 Subject: [PATCH 0139/6849] usb: gadget: omap_udc: Remove omap2 support There are no active users of this code for omap2 as the boards in use have either TUSB or MUSB controller. While at it, also fix warnings related to uninitialized dc_clk and hhc_clk. Cc: linux-usb@vger.kernel.org Cc: Kyungmin Park Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 113 +++++++--------------------------- 1 file changed, 23 insertions(+), 90 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 7ba32469c5bd..24d81dcb7b4b 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -61,9 +61,6 @@ #define DMA_ADDR_INVALID (~(dma_addr_t)0) -#define OMAP2_DMA_CH(ch) (((ch) - 1) << 1) -#define OMAP24XX_DMA(name, ch) (OMAP24XX_DMA_##name + OMAP2_DMA_CH(ch)) - /* * The OMAP UDC needs _very_ early endpoint setup: before enabling the * D+ pullup to allow enumeration. That's too early for the gadget @@ -536,12 +533,8 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) : OMAP_DMA_SYNC_ELEMENT; int dma_trigger = 0; - if (cpu_is_omap24xx()) - dma_trigger = OMAP24XX_DMA(USB_W2FC_TX0, ep->dma_channel); - /* measure length in either bytes or packets */ if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) - || (cpu_is_omap24xx() && length < ep->maxpacket) || (cpu_is_omap15xx() && length < ep->maxpacket)) { txdma_ctrl = UDC_TXN_EOT | length; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, @@ -600,28 +593,14 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) int dma_trigger = 0; u16 w; - if (cpu_is_omap24xx()) - dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); - - /* NOTE: we filtered out "short reads" before, so we know - * the buffer has only whole numbers of packets. - * except MODE SELECT(6) sent the 24 bytes data in OMAP24XX DMA mode - */ - if (cpu_is_omap24xx() && packets < ep->maxpacket) { - omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, - packets, 1, OMAP_DMA_SYNC_ELEMENT, - dma_trigger, 0); - req->dma_bytes = packets; - } else { - /* set up this DMA transfer, enable the fifo, start */ - packets /= ep->ep.maxpacket; - packets = min(packets, (unsigned)UDC_RXN_TC + 1); - req->dma_bytes = packets * ep->ep.maxpacket; - omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, - ep->ep.maxpacket >> 1, packets, - OMAP_DMA_SYNC_ELEMENT, - dma_trigger, 0); - } + /* set up this DMA transfer, enable the fifo, start */ + packets /= ep->ep.maxpacket; + packets = min(packets, (unsigned)UDC_RXN_TC + 1); + req->dma_bytes = packets * ep->ep.maxpacket; + omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, + ep->ep.maxpacket >> 1, packets, + OMAP_DMA_SYNC_ELEMENT, + dma_trigger, 0); omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, 0, 0); @@ -760,10 +739,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) ep->dma_channel = channel; if (is_in) { - if (cpu_is_omap24xx()) - dma_channel = OMAP24XX_DMA(USB_W2FC_TX0, channel); - else - dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; + dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { @@ -780,11 +756,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) 0, 0); } } else { - if (cpu_is_omap24xx()) - dma_channel = OMAP24XX_DMA(USB_W2FC_RX0, channel); - else - dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; - + dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { @@ -808,7 +780,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); /* channel type P: hw synch (fifo) */ - if (cpu_class_is_omap1() && !cpu_is_omap15xx()) + if (!cpu_is_omap15xx()) omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P); } @@ -928,13 +900,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* this isn't bogus, but OMAP DMA isn't the only hardware to * have a hard time with partial packet reads... reject it. - * Except OMAP2 can handle the small packets. */ if (use_dma && ep->has_dma && ep->bEndpointAddress != 0 && (ep->bEndpointAddress & USB_DIR_IN) == 0 - && !cpu_class_is_omap2() && (req->req.length % ep->ep.maxpacket) != 0) { DBG("%s, no partial packet OUT reads\n", __func__); return -EMSGSIZE; @@ -2090,10 +2060,6 @@ static inline int machine_without_vbus_sense(void) { return (machine_is_omap_innovator() || machine_is_omap_osk() - || machine_is_omap_apollon() -#ifndef CONFIG_MACH_OMAP_H4_OTG - || machine_is_omap_h4() -#endif || machine_is_sx1() || cpu_is_omap7xx() /* No known omap7xx boards with vbus sense */ ); @@ -2307,12 +2273,9 @@ static int proc_otg_show(struct seq_file *s) u32 trans = 0; char *ctrl_name = "(UNKNOWN)"; - /* XXX This needs major revision for OMAP2+ */ tmp = omap_readl(OTG_REV); - if (cpu_class_is_omap1()) { - ctrl_name = "tranceiver_ctrl"; - trans = omap_readw(USB_TRANSCEIVER_CTRL); - } + ctrl_name = "tranceiver_ctrl"; + trans = omap_readw(USB_TRANSCEIVER_CTRL); seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", tmp >> 4, tmp & 0xf, ctrl_name, trans); tmp = omap_readw(OTG_SYSCON_1); @@ -2399,14 +2362,12 @@ static int proc_udc_show(struct seq_file *s, void *_) HMC, udc->transceiver ? udc->transceiver->label - : ((cpu_is_omap1710() || cpu_is_omap24xx()) + : (cpu_is_omap1710() ? "external" : "(none)")); - if (cpu_class_is_omap1()) { - seq_printf(s, "ULPD control %04x req %04x status %04x\n", - omap_readw(ULPD_CLOCK_CTRL), - omap_readw(ULPD_SOFT_REQ), - omap_readw(ULPD_STATUS_REQ)); - } + seq_printf(s, "ULPD control %04x req %04x status %04x\n", + omap_readw(ULPD_CLOCK_CTRL), + omap_readw(ULPD_SOFT_REQ), + omap_readw(ULPD_STATUS_REQ)); /* OTG controller registers */ if (!cpu_is_omap15xx()) @@ -2591,7 +2552,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, * and ignored for PIO-IN on newer chips * (for more reliable behavior) */ - if (!use_dma || cpu_is_omap15xx() || cpu_is_omap24xx()) + if (!use_dma || cpu_is_omap15xx()) dbuf = 0; switch (maxp) { @@ -2795,8 +2756,8 @@ static int __init omap_udc_probe(struct platform_device *pdev) struct usb_phy *xceiv = NULL; const char *type = NULL; struct omap_usb_config *config = pdev->dev.platform_data; - struct clk *dc_clk; - struct clk *hhc_clk; + struct clk *dc_clk = NULL; + struct clk *hhc_clk = NULL; /* NOTE: "knows" the order of the resources! */ if (!request_mem_region(pdev->resource[0].start, @@ -2816,16 +2777,6 @@ static int __init omap_udc_probe(struct platform_device *pdev) udelay(100); } - if (cpu_is_omap24xx()) { - dc_clk = clk_get(&pdev->dev, "usb_fck"); - hhc_clk = clk_get(&pdev->dev, "usb_l4_ick"); - BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk)); - /* can't use omap_udc_enable_clock yet */ - clk_enable(dc_clk); - clk_enable(hhc_clk); - udelay(100); - } - if (cpu_is_omap7xx()) { dc_clk = clk_get(&pdev->dev, "usb_dc_ck"); hhc_clk = clk_get(&pdev->dev, "l3_ocpi_ck"); @@ -2875,14 +2826,6 @@ static int __init omap_udc_probe(struct platform_device *pdev) hmc = HMC_1610; - if (cpu_is_omap24xx()) { - /* this could be transceiverless in one of the - * "we don't need to know" modes. - */ - type = "external"; - goto known; - } - switch (hmc) { case 0: /* POWERUP DEFAULT == 0 */ case 4: @@ -2921,7 +2864,7 @@ bad_on_1710: goto cleanup0; } } -known: + INFO("hmc mode %d, %s transceiver\n", hmc, type); /* a "gadget" abstracts/virtualizes the controller */ @@ -2975,16 +2918,6 @@ known: clk_disable(dc_clk); } - if (cpu_is_omap24xx()) { - udc->dc_clk = dc_clk; - udc->hhc_clk = hhc_clk; - /* FIXME OMAP2 don't release hhc & dc clock */ -#if 0 - clk_disable(hhc_clk); - clk_disable(dc_clk); -#endif - } - create_proc_file(); status = device_add(&udc->gadget.dev); if (status) @@ -3013,7 +2946,7 @@ cleanup0: if (xceiv) usb_put_transceiver(xceiv); - if (cpu_is_omap16xx() || cpu_is_omap24xx() || cpu_is_omap7xx()) { + if (cpu_is_omap16xx() || cpu_is_omap7xx()) { clk_disable(hhc_clk); clk_disable(dc_clk); clk_put(hhc_clk); -- GitLab From 80dd1358d33e6c85018e1e1c5d78b29ac466221a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 May 2012 14:26:09 +0300 Subject: [PATCH 0140/6849] usb: gadget: omap_udc: make checkpatch.pl happy This patch is just a cleanup patch to make checkpatch.pl a little happier with the omap_udc.c driver. No functional changes. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 201 ++++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 80 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 24d81dcb7b4b..aa2d174a2521 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -36,9 +36,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -84,14 +84,14 @@ #ifdef USE_ISO static unsigned fifo_mode = 3; #else -static unsigned fifo_mode = 0; +static unsigned fifo_mode; #endif /* "modprobe omap_udc fifo_mode=42", or else as a kernel * boot parameter "omap_udc:fifo_mode=42" */ -module_param (fifo_mode, uint, 0); -MODULE_PARM_DESC (fifo_mode, "endpoint configuration"); +module_param(fifo_mode, uint, 0); +MODULE_PARM_DESC(fifo_mode, "endpoint configuration"); #ifdef USE_DMA static bool use_dma = 1; @@ -99,8 +99,8 @@ static bool use_dma = 1; /* "modprobe omap_udc use_dma=y", or else as a kernel * boot parameter "omap_udc:use_dma=y" */ -module_param (use_dma, bool, 0); -MODULE_PARM_DESC (use_dma, "enable/disable DMA"); +module_param(use_dma, bool, 0); +MODULE_PARM_DESC(use_dma, "enable/disable DMA"); #else /* !USE_DMA */ /* save a bit of code */ @@ -108,8 +108,8 @@ MODULE_PARM_DESC (use_dma, "enable/disable DMA"); #endif /* !USE_DMA */ -static const char driver_name [] = "omap_udc"; -static const char driver_desc [] = DRIVER_DESC; +static const char driver_name[] = "omap_udc"; +static const char driver_desc[] = DRIVER_DESC; /*-------------------------------------------------------------------------*/ @@ -247,7 +247,7 @@ static int omap_ep_disable(struct usb_ep *_ep) spin_lock_irqsave(&ep->udc->lock, flags); ep->ep.desc = NULL; - nuke (ep, -ESHUTDOWN); + nuke(ep, -ESHUTDOWN); ep->ep.maxpacket = ep->maxpacket; ep->has_dma = 0; omap_writew(UDC_SET_HALT, UDC_CTRL); @@ -270,7 +270,7 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) req = kzalloc(sizeof(*req), gfp_flags); if (req) { req->req.dma = DMA_ADDR_INVALID; - INIT_LIST_HEAD (&req->queue); + INIT_LIST_HEAD(&req->queue); } return &req->req; } @@ -281,7 +281,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) struct omap_req *req = container_of(_req, struct omap_req, req); if (_req) - kfree (req); + kfree(req); } /*-------------------------------------------------------------------------*/ @@ -361,10 +361,10 @@ write_packet(u8 *buf, struct omap_req *req, unsigned max) return len; } -// FIXME change r/w fifo calling convention +/* FIXME change r/w fifo calling convention */ -// return: 0 = still running, 1 = completed, negative = errno +/* return: 0 = still running, 1 = completed, negative = errno */ static int write_fifo(struct omap_ep *ep, struct omap_req *req) { u8 *buf; @@ -426,7 +426,7 @@ read_packet(u8 *buf, struct omap_req *req, unsigned avail) return len; } -// return: 0 = still running, 1 = queue empty, negative = errno +/* return: 0 = still running, 1 = queue empty, negative = errno */ static int read_fifo(struct omap_ep *ep, struct omap_req *req) { u8 *buf; @@ -662,7 +662,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) } omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC); - if (!list_empty (&ep->queue)) { + if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, struct omap_req, queue); next_in_dma(ep, req); @@ -681,7 +681,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) } omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC); - if (!list_empty (&ep->queue)) { + if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, struct omap_req, queue); next_out_dma(ep, req); @@ -954,7 +954,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) int is_in; if (ep->bEndpointAddress == 0) { - if (!udc->ep0_pending || !list_empty (&ep->queue)) { + if (!udc->ep0_pending || !list_empty(&ep->queue)) { spin_unlock_irqrestore(&udc->lock, flags); return -EL2HLT; } @@ -981,7 +981,8 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) * always an IN ... even for IN transfers, * a weird case which seem to stall OMAP. */ - omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); + omap_writew(UDC_EP_SEL | UDC_EP_DIR, + UDC_EP_NUM); omap_writew(UDC_CLR_EP, UDC_CTRL); omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); omap_writew(UDC_EP_DIR, UDC_EP_NUM); @@ -993,7 +994,8 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* non-empty DATA stage */ } else if (is_in) { - omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); + omap_writew(UDC_EP_SEL | UDC_EP_DIR, + UDC_EP_NUM); } else { if (udc->ep0_setup) goto irq_wait; @@ -1041,7 +1043,7 @@ static int omap_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) spin_lock_irqsave(&ep->udc->lock, flags); /* make sure it's actually queued on this endpoint */ - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { if (&req->req == _req) break; } @@ -1148,8 +1150,8 @@ static struct usb_ep_ops omap_ep_ops = { .dequeue = omap_ep_dequeue, .set_halt = omap_ep_set_halt, - // fifo_status ... report bytes in fifo - // fifo_flush ... flush fifo + /* fifo_status ... report bytes in fifo */ + /* fifo_flush ... flush fifo */ }; /*-------------------------------------------------------------------------*/ @@ -1379,7 +1381,7 @@ static void udc_quiesce(struct omap_udc *udc) udc->gadget.speed = USB_SPEED_UNKNOWN; nuke(&udc->ep[0], -ESHUTDOWN); - list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) nuke(ep, -ESHUTDOWN); } @@ -1495,7 +1497,8 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) /* read next OUT packet of request, maybe * reactiviting the fifo; stall on errors. */ - if (!req || (stat = read_fifo(ep0, req)) < 0) { + stat = read_fifo(ep0, req); + if (!req || stat < 0) { omap_writew(UDC_STALL_CMD, UDC_SYSCON2); udc->ep0_pending = 0; stat = 0; @@ -1628,7 +1631,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) /* this has rude side-effects (aborts) and * can't really work if DMA-IN is active */ - DBG("%s host set_halt, NYET \n", ep->name); + DBG("%s host set_halt, NYET\n", ep->name); goto do_stall; } use_ep(ep, 0); @@ -1719,7 +1722,7 @@ delegate: */ udc->ep0_setup = 1; spin_unlock(&udc->lock); - status = udc->driver->setup (&udc->gadget, &u.r); + status = udc->driver->setup(&udc->gadget, &u.r); spin_lock(&udc->lock); udc->ep0_setup = 0; } @@ -1764,7 +1767,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) VDBG("connect\n"); if (!udc->transceiver) pullup_enable(udc); - // if (driver->connect) call it + /* if (driver->connect) call it */ } else if (udc->gadget.speed != USB_SPEED_UNKNOWN) { udc->gadget.speed = USB_SPEED_UNKNOWN; if (!udc->transceiver) @@ -1796,7 +1799,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) } if (change & UDC_SUS) { if (udc->gadget.speed != USB_SPEED_UNKNOWN) { - // FIXME tell isp1301 to suspend/resume (?) + /* FIXME tell isp1301 to suspend/resume (?) */ if (devstat & UDC_SUS) { VDBG("suspend\n"); update_otg(udc); @@ -1999,7 +2002,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) spin_lock_irqsave(&udc->lock, flags); /* handle all non-DMA ISO transfers */ - list_for_each_entry (ep, &udc->iso, iso) { + list_for_each_entry(ep, &udc->iso, iso) { u16 stat; struct omap_req *req; @@ -2058,11 +2061,11 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) static inline int machine_without_vbus_sense(void) { - return (machine_is_omap_innovator() + return machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_sx1() - || cpu_is_omap7xx() /* No known omap7xx boards with vbus sense */ - ); + /* No known omap7xx boards with vbus sense */ + || cpu_is_omap7xx(); } static int omap_udc_start(struct usb_gadget_driver *driver, @@ -2076,7 +2079,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, if (!udc) return -ENODEV; if (!driver - // FIXME if otg, check: driver->is_otg + /* FIXME if otg, check: driver->is_otg */ || driver->max_speed < USB_SPEED_FULL || !bind || !driver->setup) return -EINVAL; @@ -2088,7 +2091,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, } /* reset state */ - list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { ep->irqs = 0; if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) continue; @@ -2126,7 +2129,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, if (status < 0) { ERR("can't bind to transceiver\n"); if (driver->unbind) { - driver->unbind (&udc->gadget); + driver->unbind(&udc->gadget); udc->gadget.dev.driver = NULL; udc->driver = NULL; } @@ -2134,9 +2137,9 @@ static int omap_udc_start(struct usb_gadget_driver *driver, } } else { if (can_pullup(udc)) - pullup_enable (udc); + pullup_enable(udc); else - pullup_disable (udc); + pullup_disable(udc); } /* boards that don't have VBUS sensing can't autogate 48MHz; @@ -2195,7 +2198,7 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) static const char proc_filename[] = "driver/udc"; #define FOURBITS "%s%s%s%s" -#define EIGHTBITS FOURBITS FOURBITS +#define EIGHTBITS "%s%s%s%s%s%s%s%s" static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) { @@ -2217,12 +2220,21 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", ep->name, buf, ep->double_buf ? "dbuf " : "", - ({char *s; switch(ep->ackwait){ - case 0: s = ""; break; - case 1: s = "(ackw) "; break; - case 2: s = "(ackw2) "; break; - default: s = "(?) "; break; - } s;}), + ({ char *s; + switch (ep->ackwait) { + case 0: + s = ""; + break; + case 1: + s = "(ackw) "; + break; + case 2: + s = "(ackw2) "; + break; + default: + s = "(?) "; + break; + } s; }), ep->irqs, stat_flg, (stat_flg & UDC_NO_RXPACKET) ? "no_rxpacket " : "", (stat_flg & UDC_MISS_IN) ? "miss_in " : "", @@ -2238,10 +2250,10 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) (stat_flg & UDC_NON_ISO_FIFO_EMPTY) ? "fifo_empty " : "", (stat_flg & UDC_NON_ISO_FIFO_FULL) ? "fifo_full " : ""); - if (list_empty (&ep->queue)) + if (list_empty(&ep->queue)) seq_printf(s, "\t(queue empty)\n"); else - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { unsigned length = req->req.actual; if (use_dma && buf[0]) { @@ -2259,11 +2271,16 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) static char *trx_mode(unsigned m, int enabled) { switch (m) { - case 0: return enabled ? "*6wire" : "unused"; - case 1: return "4wire"; - case 2: return "3wire"; - case 3: return "6wire"; - default: return "unknown"; + case 0: + return enabled ? "*6wire" : "unused"; + case 1: + return "4wire"; + case 2: + return "3wire"; + case 3: + return "6wire"; + default: + return "unknown"; } } @@ -2295,7 +2312,7 @@ static int proc_otg_show(struct seq_file *s) " b_ase_brst=%d hmc=%d\n", tmp, (tmp & OTG_EN) ? " otg_en" : "", (tmp & USBX_SYNCHRO) ? " synchro" : "", - // much more SRP stuff + /* much more SRP stuff */ (tmp & SRP_DATA) ? " srp_data" : "", (tmp & SRP_VBUS) ? " srp_vbus" : "", (tmp & OTG_PADEN) ? " otg_paden" : "", @@ -2383,7 +2400,7 @@ static int proc_udc_show(struct seq_file *s, void *_) (tmp & UDC_SELF_PWR) ? " self_pwr" : "", (tmp & UDC_SOFF_DIS) ? " soff_dis" : "", (tmp & UDC_PULLUP_EN) ? " PULLUP" : ""); - // syscon2 is write-only + /* syscon2 is write-only */ /* UDC controller registers */ if (!(tmp & UDC_PULLUP_EN)) { @@ -2467,7 +2484,7 @@ static int proc_udc_show(struct seq_file *s, void *_) if (tmp & UDC_ATT) { proc_ep_show(s, &udc->ep[0]); if (tmp & UDC_ADD) { - list_for_each_entry (ep, &udc->gadget.ep_list, + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { if (ep->ep.desc) proc_ep_show(s, ep); @@ -2536,14 +2553,29 @@ omap_ep_setup(char *name, u8 addr, u8 type, /* chip setup ... bit values are same for IN, OUT */ if (type == USB_ENDPOINT_XFER_ISOC) { switch (maxp) { - case 8: epn_rxtx = 0 << 12; break; - case 16: epn_rxtx = 1 << 12; break; - case 32: epn_rxtx = 2 << 12; break; - case 64: epn_rxtx = 3 << 12; break; - case 128: epn_rxtx = 4 << 12; break; - case 256: epn_rxtx = 5 << 12; break; - case 512: epn_rxtx = 6 << 12; break; - default: BUG(); + case 8: + epn_rxtx = 0 << 12; + break; + case 16: + epn_rxtx = 1 << 12; + break; + case 32: + epn_rxtx = 2 << 12; + break; + case 64: + epn_rxtx = 3 << 12; + break; + case 128: + epn_rxtx = 4 << 12; + break; + case 256: + epn_rxtx = 5 << 12; + break; + case 512: + epn_rxtx = 6 << 12; + break; + default: + BUG(); } epn_rxtx |= UDC_EPN_RX_ISO; dbuf = 1; @@ -2556,11 +2588,20 @@ omap_ep_setup(char *name, u8 addr, u8 type, dbuf = 0; switch (maxp) { - case 8: epn_rxtx = 0 << 12; break; - case 16: epn_rxtx = 1 << 12; break; - case 32: epn_rxtx = 2 << 12; break; - case 64: epn_rxtx = 3 << 12; break; - default: BUG(); + case 8: + epn_rxtx = 0 << 12; + break; + case 16: + epn_rxtx = 1 << 12; + break; + case 32: + epn_rxtx = 2 << 12; + break; + case 64: + epn_rxtx = 3 << 12; + break; + default: + BUG(); } if (dbuf && addr) epn_rxtx |= UDC_EPN_RX_DB; @@ -2600,7 +2641,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, ep->ep.name = ep->name; ep->ep.ops = &omap_ep_ops; ep->ep.maxpacket = ep->maxpacket = maxp; - list_add_tail (&ep->ep.ep_list, &udc->gadget.ep_list); + list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); return buf; } @@ -2608,7 +2649,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, static void omap_udc_release(struct device *dev) { complete(udc->done); - kfree (udc); + kfree(udc); udc = NULL; } @@ -2626,13 +2667,13 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) omap_writew(0, UDC_TXDMA_CFG); /* UDC_PULLUP_EN gates the chip clock */ - // OTG_SYSCON_1 |= DEV_IDLE_EN; + /* OTG_SYSCON_1 |= DEV_IDLE_EN; */ udc = kzalloc(sizeof(*udc), GFP_KERNEL); if (!udc) return -ENOMEM; - spin_lock_init (&udc->lock); + spin_lock_init(&udc->lock); udc->gadget.ops = &omap_gadget_ops; udc->gadget.ep0 = &udc->ep[0].ep; @@ -2662,13 +2703,13 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) omap_writew(0, UDC_EP_TX(tmp)); } -#define OMAP_BULK_EP(name,addr) \ +#define OMAP_BULK_EP(name, addr) \ buf = omap_ep_setup(name "-bulk", addr, \ USB_ENDPOINT_XFER_BULK, buf, 64, 1); -#define OMAP_INT_EP(name,addr, maxp) \ +#define OMAP_INT_EP(name, addr, maxp) \ buf = omap_ep_setup(name "-int", addr, \ USB_ENDPOINT_XFER_INT, buf, maxp, 0); -#define OMAP_ISO_EP(name,addr, maxp) \ +#define OMAP_ISO_EP(name, addr, maxp) \ buf = omap_ep_setup(name "-iso", addr, \ USB_ENDPOINT_XFER_ISOC, buf, maxp, 1); @@ -2869,11 +2910,11 @@ bad_on_1710: /* a "gadget" abstracts/virtualizes the controller */ status = omap_udc_setup(pdev, xceiv); - if (status) { + if (status) goto cleanup0; - } + xceiv = NULL; - // "udc" is now valid + /* "udc" is now valid */ pullup_disable(udc); #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) udc->gadget.is_otg = (config->otg != 0); @@ -2887,7 +2928,7 @@ bad_on_1710: /* USB general purpose IRQ: ep0, state changes, dma, etc */ status = request_irq(pdev->resource[1].start, omap_udc_irq, - IRQF_SAMPLE_RANDOM, driver_name, udc); + 0, driver_name, udc); if (status != 0) { ERR("can't get irq %d, err %d\n", (int) pdev->resource[1].start, status); @@ -2896,7 +2937,7 @@ bad_on_1710: /* USB "non-iso" IRQ (PIO for all but ep0) */ status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, - IRQF_SAMPLE_RANDOM, "omap_udc pio", udc); + 0, "omap_udc pio", udc); if (status != 0) { ERR("can't get irq %d, err %d\n", (int) pdev->resource[2].start, status); @@ -2939,7 +2980,7 @@ cleanup2: free_irq(pdev->resource[1].start, udc); cleanup1: - kfree (udc); + kfree(udc); udc = NULL; cleanup0: -- GitLab From 5b6d84b78930a4fa3f8380dc0ec4ac427d620201 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 May 2012 14:27:52 +0300 Subject: [PATCH 0141/6849] usb: gadget: omap_udc: remove useless print that print isn't needed at all. Remove it and move the use_dma reinitialization to probe() function. Note that ideally we would drop all cpu_is_* and machine_is_* checks from this driver instead. Later patches will come to get rid of those. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index aa2d174a2521..5e7b8912ef31 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2800,6 +2800,9 @@ static int __init omap_udc_probe(struct platform_device *pdev) struct clk *dc_clk = NULL; struct clk *hhc_clk = NULL; + if (cpu_is_omap7xx()) + use_dma = 0; + /* NOTE: "knows" the order of the resources! */ if (!request_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1, @@ -3096,16 +3099,6 @@ static struct platform_driver udc_driver = { static int __init udc_init(void) { - /* Disable DMA for omap7xx -- it doesn't work right. */ - if (cpu_is_omap7xx()) - use_dma = 0; - - INFO("%s, version: " DRIVER_VERSION -#ifdef USE_ISO - " (iso)" -#endif - "%s\n", driver_desc, - use_dma ? " (dma)" : ""); return platform_driver_probe(&udc_driver, omap_udc_probe); } module_init(udc_init); -- GitLab From dc1737cdd75b692dbdec0e0e22439a0ce1089488 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 May 2012 14:33:30 +0300 Subject: [PATCH 0142/6849] usb: gadget: omap_udc: let it work as a module this also helps removing a few lines of boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 5e7b8912ef31..814aafbed000 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2535,7 +2535,7 @@ static inline void remove_proc_file(void) {} * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that * capability yet though. */ -static unsigned __init +static unsigned __devinit omap_ep_setup(char *name, u8 addr, u8 type, unsigned buf, unsigned maxp, int dbuf) { @@ -2653,7 +2653,7 @@ static void omap_udc_release(struct device *dev) udc = NULL; } -static int __init +static int __devinit omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) { unsigned tmp, buf; @@ -2790,7 +2790,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) return 0; } -static int __init omap_udc_probe(struct platform_device *pdev) +static int __devinit omap_udc_probe(struct platform_device *pdev) { int status = -ENODEV; int hmc; @@ -3003,7 +3003,7 @@ cleanup0: return status; } -static int __exit omap_udc_remove(struct platform_device *pdev) +static int __devexit omap_udc_remove(struct platform_device *pdev) { DECLARE_COMPLETION_ONSTACK(done); @@ -3088,7 +3088,8 @@ static int omap_udc_resume(struct platform_device *dev) /*-------------------------------------------------------------------------*/ static struct platform_driver udc_driver = { - .remove = __exit_p(omap_udc_remove), + .probe = omap_udc_probe, + .remove = __devexit_p(omap_udc_remove), .suspend = omap_udc_suspend, .resume = omap_udc_resume, .driver = { @@ -3097,17 +3098,7 @@ static struct platform_driver udc_driver = { }, }; -static int __init udc_init(void) -{ - return platform_driver_probe(&udc_driver, omap_udc_probe); -} -module_init(udc_init); - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); +module_platform_driver(udc_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -- GitLab From 70617db7ad7395498e6bc54c634199bf895426c6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 May 2012 14:36:42 +0300 Subject: [PATCH 0143/6849] usb: gadget: omap_udc: remove possiblity of NULL pointer de-reference when allocating a request, it's better programming practice to make sure we return NULL if allocation failed. This will ensure that, if struct usb_request isn't the first member on our structure, we don't cheat the gadget driver into thinking allocating worked because pointer isn't 0. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 814aafbed000..f13bcdc75676 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -268,10 +268,12 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) struct omap_req *req; req = kzalloc(sizeof(*req), gfp_flags); - if (req) { - req->req.dma = DMA_ADDR_INVALID; - INIT_LIST_HEAD(&req->queue); - } + if (!req) + return NULL; + + req->req.dma = DMA_ADDR_INVALID; + INIT_LIST_HEAD(&req->queue); + return &req->req; } -- GitLab From 23673d7d26d81bd17cde3ed74c57b3f39585325f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 May 2012 14:38:32 +0300 Subject: [PATCH 0144/6849] usb: gadget: omap_udc: kfree(NULL) is safe we don't need to check for _req because kfree(NULL) is safe. Also, if someone actually passes a NULL pointer to be freed by usb_ep_free_request(), he deserves any issue he faces. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index f13bcdc75676..50e8490867ed 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -282,8 +282,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) { struct omap_req *req = container_of(_req, struct omap_req, req); - if (_req) - kfree(req); + kfree(req); } /*-------------------------------------------------------------------------*/ -- GitLab From dd8e93814a357d8f032a93b6d17216436c762e9f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 May 2012 14:42:56 +0300 Subject: [PATCH 0145/6849] usb: gadget: omap_udc: use generic map/unmap routines This patch makes use of the generic map/unmap routines on the omap_udc driver. Removes some useless and duplicated code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 46 ++++++----------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 50e8490867ed..b6cc8b19f39f 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -59,8 +59,6 @@ #define DRIVER_DESC "OMAP UDC driver" #define DRIVER_VERSION "4 October 2004" -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - /* * The OMAP UDC needs _very_ early endpoint setup: before enabling the * D+ pullup to allow enumeration. That's too early for the gadget @@ -271,7 +269,6 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) if (!req) return NULL; - req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); return &req->req; @@ -290,6 +287,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) static void done(struct omap_ep *ep, struct omap_req *req, int status) { + struct omap_udc *udc = ep->udc; unsigned stopped = ep->stopped; list_del_init(&req->queue); @@ -299,22 +297,9 @@ done(struct omap_ep *ep, struct omap_req *req, int status) else status = req->req.status; - if (use_dma && ep->has_dma) { - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - } + if (use_dma && ep->has_dma) + usb_gadget_unmap_request(&udc->gadget, &req->req, + (ep->bEndpointAddress & USB_DIR_IN)); #ifndef USB_TRACE if (status && status != -ESHUTDOWN) @@ -915,26 +900,9 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) return -ESHUTDOWN; - if (use_dma && ep->has_dma) { - if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single( - ep->udc->gadget.dev.parent, - req->req.buf, - req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 1; - } else { - dma_sync_single_for_device( - ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - (ep->bEndpointAddress & USB_DIR_IN) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 0; - } - } + if (use_dma && ep->has_dma) + usb_gadget_map_request(&udc->gadget, &req->req, + (ep->bEndpointAddress & USB_DIR_IN)); VDBG("%s queue req %p, len %d buf %p\n", ep->ep.name, _req, _req->length, _req->buf); -- GitLab From eb774a09017e39a3255e144465d150877b6e6e2f Mon Sep 17 00:00:00 2001 From: Rafal Prylowski Date: Thu, 12 Apr 2012 14:14:12 +0200 Subject: [PATCH 0146/6849] ep93xx: IDE driver platform support code Add IDE driver platform support code for ep93xx. Signed-off-by: Rafal Prylowski Acked-by: H Hartley Sweeten Signed-off-by: Ryan Mallon --- arch/arm/mach-ep93xx/core.c | 96 ++++++++++++++++++++ arch/arm/mach-ep93xx/include/mach/platform.h | 3 + arch/arm/mach-ep93xx/soc.h | 1 + 3 files changed, 100 insertions(+) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 4dd07a0e3604..4afe52aaaff3 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -797,6 +797,102 @@ static struct platform_device ep93xx_wdt_device = { .resource = ep93xx_wdt_resources, }; +/************************************************************************* + * EP93xx IDE + *************************************************************************/ +static struct resource ep93xx_ide_resources[] = { + DEFINE_RES_MEM(EP93XX_IDE_PHYS_BASE, 0x38), + DEFINE_RES_IRQ(IRQ_EP93XX_EXT3), +}; + +static struct platform_device ep93xx_ide_device = { + .name = "ep93xx-ide", + .id = -1, + .dev = { + .dma_mask = &ep93xx_ide_device.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(ep93xx_ide_resources), + .resource = ep93xx_ide_resources, +}; + +void __init ep93xx_register_ide(void) +{ + platform_device_register(&ep93xx_ide_device); +} + +int ep93xx_ide_acquire_gpio(struct platform_device *pdev) +{ + int err; + int i; + + err = gpio_request(EP93XX_GPIO_LINE_EGPIO2, dev_name(&pdev->dev)); + if (err) + return err; + err = gpio_request(EP93XX_GPIO_LINE_EGPIO15, dev_name(&pdev->dev)); + if (err) + goto fail_egpio15; + for (i = 2; i < 8; i++) { + err = gpio_request(EP93XX_GPIO_LINE_E(i), dev_name(&pdev->dev)); + if (err) + goto fail_gpio_e; + } + for (i = 4; i < 8; i++) { + err = gpio_request(EP93XX_GPIO_LINE_G(i), dev_name(&pdev->dev)); + if (err) + goto fail_gpio_g; + } + for (i = 0; i < 8; i++) { + err = gpio_request(EP93XX_GPIO_LINE_H(i), dev_name(&pdev->dev)); + if (err) + goto fail_gpio_h; + } + + /* GPIO ports E[7:2], G[7:4] and H used by IDE */ + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_EONIDE | + EP93XX_SYSCON_DEVCFG_GONIDE | + EP93XX_SYSCON_DEVCFG_HONIDE); + return 0; + +fail_gpio_h: + for (--i; i >= 0; --i) + gpio_free(EP93XX_GPIO_LINE_H(i)); + i = 8; +fail_gpio_g: + for (--i; i >= 4; --i) + gpio_free(EP93XX_GPIO_LINE_G(i)); + i = 8; +fail_gpio_e: + for (--i; i >= 2; --i) + gpio_free(EP93XX_GPIO_LINE_E(i)); + gpio_free(EP93XX_GPIO_LINE_EGPIO15); +fail_egpio15: + gpio_free(EP93XX_GPIO_LINE_EGPIO2); + return err; +} +EXPORT_SYMBOL(ep93xx_ide_acquire_gpio); + +void ep93xx_ide_release_gpio(struct platform_device *pdev) +{ + int i; + + for (i = 2; i < 8; i++) + gpio_free(EP93XX_GPIO_LINE_E(i)); + for (i = 4; i < 8; i++) + gpio_free(EP93XX_GPIO_LINE_G(i)); + for (i = 0; i < 8; i++) + gpio_free(EP93XX_GPIO_LINE_H(i)); + gpio_free(EP93XX_GPIO_LINE_EGPIO15); + gpio_free(EP93XX_GPIO_LINE_EGPIO2); + + + /* GPIO ports E[7:2], G[7:4] and H used by GPIO */ + ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_EONIDE | + EP93XX_SYSCON_DEVCFG_GONIDE | + EP93XX_SYSCON_DEVCFG_HONIDE); +} +EXPORT_SYMBOL(ep93xx_ide_release_gpio); + void __init ep93xx_init_devices(void) { /* Disallow access to MaverickCrunch initially */ diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 1ecb040d98bf..33a5122c6dc8 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -48,6 +48,9 @@ void ep93xx_register_i2s(void); int ep93xx_i2s_acquire(void); void ep93xx_i2s_release(void); void ep93xx_register_ac97(void); +void ep93xx_register_ide(void); +int ep93xx_ide_acquire_gpio(struct platform_device *pdev); +void ep93xx_ide_release_gpio(struct platform_device *pdev); void ep93xx_init_devices(void); extern struct sys_timer ep93xx_timer; diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h index 979fba722926..7bf7ff8beae7 100644 --- a/arch/arm/mach-ep93xx/soc.h +++ b/arch/arm/mach-ep93xx/soc.h @@ -69,6 +69,7 @@ #define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000) +#define EP93XX_IDE_PHYS_BASE EP93XX_AHB_PHYS(0x000a0000) #define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000) #define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000) -- GitLab From 762be29733d5b02b4359691f64c0cc968cd23c93 Mon Sep 17 00:00:00 2001 From: Rafal Prylowski Date: Thu, 12 Apr 2012 14:15:15 +0200 Subject: [PATCH 0147/6849] ep93xx: Add IDE support to edb93xx boards Add IDE support to edb93xx boards. Signed-off-by: Rafal Prylowski Acked-by: H Hartley Sweeten Signed-off-by: Ryan Mallon --- arch/arm/mach-ep93xx/edb93xx.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index d74c5cddb98b..9005ea698f1e 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -233,6 +233,29 @@ static void __init edb93xx_register_fb(void) } +/************************************************************************* + * EDB93xx IDE + *************************************************************************/ +static int __init edb93xx_has_ide(void) +{ + /* + * Although EDB9312 and EDB9315 do have IDE capability, they have + * INTRQ line wired as pull-up, which makes using IDE interface + * problematic. + */ + return machine_is_edb9312() || machine_is_edb9315() || + machine_is_edb9315a(); +} + +static void __init edb93xx_register_ide(void) +{ + if (!edb93xx_has_ide()) + return; + + ep93xx_register_ide(); +} + + static void __init edb93xx_init_machine(void) { ep93xx_init_devices(); @@ -243,6 +266,7 @@ static void __init edb93xx_init_machine(void) edb93xx_register_i2s(); edb93xx_register_pwm(); edb93xx_register_fb(); + edb93xx_register_ide(); } -- GitLab From bedfb7adc7f7e2f344b21584905b2357147ba27e Mon Sep 17 00:00:00 2001 From: Oleg Matcovschi Date: Tue, 15 May 2012 14:35:08 -0700 Subject: [PATCH 0148/6849] ARM: OMAP: dma: Clear status registers on enable/disable irq Use omap_disable_channel_irq() function instead of directly accessing CICR register in various functions. The omap_disable_chanel_irq() function now clears pending interrupts and disables interrupt on channel. Functions omap2_enable_irq_lch()/omap2_disable_irq_lch() clear interrupt status register. Signed-off-by: Oleg Matcovschi Tested-by: Jarkko Nikula [tony@atomide.com: updated comments to clarify CICR access] Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 59 +++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index cb16ade437cb..7fe626761e53 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -573,22 +573,25 @@ EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); static inline void omap_enable_channel_irq(int lch) { - u32 status; - /* Clear CSR */ if (cpu_class_is_omap1()) - status = p->dma_read(CSR, lch); - else if (cpu_class_is_omap2()) + p->dma_read(CSR, lch); + else p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); /* Enable some nice interrupts. */ p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch); } -static void omap_disable_channel_irq(int lch) +static inline void omap_disable_channel_irq(int lch) { - if (cpu_class_is_omap2()) - p->dma_write(0, CICR, lch); + /* disable channel interrupts */ + p->dma_write(0, CICR, lch); + /* Clear CSR */ + if (cpu_class_is_omap1()) + p->dma_read(CSR, lch); + else + p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); } void omap_enable_dma_irq(int lch, u16 bits) @@ -632,14 +635,14 @@ static inline void disable_lnk(int lch) l = p->dma_read(CLNK_CTRL, lch); /* Disable interrupts */ + omap_disable_channel_irq(lch); + if (cpu_class_is_omap1()) { - p->dma_write(0, CICR, lch); /* Set the STOP_LNK bit */ l |= 1 << 14; } if (cpu_class_is_omap2()) { - omap_disable_channel_irq(lch); /* Clear the ENABLE_LNK bit */ l &= ~(1 << 15); } @@ -657,6 +660,9 @@ static inline void omap2_enable_irq_lch(int lch) return; spin_lock_irqsave(&dma_chan_lock, flags); + /* clear IRQ STATUS */ + p->dma_write(1 << lch, IRQSTATUS_L0, lch); + /* Enable interrupt */ val = p->dma_read(IRQENABLE_L0, lch); val |= 1 << lch; p->dma_write(val, IRQENABLE_L0, lch); @@ -672,9 +678,12 @@ static inline void omap2_disable_irq_lch(int lch) return; spin_lock_irqsave(&dma_chan_lock, flags); + /* Disable interrupt */ val = p->dma_read(IRQENABLE_L0, lch); val &= ~(1 << lch); p->dma_write(val, IRQENABLE_L0, lch); + /* clear IRQ STATUS */ + p->dma_write(1 << lch, IRQSTATUS_L0, lch); spin_unlock_irqrestore(&dma_chan_lock, flags); } @@ -745,11 +754,8 @@ int omap_request_dma(int dev_id, const char *dev_name, } if (cpu_class_is_omap2()) { - omap2_enable_irq_lch(free_ch); omap_enable_channel_irq(free_ch); - /* Clear the CSR register and IRQ status register */ - p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, free_ch); - p->dma_write(1 << free_ch, IRQSTATUS_L0, 0); + omap2_enable_irq_lch(free_ch); } *dma_ch_out = free_ch; @@ -768,27 +774,19 @@ void omap_free_dma(int lch) return; } - if (cpu_class_is_omap1()) { - /* Disable all DMA interrupts for the channel. */ - p->dma_write(0, CICR, lch); - /* Make sure the DMA transfer is stopped. */ - p->dma_write(0, CCR, lch); - } - - if (cpu_class_is_omap2()) { + /* Disable interrupt for logical channel */ + if (cpu_class_is_omap2()) omap2_disable_irq_lch(lch); - /* Clear the CSR register and IRQ status register */ - p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch); - p->dma_write(1 << lch, IRQSTATUS_L0, lch); + /* Disable all DMA interrupts for the channel. */ + omap_disable_channel_irq(lch); - /* Disable all DMA interrupts for the channel. */ - p->dma_write(0, CICR, lch); + /* Make sure the DMA transfer is stopped. */ + p->dma_write(0, CCR, lch); - /* Make sure the DMA transfer is stopped. */ - p->dma_write(0, CCR, lch); + /* Clear registers */ + if (cpu_class_is_omap2()) omap_clear_dma(lch); - } spin_lock_irqsave(&dma_chan_lock, flags); dma_chan[lch].dev_id = -1; @@ -943,8 +941,7 @@ void omap_stop_dma(int lch) u32 l; /* Disable all interrupts on the channel */ - if (cpu_class_is_omap1()) - p->dma_write(0, CICR, lch); + omap_disable_channel_irq(lch); l = p->dma_read(CCR, lch); if (IS_DMA_ERRATA(DMA_ERRATA_i541) && -- GitLab From a22ab1c4bac78d5789dc51c1730463f845b3262f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 4 Jun 2012 00:56:15 -0700 Subject: [PATCH 0149/6849] ARM: OMAP3: There is no FS USB controller on omap3 We should not select ARCH_OMAP_OTG as the hardware does not have the legacy FS (Full Speed) USB interface. Cc: linux-usb@vger.kernel.org Cc: Kyungmin Park Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 4cf5142f22cc..0e4dd6746875 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -76,7 +76,6 @@ config SOC_OMAP3430 bool "OMAP3430 support" depends on ARCH_OMAP3 default y - select ARCH_OMAP_OTG config SOC_TI81XX bool "TI81XX support" -- GitLab From fe57ab06052234ad954617e7e1f212154d37859e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 4 Jun 2012 00:56:15 -0700 Subject: [PATCH 0150/6849] ARM: OMAP2: Remove legacy USB FS support The FS (Full Speed) USB controller is available on 2420 and 2430, but not being used. Out of the 2420 based boards only Nokia N8X0 are seeing active development and they have external HS (High Speed) TUSB controller. On omap 2430sdp there is MUSB HS controller, so there's no need to use the legacy USB FS controller. That leaves only H4 and Apollon boards that could use the FS USB controller. As both H4 and Apollon boards are old proprietary development boards, it's unlikely that we have any active developers working on those boards using the USB. So remove the FS USB support for omap2 machines. Patches are welcome if somebody wants to instead fix it all up to the current standards. Cc: linux-usb@vger.kernel.org Cc: Kyungmin Park Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 2 - arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/board-2430sdp.c | 11 - arch/arm/mach-omap2/board-apollon.c | 18 -- arch/arm/mach-omap2/board-h4.c | 13 - arch/arm/mach-omap2/usb-fs.c | 359 ---------------------------- 6 files changed, 406 deletions(-) delete mode 100644 arch/arm/mach-omap2/usb-fs.c diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 0e4dd6746875..042f157a8f94 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -64,13 +64,11 @@ config SOC_OMAP2420 depends on ARCH_OMAP2 default y select OMAP_DM_TIMER - select ARCH_OMAP_OTG config SOC_OMAP2430 bool "OMAP2430 support" depends on ARCH_OMAP2 default y - select ARCH_OMAP_OTG config SOC_OMAP3430 bool "OMAP3430 support" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fa742f3c2629..664224fb7405 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -244,9 +244,6 @@ obj-y += $(omap-flash-y) $(omap-flash-m) omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y) - -usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o -obj-y += $(usbfs-m) $(usbfs-y) obj-y += usb-musb.o obj-y += omap_phy_internal.o diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 99ca6bad5c30..6523aeabf9f2 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -254,16 +254,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = { {} /* Terminator */ }; -static struct omap_usb_config sdp2430_usb_config __initdata = { - .otg = 1, -#ifdef CONFIG_USB_GADGET_OMAP - .hmc_mode = 0x0, -#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - .hmc_mode = 0x1, -#endif - .pins[0] = 3, -}; - #ifdef CONFIG_OMAP_MUX static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, @@ -280,7 +270,6 @@ static void __init omap_2430sdp_init(void) omap_serial_init(); omap_sdrc_init(NULL, NULL); omap_hsmmc_init(mmc); - omap2_usbfs_init(&sdp2430_usb_config); omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP); usb_musb_init(NULL); diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 502c31e123be..519bcd3079e8 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -35,7 +35,6 @@ #include #include -#include #include #include "common.h" #include @@ -253,13 +252,6 @@ out: clk_put(gpmc_fck); } -static struct omap_usb_config apollon_usb_config __initdata = { - .register_dev = 1, - .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ - - .pins[0] = 6, -}; - static struct panel_generic_dpi_data apollon_panel_data = { .name = "apollon", }; @@ -297,15 +289,6 @@ static void __init apollon_led_init(void) gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds)); } -static void __init apollon_usb_init(void) -{ - /* USB device */ - /* DEVICE_SUSPEND */ - omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0); - gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend"); - omap2_usbfs_init(&apollon_usb_config); -} - #ifdef CONFIG_OMAP_MUX static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, @@ -321,7 +304,6 @@ static void __init omap_apollon_init(void) apollon_init_smc91x(); apollon_led_init(); apollon_flash_init(); - apollon_usb_init(); /* REVISIT: where's the correct place */ omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP); diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 876becf8205a..ace20482e3e1 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -32,7 +32,6 @@ #include #include -#include #include #include "common.h" #include @@ -329,17 +328,6 @@ static void __init h4_init_flash(void) h4_flash_resource.end = base + SZ_64M - 1; } -static struct omap_usb_config h4_usb_config __initdata = { - /* S1.10 OFF -- usb "download port" - * usb0 switched to Mini-B port and isp1105 transceiver; - * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging - */ - .register_dev = 1, - .pins[0] = 3, -/* .hmc_mode = 0x14,*/ /* 0:dev 1:host 2:disable */ - .hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */ -}; - static struct at24_platform_data m24c01 = { .byte_len = SZ_1K / 8, .page_size = 16, @@ -381,7 +369,6 @@ static void __init omap_h4_init(void) ARRAY_SIZE(h4_i2c_board_info)); platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); - omap2_usbfs_init(&h4_usb_config); omap_serial_init(); omap_sdrc_init(NULL, NULL); h4_init_flash(); diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c deleted file mode 100644 index 1481078763b8..000000000000 --- a/arch/arm/mach-omap2/usb-fs.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx - * - * Copyright (C) 2004 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "control.h" -#include "mux.h" - -#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN -#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO -#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO -#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN -#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG - -#if defined(CONFIG_ARCH_OMAP2) - -#ifdef CONFIG_USB_GADGET_OMAP - -static struct resource udc_resources[] = { - /* order is significant! */ - { /* registers */ - .start = UDC_BASE, - .end = UDC_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { /* general IRQ */ - .start = INT_USB_IRQ_GEN, - .flags = IORESOURCE_IRQ, - }, { /* PIO IRQ */ - .start = INT_USB_IRQ_NISO, - .flags = IORESOURCE_IRQ, - }, { /* SOF IRQ */ - .start = INT_USB_IRQ_ISO, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 udc_dmamask = ~(u32)0; - -static struct platform_device udc_device = { - .name = "omap_udc", - .id = -1, - .dev = { - .dma_mask = &udc_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(udc_resources), - .resource = udc_resources, -}; - -static inline void udc_device_init(struct omap_usb_config *pdata) -{ - pdata->udc_device = &udc_device; -} - -#else - -static inline void udc_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - -/* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = ~(u32)0; - -static struct resource ohci_resources[] = { - { - .start = OMAP_OHCI_BASE, - .end = OMAP_OHCI_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_USB_IRQ_HGEN, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device ohci_device = { - .name = "ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(ohci_resources), - .resource = ohci_resources, -}; - -static inline void ohci_device_init(struct omap_usb_config *pdata) -{ - pdata->ohci_device = &ohci_device; -} - -#else - -static inline void ohci_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) - -static struct resource otg_resources[] = { - /* order is significant! */ - { - .start = OTG_BASE, - .end = OTG_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { - .start = INT_USB_IRQ_OTG, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device otg_device = { - .name = "omap_otg", - .id = -1, - .num_resources = ARRAY_SIZE(otg_resources), - .resource = otg_resources, -}; - -static inline void otg_device_init(struct omap_usb_config *pdata) -{ - pdata->otg_device = &otg_device; -} - -#else - -static inline void otg_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -static void omap2_usb_devconf_clear(u8 port, u32 mask) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r &= ~USBTXWRMODEI(port, mask); - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb_devconf_set(u8 port, u32 mask) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r |= USBTXWRMODEI(port, mask); - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb2_disable_5pinbitll(void) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI); - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb2_enable_5pinunitll(void) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI; - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device) -{ - u32 syscon1 = 0; - - omap2_usb_devconf_clear(0, USB_BIDIR_TLL); - - if (nwires == 0) - return 0; - - if (is_device) - omap_mux_init_signal("usb0_puen", 0); - - omap_mux_init_signal("usb0_dat", 0); - omap_mux_init_signal("usb0_txen", 0); - omap_mux_init_signal("usb0_se0", 0); - if (nwires != 3) - omap_mux_init_signal("usb0_rcv", 0); - - switch (nwires) { - case 3: - syscon1 = 2; - omap2_usb_devconf_set(0, USB_BIDIR); - break; - case 4: - syscon1 = 1; - omap2_usb_devconf_set(0, USB_BIDIR); - break; - case 6: - syscon1 = 3; - omap_mux_init_signal("usb0_vp", 0); - omap_mux_init_signal("usb0_vm", 0); - omap2_usb_devconf_set(0, USB_UNIDIR); - break; - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 0, nwires); - } - - return syscon1 << 16; -} - -static u32 __init omap2_usb1_init(unsigned nwires) -{ - u32 syscon1 = 0; - - omap2_usb_devconf_clear(1, USB_BIDIR_TLL); - - if (nwires == 0) - return 0; - - /* NOTE: board-specific code must set up pin muxing for usb1, - * since each signal could come out on either of two balls. - */ - - switch (nwires) { - case 2: - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM - */ - syscon1 = 1; - omap2_usb_devconf_set(1, USB_BIDIR_TLL); - break; - case 3: - syscon1 = 2; - omap2_usb_devconf_set(1, USB_BIDIR); - break; - case 4: - syscon1 = 1; - omap2_usb_devconf_set(1, USB_BIDIR); - break; - case 6: - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 1, nwires); - } - - return syscon1 << 20; -} - -static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup) -{ - u32 syscon1 = 0; - - omap2_usb2_disable_5pinbitll(); - alt_pingroup = 0; - - /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ - if (alt_pingroup || nwires == 0) - return 0; - - omap_mux_init_signal("usb2_dat", 0); - omap_mux_init_signal("usb2_se0", 0); - if (nwires > 2) - omap_mux_init_signal("usb2_txen", 0); - if (nwires > 3) - omap_mux_init_signal("usb2_rcv", 0); - - switch (nwires) { - case 2: - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM - */ - syscon1 = 1; - omap2_usb_devconf_set(2, USB_BIDIR_TLL); - break; - case 3: - syscon1 = 2; - omap2_usb_devconf_set(2, USB_BIDIR); - break; - case 4: - syscon1 = 1; - omap2_usb_devconf_set(2, USB_BIDIR); - break; - case 5: - /* NOTE: board-specific code must mux this setting depending - * on TLL link using DP/DM. Something must also - * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} - * 2420: hdq_sio.usb2_tllse0 or vlynq_rx0.usb2_tllse0 - * 2430: hdq_sio.usb2_tllse0 or sdmmc2_dat0.usb2_tllse0 - */ - - syscon1 = 3; - omap2_usb2_enable_5pinunitll(); - break; - case 6: - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 2, nwires); - } - - return syscon1 << 24; -} - -void __init omap2_usbfs_init(struct omap_usb_config *pdata) -{ - struct clk *ick; - - if (!cpu_is_omap24xx()) - return; - - ick = clk_get(NULL, "usb_l4_ick"); - if (IS_ERR(ick)) - return; - - clk_enable(ick); - pdata->usb0_init = omap2_usb0_init; - pdata->usb1_init = omap2_usb1_init; - pdata->usb2_init = omap2_usb2_init; - udc_device_init(pdata); - ohci_device_init(pdata); - otg_device_init(pdata); - omap_otg_init(pdata); - clk_disable(ick); - clk_put(ick); -} - -#endif -- GitLab From b924b2047045844644e04b3c6e8308b2114afe7e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 4 Jun 2012 00:56:15 -0700 Subject: [PATCH 0151/6849] ARM: OMAP: Make FS USB omap1 only As the FS USB code is not being actively used for omap2+ there's no point keeping it around for omap2+. Let's make the FS USB platform init code omap1 only so we can remove the last user of omap_read/write for omap2+, and simplify things for further USB, DMA, and device tree related work. While at it, also group the mach includes for the related drivers. Cc: linux-usb@vger.kernel.org Cc: Kyungmin Park Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 2 +- arch/arm/mach-omap1/board-generic.c | 4 +- arch/arm/mach-omap1/board-h2.c | 2 +- arch/arm/mach-omap1/board-h3.c | 2 +- arch/arm/mach-omap1/board-htcherald.c | 2 +- arch/arm/mach-omap1/board-innovator.c | 2 +- arch/arm/mach-omap1/board-nokia770.c | 2 +- arch/arm/mach-omap1/board-osk.c | 2 +- arch/arm/mach-omap1/board-palmte.c | 2 +- arch/arm/mach-omap1/board-palmtt.c | 2 +- arch/arm/mach-omap1/board-palmz71.c | 2 +- arch/arm/mach-omap1/board-sx1.c | 2 +- arch/arm/mach-omap1/board-voiceblue.c | 3 +- arch/arm/mach-omap1/clock_data.c | 3 +- arch/arm/mach-omap1/include/mach/usb.h | 165 ++++++++++++++++++++ arch/arm/mach-omap1/usb.c | 116 +++++++++++++- arch/arm/plat-omap/Makefile | 2 +- arch/arm/plat-omap/include/plat/board.h | 38 ----- arch/arm/plat-omap/include/plat/usb.h | 196 +----------------------- arch/arm/plat-omap/usb.c | 145 ------------------ drivers/usb/gadget/Kconfig | 2 +- drivers/usb/gadget/omap_udc.c | 3 +- drivers/usb/host/Kconfig | 2 +- drivers/usb/host/ohci-omap.c | 7 +- drivers/usb/otg/isp1301_omap.c | 2 +- 25 files changed, 310 insertions(+), 400 deletions(-) create mode 100644 arch/arm/mach-omap1/include/mach/usb.h delete mode 100644 arch/arm/plat-omap/usb.c diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index f2f8a5847018..c53469802c03 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -37,12 +37,12 @@ #include #include #include -#include #include #include #include #include +#include #include "iomap.h" #include "common.h" diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index e75e2d55a2d7..6ec385e2b98e 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -23,8 +23,10 @@ #include #include -#include #include + +#include + #include "common.h" /* assume no Mini-AB port */ diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index a28e989a63f4..44a4ab195fbc 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -40,11 +40,11 @@ #include #include #include -#include #include #include #include +#include #include "common.h" #include "board-h2.h" diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 108a8640fc6f..86cb5a04a404 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -40,13 +40,13 @@ #include #include -#include #include #include #include #include #include +#include #include "common.h" #include "board-h3.h" diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index 118a9d4a4c54..b3f6e943e661 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -44,10 +44,10 @@ #include #include #include -#include #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 7970223a559d..f21c2966daad 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -35,11 +35,11 @@ #include #include #include -#include #include #include #include +#include #include "iomap.h" #include "common.h" diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 7212ae97f44a..4007a372481b 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index da8d872d3d1c..8784705edb60 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -45,11 +45,11 @@ #include #include -#include #include #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 949b62a73693..26bcb9defcdc 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index 7f1e1cf2bf46..4d099446dfa8 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 3c71c6bace2c..cc71a26723ef 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include @@ -45,6 +44,7 @@ #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 3b7b82b13684..8c665bd16ac2 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -37,13 +37,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index afd67f0ec495..3497769eb353 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -35,9 +35,10 @@ #include #include #include -#include +#include #include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index c6ce93f71d08..c007d80dfb62 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -25,10 +25,11 @@ #include #include #include +#include #include /* for omap_sram_reprogram_clock() */ -#include /* for OTG_BASE */ #include +#include /* for OTG_BASE */ #include "iomap.h" #include "clock.h" diff --git a/arch/arm/mach-omap1/include/mach/usb.h b/arch/arm/mach-omap1/include/mach/usb.h new file mode 100644 index 000000000000..753cd5ce6949 --- /dev/null +++ b/arch/arm/mach-omap1/include/mach/usb.h @@ -0,0 +1,165 @@ +/* + * FIXME correct answer depends on hmc_mode, + * as does (on omap1) any nonzero value for config->otg port number + */ +#ifdef CONFIG_USB_GADGET_OMAP +#define is_usb0_device(config) 1 +#else +#define is_usb0_device(config) 0 +#endif + +struct omap_usb_config { + /* Configure drivers according to the connectors on your board: + * - "A" connector (rectagular) + * ... for host/OHCI use, set "register_host". + * - "B" connector (squarish) or "Mini-B" + * ... for device/gadget use, set "register_dev". + * - "Mini-AB" connector (very similar to Mini-B) + * ... for OTG use as device OR host, initialize "otg" + */ + unsigned register_host:1; + unsigned register_dev:1; + u8 otg; /* port number, 1-based: usb1 == 2 */ + + u8 hmc_mode; + + /* implicitly true if otg: host supports remote wakeup? */ + u8 rwc; + + /* signaling pins used to talk to transceiver on usbN: + * 0 == usbN unused + * 2 == usb0-only, using internal transceiver + * 3 == 3 wire bidirectional + * 4 == 4 wire bidirectional + * 6 == 6 wire unidirectional (or TLL) + */ + u8 pins[3]; + + struct platform_device *udc_device; + struct platform_device *ohci_device; + struct platform_device *otg_device; + + u32 (*usb0_init)(unsigned nwires, unsigned is_device); + u32 (*usb1_init)(unsigned nwires); + u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup); + + int (*ocpi_enable)(void); +}; + +void omap_otg_init(struct omap_usb_config *config); + +#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) +void omap1_usb_init(struct omap_usb_config *pdata); +#else +static inline void omap1_usb_init(struct omap_usb_config *pdata) +{ +} +#endif + +#define OMAP1_OTG_BASE 0xfffb0400 +#define OMAP1_UDC_BASE 0xfffb4000 +#define OMAP1_OHCI_BASE 0xfffba000 + +#define OMAP2_OHCI_BASE 0x4805e000 +#define OMAP2_UDC_BASE 0x4805e200 +#define OMAP2_OTG_BASE 0x4805e300 +#define OTG_BASE OMAP1_OTG_BASE +#define UDC_BASE OMAP1_UDC_BASE +#define OMAP_OHCI_BASE OMAP1_OHCI_BASE + +/* + * OTG and transceiver registers, for OMAPs starting with ARM926 + */ +#define OTG_REV (OTG_BASE + 0x00) +#define OTG_SYSCON_1 (OTG_BASE + 0x04) +# define USB2_TRX_MODE(w) (((w)>>24)&0x07) +# define USB1_TRX_MODE(w) (((w)>>20)&0x07) +# define USB0_TRX_MODE(w) (((w)>>16)&0x07) +# define OTG_IDLE_EN (1 << 15) +# define HST_IDLE_EN (1 << 14) +# define DEV_IDLE_EN (1 << 13) +# define OTG_RESET_DONE (1 << 2) +# define OTG_SOFT_RESET (1 << 1) +#define OTG_SYSCON_2 (OTG_BASE + 0x08) +# define OTG_EN (1 << 31) +# define USBX_SYNCHRO (1 << 30) +# define OTG_MST16 (1 << 29) +# define SRP_GPDATA (1 << 28) +# define SRP_GPDVBUS (1 << 27) +# define SRP_GPUVBUS(w) (((w)>>24)&0x07) +# define A_WAIT_VRISE(w) (((w)>>20)&0x07) +# define B_ASE_BRST(w) (((w)>>16)&0x07) +# define SRP_DPW (1 << 14) +# define SRP_DATA (1 << 13) +# define SRP_VBUS (1 << 12) +# define OTG_PADEN (1 << 10) +# define HMC_PADEN (1 << 9) +# define UHOST_EN (1 << 8) +# define HMC_TLLSPEED (1 << 7) +# define HMC_TLLATTACH (1 << 6) +# define OTG_HMC(w) (((w)>>0)&0x3f) +#define OTG_CTRL (OTG_BASE + 0x0c) +# define OTG_USB2_EN (1 << 29) +# define OTG_USB2_DP (1 << 28) +# define OTG_USB2_DM (1 << 27) +# define OTG_USB1_EN (1 << 26) +# define OTG_USB1_DP (1 << 25) +# define OTG_USB1_DM (1 << 24) +# define OTG_USB0_EN (1 << 23) +# define OTG_USB0_DP (1 << 22) +# define OTG_USB0_DM (1 << 21) +# define OTG_ASESSVLD (1 << 20) +# define OTG_BSESSEND (1 << 19) +# define OTG_BSESSVLD (1 << 18) +# define OTG_VBUSVLD (1 << 17) +# define OTG_ID (1 << 16) +# define OTG_DRIVER_SEL (1 << 15) +# define OTG_A_SETB_HNPEN (1 << 12) +# define OTG_A_BUSREQ (1 << 11) +# define OTG_B_HNPEN (1 << 9) +# define OTG_B_BUSREQ (1 << 8) +# define OTG_BUSDROP (1 << 7) +# define OTG_PULLDOWN (1 << 5) +# define OTG_PULLUP (1 << 4) +# define OTG_DRV_VBUS (1 << 3) +# define OTG_PD_VBUS (1 << 2) +# define OTG_PU_VBUS (1 << 1) +# define OTG_PU_ID (1 << 0) +#define OTG_IRQ_EN (OTG_BASE + 0x10) /* 16-bit */ +# define DRIVER_SWITCH (1 << 15) +# define A_VBUS_ERR (1 << 13) +# define A_REQ_TMROUT (1 << 12) +# define A_SRP_DETECT (1 << 11) +# define B_HNP_FAIL (1 << 10) +# define B_SRP_TMROUT (1 << 9) +# define B_SRP_DONE (1 << 8) +# define B_SRP_STARTED (1 << 7) +# define OPRT_CHG (1 << 0) +#define OTG_IRQ_SRC (OTG_BASE + 0x14) /* 16-bit */ + // same bits as in IRQ_EN +#define OTG_OUTCTRL (OTG_BASE + 0x18) /* 16-bit */ +# define OTGVPD (1 << 14) +# define OTGVPU (1 << 13) +# define OTGPUID (1 << 12) +# define USB2VDR (1 << 10) +# define USB2PDEN (1 << 9) +# define USB2PUEN (1 << 8) +# define USB1VDR (1 << 6) +# define USB1PDEN (1 << 5) +# define USB1PUEN (1 << 4) +# define USB0VDR (1 << 2) +# define USB0PDEN (1 << 1) +# define USB0PUEN (1 << 0) +#define OTG_TEST (OTG_BASE + 0x20) /* 16-bit */ +#define OTG_VENDOR_CODE (OTG_BASE + 0xfc) /* 16-bit */ + +/*-------------------------------------------------------------------------*/ + +/* OMAP1 */ +#define USB_TRANSCEIVER_CTRL (0xfffe1000 + 0x0064) +# define CONF_USB2_UNI_R (1 << 8) +# define CONF_USB1_UNI_R (1 << 7) +# define CONF_USB_PORT0_R(x) (((x)>>4)&0x7) +# define CONF_USB0_ISOLATE_R (1 << 3) +# define CONF_USB_PWRDN_DM_R (1 << 2) +# define CONF_USB_PWRDN_DP_R (1 << 1) diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c index e61afd922766..65f88176fba8 100644 --- a/arch/arm/mach-omap1/usb.c +++ b/arch/arm/mach-omap1/usb.c @@ -27,7 +27,8 @@ #include #include -#include + +#include #include "common.h" @@ -55,6 +56,119 @@ #define INT_USB_IRQ_HGEN INT_USB_HHC_1 #define INT_USB_IRQ_OTG IH2_BASE + 8 +#ifdef CONFIG_ARCH_OMAP_OTG + +void __init +omap_otg_init(struct omap_usb_config *config) +{ + u32 syscon; + int alt_pingroup = 0; + + /* NOTE: no bus or clock setup (yet?) */ + + syscon = omap_readl(OTG_SYSCON_1) & 0xffff; + if (!(syscon & OTG_RESET_DONE)) + pr_debug("USB resets not complete?\n"); + + //omap_writew(0, OTG_IRQ_EN); + + /* pin muxing and transceiver pinouts */ + if (config->pins[0] > 2) /* alt pingroup 2 */ + alt_pingroup = 1; + syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); + syscon |= config->usb1_init(config->pins[1]); + syscon |= config->usb2_init(config->pins[2], alt_pingroup); + pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); + omap_writel(syscon, OTG_SYSCON_1); + + syscon = config->hmc_mode; + syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; +#ifdef CONFIG_USB_OTG + if (config->otg) + syscon |= OTG_EN; +#endif + if (cpu_class_is_omap1()) + pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", + omap_readl(USB_TRANSCEIVER_CTRL)); + pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); + omap_writel(syscon, OTG_SYSCON_2); + + printk("USB: hmc %d", config->hmc_mode); + if (!alt_pingroup) + printk(", usb2 alt %d wires", config->pins[2]); + else if (config->pins[0]) + printk(", usb0 %d wires%s", config->pins[0], + is_usb0_device(config) ? " (dev)" : ""); + if (config->pins[1]) + printk(", usb1 %d wires", config->pins[1]); + if (!alt_pingroup && config->pins[2]) + printk(", usb2 %d wires", config->pins[2]); + if (config->otg) + printk(", Mini-AB on usb%d", config->otg - 1); + printk("\n"); + + if (cpu_class_is_omap1()) { + u16 w; + + /* leave USB clocks/controllers off until needed */ + w = omap_readw(ULPD_SOFT_REQ); + w &= ~SOFT_USB_CLK_REQ; + omap_writew(w, ULPD_SOFT_REQ); + + w = omap_readw(ULPD_CLOCK_CTRL); + w &= ~USB_MCLK_EN; + w |= DIS_USB_PVCI_CLK; + omap_writew(w, ULPD_CLOCK_CTRL); + } + syscon = omap_readl(OTG_SYSCON_1); + syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; + +#ifdef CONFIG_USB_GADGET_OMAP + if (config->otg || config->register_dev) { + struct platform_device *udc_device = config->udc_device; + int status; + + syscon &= ~DEV_IDLE_EN; + udc_device->dev.platform_data = config; + status = platform_device_register(udc_device); + if (status) + pr_debug("can't register UDC device, %d\n", status); + } +#endif + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + if (config->otg || config->register_host) { + struct platform_device *ohci_device = config->ohci_device; + int status; + + syscon &= ~HST_IDLE_EN; + ohci_device->dev.platform_data = config; + status = platform_device_register(ohci_device); + if (status) + pr_debug("can't register OHCI device, %d\n", status); + } +#endif + +#ifdef CONFIG_USB_OTG + if (config->otg) { + struct platform_device *otg_device = config->otg_device; + int status; + + syscon &= ~OTG_IDLE_EN; + otg_device->dev.platform_data = config; + status = platform_device_register(otg_device); + if (status) + pr_debug("can't register OTG device, %d\n", status); + } +#endif + pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); + omap_writel(syscon, OTG_SYSCON_1); +} + +#else +void omap_otg_init(struct omap_usb_config *config) {} +#endif + #ifdef CONFIG_USB_GADGET_OMAP static struct resource udc_resources[] = { diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index ed8605f01155..6d87532871cd 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := common.o sram.o clock.o devices.o dma.o mux.o \ - usb.o fb.o counter_32k.o + fb.o counter_32k.o obj-m := obj-n := obj- := diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h index 4814c5b65306..e62f20a5c0af 100644 --- a/arch/arm/plat-omap/include/plat/board.h +++ b/arch/arm/plat-omap/include/plat/board.h @@ -57,44 +57,6 @@ struct omap_camera_sensor_config { int (*power_off)(void * data); }; -struct omap_usb_config { - /* Configure drivers according to the connectors on your board: - * - "A" connector (rectagular) - * ... for host/OHCI use, set "register_host". - * - "B" connector (squarish) or "Mini-B" - * ... for device/gadget use, set "register_dev". - * - "Mini-AB" connector (very similar to Mini-B) - * ... for OTG use as device OR host, initialize "otg" - */ - unsigned register_host:1; - unsigned register_dev:1; - u8 otg; /* port number, 1-based: usb1 == 2 */ - - u8 hmc_mode; - - /* implicitly true if otg: host supports remote wakeup? */ - u8 rwc; - - /* signaling pins used to talk to transceiver on usbN: - * 0 == usbN unused - * 2 == usb0-only, using internal transceiver - * 3 == 3 wire bidirectional - * 4 == 4 wire bidirectional - * 6 == 6 wire unidirectional (or TLL) - */ - u8 pins[3]; - - struct platform_device *udc_device; - struct platform_device *ohci_device; - struct platform_device *otg_device; - - u32 (*usb0_init)(unsigned nwires, unsigned is_device); - u32 (*usb1_init)(unsigned nwires); - u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup); - - int (*ocpi_enable)(void); -}; - struct omap_lcd_config { char panel_name[16]; char ctrl_name[16]; diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 762eeb0626c1..548a4c8d63df 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -44,6 +44,8 @@ struct usbhs_omap_board_data { struct regulator *regulator[OMAP3_HS_USB_PORTS]; }; +#ifdef CONFIG_ARCH_OMAP2PLUS + struct ehci_hcd_omap_platform_data { enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; int reset_gpio_port[OMAP3_HS_USB_PORTS]; @@ -64,26 +66,6 @@ struct usbhs_omap_platform_data { }; /*-------------------------------------------------------------------------*/ -#define OMAP1_OTG_BASE 0xfffb0400 -#define OMAP1_UDC_BASE 0xfffb4000 -#define OMAP1_OHCI_BASE 0xfffba000 - -#define OMAP2_OHCI_BASE 0x4805e000 -#define OMAP2_UDC_BASE 0x4805e200 -#define OMAP2_OTG_BASE 0x4805e300 - -#ifdef CONFIG_ARCH_OMAP1 - -#define OTG_BASE OMAP1_OTG_BASE -#define UDC_BASE OMAP1_UDC_BASE -#define OMAP_OHCI_BASE OMAP1_OHCI_BASE - -#else - -#define OTG_BASE OMAP2_OTG_BASE -#define UDC_BASE OMAP2_UDC_BASE -#define OMAP_OHCI_BASE OMAP2_OHCI_BASE - struct omap_musb_board_data { u8 interface_type; u8 mode; @@ -107,44 +89,6 @@ extern int omap4430_phy_init(struct device *dev); extern int omap4430_phy_exit(struct device *dev); extern int omap4430_phy_suspend(struct device *dev, int suspend); -/* - * NOTE: Please update omap USB drivers to use ioremap + read/write - */ - -#define OMAP2_L4_IO_OFFSET 0xb2000000 -#define OMAP2_L4_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L4_IO_OFFSET) - -static inline u8 omap_readb(u32 pa) -{ - return __raw_readb(OMAP2_L4_IO_ADDRESS(pa)); -} - -static inline u16 omap_readw(u32 pa) -{ - return __raw_readw(OMAP2_L4_IO_ADDRESS(pa)); -} - -static inline u32 omap_readl(u32 pa) -{ - return __raw_readl(OMAP2_L4_IO_ADDRESS(pa)); -} - -static inline void omap_writeb(u8 v, u32 pa) -{ - __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa)); -} - - -static inline void omap_writew(u16 v, u32 pa) -{ - __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa)); -} - -static inline void omap_writel(u32 v, u32 pa) -{ - __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa)); -} - #endif extern void am35x_musb_reset(void); @@ -153,142 +97,6 @@ extern void am35x_musb_clear_irq(void); extern void am35x_set_mode(u8 musb_mode); extern void ti81xx_musb_phy_power(u8 on); -/* - * FIXME correct answer depends on hmc_mode, - * as does (on omap1) any nonzero value for config->otg port number - */ -#ifdef CONFIG_USB_GADGET_OMAP -#define is_usb0_device(config) 1 -#else -#define is_usb0_device(config) 0 -#endif - -void omap_otg_init(struct omap_usb_config *config); - -#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) -void omap1_usb_init(struct omap_usb_config *pdata); -#else -static inline void omap1_usb_init(struct omap_usb_config *pdata) -{ -} -#endif - -#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP_OTG_MODULE) -void omap2_usbfs_init(struct omap_usb_config *pdata); -#else -static inline void omap2_usbfs_init(struct omap_usb_config *pdata) -{ -} -#endif - -/*-------------------------------------------------------------------------*/ - -/* - * OTG and transceiver registers, for OMAPs starting with ARM926 - */ -#define OTG_REV (OTG_BASE + 0x00) -#define OTG_SYSCON_1 (OTG_BASE + 0x04) -# define USB2_TRX_MODE(w) (((w)>>24)&0x07) -# define USB1_TRX_MODE(w) (((w)>>20)&0x07) -# define USB0_TRX_MODE(w) (((w)>>16)&0x07) -# define OTG_IDLE_EN (1 << 15) -# define HST_IDLE_EN (1 << 14) -# define DEV_IDLE_EN (1 << 13) -# define OTG_RESET_DONE (1 << 2) -# define OTG_SOFT_RESET (1 << 1) -#define OTG_SYSCON_2 (OTG_BASE + 0x08) -# define OTG_EN (1 << 31) -# define USBX_SYNCHRO (1 << 30) -# define OTG_MST16 (1 << 29) -# define SRP_GPDATA (1 << 28) -# define SRP_GPDVBUS (1 << 27) -# define SRP_GPUVBUS(w) (((w)>>24)&0x07) -# define A_WAIT_VRISE(w) (((w)>>20)&0x07) -# define B_ASE_BRST(w) (((w)>>16)&0x07) -# define SRP_DPW (1 << 14) -# define SRP_DATA (1 << 13) -# define SRP_VBUS (1 << 12) -# define OTG_PADEN (1 << 10) -# define HMC_PADEN (1 << 9) -# define UHOST_EN (1 << 8) -# define HMC_TLLSPEED (1 << 7) -# define HMC_TLLATTACH (1 << 6) -# define OTG_HMC(w) (((w)>>0)&0x3f) -#define OTG_CTRL (OTG_BASE + 0x0c) -# define OTG_USB2_EN (1 << 29) -# define OTG_USB2_DP (1 << 28) -# define OTG_USB2_DM (1 << 27) -# define OTG_USB1_EN (1 << 26) -# define OTG_USB1_DP (1 << 25) -# define OTG_USB1_DM (1 << 24) -# define OTG_USB0_EN (1 << 23) -# define OTG_USB0_DP (1 << 22) -# define OTG_USB0_DM (1 << 21) -# define OTG_ASESSVLD (1 << 20) -# define OTG_BSESSEND (1 << 19) -# define OTG_BSESSVLD (1 << 18) -# define OTG_VBUSVLD (1 << 17) -# define OTG_ID (1 << 16) -# define OTG_DRIVER_SEL (1 << 15) -# define OTG_A_SETB_HNPEN (1 << 12) -# define OTG_A_BUSREQ (1 << 11) -# define OTG_B_HNPEN (1 << 9) -# define OTG_B_BUSREQ (1 << 8) -# define OTG_BUSDROP (1 << 7) -# define OTG_PULLDOWN (1 << 5) -# define OTG_PULLUP (1 << 4) -# define OTG_DRV_VBUS (1 << 3) -# define OTG_PD_VBUS (1 << 2) -# define OTG_PU_VBUS (1 << 1) -# define OTG_PU_ID (1 << 0) -#define OTG_IRQ_EN (OTG_BASE + 0x10) /* 16-bit */ -# define DRIVER_SWITCH (1 << 15) -# define A_VBUS_ERR (1 << 13) -# define A_REQ_TMROUT (1 << 12) -# define A_SRP_DETECT (1 << 11) -# define B_HNP_FAIL (1 << 10) -# define B_SRP_TMROUT (1 << 9) -# define B_SRP_DONE (1 << 8) -# define B_SRP_STARTED (1 << 7) -# define OPRT_CHG (1 << 0) -#define OTG_IRQ_SRC (OTG_BASE + 0x14) /* 16-bit */ - // same bits as in IRQ_EN -#define OTG_OUTCTRL (OTG_BASE + 0x18) /* 16-bit */ -# define OTGVPD (1 << 14) -# define OTGVPU (1 << 13) -# define OTGPUID (1 << 12) -# define USB2VDR (1 << 10) -# define USB2PDEN (1 << 9) -# define USB2PUEN (1 << 8) -# define USB1VDR (1 << 6) -# define USB1PDEN (1 << 5) -# define USB1PUEN (1 << 4) -# define USB0VDR (1 << 2) -# define USB0PDEN (1 << 1) -# define USB0PUEN (1 << 0) -#define OTG_TEST (OTG_BASE + 0x20) /* 16-bit */ -#define OTG_VENDOR_CODE (OTG_BASE + 0xfc) /* 16-bit */ - -/*-------------------------------------------------------------------------*/ - -/* OMAP1 */ -#define USB_TRANSCEIVER_CTRL (0xfffe1000 + 0x0064) -# define CONF_USB2_UNI_R (1 << 8) -# define CONF_USB1_UNI_R (1 << 7) -# define CONF_USB_PORT0_R(x) (((x)>>4)&0x7) -# define CONF_USB0_ISOLATE_R (1 << 3) -# define CONF_USB_PWRDN_DM_R (1 << 2) -# define CONF_USB_PWRDN_DP_R (1 << 1) - -/* OMAP2 */ -# define USB_UNIDIR 0x0 -# define USB_UNIDIR_TLL 0x1 -# define USB_BIDIR 0x2 -# define USB_BIDIR_TLL 0x3 -# define USBTXWRMODEI(port, x) ((x) << (22 - (port * 2))) -# define USBT2TLL5PI (1 << 17) -# define USB0PUENACTLOI (1 << 16) -# define USBSTANDBYCTRL (1 << 15) /* AM35x */ /* USB 2.0 PHY Control */ #define CONF2_PHY_GPIOMODE (1 << 23) diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c deleted file mode 100644 index daa0327381b5..000000000000 --- a/arch/arm/plat-omap/usb.c +++ /dev/null @@ -1,145 +0,0 @@ - /* - * arch/arm/plat-omap/usb.c -- platform level USB initialization - * - * Copyright (C) 2004 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#undef DEBUG - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#ifdef CONFIG_ARCH_OMAP_OTG - -void __init -omap_otg_init(struct omap_usb_config *config) -{ - u32 syscon; - int alt_pingroup = 0; - - /* NOTE: no bus or clock setup (yet?) */ - - syscon = omap_readl(OTG_SYSCON_1) & 0xffff; - if (!(syscon & OTG_RESET_DONE)) - pr_debug("USB resets not complete?\n"); - - //omap_writew(0, OTG_IRQ_EN); - - /* pin muxing and transceiver pinouts */ - if (config->pins[0] > 2) /* alt pingroup 2 */ - alt_pingroup = 1; - syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); - syscon |= config->usb1_init(config->pins[1]); - syscon |= config->usb2_init(config->pins[2], alt_pingroup); - pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); - omap_writel(syscon, OTG_SYSCON_1); - - syscon = config->hmc_mode; - syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; -#ifdef CONFIG_USB_OTG - if (config->otg) - syscon |= OTG_EN; -#endif - if (cpu_class_is_omap1()) - pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", - omap_readl(USB_TRANSCEIVER_CTRL)); - pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); - omap_writel(syscon, OTG_SYSCON_2); - - printk("USB: hmc %d", config->hmc_mode); - if (!alt_pingroup) - printk(", usb2 alt %d wires", config->pins[2]); - else if (config->pins[0]) - printk(", usb0 %d wires%s", config->pins[0], - is_usb0_device(config) ? " (dev)" : ""); - if (config->pins[1]) - printk(", usb1 %d wires", config->pins[1]); - if (!alt_pingroup && config->pins[2]) - printk(", usb2 %d wires", config->pins[2]); - if (config->otg) - printk(", Mini-AB on usb%d", config->otg - 1); - printk("\n"); - - if (cpu_class_is_omap1()) { - u16 w; - - /* leave USB clocks/controllers off until needed */ - w = omap_readw(ULPD_SOFT_REQ); - w &= ~SOFT_USB_CLK_REQ; - omap_writew(w, ULPD_SOFT_REQ); - - w = omap_readw(ULPD_CLOCK_CTRL); - w &= ~USB_MCLK_EN; - w |= DIS_USB_PVCI_CLK; - omap_writew(w, ULPD_CLOCK_CTRL); - } - syscon = omap_readl(OTG_SYSCON_1); - syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; - -#ifdef CONFIG_USB_GADGET_OMAP - if (config->otg || config->register_dev) { - struct platform_device *udc_device = config->udc_device; - int status; - - syscon &= ~DEV_IDLE_EN; - udc_device->dev.platform_data = config; - status = platform_device_register(udc_device); - if (status) - pr_debug("can't register UDC device, %d\n", status); - } -#endif - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - if (config->otg || config->register_host) { - struct platform_device *ohci_device = config->ohci_device; - int status; - - syscon &= ~HST_IDLE_EN; - ohci_device->dev.platform_data = config; - status = platform_device_register(ohci_device); - if (status) - pr_debug("can't register OHCI device, %d\n", status); - } -#endif - -#ifdef CONFIG_USB_OTG - if (config->otg) { - struct platform_device *otg_device = config->otg_device; - int status; - - syscon &= ~OTG_IDLE_EN; - otg_device->dev.platform_data = config; - status = platform_device_register(otg_device); - if (status) - pr_debug("can't register OTG device, %d\n", status); - } -#endif - pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); - omap_writel(syscon, OTG_SYSCON_1); -} - -#else -void omap_otg_init(struct omap_usb_config *config) {} -#endif diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bddc8fd9a7be..271ca161d7ef 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -185,7 +185,7 @@ config USB_FUSB300 config USB_OMAP tristate "OMAP USB Device Controller" - depends on ARCH_OMAP + depends on ARCH_OMAP1 select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG select USB_OTG_UTILS if ARCH_OMAP help diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 7ba32469c5bd..2acf06cd9225 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -44,7 +44,8 @@ #include #include -#include + +#include #include "omap_udc.h" diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 83e58df29fe3..dcfaaa91a3fb 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -308,7 +308,7 @@ config USB_OHCI_HCD config USB_OHCI_HCD_OMAP1 bool "OHCI support for OMAP1/2 chips" - depends on USB_OHCI_HCD && (ARCH_OMAP1 || ARCH_OMAP2) + depends on USB_OHCI_HCD && ARCH_OMAP1 default y ---help--- Enables support for the OHCI controller on OMAP1/2 chips. diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 9ce35d0d9d5d..b02c344e2cc9 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -20,14 +20,15 @@ #include #include -#include #include #include #include -#include #include -#include + +#include +#include +#include /* OMAP-1510 OHCI has its own MMU for DMA */ diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 70cf5d7bca48..e0558dfcfafc 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -36,9 +36,9 @@ #include #include -#include #include +#include #ifndef DEBUG #undef VERBOSE -- GitLab From 87c9ea76a242c2f9063e2a8f3e90846c932c61a7 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 3 Jun 2012 21:56:21 +0530 Subject: [PATCH 0152/6849] mtip32xx: Remove version.h header file inclusion version.h header file inclusion is no longer required. Signed-off-by: Sachin Kamat --- drivers/block/mtip32xx/mtip32xx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index b2c88da26b2a..adb1aae3b752 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -26,7 +26,6 @@ #include #include #include -#include /* Offset of Subsystem Device ID in pci confoguration space */ #define PCI_SUBSYSTEM_DEVICEID 0x2E -- GitLab From fd7949564ced88385ca7758a4c1f47c274233dd5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 4 Jun 2012 10:01:38 +0200 Subject: [PATCH 0153/6849] block: fix return value on cfq_init() failure cfq_init() would return zero after kmem cache creation failure. Fix so that it returns -ENOMEM. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 673c977cc2bf..ae5113d3ebae 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -4202,6 +4202,7 @@ static int __init cfq_init(void) if (ret) return ret; + ret = -ENOMEM; cfq_pool = KMEM_CACHE(cfq_queue, 0); if (!cfq_pool) goto err_pol_unreg; -- GitLab From ffea73fc723a12fdde4c9fb3fcce5d154d1104a1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 4 Jun 2012 10:02:29 +0200 Subject: [PATCH 0154/6849] block: blkcg_policy_cfq shouldn't be used if !CONFIG_CFQ_GROUP_IOSCHED cfq may be built w/ or w/o blkcg support depending on CONFIG_CFQ_CGROUP_IOSCHED. If blkcg support is disabled, most of related code is ifdef'd out but some part is left dangling - blkcg_policy_cfq is left zero-filled and blkcg_policy_[un]register() calls are made on it. Feeding zero filled policy to blkcg_policy_register() is incorrect and triggers the following WARN_ON() if CONFIG_BLK_CGROUP && !CONFIG_CFQ_GROUP_IOSCHED. ------------[ cut here ]------------ WARNING: at block/blk-cgroup.c:867 Modules linked in: Modules linked in: CPU: 3 Not tainted 3.4.0-09547-gfb21aff #1 Process swapper/0 (pid: 1, task: 000000003ff80000, ksp: 000000003ff7f8b8) Krnl PSW : 0704100180000000 00000000003d76ca (blkcg_policy_register+0xca/0xe0) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:1 PM:0 EA:3 Krnl GPRS: 0000000000000000 00000000014b85ec 00000000014b85b0 0000000000000000 000000000096fb60 0000000000000000 00000000009a8e78 0000000000000048 000000000099c070 0000000000b6f000 0000000000000000 000000000099c0b8 00000000014b85b0 0000000000667580 000000003ff7fd98 000000003ff7fd70 Krnl Code: 00000000003d76be: a7280001 lhi %r2,1 00000000003d76c2: a7f4ffdf brc 15,3d7680 #00000000003d76c6: a7f40001 brc 15,3d76c8 >00000000003d76ca: a7c8ffea lhi %r12,-22 00000000003d76ce: a7f4ffce brc 15,3d766a 00000000003d76d2: a7f40001 brc 15,3d76d4 00000000003d76d6: a7c80000 lhi %r12,0 00000000003d76da: a7f4ffc2 brc 15,3d765e Call Trace: ([<0000000000b6f000>] initcall_debug+0x0/0x4) [<0000000000989e8a>] cfq_init+0x62/0xd4 [<00000000001000ba>] do_one_initcall+0x3a/0x170 [<000000000096fb60>] kernel_init+0x214/0x2bc [<0000000000623202>] kernel_thread_starter+0x6/0xc [<00000000006231fc>] kernel_thread_starter+0x0/0xc no locks held by swapper/0/1. Last Breaking-Event-Address: [<00000000003d76c6>] blkcg_policy_register+0xc6/0xe0 ---[ end trace b8ef4903fcbf9dd3 ]--- This patch fixes the problem by ensuring all blkcg support code is inside CONFIG_CFQ_GROUP_IOSCHED. * blkcg_policy_cfq declaration and blkg_to_cfqg() definition are moved inside the first CONFIG_CFQ_GROUP_IOSCHED block. __maybe_unused is dropped from blkcg_policy_cfq decl. * blkcg_deactivate_poilcy() invocation is moved inside ifdef. This also makes the activation logic match cfq_init_queue(). * All blkcg_policy_[un]register() invocations are moved inside ifdef. Signed-off-by: Tejun Heo Reported-by: Heiko Carstens LKML-Reference: <20120601112954.GC3535@osiris.boeblingen.de.ibm.com> Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index ae5113d3ebae..fb52df9744f5 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -17,8 +17,6 @@ #include "blk.h" #include "blk-cgroup.h" -static struct blkcg_policy blkcg_policy_cfq __maybe_unused; - /* * tunables */ @@ -418,11 +416,6 @@ static inline struct cfq_group *pd_to_cfqg(struct blkg_policy_data *pd) return pd ? container_of(pd, struct cfq_group, pd) : NULL; } -static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg) -{ - return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); -} - static inline struct blkcg_gq *cfqg_to_blkg(struct cfq_group *cfqg) { return pd_to_blkg(&cfqg->pd); @@ -572,6 +565,13 @@ static inline void cfqg_stats_update_avg_queue_size(struct cfq_group *cfqg) { } #ifdef CONFIG_CFQ_GROUP_IOSCHED +static struct blkcg_policy blkcg_policy_cfq; + +static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg) +{ + return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); +} + static inline void cfqg_get(struct cfq_group *cfqg) { return blkg_get(cfqg_to_blkg(cfqg)); @@ -3951,10 +3951,11 @@ static void cfq_exit_queue(struct elevator_queue *e) cfq_shutdown_timer_wq(cfqd); -#ifndef CONFIG_CFQ_GROUP_IOSCHED +#ifdef CONFIG_CFQ_GROUP_IOSCHED + blkcg_deactivate_policy(q, &blkcg_policy_cfq); +#else kfree(cfqd->root_group); #endif - blkcg_deactivate_policy(q, &blkcg_policy_cfq); kfree(cfqd); } @@ -4194,13 +4195,13 @@ static int __init cfq_init(void) #ifdef CONFIG_CFQ_GROUP_IOSCHED if (!cfq_group_idle) cfq_group_idle = 1; -#else - cfq_group_idle = 0; -#endif ret = blkcg_policy_register(&blkcg_policy_cfq); if (ret) return ret; +#else + cfq_group_idle = 0; +#endif ret = -ENOMEM; cfq_pool = KMEM_CACHE(cfq_queue, 0); @@ -4216,13 +4217,17 @@ static int __init cfq_init(void) err_free_pool: kmem_cache_destroy(cfq_pool); err_pol_unreg: +#ifdef CONFIG_CFQ_GROUP_IOSCHED blkcg_policy_unregister(&blkcg_policy_cfq); +#endif return ret; } static void __exit cfq_exit(void) { +#ifdef CONFIG_CFQ_GROUP_IOSCHED blkcg_policy_unregister(&blkcg_policy_cfq); +#endif elv_unregister(&iosched_cfq); kmem_cache_destroy(cfq_pool); } -- GitLab From 9b2ea86bc9e940950a088e9795ab28f006e73276 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 4 Jun 2012 15:21:00 +0900 Subject: [PATCH 0155/6849] blkcg: fix blkg_alloc() failure path When policy data allocation fails in the middle, blkg_alloc() invokes blkg_free() to destroy the half constructed blkg. This ends up calling pd_exit_fn() on policy datas which didn't go through pd_init_fn(). Fix it by making blkg_alloc() call pd_init_fn() immediately after each policy data allocation. Signed-off-by: Tejun Heo Acked-by: Vivek Goyal Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 02cf6335e9bd..4ab7420ba465 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -125,12 +125,8 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) blkg->pd[i] = pd; pd->blkg = blkg; - } - - /* invoke per-policy init */ - for (i = 0; i < BLKCG_MAX_POLS; i++) { - struct blkcg_policy *pol = blkcg_policy[i]; + /* invoke per-policy init */ if (blkcg_policy_enabled(blkg->q, pol)) pol->pd_init_fn(blkg); } -- GitLab From fc492f9bd13cb4c7c1299f5d390a203c1ad9a85b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 9 May 2012 22:27:41 +0100 Subject: [PATCH 0156/6849] regulator: wm8350: Convert LDOs to set_voltage_sel() Since there are two linear ranges for the LDO voltages provide a voltage mapping function and then use regulator_set_voltage_sel_regmap(). Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 38 ++++++---------------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 33c37f9c0e41..ca678eea79de 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -671,13 +671,12 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) return 0; } -static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV, unsigned *selector) +static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV) { - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, ldo = rdev_get_id(rdev), mV, min_mV = min_uV / 1000, - max_mV = max_uV / 1000; - u16 val; + int mV; + int min_mV = min_uV / 1000; + int max_mV = max_uV / 1000; if (min_mV < 900 || min_mV > 3300) return -EINVAL; @@ -698,29 +697,7 @@ static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); } - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_CONTROL; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_CONTROL; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_CONTROL; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_CONTROL; - break; - default: - return -EINVAL; - } - - *selector = mV; - - /* all LDOs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, val | mV); - return 0; + return mV; } static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, @@ -1058,7 +1035,8 @@ static struct regulator_ops wm8350_dcdc2_5_ops = { }; static struct regulator_ops wm8350_ldo_ops = { - .set_voltage = wm8350_ldo_set_voltage, + .map_voltage = wm8350_ldo_map_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = wm8350_ldo_list_voltage, .enable = regulator_enable_regmap, -- GitLab From 4d04317f6efab7359ae56e50cc9c60e9804b5015 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 4 Jun 2012 00:13:25 -0700 Subject: [PATCH 0157/6849] ARM: OMAP: Fix lis3lv02d accelerometer to use gpio_to_irq Commit 3b511201 (ARM: OMAP: rx51: Platform support for lis3lv02d accelerometer) added support for lis3lv02d accelerometer. The patch was still using OMAP_GPIO_IRQ which no longer exists. Fix it by using gpio_to_irq(). Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-peripherals.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index ff53deccecab..df2534de3361 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -144,7 +144,6 @@ static struct lis3lv02d_platform_data rx51_lis3lv02d_data = { .release_resources = lis302_release, .st_min_limits = {-32, 3, 3}, .st_max_limits = {-3, 32, 32}, - .irq2 = OMAP_GPIO_IRQ(LIS302_IRQ2_GPIO), }; #endif @@ -1030,7 +1029,6 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = { { I2C_BOARD_INFO("lis3lv02d", 0x1d), .platform_data = &rx51_lis3lv02d_data, - .irq = OMAP_GPIO_IRQ(LIS302_IRQ1_GPIO), }, #endif }; @@ -1056,6 +1054,10 @@ static int __init rx51_i2c_init(void) omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata); omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); +#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) + rx51_lis3lv02d_data.irq2 = gpio_to_irq(LIS302_IRQ2_GPIO); + rx51_peripherals_i2c_board_info_3[0].irq = gpio_to_irq(LIS302_IRQ1_GPIO); +#endif omap_register_i2c_bus(3, 400, rx51_peripherals_i2c_board_info_3, ARRAY_SIZE(rx51_peripherals_i2c_board_info_3)); return 0; -- GitLab From 9152c36a3b37a95c1161508dc105719456d7f7d0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 4 Jun 2012 09:41:38 +0800 Subject: [PATCH 0158/6849] regulator: core: Use map_voltage_linear() if list_voltage_linear() is in use and nothing is set Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8521e0d6b3bc..3cbe3129ed3b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2118,12 +2118,18 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); } else if (rdev->desc->ops->set_voltage_sel) { - if (rdev->desc->ops->map_voltage) + if (rdev->desc->ops->map_voltage) { ret = rdev->desc->ops->map_voltage(rdev, min_uV, max_uV); - else - ret = regulator_map_voltage_iterate(rdev, min_uV, - max_uV); + } else { + if (rdev->desc->ops->list_voltage == + regulator_list_voltage_linear) + ret = regulator_map_voltage_linear(rdev, + min_uV, max_uV); + else + ret = regulator_map_voltage_iterate(rdev, + min_uV, max_uV); + } if (ret >= 0) { selector = ret; -- GitLab From 695594f1b79d3b88e99e28f06afaab32c4d65853 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Jun 2012 08:14:13 +0100 Subject: [PATCH 0159/6849] ASoC: dapm: Use devm_clk_get() Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 3bb7a6f058d0..a66379accec9 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2902,7 +2902,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } break; case snd_soc_dapm_clock_supply: - w->clk = clk_get(dapm->dev, w->name); + w->clk = devm_clk_get(dapm->dev, w->name); if (IS_ERR(w->clk)) { ret = PTR_ERR(w->clk); dev_err(dapm->dev, "Failed to request %s: %d\n", -- GitLab From ec02995adad5a7b428f46c1a87fae1bc93d6dfe3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Jun 2012 08:16:20 +0100 Subject: [PATCH 0160/6849] ASoC: dapm: Bodge for lack of a widely available clk API Reported-by: Stephen Rothwell Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a66379accec9..39e8c2fdf50e 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1011,12 +1011,14 @@ int dapm_clock_event(struct snd_soc_dapm_widget *w, if (!w->clk) return -EIO; +#ifdef CONFIG_HAVE_CLK if (SND_SOC_DAPM_EVENT_ON(event)) { return clk_enable(w->clk); } else { clk_disable(w->clk); return 0; } +#endif } EXPORT_SYMBOL_GPL(dapm_clock_event); @@ -2902,6 +2904,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } break; case snd_soc_dapm_clock_supply: +#ifdef CONFIG_HAVE_CLK w->clk = devm_clk_get(dapm->dev, w->name); if (IS_ERR(w->clk)) { ret = PTR_ERR(w->clk); @@ -2909,6 +2912,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, w->name, ret); return NULL; } +#else + return NULL; +#endif break; default: break; -- GitLab From 014e5b56702575c5cd8ffc4b1a7924cfdfe0f1ea Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Mon, 4 Jun 2012 09:42:53 +0800 Subject: [PATCH 0161/6849] ASoC: fsl_ssi: convert to use devm_clk_get Signed-off-by: Richard Zhao Acked-by: Timur Tabi Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 4ed2afd47782..b10a427a8098 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -725,7 +725,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) u32 dma_events[2]; ssi_private->ssi_on_imx = true; - ssi_private->clk = clk_get(&pdev->dev, NULL); + ssi_private->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ssi_private->clk)) { ret = PTR_ERR(ssi_private->clk); dev_err(&pdev->dev, "could not get clock: %d\n", ret); @@ -842,10 +842,8 @@ error_dev: device_remove_file(&pdev->dev, dev_attr); error_clk: - if (ssi_private->ssi_on_imx) { + if (ssi_private->ssi_on_imx) clk_disable_unprepare(ssi_private->clk); - clk_put(ssi_private->clk); - } error_irq: free_irq(ssi_private->irq, ssi_private); @@ -871,7 +869,6 @@ static int fsl_ssi_remove(struct platform_device *pdev) if (ssi_private->ssi_on_imx) { platform_device_unregister(ssi_private->imx_pcm_pdev); clk_disable_unprepare(ssi_private->clk); - clk_put(ssi_private->clk); } snd_soc_unregister_dai(&pdev->dev); device_remove_file(&pdev->dev, &ssi_private->dev_attr); -- GitLab From 7376bde8945fe20d35aa51f493a7e43b60a39dbe Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 3 Jun 2012 22:50:18 +0530 Subject: [PATCH 0162/6849] ASoC: cs42l52: Remove version.h header file inclusion version.h header file is no longer needed. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l52.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index a7109413aef1..ec03abc79a9a 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include -- GitLab From 2bce133c3b00020f4bc146cea94ff5d4de9a8a0f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 3 Jun 2012 22:58:40 +0530 Subject: [PATCH 0163/6849] ASoC: lm49453: Remove version.h header file inclusion version.h header file is no longer required. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/lm49453.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 802b9f176b16..c1bc9458906b 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include -- GitLab From 96d25221d28646fc2ce0a64a725c67c1ee2f2f0a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 4 Jun 2012 12:56:58 +0800 Subject: [PATCH 0164/6849] regulator: max1586: Convert max1586_v6_ops to regulator_list_voltage_table Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max1586.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index b9444ee08da9..f215195de917 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -47,6 +47,14 @@ struct max1586_data { struct regulator_dev *rdev[0]; }; +/* + * V6 voltage + * On I2C bus, sending a "x" byte to the max1586 means : + * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3) + * As regulator framework doesn't accept voltages to be 0V, we use 1uV. + */ +static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; + /* * V3 voltage * On I2C bus, sending a "x" byte to the max1586 means : @@ -97,19 +105,6 @@ static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector) return max1586_v3_calc_voltage(max1586, selector); } -/* - * V6 voltage - * On I2C bus, sending a "x" byte to the max1586 means : - * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3) - * As regulator framework doesn't accept voltages to be 0V, we use 1uV. - */ -static int max1586_v6_calc_voltage(unsigned selector) -{ - static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; - - return voltages_uv[selector]; -} - static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned int *selector) { @@ -130,23 +125,16 @@ static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV, else if (min_uV >= 3000000) *selector = 3; - if (max1586_v6_calc_voltage(*selector) > max_uV) + if (rdev->desc->volt_table[*selector] > max_uV) return -EINVAL; dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", - max1586_v6_calc_voltage(*selector) / 1000); + rdev->desc->volt_table[*selector] / 1000); v6_prog = I2C_V6_SELECT | (u8) *selector; return i2c_smbus_write_byte(client, v6_prog); } -static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector) -{ - if (selector > MAX1586_V6_MAX_VSEL) - return -EINVAL; - return max1586_v6_calc_voltage(selector); -} - /* * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back * the set up value. @@ -158,7 +146,7 @@ static struct regulator_ops max1586_v3_ops = { static struct regulator_ops max1586_v6_ops = { .set_voltage = max1586_v6_set, - .list_voltage = max1586_v6_list, + .list_voltage = regulator_list_voltage_table, }; static const struct regulator_desc max1586_reg[] = { @@ -176,6 +164,7 @@ static const struct regulator_desc max1586_reg[] = { .ops = &max1586_v6_ops, .type = REGULATOR_VOLTAGE, .n_voltages = MAX1586_V6_MAX_VSEL + 1, + .volt_table = v6_voltages_uv, .owner = THIS_MODULE, }, }; -- GitLab From 0d032731178d78450296bdf0b27562476594c298 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 4 Jun 2012 12:58:24 +0800 Subject: [PATCH 0165/6849] regulator: max1586: Convert max1586_v6_ops to set_voltage_sel Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max1586.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index f215195de917..126c7d8f31c6 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -105,33 +105,16 @@ static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector) return max1586_v3_calc_voltage(max1586, selector); } -static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV, - unsigned int *selector) +static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, + unsigned int selector) { struct i2c_client *client = rdev_get_drvdata(rdev); u8 v6_prog; - if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV) - return -EINVAL; - if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV) - return -EINVAL; - - if (min_uV < 1800000) - *selector = 0; - else if (min_uV < 2500000) - *selector = 1; - else if (min_uV < 3000000) - *selector = 2; - else if (min_uV >= 3000000) - *selector = 3; - - if (rdev->desc->volt_table[*selector] > max_uV) - return -EINVAL; - dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", - rdev->desc->volt_table[*selector] / 1000); + rdev->desc->volt_table[selector] / 1000); - v6_prog = I2C_V6_SELECT | (u8) *selector; + v6_prog = I2C_V6_SELECT | (u8) selector; return i2c_smbus_write_byte(client, v6_prog); } @@ -145,7 +128,7 @@ static struct regulator_ops max1586_v3_ops = { }; static struct regulator_ops max1586_v6_ops = { - .set_voltage = max1586_v6_set, + .set_voltage_sel = max1586_v6_set_voltage_sel, .list_voltage = regulator_list_voltage_table, }; -- GitLab From 74adfee53b8f05b4a9db0848d19399db2cef6cbf Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 4 Jun 2012 10:19:18 +0800 Subject: [PATCH 0166/6849] regulator: max77686: Fix checkpatch warnings Fix below checkpatch warnings: $ scripts/checkpatch.pl -f drivers/regulator/max77686.c ERROR: return is not a function, parentheses are not required + return (DIV_ROUND_UP(rdev->desc->uV_step WARNING: line over 80 characters + .ops = &max77686_buck_dvs_ops, \ total: 1 errors, 1 warnings, 339 lines checked Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 4e9f4f3f062b..b76a0389d0b8 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -75,17 +75,18 @@ static int max77686_set_dvs_voltage_time_sel(struct regulator_dev *rdev, { struct max77686_data *max77686 = rdev_get_drvdata(rdev); int ramp_rate[] = {13, 27, 55, 100}; - return (DIV_ROUND_UP(rdev->desc->uV_step - * abs(new_selector - old_selector), - ramp_rate[max77686->ramp_delay])); + + return DIV_ROUND_UP(rdev->desc->uV_step * + abs(new_selector - old_selector), + ramp_rate[max77686->ramp_delay]); } static int max77686_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { /* Unconditionally 100 mV/us */ - return (DIV_ROUND_UP(rdev->desc->uV_step - * abs(new_selector - old_selector), 100)); + return DIV_ROUND_UP(rdev->desc->uV_step * + abs(new_selector - old_selector), 100); } static struct regulator_ops max77686_ops = { @@ -171,7 +172,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { #define regulator_desc_buck_dvs(num) { \ .name = "BUCK"#num, \ .id = MAX77686_BUCK##num, \ - .ops = &max77686_buck_dvs_ops, \ + .ops = &max77686_buck_dvs_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ .min_uV = MAX77686_DVS_MINUV, \ -- GitLab From 6cc90d6de16532fe68b54ee6967894f7ca83affa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Jun 2012 12:21:21 +0200 Subject: [PATCH 0167/6849] ARM i.MX pllv2: use standard register set unconditionally The i.MX5 PLL has two different register sets for setting the rate. One is used for the standard case and and is used for DVFS. Which one of them is used depends on a hardware input of the PLL. Current implementation reads back from the hardware which setting is used. This is bogus: If we ever want to implement DVFS we have to program both register sets and not only the one which happens to be used at the moment. For now, just use the standard register set uncondionally. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-pllv2.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index 4685919deb63..1b0307195a6e 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c @@ -78,7 +78,7 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; + unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, dbl; void __iomem *pllbase; s64 temp; struct clk_pllv2 *pll = to_clk_pllv2(hw); @@ -86,18 +86,12 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, pllbase = pll->base; dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; - if (pll_hfsm == 0) { - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - } else { - dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); - } + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; mfi = (mfi <= 5) ? 5 : mfi; @@ -132,7 +126,7 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, long mfi, pdf, mfn, mfd = 999999; s64 temp64; unsigned long quad_parent_rate; - unsigned long pll_hfsm, dp_ctl; + unsigned long dp_ctl; pllbase = pll->base; @@ -151,18 +145,11 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); /* use dpdck0_2 */ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; - if (pll_hfsm == 0) { - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); - } else { - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); - } + + reg = mfi << 4 | pdf; + __raw_writel(reg, pllbase + MXC_PLL_DP_OP); + __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); return 0; } -- GitLab From 9ca41bccc39f5ebbbb515dfadb2e0f912168c8bd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Jun 2012 14:51:32 +0200 Subject: [PATCH 0168/6849] ARM i.MX pllv2: make round_rate accurate in round_rate we made the assumption that we can set arbitrary frequencies and thus returned the input rate. This is not correct, for certain frequencies after setting a frequency with set_rate, recalc_rate will return different values. To fix this, introduce set_rate/recalc_rate functions which work on variables instead of registers directly. This way we can call these in round_rate to get the exact rate which we would get if we call set_rate with this value. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-pllv2.c | 78 ++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index 1b0307195a6e..0440379e3628 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c @@ -74,24 +74,15 @@ struct clk_pllv2 { void __iomem *base; }; -static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) +static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, + u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) { long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, dbl; - void __iomem *pllbase; + unsigned long dbl; s64 temp; - struct clk_pllv2 *pll = to_clk_pllv2(hw); - - pllbase = pll->base; - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; mfi = (mfi <= 5) ? 5 : mfi; @@ -117,18 +108,30 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, return temp; } -static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, +static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { + u32 dp_op, dp_mfd, dp_mfn, dp_ctl; + void __iomem *pllbase; struct clk_pllv2 *pll = to_clk_pllv2(hw); + + pllbase = pll->base; + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + + return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn); +} + +static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, + u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn) +{ u32 reg; - void __iomem *pllbase; long mfi, pdf, mfn, mfd = 999999; s64 temp64; unsigned long quad_parent_rate; - unsigned long dp_ctl; - - pllbase = pll->base; quad_parent_rate = 4 * parent_rate; pdf = mfi = -1; @@ -138,18 +141,41 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; pdf--; - temp64 = rate * (pdf+1) - quad_parent_rate * mfi; - do_div(temp64, quad_parent_rate/1000000); + temp64 = rate * (pdf + 1) - quad_parent_rate * mfi; + do_div(temp64, quad_parent_rate / 1000000); mfn = (long)temp64; + reg = mfi << 4 | pdf; + + *dp_op = reg; + *dp_mfd = mfd; + *dp_mfn = mfn; + + return 0; +} + +static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv2 *pll = to_clk_pllv2(hw); + void __iomem *pllbase; + u32 dp_ctl, dp_op, dp_mfd, dp_mfn; + int ret; + + pllbase = pll->base; + + + ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn); + if (ret) + return ret; + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); /* use dpdck0_2 */ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); + __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP); + __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN); return 0; } @@ -157,7 +183,11 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { - return rate; + u32 dp_op, dp_mfd, dp_mfn; + + __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); + return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, + dp_op, dp_mfd, dp_mfn); } static int clk_pllv2_prepare(struct clk_hw *hw) -- GitLab From cdd781ab1906d039c2a93078385645d2d5af8491 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Jun 2012 14:58:07 +0200 Subject: [PATCH 0169/6849] ARM i.MX53: Fix PLL4 base address MX53_DPLL4_BASE accidently returned the base address of PLL3. Fix this. Signed-off-by: Sascha Hauer Cc: stable@vger.kernel.org --- arch/arm/mach-imx/crm-regs-imx5.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/crm-regs-imx5.h b/arch/arm/mach-imx/crm-regs-imx5.h index 5e11ba7daee2..5e3f1f0f4cab 100644 --- a/arch/arm/mach-imx/crm-regs-imx5.h +++ b/arch/arm/mach-imx/crm-regs-imx5.h @@ -23,7 +23,7 @@ #define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) #define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) #define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) -#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) +#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR) /* PLL Register Offsets */ #define MXC_PLL_DP_CTL 0x00 -- GitLab From 27c347d64f5e4a7e141f6bdb85bbf59e0f1dcde6 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Jun 2012 16:28:48 +0530 Subject: [PATCH 0170/6849] Input: MT - fix null pointer warning Fixes the following sparse warning: drivers/input/input-mt.c:138:40: warning: Using plain integer as NULL pointer Signed-off-by: Sachin Kamat Signed-off-by: Henrik Rydberg --- drivers/input/input-mt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index f658086fbbe0..70a16c7da8cc 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -135,7 +135,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count); */ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) { - struct input_mt_slot *oldest = 0; + struct input_mt_slot *oldest = NULL; int oldid = dev->trkid; int count = 0; int i; -- GitLab From 338edabcd879320f0f86cc701161b95277be6b5d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 18 May 2012 14:33:46 +0530 Subject: [PATCH 0171/6849] usb: s3c-hsotg: Use devm_* functions in s3c-hsotg.c file devm_* functions are used to replace kzalloc, request_mem_region, ioremap and request_irq functions in probe call. With the usage of devm_* functions explicit freeing and unmapping is not required. Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 51 ++++++++-------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index f4abb0ed9872..d37585105bb4 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -136,7 +136,6 @@ struct s3c_hsotg_ep { * @driver: USB gadget driver * @plat: The platform specific configuration data. * @regs: The memory area mapped for accessing registers. - * @regs_res: The resource that was allocated when claiming register space. * @irq: The IRQ number we are using * @supplies: Definition of USB power supplies * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. @@ -158,7 +157,6 @@ struct s3c_hsotg { struct s3c_hsotg_plat *plat; void __iomem *regs; - struct resource *regs_res; int irq; struct clk *clk; @@ -3477,7 +3475,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) return -EINVAL; } - hsotg = kzalloc(sizeof(struct s3c_hsotg), GFP_KERNEL); + hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); if (!hsotg) { dev_err(dev, "cannot get memory\n"); return -ENOMEM; @@ -3489,46 +3487,33 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) hsotg->clk = clk_get(&pdev->dev, "otg"); if (IS_ERR(hsotg->clk)) { dev_err(dev, "cannot get otg clock\n"); - ret = PTR_ERR(hsotg->clk); - goto err_mem; + return PTR_ERR(hsotg->clk); } platform_set_drvdata(pdev, hsotg); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "cannot find register resource 0\n"); - ret = -EINVAL; - goto err_clk; - } - - hsotg->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!hsotg->regs_res) { - dev_err(dev, "cannot reserve registers\n"); - ret = -ENOENT; - goto err_clk; - } - hsotg->regs = ioremap(res->start, resource_size(res)); + hsotg->regs = devm_request_and_ioremap(&pdev->dev, res); if (!hsotg->regs) { dev_err(dev, "cannot map registers\n"); ret = -ENXIO; - goto err_regs_res; + goto err_clk; } ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(dev, "cannot find IRQ\n"); - goto err_regs; + goto err_clk; } hsotg->irq = ret; - ret = request_irq(ret, s3c_hsotg_irq, 0, dev_name(dev), hsotg); + ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, + dev_name(dev), hsotg); if (ret < 0) { dev_err(dev, "cannot claim IRQ\n"); - goto err_regs; + goto err_clk; } dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); @@ -3558,7 +3543,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) hsotg->supplies); if (ret) { dev_err(dev, "failed to request supplies: %d\n", ret); - goto err_irq; + goto err_clk; } ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), @@ -3642,19 +3627,11 @@ err_ep_mem: err_supplies: s3c_hsotg_phy_disable(hsotg); regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); -err_irq: - free_irq(hsotg->irq, hsotg); -err_regs: - iounmap(hsotg->regs); - -err_regs_res: - release_resource(hsotg->regs_res); - kfree(hsotg->regs_res); + err_clk: clk_disable_unprepare(hsotg->clk); clk_put(hsotg->clk); -err_mem: - kfree(hsotg); + return ret; } @@ -3675,12 +3652,6 @@ static int __devexit s3c_hsotg_remove(struct platform_device *pdev) usb_gadget_unregister_driver(hsotg->driver); } - free_irq(hsotg->irq, hsotg); - iounmap(hsotg->regs); - - release_resource(hsotg->regs_res); - kfree(hsotg->regs_res); - s3c_hsotg_phy_disable(hsotg); regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); -- GitLab From fa84c57516f6da93ebc2601348043e9bcb7b4b4d Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Sat, 26 May 2012 16:32:39 -0700 Subject: [PATCH 0172/6849] usb: gadget: f_mass_storage: change default value of the removable parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit changes the default value of the removable module parameter from “y” to “n”. This comes with line with file_storag's default and seems to be a better default. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_mass_storage.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index f67b453740bd..72116fa49ffb 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -124,7 +124,7 @@ * backing storage. * ro=b[,b...] Default false, boolean for read-only access. * removable=b[,b...] - * Default true, boolean for removable media. + * Default false, boolean for removable media. * cdrom=b[,b...] Default false, boolean for whether to emulate * a CD-ROM drive. * nofua=b[,b...] Default false, booleans for ignore FUA flag @@ -3167,8 +3167,7 @@ fsg_config_from_params(struct fsg_config *cfg, for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) { lun->ro = !!params->ro[i]; lun->cdrom = !!params->cdrom[i]; - lun->removable = /* Removable by default */ - params->removable_count <= i || params->removable[i]; + lun->removable = !!params->removable[i]; lun->filename = params->file_count > i && params->file[i][0] ? params->file[i] @@ -3203,4 +3202,3 @@ fsg_common_from_params(struct fsg_common *common, fsg_config_from_params(&cfg, params); return fsg_common_init(common, cdev, &cfg); } - -- GitLab From d3c568c302ed0e3b2d51f0335f304ca4d85de54b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 28 May 2012 23:31:39 -0700 Subject: [PATCH 0173/6849] usb: renesas_usbhs: add DMAEngine ID specification note renesas_usbhs DMAEngine uses D0FIFO/D1FIFO, but the data transfer direction should be fixed for keeping consistency. This patch explain about it on renesas_usbhs.h Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- include/linux/usb/renesas_usbhs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 547e59cc00ea..c5d36c65c33b 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -132,6 +132,14 @@ struct renesas_usbhs_driver_param { * option: * * dma id for dmaengine + * The data transfer direction on D0FIFO/D1FIFO should be + * fixed for keeping consistency. + * So, the platform id settings will be.. + * .d0_tx_id = xx_TX, + * .d1_rx_id = xx_RX, + * or + * .d1_tx_id = xx_TX, + * .d0_rx_id = xx_RX, */ int d0_tx_id; int d0_rx_id; -- GitLab From 560f1187990c6c548756bf2f1183aa19d9c97413 Mon Sep 17 00:00:00 2001 From: Koen Beel Date: Wed, 30 May 2012 20:43:37 +0200 Subject: [PATCH 0174/6849] usb: gadget: ffs: add HID descriptor support. When writing the descriptors to the ep0 file of functionfs, the HID descriptors where not recognized which caused the initialization from user space to fail. Signed-off-by: Koen Beel Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index dcd1c7fbb016..8adc79d1b402 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -1671,6 +1672,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len, } break; + case HID_DT_HID: + pr_vdebug("hid descriptor\n"); + if (length != sizeof(struct hid_descriptor)) + goto inv_length; + break; + case USB_DT_OTG: if (length != sizeof(struct usb_otg_descriptor)) goto inv_length; -- GitLab From 0a00790ff4755f2e3eab907a43725cff59fc074b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 30 May 2012 13:25:57 -0700 Subject: [PATCH 0175/6849] usb: gadget: pch_udc: Fix likely misuse of | for & Using | with a constant is always true. Likely this should have be &. Signed-off-by: Joe Perches Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 1cfcc9ecbfbc..f4fb71c9ae08 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2208,7 +2208,7 @@ static void pch_udc_complete_receiver(struct pch_udc_ep *ep) return; } if ((td->status & PCH_UDC_BUFF_STS) == PCH_UDC_BS_DMA_DONE) - if (td->status | PCH_UDC_DMA_LAST) { + if (td->status & PCH_UDC_DMA_LAST) { count = td->status & PCH_UDC_RXTX_BYTES; break; } -- GitLab From 3de6e63f7845e99981e489ddccf70b3ec02fe00a Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Jun 2012 15:08:54 +0530 Subject: [PATCH 0176/6849] usb: gadget: uvc: Fix string descriptor STALL issue when multiple uvc functions are added to a configuration This patch solved the string descriptor STALL issue when we add multiple UVC functions in a single configuration using a 'webcam.c' like composite driver. Signed-off-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 2022fe492148..054c35a22fbf 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -619,22 +619,28 @@ uvc_bind_config(struct usb_configuration *c, uvc->desc.fs_streaming = fs_streaming; uvc->desc.hs_streaming = hs_streaming; - /* Allocate string descriptor numbers. */ - if ((ret = usb_string_id(c->cdev)) < 0) - goto error; - uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret; - uvc_iad.iFunction = ret; - - if ((ret = usb_string_id(c->cdev)) < 0) - goto error; - uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret; - uvc_control_intf.iInterface = ret; - - if ((ret = usb_string_id(c->cdev)) < 0) - goto error; - uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; - uvc_streaming_intf_alt0.iInterface = ret; - uvc_streaming_intf_alt1.iInterface = ret; + /* maybe allocate device-global string IDs, and patch descriptors */ + if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { + /* Allocate string descriptor numbers. */ + ret = usb_string_id(c->cdev); + if (ret < 0) + goto error; + uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret; + uvc_iad.iFunction = ret; + + ret = usb_string_id(c->cdev); + if (ret < 0) + goto error; + uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret; + uvc_control_intf.iInterface = ret; + + ret = usb_string_id(c->cdev); + if (ret < 0) + goto error; + uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; + uvc_streaming_intf_alt0.iInterface = ret; + uvc_streaming_intf_alt1.iInterface = ret; + } /* Register the function. */ uvc->func.name = "uvc"; -- GitLab From 5797663674b0d802f275761e71593b32b0849242 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Jun 2012 15:08:55 +0530 Subject: [PATCH 0177/6849] usb: gadget: uvc: Use macro for interrupt endpoint status size instead of using a MAGIC number This patch adds a MACRO for the UVC video control status (interrupt) endpoint and removes the magic number which was being used earlier. Some UDCs have issues supporting an interrupt IN endpoint having a max packet size less than a particular value (say 32). It is easier in that case to simply change the MACRO value instead of changing the max packet size value at a number of locations. Signed-off-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 054c35a22fbf..dd7d7a98ed43 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -59,6 +59,8 @@ static struct usb_gadget_strings *uvc_function_strings[] = { #define UVC_INTF_VIDEO_CONTROL 0 #define UVC_INTF_VIDEO_STREAMING 1 +#define STATUS_BYTECOUNT 16 /* 16 bytes status */ + static struct usb_interface_assoc_descriptor uvc_iad __initdata = { .bLength = sizeof(uvc_iad), .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, @@ -87,7 +89,7 @@ static struct usb_endpoint_descriptor uvc_control_ep __initdata = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(16), + .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), .bInterval = 8, }; @@ -95,7 +97,7 @@ static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = { .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, .bDescriptorType = USB_DT_CS_ENDPOINT, .bDescriptorSubType = UVC_EP_INTERRUPT, - .wMaxTransferSize = cpu_to_le16(16), + .wMaxTransferSize = cpu_to_le16(STATUS_BYTECOUNT), }; static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = { -- GitLab From fbcaba0e3dcec8451cccdc1fa92fcddbde2bc3f2 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Jun 2012 15:08:56 +0530 Subject: [PATCH 0178/6849] usb: gadget: uvc: Add super-speed support to UVC webcam gadget This patch adds super-speed support to UVC webcam gadget. Also in this patch: - We add the configurability to pass bInterval, bMaxBurst, mult factors for video streaming endpoint (ISOC IN) through module parameters. - We use config_ep_by_speed helper routine to configure video streaming endpoint. Signed-off-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 241 ++++++++++++++++++++++++++++++++---- drivers/usb/gadget/f_uvc.h | 8 +- drivers/usb/gadget/uvc.h | 4 +- drivers/usb/gadget/webcam.c | 29 ++++- 4 files changed, 247 insertions(+), 35 deletions(-) diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index dd7d7a98ed43..2a8bf0655c60 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -29,6 +29,25 @@ unsigned int uvc_gadget_trace_param; +/*-------------------------------------------------------------------------*/ + +/* module parameters specific to the Video streaming endpoint */ +static unsigned streaming_interval = 1; +module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(streaming_interval, "1 - 16"); + +static unsigned streaming_maxpacket = 1024; +module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(streaming_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); + +static unsigned streaming_mult; +module_param(streaming_mult, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(streaming_mult, "0 - 2 (hs/ss only)"); + +static unsigned streaming_maxburst; +module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); + /* -------------------------------------------------------------------------- * Function descriptors */ @@ -84,7 +103,7 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = { .iInterface = 0, }; -static struct usb_endpoint_descriptor uvc_control_ep __initdata = { +static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -124,7 +143,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = { .iInterface = 0, }; -static struct usb_endpoint_descriptor uvc_streaming_ep = { +static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -133,15 +152,72 @@ static struct usb_endpoint_descriptor uvc_streaming_ep = { .bInterval = 1, }; +static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .wMaxPacketSize = cpu_to_le16(1024), + .bInterval = 1, +}; + +/* super speed support */ +static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), + .bInterval = 8, +}; + +static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = { + .bLength = sizeof uvc_ss_control_comp, + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 3 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ + .wBytesPerInterval = cpu_to_le16(STATUS_BYTECOUNT), +}; + +static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .wMaxPacketSize = cpu_to_le16(1024), + .bInterval = 4, +}; + +static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { + .bLength = sizeof uvc_ss_streaming_comp, + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 3 values can be tweaked if necessary */ + .bMaxBurst = 0, + .bmAttributes = 0, + .wBytesPerInterval = cpu_to_le16(1024), +}; + static const struct usb_descriptor_header * const uvc_fs_streaming[] = { (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, - (struct usb_descriptor_header *) &uvc_streaming_ep, + (struct usb_descriptor_header *) &uvc_fs_streaming_ep, NULL, }; static const struct usb_descriptor_header * const uvc_hs_streaming[] = { (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, - (struct usb_descriptor_header *) &uvc_streaming_ep, + (struct usb_descriptor_header *) &uvc_hs_streaming_ep, + NULL, +}; + +static const struct usb_descriptor_header * const uvc_ss_streaming[] = { + (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, + (struct usb_descriptor_header *) &uvc_ss_streaming_ep, + (struct usb_descriptor_header *) &uvc_ss_streaming_comp, NULL, }; @@ -217,6 +293,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) struct uvc_device *uvc = to_uvc(f); struct v4l2_event v4l2_event; struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; + int ret; INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); @@ -264,7 +341,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) return 0; if (uvc->video.ep) { - uvc->video.ep->desc = &uvc_streaming_ep; + ret = config_ep_by_speed(f->config->cdev->gadget, + &(uvc->func), uvc->video.ep); + if (ret) + return ret; usb_ep_enable(uvc->video.ep); } @@ -370,9 +450,11 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) { struct uvc_input_header_descriptor *uvc_streaming_header; struct uvc_header_descriptor *uvc_control_header; + const struct uvc_descriptor_header * const *uvc_control_desc; const struct uvc_descriptor_header * const *uvc_streaming_cls; const struct usb_descriptor_header * const *uvc_streaming_std; const struct usb_descriptor_header * const *src; + static struct usb_endpoint_descriptor *uvc_control_ep; struct usb_descriptor_header **dst; struct usb_descriptor_header **hdr; unsigned int control_size; @@ -381,10 +463,29 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) unsigned int bytes; void *mem; - uvc_streaming_cls = (speed == USB_SPEED_FULL) - ? uvc->desc.fs_streaming : uvc->desc.hs_streaming; - uvc_streaming_std = (speed == USB_SPEED_FULL) - ? uvc_fs_streaming : uvc_hs_streaming; + switch (speed) { + case USB_SPEED_SUPER: + uvc_control_desc = uvc->desc.ss_control; + uvc_streaming_cls = uvc->desc.ss_streaming; + uvc_streaming_std = uvc_ss_streaming; + uvc_control_ep = &uvc_ss_control_ep; + break; + + case USB_SPEED_HIGH: + uvc_control_desc = uvc->desc.fs_control; + uvc_streaming_cls = uvc->desc.hs_streaming; + uvc_streaming_std = uvc_hs_streaming; + uvc_control_ep = &uvc_fs_control_ep; + break; + + case USB_SPEED_FULL: + default: + uvc_control_desc = uvc->desc.fs_control; + uvc_streaming_cls = uvc->desc.fs_streaming; + uvc_streaming_std = uvc_fs_streaming; + uvc_control_ep = &uvc_fs_control_ep; + break; + } /* Descriptors layout * @@ -402,16 +503,24 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) control_size = 0; streaming_size = 0; bytes = uvc_iad.bLength + uvc_control_intf.bLength - + uvc_control_ep.bLength + uvc_control_cs_ep.bLength + + uvc_control_ep->bLength + uvc_control_cs_ep.bLength + uvc_streaming_intf_alt0.bLength; - n_desc = 5; - for (src = (const struct usb_descriptor_header**)uvc->desc.control; *src; ++src) { + if (speed == USB_SPEED_SUPER) { + bytes += uvc_ss_control_comp.bLength; + n_desc = 6; + } else { + n_desc = 5; + } + + for (src = (const struct usb_descriptor_header **)uvc_control_desc; + *src; ++src) { control_size += (*src)->bLength; bytes += (*src)->bLength; n_desc++; } - for (src = (const struct usb_descriptor_header**)uvc_streaming_cls; *src; ++src) { + for (src = (const struct usb_descriptor_header **)uvc_streaming_cls; + *src; ++src) { streaming_size += (*src)->bLength; bytes += (*src)->bLength; n_desc++; @@ -435,12 +544,15 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) uvc_control_header = mem; UVC_COPY_DESCRIPTORS(mem, dst, - (const struct usb_descriptor_header**)uvc->desc.control); + (const struct usb_descriptor_header **)uvc_control_desc); uvc_control_header->wTotalLength = cpu_to_le16(control_size); uvc_control_header->bInCollection = 1; uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; - UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep); + UVC_COPY_DESCRIPTOR(mem, dst, uvc_control_ep); + if (speed == USB_SPEED_SUPER) + UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp); + UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep); UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0); @@ -448,7 +560,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) UVC_COPY_DESCRIPTORS(mem, dst, (const struct usb_descriptor_header**)uvc_streaming_cls); uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); - uvc_streaming_header->bEndpointAddress = uvc_streaming_ep.bEndpointAddress; + uvc_streaming_header->bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); @@ -484,6 +597,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) kfree(f->descriptors); kfree(f->hs_descriptors); + kfree(f->ss_descriptors); kfree(uvc); } @@ -498,8 +612,26 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) INFO(cdev, "uvc_function_bind\n"); + /* sanity check the streaming endpoint module parameters */ + if (streaming_interval < 1) + streaming_interval = 1; + if (streaming_interval > 16) + streaming_interval = 16; + if (streaming_mult > 2) + streaming_mult = 2; + if (streaming_maxburst > 15) + streaming_maxburst = 15; + + /* + * fill in the FS video streaming specific descriptors from the + * module parameters + */ + uvc_fs_streaming_ep.wMaxPacketSize = streaming_maxpacket > 1023 ? + 1023 : streaming_maxpacket; + uvc_fs_streaming_ep.bInterval = streaming_interval; + /* Allocate endpoints. */ - ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); + ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_control_ep); if (!ep) { INFO(cdev, "Unable to allocate control EP\n"); goto error; @@ -507,7 +639,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc->control_ep = ep; ep->driver_data = uvc; - ep = usb_ep_autoconfig(cdev->gadget, &uvc_streaming_ep); + ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); if (!ep) { INFO(cdev, "Unable to allocate streaming EP\n"); goto error; @@ -528,9 +660,52 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc_streaming_intf_alt1.bInterfaceNumber = ret; uvc->streaming_intf = ret; - /* Copy descriptors. */ + /* sanity check the streaming endpoint module parameters */ + if (streaming_maxpacket > 1024) + streaming_maxpacket = 1024; + + /* Copy descriptors for FS. */ f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); - f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); + + /* support high speed hardware */ + if (gadget_is_dualspeed(cdev->gadget)) { + /* + * Fill in the HS descriptors from the module parameters for the + * Video Streaming endpoint. + * NOTE: We assume that the user knows what they are doing and + * won't give parameters that their UDC doesn't support. + */ + uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket; + uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11; + uvc_hs_streaming_ep.bInterval = streaming_interval; + uvc_hs_streaming_ep.bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; + + /* Copy descriptors. */ + f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); + } + + /* support super speed hardware */ + if (gadget_is_superspeed(c->cdev->gadget)) { + /* + * Fill in the SS descriptors from the module parameters for the + * Video Streaming endpoint. + * NOTE: We assume that the user knows what they are doing and + * won't give parameters that their UDC doesn't support. + */ + uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket; + uvc_ss_streaming_ep.bInterval = streaming_interval; + uvc_ss_streaming_comp.bmAttributes = streaming_mult; + uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst; + uvc_ss_streaming_comp.wBytesPerInterval = + streaming_maxpacket * (streaming_mult + 1) * + (streaming_maxburst + 1); + uvc_ss_streaming_ep.bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; + + /* Copy descriptors. */ + f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER); + } /* Preallocate control endpoint request. */ uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); @@ -585,9 +760,11 @@ error: */ int __init uvc_bind_config(struct usb_configuration *c, - const struct uvc_descriptor_header * const *control, + const struct uvc_descriptor_header * const *fs_control, + const struct uvc_descriptor_header * const *ss_control, const struct uvc_descriptor_header * const *fs_streaming, - const struct uvc_descriptor_header * const *hs_streaming) + const struct uvc_descriptor_header * const *hs_streaming, + const struct uvc_descriptor_header * const *ss_streaming) { struct uvc_device *uvc; int ret = 0; @@ -605,21 +782,31 @@ uvc_bind_config(struct usb_configuration *c, uvc->state = UVC_STATE_DISCONNECTED; /* Validate the descriptors. */ - if (control == NULL || control[0] == NULL || - control[0]->bDescriptorSubType != UVC_VC_HEADER) + if (fs_control == NULL || fs_control[0] == NULL || + fs_control[0]->bDescriptorSubType != UVC_VC_HEADER) + goto error; + + if (ss_control == NULL || ss_control[0] == NULL || + ss_control[0]->bDescriptorSubType != UVC_VC_HEADER) goto error; if (fs_streaming == NULL || fs_streaming[0] == NULL || - fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) + fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; if (hs_streaming == NULL || hs_streaming[0] == NULL || - hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) + hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) + goto error; + + if (ss_streaming == NULL || ss_streaming[0] == NULL || + ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; - uvc->desc.control = control; + uvc->desc.fs_control = fs_control; + uvc->desc.ss_control = ss_control; uvc->desc.fs_streaming = fs_streaming; uvc->desc.hs_streaming = hs_streaming; + uvc->desc.ss_streaming = ss_streaming; /* maybe allocate device-global string IDs, and patch descriptors */ if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/f_uvc.h index abf832935134..c3d258d30188 100644 --- a/drivers/usb/gadget/f_uvc.h +++ b/drivers/usb/gadget/f_uvc.h @@ -17,9 +17,11 @@ #include extern int uvc_bind_config(struct usb_configuration *c, - const struct uvc_descriptor_header * const *control, - const struct uvc_descriptor_header * const *fs_streaming, - const struct uvc_descriptor_header * const *hs_streaming); + const struct uvc_descriptor_header * const *fs_control, + const struct uvc_descriptor_header * const *hs_control, + const struct uvc_descriptor_header * const *fs_streaming, + const struct uvc_descriptor_header * const *hs_streaming, + const struct uvc_descriptor_header * const *ss_streaming); #endif /* _F_UVC_H_ */ diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index ca4e03a1c73a..93b0c1191115 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -153,9 +153,11 @@ struct uvc_device /* Descriptors */ struct { - const struct uvc_descriptor_header * const *control; + const struct uvc_descriptor_header * const *fs_control; + const struct uvc_descriptor_header * const *ss_control; const struct uvc_descriptor_header * const *fs_streaming; const struct uvc_descriptor_header * const *hs_streaming; + const struct uvc_descriptor_header * const *ss_streaming; } desc; unsigned int control_intf; diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 668fe128f2ef..120e134e805e 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -272,7 +272,15 @@ static const struct uvc_color_matching_descriptor uvc_color_matching = { .bMatrixCoefficients = 4, }; -static const struct uvc_descriptor_header * const uvc_control_cls[] = { +static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { + (const struct uvc_descriptor_header *) &uvc_control_header, + (const struct uvc_descriptor_header *) &uvc_camera_terminal, + (const struct uvc_descriptor_header *) &uvc_processing, + (const struct uvc_descriptor_header *) &uvc_output_terminal, + NULL, +}; + +static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = { (const struct uvc_descriptor_header *) &uvc_control_header, (const struct uvc_descriptor_header *) &uvc_camera_terminal, (const struct uvc_descriptor_header *) &uvc_processing, @@ -304,6 +312,18 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { NULL, }; +static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { + (const struct uvc_descriptor_header *) &uvc_input_header, + (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, + (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, + (const struct uvc_descriptor_header *) &uvc_color_matching, + NULL, +}; + /* -------------------------------------------------------------------------- * USB configuration */ @@ -311,8 +331,9 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { static int __init webcam_config_bind(struct usb_configuration *c) { - return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls, - uvc_hs_streaming_cls); + return uvc_bind_config(c, uvc_fs_control_cls, uvc_ss_control_cls, + uvc_fs_streaming_cls, uvc_hs_streaming_cls, + uvc_ss_streaming_cls); } static struct usb_configuration webcam_config_driver = { @@ -373,7 +394,7 @@ static struct usb_composite_driver webcam_driver = { .name = "g_webcam", .dev = &webcam_device_descriptor, .strings = webcam_device_strings, - .max_speed = USB_SPEED_HIGH, + .max_speed = USB_SPEED_SUPER, .unbind = webcam_unbind, }; -- GitLab From 206dd69a62a06197b308fa0decfd0b649fcc2811 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Mon, 21 May 2012 12:42:54 +0530 Subject: [PATCH 0179/6849] USB: DWC3: Generate interrupt on each TRB as default option Currently in case of isoc, interrupt is programmed after each TRB_NUM/4 ie 8th TRB. A TRB is programmed against each submitted request from gadget. If we do not want to limit the minimum number of necessary request to be submitted from gadget then we must receive interrupt on each TRB submission. There can be such situation with a gadget working with ping-pong buffer. If a gadget does not want to receive interrupt after each request completion then it may set no_interrupt flag. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a9fc7c4a5a20..be87e82b36c7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -766,8 +766,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, case USB_ENDPOINT_XFER_ISOC: trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; - /* IOC every DWC3_TRB_NUM / 4 so we can refill */ - if (!(cur_slot % (DWC3_TRB_NUM / 4))) + if (!req->request.no_interrupt) trb->ctrl |= DWC3_TRB_CTRL_IOC; break; -- GitLab From 389f2828bb2a5f2acde9bdeffde02743684c1d86 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Mon, 21 May 2012 12:46:26 +0530 Subject: [PATCH 0180/6849] USB: DWC3: Correct DWC3_TRB_SIZE_TRBSTS definition Correct define for DWC3_TRB_SIZE_TRBSTS. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 4d5c63dae14d..ce43b1f5f341 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -495,7 +495,7 @@ enum dwc3_device_state { #define DWC3_TRB_SIZE_MASK (0x00ffffff) #define DWC3_TRB_SIZE_LENGTH(n) ((n) & DWC3_TRB_SIZE_MASK) #define DWC3_TRB_SIZE_PCM1(n) (((n) & 0x03) << 24) -#define DWC3_TRB_SIZE_TRBSTS(n) (((n) & (0x0f << 28) >> 28)) +#define DWC3_TRB_SIZE_TRBSTS(n) (((n) & (0x0f << 28)) >> 28) #define DWC3_TRBSTS_OK 0 #define DWC3_TRBSTS_MISSED_ISOC 1 -- GitLab From d05b81824e672a48b3566634622849866de2b787 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Mon, 21 May 2012 14:51:30 +0530 Subject: [PATCH 0181/6849] USB: DWC3: Correct DWC3_DSTS_SOFFN_MASK definition SOF Number is bit16:3 of DSTS. Correct the mask accordingly. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ce43b1f5f341..e402022b9e15 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -291,7 +291,7 @@ #define DWC3_DSTS_RXFIFOEMPTY (1 << 17) -#define DWC3_DSTS_SOFFN_MASK (0x3ff << 3) +#define DWC3_DSTS_SOFFN_MASK (0x3fff << 3) #define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3) #define DWC3_DSTS_CONNECTSPD (7 << 0) -- GitLab From d6d6ec7b8854ab62f7f3907656d5d29eb47532e7 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Fri, 25 May 2012 18:54:56 +0530 Subject: [PATCH 0182/6849] usb: dwc3: Fix missed isoc IN transaction If an IN transfer is missed on isoc endpoint, then driver must insure that next ep_queue is properly handled. This patch fixes this issue by starting a new transfer for next queued request. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 3 ++ drivers/usb/dwc3/gadget.c | 73 ++++++++++++++++++++++++++------------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e402022b9e15..fcb8be2ec1c9 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -405,6 +405,7 @@ struct dwc3_event_buffer { * @number: endpoint number (1 - 15) * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK * @res_trans_idx: Resource transfer index + * @current_uf: Current uf received through last event parameter * @interval: the intervall on which the ISOC transfer is started * @name: a human readable name e.g. ep1out-bulk * @direction: true for TX, false for RX @@ -428,6 +429,7 @@ struct dwc3_ep { #define DWC3_EP_WEDGE (1 << 2) #define DWC3_EP_BUSY (1 << 4) #define DWC3_EP_PENDING_REQUEST (1 << 5) +#define DWC3_EP_MISSED_ISOC (1 << 6) /* This last one is specific to EP0 */ #define DWC3_EP0_DIR_IN (1 << 31) @@ -437,6 +439,7 @@ struct dwc3_ep { u8 number; u8 type; u8 res_trans_idx; + u16 current_uf; u32 interval; char name[20]; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index be87e82b36c7..0cab69e51380 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -990,6 +990,34 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, return 0; } +static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, + struct dwc3_ep *dep, u32 cur_uf) +{ + u32 uf; + + if (list_empty(&dep->request_list)) { + dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", + dep->name); + return; + } + + /* 4 micro frames in the future */ + uf = cur_uf + dep->interval * 4; + + __dwc3_gadget_kick_transfer(dep, uf, 1); +} + +static void dwc3_gadget_start_isoc(struct dwc3 *dwc, + struct dwc3_ep *dep, const struct dwc3_event_depevt *event) +{ + u32 cur_uf, mask; + + mask = ~(dep->interval - 1); + cur_uf = event->parameters & mask; + + __dwc3_gadget_start_isoc(dwc, dep, cur_uf); +} + static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) { struct dwc3 *dwc = dep->dwc; @@ -1019,8 +1047,14 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) list_add_tail(&req->list, &dep->request_list); - if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && (dep->flags & DWC3_EP_BUSY)) - dep->flags |= DWC3_EP_PENDING_REQUEST; + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { + if (dep->flags & DWC3_EP_BUSY) { + dep->flags |= DWC3_EP_PENDING_REQUEST; + } else if (dep->flags & DWC3_EP_MISSED_ISOC) { + __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf); + dep->flags &= ~DWC3_EP_MISSED_ISOC; + } + } /* * There are two special cases: @@ -1591,6 +1625,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_trb *trb; unsigned int count; unsigned int s_pkt = 0; + unsigned int trb_status; do { req = next_request(&dep->req_queued); @@ -1616,9 +1651,18 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, if (dep->direction) { if (count) { - dev_err(dwc->dev, "incomplete IN transfer %s\n", - dep->name); - status = -ECONNRESET; + trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); + if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { + dev_dbg(dwc->dev, "incomplete IN transfer %s\n", + dep->name); + dep->current_uf = event->parameters & + ~(dep->interval - 1); + dep->flags |= DWC3_EP_MISSED_ISOC; + } else { + dev_err(dwc->dev, "incomplete IN transfer %s\n", + dep->name); + status = -ECONNRESET; + } } } else { if (count && (event->status & DEPEVT_STATUS_SHORT)) @@ -1690,25 +1734,6 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, } } -static void dwc3_gadget_start_isoc(struct dwc3 *dwc, - struct dwc3_ep *dep, const struct dwc3_event_depevt *event) -{ - u32 uf, mask; - - if (list_empty(&dep->request_list)) { - dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", - dep->name); - return; - } - - mask = ~(dep->interval - 1); - uf = event->parameters & mask; - /* 4 micro frames in the future */ - uf += dep->interval * 4; - - __dwc3_gadget_kick_transfer(dep, uf, 1); -} - static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { -- GitLab From 70b674bfeb735557fc03cdc125ffe6d34218fcfd Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Sun, 3 Jun 2012 19:43:19 +0530 Subject: [PATCH 0183/6849] usb: dwc3: Fix break from cleanup request loop If event status says that its last completed TRB but TRB is still owned by HW then break from the loop, because we are not going to get correct TRB status from trb control/size register. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0cab69e51380..854f3a3c8832 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1681,7 +1681,8 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, if (s_pkt) break; if ((event->status & DEPEVT_STATUS_LST) && - (trb->ctrl & DWC3_TRB_CTRL_LST)) + (trb->ctrl & (DWC3_TRB_CTRL_LST | + DWC3_TRB_CTRL_HWO))) break; if ((event->status & DEPEVT_STATUS_IOC) && (trb->ctrl & DWC3_TRB_CTRL_IOC)) -- GitLab From 90ba9b1986b5ac4b2d184575847147ea7c4280a2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 3 Jun 2012 19:50:43 +0000 Subject: [PATCH 0184/6849] tcp: tcp_make_synack() can use alloc_skb() There is no value using sock_wmalloc() in tcp_make_synack(). A listener socket only sends SYNACK packets, they are not queued in a socket queue, only in Qdisc and device layers, so the number of in flight packets is limited in these layers. We used sock_wmalloc() with the %force parameter set to 1 to ignore socket limits anyway. This patch removes two atomic operations per SYNACK packet. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 803cbfe82fbc..f0b0e4414b00 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2461,7 +2461,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) s_data_desired = cvp->s_data_desired; - skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC); + skb = alloc_skb(MAX_TCP_HEADER + 15 + s_data_desired, GFP_ATOMIC); if (skb == NULL) return NULL; -- GitLab From 4aea39c11c610e411768649fdc04777903ebfe07 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 3 Jun 2012 20:33:21 +0000 Subject: [PATCH 0185/6849] tcp: tcp_make_synack() consumes dst parameter tcp_make_synack() clones the dst, and callers release it. We can avoid two atomic operations per SYNACK if tcp_make_synack() consumes dst instead of cloning it. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 1 - net/ipv4/tcp_output.c | 18 ++++++++++++++---- net/ipv6/tcp_ipv6.c | 1 - 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index c8d28c433b2b..3d9c1a4b8819 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -848,7 +848,6 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, err = net_xmit_eval(err); } - dst_release(dst); return err; } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f0b0e4414b00..c465d3e51e28 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2442,7 +2442,16 @@ int tcp_send_synack(struct sock *sk) return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); } -/* Prepare a SYN-ACK. */ +/** + * tcp_make_synack - Prepare a SYN-ACK. + * sk: listener socket + * dst: dst entry attached to the SYNACK + * req: request_sock pointer + * rvp: request_values pointer + * + * Allocate one skb and build a SYNACK packet. + * @dst is consumed : Caller should not use it again. + */ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, struct request_values *rvp) @@ -2462,13 +2471,14 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) s_data_desired = cvp->s_data_desired; skb = alloc_skb(MAX_TCP_HEADER + 15 + s_data_desired, GFP_ATOMIC); - if (skb == NULL) + if (unlikely(!skb)) { + dst_release(dst); return NULL; - + } /* Reserve space for headers. */ skb_reserve(skb, MAX_TCP_HEADER); - skb_dst_set(skb, dst_clone(dst)); + skb_dst_set(skb, dst); mss = dst_metric_advmss(dst); if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3a9aec29581a..80758255556c 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -522,7 +522,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, done: if (opt && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); - dst_release(dst); return err; } -- GitLab From 5d0ba55b6486f58cc890918d7167063d83f7fbb4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Jun 2012 01:17:19 +0000 Subject: [PATCH 0186/6849] net: use consume_skb() in place of kfree_skb() Remove some dropwatch/drop_monitor false positives. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/atm/lec.c | 6 ++++-- net/atm/pppoatm.c | 2 +- net/ax25/ax25_out.c | 2 +- net/ax25/ax25_route.c | 2 +- net/decnet/dn_neigh.c | 6 +++--- net/ipv4/ip_output.c | 4 ++-- net/netfilter/ipvs/ip_vs_xmit.c | 4 ++-- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/net/atm/lec.c b/net/atm/lec.c index a7d172105c99..3da125c384ea 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -231,9 +231,11 @@ static netdev_tx_t lec_start_xmit(struct sk_buff *skb, if (skb_headroom(skb) < 2) { pr_debug("reallocating skb\n"); skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); - kfree_skb(skb); - if (skb2 == NULL) + if (unlikely(!skb2)) { + kfree_skb(skb); return NETDEV_TX_OK; + } + consume_skb(skb); skb = skb2; } skb_push(skb, 2); diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index ce1e59fdae7b..226dca989448 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c @@ -283,7 +283,7 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb) kfree_skb(n); goto nospace; } - kfree_skb(skb); + consume_skb(skb); skb = n; if (skb == NULL) return DROP_PACKET; diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c index be8a25e0db65..be2acab9be9d 100644 --- a/net/ax25/ax25_out.c +++ b/net/ax25/ax25_out.c @@ -350,7 +350,7 @@ void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type) if (skb->sk != NULL) skb_set_owner_w(skbn, skb->sk); - kfree_skb(skb); + consume_skb(skb); skb = skbn; } diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index a65588040b9e..d39097737e38 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c @@ -474,7 +474,7 @@ struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src, if (skb->sk != NULL) skb_set_owner_w(skbn, skb->sk); - kfree_skb(skb); + consume_skb(skb); skb = skbn; } diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index ac90f658586c..8e9a35b17df4 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -240,7 +240,7 @@ static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) kfree_skb(skb); return -ENOBUFS; } - kfree_skb(skb); + consume_skb(skb); skb = skb2; net_info_ratelimited("dn_long_output: Increasing headroom\n"); } @@ -283,7 +283,7 @@ static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) kfree_skb(skb); return -ENOBUFS; } - kfree_skb(skb); + consume_skb(skb); skb = skb2; net_info_ratelimited("dn_short_output: Increasing headroom\n"); } @@ -322,7 +322,7 @@ static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) kfree_skb(skb); return -ENOBUFS; } - kfree_skb(skb); + consume_skb(skb); skb = skb2; net_info_ratelimited("dn_phase3_output: Increasing headroom\n"); } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 451f97c42eb4..b99ca4e154b9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -200,7 +200,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) } if (skb->sk) skb_set_owner_w(skb2, skb->sk); - kfree_skb(skb); + consume_skb(skb); skb = skb2; } @@ -709,7 +709,7 @@ slow_path: IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGCREATES); } - kfree_skb(skb); + consume_skb(skb); IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGOKS); return err; diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 7fd66dec859d..71d6ecb65926 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -823,7 +823,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_ERR_RL("%s(): no memory\n", __func__); return NF_STOLEN; } - kfree_skb(skb); + consume_skb(skb); skb = new_skb; old_iph = ip_hdr(skb); } @@ -942,7 +942,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_ERR_RL("%s(): no memory\n", __func__); return NF_STOLEN; } - kfree_skb(skb); + consume_skb(skb); skb = new_skb; old_iph = ipv6_hdr(skb); } -- GitLab From d594e987c6f5417cc63dd7e107a2a03a7eeee03f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Jun 2012 03:50:35 +0000 Subject: [PATCH 0187/6849] sock_diag: add SK_MEMINFO_BACKLOG Adding socket backlog len in INET_DIAG_SKMEMINFO is really useful to diagnose various TCP problems. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/sock_diag.h | 1 + net/core/sock_diag.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index db4bae78bda9..6793fac5eab5 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h @@ -18,6 +18,7 @@ enum { SK_MEMINFO_FWD_ALLOC, SK_MEMINFO_WMEM_QUEUED, SK_MEMINFO_OPTMEM, + SK_MEMINFO_BACKLOG, SK_MEMINFO_VARS, }; diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 5fd146720f39..0d934ce1075f 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -46,6 +46,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype) mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); + mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len; return 0; -- GitLab From abf710e655fe843afe0ab6a56e344567d933b018 Mon Sep 17 00:00:00 2001 From: Vikram Pandita Date: Fri, 18 May 2012 13:48:04 -0700 Subject: [PATCH 0188/6849] usb: musb: handle nuked ep dma interrupt User can trigger disabling of gadget at run time while the transfers are going on. Eg: 1: rmmod of musb driver while transfers are going on Eg: 2: On android doing: echo 0 > /sys/class/android_usb/android0/enable While a big file transfer is going on via PTP/MTP. In such a case, musb_gadget_disable() calls nuke() but the dma interrupt may still happen for an endpoint since hw would raise the interrupt in anycase. This can result in a NULL pointer access crash: [ 314.030426] PC is at txstate+0x74/0x20c [ 314.034759] LR is at musb_g_tx+0x140/0x204 [ 314.039489] pc : [] lr : [] psr: 20000193 [ 314.039520] sp : c783bc68 ip : 00000002 fp : c783bc9c [ 314.052429] r10: 00000018 r9 : 00000000 r8 : 00000200 [ 314.058258] r7 : 00000000 r6 : fc0ab130 r5 : c781a410 r4 : c6caf640 [ 314.065643] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : c781a000 [ 315.083251] Backtrace: [ 315.086242] [] (txstate+0x0/0x20c) from [] (musb_g_tx+0x140/0x204) [ 315.095123] [] (musb_g_tx+0x0/0x204) from [] (musb_dma_completion+0x40/0x54) [ 315.104980] [] (musb_dma_completion+0x0/0x54) from [] (dma_controller_irq+0x118/0x184) [ 315.115661] [] (dma_controller_irq+0x0/0x184) from [] (handle_irq_event_percpu+0x54/0x188) So put protection in code to handle possiblity of getting an interrupt for an endpoint that might have been already nuked. Reported-by: Todd Poynor Signed-off-by: Vikram Pandita Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index f42c29b11f71..695c892e70e7 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -328,6 +328,13 @@ static void txstate(struct musb *musb, struct musb_request *req) musb_ep = req->ep; + /* Check if EP is disabled */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_ep->end_point.name); + return; + } + /* we shouldn't get here while DMA is active ... but we do ... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { dev_dbg(musb->controller, "dma pending...\n"); @@ -650,6 +657,13 @@ static void rxstate(struct musb *musb, struct musb_request *req) len = musb_ep->packet_sz; + /* Check if EP is disabled */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_ep->end_point.name); + return; + } + /* We shouldn't get here while DMA is active, but we do... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { dev_dbg(musb->controller, "DMA pending...\n"); -- GitLab From 2ed9127cff9a255b7671b8d3d938109f68a87961 Mon Sep 17 00:00:00 2001 From: Mantesh Sarasetti Date: Fri, 1 Jun 2012 14:54:30 +0300 Subject: [PATCH 0189/6849] usb: musb: host: Disable MUSB DMA mode incase of DMA channel request failure Currently in case of MUSB DMA channel request failure we are not clearing MUSB_RXCSR_DMAENAB, MUSB_RXCSR_H_AUTOREQ and MUSB_RXCSR_AUTOCLEAR bits of MUSB RXCSR of MUSB DMA. Which is causing failure in receipt of data packets in next transfer. Fix is to disable the MUSB DMA mode and related bits incase of DMA channel request fails Signed-off-by: Mantesh Sarashetti Signed-off-by: Ruslan Bilovol Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_host.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ef8d744800ac..33fc45151b8f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1736,7 +1736,11 @@ void musb_host_rx(struct musb *musb, u8 epnum) c->channel_release(dma); hw_ep->rx_channel = NULL; dma = NULL; - /* REVISIT reset CSR */ + val = musb_readw(epio, MUSB_RXCSR); + val &= ~(MUSB_RXCSR_DMAENAB + | MUSB_RXCSR_H_AUTOREQ + | MUSB_RXCSR_AUTOCLEAR); + musb_writew(epio, MUSB_RXCSR, val); } } #endif /* Mentor DMA */ -- GitLab From 29a6b6c060445eb46528785d51a2d8b0e6d898c4 Mon Sep 17 00:00:00 2001 From: Raffaele Recalcati Date: Sun, 3 Jun 2012 10:43:43 +0000 Subject: [PATCH 0190/6849] net/ethernet: ks8851_mll mac address configuration support added Signed-off-by: Raffaele Recalcati Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851_mll.c | 25 +++++++++++++----- include/linux/ks8851_mll.h | 33 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 include/linux/ks8851_mll.h diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 5ffde23ac8fb..70bd329882c6 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #define DRV_NAME "ks8851_mll" @@ -1515,6 +1515,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev) struct net_device *netdev; struct ks_net *ks; u16 id, data; + struct ks8851_mll_platform_data *pdata; io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0); io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -1596,17 +1597,27 @@ static int __devinit ks8851_probe(struct platform_device *pdev) ks_disable_qmu(ks); ks_setup(ks); ks_setup_int(ks); - memcpy(netdev->dev_addr, ks->mac_addr, 6); data = ks_rdreg16(ks, KS_OBCR); ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA); - /** - * If you want to use the default MAC addr, - * comment out the 2 functions below. - */ + /* overwriting the default MAC address */ + pdata = pdev->dev.platform_data; + if (!pdata) { + netdev_err(netdev, "No platform data\n"); + err = -ENODEV; + goto err_register; + } + memcpy(ks->mac_addr, pdata->mac_addr, 6); + if (!is_valid_ether_addr(ks->mac_addr)) { + /* Use random MAC address if none passed */ + random_ether_addr(ks->mac_addr); + netdev_info(netdev, "Using random mac address\n"); + } + netdev_info(netdev, "Mac address is: %pM\n", ks->mac_addr); + + memcpy(netdev->dev_addr, ks->mac_addr, 6); - random_ether_addr(netdev->dev_addr); ks_set_mac(ks, netdev->dev_addr); id = ks_rdreg16(ks, KS_CIDER); diff --git a/include/linux/ks8851_mll.h b/include/linux/ks8851_mll.h new file mode 100644 index 000000000000..e9ccfb59ed30 --- /dev/null +++ b/include/linux/ks8851_mll.h @@ -0,0 +1,33 @@ +/* + * ks8861_mll platform data struct definition + * Copyright (c) 2012 BTicino S.p.A. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _LINUX_KS8851_MLL_H +#define _LINUX_KS8851_MLL_H + +#include + +/** + * struct ks8851_mll_platform_data - Platform data of the KS8851_MLL network driver + * @macaddr: The MAC address of the device, set to all 0:s to use the on in + * the chip. + */ +struct ks8851_mll_platform_data { + u8 mac_addr[ETH_ALEN]; +}; + +#endif -- GitLab From e3192690a3c889767d1161b228374f4926d92af0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 3 Jun 2012 17:41:40 +0000 Subject: [PATCH 0191/6849] net: Remove casts to same type Adding casts of objects to the same type is unnecessary and confusing for a human reader. For example, this cast: int y; int *p = (int *)&y; I used the coccinelle script below to find and remove these unnecessary casts. I manually removed the conversions this script produces of casts with __force and __user. @@ type T; T *p; @@ - (T *)p + p Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/9p/client.c | 2 +- net/atm/lec.c | 2 +- net/decnet/dn_nsp_out.c | 2 +- net/ipv4/af_inet.c | 2 +- net/ipv4/fib_trie.c | 13 ++++++------- net/ipv4/netfilter/nf_nat_snmp_basic.c | 4 ++-- net/ipv6/exthdrs.c | 4 ++-- net/irda/irqueue.c | 6 +++--- net/l2tp/l2tp_ppp.c | 8 ++++---- net/mac80211/scan.c | 3 +-- net/netfilter/nf_conntrack_core.c | 2 +- net/packet/af_packet.c | 9 ++++----- net/tipc/port.c | 9 ++++----- net/tipc/socket.c | 2 +- 14 files changed, 32 insertions(+), 36 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index a170893d70e0..5cbea903a5ab 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1548,7 +1548,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, kernel_buf = 1; indata = data; } else - indata = (char *)udata; + indata = udata; /* * response header len is 11 * PDU Header(7) + IO Size (4) diff --git a/net/atm/lec.c b/net/atm/lec.c index 3da125c384ea..2e3d942e77f1 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -1604,7 +1604,7 @@ static void lec_arp_expire_vcc(unsigned long data) { unsigned long flags; struct lec_arp_table *to_remove = (struct lec_arp_table *)data; - struct lec_priv *priv = (struct lec_priv *)to_remove->priv; + struct lec_priv *priv = to_remove->priv; del_timer(&to_remove->timer); diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index 564a6ad13ce7..8a96047c7c94 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -322,7 +322,7 @@ static __le16 *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, unsigned c /* Set "cross subchannel" bit in ackcrs */ ackcrs |= 0x2000; - ptr = (__le16 *)dn_mk_common_header(scp, skb, msgflag, hlen); + ptr = dn_mk_common_header(scp, skb, msgflag, hlen); *ptr++ = cpu_to_le16(acknum); *ptr++ = cpu_to_le16(ackcrs); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index c8f7aee587d1..e4e8e00a2c91 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -553,7 +553,7 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr, if (!inet_sk(sk)->inet_num && inet_autobind(sk)) return -EAGAIN; - return sk->sk_prot->connect(sk, (struct sockaddr *)uaddr, addr_len); + return sk->sk_prot->connect(sk, uaddr, addr_len); } EXPORT_SYMBOL(inet_dgram_connect); diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 30b88d7b4bd6..18cbc15b20d5 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1007,9 +1007,9 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) while (tn != NULL && (tp = node_parent((struct rt_trie_node *)tn)) != NULL) { cindex = tkey_extract_bits(key, tp->pos, tp->bits); wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); - tn = (struct tnode *) resize(t, (struct tnode *)tn); + tn = (struct tnode *)resize(t, tn); - tnode_put_child_reorg((struct tnode *)tp, cindex, + tnode_put_child_reorg(tp, cindex, (struct rt_trie_node *)tn, wasfull); tp = node_parent((struct rt_trie_node *) tn); @@ -1024,7 +1024,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) /* Handle last (top) tnode */ if (IS_TNODE(tn)) - tn = (struct tnode *)resize(t, (struct tnode *)tn); + tn = (struct tnode *)resize(t, tn); rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); tnode_free_flush(); @@ -1125,7 +1125,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) node_set_parent((struct rt_trie_node *)l, tp); cindex = tkey_extract_bits(key, tp->pos, tp->bits); - put_child(t, (struct tnode *)tp, cindex, (struct rt_trie_node *)l); + put_child(t, tp, cindex, (struct rt_trie_node *)l); } else { /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */ /* @@ -1160,8 +1160,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) if (tp) { cindex = tkey_extract_bits(key, tp->pos, tp->bits); - put_child(t, (struct tnode *)tp, cindex, - (struct rt_trie_node *)tn); + put_child(t, tp, cindex, (struct rt_trie_node *)tn); } else { rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn); tp = tn; @@ -1620,7 +1619,7 @@ static void trie_leaf_remove(struct trie *t, struct leaf *l) if (tp) { t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits); - put_child(t, (struct tnode *)tp, cindex, NULL); + put_child(t, tp, cindex, NULL); trie_rebalance(t, tp); } else RCU_INIT_POINTER(t->trie, NULL); diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 746edec8b86e..bac712293fd6 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -405,7 +405,7 @@ static unsigned char asn1_octets_decode(struct asn1_ctx *ctx, ptr = *octets; while (ctx->pointer < eoc) { - if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) { + if (!asn1_octet_decode(ctx, ptr++)) { kfree(*octets); *octets = NULL; return 0; @@ -759,7 +759,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, } break; case SNMP_OBJECTID: - if (!asn1_oid_decode(ctx, end, (unsigned long **)&lp, &len)) { + if (!asn1_oid_decode(ctx, end, &lp, &len)) { kfree(id); return 0; } diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 6447dc49429f..fa3d9c328092 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -791,14 +791,14 @@ static int ipv6_renew_option(void *ohdr, if (ohdr) { memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr)); *hdr = (struct ipv6_opt_hdr *)*p; - *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr)); + *p += CMSG_ALIGN(ipv6_optlen(*hdr)); } } else { if (newopt) { if (copy_from_user(*p, newopt, newoptlen)) return -EFAULT; *hdr = (struct ipv6_opt_hdr *)*p; - if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen) + if (ipv6_optlen(*hdr) > newoptlen) return -EINVAL; *p += CMSG_ALIGN(newoptlen); } diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index f06947c4fa82..7152624ed5f1 100644 --- a/net/irda/irqueue.c +++ b/net/irda/irqueue.c @@ -523,7 +523,7 @@ void *hashbin_remove_first( hashbin_t *hashbin) * Dequeue the entry... */ dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ], - (irda_queue_t*) entry ); + entry); hashbin->hb_size--; entry->q_next = NULL; entry->q_prev = NULL; @@ -615,7 +615,7 @@ void* hashbin_remove( hashbin_t* hashbin, long hashv, const char* name) */ if ( found ) { dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ], - (irda_queue_t*) entry ); + entry); hashbin->hb_size--; /* @@ -685,7 +685,7 @@ void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry) * Dequeue the entry... */ dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ], - (irda_queue_t*) entry ); + entry); hashbin->hb_size--; entry->q_next = NULL; entry->q_prev = NULL; diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 8ef6b9416cba..286366ef8930 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -1522,8 +1522,8 @@ static int pppol2tp_session_getsockopt(struct sock *sk, * handler, according to whether the PPPoX socket is a for a regular session * or the special tunnel type. */ -static int pppol2tp_getsockopt(struct socket *sock, int level, - int optname, char __user *optval, int __user *optlen) +static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; struct l2tp_session *session; @@ -1535,7 +1535,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, if (level != SOL_PPPOL2TP) return udp_prot.getsockopt(sk, level, optname, optval, optlen); - if (get_user(len, (int __user *) optlen)) + if (get_user(len, optlen)) return -EFAULT; len = min_t(unsigned int, len, sizeof(int)); @@ -1568,7 +1568,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, err = pppol2tp_session_getsockopt(sk, session, optname, &val); err = -EFAULT; - if (put_user(len, (int __user *) optlen)) + if (put_user(len, optlen)) goto end_put_sess; if (copy_to_user((void __user *) optval, &val, len)) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 169da0742c81..6d90a562669f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -114,8 +114,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, if (elems->tim && (!elems->parse_error || !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { - struct ieee80211_tim_ie *tim_ie = - (struct ieee80211_tim_ie *)elems->tim; + struct ieee80211_tim_ie *tim_ie = elems->tim; bss->dtim_period = tim_ie->dtim_period; if (!elems->parse_error) bss->valid_data |= IEEE80211_BSS_VALID_DTIM; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ac3af97cc468..95976a593b98 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -531,7 +531,7 @@ __nf_conntrack_confirm(struct sk_buff *skb) tstamp = nf_conn_tstamp_find(ct); if (tstamp) { if (skb->tstamp.tv64 == 0) - __net_timestamp((struct sk_buff *)skb); + __net_timestamp(skb); tstamp->start = ktime_to_ns(skb->tstamp); } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 0f661745df0f..71ac6559e0c6 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -592,7 +592,7 @@ static void init_prb_bdqc(struct packet_sock *po, p1->knxt_seq_num = 1; p1->pkbdq = pg_vec; pbd = (struct tpacket_block_desc *)pg_vec[0].buffer; - p1->pkblk_start = (char *)pg_vec[0].buffer; + p1->pkblk_start = pg_vec[0].buffer; p1->kblk_size = req_u->req3.tp_block_size; p1->knum_blocks = req_u->req3.tp_block_nr; p1->hdrlen = po->tp_hdrlen; @@ -824,8 +824,7 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1, h1->ts_first_pkt.ts_sec = ts.tv_sec; h1->ts_first_pkt.ts_nsec = ts.tv_nsec; pkc1->pkblk_start = (char *)pbd1; - pkc1->nxt_offset = (char *)(pkc1->pkblk_start + - BLK_PLUS_PRIV(pkc1->blk_sizeof_priv)); + pkc1->nxt_offset = pkc1->pkblk_start + BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); BLOCK_O2FP(pbd1) = (__u32)BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); BLOCK_O2PRIV(pbd1) = BLK_HDR_LEN; pbd1->version = pkc1->version; @@ -1018,7 +1017,7 @@ static void *__packet_lookup_frame_in_block(struct packet_sock *po, struct tpacket_block_desc *pbd; char *curr, *end; - pkc = GET_PBDQC_FROM_RB(((struct packet_ring_buffer *)&po->rx_ring)); + pkc = GET_PBDQC_FROM_RB(&po->rx_ring); pbd = GET_CURR_PBLOCK_DESC_FROM_CORE(pkc); /* Queue is frozen when user space is lagging behind */ @@ -1044,7 +1043,7 @@ static void *__packet_lookup_frame_in_block(struct packet_sock *po, smp_mb(); curr = pkc->nxt_offset; pkc->skb = skb; - end = (char *) ((char *)pbd + pkc->kblk_size); + end = (char *)pbd + pkc->kblk_size; /* first try the current block */ if (curr+TOTAL_PKT_LEN_INCL_ALIGN(len) < end) { diff --git a/net/tipc/port.c b/net/tipc/port.c index 2ad37a4db376..a1e828989d7a 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -909,8 +909,8 @@ int tipc_createport(void *usr_handle, warn("Port creation failed, no memory\n"); return -ENOMEM; } - p_ptr = (struct tipc_port *)tipc_createport_raw(NULL, port_dispatcher, - port_wakeup, importance); + p_ptr = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, + importance); if (!p_ptr) { kfree(up_ptr); return -ENOMEM; @@ -1078,8 +1078,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr) if (tp_ptr->connected) { tp_ptr->connected = 0; /* let timer expire on it's own to avoid deadlock! */ - tipc_nodesub_unsubscribe( - &((struct tipc_port *)tp_ptr)->subscription); + tipc_nodesub_unsubscribe(&tp_ptr->subscription); res = 0; } else { res = -ENOTCONN; @@ -1099,7 +1098,7 @@ int tipc_disconnect(u32 ref) p_ptr = tipc_port_lock(ref); if (!p_ptr) return -EINVAL; - res = tipc_disconnect_port((struct tipc_port *)p_ptr); + res = tipc_disconnect_port(p_ptr); tipc_port_unlock(p_ptr); return res; } diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 5577a447f531..11a863d81421 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -54,7 +54,7 @@ struct tipc_sock { }; #define tipc_sk(sk) ((struct tipc_sock *)(sk)) -#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) +#define tipc_sk_port(sk) (tipc_sk(sk)->p) #define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \ (sock->state == SS_DISCONNECTING)) -- GitLab From 79d6680f017a8084ae746f5d845a4fdc4f3a5e43 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 20 Apr 2012 15:29:20 -0600 Subject: [PATCH 0192/6849] usb: otg: isp1301_omap: resolve unused variable warning from gcc Resolve this build warning: drivers/usb/otg/isp1301_omap.c: In function 'isp1301_set_peripheral': drivers/usb/otg/isp1301_omap.c:1340:6: warning: unused variable 'l' This shows up when building with the 'omap1_defconfig' and '5912osk_testconfig' configs from git://git.pwsan.com/omap_kconfigs. Compile-tested only. Cc: Heikki Krogerus Cc: Felipe Balbi Signed-off-by: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/otg/isp1301_omap.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 70cf5d7bca48..33cd709b084e 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1336,9 +1336,6 @@ static int isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); -#ifndef CONFIG_USB_OTG - u32 l; -#endif if (!otg || isp != the_transceiver) return -ENODEV; @@ -1365,10 +1362,14 @@ isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) otg->gadget = gadget; // FIXME update its refcount - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); - l |= OTG_ID; - omap_writel(l, OTG_CTRL); + { + u32 l; + + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); + l |= OTG_ID; + omap_writel(l, OTG_CTRL); + } power_up(isp); isp->phy.state = OTG_STATE_B_IDLE; -- GitLab From f07d90107caeaa6913c70ad97b536f8cec45e8e7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 4 Jun 2012 07:16:14 +0000 Subject: [PATCH 0193/6849] net/9p: Add __force to cast of __user pointer A recent commit that removed unnecessary casts of pointers to the same type uncovered a missing __force cast. Add it. Reported by: Ben Hutchings Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/9p/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/client.c b/net/9p/client.c index 5cbea903a5ab..8260f132b32e 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1548,7 +1548,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, kernel_buf = 1; indata = data; } else - indata = udata; + indata = (__force char *)udata; /* * response header len is 11 * PDU Header(7) + IO Size (4) -- GitLab From 13497f58670c4e7a30170738f07b17d90011c785 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 4 Jun 2012 06:36:22 +0000 Subject: [PATCH 0194/6849] stmmac: remove two useless initialisations This patch removes two useless initialisations in the stmmac_rx and stmmac_tx functions. In the former, the count variable was reset twice and in the stmmac_tx we only need to increment the dirty pointer w/o setting the entry variable. v2: review the subject and comment that was not clear in my first version. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 70966330f44e..0caae72cda89 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -677,7 +677,7 @@ static void stmmac_tx(struct stmmac_priv *priv) priv->hw->desc->release_tx_desc(p); - entry = (++priv->dirty_tx) % txsize; + priv->dirty_tx++; } if (unlikely(netif_queue_stopped(priv->dev) && stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { @@ -1307,7 +1307,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) display_ring(priv->dma_rx, rxsize); } #endif - count = 0; while (!priv->hw->desc->get_rx_owner(p)) { int status; -- GitLab From c7aa12252f5142b9eee2f6e34ca8870a8e7e048c Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 4 May 2012 11:24:16 +0200 Subject: [PATCH 0195/6849] NFC: Take a reference on the LLCP local pointer when creating a socket LLCP sockets point to their local LLCP service, so they need to take a reference on it. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 46 ++++++++++++++++++++++++++++++--------------- net/nfc/llcp/llcp.h | 4 ++++ net/nfc/llcp/sock.c | 14 +++++--------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 42994fac26d6..0f6dd3a53dca 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -59,8 +59,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) release_sock(sk); sock_orphan(sk); - - s->local = NULL; } parent_sk = &parent->sk; @@ -83,8 +81,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) release_sock(accept_sk); sock_orphan(accept_sk); - - lsk->local = NULL; } } @@ -96,13 +92,39 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) release_sock(parent_sk); sock_orphan(parent_sk); - - parent->local = NULL; } mutex_unlock(&local->socket_lock); } +struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) +{ + kref_get(&local->ref); + + return local; +} + +static void local_release(struct kref *ref) +{ + struct nfc_llcp_local *local; + + local = container_of(ref, struct nfc_llcp_local, ref); + + list_del(&local->list); + nfc_llcp_socket_release(local); + del_timer_sync(&local->link_timer); + skb_queue_purge(&local->tx_queue); + destroy_workqueue(local->tx_wq); + destroy_workqueue(local->rx_wq); + kfree_skb(local->rx_pending); + kfree(local); +} + +int nfc_llcp_local_put(struct nfc_llcp_local *local) +{ + return kref_put(&local->ref, local_release); +} + static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local) { mutex_lock(&local->sdp_lock); @@ -612,7 +634,7 @@ enqueue: new_sock = nfc_llcp_sock(new_sk); new_sock->dev = local->dev; - new_sock->local = local; + new_sock->local = nfc_llcp_local_get(local); new_sock->nfc_protocol = sock->nfc_protocol; new_sock->ssap = bound_sap; new_sock->dsap = ssap; @@ -943,6 +965,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->dev = ndev; INIT_LIST_HEAD(&local->list); + kref_init(&local->ref); mutex_init(&local->sdp_lock); mutex_init(&local->socket_lock); init_timer(&local->link_timer); @@ -1015,14 +1038,7 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) return; } - list_del(&local->list); - nfc_llcp_socket_release(local); - del_timer_sync(&local->link_timer); - skb_queue_purge(&local->tx_queue); - destroy_workqueue(local->tx_wq); - destroy_workqueue(local->rx_wq); - kfree_skb(local->rx_pending); - kfree(local); + nfc_llcp_local_put(local); } int __init nfc_llcp_init(void) diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 50680ce5ae43..bc619553821b 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -44,6 +44,8 @@ struct nfc_llcp_local { struct list_head list; struct nfc_dev *dev; + struct kref ref; + struct mutex sdp_lock; struct mutex socket_lock; @@ -165,6 +167,8 @@ struct nfc_llcp_sock { struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); +struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local); +int nfc_llcp_local_put(struct nfc_llcp_local *local); u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, struct nfc_llcp_sock *sock); u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 3f339b19d140..9ac397b17718 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -111,7 +111,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) } llcp_sock->dev = dev; - llcp_sock->local = local; + llcp_sock->local = nfc_llcp_local_get(local); llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; llcp_sock->service_name_len = min_t(unsigned int, llcp_addr.service_name_len, @@ -487,7 +487,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, } llcp_sock->dev = dev; - llcp_sock->local = local; + llcp_sock->local = nfc_llcp_local_get(local); llcp_sock->ssap = nfc_llcp_get_local_ssap(local); if (llcp_sock->ssap == LLCP_SAP_MAX) { ret = -ENOMEM; @@ -701,8 +701,6 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) { - struct nfc_llcp_local *local = sock->local; - kfree(sock->service_name); skb_queue_purge(&sock->tx_queue); @@ -710,13 +708,11 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) skb_queue_purge(&sock->tx_backlog_queue); list_del_init(&sock->accept_queue); - - if (local != NULL && sock == local->sockets[sock->ssap]) - local->sockets[sock->ssap] = NULL; - else - list_del_init(&sock->list); + list_del_init(&sock->list); sock->parent = NULL; + + nfc_llcp_local_put(sock->local); } static int llcp_sock_create(struct net *net, struct socket *sock, -- GitLab From a69f32af86e389dd232b1bb2269e202c1bfcc60f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 4 May 2012 17:04:19 +0200 Subject: [PATCH 0196/6849] NFC: Socket linked list Simplify the LLCP sockets structure by putting all the connected ones into a single linked list. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 249 ++++++++++++++++++++++++-------------------- net/nfc/llcp/llcp.h | 12 ++- net/nfc/llcp/sock.c | 32 +++--- 3 files changed, 158 insertions(+), 135 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 0f6dd3a53dca..262aa827fd7f 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -31,45 +31,41 @@ static u8 llcp_magic[3] = {0x46, 0x66, 0x6d}; static struct list_head llcp_devices; -static void nfc_llcp_socket_release(struct nfc_llcp_local *local) +void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *sk) { - struct nfc_llcp_sock *parent, *s, *n; - struct sock *sk, *parent_sk; - int i; - - mutex_lock(&local->socket_lock); - - for (i = 0; i < LLCP_MAX_SAP; i++) { - parent = local->sockets[i]; - if (parent == NULL) - continue; - - /* Release all child sockets */ - list_for_each_entry_safe(s, n, &parent->list, list) { - list_del_init(&s->list); - sk = &s->sk; - - lock_sock(sk); + write_lock(&l->lock); + sk_add_node(sk, &l->head); + write_unlock(&l->lock); +} - if (sk->sk_state == LLCP_CONNECTED) - nfc_put_device(s->dev); +void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *sk) +{ + write_lock(&l->lock); + sk_del_node_init(sk); + write_unlock(&l->lock); +} - sk->sk_state = LLCP_CLOSED; +static void nfc_llcp_socket_release(struct nfc_llcp_local *local) +{ + struct sock *sk; + struct hlist_node *node, *tmp; + struct nfc_llcp_sock *llcp_sock; - release_sock(sk); + write_lock(&local->sockets.lock); - sock_orphan(sk); - } + sk_for_each_safe(sk, node, tmp, &local->sockets.head) { + llcp_sock = nfc_llcp_sock(sk); - parent_sk = &parent->sk; + lock_sock(sk); - lock_sock(parent_sk); + if (sk->sk_state == LLCP_CONNECTED) + nfc_put_device(llcp_sock->dev); - if (parent_sk->sk_state == LLCP_LISTEN) { + if (sk->sk_state == LLCP_LISTEN) { struct nfc_llcp_sock *lsk, *n; struct sock *accept_sk; - list_for_each_entry_safe(lsk, n, &parent->accept_queue, + list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, accept_queue) { accept_sk = &lsk->sk; lock_sock(accept_sk); @@ -84,17 +80,16 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) } } - if (parent_sk->sk_state == LLCP_CONNECTED) - nfc_put_device(parent->dev); + sk->sk_state = LLCP_CLOSED; - parent_sk->sk_state = LLCP_CLOSED; + release_sock(sk); - release_sock(parent_sk); + sock_orphan(sk); - sock_orphan(parent_sk); + sk_del_node_init(sk); } - mutex_unlock(&local->socket_lock); + write_unlock(&local->sockets.lock); } struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) @@ -122,6 +117,11 @@ static void local_release(struct kref *ref) int nfc_llcp_local_put(struct nfc_llcp_local *local) { + WARN_ON(local == NULL); + + if (local == NULL) + return 0; + return kref_put(&local->ref, local_release); } @@ -465,46 +465,107 @@ static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu) sock->recv_ack_n = (sock->recv_n - 1) % 16; } +static struct nfc_llcp_sock *nfc_llcp_connecting_sock_get(struct nfc_llcp_local *local, + u8 ssap) +{ + struct sock *sk; + struct nfc_llcp_sock *llcp_sock; + struct hlist_node *node; + + read_lock(&local->connecting_sockets.lock); + + sk_for_each(sk, node, &local->connecting_sockets.head) { + llcp_sock = nfc_llcp_sock(sk); + + if (llcp_sock->ssap == ssap) + goto out; + } + + llcp_sock = NULL; + +out: + read_unlock(&local->connecting_sockets.lock); + + sock_hold(&llcp_sock->sk); + + return llcp_sock; +} + static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, u8 ssap, u8 dsap) { - struct nfc_llcp_sock *sock, *llcp_sock, *n; + struct sock *sk; + struct hlist_node *node; + struct nfc_llcp_sock *llcp_sock; pr_debug("ssap dsap %d %d\n", ssap, dsap); if (ssap == 0 && dsap == 0) return NULL; - mutex_lock(&local->socket_lock); - sock = local->sockets[ssap]; - if (sock == NULL) { - mutex_unlock(&local->socket_lock); - return NULL; - } + read_lock(&local->sockets.lock); + + llcp_sock = NULL; - pr_debug("root dsap %d (%d)\n", sock->dsap, dsap); + sk_for_each(sk, node, &local->sockets.head) { + llcp_sock = nfc_llcp_sock(sk); - if (sock->dsap == dsap) { - sock_hold(&sock->sk); - mutex_unlock(&local->socket_lock); - return sock; + if (llcp_sock->ssap == ssap && + llcp_sock->dsap == dsap) + break; } - list_for_each_entry_safe(llcp_sock, n, &sock->list, list) { - pr_debug("llcp_sock %p sk %p dsap %d\n", llcp_sock, - &llcp_sock->sk, llcp_sock->dsap); - if (llcp_sock->dsap == dsap) { - sock_hold(&llcp_sock->sk); - mutex_unlock(&local->socket_lock); - return llcp_sock; - } + read_unlock(&local->sockets.lock); + + if (llcp_sock == NULL) + return NULL; + + sock_hold(&llcp_sock->sk); + + return llcp_sock; +} + +static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local, + u8 *sn, size_t sn_len) +{ + struct sock *sk; + struct hlist_node *node; + struct nfc_llcp_sock *llcp_sock; + + pr_debug("sn %zd\n", sn_len); + + if (sn == NULL || sn_len == 0) + return NULL; + + read_lock(&local->sockets.lock); + + llcp_sock = NULL; + + sk_for_each(sk, node, &local->sockets.head) { + llcp_sock = nfc_llcp_sock(sk); + + if (llcp_sock->sk.sk_state != LLCP_LISTEN) + continue; + + if (llcp_sock->service_name == NULL || + llcp_sock->service_name_len == 0) + continue; + + if (llcp_sock->service_name_len != sn_len) + continue; + + if (memcmp(sn, llcp_sock->service_name, sn_len) == 0) + break; } - pr_err("Could not find socket for %d %d\n", ssap, dsap); + read_unlock(&local->sockets.lock); - mutex_unlock(&local->socket_lock); + if (llcp_sock == NULL) + return NULL; - return NULL; + sock_hold(&llcp_sock->sk); + + return llcp_sock; } static void nfc_llcp_sock_put(struct nfc_llcp_sock *sock) @@ -540,7 +601,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, { struct sock *new_sk, *parent; struct nfc_llcp_sock *sock, *new_sock; - u8 dsap, ssap, bound_sap, reason; + u8 dsap, ssap, reason; dsap = nfc_llcp_dsap(skb); ssap = nfc_llcp_ssap(skb); @@ -551,24 +612,11 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, skb->len - LLCP_HEADER_SIZE); if (dsap != LLCP_SAP_SDP) { - bound_sap = dsap; - - mutex_lock(&local->socket_lock); - sock = local->sockets[dsap]; - if (sock == NULL) { - mutex_unlock(&local->socket_lock); + sock = nfc_llcp_sock_get(local, dsap, LLCP_SAP_SDP); + if (sock == NULL || sock->sk.sk_state != LLCP_LISTEN) { reason = LLCP_DM_NOBOUND; goto fail; } - - sock_hold(&sock->sk); - mutex_unlock(&local->socket_lock); - - lock_sock(&sock->sk); - - if (sock->dsap == LLCP_SAP_SDP && - sock->sk.sk_state == LLCP_LISTEN) - goto enqueue; } else { u8 *sn; size_t sn_len; @@ -581,40 +629,15 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, pr_debug("Service name length %zu\n", sn_len); - mutex_lock(&local->socket_lock); - for (bound_sap = 0; bound_sap < LLCP_LOCAL_SAP_OFFSET; - bound_sap++) { - sock = local->sockets[bound_sap]; - if (sock == NULL) - continue; - - if (sock->service_name == NULL || - sock->service_name_len == 0) - continue; - - if (sock->service_name_len != sn_len) - continue; - - if (sock->dsap == LLCP_SAP_SDP && - sock->sk.sk_state == LLCP_LISTEN && - !memcmp(sn, sock->service_name, sn_len)) { - pr_debug("Found service name at SAP %d\n", - bound_sap); - sock_hold(&sock->sk); - mutex_unlock(&local->socket_lock); - - lock_sock(&sock->sk); - - goto enqueue; - } + sock = nfc_llcp_sock_get_sn(local, sn, sn_len); + if (sock == NULL) { + reason = LLCP_DM_NOBOUND; + goto fail; } - mutex_unlock(&local->socket_lock); } - reason = LLCP_DM_NOBOUND; - goto fail; + lock_sock(&sock->sk); -enqueue: parent = &sock->sk; if (sk_acceptq_is_full(parent)) { @@ -636,13 +659,13 @@ enqueue: new_sock->dev = local->dev; new_sock->local = nfc_llcp_local_get(local); new_sock->nfc_protocol = sock->nfc_protocol; - new_sock->ssap = bound_sap; + new_sock->ssap = sock->ssap; new_sock->dsap = ssap; new_sock->parent = parent; pr_debug("new sock %p sk %p\n", new_sock, &new_sock->sk); - list_add_tail(&new_sock->list, &sock->list); + nfc_llcp_sock_link(&local->sockets, new_sk); nfc_llcp_accept_enqueue(&sock->sk, new_sk); @@ -813,11 +836,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) dsap = nfc_llcp_dsap(skb); ssap = nfc_llcp_ssap(skb); - llcp_sock = nfc_llcp_sock_get(local, dsap, ssap); - - if (llcp_sock == NULL) - llcp_sock = nfc_llcp_sock_get(local, dsap, LLCP_SAP_SDP); - + llcp_sock = nfc_llcp_connecting_sock_get(local, dsap); if (llcp_sock == NULL) { pr_err("Invalid CC\n"); nfc_llcp_send_dm(local, dsap, ssap, LLCP_DM_NOCONN); @@ -825,9 +844,13 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) return; } - llcp_sock->dsap = ssap; sk = &llcp_sock->sk; + /* Unlink from connecting and link to the client array */ + nfc_llcp_sock_unlink(&local->connecting_sockets, sk); + nfc_llcp_sock_link(&local->sockets, sk); + llcp_sock->dsap = ssap; + nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], skb->len - LLCP_HEADER_SIZE); @@ -967,7 +990,6 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) INIT_LIST_HEAD(&local->list); kref_init(&local->ref); mutex_init(&local->sdp_lock); - mutex_init(&local->socket_lock); init_timer(&local->link_timer); local->link_timer.data = (unsigned long) local; local->link_timer.function = nfc_llcp_symm_timer; @@ -1007,6 +1029,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) goto err_rx_wq; } + local->sockets.lock = __RW_LOCK_UNLOCKED(local->sockets.lock); + local->connecting_sockets.lock = __RW_LOCK_UNLOCKED(local->connecting_sockets.lock); + nfc_llcp_build_gb(local); local->remote_miu = LLCP_DEFAULT_MIU; diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index bc619553821b..705330470062 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -40,6 +40,11 @@ enum llcp_state { struct nfc_llcp_sock; +struct llcp_sock_list { + struct hlist_head head; + rwlock_t lock; +}; + struct nfc_llcp_local { struct list_head list; struct nfc_dev *dev; @@ -47,7 +52,6 @@ struct nfc_llcp_local { struct kref ref; struct mutex sdp_lock; - struct mutex socket_lock; struct timer_list link_timer; struct sk_buff_head tx_queue; @@ -82,12 +86,12 @@ struct nfc_llcp_local { u8 remote_rw; /* sockets array */ - struct nfc_llcp_sock *sockets[LLCP_MAX_SAP]; + struct llcp_sock_list sockets; + struct llcp_sock_list connecting_sockets; }; struct nfc_llcp_sock { struct sock sk; - struct list_head list; struct nfc_dev *dev; struct nfc_llcp_local *local; u32 target_idx; @@ -166,6 +170,8 @@ struct nfc_llcp_sock { #define LLCP_DM_REJ 0x03 +void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s); +void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s); struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local); int nfc_llcp_local_put(struct nfc_llcp_local *local); diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 9ac397b17718..8a60b53579b9 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -124,7 +124,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) if (llcp_sock->ssap == LLCP_MAX_SAP) goto put_dev; - local->sockets[llcp_sock->ssap] = llcp_sock; + nfc_llcp_sock_link(&local->sockets, sk); pr_debug("Socket bound to SAP %d\n", llcp_sock->ssap); @@ -379,15 +379,6 @@ static int llcp_sock_release(struct socket *sock) goto out; } - mutex_lock(&local->socket_lock); - - if (llcp_sock == local->sockets[llcp_sock->ssap]) - local->sockets[llcp_sock->ssap] = NULL; - else - list_del_init(&llcp_sock->list); - - mutex_unlock(&local->socket_lock); - lock_sock(sk); /* Send a DISC */ @@ -412,14 +403,12 @@ static int llcp_sock_release(struct socket *sock) } } - /* Freeing the SAP */ - if ((sk->sk_state == LLCP_CONNECTED - && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) || - sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN) - nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); + nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); release_sock(sk); + nfc_llcp_sock_unlink(&local->sockets, sk); + out: sock_orphan(sk); sock_put(sk); @@ -505,21 +494,26 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, llcp_sock->service_name_len, GFP_KERNEL); - local->sockets[llcp_sock->ssap] = llcp_sock; + nfc_llcp_sock_link(&local->connecting_sockets, sk); ret = nfc_llcp_send_connect(llcp_sock); if (ret) - goto put_dev; + goto sock_unlink; ret = sock_wait_state(sk, LLCP_CONNECTED, sock_sndtimeo(sk, flags & O_NONBLOCK)); if (ret) - goto put_dev; + goto sock_unlink; release_sock(sk); return 0; +sock_unlink: + nfc_llcp_put_ssap(local, llcp_sock->ssap); + + nfc_llcp_sock_unlink(&local->connecting_sockets, sk); + put_dev: nfc_put_device(dev); @@ -690,7 +684,6 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) skb_queue_head_init(&llcp_sock->tx_queue); skb_queue_head_init(&llcp_sock->tx_pending_queue); skb_queue_head_init(&llcp_sock->tx_backlog_queue); - INIT_LIST_HEAD(&llcp_sock->list); INIT_LIST_HEAD(&llcp_sock->accept_queue); if (sock != NULL) @@ -708,7 +701,6 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) skb_queue_purge(&sock->tx_backlog_queue); list_del_init(&sock->accept_queue); - list_del_init(&sock->list); sock->parent = NULL; -- GitLab From 7a06e586b9bfcaca310f40a857cf144d04abc8e6 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 7 May 2012 22:03:34 +0200 Subject: [PATCH 0197/6849] NFC: Move LLCP receiver window value to socket structure RW can only be fetched from a CONNECT or a CC frame thus making it an end points specific value, not a link one. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/commands.c | 45 ++++++++++++++++++++++++++++++++++------- net/nfc/llcp/llcp.c | 21 +++++++++---------- net/nfc/llcp/llcp.h | 9 ++++++--- net/nfc/llcp/sock.c | 1 + 4 files changed, 55 insertions(+), 21 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index bf8ae4f0b90c..eb51864089ef 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -117,8 +117,8 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length) return tlv; } -int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, - u8 *tlv_array, u16 tlv_array_len) +int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local, + u8 *tlv_array, u16 tlv_array_len) { u8 *tlv = tlv_array, type, length, offset = 0; @@ -149,8 +149,42 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, case LLCP_TLV_OPT: local->remote_opt = llcp_tlv_opt(tlv); break; + default: + pr_err("Invalid gt tlv value 0x%x\n", type); + break; + } + + offset += length + 2; + tlv += length + 2; + } + + pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x\n", + local->remote_version, local->remote_miu, + local->remote_lto, local->remote_opt, + local->remote_wks); + + return 0; +} + +int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock, + u8 *tlv_array, u16 tlv_array_len) +{ + u8 *tlv = tlv_array, type, length, offset = 0; + + pr_debug("TLV array length %d\n", tlv_array_len); + + if (sock == NULL) + return -ENOTCONN; + + while (offset < tlv_array_len) { + type = tlv[0]; + length = tlv[1]; + + pr_debug("type 0x%x length %d\n", type, length); + + switch (type) { case LLCP_TLV_RW: - local->remote_rw = llcp_tlv_rw(tlv); + sock->rw = llcp_tlv_rw(tlv); break; case LLCP_TLV_SN: break; @@ -163,10 +197,7 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, tlv += length + 2; } - pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n", - local->remote_version, local->remote_miu, - local->remote_lto, local->remote_opt, - local->remote_wks, local->remote_rw); + pr_debug("sock %p rw %d\n", sock, sock->rw); return 0; } diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 262aa827fd7f..d3efc5b3c19f 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -406,9 +406,9 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) return -EINVAL; } - return nfc_llcp_parse_tlv(local, - &local->remote_gb[3], - local->remote_gb_len - 3); + return nfc_llcp_parse_gb_tlv(local, + &local->remote_gb[3], + local->remote_gb_len - 3); } static void nfc_llcp_tx_work(struct work_struct *work) @@ -608,9 +608,6 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, pr_debug("%d %d\n", dsap, ssap); - nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], - skb->len - LLCP_HEADER_SIZE); - if (dsap != LLCP_SAP_SDP) { sock = nfc_llcp_sock_get(local, dsap, LLCP_SAP_SDP); if (sock == NULL || sock->sk.sk_state != LLCP_LISTEN) { @@ -663,6 +660,9 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, new_sock->dsap = ssap; new_sock->parent = parent; + nfc_llcp_parse_connection_tlv(new_sock, &skb->data[LLCP_HEADER_SIZE], + skb->len - LLCP_HEADER_SIZE); + pr_debug("new sock %p sk %p\n", new_sock, &new_sock->sk); nfc_llcp_sock_link(&local->sockets, new_sk); @@ -699,11 +699,11 @@ int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) pr_debug("Remote ready %d tx queue len %d remote rw %d", sock->remote_ready, skb_queue_len(&sock->tx_pending_queue), - local->remote_rw); + sock->rw); /* Try to queue some I frames for transmission */ while (sock->remote_ready && - skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) { + skb_queue_len(&sock->tx_pending_queue) < sock->rw) { struct sk_buff *pdu, *pending_pdu; pdu = skb_dequeue(&sock->tx_queue); @@ -851,8 +851,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) nfc_llcp_sock_link(&local->sockets, sk); llcp_sock->dsap = ssap; - nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], - skb->len - LLCP_HEADER_SIZE); + nfc_llcp_parse_connection_tlv(llcp_sock, &skb->data[LLCP_HEADER_SIZE], + skb->len - LLCP_HEADER_SIZE); sk->sk_state = LLCP_CONNECTED; sk->sk_state_change(sk); @@ -1036,7 +1036,6 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - local->remote_rw = LLCP_DEFAULT_RW; list_add(&llcp_devices, &local->list); diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 705330470062..add03e74a9ea 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -83,7 +83,6 @@ struct nfc_llcp_local { u16 remote_lto; u8 remote_opt; u16 remote_wks; - u8 remote_rw; /* sockets array */ struct llcp_sock_list sockets; @@ -97,10 +96,12 @@ struct nfc_llcp_sock { u32 target_idx; u32 nfc_protocol; + /* Link parameters */ u8 ssap; u8 dsap; char *service_name; size_t service_name_len; + u8 rw; /* Link variables */ u8 send_n; @@ -189,8 +190,10 @@ void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk); struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock); /* TLV API */ -int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, - u8 *tlv_array, u16 tlv_array_len); +int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local, + u8 *tlv_array, u16 tlv_array_len); +int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock, + u8 *tlv_array, u16 tlv_array_len); /* Commands API */ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 8a60b53579b9..aab077e68094 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -678,6 +678,7 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) llcp_sock->ssap = 0; llcp_sock->dsap = LLCP_SAP_SDP; + llcp_sock->rw = LLCP_DEFAULT_RW; llcp_sock->send_n = llcp_sock->send_ack_n = 0; llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; llcp_sock->remote_ready = 1; -- GitLab From 93d7e490b7f4a72b6c7e1dfa475fa3c3e18eb9f1 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 14 May 2012 17:37:32 +0200 Subject: [PATCH 0198/6849] NFC: Move LLCP MIU extension value to socket structure The MIU extension value can be received during the PAX or during the connection establishment process. It's definitely a connection related value rather than a link one. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/commands.c | 7 +++++-- net/nfc/llcp/llcp.c | 1 + net/nfc/llcp/llcp.h | 1 + net/nfc/llcp/sock.c | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index eb51864089ef..850e5cf79378 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -183,6 +183,9 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock, pr_debug("type 0x%x length %d\n", type, length); switch (type) { + case LLCP_TLV_MIUX: + sock->miu = llcp_tlv_miux(tlv) + 128; + break; case LLCP_TLV_RW: sock->rw = llcp_tlv_rw(tlv); break; @@ -197,7 +200,7 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock, tlv += length + 2; } - pr_debug("sock %p rw %d\n", sock, sock->rw); + pr_debug("sock %p rw %d miu %d\n", sock, sock->rw, sock->miu); return 0; } @@ -505,7 +508,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, while (remaining_len > 0) { - frag_len = min_t(size_t, local->remote_miu, remaining_len); + frag_len = min_t(size_t, sock->miu, remaining_len); pr_debug("Fragment %zd bytes remaining %zd", frag_len, remaining_len); diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index d3efc5b3c19f..5f7aa3f632fb 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -655,6 +655,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, new_sock = nfc_llcp_sock(new_sk); new_sock->dev = local->dev; new_sock->local = nfc_llcp_local_get(local); + new_sock->miu = local->remote_miu; new_sock->nfc_protocol = sock->nfc_protocol; new_sock->ssap = sock->ssap; new_sock->dsap = ssap; diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index add03e74a9ea..7286c86982ff 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -102,6 +102,7 @@ struct nfc_llcp_sock { char *service_name; size_t service_name_len; u8 rw; + u16 miu; /* Link variables */ u8 send_n; diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index aab077e68094..30e3cc71be7a 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -477,6 +477,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, llcp_sock->dev = dev; llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->miu = llcp_sock->local->remote_miu; llcp_sock->ssap = nfc_llcp_get_local_ssap(local); if (llcp_sock->ssap == LLCP_SAP_MAX) { ret = -ENOMEM; @@ -679,6 +680,7 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) llcp_sock->ssap = 0; llcp_sock->dsap = LLCP_SAP_SDP; llcp_sock->rw = LLCP_DEFAULT_RW; + llcp_sock->miu = LLCP_DEFAULT_MIU; llcp_sock->send_n = llcp_sock->send_ack_n = 0; llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; llcp_sock->remote_ready = 1; -- GitLab From 76762b73693aa7621ae8d3ea5c7efbf74beda0b9 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 14 May 2012 17:38:54 +0200 Subject: [PATCH 0199/6849] NFC: LLCP's MIUX is 10 bytes long, not 7 The mask is 0x7ff and not 0x7f and the return value is an u16. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 850e5cf79378..b982b5b890d7 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -51,7 +51,7 @@ static u8 llcp_tlv8(u8 *tlv, u8 type) return tlv[2]; } -static u8 llcp_tlv16(u8 *tlv, u8 type) +static u16 llcp_tlv16(u8 *tlv, u8 type) { if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]]) return 0; @@ -67,7 +67,7 @@ static u8 llcp_tlv_version(u8 *tlv) static u16 llcp_tlv_miux(u8 *tlv) { - return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7f; + return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7ff; } static u16 llcp_tlv_wks(u8 *tlv) -- GitLab From ab73b751303bc60d7d9fba875c958dedfe14754c Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 10 Apr 2012 12:51:52 +0200 Subject: [PATCH 0200/6849] NFC: Export LLCP general bytes getter Signed-off-by: Samuel Ortiz --- include/net/nfc/nfc.h | 1 + net/nfc/core.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index b7ca4a2a1d72..3116f923f607 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -188,6 +188,7 @@ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gt, u8 gt_len); +u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len); int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int ntargets); diff --git a/net/nfc/core.c b/net/nfc/core.c index 9f6ce011d35d..f5a43f701a9e 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -447,6 +447,14 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) } EXPORT_SYMBOL(nfc_set_remote_general_bytes); +u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len) +{ + pr_debug("dev_name=%s\n", dev_name(&dev->dev)); + + return nfc_llcp_general_bytes(dev, gb_len); +} +EXPORT_SYMBOL(nfc_get_local_general_bytes); + /** * nfc_alloc_send_skb - allocate a skb for data exchange responses * -- GitLab From fe7c580073280c15bb4eb4f82bf20dddc1a68383 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 15 May 2012 15:57:06 +0200 Subject: [PATCH 0201/6849] NFC: Add target mode protocols to the polling loop startup routine Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 39 +++++++++++++++++++++++++++++---------- drivers/nfc/pn544_hci.c | 10 ++++++---- include/linux/nfc.h | 4 ++++ include/net/nfc/hci.h | 3 ++- include/net/nfc/nfc.h | 3 ++- include/net/nfc/shdlc.h | 3 ++- net/nfc/core.c | 10 +++++----- net/nfc/hci/core.c | 5 +++-- net/nfc/hci/shdlc.c | 6 ++++-- net/nfc/nci/core.c | 7 ++++--- net/nfc/netlink.c | 19 +++++++++++++++---- net/nfc/nfc.h | 2 +- 12 files changed, 77 insertions(+), 34 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 19110f0eb15f..38a523c62132 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1078,27 +1078,23 @@ stop_poll: return 0; } -static int pn533_start_poll(struct nfc_dev *nfc_dev, u32 protocols) +static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) +{ + return 0; +} + +static int pn533_start_im_poll(struct nfc_dev *nfc_dev, u32 protocols) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_poll_modulations *start_mod; int rc; - nfc_dev_dbg(&dev->interface->dev, "%s - protocols=0x%x", __func__, - protocols); - if (dev->poll_mod_count) { nfc_dev_err(&dev->interface->dev, "Polling operation already" " active"); return -EBUSY; } - if (dev->tgt_active_prot) { - nfc_dev_err(&dev->interface->dev, "Cannot poll with a target" - " already activated"); - return -EBUSY; - } - pn533_poll_create_mod_list(dev, protocols); if (!dev->poll_mod_count) { @@ -1135,6 +1131,29 @@ error: return rc; } +static int pn533_start_poll(struct nfc_dev *nfc_dev, + u32 im_protocols, u32 tm_protocols) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + + nfc_dev_dbg(&dev->interface->dev, + "%s: im protocols 0x%x tm protocols 0x%x", + __func__, im_protocols, tm_protocols); + + if (dev->tgt_active_prot) { + nfc_dev_err(&dev->interface->dev, + "Cannot poll with a target already activated"); + return -EBUSY; + } + + if (!tm_protocols) + return pn533_start_im_poll(nfc_dev, im_protocols); + else if (!im_protocols) + return pn533_init_target(nfc_dev, tm_protocols); + else + return -EINVAL; +} + static void pn533_stop_poll(struct nfc_dev *nfc_dev) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c index 281f18c2fb82..457eac35dc74 100644 --- a/drivers/nfc/pn544_hci.c +++ b/drivers/nfc/pn544_hci.c @@ -576,7 +576,8 @@ static int pn544_hci_xmit(struct nfc_shdlc *shdlc, struct sk_buff *skb) return pn544_hci_i2c_write(client, skb->data, skb->len); } -static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols) +static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, + u32 im_protocols, u32 tm_protocols) { struct nfc_hci_dev *hdev = nfc_shdlc_get_hci_dev(shdlc); u8 phases = 0; @@ -584,7 +585,8 @@ static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols) u8 duration[2]; u8 activated; - pr_info(DRIVER_DESC ": %s protocols = %d\n", __func__, protocols); + pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", + __func__, im_protocols, tm_protocols); r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); @@ -604,10 +606,10 @@ static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols) if (r < 0) return r; - if (protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK | + if (im_protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_JEWEL_MASK)) phases |= 1; /* Type A */ - if (protocols & NFC_PROTO_FELICA_MASK) { + if (im_protocols & NFC_PROTO_FELICA_MASK) { phases |= (1 << 2); /* Type F 212 */ phases |= (1 << 3); /* Type F 424 */ } diff --git a/include/linux/nfc.h b/include/linux/nfc.h index 0ae9b5857c83..548715881fb0 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h @@ -94,6 +94,8 @@ enum nfc_commands { * @NFC_ATTR_TARGET_SENSF_RES: NFC-F targets extra information, max 18 bytes * @NFC_ATTR_COMM_MODE: Passive or active mode * @NFC_ATTR_RF_MODE: Initiator or target + * @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for + * @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for */ enum nfc_attrs { NFC_ATTR_UNSPEC, @@ -109,6 +111,8 @@ enum nfc_attrs { NFC_ATTR_COMM_MODE, NFC_ATTR_RF_MODE, NFC_ATTR_DEVICE_POWERED, + NFC_ATTR_IM_PROTOCOLS, + NFC_ATTR_TM_PROTOCOLS, /* private: internal use only */ __NFC_ATTR_AFTER_LAST }; diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index 4467c9460857..e30e6a869714 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h @@ -31,7 +31,8 @@ struct nfc_hci_ops { void (*close) (struct nfc_hci_dev *hdev); int (*hci_ready) (struct nfc_hci_dev *hdev); int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); - int (*start_poll) (struct nfc_hci_dev *hdev, u32 protocols); + int (*start_poll) (struct nfc_hci_dev *hdev, + u32 im_protocols, u32 tm_protocols); int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 3116f923f607..97aa0e81aa83 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -53,7 +53,8 @@ struct nfc_target; struct nfc_ops { int (*dev_up)(struct nfc_dev *dev); int (*dev_down)(struct nfc_dev *dev); - int (*start_poll)(struct nfc_dev *dev, u32 protocols); + int (*start_poll)(struct nfc_dev *dev, + u32 im_protocols, u32 tm_protocols); void (*stop_poll)(struct nfc_dev *dev); int (*dep_link_up)(struct nfc_dev *dev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len); diff --git a/include/net/nfc/shdlc.h b/include/net/nfc/shdlc.h index ab06afd462da..35e930d2f638 100644 --- a/include/net/nfc/shdlc.h +++ b/include/net/nfc/shdlc.h @@ -27,7 +27,8 @@ struct nfc_shdlc_ops { void (*close) (struct nfc_shdlc *shdlc); int (*hci_ready) (struct nfc_shdlc *shdlc); int (*xmit) (struct nfc_shdlc *shdlc, struct sk_buff *skb); - int (*start_poll) (struct nfc_shdlc *shdlc, u32 protocols); + int (*start_poll) (struct nfc_shdlc *shdlc, + u32 im_protocols, u32 tm_protocols); int (*target_from_gate) (struct nfc_shdlc *shdlc, u8 gate, struct nfc_target *target); int (*complete_target_discovered) (struct nfc_shdlc *shdlc, u8 gate, diff --git a/net/nfc/core.c b/net/nfc/core.c index f5a43f701a9e..c83717bfcb8a 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -121,14 +121,14 @@ error: * The device remains polling for targets until a target is found or * the nfc_stop_poll function is called. */ -int nfc_start_poll(struct nfc_dev *dev, u32 protocols) +int nfc_start_poll(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols) { int rc; - pr_debug("dev_name=%s protocols=0x%x\n", - dev_name(&dev->dev), protocols); + pr_debug("dev_name %s initiator protocols 0x%x target protocols 0x%x\n", + dev_name(&dev->dev), im_protocols, tm_protocols); - if (!protocols) + if (!im_protocols && !tm_protocols) return -EINVAL; device_lock(&dev->dev); @@ -143,7 +143,7 @@ int nfc_start_poll(struct nfc_dev *dev, u32 protocols) goto error; } - rc = dev->ops->start_poll(dev, protocols); + rc = dev->ops->start_poll(dev, im_protocols, tm_protocols); if (!rc) dev->polling = true; diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index e1a640d2b588..281f3a3bec00 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c @@ -481,12 +481,13 @@ static int hci_dev_down(struct nfc_dev *nfc_dev) return 0; } -static int hci_start_poll(struct nfc_dev *nfc_dev, u32 protocols) +static int hci_start_poll(struct nfc_dev *nfc_dev, + u32 im_protocols, u32 tm_protocols) { struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); if (hdev->ops->start_poll) - return hdev->ops->start_poll(hdev, protocols); + return hdev->ops->start_poll(hdev, im_protocols, tm_protocols); else return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_READER_REQUESTED, NULL, 0); diff --git a/net/nfc/hci/shdlc.c b/net/nfc/hci/shdlc.c index 5665dc6d893a..6b836e6242b7 100644 --- a/net/nfc/hci/shdlc.c +++ b/net/nfc/hci/shdlc.c @@ -765,14 +765,16 @@ static int nfc_shdlc_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) return 0; } -static int nfc_shdlc_start_poll(struct nfc_hci_dev *hdev, u32 protocols) +static int nfc_shdlc_start_poll(struct nfc_hci_dev *hdev, + u32 im_protocols, u32 tm_protocols) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); pr_debug("\n"); if (shdlc->ops->start_poll) - return shdlc->ops->start_poll(shdlc, protocols); + return shdlc->ops->start_poll(shdlc, + im_protocols, tm_protocols); return 0; } diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index d560e6f13072..0f718982f808 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -387,7 +387,8 @@ static int nci_dev_down(struct nfc_dev *nfc_dev) return nci_close_device(ndev); } -static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) +static int nci_start_poll(struct nfc_dev *nfc_dev, + __u32 im_protocols, __u32 tm_protocols) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); int rc; @@ -413,11 +414,11 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) return -EBUSY; } - rc = nci_request(ndev, nci_rf_discover_req, protocols, + rc = nci_request(ndev, nci_rf_discover_req, im_protocols, msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); if (!rc) - ndev->poll_prots = protocols; + ndev->poll_prots = im_protocols; return rc; } diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 581d419083aa..a18fd56798fc 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -49,6 +49,8 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 }, [NFC_ATTR_RF_MODE] = { .type = NLA_U8 }, [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 }, + [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 }, + [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 }, }; static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, @@ -519,16 +521,25 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) struct nfc_dev *dev; int rc; u32 idx; - u32 protocols; + u32 im_protocols = 0, tm_protocols = 0; pr_debug("Poll start\n"); if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || - !info->attrs[NFC_ATTR_PROTOCOLS]) + ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] && + !info->attrs[NFC_ATTR_PROTOCOLS]) && + !info->attrs[NFC_ATTR_TM_PROTOCOLS])) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); - protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]); + + if (info->attrs[NFC_ATTR_TM_PROTOCOLS]) + tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]); + else if (info->attrs[NFC_ATTR_PROTOCOLS]) + tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]); + + if (info->attrs[NFC_ATTR_IM_PROTOCOLS]) + im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]); dev = nfc_get_device(idx); if (!dev) @@ -536,7 +547,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) mutex_lock(&dev->genl_data.genl_data_mutex); - rc = nfc_start_poll(dev, protocols); + rc = nfc_start_poll(dev, im_protocols, tm_protocols); if (!rc) dev->genl_data.poll_req_pid = info->snd_pid; diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 3dd4232ae664..7d9708f2a66c 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -158,7 +158,7 @@ int nfc_dev_up(struct nfc_dev *dev); int nfc_dev_down(struct nfc_dev *dev); -int nfc_start_poll(struct nfc_dev *dev, u32 protocols); +int nfc_start_poll(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols); int nfc_stop_poll(struct nfc_dev *dev); -- GitLab From ad3823cef650bdc1ca9e7bf1a01b87ad3c0425de Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 30 May 2012 23:54:55 +0200 Subject: [PATCH 0202/6849] NFC: Implement pn533 target mode polling loop We only want to support p2p target mode for now, no host card emulation. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 109 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 38a523c62132..605a08a62e45 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -74,6 +74,8 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_IN_RELEASE 0x52 #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 +#define PN533_CMD_TG_INIT_AS_TARGET 0x8c + #define PN533_CMD_RESPONSE(cmd) (cmd + 1) /* PN533 Return codes */ @@ -253,6 +255,25 @@ struct pn533_cmd_jump_dep_response { u8 gt[]; } __packed; + +/* PN533_TG_INIT_AS_TARGET */ +#define PN533_INIT_TARGET_PASSIVE 0x1 +#define PN533_INIT_TARGET_DEP 0x2 + +struct pn533_cmd_init_target { + u8 mode; + u8 mifare[6]; + u8 felica[18]; + u8 nfcid3[10]; + u8 gb_len; + u8 gb[]; +} __packed; + +struct pn533_cmd_init_target_response { + u8 mode; + u8 cmd[]; +} __packed; + struct pn533 { struct usb_device *udev; struct usb_interface *interface; @@ -1078,11 +1099,88 @@ stop_poll: return 0; } -static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) +static int pn533_init_target_frame(struct pn533_frame *frame, + u8 *gb, size_t gb_len) { + struct pn533_cmd_init_target *cmd; + size_t cmd_len; + + cmd_len = sizeof(struct pn533_cmd_init_target) + gb_len + 1; + cmd = kzalloc(cmd_len, GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + pn533_tx_frame_init(frame, PN533_CMD_TG_INIT_AS_TARGET); + + /* DEP support only */ + cmd->mode |= PN533_INIT_TARGET_DEP; + get_random_bytes(cmd->nfcid3, 10); + cmd->gb_len = gb_len; + memcpy(cmd->gb, gb, gb_len); + /* Len Tk */ + cmd->gb[gb_len] = 0; + + memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), cmd, cmd_len); + frame->datalen += cmd_len; + + pn533_tx_frame_finish(frame); + return 0; } +static int pn533_init_target_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) +{ + struct pn533_cmd_init_target_response *resp; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + if (params_len < 0) { + nfc_dev_err(&dev->interface->dev, + "Error %d when starting as a target", + params_len); + + return params_len; + } + + resp = (struct pn533_cmd_init_target_response *) params; + + nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x\n", resp->mode); + + return 0; +} + +static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + u8 *gb; + size_t gb_len; + int rc; + + pn533_poll_reset_mod_list(dev); + + gb = nfc_get_local_general_bytes(nfc_dev, &gb_len); + if (gb == NULL) + return -ENOMEM; + + rc = pn533_init_target_frame(dev->out_frame, gb, gb_len); + if (rc < 0) + return rc; + + rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, + dev->in_maxlen, + pn533_init_target_complete, + NULL, GFP_KERNEL); + + if (rc) + nfc_dev_err(&dev->interface->dev, + "Error %d when trying to initiate as a target", rc); + + dev->poll_mod_count++; + + return rc; +} + static int pn533_start_im_poll(struct nfc_dev *nfc_dev, u32 protocols) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); @@ -1146,12 +1244,13 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, return -EBUSY; } - if (!tm_protocols) + if (im_protocols) return pn533_start_im_poll(nfc_dev, im_protocols); - else if (!im_protocols) + + if (tm_protocols) return pn533_init_target(nfc_dev, tm_protocols); - else - return -EINVAL; + + return -EINVAL; } static void pn533_stop_poll(struct nfc_dev *nfc_dev) -- GitLab From fc40a8c1a06ab7db45da790693dd9802612a055c Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 1 Jun 2012 13:21:13 +0200 Subject: [PATCH 0203/6849] NFC: Add target mode activation netlink event Userspace gets a netlink event upon target mode activation. The LLCP layer is also signaled when we get an ATR_REQ in order to get the remote general bytes. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 27 +++++++++++++++++-- include/linux/nfc.h | 7 +++++ include/net/nfc/nfc.h | 4 +++ net/nfc/core.c | 35 ++++++++++++++++++++++++ net/nfc/netlink.c | 62 +++++++++++++++++++++++++++++++++++++++++++ net/nfc/nfc.h | 3 +++ 6 files changed, 136 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 605a08a62e45..c6b9bc5ac6e6 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -260,6 +260,10 @@ struct pn533_cmd_jump_dep_response { #define PN533_INIT_TARGET_PASSIVE 0x1 #define PN533_INIT_TARGET_DEP 0x2 +#define PN533_INIT_TARGET_RESP_FRAME_MASK 0x3 +#define PN533_INIT_TARGET_RESP_ACTIVE 0x1 +#define PN533_INIT_TARGET_RESP_DEP 0x4 + struct pn533_cmd_init_target { u8 mode; u8 mifare[6]; @@ -1128,10 +1132,13 @@ static int pn533_init_target_frame(struct pn533_frame *frame, return 0; } +#define ATR_REQ_GB_OFFSET 17 static int pn533_init_target_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { struct pn533_cmd_init_target_response *resp; + u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; + size_t gb_len; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1143,11 +1150,27 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, return params_len; } + if (params_len < ATR_REQ_GB_OFFSET + 1) + return -EINVAL; + resp = (struct pn533_cmd_init_target_response *) params; - nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x\n", resp->mode); + nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x param len %d\n", + resp->mode, params_len); - return 0; + frame = resp->mode & PN533_INIT_TARGET_RESP_FRAME_MASK; + if (frame == PN533_INIT_TARGET_RESP_ACTIVE) + comm_mode = NFC_COMM_ACTIVE; + + /* Again, only DEP */ + if ((resp->mode & PN533_INIT_TARGET_RESP_DEP) == 0) + return -EOPNOTSUPP; + + gb = resp->cmd + ATR_REQ_GB_OFFSET; + gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); + + return nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, + comm_mode, gb, gb_len); } static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) diff --git a/include/linux/nfc.h b/include/linux/nfc.h index 548715881fb0..d124e9273fcb 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h @@ -56,6 +56,10 @@ * %NFC_ATTR_PROTOCOLS) * @NFC_EVENT_DEVICE_REMOVED: event emitted when a device is removed * (it sends %NFC_ATTR_DEVICE_INDEX) + * @NFC_EVENT_TM_ACTIVATED: event emitted when the adapter is activated in + * target mode. + * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated + * from target mode. */ enum nfc_commands { NFC_CMD_UNSPEC, @@ -71,6 +75,8 @@ enum nfc_commands { NFC_EVENT_DEVICE_ADDED, NFC_EVENT_DEVICE_REMOVED, NFC_EVENT_TARGET_LOST, + NFC_EVENT_TM_ACTIVATED, + NFC_EVENT_TM_DEACTIVATED, /* private: internal use only */ __NFC_CMD_AFTER_LAST }; @@ -122,6 +128,7 @@ enum nfc_attrs { #define NFC_NFCID1_MAXSIZE 10 #define NFC_SENSB_RES_MAXSIZE 12 #define NFC_SENSF_RES_MAXSIZE 18 +#define NFC_GB_MAXSIZE 48 /* NFC protocols */ #define NFC_PROTO_JEWEL 1 diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 97aa0e81aa83..41573b4bd78a 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -198,4 +198,8 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx); int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, u8 comm_mode, u8 rf_mode); +int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, + u8 *gb, size_t gb_len); +int nfc_tm_deactivated(struct nfc_dev *dev); + #endif /* __NET_NFC_H */ diff --git a/net/nfc/core.c b/net/nfc/core.c index c83717bfcb8a..17f147430b7c 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -455,6 +455,41 @@ u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len) } EXPORT_SYMBOL(nfc_get_local_general_bytes); +int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, + u8 *gb, size_t gb_len) +{ + int rc; + + device_lock(&dev->dev); + + dev->polling = false; + + if (gb != NULL) { + rc = nfc_set_remote_general_bytes(dev, gb, gb_len); + if (rc < 0) + goto out; + } + + if (protocol == NFC_PROTO_NFC_DEP_MASK) + nfc_dep_link_is_up(dev, 0, comm_mode, NFC_RF_TARGET); + + rc = nfc_genl_tm_activated(dev, protocol); + +out: + device_unlock(&dev->dev); + + return rc; +} +EXPORT_SYMBOL(nfc_tm_activated); + +int nfc_tm_deactivated(struct nfc_dev *dev) +{ + dev->dep_link_up = false; + + return nfc_genl_tm_deactivated(dev); +} +EXPORT_SYMBOL(nfc_tm_deactivated); + /** * nfc_alloc_send_skb - allocate a skb for data exchange responses * diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index a18fd56798fc..21eaa9b5c6bf 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -221,6 +221,68 @@ free_msg: return -EMSGSIZE; } +int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, + NFC_EVENT_TM_ACTIVATED); + if (!hdr) + goto free_msg; + + if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) + goto nla_put_failure; + if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + + genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); + + return 0; + +nla_put_failure: + genlmsg_cancel(msg, hdr); +free_msg: + nlmsg_free(msg); + return -EMSGSIZE; +} + +int nfc_genl_tm_deactivated(struct nfc_dev *dev) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, + NFC_EVENT_TM_DEACTIVATED); + if (!hdr) + goto free_msg; + + if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + + genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); + + return 0; + +nla_put_failure: + genlmsg_cancel(msg, hdr); +free_msg: + nlmsg_free(msg); + return -EMSGSIZE; +} + int nfc_genl_device_added(struct nfc_dev *dev) { struct sk_buff *msg; diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 7d9708f2a66c..cd9fcbe57464 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -128,6 +128,9 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, u8 comm_mode, u8 rf_mode); int nfc_genl_dep_link_down_event(struct nfc_dev *dev); +int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol); +int nfc_genl_tm_deactivated(struct nfc_dev *dev); + struct nfc_dev *nfc_get_device(unsigned int idx); static inline void nfc_put_device(struct nfc_dev *dev) -- GitLab From f212ad5e993e7efb996fc8ce94a5de8f0bd06d41 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 00:02:26 +0200 Subject: [PATCH 0204/6849] NFC: Set the NFC device RF mode appropriately Signed-off-by: Samuel Ortiz --- include/linux/nfc.h | 1 + include/net/nfc/nfc.h | 2 +- net/nfc/core.c | 14 ++++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/linux/nfc.h b/include/linux/nfc.h index d124e9273fcb..f4e6dd915b1c 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h @@ -146,6 +146,7 @@ enum nfc_attrs { /* NFC RF modes */ #define NFC_RF_INITIATOR 0 #define NFC_RF_TARGET 1 +#define NFC_RF_NONE 2 /* NFC protocols masks used in bitsets */ #define NFC_PROTO_JEWEL_MASK (1 << NFC_PROTO_JEWEL) diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 41573b4bd78a..a6a7b49a3e2d 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -100,10 +100,10 @@ struct nfc_dev { int targets_generation; struct device dev; bool dev_up; + u8 rf_mode; bool polling; struct nfc_target *active_target; bool dep_link_up; - u32 dep_rf_mode; struct nfc_genl_data genl_data; u32 supported_protocols; diff --git a/net/nfc/core.c b/net/nfc/core.c index 17f147430b7c..722a0c76c669 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -144,8 +144,10 @@ int nfc_start_poll(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols) } rc = dev->ops->start_poll(dev, im_protocols, tm_protocols); - if (!rc) + if (!rc) { dev->polling = true; + dev->rf_mode = NFC_RF_NONE; + } error: device_unlock(&dev->dev); @@ -235,8 +237,10 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) } rc = dev->ops->dep_link_up(dev, target, comm_mode, gb, gb_len); - if (!rc) + if (!rc) { dev->active_target = target; + dev->rf_mode = NFC_RF_INITIATOR; + } error: device_unlock(&dev->dev); @@ -264,7 +268,7 @@ int nfc_dep_link_down(struct nfc_dev *dev) goto error; } - if (dev->dep_rf_mode == NFC_RF_TARGET) { + if (dev->rf_mode == NFC_RF_TARGET) { rc = -EOPNOTSUPP; goto error; } @@ -286,7 +290,6 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, u8 comm_mode, u8 rf_mode) { dev->dep_link_up = true; - dev->dep_rf_mode = rf_mode; nfc_llcp_mac_is_up(dev, target_idx, comm_mode, rf_mode); @@ -330,6 +333,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) rc = dev->ops->activate_target(dev, target, protocol); if (!rc) { dev->active_target = target; + dev->rf_mode = NFC_RF_INITIATOR; if (dev->ops->check_presence) mod_timer(&dev->check_pres_timer, jiffies + @@ -470,6 +474,8 @@ int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, goto out; } + dev->rf_mode = NFC_RF_TARGET; + if (protocol == NFC_PROTO_NFC_DEP_MASK) nfc_dep_link_is_up(dev, 0, comm_mode, NFC_RF_TARGET); -- GitLab From be9ae4ce4ee66e211815122ab4f41913efed4fec Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 16 May 2012 15:55:48 +0200 Subject: [PATCH 0205/6849] NFC: Introduce target mode tx ops And rename the initiator mode data exchange ops for consistency sake. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 8 ++++---- include/net/nfc/nfc.h | 3 ++- net/nfc/core.c | 37 ++++++++++++++++++++----------------- net/nfc/hci/core.c | 8 ++++---- net/nfc/nci/core.c | 8 ++++---- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index c6b9bc5ac6e6..fd94c6f5d6a8 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1691,9 +1691,9 @@ error: return 0; } -static int pn533_data_exchange(struct nfc_dev *nfc_dev, - struct nfc_target *target, struct sk_buff *skb, - data_exchange_cb_t cb, void *cb_context) +static int pn533_transceive(struct nfc_dev *nfc_dev, + struct nfc_target *target, struct sk_buff *skb, + data_exchange_cb_t cb, void *cb_context) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_frame *out_frame, *in_frame; @@ -1853,7 +1853,7 @@ struct nfc_ops pn533_nfc_ops = { .stop_poll = pn533_stop_poll, .activate_target = pn533_activate_target, .deactivate_target = pn533_deactivate_target, - .data_exchange = pn533_data_exchange, + .im_transceive = pn533_transceive, }; static int pn533_probe(struct usb_interface *interface, diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index a6a7b49a3e2d..45c4c970575c 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -63,9 +63,10 @@ struct nfc_ops { u32 protocol); void (*deactivate_target)(struct nfc_dev *dev, struct nfc_target *target); - int (*data_exchange)(struct nfc_dev *dev, struct nfc_target *target, + int (*im_transceive)(struct nfc_dev *dev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); + int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb); int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target); }; diff --git a/net/nfc/core.c b/net/nfc/core.c index 722a0c76c669..76c1e207d297 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -413,27 +413,30 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, goto error; } - if (dev->active_target == NULL) { - rc = -ENOTCONN; - kfree_skb(skb); - goto error; - } + if (dev->rf_mode == NFC_RF_INITIATOR && dev->active_target != NULL) { + if (dev->active_target->idx != target_idx) { + rc = -EADDRNOTAVAIL; + kfree_skb(skb); + goto error; + } - if (dev->active_target->idx != target_idx) { - rc = -EADDRNOTAVAIL; + if (dev->ops->check_presence) + del_timer_sync(&dev->check_pres_timer); + + rc = dev->ops->im_transceive(dev, dev->active_target, skb, cb, + cb_context); + + if (!rc && dev->ops->check_presence) + mod_timer(&dev->check_pres_timer, jiffies + + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); + } else if (dev->rf_mode == NFC_RF_TARGET && dev->ops->tm_send != NULL) { + rc = dev->ops->tm_send(dev, skb); + } else { + rc = -ENOTCONN; kfree_skb(skb); goto error; } - if (dev->ops->check_presence) - del_timer_sync(&dev->check_pres_timer); - - rc = dev->ops->data_exchange(dev, dev->active_target, skb, cb, - cb_context); - - if (!rc && dev->ops->check_presence) - mod_timer(&dev->check_pres_timer, jiffies + - msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); error: device_unlock(&dev->dev); @@ -727,7 +730,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, struct nfc_dev *dev; if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || - !ops->deactivate_target || !ops->data_exchange) + !ops->deactivate_target || !ops->im_transceive) return NULL; if (!supported_protocols) diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index 281f3a3bec00..a8b0b71e8f86 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c @@ -512,9 +512,9 @@ static void hci_deactivate_target(struct nfc_dev *nfc_dev, { } -static int hci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target, - struct sk_buff *skb, data_exchange_cb_t cb, - void *cb_context) +static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, + struct sk_buff *skb, data_exchange_cb_t cb, + void *cb_context) { struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); int r; @@ -580,7 +580,7 @@ static struct nfc_ops hci_nfc_ops = { .stop_poll = hci_stop_poll, .activate_target = hci_activate_target, .deactivate_target = hci_deactivate_target, - .data_exchange = hci_data_exchange, + .im_transceive = hci_transceive, .check_presence = hci_check_presence, }; diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 0f718982f808..766a02b1dfa1 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -522,9 +522,9 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, } } -static int nci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target, - struct sk_buff *skb, - data_exchange_cb_t cb, void *cb_context) +static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, + struct sk_buff *skb, + data_exchange_cb_t cb, void *cb_context) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); int rc; @@ -557,7 +557,7 @@ static struct nfc_ops nci_nfc_ops = { .stop_poll = nci_stop_poll, .activate_target = nci_activate_target, .deactivate_target = nci_deactivate_target, - .data_exchange = nci_data_exchange, + .im_transceive = nci_transceive, }; /* ---- Interface to NCI drivers ---- */ -- GitLab From 73167ced31d15c04e57b9e0885ac05675e9195a4 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 00:05:50 +0200 Subject: [PATCH 0206/6849] NFC: Introduce target mode rx data callback This routine will be called by drivers whenever they receive data in target mode. This should be unexpected events and as such should be handled by a standalone API (i.e. not as a callback pointer from an existing API). Signed-off-by: Samuel Ortiz --- include/net/nfc/nfc.h | 1 + net/nfc/core.c | 12 ++++++++++++ net/nfc/llcp/llcp.c | 15 +++++++++++++++ net/nfc/nfc.h | 7 +++++++ 4 files changed, 35 insertions(+) diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 45c4c970575c..180964b954ab 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -202,5 +202,6 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, u8 *gb, size_t gb_len); int nfc_tm_deactivated(struct nfc_dev *dev); +int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb); #endif /* __NET_NFC_H */ diff --git a/net/nfc/core.c b/net/nfc/core.c index 76c1e207d297..6a3799eebc30 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -462,6 +462,18 @@ u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len) } EXPORT_SYMBOL(nfc_get_local_general_bytes); +int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb) +{ + /* Only LLCP target mode for now */ + if (dev->dep_link_up == false) { + kfree_skb(skb); + return -ENOLINK; + } + + return nfc_llcp_data_received(dev, skb); +} +EXPORT_SYMBOL(nfc_tm_data_received); + int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, u8 *gb, size_t gb_len) { diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 5f7aa3f632fb..5705e6dffb32 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -937,6 +937,21 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) return; } +int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb) +{ + struct nfc_llcp_local *local; + + local = nfc_llcp_find_local(dev); + if (local == NULL) + return -ENODEV; + + local->rx_pending = skb_get(skb); + del_timer(&local->link_timer); + queue_work(local->rx_wq, &local->rx_work); + + return 0; +} + void nfc_llcp_mac_is_down(struct nfc_dev *dev) { struct nfc_llcp_local *local; diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index cd9fcbe57464..c5e42b79a418 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -55,6 +55,7 @@ int nfc_llcp_register_device(struct nfc_dev *dev); void nfc_llcp_unregister_device(struct nfc_dev *dev); int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); +int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); int __init nfc_llcp_init(void); void nfc_llcp_exit(void); @@ -90,6 +91,12 @@ static inline u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *gb_len) return NULL; } +static inline int nfc_llcp_data_received(struct nfc_dev *dev, + struct sk_buff *skb) +{ + return 0; +} + static inline int nfc_llcp_init(void) { return 0; -- GitLab From 103b34cf5fe2bb72c38afa8523dd206e6ef3b5fe Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 00:07:51 +0200 Subject: [PATCH 0207/6849] NFC: Implement the pn533 target mode data fetching routine This one needs to be called as soon as we are activated as a target, for the pn533 to receive the first SYMM and keep the LLCP link alive. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 85 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index fd94c6f5d6a8..6a506e267d20 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 #define PN533_CMD_TG_INIT_AS_TARGET 0x8c +#define PN533_CMD_TG_GET_DATA 0x86 #define PN533_CMD_RESPONSE(cmd) (cmd + 1) @@ -83,6 +84,9 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_MI_MASK 0x40 #define PN533_CMD_RET_SUCCESS 0x00 +/* PN533 status codes */ +#define PN533_STATUS_TARGET_RELEASED 0x29 + struct pn533; typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, @@ -296,6 +300,7 @@ struct pn533 { struct workqueue_struct *wq; struct work_struct cmd_work; struct work_struct mi_work; + struct work_struct tg_work; struct pn533_frame *wq_in_frame; int wq_in_error; @@ -1132,6 +1137,68 @@ static int pn533_init_target_frame(struct pn533_frame *frame, return 0; } +#define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) +#define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 +static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) +{ + struct sk_buff *skb_resp = arg; + struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + if (params_len < 0) { + nfc_dev_err(&dev->interface->dev, + "Error %d when starting as a target", + params_len); + + return params_len; + } + + if (params_len > 0 && params[0] != 0) { + nfc_tm_deactivated(dev->nfc_dev); + + kfree_skb(skb_resp); + return 0; + } + + skb_put(skb_resp, PN533_FRAME_SIZE(in_frame)); + skb_pull(skb_resp, PN533_CMD_DATAEXCH_HEAD_LEN); + skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_SIZE); + + return nfc_tm_data_received(dev->nfc_dev, skb_resp); +} + +static void pn533_wq_tg_get_data(struct work_struct *work) +{ + struct pn533 *dev = container_of(work, struct pn533, tg_work); + struct pn533_frame *in_frame; + struct sk_buff *skb_resp; + size_t skb_resp_len; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN + + PN533_CMD_DATAEXCH_DATA_MAXLEN + + PN533_FRAME_TAIL_SIZE; + + skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); + if (!skb_resp) + return; + + in_frame = (struct pn533_frame *)skb_resp->data; + + pn533_tx_frame_init(dev->out_frame, PN533_CMD_TG_GET_DATA); + pn533_tx_frame_finish(dev->out_frame); + + pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame, + skb_resp_len, + pn533_tm_get_data_complete, + skb_resp, GFP_KERNEL); + + return; +} + #define ATR_REQ_GB_OFFSET 17 static int pn533_init_target_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) @@ -1139,6 +1206,7 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, struct pn533_cmd_init_target_response *resp; u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; size_t gb_len; + int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1169,8 +1237,17 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, gb = resp->cmd + ATR_REQ_GB_OFFSET; gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); - return nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, - comm_mode, gb, gb_len); + rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, + comm_mode, gb, gb_len); + if (rc < 0) { + nfc_dev_err(&dev->interface->dev, + "Error when signaling target activation"); + return rc; + } + + queue_work(dev->wq, &dev->tg_work); + + return 0; } static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) @@ -1553,9 +1630,6 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) return 0; } -#define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) -#define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 - static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) { int payload_len = skb->len; @@ -1920,6 +1994,7 @@ static int pn533_probe(struct usb_interface *interface, INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); + INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data); dev->wq = alloc_workqueue("pn533", WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); -- GitLab From dadb06f270ad7cd9572b82995f6261f8ca4620ac Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 00:09:11 +0200 Subject: [PATCH 0208/6849] NFC: Implement the pn533 target mode Tx op Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 82 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 6a506e267d20..db4078765ac9 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -76,6 +76,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_GET_DATA 0x86 +#define PN533_CMD_TG_SET_DATA 0x8e #define PN533_CMD_RESPONSE(cmd) (cmd + 1) @@ -1630,7 +1631,8 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) return 0; } -static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) +static int pn533_build_tx_frame(struct pn533 *dev, struct sk_buff *skb, + bool target) { int payload_len = skb->len; struct pn533_frame *out_frame; @@ -1647,14 +1649,20 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) return -ENOSYS; } - skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); - out_frame = (struct pn533_frame *) skb->data; + if (target == true) { + skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); + out_frame = (struct pn533_frame *) skb->data; - pn533_tx_frame_init(out_frame, PN533_CMD_IN_DATA_EXCHANGE); + pn533_tx_frame_init(out_frame, PN533_CMD_IN_DATA_EXCHANGE); + tg = 1; + memcpy(PN533_FRAME_CMD_PARAMS_PTR(out_frame), &tg, sizeof(u8)); + out_frame->datalen += sizeof(u8); + } else { + skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN - 1); + out_frame = (struct pn533_frame *) skb->data; + pn533_tx_frame_init(out_frame, PN533_CMD_TG_SET_DATA); + } - tg = 1; - memcpy(PN533_FRAME_CMD_PARAMS_PTR(out_frame), &tg, sizeof(u8)); - out_frame->datalen += sizeof(u8); /* The data is already in the out_frame, just update the datalen */ out_frame->datalen += payload_len; @@ -1785,7 +1793,7 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, goto error; } - rc = pn533_data_exchange_tx_frame(dev, skb); + rc = pn533_build_tx_frame(dev, skb, true); if (rc) goto error; @@ -1833,6 +1841,61 @@ error: return rc; } +static int pn533_tm_send_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) +{ + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + if (params_len < 0) { + nfc_dev_err(&dev->interface->dev, + "Error %d when sending data", + params_len); + + return params_len; + } + + if (params_len > 0 && params[0] != 0) { + nfc_tm_deactivated(dev->nfc_dev); + + return 0; + } + + queue_work(dev->wq, &dev->tg_work); + + return 0; +} + +static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + struct pn533_frame *out_frame; + int rc; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + rc = pn533_build_tx_frame(dev, skb, false); + if (rc) + goto error; + + out_frame = (struct pn533_frame *) skb->data; + + rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, + dev->in_maxlen, pn533_tm_send_complete, + NULL, GFP_KERNEL); + if (rc) { + nfc_dev_err(&dev->interface->dev, + "Error %d when trying to send data", rc); + goto error; + } + + return 0; + +error: + kfree_skb(skb); + + return rc; +} + static void pn533_wq_mi_recv(struct work_struct *work) { struct pn533 *dev = container_of(work, struct pn533, mi_work); @@ -1853,7 +1916,7 @@ static void pn533_wq_mi_recv(struct work_struct *work) skb_reserve(skb_cmd, PN533_CMD_DATAEXCH_HEAD_LEN); - rc = pn533_data_exchange_tx_frame(dev, skb_cmd); + rc = pn533_build_tx_frame(dev, skb_cmd, true); if (rc) goto error_frame; @@ -1928,6 +1991,7 @@ struct nfc_ops pn533_nfc_ops = { .activate_target = pn533_activate_target, .deactivate_target = pn533_deactivate_target, .im_transceive = pn533_transceive, + .tm_send = pn533_tm_send, }; static int pn533_probe(struct usb_interface *interface, -- GitLab From 5a0f6f3b46b28310262ad9585b80062ef56c5362 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 21 May 2012 11:44:42 +0200 Subject: [PATCH 0209/6849] NFC: Don't hold a NULL connecting LLCP socket lock Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 5705e6dffb32..b694313c2be5 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -477,8 +477,10 @@ static struct nfc_llcp_sock *nfc_llcp_connecting_sock_get(struct nfc_llcp_local sk_for_each(sk, node, &local->connecting_sockets.head) { llcp_sock = nfc_llcp_sock(sk); - if (llcp_sock->ssap == ssap) + if (llcp_sock->ssap == ssap) { + sock_hold(&llcp_sock->sk); goto out; + } } llcp_sock = NULL; @@ -486,8 +488,6 @@ static struct nfc_llcp_sock *nfc_llcp_connecting_sock_get(struct nfc_llcp_local out: read_unlock(&local->connecting_sockets.lock); - sock_hold(&llcp_sock->sk); - return llcp_sock; } -- GitLab From cb3a4503f41f7f60bbc74a937bc30a0e143fc53c Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 21 May 2012 15:59:52 +0200 Subject: [PATCH 0210/6849] NFC: Call the DEP link down ops even when in target mode Even in target mode we need to let the driver know that we want to bring the DEP link down. Signed-off-by: Samuel Ortiz --- net/nfc/core.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/net/nfc/core.c b/net/nfc/core.c index 6a3799eebc30..4177bb5104b9 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -268,11 +268,6 @@ int nfc_dep_link_down(struct nfc_dev *dev) goto error; } - if (dev->rf_mode == NFC_RF_TARGET) { - rc = -EOPNOTSUPP; - goto error; - } - rc = dev->ops->dep_link_down(dev); if (!rc) { dev->dep_link_up = false; -- GitLab From 7c2a04a933d51b45af7660bd1790339eb3c33308 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 21 May 2012 16:20:01 +0200 Subject: [PATCH 0211/6849] NFC: Reset poll mod list when stopping pn533 poll Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index db4078765ac9..6b8a65ca0d71 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1371,6 +1371,8 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev) /* prevent pn533_start_poll_complete to issue a new poll meanwhile */ usb_kill_urb(dev->in_urb); + + pn533_poll_reset_mod_list(dev); } static int pn533_activate_target_nfcdep(struct pn533 *dev) -- GitLab From 9f2f8ba172d9a7f7f600ced18b05f6fd52b83396 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 29 May 2012 21:28:58 +0200 Subject: [PATCH 0212/6849] NFC: Unregister device if pn533 initial configuration fails Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 6b8a65ca0d71..2a7e4e8e4f11 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -2112,13 +2112,17 @@ static int pn533_probe(struct usb_interface *interface, if (rc) { nfc_dev_err(&dev->interface->dev, "Error on setting MAX_RETRIES" " config"); - goto free_nfc_dev; + goto unregister_nfc_dev; } return 0; +unregister_nfc_dev: + nfc_unregister_device(dev->nfc_dev); + free_nfc_dev: nfc_free_device(dev->nfc_dev); + destroy_wq: destroy_workqueue(dev->wq); error: -- GitLab From 34a85bfcfb84fe673833290ee071de0a10dd1cac Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 29 May 2012 21:34:08 +0200 Subject: [PATCH 0213/6849] NFC: Configure pn533 RF timings Those define the ATR_RES response timeout after which the pn533 considers the target to be mute. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 2a7e4e8e4f11..d9763440b8e9 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -104,8 +104,14 @@ struct pn533_fw_version { }; /* PN533_CMD_RF_CONFIGURATION */ +#define PN533_CFGITEM_TIMING 0x02 #define PN533_CFGITEM_MAX_RETRIES 0x05 +#define PN533_CONFIG_TIMING_102 0xb +#define PN533_CONFIG_TIMING_204 0xc +#define PN533_CONFIG_TIMING_409 0xd +#define PN533_CONFIG_TIMING_819 0xe + #define PN533_CONFIG_MAX_RETRIES_NO_RETRY 0x00 #define PN533_CONFIG_MAX_RETRIES_ENDLESS 0xFF @@ -115,6 +121,12 @@ struct pn533_config_max_retries { u8 mx_rty_passive_act; } __packed; +struct pn533_config_timing { + u8 rfu; + u8 atr_res_timeout; + u8 dep_timeout; +} __packed; + /* PN533_CMD_IN_LIST_PASSIVE_TARGET */ /* felica commands opcode */ @@ -2004,6 +2016,7 @@ static int pn533_probe(struct usb_interface *interface, struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; struct pn533_config_max_retries max_retries; + struct pn533_config_timing timing; int in_endpoint = 0; int out_endpoint = 0; int rc = -ENOMEM; @@ -2115,6 +2128,18 @@ static int pn533_probe(struct usb_interface *interface, goto unregister_nfc_dev; } + timing.rfu = PN533_CONFIG_TIMING_102; + timing.atr_res_timeout = PN533_CONFIG_TIMING_204; + timing.dep_timeout = PN533_CONFIG_TIMING_409; + + rc = pn533_set_configuration(dev, PN533_CFGITEM_TIMING, + (u8 *) &timing, sizeof(timing)); + if (rc) { + nfc_dev_err(&dev->interface->dev, + "Error on setting RF timings"); + goto unregister_nfc_dev; + } + return 0; unregister_nfc_dev: -- GitLab From d7f3345d3af568394080890ca3136c4ea1021cba Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 29 May 2012 21:45:21 +0200 Subject: [PATCH 0214/6849] NFC: Add passive initiator data for pn533 When trying to enable a DEP link as a passive initiator, pn533 needs to provide the polling request command payload. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index d9763440b8e9..806ab3da6414 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -256,7 +256,7 @@ struct pn533_cmd_jump_dep { u8 active; u8 baud; u8 next; - u8 gt[]; + u8 data[]; } __packed; struct pn533_cmd_jump_dep_response { @@ -1582,12 +1582,14 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, return 0; } +#define PASSIVE_DATA_LEN 5 static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, u8 comm_mode, u8* gb, size_t gb_len) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_cmd_jump_dep *cmd; - u8 cmd_len; + u8 cmd_len, *data_ptr; + u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3}; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1605,6 +1607,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, } cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len; + if (comm_mode == NFC_COMM_PASSIVE) + cmd_len += PASSIVE_DATA_LEN; + cmd = kzalloc(cmd_len, GFP_KERNEL); if (cmd == NULL) return -ENOMEM; @@ -1612,10 +1617,18 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_JUMP_FOR_DEP); cmd->active = !comm_mode; - cmd->baud = 0; + cmd->next = 0; + cmd->baud = 2; + data_ptr = cmd->data; + if (comm_mode == NFC_COMM_PASSIVE && cmd->baud > 0) { + memcpy(data_ptr, passive_data, PASSIVE_DATA_LEN); + cmd->next |= 1; + data_ptr += PASSIVE_DATA_LEN; + } + if (gb != NULL && gb_len > 0) { - cmd->next = 4; /* We have some Gi */ - memcpy(cmd->gt, gb, gb_len); + cmd->next |= 4; /* We have some Gi */ + memcpy(data_ptr, gb, gb_len); } else { cmd->next = 0; } -- GitLab From 51d9e803b906ea8ef995980d5367ab66ff79305a Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 30 May 2012 01:48:46 +0200 Subject: [PATCH 0215/6849] NFC: Add type A and type F parameters for pn533 target mode Without those settings several devices will not activate pn533 as a target. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 806ab3da6414..6e4b228c7e6f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1126,6 +1126,13 @@ static int pn533_init_target_frame(struct pn533_frame *frame, { struct pn533_cmd_init_target *cmd; size_t cmd_len; + u8 felica_params[18] = {0x1, 0xfe, /* DEP */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* random */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff}; /* System code */ + u8 mifare_params[6] = {0x1, 0x1, /* SENS_RES */ + 0x0, 0x0, 0x0, + 0x40}; /* SEL_RES for DEP */ cmd_len = sizeof(struct pn533_cmd_init_target) + gb_len + 1; cmd = kzalloc(cmd_len, GFP_KERNEL); @@ -1136,17 +1143,33 @@ static int pn533_init_target_frame(struct pn533_frame *frame, /* DEP support only */ cmd->mode |= PN533_INIT_TARGET_DEP; - get_random_bytes(cmd->nfcid3, 10); + + /* Felica params */ + memcpy(cmd->felica, felica_params, 18); + get_random_bytes(cmd->felica + 2, 6); + + /* NFCID3 */ + memset(cmd->nfcid3, 0, 10); + memcpy(cmd->nfcid3, cmd->felica, 8); + + /* MIFARE params */ + memcpy(cmd->mifare, mifare_params, 6); + + /* General bytes */ cmd->gb_len = gb_len; memcpy(cmd->gb, gb, gb_len); + /* Len Tk */ cmd->gb[gb_len] = 0; memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), cmd, cmd_len); + frame->datalen += cmd_len; pn533_tx_frame_finish(frame); + kfree(cmd); + return 0; } -- GitLab From 6fbbdc16be3881aabaa4096c3466b9bbd361bd1f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 30 May 2012 17:20:25 +0200 Subject: [PATCH 0216/6849] NFC: Implement pn533 polling loop After going through all the modulations, the pn533 driver spends 2 seconds listening for targets. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 287 +++++++++++++++++++++++++------------------- 1 file changed, 161 insertions(+), 126 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 6e4b228c7e6f..c9ba96c320fe 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -45,6 +45,9 @@ static const struct usb_device_id pn533_table[] = { }; MODULE_DEVICE_TABLE(usb, pn533_table); +/* How much time we spend listening for initiators */ +#define PN533_LISTEN_TIME 2 + /* frame definitions */ #define PN533_FRAME_TAIL_SIZE 2 #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ @@ -163,6 +166,7 @@ enum { PN533_POLL_MOD_424KBPS_FELICA, PN533_POLL_MOD_106KBPS_JEWEL, PN533_POLL_MOD_847KBPS_B, + PN533_LISTEN_MOD, __PN533_POLL_MOD_AFTER_LAST, }; @@ -230,6 +234,9 @@ const struct pn533_poll_modulations poll_mod[] = { }, .len = 3, }, + [PN533_LISTEN_MOD] = { + .len = 0, + }, }; /* PN533_CMD_IN_ATR */ @@ -312,10 +319,13 @@ struct pn533 { struct workqueue_struct *wq; struct work_struct cmd_work; + struct work_struct poll_work; struct work_struct mi_work; struct work_struct tg_work; + struct timer_list listen_timer; struct pn533_frame *wq_in_frame; int wq_in_error; + int cancel_listen; pn533_cmd_complete_t cmd_complete; void *cmd_complete_arg; @@ -326,6 +336,10 @@ struct pn533 { u8 poll_mod_count; u8 poll_mod_curr; u32 poll_protocols; + u32 listen_protocols; + + u8 *gb; + size_t gb_len; u8 tgt_available_prots; u8 tgt_active_prot; @@ -1006,6 +1020,11 @@ static int pn533_target_found(struct pn533 *dev, return 0; } +static inline void pn533_poll_next_mod(struct pn533 *dev) +{ + dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count; +} + static void pn533_poll_reset_mod_list(struct pn533 *dev) { dev->poll_mod_count = 0; @@ -1018,107 +1037,52 @@ static void pn533_poll_add_mod(struct pn533 *dev, u8 mod_index) dev->poll_mod_count++; } -static void pn533_poll_create_mod_list(struct pn533 *dev, u32 protocols) +static void pn533_poll_create_mod_list(struct pn533 *dev, + u32 im_protocols, u32 tm_protocols) { pn533_poll_reset_mod_list(dev); - if (protocols & NFC_PROTO_MIFARE_MASK - || protocols & NFC_PROTO_ISO14443_MASK - || protocols & NFC_PROTO_NFC_DEP_MASK) + if (im_protocols & NFC_PROTO_MIFARE_MASK + || im_protocols & NFC_PROTO_ISO14443_MASK + || im_protocols & NFC_PROTO_NFC_DEP_MASK) pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A); - if (protocols & NFC_PROTO_FELICA_MASK - || protocols & NFC_PROTO_NFC_DEP_MASK) { + if (im_protocols & NFC_PROTO_FELICA_MASK + || im_protocols & NFC_PROTO_NFC_DEP_MASK) { pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA); pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA); } - if (protocols & NFC_PROTO_JEWEL_MASK) + if (im_protocols & NFC_PROTO_JEWEL_MASK) pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL); - if (protocols & NFC_PROTO_ISO14443_MASK) + if (im_protocols & NFC_PROTO_ISO14443_MASK) pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B); -} - -static void pn533_start_poll_frame(struct pn533_frame *frame, - struct pn533_poll_modulations *mod) -{ - - pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET); - memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len); - frame->datalen += mod->len; - - pn533_tx_frame_finish(frame); + if (tm_protocols) + pn533_poll_add_mod(dev, PN533_LISTEN_MOD); } static int pn533_start_poll_complete(struct pn533 *dev, void *arg, - u8 *params, int params_len) + u8 *params, int params_len) { struct pn533_poll_response *resp; - struct pn533_poll_modulations *next_mod; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - if (params_len == -ENOENT) { - nfc_dev_dbg(&dev->interface->dev, "Polling operation has been" - " stopped"); - goto stop_poll; - } - - if (params_len < 0) { - nfc_dev_err(&dev->interface->dev, "Error %d when running poll", - params_len); - goto stop_poll; - } - resp = (struct pn533_poll_response *) params; if (resp->nbtg) { rc = pn533_target_found(dev, resp, params_len); /* We must stop the poll after a valid target found */ - if (rc == 0) - goto stop_poll; - - if (rc != -EAGAIN) - nfc_dev_err(&dev->interface->dev, "The target found is" - " not valid - continuing to poll"); - } - - dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count; - - next_mod = dev->poll_mod_active[dev->poll_mod_curr]; - - nfc_dev_dbg(&dev->interface->dev, "Polling next modulation (0x%x)", - dev->poll_mod_curr); - - pn533_start_poll_frame(dev->out_frame, next_mod); - - /* Don't need to down the semaphore again */ - rc = __pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen, pn533_start_poll_complete, - NULL, GFP_ATOMIC); - - if (rc == -EPERM) { - nfc_dev_dbg(&dev->interface->dev, "Cannot poll next modulation" - " because poll has been stopped"); - goto stop_poll; - } - - if (rc) { - nfc_dev_err(&dev->interface->dev, "Error %d when trying to poll" - " next modulation", rc); - goto stop_poll; + if (rc == 0) { + pn533_poll_reset_mod_list(dev); + return 0; + } } - /* Inform caller function to do not up the semaphore */ - return -EINPROGRESS; - -stop_poll: - pn533_poll_reset_mod_list(dev); - dev->poll_protocols = 0; - return 0; + return -EAGAIN; } static int pn533_init_target_frame(struct pn533_frame *frame, @@ -1286,83 +1250,136 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, return 0; } -static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) +static void pn533_listen_mode_timer(unsigned long data) { - struct pn533 *dev = nfc_get_drvdata(nfc_dev); - u8 *gb; - size_t gb_len; + struct pn533 *dev = (struct pn533 *) data; + + nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout"); + + /* An ack will cancel the last issued command (poll) */ + pn533_send_ack(dev, GFP_ATOMIC); + + dev->cancel_listen = 1; + + up(&dev->cmd_lock); + + pn533_poll_next_mod(dev); + + queue_work(dev->wq, &dev->poll_work); +} + +static int pn533_poll_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) +{ + struct pn533_poll_modulations *cur_mod; int rc; - pn533_poll_reset_mod_list(dev); + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - gb = nfc_get_local_general_bytes(nfc_dev, &gb_len); - if (gb == NULL) - return -ENOMEM; + if (params_len == -ENOENT) { + if (dev->poll_mod_count != 0) + return 0; - rc = pn533_init_target_frame(dev->out_frame, gb, gb_len); - if (rc < 0) - return rc; + nfc_dev_err(&dev->interface->dev, + "Polling operation has been stopped"); - rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen, - pn533_init_target_complete, - NULL, GFP_KERNEL); + goto stop_poll; + } - if (rc) + if (params_len < 0) { nfc_dev_err(&dev->interface->dev, - "Error %d when trying to initiate as a target", rc); + "Error %d when running poll", params_len); - dev->poll_mod_count++; + goto stop_poll; + } - return rc; + cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; + + if (cur_mod->len == 0) { + del_timer(&dev->listen_timer); + + return pn533_init_target_complete(dev, arg, params, params_len); + } else { + rc = pn533_start_poll_complete(dev, arg, params, params_len); + if (!rc) + return rc; + } + + pn533_poll_next_mod(dev); + + queue_work(dev->wq, &dev->poll_work); + + return 0; + +stop_poll: + pn533_poll_reset_mod_list(dev); + dev->poll_protocols = 0; + return 0; } -static int pn533_start_im_poll(struct nfc_dev *nfc_dev, u32 protocols) +static void pn533_build_poll_frame(struct pn533 *dev, + struct pn533_frame *frame, + struct pn533_poll_modulations *mod) { - struct pn533 *dev = nfc_get_drvdata(nfc_dev); - struct pn533_poll_modulations *start_mod; - int rc; + nfc_dev_dbg(&dev->interface->dev, "mod len %d\n", mod->len); - if (dev->poll_mod_count) { - nfc_dev_err(&dev->interface->dev, "Polling operation already" - " active"); - return -EBUSY; - } + if (mod->len == 0) { + /* Listen mode */ + pn533_init_target_frame(frame, dev->gb, dev->gb_len); + } else { + /* Polling mode */ + pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET); - pn533_poll_create_mod_list(dev, protocols); + memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len); + frame->datalen += mod->len; - if (!dev->poll_mod_count) { - nfc_dev_err(&dev->interface->dev, "No valid protocols" - " specified"); - rc = -EINVAL; - goto error; + pn533_tx_frame_finish(frame); } +} - nfc_dev_dbg(&dev->interface->dev, "It will poll %d modulations types", - dev->poll_mod_count); +static int pn533_send_poll_frame(struct pn533 *dev) +{ + struct pn533_poll_modulations *cur_mod; + int rc; - dev->poll_mod_curr = 0; - start_mod = dev->poll_mod_active[dev->poll_mod_curr]; + cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; - pn533_start_poll_frame(dev->out_frame, start_mod); + pn533_build_poll_frame(dev, dev->out_frame, cur_mod); rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen, pn533_start_poll_complete, + dev->in_maxlen, pn533_poll_complete, NULL, GFP_KERNEL); + if (rc) + nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc); - if (rc) { - nfc_dev_err(&dev->interface->dev, "Error %d when trying to" - " start poll", rc); - goto error; + return rc; +} + +static void pn533_wq_poll(struct work_struct *work) +{ + struct pn533 *dev = container_of(work, struct pn533, poll_work); + struct pn533_poll_modulations *cur_mod; + int rc; + + cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; + + nfc_dev_dbg(&dev->interface->dev, + "%s cancel_listen %d modulation len %d", + __func__, dev->cancel_listen, cur_mod->len); + + if (dev->cancel_listen == 1) { + dev->cancel_listen = 0; + usb_kill_urb(dev->in_urb); } - dev->poll_protocols = protocols; + rc = pn533_send_poll_frame(dev); + if (rc) + return; - return 0; + if (cur_mod->len == 0 && dev->poll_mod_count > 1) + mod_timer(&dev->listen_timer, jiffies + PN533_LISTEN_TIME * HZ); -error: - pn533_poll_reset_mod_list(dev); - return rc; + return; } static int pn533_start_poll(struct nfc_dev *nfc_dev, @@ -1380,13 +1397,18 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, return -EBUSY; } - if (im_protocols) - return pn533_start_im_poll(nfc_dev, im_protocols); + if (tm_protocols) { + dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len); + if (dev->gb == NULL) + tm_protocols = 0; + } - if (tm_protocols) - return pn533_init_target(nfc_dev, tm_protocols); + dev->poll_mod_curr = 0; + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); + dev->poll_protocols = im_protocols; + dev->listen_protocols = tm_protocols; - return -EINVAL; + return pn533_send_poll_frame(dev); } static void pn533_stop_poll(struct nfc_dev *nfc_dev) @@ -1395,6 +1417,8 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev) nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + del_timer(&dev->listen_timer); + if (!dev->poll_mod_count) { nfc_dev_dbg(&dev->interface->dev, "Polling operation was not" " running"); @@ -1676,6 +1700,10 @@ out: static int pn533_dep_link_down(struct nfc_dev *nfc_dev) { + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + + pn533_poll_reset_mod_list(dev); + pn533_deactivate_target(nfc_dev, 0); return 0; @@ -2110,12 +2138,17 @@ static int pn533_probe(struct usb_interface *interface, INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data); + INIT_WORK(&dev->poll_work, pn533_wq_poll); dev->wq = alloc_workqueue("pn533", WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); if (dev->wq == NULL) goto error; + init_timer(&dev->listen_timer); + dev->listen_timer.data = (unsigned long) dev; + dev->listen_timer.function = pn533_listen_mode_timer; + skb_queue_head_init(&dev->resp_q); usb_set_intfdata(interface, dev); @@ -2212,6 +2245,8 @@ static void pn533_disconnect(struct usb_interface *interface) skb_queue_purge(&dev->resp_q); + del_timer(&dev->listen_timer); + kfree(dev->in_frame); usb_free_urb(dev->in_urb); kfree(dev->out_frame); -- GitLab From 844579603889ef1ab1fdbf2223579d6842e62bfe Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 30 May 2012 17:48:29 +0200 Subject: [PATCH 0217/6849] NFC: Requeue lost LLCP frames When receiving an I or RR frame telling us that some of the pending queues were not received, we should requeue them before the currently pending ones. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 86 +++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index b694313c2be5..0fc60da6a0a1 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -411,28 +411,6 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) local->remote_gb_len - 3); } -static void nfc_llcp_tx_work(struct work_struct *work) -{ - struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, - tx_work); - struct sk_buff *skb; - - skb = skb_dequeue(&local->tx_queue); - if (skb != NULL) { - pr_debug("Sending pending skb\n"); - print_hex_dump(KERN_DEBUG, "LLCP Tx: ", DUMP_PREFIX_OFFSET, - 16, 1, skb->data, skb->len, true); - - nfc_data_exchange(local->dev, local->target_idx, - skb, nfc_llcp_recv, local); - } else { - nfc_llcp_send_symm(local->dev); - } - - mod_timer(&local->link_timer, - jiffies + msecs_to_jiffies(local->remote_lto)); -} - static u8 nfc_llcp_dsap(struct sk_buff *pdu) { return (pdu->data[0] & 0xfc) >> 2; @@ -465,6 +443,45 @@ static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu) sock->recv_ack_n = (sock->recv_n - 1) % 16; } +static void nfc_llcp_tx_work(struct work_struct *work) +{ + struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, + tx_work); + struct sk_buff *skb; + struct sock *sk; + struct nfc_llcp_sock *llcp_sock; + + skb = skb_dequeue(&local->tx_queue); + if (skb != NULL) { + sk = skb->sk; + llcp_sock = nfc_llcp_sock(sk); + if (llcp_sock != NULL) { + int ret; + + pr_debug("Sending pending skb\n"); + print_hex_dump(KERN_DEBUG, "LLCP Tx: ", + DUMP_PREFIX_OFFSET, 16, 1, + skb->data, skb->len, true); + + ret = nfc_data_exchange(local->dev, local->target_idx, + skb, nfc_llcp_recv, local); + + if (!ret && nfc_llcp_ptype(skb) == LLCP_PDU_I) { + skb = skb_get(skb); + skb_queue_tail(&llcp_sock->tx_pending_queue, + skb); + } + } else { + nfc_llcp_send_symm(local->dev); + } + } else { + nfc_llcp_send_symm(local->dev); + } + + mod_timer(&local->link_timer, + jiffies + msecs_to_jiffies(2 * local->remote_lto)); +} + static struct nfc_llcp_sock *nfc_llcp_connecting_sock_get(struct nfc_llcp_local *local, u8 ssap) { @@ -705,7 +722,7 @@ int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) /* Try to queue some I frames for transmission */ while (sock->remote_ready && skb_queue_len(&sock->tx_pending_queue) < sock->rw) { - struct sk_buff *pdu, *pending_pdu; + struct sk_buff *pdu; pdu = skb_dequeue(&sock->tx_queue); if (pdu == NULL) @@ -714,10 +731,7 @@ int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) /* Update N(S)/N(R) */ nfc_llcp_set_nrns(sock, pdu); - pending_pdu = skb_clone(pdu, GFP_KERNEL); - skb_queue_tail(&local->tx_queue, pdu); - skb_queue_tail(&sock->tx_pending_queue, pending_pdu); nr_frames++; } @@ -774,11 +788,21 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, llcp_sock->send_ack_n = nr; - skb_queue_walk_safe(&llcp_sock->tx_pending_queue, s, tmp) - if (nfc_llcp_ns(s) <= nr) { - skb_unlink(s, &llcp_sock->tx_pending_queue); - kfree_skb(s); - } + /* Remove and free all skbs until ns == nr */ + skb_queue_walk_safe(&llcp_sock->tx_pending_queue, s, tmp) { + skb_unlink(s, &llcp_sock->tx_pending_queue); + kfree_skb(s); + + if (nfc_llcp_ns(s) == nr) + break; + } + + /* Re-queue the remaining skbs for transmission */ + skb_queue_reverse_walk_safe(&llcp_sock->tx_pending_queue, + s, tmp) { + skb_unlink(s, &llcp_sock->tx_pending_queue); + skb_queue_head(&local->tx_queue, s); + } } if (ptype == LLCP_PDU_RR) -- GitLab From 56af2568c27ee697a5a34cf037e3253e7b77e80b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 30 May 2012 18:06:11 +0200 Subject: [PATCH 0218/6849] NFC: Send a receiver ready frame only to reply to an I frame Sending an RR as a reply to another RR is fine but not quite logical. We should send RRs only as a reply to I frames. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 0fc60da6a0a1..3fe68e1d2e88 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -810,7 +810,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, else if (ptype == LLCP_PDU_RNR) llcp_sock->remote_ready = false; - if (nfc_llcp_queue_i_frames(llcp_sock) == 0) + if (nfc_llcp_queue_i_frames(llcp_sock) == 0 && ptype == LLCP_PDU_I) nfc_llcp_send_rr(llcp_sock); release_sock(sk); -- GitLab From 5e50ee3ae6e465be89dd0a66f78c3211a412d595 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 11:48:58 +0200 Subject: [PATCH 0219/6849] NFC: Switch to Initiator mode when getting NFC_ATTR_PROTOCOLS That is needed for keeping backward compatibility with apps using the old netlink polling API (NFC_ATTR_PROTOCOLS instead of NFC_ATTR_IM_PROTOCOLS). Signed-off-by: Samuel Ortiz --- net/nfc/netlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 21eaa9b5c6bf..03c31db38f12 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -597,11 +597,11 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NFC_ATTR_TM_PROTOCOLS]) tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]); - else if (info->attrs[NFC_ATTR_PROTOCOLS]) - tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]); if (info->attrs[NFC_ATTR_IM_PROTOCOLS]) im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]); + else if (info->attrs[NFC_ATTR_PROTOCOLS]) + im_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]); dev = nfc_get_device(idx); if (!dev) -- GitLab From 07922bb1e0eb3fb4e559eea2430a35dbf33659e0 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 17:29:15 +0200 Subject: [PATCH 0220/6849] NFC: Destroy LLCP timout workqueue when releasing the link Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 3fe68e1d2e88..5d503eeb15a1 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -111,6 +111,7 @@ static void local_release(struct kref *ref) skb_queue_purge(&local->tx_queue); destroy_workqueue(local->tx_wq); destroy_workqueue(local->rx_wq); + destroy_workqueue(local->timeout_wq); kfree_skb(local->rx_pending); kfree(local); } -- GitLab From 41a8ec496de8f4ef161fa0293de8cd9aa5773325 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 17:44:44 +0200 Subject: [PATCH 0221/6849] NFC: Set the proper baud rate when trying to activate pn533 targets We get the right baud rate from the last polled modulation. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index c9ba96c320fe..b97e3c81ec0b 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1629,6 +1629,20 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, return 0; } +static int pn533_mod_to_baud(struct pn533 *dev) +{ + switch (dev->poll_mod_curr) { + case PN533_POLL_MOD_106KBPS_A: + return 0; + case PN533_POLL_MOD_212KBPS_FELICA: + return 1; + case PN533_POLL_MOD_424KBPS_FELICA: + return 2; + default: + return -EINVAL; + } +} + #define PASSIVE_DATA_LEN 5 static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, u8 comm_mode, u8* gb, size_t gb_len) @@ -1637,7 +1651,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, struct pn533_cmd_jump_dep *cmd; u8 cmd_len, *data_ptr; u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3}; - int rc; + int rc, baud; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1653,6 +1667,13 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, return -EBUSY; } + baud = pn533_mod_to_baud(dev); + if (baud < 0) { + nfc_dev_err(&dev->interface->dev, + "Invalid curr modulation %d", dev->poll_mod_curr); + return baud; + } + cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len; if (comm_mode == NFC_COMM_PASSIVE) cmd_len += PASSIVE_DATA_LEN; @@ -1665,7 +1686,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, cmd->active = !comm_mode; cmd->next = 0; - cmd->baud = 2; + cmd->baud = baud; data_ptr = cmd->data; if (comm_mode == NFC_COMM_PASSIVE && cmd->baud > 0) { memcpy(data_ptr, passive_data, PASSIVE_DATA_LEN); -- GitLab From 0201ed0349a71cec12ced7e142e6df78504f38fb Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 17:56:46 +0200 Subject: [PATCH 0222/6849] NFC: Convert pn533 from semaphore to mutex Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index b97e3c81ec0b..58c1641cf658 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -329,7 +329,7 @@ struct pn533 { pn533_cmd_complete_t cmd_complete; void *cmd_complete_arg; - struct semaphore cmd_lock; + struct mutex cmd_lock; u8 cmd; struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1]; @@ -462,7 +462,7 @@ static void pn533_wq_cmd_complete(struct work_struct *work) PN533_FRAME_CMD_PARAMS_LEN(in_frame)); if (rc != -EINPROGRESS) - up(&dev->cmd_lock); + mutex_unlock(&dev->cmd_lock); } static void pn533_recv_response(struct urb *urb) @@ -640,7 +640,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - if (down_trylock(&dev->cmd_lock)) + if (!mutex_trylock(&dev->cmd_lock)) return -EBUSY; rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame, @@ -650,7 +650,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, return 0; error: - up(&dev->cmd_lock); + mutex_unlock(&dev->cmd_lock); return rc; } @@ -1261,7 +1261,7 @@ static void pn533_listen_mode_timer(unsigned long data) dev->cancel_listen = 1; - up(&dev->cmd_lock); + mutex_unlock(&dev->cmd_lock); pn533_poll_next_mod(dev); @@ -2054,7 +2054,7 @@ error_cmd: kfree(arg); - up(&dev->cmd_lock); + mutex_unlock(&dev->cmd_lock); } static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata, @@ -2114,7 +2114,7 @@ static int pn533_probe(struct usb_interface *interface, dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; - sema_init(&dev->cmd_lock, 1); + mutex_init(&dev->cmd_lock); iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { -- GitLab From 51ad304cc8db5589d1e7b0a9df3858381753d788 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 31 May 2012 20:01:32 +0200 Subject: [PATCH 0223/6849] NFC: Monitor pn533 target mode When receiving a DEP link down event, we should cancel all pending URBs if we're activated as a target or if we're an initiator. Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 58c1641cf658..9ac829e22e73 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -343,6 +343,7 @@ struct pn533 { u8 tgt_available_prots; u8 tgt_active_prot; + u8 tgt_mode; }; struct pn533_frame { @@ -1158,6 +1159,8 @@ static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg, if (params_len > 0 && params[0] != 0) { nfc_tm_deactivated(dev->nfc_dev); + dev->tgt_mode = 0; + kfree_skb(skb_resp); return 0; } @@ -1245,6 +1248,8 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, return rc; } + dev->tgt_mode = 1; + queue_work(dev->wq, &dev->tg_work); return 0; @@ -1397,6 +1402,12 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, return -EBUSY; } + if (dev->tgt_mode) { + nfc_dev_err(&dev->interface->dev, + "Cannot poll while already being activated"); + return -EBUSY; + } + if (tm_protocols) { dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len); if (dev->gb == NULL) @@ -1725,7 +1736,15 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) pn533_poll_reset_mod_list(dev); - pn533_deactivate_target(nfc_dev, 0); + if (dev->tgt_mode || dev->tgt_active_prot) { + pn533_send_ack(dev, GFP_KERNEL); + usb_kill_urb(dev->in_urb); + } + + dev->tgt_active_prot = 0; + dev->tgt_mode = 0; + + skb_queue_purge(&dev->resp_q); return 0; } @@ -1956,6 +1975,8 @@ static int pn533_tm_send_complete(struct pn533 *dev, void *arg, if (params_len > 0 && params[0] != 0) { nfc_tm_deactivated(dev->nfc_dev); + dev->tgt_mode = 0; + return 0; } -- GitLab From 55c03cff7fd73349473cc0a964df9d55b312dbbc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 May 2012 17:12:12 -0700 Subject: [PATCH 0224/6849] staging: comedi: remove private header comedi_pci.h Remove the private header, comedi_pci.h, by moving the two helper functions into divers.c and providing the prototypes in comedidev.h. This allows the comedi_pci_enable/disable helper functions to be shared instead of having an inline version in every comedi pci driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 5 +- drivers/staging/comedi/drivers.c | 34 +++++++++++ .../drivers/addi-data/addi_amcc_s5933.h | 2 - drivers/staging/comedi/drivers/adl_pci6208.c | 1 - drivers/staging/comedi/drivers/adl_pci7230.c | 1 - drivers/staging/comedi/drivers/adl_pci7296.c | 1 - drivers/staging/comedi/drivers/adl_pci7432.c | 1 - drivers/staging/comedi/drivers/adl_pci8164.c | 1 - drivers/staging/comedi/drivers/adl_pci9111.c | 1 - drivers/staging/comedi/drivers/adl_pci9118.c | 1 - drivers/staging/comedi/drivers/adv_pci1710.c | 2 - drivers/staging/comedi/drivers/adv_pci1723.c | 2 - drivers/staging/comedi/drivers/adv_pci_dio.c | 1 - drivers/staging/comedi/drivers/amplc_dio200.c | 2 - drivers/staging/comedi/drivers/amplc_pc236.c | 2 - drivers/staging/comedi/drivers/amplc_pc263.c | 2 - drivers/staging/comedi/drivers/amplc_pci224.c | 2 - drivers/staging/comedi/drivers/amplc_pci230.c | 1 - drivers/staging/comedi/drivers/cb_pcidas.c | 1 - drivers/staging/comedi/drivers/cb_pcidas64.c | 1 - drivers/staging/comedi/drivers/cb_pcidda.c | 2 - drivers/staging/comedi/drivers/cb_pcidio.c | 1 - drivers/staging/comedi/drivers/cb_pcimdas.c | 1 - drivers/staging/comedi/drivers/cb_pcimdda.c | 2 - drivers/staging/comedi/drivers/comedi_pci.h | 60 ------------------- .../staging/comedi/drivers/contec_pci_dio.c | 2 - drivers/staging/comedi/drivers/daqboard2000.c | 1 - drivers/staging/comedi/drivers/das08.c | 1 - drivers/staging/comedi/drivers/dt3000.c | 2 - drivers/staging/comedi/drivers/dyna_pci10xx.c | 1 - drivers/staging/comedi/drivers/gsc_hpdi.c | 1 - drivers/staging/comedi/drivers/icp_multi.h | 1 - drivers/staging/comedi/drivers/jr3_pci.c | 1 - drivers/staging/comedi/drivers/ke_counter.c | 2 - drivers/staging/comedi/drivers/me4000.c | 1 - drivers/staging/comedi/drivers/me_daq.c | 2 - drivers/staging/comedi/drivers/mite.c | 1 - drivers/staging/comedi/drivers/rtd520.c | 1 - drivers/staging/comedi/drivers/s626.c | 2 - 39 files changed, 37 insertions(+), 112 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/comedi_pci.h diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 134be93eaa6d..9cd2b5117106 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -40,6 +40,7 @@ #include #include #include +#include #include "comedi.h" @@ -180,7 +181,6 @@ struct comedi_async { unsigned int x); }; -struct pci_dev; struct usb_interface; struct comedi_driver { @@ -310,7 +310,8 @@ int comedi_driver_unregister(struct comedi_driver *); module_driver(__comedi_driver, comedi_driver_register, \ comedi_driver_unregister) -struct pci_driver; +int comedi_pci_enable(struct pci_dev *, const char *); +void comedi_pci_disable(struct pci_dev *); int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *); void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1c3d6386ea36..7289dcb5c32c 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -908,6 +908,40 @@ static void comedi_auto_unconfig(struct device *hardware_device) comedi_free_board_minor(minor); } +/** + * comedi_pci_enable() - Enable the PCI device and request the regions. + * @pdev: pci_dev struct + * @res_name: name for the requested reqource + */ +int comedi_pci_enable(struct pci_dev *pdev, const char *res_name) +{ + int rc; + + rc = pci_enable_device(pdev); + if (rc < 0) + return rc; + + rc = pci_request_regions(pdev, res_name); + if (rc < 0) + pci_disable_device(pdev); + + return rc; +} +EXPORT_SYMBOL_GPL(comedi_pci_enable); + +/** + * comedi_pci_disable() - Release the regions and disable the PCI device. + * @pdev: pci_dev struct + * + * This must be matched with a previous successful call to comedi_pci_enable(). + */ +void comedi_pci_disable(struct pci_dev *pdev) +{ + pci_release_regions(pdev); + pci_disable_device(pdev); +} +EXPORT_SYMBOL_GPL(comedi_pci_disable); + static int comedi_old_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) { diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 35a3ea19359f..d70ac8bb6228 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -22,8 +22,6 @@ #include "../../comedidev.h" -#include "../comedi_pci.h" - #ifdef PCI_SUPPORT_VER1 #error No support for 2.1.55 and older #endif diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index de8c68af3210..2f48dc72b20e 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -52,7 +52,6 @@ References: * options that are used with comedi_config. */ #include "../comedidev.h" -#include "comedi_pci.h" /* Board descriptions */ struct pci6208_board { diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index e8053bc825f4..e7eb2290106a 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -36,7 +36,6 @@ Configuration Options: #include "../comedidev.h" #include -#include "comedi_pci.h" #define PCI7230_DI 0x00 #define PCI7230_DO 0x00 diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index b4dae3b7598b..bf2f7fb86d77 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -37,7 +37,6 @@ Configuration Options: #include "../comedidev.h" #include -#include "comedi_pci.h" #include "8255.h" /* #include "8253.h" */ diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index 9cbfb61a4478..2fc1dbbd81e4 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -36,7 +36,6 @@ Configuration Options: #include "../comedidev.h" #include -#include "comedi_pci.h" #define PCI7432_DI 0x00 #define PCI7432_DO 0x00 diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 409ef13ad090..fbc859e6c201 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -38,7 +38,6 @@ Configuration Options: #include #include #include "comedi_fc.h" -#include "comedi_pci.h" #include "8253.h" #define PCI8164_AXIS_X 0x00 diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index ccfb1a52154e..308cca76cb82 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -81,7 +81,6 @@ TODO: #include #include "8253.h" -#include "comedi_pci.h" #include "comedi_fc.h" #define PCI9111_DRIVER_NAME "adl_pci9111" diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 78645863297b..aa4244e5f918 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -71,7 +71,6 @@ Configuration options: #include "amcc_s5933.h" #include "8253.h" -#include "comedi_pci.h" #include "comedi_fc.h" #define PCI_VENDOR_ID_AMCC 0x10e8 diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index de8c98cfe367..db9f0a56f79f 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -45,8 +45,6 @@ Configuration options: #include "../comedidev.h" -#include "comedi_pci.h" - #include "8253.h" #include "amcc_s5933.h" diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 336addcbce3a..b8768b54e943 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -50,8 +50,6 @@ TODO: #include "../comedidev.h" -#include "comedi_pci.h" - #define PCI_VENDOR_ID_ADVANTECH 0x13fe /* Advantech PCI vendor ID */ /* hardware types of the cards */ diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 43a32dc12cde..df8236c952e7 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -33,7 +33,6 @@ Configuration options: #include -#include "comedi_pci.h" #include "8255.h" #include "8253.h" diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index c9c5d97b3ca2..f6f6144344b4 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -210,8 +210,6 @@ order they appear in the channel list. #include "../comedidev.h" -#include "comedi_pci.h" - #include "8255.h" #include "8253.h" diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 57ba3228b1a9..6cb06ec1b30d 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -56,8 +56,6 @@ unused. #include "../comedidev.h" -#include "comedi_pci.h" - #include "8255.h" #include "plx9052.h" diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 974d7450051e..086579f756ff 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -46,8 +46,6 @@ The state of the outputs can be read. #include "../comedidev.h" -#include "comedi_pci.h" - #define PC263_DRIVER_NAME "amplc_pc263" #ifdef CONFIG_COMEDI_AMPLC_PC263_ISA_MODULE diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index fbf19cae8747..0d1f9cc50ef3 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -108,8 +108,6 @@ Caveats: #include "../comedidev.h" -#include "comedi_pci.h" - #include "comedi_fc.h" #include "8253.h" diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index d4c80b1281f2..b05a684b80ba 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -193,7 +193,6 @@ for (or detection of) various hardware problems added by Ian Abbott. #include #include -#include "comedi_pci.h" #include "8253.h" #include "8255.h" diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index ee9e084bb96c..7f88d08ee579 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -77,7 +77,6 @@ analog triggering on 1602 series #include "8253.h" #include "8255.h" #include "amcc_s5933.h" -#include "comedi_pci.h" #include "comedi_fc.h" #undef CB_PCIDAS_DEBUG /* disable debugging code */ diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 9d0b8754ff5b..1e30f227e98e 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -87,7 +87,6 @@ TODO: #include #include -#include "comedi_pci.h" #include "8253.h" #include "8255.h" #include "plx9080.h" diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 25ebca11eadc..dc4cf0b030ef 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -48,10 +48,8 @@ Please report success/failure with other different cards to #include "../comedidev.h" -#include "comedi_pci.h" #include "8255.h" - /* PCI vendor number of ComputerBoards */ #define PCI_VENDOR_ID_CB 0x1307 #define EEPROM_SIZE 128 /* number of entries in eeprom */ diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 713132c8dbb5..58d5a3d257bd 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -41,7 +41,6 @@ Passing a zero for an option is the same as leaving it unspecified. /*------------------------------ HEADER FILES ---------------------------------*/ #include "../comedidev.h" -#include "comedi_pci.h" #include "8255.h" /*-------------------------- MACROS and DATATYPES -----------------------------*/ diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 5f834d02ec24..a06b67a0b36d 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -45,7 +45,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #include #include -#include "comedi_pci.h" #include "plx9052.h" #include "8255.h" diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index b339685e234d..bec250bf15bb 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -86,8 +86,6 @@ Configuration Options: #include "../comedidev.h" -#include "comedi_pci.h" - #include "8255.h" /* device ids of the cards we support -- currently only 1 card supported */ diff --git a/drivers/staging/comedi/drivers/comedi_pci.h b/drivers/staging/comedi/drivers/comedi_pci.h deleted file mode 100644 index c14a036a0536..000000000000 --- a/drivers/staging/comedi/drivers/comedi_pci.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - comedi/drivers/comedi_pci.h - Various PCI functions for drivers. - - Copyright (C) 2007 MEV Ltd. - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef _COMEDI_PCI_H_ -#define _COMEDI_PCI_H_ - -#include - -/* - * Enable the PCI device and request the regions. - */ -static inline int comedi_pci_enable(struct pci_dev *pdev, const char *res_name) -{ - int rc; - - rc = pci_enable_device(pdev); - if (rc < 0) - return rc; - - rc = pci_request_regions(pdev, res_name); - if (rc < 0) - pci_disable_device(pdev); - - return rc; -} - -/* - * Release the regions and disable the PCI device. - * - * This must be matched with a previous successful call to comedi_pci_enable(). - */ -static inline void comedi_pci_disable(struct pci_dev *pdev) -{ - pci_release_regions(pdev); - pci_disable_device(pdev); -} - -#endif diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index b8bac80f2baf..2cd7407adbea 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -36,8 +36,6 @@ Configuration Options: #include "../comedidev.h" -#include "comedi_pci.h" - enum contec_model { PIO1616L = 0, }; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 696b58ca2e59..d84794ca4380 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -118,7 +118,6 @@ Configuration options: #include #include -#include "comedi_pci.h" #include "8255.h" #define DAQBOARD2000_SUBSYSTEM_IDS2 0x00021616 /* Daqboard/2000 - 2 Dacs */ diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 1f319435e23f..f53e59776a37 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -55,7 +55,6 @@ #include -#include "comedi_pci.h" #include "8255.h" #include "das08.h" diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 0d273269b572..2c1c6140f38f 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -63,8 +63,6 @@ AO commands are not supported. #include "../comedidev.h" #include -#include "comedi_pci.h" - #define PCI_VENDOR_ID_DT 0x1116 static const struct comedi_lrange range_dt3000_ai = { 4, { diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index b0cec7b1b0c9..9586f24ded73 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -38,7 +38,6 @@ */ #include "../comedidev.h" -#include "comedi_pci.h" #include #define PCI_VENDOR_ID_DYNALOG 0x10b5 diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 8aece08bd0dd..79e22b13f734 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -49,7 +49,6 @@ support could be added to this driver. #include "../comedidev.h" #include -#include "comedi_pci.h" #include "plx9080.h" #include "comedi_fc.h" diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h index 68acefe16888..dbf9908cfde6 100644 --- a/drivers/staging/comedi/drivers/icp_multi.h +++ b/drivers/staging/comedi/drivers/icp_multi.h @@ -11,7 +11,6 @@ #define _ICP_MULTI_H_ #include "../comedidev.h" -#include "comedi_pci.h" /****************************************************************************/ diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index d536a11edb95..e8dfc367aa8d 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -49,7 +49,6 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #include #include #include -#include "comedi_pci.h" #include "jr3_pci.h" #define PCI_VENDOR_ID_JR3 0x1762 diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 09d191844bf8..9f92420dd826 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -40,8 +40,6 @@ Kolter Electronic PCI Counter Card. #include "../comedidev.h" -#include "comedi_pci.h" - #define CNT_DRIVER_NAME "ke_counter" #define PCI_VENDOR_ID_KOLTER 0x1001 #define CNT_CARD_DEVICE_ID 0x0014 diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 8ca1b54600db..cb6bf8c5fb45 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -58,7 +58,6 @@ broken. #include #include -#include "comedi_pci.h" #include "me4000.h" #if 0 /* file removed due to GPL incompatibility */ diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index ffe251250e6f..fcadb0fcd1d0 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -54,8 +54,6 @@ from http://www.comedi.org #include #include "../comedidev.h" -#include "comedi_pci.h" - /*#include "me2600_fw.h" */ #define ME_DRIVER_NAME "me_daq" diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 13e9c8071696..a93166d6a8f8 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -52,7 +52,6 @@ #include "mite.h" #include "comedi_fc.h" -#include "comedi_pci.h" #include "../comedidev.h" diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 1678a0ccb8c1..d3e2786f07cb 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -105,7 +105,6 @@ Configuration options: #include #include "../comedidev.h" -#include "comedi_pci.h" #define DRV_NAME "rtd520" diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 7beb8f6853af..516037009dcd 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -74,8 +74,6 @@ INSN_CONFIG instructions: #include "../comedidev.h" -#include "comedi_pci.h" - #include "comedi_fc.h" #include "s626.h" -- GitLab From 85a15d5bcab6dbae638fb51e2bc93217c7c3b23c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 May 2012 17:43:31 -0700 Subject: [PATCH 0225/6849] staging: comedi: dt3000: io_addr is a void __iomem * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The io_addr variable in struct dt3k_private is an ioremap'ed pci resource and should be void __iomem * not a void *. This quiets a lot of sparse warings for the writew and readw calls like: warning: incorrect type in argument 1 (different address spaces)    expected void const volatile [noderef] *addr    got void * warning: incorrect type in argument 2 (different address spaces)    expected void volatile [noderef] *addr    got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 2c1c6140f38f..af0202474127 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -252,7 +252,7 @@ struct dt3k_private { struct pci_dev *pci_dev; resource_size_t phys_addr; - void *io_addr; + void __iomem *io_addr; unsigned int lock; unsigned int ao_readback[2]; unsigned int ai_front; -- GitLab From ff450314d5ef05843d3b3bd33fc65f7aaea3b2df Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 May 2012 17:52:07 -0700 Subject: [PATCH 0226/6849] staging: comedi: gsc_hpdi: plx9080_iobase and hpdi_iobase are void __iomem * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plx9080_iobase and hpdi_iobase variables in struct hpdi_private are ioremap'ed pci resource and should be void __iomem * not void *. This quiets a lot of sparse warings for the writel and readl calls like: warning: incorrect type in argument 1 (different address spaces)    expected void const volatile [noderef] *addr    got void * warning: incorrect type in argument 2 (different address spaces)    expected void volatile [noderef] *addr    got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 79e22b13f734..eeb05553e1a7 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -296,8 +296,8 @@ struct hpdi_private { resource_size_t plx9080_phys_iobase; resource_size_t hpdi_phys_iobase; /* base addresses (ioremapped) */ - void *plx9080_iobase; - void *hpdi_iobase; + void __iomem *plx9080_iobase; + void __iomem *hpdi_iobase; uint32_t *dio_buffer[NUM_DMA_BUFFERS]; /* dma buffers */ /* physical addresses of dma buffers */ dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS]; @@ -363,7 +363,7 @@ static void disable_plx_interrupts(struct comedi_device *dev) static void init_plx9080(struct comedi_device *dev) { uint32_t bits; - void *plx_iobase = priv(dev)->plx9080_iobase; + void __iomem *plx_iobase = priv(dev)->plx9080_iobase; /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", @@ -672,10 +672,10 @@ static void hpdi_detach(struct comedi_device *dev) if ((priv(dev)) && (priv(dev)->hw_dev)) { if (priv(dev)->plx9080_iobase) { disable_plx_interrupts(dev); - iounmap((void *)priv(dev)->plx9080_iobase); + iounmap(priv(dev)->plx9080_iobase); } if (priv(dev)->hpdi_iobase) - iounmap((void *)priv(dev)->hpdi_iobase); + iounmap(priv(dev)->hpdi_iobase); /* free pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { if (priv(dev)->dio_buffer[i]) @@ -902,7 +902,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) uint32_t next_transfer_addr; int j; int num_samples = 0; - void *pci_addr_reg; + void __iomem *pci_addr_reg; if (channel) pci_addr_reg = -- GitLab From 86a5eb8ccef09916e622b43f97f115c2526d7d2e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 May 2012 17:55:33 -0700 Subject: [PATCH 0227/6849] staging: comedi: icp_multi: io_addr is a void __iomem * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The io_addr variable in struct dt3k_private is an ioremap'ed pci resource and should be void __iomem * not a void *. This quiets a lot of sparse warings for the writew and readw calls like: warning: incorrect type in argument 1 (different address spaces)    expected void const volatile [noderef] *addr    got void * warning: incorrect type in argument 2 (different address spaces)    expected void volatile [noderef] *addr    got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/icp_multi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index fdc596fb0990..f870d3da0324 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -148,7 +148,7 @@ struct boardtype { struct icp_multi_private { struct pcilst_struct *card; /* pointer to card */ char valid; /* card is usable */ - void *io_addr; /* Pointer to mapped io address */ + void __iomem *io_addr; /* Pointer to mapped io address */ resource_size_t phys_iobase; /* Physical io address */ unsigned int AdcCmdStatus; /* ADC Command/Status register */ unsigned int DacCmdStatus; /* DAC Command/Status register */ -- GitLab From 4aa7419e082ef5ca38f8934d38fda5909a27962b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 May 2012 18:10:07 -0700 Subject: [PATCH 0228/6849] staging: comedi: ii_pci20kc: iobase and ioaddr are void __iomem * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iobase variables in struct pci20xxx_subdev_private and ioaddr variable in struct pci20xxx_private should be void __iomem * not void *. This quiets a lot of sparse warings for the writeb and readb calls like: warning: incorrect type in argument 1 (different address spaces)    expected void const volatile [noderef] *addr    got void * warning: incorrect type in argument 2 (different address spaces)    expected void volatile [noderef] *addr    got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ii_pci20kc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index f0a579a04a7d..6f6947602398 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -135,15 +135,15 @@ options for PCI-20341M: #define PCI20341_SCANLIST 0x80 /* Channel/Gain Scan List */ union pci20xxx_subdev_private { - void *iobase; + void __iomem *iobase; struct { - void *iobase; + void __iomem *iobase; const struct comedi_lrange *ao_range_list[2]; /* range of channels of ao module */ unsigned int last_data[2]; } pci20006; struct { - void *iobase; + void __iomem *iobase; int timebase; int settling_time; int ai_gain; @@ -152,7 +152,7 @@ union pci20xxx_subdev_private { struct pci20xxx_private { - void *ioaddr; + void __iomem *ioaddr; union pci20xxx_subdev_private subdev_private[PCI20000_MODULES]; }; @@ -210,7 +210,7 @@ static int pci20xxx_attach(struct comedi_device *dev, if (ret < 0) return ret; - devpriv->ioaddr = (void *)(unsigned long)it->options[0]; + devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0]; dev->board_name = "pci20kc"; /* Check PCI-20001 C-2A Carrier Board ID */ -- GitLab From 42caa910f286e2be0763a6fb8aa7a998e10c6e02 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 21 May 2012 18:21:39 -0700 Subject: [PATCH 0229/6849] staging: comedi: s626: base_addr is a void __iomem * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The base_addr variable in struct s626_private is an ioremap'ed pci resource and should be void __iomem * not a void *. This quiets a lot of sparse warings for the writel and readl calls like: warning: incorrect type in argument 1 (different address spaces)    expected void const volatile [noderef] *addr    got void * warning: incorrect type in argument 2 (different address spaces)    expected void volatile [noderef] *addr    got void * Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 516037009dcd..d6dc3381205a 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -118,7 +118,7 @@ static const struct s626_board s626_boards[] = { struct s626_private { struct pci_dev *pdev; - void *base_addr; + void __iomem *base_addr; int got_regions; short allocatedBuf; uint8_t ai_cmd_running; /* ai_cmd is running */ -- GitLab From ad401db6684bef91aca6304e640d63c9c858de2b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 18:08:36 -0700 Subject: [PATCH 0230/6849] staging: comedi: remove thisboard macro in the ssv_dnp driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ssv_dnp.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 16c4f5a757bb..de580958e32a 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -59,9 +59,6 @@ struct dnp_board { int have_dio; }; -/* Useful for shorthand access to the particular board structure ----------- */ -#define thisboard ((const struct dnp_board *)dev->board_ptr) - /* This structure is for data unique to the DNP driver --------------------- */ struct dnp_private_data { @@ -188,18 +185,12 @@ static int dnp_dio_insn_config(struct comedi_device *dev, static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dnp_board *board = comedi_board(dev); struct comedi_subdevice *s; printk(KERN_INFO "comedi%d: dnp: ", dev->minor); - /* Autoprobing: this should find out which board we have. Currently */ - /* only the 1486 board is supported and autoprobing is not */ - /* implemented :-) */ - /* dev->board_ptr = dnp_probe(dev); */ - - /* Initialize the name of the board. */ - /* We can use the "thisboard" macro now. */ - dev->board_name = thisboard->name; + dev->board_name = board->name; /* Allocate the private structure area. alloc_private() is a */ /* convenient macro defined in comedidev.h. */ -- GitLab From 609dd342fb7eab79d42350455c2d86238c7dc15f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 18:04:18 -0700 Subject: [PATCH 0231/6849] staging: comedi: remove this_board macro in the serial2002 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/serial2002.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 6342bc5ddb3e..9200310dce5d 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -47,11 +47,6 @@ struct serial2002_board { const char *name; }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct serial2002_board *)dev->board_ptr) - struct serial2002_range_table_t { /* HACK... */ @@ -783,10 +778,11 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, static int serial2002_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct serial2002_board *board = comedi_board(dev); struct comedi_subdevice *s; dev_dbg(dev->hw_dev, "comedi%d: attached\n", dev->minor); - dev->board_name = thisboard->name; + dev->board_name = board->name; if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) return -ENOMEM; dev->open = serial_2002_open; -- GitLab From 354c00a67697fc7a56b540647ef7fe93333ed903 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:59:07 -0700 Subject: [PATCH 0232/6849] staging: comedi: remove this_board macro in the rti800 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rti800.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index f0eb52a77881..04a23687ae3e 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -138,8 +138,6 @@ struct rti800_board { int has_ao; }; -#define this_board ((const struct rti800_board *)dev->board_ptr) - static irqreturn_t rti800_interrupt(int irq, void *dev); struct rti800_private { @@ -309,6 +307,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev, static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct rti800_board *board = comedi_board(dev); unsigned int irq; unsigned long iobase; int ret; @@ -347,7 +346,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "( no irq )\n"); } - dev->board_name = this_board->name; + dev->board_name = board->name; ret = alloc_subdevices(dev, 4); if (ret < 0) @@ -386,7 +385,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) } s++; - if (this_board->has_ao) { + if (board->has_ao) { /* ao subdevice (only on rti815) */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; -- GitLab From d5016e242b3ca919e3be7fa98dbb2b35e61c1efe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:54:46 -0700 Subject: [PATCH 0233/6849] staging: comedi: remove this_board macro in the poc driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/poc.c | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index e7120480687b..95e348fa89c8 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -57,8 +57,6 @@ struct boarddef_struct { const struct comedi_lrange *range; }; -#define this_board ((const struct boarddef_struct *)dev->board_ptr) - static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -137,22 +135,23 @@ static int pcl734_insn_bits(struct comedi_device *dev, static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boarddef_struct *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; unsigned int iosize; iobase = it->options[0]; printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, - this_board->name, iobase); + board->name, iobase); - dev->board_name = this_board->name; + dev->board_name = board->name; if (iobase == 0) { printk(KERN_ERR "io base address required\n"); return -EINVAL; } - iosize = this_board->iosize; + iosize = board->iosize; /* check if io addresses are available */ if (!request_region(iobase, iosize, "dac02")) { printk(KERN_ERR "I/O port conflict: failed to allocate ports " @@ -163,18 +162,18 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_subdevices(dev, 1) < 0) return -ENOMEM; - if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0) + if (alloc_private(dev, sizeof(unsigned int) * board->n_chan) < 0) return -ENOMEM; /* analog output subdevice */ s = dev->subdevices + 0; - s->type = this_board->type; - s->n_chan = this_board->n_chan; - s->maxdata = (1 << this_board->n_bits) - 1; - s->range_table = this_board->range; - s->insn_write = this_board->winsn; - s->insn_read = this_board->rinsn; - s->insn_bits = this_board->insnbits; + s->type = board->type; + s->n_chan = board->n_chan; + s->maxdata = (1 << board->n_bits) - 1; + s->range_table = board->range; + s->insn_write = board->winsn; + s->insn_read = board->rinsn; + s->insn_bits = board->insnbits; if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) s->subdev_flags = SDF_WRITABLE; @@ -183,8 +182,10 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void poc_detach(struct comedi_device *dev) { + const struct boarddef_struct *board = comedi_board(dev); + if (dev->iobase) - release_region(dev->iobase, this_board->iosize); + release_region(dev->iobase, board->iosize); } static const struct boarddef_struct boards[] = { -- GitLab From a28b59957d3ad01481c2ea87aca50cfdb85417f2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:51:35 -0700 Subject: [PATCH 0234/6849] staging: comedi: remove this_board macro in the pcmuio driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmuio.c | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 623381d50dac..b1a9bed38551 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -155,11 +155,6 @@ struct pcmuio_board { const int num_ports; }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct pcmuio_board *)dev->board_ptr) - /* this structure is for data unique to this subdevice. */ struct pcmuio_subdev_private { /* mapping of halfwords (bytes) in port/chanarray to iobase */ @@ -354,7 +349,9 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { - if (asic < 0 || asic >= thisboard->num_asics) + const struct pcmuio_board *board = comedi_board(dev); + + if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ if (page < 0 || page >= NUM_PAGES) return; /* more paranoia */ @@ -370,9 +367,10 @@ static void switch_page(struct comedi_device *dev, int asic, int page) static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ + const struct pcmuio_board *board = comedi_board(dev); int asic; - for (asic = 0; asic < thisboard->num_asics; ++asic) { + for (asic = 0; asic < board->num_asics; ++asic) { int port, page; unsigned long baseaddr = dev->iobase + asic * ASIC_IOSIZE; @@ -407,7 +405,9 @@ static void init_asics(struct comedi_device *dev) #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { - if (asic < 0 || asic >= thisboard->num_asics) + const struct pcmuio_board *board = comedi_board(dev); + + if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -420,7 +420,9 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { - if (asic < 0 || asic >= thisboard->num_asics) + const struct pcmuio_board *board = comedi_board(dev); + + if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -747,6 +749,7 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcmuio_board *board = comedi_board(dev); struct comedi_subdevice *s; int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; unsigned long iobase; @@ -762,17 +765,13 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; if (!iobase || !request_region(iobase, - thisboard->num_asics * ASIC_IOSIZE, + board->num_asics * ASIC_IOSIZE, dev->driver->driver_name)) { dev_err(dev->hw_dev, "I/O port conflict\n"); return -EIO; } -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; + dev->board_name = board->name; /* * Allocate the private structure area. alloc_private() is a @@ -792,7 +791,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) spin_lock_init(&devpriv->asics[asic].spinlock); } - chans_left = CHANS_PER_ASIC * thisboard->num_asics; + chans_left = CHANS_PER_ASIC * board->num_asics; n_subdevs = CALC_N_SUBDEVS(chans_left); devpriv->sprivs = kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), @@ -881,7 +880,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { if (irq[asic] && request_irq(irq[asic], interrupt_pcmuio, - IRQF_SHARED, thisboard->name, dev)) { + IRQF_SHARED, board->name, dev)) { int i; /* unroll the allocated irqs.. */ for (i = asic - 1; i >= 0; --i) { @@ -898,7 +897,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq[0]) { dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]); - if (irq[1] && thisboard->num_asics == 2) + if (irq[1] && board->num_asics == 2) dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]); } else { dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n"); @@ -910,10 +909,11 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmuio_detach(struct comedi_device *dev) { + const struct pcmuio_board *board = comedi_board(dev); int i; if (dev->iobase) - release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); + release_region(dev->iobase, ASIC_IOSIZE * board->num_asics); for (i = 0; i < MAX_ASICS; ++i) { if (devpriv->asics[i].irq) free_irq(devpriv->asics[i].irq, dev); -- GitLab From 57bbeb3b9bc32f1ee4b14439e11ed475deab1263 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:46:56 -0700 Subject: [PATCH 0235/6849] staging: comedi: remove this_board macro in the pcmmio driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmmio.c | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index efed168d2bac..c4482ae9d08b 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -183,11 +183,6 @@ static const struct comedi_lrange ranges_ao = { RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)} }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct pcmmio_board *)dev->board_ptr) - /* this structure is for data unique to this subdevice. */ struct pcmmio_subdev_private { @@ -423,7 +418,9 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { - if (asic < 0 || asic >= thisboard->dio_num_asics) + const struct pcmmio_board *board = comedi_board(dev); + + if (asic < 0 || asic >= board->dio_num_asics) return; /* paranoia */ if (page < 0 || page >= NUM_PAGES) return; /* more paranoia */ @@ -439,9 +436,10 @@ static void switch_page(struct comedi_device *dev, int asic, int page) static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ + const struct pcmmio_board *board = comedi_board(dev); int asic; - for (asic = 0; asic < thisboard->dio_num_asics; ++asic) { + for (asic = 0; asic < board->dio_num_asics; ++asic) { int port, page; unsigned long baseaddr = devpriv->asics[asic].iobase; @@ -476,7 +474,9 @@ static void init_asics(struct comedi_device *dev) #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { - if (asic < 0 || asic >= thisboard->dio_num_asics) + const struct pcmmio_board *board = comedi_board(dev); + + if (asic < 0 || asic >= board->dio_num_asics) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -490,7 +490,9 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { - if (asic < 0 || asic >= thisboard->dio_num_asics) + const struct pcmmio_board *board = comedi_board(dev); + + if (asic < 0 || asic >= board->dio_num_asics) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -1012,6 +1014,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcmmio_board *board = comedi_board(dev); struct comedi_subdevice *s; int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, thisasic_chanct = 0; @@ -1027,17 +1030,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; if (!iobase || !request_region(iobase, - thisboard->total_iosize, + board->total_iosize, dev->driver->driver_name)) { printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); return -EIO; } -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; + dev->board_name = board->name; /* * Allocate the private structure area. alloc_private() is a @@ -1061,7 +1060,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) spin_lock_init(&devpriv->asics[asic].spinlock); } - chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics; + chans_left = CHANS_PER_ASIC * board->dio_num_asics; n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); n_subdevs = n_dio_subdevs + 2; devpriv->sprivs = @@ -1088,13 +1087,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) sdev_no = 0; s = dev->subdevices + sdev_no; s->private = devpriv->sprivs + sdev_no; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = thisboard->ai_range_table; + s->maxdata = (1 << board->ai_bits) - 1; + s->range_table = board->ai_range_table; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->type = COMEDI_SUBD_AI; - s->n_chan = thisboard->n_ai_chans; + s->n_chan = board->n_ai_chans; s->len_chanlist = s->n_chan; - s->insn_read = thisboard->ai_rinsn; + s->insn_read = board->ai_rinsn; subpriv->iobase = dev->iobase + 0; /* initialize the resource enable register by clearing it */ outb(0, subpriv->iobase + 3); @@ -1104,14 +1103,14 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ++sdev_no; s = dev->subdevices + sdev_no; s->private = devpriv->sprivs + sdev_no; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ao_range_table; + s->maxdata = (1 << board->ao_bits) - 1; + s->range_table = board->ao_range_table; s->subdev_flags = SDF_READABLE; s->type = COMEDI_SUBD_AO; - s->n_chan = thisboard->n_ao_chans; + s->n_chan = board->n_ao_chans; s->len_chanlist = s->n_chan; - s->insn_read = thisboard->ao_rinsn; - s->insn_write = thisboard->ao_winsn; + s->insn_read = board->ao_rinsn; + s->insn_write = board->ao_winsn; subpriv->iobase = dev->iobase + 8; /* initialize the resource enable register by clearing it */ outb(0, subpriv->iobase + 3); @@ -1192,7 +1191,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { if (irq[asic] && request_irq(irq[asic], interrupt_pcmmio, - IRQF_SHARED, thisboard->name, dev)) { + IRQF_SHARED, board->name, dev)) { int i; /* unroll the allocated irqs.. */ for (i = asic - 1; i >= 0; --i) { @@ -1211,7 +1210,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq[0]) { printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]); - if (thisboard->dio_num_asics == 2 && irq[1]) + if (board->dio_num_asics == 2 && irq[1]) printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n", dev->minor, irq[1]); } else { @@ -1225,10 +1224,11 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmmio_detach(struct comedi_device *dev) { + const struct pcmmio_board *board = comedi_board(dev); int i; if (dev->iobase) - release_region(dev->iobase, thisboard->total_iosize); + release_region(dev->iobase, board->total_iosize); for (i = 0; i < MAX_ASICS; ++i) { if (devpriv && devpriv->asics[i].irq) free_irq(devpriv->asics[i].irq, dev); -- GitLab From 2fbffee0604fd3f6f9e3aa56e3fe1aa061a32ca6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:42:55 -0700 Subject: [PATCH 0236/6849] staging: comedi: remove thisboard macro in the pcmda12 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmda12.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 4786148b4fd0..f49c66afe5fc 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -80,11 +80,6 @@ static const struct comedi_lrange pcmda12_ranges = { } }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct pcmda12_board *)dev->board_ptr) - struct pcmda12_private { unsigned int ao_readback[CHANS]; @@ -167,6 +162,7 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmda12_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcmda12_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; @@ -181,11 +177,7 @@ static int pcmda12_attach(struct comedi_device *dev, } dev->iobase = iobase; -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; + dev->board_name = board->name; /* * Allocate the private structure area. alloc_private() is a -- GitLab From 449b683c6b4f92af648447f9eb449fd52ce6d56b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:39:22 -0700 Subject: [PATCH 0237/6849] staging: comedi: remove this_board macro in the pcmad driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmad.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 1ec7d5cb346a..2ec0b2e63c35 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -58,8 +58,6 @@ struct pcmad_board_struct { int n_ai_bits; }; -#define this_board ((const struct pcmad_board_struct *)(dev->board_ptr)) - struct pcmad_priv_struct { int differential; int twos_comp; @@ -72,6 +70,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcmad_board_struct *board = comedi_board(dev); int i; int chan; int n; @@ -89,7 +88,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8); if (devpriv->twos_comp) - data[n] ^= (1 << (this_board->n_ai_bits - 1)); + data[n] ^= (1 << (board->n_ai_bits - 1)); } return n; @@ -104,6 +103,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, */ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcmad_board_struct *board = comedi_board(dev); int ret; struct comedi_subdevice *s; unsigned long iobase; @@ -125,7 +125,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - dev->board_name = this_board->name; + dev->board_name = board->name; s = dev->subdevices + 0; s->type = COMEDI_SUBD_AI; @@ -133,7 +133,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->n_chan = 16; /* XXX */ s->len_chanlist = 1; s->insn_read = pcmad_ai_insn_read; - s->maxdata = (1 << this_board->n_ai_bits) - 1; + s->maxdata = (1 << board->n_ai_bits) - 1; s->range_table = &range_unknown; return 0; -- GitLab From 3cff0f1249f9be93c44ea071bafd9f28f673898d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:26:43 -0700 Subject: [PATCH 0238/6849] staging: comedi: remove this_board macro in the pcm3724 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcm3724.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 7492b8f1d499..9eee708e8442 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -76,10 +76,6 @@ struct priv_pcm3724 { int dio_2; }; -#define this_board ((const struct pcm3724_board *)dev->board_ptr) - -/* (setq c-basic-offset 8) */ - static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { unsigned long iobase = arg; @@ -234,12 +230,13 @@ static int subdev_3724_insn_config(struct comedi_device *dev, static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcm3724_board *board = comedi_board(dev); unsigned long iobase; unsigned int iorange; int ret, i, n_subdevices; iobase = it->options[0]; - iorange = this_board->io_range; + iorange = board->io_range; ret = alloc_private(dev, sizeof(struct priv_pcm3724)); if (ret < 0) @@ -249,17 +246,17 @@ static int pcm3724_attach(struct comedi_device *dev, ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0; printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, - this_board->name, iobase); + board->name, iobase); if (!iobase || !request_region(iobase, iorange, "pcm3724")) { printk("I/O port conflict\n"); return -EIO; } dev->iobase = iobase; - dev->board_name = this_board->name; + dev->board_name = board->name; printk(KERN_INFO "\n"); - n_subdevices = this_board->numofports; + n_subdevices = board->numofports; ret = alloc_subdevices(dev, n_subdevices); if (ret < 0) @@ -275,6 +272,7 @@ static int pcm3724_attach(struct comedi_device *dev, static void pcm3724_detach(struct comedi_device *dev) { + const struct pcm3724_board *board = comedi_board(dev); int i; if (dev->subdevices) { @@ -282,7 +280,7 @@ static void pcm3724_detach(struct comedi_device *dev) subdev_8255_cleanup(dev, dev->subdevices + i); } if (dev->iobase) - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); } static const struct pcm3724_board boardtypes[] = { -- GitLab From dd8a4b478846c2cd38c09dcc564a8b964da185d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:22:48 -0700 Subject: [PATCH 0239/6849] staging: comedi: remove this_board macro in the pcl818 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 74 +++++++++++++------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 1406c9720f5d..6c84b29a8dad 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -326,7 +326,6 @@ static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0 }; #define devpriv ((struct pcl818_private *)dev->private) -#define this_board ((const struct pcl818_board *)dev->board_ptr) /* ============================================================================== @@ -1264,6 +1263,7 @@ static int check_single_ended(unsigned int port) static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcl818_board *board = comedi_board(dev); int err = 0; int tmp, divisor1 = 0, divisor2 = 0; @@ -1334,8 +1334,8 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ns_min) { - cmd->convert_arg = this_board->ns_min; + if (cmd->convert_arg < board->ns_min) { + cmd->convert_arg = board->ns_min; err++; } } else { /* TRIG_EXT */ @@ -1371,8 +1371,8 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); - if (cmd->convert_arg < this_board->ns_min) - cmd->convert_arg = this_board->ns_min; + if (cmd->convert_arg < board->ns_min) + cmd->convert_arg = board->ns_min; if (tmp != cmd->convert_arg) err++; } @@ -1519,6 +1519,8 @@ static int pcl818_check(unsigned long iobase) */ static void pcl818_reset(struct comedi_device *dev) { + const struct pcl818_board *board = comedi_board(dev); + if (devpriv->usefifo) { /* FIFO shutdown */ outb(0, dev->iobase + PCL818_FI_INTCLR); outb(0, dev->iobase + PCL818_FI_FLUSH); @@ -1537,7 +1539,7 @@ static void pcl818_reset(struct comedi_device *dev) outb(0xb0, dev->iobase + PCL818_CTRCTL); /* Stop pacer */ outb(0x70, dev->iobase + PCL818_CTRCTL); outb(0x30, dev->iobase + PCL818_CTRCTL); - if (this_board->is_818) { + if (board->is_818) { outb(0, dev->iobase + PCL818_RANGE); } else { outb(0, dev->iobase + PCL718_DA2_LO); @@ -1636,6 +1638,7 @@ static int rtc_setfreq_irq(int freq) static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl818_board *board = comedi_board(dev); int ret; unsigned long iobase; unsigned int irq; @@ -1651,9 +1654,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; printk ("comedi%d: pcl818: board=%s, ioport=0x%03lx", - dev->minor, this_board->name, iobase); - devpriv->io_range = this_board->io_range; - if ((this_board->fifo) && (it->options[2] == -1)) { /* we've board with FIFO and we want to use FIFO */ + dev->minor, board->name, iobase); + devpriv->io_range = board->io_range; + if ((board->fifo) && (it->options[2] == -1)) { + /* we've board with FIFO and we want to use FIFO */ devpriv->io_range = PCLx1xFIFO_RANGE; devpriv->usefifo = 1; } @@ -1669,14 +1673,14 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - /* set up some name stuff */ - dev->board_name = this_board->name; + dev->board_name = board->name; + /* grab our IRQ */ irq = 0; - if (this_board->IRQbits != 0) { /* board support IRQ */ + if (board->IRQbits != 0) { /* board support IRQ */ irq = it->options[1]; if (irq) { /* we want to use IRQ */ - if (((1 << irq) & this_board->IRQbits) == 0) { + if (((1 << irq) & board->IRQbits) == 0) { printk (", IRQ %u is out of allowed range, DISABLING IT", irq); @@ -1740,11 +1744,11 @@ no_rtc: devpriv->dma = dma; if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0)) goto no_dma; /* if we haven't IRQ, we can't use DMA */ - if (this_board->DMAbits != 0) { /* board support DMA */ + if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; if (dma < 1) goto no_dma; /* DMA disabled */ - if (((1 << dma) & this_board->DMAbits) == 0) { + if (((1 << dma) & board->DMAbits) == 0) { printk(KERN_ERR "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } @@ -1779,24 +1783,24 @@ no_dma: return ret; s = dev->subdevices + 0; - if (!this_board->n_aichan_se) { + if (!board->n_aichan_se) { s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_AI; devpriv->sub_ai = s; s->subdev_flags = SDF_READABLE; if (check_single_ended(dev->iobase)) { - s->n_chan = this_board->n_aichan_se; + s->n_chan = board->n_aichan_se; s->subdev_flags |= SDF_COMMON | SDF_GROUND; printk(", %dchans S.E. DAC", s->n_chan); } else { - s->n_chan = this_board->n_aichan_diff; + s->n_chan = board->n_aichan_diff; s->subdev_flags |= SDF_DIFF; printk(", %dchans DIFF DAC", s->n_chan); } - s->maxdata = this_board->ai_maxdata; + s->maxdata = board->ai_maxdata; s->len_chanlist = s->n_chan; - s->range_table = this_board->ai_range_type; + s->range_table = board->ai_range_type; s->cancel = pcl818_ai_cancel; s->insn_read = pcl818_ai_insn_read; if ((irq) || (devpriv->dma_rtc)) { @@ -1805,7 +1809,7 @@ no_dma: s->do_cmdtest = ai_cmdtest; s->do_cmd = ai_cmd; } - if (this_board->is_818) { + if (board->is_818) { if ((it->options[4] == 1) || (it->options[4] == 10)) s->range_table = &range_pcl818l_h_ai; /* secondary range list jumper selectable */ } else { @@ -1845,15 +1849,15 @@ no_dma: } s = dev->subdevices + 1; - if (!this_board->n_aochan) { + if (!board->n_aochan) { s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = this_board->n_aochan; - s->maxdata = this_board->ao_maxdata; - s->len_chanlist = this_board->n_aochan; - s->range_table = this_board->ao_range_type; + s->n_chan = board->n_aochan; + s->maxdata = board->ao_maxdata; + s->len_chanlist = board->n_aochan; + s->range_table = board->ao_range_type; s->insn_read = pcl818_ao_insn_read; s->insn_write = pcl818_ao_insn_write; #ifdef unused @@ -1864,7 +1868,7 @@ no_dma: } #endif #endif - if (this_board->is_818) { + if (board->is_818) { if ((it->options[4] == 1) || (it->options[4] == 10)) s->range_table = &range_unipolar10; if (it->options[4] == 2) @@ -1878,27 +1882,27 @@ no_dma: } s = dev->subdevices + 2; - if (!this_board->n_dichan) { + if (!board->n_dichan) { s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; - s->n_chan = this_board->n_dichan; + s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = this_board->n_dichan; + s->len_chanlist = board->n_dichan; s->range_table = &range_digital; s->insn_bits = pcl818_di_insn_bits; } s = dev->subdevices + 3; - if (!this_board->n_dochan) { + if (!board->n_dochan) { s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = this_board->n_dochan; + s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = this_board->n_dochan; + s->len_chanlist = board->n_dochan; s->range_table = &range_digital; s->insn_bits = pcl818_do_insn_bits; } @@ -1910,9 +1914,9 @@ no_dma: devpriv->i8253_osc_base = 1000; /* max sampling speed */ - devpriv->ns_min = this_board->ns_min; + devpriv->ns_min = board->ns_min; - if (!this_board->is_818) { + if (!board->is_818) { if ((it->options[6] == 1) || (it->options[6] == 100)) devpriv->ns_min = 10000; /* extended PCL718 to 100kHz DAC */ } -- GitLab From 240c6e6a7125fd7a6ebcbdd8fbbf646df0f69186 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:14:14 -0700 Subject: [PATCH 0240/6849] staging: comedi: remove this_board macro in the pcl816 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 71 +++++++++++++------------ 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index cc67b6d46059..277a23ece6fa 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -126,7 +126,6 @@ struct pcl816_board { }; #define devpriv ((struct pcl816_private *)dev->private) -#define this_board ((const struct pcl816_board *)dev->board_ptr) #ifdef unused static int RTC_lock; /* RTC lock */ @@ -451,6 +450,7 @@ static void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd) static int pcl816_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcl816_board *board = comedi_board(dev); int err = 0; int tmp, divisor1 = 0, divisor2 = 0; @@ -531,8 +531,8 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, err++; } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; + if (cmd->convert_arg < board->ai_ns_min) { + cmd->convert_arg = board->ai_ns_min; err++; } } else { /* TRIG_EXT */ @@ -565,12 +565,12 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, /* step 4: fix up any arguments */ if (cmd->convert_src == TRIG_TIMER) { tmp = cmd->convert_arg; - i8253_cascade_ns_to_timer(this_board->i8254_osc_base, + i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); - if (cmd->convert_arg < this_board->ai_ns_min) - cmd->convert_arg = this_board->ai_ns_min; + if (cmd->convert_arg < board->ai_ns_min) + cmd->convert_arg = board->ai_ns_min; if (tmp != cmd->convert_arg) err++; } @@ -592,6 +592,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct pcl816_board *board = comedi_board(dev); unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq; struct comedi_cmd *cmd = &s->async->cmd; unsigned int seglen; @@ -609,10 +610,10 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EBUSY; if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_ns_min) - cmd->convert_arg = this_board->ai_ns_min; + if (cmd->convert_arg < board->ai_ns_min) + cmd->convert_arg = board->ai_ns_min; - i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1, + i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); @@ -1028,6 +1029,7 @@ static int set_rtc_irq_bit(unsigned char bit) static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl816_board *board = comedi_board(dev); int ret; unsigned long iobase; unsigned int irq, dma; @@ -1038,9 +1040,9 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* claim our I/O space */ iobase = it->options[0]; printk("comedi%d: pcl816: board=%s, ioport=0x%03lx", dev->minor, - this_board->name, iobase); + board->name, iobase); - if (!request_region(iobase, this_board->io_range, "pcl816")) { + if (!request_region(iobase, board->io_range, "pcl816")) { printk("I/O port conflict\n"); return -EIO; } @@ -1056,15 +1058,14 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; /* Can't alloc mem */ - /* set up some name stuff */ - dev->board_name = this_board->name; + dev->board_name = board->name; /* grab our IRQ */ irq = 0; - if (this_board->IRQbits != 0) { /* board support IRQ */ + if (board->IRQbits != 0) { /* board support IRQ */ irq = it->options[1]; if (irq) { /* we want to use IRQ */ - if (((1 << irq) & this_board->IRQbits) == 0) { + if (((1 << irq) & board->IRQbits) == 0) { printk (", IRQ %u is out of allowed range, " "DISABLING IT", irq); @@ -1134,12 +1135,12 @@ no_rtc: if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0)) goto no_dma; /* if we haven't IRQ, we can't use DMA */ - if (this_board->DMAbits != 0) { /* board support DMA */ + if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; if (dma < 1) goto no_dma; /* DMA disabled */ - if (((1 << dma) & this_board->DMAbits) == 0) { + if (((1 << dma) & board->DMAbits) == 0) { printk(", DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } @@ -1185,11 +1186,11 @@ no_rtc: no_dma: -/* if (this_board->n_aochan > 0) +/* if (board->n_aochan > 0) subdevs[1] = COMEDI_SUBD_AO; - if (this_board->n_dichan > 0) + if (board->n_dichan > 0) subdevs[2] = COMEDI_SUBD_DI; - if (this_board->n_dochan > 0) + if (board->n_dochan > 0) subdevs[3] = COMEDI_SUBD_DO; */ @@ -1198,17 +1199,17 @@ no_dma: return ret; s = dev->subdevices + 0; - if (this_board->n_aichan > 0) { + if (board->n_aichan > 0) { s->type = COMEDI_SUBD_AI; devpriv->sub_ai = s; dev->read_subdev = s; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; - s->n_chan = this_board->n_aichan; + s->n_chan = board->n_aichan; s->subdev_flags |= SDF_DIFF; /* printk (", %dchans DIFF DAC - %d", s->n_chan, i); */ - s->maxdata = this_board->ai_maxdata; - s->len_chanlist = this_board->ai_chanlist; - s->range_table = this_board->ai_range_type; + s->maxdata = board->ai_maxdata; + s->len_chanlist = board->ai_chanlist; + s->range_table = board->ai_range_type; s->cancel = pcl816_ai_cancel; s->do_cmdtest = pcl816_ai_cmdtest; s->do_cmd = pcl816_ai_cmd; @@ -1221,25 +1222,25 @@ no_dma: #if 0 case COMEDI_SUBD_AO: s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = this_board->n_aochan; - s->maxdata = this_board->ao_maxdata; - s->len_chanlist = this_board->ao_chanlist; - s->range_table = this_board->ao_range_type; + s->n_chan = board->n_aochan; + s->maxdata = board->ao_maxdata; + s->len_chanlist = board->ao_chanlist; + s->range_table = board->ao_range_type; break; case COMEDI_SUBD_DI: s->subdev_flags = SDF_READABLE; - s->n_chan = this_board->n_dichan; + s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = this_board->n_dichan; + s->len_chanlist = board->n_dichan; s->range_table = &range_digital; break; case COMEDI_SUBD_DO: s->subdev_flags = SDF_WRITABLE; - s->n_chan = this_board->n_dochan; + s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = this_board->n_dochan; + s->len_chanlist = board->n_dochan; s->range_table = &range_digital; break; #endif @@ -1253,6 +1254,8 @@ case COMEDI_SUBD_DO: static void pcl816_detach(struct comedi_device *dev) { + const struct pcl816_board *board = comedi_board(dev); + if (dev->private) { pcl816_ai_cancel(dev, devpriv->sub_ai); pcl816_reset(dev); @@ -1275,7 +1278,7 @@ static void pcl816_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); #ifdef unused if (devpriv->dma_rtc) RTC_lock--; -- GitLab From 3cb08e08fbeab09fa5f3ba1cf27176dd41f5b70f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:09:03 -0700 Subject: [PATCH 0241/6849] staging: comedi: remove this_board macro in the pcl812 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 98 +++++++++++++------------ 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 51f4ca9f7927..28780ede1ee5 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -336,8 +336,6 @@ struct pcl812_board { unsigned char haveMPC508; /* 1=board use MPC508A multiplexor */ }; -#define this_board ((const struct pcl812_board *)dev->board_ptr) - struct pcl812_private { unsigned char valid; /* =1 device is OK */ @@ -560,6 +558,7 @@ static void pcl812_cmdtest_out(int e, struct comedi_cmd *cmd) static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcl812_board *board = comedi_board(dev); int err = 0; int tmp, divisor1, divisor2; @@ -666,8 +665,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; + if (cmd->convert_arg < board->ai_ns_min) { + cmd->convert_arg = board->ai_ns_min; err++; } } else { /* TRIG_EXT */ @@ -682,7 +681,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, err++; } if (cmd->chanlist_len > MAX_CHANLIST_LEN) { - cmd->chanlist_len = this_board->n_aichan; + cmd->chanlist_len = board->n_aichan; err++; } if (cmd->scan_end_arg != cmd->chanlist_len) { @@ -715,11 +714,11 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, if (cmd->convert_src == TRIG_TIMER) { tmp = cmd->convert_arg; - i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1, + i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); - if (cmd->convert_arg < this_board->ai_ns_min) - cmd->convert_arg = this_board->ai_ns_min; + if (cmd->convert_arg < board->ai_ns_min) + cmd->convert_arg = board->ai_ns_min; if (tmp != cmd->convert_arg) err++; } @@ -741,6 +740,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, */ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct pcl812_board *board = comedi_board(dev); unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes; struct comedi_cmd *cmd = &s->async->cmd; @@ -767,9 +767,9 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EINVAL; if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_ns_min) - cmd->convert_arg = this_board->ai_ns_min; - i8253_cascade_ns_to_timer(this_board->i8254_osc_base, + if (cmd->convert_arg < board->ai_ns_min) + cmd->convert_arg = board->ai_ns_min; + i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1, &divisor2, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); @@ -1192,6 +1192,7 @@ static void start_pacer(struct comedi_device *dev, int mode, */ static void free_resources(struct comedi_device *dev) { + const struct pcl812_board *board = comedi_board(dev); if (dev->private) { if (devpriv->dmabuf[0]) @@ -1204,7 +1205,7 @@ static void free_resources(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); } /* @@ -1234,6 +1235,8 @@ static int pcl812_ai_cancel(struct comedi_device *dev, */ static void pcl812_reset(struct comedi_device *dev) { + const struct pcl812_board *board = comedi_board(dev); + #ifdef PCL812_EXTDEBUG printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_reset(...)\n"); #endif @@ -1242,7 +1245,7 @@ static void pcl812_reset(struct comedi_device *dev) devpriv->old_chan_reg = -1; /* invalidate chain/gain memory */ devpriv->old_gain_reg = -1; - switch (this_board->board_type) { + switch (board->board_type) { case boardPCL812PG: case boardPCL812: case boardACL8112: @@ -1273,6 +1276,7 @@ static void pcl812_reset(struct comedi_device *dev) static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl812_board *board = comedi_board(dev); int ret, subdev; unsigned long iobase; unsigned int irq; @@ -1283,9 +1287,9 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; printk(KERN_INFO "comedi%d: pcl812: board=%s, ioport=0x%03lx", - dev->minor, this_board->name, iobase); + dev->minor, board->name, iobase); - if (!request_region(iobase, this_board->io_range, "pcl812")) { + if (!request_region(iobase, board->io_range, "pcl812")) { printk("I/O port conflict\n"); return -EIO; } @@ -1297,13 +1301,13 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; /* Can't alloc mem */ } - dev->board_name = this_board->name; + dev->board_name = board->name; irq = 0; - if (this_board->IRQbits != 0) { /* board support IRQ */ + if (board->IRQbits != 0) { /* board support IRQ */ irq = it->options[1]; if (irq) { /* we want to use IRQ */ - if (((1 << irq) & this_board->IRQbits) == 0) { + if (((1 << irq) & board->IRQbits) == 0) { printk (", IRQ %u is out of allowed range, " "DISABLING IT", irq); @@ -1328,9 +1332,9 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dma = dma; if (!dev->irq) goto no_dma; /* if we haven't IRQ, we can't use DMA */ - if (this_board->DMAbits != 0) { /* board support DMA */ + if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; - if (((1 << dma) & this_board->DMAbits) == 0) { + if (((1 << dma) & board->DMAbits) == 0) { printk(", DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } @@ -1369,13 +1373,13 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) no_dma: n_subdevices = 0; - if (this_board->n_aichan > 0) + if (board->n_aichan > 0) n_subdevices++; - if (this_board->n_aochan > 0) + if (board->n_aochan > 0) n_subdevices++; - if (this_board->n_dichan > 0) + if (board->n_dichan > 0) n_subdevices++; - if (this_board->n_dochan > 0) + if (board->n_dochan > 0) n_subdevices++; ret = alloc_subdevices(dev, n_subdevices); @@ -1387,46 +1391,46 @@ no_dma: subdev = 0; /* analog input */ - if (this_board->n_aichan > 0) { + if (board->n_aichan > 0) { s = dev->subdevices + subdev; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE; - switch (this_board->board_type) { + switch (board->board_type) { case boardA821: if (it->options[2] == 1) { - s->n_chan = this_board->n_aichan_diff; + s->n_chan = board->n_aichan_diff; s->subdev_flags |= SDF_DIFF; devpriv->use_diff = 1; } else { - s->n_chan = this_board->n_aichan; + s->n_chan = board->n_aichan; s->subdev_flags |= SDF_GROUND; } break; case boardACL8112: case boardACL8216: if (it->options[4] == 1) { - s->n_chan = this_board->n_aichan_diff; + s->n_chan = board->n_aichan_diff; s->subdev_flags |= SDF_DIFF; devpriv->use_diff = 1; } else { - s->n_chan = this_board->n_aichan; + s->n_chan = board->n_aichan; s->subdev_flags |= SDF_GROUND; } break; default: - s->n_chan = this_board->n_aichan; + s->n_chan = board->n_aichan; s->subdev_flags |= SDF_GROUND; break; } - s->maxdata = this_board->ai_maxdata; + s->maxdata = board->ai_maxdata; s->len_chanlist = MAX_CHANLIST_LEN; - s->range_table = this_board->rangelist_ai; - if (this_board->board_type == boardACL8216) + s->range_table = board->rangelist_ai; + if (board->board_type == boardACL8216) s->insn_read = acl8216_ai_insn_read; else s->insn_read = pcl812_ai_insn_read; - devpriv->use_MPC = this_board->haveMPC508; + devpriv->use_MPC = board->haveMPC508; s->cancel = pcl812_ai_cancel; if (dev->irq) { dev->read_subdev = s; @@ -1435,7 +1439,7 @@ no_dma: s->do_cmd = pcl812_ai_cmd; s->poll = pcl812_ai_poll; } - switch (this_board->board_type) { + switch (board->board_type) { case boardPCL812PG: if (it->options[4] == 1) s->range_table = &range_pcl812pg2_ai; @@ -1529,17 +1533,17 @@ no_dma: } /* analog output */ - if (this_board->n_aochan > 0) { + if (board->n_aochan > 0) { s = dev->subdevices + subdev; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = this_board->n_aochan; + s->n_chan = board->n_aochan; s->maxdata = 0xfff; s->len_chanlist = 1; - s->range_table = this_board->rangelist_ao; + s->range_table = board->rangelist_ao; s->insn_read = pcl812_ao_insn_read; s->insn_write = pcl812_ao_insn_write; - switch (this_board->board_type) { + switch (board->board_type) { case boardA821: if (it->options[3] == 1) s->range_table = &range_unipolar10; @@ -1558,32 +1562,32 @@ no_dma: } /* digital input */ - if (this_board->n_dichan > 0) { + if (board->n_dichan > 0) { s = dev->subdevices + subdev; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; - s->n_chan = this_board->n_dichan; + s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = this_board->n_dichan; + s->len_chanlist = board->n_dichan; s->range_table = &range_digital; s->insn_bits = pcl812_di_insn_bits; subdev++; } /* digital output */ - if (this_board->n_dochan > 0) { + if (board->n_dochan > 0) { s = dev->subdevices + subdev; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = this_board->n_dochan; + s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = this_board->n_dochan; + s->len_chanlist = board->n_dochan; s->range_table = &range_digital; s->insn_bits = pcl812_do_insn_bits; subdev++; } - switch (this_board->board_type) { + switch (board->board_type) { case boardACL8216: devpriv->ai_is16b = 1; case boardPCL812PG: -- GitLab From 6f929aeb175fd634f5d1ea54c045cf632a052557 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 17:03:19 -0700 Subject: [PATCH 0242/6849] staging: comedi: remove this_board macro in the pcl730 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl730.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index e11704addedb..02a4386e1031 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -32,8 +32,6 @@ struct pcl730_board { unsigned int io_range; /* len of I/O space */ }; -#define this_board ((const struct pcl730_board *)dev->board_ptr) - static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -70,19 +68,20 @@ static int pcl730_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl730_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; iobase = it->options[0]; - iorange = this_board->io_range; + iorange = board->io_range; printk(KERN_INFO "comedi%d: pcl730: board=%s 0x%04lx ", dev->minor, - this_board->name, iobase); + board->name, iobase); if (!request_region(iobase, iorange, "pcl730")) { printk("I/O port conflict\n"); return -EIO; } - dev->board_name = this_board->name; + dev->board_name = board->name; dev->iobase = iobase; dev->irq = 0; @@ -136,8 +135,10 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcl730_detach(struct comedi_device *dev) { + const struct pcl730_board *board = comedi_board(dev); + if (dev->iobase) - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); } static const struct pcl730_board boardtypes[] = { -- GitLab From d877269ed3c539b4cfcd738b5e705267d95bd5fd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:59:57 -0700 Subject: [PATCH 0243/6849] staging: comedi: remove this_board macro in the pcl726 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl726.c | 39 ++++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index d25c30c694e3..e9449bb2ba00 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -145,8 +145,6 @@ static const struct pcl726_board boardtypes[] = { &rangelist_728[0],}, }; -#define this_board ((const struct pcl726_board *)dev->board_ptr) - struct pcl726_private { int bipolar[12]; @@ -197,11 +195,13 @@ static int pcl726_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcl726_board *board = comedi_board(dev); + if (insn->n != 2) return -EINVAL; - data[1] = inb(dev->iobase + this_board->di_lo) | - (inb(dev->iobase + this_board->di_hi) << 8); + data[1] = inb(dev->iobase + board->di_lo) | + (inb(dev->iobase + board->di_hi) << 8); return 2; } @@ -210,6 +210,8 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcl726_board *board = comedi_board(dev); + if (insn->n != 2) return -EINVAL; @@ -218,9 +220,9 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, s->state |= data[0] & data[1]; } if (data[1] & 0x00ff) - outb(s->state & 0xff, dev->iobase + this_board->do_lo); + outb(s->state & 0xff, dev->iobase + board->do_lo); if (data[1] & 0xff00) - outb((s->state >> 8), dev->iobase + this_board->do_hi); + outb((s->state >> 8), dev->iobase + board->do_hi); data[1] = s->state; @@ -229,6 +231,7 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl726_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; @@ -238,9 +241,9 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif iobase = it->options[0]; - iorange = this_board->io_range; + iorange = board->io_range; printk(KERN_WARNING "comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor, - this_board->name, iobase); + board->name, iobase); if (!request_region(iobase, iorange, "pcl726")) { printk(KERN_WARNING "I/O port conflict\n"); return -EIO; @@ -248,7 +251,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; - dev->board_name = this_board->name; + dev->board_name = board->name; ret = alloc_private(dev, sizeof(struct pcl726_private)); if (ret < 0) @@ -297,23 +300,23 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* ao */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = this_board->n_aochan; + s->n_chan = board->n_aochan; s->maxdata = 0xfff; s->len_chanlist = 1; s->insn_write = pcl726_ao_insn; s->insn_read = pcl726_ao_insn_read; s->range_table_list = devpriv->rangelist; - for (i = 0; i < this_board->n_aochan; i++) { + for (i = 0; i < board->n_aochan; i++) { int j; j = it->options[2 + 1]; - if ((j < 0) || (j >= this_board->num_of_ranges)) { + if ((j < 0) || (j >= board->num_of_ranges)) { printk ("Invalid range for channel %d! Must be 0<=%d<%d\n", - i, j, this_board->num_of_ranges - 1); + i, j, board->num_of_ranges - 1); j = 0; } - devpriv->rangelist[i] = this_board->range_type_list[j]; + devpriv->rangelist[i] = board->range_type_list[j]; if (devpriv->rangelist[i]->range[0].min == -devpriv->rangelist[i]->range[0].max) devpriv->bipolar[i] = 1; /* bipolar range */ @@ -321,7 +324,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = dev->subdevices + 1; /* di */ - if (!this_board->have_dio) { + if (!board->have_dio) { s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_DI; @@ -335,7 +338,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = dev->subdevices + 2; /* do */ - if (!this_board->have_dio) { + if (!board->have_dio) { s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_DO; @@ -352,12 +355,14 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcl726_detach(struct comedi_device *dev) { + const struct pcl726_board *board = comedi_board(dev); + #ifdef ACL6126_IRQ if (dev->irq) free_irq(dev->irq, dev); #endif if (dev->iobase) - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); } static struct comedi_driver pcl726_driver = { -- GitLab From f21b15be885ca3e14199773c9a9f52c90804fdb9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:55:37 -0700 Subject: [PATCH 0244/6849] staging: comedi: remove this_board macro in the pcl724 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl724.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 1f66fe1c7d5e..4136a03a5125 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -67,8 +67,6 @@ struct pcl724_board { char is_pet48; }; -#define this_board ((const struct pcl724_board *)dev->board_ptr) - static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { unsigned long iobase = arg; @@ -100,6 +98,7 @@ static int subdev_8255mapped_cb(int dir, int port, int data, static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl724_board *board = comedi_board(dev); unsigned long iobase; unsigned int iorange; int ret, i, n_subdevices; @@ -108,12 +107,12 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif iobase = it->options[0]; - iorange = this_board->io_range; - if ((this_board->can_have96) && ((it->options[1] == 1) + iorange = board->io_range; + if ((board->can_have96) && ((it->options[1] == 1) || (it->options[1] == 96))) iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */ printk(KERN_INFO "comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor, - this_board->name, iobase); + board->name, iobase); if (!request_region(iobase, iorange, "pcl724")) { printk("I/O port conflict\n"); return -EIO; @@ -121,14 +120,14 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; - dev->board_name = this_board->name; + dev->board_name = board->name; #ifdef PCL724_IRQ irq = 0; - if (this_board->IRQbits != 0) { /* board support IRQ */ + if (board->IRQbits != 0) { /* board support IRQ */ irq = it->options[1]; if (irq) { /* we want to use IRQ */ - if (((1 << irq) & this_board->IRQbits) == 0) { + if (((1 << irq) & board->IRQbits) == 0) { printk(KERN_WARNING ", IRQ %u is out of allowed range, " "DISABLING IT", irq); @@ -152,8 +151,8 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("\n"); - n_subdevices = this_board->numofports; - if ((this_board->can_have96) && ((it->options[1] == 1) + n_subdevices = board->numofports; + if ((board->can_have96) && ((it->options[1] == 1) || (it->options[1] == 96))) n_subdevices = 4; /* PCL-724 in 96 DIO configuration */ @@ -162,7 +161,7 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; for (i = 0; i < dev->n_subdevices; i++) { - if (this_board->is_pet48) { + if (board->is_pet48) { subdev_8255_init(dev, dev->subdevices + i, subdev_8255mapped_cb, (unsigned long)(dev->iobase + @@ -179,6 +178,7 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcl724_detach(struct comedi_device *dev) { + const struct pcl724_board *board = comedi_board(dev); int i; for (i = 0; i < dev->n_subdevices; i++) @@ -187,7 +187,7 @@ static void pcl724_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); #endif - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); } static const struct pcl724_board boardtypes[] = { -- GitLab From 90d662e3f1b42145f6d1ae9e58a423c859ed284d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:52:00 -0700 Subject: [PATCH 0245/6849] staging: comedi: remove this_board macro in the pcl711 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl711.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 2e7753f988aa..e943b52d04a8 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -148,8 +148,6 @@ struct pcl711_board { const struct comedi_lrange *ai_range_type; }; -#define this_board ((const struct pcl711_board *)dev->board_ptr) - struct pcl711_private { int board; @@ -169,6 +167,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) int lo, hi; int data; struct comedi_device *dev = d; + const struct pcl711_board *board = comedi_board(dev); struct comedi_subdevice *s = dev->subdevices + 0; if (!dev->attached) { @@ -184,7 +183,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) /* FIXME! Nothing else sets ntrig! */ if (!(--devpriv->ntrig)) { - if (this_board->is_8112) + if (board->is_8112) outb(1, dev->iobase + PCL711_MODE); else outb(0, dev->iobase + PCL711_MODE); @@ -197,13 +196,14 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) static void pcl711_set_changain(struct comedi_device *dev, int chan) { + const struct pcl711_board *board = comedi_board(dev); int chan_register; outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN); chan_register = CR_CHAN(chan); - if (this_board->is_8112) { + if (board->is_8112) { /* * Set the correct channel. The two channel banks are switched @@ -225,6 +225,7 @@ static void pcl711_set_changain(struct comedi_device *dev, int chan) static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcl711_board *board = comedi_board(dev); int i, n; int hi, lo; @@ -237,7 +238,7 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, */ outb(1, dev->iobase + PCL711_MODE); - if (!this_board->is_8112) + if (!board->is_8112) outb(0, dev->iobase + PCL711_SOFTTRIG); i = PCL711_TIMEOUT; @@ -481,6 +482,7 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pcl711_board *board = comedi_board(dev); int ret; unsigned long iobase; unsigned int irq; @@ -498,12 +500,11 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* there should be a sanity check here */ - /* set up some name stuff */ - dev->board_name = this_board->name; + dev->board_name = board->name; /* grab our IRQ */ irq = it->options[1]; - if (irq > this_board->maxirq) { + if (irq > board->maxirq) { printk(KERN_ERR "irq out of range\n"); return -EINVAL; } @@ -529,10 +530,10 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* AI subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = this_board->n_aichan; + s->n_chan = board->n_aichan; s->maxdata = 0xfff; s->len_chanlist = 1; - s->range_table = this_board->ai_range_type; + s->range_table = board->ai_range_type; s->insn_read = pcl711_ai_insn; if (irq) { dev->read_subdev = s; @@ -545,7 +546,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* AO subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = this_board->n_aochan; + s->n_chan = board->n_aochan; s->maxdata = 0xfff; s->len_chanlist = 1; s->range_table = &range_bipolar5; @@ -577,7 +578,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) this is the "base value" for the mode register, which is used for the irq on the PCL711 */ - if (this_board->is_pcl711b) + if (board->is_pcl711b) devpriv->mode = (dev->irq << 4); /* clear DAC */ -- GitLab From 27b40b89e83aa3db99e392694c46b053ad804bba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:46:07 -0700 Subject: [PATCH 0246/6849] staging: comedi: remove boardtype macro in the ni_atmio16d driver The 'boardtype' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio16d.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 4f6145326747..a0890ee202f4 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -110,8 +110,6 @@ struct atmio16_board_t { int has_8255; }; -#define boardtype ((const struct atmio16_board_t *)dev->board_ptr) - /* range structs */ static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, { BIP_RANGE @@ -693,6 +691,7 @@ static int atmio16d_dio_insn_config(struct comedi_device *dev, static int atmio16d_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct atmio16_board_t *board = comedi_board(dev); unsigned int irq; unsigned long iobase; int ret; @@ -708,8 +707,7 @@ static int atmio16d_attach(struct comedi_device *dev, } dev->iobase = iobase; - /* board name */ - dev->board_name = boardtype->name; + dev->board_name = board->name; ret = alloc_subdevices(dev, 4); if (ret < 0) @@ -811,7 +809,7 @@ static int atmio16d_attach(struct comedi_device *dev, /* 8255 subdevice */ s++; - if (boardtype->has_8255) + if (board->has_8255) subdev_8255_init(dev, s, NULL, dev->iobase); else s->type = COMEDI_SUBD_UNUSED; @@ -831,7 +829,9 @@ static int atmio16d_attach(struct comedi_device *dev, static void atmio16d_detach(struct comedi_device *dev) { - if (dev->subdevices && boardtype->has_8255) + const struct atmio16_board_t *board = comedi_board(dev); + + if (dev->subdevices && board->has_8255) subdev_8255_cleanup(dev, dev->subdevices + 3); if (dev->irq) free_irq(dev->irq, dev); -- GitLab From 75b9ad9e902a51edc90cfcb4dd84c53683554de2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:41:39 -0700 Subject: [PATCH 0247/6849] staging: comedi: remove thisboard macro in the ni_at_ao driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_ao.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index c43dd8ada1da..bfe7fb79880d 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -157,8 +157,6 @@ struct atao_board { int n_ao_chans; }; -#define thisboard ((struct atao_board *)dev->board_ptr) - struct atao_private { unsigned short cfg1; @@ -335,6 +333,7 @@ static int atao_calib_insn_write(struct comedi_device *dev, static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct atao_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; int ao_unipolar; @@ -352,9 +351,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - /* dev->board_ptr = atao_probe(dev); */ - - dev->board_name = thisboard->name; + dev->board_name = board->name; if (alloc_private(dev, sizeof(struct atao_private)) < 0) return -ENOMEM; @@ -366,7 +363,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->n_ao_chans; + s->n_chan = board->n_ao_chans; s->maxdata = (1 << 12) - 1; if (ao_unipolar) s->range_table = &range_unipolar10; -- GitLab From 061319698271bc80155cf3a67f0d5afed4024705 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:33:51 -0700 Subject: [PATCH 0248/6849] staging: comedi: remove this_board macro in the dt282x driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 736d8facaee8..eefda3c064d3 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -221,8 +221,6 @@ struct dt282x_board { int dabits; }; -#define this_board ((const struct dt282x_board *)dev->board_ptr) - struct dt282x_private { int ad_2scomp; /* we have 2's comp jumper set */ int da0_2scomp; /* same, for DAC0 */ @@ -580,6 +578,7 @@ static int dt282x_ai_insn_read(struct comedi_device *dev, static int dt282x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct dt282x_board *board = comedi_board(dev); int err = 0; int tmp; @@ -658,8 +657,8 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, cmd->convert_arg = SLOWEST_TIMER; err++; } - if (cmd->convert_arg < this_board->ai_speed) { - cmd->convert_arg = this_board->ai_speed; + if (cmd->convert_arg < board->ai_speed) { + cmd->convert_arg = board->ai_speed; err++; } if (cmd->scan_end_arg != cmd->chanlist_len) { @@ -694,6 +693,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct dt282x_board *board = comedi_board(dev); struct comedi_cmd *cmd = &s->async->cmd; int timer; @@ -706,8 +706,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dt282x_disable_dma(dev); - if (cmd->convert_arg < this_board->ai_speed) - cmd->convert_arg = this_board->ai_speed; + if (cmd->convert_arg < board->ai_speed) + cmd->convert_arg = board->ai_speed; timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST); outw(timer, dev->iobase + DT2821_TMRCTR); @@ -1176,12 +1176,13 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) */ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dt282x_board *board = comedi_board(dev); int i, irq; int ret; struct comedi_subdevice *s; unsigned long iobase; - dev->board_name = this_board->name; + dev->board_name = board->name; iobase = it->options[opt_iobase]; if (!iobase) -- GitLab From 5a011d61ed5ca531470493acf19756fc4e894675 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:28:02 -0700 Subject: [PATCH 0249/6849] staging: comedi: remove this_board macro in the dt2811 driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2811.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 106ffea30b95..727da9e19206 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -211,8 +211,6 @@ struct dt2811_board { const struct comedi_lrange *unip_5; }; -#define this_board ((const struct dt2811_board *)dev->board_ptr) - enum { card_2811_pgh, card_2811_pgl }; struct dt2811_private { @@ -404,6 +402,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* unsigned long irqs; */ /* long flags; */ + const struct dt2811_board *board = comedi_board(dev); int ret; struct comedi_subdevice *s; unsigned long iobase; @@ -418,7 +417,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - dev->board_name = this_board->name; + dev->board_name = board->name; #if 0 outb(0, dev->iobase + DT2811_ADCSR); @@ -527,13 +526,13 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) switch (it->options[3]) { case 0: default: - s->range_table = this_board->bip_5; + s->range_table = board->bip_5; break; case 1: - s->range_table = this_board->bip_2_5; + s->range_table = board->bip_2_5; break; case 2: - s->range_table = this_board->unip_5; + s->range_table = board->unip_5; break; } -- GitLab From df9d33493474a342c866119c28204e0a790de5c0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:23:09 -0700 Subject: [PATCH 0250/6849] staging: comedi: remove thisboard macro in the dmm32at driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dmm32at.c | 39 ++++++++---------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 83828903db4b..5be99b5d22e4 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -189,11 +189,6 @@ static const struct dmm32at_board dmm32at_boards[] = { }, }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct dmm32at_board *)dev->board_ptr) - /* this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, * feel free to suggest moving the variable to the struct comedi_device struct. @@ -290,6 +285,7 @@ void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec); static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dmm32at_board *board = comedi_board(dev); int ret; struct comedi_subdevice *s; unsigned char aihi, ailo, fifostat, aistat, intstat, airback; @@ -304,7 +300,7 @@ static int dmm32at_attach(struct comedi_device *dev, iobase, irq); /* register address space */ - if (!request_region(iobase, DMM32AT_MEMSIZE, thisboard->name)) { + if (!request_region(iobase, DMM32AT_MEMSIZE, board->name)) { printk(KERN_ERR "comedi%d: dmm32at: I/O port conflict\n", dev->minor); return -EIO; @@ -358,7 +354,7 @@ static int dmm32at_attach(struct comedi_device *dev, /* board is there, register interrupt */ if (irq) { - ret = request_irq(irq, dmm32at_isr, 0, thisboard->name, dev); + ret = request_irq(irq, dmm32at_isr, 0, board->name, dev); if (ret < 0) { printk(KERN_ERR "dmm32at: irq conflict\n"); return ret; @@ -366,18 +362,7 @@ static int dmm32at_attach(struct comedi_device *dev, dev->irq = irq; } -/* - * If you can probe the device to determine what device in a series - * it is, this is the place to do it. Otherwise, dev->board_ptr - * should already be initialized. - */ - /* dev->board_ptr = dmm32at_probe(dev); */ - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; + dev->board_name = board->name; /* * Allocate the private structure area. alloc_private() is a @@ -399,9 +384,9 @@ static int dmm32at_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_AI; /* we support single-ended (ground) and differential */ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = thisboard->ai_ranges; + s->n_chan = board->ai_chans; + s->maxdata = (1 << board->ai_bits) - 1; + s->range_table = board->ai_ranges; s->len_chanlist = 32; /* This is the maximum chanlist length that the board can handle */ s->insn_read = dmm32at_ai_rinsn; @@ -413,15 +398,15 @@ static int dmm32at_attach(struct comedi_device *dev, /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_chans; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ao_ranges; + s->n_chan = board->ao_chans; + s->maxdata = (1 << board->ao_bits) - 1; + s->range_table = board->ao_ranges; s->insn_write = dmm32at_ao_winsn; s->insn_read = dmm32at_ao_rinsn; s = dev->subdevices + 2; /* digital i/o subdevice */ - if (thisboard->have_dio) { + if (board->have_dio) { /* get access to the DIO regs */ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); @@ -433,7 +418,7 @@ static int dmm32at_attach(struct comedi_device *dev, /* set up the subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->dio_chans; + s->n_chan = board->dio_chans; s->maxdata = 1; s->state = 0; s->range_table = &range_digital; -- GitLab From 4c354b492eeb257e65886329ba5acfb1fde81dec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:13:38 -0700 Subject: [PATCH 0251/6849] staging: comedi: remove thisboard macro in the das16m1 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16m1.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index d2e1490cd808..e468ff14aa52 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -150,7 +150,6 @@ struct das16m1_private_struct { unsigned int divisor2; /* divides master clock to obtain conversion speed */ }; #define devpriv ((struct das16m1_private_struct *)(dev->private)) -#define thisboard ((const struct das16m1_board *)(dev->board_ptr)) static inline short munge_sample(short data) { @@ -168,6 +167,7 @@ static void munge_sample_array(short *array, unsigned int num_elements) static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct das16m1_board *board = comedi_board(dev); unsigned int err = 0, tmp, i; /* make sure triggers are valid */ @@ -225,8 +225,8 @@ static int das16m1_cmd_test(struct comedi_device *dev, } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; + if (cmd->convert_arg < board->ai_speed) { + cmd->convert_arg = board->ai_speed; err++; } } @@ -600,6 +600,7 @@ static int das16m1_irq_bits(unsigned int irq) static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct das16m1_board *board = comedi_board(dev); struct comedi_subdevice *s; int ret; unsigned int irq; @@ -611,7 +612,7 @@ static int das16m1_attach(struct comedi_device *dev, if (ret < 0) return ret; - dev->board_name = thisboard->name; + dev->board_name = board->name; if (!request_region(iobase, DAS16M1_SIZE, dev->driver->driver_name)) { comedi_error(dev, "I/O port conflict\n"); -- GitLab From d493f213ab2bfcc41792f904abee75ecfd6afc10 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 16:09:58 -0700 Subject: [PATCH 0252/6849] staging: comedi: remove thisboard macro in the das16 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 106 ++++++++++++++----------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 998444c1ba32..61705366dd40 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -393,11 +393,11 @@ struct das16_private_struct { volatile short timer_mode; /* true if using timer mode */ }; #define devpriv ((struct das16_private_struct *)(dev->private)) -#define thisboard ((struct das16_board *)(dev->board_ptr)) static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct das16_board *board = comedi_board(dev); int err = 0, tmp; int gain, start_chan, i; int mask; @@ -411,7 +411,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, tmp = cmd->scan_begin_src; mask = TRIG_FOLLOW; /* if board supports burst mode */ - if (thisboard->size > 0x400) + if (board->size > 0x400) mask |= TRIG_TIMER | TRIG_EXT; cmd->scan_begin_src &= mask; if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) @@ -420,7 +420,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, tmp = cmd->convert_src; mask = TRIG_TIMER | TRIG_EXT; /* if board supports burst mode */ - if (thisboard->size > 0x400) + if (board->size > 0x400) mask |= TRIG_NOW; cmd->convert_src &= mask; if (!cmd->convert_src || tmp != cmd->convert_src) @@ -483,15 +483,15 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, /* check against maximum frequency */ if (cmd->scan_begin_src == TRIG_TIMER) { if (cmd->scan_begin_arg < - thisboard->ai_speed * cmd->chanlist_len) { + board->ai_speed * cmd->chanlist_len) { cmd->scan_begin_arg = - thisboard->ai_speed * cmd->chanlist_len; + board->ai_speed * cmd->chanlist_len; err++; } } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; + if (cmd->convert_arg < board->ai_speed) { + cmd->convert_arg = board->ai_speed; err++; } } @@ -614,6 +614,7 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct das16_board *board = comedi_board(dev); struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte; @@ -637,7 +638,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t); /* disable conversions for das1600 mode */ - if (thisboard->size > 0x400) + if (board->size > 0x400) outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV); /* set scan limits */ @@ -648,9 +649,9 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) /* set gain (this is also burst rate register but according to * computer boards manual, burst rate does nothing, even on * keithley cards) */ - if (thisboard->ai_pg != das16_pg_none) { + if (board->ai_pg != das16_pg_none) { range = CR_RANGE(cmd->chanlist[0]); - outb((das16_gainlists[thisboard->ai_pg])[range], + outb((das16_gainlists[board->ai_pg])[range], dev->iobase + DAS16_GAIN); } @@ -663,7 +664,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) /* enable counters */ byte = 0; /* Enable burst mode if appropriate. */ - if (thisboard->size > 0x400) { + if (board->size > 0x400) { if (cmd->convert_src == TRIG_NOW) { outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST); /* set burst length */ @@ -710,7 +711,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); /* Enable conversions if using das1600 mode */ - if (thisboard->size > 0x400) + if (board->size > 0x400) outb(0, dev->iobase + DAS1600_CONV); @@ -719,6 +720,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct das16_board *board = comedi_board(dev); unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -735,7 +737,7 @@ static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) } /* disable burst mode */ - if (thisboard->size > 0x400) + if (board->size > 0x400) outb(0, dev->iobase + DAS1600_BURST); @@ -755,6 +757,7 @@ static void das16_reset(struct comedi_device *dev) static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct das16_board *board = comedi_board(dev); int i, n; int range; int chan; @@ -770,9 +773,9 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, outb(chan, dev->iobase + DAS16_MUX); /* set gain */ - if (thisboard->ai_pg != das16_pg_none) { + if (board->ai_pg != das16_pg_none) { range = CR_RANGE(insn->chanspec); - outb((das16_gainlists[thisboard->ai_pg])[range], + outb((das16_gainlists[board->ai_pg])[range], dev->iobase + DAS16_GAIN); } @@ -790,7 +793,7 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, } msb = inb(dev->iobase + DAS16_AI_MSB); lsb = inb(dev->iobase + DAS16_AI_LSB); - if (thisboard->ai_nbits == 12) + if (board->ai_nbits == 12) data[n] = ((lsb >> 4) & 0xf) | (msb << 4); else data[n] = lsb | (msb << 8); @@ -835,6 +838,7 @@ static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct das16_board *board = comedi_board(dev); int i; int lsb, msb; int chan; @@ -842,7 +846,7 @@ static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, chan = CR_CHAN(insn->chanspec); for (i = 0; i < insn->n; i++) { - if (thisboard->ao_nbits == 12) { + if (board->ao_nbits == 12) { lsb = (data[i] << 4) & 0xff; msb = (data[i] >> 4) & 0xff; } else { @@ -892,6 +896,7 @@ static int disable_dma_on_even(struct comedi_device *dev) static void das16_interrupt(struct comedi_device *dev) { + const struct das16_board *board = comedi_board(dev); unsigned long dma_flags, spin_flags; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; @@ -953,7 +958,7 @@ static void das16_interrupt(struct comedi_device *dev) set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); /* reenable conversions for das1600 mode, (stupid hardware) */ - if (thisboard->size > 0x400 && devpriv->timer_mode == 0) + if (board->size > 0x400 && devpriv->timer_mode == 0) outb(0x00, dev->iobase + DAS1600_CONV); } @@ -1015,6 +1020,7 @@ static void reg_dump(struct comedi_device *dev) static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct das16_board *board = comedi_board(dev); int status; int diobits; @@ -1039,9 +1045,9 @@ static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) diobits = inb(dev->iobase + DAS16_DIO) & 0xf0; printk(KERN_INFO " id bits are 0x%02x\n", diobits); - if (thisboard->id != diobits) { + if (board->id != diobits) { printk(KERN_INFO " requested board's id bits are 0x%x (ignore)\n", - thisboard->id); + board->id); } return 0; @@ -1071,12 +1077,13 @@ static void das16_ai_munge(struct comedi_device *dev, unsigned int num_bytes, unsigned int start_chan_index) { + const struct das16_board *board = comedi_board(dev); unsigned int i, num_samples = num_bytes / sizeof(short); short *data = array; for (i = 0; i < num_samples; i++) { data[i] = le16_to_cpu(data[i]); - if (thisboard->ai_nbits == 12) + if (board->ai_nbits == 12) data[i] = (data[i] >> 4) & 0xfff; } @@ -1092,6 +1099,7 @@ static void das16_ai_munge(struct comedi_device *dev, */ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct das16_board *board = comedi_board(dev); struct comedi_subdevice *s; int ret; unsigned int irq; @@ -1130,9 +1138,9 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - if (thisboard->size < 0x400) { - printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size); - if (!request_region(iobase, thisboard->size, "das16")) { + if (board->size < 0x400) { + printk(" 0x%04lx-0x%04lx\n", iobase, iobase + board->size); + if (!request_region(iobase, board->size, "das16")) { printk(KERN_ERR " I/O port conflict\n"); return -EIO; } @@ -1140,18 +1148,18 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO " 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n", iobase, iobase + 0x0f, iobase + 0x400, - iobase + 0x400 + (thisboard->size & 0x3ff)); + iobase + 0x400 + (board->size & 0x3ff)); if (!request_region(iobase, 0x10, "das16")) { printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n", iobase, iobase + 0x0f); return -EIO; } - if (!request_region(iobase + 0x400, thisboard->size & 0x3ff, + if (!request_region(iobase + 0x400, board->size & 0x3ff, "das16")) { release_region(iobase, 0x10); printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n", iobase + 0x400, - iobase + 0x400 + (thisboard->size & 0x3ff)); + iobase + 0x400 + (board->size & 0x3ff)); return -EIO; } } @@ -1163,10 +1171,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_ERR " id bits do not match selected board, aborting\n"); return -EINVAL; } - dev->board_name = thisboard->name; + dev->board_name = board->name; /* get master clock speed */ - if (thisboard->size < 0x400) { + if (board->size < 0x400) { if (it->options[3]) devpriv->clockbase = 1000 / it->options[3]; else @@ -1222,7 +1230,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* get any user-defined input range */ - if (thisboard->ai_pg == das16_pg_none && + if (board->ai_pg == das16_pg_none && (it->options[4] || it->options[5])) { /* allocate single-range range table */ devpriv->user_ai_range_table = @@ -1263,7 +1271,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = dev->subdevices + 0; dev->read_subdev = s; /* ai */ - if (thisboard->ai) { + if (board->ai) { s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; if (devpriv->ai_singleended) { @@ -1275,15 +1283,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 8; s->subdev_flags |= SDF_DIFF; } - s->maxdata = (1 << thisboard->ai_nbits) - 1; + s->maxdata = (1 << board->ai_nbits) - 1; if (devpriv->user_ai_range_table) { /* user defined ai range */ s->range_table = devpriv->user_ai_range_table; } else if (devpriv->ai_unipolar) { - s->range_table = das16_ai_uni_lranges[thisboard->ai_pg]; + s->range_table = das16_ai_uni_lranges[board->ai_pg]; } else { - s->range_table = das16_ai_bip_lranges[thisboard->ai_pg]; + s->range_table = das16_ai_bip_lranges[board->ai_pg]; } - s->insn_read = thisboard->ai; + s->insn_read = board->ai; s->do_cmdtest = das16_cmd_test; s->do_cmd = das16_cmd_exec; s->cancel = das16_cancel; @@ -1294,44 +1302,44 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = dev->subdevices + 1; /* ao */ - if (thisboard->ao) { + if (board->ao) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; - s->maxdata = (1 << thisboard->ao_nbits) - 1; + s->maxdata = (1 << board->ao_nbits) - 1; /* user defined ao range */ if (devpriv->user_ao_range_table) s->range_table = devpriv->user_ao_range_table; else s->range_table = &range_unknown; - s->insn_write = thisboard->ao; + s->insn_write = board->ao; } else { s->type = COMEDI_SUBD_UNUSED; } s = dev->subdevices + 2; /* di */ - if (thisboard->di) { + if (board->di) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = thisboard->di; + s->insn_bits = board->di; } else { s->type = COMEDI_SUBD_UNUSED; } s = dev->subdevices + 3; /* do */ - if (thisboard->do_) { + if (board->do_) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = thisboard->do_; + s->insn_bits = board->do_; /* initialize digital output lines */ outb(s->state, dev->iobase + DAS16_DIO); } else { @@ -1340,9 +1348,9 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = dev->subdevices + 4; /* 8255 */ - if (thisboard->i8255_offset != 0) { + if (board->i8255_offset != 0) { subdev_8255_init(dev, s, NULL, (dev->iobase + - thisboard->i8255_offset)); + board->i8255_offset)); } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1353,7 +1361,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); /* turn on das1600 mode if available */ - if (thisboard->size > 0x400) { + if (board->size > 0x400) { outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE); outb(0, dev->iobase + DAS1600_CONV); outb(0, dev->iobase + DAS1600_BURST); @@ -1364,6 +1372,8 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void das16_detach(struct comedi_device *dev) { + const struct das16_board *board = comedi_board(dev); + das16_reset(dev); if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 4); @@ -1384,12 +1394,12 @@ static void das16_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) { - if (thisboard->size < 0x400) { - release_region(dev->iobase, thisboard->size); + if (board->size < 0x400) { + release_region(dev->iobase, board->size); } else { release_region(dev->iobase, 0x10); release_region(dev->iobase + 0x400, - thisboard->size & 0x3ff); + board->size & 0x3ff); } } } -- GitLab From bf4683bdbdfafc02f5f4d3170efcd25ff9f00c6b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 15:58:28 -0700 Subject: [PATCH 0253/6849] staging: comedi: remove thisboard macro in the comedi_test driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 873e37450bba..9f3c3d5d02a4 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -67,8 +67,6 @@ struct waveform_board { #define N_CHANS 8 -#define thisboard ((const struct waveform_board *)dev->board_ptr) - /* Data unique to this driver */ struct waveform_private { struct timer_list timer; @@ -429,12 +427,13 @@ static int waveform_ao_insn_write(struct comedi_device *dev, static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct waveform_board *board = comedi_board(dev); struct comedi_subdevice *s; int amplitude = it->options[0]; int period = it->options[1]; int i; - dev->board_name = thisboard->name; + dev->board_name = board->name; if (alloc_private(dev, sizeof(struct waveform_private)) < 0) return -ENOMEM; @@ -457,8 +456,8 @@ static int waveform_attach(struct comedi_device *dev, /* analog input subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; + s->n_chan = board->ai_chans; + s->maxdata = (1 << board->ai_bits) - 1; s->range_table = &waveform_ai_ranges; s->len_chanlist = s->n_chan * 2; s->insn_read = waveform_ai_insn_read; @@ -471,8 +470,8 @@ static int waveform_attach(struct comedi_device *dev, /* analog output subdevice (loopback) */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; + s->n_chan = board->ai_chans; + s->maxdata = (1 << board->ai_bits) - 1; s->range_table = &waveform_ai_ranges; s->len_chanlist = s->n_chan * 2; s->insn_write = waveform_ao_insn_write; -- GitLab From b74055465ce47c75b3ebf667c2ff0661828d7a11 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 15:51:14 -0700 Subject: [PATCH 0254/6849] staging: comedi: remove thisboard macro in the aio_iiro_16 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/aio_iiro_16.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 04f6f94b1f47..5c1548b385f4 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -57,8 +57,6 @@ static const struct aio_iiro_16_board aio_iiro_16_boards[] = { .do_ = 16}, }; -#define thisboard ((const struct aio_iiro_16_board *) dev->board_ptr) - struct aio_iiro_16_private { int data; struct pci_dev *pci_dev; @@ -106,12 +104,13 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct aio_iiro_16_board *board = comedi_board(dev); int iobase; struct comedi_subdevice *s; printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor); - dev->board_name = thisboard->name; + dev->board_name = board->name; iobase = it->options[0]; -- GitLab From 797ef32ba35589393f993bb2f18698d4bc3ad07d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 15:46:02 -0700 Subject: [PATCH 0255/6849] staging: comedi: remove this_board macro in the aio_aio12_8 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/aio_aio12_8.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 64d82bc4ffe4..d215ae16668b 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -80,8 +80,6 @@ static const struct aio12_8_boardtype board_types[] = { .name = "aio_aio12_8"}, }; -#define thisboard ((const struct aio12_8_boardtype *) dev->board_ptr) - struct aio12_8_private { unsigned int ao_readback[4]; }; @@ -167,6 +165,7 @@ static const struct comedi_lrange range_aio_aio12_8 = { static int aio_aio12_8_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct aio12_8_boardtype *board = comedi_board(dev); int iobase; struct comedi_subdevice *s; @@ -176,7 +175,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, return -EIO; } - dev->board_name = thisboard->name; + dev->board_name = board->name; dev->iobase = iobase; -- GitLab From b13ff04654b406618f96e59168006c530f4774aa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 15:41:29 -0700 Subject: [PATCH 0256/6849] staging: comedi: remove thisboard macro in the adq12b driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adq12b.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 7d585a12050f..1da298967413 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -125,8 +125,6 @@ struct adq12b_board { int do_chans; }; -#define thisboard ((const struct adq12b_board *)dev->board_ptr) - struct adq12b_private { int unipolar; /* option 2 of comedi_config (1 is iobase) */ int differential; /* option 3 of comedi_config */ @@ -222,6 +220,7 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct adq12b_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; int unipolar, differential; @@ -250,11 +249,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; + dev->board_name = board->name; /* * Allocate the private structure area. alloc_private() is a @@ -284,10 +279,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_AI; if (differential) { s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai_diff_chans; + s->n_chan = board->ai_diff_chans; } else { s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = thisboard->ai_se_chans; + s->n_chan = board->ai_se_chans; } if (unipolar) @@ -295,7 +290,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) else s->range_table = &range_adq12b_ai_bipolar; - s->maxdata = (1 << thisboard->ai_bits) - 1; + s->maxdata = (1 << board->ai_bits) - 1; s->len_chanlist = 4; /* This is the maximum chanlist length that the board can handle */ @@ -305,7 +300,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital input subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; - s->n_chan = thisboard->di_chans; + s->n_chan = board->di_chans; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = adq12b_di_insn_bits; @@ -314,7 +309,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->do_chans; + s->n_chan = board->do_chans; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = adq12b_do_insn_bits; -- GitLab From 960ca1ae1e0676dfef699c37362dad1d4fee5397 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 15:31:41 -0700 Subject: [PATCH 0257/6849] staging: comedi: remove this_board macro in the acl7225b driver The 'this_board' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/acl7225b.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index 4e4fc418655f..c1963add660d 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -27,8 +27,6 @@ struct boardtype { int io_range; /* len of I/O space */ }; -#define this_board ((const struct boardtype *)dev->board_ptr) - static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -67,19 +65,20 @@ static int acl7225b_di_insn(struct comedi_device *dev, static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct boardtype *board = comedi_board(dev); struct comedi_subdevice *s; int iobase, iorange; iobase = it->options[0]; - iorange = this_board->io_range; + iorange = board->io_range; printk(KERN_INFO "comedi%d: acl7225b: board=%s 0x%04x\n", dev->minor, - this_board->name, iobase); + board->name, iobase); if (!request_region(iobase, iorange, "acl7225b")) { printk(KERN_ERR "comedi%d: request_region failed - I/O port conflict\n", dev->minor); return -EIO; } - dev->board_name = this_board->name; + dev->board_name = board->name; dev->iobase = iobase; dev->irq = 0; @@ -121,8 +120,10 @@ static int acl7225b_attach(struct comedi_device *dev, static void acl7225b_detach(struct comedi_device *dev) { + const struct boardtype *board = comedi_board(dev); + if (dev->iobase) - release_region(dev->iobase, this_board->io_range); + release_region(dev->iobase, board->io_range); } static const struct boardtype boardtypes[] = { -- GitLab From 5254cbe795c3bb9ef28d61a474d707385fc87178 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 22 May 2012 18:20:10 -0700 Subject: [PATCH 0258/6849] staging: comedi: remove this_board macro in the s526 driver The 'thisboard' macro depends on having a local variable with a magic name. The CodingStyle document suggests not doing this to avoid confusion. Remove the macro and use the comedi_board() inline helper to get the dev->board_ptr information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s526.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 7a56434eb224..3c8e9799824e 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -200,11 +200,6 @@ static const struct s526_board s526_boards[] = { #define ADDR_REG(reg) (dev->iobase + (reg)) #define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8) -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct s526_board *)dev->board_ptr) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device @@ -744,6 +739,7 @@ static int s526_dio_insn_config(struct comedi_device *dev, static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct s526_board *board = comedi_board(dev); struct comedi_subdevice *s; int iobase; int i, n; @@ -754,7 +750,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "comedi%d: s526: ", dev->minor); iobase = it->options[0]; - if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) { + if (!iobase || !request_region(iobase, S526_IOSIZE, board->name)) { comedi_error(dev, "I/O port conflict"); return -EIO; } @@ -769,13 +765,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) } ***/ -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_ptr = &s526_boards[0]; - - dev->board_name = thisboard->name; + dev->board_name = board->name; /* * Allocate the private structure area. alloc_private() is a @@ -797,7 +787,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */ - s->n_chan = thisboard->gpct_chans; + s->n_chan = board->gpct_chans; s->maxdata = 0x00ffffff; /* 24 bit counter */ s->insn_read = s526_gpct_rinsn; s->insn_config = s526_gpct_insn_config; @@ -838,7 +828,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = dev->subdevices + 3; /* digital i/o subdevice */ - if (thisboard->have_dio) { + if (board->have_dio) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 8; -- GitLab From 1c9de58acc06cba56b5f1bd17a5a74a66427f8b1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 May 2012 15:14:45 +0300 Subject: [PATCH 0259/6849] staging: comedi: cleanup comedi_recognize() This function is more complicated than it needs to be because of the consts. It's not worth saving them when we drop the consts anyway when we return (void *)name_ptr. Signed-off-by: Dan Carpenter Cc: Ian Abbott Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 7289dcb5c32c..438c52a313b1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -304,14 +304,13 @@ static int postconfig(struct comedi_device *dev) * that register their supported board names */ static void *comedi_recognize(struct comedi_driver *driv, const char *name) { - unsigned i; - const char *const *name_ptr = driv->board_name; + char **name_ptr = (char **)driv->board_name; + int i; + for (i = 0; i < driv->num_names; i++) { if (strcmp(*name_ptr, name) == 0) - return (void *)name_ptr; - name_ptr = - (const char *const *)((const char *)name_ptr + - driv->offset); + return name_ptr; + name_ptr = (void *)name_ptr + driv->offset; } return NULL; -- GitLab From 8ce8e2b56f36c737888d040016f103d91ecbfbad Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:20 -0300 Subject: [PATCH 0260/6849] Bluetooth: Fix coding style in mgmt.c Follow the coding style of the net subsystem. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 25d220776079..6a7e926c418f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -871,7 +871,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, } if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || - mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { + mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, MGMT_STATUS_BUSY); goto failed; @@ -978,7 +978,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, } if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || - mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { + mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { err = cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, MGMT_STATUS_BUSY); goto failed; @@ -1001,7 +1001,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, scan = 0; if (test_bit(HCI_ISCAN, &hdev->flags) && - hdev->discov_timeout > 0) + hdev->discov_timeout > 0) cancel_delayed_work(&hdev->discov_off); } @@ -1056,7 +1056,7 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, bool changed = false; if (!!cp->val != test_bit(HCI_LINK_SECURITY, - &hdev->dev_flags)) { + &hdev->dev_flags)) { change_bit(HCI_LINK_SECURITY, &hdev->dev_flags); changed = true; } @@ -1317,7 +1317,7 @@ static bool enable_service_cache(struct hci_dev *hdev) } static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, - u16 len) + u16 len) { struct mgmt_cp_remove_uuid *cp = data; struct pending_cmd *cmd; @@ -1442,7 +1442,7 @@ unlock: } static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, - u16 len) + u16 len) { struct mgmt_cp_load_link_keys *cp = data; u16 key_count, expected_len; @@ -1454,13 +1454,13 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, sizeof(struct mgmt_link_key_info); if (expected_len != len) { BT_ERR("load_link_keys: expected %u bytes, got %u bytes", - len, expected_len); + len, expected_len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, MGMT_STATUS_INVALID_PARAMS); } BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys, - key_count); + key_count); hci_dev_lock(hdev); @@ -1535,10 +1535,10 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, if (cp->disconnect) { if (cp->addr.type == BDADDR_BREDR) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, - &cp->addr.bdaddr); + &cp->addr.bdaddr); else conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, - &cp->addr.bdaddr); + &cp->addr.bdaddr); } else { conn = NULL; } @@ -1813,7 +1813,7 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, hdev->io_capability = cp->io_capability; BT_DBG("%s IO capability set to 0x%02x", hdev->name, - hdev->io_capability); + hdev->io_capability); hci_dev_unlock(hdev); @@ -1941,7 +1941,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, cmd->user_data = conn; if (conn->state == BT_CONNECTED && - hci_conn_security(conn, sec_level, auth_type)) + hci_conn_security(conn, sec_level, auth_type)) pairing_complete(cmd, 0); err = 0; @@ -2238,7 +2238,7 @@ unlock: } static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, - void *data, u16 len) + void *data, u16 len) { struct mgmt_cp_remove_remote_oob_data *cp = data; u8 status; @@ -2407,7 +2407,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, case DISCOVERY_RESOLVING: e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, - NAME_PENDING); + NAME_PENDING); if (!e) { mgmt_pending_remove(cmd); err = cmd_complete(sk, hdev->id, @@ -2629,7 +2629,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, sizeof(struct mgmt_ltk_info); if (expected_len != len) { BT_ERR("load_keys: expected %u bytes, got %u bytes", - len, expected_len); + len, expected_len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, EINVAL); } @@ -2754,7 +2754,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) } if (opcode >= ARRAY_SIZE(mgmt_handlers) || - mgmt_handlers[opcode].func == NULL) { + mgmt_handlers[opcode].func == NULL) { BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, index, opcode, MGMT_STATUS_UNKNOWN_COMMAND); @@ -2762,7 +2762,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) } if ((hdev && opcode < MGMT_OP_READ_INFO) || - (!hdev && opcode >= MGMT_OP_READ_INFO)) { + (!hdev && opcode >= MGMT_OP_READ_INFO)) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_INDEX); goto done; @@ -2771,7 +2771,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) handler = &mgmt_handlers[opcode]; if ((handler->var_len && len < handler->data_len) || - (!handler->var_len && len != handler->data_len)) { + (!handler->var_len && len != handler->data_len)) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_PARAMS); goto done; @@ -3090,7 +3090,7 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, mgmt_pending_remove(cmd); mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, - hdev); + hdev); return err; } @@ -3180,7 +3180,7 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, } int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type) + u8 link_type, u8 addr_type) { struct mgmt_ev_user_passkey_request ev; @@ -3194,8 +3194,8 @@ int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, } static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type, u8 status, - u8 opcode) + u8 link_type, u8 addr_type, u8 status, + u8 opcode) { struct pending_cmd *cmd; struct mgmt_rp_user_confirm_reply rp; -- GitLab From be7c2b99e9cde90e398f61121f3f45d65d5644c7 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:21 -0300 Subject: [PATCH 0261/6849] Bluetooth: Fix coding style in sco.c Follow the net subsystem rules. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/sco.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index cbdd313659a7..78473ff7cc8d 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -523,7 +523,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen goto done; err = bt_sock_wait_state(sk, BT_CONNECTED, - sock_sndtimeo(sk, flags & O_NONBLOCK)); + sock_sndtimeo(sk, flags & O_NONBLOCK)); done: release_sock(sk); @@ -788,7 +788,7 @@ static int sco_sock_shutdown(struct socket *sock, int how) if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) err = bt_sock_wait_state(sk, BT_CLOSED, - sk->sk_lingertime); + sk->sk_lingertime); } release_sock(sk); return err; @@ -878,7 +878,7 @@ static void sco_conn_ready(struct sco_conn *conn) bh_lock_sock(parent); sk = sco_sock_alloc(sock_net(parent), NULL, - BTPROTO_SCO, GFP_ATOMIC); + BTPROTO_SCO, GFP_ATOMIC); if (!sk) { bh_unlock_sock(parent); goto done; @@ -920,7 +920,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) continue; if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || - !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { + !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { lm |= HCI_LM_ACCEPT; break; } @@ -981,7 +981,7 @@ static int sco_debugfs_show(struct seq_file *f, void *p) sk_for_each(sk, node, &sco_sk_list.head) { seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), - batostr(&bt_sk(sk)->dst), sk->sk_state); + batostr(&bt_sk(sk)->dst), sk->sk_state); } read_unlock(&sco_sk_list.lock); @@ -1044,8 +1044,8 @@ int __init sco_init(void) } if (bt_debugfs) { - sco_debugfs = debugfs_create_file("sco", 0444, - bt_debugfs, NULL, &sco_debugfs_fops); + sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs, + NULL, &sco_debugfs_fops); if (!sco_debugfs) BT_ERR("Failed to create SCO debug file"); } -- GitLab From 3bb3c7551c2f1083263aee8312b3db1e751ca0fb Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:22 -0300 Subject: [PATCH 0262/6849] Bluetooth: Fix coding style in hci_sock.c Follow the net subsystem rules. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_sock.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 5914623f426a..bdf51d1d2c19 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -113,7 +113,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) flt = &hci_pi(sk)->filter; if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ? - 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask)) + 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), + &flt->type_mask)) continue; if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) { @@ -747,7 +748,7 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_ } static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) + struct msghdr *msg, size_t len, int flags) { int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; @@ -857,8 +858,9 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, u16 ocf = hci_opcode_ocf(opcode); if (((ogf > HCI_SFLT_MAX_OGF) || - !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) && - !capable(CAP_NET_RAW)) { + !hci_test_bit(ocf & HCI_FLT_OCF_BITS, + &hci_sec_filter.ocf_mask[ogf])) && + !capable(CAP_NET_RAW)) { err = -EPERM; goto drop; } -- GitLab From b80f021f706f3578a1e80069c8e0f73b9a0ca6a7 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:23 -0300 Subject: [PATCH 0263/6849] Bluetooth: Fix coding style in hci_sysfs.c Follow the net subsystem rules. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_sysfs.c | 93 ++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 937f3187eafa..847a8445c53c 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -31,27 +31,30 @@ static inline char *link_typetostr(int type) } } -static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_link_type(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); return sprintf(buf, "%s\n", link_typetostr(conn->type)); } -static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_link_address(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); return sprintf(buf, "%s\n", batostr(&conn->dst)); } -static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_link_features(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - conn->features[0], conn->features[1], - conn->features[2], conn->features[3], - conn->features[4], conn->features[5], - conn->features[6], conn->features[7]); + conn->features[0], conn->features[1], + conn->features[2], conn->features[3], + conn->features[4], conn->features[5], + conn->features[6], conn->features[7]); } #define LINK_ATTR(_name, _mode, _show, _store) \ @@ -185,19 +188,22 @@ static inline char *host_typetostr(int type) } } -static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_bus(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); } -static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_type(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); } -static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_name(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); char name[HCI_MAX_NAME_LENGTH + 1]; @@ -210,55 +216,64 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, char return sprintf(buf, "%s\n", name); } -static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_class(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "0x%.2x%.2x%.2x\n", - hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); + hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); } -static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_address(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%s\n", batostr(&hdev->bdaddr)); } -static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_features(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - hdev->features[0], hdev->features[1], - hdev->features[2], hdev->features[3], - hdev->features[4], hdev->features[5], - hdev->features[6], hdev->features[7]); + hdev->features[0], hdev->features[1], + hdev->features[2], hdev->features[3], + hdev->features[4], hdev->features[5], + hdev->features[6], hdev->features[7]); } -static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_manufacturer(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->manufacturer); } -static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_hci_version(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->hci_ver); } -static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_hci_revision(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->hci_rev); } -static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_idle_timeout(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->idle_timeout); } -static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t store_idle_timeout(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct hci_dev *hdev = to_hci_dev(dev); unsigned int val; @@ -276,13 +291,16 @@ static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *a return count; } -static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_sniff_max_interval(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->sniff_max_interval); } -static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t store_sniff_max_interval(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct hci_dev *hdev = to_hci_dev(dev); u16 val; @@ -300,13 +318,16 @@ static ssize_t store_sniff_max_interval(struct device *dev, struct device_attrib return count; } -static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_sniff_min_interval(struct device *dev, + struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->sniff_min_interval); } -static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t store_sniff_min_interval(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct hci_dev *hdev = to_hci_dev(dev); u16 val; @@ -335,11 +356,11 @@ static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, - show_idle_timeout, store_idle_timeout); + show_idle_timeout, store_idle_timeout); static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, - show_sniff_max_interval, store_sniff_max_interval); + show_sniff_max_interval, store_sniff_max_interval); static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, - show_sniff_min_interval, store_sniff_min_interval); + show_sniff_min_interval, store_sniff_min_interval); static struct attribute *bt_host_attrs[] = { &dev_attr_bus.attr, @@ -455,8 +476,8 @@ static void print_bt_uuid(struct seq_file *f, u8 *uuid) memcpy(&data5, &uuid[14], 2); seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x\n", - ntohl(data0), ntohs(data1), ntohs(data2), - ntohs(data3), ntohl(data4), ntohs(data5)); + ntohl(data0), ntohs(data1), ntohs(data2), ntohs(data3), + ntohl(data4), ntohs(data5)); } static int uuids_show(struct seq_file *f, void *p) @@ -513,7 +534,7 @@ static int auto_accept_delay_get(void *data, u64 *val) } DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, - auto_accept_delay_set, "%llu\n"); + auto_accept_delay_set, "%llu\n"); void hci_init_sysfs(struct hci_dev *hdev) { @@ -547,15 +568,15 @@ int hci_add_sysfs(struct hci_dev *hdev) return 0; debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, - hdev, &inquiry_cache_fops); + hdev, &inquiry_cache_fops); debugfs_create_file("blacklist", 0444, hdev->debugfs, - hdev, &blacklist_fops); + hdev, &blacklist_fops); debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev, - &auto_accept_delay_fops); + &auto_accept_delay_fops); return 0; } -- GitLab From 807deac275cfd5b1d1d634d6aff2f9f77a843c73 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:24 -0300 Subject: [PATCH 0264/6849] Bluetooth: Fix coding style in hci_event.c Follow the net subsystem rules. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 239 +++++++++++++++++++++----------------- 1 file changed, 135 insertions(+), 104 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4eefb7f65cf6..6c2d7ccf26e5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -95,7 +95,8 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) hci_conn_check_pending(hdev); } -static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, + struct sk_buff *skb) { BT_DBG("%s", hdev->name); } @@ -166,7 +167,8 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cc_read_def_link_policy(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_rp_read_def_link_policy *rp = (void *) skb->data; @@ -178,7 +180,8 @@ static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *sk hdev->link_policy = __le16_to_cpu(rp->policy); } -static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cc_write_def_link_policy(struct hci_dev *hdev, + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); void *sent; @@ -329,7 +332,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) if (hdev->discov_timeout > 0) { int to = msecs_to_jiffies(hdev->discov_timeout * 1000); queue_delayed_work(hdev->workqueue, &hdev->discov_off, - to); + to); } } else if (old_iscan) mgmt_discoverable(hdev, 0); @@ -358,7 +361,7 @@ static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) memcpy(hdev->dev_class, rp->dev_class, 3); BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, - hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); + hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); } static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) @@ -473,7 +476,7 @@ static u8 hci_get_inquiry_mode(struct hci_dev *hdev) return 1; if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && - hdev->lmp_subver == 0x0757) + hdev->lmp_subver == 0x0757) return 1; if (hdev->manufacturer == 15) { @@ -486,7 +489,7 @@ static u8 hci_get_inquiry_mode(struct hci_dev *hdev) } if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && - hdev->lmp_subver == 0x1805) + hdev->lmp_subver == 0x1805) return 1; return 0; @@ -618,8 +621,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, - hdev->manufacturer, - hdev->hci_ver, hdev->hci_rev); + hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); if (test_bit(HCI_INIT, &hdev->flags)) hci_setup(hdev); @@ -713,10 +715,10 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, - hdev->features[0], hdev->features[1], - hdev->features[2], hdev->features[3], - hdev->features[4], hdev->features[5], - hdev->features[6], hdev->features[7]); + hdev->features[0], hdev->features[1], + hdev->features[2], hdev->features[3], + hdev->features[4], hdev->features[5], + hdev->features[6], hdev->features[7]); } static void hci_set_le_support(struct hci_dev *hdev) @@ -736,7 +738,7 @@ static void hci_set_le_support(struct hci_dev *hdev) } static void hci_cc_read_local_ext_features(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_local_ext_features *rp = (void *) skb->data; @@ -762,7 +764,7 @@ done: } static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; @@ -798,9 +800,8 @@ static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) hdev->acl_cnt = hdev->acl_pkts; hdev->sco_cnt = hdev->sco_pkts; - BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, - hdev->acl_mtu, hdev->acl_pkts, - hdev->sco_mtu, hdev->sco_pkts); + BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, + hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); } static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) @@ -816,7 +817,7 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_read_data_block_size(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_data_block_size *rp = (void *) skb->data; @@ -832,7 +833,7 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev, hdev->block_cnt = hdev->num_blocks; BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, - hdev->block_cnt, hdev->block_len); + hdev->block_cnt, hdev->block_len); hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status); } @@ -847,7 +848,7 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_read_local_amp_info(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_local_amp_info *rp = (void *) skb->data; @@ -871,7 +872,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, } static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -890,7 +891,7 @@ static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -900,7 +901,7 @@ static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, } static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; @@ -959,7 +960,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, - rp->status); + rp->status); hci_dev_unlock(hdev); } @@ -1000,7 +1001,7 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_user_confirm_reply *rp = (void *) skb->data; @@ -1031,7 +1032,7 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_user_confirm_reply *rp = (void *) skb->data; @@ -1047,7 +1048,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, } static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_local_oob_data *rp = (void *) skb->data; @@ -1076,7 +1077,7 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_cp_le_set_scan_enable *cp; __u8 status = *((__u8 *) skb->data); @@ -1157,7 +1158,7 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) } static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_cp_write_le_host_supported *sent; __u8 status = *((__u8 *) skb->data); @@ -1176,7 +1177,7 @@ static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, } if (test_bit(HCI_MGMT, &hdev->dev_flags) && - !test_bit(HCI_INIT, &hdev->flags)) + !test_bit(HCI_INIT, &hdev->flags)) mgmt_le_enable_complete(hdev, sent->le, status); hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); @@ -1333,7 +1334,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) } static int hci_outgoing_auth_needed(struct hci_dev *hdev, - struct hci_conn *conn) + struct hci_conn *conn) { if (conn->state != BT_CONFIG || !conn->out) return 0; @@ -1343,9 +1344,8 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, /* Only request authentication for SSP connections or non-SSP * devices with sec_level HIGH or if MITM protection is requested */ - if (!hci_conn_ssp_enabled(conn) && - conn->pending_sec_level != BT_SECURITY_HIGH && - !(conn->auth_type & 0x01)) + if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && + conn->pending_sec_level != BT_SECURITY_HIGH) return 0; return 1; @@ -1638,7 +1638,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), - conn); + conn); if (status) { if (conn && conn->state == BT_CONNECT) { @@ -1668,7 +1668,8 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) BT_DBG("%s status 0x%x", hdev->name, status); } -static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); struct discovery_state *discov = &hdev->discovery; @@ -1708,7 +1709,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_inquiry_result_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct inquiry_data data; struct inquiry_info *info = (void *) (skb->data + 1); @@ -1745,7 +1747,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * hci_dev_unlock(hdev); } -static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_conn_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1823,18 +1826,19 @@ unlock: hci_conn_check_pending(hdev); } -static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_conn_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_conn_request *ev = (void *) skb->data; int mask = hdev->link_mode; - BT_DBG("%s bdaddr %s type 0x%x", hdev->name, - batostr(&ev->bdaddr), ev->link_type); + BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr), + ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); if ((mask & HCI_LM_ACCEPT) && - !hci_blacklist_lookup(hdev, &ev->bdaddr)) { + !hci_blacklist_lookup(hdev, &ev->bdaddr)) { /* Connection accepted */ struct inquiry_entry *ie; struct hci_conn *conn; @@ -1897,7 +1901,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk } } -static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_disconn_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_disconn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1914,10 +1919,10 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff conn->state = BT_CLOSED; if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && - (conn->type == ACL_LINK || conn->type == LE_LINK)) { + (conn->type == ACL_LINK || conn->type == LE_LINK)) { if (ev->status != 0) mgmt_disconnect_failed(hdev, &conn->dst, conn->type, - conn->dst_type, ev->status); + conn->dst_type, ev->status); else mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type); @@ -1934,7 +1939,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_auth_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_auth_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1949,7 +1955,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s if (!ev->status) { if (!hci_conn_ssp_enabled(conn) && - test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { + test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { BT_INFO("re-auth of legacy device is not possible."); } else { conn->link_mode |= HCI_LM_AUTH; @@ -1969,7 +1975,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s cp.handle = ev->handle; cp.encrypt = 0x01; hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), - &cp); + &cp); } else { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); @@ -1989,7 +1995,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s cp.handle = ev->handle; cp.encrypt = 0x01; hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), - &cp); + &cp); } else { clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); hci_encrypt_cfm(conn, ev->status, 0x00); @@ -2039,7 +2045,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_encrypt_change_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_encrypt_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2082,7 +2089,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_change_link_key_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -2104,7 +2112,8 @@ static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct hci_dev_unlock(hdev); } -static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_remote_features_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; @@ -2128,7 +2137,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff cp.handle = ev->handle; cp.page = 0x01; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, - sizeof(cp), &cp); + sizeof(cp), &cp); goto unlock; } @@ -2153,17 +2162,20 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_remote_version_evt(struct hci_dev *hdev, + struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_cmd_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_cmd_complete *ev = (void *) skb->data; __u16 opcode; @@ -2465,7 +2477,8 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) } } -static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_role_change_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_role_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2491,7 +2504,8 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb hci_dev_unlock(hdev); } -static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_num_comp_pkts *ev = (void *) skb->data; int i; @@ -2502,7 +2516,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s } if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + - ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { + ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { BT_DBG("%s bad parameters", hdev->name); return; } @@ -2569,13 +2583,13 @@ static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, } if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + - ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { + ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { BT_DBG("%s bad parameters", hdev->name); return; } BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, - ev->num_hndl); + ev->num_hndl); for (i = 0; i < ev->num_hndl; i++) { struct hci_comp_blocks_info *info = &ev->handles[i]; @@ -2607,7 +2621,8 @@ static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, queue_work(hdev->workqueue, &hdev->tx_work); } -static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_mode_change_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_mode_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2635,7 +2650,8 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb hci_dev_unlock(hdev); } -static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_pin_code_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_pin_code_req *ev = (void *) skb->data; struct hci_conn *conn; @@ -2656,7 +2672,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, - sizeof(ev->bdaddr), &ev->bdaddr); + sizeof(ev->bdaddr), &ev->bdaddr); else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { u8 secure; @@ -2672,7 +2688,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_link_key_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_link_key_req *ev = (void *) skb->data; struct hci_cp_link_key_reply cp; @@ -2689,15 +2706,15 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff key = hci_find_link_key(hdev, &ev->bdaddr); if (!key) { BT_DBG("%s link key not found for %s", hdev->name, - batostr(&ev->bdaddr)); + batostr(&ev->bdaddr)); goto not_found; } BT_DBG("%s found key type %u for %s", hdev->name, key->type, - batostr(&ev->bdaddr)); + batostr(&ev->bdaddr)); if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && - key->type == HCI_LK_DEBUG_COMBINATION) { + key->type == HCI_LK_DEBUG_COMBINATION) { BT_DBG("%s ignoring debug key", hdev->name); goto not_found; } @@ -2705,16 +2722,15 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); if (conn) { if (key->type == HCI_LK_UNAUTH_COMBINATION && - conn->auth_type != 0xff && - (conn->auth_type & 0x01)) { + conn->auth_type != 0xff && (conn->auth_type & 0x01)) { BT_DBG("%s ignoring unauthenticated key", hdev->name); goto not_found; } if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && - conn->pending_sec_level == BT_SECURITY_HIGH) { + conn->pending_sec_level == BT_SECURITY_HIGH) { BT_DBG("%s ignoring key unauthenticated for high \ - security", hdev->name); + security", hdev->name); goto not_found; } @@ -2736,7 +2752,8 @@ not_found: hci_dev_unlock(hdev); } -static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_link_key_notify_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_link_key_notify *ev = (void *) skb->data; struct hci_conn *conn; @@ -2760,12 +2777,13 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, - ev->key_type, pin_len); + ev->key_type, pin_len); hci_dev_unlock(hdev); } -static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_clock_offset_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_clock_offset *ev = (void *) skb->data; struct hci_conn *conn; @@ -2788,7 +2806,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk hci_dev_unlock(hdev); } -static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_pkt_type_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2804,7 +2823,8 @@ static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff hci_dev_unlock(hdev); } -static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; struct inquiry_entry *ie; @@ -2822,7 +2842,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff * hci_dev_unlock(hdev); } -static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct inquiry_data data; int num_rsp = *((__u8 *) skb->data); @@ -2881,7 +2902,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct hci_dev_unlock(hdev); } -static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_ext_features *ev = (void *) skb->data; struct hci_conn *conn; @@ -2929,7 +2951,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_sync_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -2984,19 +3007,22 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, + struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_sniff_subrate *ev = (void *) skb->data; BT_DBG("%s status %d", hdev->name, ev->status); } -static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct inquiry_data data; struct extended_inquiry_info *info = (void *) (skb->data + 1); @@ -3062,7 +3088,8 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn) return conn->auth_type; } -static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_io_capa_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_io_capa_request *ev = (void *) skb->data; struct hci_conn *conn; @@ -3081,7 +3108,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff goto unlock; if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || - (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { + (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { struct hci_cp_io_capability_reply cp; bacpy(&cp.bdaddr, &ev->bdaddr); @@ -3093,13 +3120,13 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff cp.authentication = conn->auth_type; if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) && - hci_find_remote_oob_data(hdev, &conn->dst)) + hci_find_remote_oob_data(hdev, &conn->dst)) cp.oob_data = 0x01; else cp.oob_data = 0x00; hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, - sizeof(cp), &cp); + sizeof(cp), &cp); } else { struct hci_cp_io_capability_neg_reply cp; @@ -3107,14 +3134,15 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, - sizeof(cp), &cp); + sizeof(cp), &cp); } unlock: hci_dev_unlock(hdev); } -static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_io_capa_reply *ev = (void *) skb->data; struct hci_conn *conn; @@ -3137,7 +3165,7 @@ unlock: } static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_ev_user_confirm_req *ev = (void *) skb->data; int loc_mitm, rem_mitm, confirm_hint = 0; @@ -3165,13 +3193,13 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) { BT_DBG("Rejecting request: remote device can't provide MITM"); hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, - sizeof(ev->bdaddr), &ev->bdaddr); + sizeof(ev->bdaddr), &ev->bdaddr); goto unlock; } /* If no side requires MITM protection; auto-accept */ if ((!loc_mitm || conn->remote_cap == 0x03) && - (!rem_mitm || conn->io_capability == 0x03)) { + (!rem_mitm || conn->io_capability == 0x03)) { /* If we're not the initiators request authorization to * proceed from user space (mgmt_user_confirm with @@ -3183,7 +3211,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, } BT_DBG("Auto-accept of user confirmation with %ums delay", - hdev->auto_accept_delay); + hdev->auto_accept_delay); if (hdev->auto_accept_delay > 0) { int delay = msecs_to_jiffies(hdev->auto_accept_delay); @@ -3192,7 +3220,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, } hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, - sizeof(ev->bdaddr), &ev->bdaddr); + sizeof(ev->bdaddr), &ev->bdaddr); goto unlock; } @@ -3205,7 +3233,7 @@ unlock: } static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_ev_user_passkey_req *ev = (void *) skb->data; @@ -3219,7 +3247,8 @@ static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_simple_pair_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3247,7 +3276,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_remote_host_features_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_host_features *ev = (void *) skb->data; struct inquiry_entry *ie; @@ -3285,20 +3315,21 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), - &cp); + &cp); } else { struct hci_cp_remote_oob_data_neg_reply cp; bacpy(&cp.bdaddr, &ev->bdaddr); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp), - &cp); + &cp); } unlock: hci_dev_unlock(hdev); } -static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_le_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3321,7 +3352,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff if (ev->status) { mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, - conn->dst_type, ev->status); + conn->dst_type, ev->status); hci_proto_connect_cfm(conn, ev->status); conn->state = BT_CLOSED; hci_conn_del(conn); @@ -3346,7 +3377,7 @@ unlock: } static inline void hci_le_adv_report_evt(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { u8 num_reports = skb->data[0]; void *ptr = &skb->data[1]; @@ -3368,7 +3399,7 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, } static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_ev_le_ltk_req *ev = (void *) skb->data; struct hci_cp_le_ltk_reply cp; -- GitLab From 5974e4c469658696e6e0ce8951a59a61b122415a Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:25 -0300 Subject: [PATCH 0265/6849] Bluetooth: Fix coding style in hci_conn.c Follow net subsystem rules. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_conn.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3f18a6ed9731..971601e0ad4a 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -185,7 +185,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) } void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, - u16 latency, u16 to_multiplier) + u16 latency, u16 to_multiplier) { struct hci_cp_le_conn_update cp; struct hci_dev *hdev = conn->hdev; @@ -205,7 +205,7 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, EXPORT_SYMBOL(hci_le_conn_update); void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], - __u8 ltk[16]) + __u8 ltk[16]) { struct hci_dev *hdev = conn->hdev; struct hci_cp_le_start_enc cp; @@ -247,7 +247,7 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) static void hci_conn_timeout(struct work_struct *work) { struct hci_conn *conn = container_of(work, struct hci_conn, - disc_work.work); + disc_work.work); __u8 reason; BT_DBG("conn %p state %s", conn, state_to_string(conn->state)); @@ -327,7 +327,7 @@ static void hci_conn_auto_accept(unsigned long arg) struct hci_dev *hdev = conn->hdev; hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), - &conn->dst); + &conn->dst); } struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) @@ -376,7 +376,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, - (unsigned long) conn); + (unsigned long) conn); atomic_set(&conn->refcnt, 0); @@ -545,7 +545,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, hci_conn_hold(sco); if (acl->state == BT_CONNECTED && - (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { + (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { set_bit(HCI_CONN_POWER_SAVE, &acl->flags); hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON); @@ -600,7 +600,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) cp.handle = cpu_to_le16(conn->handle); hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); + sizeof(cp), &cp); if (conn->key_type != 0xff) set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); } @@ -618,7 +618,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) cp.handle = cpu_to_le16(conn->handle); cp.encrypt = 0x01; hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), - &cp); + &cp); } } @@ -648,8 +648,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) /* An unauthenticated combination key has sufficient security for security level 1 and 2. */ if (conn->key_type == HCI_LK_UNAUTH_COMBINATION && - (sec_level == BT_SECURITY_MEDIUM || - sec_level == BT_SECURITY_LOW)) + (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) goto encrypt; /* A combination key has always sufficient security for the security @@ -657,8 +656,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) is generated using maximum PIN code length (16). For pre 2.1 units. */ if (conn->key_type == HCI_LK_COMBINATION && - (sec_level != BT_SECURITY_HIGH || - conn->pin_length == 16)) + (sec_level != BT_SECURITY_HIGH || conn->pin_length == 16)) goto encrypt; auth: @@ -701,7 +699,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) struct hci_cp_change_conn_link_key cp; cp.handle = cpu_to_le16(conn->handle); hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, - sizeof(cp), &cp); + sizeof(cp), &cp); } return 0; @@ -752,7 +750,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) timer: if (hdev->idle_timeout > 0) mod_timer(&conn->idle_timer, - jiffies + msecs_to_jiffies(hdev->idle_timeout)); + jiffies + msecs_to_jiffies(hdev->idle_timeout)); } /* Drop all connection on the device */ -- GitLab From a8c5fb1afe0b2661a8be78e340f86e6a627f9b32 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 17 May 2012 00:36:26 -0300 Subject: [PATCH 0266/6849] Bluetooth: Fix coding style in hci_core.c Follow net subsystem rules. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 103 ++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 411ace8e647b..d0a960dabd53 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -124,8 +124,9 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) } /* Execute request and wait for completion. */ -static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), - unsigned long opt, __u32 timeout) +static int __hci_request(struct hci_dev *hdev, + void (*req)(struct hci_dev *hdev, unsigned long opt), + unsigned long opt, __u32 timeout) { DECLARE_WAITQUEUE(wait, current); int err = 0; @@ -417,7 +418,8 @@ static void inquiry_cache_flush(struct hci_dev *hdev) INIT_LIST_HEAD(&cache->resolve); } -struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) +struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, + bdaddr_t *bdaddr) { struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; @@ -478,7 +480,7 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, list_for_each_entry(p, &cache->resolve, list) { if (p->name_state != NAME_PENDING && - abs(p->data.rssi) >= abs(ie->data.rssi)) + abs(p->data.rssi) >= abs(ie->data.rssi)) break; pos = &p->list; } @@ -503,7 +505,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, *ssp = true; if (ie->name_state == NAME_NEEDED && - data->rssi != ie->data.rssi) { + data->rssi != ie->data.rssi) { ie->data.rssi = data->rssi; hci_inquiry_cache_update_resolve(hdev, ie); } @@ -527,7 +529,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, update: if (name_known && ie->name_state != NAME_KNOWN && - ie->name_state != NAME_PENDING) { + ie->name_state != NAME_PENDING) { ie->name_state = NAME_KNOWN; list_del(&ie->list); } @@ -605,8 +607,7 @@ int hci_inquiry(void __user *arg) hci_dev_lock(hdev); if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || - inquiry_cache_empty(hdev) || - ir.flags & IREQ_CACHE_FLUSH) { + inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { inquiry_cache_flush(hdev); do_inquiry = 1; } @@ -641,7 +642,7 @@ int hci_inquiry(void __user *arg) if (!copy_to_user(ptr, &ir, sizeof(ir))) { ptr += sizeof(ir); if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * - ir.num_rsp)) + ir.num_rsp)) err = -EFAULT; } else err = -EFAULT; @@ -702,11 +703,11 @@ int hci_dev_open(__u16 dev) hdev->init_last_cmd = 0; ret = __hci_request(hdev, hci_init_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); if (lmp_host_le_capable(hdev)) ret = __hci_request(hdev, hci_le_init_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); clear_bit(HCI_INIT, &hdev->flags); } @@ -791,10 +792,10 @@ static int hci_dev_do_close(struct hci_dev *hdev) skb_queue_purge(&hdev->cmd_q); atomic_set(&hdev->cmd_cnt, 1); if (!test_bit(HCI_RAW, &hdev->flags) && - test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { + test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { set_bit(HCI_INIT, &hdev->flags); __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(250)); + msecs_to_jiffies(250)); clear_bit(HCI_INIT, &hdev->flags); } @@ -884,7 +885,7 @@ int hci_dev_reset(__u16 dev) if (!test_bit(HCI_RAW, &hdev->flags)) ret = __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); done: hci_req_unlock(hdev); @@ -924,7 +925,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) switch (cmd) { case HCISETAUTH: err = hci_request(hdev, hci_auth_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETENCRYPT: @@ -936,23 +937,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) if (!test_bit(HCI_AUTH, &hdev->flags)) { /* Auth must be enabled first */ err = hci_request(hdev, hci_auth_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); if (err) break; } err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETSCAN: err = hci_request(hdev, hci_scan_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETLINKPOL: err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETLINKMODE: @@ -1103,7 +1104,7 @@ static void hci_power_on(struct work_struct *work) if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) schedule_delayed_work(&hdev->power_off, - msecs_to_jiffies(AUTO_OFF_TIMEOUT)); + msecs_to_jiffies(AUTO_OFF_TIMEOUT)); if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) mgmt_index_added(hdev); @@ -1112,7 +1113,7 @@ static void hci_power_on(struct work_struct *work) static void hci_power_off(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, - power_off.work); + power_off.work); BT_DBG("%s", hdev->name); @@ -1193,7 +1194,7 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) } static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, - u8 key_type, u8 old_key_type) + u8 key_type, u8 old_key_type) { /* Legacy key */ if (key_type < 0x03) @@ -1234,7 +1235,7 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) list_for_each_entry(k, &hdev->long_term_keys, list) { if (k->ediv != ediv || - memcmp(rand, k->rand, sizeof(k->rand))) + memcmp(rand, k->rand, sizeof(k->rand))) continue; return k; @@ -1251,7 +1252,7 @@ struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, list_for_each_entry(k, &hdev->long_term_keys, list) if (addr_type == k->bdaddr_type && - bacmp(bdaddr, &k->bdaddr) == 0) + bacmp(bdaddr, &k->bdaddr) == 0) return k; return NULL; @@ -1283,8 +1284,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, * combination key for legacy pairing even when there's no * previous key */ if (type == HCI_LK_CHANGED_COMBINATION && - (!conn || conn->remote_auth == 0xff) && - old_key_type == 0xff) { + (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { type = HCI_LK_COMBINATION; if (conn) conn->key_type = type; @@ -1741,7 +1741,7 @@ int hci_register_dev(struct hci_dev *hdev) write_unlock(&hci_dev_list_lock); hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | - WQ_MEM_RECLAIM, 1); + WQ_MEM_RECLAIM, 1); if (!hdev->workqueue) { error = -ENOMEM; goto err; @@ -1752,7 +1752,8 @@ int hci_register_dev(struct hci_dev *hdev) goto err_wqueue; hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, - RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); + RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, + hdev); if (hdev->rfkill) { if (rfkill_register(hdev->rfkill) < 0) { rfkill_destroy(hdev->rfkill); @@ -1799,7 +1800,7 @@ void hci_unregister_dev(struct hci_dev *hdev) kfree_skb(hdev->reassembly[i]); if (!test_bit(HCI_INIT, &hdev->flags) && - !test_bit(HCI_SETUP, &hdev->dev_flags)) { + !test_bit(HCI_SETUP, &hdev->dev_flags)) { hci_dev_lock(hdev); mgmt_index_removed(hdev); hci_dev_unlock(hdev); @@ -1853,7 +1854,7 @@ int hci_recv_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; if (!hdev || (!test_bit(HCI_UP, &hdev->flags) - && !test_bit(HCI_INIT, &hdev->flags))) { + && !test_bit(HCI_INIT, &hdev->flags))) { kfree_skb(skb); return -ENXIO; } @@ -1872,7 +1873,7 @@ int hci_recv_frame(struct sk_buff *skb) EXPORT_SYMBOL(hci_recv_frame); static int hci_reassembly(struct hci_dev *hdev, int type, void *data, - int count, __u8 index) + int count, __u8 index) { int len = 0; int hlen = 0; @@ -1881,7 +1882,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data, struct bt_skb_cb *scb; if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || - index >= NUM_REASSEMBLY) + index >= NUM_REASSEMBLY) return -EILSEQ; skb = hdev->reassembly[index]; @@ -2023,7 +2024,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) type = bt_cb(skb)->pkt_type; rem = hci_reassembly(hdev, type, data, count, - STREAM_REASSEMBLY); + STREAM_REASSEMBLY); if (rem < 0) return rem; @@ -2157,7 +2158,7 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) } static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, - struct sk_buff *skb, __u16 flags) + struct sk_buff *skb, __u16 flags) { struct hci_dev *hdev = conn->hdev; struct sk_buff *list; @@ -2244,7 +2245,8 @@ EXPORT_SYMBOL(hci_send_sco); /* ---- HCI TX task (outgoing data) ---- */ /* HCI Connection scheduler */ -static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) +static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, + int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL, *c; @@ -2316,7 +2318,7 @@ static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) list_for_each_entry_rcu(c, &h->list, list) { if (c->type == type && c->sent) { BT_ERR("%s killing stalled connection %s", - hdev->name, batostr(&c->dst)); + hdev->name, batostr(&c->dst)); hci_acl_disconn(c, 0x13); } } @@ -2325,7 +2327,7 @@ static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) } static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, - int *quote) + int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_chan *chan = NULL; @@ -2442,7 +2444,7 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) skb->priority = HCI_PRIO_MAX - 1; BT_DBG("chan %p skb %p promoted to %d", chan, skb, - skb->priority); + skb->priority); } if (hci_conn_num(hdev, type) == num) @@ -2465,7 +2467,7 @@ static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) /* ACL tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ if (!cnt && time_after(jiffies, hdev->acl_last_tx + - msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) + msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) hci_link_tx_to(hdev, ACL_LINK); } } @@ -2480,11 +2482,11 @@ static inline void hci_sched_acl_pkt(struct hci_dev *hdev) __check_timeout(hdev, cnt); while (hdev->acl_cnt && - (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { + (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { BT_DBG("chan %p skb %p len %d priority %u", chan, skb, - skb->len, skb->priority); + skb->len, skb->priority); /* Stop if priority has changed */ if (skb->priority < priority) @@ -2518,13 +2520,13 @@ static inline void hci_sched_acl_blk(struct hci_dev *hdev) __check_timeout(hdev, cnt); while (hdev->block_cnt > 0 && - (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { + (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote > 0 && (skb = skb_peek(&chan->data_q))) { int blocks; BT_DBG("chan %p skb %p len %d priority %u", chan, skb, - skb->len, skb->priority); + skb->len, skb->priority); /* Stop if priority has changed */ if (skb->priority < priority) @@ -2537,7 +2539,7 @@ static inline void hci_sched_acl_blk(struct hci_dev *hdev) return; hci_conn_enter_active_mode(chan->conn, - bt_cb(skb)->force_active); + bt_cb(skb)->force_active); hci_send_frame(skb); hdev->acl_last_tx = jiffies; @@ -2634,7 +2636,7 @@ static inline void hci_sched_le(struct hci_dev *hdev) /* LE tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ if (!hdev->le_cnt && hdev->le_pkts && - time_after(jiffies, hdev->le_last_tx + HZ * 45)) + time_after(jiffies, hdev->le_last_tx + HZ * 45)) hci_link_tx_to(hdev, LE_LINK); } @@ -2644,7 +2646,7 @@ static inline void hci_sched_le(struct hci_dev *hdev) u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { BT_DBG("chan %p skb %p len %d priority %u", chan, skb, - skb->len, skb->priority); + skb->len, skb->priority); /* Stop if priority has changed */ if (skb->priority < priority) @@ -2676,7 +2678,7 @@ static void hci_tx_work(struct work_struct *work) struct sk_buff *skb; BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, - hdev->sco_cnt, hdev->le_cnt); + hdev->sco_cnt, hdev->le_cnt); /* Schedule queues and send stuff to HCI driver */ @@ -2708,7 +2710,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) flags = hci_flags(handle); handle = hci_handle(handle); - BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); + BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, + handle, flags); hdev->stat.acl_rx++; @@ -2732,7 +2735,7 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) return; } else { BT_ERR("%s ACL packet for unknown connection handle %d", - hdev->name, handle); + hdev->name, handle); } kfree_skb(skb); @@ -2763,7 +2766,7 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) return; } else { BT_ERR("%s SCO packet for unknown connection handle %d", - hdev->name, handle); + hdev->name, handle); } kfree_skb(skb); -- GitLab From 9dc9affcb776b75f6d3e5d69d6e2a679407854f1 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 16:20:14 -0700 Subject: [PATCH 0267/6849] Bluetooth: Free allocated ERTM SREJ list if init fails If the ERTM SREJ list is properly allocated but the retransmit list allocation fails, the SREJ list must be freed before returning from l2cap_ertm_init. l2cap_chan_del will not clean up the SREJ list if l2cap_ertm_init returns a failure code. Signed-off-by: Mat Martineau Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 24f144b72a96..078bf805cd97 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2381,7 +2381,11 @@ static inline int l2cap_ertm_init(struct l2cap_chan *chan) if (err < 0) return err; - return l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win); + err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win); + if (err < 0) + l2cap_seq_list_free(&chan->srej_list); + + return err; } static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) -- GitLab From 2827011f666e157f3307d55070a75e1d1110b194 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 21:14:09 -0700 Subject: [PATCH 0268/6849] Bluetooth: Fix early return from l2cap_chan_del This fixes a regression from commit 2ead70b8390d199ca04cd35311b51f5f3676079e that is present in all kernels starting at v3.0. When L2CAP information was moved to struct l2cap_chan, a check was added to l2cap_chan_del to avoid certain cleanup operations when ERTM or streaming mode had not yet been initialized. The logic in the check did not take in to account that chan->conf_state is set to 0 in l2cap_chan_ready, so l2cap_chan_del failed to cancel timers and leaked memory any time the ERTM queues or lists were not empty. This change makes sure that l2cap_chan_del only returns early if ERTM initialization was not performed. Signed-off-by: Mat Martineau Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1c7d1cd5e679..452fcc4c0fff 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -597,6 +597,7 @@ enum { CONF_EWS_RECV, CONF_LOC_CONF_PEND, CONF_REM_CONF_PEND, + CONF_NOT_COMPLETE, }; #define L2CAP_CONF_MAX_CONF_REQ 2 diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 078bf805cd97..d9f215f3f8e9 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -392,6 +392,9 @@ struct l2cap_chan *l2cap_chan_create(void) atomic_set(&chan->refcnt, 1); + /* This flag is cleared in l2cap_chan_ready() */ + set_bit(CONF_NOT_COMPLETE, &chan->conf_state); + BT_DBG("chan %p", chan); return chan; @@ -509,8 +512,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) release_sock(sk); - if (!(test_bit(CONF_OUTPUT_DONE, &chan->conf_state) && - test_bit(CONF_INPUT_DONE, &chan->conf_state))) + if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) return; skb_queue_purge(&chan->tx_q); @@ -923,6 +925,7 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) BT_DBG("sk %p, parent %p", sk, parent); + /* This clears all conf flags, including CONF_NOT_COMPLETE */ chan->conf_state = 0; __clear_chan_timer(chan); -- GitLab From b191e031b744f16116e9a546e36b13aadb8cba00 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:31 -0700 Subject: [PATCH 0269/6849] Bluetooth: Change default state of ERTM disable flag This is to allow for ERTM state machine replacement in the patches that follow. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d9f215f3f8e9..474ad7abadda 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -57,7 +57,7 @@ #include #include -bool disable_ertm; +bool disable_ertm = 1; static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, }; -- GitLab From 608bcc6d70850be9e3aa7c3831045304a2a65fbb Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:32 -0700 Subject: [PATCH 0270/6849] Bluetooth: Add a new L2CAP ERTM transmit state machine. This implements a top-level transmit state machine with handlers for the two ERTM states defined in the specification: XMIT and WAIT_F. The state machine accepts an event and, optionally, a list of skbs to transmit. In addition to data transmission, the local busy state can be modified, acks are processed, and monitor and retransmit timeouts are handled. This mirrors the structure of the state tables in the spec. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 254 +++++++++++++++++++++++++++++++++++-- 1 file changed, 246 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 474ad7abadda..c5232d25da52 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -73,6 +73,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); +static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event); + /* ---- L2CAP channels ---- */ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) @@ -224,6 +227,19 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) release_sock(sk); } +static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head, + u16 seq) +{ + struct sk_buff *skb; + + skb_queue_walk(head, skb) { + if (bt_cb(skb)->control.txseq == seq) + return skb; + } + + return NULL; +} + /* ---- L2CAP sequence number lists ---- */ /* For ERTM, ordered lists of sequence numbers must be tracked for @@ -2120,16 +2136,15 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, if (err) break; - if (chan->mode == L2CAP_MODE_ERTM && chan->tx_send_head == NULL) - chan->tx_send_head = seg_queue.next; - skb_queue_splice_tail_init(&seg_queue, &chan->tx_q); - - if (chan->mode == L2CAP_MODE_ERTM) - err = l2cap_ertm_send(chan); - else + if (chan->mode == L2CAP_MODE_ERTM) { + err = l2cap_tx(chan, 0, &seg_queue, + L2CAP_EV_DATA_REQUEST); + } else { + skb_queue_splice_tail_init(&seg_queue, &chan->tx_q); l2cap_streaming_send(chan); + } - if (err >= 0) + if (!err) err = len; /* If the skbs were not queued for sending, they'll still be in @@ -2146,6 +2161,229 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, return err; } +static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) +{ + struct sk_buff *acked_skb; + u16 ackseq; + + BT_DBG("chan %p, reqseq %d", chan, reqseq); + + if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) + return; + + BT_DBG("expected_ack_seq %d, unacked_frames %d", + chan->expected_ack_seq, chan->unacked_frames); + + for (ackseq = chan->expected_ack_seq; ackseq != reqseq; + ackseq = __next_seq(chan, ackseq)) { + + acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq); + if (acked_skb) { + skb_unlink(acked_skb, &chan->tx_q); + kfree_skb(acked_skb); + chan->unacked_frames--; + } + } + + chan->expected_ack_seq = reqseq; + + if (chan->unacked_frames == 0) + __clear_retrans_timer(chan); + + BT_DBG("unacked_frames %d", (int) chan->unacked_frames); +} + +static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) +{ + BT_DBG("chan %p", chan); + + chan->expected_tx_seq = chan->buffer_seq; + l2cap_seq_list_clear(&chan->srej_list); + skb_queue_purge(&chan->srej_q); + chan->rx_state = L2CAP_RX_STATE_RECV; +} + +static int l2cap_tx_state_xmit(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event) +{ + int err = 0; + + BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + event); + + switch (event) { + case L2CAP_EV_DATA_REQUEST: + if (chan->tx_send_head == NULL) + chan->tx_send_head = skb_peek(skbs); + + skb_queue_splice_tail_init(skbs, &chan->tx_q); + l2cap_ertm_send(chan); + break; + case L2CAP_EV_LOCAL_BUSY_DETECTED: + BT_DBG("Enter LOCAL_BUSY"); + set_bit(CONN_LOCAL_BUSY, &chan->conn_state); + + if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { + /* The SREJ_SENT state must be aborted if we are to + * enter the LOCAL_BUSY state. + */ + l2cap_abort_rx_srej_sent(chan); + } + + l2cap_send_ack(chan); + + break; + case L2CAP_EV_LOCAL_BUSY_CLEAR: + BT_DBG("Exit LOCAL_BUSY"); + clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); + + if (test_bit(CONN_RNR_SENT, &chan->conn_state)) { + struct l2cap_ctrl local_control; + + memset(&local_control, 0, sizeof(local_control)); + local_control.sframe = 1; + local_control.super = L2CAP_SUPER_RR; + local_control.poll = 1; + local_control.reqseq = chan->buffer_seq; + l2cap_send_sframe(chan, 0); + + chan->retry_count = 1; + __set_monitor_timer(chan); + chan->tx_state = L2CAP_TX_STATE_WAIT_F; + } + break; + case L2CAP_EV_RECV_REQSEQ_AND_FBIT: + l2cap_process_reqseq(chan, control->reqseq); + break; + case L2CAP_EV_EXPLICIT_POLL: + l2cap_send_rr_or_rnr(chan, 1); + chan->retry_count = 1; + __set_monitor_timer(chan); + __clear_ack_timer(chan); + chan->tx_state = L2CAP_TX_STATE_WAIT_F; + break; + case L2CAP_EV_RETRANS_TO: + l2cap_send_rr_or_rnr(chan, 1); + chan->retry_count = 1; + __set_monitor_timer(chan); + chan->tx_state = L2CAP_TX_STATE_WAIT_F; + break; + case L2CAP_EV_RECV_FBIT: + /* Nothing to process */ + break; + default: + break; + } + + return err; +} + +static int l2cap_tx_state_wait_f(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event) +{ + int err = 0; + + BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + event); + + switch (event) { + case L2CAP_EV_DATA_REQUEST: + if (chan->tx_send_head == NULL) + chan->tx_send_head = skb_peek(skbs); + /* Queue data, but don't send. */ + skb_queue_splice_tail_init(skbs, &chan->tx_q); + break; + case L2CAP_EV_LOCAL_BUSY_DETECTED: + BT_DBG("Enter LOCAL_BUSY"); + set_bit(CONN_LOCAL_BUSY, &chan->conn_state); + + if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { + /* The SREJ_SENT state must be aborted if we are to + * enter the LOCAL_BUSY state. + */ + l2cap_abort_rx_srej_sent(chan); + } + + l2cap_send_ack(chan); + + break; + case L2CAP_EV_LOCAL_BUSY_CLEAR: + BT_DBG("Exit LOCAL_BUSY"); + clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); + + if (test_bit(CONN_RNR_SENT, &chan->conn_state)) { + struct l2cap_ctrl local_control; + memset(&local_control, 0, sizeof(local_control)); + local_control.sframe = 1; + local_control.super = L2CAP_SUPER_RR; + local_control.poll = 1; + local_control.reqseq = chan->buffer_seq; + l2cap_send_sframe(chan, 0); + + chan->retry_count = 1; + __set_monitor_timer(chan); + chan->tx_state = L2CAP_TX_STATE_WAIT_F; + } + break; + case L2CAP_EV_RECV_REQSEQ_AND_FBIT: + l2cap_process_reqseq(chan, control->reqseq); + + /* Fall through */ + + case L2CAP_EV_RECV_FBIT: + if (control && control->final) { + __clear_monitor_timer(chan); + if (chan->unacked_frames > 0) + __set_retrans_timer(chan); + chan->retry_count = 0; + chan->tx_state = L2CAP_TX_STATE_XMIT; + BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state); + } + break; + case L2CAP_EV_EXPLICIT_POLL: + /* Ignore */ + break; + case L2CAP_EV_MONITOR_TO: + if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) { + l2cap_send_rr_or_rnr(chan, 1); + __set_monitor_timer(chan); + chan->retry_count++; + } else { + l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); + } + break; + default: + break; + } + + return err; +} + +static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event) +{ + int err = 0; + + BT_DBG("chan %p, control %p, skbs %p, event %d, state %d", + chan, control, skbs, event, chan->tx_state); + + switch (chan->tx_state) { + case L2CAP_TX_STATE_XMIT: + err = l2cap_tx_state_xmit(chan, control, skbs, event); + break; + case L2CAP_TX_STATE_WAIT_F: + err = l2cap_tx_state_wait_f(chan, control, skbs, event); + break; + default: + /* Ignore event */ + break; + } + + return err; +} + /* Copy frame to all raw sockets on that connection */ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { -- GitLab From 3733937d96f3fe4dfc3b8da43385d739e905ff41 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:33 -0700 Subject: [PATCH 0271/6849] Bluetooth: Refactor l2cap_streaming_send This new implementation uses struct l2cap_ctrl to compose the streaming mode headers. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 48 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c5232d25da52..25edccff4c94 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1650,29 +1650,45 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) __clear_retrans_timer(chan); } -static void l2cap_streaming_send(struct l2cap_chan *chan) +static int l2cap_streaming_send(struct l2cap_chan *chan, + struct sk_buff_head *skbs) { struct sk_buff *skb; - u32 control; - u16 fcs; + struct l2cap_ctrl *control; - while ((skb = skb_dequeue(&chan->tx_q))) { - control = __get_control(chan, skb->data + L2CAP_HDR_SIZE); - control |= __set_txseq(chan, chan->next_tx_seq); - control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar); - __put_control(chan, control, skb->data + L2CAP_HDR_SIZE); + BT_DBG("chan %p, skbs %p", chan, skbs); + + if (chan->state != BT_CONNECTED) + return -ENOTCONN; + + skb_queue_splice_tail_init(skbs, &chan->tx_q); + + while (!skb_queue_empty(&chan->tx_q)) { + + skb = skb_dequeue(&chan->tx_q); + + bt_cb(skb)->control.retries = 1; + control = &bt_cb(skb)->control; + + control->reqseq = 0; + control->txseq = chan->next_tx_seq; + + __pack_control(chan, control, skb); if (chan->fcs == L2CAP_FCS_CRC16) { - fcs = crc16(0, (u8 *)skb->data, - skb->len - L2CAP_FCS_SIZE); - put_unaligned_le16(fcs, - skb->data + skb->len - L2CAP_FCS_SIZE); + u16 fcs = crc16(0, (u8 *) skb->data, skb->len); + put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); } l2cap_do_send(chan, skb); + BT_DBG("Sent txseq %d", (int)control->txseq); + chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); + chan->frames_sent++; } + + return 0; } static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq) @@ -2136,13 +2152,11 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, if (err) break; - if (chan->mode == L2CAP_MODE_ERTM) { + if (chan->mode == L2CAP_MODE_ERTM) err = l2cap_tx(chan, 0, &seg_queue, L2CAP_EV_DATA_REQUEST); - } else { - skb_queue_splice_tail_init(&seg_queue, &chan->tx_q); - l2cap_streaming_send(chan); - } + else + err = l2cap_streaming_send(chan, &seg_queue); if (!err) err = len; -- GitLab From 18a48e76640c590a14b0286c9da5fde6ac146cc2 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:34 -0700 Subject: [PATCH 0272/6849] Bluetooth: Refactor l2cap_ertm_send The new implementation is aware of the new transmit state machine, and uses struct l2cap_ctrl to compose ERTM headers. It also has improved error handling for allocation failures, and does not send the packet until after all skb and channel data structures are updated. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 79 +++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 25edccff4c94..429a67ea47d0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1741,9 +1741,10 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq) static int l2cap_ertm_send(struct l2cap_chan *chan) { struct sk_buff *skb, *tx_skb; - u16 fcs; - u32 control; - int nsent = 0; + struct l2cap_ctrl *control; + int sent = 0; + + BT_DBG("chan %p", chan); if (chan->state != BT_CONNECTED) return -ENOTCONN; @@ -1751,61 +1752,57 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return 0; - while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) { - - if (bt_cb(skb)->control.retries == chan->remote_max_tx && - chan->remote_max_tx) { - l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); - break; - } + while (chan->tx_send_head && + chan->unacked_frames < chan->remote_tx_win && + chan->tx_state == L2CAP_TX_STATE_XMIT) { - tx_skb = skb_clone(skb, GFP_ATOMIC); + skb = chan->tx_send_head; - bt_cb(skb)->control.retries++; - - control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); - control &= __get_sar_mask(chan); + bt_cb(skb)->control.retries = 1; + control = &bt_cb(skb)->control; if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) - control |= __set_ctrl_final(chan); + control->final = 1; - control |= __set_reqseq(chan, chan->buffer_seq); - control |= __set_txseq(chan, chan->next_tx_seq); - control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar); + control->reqseq = chan->buffer_seq; + chan->last_acked_seq = chan->buffer_seq; + control->txseq = chan->next_tx_seq; - __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); + __pack_control(chan, control, skb); if (chan->fcs == L2CAP_FCS_CRC16) { - fcs = crc16(0, (u8 *)skb->data, - tx_skb->len - L2CAP_FCS_SIZE); - put_unaligned_le16(fcs, skb->data + - tx_skb->len - L2CAP_FCS_SIZE); + u16 fcs = crc16(0, (u8 *) skb->data, skb->len); + put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); } - l2cap_do_send(chan, tx_skb); + /* Clone after data has been modified. Data is assumed to be + read-only (for locking purposes) on cloned sk_buffs. + */ + tx_skb = skb_clone(skb, GFP_KERNEL); - __set_retrans_timer(chan); + if (!tx_skb) + break; - bt_cb(skb)->control.txseq = chan->next_tx_seq; + __set_retrans_timer(chan); chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); - - if (bt_cb(skb)->control.retries == 1) { - chan->unacked_frames++; - - if (!nsent++) - __clear_ack_timer(chan); - } - + chan->unacked_frames++; chan->frames_sent++; + sent++; if (skb_queue_is_last(&chan->tx_q, skb)) chan->tx_send_head = NULL; else chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); + + l2cap_do_send(chan, tx_skb); + BT_DBG("Sent txseq %d", (int)control->txseq); } - return nsent; + BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent, + (int) chan->unacked_frames, skb_queue_len(&chan->tx_q)); + + return sent; } static int l2cap_retransmit_frames(struct l2cap_chan *chan) @@ -2009,7 +2006,11 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, lh->cid = cpu_to_le16(chan->dcid); lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); - __put_control(chan, 0, skb_put(skb, __ctrl_size(chan))); + /* Control header is populated later */ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE)); + else + put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE)); if (sdulen) put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE)); @@ -2020,9 +2021,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, return ERR_PTR(err); } - if (chan->fcs == L2CAP_FCS_CRC16) - put_unaligned_le16(0, skb_put(skb, L2CAP_FCS_SIZE)); - + bt_cb(skb)->control.fcs = chan->fcs; bt_cb(skb)->control.retries = 0; return skb; } -- GitLab From a67d7f6fca776317bb478c96f25196972c05d173 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:35 -0700 Subject: [PATCH 0273/6849] Bluetooth: Refactor l2cap_send_sframe The new implementation uses struct l2cap_ctrl to set up the sframe fields, and also reduces duplicate acks by canceling the ack timer whenever an RR or RNR frame is sent. sframe PDU generation is also split in to a separate function to separate it from the logic related to the connection state and sframe type. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 87 ++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 429a67ea47d0..c7bf613294cc 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -848,15 +848,12 @@ static inline void __pack_control(struct l2cap_chan *chan, } } -static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control) +static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan, + u32 control) { struct sk_buff *skb; struct l2cap_hdr *lh; - struct l2cap_conn *conn = chan->conn; - int count, hlen; - - if (chan->state != BT_CONNECTED) - return; + int hlen; if (test_bit(FLAG_EXT_CTRL, &chan->flags)) hlen = L2CAP_EXT_HDR_SIZE; @@ -866,35 +863,65 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control) if (chan->fcs == L2CAP_FCS_CRC16) hlen += L2CAP_FCS_SIZE; - BT_DBG("chan %p, control 0x%8.8x", chan, control); - - count = min_t(unsigned int, conn->mtu, hlen); - - control |= __set_sframe(chan); - - if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) - control |= __set_ctrl_final(chan); - - if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) - control |= __set_ctrl_poll(chan); + skb = bt_skb_alloc(hlen, GFP_KERNEL); - skb = bt_skb_alloc(count, GFP_ATOMIC); if (!skb) - return; + return ERR_PTR(-ENOMEM); lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); lh->cid = cpu_to_le16(chan->dcid); - __put_control(chan, control, skb_put(skb, __ctrl_size(chan))); + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE)); + else + put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE)); if (chan->fcs == L2CAP_FCS_CRC16) { - u16 fcs = crc16(0, (u8 *)lh, count - L2CAP_FCS_SIZE); + u16 fcs = crc16(0, (u8 *)skb->data, skb->len); put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); } skb->priority = HCI_PRIO_MAX; - l2cap_do_send(chan, skb); + return skb; +} + +static void l2cap_send_sframe(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + struct sk_buff *skb; + u32 control_field; + + BT_DBG("chan %p, control %p", chan, control); + + if (!control->sframe) + return; + + if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) && + !control->poll) + control->final = 1; + + if (control->super == L2CAP_SUPER_RR) + clear_bit(CONN_RNR_SENT, &chan->conn_state); + else if (control->super == L2CAP_SUPER_RNR) + set_bit(CONN_RNR_SENT, &chan->conn_state); + + if (control->super != L2CAP_SUPER_SREJ) { + chan->last_acked_seq = control->reqseq; + __clear_ack_timer(chan); + } + + BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq, + control->final, control->poll, control->super); + + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + control_field = __pack_extended_control(control); + else + control_field = __pack_enhanced_control(control); + + skb = l2cap_create_sframe_pdu(chan, control_field); + if (!IS_ERR(skb)) + l2cap_do_send(chan, skb); } static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control) @@ -906,8 +933,6 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control) control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); control |= __set_reqseq(chan, chan->buffer_seq); - - l2cap_send_sframe(chan, control); } static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) @@ -1826,7 +1851,6 @@ static void __l2cap_send_ack(struct l2cap_chan *chan) if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); set_bit(CONN_RNR_SENT, &chan->conn_state); - l2cap_send_sframe(chan, control); return; } @@ -1834,7 +1858,6 @@ static void __l2cap_send_ack(struct l2cap_chan *chan) return; control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); - l2cap_send_sframe(chan, control); } static void l2cap_send_ack(struct l2cap_chan *chan) @@ -1853,8 +1876,6 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan) tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); control |= __set_reqseq(chan, tail->tx_seq); - - l2cap_send_sframe(chan, control); } static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, @@ -2259,7 +2280,7 @@ static int l2cap_tx_state_xmit(struct l2cap_chan *chan, local_control.super = L2CAP_SUPER_RR; local_control.poll = 1; local_control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, 0); + l2cap_send_sframe(chan, &local_control); chan->retry_count = 1; __set_monitor_timer(chan); @@ -2333,7 +2354,7 @@ static int l2cap_tx_state_wait_f(struct l2cap_chan *chan, local_control.super = L2CAP_SUPER_RR; local_control.poll = 1; local_control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, 0); + l2cap_send_sframe(chan, &local_control); chan->retry_count = 1; __set_monitor_timer(chan); @@ -4233,7 +4254,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); - l2cap_send_sframe(chan, control); set_bit(CONN_RNR_SENT, &chan->conn_state); } @@ -4245,7 +4265,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && chan->frames_sent == 0) { control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); - l2cap_send_sframe(chan, control); } } @@ -4404,7 +4423,6 @@ static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) control = __set_reqseq(chan, chan->buffer_seq); control |= __set_ctrl_poll(chan); control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); - l2cap_send_sframe(chan, control); chan->retry_count = 1; __clear_retrans_timer(chan); @@ -4468,7 +4486,6 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq) } control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); control |= __set_reqseq(chan, l->tx_seq); - l2cap_send_sframe(chan, control); list_del(&l->list); list_add_tail(&l->list, &chan->srej_l); } @@ -4483,7 +4500,6 @@ static int l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq) control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); control |= __set_reqseq(chan, chan->expected_tx_seq); l2cap_seq_list_append(&chan->srej_list, chan->expected_tx_seq); - l2cap_send_sframe(chan, control); new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); if (!new) @@ -4767,7 +4783,6 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u32 rx_c l2cap_send_srejtail(chan); } else { rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR); - l2cap_send_sframe(chan, rx_control); } } -- GitLab From cec8ab6e20a7fbdc056894ff7b3fbdbc2a82a563 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:36 -0700 Subject: [PATCH 0274/6849] Bluetooth: Consolidate common receive code for ERTM and streaming mode Creates a new l2cap_data_rcv function that combines previous code from l2cap_ertm_data_rcv and l2cap_data_channel. This reduces duplicate code for streaming mode, and sets up a framework for the ERTM receive state machine. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 126 ++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c7bf613294cc..a84d33769192 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -791,9 +791,11 @@ static inline void __unpack_control(struct l2cap_chan *chan, if (test_bit(FLAG_EXT_CTRL, &chan->flags)) { __unpack_extended_control(get_unaligned_le32(skb->data), &bt_cb(skb)->control); + skb_pull(skb, L2CAP_EXT_CTRL_SIZE); } else { __unpack_enhanced_control(get_unaligned_le16(skb->data), &bt_cb(skb)->control); + skb_pull(skb, L2CAP_ENH_CTRL_SIZE); } } @@ -4820,27 +4822,39 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_cont return 0; } -static int l2cap_ertm_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) +static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + struct sk_buff *skb, u8 event) { - u32 control; - u16 req_seq; - int len, next_tx_seq_offset, req_seq_offset; + /* Placeholder */ + return -ENOTSUPP; +} + +static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + struct sk_buff *skb) +{ + /* Placeholder */ + return -ENOTSUPP; +} + +static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) +{ + struct l2cap_ctrl *control = &bt_cb(skb)->control; + u16 len; + u8 event; __unpack_control(chan, skb); - control = __get_control(chan, skb->data); - skb_pull(skb, __ctrl_size(chan)); len = skb->len; /* * We can just drop the corrupted I-frame here. * Receiver will miss it and start proper recovery - * procedures and ask retransmission. + * procedures and ask for retransmission. */ if (l2cap_check_fcs(chan, skb)) goto drop; - if (__is_sar_start(chan, control) && !__is_sframe(chan, control)) + if (!control->sframe && control->sar == L2CAP_SAR_START) len -= L2CAP_SDULEN_SIZE; if (chan->fcs == L2CAP_FCS_CRC16) @@ -4851,34 +4865,57 @@ static int l2cap_ertm_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) goto drop; } - req_seq = __get_reqseq(chan, control); - - req_seq_offset = __seq_offset(chan, req_seq, chan->expected_ack_seq); - - next_tx_seq_offset = __seq_offset(chan, chan->next_tx_seq, - chan->expected_ack_seq); + if (!control->sframe) { + int err; - /* check for invalid req-seq */ - if (req_seq_offset > next_tx_seq_offset) { - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - goto drop; - } + BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d", + control->sar, control->reqseq, control->final, + control->txseq); - if (!__is_sframe(chan, control)) { - if (len < 0) { - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + /* Validate F-bit - F=0 always valid, F=1 only + * valid in TX WAIT_F + */ + if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F) goto drop; + + if (chan->mode != L2CAP_MODE_STREAMING) { + event = L2CAP_EV_RECV_IFRAME; + err = l2cap_rx(chan, control, skb, event); + } else { + err = l2cap_stream_rx(chan, control, skb); } - l2cap_data_channel_iframe(chan, control, skb); + if (err) + l2cap_send_disconn_req(chan->conn, chan, + ECONNRESET); } else { + const u8 rx_func_to_event[4] = { + L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ, + L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ + }; + + /* Only I-frames are expected in streaming mode */ + if (chan->mode == L2CAP_MODE_STREAMING) + goto drop; + + BT_DBG("sframe reqseq %d, final %d, poll %d, super %d", + control->reqseq, control->final, control->poll, + control->super); + if (len != 0) { BT_ERR("%d", len); l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); goto drop; } - l2cap_data_channel_sframe(chan, control, skb); + /* Validate F and P bits */ + if (control->final && (control->poll || + chan->tx_state != L2CAP_TX_STATE_WAIT_F)) + goto drop; + + event = rx_func_to_event[control->super]; + if (l2cap_rx(chan, control, skb, event)) + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); } return 0; @@ -4891,9 +4928,6 @@ drop: static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) { struct l2cap_chan *chan; - u32 control; - u16 tx_seq; - int len; chan = l2cap_get_chan_by_scid(conn, cid); if (!chan) { @@ -4923,44 +4957,8 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk break; case L2CAP_MODE_ERTM: - l2cap_ertm_data_rcv(chan, skb); - - goto done; - case L2CAP_MODE_STREAMING: - control = __get_control(chan, skb->data); - skb_pull(skb, __ctrl_size(chan)); - len = skb->len; - - if (l2cap_check_fcs(chan, skb)) - goto drop; - - if (__is_sar_start(chan, control)) - len -= L2CAP_SDULEN_SIZE; - - if (chan->fcs == L2CAP_FCS_CRC16) - len -= L2CAP_FCS_SIZE; - - if (len > chan->mps || len < 0 || __is_sframe(chan, control)) - goto drop; - - tx_seq = __get_txseq(chan, control); - - if (chan->expected_tx_seq != tx_seq) { - /* Frame(s) missing - must discard partial SDU */ - kfree_skb(chan->sdu); - chan->sdu = NULL; - chan->sdu_last_frag = NULL; - chan->sdu_len = 0; - - /* TODO: Notify userland of missing data */ - } - - chan->expected_tx_seq = __next_seq(chan, tx_seq); - - if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - + l2cap_data_rcv(chan, skb); goto done; default: -- GitLab From 4b51dae96731c9d82f5634e75ac7ffd3b9c1b060 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:37 -0700 Subject: [PATCH 0275/6849] Bluetooth: Add streaming mode receive and incoming packet classifier Streaming mode reception is fairly simple, with in-sequence frames being reassembled as they arrive. Out-of-sequence frames are dropped, and also clear any partially-assembled SDUs that may exist. The packet classifier determines if the txseq value of the incoming packet is expected, invalid (resulting in a disconnection), invalid (ignorable), duplicate, or having to do with an SREJ request that was previously sent. The rules for each classification are defined in the ERTM specification, and consolidating these rules in one place helps clarify the receive state machine. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 136 +++++++++++++++++++++++++++++++++++-- 1 file changed, 130 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a84d33769192..0a195ab4a385 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2420,6 +2420,13 @@ static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, return err; } +static void l2cap_pass_to_tx(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + BT_DBG("chan %p, control %p", chan, control); + l2cap_tx(chan, control, 0, L2CAP_EV_RECV_REQSEQ_AND_FBIT); +} + /* Copy frame to all raw sockets on that connection */ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { @@ -4324,11 +4331,12 @@ static void append_skb_frag(struct sk_buff *skb, skb->truesize += new_frag->truesize; } -static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u32 control) +static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, + struct l2cap_ctrl *control) { int err = -EINVAL; - switch (__get_ctrl_sar(chan, control)) { + switch (control->sar) { case L2CAP_SAR_UNSEGMENTED: if (chan->sdu) break; @@ -4463,7 +4471,6 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u16 tx_seq) skb = skb_dequeue(&chan->srej_q); control = __set_ctrl_sar(chan, bt_cb(skb)->control.sar); - err = l2cap_reassemble_sdu(chan, skb, control); if (err < 0) { l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); @@ -4637,7 +4644,6 @@ expected: return 0; } - err = l2cap_reassemble_sdu(chan, skb, rx_control); chan->buffer_seq = __next_seq(chan, chan->buffer_seq); if (err < 0) { @@ -4822,6 +4828,93 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_cont return 0; } +static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) +{ + BT_DBG("chan %p, txseq %d", chan, txseq); + + BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq, + chan->expected_tx_seq); + + if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { + if (__seq_offset(chan, txseq, chan->last_acked_seq) >= + chan->tx_win) { + /* See notes below regarding "double poll" and + * invalid packets. + */ + if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) { + BT_DBG("Invalid/Ignore - after SREJ"); + return L2CAP_TXSEQ_INVALID_IGNORE; + } else { + BT_DBG("Invalid - in window after SREJ sent"); + return L2CAP_TXSEQ_INVALID; + } + } + + if (chan->srej_list.head == txseq) { + BT_DBG("Expected SREJ"); + return L2CAP_TXSEQ_EXPECTED_SREJ; + } + + if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) { + BT_DBG("Duplicate SREJ - txseq already stored"); + return L2CAP_TXSEQ_DUPLICATE_SREJ; + } + + if (l2cap_seq_list_contains(&chan->srej_list, txseq)) { + BT_DBG("Unexpected SREJ - not requested"); + return L2CAP_TXSEQ_UNEXPECTED_SREJ; + } + } + + if (chan->expected_tx_seq == txseq) { + if (__seq_offset(chan, txseq, chan->last_acked_seq) >= + chan->tx_win) { + BT_DBG("Invalid - txseq outside tx window"); + return L2CAP_TXSEQ_INVALID; + } else { + BT_DBG("Expected"); + return L2CAP_TXSEQ_EXPECTED; + } + } + + if (__seq_offset(chan, txseq, chan->last_acked_seq) < + __seq_offset(chan, chan->expected_tx_seq, + chan->last_acked_seq)){ + BT_DBG("Duplicate - expected_tx_seq later than txseq"); + return L2CAP_TXSEQ_DUPLICATE; + } + + if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) { + /* A source of invalid packets is a "double poll" condition, + * where delays cause us to send multiple poll packets. If + * the remote stack receives and processes both polls, + * sequence numbers can wrap around in such a way that a + * resent frame has a sequence number that looks like new data + * with a sequence gap. This would trigger an erroneous SREJ + * request. + * + * Fortunately, this is impossible with a tx window that's + * less than half of the maximum sequence number, which allows + * invalid frames to be safely ignored. + * + * With tx window sizes greater than half of the tx window + * maximum, the frame is invalid and cannot be ignored. This + * causes a disconnect. + */ + + if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) { + BT_DBG("Invalid/Ignore - txseq outside tx window"); + return L2CAP_TXSEQ_INVALID_IGNORE; + } else { + BT_DBG("Invalid - txseq outside tx window"); + return L2CAP_TXSEQ_INVALID; + } + } else { + BT_DBG("Unexpected - txseq indicates missing frames"); + return L2CAP_TXSEQ_UNEXPECTED; + } +} + static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff *skb, u8 event) { @@ -4832,8 +4925,39 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff *skb) { - /* Placeholder */ - return -ENOTSUPP; + int err = 0; + + BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, + chan->rx_state); + + if (l2cap_classify_txseq(chan, control->txseq) == + L2CAP_TXSEQ_EXPECTED) { + l2cap_pass_to_tx(chan, control); + + BT_DBG("buffer_seq %d->%d", chan->buffer_seq, + __next_seq(chan, chan->buffer_seq)); + + chan->buffer_seq = __next_seq(chan, chan->buffer_seq); + + l2cap_reassemble_sdu(chan, skb, control); + } else { + if (chan->sdu) { + kfree_skb(chan->sdu); + chan->sdu = NULL; + } + chan->sdu_last_frag = NULL; + chan->sdu_len = 0; + + if (skb) { + BT_DBG("Freeing %p", skb); + kfree_skb(skb); + } + } + + chan->last_acked_seq = control->txseq; + chan->expected_tx_seq = __next_seq(chan, control->txseq); + + return err; } static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) -- GitLab From f5dbb0772df3feb2bb5eda8a9f0e0acdeb25653f Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:38 -0700 Subject: [PATCH 0276/6849] Bluetooth: Remove receive code that has been superceded This deletes the receive code that had handlers for each frame type at the top level, and then had logic to determine the receive state within each handler. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 8 - net/bluetooth/l2cap_core.c | 492 ---------------------------------- 2 files changed, 500 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 452fcc4c0fff..7d1da5a7d11e 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -419,11 +419,6 @@ struct l2cap_seq_list { #define L2CAP_SEQ_LIST_CLEAR 0xFFFF #define L2CAP_SEQ_LIST_TAIL 0x8000 -struct srej_list { - __u16 tx_seq; - struct list_head list; -}; - struct l2cap_chan { struct sock *sk; @@ -475,14 +470,12 @@ struct l2cap_chan { __u16 expected_ack_seq; __u16 expected_tx_seq; __u16 buffer_seq; - __u16 buffer_seq_srej; __u16 srej_save_reqseq; __u16 last_acked_seq; __u16 frames_sent; __u16 unacked_frames; __u8 retry_count; __u16 srej_queue_next; - __u8 num_acked; __u16 sdu_len; struct sk_buff *sdu; struct sk_buff *sdu_last_frag; @@ -515,7 +508,6 @@ struct l2cap_chan { struct sk_buff_head srej_q; struct l2cap_seq_list srej_list; struct l2cap_seq_list retrans_list; - struct list_head srej_l; struct list_head list; struct list_head global_l; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0a195ab4a385..d795d15cadf9 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -534,8 +534,6 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) skb_queue_purge(&chan->tx_q); if (chan->mode == L2CAP_MODE_ERTM) { - struct srej_list *l, *tmp; - __clear_retrans_timer(chan); __clear_monitor_timer(chan); __clear_ack_timer(chan); @@ -544,10 +542,6 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_seq_list_free(&chan->srej_list); l2cap_seq_list_free(&chan->retrans_list); - list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { - list_del(&l->list); - kfree(l); - } } } @@ -1658,25 +1652,6 @@ static void l2cap_retrans_timeout(struct work_struct *work) l2cap_chan_put(chan); } -static void l2cap_drop_acked_frames(struct l2cap_chan *chan) -{ - struct sk_buff *skb; - - while ((skb = skb_peek(&chan->tx_q)) && - chan->unacked_frames) { - if (bt_cb(skb)->control.txseq == chan->expected_ack_seq) - break; - - skb = skb_dequeue(&chan->tx_q); - kfree_skb(skb); - - chan->unacked_frames--; - } - - if (!chan->unacked_frames) - __clear_retrans_timer(chan); -} - static int l2cap_streaming_send(struct l2cap_chan *chan, struct sk_buff_head *skbs) { @@ -1718,53 +1693,6 @@ static int l2cap_streaming_send(struct l2cap_chan *chan, return 0; } -static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq) -{ - struct sk_buff *skb, *tx_skb; - u16 fcs; - u32 control; - - skb = skb_peek(&chan->tx_q); - if (!skb) - return; - - while (bt_cb(skb)->control.txseq != tx_seq) { - if (skb_queue_is_last(&chan->tx_q, skb)) - return; - - skb = skb_queue_next(&chan->tx_q, skb); - } - - if (bt_cb(skb)->control.retries == chan->remote_max_tx && - chan->remote_max_tx) { - l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); - return; - } - - tx_skb = skb_clone(skb, GFP_ATOMIC); - bt_cb(skb)->control.retries++; - - control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); - control &= __get_sar_mask(chan); - - if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) - control |= __set_ctrl_final(chan); - - control |= __set_reqseq(chan, chan->buffer_seq); - control |= __set_txseq(chan, tx_seq); - - __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); - - if (chan->fcs == L2CAP_FCS_CRC16) { - fcs = crc16(0, (u8 *)tx_skb->data, - tx_skb->len - L2CAP_FCS_SIZE); - put_unaligned_le16(fcs, - tx_skb->data + tx_skb->len - L2CAP_FCS_SIZE); - } - - l2cap_do_send(chan, tx_skb); -} - static int l2cap_ertm_send(struct l2cap_chan *chan) { struct sk_buff *skb, *tx_skb; @@ -1868,18 +1796,6 @@ static void l2cap_send_ack(struct l2cap_chan *chan) __l2cap_send_ack(chan); } -static void l2cap_send_srejtail(struct l2cap_chan *chan) -{ - struct srej_list *tail; - u32 control; - - control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); - control |= __set_ctrl_final(chan); - - tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); - control |= __set_reqseq(chan, tail->tx_seq); -} - static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, struct msghdr *msg, int len, int count, struct sk_buff *skb) @@ -2639,7 +2555,6 @@ static inline int l2cap_ertm_init(struct l2cap_chan *chan) chan->expected_ack_seq = 0; chan->unacked_frames = 0; chan->buffer_seq = 0; - chan->num_acked = 0; chan->frames_sent = 0; chan->last_acked_seq = 0; chan->sdu = NULL; @@ -2660,7 +2575,6 @@ static inline int l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->srej_q); - INIT_LIST_HEAD(&chan->srej_l); err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win); if (err < 0) return err; @@ -4277,41 +4191,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) } } -static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u16 tx_seq, u8 sar) -{ - struct sk_buff *next_skb; - int tx_seq_offset, next_tx_seq_offset; - - bt_cb(skb)->control.txseq = tx_seq; - bt_cb(skb)->control.sar = sar; - - next_skb = skb_peek(&chan->srej_q); - - tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); - - while (next_skb) { - if (bt_cb(next_skb)->control.txseq == tx_seq) - return -EINVAL; - - next_tx_seq_offset = __seq_offset(chan, - bt_cb(next_skb)->control.txseq, chan->buffer_seq); - - if (next_tx_seq_offset > tx_seq_offset) { - __skb_queue_before(&chan->srej_q, next_skb, skb); - return 0; - } - - if (skb_queue_is_last(&chan->srej_q, next_skb)) - next_skb = NULL; - else - next_skb = skb_queue_next(&chan->srej_q, next_skb); - } - - __skb_queue_tail(&chan->srej_q, skb); - - return 0; -} - static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag, struct sk_buff **last_frag) { @@ -4457,377 +4336,6 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) } } -static void l2cap_check_srej_gap(struct l2cap_chan *chan, u16 tx_seq) -{ - struct sk_buff *skb; - u32 control; - - while ((skb = skb_peek(&chan->srej_q)) && - !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - int err; - - if (bt_cb(skb)->control.txseq != tx_seq) - break; - - skb = skb_dequeue(&chan->srej_q); - control = __set_ctrl_sar(chan, bt_cb(skb)->control.sar); - - if (err < 0) { - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - break; - } - - chan->buffer_seq_srej = __next_seq(chan, chan->buffer_seq_srej); - tx_seq = __next_seq(chan, tx_seq); - } -} - -static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq) -{ - struct srej_list *l, *tmp; - u32 control; - - list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { - if (l->tx_seq == tx_seq) { - list_del(&l->list); - kfree(l); - return; - } - control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); - control |= __set_reqseq(chan, l->tx_seq); - list_del(&l->list); - list_add_tail(&l->list, &chan->srej_l); - } -} - -static int l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq) -{ - struct srej_list *new; - u32 control; - - while (tx_seq != chan->expected_tx_seq) { - control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); - control |= __set_reqseq(chan, chan->expected_tx_seq); - l2cap_seq_list_append(&chan->srej_list, chan->expected_tx_seq); - - new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); - if (!new) - return -ENOMEM; - - new->tx_seq = chan->expected_tx_seq; - - chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); - - list_add_tail(&new->list, &chan->srej_l); - } - - chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); - - return 0; -} - -static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) -{ - u16 tx_seq = __get_txseq(chan, rx_control); - u16 req_seq = __get_reqseq(chan, rx_control); - u8 sar = __get_ctrl_sar(chan, rx_control); - int tx_seq_offset, expected_tx_seq_offset; - int num_to_ack = (chan->tx_win/6) + 1; - int err = 0; - - BT_DBG("chan %p len %d tx_seq %d rx_control 0x%8.8x", chan, skb->len, - tx_seq, rx_control); - - if (__is_ctrl_final(chan, rx_control) && - test_bit(CONN_WAIT_F, &chan->conn_state)) { - __clear_monitor_timer(chan); - if (chan->unacked_frames > 0) - __set_retrans_timer(chan); - clear_bit(CONN_WAIT_F, &chan->conn_state); - } - - chan->expected_ack_seq = req_seq; - l2cap_drop_acked_frames(chan); - - tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); - - /* invalid tx_seq */ - if (tx_seq_offset >= chan->tx_win) { - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - goto drop; - } - - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) - l2cap_send_ack(chan); - goto drop; - } - - if (tx_seq == chan->expected_tx_seq) - goto expected; - - if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { - struct srej_list *first; - - first = list_first_entry(&chan->srej_l, - struct srej_list, list); - if (tx_seq == first->tx_seq) { - l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); - l2cap_check_srej_gap(chan, tx_seq); - - list_del(&first->list); - kfree(first); - - if (list_empty(&chan->srej_l)) { - chan->buffer_seq = chan->buffer_seq_srej; - clear_bit(CONN_SREJ_SENT, &chan->conn_state); - l2cap_send_ack(chan); - BT_DBG("chan %p, Exit SREJ_SENT", chan); - } - } else { - struct srej_list *l; - - /* duplicated tx_seq */ - if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0) - goto drop; - - list_for_each_entry(l, &chan->srej_l, list) { - if (l->tx_seq == tx_seq) { - l2cap_resend_srejframe(chan, tx_seq); - return 0; - } - } - - err = l2cap_send_srejframe(chan, tx_seq); - if (err < 0) { - l2cap_send_disconn_req(chan->conn, chan, -err); - return err; - } - } - } else { - expected_tx_seq_offset = __seq_offset(chan, - chan->expected_tx_seq, chan->buffer_seq); - - /* duplicated tx_seq */ - if (tx_seq_offset < expected_tx_seq_offset) - goto drop; - - set_bit(CONN_SREJ_SENT, &chan->conn_state); - - BT_DBG("chan %p, Enter SREJ", chan); - - INIT_LIST_HEAD(&chan->srej_l); - chan->buffer_seq_srej = chan->buffer_seq; - - __skb_queue_head_init(&chan->srej_q); - l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); - - /* Set P-bit only if there are some I-frames to ack. */ - if (__clear_ack_timer(chan)) - set_bit(CONN_SEND_PBIT, &chan->conn_state); - - err = l2cap_send_srejframe(chan, tx_seq); - if (err < 0) { - l2cap_send_disconn_req(chan->conn, chan, -err); - return err; - } - } - return 0; - -expected: - chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); - - if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { - bt_cb(skb)->control.txseq = tx_seq; - bt_cb(skb)->control.sar = sar; - __skb_queue_tail(&chan->srej_q, skb); - return 0; - } - - chan->buffer_seq = __next_seq(chan, chan->buffer_seq); - - if (err < 0) { - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - return err; - } - - if (__is_ctrl_final(chan, rx_control)) { - if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) - l2cap_retransmit_frames(chan); - } - - - chan->num_acked = (chan->num_acked + 1) % num_to_ack; - if (chan->num_acked == num_to_ack - 1) - l2cap_send_ack(chan); - else - __set_ack_timer(chan); - - return 0; - -drop: - kfree_skb(skb); - return 0; -} - -static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u32 rx_control) -{ - BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, - __get_reqseq(chan, rx_control), rx_control); - - chan->expected_ack_seq = __get_reqseq(chan, rx_control); - l2cap_drop_acked_frames(chan); - - if (__is_ctrl_poll(chan, rx_control)) { - set_bit(CONN_SEND_FBIT, &chan->conn_state); - if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { - if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && - (chan->unacked_frames > 0)) - __set_retrans_timer(chan); - - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - l2cap_send_srejtail(chan); - } else { - l2cap_send_i_or_rr_or_rnr(chan); - } - - } else if (__is_ctrl_final(chan, rx_control)) { - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - - if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) - l2cap_retransmit_frames(chan); - - } else { - if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && - (chan->unacked_frames > 0)) - __set_retrans_timer(chan); - - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) - l2cap_send_ack(chan); - else - l2cap_ertm_send(chan); - } -} - -static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u32 rx_control) -{ - u16 tx_seq = __get_reqseq(chan, rx_control); - - BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); - - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - - chan->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(chan); - - if (__is_ctrl_final(chan, rx_control)) { - if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) - l2cap_retransmit_frames(chan); - } else { - l2cap_retransmit_frames(chan); - - if (test_bit(CONN_WAIT_F, &chan->conn_state)) - set_bit(CONN_REJ_ACT, &chan->conn_state); - } -} -static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u32 rx_control) -{ - u16 tx_seq = __get_reqseq(chan, rx_control); - - BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); - - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - - if (__is_ctrl_poll(chan, rx_control)) { - chan->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(chan); - - set_bit(CONN_SEND_FBIT, &chan->conn_state); - l2cap_retransmit_one_frame(chan, tx_seq); - - l2cap_ertm_send(chan); - - if (test_bit(CONN_WAIT_F, &chan->conn_state)) { - chan->srej_save_reqseq = tx_seq; - set_bit(CONN_SREJ_ACT, &chan->conn_state); - } - } else if (__is_ctrl_final(chan, rx_control)) { - if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && - chan->srej_save_reqseq == tx_seq) - clear_bit(CONN_SREJ_ACT, &chan->conn_state); - else - l2cap_retransmit_one_frame(chan, tx_seq); - } else { - l2cap_retransmit_one_frame(chan, tx_seq); - if (test_bit(CONN_WAIT_F, &chan->conn_state)) { - chan->srej_save_reqseq = tx_seq; - set_bit(CONN_SREJ_ACT, &chan->conn_state); - } - } -} - -static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u32 rx_control) -{ - u16 tx_seq = __get_reqseq(chan, rx_control); - - BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); - - set_bit(CONN_REMOTE_BUSY, &chan->conn_state); - chan->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(chan); - - if (__is_ctrl_poll(chan, rx_control)) - set_bit(CONN_SEND_FBIT, &chan->conn_state); - - if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { - __clear_retrans_timer(chan); - if (__is_ctrl_poll(chan, rx_control)) - l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); - return; - } - - if (__is_ctrl_poll(chan, rx_control)) { - l2cap_send_srejtail(chan); - } else { - rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR); - } -} - -static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) -{ - BT_DBG("chan %p rx_control 0x%8.8x len %d", chan, rx_control, skb->len); - - if (__is_ctrl_final(chan, rx_control) && - test_bit(CONN_WAIT_F, &chan->conn_state)) { - __clear_monitor_timer(chan); - if (chan->unacked_frames > 0) - __set_retrans_timer(chan); - clear_bit(CONN_WAIT_F, &chan->conn_state); - } - - switch (__get_ctrl_super(chan, rx_control)) { - case L2CAP_SUPER_RR: - l2cap_data_channel_rrframe(chan, rx_control); - break; - - case L2CAP_SUPER_REJ: - l2cap_data_channel_rejframe(chan, rx_control); - break; - - case L2CAP_SUPER_SREJ: - l2cap_data_channel_srejframe(chan, rx_control); - break; - - case L2CAP_SUPER_RNR: - l2cap_data_channel_rnrframe(chan, rx_control); - break; - } - - kfree_skb(skb); - return 0; -} - static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) { BT_DBG("chan %p, txseq %d", chan, txseq); -- GitLab From 0a0aba42b8daba55e4d2bdfc3c8ca7d7d827b723 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:39 -0700 Subject: [PATCH 0277/6849] Bluetooth: Refactor l2cap_send_ack The function now encapsulates more of the logic to either immediately send an ack if the transmit window is over 75% full, or wait for the ack timer to expire if the transmit window is not full enough. It is also able to push out waiting iframes that can carry an acknowledgement. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 60 +++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d795d15cadf9..f4d4eafb805d 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1772,28 +1772,54 @@ static int l2cap_retransmit_frames(struct l2cap_chan *chan) return ret; } -static void __l2cap_send_ack(struct l2cap_chan *chan) +static void l2cap_send_ack(struct l2cap_chan *chan) { - u32 control = 0; + struct l2cap_ctrl control; + u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq, + chan->last_acked_seq); + int threshold; - control |= __set_reqseq(chan, chan->buffer_seq); + BT_DBG("chan %p last_acked_seq %d buffer_seq %d", + chan, chan->last_acked_seq, chan->buffer_seq); - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); - set_bit(CONN_RNR_SENT, &chan->conn_state); - return; - } + memset(&control, 0, sizeof(control)); + control.sframe = 1; - if (l2cap_ertm_send(chan) > 0) - return; + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && + chan->rx_state == L2CAP_RX_STATE_RECV) { + __clear_ack_timer(chan); + control.super = L2CAP_SUPER_RNR; + control.reqseq = chan->buffer_seq; + l2cap_send_sframe(chan, &control); + } else { + if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) { + l2cap_ertm_send(chan); + /* If any i-frames were sent, they included an ack */ + if (chan->buffer_seq == chan->last_acked_seq) + frames_to_ack = 0; + } - control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); -} + /* Ack now if the tx window is 3/4ths full. + * Calculate without mul or div + */ + threshold = chan->tx_win; + threshold += threshold << 1; + threshold >>= 2; + + BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack, + threshold); + + if (frames_to_ack >= threshold) { + __clear_ack_timer(chan); + control.super = L2CAP_SUPER_RR; + control.reqseq = chan->buffer_seq; + l2cap_send_sframe(chan, &control); + frames_to_ack = 0; + } -static void l2cap_send_ack(struct l2cap_chan *chan) -{ - __clear_ack_timer(chan); - __l2cap_send_ack(chan); + if (frames_to_ack) + __set_ack_timer(chan); + } } static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, @@ -2539,7 +2565,7 @@ static void l2cap_ack_timeout(struct work_struct *work) l2cap_chan_lock(chan); - __l2cap_send_ack(chan); + l2cap_send_ack(chan); l2cap_chan_unlock(chan); -- GitLab From 61aa4f5b9f43b21668aec51da2df3e9ed5f4226d Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:40 -0700 Subject: [PATCH 0278/6849] Bluetooth: Use the transmit state machine for busy state changes This lets the transmit state machine handle local busy state changes, since different actions are taken in the different transmit states. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 45 +++++--------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index f4d4eafb805d..8436806835e0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4318,48 +4318,15 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, return err; } -static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) -{ - BT_DBG("chan %p, Enter local busy", chan); - - set_bit(CONN_LOCAL_BUSY, &chan->conn_state); - l2cap_seq_list_clear(&chan->srej_list); - - __set_ack_timer(chan); -} - -static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) +void l2cap_chan_busy(struct l2cap_chan *chan, int busy) { - u32 control; - - if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) - goto done; - - control = __set_reqseq(chan, chan->buffer_seq); - control |= __set_ctrl_poll(chan); - control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); - chan->retry_count = 1; - - __clear_retrans_timer(chan); - __set_monitor_timer(chan); - - set_bit(CONN_WAIT_F, &chan->conn_state); - -done: - clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); - clear_bit(CONN_RNR_SENT, &chan->conn_state); + u8 event; - BT_DBG("chan %p, Exit local busy", chan); -} + if (chan->mode != L2CAP_MODE_ERTM) + return; -void l2cap_chan_busy(struct l2cap_chan *chan, int busy) -{ - if (chan->mode == L2CAP_MODE_ERTM) { - if (busy) - l2cap_ertm_enter_local_busy(chan); - else - l2cap_ertm_exit_local_busy(chan); - } + event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR; + l2cap_tx(chan, 0, 0, event); } static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) -- GitLab From e31f76337257616aca0ea15abee271513b17426c Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:41 -0700 Subject: [PATCH 0279/6849] Bluetooth: Update l2cap_send_i_or_rr_or_rnr to fit the spec better This action now exactly matches what is defined in the ERTM specification, including clearing the remote busy flag and setting the retransmit timer rather than retransmitting frames directly. The spec does not retransmit frames as part of this action, since retransmission is only triggered by REJ, SREJ, or an RR with the final bit set. struct l2cap_ctrl is also used to set up header values. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 40 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8436806835e0..a7d96c937392 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1760,18 +1760,6 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) return sent; } -static int l2cap_retransmit_frames(struct l2cap_chan *chan) -{ - int ret; - - if (!skb_queue_empty(&chan->tx_q)) - chan->tx_send_head = chan->tx_q.next; - - chan->next_tx_seq = chan->expected_ack_seq; - ret = l2cap_ertm_send(chan); - return ret; -} - static void l2cap_send_ack(struct l2cap_chan *chan) { struct l2cap_ctrl control; @@ -4195,25 +4183,35 @@ static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { - u32 control = 0; + struct l2cap_ctrl control; - chan->frames_sent = 0; + BT_DBG("chan %p", chan); - control |= __set_reqseq(chan, chan->buffer_seq); + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.final = 1; + control.reqseq = chan->buffer_seq; + set_bit(CONN_SEND_FBIT, &chan->conn_state); if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); - set_bit(CONN_RNR_SENT, &chan->conn_state); + control.super = L2CAP_SUPER_RNR; + l2cap_send_sframe(chan, &control); } - if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) - l2cap_retransmit_frames(chan); + if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) && + chan->unacked_frames > 0) + __set_retrans_timer(chan); + /* Send pending iframes */ l2cap_ertm_send(chan); if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && - chan->frames_sent == 0) { - control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); + test_bit(CONN_SEND_FBIT, &chan->conn_state)) { + /* F-bit wasn't sent in an s-frame or i-frame yet, so + * send it now. + */ + control.super = L2CAP_SUPER_RR; + l2cap_send_sframe(chan, &control); } } -- GitLab From d2a7ac5d5d3a0b166ac128883bd088064c029fe5 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:42 -0700 Subject: [PATCH 0280/6849] Bluetooth: Add the ERTM receive state machine This adds a top-level state machine with handlers for two receive states defined in the ERTM spec, RECV and SREJ_SENT. The reqseq value of the incoming frame is also validated at the top level and a disconnection is forced if it is invalid. The actions for the RECV and SREJ_SENT states are implemented according to the state tables in the ERTM specification. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 355 ++++++++++++++++++++++++++++++++++++- 1 file changed, 353 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a7d96c937392..287d64cf2dd4 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1760,6 +1760,12 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) return sent; } +static void l2cap_retransmit_all(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + /* Placeholder */ +} + static void l2cap_send_ack(struct l2cap_chan *chan) { struct l2cap_ctrl control; @@ -2127,6 +2133,21 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, return err; } +static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) +{ + /* Placeholder */ +} + +static void l2cap_send_srej_tail(struct l2cap_chan *chan) +{ + /* Placeholder */ +} + +static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) +{ + /* Placeholder */ +} + static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) { struct sk_buff *acked_skb; @@ -4327,6 +4348,24 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) l2cap_tx(chan, 0, 0, event); } +static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) +{ + /* Placeholder */ + return 0; +} + +static void l2cap_handle_srej(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + /* Placeholder */ +} + +static void l2cap_handle_rej(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + /* Placeholder */ +} + static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) { BT_DBG("chan %p, txseq %d", chan, txseq); @@ -4414,11 +4453,323 @@ static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) } } +static int l2cap_rx_state_recv(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff *skb, u8 event) +{ + int err = 0; + bool skb_in_use = 0; + + BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + event); + + switch (event) { + case L2CAP_EV_RECV_IFRAME: + switch (l2cap_classify_txseq(chan, control->txseq)) { + case L2CAP_TXSEQ_EXPECTED: + l2cap_pass_to_tx(chan, control); + + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + BT_DBG("Busy, discarding expected seq %d", + control->txseq); + break; + } + + chan->expected_tx_seq = __next_seq(chan, + control->txseq); + + chan->buffer_seq = chan->expected_tx_seq; + skb_in_use = 1; + + err = l2cap_reassemble_sdu(chan, skb, control); + if (err) + break; + + if (control->final) { + if (!test_and_clear_bit(CONN_REJ_ACT, + &chan->conn_state)) { + control->final = 0; + l2cap_retransmit_all(chan, control); + l2cap_ertm_send(chan); + } + } + + if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) + l2cap_send_ack(chan); + break; + case L2CAP_TXSEQ_UNEXPECTED: + l2cap_pass_to_tx(chan, control); + + /* Can't issue SREJ frames in the local busy state. + * Drop this frame, it will be seen as missing + * when local busy is exited. + */ + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + BT_DBG("Busy, discarding unexpected seq %d", + control->txseq); + break; + } + + /* There was a gap in the sequence, so an SREJ + * must be sent for each missing frame. The + * current frame is stored for later use. + */ + skb_queue_tail(&chan->srej_q, skb); + skb_in_use = 1; + BT_DBG("Queued %p (queue len %d)", skb, + skb_queue_len(&chan->srej_q)); + + clear_bit(CONN_SREJ_ACT, &chan->conn_state); + l2cap_seq_list_clear(&chan->srej_list); + l2cap_send_srej(chan, control->txseq); + + chan->rx_state = L2CAP_RX_STATE_SREJ_SENT; + break; + case L2CAP_TXSEQ_DUPLICATE: + l2cap_pass_to_tx(chan, control); + break; + case L2CAP_TXSEQ_INVALID_IGNORE: + break; + case L2CAP_TXSEQ_INVALID: + default: + l2cap_send_disconn_req(chan->conn, chan, + ECONNRESET); + break; + } + break; + case L2CAP_EV_RECV_RR: + l2cap_pass_to_tx(chan, control); + if (control->final) { + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + + if (!test_and_clear_bit(CONN_REJ_ACT, + &chan->conn_state)) { + control->final = 0; + l2cap_retransmit_all(chan, control); + } + + l2cap_ertm_send(chan); + } else if (control->poll) { + l2cap_send_i_or_rr_or_rnr(chan); + } else { + if (test_and_clear_bit(CONN_REMOTE_BUSY, + &chan->conn_state) && + chan->unacked_frames) + __set_retrans_timer(chan); + + l2cap_ertm_send(chan); + } + break; + case L2CAP_EV_RECV_RNR: + set_bit(CONN_REMOTE_BUSY, &chan->conn_state); + l2cap_pass_to_tx(chan, control); + if (control && control->poll) { + set_bit(CONN_SEND_FBIT, &chan->conn_state); + l2cap_send_rr_or_rnr(chan, 0); + } + __clear_retrans_timer(chan); + l2cap_seq_list_clear(&chan->retrans_list); + break; + case L2CAP_EV_RECV_REJ: + l2cap_handle_rej(chan, control); + break; + case L2CAP_EV_RECV_SREJ: + l2cap_handle_srej(chan, control); + break; + default: + break; + } + + if (skb && !skb_in_use) { + BT_DBG("Freeing %p", skb); + kfree_skb(skb); + } + + return err; +} + +static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff *skb, u8 event) +{ + int err = 0; + u16 txseq = control->txseq; + bool skb_in_use = 0; + + BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + event); + + switch (event) { + case L2CAP_EV_RECV_IFRAME: + switch (l2cap_classify_txseq(chan, txseq)) { + case L2CAP_TXSEQ_EXPECTED: + /* Keep frame for reassembly later */ + l2cap_pass_to_tx(chan, control); + skb_queue_tail(&chan->srej_q, skb); + skb_in_use = 1; + BT_DBG("Queued %p (queue len %d)", skb, + skb_queue_len(&chan->srej_q)); + + chan->expected_tx_seq = __next_seq(chan, txseq); + break; + case L2CAP_TXSEQ_EXPECTED_SREJ: + l2cap_seq_list_pop(&chan->srej_list); + + l2cap_pass_to_tx(chan, control); + skb_queue_tail(&chan->srej_q, skb); + skb_in_use = 1; + BT_DBG("Queued %p (queue len %d)", skb, + skb_queue_len(&chan->srej_q)); + + err = l2cap_rx_queued_iframes(chan); + if (err) + break; + + break; + case L2CAP_TXSEQ_UNEXPECTED: + /* Got a frame that can't be reassembled yet. + * Save it for later, and send SREJs to cover + * the missing frames. + */ + skb_queue_tail(&chan->srej_q, skb); + skb_in_use = 1; + BT_DBG("Queued %p (queue len %d)", skb, + skb_queue_len(&chan->srej_q)); + + l2cap_pass_to_tx(chan, control); + l2cap_send_srej(chan, control->txseq); + break; + case L2CAP_TXSEQ_UNEXPECTED_SREJ: + /* This frame was requested with an SREJ, but + * some expected retransmitted frames are + * missing. Request retransmission of missing + * SREJ'd frames. + */ + skb_queue_tail(&chan->srej_q, skb); + skb_in_use = 1; + BT_DBG("Queued %p (queue len %d)", skb, + skb_queue_len(&chan->srej_q)); + + l2cap_pass_to_tx(chan, control); + l2cap_send_srej_list(chan, control->txseq); + break; + case L2CAP_TXSEQ_DUPLICATE_SREJ: + /* We've already queued this frame. Drop this copy. */ + l2cap_pass_to_tx(chan, control); + break; + case L2CAP_TXSEQ_DUPLICATE: + /* Expecting a later sequence number, so this frame + * was already received. Ignore it completely. + */ + break; + case L2CAP_TXSEQ_INVALID_IGNORE: + break; + case L2CAP_TXSEQ_INVALID: + default: + l2cap_send_disconn_req(chan->conn, chan, + ECONNRESET); + break; + } + break; + case L2CAP_EV_RECV_RR: + l2cap_pass_to_tx(chan, control); + if (control->final) { + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + + if (!test_and_clear_bit(CONN_REJ_ACT, + &chan->conn_state)) { + control->final = 0; + l2cap_retransmit_all(chan, control); + } + + l2cap_ertm_send(chan); + } else if (control->poll) { + if (test_and_clear_bit(CONN_REMOTE_BUSY, + &chan->conn_state) && + chan->unacked_frames) { + __set_retrans_timer(chan); + } + + set_bit(CONN_SEND_FBIT, &chan->conn_state); + l2cap_send_srej_tail(chan); + } else { + if (test_and_clear_bit(CONN_REMOTE_BUSY, + &chan->conn_state) && + chan->unacked_frames) + __set_retrans_timer(chan); + + l2cap_send_ack(chan); + } + break; + case L2CAP_EV_RECV_RNR: + set_bit(CONN_REMOTE_BUSY, &chan->conn_state); + l2cap_pass_to_tx(chan, control); + if (control->poll) { + l2cap_send_srej_tail(chan); + } else { + struct l2cap_ctrl rr_control; + memset(&rr_control, 0, sizeof(rr_control)); + rr_control.sframe = 1; + rr_control.super = L2CAP_SUPER_RR; + rr_control.reqseq = chan->buffer_seq; + l2cap_send_sframe(chan, &rr_control); + } + + break; + case L2CAP_EV_RECV_REJ: + l2cap_handle_rej(chan, control); + break; + case L2CAP_EV_RECV_SREJ: + l2cap_handle_srej(chan, control); + break; + } + + if (skb && !skb_in_use) { + BT_DBG("Freeing %p", skb); + kfree_skb(skb); + } + + return err; +} + +static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq) +{ + /* Make sure reqseq is for a packet that has been sent but not acked */ + u16 unacked; + + unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq); + return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked; +} + static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff *skb, u8 event) { - /* Placeholder */ - return -ENOTSUPP; + int err = 0; + + BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan, + control, skb, event, chan->rx_state); + + if (__valid_reqseq(chan, control->reqseq)) { + switch (chan->rx_state) { + case L2CAP_RX_STATE_RECV: + err = l2cap_rx_state_recv(chan, control, skb, event); + break; + case L2CAP_RX_STATE_SREJ_SENT: + err = l2cap_rx_state_srej_sent(chan, control, skb, + event); + break; + default: + /* shut it down */ + break; + } + } else { + BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d", + control->reqseq, chan->next_tx_seq, + chan->expected_ack_seq); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + } + + return err; } static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, -- GitLab From e1fbd4c19a5c4d4f490d70e73745cf2cf0dc1955 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:43 -0700 Subject: [PATCH 0281/6849] Bluetooth: Add implementation for retransmitting all unacked frames This adds l2cap_ertm_resend to retransmit frames based on the sequence numbers in chan->retrans_list. If the retransmit limit is reached for any individual frame is reached, the connection is dropped. skbs that are cloned already are copied to avoid modifying shared data (this is uncommon). To retransmit all frames, l2cap_retransmit_all now builds a list of all unacked sequence numbers and then calls l2cap_ertm_resend. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 106 ++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 287d64cf2dd4..26963a5e3f58 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1760,10 +1760,114 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) return sent; } +static void l2cap_ertm_resend(struct l2cap_chan *chan) +{ + struct l2cap_ctrl control; + struct sk_buff *skb; + struct sk_buff *tx_skb; + u16 seq; + + BT_DBG("chan %p", chan); + + if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) + return; + + while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) { + seq = l2cap_seq_list_pop(&chan->retrans_list); + + skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq); + if (!skb) { + BT_DBG("Error: Can't retransmit seq %d, frame missing", + seq); + continue; + } + + bt_cb(skb)->control.retries++; + control = bt_cb(skb)->control; + + if (chan->max_tx != 0 && + bt_cb(skb)->control.retries > chan->max_tx) { + BT_DBG("Retry limit exceeded (%d)", chan->max_tx); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + l2cap_seq_list_clear(&chan->retrans_list); + break; + } + + control.reqseq = chan->buffer_seq; + if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) + control.final = 1; + else + control.final = 0; + + if (skb_cloned(skb)) { + /* Cloned sk_buffs are read-only, so we need a + * writeable copy + */ + tx_skb = skb_copy(skb, GFP_ATOMIC); + } else { + tx_skb = skb_clone(skb, GFP_ATOMIC); + } + + if (!tx_skb) { + l2cap_seq_list_clear(&chan->retrans_list); + break; + } + + /* Update skb contents */ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) { + put_unaligned_le32(__pack_extended_control(&control), + tx_skb->data + L2CAP_HDR_SIZE); + } else { + put_unaligned_le16(__pack_enhanced_control(&control), + tx_skb->data + L2CAP_HDR_SIZE); + } + + if (chan->fcs == L2CAP_FCS_CRC16) { + u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len); + put_unaligned_le16(fcs, skb_put(tx_skb, + L2CAP_FCS_SIZE)); + } + + l2cap_do_send(chan, tx_skb); + + BT_DBG("Resent txseq %d", control.txseq); + + chan->last_acked_seq = chan->buffer_seq; + } +} + static void l2cap_retransmit_all(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - /* Placeholder */ + struct sk_buff *skb; + + BT_DBG("chan %p, control %p", chan, control); + + if (control->poll) + set_bit(CONN_SEND_FBIT, &chan->conn_state); + + l2cap_seq_list_clear(&chan->retrans_list); + + if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) + return; + + if (chan->unacked_frames) { + skb_queue_walk(&chan->tx_q, skb) { + if (bt_cb(skb)->control.txseq == control->reqseq || + skb == chan->tx_send_head) + break; + } + + skb_queue_walk_from(&chan->tx_q, skb) { + if (skb == chan->tx_send_head) + break; + + l2cap_seq_list_append(&chan->retrans_list, + bt_cb(skb)->control.txseq); + } + + l2cap_ertm_resend(chan); + } } static void l2cap_send_ack(struct l2cap_chan *chan) -- GitLab From bed68bde7ebdb591cc67921261307626c8f37936 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:44 -0700 Subject: [PATCH 0282/6849] Bluetooth: Send SREJ frames when packets go missing The ERTM specification lays out three scenarios for sending SREJ frames to request retransmission of specific frames. l2cap_send_srej requests all frames up to a given txseq that are not already queued for reassembly. l2cap_send_srej_tail only requests the most recent missing frame. l2cap_send_srej_list resends SREJ frames for data that was requested for resend but never received. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 56 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 26963a5e3f58..5823697cf9de 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2239,17 +2239,67 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) { - /* Placeholder */ + struct l2cap_ctrl control; + u16 seq; + + BT_DBG("chan %p, txseq %d", chan, txseq); + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.super = L2CAP_SUPER_SREJ; + + for (seq = chan->expected_tx_seq; seq != txseq; + seq = __next_seq(chan, seq)) { + if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) { + control.reqseq = seq; + l2cap_send_sframe(chan, &control); + l2cap_seq_list_append(&chan->srej_list, seq); + } + } + + chan->expected_tx_seq = __next_seq(chan, txseq); } static void l2cap_send_srej_tail(struct l2cap_chan *chan) { - /* Placeholder */ + struct l2cap_ctrl control; + + BT_DBG("chan %p", chan); + + if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR) + return; + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.super = L2CAP_SUPER_SREJ; + control.reqseq = chan->srej_list.tail; + l2cap_send_sframe(chan, &control); } static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) { - /* Placeholder */ + struct l2cap_ctrl control; + u16 initial_head; + u16 seq; + + BT_DBG("chan %p, txseq %d", chan, txseq); + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.super = L2CAP_SUPER_SREJ; + + /* Capture initial list head to allow only one pass through the list. */ + initial_head = chan->srej_list.head; + + do { + seq = l2cap_seq_list_pop(&chan->srej_list); + if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR) + break; + + control.reqseq = seq; + l2cap_send_sframe(chan, &control); + l2cap_seq_list_append(&chan->srej_list, seq); + } while (chan->srej_list.head != initial_head); } static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) -- GitLab From 63838725c6478102894cfb88feb2a9b1c331855d Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:45 -0700 Subject: [PATCH 0283/6849] Bluetooth: Reassemble all available data when retransmissions succeed. As retransmitted packets arrive, attempt to reassemble SDUs. If all requested retransmissions have been received, acknowledge them and transition back to the RECV state. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5823697cf9de..fd324d4cb217 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4504,8 +4504,36 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) { - /* Placeholder */ - return 0; + int err = 0; + /* Pass sequential frames to l2cap_reassemble_sdu() + * until a gap is encountered. + */ + + BT_DBG("chan %p", chan); + + while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + struct sk_buff *skb; + BT_DBG("Searching for skb with txseq %d (queue len %d)", + chan->buffer_seq, skb_queue_len(&chan->srej_q)); + + skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq); + + if (!skb) + break; + + skb_unlink(skb, &chan->srej_q); + chan->buffer_seq = __next_seq(chan, chan->buffer_seq); + err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control); + if (err) + break; + } + + if (skb_queue_empty(&chan->srej_q)) { + chan->rx_state = L2CAP_RX_STATE_RECV; + l2cap_send_ack(chan); + } + + return err; } static void l2cap_handle_srej(struct l2cap_chan *chan, -- GitLab From f80842a83ec224e70ebbd11a20832e71e5911b45 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:46 -0700 Subject: [PATCH 0284/6849] Bluetooth: Handle SREJ requests to resend unacked frames When a remote device sends an SREJ, retransmit the frame with the corresponding sequence number (subject to special cases with poll and final flags). An SREJ is also an implicit indication the the remote device is not in a busy state. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 70 +++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index fd324d4cb217..36842a29bb47 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1836,6 +1836,15 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) } } +static void l2cap_retransmit(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + BT_DBG("chan %p, control %p", chan, control); + + l2cap_seq_list_append(&chan->retrans_list, control->reqseq); + l2cap_ertm_resend(chan); +} + static void l2cap_retransmit_all(struct l2cap_chan *chan, struct l2cap_ctrl *control) { @@ -2532,6 +2541,13 @@ static void l2cap_pass_to_tx(struct l2cap_chan *chan, l2cap_tx(chan, control, 0, L2CAP_EV_RECV_REQSEQ_AND_FBIT); } +static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan, + struct l2cap_ctrl *control) +{ + BT_DBG("chan %p, control %p", chan, control); + l2cap_tx(chan, control, 0, L2CAP_EV_RECV_FBIT); +} + /* Copy frame to all raw sockets on that connection */ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { @@ -4539,7 +4555,59 @@ static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) static void l2cap_handle_srej(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - /* Placeholder */ + struct sk_buff *skb; + + BT_DBG("chan %p, control %p", chan, control); + + if (control->reqseq == chan->next_tx_seq) { + BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + return; + } + + skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq); + + if (skb == NULL) { + BT_DBG("Seq %d not available for retransmission", + control->reqseq); + return; + } + + if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) { + BT_DBG("Retry limit exceeded (%d)", chan->max_tx); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + return; + } + + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + + if (control->poll) { + l2cap_pass_to_tx(chan, control); + + set_bit(CONN_SEND_FBIT, &chan->conn_state); + l2cap_retransmit(chan, control); + l2cap_ertm_send(chan); + + if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) { + set_bit(CONN_SREJ_ACT, &chan->conn_state); + chan->srej_save_reqseq = control->reqseq; + } + } else { + l2cap_pass_to_tx_fbit(chan, control); + + if (control->final) { + if (chan->srej_save_reqseq != control->reqseq || + !test_and_clear_bit(CONN_SREJ_ACT, + &chan->conn_state)) + l2cap_retransmit(chan, control); + } else { + l2cap_retransmit(chan, control); + if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) { + set_bit(CONN_SREJ_ACT, &chan->conn_state); + chan->srej_save_reqseq = control->reqseq; + } + } + } } static void l2cap_handle_rej(struct l2cap_chan *chan, -- GitLab From fcd289df8892268ec0783588e0d7e0346fd6a1cd Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:47 -0700 Subject: [PATCH 0285/6849] Bluetooth: Handle incoming REJ frames REJ frames are sent by the remote device to request that all frames after a given sequence number be retransmitted. These are also an implicit indication that the remote device is not in a busy state and can receive new iframes. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 36842a29bb47..5e4a881a6e19 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4613,7 +4613,38 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, static void l2cap_handle_rej(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - /* Placeholder */ + struct sk_buff *skb; + + BT_DBG("chan %p, control %p", chan, control); + + if (control->reqseq == chan->next_tx_seq) { + BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + return; + } + + skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq); + + if (chan->max_tx && skb && + bt_cb(skb)->control.retries >= chan->max_tx) { + BT_DBG("Retry limit exceeded (%d)", chan->max_tx); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + return; + } + + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + + l2cap_pass_to_tx(chan, control); + + if (control->final) { + if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) + l2cap_retransmit_all(chan, control); + } else { + l2cap_retransmit_all(chan, control); + l2cap_ertm_send(chan); + if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) + set_bit(CONN_REJ_ACT, &chan->conn_state); + } } static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) -- GitLab From c9e3d5e00408c96f82b88a8de5d54f7a1343b110 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:48 -0700 Subject: [PATCH 0286/6849] Bluetooth: Use new header structures in l2cap_send_rr_or_rnr struct l2cap_ctrl is now used, and the sframe is now sent directly rather than depending on a separate call. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5e4a881a6e19..8ea9ec648bfd 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -920,15 +920,23 @@ static void l2cap_send_sframe(struct l2cap_chan *chan, l2cap_do_send(chan, skb); } -static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control) +static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) { - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); - set_bit(CONN_RNR_SENT, &chan->conn_state); - } else - control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); + struct l2cap_ctrl control; + + BT_DBG("chan %p, poll %d", chan, poll); + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.poll = poll; - control |= __set_reqseq(chan, chan->buffer_seq); + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) + control.super = L2CAP_SUPER_RNR; + else + control.super = L2CAP_SUPER_RR; + + control.reqseq = chan->buffer_seq; + l2cap_send_sframe(chan, &control); } static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) -- GitLab From 4239d16f360ce4c8a1798508dd171ebce93985ba Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:49 -0700 Subject: [PATCH 0287/6849] Bluetooth: Check rules when setting retransmit or monitor timers The ERTM specification requires the retransmit timer to be cancelled when the monitor timer is set. The retransmit timer cannot be set again while the monitor timer is pending. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 4 ---- net/bluetooth/l2cap_core.c | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7d1da5a7d11e..117db8e4a5f4 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -706,11 +706,7 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) -#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ - msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) -#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ - msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8ea9ec648bfd..38e9a0ea4f48 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -227,6 +227,24 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) release_sock(sk); } +static void __set_retrans_timer(struct l2cap_chan *chan) +{ + if (!delayed_work_pending(&chan->monitor_timer) && + chan->retrans_timeout) { + l2cap_set_timer(chan, &chan->retrans_timer, + msecs_to_jiffies(chan->retrans_timeout)); + } +} + +static void __set_monitor_timer(struct l2cap_chan *chan) +{ + __clear_retrans_timer(chan); + if (chan->monitor_timeout) { + l2cap_set_timer(chan, &chan->monitor_timer, + msecs_to_jiffies(chan->monitor_timeout)); + } +} + static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head, u16 seq) { @@ -1619,7 +1637,7 @@ int __l2cap_wait_ack(struct sock *sk) static void l2cap_monitor_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - monitor_timer.work); + monitor_timer.work); BT_DBG("chan %p", chan); @@ -1643,7 +1661,7 @@ static void l2cap_monitor_timeout(struct work_struct *work) static void l2cap_retrans_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - retrans_timer.work); + retrans_timer.work); BT_DBG("chan %p", chan); -- GitLab From 80909e04de4dbbe76a220ccd5f9b32d8d5a8c22c Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:50 -0700 Subject: [PATCH 0288/6849] Bluetooth: Use the ERTM transmit state machine from timeout handlers Different states have different actions for retransmit and monitor timeouts, so remove the logic for those actions from the timer handlers. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 38e9a0ea4f48..3c5ae0e4c569 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1643,17 +1643,14 @@ static void l2cap_monitor_timeout(struct work_struct *work) l2cap_chan_lock(chan); - if (chan->retry_count >= chan->remote_max_tx) { - l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); + if (!chan->conn) { l2cap_chan_unlock(chan); l2cap_chan_put(chan); return; } - chan->retry_count++; - __set_monitor_timer(chan); + l2cap_tx(chan, 0, 0, L2CAP_EV_MONITOR_TO); - l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); l2cap_chan_unlock(chan); l2cap_chan_put(chan); } @@ -1667,13 +1664,13 @@ static void l2cap_retrans_timeout(struct work_struct *work) l2cap_chan_lock(chan); - chan->retry_count = 1; - __set_monitor_timer(chan); - - set_bit(CONN_WAIT_F, &chan->conn_state); - - l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); + if (!chan->conn) { + l2cap_chan_unlock(chan); + l2cap_chan_put(chan); + return; + } + l2cap_tx(chan, 0, 0, L2CAP_EV_RETRANS_TO); l2cap_chan_unlock(chan); l2cap_chan_put(chan); } -- GitLab From 0362520bf9d35f09c2693e14352f4b0ad07397fa Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:51 -0700 Subject: [PATCH 0289/6849] Bluetooth: Simplify the ERTM ack timeout Since l2cap_send_ack can trigger extra actions like sending iframes, don't call it. Just send an RR or RNR frame if an ack needs sending. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3c5ae0e4c569..293b78a6c644 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2761,16 +2761,20 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) static void l2cap_ack_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - ack_timer.work); + ack_timer.work); + u16 frames_to_ack; BT_DBG("chan %p", chan); l2cap_chan_lock(chan); - l2cap_send_ack(chan); + frames_to_ack = __seq_offset(chan, chan->buffer_seq, + chan->last_acked_seq); - l2cap_chan_unlock(chan); + if (frames_to_ack) + l2cap_send_rr_or_rnr(chan, 0); + l2cap_chan_unlock(chan); l2cap_chan_put(chan); } -- GitLab From 6ea0048575089e9a714e08bc3debec4b1b9d7664 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:52 -0700 Subject: [PATCH 0290/6849] Bluetooth: Remove unneccesary inline Let the compiler decide if inlining is appropriate. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 293b78a6c644..288c8e660377 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4399,7 +4399,7 @@ static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) return 0; } -static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) +static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { struct l2cap_ctrl control; -- GitLab From 273759e2c3bd69efe74799c446df69d9ea5ca418 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:53 -0700 Subject: [PATCH 0291/6849] Bluetooth: Set txwin values for streaming mode The transmit window values must be configured for streaming mode, even though streaming mode does not have a window. This enables use of extended headers when the transmit window socket option is set to 64 or larger. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 288c8e660377..db59b259297f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2941,6 +2941,7 @@ done: break; case L2CAP_MODE_STREAMING: + l2cap_txwin_setup(chan); rfc.mode = L2CAP_MODE_STREAMING; rfc.txwin_size = 0; rfc.max_transmit = 0; -- GitLab From 522cc2ee6e55ba49f4df338e0dfcfb989b46eb8c Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:54 -0700 Subject: [PATCH 0292/6849] Bluetooth: Remove unused ERTM control field macros Now that l2cap_ctrl is used to set up control fields, these macros are not needed. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 168 ---------------------------------- 1 file changed, 168 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 117db8e4a5f4..7bc40198f147 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -725,174 +725,6 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) return (seq + 1) % (chan->tx_win_max + 1); } -static inline int l2cap_tx_window_full(struct l2cap_chan *ch) -{ - int sub; - - sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64; - - if (sub < 0) - sub += 64; - - return sub == ch->remote_tx_win; -} - -static inline __u16 __get_reqseq(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (ctrl & L2CAP_EXT_CTRL_REQSEQ) >> - L2CAP_EXT_CTRL_REQSEQ_SHIFT; - else - return (ctrl & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT; -} - -static inline __u32 __set_reqseq(struct l2cap_chan *chan, __u32 reqseq) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT) & - L2CAP_EXT_CTRL_REQSEQ; - else - return (reqseq << L2CAP_CTRL_REQSEQ_SHIFT) & L2CAP_CTRL_REQSEQ; -} - -static inline __u16 __get_txseq(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (ctrl & L2CAP_EXT_CTRL_TXSEQ) >> - L2CAP_EXT_CTRL_TXSEQ_SHIFT; - else - return (ctrl & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT; -} - -static inline __u32 __set_txseq(struct l2cap_chan *chan, __u32 txseq) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT) & - L2CAP_EXT_CTRL_TXSEQ; - else - return (txseq << L2CAP_CTRL_TXSEQ_SHIFT) & L2CAP_CTRL_TXSEQ; -} - -static inline bool __is_sframe(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return ctrl & L2CAP_EXT_CTRL_FRAME_TYPE; - else - return ctrl & L2CAP_CTRL_FRAME_TYPE; -} - -static inline __u32 __set_sframe(struct l2cap_chan *chan) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return L2CAP_EXT_CTRL_FRAME_TYPE; - else - return L2CAP_CTRL_FRAME_TYPE; -} - -static inline __u8 __get_ctrl_sar(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (ctrl & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT; - else - return (ctrl & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT; -} - -static inline __u32 __set_ctrl_sar(struct l2cap_chan *chan, __u32 sar) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (sar << L2CAP_EXT_CTRL_SAR_SHIFT) & L2CAP_EXT_CTRL_SAR; - else - return (sar << L2CAP_CTRL_SAR_SHIFT) & L2CAP_CTRL_SAR; -} - -static inline bool __is_sar_start(struct l2cap_chan *chan, __u32 ctrl) -{ - return __get_ctrl_sar(chan, ctrl) == L2CAP_SAR_START; -} - -static inline __u32 __get_sar_mask(struct l2cap_chan *chan) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return L2CAP_EXT_CTRL_SAR; - else - return L2CAP_CTRL_SAR; -} - -static inline __u8 __get_ctrl_super(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (ctrl & L2CAP_EXT_CTRL_SUPERVISE) >> - L2CAP_EXT_CTRL_SUPER_SHIFT; - else - return (ctrl & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT; -} - -static inline __u32 __set_ctrl_super(struct l2cap_chan *chan, __u32 super) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return (super << L2CAP_EXT_CTRL_SUPER_SHIFT) & - L2CAP_EXT_CTRL_SUPERVISE; - else - return (super << L2CAP_CTRL_SUPER_SHIFT) & - L2CAP_CTRL_SUPERVISE; -} - -static inline __u32 __set_ctrl_final(struct l2cap_chan *chan) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return L2CAP_EXT_CTRL_FINAL; - else - return L2CAP_CTRL_FINAL; -} - -static inline bool __is_ctrl_final(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return ctrl & L2CAP_EXT_CTRL_FINAL; - else - return ctrl & L2CAP_CTRL_FINAL; -} - -static inline __u32 __set_ctrl_poll(struct l2cap_chan *chan) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return L2CAP_EXT_CTRL_POLL; - else - return L2CAP_CTRL_POLL; -} - -static inline bool __is_ctrl_poll(struct l2cap_chan *chan, __u32 ctrl) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return ctrl & L2CAP_EXT_CTRL_POLL; - else - return ctrl & L2CAP_CTRL_POLL; -} - -static inline __u32 __get_control(struct l2cap_chan *chan, void *p) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return get_unaligned_le32(p); - else - return get_unaligned_le16(p); -} - -static inline void __put_control(struct l2cap_chan *chan, __u32 control, - void *p) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return put_unaligned_le32(control, p); - else - return put_unaligned_le16(control, p); -} - -static inline __u8 __ctrl_size(struct l2cap_chan *chan) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return L2CAP_EXT_HDR_SIZE - L2CAP_HDR_SIZE; - else - return L2CAP_ENH_HDR_SIZE - L2CAP_HDR_SIZE; -} extern bool disable_ertm; -- GitLab From d1de6d46dc7b503d77ec59c849acacadfece1da1 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:55 -0700 Subject: [PATCH 0293/6849] Bluetooth: Enable ERTM by default This enables the new receive and transmit state machines. Signed-off-by: Mat Martineau Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index db59b259297f..b70dca4472a7 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -57,7 +57,7 @@ #include #include -bool disable_ertm = 1; +bool disable_ertm; static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, }; -- GitLab From ee556f662ca9e96a3cdb0d10745f9fd0cbf549af Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 18 May 2012 20:22:38 -0300 Subject: [PATCH 0294/6849] Bluetooth: Do not purge queue in Basic Mode chan->tx_q is only initialized if we use ERTM or Streaming mode. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b70dca4472a7..ae69da8d01e7 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -549,9 +549,11 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) return; - skb_queue_purge(&chan->tx_q); + switch(chan->mode) { + case L2CAP_MODE_BASIC: + break; - if (chan->mode == L2CAP_MODE_ERTM) { + case L2CAP_MODE_ERTM: __clear_retrans_timer(chan); __clear_monitor_timer(chan); __clear_ack_timer(chan); @@ -560,7 +562,15 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_seq_list_free(&chan->srej_list); l2cap_seq_list_free(&chan->retrans_list); + + /* fall through */ + + case L2CAP_MODE_STREAMING: + skb_queue_purge(&chan->tx_q); + break; } + + return; } static void l2cap_chan_cleanup_listen(struct sock *parent) -- GitLab From 401bb1f768c842b9fbfaeb7741cc5cf17c70ffd1 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 21 May 2012 15:47:46 +0300 Subject: [PATCH 0295/6849] Bluetooth: Silent sparse warnings Silence warnings below: net/bluetooth/l2cap_core.c:1662:24: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:1662:27: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:1683:24: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:1683:27: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:2260:46: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:2574:33: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:2581:33: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:4556:24: warning: Using plain integer as NULL pointer net/bluetooth/l2cap_core.c:4556:27: warning: Using plain integer as NULL pointer Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index ae69da8d01e7..c85a3a2a37bf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1659,7 +1659,7 @@ static void l2cap_monitor_timeout(struct work_struct *work) return; } - l2cap_tx(chan, 0, 0, L2CAP_EV_MONITOR_TO); + l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO); l2cap_chan_unlock(chan); l2cap_chan_put(chan); @@ -1680,7 +1680,7 @@ static void l2cap_retrans_timeout(struct work_struct *work) return; } - l2cap_tx(chan, 0, 0, L2CAP_EV_RETRANS_TO); + l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO); l2cap_chan_unlock(chan); l2cap_chan_put(chan); } @@ -2257,7 +2257,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, break; if (chan->mode == L2CAP_MODE_ERTM) - err = l2cap_tx(chan, 0, &seg_queue, + err = l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST); else err = l2cap_streaming_send(chan, &seg_queue); @@ -2571,14 +2571,14 @@ static void l2cap_pass_to_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control) { BT_DBG("chan %p, control %p", chan, control); - l2cap_tx(chan, control, 0, L2CAP_EV_RECV_REQSEQ_AND_FBIT); + l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT); } static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { BT_DBG("chan %p, control %p", chan, control); - l2cap_tx(chan, control, 0, L2CAP_EV_RECV_FBIT); + l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT); } /* Copy frame to all raw sockets on that connection */ @@ -4553,7 +4553,7 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) return; event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR; - l2cap_tx(chan, 0, 0, event); + l2cap_tx(chan, NULL, NULL, event); } static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) -- GitLab From be4aad05af0ec949a91e7bbaa55c02a954714473 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 21 May 2012 13:58:21 -0300 Subject: [PATCH 0296/6849] Bluetooth: Remove double check for BT_CONNECTED The same check is done just before call l2cap_streaming_send() Signed-off-by: Gustavo Padovan Reviewed-by: Mat Martineau Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c85a3a2a37bf..5bf828753a93 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1693,9 +1693,6 @@ static int l2cap_streaming_send(struct l2cap_chan *chan, BT_DBG("chan %p, skbs %p", chan, skbs); - if (chan->state != BT_CONNECTED) - return -ENOTCONN; - skb_queue_splice_tail_init(skbs, &chan->tx_q); while (!skb_queue_empty(&chan->tx_q)) { -- GitLab From d660366d53119fbd988e1b1d6ea2c00358a8e688 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 21 May 2012 13:58:22 -0300 Subject: [PATCH 0297/6849] Bluetooth: Remove dead int returns These functions were returning always 0, we just make then void. Signed-off-by: Gustavo Padovan Reviewed-by: Mat Martineau Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 48 +++++++++++++------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5bf828753a93..b644f4085f49 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -73,7 +73,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); -static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, +static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event); /* ---- L2CAP channels ---- */ @@ -1685,8 +1685,8 @@ static void l2cap_retrans_timeout(struct work_struct *work) l2cap_chan_put(chan); } -static int l2cap_streaming_send(struct l2cap_chan *chan, - struct sk_buff_head *skbs) +static void l2cap_streaming_send(struct l2cap_chan *chan, + struct sk_buff_head *skbs) { struct sk_buff *skb; struct l2cap_ctrl *control; @@ -1719,8 +1719,6 @@ static int l2cap_streaming_send(struct l2cap_chan *chan, chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); chan->frames_sent++; } - - return 0; } static int l2cap_ertm_send(struct l2cap_chan *chan) @@ -2254,13 +2252,11 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, break; if (chan->mode == L2CAP_MODE_ERTM) - err = l2cap_tx(chan, NULL, &seg_queue, - L2CAP_EV_DATA_REQUEST); + l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST); else - err = l2cap_streaming_send(chan, &seg_queue); + l2cap_streaming_send(chan, &seg_queue); - if (!err) - err = len; + err = len; /* If the skbs were not queued for sending, they'll still be in * seg_queue and need to be purged. @@ -2383,12 +2379,10 @@ static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) chan->rx_state = L2CAP_RX_STATE_RECV; } -static int l2cap_tx_state_xmit(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event) +static void l2cap_tx_state_xmit(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event) { - int err = 0; - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, event); @@ -2455,16 +2449,12 @@ static int l2cap_tx_state_xmit(struct l2cap_chan *chan, default: break; } - - return err; } -static int l2cap_tx_state_wait_f(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event) +static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event) { - int err = 0; - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, event); @@ -2537,31 +2527,25 @@ static int l2cap_tx_state_wait_f(struct l2cap_chan *chan, default: break; } - - return err; } -static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event) +static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + struct sk_buff_head *skbs, u8 event) { - int err = 0; - BT_DBG("chan %p, control %p, skbs %p, event %d, state %d", chan, control, skbs, event, chan->tx_state); switch (chan->tx_state) { case L2CAP_TX_STATE_XMIT: - err = l2cap_tx_state_xmit(chan, control, skbs, event); + l2cap_tx_state_xmit(chan, control, skbs, event); break; case L2CAP_TX_STATE_WAIT_F: - err = l2cap_tx_state_wait_f(chan, control, skbs, event); + l2cap_tx_state_wait_f(chan, control, skbs, event); break; default: /* Ignore event */ break; } - - return err; } static void l2cap_pass_to_tx(struct l2cap_chan *chan, -- GitLab From 38351c66e407e610283e5332b819822055db473c Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Tue, 22 May 2012 19:00:20 -0300 Subject: [PATCH 0298/6849] Bluetooth: Fix trailing whitespaces in license text As reported by checkpatch.pl Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- include/net/bluetooth/bluetooth.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 961669b648fd..b98181bd2b33 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -1,4 +1,4 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated @@ -12,13 +12,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ -- GitLab From a6c511c636848f871f5b7aef38e25e5b894b3b48 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 23 May 2012 12:35:46 +0200 Subject: [PATCH 0299/6849] Bluetooth: Rename HCI_QUIRK_NO_RESET to HCI_QUIRK_RESET_ON_CLOSE HCI_QUIRK_NO_RESET name is misleading - purpose of this quirk is to reset device on close instead of init, not to not reset at all. Rename it to HCI_QUIRK_RESET_ON_CLOSE to avoid confusion. Signed-off-by: Szymon Janc Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bpa10x.c | 2 +- drivers/bluetooth/btusb.c | 6 +++--- drivers/bluetooth/hci_ldisc.c | 2 +- include/net/bluetooth/hci.h | 2 +- net/bluetooth/hci_core.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 609861a53c28..29caaed2d715 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -470,7 +470,7 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id * hdev->flush = bpa10x_flush; hdev->send = bpa10x_send_frame; - set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); err = hci_register_dev(hdev); if (err < 0) { diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c9463af8e564..3a6cdc9b75a3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1026,7 +1026,7 @@ static int btusb_probe(struct usb_interface *intf, data->isoc = usb_ifnum_to_if(data->udev, 1); if (!reset) - set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) { if (!disable_scofix) @@ -1038,7 +1038,7 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_DIGIANSWER) { data->cmdreq_type = USB_TYPE_VENDOR; - set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); } if (id->driver_info & BTUSB_CSR) { @@ -1046,7 +1046,7 @@ static int btusb_probe(struct usb_interface *intf, /* Old firmware would otherwise execute USB reset */ if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117) - set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); } if (id->driver_info & BTUSB_SNIFFER) { diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index e564579a6115..2f9b796e106e 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -394,7 +394,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags)) - set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) hdev->dev_type = HCI_AMP; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 66a7b579e31c..97c57aa938f3 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -58,7 +58,7 @@ /* HCI device quirks */ enum { - HCI_QUIRK_NO_RESET, + HCI_QUIRK_RESET_ON_CLOSE, HCI_QUIRK_RAW_DEVICE, HCI_QUIRK_FIXUP_BUFFER_SIZE }; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d0a960dabd53..0ed4edf0f77b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -203,7 +203,7 @@ static void bredr_init(struct hci_dev *hdev) /* Mandatory initialization */ /* Reset */ - if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { + if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { set_bit(HCI_RESET, &hdev->flags); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); } @@ -792,7 +792,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) skb_queue_purge(&hdev->cmd_q); atomic_set(&hdev->cmd_cnt, 1); if (!test_bit(HCI_RAW, &hdev->flags) && - test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { + test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { set_bit(HCI_INIT, &hdev->flags); __hci_request(hdev, hci_reset_req, 0, msecs_to_jiffies(250)); -- GitLab From 9b3b44604ac8e06d299718c5d0fa0b91b675ae0b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 23 May 2012 11:31:20 +0300 Subject: [PATCH 0300/6849] Bluetooth: Use defined link key size Remove magic number with defined link key size. Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci.h | 6 ++++-- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_core.c | 2 +- net/bluetooth/hci_event.c | 2 +- net/bluetooth/mgmt.c | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 97c57aa938f3..0bc5555510f3 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -30,6 +30,8 @@ #define HCI_MAX_EVENT_SIZE 260 #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) +#define HCI_LINK_KEY_SIZE 16 + /* HCI dev events */ #define HCI_DEV_REG 1 #define HCI_DEV_UNREG 2 @@ -371,7 +373,7 @@ struct hci_cp_reject_conn_req { #define HCI_OP_LINK_KEY_REPLY 0x040b struct hci_cp_link_key_reply { bdaddr_t bdaddr; - __u8 link_key[16]; + __u8 link_key[HCI_LINK_KEY_SIZE]; } __packed; #define HCI_OP_LINK_KEY_NEG_REPLY 0x040c @@ -1048,7 +1050,7 @@ struct hci_ev_link_key_req { #define HCI_EV_LINK_KEY_NOTIFY 0x18 struct hci_ev_link_key_notify { bdaddr_t bdaddr; - __u8 link_key[16]; + __u8 link_key[HCI_LINK_KEY_SIZE]; __u8 key_type; } __packed; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 9fc7728f94e4..6c658fc7ac93 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -105,7 +105,7 @@ struct link_key { struct list_head list; bdaddr_t bdaddr; u8 type; - u8 val[16]; + u8 val[HCI_LINK_KEY_SIZE]; u8 pin_len; }; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 0ed4edf0f77b..027257d4b52a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1291,7 +1291,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, } bacpy(&key->bdaddr, bdaddr); - memcpy(key->val, val, 16); + memcpy(key->val, val, HCI_LINK_KEY_SIZE); key->pin_len = pin_len; if (type == HCI_LK_CHANGED_COMBINATION) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6c2d7ccf26e5..1795c0c9b411 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2739,7 +2739,7 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, } bacpy(&cp.bdaddr, &ev->bdaddr); - memcpy(cp.link_key, key->val, 16); + memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 6a7e926c418f..1fd49e652694 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2955,7 +2955,7 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bacpy(&ev.key.addr.bdaddr, &key->bdaddr); ev.key.addr.type = BDADDR_BREDR; ev.key.type = key->type; - memcpy(ev.key.val, key->val, 16); + memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); ev.key.pin_len = key->pin_len; return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); -- GitLab From 5325e5bb86f6dd2977f0891b9eaff57293538d50 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 23 May 2012 11:31:22 +0300 Subject: [PATCH 0301/6849] Bluetooth: Preserve L2CAP flags values Previous callers of l2cap_build_conf_rsp in l2cap_config_req use flags instead of continuation flag hardcoded value. It does not change logic and preserve future possible flags. Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b644f4085f49..db76a7750ee6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3641,7 +3641,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr /* Incomplete config. Send empty response. */ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, - L2CAP_CONF_SUCCESS, 0x0001), rsp); + L2CAP_CONF_SUCCESS, flags), rsp); goto unlock; } @@ -3697,7 +3697,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, - L2CAP_CONF_SUCCESS, 0x0000), rsp); + L2CAP_CONF_SUCCESS, flags), rsp); } unlock: -- GitLab From 4f42a8cd4905e69ba4dd694d9338aeee1bb7e9ab Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 23 May 2012 11:31:23 +0300 Subject: [PATCH 0302/6849] Bluetooth: trivial: Remove empty line Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_conn.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 971601e0ad4a..da9f827241d0 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -425,7 +425,6 @@ int hci_conn_del(struct hci_conn *conn) } } - hci_chan_list_flush(conn); hci_conn_hash_del(hdev, conn); -- GitLab From 6039aa73a1323edc2d6d93a22505d4dc28f38e3f Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 23 May 2012 04:04:18 -0300 Subject: [PATCH 0303/6849] Bluetooth: Remove most of the inline usage Only obvious cases were left as inline, mostly oneline functions. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/bnep/core.c | 4 +- net/bluetooth/bnep/netdev.c | 6 +- net/bluetooth/hci_core.c | 33 +++++---- net/bluetooth/hci_event.c | 144 +++++++++++++++--------------------- net/bluetooth/hci_sock.c | 6 +- net/bluetooth/hidp/core.c | 4 +- net/bluetooth/mgmt.c | 2 +- net/bluetooth/rfcomm/core.c | 18 ++--- net/bluetooth/rfcomm/tty.c | 4 +- net/bluetooth/sco.c | 9 ++- 10 files changed, 104 insertions(+), 126 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 031d7d656754..a918f6e4f003 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -306,7 +306,7 @@ static u8 __bnep_rx_hlen[] = { ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */ }; -static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) +static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) { struct net_device *dev = s->dev; struct sk_buff *nskb; @@ -404,7 +404,7 @@ static u8 __bnep_tx_types[] = { BNEP_COMPRESSED }; -static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) +static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) { struct ethhdr *eh = (void *) skb->data; struct socket *sock = s->sock; diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index bc4086480d97..46c9ece7b04a 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -128,7 +128,7 @@ static void bnep_net_timeout(struct net_device *dev) } #ifdef CONFIG_BT_BNEP_MC_FILTER -static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s) +static int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s) { struct ethhdr *eh = (void *) skb->data; @@ -140,7 +140,7 @@ static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s #ifdef CONFIG_BT_BNEP_PROTO_FILTER /* Determine ether protocol. Based on eth_type_trans. */ -static inline u16 bnep_net_eth_proto(struct sk_buff *skb) +static u16 bnep_net_eth_proto(struct sk_buff *skb) { struct ethhdr *eh = (void *) skb->data; u16 proto = ntohs(eh->h_proto); @@ -154,7 +154,7 @@ static inline u16 bnep_net_eth_proto(struct sk_buff *skb) return ETH_P_802_2; } -static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) +static int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) { u16 proto = bnep_net_eth_proto(skb); struct bnep_proto_filter *f = s->proto_filter; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 027257d4b52a..2dc61d38bf62 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -167,8 +167,9 @@ static int __hci_request(struct hci_dev *hdev, return err; } -static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), - unsigned long opt, __u32 timeout) +static int hci_request(struct hci_dev *hdev, + void (*req)(struct hci_dev *hdev, unsigned long opt), + unsigned long opt, __u32 timeout) { int ret; @@ -2245,8 +2246,8 @@ EXPORT_SYMBOL(hci_send_sco); /* ---- HCI TX task (outgoing data) ---- */ /* HCI Connection scheduler */ -static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, - int *quote) +static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, + int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL, *c; @@ -2305,7 +2306,7 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, return conn; } -static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) +static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *c; @@ -2326,8 +2327,8 @@ static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) rcu_read_unlock(); } -static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, - int *quote) +static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, + int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_chan *chan = NULL; @@ -2461,7 +2462,7 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); } -static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) +static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) { if (!test_bit(HCI_RAW, &hdev->flags)) { /* ACL tx timeout must be longer than maximum @@ -2472,7 +2473,7 @@ static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) } } -static inline void hci_sched_acl_pkt(struct hci_dev *hdev) +static void hci_sched_acl_pkt(struct hci_dev *hdev) { unsigned int cnt = hdev->acl_cnt; struct hci_chan *chan; @@ -2510,7 +2511,7 @@ static inline void hci_sched_acl_pkt(struct hci_dev *hdev) hci_prio_recalculate(hdev, ACL_LINK); } -static inline void hci_sched_acl_blk(struct hci_dev *hdev) +static void hci_sched_acl_blk(struct hci_dev *hdev) { unsigned int cnt = hdev->block_cnt; struct hci_chan *chan; @@ -2556,7 +2557,7 @@ static inline void hci_sched_acl_blk(struct hci_dev *hdev) hci_prio_recalculate(hdev, ACL_LINK); } -static inline void hci_sched_acl(struct hci_dev *hdev) +static void hci_sched_acl(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); @@ -2575,7 +2576,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev) } /* Schedule SCO */ -static inline void hci_sched_sco(struct hci_dev *hdev) +static void hci_sched_sco(struct hci_dev *hdev) { struct hci_conn *conn; struct sk_buff *skb; @@ -2598,7 +2599,7 @@ static inline void hci_sched_sco(struct hci_dev *hdev) } } -static inline void hci_sched_esco(struct hci_dev *hdev) +static void hci_sched_esco(struct hci_dev *hdev) { struct hci_conn *conn; struct sk_buff *skb; @@ -2621,7 +2622,7 @@ static inline void hci_sched_esco(struct hci_dev *hdev) } } -static inline void hci_sched_le(struct hci_dev *hdev) +static void hci_sched_le(struct hci_dev *hdev) { struct hci_chan *chan; struct sk_buff *skb; @@ -2698,7 +2699,7 @@ static void hci_tx_work(struct work_struct *work) /* ----- HCI RX task (incoming data processing) ----- */ /* ACL data packet */ -static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_acl_hdr *hdr = (void *) skb->data; struct hci_conn *conn; @@ -2742,7 +2743,7 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) } /* SCO data packet */ -static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_sco_hdr *hdr = (void *) skb->data; struct hci_conn *conn; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 1795c0c9b411..75b03fc78002 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1157,8 +1157,8 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); } -static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_write_le_host_supported(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_cp_write_le_host_supported *sent; __u8 status = *((__u8 *) skb->data); @@ -1183,7 +1183,7 @@ static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); } -static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) +static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%x", hdev->name, status); @@ -1204,7 +1204,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) hci_dev_unlock(hdev); } -static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) +static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) { struct hci_cp_create_conn *cp; struct hci_conn *conn; @@ -1351,7 +1351,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, return 1; } -static inline int hci_resolve_name(struct hci_dev *hdev, +static int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e) { struct hci_cp_remote_name_req cp; @@ -1668,8 +1668,7 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) BT_DBG("%s status 0x%x", hdev->name, status); } -static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); struct discovery_state *discov = &hdev->discovery; @@ -1709,8 +1708,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_inquiry_result_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct inquiry_data data; struct inquiry_info *info = (void *) (skb->data + 1); @@ -1747,8 +1745,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_conn_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1826,8 +1823,7 @@ unlock: hci_conn_check_pending(hdev); } -static inline void hci_conn_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_request *ev = (void *) skb->data; int mask = hdev->link_mode; @@ -1901,8 +1897,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, } } -static inline void hci_disconn_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_disconn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1939,8 +1934,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_auth_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_auth_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -2006,7 +2000,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_name *ev = (void *) skb->data; struct hci_conn *conn; @@ -2045,8 +2039,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_encrypt_change_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_encrypt_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2089,8 +2082,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_change_link_key_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_change_link_key_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -2112,8 +2105,8 @@ static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_remote_features_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_remote_features_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; @@ -2162,20 +2155,18 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_remote_version_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_qos_setup_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static inline void hci_cmd_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_cmd_complete *ev = (void *) skb->data; __u16 opcode; @@ -2396,7 +2387,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, } } -static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_cmd_status *ev = (void *) skb->data; __u16 opcode; @@ -2477,8 +2468,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) } } -static inline void hci_role_change_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_role_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2504,8 +2494,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_num_comp_pkts *ev = (void *) skb->data; int i; @@ -2571,8 +2560,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, queue_work(hdev->workqueue, &hdev->tx_work); } -static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_num_comp_blocks *ev = (void *) skb->data; int i; @@ -2621,8 +2609,7 @@ static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, queue_work(hdev->workqueue, &hdev->tx_work); } -static inline void hci_mode_change_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_mode_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2650,8 +2637,7 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_pin_code_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pin_code_req *ev = (void *) skb->data; struct hci_conn *conn; @@ -2688,8 +2674,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_link_key_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_link_key_req *ev = (void *) skb->data; struct hci_cp_link_key_reply cp; @@ -2752,8 +2737,7 @@ not_found: hci_dev_unlock(hdev); } -static inline void hci_link_key_notify_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_link_key_notify *ev = (void *) skb->data; struct hci_conn *conn; @@ -2782,8 +2766,7 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_clock_offset_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_clock_offset *ev = (void *) skb->data; struct hci_conn *conn; @@ -2806,8 +2789,7 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pkt_type_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2823,8 +2805,7 @@ static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; struct inquiry_entry *ie; @@ -2842,8 +2823,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct inquiry_data data; int num_rsp = *((__u8 *) skb->data); @@ -2902,8 +2883,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_remote_ext_features_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_ext_features *ev = (void *) skb->data; struct hci_conn *conn; @@ -2951,8 +2932,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_sync_conn_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_sync_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3007,22 +2988,20 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_sniff_subrate *ev = (void *) skb->data; BT_DBG("%s status %d", hdev->name, ev->status); } -static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct inquiry_data data; struct extended_inquiry_info *info = (void *) (skb->data + 1); @@ -3069,7 +3048,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline u8 hci_get_auth_req(struct hci_conn *conn) +static u8 hci_get_auth_req(struct hci_conn *conn) { /* If remote requests dedicated bonding follow that lead */ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) { @@ -3088,8 +3067,7 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn) return conn->auth_type; } -static inline void hci_io_capa_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_io_capa_request *ev = (void *) skb->data; struct hci_conn *conn; @@ -3141,8 +3119,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_io_capa_reply *ev = (void *) skb->data; struct hci_conn *conn; @@ -3164,8 +3141,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_user_confirm_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_user_confirm_req *ev = (void *) skb->data; int loc_mitm, rem_mitm, confirm_hint = 0; @@ -3232,8 +3209,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_user_passkey_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_user_passkey_req *ev = (void *) skb->data; @@ -3247,8 +3224,8 @@ static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_simple_pair_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_simple_pair_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3276,8 +3253,8 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_remote_host_features_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_remote_host_features_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_host_features *ev = (void *) skb->data; struct inquiry_entry *ie; @@ -3293,8 +3270,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; struct oob_data *data; @@ -3328,8 +3305,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3376,8 +3352,7 @@ unlock: hci_dev_unlock(hdev); } -static inline void hci_le_adv_report_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) { u8 num_reports = skb->data[0]; void *ptr = &skb->data[1]; @@ -3398,8 +3373,7 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_ltk_req *ev = (void *) skb->data; struct hci_cp_le_ltk_reply cp; @@ -3442,7 +3416,7 @@ not_found: hci_dev_unlock(hdev); } -static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_meta *le_ev = (void *) skb->data; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index bdf51d1d2c19..89767ad095de 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -496,7 +496,8 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) } /* Ioctls that require bound socket */ -static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) +static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, + unsigned long arg) { struct hci_dev *hdev = hci_pi(sk)->hdev; @@ -712,7 +713,8 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *add return 0; } -static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) +static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, + struct sk_buff *skb) { __u32 mask = hci_pi(sk)->cmsg_mask; diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 2c20d765b394..c8625b8ccb6a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -268,7 +268,7 @@ static int __hidp_send_ctrl_message(struct hidp_session *session, return 0; } -static inline int hidp_send_ctrl_message(struct hidp_session *session, +static int hidp_send_ctrl_message(struct hidp_session *session, unsigned char hdr, unsigned char *data, int size) { int err; @@ -471,7 +471,7 @@ static void hidp_set_timer(struct hidp_session *session) mod_timer(&session->timer, jiffies + HZ * session->idle_to); } -static inline void hidp_del_timer(struct hidp_session *session) +static void hidp_del_timer(struct hidp_session *session) { if (session->idle_to > 0) del_timer(&session->timer); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 1fd49e652694..df03c7d20331 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1821,7 +1821,7 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, 0); } -static inline struct pending_cmd *find_pairing(struct hci_conn *conn) +static struct pending_cmd *find_pairing(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; struct pending_cmd *cmd; diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 8a602388f1e7..585d3916d3d4 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -115,14 +115,14 @@ static void rfcomm_session_del(struct rfcomm_session *s); #define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1) #define __get_rpn_parity(line) (((line) >> 3) & 0x7) -static inline void rfcomm_schedule(void) +static void rfcomm_schedule(void) { if (!rfcomm_thread) return; wake_up_process(rfcomm_thread); } -static inline void rfcomm_session_put(struct rfcomm_session *s) +static void rfcomm_session_put(struct rfcomm_session *s) { if (atomic_dec_and_test(&s->refcnt)) rfcomm_session_del(s); @@ -227,7 +227,7 @@ static int rfcomm_l2sock_create(struct socket **sock) return err; } -static inline int rfcomm_check_security(struct rfcomm_dlc *d) +static int rfcomm_check_security(struct rfcomm_dlc *d) { struct sock *sk = d->session->sock->sk; struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; @@ -1750,7 +1750,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s) /* Send data queued for the DLC. * Return number of frames left in the queue. */ -static inline int rfcomm_process_tx(struct rfcomm_dlc *d) +static int rfcomm_process_tx(struct rfcomm_dlc *d) { struct sk_buff *skb; int err; @@ -1798,7 +1798,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d) return skb_queue_len(&d->tx_queue); } -static inline void rfcomm_process_dlcs(struct rfcomm_session *s) +static void rfcomm_process_dlcs(struct rfcomm_session *s) { struct rfcomm_dlc *d; struct list_head *p, *n; @@ -1858,7 +1858,7 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) } } -static inline void rfcomm_process_rx(struct rfcomm_session *s) +static void rfcomm_process_rx(struct rfcomm_session *s) { struct socket *sock = s->sock; struct sock *sk = sock->sk; @@ -1883,7 +1883,7 @@ static inline void rfcomm_process_rx(struct rfcomm_session *s) } } -static inline void rfcomm_accept_connection(struct rfcomm_session *s) +static void rfcomm_accept_connection(struct rfcomm_session *s) { struct socket *sock = s->sock, *nsock; int err; @@ -1917,7 +1917,7 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) sock_release(nsock); } -static inline void rfcomm_check_connection(struct rfcomm_session *s) +static void rfcomm_check_connection(struct rfcomm_session *s) { struct sock *sk = s->sock->sk; @@ -1941,7 +1941,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s) } } -static inline void rfcomm_process_sessions(void) +static void rfcomm_process_sessions(void) { struct list_head *p, *n; diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index d1820ff14aee..f2f4d064df94 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -132,7 +132,7 @@ static struct rfcomm_dev *__rfcomm_dev_get(int id) return NULL; } -static inline struct rfcomm_dev *rfcomm_dev_get(int id) +static struct rfcomm_dev *rfcomm_dev_get(int id) { struct rfcomm_dev *dev; @@ -345,7 +345,7 @@ static void rfcomm_wfree(struct sk_buff *skb) tty_port_put(&dev->port); } -static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) +static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) { tty_port_get(&dev->port); atomic_add(skb->truesize, &dev->wmem_alloc); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 78473ff7cc8d..824ae2fd15eb 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -123,7 +123,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) return conn; } -static inline struct sock *sco_chan_get(struct sco_conn *conn) +static struct sock *sco_chan_get(struct sco_conn *conn) { struct sock *sk = NULL; sco_conn_lock(conn); @@ -157,7 +157,8 @@ static int sco_conn_del(struct hci_conn *hcon, int err) return 0; } -static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) +static int sco_chan_add(struct sco_conn *conn, struct sock *sk, + struct sock *parent) { int err = 0; @@ -228,7 +229,7 @@ done: return err; } -static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) +static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) { struct sco_conn *conn = sco_pi(sk)->conn; struct sk_buff *skb; @@ -254,7 +255,7 @@ static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) return len; } -static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) +static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) { struct sock *sk = sco_chan_get(conn); -- GitLab From fc5fef615a963c8b13abf0bbc2a8e8d7c3fd1ffb Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 23 May 2012 04:04:19 -0300 Subject: [PATCH 0304/6849] Bluetooth: Remove 'register' usage from the subsystem Let the compiler chooses what is best. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bluecard_cs.c | 10 +++++----- drivers/bluetooth/bt3c_cs.c | 4 ++-- drivers/bluetooth/btuart_cs.c | 4 ++-- drivers/bluetooth/dtl1_cs.c | 4 ++-- drivers/bluetooth/hci_bcsp.c | 2 +- drivers/bluetooth/hci_h4.c | 2 +- drivers/bluetooth/hci_ll.c | 6 +++--- net/bluetooth/hci_conn.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/bluetooth/sco.c | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 1fcd92380356..585c88e01893 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -231,12 +231,12 @@ static void bluecard_write_wakeup(bluecard_info_t *info) } do { - register unsigned int iobase = info->p_dev->resource[0]->start; - register unsigned int offset; - register unsigned char command; - register unsigned long ready_bit; + unsigned int iobase = info->p_dev->resource[0]->start; + unsigned int offset; + unsigned char command; + unsigned long ready_bit; register struct sk_buff *skb; - register int len; + int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 308c8599ab55..b2b0fbbb43b5 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -186,9 +186,9 @@ static void bt3c_write_wakeup(bt3c_info_t *info) return; do { - register unsigned int iobase = info->p_dev->resource[0]->start; + unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; - register int len; + int len; if (!pcmcia_dev_present(info->p_dev)) break; diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index c4fc2f3fc32c..65b8d996840c 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -140,9 +140,9 @@ static void btuart_write_wakeup(btuart_info_t *info) } do { - register unsigned int iobase = info->p_dev->resource[0]->start; + unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; - register int len; + int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 6e8d96189684..b1b37ccd3cd4 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -144,9 +144,9 @@ static void dtl1_write_wakeup(dtl1_info_t *info) } do { - register unsigned int iobase = info->p_dev->resource[0]->start; + unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; - register int len; + int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 661a8dc4d2f8..57e502e06080 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -552,7 +552,7 @@ static u16 bscp_get_crc(struct bcsp_struct *bcsp) static int bcsp_recv(struct hci_uart *hu, void *data, int count) { struct bcsp_struct *bcsp = hu->priv; - register unsigned char *ptr; + unsigned char *ptr; BT_DBG("hu %p count %d rx_state %d rx_count %ld", hu, count, bcsp->rx_state, bcsp->rx_count); diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 748329468d26..c60623f206d4 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -126,7 +126,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) static inline int h4_check_data_len(struct h4_struct *h4, int len) { - register int room = skb_tailroom(h4->rx_skb); + int room = skb_tailroom(h4->rx_skb); BT_DBG("len %d room %d", len, room); diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index b874c0efde24..ff6d589c34a5 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -348,7 +348,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) static inline int ll_check_data_len(struct ll_struct *ll, int len) { - register int room = skb_tailroom(ll->rx_skb); + int room = skb_tailroom(ll->rx_skb); BT_DBG("len %d room %d", len, room); @@ -374,11 +374,11 @@ static inline int ll_check_data_len(struct ll_struct *ll, int len) static int ll_recv(struct hci_uart *hu, void *data, int count) { struct ll_struct *ll = hu->priv; - register char *ptr; + char *ptr; struct hci_event_hdr *eh; struct hci_acl_hdr *ah; struct hci_sco_hdr *sh; - register int len, type, dlen; + int len, type, dlen; BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count); diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index da9f827241d0..0d73577b84cb 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -799,7 +799,7 @@ EXPORT_SYMBOL(hci_conn_put_device); int hci_get_conn_list(void __user *arg) { - register struct hci_conn *c; + struct hci_conn *c; struct hci_conn_list_req req, *cl; struct hci_conn_info *ci; struct hci_dev *hdev; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 89767ad095de..c1e0c3df5e6c 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -118,7 +118,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) continue; if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) { - register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); + int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); if (!hci_test_bit(evt, &flt->event_mask)) continue; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 824ae2fd15eb..6401ccae2045 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -908,7 +908,7 @@ done: /* ----- SCO interface with lower layer (HCI) ----- */ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) { - register struct sock *sk; + struct sock *sk; struct hlist_node *node; int lm = 0; -- GitLab From c3c7ea65941a0b7a4f1b9655e7aaaab6ce1874d2 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 23 May 2012 04:04:20 -0300 Subject: [PATCH 0305/6849] Bluetooth: Fix coding style in include/net/bluetooth Fix all warning and errors reported by checkpatch but license trailing whitespace and bdaddr_t definition. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- include/net/bluetooth/bluetooth.h | 26 ++++++++++++++------------ include/net/bluetooth/hci.h | 4 ++-- include/net/bluetooth/hci_core.h | 12 +++++++----- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index b98181bd2b33..7a9f9612db5a 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -25,7 +25,7 @@ #ifndef __BLUETOOTH_H #define __BLUETOOTH_H -#include +#include #include #include #include @@ -168,8 +168,8 @@ typedef struct { #define BDADDR_LE_PUBLIC 0x01 #define BDADDR_LE_RANDOM 0x02 -#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) -#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} }) +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) /* Copy, swap, convert BD Address */ static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) @@ -215,7 +215,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); -uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); +uint bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait); int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); @@ -225,12 +225,12 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); /* Skb helpers */ struct l2cap_ctrl { - unsigned int sframe : 1, - poll : 1, - final : 1, - fcs : 1, - sar : 2, - super : 2; + unsigned int sframe:1, + poll:1, + final:1, + fcs:1, + sar:2, + super:2; __u16 reqseq; __u16 txseq; __u8 retries; @@ -249,7 +249,8 @@ static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) { struct sk_buff *skb; - if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) { + skb = alloc_skb(len + BT_SKB_RESERVE, how); + if (skb) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } @@ -261,7 +262,8 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, { struct sk_buff *skb; - if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { + skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err); + if (skb) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 0bc5555510f3..5de351e49d49 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1309,12 +1309,12 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) } /* Command opcode pack/unpack */ -#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10)) +#define hci_opcode_pack(ogf, ocf) ((__u16) ((ocf & 0x03ff)|(ogf << 10))) #define hci_opcode_ogf(op) (op >> 10) #define hci_opcode_ocf(op) (op & 0x03ff) /* ACL handle and flags pack/unpack */ -#define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12)) +#define hci_handle_pack(h, f) ((__u16) ((h & 0x0fff)|(f << 12))) #define hci_handle(h) (h & 0x0fff) #define hci_flags(h) (h >> 12) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6c658fc7ac93..a8ba50d7a81e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -65,7 +65,7 @@ struct discovery_state { DISCOVERY_RESOLVING, DISCOVERY_STOPPING, } state; - struct list_head all; /* All devices found during inquiry */ + struct list_head all; /* All devices found during inquiry */ struct list_head unknown; /* Name state not known */ struct list_head resolve; /* Name needs to be resolved */ __u32 timestamp; @@ -360,7 +360,8 @@ extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status); extern int l2cap_disconn_ind(struct hci_conn *hcon); extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); -extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); +extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, + u16 flags); extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status); @@ -429,8 +430,8 @@ enum { static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - return (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && - test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)); + return test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && + test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); } static inline void hci_conn_hash_init(struct hci_dev *hdev) @@ -661,7 +662,8 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); int hci_inquiry(void __user *arg); -struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); +struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, + bdaddr_t *bdaddr); int hci_blacklist_clear(struct hci_dev *hdev); int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); -- GitLab From 8fc9ced398824739d3c25c8aa7f6f34d8e7a49d9 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 23 May 2012 04:04:21 -0300 Subject: [PATCH 0306/6849] Bluetooth: Fix coding style in the subsystem This is some leftover from the last patches that fixed style. It is mostly line over 80 characters fixes reported by checkpatch.pl. checkpatch.pl is clean for these files now. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/af_bluetooth.c | 3 ++- net/bluetooth/hci_conn.c | 3 ++- net/bluetooth/hci_core.c | 7 +++++-- net/bluetooth/hci_event.c | 23 ++++++++++++++--------- net/bluetooth/hci_sock.c | 21 ++++++++++++++------- net/bluetooth/hci_sysfs.c | 4 ++-- net/bluetooth/lib.c | 2 +- net/bluetooth/mgmt.c | 12 ++++++++---- 8 files changed, 48 insertions(+), 27 deletions(-) diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 46e7f86acfc9..e31a20f5b6be 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -418,7 +418,8 @@ static inline unsigned int bt_accept_poll(struct sock *parent) return 0; } -unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait) +unsigned int bt_sock_poll(struct file *file, struct socket *sock, + poll_table *wait) { struct sock *sk = sock->sk; unsigned int mask = 0; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 0d73577b84cb..231fc4400f37 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -453,7 +453,8 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) read_lock(&hci_dev_list_lock); list_for_each_entry(d, &hci_dev_list, list) { - if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) + if (!test_bit(HCI_UP, &d->flags) || + test_bit(HCI_RAW, &d->flags)) continue; /* Simple routing: diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 2dc61d38bf62..bee425ad25b5 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -622,7 +622,9 @@ int hci_inquiry(void __user *arg) goto done; } - /* for unlimited number of responses we will use buffer with 255 entries */ + /* for unlimited number of responses we will use buffer with + * 255 entries + */ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; /* cache_dump can't sleep. Therefore we allocate temp buffer and then @@ -2610,7 +2612,8 @@ static void hci_sched_esco(struct hci_dev *hdev) if (!hci_conn_num(hdev, ESCO_LINK)) return; - while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { + while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, + "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_frame(skb); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 75b03fc78002..87e6f74af6fe 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -409,7 +409,8 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); } -static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cc_write_voice_setting(struct hci_dev *hdev, + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); __u16 setting; @@ -648,7 +649,8 @@ static void hci_setup_link_policy(struct hci_dev *hdev) hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); } -static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cc_read_local_commands(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_rp_read_local_commands *rp = (void *) skb->data; @@ -666,7 +668,8 @@ done: hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); } -static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) +static void hci_cc_read_local_features(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_rp_read_local_features *rp = (void *) skb->data; @@ -1845,7 +1848,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) if (ie) memcpy(ie->data.dev_class, ev->dev_class, 3); - conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); + conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, + &ev->bdaddr); if (!conn) { conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); if (!conn) { @@ -2623,7 +2627,8 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->mode = ev->mode; conn->interval = __le16_to_cpu(ev->interval); - if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) { + if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, + &conn->flags)) { if (conn->mode == HCI_CM_ACTIVE) set_bit(HCI_CONN_POWER_SAVE, &conn->flags); else @@ -2714,8 +2719,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && conn->pending_sec_level == BT_SECURITY_HIGH) { - BT_DBG("%s ignoring key unauthenticated for high \ - security", hdev->name); + BT_DBG("%s ignoring key unauthenticated for high security", + hdev->name); goto not_found; } @@ -3097,8 +3102,8 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->auth_type = hci_get_auth_req(conn); cp.authentication = conn->auth_type; - if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) && - hci_find_remote_oob_data(hdev, &conn->dst)) + if (hci_find_remote_oob_data(hdev, &conn->dst) && + (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags))) cp.oob_data = 0x01; else cp.oob_data = 0x00; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index c1e0c3df5e6c..9d8e1c39955e 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -241,7 +241,8 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) struct hci_mon_hdr *hdr; /* Create a private copy with headroom */ - skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC); + skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, + GFP_ATOMIC); if (!skb_copy) continue; @@ -542,7 +543,8 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, } } -static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, + unsigned long arg) { struct sock *sk = sock->sk; void __user *argp = (void __user *) arg; @@ -603,7 +605,8 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a } } -static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) +static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, + int addr_len) { struct sockaddr_hci haddr; struct sock *sk = sock->sk; @@ -692,7 +695,8 @@ done: return err; } -static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer) +static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, + int *addr_len, int peer) { struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; struct sock *sk = sock->sk; @@ -720,7 +724,8 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, if (mask & HCI_CMSG_DIR) { int incoming = bt_cb(skb)->incoming; - put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming); + put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), + &incoming); } if (mask & HCI_CMSG_TSTAMP) { @@ -895,7 +900,8 @@ drop: goto done; } -static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len) +static int hci_sock_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, unsigned int len) { struct hci_ufilter uf = { .opcode = 0 }; struct sock *sk = sock->sk; @@ -977,7 +983,8 @@ done: return err; } -static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) +static int hci_sock_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) { struct hci_ufilter uf; struct sock *sk = sock->sk; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 847a8445c53c..ee8d9ea6bf3c 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -220,8 +220,8 @@ static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); - return sprintf(buf, "0x%.2x%.2x%.2x\n", - hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); + return sprintf(buf, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], + hdev->dev_class[1], hdev->dev_class[0]); } static ssize_t show_address(struct device *dev, diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index 506628876f36..994bc3c7ddc7 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index df03c7d20331..984afe4ef407 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -714,7 +714,8 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, } static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, - void (*cb)(struct pending_cmd *cmd, void *data), + void (*cb)(struct pending_cmd *cmd, + void *data), void *data) { struct list_head *p, *n; @@ -1594,7 +1595,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, } if (cp->addr.type == BDADDR_BREDR) - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, + &cp->addr.bdaddr); else conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); @@ -3226,7 +3228,8 @@ int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status) { return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type, - status, MGMT_OP_USER_CONFIRM_NEG_REPLY); + status, + MGMT_OP_USER_CONFIRM_NEG_REPLY); } int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, @@ -3240,7 +3243,8 @@ int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status) { return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type, - status, MGMT_OP_USER_PASSKEY_NEG_REPLY); + status, + MGMT_OP_USER_PASSKEY_NEG_REPLY); } int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -- GitLab From 8c520a59927a5600973782505dbb750d985057c4 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 23 May 2012 04:04:22 -0300 Subject: [PATCH 0307/6849] Bluetooth: Remove unnecessary headers include Most of the include were unnecessary or already included by some other header. Replace module.h by export.h where possible. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 8 -------- include/net/bluetooth/bluetooth.h | 3 --- include/net/bluetooth/hci.h | 1 - include/net/bluetooth/hci_core.h | 1 - net/bluetooth/af_bluetooth.c | 11 ----------- net/bluetooth/bnep/core.c | 17 ----------------- net/bluetooth/bnep/netdev.c | 10 +--------- net/bluetooth/bnep/sock.c | 18 +----------------- net/bluetooth/hci_conn.c | 16 +--------------- net/bluetooth/hci_core.c | 23 ++--------------------- net/bluetooth/hci_event.c | 15 +-------------- net/bluetooth/hci_sock.c | 20 +------------------- net/bluetooth/hci_sysfs.c | 4 ---- net/bluetooth/hidp/core.c | 19 ------------------- net/bluetooth/hidp/sock.c | 16 +--------------- net/bluetooth/l2cap_core.c | 19 ------------------- net/bluetooth/l2cap_sock.c | 1 - net/bluetooth/lib.c | 7 +------ net/bluetooth/mgmt.c | 2 -- net/bluetooth/rfcomm/core.c | 14 -------------- net/bluetooth/rfcomm/sock.c | 21 +-------------------- net/bluetooth/rfcomm/tty.c | 5 ----- net/bluetooth/sco.c | 18 ------------------ net/bluetooth/smp.c | 7 ++++--- 24 files changed, 14 insertions(+), 262 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3a6cdc9b75a3..a45e717f5f84 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -21,15 +21,7 @@ * */ -#include #include -#include -#include -#include -#include -#include -#include - #include #include diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 7a9f9612db5a..565d4bee1e49 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -25,9 +25,6 @@ #ifndef __BLUETOOTH_H #define __BLUETOOTH_H -#include -#include -#include #include #include diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 5de351e49d49..edb663908121 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1292,7 +1292,6 @@ struct hci_sco_hdr { __u8 dlen; } __packed; -#include static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb) { return (struct hci_event_hdr *) skb->data; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a8ba50d7a81e..d584a47d1c86 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -25,7 +25,6 @@ #ifndef __HCI_CORE_H #define __HCI_CORE_H -#include #include /* HCI priority */ diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index e31a20f5b6be..251747269d37 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -25,18 +25,7 @@ /* Bluetooth address family and sockets. */ #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index a918f6e4f003..4a6620bc1570 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -26,26 +26,9 @@ */ #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include - -#include #include - -#include #include -#include - #include #include diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 46c9ece7b04a..98f86f91d47c 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -25,16 +25,8 @@ SOFTWARE IS DISCLAIMED. */ -#include -#include - -#include -#include +#include #include -#include -#include - -#include #include #include diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 180bfc45810d..5e5f5b410e0b 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -24,24 +24,8 @@ SOFTWARE IS DISCLAIMED. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include - #include "bnep.h" diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 231fc4400f37..3bb2d552a888 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -24,21 +24,7 @@ /* Bluetooth HCI connection handling. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include #include #include diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bee425ad25b5..3431ec908c02 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -25,28 +25,9 @@ /* Bluetooth HCI core. */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -#include -#include +#include #include #include diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 87e6f74af6fe..5e24a57a4613 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -24,20 +24,7 @@ /* Bluetooth HCI event handling. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include #include #include diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 9d8e1c39955e..a7f04de03d79 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -24,25 +24,7 @@ /* Bluetooth HCI sockets. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include #include #include diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index ee8d9ea6bf3c..a20e61c3653d 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -1,10 +1,6 @@ /* Bluetooth HCI driver model support. */ -#include -#include -#include #include -#include #include #include diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index c8625b8ccb6a..8a4afc7515a2 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -21,27 +21,8 @@ */ #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include #include -#include - -#include -#include #include #include diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 73a32d705c1f..18b3f6892a36 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -20,22 +20,8 @@ SOFTWARE IS DISCLAIMED. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include #include "hidp.h" diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index db76a7750ee6..f6b785593ec3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -30,27 +30,8 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include -#include - -#include #include #include diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 3bb1611b9d48..4d3660540c05 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -27,7 +27,6 @@ /* Bluetooth L2CAP sockets. */ -#include #include #include diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index 994bc3c7ddc7..e1c97527e16c 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -26,12 +26,7 @@ #define pr_fmt(fmt) "Bluetooth: " fmt -#include - -#include -#include -#include -#include +#include #include diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 984afe4ef407..205574edff20 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -24,8 +24,6 @@ /* Bluetooth HCI Management interface */ -#include -#include #include #include diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 585d3916d3d4..c75107ef8920 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -26,22 +26,8 @@ */ #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include #include -#include - -#include -#include #include #include diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index e8707debb864..7e1e59645c05 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -25,27 +25,8 @@ * RFCOMM sockets. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include - -#include #include #include diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index f2f4d064df94..cb960773c002 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -31,11 +31,6 @@ #include #include -#include -#include -#include -#include - #include #include #include diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 6401ccae2045..40bbe25dcff7 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -25,26 +25,8 @@ /* Bluetooth SCO sockets. */ #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include - -#include #include #include diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6fc7c4708f3e..ff4835b61de9 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -20,14 +20,15 @@ SOFTWARE IS DISCLAIMED. */ +#include +#include +#include + #include #include #include #include #include -#include -#include -#include #define SMP_TIMEOUT msecs_to_jiffies(30000) -- GitLab From 8449e381a8558fb1d911017ea26bae681fea4240 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 23 May 2012 04:04:23 -0300 Subject: [PATCH 0308/6849] Bluetooth: Remove unneeded EXPORT_SYMBOL After l2cap, sco and bluetooth modules merge some symbols doesn't need to be exported anymore. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_conn.c | 5 ----- net/bluetooth/hci_core.c | 4 ---- 2 files changed, 9 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3bb2d552a888..8163ee175d6a 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -188,7 +188,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); } -EXPORT_SYMBOL(hci_le_conn_update); void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], __u8 ltk[16]) @@ -207,7 +206,6 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp); } -EXPORT_SYMBOL(hci_le_start_enc); /* Device _must_ be locked */ void hci_sco_setup(struct hci_conn *conn, __u8 status) @@ -546,7 +544,6 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, return sco; } -EXPORT_SYMBOL(hci_connect); /* Check link security requirement */ int hci_conn_check_link_mode(struct hci_conn *conn) @@ -558,7 +555,6 @@ int hci_conn_check_link_mode(struct hci_conn *conn) return 1; } -EXPORT_SYMBOL(hci_conn_check_link_mode); /* Authenticate remote device */ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) @@ -690,7 +686,6 @@ int hci_conn_change_link_key(struct hci_conn *conn) return 0; } -EXPORT_SYMBOL(hci_conn_change_link_key); /* Switch role */ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 3431ec908c02..9c586fbdb71b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1227,7 +1227,6 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) return NULL; } -EXPORT_SYMBOL(hci_find_ltk); struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) @@ -1241,7 +1240,6 @@ struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, return NULL; } -EXPORT_SYMBOL(hci_find_ltk_by_addr); int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) @@ -2201,7 +2199,6 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) queue_work(hdev->workqueue, &hdev->tx_work); } -EXPORT_SYMBOL(hci_send_acl); /* Send SCO data */ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) @@ -2224,7 +2221,6 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) skb_queue_tail(&conn->data_q, skb); queue_work(hdev->workqueue, &hdev->tx_work); } -EXPORT_SYMBOL(hci_send_sco); /* ---- HCI TX task (outgoing data) ---- */ -- GitLab From 59e54bd15d63f102c71c3ce695bca5ed90926e46 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 23 May 2012 15:44:06 +0300 Subject: [PATCH 0309/6849] Bluetooth: Define L2CAP conf continuation flag Define Continuation flag which the only flag used from Flags field in L2CAP Configuration Request and Response. Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 3 +++ net/bluetooth/l2cap_core.c | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7bc40198f147..01422578cc78 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -271,6 +271,9 @@ struct l2cap_conf_rsp { #define L2CAP_CONF_PENDING 0x0004 #define L2CAP_CONF_EFS_REJECT 0x0005 +/* configuration req/rsp continuation flag */ +#define L2CAP_CONF_FLAG_CONTINUATION 0x0001 + struct l2cap_conf_opt { __u8 type; __u8 len; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index f6b785593ec3..e31b005f9827 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2944,7 +2944,7 @@ done: } req->dcid = cpu_to_le16(chan->dcid); - req->flags = cpu_to_le16(0); + req->flags = __constant_cpu_to_le16(0); return ptr - data; } @@ -3164,7 +3164,7 @@ done: } rsp->scid = cpu_to_le16(chan->dcid); rsp->result = cpu_to_le16(result); - rsp->flags = cpu_to_le16(0x0000); + rsp->flags = __constant_cpu_to_le16(0); return ptr - data; } @@ -3263,7 +3263,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi } req->dcid = cpu_to_le16(chan->dcid); - req->flags = cpu_to_le16(0x0000); + req->flags = __constant_cpu_to_le16(0); return ptr - data; } @@ -3618,7 +3618,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr memcpy(chan->conf_req + chan->conf_len, req->data, len); chan->conf_len += len; - if (flags & 0x0001) { + if (flags & L2CAP_CONF_FLAG_CONTINUATION) { /* Incomplete config. Send empty response. */ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, @@ -3769,7 +3769,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto done; } - if (flags & 0x01) + if (flags & L2CAP_CONF_FLAG_CONTINUATION) goto done; set_bit(CONF_INPUT_DONE, &chan->conf_state); -- GitLab From 2d369359f1e0fa13852404ff2f8063235a27d8a7 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 23 May 2012 14:59:30 -0700 Subject: [PATCH 0310/6849] Bluetooth: Send a configuration request after security confirmation Sometimes an ACL link must be raised to a higher security level after an L2CAP connection is requested, but before a connection response is sent. In this case, a connection response sent by L2CAP was not immediately followed by a configuration request. Other code paths do send this configuration request right away. It was possible for the connection to stall while L2CAP waited for the remote device (like PTS) to trigger the configuration process. Here is an abbreviated hcidump of the failure case with PTS: 1337806446.051982 > ACL data: handle 43 flags 0x02 dlen 10 L2CAP(s): Info req: type 2 1337806446.052050 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Info rsp: type 2 result 0 Extended feature mask 0x000000b8 1337806446.595320 > ACL data: handle 43 flags 0x02 dlen 12 L2CAP(s): Connect req: psm 4097 scid 0x0041 1337806446.595673 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 1 status 0 1337806446.595679 < ACL data: handle 43 flags 0x00 dlen 10 L2CAP(s): Info req: type 2 1337806446.669835 > ACL data: handle 43 flags 0x02 dlen 16 L2CAP(s): Info rsp: type 2 result 0 Extended feature mask 0x00000028 1337806446.669899 < HCI Command: Authentication Requested (0x01|0x0011) plen 2 1337806446.669906 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 1 status 1 1337806446.769888 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 0 status 0 At this point, the connection stalls and no further messages are sent on the L2CAP signaling channel. No data is received either. If we immediately send a configuration request after a successful connect response, the connection completes: 1337724090.041162 > ACL data: handle 43 flags 0x02 dlen 10 L2CAP(s): Info req: type 2 1337724090.041236 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Info rsp: type 2 result 0 Extended feature mask 0x000000b8 1337724090.597128 > ACL data: handle 43 flags 0x02 dlen 12 L2CAP(s): Connect req: psm 4097 scid 0x0041 1337724090.597236 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 1 status 0 1337724090.597244 < ACL data: handle 43 flags 0x00 dlen 10 L2CAP(s): Info req: type 2 1337724090.660842 > ACL data: handle 43 flags 0x02 dlen 16 L2CAP(s): Info rsp: type 2 result 0 Extended feature mask 0x00000028 1337724090.660926 < HCI Command: Authentication Requested (0x01|0x0011) plen 2 1337724090.660934 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 1 status 1 1337724090.755162 < ACL data: handle 43 flags 0x00 dlen 16 L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 0 status 0 1337724090.755171 < ACL data: handle 43 flags 0x00 dlen 23 L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 11 1337724091.361847 > ACL data: handle 43 flags 0x02 dlen 29 L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 15 1337724091.863808 > ACL data: handle 43 flags 0x02 dlen 23 L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 11 1337724091.863882 < ACL data: handle 43 flags 0x00 dlen 29 L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 15 1337724092.683745 > ACL data: handle 43 flags 0x02 dlen 12 L2CAP(d): cid 0x0040 len 8 [psm 4097] 0000: 00 00 11 22 33 44 34 2f ..."3D4/ Signed-off-by: Mat Martineau Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e31b005f9827..c9e6ae4a3363 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5500,6 +5500,17 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) rsp.status = cpu_to_le16(stat); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); + + if (!test_bit(CONF_REQ_SENT, &chan->conf_state) && + res == L2CAP_CR_SUCCESS) { + char buf[128]; + set_bit(CONF_REQ_SENT, &chan->conf_state); + l2cap_send_cmd(conn, l2cap_get_ident(conn), + L2CAP_CONF_REQ, + l2cap_build_conf_req(chan, buf), + buf); + chan->num_conf_req++; + } } l2cap_chan_unlock(chan); -- GitLab From 37ed561e823f5f91ca87522d61a57974be583c0d Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 23 May 2012 18:50:04 -0700 Subject: [PATCH 0311/6849] Bluetooth: btmrvl: add SD8787 Bluetooth AMP device ID SD8787 SDIO function 3 (device ID 0x911B) is for Bluetooth AMP. Signed-off-by: Bing Zhao Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_sdio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index a853244e7fd7..2867499f7256 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -110,6 +110,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8787 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, + /* Marvell SD8787 Bluetooth AMP device */ + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911B), + .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, /* Marvell SD8797 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, -- GitLab From 6d3c730f03e0d1aed2125c1a64ad8857c63f5163 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 24 May 2012 03:36:37 -0300 Subject: [PATCH 0312/6849] Bluetooth: Use lmp_ssp_capable() macro Make the check more user friendly. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5e24a57a4613..80f209b01b9e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -557,7 +557,7 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->hci_ver > BLUETOOTH_VER_1_1) hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); - if (hdev->features[6] & LMP_SIMPLE_PAIR) { + if (lmp_ssp_capable(hdev)) { if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 mode = 0x01; hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, -- GitLab From 2983fd682444180e45567ce8147a612b97ba69da Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 24 May 2012 15:42:50 +0300 Subject: [PATCH 0313/6849] Bluetooth: Define and use PSM identifiers Define assigned Protocol and Service Multiplexor (PSM) identifiers and use them instead of magic numbers. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 4 ++++ net/bluetooth/l2cap_core.c | 4 ++-- net/bluetooth/l2cap_sock.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 01422578cc78..f44344b92d2d 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -229,6 +229,10 @@ struct l2cap_conn_rsp { __le16 status; } __packed; +/* protocol/service multiplexer (PSM) */ +#define L2CAP_PSM_SDP 0x0001 +#define L2CAP_PSM_RFCOMM 0x0003 + /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c9e6ae4a3363..65c3f4e13965 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -648,7 +648,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) default: return HCI_AT_NO_BONDING; } - } else if (chan->psm == cpu_to_le16(0x0001)) { + } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) { if (chan->sec_level == BT_SECURITY_LOW) chan->sec_level = BT_SECURITY_SDP; @@ -3393,7 +3393,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd lock_sock(parent); /* Check if the ACL is secure enough (if not SDP) */ - if (psm != cpu_to_le16(0x0001) && + if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && !hci_conn_check_link_mode(conn->hcon)) { conn->disc_reason = HCI_ERROR_AUTH_FAILURE; result = L2CAP_CR_SEC_BLOCK; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 4d3660540c05..d244361a455c 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -88,8 +88,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) if (err < 0) goto done; - if (__le16_to_cpu(la.l2_psm) == 0x0001 || - __le16_to_cpu(la.l2_psm) == 0x0003) + if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP || + __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM) chan->sec_level = BT_SECURITY_SDP; bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); -- GitLab From ac73498cbb54ebe3a06709ba7e4feb99c83113bf Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 24 May 2012 15:42:51 +0300 Subject: [PATCH 0314/6849] Bluetooth: Use __constant when dealing with constants __constant_cpu_to_le16() is the right go here. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 65c3f4e13965..6eb2ef2de723 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -616,7 +616,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); rsp.result = cpu_to_le16(result); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); } @@ -1010,7 +1010,7 @@ static void l2cap_do_start(struct l2cap_chan *chan) l2cap_send_conn_req(chan); } else { struct l2cap_info_req req; - req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); + req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; conn->info_ident = l2cap_get_ident(conn); @@ -1110,20 +1110,20 @@ static void l2cap_conn_start(struct l2cap_conn *conn) if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { struct sock *parent = bt_sk(sk)->parent; - rsp.result = cpu_to_le16(L2CAP_CR_PEND); - rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); + rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); + rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); if (parent) parent->sk_data_ready(parent, 0); } else { __l2cap_state_change(chan, BT_CONFIG); - rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); } release_sock(sk); } else { - rsp.result = cpu_to_le16(L2CAP_CR_PEND); - rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); + rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); + rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND); } l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, @@ -2595,9 +2595,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); if (conn->hcon->type == LE_LINK) - lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING); + lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING); else - lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); + lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING); cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); cmd->code = code; @@ -2709,8 +2709,8 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) efs.stype = chan->local_stype; efs.msdu = cpu_to_le16(chan->local_msdu); efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); - efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); - efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); + efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); + efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); break; case L2CAP_MODE_STREAMING: @@ -3290,8 +3290,8 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); - rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); @@ -3329,8 +3329,8 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) * did not send an RFC option. */ rfc.mode = chan->mode; - rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); - rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); + rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); + rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); rfc.max_pdu_size = cpu_to_le16(chan->imtu); BT_ERR("Expected RFC option was not found, using defaults"); @@ -3474,7 +3474,7 @@ sendresp: if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { struct l2cap_info_req info; - info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); + info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; conn->info_ident = l2cap_get_ident(conn); @@ -3596,7 +3596,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { struct l2cap_cmd_rej_cid rej; - rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID); + rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); rej.scid = cpu_to_le16(chan->scid); rej.dcid = cpu_to_le16(chan->dcid); @@ -3886,8 +3886,8 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm u8 buf[8]; u32 feat_mask = l2cap_feat_mask; struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; - rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); - rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); + rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); + rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); if (!disable_ertm) feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | L2CAP_FEAT_FCS; @@ -3907,15 +3907,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm else l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; - rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); - rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); + rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); + rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), buf); } else { struct l2cap_info_rsp rsp; rsp.type = cpu_to_le16(type); - rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP); + rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP); l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp); } @@ -3955,7 +3955,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) { struct l2cap_info_req req; - req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); + req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); conn->info_ident = l2cap_get_ident(conn); @@ -4190,9 +4190,9 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, err = l2cap_check_conn_param(min, max, latency, to_multiplier); if (err) - rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); + rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); else - rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); + rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, sizeof(rsp), &rsp); @@ -4340,7 +4340,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, BT_ERR("Wrong link type (%d)", err); /* FIXME: Map err to a valid reason */ - rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); + rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); } -- GitLab From 82781e634f815e9a675ef643a5e11da0cf77ce0e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 25 May 2012 11:38:27 +0300 Subject: [PATCH 0315/6849] Bluetooth: Use __constant modifier in HCI code Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_conn.c | 36 ++++++++++++++++++------------------ net/bluetooth/hci_core.c | 2 +- net/bluetooth/hci_event.c | 6 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 8163ee175d6a..126876d915f5 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -40,15 +40,15 @@ static void hci_le_connect(struct hci_conn *conn) conn->sec_level = BT_SECURITY_LOW; memset(&cp, 0, sizeof(cp)); - cp.scan_interval = cpu_to_le16(0x0060); - cp.scan_window = cpu_to_le16(0x0030); + cp.scan_interval = __constant_cpu_to_le16(0x0060); + cp.scan_window = __constant_cpu_to_le16(0x0030); bacpy(&cp.peer_addr, &conn->dst); cp.peer_addr_type = conn->dst_type; - cp.conn_interval_min = cpu_to_le16(0x0028); - cp.conn_interval_max = cpu_to_le16(0x0038); - cp.supervision_timeout = cpu_to_le16(0x002a); - cp.min_ce_len = cpu_to_le16(0x0000); - cp.max_ce_len = cpu_to_le16(0x0000); + cp.conn_interval_min = __constant_cpu_to_le16(0x0028); + cp.conn_interval_max = __constant_cpu_to_le16(0x0038); + cp.supervision_timeout = __constant_cpu_to_le16(0x002a); + cp.min_ce_len = __constant_cpu_to_le16(0x0000); + cp.max_ce_len = __constant_cpu_to_le16(0x0000); hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); } @@ -85,7 +85,7 @@ void hci_acl_connect(struct hci_conn *conn) cp.pscan_rep_mode = ie->data.pscan_rep_mode; cp.pscan_mode = ie->data.pscan_mode; cp.clock_offset = ie->data.clock_offset | - cpu_to_le16(0x8000); + __constant_cpu_to_le16(0x8000); } memcpy(conn->dev_class, ie->data.dev_class, 3); @@ -161,9 +161,9 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) cp.handle = cpu_to_le16(handle); cp.pkt_type = cpu_to_le16(conn->pkt_type); - cp.tx_bandwidth = cpu_to_le32(0x00001f40); - cp.rx_bandwidth = cpu_to_le32(0x00001f40); - cp.max_latency = cpu_to_le16(0xffff); + cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); + cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); + cp.max_latency = __constant_cpu_to_le16(0xffff); cp.voice_setting = cpu_to_le16(hdev->voice_setting); cp.retrans_effort = 0xff; @@ -183,8 +183,8 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, cp.conn_interval_max = cpu_to_le16(max); cp.conn_latency = cpu_to_le16(latency); cp.supervision_timeout = cpu_to_le16(to_multiplier); - cp.min_ce_len = cpu_to_le16(0x0001); - cp.max_ce_len = cpu_to_le16(0x0001); + cp.min_ce_len = __constant_cpu_to_le16(0x0001); + cp.max_ce_len = __constant_cpu_to_le16(0x0001); hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); } @@ -279,9 +279,9 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { struct hci_cp_sniff_subrate cp; cp.handle = cpu_to_le16(conn->handle); - cp.max_latency = cpu_to_le16(0); - cp.min_remote_timeout = cpu_to_le16(0); - cp.min_local_timeout = cpu_to_le16(0); + cp.max_latency = __constant_cpu_to_le16(0); + cp.min_remote_timeout = __constant_cpu_to_le16(0); + cp.min_local_timeout = __constant_cpu_to_le16(0); hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); } @@ -290,8 +290,8 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) cp.handle = cpu_to_le16(conn->handle); cp.max_interval = cpu_to_le16(hdev->sniff_max_interval); cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); - cp.attempt = cpu_to_le16(4); - cp.timeout = cpu_to_le16(1); + cp.attempt = __constant_cpu_to_le16(4); + cp.timeout = __constant_cpu_to_le16(1); hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); } } diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9c586fbdb71b..73b459658ccc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -218,7 +218,7 @@ static void bredr_init(struct hci_dev *hdev) hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); /* Connection accept timeout ~20 secs */ - param = cpu_to_le16(0x7d00); + param = __constant_cpu_to_le16(0x7d00); hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); bacpy(&cp.bdaddr, BDADDR_ANY); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 80f209b01b9e..ac86b656c7a8 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1869,9 +1869,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) bacpy(&cp.bdaddr, &ev->bdaddr); cp.pkt_type = cpu_to_le16(conn->pkt_type); - cp.tx_bandwidth = cpu_to_le32(0x00001f40); - cp.rx_bandwidth = cpu_to_le32(0x00001f40); - cp.max_latency = cpu_to_le16(0xffff); + cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); + cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); + cp.max_latency = __constant_cpu_to_le16(0xffff); cp.content_format = cpu_to_le16(hdev->voice_setting); cp.retrans_effort = 0xff; -- GitLab From 523e93cdb39086b25af2ed19d2a69248510727a2 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 25 May 2012 15:09:26 +0300 Subject: [PATCH 0316/6849] Bluetooth: Define HCI AMP cmd struct Add HCI commands to deal with Bluetooth AMP controllers. Those commands will be used by bluetooth and softamp code. Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci.h | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index edb663908121..de09a26e4223 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -31,6 +31,7 @@ #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) #define HCI_LINK_KEY_SIZE 16 +#define HCI_AMP_LINK_KEY_SIZE (2 * HCI_LINK_KEY_SIZE) /* HCI dev events */ #define HCI_DEV_REG 1 @@ -525,6 +526,28 @@ struct hci_cp_io_capability_neg_reply { __u8 reason; } __packed; +#define HCI_OP_CREATE_PHY_LINK 0x0435 +struct hci_cp_create_phy_link { + __u8 phy_handle; + __u8 key_len; + __u8 key_type; + __u8 key[HCI_AMP_LINK_KEY_SIZE]; +} __packed; + +#define HCI_OP_ACCEPT_PHY_LINK 0x0436 +struct hci_cp_accept_phy_link { + __u8 phy_handle; + __u8 key_len; + __u8 key_type; + __u8 key[HCI_AMP_LINK_KEY_SIZE]; +} __packed; + +#define HCI_OP_DISCONN_PHY_LINK 0x0437 +struct hci_cp_disconn_phy_link { + __u8 phy_handle; + __u8 reason; +} __packed; + #define HCI_OP_SNIFF_MODE 0x0803 struct hci_cp_sniff_mode { __le16 handle; @@ -820,6 +843,31 @@ struct hci_rp_read_local_amp_info { __le32 be_flush_to; } __packed; +#define HCI_OP_READ_LOCAL_AMP_ASSOC 0x140a +struct hci_cp_read_local_amp_assoc { + __u8 phy_handle; + __le16 len_so_far; + __le16 max_len; +} __packed; +struct hci_rp_read_local_amp_assoc { + __u8 status; + __u8 phy_handle; + __le16 rem_len; + __u8 frag[0]; +} __packed; + +#define HCI_OP_WRITE_REMOTE_AMP_ASSOC 0x140b +struct hci_cp_write_remote_amp_assoc { + __u8 phy_handle; + __le16 len_so_far; + __le16 rem_len; + __u8 frag[0]; +} __packed; +struct hci_rp_write_remote_amp_assoc { + __u8 status; + __u8 phy_handle; +} __packed; + #define HCI_OP_LE_SET_EVENT_MASK 0x2001 struct hci_cp_le_set_event_mask { __u8 mask[8]; @@ -1192,6 +1240,39 @@ struct hci_ev_le_meta { __u8 subevent; } __packed; +#define HCI_EV_PHY_LINK_COMPLETE 0x40 +struct hci_ev_phy_link_complete { + __u8 status; + __u8 phy_handle; +} __packed; + +#define HCI_EV_CHANNEL_SELECTED 0x41 +struct hci_ev_channel_selected { + __u8 phy_handle; +} __packed; + +#define HCI_EV_DISCONN_PHY_LINK_COMPLETE 0x42 +struct hci_ev_disconn_phy_link_complete { + __u8 status; + __u8 phy_handle; + __u8 reason; +} __packed; + +#define HCI_EV_LOGICAL_LINK_COMPLETE 0x45 +struct hci_ev_logical_link_complete { + __u8 status; + __le16 handle; + __u8 phy_handle; + __u8 flow_spec_id; +} __packed; + +#define HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE 0x46 +struct hci_ev_disconn_logical_link_complete { + __u8 status; + __le16 handle; + __u8 reason; +} __packed; + #define HCI_EV_NUM_COMP_BLOCKS 0x48 struct hci_comp_blocks_info { __le16 handle; -- GitLab From 35d401df3db4cb7a0403b42641bbf5694e64d374 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 25 May 2012 18:57:05 -0300 Subject: [PATCH 0317/6849] Bluetooth: Get a more accurate L2CAP PDU len Both FCS and Extended header might be or might not be present in a ERTM channel. Signed-off-by: Gustavo Padovan Reviewed-by: Mat Martineau Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 6eb2ef2de723..155aa509b3af 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2130,7 +2130,13 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); /* Adjust for largest possible L2CAP overhead. */ - pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE; + if (chan->fcs) + pdu_len -= L2CAP_FCS_SIZE; + + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + pdu_len -= L2CAP_EXT_HDR_SIZE; + else + pdu_len -= L2CAP_ENH_HDR_SIZE; /* Remote device may have requested smaller PDUs */ pdu_len = min_t(size_t, pdu_len, chan->remote_mps); -- GitLab From 2f84a2e6a6978810b06b5f33892152183f1dace9 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 25 May 2012 09:30:53 -0300 Subject: [PATCH 0318/6849] Bluetooth: Remove extra l2cap_state_change(BT_CONNECTED) This is already performed inside l2cap_chan_ready(), so we don't need it here again. Signed-off-by: Gustavo Padovan Acked-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 155aa509b3af..0d556f7faaf6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3651,8 +3651,6 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { set_default_fcs(chan); - l2cap_state_change(chan, BT_CONNECTED); - if (chan->mode == L2CAP_MODE_ERTM || chan->mode == L2CAP_MODE_STREAMING) err = l2cap_ertm_init(chan); @@ -3783,7 +3781,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) { set_default_fcs(chan); - l2cap_state_change(chan, BT_CONNECTED); if (chan->mode == L2CAP_MODE_ERTM || chan->mode == L2CAP_MODE_STREAMING) err = l2cap_ertm_init(chan); -- GitLab From 6754e0df133b088aa97ae6f2d3fd5377e43d1fc6 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 25 May 2012 09:30:56 -0300 Subject: [PATCH 0319/6849] Bluetooth: Use l2cap_chan_ready() in LE path This replace code in l2cap_le_conn_ready() by a similar code in l2cap_chan_ready(). Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0d556f7faaf6..de0dc9ec9862 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1228,10 +1228,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) l2cap_chan_add(conn, chan); - __set_chan_timer(chan, sk->sk_sndtimeo); - - __l2cap_state_change(chan, BT_CONNECTED); - parent->sk_data_ready(parent, 0); + l2cap_chan_ready(chan); clean: release_sock(parent); -- GitLab From 3df92b31b2b593c5a067634ef2c30e76b2b2548d Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 27 May 2012 22:36:56 +0200 Subject: [PATCH 0320/6849] Bluetooth: Really fix registering hci with duplicate name Commit fc50744 ("Bluetooth: Fix registering hci with duplicate name") didn't fully fix the duplicate naming issue with devices, and duplicate device names could still be created: [ 142.484097] device: 'hci1': device_add [...] [ 150.545263] device: 'hci1': device_add [ 150.550128] kobject: 'hci1' (ffff880014cc4e58): kobject_add_internal: parent: 'bluetooth', set: 'devices' [ 150.558979] ------------[ cut here ]------------ [ 150.561438] WARNING: at fs/sysfs/dir.c:529 sysfs_add_one+0xb0/0xd0() [ 150.572974] Hardware name: Bochs [ 150.580502] sysfs: cannot create duplicate filename '/devices/virtual/bluetooth/hci1' [ 150.584444] Pid: 7563, comm: trinity-child1 Tainted: G W 3.4.0-next-20120524-sasha #296 [...] Instead of the weird logic and the attempt at keeping the device list sorted, just use an IDA. Signed-off-by: Sasha Levin Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 41 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 73b459658ccc..979556a2649a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -26,6 +26,7 @@ /* Bluetooth HCI core. */ #include +#include #include @@ -46,6 +47,9 @@ DEFINE_RWLOCK(hci_dev_list_lock); LIST_HEAD(hci_cb_list); DEFINE_RWLOCK(hci_cb_list_lock); +/* HCI ID Numbering */ +static DEFINE_IDA(hci_index_ida); + /* ---- HCI notifications ---- */ static void hci_notify(struct hci_dev *hdev, int event) @@ -1689,37 +1693,35 @@ EXPORT_SYMBOL(hci_free_dev); /* Register HCI device */ int hci_register_dev(struct hci_dev *hdev) { - struct list_head *head, *p; int id, error; if (!hdev->open || !hdev->close) return -EINVAL; - write_lock(&hci_dev_list_lock); - /* Do not allow HCI_AMP devices to register at index 0, * so the index can be used as the AMP controller ID. */ - id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; - head = &hci_dev_list; - - /* Find first available device id */ - list_for_each(p, &hci_dev_list) { - int nid = list_entry(p, struct hci_dev, list)->id; - if (nid > id) - break; - if (nid == id) - id++; - head = p; + switch (hdev->dev_type) { + case HCI_BREDR: + id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); + break; + case HCI_AMP: + id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); + break; + default: + return -EINVAL; } + if (id < 0) + return id; + sprintf(hdev->name, "hci%d", id); hdev->id = id; BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); - list_add(&hdev->list, head); - + write_lock(&hci_dev_list_lock); + list_add(&hdev->list, &hci_dev_list); write_unlock(&hci_dev_list_lock); hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | @@ -1755,6 +1757,7 @@ int hci_register_dev(struct hci_dev *hdev) err_wqueue: destroy_workqueue(hdev->workqueue); err: + ida_simple_remove(&hci_index_ida, hdev->id); write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); @@ -1766,12 +1769,14 @@ EXPORT_SYMBOL(hci_register_dev); /* Unregister HCI device */ void hci_unregister_dev(struct hci_dev *hdev) { - int i; + int i, id; BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); set_bit(HCI_UNREGISTER, &hdev->dev_flags); + id = hdev->id; + write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); @@ -1812,6 +1817,8 @@ void hci_unregister_dev(struct hci_dev *hdev) hci_dev_unlock(hdev); hci_dev_put(hdev); + + ida_simple_remove(&hci_index_ida, id); } EXPORT_SYMBOL(hci_unregister_dev); -- GitLab From 80b980279508edd1a92d8d77ec99b0ddad00c5fe Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Sun, 27 May 2012 22:27:51 -0300 Subject: [PATCH 0321/6849] Bluetooth: Use chan as parameters for l2cap chan ops Use chan instead of void * makes more sense here. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 10 ++++++---- net/bluetooth/l2cap_core.c | 30 +++++++++++++++--------------- net/bluetooth/l2cap_sock.c | 16 ++++++++-------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index f44344b92d2d..aa2dbc680d5c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -527,10 +527,12 @@ struct l2cap_chan { struct l2cap_ops { char *name; - struct l2cap_chan *(*new_connection) (void *data); - int (*recv) (void *data, struct sk_buff *skb); - void (*close) (void *data); - void (*state_change) (void *data, int state); + struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan); + int (*recv) (struct l2cap_chan * chan, + struct sk_buff *skb); + void (*close) (struct l2cap_chan *chan); + void (*state_change) (struct l2cap_chan *chan, + int state); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, unsigned long len, int nb); }; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index de0dc9ec9862..7edc8146db26 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -180,7 +180,7 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state) state_to_string(state)); chan->state = state; - chan->ops->state_change(chan->data, state); + chan->ops->state_change(chan, state); } static void l2cap_state_change(struct l2cap_chan *chan, int state) @@ -381,7 +381,7 @@ static void l2cap_chan_timeout(struct work_struct *work) l2cap_chan_unlock(chan); - chan->ops->close(chan->data); + chan->ops->close(chan); mutex_unlock(&conn->chan_lock); l2cap_chan_put(chan); @@ -569,7 +569,7 @@ static void l2cap_chan_cleanup_listen(struct sock *parent) l2cap_chan_close(chan, ECONNRESET); l2cap_chan_unlock(chan); - chan->ops->close(chan->data); + chan->ops->close(chan); } } @@ -1213,7 +1213,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) goto clean; } - chan = pchan->ops->new_connection(pchan->data); + chan = pchan->ops->new_connection(pchan); if (!chan) goto clean; @@ -1324,7 +1324,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) l2cap_chan_unlock(chan); - chan->ops->close(chan->data); + chan->ops->close(chan); l2cap_chan_put(chan); } @@ -2568,7 +2568,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) if (!nskb) continue; - if (chan->ops->recv(chan->data, nskb)) + if (chan->ops->recv(chan, nskb)) kfree_skb(nskb); } @@ -3411,7 +3411,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd goto response; } - chan = pchan->ops->new_connection(pchan->data); + chan = pchan->ops->new_connection(pchan); if (!chan) goto response; @@ -3420,7 +3420,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd /* Check if we already have channel with that dcid */ if (__l2cap_get_chan_by_dcid(conn, scid)) { sock_set_flag(sk, SOCK_ZAPPED); - chan->ops->close(chan->data); + chan->ops->close(chan); goto response; } @@ -3831,7 +3831,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd l2cap_chan_unlock(chan); - chan->ops->close(chan->data); + chan->ops->close(chan); l2cap_chan_put(chan); mutex_unlock(&conn->chan_lock); @@ -3865,7 +3865,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd l2cap_chan_unlock(chan); - chan->ops->close(chan->data); + chan->ops->close(chan); l2cap_chan_put(chan); mutex_unlock(&conn->chan_lock); @@ -4435,7 +4435,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, if (chan->sdu) break; - err = chan->ops->recv(chan->data, skb); + err = chan->ops->recv(chan, skb); break; case L2CAP_SAR_START: @@ -4485,7 +4485,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, if (chan->sdu->len != chan->sdu_len) break; - err = chan->ops->recv(chan->data, chan->sdu); + err = chan->ops->recv(chan, chan->sdu); if (!err) { /* Reassembly complete */ @@ -5207,7 +5207,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan->data, skb)) + if (!chan->ops->recv(chan, skb)) goto done; break; @@ -5246,7 +5246,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan->data, skb)) + if (!chan->ops->recv(chan, skb)) return 0; drop: @@ -5272,7 +5272,7 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid, if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan->data, skb)) + if (!chan->ops->recv(chan, skb)) return 0; drop: diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d244361a455c..db787f67c52a 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -872,9 +872,9 @@ static int l2cap_sock_release(struct socket *sock) return err; } -static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) +static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) { - struct sock *sk, *parent = data; + struct sock *sk, *parent = chan->data; sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); @@ -888,10 +888,10 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) return l2cap_pi(sk)->chan; } -static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) +static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { int err; - struct sock *sk = data; + struct sock *sk = chan->data; struct l2cap_pinfo *pi = l2cap_pi(sk); lock_sock(sk); @@ -924,16 +924,16 @@ done: return err; } -static void l2cap_sock_close_cb(void *data) +static void l2cap_sock_close_cb(struct l2cap_chan *chan) { - struct sock *sk = data; + struct sock *sk = chan->data; l2cap_sock_kill(sk); } -static void l2cap_sock_state_change_cb(void *data, int state) +static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state) { - struct sock *sk = data; + struct sock *sk = chan->data; sk->sk_state = state; } -- GitLab From c0df7f6e06e1aeccee39c801af7f78cadeb9f345 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Sun, 27 May 2012 22:27:52 -0300 Subject: [PATCH 0322/6849] Bluetooth: Move clean up code and set of SOCK_ZAPPED to l2cap_sock.c This remove a bit more of socket code from l2cap core, this calls set the SOCK_ZAPPED and do some clean up depending on the socket state. Reported-by: Mat Martineau Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 55 ++++++------------------------- net/bluetooth/l2cap_sock.c | 61 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 46 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index aa2dbc680d5c..76b0e7e5dec2 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -530,6 +530,7 @@ struct l2cap_ops { struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan); int (*recv) (struct l2cap_chan * chan, struct sk_buff *skb); + void (*teardown) (struct l2cap_chan *chan, int err); void (*close) (struct l2cap_chan *chan); void (*state_change) (struct l2cap_chan *chan, int state); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 7edc8146db26..1f4c72074154 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -493,9 +493,7 @@ static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) static void l2cap_chan_del(struct l2cap_chan *chan, int err) { - struct sock *sk = chan->sk; struct l2cap_conn *conn = chan->conn; - struct sock *parent = bt_sk(sk)->parent; __clear_chan_timer(chan); @@ -511,21 +509,8 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) hci_conn_put(conn->hcon); } - lock_sock(sk); - - __l2cap_state_change(chan, BT_CLOSED); - sock_set_flag(sk, SOCK_ZAPPED); - - if (err) - __l2cap_chan_set_err(chan, err); - - if (parent) { - bt_accept_unlink(sk); - parent->sk_data_ready(parent, 0); - } else - sk->sk_state_change(sk); - - release_sock(sk); + if (chan->ops->teardown) + chan->ops->teardown(chan, err); if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) return; @@ -554,25 +539,6 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) return; } -static void l2cap_chan_cleanup_listen(struct sock *parent) -{ - struct sock *sk; - - BT_DBG("parent %p", parent); - - /* Close not yet accepted channels */ - while ((sk = bt_accept_dequeue(parent, NULL))) { - struct l2cap_chan *chan = l2cap_pi(sk)->chan; - - l2cap_chan_lock(chan); - __clear_chan_timer(chan); - l2cap_chan_close(chan, ECONNRESET); - l2cap_chan_unlock(chan); - - chan->ops->close(chan); - } -} - void l2cap_chan_close(struct l2cap_chan *chan, int reason) { struct l2cap_conn *conn = chan->conn; @@ -583,12 +549,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) switch (chan->state) { case BT_LISTEN: - lock_sock(sk); - l2cap_chan_cleanup_listen(sk); - - __l2cap_state_change(chan, BT_CLOSED); - sock_set_flag(sk, SOCK_ZAPPED); - release_sock(sk); + if (chan->ops->teardown) + chan->ops->teardown(chan, 0); break; case BT_CONNECTED: @@ -630,9 +592,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) break; default: - lock_sock(sk); - sock_set_flag(sk, SOCK_ZAPPED); - release_sock(sk); + if (chan->ops->teardown) + chan->ops->teardown(chan, 0); break; } } @@ -3419,7 +3380,9 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd /* Check if we already have channel with that dcid */ if (__l2cap_get_chan_by_dcid(conn, scid)) { - sock_set_flag(sk, SOCK_ZAPPED); + if (chan->ops->teardown) + chan->ops->teardown(chan, 0); + chan->ops->close(chan); goto response; } diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index db787f67c52a..3f5946351fb9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -872,6 +872,25 @@ static int l2cap_sock_release(struct socket *sock) return err; } +static void l2cap_sock_cleanup_listen(struct sock *parent) +{ + struct sock *sk; + + BT_DBG("parent %p", parent); + + /* Close not yet accepted channels */ + while ((sk = bt_accept_dequeue(parent, NULL))) { + struct l2cap_chan *chan = l2cap_pi(sk)->chan; + + l2cap_chan_lock(chan); + __clear_chan_timer(chan); + l2cap_chan_close(chan, ECONNRESET); + l2cap_chan_unlock(chan); + + l2cap_sock_kill(sk); + } +} + static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) { struct sock *sk, *parent = chan->data; @@ -931,6 +950,47 @@ static void l2cap_sock_close_cb(struct l2cap_chan *chan) l2cap_sock_kill(sk); } +static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) +{ + struct sock *sk = chan->data; + struct sock *parent; + + lock_sock(sk); + + parent = bt_sk(sk)->parent; + + sock_set_flag(sk, SOCK_ZAPPED); + + switch (chan->state) { + case BT_OPEN: + case BT_BOUND: + case BT_CLOSED: + break; + case BT_LISTEN: + l2cap_sock_cleanup_listen(sk); + sk->sk_state = BT_CLOSED; + chan->state = BT_CLOSED; + + break; + default: + sk->sk_state = BT_CLOSED; + chan->state = BT_CLOSED; + + sk->sk_err = err; + + if (parent) { + bt_accept_unlink(sk); + parent->sk_data_ready(parent, 0); + } else { + sk->sk_state_change(sk); + } + + break; + } + + release_sock(sk); +} + static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state) { struct sock *sk = chan->data; @@ -959,6 +1019,7 @@ static struct l2cap_ops l2cap_chan_ops = { .new_connection = l2cap_sock_new_connection_cb, .recv = l2cap_sock_recv_cb, .close = l2cap_sock_close_cb, + .teardown = l2cap_sock_teardown_cb, .state_change = l2cap_sock_state_change_cb, .alloc_skb = l2cap_sock_alloc_skb_cb, }; -- GitLab From 54a59aa2b562872781d6a8fc89f300d360941691 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Sun, 27 May 2012 22:27:53 -0300 Subject: [PATCH 0323/6849] Bluetooth: Add l2cap_chan->ops->ready() This move socket specific code to l2cap_sock.c. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 18 +++--------------- net/bluetooth/l2cap_sock.c | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 76b0e7e5dec2..c5726c24ee03 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -534,6 +534,7 @@ struct l2cap_ops { void (*close) (struct l2cap_chan *chan); void (*state_change) (struct l2cap_chan *chan, int state); + void (*ready) (struct l2cap_chan *chan); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, unsigned long len, int nb); }; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 1f4c72074154..5947eb1c1bee 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -931,26 +931,14 @@ static void l2cap_send_conn_req(struct l2cap_chan *chan) static void l2cap_chan_ready(struct l2cap_chan *chan) { - struct sock *sk = chan->sk; - struct sock *parent; - - lock_sock(sk); - - parent = bt_sk(sk)->parent; - - BT_DBG("sk %p, parent %p", sk, parent); - /* This clears all conf flags, including CONF_NOT_COMPLETE */ chan->conf_state = 0; __clear_chan_timer(chan); - __l2cap_state_change(chan, BT_CONNECTED); - sk->sk_state_change(sk); + chan->state = BT_CONNECTED; - if (parent) - parent->sk_data_ready(parent, 0); - - release_sock(sk); + if (chan->ops->ready) + chan->ops->ready(chan); } static void l2cap_do_start(struct l2cap_chan *chan) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 3f5946351fb9..5563023001c6 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1014,6 +1014,26 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, return skb; } +static void l2cap_sock_ready_cb(struct l2cap_chan *chan) +{ + struct sock *sk = chan->data; + struct sock *parent; + + lock_sock(sk); + + parent = bt_sk(sk)->parent; + + BT_DBG("sk %p, parent %p", sk, parent); + + sk->sk_state = BT_CONNECTED; + sk->sk_state_change(sk); + + if (parent) + parent->sk_data_ready(parent, 0); + + release_sock(sk); +} + static struct l2cap_ops l2cap_chan_ops = { .name = "L2CAP Socket Interface", .new_connection = l2cap_sock_new_connection_cb, @@ -1021,6 +1041,7 @@ static struct l2cap_ops l2cap_chan_ops = { .close = l2cap_sock_close_cb, .teardown = l2cap_sock_teardown_cb, .state_change = l2cap_sock_state_change_cb, + .ready = l2cap_sock_ready_cb, .alloc_skb = l2cap_sock_alloc_skb_cb, }; -- GitLab From 0797e01d877b9677d07b89e0776c061df8878f27 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Sun, 27 May 2012 22:27:54 -0300 Subject: [PATCH 0324/6849] Bluetooth: Use chan->state instead of sk->sk_state These vars are kept in sync so we can use chan->state here. Signed-off-by: Gustavo Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5947eb1c1bee..35e6d7dd329b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1442,21 +1442,17 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, goto done; } - lock_sock(sk); - - switch (sk->sk_state) { + switch (chan->state) { case BT_CONNECT: case BT_CONNECT2: case BT_CONFIG: /* Already connecting */ err = 0; - release_sock(sk); goto done; case BT_CONNECTED: /* Already connected */ err = -EISCONN; - release_sock(sk); goto done; case BT_OPEN: @@ -1466,13 +1462,12 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, default: err = -EBADFD; - release_sock(sk); goto done; } /* Set destination address and psm */ + lock_sock(sk); bacpy(&bt_sk(sk)->dst, dst); - release_sock(sk); chan->psm = psm; -- GitLab From 538266929eb7165f92b91eb0f403120fe759e742 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Sun, 27 May 2012 22:27:55 -0300 Subject: [PATCH 0325/6849] Bluetooth: Move check for backlog size to l2cap_sock.c Remove socket specific code from l2cap_core.c Signed-off-by: Gustavo Padovan Acked-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 12 ------------ net/bluetooth/l2cap_sock.c | 6 ++++++ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 35e6d7dd329b..d64c836f2bcf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1156,12 +1156,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) lock_sock(parent); - /* Check for backlog size */ - if (sk_acceptq_is_full(parent)) { - BT_DBG("backlog full %d", parent->sk_ack_backlog); - goto clean; - } - chan = pchan->ops->new_connection(pchan); if (!chan) goto clean; @@ -3349,12 +3343,6 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd result = L2CAP_CR_NO_MEM; - /* Check for backlog size */ - if (sk_acceptq_is_full(parent)) { - BT_DBG("backlog full %d", parent->sk_ack_backlog); - goto response; - } - chan = pchan->ops->new_connection(pchan); if (!chan) goto response; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5563023001c6..d856cc8f22a3 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -895,6 +895,12 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) { struct sock *sk, *parent = chan->data; + /* Check for backlog size */ + if (sk_acceptq_is_full(parent)) { + BT_DBG("backlog full %d", parent->sk_ack_backlog); + return NULL; + } + sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); if (!sk) -- GitLab From 2dfa1003ccd19b435de0be00f6afb7ccdffd7596 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Sun, 27 May 2012 22:27:58 -0300 Subject: [PATCH 0326/6849] Bluetooth: check for already existent channel before create new one Move this check to before the channel time creation simplifies the code and avoid memory allocation if the channel already exist. Signed-off-by: Gustavo Padovan Acked-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d64c836f2bcf..6f30d1da89a0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3343,21 +3343,16 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd result = L2CAP_CR_NO_MEM; + /* Check if we already have channel with that dcid */ + if (__l2cap_get_chan_by_dcid(conn, scid)) + goto response; + chan = pchan->ops->new_connection(pchan); if (!chan) goto response; sk = chan->sk; - /* Check if we already have channel with that dcid */ - if (__l2cap_get_chan_by_dcid(conn, scid)) { - if (chan->ops->teardown) - chan->ops->teardown(chan, 0); - - chan->ops->close(chan); - goto response; - } - hci_conn_hold(conn->hcon); bacpy(&bt_sk(sk)->src, conn->src); -- GitLab From 0181a70f549bd1683d18a5a1d79ac25bcdb76570 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 10:04:05 +0300 Subject: [PATCH 0327/6849] Bluetooth: trivial: Use defined PSMLEN instead of magic Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 6f30d1da89a0..778c0c8cdc59 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5235,7 +5235,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) case L2CAP_CID_CONN_LESS: psm = get_unaligned((__le16 *) skb->data); - skb_pull(skb, 2); + skb_pull(skb, L2CAP_PSMLEN_SIZE); l2cap_conless_channel(conn, psm, skb); break; -- GitLab From 466f8004f364e9cb46d9124109972489eccfb404 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:01 +0300 Subject: [PATCH 0328/6849] Bluetooth: A2MP: Create A2MP channel Create and initialize fixed A2MP channel Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 6 +++ net/bluetooth/Makefile | 3 +- net/bluetooth/a2mp.c | 69 +++++++++++++++++++++++++++++++++++ net/bluetooth/l2cap_core.c | 6 +-- 4 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 net/bluetooth/a2mp.c diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index c5726c24ee03..aaba222306b6 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -52,6 +52,8 @@ #define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) #define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) +#define L2CAP_A2MP_DEFAULT_MTU 670 + /* L2CAP socket address */ struct sockaddr_l2 { sa_family_t l2_family; @@ -236,6 +238,7 @@ struct l2cap_conn_rsp { /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 +#define L2CAP_CID_A2MP 0x0003 #define L2CAP_CID_LE_DATA 0x0004 #define L2CAP_CID_LE_SIGNALING 0x0005 #define L2CAP_CID_SMP 0x0006 @@ -758,5 +761,8 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, void l2cap_chan_busy(struct l2cap_chan *chan, int busy); int l2cap_chan_check_security(struct l2cap_chan *chan); void l2cap_chan_set_defaults(struct l2cap_chan *chan); +int l2cap_ertm_init(struct l2cap_chan *chan); +void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); +void l2cap_chan_del(struct l2cap_chan *chan, int err); #endif /* __L2CAP_H */ diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 2dc5a5700f53..fa6d94a4602a 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_BT_CMTP) += cmtp/ obj-$(CONFIG_BT_HIDP) += hidp/ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ - hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o + hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ + a2mp.o diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c new file mode 100644 index 000000000000..de455a264451 --- /dev/null +++ b/net/bluetooth/a2mp.c @@ -0,0 +1,69 @@ +/* + Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved. + Copyright (c) 2011,2012 Intel Corp. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 and + only version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#include +#include +#include + +static struct l2cap_ops a2mp_chan_ops = { + .name = "L2CAP A2MP channel", +}; + +static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) +{ + struct l2cap_chan *chan; + int err; + + chan = l2cap_chan_create(); + if (!chan) + return NULL; + + BT_DBG("chan %p", chan); + + hci_conn_hold(conn->hcon); + + chan->omtu = L2CAP_A2MP_DEFAULT_MTU; + chan->imtu = L2CAP_A2MP_DEFAULT_MTU; + chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; + + chan->ops = &a2mp_chan_ops; + + l2cap_chan_set_defaults(chan); + chan->remote_max_tx = chan->max_tx; + chan->remote_tx_win = chan->tx_win; + + chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO; + chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; + + skb_queue_head_init(&chan->tx_q); + + chan->mode = L2CAP_MODE_ERTM; + + err = l2cap_ertm_init(chan); + if (err < 0) { + l2cap_chan_del(chan, 0); + return NULL; + } + + chan->conf_state = 0; + + l2cap_chan_add(conn, chan); + + chan->remote_mps = chan->omtu; + chan->mps = chan->omtu; + + chan->state = BT_CONNECTED; + + return chan; +} diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 778c0c8cdc59..2c616cf24c71 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -484,14 +484,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) list_add(&chan->list, &conn->chan_l); } -static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) +void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { mutex_lock(&conn->chan_lock); __l2cap_chan_add(conn, chan); mutex_unlock(&conn->chan_lock); } -static void l2cap_chan_del(struct l2cap_chan *chan, int err) +void l2cap_chan_del(struct l2cap_chan *chan, int err) { struct l2cap_conn *conn = chan->conn; @@ -2691,7 +2691,7 @@ static void l2cap_ack_timeout(struct work_struct *work) l2cap_chan_put(chan); } -static inline int l2cap_ertm_init(struct l2cap_chan *chan) +int l2cap_ertm_init(struct l2cap_chan *chan) { int err; -- GitLab From 9740e49d17e55f3832661fd99a8e0a17e921a82e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:02 +0300 Subject: [PATCH 0329/6849] Bluetooth: A2MP: AMP Manager basic functions Define AMP Manager and some basic functions. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/a2mp.h | 30 ++++++++++++++++++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/a2mp.c | 54 ++++++++++++++++++++++++++++++++ net/bluetooth/hci_conn.c | 4 +++ 4 files changed, 89 insertions(+) create mode 100644 include/net/bluetooth/a2mp.h diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h new file mode 100644 index 000000000000..ff4754000cf8 --- /dev/null +++ b/include/net/bluetooth/a2mp.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved. + Copyright (c) 2011,2012 Intel Corp. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 and + only version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#ifndef __A2MP_H +#define __A2MP_H + +struct amp_mgr { + struct l2cap_conn *l2cap_conn; + struct l2cap_chan *a2mp_chan; + struct kref kref; + __u8 ident; + __u8 handle; + unsigned long flags; +}; + +void amp_mgr_get(struct amp_mgr *mgr); +int amp_mgr_put(struct amp_mgr *mgr); + +#endif /* __A2MP_H */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d584a47d1c86..6e64b76e30aa 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -332,6 +332,7 @@ struct hci_conn { void *l2cap_data; void *sco_data; void *smp_conn; + struct amp_mgr *amp_mgr; struct hci_conn *link; diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index de455a264451..3c241c2b3e1a 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -15,6 +15,7 @@ #include #include #include +#include static struct l2cap_ops a2mp_chan_ops = { .name = "L2CAP A2MP channel", @@ -67,3 +68,56 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) return chan; } + +/* AMP Manager functions */ +void amp_mgr_get(struct amp_mgr *mgr) +{ + BT_DBG("mgr %p", mgr); + + kref_get(&mgr->kref); +} + +static void amp_mgr_destroy(struct kref *kref) +{ + struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref); + + BT_DBG("mgr %p", mgr); + + kfree(mgr); +} + +int amp_mgr_put(struct amp_mgr *mgr) +{ + BT_DBG("mgr %p", mgr); + + return kref_put(&mgr->kref, &_mgr_destroy); +} + +static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) +{ + struct amp_mgr *mgr; + struct l2cap_chan *chan; + + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + if (!mgr) + return NULL; + + BT_DBG("conn %p mgr %p", conn, mgr); + + mgr->l2cap_conn = conn; + + chan = a2mp_chan_open(conn); + if (!chan) { + kfree(mgr); + return NULL; + } + + mgr->a2mp_chan = chan; + chan->data = mgr; + + conn->hcon->amp_mgr = mgr; + + kref_init(&mgr->kref); + + return mgr; +} diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 126876d915f5..1458667b2845 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -28,6 +28,7 @@ #include #include +#include static void hci_le_connect(struct hci_conn *conn) { @@ -411,6 +412,9 @@ int hci_conn_del(struct hci_conn *conn) hci_chan_list_flush(conn); + if (conn->amp_mgr) + amp_mgr_put(conn->amp_mgr); + hci_conn_hash_del(hdev, conn); if (hdev->notify) hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); -- GitLab From f6d3c6e783b0e9f75b18232f8ff8cd5dbc3f7301 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:03 +0300 Subject: [PATCH 0330/6849] Bluetooth: A2MP: Build and Send msg helpers Helper function to build and send A2MP messages. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/a2mp.h | 7 ++++++ net/bluetooth/a2mp.c | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index ff4754000cf8..654df60cfd6d 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h @@ -24,6 +24,13 @@ struct amp_mgr { unsigned long flags; }; +struct a2mp_cmd { + __u8 code; + __u8 ident; + __le16 len; + __u8 data[0]; +} __packed; + void amp_mgr_get(struct amp_mgr *mgr); int amp_mgr_put(struct amp_mgr *mgr); diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 3c241c2b3e1a..53f49a0b7f9a 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -17,6 +17,52 @@ #include #include +/* A2MP build & send command helper functions */ +static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) +{ + struct a2mp_cmd *cmd; + int plen; + + plen = sizeof(*cmd) + len; + cmd = kzalloc(plen, GFP_KERNEL); + if (!cmd) + return NULL; + + cmd->code = code; + cmd->ident = ident; + cmd->len = cpu_to_le16(len); + + memcpy(cmd->data, data, len); + + return cmd; +} + +static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, + void *data) +{ + struct l2cap_chan *chan = mgr->a2mp_chan; + struct a2mp_cmd *cmd; + u16 total_len = len + sizeof(*cmd); + struct kvec iv; + struct msghdr msg; + + cmd = __a2mp_build(code, ident, len, data); + if (!cmd) + return; + + iv.iov_base = cmd; + iv.iov_len = total_len; + + memset(&msg, 0, sizeof(msg)); + + msg.msg_iov = (struct iovec *) &iv; + msg.msg_iovlen = 1; + + l2cap_chan_send(chan, &msg, total_len, 0); + + kfree(cmd); +} + static struct l2cap_ops a2mp_chan_ops = { .name = "L2CAP A2MP channel", }; -- GitLab From 46d5c9088fbcc8a570bc271f77940973d9cae074 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:04 +0300 Subject: [PATCH 0331/6849] Bluetooth: A2MP: Add chan callbacks Add L2CAP chan ops callbacks. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 53f49a0b7f9a..f7c710cacf44 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -63,8 +63,63 @@ static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, kfree(cmd); } +static void a2mp_chan_close_cb(struct l2cap_chan *chan) +{ + l2cap_chan_destroy(chan); +} + +static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state) +{ + struct amp_mgr *mgr = chan->data; + + if (!mgr) + return; + + BT_DBG("chan %p state %s", chan, state_to_string(state)); + + chan->state = state; + + switch (state) { + case BT_CLOSED: + if (mgr) + amp_mgr_put(mgr); + break; + } +} + +static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, + unsigned long len, int nb) +{ + return bt_skb_alloc(len, GFP_KERNEL); +} + +static struct l2cap_chan *a2mp_chan_no_new_conn_cb(struct l2cap_chan *chan) +{ + BT_ERR("new_connection for chan %p not implemented", chan); + + return NULL; +} + +static void a2mp_chan_no_teardown_cb(struct l2cap_chan *chan, int err) +{ + BT_ERR("teardown for chan %p not implemented", chan); +} + +static void a2mp_chan_no_ready(struct l2cap_chan *chan) +{ + BT_ERR("ready for chan %p not implemented", chan); +} + static struct l2cap_ops a2mp_chan_ops = { .name = "L2CAP A2MP channel", + .close = a2mp_chan_close_cb, + .state_change = a2mp_chan_state_change_cb, + .alloc_skb = a2mp_chan_alloc_skb_cb, + + /* Not implemented for A2MP */ + .new_connection = a2mp_chan_no_new_conn_cb, + .teardown = a2mp_chan_no_teardown_cb, + .ready = a2mp_chan_no_ready, }; static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) -- GitLab From b9058fb67c42851b4f852d90b11f43279586aae9 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:05 +0300 Subject: [PATCH 0332/6849] Bluetooth: A2MP: Definitions for A2MP commands Define A2MP command IDs and packet structures. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/a2mp.h | 73 ++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index 654df60cfd6d..7cbeb911fbd1 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h @@ -31,6 +31,79 @@ struct a2mp_cmd { __u8 data[0]; } __packed; +/* A2MP command codes */ +#define A2MP_COMMAND_REJ 0x01 +struct a2mp_cmd_rej { + __le16 reason; + __u8 data[0]; +} __packed; + +#define A2MP_DISCOVER_REQ 0x02 +struct a2mp_discov_req { + __le16 mtu; + __le16 ext_feat; +} __packed; + +struct a2mp_cl { + __u8 id; + __u8 type; + __u8 status; +} __packed; + +#define A2MP_DISCOVER_RSP 0x03 +struct a2mp_discov_rsp { + __le16 mtu; + __le16 ext_feat; + struct a2mp_cl cl[0]; +} __packed; + +#define A2MP_CHANGE_NOTIFY 0x04 +#define A2MP_CHANGE_RSP 0x05 + +#define A2MP_GETINFO_REQ 0x06 +struct a2mp_info_req { + __u8 id; +} __packed; + +#define A2MP_GETINFO_RSP 0x07 +struct a2mp_info_rsp { + __u8 id; + __u8 status; + __le32 total_bw; + __le32 max_bw; + __le32 min_latency; + __le16 pal_cap; + __le16 assoc_size; +} __packed; + +#define A2MP_GETAMPASSOC_REQ 0x08 +struct a2mp_amp_assoc_req { + __u8 id; +} __packed; + +#define A2MP_GETAMPASSOC_RSP 0x09 +struct a2mp_amp_assoc_rsp { + __u8 id; + __u8 status; + __u8 amp_assoc[0]; +} __packed; + +#define A2MP_CREATEPHYSLINK_REQ 0x0A +#define A2MP_DISCONNPHYSLINK_REQ 0x0C +struct a2mp_physlink_req { + __u8 local_id; + __u8 remote_id; + __u8 amp_assoc[0]; +} __packed; + +#define A2MP_CREATEPHYSLINK_RSP 0x0B +#define A2MP_DISCONNPHYSLINK_RSP 0x0D +struct a2mp_physlink_rsp { + __u8 local_id; + __u8 remote_id; + __u8 status; +} __packed; + void amp_mgr_get(struct amp_mgr *mgr); int amp_mgr_put(struct amp_mgr *mgr); -- GitLab From e7af522e04bcf68caae6802722efc5c6e8fa63a7 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:06 +0300 Subject: [PATCH 0333/6849] Bluetooth: A2MP: Define A2MP status codes A2MP status codes copied from Bluez patch sent by Peter Krystad . Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/a2mp.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index 7cbeb911fbd1..391acd7a67d4 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h @@ -104,6 +104,16 @@ struct a2mp_physlink_rsp { __u8 status; } __packed; +/* A2MP response status */ +#define A2MP_STATUS_SUCCESS 0x00 +#define A2MP_STATUS_INVALID_CTRL_ID 0x01 +#define A2MP_STATUS_UNABLE_START_LINK_CREATION 0x02 +#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02 +#define A2MP_STATUS_COLLISION_OCCURED 0x03 +#define A2MP_STATUS_DISCONN_REQ_RECVD 0x04 +#define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 +#define A2MP_STATUS_SECURITY_VIOLATION 0x06 + void amp_mgr_get(struct amp_mgr *mgr); int amp_mgr_put(struct amp_mgr *mgr); -- GitLab From 6b44d9b8d96b37f72ccd7335b32f386a67b7f1f4 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:07 +0300 Subject: [PATCH 0334/6849] Bluetooth: A2MP: Process A2MP messages Implement basic processing for AMP Manager Protocol (A2MP). Example below shows processing unrecognized command. ... > ACL data: handle 11 flags 0x02 dlen 12 A2MP: code 0x00 ident 3 len 0 < ACL data: handle 11 flags 0x00 dlen 14 A2MP: Command Reject: reason (0) - Command not recognized ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index f7c710cacf44..0726c9fe005c 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -63,6 +63,70 @@ static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, kfree(cmd); } +/* Handle A2MP signalling */ +static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) +{ + struct a2mp_cmd *hdr = (void *) skb->data; + struct amp_mgr *mgr = chan->data; + int err = 0; + + amp_mgr_get(mgr); + + while (skb->len >= sizeof(*hdr)) { + struct a2mp_cmd *hdr = (void *) skb->data; + u16 len = le16_to_cpu(hdr->len); + + BT_DBG("code 0x%02x id %d len %d", hdr->code, hdr->ident, len); + + skb_pull(skb, sizeof(*hdr)); + + if (len > skb->len || !hdr->ident) { + err = -EINVAL; + break; + } + + mgr->ident = hdr->ident; + + switch (hdr->code) { + case A2MP_COMMAND_REJ: + case A2MP_DISCOVER_REQ: + case A2MP_CHANGE_NOTIFY: + case A2MP_GETINFO_REQ: + case A2MP_GETAMPASSOC_REQ: + case A2MP_CREATEPHYSLINK_REQ: + case A2MP_DISCONNPHYSLINK_REQ: + case A2MP_CHANGE_RSP: + case A2MP_DISCOVER_RSP: + case A2MP_GETINFO_RSP: + case A2MP_GETAMPASSOC_RSP: + case A2MP_CREATEPHYSLINK_RSP: + case A2MP_DISCONNPHYSLINK_RSP: + default: + BT_ERR("Unknown A2MP sig cmd 0x%2.2x", hdr->code); + err = -EINVAL; + break; + } + } + + if (err) { + struct a2mp_cmd_rej rej; + rej.reason = __constant_cpu_to_le16(0); + + BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err); + + a2mp_send(mgr, A2MP_COMMAND_REJ, hdr->ident, sizeof(rej), + &rej); + } + + /* Always free skb and return success error code to prevent + from sending L2CAP Disconnect over A2MP channel */ + kfree_skb(skb); + + amp_mgr_put(mgr); + + return 0; +} + static void a2mp_chan_close_cb(struct l2cap_chan *chan) { l2cap_chan_destroy(chan); @@ -112,6 +176,7 @@ static void a2mp_chan_no_ready(struct l2cap_chan *chan) static struct l2cap_ops a2mp_chan_ops = { .name = "L2CAP A2MP channel", + .recv = a2mp_chan_recv_cb, .close = a2mp_chan_close_cb, .state_change = a2mp_chan_state_change_cb, .alloc_skb = a2mp_chan_alloc_skb_cb, -- GitLab From 21dbd2ce35f6d2b4aa5363be6c839cdb50644e11 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:08 +0300 Subject: [PATCH 0335/6849] Bluetooth: A2MP: Process A2MP Command Reject Placeholder for future A2MP Command Reject handler. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 0726c9fe005c..188b42120074 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -63,6 +63,22 @@ static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, kfree(cmd); } +/* Processing A2MP messages */ +static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_cmd_rej *rej = (void *) skb->data; + + if (le16_to_cpu(hdr->len) < sizeof(*rej)) + return -EINVAL; + + BT_DBG("ident %d reason %d", hdr->ident, le16_to_cpu(rej->reason)); + + skb_pull(skb, sizeof(*rej)); + + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -89,6 +105,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) switch (hdr->code) { case A2MP_COMMAND_REJ: + a2mp_command_rej(mgr, skb, hdr); + break; + case A2MP_DISCOVER_REQ: case A2MP_CHANGE_NOTIFY: case A2MP_GETINFO_REQ: -- GitLab From 8598d064cbf22b2d84c7cd8a9fcb97138baffe3f Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:09 +0300 Subject: [PATCH 0336/6849] Bluetooth: A2MP: Process A2MP Discover Request Adds helper functions to count HCI devs and process A2MP Discover Request, code makes sure that first controller in the list is BREDR one. Trace is shown below: ... > ACL data: handle 11 flags 0x02 dlen 16 A2MP: Discover req: mtu/mps 670 mask: 0x0000 < ACL data: handle 11 flags 0x00 dlen 22 A2MP: Discover rsp: mtu/mps 670 mask: 0x0000 Controller list: id 0 type 0 (BR-EDR) status 0x01 (Bluetooth only) id 1 type 1 (802.11 AMP) status 0x01 (Bluetooth only) ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/a2mp.h | 2 + include/net/bluetooth/hci.h | 3 ++ include/net/bluetooth/hci_core.h | 13 +++++ net/bluetooth/a2mp.c | 85 ++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index 391acd7a67d4..96f9cc2cf59b 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h @@ -15,6 +15,8 @@ #ifndef __A2MP_H #define __A2MP_H +#define A2MP_FEAT_EXT 0x8000 + struct amp_mgr { struct l2cap_conn *l2cap_conn; struct l2cap_chan *a2mp_chan; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index de09a26e4223..66af2c6193d5 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -59,6 +59,9 @@ #define HCI_BREDR 0x00 #define HCI_AMP 0x01 +/* First BR/EDR Controller shall have ID = 0 */ +#define HCI_BREDR_ID 0 + /* HCI device quirks */ enum { HCI_QUIRK_RESET_ON_CLOSE, diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6e64b76e30aa..20fd57367ddc 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -641,6 +641,19 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) dev_set_drvdata(&hdev->dev, data); } +/* hci_dev_list shall be locked */ +static inline uint8_t __hci_num_ctrl(void) +{ + uint8_t count = 0; + struct list_head *p; + + list_for_each(p, &hci_dev_list) { + count++; + } + + return count; +} + struct hci_dev *hci_dev_get(int index); struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 188b42120074..1cc920a62b0f 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -63,6 +63,36 @@ static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, kfree(cmd); } +static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) +{ + cl->id = 0; + cl->type = 0; + cl->status = 1; +} + +/* hci_dev_list shall be locked */ +static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl) +{ + int i = 0; + struct hci_dev *hdev; + + __a2mp_cl_bredr(cl); + + list_for_each_entry(hdev, &hci_dev_list, list) { + /* Iterate through AMP controllers */ + if (hdev->id == HCI_BREDR_ID) + continue; + + /* Starting from second entry */ + if (++i >= num_ctrl) + return; + + cl[i].id = hdev->id; + cl[i].type = hdev->amp_type; + cl[i].status = hdev->amp_status; + } +} + /* Processing A2MP messages */ static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_cmd *hdr) @@ -79,6 +109,58 @@ static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb, return 0; } +static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_discov_req *req = (void *) skb->data; + u16 len = le16_to_cpu(hdr->len); + struct a2mp_discov_rsp *rsp; + u16 ext_feat; + u8 num_ctrl; + + if (len < sizeof(*req)) + return -EINVAL; + + skb_pull(skb, sizeof(*req)); + + ext_feat = le16_to_cpu(req->ext_feat); + + BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(req->mtu), ext_feat); + + /* check that packet is not broken for now */ + while (ext_feat & A2MP_FEAT_EXT) { + if (len < sizeof(ext_feat)) + return -EINVAL; + + ext_feat = get_unaligned_le16(skb->data); + BT_DBG("efm 0x%4.4x", ext_feat); + len -= sizeof(ext_feat); + skb_pull(skb, sizeof(ext_feat)); + } + + read_lock(&hci_dev_list_lock); + + num_ctrl = __hci_num_ctrl(); + len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp); + rsp = kmalloc(len, GFP_ATOMIC); + if (!rsp) { + read_unlock(&hci_dev_list_lock); + return -ENOMEM; + } + + rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); + rsp->ext_feat = 0; + + __a2mp_add_cl(mgr, rsp->cl, num_ctrl); + + read_unlock(&hci_dev_list_lock); + + a2mp_send(mgr, A2MP_DISCOVER_RSP, hdr->ident, len, rsp); + + kfree(rsp); + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -109,6 +191,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) break; case A2MP_DISCOVER_REQ: + err = a2mp_discover_req(mgr, skb, hdr); + break; + case A2MP_CHANGE_NOTIFY: case A2MP_GETINFO_REQ: case A2MP_GETAMPASSOC_REQ: -- GitLab From 329d81af29344a2ad2f9595310be74644421797a Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:10 +0300 Subject: [PATCH 0337/6849] Bluetooth: A2MP: Process A2MP Change Notify Placeholder for A2MP Change Notify handler. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 1cc920a62b0f..6cdaa85ab5e9 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -161,6 +161,22 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, return 0; } +static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_cl *cl = (void *) skb->data; + + while (skb->len >= sizeof(*cl)) { + BT_DBG("Controller id %d type %d status %d", cl->id, cl->type, + cl->status); + cl = (struct a2mp_cl *) skb_pull(skb, sizeof(*cl)); + } + + /* TODO send A2MP_CHANGE_RSP */ + + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -195,6 +211,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) break; case A2MP_CHANGE_NOTIFY: + err = a2mp_change_notify(mgr, skb, hdr); + break; + case A2MP_GETINFO_REQ: case A2MP_GETAMPASSOC_REQ: case A2MP_CREATEPHYSLINK_REQ: -- GitLab From 47f2d97d38816aaca94c9b6961c6eff1cfcd0bd6 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:11 +0300 Subject: [PATCH 0338/6849] Bluetooth: A2MP: Process A2MP Get Info Request Process A2MP Get Info Request. Example of trace log for invalid controller id is shown below: ... > ACL data: handle 11 flags 0x02 dlen 13 A2MP: Get Info req: id 238 < ACL data: handle 11 flags 0x00 dlen 30 A2MP: Get Info rsp: id 238 status (1) Invalid Controller ID ... Note that If the Status field is set to Invalid Controller ID all subsequent fields in the AMP Get Info Response shall be ignored by the receiver. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 6cdaa85ab5e9..350088e2015a 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -177,6 +177,40 @@ static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, return 0; } +static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_info_req *req = (void *) skb->data; + struct a2mp_info_rsp rsp; + struct hci_dev *hdev; + + if (le16_to_cpu(hdr->len) < sizeof(*req)) + return -EINVAL; + + BT_DBG("id %d", req->id); + + rsp.id = req->id; + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; + + hdev = hci_dev_get(req->id); + if (hdev && hdev->amp_type != HCI_BREDR) { + rsp.status = 0; + rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); + rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); + rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); + rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); + rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); + } + + if (hdev) + hci_dev_put(hdev); + + a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp); + + skb_pull(skb, sizeof(*req)); + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -215,6 +249,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) break; case A2MP_GETINFO_REQ: + err = a2mp_getinfo_req(mgr, skb, hdr); + break; + case A2MP_GETAMPASSOC_REQ: case A2MP_CREATEPHYSLINK_REQ: case A2MP_DISCONNPHYSLINK_REQ: -- GitLab From a28381dc9ca3e54b0678e2cd7c68c1afb2d7cc76 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:12 +0300 Subject: [PATCH 0339/6849] Bluetooth: A2MP: Process A2MP Get AMP Assoc Request Example trace when receiving AMP Assoc Request with wrong AMP id. ... > ACL data: handle 11 flags 0x02 dlen 13 A2MP: Get AMP Assoc req: id 238 < ACL data: handle 11 flags 0x00 dlen 14 A2MP: Get AMP Assoc rsp: id 238 status (1) Invalid Controller ID assoc data: ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 350088e2015a..b8eeb33d60d7 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -211,6 +211,38 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, return 0; } +static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_amp_assoc_req *req = (void *) skb->data; + struct hci_dev *hdev; + + if (le16_to_cpu(hdr->len) < sizeof(*req)) + return -EINVAL; + + BT_DBG("id %d", req->id); + + hdev = hci_dev_get(req->id); + if (!hdev || hdev->amp_type == HCI_BREDR) { + struct a2mp_amp_assoc_rsp rsp; + rsp.id = req->id; + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; + + a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp), + &rsp); + goto clean; + } + + /* Placeholder for HCI Read AMP Assoc */ + +clean: + if (hdev) + hci_dev_put(hdev); + + skb_pull(skb, sizeof(*req)); + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -253,6 +285,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) break; case A2MP_GETAMPASSOC_REQ: + err = a2mp_getampassoc_req(mgr, skb, hdr); + break; + case A2MP_CREATEPHYSLINK_REQ: case A2MP_DISCONNPHYSLINK_REQ: case A2MP_CHANGE_RSP: -- GitLab From e072f5dab22e7bf0a10daf854acc0fc271396ee7 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:13 +0300 Subject: [PATCH 0340/6849] Bluetooth: A2MP: Process A2MP Create Physlink Request Placeholder for A2MP Create Physlink Request. Handles requests with invalid controler id as shown below: ... > ACL data: handle 11 flags 0x02 dlen 50 A2MP: Create Physical Link req: local id 1 remote id 85 Assoc data: < ACL data: handle 11 flags 0x00 dlen 15 A2MP: Create Physical Link rsp: local id 85 remote id 1 status 1 Invalid Controller ID ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index b8eeb33d60d7..ca52a91edd29 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -243,6 +243,43 @@ clean: return 0; } +static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_physlink_req *req = (void *) skb->data; + + struct a2mp_physlink_rsp rsp; + struct hci_dev *hdev; + + if (le16_to_cpu(hdr->len) < sizeof(*req)) + return -EINVAL; + + BT_DBG("local_id %d, remote_id %d", req->local_id, req->remote_id); + + rsp.local_id = req->remote_id; + rsp.remote_id = req->local_id; + + hdev = hci_dev_get(req->remote_id); + if (!hdev || hdev->amp_type != HCI_AMP) { + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; + goto send_rsp; + } + + /* TODO process physlink create */ + + rsp.status = A2MP_STATUS_SUCCESS; + +send_rsp: + if (hdev) + hci_dev_put(hdev); + + a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, sizeof(rsp), + &rsp); + + skb_pull(skb, le16_to_cpu(hdr->len)); + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -289,6 +326,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) break; case A2MP_CREATEPHYSLINK_REQ: + err = a2mp_createphyslink_req(mgr, skb, hdr); + break; + case A2MP_DISCONNPHYSLINK_REQ: case A2MP_CHANGE_RSP: case A2MP_DISCOVER_RSP: -- GitLab From 6113f84fc1a8962aed25f54a115b196e9aea151f Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:14 +0300 Subject: [PATCH 0341/6849] Bluetooth: A2MP: Process A2MP Disc Physlink Request Placeholder for A2MP Disconnect Physlink Request. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index ca52a91edd29..400696b3b817 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -280,6 +280,39 @@ send_rsp: return 0; } +static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + struct a2mp_physlink_req *req = (void *) skb->data; + struct a2mp_physlink_rsp rsp; + struct hci_dev *hdev; + + if (le16_to_cpu(hdr->len) < sizeof(*req)) + return -EINVAL; + + BT_DBG("local_id %d remote_id %d", req->local_id, req->remote_id); + + rsp.local_id = req->remote_id; + rsp.remote_id = req->local_id; + rsp.status = A2MP_STATUS_SUCCESS; + + hdev = hci_dev_get(req->local_id); + if (!hdev) { + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; + goto send_rsp; + } + + /* TODO Disconnect Phys Link here */ + + hci_dev_put(hdev); + +send_rsp: + a2mp_send(mgr, A2MP_DISCONNPHYSLINK_RSP, hdr->ident, sizeof(rsp), &rsp); + + skb_pull(skb, sizeof(*req)); + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -330,6 +363,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) break; case A2MP_DISCONNPHYSLINK_REQ: + err = a2mp_discphyslink_req(mgr, skb, hdr); + break; + case A2MP_CHANGE_RSP: case A2MP_DISCOVER_RSP: case A2MP_GETINFO_RSP: -- GitLab From f6410a849b76f56c78d989786eb427b85a559b9f Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:15 +0300 Subject: [PATCH 0342/6849] Bluetooth: A2MP: Process A2MP Command Responses Process A2MP responses, print cmd code and ident for now. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 400696b3b817..6a933dab1b7f 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -313,6 +313,15 @@ send_rsp: return 0; } +static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb, + struct a2mp_cmd *hdr) +{ + BT_DBG("ident %d code %d", hdr->ident, hdr->code); + + skb_pull(skb, le16_to_cpu(hdr->len)); + return 0; +} + /* Handle A2MP signalling */ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { @@ -372,6 +381,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) case A2MP_GETAMPASSOC_RSP: case A2MP_CREATEPHYSLINK_RSP: case A2MP_DISCONNPHYSLINK_RSP: + err = a2mp_cmd_rsp(mgr, skb, hdr); + break; + default: BT_ERR("Unknown A2MP sig cmd 0x%2.2x", hdr->code); err = -EINVAL; -- GitLab From 416fa7527d6bf658e5517ea36d2de9270be2c11e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:16 +0300 Subject: [PATCH 0343/6849] Bluetooth: A2MP: Handling fixed channels A2MP fixed channel do not have sk Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/a2mp.c | 3 +-- net/bluetooth/l2cap_core.c | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index aaba222306b6..a00b43ecbc77 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -581,6 +581,7 @@ struct l2cap_conn { #define L2CAP_CHAN_RAW 1 #define L2CAP_CHAN_CONN_LESS 2 #define L2CAP_CHAN_CONN_ORIENTED 3 +#define L2CAP_CHAN_CONN_FIX_A2MP 4 /* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 6a933dab1b7f..f1ec1b1d308f 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -483,8 +483,7 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) hci_conn_hold(conn->hcon); - chan->omtu = L2CAP_A2MP_DEFAULT_MTU; - chan->imtu = L2CAP_A2MP_DEFAULT_MTU; + chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP; chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; chan->ops = &a2mp_chan_ops; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2c616cf24c71..fc572795497a 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -465,6 +465,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) chan->omtu = L2CAP_DEFAULT_MTU; break; + case L2CAP_CHAN_CONN_FIX_A2MP: + chan->scid = L2CAP_CID_A2MP; + chan->dcid = L2CAP_CID_A2MP; + chan->omtu = L2CAP_A2MP_DEFAULT_MTU; + chan->imtu = L2CAP_A2MP_DEFAULT_MTU; + break; + default: /* Raw socket can send/recv signalling messages only */ chan->scid = L2CAP_CID_SIGNALING; @@ -1001,6 +1008,11 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c __clear_ack_timer(chan); } + if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { + __l2cap_state_change(chan, BT_DISCONN); + return; + } + req.dcid = cpu_to_le16(chan->dcid); req.scid = cpu_to_le16(chan->scid); l2cap_send_cmd(conn, l2cap_get_ident(conn), @@ -1195,6 +1207,11 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) l2cap_chan_lock(chan); + if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { + l2cap_chan_unlock(chan); + continue; + } + if (conn->hcon->type == LE_LINK) { if (smp_conn_security(conn, chan->sec_level)) l2cap_chan_ready(chan); -- GitLab From 97e8e89d2d8185b7644c9941636d3682eedc517b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 29 May 2012 13:59:17 +0300 Subject: [PATCH 0344/6849] Bluetooth: A2MP: Manage incoming connections Handle incoming A2MP connection by creating AMP manager and processing A2MP messages. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/a2mp.h | 4 ++++ net/bluetooth/a2mp.c | 16 ++++++++++++++++ net/bluetooth/l2cap_core.c | 19 +++++++++++++++---- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h index 96f9cc2cf59b..6a76e0a0705e 100644 --- a/include/net/bluetooth/a2mp.h +++ b/include/net/bluetooth/a2mp.h @@ -15,6 +15,8 @@ #ifndef __A2MP_H #define __A2MP_H +#include + #define A2MP_FEAT_EXT 0x8000 struct amp_mgr { @@ -118,5 +120,7 @@ struct a2mp_physlink_rsp { void amp_mgr_get(struct amp_mgr *mgr); int amp_mgr_put(struct amp_mgr *mgr); +struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, + struct sk_buff *skb); #endif /* __A2MP_H */ diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index f1ec1b1d308f..e08ca2ac31aa 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -569,3 +569,19 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) return mgr; } + +struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, + struct sk_buff *skb) +{ + struct amp_mgr *mgr; + + mgr = amp_mgr_create(conn); + if (!mgr) { + BT_ERR("Could not create AMP manager"); + return NULL; + } + + BT_DBG("mgr: %p chan %p", mgr, mgr->a2mp_chan); + + return mgr->a2mp_chan; +} diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index fc572795497a..3daac2c6b7b4 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -37,6 +37,7 @@ #include #include #include +#include bool disable_ertm; @@ -5132,10 +5133,20 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk chan = l2cap_get_chan_by_scid(conn, cid); if (!chan) { - BT_DBG("unknown cid 0x%4.4x", cid); - /* Drop packet and return */ - kfree_skb(skb); - return 0; + if (cid == L2CAP_CID_A2MP) { + chan = a2mp_channel_create(conn, skb); + if (!chan) { + kfree_skb(skb); + return 0; + } + + l2cap_chan_lock(chan); + } else { + BT_DBG("unknown cid 0x%4.4x", cid); + /* Drop packet and return */ + kfree_skb(skb); + return 0; + } } BT_DBG("chan %p, len %d", chan, skb->len); -- GitLab From 1afd5be87e30997a5623260d9177ed62cf88adbe Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 28 May 2012 11:47:20 +0200 Subject: [PATCH 0345/6849] Bluetooth: Remove unused HCI timeouts definitions Those are not used anywhere in code (and never were since introduction in 2006) so just remove them. Signed-off-by: Szymon Janc Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 66af2c6193d5..3f5d682e866f 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -139,10 +139,8 @@ enum { #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ -#define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ -#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ #define HCI_CMD_TIMEOUT (1000) /* 1 seconds */ #define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */ -- GitLab From fd83e2c27c1bd8b0e9dc7596339c2411385f8b0c Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 30 May 2012 09:55:32 +0300 Subject: [PATCH 0346/6849] Bluetooth: Do not check func ready existence Functions will be always defined and in case not implemented as dummy __no_func. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3daac2c6b7b4..953ac53ae438 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -945,8 +945,7 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) chan->state = BT_CONNECTED; - if (chan->ops->ready) - chan->ops->ready(chan); + chan->ops->ready(chan); } static void l2cap_do_start(struct l2cap_chan *chan) -- GitLab From 3cabbfdad3150e0083a64c951701c970ef970c77 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 31 May 2012 11:01:37 +0300 Subject: [PATCH 0347/6849] Bluetooth: A2MP: Do not reference hci_conn Make A2MP channel special channel which do not reference hci_conn. This prevents from keeping ACL connection open when all L2CAP channels got closed. hci_conn_hold and hci_conn_put are not reference counts on the hci_conn structure in the typical way. They are reference counts for the ACL. When you do the last hci_conn_put, the ACL is disconnected after a timeout. Reported-by: Mat Martineau Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/a2mp.c | 2 -- net/bluetooth/l2cap_core.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index e08ca2ac31aa..0772c680abe6 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -481,8 +481,6 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) BT_DBG("chan %p", chan); - hci_conn_hold(conn->hcon); - chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP; chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 953ac53ae438..bef5266563a6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -514,7 +514,9 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_chan_put(chan); chan->conn = NULL; - hci_conn_put(conn->hcon); + + if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) + hci_conn_put(conn->hcon); } if (chan->ops->teardown) -- GitLab From 13ca56e0537aa148b7e7a6ea38ca6a6a1dc3e197 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 31 May 2012 11:18:55 +0300 Subject: [PATCH 0348/6849] Bluetooth: Make l2cap_data_channel return void l2cap_data_channel always return 0 which is not used anywhere, make it void function. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index bef5266563a6..56f5c0e31649 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5128,7 +5128,8 @@ drop: return 0; } -static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) +static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, + struct sk_buff *skb) { struct l2cap_chan *chan; @@ -5138,7 +5139,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk chan = a2mp_channel_create(conn, skb); if (!chan) { kfree_skb(skb); - return 0; + return; } l2cap_chan_lock(chan); @@ -5146,7 +5147,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk BT_DBG("unknown cid 0x%4.4x", cid); /* Drop packet and return */ kfree_skb(skb); - return 0; + return; } } @@ -5184,8 +5185,6 @@ drop: done: l2cap_chan_unlock(chan); - - return 0; } static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) -- GitLab From 84104b241d26302cb9083779d06741002534a58e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 31 May 2012 11:18:56 +0300 Subject: [PATCH 0349/6849] Bluetooth: Make l2cap_conless_channel return void l2cap_conless_channel always return 0 which is not used. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 56f5c0e31649..a8d69aba39fd 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5187,7 +5187,8 @@ done: l2cap_chan_unlock(chan); } -static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) +static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, + struct sk_buff *skb) { struct l2cap_chan *chan; @@ -5204,12 +5205,10 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str goto drop; if (!chan->ops->recv(chan, skb)) - return 0; + return; drop: kfree_skb(skb); - - return 0; } static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid, -- GitLab From 6810fca724d2a3c08c0d2eb8510648e7a36ab592 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 31 May 2012 11:18:57 +0300 Subject: [PATCH 0350/6849] Bluetooth: Make l2cap_att_channel return void l2cap_att_channel always returns 0 which is not used. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a8d69aba39fd..8229ae4fb4fd 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5211,8 +5211,8 @@ drop: kfree_skb(skb); } -static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid, - struct sk_buff *skb) +static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid, + struct sk_buff *skb) { struct l2cap_chan *chan; @@ -5229,12 +5229,10 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid, goto drop; if (!chan->ops->recv(chan, skb)) - return 0; + return; drop: kfree_skb(skb); - - return 0; } static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) -- GitLab From ba7aa64fe24d293bd433b82c30d505ab8611673f Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Tue, 29 May 2012 13:29:16 -0300 Subject: [PATCH 0351/6849] Bluetooth: Create function to return the ERTM header size Simplify the handling of different ERTM header size. We were the same check in some places of the code, and more is expected to come, so just replace them with a function. Signed-off-by: Gustavo Padovan Acked-by: Andrei Emeltchenko Signed-off-by: Johan Hedberg --- net/bluetooth/l2cap_core.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8229ae4fb4fd..136c2af6684b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -824,17 +824,20 @@ static inline void __pack_control(struct l2cap_chan *chan, } } +static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return L2CAP_EXT_HDR_SIZE; + else + return L2CAP_ENH_HDR_SIZE; +} + static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan, u32 control) { struct sk_buff *skb; struct l2cap_hdr *lh; - int hlen; - - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - hlen = L2CAP_EXT_HDR_SIZE; - else - hlen = L2CAP_ENH_HDR_SIZE; + int hlen = __ertm_hdr_size(chan); if (chan->fcs == L2CAP_FCS_CRC16) hlen += L2CAP_FCS_SIZE; @@ -2018,10 +2021,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, if (!conn) return ERR_PTR(-ENOTCONN); - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - hlen = L2CAP_EXT_HDR_SIZE; - else - hlen = L2CAP_ENH_HDR_SIZE; + hlen = __ertm_hdr_size(chan); if (sdulen) hlen += L2CAP_SDULEN_SIZE; @@ -2087,10 +2087,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, if (chan->fcs) pdu_len -= L2CAP_FCS_SIZE; - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - pdu_len -= L2CAP_EXT_HDR_SIZE; - else - pdu_len -= L2CAP_ENH_HDR_SIZE; + pdu_len -= __ertm_hdr_size(chan); /* Remote device may have requested smaller PDUs */ pdu_len = min_t(size_t, pdu_len, chan->remote_mps); -- GitLab From f0f6279976c8f0768468293546785c18894a704c Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Tue, 29 May 2012 13:29:17 -0300 Subject: [PATCH 0352/6849] Bluetooth: Remove unused err var from l2cap_segment_sdu() Trivial fix, let the code cleaner. Signed-off-by: Gustavo Padovan Reviewed-by: Mat Martineau Signed-off-by: Johan Hedberg --- net/bluetooth/l2cap_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 136c2af6684b..9750204011c6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2068,7 +2068,6 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, struct sk_buff *skb; u16 sdu_len; size_t pdu_len; - int err = 0; u8 sar; BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len); @@ -2127,7 +2126,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, } } - return err; + return 0; } int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, -- GitLab From dfc94dbdb999154dc2ff44e6011a4912c0b29e88 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 30 May 2012 15:39:21 +0200 Subject: [PATCH 0353/6849] Bluetooth: Allow only one LE connection attempt Only one outgoing LE connection attempt should be possible. hci_connect() will now return -EBUSY in case there's another pending outgoing connection. Signed-off-by: Andrzej Kaczmarek Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_conn.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 1458667b2845..2fcced377e50 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -483,6 +483,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, if (type == LE_LINK) { le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); if (!le) { + le = hci_conn_hash_lookup_state(hdev, LE_LINK, + BT_CONNECT); + if (le) + return ERR_PTR(-EBUSY); + le = hci_conn_add(hdev, LE_LINK, dst); if (!le) return ERR_PTR(-ENOMEM); -- GitLab From 489dc48e7583d825304b0aff3fc17e706627b3c8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 30 May 2012 15:39:22 +0200 Subject: [PATCH 0354/6849] Bluetooth: Return proper mgmt state when LE pairing connection failed MGMT_STATUS_BUSY should be returned when LE pairing cannot be started due to another outgoing connection attempt is ongoing. Signed-off-by: Andrzej Kaczmarek Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 205574edff20..958f764cc6ab 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1911,8 +1911,15 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (IS_ERR(conn)) { + int status; + + if (PTR_ERR(conn) == -EBUSY) + status = MGMT_STATUS_BUSY; + else + status = MGMT_STATUS_CONNECT_FAILED; + err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - MGMT_STATUS_CONNECT_FAILED, &rp, + status, &rp, sizeof(rp)); goto unlock; } -- GitLab From 4f72b3291c9537a3c3c94552e248eaed8e4f8492 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 30 May 2012 15:39:23 +0200 Subject: [PATCH 0355/6849] Bluetooth: Fix not removing hci_conn for failed LE connection This patch changes way LE Connection Complete event with error status are handled. BDADDR returned in such event packet do not need to be valid and should not be used to search for existing hci_conn. Instead, any hci_conn with BT_CONNECT state should be matched since there can be only one pending LE outgoing connection at any time. If not handled properly, appriopriate hci_conn will not be removed and subsequent connection to given peer will try to reuse it without making actual connection attempt. 2012-05-07 11:21:39.133378 < HCI Command: LE Create Connection (0x08|0x000d) plen 25 bdaddr 00:22:D0:10:13:EE type 1 2012-05-07 11:21:39.138774 > HCI Event: Command Status (0x0f) plen 4 LE Create Connection (0x08|0x000d) status 0x00 ncmd 1 2012-05-07 11:21:44.752854 < HCI Command: LE Create Connection Cancel (0x08|0x000e) plen 0 2012-05-07 11:21:44.759475 > HCI Event: Command Complete (0x0e) plen 4 LE Create Connection Cancel (0x08|0x000e) ncmd 1 2012-05-07 11:21:44.764479 > HCI Event: LE Meta Event (0x3e) plen 19 LE Connection Complete status 0x02 handle 0, role master bdaddr 00:00:00:00:00:00 (Public) [14898.739425] [6603] hci_connect: hci0 dst 00:22:D0:10:13:EE [14898.739429] [6603] hci_conn_add: hci0 dst 00:22:D0:10:13:EE [14898.739434] [6603] hci_conn_init_sysfs: conn ffff880079f03000 [14898.739440] [6603] hci_send_cmd: hci0 opcode 0x200d plen 25 [14898.739443] [6603] hci_send_cmd: skb len 28 [14898.739487] [6603] hci_chan_create: hci0 conn ffff880079f03000 ... [14938.860231] [55] hci_send_cmd: hci0 opcode 0x200e plen 0 ... [14938.876427] [55] hci_le_conn_complete_evt: hci0 status 2 [14938.876433] [55] hci_conn_add: hci0 dst 00:00:00:00:00:00 [14938.876439] [55] hci_conn_init_sysfs: conn ffff88007aeff800 [14938.876454] [55] hci_send_to_control: len 14 [14938.876470] [55] l2cap_connect_cfm: hcon ffff88007aeff800 bdaddr 00:00:00:00:00:00 status 2 [14938.876474] [55] hci_conn_del: hci0 conn ffff88007aeff800 handle 0 Signed-off-by: Andrzej Kaczmarek Acked-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_event.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index ac86b656c7a8..47656beee14c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3306,6 +3306,19 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); + if (ev->status) { + conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); + if (!conn) + goto unlock; + + mgmt_connect_failed(hdev, &conn->dst, conn->type, + conn->dst_type, ev->status); + hci_proto_connect_cfm(conn, ev->status); + conn->state = BT_CLOSED; + hci_conn_del(conn); + goto unlock; + } + conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); if (!conn) { conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); @@ -3318,15 +3331,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->dst_type = ev->bdaddr_type; } - if (ev->status) { - mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, - conn->dst_type, ev->status); - hci_proto_connect_cfm(conn, ev->status); - conn->state = BT_CLOSED; - hci_conn_del(conn); - goto unlock; - } - if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type, 0, NULL, 0, NULL); -- GitLab From 6fcb06a28d150095f042c477fbe20a9767d9a951 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 31 May 2012 17:01:33 -0300 Subject: [PATCH 0356/6849] Bluetooth: Change default MTU for L2CAP ATT channel This patch changes the default MTU value for L2CAP ATT fixed channel to L2CAP_DEFAULT_MTU (672 octets). Differently from others L2CAP channels, in L2CAP ATT fixed channel there is no MTU negotiation. The MTU value for that channel is up to the L2CAP implementation. The only restriction in L2CAP spec is the MTU value must not be less than 23 octets. At ATT protocol level (on top of L2CAP), we have the ATT_MTU which defines the maximum size of any ATT message sent between client and server. GATT profile defines ATT_MTU default value to 23 octets. If a GATT based profile wants to use ATT_MTU greater than 23 octets (e.g. HID over GATT profile), it should negotiate a new value by executing the GATT Exchange MTU sub-procedure. Thus, in order to support any value of ATT_MTU negotiated at ATT protocol level, our L2CAP implementation should have L2CAP ATT fixed channel MTU equal or greater than ATT_MAX_MTU (512 octets). Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9750204011c6..f9bffe3af026 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -449,7 +449,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) case L2CAP_CHAN_CONN_ORIENTED: if (conn->hcon->type == LE_LINK) { /* LE connection */ - chan->omtu = L2CAP_LE_DEFAULT_MTU; + chan->omtu = L2CAP_DEFAULT_MTU; chan->scid = L2CAP_CID_LE_DATA; chan->dcid = L2CAP_CID_LE_DATA; } else { -- GitLab From 682877c31fc1b6510b694b6b8e78d8dde53a47cc Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 31 May 2012 17:01:34 -0300 Subject: [PATCH 0357/6849] Bluetooth: Check MTU value in l2cap_sock_setsockopt_old If user tries to set an invalid MTU value, l2cap_sock_setsockopt_old should return -EINVAL. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_sock.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d856cc8f22a3..ab5868d94307 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -445,6 +445,22 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch return err; } +static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) +{ + switch (chan->scid) { + case L2CAP_CID_LE_DATA: + if (mtu < L2CAP_LE_DEFAULT_MTU) + return false; + break; + + default: + if (mtu < L2CAP_DEFAULT_MIN_MTU) + return false; + } + + return true; +} + static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; @@ -483,6 +499,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us break; } + if (!l2cap_valid_mtu(chan, opts.imtu)) { + err = -EINVAL; + break; + } + chan->mode = opts.mode; switch (chan->mode) { case L2CAP_MODE_BASIC: -- GitLab From 8c3a4f004e706fd7e681c68c6de4946c8c76b976 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 31 May 2012 17:01:35 -0300 Subject: [PATCH 0358/6849] Bluetooth: Rename L2CAP_LE_DEFAULT_MTU This patch renames L2CAP_LE_DEFAULT_MTU macro to L2CAP_LE_MIN_MTU since it represents the minimum MTU value, not the default MTU value for LE. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 2 +- net/bluetooth/l2cap_sock.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index a00b43ecbc77..ce99c5683d9e 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -40,11 +40,11 @@ #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ #define L2CAP_DEFAULT_ACK_TO 200 -#define L2CAP_LE_DEFAULT_MTU 23 #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF #define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF #define L2CAP_BREDR_MAX_PAYLOAD 1019 /* 3-DH5 packet */ +#define L2CAP_LE_MIN_MTU 23 #define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100) #define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index ab5868d94307..a4bb27e8427e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -449,7 +449,7 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) { switch (chan->scid) { case L2CAP_CID_LE_DATA: - if (mtu < L2CAP_LE_DEFAULT_MTU) + if (mtu < L2CAP_LE_MIN_MTU) return false; break; -- GitLab From 7e1af8a3a51dbf5dc7392fb294a0830f7e853aa8 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Tue, 29 May 2012 13:19:26 -0300 Subject: [PATCH 0359/6849] Bluetooth: Create empty l2cap ops function A2MP doesn't use part of the L2CAP chan ops API so we just create general empty function instead of the A2MP specific one. Signed-off-by: Gustavo Padovan Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 12 ++++++++++++ net/bluetooth/a2mp.c | 23 +++-------------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ce99c5683d9e..d80e3f0691b4 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -740,6 +740,18 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) return (seq + 1) % (chan->tx_win_max + 1); } +static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan) +{ + return NULL; +} + +static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err) +{ +} + +static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) +{ +} extern bool disable_ertm; diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 0772c680abe6..fb93250b3938 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -440,23 +440,6 @@ static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, return bt_skb_alloc(len, GFP_KERNEL); } -static struct l2cap_chan *a2mp_chan_no_new_conn_cb(struct l2cap_chan *chan) -{ - BT_ERR("new_connection for chan %p not implemented", chan); - - return NULL; -} - -static void a2mp_chan_no_teardown_cb(struct l2cap_chan *chan, int err) -{ - BT_ERR("teardown for chan %p not implemented", chan); -} - -static void a2mp_chan_no_ready(struct l2cap_chan *chan) -{ - BT_ERR("ready for chan %p not implemented", chan); -} - static struct l2cap_ops a2mp_chan_ops = { .name = "L2CAP A2MP channel", .recv = a2mp_chan_recv_cb, @@ -465,9 +448,9 @@ static struct l2cap_ops a2mp_chan_ops = { .alloc_skb = a2mp_chan_alloc_skb_cb, /* Not implemented for A2MP */ - .new_connection = a2mp_chan_no_new_conn_cb, - .teardown = a2mp_chan_no_teardown_cb, - .ready = a2mp_chan_no_ready, + .new_connection = l2cap_chan_no_new_connection, + .teardown = l2cap_chan_no_teardown, + .ready = l2cap_chan_no_ready, }; static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) -- GitLab From 0431a43ca5ada5ffd3668116b64168f4a1a64286 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 31 May 2012 20:01:41 -0300 Subject: [PATCH 0360/6849] Bluetooth: Filter duplicated reports in LE scan This patch enables filtering duplicated advertising reports during LE scan. Some LE devices advertise using very small intervals generating lots of equal advertising report events to the host. Each event generates a mgmt_device_found event which is copied to userspace. Enabling this feature, duplicated advertising reports are filtered at controller's link layer. This way, the controller doesn't wake up the host to report duplicated advertising reports and, consequently, less data is copied to userspace. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 979556a2649a..cf39e95777fc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1526,6 +1526,7 @@ static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) memset(&cp, 0, sizeof(cp)); cp.enable = 1; + cp.filter_dup = 1; hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); } -- GitLab From d060991f3bf4b6f8e9c5dec0c210fe76d9165000 Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Thu, 31 May 2012 22:53:39 -0300 Subject: [PATCH 0361/6849] Bluetooth: Fix checking the wrong flag when accepting a socket Most probably a typo, the check should have been for BT_SK_DEFER_SETUP instead of BT_DEFER_SETUP (which right now only represents a socket option). Signed-off-by: Vinicius Costa Gomes Acked-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/af_bluetooth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 251747269d37..f7db5792ec64 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -199,7 +199,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) } if (sk->sk_state == BT_CONNECTED || !newsock || - test_bit(BT_DEFER_SETUP, &bt_sk(parent)->flags)) { + test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) { bt_accept_unlink(sk); if (newsock) sock_graft(sk, newsock); -- GitLab From 7490c6c2013dc1d42557d7c4694930631b0d0f34 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 1 Jun 2012 16:18:25 +0300 Subject: [PATCH 0362/6849] Bluetooth: Remove magic disconnect reason The macro gives a better idea of the what the error really is. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cf39e95777fc..08994ecc3b6a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2307,7 +2307,7 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) if (c->type == type && c->sent) { BT_ERR("%s killing stalled connection %s", hdev->name, batostr(&c->dst)); - hci_acl_disconn(c, 0x13); + hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); } } -- GitLab From 8d0300a1d983a10cd3358f47b4317eca62c9b96b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 14:14:13 -0700 Subject: [PATCH 0363/6849] staging: comedi: adl_pci7230: factor out the find PCI device code Factor out the code that finds a matching PCI device from attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci7230.c | 53 +++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index e7eb2290106a..2c8349273d7f 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -80,18 +80,38 @@ static int adl_pci7230_di_insn_bits(struct comedi_device *dev, return 2; } -static int adl_pci7230_attach(struct comedi_device *dev, +static struct pci_dev *adl_pci7230_find_pci(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || + pcidev->device != PCI_DEVICE_ID_PCI7230) + continue; + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) + continue; + } + return pcidev; + } + printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return NULL; +} + +static int adl_pci7230_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ struct comedi_subdevice *s; - int bus, slot; printk(KERN_INFO "comedi%d: adl_pci7230\n", dev->minor); dev->board_name = "pci7230"; - bus = it->options[0]; - slot = it->options[1]; if (alloc_private(dev, sizeof(struct adl_pci7230_private)) < 0) return -ENOMEM; @@ -99,31 +119,16 @@ static int adl_pci7230_attach(struct comedi_device *dev, if (alloc_subdevices(dev, 2) < 0) return -ENOMEM; - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && - pcidev->device == PCI_DEVICE_ID_PCI7230) { - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) { - continue; - } - } - devpriv->pci_dev = pcidev; - break; - } - } - if (pcidev == NULL) { - printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); + devpriv->pci_dev = adl_pci7230_find_pci(dev, it); + if (!devpriv->pci_dev) return -EIO; - } - if (comedi_pci_enable(pcidev, "adl_pci7230") < 0) { + + if (comedi_pci_enable(devpriv->pci_dev, "adl_pci7230") < 0) { printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", dev->minor); return -EIO; } - dev->iobase = pci_resource_start(pcidev, 2); + dev->iobase = pci_resource_start(devpriv->pci_dev, 2); printk(KERN_DEBUG "comedi: base addr %4lx\n", dev->iobase); s = dev->subdevices + 0; -- GitLab From 93b6e4790ecd3025a1a38d3758ee1ac0b264799c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 16:34:58 -0700 Subject: [PATCH 0364/6849] staging: comedi: adl_pci9118: factor out the find PCI device code Factor out the code that finds a matching PCI device from attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 99 +++++++++----------- 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index aa4244e5f918..f2135bfca290 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2110,6 +2110,44 @@ static int pci9118_reset(struct comedi_device *dev) return 0; } +static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor != PCI_VENDOR_ID_AMCC) + continue; + if (pcidev->device != this_board->device_id) + continue; + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) + continue; + } + /* + * Look for device that isn't in use. + * Enable PCI device and request regions. + */ + if (comedi_pci_enable(pcidev, "adl_pci9118")) + continue; + printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", + pcidev->bus->number, + PCI_SLOT(pcidev->devfn), + PCI_FUNC(pcidev->devfn), + (unsigned long)pci_resource_start(pcidev, 2), + (unsigned long)pci_resource_start(pcidev, 0)); + return pcidev; + } + printk(KERN_ERR + "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return NULL; +} + static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -2117,17 +2155,10 @@ static int pci9118_attach(struct comedi_device *dev, int ret, pages, i; unsigned short master; unsigned int irq; - unsigned long iobase_a, iobase_9; - struct pci_dev *pcidev; - int opt_bus, opt_slot; - const char *errstr; - unsigned char pci_bus, pci_slot, pci_func; u16 u16w; printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name); - opt_bus = it->options[0]; - opt_slot = it->options[1]; if (it->options[3] & 1) master = 0; /* user don't want use bus master */ else @@ -2139,61 +2170,19 @@ static int pci9118_attach(struct comedi_device *dev, return -ENOMEM; } - /* Look for matching PCI device */ - errstr = "not found!"; - pcidev = NULL; - while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC, - this_board->device_id, - pcidev))) { - /* Found matching vendor/device. */ - if (opt_bus || opt_slot) { - /* Check bus/slot. */ - if (opt_bus != pcidev->bus->number - || opt_slot != PCI_SLOT(pcidev->devfn)) - continue; /* no match */ - } - /* - * Look for device that isn't in use. - * Enable PCI device and request regions. - */ - if (comedi_pci_enable(pcidev, "adl_pci9118")) { - errstr = - "failed to enable PCI device and request regions!"; - continue; - } - break; - } - - if (!pcidev) { - if (opt_bus || opt_slot) { - printk(KERN_ERR " - Card at b:s %d:%d %s\n", - opt_bus, opt_slot, errstr); - } else { - printk(KERN_ERR " - Card %s\n", errstr); - } + devpriv->pcidev = pci9118_find_pci(dev, it); + if (!devpriv->pcidev) return -EIO; - } if (master) - pci_set_master(pcidev); + pci_set_master(devpriv->pcidev); + irq = devpriv->pcidev->irq; + devpriv->iobase_a = pci_resource_start(devpriv->pcidev, 0); + dev->iobase = pci_resource_start(devpriv->pcidev, 2); - pci_bus = pcidev->bus->number; - pci_slot = PCI_SLOT(pcidev->devfn); - pci_func = PCI_FUNC(pcidev->devfn); - irq = pcidev->irq; - iobase_a = pci_resource_start(pcidev, 0); - iobase_9 = pci_resource_start(pcidev, 2); - - printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, - pci_slot, pci_func, iobase_9, iobase_a); - - dev->iobase = iobase_9; dev->board_name = this_board->name; - devpriv->pcidev = pcidev; - devpriv->iobase_a = iobase_a; - pci9118_reset(dev); if (it->options[3] & 2) -- GitLab From 1158244e013eeac80ad418ab8042cfc4462ee278 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 16:06:39 -0700 Subject: [PATCH 0365/6849] staging: comedi: adl_pci9111: factor out the find PCI device code Factor out the code that finds a matching PCI device from attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 107 +++++++++---------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 308cca76cb82..410bbf9f5a95 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1209,17 +1209,47 @@ static int pci9111_reset(struct comedi_device *dev) return 0; } -/* Attach */ -/* - Register PCI device */ -/* - Declare device driver capability */ +static struct pci_dev *pci9111_find_pci(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + int i; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor != PCI_VENDOR_ID_ADLINK) + continue; + for (i = 0; i < pci9111_board_nbr; i++) { + if (pcidev->device != pci9111_boards[i].device_id) + continue; + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) + continue; + } + dev->board_ptr = pci9111_boards + i; + printk(KERN_ERR + "comedi%d: found %s (b:s:f=%d:%d:%d), irq=%d\n", + dev->minor, pci9111_boards[i].name, + pcidev->bus->number, PCI_SLOT(pcidev->devfn), + PCI_FUNC(pcidev->devfn), pcidev->irq); + return pcidev; + } + } + printk(KERN_ERR + "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return NULL; +} static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *subdevice; unsigned long io_base, io_range, lcr_io_base, lcr_io_range; - struct pci_dev *pci_device = NULL; - int error, i; + int error; const struct pci9111_board *board; if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) @@ -1229,65 +1259,25 @@ static int pci9111_attach(struct comedi_device *dev, printk(KERN_ERR "comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor); - for_each_pci_dev(pci_device) { - if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) { - for (i = 0; i < pci9111_board_nbr; i++) { - if (pci9111_boards[i].device_id == - pci_device->device) { - /* was a particular bus/slot - * requested? */ - if ((it->options[0] != 0) - || (it->options[1] != 0)) { - /* are we on the wrong - * bus/slot? */ - if (pci_device->bus->number != - it->options[0] - || - PCI_SLOT(pci_device->devfn) - != it->options[1]) { - continue; - } - } - - dev->board_ptr = pci9111_boards + i; - board = - (struct pci9111_board *) - dev->board_ptr; - dev_private->pci_device = pci_device; - goto found; - } - } - } - } - - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, it->options[0], it->options[1]); - return -EIO; - -found: - - printk(KERN_ERR "comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", - dev->minor, - pci9111_boards[i].name, - pci_device->bus->number, - PCI_SLOT(pci_device->devfn), - PCI_FUNC(pci_device->devfn), pci_device->irq); + dev_private->pci_device = pci9111_find_pci(dev, it); + if (!dev_private->pci_device) + return -EIO; + board = (struct pci9111_board *)dev->board_ptr; /* TODO: Warn about non-tested boards. */ /* Read local configuration register base address * [PCI_BASE_ADDRESS #1]. */ - lcr_io_base = pci_resource_start(pci_device, 1); - lcr_io_range = pci_resource_len(pci_device, 1); + lcr_io_base = pci_resource_start(dev_private->pci_device, 1); + lcr_io_range = pci_resource_len(dev_private->pci_device, 1); printk ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", dev->minor, lcr_io_base, lcr_io_range); /* Enable PCI device and request regions */ - if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) { + if (comedi_pci_enable(dev_private->pci_device, PCI9111_DRIVER_NAME) < 0) { printk ("comedi%d: Failed to enable PCI device and request regions\n", dev->minor); @@ -1295,8 +1285,8 @@ found: } /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ - io_base = pci_resource_start(pci_device, 2); - io_range = pci_resource_len(pci_device, 2); + io_base = pci_resource_start(dev_private->pci_device, 2); + io_range = pci_resource_len(dev_private->pci_device, 2); printk(KERN_ERR "comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n", dev->minor, io_base, io_range); @@ -1313,16 +1303,17 @@ found: /* Irq setup */ dev->irq = 0; - if (pci_device->irq > 0) { - if (request_irq(pci_device->irq, pci9111_interrupt, + if (dev_private->pci_device->irq > 0) { + dev->irq = dev_private->pci_device->irq; + + if (request_irq(dev->irq, pci9111_interrupt, IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { printk(KERN_ERR "comedi%d: unable to allocate irq %u\n", - dev->minor, pci_device->irq); + dev->minor, dev->irq); return -EINVAL; } } - dev->irq = pci_device->irq; /* TODO: Add external multiplexer setup (according to option[2]). */ -- GitLab From d3ff7b93ee8b619f777a73f34812e66de07ecd93 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 15:44:10 -0700 Subject: [PATCH 0366/6849] staging: comedi: adl_pci8164: factor out the PCI device code Factor out the code that finds a matching PCI device from attach function. This allows reducing the indent level of the remaining code in the attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 149 ++++++++++--------- 1 file changed, 78 insertions(+), 71 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index fbc859e6c201..344754877892 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -223,19 +223,40 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } +static struct pci_dev *adl_pci8164_find_pci(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || + pcidev->device != PCI_DEVICE_ID_PCI8164) + continue; + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) + continue; + } + return pcidev; + } + printk(KERN_ERR + "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return NULL; +} + static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - struct pci_dev *pcidev = NULL; struct comedi_subdevice *s; - int bus, slot; printk(KERN_INFO "comedi: attempt to attach...\n"); printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); dev->board_name = "pci8164"; - bus = it->options[0]; - slot = it->options[1]; if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) return -ENOMEM; @@ -243,74 +264,60 @@ static int adl_pci8164_attach(struct comedi_device *dev, if (alloc_subdevices(dev, 4) < 0) return -ENOMEM; - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && - pcidev->device == PCI_DEVICE_ID_PCI8164) { - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus - || PCI_SLOT(pcidev->devfn) != slot) - continue; - } - devpriv->pci_dev = pcidev; - if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable " - "PCI device and request regions\n", dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_DEBUG "comedi: base addr %4lx\n", - dev->iobase); - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_msts; - s->insn_write = adl_pci8164_insn_write_cmd; - - s = dev->subdevices + 1; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_ssts; - s->insn_write = adl_pci8164_insn_write_otp; - - s = dev->subdevices + 2; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf0; - s->insn_write = adl_pci8164_insn_write_buf0; - - s = dev->subdevices + 3; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf1; - s->insn_write = adl_pci8164_insn_write_buf1; - - printk(KERN_INFO "comedi: attached\n"); - - return 1; - } - } + devpriv->pci_dev = adl_pci8164_find_pci(dev, it); + if (!devpriv->pci_dev) + return -EIO; - printk(KERN_ERR "comedi%d: no supported board found!" - "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot); - return -EIO; + if (comedi_pci_enable(devpriv->pci_dev, "adl_pci8164") < 0) { + printk(KERN_ERR "comedi%d: Failed to enable " + "PCI device and request regions\n", dev->minor); + return -EIO; + } + dev->iobase = pci_resource_start(devpriv->pci_dev, 2); + printk(KERN_DEBUG "comedi: base addr %4lx\n", dev->iobase); + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_msts; + s->insn_write = adl_pci8164_insn_write_cmd; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_ssts; + s->insn_write = adl_pci8164_insn_write_otp; + + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_buf0; + s->insn_write = adl_pci8164_insn_write_buf0; + + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_buf1; + s->insn_write = adl_pci8164_insn_write_buf1; + + printk(KERN_INFO "comedi: attached\n"); + return 0; } static void adl_pci8164_detach(struct comedi_device *dev) -- GitLab From fc330f458941df0f1651964e8e1207e62fb6db51 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 14:38:33 -0700 Subject: [PATCH 0367/6849] staging: comedi: adl_pci7432: factor out the PCI device code Factor out the code that finds a matching PCI device from attach function. This allows reducing the indent level of the remaining code in the attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci7432.c | 112 ++++++++++--------- 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index 2fc1dbbd81e4..dd818f1b75ae 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -88,18 +88,39 @@ static int adl_pci7432_di_insn_bits(struct comedi_device *dev, return 2; } +static struct pci_dev *adl_pci7432_find_pci(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || + pcidev->device != PCI_DEVICE_ID_PCI7432) + continue; + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) + continue; + } + return pcidev; + } + printk(KERN_ERR + "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return NULL; +} + static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - struct pci_dev *pcidev = NULL; struct comedi_subdevice *s; - int bus, slot; printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); dev->board_name = "pci7432"; - bus = it->options[0]; - slot = it->options[1]; if (alloc_private(dev, sizeof(struct adl_pci7432_private)) < 0) return -ENOMEM; @@ -107,57 +128,40 @@ static int adl_pci7432_attach(struct comedi_device *dev, if (alloc_subdevices(dev, 2) < 0) return -ENOMEM; - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && - pcidev->device == PCI_DEVICE_ID_PCI7432) { - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus - || PCI_SLOT(pcidev->devfn) != slot) { - continue; - } - } - devpriv->pci_dev = pcidev; - if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_INFO "comedi: base addr %4lx\n", - dev->iobase); - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = - SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 32; - s->maxdata = 1; - s->len_chanlist = 32; - s->io_bits = 0x00000000; - s->range_table = &range_digital; - s->insn_bits = adl_pci7432_di_insn_bits; - - s = dev->subdevices + 1; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_WRITABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 32; - s->maxdata = 1; - s->len_chanlist = 32; - s->io_bits = 0xffffffff; - s->range_table = &range_digital; - s->insn_bits = adl_pci7432_do_insn_bits; - - printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", - dev->minor); - return 1; - } - } + devpriv->pci_dev = adl_pci7432_find_pci(dev, it); + if (!devpriv->pci_dev) + return -EIO; - printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); - return -EIO; + if (comedi_pci_enable(devpriv->pci_dev, "adl_pci7432") < 0) { + printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", + dev->minor); + return -EIO; + } + dev->iobase = pci_resource_start(devpriv->pci_dev, 2); + printk(KERN_INFO "comedi: base addr %4lx\n", dev->iobase); + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 32; + s->maxdata = 1; + s->len_chanlist = 32; + s->io_bits = 0x00000000; + s->range_table = &range_digital; + s->insn_bits = adl_pci7432_di_insn_bits; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 32; + s->maxdata = 1; + s->len_chanlist = 32; + s->io_bits = 0xffffffff; + s->range_table = &range_digital; + s->insn_bits = adl_pci7432_do_insn_bits; + + printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", dev->minor); + return 0; } static void adl_pci7432_detach(struct comedi_device *dev) -- GitLab From 262ea0d476049fa393509a70c9ecfa06df403b4a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 14:28:47 -0700 Subject: [PATCH 0368/6849] staging: comedi: adl_pci7296: factor out the PCI device code Factor out the code that finds a matching PCI device from attach function. This allows reducing the indent level of the remaining code in the attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci7296.c | 121 ++++++++++--------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index bf2f7fb86d77..0b8b27983122 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -54,19 +54,40 @@ struct adl_pci7296_private { #define devpriv ((struct adl_pci7296_private *)dev->private) +static struct pci_dev *adl_pci7296_find_pci(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor != PCI_VENDOR_ID_ADLINK || + pcidev->device != PCI_DEVICE_ID_PCI7296) + continue; + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) + continue; + } + return pcidev; + } + printk(KERN_ERR + "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return NULL; +} + static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - struct pci_dev *pcidev = NULL; struct comedi_subdevice *s; - int bus, slot; int ret; printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); dev->board_name = "pci7432"; - bus = it->options[0]; - slot = it->options[1]; if (alloc_private(dev, sizeof(struct adl_pci7296_private)) < 0) return -ENOMEM; @@ -74,63 +95,45 @@ static int adl_pci7296_attach(struct comedi_device *dev, if (alloc_subdevices(dev, 4) < 0) return -ENOMEM; - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && - pcidev->device == PCI_DEVICE_ID_PCI7296) { - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus - || PCI_SLOT(pcidev->devfn) != slot) { - continue; - } - } - devpriv->pci_dev = pcidev; - if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); - return -EIO; - } - - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_INFO "comedi: base addr %4lx\n", - dev->iobase); - - /* four 8255 digital io subdevices */ - s = dev->subdevices + 0; - subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase)); - - s = dev->subdevices + 1; - ret = subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase + - PORT2A)); - if (ret < 0) - return ret; - - s = dev->subdevices + 2; - ret = subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase + - PORT3A)); - if (ret < 0) - return ret; - - s = dev->subdevices + 3; - ret = subdev_8255_init(dev, s, NULL, - (unsigned long)(dev->iobase + - PORT4A)); - if (ret < 0) - return ret; - - printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", - dev->minor); - - return 1; - } + devpriv->pci_dev = adl_pci7296_find_pci(dev, it); + if (!devpriv->pci_dev) + return -EIO; + + if (comedi_pci_enable(devpriv->pci_dev, "adl_pci7296") < 0) { + printk(KERN_ERR + "comedi%d: Failed to enable PCI device and request regions\n", + dev->minor); + return -EIO; } - printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); - return -EIO; + dev->iobase = pci_resource_start(devpriv->pci_dev, 2); + printk(KERN_INFO "comedi: base addr %4lx\n", dev->iobase); + + /* four 8255 digital io subdevices */ + s = dev->subdevices + 0; + subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase)); + + s = dev->subdevices + 1; + ret = subdev_8255_init(dev, s, NULL, + (unsigned long)(dev->iobase + PORT2A)); + if (ret < 0) + return ret; + + s = dev->subdevices + 2; + ret = subdev_8255_init(dev, s, NULL, + (unsigned long)(dev->iobase + PORT3A)); + if (ret < 0) + return ret; + + s = dev->subdevices + 3; + ret = subdev_8255_init(dev, s, NULL, + (unsigned long)(dev->iobase + PORT4A)); + if (ret < 0) + return ret; + + printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", dev->minor); + + return 0; } static void adl_pci7296_detach(struct comedi_device *dev) -- GitLab From c98d90fd1fb9a5ff612e05766198cb09a1dd63b7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 18:31:48 -0700 Subject: [PATCH 0369/6849] staging: comedi: rtd520 complete the refactor to remove all forward declarations Complete the refactor of the rtd520 driver to remove all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 2704 +++++++++++------------ 1 file changed, 1337 insertions(+), 1367 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index d3e2786f07cb..84b28b6b99d6 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -702,1616 +702,1586 @@ struct rtdPrivate { #define RtdDma1Status(dev) \ readb(devpriv->lcfg+LCFG_DMACSR1) -static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int rtd_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int rtd_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); /* - * static int rtd_ai_poll(struct comedi_device *dev, - * struct comedi_subdevice *s); - */ -static int rtd_ns_to_timer(unsigned int *ns, int roundMode); -static irqreturn_t rtd_interrupt(int irq, void *d); -static int rtd520_probe_fifo_depth(struct comedi_device *dev); + Given a desired period and the clock period (both in ns), + return the proper counter value (divider-1). + Sets the original period to be the true value. + Note: you have to check if the value is larger than the counter range! +*/ +static int rtd_ns_to_timer_base(unsigned int *nanosec, /* desired period (in ns) */ + int round_mode, int base) +{ /* clock period (in ns) */ + int divider; + + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + divider = (*nanosec + base / 2) / base; + break; + case TRIG_ROUND_DOWN: + divider = (*nanosec) / base; + break; + case TRIG_ROUND_UP: + divider = (*nanosec + base - 1) / base; + break; + } + if (divider < 2) + divider = 2; /* min is divide by 2 */ + + /* Note: we don't check for max, because different timers + have different ranges */ + + *nanosec = base * divider; + return divider - 1; /* countdown is divisor+1 */ +} /* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ /* board name and options flags */ - struct comedi_subdevice *s; - struct pci_dev *pcidev; - int ret; - resource_size_t physLas0; /* configuration */ - resource_size_t physLas1; /* data area */ - resource_size_t physLcfg; /* PLX9080 */ -#ifdef USE_DMA - int index; -#endif + Given a desired period (in ns), + return the proper counter value (divider-1) for the internal clock. + Sets the original period to be the true value. +*/ +static int rtd_ns_to_timer(unsigned int *ns, int round_mode) +{ + return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE); +} - printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor); +/* + Convert a single comedi channel-gain entry to a RTD520 table entry +*/ +static unsigned short rtdConvertChanGain(struct comedi_device *dev, + unsigned int comediChan, int chanIndex) +{ /* index in channel list */ + unsigned int chan, range, aref; + unsigned short r = 0; -#if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA) - /* You can set this a load time: modprobe comedi comedi_debug=1 */ - if (0 == comedi_debug) /* force DMA debug printks */ - comedi_debug = 1; -#endif + chan = CR_CHAN(comediChan); + range = CR_RANGE(comediChan); + aref = CR_AREF(comediChan); - /* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0) - return -ENOMEM; + r |= chan & 0xf; - /* - * Probe the device to determine what device in the series it is. - */ - for (pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, NULL); - pcidev != NULL; - pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) { - int i; + /* Note: we also setup the channel list bipolar flag array */ + if (range < thisboard->range10Start) { /* first batch are +-5 */ + r |= 0x000; /* +-5 range */ + r |= (range & 0x7) << 4; /* gain */ + CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); + } else if (range < thisboard->rangeUniStart) { /* second batch are +-10 */ + r |= 0x100; /* +-10 range */ + /* gain */ + r |= ((range - thisboard->range10Start) & 0x7) << 4; + CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); + } else { /* last batch is +10 */ + r |= 0x200; /* +10 range */ + /* gain */ + r |= ((range - thisboard->rangeUniStart) & 0x7) << 4; + CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex); + } - if (it->options[0] || it->options[1]) { - if (pcidev->bus->number != it->options[0] - || PCI_SLOT(pcidev->devfn) != it->options[1]) { - continue; - } - } - for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i) { - if (pcidev->device == rtd520Boards[i].device_id) { - dev->board_ptr = &rtd520Boards[i]; - break; - } + switch (aref) { + case AREF_GROUND: /* on-board ground */ + break; + + case AREF_COMMON: + r |= 0x80; /* ref external analog common */ + break; + + case AREF_DIFF: + r |= 0x400; /* differential inputs */ + break; + + case AREF_OTHER: /* ??? */ + break; + } + /*printk ("chan=%d r=%d a=%d -> 0x%x\n", + chan, range, aref, r); */ + return r; +} + +/* + Setup the channel-gain table from a comedi list +*/ +static void rtd_load_channelgain_list(struct comedi_device *dev, + unsigned int n_chan, unsigned int *list) +{ + if (n_chan > 1) { /* setup channel gain table */ + int ii; + RtdClearCGT(dev); + RtdEnableCGT(dev, 1); /* enable table */ + for (ii = 0; ii < n_chan; ii++) { + RtdWriteCGTable(dev, rtdConvertChanGain(dev, list[ii], + ii)); } - if (dev->board_ptr) - break; /* found one */ + } else { /* just use the channel gain latch */ + RtdEnableCGT(dev, 0); /* disable table, enable latch */ + RtdWriteCGLatch(dev, rtdConvertChanGain(dev, list[0], 0)); } - if (!pcidev) { - if (it->options[0] && it->options[1]) { - printk(KERN_INFO "No RTD card at bus=%d slot=%d.\n", - it->options[0], it->options[1]); - } else { - printk(KERN_INFO "No RTD card found.\n"); +} + +/* determine fifo size by doing adc conversions until the fifo half +empty status flag clears */ +static int rtd520_probe_fifo_depth(struct comedi_device *dev) +{ + unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND); + unsigned i; + static const unsigned limit = 0x2000; + unsigned fifo_size = 0; + + RtdAdcClearFifo(dev); + rtd_load_channelgain_list(dev, 1, &chanspec); + RtdAdcConversionSource(dev, 0); /* software */ + /* convert samples */ + for (i = 0; i < limit; ++i) { + unsigned fifo_status; + /* trigger conversion */ + RtdAdcStart(dev); + udelay(1); + fifo_status = RtdFifoStatus(dev); + if ((fifo_status & FS_ADC_HEMPTY) == 0) { + fifo_size = 2 * i; + break; } + } + if (i == limit) { + printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", + DRV_NAME); return -EIO; } - devpriv->pci_dev = pcidev; - dev->board_name = thisboard->name; - - ret = comedi_pci_enable(pcidev, DRV_NAME); - if (ret < 0) { - printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); - return ret; + RtdAdcClearFifo(dev); + if (fifo_size != 0x400 && fifo_size != 0x2000) { + printk + (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n", + DRV_NAME, fifo_size); + return -EIO; } - devpriv->got_regions = 1; - - /* - * Initialize base addresses - */ - /* Get the physical address from PCI config */ - physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX); - physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX); - physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX); - /* Now have the kernel map this into memory */ - /* ASSUME page aligned */ - devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE); - devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE); - devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE); + return fifo_size; +} - if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) - return -ENOMEM; +/* + "instructions" read/write data in "one-shot" or "software-triggered" + mode (simplest case). + This doesn't use interrupts. + Note, we don't do any settling delays. Use a instruction list to + select, delay, then read. + */ +static int rtd_ai_rinsn(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_insn *insn, + unsigned int *data) +{ + int n, ii; + int stat; - DPRINTK("%s: LAS0=%llx, LAS1=%llx, CFG=%llx.\n", dev->board_name, - (unsigned long long)physLas0, (unsigned long long)physLas1, - (unsigned long long)physLcfg); - { /* The RTD driver does this */ - unsigned char pci_latency; - u16 revision; - /*uint32_t epld_version; */ + /* clear any old fifo data */ + RtdAdcClearFifo(dev); - pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID, - &revision); - DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); + /* write channel to multiplexer and clear channel gain table */ + rtd_load_channelgain_list(dev, 1, &insn->chanspec); - pci_read_config_byte(devpriv->pci_dev, - PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency < 32) { - printk(KERN_INFO "%s: PCI latency changed from %d to %d\n", - dev->board_name, pci_latency, 32); - pci_write_config_byte(devpriv->pci_dev, - PCI_LATENCY_TIMER, 32); - } else { - DPRINTK("rtd520: PCI latency = %d\n", pci_latency); - } + /* set conversion source */ + RtdAdcConversionSource(dev, 0); /* software */ - /* - * Undocumented EPLD version (doesn't match RTD driver results) - */ - /*DPRINTK ("rtd520: Reading epld from %p\n", - devpriv->las0+0); - epld_version = readl (devpriv->las0+0); - if ((epld_version & 0xF0) >> 4 == 0x0F) { - DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version); - } else { - DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4); - } */ + /* convert n samples */ + for (n = 0; n < insn->n; n++) { + s16 d; + /* trigger conversion */ + RtdAdcStart(dev); + + for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) { + stat = RtdFifoStatus(dev); + if (stat & FS_ADC_NOT_EMPTY) /* 1 -> not empty */ + break; + WAIT_QUIETLY; + } + if (ii >= RTD_ADC_TIMEOUT) { + DPRINTK + ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n", + stat ^ 0x6666); + return -ETIMEDOUT; + } + + /* read data */ + d = RtdAdcFifoGet(dev); /* get 2s comp value */ + /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */ + d = d >> 3; /* low 3 bits are marker lines */ + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) + /* convert to comedi unsigned data */ + data[n] = d + 2048; + else + data[n] = d; } - /* Show board configuration */ - printk(KERN_INFO "%s:", dev->board_name); + /* return the number of samples read/written */ + return n; +} - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; +/* + Get what we know is there.... Fast! + This uses 1/2 the bus cycles of read_dregs (below). + The manual claims that we can do a lword read, but it doesn't work here. +*/ +static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, + int count) +{ + int ii; - s = dev->subdevices + 0; - dev->read_subdev = s; - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; - s->n_chan = thisboard->aiChans; - s->maxdata = (1 << thisboard->aiBits) - 1; - if (thisboard->aiMaxGain <= 32) - s->range_table = &rtd_ai_7520_range; - else - s->range_table = &rtd_ai_4520_range; + for (ii = 0; ii < count; ii++) { + short sample; + s16 d; - s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ - s->insn_read = rtd_ai_rinsn; - s->do_cmd = rtd_ai_cmd; - s->do_cmdtest = rtd_ai_cmdtest; - s->cancel = rtd_ai_cancel; - /* s->poll = rtd_ai_poll; *//* not ready yet */ + if (0 == devpriv->aiCount) { /* done */ + d = RtdAdcFifoGet(dev); /* Read N and discard */ + continue; + } +#if 0 + if (0 == (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY)) { /* DEBUG */ + DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1, + count); + break; + } +#endif + d = RtdAdcFifoGet(dev); /* get 2s comp value */ - s = dev->subdevices + 1; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 2; - s->maxdata = (1 << thisboard->aiBits) - 1; - s->range_table = &rtd_ao_range; - s->insn_write = rtd_ao_winsn; - s->insn_read = rtd_ao_rinsn; + d = d >> 3; /* low 3 bits are marker lines */ + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + /* convert to comedi unsigned data */ + sample = d + 2048; + } else + sample = d; - s = dev->subdevices + 2; - /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - /* we only support port 0 right now. Ignoring port 1 and user IO */ - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = rtd_dio_insn_bits; - s->insn_config = rtd_dio_insn_config; + if (!comedi_buf_put(s->async, sample)) + return -1; - /* timer/counter subdevices (not currently supported) */ - s = dev->subdevices + 3; - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 3; - s->maxdata = 0xffff; + if (devpriv->aiCount > 0) /* < 0, means read forever */ + devpriv->aiCount--; + } + return 0; +} - /* initialize board, per RTD spec */ - /* also, initialize shadow registers */ - RtdResetBoard(dev); - udelay(100); /* needed? */ - RtdPlxInterruptWrite(dev, 0); - RtdInterruptMask(dev, 0); /* and sets shadow */ - RtdInterruptClearMask(dev, ~0); /* and sets shadow */ - RtdInterruptClear(dev); /* clears bits set by mask */ - RtdInterruptOverrunClear(dev); - RtdClearCGT(dev); - RtdAdcClearFifo(dev); - RtdDacClearFifo(dev, 0); - RtdDacClearFifo(dev, 1); - /* clear digital IO fifo */ - RtdDioStatusWrite(dev, 0); /* safe state, set shadow */ - RtdUtcCtrlPut(dev, 0, 0x30); /* safe state, set shadow */ - RtdUtcCtrlPut(dev, 1, 0x30); /* safe state, set shadow */ - RtdUtcCtrlPut(dev, 2, 0x30); /* safe state, set shadow */ - RtdUtcCtrlPut(dev, 3, 0); /* safe state, set shadow */ - /* TODO: set user out source ??? */ +/* + unknown amout of data is waiting in fifo. +*/ +static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) +{ + while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ + short sample; + s16 d = RtdAdcFifoGet(dev); /* get 2s comp value */ - /* check if our interrupt is available and get it */ - ret = request_irq(devpriv->pci_dev->irq, rtd_interrupt, - IRQF_SHARED, DRV_NAME, dev); + if (0 == devpriv->aiCount) { /* done */ + continue; /* read rest */ + } - if (ret < 0) { - printk("Could not get interrupt! (%u)\n", - devpriv->pci_dev->irq); - return ret; - } - dev->irq = devpriv->pci_dev->irq; - printk(KERN_INFO "( irq=%u )", dev->irq); + d = d >> 3; /* low 3 bits are marker lines */ + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + /* convert to comedi unsigned data */ + sample = d + 2048; + } else + sample = d; - ret = rtd520_probe_fifo_depth(dev); - if (ret < 0) - return ret; + if (!comedi_buf_put(s->async, sample)) + return -1; - devpriv->fifoLen = ret; - printk("( fifoLen=%d )", devpriv->fifoLen); + if (devpriv->aiCount > 0) /* < 0, means read forever */ + devpriv->aiCount--; + } + return 0; +} #ifdef USE_DMA - if (dev->irq > 0) { - printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT); - /* - * The PLX9080 has 2 DMA controllers, but there could be - * 4 sources: ADC, digital, DAC1, and DAC2. Since only the - * ADC supports cmd mode right now, this isn't an issue (yet) - */ - devpriv->dma0Offset = 0; +/* + Terminate a DMA transfer and wait for everything to quiet down +*/ +void abort_dma(struct comedi_device *dev, unsigned int channel) +{ /* DMA channel 0, 1 */ + unsigned long dma_cs_addr; /* the control/status register */ + uint8_t status; + unsigned int ii; + /* unsigned long flags; */ - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - devpriv->dma0Buff[index] = - pci_alloc_consistent(devpriv->pci_dev, - sizeof(u16) * - devpriv->fifoLen / 2, - &devpriv-> - dma0BuffPhysAddr[index]); - if (devpriv->dma0Buff[index] == NULL) { - ret = -ENOMEM; - goto rtd_attach_die_error; - } - /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n", - index, - devpriv->dma0Buff[index], - devpriv->dma0BuffPhysAddr[index]); */ - } + dma_cs_addr = (unsigned long)devpriv->lcfg + + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1); - /* - * setup DMA descriptor ring (use cpu_to_le32 for byte - * ordering?) - */ - devpriv->dma0Chain = - pci_alloc_consistent(devpriv->pci_dev, - sizeof(struct plx_dma_desc) * - DMA_CHAIN_COUNT, - &devpriv->dma0ChainPhysAddr); - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - devpriv->dma0Chain[index].pci_start_addr = - devpriv->dma0BuffPhysAddr[index]; - devpriv->dma0Chain[index].local_start_addr = - DMALADDR_ADC; - devpriv->dma0Chain[index].transfer_size = - sizeof(u16) * devpriv->fifoLen / 2; - devpriv->dma0Chain[index].next = - (devpriv->dma0ChainPhysAddr + ((index + - 1) % - (DMA_CHAIN_COUNT)) - * sizeof(devpriv->dma0Chain[0])) - | DMA_TRANSFER_BITS; - /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n", - index, - ((long)devpriv->dma0ChainPhysAddr - + (index * sizeof(devpriv->dma0Chain[0]))), - devpriv->dma0Chain[index].pci_start_addr, - devpriv->dma0Chain[index].local_start_addr, - devpriv->dma0Chain[index].transfer_size, - devpriv->dma0Chain[index].next); */ - } + /* spinlock for plx dma control/status reg */ + /* spin_lock_irqsave( &dev->spinlock, flags ); */ - if (devpriv->dma0Chain == NULL) { - ret = -ENOMEM; - goto rtd_attach_die_error; - } + /* abort dma transfer if necessary */ + status = readb(dma_cs_addr); + if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */ + DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n", + channel, status); + goto abortDmaExit; + } - RtdDma0Mode(dev, DMA_MODE_BITS); - /* set DMA trigger source */ - RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); - } else { - printk(KERN_INFO "( no IRQ->no DMA )"); + /* wait to make sure done bit is zero (needed?) */ + for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) { + WAIT_QUIETLY; + status = readb(dma_cs_addr); + } + if (status & PLX_DMA_DONE_BIT) { + printk("rtd520: Timeout waiting for dma %i done clear\n", + channel); + goto abortDmaExit; } -#endif /* USE_DMA */ - if (dev->irq) { /* enable plx9080 interrupts */ - RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE); + /* disable channel (required) */ + writeb(0, dma_cs_addr); + udelay(1); /* needed?? */ + /* set abort bit for channel */ + writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); + + /* wait for dma done bit to be set */ + status = readb(dma_cs_addr); + for (ii = 0; + (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) { + status = readb(dma_cs_addr); + WAIT_QUIETLY; + } + if ((status & PLX_DMA_DONE_BIT) == 0) { + printk("rtd520: Timeout waiting for dma %i done set\n", + channel); } - printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor); +abortDmaExit: + /* spin_unlock_irqrestore( &dev->spinlock, flags ); */ +} - return 1; +/* + Process what is in the DMA transfer buffer and pass to comedi + Note: this is not re-entrant +*/ +static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) +{ + int ii, n; + s16 *dp; -#if 0 - /* hit an error, clean up memory and return ret */ -/* rtd_attach_die_error: */ -#ifdef USE_DMA - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - if (NULL != devpriv->dma0Buff[index]) { /* free buffer memory */ - pci_free_consistent(devpriv->pci_dev, - sizeof(u16) * devpriv->fifoLen / 2, - devpriv->dma0Buff[index], - devpriv->dma0BuffPhysAddr[index]); - devpriv->dma0Buff[index] = NULL; + if (devpriv->aiCount == 0) /* transfer already complete */ + return 0; + + dp = devpriv->dma0Buff[devpriv->dma0Offset]; + for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */ + short sample; + + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */ + else + sample = *dp >> 3; /* low 3 bits are marker lines */ + + *dp++ = sample; /* put processed value back */ + + if (++s->async->cur_chan >= s->async->cmd.chanlist_len) + s->async->cur_chan = 0; + + ++ii; /* number ready to transfer */ + if (devpriv->aiCount > 0) { /* < 0, means read forever */ + if (--devpriv->aiCount == 0) { /* done */ + /*DPRINTK ("rtd520: Final %d samples\n", ii); */ + break; + } } } - if (NULL != devpriv->dma0Chain) { - pci_free_consistent(devpriv->pci_dev, - sizeof(struct plx_dma_desc) - * DMA_CHAIN_COUNT, - devpriv->dma0Chain, - devpriv->dma0ChainPhysAddr); - devpriv->dma0Chain = NULL; - } -#endif /* USE_DMA */ - /* subdevices and priv are freed by the core */ - if (dev->irq) { - /* disable interrupt controller */ - RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev) - & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E)); - free_irq(dev->irq, dev); + + /* now pass the whole array to the comedi buffer */ + dp = devpriv->dma0Buff[devpriv->dma0Offset]; + n = comedi_buf_write_alloc(s->async, ii * sizeof(s16)); + if (n < (ii * sizeof(s16))) { /* any residual is an error */ + DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n", + ii - (n / sizeof(s16))); + s->async->events |= COMEDI_CB_ERROR; + return -1; } + comedi_buf_memcpy_to(s->async, 0, dp, n); + comedi_buf_write_free(s->async, n); - /* release all regions that were allocated */ - if (devpriv->las0) - iounmap(devpriv->las0); + /* + * always at least 1 scan -- 1/2 FIFO is larger than our max scan list + */ + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - if (devpriv->las1) - iounmap(devpriv->las1); + if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */ + devpriv->dma0Offset = 0; + } + return 0; +} +#endif /* USE_DMA */ - if (devpriv->lcfg) - iounmap(devpriv->lcfg); +/* + Handle all rtd520 interrupts. + Runs atomically and is never re-entered. + This is a "slow handler"; other interrupts may be active. + The data conversion may someday happen in a "bottom half". +*/ +static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ + void *d) +{ /* our data *//* cpu context (ignored) */ + struct comedi_device *dev = d; /* must be called "dev" for devpriv */ + u16 status; + u16 fifoStatus; + struct comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */ - if (devpriv->pci_dev) - pci_dev_put(devpriv->pci_dev); + if (!dev->attached) + return IRQ_NONE; - return ret; -#endif -} + devpriv->intCount++; /* DEBUG statistics */ -static void rtd_detach(struct comedi_device *dev) -{ + fifoStatus = RtdFifoStatus(dev); + /* check for FIFO full, this automatically halts the ADC! */ + if (!(fifoStatus & FS_ADC_NOT_FULL)) { /* 0 -> full */ + DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ + goto abortTransfer; + } #ifdef USE_DMA - int index; -#endif + if (devpriv->flags & DMA0_ACTIVE) { /* Check DMA */ + u32 istatus = RtdPlxInterruptRead(dev); - if (devpriv) { - /* Shut down any board ops by resetting it */ -#ifdef USE_DMA - if (devpriv->lcfg) { - RtdDma0Control(dev, 0); /* disable DMA */ - RtdDma1Control(dev, 0); /* disable DMA */ - RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE); - } -#endif /* USE_DMA */ - if (devpriv->las0) { - RtdResetBoard(dev); - RtdInterruptMask(dev, 0); - RtdInterruptClearMask(dev, ~0); - RtdInterruptClear(dev); /* clears bits set by mask */ - } -#ifdef USE_DMA - /* release DMA */ - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - if (NULL != devpriv->dma0Buff[index]) { - pci_free_consistent(devpriv->pci_dev, - sizeof(u16) * - devpriv->fifoLen / 2, - devpriv->dma0Buff[index], - devpriv-> - dma0BuffPhysAddr[index]); - devpriv->dma0Buff[index] = NULL; + if (istatus & ICS_DMA0_A) { + if (ai_process_dma(dev, s) < 0) { + DPRINTK + ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n", + devpriv->aiCount); + RtdDma0Control(dev, + (devpriv->dma0Control & + ~PLX_DMA_START_BIT) + | PLX_CLEAR_DMA_INTR_BIT); + goto abortTransfer; } + + /*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n", + devpriv->aiCount, istatus); */ + RtdDma0Control(dev, + (devpriv-> + dma0Control & ~PLX_DMA_START_BIT) + | PLX_CLEAR_DMA_INTR_BIT); + if (0 == devpriv->aiCount) { /* counted down */ + DPRINTK("rtd520: Samples Done (DMA).\n"); + goto transferDone; + } + comedi_event(dev, s); + } else { + /*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus); */ } - if (NULL != devpriv->dma0Chain) { - pci_free_consistent(devpriv->pci_dev, - sizeof(struct plx_dma_desc) * - DMA_CHAIN_COUNT, devpriv->dma0Chain, - devpriv->dma0ChainPhysAddr); - devpriv->dma0Chain = NULL; - } + } + /* Fall through and check for other interrupt sources */ #endif /* USE_DMA */ - if (dev->irq) { - RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev) - & ~(ICS_PLIE | ICS_DMA0_E | - ICS_DMA1_E)); - free_irq(dev->irq, dev); - } - if (devpriv->las0) - iounmap(devpriv->las0); - if (devpriv->las1) - iounmap(devpriv->las1); - if (devpriv->lcfg) - iounmap(devpriv->lcfg); - if (devpriv->pci_dev) { - if (devpriv->got_regions) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); + + status = RtdInterruptStatus(dev); + /* if interrupt was not caused by our board, or handled above */ + if (0 == status) + return IRQ_HANDLED; + + if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */ + /* since the priority interrupt controller may have queued a sample + counter interrupt, even though we have already finished, + we must handle the possibility that there is no data here */ + if (!(fifoStatus & FS_ADC_HEMPTY)) { /* 0 -> 1/2 full */ + /*DPRINTK("rtd520: Sample int, reading 1/2FIFO. fifo_status 0x%x\n", + (fifoStatus ^ 0x6666) & 0x7777); */ + if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) { + DPRINTK + ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n", + devpriv->aiCount); + goto abortTransfer; + } + if (0 == devpriv->aiCount) { /* counted down */ + DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ + goto transferDone; + } + comedi_event(dev, s); + } else if (devpriv->transCount > 0) { /* read often */ + /*DPRINTK("rtd520: Sample int, reading %d fifo_status 0x%x\n", + devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */ + if (fifoStatus & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ + if (ai_read_n(dev, s, devpriv->transCount) < 0) { + DPRINTK + ("rtd520: comedi read buffer overflow (N) with %ld to go!\n", + devpriv->aiCount); + goto abortTransfer; + } + if (0 == devpriv->aiCount) { /* counted down */ + DPRINTK + ("rtd520: Samples Done (N). fifo_status was 0x%x\n", + (fifoStatus ^ 0x6666) & 0x7777); + goto transferDone; + } + comedi_event(dev, s); + } + } else { /* wait for 1/2 FIFO (old) */ + DPRINTK + ("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n", + (fifoStatus ^ 0x6666) & 0x7777); } + } else { + DPRINTK("rtd520: unknown interrupt source!\n"); } -} -/* - Convert a single comedi channel-gain entry to a RTD520 table entry -*/ -static unsigned short rtdConvertChanGain(struct comedi_device *dev, - unsigned int comediChan, int chanIndex) -{ /* index in channel list */ - unsigned int chan, range, aref; - unsigned short r = 0; + if (0xffff & RtdInterruptOverrunStatus(dev)) { /* interrupt overrun */ + DPRINTK + ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n", + devpriv->aiCount, 0xffff & RtdInterruptOverrunStatus(dev)); + goto abortTransfer; + } - chan = CR_CHAN(comediChan); - range = CR_RANGE(comediChan); - aref = CR_AREF(comediChan); + /* clear the interrupt */ + RtdInterruptClearMask(dev, status); + RtdInterruptClear(dev); + return IRQ_HANDLED; - r |= chan & 0xf; +abortTransfer: + RtdAdcClearFifo(dev); /* clears full flag */ + s->async->events |= COMEDI_CB_ERROR; + devpriv->aiCount = 0; /* stop and don't transfer any more */ + /* fall into transferDone */ - /* Note: we also setup the channel list bipolar flag array */ - if (range < thisboard->range10Start) { /* first batch are +-5 */ - r |= 0x000; /* +-5 range */ - r |= (range & 0x7) << 4; /* gain */ - CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); - } else if (range < thisboard->rangeUniStart) { /* second batch are +-10 */ - r |= 0x100; /* +-10 range */ - /* gain */ - r |= ((range - thisboard->range10Start) & 0x7) << 4; - CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); - } else { /* last batch is +10 */ - r |= 0x200; /* +10 range */ - /* gain */ - r |= ((range - thisboard->rangeUniStart) & 0x7) << 4; - CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex); +transferDone: + RtdPacerStopSource(dev, 0); /* stop on SOFTWARE stop */ + RtdPacerStop(dev); /* Stop PACER */ + RtdAdcConversionSource(dev, 0); /* software trigger only */ + RtdInterruptMask(dev, 0); /* mask out SAMPLE */ +#ifdef USE_DMA + if (devpriv->flags & DMA0_ACTIVE) { + RtdPlxInterruptWrite(dev, /* disable any more interrupts */ + RtdPlxInterruptRead(dev) & ~ICS_DMA0_E); + abort_dma(dev, 0); + devpriv->flags &= ~DMA0_ACTIVE; + /* if Using DMA, then we should have read everything by now */ + if (devpriv->aiCount > 0) { + DPRINTK("rtd520: Lost DMA data! %ld remain\n", + devpriv->aiCount); + } } +#endif /* USE_DMA */ - switch (aref) { - case AREF_GROUND: /* on-board ground */ - break; + if (devpriv->aiCount > 0) { /* there shouldn't be anything left */ + fifoStatus = RtdFifoStatus(dev); + DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777); /* should read all 0s */ + ai_read_dregs(dev, s); /* read anything left in FIFO */ + } - case AREF_COMMON: - r |= 0x80; /* ref external analog common */ - break; + s->async->events |= COMEDI_CB_EOA; /* signal end to comedi */ + comedi_event(dev, s); - case AREF_DIFF: - r |= 0x400; /* differential inputs */ - break; + /* clear the interrupt */ + status = RtdInterruptStatus(dev); + RtdInterruptClearMask(dev, status); + RtdInterruptClear(dev); - case AREF_OTHER: /* ??? */ - break; - } - /*printk ("chan=%d r=%d a=%d -> 0x%x\n", - chan, range, aref, r); */ - return r; + fifoStatus = RtdFifoStatus(dev); /* DEBUG */ + DPRINTK + ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n", + devpriv->intCount, status, + 0xffff & RtdInterruptOverrunStatus(dev)); + + return IRQ_HANDLED; } +#if 0 /* - Setup the channel-gain table from a comedi list + return the number of samples available */ -static void rtd_load_channelgain_list(struct comedi_device *dev, - unsigned int n_chan, unsigned int *list) +static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { - if (n_chan > 1) { /* setup channel gain table */ - int ii; - RtdClearCGT(dev); - RtdEnableCGT(dev, 1); /* enable table */ - for (ii = 0; ii < n_chan; ii++) { - RtdWriteCGTable(dev, rtdConvertChanGain(dev, list[ii], - ii)); - } - } else { /* just use the channel gain latch */ - RtdEnableCGT(dev, 0); /* disable table, enable latch */ - RtdWriteCGLatch(dev, rtdConvertChanGain(dev, list[0], 0)); - } + /* TODO: This needs to mask interrupts, read_dregs, and then re-enable */ + /* Not sure what to do if DMA is active */ + return s->async->buf_write_count - s->async->buf_read_count; } +#endif -/* determine fifo size by doing adc conversions until the fifo half -empty status flag clears */ -static int rtd520_probe_fifo_depth(struct comedi_device *dev) +/* + cmdtest tests a particular command to see if it is valid. + Using the cmdtest ioctl, a user can create a valid cmd + and then have it executed by the cmd ioctl (asyncronously). + + cmdtest returns 1,2,3,4 or 0, depending on which tests + the command passes. +*/ + +static int rtd_ai_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_cmd *cmd) { - unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND); - unsigned i; - static const unsigned limit = 0x2000; - unsigned fifo_size = 0; + int err = 0; + int tmp; - RtdAdcClearFifo(dev); - rtd_load_channelgain_list(dev, 1, &chanspec); - RtdAdcConversionSource(dev, 0); /* software */ - /* convert samples */ - for (i = 0; i < limit; ++i) { - unsigned fifo_status; - /* trigger conversion */ - RtdAdcStart(dev); - udelay(1); - fifo_status = RtdFifoStatus(dev); - if ((fifo_status & FS_ADC_HEMPTY) == 0) { - fifo_size = 2 * i; - break; - } - } - if (i == limit) { - printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", - DRV_NAME); - return -EIO; - } - RtdAdcClearFifo(dev); - if (fifo_size != 0x400 && fifo_size != 0x2000) { - printk - (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n", - DRV_NAME, fifo_size); - return -EIO; - } - return fifo_size; -} + /* step 1: make sure trigger sources are trivially valid */ -/* - "instructions" read/write data in "one-shot" or "software-triggered" - mode (simplest case). - This doesn't use interrupts. + tmp = cmd->start_src; + cmd->start_src &= TRIG_NOW; + if (!cmd->start_src || tmp != cmd->start_src) + err++; - Note, we don't do any settling delays. Use a instruction list to - select, delay, then read. - */ -static int rtd_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - int n, ii; - int stat; + tmp = cmd->scan_begin_src; + cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; + if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) + err++; - /* clear any old fifo data */ - RtdAdcClearFifo(dev); - /* write channel to multiplexer and clear channel gain table */ - rtd_load_channelgain_list(dev, 1, &insn->chanspec); + tmp = cmd->convert_src; + cmd->convert_src &= TRIG_TIMER | TRIG_EXT; + if (!cmd->convert_src || tmp != cmd->convert_src) + err++; - /* set conversion source */ - RtdAdcConversionSource(dev, 0); /* software */ - /* convert n samples */ - for (n = 0; n < insn->n; n++) { - s16 d; - /* trigger conversion */ - RtdAdcStart(dev); + tmp = cmd->scan_end_src; + cmd->scan_end_src &= TRIG_COUNT; + if (!cmd->scan_end_src || tmp != cmd->scan_end_src) + err++; - for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) { - stat = RtdFifoStatus(dev); - if (stat & FS_ADC_NOT_EMPTY) /* 1 -> not empty */ - break; - WAIT_QUIETLY; - } - if (ii >= RTD_ADC_TIMEOUT) { - DPRINTK - ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n", - stat ^ 0x6666); - return -ETIMEDOUT; - } - /* read data */ - d = RtdAdcFifoGet(dev); /* get 2s comp value */ - /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */ - d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) - /* convert to comedi unsigned data */ - data[n] = d + 2048; - else - data[n] = d; + tmp = cmd->stop_src; + cmd->stop_src &= TRIG_COUNT | TRIG_NONE; + if (!cmd->stop_src || tmp != cmd->stop_src) + err++; + + + if (err) + return 1; + + /* step 2: make sure trigger sources are unique + and mutually compatible */ + /* note that mutual compatibility is not an issue here */ + if (cmd->scan_begin_src != TRIG_TIMER && + cmd->scan_begin_src != TRIG_EXT) { + err++; } + if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) + err++; - /* return the number of samples read/written */ - return n; -} + if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) + err++; -/* - Get what we know is there.... Fast! - This uses 1/2 the bus cycles of read_dregs (below). + if (err) + return 2; - The manual claims that we can do a lword read, but it doesn't work here. -*/ -static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, - int count) -{ - int ii; + /* step 3: make sure arguments are trivially compatible */ - for (ii = 0; ii < count; ii++) { - short sample; - s16 d; + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + err++; + } - if (0 == devpriv->aiCount) { /* done */ - d = RtdAdcFifoGet(dev); /* Read N and discard */ - continue; + if (cmd->scan_begin_src == TRIG_TIMER) { + /* Note: these are time periods, not actual rates */ + if (1 == cmd->chanlist_len) { /* no scanning */ + if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) { + cmd->scan_begin_arg = RTD_MAX_SPEED_1; + rtd_ns_to_timer(&cmd->scan_begin_arg, + TRIG_ROUND_UP); + err++; + } + if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) { + cmd->scan_begin_arg = RTD_MIN_SPEED_1; + rtd_ns_to_timer(&cmd->scan_begin_arg, + TRIG_ROUND_DOWN); + err++; + } + } else { + if (cmd->scan_begin_arg < RTD_MAX_SPEED) { + cmd->scan_begin_arg = RTD_MAX_SPEED; + rtd_ns_to_timer(&cmd->scan_begin_arg, + TRIG_ROUND_UP); + err++; + } + if (cmd->scan_begin_arg > RTD_MIN_SPEED) { + cmd->scan_begin_arg = RTD_MIN_SPEED; + rtd_ns_to_timer(&cmd->scan_begin_arg, + TRIG_ROUND_DOWN); + err++; + } } -#if 0 - if (0 == (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY)) { /* DEBUG */ - DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1, - count); - break; + } else { + /* external trigger */ + /* should be level/edge, hi/lo specification here */ + /* should specify multiple external triggers */ + if (cmd->scan_begin_arg > 9) { + cmd->scan_begin_arg = 9; + err++; + } + } + if (cmd->convert_src == TRIG_TIMER) { + if (1 == cmd->chanlist_len) { /* no scanning */ + if (cmd->convert_arg < RTD_MAX_SPEED_1) { + cmd->convert_arg = RTD_MAX_SPEED_1; + rtd_ns_to_timer(&cmd->convert_arg, + TRIG_ROUND_UP); + err++; + } + if (cmd->convert_arg > RTD_MIN_SPEED_1) { + cmd->convert_arg = RTD_MIN_SPEED_1; + rtd_ns_to_timer(&cmd->convert_arg, + TRIG_ROUND_DOWN); + err++; + } + } else { + if (cmd->convert_arg < RTD_MAX_SPEED) { + cmd->convert_arg = RTD_MAX_SPEED; + rtd_ns_to_timer(&cmd->convert_arg, + TRIG_ROUND_UP); + err++; + } + if (cmd->convert_arg > RTD_MIN_SPEED) { + cmd->convert_arg = RTD_MIN_SPEED; + rtd_ns_to_timer(&cmd->convert_arg, + TRIG_ROUND_DOWN); + err++; + } + } + } else { + /* external trigger */ + /* see above */ + if (cmd->convert_arg > 9) { + cmd->convert_arg = 9; + err++; } + } + +#if 0 + if (cmd->scan_end_arg != cmd->chanlist_len) { + cmd->scan_end_arg = cmd->chanlist_len; + err++; + } #endif - d = RtdAdcFifoGet(dev); /* get 2s comp value */ + if (cmd->stop_src == TRIG_COUNT) { + /* TODO check for rounding error due to counter wrap */ - d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { - /* convert to comedi unsigned data */ - sample = d + 2048; - } else - sample = d; + } else { + /* TRIG_NONE */ + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + err++; + } + } - if (!comedi_buf_put(s->async, sample)) - return -1; + if (err) + return 3; - if (devpriv->aiCount > 0) /* < 0, means read forever */ - devpriv->aiCount--; + + /* step 4: fix up any arguments */ + + if (cmd->chanlist_len > RTD_MAX_CHANLIST) { + cmd->chanlist_len = RTD_MAX_CHANLIST; + err++; } - return 0; -} + if (cmd->scan_begin_src == TRIG_TIMER) { + tmp = cmd->scan_begin_arg; + rtd_ns_to_timer(&cmd->scan_begin_arg, + cmd->flags & TRIG_ROUND_MASK); + if (tmp != cmd->scan_begin_arg) + err++; -/* - unknown amout of data is waiting in fifo. -*/ -static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) -{ - while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ - short sample; - s16 d = RtdAdcFifoGet(dev); /* get 2s comp value */ + } + if (cmd->convert_src == TRIG_TIMER) { + tmp = cmd->convert_arg; + rtd_ns_to_timer(&cmd->convert_arg, + cmd->flags & TRIG_ROUND_MASK); + if (tmp != cmd->convert_arg) + err++; - if (0 == devpriv->aiCount) { /* done */ - continue; /* read rest */ + if (cmd->scan_begin_src == TRIG_TIMER + && (cmd->scan_begin_arg + < (cmd->convert_arg * cmd->scan_end_arg))) { + cmd->scan_begin_arg = + cmd->convert_arg * cmd->scan_end_arg; + err++; } + } - d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { - /* convert to comedi unsigned data */ - sample = d + 2048; - } else - sample = d; - - if (!comedi_buf_put(s->async, sample)) - return -1; + if (err) + return 4; - if (devpriv->aiCount > 0) /* < 0, means read forever */ - devpriv->aiCount--; - } return 0; } -#ifdef USE_DMA /* - Terminate a DMA transfer and wait for everything to quiet down + Execute a analog in command with many possible triggering options. + The data get stored in the async structure of the subdevice. + This is usually done by an interrupt handler. + Userland gets to the data using read calls. */ -void abort_dma(struct comedi_device *dev, unsigned int channel) -{ /* DMA channel 0, 1 */ - unsigned long dma_cs_addr; /* the control/status register */ - uint8_t status; - unsigned int ii; - /* unsigned long flags; */ - - dma_cs_addr = (unsigned long)devpriv->lcfg - + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1); - - /* spinlock for plx dma control/status reg */ - /* spin_lock_irqsave( &dev->spinlock, flags ); */ +static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +{ + struct comedi_cmd *cmd = &s->async->cmd; + int timer; - /* abort dma transfer if necessary */ - status = readb(dma_cs_addr); - if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */ - DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n", - channel, status); - goto abortDmaExit; + /* stop anything currently running */ + RtdPacerStopSource(dev, 0); /* stop on SOFTWARE stop */ + RtdPacerStop(dev); /* make sure PACER is stopped */ + RtdAdcConversionSource(dev, 0); /* software trigger only */ + RtdInterruptMask(dev, 0); +#ifdef USE_DMA + if (devpriv->flags & DMA0_ACTIVE) { /* cancel anything running */ + RtdPlxInterruptWrite(dev, /* disable any more interrupts */ + RtdPlxInterruptRead(dev) & ~ICS_DMA0_E); + abort_dma(dev, 0); + devpriv->flags &= ~DMA0_ACTIVE; + if (RtdPlxInterruptRead(dev) & ICS_DMA0_A) { /*clear pending int */ + RtdDma0Control(dev, PLX_CLEAR_DMA_INTR_BIT); + } } + RtdDma0Reset(dev); /* reset onboard state */ +#endif /* USE_DMA */ + RtdAdcClearFifo(dev); /* clear any old data */ + RtdInterruptOverrunClear(dev); + devpriv->intCount = 0; - /* wait to make sure done bit is zero (needed?) */ - for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) { - WAIT_QUIETLY; - status = readb(dma_cs_addr); - } - if (status & PLX_DMA_DONE_BIT) { - printk("rtd520: Timeout waiting for dma %i done clear\n", - channel); - goto abortDmaExit; + if (!dev->irq) { /* we need interrupts for this */ + DPRINTK("rtd520: ERROR! No interrupt available!\n"); + return -ENXIO; } - /* disable channel (required) */ - writeb(0, dma_cs_addr); - udelay(1); /* needed?? */ - /* set abort bit for channel */ - writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); + /* start configuration */ + /* load channel list and reset CGT */ + rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist); - /* wait for dma done bit to be set */ - status = readb(dma_cs_addr); - for (ii = 0; - (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) { - status = readb(dma_cs_addr); - WAIT_QUIETLY; + /* setup the common case and override if needed */ + if (cmd->chanlist_len > 1) { + /*DPRINTK ("rtd520: Multi channel setup\n"); */ + RtdPacerStartSource(dev, 0); /* software triggers pacer */ + RtdBurstStartSource(dev, 1); /* PACER triggers burst */ + RtdAdcConversionSource(dev, 2); /* BURST triggers ADC */ + } else { /* single channel */ + /*DPRINTK ("rtd520: single channel setup\n"); */ + RtdPacerStartSource(dev, 0); /* software triggers pacer */ + RtdAdcConversionSource(dev, 1); /* PACER triggers ADC */ } - if ((status & PLX_DMA_DONE_BIT) == 0) { - printk("rtd520: Timeout waiting for dma %i done set\n", - channel); + RtdAboutCounter(dev, devpriv->fifoLen / 2 - 1); /* 1/2 FIFO */ + + if (TRIG_TIMER == cmd->scan_begin_src) { + /* scan_begin_arg is in nanoseconds */ + /* find out how many samples to wait before transferring */ + if (cmd->flags & TRIG_WAKE_EOS) { + /* this may generate un-sustainable interrupt rates */ + /* the application is responsible for doing the right thing */ + devpriv->transCount = cmd->chanlist_len; + devpriv->flags |= SEND_EOS; + } else { + /* arrange to transfer data periodically */ + devpriv->transCount + = + (TRANS_TARGET_PERIOD * cmd->chanlist_len) / + cmd->scan_begin_arg; + if (devpriv->transCount < cmd->chanlist_len) { + /* transfer after each scan (and avoid 0) */ + devpriv->transCount = cmd->chanlist_len; + } else { /* make a multiple of scan length */ + devpriv->transCount = + (devpriv->transCount + + cmd->chanlist_len - 1) + / cmd->chanlist_len; + devpriv->transCount *= cmd->chanlist_len; + } + devpriv->flags |= SEND_EOS; + } + if (devpriv->transCount >= (devpriv->fifoLen / 2)) { + /* out of counter range, use 1/2 fifo instead */ + devpriv->transCount = 0; + devpriv->flags &= ~SEND_EOS; + } else { + /* interrupt for each transfer */ + RtdAboutCounter(dev, devpriv->transCount - 1); + } + + DPRINTK + ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", + cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, + cmd->scan_begin_arg, devpriv->flags); + } else { /* unknown timing, just use 1/2 FIFO */ + devpriv->transCount = 0; + devpriv->flags &= ~SEND_EOS; } + RtdPacerClockSource(dev, 1); /* use INTERNAL 8Mhz clock source */ + RtdAboutStopEnable(dev, 1); /* just interrupt, dont stop */ -abortDmaExit: - /* spin_unlock_irqrestore( &dev->spinlock, flags ); */ -} + /* BUG??? these look like enumerated values, but they are bit fields */ -/* - Process what is in the DMA transfer buffer and pass to comedi - Note: this is not re-entrant -*/ -static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) -{ - int ii, n; - s16 *dp; + /* First, setup when to stop */ + switch (cmd->stop_src) { + case TRIG_COUNT: /* stop after N scans */ + devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len; + if ((devpriv->transCount > 0) + && (devpriv->transCount > devpriv->aiCount)) { + devpriv->transCount = devpriv->aiCount; + } + break; - if (devpriv->aiCount == 0) /* transfer already complete */ - return 0; + case TRIG_NONE: /* stop when cancel is called */ + devpriv->aiCount = -1; /* read forever */ + break; - dp = devpriv->dma0Buff[devpriv->dma0Offset]; - for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */ - short sample; + default: + DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n", + cmd->stop_src); + } + + /* Scan timing */ + switch (cmd->scan_begin_src) { + case TRIG_TIMER: /* periodic scanning */ + timer = rtd_ns_to_timer(&cmd->scan_begin_arg, + TRIG_ROUND_NEAREST); + /* set PACER clock */ + /*DPRINTK ("rtd520: loading %d into pacer\n", timer); */ + RtdPacerCounter(dev, timer); - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { - sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */ - else - sample = *dp >> 3; /* low 3 bits are marker lines */ + break; - *dp++ = sample; /* put processed value back */ + case TRIG_EXT: + RtdPacerStartSource(dev, 1); /* EXTERNALy trigger pacer */ + break; - if (++s->async->cur_chan >= s->async->cmd.chanlist_len) - s->async->cur_chan = 0; + default: + DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n", + cmd->scan_begin_src); + } - ++ii; /* number ready to transfer */ - if (devpriv->aiCount > 0) { /* < 0, means read forever */ - if (--devpriv->aiCount == 0) { /* done */ - /*DPRINTK ("rtd520: Final %d samples\n", ii); */ - break; - } + /* Sample timing within a scan */ + switch (cmd->convert_src) { + case TRIG_TIMER: /* periodic */ + if (cmd->chanlist_len > 1) { /* only needed for multi-channel */ + timer = rtd_ns_to_timer(&cmd->convert_arg, + TRIG_ROUND_NEAREST); + /* setup BURST clock */ + /*DPRINTK ("rtd520: loading %d into burst\n", timer); */ + RtdBurstCounter(dev, timer); } - } - /* now pass the whole array to the comedi buffer */ - dp = devpriv->dma0Buff[devpriv->dma0Offset]; - n = comedi_buf_write_alloc(s->async, ii * sizeof(s16)); - if (n < (ii * sizeof(s16))) { /* any residual is an error */ - DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n", - ii - (n / sizeof(s16))); - s->async->events |= COMEDI_CB_ERROR; - return -1; - } - comedi_buf_memcpy_to(s->async, 0, dp, n); - comedi_buf_write_free(s->async, n); + break; - /* - * always at least 1 scan -- 1/2 FIFO is larger than our max scan list - */ - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + case TRIG_EXT: /* external */ + RtdBurstStartSource(dev, 2); /* EXTERNALy trigger burst */ + break; - if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */ - devpriv->dma0Offset = 0; + default: + DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n", + cmd->convert_src); } - return 0; -} -#endif /* USE_DMA */ - -/* - Handle all rtd520 interrupts. - Runs atomically and is never re-entered. - This is a "slow handler"; other interrupts may be active. - The data conversion may someday happen in a "bottom half". -*/ -static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ - void *d) -{ /* our data *//* cpu context (ignored) */ - struct comedi_device *dev = d; /* must be called "dev" for devpriv */ - u16 status; - u16 fifoStatus; - struct comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */ - - if (!dev->attached) - return IRQ_NONE; + /* end configuration */ - devpriv->intCount++; /* DEBUG statistics */ + /* This doesn't seem to work. There is no way to clear an interrupt + that the priority controller has queued! */ + RtdInterruptClearMask(dev, ~0); /* clear any existing flags */ + RtdInterruptClear(dev); - fifoStatus = RtdFifoStatus(dev); - /* check for FIFO full, this automatically halts the ADC! */ - if (!(fifoStatus & FS_ADC_NOT_FULL)) { /* 0 -> full */ - DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ - goto abortTransfer; - } + /* TODO: allow multiple interrupt sources */ + if (devpriv->transCount > 0) { /* transfer every N samples */ + RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT); + DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount); + } else { /* 1/2 FIFO transfers */ #ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { /* Check DMA */ - u32 istatus = RtdPlxInterruptRead(dev); + devpriv->flags |= DMA0_ACTIVE; - if (istatus & ICS_DMA0_A) { - if (ai_process_dma(dev, s) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n", - devpriv->aiCount); - RtdDma0Control(dev, - (devpriv->dma0Control & - ~PLX_DMA_START_BIT) - | PLX_CLEAR_DMA_INTR_BIT); - goto abortTransfer; - } + /* point to first transfer in ring */ + devpriv->dma0Offset = 0; + RtdDma0Mode(dev, DMA_MODE_BITS); + RtdDma0Next(dev, /* point to first block */ + devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next); + RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); /* set DMA trigger source */ - /*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n", - devpriv->aiCount, istatus); */ - RtdDma0Control(dev, - (devpriv-> - dma0Control & ~PLX_DMA_START_BIT) - | PLX_CLEAR_DMA_INTR_BIT); - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK("rtd520: Samples Done (DMA).\n"); - goto transferDone; - } - comedi_event(dev, s); - } else { - /*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus); */ - } - } - /* Fall through and check for other interrupt sources */ + RtdPlxInterruptWrite(dev, /* enable interrupt */ + RtdPlxInterruptRead(dev) | ICS_DMA0_E); + /* Must be 2 steps. See PLX app note about "Starting a DMA transfer" */ + RtdDma0Control(dev, PLX_DMA_EN_BIT); /* enable DMA (clear INTR?) */ + RtdDma0Control(dev, PLX_DMA_EN_BIT | PLX_DMA_START_BIT); /*start DMA */ + DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n", + RtdPlxInterruptRead(dev), devpriv->intMask); +#else /* USE_DMA */ + RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT); + DPRINTK("rtd520: Transferring every 1/2 FIFO\n"); #endif /* USE_DMA */ - - status = RtdInterruptStatus(dev); - /* if interrupt was not caused by our board, or handled above */ - if (0 == status) - return IRQ_HANDLED; - - if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */ - /* since the priority interrupt controller may have queued a sample - counter interrupt, even though we have already finished, - we must handle the possibility that there is no data here */ - if (!(fifoStatus & FS_ADC_HEMPTY)) { /* 0 -> 1/2 full */ - /*DPRINTK("rtd520: Sample int, reading 1/2FIFO. fifo_status 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); */ - if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n", - devpriv->aiCount); - goto abortTransfer; - } - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ - goto transferDone; - } - comedi_event(dev, s); - } else if (devpriv->transCount > 0) { /* read often */ - /*DPRINTK("rtd520: Sample int, reading %d fifo_status 0x%x\n", - devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */ - if (fifoStatus & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ - if (ai_read_n(dev, s, devpriv->transCount) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (N) with %ld to go!\n", - devpriv->aiCount); - goto abortTransfer; - } - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK - ("rtd520: Samples Done (N). fifo_status was 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); - goto transferDone; - } - comedi_event(dev, s); - } - } else { /* wait for 1/2 FIFO (old) */ - DPRINTK - ("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); - } - } else { - DPRINTK("rtd520: unknown interrupt source!\n"); - } - - if (0xffff & RtdInterruptOverrunStatus(dev)) { /* interrupt overrun */ - DPRINTK - ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n", - devpriv->aiCount, 0xffff & RtdInterruptOverrunStatus(dev)); - goto abortTransfer; } - /* clear the interrupt */ - RtdInterruptClearMask(dev, status); - RtdInterruptClear(dev); - return IRQ_HANDLED; + /* BUG: start_src is ASSUMED to be TRIG_NOW */ + /* BUG? it seems like things are running before the "start" */ + RtdPacerStart(dev); /* Start PACER */ + return 0; +} -abortTransfer: - RtdAdcClearFifo(dev); /* clears full flag */ - s->async->events |= COMEDI_CB_ERROR; - devpriv->aiCount = 0; /* stop and don't transfer any more */ - /* fall into transferDone */ +/* + Stop a running data acquisition. +*/ +static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) +{ + u16 status; -transferDone: RtdPacerStopSource(dev, 0); /* stop on SOFTWARE stop */ RtdPacerStop(dev); /* Stop PACER */ RtdAdcConversionSource(dev, 0); /* software trigger only */ - RtdInterruptMask(dev, 0); /* mask out SAMPLE */ + RtdInterruptMask(dev, 0); + devpriv->aiCount = 0; /* stop and don't transfer any more */ #ifdef USE_DMA if (devpriv->flags & DMA0_ACTIVE) { RtdPlxInterruptWrite(dev, /* disable any more interrupts */ RtdPlxInterruptRead(dev) & ~ICS_DMA0_E); abort_dma(dev, 0); devpriv->flags &= ~DMA0_ACTIVE; - /* if Using DMA, then we should have read everything by now */ - if (devpriv->aiCount > 0) { - DPRINTK("rtd520: Lost DMA data! %ld remain\n", - devpriv->aiCount); - } } #endif /* USE_DMA */ - - if (devpriv->aiCount > 0) { /* there shouldn't be anything left */ - fifoStatus = RtdFifoStatus(dev); - DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777); /* should read all 0s */ - ai_read_dregs(dev, s); /* read anything left in FIFO */ - } - - s->async->events |= COMEDI_CB_EOA; /* signal end to comedi */ - comedi_event(dev, s); - - /* clear the interrupt */ status = RtdInterruptStatus(dev); - RtdInterruptClearMask(dev, status); - RtdInterruptClear(dev); - - fifoStatus = RtdFifoStatus(dev); /* DEBUG */ DPRINTK - ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n", - devpriv->intCount, status, - 0xffff & RtdInterruptOverrunStatus(dev)); - - return IRQ_HANDLED; -} - -#if 0 -/* - return the number of samples available -*/ -static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) -{ - /* TODO: This needs to mask interrupts, read_dregs, and then re-enable */ - /* Not sure what to do if DMA is active */ - return s->async->buf_write_count - s->async->buf_read_count; + ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n", + devpriv->intCount, status, + 0xffff & RtdInterruptOverrunStatus(dev)); + return 0; } -#endif /* - cmdtest tests a particular command to see if it is valid. - Using the cmdtest ioctl, a user can create a valid cmd - and then have it executed by the cmd ioctl (asyncronously). - - cmdtest returns 1,2,3,4 or 0, depending on which tests - the command passes. + Output one (or more) analog values to a single port as fast as possible. */ - -static int rtd_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) +static int rtd_ao_winsn(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_insn *insn, + unsigned int *data) { - int err = 0; - int tmp; - - /* step 1: make sure trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + int i; + int chan = CR_CHAN(insn->chanspec); + int range = CR_RANGE(insn->chanspec); + /* Configure the output range (table index matches the range values) */ + RtdDacRange(dev, chan, range); - if (err) - return 1; + /* Writing a list of values to an AO channel is probably not + * very useful, but that's how the interface is defined. */ + for (i = 0; i < insn->n; ++i) { + int val = data[i] << 3; + int stat = 0; /* initialize to avoid bogus warning */ + int ii; - /* step 2: make sure trigger sources are unique - and mutually compatible */ - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) { - err++; - } - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) - err++; + /* VERIFY: comedi range and offset conversions */ - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + if ((range > 1) /* bipolar */ + && (data[i] < 2048)) { + /* offset and sign extend */ + val = (((int)data[i]) - 2048) << 3; + } else { /* unipolor */ + val = data[i] << 3; + } - if (err) - return 2; + DPRINTK + ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n", + chan, range, data[i], val); - /* step 3: make sure arguments are trivially compatible */ + /* a typical programming sequence */ + RtdDacFifoPut(dev, chan, val); /* put the value in */ + RtdDacUpdate(dev, chan); /* trigger the conversion */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + devpriv->aoValue[chan] = data[i]; /* save for read back */ - if (cmd->scan_begin_src == TRIG_TIMER) { - /* Note: these are time periods, not actual rates */ - if (1 == cmd->chanlist_len) { /* no scanning */ - if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) { - cmd->scan_begin_arg = RTD_MAX_SPEED_1; - rtd_ns_to_timer(&cmd->scan_begin_arg, - TRIG_ROUND_UP); - err++; - } - if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) { - cmd->scan_begin_arg = RTD_MIN_SPEED_1; - rtd_ns_to_timer(&cmd->scan_begin_arg, - TRIG_ROUND_DOWN); - err++; - } - } else { - if (cmd->scan_begin_arg < RTD_MAX_SPEED) { - cmd->scan_begin_arg = RTD_MAX_SPEED; - rtd_ns_to_timer(&cmd->scan_begin_arg, - TRIG_ROUND_UP); - err++; - } - if (cmd->scan_begin_arg > RTD_MIN_SPEED) { - cmd->scan_begin_arg = RTD_MIN_SPEED; - rtd_ns_to_timer(&cmd->scan_begin_arg, - TRIG_ROUND_DOWN); - err++; - } - } - } else { - /* external trigger */ - /* should be level/edge, hi/lo specification here */ - /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (1 == cmd->chanlist_len) { /* no scanning */ - if (cmd->convert_arg < RTD_MAX_SPEED_1) { - cmd->convert_arg = RTD_MAX_SPEED_1; - rtd_ns_to_timer(&cmd->convert_arg, - TRIG_ROUND_UP); - err++; - } - if (cmd->convert_arg > RTD_MIN_SPEED_1) { - cmd->convert_arg = RTD_MIN_SPEED_1; - rtd_ns_to_timer(&cmd->convert_arg, - TRIG_ROUND_DOWN); - err++; - } - } else { - if (cmd->convert_arg < RTD_MAX_SPEED) { - cmd->convert_arg = RTD_MAX_SPEED; - rtd_ns_to_timer(&cmd->convert_arg, - TRIG_ROUND_UP); - err++; - } - if (cmd->convert_arg > RTD_MIN_SPEED) { - cmd->convert_arg = RTD_MIN_SPEED; - rtd_ns_to_timer(&cmd->convert_arg, - TRIG_ROUND_DOWN); - err++; - } + for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) { + stat = RtdFifoStatus(dev); + /* 1 -> not empty */ + if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY : + FS_DAC2_NOT_EMPTY)) + break; + WAIT_QUIETLY; } - } else { - /* external trigger */ - /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; + if (ii >= RTD_DAC_TIMEOUT) { + DPRINTK + ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n", + stat ^ 0x6666); + return -ETIMEDOUT; } } -#if 0 - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } -#endif - if (cmd->stop_src == TRIG_COUNT) { - /* TODO check for rounding error due to counter wrap */ + /* return the number of samples read/written */ + return i; +} - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } +/* AO subdevices should have a read insn as well as a write insn. + * Usually this means copying a value stored in devpriv. */ +static int rtd_ao_rinsn(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_insn *insn, + unsigned int *data) +{ + int i; + int chan = CR_CHAN(insn->chanspec); - if (err) - return 3; + for (i = 0; i < insn->n; i++) + data[i] = devpriv->aoValue[chan]; - /* step 4: fix up any arguments */ + return i; +} - if (cmd->chanlist_len > RTD_MAX_CHANLIST) { - cmd->chanlist_len = RTD_MAX_CHANLIST; - err++; - } - if (cmd->scan_begin_src == TRIG_TIMER) { - tmp = cmd->scan_begin_arg; - rtd_ns_to_timer(&cmd->scan_begin_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->scan_begin_arg) - err++; +/* + Write a masked set of bits and the read back the port. + We track what the bits should be (i.e. we don't read the port first). - } - if (cmd->convert_src == TRIG_TIMER) { - tmp = cmd->convert_arg; - rtd_ns_to_timer(&cmd->convert_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->convert_arg) - err++; + DIO devices are slightly special. Although it is possible to + * implement the insn_read/insn_write interface, it is much more + * useful to applications if you implement the insn_bits interface. + * This allows packed reading/writing of the DIO channels. The + * comedi core can convert between insn_bits and insn_read/write + */ +static int rtd_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; - if (cmd->scan_begin_src == TRIG_TIMER - && (cmd->scan_begin_arg - < (cmd->convert_arg * cmd->scan_end_arg))) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->scan_end_arg; - err++; - } + /* The insn data is a mask in data[0] and the new data + * in data[1], each channel cooresponding to a bit. */ + if (data[0]) { + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + + /* Write out the new digital output lines */ + RtdDio0Write(dev, s->state); } + /* on return, data[1] contains the value of the digital + * input lines. */ + data[1] = RtdDio0Read(dev); - if (err) - return 4; + /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */ - return 0; + return 2; } /* - Execute a analog in command with many possible triggering options. - The data get stored in the async structure of the subdevice. - This is usually done by an interrupt handler. - Userland gets to the data using read calls. + Configure one bit on a IO port as Input or Output (hence the name :-). */ -static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +static int rtd_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { - struct comedi_cmd *cmd = &s->async->cmd; - int timer; - - /* stop anything currently running */ - RtdPacerStopSource(dev, 0); /* stop on SOFTWARE stop */ - RtdPacerStop(dev); /* make sure PACER is stopped */ - RtdAdcConversionSource(dev, 0); /* software trigger only */ - RtdInterruptMask(dev, 0); -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { /* cancel anything running */ - RtdPlxInterruptWrite(dev, /* disable any more interrupts */ - RtdPlxInterruptRead(dev) & ~ICS_DMA0_E); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - if (RtdPlxInterruptRead(dev) & ICS_DMA0_A) { /*clear pending int */ - RtdDma0Control(dev, PLX_CLEAR_DMA_INTR_BIT); - } - } - RtdDma0Reset(dev); /* reset onboard state */ -#endif /* USE_DMA */ - RtdAdcClearFifo(dev); /* clear any old data */ - RtdInterruptOverrunClear(dev); - devpriv->intCount = 0; - - if (!dev->irq) { /* we need interrupts for this */ - DPRINTK("rtd520: ERROR! No interrupt available!\n"); - return -ENXIO; - } - - /* start configuration */ - /* load channel list and reset CGT */ - rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist); + int chan = CR_CHAN(insn->chanspec); - /* setup the common case and override if needed */ - if (cmd->chanlist_len > 1) { - /*DPRINTK ("rtd520: Multi channel setup\n"); */ - RtdPacerStartSource(dev, 0); /* software triggers pacer */ - RtdBurstStartSource(dev, 1); /* PACER triggers burst */ - RtdAdcConversionSource(dev, 2); /* BURST triggers ADC */ - } else { /* single channel */ - /*DPRINTK ("rtd520: single channel setup\n"); */ - RtdPacerStartSource(dev, 0); /* software triggers pacer */ - RtdAdcConversionSource(dev, 1); /* PACER triggers ADC */ + /* The input or output configuration of each digital line is + * configured by a special insn_config instruction. chanspec + * contains the channel to be changed, and data[0] contains the + * value COMEDI_INPUT or COMEDI_OUTPUT. */ + switch (data[0]) { + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits |= 1 << chan; /* 1 means Out */ + break; + case INSN_CONFIG_DIO_INPUT: + s->io_bits &= ~(1 << chan); + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = + (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + break; + default: + return -EINVAL; } - RtdAboutCounter(dev, devpriv->fifoLen / 2 - 1); /* 1/2 FIFO */ - if (TRIG_TIMER == cmd->scan_begin_src) { - /* scan_begin_arg is in nanoseconds */ - /* find out how many samples to wait before transferring */ - if (cmd->flags & TRIG_WAKE_EOS) { - /* this may generate un-sustainable interrupt rates */ - /* the application is responsible for doing the right thing */ - devpriv->transCount = cmd->chanlist_len; - devpriv->flags |= SEND_EOS; - } else { - /* arrange to transfer data periodically */ - devpriv->transCount - = - (TRANS_TARGET_PERIOD * cmd->chanlist_len) / - cmd->scan_begin_arg; - if (devpriv->transCount < cmd->chanlist_len) { - /* transfer after each scan (and avoid 0) */ - devpriv->transCount = cmd->chanlist_len; - } else { /* make a multiple of scan length */ - devpriv->transCount = - (devpriv->transCount + - cmd->chanlist_len - 1) - / cmd->chanlist_len; - devpriv->transCount *= cmd->chanlist_len; - } - devpriv->flags |= SEND_EOS; - } - if (devpriv->transCount >= (devpriv->fifoLen / 2)) { - /* out of counter range, use 1/2 fifo instead */ - devpriv->transCount = 0; - devpriv->flags &= ~SEND_EOS; - } else { - /* interrupt for each transfer */ - RtdAboutCounter(dev, devpriv->transCount - 1); - } + DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits); + /* TODO support digital match interrupts and strobes */ + RtdDioStatusWrite(dev, 0x01); /* make Dio0Ctrl point to direction */ + RtdDio0CtrlWrite(dev, s->io_bits); /* set direction 1 means Out */ + RtdDioStatusWrite(dev, 0); /* make Dio0Ctrl clear interrupts */ - DPRINTK - ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", - cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, - cmd->scan_begin_arg, devpriv->flags); - } else { /* unknown timing, just use 1/2 FIFO */ - devpriv->transCount = 0; - devpriv->flags &= ~SEND_EOS; - } - RtdPacerClockSource(dev, 1); /* use INTERNAL 8Mhz clock source */ - RtdAboutStopEnable(dev, 1); /* just interrupt, dont stop */ + /* port1 can only be all input or all output */ - /* BUG??? these look like enumerated values, but they are bit fields */ + /* there are also 2 user input lines and 2 user output lines */ - /* First, setup when to stop */ - switch (cmd->stop_src) { - case TRIG_COUNT: /* stop after N scans */ - devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len; - if ((devpriv->transCount > 0) - && (devpriv->transCount > devpriv->aiCount)) { - devpriv->transCount = devpriv->aiCount; - } - break; + return 1; +} - case TRIG_NONE: /* stop when cancel is called */ - devpriv->aiCount = -1; /* read forever */ - break; +static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ /* board name and options flags */ + struct comedi_subdevice *s; + struct pci_dev *pcidev; + int ret; + resource_size_t physLas0; /* configuration */ + resource_size_t physLas1; /* data area */ + resource_size_t physLcfg; /* PLX9080 */ +#ifdef USE_DMA + int index; +#endif - default: - DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n", - cmd->stop_src); - } + printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor); - /* Scan timing */ - switch (cmd->scan_begin_src) { - case TRIG_TIMER: /* periodic scanning */ - timer = rtd_ns_to_timer(&cmd->scan_begin_arg, - TRIG_ROUND_NEAREST); - /* set PACER clock */ - /*DPRINTK ("rtd520: loading %d into pacer\n", timer); */ - RtdPacerCounter(dev, timer); +#if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA) + /* You can set this a load time: modprobe comedi comedi_debug=1 */ + if (0 == comedi_debug) /* force DMA debug printks */ + comedi_debug = 1; +#endif - break; + /* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0) + return -ENOMEM; - case TRIG_EXT: - RtdPacerStartSource(dev, 1); /* EXTERNALy trigger pacer */ - break; + /* + * Probe the device to determine what device in the series it is. + */ + for (pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, NULL); + pcidev != NULL; + pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) { + int i; - default: - DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n", - cmd->scan_begin_src); + if (it->options[0] || it->options[1]) { + if (pcidev->bus->number != it->options[0] + || PCI_SLOT(pcidev->devfn) != it->options[1]) { + continue; + } + } + for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i) { + if (pcidev->device == rtd520Boards[i].device_id) { + dev->board_ptr = &rtd520Boards[i]; + break; + } + } + if (dev->board_ptr) + break; /* found one */ } - - /* Sample timing within a scan */ - switch (cmd->convert_src) { - case TRIG_TIMER: /* periodic */ - if (cmd->chanlist_len > 1) { /* only needed for multi-channel */ - timer = rtd_ns_to_timer(&cmd->convert_arg, - TRIG_ROUND_NEAREST); - /* setup BURST clock */ - /*DPRINTK ("rtd520: loading %d into burst\n", timer); */ - RtdBurstCounter(dev, timer); + if (!pcidev) { + if (it->options[0] && it->options[1]) { + printk(KERN_INFO "No RTD card at bus=%d slot=%d.\n", + it->options[0], it->options[1]); + } else { + printk(KERN_INFO "No RTD card found.\n"); } + return -EIO; + } + devpriv->pci_dev = pcidev; + dev->board_name = thisboard->name; - break; - - case TRIG_EXT: /* external */ - RtdBurstStartSource(dev, 2); /* EXTERNALy trigger burst */ - break; - - default: - DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n", - cmd->convert_src); + ret = comedi_pci_enable(pcidev, DRV_NAME); + if (ret < 0) { + printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); + return ret; } - /* end configuration */ + devpriv->got_regions = 1; - /* This doesn't seem to work. There is no way to clear an interrupt - that the priority controller has queued! */ - RtdInterruptClearMask(dev, ~0); /* clear any existing flags */ - RtdInterruptClear(dev); + /* + * Initialize base addresses + */ + /* Get the physical address from PCI config */ + physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX); + physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX); + physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX); + /* Now have the kernel map this into memory */ + /* ASSUME page aligned */ + devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE); + devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE); + devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE); - /* TODO: allow multiple interrupt sources */ - if (devpriv->transCount > 0) { /* transfer every N samples */ - RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT); - DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount); - } else { /* 1/2 FIFO transfers */ -#ifdef USE_DMA - devpriv->flags |= DMA0_ACTIVE; + if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) + return -ENOMEM; - /* point to first transfer in ring */ - devpriv->dma0Offset = 0; - RtdDma0Mode(dev, DMA_MODE_BITS); - RtdDma0Next(dev, /* point to first block */ - devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next); - RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); /* set DMA trigger source */ - RtdPlxInterruptWrite(dev, /* enable interrupt */ - RtdPlxInterruptRead(dev) | ICS_DMA0_E); - /* Must be 2 steps. See PLX app note about "Starting a DMA transfer" */ - RtdDma0Control(dev, PLX_DMA_EN_BIT); /* enable DMA (clear INTR?) */ - RtdDma0Control(dev, PLX_DMA_EN_BIT | PLX_DMA_START_BIT); /*start DMA */ - DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n", - RtdPlxInterruptRead(dev), devpriv->intMask); -#else /* USE_DMA */ - RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT); - DPRINTK("rtd520: Transferring every 1/2 FIFO\n"); -#endif /* USE_DMA */ - } + DPRINTK("%s: LAS0=%llx, LAS1=%llx, CFG=%llx.\n", dev->board_name, + (unsigned long long)physLas0, (unsigned long long)physLas1, + (unsigned long long)physLcfg); + { /* The RTD driver does this */ + unsigned char pci_latency; + u16 revision; + /*uint32_t epld_version; */ - /* BUG: start_src is ASSUMED to be TRIG_NOW */ - /* BUG? it seems like things are running before the "start" */ - RtdPacerStart(dev); /* Start PACER */ - return 0; -} + pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID, + &revision); + DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); -/* - Stop a running data acquisition. -*/ -static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - u16 status; + pci_read_config_byte(devpriv->pci_dev, + PCI_LATENCY_TIMER, &pci_latency); + if (pci_latency < 32) { + printk(KERN_INFO "%s: PCI latency changed from %d to %d\n", + dev->board_name, pci_latency, 32); + pci_write_config_byte(devpriv->pci_dev, + PCI_LATENCY_TIMER, 32); + } else { + DPRINTK("rtd520: PCI latency = %d\n", pci_latency); + } - RtdPacerStopSource(dev, 0); /* stop on SOFTWARE stop */ - RtdPacerStop(dev); /* Stop PACER */ - RtdAdcConversionSource(dev, 0); /* software trigger only */ - RtdInterruptMask(dev, 0); - devpriv->aiCount = 0; /* stop and don't transfer any more */ -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { - RtdPlxInterruptWrite(dev, /* disable any more interrupts */ - RtdPlxInterruptRead(dev) & ~ICS_DMA0_E); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; + /* + * Undocumented EPLD version (doesn't match RTD driver results) + */ + /*DPRINTK ("rtd520: Reading epld from %p\n", + devpriv->las0+0); + epld_version = readl (devpriv->las0+0); + if ((epld_version & 0xF0) >> 4 == 0x0F) { + DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version); + } else { + DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4); + } */ } -#endif /* USE_DMA */ - status = RtdInterruptStatus(dev); - DPRINTK - ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n", - devpriv->intCount, status, - 0xffff & RtdInterruptOverrunStatus(dev)); - return 0; -} -/* - Given a desired period and the clock period (both in ns), - return the proper counter value (divider-1). - Sets the original period to be the true value. - Note: you have to check if the value is larger than the counter range! -*/ -static int rtd_ns_to_timer_base(unsigned int *nanosec, /* desired period (in ns) */ - int round_mode, int base) -{ /* clock period (in ns) */ - int divider; + /* Show board configuration */ + printk(KERN_INFO "%s:", dev->board_name); - switch (round_mode) { - case TRIG_ROUND_NEAREST: - default: - divider = (*nanosec + base / 2) / base; - break; - case TRIG_ROUND_DOWN: - divider = (*nanosec) / base; - break; - case TRIG_ROUND_UP: - divider = (*nanosec + base - 1) / base; - break; - } - if (divider < 2) - divider = 2; /* min is divide by 2 */ + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; - /* Note: we don't check for max, because different timers - have different ranges */ - *nanosec = base * divider; - return divider - 1; /* countdown is divisor+1 */ -} + s = dev->subdevices + 0; + dev->read_subdev = s; + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; + s->n_chan = thisboard->aiChans; + s->maxdata = (1 << thisboard->aiBits) - 1; + if (thisboard->aiMaxGain <= 32) + s->range_table = &rtd_ai_7520_range; + else + s->range_table = &rtd_ai_4520_range; -/* - Given a desired period (in ns), - return the proper counter value (divider-1) for the internal clock. - Sets the original period to be the true value. -*/ -static int rtd_ns_to_timer(unsigned int *ns, int round_mode) -{ - return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE); -} + s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ + s->insn_read = rtd_ai_rinsn; + s->do_cmd = rtd_ai_cmd; + s->do_cmdtest = rtd_ai_cmdtest; + s->cancel = rtd_ai_cancel; + /* s->poll = rtd_ai_poll; *//* not ready yet */ -/* - Output one (or more) analog values to a single port as fast as possible. -*/ -static int rtd_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - int i; - int chan = CR_CHAN(insn->chanspec); - int range = CR_RANGE(insn->chanspec); + s = dev->subdevices + 1; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 2; + s->maxdata = (1 << thisboard->aiBits) - 1; + s->range_table = &rtd_ao_range; + s->insn_write = rtd_ao_winsn; + s->insn_read = rtd_ao_rinsn; - /* Configure the output range (table index matches the range values) */ - RtdDacRange(dev, chan, range); + s = dev->subdevices + 2; + /* digital i/o subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + /* we only support port 0 right now. Ignoring port 1 and user IO */ + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = rtd_dio_insn_bits; + s->insn_config = rtd_dio_insn_config; - /* Writing a list of values to an AO channel is probably not - * very useful, but that's how the interface is defined. */ - for (i = 0; i < insn->n; ++i) { - int val = data[i] << 3; - int stat = 0; /* initialize to avoid bogus warning */ - int ii; + /* timer/counter subdevices (not currently supported) */ + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 3; + s->maxdata = 0xffff; - /* VERIFY: comedi range and offset conversions */ + /* initialize board, per RTD spec */ + /* also, initialize shadow registers */ + RtdResetBoard(dev); + udelay(100); /* needed? */ + RtdPlxInterruptWrite(dev, 0); + RtdInterruptMask(dev, 0); /* and sets shadow */ + RtdInterruptClearMask(dev, ~0); /* and sets shadow */ + RtdInterruptClear(dev); /* clears bits set by mask */ + RtdInterruptOverrunClear(dev); + RtdClearCGT(dev); + RtdAdcClearFifo(dev); + RtdDacClearFifo(dev, 0); + RtdDacClearFifo(dev, 1); + /* clear digital IO fifo */ + RtdDioStatusWrite(dev, 0); /* safe state, set shadow */ + RtdUtcCtrlPut(dev, 0, 0x30); /* safe state, set shadow */ + RtdUtcCtrlPut(dev, 1, 0x30); /* safe state, set shadow */ + RtdUtcCtrlPut(dev, 2, 0x30); /* safe state, set shadow */ + RtdUtcCtrlPut(dev, 3, 0); /* safe state, set shadow */ + /* TODO: set user out source ??? */ - if ((range > 1) /* bipolar */ - && (data[i] < 2048)) { - /* offset and sign extend */ - val = (((int)data[i]) - 2048) << 3; - } else { /* unipolor */ - val = data[i] << 3; - } + /* check if our interrupt is available and get it */ + ret = request_irq(devpriv->pci_dev->irq, rtd_interrupt, + IRQF_SHARED, DRV_NAME, dev); - DPRINTK - ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n", - chan, range, data[i], val); + if (ret < 0) { + printk("Could not get interrupt! (%u)\n", + devpriv->pci_dev->irq); + return ret; + } + dev->irq = devpriv->pci_dev->irq; + printk(KERN_INFO "( irq=%u )", dev->irq); - /* a typical programming sequence */ - RtdDacFifoPut(dev, chan, val); /* put the value in */ - RtdDacUpdate(dev, chan); /* trigger the conversion */ + ret = rtd520_probe_fifo_depth(dev); + if (ret < 0) + return ret; - devpriv->aoValue[chan] = data[i]; /* save for read back */ + devpriv->fifoLen = ret; + printk("( fifoLen=%d )", devpriv->fifoLen); + +#ifdef USE_DMA + if (dev->irq > 0) { + printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT); + /* + * The PLX9080 has 2 DMA controllers, but there could be + * 4 sources: ADC, digital, DAC1, and DAC2. Since only the + * ADC supports cmd mode right now, this isn't an issue (yet) + */ + devpriv->dma0Offset = 0; - for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) { - stat = RtdFifoStatus(dev); - /* 1 -> not empty */ - if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY : - FS_DAC2_NOT_EMPTY)) - break; - WAIT_QUIETLY; + for (index = 0; index < DMA_CHAIN_COUNT; index++) { + devpriv->dma0Buff[index] = + pci_alloc_consistent(devpriv->pci_dev, + sizeof(u16) * + devpriv->fifoLen / 2, + &devpriv-> + dma0BuffPhysAddr[index]); + if (devpriv->dma0Buff[index] == NULL) { + ret = -ENOMEM; + goto rtd_attach_die_error; + } + /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n", + index, + devpriv->dma0Buff[index], + devpriv->dma0BuffPhysAddr[index]); */ } - if (ii >= RTD_DAC_TIMEOUT) { - DPRINTK - ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n", - stat ^ 0x6666); - return -ETIMEDOUT; + + /* + * setup DMA descriptor ring (use cpu_to_le32 for byte + * ordering?) + */ + devpriv->dma0Chain = + pci_alloc_consistent(devpriv->pci_dev, + sizeof(struct plx_dma_desc) * + DMA_CHAIN_COUNT, + &devpriv->dma0ChainPhysAddr); + for (index = 0; index < DMA_CHAIN_COUNT; index++) { + devpriv->dma0Chain[index].pci_start_addr = + devpriv->dma0BuffPhysAddr[index]; + devpriv->dma0Chain[index].local_start_addr = + DMALADDR_ADC; + devpriv->dma0Chain[index].transfer_size = + sizeof(u16) * devpriv->fifoLen / 2; + devpriv->dma0Chain[index].next = + (devpriv->dma0ChainPhysAddr + ((index + + 1) % + (DMA_CHAIN_COUNT)) + * sizeof(devpriv->dma0Chain[0])) + | DMA_TRANSFER_BITS; + /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n", + index, + ((long)devpriv->dma0ChainPhysAddr + + (index * sizeof(devpriv->dma0Chain[0]))), + devpriv->dma0Chain[index].pci_start_addr, + devpriv->dma0Chain[index].local_start_addr, + devpriv->dma0Chain[index].transfer_size, + devpriv->dma0Chain[index].next); */ } - } - /* return the number of samples read/written */ - return i; -} + if (devpriv->dma0Chain == NULL) { + ret = -ENOMEM; + goto rtd_attach_die_error; + } -/* AO subdevices should have a read insn as well as a write insn. - * Usually this means copying a value stored in devpriv. */ -static int rtd_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - int i; - int chan = CR_CHAN(insn->chanspec); + RtdDma0Mode(dev, DMA_MODE_BITS); + /* set DMA trigger source */ + RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); + } else { + printk(KERN_INFO "( no IRQ->no DMA )"); + } +#endif /* USE_DMA */ - for (i = 0; i < insn->n; i++) - data[i] = devpriv->aoValue[chan]; + if (dev->irq) { /* enable plx9080 interrupts */ + RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE); + } + printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor); - return i; -} + return 1; -/* - Write a masked set of bits and the read back the port. - We track what the bits should be (i.e. we don't read the port first). +#if 0 + /* hit an error, clean up memory and return ret */ +/* rtd_attach_die_error: */ +#ifdef USE_DMA + for (index = 0; index < DMA_CHAIN_COUNT; index++) { + if (NULL != devpriv->dma0Buff[index]) { /* free buffer memory */ + pci_free_consistent(devpriv->pci_dev, + sizeof(u16) * devpriv->fifoLen / 2, + devpriv->dma0Buff[index], + devpriv->dma0BuffPhysAddr[index]); + devpriv->dma0Buff[index] = NULL; + } + } + if (NULL != devpriv->dma0Chain) { + pci_free_consistent(devpriv->pci_dev, + sizeof(struct plx_dma_desc) + * DMA_CHAIN_COUNT, + devpriv->dma0Chain, + devpriv->dma0ChainPhysAddr); + devpriv->dma0Chain = NULL; + } +#endif /* USE_DMA */ + /* subdevices and priv are freed by the core */ + if (dev->irq) { + /* disable interrupt controller */ + RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev) + & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E)); + free_irq(dev->irq, dev); + } - DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The - * comedi core can convert between insn_bits and insn_read/write - */ -static int rtd_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; + /* release all regions that were allocated */ + if (devpriv->las0) + iounmap(devpriv->las0); - /* The insn data is a mask in data[0] and the new data - * in data[1], each channel cooresponding to a bit. */ - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; + if (devpriv->las1) + iounmap(devpriv->las1); - /* Write out the new digital output lines */ - RtdDio0Write(dev, s->state); - } - /* on return, data[1] contains the value of the digital - * input lines. */ - data[1] = RtdDio0Read(dev); + if (devpriv->lcfg) + iounmap(devpriv->lcfg); - /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */ + if (devpriv->pci_dev) + pci_dev_put(devpriv->pci_dev); - return 2; + return ret; +#endif } -/* - Configure one bit on a IO port as Input or Output (hence the name :-). -*/ -static int rtd_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static void rtd_detach(struct comedi_device *dev) { - int chan = CR_CHAN(insn->chanspec); +#ifdef USE_DMA + int index; +#endif - /* The input or output configuration of each digital line is - * configured by a special insn_config instruction. chanspec - * contains the channel to be changed, and data[0] contains the - * value COMEDI_INPUT or COMEDI_OUTPUT. */ - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= 1 << chan; /* 1 means Out */ - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~(1 << chan); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = - (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; + if (devpriv) { + /* Shut down any board ops by resetting it */ +#ifdef USE_DMA + if (devpriv->lcfg) { + RtdDma0Control(dev, 0); /* disable DMA */ + RtdDma1Control(dev, 0); /* disable DMA */ + RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE); + } +#endif /* USE_DMA */ + if (devpriv->las0) { + RtdResetBoard(dev); + RtdInterruptMask(dev, 0); + RtdInterruptClearMask(dev, ~0); + RtdInterruptClear(dev); /* clears bits set by mask */ + } +#ifdef USE_DMA + /* release DMA */ + for (index = 0; index < DMA_CHAIN_COUNT; index++) { + if (NULL != devpriv->dma0Buff[index]) { + pci_free_consistent(devpriv->pci_dev, + sizeof(u16) * + devpriv->fifoLen / 2, + devpriv->dma0Buff[index], + devpriv-> + dma0BuffPhysAddr[index]); + devpriv->dma0Buff[index] = NULL; + } + } + if (NULL != devpriv->dma0Chain) { + pci_free_consistent(devpriv->pci_dev, + sizeof(struct plx_dma_desc) * + DMA_CHAIN_COUNT, devpriv->dma0Chain, + devpriv->dma0ChainPhysAddr); + devpriv->dma0Chain = NULL; + } +#endif /* USE_DMA */ + if (dev->irq) { + RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev) + & ~(ICS_PLIE | ICS_DMA0_E | + ICS_DMA1_E)); + free_irq(dev->irq, dev); + } + if (devpriv->las0) + iounmap(devpriv->las0); + if (devpriv->las1) + iounmap(devpriv->las1); + if (devpriv->lcfg) + iounmap(devpriv->lcfg); + if (devpriv->pci_dev) { + if (devpriv->got_regions) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } } - - DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits); - /* TODO support digital match interrupts and strobes */ - RtdDioStatusWrite(dev, 0x01); /* make Dio0Ctrl point to direction */ - RtdDio0CtrlWrite(dev, s->io_bits); /* set direction 1 means Out */ - RtdDioStatusWrite(dev, 0); /* make Dio0Ctrl clear interrupts */ - - /* port1 can only be all input or all output */ - - /* there are also 2 user input lines and 2 user output lines */ - - return 1; } static struct comedi_driver rtd520_driver = { -- GitLab From 73e183c347242c90524f8913f1af5fc481ad5370 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 23 May 2012 18:19:17 -0700 Subject: [PATCH 0370/6849] staging: comedi: das1800: complete the refactor to remove all forward declarations Complete the refactor of the das1800 driver to remove all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 1242 +++++++++++----------- 1 file changed, 598 insertions(+), 644 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 2ac344354c1d..079fb06de215 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -183,46 +183,6 @@ enum { das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao }; -static int das1800_probe(struct comedi_device *dev); -static int das1800_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); -static irqreturn_t das1800_interrupt(int irq, void *d); -static int das1800_ai_poll(struct comedi_device *dev, - struct comedi_subdevice *s); -static void das1800_ai_handler(struct comedi_device *dev); -static void das1800_handle_dma(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int status); -static void das1800_flush_dma(struct comedi_device *dev, - struct comedi_subdevice *s); -static void das1800_flush_dma_channel(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int channel, uint16_t *buffer); -static void das1800_handle_fifo_half_full(struct comedi_device *dev, - struct comedi_subdevice *s); -static void das1800_handle_fifo_not_empty(struct comedi_device *dev, - struct comedi_subdevice *s); -static int das1800_ai_do_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int das1800_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); -static int das1800_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das1800_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das1800_di_rbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das1800_do_wbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int das1800_set_frequency(struct comedi_device *dev); -static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode); -static unsigned int suggest_transfer_size(struct comedi_cmd *cmd); - /* analog input ranges */ static const struct comedi_lrange range_ai_das1801 = { 8, @@ -515,421 +475,203 @@ static const struct comedi_lrange range_ao_2 = { }; */ -static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, - unsigned int dma1) +static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, + uint16_t sample) { - unsigned long flags; - - /* need an irq to do dma */ - if (dev->irq && dma0) { - /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ - switch ((dma0 & 0x7) | (dma1 << 4)) { - case 0x5: /* dma0 == 5 */ - devpriv->dma_bits |= DMA_CH5; - break; - case 0x6: /* dma0 == 6 */ - devpriv->dma_bits |= DMA_CH6; - break; - case 0x7: /* dma0 == 7 */ - devpriv->dma_bits |= DMA_CH7; - break; - case 0x65: /* dma0 == 5, dma1 == 6 */ - devpriv->dma_bits |= DMA_CH5_CH6; - break; - case 0x76: /* dma0 == 6, dma1 == 7 */ - devpriv->dma_bits |= DMA_CH6_CH7; - break; - case 0x57: /* dma0 == 7, dma1 == 5 */ - devpriv->dma_bits |= DMA_CH7_CH5; - break; - default: - dev_err(dev->hw_dev, " only supports dma channels 5 through 7\n" - " Dual dma only allows the following combinations:\n" - " dma 5,6 / 6,7 / or 7,5\n"); - return -EINVAL; - break; - } - if (request_dma(dma0, dev->driver->driver_name)) { - dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", - dma0); - return -EINVAL; - } - devpriv->dma0 = dma0; - devpriv->dma_current = dma0; - if (dma1) { - if (request_dma(dma1, dev->driver->driver_name)) { - dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", - dma1); - return -EINVAL; - } - devpriv->dma1 = dma1; - } - devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); - if (devpriv->ai_buf0 == NULL) - return -ENOMEM; - devpriv->dma_current_buf = devpriv->ai_buf0; - if (dma1) { - devpriv->ai_buf1 = - kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); - if (devpriv->ai_buf1 == NULL) - return -ENOMEM; - } - flags = claim_dma_lock(); - disable_dma(devpriv->dma0); - set_dma_mode(devpriv->dma0, DMA_MODE_READ); - if (dma1) { - disable_dma(devpriv->dma1); - set_dma_mode(devpriv->dma1, DMA_MODE_READ); - } - release_dma_lock(flags); - } - return 0; + sample += 1 << (thisboard->resolution - 1); + return sample; } -static int das1800_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static void munge_data(struct comedi_device *dev, uint16_t * array, + unsigned int num_elements) { - struct comedi_subdevice *s; - unsigned long iobase = it->options[0]; - unsigned int irq = it->options[1]; - unsigned int dma0 = it->options[2]; - unsigned int dma1 = it->options[3]; - unsigned long iobase2; - int board; - int retval; + unsigned int i; + int unipolar; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct das1800_private)) < 0) - return -ENOMEM; + /* see if card is using a unipolar or bipolar range so we can munge data correctly */ + unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; - printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor, - dev->driver->driver_name, iobase); - if (irq) { - printk(KERN_CONT ", irq %u", irq); - if (dma0) { - printk(KERN_CONT ", dma %u", dma0); - if (dma1) - printk(KERN_CONT " and %u", dma1); - } + /* convert to unsigned type if we are in a bipolar mode */ + if (!unipolar) { + for (i = 0; i < num_elements; i++) + array[i] = munge_bipolar_sample(dev, array[i]); } - printk(KERN_CONT "\n"); +} - if (iobase == 0) { - dev_err(dev->hw_dev, "io base address required\n"); - return -EINVAL; - } +static void das1800_handle_fifo_half_full(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int numPoints = 0; /* number of points to read */ + struct comedi_cmd *cmd = &s->async->cmd; - /* check if io addresses are available */ - if (!request_region(iobase, DAS1800_SIZE, dev->driver->driver_name)) { - printk - (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", - iobase, iobase + DAS1800_SIZE - 1); - return -EIO; - } - dev->iobase = iobase; + numPoints = FIFO_SIZE / 2; + /* if we only need some of the points */ + if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) + numPoints = devpriv->count; + insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); + munge_data(dev, devpriv->ai_buf0, numPoints); + cfc_write_array_to_buffer(s, devpriv->ai_buf0, + numPoints * sizeof(devpriv->ai_buf0[0])); + if (cmd->stop_src == TRIG_COUNT) + devpriv->count -= numPoints; + return; +} - board = das1800_probe(dev); - if (board < 0) { - dev_err(dev->hw_dev, "unable to determine board type\n"); - return -ENODEV; - } +static void das1800_handle_fifo_not_empty(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + short dpnt; + int unipolar; + struct comedi_cmd *cmd = &s->async->cmd; - dev->board_ptr = das1800_boards + board; - dev->board_name = thisboard->name; + unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; - /* if it is an 'ao' board with fancy analog out then we need extra io ports */ - if (thisboard->ao_ability == 2) { - iobase2 = iobase + IOBASE2; - if (!request_region(iobase2, DAS1800_SIZE, - dev->driver->driver_name)) { - printk - (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", - iobase2, iobase2 + DAS1800_SIZE - 1); - return -EIO; - } - devpriv->iobase2 = iobase2; + while (inb(dev->iobase + DAS1800_STATUS) & FNE) { + if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) + break; + dpnt = inw(dev->iobase + DAS1800_FIFO); + /* convert to unsigned type if we are in a bipolar mode */ + if (!unipolar) + ; + dpnt = munge_bipolar_sample(dev, dpnt); + cfc_write_to_buffer(s, dpnt); + if (cmd->stop_src == TRIG_COUNT) + devpriv->count--; } - /* grab our IRQ */ - if (irq) { - if (request_irq(irq, das1800_interrupt, 0, - dev->driver->driver_name, dev)) { - dev_dbg(dev->hw_dev, "unable to allocate irq %u\n", - irq); - return -EINVAL; - } - } - dev->irq = irq; + return; +} - /* set bits that tell card which irq to use */ - switch (irq) { - case 0: - break; - case 3: - devpriv->irq_dma_bits |= 0x8; - break; - case 5: - devpriv->irq_dma_bits |= 0x10; - break; - case 7: - devpriv->irq_dma_bits |= 0x18; - break; - case 10: - devpriv->irq_dma_bits |= 0x28; - break; - case 11: - devpriv->irq_dma_bits |= 0x30; - break; - case 15: - devpriv->irq_dma_bits |= 0x38; - break; - default: - dev_err(dev->hw_dev, "irq out of range\n"); - return -EINVAL; - break; - } +/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). + * Assumes dma lock is held */ +static void das1800_flush_dma_channel(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int channel, uint16_t *buffer) +{ + unsigned int num_bytes, num_samples; + struct comedi_cmd *cmd = &s->async->cmd; - retval = das1800_init_dma(dev, dma0, dma1); - if (retval < 0) - return retval; + disable_dma(channel); - if (devpriv->ai_buf0 == NULL) { - devpriv->ai_buf0 = - kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); - if (devpriv->ai_buf0 == NULL) - return -ENOMEM; - } + /* clear flip-flop to make sure 2-byte registers + * get set correctly */ + clear_dma_ff(channel); - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + /* figure out how many points to read */ + num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); + num_samples = num_bytes / sizeof(short); - /* analog input subdevice */ - s = dev->subdevices + 0; - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; - if (thisboard->common) - s->subdev_flags |= SDF_COMMON; - s->n_chan = thisboard->qram_len; - s->len_chanlist = thisboard->qram_len; - s->maxdata = (1 << thisboard->resolution) - 1; - s->range_table = thisboard->range_ai; - s->do_cmd = das1800_ai_do_cmd; - s->do_cmdtest = das1800_ai_do_cmdtest; - s->insn_read = das1800_ai_rinsn; - s->poll = das1800_ai_poll; - s->cancel = das1800_cancel; - - /* analog out */ - s = dev->subdevices + 1; - if (thisboard->ao_ability == 1) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_n_chan; - s->maxdata = (1 << thisboard->resolution) - 1; - s->range_table = &range_ao_1; - s->insn_write = das1800_ao_winsn; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* if we only need some of the points */ + if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) + num_samples = devpriv->count; - /* di */ - s = dev->subdevices + 2; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = das1800_di_rbits; + munge_data(dev, buffer, num_samples); + cfc_write_array_to_buffer(s, buffer, num_bytes); + if (s->async->cmd.stop_src == TRIG_COUNT) + devpriv->count -= num_samples; - /* do */ - s = dev->subdevices + 3; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = thisboard->do_n_chan; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = das1800_do_wbits; + return; +} - das1800_cancel(dev, dev->read_subdev); +/* flushes remaining data from board when external trigger has stopped acquisition + * and we are using dma transfers */ +static void das1800_flush_dma(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned long flags; + const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; - /* initialize digital out channels */ - outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); + flags = claim_dma_lock(); + das1800_flush_dma_channel(dev, s, devpriv->dma_current, + devpriv->dma_current_buf); - /* initialize analog out channels */ - if (thisboard->ao_ability == 1) { - /* select 'update' dac channel for baseAddress + 0x0 */ - outb(DAC(thisboard->ao_n_chan - 1), - dev->iobase + DAS1800_SELECT); - outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); + if (dual_dma) { + /* switch to other channel and flush it */ + if (devpriv->dma_current == devpriv->dma0) { + devpriv->dma_current = devpriv->dma1; + devpriv->dma_current_buf = devpriv->ai_buf1; + } else { + devpriv->dma_current = devpriv->dma0; + devpriv->dma_current_buf = devpriv->ai_buf0; + } + das1800_flush_dma_channel(dev, s, devpriv->dma_current, + devpriv->dma_current_buf); } - return 0; -}; + release_dma_lock(flags); -static void das1800_detach(struct comedi_device *dev) -{ - if (dev->iobase) - release_region(dev->iobase, DAS1800_SIZE); - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->private) { - if (devpriv->iobase2) - release_region(devpriv->iobase2, DAS1800_SIZE); - if (devpriv->dma0) - free_dma(devpriv->dma0); - if (devpriv->dma1) - free_dma(devpriv->dma1); - kfree(devpriv->ai_buf0); - kfree(devpriv->ai_buf1); - } -}; + /* get any remaining samples in fifo */ + das1800_handle_fifo_not_empty(dev, s); -/* probes and checks das-1800 series board type - */ -static int das1800_probe(struct comedi_device *dev) + return; +} + +static void das1800_handle_dma(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int status) { - int id; - int board; + unsigned long flags; + const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; - id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ - board = ((struct das1800_board *)dev->board_ptr) - das1800_boards; + flags = claim_dma_lock(); + das1800_flush_dma_channel(dev, s, devpriv->dma_current, + devpriv->dma_current_buf); + /* re-enable dma channel */ + set_dma_addr(devpriv->dma_current, + virt_to_bus(devpriv->dma_current_buf)); + set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); + enable_dma(devpriv->dma_current); + release_dma_lock(flags); - switch (id) { - case 0x3: - if (board == das1801st_da || board == das1802st_da || - board == das1701st_da || board == das1702st_da) { - dev_dbg(dev->hw_dev, "Board model: %s\n", - das1800_boards[board].name); - return board; - } - printk - (" Board model (probed, not recommended): das-1800st-da series\n"); - return das1801st; - break; - case 0x4: - if (board == das1802hr_da || board == das1702hr_da) { - dev_dbg(dev->hw_dev, "Board model: %s\n", - das1800_boards[board].name); - return board; - } - printk - (" Board model (probed, not recommended): das-1802hr-da\n"); - return das1802hr; - break; - case 0x5: - if (board == das1801ao || board == das1802ao || - board == das1701ao || board == das1702ao) { - dev_dbg(dev->hw_dev, "Board model: %s\n", - das1800_boards[board].name); - return board; - } - printk - (" Board model (probed, not recommended): das-1800ao series\n"); - return das1801ao; - break; - case 0x6: - if (board == das1802hr || board == das1702hr) { - dev_dbg(dev->hw_dev, "Board model: %s\n", - das1800_boards[board].name); - return board; - } - printk - (" Board model (probed, not recommended): das-1802hr\n"); - return das1802hr; - break; - case 0x7: - if (board == das1801st || board == das1802st || - board == das1701st || board == das1702st) { - dev_dbg(dev->hw_dev, "Board model: %s\n", - das1800_boards[board].name); - return board; - } - printk - (" Board model (probed, not recommended): das-1800st series\n"); - return das1801st; - break; - case 0x8: - if (board == das1801hc || board == das1802hc) { - dev_dbg(dev->hw_dev, "Board model: %s\n", - das1800_boards[board].name); - return board; + if (status & DMATC) { + /* clear DMATC interrupt bit */ + outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); + /* switch dma channels for next time, if appropriate */ + if (dual_dma) { + /* read data from the other channel next time */ + if (devpriv->dma_current == devpriv->dma0) { + devpriv->dma_current = devpriv->dma1; + devpriv->dma_current_buf = devpriv->ai_buf1; + } else { + devpriv->dma_current = devpriv->dma0; + devpriv->dma_current_buf = devpriv->ai_buf0; + } } - printk - (" Board model (probed, not recommended): das-1800hc series\n"); - return das1801hc; - break; - default: - printk - (" Board model: probe returned 0x%x (unknown, please report)\n", - id); - return board; - break; } - return -1; + + return; } -static int das1800_ai_poll(struct comedi_device *dev, - struct comedi_subdevice *s) +static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - unsigned long flags; - - /* prevent race with interrupt handler */ - spin_lock_irqsave(&dev->spinlock, flags); - das1800_ai_handler(dev); - spin_unlock_irqrestore(&dev->spinlock, flags); - - return s->async->buf_write_count - s->async->buf_read_count; + outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ + outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ + outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ + if (devpriv->dma0) + disable_dma(devpriv->dma0); + if (devpriv->dma1) + disable_dma(devpriv->dma1); + return 0; } -static irqreturn_t das1800_interrupt(int irq, void *d) +/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ +static void das1800_ai_handler(struct comedi_device *dev) { - struct comedi_device *dev = d; - unsigned int status; + struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + unsigned int status = inb(dev->iobase + DAS1800_STATUS); - if (dev->attached == 0) { - comedi_error(dev, "premature interrupt"); - return IRQ_HANDLED; - } - - /* Prevent race with das1800_ai_poll() on multi processor systems. - * Also protects indirect addressing in das1800_ai_handler */ - spin_lock(&dev->spinlock); - status = inb(dev->iobase + DAS1800_STATUS); - - /* if interrupt was not caused by das-1800 */ - if (!(status & INT)) { - spin_unlock(&dev->spinlock); - return IRQ_NONE; - } - /* clear the interrupt status bit INT */ - outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); - /* handle interrupt */ - das1800_ai_handler(dev); - - spin_unlock(&dev->spinlock); - return IRQ_HANDLED; -} - -/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ -static void das1800_ai_handler(struct comedi_device *dev) -{ - struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - unsigned int status = inb(dev->iobase + DAS1800_STATUS); - - async->events = 0; - /* select adc for base address + 0 */ - outb(ADC, dev->iobase + DAS1800_SELECT); - /* dma buffer full */ - if (devpriv->irq_dma_bits & DMA_ENABLED) { - /* look for data from dma transfer even if dma terminal count hasn't happened yet */ - das1800_handle_dma(dev, s, status); - } else if (status & FHF) { /* if fifo half full */ - das1800_handle_fifo_half_full(dev, s); - } else if (status & FNE) { /* if fifo not empty */ - das1800_handle_fifo_not_empty(dev, s); + async->events = 0; + /* select adc for base address + 0 */ + outb(ADC, dev->iobase + DAS1800_SELECT); + /* dma buffer full */ + if (devpriv->irq_dma_bits & DMA_ENABLED) { + /* look for data from dma transfer even if dma terminal count hasn't happened yet */ + das1800_handle_dma(dev, s, status); + } else if (status & FHF) { /* if fifo half full */ + das1800_handle_fifo_half_full(dev, s); + } else if (status & FNE) { /* if fifo not empty */ + das1800_handle_fifo_not_empty(dev, s); } async->events |= COMEDI_CB_BLOCK; @@ -965,182 +707,75 @@ static void das1800_ai_handler(struct comedi_device *dev) return; } -static void das1800_handle_dma(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int status) +static int das1800_ai_poll(struct comedi_device *dev, + struct comedi_subdevice *s) { unsigned long flags; - const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; - - flags = claim_dma_lock(); - das1800_flush_dma_channel(dev, s, devpriv->dma_current, - devpriv->dma_current_buf); - /* re-enable dma channel */ - set_dma_addr(devpriv->dma_current, - virt_to_bus(devpriv->dma_current_buf)); - set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); - enable_dma(devpriv->dma_current); - release_dma_lock(flags); - - if (status & DMATC) { - /* clear DMATC interrupt bit */ - outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); - /* switch dma channels for next time, if appropriate */ - if (dual_dma) { - /* read data from the other channel next time */ - if (devpriv->dma_current == devpriv->dma0) { - devpriv->dma_current = devpriv->dma1; - devpriv->dma_current_buf = devpriv->ai_buf1; - } else { - devpriv->dma_current = devpriv->dma0; - devpriv->dma_current_buf = devpriv->ai_buf0; - } - } - } - return; -} + /* prevent race with interrupt handler */ + spin_lock_irqsave(&dev->spinlock, flags); + das1800_ai_handler(dev); + spin_unlock_irqrestore(&dev->spinlock, flags); -static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, - uint16_t sample) -{ - sample += 1 << (thisboard->resolution - 1); - return sample; + return s->async->buf_write_count - s->async->buf_read_count; } -static void munge_data(struct comedi_device *dev, uint16_t * array, - unsigned int num_elements) +static irqreturn_t das1800_interrupt(int irq, void *d) { - unsigned int i; - int unipolar; - - /* see if card is using a unipolar or bipolar range so we can munge data correctly */ - unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; + struct comedi_device *dev = d; + unsigned int status; - /* convert to unsigned type if we are in a bipolar mode */ - if (!unipolar) { - for (i = 0; i < num_elements; i++) - array[i] = munge_bipolar_sample(dev, array[i]); + if (dev->attached == 0) { + comedi_error(dev, "premature interrupt"); + return IRQ_HANDLED; } -} - -/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). - * Assumes dma lock is held */ -static void das1800_flush_dma_channel(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int channel, uint16_t *buffer) -{ - unsigned int num_bytes, num_samples; - struct comedi_cmd *cmd = &s->async->cmd; - - disable_dma(channel); - - /* clear flip-flop to make sure 2-byte registers - * get set correctly */ - clear_dma_ff(channel); - - /* figure out how many points to read */ - num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); - num_samples = num_bytes / sizeof(short); - - /* if we only need some of the points */ - if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) - num_samples = devpriv->count; - - munge_data(dev, buffer, num_samples); - cfc_write_array_to_buffer(s, buffer, num_bytes); - if (s->async->cmd.stop_src == TRIG_COUNT) - devpriv->count -= num_samples; - return; -} - -/* flushes remaining data from board when external trigger has stopped acquisition - * and we are using dma transfers */ -static void das1800_flush_dma(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - unsigned long flags; - const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; - - flags = claim_dma_lock(); - das1800_flush_dma_channel(dev, s, devpriv->dma_current, - devpriv->dma_current_buf); + /* Prevent race with das1800_ai_poll() on multi processor systems. + * Also protects indirect addressing in das1800_ai_handler */ + spin_lock(&dev->spinlock); + status = inb(dev->iobase + DAS1800_STATUS); - if (dual_dma) { - /* switch to other channel and flush it */ - if (devpriv->dma_current == devpriv->dma0) { - devpriv->dma_current = devpriv->dma1; - devpriv->dma_current_buf = devpriv->ai_buf1; - } else { - devpriv->dma_current = devpriv->dma0; - devpriv->dma_current_buf = devpriv->ai_buf0; - } - das1800_flush_dma_channel(dev, s, devpriv->dma_current, - devpriv->dma_current_buf); + /* if interrupt was not caused by das-1800 */ + if (!(status & INT)) { + spin_unlock(&dev->spinlock); + return IRQ_NONE; } + /* clear the interrupt status bit INT */ + outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); + /* handle interrupt */ + das1800_ai_handler(dev); - release_dma_lock(flags); - - /* get any remaining samples in fifo */ - das1800_handle_fifo_not_empty(dev, s); - - return; -} - -static void das1800_handle_fifo_half_full(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - int numPoints = 0; /* number of points to read */ - struct comedi_cmd *cmd = &s->async->cmd; - - numPoints = FIFO_SIZE / 2; - /* if we only need some of the points */ - if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) - numPoints = devpriv->count; - insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); - munge_data(dev, devpriv->ai_buf0, numPoints); - cfc_write_array_to_buffer(s, devpriv->ai_buf0, - numPoints * sizeof(devpriv->ai_buf0[0])); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count -= numPoints; - return; + spin_unlock(&dev->spinlock); + return IRQ_HANDLED; } -static void das1800_handle_fifo_not_empty(struct comedi_device *dev, - struct comedi_subdevice *s) +/* converts requested conversion timing to timing compatible with + * hardware, used only when card is in 'burst mode' + */ +static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) { - short dpnt; - int unipolar; - struct comedi_cmd *cmd = &s->async->cmd; + unsigned int micro_sec; - unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; + /* in burst mode, the maximum conversion time is 64 microseconds */ + if (convert_arg > 64000) + convert_arg = 64000; - while (inb(dev->iobase + DAS1800_STATUS) & FNE) { - if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) - break; - dpnt = inw(dev->iobase + DAS1800_FIFO); - /* convert to unsigned type if we are in a bipolar mode */ - if (!unipolar) - ; - dpnt = munge_bipolar_sample(dev, dpnt); - cfc_write_to_buffer(s, dpnt); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count--; + /* the conversion time must be an integral number of microseconds */ + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + micro_sec = (convert_arg + 500) / 1000; + break; + case TRIG_ROUND_DOWN: + micro_sec = convert_arg / 1000; + break; + case TRIG_ROUND_UP: + micro_sec = (convert_arg - 1) / 1000 + 1; + break; } - return; -} - -static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ - outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ - outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ - if (devpriv->dma0) - disable_dma(devpriv->dma0); - if (devpriv->dma1) - disable_dma(devpriv->dma1); - return 0; + /* return number of nanoseconds */ + return micro_sec * 1000; } /* test analog input cmd */ @@ -1322,10 +957,6 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, return 0; } -/* analog input cmd interface */ - -/* first, some utility functions used in the main ai_do_cmd() */ - /* returns appropriate bits for control register a, depending on command */ static int control_a_bits(struct comedi_cmd cmd) { @@ -1396,15 +1027,34 @@ static int control_c_bits(struct comedi_cmd cmd) return control_c; } -/* sets up counters */ -static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) +/* loads counters with divisor1, divisor2 from private structure */ +static int das1800_set_frequency(struct comedi_device *dev) { - /* setup cascaded counters for conversion/scan frequency */ - switch (cmd.scan_begin_src) { - case TRIG_FOLLOW: /* not in burst mode */ - if (cmd.convert_src == TRIG_TIMER) { - /* set conversion frequency */ - i8253_cascade_ns_to_timer_2div(TIMER_BASE, + int err = 0; + + /* counter 1, mode 2 */ + if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, + 2)) + err++; + /* counter 2, mode 2 */ + if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, + 2)) + err++; + if (err) + return -1; + + return 0; +} + +/* sets up counters */ +static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) +{ + /* setup cascaded counters for conversion/scan frequency */ + switch (cmd.scan_begin_src) { + case TRIG_FOLLOW: /* not in burst mode */ + if (cmd.convert_src == TRIG_TIMER) { + /* set conversion frequency */ + i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(cmd.convert_arg), @@ -1436,6 +1086,44 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) return 0; } +/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ +static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) +{ + unsigned int size = DMA_BUF_SIZE; + static const int sample_size = 2; /* size in bytes of one sample from board */ + unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ + unsigned int max_size; /* maximum size we will allow for a transfer */ + + /* make dma buffer fill in 0.3 seconds for timed modes */ + switch (cmd->scan_begin_src) { + case TRIG_FOLLOW: /* not in burst mode */ + if (cmd->convert_src == TRIG_TIMER) + size = (fill_time / cmd->convert_arg) * sample_size; + break; + case TRIG_TIMER: + size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * + sample_size; + break; + default: + size = DMA_BUF_SIZE; + break; + } + + /* set a minimum and maximum size allowed */ + max_size = DMA_BUF_SIZE; + /* if we are taking limited number of conversions, limit transfer size to that */ + if (cmd->stop_src == TRIG_COUNT && + cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) + max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; + + if (size > max_size) + size = max_size; + if (size < sample_size) + size = sample_size; + + return size; +} + /* sets up dma */ static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) { @@ -1689,91 +1377,357 @@ static int das1800_do_wbits(struct comedi_device *dev, return 2; } -/* loads counters with divisor1, divisor2 from private structure */ -static int das1800_set_frequency(struct comedi_device *dev) +static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, + unsigned int dma1) { - int err = 0; - - /* counter 1, mode 2 */ - if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, - 2)) - err++; - /* counter 2, mode 2 */ - if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, - 2)) - err++; - if (err) - return -1; + unsigned long flags; + /* need an irq to do dma */ + if (dev->irq && dma0) { + /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ + switch ((dma0 & 0x7) | (dma1 << 4)) { + case 0x5: /* dma0 == 5 */ + devpriv->dma_bits |= DMA_CH5; + break; + case 0x6: /* dma0 == 6 */ + devpriv->dma_bits |= DMA_CH6; + break; + case 0x7: /* dma0 == 7 */ + devpriv->dma_bits |= DMA_CH7; + break; + case 0x65: /* dma0 == 5, dma1 == 6 */ + devpriv->dma_bits |= DMA_CH5_CH6; + break; + case 0x76: /* dma0 == 6, dma1 == 7 */ + devpriv->dma_bits |= DMA_CH6_CH7; + break; + case 0x57: /* dma0 == 7, dma1 == 5 */ + devpriv->dma_bits |= DMA_CH7_CH5; + break; + default: + dev_err(dev->hw_dev, " only supports dma channels 5 through 7\n" + " Dual dma only allows the following combinations:\n" + " dma 5,6 / 6,7 / or 7,5\n"); + return -EINVAL; + break; + } + if (request_dma(dma0, dev->driver->driver_name)) { + dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", + dma0); + return -EINVAL; + } + devpriv->dma0 = dma0; + devpriv->dma_current = dma0; + if (dma1) { + if (request_dma(dma1, dev->driver->driver_name)) { + dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", + dma1); + return -EINVAL; + } + devpriv->dma1 = dma1; + } + devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); + if (devpriv->ai_buf0 == NULL) + return -ENOMEM; + devpriv->dma_current_buf = devpriv->ai_buf0; + if (dma1) { + devpriv->ai_buf1 = + kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); + if (devpriv->ai_buf1 == NULL) + return -ENOMEM; + } + flags = claim_dma_lock(); + disable_dma(devpriv->dma0); + set_dma_mode(devpriv->dma0, DMA_MODE_READ); + if (dma1) { + disable_dma(devpriv->dma1); + set_dma_mode(devpriv->dma1, DMA_MODE_READ); + } + release_dma_lock(flags); + } return 0; } -/* converts requested conversion timing to timing compatible with - * hardware, used only when card is in 'burst mode' - */ -static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) +static int das1800_probe(struct comedi_device *dev) { - unsigned int micro_sec; + int id; + int board; - /* in burst mode, the maximum conversion time is 64 microseconds */ - if (convert_arg > 64000) - convert_arg = 64000; + id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ + board = ((struct das1800_board *)dev->board_ptr) - das1800_boards; - /* the conversion time must be an integral number of microseconds */ - switch (round_mode) { - case TRIG_ROUND_NEAREST: - default: - micro_sec = (convert_arg + 500) / 1000; + switch (id) { + case 0x3: + if (board == das1801st_da || board == das1802st_da || + board == das1701st_da || board == das1702st_da) { + dev_dbg(dev->hw_dev, "Board model: %s\n", + das1800_boards[board].name); + return board; + } + printk + (" Board model (probed, not recommended): das-1800st-da series\n"); + return das1801st; break; - case TRIG_ROUND_DOWN: - micro_sec = convert_arg / 1000; + case 0x4: + if (board == das1802hr_da || board == das1702hr_da) { + dev_dbg(dev->hw_dev, "Board model: %s\n", + das1800_boards[board].name); + return board; + } + printk + (" Board model (probed, not recommended): das-1802hr-da\n"); + return das1802hr; break; - case TRIG_ROUND_UP: - micro_sec = (convert_arg - 1) / 1000 + 1; + case 0x5: + if (board == das1801ao || board == das1802ao || + board == das1701ao || board == das1702ao) { + dev_dbg(dev->hw_dev, "Board model: %s\n", + das1800_boards[board].name); + return board; + } + printk + (" Board model (probed, not recommended): das-1800ao series\n"); + return das1801ao; + break; + case 0x6: + if (board == das1802hr || board == das1702hr) { + dev_dbg(dev->hw_dev, "Board model: %s\n", + das1800_boards[board].name); + return board; + } + printk + (" Board model (probed, not recommended): das-1802hr\n"); + return das1802hr; + break; + case 0x7: + if (board == das1801st || board == das1802st || + board == das1701st || board == das1702st) { + dev_dbg(dev->hw_dev, "Board model: %s\n", + das1800_boards[board].name); + return board; + } + printk + (" Board model (probed, not recommended): das-1800st series\n"); + return das1801st; + break; + case 0x8: + if (board == das1801hc || board == das1802hc) { + dev_dbg(dev->hw_dev, "Board model: %s\n", + das1800_boards[board].name); + return board; + } + printk + (" Board model (probed, not recommended): das-1800hc series\n"); + return das1801hc; + break; + default: + printk + (" Board model: probe returned 0x%x (unknown, please report)\n", + id); + return board; break; } - - /* return number of nanoseconds */ - return micro_sec * 1000; + return -1; } -/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ -static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) +static int das1800_attach(struct comedi_device *dev, + struct comedi_devconfig *it) { - unsigned int size = DMA_BUF_SIZE; - static const int sample_size = 2; /* size in bytes of one sample from board */ - unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ - unsigned int max_size; /* maximum size we will allow for a transfer */ + struct comedi_subdevice *s; + unsigned long iobase = it->options[0]; + unsigned int irq = it->options[1]; + unsigned int dma0 = it->options[2]; + unsigned int dma1 = it->options[3]; + unsigned long iobase2; + int board; + int retval; - /* make dma buffer fill in 0.3 seconds for timed modes */ - switch (cmd->scan_begin_src) { - case TRIG_FOLLOW: /* not in burst mode */ - if (cmd->convert_src == TRIG_TIMER) - size = (fill_time / cmd->convert_arg) * sample_size; + /* allocate and initialize dev->private */ + if (alloc_private(dev, sizeof(struct das1800_private)) < 0) + return -ENOMEM; + + printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor, + dev->driver->driver_name, iobase); + if (irq) { + printk(KERN_CONT ", irq %u", irq); + if (dma0) { + printk(KERN_CONT ", dma %u", dma0); + if (dma1) + printk(KERN_CONT " and %u", dma1); + } + } + printk(KERN_CONT "\n"); + + if (iobase == 0) { + dev_err(dev->hw_dev, "io base address required\n"); + return -EINVAL; + } + + /* check if io addresses are available */ + if (!request_region(iobase, DAS1800_SIZE, dev->driver->driver_name)) { + printk + (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", + iobase, iobase + DAS1800_SIZE - 1); + return -EIO; + } + dev->iobase = iobase; + + board = das1800_probe(dev); + if (board < 0) { + dev_err(dev->hw_dev, "unable to determine board type\n"); + return -ENODEV; + } + + dev->board_ptr = das1800_boards + board; + dev->board_name = thisboard->name; + + /* if it is an 'ao' board with fancy analog out then we need extra io ports */ + if (thisboard->ao_ability == 2) { + iobase2 = iobase + IOBASE2; + if (!request_region(iobase2, DAS1800_SIZE, + dev->driver->driver_name)) { + printk + (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", + iobase2, iobase2 + DAS1800_SIZE - 1); + return -EIO; + } + devpriv->iobase2 = iobase2; + } + + /* grab our IRQ */ + if (irq) { + if (request_irq(irq, das1800_interrupt, 0, + dev->driver->driver_name, dev)) { + dev_dbg(dev->hw_dev, "unable to allocate irq %u\n", + irq); + return -EINVAL; + } + } + dev->irq = irq; + + /* set bits that tell card which irq to use */ + switch (irq) { + case 0: break; - case TRIG_TIMER: - size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * - sample_size; + case 3: + devpriv->irq_dma_bits |= 0x8; + break; + case 5: + devpriv->irq_dma_bits |= 0x10; + break; + case 7: + devpriv->irq_dma_bits |= 0x18; + break; + case 10: + devpriv->irq_dma_bits |= 0x28; + break; + case 11: + devpriv->irq_dma_bits |= 0x30; + break; + case 15: + devpriv->irq_dma_bits |= 0x38; break; default: - size = DMA_BUF_SIZE; + dev_err(dev->hw_dev, "irq out of range\n"); + return -EINVAL; break; } - /* set a minimum and maximum size allowed */ - max_size = DMA_BUF_SIZE; - /* if we are taking limited number of conversions, limit transfer size to that */ - if (cmd->stop_src == TRIG_COUNT && - cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) - max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; + retval = das1800_init_dma(dev, dma0, dma1); + if (retval < 0) + return retval; - if (size > max_size) - size = max_size; - if (size < sample_size) - size = sample_size; + if (devpriv->ai_buf0 == NULL) { + devpriv->ai_buf0 = + kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); + if (devpriv->ai_buf0 == NULL) + return -ENOMEM; + } - return size; -} + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + /* analog input subdevice */ + s = dev->subdevices + 0; + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; + if (thisboard->common) + s->subdev_flags |= SDF_COMMON; + s->n_chan = thisboard->qram_len; + s->len_chanlist = thisboard->qram_len; + s->maxdata = (1 << thisboard->resolution) - 1; + s->range_table = thisboard->range_ai; + s->do_cmd = das1800_ai_do_cmd; + s->do_cmdtest = das1800_ai_do_cmdtest; + s->insn_read = das1800_ai_rinsn; + s->poll = das1800_ai_poll; + s->cancel = das1800_cancel; + + /* analog out */ + s = dev->subdevices + 1; + if (thisboard->ao_ability == 1) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = thisboard->ao_n_chan; + s->maxdata = (1 << thisboard->resolution) - 1; + s->range_table = &range_ao_1; + s->insn_write = das1800_ao_winsn; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* di */ + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = das1800_di_rbits; + + /* do */ + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = thisboard->do_n_chan; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = das1800_do_wbits; + + das1800_cancel(dev, dev->read_subdev); + + /* initialize digital out channels */ + outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); + + /* initialize analog out channels */ + if (thisboard->ao_ability == 1) { + /* select 'update' dac channel for baseAddress + 0x0 */ + outb(DAC(thisboard->ao_n_chan - 1), + dev->iobase + DAS1800_SELECT); + outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); + } + + return 0; +}; + +static void das1800_detach(struct comedi_device *dev) +{ + if (dev->iobase) + release_region(dev->iobase, DAS1800_SIZE); + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->private) { + if (devpriv->iobase2) + release_region(devpriv->iobase2, DAS1800_SIZE); + if (devpriv->dma0) + free_dma(devpriv->dma0); + if (devpriv->dma1) + free_dma(devpriv->dma1); + kfree(devpriv->ai_buf0); + kfree(devpriv->ai_buf1); + } +}; static struct comedi_driver das1800_driver = { .driver_name = "das1800", -- GitLab From 4b5c0f106e7eb588e904184d9bc16427111c486f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:11 +0100 Subject: [PATCH 0371/6849] staging: comedi: das08: Use IS_ENABLED() Change conditional compilation on kernel config options to use the IS_ENABLED() macro. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 50 +++++++++++--------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index f53e59776a37..d921bee3bbc3 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -60,17 +60,7 @@ #define DRV_NAME "das08" -#ifdef CONFIG_COMEDI_DAS08_ISA_MODULE -#define CONFIG_COMEDI_DAS08_ISA -#endif -#ifdef CONFIG_COMEDI_DAS08_PCI_MODULE -#define CONFIG_COMEDI_DAS08_PCI -#endif -#ifdef CONFIG_COMEDI_DAS08_CS_MODULE -#define CONFIG_COMEDI_DAS08_CS -#endif - -#if defined(CONFIG_COMEDI_DAS08_ISA) || defined(CONFIG_COMEDI_DAS08_PCI) +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) || IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) #define DO_COMEDI_DRIVER_REGISTER #endif @@ -173,7 +163,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -#ifdef CONFIG_COMEDI_DAS08_ISA +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -270,7 +260,7 @@ static const int *const das08_gainlists[] = { #ifdef DO_COMEDI_DRIVER_REGISTER static const struct das08_board_struct das08_boards[] = { -#ifdef CONFIG_COMEDI_DAS08_ISA +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) { .name = "isa-das08", /* cio-das08.pdf */ .bustype = isa, @@ -460,8 +450,8 @@ static const struct das08_board_struct das08_boards[] = { .name = "das08-pga-g2", /* a KM board */ }, #endif -#endif /* CONFIG_COMEDI_DAS08_ISA */ -#ifdef CONFIG_COMEDI_DAS08_PCI +#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) */ +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) { .name = "das08", /* pci-das08 */ .id = PCI_DEVICE_ID_PCIDAS08, @@ -479,11 +469,11 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 4, .iosize = 8, }, -#endif /* CONFIG_COMEDI_DAS08_PCI */ +#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ }; #endif /* DO_COMEDI_DRIVER_REGISTER */ -#ifdef CONFIG_COMEDI_DAS08_CS +#if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { { .name = "pcm-das08", @@ -523,7 +513,7 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { }; #endif -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, {0} @@ -638,7 +628,7 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return 2; } -#ifdef CONFIG_COMEDI_DAS08_ISA +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -650,7 +640,7 @@ static int das08jr_di_rbits(struct comedi_device *dev, } #endif -#ifdef CONFIG_COMEDI_DAS08_ISA +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -667,7 +657,7 @@ static int das08jr_do_wbits(struct comedi_device *dev, } #endif -#ifdef CONFIG_COMEDI_DAS08_ISA +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -704,7 +694,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, * a different method to force an update. * */ -#ifdef CONFIG_COMEDI_DAS08_ISA +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1006,7 +996,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; unsigned long iobase; -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) unsigned long pci_iobase = 0; struct pci_dev *pdev = NULL; #endif @@ -1016,7 +1006,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; printk(KERN_INFO "comedi%d: das08: ", dev->minor); -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) /* deal with a pci board */ if (thisboard->bustype == pci) { if (it->options[0] || it->options[1]) { @@ -1068,7 +1058,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); #endif } else -#endif /* CONFIG_COMEDI_DAS08_PCI */ +#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ { iobase = it->options[0]; } @@ -1086,7 +1076,7 @@ void das08_common_detach(struct comedi_device *dev) if (dev->iobase) release_region(dev->iobase, thisboard->iosize); } -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) if (devpriv) { if (devpriv->pdev) { if (devpriv->pci_iobase) @@ -1099,7 +1089,7 @@ void das08_common_detach(struct comedi_device *dev) } EXPORT_SYMBOL_GPL(das08_common_detach); -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static int __devinit driver_das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -1127,7 +1117,7 @@ static int __init driver_das08_init_module(void) if (retval < 0) return retval; #endif -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) driver_das08_pci_driver.name = (char *)driver_das08.driver_name; retval = pci_register_driver(&driver_das08_pci_driver); #endif @@ -1136,7 +1126,7 @@ static int __init driver_das08_init_module(void) static void __exit driver_das08_cleanup_module(void) { -#ifdef CONFIG_COMEDI_DAS08_PCI +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) pci_unregister_driver(&driver_das08_pci_driver); #endif #ifdef DO_COMEDI_DRIVER_REGISTER @@ -1147,7 +1137,7 @@ static void __exit driver_das08_cleanup_module(void) module_init(driver_das08_init_module); module_exit(driver_das08_cleanup_module); -#ifdef CONFIG_COMEDI_DAS08_CS +#if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) EXPORT_SYMBOL_GPL(das08_cs_boards); #endif -- GitLab From d60d9f34d37775fa64695a22b405e58ac3cda39c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:12 +0100 Subject: [PATCH 0372/6849] staging: comedi: das08: Move I/O resource (de)allocation. Don't deal with allocation and deallocation of I/O resources and PCI enabling/disabling in the exported functions das08_common_attach() and das08_common_detach(). Do it in das08_attach() and new function das08_detach() (which is now the comedi detach() hook for this driver). This keeps things more symmetrical. Callers of das08_common_attach() and das08_common_detach() are now responsible for allocation of their own I/O resources and enabling of their own devices. The only external caller of das08_common_attach() and das08_common_detach() is the das08_cs module, which looks after its own I/O resources. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 57 ++++++++++++-------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index d921bee3bbc3..c69df87c5751 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -861,12 +861,13 @@ static int das08_counter_config(struct comedi_device *dev, #ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it); +static void das08_detach(struct comedi_device *dev); static struct comedi_driver driver_das08 = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, - .detach = das08_common_detach, + .detach = das08_detach, .board_name = &das08_boards[0].name, .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), .offset = sizeof(struct das08_board_struct), @@ -878,14 +879,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) struct comedi_subdevice *s; int ret; - /* allocate ioports for non-pcmcia, non-pci boards */ - if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) { - printk(KERN_INFO " iobase 0x%lx\n", iobase); - if (!request_region(iobase, thisboard->iosize, DRV_NAME)) { - printk(KERN_ERR " I/O port conflict\n"); - return -EIO; - } - } dev->iobase = iobase; dev->board_name = thisboard->name; @@ -996,19 +989,15 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; unsigned long iobase; -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - unsigned long pci_iobase = 0; - struct pci_dev *pdev = NULL; -#endif ret = alloc_private(dev, sizeof(struct das08_private_struct)); if (ret < 0) return ret; printk(KERN_INFO "comedi%d: das08: ", dev->minor); -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - /* deal with a pci board */ - if (thisboard->bustype == pci) { + if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { + unsigned long pci_iobase = 0; + struct pci_dev *pdev = NULL; if (it->options[0] || it->options[1]) { printk("bus %i slot %i ", it->options[0], it->options[1]); @@ -1057,13 +1046,16 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Enable local interrupt 1 and pci interrupt */ outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); #endif - } else -#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ - { + } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && + (thisboard->bustype == isa || thisboard->bustype == pc104)) { iobase = it->options[0]; - } - printk(KERN_INFO "\n"); - + printk(KERN_INFO " iobase 0x%lx\n", iobase); + if (!request_region(iobase, thisboard->iosize, DRV_NAME)) { + printk(KERN_ERR " I/O port conflict\n"); + return -EIO; + } + } else + return -EIO; return das08_common_attach(dev, iobase); } #endif /* DO_COMEDI_DRIVER_REGISTER */ @@ -1072,22 +1064,27 @@ void das08_common_detach(struct comedi_device *dev) { if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 4); - if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) { +} +EXPORT_SYMBOL_GPL(das08_common_detach); + +#ifdef DO_COMEDI_DRIVER_REGISTER +static void das08_detach(struct comedi_device *dev) +{ + das08_common_detach(dev); + if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && + (thisboard->bustype == isa || thisboard->bustype == pc104)) { if (dev->iobase) release_region(dev->iobase, thisboard->iosize); - } -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - if (devpriv) { - if (devpriv->pdev) { + } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && + thisboard->bustype == pci) { + if (devpriv && devpriv->pdev) { if (devpriv->pci_iobase) comedi_pci_disable(devpriv->pdev); - pci_dev_put(devpriv->pdev); } } -#endif } -EXPORT_SYMBOL_GPL(das08_common_detach); +#endif /* DO_COMEDI_DRIVER_REGISTER */ #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static int __devinit driver_das08_pci_probe(struct pci_dev *dev, -- GitLab From 1e576a5707c95a4fb5927d97ed21582a55f75a82 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:13 +0100 Subject: [PATCH 0373/6849] staging: comedi: das08: Use module_comedi_{pci_, }driver If PCI boards are supported, use the module_comedi_pci_driver() macro to register the module as a comedi driver and a PCI driver. Otherwise, if ISA (or PC/104) boards are supported, use the module_comedi_driver() macro to register the module as a comedi driver. Otherwise, this is only a helper module for an external comedi driver (das08_cs). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 46 +++++++++++--------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index c69df87c5751..3e0c02122270 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -863,7 +863,7 @@ static int das08_counter_config(struct comedi_device *dev, static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void das08_detach(struct comedi_device *dev); -static struct comedi_driver driver_das08 = { +static struct comedi_driver das08_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, @@ -1087,52 +1087,44 @@ static void das08_detach(struct comedi_device *dev) #endif /* DO_COMEDI_DRIVER_REGISTER */ #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) -static int __devinit driver_das08_pci_probe(struct pci_dev *dev, +static int __devinit das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_das08); + return comedi_pci_auto_config(dev, &das08_driver); } -static void __devexit driver_das08_pci_remove(struct pci_dev *dev) +static void __devexit das08_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_das08_pci_driver = { +static struct pci_driver das08_pci_driver = { .id_table = das08_pci_table, - .probe = &driver_das08_pci_probe, - .remove = __devexit_p(&driver_das08_pci_remove) + .name = DRV_NAME, + .probe = &das08_pci_probe, + .remove = __devexit_p(&das08_pci_remove) }; #endif /* CONFIG_COMEDI_DAS08_PCI */ -static int __init driver_das08_init_module(void) -{ - int retval = 0; - #ifdef DO_COMEDI_DRIVER_REGISTER - retval = comedi_driver_register(&driver_das08); - if (retval < 0) - return retval; -#endif #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - driver_das08_pci_driver.name = (char *)driver_das08.driver_name; - retval = pci_register_driver(&driver_das08_pci_driver); +module_comedi_pci_driver(das08_driver, das08_pci_driver); +#else +module_comedi_driver(das08_driver); #endif - return retval; +#else /* DO_COMEDI_DRIVER_REGISTER */ +static int __init das08_init(void) +{ + return 0; } -static void __exit driver_das08_cleanup_module(void) +static void __exit das08_exit(void) { -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - pci_unregister_driver(&driver_das08_pci_driver); -#endif -#ifdef DO_COMEDI_DRIVER_REGISTER - comedi_driver_unregister(&driver_das08); -#endif } -module_init(driver_das08_init_module); -module_exit(driver_das08_cleanup_module); +module_init(das08_init); +module_exit(das08_exit); +#endif /* DO_COMEDI_DRIVER_REGISTER */ #if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) EXPORT_SYMBOL_GPL(das08_cs_boards); -- GitLab From d8fdaea5c9cd422f87cf0257c191e030a54d71e2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:14 +0100 Subject: [PATCH 0374/6849] staging: comedi: das08: Remove forward function declarations. Moved some functions to avoid forward declarations. Moved a few other bits at the same time to keep EXPORT_SYMBOL{,_GPL}() close to the symbol being exported, and PCI table close to the code that refers to it. Changed whitespace in das08_board[] and das08_cs_board[] initializers. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 585 ++++++++++++------------- 1 file changed, 277 insertions(+), 308 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 3e0c02122270..901411e616d3 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -157,29 +157,6 @@ /* gainlist same as _pgx_ below */ -static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) -static int das08jr_di_rbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das08jr_do_wbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das08jr_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das08ao_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -#endif -static void i8254_set_mode_low(unsigned int base, int channel, - unsigned int mode); - static const struct comedi_lrange range_das08_pgl = { 9, { BIP_RANGE(10), BIP_RANGE(5), @@ -258,270 +235,6 @@ static const int *const das08_gainlists[] = { das08_pgm_gainlist, }; -#ifdef DO_COMEDI_DRIVER_REGISTER -static const struct das08_board_struct das08_boards[] = { -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) - { - .name = "isa-das08", /* cio-das08.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pg_none, - .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 12, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 8, - .i8254_offset = 4, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08-pgm", /* cio-das08pgx.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pgm, - .ai_encoding = das08_encode12, - .ao = NULL, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08-pgh", /* cio-das08pgx.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pgh, - .ai_encoding = das08_encode12, - .ao = NULL, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08-pgl", /* cio-das08pgx.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pgl, - .ai_encoding = das08_encode12, - .ao = NULL, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08-aoh", /* cio-das08_aox.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pgh, - .ai_encoding = das08_encode12, - .ao = das08ao_ao_winsn, /* 8 */ - .ao_nbits = 12, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0x0c, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08-aol", /* cio-das08_aox.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pgl, - .ai_encoding = das08_encode12, - .ao = das08ao_ao_winsn, /* 8 */ - .ao_nbits = 12, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0x0c, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08-aom", /* cio-das08_aox.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pgm, - .ai_encoding = das08_encode12, - .ao = das08ao_ao_winsn, /* 8 */ - .ao_nbits = 12, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0x0c, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08/jr-ao", /* cio-das08-jr-ao.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pg_none, - .ai_encoding = das08_encode12, - .ao = das08jr_ao_winsn, - .ao_nbits = 12, - .di = das08jr_di_rbits, - .do_ = das08jr_do_wbits, - .do_nchan = 8, - .i8255_offset = 0, - .i8254_offset = 0, - .iosize = 16, /* unchecked */ - }, - { - .name = "das08jr-16-ao", /* cio-das08jr-16-ao.pdf */ - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 16, - .ai_pg = das08_pg_none, - .ai_encoding = das08_encode12, - .ao = das08jr_ao_winsn, - .ao_nbits = 16, - .di = das08jr_di_rbits, - .do_ = das08jr_do_wbits, - .do_nchan = 8, - .i8255_offset = 0, - .i8254_offset = 0x04, - .iosize = 16, /* unchecked */ - }, - { - .name = "pc104-das08", - .bustype = pc104, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_pg_none, - .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 4, - .iosize = 16, /* unchecked */ - }, -#if 0 - { - .name = "das08/f", - }, - { - .name = "das08jr", - }, -#endif - { - .name = "das08jr/16", - .bustype = isa, - .ai = das08_ai_rinsn, - .ai_nbits = 16, - .ai_pg = das08_pg_none, - .ai_encoding = das08_encode16, - .ao = NULL, - .ao_nbits = 0, - .di = das08jr_di_rbits, - .do_ = das08jr_do_wbits, - .do_nchan = 8, - .i8255_offset = 0, - .i8254_offset = 0, - .iosize = 16, /* unchecked */ - }, -#if 0 - { - .name = "das48-pga", /* cio-das48-pga.pdf */ - }, - { - .name = "das08-pga-g2", /* a KM board */ - }, -#endif -#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) */ -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - { - .name = "das08", /* pci-das08 */ - .id = PCI_DEVICE_ID_PCIDAS08, - .bustype = pci, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 4, - .iosize = 8, - }, -#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ -}; -#endif /* DO_COMEDI_DRIVER_REGISTER */ - -#if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) -struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { - { - .name = "pcm-das08", - .id = 0x0, /* XXX */ - .bustype = pcmcia, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_pcm_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 3, - .i8255_offset = 0, - .i8254_offset = 0, - .iosize = 16, - }, - /* duplicate so driver name can be used also */ - { - .name = "das08_cs", - .id = 0x0, /* XXX */ - .bustype = pcmcia, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_pcm_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 3, - .i8255_offset = 0, - .i8254_offset = 0, - .iosize = 16, - }, -}; -#endif - -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) -static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, das08_pci_table); -#endif - #define devpriv ((struct das08_private_struct *)dev->private) #define thisboard ((const struct das08_board_struct *)dev->board_ptr) @@ -776,13 +489,6 @@ static void i8254_write_channel(struct i8254_struct *st, int channel, i8254_write_channel_low(st->iobase, chan, value); } -static void i8254_initialize(struct i8254_struct *st) -{ - int i; - for (i = 0; i < 3; ++i) - i8254_set_mode_low(st->iobase, i, st->mode[i]); -} - static void i8254_set_mode_low(unsigned int base, int channel, unsigned int mode) { @@ -811,6 +517,13 @@ static unsigned int i8254_read_status(struct i8254_struct *st, int channel) return i8254_read_status_low(st->iobase, chan); } +static void i8254_initialize(struct i8254_struct *st) +{ + int i; + for (i = 0; i < 3; ++i) + i8254_set_mode_low(st->iobase, i, st->mode[i]); +} + static int das08_counter_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -860,18 +573,259 @@ static int das08_counter_config(struct comedi_device *dev, } #ifdef DO_COMEDI_DRIVER_REGISTER -static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void das08_detach(struct comedi_device *dev); +static const struct das08_board_struct das08_boards[] = { +#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) + { + .name = "isa-das08", /* cio-das08.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pg_none, + .ai_encoding = das08_encode12, + .ao = NULL, + .ao_nbits = 12, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 8, + .i8254_offset = 4, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08-pgm", /* cio-das08pgx.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pgm, + .ai_encoding = das08_encode12, + .ao = NULL, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08-pgh", /* cio-das08pgx.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pgh, + .ai_encoding = das08_encode12, + .ao = NULL, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08-pgl", /* cio-das08pgx.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pgl, + .ai_encoding = das08_encode12, + .ao = NULL, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08-aoh", /* cio-das08_aox.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pgh, + .ai_encoding = das08_encode12, + .ao = das08ao_ao_winsn, /* 8 */ + .ao_nbits = 12, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0x0c, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08-aol", /* cio-das08_aox.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pgl, + .ai_encoding = das08_encode12, + .ao = das08ao_ao_winsn, /* 8 */ + .ao_nbits = 12, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0x0c, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08-aom", /* cio-das08_aox.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pgm, + .ai_encoding = das08_encode12, + .ao = das08ao_ao_winsn, /* 8 */ + .ao_nbits = 12, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0x0c, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08/jr-ao", /* cio-das08-jr-ao.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pg_none, + .ai_encoding = das08_encode12, + .ao = das08jr_ao_winsn, + .ao_nbits = 12, + .di = das08jr_di_rbits, + .do_ = das08jr_do_wbits, + .do_nchan = 8, + .i8255_offset = 0, + .i8254_offset = 0, + .iosize = 16, /* unchecked */ + }, + { + .name = "das08jr-16-ao", /* cio-das08jr-16-ao.pdf */ + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 16, + .ai_pg = das08_pg_none, + .ai_encoding = das08_encode12, + .ao = das08jr_ao_winsn, + .ao_nbits = 16, + .di = das08jr_di_rbits, + .do_ = das08jr_do_wbits, + .do_nchan = 8, + .i8255_offset = 0, + .i8254_offset = 0x04, + .iosize = 16, /* unchecked */ + }, + { + .name = "pc104-das08", + .bustype = pc104, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_pg_none, + .ai_encoding = das08_encode12, + .ao = NULL, + .ao_nbits = 0, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 4, + .iosize = 16, /* unchecked */ + }, +#if 0 + { + .name = "das08/f", + }, + { + .name = "das08jr", + }, +#endif + { + .name = "das08jr/16", + .bustype = isa, + .ai = das08_ai_rinsn, + .ai_nbits = 16, + .ai_pg = das08_pg_none, + .ai_encoding = das08_encode16, + .ao = NULL, + .ao_nbits = 0, + .di = das08jr_di_rbits, + .do_ = das08jr_do_wbits, + .do_nchan = 8, + .i8255_offset = 0, + .i8254_offset = 0, + .iosize = 16, /* unchecked */ + }, +#if 0 + { + .name = "das48-pga", /* cio-das48-pga.pdf */ + }, + { + .name = "das08-pga-g2", /* a KM board */ + }, +#endif +#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) */ +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) + { + .name = "das08", /* pci-das08 */ + .id = PCI_DEVICE_ID_PCIDAS08, + .bustype = pci, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_encode12, + .ao = NULL, + .ao_nbits = 0, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 4, + .iosize = 8, + }, +#endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ +}; +#endif /* DO_COMEDI_DRIVER_REGISTER */ -static struct comedi_driver das08_driver = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = das08_attach, - .detach = das08_detach, - .board_name = &das08_boards[0].name, - .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), - .offset = sizeof(struct das08_board_struct), +#if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) +struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { + { + .name = "pcm-das08", + .id = 0x0, /* XXX */ + .bustype = pcmcia, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_pcm_encode12, + .ao = NULL, + .ao_nbits = 0, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 3, + .i8255_offset = 0, + .i8254_offset = 0, + .iosize = 16, + }, + /* duplicate so driver name can be used also */ + { + .name = "das08_cs", + .id = 0x0, /* XXX */ + .bustype = pcmcia, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_pcm_encode12, + .ao = NULL, + .ao_nbits = 0, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 3, + .i8255_offset = 0, + .i8254_offset = 0, + .iosize = 16, + }, }; +EXPORT_SYMBOL_GPL(das08_cs_boards); #endif int das08_common_attach(struct comedi_device *dev, unsigned long iobase) @@ -1086,7 +1040,26 @@ static void das08_detach(struct comedi_device *dev) } #endif /* DO_COMEDI_DRIVER_REGISTER */ +#ifdef DO_COMEDI_DRIVER_REGISTER +static struct comedi_driver das08_driver = { + .driver_name = DRV_NAME, + .module = THIS_MODULE, + .attach = das08_attach, + .detach = das08_detach, + .board_name = &das08_boards[0].name, + .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), + .offset = sizeof(struct das08_board_struct), +}; +#endif + #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, + {0} +}; + +MODULE_DEVICE_TABLE(pci, das08_pci_table); + static int __devinit das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -1126,10 +1099,6 @@ module_init(das08_init); module_exit(das08_exit); #endif /* DO_COMEDI_DRIVER_REGISTER */ -#if IS_ENABLED(CONFIG_COMEDI_DAS08_CS) -EXPORT_SYMBOL_GPL(das08_cs_boards); -#endif - MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- GitLab From 33fba3b7841b0cf7565e4352a2bab69fc5f4288f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:15 +0100 Subject: [PATCH 0375/6849] staging: comedi: das08: Replace printk calls Replace the printk calls with dev_info, dev_err, etc. Some of the printk strings were missing newlines on the end. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 30 ++++++++++---------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 901411e616d3..680384c8e099 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -274,7 +274,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* clear over-range bits for 16-bit boards */ if (thisboard->ai_nbits == 16) if (inb(dev->iobase + DAS08_MSB) & 0x80) - printk(KERN_INFO "das08: over-range\n"); + dev_info(dev->class_dev, "over-range\n"); /* trigger conversion */ outb_p(0, dev->iobase + DAS08_TRIG_12BIT); @@ -284,7 +284,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, break; } if (i == TIMEOUT) { - printk(KERN_ERR "das08: timeout\n"); + dev_err(dev->class_dev, "timeout\n"); return -ETIME; } msb = inb(dev->iobase + DAS08_MSB); @@ -529,11 +529,7 @@ static int das08_counter_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { int chan = insn->chanspec; - - /* printk("Reading counter channel %d ",chan); */ data[0] = i8254_read_channel(&devpriv->i8254, chan); - /* printk("=> 0x%08X\n",data[0]); */ - return 1; } @@ -542,10 +538,7 @@ static int das08_counter_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { int chan = insn->chanspec; - - /* printk("Writing counter channel %d with 0x%04X\n",chan,data[0]); */ i8254_write_channel(&devpriv->i8254, chan, data[0]); - return 1; } @@ -948,15 +941,14 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - printk(KERN_INFO "comedi%d: das08: ", dev->minor); + dev_info(dev->class_dev, "attach\n"); if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { unsigned long pci_iobase = 0; struct pci_dev *pdev = NULL; if (it->options[0] || it->options[1]) { - printk("bus %i slot %i ", + dev_info(dev->class_dev, "pci bus %i slot %i\n", it->options[0], it->options[1]); } - printk("\n"); /* find card */ for_each_pci_dev(pdev) { if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS @@ -973,21 +965,21 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } if (!pdev) { - printk(KERN_ERR "No pci das08 cards found\n"); + dev_err(dev->class_dev, "No pci das08 cards found\n"); return -EIO; } devpriv->pdev = pdev; /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, DRV_NAME)) { - printk(KERN_ERR " Error enabling PCI device and " - "requesting regions\n"); + dev_err(dev->class_dev, + "Error enabling PCI device and requesting regions\n"); return -EIO; } /* read base addresses */ pci_iobase = pci_resource_start(pdev, 1); iobase = pci_resource_start(pdev, 2); - printk(KERN_INFO "pcibase 0x%lx iobase 0x%lx\n", - pci_iobase, iobase); + dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", + pci_iobase, iobase); devpriv->pci_iobase = pci_iobase; #if 0 /* We could enable to pci-das08's interrupt here to make it possible @@ -1003,9 +995,9 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && (thisboard->bustype == isa || thisboard->bustype == pc104)) { iobase = it->options[0]; - printk(KERN_INFO " iobase 0x%lx\n", iobase); + dev_info(dev->class_dev, "iobase 0x%lx\n", iobase); if (!request_region(iobase, thisboard->iosize, DRV_NAME)) { - printk(KERN_ERR " I/O port conflict\n"); + dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } } else -- GitLab From 282f3528e21cd35f85e8ea3cb7dbcd285a6e5379 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:16 +0100 Subject: [PATCH 0376/6849] staging: comedi: das08: Remove thisboard and devpriv macros The 'thisboard' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macros with local variables wherever they occur. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 680384c8e099..8ebb56d9682e 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -235,14 +235,13 @@ static const int *const das08_gainlists[] = { das08_pgm_gainlist, }; -#define devpriv ((struct das08_private_struct *)dev->private) -#define thisboard ((const struct das08_board_struct *)dev->board_ptr) - #define TIMEOUT 100000 static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv = dev->private; int i, n; int chan; int range; @@ -320,6 +319,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das08_private_struct *devpriv = dev->private; int wbits; /* get current settings of digital output lines */ @@ -358,6 +358,8 @@ static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das08_private_struct *devpriv = dev->private; + /* null bits we are going to set */ devpriv->do_bits &= ~data[0]; /* set new bit values */ @@ -528,6 +530,7 @@ static int das08_counter_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das08_private_struct *devpriv = dev->private; int chan = insn->chanspec; data[0] = i8254_read_channel(&devpriv->i8254, chan); return 1; @@ -537,6 +540,7 @@ static int das08_counter_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das08_private_struct *devpriv = dev->private; int chan = insn->chanspec; i8254_write_channel(&devpriv->i8254, chan, data[0]); return 1; @@ -546,6 +550,7 @@ static int das08_counter_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das08_private_struct *devpriv = dev->private; int chan = insn->chanspec; if (insn->n != 2) @@ -823,6 +828,8 @@ EXPORT_SYMBOL_GPL(das08_cs_boards); int das08_common_attach(struct comedi_device *dev, unsigned long iobase) { + const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv = dev->private; struct comedi_subdevice *s; int ret; @@ -934,12 +941,15 @@ EXPORT_SYMBOL_GPL(das08_common_attach); #ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv; int ret; unsigned long iobase; ret = alloc_private(dev, sizeof(struct das08_private_struct)); if (ret < 0) return ret; + devpriv = dev->private; dev_info(dev->class_dev, "attach\n"); if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { @@ -1016,6 +1026,9 @@ EXPORT_SYMBOL_GPL(das08_common_detach); #ifdef DO_COMEDI_DRIVER_REGISTER static void das08_detach(struct comedi_device *dev) { + const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv = dev->private; + das08_common_detach(dev); if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && (thisboard->bustype == isa || thisboard->bustype == pc104)) { -- GitLab From f86b0d7da3ab15f73723d98f6685d6d8ef48c166 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:17 +0100 Subject: [PATCH 0377/6849] staging: comedi: das08: Support multiple PCI card types in future Rename the existing board entry named "das08" for the PCI-DAS08 board to "pci-das08". Add a new wildcard board entry called "das08" that will match any supported PCI board. If 'dev->board_ptr' points to the wildcard board entry in the ->attach() routine, it will be replaced with a supported PCI board entry if there are any (taking into account the bus and slot specified by the device config options passed in to the function). Split the code that finds a matching PCI device into a new function das08_find_pci(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 96 +++++++++++++++++++------- 1 file changed, 71 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 8ebb56d9682e..7324461e3f27 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -32,7 +32,7 @@ * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm), * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh), * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao), - * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08), + * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (pci-das08 or das08), * PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16) * Status: works * @@ -765,7 +765,7 @@ static const struct das08_board_struct das08_boards[] = { #endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) */ #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) { - .name = "das08", /* pci-das08 */ + .name = "pci-das08", /* pci-das08 */ .id = PCI_DEVICE_ID_PCIDAS08, .bustype = pci, .ai = das08_ai_rinsn, @@ -781,6 +781,11 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 4, .iosize = 8, }, + { /* wildcard entry matches any supported PCI device */ + .name = DRV_NAME, + .id = PCI_ANY_ID, + .bustype = pci, + }, #endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ }; #endif /* DO_COMEDI_DRIVER_REGISTER */ @@ -938,6 +943,66 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) } EXPORT_SYMBOL_GPL(das08_common_attach); +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +static struct pci_dev *das08_find_pci(struct comedi_device *dev, + int bus, int slot) +{ + const struct das08_board_struct *thisboard = comedi_board(dev); + struct pci_dev *pdev; + unsigned int matchid; + + if (bus || slot) + dev_dbg(dev->class_dev, "Looking for %s at PCI %02X:%02X\n", + thisboard->name, bus, slot); + else + dev_dbg(dev->class_dev, "Looking for %s on PCI buses\n", + thisboard->name); + + matchid = thisboard->id; + pdev = NULL; + for_each_pci_dev(pdev) { + if ((bus || slot) && + (bus != pdev->bus->number || slot != PCI_SLOT(pdev->devfn))) + continue; + if (pdev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) + continue; + if (matchid == PCI_ANY_ID) { + /* wildcard board matches any supported PCI board */ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(das08_boards); i++) { + if (das08_boards[i].bustype != pci) + continue; + if (pdev->device == das08_boards[i].id) { + /* replace wildcard board_ptr */ + dev->board_ptr = &das08_boards[i]; + thisboard = comedi_board(dev); + break; + } + } + if (i == ARRAY_SIZE(das08_boards)) + continue; + } else { + /* match specific PCI board */ + if (pdev->device != matchid) + continue; + } + /* found a match */ + dev_info(dev->class_dev, "Found %s at PCI %s\n", + thisboard->name, pci_name(pdev)); + return pdev; + } + /* no match found */ + if (bus || slot) + dev_err(dev->class_dev, + "No %s cards found at PCI %02X:%02X\n", + thisboard->name, bus, slot); + else + dev_err(dev->class_dev, "No %s cards found on PCI buses\n", + thisboard->name); + return NULL; +} +#endif + #ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -954,30 +1019,11 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, "attach\n"); if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { unsigned long pci_iobase = 0; - struct pci_dev *pdev = NULL; - if (it->options[0] || it->options[1]) { - dev_info(dev->class_dev, "pci bus %i slot %i\n", - it->options[0], it->options[1]); - } - /* find card */ - for_each_pci_dev(pdev) { - if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS - && pdev->device == PCI_DEVICE_ID_PCIDAS08) { - if (it->options[0] || it->options[1]) { - if (pdev->bus->number == it->options[0] - && PCI_SLOT(pdev->devfn) == - it->options[1]) { - break; - } - } else { - break; - } - } - } - if (!pdev) { - dev_err(dev->class_dev, "No pci das08 cards found\n"); + struct pci_dev *pdev; + pdev = das08_find_pci(dev, it->options[0], it->options[1]); + if (pdev == NULL) return -EIO; - } + thisboard = comedi_board(dev); /* replaced wildcard board */ devpriv->pdev = pdev; /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, DRV_NAME)) { -- GitLab From 8b7d417c406bafacedeae6cc3e110b11640d14e5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 24 May 2012 17:27:18 +0100 Subject: [PATCH 0378/6849] staging: comedi: das08: Add attach_pci() hook Implement the attach_pci() hook. This is called by comedi_pci_auto_config() in preference to the old attach() hook and avoids searching for the probed PCI device. Factor out some common code used by both the attach() and attach_pci() hooks into a couple of new functions, das08_pci_attach_common() and das08_find_pci_board(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 118 +++++++++++++++++-------- 1 file changed, 79 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 7324461e3f27..fa2784d65569 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -943,6 +943,75 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) } EXPORT_SYMBOL_GPL(das08_common_attach); +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +static int das08_pci_attach_common(struct comedi_device *dev, + struct pci_dev *pdev) +{ + unsigned long iobase; + unsigned long pci_iobase; + struct das08_private_struct *devpriv = dev->private; + + devpriv->pdev = pdev; + /* enable PCI device and reserve I/O spaces */ + if (comedi_pci_enable(pdev, dev->driver->driver_name)) { + dev_err(dev->class_dev, + "Error enabling PCI device and requesting regions\n"); + return -EIO; + } + /* read base addresses */ + pci_iobase = pci_resource_start(pdev, 1); + iobase = pci_resource_start(pdev, 2); + dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", + pci_iobase, iobase); + devpriv->pci_iobase = pci_iobase; +#if 0 + /* We could enable pci-das08's interrupt here to make it possible + * to do timed input in this driver, but there is little point since + * conversions would have to be started by the interrupt handler + * so you might as well use comedi_rt_timer to emulate commands + */ + /* set source of interrupt trigger to counter2 output */ + outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL); + /* Enable local interrupt 1 and pci interrupt */ + outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); +#endif + return das08_common_attach(dev, iobase); +} +#endif + +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +static const struct das08_board_struct * +das08_find_pci_board(struct pci_dev *pdev) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(das08_boards); i++) + if (das08_boards[i].bustype == pci && + pdev->device == das08_boards[i].id) + return &das08_boards[i]; + return NULL; +} +#endif + +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +/* only called in the PCI probe path, via comedi_pci_auto_config() */ +static int __devinit das08_attach_pci(struct comedi_device *dev, + struct pci_dev *pdev) +{ + int ret; + + ret = alloc_private(dev, sizeof(struct das08_private_struct)); + if (ret < 0) + return ret; + dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev)); + dev->board_ptr = das08_find_pci_board(pdev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + return das08_pci_attach_common(dev, pdev); +} +#endif + #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static struct pci_dev *das08_find_pci(struct comedi_device *dev, int bus, int slot) @@ -968,19 +1037,12 @@ static struct pci_dev *das08_find_pci(struct comedi_device *dev, continue; if (matchid == PCI_ANY_ID) { /* wildcard board matches any supported PCI board */ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(das08_boards); i++) { - if (das08_boards[i].bustype != pci) - continue; - if (pdev->device == das08_boards[i].id) { - /* replace wildcard board_ptr */ - dev->board_ptr = &das08_boards[i]; - thisboard = comedi_board(dev); - break; - } - } - if (i == ARRAY_SIZE(das08_boards)) + const struct das08_board_struct *foundboard; + foundboard = das08_find_pci_board(pdev); + if (foundboard == NULL) continue; + /* replace wildcard board_ptr */ + dev->board_ptr = thisboard = foundboard; } else { /* match specific PCI board */ if (pdev->device != matchid) @@ -1018,36 +1080,11 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, "attach\n"); if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) { - unsigned long pci_iobase = 0; struct pci_dev *pdev; pdev = das08_find_pci(dev, it->options[0], it->options[1]); if (pdev == NULL) return -EIO; - thisboard = comedi_board(dev); /* replaced wildcard board */ - devpriv->pdev = pdev; - /* enable PCI device and reserve I/O spaces */ - if (comedi_pci_enable(pdev, DRV_NAME)) { - dev_err(dev->class_dev, - "Error enabling PCI device and requesting regions\n"); - return -EIO; - } - /* read base addresses */ - pci_iobase = pci_resource_start(pdev, 1); - iobase = pci_resource_start(pdev, 2); - dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", - pci_iobase, iobase); - devpriv->pci_iobase = pci_iobase; -#if 0 -/* We could enable to pci-das08's interrupt here to make it possible - * to do timed input in this driver, but there is little point since - * conversions would have to be started by the interrupt handler - * so you might as well use comedi_rt_timer to emulate commands - */ - /* set source of interrupt trigger to counter2 output */ - outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL); - /* Enable local interrupt 1 and pci interrupt */ - outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); -#endif + return das08_pci_attach_common(dev, pdev); } else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && (thisboard->bustype == isa || thisboard->bustype == pc104)) { iobase = it->options[0]; @@ -1056,9 +1093,9 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } + return das08_common_attach(dev, iobase); } else return -EIO; - return das08_common_attach(dev, iobase); } #endif /* DO_COMEDI_DRIVER_REGISTER */ @@ -1096,6 +1133,9 @@ static struct comedi_driver das08_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) + .attach_pci = das08_attach_pci, +#endif .detach = das08_detach, .board_name = &das08_boards[0].name, .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), -- GitLab From bc04bec0e0c982dfc90e206ea51f19bd650ccee2 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 27 May 2012 01:45:19 +0900 Subject: [PATCH 0379/6849] staging: comedi: Fix typo in comedi Correct spelling typo in comments within staging/comedi. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 4 ++-- drivers/staging/comedi/drivers/das800.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 +- drivers/staging/comedi/drivers/gsc_hpdi.c | 2 +- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/usbduxsigma.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index f2135bfca290..3670ebdbcd81 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -299,7 +299,7 @@ struct pci9118_private { short *ai_data; short ao_data[2]; /* data output buffer */ unsigned int ai_scans; /* number of scans to do */ - char dma_doublebuf; /* we can use double buffring */ + char dma_doublebuf; /* we can use double buffering */ unsigned int dma_actbuf; /* which buffer is used now */ short *dmabuf_virt[2]; /* * pointers to begin of diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 7f88d08ee579..074feeef829b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -57,8 +57,8 @@ range and aref. AI Triggering: For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used. For 1602 series, the start_arg is interpreted as follows: - start_arg == 0 => gated triger (level high) - start_arg == CR_INVERT => gated triger (level low) + start_arg == 0 => gated trigger (level high) + start_arg == CR_INVERT => gated trigger (level low) start_arg == CR_EDGE => Rising edge start_arg == CR_EDGE | CR_INVERT => Falling edge For the other boards the trigger will be done on rising edge diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index a3a54e1c5c98..4e33b2a28d97 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -450,7 +450,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) /* otherwise, stop taking data */ } else { spin_unlock_irqrestore(&dev->spinlock, irq_flags); - disable_das800(dev); /* diable hardware triggered conversions */ + disable_das800(dev); /* disable hardware triggered conversions */ async->events |= COMEDI_CB_EOA; } comedi_event(dev, s); diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 9586f24ded73..367a7c88a0fd 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -141,7 +141,7 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, for (counter = 0; counter < READ_TIMEOUT; counter++) { d = inw_p(devpriv->BADR2); - /* check if read is successfull if the EOC bit is set */ + /* check if read is successful if the EOC bit is set */ if (d & (1 << 15)) goto conv_finish; } diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index eeb05553e1a7..fe1fd2f75f0d 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -631,7 +631,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_WARNING " irq %u\n", dev->irq); - /* alocate pci dma buffers */ + /* allocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { priv(dev)->dio_buffer[i] = pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE, diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index f870d3da0324..1f254f480a66 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -835,7 +835,7 @@ static int icp_multi_attach(struct comedi_device *dev, printk(KERN_WARNING "icp_multi EDBG: BGN: icp_multi_attach(...)\n"); - /* Alocate private data storage space */ + /* Allocate private data storage space */ ret = alloc_private(dev, sizeof(struct icp_multi_private)); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 465afbdf4069..441ccef4c110 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1358,7 +1358,7 @@ static int usbdux_ai_insn_read(struct comedi_device *dev, /* 32 bits big endian from the A/D converter */ one = be32_to_cpu(*((int32_t *) ((this_usbduxsub->insnBuffer)+1))); - /* mask out the staus byte */ + /* mask out the status byte */ one = one & 0x00ffffff; /* turn it into an unsigned integer */ one = one ^ 0x00800000; -- GitLab From 856ff77e3307eb89ba68e7cc3c1fa91112efff89 Mon Sep 17 00:00:00 2001 From: Dimitrios Semitsoglou-Tsiapos Date: Tue, 29 May 2012 00:51:44 +0300 Subject: [PATCH 0380/6849] staging: comedi: cb_pcidas64: Fixed coding style errors Fixed a few coding style errors in cb_pcidas64. Signed-off-by: Dimitrios Semitsoglou-Tsiapos Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 1e30f227e98e..5bcadcb00c99 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1152,7 +1152,7 @@ static int eeprom_read_insn(struct comedi_device *dev, static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); static unsigned int get_divisor(unsigned int ns, unsigned int flags); static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t * data, unsigned int length); + const uint8_t *data, unsigned int length); static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value); static int caldac_8800_write(struct comedi_device *dev, unsigned int address, @@ -1229,7 +1229,7 @@ static unsigned int hw_revision(const struct comedi_device *dev, } static void set_dac_range_bits(struct comedi_device *dev, - volatile uint16_t * bits, unsigned int channel, + volatile uint16_t *bits, unsigned int channel, unsigned int range) { unsigned int code = board(dev)->ao_range_code[range]; @@ -4190,7 +4190,7 @@ static void i2c_stop(struct comedi_device *dev) } static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t * data, unsigned int length) + const uint8_t *data, unsigned int length) { unsigned int i; uint8_t bitstream; -- GitLab From 5b28e55eb15f88920cd509332a22f80d72d55284 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 29 May 2012 15:30:18 -0700 Subject: [PATCH 0381/6849] staging: comedi: Make COMEDI_FC a hidden Kconfig option The COMEDI_FC Kconfig option is selected by the relevant drivers when needed. Since it only contains shared functions, selecting it manually serves no purpose. Just make it a hidden selection. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 3bbe3fd103f3..54e32da55c7c 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1305,15 +1305,8 @@ config COMEDI_8255 called 8255. config COMEDI_FC - tristate "Comedi shared functions for low-level driver support" + tristate depends on COMEDI - ---help--- - Enable support for shared functions for low-level drivers. - This module is not used directly by end-users. Rather, it - is used by many other comedi drivers. - - To compile this driver as a module, choose M here: the module will be - called comedi_fc. config COMEDI_AMPLC_DIO200 tristate -- GitLab From 1364b02fbf6e2d298ff2428ace81f9c6517b4bd8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 31 May 2012 13:56:28 -0700 Subject: [PATCH 0382/6849] staging: comedi: drivers.c: remove unused inline functions Remove the inline functions uvirt_to_kva and kvirt_to_kva, they are not referenced by any of the drivers.c code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 33 -------------------------------- 1 file changed, 33 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 438c52a313b1..9d2b206251ac 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -383,39 +383,6 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, return 1; } -static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) -{ - unsigned long ret = 0UL; - pmd_t *pmd; - pte_t *ptep, pte; - pud_t *pud; - - if (!pgd_none(*pgd)) { - pud = pud_offset(pgd, adr); - pmd = pmd_offset(pud, adr); - if (!pmd_none(*pmd)) { - ptep = pte_offset_kernel(pmd, adr); - pte = *ptep; - if (pte_present(pte)) { - ret = (unsigned long) - page_address(pte_page(pte)); - ret |= (adr & (PAGE_SIZE - 1)); - } - } - } - return ret; -} - -static inline unsigned long kvirt_to_kva(unsigned long adr) -{ - unsigned long va, kva; - - va = adr; - kva = uvirt_to_kva(pgd_offset_k(va), va); - - return kva; -} - int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { -- GitLab From 1bb6dfc407b7c29d22dc9b5d21db86f50653b46e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:28 +0100 Subject: [PATCH 0383/6849] staging: comedi: amplc_pc236: Use IS_ENABLED() Change conditional compilation on kernel config options to use the IS_ENABLED() macro. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 48 ++++++++------------ 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 6cb06ec1b30d..5f1caacbce13 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -61,14 +61,6 @@ unused. #define PC236_DRIVER_NAME "amplc_pc236" -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA_MODULE -#define CONFIG_COMEDI_AMPLC_PC236_ISA -#endif - -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI_MODULE -#define CONFIG_COMEDI_AMPLC_PC236_PCI -#endif - /* PCI236 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 @@ -112,7 +104,7 @@ struct pc236_board { enum pc236_model model; }; static const struct pc236_board pc236_boards[] = { -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) { .name = "pc36at", .fancy_name = "PC36AT", @@ -120,7 +112,7 @@ static const struct pc236_board pc236_boards[] = { .model = pc36at_model, }, #endif -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) { .name = "pci236", .fancy_name = "PCI236", @@ -138,7 +130,7 @@ static const struct pc236_board pc236_boards[] = { #endif }; -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, {0} @@ -157,7 +149,7 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table); feel free to suggest moving the variable to the struct comedi_device struct. */ struct pc236_private { -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) /* PCI device */ struct pci_dev *pci_dev; unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ @@ -185,7 +177,7 @@ static struct comedi_driver driver_amplc_pc236 = { .num_names = ARRAY_SIZE(pc236_boards), }; -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -240,7 +232,7 @@ module_init(driver_amplc_pc236_init_module); module_exit(driver_amplc_pc236_cleanup_module); #endif -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) static int pc236_request_region(unsigned minor, unsigned long from, unsigned long extent); #endif @@ -263,7 +255,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d); * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) static int pc236_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -332,7 +324,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -353,14 +345,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Process options. */ switch (thisboard->bustype) { -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) case isa_bustype: iobase = it->options[0]; irq = it->options[1]; share_irq = 0; break; #endif -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -386,7 +378,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) if (pci_dev) { ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); @@ -402,7 +394,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); if (ret < 0) return ret; @@ -452,12 +444,12 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); switch (thisboard->bustype) { -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) case isa_bustype: printk("(base %#lx) ", iobase); break; #endif -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) case pci_bustype: printk("(pci %s) ", pci_name(pci_dev)); break; @@ -484,7 +476,7 @@ static void pc236_detach(struct comedi_device *dev) if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); if (devpriv) { -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -492,7 +484,7 @@ static void pc236_detach(struct comedi_device *dev) } else #endif { -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); #endif @@ -504,7 +496,7 @@ static void pc236_detach(struct comedi_device *dev) * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ -#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) static int pc236_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -528,7 +520,7 @@ static void pc236_intr_disable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 0; -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) if (devpriv->lcr_iobase) outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); #endif @@ -546,7 +538,7 @@ static void pc236_intr_enable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 1; -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) if (devpriv->lcr_iobase) outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR); #endif @@ -568,7 +560,7 @@ static int pc236_intr_check(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->enable_irq) { retval = 1; -#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) if (devpriv->lcr_iobase) { if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR) & PLX9052_INTCSR_LI1STAT_MASK) -- GitLab From c25386f5db48ee5d94b6ff3b1dc43ea6c87c9560 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:29 +0100 Subject: [PATCH 0384/6849] staging: comedi: amplc_pc236: Use module_comedi_{pci,}_driver() If PCI boards are supported, use the module_comedi_pci_driver() macro to register the module as a comedi driver and a PCI driver. Otherwise, only ISA boards are supported so use the module_comedi_driver() macro to register the module as a comedi driver. Renamed 'driver_amplc_pc236' to 'amplc_pc236_driver' and removed 'driver_' prefix from PCI related functions and variables, purely for aesthetic reasons. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 50 ++++---------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 5f1caacbce13..afd08f043403 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -167,7 +167,7 @@ struct pc236_private { */ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void pc236_detach(struct comedi_device *dev); -static struct comedi_driver driver_amplc_pc236 = { +static struct comedi_driver amplc_pc236_driver = { .driver_name = PC236_DRIVER_NAME, .module = THIS_MODULE, .attach = pc236_attach, @@ -178,58 +178,28 @@ static struct comedi_driver driver_amplc_pc236 = { }; #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) -static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev, +static int __devinit amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_amplc_pc236); + return comedi_pci_auto_config(dev, &lc_pc236_driver); } -static void __devexit driver_amplc_pc236_pci_remove(struct pci_dev *dev) +static void __devexit amplc_pc236_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_amplc_pc236_pci_driver = { +static struct pci_driver amplc_pc236_pci_driver = { + .name = PC236_DRIVER_NAME, .id_table = pc236_pci_table, - .probe = &driver_amplc_pc236_pci_probe, - .remove = __devexit_p(&driver_amplc_pc236_pci_remove) + .probe = &lc_pc236_pci_probe, + .remove = __devexit_p(&lc_pc236_pci_remove) }; -static int __init driver_amplc_pc236_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_amplc_pc236); - if (retval < 0) - return retval; - - driver_amplc_pc236_pci_driver.name = - (char *)driver_amplc_pc236.driver_name; - return pci_register_driver(&driver_amplc_pc236_pci_driver); -} - -static void __exit driver_amplc_pc236_cleanup_module(void) -{ - pci_unregister_driver(&driver_amplc_pc236_pci_driver); - comedi_driver_unregister(&driver_amplc_pc236); -} - -module_init(driver_amplc_pc236_init_module); -module_exit(driver_amplc_pc236_cleanup_module); +module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver); #else -static int __init driver_amplc_pc236_init_module(void) -{ - return comedi_driver_register(&driver_amplc_pc236); -} - -static void __exit driver_amplc_pc236_cleanup_module(void) -{ - comedi_driver_unregister(&driver_amplc_pc236); -} - -module_init(driver_amplc_pc236_init_module); -module_exit(driver_amplc_pc236_cleanup_module); +module_comedi_driver(amplc_pc236_driver); #endif #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) -- GitLab From 7bd06f69f3f52fcd04999790a2a9d66f1a8cd0c9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:30 +0100 Subject: [PATCH 0385/6849] staging: comedi: amplc_pc236: Remove forward function declarations Moved some functions and variables to avoid forward declarations. Moved PCI table closer to the struct pci_driver that refers to it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 476 +++++++++---------- 1 file changed, 226 insertions(+), 250 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index afd08f043403..007b45bef7b0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -130,15 +130,6 @@ static const struct pc236_board pc236_boards[] = { #endif }; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) -static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, pc236_pci_table); -#endif /* CONFIG_COMEDI_AMPLC_PC236_PCI */ - /* * Useful for shorthand access to the particular board structure */ @@ -159,68 +150,6 @@ struct pc236_private { #define devpriv ((struct pc236_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void pc236_detach(struct comedi_device *dev); -static struct comedi_driver amplc_pc236_driver = { - .driver_name = PC236_DRIVER_NAME, - .module = THIS_MODULE, - .attach = pc236_attach, - .detach = pc236_detach, - .board_name = &pc236_boards[0].name, - .offset = sizeof(struct pc236_board), - .num_names = ARRAY_SIZE(pc236_boards), -}; - -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) -static int __devinit amplc_pc236_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) -{ - return comedi_pci_auto_config(dev, &lc_pc236_driver); -} - -static void __devexit amplc_pc236_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver amplc_pc236_pci_driver = { - .name = PC236_DRIVER_NAME, - .id_table = pc236_pci_table, - .probe = &lc_pc236_pci_probe, - .remove = __devexit_p(&lc_pc236_pci_remove) -}; - -module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver); -#else -module_comedi_driver(amplc_pc236_driver); -#endif - -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) -static int pc236_request_region(unsigned minor, unsigned long from, - unsigned long extent); -#endif -static void pc236_intr_disable(struct comedi_device *dev); -static void pc236_intr_enable(struct comedi_device *dev); -static int pc236_intr_check(struct comedi_device *dev); -static int pc236_intr_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int pc236_intr_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int pc236_intr_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); -static int pc236_intr_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); -static irqreturn_t pc236_interrupt(int irq, void *d); - /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -283,185 +212,6 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot, } #endif -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase = 0; - unsigned int irq = 0; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - struct pci_dev *pci_dev = NULL; - int bus = 0, slot = 0; -#endif - int share_irq = 0; - int ret; - - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, - PC236_DRIVER_NAME); -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - ret = alloc_private(dev, sizeof(struct pc236_private)); - if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - return ret; - } - /* Process options. */ - switch (thisboard->bustype) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - case isa_bustype: - iobase = it->options[0]; - irq = it->options[1]; - share_irq = 0; - break; -#endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: - bus = it->options[0]; - slot = it->options[1]; - share_irq = 1; - - ret = pc236_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; - devpriv->pci_dev = pci_dev; - break; -#endif - default: - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, PC236_DRIVER_NAME); - return -EINVAL; - break; - } - -/* - * Initialize dev->board_name. - */ - dev->board_name = thisboard->name; - - /* Enable device and reserve I/O spaces. */ -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (pci_dev) { - - ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); - if (ret < 0) { - printk(KERN_ERR - "comedi%d: error! cannot enable PCI device and request regions!\n", - dev->minor); - return ret; - } - devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); - iobase = pci_resource_start(pci_dev, 2); - irq = pci_dev->irq; - } else -#endif - { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); - if (ret < 0) - return ret; -#endif - } - dev->iobase = iobase; - -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - ret = alloc_subdevices(dev, 2); - if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - return ret; - } - - s = dev->subdevices + 0; - /* digital i/o subdevice (8255) */ - ret = subdev_8255_init(dev, s, NULL, iobase); - if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - return ret; - } - s = dev->subdevices + 1; - dev->read_subdev = s; - s->type = COMEDI_SUBD_UNUSED; - pc236_intr_disable(dev); - if (irq) { - unsigned long flags = share_irq ? IRQF_SHARED : 0; - - if (request_irq(irq, pc236_interrupt, flags, - PC236_DRIVER_NAME, dev) >= 0) { - dev->irq = irq; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; - s->n_chan = 1; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = pc236_intr_insn; - s->do_cmdtest = pc236_intr_cmdtest; - s->do_cmd = pc236_intr_cmd; - s->cancel = pc236_intr_cancel; - } - } - printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - switch (thisboard->bustype) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - case isa_bustype: - printk("(base %#lx) ", iobase); - break; -#endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: - printk("(pci %s) ", pci_name(pci_dev)); - break; -#endif - default: - break; - } - if (irq) - printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - else - printk("(no irq) "); - - printk("attached\n"); - - return 1; -} - -static void pc236_detach(struct comedi_device *dev) -{ - if (devpriv) - pc236_intr_disable(dev); - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 0); - if (devpriv) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } else -#endif - { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - if (dev->iobase) - release_region(dev->iobase, PC236_IO_SIZE); -#endif - } - } -} - /* * This function checks and requests an I/O region, reporting an error * if there is a conflict. @@ -681,6 +431,232 @@ static irqreturn_t pc236_interrupt(int irq, void *d) return IRQ_RETVAL(handled); } +/* + * Attach is called by the Comedi core to configure the driver + * for a particular board. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that + * address. + */ +static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + unsigned long iobase = 0; + unsigned int irq = 0; +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + struct pci_dev *pci_dev = NULL; + int bus = 0, slot = 0; +#endif + int share_irq = 0; + int ret; + + printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, + PC236_DRIVER_NAME); +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + ret = alloc_private(dev, sizeof(struct pc236_private)); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + /* Process options. */ + switch (thisboard->bustype) { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + case isa_bustype: + iobase = it->options[0]; + irq = it->options[1]; + share_irq = 0; + break; +#endif +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + case pci_bustype: + bus = it->options[0]; + slot = it->options[1]; + share_irq = 1; + + ret = pc236_find_pci(dev, bus, slot, &pci_dev); + if (ret < 0) + return ret; + devpriv->pci_dev = pci_dev; + break; +#endif + default: + printk(KERN_ERR + "comedi%d: %s: BUG! cannot determine board type!\n", + dev->minor, PC236_DRIVER_NAME); + return -EINVAL; + break; + } + +/* + * Initialize dev->board_name. + */ + dev->board_name = thisboard->name; + + /* Enable device and reserve I/O spaces. */ +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + if (pci_dev) { + + ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); + if (ret < 0) { + printk(KERN_ERR + "comedi%d: error! cannot enable PCI device and request regions!\n", + dev->minor); + return ret; + } + devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); + iobase = pci_resource_start(pci_dev, 2); + irq = pci_dev->irq; + } else +#endif + { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); + if (ret < 0) + return ret; +#endif + } + dev->iobase = iobase; + +/* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + */ + ret = alloc_subdevices(dev, 2); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + + s = dev->subdevices + 0; + /* digital i/o subdevice (8255) */ + ret = subdev_8255_init(dev, s, NULL, iobase); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + s = dev->subdevices + 1; + dev->read_subdev = s; + s->type = COMEDI_SUBD_UNUSED; + pc236_intr_disable(dev); + if (irq) { + unsigned long flags = share_irq ? IRQF_SHARED : 0; + + if (request_irq(irq, pc236_interrupt, flags, + PC236_DRIVER_NAME, dev) >= 0) { + dev->irq = irq; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->n_chan = 1; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pc236_intr_insn; + s->do_cmdtest = pc236_intr_cmdtest; + s->do_cmd = pc236_intr_cmd; + s->cancel = pc236_intr_cancel; + } + } + printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); + switch (thisboard->bustype) { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + case isa_bustype: + printk("(base %#lx) ", iobase); + break; +#endif +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + case pci_bustype: + printk("(pci %s) ", pci_name(pci_dev)); + break; +#endif + default: + break; + } + if (irq) + printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); + else + printk("(no irq) "); + + printk("attached\n"); + + return 1; +} + +static void pc236_detach(struct comedi_device *dev) +{ + if (devpriv) + pc236_intr_disable(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->subdevices) + subdev_8255_cleanup(dev, dev->subdevices + 0); + if (devpriv) { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + if (devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } else +#endif + { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + if (dev->iobase) + release_region(dev->iobase, PC236_IO_SIZE); +#endif + } + } +} + +/* + * The struct comedi_driver structure tells the Comedi core module + * which functions to call to configure/deconfigure (attach/detach) + * the board, and also about the kernel module that contains + * the device code. + */ +static struct comedi_driver amplc_pc236_driver = { + .driver_name = PC236_DRIVER_NAME, + .module = THIS_MODULE, + .attach = pc236_attach, + .detach = pc236_detach, + .board_name = &pc236_boards[0].name, + .offset = sizeof(struct pc236_board), + .num_names = ARRAY_SIZE(pc236_boards), +}; + +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) +static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, + {0} +}; + +MODULE_DEVICE_TABLE(pci, pc236_pci_table); + +static int __devinit amplc_pc236_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &lc_pc236_driver); +} + +static void __devexit amplc_pc236_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver amplc_pc236_pci_driver = { + .name = PC236_DRIVER_NAME, + .id_table = pc236_pci_table, + .probe = &lc_pc236_pci_probe, + .remove = __devexit_p(&lc_pc236_pci_remove) +}; + +module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver); +#else +module_comedi_driver(amplc_pc236_driver); +#endif + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- GitLab From 62bc23d145d636f0de2bf412dcf31a33fcf16046 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:31 +0100 Subject: [PATCH 0386/6849] staging: comedi: amplc_pc236: Replace printk calls Replace the printk calls with dev_info, dev_err, etc. There were some consecutive printk calls without newlines which now scnprintf into a temporary buffer and this bit of code has been factored out into new function pc236_report_attach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 108 +++++++++---------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 007b45bef7b0..b56881c7e603 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -201,12 +201,12 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot, } /* No match found. */ if (bus || slot) { - printk(KERN_ERR - "comedi%d: error! no %s found at pci %02x:%02x!\n", - dev->minor, thisboard->name, bus, slot); + dev_err(dev->class_dev, + "error! no %s found at pci %02x:%02x!\n", + thisboard->name, bus, slot); } else { - printk(KERN_ERR "comedi%d: error! no %s found!\n", - dev->minor, thisboard->name); + dev_err(dev->class_dev, "error! no %s found!\n", + thisboard->name); } return -EIO; } @@ -217,12 +217,12 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot, * if there is a conflict. */ #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) -static int pc236_request_region(unsigned minor, unsigned long from, +static int pc236_request_region(struct comedi_device *dev, unsigned long from, unsigned long extent) { if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) { - printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", - minor, from, extent); + dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n", + from, extent); return -EIO; } return 0; @@ -431,6 +431,39 @@ static irqreturn_t pc236_interrupt(int irq, void *d) return IRQ_RETVAL(handled); } +static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) +{ + char tmpbuf[60]; + int tmplen; + + switch (thisboard->bustype) { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + case isa_bustype: + tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), + "(base %#lx) ", dev->iobase); + break; +#endif +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + case pci_bustype: + tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), + "(pci %s) ", pci_name(devpriv->pci_dev)); + break; +#endif + default: + tmplen = 0; + break; + } + if (irq) + tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen, + "(irq %u%s) ", irq, + (dev->irq ? "" : " UNAVAILABLE")); + else + tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen, + "(no irq) "); + dev_info(dev->class_dev, "%s %sattached\n", + dev->board_name, tmpbuf); +} + /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -449,16 +482,10 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) int share_irq = 0; int ret; - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, - PC236_DRIVER_NAME); -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ + dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n"); ret = alloc_private(dev, sizeof(struct pc236_private)); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } /* Process options. */ @@ -483,16 +510,13 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; #endif default: - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, PC236_DRIVER_NAME); + dev_err(dev->class_dev, PC236_DRIVER_NAME + ": BUG! cannot determine board type!\n"); return -EINVAL; break; } -/* - * Initialize dev->board_name. - */ + /* Initialize dev->board_name. */ dev->board_name = thisboard->name; /* Enable device and reserve I/O spaces. */ @@ -501,9 +525,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); if (ret < 0) { - printk(KERN_ERR - "comedi%d: error! cannot enable PCI device and request regions!\n", - dev->minor); + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); return ret; } devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); @@ -513,21 +536,16 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif { #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); + ret = pc236_request_region(dev, iobase, PC236_IO_SIZE); if (ret < 0) return ret; #endif } dev->iobase = iobase; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ ret = alloc_subdevices(dev, 2); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } @@ -535,8 +553,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital i/o subdevice (8255) */ ret = subdev_8255_init(dev, s, NULL, iobase); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } s = dev->subdevices + 1; @@ -560,28 +577,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->cancel = pc236_intr_cancel; } } - printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - switch (thisboard->bustype) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - case isa_bustype: - printk("(base %#lx) ", iobase); - break; -#endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: - printk("(pci %s) ", pci_name(pci_dev)); - break; -#endif - default: - break; - } - if (irq) - printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - else - printk("(no irq) "); - - printk("attached\n"); - + pc236_report_attach(dev, irq); return 1; } -- GitLab From 916d7028a91a6a0e4b76e7cfb97819f294cbd803 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:32 +0100 Subject: [PATCH 0387/6849] staging: comedi: amplc_pc236: Remove unused fancy_name Remove fancy_name member from struct pc236_board. It is initialized in pc235_boards[] but not used anywhere else. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 32 +++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index b56881c7e603..79265696ac52 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -98,7 +98,6 @@ enum pc236_model { pc36at_model, pci236_model, anypci_model }; struct pc236_board { const char *name; - const char *fancy_name; unsigned short devid; enum pc236_bustype bustype; enum pc236_model model; @@ -106,27 +105,24 @@ struct pc236_board { static const struct pc236_board pc236_boards[] = { #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) { - .name = "pc36at", - .fancy_name = "PC36AT", - .bustype = isa_bustype, - .model = pc36at_model, - }, + .name = "pc36at", + .bustype = isa_bustype, + .model = pc36at_model, + }, #endif #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) { - .name = "pci236", - .fancy_name = "PCI236", - .devid = PCI_DEVICE_ID_AMPLICON_PCI236, - .bustype = pci_bustype, - .model = pci236_model, - }, + .name = "pci236", + .devid = PCI_DEVICE_ID_AMPLICON_PCI236, + .bustype = pci_bustype, + .model = pci236_model, + }, { - .name = PC236_DRIVER_NAME, - .fancy_name = PC236_DRIVER_NAME, - .devid = PCI_DEVICE_ID_INVALID, - .bustype = pci_bustype, - .model = anypci_model, /* wildcard */ - }, + .name = PC236_DRIVER_NAME, + .devid = PCI_DEVICE_ID_INVALID, + .bustype = pci_bustype, + .model = anypci_model, /* wildcard */ + }, #endif }; -- GitLab From 273ba547da12406d609795bc8976cb2464b15d82 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:33 +0100 Subject: [PATCH 0388/6849] staging: comedi: amplc_pc236: Change return type of pc236_find_pci() pc236_find_pci() finds a supported PCI device, returning 0 on success or -EIO on failure and returning the pointer to the PCI device via a struct pci_dev ** parameter. Change it to return the struct pci_dev * on success or NULL on failure. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 79265696ac52..a94ac0e668a9 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -151,14 +151,11 @@ struct pc236_private { * bus and slot. */ #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) -static int -pc236_find_pci(struct comedi_device *dev, int bus, int slot, - struct pci_dev **pci_dev_p) +struct pci_dev * +pc236_find_pci(struct comedi_device *dev, int bus, int slot) { struct pci_dev *pci_dev = NULL; - *pci_dev_p = NULL; - /* Look for matching PCI device. */ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL); pci_dev != NULL; @@ -192,8 +189,7 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot, } /* Found a match. */ - *pci_dev_p = pci_dev; - return 0; + return pci_dev; } /* No match found. */ if (bus || slot) { @@ -204,7 +200,7 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot, dev_err(dev->class_dev, "error! no %s found!\n", thisboard->name); } - return -EIO; + return NULL; } #endif @@ -499,9 +495,9 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) slot = it->options[1]; share_irq = 1; - ret = pc236_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; + pci_dev = pc236_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; devpriv->pci_dev = pci_dev; break; #endif -- GitLab From 24ffe74c93ac93bae84b2e44b868bbfd2c7954c3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:34 +0100 Subject: [PATCH 0389/6849] staging: comedi: amplc_pc236: Remove thisboard and devpriv macros The 'thisboard' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macros with local variables wherever they occur. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 27 ++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index a94ac0e668a9..d52c7280d8d4 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -126,11 +126,6 @@ static const struct pc236_board pc236_boards[] = { #endif }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct pc236_board *)dev->board_ptr) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. @@ -144,8 +139,6 @@ struct pc236_private { int enable_irq; }; -#define devpriv ((struct pc236_private *)dev->private) - /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -154,6 +147,7 @@ struct pc236_private { struct pci_dev * pc236_find_pci(struct comedi_device *dev, int bus, int slot) { + const struct pc236_board *thisboard = comedi_board(dev); struct pci_dev *pci_dev = NULL; /* Look for matching PCI device. */ @@ -177,6 +171,7 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot) if (pci_dev->device == pc236_boards[i].devid) { /* Change board_ptr to matched board. */ dev->board_ptr = &pc236_boards[i]; + thisboard = comedi_board(dev); break; } } @@ -228,6 +223,7 @@ static int pc236_request_region(struct comedi_device *dev, unsigned long from, */ static void pc236_intr_disable(struct comedi_device *dev) { + struct pc236_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -246,6 +242,7 @@ static void pc236_intr_disable(struct comedi_device *dev) */ static void pc236_intr_enable(struct comedi_device *dev) { + struct pc236_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -266,6 +263,7 @@ static void pc236_intr_enable(struct comedi_device *dev) */ static int pc236_intr_check(struct comedi_device *dev) { + struct pc236_private *devpriv = dev->private; int retval = 0; unsigned long flags; @@ -425,6 +423,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d) static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) { + const struct pc236_board *thisboard = comedi_board(dev); char tmpbuf[60]; int tmplen; @@ -436,9 +435,12 @@ static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) break; #endif #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: - tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), - "(pci %s) ", pci_name(devpriv->pci_dev)); + case pci_bustype: { + struct pc236_private *devpriv = dev->private; + struct pci_dev *pci_dev = devpriv->pci_dev; + tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), + "(pci %s) ", pci_name(pci_dev)); + } break; #endif default: @@ -464,10 +466,12 @@ static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) */ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pc236_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + struct pc236_private *devpriv = dev->private; struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -498,6 +502,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) pci_dev = pc236_find_pci(dev, bus, slot); if (pci_dev == NULL) return -EIO; + thisboard = comedi_board(dev); /* replaced wildcard board */ devpriv->pci_dev = pci_dev; break; #endif @@ -575,6 +580,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pc236_detach(struct comedi_device *dev) { + struct pc236_private *devpriv = dev->private; + if (devpriv) pc236_intr_disable(dev); if (dev->irq) -- GitLab From 18e41de083075b3b6a0bd55e00f1662d045efb49 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 29 May 2012 14:49:35 +0100 Subject: [PATCH 0390/6849] staging: comedi: amplc_pc236: Add attach_pci() hook Implement the attach_pci() hook as function pc236_attach_pci(). This is called bu comedi_pci_auto_config() in preference to the old attach() hook (implemented by pc236_attach()) and avoids searching for the probed PCI device. Factor out code common to pc236_find_pci() and pc236_attach_pci() into new function pc236_find_pci_board(). Factor out most code common to pc236_attach() and pc236_attach_pci() into new functions pc236_pci_common_attach() and pc236_common_attach(). Also #if out member 'devid' from struct pc236_board unless PCI boards are supported as it is not used for ISA boards. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 220 +++++++++++-------- 1 file changed, 129 insertions(+), 91 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index d52c7280d8d4..f1199066d14f 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -98,7 +98,9 @@ enum pc236_model { pc36at_model, pci236_model, anypci_model }; struct pc236_board { const char *name; +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) unsigned short devid; +#endif enum pc236_bustype bustype; enum pc236_model model; }; @@ -139,6 +141,22 @@ struct pc236_private { int enable_irq; }; +/* + * This function looks for a board matching the supplied PCI device. + */ +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) +static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) + if (pc236_boards[i].bustype == pci_bustype && + pci_dev->device == pc236_boards[i].devid) + return &pc236_boards[i]; + return NULL; +} +#endif + /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -162,21 +180,13 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot) continue; } if (thisboard->model == anypci_model) { - /* Match any supported model. */ - int i; - - for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) { - if (pc236_boards[i].bustype != pci_bustype) - continue; - if (pci_dev->device == pc236_boards[i].devid) { - /* Change board_ptr to matched board. */ - dev->board_ptr = &pc236_boards[i]; - thisboard = comedi_board(dev); - break; - } - } - if (i == ARRAY_SIZE(pc236_boards)) + /* Wildcard board matches any supported PCI board. */ + const struct pc236_board *foundboard; + foundboard = pc236_find_pci_board(pci_dev); + if (foundboard == NULL) continue; + /* Replace wildcard board_ptr. */ + dev->board_ptr = thisboard = foundboard; } else { /* Match specific model name. */ if (pci_dev->device != thisboard->devid) @@ -458,86 +468,14 @@ static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) dev->board_name, tmpbuf); } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase, + unsigned int irq, unsigned long req_irq_flags) { const struct pc236_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; - unsigned long iobase = 0; - unsigned int irq = 0; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - struct pc236_private *devpriv = dev->private; - struct pci_dev *pci_dev = NULL; - int bus = 0, slot = 0; -#endif - int share_irq = 0; int ret; - dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct pc236_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } - /* Process options. */ - switch (thisboard->bustype) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - case isa_bustype: - iobase = it->options[0]; - irq = it->options[1]; - share_irq = 0; - break; -#endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: - bus = it->options[0]; - slot = it->options[1]; - share_irq = 1; - - pci_dev = pc236_find_pci(dev, bus, slot); - if (pci_dev == NULL) - return -EIO; - thisboard = comedi_board(dev); /* replaced wildcard board */ - devpriv->pci_dev = pci_dev; - break; -#endif - default: - dev_err(dev->class_dev, PC236_DRIVER_NAME - ": BUG! cannot determine board type!\n"); - return -EINVAL; - break; - } - - /* Initialize dev->board_name. */ dev->board_name = thisboard->name; - - /* Enable device and reserve I/O spaces. */ -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (pci_dev) { - - ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); - return ret; - } - devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); - iobase = pci_resource_start(pci_dev, 2); - irq = pci_dev->irq; - } else -#endif - { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - ret = pc236_request_region(dev, iobase, PC236_IO_SIZE); - if (ret < 0) - return ret; -#endif - } dev->iobase = iobase; ret = alloc_subdevices(dev, 2); @@ -558,9 +496,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; pc236_intr_disable(dev); if (irq) { - unsigned long flags = share_irq ? IRQF_SHARED : 0; - - if (request_irq(irq, pc236_interrupt, flags, + if (request_irq(irq, pc236_interrupt, req_irq_flags, PC236_DRIVER_NAME, dev) >= 0) { dev->irq = irq; s->type = COMEDI_SUBD_DI; @@ -578,6 +514,105 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) +static int pc236_pci_common_attach(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + struct pc236_private *devpriv = dev->private; + unsigned long iobase; + int ret; + + devpriv->pci_dev = pci_dev; + ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); + if (ret < 0) { + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); + return ret; + } + devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); + iobase = pci_resource_start(pci_dev, 2); + return pc236_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); +} +#endif + +/* + * Attach is called by the Comedi core to configure the driver + * for a particular board. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that + * address. + */ +static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct pc236_board *thisboard = comedi_board(dev); + int ret; + + dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n"); + ret = alloc_private(dev, sizeof(struct pc236_private)); + if (ret < 0) { + dev_err(dev->class_dev, "error! out of memory!\n"); + return ret; + } + /* Process options according to bus type. */ + switch (thisboard->bustype) { +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + case isa_bustype: { + unsigned long iobase = it->options[0]; + unsigned int irq = it->options[1]; + ret = pc236_request_region(dev, iobase, PC236_IO_SIZE); + if (ret < 0) + return ret; + return pc236_common_attach(dev, iobase, irq, 0); + } + break; +#endif +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + case pci_bustype: { + int bus = it->options[0]; + int slot = it->options[1]; + struct pci_dev *pci_dev; + + pci_dev = pc236_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; + return pc236_pci_common_attach(dev, pci_dev); + } + break; +#endif + default: + dev_err(dev->class_dev, PC236_DRIVER_NAME + ": BUG! cannot determine board type!\n"); + break; + } + return -EINVAL; +} + +/* + * The attach_pci hook (if non-NULL) is called at PCI probe time in preference + * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should + * be a board entry matching the supplied PCI device. + */ +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) +static int __devinit pc236_attach_pci(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + int ret; + + dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n", + pci_name(pci_dev)); + ret = alloc_private(dev, sizeof(struct pc236_private)); + if (ret < 0) { + dev_err(dev->class_dev, "error! out of memory!\n"); + return ret; + } + dev->board_ptr = pc236_find_pci_board(pci_dev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + return pc236_pci_common_attach(dev, pci_dev); +} +#endif + static void pc236_detach(struct comedi_device *dev) { struct pc236_private *devpriv = dev->private; @@ -615,6 +650,9 @@ static struct comedi_driver amplc_pc236_driver = { .driver_name = PC236_DRIVER_NAME, .module = THIS_MODULE, .attach = pc236_attach, +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) + .attach_pci = pc236_attach_pci, +#endif .detach = pc236_detach, .board_name = &pc236_boards[0].name, .offset = sizeof(struct pc236_board), -- GitLab From a46e759fc05a048530da43f241c8f07e0624232c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 14:37:52 +0100 Subject: [PATCH 0391/6849] staging: comedi: amplc_pc236: Remove most #if lines Remove most of the #if IS_ENABLED(xxx) lines, but add extra if (IS_ENABLED(xxx)) tests so the compiler can remove unreachable code. The pci_driver stuff and device table is still conditionally compiled. Also made pc236_find_pci() static as it was accidentally made non-static by an earlier patch, so the compiler wouldn't remove it when it was unreachable. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 118 +++++++------------ 1 file changed, 40 insertions(+), 78 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index f1199066d14f..9cf514e54a58 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -98,9 +98,7 @@ enum pc236_model { pc36at_model, pci236_model, anypci_model }; struct pc236_board { const char *name; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) unsigned short devid; -#endif enum pc236_bustype bustype; enum pc236_model model; }; @@ -133,18 +131,15 @@ static const struct pc236_board pc236_boards[] = { feel free to suggest moving the variable to the struct comedi_device struct. */ struct pc236_private { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) /* PCI device */ struct pci_dev *pci_dev; unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ -#endif int enable_irq; }; /* * This function looks for a board matching the supplied PCI device. */ -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev) { unsigned int i; @@ -155,14 +150,12 @@ static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev) return &pc236_boards[i]; return NULL; } -#endif /* * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) -struct pci_dev * +static struct pci_dev * pc236_find_pci(struct comedi_device *dev, int bus, int slot) { const struct pc236_board *thisboard = comedi_board(dev); @@ -207,13 +200,11 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot) } return NULL; } -#endif /* * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) static int pc236_request_region(struct comedi_device *dev, unsigned long from, unsigned long extent) { @@ -224,7 +215,6 @@ static int pc236_request_region(struct comedi_device *dev, unsigned long from, } return 0; } -#endif /* * This function is called to mark the interrupt as disabled (no command @@ -238,10 +228,8 @@ static void pc236_intr_disable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 0; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (devpriv->lcr_iobase) + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && devpriv->lcr_iobase) outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); -#endif spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -257,10 +245,8 @@ static void pc236_intr_enable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 1; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (devpriv->lcr_iobase) + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && devpriv->lcr_iobase) outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR); -#endif spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -280,8 +266,8 @@ static int pc236_intr_check(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->enable_irq) { retval = 1; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (devpriv->lcr_iobase) { + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && + devpriv->lcr_iobase) { if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR) & PLX9052_INTCSR_LI1STAT_MASK) == PLX9052_INTCSR_LI1STAT_INACTIVE) { @@ -292,7 +278,6 @@ static int pc236_intr_check(struct comedi_device *dev) devpriv->lcr_iobase + PLX9052_INTCSR); } } -#endif } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -437,26 +422,18 @@ static void pc236_report_attach(struct comedi_device *dev, unsigned int irq) char tmpbuf[60]; int tmplen; - switch (thisboard->bustype) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - case isa_bustype: + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) && + thisboard->bustype == isa_bustype) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); - break; -#endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: { - struct pc236_private *devpriv = dev->private; - struct pci_dev *pci_dev = devpriv->pci_dev; - tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), - "(pci %s) ", pci_name(pci_dev)); - } - break; -#endif - default: + else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && + thisboard->bustype == pci_bustype) { + struct pc236_private *devpriv = dev->private; + struct pci_dev *pci_dev = devpriv->pci_dev; + tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), + "(pci %s) ", pci_name(pci_dev)); + } else tmplen = 0; - break; - } if (irq) tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen, "(irq %u%s) ", irq, @@ -514,7 +491,6 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase, return 1; } -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) static int pc236_pci_common_attach(struct comedi_device *dev, struct pci_dev *pci_dev) { @@ -533,7 +509,6 @@ static int pc236_pci_common_attach(struct comedi_device *dev, iobase = pci_resource_start(pci_dev, 2); return pc236_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); } -#endif /* * Attach is called by the Comedi core to configure the driver @@ -553,37 +528,29 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } /* Process options according to bus type. */ - switch (thisboard->bustype) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) - case isa_bustype: { - unsigned long iobase = it->options[0]; - unsigned int irq = it->options[1]; - ret = pc236_request_region(dev, iobase, PC236_IO_SIZE); - if (ret < 0) - return ret; - return pc236_common_attach(dev, iobase, irq, 0); - } - break; -#endif -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - case pci_bustype: { - int bus = it->options[0]; - int slot = it->options[1]; - struct pci_dev *pci_dev; - - pci_dev = pc236_find_pci(dev, bus, slot); - if (pci_dev == NULL) - return -EIO; - return pc236_pci_common_attach(dev, pci_dev); - } - break; -#endif - default: + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) && + thisboard->bustype == isa_bustype) { + unsigned long iobase = it->options[0]; + unsigned int irq = it->options[1]; + ret = pc236_request_region(dev, iobase, PC236_IO_SIZE); + if (ret < 0) + return ret; + return pc236_common_attach(dev, iobase, irq, 0); + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && + thisboard->bustype == pci_bustype) { + int bus = it->options[0]; + int slot = it->options[1]; + struct pci_dev *pci_dev; + + pci_dev = pc236_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; + return pc236_pci_common_attach(dev, pci_dev); + } else { dev_err(dev->class_dev, PC236_DRIVER_NAME ": BUG! cannot determine board type!\n"); - break; + return -EINVAL; } - return -EINVAL; } /* @@ -591,12 +558,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should * be a board entry matching the supplied PCI device. */ -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) static int __devinit pc236_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { int ret; + if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)) + return -EINVAL; + dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); ret = alloc_private(dev, sizeof(struct pc236_private)); @@ -611,7 +580,6 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, } return pc236_pci_common_attach(dev, pci_dev); } -#endif static void pc236_detach(struct comedi_device *dev) { @@ -624,18 +592,14 @@ static void pc236_detach(struct comedi_device *dev) if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); if (devpriv) { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) - if (devpriv->pci_dev) { + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) && + devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); - } else -#endif - { -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA) + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA)) { if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); -#endif } } } @@ -650,9 +614,7 @@ static struct comedi_driver amplc_pc236_driver = { .driver_name = PC236_DRIVER_NAME, .module = THIS_MODULE, .attach = pc236_attach, -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) .attach_pci = pc236_attach_pci, -#endif .detach = pc236_detach, .board_name = &pc236_boards[0].name, .offset = sizeof(struct pc236_board), -- GitLab From 9f989000b54fe3131104bb26f1cc7bd0fab92e40 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:35 +0100 Subject: [PATCH 0392/6849] staging: comedi: amplc_pc263: Correct initial state The initial state of the relays is being read incorrectly. It's reading a single 8-bit port twice, but should be reading two consecutive 8-bit ports. Fix it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 086579f756ff..e2dbf74be81a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -330,8 +330,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* all outputs */ s->io_bits = 0xffff; /* read initial relay state */ - s->state = inb(dev->iobase); - s->state = s->state | (inb(dev->iobase) << 8); + s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); switch (thisboard->bustype) { -- GitLab From d35a73e099fd9900208ebdbc3adaba76d30acac4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:36 +0100 Subject: [PATCH 0393/6849] staging: comedi: amplc_pc263: Change DIO subdevice to DO This is a relay output card with no inputs. It's single subdevice is currently a digital input/output subdevice (COMEDI_SUBD_DIO). It should really be a digital output subdevice (COMEDI_SUBD_DO). Change the subdevice type and remove the insn_config() hook as it doesn't do anything useful. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 38 +++++--------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index e2dbf74be81a..a6a25436fadc 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -154,12 +154,9 @@ static struct comedi_driver driver_amplc_pc263 = { static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent); #endif -static int pc263_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pc263_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); +static int pc263_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); /* * This function looks for a PCI device matching the requested board name, @@ -319,16 +316,13 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) } s = dev->subdevices + 0; - /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; + /* digital output subdevice */ + s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->insn_bits = pc263_dio_insn_bits; - s->insn_config = pc263_dio_insn_config; - /* all outputs */ - s->io_bits = 0xffff; + s->insn_bits = pc263_do_insn_bits; /* read initial relay state */ s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); @@ -391,14 +385,9 @@ static int pc263_request_region(unsigned minor, unsigned long from, } #endif -/* DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The - * comedi core can convert between insn_bits and insn_read/write */ -static int pc263_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int pc263_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { if (insn->n != 2) return -EINVAL; @@ -422,15 +411,6 @@ static int pc263_dio_insn_bits(struct comedi_device *dev, return 2; } -static int pc263_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (insn->n != 1) - return -EINVAL; - return 1; -} - /* * A convenient macro that defines init_module() and cleanup_module(), * as necessary. -- GitLab From 61f5a223155d278c9731f2406513847b8fe0bddc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:37 +0100 Subject: [PATCH 0394/6849] staging: comedi: amplc_pc263: Add a missing case There is a missing case label in the switch statement that prints out details of the attached device in pc263_attach(). Fix it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index a6a25436fadc..f38a56ea4af7 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -334,6 +334,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; #endif #ifdef CONFIG_COMEDI_AMPLC_PC263_PCI + case pci_bustype: printk("(pci %s) ", pci_name(pci_dev)); break; #endif -- GitLab From b4843c19be4cbae48dc002080bdf49c274f26796 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:38 +0100 Subject: [PATCH 0395/6849] staging: comedi: amplc_pc263: Use IS_ENABLED() Change conditional compilation on kernel options to use the IS_ENABLED() macro. Remove most of the #ifdef lines and add extra if (IS_ENABLED(xxx)) tests so the compiler can remove unreachable code. The pci_driver stuff and device table is still conditionally compiled. In pc263_attach() move the call to alloc_private() as it is only used for PCI devices. (In pc263_detach(), for ISA devices a non-zero dev->iobase means the I/O region needs releasing.) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 181 ++++++------------- 1 file changed, 59 insertions(+), 122 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index f38a56ea4af7..f33eb0d43274 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -48,14 +48,6 @@ The state of the outputs can be read. #define PC263_DRIVER_NAME "amplc_pc263" -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA_MODULE -#define CONFIG_COMEDI_AMPLC_PC263_ISA -#endif - -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI_MODULE -#define CONFIG_COMEDI_AMPLC_PC263_PCI -#endif - /* PCI263 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c @@ -79,33 +71,33 @@ struct pc263_board { enum pc263_model model; }; static const struct pc263_board pc263_boards[] = { -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) { - .name = "pc263", - .fancy_name = "PC263", - .bustype = isa_bustype, - .model = pc263_model, - }, + .name = "pc263", + .fancy_name = "PC263", + .bustype = isa_bustype, + .model = pc263_model, + }, #endif -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) { - .name = "pci263", - .fancy_name = "PCI263", - .devid = PCI_DEVICE_ID_AMPLICON_PCI263, - .bustype = pci_bustype, - .model = pci263_model, - }, + .name = "pci263", + .fancy_name = "PCI263", + .devid = PCI_DEVICE_ID_AMPLICON_PCI263, + .bustype = pci_bustype, + .model = pci263_model, + }, { - .name = PC263_DRIVER_NAME, - .fancy_name = PC263_DRIVER_NAME, - .devid = PCI_DEVICE_ID_INVALID, - .bustype = pci_bustype, - .model = anypci_model, /* wildcard */ - }, + .name = PC263_DRIVER_NAME, + .fancy_name = PC263_DRIVER_NAME, + .devid = PCI_DEVICE_ID_INVALID, + .bustype = pci_bustype, + .model = anypci_model, /* wildcard */ + }, #endif }; -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, {0} @@ -123,14 +115,12 @@ MODULE_DEVICE_TABLE(pci, pc263_pci_table); several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. */ -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI struct pc263_private { /* PCI device. */ struct pci_dev *pci_dev; }; #define devpriv ((struct pc263_private *)dev->private) -#endif /* CONFIG_COMEDI_AMPLC_PC263_PCI */ /* * The struct comedi_driver structure tells the Comedi core module @@ -150,10 +140,8 @@ static struct comedi_driver driver_amplc_pc263 = { .num_names = ARRAY_SIZE(pc263_boards), }; -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent); -#endif static int pc263_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -162,7 +150,6 @@ static int pc263_do_insn_bits(struct comedi_device *dev, * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static int pc263_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -218,7 +205,6 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot, } return -EIO; } -#endif /* * Attach is called by the Comedi core to configure the driver @@ -230,60 +216,35 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase = 0; -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - struct pci_dev *pci_dev = NULL; - int bus = 0, slot = 0; -#endif int ret; printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, PC263_DRIVER_NAME); -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - ret = alloc_private(dev, sizeof(struct pc263_private)); - if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - return ret; - } -#endif - /* Process options. */ - switch (thisboard->bustype) { -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA - case isa_bustype: + + /* Process options and reserve resources according to bus type. */ + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && + thisboard->bustype == isa_bustype) { iobase = it->options[0]; - break; -#endif -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - case pci_bustype: + ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE); + if (ret < 0) + return ret; + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && + thisboard->bustype == pci_bustype) { + struct pci_dev *pci_dev = NULL; + int bus, slot; + + ret = alloc_private(dev, sizeof(struct pc263_private)); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } bus = it->options[0]; slot = it->options[1]; - ret = pc263_find_pci(dev, bus, slot, &pci_dev); if (ret < 0) return ret; devpriv->pci_dev = pci_dev; - break; -#endif - default: - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, PC263_DRIVER_NAME); - return -EINVAL; - break; - } - -/* - * Initialize dev->board_name. - */ - dev->board_name = thisboard->name; - - /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - if (pci_dev) { ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { printk(KERN_ERR @@ -293,21 +254,16 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } iobase = pci_resource_start(pci_dev, 2); - } else -#endif - { -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA - ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE); - if (ret < 0) - return ret; -#endif + } else { + printk(KERN_ERR + "comedi%d: %s: BUG! cannot determine board type!\n", + dev->minor, PC263_DRIVER_NAME); + return -EINVAL; } + + dev->board_name = thisboard->name; dev->iobase = iobase; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ ret = alloc_subdevices(dev, 1); if (ret < 0) { printk(KERN_ERR "comedi%d: error! out of memory!\n", @@ -327,20 +283,12 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - switch (thisboard->bustype) { -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA - case isa_bustype: + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && + thisboard->bustype == isa_bustype) printk("(base %#lx) ", iobase); - break; -#endif -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - case pci_bustype: - printk("(pci %s) ", pci_name(pci_dev)); - break; -#endif - default: - break; - } + else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && + thisboard->bustype == pci_bustype) + printk("(pci %s) ", pci_name(devpriv->pci_dev)); printk("attached\n"); @@ -349,23 +297,14 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pc263_detach(struct comedi_device *dev) { -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - if (devpriv) -#endif - { -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI - if (devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } else -#endif - { -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA - if (dev->iobase) - release_region(dev->iobase, PC263_IO_SIZE); -#endif - } + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && devpriv && + devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA)) { + if (dev->iobase) + release_region(dev->iobase, PC263_IO_SIZE); } } @@ -373,7 +312,6 @@ static void pc263_detach(struct comedi_device *dev) * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ -#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -384,7 +322,6 @@ static int pc263_request_region(unsigned minor, unsigned long from, } return 0; } -#endif static int pc263_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -416,7 +353,7 @@ static int pc263_do_insn_bits(struct comedi_device *dev, * A convenient macro that defines init_module() and cleanup_module(), * as necessary. */ -#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) -- GitLab From 40372f5f66c4d123b8bd17b785fadecd19eb2bd1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:39 +0100 Subject: [PATCH 0396/6849] staging: comedi: amplc_pc263: Use module_comedi_{pci, }_driver() If PCI boards are supported, use the module_comedi_pci_driver() macro to register the module as a comedi driver and a PCI driver. Otherwise, only ISA boards are supported so use the module_comedi_driver() macro to register the module as a comedi driver. Renamed 'driver_amplc_pc263' to 'amplc_pc263_driver' and removed 'driver_' prefix from PCI related functions and variables, purely for aesthetic reasons. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 55 ++++---------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index f33eb0d43274..f3cab3547bde 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -130,7 +130,7 @@ struct pc263_private { */ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void pc263_detach(struct comedi_device *dev); -static struct comedi_driver driver_amplc_pc263 = { +static struct comedi_driver amplc_pc263_driver = { .driver_name = PC263_DRIVER_NAME, .module = THIS_MODULE, .attach = pc263_attach, @@ -349,63 +349,28 @@ static int pc263_do_insn_bits(struct comedi_device *dev, return 2; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) -static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev, +static int __devinit amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_amplc_pc263); + return comedi_pci_auto_config(dev, &lc_pc263_driver); } -static void __devexit driver_amplc_pc263_pci_remove(struct pci_dev *dev) +static void __devexit amplc_pc263_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_amplc_pc263_pci_driver = { +static struct pci_driver amplc_pc263_pci_driver = { + .name = PC263_DRIVER_NAME, .id_table = pc263_pci_table, - .probe = &driver_amplc_pc263_pci_probe, - .remove = __devexit_p(&driver_amplc_pc263_pci_remove) + .probe = &lc_pc263_pci_probe, + .remove = __devexit_p(&lc_pc263_pci_remove) }; - -static int __init driver_amplc_pc263_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_amplc_pc263); - if (retval < 0) - return retval; - - driver_amplc_pc263_pci_driver.name = - (char *)driver_amplc_pc263.driver_name; - return pci_register_driver(&driver_amplc_pc263_pci_driver); -} - -static void __exit driver_amplc_pc263_cleanup_module(void) -{ - pci_unregister_driver(&driver_amplc_pc263_pci_driver); - comedi_driver_unregister(&driver_amplc_pc263); -} - -module_init(driver_amplc_pc263_init_module); -module_exit(driver_amplc_pc263_cleanup_module); +module_comedi_pci_driver(amplc_pc263_driver, amplc_pc263_pci_driver); #else -static int __init driver_amplc_pc263_init_module(void) -{ - return comedi_driver_register(&driver_amplc_pc263); -} - -static void __exit driver_amplc_pc263_cleanup_module(void) -{ - comedi_driver_unregister(&driver_amplc_pc263); -} - -module_init(driver_amplc_pc263_init_module); -module_exit(driver_amplc_pc263_cleanup_module); +module_comedi_driver(amplc_pc263_driver); #endif MODULE_AUTHOR("Comedi http://www.comedi.org"); -- GitLab From ba7914cd133cff9ac73e3434ba6980f2ac97a362 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:40 +0100 Subject: [PATCH 0397/6849] staging: comedi: amplc_pc263: Remove forward function declarations Moved some functions and variables to avoid forward declarations. Moved PCI table closer to the struct pci_driver that refers to it. Also removed some useless comments from pc263_attach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 123 ++++++++----------- 1 file changed, 52 insertions(+), 71 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index f3cab3547bde..5d5d9a280cea 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -97,15 +97,6 @@ static const struct pc263_board pc263_boards[] = { #endif }; -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) -static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, pc263_pci_table); -#endif /* CONFIG_COMEDI_AMPLC_PC263_PCI */ - /* * Useful for shorthand access to the particular board structure */ @@ -122,30 +113,6 @@ struct pc263_private { #define devpriv ((struct pc263_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void pc263_detach(struct comedi_device *dev); -static struct comedi_driver amplc_pc263_driver = { - .driver_name = PC263_DRIVER_NAME, - .module = THIS_MODULE, - .attach = pc263_attach, - .detach = pc263_detach, - .board_name = &pc263_boards[0].name, - .offset = sizeof(struct pc263_board), - .num_names = ARRAY_SIZE(pc263_boards), -}; - -static int pc263_request_region(unsigned minor, unsigned long from, - unsigned long extent); -static int pc263_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -205,6 +172,39 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot, } return -EIO; } +/* + * This function checks and requests an I/O region, reporting an error + * if there is a conflict. + */ +static int pc263_request_region(unsigned minor, unsigned long from, + unsigned long extent) +{ + if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) { + printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", + minor, from, extent); + return -EIO; + } + return 0; +} + +static int pc263_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + /* The insn data is a mask in data[0] and the new data + * in data[1], each channel cooresponding to a bit. */ + if (data[0]) { + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + /* Write out the new digital output lines */ + outb(s->state & 0xFF, dev->iobase); + outb(s->state >> 8, dev->iobase + 1); + } + return 2; +} /* * Attach is called by the Comedi core to configure the driver @@ -309,47 +309,28 @@ static void pc263_detach(struct comedi_device *dev) } /* - * This function checks and requests an I/O region, reporting an error - * if there is a conflict. + * The struct comedi_driver structure tells the Comedi core module + * which functions to call to configure/deconfigure (attach/detach) + * the board, and also about the kernel module that contains + * the device code. */ -static int pc263_request_region(unsigned minor, unsigned long from, - unsigned long extent) -{ - if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) { - printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", - minor, from, extent); - return -EIO; - } - return 0; -} - -static int pc263_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - /* The insn data is a mask in data[0] and the new data - * in data[1], each channel cooresponding to a bit. */ - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - /* Write out the new digital output lines */ - outb(s->state & 0xFF, dev->iobase); - outb(s->state >> 8, dev->iobase + 1); - } - - /* on return, data[1] contains the value of the digital - * input and output lines. */ - /* or we could just return the software copy of the output values if - * it was a purely digital output subdevice */ - data[1] = s->state; - - return 2; -} +static struct comedi_driver amplc_pc263_driver = { + .driver_name = PC263_DRIVER_NAME, + .module = THIS_MODULE, + .attach = pc263_attach, + .detach = pc263_detach, + .board_name = &pc263_boards[0].name, + .offset = sizeof(struct pc263_board), + .num_names = ARRAY_SIZE(pc263_boards), +}; #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) +static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, + {0} +}; +MODULE_DEVICE_TABLE(pci, pc263_pci_table); + static int __devinit amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) -- GitLab From 03668b101362b031b74a7cde865fa7346b44eb30 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:41 +0100 Subject: [PATCH 0398/6849] staging: comedi: amplc_pc263: Replace printk calls Replace the printk calls with dev_info, dev_err, etc. There were some consecutive printk calls without newlines which now snprintf into a temporary buffer and this bit of code has been factored out into new function pc263_report_attach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 65 ++++++++++---------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 5d5d9a280cea..b504c430cb37 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -163,12 +163,12 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot, } /* No match found. */ if (bus || slot) { - printk(KERN_ERR - "comedi%d: error! no %s found at pci %02x:%02x!\n", - dev->minor, thisboard->name, bus, slot); + dev_err(dev->class_dev, + "error! no %s found at pci %02x:%02x!\n", + thisboard->name, bus, slot); } else { - printk(KERN_ERR "comedi%d: error! no %s found!\n", - dev->minor, thisboard->name); + dev_err(dev->class_dev, "error! no %s found!\n", + thisboard->name); } return -EIO; } @@ -176,12 +176,12 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot, * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ -static int pc263_request_region(unsigned minor, unsigned long from, +static int pc263_request_region(struct comedi_device *dev, unsigned long from, unsigned long extent) { if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) { - printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", - minor, from, extent); + dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n", + from, extent); return -EIO; } return 0; @@ -206,6 +206,22 @@ static int pc263_do_insn_bits(struct comedi_device *dev, return 2; } +static void pc263_report_attach(struct comedi_device *dev) +{ + char tmpbuf[40]; + + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && + thisboard->bustype == isa_bustype) + snprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase); + else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && + thisboard->bustype == pci_bustype) + snprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", + pci_name(devpriv->pci_dev)); + else + tmpbuf[0] = '\0'; + dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf); +} + /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -218,14 +234,13 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase = 0; int ret; - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, - PC263_DRIVER_NAME); + dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach\n"); /* Process options and reserve resources according to bus type. */ if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && thisboard->bustype == isa_bustype) { iobase = it->options[0]; - ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE); + ret = pc263_request_region(dev, iobase, PC263_IO_SIZE); if (ret < 0) return ret; } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && @@ -235,8 +250,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = alloc_private(dev, sizeof(struct pc263_private)); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } bus = it->options[0]; @@ -247,17 +261,14 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { - printk(KERN_ERR - "comedi%d: error! cannot enable PCI device and " - "request regions!\n", - dev->minor); + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); return ret; } iobase = pci_resource_start(pci_dev, 2); } else { - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, PC263_DRIVER_NAME); + dev_err(dev->class_dev, PC263_DRIVER_NAME + ": BUG! cannot determine board type!\n"); return -EINVAL; } @@ -266,8 +277,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = alloc_subdevices(dev, 1); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } @@ -282,16 +292,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* read initial relay state */ s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); - printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && - thisboard->bustype == isa_bustype) - printk("(base %#lx) ", iobase); - else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && - thisboard->bustype == pci_bustype) - printk("(pci %s) ", pci_name(devpriv->pci_dev)); - - printk("attached\n"); - + pc263_report_attach(dev); return 1; } -- GitLab From 6ac682520ec3318f0a43582f642c0444ad5e3314 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:42 +0100 Subject: [PATCH 0399/6849] staging: comedi: amplc_pc263: Remove unused fancy_name Remove fancy_name member from struct pc263_board. It is initialized in pc263_boards[] but not used anywhere else. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index b504c430cb37..9fa98c4d27e0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -65,7 +65,6 @@ enum pc263_model { pc263_model, pci263_model, anypci_model }; struct pc263_board { const char *name; - const char *fancy_name; unsigned short devid; enum pc263_bustype bustype; enum pc263_model model; @@ -74,7 +73,6 @@ static const struct pc263_board pc263_boards[] = { #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) { .name = "pc263", - .fancy_name = "PC263", .bustype = isa_bustype, .model = pc263_model, }, @@ -82,14 +80,12 @@ static const struct pc263_board pc263_boards[] = { #if IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) { .name = "pci263", - .fancy_name = "PCI263", .devid = PCI_DEVICE_ID_AMPLICON_PCI263, .bustype = pci_bustype, .model = pci263_model, }, { .name = PC263_DRIVER_NAME, - .fancy_name = PC263_DRIVER_NAME, .devid = PCI_DEVICE_ID_INVALID, .bustype = pci_bustype, .model = anypci_model, /* wildcard */ -- GitLab From 7ac75ba4f364fb655c89b4f9ccf1cfbdf9dfd370 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:43 +0100 Subject: [PATCH 0400/6849] staging: comedi: amplc_pc263: Change return type of pc263_find_pci() pc263_find_pci() finds a supported PCI device, returning 0 on success or -EIO on failure and returning the pointer to the PCI device via a struct pci_dev ** parameter. Change it to return the struct pci_dev * on success or NULL on failure. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 9fa98c4d27e0..dd0b4b20582b 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -113,14 +113,11 @@ struct pc263_private { * This function looks for a PCI device matching the requested board name, * bus and slot. */ -static int -pc263_find_pci(struct comedi_device *dev, int bus, int slot, - struct pci_dev **pci_dev_p) +static struct pci_dev * +pc263_find_pci(struct comedi_device *dev, int bus, int slot) { struct pci_dev *pci_dev = NULL; - *pci_dev_p = NULL; - /* Look for matching PCI device. */ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL); pci_dev != NULL; @@ -154,8 +151,7 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot, } /* Found a match. */ - *pci_dev_p = pci_dev; - return 0; + return pci_dev; } /* No match found. */ if (bus || slot) { @@ -166,7 +162,7 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot, dev_err(dev->class_dev, "error! no %s found!\n", thisboard->name); } - return -EIO; + return NULL; } /* * This function checks and requests an I/O region, reporting an error @@ -251,9 +247,9 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) } bus = it->options[0]; slot = it->options[1]; - ret = pc263_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; + pci_dev = pc263_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { -- GitLab From 04d66968b34e3e22a524064df387c9fe906c6efa Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:44 +0100 Subject: [PATCH 0401/6849] staging: comedi: amplc_pc263: Remove thisboard and devpriv macros The 'thisboard' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macros with local variables wherever they occur. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index dd0b4b20582b..62fc335c4ea0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -93,11 +93,6 @@ static const struct pc263_board pc263_boards[] = { #endif }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct pc263_board *)dev->board_ptr) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. @@ -107,8 +102,6 @@ struct pc263_private { struct pci_dev *pci_dev; }; -#define devpriv ((struct pc263_private *)dev->private) - /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -116,6 +109,7 @@ struct pc263_private { static struct pci_dev * pc263_find_pci(struct comedi_device *dev, int bus, int slot) { + const struct pc263_board *thisboard = comedi_board(dev); struct pci_dev *pci_dev = NULL; /* Look for matching PCI device. */ @@ -139,6 +133,7 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot) if (pci_dev->device == pc263_boards[i].devid) { /* Change board_ptr to matched board. */ dev->board_ptr = &pc263_boards[i]; + thisboard = comedi_board(dev); break; } } @@ -200,6 +195,8 @@ static int pc263_do_insn_bits(struct comedi_device *dev, static void pc263_report_attach(struct comedi_device *dev) { + const struct pc263_board *thisboard = comedi_board(dev); + struct pc263_private *devpriv = dev->private; char tmpbuf[40]; if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && @@ -222,6 +219,7 @@ static void pc263_report_attach(struct comedi_device *dev) */ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pc263_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase = 0; int ret; @@ -237,6 +235,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && thisboard->bustype == pci_bustype) { + struct pc263_private *devpriv; struct pci_dev *pci_dev = NULL; int bus, slot; @@ -245,11 +244,13 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } + devpriv = dev->private; bus = it->options[0]; slot = it->options[1]; pci_dev = pc263_find_pci(dev, bus, slot); if (pci_dev == NULL) return -EIO; + thisboard = comedi_board(dev); /* replaced wildcard board */ devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { @@ -290,6 +291,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pc263_detach(struct comedi_device *dev) { + struct pc263_private *devpriv = dev->private; + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && devpriv && devpriv->pci_dev) { if (dev->iobase) -- GitLab From d8967b6ed676c697da3c05ab917a8eaae7a14f81 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 30 May 2012 19:04:45 +0100 Subject: [PATCH 0402/6849] staging: comedi: amplc_pc263: Add attach_pci() hook Implement the attach_pci() hook as function pc263_attach_pci(). This is called bu comedi_pci_auto_config() in preference to the old attach() hook (implemented by pc263_attach()) and avoids searching for the probed PCI device. Factor out code common to pc263_find_pci() and pc263_attach_pci() into new function pc263_find_pci_board(). Factor out most code common to pc263_attach() and pc263_attach_pci() into new functions pc263_pci_common_attach() and pc263_common_attach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc263.c | 141 +++++++++++++------ 1 file changed, 95 insertions(+), 46 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 62fc335c4ea0..7020907f1af7 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -102,6 +102,21 @@ struct pc263_private { struct pci_dev *pci_dev; }; +/* + * This function looks for a board matching the supplied PCI device. + */ +static const struct pc263_board *pc263_find_pci_board(struct pci_dev *pci_dev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) + if (pc263_boards[i].bustype == pci_bustype && + pci_dev->device == pc263_boards[i].devid) + return &pc263_boards[i]; + return NULL; +} + + /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -124,21 +139,13 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot) continue; } if (thisboard->model == anypci_model) { - /* Match any supported model. */ - int i; - - for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) { - if (pc263_boards[i].bustype != pci_bustype) - continue; - if (pci_dev->device == pc263_boards[i].devid) { - /* Change board_ptr to matched board. */ - dev->board_ptr = &pc263_boards[i]; - thisboard = comedi_board(dev); - break; - } - } - if (i == ARRAY_SIZE(pc263_boards)) + /* Wildcard board matches any supported PCI board. */ + const struct pc263_board *foundboard; + foundboard = pc263_find_pci_board(pci_dev); + if (foundboard == NULL) continue; + /* Replace wildcard board_ptr. */ + dev->board_ptr = thisboard = foundboard; } else { /* Match specific model name. */ if (pci_dev->device != thisboard->devid) @@ -211,6 +218,54 @@ static void pc263_report_attach(struct comedi_device *dev) dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf); } +static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase) +{ + const struct pc263_board *thisboard = comedi_board(dev); + struct comedi_subdevice *s; + int ret; + + dev->board_name = thisboard->name; + dev->iobase = iobase; + + ret = alloc_subdevices(dev, 1); + if (ret < 0) { + dev_err(dev->class_dev, "error! out of memory!\n"); + return ret; + } + + s = dev->subdevices + 0; + /* digital output subdevice */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pc263_do_insn_bits; + /* read initial relay state */ + s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); + + pc263_report_attach(dev); + return 1; +} + +static int pc263_pci_common_attach(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + struct pc263_private *devpriv = dev->private; + unsigned long iobase; + int ret; + + devpriv->pci_dev = pci_dev; + ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); + if (ret < 0) { + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); + return ret; + } + iobase = pci_resource_start(pci_dev, 2); + return pc263_common_attach(dev, iobase); +} + /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -220,8 +275,6 @@ static void pc263_report_attach(struct comedi_device *dev) static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pc263_board *thisboard = comedi_board(dev); - struct comedi_subdevice *s; - unsigned long iobase = 0; int ret; dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach\n"); @@ -229,14 +282,14 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Process options and reserve resources according to bus type. */ if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA) && thisboard->bustype == isa_bustype) { - iobase = it->options[0]; + unsigned long iobase = it->options[0]; ret = pc263_request_region(dev, iobase, PC263_IO_SIZE); if (ret < 0) return ret; + return pc263_common_attach(dev, iobase); } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) && thisboard->bustype == pci_bustype) { - struct pc263_private *devpriv; - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; int bus, slot; ret = alloc_private(dev, sizeof(struct pc263_private)); @@ -244,49 +297,44 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } - devpriv = dev->private; bus = it->options[0]; slot = it->options[1]; pci_dev = pc263_find_pci(dev, bus, slot); if (pci_dev == NULL) return -EIO; - thisboard = comedi_board(dev); /* replaced wildcard board */ - devpriv->pci_dev = pci_dev; - ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); - return ret; - } - iobase = pci_resource_start(pci_dev, 2); + return pc263_pci_common_attach(dev, pci_dev); } else { dev_err(dev->class_dev, PC263_DRIVER_NAME ": BUG! cannot determine board type!\n"); return -EINVAL; } +} +/* + * The attach_pci hook (if non-NULL) is called at PCI probe time in preference + * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should + * be a board entry matching the supplied PCI device. + */ +static int __devinit pc263_attach_pci(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + int ret; - dev->board_name = thisboard->name; - dev->iobase = iobase; + if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI)) + return -EINVAL; - ret = alloc_subdevices(dev, 1); + dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach pci %s\n", + pci_name(pci_dev)); + ret = alloc_private(dev, sizeof(struct pc263_private)); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } - - s = dev->subdevices + 0; - /* digital output subdevice */ - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = pc263_do_insn_bits; - /* read initial relay state */ - s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); - - pc263_report_attach(dev); - return 1; + dev->board_ptr = pc263_find_pci_board(pci_dev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + return pc263_pci_common_attach(dev, pci_dev); } static void pc263_detach(struct comedi_device *dev) @@ -314,6 +362,7 @@ static struct comedi_driver amplc_pc263_driver = { .driver_name = PC263_DRIVER_NAME, .module = THIS_MODULE, .attach = pc263_attach, + .attach_pci = pc263_attach_pci, .detach = pc263_detach, .board_name = &pc263_boards[0].name, .offset = sizeof(struct pc263_board), -- GitLab From a6e11e3b9ffe994f1f2f8ab74ebdc9d1937c16e0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:31 +0100 Subject: [PATCH 0403/6849] staging: comedi: amplc_dio200: Use IS_ENABLED() Change conditional compilation on kernel options to use the IS_ENABLED() macro. Remove most of the #ifdef lines and add extra if (IS_ENABLED(xxx)) tests so the compiler can remove unreachable code. The pci_driver stuff and device table and some of the static const data is still conditionally compiled. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 122 ++++++------------ 1 file changed, 41 insertions(+), 81 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index f6f6144344b4..95d4370bf7af 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -215,14 +215,6 @@ order they appear in the channel list. #define DIO200_DRIVER_NAME "amplc_dio200" -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA_MODULE -#define CONFIG_COMEDI_AMPLC_DIO200_ISA -#endif - -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI_MODULE -#define CONFIG_COMEDI_AMPLC_DIO200_PCI -#endif - /* PCI IDs */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a @@ -280,12 +272,12 @@ enum dio200_model { }; enum dio200_layout { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) pc212_layout, pc214_layout, #endif pc215_layout, -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) pc218_layout, #endif pc272_layout @@ -300,7 +292,7 @@ struct dio200_board { }; static const struct dio200_board dio200_boards[] = { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) { .name = "pc212e", .bustype = isa_bustype, @@ -332,7 +324,7 @@ static const struct dio200_board dio200_boards[] = { .layout = pc272_layout, }, #endif -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) { .name = "pci215", .devid = PCI_DEVICE_ID_AMPLICON_PCI215, @@ -375,7 +367,7 @@ struct dio200_layout_struct { }; static const struct dio200_layout_struct dio200_layouts[] = { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) [pc212_layout] = { .n_subdevs = 6, .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, @@ -404,7 +396,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 1, }, -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) [pc218_layout] = { .n_subdevs = 7, .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, @@ -431,7 +423,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { * PCI driver table. */ -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, @@ -453,9 +445,7 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table); feel free to suggest moving the variable to the struct comedi_device struct. */ struct dio200_private { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI struct pci_dev *pci_dev; /* PCI device */ -#endif int intr_sd; }; @@ -502,7 +492,7 @@ static struct comedi_driver driver_amplc_dio200 = { .num_names = ARRAY_SIZE(dio200_boards), }; -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -561,7 +551,6 @@ module_exit(driver_amplc_dio200_cleanup_module); * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static int dio200_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -617,13 +606,11 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, } return -EIO; } -#endif /* * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA static int dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -634,7 +621,6 @@ dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) } return 0; } -#endif /* * 'insn_bits' function for an 'INTERRUPT' subdevice. @@ -1346,10 +1332,6 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI - struct pci_dev *pci_dev = NULL; - int bus = 0, slot = 0; -#endif const struct dio200_layout_struct *layout; int share_irq = 0; int sdx; @@ -1366,40 +1348,27 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } - /* Process options. */ - switch (thisboard->bustype) { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA - case isa_bustype: + /* Process options and reserve resources according to bus type. */ + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && + thisboard->bustype == isa_bustype) { iobase = it->options[0]; irq = it->options[1]; share_irq = 0; - break; -#endif -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI - case pci_bustype: + ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); + if (ret < 0) + return ret; + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && + thisboard->bustype == pci_bustype) { + struct pci_dev *pci_dev = NULL; + int bus, slot; + bus = it->options[0]; slot = it->options[1]; share_irq = 1; - ret = dio200_find_pci(dev, bus, slot, &pci_dev); if (ret < 0) return ret; devpriv->pci_dev = pci_dev; - break; -#endif - default: - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, DIO200_DRIVER_NAME); - return -EINVAL; - break; - } - - devpriv->intr_sd = -1; - - /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI - if (pci_dev) { ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { printk(KERN_ERR @@ -1409,15 +1378,15 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } iobase = pci_resource_start(pci_dev, 2); irq = pci_dev->irq; - } else -#endif - { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA - ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); - if (ret < 0) - return ret; -#endif + } else { + printk(KERN_ERR + "comedi%d: %s: BUG! cannot determine board type!\n", + dev->minor, DIO200_DRIVER_NAME); + return -EINVAL; } + + devpriv->intr_sd = -1; + dev->iobase = iobase; layout = thislayout; @@ -1492,20 +1461,12 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - switch (thisboard->bustype) { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA - case isa_bustype: + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && + thisboard->bustype == isa_bustype) printk("(base %#lx) ", iobase); - break; -#endif -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI - case pci_bustype: - printk("(pci %s) ", pci_name(pci_dev)); - break; -#endif - default: - break; - } + else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && + thisboard->bustype == pci_bustype) + printk("(pci %s) ", pci_name(devpriv->pci_dev)); if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); else @@ -1543,18 +1504,17 @@ static void dio200_detach(struct comedi_device *dev) } } if (devpriv) { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI - if (devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } else -#endif - { -#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && + thisboard->bustype == pci_bustype) { + if (devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && + thisboard->bustype == isa_bustype) { if (dev->iobase) release_region(dev->iobase, DIO200_IO_SIZE); -#endif } } } -- GitLab From d22e9306c3e119ebc058d5b77306042d6603b231 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:32 +0100 Subject: [PATCH 0404/6849] staging: comedi: amplc_dio200: Use module_comedi_{pci,}_driver() If PCI boards are supported, use the module_comedi_pci_driver() macro to register the module as a comedi driver and a PCI driver. Otherwise, only ISA boards are supported so use the module_comedi_driver() macro to register the module as a comedi driver. Renamed 'driver_amplc_dio200' to 'amplc_dio200_driver' and removed 'driver_' prefix from PCI related functions and variables, purely for aesthetic reasons. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 51 ++++--------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 95d4370bf7af..598e51a0cd21 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -482,7 +482,7 @@ struct dio200_subdev_intr { static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void dio200_detach(struct comedi_device *dev); -static struct comedi_driver driver_amplc_dio200 = { +static struct comedi_driver amplc_dio200_driver = { .driver_name = DIO200_DRIVER_NAME, .module = THIS_MODULE, .attach = dio200_attach, @@ -493,58 +493,27 @@ static struct comedi_driver driver_amplc_dio200 = { }; #if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) -static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev, +static int __devinit amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_amplc_dio200); + return comedi_pci_auto_config(dev, &lc_dio200_driver); } -static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev) +static void __devexit amplc_dio200_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_amplc_dio200_pci_driver = { +static struct pci_driver amplc_dio200_pci_driver = { + .name = DIO200_DRIVER_NAME, .id_table = dio200_pci_table, - .probe = &driver_amplc_dio200_pci_probe, - .remove = __devexit_p(&driver_amplc_dio200_pci_remove) + .probe = &lc_dio200_pci_probe, + .remove = __devexit_p(&lc_dio200_pci_remove) }; - -static int __init driver_amplc_dio200_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_amplc_dio200); - if (retval < 0) - return retval; - - driver_amplc_dio200_pci_driver.name = - (char *)driver_amplc_dio200.driver_name; - return pci_register_driver(&driver_amplc_dio200_pci_driver); -} - -static void __exit driver_amplc_dio200_cleanup_module(void) -{ - pci_unregister_driver(&driver_amplc_dio200_pci_driver); - comedi_driver_unregister(&driver_amplc_dio200); -} - -module_init(driver_amplc_dio200_init_module); -module_exit(driver_amplc_dio200_cleanup_module); +module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver); #else -static int __init driver_amplc_dio200_init_module(void) -{ - return comedi_driver_register(&driver_amplc_dio200); -} - -static void __exit driver_amplc_dio200_cleanup_module(void) -{ - comedi_driver_unregister(&driver_amplc_dio200); -} - -module_init(driver_amplc_dio200_init_module); -module_exit(driver_amplc_dio200_cleanup_module); +module_comedi_driver(amplc_dio200_driver); #endif /* -- GitLab From fd97962b4142fc3460d3628c3842be6d33b9aa94 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:33 +0100 Subject: [PATCH 0405/6849] staging: comedi: amplc_dio200: Remove forward function declarations Moved some functions and variables to avoid forward declarations. Moved PCI table closer to the struct pci_driver that refers to it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 105 ++++++++---------- 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 598e51a0cd21..8b31ab9ce90f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -419,20 +419,6 @@ static const struct dio200_layout_struct dio200_layouts[] = { }, }; -/* - * PCI driver table. - */ - -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) -static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, dio200_pci_table); -#endif /* CONFIG_COMEDI_AMPLC_DIO200_PCI */ - /* * Useful for shorthand access to the particular board structure */ @@ -473,49 +459,6 @@ struct dio200_subdev_intr { int continuous; }; -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int dio200_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static void dio200_detach(struct comedi_device *dev); -static struct comedi_driver amplc_dio200_driver = { - .driver_name = DIO200_DRIVER_NAME, - .module = THIS_MODULE, - .attach = dio200_attach, - .detach = dio200_detach, - .board_name = &dio200_boards[0].name, - .offset = sizeof(struct dio200_board), - .num_names = ARRAY_SIZE(dio200_boards), -}; - -#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) -static int __devinit amplc_dio200_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) -{ - return comedi_pci_auto_config(dev, &lc_dio200_driver); -} - -static void __devexit amplc_dio200_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver amplc_dio200_pci_driver = { - .name = DIO200_DRIVER_NAME, - .id_table = dio200_pci_table, - .probe = &lc_dio200_pci_probe, - .remove = __devexit_p(&lc_dio200_pci_remove) -}; -module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver); -#else -module_comedi_driver(amplc_dio200_driver); -#endif - /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -1488,6 +1431,54 @@ static void dio200_detach(struct comedi_device *dev) } } +/* + * The struct comedi_driver structure tells the Comedi core module + * which functions to call to configure/deconfigure (attach/detach) + * the board, and also about the kernel module that contains + * the device code. + */ +static struct comedi_driver amplc_dio200_driver = { + .driver_name = DIO200_DRIVER_NAME, + .module = THIS_MODULE, + .attach = dio200_attach, + .detach = dio200_detach, + .board_name = &dio200_boards[0].name, + .offset = sizeof(struct dio200_board), + .num_names = ARRAY_SIZE(dio200_boards), +}; + +#if IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) +static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, + {0} +}; + +MODULE_DEVICE_TABLE(pci, dio200_pci_table); + +static int __devinit amplc_dio200_pci_probe(struct pci_dev *dev, + const struct pci_device_id + *ent) +{ + return comedi_pci_auto_config(dev, &lc_dio200_driver); +} + +static void __devexit amplc_dio200_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver amplc_dio200_pci_driver = { + .name = DIO200_DRIVER_NAME, + .id_table = dio200_pci_table, + .probe = &lc_dio200_pci_probe, + .remove = __devexit_p(&lc_dio200_pci_remove) +}; +module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver); +#else +module_comedi_driver(amplc_dio200_driver); +#endif + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- GitLab From 485455d01b26e849d30c2b20ce20a4d6fc50555e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:34 +0100 Subject: [PATCH 0406/6849] staging: comedi: amplc_dio200: Replace printk calls Replace the printk calls with dev_info, dev_err, etc. There were some consecutive printk calls without newlines which now scnprintf into a temporary buffer and this bit of code has been factored out into new function dio200_report_attach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 89 ++++++++++--------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 8b31ab9ce90f..be932e88895a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -509,12 +509,12 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, } /* No match found. */ if (bus || slot) { - printk(KERN_ERR - "comedi%d: error! no %s found at pci %02x:%02x!\n", - dev->minor, thisboard->name, bus, slot); + dev_err(dev->class_dev, + "error! no %s found at pci %02x:%02x!\n", + thisboard->name, bus, slot); } else { - printk(KERN_ERR "comedi%d: error! no %s found!\n", - dev->minor, thisboard->name); + dev_err(dev->class_dev, "error! no %s found!\n", + thisboard->name); } return -EIO; } @@ -524,11 +524,12 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, * if there is a conflict. */ static int -dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) +dio200_request_region(struct comedi_device *dev, + unsigned long from, unsigned long extent) { if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) { - printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", - minor, from, extent); + dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n", + from, extent); return -EIO; } return 0; @@ -926,8 +927,7 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); if (!subpriv) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return -ENOMEM; } subpriv->iobase = iobase; @@ -1180,8 +1180,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); if (!subpriv) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return -ENOMEM; } @@ -1233,6 +1232,31 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev, kfree(subpriv); } +static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) +{ + char tmpbuf[60]; + int tmplen; + + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && + thisboard->bustype == isa_bustype) + tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), + "(base %#lx) ", dev->iobase); + else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && + thisboard->bustype == pci_bustype) + tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), + "(pci %s) ", pci_name(devpriv->pci_dev)); + else + tmplen = 0; + if (irq) + tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen, + "(irq %u%s) ", irq, + (dev->irq ? "" : " UNAVAILABLE")); + else + tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen, + "(no irq) "); + dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf); +} + /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -1250,13 +1274,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned n; int ret; - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, - DIO200_DRIVER_NAME); + dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n"); ret = alloc_private(dev, sizeof(struct dio200_private)); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } @@ -1266,7 +1288,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; irq = it->options[1]; share_irq = 0; - ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); + ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); if (ret < 0) return ret; } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && @@ -1283,17 +1305,15 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { - printk(KERN_ERR - "comedi%d: error! cannot enable PCI device and request regions!\n", - dev->minor); + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); return ret; } iobase = pci_resource_start(pci_dev, 2); irq = pci_dev->irq; } else { - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, DIO200_DRIVER_NAME); + dev_err(dev->class_dev, DIO200_DRIVER_NAME + ": BUG! cannot determine board type!\n"); return -EINVAL; } @@ -1305,8 +1325,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = alloc_subdevices(dev, layout->n_subdevs); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } @@ -1366,26 +1385,12 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) DIO200_DRIVER_NAME, dev) >= 0) { dev->irq = irq; } else { - printk(KERN_WARNING - "comedi%d: warning! irq %u unavailable!\n", - dev->minor, irq); + dev_warn(dev->class_dev, + "warning! irq %u unavailable!\n", irq); } } - printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && - thisboard->bustype == isa_bustype) - printk("(base %#lx) ", iobase); - else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && - thisboard->bustype == pci_bustype) - printk("(pci %s) ", pci_name(devpriv->pci_dev)); - if (irq) - printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - else - printk("(no irq) "); - - printk("attached\n"); - + dio200_report_attach(dev, irq); return 1; } -- GitLab From 181ad5edbf6d3c244263b770e9dd4eda645de5bf Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:35 +0100 Subject: [PATCH 0407/6849] staging: comedi: amplc_dio200: Change return type of dio200_find_pci() dio200_find_pci() finds a supported PCI device, returning 0 on success or -EIO on failure and returning the pointer to the PCI device via a struct pci_dev ** parameter. Change it to return the struct pci_dev * on success or NULL on failure. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index be932e88895a..6d04378f553f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -463,14 +463,11 @@ struct dio200_subdev_intr { * This function looks for a PCI device matching the requested board name, * bus and slot. */ -static int -dio200_find_pci(struct comedi_device *dev, int bus, int slot, - struct pci_dev **pci_dev_p) +static struct pci_dev * +dio200_find_pci(struct comedi_device *dev, int bus, int slot) { struct pci_dev *pci_dev = NULL; - *pci_dev_p = NULL; - /* Look for matching PCI device. */ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL); pci_dev != NULL; @@ -504,8 +501,7 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, } /* Found a match. */ - *pci_dev_p = pci_dev; - return 0; + return pci_dev; } /* No match found. */ if (bus || slot) { @@ -516,7 +512,7 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, dev_err(dev->class_dev, "error! no %s found!\n", thisboard->name); } - return -EIO; + return NULL; } /* @@ -1293,15 +1289,15 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && thisboard->bustype == pci_bustype) { - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; int bus, slot; bus = it->options[0]; slot = it->options[1]; share_irq = 1; - ret = dio200_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; + pci_dev = dio200_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { -- GitLab From adb4601a82343e846997320b41d5b7d49137fe42 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:36 +0100 Subject: [PATCH 0408/6849] staging: comedi: amplc_dio200: Remove thisboard, thislayout and devpriv macros The 'thisboard', 'thislayout' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macros with local variables wherever they occur. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6d04378f553f..5b8c6775dbc9 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -419,13 +419,6 @@ static const struct dio200_layout_struct dio200_layouts[] = { }, }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct dio200_board *)dev->board_ptr) -#define thislayout (&dio200_layouts[((struct dio200_board *) \ - dev->board_ptr)->layout]) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. @@ -435,8 +428,6 @@ struct dio200_private { int intr_sd; }; -#define devpriv ((struct dio200_private *)dev->private) - struct dio200_subdev_8254 { unsigned long iobase; /* Counter base address */ unsigned long clk_sce_iobase; /* CLK_SCE base address */ @@ -466,6 +457,7 @@ struct dio200_subdev_intr { static struct pci_dev * dio200_find_pci(struct comedi_device *dev, int bus, int slot) { + const struct dio200_board *thisboard = comedi_board(dev); struct pci_dev *pci_dev = NULL; /* Look for matching PCI device. */ @@ -489,6 +481,7 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot) if (pci_dev->device == dio200_boards[i].devid) { /* Change board_ptr to matched board. */ dev->board_ptr = &dio200_boards[i]; + thisboard = comedi_board(dev); break; } } @@ -972,6 +965,7 @@ dio200_subdev_intr_cleanup(struct comedi_device *dev, static irqreturn_t dio200_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct dio200_private *devpriv = dev->private; int handled; if (!dev->attached) @@ -1230,6 +1224,8 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev, static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) { + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; char tmpbuf[60]; int tmplen; @@ -1261,6 +1257,8 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) */ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; @@ -1277,6 +1275,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } + devpriv = dev->private; /* Process options and reserve resources according to bus type. */ if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && @@ -1298,6 +1297,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) pci_dev = dio200_find_pci(dev, bus, slot); if (pci_dev == NULL) return -EIO; + thisboard = comedi_board(dev); /* replaced wildcard board */ devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { @@ -1317,7 +1317,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; - layout = thislayout; + layout = &dio200_layouts[thisboard->layout]; ret = alloc_subdevices(dev, layout->n_subdevs); if (ret < 0) { @@ -1392,13 +1392,15 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dio200_detach(struct comedi_device *dev) { + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; const struct dio200_layout_struct *layout; unsigned n; if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { - layout = thislayout; + layout = &dio200_layouts[thisboard->layout]; for (n = 0; n < dev->n_subdevices; n++) { struct comedi_subdevice *s = &dev->subdevices[n]; switch (layout->sdtype[n]) { -- GitLab From c894ec8da05aa8a58830297d1564675f3e1174cc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 14:08:37 +0100 Subject: [PATCH 0409/6849] staging: comedi: amplc_dio200: Add attach_pci() hook Implement the attach_pci() hook as function dio200_attach_pci(). This is called by comedi_pci_auto_config() in preference to the old attach() hook (implemented by dio200_attach()) and avoids searching for the probed PCI device. Factor out code common to dio200_find_pci() and dio200_attach_pci() into new function dio200_find_pci_board(). Factor out most code common to dio200_attach() and dio200_attach_pci() into new functions dio200_pci_common_attach() and dio200_common_attach(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 215 +++++++++++------- 1 file changed, 127 insertions(+), 88 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 5b8c6775dbc9..3afebb24b26b 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -450,6 +450,21 @@ struct dio200_subdev_intr { int continuous; }; +/* + * This function looks for a board matching the supplied PCI device. + */ +static const struct dio200_board * +dio200_find_pci_board(struct pci_dev *pci_dev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) + if (dio200_boards[i].bustype == pci_bustype && + pci_dev->device == dio200_boards[i].devid) + return &dio200_boards[i]; + return NULL; +} + /* * This function looks for a PCI device matching the requested board name, * bus and slot. @@ -472,21 +487,15 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot) continue; } if (thisboard->model == anypci_model) { - /* Match any supported model. */ - int i; - - for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) { - if (dio200_boards[i].bustype != pci_bustype) - continue; - if (pci_dev->device == dio200_boards[i].devid) { - /* Change board_ptr to matched board. */ - dev->board_ptr = &dio200_boards[i]; - thisboard = comedi_board(dev); - break; - } - } - if (i == ARRAY_SIZE(dio200_boards)) + /* Wildcard board matches any supported PCI board. */ + const struct dio200_board *foundboard; + + foundboard = dio200_find_pci_board(pci_dev); + if (foundboard == NULL) continue; + /* Replace wildcard board_ptr. */ + dev->board_ptr = foundboard; + thisboard = comedi_board(dev); } else { /* Match specific model name. */ if (pci_dev->device != thisboard->devid) @@ -1249,82 +1258,26 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf); } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, + unsigned int irq, unsigned long req_irq_flags) { const struct dio200_board *thisboard = comedi_board(dev); - struct dio200_private *devpriv; + struct dio200_private *devpriv = dev->private; + const struct dio200_layout_struct *layout = + &dio200_layouts[thisboard->layout]; struct comedi_subdevice *s; - unsigned long iobase = 0; - unsigned int irq = 0; - const struct dio200_layout_struct *layout; - int share_irq = 0; int sdx; - unsigned n; + unsigned int n; int ret; - dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n"); - - ret = alloc_private(dev, sizeof(struct dio200_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } - devpriv = dev->private; - - /* Process options and reserve resources according to bus type. */ - if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && - thisboard->bustype == isa_bustype) { - iobase = it->options[0]; - irq = it->options[1]; - share_irq = 0; - ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); - if (ret < 0) - return ret; - } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && - thisboard->bustype == pci_bustype) { - struct pci_dev *pci_dev; - int bus, slot; - - bus = it->options[0]; - slot = it->options[1]; - share_irq = 1; - pci_dev = dio200_find_pci(dev, bus, slot); - if (pci_dev == NULL) - return -EIO; - thisboard = comedi_board(dev); /* replaced wildcard board */ - devpriv->pci_dev = pci_dev; - ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); - return ret; - } - iobase = pci_resource_start(pci_dev, 2); - irq = pci_dev->irq; - } else { - dev_err(dev->class_dev, DIO200_DRIVER_NAME - ": BUG! cannot determine board type!\n"); - return -EINVAL; - } - devpriv->intr_sd = -1; - dev->iobase = iobase; - - layout = &dio200_layouts[thisboard->layout]; - + dev->board_name = thisboard->name; ret = alloc_subdevices(dev, layout->n_subdevs); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } - for (n = 0; n < dev->n_subdevices; n++) { s = &dev->subdevices[n]; switch (layout->sdtype[n]) { @@ -1335,7 +1288,6 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) layout->has_clk_gat_sce); if (ret < 0) return ret; - break; case sd_8255: /* digital i/o subdevice (8255) */ @@ -1343,7 +1295,6 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase + layout->sdinfo[n]); if (ret < 0) return ret; - break; case sd_intr: /* 'INTERRUPT' subdevice */ @@ -1356,7 +1307,6 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) has_int_sce); if (ret < 0) return ret; - devpriv->intr_sd = n; } else { s->type = COMEDI_SUBD_UNUSED; @@ -1367,17 +1317,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; } } - sdx = devpriv->intr_sd; if (sdx >= 0 && sdx < dev->n_subdevices) dev->read_subdev = &dev->subdevices[sdx]; - - dev->board_name = thisboard->name; - if (irq) { - unsigned long flags = share_irq ? IRQF_SHARED : 0; - - if (request_irq(irq, dio200_interrupt, flags, + if (request_irq(irq, dio200_interrupt, req_irq_flags, DIO200_DRIVER_NAME, dev) >= 0) { dev->irq = irq; } else { @@ -1385,11 +1329,105 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) "warning! irq %u unavailable!\n", irq); } } - dio200_report_attach(dev, irq); return 1; } +static int dio200_pci_common_attach(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + struct dio200_private *devpriv = dev->private; + unsigned long iobase; + int ret; + + devpriv->pci_dev = pci_dev; + ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); + if (ret < 0) { + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); + return ret; + } + iobase = pci_resource_start(pci_dev, 2); + return dio200_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); +} + +/* + * Attach is called by the Comedi core to configure the driver + * for a particular board. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that + * address. + */ +static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct dio200_board *thisboard = comedi_board(dev); + int ret; + + dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n"); + + ret = alloc_private(dev, sizeof(struct dio200_private)); + if (ret < 0) { + dev_err(dev->class_dev, "error! out of memory!\n"); + return ret; + } + + /* Process options and reserve resources according to bus type. */ + if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA) && + thisboard->bustype == isa_bustype) { + unsigned long iobase; + unsigned int irq; + + iobase = it->options[0]; + irq = it->options[1]; + ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); + if (ret < 0) + return ret; + return dio200_common_attach(dev, iobase, irq, 0); + } else if (IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) && + thisboard->bustype == pci_bustype) { + struct pci_dev *pci_dev; + int bus, slot; + + bus = it->options[0]; + slot = it->options[1]; + pci_dev = dio200_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; + return dio200_pci_common_attach(dev, pci_dev); + } else { + dev_err(dev->class_dev, DIO200_DRIVER_NAME + ": BUG! cannot determine board type!\n"); + return -EINVAL; + } +} + +/* + * The attach_pci hook (if non-NULL) is called at PCI probe time in preference + * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should + * be a board entry matching the supplied PCI device. + */ +static int __devinit dio200_attach_pci(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + int ret; + + if (!IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI)) + return -EINVAL; + + dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n", + pci_name(pci_dev)); + ret = alloc_private(dev, sizeof(struct dio200_private)); + if (ret < 0) { + dev_err(dev->class_dev, "error! out of memory!\n"); + return ret; + } + dev->board_ptr = dio200_find_pci_board(pci_dev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + return dio200_pci_common_attach(dev, pci_dev); +} + static void dio200_detach(struct comedi_device *dev) { const struct dio200_board *thisboard = comedi_board(dev); @@ -1444,6 +1482,7 @@ static struct comedi_driver amplc_dio200_driver = { .driver_name = DIO200_DRIVER_NAME, .module = THIS_MODULE, .attach = dio200_attach, + .attach_pci = dio200_attach_pci, .detach = dio200_detach, .board_name = &dio200_boards[0].name, .offset = sizeof(struct dio200_board), -- GitLab From 52954abcee66f9a3c5c2416a89c8b2affd2f5a2b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 16:02:02 +0100 Subject: [PATCH 0410/6849] staging: comedi: amplc_pci224: __devinit pci224_attach_pci() pci224_attach_pci() is only called during PCI probe, indirectly via comedi_pci_auto_config(), so it can be marked __devinit. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 0d1f9cc50ef3..96a9d341fa15 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1495,7 +1495,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) return pci224_attach_common(dev, pci_dev, it->options); } -static int +static int __devinit pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { int ret; -- GitLab From eedc1b7be2ea7c8350f359ff9afa568cb89a70d7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 16:02:03 +0100 Subject: [PATCH 0411/6849] staging: comedi: amplc_pci224: Replace printk calls Replace the printk calls with dev_info, dev_err, etc. There were some consecutive printk calls without newlines which now scnprintf into a temporary buffer and this bit of code has been factored out into new function pci224_report_attach(). A couple of DPRINTK() macro calls which may result in printk() calls have been left alone to be tackled en masse at a later date. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 80 +++++++++---------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 96a9d341fa15..a07546e0622e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -626,8 +626,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, /* Nothing left to put in the FIFO. */ pci224_ao_stop(dev, s); s->async->events |= COMEDI_CB_OVERFLOW; - printk(KERN_ERR "comedi%d: " - "AO buffer underrun\n", dev->minor); + dev_err(dev->class_dev, "AO buffer underrun\n"); } } /* Determine how many new scans can be put in the FIFO. */ @@ -1295,16 +1294,29 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, } /* No match found. */ if (bus || slot) { - printk(KERN_ERR "comedi%d: error! " - "no %s found at pci %02x:%02x!\n", - dev->minor, thisboard->name, bus, slot); + dev_err(dev->class_dev, + "error! no %s found at pci %02x:%02x!\n", + thisboard->name, bus, slot); } else { - printk(KERN_ERR "comedi%d: error! no %s found!\n", - dev->minor, thisboard->name); + dev_err(dev->class_dev, "error! no %s found!\n", + thisboard->name); } return -EIO; } +static void pci224_report_attach(struct comedi_device *dev, unsigned int irq) +{ + char tmpbuf[30]; + + if (irq) + snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq, + (dev->irq ? "" : " UNAVAILABLE")); + else + snprintf(tmpbuf, sizeof(tmpbuf), "no irq"); + dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n", + dev->board_name, pci_name(devpriv->pci_dev), tmpbuf); +} + /* * Common part of attach and attach_pci. */ @@ -1319,9 +1331,9 @@ static int pci224_attach_common(struct comedi_device *dev, devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, DRIVER_NAME); if (ret < 0) { - printk(KERN_ERR - "comedi%d: error! cannot enable PCI device " - "and request regions!\n", dev->minor); + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n" + ); return ret; } spin_lock_init(&devpriv->ao_spinlock); @@ -1368,8 +1380,7 @@ static int pci224_attach_common(struct comedi_device *dev, /* Allocate subdevices. There is only one! */ ret = alloc_subdevices(dev, 1); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } @@ -1403,10 +1414,9 @@ static int pci224_attach_common(struct comedi_device *dev, if (options) { for (n = 2; n < 3 + s->n_chan; n++) { if (options[n] < 0 || options[n] > 1) { - printk(KERN_WARNING - "comedi%d: %s: warning! bad options[%u]=%d\n", - dev->minor, DRIVER_NAME, n, - options[n]); + dev_warn(dev->class_dev, DRIVER_NAME + ": warning! bad options[%u]=%d\n", + n, options[n]); } } } @@ -1435,9 +1445,9 @@ static int pci224_attach_common(struct comedi_device *dev, devpriv->hwrange = hwrange_pci224_external; } else { if (options && options[2] != 0) { - printk(KERN_WARNING "comedi%d: %s: warning! " - "bad options[2]=%d\n", - dev->minor, DRIVER_NAME, options[2]); + dev_warn(dev->class_dev, DRIVER_NAME + ": warning! bad options[2]=%d\n", + options[2]); } s->range_table = &range_pci224_internal; devpriv->hwrange = hwrange_pci224_internal; @@ -1450,24 +1460,15 @@ static int pci224_attach_common(struct comedi_device *dev, ret = request_irq(irq, pci224_interrupt, IRQF_SHARED, DRIVER_NAME, dev); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! " - "unable to allocate irq %u\n", dev->minor, irq); + dev_err(dev->class_dev, + "error! unable to allocate irq %u\n", irq); return ret; } else { dev->irq = irq; } } - printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - printk("(pci %s) ", pci_name(pci_dev)); - if (irq) - printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - else - printk("(no irq) "); - - - printk("attached\n"); - + pci224_report_attach(dev, irq); return 1; } @@ -1477,14 +1478,13 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) int bus, slot; int ret; - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME); + dev_info(dev->class_dev, DRIVER_NAME ": attach\n"); bus = it->options[0]; slot = it->options[1]; ret = alloc_private(dev, sizeof(struct pci224_private)); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } @@ -1500,21 +1500,19 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { int ret; - printk(KERN_DEBUG "comedi%d: %s: attach_pci %s\n", dev->minor, - DRIVER_NAME, pci_name(pci_dev)); + dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n", + pci_name(pci_dev)); ret = alloc_private(dev, sizeof(struct pci224_private)); if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); + dev_err(dev->class_dev, "error! out of memory!\n"); return ret; } dev->board_ptr = pci224_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { - printk(KERN_ERR - "comedi%d: %s: BUG! cannot determine board type!\n", - dev->minor, DRIVER_NAME); + dev_err(dev->class_dev, + DRIVER_NAME ": BUG! cannot determine board type!\n"); return -EINVAL; } return pci224_attach_common(dev, pci_dev, NULL); -- GitLab From 01ea83bce2d5219a71a044a084e3cecd6f0ad28e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 16:02:04 +0100 Subject: [PATCH 0412/6849] staging: comedi: amplc_pci224: Change return type of pci224_find_pci() pci224_find_pci() finds a supported PCI device, returning 0 on success or -EIO on failure and returning the pointer to the PCI device via a struct pci_dev ** parameter. Change it to return the struct pci_dev * on success or NULL on failure. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index a07546e0622e..4c41c289696c 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1255,14 +1255,11 @@ static const struct pci224_board * This function looks for a PCI device matching the requested board name, * bus and slot. */ -static int -pci224_find_pci(struct comedi_device *dev, int bus, int slot, - struct pci_dev **pci_dev_p) +static struct pci_dev * +pci224_find_pci(struct comedi_device *dev, int bus, int slot) { struct pci_dev *pci_dev = NULL; - *pci_dev_p = NULL; - /* Look for matching PCI device. */ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL); pci_dev != NULL; @@ -1289,8 +1286,7 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, } /* Found a match. */ - *pci_dev_p = pci_dev; - return 0; + return pci_dev; } /* No match found. */ if (bus || slot) { @@ -1301,7 +1297,7 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, dev_err(dev->class_dev, "error! no %s found!\n", thisboard->name); } - return -EIO; + return NULL; } static void pci224_report_attach(struct comedi_device *dev, unsigned int irq) @@ -1488,9 +1484,9 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } - ret = pci224_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; + pci_dev = pci224_find_pci(dev, bus, slot); + if (pci_dev == NULL) + return -EIO; return pci224_attach_common(dev, pci_dev, it->options); } -- GitLab From 9dc5a822ea8eaa2397f95aace504fcc657a6cd8b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 16:02:05 +0100 Subject: [PATCH 0413/6849] staging: comedi: amplc_pci224: Remove thisboard and devpriv macros The 'thisboard' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macros with local variables wherever they occur. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4c41c289696c..43f07f8f365e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -377,11 +377,6 @@ static const struct pci224_board pci224_boards[] = { }, }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((struct pci224_board *)dev->board_ptr) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. */ @@ -405,8 +400,6 @@ struct pci224_private { unsigned char intsce; }; -#define devpriv ((struct pci224_private *)dev->private) - /* * Called from the 'insn_write' function to perform a single write. */ @@ -414,6 +407,8 @@ static void pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int data) { + const struct pci224_board *thisboard = comedi_board(dev); + struct pci224_private *devpriv = dev->private; unsigned short mangled; /* Store unmangled data for readback. */ @@ -476,6 +471,7 @@ static int pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci224_private *devpriv = dev->private; int i; int chan; @@ -504,6 +500,7 @@ pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2, static void pci224_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci224_private *devpriv = dev->private; unsigned long flags; if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) @@ -547,6 +544,7 @@ static void pci224_ao_stop(struct comedi_device *dev, static void pci224_ao_start(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned long flags; @@ -575,6 +573,7 @@ static void pci224_ao_start(struct comedi_device *dev, static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int num_scans; unsigned int room; @@ -721,6 +720,7 @@ static int pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct pci224_private *devpriv = dev->private; int err = 0; unsigned int tmp; @@ -991,6 +991,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, */ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int range; unsigned int i, j; @@ -1163,6 +1164,8 @@ static void pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *data, unsigned int num_bytes, unsigned int chan_index) { + const struct pci224_board *thisboard = comedi_board(dev); + struct pci224_private *devpriv = dev->private; struct comedi_async *async = s->async; short *array = data; unsigned int length = num_bytes / sizeof(*array); @@ -1193,6 +1196,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, static irqreturn_t pci224_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct pci224_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; struct comedi_cmd *cmd; unsigned char intstat, valid_intstat; @@ -1258,6 +1262,7 @@ static const struct pci224_board static struct pci_dev * pci224_find_pci(struct comedi_device *dev, int bus, int slot) { + const struct pci224_board *thisboard = comedi_board(dev); struct pci_dev *pci_dev = NULL; /* Look for matching PCI device. */ @@ -1279,6 +1284,7 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot) continue; /* Change board_ptr to matched board. */ dev->board_ptr = board_ptr; + thisboard = comedi_board(dev); } else { /* Match specific model name. */ if (thisboard->devid != pci_dev->device) @@ -1302,6 +1308,7 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot) static void pci224_report_attach(struct comedi_device *dev, unsigned int irq) { + struct pci224_private *devpriv = dev->private; char tmpbuf[30]; if (irq) @@ -1319,6 +1326,8 @@ static void pci224_report_attach(struct comedi_device *dev, unsigned int irq) static int pci224_attach_common(struct comedi_device *dev, struct pci_dev *pci_dev, int *options) { + const struct pci224_board *thisboard = comedi_board(dev); + struct pci224_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned int irq; unsigned n; @@ -1516,6 +1525,8 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) static void pci224_detach(struct comedi_device *dev) { + struct pci224_private *devpriv = dev->private; + if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { -- GitLab From 4b05d17d8dcea60ccb1c39aaec60164dccdbc3e5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:39 +0100 Subject: [PATCH 0414/6849] staging: comedi: amplc_pci230: Replace printk calls Replace the printk calls with dev_info, dev_err, etc. A load of DPRINTK() macro calls which may result in printk() calls have been left alone to be tackled en masse at a later date. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index b05a684b80ba..512ead739895 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -697,8 +697,8 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pci_dev *pci_dev = NULL; int i = 0, irq_hdl, rc; - printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor, - thisboard->name, it->options[0], it->options[1]); + dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n", + thisboard->name, it->options[0], it->options[1]); /* Allocate the private structure area using alloc_private(). * Macro defined in comedidev.h - memsets struct fields to 0. */ @@ -772,8 +772,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } if (!pci_dev) { - printk("comedi%d: No %s card found\n", dev->minor, - thisboard->name); + dev_err(dev->class_dev, "No %s card found\n", thisboard->name); return -EIO; } devpriv->pci_dev = pci_dev; @@ -785,8 +784,8 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Enable PCI device and reserve I/O spaces. */ if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) { - printk("comedi%d: failed to enable PCI device " - "and request regions\n", dev->minor); + dev_err(dev->class_dev, + "failed to enable PCI device and request regions\n"); return -EIO; } @@ -795,8 +794,9 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase1 = pci_resource_start(pci_dev, 2); iobase2 = pci_resource_start(pci_dev, 3); - printk("comedi%d: %s I/O region 1 0x%04lx I/O region 2 0x%04lx\n", - dev->minor, dev->board_name, iobase1, iobase2); + dev_dbg(dev->class_dev, + "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n", + dev->board_name, iobase1, iobase2); devpriv->iobase1 = iobase1; dev->iobase = iobase2; @@ -811,10 +811,10 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->hwver = inw(dev->iobase + PCI230P_HWVER); if (devpriv->hwver < thisboard->min_hwver) { - printk("comedi%d: %s - bad hardware version " - "- got %u, need %u\n", dev->minor, - dev->board_name, devpriv->hwver, - thisboard->min_hwver); + dev_err(dev->class_dev, + "%s - bad hardware version - got %u, need %u\n", + dev->board_name, devpriv->hwver, + thisboard->min_hwver); return -EIO; } if (devpriv->hwver > 0) { @@ -862,13 +862,13 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq_hdl = request_irq(devpriv->pci_dev->irq, pci230_interrupt, IRQF_SHARED, "amplc_pci230", dev); if (irq_hdl < 0) { - printk("comedi%d: unable to register irq, " - "commands will not be available %d\n", dev->minor, - devpriv->pci_dev->irq); + dev_warn(dev->class_dev, + "unable to register irq %u, commands will not be available\n", + devpriv->pci_dev->irq); } else { dev->irq = devpriv->pci_dev->irq; - printk("comedi%d: registered irq %u\n", dev->minor, - devpriv->pci_dev->irq); + dev_dbg(dev->class_dev, "registered irq %u\n", + devpriv->pci_dev->irq); } /* @@ -931,7 +931,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - printk("comedi%d: attached\n", dev->minor); + dev_info(dev->class_dev, "attached\n"); return 1; } @@ -1117,9 +1117,7 @@ static int pci230_ai_rinsn(struct comedi_device *dev, udelay(1); } if (i == TIMEOUT) { - /* printk() should be used instead of printk() - * whenever the code can be called from real-time. */ - printk("timeout\n"); + dev_err(dev->class_dev, "timeout\n"); return -ETIMEDOUT; } @@ -1992,13 +1990,9 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, (s->n_chan / 2) - 1); } if ((errors & buggy_chan0_err) != 0) { - /* Use printk instead of DPRINTK here. */ - printk("comedi: comedi%d: amplc_pci230: " - "ai_cmdtest: Buggy PCI230+/260+ " - "h/w version %u requires first channel " - "of multi-channel sequence to be 0 " - "(corrected in h/w version 4)\n", - dev->minor, devpriv->hwver); + dev_info(dev->class_dev, + "amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n", + devpriv->hwver); } } } -- GitLab From 967bfbc2c90e456bdfc0ef045dd1e81221461c06 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:40 +0100 Subject: [PATCH 0415/6849] staging: comedi: amplc_pci230: Remove thisboard and devpriv macros The 'thisboard' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macros with local variables wherever they occur. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 512ead739895..6d3c6c9dff00 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -499,11 +499,7 @@ static const struct pci230_board pci230_boards[] = { }, }; -/* - * Useful for shorthand access to the particular board structure - */ #define n_pci230_boards ARRAY_SIZE(pci230_boards) -#define thisboard ((const struct pci230_board *)dev->board_ptr) /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, @@ -548,8 +544,6 @@ struct pci230_private { unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners. */ }; -#define devpriv ((struct pci230_private *)dev->private) - /* PCI230 clock source periods in ns */ static const unsigned int pci230_timebase[8] = { [CLK_10MHZ] = TIMEBASE_10MHZ, @@ -627,9 +621,12 @@ static void pci230_handle_ai(struct comedi_device *dev, static short pci230_ai_read(struct comedi_device *dev) { - /* Read sample. */ - short data = (short)inw(dev->iobase + PCI230_ADCDATA); + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; + short data; + /* Read sample. */ + data = (short)inw(dev->iobase + PCI230_ADCDATA); /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower * four bits reserved for expansion). */ /* PCI230+ is 16 bit AI. */ @@ -646,12 +643,14 @@ static short pci230_ai_read(struct comedi_device *dev) static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev, short datum) { + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; + /* If a bipolar range was specified, mangle it (straight binary->twos * complement). */ if (devpriv->ao_bipolar) datum ^= 1 << (thisboard->ao_bits - 1); - /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower * four bits reserved for expansion). */ /* PCI230+ is also 12 bit AO. */ @@ -662,6 +661,8 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev, static inline void pci230_ao_write_nofifo(struct comedi_device *dev, short datum, unsigned int chan) { + struct pci230_private *devpriv = dev->private; + /* Store unmangled datum to be read back later. */ devpriv->ao_readback[chan] = datum; @@ -675,6 +676,8 @@ static inline void pci230_ao_write_nofifo(struct comedi_device *dev, static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum, unsigned int chan) { + struct pci230_private *devpriv = dev->private; + /* Store unmangled datum to be read back later. */ devpriv->ao_readback[chan] = datum; @@ -691,6 +694,8 @@ static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum, */ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv; struct comedi_subdevice *s; unsigned long iobase1, iobase2; /* PCI230's I/O spaces 1 and 2 respectively. */ @@ -704,6 +709,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Macro defined in comedidev.h - memsets struct fields to 0. */ if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) return -ENOMEM; + devpriv = dev->private; spin_lock_init(&devpriv->isr_spinlock); spin_lock_init(&devpriv->res_spinlock); @@ -742,6 +748,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Change board_ptr to matched board */ dev->board_ptr = &pci230_boards[i]; + thisboard = comedi_board(dev); break; } } @@ -938,6 +945,9 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pci230_detach(struct comedi_device *dev) { + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; + if (dev->subdevices && thisboard->have_dio) subdev_8255_cleanup(dev, dev->subdevices + 2); if (dev->irq) @@ -954,6 +964,7 @@ static void pci230_detach(struct comedi_device *dev) static int get_resources(struct comedi_device *dev, unsigned int res_mask, unsigned char owner) { + struct pci230_private *devpriv = dev->private; int ok; unsigned int i; unsigned int b; @@ -996,6 +1007,7 @@ static inline int get_one_resource(struct comedi_device *dev, static void put_resources(struct comedi_device *dev, unsigned int res_mask, unsigned char owner) { + struct pci230_private *devpriv = dev->private; unsigned int i; unsigned int b; unsigned long irqflags; @@ -1032,6 +1044,7 @@ static int pci230_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci230_private *devpriv = dev->private; unsigned int n, i; unsigned int chan, range, aref; unsigned int gainshift; @@ -1136,6 +1149,7 @@ static int pci230_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci230_private *devpriv = dev->private; int i; int chan, range; @@ -1165,6 +1179,7 @@ static int pci230_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci230_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -1177,6 +1192,8 @@ static int pci230_ao_rinsn(struct comedi_device *dev, static int pci230_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; int err = 0; unsigned int tmp; @@ -1390,6 +1407,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) { + struct pci230_private *devpriv = dev->private; unsigned long irqflags; if (trig_num != 0) @@ -1422,6 +1440,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, static void pci230_ao_start(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned long irqflags; @@ -1523,6 +1542,7 @@ static int pci230_ao_inttrig_start(struct comedi_device *dev, static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; unsigned short daccon; unsigned int range; @@ -1625,6 +1645,8 @@ static int pci230_ai_check_scan_period(struct comedi_cmd *cmd) static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; int err = 0; unsigned int tmp; @@ -2006,6 +2028,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int scanlen = cmd->scan_end_arg; unsigned int wake; @@ -2050,6 +2073,7 @@ static int pci230_ai_inttrig_convert(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) { + struct pci230_private *devpriv = dev->private; unsigned long irqflags; if (trig_num != 0) @@ -2092,6 +2116,7 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) { + struct pci230_private *devpriv = dev->private; unsigned long irqflags; unsigned char zgat; @@ -2114,6 +2139,7 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev, static void pci230_ai_start(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; unsigned long irqflags; unsigned short conv; struct comedi_async *async = s->async; @@ -2264,6 +2290,7 @@ static int pci230_ai_inttrig_start(struct comedi_device *dev, static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; unsigned int i, chan, range, diff; unsigned int res_mask; unsigned short adccon, adcen; @@ -2509,6 +2536,7 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, unsigned int mode, uint64_t ns, unsigned int round) { + struct pci230_private *devpriv = dev->private; unsigned int clk_src; unsigned int count; @@ -2527,6 +2555,8 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct) { + struct pci230_private *devpriv = dev->private; + i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, I8254_MODE1); /* Counter ct, 8254 mode 1, initial count not written. */ @@ -2537,6 +2567,7 @@ static irqreturn_t pci230_interrupt(int irq, void *d) { unsigned char status_int, valid_status_int; struct comedi_device *dev = (struct comedi_device *)d; + struct pci230_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned long irqflags; @@ -2599,6 +2630,7 @@ static irqreturn_t pci230_interrupt(int irq, void *d) static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; short data; int i, ret; struct comedi_async *async = s->async; @@ -2637,6 +2669,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int num_scans; @@ -2742,6 +2775,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; unsigned int events = 0; unsigned int status_fifo; unsigned int i; @@ -2842,6 +2876,7 @@ static void pci230_handle_ai(struct comedi_device *dev, static void pci230_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; unsigned long irqflags; unsigned char intsrc; int started; @@ -2905,6 +2940,7 @@ static int pci230_ao_cancel(struct comedi_device *dev, static void pci230_ai_stop(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci230_private *devpriv = dev->private; unsigned long irqflags; struct comedi_cmd *cmd; int started; -- GitLab From ba54fa6893aa72159c046c6099f7644df745feea Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:41 +0100 Subject: [PATCH 0416/6849] staging: comedi: amplc_pci230: Add attach_pci() hook Implement the attach_pci() hook as function pci230_attach_pci(). This is called by comedi_pci_auto_config() in preference to the old attach() hook (implemented by pci230_attach() and still required for "manual" configuration of comedi devices). The advantage of the attach_pci() hook is that it avoids searching for the PCI device. Refactor pci230_attach() and factor out code common to pci230_attach() and pci230_attach_pci() into new functions pci230_match_pci_board(), pci230_find_pci_board(), pci230_find_pci(), pci230_alloc_private() and pci230_attach_common(). Finally, move pci230_attach() and pci230_detach() along with all the new functions towards the bottom of the file as it makes the patch much cleaner (though longer) and I plan to move things around soon to get rid of the remaining forward references. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 578 +++++++++--------- 1 file changed, 301 insertions(+), 277 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 6d3c6c9dff00..fbc9da99c6f5 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -499,8 +499,6 @@ static const struct pci230_board pci230_boards[] = { }, }; -#define n_pci230_boards ARRAY_SIZE(pci230_boards) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. */ @@ -686,281 +684,6 @@ static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum, dev->iobase + PCI230P2_DACDATA); } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - const struct pci230_board *thisboard = comedi_board(dev); - struct pci230_private *devpriv; - struct comedi_subdevice *s; - unsigned long iobase1, iobase2; - /* PCI230's I/O spaces 1 and 2 respectively. */ - struct pci_dev *pci_dev = NULL; - int i = 0, irq_hdl, rc; - - dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n", - thisboard->name, it->options[0], it->options[1]); - - /* Allocate the private structure area using alloc_private(). - * Macro defined in comedidev.h - memsets struct fields to 0. */ - if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) - return -ENOMEM; - devpriv = dev->private; - - spin_lock_init(&devpriv->isr_spinlock); - spin_lock_init(&devpriv->res_spinlock); - spin_lock_init(&devpriv->ai_stop_spinlock); - spin_lock_init(&devpriv->ao_stop_spinlock); - /* Find card */ - for_each_pci_dev(pci_dev) { - if (it->options[0] || it->options[1]) { - /* Match against bus/slot options. */ - if (it->options[0] != pci_dev->bus->number || - it->options[1] != PCI_SLOT(pci_dev->devfn)) - continue; - } - if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON) - continue; - if (thisboard->id == PCI_DEVICE_ID_INVALID) { - /* The name was specified as "amplc_pci230" which is - * used to match any supported device. Replace the - * current dev->board_ptr with one that matches the - * PCI device ID. */ - for (i = 0; i < n_pci230_boards; i++) { - if (pci_dev->device == pci230_boards[i].id) { - if (pci230_boards[i].min_hwver > 0) { - /* Check for a '+' model. - * First check length of - * registers. */ - if (pci_resource_len(pci_dev, 3) - < 32) { - /* Not a '+' model. */ - continue; - } - /* TODO: temporarily enable the - * PCI device and read the - * hardware version register. - * For now assume it's okay. */ - } - /* Change board_ptr to matched board */ - dev->board_ptr = &pci230_boards[i]; - thisboard = comedi_board(dev); - break; - } - } - if (i < n_pci230_boards) - break; - } else { - /* The name was specified as a specific device name. - * The current dev->board_ptr is correct. Check - * whether it matches the PCI device ID. */ - if (thisboard->id == pci_dev->device) { - /* Check minimum hardware version. */ - if (thisboard->min_hwver > 0) { - /* Looking for a '+' model. First - * check length of registers. */ - if (pci_resource_len(pci_dev, 3) < 32) { - /* Not a '+' model. */ - continue; - } - /* TODO: temporarily enable the PCI - * device and read the hardware version - * register. For now, assume it's - * okay. */ - break; - } else { - break; - } - } - } - } - if (!pci_dev) { - dev_err(dev->class_dev, "No %s card found\n", thisboard->name); - return -EIO; - } - devpriv->pci_dev = pci_dev; - - /* - * Initialize dev->board_name. - */ - dev->board_name = thisboard->name; - - /* Enable PCI device and reserve I/O spaces. */ - if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) { - dev_err(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; - } - - /* Read base addresses of the PCI230's two I/O regions from PCI - * configuration register. */ - iobase1 = pci_resource_start(pci_dev, 2); - iobase2 = pci_resource_start(pci_dev, 3); - - dev_dbg(dev->class_dev, - "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n", - dev->board_name, iobase1, iobase2); - - devpriv->iobase1 = iobase1; - dev->iobase = iobase2; - - /* Read bits of DACCON register - only the output range. */ - devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK; - - /* Read hardware version register and set extended function register - * if they exist. */ - if (pci_resource_len(pci_dev, 3) >= 32) { - unsigned short extfunc = 0; - - devpriv->hwver = inw(dev->iobase + PCI230P_HWVER); - if (devpriv->hwver < thisboard->min_hwver) { - dev_err(dev->class_dev, - "%s - bad hardware version - got %u, need %u\n", - dev->board_name, devpriv->hwver, - thisboard->min_hwver); - return -EIO; - } - if (devpriv->hwver > 0) { - if (!thisboard->have_dio) { - /* No DIO ports. Route counters' external gates - * to the EXTTRIG signal (PCI260+ pin 17). - * (Otherwise, they would be routed to DIO - * inputs PC0, PC1 and PC2 which don't exist - * on PCI260[+].) */ - extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG; - } - if ((thisboard->ao_chans > 0) - && (devpriv->hwver >= 2)) { - /* Enable DAC FIFO functionality. */ - extfunc |= PCI230P2_EXTFUNC_DACFIFO; - } - } - outw(extfunc, dev->iobase + PCI230P_EXTFUNC); - if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) { - /* Temporarily enable DAC FIFO, reset it and disable - * FIFO wraparound. */ - outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN - | PCI230P2_DAC_FIFO_RESET, - dev->iobase + PCI230_DACCON); - /* Clear DAC FIFO channel enable register. */ - outw(0, dev->iobase + PCI230P2_DACEN); - /* Disable DAC FIFO. */ - outw(devpriv->daccon, dev->iobase + PCI230_DACCON); - } - } - - /* Disable board's interrupts. */ - outb(0, devpriv->iobase1 + PCI230_INT_SCE); - - /* Set ADC to a reasonable state. */ - devpriv->adcg = 0; - devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE - | PCI230_ADC_IR_BIP; - outw(1 << 0, dev->iobase + PCI230_ADCEN); - outw(devpriv->adcg, dev->iobase + PCI230_ADCG); - outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, - dev->iobase + PCI230_ADCCON); - - /* Register the interrupt handler. */ - irq_hdl = request_irq(devpriv->pci_dev->irq, pci230_interrupt, - IRQF_SHARED, "amplc_pci230", dev); - if (irq_hdl < 0) { - dev_warn(dev->class_dev, - "unable to register irq %u, commands will not be available\n", - devpriv->pci_dev->irq); - } else { - dev->irq = devpriv->pci_dev->irq; - dev_dbg(dev->class_dev, "registered irq %u\n", - devpriv->pci_dev->irq); - } - - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_subdevices(dev, 3) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = &pci230_ai_range; - s->insn_read = &pci230_ai_rinsn; - s->len_chanlist = 256; /* but there are restrictions. */ - /* Only register commands if the interrupt handler is installed. */ - if (irq_hdl == 0) { - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->do_cmd = &pci230_ai_cmd; - s->do_cmdtest = &pci230_ai_cmdtest; - s->cancel = pci230_ai_cancel; - } - - s = dev->subdevices + 1; - /* analog output subdevice */ - if (thisboard->ao_chans > 0) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = thisboard->ao_chans; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = &pci230_ao_range; - s->insn_write = &pci230_ao_winsn; - s->insn_read = &pci230_ao_rinsn; - s->len_chanlist = thisboard->ao_chans; - /* Only register commands if the interrupt handler is - * installed. */ - if (irq_hdl == 0) { - dev->write_subdev = s; - s->subdev_flags |= SDF_CMD_WRITE; - s->do_cmd = &pci230_ao_cmd; - s->do_cmdtest = &pci230_ao_cmdtest; - s->cancel = pci230_ao_cancel; - } - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - s = dev->subdevices + 2; - /* digital i/o subdevice */ - if (thisboard->have_dio) { - rc = subdev_8255_init(dev, s, NULL, - (devpriv->iobase1 + PCI230_PPI_X_BASE)); - if (rc < 0) - return rc; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - dev_info(dev->class_dev, "attached\n"); - - return 1; -} - -static void pci230_detach(struct comedi_device *dev) -{ - const struct pci230_board *thisboard = comedi_board(dev); - struct pci230_private *devpriv = dev->private; - - if (dev->subdevices && thisboard->have_dio) - subdev_8255_cleanup(dev, dev->subdevices + 2); - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv) { - if (devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - } -} - static int get_resources(struct comedi_device *dev, unsigned int res_mask, unsigned char owner) { @@ -2995,10 +2718,311 @@ static int pci230_ai_cancel(struct comedi_device *dev, return 0; } +/* Check if PCI device matches a specific board. */ +static bool pci230_match_pci_board(const struct pci230_board *board, + struct pci_dev *pci_dev) +{ + /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */ + if (board->id != pci_dev->device) + return false; + if (board->min_hwver == 0) + return true; + /* Looking for a '+' model. First check length of registers. */ + if (pci_resource_len(pci_dev, 3) < 32) + return false; /* Not a '+' model. */ + /* TODO: temporarily enable PCI device and read the hardware version + * register. For now, assume it's okay. */ + return true; +} + +/* Look for board matching PCI device. */ +static const struct pci230_board *pci230_find_pci_board(struct pci_dev *pci_dev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pci230_boards); i++) + if (pci230_match_pci_board(&pci230_boards[i], pci_dev)) + return &pci230_boards[i]; + return NULL; +} + +/* Look for PCI device matching requested board name, bus and slot. */ +static struct pci_dev *pci230_find_pci(struct comedi_device *dev, + int bus, int slot) +{ + const struct pci230_board *thisboard = comedi_board(dev); + struct pci_dev *pci_dev = NULL; + + for_each_pci_dev(pci_dev) { + /* Check vendor ID (same for all supported PCI boards). */ + if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON) + continue; + /* If bus/slot specified, check them. */ + if ((bus || slot) && + (bus != pci_dev->bus->number || + slot != PCI_SLOT(pci_dev->devfn))) + continue; + if (thisboard->id == PCI_DEVICE_ID_INVALID) { + /* Wildcard board matches any supported PCI board. */ + const struct pci230_board *foundboard; + + foundboard = pci230_find_pci_board(pci_dev); + if (foundboard == NULL) + continue; + /* Replace wildcard board_ptr. */ + dev->board_ptr = foundboard; + thisboard = comedi_board(dev); + } else { + /* Need to match a specific board. */ + if (!pci230_match_pci_board(thisboard, pci_dev)) + continue; + } + /* Found a matching PCI device. */ + return pci_dev; + } + /* No matching PCI device found. */ + if (bus || slot) + dev_err(dev->class_dev, + "error! no %s found at pci %02x:%02x\n", + thisboard->name, bus, slot); + else + dev_err(dev->class_dev, + "error! no %s found\n", thisboard->name); + return NULL; +} + +static int pci230_alloc_private(struct comedi_device *dev) +{ + struct pci230_private *devpriv; + int err; + + /* sets dev->private to allocated memory */ + err = alloc_private(dev, sizeof(struct pci230_private)); + if (err) { + dev_err(dev->class_dev, "error! out of memory!\n"); + return err; + } + devpriv = dev->private; + spin_lock_init(&devpriv->isr_spinlock); + spin_lock_init(&devpriv->res_spinlock); + spin_lock_init(&devpriv->ai_stop_spinlock); + spin_lock_init(&devpriv->ao_stop_spinlock); + return 0; +} + +/* Common part of attach and attach_pci. */ +static int pci230_attach_common(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; + struct comedi_subdevice *s; + unsigned long iobase1, iobase2; + /* PCI230's I/O spaces 1 and 2 respectively. */ + int irq_hdl, rc; + + devpriv->pci_dev = pci_dev; + dev->board_name = thisboard->name; + /* Enable PCI device and reserve I/O spaces. */ + if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) { + dev_err(dev->class_dev, + "failed to enable PCI device and request regions\n"); + return -EIO; + } + /* Read base addresses of the PCI230's two I/O regions from PCI + * configuration register. */ + iobase1 = pci_resource_start(pci_dev, 2); + iobase2 = pci_resource_start(pci_dev, 3); + dev_dbg(dev->class_dev, + "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n", + dev->board_name, iobase1, iobase2); + devpriv->iobase1 = iobase1; + dev->iobase = iobase2; + /* Read bits of DACCON register - only the output range. */ + devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK; + /* Read hardware version register and set extended function register + * if they exist. */ + if (pci_resource_len(pci_dev, 3) >= 32) { + unsigned short extfunc = 0; + + devpriv->hwver = inw(dev->iobase + PCI230P_HWVER); + if (devpriv->hwver < thisboard->min_hwver) { + dev_err(dev->class_dev, + "%s - bad hardware version - got %u, need %u\n", + dev->board_name, devpriv->hwver, + thisboard->min_hwver); + return -EIO; + } + if (devpriv->hwver > 0) { + if (!thisboard->have_dio) { + /* No DIO ports. Route counters' external gates + * to the EXTTRIG signal (PCI260+ pin 17). + * (Otherwise, they would be routed to DIO + * inputs PC0, PC1 and PC2 which don't exist + * on PCI260[+].) */ + extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG; + } + if ((thisboard->ao_chans > 0) + && (devpriv->hwver >= 2)) { + /* Enable DAC FIFO functionality. */ + extfunc |= PCI230P2_EXTFUNC_DACFIFO; + } + } + outw(extfunc, dev->iobase + PCI230P_EXTFUNC); + if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) { + /* Temporarily enable DAC FIFO, reset it and disable + * FIFO wraparound. */ + outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN + | PCI230P2_DAC_FIFO_RESET, + dev->iobase + PCI230_DACCON); + /* Clear DAC FIFO channel enable register. */ + outw(0, dev->iobase + PCI230P2_DACEN); + /* Disable DAC FIFO. */ + outw(devpriv->daccon, dev->iobase + PCI230_DACCON); + } + } + /* Disable board's interrupts. */ + outb(0, devpriv->iobase1 + PCI230_INT_SCE); + /* Set ADC to a reasonable state. */ + devpriv->adcg = 0; + devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE + | PCI230_ADC_IR_BIP; + outw(1 << 0, dev->iobase + PCI230_ADCEN); + outw(devpriv->adcg, dev->iobase + PCI230_ADCG); + outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, + dev->iobase + PCI230_ADCCON); + /* Register the interrupt handler. */ + irq_hdl = request_irq(devpriv->pci_dev->irq, pci230_interrupt, + IRQF_SHARED, "amplc_pci230", dev); + if (irq_hdl < 0) { + dev_warn(dev->class_dev, + "unable to register irq %u, commands will not be available\n", + devpriv->pci_dev->irq); + } else { + dev->irq = devpriv->pci_dev->irq; + dev_dbg(dev->class_dev, "registered irq %u\n", + devpriv->pci_dev->irq); + } + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_subdevices(dev, 3) < 0) + return -ENOMEM; + s = dev->subdevices + 0; + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; + s->n_chan = thisboard->ai_chans; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = &pci230_ai_range; + s->insn_read = &pci230_ai_rinsn; + s->len_chanlist = 256; /* but there are restrictions. */ + /* Only register commands if the interrupt handler is installed. */ + if (irq_hdl == 0) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->do_cmd = &pci230_ai_cmd; + s->do_cmdtest = &pci230_ai_cmdtest; + s->cancel = pci230_ai_cancel; + } + s = dev->subdevices + 1; + /* analog output subdevice */ + if (thisboard->ao_chans > 0) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; + s->n_chan = thisboard->ao_chans; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = &pci230_ao_range; + s->insn_write = &pci230_ao_winsn; + s->insn_read = &pci230_ao_rinsn; + s->len_chanlist = thisboard->ao_chans; + /* Only register commands if the interrupt handler is + * installed. */ + if (irq_hdl == 0) { + dev->write_subdev = s; + s->subdev_flags |= SDF_CMD_WRITE; + s->do_cmd = &pci230_ao_cmd; + s->do_cmdtest = &pci230_ao_cmdtest; + s->cancel = pci230_ao_cancel; + } + } else { + s->type = COMEDI_SUBD_UNUSED; + } + s = dev->subdevices + 2; + /* digital i/o subdevice */ + if (thisboard->have_dio) { + rc = subdev_8255_init(dev, s, NULL, + (devpriv->iobase1 + PCI230_PPI_X_BASE)); + if (rc < 0) + return rc; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + dev_info(dev->class_dev, "attached\n"); + return 1; +} + +static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct pci230_board *thisboard = comedi_board(dev); + struct pci_dev *pci_dev; + int rc; + + dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n", + thisboard->name, it->options[0], it->options[1]); + rc = pci230_alloc_private(dev); /* sets dev->private */ + if (rc) + return rc; + /* Find card. */ + pci_dev = pci230_find_pci(dev, it->options[0], it->options[1]); + if (!pci_dev) + return -EIO; + return pci230_attach_common(dev, pci_dev); +} + +static int __devinit pci230_attach_pci(struct comedi_device *dev, + struct pci_dev *pci_dev) +{ + int rc; + + dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n", + pci_name(pci_dev)); + rc = pci230_alloc_private(dev); /* sets dev->private */ + if (rc) + return rc; + dev->board_ptr = pci230_find_pci_board(pci_dev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, + "amplc_pci230: BUG! cannot determine board type!\n"); + return -EINVAL; + } + return pci230_attach_common(dev, pci_dev); +} + +static void pci230_detach(struct comedi_device *dev) +{ + const struct pci230_board *thisboard = comedi_board(dev); + struct pci230_private *devpriv = dev->private; + + if (dev->subdevices && thisboard->have_dio) + subdev_8255_cleanup(dev, dev->subdevices + 2); + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } + } +} + static struct comedi_driver amplc_pci230_driver = { .driver_name = "amplc_pci230", .module = THIS_MODULE, .attach = pci230_attach, + .attach_pci = pci230_attach_pci, .detach = pci230_detach, .board_name = &pci230_boards[0].name, .offset = sizeof(pci230_boards[0]), -- GitLab From 027ee06835e96d425998003fe0b60ab128581fd6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:42 +0100 Subject: [PATCH 0417/6849] staging: comedi: amplc_pci230: Remove forward declarations 1 Remove the redundant forward function declarations. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index fbc9da99c6f5..a99e90f7b556 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -579,39 +579,17 @@ static const struct comedi_lrange pci230_ao_range = { 2, { /* PCI230 daccon bipolar flag for each analogue output range. */ static const unsigned char pci230_ao_bipolar[2] = { 0, 1 }; -static int pci230_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int pci230_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int pci230_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, unsigned int mode, uint64_t ns, unsigned int round); static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round); static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct); -static irqreturn_t pci230_interrupt(int irq, void *d); -static int pci230_ao_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int pci230_ao_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); static void pci230_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s); static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_subdevice *s); static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdevice *s); -static int pci230_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int pci230_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); static void pci230_ai_stop(struct comedi_device *dev, struct comedi_subdevice *s); static void pci230_handle_ai(struct comedi_device *dev, -- GitLab From 091e8d8ff434f5e6e67dcfd742e2df8cac999ce4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:43 +0100 Subject: [PATCH 0418/6849] staging: comedi: amplc_pci230: Remove forward declarations 2 Remove some forward function declarations: pci230_ct_setup_ns_mode(), pci230_ns_to_single_timer(), pci230_cancel_ct(). Also need to move: divide_ns(). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 165 +++++++++--------- 1 file changed, 80 insertions(+), 85 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a99e90f7b556..d028962a5384 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -579,11 +579,6 @@ static const struct comedi_lrange pci230_ao_range = { 2, { /* PCI230 daccon bipolar flag for each analogue output range. */ static const unsigned char pci230_ao_bipolar[2] = { 0, 1 }; -static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, - unsigned int mode, uint64_t ns, - unsigned int round); -static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round); -static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct); static void pci230_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s); static void pci230_handle_ao_nofifo(struct comedi_device *dev, @@ -738,6 +733,86 @@ static inline void put_all_resources(struct comedi_device *dev, put_resources(dev, (1U << NUM_RESOURCES) - 1, owner); } +static unsigned int divide_ns(uint64_t ns, unsigned int timebase, + unsigned int round_mode) +{ + uint64_t div; + unsigned int rem; + + div = ns; + rem = do_div(div, timebase); + round_mode &= TRIG_ROUND_MASK; + switch (round_mode) { + default: + case TRIG_ROUND_NEAREST: + div += (rem + (timebase / 2)) / timebase; + break; + case TRIG_ROUND_DOWN: + break; + case TRIG_ROUND_UP: + div += (rem + timebase - 1) / timebase; + break; + } + return div > UINT_MAX ? UINT_MAX : (unsigned int)div; +} + +/* Given desired period in ns, returns the required internal clock source + * and gets the initial count. */ +static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count, + unsigned int round_mode) +{ + unsigned int clk_src, cnt; + + for (clk_src = CLK_10MHZ;; clk_src++) { + cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode); + if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) + break; + + } + *count = cnt; + return clk_src; +} + +static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round) +{ + unsigned int count; + unsigned int clk_src; + + clk_src = pci230_choose_clk_count(*ns, &count, round); + *ns = count * pci230_timebase[clk_src]; + return; +} + +static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, + unsigned int mode, uint64_t ns, + unsigned int round) +{ + struct pci230_private *devpriv = dev->private; + unsigned int clk_src; + unsigned int count; + + /* Set mode. */ + i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode); + /* Determine clock source and count. */ + clk_src = pci230_choose_clk_count(ns, &count, round); + /* Program clock source. */ + outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE); + /* Set initial count. */ + if (count >= 65536) + count = 0; + + i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count); +} + +static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct) +{ + struct pci230_private *devpriv = dev->private; + + i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, + I8254_MODE1); + /* Counter ct, 8254 mode 1, initial count not written. */ +} + /* * COMEDI_SUBD_AI instruction; */ @@ -2183,86 +2258,6 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static unsigned int divide_ns(uint64_t ns, unsigned int timebase, - unsigned int round_mode) -{ - uint64_t div; - unsigned int rem; - - div = ns; - rem = do_div(div, timebase); - round_mode &= TRIG_ROUND_MASK; - switch (round_mode) { - default: - case TRIG_ROUND_NEAREST: - div += (rem + (timebase / 2)) / timebase; - break; - case TRIG_ROUND_DOWN: - break; - case TRIG_ROUND_UP: - div += (rem + timebase - 1) / timebase; - break; - } - return div > UINT_MAX ? UINT_MAX : (unsigned int)div; -} - -/* Given desired period in ns, returns the required internal clock source - * and gets the initial count. */ -static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count, - unsigned int round_mode) -{ - unsigned int clk_src, cnt; - - for (clk_src = CLK_10MHZ;; clk_src++) { - cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode); - if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) - break; - - } - *count = cnt; - return clk_src; -} - -static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round) -{ - unsigned int count; - unsigned int clk_src; - - clk_src = pci230_choose_clk_count(*ns, &count, round); - *ns = count * pci230_timebase[clk_src]; - return; -} - -static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, - unsigned int mode, uint64_t ns, - unsigned int round) -{ - struct pci230_private *devpriv = dev->private; - unsigned int clk_src; - unsigned int count; - - /* Set mode. */ - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode); - /* Determine clock source and count. */ - clk_src = pci230_choose_clk_count(ns, &count, round); - /* Program clock source. */ - outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE); - /* Set initial count. */ - if (count >= 65536) - count = 0; - - i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count); -} - -static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct) -{ - struct pci230_private *devpriv = dev->private; - - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, - I8254_MODE1); - /* Counter ct, 8254 mode 1, initial count not written. */ -} - /* Interrupt handler */ static irqreturn_t pci230_interrupt(int irq, void *d) { -- GitLab From bd4447e597e0609fccb91aeeb2add40a7fcf3289 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:44 +0100 Subject: [PATCH 0419/6849] staging: comedi: amplc_pci230: Remove forward declarations 3 Move these functions and remove their forward declarations: pci230_ao_stop(), pci230_handle_ao_nofifo(), pci230_handle_ao_fifo(). Also move pci230_ao_cancel() for aesthetic reasons. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 412 +++++++++--------- 1 file changed, 197 insertions(+), 215 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index d028962a5384..0e9c4ba6e6c0 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -579,12 +579,6 @@ static const struct comedi_lrange pci230_ao_range = { 2, { /* PCI230 daccon bipolar flag for each analogue output range. */ static const unsigned char pci230_ao_bipolar[2] = { 0, 1 }; -static void pci230_ao_stop(struct comedi_device *dev, - struct comedi_subdevice *s); -static void pci230_handle_ao_nofifo(struct comedi_device *dev, - struct comedi_subdevice *s); -static int pci230_handle_ao_fifo(struct comedi_device *dev, - struct comedi_subdevice *s); static void pci230_ai_stop(struct comedi_device *dev, struct comedi_subdevice *s); static void pci230_handle_ai(struct comedi_device *dev, @@ -1179,6 +1173,196 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, return 0; } +static void pci230_ao_stop(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct pci230_private *devpriv = dev->private; + unsigned long irqflags; + unsigned char intsrc; + int started; + struct comedi_cmd *cmd; + + spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); + started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state); + spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); + if (!started) + return; + cmd = &s->async->cmd; + if (cmd->scan_begin_src == TRIG_TIMER) { + /* Stop scan rate generator. */ + pci230_cancel_ct(dev, 1); + } + /* Determine interrupt source. */ + if (devpriv->hwver < 2) { + /* Not using DAC FIFO. Using CT1 interrupt. */ + intsrc = PCI230_INT_ZCLK_CT1; + } else { + /* Using DAC FIFO interrupt. */ + intsrc = PCI230P2_INT_DAC; + } + /* Disable interrupt and wait for interrupt routine to finish running + * unless we are called from the interrupt routine. */ + spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); + devpriv->int_en &= ~intsrc; + while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { + spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); + } + if (devpriv->ier != devpriv->int_en) { + devpriv->ier = devpriv->int_en; + outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + } + spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + if (devpriv->hwver >= 2) { + /* Using DAC FIFO. Reset FIFO, clear underrun error, + * disable FIFO. */ + devpriv->daccon &= PCI230_DAC_OR_MASK; + outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET + | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR, + dev->iobase + PCI230_DACCON); + } + /* Release resources. */ + put_all_resources(dev, OWNER_AOCMD); +} + +static void pci230_handle_ao_nofifo(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct pci230_private *devpriv = dev->private; + short data; + int i, ret; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + + if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) + return; + for (i = 0; i < cmd->chanlist_len; i++) { + /* Read sample from Comedi's circular buffer. */ + ret = comedi_buf_get(s->async, &data); + if (ret == 0) { + s->async->events |= COMEDI_CB_OVERFLOW; + pci230_ao_stop(dev, s); + comedi_error(dev, "AO buffer underrun"); + return; + } + /* Write value to DAC. */ + pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i])); + } + async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + if (!devpriv->ao_continuous) { + devpriv->ao_scan_count--; + if (devpriv->ao_scan_count == 0) { + /* End of acquisition. */ + async->events |= COMEDI_CB_EOA; + pci230_ao_stop(dev, s); + } + } +} + +/* Loads DAC FIFO (if using it) from buffer. */ +/* Returns 0 if AO finished due to completion or error, 1 if still going. */ +static int pci230_handle_ao_fifo(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct pci230_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + unsigned int num_scans; + unsigned int room; + unsigned short dacstat; + unsigned int i, n; + unsigned int bytes_per_scan; + unsigned int events = 0; + int running; + + /* Get DAC FIFO status. */ + dacstat = inw(dev->iobase + PCI230_DACCON); + /* Determine number of scans available in buffer. */ + bytes_per_scan = cmd->chanlist_len * sizeof(short); + num_scans = comedi_buf_read_n_available(async) / bytes_per_scan; + if (!devpriv->ao_continuous) { + /* Fixed number of scans. */ + if (num_scans > devpriv->ao_scan_count) + num_scans = devpriv->ao_scan_count; + if (devpriv->ao_scan_count == 0) { + /* End of acquisition. */ + events |= COMEDI_CB_EOA; + } + } + if (events == 0) { + /* Check for FIFO underrun. */ + if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) { + comedi_error(dev, "AO FIFO underrun"); + events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; + } + /* Check for buffer underrun if FIFO less than half full + * (otherwise there will be loads of "DAC FIFO not half full" + * interrupts). */ + if ((num_scans == 0) + && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) { + comedi_error(dev, "AO buffer underrun"); + events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; + } + } + if (events == 0) { + /* Determine how much room is in the FIFO (in samples). */ + if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) + room = PCI230P2_DAC_FIFOROOM_FULL; + else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) + room = PCI230P2_DAC_FIFOROOM_HALFTOFULL; + else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) + room = PCI230P2_DAC_FIFOROOM_EMPTY; + else + room = PCI230P2_DAC_FIFOROOM_ONETOHALF; + /* Convert room to number of scans that can be added. */ + room /= cmd->chanlist_len; + /* Determine number of scans to process. */ + if (num_scans > room) + num_scans = room; + /* Process scans. */ + for (n = 0; n < num_scans; n++) { + for (i = 0; i < cmd->chanlist_len; i++) { + short datum; + + comedi_buf_get(async, &datum); + pci230_ao_write_fifo(dev, datum, + CR_CHAN(cmd->chanlist[i])); + } + } + events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK; + if (!devpriv->ao_continuous) { + devpriv->ao_scan_count -= num_scans; + if (devpriv->ao_scan_count == 0) { + /* All data for the command has been written + * to FIFO. Set FIFO interrupt trigger level + * to 'empty'. */ + devpriv->daccon = (devpriv->daccon + & + ~PCI230P2_DAC_INT_FIFO_MASK) + | PCI230P2_DAC_INT_FIFO_EMPTY; + outw(devpriv->daccon, + dev->iobase + PCI230_DACCON); + } + } + /* Check if FIFO underrun occurred while writing to FIFO. */ + dacstat = inw(dev->iobase + PCI230_DACCON); + if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) { + comedi_error(dev, "AO FIFO underrun"); + events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; + } + } + if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) + != 0) { + /* Stopping AO due to completion or error. */ + pci230_ao_stop(dev, s); + running = 0; + } else { + running = 1; + } + async->events |= events; + return running; +} + static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) @@ -1394,6 +1578,13 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } +static int pci230_ao_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + pci230_ao_stop(dev, s); + return 0; +} + static int pci230_ai_check_scan_period(struct comedi_cmd *cmd) { unsigned int min_scan_period, chanlist_len; @@ -2323,151 +2514,6 @@ static irqreturn_t pci230_interrupt(int irq, void *d) return IRQ_HANDLED; } -static void pci230_handle_ao_nofifo(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct pci230_private *devpriv = dev->private; - short data; - int i, ret; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - - if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) - return; - - - for (i = 0; i < cmd->chanlist_len; i++) { - /* Read sample from Comedi's circular buffer. */ - ret = comedi_buf_get(s->async, &data); - if (ret == 0) { - s->async->events |= COMEDI_CB_OVERFLOW; - pci230_ao_stop(dev, s); - comedi_error(dev, "AO buffer underrun"); - return; - } - /* Write value to DAC. */ - pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i])); - } - - async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - if (!devpriv->ao_continuous) { - devpriv->ao_scan_count--; - if (devpriv->ao_scan_count == 0) { - /* End of acquisition. */ - async->events |= COMEDI_CB_EOA; - pci230_ao_stop(dev, s); - } - } -} - -/* Loads DAC FIFO (if using it) from buffer. */ -/* Returns 0 if AO finished due to completion or error, 1 if still going. */ -static int pci230_handle_ao_fifo(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct pci230_private *devpriv = dev->private; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - unsigned int num_scans; - unsigned int room; - unsigned short dacstat; - unsigned int i, n; - unsigned int bytes_per_scan; - unsigned int events = 0; - int running; - - /* Get DAC FIFO status. */ - dacstat = inw(dev->iobase + PCI230_DACCON); - - /* Determine number of scans available in buffer. */ - bytes_per_scan = cmd->chanlist_len * sizeof(short); - num_scans = comedi_buf_read_n_available(async) / bytes_per_scan; - if (!devpriv->ao_continuous) { - /* Fixed number of scans. */ - if (num_scans > devpriv->ao_scan_count) - num_scans = devpriv->ao_scan_count; - - if (devpriv->ao_scan_count == 0) { - /* End of acquisition. */ - events |= COMEDI_CB_EOA; - } - } - if (events == 0) { - /* Check for FIFO underrun. */ - if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) { - comedi_error(dev, "AO FIFO underrun"); - events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; - } - /* Check for buffer underrun if FIFO less than half full - * (otherwise there will be loads of "DAC FIFO not half full" - * interrupts). */ - if ((num_scans == 0) - && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) { - comedi_error(dev, "AO buffer underrun"); - events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; - } - } - if (events == 0) { - /* Determine how much room is in the FIFO (in samples). */ - if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) - room = PCI230P2_DAC_FIFOROOM_FULL; - else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) - room = PCI230P2_DAC_FIFOROOM_HALFTOFULL; - else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) - room = PCI230P2_DAC_FIFOROOM_EMPTY; - else - room = PCI230P2_DAC_FIFOROOM_ONETOHALF; - - /* Convert room to number of scans that can be added. */ - room /= cmd->chanlist_len; - /* Determine number of scans to process. */ - if (num_scans > room) - num_scans = room; - - /* Process scans. */ - for (n = 0; n < num_scans; n++) { - for (i = 0; i < cmd->chanlist_len; i++) { - short datum; - - comedi_buf_get(async, &datum); - pci230_ao_write_fifo(dev, datum, - CR_CHAN(cmd->chanlist[i])); - } - } - events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK; - if (!devpriv->ao_continuous) { - devpriv->ao_scan_count -= num_scans; - if (devpriv->ao_scan_count == 0) { - /* All data for the command has been written - * to FIFO. Set FIFO interrupt trigger level - * to 'empty'. */ - devpriv->daccon = (devpriv->daccon - & - ~PCI230P2_DAC_INT_FIFO_MASK) - | PCI230P2_DAC_INT_FIFO_EMPTY; - outw(devpriv->daccon, - dev->iobase + PCI230_DACCON); - } - } - /* Check if FIFO underrun occurred while writing to FIFO. */ - dacstat = inw(dev->iobase + PCI230_DACCON); - if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) { - comedi_error(dev, "AO FIFO underrun"); - events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; - } - } - if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) - != 0) { - /* Stopping AO due to completion or error. */ - pci230_ao_stop(dev, s); - running = 0; - } else { - running = 1; - } - async->events |= events; - return running; -} - static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -2569,70 +2615,6 @@ static void pci230_handle_ai(struct comedi_device *dev, } } -static void pci230_ao_stop(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct pci230_private *devpriv = dev->private; - unsigned long irqflags; - unsigned char intsrc; - int started; - struct comedi_cmd *cmd; - - spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); - started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state); - spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); - if (!started) - return; - - - cmd = &s->async->cmd; - if (cmd->scan_begin_src == TRIG_TIMER) { - /* Stop scan rate generator. */ - pci230_cancel_ct(dev, 1); - } - - /* Determine interrupt source. */ - if (devpriv->hwver < 2) { - /* Not using DAC FIFO. Using CT1 interrupt. */ - intsrc = PCI230_INT_ZCLK_CT1; - } else { - /* Using DAC FIFO interrupt. */ - intsrc = PCI230P2_INT_DAC; - } - /* Disable interrupt and wait for interrupt routine to finish running - * unless we are called from the interrupt routine. */ - spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); - devpriv->int_en &= ~intsrc; - while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { - spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); - spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); - } - if (devpriv->ier != devpriv->int_en) { - devpriv->ier = devpriv->int_en; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); - } - spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); - - if (devpriv->hwver >= 2) { - /* Using DAC FIFO. Reset FIFO, clear underrun error, - * disable FIFO. */ - devpriv->daccon &= PCI230_DAC_OR_MASK; - outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET - | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR, - dev->iobase + PCI230_DACCON); - } - - /* Release resources. */ - put_all_resources(dev, OWNER_AOCMD); -} - -static int pci230_ao_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - pci230_ao_stop(dev, s); - return 0; -} - static void pci230_ai_stop(struct comedi_device *dev, struct comedi_subdevice *s) { -- GitLab From 5d3b0d1859722a855b0310fcdc34c2e545cc1c7d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 1 Jun 2012 17:31:45 +0100 Subject: [PATCH 0420/6849] staging: comedi: amplc_pci230: Remove forward declarations 4 Move these functions and remove their forward declarations: pci230_ai_stop(), pci230_handle_ai(). Also move pci230_ai_cancel() for aesthetic reasons. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 310 +++++++++--------- 1 file changed, 146 insertions(+), 164 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 0e9c4ba6e6c0..30487be11650 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -579,11 +579,6 @@ static const struct comedi_lrange pci230_ao_range = { 2, { /* PCI230 daccon bipolar flag for each analogue output range. */ static const unsigned char pci230_ao_bipolar[2] = { 0, 1 }; -static void pci230_ai_stop(struct comedi_device *dev, - struct comedi_subdevice *s); -static void pci230_handle_ai(struct comedi_device *dev, - struct comedi_subdevice *s); - static short pci230_ai_read(struct comedi_device *dev) { const struct pci230_board *thisboard = comedi_board(dev); @@ -2103,6 +2098,52 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev, return 1; } +static void pci230_ai_stop(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct pci230_private *devpriv = dev->private; + unsigned long irqflags; + struct comedi_cmd *cmd; + int started; + + spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); + started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state); + spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); + if (!started) + return; + cmd = &s->async->cmd; + if (cmd->convert_src == TRIG_TIMER) { + /* Stop conversion rate generator. */ + pci230_cancel_ct(dev, 2); + } + if (cmd->scan_begin_src != TRIG_FOLLOW) { + /* Stop scan period monostable. */ + pci230_cancel_ct(dev, 0); + } + spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); + /* Disable ADC interrupt and wait for interrupt routine to finish + * running unless we are called from the interrupt routine. */ + devpriv->int_en &= ~PCI230_INT_ADC; + while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { + spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); + } + if (devpriv->ier != devpriv->int_en) { + devpriv->ier = devpriv->int_en; + outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + } + spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + /* Reset FIFO, disable FIFO and set start conversion source to none. + * Keep se/diff and bip/uni settings */ + devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK + | PCI230_ADC_IM_MASK)) | + PCI230_ADC_TRIG_NONE; + outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, + dev->iobase + PCI230_ADCCON); + /* Release resources. */ + put_all_resources(dev, OWNER_AICMD); +} + static void pci230_ai_start(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -2255,6 +2296,99 @@ static int pci230_ai_inttrig_start(struct comedi_device *dev, return 1; } +static void pci230_handle_ai(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct pci230_private *devpriv = dev->private; + unsigned int events = 0; + unsigned int status_fifo; + unsigned int i; + unsigned int todo; + unsigned int fifoamount; + struct comedi_async *async = s->async; + unsigned int scanlen = async->cmd.scan_end_arg; + + /* Determine number of samples to read. */ + if (devpriv->ai_continuous) { + todo = PCI230_ADC_FIFOLEVEL_HALFFULL; + } else if (devpriv->ai_scan_count == 0) { + todo = 0; + } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL) + || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) { + todo = PCI230_ADC_FIFOLEVEL_HALFFULL; + } else { + todo = (devpriv->ai_scan_count * scanlen) + - devpriv->ai_scan_pos; + if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) + todo = PCI230_ADC_FIFOLEVEL_HALFFULL; + } + if (todo == 0) + return; + fifoamount = 0; + for (i = 0; i < todo; i++) { + if (fifoamount == 0) { + /* Read FIFO state. */ + status_fifo = inw(dev->iobase + PCI230_ADCCON); + if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) { + /* Report error otherwise FIFO overruns will go + * unnoticed by the caller. */ + comedi_error(dev, "AI FIFO overrun"); + events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; + break; + } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) { + /* FIFO empty. */ + break; + } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) { + /* FIFO half full. */ + fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL; + } else { + /* FIFO not empty. */ + if (devpriv->hwver > 0) { + /* Read PCI230+/260+ ADC FIFO level. */ + fifoamount = inw(dev->iobase + + PCI230P_ADCFFLEV); + if (fifoamount == 0) { + /* Shouldn't happen. */ + break; + } + } else { + fifoamount = 1; + } + } + } + /* Read sample and store in Comedi's circular buffer. */ + if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) { + events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; + comedi_error(dev, "AI buffer overflow"); + break; + } + fifoamount--; + devpriv->ai_scan_pos++; + if (devpriv->ai_scan_pos == scanlen) { + /* End of scan. */ + devpriv->ai_scan_pos = 0; + devpriv->ai_scan_count--; + async->events |= COMEDI_CB_EOS; + } + } + if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) { + /* End of acquisition. */ + events |= COMEDI_CB_EOA; + } else { + /* More samples required, tell Comedi to block. */ + events |= COMEDI_CB_BLOCK; + } + async->events |= events; + if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | + COMEDI_CB_OVERFLOW)) != 0) { + /* disable hardware conversions */ + pci230_ai_stop(dev, s); + } else { + /* update FIFO interrupt trigger level */ + pci230_ai_update_fifo_trigger_level(dev, s); + } +} + static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct pci230_private *devpriv = dev->private; @@ -2449,6 +2583,13 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } +static int pci230_ai_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + pci230_ai_stop(dev, s); + return 0; +} + /* Interrupt handler */ static irqreturn_t pci230_interrupt(int irq, void *d) { @@ -2514,165 +2655,6 @@ static irqreturn_t pci230_interrupt(int irq, void *d) return IRQ_HANDLED; } -static void pci230_handle_ai(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct pci230_private *devpriv = dev->private; - unsigned int events = 0; - unsigned int status_fifo; - unsigned int i; - unsigned int todo; - unsigned int fifoamount; - struct comedi_async *async = s->async; - unsigned int scanlen = async->cmd.scan_end_arg; - - /* Determine number of samples to read. */ - if (devpriv->ai_continuous) { - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else if (devpriv->ai_scan_count == 0) { - todo = 0; - } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL) - || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) { - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else { - todo = (devpriv->ai_scan_count * scanlen) - - devpriv->ai_scan_pos; - if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - - } - - if (todo == 0) - return; - - - fifoamount = 0; - for (i = 0; i < todo; i++) { - if (fifoamount == 0) { - /* Read FIFO state. */ - status_fifo = inw(dev->iobase + PCI230_ADCCON); - - if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) { - /* Report error otherwise FIFO overruns will go - * unnoticed by the caller. */ - comedi_error(dev, "AI FIFO overrun"); - events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; - break; - } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) { - /* FIFO empty. */ - break; - } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) { - /* FIFO half full. */ - fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else { - /* FIFO not empty. */ - if (devpriv->hwver > 0) { - /* Read PCI230+/260+ ADC FIFO level. */ - fifoamount = inw(dev->iobase - + PCI230P_ADCFFLEV); - if (fifoamount == 0) { - /* Shouldn't happen. */ - break; - } - } else { - fifoamount = 1; - } - } - } - - /* Read sample and store in Comedi's circular buffer. */ - if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) { - events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; - comedi_error(dev, "AI buffer overflow"); - break; - } - fifoamount--; - devpriv->ai_scan_pos++; - if (devpriv->ai_scan_pos == scanlen) { - /* End of scan. */ - devpriv->ai_scan_pos = 0; - devpriv->ai_scan_count--; - async->events |= COMEDI_CB_EOS; - } - } - - if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) { - /* End of acquisition. */ - events |= COMEDI_CB_EOA; - } else { - /* More samples required, tell Comedi to block. */ - events |= COMEDI_CB_BLOCK; - } - async->events |= events; - - if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW)) != 0) { - /* disable hardware conversions */ - pci230_ai_stop(dev, s); - } else { - /* update FIFO interrupt trigger level */ - pci230_ai_update_fifo_trigger_level(dev, s); - } -} - -static void pci230_ai_stop(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct pci230_private *devpriv = dev->private; - unsigned long irqflags; - struct comedi_cmd *cmd; - int started; - - spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); - started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state); - spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); - if (!started) - return; - - - cmd = &s->async->cmd; - if (cmd->convert_src == TRIG_TIMER) { - /* Stop conversion rate generator. */ - pci230_cancel_ct(dev, 2); - } - if (cmd->scan_begin_src != TRIG_FOLLOW) { - /* Stop scan period monostable. */ - pci230_cancel_ct(dev, 0); - } - - spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); - /* Disable ADC interrupt and wait for interrupt routine to finish - * running unless we are called from the interrupt routine. */ - devpriv->int_en &= ~PCI230_INT_ADC; - while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { - spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); - spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); - } - if (devpriv->ier != devpriv->int_en) { - devpriv->ier = devpriv->int_en; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); - } - spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); - - /* Reset FIFO, disable FIFO and set start conversion source to none. - * Keep se/diff and bip/uni settings */ - devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK - | PCI230_ADC_IM_MASK)) | - PCI230_ADC_TRIG_NONE; - outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, - dev->iobase + PCI230_ADCCON); - - /* Release resources. */ - put_all_resources(dev, OWNER_AICMD); -} - -static int pci230_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - pci230_ai_stop(dev, s); - return 0; -} - /* Check if PCI device matches a specific board. */ static bool pci230_match_pci_board(const struct pci230_board *board, struct pci_dev *pci_dev) -- GitLab From 9f132652d94c96476b0b0a8caf0c10e96ab10fa8 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 5 Jun 2012 00:02:05 -0400 Subject: [PATCH 0421/6849] ACPI sysfs.c strlen fix Current code is ignoring the last character of "enable" and "disable" in comparisons. https://bugzilla.kernel.org/show_bug.cgi?id=33732 Signed-off-by: Len Brown --- drivers/acpi/sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 9f66181c814e..240a24400976 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; - if (!strncmp(val, "enable", strlen("enable") - 1)) { + if (!strncmp(val, "enable", strlen("enable"))) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) @@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) goto exit; } - if (!strncmp(val, "disable", strlen("disable") - 1)) { + if (!strncmp(val, "disable", strlen("disable"))) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); -- GitLab From 8a7245ea2c48641257ff149569b56650d0cfc99c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 20 May 2012 14:06:36 -0700 Subject: [PATCH 0422/6849] Staging: android: alarm: Rename pr_alarm to alarm_dbg Rename a macro to make it explicit it's for debugging. Use %s: __func__ instead of embedding function names. Coalesce formats, align arguments. Signed-off-by: Joe Perches Acked-by: David Rientjes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 34 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 53ce6ecf390a..32614d611283 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -29,16 +29,14 @@ #define ANDROID_ALARM_PRINT_IO (1U << 1) #define ANDROID_ALARM_PRINT_INT (1U << 2) - static int debug_mask = ANDROID_ALARM_PRINT_INFO; module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) +#define alarm_dbg(debug_level_mask, fmt, ...) \ +do { \ + if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) \ + pr_info(fmt, ##__VA_ARGS__); \ +} while (0) #define ANDROID_ALARM_WAKEUP_MASK ( \ ANDROID_ALARM_RTC_WAKEUP_MASK | \ @@ -138,7 +136,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm %d clear\n", alarm_type); + alarm_dbg(IO, "alarm %d clear\n", alarm_type); devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; @@ -167,8 +165,9 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, - new_alarm_time.tv_sec, new_alarm_time.tv_nsec); + alarm_dbg(IO, "alarm %d set %ld.%09ld\n", + alarm_type, + new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); @@ -179,7 +178,7 @@ from_old_alarm_set: /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); - pr_alarm(IO, "alarm wait\n"); + alarm_dbg(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { __pm_relax(&alarm_wake_lock); wait_pending = 0; @@ -260,9 +259,10 @@ static int alarm_release(struct inode *inode, struct file *file) for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { uint32_t alarm_type_mask = 1U << i; if (alarm_enabled & alarm_type_mask) { - pr_alarm(INFO, "alarm_release: clear alarm, " - "pending %d\n", - !!(alarm_pending & alarm_type_mask)); + alarm_dbg(INFO, + "%s: clear alarm, pending %d\n", + __func__, + !!(alarm_pending & alarm_type_mask)); alarm_enabled &= ~alarm_type_mask; } spin_unlock_irqrestore(&alarm_slock, flags); @@ -271,8 +271,8 @@ static int alarm_release(struct inode *inode, struct file *file) } if (alarm_pending | wait_pending) { if (alarm_pending) - pr_alarm(INFO, "alarm_release: clear " - "pending alarms %x\n", alarm_pending); + alarm_dbg(INFO, "%s: clear pending alarms %x\n", + __func__, alarm_pending); __pm_relax(&alarm_wake_lock); wait_pending = 0; alarm_pending = 0; @@ -288,7 +288,7 @@ static void devalarm_triggered(struct devalarm *alarm) unsigned long flags; uint32_t alarm_type_mask = 1U << alarm->type; - pr_alarm(INT, "devalarm_triggered type %d\n", alarm->type); + alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type); spin_lock_irqsave(&alarm_slock, flags); if (alarm_enabled & alarm_type_mask) { __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */ -- GitLab From 3fe192d8e0c99ca3b96573cdc7cc03cfcf935f74 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 21 May 2012 07:56:57 -0700 Subject: [PATCH 0423/6849] staging "rts_pstor" fix some typos while reading through rts_pstor Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/ms.c | 2 +- drivers/staging/rts_pstor/sd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index 0bf6d95b3fab..7cc2b53f20d0 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -2488,7 +2488,7 @@ int reset_ms_card(struct rtsx_chip *chip) if (!CHK_MSPRO(ms_card)) { /* Build table for the last segment, - * to check if L2P talbe block exist,erasing it + * to check if L2P table block exists, erasing it */ retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); if (retval != STATUS_SUCCESS) { diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index aab690932eae..b9474a8aefc0 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1169,7 +1169,7 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]); } else { /* Maximum current consumption, check whether current is acceptable; - * bit[511:496] = 0x0000 means some error happaned. + * bit[511:496] = 0x0000 means some error happened. */ u16 cc = ((u16)buf[0] << 8) | buf[1]; RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc); -- GitLab From 76cc6f92039208e04291af751c5d46568aa24162 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:53 -0400 Subject: [PATCH 0424/6849] Staging: bcm: Remove typedef from "eInterface_setting" in Adapter.h This patch removes the typedef from eInterface_setting, and renames the enum to bcm_einterface_setting. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index aa51d17be5a1..a67022f23871 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -585,9 +585,9 @@ int InitAdapter(PMINI_ADAPTER psAdapter); #define EP5 4 #define EP6 5 -typedef enum eInterface_setting { +enum bcm_einterface_setting { DEFAULT_SETTING_0 = 0, ALTERNATE_SETTING_1 = 1, -} INTERFACE_SETTING; +}; #endif /* __ADAPTER_H__ */ -- GitLab From be3099957ca9d465a46b83d08c1cd9617a461078 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:54 -0400 Subject: [PATCH 0425/6849] Staging: bcm: Remove typedef for _DDR_SETTING and call directly. This patch removes the typedef for _DDR_SETTING, changes the name of the struct from _DDR_SETTING, to bcm_ddr_setting. In addition, any calls to the following typedefs "DDR_SET_NODE and *PDDR_SET_NODE" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 5 ++- drivers/staging/bcm/DDRInit.c | 62 +++++++++++++++++------------------ 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index a67022f23871..9b788563a014 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -549,11 +549,10 @@ typedef struct _cntl_pkt { } cntl_pkt; typedef LINK_REQUEST CONTROL_MESSAGE; -typedef struct _DDR_SETTING { +struct bcm_ddr_setting { UINT ulRegAddress; UINT ulRegValue; -} DDR_SETTING, *PDDR_SETTING; -typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE; +}; int InitAdapter(PMINI_ADAPTER psAdapter); /* ===================================================================== diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 2b46f4d4ef0e..e7571da81216 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -7,7 +7,7 @@ //DDR INIT-133Mhz #define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 //index for 0x0F007000 -static DDR_SET_NODE asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting {0x0F000800,0x00007212}, {0x0f000820,0x07F13FFF}, {0x0f000810,0x00000F95}, @@ -65,7 +65,7 @@ static DDR_SET_NODE asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting }; //80Mhz #define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 //index for 0x0F007000 -static DDR_SET_NODE asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting {0x0f000810,0x00000F95}, {0x0f000820,0x07f1ffff}, {0x0f000860,0x00000000}, @@ -117,7 +117,7 @@ static DDR_SET_NODE asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting }; //100Mhz #define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 //index for 0x0F007000 -static DDR_SET_NODE asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting {0x0F000800,0x00007008}, {0x0f000810,0x00000F95}, {0x0f000820,0x07F13E3F}, @@ -177,7 +177,7 @@ static DDR_SET_NODE asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting //Net T3B DDR Settings //DDR INIT-133Mhz -static DDR_SET_NODE asDPLL_266MHZ[] = { +static struct bcm_ddr_setting asDPLL_266MHZ[] = { {0x0F000800,0x00007212}, {0x0f000820,0x07F13FFF}, {0x0f000810,0x00000F95}, @@ -189,7 +189,7 @@ static DDR_SET_NODE asDPLL_266MHZ[] = { }; #define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000 -static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting {0x0f000810,0x00000F95}, {0x0f000810,0x00000F95}, {0x0f000810,0x00000F95}, @@ -247,7 +247,7 @@ static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting }; #define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 -static DDR_SET_NODE asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting {0x0f000810,0x00000F95}, {0x0f000820,0x07F13FFF}, {0x0f000840,0x0FFF1F00}, @@ -301,7 +301,7 @@ static DDR_SET_NODE asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting //100Mhz #define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 //index for 0x0F007000 -static DDR_SET_NODE asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting {0x0f000810,0x00000F95}, {0x0f000820,0x07F1369B}, {0x0f000840,0x0FFF0800}, @@ -356,7 +356,7 @@ static DDR_SET_NODE asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 //index for 0x0F007000 -static DDR_SET_NODE asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting {0x0f000820,0x03F1365B}, {0x0f000810,0x00002F95}, {0x0f000880,0x000003DD}, @@ -416,7 +416,7 @@ static DDR_SET_NODE asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting }; #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 //index for 0x0F007000 -static DDR_SET_NODE asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting {0x0f000810,0x00002F95}, {0x0f000820,0x03F1369B}, {0x0f000840,0x0fff0000}, @@ -476,7 +476,7 @@ static DDR_SET_NODE asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting }; #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 -static DDR_SET_NODE asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting {0x0f000820,0x07F13FFF}, {0x0f000810,0x00002F95}, {0x0f000860,0x00000000}, @@ -536,7 +536,7 @@ static DDR_SET_NODE asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting ///T3 LP-B (UMA-B) #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 //index for 0x0F007000 -static DDR_SET_NODE asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting {0x0f000820,0x03F137DB}, {0x0f000810,0x01842795}, @@ -594,7 +594,7 @@ static DDR_SET_NODE asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 //index for 0x0F007000 -static DDR_SET_NODE asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting {0x0f000820,0x03F1365B}, {0x0f000810,0x00002F95}, {0x0f000880,0x000003DD}, @@ -655,7 +655,7 @@ static DDR_SET_NODE asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting }; #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 //index for 0x0F007000 -static DDR_SET_NODE asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting {0x0f000810,0x00002F95}, {0x0f000820,0x03F1369B}, {0x0f000840,0x0fff0000}, @@ -716,7 +716,7 @@ static DDR_SET_NODE asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting }; #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 //index for 0x0F007000 -static DDR_SET_NODE asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting +static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting {0x0f000820,0x07F13FFF}, {0x0f000810,0x00002F95}, {0x0f000860,0x00000000}, @@ -774,7 +774,7 @@ static DDR_SET_NODE asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting int ddr_init(MINI_ADAPTER *Adapter) { - PDDR_SETTING psDDRSetting=NULL; + struct bcm_ddr_setting *psDDRSetting=NULL; ULONG RegCount=0; UINT value = 0; UINT uiResetValue = 0; @@ -789,17 +789,17 @@ int ddr_init(MINI_ADAPTER *Adapter) case DDR_80_MHZ: psDDRSetting=asT3LP_DDRSetting80MHz; RegCount=(sizeof(asT3LP_DDRSetting80MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: psDDRSetting=asT3LP_DDRSetting100MHz; RegCount=(sizeof(asT3LP_DDRSetting100MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: psDDRSetting=asT3LP_DDRSetting133MHz; RegCount=(sizeof(asT3LP_DDRSetting133MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); if(Adapter->bMipsConfig == MIPS_200_MHZ) { uiClockSetting = 0x03F13652; @@ -846,17 +846,17 @@ int ddr_init(MINI_ADAPTER *Adapter) case DDR_80_MHZ: psDDRSetting = asT3LPB_DDRSetting80MHz; RegCount=(sizeof(asT3B_DDRSetting80MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: psDDRSetting=asT3LPB_DDRSetting100MHz; RegCount=(sizeof(asT3B_DDRSetting100MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: psDDRSetting = asT3LPB_DDRSetting133MHz; RegCount=(sizeof(asT3B_DDRSetting133MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); if(Adapter->bMipsConfig == MIPS_200_MHZ) { @@ -870,7 +870,7 @@ int ddr_init(MINI_ADAPTER *Adapter) case DDR_160_MHZ: psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SETTING); + RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(struct bcm_ddr_setting); if(Adapter->bMipsConfig == MIPS_200_MHZ) { @@ -894,17 +894,17 @@ int ddr_init(MINI_ADAPTER *Adapter) case DDR_80_MHZ: psDDRSetting = asT3_DDRSetting80MHz; RegCount = (sizeof(asT3_DDRSetting80MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: psDDRSetting = asT3_DDRSetting100MHz; RegCount = (sizeof(asT3_DDRSetting100MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: psDDRSetting = asT3_DDRSetting133MHz; RegCount = (sizeof(asT3_DDRSetting133MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; default: return -EINVAL; @@ -916,12 +916,12 @@ int ddr_init(MINI_ADAPTER *Adapter) case DDR_80_MHZ: psDDRSetting = asT3B_DDRSetting80MHz; RegCount=(sizeof(asT3B_DDRSetting80MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: psDDRSetting=asT3B_DDRSetting100MHz; RegCount=(sizeof(asT3B_DDRSetting100MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: @@ -931,13 +931,13 @@ int ddr_init(MINI_ADAPTER *Adapter) sizeof(asDPLL_266MHZ)); psDDRSetting = asT3B_DDRSetting133MHz; RegCount=(sizeof(asT3B_DDRSetting133MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); } else { psDDRSetting = asT3B_DDRSetting133MHz; RegCount=(sizeof(asT3B_DDRSetting133MHz)/ - sizeof(DDR_SETTING)); + sizeof(struct bcm_ddr_setting)); if(Adapter->bMipsConfig == MIPS_200_MHZ) { uiClockSetting = 0x07F13652; @@ -1101,7 +1101,7 @@ int ddr_init(MINI_ADAPTER *Adapter) int download_ddr_settings(PMINI_ADAPTER Adapter) { - PDDR_SET_NODE psDDRSetting=NULL; + struct bcm_ddr_setting *psDDRSetting=NULL; ULONG RegCount=0; unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY; UINT value = 0; @@ -1250,7 +1250,7 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) } ul_ddr_setting_load_addr+=sizeof(ULONG); - RegCount*=(sizeof(DDR_SETTING)/sizeof(ULONG)); + RegCount*=(sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); while(RegCount && !retval) { -- GitLab From 7905c78816783dff5d167cf922557e35e8c1a45f Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:55 -0400 Subject: [PATCH 0426/6849] Staging: bcm: Remove typedef for _cntl_pkt in Adapter.h This patch removes typedef for _cntl_pkt because it is not used. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 9b788563a014..45c2e8c35980 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -543,10 +543,7 @@ typedef struct FirmwareInfo { /* holds the value of net_device structure.. */ extern struct net_device *gblpnetdev; -typedef struct _cntl_pkt { - PMINI_ADAPTER Adapter; - PLEADER PLeader; -} cntl_pkt; + typedef LINK_REQUEST CONTROL_MESSAGE; struct bcm_ddr_setting { -- GitLab From 7a27a2ccf8a6368f6d7f77cb02f5c5c698015c2e Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:56 -0400 Subject: [PATCH 0427/6849] Staging: bcm: Remove typedef for FirmwareInfo and call directly. This patch removes typedef for FirmwareInfo, changes the name from Firmwareinfo to bcm_firmware_info. In addition, any calls to the following typedefs "PFIRMWARE_INFO, FIRMWARE_INFO" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 4 ++-- drivers/staging/bcm/Bcmchar.c | 4 ++-- drivers/staging/bcm/InterfaceDld.c | 4 ++-- drivers/staging/bcm/Prototypes.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 45c2e8c35980..12a43fb92c18 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -535,11 +535,11 @@ struct _ETH_HEADER_STRUC { } __packed; typedef struct _ETH_HEADER_STRUC ETH_HEADER_STRUC, *PETH_HEADER_STRUC; -typedef struct FirmwareInfo { +struct bcm_firmware_info { void __user *pvMappedFirmwareAddress; ULONG u32FirmwareLength; ULONG u32StartingAddress; -} __packed FIRMWARE_INFO, *PFIRMWARE_INFO; +} __packed; /* holds the value of net_device structure.. */ extern struct net_device *gblpnetdev; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index cf3059216958..cd0348e5914d 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -787,7 +787,7 @@ cntrlEnd: } case IOCTL_BCM_BUFFER_DOWNLOAD: { - FIRMWARE_INFO *psFwInfo = NULL; + struct bcm_firmware_info *psFwInfo = NULL; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); if (!down_trylock(&Adapter->fw_download_sema)) { @@ -807,7 +807,7 @@ cntrlEnd: BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n", IoBuffer.InputLength); - if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) { + if (IoBuffer.InputLength > sizeof(struct bcm_firmware_info)) { up(&Adapter->fw_download_sema); return -EINVAL; } diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 65c352f35681..cb0e72ee0789 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -132,7 +132,7 @@ exit: return Status; } -static int bcm_download_config_file(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) +static int bcm_download_config_file(PMINI_ADAPTER Adapter, struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; B_UINT32 value = 0; @@ -229,7 +229,7 @@ static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char return retval; } -int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) +int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; PUCHAR buff = NULL; diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index b80b806c90a3..a8676b9b0624 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -92,7 +92,7 @@ int ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *buf); void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, PPER_TARANG_DATA pTarang); void beceem_parse_target_struct(PMINI_ADAPTER Adapter); -int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo); +int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, struct bcm_firmware_info *psFwInfo); void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter, CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex); -- GitLab From 406a50826fb728ff3105907a2bf3e3180667e122 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:57 -0400 Subject: [PATCH 0428/6849] Staging: bcm: Remove typedef for _ETH_HEADER_STRUC and call directly. This patch removes typedef for _ETH_HEADER_STRUC, changes the name of the struct from _ETH_HEADER_STRUC to bcm_eth_header. In addition, any calls to the following typedefs "ETH_HEADER_STRUC, *PETH_HEADER_STRUC" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 3 +-- drivers/staging/bcm/Protocol.h | 8 ++++---- drivers/staging/bcm/Qos.c | 12 ++++++------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 12a43fb92c18..338f1acfdd18 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -528,12 +528,11 @@ typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER; #define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) -struct _ETH_HEADER_STRUC { +struct bcm_eth_header { UCHAR au8DestinationAddress[6]; UCHAR au8SourceAddress[6]; USHORT u16Etype; } __packed; -typedef struct _ETH_HEADER_STRUC ETH_HEADER_STRUC, *PETH_HEADER_STRUC; struct bcm_firmware_info { void __user *pvMappedFirmwareAddress; diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h index b8a4009bdf0c..562d4dd81a7c 100644 --- a/drivers/staging/bcm/Protocol.h +++ b/drivers/staging/bcm/Protocol.h @@ -55,7 +55,7 @@ typedef struct _S_ETHCS_PKT_INFO typedef struct _ETH_CS_802_Q_FRAME { - ETH_HEADER_STRUC EThHdr; + struct bcm_eth_header EThHdr; USHORT UserPriority:3; USHORT CFI:1; USHORT VLANID:12; @@ -64,7 +64,7 @@ typedef struct _ETH_CS_802_Q_FRAME typedef struct _ETH_CS_802_LLC_FRAME { - ETH_HEADER_STRUC EThHdr; + struct bcm_eth_header EThHdr; unsigned char DSAP; unsigned char SSAP; unsigned char Control; @@ -72,7 +72,7 @@ typedef struct _ETH_CS_802_LLC_FRAME typedef struct _ETH_CS_802_LLC_SNAP_FRAME { - ETH_HEADER_STRUC EThHdr; + struct bcm_eth_header EThHdr; unsigned char DSAP; unsigned char SSAP; unsigned char Control; @@ -82,7 +82,7 @@ typedef struct _ETH_CS_802_LLC_SNAP_FRAME typedef struct _ETH_CS_ETH2_FRAME { - ETH_HEADER_STRUC EThHdr; + struct bcm_eth_header EThHdr; } __attribute__((packed)) ETH_CS_ETH2_FRAME; #define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800) diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index c97020f0fb6a..9bf61ff6ac78 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -733,7 +733,7 @@ static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct s if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame) return FALSE; - uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xF000) >> 13; + uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(struct bcm_eth_header))) & 0xF000) >> 13; if((uPriority >= pstClassifierRule->usUserPriority[0]) && (uPriority <= pstClassifierRule->usUserPriority[1])) bClassificationSucceed = TRUE; @@ -751,7 +751,7 @@ static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct s if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame) return FALSE; - usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xFFF; + usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(struct bcm_eth_header))) & 0xFFF; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__,usVLANID, uPriority); @@ -774,12 +774,12 @@ static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb, B_UINT8 EthCSCupport) { BOOLEAN bClassificationSucceed = FALSE; - bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress); + bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((struct bcm_eth_header *)(skb->data))->au8SourceAddress); if(!bClassificationSucceed) return FALSE; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS SrcMAC Matched\n"); - bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,((ETH_HEADER_STRUC*)(skb->data))->au8DestinationAddress); + bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,((struct bcm_eth_header *)(skb->data))->au8DestinationAddress); if(!bClassificationSucceed) return FALSE; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS DestMAC Matched\n"); @@ -804,7 +804,7 @@ static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb, static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload, PS_ETHCS_PKT_INFO pstEthCsPktInfo) { - USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype); + USHORT u16Etype = ntohs(((struct bcm_eth_header *)pvEthPayload)->u16Etype); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype); if(u16Etype > 0x5dc) @@ -845,7 +845,7 @@ static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload, else pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket; - pstEthCsPktInfo->usEtherType = ((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype; + pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo->eNwpktIPFrameType); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo->eNwpktEthFrameType); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo->usEtherType); -- GitLab From 3753164384a99c52682ba6dc38a9c8a87ecf55ad Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:58 -0400 Subject: [PATCH 0429/6849] Staging: bcm: Remove typedef for _STTARGETDSXBUFFER and call directly. This patch removes typedef for _STTARGETDSXBUFFER, changes the name of the struct from _STTARGETDSXBUFFER to bcm_targetdsx_buffer. In addition, any calls to the following typedefs "STTARGETDSXBUFFER, *PSTTARGETDSXBUFFER" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 338f1acfdd18..1d18ef9dd35c 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -332,11 +332,11 @@ typedef struct _TARGET_PARAMS { } STARGETPARAMS, *PSTARGETPARAMS; #endif -typedef struct _STTARGETDSXBUFFER { +struct bcm_targetdsx_buffer { ULONG ulTargetDsxBuffer; B_UINT16 tid; BOOLEAN valid; -} STTARGETDSXBUFFER, *PSTTARGETDSXBUFFER; +}; typedef int (*FP_FLASH_WRITE)(struct _MINI_ADAPTER *, UINT, PVOID); @@ -404,7 +404,7 @@ struct _MINI_ADAPTER { UINT index_datpkt; struct semaphore rdmwrmsync; - STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; + struct bcm_targetdsx_buffer astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; ULONG ulFreeTargetBufferCnt; ULONG ulCurrentTargetBuffer; ULONG ulTotalTargetBuffersAvailable; -- GitLab From d0830f6c44050b78fde2fca8597d04064854cd87 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:04:59 -0400 Subject: [PATCH 0430/6849] Staging: bcm: Remove condition check on macro REL_4_1 because it is not used. This patch removes the conditional check on macro REL_4_1, and the corresponding controlled text because it is not used. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 81 ----------------------------------- drivers/staging/bcm/Macros.h | 4 -- 2 files changed, 85 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 1d18ef9dd35c..ade2b0d67974 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -251,87 +251,6 @@ typedef struct _PER_TARANG_DATA { ULONG RxCntrlMsgBitMask; } PER_TARANG_DATA, *PPER_TARANG_DATA; -#ifdef REL_4_1 -typedef struct _TARGET_PARAMS { - B_UINT32 m_u32CfgVersion; - - /* Scanning Related Params */ - B_UINT32 m_u32CenterFrequency; - B_UINT32 m_u32BandAScan; - B_UINT32 m_u32BandBScan; - B_UINT32 m_u32BandCScan; - - /* QoS Params */ - B_UINT32 m_u32minGrantsize; /* size of minimum grant is 0 or 6 */ - B_UINT32 m_u32PHSEnable; - - /* HO Params */ - B_UINT32 m_u32HoEnable; - B_UINT32 m_u32HoReserved1; - B_UINT32 m_u32HoReserved2; - - /* Power Control Params */ - B_UINT32 m_u32MimoEnable; - B_UINT32 m_u32SecurityEnable; - /* - * bit 1: 1 Idlemode enable; - * bit 2: 1 Sleepmode Enable - */ - B_UINT32 m_u32PowerSavingModesEnable; - /* PowerSaving Mode Options: - * bit 0 = 1: CPE mode - to keep pcmcia if alive; - * bit 1 = 1: CINR reporing in Idlemode Msg - * bit 2 = 1: Default PSC Enable in sleepmode - */ - B_UINT32 m_u32PowerSavingModeOptions; - - B_UINT32 m_u32ArqEnable; - - /* From Version #3, the HARQ section renamed as general */ - B_UINT32 m_u32HarqEnable; - /* EEPROM Param Location */ - B_UINT32 m_u32EEPROMFlag; - /* BINARY TYPE - 4th MSByte: - * Interface Type - 3rd MSByte: - * Vendor Type - 2nd MSByte - */ - /* Unused - LSByte */ - B_UINT32 m_u32Customize; - B_UINT32 m_u32ConfigBW; /* In Hz */ - B_UINT32 m_u32ShutDownTimer; - B_UINT32 m_u32RadioParameter; - B_UINT32 m_u32PhyParameter1; - B_UINT32 m_u32PhyParameter2; - B_UINT32 m_u32PhyParameter3; - - /* in eval mode only; - * lower 16bits = basic cid for testing; - * then bit 16 is test cqich, - * bit 17 test init rang; - * bit 18 test periodic rang - * bit 19 is test harq ack/nack - */ - B_UINT32 m_u32TestOptions; - B_UINT32 m_u32MaxMACDataperDLFrame; - B_UINT32 m_u32MaxMACDataperULFrame; - B_UINT32 m_u32Corr2MacFlags; - - /* adding driver params. */ - B_UINT32 HostDrvrConfig1; - B_UINT32 HostDrvrConfig2; - B_UINT32 HostDrvrConfig3; - B_UINT32 HostDrvrConfig4; - B_UINT32 HostDrvrConfig5; - B_UINT32 HostDrvrConfig6; - B_UINT32 m_u32SegmentedPUSCenable; - - /* BAMC enable - but 4.x does not support this feature - * This is added just to sync 4.x and 5.x CFGs - */ - B_UINT32 m_u32BandAMCEnable; -} STARGETPARAMS, *PSTARGETPARAMS; -#endif - struct bcm_targetdsx_buffer { ULONG ulTargetDsxBuffer; B_UINT16 tid; diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 46ed99c53764..8238cdba7a0f 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -252,11 +252,7 @@ typedef enum _E_PHS_DSC_ACTION { #define IDLE_MODE_WAKEUP_NOTIFIER_ADDRESS 0x1FC02FA8 #define IDLE_MODE_MAX_RETRY_COUNT 1000 -#ifdef REL_4_1 -#define CONFIG_BEGIN_ADDR 0xBF60B004 -#else #define CONFIG_BEGIN_ADDR 0xBF60B000 -#endif #define FIRMWARE_BEGIN_ADDR 0xBFC00000 -- GitLab From 774bea8314c3fa59a977e64114286d6e3341b7cc Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:00 -0400 Subject: [PATCH 0431/6849] Staging: bcm: Remove typedef for _PER_TARANG_DATA and call directly. This patch removes typedef for _PER_TARANG_DATA, changes the name of the struct from _PER_TARANG_DATA to bcm_per_tarang_data. In addition, any calls to the following typedefs "PER_TARANG_DATA, *PPER_TARANG_DATA" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 8 ++++---- drivers/staging/bcm/Bcmchar.c | 12 ++++++------ drivers/staging/bcm/HandleControlPacket.c | 4 ++-- drivers/staging/bcm/Prototypes.h | 2 +- drivers/staging/bcm/hostmibs.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index ade2b0d67974..7f58322e68b4 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -239,8 +239,8 @@ struct _packet_info { }; typedef struct _packet_info PacketInfo; -typedef struct _PER_TARANG_DATA { - struct _PER_TARANG_DATA *next; +struct bcm_tarang_data { + struct bcm_tarang_data *next; struct _MINI_ADAPTER *Adapter; struct sk_buff *RxAppControlHead; struct sk_buff *RxAppControlTail; @@ -249,7 +249,7 @@ typedef struct _PER_TARANG_DATA { BOOLEAN bApplicationToExit; S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs; ULONG RxCntrlMsgBitMask; -} PER_TARANG_DATA, *PPER_TARANG_DATA; +}; struct bcm_targetdsx_buffer { ULONG ulTargetDsxBuffer; @@ -280,7 +280,7 @@ struct _MINI_ADAPTER { struct sk_buff *RxControlTail; struct semaphore RxAppControlQueuelock; struct semaphore fw_download_sema; - PPER_TARANG_DATA pTarangs; + struct bcm_tarang_data *pTarangs; spinlock_t control_queue_lock; wait_queue_head_t process_read_wait_queue; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index cd0348e5914d..03dc2b010450 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -16,10 +16,10 @@ static int bcm_char_open(struct inode *inode, struct file * filp) { PMINI_ADAPTER Adapter = NULL; - PPER_TARANG_DATA pTarang = NULL; + struct bcm_tarang_data *pTarang = NULL; Adapter = GET_BCM_ADAPTER(gblpnetdev); - pTarang = kzalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL); + pTarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL); if (!pTarang) return -ENOMEM; @@ -43,11 +43,11 @@ static int bcm_char_open(struct inode *inode, struct file * filp) static int bcm_char_release(struct inode *inode, struct file *filp) { - PPER_TARANG_DATA pTarang, tmp, ptmp; + struct bcm_tarang_data *pTarang, *tmp, *ptmp; PMINI_ADAPTER Adapter = NULL; struct sk_buff *pkt, *npkt; - pTarang = (PPER_TARANG_DATA)filp->private_data; + pTarang = (struct bcm_tarang_data *)filp->private_data; if (pTarang == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, @@ -97,7 +97,7 @@ static int bcm_char_release(struct inode *inode, struct file *filp) static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) { - PPER_TARANG_DATA pTarang = filp->private_data; + struct bcm_tarang_data *pTarang = filp->private_data; PMINI_ADAPTER Adapter = pTarang->Adapter; struct sk_buff *Packet = NULL; ssize_t PktLen = 0; @@ -155,7 +155,7 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { - PPER_TARANG_DATA pTarang = filp->private_data; + struct bcm_tarang_data *pTarang = filp->private_data; void __user *argp = (void __user *)arg; PMINI_ADAPTER Adapter = pTarang->Adapter; INT Status = STATUS_FAILURE; diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c index b058e30b2ca6..691b366bfe4f 100644 --- a/drivers/staging/bcm/HandleControlPacket.c +++ b/drivers/staging/bcm/HandleControlPacket.c @@ -13,7 +13,7 @@ */ static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb) { - PPER_TARANG_DATA pTarang = NULL; + struct bcm_tarang_data *pTarang = NULL; BOOLEAN HighPriorityMessage = FALSE; struct sk_buff *newPacket = NULL; CHAR cntrl_msg_mask_bit = 0; @@ -214,7 +214,7 @@ int control_packet_handler(PMINI_ADAPTER Adapter /* pointer to adapter object*/) INT flushAllAppQ(void) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - PPER_TARANG_DATA pTarang = NULL; + struct bcm_tarang_data *pTarang = NULL; struct sk_buff *PacketToDrop = NULL; for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { while (pTarang->RxAppControlHead != NULL) { diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index a8676b9b0624..b22f61d96c49 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -89,7 +89,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter); int ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *buf); -void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, PPER_TARANG_DATA pTarang); +void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, struct bcm_tarang_data *pTarang); void beceem_parse_target_struct(PMINI_ADAPTER Adapter); int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, struct bcm_firmware_info *psFwInfo); diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c index 101c4e31249e..27ddcbfd5935 100644 --- a/drivers/staging/bcm/hostmibs.c +++ b/drivers/staging/bcm/hostmibs.c @@ -94,7 +94,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMib return STATUS_SUCCESS; } -VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, const PPER_TARANG_DATA pTarang) +VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, struct bcm_tarang_data *pTarang) { memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs), &(pTarang->stDroppedAppCntrlMsgs), -- GitLab From 0b3edf760a56cf5372d2dafa35b400561ddc0eb0 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:01 -0400 Subject: [PATCH 0432/6849] Staging: bcm: Remove typedef for _packet_info and call directly. This patch removes typedef for _packet_info, changes the name of the struct from _packet_info to bcm_packet_info. In addition, any calls to the following typedefs "PacketInfo, _packet_info" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 6 ++---- drivers/staging/bcm/Bcmchar.c | 2 +- drivers/staging/bcm/CmHost.c | 2 +- drivers/staging/bcm/LeakyBucket.c | 6 +++--- drivers/staging/bcm/sort.c | 6 +++--- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 7f58322e68b4..20ac2b3ecdd2 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -99,7 +99,6 @@ typedef union _U_IP_ADDRESS { UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; }; } U_IP_ADDRESS; -struct _packet_info; typedef struct _S_HDR_SUPRESSION_CONTEXTINFO { UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; /* Intermediate buffer to accumulate pkt Header for PHS */ @@ -168,7 +167,7 @@ typedef struct _S_FRAGMENTED_PACKET_INFO { BOOLEAN bOutOfOrderFragment; } S_FRAGMENTED_PACKET_INFO, *PS_FRAGMENTED_PACKET_INFO; -struct _packet_info { +struct bcm_packet_info { /* classification extension Rule */ ULONG ulSFID; USHORT usVCID_Value; @@ -237,7 +236,6 @@ struct _packet_info { UCHAR bIPCSSupport; UCHAR bEthCSSupport; }; -typedef struct _packet_info PacketInfo; struct bcm_tarang_data { struct bcm_tarang_data *next; @@ -296,7 +294,7 @@ struct _MINI_ADAPTER { USHORT PrevNumRecvDescs; USHORT CurrNumRecvDescs; UINT u32TotalDSD; - PacketInfo PackInfo[NO_OF_QUEUES]; + struct bcm_packet_info PackInfo[NO_OF_QUEUES]; S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS]; BOOLEAN TransferMode; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 03dc2b010450..8d4052a7deae 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -971,7 +971,7 @@ cntrlEnd: break; case IOCTL_GET_PACK_INFO: - if (copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES)) + if (copy_to_user(argp, &Adapter->PackInfo, sizeof(struct bcm_packet_info)*NO_OF_QUEUES)) return -EFAULT; Status = STATUS_SUCCESS; break; diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 7e38af5e1765..f584fdc6be44 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1918,7 +1918,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /* "); /* Validate the parameters */ @@ -113,7 +113,7 @@ This function despatches packet from the specified queue. @return Zero(success) or Negative value(failure) */ static INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**bValid || !pb->bValid) return 0; @@ -27,7 +27,7 @@ VOID SortPackInfo(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); - sort(Adapter->PackInfo, NO_OF_QUEUES, sizeof(PacketInfo), + sort(Adapter->PackInfo, NO_OF_QUEUES, sizeof(struct bcm_packet_info), compare_packet_info, NULL); } -- GitLab From 7f22485def175b9378019b90a1a54cd8f5df0af0 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:02 -0400 Subject: [PATCH 0433/6849] Staging: bcm: Remove typedef for _S_FRAGMENTED_PACKET_INFO and call directly. This patch removes typedef for _S_FRAGMENTED_PACKET_INFO, changes the name of the struct from _S_FRAGMENTED_PACKET_INFO to bcm_fragmented_packet_info. In addition, any calls to the following typedefs "S_FRAGMENTED_PACKET_INFO, *PS_FRAGMENTED_PACKET_INFO" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 6 +++--- drivers/staging/bcm/Misc.c | 8 ++++---- drivers/staging/bcm/Prototypes.h | 2 +- drivers/staging/bcm/Qos.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 20ac2b3ecdd2..f604b1bfa45d 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -159,13 +159,13 @@ typedef struct _S_CLASSIFIER_RULE { } S_CLASSIFIER_RULE; /* typedef struct _S_CLASSIFIER_RULE S_CLASSIFIER_RULE; */ -typedef struct _S_FRAGMENTED_PACKET_INFO { +struct bcm_fragmented_packet_info { BOOLEAN bUsed; ULONG ulSrcIpAddress; USHORT usIpIdentification; S_CLASSIFIER_RULE *pstMatchedClassifierEntry; BOOLEAN bOutOfOrderFragment; -} S_FRAGMENTED_PACKET_INFO, *PS_FRAGMENTED_PACKET_INFO; +}; struct bcm_packet_info { /* classification extension Rule */ @@ -389,7 +389,7 @@ struct _MINI_ADAPTER { BOOLEAN bDPLLConfig; UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - S_FRAGMENTED_PACKET_INFO astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES]; + struct bcm_fragmented_packet_info astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES]; atomic_t uiMBupdate; UINT32 PmuMode; NVM_TYPE eNVMType; diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 8223a6913fc5..3ca962d6adee 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1533,12 +1533,12 @@ S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentific return NULL; } -void AddFragIPClsEntry(PMINI_ADAPTER Adapter, PS_FRAGMENTED_PACKET_INFO psFragPktInfo) +void AddFragIPClsEntry(PMINI_ADAPTER Adapter, struct bcm_fragmented_packet_info *psFragPktInfo) { UINT uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) { - memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(S_FRAGMENTED_PACKET_INFO)); + memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info)); break; } } @@ -1552,7 +1552,7 @@ void DelFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG S (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIp)) - memset(&Adapter->astFragmentedPktClassifierTable[uiIndex], 0, sizeof(S_FRAGMENTED_PACKET_INFO)); + memset(&Adapter->astFragmentedPktClassifierTable[uiIndex], 0, sizeof(struct bcm_fragmented_packet_info)); } } @@ -1652,7 +1652,7 @@ static void beceem_protocol_reset(PMINI_ADAPTER Adapter) if (Adapter->TimerActive == TRUE) Adapter->TimerActive = FALSE; - memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); + memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(struct bcm_fragmented_packet_info) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); for (i = 0; i < HiPriority; i++) { /* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */ diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index b22f61d96c49..4bb3796c9c5a 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -103,7 +103,7 @@ int InitLedSettings(PMINI_ADAPTER Adapter); S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP); -void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo); +void AddFragIPClsEntry(PMINI_ADAPTER Adapter, struct bcm_fragmented_packet_info *psFragPktInfo); void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp); diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index 9bf61ff6ac78..c87801cdd866 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -631,7 +631,7 @@ USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) if(bFragmentedPkt && (usCurrFragment == 0)) { //First Fragment of Fragmented Packet. Create Frag CLS Entry - S_FRAGMENTED_PACKET_INFO stFragPktInfo; + struct bcm_fragmented_packet_info stFragPktInfo; stFragPktInfo.bUsed = TRUE; stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr; stFragPktInfo.usIpIdentification = pIpHeader->id; -- GitLab From 92562aeec46c965821c59f78e58f1cfe0a47bbaf Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:03 -0400 Subject: [PATCH 0434/6849] Staging: bcm: Remove typedef for _S_CLASSIFIER_RULE and call directly. This patch removes typedef for _S_CLASSIFIER_RULE, changes the name of the struct from _S_CLASSIFIER_RULE to bcm_classifier_rule. In addition, any calls to the following typedefs "S_CLASSIFIER_RULE" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 9 ++++---- drivers/staging/bcm/CmHost.c | 10 ++++----- drivers/staging/bcm/IPv6Protocol.c | 10 ++++----- drivers/staging/bcm/IPv6ProtocolHdr.h | 8 +++---- drivers/staging/bcm/Misc.c | 4 ++-- drivers/staging/bcm/Prototypes.h | 8 +++---- drivers/staging/bcm/Qos.c | 30 +++++++++++++-------------- drivers/staging/bcm/sort.c | 6 +++--- 8 files changed, 42 insertions(+), 43 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index f604b1bfa45d..d2260fe8c2a1 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -105,7 +105,7 @@ typedef struct _S_HDR_SUPRESSION_CONTEXTINFO { UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; /* Intermediate buffer containing pkt Header after PHS */ } S_HDR_SUPRESSION_CONTEXTINFO; -typedef struct _S_CLASSIFIER_RULE { +struct bcm_classifier_rule { ULONG ulSFID; UCHAR ucReserved[2]; B_UINT16 uiClassifierRuleIndex; @@ -156,14 +156,13 @@ typedef struct _S_CLASSIFIER_RULE { UCHAR usUserPriority[2]; USHORT usVLANID; USHORT usValidityBitMap; -} S_CLASSIFIER_RULE; -/* typedef struct _S_CLASSIFIER_RULE S_CLASSIFIER_RULE; */ +}; struct bcm_fragmented_packet_info { BOOLEAN bUsed; ULONG ulSrcIpAddress; USHORT usIpIdentification; - S_CLASSIFIER_RULE *pstMatchedClassifierEntry; + struct bcm_classifier_rule *pstMatchedClassifierEntry; BOOLEAN bOutOfOrderFragment; }; @@ -295,7 +294,7 @@ struct _MINI_ADAPTER { USHORT CurrNumRecvDescs; UINT u32TotalDSD; struct bcm_packet_info PackInfo[NO_OF_QUEUES]; - S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS]; + struct bcm_classifier_rule astClassifierTable[MAX_CLASSIFIERS]; BOOLEAN TransferMode; /*************** qos ******************/ diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index f584fdc6be44..a0b1720aae3e 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -112,7 +112,7 @@ static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) } static inline VOID -CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, +CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry, B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc, BOOLEAN bIpVersion6, E_IPADDR_CONTEXT eIpAddrContext) { @@ -238,7 +238,7 @@ void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter, B_UINT16 TID, BOOLEAN bFreeAll) */ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSLTypes *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex) { - S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + struct bcm_classifier_rule *pstClassifierEntry = NULL; /* VOID *pvPhsContext = NULL; */ int i; /* UCHAR ucProtocolLength=0; */ @@ -367,7 +367,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL */ static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex, UINT nClassifierIndex) { - S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + struct bcm_classifier_rule *pstClassifierEntry = NULL; B_UINT16 u16PacketClassificationRuleIndex; USHORT usVCID; /* VOID *pvPhsContext = NULL; */ @@ -386,7 +386,7 @@ static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSear if (pstClassifierEntry) { pstClassifierEntry->bUsed = FALSE; pstClassifierEntry->uiClassifierRuleIndex = 0; - memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_RULE)); + memset(pstClassifierEntry, 0, sizeof(struct bcm_classifier_rule)); /* Delete the PHS Rule for this classifier */ PhsDeleteClassifierRule(&Adapter->stBCMPhsContext, usVCID, u16PacketClassificationRuleIndex); @@ -398,7 +398,7 @@ static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSear */ VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) { - S_CLASSIFIER_RULE *pstClassifierEntry = NULL; + struct bcm_classifier_rule *pstClassifierEntry = NULL; int i; /* B_UINT16 u16PacketClassificationRuleIndex; */ USHORT ulVCID; diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 1da21642c18e..4adbf9dbf7b5 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -1,8 +1,8 @@ #include "headers.h" -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, +static BOOLEAN MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule, IPV6Header *pstIpv6Header); -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, +static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, IPV6Header *pstIpv6Header); static VOID DumpIpv6Header(IPV6Header *pstIpv6Header); @@ -181,7 +181,7 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet */ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, - S_CLASSIFIER_RULE *pstClassifierRule) + struct bcm_classifier_rule *pstClassifierRule) { USHORT ushDestPort = 0; USHORT ushSrcPort = 0; @@ -288,7 +288,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, } -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, +static BOOLEAN MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule, IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; @@ -344,7 +344,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, return FALSE; } -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, +static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, IPV6Header *pstIpv6Header) { UINT uiLoopIndex = 0; diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h index a0db5a1de763..369b55316c79 100644 --- a/drivers/staging/bcm/IPv6ProtocolHdr.h +++ b/drivers/staging/bcm/IPv6ProtocolHdr.h @@ -104,13 +104,13 @@ typedef enum _E_IPADDR_CONTEXT USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ PVOID pcIpHeader, /**bShutStatus = FALSE; } -S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG SrcIP) +struct bcm_classifier_rule *GetFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG SrcIP) { UINT uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 4bb3796c9c5a..42a04b95909d 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -33,9 +33,9 @@ INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid); USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb); -BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort); -BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort); -BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol); +BOOLEAN MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushSrcPort); +BOOLEAN MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushSrcPort); +BOOLEAN MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,UCHAR ucProtocol); INT SetupNextSend(PMINI_ADAPTER Adapter, /**ucEtherTypeLen==0)|| @@ -718,7 +718,7 @@ static BOOLEAN EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE *pstClassifierRule,struct } -static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) +static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) { BOOLEAN bClassificationSucceed = FALSE; USHORT usVLANID; @@ -770,7 +770,7 @@ static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct s static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb, PS_ETHCS_PKT_INFO pstEthCsPktInfo, - S_CLASSIFIER_RULE *pstClassifierRule, + struct bcm_classifier_rule *pstClassifierRule, B_UINT8 EthCSCupport) { BOOLEAN bClassificationSucceed = FALSE; diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c index 79585e4affff..5f891fa90a62 100644 --- a/drivers/staging/bcm/sort.c +++ b/drivers/staging/bcm/sort.c @@ -33,8 +33,8 @@ VOID SortPackInfo(PMINI_ADAPTER Adapter) static int compare_classifiers(void const *a, void const *b) { - S_CLASSIFIER_RULE const *pa = a; - S_CLASSIFIER_RULE const *pb = b; + struct bcm_classifier_rule const *pa = a; + struct bcm_classifier_rule const *pb = b; if (!pa->bUsed || !pb->bUsed) return 0; @@ -48,5 +48,5 @@ VOID SortClassifiers(PMINI_ADAPTER Adapter) DBG_LVL_ALL, "<======="); sort(Adapter->astClassifierTable, MAX_CLASSIFIERS, - sizeof(S_CLASSIFIER_RULE), compare_classifiers, NULL); + sizeof(struct bcm_classifier_rule), compare_classifiers, NULL); } -- GitLab From f428450a5d675682def5403e6842f6c61872c3dd Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:04 -0400 Subject: [PATCH 0435/6849] Staging: bcm: Remove typedef for _S_HDR_SUPRESSION_CONTEXTINFO and call directly. This patch removes typedef for _S_HDR_SUPRESSION_CONTEXTINFO, changes the name of the struct from _S_HDR_SUPRESSION_CONTEXTINFO to bcm_hdr_supression_contextinfo. In addition, any calls to the following typedefs "S_HDR_SUPRESSION_CONTEXTINFO" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index d2260fe8c2a1..9b5a0aa805af 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -100,10 +100,10 @@ typedef union _U_IP_ADDRESS { }; } U_IP_ADDRESS; -typedef struct _S_HDR_SUPRESSION_CONTEXTINFO { +struct bcm_hdr_supression_contextinfo { UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; /* Intermediate buffer to accumulate pkt Header for PHS */ UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; /* Intermediate buffer containing pkt Header after PHS */ -} S_HDR_SUPRESSION_CONTEXTINFO; +}; struct bcm_classifier_rule { ULONG ulSFID; @@ -380,7 +380,7 @@ struct _MINI_ADAPTER { BOOLEAN bLinkDownRequested; int downloadDDR; PHS_DEVICE_EXTENSION stBCMPhsContext; - S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo; + struct bcm_hdr_supression_contextinfo stPhsTxContextInfo; uint8_t ucaPHSPktRestoreBuf[2048]; uint8_t bPHSEnabled; BOOLEAN AutoFirmDld; -- GitLab From 0e000c2ee331a3389ab8875cb036e9cfcbcebea5 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:05 -0400 Subject: [PATCH 0436/6849] Staging: bcm: Remove typedef for _CLASSIFICATION_ONLY. This patch removes typedef for _CLASSIFICATION_ONLY, because it is not being used. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 9b5a0aa805af..13c0d0af0928 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -66,16 +66,6 @@ typedef struct _CLASSIFICATION_RULE { USHORT usVcid; } CLASSIFICATION_RULE, *PCLASSIFICATION_RULE; -typedef struct _CLASSIFICATION_ONLY { - USHORT usVcid; - ULONG DestIpAddress; - ULONG DestIpMask; - USHORT usPortLo; - USHORT usPortHi; - BOOLEAN bIpVersion; - UCHAR ucDestinationAddress[16]; -} CLASSIFICATION_ONLY, *PCLASSIFICATION_ONLY; - #define MAX_IP_RANGE_LENGTH 4 #define MAX_PORT_RANGE 4 #define MAX_PROTOCOL_LENGTH 32 -- GitLab From fa64354ff32a06dc8f392c2b3e0ddd57e2eb0357 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:06 -0400 Subject: [PATCH 0437/6849] Staging: bcm: Remove typedef for _CLASSIFICATION_RULE. This patch removes typedef for _CLASSIFICATION_RULE, because it is not being used. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 13c0d0af0928..e6269236c567 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -54,18 +54,6 @@ typedef struct _ADD_CONNECTION { UCHAR SrcProtocol; } ADD_CONNECTION, *PADD_CONNECTION; -typedef struct _CLASSIFICATION_RULE { - UCHAR ucIPSrcAddrLen; - UCHAR ucIPSrcAddr[32]; - UCHAR ucIPDestAddrLen; - UCHAR ucIPDestAddr[32]; - UCHAR ucSrcPortRangeLen; - UCHAR ucSrcPortRange[4]; - UCHAR ucDestPortRangeLen; - UCHAR ucDestPortRange[4]; - USHORT usVcid; -} CLASSIFICATION_RULE, *PCLASSIFICATION_RULE; - #define MAX_IP_RANGE_LENGTH 4 #define MAX_PORT_RANGE 4 #define MAX_PROTOCOL_LENGTH 32 -- GitLab From 845bd532cda92afc3329dff753aefbe4164a8f83 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:07 -0400 Subject: [PATCH 0438/6849] Staging: bcm: Remove typedef for _ADD_CONNECTION. This patch removes typedef for _ADD_CONNECTION, because it is not being used. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index e6269236c567..5256e3f2bcc3 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -34,26 +34,6 @@ struct link_request { } __packed; typedef struct link_request LINK_REQUEST, *PLINK_REQUEST; -/* classification extension is added */ -typedef struct _ADD_CONNECTION { - ULONG SrcIpAddressCount; - ULONG SrcIpAddress[MAX_CONNECTIONS]; - ULONG SrcIpMask[MAX_CONNECTIONS]; - - ULONG DestIpAddressCount; - ULONG DestIpAddress[MAX_CONNECTIONS]; - ULONG DestIpMask[MAX_CONNECTIONS]; - - USHORT SrcPortBegin; - USHORT SrcPortEnd; - - USHORT DestPortBegin; - USHORT DestPortEnd; - - UCHAR SrcTOS; - UCHAR SrcProtocol; -} ADD_CONNECTION, *PADD_CONNECTION; - #define MAX_IP_RANGE_LENGTH 4 #define MAX_PORT_RANGE 4 #define MAX_PROTOCOL_LENGTH 32 -- GitLab From 2610c7a889103587ce9a5714291a53dbf5490c3c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:08 -0400 Subject: [PATCH 0439/6849] Staging: bcm: Remove typedef for link_request and call directly. This patch removes typedef for link_request, changes the name of the struct from link_request to bcm_link_request. In addition, any calls to the following typedefs "LINK_REQUEST, *PLINK_REQUEST, *CONTROL_MESSAGE" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 5 +---- drivers/staging/bcm/Bcmchar.c | 2 +- drivers/staging/bcm/InterfaceTx.c | 2 +- drivers/staging/bcm/Misc.c | 18 +++++++++--------- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 5256e3f2bcc3..a36767d9c551 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -28,11 +28,10 @@ struct _CONTROL_PACKET { } __packed; typedef struct _CONTROL_PACKET CONTROL_PACKET, *PCONTROL_PACKET; -struct link_request { +struct bcm_link_request { LEADER Leader; UCHAR szData[4]; } __packed; -typedef struct link_request LINK_REQUEST, *PLINK_REQUEST; #define MAX_IP_RANGE_LENGTH 4 #define MAX_PORT_RANGE 4 @@ -417,8 +416,6 @@ struct bcm_firmware_info { /* holds the value of net_device structure.. */ extern struct net_device *gblpnetdev; -typedef LINK_REQUEST CONTROL_MESSAGE; - struct bcm_ddr_setting { UINT ulRegAddress; UINT ulRegValue; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 8d4052a7deae..d1dc0c3852ab 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -722,7 +722,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) return -EFAULT; - if (IoBuffer.InputLength < sizeof(struct link_request)) + if (IoBuffer.InputLength < sizeof(struct bcm_link_request)) return -EINVAL; if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE) diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index a842de9de6b5..3012f29cf85c 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -5,7 +5,7 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { PUSB_TCB pTcb= (PUSB_TCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; - CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer; + struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index b2d90d1e26af..954c3adf7944 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -237,7 +237,7 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) INT Status = 0; unsigned char *ctrl_buff = NULL; UINT pktlen = 0; - PLINK_REQUEST pLinkReq = NULL; + struct bcm_link_request *pLinkReq = NULL; PUCHAR pucAddIndication = NULL; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>"); @@ -246,7 +246,7 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) return -EINVAL; } - pLinkReq = (PLINK_REQUEST)ioBuffer; + pLinkReq = (struct bcm_link_request *)ioBuffer; pLeader = (PLEADER)ioBuffer; /* ioBuffer Contains sw_Status and Payload */ if (Adapter->bShutStatus == TRUE && @@ -414,7 +414,7 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) * * Returns - None. *****************************************************************/ -static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, PLINK_REQUEST pstStatisticsPtrRequest) +static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, struct bcm_link_request *pstStatisticsPtrRequest) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>"); pstStatisticsPtrRequest->Leader.Status = STATS_POINTER_REQ_STATUS; @@ -438,10 +438,10 @@ static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, PLINK_REQUEST ps *******************************************************************/ VOID LinkMessage(PMINI_ADAPTER Adapter) { - PLINK_REQUEST pstLinkRequest = NULL; + struct bcm_link_request *pstLinkRequest = NULL; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); if (Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) { - pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); + pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC); if (!pstLinkRequest) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); return; @@ -456,7 +456,7 @@ VOID LinkMessage(PMINI_ADAPTER Adapter) Adapter->bSyncUpRequestSent = TRUE; } else if (Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) { - pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); + pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC); if (!pstLinkRequest) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); return; @@ -584,7 +584,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter) { INT status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; struct timeval tv; - CONTROL_MESSAGE stIdleResponse = {{0} }; + struct bcm_link_request stIdleResponse = {{0} }; memset(&tv, 0, sizeof(tv)); stIdleResponse.Leader.Status = IDLE_MESSAGE; stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH; @@ -1392,11 +1392,11 @@ static VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter) static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) { - CONTROL_MESSAGE stShutdownResponse; + struct bcm_link_request stShutdownResponse; UINT NVMAccess = 0, lowPwrAbortMsg = 0; UINT Status = 0; - memset(&stShutdownResponse, 0, sizeof(CONTROL_MESSAGE)); + memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request)); stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ; stShutdownResponse.Leader.PLength = 8; /* 8 bytes; */ stShutdownResponse.szData[0] = LINK_UP_ACK; -- GitLab From c1975eda98d12c7b34cdc94c53cda32de263e4af Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:09 -0400 Subject: [PATCH 0440/6849] Staging: bcm: Remove typedef for _CONTROL_PACKET and call directly. This patch removes typedef for _CONTROL_PACKET, changes the name of the struct from _CONTROL_PACKET to bcm_control_packet. In addition, any calls to the following typedefs "CONTROL_PACKET, *PCONTROL_PACKET" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index a36767d9c551..ea83bc03b696 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -21,12 +21,11 @@ struct _PACKETTOSEND { } __packed; typedef struct _PACKETTOSEND PACKETTOSEND, *PPACKETTOSEND; -struct _CONTROL_PACKET { +struct bcm_control_packet { PVOID ControlBuff; UINT ControlBuffLen; - struct _CONTROL_PACKET *next; + struct bcm_control_packet *next; } __packed; -typedef struct _CONTROL_PACKET CONTROL_PACKET, *PCONTROL_PACKET; struct bcm_link_request { LEADER Leader; -- GitLab From a869993f8f763b9792990e7ef8e8a644b799d0d3 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:10 -0400 Subject: [PATCH 0441/6849] Staging: bcm: Remove typedef for _PACKETTOSEND and call directly. This patch removes typedef for _PACKETTOSEND, changes the name of the struct from _PACKETTOSEND to bcm_packettosend. In addition, any calls to the following typedefs "PACKETTOSEND, *PPACKETTOSEND" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 3 +-- drivers/staging/bcm/Macros.h | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index ea83bc03b696..fce61ed2ab06 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -15,11 +15,10 @@ struct _LEADER { } __packed; typedef struct _LEADER LEADER, *PLEADER; -struct _PACKETTOSEND { +struct bcm_packettosend { LEADER Leader; UCHAR ucPayload; } __packed; -typedef struct _PACKETTOSEND PACKETTOSEND, *PPACKETTOSEND; struct bcm_control_packet { PVOID ControlBuff; diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 8238cdba7a0f..7c03cce5eede 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -109,10 +109,10 @@ #define LEADER_STATUS 0x00 #define LEADER_STATUS_TCP_ACK 0x1 #define LEADER_SIZE sizeof(LEADER) -#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) -#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) +#define MAC_ADDR_REQ_SIZE sizeof(struct bcm_packettosend) +#define SS_INFO_REQ_SIZE sizeof(struct bcm_packettosend) #define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest)) -#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) +#define IDLE_REQ_SIZE sizeof(struct bcm_packettosend) #define MAX_TRANSFER_CTRL_BYTE_USB (2*1024) -- GitLab From ff352042ebb8f3823fb3725bc2356f6a60ce20df Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:11 -0400 Subject: [PATCH 0442/6849] Staging: bcm: Remove typedef for _LEADER and call directly. This patch removes typedef for _LEADER, changes the name of the struct from _LEADER to bcm_leader. In addition, any calls to the following typedefs "LEADER, *PLEADER" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 7 +++---- drivers/staging/bcm/CmHost.c | 4 ++-- drivers/staging/bcm/InterfaceRx.c | 6 +++--- drivers/staging/bcm/LeakyBucket.c | 4 ++-- drivers/staging/bcm/Macros.h | 2 +- drivers/staging/bcm/Misc.c | 6 +++--- drivers/staging/bcm/Transmit.c | 6 +++--- 7 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index fce61ed2ab06..f269daa2d52d 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -7,16 +7,15 @@ #define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256 #include "Debug.h" -struct _LEADER { +struct bcm_leader { USHORT Vcid; USHORT PLength; UCHAR Status; UCHAR Unused[3]; } __packed; -typedef struct _LEADER LEADER, *PLEADER; struct bcm_packettosend { - LEADER Leader; + struct bcm_leader Leader; UCHAR ucPayload; } __packed; @@ -27,7 +26,7 @@ struct bcm_control_packet { } __packed; struct bcm_link_request { - LEADER Leader; + struct bcm_leader Leader; UCHAR szData[4]; } __packed; diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index a0b1720aae3e..7189df69d81f 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1663,7 +1663,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /* "); - pLeader = (PLEADER)Adapter->caDsxReqResp; + pLeader = (struct bcm_leader *)Adapter->caDsxReqResp; pLeader->Status = CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ; pLeader->Vcid = 0; diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index d495828a731f..7940a2e7def2 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -46,7 +46,7 @@ static void read_bulk_callback(struct urb *urb) PUSB_RCB pRcb = (PUSB_RCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter; PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; - PLEADER pLeader = urb->transfer_buffer; + struct bcm_leader *pLeader = urb->transfer_buffer; if (unlikely(netif_msg_rx_status(Adapter))) pr_info(PFX "%s: rx urb status %d length %d\n", @@ -126,7 +126,7 @@ static void read_bulk_callback(struct urb *urb) BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt..."); *(PUSHORT)skb->data = pLeader->Status; memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + - (sizeof(LEADER)), pLeader->PLength); + (sizeof(struct bcm_leader)), pLeader->PLength); skb->len = pLeader->PLength + sizeof(USHORT); spin_lock(&Adapter->control_queue_lock); @@ -144,7 +144,7 @@ static void read_bulk_callback(struct urb *urb) */ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt..."); skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); - memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength); + memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(struct bcm_leader), pLeader->PLength); skb->dev = Adapter->dev; /* currently skb->len has extra ETH_HLEN bytes in the beginning */ diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index 89f1e577f7cd..a6584d7c28bd 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -243,10 +243,10 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, struct bcm_packet { spin_lock_bh(&psSF->SFQueueLock); psSF->NumOfPacketsSent++; - psSF->uiSentBytes+=((PLEADER)pControlPacket)->PLength; + psSF->uiSentBytes+=((struct bcm_leader *)pControlPacket)->PLength; psSF->uiSentPackets++; atomic_dec(&Adapter->TotalPacketCount); - psSF->uiCurrentBytesOnHost -= ((PLEADER)pControlPacket)->PLength; + psSF->uiCurrentBytesOnHost -= ((struct bcm_leader *)pControlPacket)->PLength; psSF->uiCurrentPacketsOnHost--; atomic_inc(&Adapter->index_rd_txcntrlpkt); spin_unlock_bh(&psSF->SFQueueLock); diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 7c03cce5eede..b5ca6f6a1cb2 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -108,7 +108,7 @@ /*Leader related terms */ #define LEADER_STATUS 0x00 #define LEADER_STATUS_TCP_ACK 0x1 -#define LEADER_SIZE sizeof(LEADER) +#define LEADER_SIZE sizeof(struct bcm_leader) #define MAC_ADDR_REQ_SIZE sizeof(struct bcm_packettosend) #define SS_INFO_REQ_SIZE sizeof(struct bcm_packettosend) #define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest)) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 954c3adf7944..2772e9259f42 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -233,7 +233,7 @@ exit_download: */ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) { - PLEADER pLeader = NULL; + struct bcm_leader *pLeader = NULL; INT Status = 0; unsigned char *ctrl_buff = NULL; UINT pktlen = 0; @@ -247,7 +247,7 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) } pLinkReq = (struct bcm_link_request *)ioBuffer; - pLeader = (PLEADER)ioBuffer; /* ioBuffer Contains sw_Status and Payload */ + pLeader = (struct bcm_leader *)ioBuffer; /* ioBuffer Contains sw_Status and Payload */ if (Adapter->bShutStatus == TRUE && pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD && @@ -373,7 +373,7 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) memset(ctrl_buff, 0, pktlen+LEADER_SIZE); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); - *(PLEADER)ctrl_buff = *pLeader; + *(struct bcm_leader *)ctrl_buff = *pLeader; memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index d5e4a7404f71..63c6a74bb1ff 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -43,7 +43,7 @@ This function dispatches control packet to the h/w interface */ INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket) { - PLEADER PLeader = (PLEADER)pControlPacket; + struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); if(!pControlPacket || !Adapter) @@ -90,7 +90,7 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid) BOOLEAN bHeaderSupressionEnabled = FALSE; B_UINT16 uiClassifierRuleID; u16 QueueIndex = skb_get_queue_mapping(Packet); - LEADER Leader={0}; + struct bcm_leader Leader={0}; if(Packet->len > MAX_DEVICE_DESC_SIZE) { @@ -143,7 +143,7 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid) else { Leader.PLength = Packet->len - ETH_HLEN; - memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); + memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); } status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, -- GitLab From 2979460d7aba1dac3452edcacd7b8c4cfcf06067 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 26 May 2012 12:05:12 -0400 Subject: [PATCH 0443/6849] Staging: bcm: Remove typedef for _MINI_ADAPTER and call directly. This patch removes typedef for _MINI_ADAPTER, changes the name of the struct from _MINI_ADAPTER to bcm_mini_adapter. In addition, any calls to the following typedefs "MINI_ADAPTER, *PMINI_ADAPTER" are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 13 +- drivers/staging/bcm/Bcmchar.c | 12 +- drivers/staging/bcm/Bcmnet.c | 18 +- drivers/staging/bcm/CmHost.c | 50 +++--- drivers/staging/bcm/CmHost.h | 10 +- drivers/staging/bcm/DDRInit.c | 4 +- drivers/staging/bcm/DDRInit.h | 4 +- drivers/staging/bcm/HandleControlPacket.c | 6 +- drivers/staging/bcm/IPv6Protocol.c | 16 +- drivers/staging/bcm/IPv6ProtocolHdr.h | 2 +- drivers/staging/bcm/InterfaceAdapter.h | 2 +- drivers/staging/bcm/InterfaceDld.c | 14 +- drivers/staging/bcm/InterfaceIdleMode.c | 12 +- drivers/staging/bcm/InterfaceIdleMode.h | 10 +- drivers/staging/bcm/InterfaceInit.c | 8 +- drivers/staging/bcm/InterfaceIsr.c | 2 +- drivers/staging/bcm/InterfaceIsr.h | 4 +- drivers/staging/bcm/InterfaceMisc.c | 2 +- drivers/staging/bcm/InterfaceMisc.h | 2 +- drivers/staging/bcm/InterfaceRx.c | 6 +- drivers/staging/bcm/InterfaceTx.c | 4 +- drivers/staging/bcm/LeakyBucket.c | 10 +- drivers/staging/bcm/Misc.c | 88 +++++----- drivers/staging/bcm/PHSModule.c | 38 ++-- drivers/staging/bcm/PHSModule.h | 6 +- drivers/staging/bcm/Prototypes.h | 160 ++++++++--------- drivers/staging/bcm/Qos.c | 42 ++--- drivers/staging/bcm/Transmit.c | 8 +- drivers/staging/bcm/hostmibs.c | 4 +- drivers/staging/bcm/led_control.c | 22 +-- drivers/staging/bcm/nvm.c | 204 +++++++++++----------- drivers/staging/bcm/sort.c | 4 +- drivers/staging/bcm/vendorspecificextn.c | 6 +- drivers/staging/bcm/vendorspecificextn.h | 6 +- 34 files changed, 399 insertions(+), 400 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index f269daa2d52d..11d2c5a84552 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -192,7 +192,7 @@ struct bcm_packet_info { struct bcm_tarang_data { struct bcm_tarang_data *next; - struct _MINI_ADAPTER *Adapter; + struct bcm_mini_adapter *Adapter; struct sk_buff *RxAppControlHead; struct sk_buff *RxAppControlTail; int AppCtrlQueueLen; @@ -208,15 +208,15 @@ struct bcm_targetdsx_buffer { BOOLEAN valid; }; -typedef int (*FP_FLASH_WRITE)(struct _MINI_ADAPTER *, UINT, PVOID); +typedef int (*FP_FLASH_WRITE)(struct bcm_mini_adapter *, UINT, PVOID); -typedef int (*FP_FLASH_WRITE_STATUS)(struct _MINI_ADAPTER *, UINT, PVOID); +typedef int (*FP_FLASH_WRITE_STATUS)(struct bcm_mini_adapter *, UINT, PVOID); /* * Driver adapter data structure */ -struct _MINI_ADAPTER { - struct _MINI_ADAPTER *next; +struct bcm_mini_adapter { + struct bcm_mini_adapter *next; struct net_device *dev; u32 msg_enable; CHAR *caDsxReqResp; @@ -394,7 +394,6 @@ struct _MINI_ADAPTER { UINT gpioBitMap; S_BCM_DEBUG_STATE stDebugState; }; -typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER; #define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) @@ -417,7 +416,7 @@ struct bcm_ddr_setting { UINT ulRegAddress; UINT ulRegValue; }; -int InitAdapter(PMINI_ADAPTER psAdapter); +int InitAdapter(struct bcm_mini_adapter *psAdapter); /* ===================================================================== * Beceem vendor request codes for EP0 diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index d1dc0c3852ab..cf411d1706b1 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -15,7 +15,7 @@ static int bcm_char_open(struct inode *inode, struct file * filp) { - PMINI_ADAPTER Adapter = NULL; + struct bcm_mini_adapter *Adapter = NULL; struct bcm_tarang_data *pTarang = NULL; Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -44,7 +44,7 @@ static int bcm_char_open(struct inode *inode, struct file * filp) static int bcm_char_release(struct inode *inode, struct file *filp) { struct bcm_tarang_data *pTarang, *tmp, *ptmp; - PMINI_ADAPTER Adapter = NULL; + struct bcm_mini_adapter *Adapter = NULL; struct sk_buff *pkt, *npkt; pTarang = (struct bcm_tarang_data *)filp->private_data; @@ -98,7 +98,7 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) { struct bcm_tarang_data *pTarang = filp->private_data; - PMINI_ADAPTER Adapter = pTarang->Adapter; + struct bcm_mini_adapter *Adapter = pTarang->Adapter; struct sk_buff *Packet = NULL; ssize_t PktLen = 0; int wait_ret_val = 0; @@ -157,7 +157,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { struct bcm_tarang_data *pTarang = filp->private_data; void __user *argp = (void __user *)arg; - PMINI_ADAPTER Adapter = pTarang->Adapter; + struct bcm_mini_adapter *Adapter = pTarang->Adapter; INT Status = STATUS_FAILURE; int timeout = 0; IOCTL_BUFFER IoBuffer; @@ -2014,7 +2014,7 @@ static const struct file_operations bcm_fops = { .llseek = no_llseek, }; -int register_control_device_interface(PMINI_ADAPTER Adapter) +int register_control_device_interface(struct bcm_mini_adapter *Adapter) { if (Adapter->major > 0) @@ -2039,7 +2039,7 @@ int register_control_device_interface(PMINI_ADAPTER Adapter) return 0; } -void unregister_control_device_interface(PMINI_ADAPTER Adapter) +void unregister_control_device_interface(struct bcm_mini_adapter *Adapter) { if (Adapter->major > 0) { device_destroy(bcm_class, MKDEV(Adapter->major, 0)); diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 133e146a3dd4..6e8c7f523214 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -4,7 +4,7 @@ struct net_device *gblpnetdev; static INT bcm_open(struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); if (Adapter->fw_download_done == FALSE) { pr_notice(PFX "%s: link up failed (download in progress)\n", @@ -28,7 +28,7 @@ static INT bcm_open(struct net_device *dev) static INT bcm_close(struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); if (netif_msg_ifdown(Adapter)) pr_info(PFX "%s: disabling interface\n", dev->name); @@ -59,7 +59,7 @@ static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb) static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); u16 qindex = skb_get_queue_mapping(skb); @@ -141,7 +141,7 @@ static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter; struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface); @@ -156,21 +156,21 @@ static void bcm_get_drvinfo(struct net_device *dev, static u32 bcm_get_link(struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); return Adapter->LinkUpStatus; } static u32 bcm_get_msglevel(struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); return Adapter->msg_enable; } static void bcm_set_msglevel(struct net_device *dev, u32 level) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); Adapter->msg_enable = level; } @@ -183,7 +183,7 @@ static const struct ethtool_ops bcm_ethtool_ops = { .set_msglevel = bcm_set_msglevel, }; -int register_networkdev(PMINI_ADAPTER Adapter) +int register_networkdev(struct bcm_mini_adapter *Adapter) { struct net_device *net = Adapter->dev; PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter; @@ -224,7 +224,7 @@ int register_networkdev(PMINI_ADAPTER Adapter) return 0; } -void unregister_networkdev(PMINI_ADAPTER Adapter) +void unregister_networkdev(struct bcm_mini_adapter *Adapter) { struct net_device *net = Adapter->dev; PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter; diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 7189df69d81f..189d243878c9 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -14,7 +14,7 @@ enum E_CLASSIFIER_ACTION { eDeleteClassifier }; -static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid); +static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UINT16 tid); /************************************************************ * Function - SearchSfid @@ -28,7 +28,7 @@ static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid); * Returns - Queue index for this SFID(If matched) * Else Invalid Queue Index(If Not matched) ************************************************************/ -int SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) +int SearchSfid(struct bcm_mini_adapter *Adapter, UINT uiSfid) { int i; @@ -49,7 +49,7 @@ int SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) * Returns - Queue index for the free SFID * Else returns Invalid Index. ****************************************************************/ -static int SearchFreeSfid(PMINI_ADAPTER Adapter) +static int SearchFreeSfid(struct bcm_mini_adapter *Adapter) { int i; @@ -63,12 +63,12 @@ static int SearchFreeSfid(PMINI_ADAPTER Adapter) /* * Function: SearchClsid * Description: This routinue would search Classifier having specified ClassifierID as input parameter - * Input parameters: PMINI_ADAPTER Adapter - Adapter Context + * Input parameters: struct bcm_mini_adapter *Adapter - Adapter Context * unsigned int uiSfid - The SF in which the classifier is to searched * B_UINT16 uiClassifierID - The classifier ID to be searched * Return: int :Classifier table index of matching entry */ -static int SearchClsid(PMINI_ADAPTER Adapter, ULONG ulSFID, B_UINT16 uiClassifierID) +static int SearchClsid(struct bcm_mini_adapter *Adapter, ULONG ulSFID, B_UINT16 uiClassifierID) { int i; @@ -87,7 +87,7 @@ static int SearchClsid(PMINI_ADAPTER Adapter, ULONG ulSFID, B_UINT16 uiClassifi * This routinue would search Free available Classifier entry in classifier table. * @return free Classifier Entry index in classifier table for specified SF */ -static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/) +static int SearchFreeClsid(struct bcm_mini_adapter *Adapter /**Adapter Context*/) { int i; @@ -99,7 +99,7 @@ static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/) return MAX_CLASSIFIERS+1; } -static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) +static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex) { /* deleting all the packet held in the SF */ flush_queue(Adapter, uiSearchRuleIndex); @@ -120,7 +120,7 @@ CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry, UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; UCHAR *ptrClassifierIpAddress = NULL; UCHAR *ptrClassifierIpMask = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if (bIpVersion6) nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES; @@ -214,7 +214,7 @@ CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry, } } -void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter, B_UINT16 TID, BOOLEAN bFreeAll) +void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, BOOLEAN bFreeAll) { int i; @@ -236,7 +236,7 @@ void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter, B_UINT16 TID, BOOLEAN bFreeAll) * @ingroup ctrl_pkt_functions * copy classifier rule into the specified SF index */ -static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSLTypes *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex) +static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, stConvergenceSLTypes *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex) { struct bcm_classifier_rule *pstClassifierEntry = NULL; /* VOID *pvPhsContext = NULL; */ @@ -365,7 +365,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL /* * @ingroup ctrl_pkt_functions */ -static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex, UINT nClassifierIndex) +static inline VOID DeleteClassifierRuleFromSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex, UINT nClassifierIndex) { struct bcm_classifier_rule *pstClassifierEntry = NULL; B_UINT16 u16PacketClassificationRuleIndex; @@ -396,7 +396,7 @@ static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSear /* * @ingroup ctrl_pkt_functions */ -VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) +VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex) { struct bcm_classifier_rule *pstClassifierEntry = NULL; int i; @@ -428,7 +428,7 @@ VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) * related data into the Adapter structure. * @ingroup ctrl_pkt_functions */ -static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* "); @@ -1325,7 +1325,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " bValid: 0x%X", pstAddIndication->sfActiveSet.bValid); } -static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer) +static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter, ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer) { UINT nBytesToRead = sizeof(stServiceFlowParamSI); @@ -1342,7 +1342,7 @@ static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet return 1; } -static ULONG StoreSFParam(PMINI_ADAPTER Adapter, PUCHAR pucSrcBuffer, ULONG ulAddrSFParamSet) +static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, ULONG ulAddrSFParamSet) { UINT nBytesToWrite = sizeof(stServiceFlowParamSI); int ret = 0; @@ -1358,7 +1358,7 @@ static ULONG StoreSFParam(PMINI_ADAPTER Adapter, PUCHAR pucSrcBuffer, ULONG ulAd return 1; } -ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter, PVOID pvBuffer, UINT *puBufferLength) +ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength) { stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL; stLocalSFAddIndication *pstAddIndication = NULL; @@ -1473,7 +1473,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter, PVOID pvBuffer, UINT } static inline stLocalSFAddIndicationAlt -*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter, register PVOID pvBuffer) +*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer) { ULONG ulStatus = 0; stLocalSFAddIndication *pstAddIndication = NULL; @@ -1551,7 +1551,7 @@ failed_restore_sf_param: return NULL; } -ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter) +ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) { ULONG ulTargetDsxBuffersBase = 0; ULONG ulCntTargetBuffers; @@ -1598,7 +1598,7 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter) return 1; } -static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid) +static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UINT16 tid) { ULONG ulTargetDSXBufferAddress; ULONG ulTargetDsxBufferIndexToUse, ulMaxTry; @@ -1632,7 +1632,7 @@ static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid) return ulTargetDSXBufferAddress; } -int AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) +int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) { /* * Need to Allocate memory to contain the SUPER Large structures @@ -1645,7 +1645,7 @@ int AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) return 0; } -int FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) +int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) { kfree(Adapter->caDsxReqResp); return 0; @@ -1657,7 +1657,7 @@ int FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) * for the Connection Management. * @return - Queue index for the free SFID else returns Invalid Index. */ -BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /* pTarangs; pTarang; pTarang = pTarang->next) { diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 4adbf9dbf7b5..4745ddd62f5b 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -12,7 +12,7 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; USHORT usNextHeaderOffset = 0 ; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if ((ppucPayload == NULL) || (*pusPayloadLength == 0) || (*bParseDone)) { @@ -147,7 +147,7 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, BOOLEAN bDone = FALSE; UCHAR ucHeaderType = 0; UCHAR *pucNextHeader = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if (!pucPayload || (usPayloadLength == 0)) return 0; @@ -177,10 +177,10 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, /* - * Arg 1 PMINI_ADAPTER Adapter is a pointer ot the driver contorl structure + * Arg 1 struct bcm_mini_adapter *Adapter is a pointer ot the driver contorl structure * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet */ -USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, +USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader, struct bcm_classifier_rule *pstClassifierRule) { USHORT ushDestPort = 0; @@ -295,7 +295,7 @@ static BOOLEAN MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule UINT uiIpv6AddIndex = 0; UINT uiIpv6AddrNoLongWords = 4; ULONG aulSrcIP[4]; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); /* * This is the no. of Src Addresses ie Range of IP Addresses contained * in the classifier rule for which we need to match @@ -351,7 +351,7 @@ static BOOLEAN MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRul UINT uiIpv6AddIndex = 0; UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); /* * This is the no. of Destination Addresses * ie Range of IP Addresses contained in the classifier rule @@ -406,7 +406,7 @@ VOID DumpIpv6Address(ULONG *puIpv6Address) { UINT uiIpv6AddrNoLongWords = 4; UINT uiIpv6AddIndex = 0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx", puIpv6Address[uiIpv6AddIndex]); @@ -418,7 +418,7 @@ static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) { UCHAR ucVersion; UCHAR ucPrio; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h index 369b55316c79..8ba88a5b081c 100644 --- a/drivers/staging/bcm/IPv6ProtocolHdr.h +++ b/drivers/staging/bcm/IPv6ProtocolHdr.h @@ -102,7 +102,7 @@ typedef enum _E_IPADDR_CONTEXT //Function Prototypes -USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ +USHORT IpVersion6(struct bcm_mini_adapter *Adapter, /**< Pointer to the driver control structure */ PVOID pcIpHeader, /**psAdapter; */ + /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */ char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); if (!buff) @@ -132,7 +132,7 @@ exit: return Status; } -static int bcm_download_config_file(PMINI_ADAPTER Adapter, struct bcm_firmware_info *psFwInfo) +static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; B_UINT32 value = 0; @@ -208,7 +208,7 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter, struct bcm_firmware_i static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff, unsigned int len) { int retval = STATUS_SUCCESS; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if ((len-sizeof(unsigned int)) < 4) { if (memcmp(readbackbuff , buff, len)) retval = -EINVAL; @@ -229,7 +229,7 @@ static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char return retval; } -int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, struct bcm_firmware_info *psFwInfo) +int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; PUCHAR buff = NULL; @@ -278,7 +278,7 @@ error: return retval; } -static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) +static INT buffDnld(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) { unsigned int len = 0; int retval = STATUS_SUCCESS; @@ -299,7 +299,7 @@ static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32Firmware return retval; } -static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) +static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) { UINT len = u32FirmwareLength; INT retval = STATUS_SUCCESS; @@ -334,7 +334,7 @@ static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32Fi return retval; } -INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress) +INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress) { INT status = STATUS_SUCCESS; diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c index faeb03e62c06..4f2f490921e1 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ b/drivers/staging/bcm/InterfaceIdleMode.c @@ -7,7 +7,7 @@ Description: This is the hardware specific Function for waking up HW device fr A software abort pattern is written to the device to wake it and necessary power state transitions from host are performed here. -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context +Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful. @@ -22,7 +22,7 @@ Description: This is the hardware specific Function for responding to Idle mod Necessary power state transitions from host for idle mode or other device specific initializations are performed here. -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context +Input parameters: IN struct bcm_mini_adapter * Adapter - Miniport Adapter Context Return: BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful. @@ -42,7 +42,7 @@ send to f/w with in 200 ms after the Idle/Shutdown req issued */ -int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer) +int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int* puiBuffer) { int status = STATUS_SUCCESS; unsigned int uiRegRead = 0; @@ -147,7 +147,7 @@ int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer) return status; } -static int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern) +static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, unsigned int Pattern) { int status = STATUS_SUCCESS; unsigned int value; @@ -246,7 +246,7 @@ static int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern) } return status; } -int InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter) +int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter) { ULONG Status = 0; if(Adapter->bTriedToWakeUpFromlowPowerMode) @@ -263,7 +263,7 @@ int InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter) return Status; } -void InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter) +void InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter) { unsigned int uiRegVal = 0; INT Status = 0; diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h index 859a2ffba6b7..c3338c8a1dc8 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.h +++ b/drivers/staging/bcm/InterfaceIdleMode.h @@ -1,14 +1,14 @@ #ifndef _INTERFACE_IDLEMODE_H #define _INTERFACE_IDLEMODE_H -INT InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter); +INT InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter); -INT InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int *puiBuffer); +INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer); -VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter); +VOID InterfaceWriteIdleModeWakePattern(struct bcm_mini_adapter *Adapter); -INT InterfaceWakeUp(PMINI_ADAPTER Adapter); +INT InterfaceWakeUp(struct bcm_mini_adapter * Adapter); -VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter); +VOID InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter); #endif diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 8e3c586a699c..8f85de6a57ba 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -65,7 +65,7 @@ static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) AdapterFree(psIntfAdapter->psAdapter); } -static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) +static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter) { unsigned long ulReg = 0; int bytes; @@ -143,12 +143,12 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi { struct usb_device *udev = interface_to_usbdev(intf); int retval; - PMINI_ADAPTER psAdapter; + struct bcm_mini_adapter *psAdapter; PS_INTERFACE_ADAPTER psIntfAdapter; struct net_device *ndev; /* Reserve one extra queue for the bit-bucket */ - ndev = alloc_etherdev_mq(sizeof(MINI_ADAPTER), NO_OF_QUEUES+1); + ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter), NO_OF_QUEUES+1); if (ndev == NULL) { dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); return -ENOMEM; @@ -257,7 +257,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi static void usbbcm_disconnect(struct usb_interface *intf) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); - PMINI_ADAPTER psAdapter; + struct bcm_mini_adapter *psAdapter; struct usb_device *udev = interface_to_usbdev(intf); if (psIntfAdapter == NULL) diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index 67719d57256d..6ee3428daa55 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -5,7 +5,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) { int status = urb->status; PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context; - PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ; + struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter ; if (netif_msg_intr(Adapter)) pr_info(PFX "%s: interrupt status %d\n", diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h index 6065a7141bca..40399788c419 100644 --- a/drivers/staging/bcm/InterfaceIsr.h +++ b/drivers/staging/bcm/InterfaceIsr.h @@ -7,9 +7,9 @@ int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter); INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter); -VOID InterfaceEnableInterrupt(PMINI_ADAPTER Adapter); +VOID InterfaceEnableInterrupt(struct bcm_mini_adapter *Adapter); -VOID InterfaceDisableInterrupt(PMINI_ADAPTER Adapter); +VOID InterfaceDisableInterrupt(struct bcm_mini_adapter *Adapter); #endif diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 2218faeaf8ac..bbe909946091 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -133,7 +133,7 @@ INT BcmWRM(PVOID arg, return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); } -INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter) +INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) { PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter); INT status = STATUS_SUCCESS; diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h index 6c9e39bf9889..1dfabdc3aadd 100644 --- a/drivers/staging/bcm/InterfaceMisc.h +++ b/drivers/staging/bcm/InterfaceMisc.h @@ -33,7 +33,7 @@ int BcmWRM(PVOID arg, PVOID buff, INT len); -INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter); +INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter); VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter); diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 7940a2e7def2..8a9f90fbdf13 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -1,6 +1,6 @@ #include "headers.h" -static int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) +static int SearchVcid(struct bcm_mini_adapter *Adapter,unsigned short usVcid) { int iIndex=0; @@ -45,7 +45,7 @@ static void read_bulk_callback(struct urb *urb) //int idleflag = 0 ; PUSB_RCB pRcb = (PUSB_RCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter; - PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; + struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; struct bcm_leader *pLeader = urb->transfer_buffer; if (unlikely(netif_msg_rx_status(Adapter))) @@ -232,7 +232,7 @@ Function: InterfaceRx Description: This is the hardware specific Function for Receiving data packet/control packets from the device. -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context +Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index 3012f29cf85c..7e2b53be4d9e 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -6,9 +6,9 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) PUSB_TCB pTcb= (PUSB_TCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; - PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; + struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if (unlikely(netif_msg_tx_done(Adapter))) pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index a6584d7c28bd..6e8a3279698b 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -15,7 +15,7 @@ * Returns - None **********************************************************************/ -static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter) +static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter) { ULONG liCurrentTime; INT i = 0; @@ -75,7 +75,7 @@ static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter) * Returns - The number of bytes allowed for transmission. * ***********************************************************************/ -static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, struct bcm_packet_info *psSF) +static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>"); /* Validate the parameters */ @@ -112,7 +112,7 @@ static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, struct bcm_packet_info *psSF This function despatches packet from the specified queue. @return Zero(success) or Negative value(failure) */ -static INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**dev); } -static int create_worker_threads(PMINI_ADAPTER psAdapter) +static int create_worker_threads(struct bcm_mini_adapter *psAdapter) { /* Rx Control Packets Processing */ psAdapter->control_packet_handler = kthread_run((int (*)(void *)) @@ -155,7 +155,7 @@ static int create_worker_threads(PMINI_ADAPTER psAdapter) return 0; } -static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path) +static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path) { struct file *flp = NULL; mm_segment_t oldfs; @@ -179,7 +179,7 @@ static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path) * Path to image file * Download Address on the chip */ -static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path, unsigned int loc) +static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc) { int errorno = 0; struct file *flp = NULL; @@ -231,7 +231,7 @@ exit_download: * Logical Adapter * Control Packet Buffer */ -INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) +INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer) { struct bcm_leader *pLeader = NULL; INT Status = 0; @@ -414,7 +414,7 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) * * Returns - None. *****************************************************************/ -static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, struct bcm_link_request *pstStatisticsPtrRequest) +static VOID SendStatisticsPointerRequest(struct bcm_mini_adapter *Adapter, struct bcm_link_request *pstStatisticsPtrRequest) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>"); pstStatisticsPtrRequest->Leader.Status = STATS_POINTER_REQ_STATUS; @@ -436,7 +436,7 @@ static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, struct bcm_link_ * * Returns - None. *******************************************************************/ -VOID LinkMessage(PMINI_ADAPTER Adapter) +VOID LinkMessage(struct bcm_mini_adapter *Adapter) { struct bcm_link_request *pstLinkRequest = NULL; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); @@ -487,7 +487,7 @@ VOID LinkMessage(PMINI_ADAPTER Adapter) * * Returns - None. ************************************************************************/ -VOID StatisticsResponse(PMINI_ADAPTER Adapter, PVOID pvBuffer) +VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); @@ -506,7 +506,7 @@ VOID StatisticsResponse(PMINI_ADAPTER Adapter, PVOID pvBuffer) * * Returns - None. ***********************************************************************/ -VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer) +VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); @@ -580,7 +580,7 @@ VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer) return; } -void SendIdleModeResponse(PMINI_ADAPTER Adapter) +void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) { INT status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; struct timeval tv; @@ -679,7 +679,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter) * * Returns - None. *******************************************************************/ -VOID DumpPackInfo(PMINI_ADAPTER Adapter) +VOID DumpPackInfo(struct bcm_mini_adapter *Adapter) { UINT uiLoopIndex = 0; UINT uiIndex = 0; @@ -808,10 +808,10 @@ VOID DumpPackInfo(PMINI_ADAPTER Adapter) return; } -int reset_card_proc(PMINI_ADAPTER ps_adapter) +int reset_card_proc(struct bcm_mini_adapter *ps_adapter) { int retval = STATUS_SUCCESS; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PS_INTERFACE_ADAPTER psIntfAdapter = NULL; unsigned int value = 0, uiResetValue = 0; int bytes; @@ -926,7 +926,7 @@ err_exit: return retval; } -int run_card_proc(PMINI_ADAPTER ps_adapter) +int run_card_proc(struct bcm_mini_adapter *ps_adapter) { int status = STATUS_SUCCESS; int bytes; @@ -953,7 +953,7 @@ int run_card_proc(PMINI_ADAPTER ps_adapter) return status; } -int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) +int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter) { int status; UINT value = 0; @@ -1077,7 +1077,7 @@ OUT: return status; } -static int bcm_parse_target_params(PMINI_ADAPTER Adapter) +static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter) { struct file *flp = NULL; mm_segment_t oldfs = {0}; @@ -1128,7 +1128,7 @@ static int bcm_parse_target_params(PMINI_ADAPTER Adapter) return STATUS_SUCCESS; } -void beceem_parse_target_struct(PMINI_ADAPTER Adapter) +void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter) { UINT uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0; @@ -1186,7 +1186,7 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter) doPowerAutoCorrection(Adapter); } -static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) +static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) { UINT reporting_mode; @@ -1218,7 +1218,7 @@ static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) } #if 0 -static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress) +static unsigned char *ReadMacAddrEEPROM(struct bcm_mini_adapter *Adapter, ulong dwAddress) { int status = 0, i = 0; unsigned int temp = 0; @@ -1272,13 +1272,13 @@ static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount) #define CACHE_ADDRESS_MASK 0x80000000 #define UNCACHE_ADDRESS_MASK 0xa0000000 -int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { return Adapter->interface_rdm(Adapter->pvInterfaceAdapter, uiAddress, pucBuff, sSize); } -int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { int iRetVal; @@ -1287,13 +1287,13 @@ int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) return iRetVal; } -int wrmalt(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) { convertEndian(RWM_WRITE, pucBuff, size); return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size); } -int rdmalt(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) { INT uiRetVal = 0; @@ -1303,7 +1303,7 @@ int rdmalt(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) return uiRetVal; } -int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { INT status = STATUS_SUCCESS; down(&Adapter->rdmwrmsync); @@ -1322,7 +1322,7 @@ exit: return status; } -int wrmaltWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) { int iRetVal = STATUS_SUCCESS; @@ -1342,7 +1342,7 @@ exit: return iRetVal; } -int rdmaltWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) { INT uiRetVal = STATUS_SUCCESS; @@ -1361,7 +1361,7 @@ exit: return uiRetVal; } -static VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter) +static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) { int clear_abort_pattern = 0, Status = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); @@ -1390,7 +1390,7 @@ static VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); } -static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) +static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter) { struct bcm_link_request stShutdownResponse; UINT NVMAccess = 0, lowPwrAbortMsg = 0; @@ -1474,7 +1474,7 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) } } -static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter, PUCHAR pucBuffer) +static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) { B_UINT32 uiResetValue = 0; @@ -1503,7 +1503,7 @@ static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter, PUCHAR pucBuffer) return; } -VOID ResetCounters(PMINI_ADAPTER Adapter) +VOID ResetCounters(struct bcm_mini_adapter *Adapter) { beceem_protocol_reset(Adapter); Adapter->CurrNumRecvDescs = 0; @@ -1519,7 +1519,7 @@ VOID ResetCounters(PMINI_ADAPTER Adapter) Adapter->bShutStatus = FALSE; } -struct bcm_classifier_rule *GetFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG SrcIP) +struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP) { UINT uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { @@ -1533,7 +1533,7 @@ struct bcm_classifier_rule *GetFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIp return NULL; } -void AddFragIPClsEntry(PMINI_ADAPTER Adapter, struct bcm_fragmented_packet_info *psFragPktInfo) +void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo) { UINT uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { @@ -1544,7 +1544,7 @@ void AddFragIPClsEntry(PMINI_ADAPTER Adapter, struct bcm_fragmented_packet_info } } -void DelFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG SrcIp) +void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp) { UINT uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { @@ -1556,7 +1556,7 @@ void DelFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG S } } -void update_per_cid_rx(PMINI_ADAPTER Adapter) +void update_per_cid_rx(struct bcm_mini_adapter *Adapter) { UINT qindex = 0; @@ -1580,7 +1580,7 @@ void update_per_cid_rx(PMINI_ADAPTER Adapter) Adapter->liDrainCalculated = jiffies; } -void update_per_sf_desc_cnts(PMINI_ADAPTER Adapter) +void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) { INT iIndex = 0; u32 uibuff[MAX_TARGET_DSX_BUFFERS]; @@ -1606,7 +1606,7 @@ void update_per_sf_desc_cnts(PMINI_ADAPTER Adapter) atomic_set(&Adapter->uiMBupdate, FALSE); } -void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) +void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex) { struct sk_buff *PacketToDrop = NULL; struct net_device_stats *netstats = &Adapter->dev->stats; @@ -1630,7 +1630,7 @@ void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); } -static void beceem_protocol_reset(PMINI_ADAPTER Adapter) +static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter) { int i; if (netif_msg_link(Adapter)) diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 4aa2b71a40eb..a6e61510d278 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -58,7 +58,7 @@ Description: This routine handle PHS(Payload Header Suppression for Tx path. The header data after supression is copied back to the NDIS_PACKET. -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context +Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context IN Packet - NDIS packet containing data to be transmitted IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to identify PHS rule to be applied. @@ -69,7 +69,7 @@ Return: STATUS_SUCCESS - If the send was successful. Other - If an error occured. */ -int PHSTransmit(PMINI_ADAPTER Adapter, +int PHSTransmit(struct bcm_mini_adapter *Adapter, struct sk_buff **pPacket, USHORT Vcid, B_UINT16 uiClassifierRuleID, @@ -209,7 +209,7 @@ int PHSTransmit(PMINI_ADAPTER Adapter, return STATUS_SUCCESS; } -int PHSReceive(PMINI_ADAPTER Adapter, +int PHSReceive(struct bcm_mini_adapter *Adapter, USHORT usVcid, struct sk_buff *packet, UINT *punPacketLen, @@ -273,7 +273,7 @@ int PHSReceive(PMINI_ADAPTER Adapter, void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet"); BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen); } @@ -291,7 +291,7 @@ void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) // TRUE(1) -If allocation of memory was success full. // FALSE -If allocation of memory fails. //----------------------------------------------------------------------------- -int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) +int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension, struct bcm_mini_adapter *Adapter) { int i; S_SERVICEFLOW_TABLE *pstServiceFlowTable; @@ -398,7 +398,7 @@ ULONG PhsUpdateClassifierRule(IN void* pvContext, ULONG lStatus =0; UINT nSFIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -462,7 +462,7 @@ ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; @@ -528,7 +528,7 @@ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; if(pDeviceExtension) @@ -592,7 +592,7 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid) UINT nSFIndex =0, nClsidIndex =0 ; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n"); @@ -684,7 +684,7 @@ ULONG PhsCompress(IN void* pvContext, S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL; S_PHS_RULE *pstPhsRule = NULL; ULONG lStatus =0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -778,7 +778,7 @@ ULONG PhsDeCompress(IN void* pvContext, S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_PHS_RULE *pstPhsRule = NULL; UINT phsi; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext; @@ -847,7 +847,7 @@ ULONG PhsDeCompress(IN void* pvContext, static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) { int i,j; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); if(psServiceFlowRulesTable) @@ -1057,7 +1057,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, UINT uiStatus =PHS_SUCCESS; UINT nClassifierIndex = 0; S_CLASSIFIER_TABLE *psaClassifiertable = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>"); @@ -1148,7 +1148,7 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, BOOLEAN bFreeEntryFound = FALSE; S_CLASSIFIER_ENTRY *psClassifierRules = NULL; UINT nStatus = PHS_SUCCESS; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule"); if(psaClassifiertable == NULL) { @@ -1259,7 +1259,7 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, S_PHS_RULE *pstAddPhsRule = NULL; UINT nPhsRuleIndex = 0; BOOLEAN bPHSRuleOrphaned = FALSE; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); psPhsRule->u8RefCnt =0; /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ @@ -1334,7 +1334,7 @@ static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifi void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension) { int i,j,k,l; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n"); for(i=0;i\n"); *header_size = 0; @@ -1495,7 +1495,7 @@ static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf { unsigned char *old_addr = out_buf; int supress = 0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(phs_rule == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!"); @@ -1557,7 +1557,7 @@ static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buff { unsigned int size=0; int bit,i=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm); diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h index c629585d0a8c..b5f21157ac47 100644 --- a/drivers/staging/bcm/PHSModule.h +++ b/drivers/staging/bcm/PHSModule.h @@ -1,7 +1,7 @@ #ifndef BCM_MINIPORT_PHSMODULE_H #define BCM_MINIPORT_PHSMODULE_H -int PHSTransmit(PMINI_ADAPTER Adapter, +int PHSTransmit(struct bcm_mini_adapter *Adapter, struct sk_buff **pPacket, USHORT Vcid, B_UINT16 uiClassifierRuleID, @@ -9,7 +9,7 @@ int PHSTransmit(PMINI_ADAPTER Adapter, PUINT PacketLen, UCHAR bEthCSSupport); -int PHSReceive(PMINI_ADAPTER Adapter, +int PHSReceive(struct bcm_mini_adapter *Adapter, USHORT usVcid, struct sk_buff *packet, UINT *punPacketLen, @@ -25,7 +25,7 @@ void DumpFullPacket(UCHAR *pBuf,UINT nPktLen); void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension); -int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter); +int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,struct bcm_mini_adapter *Adapter); int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt); diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 42a04b95909d..3c8cc5ba2e2e 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -1,172 +1,172 @@ #ifndef _PROTOTYPES_H_ #define _PROTOTYPES_H_ -VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer); +VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer); -VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer); +VOID StatisticsResponse(struct bcm_mini_adapter *Adapter,PVOID pvBuffer); -VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer); +VOID IdleModeResponse(struct bcm_mini_adapter *Adapter,PUINT puiBuffer); -int control_packet_handler (PMINI_ADAPTER Adapter); +int control_packet_handler (struct bcm_mini_adapter *Adapter); -VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex); +VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter,UINT uiSearchRuleIndex); -VOID flush_all_queues(PMINI_ADAPTER Adapter); +VOID flush_all_queues(struct bcm_mini_adapter *Adapter); -int register_control_device_interface(PMINI_ADAPTER ps_adapter); +int register_control_device_interface(struct bcm_mini_adapter *ps_adapter); -void unregister_control_device_interface(PMINI_ADAPTER Adapter); +void unregister_control_device_interface(struct bcm_mini_adapter *Adapter); -INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**ucIPSourceAddressLength) @@ -61,7 +61,7 @@ BOOLEAN MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule,ULONG ul BOOLEAN MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule,ULONG ulDestIP) { UCHAR ucLoopIndex=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); ulDestIP=ntohl(ulDestIP); if(0 == pstClassifierRule->ucIPDestinationAddressLength) @@ -94,7 +94,7 @@ BOOLEAN MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule,ULONG u BOOLEAN MatchTos(struct bcm_classifier_rule *pstClassifierRule,UCHAR ucTypeOfService) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if( 3 != pstClassifierRule->ucIPTypeOfServiceLength ) return TRUE; @@ -120,7 +120,7 @@ BOOLEAN MatchTos(struct bcm_classifier_rule *pstClassifierRule,UCHAR ucTypeOfSer BOOLEAN MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,UCHAR ucProtocol) { UCHAR ucLoopIndex=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(0 == pstClassifierRule->ucProtocolLength) return TRUE; for(ucLoopIndex=0;ucLoopIndexucProtocolLength;ucLoopIndex++) @@ -150,7 +150,7 @@ BOOLEAN MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushSrc { UCHAR ucLoopIndex=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(0 == pstClassifierRule->ucSrcPortRangeLength) @@ -181,7 +181,7 @@ BOOLEAN MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushSrc BOOLEAN MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushDestPort) { UCHAR ucLoopIndex=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(0 == pstClassifierRule->ucDestPortRangeLength) return TRUE; @@ -204,7 +204,7 @@ BOOLEAN MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushDe Compares IPV4 Ip address and port number @return Queue Index. */ -static USHORT IpVersion4(PMINI_ADAPTER Adapter, +static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd, struct bcm_classifier_rule *pstClassifierRule) { @@ -302,7 +302,7 @@ static USHORT IpVersion4(PMINI_ADAPTER Adapter, return bClassificationSucceed; } -VOID PruneQueueAllSF(PMINI_ADAPTER Adapter) +VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter) { UINT iIndex = 0; @@ -323,7 +323,7 @@ is less than number of bytes in the queue. If so - drops packets from the Head till the number of bytes is less than or equal to max queue size for the queue. */ -static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex) +static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex) { struct sk_buff* PacketToDrop=NULL; struct net_device_stats *netstats; @@ -392,7 +392,7 @@ static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "<====="); } -VOID flush_all_queues(PMINI_ADAPTER Adapter) +VOID flush_all_queues(struct bcm_mini_adapter *Adapter) { INT iQIndex; UINT uiTotalPacketLength; @@ -442,7 +442,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "<====="); } -USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) +USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter,struct sk_buff* skb) { INT uiLoopIndex=0; struct bcm_classifier_rule *pstClassifierRule = NULL; @@ -652,7 +652,7 @@ USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) static BOOLEAN EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule,PUCHAR Mac) { UINT i=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(pstClassifierRule->ucEthCSSrcMACLen==0) return TRUE; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__); @@ -669,7 +669,7 @@ static BOOLEAN EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifier static BOOLEAN EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule,PUCHAR Mac) { UINT i=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(pstClassifierRule->ucEthCSDestMACLen==0) return TRUE; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__); @@ -685,7 +685,7 @@ static BOOLEAN EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifie static BOOLEAN EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if((pstClassifierRule->ucEtherTypeLen==0)|| (pstClassifierRule->au8EthCSEtherType[0] == 0)) return TRUE; @@ -723,7 +723,7 @@ static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule BOOLEAN bClassificationSucceed = FALSE; USHORT usVLANID; B_UINT8 uPriority = 0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n",__FUNCTION__,ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),pstClassifierRule->usVLANID); @@ -768,7 +768,7 @@ static BOOLEAN EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule } -static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb, +static BOOLEAN EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,struct sk_buff* skb, PS_ETHCS_PKT_INFO pstEthCsPktInfo, struct bcm_classifier_rule *pstClassifierRule, B_UINT8 EthCSCupport) @@ -801,7 +801,7 @@ static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb, return bClassificationSucceed; } -static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload, +static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,PVOID pvEthPayload, PS_ETHCS_PKT_INFO pstEthCsPktInfo) { USHORT u16Etype = ntohs(((struct bcm_eth_header *)pvEthPayload)->u16Etype); diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 63c6a74bb1ff..5e603ce76fea 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -41,7 +41,7 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53 This function dispatches control packet to the h/w interface @return zero(success) or -ve value(failure) */ -INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket) +INT SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) { struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; @@ -84,7 +84,7 @@ This function despatches the IP packets with the given vcid to the target via the host h/w interface. @return zero(success) or -ve value(failure) */ -INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid) +INT SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) { int status=0; BOOLEAN bHeaderSupressionEnabled = FALSE; @@ -180,7 +180,7 @@ errExit: return status; } -static int tx_pending(PMINI_ADAPTER Adapter) +static int tx_pending(struct bcm_mini_adapter *Adapter) { return (atomic_read(&Adapter->TxPktAvail) && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc)) @@ -191,7 +191,7 @@ static int tx_pending(PMINI_ADAPTER Adapter) @ingroup tx_functions Transmit thread */ -int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ +int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/ ) { int status = 0; diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c index 27ddcbfd5935..08d13a4dfd70 100644 --- a/drivers/staging/bcm/hostmibs.c +++ b/drivers/staging/bcm/hostmibs.c @@ -9,7 +9,7 @@ #include "headers.h" -INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs) +INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs) { S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_PHS_RULE *pstPhsRule = NULL; @@ -101,7 +101,7 @@ VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, struct bcm_t sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); } -VOID CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter, CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex) +VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex) { S_MIBS_EXTSERVICEFLOW_PARAMETERS *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable; diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c index c7f488629722..252a1b31d618 100644 --- a/drivers/staging/bcm/led_control.c +++ b/drivers/staging/bcm/led_control.c @@ -13,7 +13,7 @@ static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size) return u16CheckSum; } -BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios) +BOOLEAN IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios) { INT Status; Status = (Adapter->gpioBitMap & gpios) ^ gpios; @@ -23,7 +23,7 @@ BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios) return TRUE; } -static INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, +static INT LED_Blink(struct bcm_mini_adapter *Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate) { int Status = STATUS_SUCCESS; @@ -95,7 +95,7 @@ static INT ScaleRateofTransfer(ULONG rate) -static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx, +static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_Num_tx, UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate) { @@ -261,7 +261,7 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx, * * ----------------------------------------------------------------------------- */ -static INT ValidateDSDParamsChecksum(PMINI_ADAPTER Adapter, ULONG ulParamOffset, +static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, ULONG ulParamOffset, USHORT usParamLen) { INT Status = STATUS_SUCCESS; @@ -347,7 +347,7 @@ exit: * * ----------------------------------------------------------------------------- */ -static INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset) +static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter, ULONG ulHwParamOffset) { INT Status = STATUS_SUCCESS; @@ -371,7 +371,7 @@ static INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset) return Status; } /* ValidateHWParmStructure() */ -static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, +static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter, UCHAR GPIO_Array[]) { int Status = STATUS_SUCCESS; @@ -477,7 +477,7 @@ static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, } -static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, +static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter, BOOLEAN *bEnableThread) { int Status = STATUS_SUCCESS; @@ -580,7 +580,7 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, * * ----------------------------------------------------------------------------- */ -static VOID LedGpioInit(PMINI_ADAPTER Adapter) +static VOID LedGpioInit(struct bcm_mini_adapter *Adapter) { UINT uiResetValue = 0; UINT uiIndex = 0; @@ -605,7 +605,7 @@ static VOID LedGpioInit(PMINI_ADAPTER Adapter) Adapter->LEDInfo.bIdle_led_off = FALSE; } -static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, +static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx, UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex, LedEventInfo_t currdriverstate) { @@ -645,7 +645,7 @@ static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, } return STATUS_SUCCESS; } -static VOID LEDControlThread(PMINI_ADAPTER Adapter) +static VOID LEDControlThread(struct bcm_mini_adapter *Adapter) { UINT uiIndex = 0; UCHAR GPIO_num = 0; @@ -857,7 +857,7 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter) Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; } -int InitLedSettings(PMINI_ADAPTER Adapter) +int InitLedSettings(struct bcm_mini_adapter *Adapter) { int Status = STATUS_SUCCESS; BOOLEAN bEnableThread = TRUE; diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 7d703cb3c5e0..f16d3bb54c3c 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -2,54 +2,54 @@ #define DWORD unsigned int -static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset); -static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter); -static INT BcmGetActiveISO(PMINI_ADAPTER Adapter); -static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter); -static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter); -static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize); - -static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter); -static INT BcmGetNvmSize(PMINI_ADAPTER Adapter); -static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter); -static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter); - -static INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); - -static B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset); -static INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section); -static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section); - -static INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd); -static INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd); -static INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso); -static INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso); - -static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); -static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); -static INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); -static INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, PUINT pBuff, +static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset); +static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); +static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter); +static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); +static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); +static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize); + +static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); +static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter); +static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter); +static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter); + +static INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); + +static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset); +static INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section); +static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section); + +static INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd); +static INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd); +static INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso); +static INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso); + +static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); +static INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, FLASH2X_SECTION_VAL eFlash2xSectionVal, UINT uiOffset, UINT uiNumBytes); -static FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter); -static FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter); +static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter); +static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter); static INT BeceemFlashBulkRead( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes); static INT BeceemFlashBulkWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, BOOLEAN bVerify); -static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter); +static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); -static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData); +static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData); // Procedure: ReadEEPROMStatusRegister // @@ -62,7 +62,7 @@ static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwD // //----------------------------------------------------------------------------- -static UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter ) +static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter ) { UCHAR uiData = 0; DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; @@ -128,7 +128,7 @@ static UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter ) // OSAL_STATUS_CODE: //----------------------------------------------------------------------------- -INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter, +INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, DWORD dwAddress, DWORD *pdwData, DWORD dwNumWords @@ -255,7 +255,7 @@ INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter, // OSAL_STATUS_CODE: //----------------------------------------------------------------------------- -INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter, +INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, DWORD uiOffset, DWORD *pBuffer ) @@ -285,7 +285,7 @@ INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter, -INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter) +INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) { INT Status; unsigned char puMacAddr[6]; @@ -318,7 +318,7 @@ INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter) //----------------------------------------------------------------------------- INT BeceemEEPROMBulkRead( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) @@ -436,7 +436,7 @@ INT BeceemEEPROMBulkRead( //----------------------------------------------------------------------------- static INT BeceemFlashBulkRead( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) @@ -518,7 +518,7 @@ static INT BeceemFlashBulkRead( // //----------------------------------------------------------------------------- -static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) +static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) { if(IsFlash2x(Adapter)) return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); @@ -541,7 +541,7 @@ static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter) +static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) { UINT uiData = 0; UINT uiIndex = 0; @@ -607,7 +607,7 @@ static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter) //----------------------------------------------------------------------------- -static INT FlashSectorErase(PMINI_ADAPTER Adapter, +static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, UINT addr, UINT numOfSectors) { @@ -672,7 +672,7 @@ static INT FlashSectorErase(PMINI_ADAPTER Adapter, //----------------------------------------------------------------------------- static INT flashByteWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { @@ -762,7 +762,7 @@ static INT flashByteWrite( //----------------------------------------------------------------------------- static INT flashWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) @@ -848,7 +848,7 @@ static INT flashWrite( // //----------------------------------------------------------------------------- static INT flashByteWriteStatus( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { @@ -935,7 +935,7 @@ static INT flashByteWriteStatus( //----------------------------------------------------------------------------- static INT flashWriteStatus( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { @@ -1014,7 +1014,7 @@ static INT flashWriteStatus( // //----------------------------------------------------------------------------- -static VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus) +static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter,ULONG ulWriteStatus) { UINT value; value = (FLASH_CMD_WRITE_ENABLE<< 24); @@ -1037,7 +1037,7 @@ static VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStat // ULONG - Status value before UnProtect. // //----------------------------------------------------------------------------- -static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength) +static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter,UINT uiOffset, UINT uiLength) { ULONG ulStatus = 0; ULONG ulWriteStatus = 0; @@ -1146,7 +1146,7 @@ static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT ui //----------------------------------------------------------------------------- static INT BeceemFlashBulkWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -1365,7 +1365,7 @@ BeceemFlashBulkWrite_EXIT: //----------------------------------------------------------------------------- static INT BeceemFlashBulkWriteStatus( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -1545,7 +1545,7 @@ BeceemFlashBulkWriteStatus_EXIT: //----------------------------------------------------------------------------- -INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter) +INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); UINT uiEepromSize = 0; @@ -1614,7 +1614,7 @@ INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) +INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff, pPtr; UINT uiEepromSize = 0; @@ -1699,7 +1699,7 @@ INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) //----------------------------------------------------------------------------- static INT BeceemEEPROMReadBackandVerify( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) @@ -1798,7 +1798,7 @@ static VOID BcmSwapWord(UINT *ptr1) { // OSAL_STATUS_CODE // //----------------------------------------------------------------------------- -static INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset ) +static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset ) { UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; UINT uiStatus = 0; @@ -1934,7 +1934,7 @@ static INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiO //----------------------------------------------------------------------------- INT BeceemEEPROMBulkWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUCHAR pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -2036,7 +2036,7 @@ INT BeceemEEPROMBulkWrite( //----------------------------------------------------------------------------- INT BeceemNVMRead( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) @@ -2099,7 +2099,7 @@ INT BeceemNVMRead( //----------------------------------------------------------------------------- INT BeceemNVMWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -2233,7 +2233,7 @@ INT BeceemNVMWrite( // - if failed. //----------------------------------------------------------------------------- -INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize) +INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize) { INT Status = -1; FLASH_CS_INFO sFlashCsInfo = {0}; @@ -2308,7 +2308,7 @@ INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize) // //----------------------------------------------------------------------------- -static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) +static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) { UINT uiSectorSize = 0; UINT uiSectorSig = 0; @@ -2377,7 +2377,7 @@ static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig // //----------------------------------------------------------------------------- -static INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter) +static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) { UINT value = 0; /* CHIP Bug : Clear the Avail bits on the Read queue. The default @@ -2413,7 +2413,7 @@ static INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -INT BcmInitNVM(PMINI_ADAPTER ps_adapter) +INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) { BcmValidateNvmType(ps_adapter); BcmInitEEPROMQueues(ps_adapter); @@ -2445,7 +2445,7 @@ INT BcmInitNVM(PMINI_ADAPTER ps_adapter) */ /***************************************************************************/ -static INT BcmGetNvmSize(PMINI_ADAPTER Adapter) +static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) { if(Adapter->eNVMType == NVM_EEPROM) { @@ -2469,7 +2469,7 @@ static INT BcmGetNvmSize(PMINI_ADAPTER Adapter) // Returns: // //----------------------------------------------------------------------------- -static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter) +static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) { // @@ -2495,7 +2495,7 @@ static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter) // Returns: // Flash ID //----------------------------------------------------------------------------- -static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter) +static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) { ULONG ulRDID = 0; UINT value; @@ -2518,7 +2518,7 @@ static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter) } -INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter) +INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { if(psAdapter == NULL) { @@ -2552,7 +2552,7 @@ INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter) return STATUS_SUCCESS; } -INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter) +INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { if(psAdapter == NULL) { @@ -2565,7 +2565,7 @@ INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter) return STATUS_SUCCESS ; } -static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter) +static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,struct bcm_mini_adapter *Adapter) { UINT Index = 0; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); @@ -2715,14 +2715,14 @@ static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) return STATUS_SUCCESS; } -static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) +static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section) { return ( Adapter->uiVendorExtnFlag && (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) ); } -static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter) +static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) { B_UINT32 i = 0; UINT uiSizeSection = 0; @@ -2813,7 +2813,7 @@ static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) +static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) { //FLASH_CS_INFO sFlashCsInfo = {0}; @@ -2960,7 +2960,7 @@ static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter) +static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) { UINT uiData = 0; @@ -3004,7 +3004,7 @@ static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter) * On Failure -returns STATUS_FAILURE **/ -INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) +INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { /* * Considering all the section for which end offset can be calculated or directly given @@ -3098,7 +3098,7 @@ INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlas * On Failure -returns STATUS_FAILURE **/ -INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { INT SectEndOffset = 0 ; SectEndOffset = INVALID_OFFSET; @@ -3188,7 +3188,7 @@ INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2 */ INT BcmFlash2xBulkRead( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, FLASH2X_SECTION_VAL eFlash2xSectionVal, UINT uiOffsetWithinSectionVal, @@ -3257,7 +3257,7 @@ INT BcmFlash2xBulkRead( */ INT BcmFlash2xBulkWrite( - PMINI_ADAPTER Adapter, + struct bcm_mini_adapter *Adapter, PUINT pBuffer, FLASH2X_SECTION_VAL eFlash2xSectVal, UINT uiOffset, @@ -3322,7 +3322,7 @@ INT BcmFlash2xBulkWrite( * Return STATUS_SUCESS if get success in setting the right DSD else negaive error code * **/ -static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) +static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) { FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ; @@ -3371,7 +3371,7 @@ static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) * **/ -static INT BcmGetActiveISO(PMINI_ADAPTER Adapter) +static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter) { INT HighestPriISO = 0 ; @@ -3399,7 +3399,7 @@ static INT BcmGetActiveISO(PMINI_ADAPTER Adapter) * Failure:-FALSE, offset is RO * **/ -B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset) +B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) { UINT uiSectorNum = 0; UINT uiWordOfSectorPermission =0; @@ -3424,7 +3424,7 @@ B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset) static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); @@ -3456,7 +3456,7 @@ static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) * Failure:- negative error code **/ -INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap) +INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap) { @@ -3752,7 +3752,7 @@ BcmSetActiveSection :- Set Active section is used to make priority field highest Return Value:- Make the priorit highest else return erorr code **/ -INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) +INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) { unsigned int SectImagePriority = 0; INT Status =STATUS_SUCCESS; @@ -3958,7 +3958,7 @@ BcmCopyISO - Used only for copying the ISO section Return value:- SUCCESS if copies successfully else negative error code **/ -INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) +INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut) { PCHAR Buff = NULL; @@ -4289,7 +4289,7 @@ Return Value :- **/ -INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { INT Status = STATUS_SUCCESS ; @@ -4321,7 +4321,7 @@ Return Value :- Failure :-Return negative error code **/ -INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) +INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { UINT uiSignature = 0 ; @@ -4394,7 +4394,7 @@ Return values:-Return TRUE is request is valid else FALSE. **/ -INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) +INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) { UINT uiNumOfBytes = 0 ; UINT uiSectStartOffset = 0 ; @@ -4459,7 +4459,7 @@ Return value:- return TRUE if flah2.x of hgher version else return false. **/ -INT IsFlash2x(PMINI_ADAPTER Adapter) +INT IsFlash2x(struct bcm_mini_adapter *Adapter) { if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) return TRUE ; @@ -4474,7 +4474,7 @@ Return Value:- Success :- Base Address of the Flash **/ -static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter) +static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) { UINT uiBaseAddr = 0; @@ -4525,7 +4525,7 @@ Return Values- **/ -INT BcmCopySection(PMINI_ADAPTER Adapter, +INT BcmCopySection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL SrcSection, FLASH2X_SECTION_VAL DstSection, UINT offset, @@ -4642,7 +4642,7 @@ Return value :- **/ -INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) +INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset) { UINT offsetToProtect = 0,HeaderSizeToProtect =0; BOOLEAN bHasHeader = FALSE ; @@ -4715,7 +4715,7 @@ BcmDoChipSelect : This will selcet the appropriate chip for writing. OutPut:- Select the Appropriate chip and retrn status Success **/ -static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset) +static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) { UINT FlashConfig = 0; INT ChipNum = 0; @@ -4791,7 +4791,7 @@ static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset) return STATUS_SUCCESS; } -INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd) +INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { UINT uiDSDsig = 0; //UINT sigoffsetInMap = 0; @@ -4816,7 +4816,7 @@ INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd) return uiDSDsig ; } -INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd) +INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { //UINT priOffsetInMap = 0 ; unsigned int uiDSDPri = STATUS_FAILURE; @@ -4839,7 +4839,7 @@ INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd) } return uiDSDPri; } -FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter) +FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter) { INT DSDHighestPri = STATUS_FAILURE; INT DsdPri= 0 ; @@ -4873,7 +4873,7 @@ FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter) return HighestPriDSD ; } -INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso) +INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { UINT uiISOsig = 0; //UINT sigoffsetInMap = 0; @@ -4898,7 +4898,7 @@ INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso) return uiISOsig ; } -INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso) +INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { unsigned int ISOPri = STATUS_FAILURE; @@ -4919,7 +4919,7 @@ INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso) } return ISOPri; } -FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter) +FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter) { INT ISOHighestPri = STATUS_FAILURE; INT ISOPri= 0 ; @@ -4943,7 +4943,7 @@ FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri); return HighestPriISO ; } -INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, +INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, FLASH2X_SECTION_VAL eFlash2xSectionVal, UINT uiOffset, @@ -5006,7 +5006,7 @@ INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, return Status; } -BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) +BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section) { BOOLEAN SectionPresent = FALSE ; @@ -5062,7 +5062,7 @@ BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section } return SectionPresent ; } -INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section) +INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section) { INT offset = STATUS_FAILURE; INT Status = FALSE; @@ -5087,7 +5087,7 @@ INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section) return Status ; } -static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; @@ -5160,7 +5160,7 @@ static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSect return STATUS_SUCCESS ; } -static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; @@ -5212,7 +5212,7 @@ static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSect return STATUS_SUCCESS ; } -BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter) +BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter) { if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) return TRUE; diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c index 5f891fa90a62..d518c4217f13 100644 --- a/drivers/staging/bcm/sort.c +++ b/drivers/staging/bcm/sort.c @@ -22,7 +22,7 @@ static int compare_packet_info(void const *a, void const *b) return pa->u8TrafficPriority - pb->u8TrafficPriority; } -VOID SortPackInfo(PMINI_ADAPTER Adapter) +VOID SortPackInfo(struct bcm_mini_adapter *Adapter) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); @@ -42,7 +42,7 @@ static int compare_classifiers(void const *a, void const *b) return pa->u8ClassifierRulePriority - pb->u8ClassifierRulePriority; } -VOID SortClassifiers(PMINI_ADAPTER Adapter) +VOID SortClassifiers(struct bcm_mini_adapter *Adapter) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c index 4178cd161da3..833883c21a22 100644 --- a/drivers/staging/bcm/vendorspecificextn.c +++ b/drivers/staging/bcm/vendorspecificextn.c @@ -28,7 +28,7 @@ INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendo // STATUS_SUCCESS/STATUS_FAILURE // //----------------------------------------------------------------------------- -INT vendorextnInit(PMINI_ADAPTER Adapter) +INT vendorextnInit(struct bcm_mini_adapter *Adapter) { return STATUS_SUCCESS; } @@ -45,7 +45,7 @@ INT vendorextnInit(PMINI_ADAPTER Adapter) // STATUS_SUCCESS/STATUS_FAILURE // //----------------------------------------------------------------------------- -INT vendorextnExit(PMINI_ADAPTER Adapter) +INT vendorextnExit(struct bcm_mini_adapter *Adapter) { return STATUS_SUCCESS; } @@ -65,7 +65,7 @@ INT vendorextnExit(PMINI_ADAPTER Adapter) // STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value // //-------------------------------------------------------------------------- -INT vendorextnIoctl(PMINI_ADAPTER Adapter, UINT cmd, ULONG arg) +INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg) { return CONTINUE_COMMON_PATH; } diff --git a/drivers/staging/bcm/vendorspecificextn.h b/drivers/staging/bcm/vendorspecificextn.h index 7ff14951f0ca..f237891b9f29 100644 --- a/drivers/staging/bcm/vendorspecificextn.h +++ b/drivers/staging/bcm/vendorspecificextn.h @@ -5,9 +5,9 @@ #define CONTINUE_COMMON_PATH 0xFFFF INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendorInfo); -INT vendorextnExit(PMINI_ADAPTER Adapter); -INT vendorextnInit(PMINI_ADAPTER Adapter); -INT vendorextnIoctl(PMINI_ADAPTER Adapter, UINT cmd, ULONG arg); +INT vendorextnExit(struct bcm_mini_adapter *Adapter); +INT vendorextnInit(struct bcm_mini_adapter *Adapter); +INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg); INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, UINT offset, UINT numOfBytes); INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal, -- GitLab From 9c8ea1b29bc9c9bbd922a652d1b91ddceeb180c6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 21 May 2012 14:18:06 +0200 Subject: [PATCH 0444/6849] iio: add LM3533 ambient-light-sensor driver Add sub-driver for the ambient-light-sensor interface on National Semiconductor / TI LM3533 lighting power chips. The sensor interface can be used to control the LEDs and backlights of the chip through defining five light zones and three sets of corresponding output-current values. The driver provides raw and mean adc readings along with the current light zone through sysfs. A threshold event can be generated on zone changes. The ALS-control output values can be set per zone for the three current output channels. Signed-off-by: Johan Hovold Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../testing/sysfs-bus-iio-light-lm3533-als | 62 ++ drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/light/Kconfig | 22 + drivers/iio/light/Makefile | 5 + drivers/iio/light/lm3533-als.c | 932 ++++++++++++++++++ 6 files changed, 1023 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als create mode 100644 drivers/iio/light/Kconfig create mode 100644 drivers/iio/light/Makefile create mode 100644 drivers/iio/light/lm3533-als.c diff --git a/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als b/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als new file mode 100644 index 000000000000..694a52c8cf82 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als @@ -0,0 +1,62 @@ +What: /sys/.../events/in_illuminance0_thresh_either_en +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Event generated when channel passes one of the four thresholds + in each direction (rising|falling) and a zone change occurs. + The corresponding light zone can be read from + in_illuminance0_zone. + +What: /sys/.../events/in_illuminance0_threshY_hysteresis +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Get the hysteresis for thresholds Y, that is, + + threshY_hysteresis = threshY_raising - threshY_falling + +What: /sys/.../events/illuminance_threshY_falling_value +What: /sys/.../events/illuminance_threshY_raising_value +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Specifies the value of threshold that the device is comparing + against for the events enabled by + in_illuminance0_thresh_either_en (0..255), where Y in 0..3. + + Note that threshY_falling must be less than or equal to + threshY_raising. + + These thresholds correspond to the eight zone-boundary + registers (boundaryY_{low,high}) and defines the five light + zones. + +What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_zone +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Get the current light zone (0..4) as defined by the + in_illuminance0_threshY_{falling,rising} thresholds. + +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Get output current for channel Y (0..255), that is, + out_currentY_currentZ_raw, where Z is the current zone. + +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_currentZ_raw +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the output current for channel out_currentY when in zone + Z (0..255), where Y in 0..2 and Z in 0..4. + + These values correspond to the ALS-mapper target registers for + ALS-mapper Y + 1. diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 56eecefcec75..cacc74d70241 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -50,5 +50,6 @@ config IIO_CONSUMERS_PER_TRIGGER source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" +source "drivers/iio/light/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index e425afd1480c..060b674d278c 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-y += adc/ obj-y += amplifiers/ +obj-y += light/ diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig new file mode 100644 index 000000000000..db5618e7d90b --- /dev/null +++ b/drivers/iio/light/Kconfig @@ -0,0 +1,22 @@ +# +# Light sensors +# +menu "Light sensors" + +config SENSORS_LM3533 + tristate "LM3533 ambient light sensor" + depends on MFD_LM3533 + help + If you say yes here you get support for the ambient light sensor + interface on National Semiconductor / TI LM3533 Lighting Power + chips. + + The sensor interface can be used to control the LEDs and backlights + of the chip through defining five light zones and three sets of + corresponding output-current values. + + The driver provides raw and mean adc readings along with the current + light zone through sysfs. A threshold event can be generated on zone + changes. The ALS-control output values can be set per zone for the + three current output channels. +endmenu diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile new file mode 100644 index 000000000000..c1c23a024cd2 --- /dev/null +++ b/drivers/iio/light/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for IIO Light sensors +# + +obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c new file mode 100644 index 000000000000..c3e7bac13123 --- /dev/null +++ b/drivers/iio/light/lm3533-als.c @@ -0,0 +1,932 @@ +/* + * lm3533-als.c -- LM3533 Ambient Light Sensor driver + * + * Copyright (C) 2011-2012 Texas Instruments + * + * Author: Johan Hovold + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define LM3533_ALS_RESISTOR_MIN 1 +#define LM3533_ALS_RESISTOR_MAX 127 +#define LM3533_ALS_CHANNEL_CURRENT_MAX 2 +#define LM3533_ALS_THRESH_MAX 3 +#define LM3533_ALS_ZONE_MAX 4 + +#define LM3533_REG_ALS_RESISTOR_SELECT 0x30 +#define LM3533_REG_ALS_CONF 0x31 +#define LM3533_REG_ALS_ZONE_INFO 0x34 +#define LM3533_REG_ALS_READ_ADC_RAW 0x37 +#define LM3533_REG_ALS_READ_ADC_AVERAGE 0x38 +#define LM3533_REG_ALS_BOUNDARY_BASE 0x50 +#define LM3533_REG_ALS_TARGET_BASE 0x60 + +#define LM3533_ALS_ENABLE_MASK 0x01 +#define LM3533_ALS_INPUT_MODE_MASK 0x02 +#define LM3533_ALS_INT_ENABLE_MASK 0x01 + +#define LM3533_ALS_ZONE_SHIFT 2 +#define LM3533_ALS_ZONE_MASK 0x1c + +#define LM3533_ALS_FLAG_INT_ENABLED 1 + + +struct lm3533_als { + struct lm3533 *lm3533; + struct platform_device *pdev; + + unsigned long flags; + int irq; + + atomic_t zone; + struct mutex thresh_mutex; +}; + + +static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average, + int *adc) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 reg; + u8 val; + int ret; + + if (average) + reg = LM3533_REG_ALS_READ_ADC_AVERAGE; + else + reg = LM3533_REG_ALS_READ_ADC_RAW; + + ret = lm3533_read(als->lm3533, reg, &val); + if (ret) { + dev_err(&indio_dev->dev, "failed to read adc\n"); + return ret; + } + + *adc = val; + + return 0; +} + +static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 val; + int ret; + + ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val); + if (ret) { + dev_err(&indio_dev->dev, "failed to read zone\n"); + return ret; + } + + val = (val & LM3533_ALS_ZONE_MASK) >> LM3533_ALS_ZONE_SHIFT; + *zone = min_t(u8, val, LM3533_ALS_ZONE_MAX); + + return 0; +} + +static int lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone) +{ + struct lm3533_als *als = iio_priv(indio_dev); + int ret; + + if (test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags)) { + *zone = atomic_read(&als->zone); + } else { + ret = _lm3533_als_get_zone(indio_dev, zone); + if (ret) + return ret; + } + + return 0; +} + +/* + * channel output channel 0..2 + * zone zone 0..4 + */ +static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone) +{ + return LM3533_REG_ALS_TARGET_BASE + 5 * channel + zone; +} + +static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel, + unsigned zone, u8 *val) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 reg; + int ret; + + if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX) + return -EINVAL; + + if (zone > LM3533_ALS_ZONE_MAX) + return -EINVAL; + + reg = lm3533_als_get_target_reg(channel, zone); + ret = lm3533_read(als->lm3533, reg, val); + if (ret) + dev_err(&indio_dev->dev, "failed to get target current\n"); + + return ret; +} + +static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel, + unsigned zone, u8 val) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 reg; + int ret; + + if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX) + return -EINVAL; + + if (zone > LM3533_ALS_ZONE_MAX) + return -EINVAL; + + reg = lm3533_als_get_target_reg(channel, zone); + ret = lm3533_write(als->lm3533, reg, val); + if (ret) + dev_err(&indio_dev->dev, "failed to set target current\n"); + + return ret; +} + +static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel, + int *val) +{ + u8 zone; + u8 target; + int ret; + + ret = lm3533_als_get_zone(indio_dev, &zone); + if (ret) + return ret; + + ret = lm3533_als_get_target(indio_dev, channel, zone, &target); + if (ret) + return ret; + + *val = target; + + return 0; +} + +static int lm3533_als_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret; + + switch (mask) { + case 0: + switch (chan->type) { + case IIO_LIGHT: + ret = lm3533_als_get_adc(indio_dev, false, val); + break; + case IIO_CURRENT: + ret = lm3533_als_get_current(indio_dev, chan->channel, + val); + break; + default: + return -EINVAL; + } + break; + case IIO_CHAN_INFO_AVERAGE_RAW: + ret = lm3533_als_get_adc(indio_dev, true, val); + break; + default: + return -EINVAL; + } + + if (ret) + return ret; + + return IIO_VAL_INT; +} + +#define CHANNEL_CURRENT(_channel) \ + { \ + .type = IIO_CURRENT, \ + .channel = _channel, \ + .indexed = true, \ + .output = true, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + } + +static const struct iio_chan_spec lm3533_als_channels[] = { + { + .type = IIO_LIGHT, + .channel = 0, + .indexed = true, + .info_mask = (IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_RAW_SEPARATE_BIT), + }, + CHANNEL_CURRENT(0), + CHANNEL_CURRENT(1), + CHANNEL_CURRENT(2), +}; + +static irqreturn_t lm3533_als_isr(int irq, void *dev_id) +{ + + struct iio_dev *indio_dev = dev_id; + struct lm3533_als *als = iio_priv(indio_dev); + u8 zone; + int ret; + + /* Clear interrupt by reading the ALS zone register. */ + ret = _lm3533_als_get_zone(indio_dev, &zone); + if (ret) + goto out; + + atomic_set(&als->zone, zone); + + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns()); +out: + return IRQ_HANDLED; +} + +static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 mask = LM3533_ALS_INT_ENABLE_MASK; + u8 val; + int ret; + + if (enable) + val = mask; + else + val = 0; + + ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask); + if (ret) { + dev_err(&indio_dev->dev, "failed to set int mode %d\n", + enable); + return ret; + } + + return 0; +} + +static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 mask = LM3533_ALS_INT_ENABLE_MASK; + u8 val; + int ret; + + ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val); + if (ret) { + dev_err(&indio_dev->dev, "failed to get int mode\n"); + return ret; + } + + *enable = !!(val & mask); + + return 0; +} + +static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising) +{ + u8 offset = !raising; + + return LM3533_REG_ALS_BOUNDARY_BASE + 2 * nr + offset; +} + +static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr, + bool raising, u8 *val) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 reg; + int ret; + + if (nr > LM3533_ALS_THRESH_MAX) + return -EINVAL; + + reg = lm3533_als_get_threshold_reg(nr, raising); + ret = lm3533_read(als->lm3533, reg, val); + if (ret) + dev_err(&indio_dev->dev, "failed to get threshold\n"); + + return ret; +} + +static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr, + bool raising, u8 val) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 val2; + u8 reg, reg2; + int ret; + + if (nr > LM3533_ALS_THRESH_MAX) + return -EINVAL; + + reg = lm3533_als_get_threshold_reg(nr, raising); + reg2 = lm3533_als_get_threshold_reg(nr, !raising); + + mutex_lock(&als->thresh_mutex); + ret = lm3533_read(als->lm3533, reg2, &val2); + if (ret) { + dev_err(&indio_dev->dev, "failed to get threshold\n"); + goto out; + } + /* + * This device does not allow negative hysteresis (in fact, it uses + * whichever value is smaller as the lower bound) so we need to make + * sure that thresh_falling <= thresh_raising. + */ + if ((raising && (val < val2)) || (!raising && (val > val2))) { + ret = -EINVAL; + goto out; + } + + ret = lm3533_write(als->lm3533, reg, val); + if (ret) { + dev_err(&indio_dev->dev, "failed to set threshold\n"); + goto out; + } +out: + mutex_unlock(&als->thresh_mutex); + + return ret; +} + +static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr, + u8 *val) +{ + struct lm3533_als *als = iio_priv(indio_dev); + u8 falling; + u8 raising; + int ret; + + if (nr > LM3533_ALS_THRESH_MAX) + return -EINVAL; + + mutex_lock(&als->thresh_mutex); + ret = lm3533_als_get_threshold(indio_dev, nr, false, &falling); + if (ret) + goto out; + ret = lm3533_als_get_threshold(indio_dev, nr, true, &raising); + if (ret) + goto out; + + *val = raising - falling; +out: + mutex_unlock(&als->thresh_mutex); + + return ret; +} + +static int show_thresh_either_en(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct lm3533_als *als = iio_priv(indio_dev); + int enable; + int ret; + + if (als->irq) { + ret = lm3533_als_get_int_mode(indio_dev, &enable); + if (ret) + return ret; + } else { + enable = 0; + } + + return scnprintf(buf, PAGE_SIZE, "%u\n", enable); +} + +static int store_thresh_either_en(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct lm3533_als *als = iio_priv(indio_dev); + unsigned long enable; + bool int_enabled; + u8 zone; + int ret; + + if (!als->irq) + return -EBUSY; + + if (kstrtoul(buf, 0, &enable)) + return -EINVAL; + + int_enabled = test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); + + if (enable && !int_enabled) { + ret = lm3533_als_get_zone(indio_dev, &zone); + if (ret) + return ret; + + atomic_set(&als->zone, zone); + + set_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); + } + + ret = lm3533_als_set_int_mode(indio_dev, enable); + if (ret) { + if (!int_enabled) + clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); + + return ret; + } + + if (!enable) + clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); + + return len; +} + +static ssize_t show_zone(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + u8 zone; + int ret; + + ret = lm3533_als_get_zone(indio_dev, &zone); + if (ret) + return ret; + + return scnprintf(buf, PAGE_SIZE, "%u\n", zone); +} + +enum lm3533_als_attribute_type { + LM3533_ATTR_TYPE_HYSTERESIS, + LM3533_ATTR_TYPE_TARGET, + LM3533_ATTR_TYPE_THRESH_FALLING, + LM3533_ATTR_TYPE_THRESH_RAISING, +}; + +struct lm3533_als_attribute { + struct device_attribute dev_attr; + enum lm3533_als_attribute_type type; + u8 val1; + u8 val2; +}; + +static inline struct lm3533_als_attribute * +to_lm3533_als_attr(struct device_attribute *attr) +{ + return container_of(attr, struct lm3533_als_attribute, dev_attr); +} + +static ssize_t show_als_attr(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr); + u8 val; + int ret; + + switch (als_attr->type) { + case LM3533_ATTR_TYPE_HYSTERESIS: + ret = lm3533_als_get_hysteresis(indio_dev, als_attr->val1, + &val); + break; + case LM3533_ATTR_TYPE_TARGET: + ret = lm3533_als_get_target(indio_dev, als_attr->val1, + als_attr->val2, &val); + break; + case LM3533_ATTR_TYPE_THRESH_FALLING: + ret = lm3533_als_get_threshold(indio_dev, als_attr->val1, + false, &val); + break; + case LM3533_ATTR_TYPE_THRESH_RAISING: + ret = lm3533_als_get_threshold(indio_dev, als_attr->val1, + true, &val); + break; + default: + ret = -ENXIO; + } + + if (ret) + return ret; + + return scnprintf(buf, PAGE_SIZE, "%u\n", val); +} + +static ssize_t store_als_attr(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr); + u8 val; + int ret; + + if (kstrtou8(buf, 0, &val)) + return -EINVAL; + + switch (als_attr->type) { + case LM3533_ATTR_TYPE_TARGET: + ret = lm3533_als_set_target(indio_dev, als_attr->val1, + als_attr->val2, val); + break; + case LM3533_ATTR_TYPE_THRESH_FALLING: + ret = lm3533_als_set_threshold(indio_dev, als_attr->val1, + false, val); + break; + case LM3533_ATTR_TYPE_THRESH_RAISING: + ret = lm3533_als_set_threshold(indio_dev, als_attr->val1, + true, val); + break; + default: + ret = -ENXIO; + } + + if (ret) + return ret; + + return len; +} + +#define ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \ + { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type, \ + .val1 = _val1, \ + .val2 = _val2 } + +#define LM3533_ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \ + struct lm3533_als_attribute lm3533_als_attr_##_name = \ + ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) + +#define ALS_TARGET_ATTR_RW(_channel, _zone) \ + LM3533_ALS_ATTR(out_current##_channel##_current##_zone##_raw, \ + S_IRUGO | S_IWUSR, \ + show_als_attr, store_als_attr, \ + LM3533_ATTR_TYPE_TARGET, _channel, _zone) +/* + * ALS output current values (ALS mapper targets) + * + * out_current[0-2]_current[0-4]_raw 0-255 + */ +static ALS_TARGET_ATTR_RW(0, 0); +static ALS_TARGET_ATTR_RW(0, 1); +static ALS_TARGET_ATTR_RW(0, 2); +static ALS_TARGET_ATTR_RW(0, 3); +static ALS_TARGET_ATTR_RW(0, 4); + +static ALS_TARGET_ATTR_RW(1, 0); +static ALS_TARGET_ATTR_RW(1, 1); +static ALS_TARGET_ATTR_RW(1, 2); +static ALS_TARGET_ATTR_RW(1, 3); +static ALS_TARGET_ATTR_RW(1, 4); + +static ALS_TARGET_ATTR_RW(2, 0); +static ALS_TARGET_ATTR_RW(2, 1); +static ALS_TARGET_ATTR_RW(2, 2); +static ALS_TARGET_ATTR_RW(2, 3); +static ALS_TARGET_ATTR_RW(2, 4); + +#define ALS_THRESH_FALLING_ATTR_RW(_nr) \ + LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_falling_value, \ + S_IRUGO | S_IWUSR, \ + show_als_attr, store_als_attr, \ + LM3533_ATTR_TYPE_THRESH_FALLING, _nr, 0) + +#define ALS_THRESH_RAISING_ATTR_RW(_nr) \ + LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_raising_value, \ + S_IRUGO | S_IWUSR, \ + show_als_attr, store_als_attr, \ + LM3533_ATTR_TYPE_THRESH_RAISING, _nr, 0) +/* + * ALS Zone thresholds (boundaries) + * + * in_illuminance0_thresh[0-3]_falling_value 0-255 + * in_illuminance0_thresh[0-3]_raising_value 0-255 + */ +static ALS_THRESH_FALLING_ATTR_RW(0); +static ALS_THRESH_FALLING_ATTR_RW(1); +static ALS_THRESH_FALLING_ATTR_RW(2); +static ALS_THRESH_FALLING_ATTR_RW(3); + +static ALS_THRESH_RAISING_ATTR_RW(0); +static ALS_THRESH_RAISING_ATTR_RW(1); +static ALS_THRESH_RAISING_ATTR_RW(2); +static ALS_THRESH_RAISING_ATTR_RW(3); + +#define ALS_HYSTERESIS_ATTR_RO(_nr) \ + LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_hysteresis, \ + S_IRUGO, show_als_attr, NULL, \ + LM3533_ATTR_TYPE_HYSTERESIS, _nr, 0) +/* + * ALS Zone threshold hysteresis + * + * threshY_hysteresis = threshY_raising - threshY_falling + * + * in_illuminance0_thresh[0-3]_hysteresis 0-255 + * in_illuminance0_thresh[0-3]_hysteresis 0-255 + */ +static ALS_HYSTERESIS_ATTR_RO(0); +static ALS_HYSTERESIS_ATTR_RO(1); +static ALS_HYSTERESIS_ATTR_RO(2); +static ALS_HYSTERESIS_ATTR_RO(3); + +#define ILLUMINANCE_ATTR_RO(_name) \ + DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL) +#define ILLUMINANCE_ATTR_RW(_name) \ + DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR , \ + show_##_name, store_##_name) +/* + * ALS Zone threshold-event enable + * + * in_illuminance0_thresh_either_en 0,1 + */ +static ILLUMINANCE_ATTR_RW(thresh_either_en); + +/* + * ALS Current Zone + * + * in_illuminance0_zone 0-4 + */ +static ILLUMINANCE_ATTR_RO(zone); + +static struct attribute *lm3533_als_event_attributes[] = { + &dev_attr_in_illuminance0_thresh_either_en.attr, + &lm3533_als_attr_in_illuminance0_thresh0_falling_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh0_hysteresis.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh0_raising_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh1_falling_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh1_hysteresis.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh1_raising_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh2_falling_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh2_hysteresis.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh2_raising_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh3_falling_value.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh3_hysteresis.dev_attr.attr, + &lm3533_als_attr_in_illuminance0_thresh3_raising_value.dev_attr.attr, + NULL +}; + +static struct attribute_group lm3533_als_event_attribute_group = { + .attrs = lm3533_als_event_attributes +}; + +static struct attribute *lm3533_als_attributes[] = { + &dev_attr_in_illuminance0_zone.attr, + &lm3533_als_attr_out_current0_current0_raw.dev_attr.attr, + &lm3533_als_attr_out_current0_current1_raw.dev_attr.attr, + &lm3533_als_attr_out_current0_current2_raw.dev_attr.attr, + &lm3533_als_attr_out_current0_current3_raw.dev_attr.attr, + &lm3533_als_attr_out_current0_current4_raw.dev_attr.attr, + &lm3533_als_attr_out_current1_current0_raw.dev_attr.attr, + &lm3533_als_attr_out_current1_current1_raw.dev_attr.attr, + &lm3533_als_attr_out_current1_current2_raw.dev_attr.attr, + &lm3533_als_attr_out_current1_current3_raw.dev_attr.attr, + &lm3533_als_attr_out_current1_current4_raw.dev_attr.attr, + &lm3533_als_attr_out_current2_current0_raw.dev_attr.attr, + &lm3533_als_attr_out_current2_current1_raw.dev_attr.attr, + &lm3533_als_attr_out_current2_current2_raw.dev_attr.attr, + &lm3533_als_attr_out_current2_current3_raw.dev_attr.attr, + &lm3533_als_attr_out_current2_current4_raw.dev_attr.attr, + NULL +}; + +static struct attribute_group lm3533_als_attribute_group = { + .attrs = lm3533_als_attributes +}; + +static int __devinit lm3533_als_set_input_mode(struct lm3533_als *als, + bool pwm_mode) +{ + u8 mask = LM3533_ALS_INPUT_MODE_MASK; + u8 val; + int ret; + + if (pwm_mode) + val = mask; /* pwm input */ + else + val = 0; /* analog input */ + + ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask); + if (ret) { + dev_err(&als->pdev->dev, "failed to set input mode %d\n", + pwm_mode); + return ret; + } + + return 0; +} + +static int __devinit lm3533_als_set_resistor(struct lm3533_als *als, u8 val) +{ + int ret; + + if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) + return -EINVAL; + + ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val); + if (ret) { + dev_err(&als->pdev->dev, "failed to set resistor\n"); + return ret; + } + + return 0; +} + +static int __devinit lm3533_als_setup(struct lm3533_als *als, + struct lm3533_als_platform_data *pdata) +{ + int ret; + + ret = lm3533_als_set_input_mode(als, pdata->pwm_mode); + if (ret) + return ret; + + /* ALS input is always high impedance in PWM-mode. */ + if (!pdata->pwm_mode) { + ret = lm3533_als_set_resistor(als, pdata->r_select); + if (ret) + return ret; + } + + return 0; +} + +static int __devinit lm3533_als_setup_irq(struct lm3533_als *als, void *dev) +{ + u8 mask = LM3533_ALS_INT_ENABLE_MASK; + int ret; + + /* Make sure interrupts are disabled. */ + ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask); + if (ret) { + dev_err(&als->pdev->dev, "failed to disable interrupts\n"); + return ret; + } + + ret = request_threaded_irq(als->irq, NULL, lm3533_als_isr, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + dev_name(&als->pdev->dev), dev); + if (ret) { + dev_err(&als->pdev->dev, "failed to request irq %d\n", + als->irq); + return ret; + } + + return 0; +} + +static int __devinit lm3533_als_enable(struct lm3533_als *als) +{ + u8 mask = LM3533_ALS_ENABLE_MASK; + int ret; + + ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask); + if (ret) + dev_err(&als->pdev->dev, "failed to enable ALS\n"); + + return ret; +} + +static int lm3533_als_disable(struct lm3533_als *als) +{ + u8 mask = LM3533_ALS_ENABLE_MASK; + int ret; + + ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask); + if (ret) + dev_err(&als->pdev->dev, "failed to disable ALS\n"); + + return ret; +} + +static const struct iio_info lm3533_als_info = { + .attrs = &lm3533_als_attribute_group, + .event_attrs = &lm3533_als_event_attribute_group, + .driver_module = THIS_MODULE, + .read_raw = &lm3533_als_read_raw, +}; + +static int __devinit lm3533_als_probe(struct platform_device *pdev) +{ + struct lm3533 *lm3533; + struct lm3533_als_platform_data *pdata; + struct lm3533_als *als; + struct iio_dev *indio_dev; + int ret; + + lm3533 = dev_get_drvdata(pdev->dev.parent); + if (!lm3533) + return -EINVAL; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data\n"); + return -EINVAL; + } + + indio_dev = iio_device_alloc(sizeof(*als)); + if (!indio_dev) + return -ENOMEM; + + indio_dev->info = &lm3533_als_info; + indio_dev->channels = lm3533_als_channels; + indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels); + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = pdev->dev.parent; + indio_dev->modes = INDIO_DIRECT_MODE; + + als = iio_priv(indio_dev); + als->lm3533 = lm3533; + als->pdev = pdev; + als->irq = lm3533->irq; + atomic_set(&als->zone, 0); + mutex_init(&als->thresh_mutex); + + platform_set_drvdata(pdev, indio_dev); + + if (als->irq) { + ret = lm3533_als_setup_irq(als, indio_dev); + if (ret) + goto err_free_dev; + } + + ret = lm3533_als_setup(als, pdata); + if (ret) + goto err_free_irq; + + ret = lm3533_als_enable(als); + if (ret) + goto err_free_irq; + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "failed to register ALS\n"); + goto err_disable; + } + + return 0; + +err_disable: + lm3533_als_disable(als); +err_free_irq: + if (als->irq) + free_irq(als->irq, indio_dev); +err_free_dev: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit lm3533_als_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct lm3533_als *als = iio_priv(indio_dev); + + lm3533_als_set_int_mode(indio_dev, false); + iio_device_unregister(indio_dev); + lm3533_als_disable(als); + if (als->irq) + free_irq(als->irq, indio_dev); + iio_device_free(indio_dev); + + return 0; +} + +static struct platform_driver lm3533_als_driver = { + .driver = { + .name = "lm3533-als", + .owner = THIS_MODULE, + }, + .probe = lm3533_als_probe, + .remove = __devexit_p(lm3533_als_remove), +}; +module_platform_driver(lm3533_als_driver); + +MODULE_AUTHOR("Johan Hovold "); +MODULE_DESCRIPTION("LM3533 Ambient Light Sensor driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:lm3533-als"); -- GitLab From d802bf6f098c134181397496cac8dbc80f441a75 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 21 May 2012 14:30:31 +0200 Subject: [PATCH 0445/6849] iio: documentation: Add out_altvoltage and friends Continuous frequency/clock generating devices, such as DDSs or PLLs should use out_altvoltage. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-iio | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 5bc8a476c15e..cfedf63cce15 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -219,6 +219,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale @@ -273,6 +274,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available What: /sys/.../iio:deviceX/in_voltageX_scale_available What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available +What: /sys/.../iio:deviceX/out_altvoltageX_scale_available What: /sys/.../iio:deviceX/in_capacitance_scale_available KernelVersion: 2.635 Contact: linux-iio@vger.kernel.org @@ -298,14 +300,19 @@ Description: gives the 3dB frequency of the filter in Hz. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled, no bias etc.) output voltage for channel Y. The number must always be specified and unique if the output corresponds to a single channel. + While DAC like devices typically use out_voltage, + a continuous frequency generating device, such as + a DDS or PLL should use out_altvoltage. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY&Z_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -316,6 +323,8 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -330,6 +339,8 @@ Description: What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available +What: /sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available +What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -338,6 +349,8 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -346,6 +359,24 @@ Description: normal operation. Y may be suppressed if all outputs are controlled together. +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Output frequency for channel Y in Hz. The number must always be + specified and unique if the output corresponds to a single + channel. + +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Phase in radians of one frequency/clock output Y + (out_altvoltageY) relative to another frequency/clock output + (out_altvoltageZ) of the device X. The number must always be + specified and unique if the output corresponds to a single + channel. + What: /sys/bus/iio/devices/iio:deviceX/events KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org -- GitLab From 04723de09d034c1f1f871787ebbc6cc2e474dd2f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 May 2012 12:30:02 +0200 Subject: [PATCH 0446/6849] staging:iio: remove num_interrupt_lines from documentation Commit 5aa9618896e0ba49 ("staging:iio: remove broken support for multiple event interfaces.") removed the num_interrupt_lines field from struct iio_info but the documentation was never updated. Signed-off-by: Johan Hovold Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/device.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index 0338c7cd0a8b..f03fbd3bb454 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -29,8 +29,6 @@ Then fill in the following: * info->driver_module: Set to THIS_MODULE. Used to ensure correct ownership of various resources allocate by the core. - * info->num_interrupt_lines: - Number of event triggering hardware lines the device has. * info->event_attrs: Attributes used to enable / disable hardware events. * info->attrs: -- GitLab From e407fd655bf9b40c38cba29aa7d38149989798bb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 10:41:42 +0200 Subject: [PATCH 0447/6849] iio: Fix potential use after free There is no guarantee that the last reference to the iio device has already been dropped when iio_device_free is called. This means that we can up calling iio_dev_release after iio_device_free which will lead to a use after free. As the general rule the struct containing the device should always be freed in the release callback. This is what this patch does, it moves freeing the iio device struct as well as releasing the idr reference to the release callback. To ensure that the device is not freed before calling iio_device_free the device_unregister call in iio_device_unregister is broken apart. iio_device_unregister will now only call device_del to remove the device from the system and iio_device_free will call put_device to drop the reference we obtained in iio_devce_alloc. We also have to take care that calling iio_device_free without having called iio_device_register still works (i.e. this can happen if something failed during device initialization). For this to work properly two minor changes were necessary: channel_attr_list needs to be initialized in iio_device_alloc and we have to check whether the chrdev has been registered before releasing it in iio_device_release. This change also brings iio_device_unregister and iio_device_free more in sync with iio_device_register and iio_device_alloc which call device_add and device_initialize respectively. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 1ddd8861c71b..4f947e4377ef 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -661,7 +661,6 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) * New channel registration method - relies on the fact a group does * not need to be initialized if it is name is NULL. */ - INIT_LIST_HEAD(&indio_dev->channel_attr_list); if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { ret = iio_device_add_channel_sysfs(indio_dev, @@ -725,12 +724,16 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - cdev_del(&indio_dev->chrdev); + if (indio_dev->chrdev.dev) + cdev_del(&indio_dev->chrdev); if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); iio_device_unregister_debugfs(indio_dev); + + ida_simple_remove(&iio_ida, indio_dev->id); + kfree(indio_dev); } static struct device_type iio_dev_type = { @@ -761,6 +764,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) dev_set_drvdata(&dev->dev, (void *)dev); mutex_init(&dev->mlock); mutex_init(&dev->info_exist_lock); + INIT_LIST_HEAD(&dev->channel_attr_list); dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); if (dev->id < 0) { @@ -778,10 +782,8 @@ EXPORT_SYMBOL(iio_device_alloc); void iio_device_free(struct iio_dev *dev) { - if (dev) { - ida_simple_remove(&iio_ida, dev->id); - kfree(dev); - } + if (dev) + put_device(&dev->dev); } EXPORT_SYMBOL(iio_device_free); @@ -902,7 +904,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_lock(&indio_dev->info_exist_lock); indio_dev->info = NULL; mutex_unlock(&indio_dev->info_exist_lock); - device_unregister(&indio_dev->dev); + device_del(&indio_dev->dev); } EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); -- GitLab From 76eb9a30db4bc8fd172f9155247264b5f2686d7b Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 20 Feb 2012 14:20:06 +0800 Subject: [PATCH 0448/6849] ACPI, x86: fix Dell M6600 ACPI reboot regression via DMI Dell Precision M6600 is known to require PCI reboot, so add it to the reboot blacklist in pci_reboot_dmi_table[]. https://bugzilla.kernel.org/show_bug.cgi?id=42749 cc: x86@kernel.org Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- arch/x86/kernel/reboot.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 79c45af81604..412db5716d91 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -451,6 +451,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), }, }, + { /* Handle problems with rebooting on the Precision M6600. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 990", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), + }, + }, { } }; -- GitLab From cd1678f963298a9e777f3edb72d28bc18a3a32c2 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 29 May 2012 12:41:19 +0200 Subject: [PATCH 0449/6849] iio: frequency: New driver for AD9523 SPI Low Jitter Clock Generator Changes since V1: Apply Jonathan's review feedback: Revise device status attribute names, and split documentation into two sections. Add additional comments, and fix indention issues. Remove pointless zero initializations. Revise return value handling. Simplify some code sections. Split store_eeprom and sync handling into separate functions. Use strtobool where applicable. Document platform data structures using kernel-doc style. Use dev_to_iio_dev write_raw IIO_CHAN_INFO_FREQUENCY: Reject values <= 0 Make patch target drivers/iio Changes since V2: Use for_each_clear_bit() and __set_bit() where applicable. Add descriptive comment. Avoid temporary for struct regulator. spi_device_id name use ad9523-1, ad9523 will be added later. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../testing/sysfs-bus-iio-frequency-ad9523 | 37 + drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/frequency/Kconfig | 23 + drivers/iio/frequency/Makefile | 5 + drivers/iio/frequency/ad9523.c | 1057 +++++++++++++++++ include/linux/iio/frequency/ad9523.h | 195 +++ 7 files changed, 1319 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 create mode 100644 drivers/iio/frequency/Kconfig create mode 100644 drivers/iio/frequency/Makefile create mode 100644 drivers/iio/frequency/ad9523.c create mode 100644 include/linux/iio/frequency/ad9523.h diff --git a/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 b/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 new file mode 100644 index 000000000000..2ce9c3f68eee --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 @@ -0,0 +1,37 @@ +What: /sys/bus/iio/devices/iio:deviceX/pll2_feedback_clk_present +What: /sys/bus/iio/devices/iio:deviceX/pll2_reference_clk_present +What: /sys/bus/iio/devices/iio:deviceX/pll1_reference_clk_a_present +What: /sys/bus/iio/devices/iio:deviceX/pll1_reference_clk_b_present +What: /sys/bus/iio/devices/iio:deviceX/pll1_reference_clk_test_present +What: /sys/bus/iio/devices/iio:deviceX/vcxo_clk_present +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Reading returns either '1' or '0'. + '1' means that the clock in question is present. + '0' means that the clock is missing. + +What: /sys/bus/iio/devices/iio:deviceX/pllY_locked +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Reading returns either '1' or '0'. '1' means that the + pllY is locked. + +What: /sys/bus/iio/devices/iio:deviceX/store_eeprom +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Writing '1' stores the current device configuration into + on-chip EEPROM. After power-up or chip reset the device will + automatically load the saved configuration. + +What: /sys/bus/iio/devices/iio:deviceX/sync_dividers +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Writing '1' triggers the clock distribution synchronization + functionality. All dividers are reset and the channels start + with their predefined phase offsets (out_altvoltageY_phase). + Writing this file has the effect as driving the external + /SYNC pin low. diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index cacc74d70241..64c88e5cda4d 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -51,5 +51,6 @@ config IIO_CONSUMERS_PER_TRIGGER source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/light/Kconfig" +source "drivers/iio/frequency/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 060b674d278c..bd801c0bbc2f 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-y += adc/ obj-y += amplifiers/ obj-y += light/ +obj-y += frequency/ diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig new file mode 100644 index 000000000000..0458c92464a3 --- /dev/null +++ b/drivers/iio/frequency/Kconfig @@ -0,0 +1,23 @@ +# +# Frequency +# Direct Digital Synthesis drivers (DDS) +# Clock Distribution device drivers +# Phase-Locked Loop (PLL) frequency synthesizers +# + +menu "Frequency Synthesizers DDS/PLL" + +menu "Clock Generator/Distribution" + +config AD9523 + tristate "Analog Devices AD9523 Low Jitter Clock Generator" + depends on SPI + help + Say yes here to build support for Analog Devices AD9523 Low Jitter + Clock Generator. The driver provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad9523. + +endmenu +endmenu diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile new file mode 100644 index 000000000000..1b5b22417da1 --- /dev/null +++ b/drivers/iio/frequency/Makefile @@ -0,0 +1,5 @@ +# +# Makefile iio/frequency +# + +obj-$(CONFIG_AD9523) += ad9523.o diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c new file mode 100644 index 000000000000..7272924484c1 --- /dev/null +++ b/drivers/iio/frequency/ad9523.c @@ -0,0 +1,1057 @@ +/* + * AD9523 SPI Low Jitter Clock Generator + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define AD9523_READ (1 << 15) +#define AD9523_WRITE (0 << 15) +#define AD9523_CNT(x) (((x) - 1) << 13) +#define AD9523_ADDR(x) ((x) & 0xFFF) + +#define AD9523_R1B (1 << 16) +#define AD9523_R2B (2 << 16) +#define AD9523_R3B (3 << 16) +#define AD9523_TRANSF_LEN(x) ((x) >> 16) + +#define AD9523_SERIAL_PORT_CONFIG (AD9523_R1B | 0x0) +#define AD9523_VERSION_REGISTER (AD9523_R1B | 0x2) +#define AD9523_PART_REGISTER (AD9523_R1B | 0x3) +#define AD9523_READBACK_CTRL (AD9523_R1B | 0x4) + +#define AD9523_EEPROM_CUSTOMER_VERSION_ID (AD9523_R2B | 0x6) + +#define AD9523_PLL1_REF_A_DIVIDER (AD9523_R2B | 0x11) +#define AD9523_PLL1_REF_B_DIVIDER (AD9523_R2B | 0x13) +#define AD9523_PLL1_REF_TEST_DIVIDER (AD9523_R1B | 0x14) +#define AD9523_PLL1_FEEDBACK_DIVIDER (AD9523_R2B | 0x17) +#define AD9523_PLL1_CHARGE_PUMP_CTRL (AD9523_R2B | 0x19) +#define AD9523_PLL1_INPUT_RECEIVERS_CTRL (AD9523_R1B | 0x1A) +#define AD9523_PLL1_REF_CTRL (AD9523_R1B | 0x1B) +#define AD9523_PLL1_MISC_CTRL (AD9523_R1B | 0x1C) +#define AD9523_PLL1_LOOP_FILTER_CTRL (AD9523_R1B | 0x1D) + +#define AD9523_PLL2_CHARGE_PUMP (AD9523_R1B | 0xF0) +#define AD9523_PLL2_FEEDBACK_DIVIDER_AB (AD9523_R1B | 0xF1) +#define AD9523_PLL2_CTRL (AD9523_R1B | 0xF2) +#define AD9523_PLL2_VCO_CTRL (AD9523_R1B | 0xF3) +#define AD9523_PLL2_VCO_DIVIDER (AD9523_R1B | 0xF4) +#define AD9523_PLL2_LOOP_FILTER_CTRL (AD9523_R2B | 0xF6) +#define AD9523_PLL2_R2_DIVIDER (AD9523_R1B | 0xF7) + +#define AD9523_CHANNEL_CLOCK_DIST(ch) (AD9523_R3B | (0x192 + 3 * ch)) + +#define AD9523_PLL1_OUTPUT_CTRL (AD9523_R1B | 0x1BA) +#define AD9523_PLL1_OUTPUT_CHANNEL_CTRL (AD9523_R1B | 0x1BB) + +#define AD9523_READBACK_0 (AD9523_R1B | 0x22C) +#define AD9523_READBACK_1 (AD9523_R1B | 0x22D) + +#define AD9523_STATUS_SIGNALS (AD9523_R3B | 0x232) +#define AD9523_POWER_DOWN_CTRL (AD9523_R1B | 0x233) +#define AD9523_IO_UPDATE (AD9523_R1B | 0x234) + +#define AD9523_EEPROM_DATA_XFER_STATUS (AD9523_R1B | 0xB00) +#define AD9523_EEPROM_ERROR_READBACK (AD9523_R1B | 0xB01) +#define AD9523_EEPROM_CTRL1 (AD9523_R1B | 0xB02) +#define AD9523_EEPROM_CTRL2 (AD9523_R1B | 0xB03) + +/* AD9523_SERIAL_PORT_CONFIG */ + +#define AD9523_SER_CONF_SDO_ACTIVE (1 << 7) +#define AD9523_SER_CONF_SOFT_RESET (1 << 5) + +/* AD9523_READBACK_CTRL */ +#define AD9523_READBACK_CTRL_READ_BUFFERED (1 << 0) + +/* AD9523_PLL1_CHARGE_PUMP_CTRL */ +#define AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(x) (((x) / 500) & 0x7F) +#define AD9523_PLL1_CHARGE_PUMP_TRISTATE (1 << 7) +#define AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL (3 << 8) +#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_DOWN (2 << 8) +#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_UP (1 << 8) +#define AD9523_PLL1_CHARGE_PUMP_MODE_TRISTATE (0 << 8) +#define AD9523_PLL1_BACKLASH_PW_MIN (0 << 10) +#define AD9523_PLL1_BACKLASH_PW_LOW (1 << 10) +#define AD9523_PLL1_BACKLASH_PW_HIGH (2 << 10) +#define AD9523_PLL1_BACKLASH_PW_MAX (3 << 10) + +/* AD9523_PLL1_INPUT_RECEIVERS_CTRL */ +#define AD9523_PLL1_REF_TEST_RCV_EN (1 << 7) +#define AD9523_PLL1_REFB_DIFF_RCV_EN (1 << 6) +#define AD9523_PLL1_REFA_DIFF_RCV_EN (1 << 5) +#define AD9523_PLL1_REFB_RCV_EN (1 << 4) +#define AD9523_PLL1_REFA_RCV_EN (1 << 3) +#define AD9523_PLL1_REFA_REFB_PWR_CTRL_EN (1 << 2) +#define AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN (1 << 1) +#define AD9523_PLL1_OSC_IN_DIFF_EN (1 << 0) + +/* AD9523_PLL1_REF_CTRL */ +#define AD9523_PLL1_BYPASS_REF_TEST_DIV_EN (1 << 7) +#define AD9523_PLL1_BYPASS_FEEDBACK_DIV_EN (1 << 6) +#define AD9523_PLL1_ZERO_DELAY_MODE_INT (1 << 5) +#define AD9523_PLL1_ZERO_DELAY_MODE_EXT (0 << 5) +#define AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN (1 << 4) +#define AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN (1 << 3) +#define AD9523_PLL1_ZD_IN_DIFF_EN (1 << 2) +#define AD9523_PLL1_REFB_CMOS_NEG_INP_EN (1 << 1) +#define AD9523_PLL1_REFA_CMOS_NEG_INP_EN (1 << 0) + +/* AD9523_PLL1_MISC_CTRL */ +#define AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN (1 << 7) +#define AD9523_PLL1_OSC_CTRL_FAIL_VCC_BY2_EN (1 << 6) +#define AD9523_PLL1_REF_MODE(x) ((x) << 2) +#define AD9523_PLL1_BYPASS_REFB_DIV (1 << 1) +#define AD9523_PLL1_BYPASS_REFA_DIV (1 << 0) + +/* AD9523_PLL1_LOOP_FILTER_CTRL */ +#define AD9523_PLL1_LOOP_FILTER_RZERO(x) ((x) & 0xF) + +/* AD9523_PLL2_CHARGE_PUMP */ +#define AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(x) ((x) / 3500) + +/* AD9523_PLL2_FEEDBACK_DIVIDER_AB */ +#define AD9523_PLL2_FB_NDIV_A_CNT(x) (((x) & 0x3) << 6) +#define AD9523_PLL2_FB_NDIV_B_CNT(x) (((x) & 0x3F) << 0) +#define AD9523_PLL2_FB_NDIV(a, b) (4 * (b) + (a)) + +/* AD9523_PLL2_CTRL */ +#define AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL (3 << 0) +#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_DOWN (2 << 0) +#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_UP (1 << 0) +#define AD9523_PLL2_CHARGE_PUMP_MODE_TRISTATE (0 << 0) +#define AD9523_PLL2_BACKLASH_PW_MIN (0 << 2) +#define AD9523_PLL2_BACKLASH_PW_LOW (1 << 2) +#define AD9523_PLL2_BACKLASH_PW_HIGH (2 << 2) +#define AD9523_PLL2_BACKLASH_PW_MAX (3 << 1) +#define AD9523_PLL2_BACKLASH_CTRL_EN (1 << 4) +#define AD9523_PLL2_FREQ_DOUBLER_EN (1 << 5) +#define AD9523_PLL2_LOCK_DETECT_PWR_DOWN_EN (1 << 7) + +/* AD9523_PLL2_VCO_CTRL */ +#define AD9523_PLL2_VCO_CALIBRATE (1 << 1) +#define AD9523_PLL2_FORCE_VCO_MIDSCALE (1 << 2) +#define AD9523_PLL2_FORCE_REFERENCE_VALID (1 << 3) +#define AD9523_PLL2_FORCE_RELEASE_SYNC (1 << 4) + +/* AD9523_PLL2_VCO_DIVIDER */ +#define AD9523_PLL2_VCO_DIV_M1(x) ((((x) - 3) & 0x3) << 0) +#define AD9523_PLL2_VCO_DIV_M2(x) ((((x) - 3) & 0x3) << 4) +#define AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN (1 << 2) +#define AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN (1 << 6) + +/* AD9523_PLL2_LOOP_FILTER_CTRL */ +#define AD9523_PLL2_LOOP_FILTER_CPOLE1(x) (((x) & 0x7) << 0) +#define AD9523_PLL2_LOOP_FILTER_RZERO(x) (((x) & 0x7) << 3) +#define AD9523_PLL2_LOOP_FILTER_RPOLE2(x) (((x) & 0x7) << 6) +#define AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN (1 << 8) + +/* AD9523_PLL2_R2_DIVIDER */ +#define AD9523_PLL2_R2_DIVIDER_VAL(x) (((x) & 0x1F) << 0) + +/* AD9523_CHANNEL_CLOCK_DIST */ +#define AD9523_CLK_DIST_DIV_PHASE(x) (((x) & 0x3F) << 18) +#define AD9523_CLK_DIST_DIV_PHASE_REV(x) ((ret >> 18) & 0x3F) +#define AD9523_CLK_DIST_DIV(x) ((((x) - 1) & 0x3FF) << 8) +#define AD9523_CLK_DIST_DIV_REV(x) (((ret >> 8) & 0x3FF) + 1) +#define AD9523_CLK_DIST_INV_DIV_OUTPUT_EN (1 << 7) +#define AD9523_CLK_DIST_IGNORE_SYNC_EN (1 << 6) +#define AD9523_CLK_DIST_PWR_DOWN_EN (1 << 5) +#define AD9523_CLK_DIST_LOW_PWR_MODE_EN (1 << 4) +#define AD9523_CLK_DIST_DRIVER_MODE(x) (((x) & 0xF) << 0) + +/* AD9523_PLL1_OUTPUT_CTRL */ +#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH6_M2 (1 << 7) +#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH5_M2 (1 << 6) +#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 (1 << 5) +#define AD9523_PLL1_OUTP_CTRL_CMOS_DRV_WEAK (1 << 4) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_1 (0 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_2 (1 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_4 (2 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_8 (4 << 0) +#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_16 (8 << 0) + +/* AD9523_PLL1_OUTPUT_CHANNEL_CTRL */ +#define AD9523_PLL1_OUTP_CH_CTRL_OUTPUT_PWR_DOWN_EN (1 << 7) +#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH9_M2 (1 << 6) +#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH8_M2 (1 << 5) +#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 (1 << 4) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH3 (1 << 3) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH2 (1 << 2) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH1 (1 << 1) +#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 (1 << 0) + +/* AD9523_READBACK_0 */ +#define AD9523_READBACK_0_STAT_PLL2_REF_CLK (1 << 7) +#define AD9523_READBACK_0_STAT_PLL2_FB_CLK (1 << 6) +#define AD9523_READBACK_0_STAT_VCXO (1 << 5) +#define AD9523_READBACK_0_STAT_REF_TEST (1 << 4) +#define AD9523_READBACK_0_STAT_REFB (1 << 3) +#define AD9523_READBACK_0_STAT_REFA (1 << 2) +#define AD9523_READBACK_0_STAT_PLL2_LD (1 << 1) +#define AD9523_READBACK_0_STAT_PLL1_LD (1 << 0) + +/* AD9523_READBACK_1 */ +#define AD9523_READBACK_1_HOLDOVER_ACTIVE (1 << 3) +#define AD9523_READBACK_1_AUTOMODE_SEL_REFB (1 << 2) +#define AD9523_READBACK_1_VCO_CALIB_IN_PROGRESS (1 << 0) + +/* AD9523_STATUS_SIGNALS */ +#define AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL (1 << 16) +#define AD9523_STATUS_MONITOR_01_PLL12_LOCKED (0x302) +/* AD9523_POWER_DOWN_CTRL */ +#define AD9523_POWER_DOWN_CTRL_PLL1_PWR_DOWN (1 << 2) +#define AD9523_POWER_DOWN_CTRL_PLL2_PWR_DOWN (1 << 1) +#define AD9523_POWER_DOWN_CTRL_DIST_PWR_DOWN (1 << 0) + +/* AD9523_IO_UPDATE */ +#define AD9523_IO_UPDATE_EN (1 << 0) + +/* AD9523_EEPROM_DATA_XFER_STATUS */ +#define AD9523_EEPROM_DATA_XFER_IN_PROGRESS (1 << 0) + +/* AD9523_EEPROM_ERROR_READBACK */ +#define AD9523_EEPROM_ERROR_READBACK_FAIL (1 << 0) + +/* AD9523_EEPROM_CTRL1 */ +#define AD9523_EEPROM_CTRL1_SOFT_EEPROM (1 << 1) +#define AD9523_EEPROM_CTRL1_EEPROM_WRITE_PROT_DIS (1 << 0) + +/* AD9523_EEPROM_CTRL2 */ +#define AD9523_EEPROM_CTRL2_REG2EEPROM (1 << 0) + +#define AD9523_NUM_CHAN 14 +#define AD9523_NUM_CHAN_ALT_CLK_SRC 10 + +/* Helpers to avoid excess line breaks */ +#define AD_IFE(_pde, _a, _b) ((pdata->_pde) ? _a : _b) +#define AD_IF(_pde, _a) AD_IFE(_pde, _a, 0) + +enum { + AD9523_STAT_PLL1_LD, + AD9523_STAT_PLL2_LD, + AD9523_STAT_REFA, + AD9523_STAT_REFB, + AD9523_STAT_REF_TEST, + AD9523_STAT_VCXO, + AD9523_STAT_PLL2_FB_CLK, + AD9523_STAT_PLL2_REF_CLK, + AD9523_SYNC, + AD9523_EEPROM, +}; + +enum { + AD9523_VCO1, + AD9523_VCO2, + AD9523_VCXO, + AD9523_NUM_CLK_SRC, +}; + +struct ad9523_state { + struct spi_device *spi; + struct regulator *reg; + struct ad9523_platform_data *pdata; + struct iio_chan_spec ad9523_channels[AD9523_NUM_CHAN]; + + unsigned long vcxo_freq; + unsigned long vco_freq; + unsigned long vco_out_freq[AD9523_NUM_CLK_SRC]; + unsigned char vco_out_map[AD9523_NUM_CHAN_ALT_CLK_SRC]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + union { + __be32 d32; + u8 d8[4]; + } data[2] ____cacheline_aligned; +}; + +static int ad9523_read(struct iio_dev *indio_dev, unsigned addr) +{ + struct ad9523_state *st = iio_priv(indio_dev); + struct spi_message m; + int ret; + + /* We encode the register size 1..3 bytes into the register address. + * On transfer we get the size from the register datum, and make sure + * the result is properly aligned. + */ + + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[2], + .len = 2, + }, { + .rx_buf = &st->data[1].d8[4 - AD9523_TRANSF_LEN(addr)], + .len = AD9523_TRANSF_LEN(addr), + }, + }; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + st->data[0].d32 = cpu_to_be32(AD9523_READ | + AD9523_CNT(AD9523_TRANSF_LEN(addr)) | + AD9523_ADDR(addr)); + + ret = spi_sync(st->spi, &m); + if (ret < 0) + dev_err(&indio_dev->dev, "read failed (%d)", ret); + else + ret = be32_to_cpu(st->data[1].d32) & (0xFFFFFF >> + (8 * (3 - AD9523_TRANSF_LEN(addr)))); + + return ret; +}; + +static int ad9523_write(struct iio_dev *indio_dev, unsigned addr, unsigned val) +{ + struct ad9523_state *st = iio_priv(indio_dev); + struct spi_message m; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[2], + .len = 2, + }, { + .tx_buf = &st->data[1].d8[4 - AD9523_TRANSF_LEN(addr)], + .len = AD9523_TRANSF_LEN(addr), + }, + }; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + st->data[0].d32 = cpu_to_be32(AD9523_WRITE | + AD9523_CNT(AD9523_TRANSF_LEN(addr)) | + AD9523_ADDR(addr)); + st->data[1].d32 = cpu_to_be32(val); + + ret = spi_sync(st->spi, &m); + + if (ret < 0) + dev_err(&indio_dev->dev, "write failed (%d)", ret); + + return ret; +} + +static int ad9523_io_update(struct iio_dev *indio_dev) +{ + return ad9523_write(indio_dev, AD9523_IO_UPDATE, AD9523_IO_UPDATE_EN); +} + +static int ad9523_vco_out_map(struct iio_dev *indio_dev, + unsigned ch, bool out) +{ + struct ad9523_state *st = iio_priv(indio_dev); + int ret; + unsigned mask; + + switch (ch) { + case 0 ... 3: + ret = ad9523_read(indio_dev, AD9523_PLL1_OUTPUT_CHANNEL_CTRL); + if (ret < 0) + break; + mask = AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 << ch; + if (out) { + ret |= mask; + out = 2; + } else { + ret &= ~mask; + } + ret = ad9523_write(indio_dev, + AD9523_PLL1_OUTPUT_CHANNEL_CTRL, ret); + break; + case 4 ... 6: + ret = ad9523_read(indio_dev, AD9523_PLL1_OUTPUT_CTRL); + if (ret < 0) + break; + mask = AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 << (ch - 4); + if (out) + ret |= mask; + else + ret &= ~mask; + ret = ad9523_write(indio_dev, AD9523_PLL1_OUTPUT_CTRL, ret); + break; + case 7 ... 9: + ret = ad9523_read(indio_dev, AD9523_PLL1_OUTPUT_CHANNEL_CTRL); + if (ret < 0) + break; + mask = AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 << (ch - 7); + if (out) + ret |= mask; + else + ret &= ~mask; + ret = ad9523_write(indio_dev, + AD9523_PLL1_OUTPUT_CHANNEL_CTRL, ret); + break; + default: + return 0; + } + + st->vco_out_map[ch] = out; + + return ret; +} + +static int ad9523_set_clock_provider(struct iio_dev *indio_dev, + unsigned ch, unsigned long freq) +{ + struct ad9523_state *st = iio_priv(indio_dev); + long tmp1, tmp2; + bool use_alt_clk_src; + + switch (ch) { + case 0 ... 3: + use_alt_clk_src = (freq == st->vco_out_freq[AD9523_VCXO]); + break; + case 4 ... 9: + tmp1 = st->vco_out_freq[AD9523_VCO1] / freq; + tmp2 = st->vco_out_freq[AD9523_VCO2] / freq; + tmp1 *= freq; + tmp2 *= freq; + use_alt_clk_src = (abs(tmp1 - freq) > abs(tmp2 - freq)); + break; + default: + /* Ch 10..14: No action required, return success */ + return 0; + } + + return ad9523_vco_out_map(indio_dev, ch, use_alt_clk_src); +} + +static int ad9523_store_eeprom(struct iio_dev *indio_dev) +{ + int ret, tmp; + + ret = ad9523_write(indio_dev, AD9523_EEPROM_CTRL1, + AD9523_EEPROM_CTRL1_EEPROM_WRITE_PROT_DIS); + if (ret < 0) + return ret; + ret = ad9523_write(indio_dev, AD9523_EEPROM_CTRL2, + AD9523_EEPROM_CTRL2_REG2EEPROM); + if (ret < 0) + return ret; + + tmp = 4; + do { + msleep(16); + ret = ad9523_read(indio_dev, + AD9523_EEPROM_DATA_XFER_STATUS); + if (ret < 0) + return ret; + } while ((ret & AD9523_EEPROM_DATA_XFER_IN_PROGRESS) && tmp--); + + ret = ad9523_write(indio_dev, AD9523_EEPROM_CTRL1, 0); + if (ret < 0) + return ret; + + ret = ad9523_read(indio_dev, AD9523_EEPROM_ERROR_READBACK); + if (ret < 0) + return ret; + + if (ret & AD9523_EEPROM_ERROR_READBACK_FAIL) { + dev_err(&indio_dev->dev, "Verify EEPROM failed"); + ret = -EIO; + } + + return ret; +} + +static int ad9523_sync(struct iio_dev *indio_dev) +{ + int ret, tmp; + + ret = ad9523_read(indio_dev, AD9523_STATUS_SIGNALS); + if (ret < 0) + return ret; + + tmp = ret; + tmp |= AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL; + + ret = ad9523_write(indio_dev, AD9523_STATUS_SIGNALS, tmp); + if (ret < 0) + return ret; + + ad9523_io_update(indio_dev); + tmp &= ~AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL; + + ret = ad9523_write(indio_dev, AD9523_STATUS_SIGNALS, tmp); + if (ret < 0) + return ret; + + return ad9523_io_update(indio_dev); +} + +static ssize_t ad9523_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + bool state; + int ret; + + ret = strtobool(buf, &state); + if (ret < 0) + return ret; + + if (!state) + return 0; + + mutex_lock(&indio_dev->mlock); + switch ((u32)this_attr->address) { + case AD9523_SYNC: + ret = ad9523_sync(indio_dev); + break; + case AD9523_EEPROM: + ret = ad9523_store_eeprom(indio_dev); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t ad9523_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + + mutex_lock(&indio_dev->mlock); + ret = ad9523_read(indio_dev, AD9523_READBACK_0); + if (ret >= 0) { + ret = sprintf(buf, "%d\n", !!(ret & (1 << + (u32)this_attr->address))); + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static IIO_DEVICE_ATTR(pll1_locked, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_PLL1_LD); + +static IIO_DEVICE_ATTR(pll2_locked, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_PLL2_LD); + +static IIO_DEVICE_ATTR(pll1_reference_clk_a_present, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_REFA); + +static IIO_DEVICE_ATTR(pll1_reference_clk_b_present, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_REFB); + +static IIO_DEVICE_ATTR(pll1_reference_clk_test_present, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_REF_TEST); + +static IIO_DEVICE_ATTR(vcxo_clk_present, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_VCXO); + +static IIO_DEVICE_ATTR(pll2_feedback_clk_present, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_PLL2_FB_CLK); + +static IIO_DEVICE_ATTR(pll2_reference_clk_present, S_IRUGO, + ad9523_show, + NULL, + AD9523_STAT_PLL2_REF_CLK); + +static IIO_DEVICE_ATTR(sync_dividers, S_IWUSR, + NULL, + ad9523_store, + AD9523_SYNC); + +static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, + NULL, + ad9523_store, + AD9523_EEPROM); + +static struct attribute *ad9523_attributes[] = { + &iio_dev_attr_sync_dividers.dev_attr.attr, + &iio_dev_attr_store_eeprom.dev_attr.attr, + &iio_dev_attr_pll2_feedback_clk_present.dev_attr.attr, + &iio_dev_attr_pll2_reference_clk_present.dev_attr.attr, + &iio_dev_attr_pll1_reference_clk_a_present.dev_attr.attr, + &iio_dev_attr_pll1_reference_clk_b_present.dev_attr.attr, + &iio_dev_attr_pll1_reference_clk_test_present.dev_attr.attr, + &iio_dev_attr_vcxo_clk_present.dev_attr.attr, + &iio_dev_attr_pll1_locked.dev_attr.attr, + &iio_dev_attr_pll2_locked.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9523_attribute_group = { + .attrs = ad9523_attributes, +}; + +static int ad9523_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad9523_state *st = iio_priv(indio_dev); + unsigned code; + int ret; + + mutex_lock(&indio_dev->mlock); + ret = ad9523_read(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel)); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + switch (m) { + case IIO_CHAN_INFO_RAW: + *val = !(ret & AD9523_CLK_DIST_PWR_DOWN_EN); + return IIO_VAL_INT; + case IIO_CHAN_INFO_FREQUENCY: + *val = st->vco_out_freq[st->vco_out_map[chan->channel]] / + AD9523_CLK_DIST_DIV_REV(ret); + return IIO_VAL_INT; + case IIO_CHAN_INFO_PHASE: + code = (AD9523_CLK_DIST_DIV_PHASE_REV(ret) * 3141592) / + AD9523_CLK_DIST_DIV_REV(ret); + *val = code / 1000000; + *val2 = (code % 1000000) * 10; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +}; + +static int ad9523_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad9523_state *st = iio_priv(indio_dev); + unsigned reg; + int ret, tmp, code; + + mutex_lock(&indio_dev->mlock); + ret = ad9523_read(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel)); + if (ret < 0) + goto out; + + reg = ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val) + reg &= ~AD9523_CLK_DIST_PWR_DOWN_EN; + else + reg |= AD9523_CLK_DIST_PWR_DOWN_EN; + break; + case IIO_CHAN_INFO_FREQUENCY: + if (val <= 0) { + ret = -EINVAL; + goto out; + } + ret = ad9523_set_clock_provider(indio_dev, chan->channel, val); + if (ret < 0) + goto out; + tmp = st->vco_out_freq[st->vco_out_map[chan->channel]] / val; + tmp = clamp(tmp, 1, 1024); + reg &= ~(0x3FF << 8); + reg |= AD9523_CLK_DIST_DIV(tmp); + break; + case IIO_CHAN_INFO_PHASE: + code = val * 1000000 + val2 % 1000000; + tmp = (code * AD9523_CLK_DIST_DIV_REV(ret)) / 3141592; + tmp = clamp(tmp, 0, 63); + reg &= ~AD9523_CLK_DIST_DIV_PHASE(~0); + reg |= AD9523_CLK_DIST_DIV_PHASE(tmp); + break; + default: + ret = -EINVAL; + goto out; + } + + ret = ad9523_write(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel), + reg); + if (ret < 0) + goto out; + + ad9523_io_update(indio_dev); +out: + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static int ad9523_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + int ret; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + ret = ad9523_write(indio_dev, reg | AD9523_R1B, writeval); + ad9523_io_update(indio_dev); + } else { + ret = ad9523_read(indio_dev, reg | AD9523_R1B); + if (ret < 0) + return ret; + *readval = ret; + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static const struct iio_info ad9523_info = { + .read_raw = &ad9523_read_raw, + .write_raw = &ad9523_write_raw, + .debugfs_reg_access = &ad9523_reg_access, + .attrs = &ad9523_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int ad9523_setup(struct iio_dev *indio_dev) +{ + struct ad9523_state *st = iio_priv(indio_dev); + struct ad9523_platform_data *pdata = st->pdata; + struct ad9523_channel_spec *chan; + unsigned long active_mask = 0; + int ret, i; + + ret = ad9523_write(indio_dev, AD9523_SERIAL_PORT_CONFIG, + AD9523_SER_CONF_SOFT_RESET | + (st->spi->mode & SPI_3WIRE ? 0 : + AD9523_SER_CONF_SDO_ACTIVE)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_READBACK_CTRL, + AD9523_READBACK_CTRL_READ_BUFFERED); + if (ret < 0) + return ret; + + ret = ad9523_io_update(indio_dev); + if (ret < 0) + return ret; + + /* + * PLL1 Setup + */ + ret = ad9523_write(indio_dev, AD9523_PLL1_REF_A_DIVIDER, + pdata->refa_r_div); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_REF_B_DIVIDER, + pdata->refb_r_div); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_FEEDBACK_DIVIDER, + pdata->pll1_feedback_div); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_CHARGE_PUMP_CTRL, + AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(pdata-> + pll1_charge_pump_current_nA) | + AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL | + AD9523_PLL1_BACKLASH_PW_MIN); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_INPUT_RECEIVERS_CTRL, + AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_RCV_EN) | + AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_RCV_EN) | + AD_IF(osc_in_diff_en, AD9523_PLL1_OSC_IN_DIFF_EN) | + AD_IF(osc_in_cmos_neg_inp_en, + AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN) | + AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_DIFF_RCV_EN) | + AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_DIFF_RCV_EN)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_REF_CTRL, + AD_IF(zd_in_diff_en, AD9523_PLL1_ZD_IN_DIFF_EN) | + AD_IF(zd_in_cmos_neg_inp_en, + AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN) | + AD_IF(zero_delay_mode_internal_en, + AD9523_PLL1_ZERO_DELAY_MODE_INT) | + AD_IF(osc_in_feedback_en, AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN) | + AD_IF(refa_cmos_neg_inp_en, AD9523_PLL1_REFA_CMOS_NEG_INP_EN) | + AD_IF(refb_cmos_neg_inp_en, AD9523_PLL1_REFB_CMOS_NEG_INP_EN)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_MISC_CTRL, + AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN | + AD9523_PLL1_REF_MODE(pdata->ref_mode)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL1_LOOP_FILTER_CTRL, + AD9523_PLL1_LOOP_FILTER_RZERO(pdata->pll1_loop_filter_rzero)); + if (ret < 0) + return ret; + /* + * PLL2 Setup + */ + + ret = ad9523_write(indio_dev, AD9523_PLL2_CHARGE_PUMP, + AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(pdata-> + pll2_charge_pump_current_nA)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_FEEDBACK_DIVIDER_AB, + AD9523_PLL2_FB_NDIV_A_CNT(pdata->pll2_ndiv_a_cnt) | + AD9523_PLL2_FB_NDIV_B_CNT(pdata->pll2_ndiv_b_cnt)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_CTRL, + AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL | + AD9523_PLL2_BACKLASH_CTRL_EN | + AD_IF(pll2_freq_doubler_en, AD9523_PLL2_FREQ_DOUBLER_EN)); + if (ret < 0) + return ret; + + st->vco_freq = (pdata->vcxo_freq * (pdata->pll2_freq_doubler_en ? 2 : 1) + / pdata->pll2_r2_div) * AD9523_PLL2_FB_NDIV(pdata-> + pll2_ndiv_a_cnt, pdata->pll2_ndiv_b_cnt); + + ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_CTRL, + AD9523_PLL2_VCO_CALIBRATE); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_VCO_DIVIDER, + AD9523_PLL2_VCO_DIV_M1(pdata->pll2_vco_diff_m1) | + AD9523_PLL2_VCO_DIV_M2(pdata->pll2_vco_diff_m2) | + AD_IFE(pll2_vco_diff_m1, 0, + AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN) | + AD_IFE(pll2_vco_diff_m2, 0, + AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN)); + if (ret < 0) + return ret; + + if (pdata->pll2_vco_diff_m1) + st->vco_out_freq[AD9523_VCO1] = + st->vco_freq / pdata->pll2_vco_diff_m1; + + if (pdata->pll2_vco_diff_m2) + st->vco_out_freq[AD9523_VCO2] = + st->vco_freq / pdata->pll2_vco_diff_m2; + + st->vco_out_freq[AD9523_VCXO] = pdata->vcxo_freq; + + ret = ad9523_write(indio_dev, AD9523_PLL2_R2_DIVIDER, + AD9523_PLL2_R2_DIVIDER_VAL(pdata->pll2_r2_div)); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_PLL2_LOOP_FILTER_CTRL, + AD9523_PLL2_LOOP_FILTER_CPOLE1(pdata->cpole1) | + AD9523_PLL2_LOOP_FILTER_RZERO(pdata->rzero) | + AD9523_PLL2_LOOP_FILTER_RPOLE2(pdata->rpole2) | + AD_IF(rzero_bypass_en, + AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN)); + if (ret < 0) + return ret; + + for (i = 0; i < pdata->num_channels; i++) { + chan = &pdata->channels[i]; + if (chan->channel_num < AD9523_NUM_CHAN) { + __set_bit(chan->channel_num, &active_mask); + ret = ad9523_write(indio_dev, + AD9523_CHANNEL_CLOCK_DIST(chan->channel_num), + AD9523_CLK_DIST_DRIVER_MODE(chan->driver_mode) | + AD9523_CLK_DIST_DIV(chan->channel_divider) | + AD9523_CLK_DIST_DIV_PHASE(chan->divider_phase) | + (chan->sync_ignore_en ? + AD9523_CLK_DIST_IGNORE_SYNC_EN : 0) | + (chan->divider_output_invert_en ? + AD9523_CLK_DIST_INV_DIV_OUTPUT_EN : 0) | + (chan->low_power_mode_en ? + AD9523_CLK_DIST_LOW_PWR_MODE_EN : 0) | + (chan->output_dis ? + AD9523_CLK_DIST_PWR_DOWN_EN : 0)); + if (ret < 0) + return ret; + + ret = ad9523_vco_out_map(indio_dev, chan->channel_num, + chan->use_alt_clock_src); + if (ret < 0) + return ret; + + st->ad9523_channels[i].type = IIO_ALTVOLTAGE; + st->ad9523_channels[i].output = 1; + st->ad9523_channels[i].indexed = 1; + st->ad9523_channels[i].channel = chan->channel_num; + st->ad9523_channels[i].extend_name = + chan->extended_name; + st->ad9523_channels[i].info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_PHASE_SEPARATE_BIT | + IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT; + } + } + + for_each_clear_bit(i, &active_mask, AD9523_NUM_CHAN) + ad9523_write(indio_dev, + AD9523_CHANNEL_CLOCK_DIST(i), + AD9523_CLK_DIST_DRIVER_MODE(TRISTATE) | + AD9523_CLK_DIST_PWR_DOWN_EN); + + ret = ad9523_write(indio_dev, AD9523_POWER_DOWN_CTRL, 0); + if (ret < 0) + return ret; + + ret = ad9523_write(indio_dev, AD9523_STATUS_SIGNALS, + AD9523_STATUS_MONITOR_01_PLL12_LOCKED); + if (ret < 0) + return ret; + + ret = ad9523_io_update(indio_dev); + if (ret < 0) + return ret; + + return 0; +} + +static int __devinit ad9523_probe(struct spi_device *spi) +{ + struct ad9523_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct ad9523_state *st; + int ret; + + if (!pdata) { + dev_err(&spi->dev, "no platform data?\n"); + return -EINVAL; + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + st->pdata = pdata; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = (pdata->name[0] != 0) ? pdata->name : + spi_get_device_id(spi)->name; + indio_dev->info = &ad9523_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->ad9523_channels; + indio_dev->num_channels = pdata->num_channels; + + ret = ad9523_setup(indio_dev); + if (ret < 0) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_disable_reg; + + dev_info(&spi->dev, "probed %s\n", indio_dev->name); + + return 0; + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad9523_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad9523_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad9523_id[] = { + {"ad9523-1", 9523}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9523_id); + +static struct spi_driver ad9523_driver = { + .driver = { + .name = "ad9523", + .owner = THIS_MODULE, + }, + .probe = ad9523_probe, + .remove = __devexit_p(ad9523_remove), + .id_table = ad9523_id, +}; +module_spi_driver(ad9523_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9523 CLOCKDIST/PLL"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/frequency/ad9523.h b/include/linux/iio/frequency/ad9523.h new file mode 100644 index 000000000000..12ce3ee427fd --- /dev/null +++ b/include/linux/iio/frequency/ad9523.h @@ -0,0 +1,195 @@ +/* + * AD9523 SPI Low Jitter Clock Generator + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_FREQUENCY_AD9523_H_ +#define IIO_FREQUENCY_AD9523_H_ + +enum outp_drv_mode { + TRISTATE, + LVPECL_8mA, + LVDS_4mA, + LVDS_7mA, + HSTL0_16mA, + HSTL1_8mA, + CMOS_CONF1, + CMOS_CONF2, + CMOS_CONF3, + CMOS_CONF4, + CMOS_CONF5, + CMOS_CONF6, + CMOS_CONF7, + CMOS_CONF8, + CMOS_CONF9 +}; + +enum ref_sel_mode { + NONEREVERTIVE_STAY_ON_REFB, + REVERT_TO_REFA, + SELECT_REFA, + SELECT_REFB, + EXT_REF_SEL +}; + +/** + * struct ad9523_channel_spec - Output channel configuration + * + * @channel_num: Output channel number. + * @divider_output_invert_en: Invert the polarity of the output clock. + * @sync_ignore_en: Ignore chip-level SYNC signal. + * @low_power_mode_en: Reduce power used in the differential output modes. + * @use_alt_clock_src: Channel divider uses alternative clk source. + * @output_dis: Disables, powers down the entire channel. + * @driver_mode: Output driver mode (logic level family). + * @divider_phase: Divider initial phase after a SYNC. Range 0..63 + LSB = 1/2 of a period of the divider input clock. + * @channel_divider: 10-bit channel divider. + * @extended_name: Optional descriptive channel name. + */ + +struct ad9523_channel_spec { + unsigned channel_num; + bool divider_output_invert_en; + bool sync_ignore_en; + bool low_power_mode_en; + /* CH0..CH3 VCXO, CH4..CH9 VCO2 */ + bool use_alt_clock_src; + bool output_dis; + enum outp_drv_mode driver_mode; + unsigned char divider_phase; + unsigned short channel_divider; + char extended_name[16]; +}; + +enum pll1_rzero_resistor { + RZERO_883_OHM, + RZERO_677_OHM, + RZERO_341_OHM, + RZERO_135_OHM, + RZERO_10_OHM, + RZERO_USE_EXT_RES = 8, +}; + +enum rpole2_resistor { + RPOLE2_900_OHM, + RPOLE2_450_OHM, + RPOLE2_300_OHM, + RPOLE2_225_OHM, +}; + +enum rzero_resistor { + RZERO_3250_OHM, + RZERO_2750_OHM, + RZERO_2250_OHM, + RZERO_2100_OHM, + RZERO_3000_OHM, + RZERO_2500_OHM, + RZERO_2000_OHM, + RZERO_1850_OHM, +}; + +enum cpole1_capacitor { + CPOLE1_0_PF, + CPOLE1_8_PF, + CPOLE1_16_PF, + CPOLE1_24_PF, + _CPOLE1_24_PF, /* place holder */ + CPOLE1_32_PF, + CPOLE1_40_PF, + CPOLE1_48_PF, +}; + +/** + * struct ad9523_platform_data - platform specific information + * + * @vcxo_freq: External VCXO frequency in Hz + * @refa_diff_rcv_en: REFA differential/single-ended input selection. + * @refb_diff_rcv_en: REFB differential/single-ended input selection. + * @zd_in_diff_en: Zero Delay differential/single-ended input selection. + * @osc_in_diff_en: OSC differential/ single-ended input selection. + * @refa_cmos_neg_inp_en: REFA single-ended neg./pos. input enable. + * @refb_cmos_neg_inp_en: REFB single-ended neg./pos. input enable. + * @zd_in_cmos_neg_inp_en: Zero Delay single-ended neg./pos. input enable. + * @osc_in_cmos_neg_inp_en: OSC single-ended neg./pos. input enable. + * @refa_r_div: PLL1 10-bit REFA R divider. + * @refb_r_div: PLL1 10-bit REFB R divider. + * @pll1_feedback_div: PLL1 10-bit Feedback N divider. + * @pll1_charge_pump_current_nA: Magnitude of PLL1 charge pump current (nA). + * @zero_delay_mode_internal_en: Internal, external Zero Delay mode selection. + * @osc_in_feedback_en: PLL1 feedback path, local feedback from + * the OSC_IN receiver or zero delay mode + * @pll1_loop_filter_rzero: PLL1 Loop Filter Zero Resistor selection. + * @ref_mode: Reference selection mode. + * @pll2_charge_pump_current_nA: Magnitude of PLL2 charge pump current (nA). + * @pll2_ndiv_a_cnt: PLL2 Feedback N-divider, A Counter, range 0..4. + * @pll2_ndiv_b_cnt: PLL2 Feedback N-divider, B Counter, range 0..63. + * @pll2_freq_doubler_en: PLL2 frequency doubler enable. + * @pll2_r2_div: PLL2 R2 divider, range 0..31. + * @pll2_vco_diff_m1: VCO1 divider, range 3..5. + * @pll2_vco_diff_m2: VCO2 divider, range 3..5. + * @rpole2: PLL2 loop filter Rpole resistor value. + * @rzero: PLL2 loop filter Rzero resistor value. + * @cpole1: PLL2 loop filter Cpole capacitor value. + * @rzero_bypass_en: PLL2 loop filter Rzero bypass enable. + * @num_channels: Array size of struct ad9523_channel_spec. + * @channels: Pointer to channel array. + * @name: Optional alternative iio device name. + */ + +struct ad9523_platform_data { + unsigned long vcxo_freq; + + /* Differential/ Single-Ended Input Configuration */ + bool refa_diff_rcv_en; + bool refb_diff_rcv_en; + bool zd_in_diff_en; + bool osc_in_diff_en; + + /* + * Valid if differential input disabled + * if false defaults to pos input + */ + bool refa_cmos_neg_inp_en; + bool refb_cmos_neg_inp_en; + bool zd_in_cmos_neg_inp_en; + bool osc_in_cmos_neg_inp_en; + + /* PLL1 Setting */ + unsigned short refa_r_div; + unsigned short refb_r_div; + unsigned short pll1_feedback_div; + unsigned short pll1_charge_pump_current_nA; + bool zero_delay_mode_internal_en; + bool osc_in_feedback_en; + enum pll1_rzero_resistor pll1_loop_filter_rzero; + + /* Reference */ + enum ref_sel_mode ref_mode; + + /* PLL2 Setting */ + unsigned int pll2_charge_pump_current_nA; + unsigned char pll2_ndiv_a_cnt; + unsigned char pll2_ndiv_b_cnt; + bool pll2_freq_doubler_en; + unsigned char pll2_r2_div; + unsigned char pll2_vco_diff_m1; /* 3..5 */ + unsigned char pll2_vco_diff_m2; /* 3..5 */ + + /* Loop Filter PLL2 */ + enum rpole2_resistor rpole2; + enum rzero_resistor rzero; + enum cpole1_capacitor cpole1; + bool rzero_bypass_en; + + /* Output Channel Configuration */ + int num_channels; + struct ad9523_channel_spec *channels; + + char name[SPI_NAME_SIZE]; +}; + +#endif /* IIO_FREQUENCY_AD9523_H_ */ -- GitLab From e31166f0fd48478866ee9661c36789126435ebe8 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 29 May 2012 12:41:20 +0200 Subject: [PATCH 0450/6849] iio: frequency: New driver for Analog Devices ADF4350/ADF4351 Wideband Synthesizers Changes since V1: Apply Jonathan's review feedback: Introduce and use IIO_ALTVOLTAGE. Fix up comments and documentation. Remove dead code. Reorder some code fragments. Add missing iio_device_free. Convert to new API. Fix-up out of staging includes. Removed pll_locked attribute. Changes since V2: Use module_spi_driver. adf4350_remove: move gpio_free after regulator. target patch to drivers/iio Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../testing/sysfs-bus-iio-frequency-adf4350 | 21 + drivers/iio/frequency/Kconfig | 18 + drivers/iio/frequency/Makefile | 1 + drivers/iio/frequency/adf4350.c | 478 ++++++++++++++++++ include/linux/iio/frequency/adf4350.h | 126 +++++ 5 files changed, 644 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 create mode 100644 drivers/iio/frequency/adf4350.c create mode 100644 include/linux/iio/frequency/adf4350.h diff --git a/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 new file mode 100644 index 000000000000..d89aded01c5a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 @@ -0,0 +1,21 @@ +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency_resolution +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Stores channel Y frequency resolution/channel spacing in Hz. + The value given directly influences the MODULUS used by + the fractional-N PLL. It is assumed that the algorithm + that is used to compute the various dividers, is able to + generate proper values for multiples of channel spacing. + +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_refin_frequency +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Sets channel Y REFin frequency in Hz. In some clock chained + applications, the reference frequency used by the PLL may + change during runtime. This attribute allows the user to + adjust the reference frequency accordingly. + The value written has no effect until out_altvoltageY_frequency + is updated. Consider to use out_altvoltageY_powerdown to power + down the PLL and it's RFOut buffers during REFin changes. diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index 0458c92464a3..6aaa33ef4544 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -19,5 +19,23 @@ config AD9523 To compile this driver as a module, choose M here: the module will be called ad9523. +endmenu + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# + +menu "Phase-Locked Loop (PLL) frequency synthesizers" + +config ADF4350 + tristate "Analog Devices ADF4350/ADF4351 Wideband Synthesizers" + depends on SPI + help + Say yes here to build support for Analog Devices ADF4350/ADF4351 + Wideband Synthesizers. The driver provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called adf4350. + endmenu endmenu diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile index 1b5b22417da1..00d26e5d1dc2 100644 --- a/drivers/iio/frequency/Makefile +++ b/drivers/iio/frequency/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_AD9523) += ad9523.o +obj-$(CONFIG_ADF4350) += adf4350.o diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c new file mode 100644 index 000000000000..fd4c8501aba9 --- /dev/null +++ b/drivers/iio/frequency/adf4350.c @@ -0,0 +1,478 @@ +/* + * ADF4350/ADF4351 SPI Wideband Synthesizer driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +enum { + ADF4350_FREQ, + ADF4350_FREQ_REFIN, + ADF4350_FREQ_RESOLUTION, + ADF4350_PWRDOWN, +}; + +struct adf4350_state { + struct spi_device *spi; + struct regulator *reg; + struct adf4350_platform_data *pdata; + unsigned long clkin; + unsigned long chspc; /* Channel Spacing */ + unsigned long fpfd; /* Phase Frequency Detector */ + unsigned long min_out_freq; + unsigned r0_fract; + unsigned r0_int; + unsigned r1_mod; + unsigned r4_rf_div_sel; + unsigned long regs[6]; + unsigned long regs_hw[6]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __be32 val ____cacheline_aligned; +}; + +static struct adf4350_platform_data default_pdata = { + .clkin = 122880000, + .channel_spacing = 10000, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), + .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), + .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | + ADF4350_REG4_MUTE_TILL_LOCK_EN, + .gpio_lock_detect = -1, +}; + +static int adf4350_sync_config(struct adf4350_state *st) +{ + int ret, i, doublebuf = 0; + + for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) { + if ((st->regs_hw[i] != st->regs[i]) || + ((i == ADF4350_REG0) && doublebuf)) { + + switch (i) { + case ADF4350_REG1: + case ADF4350_REG4: + doublebuf = 1; + break; + } + + st->val = cpu_to_be32(st->regs[i] | i); + ret = spi_write(st->spi, &st->val, 4); + if (ret < 0) + return ret; + st->regs_hw[i] = st->regs[i]; + dev_dbg(&st->spi->dev, "[%d] 0x%X\n", + i, (u32)st->regs[i] | i); + } + } + return 0; +} + +static int adf4350_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct adf4350_state *st = iio_priv(indio_dev); + int ret; + + if (reg > ADF4350_REG5) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + if (readval == NULL) { + st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2)); + ret = adf4350_sync_config(st); + } else { + *readval = st->regs_hw[reg]; + ret = 0; + } + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int adf4350_tune_r_cnt(struct adf4350_state *st, unsigned short r_cnt) +{ + struct adf4350_platform_data *pdata = st->pdata; + + do { + r_cnt++; + st->fpfd = (st->clkin * (pdata->ref_doubler_en ? 2 : 1)) / + (r_cnt * (pdata->ref_div2_en ? 2 : 1)); + } while (st->fpfd > ADF4350_MAX_FREQ_PFD); + + return r_cnt; +} + +static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) +{ + struct adf4350_platform_data *pdata = st->pdata; + u64 tmp; + u32 div_gcd, prescaler; + u16 mdiv, r_cnt = 0; + u8 band_sel_div; + + if (freq > ADF4350_MAX_OUT_FREQ || freq < st->min_out_freq) + return -EINVAL; + + if (freq > ADF4350_MAX_FREQ_45_PRESC) { + prescaler = ADF4350_REG1_PRESCALER; + mdiv = 75; + } else { + prescaler = 0; + mdiv = 23; + } + + st->r4_rf_div_sel = 0; + + while (freq < ADF4350_MIN_VCO_FREQ) { + freq <<= 1; + st->r4_rf_div_sel++; + } + + /* + * Allow a predefined reference division factor + * if not set, compute our own + */ + if (pdata->ref_div_factor) + r_cnt = pdata->ref_div_factor - 1; + + do { + r_cnt = adf4350_tune_r_cnt(st, r_cnt); + + st->r1_mod = st->fpfd / st->chspc; + while (st->r1_mod > ADF4350_MAX_MODULUS) { + r_cnt = adf4350_tune_r_cnt(st, r_cnt); + st->r1_mod = st->fpfd / st->chspc; + } + + tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); + do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ + st->r0_fract = do_div(tmp, st->r1_mod); + st->r0_int = tmp; + } while (mdiv > st->r0_int); + + band_sel_div = DIV_ROUND_UP(st->fpfd, ADF4350_MAX_BANDSEL_CLK); + + if (st->r0_fract && st->r1_mod) { + div_gcd = gcd(st->r1_mod, st->r0_fract); + st->r1_mod /= div_gcd; + st->r0_fract /= div_gcd; + } else { + st->r0_fract = 0; + st->r1_mod = 1; + } + + dev_dbg(&st->spi->dev, "VCO: %llu Hz, PFD %lu Hz\n" + "REF_DIV %d, R0_INT %d, R0_FRACT %d\n" + "R1_MOD %d, RF_DIV %d\nPRESCALER %s, BAND_SEL_DIV %d\n", + freq, st->fpfd, r_cnt, st->r0_int, st->r0_fract, st->r1_mod, + 1 << st->r4_rf_div_sel, prescaler ? "8/9" : "4/5", + band_sel_div); + + st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | + ADF4350_REG0_FRACT(st->r0_fract); + + st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) | + ADF4350_REG1_MOD(st->r1_mod) | + prescaler; + + st->regs[ADF4350_REG2] = + ADF4350_REG2_10BIT_R_CNT(r_cnt) | + ADF4350_REG2_DOUBLE_BUFF_EN | + (pdata->ref_doubler_en ? ADF4350_REG2_RMULT2_EN : 0) | + (pdata->ref_div2_en ? ADF4350_REG2_RDIV2_EN : 0) | + (pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS | + ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N | + ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) | + ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9))); + + st->regs[ADF4350_REG3] = pdata->r3_user_settings & + (ADF4350_REG3_12BIT_CLKDIV(0xFFF) | + ADF4350_REG3_12BIT_CLKDIV_MODE(0x3) | + ADF4350_REG3_12BIT_CSR_EN | + ADF4351_REG3_CHARGE_CANCELLATION_EN | + ADF4351_REG3_ANTI_BACKLASH_3ns_EN | + ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH); + + st->regs[ADF4350_REG4] = + ADF4350_REG4_FEEDBACK_FUND | + ADF4350_REG4_RF_DIV_SEL(st->r4_rf_div_sel) | + ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(band_sel_div) | + ADF4350_REG4_RF_OUT_EN | + (pdata->r4_user_settings & + (ADF4350_REG4_OUTPUT_PWR(0x3) | + ADF4350_REG4_AUX_OUTPUT_PWR(0x3) | + ADF4350_REG4_AUX_OUTPUT_EN | + ADF4350_REG4_AUX_OUTPUT_FUND | + ADF4350_REG4_MUTE_TILL_LOCK_EN)); + + st->regs[ADF4350_REG5] = ADF4350_REG5_LD_PIN_MODE_DIGITAL; + + return adf4350_sync_config(st); +} + +static ssize_t adf4350_write(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct adf4350_state *st = iio_priv(indio_dev); + unsigned long long readin; + int ret; + + ret = kstrtoull(buf, 10, &readin); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + switch ((u32)private) { + case ADF4350_FREQ: + ret = adf4350_set_freq(st, readin); + break; + case ADF4350_FREQ_REFIN: + if (readin > ADF4350_MAX_FREQ_REFIN) + ret = -EINVAL; + else + st->clkin = readin; + break; + case ADF4350_FREQ_RESOLUTION: + if (readin == 0) + ret = -EINVAL; + else + st->chspc = readin; + break; + case ADF4350_PWRDOWN: + if (readin) + st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; + else + st->regs[ADF4350_REG2] &= ~ADF4350_REG2_POWER_DOWN_EN; + + adf4350_sync_config(st); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t adf4350_read(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct adf4350_state *st = iio_priv(indio_dev); + unsigned long long val; + int ret = 0; + + mutex_lock(&indio_dev->mlock); + switch ((u32)private) { + case ADF4350_FREQ: + val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) * + (u64)st->fpfd; + do_div(val, st->r1_mod * (1 << st->r4_rf_div_sel)); + /* PLL unlocked? return error */ + if (gpio_is_valid(st->pdata->gpio_lock_detect)) + if (!gpio_get_value(st->pdata->gpio_lock_detect)) { + dev_dbg(&st->spi->dev, "PLL un-locked\n"); + ret = -EBUSY; + } + break; + case ADF4350_FREQ_REFIN: + val = st->clkin; + break; + case ADF4350_FREQ_RESOLUTION: + val = st->chspc; + break; + case ADF4350_PWRDOWN: + val = !!(st->regs[ADF4350_REG2] & ADF4350_REG2_POWER_DOWN_EN); + break; + } + mutex_unlock(&indio_dev->mlock); + + return ret < 0 ? ret : sprintf(buf, "%llu\n", val); +} + +#define _ADF4350_EXT_INFO(_name, _ident) { \ + .name = _name, \ + .read = adf4350_read, \ + .write = adf4350_write, \ + .private = _ident, \ +} + +static const struct iio_chan_spec_ext_info adf4350_ext_info[] = { + /* Ideally we use IIO_CHAN_INFO_FREQUENCY, but there are + * values > 2^32 in order to support the entire frequency range + * in Hz. Using scale is a bit ugly. + */ + _ADF4350_EXT_INFO("frequency", ADF4350_FREQ), + _ADF4350_EXT_INFO("frequency_resolution", ADF4350_FREQ_RESOLUTION), + _ADF4350_EXT_INFO("refin_frequency", ADF4350_FREQ_REFIN), + _ADF4350_EXT_INFO("powerdown", ADF4350_PWRDOWN), + { }, +}; + +static const struct iio_chan_spec adf4350_chan = { + .type = IIO_ALTVOLTAGE, + .indexed = 1, + .output = 1, + .ext_info = adf4350_ext_info, +}; + +static const struct iio_info adf4350_info = { + .debugfs_reg_access = &adf4350_reg_access, + .driver_module = THIS_MODULE, +}; + +static int __devinit adf4350_probe(struct spi_device *spi) +{ + struct adf4350_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct adf4350_state *st; + int ret; + + if (!pdata) { + dev_warn(&spi->dev, "no platform data? using default\n"); + + pdata = &default_pdata; + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + st->pdata = pdata; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = (pdata->name[0] != 0) ? pdata->name : + spi_get_device_id(spi)->name; + + indio_dev->info = &adf4350_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = &adf4350_chan; + indio_dev->num_channels = 1; + + st->chspc = pdata->channel_spacing; + st->clkin = pdata->clkin; + + st->min_out_freq = spi_get_device_id(spi)->driver_data == 4351 ? + ADF4351_MIN_OUT_FREQ : ADF4350_MIN_OUT_FREQ; + + memset(st->regs_hw, 0xFF, sizeof(st->regs_hw)); + + if (gpio_is_valid(pdata->gpio_lock_detect)) { + ret = gpio_request(pdata->gpio_lock_detect, indio_dev->name); + if (ret) { + dev_err(&spi->dev, "fail to request lock detect GPIO-%d", + pdata->gpio_lock_detect); + goto error_disable_reg; + } + gpio_direction_input(pdata->gpio_lock_detect); + } + + if (pdata->power_up_frequency) { + ret = adf4350_set_freq(st, pdata->power_up_frequency); + if (ret) + goto error_free_gpio; + } + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_gpio; + + return 0; + +error_free_gpio: + if (gpio_is_valid(pdata->gpio_lock_detect)) + gpio_free(pdata->gpio_lock_detect); + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit adf4350_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adf4350_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; + adf4350_sync_config(st); + + iio_device_unregister(indio_dev); + + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + + if (gpio_is_valid(st->pdata->gpio_lock_detect)) + gpio_free(st->pdata->gpio_lock_detect); + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id adf4350_id[] = { + {"adf4350", 4350}, + {"adf4351", 4351}, + {} +}; + +static struct spi_driver adf4350_driver = { + .driver = { + .name = "adf4350", + .owner = THIS_MODULE, + }, + .probe = adf4350_probe, + .remove = __devexit_p(adf4350_remove), + .id_table = adf4350_id, +}; +module_spi_driver(adf4350_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices ADF4350/ADF4351 PLL"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h new file mode 100644 index 000000000000..b76b4a87065e --- /dev/null +++ b/include/linux/iio/frequency/adf4350.h @@ -0,0 +1,126 @@ +/* + * ADF4350/ADF4351 SPI PLL driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_PLL_ADF4350_H_ +#define IIO_PLL_ADF4350_H_ + +/* Registers */ +#define ADF4350_REG0 0 +#define ADF4350_REG1 1 +#define ADF4350_REG2 2 +#define ADF4350_REG3 3 +#define ADF4350_REG4 4 +#define ADF4350_REG5 5 + +/* REG0 Bit Definitions */ +#define ADF4350_REG0_FRACT(x) (((x) & 0xFFF) << 3) +#define ADF4350_REG0_INT(x) (((x) & 0xFFFF) << 15) + +/* REG1 Bit Definitions */ +#define ADF4350_REG1_MOD(x) (((x) & 0xFFF) << 3) +#define ADF4350_REG1_PHASE(x) (((x) & 0xFFF) << 15) +#define ADF4350_REG1_PRESCALER (1 << 27) + +/* REG2 Bit Definitions */ +#define ADF4350_REG2_COUNTER_RESET_EN (1 << 3) +#define ADF4350_REG2_CP_THREESTATE_EN (1 << 4) +#define ADF4350_REG2_POWER_DOWN_EN (1 << 5) +#define ADF4350_REG2_PD_POLARITY_POS (1 << 6) +#define ADF4350_REG2_LDP_6ns (1 << 7) +#define ADF4350_REG2_LDP_10ns (0 << 7) +#define ADF4350_REG2_LDF_FRACT_N (0 << 8) +#define ADF4350_REG2_LDF_INT_N (1 << 8) +#define ADF4350_REG2_CHARGE_PUMP_CURR_uA(x) (((((x)-312) / 312) & 0xF) << 9) +#define ADF4350_REG2_DOUBLE_BUFF_EN (1 << 13) +#define ADF4350_REG2_10BIT_R_CNT(x) ((x) << 14) +#define ADF4350_REG2_RDIV2_EN (1 << 24) +#define ADF4350_REG2_RMULT2_EN (1 << 25) +#define ADF4350_REG2_MUXOUT(x) ((x) << 26) +#define ADF4350_REG2_NOISE_MODE(x) ((x) << 29) +#define ADF4350_MUXOUT_THREESTATE 0 +#define ADF4350_MUXOUT_DVDD 1 +#define ADF4350_MUXOUT_GND 2 +#define ADF4350_MUXOUT_R_DIV_OUT 3 +#define ADF4350_MUXOUT_N_DIV_OUT 4 +#define ADF4350_MUXOUT_ANALOG_LOCK_DETECT 5 +#define ADF4350_MUXOUT_DIGITAL_LOCK_DETECT 6 + +/* REG3 Bit Definitions */ +#define ADF4350_REG3_12BIT_CLKDIV(x) ((x) << 3) +#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 16) +#define ADF4350_REG3_12BIT_CSR_EN (1 << 18) +#define ADF4351_REG3_CHARGE_CANCELLATION_EN (1 << 21) +#define ADF4351_REG3_ANTI_BACKLASH_3ns_EN (1 << 22) +#define ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH (1 << 23) + +/* REG4 Bit Definitions */ +#define ADF4350_REG4_OUTPUT_PWR(x) ((x) << 3) +#define ADF4350_REG4_RF_OUT_EN (1 << 5) +#define ADF4350_REG4_AUX_OUTPUT_PWR(x) ((x) << 6) +#define ADF4350_REG4_AUX_OUTPUT_EN (1 << 8) +#define ADF4350_REG4_AUX_OUTPUT_FUND (1 << 9) +#define ADF4350_REG4_AUX_OUTPUT_DIV (0 << 9) +#define ADF4350_REG4_MUTE_TILL_LOCK_EN (1 << 10) +#define ADF4350_REG4_VCO_PWRDOWN_EN (1 << 11) +#define ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(x) ((x) << 12) +#define ADF4350_REG4_RF_DIV_SEL(x) ((x) << 20) +#define ADF4350_REG4_FEEDBACK_DIVIDED (0 << 23) +#define ADF4350_REG4_FEEDBACK_FUND (1 << 23) + +/* REG5 Bit Definitions */ +#define ADF4350_REG5_LD_PIN_MODE_LOW (0 << 22) +#define ADF4350_REG5_LD_PIN_MODE_DIGITAL (1 << 22) +#define ADF4350_REG5_LD_PIN_MODE_HIGH (3 << 22) + +/* Specifications */ +#define ADF4350_MAX_OUT_FREQ 4400000000ULL /* Hz */ +#define ADF4350_MIN_OUT_FREQ 137500000 /* Hz */ +#define ADF4351_MIN_OUT_FREQ 34375000 /* Hz */ +#define ADF4350_MIN_VCO_FREQ 2200000000ULL /* Hz */ +#define ADF4350_MAX_FREQ_45_PRESC 3000000000ULL /* Hz */ +#define ADF4350_MAX_FREQ_PFD 32000000 /* Hz */ +#define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */ +#define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */ +#define ADF4350_MAX_MODULUS 4095 + +/** + * struct adf4350_platform_data - platform specific information + * @name: Optional device name. + * @clkin: REFin frequency in Hz. + * @channel_spacing: Channel spacing in Hz (influences MODULUS). + * @power_up_frequency: Optional, If set in Hz the PLL tunes to the desired + * frequency on probe. + * @ref_div_factor: Optional, if set the driver skips dynamic calculation + * and uses this default value instead. + * @ref_doubler_en: Enables reference doubler. + * @ref_div2_en: Enables reference divider. + * @r2_user_settings: User defined settings for ADF4350/1 REGISTER_2. + * @r3_user_settings: User defined settings for ADF4350/1 REGISTER_3. + * @r4_user_settings: User defined settings for ADF4350/1 REGISTER_4. + * @gpio_lock_detect: Optional, if set with a valid GPIO number, + * pll lock state is tested upon read. + * If not used - set to -1. + */ + +struct adf4350_platform_data { + char name[32]; + unsigned long clkin; + unsigned long channel_spacing; + unsigned long long power_up_frequency; + + unsigned short ref_div_factor; /* 10-bit R counter */ + bool ref_doubler_en; + bool ref_div2_en; + + unsigned r2_user_settings; + unsigned r3_user_settings; + unsigned r4_user_settings; + int gpio_lock_detect; +}; + +#endif /* IIO_PLL_ADF4350_H_ */ -- GitLab From 44dd5b02530a5aaea16c1a0a9eea377407445b4a Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Jun 2012 11:34:49 +0530 Subject: [PATCH 0451/6849] staging: iio: Remove version.h header file inclusion version.h header file is no longer required. Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index c3b05a1b3ea8..040da4acc66e 100755 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include -- GitLab From e4e8b7765867e8f4705bcc18b8930edbe0e4ef3c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 10:50:02 +0200 Subject: [PATCH 0452/6849] iio: Add iio_device_get() This patch add the iio_device_get() function, which increases the reference count of a iio device. The matching function to decrease the reference count - iio_device_put() - already exists. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/iio.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 3a4f6a3ab80d..3238fa3374f7 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -438,6 +438,17 @@ static inline struct iio_dev *dev_to_iio_dev(struct device *dev) return container_of(dev, struct iio_dev, dev); } +/** + * iio_device_get() - increment reference count for the device + * @indio_dev: IIO device structure + * + * Returns: The passed IIO device + **/ +static inline struct iio_dev *iio_device_get(struct iio_dev *indio_dev) +{ + return indio_dev ? dev_to_iio_dev(get_device(&indio_dev->dev)) : NULL; +} + /* Can we make this smaller? */ #define IIO_ALIGN L1_CACHE_BYTES /** -- GitLab From 1875ffd218ddafd78f0f8e78198c137cef97fd8a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 10:50:03 +0200 Subject: [PATCH 0453/6849] iio:inkern: Use iio_device_{get,put} Use iio_device_get and iio_device_put instead of open-coding it. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/iio/inkern.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 922645893dc8..d4760bd1e9b1 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -125,7 +125,7 @@ struct iio_channel *iio_st_channel_get(const char *name, strcmp(channel_name, c_i->map->consumer_channel) != 0)) continue; c = c_i; - get_device(&c->indio_dev->dev); + iio_device_get(c->indio_dev); break; } mutex_unlock(&iio_map_list_lock); @@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(iio_st_channel_get); void iio_st_channel_release(struct iio_channel *channel) { - put_device(&channel->indio_dev->dev); + iio_device_put(channel->indio_dev); kfree(channel); } EXPORT_SYMBOL_GPL(iio_st_channel_release); @@ -195,10 +195,10 @@ struct iio_channel *iio_st_channel_get_all(const char *name) c->map->adc_channel_label); if (chans[mapind].channel == NULL) { ret = -EINVAL; - put_device(&chans[mapind].indio_dev->dev); + iio_device_put(chans[mapind].indio_dev); goto error_free_chans; } - get_device(&chans[mapind].indio_dev->dev); + iio_device_get(chans[mapind].indio_dev); mapind++; } mutex_unlock(&iio_map_list_lock); @@ -210,8 +210,7 @@ struct iio_channel *iio_st_channel_get_all(const char *name) error_free_chans: for (i = 0; i < nummaps; i++) - if (chans[i].indio_dev) - put_device(&chans[i].indio_dev->dev); + iio_device_put(chans[i].indio_dev); kfree(chans); error_ret: mutex_unlock(&iio_map_list_lock); @@ -225,7 +224,7 @@ void iio_st_channel_release_all(struct iio_channel *channels) struct iio_channel *chan = &channels[0]; while (chan->indio_dev) { - put_device(&chan->indio_dev->dev); + iio_device_put(chan->indio_dev); chan++; } kfree(channels); -- GitLab From 5212cc8a9d833791a7aec566db136e78951f203d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:11 +0200 Subject: [PATCH 0454/6849] iio: Add helper functions for enum style channel attributes We often have the case were we do have a enum style channel attribute. These attributes have in common that they are a list of string values which usually map in a 1-to-1 fashion to integer values. This patch implements some common helper code for implementing enum style channel attributes using extended channel attributes. The helper functions take care of converting between the string and integer values, as well providing a function for "_available" attributes which list all available enum items. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-core.c | 63 ++++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 64 +++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 1ddd8861c71b..56a3c0bc996c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -289,6 +289,69 @@ static ssize_t iio_write_channel_ext_info(struct device *dev, this_attr->c, buf, len); } +ssize_t iio_enum_available_read(struct iio_dev *indio_dev, + uintptr_t priv, const struct iio_chan_spec *chan, char *buf) +{ + const struct iio_enum *e = (const struct iio_enum *)priv; + unsigned int i; + size_t len = 0; + + if (!e->num_items) + return 0; + + for (i = 0; i < e->num_items; ++i) + len += snprintf(buf + len, PAGE_SIZE - len, "%s ", e->items[i]); + + /* replace last space with a newline */ + buf[len - 1] = '\n'; + + return len; +} +EXPORT_SYMBOL_GPL(iio_enum_available_read); + +ssize_t iio_enum_read(struct iio_dev *indio_dev, + uintptr_t priv, const struct iio_chan_spec *chan, char *buf) +{ + const struct iio_enum *e = (const struct iio_enum *)priv; + int i; + + if (!e->get) + return -EINVAL; + + i = e->get(indio_dev, chan); + if (i < 0) + return i; + else if (i >= e->num_items) + return -EINVAL; + + return sprintf(buf, "%s\n", e->items[i]); +} +EXPORT_SYMBOL_GPL(iio_enum_read); + +ssize_t iio_enum_write(struct iio_dev *indio_dev, + uintptr_t priv, const struct iio_chan_spec *chan, const char *buf, + size_t len) +{ + const struct iio_enum *e = (const struct iio_enum *)priv; + unsigned int i; + int ret; + + if (!e->set) + return -EINVAL; + + for (i = 0; i < e->num_items; i++) { + if (sysfs_streq(buf, e->items[i])) + break; + } + + if (i == e->num_items) + return -EINVAL; + + ret = e->set(indio_dev, chan, i); + return ret ? ret : len; +} +EXPORT_SYMBOL_GPL(iio_enum_write); + static ssize_t iio_read_channel_info(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 3238fa3374f7..944c63511731 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -129,6 +129,70 @@ struct iio_chan_spec_ext_info { uintptr_t private; }; +/** + * struct iio_enum - Enum channel info attribute + * items: A array of strings. + * num_items: Length of the item array. + * set: Set callback function, may be NULL. + * get: Get callback function, may be NULL. + * + * The iio_enum struct can be used to implement enum style channel attributes. + * Enum style attributes are those which have a set of strings which map to + * unsigned integer values. The IIO enum helper code takes care of mapping + * between value and string as well as generating a "_available" file which + * contains a list of all available items. The set callback will be called when + * the attribute is updated. The last parameter is the index to the newly + * activated item. The get callback will be used to query the currently active + * item and is supposed to return the index for it. + */ +struct iio_enum { + const char * const *items; + unsigned int num_items; + int (*set)(struct iio_dev *, const struct iio_chan_spec *, unsigned int); + int (*get)(struct iio_dev *, const struct iio_chan_spec *); +}; + +ssize_t iio_enum_available_read(struct iio_dev *indio_dev, + uintptr_t priv, const struct iio_chan_spec *chan, char *buf); +ssize_t iio_enum_read(struct iio_dev *indio_dev, + uintptr_t priv, const struct iio_chan_spec *chan, char *buf); +ssize_t iio_enum_write(struct iio_dev *indio_dev, + uintptr_t priv, const struct iio_chan_spec *chan, const char *buf, + size_t len); + +/** + * IIO_ENUM() - Initialize enum extended channel attribute + * @_name: Attribute name + * @_shared: Whether the attribute is shared between all channels + * @_e: Pointer to a iio_enum struct + * + * This should usually be used together with IIO_ENUM_AVAILABLE() + */ +#define IIO_ENUM(_name, _shared, _e) \ +{ \ + .name = (_name), \ + .shared = (_shared), \ + .read = iio_enum_read, \ + .write = iio_enum_write, \ + .private = (uintptr_t)(_e), \ +} + +/** + * IIO_ENUM_AVAILABLE() - Initialize enum available extended channel attribute + * @_name: Attribute name ("_available" will be appended to the name) + * @_e: Pointer to a iio_enum struct + * + * Creates a read only attribute which list all the available enum items in a + * space separated list. This should usually be used together with IIO_ENUM() + */ +#define IIO_ENUM_AVAILABLE(_name, _e) \ +{ \ + .name = (_name "_available"), \ + .shared = true, \ + .read = iio_enum_available_read, \ + .private = (uintptr_t)(_e), \ +} + /** * struct iio_chan_spec - specification of a single channel * @type: What type of measurement is the channel making. -- GitLab From 26628f6b53d1ae3610146607c0c7fcbaf403bee7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:12 +0200 Subject: [PATCH 0455/6849] staging:iio:dac:ad5064: Use iio_enum for powerdown modes This allows us to remove some boilerplate code for comparing and formatting the enum strings. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5064.c | 65 +++++++++++--------------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index 047148aa66b2..2394f05182ca 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -136,57 +136,42 @@ static int ad5064_sync_powerdown_mode(struct ad5064_state *st, return ret; } -static const char ad5064_powerdown_modes[][15] = { - [AD5064_LDAC_PWRDN_NONE] = "", - [AD5064_LDAC_PWRDN_1K] = "1kohm_to_gnd", - [AD5064_LDAC_PWRDN_100K] = "100kohm_to_gnd", - [AD5064_LDAC_PWRDN_3STATE] = "three_state", +static const char * const ad5064_powerdown_modes[] = { + "1kohm_to_gnd", + "100kohm_to_gnd", + "three_state", }; -static ssize_t ad5064_read_powerdown_mode_available(struct iio_dev *indio_dev, - uintptr_t private, const struct iio_chan_spec *chan, char *buf) -{ - return sprintf(buf, "%s %s %s\n", ad5064_powerdown_modes[1], - ad5064_powerdown_modes[2], ad5064_powerdown_modes[3]); -} - -static ssize_t ad5064_read_powerdown_mode(struct iio_dev *indio_dev, - uintptr_t private, const struct iio_chan_spec *chan, char *buf) +static int ad5064_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { struct ad5064_state *st = iio_priv(indio_dev); - return sprintf(buf, "%s\n", - ad5064_powerdown_modes[st->pwr_down_mode[chan->channel]]); + return st->pwr_down_mode[chan->channel] - 1; } -static ssize_t ad5064_write_powerdown_mode(struct iio_dev *indio_dev, - uintptr_t private, const struct iio_chan_spec *chan, const char *buf, - size_t len) +static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { struct ad5064_state *st = iio_priv(indio_dev); - unsigned int mode, i; int ret; - mode = 0; - - for (i = 1; i < ARRAY_SIZE(ad5064_powerdown_modes); ++i) { - if (sysfs_streq(buf, ad5064_powerdown_modes[i])) { - mode = i; - break; - } - } - if (mode == 0) - return -EINVAL; - mutex_lock(&indio_dev->mlock); - st->pwr_down_mode[chan->channel] = mode; + st->pwr_down_mode[chan->channel] = mode + 1; ret = ad5064_sync_powerdown_mode(st, chan->channel); mutex_unlock(&indio_dev->mlock); - return ret ? ret : len; + return ret; } +static const struct iio_enum ad5064_powerdown_mode_enum = { + .items = ad5064_powerdown_modes, + .num_items = ARRAY_SIZE(ad5064_powerdown_modes), + .get = ad5064_get_powerdown_mode, + .set = ad5064_set_powerdown_mode, +}; + static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, char *buf) { @@ -286,22 +271,14 @@ static const struct iio_info ad5064_info = { .driver_module = THIS_MODULE, }; -static struct iio_chan_spec_ext_info ad5064_ext_info[] = { +static const struct iio_chan_spec_ext_info ad5064_ext_info[] = { { .name = "powerdown", .read = ad5064_read_dac_powerdown, .write = ad5064_write_dac_powerdown, }, - { - .name = "powerdown_mode", - .read = ad5064_read_powerdown_mode, - .write = ad5064_write_powerdown_mode, - }, - { - .name = "powerdown_mode_available", - .shared = true, - .read = ad5064_read_powerdown_mode_available, - }, + IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum), { }, }; -- GitLab From 09d48aa9f67e05770c48df6437a753b9c4d4469a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:13 +0200 Subject: [PATCH 0456/6849] staging:iio:dac:ad5446: Use iio_enum for powerdown modes This allows us to remove some boilerplate code for comparing and formatting the enum strings. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5446.c | 55 +++++++++++--------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index daa65b384c13..1774f7f15d36 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -42,47 +42,34 @@ static int ad5660_write(struct ad5446_state *st, unsigned val) } static const char * const ad5446_powerdown_modes[] = { - "", "1kohm_to_gnd", "100kohm_to_gnd", "three_state" + "1kohm_to_gnd", "100kohm_to_gnd", "three_state" }; -static ssize_t ad5446_read_powerdown_mode_available(struct iio_dev *indio_dev, - uintptr_t private, const struct iio_chan_spec *chan, char *buf) -{ - return sprintf(buf, "%s %s %s\n", ad5446_powerdown_modes[1], - ad5446_powerdown_modes[2], ad5446_powerdown_modes[3]); -} - -static ssize_t ad5446_write_powerdown_mode(struct iio_dev *indio_dev, - uintptr_t private, - const struct iio_chan_spec *chan, - const char *buf, size_t len) +static int ad5446_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { struct ad5446_state *st = iio_priv(indio_dev); - int i; - - for (i = 1; i < ARRAY_SIZE(ad5446_powerdown_modes); i++) { - if (sysfs_streq(buf, ad5446_powerdown_modes[i])) { - st->pwr_down_mode = i; - break; - } - } - if (i == ARRAY_SIZE(ad5446_powerdown_modes)) - return -EINVAL; + st->pwr_down_mode = mode + 1; - return len; + return 0; } -static ssize_t ad5446_read_powerdown_mode(struct iio_dev *indio_dev, - uintptr_t private, - const struct iio_chan_spec *chan, - char *buf) +static int ad5446_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { struct ad5446_state *st = iio_priv(indio_dev); - return sprintf(buf, "%s\n", ad5446_powerdown_modes[st->pwr_down_mode]); + return st->pwr_down_mode - 1; } +static const struct iio_enum ad5446_powerdown_mode_enum = { + .items = ad5446_powerdown_modes, + .num_items = ARRAY_SIZE(ad5446_powerdown_modes), + .get = ad5446_get_powerdown_mode, + .set = ad5446_set_powerdown_mode, +}; + static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, @@ -129,15 +116,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { .name = "powerdown", .read = ad5446_read_dac_powerdown, .write = ad5446_write_dac_powerdown, - }, { - .name = "powerdown_mode", - .read = ad5446_read_powerdown_mode, - .write = ad5446_write_powerdown_mode, - }, { - .name = "powerdown_mode_available", - .shared = true, - .read = ad5446_read_powerdown_mode_available, }, + IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum), { }, }; @@ -321,6 +302,8 @@ static int __devinit ad5446_probe(struct spi_device *spi) indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; + st->pwr_down_mode = MODE_PWRDWN_1k; + if (st->chip_info->int_vref_mv) st->vref_mv = st->chip_info->int_vref_mv; else if (voltage_uv) -- GitLab From 868e0862c9f6a8bd6bf42534b80e1e7bd230bf74 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:14 +0200 Subject: [PATCH 0457/6849] staging:iio:dac:ad5380: Convert to extended channel attributes Use extended channel attributes instead of raw sysfs files for the additional channel attributes. This allows us to remove some boilerplate code. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5380.c | 250 ++++++++++++++----------------- 1 file changed, 116 insertions(+), 134 deletions(-) diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c index 370d2842190e..7a35cc6c4c67 100644 --- a/drivers/staging/iio/dac/ad5380.c +++ b/drivers/staging/iio/dac/ad5380.c @@ -81,103 +81,18 @@ enum ad5380_type { ID_AD5392_5, }; -#define AD5380_CHANNEL(_bits) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .output = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ - .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)) \ -} - -static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { - [ID_AD5380_3] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 40, - .int_vref = 1250000, - }, - [ID_AD5380_5] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 40, - .int_vref = 2500000, - }, - [ID_AD5381_3] = { - .channel_template = AD5380_CHANNEL(12), - .num_channels = 16, - .int_vref = 1250000, - }, - [ID_AD5381_5] = { - .channel_template = AD5380_CHANNEL(12), - .num_channels = 16, - .int_vref = 2500000, - }, - [ID_AD5382_3] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 32, - .int_vref = 1250000, - }, - [ID_AD5382_5] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 32, - .int_vref = 2500000, - }, - [ID_AD5383_3] = { - .channel_template = AD5380_CHANNEL(12), - .num_channels = 32, - .int_vref = 1250000, - }, - [ID_AD5383_5] = { - .channel_template = AD5380_CHANNEL(12), - .num_channels = 32, - .int_vref = 2500000, - }, - [ID_AD5390_3] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 16, - .int_vref = 1250000, - }, - [ID_AD5390_5] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 16, - .int_vref = 2500000, - }, - [ID_AD5391_3] = { - .channel_template = AD5380_CHANNEL(12), - .num_channels = 16, - .int_vref = 1250000, - }, - [ID_AD5391_5] = { - .channel_template = AD5380_CHANNEL(12), - .num_channels = 16, - .int_vref = 2500000, - }, - [ID_AD5392_3] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 8, - .int_vref = 1250000, - }, - [ID_AD5392_5] = { - .channel_template = AD5380_CHANNEL(14), - .num_channels = 8, - .int_vref = 2500000, - }, -}; - -static ssize_t ad5380_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ad5380_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); } -static ssize_t ad5380_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) +static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); bool pwr_down; int ret; @@ -200,20 +115,14 @@ static ssize_t ad5380_write_dac_powerdown(struct device *dev, return ret ? ret : len; } -static IIO_DEVICE_ATTR(out_voltage_powerdown, - S_IRUGO | S_IWUSR, - ad5380_read_dac_powerdown, - ad5380_write_dac_powerdown, 0); - -static const char ad5380_powerdown_modes[][15] = { - [0] = "100kohm_to_gnd", - [1] = "three_state", +static const char * const ad5380_powerdown_modes[] = { + "100kohm_to_gnd", + "three_state", }; -static ssize_t ad5380_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static int ad5380_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); unsigned int mode; int ret; @@ -224,49 +133,27 @@ static ssize_t ad5380_read_powerdown_mode(struct device *dev, mode = (mode >> AD5380_CTRL_PWR_DOWN_MODE_OFFSET) & 1; - return sprintf(buf, "%s\n", ad5380_powerdown_modes[mode]); + return mode; } -static ssize_t ad5380_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) +static int ad5380_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); - unsigned int i; int ret; - for (i = 0; i < ARRAY_SIZE(ad5380_powerdown_modes); ++i) { - if (sysfs_streq(buf, ad5380_powerdown_modes[i])) - break; - } - - if (i == ARRAY_SIZE(ad5380_powerdown_modes)) - return -EINVAL; - ret = regmap_update_bits(st->regmap, AD5380_REG_SF_CTRL, 1 << AD5380_CTRL_PWR_DOWN_MODE_OFFSET, - i << AD5380_CTRL_PWR_DOWN_MODE_OFFSET); + mode << AD5380_CTRL_PWR_DOWN_MODE_OFFSET); - return ret ? ret : len; + return ret; } -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, - S_IRUGO | S_IWUSR, - ad5380_read_powerdown_mode, - ad5380_write_powerdown_mode, 0); - -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "100kohm_to_gnd three_state"); - -static struct attribute *ad5380_attributes[] = { - &iio_dev_attr_out_voltage_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5380_attribute_group = { - .attrs = ad5380_attributes, +static const struct iio_enum ad5380_powerdown_mode_enum = { + .items = ad5380_powerdown_modes, + .num_items = ARRAY_SIZE(ad5380_powerdown_modes), + .get = ad5380_get_powerdown_mode, + .set = ad5380_set_powerdown_mode, }; static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan, @@ -354,10 +241,105 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad5380_info = { .read_raw = ad5380_read_raw, .write_raw = ad5380_write_raw, - .attrs = &ad5380_attribute_group, .driver_module = THIS_MODULE, }; +static struct iio_chan_spec_ext_info ad5380_ext_info[] = { + { + .name = "powerdown", + .read = ad5380_read_dac_powerdown, + .write = ad5380_write_dac_powerdown, + }, + IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum), + { }, +}; + +#define AD5380_CHANNEL(_bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)), \ + .ext_info = ad5380_ext_info, \ +} + +static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { + [ID_AD5380_3] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 40, + .int_vref = 1250000, + }, + [ID_AD5380_5] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 40, + .int_vref = 2500000, + }, + [ID_AD5381_3] = { + .channel_template = AD5380_CHANNEL(12), + .num_channels = 16, + .int_vref = 1250000, + }, + [ID_AD5381_5] = { + .channel_template = AD5380_CHANNEL(12), + .num_channels = 16, + .int_vref = 2500000, + }, + [ID_AD5382_3] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 32, + .int_vref = 1250000, + }, + [ID_AD5382_5] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 32, + .int_vref = 2500000, + }, + [ID_AD5383_3] = { + .channel_template = AD5380_CHANNEL(12), + .num_channels = 32, + .int_vref = 1250000, + }, + [ID_AD5383_5] = { + .channel_template = AD5380_CHANNEL(12), + .num_channels = 32, + .int_vref = 2500000, + }, + [ID_AD5390_3] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 16, + .int_vref = 1250000, + }, + [ID_AD5390_5] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 16, + .int_vref = 2500000, + }, + [ID_AD5391_3] = { + .channel_template = AD5380_CHANNEL(12), + .num_channels = 16, + .int_vref = 1250000, + }, + [ID_AD5391_5] = { + .channel_template = AD5380_CHANNEL(12), + .num_channels = 16, + .int_vref = 2500000, + }, + [ID_AD5392_3] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 8, + .int_vref = 1250000, + }, + [ID_AD5392_5] = { + .channel_template = AD5380_CHANNEL(14), + .num_channels = 8, + .int_vref = 2500000, + }, +}; + static int __devinit ad5380_alloc_channels(struct iio_dev *indio_dev) { struct ad5380_state *st = iio_priv(indio_dev); -- GitLab From 8d05d7773d644bbde98e27eeba0e8f6251b30d1e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:15 +0200 Subject: [PATCH 0458/6849] staging:iio:dac:ad5504: Convert to extended channel attributes Use extended channel attributes instead of raw sysfs files for the additional channel attributes. This allows us to remove some boilerplate code. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5504.c | 163 +++++++++++-------------------- 1 file changed, 58 insertions(+), 105 deletions(-) diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index 019cf15cd24a..acb1d59b2de4 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -22,24 +22,6 @@ #include "dac.h" #include "ad5504.h" -#define AD5504_CHANNEL(_chan) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .output = 1, \ - .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .address = AD5504_ADDR_DAC(_chan), \ - .scan_type = IIO_ST('u', 12, 16, 0), \ -} - -static const struct iio_chan_spec ad5504_channels[] = { - AD5504_CHANNEL(0), - AD5504_CHANNEL(1), - AD5504_CHANNEL(2), - AD5504_CHANNEL(3), -}; - static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val) { u16 tmp = cpu_to_be16(AD5504_CMD_WRITE | @@ -122,65 +104,61 @@ static int ad5504_write_raw(struct iio_dev *indio_dev, return -EINVAL; } -static ssize_t ad5504_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static const char * const ad5504_powerdown_modes[] = { + "20kohm_to_gnd", + "three_state", +}; + +static int ad5504_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); - const char mode[][14] = {"20kohm_to_gnd", "three_state"}; - - return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); + return st->pwr_down_mode; } -static ssize_t ad5504_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static int ad5504_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); - int ret; - if (sysfs_streq(buf, "20kohm_to_gnd")) - st->pwr_down_mode = AD5504_DAC_PWRDN_20K; - else if (sysfs_streq(buf, "three_state")) - st->pwr_down_mode = AD5504_DAC_PWRDN_3STATE; - else - ret = -EINVAL; + st->pwr_down_mode = mode; - return ret ? ret : len; + return 0; } -static ssize_t ad5504_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, - char *buf) +static const struct iio_enum ad5504_powerdown_mode_enum = { + .items = ad5504_powerdown_modes, + .num_items = ARRAY_SIZE(ad5504_powerdown_modes), + .get = ad5504_get_powerdown_mode, + .set = ad5504_set_powerdown_mode, +}; + +static ssize_t ad5504_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); return sprintf(buf, "%d\n", - !(st->pwr_down_mask & (1 << this_attr->address))); + !(st->pwr_down_mask & (1 << chan->channel))); } -static ssize_t ad5504_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { long readin; int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); if (ret) return ret; if (readin == 0) - st->pwr_down_mask |= (1 << this_attr->address); + st->pwr_down_mask |= (1 << chan->channel); else if (readin == 1) - st->pwr_down_mask &= ~(1 << this_attr->address); + st->pwr_down_mask &= ~(1 << chan->channel); else ret = -EINVAL; @@ -194,50 +172,6 @@ static ssize_t ad5504_write_dac_powerdown(struct device *dev, return ret ? ret : len; } -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO | - S_IWUSR, ad5504_read_powerdown_mode, - ad5504_write_powerdown_mode, 0); - -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "20kohm_to_gnd three_state"); - -#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \ - IIO_DEVICE_ATTR(out_voltage##_num##_powerdown, \ - S_IRUGO | S_IWUSR, _show, _store, _addr) -static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5504_read_dac_powerdown, - ad5504_write_dac_powerdown, 0); -static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5504_read_dac_powerdown, - ad5504_write_dac_powerdown, 1); -static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5504_read_dac_powerdown, - ad5504_write_dac_powerdown, 2); -static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5504_read_dac_powerdown, - ad5504_write_dac_powerdown, 3); - -static struct attribute *ad5504_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage1_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage2_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage3_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5504_attribute_group = { - .attrs = ad5504_attributes, -}; - -static struct attribute *ad5501_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5501_attribute_group = { - .attrs = ad5501_attributes, -}; - static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000"); static IIO_CONST_ATTR(temp0_thresh_rising_en, "1"); @@ -267,17 +201,38 @@ static irqreturn_t ad5504_event_handler(int irq, void *private) static const struct iio_info ad5504_info = { .write_raw = ad5504_write_raw, .read_raw = ad5504_read_raw, - .attrs = &ad5504_attribute_group, .event_attrs = &ad5504_ev_attribute_group, .driver_module = THIS_MODULE, }; -static const struct iio_info ad5501_info = { - .write_raw = ad5504_write_raw, - .read_raw = ad5504_read_raw, - .attrs = &ad5501_attribute_group, - .event_attrs = &ad5504_ev_attribute_group, - .driver_module = THIS_MODULE, +static const struct iio_chan_spec_ext_info ad5504_ext_info[] = { + { + .name = "powerdown", + .read = ad5504_read_dac_powerdown, + .write = ad5504_write_dac_powerdown, + }, + IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum), + { }, +}; + +#define AD5504_CHANNEL(_chan) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (_chan), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = AD5504_ADDR_DAC(_chan), \ + .scan_type = IIO_ST('u', 12, 16, 0), \ + .ext_info = ad5504_ext_info, \ +} + +static const struct iio_chan_spec ad5504_channels[] = { + AD5504_CHANNEL(0), + AD5504_CHANNEL(1), + AD5504_CHANNEL(2), + AD5504_CHANNEL(3), }; static int __devinit ad5504_probe(struct spi_device *spi) @@ -315,13 +270,11 @@ static int __devinit ad5504_probe(struct spi_device *spi) st->spi = spi; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(st->spi)->name; - if (spi_get_device_id(st->spi)->driver_data == ID_AD5501) { - indio_dev->info = &ad5501_info; + indio_dev->info = &ad5504_info; + if (spi_get_device_id(st->spi)->driver_data == ID_AD5501) indio_dev->num_channels = 1; - } else { - indio_dev->info = &ad5504_info; + else indio_dev->num_channels = 4; - } indio_dev->channels = ad5504_channels; indio_dev->modes = INDIO_DIRECT_MODE; -- GitLab From 66eb90505eaf38f3e88491eb9090cd7be7c2da03 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:16 +0200 Subject: [PATCH 0459/6849] staging:iio:dac:ad5624r: Convert to extended channel attributes Use extended channel attributes instead of raw sysfs files for the additional channel attributes. This allows us to remove some boilerplate code. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 208 +++++++++++--------------- 1 file changed, 90 insertions(+), 118 deletions(-) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 42ff644ac43e..4c95eae1f3ac 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -21,56 +21,6 @@ #include "dac.h" #include "ad5624r.h" -#define AD5624R_CHANNEL(_chan, _bits) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .output = 1, \ - .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .address = (_chan), \ - .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ -} - -#define DECLARE_AD5624R_CHANNELS(_name, _bits) \ - const struct iio_chan_spec _name##_channels[] = { \ - AD5624R_CHANNEL(0, _bits), \ - AD5624R_CHANNEL(1, _bits), \ - AD5624R_CHANNEL(2, _bits), \ - AD5624R_CHANNEL(3, _bits), \ -} - -static DECLARE_AD5624R_CHANNELS(ad5624r, 12); -static DECLARE_AD5624R_CHANNELS(ad5644r, 14); -static DECLARE_AD5624R_CHANNELS(ad5664r, 16); - -static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = { - [ID_AD5624R3] = { - .channels = ad5624r_channels, - .int_vref_mv = 1250, - }, - [ID_AD5624R5] = { - .channels = ad5624r_channels, - .int_vref_mv = 2500, - }, - [ID_AD5644R3] = { - .channels = ad5644r_channels, - .int_vref_mv = 1250, - }, - [ID_AD5644R5] = { - .channels = ad5644r_channels, - .int_vref_mv = 2500, - }, - [ID_AD5664R3] = { - .channels = ad5664r_channels, - .int_vref_mv = 1250, - }, - [ID_AD5664R5] = { - .channels = ad5664r_channels, - .int_vref_mv = 2500, - }, -}; - static int ad5624r_spi_write(struct spi_device *spi, u8 cmd, u8 addr, u16 val, u8 len) { @@ -138,67 +88,62 @@ static int ad5624r_write_raw(struct iio_dev *indio_dev, return -EINVAL; } -static ssize_t ad5624r_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static const char * const ad5624r_powerdown_modes[] = { + "1kohm_to_gnd", + "100kohm_to_gnd", + "three_state" +}; + +static int ad5624r_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); - char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; - - return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); + return st->pwr_down_mode; } -static ssize_t ad5624r_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static int ad5624r_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); - int ret; - if (sysfs_streq(buf, "1kohm_to_gnd")) - st->pwr_down_mode = AD5624R_LDAC_PWRDN_1K; - else if (sysfs_streq(buf, "100kohm_to_gnd")) - st->pwr_down_mode = AD5624R_LDAC_PWRDN_100K; - else if (sysfs_streq(buf, "three_state")) - st->pwr_down_mode = AD5624R_LDAC_PWRDN_3STATE; - else - ret = -EINVAL; + st->pwr_down_mode = mode; - return ret ? ret : len; + return 0; } -static ssize_t ad5624r_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, - char *buf) +static const struct iio_enum ad5624r_powerdown_mode_enum = { + .items = ad5624r_powerdown_modes, + .num_items = ARRAY_SIZE(ad5624r_powerdown_modes), + .get = ad5624r_get_powerdown_mode, + .set = ad5624r_set_powerdown_mode, +}; + +static ssize_t ad5624r_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); return sprintf(buf, "%d\n", - !!(st->pwr_down_mask & (1 << this_attr->address))); + !!(st->pwr_down_mask & (1 << chan->channel))); } -static ssize_t ad5624r_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { long readin; int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); if (ret) return ret; if (readin == 1) - st->pwr_down_mask |= (1 << this_attr->address); + st->pwr_down_mask |= (1 << chan->channel); else if (!readin) - st->pwr_down_mask &= ~(1 << this_attr->address); + st->pwr_down_mask &= ~(1 << chan->channel); else ret = -EINVAL; @@ -209,47 +154,74 @@ static ssize_t ad5624r_write_dac_powerdown(struct device *dev, return ret ? ret : len; } -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO | - S_IWUSR, ad5624r_read_powerdown_mode, - ad5624r_write_powerdown_mode, 0); - -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "1kohm_to_gnd 100kohm_to_gnd three_state"); - -#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \ - IIO_DEVICE_ATTR(out_voltage##_num##_powerdown, \ - S_IRUGO | S_IWUSR, _show, _store, _addr) - -static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5624r_read_dac_powerdown, - ad5624r_write_dac_powerdown, 0); -static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5624r_read_dac_powerdown, - ad5624r_write_dac_powerdown, 1); -static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5624r_read_dac_powerdown, - ad5624r_write_dac_powerdown, 2); -static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5624r_read_dac_powerdown, - ad5624r_write_dac_powerdown, 3); - -static struct attribute *ad5624r_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage1_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage2_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage3_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5624r_attribute_group = { - .attrs = ad5624r_attributes, -}; - static const struct iio_info ad5624r_info = { .write_raw = ad5624r_write_raw, .read_raw = ad5624r_read_raw, - .attrs = &ad5624r_attribute_group, .driver_module = THIS_MODULE, }; +static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = { + { + .name = "powerdown", + .read = ad5624r_read_dac_powerdown, + .write = ad5624r_write_dac_powerdown, + }, + IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum), + { }, +}; + +#define AD5624R_CHANNEL(_chan, _bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (_chan), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = (_chan), \ + .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ + .ext_info = ad5624r_ext_info, \ +} + +#define DECLARE_AD5624R_CHANNELS(_name, _bits) \ + const struct iio_chan_spec _name##_channels[] = { \ + AD5624R_CHANNEL(0, _bits), \ + AD5624R_CHANNEL(1, _bits), \ + AD5624R_CHANNEL(2, _bits), \ + AD5624R_CHANNEL(3, _bits), \ +} + +static DECLARE_AD5624R_CHANNELS(ad5624r, 12); +static DECLARE_AD5624R_CHANNELS(ad5644r, 14); +static DECLARE_AD5624R_CHANNELS(ad5664r, 16); + +static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = { + [ID_AD5624R3] = { + .channels = ad5624r_channels, + .int_vref_mv = 1250, + }, + [ID_AD5624R5] = { + .channels = ad5624r_channels, + .int_vref_mv = 2500, + }, + [ID_AD5644R3] = { + .channels = ad5644r_channels, + .int_vref_mv = 1250, + }, + [ID_AD5644R5] = { + .channels = ad5644r_channels, + .int_vref_mv = 2500, + }, + [ID_AD5664R3] = { + .channels = ad5664r_channels, + .int_vref_mv = 1250, + }, + [ID_AD5664R5] = { + .channels = ad5664r_channels, + .int_vref_mv = 2500, + }, +}; + static int __devinit ad5624r_probe(struct spi_device *spi) { struct ad5624r_state *st; -- GitLab From fe4586a8753117a089acb54f75870d07c8e474d0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:17 +0200 Subject: [PATCH 0460/6849] staging:iio:dac:ad5686: Convert to extended channel attributes Use extended channel attributes instead of raw sysfs files for the additional channel attributes. This allows us to remove some boilerplate code. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5686.c | 196 +++++++++++++------------------ 1 file changed, 80 insertions(+), 116 deletions(-) diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index c1e903ebc7b9..f07e19721c9a 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -93,40 +93,6 @@ enum ad5686_supported_device_ids { ID_AD5685, ID_AD5686, }; -#define AD5868_CHANNEL(chan, bits, shift) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .output = 1, \ - .channel = chan, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .address = AD5686_ADDR_DAC(chan), \ - .scan_type = IIO_ST('u', bits, 16, shift) \ -} -static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { - [ID_AD5684] = { - .channel[0] = AD5868_CHANNEL(0, 12, 4), - .channel[1] = AD5868_CHANNEL(1, 12, 4), - .channel[2] = AD5868_CHANNEL(2, 12, 4), - .channel[3] = AD5868_CHANNEL(3, 12, 4), - .int_vref_mv = 2500, - }, - [ID_AD5685] = { - .channel[0] = AD5868_CHANNEL(0, 14, 2), - .channel[1] = AD5868_CHANNEL(1, 14, 2), - .channel[2] = AD5868_CHANNEL(2, 14, 2), - .channel[3] = AD5868_CHANNEL(3, 14, 2), - .int_vref_mv = 2500, - }, - [ID_AD5686] = { - .channel[0] = AD5868_CHANNEL(0, 16, 0), - .channel[1] = AD5868_CHANNEL(1, 16, 0), - .channel[2] = AD5868_CHANNEL(2, 16, 0), - .channel[3] = AD5868_CHANNEL(3, 16, 0), - .int_vref_mv = 2500, - }, -}; - static int ad5686_spi_write(struct ad5686_state *st, u8 cmd, u8 addr, u16 val, u8 shift) { @@ -170,73 +136,63 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 addr) return be32_to_cpu(st->data[2].d32); } -static ssize_t ad5686_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static const char * const ad5686_powerdown_modes[] = { + "1kohm_to_gnd", + "100kohm_to_gnd", + "three_state" +}; + +static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; - - return sprintf(buf, "%s\n", mode[(st->pwr_down_mode >> - (this_attr->address * 2)) & 0x3]); + return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1; } -static ssize_t ad5686_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - unsigned mode; - - if (sysfs_streq(buf, "1kohm_to_gnd")) - mode = AD5686_LDAC_PWRDN_1K; - else if (sysfs_streq(buf, "100kohm_to_gnd")) - mode = AD5686_LDAC_PWRDN_100K; - else if (sysfs_streq(buf, "three_state")) - mode = AD5686_LDAC_PWRDN_3STATE; - else - return -EINVAL; - st->pwr_down_mode &= ~(0x3 << (this_attr->address * 2)); - st->pwr_down_mode |= (mode << (this_attr->address * 2)); + st->pwr_down_mode &= ~(0x3 << (chan->channel * 2)); + st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2)); - return len; + return 0; } -static ssize_t ad5686_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, - char *buf) +static const struct iio_enum ad5686_powerdown_mode_enum = { + .items = ad5686_powerdown_modes, + .num_items = ARRAY_SIZE(ad5686_powerdown_modes), + .get = ad5686_get_powerdown_mode, + .set = ad5686_set_powerdown_mode, +}; + +static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); return sprintf(buf, "%d\n", !!(st->pwr_down_mask & - (0x3 << (this_attr->address * 2)))); + (0x3 << (chan->channel * 2)))); } -static ssize_t ad5686_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { bool readin; int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strtobool(buf, &readin); if (ret) return ret; if (readin == true) - st->pwr_down_mask |= (0x3 << (this_attr->address * 2)); + st->pwr_down_mask |= (0x3 << (chan->channel * 2)); else - st->pwr_down_mask &= ~(0x3 << (this_attr->address * 2)); + st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0, st->pwr_down_mask & st->pwr_down_mode, 0); @@ -244,48 +200,6 @@ static ssize_t ad5686_write_dac_powerdown(struct device *dev, return ret ? ret : len; } -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "1kohm_to_gnd 100kohm_to_gnd three_state"); - -#define IIO_DEV_ATTR_DAC_POWERDOWN_MODE(_num) \ - IIO_DEVICE_ATTR(out_voltage##_num##_powerdown_mode, \ - S_IRUGO | S_IWUSR, \ - ad5686_read_powerdown_mode, \ - ad5686_write_powerdown_mode, _num) - -static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(0); -static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(1); -static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(2); -static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(3); - -#define IIO_DEV_ATTR_DAC_POWERDOWN(_num) \ - IIO_DEVICE_ATTR(out_voltage##_num##_powerdown, \ - S_IRUGO | S_IWUSR, \ - ad5686_read_dac_powerdown, \ - ad5686_write_dac_powerdown, _num) - -static IIO_DEV_ATTR_DAC_POWERDOWN(0); -static IIO_DEV_ATTR_DAC_POWERDOWN(1); -static IIO_DEV_ATTR_DAC_POWERDOWN(2); -static IIO_DEV_ATTR_DAC_POWERDOWN(3); - -static struct attribute *ad5686_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage1_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage2_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage3_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage0_powerdown_mode.dev_attr.attr, - &iio_dev_attr_out_voltage1_powerdown_mode.dev_attr.attr, - &iio_dev_attr_out_voltage2_powerdown_mode.dev_attr.attr, - &iio_dev_attr_out_voltage3_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5686_attribute_group = { - .attrs = ad5686_attributes, -}; - static int ad5686_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, @@ -349,10 +263,57 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5686_info = { .read_raw = ad5686_read_raw, .write_raw = ad5686_write_raw, - .attrs = &ad5686_attribute_group, .driver_module = THIS_MODULE, }; +static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { + { + .name = "powerdown", + .read = ad5686_read_dac_powerdown, + .write = ad5686_write_dac_powerdown, + }, + IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum), + { }, +}; + +#define AD5868_CHANNEL(chan, bits, shift) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = chan, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = AD5686_ADDR_DAC(chan), \ + .scan_type = IIO_ST('u', bits, 16, shift), \ + .ext_info = ad5686_ext_info, \ +} + +static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { + [ID_AD5684] = { + .channel[0] = AD5868_CHANNEL(0, 12, 4), + .channel[1] = AD5868_CHANNEL(1, 12, 4), + .channel[2] = AD5868_CHANNEL(2, 12, 4), + .channel[3] = AD5868_CHANNEL(3, 12, 4), + .int_vref_mv = 2500, + }, + [ID_AD5685] = { + .channel[0] = AD5868_CHANNEL(0, 14, 2), + .channel[1] = AD5868_CHANNEL(1, 14, 2), + .channel[2] = AD5868_CHANNEL(2, 14, 2), + .channel[3] = AD5868_CHANNEL(3, 14, 2), + .int_vref_mv = 2500, + }, + [ID_AD5686] = { + .channel[0] = AD5868_CHANNEL(0, 16, 0), + .channel[1] = AD5868_CHANNEL(1, 16, 0), + .channel[2] = AD5868_CHANNEL(2, 16, 0), + .channel[3] = AD5868_CHANNEL(3, 16, 0), + .int_vref_mv = 2500, + }, +}; + + static int __devinit ad5686_probe(struct spi_device *spi) { struct ad5686_state *st; @@ -385,6 +346,9 @@ static int __devinit ad5686_probe(struct spi_device *spi) st->spi = spi; + /* Set all the power down mode for all channels to 1K pulldown */ + st->pwr_down_mode = 0x55; + indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->info = &ad5686_info; -- GitLab From 4571b39b0b08ff855707011c6f7fa04ceb43e5ca Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:18 +0200 Subject: [PATCH 0461/6849] staging:iio:dac:ad5791: Convert to extended channel attributes Use extended channel attributes instead of raw sysfs files for the additional channel attributes. This allows us to remove some boilerplate code. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5791.c | 122 ++++++++++++++----------------- 1 file changed, 53 insertions(+), 69 deletions(-) diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index 13d8b5bb1cea..ad33725dd3a4 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -72,71 +72,50 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val) return ret; } -#define AD5791_CHAN(bits, shift) { \ - .type = IIO_VOLTAGE, \ - .output = 1, \ - .indexed = 1, \ - .address = AD5791_ADDR_DAC0, \ - .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ - .scan_type = IIO_ST('u', bits, 24, shift) \ -} - -static const struct iio_chan_spec ad5791_channels[] = { - [ID_AD5760] = AD5791_CHAN(16, 4), - [ID_AD5780] = AD5791_CHAN(18, 2), - [ID_AD5781] = AD5791_CHAN(18, 2), - [ID_AD5791] = AD5791_CHAN(20, 0) +static const char * const ad5791_powerdown_modes[] = { + "6kohm_to_gnd", + "three_state", }; -static ssize_t ad5791_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); - const char mode[][14] = {"6kohm_to_gnd", "three_state"}; - - return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); + return st->pwr_down_mode; } -static ssize_t ad5791_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int mode) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); - int ret; - if (sysfs_streq(buf, "6kohm_to_gnd")) - st->pwr_down_mode = AD5791_DAC_PWRDN_6K; - else if (sysfs_streq(buf, "three_state")) - st->pwr_down_mode = AD5791_DAC_PWRDN_3STATE; - else - ret = -EINVAL; + st->pwr_down_mode = mode; - return ret ? ret : len; + return 0; } -static ssize_t ad5791_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, - char *buf) +static const struct iio_enum ad5791_powerdown_mode_enum = { + .items = ad5791_powerdown_modes, + .num_items = ARRAY_SIZE(ad5791_powerdown_modes), + .get = ad5791_get_powerdown_mode, + .set = ad5791_set_powerdown_mode, +}; + +static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); } -static ssize_t ad5791_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { long readin; int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); ret = strict_strtol(buf, 10, &readin); @@ -160,31 +139,6 @@ static ssize_t ad5791_write_dac_powerdown(struct device *dev, return ret ? ret : len; } -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO | - S_IWUSR, ad5791_read_powerdown_mode, - ad5791_write_powerdown_mode, 0); - -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "6kohm_to_gnd three_state"); - -#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \ - IIO_DEVICE_ATTR(out_voltage##_num##_powerdown, \ - S_IRUGO | S_IWUSR, _show, _store, _addr) - -static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5791_read_dac_powerdown, - ad5791_write_dac_powerdown, 0); - -static struct attribute *ad5791_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5791_attribute_group = { - .attrs = ad5791_attributes, -}; - static int ad5791_get_lin_comp(unsigned int span) { if (span <= 10000) @@ -254,6 +208,37 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, }; +static const struct iio_chan_spec_ext_info ad5791_ext_info[] = { + { + .name = "powerdown", + .shared = true, + .read = ad5791_read_dac_powerdown, + .write = ad5791_write_dac_powerdown, + }, + IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum), + { }, +}; + +#define AD5791_CHAN(bits, shift) { \ + .type = IIO_VOLTAGE, \ + .output = 1, \ + .indexed = 1, \ + .address = AD5791_ADDR_DAC0, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ + .scan_type = IIO_ST('u', bits, 24, shift), \ + .ext_info = ad5791_ext_info, \ +} + +static const struct iio_chan_spec ad5791_channels[] = { + [ID_AD5760] = AD5791_CHAN(16, 4), + [ID_AD5780] = AD5791_CHAN(18, 2), + [ID_AD5781] = AD5791_CHAN(18, 2), + [ID_AD5791] = AD5791_CHAN(20, 0) +}; static int ad5791_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -278,7 +263,6 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5791_info = { .read_raw = &ad5791_read_raw, .write_raw = &ad5791_write_raw, - .attrs = &ad5791_attribute_group, .driver_module = THIS_MODULE, }; -- GitLab From cadb695113f6f30b0a19a0437dbcf000e1d3419a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:19 +0200 Subject: [PATCH 0462/6849] staging:iio:dac: Remove unused dac.h includes None of these drivers use anything from dac.h, so remove the include. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5064.c | 1 - drivers/staging/iio/dac/ad5360.c | 1 - drivers/staging/iio/dac/ad5380.c | 2 -- drivers/staging/iio/dac/ad5421.c | 1 - drivers/staging/iio/dac/ad5446.c | 1 - drivers/staging/iio/dac/ad5504.c | 2 +- drivers/staging/iio/dac/ad5624r_spi.c | 2 +- drivers/staging/iio/dac/ad5686.c | 1 - drivers/staging/iio/dac/ad5764.c | 1 - drivers/staging/iio/dac/ad5791.c | 2 +- 10 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index 2394f05182ca..276af02520af 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -18,7 +18,6 @@ #include #include -#include "dac.h" #define AD5064_MAX_DAC_CHANNELS 8 #define AD5064_MAX_VREFS 4 diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c index 38660efca78a..8fce84fe70b1 100644 --- a/drivers/staging/iio/dac/ad5360.c +++ b/drivers/staging/iio/dac/ad5360.c @@ -18,7 +18,6 @@ #include #include -#include "dac.h" #define AD5360_CMD(x) ((x) << 22) #define AD5360_ADDR(x) ((x) << 16) diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c index 7a35cc6c4c67..5dfb4451728f 100644 --- a/drivers/staging/iio/dac/ad5380.c +++ b/drivers/staging/iio/dac/ad5380.c @@ -20,8 +20,6 @@ #include #include -#include "dac.h" - #define AD5380_REG_DATA(x) (((x) << 2) | 3) #define AD5380_REG_OFFSET(x) (((x) << 2) | 2) diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c index ffbd4c234f57..ea2f83b4e357 100644 --- a/drivers/staging/iio/dac/ad5421.c +++ b/drivers/staging/iio/dac/ad5421.c @@ -19,7 +19,6 @@ #include #include #include -#include "dac.h" #include "ad5421.h" diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 1774f7f15d36..49f557fc673b 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -20,7 +20,6 @@ #include #include -#include "dac.h" #include "ad5446.h" diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index acb1d59b2de4..331b536ec8aa 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -19,7 +19,7 @@ #include #include #include -#include "dac.h" + #include "ad5504.h" static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 4c95eae1f3ac..7524f96b8e52 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -18,7 +18,7 @@ #include #include -#include "dac.h" + #include "ad5624r.h" static int ad5624r_spi_write(struct spi_device *spi, diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index f07e19721c9a..6948d75e1036 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -18,7 +18,6 @@ #include #include -#include "dac.h" #define AD5686_DAC_CHANNELS 4 diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c index 03dbd937b081..ffce30447445 100644 --- a/drivers/staging/iio/dac/ad5764.c +++ b/drivers/staging/iio/dac/ad5764.c @@ -18,7 +18,6 @@ #include #include -#include "dac.h" #define AD5764_REG_SF_NOP 0x0 #define AD5764_REG_SF_CONFIG 0x1 diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index ad33725dd3a4..4e955ed9451d 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -19,7 +19,7 @@ #include #include -#include "dac.h" + #include "ad5791.h" static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val) -- GitLab From 4cd8d87446d521b7824aa1be84d767c8b5300601 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:20 +0200 Subject: [PATCH 0463/6849] staging:iio:dac:max517: Convert to channel spec Convert the max517 driver to channel spec. As part of the conversion the "out_voltage_1&2_raw" property, which updates both channel 1 and 2 simultaneously with the same value, is lost, since this is not really covered by the IIO spec and has only a limited use case in practice. Also the channel index for the sysfs files is now zero based instead of one based, which means all channel numbers will be lower by one. E.g. "out_voltage_1_scale" instead of "out_voltage_2_scale" Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Acked-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/max517.c | 172 +++++++++++-------------------- 1 file changed, 61 insertions(+), 111 deletions(-) diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index 5287cad1f3a4..403e06fbc39e 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -27,7 +27,6 @@ #include #include -#include "dac.h" #include "max517.h" @@ -55,129 +54,67 @@ struct max517_data { * bit 1: channel 2 * (this way, it's possible to set both channels at once) */ -static ssize_t max517_set_value(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count, int channel) +static int max517_set_value(struct iio_dev *indio_dev, + long val, int channel) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct max517_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - u8 outbuf[4]; /* 1x or 2x command + value */ - int outbuf_size = 0; + u8 outbuf[2]; int res; - long val; - - res = strict_strtol(buf, 10, &val); - - if (res) - return res; if (val < 0 || val > 255) return -EINVAL; - if (channel & 1) { - outbuf[outbuf_size++] = COMMAND_CHANNEL0; - outbuf[outbuf_size++] = val; - } - if (channel & 2) { - outbuf[outbuf_size++] = COMMAND_CHANNEL1; - outbuf[outbuf_size++] = val; - } + outbuf[0] = channel; + outbuf[1] = val; - /* - * At this point, there are always 1 or 2 two-byte commands in - * outbuf. With 2 commands, the device can set two outputs - * simultaneously, latching the values upon the end of the I2C - * transfer. - */ - - res = i2c_master_send(client, outbuf, outbuf_size); + res = i2c_master_send(client, outbuf, 2); if (res < 0) return res; - - return count; -} - -static ssize_t max517_set_value_1(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return max517_set_value(dev, attr, buf, count, 1); -} -static IIO_DEV_ATTR_OUT_RAW(1, max517_set_value_1, 0); - -static ssize_t max517_set_value_2(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return max517_set_value(dev, attr, buf, count, 2); -} -static IIO_DEV_ATTR_OUT_RAW(2, max517_set_value_2, 1); - -static ssize_t max517_set_value_both(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return max517_set_value(dev, attr, buf, count, 3); + else if (res != 2) + return -EIO; + else + return 0; } -static IIO_DEVICE_ATTR_NAMED(out_voltage1and2_raw, - out_voltage1&2_raw, S_IWUSR, NULL, - max517_set_value_both, -1); -static ssize_t max517_show_scale(struct device *dev, - struct device_attribute *attr, - char *buf, int channel) +static int max517_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct max517_data *data = iio_priv(indio_dev); - /* Corresponds to Vref / 2^(bits) */ - unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8; - - return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); + unsigned int scale_uv; + + switch (m) { + case IIO_CHAN_INFO_SCALE: + /* Corresponds to Vref / 2^(bits) */ + scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8; + *val = scale_uv / 1000000; + *val2 = scale_uv % 1000000; + return IIO_VAL_INT_PLUS_MICRO; + default: + break; + } + return -EINVAL; } -static ssize_t max517_show_scale1(struct device *dev, - struct device_attribute *attr, - char *buf) +static int max517_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long mask) { - return max517_show_scale(dev, attr, buf, 1); -} -static IIO_DEVICE_ATTR(out_voltage1_scale, S_IRUGO, - max517_show_scale1, NULL, 0); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = max517_set_value(indio_dev, val, chan->channel); + break; + default: + ret = -EINVAL; + break; + } -static ssize_t max517_show_scale2(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return max517_show_scale(dev, attr, buf, 2); + return ret; } -static IIO_DEVICE_ATTR(out_voltage2_scale, S_IRUGO, - max517_show_scale2, NULL, 0); - -/* On MAX517 variant, we have one output */ -static struct attribute *max517_attributes[] = { - &iio_dev_attr_out_voltage1_raw.dev_attr.attr, - &iio_dev_attr_out_voltage1_scale.dev_attr.attr, - NULL -}; - -static struct attribute_group max517_attribute_group = { - .attrs = max517_attributes, -}; - -/* On MAX518 and MAX519 variant, we have two outputs */ -static struct attribute *max518_attributes[] = { - &iio_dev_attr_out_voltage1_raw.dev_attr.attr, - &iio_dev_attr_out_voltage1_scale.dev_attr.attr, - &iio_dev_attr_out_voltage2_raw.dev_attr.attr, - &iio_dev_attr_out_voltage2_scale.dev_attr.attr, - &iio_dev_attr_out_voltage1and2_raw.dev_attr.attr, - NULL -}; - -static struct attribute_group max518_attribute_group = { - .attrs = max518_attributes, -}; #ifdef CONFIG_PM_SLEEP static int max517_suspend(struct device *dev) @@ -201,13 +138,24 @@ static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume); #endif static const struct iio_info max517_info = { - .attrs = &max517_attribute_group, + .read_raw = max517_read_raw, + .write_raw = max517_write_raw, .driver_module = THIS_MODULE, }; -static const struct iio_info max518_info = { - .attrs = &max518_attribute_group, - .driver_module = THIS_MODULE, +#define MAX517_CHANNEL(chan) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (chan), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .scan_type = IIO_ST('u', 8, 8, 0), \ +} + +static const struct iio_chan_spec max517_channels[] = { + MAX517_CHANNEL(0), + MAX517_CHANNEL(1) }; static int max517_probe(struct i2c_client *client, @@ -230,12 +178,14 @@ static int max517_probe(struct i2c_client *client, /* establish that the iio_dev is a child of the i2c device */ indio_dev->dev.parent = &client->dev; - /* reduced attribute set for MAX517 */ + /* reduced channel set for MAX517 */ if (id->driver_data == ID_MAX517) - indio_dev->info = &max517_info; + indio_dev->num_channels = 1; else - indio_dev->info = &max518_info; + indio_dev->num_channels = 2; + indio_dev->channels = max517_channels; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &max517_info; /* * Reference voltage on MAX518 and default is 5V, else take vref_mv -- GitLab From 159fe695ae2ad53b915465f30ddd0fbc7f014900 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:21 +0200 Subject: [PATCH 0464/6849] staging:iio:dac: Remove dac.h Now that all drivers have been converted to channel spec, we can finally remove the dac.h file since it is no longer used. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/dac.h | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 drivers/staging/iio/dac/dac.h diff --git a/drivers/staging/iio/dac/dac.h b/drivers/staging/iio/dac/dac.h deleted file mode 100644 index 0754d715cf9c..000000000000 --- a/drivers/staging/iio/dac/dac.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * dac.h - sysfs attributes associated with DACs - */ - -#define IIO_DEV_ATTR_OUT_RAW(_num, _store, _addr) \ - IIO_DEVICE_ATTR(out_voltage##_num##_raw, S_IWUSR, NULL, _store, _addr) -- GitLab From 3bbbf150ffde2ca48249537d2d9e4b52bc0a5fc8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:22 +0200 Subject: [PATCH 0465/6849] staging:iio:dac:ad5504: Use strtobool for boolean values Use strtobool for parsing the powerdown value instead of strict_strtol, since the powerdown attribute is a boolean value. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5504.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index 331b536ec8aa..220150d2a165 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -147,20 +147,18 @@ static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len) { - long readin; + bool pwr_down; int ret; struct ad5504_state *st = iio_priv(indio_dev); - ret = strict_strtol(buf, 10, &readin); + ret = strtobool(buf, &pwr_down); if (ret) return ret; - if (readin == 0) + if (pwr_down) st->pwr_down_mask |= (1 << chan->channel); - else if (readin == 1) - st->pwr_down_mask &= ~(1 << chan->channel); else - ret = -EINVAL; + st->pwr_down_mask &= ~(1 << chan->channel); ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL, AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | -- GitLab From 2490594e89c7286585daeaf05a06b6cd7b5c8876 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:23 +0200 Subject: [PATCH 0466/6849] staging:iio:dac:ad5624r: Use strtobool for boolean values Use strtobool for parsing the powerdown value instead of strict_strtol, since the powerdown attribute is a boolean value. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 7524f96b8e52..6a7d6a48cc6d 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -132,20 +132,18 @@ static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len) { - long readin; + bool pwr_down; int ret; struct ad5624r_state *st = iio_priv(indio_dev); - ret = strict_strtol(buf, 10, &readin); + ret = strtobool(buf, &pwr_down); if (ret) return ret; - if (readin == 1) + if (pwr_down) st->pwr_down_mask |= (1 << chan->channel); - else if (!readin) - st->pwr_down_mask &= ~(1 << chan->channel); else - ret = -EINVAL; + st->pwr_down_mask &= ~(1 << chan->channel); ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, (st->pwr_down_mode << 4) | -- GitLab From 4468cb552536731fd85f22a367602e9242a55376 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:24 +0200 Subject: [PATCH 0467/6849] staging:iio:dac:ad5791: Use strtobool for boolean values Use strtobool for parsing the powerdown value instead of strict_strtol, since the powerdown attribute is a boolean value. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5791.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index 4e955ed9451d..82b51a7aa808 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -114,25 +114,23 @@ static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len) { - long readin; + bool pwr_down; int ret; struct ad5791_state *st = iio_priv(indio_dev); - ret = strict_strtol(buf, 10, &readin); + ret = strtobool(buf, &pwr_down); if (ret) return ret; - if (readin == 0) { - st->pwr_down = false; + if (!pwr_down) { st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); - } else if (readin == 1) { - st->pwr_down = true; + } else { if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K) st->ctrl |= AD5791_CTRL_OPGND; else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE) st->ctrl |= AD5791_CTRL_DACTRI; - } else - ret = -EINVAL; + } + st->pwr_down = pwr_down; ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl); -- GitLab From 4f0a788dc892d62fabcfd61b289b6212bdedadfd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:25 +0200 Subject: [PATCH 0468/6849] staging:iio:dac:ad5504: Check if IRQ was requested before freeing it IRQ support is optional, so we have to check whether it was actually requested before we attempt to free it. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5504.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index 220150d2a165..f3d7b47cfe1d 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -294,7 +294,8 @@ static int __devinit ad5504_probe(struct spi_device *spi) return 0; error_free_irq: - free_irq(spi->irq, indio_dev); + if (spi->irq) + free_irq(spi->irq, indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); -- GitLab From a98348b74ec2c4c5cda0f14d38ff19e08fc4e4bf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:26 +0200 Subject: [PATCH 0469/6849] staging:iio:dac:ad5504: Move private structs and defines from header to C file The header for this driver contains some private structs and defines, which do not have to be shared between multiple source files, as well as the platform data struct for this driver, which has to be shared with other source files. Since there is no need to expose those private structs and defines move them to the source file. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5504.c | 45 ++++++++++++++++++++++++++++++++ drivers/staging/iio/dac/ad5504.h | 45 -------------------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index f3d7b47cfe1d..1289e9bc1688 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -22,6 +22,51 @@ #include "ad5504.h" +#define AD5505_BITS 12 +#define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1) + +#define AD5504_CMD_READ (1 << 15) +#define AD5504_CMD_WRITE (0 << 15) +#define AD5504_ADDR(addr) ((addr) << 12) + +/* Registers */ +#define AD5504_ADDR_NOOP 0 +#define AD5504_ADDR_DAC(x) ((x) + 1) +#define AD5504_ADDR_ALL_DAC 5 +#define AD5504_ADDR_CTRL 7 + +/* Control Register */ +#define AD5504_DAC_PWR(ch) ((ch) << 2) +#define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6) +#define AD5504_DAC_PWRDN_20K 0 +#define AD5504_DAC_PWRDN_3STATE 1 + +/** + * struct ad5446_state - driver instance specific data + * @us: spi_device + * @reg: supply regulator + * @vref_mv: actual reference voltage used + * @pwr_down_mask power down mask + * @pwr_down_mode current power down mode + */ + +struct ad5504_state { + struct spi_device *spi; + struct regulator *reg; + unsigned short vref_mv; + unsigned pwr_down_mask; + unsigned pwr_down_mode; +}; + +/** + * ad5504_supported_device_ids: + */ + +enum ad5504_supported_device_ids { + ID_AD5504, + ID_AD5501, +}; + static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val) { u16 tmp = cpu_to_be16(AD5504_CMD_WRITE | diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h index afe09522f53c..d4980bf688bf 100644 --- a/drivers/staging/iio/dac/ad5504.h +++ b/drivers/staging/iio/dac/ad5504.h @@ -9,25 +9,6 @@ #ifndef SPI_AD5504_H_ #define SPI_AD5504_H_ -#define AD5505_BITS 12 -#define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1) - -#define AD5504_CMD_READ (1 << 15) -#define AD5504_CMD_WRITE (0 << 15) -#define AD5504_ADDR(addr) ((addr) << 12) - -/* Registers */ -#define AD5504_ADDR_NOOP 0 -#define AD5504_ADDR_DAC(x) ((x) + 1) -#define AD5504_ADDR_ALL_DAC 5 -#define AD5504_ADDR_CTRL 7 - -/* Control Register */ -#define AD5504_DAC_PWR(ch) ((ch) << 2) -#define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6) -#define AD5504_DAC_PWRDN_20K 0 -#define AD5504_DAC_PWRDN_3STATE 1 - /* * TODO: struct ad5504_platform_data needs to go into include/linux/iio */ @@ -36,30 +17,4 @@ struct ad5504_platform_data { u16 vref_mv; }; -/** - * struct ad5446_state - driver instance specific data - * @us: spi_device - * @reg: supply regulator - * @vref_mv: actual reference voltage used - * @pwr_down_mask power down mask - * @pwr_down_mode current power down mode - */ - -struct ad5504_state { - struct spi_device *spi; - struct regulator *reg; - unsigned short vref_mv; - unsigned pwr_down_mask; - unsigned pwr_down_mode; -}; - -/** - * ad5504_supported_device_ids: - */ - -enum ad5504_supported_device_ids { - ID_AD5504, - ID_AD5501, -}; - #endif /* SPI_AD5504_H_ */ -- GitLab From 20374d1a36df3e20cd6742ba376684e5506254a8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:27 +0200 Subject: [PATCH 0470/6849] staging:iio:dac:ad5791: Move private structs and defines from header to C file The header for this driver contains some private structs and defines, which do not have to be shared between multiple source files, as well as the platform data struct for this driver, which has to be shared with other source files. Since there is no need to expose those private structs and defines move them to the source file. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5791.c | 83 ++++++++++++++++++++++++++++++++ drivers/staging/iio/dac/ad5791.h | 83 -------------------------------- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index 82b51a7aa808..5de28c2a57ef 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -22,6 +22,89 @@ #include "ad5791.h" +#define AD5791_RES_MASK(x) ((1 << (x)) - 1) +#define AD5791_DAC_MASK AD5791_RES_MASK(20) +#define AD5791_DAC_MSB (1 << 19) + +#define AD5791_CMD_READ (1 << 23) +#define AD5791_CMD_WRITE (0 << 23) +#define AD5791_ADDR(addr) ((addr) << 20) + +/* Registers */ +#define AD5791_ADDR_NOOP 0 +#define AD5791_ADDR_DAC0 1 +#define AD5791_ADDR_CTRL 2 +#define AD5791_ADDR_CLRCODE 3 +#define AD5791_ADDR_SW_CTRL 4 + +/* Control Register */ +#define AD5791_CTRL_RBUF (1 << 1) +#define AD5791_CTRL_OPGND (1 << 2) +#define AD5791_CTRL_DACTRI (1 << 3) +#define AD5791_CTRL_BIN2SC (1 << 4) +#define AD5791_CTRL_SDODIS (1 << 5) +#define AD5761_CTRL_LINCOMP(x) ((x) << 6) + +#define AD5791_LINCOMP_0_10 0 +#define AD5791_LINCOMP_10_12 1 +#define AD5791_LINCOMP_12_16 2 +#define AD5791_LINCOMP_16_19 3 +#define AD5791_LINCOMP_19_20 12 + +#define AD5780_LINCOMP_0_10 0 +#define AD5780_LINCOMP_10_20 12 + +/* Software Control Register */ +#define AD5791_SWCTRL_LDAC (1 << 0) +#define AD5791_SWCTRL_CLR (1 << 1) +#define AD5791_SWCTRL_RESET (1 << 2) + +#define AD5791_DAC_PWRDN_6K 0 +#define AD5791_DAC_PWRDN_3STATE 1 + +/** + * struct ad5791_chip_info - chip specific information + * @get_lin_comp: function pointer to the device specific function + */ + +struct ad5791_chip_info { + int (*get_lin_comp) (unsigned int span); +}; + +/** + * struct ad5791_state - driver instance specific data + * @us: spi_device + * @reg_vdd: positive supply regulator + * @reg_vss: negative supply regulator + * @chip_info: chip model specific constants + * @vref_mv: actual reference voltage used + * @vref_neg_mv: voltage of the negative supply + * @pwr_down_mode current power down mode + */ + +struct ad5791_state { + struct spi_device *spi; + struct regulator *reg_vdd; + struct regulator *reg_vss; + const struct ad5791_chip_info *chip_info; + unsigned short vref_mv; + unsigned int vref_neg_mv; + unsigned ctrl; + unsigned pwr_down_mode; + bool pwr_down; +}; + +/** + * ad5791_supported_device_ids: + */ + +enum ad5791_supported_device_ids { + ID_AD5760, + ID_AD5780, + ID_AD5781, + ID_AD5791, +}; + static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val) { union { diff --git a/drivers/staging/iio/dac/ad5791.h b/drivers/staging/iio/dac/ad5791.h index fd7edbdb4ec3..87a6c922f18e 100644 --- a/drivers/staging/iio/dac/ad5791.h +++ b/drivers/staging/iio/dac/ad5791.h @@ -9,46 +9,6 @@ #ifndef SPI_AD5791_H_ #define SPI_AD5791_H_ -#define AD5791_RES_MASK(x) ((1 << (x)) - 1) -#define AD5791_DAC_MASK AD5791_RES_MASK(20) -#define AD5791_DAC_MSB (1 << 19) - -#define AD5791_CMD_READ (1 << 23) -#define AD5791_CMD_WRITE (0 << 23) -#define AD5791_ADDR(addr) ((addr) << 20) - -/* Registers */ -#define AD5791_ADDR_NOOP 0 -#define AD5791_ADDR_DAC0 1 -#define AD5791_ADDR_CTRL 2 -#define AD5791_ADDR_CLRCODE 3 -#define AD5791_ADDR_SW_CTRL 4 - -/* Control Register */ -#define AD5791_CTRL_RBUF (1 << 1) -#define AD5791_CTRL_OPGND (1 << 2) -#define AD5791_CTRL_DACTRI (1 << 3) -#define AD5791_CTRL_BIN2SC (1 << 4) -#define AD5791_CTRL_SDODIS (1 << 5) -#define AD5761_CTRL_LINCOMP(x) ((x) << 6) - -#define AD5791_LINCOMP_0_10 0 -#define AD5791_LINCOMP_10_12 1 -#define AD5791_LINCOMP_12_16 2 -#define AD5791_LINCOMP_16_19 3 -#define AD5791_LINCOMP_19_20 12 - -#define AD5780_LINCOMP_0_10 0 -#define AD5780_LINCOMP_10_20 12 - -/* Software Control Register */ -#define AD5791_SWCTRL_LDAC (1 << 0) -#define AD5791_SWCTRL_CLR (1 << 1) -#define AD5791_SWCTRL_RESET (1 << 2) - -#define AD5791_DAC_PWRDN_6K 0 -#define AD5791_DAC_PWRDN_3STATE 1 - /* * TODO: struct ad5791_platform_data needs to go into include/linux/iio */ @@ -66,47 +26,4 @@ struct ad5791_platform_data { bool use_rbuf_gain2; }; -/** - * struct ad5791_chip_info - chip specific information - * @get_lin_comp: function pointer to the device specific function - */ - -struct ad5791_chip_info { - int (*get_lin_comp) (unsigned int span); -}; - -/** - * struct ad5791_state - driver instance specific data - * @us: spi_device - * @reg_vdd: positive supply regulator - * @reg_vss: negative supply regulator - * @chip_info: chip model specific constants - * @vref_mv: actual reference voltage used - * @vref_neg_mv: voltage of the negative supply - * @pwr_down_mode current power down mode - */ - -struct ad5791_state { - struct spi_device *spi; - struct regulator *reg_vdd; - struct regulator *reg_vss; - const struct ad5791_chip_info *chip_info; - unsigned short vref_mv; - unsigned int vref_neg_mv; - unsigned ctrl; - unsigned pwr_down_mode; - bool pwr_down; -}; - -/** - * ad5791_supported_device_ids: - */ - -enum ad5791_supported_device_ids { - ID_AD5760, - ID_AD5780, - ID_AD5781, - ID_AD5791, -}; - #endif /* SPI_AD5791_H_ */ -- GitLab From dbdc025bb239ce62c9b4d28c459a98f22ce9ec0a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 11:36:28 +0200 Subject: [PATCH 0471/6849] staging:iio: Move DAC drivers out of staging The IIO DAC drivers are in a reasonably good shape. They all make use of channel spec and non of them provides non-documented sysfs attributes. Code style should be OK as well, both checkpatch and coccicheck only report trivial issues. So lets move the whole folder out of staging. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/{staging => }/iio/dac/Kconfig | 0 drivers/{staging => }/iio/dac/Makefile | 0 drivers/{staging => }/iio/dac/ad5064.c | 0 drivers/{staging => }/iio/dac/ad5360.c | 0 drivers/{staging => }/iio/dac/ad5380.c | 0 drivers/{staging => }/iio/dac/ad5421.c | 2 +- drivers/{staging => }/iio/dac/ad5446.c | 0 drivers/{staging => }/iio/dac/ad5446.h | 0 drivers/{staging => }/iio/dac/ad5504.c | 3 +-- drivers/{staging => }/iio/dac/ad5624r.h | 0 drivers/{staging => }/iio/dac/ad5624r_spi.c | 0 drivers/{staging => }/iio/dac/ad5686.c | 0 drivers/{staging => }/iio/dac/ad5764.c | 0 drivers/{staging => }/iio/dac/ad5791.c | 3 +-- drivers/{staging => }/iio/dac/max517.c | 3 +-- drivers/staging/iio/Kconfig | 1 - drivers/staging/iio/Makefile | 1 - {drivers/staging => include/linux}/iio/dac/ad5421.h | 4 ---- {drivers/staging => include/linux}/iio/dac/ad5504.h | 4 ---- {drivers/staging => include/linux}/iio/dac/ad5791.h | 4 ---- {drivers/staging => include/linux}/iio/dac/max517.h | 4 ---- 23 files changed, 6 insertions(+), 25 deletions(-) rename drivers/{staging => }/iio/dac/Kconfig (100%) rename drivers/{staging => }/iio/dac/Makefile (100%) rename drivers/{staging => }/iio/dac/ad5064.c (100%) rename drivers/{staging => }/iio/dac/ad5360.c (100%) rename drivers/{staging => }/iio/dac/ad5380.c (100%) rename drivers/{staging => }/iio/dac/ad5421.c (99%) rename drivers/{staging => }/iio/dac/ad5446.c (100%) rename drivers/{staging => }/iio/dac/ad5446.h (100%) rename drivers/{staging => }/iio/dac/ad5504.c (99%) rename drivers/{staging => }/iio/dac/ad5624r.h (100%) rename drivers/{staging => }/iio/dac/ad5624r_spi.c (100%) rename drivers/{staging => }/iio/dac/ad5686.c (100%) rename drivers/{staging => }/iio/dac/ad5764.c (100%) rename drivers/{staging => }/iio/dac/ad5791.c (99%) rename drivers/{staging => }/iio/dac/max517.c (99%) rename {drivers/staging => include/linux}/iio/dac/ad5421.h (92%) rename {drivers/staging => include/linux}/iio/dac/ad5504.h (74%) rename {drivers/staging => include/linux}/iio/dac/ad5791.h (87%) rename {drivers/staging => include/linux}/iio/dac/max517.h (76%) diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 64c88e5cda4d..103349f2b3b5 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -52,5 +52,6 @@ source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/light/Kconfig" source "drivers/iio/frequency/Kconfig" +source "drivers/iio/dac/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index bd801c0bbc2f..c38fa2a40af2 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -13,3 +13,4 @@ obj-y += adc/ obj-y += amplifiers/ obj-y += light/ obj-y += frequency/ +obj-y += dac/ diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/iio/dac/Kconfig similarity index 100% rename from drivers/staging/iio/dac/Kconfig rename to drivers/iio/dac/Kconfig diff --git a/drivers/staging/iio/dac/Makefile b/drivers/iio/dac/Makefile similarity index 100% rename from drivers/staging/iio/dac/Makefile rename to drivers/iio/dac/Makefile diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c similarity index 100% rename from drivers/staging/iio/dac/ad5064.c rename to drivers/iio/dac/ad5064.c diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c similarity index 100% rename from drivers/staging/iio/dac/ad5360.c rename to drivers/iio/dac/ad5360.c diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c similarity index 100% rename from drivers/staging/iio/dac/ad5380.c rename to drivers/iio/dac/ad5380.c diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c similarity index 99% rename from drivers/staging/iio/dac/ad5421.c rename to drivers/iio/dac/ad5421.c index ea2f83b4e357..cdbc5bf25c31 100644 --- a/drivers/staging/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -19,7 +19,7 @@ #include #include #include -#include "ad5421.h" +#include #define AD5421_REG_DAC_DATA 0x1 diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c similarity index 100% rename from drivers/staging/iio/dac/ad5446.c rename to drivers/iio/dac/ad5446.c diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h similarity index 100% rename from drivers/staging/iio/dac/ad5446.h rename to drivers/iio/dac/ad5446.h diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c similarity index 99% rename from drivers/staging/iio/dac/ad5504.c rename to drivers/iio/dac/ad5504.c index 1289e9bc1688..242bdc7d0044 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -19,8 +19,7 @@ #include #include #include - -#include "ad5504.h" +#include #define AD5505_BITS 12 #define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1) diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/iio/dac/ad5624r.h similarity index 100% rename from drivers/staging/iio/dac/ad5624r.h rename to drivers/iio/dac/ad5624r.h diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c similarity index 100% rename from drivers/staging/iio/dac/ad5624r_spi.c rename to drivers/iio/dac/ad5624r_spi.c diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c similarity index 100% rename from drivers/staging/iio/dac/ad5686.c rename to drivers/iio/dac/ad5686.c diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c similarity index 100% rename from drivers/staging/iio/dac/ad5764.c rename to drivers/iio/dac/ad5764.c diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c similarity index 99% rename from drivers/staging/iio/dac/ad5791.c rename to drivers/iio/dac/ad5791.c index 5de28c2a57ef..2bd2e37280ff 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -19,8 +19,7 @@ #include #include - -#include "ad5791.h" +#include #define AD5791_RES_MASK(x) ((1 << (x)) - 1) #define AD5791_DAC_MASK AD5791_RES_MASK(20) diff --git a/drivers/staging/iio/dac/max517.c b/drivers/iio/dac/max517.c similarity index 99% rename from drivers/staging/iio/dac/max517.c rename to drivers/iio/dac/max517.c index 403e06fbc39e..92c77c82026c 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -27,8 +27,7 @@ #include #include - -#include "max517.h" +#include #define MAX517_DRV_NAME "max517" diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 3c8e5ec26ac1..04cd6ec1f70f 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -29,7 +29,6 @@ source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" source "drivers/staging/iio/cdc/Kconfig" -source "drivers/staging/iio/dac/Kconfig" source "drivers/staging/iio/frequency/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/impedance-analyzer/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 6a46d5afb380..fa6937d92ee3 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -17,7 +17,6 @@ obj-y += accel/ obj-y += adc/ obj-y += addac/ obj-y += cdc/ -obj-y += dac/ obj-y += frequency/ obj-y += gyro/ obj-y += impedance-analyzer/ diff --git a/drivers/staging/iio/dac/ad5421.h b/include/linux/iio/dac/ad5421.h similarity index 92% rename from drivers/staging/iio/dac/ad5421.h rename to include/linux/iio/dac/ad5421.h index cd2bb84ff1b0..8fd8f057a890 100644 --- a/drivers/staging/iio/dac/ad5421.h +++ b/include/linux/iio/dac/ad5421.h @@ -1,10 +1,6 @@ #ifndef __IIO_DAC_AD5421_H__ #define __IIO_DAC_AD5421_H__ -/* - * TODO: This file needs to go into include/linux/iio - */ - /** * enum ad5421_current_range - Current range the AD5421 is configured for. * @AD5421_CURRENT_RANGE_4mA_20mA: 4 mA to 20 mA (RANGE1,0 pins = 00) diff --git a/drivers/staging/iio/dac/ad5504.h b/include/linux/iio/dac/ad5504.h similarity index 74% rename from drivers/staging/iio/dac/ad5504.h rename to include/linux/iio/dac/ad5504.h index d4980bf688bf..43895376a9ca 100644 --- a/drivers/staging/iio/dac/ad5504.h +++ b/include/linux/iio/dac/ad5504.h @@ -9,10 +9,6 @@ #ifndef SPI_AD5504_H_ #define SPI_AD5504_H_ -/* - * TODO: struct ad5504_platform_data needs to go into include/linux/iio - */ - struct ad5504_platform_data { u16 vref_mv; }; diff --git a/drivers/staging/iio/dac/ad5791.h b/include/linux/iio/dac/ad5791.h similarity index 87% rename from drivers/staging/iio/dac/ad5791.h rename to include/linux/iio/dac/ad5791.h index 87a6c922f18e..45ee281c6660 100644 --- a/drivers/staging/iio/dac/ad5791.h +++ b/include/linux/iio/dac/ad5791.h @@ -9,10 +9,6 @@ #ifndef SPI_AD5791_H_ #define SPI_AD5791_H_ -/* - * TODO: struct ad5791_platform_data needs to go into include/linux/iio - */ - /** * struct ad5791_platform_data - platform specific information * @vref_pos_mv: Vdd Positive Analog Supply Volatge (mV) diff --git a/drivers/staging/iio/dac/max517.h b/include/linux/iio/dac/max517.h similarity index 76% rename from drivers/staging/iio/dac/max517.h rename to include/linux/iio/dac/max517.h index 8106cf24642a..f6d1d252f08d 100644 --- a/drivers/staging/iio/dac/max517.h +++ b/include/linux/iio/dac/max517.h @@ -8,10 +8,6 @@ #ifndef IIO_DAC_MAX517_H_ #define IIO_DAC_MAX517_H_ -/* - * TODO: struct max517_platform_data needs to go into include/linux/iio - */ - struct max517_platform_data { u16 vref_mv[2]; }; -- GitLab From 1079def493b55e7a69e6eefc6e026224e1d90e2a Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Mon, 4 Jun 2012 15:11:04 +0530 Subject: [PATCH 0472/6849] staging: iio: hmc5843: Make it behave better as modules The memory regions of the probe and remove are move to __devinit and __devexit respectively. Acked-by: Jonathan Cameron Signed-off-by: Shubhrajyoti D Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/hmc5843.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index c1fa09f07625..6c3e50f7c0d8 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -665,7 +665,7 @@ static const struct iio_info hmc5843_info = { .driver_module = THIS_MODULE, }; -static int hmc5843_probe(struct i2c_client *client, +static int __devinit hmc5843_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct hmc5843_data *data; @@ -704,7 +704,7 @@ exit: return err; } -static int hmc5843_remove(struct i2c_client *client) +static int __devexit hmc5843_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); @@ -755,7 +755,7 @@ static struct i2c_driver hmc5843_driver = { }, .id_table = hmc5843_id, .probe = hmc5843_probe, - .remove = hmc5843_remove, + .remove = __devexit_p(hmc5843_remove), .detect = hmc5843_detect, .address_list = normal_i2c, }; -- GitLab From f61343b397975c6360c0f83edebbfdad19baf8f7 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Mon, 4 Jun 2012 15:11:05 +0530 Subject: [PATCH 0473/6849] staging: iio: ak8975: Make it behave better as modules The memory regions of the probe and remove are move to __devinit and __devexit respectively. Acked-by: Jonathan Cameron Signed-off-by: Shubhrajyoti D Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 5834e4a70f8c..7562cafb26bb 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -471,7 +471,7 @@ static const struct iio_info ak8975_info = { .driver_module = THIS_MODULE, }; -static int ak8975_probe(struct i2c_client *client, +static int __devinit ak8975_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ak8975_data *data; @@ -545,7 +545,7 @@ exit: return err; } -static int ak8975_remove(struct i2c_client *client) +static int __devexit ak8975_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct ak8975_data *data = iio_priv(indio_dev); -- GitLab From 2ce2e4b2b56dd564d27e7aadb92ed0c2342a9c57 Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:24 -0500 Subject: [PATCH 0474/6849] ARM: imx: Modify IMX_IO_P2V macro A change is needed in the IMX_IO_P2V macro to allow all imx5 platforms to use common definitions when accessing registers of peripherals on the AIPS2 bus. With this change, IMX_IO_P2V(MX50_AIPS2_BASE_ADDR) == IMX_IO_P2V(MX51_AIPS2_BASE_ADDR) == IMX_IO_P2V(MX53_AIPS2_BASE_ADDR). This change was tested for mapping conflicts using the iop2v script found at git://git.pengutronix.de/git/ukl/imx-iop2v.git and by performing a bootup of a default build using imx_v6_v7_defconfig on a imx51 babbage board and imx53 loco board. The comments were modified to reflect the output given by the script which shows the virtual address mappings. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/hardware.h | 25 +++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index 0630513554de..071afd0b9283 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h @@ -50,7 +50,7 @@ * IO 0x00200000+0x100000 -> 0xf4000000+0x100000 * mx21: * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000 - * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000 + * SAHB1 0x80000000+0x100000 -> 0xf5000000+0x100000 * X_MEMC 0xdf000000+0x004000 -> 0xf5f00000+0x004000 * mx25: * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000 @@ -58,47 +58,50 @@ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 * mx27: * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000 - * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000 + * SAHB1 0x80000000+0x100000 -> 0xf5000000+0x100000 * X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000 * mx31: * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000 * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 - * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000 + * X_MEMC 0xb8000000+0x010000 -> 0xf5c00000+0x010000 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 * mx35: * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000 * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 - * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000 + * X_MEMC 0xb8000000+0x010000 -> 0xf5c00000+0x010000 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 * mx50: * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 - * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 + * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 * mx51: - * TZIC 0xe0000000+0x004000 -> 0xf5000000+0x004000 + * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000 + * DEBUG 0x60000000+0x100000 -> 0xf5000000+0x100000 * SPBA0 0x70000000+0x100000 -> 0xf5400000+0x100000 * AIPS1 0x73f00000+0x100000 -> 0xf5700000+0x100000 - * AIPS2 0x83f00000+0x100000 -> 0xf4300000+0x100000 + * AIPS2 0x83f00000+0x100000 -> 0xf5300000+0x100000 * mx53: * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 + * DEBUG 0x40000000+0x100000 -> 0xf5000000+0x100000 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 * mx6q: - * SCU 0x00a00000+0x001000 -> 0xf4000000+0x001000 + * SCU 0x00a00000+0x004000 -> 0xf4000000+0x004000 * CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000 - * ANATOP 0x020c8000+0x001000 -> 0xf42c8000+0x001000 + * ANATOP 0x020c8000+0x004000 -> 0xf42c8000+0x004000 * UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000 */ #define IMX_IO_P2V(x) ( \ - 0xf4000000 + \ + (((x) & 0x80000000) >> 7) | \ + (0xf4000000 + \ (((x) & 0x50000000) >> 6) + \ (((x) & 0x0b000000) >> 4) + \ - (((x) & 0x000fffff))) + (((x) & 0x000fffff)))) #define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x)) -- GitLab From eee4f4003824b0887251a3ba4493217371816a57 Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:25 -0500 Subject: [PATCH 0475/6849] ARM: imx: Add comments to tzic_enable_waker() Add additional comments to the tzic_enable_wake() funciton to clarify its intended usage. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/tzic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index 98308ec1f321..a45dbea5e176 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c @@ -190,6 +190,10 @@ void __init tzic_init_irq(void __iomem *irqbase) * tzic_enable_wake() - enable wakeup interrupt * * @return 0 if successful; non-zero otherwise + * + * This function provides an interrupt synchronization point that is required + * by tzic enabled platforms before entering imx specific low power modes (ie, + * those low power modes beyond the WAIT_CLOCKED basic ARM WFI only mode). */ int tzic_enable_wake(void) { -- GitLab From 565fa91f236524b6ba4872903dc9cc9c874493e6 Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:26 -0500 Subject: [PATCH 0476/6849] ARM: imx: clean and consolidate imx5 suspend and idle code The imx5 idle code that existed in mm-imx5.c is moved to pm-imx5.c. The imx5_pm_init call is now exported and called during the MACHINE_START late_init in supported imx5 platforms. Remove various enabling/disabling of the gpc_dvfs clock and enable it once during initialization. This is a very low power clock that must be enabled during low power operations. There are only two "suspend_state_t" imx5 low power modes ever used. STOP_POWER_OFF for suspend to mem and WAIT_UNCLOCKED_POWER_OFF for idle and suspend to standby. The latter mode only requires 500 nanoseconds of extra hardware exit time beyond a basic WFI operation (WAIT_CLOCKED mode) so no other idle mode is necessary. Given this information, it is more efficient to keep the registers in the often used WAIT_UNCLOCKED_POWER_OFF state and only to and from the STOP_POWER_OFF register state as needed when suspend to mem is required. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mm-imx5.c | 21 +------- arch/arm/mach-imx/pm-imx5.c | 67 +++++++++++++++---------- arch/arm/plat-mxc/include/mach/common.h | 3 +- 3 files changed, 44 insertions(+), 47 deletions(-) diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index feeee17da96b..d84421e1467d 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -24,24 +23,6 @@ #include #include -static struct clk *gpc_dvfs_clk; - -static void imx5_idle(void) -{ - /* gpc clock is needed for SRPG */ - if (gpc_dvfs_clk == NULL) { - gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); - if (IS_ERR(gpc_dvfs_clk)) - return; - clk_prepare(gpc_dvfs_clk); - } - clk_enable(gpc_dvfs_clk); - mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (!tzic_enable_wake()) - cpu_do_idle(); - clk_disable(gpc_dvfs_clk); -} - /* * Define the MX50 memory map. */ @@ -105,7 +86,6 @@ void __init imx51_init_early(void) mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); - arm_pm_idle = imx5_idle; } void __init imx53_init_early(void) @@ -241,4 +221,5 @@ void __init imx53_soc_init(void) void __init imx51_init_late(void) { mx51_neon_fixup(); + imx51_pm_init(); } diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index e26a9cb05ed8..baf93214f899 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -13,18 +13,27 @@ #include #include #include +#include #include #include #include #include "crm-regs-imx5.h" -static struct clk *gpc_dvfs_clk; +/* + * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit. + * This is also the lowest power state possible without affecting + * non-cpu parts of the system. For these reasons, imx5 should default + * to always using this state for cpu idling. The PM_SUSPEND_STANDBY also + * uses this state and needs to take no action when registers remain confgiured + * for this state. + */ +#define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF /* * set cpu low power mode before WFI instruction. This function is called * mx5 because it can be used for mx50, mx51, and mx53. */ -void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) +static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) { u32 plat_lpc, arm_srpgcr, ccm_clpcr; u32 empgc0, empgc1; @@ -87,11 +96,6 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) } } -static int mx5_suspend_prepare(void) -{ - return clk_prepare_enable(gpc_dvfs_clk); -} - static int mx5_suspend_enter(suspend_state_t state) { switch (state) { @@ -99,7 +103,7 @@ static int mx5_suspend_enter(suspend_state_t state) mx5_cpu_lp_set(STOP_POWER_OFF); break; case PM_SUSPEND_STANDBY: - mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + /* DEFAULT_IDLE_STATE already configured */ break; default: return -EINVAL; @@ -114,12 +118,10 @@ static int mx5_suspend_enter(suspend_state_t state) __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); } cpu_do_idle(); - return 0; -} -static void mx5_suspend_finish(void) -{ - clk_disable_unprepare(gpc_dvfs_clk); + /* return registers to default idle state */ + mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); + return 0; } static int mx5_pm_valid(suspend_state_t state) @@ -129,25 +131,38 @@ static int mx5_pm_valid(suspend_state_t state) static const struct platform_suspend_ops mx5_suspend_ops = { .valid = mx5_pm_valid, - .prepare = mx5_suspend_prepare, .enter = mx5_suspend_enter, - .finish = mx5_suspend_finish, }; -static int __init mx5_pm_init(void) +static void imx5_pm_idle(void) { - if (!cpu_is_mx51() && !cpu_is_mx53()) - return 0; + if (likely(!tzic_enable_wake())) + cpu_do_idle(); +} + +static int __init imx5_pm_common_init(void) +{ + int ret; + struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); + + if (IS_ERR(gpc_dvfs_clk)) + return PTR_ERR(gpc_dvfs_clk); - if (gpc_dvfs_clk == NULL) - gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); + ret = clk_prepare_enable(gpc_dvfs_clk); + if (ret) + return ret; - if (!IS_ERR(gpc_dvfs_clk)) { - if (cpu_is_mx51()) - suspend_set_ops(&mx5_suspend_ops); - } else - return -EPERM; + arm_pm_idle = imx5_pm_idle; + + /* Set the registers to the default cpu idle state. */ + mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); return 0; } -device_initcall(mx5_pm_init); + +void __init imx51_pm_init(void) +{ + int ret = imx5_pm_common_init(); + if (!ret) + suspend_set_ops(&mx5_suspend_ops); +} diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index cf663d84e7c1..f65d068e1820 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -95,7 +95,6 @@ enum mx3_cpu_pwr_mode { }; extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); -extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode); extern void imx_print_silicon_rev(const char *cpu, int srev); void avic_handle_irq(struct pt_regs *); @@ -146,8 +145,10 @@ extern void imx6q_clock_map_io(void); #ifdef CONFIG_PM extern void imx6q_pm_init(void); +extern void imx51_pm_init(void); #else static inline void imx6q_pm_init(void) {} +static inline void imx51_pm_init(void) {} #endif #ifdef CONFIG_NEON -- GitLab From aa96a18d22dc7ad4dbc98cb0f4b2967a9fc979ca Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:27 -0500 Subject: [PATCH 0477/6849] ARM: imx: Enable imx53 low power idle Add various functionality needed to enable a imx53 low power idle state. This includes adding the imx53 gpc_dvfs clock and making a common imx5_late_init function and initializing all imx53 MACHINE_STATE late_init calls to imx5_late_init. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-imx51-imx53.c | 2 +- arch/arm/mach-imx/imx53-dt.c | 1 + arch/arm/mach-imx/mach-mx53_ard.c | 1 + arch/arm/mach-imx/mach-mx53_evk.c | 1 + arch/arm/mach-imx/mach-mx53_loco.c | 1 + arch/arm/mach-imx/mach-mx53_smd.c | 1 + arch/arm/mach-imx/mm-imx5.c | 5 +++++ arch/arm/mach-imx/pm-imx5.c | 5 +++++ arch/arm/plat-mxc/include/mach/common.h | 3 +++ 9 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index fcd94f3b0f0e..8a2e7194b221 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -279,6 +279,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); + clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); /* Set SDHC parents to be PLL2 */ clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]); @@ -336,7 +337,6 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL); clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0"); clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); - clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu"); clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu"); diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c index eb04b6248e48..481c3e96ad7f 100644 --- a/arch/arm/mach-imx/imx53-dt.c +++ b/arch/arm/mach-imx/imx53-dt.c @@ -147,6 +147,7 @@ DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)") .handle_irq = imx53_handle_irq, .timer = &imx53_timer, .init_machine = imx53_dt_init, + .init_late = imx53_init_late, .dt_compat = imx53_dt_board_compat, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c index 05641980dc5e..f1e83d6d2dfc 100644 --- a/arch/arm/mach-imx/mach-mx53_ard.c +++ b/arch/arm/mach-imx/mach-mx53_ard.c @@ -266,5 +266,6 @@ MACHINE_START(MX53_ARD, "Freescale MX53 ARD Board") .handle_irq = imx53_handle_irq, .timer = &mx53_ard_timer, .init_machine = mx53_ard_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_evk.c b/arch/arm/mach-imx/mach-mx53_evk.c index 5a72188b9cdb..8387496ef5ec 100644 --- a/arch/arm/mach-imx/mach-mx53_evk.c +++ b/arch/arm/mach-imx/mach-mx53_evk.c @@ -174,5 +174,6 @@ MACHINE_START(MX53_EVK, "Freescale MX53 EVK Board") .handle_irq = imx53_handle_irq, .timer = &mx53_evk_timer, .init_machine = mx53_evk_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_loco.c b/arch/arm/mach-imx/mach-mx53_loco.c index 37f67cac15a4..e266f3f0f080 100644 --- a/arch/arm/mach-imx/mach-mx53_loco.c +++ b/arch/arm/mach-imx/mach-mx53_loco.c @@ -316,5 +316,6 @@ MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board") .handle_irq = imx53_handle_irq, .timer = &mx53_loco_timer, .init_machine = mx53_loco_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_smd.c b/arch/arm/mach-imx/mach-mx53_smd.c index 8e972c5c3e13..4f4c1b93ea66 100644 --- a/arch/arm/mach-imx/mach-mx53_smd.c +++ b/arch/arm/mach-imx/mach-mx53_smd.c @@ -163,5 +163,6 @@ MACHINE_START(MX53_SMD, "Freescale MX53 SMD Board") .handle_irq = imx53_handle_irq, .timer = &mx53_smd_timer, .init_machine = mx53_smd_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index d84421e1467d..cc7e7ca52908 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -223,3 +223,8 @@ void __init imx51_init_late(void) mx51_neon_fixup(); imx51_pm_init(); } + +void __init imx53_init_late(void) +{ + imx53_pm_init(); +} diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index baf93214f899..b3dcd8e50d5b 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -166,3 +166,8 @@ void __init imx51_pm_init(void) if (!ret) suspend_set_ops(&mx5_suspend_ops); } + +void __init imx53_pm_init(void) +{ + imx5_pm_common_init(); +} diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index f65d068e1820..3314e6952556 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -54,6 +54,7 @@ extern void imx50_soc_init(void); extern void imx51_soc_init(void); extern void imx53_soc_init(void); extern void imx51_init_late(void); +extern void imx53_init_late(void); extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); extern int mx1_clocks_init(unsigned long fref); @@ -146,9 +147,11 @@ extern void imx6q_clock_map_io(void); #ifdef CONFIG_PM extern void imx6q_pm_init(void); extern void imx51_pm_init(void); +extern void imx53_pm_init(void); #else static inline void imx6q_pm_init(void) {} static inline void imx51_pm_init(void) {} +static inline void imx53_pm_init(void) {} #endif #ifdef CONFIG_NEON -- GitLab From 2da50e6284caadd92ded697e41fb200358f64261 Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:28 -0500 Subject: [PATCH 0478/6849] ARM: imx: Add common imx cpuidle init functionality. Add common cpuidle init functionality that can be used by various imx platforms. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/Makefile | 1 + arch/arm/plat-mxc/cpuidle.c | 80 ++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/cpuidle.h | 22 +++++++ 3 files changed, 103 insertions(+) create mode 100644 arch/arm/plat-mxc/cpuidle.c create mode 100644 arch/arm/plat-mxc/include/mach/cpuidle.h diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index e81290c27c65..63b064b5c1d5 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o ifdef CONFIG_SND_IMX_SOC obj-y += ssi-fiq.o obj-y += ssi-fiq-ksym.o diff --git a/arch/arm/plat-mxc/cpuidle.c b/arch/arm/plat-mxc/cpuidle.c new file mode 100644 index 000000000000..d4cb511a44a8 --- /dev/null +++ b/arch/arm/plat-mxc/cpuidle.c @@ -0,0 +1,80 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include + +static struct cpuidle_device __percpu * imx_cpuidle_devices; + +static void __init imx_cpuidle_devices_uninit(void) +{ + int cpu_id; + struct cpuidle_device *dev; + + for_each_possible_cpu(cpu_id) { + dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); + cpuidle_unregister_device(dev); + } + + free_percpu(imx_cpuidle_devices); +} + +int __init imx_cpuidle_init(struct cpuidle_driver *drv) +{ + struct cpuidle_device *dev; + int cpu_id, ret; + + if (drv->state_count > CPUIDLE_STATE_MAX) { + pr_err("%s: state_count exceeds maximum\n", __func__); + return -EINVAL; + } + + ret = cpuidle_register_driver(drv); + if (ret) { + pr_err("%s: Failed to register cpuidle driver with error: %d\n", + __func__, ret); + return ret; + } + + imx_cpuidle_devices = alloc_percpu(struct cpuidle_device); + if (imx_cpuidle_devices == NULL) { + ret = -ENOMEM; + goto unregister_drv; + } + + /* initialize state data for each cpuidle_device */ + for_each_possible_cpu(cpu_id) { + dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); + dev->cpu = cpu_id; + dev->state_count = drv->state_count; + + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("%s: Failed to register cpu %u, error: %d\n", + __func__, cpu_id, ret); + goto uninit; + } + } + + return 0; + +uninit: + imx_cpuidle_devices_uninit(); + +unregister_drv: + cpuidle_unregister_driver(drv); + return ret; +} diff --git a/arch/arm/plat-mxc/include/mach/cpuidle.h b/arch/arm/plat-mxc/include/mach/cpuidle.h new file mode 100644 index 000000000000..bc932d1af372 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/cpuidle.h @@ -0,0 +1,22 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include + +#ifdef CONFIG_CPU_IDLE +extern int imx_cpuidle_init(struct cpuidle_driver *drv); +#else +static inline int imx_cpuidle_init(struct cpuidle_driver *drv) +{ + return -ENODEV; +} +#endif -- GitLab From ccc12b32dc8c8e88a5b35f8df34ec7c80f2e10b0 Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:29 -0500 Subject: [PATCH 0479/6849] ARM: imx: Add imx5 cpuidle Add cpuidle driver for imx5 platform. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/pm-imx5.c | 43 +++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index b3dcd8e50d5b..19621ed1ffa5 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -12,10 +12,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include "crm-regs-imx5.h" @@ -134,12 +136,48 @@ static const struct platform_suspend_ops mx5_suspend_ops = { .enter = mx5_suspend_enter, }; -static void imx5_pm_idle(void) +static inline int imx5_cpu_do_idle(void) { - if (likely(!tzic_enable_wake())) + int ret = tzic_enable_wake(); + + if (likely(!ret)) cpu_do_idle(); + + return ret; +} + +static void imx5_pm_idle(void) +{ + imx5_cpu_do_idle(); +} + +static int imx5_cpuidle_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int idx) +{ + int ret; + + ret = imx5_cpu_do_idle(); + if (ret < 0) + return ret; + + return idx; } +static struct cpuidle_driver imx5_cpuidle_driver = { + .name = "imx5_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = { + .enter = imx5_cpuidle_enter, + .exit_latency = 2, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IMX5 SRPG", + .desc = "CPU state retained,powered off", + }, + .state_count = 1, +}; + static int __init imx5_pm_common_init(void) { int ret; @@ -157,6 +195,7 @@ static int __init imx5_pm_common_init(void) /* Set the registers to the default cpu idle state. */ mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); + imx_cpuidle_init(&imx5_cpuidle_driver); return 0; } -- GitLab From b9d18dc3a05d59894d60d5e173ebfb89a4b91bdf Mon Sep 17 00:00:00 2001 From: Robert Lee Date: Mon, 21 May 2012 17:50:30 -0500 Subject: [PATCH 0480/6849] ARM: imx: Add imx6q cpuidle driver Add basic imx6q cpuidle driver. For now, only basic WFI state is supported. Deeper idle states will be added in the future. Signed-off-by: Robert Lee Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mach-imx6q.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index b47e98b7d539..d4ca2c470142 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -12,7 +12,9 @@ #include #include +#include #include +#include #include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -31,8 +34,10 @@ #include #include #include +#include #include + void imx6q_restart(char mode, const char *cmd) { struct device_node *np; @@ -129,6 +134,19 @@ static void __init imx6q_init_machine(void) imx6q_pm_init(); } +static struct cpuidle_driver imx6q_cpuidle_driver = { + .name = "imx6q_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .state_count = 1, +}; + +static void __init imx6q_init_late(void) +{ + imx_cpuidle_init(&imx6q_cpuidle_driver); +} + static void __init imx6q_map_io(void) { imx_lluart_map_io(); @@ -186,6 +204,7 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") .handle_irq = imx6q_handle_irq, .timer = &imx6q_timer, .init_machine = imx6q_init_machine, + .init_late = imx6q_init_late, .dt_compat = imx6q_dt_compat, .restart = imx6q_restart, MACHINE_END -- GitLab From 7412ff139d73f5561492478e89a22aede7252b7b Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 4 Jun 2012 12:43:03 -0700 Subject: [PATCH 0481/6849] mtip32xx: Remove 'registers' and 'flags' from sysfs This patch removes entries 'registers' and 'flags' from sysfs. Updated ABI file to reflect this change. Reported-by: Greg Kroah-Hartman Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- Documentation/ABI/testing/sysfs-block-rssd | 21 ----- drivers/block/mtip32xx/mtip32xx.c | 92 +--------------------- 2 files changed, 1 insertion(+), 112 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-block-rssd b/Documentation/ABI/testing/sysfs-block-rssd index 679ce3543122..beef30c046b0 100644 --- a/Documentation/ABI/testing/sysfs-block-rssd +++ b/Documentation/ABI/testing/sysfs-block-rssd @@ -1,26 +1,5 @@ -What: /sys/block/rssd*/registers -Date: March 2012 -KernelVersion: 3.3 -Contact: Asai Thambi S P -Description: This is a read-only file. Dumps below driver information and - hardware registers. - - S ACTive - - Command Issue - - Completed - - PORT IRQ STAT - - HOST IRQ STAT - - Allocated - - Commands in Q - What: /sys/block/rssd*/status Date: April 2012 KernelVersion: 3.4 Contact: Asai Thambi S P Description: This is a read-only file. Indicates the status of the device. - -What: /sys/block/rssd*/flags -Date: May 2012 -KernelVersion: 3.5 -Contact: Asai Thambi S P -Description: This is a read-only file. Dumps the flags in port and driver - data structure diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 264bc77dcb91..b6e95b911b8c 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2546,7 +2546,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, } /* - * Sysfs register/status dump. + * Sysfs status dump. * * @dev Pointer to the device structure, passed by the kernrel. * @attr Pointer to the device_attribute structure passed by the kernel. @@ -2555,71 +2555,6 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t mtip_hw_show_registers(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u32 group_allocated; - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; - int n; - - size += sprintf(&buf[size], "Hardware\n--------\n"); - size += sprintf(&buf[size], "S ACTive : [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) - size += sprintf(&buf[size], "%08X ", - readl(dd->port->s_active[n])); - - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Command Issue : [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) - size += sprintf(&buf[size], "%08X ", - readl(dd->port->cmd_issue[n])); - - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Completed : [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) - size += sprintf(&buf[size], "%08X ", - readl(dd->port->completed[n])); - - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "PORT IRQ STAT : [ 0x%08X ]\n", - readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "HOST IRQ STAT : [ 0x%08X ]\n", - readl(dd->mmio + HOST_IRQ_STAT)); - size += sprintf(&buf[size], "\n"); - - size += sprintf(&buf[size], "Local\n-----\n"); - size += sprintf(&buf[size], "Allocated : [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) { - if (sizeof(long) > sizeof(u32)) - group_allocated = - dd->port->allocated[n/2] >> (32*(n&1)); - else - group_allocated = dd->port->allocated[n]; - size += sprintf(&buf[size], "%08X ", group_allocated); - } - size += sprintf(&buf[size], "]\n"); - - size += sprintf(&buf[size], "Commands in Q: [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) { - if (sizeof(long) > sizeof(u32)) - group_allocated = - dd->port->cmds_to_issue[n/2] >> (32*(n&1)); - else - group_allocated = dd->port->cmds_to_issue[n]; - size += sprintf(&buf[size], "%08X ", group_allocated); - } - size += sprintf(&buf[size], "]\n"); - - return size; -} - static ssize_t mtip_hw_show_status(struct device *dev, struct device_attribute *attr, char *buf) @@ -2637,24 +2572,7 @@ static ssize_t mtip_hw_show_status(struct device *dev, return size; } -static ssize_t mtip_hw_show_flags(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; - - size += sprintf(&buf[size], "Flag in port struct : [ %08lX ]\n", - dd->port->flags); - size += sprintf(&buf[size], "Flag in dd struct : [ %08lX ]\n", - dd->dd_flag); - - return size; -} - -static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); -static DEVICE_ATTR(flags, S_IRUGO, mtip_hw_show_flags, NULL); /* * Create the sysfs related attributes. @@ -2671,15 +2589,9 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; - if (sysfs_create_file(kobj, &dev_attr_registers.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'registers' sysfs entry\n"); if (sysfs_create_file(kobj, &dev_attr_status.attr)) dev_warn(&dd->pdev->dev, "Error creating 'status' sysfs entry\n"); - if (sysfs_create_file(kobj, &dev_attr_flags.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'flags' sysfs entry\n"); return 0; } @@ -2698,9 +2610,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; - sysfs_remove_file(kobj, &dev_attr_registers.attr); sysfs_remove_file(kobj, &dev_attr_status.attr); - sysfs_remove_file(kobj, &dev_attr_flags.attr); return 0; } -- GitLab From 7b421d24eac79800ee68905f732300a291f72f00 Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Mon, 4 Jun 2012 12:44:02 -0700 Subject: [PATCH 0482/6849] mtip32xx: Create debugfs entries for troubleshooting On module load, creates a debugfs parent 'rssd' in debugfs root. Then for each device, create a new node with corresponding disk name. Under the new node, two entries 'registers' and 'flags' are created. NOTE: These entries were removed from sysfs in the previous patch Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 162 +++++++++++++++++++++++++++++- drivers/block/mtip32xx/mtip32xx.h | 4 + 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index b6e95b911b8c..a8fddeb3d638 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -37,6 +37,7 @@ #include #include <../drivers/ata/ahci.h> #include +#include #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -85,6 +86,7 @@ static int instance; * allocated in mtip_init(). */ static int mtip_major; +static struct dentry *dfs_parent; static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); @@ -2574,6 +2576,120 @@ static ssize_t mtip_hw_show_status(struct device *dev, static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); +static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, + size_t len, loff_t *offset) +{ + struct driver_data *dd = (struct driver_data *)f->private_data; + char buf[MTIP_DFS_MAX_BUF_SIZE]; + u32 group_allocated; + int size = *offset; + int n; + + if (!len || size) + return 0; + + if (size < 0) + return -EINVAL; + + size += sprintf(&buf[size], "H/ S ACTive : [ 0x"); + + for (n = dd->slot_groups-1; n >= 0; n--) + size += sprintf(&buf[size], "%08X ", + readl(dd->port->s_active[n])); + + size += sprintf(&buf[size], "]\n"); + size += sprintf(&buf[size], "H/ Command Issue : [ 0x"); + + for (n = dd->slot_groups-1; n >= 0; n--) + size += sprintf(&buf[size], "%08X ", + readl(dd->port->cmd_issue[n])); + + size += sprintf(&buf[size], "]\n"); + size += sprintf(&buf[size], "H/ Completed : [ 0x"); + + for (n = dd->slot_groups-1; n >= 0; n--) + size += sprintf(&buf[size], "%08X ", + readl(dd->port->completed[n])); + + size += sprintf(&buf[size], "]\n"); + size += sprintf(&buf[size], "H/ PORT IRQ STAT : [ 0x%08X ]\n", + readl(dd->port->mmio + PORT_IRQ_STAT)); + size += sprintf(&buf[size], "H/ HOST IRQ STAT : [ 0x%08X ]\n", + readl(dd->mmio + HOST_IRQ_STAT)); + size += sprintf(&buf[size], "\n"); + + size += sprintf(&buf[size], "L/ Allocated : [ 0x"); + + for (n = dd->slot_groups-1; n >= 0; n--) { + if (sizeof(long) > sizeof(u32)) + group_allocated = + dd->port->allocated[n/2] >> (32*(n&1)); + else + group_allocated = dd->port->allocated[n]; + size += sprintf(&buf[size], "%08X ", group_allocated); + } + size += sprintf(&buf[size], "]\n"); + + size += sprintf(&buf[size], "L/ Commands in Q : [ 0x"); + + for (n = dd->slot_groups-1; n >= 0; n--) { + if (sizeof(long) > sizeof(u32)) + group_allocated = + dd->port->cmds_to_issue[n/2] >> (32*(n&1)); + else + group_allocated = dd->port->cmds_to_issue[n]; + size += sprintf(&buf[size], "%08X ", group_allocated); + } + size += sprintf(&buf[size], "]\n"); + + *offset = size <= len ? size : len; + size = copy_to_user(ubuf, buf, *offset); + if (size) + return -EFAULT; + + return *offset; +} + +static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, + size_t len, loff_t *offset) +{ + struct driver_data *dd = (struct driver_data *)f->private_data; + char buf[MTIP_DFS_MAX_BUF_SIZE]; + int size = *offset; + + if (!len || size) + return 0; + + if (size < 0) + return -EINVAL; + + size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n", + dd->port->flags); + size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n", + dd->dd_flag); + + *offset = size <= len ? size : len; + size = copy_to_user(ubuf, buf, *offset); + if (size) + return -EFAULT; + + return *offset; +} + +static const struct file_operations mtip_regs_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = mtip_hw_read_registers, + .llseek = no_llseek, +}; + +static const struct file_operations mtip_flags_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = mtip_hw_read_flags, + .llseek = no_llseek, +}; + /* * Create the sysfs related attributes. * @@ -2615,6 +2731,34 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) return 0; } +static int mtip_hw_debugfs_init(struct driver_data *dd) +{ + if (!dfs_parent) + return -1; + + dd->dfs_node = debugfs_create_dir(dd->disk->disk_name, dfs_parent); + if (IS_ERR_OR_NULL(dd->dfs_node)) { + dev_warn(&dd->pdev->dev, + "Error creating node %s under debugfs\n", + dd->disk->disk_name); + dd->dfs_node = NULL; + return -1; + } + + debugfs_create_file("flags", S_IRUGO, dd->dfs_node, dd, + &mtip_flags_fops); + debugfs_create_file("registers", S_IRUGO, dd->dfs_node, dd, + &mtip_regs_fops); + + return 0; +} + +static void mtip_hw_debugfs_exit(struct driver_data *dd) +{ + debugfs_remove_recursive(dd->dfs_node); +} + + /* * Perform any init/resume time hardware setup * @@ -3640,6 +3784,7 @@ skip_create_disk: mtip_hw_sysfs_init(dd, kobj); kobject_put(kobj); } + mtip_hw_debugfs_init(dd); if (dd->mtip_svc_handler) { set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); @@ -3665,6 +3810,8 @@ start_service_thread: return rv; kthread_run_error: + mtip_hw_debugfs_exit(dd); + /* Delete our gendisk. This also removes the device from /dev */ del_gendisk(dd->disk); @@ -3715,6 +3862,7 @@ static int mtip_block_remove(struct driver_data *dd) kobject_put(kobj); } } + mtip_hw_debugfs_exit(dd); /* * Delete our gendisk structure. This also removes the device @@ -4062,10 +4210,20 @@ static int __init mtip_init(void) } mtip_major = error; + if (!dfs_parent) { + dfs_parent = debugfs_create_dir("rssd", NULL); + if (IS_ERR_OR_NULL(dfs_parent)) { + printk(KERN_WARNING "Error creating debugfs parent\n"); + dfs_parent = NULL; + } + } + /* Register our PCI operations. */ error = pci_register_driver(&mtip_pci_driver); - if (error) + if (error) { + debugfs_remove(dfs_parent); unregister_blkdev(mtip_major, MTIP_DRV_NAME); + } return error; } @@ -4082,6 +4240,8 @@ static int __init mtip_init(void) */ static void __exit mtip_exit(void) { + debugfs_remove_recursive(dfs_parent); + /* Release the allocated major block device number. */ unregister_blkdev(mtip_major, MTIP_DRV_NAME); diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index adb1aae3b752..f51fc23d17bb 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -110,6 +110,8 @@ #define dbg_printk(format, arg...) #endif +#define MTIP_DFS_MAX_BUF_SIZE 1024 + #define __force_bit2int (unsigned int __force) enum { @@ -446,6 +448,8 @@ struct driver_data { unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ + + struct dentry *dfs_node; }; #endif -- GitLab From d0a9001dce0ea24751b1f6336f2881ac906cabbb Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Thu, 10 May 2012 14:23:01 +0530 Subject: [PATCH 0483/6849] ARM: OMAP2+: am33xx: Add low level debugging support Add support for low level debugging on AM335X EVM (AM33XX family). Currently only support for UART1 console, which is used on AM335X EVM is added. Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Hiremath Reviewed-by: Kevin Hilman Cc: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/include/mach/debug-macro.S | 17 ++++++++++++++++- arch/arm/plat-omap/include/plat/serial.h | 4 ++++ arch/arm/plat-omap/include/plat/uncompress.h | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index cdfc2a1f0e75..d7f844a99a7b 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -72,6 +72,8 @@ omap_uart_lsr: .word 0 beq 82f @ configure UART2 cmp \rp, #TI81XXUART3 @ ti81Xx UART offsets different beq 83f @ configure UART3 + cmp \rp, #AM33XXUART1 @ AM33XX UART offsets different + beq 84f @ configure UART1 cmp \rp, #ZOOM_UART @ only on zoom2/3 beq 95f @ configure ZOOM_UART @@ -100,7 +102,9 @@ omap_uart_lsr: .word 0 b 98f 83: mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) b 98f - +84: ldr \rp, =AM33XX_UART1_BASE + and \rp, \rp, #0x00ffffff + b 97f 95: ldr \rp, =ZOOM_UART_BASE str \rp, [\tmp, #0] @ omap_uart_phys ldr \rp, =ZOOM_UART_VIRT @@ -109,6 +113,17 @@ omap_uart_lsr: .word 0 str \rp, [\tmp, #8] @ omap_uart_lsr b 10b + /* AM33XX: Store both phys and virt address for the uart */ +97: add \rp, \rp, #0x44000000 @ phys base + str \rp, [\tmp, #0] @ omap_uart_phys + sub \rp, \rp, #0x44000000 @ phys base + add \rp, \rp, #0xf9000000 @ virt base + str \rp, [\tmp, #4] @ omap_uart_virt + mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) + str \rp, [\tmp, #8] @ omap_uart_lsr + + b 10b + /* Store both phys and virt address for the uart */ 98: add \rp, \rp, #0x48000000 @ phys base str \rp, [\tmp, #0] @ omap_uart_phys diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index b073e5f2b190..28e2d250c2fd 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -60,6 +60,9 @@ /* AM3505/3517 UART4 */ #define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ +/* AM33XX serial port */ +#define AM33XX_UART1_BASE 0x44E09000 + /* External port on Zoom2/3 */ #define ZOOM_UART_BASE 0x10000000 #define ZOOM_UART_VIRT 0xfa400000 @@ -93,6 +96,7 @@ #define TI81XXUART1 81 #define TI81XXUART2 82 #define TI81XXUART3 83 +#define AM33XXUART1 84 #define ZOOM_UART 95 /* Only on zoom2/3 */ /* This is only used by 8250.c for omap1510 */ diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index cc3f11ba7a99..ac4323390213 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -103,6 +103,10 @@ static inline void flush(void) _DEBUG_LL_ENTRY(mach, TI81XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ TI81XXUART##p) +#define DEBUG_LL_AM33XX(p, mach) \ + _DEBUG_LL_ENTRY(mach, AM33XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ + AM33XXUART##p) + static inline void __arch_decomp_setup(unsigned long arch_id) { int port = 0; @@ -183,6 +187,8 @@ static inline void __arch_decomp_setup(unsigned long arch_id) /* TI8148 base boards using UART1 */ DEBUG_LL_TI81XX(1, ti8148evm); + /* AM33XX base boards using UART1 */ + DEBUG_LL_AM33XX(1, am335xevm); } while (0); } -- GitLab From 18847b42f8d157201550015296a222a9009a04da Mon Sep 17 00:00:00 2001 From: Javier Martin Date: Fri, 1 Jun 2012 09:45:33 +0200 Subject: [PATCH 0484/6849] ARM i.MX27 Visstrim M10: fix gpio handling. Some GPIOs in Visstrim M10 are used without being registered. This leads to USB and video malfunctions. This patch registers those GPIOs to solve the issue. Signed-off-by: Javier Martin Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mach-imx27_visstrim_m10.c | 36 ++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index f7b074f496f0..2c6a783d4c04 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -107,6 +107,8 @@ static const int visstrim_m10_pins[] __initconst = { PB23_PF_USB_PWR, PB24_PF_USB_OC, /* CSI */ + TVP5150_RSTN | GPIO_GPIO | GPIO_OUT, + TVP5150_PWDN | GPIO_GPIO | GPIO_OUT, PB10_PF_CSI_D0, PB11_PF_CSI_D1, PB12_PF_CSI_D2, @@ -121,6 +123,24 @@ static const int visstrim_m10_pins[] __initconst = { PB21_PF_CSI_HSYNC, }; +static const struct gpio visstrim_m10_gpios[] __initconst = { + { + .gpio = TVP5150_RSTN, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH, + .label = "tvp5150_rstn", + }, + { + .gpio = TVP5150_PWDN, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, + .label = "tvp5150_pwdn", + }, + { + .gpio = OTG_PHY_CS_GPIO, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, + .label = "usbotg_cs", + }, +}; + /* Camera */ static int visstrim_camera_power(struct device *dev, int on) { @@ -164,13 +184,6 @@ static void __init visstrim_camera_init(void) struct platform_device *pdev; int dma; - /* Initialize tvp5150 gpios */ - mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT); - mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT); - gpio_set_value(TVP5150_RSTN, 1); - gpio_set_value(TVP5150_PWDN, 0); - ndelay(1); - gpio_set_value(TVP5150_PWDN, 1); ndelay(1); gpio_set_value(TVP5150_RSTN, 0); @@ -351,10 +364,6 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { /* USB OTG */ static int otg_phy_init(struct platform_device *pdev) { - gpio_set_value(OTG_PHY_CS_GPIO, 0); - - mdelay(10); - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); } @@ -380,6 +389,11 @@ static void __init visstrim_m10_board_init(void) if (ret) pr_err("Failed to setup pins (%d)\n", ret); + ret = gpio_request_array(visstrim_m10_gpios, + ARRAY_SIZE(visstrim_m10_gpios)); + if (ret) + pr_err("Failed to request gpios (%d)\n", ret); + imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata); imx27_add_imx_uart0(&uart_pdata); -- GitLab From 08f3098928c991560408e8c71d4af8b1a3ff2d67 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Fri, 11 May 2012 00:38:49 +0530 Subject: [PATCH 0485/6849] ARM: OMAP2+: am33xx: Add AM335XEVM machine support This patch adds minimal support for AM335X machine init. During last merge window, two separate patches supporting am33xx machine init had been submitted, 1. Link to earlier Baseport patch submission (Legacy): http://www.mail-archive.com/linux-omap@vger.kernel.org/msg59325.html 2. Link to earlier DT based machine init support patch submission: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg61398.html And both had got accepted at that time, but got missed during merge window. But now, since we have taken decision to make am33xx as a separate class and not to follow omap3 family, these patches needs to changes accordingly (only changes), - Combine both the patches, since early init and timer init used in board-generic.c file requires them. - Remove dependency on AM3517EVM, and only use DT approach for machine init. - Change the config option (as changed recently) CONFIG_SOC_OMAPAM33XX --> CONFIG_SOC_AM33XX Signed-off-by: Vaibhav Hiremath Signed-off-by: Vaibhav Hiremath Cc: Benoit Cousson Cc: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-generic.c | 18 ++++++++++++++++++ arch/arm/mach-omap2/common.h | 2 ++ arch/arm/mach-omap2/io.c | 10 ++++++++++ arch/arm/mach-omap2/irq.c | 2 +- arch/arm/mach-omap2/timer.c | 5 +++++ 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 202934657867..2f2abfb82d84 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -112,6 +112,24 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") MACHINE_END #endif +#ifdef CONFIG_SOC_AM33XX +static const char *am33xx_boards_compat[] __initdata = { + "ti,am33xx", + NULL, +}; + +DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = am33xx_map_io, + .init_early = am33xx_init_early, + .init_irq = omap_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, + .timer = &omap3_am33xx_timer, + .dt_compat = am33xx_boards_compat, +MACHINE_END +#endif + #ifdef CONFIG_ARCH_OMAP4 static const char *omap4_boards_compat[] __initdata = { "ti,omap4", diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index be9dfd1abe60..56f687bebd0a 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -120,6 +120,7 @@ extern void omap2_init_common_infrastructure(void); extern struct sys_timer omap2_timer; extern struct sys_timer omap3_timer; extern struct sys_timer omap3_secure_timer; +extern struct sys_timer omap3_am33xx_timer; extern struct sys_timer omap4_timer; void omap2420_init_early(void); @@ -130,6 +131,7 @@ void omap3630_init_early(void); void omap3_init_early(void); /* Do not use this one */ void am35xx_init_early(void); void ti81xx_init_early(void); +void am33xx_init_early(void); void omap4430_init_early(void); void omap3_init_late(void); /* Do not use this one */ void omap4430_init_late(void); diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 8d014ba04abc..5d6b2346bf75 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -477,6 +477,16 @@ void __init ti81xx_init_late(void) } #endif +#ifdef CONFIG_SOC_AM33XX +void __init am33xx_init_early(void) +{ + omap2_set_globals_am33xx(); + omap3xxx_check_revision(); + ti81xx_check_features(); + omap_common_init_early(); +} +#endif + #ifdef CONFIG_ARCH_OMAP4 void __init omap4430_init_early(void) { diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index fdc4303be563..428685f65060 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -279,7 +279,7 @@ int __init omap_intc_of_init(struct device_node *node, return 0; } -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; void omap_intc_save_context(void) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 840929bd9dae..ea6a0eb13f05 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -368,6 +368,11 @@ OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE, OMAP_SYS_TIMER(3_secure) #endif +#ifdef CONFIG_SOC_AM33XX +OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, 2, OMAP4_MPU_SOURCE) +OMAP_SYS_TIMER(3_am33xx) +#endif + #ifdef CONFIG_ARCH_OMAP4 #ifdef CONFIG_LOCAL_TIMERS static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, -- GitLab From cc502bb741e1797290381da14dddb695ec1adbaf Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 3 Jun 2012 18:39:13 +0200 Subject: [PATCH 0486/6849] renesas_usbhs: cleanup quoted includes A few quoted includes start with a superfluous "./". Clean up those quoted includes. Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/usb/renesas_usbhs/common.c | 2 +- drivers/usb/renesas_usbhs/common.h | 4 ++-- drivers/usb/renesas_usbhs/fifo.c | 4 ++-- drivers/usb/renesas_usbhs/mod.c | 4 ++-- drivers/usb/renesas_usbhs/mod.h | 2 +- drivers/usb/renesas_usbhs/pipe.c | 4 ++-- drivers/usb/renesas_usbhs/pipe.h | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index a165490bae48..8c9bb1ad3069 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -19,7 +19,7 @@ #include #include #include -#include "./common.h" +#include "common.h" /* * image of renesas_usbhs diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 3f3ccd358753..dddf40a59ded 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -22,8 +22,8 @@ struct usbhs_priv; -#include "./mod.h" -#include "./pipe.h" +#include "mod.h" +#include "pipe.h" /* * diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 6ec7f838d7fa..08313574aac8 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -17,8 +17,8 @@ #include #include #include -#include "./common.h" -#include "./pipe.h" +#include "common.h" +#include "pipe.h" #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) #define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo)) diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 0871e816df45..82a628f96c03 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -16,8 +16,8 @@ */ #include -#include "./common.h" -#include "./mod.h" +#include "common.h" +#include "mod.h" #define usbhs_priv_to_modinfo(priv) (&priv->mod_info) #define usbhs_mod_info_call(priv, func, param...) \ diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h index 6c6875533f01..1ef5bf604070 100644 --- a/drivers/usb/renesas_usbhs/mod.h +++ b/drivers/usb/renesas_usbhs/mod.h @@ -19,7 +19,7 @@ #include #include -#include "./common.h" +#include "common.h" /* * struct diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index feb06d6d2814..122526cfd32b 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -16,8 +16,8 @@ */ #include #include -#include "./common.h" -#include "./pipe.h" +#include "common.h" +#include "pipe.h" /* * macros diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index fa18b7dc2b2a..08786c06dcf1 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -17,8 +17,8 @@ #ifndef RENESAS_USB_PIPE_H #define RENESAS_USB_PIPE_H -#include "./common.h" -#include "./fifo.h" +#include "common.h" +#include "fifo.h" /* * struct -- GitLab From c224071e28e2bbd213cce2e6e9dde26e78542ca8 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 3 Jun 2012 18:39:42 +0200 Subject: [PATCH 0487/6849] parisc: cleanup quoted include A quoted include starts with a superfluous "./". Clean up that quoted include. Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/parisc/iosapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 1f9e9fefb8e7..69ff60832b09 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -146,7 +146,7 @@ #endif #include -#include "./iosapic_private.h" +#include "iosapic_private.h" #define MODULE_NAME "iosapic" -- GitLab From 51ce29196dee3084387aa4448d75edc282a91685 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 5 Jun 2012 16:42:38 +0800 Subject: [PATCH 0488/6849] ARM: dts: update memory size on brownstone The memory size on brownstone should be 128MB, not 64MB. Signed-off-by: Haojian Zhuang --- arch/arm/boot/dts/mmp2-brownstone.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts index 153a4b2d12b5..c9b4f27d191e 100644 --- a/arch/arm/boot/dts/mmp2-brownstone.dts +++ b/arch/arm/boot/dts/mmp2-brownstone.dts @@ -11,7 +11,7 @@ /include/ "mmp2.dtsi" / { - model = "Marvell MMP2 Aspenite Development Board"; + model = "Marvell MMP2 Brownstone Development Board"; compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; chosen { @@ -19,7 +19,7 @@ }; memory { - reg = <0x00000000 0x04000000>; + reg = <0x00000000 0x08000000>; }; soc { -- GitLab From e39fe251e03b6df83e740e2f598c04f382b4d3c7 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Mon, 4 Jun 2012 20:45:40 +0200 Subject: [PATCH 0489/6849] HID: wiimote-ext: comment spelling fix Signed-off-by: Giuseppe Bilotta Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c index aa958706c0e5..0a1805c9b0e5 100644 --- a/drivers/hid/hid-wiimote-ext.c +++ b/drivers/hid/hid-wiimote-ext.c @@ -77,7 +77,7 @@ static __u16 wiiext_keymap[] = { BTN_TR, /* WIIEXT_KEY_RT */ }; -/* diable all extensions */ +/* disable all extensions */ static void ext_disable(struct wiimote_ext *ext) { unsigned long flags; -- GitLab From 10bd21c0547ba2834374ccdddbc6a984eeed432c Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 5 Jun 2012 17:42:23 +0800 Subject: [PATCH 0490/6849] ARM: mmp: fix missing cascade_irq in irq handler While supporting board in non-DT mode, icu_data[i]->cascade_irq isn't assigned with correct value. Signed-off-by: Haojian Zhuang --- arch/arm/mach-mmp/irq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c index fcfe0e3bd701..e60c7d98922b 100644 --- a/arch/arm/mach-mmp/irq.c +++ b/arch/arm/mach-mmp/irq.c @@ -241,6 +241,7 @@ void __init mmp2_init_icu(void) icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE; icu_data[1].nr_irqs = 2; + icu_data[1].cascade_irq = 4; icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs, icu_data[1].virq_base, 0, @@ -249,6 +250,7 @@ void __init mmp2_init_icu(void) icu_data[2].reg_status = mmp_icu_base + 0x154; icu_data[2].reg_mask = mmp_icu_base + 0x16c; icu_data[2].nr_irqs = 2; + icu_data[2].cascade_irq = 5; icu_data[2].virq_base = IRQ_MMP2_RTC_BASE; icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs, icu_data[2].virq_base, 0, @@ -257,6 +259,7 @@ void __init mmp2_init_icu(void) icu_data[3].reg_status = mmp_icu_base + 0x180; icu_data[3].reg_mask = mmp_icu_base + 0x17c; icu_data[3].nr_irqs = 3; + icu_data[3].cascade_irq = 9; icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE; icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs, icu_data[3].virq_base, 0, @@ -265,6 +268,7 @@ void __init mmp2_init_icu(void) icu_data[4].reg_status = mmp_icu_base + 0x158; icu_data[4].reg_mask = mmp_icu_base + 0x170; icu_data[4].nr_irqs = 5; + icu_data[4].cascade_irq = 17; icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE; icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs, icu_data[4].virq_base, 0, @@ -273,6 +277,7 @@ void __init mmp2_init_icu(void) icu_data[5].reg_status = mmp_icu_base + 0x15c; icu_data[5].reg_mask = mmp_icu_base + 0x174; icu_data[5].nr_irqs = 15; + icu_data[5].cascade_irq = 35; icu_data[5].virq_base = IRQ_MMP2_MISC_BASE; icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs, icu_data[5].virq_base, 0, @@ -281,6 +286,7 @@ void __init mmp2_init_icu(void) icu_data[6].reg_status = mmp_icu_base + 0x160; icu_data[6].reg_mask = mmp_icu_base + 0x178; icu_data[6].nr_irqs = 2; + icu_data[6].cascade_irq = 51; icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE; icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs, icu_data[6].virq_base, 0, @@ -289,6 +295,7 @@ void __init mmp2_init_icu(void) icu_data[7].reg_status = mmp_icu_base + 0x188; icu_data[7].reg_mask = mmp_icu_base + 0x184; icu_data[7].nr_irqs = 2; + icu_data[7].cascade_irq = 55; icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE; icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs, icu_data[7].virq_base, 0, -- GitLab From 2f989f7e9f5f9ba97535fa58f4240ec250d6b2df Mon Sep 17 00:00:00 2001 From: M R Swami Reddy Date: Fri, 1 Jun 2012 22:21:54 +0530 Subject: [PATCH 0491/6849] ASoC: Support TI Isabelle Audio driver ASoC: Support TI Isabelle Audio driver The Isabelle Audio IC is a complete low power high fidelity CODEC with integrated ADCs, DACs, decimation and interpolation filters, PLL, and power providers. This device supports 2 analog and 2 digital microphone channels, a mono earpiece driver, stereo class G headphone drivers with ultra low power and best SNR in the industry, stereo Class D speaker drivers, and 2 high performance Line drivers. The below patch is a basic driver code for TI Isabelle audio codec. The functionalities like headset detection, etc., will be included incrementally in the up-coming patches. Signed-off-by: Vishwas A Deshpande Signed-off-by: M R Swami Reddy Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/isabelle.c | 1179 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/isabelle.h | 143 +++++ 4 files changed, 1328 insertions(+) create mode 100644 sound/soc/codecs/isabelle.c create mode 100644 sound/soc/codecs/isabelle.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 1e1613a438dd..8b879c71c23c 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_CX20442 select SND_SOC_DA7210 if I2C select SND_SOC_DFBMCS320 + select SND_SOC_ISABELLE if I2C select SND_SOC_JZ4740_CODEC select SND_SOC_LM4857 if I2C select SND_SOC_LM49453 if I2C @@ -225,6 +226,9 @@ config SND_SOC_DFBMCS320 config SND_SOC_DMIC tristate +config SND_SOC_ISABELLE + tristate + config SND_SOC_LM49453 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index fc27fec39487..e50811b182a4 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -23,6 +23,7 @@ snd-soc-cx20442-objs := cx20442.o snd-soc-da7210-objs := da7210.o snd-soc-dfbmcs320-objs := dfbmcs320.o snd-soc-dmic-objs := dmic.o +snd-soc-isabelle-objs := isabelle.o snd-soc-jz4740-codec-objs := jz4740.o snd-soc-l3-objs := l3.o snd-soc-lm4857-objs := lm4857.o @@ -134,6 +135,7 @@ obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o +obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c new file mode 100644 index 000000000000..b6921a82fbcc --- /dev/null +++ b/sound/soc/codecs/isabelle.c @@ -0,0 +1,1179 @@ +/* + * isabelle.c - Low power high fidelity audio codec driver + * + * Copyright (c) 2012 Texas Instruments, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * + * Initially based on sound/soc/codecs/twl6040.c + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "isabelle.h" + + +/* Register default values for ISABELLE driver. */ +static struct reg_default isabelle_reg_defs[] = { + { 0, 0x00 }, + { 1, 0x00 }, + { 2, 0x00 }, + { 3, 0x00 }, + { 4, 0x00 }, + { 5, 0x00 }, + { 6, 0x00 }, + { 7, 0x00 }, + { 8, 0x00 }, + { 9, 0x00 }, + { 10, 0x00 }, + { 11, 0x00 }, + { 12, 0x00 }, + { 13, 0x00 }, + { 14, 0x00 }, + { 15, 0x00 }, + { 16, 0x00 }, + { 17, 0x00 }, + { 18, 0x00 }, + { 19, 0x00 }, + { 20, 0x00 }, + { 21, 0x02 }, + { 22, 0x02 }, + { 23, 0x02 }, + { 24, 0x02 }, + { 25, 0x0F }, + { 26, 0x8F }, + { 27, 0x0F }, + { 28, 0x8F }, + { 29, 0x00 }, + { 30, 0x00 }, + { 31, 0x00 }, + { 32, 0x00 }, + { 33, 0x00 }, + { 34, 0x00 }, + { 35, 0x00 }, + { 36, 0x00 }, + { 37, 0x00 }, + { 38, 0x00 }, + { 39, 0x00 }, + { 40, 0x00 }, + { 41, 0x00 }, + { 42, 0x00 }, + { 43, 0x00 }, + { 44, 0x00 }, + { 45, 0x00 }, + { 46, 0x00 }, + { 47, 0x00 }, + { 48, 0x00 }, + { 49, 0x00 }, + { 50, 0x00 }, + { 51, 0x00 }, + { 52, 0x00 }, + { 53, 0x00 }, + { 54, 0x00 }, + { 55, 0x00 }, + { 56, 0x00 }, + { 57, 0x00 }, + { 58, 0x00 }, + { 59, 0x00 }, + { 60, 0x00 }, + { 61, 0x00 }, + { 62, 0x00 }, + { 63, 0x00 }, + { 64, 0x00 }, + { 65, 0x00 }, + { 66, 0x00 }, + { 67, 0x00 }, + { 68, 0x00 }, + { 69, 0x90 }, + { 70, 0x90 }, + { 71, 0x90 }, + { 72, 0x00 }, + { 73, 0x00 }, + { 74, 0x00 }, + { 75, 0x00 }, + { 76, 0x00 }, + { 77, 0x00 }, + { 78, 0x00 }, + { 79, 0x00 }, + { 80, 0x00 }, + { 81, 0x00 }, + { 82, 0x00 }, + { 83, 0x00 }, + { 84, 0x00 }, + { 85, 0x07 }, + { 86, 0x00 }, + { 87, 0x00 }, + { 88, 0x00 }, + { 89, 0x07 }, + { 90, 0x80 }, + { 91, 0x07 }, + { 92, 0x07 }, + { 93, 0x00 }, + { 94, 0x00 }, + { 95, 0x00 }, + { 96, 0x00 }, + { 97, 0x00 }, + { 98, 0x00 }, + { 99, 0x00 }, +}; + +static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"}; +static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; + +static const struct soc_enum isabelle_rx1_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), + SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), +}; + +static const struct soc_enum isabelle_rx2_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), + SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), +}; + +/* Headset DAC playback switches */ +static const struct snd_kcontrol_new rx1_mux_controls = + SOC_DAPM_ENUM("Route", isabelle_rx1_enum); + +static const struct snd_kcontrol_new rx2_mux_controls = + SOC_DAPM_ENUM("Route", isabelle_rx2_enum); + +/* TX input selection */ +static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"}; +static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; + +static const struct soc_enum isabelle_atx_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), + SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), +}; + +static const struct soc_enum isabelle_vtx_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), + SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), +}; + +static const struct snd_kcontrol_new atx_mux_controls = + SOC_DAPM_ENUM("Route", isabelle_atx_enum); + +static const struct snd_kcontrol_new vtx_mux_controls = + SOC_DAPM_ENUM("Route", isabelle_vtx_enum); + +/* Left analog microphone selection */ +static const char *isabelle_amic1_texts[] = { + "Main Mic", "Headset Mic", "Aux/FM Left"}; + +/* Left analog microphone selection */ +static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; + +static const struct soc_enum isabelle_amic1_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, + ARRAY_SIZE(isabelle_amic1_texts), + isabelle_amic1_texts), +}; + +static const struct soc_enum isabelle_amic2_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, + ARRAY_SIZE(isabelle_amic2_texts), + isabelle_amic2_texts), +}; + +static const struct snd_kcontrol_new amic1_control = + SOC_DAPM_ENUM("Route", isabelle_amic1_enum); + +static const struct snd_kcontrol_new amic2_control = + SOC_DAPM_ENUM("Route", isabelle_amic2_enum); + +static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"}; + +static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; + +static const struct soc_enum isabelle_st_audio_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, + isabelle_st_audio_texts), + SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, + isabelle_st_audio_texts), +}; + +static const struct soc_enum isabelle_st_voice_enum[] = { + SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, + isabelle_st_voice_texts), + SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, + isabelle_st_voice_texts), +}; + +static const struct snd_kcontrol_new st_audio_control = + SOC_DAPM_ENUM("Route", isabelle_st_audio_enum); + +static const struct snd_kcontrol_new st_voice_control = + SOC_DAPM_ENUM("Route", isabelle_st_voice_enum); + +/* Mixer controls */ +static const struct snd_kcontrol_new isabelle_hs_left_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC1L Playback Switch", ISABELLE_HSDRV_CFG1_REG, 7, 1, 0), +SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_hs_right_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC1R Playback Switch", ISABELLE_HSDRV_CFG1_REG, 5, 1, 0), +SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 4, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_hf_left_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_HFLPGA_CFG_REG, 7, 1, 0), +SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HFLPGA_CFG_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_hf_right_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC2R Playback Switch", ISABELLE_HFRPGA_CFG_REG, 7, 1, 0), +SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HFRPGA_CFG_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_ep_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_EARDRV_CFG1_REG, 7, 1, 0), +SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_EARDRV_CFG1_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_aux_left_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC3L Playback Switch", ISABELLE_LINEAMP_CFG_REG, 7, 1, 0), +SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_aux_right_mixer_controls[] = { +SOC_DAPM_SINGLE("DAC3R Playback Switch", ISABELLE_LINEAMP_CFG_REG, 5, 1, 0), +SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 4, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_dpga1_left_mixer_controls[] = { +SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 7, 1, 0), +SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 6, 1, 0), +SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 5, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_dpga1_right_mixer_controls[] = { +SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 3, 1, 0), +SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 2, 1, 0), +SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 1, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_dpga2_left_mixer_controls[] = { +SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 7, 1, 0), +SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 6, 1, 0), +SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 5, 1, 0), +SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 4, 1, 0), +SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 3, 1, 0), +SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 2, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_dpga2_right_mixer_controls[] = { +SOC_DAPM_SINGLE("USNC Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 7, 1, 0), +SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 3, 1, 0), +SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 2, 1, 0), +SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 1, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_dpga3_left_mixer_controls[] = { +SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 7, 1, 0), +SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 6, 1, 0), +SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 5, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_dpga3_right_mixer_controls[] = { +SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 3, 1, 0), +SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 2, 1, 0), +SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 1, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_rx1_mixer_controls[] = { +SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 7, 1, 0), +SOC_DAPM_SINGLE("DL1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_rx2_mixer_controls[] = { +SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 5, 1, 0), +SOC_DAPM_SINGLE("DL2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 4, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_rx3_mixer_controls[] = { +SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 3, 1, 0), +SOC_DAPM_SINGLE("DL3 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 2, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_rx4_mixer_controls[] = { +SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 1, 1, 0), +SOC_DAPM_SINGLE("DL4 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 0, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_rx5_mixer_controls[] = { +SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 7, 1, 0), +SOC_DAPM_SINGLE("DL5 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 6, 1, 0), +}; + +static const struct snd_kcontrol_new isabelle_rx6_mixer_controls[] = { +SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 5, 1, 0), +SOC_DAPM_SINGLE("DL6 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 4, 1, 0), +}; + +static const struct snd_kcontrol_new ep_path_enable_control = + SOC_DAPM_SINGLE("Switch", ISABELLE_EARDRV_CFG2_REG, 0, 1, 0); + +/* TLV Declarations */ +static const DECLARE_TLV_DB_SCALE(mic_amp_tlv, 0, 100, 0); +static const DECLARE_TLV_DB_SCALE(afm_amp_tlv, -3300, 300, 0); +static const DECLARE_TLV_DB_SCALE(dac_tlv, -1200, 200, 0); +static const DECLARE_TLV_DB_SCALE(hf_tlv, -5000, 200, 0); + +/* from -63 to 0 dB in 1 dB steps */ +static const DECLARE_TLV_DB_SCALE(dpga_tlv, -6300, 100, 1); + +/* from -63 to 9 dB in 1 dB steps */ +static const DECLARE_TLV_DB_SCALE(rx_tlv, -6300, 100, 1); + +static const DECLARE_TLV_DB_SCALE(st_tlv, -2700, 300, 1); +static const DECLARE_TLV_DB_SCALE(tx_tlv, -600, 100, 0); + +static const struct snd_kcontrol_new isabelle_snd_controls[] = { + SOC_DOUBLE_TLV("Headset Playback Volume", ISABELLE_HSDRV_GAIN_REG, + 4, 0, 0xF, 0, dac_tlv), + SOC_DOUBLE_R_TLV("Handsfree Playback Volume", + ISABELLE_HFLPGA_CFG_REG, ISABELLE_HFRPGA_CFG_REG, + 0, 0x1F, 0, hf_tlv), + SOC_DOUBLE_TLV("Aux Playback Volume", ISABELLE_LINEAMP_GAIN_REG, + 4, 0, 0xF, 0, dac_tlv), + SOC_SINGLE_TLV("Earpiece Playback Volume", ISABELLE_EARDRV_CFG1_REG, + 0, 0xF, 0, dac_tlv), + + SOC_DOUBLE_TLV("Aux FM Volume", ISABELLE_APGA_GAIN_REG, 4, 0, 0xF, 0, + afm_amp_tlv), + SOC_SINGLE_TLV("Mic1 Capture Volume", ISABELLE_MIC1_GAIN_REG, 3, 0x1F, + 0, mic_amp_tlv), + SOC_SINGLE_TLV("Mic2 Capture Volume", ISABELLE_MIC2_GAIN_REG, 3, 0x1F, + 0, mic_amp_tlv), + + SOC_DOUBLE_R_TLV("DPGA1 Volume", ISABELLE_DPGA1L_GAIN_REG, + ISABELLE_DPGA1R_GAIN_REG, 0, 0x3F, 0, dpga_tlv), + SOC_DOUBLE_R_TLV("DPGA2 Volume", ISABELLE_DPGA2L_GAIN_REG, + ISABELLE_DPGA2R_GAIN_REG, 0, 0x3F, 0, dpga_tlv), + SOC_DOUBLE_R_TLV("DPGA3 Volume", ISABELLE_DPGA3L_GAIN_REG, + ISABELLE_DPGA3R_GAIN_REG, 0, 0x3F, 0, dpga_tlv), + + SOC_SINGLE_TLV("Sidetone Audio TX1 Volume", + ISABELLE_ATX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv), + SOC_SINGLE_TLV("Sidetone Audio TX2 Volume", + ISABELLE_ATX_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv), + SOC_SINGLE_TLV("Sidetone Voice TX1 Volume", + ISABELLE_VTX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv), + SOC_SINGLE_TLV("Sidetone Voice TX2 Volume", + ISABELLE_VTX2_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv), + + SOC_SINGLE_TLV("Audio TX1 Volume", ISABELLE_ATX1_DPGA_REG, 4, 0xF, 0, + tx_tlv), + SOC_SINGLE_TLV("Audio TX2 Volume", ISABELLE_ATX2_DPGA_REG, 4, 0xF, 0, + tx_tlv), + SOC_SINGLE_TLV("Voice TX1 Volume", ISABELLE_VTX1_DPGA_REG, 4, 0xF, 0, + tx_tlv), + SOC_SINGLE_TLV("Voice TX2 Volume", ISABELLE_VTX2_DPGA_REG, 4, 0xF, 0, + tx_tlv), + + SOC_SINGLE_TLV("RX1 DPGA Volume", ISABELLE_RX1_DPGA_REG, 0, 0x3F, 0, + rx_tlv), + SOC_SINGLE_TLV("RX2 DPGA Volume", ISABELLE_RX2_DPGA_REG, 0, 0x3F, 0, + rx_tlv), + SOC_SINGLE_TLV("RX3 DPGA Volume", ISABELLE_RX3_DPGA_REG, 0, 0x3F, 0, + rx_tlv), + SOC_SINGLE_TLV("RX4 DPGA Volume", ISABELLE_RX4_DPGA_REG, 0, 0x3F, 0, + rx_tlv), + SOC_SINGLE_TLV("RX5 DPGA Volume", ISABELLE_RX5_DPGA_REG, 0, 0x3F, 0, + rx_tlv), + SOC_SINGLE_TLV("RX6 DPGA Volume", ISABELLE_RX6_DPGA_REG, 0, 0x3F, 0, + rx_tlv), + + SOC_SINGLE("Headset Noise Gate", ISABELLE_HS_NG_CFG1_REG, 7, 1, 0), + SOC_SINGLE("Handsfree Noise Gate", ISABELLE_HF_NG_CFG1_REG, 7, 1, 0), + + SOC_SINGLE("ATX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 7, 1, 0), + SOC_SINGLE("ATX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 6, 1, 0), + SOC_SINGLE("ARX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 5, 1, 0), + SOC_SINGLE("ARX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 4, 1, 0), + SOC_SINGLE("ARX3 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 3, 1, 0), + SOC_SINGLE("ARX4 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 2, 1, 0), + SOC_SINGLE("ARX5 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 1, 1, 0), + SOC_SINGLE("ARX6 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 0, 1, 0), + SOC_SINGLE("VRX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 3, 1, 0), + SOC_SINGLE("VRX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, + 2, 1, 0), + + SOC_SINGLE("ATX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, + 7, 1, 0), + SOC_SINGLE("ATX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, + 6, 1, 0), + SOC_SINGLE("VTX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, + 5, 1, 0), + SOC_SINGLE("VTX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, + 4, 1, 0), + SOC_SINGLE("RX1 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, + 5, 1, 0), + SOC_SINGLE("RX2 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, + 4, 1, 0), + SOC_SINGLE("RX3 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, + 3, 1, 0), + SOC_SINGLE("RX4 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, + 2, 1, 0), + SOC_SINGLE("RX5 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, + 1, 1, 0), + SOC_SINGLE("RX6 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, + 0, 1, 0), + + SOC_SINGLE("ULATX12 Capture Switch", ISABELLE_ULATX12_INTF_CFG_REG, + 7, 1, 0), + + SOC_SINGLE("DL12 Playback Switch", ISABELLE_DL12_INTF_CFG_REG, + 7, 1, 0), + SOC_SINGLE("DL34 Playback Switch", ISABELLE_DL34_INTF_CFG_REG, + 7, 1, 0), + SOC_SINGLE("DL56 Playback Switch", ISABELLE_DL56_INTF_CFG_REG, + 7, 1, 0), + + /* DMIC Switch */ + SOC_SINGLE("DMIC Switch", ISABELLE_DMIC_CFG_REG, 0, 1, 0), +}; + +static const struct snd_soc_dapm_widget isabelle_dapm_widgets[] = { + /* Inputs */ + SND_SOC_DAPM_INPUT("MAINMIC"), + SND_SOC_DAPM_INPUT("HSMIC"), + SND_SOC_DAPM_INPUT("SUBMIC"), + SND_SOC_DAPM_INPUT("LINEIN1"), + SND_SOC_DAPM_INPUT("LINEIN2"), + SND_SOC_DAPM_INPUT("DMICDAT"), + + /* Outputs */ + SND_SOC_DAPM_OUTPUT("HSOL"), + SND_SOC_DAPM_OUTPUT("HSOR"), + SND_SOC_DAPM_OUTPUT("HFL"), + SND_SOC_DAPM_OUTPUT("HFR"), + SND_SOC_DAPM_OUTPUT("EP"), + SND_SOC_DAPM_OUTPUT("LINEOUT1"), + SND_SOC_DAPM_OUTPUT("LINEOUT2"), + + SND_SOC_DAPM_PGA("DL1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DL2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DL3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DL4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DL5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DL6", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* Analog input muxes for the capture amplifiers */ + SND_SOC_DAPM_MUX("Analog Left Capture Route", + SND_SOC_NOPM, 0, 0, &amic1_control), + SND_SOC_DAPM_MUX("Analog Right Capture Route", + SND_SOC_NOPM, 0, 0, &amic2_control), + + SND_SOC_DAPM_MUX("Sidetone Audio Playback", SND_SOC_NOPM, 0, 0, + &st_audio_control), + SND_SOC_DAPM_MUX("Sidetone Voice Playback", SND_SOC_NOPM, 0, 0, + &st_voice_control), + + /* AIF */ + SND_SOC_DAPM_AIF_IN("INTF1_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 7, 0), + SND_SOC_DAPM_AIF_IN("INTF2_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 6, 0), + + SND_SOC_DAPM_AIF_OUT("INTF1_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 5, 0), + SND_SOC_DAPM_AIF_OUT("INTF2_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 4, 0), + + SND_SOC_DAPM_OUT_DRV("ULATX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("ULATX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("ULVTX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("ULVTX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* Analog Capture PGAs */ + SND_SOC_DAPM_PGA("MicAmp1", ISABELLE_AMIC_CFG_REG, 5, 0, NULL, 0), + SND_SOC_DAPM_PGA("MicAmp2", ISABELLE_AMIC_CFG_REG, 4, 0, NULL, 0), + + /* Auxiliary FM PGAs */ + SND_SOC_DAPM_PGA("APGA1", ISABELLE_APGA_CFG_REG, 7, 0, NULL, 0), + SND_SOC_DAPM_PGA("APGA2", ISABELLE_APGA_CFG_REG, 6, 0, NULL, 0), + + /* ADCs */ + SND_SOC_DAPM_ADC("ADC1", "Left Front Capture", + ISABELLE_AMIC_CFG_REG, 7, 0), + SND_SOC_DAPM_ADC("ADC2", "Right Front Capture", + ISABELLE_AMIC_CFG_REG, 6, 0), + + /* Microphone Bias */ + SND_SOC_DAPM_SUPPLY("Headset Mic Bias", ISABELLE_ABIAS_CFG_REG, + 3, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Main Mic Bias", ISABELLE_ABIAS_CFG_REG, + 2, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias", + ISABELLE_DBIAS_CFG_REG, 3, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias", + ISABELLE_DBIAS_CFG_REG, 2, 0, NULL, 0), + + /* Mixers */ + SND_SOC_DAPM_MIXER("Headset Left Mixer", SND_SOC_NOPM, 0, 0, + isabelle_hs_left_mixer_controls, + ARRAY_SIZE(isabelle_hs_left_mixer_controls)), + SND_SOC_DAPM_MIXER("Headset Right Mixer", SND_SOC_NOPM, 0, 0, + isabelle_hs_right_mixer_controls, + ARRAY_SIZE(isabelle_hs_right_mixer_controls)), + SND_SOC_DAPM_MIXER("Handsfree Left Mixer", SND_SOC_NOPM, 0, 0, + isabelle_hf_left_mixer_controls, + ARRAY_SIZE(isabelle_hf_left_mixer_controls)), + SND_SOC_DAPM_MIXER("Handsfree Right Mixer", SND_SOC_NOPM, 0, 0, + isabelle_hf_right_mixer_controls, + ARRAY_SIZE(isabelle_hf_right_mixer_controls)), + SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_aux_left_mixer_controls, + ARRAY_SIZE(isabelle_aux_left_mixer_controls)), + SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_aux_right_mixer_controls, + ARRAY_SIZE(isabelle_aux_right_mixer_controls)), + SND_SOC_DAPM_MIXER("Earphone Mixer", SND_SOC_NOPM, 0, 0, + isabelle_ep_mixer_controls, + ARRAY_SIZE(isabelle_ep_mixer_controls)), + + SND_SOC_DAPM_MIXER("DPGA1L Mixer", SND_SOC_NOPM, 0, 0, + isabelle_dpga1_left_mixer_controls, + ARRAY_SIZE(isabelle_dpga1_left_mixer_controls)), + SND_SOC_DAPM_MIXER("DPGA1R Mixer", SND_SOC_NOPM, 0, 0, + isabelle_dpga1_right_mixer_controls, + ARRAY_SIZE(isabelle_dpga1_right_mixer_controls)), + SND_SOC_DAPM_MIXER("DPGA2L Mixer", SND_SOC_NOPM, 0, 0, + isabelle_dpga2_left_mixer_controls, + ARRAY_SIZE(isabelle_dpga2_left_mixer_controls)), + SND_SOC_DAPM_MIXER("DPGA2R Mixer", SND_SOC_NOPM, 0, 0, + isabelle_dpga2_right_mixer_controls, + ARRAY_SIZE(isabelle_dpga2_right_mixer_controls)), + SND_SOC_DAPM_MIXER("DPGA3L Mixer", SND_SOC_NOPM, 0, 0, + isabelle_dpga3_left_mixer_controls, + ARRAY_SIZE(isabelle_dpga3_left_mixer_controls)), + SND_SOC_DAPM_MIXER("DPGA3R Mixer", SND_SOC_NOPM, 0, 0, + isabelle_dpga3_right_mixer_controls, + ARRAY_SIZE(isabelle_dpga3_right_mixer_controls)), + + SND_SOC_DAPM_MIXER("RX1 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_rx1_mixer_controls, + ARRAY_SIZE(isabelle_rx1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX2 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_rx2_mixer_controls, + ARRAY_SIZE(isabelle_rx2_mixer_controls)), + SND_SOC_DAPM_MIXER("RX3 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_rx3_mixer_controls, + ARRAY_SIZE(isabelle_rx3_mixer_controls)), + SND_SOC_DAPM_MIXER("RX4 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_rx4_mixer_controls, + ARRAY_SIZE(isabelle_rx4_mixer_controls)), + SND_SOC_DAPM_MIXER("RX5 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_rx5_mixer_controls, + ARRAY_SIZE(isabelle_rx5_mixer_controls)), + SND_SOC_DAPM_MIXER("RX6 Mixer", SND_SOC_NOPM, 0, 0, + isabelle_rx6_mixer_controls, + ARRAY_SIZE(isabelle_rx6_mixer_controls)), + + /* DACs */ + SND_SOC_DAPM_DAC("DAC1L", "Headset Playback", ISABELLE_DAC_CFG_REG, + 5, 0), + SND_SOC_DAPM_DAC("DAC1R", "Headset Playback", ISABELLE_DAC_CFG_REG, + 4, 0), + SND_SOC_DAPM_DAC("DAC2L", "Handsfree Playback", ISABELLE_DAC_CFG_REG, + 3, 0), + SND_SOC_DAPM_DAC("DAC2R", "Handsfree Playback", ISABELLE_DAC_CFG_REG, + 2, 0), + SND_SOC_DAPM_DAC("DAC3L", "Lineout Playback", ISABELLE_DAC_CFG_REG, + 1, 0), + SND_SOC_DAPM_DAC("DAC3R", "Lineout Playback", ISABELLE_DAC_CFG_REG, + 0, 0), + + /* Analog Playback PGAs */ + SND_SOC_DAPM_PGA("Sidetone Audio PGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("Sidetone Voice PGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("HF Left PGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("HF Right PGA", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DPGA1L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DPGA1R", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DPGA2L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DPGA2R", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DPGA3L", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DPGA3R", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* Analog Playback Mux */ + SND_SOC_DAPM_MUX("RX1 Playback", ISABELLE_ALU_RX_EN_REG, 5, 0, + &rx1_mux_controls), + SND_SOC_DAPM_MUX("RX2 Playback", ISABELLE_ALU_RX_EN_REG, 4, 0, + &rx2_mux_controls), + + /* TX Select */ + SND_SOC_DAPM_MUX("ATX Select", ISABELLE_TX_INPUT_CFG_REG, + 7, 0, &atx_mux_controls), + SND_SOC_DAPM_MUX("VTX Select", ISABELLE_TX_INPUT_CFG_REG, + 6, 0, &vtx_mux_controls), + + SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, + &ep_path_enable_control), + + /* Output Drivers */ + SND_SOC_DAPM_OUT_DRV("HS Left Driver", ISABELLE_HSDRV_CFG2_REG, + 1, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("HS Right Driver", ISABELLE_HSDRV_CFG2_REG, + 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("LINEOUT1 Left Driver", ISABELLE_LINEAMP_CFG_REG, + 1, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("LINEOUT2 Right Driver", ISABELLE_LINEAMP_CFG_REG, + 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("Earphone Driver", ISABELLE_EARDRV_CFG2_REG, + 1, 0, NULL, 0), + + SND_SOC_DAPM_OUT_DRV("HF Left Driver", ISABELLE_HFDRV_CFG_REG, + 1, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("HF Right Driver", ISABELLE_HFDRV_CFG_REG, + 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route isabelle_intercon[] = { + /* Interface mapping */ + { "DL1", "DL12 Playback Switch", "INTF1_SDI" }, + { "DL2", "DL12 Playback Switch", "INTF1_SDI" }, + { "DL3", "DL34 Playback Switch", "INTF1_SDI" }, + { "DL4", "DL34 Playback Switch", "INTF1_SDI" }, + { "DL5", "DL56 Playback Switch", "INTF1_SDI" }, + { "DL6", "DL56 Playback Switch", "INTF1_SDI" }, + + { "DL1", "DL12 Playback Switch", "INTF2_SDI" }, + { "DL2", "DL12 Playback Switch", "INTF2_SDI" }, + { "DL3", "DL34 Playback Switch", "INTF2_SDI" }, + { "DL4", "DL34 Playback Switch", "INTF2_SDI" }, + { "DL5", "DL56 Playback Switch", "INTF2_SDI" }, + { "DL6", "DL56 Playback Switch", "INTF2_SDI" }, + + /* Input side mapping */ + { "Sidetone Audio PGA", NULL, "Sidetone Audio Playback" }, + { "Sidetone Voice PGA", NULL, "Sidetone Voice Playback" }, + + { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Audio PGA" }, + + { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" }, + { "RX1 Mixer", "DL1 Playback Switch", "DL1" }, + + { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Audio PGA" }, + + { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" }, + { "RX2 Mixer", "DL2 Playback Switch", "DL2" }, + + { "RX3 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" }, + { "RX3 Mixer", "DL3 Playback Switch", "DL3" }, + + { "RX4 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" }, + { "RX4 Mixer", "DL4 Playback Switch", "DL4" }, + + { "RX5 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" }, + { "RX5 Mixer", "DL5 Playback Switch", "DL5" }, + + { "RX6 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" }, + { "RX6 Mixer", "DL6 Playback Switch", "DL6" }, + + /* Capture path */ + { "Analog Left Capture Route", "Headset Mic", "HSMIC" }, + { "Analog Left Capture Route", "Main Mic", "MAINMIC" }, + { "Analog Left Capture Route", "Aux/FM Left", "LINEIN1" }, + + { "Analog Right Capture Route", "Sub Mic", "SUBMIC" }, + { "Analog Right Capture Route", "Aux/FM Right", "LINEIN2" }, + + { "MicAmp1", NULL, "Analog Left Capture Route" }, + { "MicAmp2", NULL, "Analog Right Capture Route" }, + + { "ADC1", NULL, "MicAmp1" }, + { "ADC2", NULL, "MicAmp2" }, + + { "ATX Select", "AMIC1", "ADC1" }, + { "ATX Select", "DMIC", "DMICDAT" }, + { "ATX Select", "AMIC2", "ADC2" }, + + { "VTX Select", "AMIC1", "ADC1" }, + { "VTX Select", "DMIC", "DMICDAT" }, + { "VTX Select", "AMIC2", "ADC2" }, + + { "ULATX1", "ATX1 Filter Enable Switch", "ATX Select" }, + { "ULATX1", "ATX1 Filter Bypass Switch", "ATX Select" }, + { "ULATX2", "ATX2 Filter Enable Switch", "ATX Select" }, + { "ULATX2", "ATX2 Filter Bypass Switch", "ATX Select" }, + + { "ULVTX1", "VTX1 Filter Enable Switch", "VTX Select" }, + { "ULVTX1", "VTX1 Filter Bypass Switch", "VTX Select" }, + { "ULVTX2", "VTX2 Filter Enable Switch", "VTX Select" }, + { "ULVTX2", "VTX2 Filter Bypass Switch", "VTX Select" }, + + { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX1" }, + { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX2" }, + { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX1" }, + { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX2" }, + + { "INTF1_SDO", NULL, "ULVTX1" }, + { "INTF1_SDO", NULL, "ULVTX2" }, + { "INTF2_SDO", NULL, "ULVTX1" }, + { "INTF2_SDO", NULL, "ULVTX2" }, + + /* AFM Path */ + { "APGA1", NULL, "LINEIN1" }, + { "APGA2", NULL, "LINEIN2" }, + + { "RX1 Playback", "VRX1 Filter Bypass Switch", "RX1 Mixer" }, + { "RX1 Playback", "ARX1 Filter Bypass Switch", "RX1 Mixer" }, + { "RX1 Playback", "RX1 Filter Enable Switch", "RX1 Mixer" }, + + { "RX2 Playback", "VRX2 Filter Bypass Switch", "RX2 Mixer" }, + { "RX2 Playback", "ARX2 Filter Bypass Switch", "RX2 Mixer" }, + { "RX2 Playback", "RX2 Filter Enable Switch", "RX2 Mixer" }, + + { "RX3 Playback", "ARX3 Filter Bypass Switch", "RX3 Mixer" }, + { "RX3 Playback", "RX3 Filter Enable Switch", "RX3 Mixer" }, + + { "RX4 Playback", "ARX4 Filter Bypass Switch", "RX4 Mixer" }, + { "RX4 Playback", "RX4 Filter Enable Switch", "RX4 Mixer" }, + + { "RX5 Playback", "ARX5 Filter Bypass Switch", "RX5 Mixer" }, + { "RX5 Playback", "RX5 Filter Enable Switch", "RX5 Mixer" }, + + { "RX6 Playback", "ARX6 Filter Bypass Switch", "RX6 Mixer" }, + { "RX6 Playback", "RX6 Filter Enable Switch", "RX6 Mixer" }, + + { "DPGA1L Mixer", "RX1 Playback Switch", "RX1 Playback" }, + { "DPGA1L Mixer", "RX3 Playback Switch", "RX3 Playback" }, + { "DPGA1L Mixer", "RX5 Playback Switch", "RX5 Playback" }, + + { "DPGA1R Mixer", "RX2 Playback Switch", "RX2 Playback" }, + { "DPGA1R Mixer", "RX4 Playback Switch", "RX4 Playback" }, + { "DPGA1R Mixer", "RX6 Playback Switch", "RX6 Playback" }, + + { "DPGA1L", NULL, "DPGA1L Mixer" }, + { "DPGA1R", NULL, "DPGA1R Mixer" }, + + { "DAC1L", NULL, "DPGA1L" }, + { "DAC1R", NULL, "DPGA1R" }, + + { "DPGA2L Mixer", "RX1 Playback Switch", "RX1 Playback" }, + { "DPGA2L Mixer", "RX2 Playback Switch", "RX2 Playback" }, + { "DPGA2L Mixer", "RX3 Playback Switch", "RX3 Playback" }, + { "DPGA2L Mixer", "RX4 Playback Switch", "RX4 Playback" }, + { "DPGA2L Mixer", "RX5 Playback Switch", "RX5 Playback" }, + { "DPGA2L Mixer", "RX6 Playback Switch", "RX6 Playback" }, + + { "DPGA2R Mixer", "RX2 Playback Switch", "RX2 Playback" }, + { "DPGA2R Mixer", "RX4 Playback Switch", "RX4 Playback" }, + { "DPGA2R Mixer", "RX6 Playback Switch", "RX6 Playback" }, + + { "DPGA2L", NULL, "DPGA2L Mixer" }, + { "DPGA2R", NULL, "DPGA2R Mixer" }, + + { "DAC2L", NULL, "DPGA2L" }, + { "DAC2R", NULL, "DPGA2R" }, + + { "DPGA3L Mixer", "RX1 Playback Switch", "RX1 Playback" }, + { "DPGA3L Mixer", "RX3 Playback Switch", "RX3 Playback" }, + { "DPGA3L Mixer", "RX5 Playback Switch", "RX5 Playback" }, + + { "DPGA3R Mixer", "RX2 Playback Switch", "RX2 Playback" }, + { "DPGA3R Mixer", "RX4 Playback Switch", "RX4 Playback" }, + { "DPGA3R Mixer", "RX6 Playback Switch", "RX6 Playback" }, + + { "DPGA3L", NULL, "DPGA3L Mixer" }, + { "DPGA3R", NULL, "DPGA3R Mixer" }, + + { "DAC3L", NULL, "DPGA3L" }, + { "DAC3R", NULL, "DPGA3R" }, + + { "Headset Left Mixer", "DAC1L Playback Switch", "DAC1L" }, + { "Headset Left Mixer", "APGA1 Playback Switch", "APGA1" }, + + { "Headset Right Mixer", "DAC1R Playback Switch", "DAC1R" }, + { "Headset Right Mixer", "APGA2 Playback Switch", "APGA2" }, + + { "HS Left Driver", NULL, "Headset Left Mixer" }, + { "HS Right Driver", NULL, "Headset Right Mixer" }, + + { "HSOL", NULL, "HS Left Driver" }, + { "HSOR", NULL, "HS Right Driver" }, + + /* Earphone playback path */ + { "Earphone Mixer", "DAC2L Playback Switch", "DAC2L" }, + { "Earphone Mixer", "APGA1 Playback Switch", "APGA1" }, + + { "Earphone Playback", "Switch", "Earphone Mixer" }, + { "Earphone Driver", NULL, "Earphone Playback" }, + { "EP", NULL, "Earphone Driver" }, + + { "Handsfree Left Mixer", "DAC2L Playback Switch", "DAC2L" }, + { "Handsfree Left Mixer", "APGA1 Playback Switch", "APGA1" }, + + { "Handsfree Right Mixer", "DAC2R Playback Switch", "DAC2R" }, + { "Handsfree Right Mixer", "APGA2 Playback Switch", "APGA2" }, + + { "HF Left PGA", NULL, "Handsfree Left Mixer" }, + { "HF Right PGA", NULL, "Handsfree Right Mixer" }, + + { "HF Left Driver", NULL, "HF Left PGA" }, + { "HF Right Driver", NULL, "HF Right PGA" }, + + { "HFL", NULL, "HF Left Driver" }, + { "HFR", NULL, "HF Right Driver" }, + + { "LINEOUT1 Mixer", "DAC3L Playback Switch", "DAC3L" }, + { "LINEOUT1 Mixer", "APGA1 Playback Switch", "APGA1" }, + + { "LINEOUT2 Mixer", "DAC3R Playback Switch", "DAC3R" }, + { "LINEOUT2 Mixer", "APGA2 Playback Switch", "APGA2" }, + + { "LINEOUT1 Driver", NULL, "LINEOUT1 Mixer" }, + { "LINEOUT2 Driver", NULL, "LINEOUT2 Mixer" }, + + { "LINEOUT1", NULL, "LINEOUT1 Driver" }, + { "LINEOUT2", NULL, "LINEOUT2 Driver" }, +}; + +static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute) +{ + snd_soc_update_bits(dai->codec, ISABELLE_DAC1_SOFTRAMP_REG, + BIT(4), (mute ? BIT(4) : 0)); + + return 0; +} + +static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute) +{ + snd_soc_update_bits(dai->codec, ISABELLE_DAC2_SOFTRAMP_REG, + BIT(4), (mute ? BIT(4) : 0)); + + return 0; +} + +static int isabelle_line_mute(struct snd_soc_dai *dai, int mute) +{ + snd_soc_update_bits(dai->codec, ISABELLE_DAC3_SOFTRAMP_REG, + BIT(4), (mute ? BIT(4) : 0)); + + return 0; +} + +static int isabelle_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + break; + case SND_SOC_BIAS_PREPARE: + break; + + case SND_SOC_BIAS_STANDBY: + snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG, + ISABELLE_CHIP_EN, BIT(0)); + break; + + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG, + ISABELLE_CHIP_EN, 0); + break; + } + + codec->dapm.bias_level = level; + + return 0; +} + +static int isabelle_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + u16 aif = 0; + unsigned int fs_val = 0; + + switch (params_rate(params)) { + case 8000: + fs_val = ISABELLE_FS_RATE_8; + break; + case 11025: + fs_val = ISABELLE_FS_RATE_11; + break; + case 12000: + fs_val = ISABELLE_FS_RATE_12; + break; + case 16000: + fs_val = ISABELLE_FS_RATE_16; + break; + case 22050: + fs_val = ISABELLE_FS_RATE_22; + break; + case 24000: + fs_val = ISABELLE_FS_RATE_24; + break; + case 32000: + fs_val = ISABELLE_FS_RATE_32; + break; + case 44100: + fs_val = ISABELLE_FS_RATE_44; + break; + case 48000: + fs_val = ISABELLE_FS_RATE_48; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, ISABELLE_FS_RATE_CFG_REG, + ISABELLE_FS_RATE_MASK, fs_val); + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S20_3LE: + aif |= ISABELLE_AIF_LENGTH_20; + break; + case SNDRV_PCM_FORMAT_S32_LE: + aif |= ISABELLE_AIF_LENGTH_32; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG, + ISABELLE_AIF_LENGTH_MASK, aif); + + return 0; +} + +static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + unsigned int aif_val = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + aif_val &= ~ISABELLE_AIF_MS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + aif_val |= ISABELLE_AIF_MS; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + aif_val |= ISABELLE_I2S_MODE; + break; + case SND_SOC_DAIFMT_LEFT_J: + aif_val |= ISABELLE_LEFT_J_MODE; + break; + case SND_SOC_DAIFMT_PDM: + aif_val |= ISABELLE_PDM_MODE; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG, + (ISABELLE_AIF_MS | ISABELLE_AIF_FMT_MASK), aif_val); + + return 0; +} + +/* Rates supported by Isabelle driver */ +#define ISABELLE_RATES SNDRV_PCM_RATE_8000_48000 + +/* Formates supported by Isabelle driver. */ +#define ISABELLE_FORMATS (SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops isabelle_hs_dai_ops = { + .hw_params = isabelle_hw_params, + .set_fmt = isabelle_set_dai_fmt, + .digital_mute = isabelle_hs_mute, +}; + +static struct snd_soc_dai_ops isabelle_hf_dai_ops = { + .hw_params = isabelle_hw_params, + .set_fmt = isabelle_set_dai_fmt, + .digital_mute = isabelle_hf_mute, +}; + +static struct snd_soc_dai_ops isabelle_line_dai_ops = { + .hw_params = isabelle_hw_params, + .set_fmt = isabelle_set_dai_fmt, + .digital_mute = isabelle_line_mute, +}; + +static struct snd_soc_dai_ops isabelle_ul_dai_ops = { + .hw_params = isabelle_hw_params, + .set_fmt = isabelle_set_dai_fmt, +}; + +/* ISABELLE dai structure */ +struct snd_soc_dai_driver isabelle_dai[] = { + { + .name = "isabelle-dl1", + .playback = { + .stream_name = "Headset Playback", + .channels_min = 1, + .channels_max = 2, + .rates = ISABELLE_RATES, + .formats = ISABELLE_FORMATS, + }, + .ops = &isabelle_hs_dai_ops, + }, + { + .name = "isabelle-dl2", + .playback = { + .stream_name = "Handsfree Playback", + .channels_min = 1, + .channels_max = 2, + .rates = ISABELLE_RATES, + .formats = ISABELLE_FORMATS, + }, + .ops = &isabelle_hf_dai_ops, + }, + { + .name = "isabelle-lineout", + .playback = { + .stream_name = "Lineout Playback", + .channels_min = 1, + .channels_max = 2, + .rates = ISABELLE_RATES, + .formats = ISABELLE_FORMATS, + }, + .ops = &isabelle_line_dai_ops, + }, + { + .name = "isabelle-ul", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = ISABELLE_RATES, + .formats = ISABELLE_FORMATS, + }, + .ops = &isabelle_ul_dai_ops, + }, +}; + +static int isabelle_probe(struct snd_soc_codec *codec) +{ + int ret = 0; + + codec->control_data = dev_get_regmap(codec->dev, NULL); + + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_isabelle = { + .probe = isabelle_probe, + .set_bias_level = isabelle_set_bias_level, + .controls = isabelle_snd_controls, + .num_controls = ARRAY_SIZE(isabelle_snd_controls), + .dapm_widgets = isabelle_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), + .dapm_routes = isabelle_intercon, + .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), + .idle_bias_off = true, +}; + +static const struct regmap_config isabelle_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = ISABELLE_MAX_REGISTER, + .reg_defaults = isabelle_reg_defs, + .num_reg_defaults = ARRAY_SIZE(isabelle_reg_defs), + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap *isabelle_regmap; + int ret = 0; + + i2c_set_clientdata(i2c, isabelle_regmap); + + isabelle_regmap = devm_regmap_init_i2c(i2c, &isabelle_regmap_config); + if (IS_ERR(isabelle_regmap)) { + ret = PTR_ERR(isabelle_regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_isabelle, isabelle_dai, + ARRAY_SIZE(isabelle_dai)); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); + regmap_exit(dev_get_regmap(&i2c->dev, NULL)); + return ret; + } + + return ret; +} + +static int __devexit isabelle_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + regmap_exit(dev_get_regmap(&client->dev, NULL)); + return 0; +} + +static const struct i2c_device_id isabelle_i2c_id[] = { + { "isabelle", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, isabelle_i2c_id); + +static struct i2c_driver isabelle_i2c_driver = { + .driver = { + .name = "isabelle", + .owner = THIS_MODULE, + }, + .probe = isabelle_i2c_probe, + .remove = __devexit_p(isabelle_i2c_remove), + .id_table = isabelle_i2c_id, +}; + +module_i2c_driver(isabelle_i2c_driver); + +MODULE_DESCRIPTION("ASoC ISABELLE driver"); +MODULE_AUTHOR("Vishwas A Deshpande "); +MODULE_AUTHOR("M R Swami Reddy "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/isabelle.h b/sound/soc/codecs/isabelle.h new file mode 100644 index 000000000000..96d839a8c956 --- /dev/null +++ b/sound/soc/codecs/isabelle.h @@ -0,0 +1,143 @@ +/* + * isabelle.h - Low power high fidelity audio codec driver header file + * + * Copyright (c) 2012 Texas Instruments, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + */ + +#ifndef _ISABELLE_H +#define _ISABELLE_H + +#include + +/* ISABELLE REGISTERS */ + +#define ISABELLE_PWR_CFG_REG 0x01 +#define ISABELLE_PWR_EN_REG 0x02 +#define ISABELLE_PS_EN1_REG 0x03 +#define ISABELLE_INT1_STATUS_REG 0x04 +#define ISABELLE_INT1_MASK_REG 0x05 +#define ISABELLE_INT2_STATUS_REG 0x06 +#define ISABELLE_INT2_MASK_REG 0x07 +#define ISABELLE_HKCTL1_REG 0x08 +#define ISABELLE_HKCTL2_REG 0x09 +#define ISABELLE_HKCTL3_REG 0x0A +#define ISABELLE_ACCDET_STATUS_REG 0x0B +#define ISABELLE_BUTTON_ID_REG 0x0C +#define ISABELLE_PLL_CFG_REG 0x10 +#define ISABELLE_PLL_EN_REG 0x11 +#define ISABELLE_FS_RATE_CFG_REG 0x12 +#define ISABELLE_INTF_CFG_REG 0x13 +#define ISABELLE_INTF_EN_REG 0x14 +#define ISABELLE_ULATX12_INTF_CFG_REG 0x15 +#define ISABELLE_DL12_INTF_CFG_REG 0x16 +#define ISABELLE_DL34_INTF_CFG_REG 0x17 +#define ISABELLE_DL56_INTF_CFG_REG 0x18 +#define ISABELLE_ATX_STPGA1_CFG_REG 0x19 +#define ISABELLE_ATX_STPGA2_CFG_REG 0x1A +#define ISABELLE_VTX_STPGA1_CFG_REG 0x1B +#define ISABELLE_VTX2_STPGA2_CFG_REG 0x1C +#define ISABELLE_ATX1_DPGA_REG 0x1D +#define ISABELLE_ATX2_DPGA_REG 0x1E +#define ISABELLE_VTX1_DPGA_REG 0x1F +#define ISABELLE_VTX2_DPGA_REG 0x20 +#define ISABELLE_TX_INPUT_CFG_REG 0x21 +#define ISABELLE_RX_INPUT_CFG_REG 0x22 +#define ISABELLE_RX_INPUT_CFG2_REG 0x23 +#define ISABELLE_VOICE_HPF_CFG_REG 0x24 +#define ISABELLE_AUDIO_HPF_CFG_REG 0x25 +#define ISABELLE_RX1_DPGA_REG 0x26 +#define ISABELLE_RX2_DPGA_REG 0x27 +#define ISABELLE_RX3_DPGA_REG 0x28 +#define ISABELLE_RX4_DPGA_REG 0x29 +#define ISABELLE_RX5_DPGA_REG 0x2A +#define ISABELLE_RX6_DPGA_REG 0x2B +#define ISABELLE_ALU_TX_EN_REG 0x2C +#define ISABELLE_ALU_RX_EN_REG 0x2D +#define ISABELLE_IIR_RESYNC_REG 0x2E +#define ISABELLE_ABIAS_CFG_REG 0x30 +#define ISABELLE_DBIAS_CFG_REG 0x31 +#define ISABELLE_MIC1_GAIN_REG 0x32 +#define ISABELLE_MIC2_GAIN_REG 0x33 +#define ISABELLE_AMIC_CFG_REG 0x34 +#define ISABELLE_DMIC_CFG_REG 0x35 +#define ISABELLE_APGA_GAIN_REG 0x36 +#define ISABELLE_APGA_CFG_REG 0x37 +#define ISABELLE_TX_GAIN_DLY_REG 0x38 +#define ISABELLE_RX_GAIN_DLY_REG 0x39 +#define ISABELLE_RX_PWR_CTRL_REG 0x3A +#define ISABELLE_DPGA1LR_IN_SEL_REG 0x3B +#define ISABELLE_DPGA1L_GAIN_REG 0x3C +#define ISABELLE_DPGA1R_GAIN_REG 0x3D +#define ISABELLE_DPGA2L_IN_SEL_REG 0x3E +#define ISABELLE_DPGA2R_IN_SEL_REG 0x3F +#define ISABELLE_DPGA2L_GAIN_REG 0x40 +#define ISABELLE_DPGA2R_GAIN_REG 0x41 +#define ISABELLE_DPGA3LR_IN_SEL_REG 0x42 +#define ISABELLE_DPGA3L_GAIN_REG 0x43 +#define ISABELLE_DPGA3R_GAIN_REG 0x44 +#define ISABELLE_DAC1_SOFTRAMP_REG 0x45 +#define ISABELLE_DAC2_SOFTRAMP_REG 0x46 +#define ISABELLE_DAC3_SOFTRAMP_REG 0x47 +#define ISABELLE_DAC_CFG_REG 0x48 +#define ISABELLE_EARDRV_CFG1_REG 0x49 +#define ISABELLE_EARDRV_CFG2_REG 0x4A +#define ISABELLE_HSDRV_GAIN_REG 0x4B +#define ISABELLE_HSDRV_CFG1_REG 0x4C +#define ISABELLE_HSDRV_CFG2_REG 0x4D +#define ISABELLE_HS_NG_CFG1_REG 0x4E +#define ISABELLE_HS_NG_CFG2_REG 0x4F +#define ISABELLE_LINEAMP_GAIN_REG 0x50 +#define ISABELLE_LINEAMP_CFG_REG 0x51 +#define ISABELLE_HFL_VOL_CTRL_REG 0x52 +#define ISABELLE_HFL_SFTVOL_CTRL_REG 0x53 +#define ISABELLE_HFL_LIM_CTRL_1_REG 0x54 +#define ISABELLE_HFL_LIM_CTRL_2_REG 0x55 +#define ISABELLE_HFR_VOL_CTRL_REG 0x56 +#define ISABELLE_HFR_SFTVOL_CTRL_REG 0x57 +#define ISABELLE_HFR_LIM_CTRL_1_REG 0x58 +#define ISABELLE_HFR_LIM_CTRL_2_REG 0x59 +#define ISABELLE_HF_MODE_REG 0x5A +#define ISABELLE_HFLPGA_CFG_REG 0x5B +#define ISABELLE_HFRPGA_CFG_REG 0x5C +#define ISABELLE_HFDRV_CFG_REG 0x5D +#define ISABELLE_PDMOUT_CFG1_REG 0x5E +#define ISABELLE_PDMOUT_CFG2_REG 0x5F +#define ISABELLE_PDMOUT_L_WM_REG 0x60 +#define ISABELLE_PDMOUT_R_WM_REG 0x61 +#define ISABELLE_HF_NG_CFG1_REG 0x62 +#define ISABELLE_HF_NG_CFG2_REG 0x63 + +/* ISABELLE_PWR_EN_REG (0x02h) */ +#define ISABELLE_CHIP_EN BIT(0) + +/* ISABELLE DAI FORMATS */ +#define ISABELLE_AIF_FMT_MASK 0x70 +#define ISABELLE_I2S_MODE 0x0 +#define ISABELLE_LEFT_J_MODE 0x1 +#define ISABELLE_PDM_MODE 0x2 + +#define ISABELLE_AIF_LENGTH_MASK 0x30 +#define ISABELLE_AIF_LENGTH_20 0x00 +#define ISABELLE_AIF_LENGTH_32 0x10 + +#define ISABELLE_AIF_MS 0x80 + +#define ISABELLE_FS_RATE_MASK 0xF +#define ISABELLE_FS_RATE_8 0x0 +#define ISABELLE_FS_RATE_11 0x1 +#define ISABELLE_FS_RATE_12 0x2 +#define ISABELLE_FS_RATE_16 0x4 +#define ISABELLE_FS_RATE_22 0x5 +#define ISABELLE_FS_RATE_24 0x6 +#define ISABELLE_FS_RATE_32 0x8 +#define ISABELLE_FS_RATE_44 0x9 +#define ISABELLE_FS_RATE_48 0xA + +#define ISABELLE_MAX_REGISTER 0xFF + +#endif -- GitLab From 5eba8ec37fe8cfed4cacff56f9025b756cc43faa Mon Sep 17 00:00:00 2001 From: MR Swami Reddy Date: Mon, 4 Jun 2012 17:44:54 +0530 Subject: [PATCH 0492/6849] ASoC: isabelle: Remove regmap_exit() With devm_ APIs regmap_exit() not needed, so remove regmap_exit(). Signed-off-by: Vishwas A Deshpande Signed-off-by: M R Swami Reddy Signed-off-by: Mark Brown --- sound/soc/codecs/isabelle.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index b6921a82fbcc..bcc77ef0eda2 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1141,7 +1141,6 @@ static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, ARRAY_SIZE(isabelle_dai)); if (ret < 0) { dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); - regmap_exit(dev_get_regmap(&i2c->dev, NULL)); return ret; } @@ -1151,7 +1150,6 @@ static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, static int __devexit isabelle_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - regmap_exit(dev_get_regmap(&client->dev, NULL)); return 0; } -- GitLab From 165961efc03159631eadc086877704c7778ac356 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 10:44:23 +0100 Subject: [PATCH 0493/6849] ASoC: dapm: The clock API is even less consistent than thought Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 39e8c2fdf50e..7365fed1ba74 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2904,7 +2904,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } break; case snd_soc_dapm_clock_supply: -#ifdef CONFIG_HAVE_CLK +#ifdef CONFIG_CLKDEV_LOOKUP w->clk = devm_clk_get(dapm->dev, w->name); if (IS_ERR(w->clk)) { ret = PTR_ERR(w->clk); -- GitLab From 571f6a7f07e9dda6c9795398747278e52368c88a Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Mon, 4 Jun 2012 13:19:41 -0500 Subject: [PATCH 0494/6849] ASoC: cs42l73: Convert to devm_regmap_init_i2c() Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l73.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index e0d45fdaa750..2c08c4cb465a 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1362,11 +1362,11 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, i2c_set_clientdata(i2c_client, cs42l73); - cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap); + cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); if (IS_ERR(cs42l73->regmap)) { ret = PTR_ERR(cs42l73->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); - goto err; + return ret; } /* initialize codec */ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); @@ -1384,13 +1384,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, dev_err(&i2c_client->dev, "CS42L73 Device ID (%X). Expected %X\n", devid, CS42L73_DEVID); - goto err_regmap; + return ret; } ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); if (ret < 0) { dev_err(&i2c_client->dev, "Get Revision ID failed\n"); - goto err_regmap; + return ret;; } dev_info(&i2c_client->dev, @@ -1402,23 +1402,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, &soc_codec_dev_cs42l73, cs42l73_dai, ARRAY_SIZE(cs42l73_dai)); if (ret < 0) - goto err_regmap; + return ret; return 0; - -err_regmap: - regmap_exit(cs42l73->regmap); - -err: - return ret; } static __devexit int cs42l73_i2c_remove(struct i2c_client *client) { - struct cs42l73_private *cs42l73 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(cs42l73->regmap); - return 0; } -- GitLab From 134b2f576b9144223dd5b59a496218e3aadaf56b Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Mon, 4 Jun 2012 13:19:42 -0500 Subject: [PATCH 0495/6849] ASoC: cs42l52: Convert to devm_regmap_init_i2c() Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l52.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index ec03abc79a9a..628daf6a1d97 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1216,11 +1216,11 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, return -ENOMEM; cs42l52->dev = &i2c_client->dev; - cs42l52->regmap = regmap_init_i2c(i2c_client, &cs42l52_regmap); + cs42l52->regmap = devm_regmap_init_i2c(i2c_client, &cs42l52_regmap); if (IS_ERR(cs42l52->regmap)) { ret = PTR_ERR(cs42l52->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); - goto err; + return ret; } i2c_set_clientdata(i2c_client, cs42l52); @@ -1242,7 +1242,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, dev_err(&i2c_client->dev, "CS42L52 Device ID (%X). Expected %X\n", devid, CS42L52_CHIP_ID); - goto err_regmap; + return ret; } regcache_cache_only(cs42l52->regmap, true); @@ -1250,23 +1250,13 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_cs42l52, &cs42l52_dai, 1); if (ret < 0) - goto err_regmap; + return ret; return 0; - -err_regmap: - regmap_exit(cs42l52->regmap); - -err: - return ret; } static int cs42l52_i2c_remove(struct i2c_client *client) { - struct cs42l52_private *cs42l52 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(cs42l52->regmap); - return 0; } -- GitLab From 61dc479e99d4d74c6113656dc50babed90a384c5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 11:08:45 +0100 Subject: [PATCH 0496/6849] Revert "ASoC: fsl_ssi: convert to use devm_clk_get" This reverts commit 014e5b56702575c5cd8ffc4b1a7924cfdfe0f1ea since PowerPC doesn't use clkdev and hasn't implemented devm_clk_get() itself. Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index b10a427a8098..4ed2afd47782 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -725,7 +725,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) u32 dma_events[2]; ssi_private->ssi_on_imx = true; - ssi_private->clk = devm_clk_get(&pdev->dev, NULL); + ssi_private->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(ssi_private->clk)) { ret = PTR_ERR(ssi_private->clk); dev_err(&pdev->dev, "could not get clock: %d\n", ret); @@ -842,8 +842,10 @@ error_dev: device_remove_file(&pdev->dev, dev_attr); error_clk: - if (ssi_private->ssi_on_imx) + if (ssi_private->ssi_on_imx) { clk_disable_unprepare(ssi_private->clk); + clk_put(ssi_private->clk); + } error_irq: free_irq(ssi_private->irq, ssi_private); @@ -869,6 +871,7 @@ static int fsl_ssi_remove(struct platform_device *pdev) if (ssi_private->ssi_on_imx) { platform_device_unregister(ssi_private->imx_pcm_pdev); clk_disable_unprepare(ssi_private->clk); + clk_put(ssi_private->clk); } snd_soc_unregister_dai(&pdev->dev); device_remove_file(&pdev->dev, &ssi_private->dev_attr); -- GitLab From f03c4a57cf0cbb4f961bca287f8bdfd3d6eb7e1a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Jun 2012 08:39:52 +0800 Subject: [PATCH 0497/6849] regulator: tps6507x: Remove unused min_uV and max_uV from struct tps_info The min_uV and max_uV are not used in this driver. For table based voltage mappings, we can get min_uV and max_uV by info->table[0] and info->table[table_len -1]. Thus remove min_uV and max_uV from struct tps_info. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6507x-regulator.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c771e1077cc1..eed6678c2906 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -91,8 +91,6 @@ static const unsigned int LDO2_VSEL_table[] = { struct tps_info { const char *name; - unsigned min_uV; - unsigned max_uV; u8 table_len; const unsigned int *table; @@ -103,36 +101,26 @@ struct tps_info { static struct tps_info tps6507x_pmic_regs[] = { { .name = "VDCDC1", - .min_uV = 725000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), .table = VDCDCx_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 725000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), .table = VDCDCx_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 725000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), .table = VDCDCx_VSEL_table, }, { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(LDO1_VSEL_table), .table = LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 725000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(LDO2_VSEL_table), .table = LDO2_VSEL_table, }, -- GitLab From 93b07e7bcd50bb73d3d60043438fa68bd5a0988b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Jun 2012 08:58:13 +0800 Subject: [PATCH 0498/6849] regulator: tps6507x: Avoid duplicating the same mapping table for LDO2 and VDCDCx The voltage mapping table for LDO2 is exactly the same as VDCDCx. Thus we can use one mapping table for both LDO2 and VDCDCx instead of duplicating the mapping table. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6507x-regulator.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index eed6678c2906..07d01ccdf308 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -70,24 +70,8 @@ static const unsigned int LDO1_VSEL_table[] = { 2800000, 3000000, 3100000, 3300000, }; -static const unsigned int LDO2_VSEL_table[] = { - 725000, 750000, 775000, 800000, - 825000, 850000, 875000, 900000, - 925000, 950000, 975000, 1000000, - 1025000, 1050000, 1075000, 1100000, - 1125000, 1150000, 1175000, 1200000, - 1225000, 1250000, 1275000, 1300000, - 1325000, 1350000, 1375000, 1400000, - 1425000, 1450000, 1475000, 1500000, - 1550000, 1600000, 1650000, 1700000, - 1750000, 1800000, 1850000, 1900000, - 1950000, 2000000, 2050000, 2100000, - 2150000, 2200000, 2250000, 2300000, - 2350000, 2400000, 2450000, 2500000, - 2550000, 2600000, 2650000, 2700000, - 2750000, 2800000, 2850000, 2900000, - 3000000, 3100000, 3200000, 3300000, -}; +/* The voltage mapping table for LDO2 is the same as VDCDCx */ +#define LDO2_VSEL_table VDCDCx_VSEL_table struct tps_info { const char *name; -- GitLab From cd86e3ce304189fbdb144622245d0da9189551a1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Jun 2012 18:20:21 +0100 Subject: [PATCH 0499/6849] ASoC: lm59453: Unconstify dai_driver The core fills in some blanks which makes it annoying to do the right thing and constify the calls in the core. Signed-off-by: Mark Brown --- sound/soc/codecs/lm49453.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index c1bc9458906b..99b0a9dcff34 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1357,7 +1357,7 @@ static struct snd_soc_dai_ops lm49453_lineout_dai_ops = { }; /* LM49453 dai structure. */ -static const struct snd_soc_dai_driver lm49453_dai[] = { +static struct snd_soc_dai_driver lm49453_dai[] = { { .name = "LM49453 Headset", .playback = { -- GitLab From 91930652a23de0873a157aa1d9962cb878d64451 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 5 Jun 2012 04:04:11 -0700 Subject: [PATCH 0500/6849] OMAP2+: UART: Add mechanism to probe uart pins and configure rx wakeup The commit (bce492c0 ARM: OMAP2+: UART: Fix incorrect population of default uart pads) removed default uart pads that where getting populated and which was making rx pin wakeup capable. If uart pads were used in different mode by any other module then it would fail since the default pads took over all the uart pins forcefully. With removal of default pads the rx_pad wakeup for console uart while waking up from off mode is broken. Utilise the mux api available to probe the availability of mux pins in uart mode and probe for availability of uart pin in mux mode0 if uart is available as uart pin itself then configure rx pin as wakeup capable. This patch itself doesn't cater to all boards. Boards using uart rx wakeup mechanism should ensure the usage of omap_serial_init_port by configuring required uart ports and pass necessary mux data, till then this probing of uart pins can cater to enabling of rx pad wakeup to most of the boards. This patch can also throw some boot warning from _omap_mux_get_by_name if pin is requested for availability is not present while dynamically probing the uart pins availability such boot warnings can be addressed only when board files are patched with omap_serial_init_port calls passing the right pads needed for a given port. Discussion Threads for reference: http://www.spinics.net/lists/linux-omap/msg69859.html http://www.spinics.net/lists/linux-omap/msg68659.html Cc: Felipe Balbi Cc: Kevin Hilman Cc: Russ Dill Cc: Paul Walmsley Cc: Ameya Palande Signed-off-by: Govindraj.R [tony@atomide.com: updated to fix compile when CONFIG_OMAP_MUX is not set] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/mux.c | 3 +- arch/arm/mach-omap2/mux.h | 11 ++++++ arch/arm/mach-omap2/serial.c | 67 +++++++++++++++++++++++++++++++++--- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 80e55c5c9998..4b46b91cca5c 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -217,8 +217,7 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, return -ENODEV; } -static int __init -omap_mux_get_by_name(const char *muxname, +int __init omap_mux_get_by_name(const char *muxname, struct omap_mux_partition **found_partition, struct omap_mux **found_mux) { diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 69fe060a0b75..471e62a74a16 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -59,6 +59,7 @@ #define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN #define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4) +#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0) /* Flags for omapX_mux_init */ #define OMAP_PACKAGE_MASK 0xffff @@ -225,8 +226,18 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads); */ void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state); +int omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux); #else +static inline int omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux) +{ + return 0; +} + static inline int omap_mux_init_gpio(int gpio, int val) { return 0; diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 292d4aaca068..c1b93c752d70 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -57,6 +57,7 @@ struct omap_uart_state { struct list_head node; struct omap_hwmod *oh; + struct omap_device_pad default_omap_uart_pads[2]; }; static LIST_HEAD(uart_list); @@ -126,11 +127,70 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX -static void omap_serial_fill_default_pads(struct omap_board_data *bdata) + +#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28 +static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN], + tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata; + +static void __init +omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata, + struct omap_uart_state *uart) +{ + uart->default_omap_uart_pads[0].name = rx_pad_name; + uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX | + OMAP_DEVICE_PAD_WAKEUP; + uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT | + OMAP_MUX_MODE0; + uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0; + uart->default_omap_uart_pads[1].name = tx_pad_name; + uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT | + OMAP_MUX_MODE0; + bdata->pads = uart->default_omap_uart_pads; + bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads); +} + +static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, + struct omap_uart_state *uart) { + struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL; + struct omap_mux *rx_mux = NULL, *tx_mux = NULL; + char *rx_fmt, *tx_fmt; + int uart_nr = bdata->id + 1; + + if (bdata->id != 2) { + rx_fmt = "uart%d_rx.uart%d_rx"; + tx_fmt = "uart%d_tx.uart%d_tx"; + } else { + rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx"; + tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx"; + } + + snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt, + uart_nr, uart_nr); + snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt, + uart_nr, uart_nr); + + if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 && + omap_mux_get_by_name + (tx_pad_name, &tx_partition, &tx_mux) >= 0) { + u16 tx_mode, rx_mode; + + tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset); + rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset); + + /* + * Check if uart is used in default tx/rx mode i.e. in mux mode0 + * if yes then configure rx pin for wake up capability + */ + if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode)) + omap_serial_fill_uart_tx_rx_pads(bdata, uart); + } } #else -static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} +static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, + struct omap_uart_state *uart) +{ +} #endif static char *cmdline_find_option(char *str) @@ -287,8 +347,7 @@ void __init omap_serial_board_init(struct omap_uart_port_info *info) bdata.pads = NULL; bdata.pads_cnt = 0; - if (cpu_is_omap44xx() || cpu_is_omap34xx()) - omap_serial_fill_default_pads(&bdata); + omap_serial_check_wakeup(&bdata, uart); if (!info) omap_serial_init_port(&bdata, NULL); -- GitLab From 569ba7d2083681abbfc2f6d6550e74e64833dada Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 30 May 2012 21:58:46 +0200 Subject: [PATCH 0501/6849] s390/kvm: get rid of duplicate instruction After commit 5e8010cb50d3de7202641c0088c211f7c9593ebc s390: replace TIF_SIE with PF_VCPU there is no need to load the thread info before sie_loop where it is also loaded. Get rid of this duplicate instruction. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/entry64.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 229fe1d07749..bf80a5921173 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -974,7 +974,6 @@ ENTRY(sie64a) stg %r3,__SF_EMPTY+8(%r15) # save guest register save area xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 - lg %r14,__LC_THREAD_INFO # pointer thread_info struct sie_loop: lg %r14,__LC_THREAD_INFO # pointer thread_info struct tm __TI_flags+7(%r14),_TIF_EXIT_SIE -- GitLab From 524b24ada792b40e1eb2eae59f7a096f26c3b788 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Jun 2012 12:11:41 +0200 Subject: [PATCH 0502/6849] s390/smp: remove redundant check condition code "status stored" for sigp sense running always implies that only the "not running" status bit is set. Therefore no need to check if it is set. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 15cca26ccb6c..c78074c6cc1d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -158,8 +158,8 @@ static inline int pcpu_running(struct pcpu *pcpu) if (__pcpu_sigp(pcpu->address, sigp_sense_running, 0, &pcpu->status) != sigp_status_stored) return 1; - /* Check for running status */ - return !(pcpu->status & 0x400); + /* Status stored condition code is equivalent to cpu not running. */ + return 0; } /* -- GitLab From a9ae32c3d9a6557f24db0e186bf2f84205780b8a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Jun 2012 12:55:15 +0200 Subject: [PATCH 0503/6849] s390/smp/kvm: unifiy sigp definitions The smp and the kvm code have different defines for the sigp order codes. Let's just have a single place where these are defined. Also move the sigp condition code and sigp cpu status bits to the new sigp.h header file. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sigp.h | 31 ++++++++++++++++ arch/s390/kernel/smp.c | 72 ++++++++++++------------------------ arch/s390/kvm/sigp.c | 46 +++++------------------ 3 files changed, 64 insertions(+), 85 deletions(-) create mode 100644 arch/s390/include/asm/sigp.h diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h new file mode 100644 index 000000000000..7306270b5b84 --- /dev/null +++ b/arch/s390/include/asm/sigp.h @@ -0,0 +1,31 @@ +#ifndef __S390_ASM_SIGP_H +#define __S390_ASM_SIGP_H + +/* SIGP order codes */ +#define SIGP_SENSE 1 +#define SIGP_EXTERNAL_CALL 2 +#define SIGP_EMERGENCY_SIGNAL 3 +#define SIGP_STOP 5 +#define SIGP_RESTART 6 +#define SIGP_STOP_AND_STORE_STATUS 9 +#define SIGP_INITIAL_CPU_RESET 11 +#define SIGP_SET_PREFIX 13 +#define SIGP_STORE_STATUS_AT_ADDRESS 14 +#define SIGP_SET_ARCHITECTURE 18 +#define SIGP_SENSE_RUNNING 21 + +/* SIGP condition codes */ +#define SIGP_CC_ORDER_CODE_ACCEPTED 0 +#define SIGP_CC_STATUS_STORED 1 +#define SIGP_CC_BUSY 2 +#define SIGP_CC_NOT_OPERATIONAL 3 + +/* SIGP cpu status bits */ + +#define SIGP_STATUS_CHECK_STOP 0x00000010UL +#define SIGP_STATUS_STOPPED 0x00000040UL +#define SIGP_STATUS_INVALID_PARAMETER 0x00000100UL +#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL +#define SIGP_STATUS_NOT_RUNNING 0x00000400UL + +#endif /* __S390_ASM_SIGP_H */ diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index c78074c6cc1d..6e4047e4b498 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -44,33 +44,9 @@ #include #include #include +#include #include "entry.h" -enum { - sigp_sense = 1, - sigp_external_call = 2, - sigp_emergency_signal = 3, - sigp_start = 4, - sigp_stop = 5, - sigp_restart = 6, - sigp_stop_and_store_status = 9, - sigp_initial_cpu_reset = 11, - sigp_cpu_reset = 12, - sigp_set_prefix = 13, - sigp_store_status_at_address = 14, - sigp_store_extended_status_at_address = 15, - sigp_set_architecture = 18, - sigp_conditional_emergency_signal = 19, - sigp_sense_running = 21, -}; - -enum { - sigp_order_code_accepted = 0, - sigp_status_stored = 1, - sigp_busy = 2, - sigp_not_operational = 3, -}; - enum { ec_schedule = 0, ec_call_function, @@ -124,7 +100,7 @@ static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status) while (1) { cc = __pcpu_sigp(addr, order, parm, status); - if (cc != sigp_busy) + if (cc != SIGP_CC_BUSY) return cc; cpu_relax(); } @@ -136,7 +112,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm) for (retry = 0; ; retry++) { cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status); - if (cc != sigp_busy) + if (cc != SIGP_CC_BUSY) break; if (retry >= 3) udelay(10); @@ -146,8 +122,8 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm) static inline int pcpu_stopped(struct pcpu *pcpu) { - if (__pcpu_sigp(pcpu->address, sigp_sense, - 0, &pcpu->status) != sigp_status_stored) + if (__pcpu_sigp(pcpu->address, SIGP_SENSE, + 0, &pcpu->status) != SIGP_CC_STATUS_STORED) return 0; /* Check for stopped and check stop state */ return !!(pcpu->status & 0x50); @@ -155,8 +131,8 @@ static inline int pcpu_stopped(struct pcpu *pcpu) static inline int pcpu_running(struct pcpu *pcpu) { - if (__pcpu_sigp(pcpu->address, sigp_sense_running, - 0, &pcpu->status) != sigp_status_stored) + if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING, + 0, &pcpu->status) != SIGP_CC_STATUS_STORED) return 1; /* Status stored condition code is equivalent to cpu not running. */ return 0; @@ -181,7 +157,7 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit) set_bit(ec_bit, &pcpu->ec_mask); order = pcpu_running(pcpu) ? - sigp_external_call : sigp_emergency_signal; + SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL; pcpu_sigp_retry(pcpu, order, 0); } @@ -214,7 +190,7 @@ static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) goto out; #endif lowcore_ptr[cpu] = lc; - pcpu_sigp_retry(pcpu, sigp_set_prefix, (u32)(unsigned long) lc); + pcpu_sigp_retry(pcpu, SIGP_SET_PREFIX, (u32)(unsigned long) lc); return 0; out: if (pcpu != &pcpu_devices[0]) { @@ -229,7 +205,7 @@ out: static void pcpu_free_lowcore(struct pcpu *pcpu) { - pcpu_sigp_retry(pcpu, sigp_set_prefix, 0); + pcpu_sigp_retry(pcpu, SIGP_SET_PREFIX, 0); lowcore_ptr[pcpu - pcpu_devices] = NULL; #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { @@ -288,7 +264,7 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) lc->restart_fn = (unsigned long) func; lc->restart_data = (unsigned long) data; lc->restart_source = -1UL; - pcpu_sigp_retry(pcpu, sigp_restart, 0); + pcpu_sigp_retry(pcpu, SIGP_RESTART, 0); } /* @@ -309,7 +285,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), if (pcpu->address == restart.source) func(data); /* should not return */ /* Stop target cpu (if func returns this stops the current cpu). */ - pcpu_sigp_retry(pcpu, sigp_stop, 0); + pcpu_sigp_retry(pcpu, SIGP_STOP, 0); /* Restart func on the target cpu and stop the current cpu. */ memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); asm volatile( @@ -388,8 +364,8 @@ void smp_emergency_stop(cpumask_t *cpumask) for_each_cpu(cpu, cpumask) { struct pcpu *pcpu = pcpu_devices + cpu; set_bit(ec_stop_cpu, &pcpu->ec_mask); - while (__pcpu_sigp(pcpu->address, sigp_emergency_signal, - 0, NULL) == sigp_busy && + while (__pcpu_sigp(pcpu->address, SIGP_EMERGENCY_SIGNAL, + 0, NULL) == SIGP_CC_BUSY && get_clock() < end) cpu_relax(); } @@ -425,7 +401,7 @@ void smp_send_stop(void) /* stop all processors */ for_each_cpu(cpu, &cpumask) { struct pcpu *pcpu = pcpu_devices + cpu; - pcpu_sigp_retry(pcpu, sigp_stop, 0); + pcpu_sigp_retry(pcpu, SIGP_STOP, 0); while (!pcpu_stopped(pcpu)) cpu_relax(); } @@ -436,7 +412,7 @@ void smp_send_stop(void) */ void smp_stop_cpu(void) { - pcpu_sigp_retry(pcpu_devices + smp_processor_id(), sigp_stop, 0); + pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0); for (;;) ; } @@ -590,7 +566,7 @@ static void __init smp_get_save_area(int cpu, u16 address) } #endif /* Get the registers of a non-boot cpu. */ - __pcpu_sigp_relax(address, sigp_stop_and_store_status, 0, NULL); + __pcpu_sigp_relax(address, SIGP_STOP_AND_STORE_STATUS, 0, NULL); memcpy_real(save_area, lc + SAVE_AREA_BASE, sizeof(*save_area)); } @@ -599,8 +575,8 @@ int smp_store_status(int cpu) struct pcpu *pcpu; pcpu = pcpu_devices + cpu; - if (__pcpu_sigp_relax(pcpu->address, sigp_stop_and_store_status, - 0, NULL) != sigp_order_code_accepted) + if (__pcpu_sigp_relax(pcpu->address, SIGP_STOP_AND_STORE_STATUS, + 0, NULL) != SIGP_CC_ORDER_CODE_ACCEPTED) return -EIO; return 0; } @@ -621,8 +597,8 @@ static struct sclp_cpu_info *smp_get_cpu_info(void) if (info && (use_sigp_detection || sclp_get_cpu_info(info))) { use_sigp_detection = 1; for (address = 0; address <= MAX_CPU_ADDRESS; address++) { - if (__pcpu_sigp_relax(address, sigp_sense, 0, NULL) == - sigp_not_operational) + if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) == + SIGP_CC_NOT_OPERATIONAL) continue; info->cpu[info->configured].address = address; info->configured++; @@ -734,8 +710,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) pcpu = pcpu_devices + cpu; if (pcpu->state != CPU_STATE_CONFIGURED) return -EIO; - if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) != - sigp_order_code_accepted) + if (pcpu_sigp_retry(pcpu, SIGP_INITIAL_CPU_RESET, 0) != + SIGP_CC_ORDER_CODE_ACCEPTED) return -EIO; rc = pcpu_alloc_lowcore(pcpu, cpu); @@ -795,7 +771,7 @@ void __cpu_die(unsigned int cpu) void __noreturn cpu_die(void) { idle_task_exit(); - pcpu_sigp_retry(pcpu_devices + smp_processor_id(), sigp_stop, 0); + pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0); for (;;) ; } diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 0ad4cf238391..fda1d64f15ee 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -15,38 +15,10 @@ #include #include #include +#include #include "gaccess.h" #include "kvm-s390.h" -/* sigp order codes */ -#define SIGP_SENSE 0x01 -#define SIGP_EXTERNAL_CALL 0x02 -#define SIGP_EMERGENCY 0x03 -#define SIGP_START 0x04 -#define SIGP_STOP 0x05 -#define SIGP_RESTART 0x06 -#define SIGP_STOP_STORE_STATUS 0x09 -#define SIGP_INITIAL_CPU_RESET 0x0b -#define SIGP_CPU_RESET 0x0c -#define SIGP_SET_PREFIX 0x0d -#define SIGP_STORE_STATUS_ADDR 0x0e -#define SIGP_SET_ARCH 0x12 -#define SIGP_SENSE_RUNNING 0x15 - -/* cpu status bits */ -#define SIGP_STAT_EQUIPMENT_CHECK 0x80000000UL -#define SIGP_STAT_NOT_RUNNING 0x00000400UL -#define SIGP_STAT_INCORRECT_STATE 0x00000200UL -#define SIGP_STAT_INVALID_PARAMETER 0x00000100UL -#define SIGP_STAT_EXT_CALL_PENDING 0x00000080UL -#define SIGP_STAT_STOPPED 0x00000040UL -#define SIGP_STAT_OPERATOR_INTERV 0x00000020UL -#define SIGP_STAT_CHECK_STOP 0x00000010UL -#define SIGP_STAT_INOPERATIVE 0x00000004UL -#define SIGP_STAT_INVALID_ORDER 0x00000002UL -#define SIGP_STAT_RECEIVER_CHECK 0x00000001UL - - static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, u64 *reg) { @@ -65,7 +37,7 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, rc = 1; /* status stored */ } else { *reg &= 0xffffffff00000000UL; - *reg |= SIGP_STAT_STOPPED; + *reg |= SIGP_STATUS_STOPPED; rc = 1; /* status stored */ } spin_unlock(&fi->lock); @@ -235,7 +207,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, address = address & 0x7fffe000u; if (copy_from_guest_absolute(vcpu, &tmp, address, 1) || copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1)) { - *reg |= SIGP_STAT_INVALID_PARAMETER; + *reg |= SIGP_STATUS_INVALID_PARAMETER; return 1; /* invalid parameter */ } @@ -249,7 +221,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, if (li == NULL) { rc = 1; /* incorrect state */ - *reg &= SIGP_STAT_INCORRECT_STATE; + *reg &= SIGP_STATUS_INCORRECT_STATE; kfree(inti); goto out_fi; } @@ -258,7 +230,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, /* cpu must be in stopped state */ if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { rc = 1; /* incorrect state */ - *reg &= SIGP_STAT_INCORRECT_STATE; + *reg &= SIGP_STATUS_INCORRECT_STATE; kfree(inti); goto out_li; } @@ -300,7 +272,7 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, } else { /* not running */ *reg &= 0xffffffff00000000UL; - *reg |= SIGP_STAT_NOT_RUNNING; + *reg |= SIGP_STATUS_NOT_RUNNING; rc = 0; } } @@ -375,7 +347,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) vcpu->stat.instruction_sigp_external_call++; rc = __sigp_external_call(vcpu, cpu_addr); break; - case SIGP_EMERGENCY: + case SIGP_EMERGENCY_SIGNAL: vcpu->stat.instruction_sigp_emergency++; rc = __sigp_emergency(vcpu, cpu_addr); break; @@ -383,12 +355,12 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) vcpu->stat.instruction_sigp_stop++; rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP); break; - case SIGP_STOP_STORE_STATUS: + case SIGP_STOP_AND_STORE_STATUS: vcpu->stat.instruction_sigp_stop++; rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | ACTION_STOP_ON_STOP); break; - case SIGP_SET_ARCH: + case SIGP_SET_ARCHITECTURE: vcpu->stat.instruction_sigp_arch++; rc = __sigp_set_arch(vcpu, parameter); break; -- GitLab From a095a8a9d5c2ffa15589298aabb64c75c39bf9be Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Jun 2012 14:07:47 +0200 Subject: [PATCH 0504/6849] s390/smp: use sigp cpu status definitions We got them from the kvm code, so let's use them. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 6e4047e4b498..53ac2344ca7a 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -125,8 +125,7 @@ static inline int pcpu_stopped(struct pcpu *pcpu) if (__pcpu_sigp(pcpu->address, SIGP_SENSE, 0, &pcpu->status) != SIGP_CC_STATUS_STORED) return 0; - /* Check for stopped and check stop state */ - return !!(pcpu->status & 0x50); + return !!(pcpu->status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED)); } static inline int pcpu_running(struct pcpu *pcpu) -- GitLab From eb546195a7d8bc492ec6865980bf767474e74d87 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Jun 2012 15:05:43 +0200 Subject: [PATCH 0505/6849] s390/sigp: use sigp order code defines in assembly code Use sigp order code defines in assembly code as well. With this change all places that use sigp constants should have been converted to use self describing defines instead of directly using constants. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/base.S | 3 ++- arch/s390/kernel/entry.S | 5 +++-- arch/s390/kernel/entry64.S | 5 +++-- arch/s390/kernel/head_kdump.S | 6 ++++-- arch/s390/kernel/reipl.S | 3 ++- arch/s390/kernel/reipl64.S | 3 ++- arch/s390/kernel/relocate_kernel.S | 3 ++- arch/s390/kernel/relocate_kernel64.S | 5 +++-- arch/s390/kernel/smp.c | 8 +++++--- arch/s390/kernel/swsusp_asm64.S | 13 +++++++------ 10 files changed, 33 insertions(+), 21 deletions(-) diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index c880ff72db44..8c20d0efd483 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef CONFIG_64BIT @@ -100,7 +101,7 @@ ENTRY(diag308_reset) .Lrestart_part2: lhi %r0,0 # Load r0 with zero lhi %r1,2 # Use mode 2 = ESAME (dump) - sigp %r1,%r0,0x12 # Switch to ESAME mode + sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to ESAME mode sam64 # Switch to 64 bit addressing mode larl %r4,.Lctlregs # Restore control registers lctlg %c0,%c15,0(%r4) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 1ae93b573d7d..3787f9e6907a 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -18,6 +18,7 @@ #include #include #include +#include __PT_R0 = __PT_GPRS __PT_R1 = __PT_GPRS + 4 @@ -726,12 +727,12 @@ ENTRY(restart_int_handler) lm %r1,%r3,__LC_RESTART_FN # load fn, parm & source cpu ltr %r3,%r3 # test source cpu address jm 1f # negative -> skip source stop -0: sigp %r4,%r3,1 # sigp sense to source cpu +0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu brc 10,0b # wait for status stored 1: basr %r14,%r1 # call function stap __SF_EMPTY(%r15) # store cpu address lh %r3,__SF_EMPTY(%r15) -2: sigp %r4,%r3,5 # sigp stop to current cpu +2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu brc 2,2b 3: j 3b diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index bf80a5921173..d5f02e480e51 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -18,6 +18,7 @@ #include #include #include +#include __PT_R0 = __PT_GPRS __PT_R1 = __PT_GPRS + 8 @@ -753,12 +754,12 @@ ENTRY(restart_int_handler) lmg %r1,%r3,__LC_RESTART_FN # load fn, parm & source cpu ltgr %r3,%r3 # test source cpu address jm 1f # negative -> skip source stop -0: sigp %r4,%r3,1 # sigp sense to source cpu +0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu brc 10,0b # wait for status stored 1: basr %r14,%r1 # call function stap __SF_EMPTY(%r15) # store cpu address llgh %r3,__SF_EMPTY(%r15) -2: sigp %r4,%r3,5 # sigp stop to current cpu +2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu brc 2,2b 3: j 3b diff --git a/arch/s390/kernel/head_kdump.S b/arch/s390/kernel/head_kdump.S index 796c976b5fdc..acaaaf4b7055 100644 --- a/arch/s390/kernel/head_kdump.S +++ b/arch/s390/kernel/head_kdump.S @@ -5,6 +5,8 @@ * Author(s): Michael Holzheu */ +#include + #define DATAMOVER_ADDR 0x4000 #define COPY_PAGE_ADDR 0x6000 @@ -19,7 +21,7 @@ .align 2 .Lep_startup_kdump: lhi %r1,2 # mode 2 = esame (dump) - sigp %r1,%r0,0x12 # Switch to esame mode + sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to esame mode sam64 # Switch to 64 bit addressing basr %r13,0 .Lbase: @@ -88,7 +90,7 @@ startup_kdump_relocated: sam31 # Switch to 31 bit addr mode sr %r1,%r1 # Erase register r1 sr %r2,%r2 # Erase register r2 - sigp %r1,%r2,0x12 # Switch to 31 bit arch mode + sigp %r1,%r2,SIGP_SET_ARCHITECTURE # Switch to 31 bit arch mode lpsw 0 # Start new kernel... .align 8 .Lrestart_psw: diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index ad67c214be04..1c5e9e3e2aa4 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -8,6 +8,7 @@ #include #include +#include # # store_status: Empty implementation until kdump is supported on 31 bit @@ -60,7 +61,7 @@ ENTRY(do_reipl_asm) bas %r14,.Ldisab-.Lpg0(%r13) .L003: st %r1,__LC_SUBCHANNEL_ID lpsw 0 - sigp 0,0,0(6) + sigp 0,0,SIGP_RESTART .Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) lpsw .Ldispsw-.Lpg0(%r13) .align 8 diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S index 36b32658fb24..02f5a73d1820 100644 --- a/arch/s390/kernel/reipl64.S +++ b/arch/s390/kernel/reipl64.S @@ -6,6 +6,7 @@ #include #include +#include # # store_status @@ -106,7 +107,7 @@ ENTRY(do_reipl_asm) .L003: st %r1,__LC_SUBCHANNEL_ID lhi %r1,0 # mode 0 = esa slr %r0,%r0 # set cpuid to zero - sigp %r1,%r0,0x12 # switch to esa mode + sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esa mode lpsw 0 .Ldisab: sll %r14,1 srl %r14,1 # need to kill hi bit to avoid specification exceptions. diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index c91d70aede91..bfad96a64222 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -9,6 +9,7 @@ */ #include +#include /* * moves the new kernel to its destination... @@ -93,7 +94,7 @@ ENTRY(relocate_kernel) .no_diag308: sr %r1,%r1 # clear %r1 sr %r2,%r2 # clear %r2 - sigp %r1,%r2,0x12 # set cpuid to zero + sigp %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero lpsw 0 # hopefully start new kernel... .align 8 diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S index 7c3ce589a7f0..35508f335688 100644 --- a/arch/s390/kernel/relocate_kernel64.S +++ b/arch/s390/kernel/relocate_kernel64.S @@ -9,6 +9,7 @@ */ #include +#include /* * moves the new kernel to its destination... @@ -45,7 +46,7 @@ ENTRY(relocate_kernel) diag %r0,%r0,0x308 .back: lhi %r1,1 # mode 1 = esame - sigp %r1,%r0,0x12 # switch to esame mode + sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esame mode sam64 # switch to 64 bit addressing mode basr %r13,0 .back_base: @@ -96,7 +97,7 @@ ENTRY(relocate_kernel) sam31 # 31 bit mode sr %r1,%r1 # erase register r1 sr %r2,%r2 # erase register r2 - sigp %r1,%r2,0x12 # set cpuid to zero + sigp %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero lpsw 0 # hopefully start new kernel... .align 8 diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 53ac2344ca7a..e01408429ad6 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -288,11 +288,13 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), /* Restart func on the target cpu and stop the current cpu. */ memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); asm volatile( - "0: sigp 0,%0,6 # sigp restart to target cpu\n" + "0: sigp 0,%0,%2 # sigp restart to target cpu\n" " brc 2,0b # busy, try again\n" - "1: sigp 0,%1,5 # sigp stop to current cpu\n" + "1: sigp 0,%1,%3 # sigp stop to current cpu\n" " brc 2,1b # busy, try again\n" - : : "d" (pcpu->address), "d" (restart.source) : "0", "1", "cc"); + : : "d" (pcpu->address), "d" (restart.source), + "K" (SIGP_RESTART), "K" (SIGP_STOP) + : "0", "1", "cc"); for (;;) ; } diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index dd70ef046058..d4ca4e0617b5 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S @@ -12,6 +12,7 @@ #include #include #include +#include /* * Save register context in absolute 0 lowcore and call swsusp_save() to @@ -163,7 +164,7 @@ ENTRY(swsusp_arch_resume) diag %r0,%r0,0x308 restart_entry: lhi %r1,1 - sigp %r1,%r0,0x12 + sigp %r1,%r0,SIGP_SET_ARCHITECTURE sam64 larl %r1,.Lnew_pgm_check_psw lpswe 0(%r1) @@ -179,7 +180,7 @@ pgm_check_entry: larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ mvc __LC_RST_NEW_PSW(16,%r0),0(%r4) 3: - sigp %r9,%r1,11 /* sigp initial cpu reset */ + sigp %r9,%r1,SIGP_INITIAL_CPU_RESET /* sigp initial cpu reset */ brc 8,4f /* accepted */ brc 2,3b /* busy, try again */ @@ -190,16 +191,16 @@ pgm_check_entry: larl %r3,_sclp_print_early lghi %r1,0 sam31 - sigp %r1,%r0,0x12 + sigp %r1,%r0,SIGP_SET_ARCHITECTURE basr %r14,%r3 larl %r3,.Ldisabled_wait_31 lpsw 0(%r3) 4: /* Switch to suspend CPU */ - sigp %r9,%r1,6 /* sigp restart to suspend CPU */ + sigp %r9,%r1,SIGP_RESTART /* sigp restart to suspend CPU */ brc 2,4b /* busy, try again */ 5: - sigp %r9,%r2,5 /* sigp stop to current resume CPU */ + sigp %r9,%r2,SIGP_STOP /* sigp stop to current resume CPU */ brc 2,5b /* busy, try again */ 6: j 6b @@ -207,7 +208,7 @@ restart_suspend: larl %r1,.Lresume_cpu llgh %r2,0(%r1) 7: - sigp %r9,%r2,1 /* sigp sense, wait for resume CPU */ + sigp %r9,%r2,SIGP_SENSE /* sigp sense, wait for resume CPU */ brc 8,7b /* accepted, status 0, still running */ brc 2,7b /* busy, try again */ tmll %r9,0x40 /* Test if resume CPU is stopped */ -- GitLab From ed35ba9af4f40056a222dd7b67f39f1f6172185a Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 4 Jun 2012 19:29:41 +0200 Subject: [PATCH 0506/6849] s390/cio/chp: cleanup attribute usage Let the driver core handle device attribute creation and removal. This will simplify the code and eliminates races between attribute availability and userspace notification via uevents. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index e792436c9270..9b054806f7b1 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -362,10 +362,13 @@ static struct attribute *chp_attrs[] = { &dev_attr_shared.attr, NULL, }; - static struct attribute_group chp_attr_group = { .attrs = chp_attrs, }; +static const struct attribute_group *chp_attr_groups[] = { + &chp_attr_group, + NULL, +}; static void chp_release(struct device *dev) { @@ -397,6 +400,7 @@ int chp_new(struct chp_id chpid) chp->chpid = chpid; chp->state = 1; chp->dev.parent = &channel_subsystems[chpid.cssid]->device; + chp->dev.groups = chp_attr_groups; chp->dev.release = chp_release; mutex_init(&chp->lock); @@ -426,16 +430,10 @@ int chp_new(struct chp_id chpid) put_device(&chp->dev); goto out; } - ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group); - if (ret) { - device_unregister(&chp->dev); - goto out; - } mutex_lock(&channel_subsystems[chpid.cssid]->mutex); if (channel_subsystems[chpid.cssid]->cm_enabled) { ret = chp_add_cmg_attr(chp); if (ret) { - sysfs_remove_group(&chp->dev.kobj, &chp_attr_group); device_unregister(&chp->dev); mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); goto out; -- GitLab From 8d4ecfcb6bd19c562e60f80f13cf222db5b4a073 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 4 Jun 2012 19:31:00 +0200 Subject: [PATCH 0507/6849] s390/ccwgroup: remove unused ccwgroup_device member The creator_id is no longer used. Just get rid of it. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ccwgroup.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index f2ef34f6d6e5..01a905eb11e0 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -6,14 +6,12 @@ struct ccw_driver; /** * struct ccwgroup_device - ccw group device - * @creator_id: unique number of the driver * @state: online/offline state * @count: number of attached slave devices * @dev: embedded device structure * @cdev: variable number of slave devices, allocated as needed */ struct ccwgroup_device { - unsigned long creator_id; enum { CCWGROUP_OFFLINE, CCWGROUP_ONLINE, -- GitLab From 76e0377b2450af577077c7e4e00ae6da738d1884 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 4 Jun 2012 19:32:13 +0200 Subject: [PATCH 0508/6849] s390/vmlogrdr: cleanup device attribute usage Let the driver core handle device attribute creation and removal. This will simplify the code and eliminates races between attribute availability and userspace notification via uevents. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmlogrdr.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 524d988d89dd..e9d70aedbaa2 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -668,6 +668,13 @@ static struct attribute *vmlogrdr_attrs[] = { &dev_attr_recording.attr, NULL, }; +static struct attribute_group vmlogrdr_attr_group = { + .attrs = vmlogrdr_attrs, +}; +static const struct attribute_group *vmlogrdr_attr_groups[] = { + &vmlogrdr_attr_group, + NULL, +}; static int vmlogrdr_pm_prepare(struct device *dev) { @@ -692,10 +699,6 @@ static const struct dev_pm_ops vmlogrdr_pm_ops = { .prepare = vmlogrdr_pm_prepare, }; -static struct attribute_group vmlogrdr_attr_group = { - .attrs = vmlogrdr_attrs, -}; - static struct class *vmlogrdr_class; static struct device_driver vmlogrdr_driver = { .name = "vmlogrdr", @@ -762,6 +765,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) dev->bus = &iucv_bus; dev->parent = iucv_root; dev->driver = &vmlogrdr_driver; + dev->groups = vmlogrdr_attr_groups; dev_set_drvdata(dev, priv); /* * The release function could be called after the @@ -779,11 +783,6 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) return ret; } - ret = sysfs_create_group(&dev->kobj, &vmlogrdr_attr_group); - if (ret) { - device_unregister(dev); - return ret; - } priv->class_device = device_create(vmlogrdr_class, dev, MKDEV(vmlogrdr_major, priv->minor_num), @@ -791,7 +790,6 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) if (IS_ERR(priv->class_device)) { ret = PTR_ERR(priv->class_device); priv->class_device=NULL; - sysfs_remove_group(&dev->kobj, &vmlogrdr_attr_group); device_unregister(dev); return ret; } @@ -804,7 +802,6 @@ static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) { device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num)); if (priv->device != NULL) { - sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group); device_unregister(priv->device); priv->device=NULL; } -- GitLab From 72f6e3a8bc956fddf6e004ae9b804977d1458e77 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 4 Jun 2012 19:33:09 +0200 Subject: [PATCH 0509/6849] s390/vmlogrdr: cleanup driver attribute usage Let the driver core handle driver attribute creation and removal. This will simplify the code and eliminates races between attribute availability and userspace notification via uevents. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmlogrdr.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e9d70aedbaa2..5138fc93dc00 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -656,10 +656,19 @@ static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver, len = strlen(buf); return len; } - - static DRIVER_ATTR(recording_status, 0444, vmlogrdr_recording_status_show, NULL); +static struct attribute *vmlogrdr_drv_attrs[] = { + &driver_attr_recording_status.attr, + NULL, +}; +static struct attribute_group vmlogrdr_drv_attr_group = { + .attrs = vmlogrdr_drv_attrs, +}; +static const struct attribute_group *vmlogrdr_drv_attr_groups[] = { + &vmlogrdr_drv_attr_group, + NULL, +}; static struct attribute *vmlogrdr_attrs[] = { &dev_attr_autopurge.attr, @@ -704,9 +713,9 @@ static struct device_driver vmlogrdr_driver = { .name = "vmlogrdr", .bus = &iucv_bus, .pm = &vmlogrdr_pm_ops, + .groups = vmlogrdr_drv_attr_groups, }; - static int vmlogrdr_register_driver(void) { int ret; @@ -720,21 +729,14 @@ static int vmlogrdr_register_driver(void) if (ret) goto out_iucv; - ret = driver_create_file(&vmlogrdr_driver, - &driver_attr_recording_status); - if (ret) - goto out_driver; - vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); if (IS_ERR(vmlogrdr_class)) { ret = PTR_ERR(vmlogrdr_class); vmlogrdr_class = NULL; - goto out_attr; + goto out_driver; } return 0; -out_attr: - driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); out_driver: driver_unregister(&vmlogrdr_driver); out_iucv: @@ -748,7 +750,6 @@ static void vmlogrdr_unregister_driver(void) { class_destroy(vmlogrdr_class); vmlogrdr_class = NULL; - driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); driver_unregister(&vmlogrdr_driver); iucv_unregister(&vmlogrdr_iucv_handler, 1); } -- GitLab From 9a1a69901dae144ae160af5ac38848866d7c83b1 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:06 +0300 Subject: [PATCH 0510/6849] wl18xx: add new module Add the wl18xx module and the probe functions. Use wlcore for the main parts (not functional at this point due to differences in the wl18xx initialization). Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/Kconfig | 1 + drivers/net/wireless/ti/Makefile | 1 + drivers/net/wireless/ti/wl18xx/Kconfig | 6 ++ drivers/net/wireless/ti/wl18xx/Makefile | 3 + drivers/net/wireless/ti/wl18xx/main.c | 73 +++++++++++++++++++++++++ 5 files changed, 84 insertions(+) create mode 100644 drivers/net/wireless/ti/wl18xx/Kconfig create mode 100644 drivers/net/wireless/ti/wl18xx/Makefile create mode 100644 drivers/net/wireless/ti/wl18xx/main.c diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig index 1a72932e2213..be800119d0a3 100644 --- a/drivers/net/wireless/ti/Kconfig +++ b/drivers/net/wireless/ti/Kconfig @@ -8,6 +8,7 @@ menuconfig WL_TI if WL_TI source "drivers/net/wireless/ti/wl1251/Kconfig" source "drivers/net/wireless/ti/wl12xx/Kconfig" +source "drivers/net/wireless/ti/wl18xx/Kconfig" # keep last for automatic dependencies source "drivers/net/wireless/ti/wlcore/Kconfig" diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile index 0a565622d4a4..4d6823983c04 100644 --- a/drivers/net/wireless/ti/Makefile +++ b/drivers/net/wireless/ti/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_WLCORE) += wlcore/ obj-$(CONFIG_WL12XX) += wl12xx/ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/ obj-$(CONFIG_WL1251) += wl1251/ +obj-$(CONFIG_WL18XX) += wl18xx/ diff --git a/drivers/net/wireless/ti/wl18xx/Kconfig b/drivers/net/wireless/ti/wl18xx/Kconfig new file mode 100644 index 000000000000..1451d1f377c9 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/Kconfig @@ -0,0 +1,6 @@ +config WL18XX + tristate "TI wl18xx support" + select WLCORE + ---help--- + This module adds support for wireless adapters based on TI + WiLink 8 chipsets. diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile new file mode 100644 index 000000000000..d187037bef70 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/Makefile @@ -0,0 +1,3 @@ +wl18xx-objs = main.o + +obj-$(CONFIG_WL18XX) += wl18xx.o diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c new file mode 100644 index 000000000000..cb835d914bab --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -0,0 +1,73 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include "../wlcore/wlcore.h" +#include "../wlcore/debug.h" + +int __devinit wl18xx_probe(struct platform_device *pdev) +{ + struct wl1271 *wl; + struct ieee80211_hw *hw; + + hw = wlcore_alloc_hw(0); + if (IS_ERR(hw)) { + wl1271_error("can't allocate hw"); + return PTR_ERR(hw); + } + + wl = hw->priv; + + return wlcore_probe(wl, pdev); +} + +static const struct platform_device_id wl18xx_id_table[] __devinitconst = { + { "wl18xx", 0 }, + { } /* Terminating Entry */ +}; +MODULE_DEVICE_TABLE(platform, wl18xx_id_table); + +static struct platform_driver wl18xx_driver = { + .probe = wl18xx_probe, + .remove = __devexit_p(wlcore_remove), + .id_table = wl18xx_id_table, + .driver = { + .name = "wl18xx_driver", + .owner = THIS_MODULE, + } +}; + +static int __init wl18xx_init(void) +{ + return platform_driver_register(&wl18xx_driver); +} +module_init(wl18xx_init); + +static void __exit wl18xx_exit(void) +{ + platform_driver_unregister(&wl18xx_driver); +} +module_exit(wl18xx_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Luciano Coelho "); -- GitLab From 197c62832b1a347f933fea286fc70266026ef5fb Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:07 +0300 Subject: [PATCH 0511/6849] wlcore_sdio/wl18xx: use SDIO revision number to identify wl18xx chips At least in PG1, the wl18xx chips use the same SDIO vendor/device ID, so it's not possible to figure out which driver is to be used. As a workaround, we can check the SDIO revision number, because wl18xx uses 3.00 and wl12xx does not. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/sdio.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 0a72347cfc4c..1082e394e8f7 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -196,6 +197,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, struct resource res[1]; mmc_pm_flag_t mmcflags; int ret = -ENOMEM; + const char *chip_family; /* We are only able to handle the wlan function */ if (func->num != 0x02) @@ -236,7 +238,18 @@ static int __devinit wl1271_probe(struct sdio_func *func, /* Tell PM core that we don't need the card to be powered now */ pm_runtime_put_noidle(&func->dev); - glue->core = platform_device_alloc("wl12xx", -1); + /* + * Due to a hardware bug, we can't differentiate wl18xx from + * wl12xx, because both report the same device ID. The only + * way to differentiate is by checking the SDIO revision, + * which is 3.00 on the wl18xx chips. + */ + if (func->card->cccr.sdio_vsn == SDIO_SDIO_REV_3_00) + chip_family = "wl18xx"; + else + chip_family = "wl12xx"; + + glue->core = platform_device_alloc(chip_family, -1); if (!glue->core) { dev_err(glue->dev, "can't allocate platform_device"); ret = -ENOMEM; -- GitLab From 554c36b7373ffcbe9c752ad779402f8cf3a44b48 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:08 +0300 Subject: [PATCH 0512/6849] wl18xx: add empty operations struct We don't have any chip-specific operations yet, but now wlcore has defined an operations structure and requires the pointer to be set. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index cb835d914bab..3fa9298e0b42 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -25,6 +25,9 @@ #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" +static struct wlcore_ops wl18xx_ops = { +}; + int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -37,6 +40,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) } wl = hw->priv; + wl->ops = &wl18xx_ops; return wlcore_probe(wl, pdev); } -- GitLab From 82b890cd4ea90e127feca3c27a7625e304e7e193 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:09 +0300 Subject: [PATCH 0513/6849] wl18xx: add partition table Define and add the partition table in the wlcore struct. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 3fa9298e0b42..f3a164a9d294 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -28,6 +28,40 @@ static struct wlcore_ops wl18xx_ops = { }; +static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { + [PART_TOP_PRCM_ELP_SOC] = { + .mem = { .start = 0x00A02000, .size = 0x00010000 }, + .reg = { .start = 0x00807000, .size = 0x00005000 }, + .mem2 = { .start = 0x00800000, .size = 0x0000B000 }, + .mem3 = { .start = 0x00000000, .size = 0x00000000 }, + }, + [PART_DOWN] = { + .mem = { .start = 0x00000000, .size = 0x00014000 }, + .reg = { .start = 0x00810000, .size = 0x0000BFFF }, + .mem2 = { .start = 0x00000000, .size = 0x00000000 }, + .mem3 = { .start = 0x00000000, .size = 0x00000000 }, + }, + [PART_BOOT] = { + .mem = { .start = 0x00700000, .size = 0x0000030c }, + .reg = { .start = 0x00802000, .size = 0x00014578 }, + .mem2 = { .start = 0x00B00404, .size = 0x00001000 }, + .mem3 = { .start = 0x00C00000, .size = 0x00000400 }, + }, + [PART_WORK] = { + .mem = { .start = 0x00800000, .size = 0x000050FC }, + .reg = { .start = 0x00B00404, .size = 0x00001000 }, + .mem2 = { .start = 0x00C00000, .size = 0x00000400 }, + .mem3 = { .start = 0x00000000, .size = 0x00000000 }, + }, + [PART_PHY_INIT] = { + /* TODO: use the phy_conf struct size here */ + .mem = { .start = 0x80926000, .size = 252 }, + .reg = { .start = 0x00000000, .size = 0x00000000 }, + .mem2 = { .start = 0x00000000, .size = 0x00000000 }, + .mem3 = { .start = 0x00000000, .size = 0x00000000 }, + }, +}; + int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -41,6 +75,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl = hw->priv; wl->ops = &wl18xx_ops; + wl->ptable = wl18xx_ptable; return wlcore_probe(wl, pdev); } -- GitLab From 5d4a9fa692ce0fc9fff0a35e53b3a9be44b48da5 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:10 +0300 Subject: [PATCH 0514/6849] wl18xx: add register table Add the register table with the appropriate values for wl18xx. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 23 ++++++ drivers/net/wireless/ti/wl18xx/reg.h | 112 ++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 drivers/net/wireless/ti/wl18xx/reg.h diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index f3a164a9d294..88fd93485175 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -25,6 +25,8 @@ #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" +#include "reg.h" + static struct wlcore_ops wl18xx_ops = { }; @@ -62,6 +64,26 @@ static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { }, }; +static const int wl18xx_rtable[REG_TABLE_LEN] = { + [REG_ECPU_CONTROL] = WL18XX_REG_ECPU_CONTROL, + [REG_INTERRUPT_NO_CLEAR] = WL18XX_REG_INTERRUPT_NO_CLEAR, + [REG_INTERRUPT_ACK] = WL18XX_REG_INTERRUPT_ACK, + [REG_COMMAND_MAILBOX_PTR] = WL18XX_REG_COMMAND_MAILBOX_PTR, + [REG_EVENT_MAILBOX_PTR] = WL18XX_REG_EVENT_MAILBOX_PTR, + [REG_INTERRUPT_TRIG] = WL18XX_REG_INTERRUPT_TRIG_H, + [REG_INTERRUPT_MASK] = WL18XX_REG_INTERRUPT_MASK, + [REG_PC_ON_RECOVERY] = 0, /* TODO: where is the PC? */ + [REG_CHIP_ID_B] = WL18XX_REG_CHIP_ID_B, + [REG_CMD_MBOX_ADDRESS] = WL18XX_CMD_MBOX_ADDRESS, + + /* data access memory addresses, used with partition translation */ + [REG_SLV_MEM_DATA] = WL18XX_SLV_MEM_DATA, + [REG_SLV_REG_DATA] = WL18XX_SLV_REG_DATA, + + /* raw data access memory addresses */ + [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR, +}; + int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -76,6 +98,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl = hw->priv; wl->ops = &wl18xx_ops; wl->ptable = wl18xx_ptable; + wl->rtable = wl18xx_rtable; return wlcore_probe(wl, pdev); } diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h new file mode 100644 index 000000000000..9af0c83727d6 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -0,0 +1,112 @@ +/* + * This file is part of wlcore + * + * Copyright (C) 2011 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __REG_H__ +#define __REG_H__ + +#define WL18XX_REGISTERS_BASE 0x00800000 +#define WL18XX_CODE_BASE 0x00000000 +#define WL18XX_DATA_BASE 0x00400000 +#define WL18XX_DOUBLE_BUFFER_BASE 0x00600000 +#define WL18XX_MCU_KEY_SEARCH_BASE 0x00700000 +#define WL18XX_PHY_BASE 0x00900000 +#define WL18XX_TOP_OCP_BASE 0x00A00000 +#define WL18XX_PACKET_RAM_BASE 0x00B00000 +#define WL18XX_HOST_BASE 0x00C00000 + +#define WL18XX_REGISTERS_DOWN_SIZE 0x0000B000 + +#define WL18XX_REG_BOOT_PART_START 0x00802000 +#define WL18XX_REG_BOOT_PART_SIZE 0x00014578 + +#define WL18XX_PHY_INIT_MEM_ADDR 0x80926000 + +#define WL18XX_SDIO_WSPI_BASE (WL18XX_REGISTERS_BASE) +#define WL18XX_REG_CONFIG_BASE (WL18XX_REGISTERS_BASE + 0x02000) +#define WL18XX_WGCM_REGS_BASE (WL18XX_REGISTERS_BASE + 0x03000) +#define WL18XX_ENC_BASE (WL18XX_REGISTERS_BASE + 0x04000) +#define WL18XX_INTERRUPT_BASE (WL18XX_REGISTERS_BASE + 0x05000) +#define WL18XX_UART_BASE (WL18XX_REGISTERS_BASE + 0x06000) +#define WL18XX_WELP_BASE (WL18XX_REGISTERS_BASE + 0x07000) +#define WL18XX_TCP_CKSM_BASE (WL18XX_REGISTERS_BASE + 0x08000) +#define WL18XX_FIFO_BASE (WL18XX_REGISTERS_BASE + 0x09000) +#define WL18XX_OCP_BRIDGE_BASE (WL18XX_REGISTERS_BASE + 0x0A000) +#define WL18XX_PMAC_RX_BASE (WL18XX_REGISTERS_BASE + 0x14800) +#define WL18XX_PMAC_ACM_BASE (WL18XX_REGISTERS_BASE + 0x14C00) +#define WL18XX_PMAC_TX_BASE (WL18XX_REGISTERS_BASE + 0x15000) +#define WL18XX_PMAC_CSR_BASE (WL18XX_REGISTERS_BASE + 0x15400) + +#define WL18XX_REG_ECPU_CONTROL (WL18XX_REGISTERS_BASE + 0x02004) +#define WL18XX_REG_INTERRUPT_NO_CLEAR (WL18XX_REGISTERS_BASE + 0x050E8) +#define WL18XX_REG_INTERRUPT_ACK (WL18XX_REGISTERS_BASE + 0x050F0) +#define WL18XX_REG_INTERRUPT_TRIG (WL18XX_REGISTERS_BASE + 0x5074) +#define WL18XX_REG_INTERRUPT_TRIG_H (WL18XX_REGISTERS_BASE + 0x5078) +#define WL18XX_REG_INTERRUPT_MASK (WL18XX_REGISTERS_BASE + 0x0050DC) + +#define WL18XX_REG_CHIP_ID_B (WL18XX_REGISTERS_BASE + 0x01542C) + +#define WL18XX_SLV_MEM_DATA (WL18XX_HOST_BASE + 0x0018) +#define WL18XX_SLV_REG_DATA (WL18XX_HOST_BASE + 0x0008) + +/* Scratch Pad registers*/ +#define WL18XX_SCR_PAD0 (WL18XX_REGISTERS_BASE + 0x0154EC) +#define WL18XX_SCR_PAD1 (WL18XX_REGISTERS_BASE + 0x0154F0) +#define WL18XX_SCR_PAD2 (WL18XX_REGISTERS_BASE + 0x0154F4) +#define WL18XX_SCR_PAD3 (WL18XX_REGISTERS_BASE + 0x0154F8) +#define WL18XX_SCR_PAD4 (WL18XX_REGISTERS_BASE + 0x0154FC) +#define WL18XX_SCR_PAD4_SET (WL18XX_REGISTERS_BASE + 0x015504) +#define WL18XX_SCR_PAD4_CLR (WL18XX_REGISTERS_BASE + 0x015500) +#define WL18XX_SCR_PAD5 (WL18XX_REGISTERS_BASE + 0x015508) +#define WL18XX_SCR_PAD5_SET (WL18XX_REGISTERS_BASE + 0x015510) +#define WL18XX_SCR_PAD5_CLR (WL18XX_REGISTERS_BASE + 0x01550C) +#define WL18XX_SCR_PAD6 (WL18XX_REGISTERS_BASE + 0x015514) +#define WL18XX_SCR_PAD7 (WL18XX_REGISTERS_BASE + 0x015518) +#define WL18XX_SCR_PAD8 (WL18XX_REGISTERS_BASE + 0x01551C) +#define WL18XX_SCR_PAD9 (WL18XX_REGISTERS_BASE + 0x015520) + +/* Spare registers*/ +#define WL18XX_SPARE_A1 (WL18XX_REGISTERS_BASE + 0x002194) +#define WL18XX_SPARE_A2 (WL18XX_REGISTERS_BASE + 0x002198) +#define WL18XX_SPARE_A3 (WL18XX_REGISTERS_BASE + 0x00219C) +#define WL18XX_SPARE_A4 (WL18XX_REGISTERS_BASE + 0x0021A0) +#define WL18XX_SPARE_A5 (WL18XX_REGISTERS_BASE + 0x0021A4) +#define WL18XX_SPARE_A6 (WL18XX_REGISTERS_BASE + 0x0021A8) +#define WL18XX_SPARE_A7 (WL18XX_REGISTERS_BASE + 0x0021AC) +#define WL18XX_SPARE_A8 (WL18XX_REGISTERS_BASE + 0x0021B0) +#define WL18XX_SPARE_B1 (WL18XX_REGISTERS_BASE + 0x015524) +#define WL18XX_SPARE_B2 (WL18XX_REGISTERS_BASE + 0x015528) +#define WL18XX_SPARE_B3 (WL18XX_REGISTERS_BASE + 0x01552C) +#define WL18XX_SPARE_B4 (WL18XX_REGISTERS_BASE + 0x015530) +#define WL18XX_SPARE_B5 (WL18XX_REGISTERS_BASE + 0x015534) +#define WL18XX_SPARE_B6 (WL18XX_REGISTERS_BASE + 0x015538) +#define WL18XX_SPARE_B7 (WL18XX_REGISTERS_BASE + 0x01553C) +#define WL18XX_SPARE_B8 (WL18XX_REGISTERS_BASE + 0x015540) + +#define WL18XX_REG_COMMAND_MAILBOX_PTR (WL18XX_SCR_PAD0) +#define WL18XX_REG_EVENT_MAILBOX_PTR (WL18XX_SCR_PAD1) + +#define WL18XX_CMD_MBOX_ADDRESS 0xB007B4 + +#define WL18XX_FW_STATUS_ADDR 0x50F8 + +#define CHIP_ID_185x_PG10 (0x06030101) + +#endif /* __REG_H__ */ -- GitLab From 0cd6543f6852d646985786a429027bd0461e1cb4 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:11 +0300 Subject: [PATCH 0515/6849] wl18xx: add identify chip operation Add identify_chip operation to detect the chip ID for wl185x and set the correct firmware name. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 34 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 88fd93485175..e517afd98f41 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -27,9 +27,6 @@ #include "reg.h" -static struct wlcore_ops wl18xx_ops = { -}; - static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { [PART_TOP_PRCM_ELP_SOC] = { .mem = { .start = 0x00A02000, .size = 0x00010000 }, @@ -84,6 +81,36 @@ static const int wl18xx_rtable[REG_TABLE_LEN] = { [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR, }; +/* TODO: maybe move to a new header file? */ +#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw.bin" + +static int wl18xx_identify_chip(struct wl1271 *wl) +{ + int ret = 0; + + switch (wl->chip.id) { + case CHIP_ID_185x_PG10: + wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", + wl->chip.id); + wl->sr_fw_name = WL18XX_FW_NAME; + wl->quirks |= WLCORE_QUIRK_NO_ELP; + + /* TODO: need to blocksize alignment for RX/TX separately? */ + break; + default: + wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); + ret = -ENODEV; + goto out; + } + +out: + return ret; +} + +static struct wlcore_ops wl18xx_ops = { + .identify_chip = wl18xx_identify_chip, +}; + int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -133,3 +160,4 @@ module_exit(wl18xx_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); +MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From 46a1d51261bc4d9cd35b4e41a9b623687c0b4b8c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:12 +0300 Subject: [PATCH 0516/6849] wl18xx: add some boot operations and hw-specific configurations Implement the boot operation. Add a wl18xx-specific configuration structure (namely to configure the mac and phy parameters). The default hw configuration matches the DVP board. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/conf.h | 57 ++++++++ drivers/net/wireless/ti/wl18xx/main.c | 180 +++++++++++++++++++++++++- drivers/net/wireless/ti/wl18xx/reg.h | 75 +++++++++++ 3 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ti/wl18xx/conf.h diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h new file mode 100644 index 000000000000..7cd7bf16879e --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -0,0 +1,57 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL18XX_CONF_H__ +#define __WL18XX_CONF_H__ + +struct wl18xx_conf_phy { + u8 phy_standalone; + u8 rdl; + u8 enable_clpc; + u8 enable_tx_low_pwr_on_siso_rdl; + u8 auto_detect; + u8 dedicated_fem; + u8 low_band_component; + u8 low_band_component_type; + u8 high_band_component; + u8 high_band_component_type; + u8 number_of_assembled_ant2_4; + u8 number_of_assembled_ant5; + u8 external_pa_dc2dc; + u8 tcxo_ldo_voltage; + u8 xtal_itrim_val; + u8 srf_state; + u8 io_configuration; + u8 sdio_configuration; + u8 settings; + u8 rx_profile; + u8 primary_clock_setting_time; + u8 clock_valid_on_wake_up; + u8 secondary_clock_setting_time; +}; + +struct wl18xx_conf { + /* TODO: move the wlcore conf here? */ + + struct wl18xx_conf_phy phy; +}; + +#endif /* __WL18XX_CONF_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index e517afd98f41..12632d0373cc 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -24,8 +24,40 @@ #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" +#include "../wlcore/io.h" +#include "../wlcore/acx.h" +#include "../wlcore/boot.h" #include "reg.h" +#include "conf.h" + +static struct wl18xx_conf wl18xx_default_conf = { + .phy = { + .phy_standalone = 0x00, + .primary_clock_setting_time = 0x05, + .clock_valid_on_wake_up = 0x00, + .secondary_clock_setting_time = 0x05, + .rdl = 0x01, + .auto_detect = 0x00, + .dedicated_fem = FEM_NONE, + .low_band_component = COMPONENT_2_WAY_SWITCH, + .low_band_component_type = 0x05, + .high_band_component = COMPONENT_2_WAY_SWITCH, + .high_band_component_type = 0x09, + .number_of_assembled_ant2_4 = 0x01, + .number_of_assembled_ant5 = 0x01, + .external_pa_dc2dc = 0x00, + .tcxo_ldo_voltage = 0x00, + .xtal_itrim_val = 0x04, + .srf_state = 0x00, + .io_configuration = 0x01, + .sdio_configuration = 0x00, + .settings = 0x00, + .enable_clpc = 0x00, + .enable_tx_low_pwr_on_siso_rdl = 0x00, + .rx_profile = 0x00, + }, +}; static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { [PART_TOP_PRCM_ELP_SOC] = { @@ -107,8 +139,154 @@ out: return ret; } +static void wl18xx_set_clk(struct wl1271 *wl) +{ + /* + * TODO: this is hardcoded just for DVP/EVB, fix according to + * new unified_drv. + */ + wl1271_write32(wl, WL18XX_SCR_PAD2, 0xB3); + + wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + wl1271_write32(wl, 0x00A02360, 0xD0078); + wl1271_write32(wl, 0x00A0236c, 0x12); + wl1271_write32(wl, 0x00A02390, 0x20118); +} + +static void wl18xx_boot_soft_reset(struct wl1271 *wl) +{ + /* disable Rx/Tx */ + wl1271_write32(wl, WL18XX_ENABLE, 0x0); + + /* disable auto calibration on start*/ + wl1271_write32(wl, WL18XX_SPARE_A2, 0xffff); +} + +static int wl18xx_pre_boot(struct wl1271 *wl) +{ + /* TODO: add hw_pg_ver reading */ + + wl18xx_set_clk(wl); + + /* Continue the ELP wake up sequence */ + wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + udelay(500); + + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + + /* Disable interrupts */ + wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); + + wl18xx_boot_soft_reset(wl); + + return 0; +} + +static void wl18xx_pre_upload(struct wl1271 *wl) +{ + u32 tmp; + + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + + /* TODO: check if this is all needed */ + wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); + + tmp = wlcore_read_reg(wl, REG_CHIP_ID_B); + + wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); + + tmp = wl1271_read32(wl, WL18XX_SCR_PAD2); +} + +static void wl18xx_set_mac_and_phy(struct wl1271 *wl) +{ + struct wl18xx_mac_and_phy_params params; + + memset(¶ms, 0, sizeof(params)); + + params.phy_standalone = wl18xx_default_conf.phy.phy_standalone; + params.rdl = wl18xx_default_conf.phy.rdl; + params.enable_clpc = wl18xx_default_conf.phy.enable_clpc; + params.enable_tx_low_pwr_on_siso_rdl = + wl18xx_default_conf.phy.enable_tx_low_pwr_on_siso_rdl; + params.auto_detect = wl18xx_default_conf.phy.auto_detect; + params.dedicated_fem = wl18xx_default_conf.phy.dedicated_fem; + params.low_band_component = wl18xx_default_conf.phy.low_band_component; + params.low_band_component_type = + wl18xx_default_conf.phy.low_band_component_type; + params.high_band_component = + wl18xx_default_conf.phy.high_band_component; + params.high_band_component_type = + wl18xx_default_conf.phy.high_band_component_type; + params.number_of_assembled_ant2_4 = + wl18xx_default_conf.phy.number_of_assembled_ant2_4; + params.number_of_assembled_ant5 = + wl18xx_default_conf.phy.number_of_assembled_ant5; + params.external_pa_dc2dc = wl18xx_default_conf.phy.external_pa_dc2dc; + params.tcxo_ldo_voltage = wl18xx_default_conf.phy.tcxo_ldo_voltage; + params.xtal_itrim_val = wl18xx_default_conf.phy.xtal_itrim_val; + params.srf_state = wl18xx_default_conf.phy.srf_state; + params.io_configuration = wl18xx_default_conf.phy.io_configuration; + params.sdio_configuration = wl18xx_default_conf.phy.sdio_configuration; + params.settings = wl18xx_default_conf.phy.settings; + params.rx_profile = wl18xx_default_conf.phy.rx_profile; + params.primary_clock_setting_time = + wl18xx_default_conf.phy.primary_clock_setting_time; + params.clock_valid_on_wake_up = + wl18xx_default_conf.phy.clock_valid_on_wake_up; + params.secondary_clock_setting_time = + wl18xx_default_conf.phy.secondary_clock_setting_time; + + /* TODO: hardcoded for now */ + params.board_type = BOARD_TYPE_DVP_EVB_18XX; + + wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); + wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)¶ms, + sizeof(params), false); +} + +static void wl18xx_enable_interrupts(struct wl1271 *wl) +{ + wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); + + wlcore_enable_interrupts(wl); + wlcore_write_reg(wl, REG_INTERRUPT_MASK, + WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); +} + +static int wl18xx_boot(struct wl1271 *wl) +{ + int ret; + + ret = wl18xx_pre_boot(wl); + if (ret < 0) + goto out; + + ret = wlcore_boot_upload_nvs(wl); + if (ret < 0) + goto out; + + wl18xx_pre_upload(wl); + + ret = wlcore_boot_upload_firmware(wl); + if (ret < 0) + goto out; + + wl18xx_set_mac_and_phy(wl); + + ret = wlcore_boot_run_firmware(wl); + if (ret < 0) + goto out; + + wl18xx_enable_interrupts(wl); + +out: + return ret; +} + static struct wlcore_ops wl18xx_ops = { - .identify_chip = wl18xx_identify_chip, + .identify_chip = wl18xx_identify_chip, + .boot = wl18xx_boot, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 9af0c83727d6..2916d6939d44 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -102,6 +102,10 @@ #define WL18XX_REG_COMMAND_MAILBOX_PTR (WL18XX_SCR_PAD0) #define WL18XX_REG_EVENT_MAILBOX_PTR (WL18XX_SCR_PAD1) +#define WL18XX_EEPROMLESS_IND (WL18XX_SCR_PAD4) + +#define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100) +#define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C) #define WL18XX_CMD_MBOX_ADDRESS 0xB007B4 @@ -109,4 +113,75 @@ #define CHIP_ID_185x_PG10 (0x06030101) +/* TODO: maybe move elsewhere? */ +#define NUM_OF_CHANNELS_11_ABG 150 +#define NUM_OF_CHANNELS_11_P 7 +#define WL18XX_NUM_OF_SUB_BANDS 9 +#define SRF_TABLE_LEN 16 +#define PIN_MUXING_SIZE 2 + +enum { + COMPONENT_NO_SWITCH = 0x0, + COMPONENT_2_WAY_SWITCH = 0x1, + COMPONENT_3_WAY_SWITCH = 0x2, + COMPONENT_MATCHING = 0x3, +}; + +enum { + FEM_NONE = 0x0, + FEM_VENDOR_1 = 0x1, + FEM_VENDOR_2 = 0x2, + FEM_VENDOR_3 = 0x3, +}; + +enum { + BOARD_TYPE_FPGA_18XX = 0, + BOARD_TYPE_HDK_18XX = 1, + BOARD_TYPE_DVP_EVB_18XX = 2, +}; + +struct wl18xx_mac_and_phy_params { + u8 phy_standalone; + u8 rdl; + u8 enable_clpc; + u8 enable_tx_low_pwr_on_siso_rdl; + u8 auto_detect; + u8 dedicated_fem; + + u8 low_band_component; + + /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ + u8 low_band_component_type; + + u8 high_band_component; + + /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ + u8 high_band_component_type; + u8 number_of_assembled_ant2_4; + u8 number_of_assembled_ant5; + u8 pin_muxing_platform_options[PIN_MUXING_SIZE]; + u8 external_pa_dc2dc; + u8 tcxo_ldo_voltage; + u8 xtal_itrim_val; + u8 srf_state; + u8 srf1[SRF_TABLE_LEN]; + u8 srf2[SRF_TABLE_LEN]; + u8 srf3[SRF_TABLE_LEN]; + u8 io_configuration; + u8 sdio_configuration; + u8 settings; + u8 rx_profile; + u8 per_chan_pwr_limit_arr_11abg[NUM_OF_CHANNELS_11_ABG]; + u8 pwr_limit_reference_11_abg; + u8 per_chan_pwr_limit_arr_11p[NUM_OF_CHANNELS_11_P]; + u8 pwr_limit_reference_11p; + u8 per_sub_band_tx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; + u8 per_sub_band_rx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; + u8 primary_clock_setting_time; + u8 clock_valid_on_wake_up; + u8 secondary_clock_setting_time; + u8 board_type; + u8 padding[1]; +} __packed; + #endif /* __REG_H__ */ -- GitLab From 274c66cdcd89654de276be871627181b192a6e30 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:13 +0300 Subject: [PATCH 0517/6849] wl18xx: add trigger command and ack event operations Add the operations that allow wlcore to trigger commands to the firmware and acknowledge when an event has been fully received. Allocate a private buffer to hold the maximum sized cmd. Send the entire length of the buffer each time a command is sent to signal EOT. Remove the previous EOT mechanism. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 20 +++++++++++++++ drivers/net/wireless/ti/wl18xx/reg.h | 16 ++++++++++++ drivers/net/wireless/ti/wl18xx/wl18xx.h | 33 +++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 drivers/net/wireless/ti/wl18xx/wl18xx.h diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 12632d0373cc..6a487c83752d 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -30,6 +30,7 @@ #include "reg.h" #include "conf.h" +#include "wl18xx.h" static struct wl18xx_conf wl18xx_default_conf = { .phy = { @@ -284,9 +285,28 @@ out: return ret; } +static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, + void *buf, size_t len) +{ + struct wl18xx_priv *priv = wl->priv; + + memcpy(priv->cmd_buf, buf, len); + memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len); + + wl1271_write(wl, cmd_box_addr, priv->cmd_buf, WL18XX_CMD_MAX_SIZE, + false); +} + +static void wl18xx_ack_event(struct wl1271 *wl) +{ + wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, + .trigger_cmd = wl18xx_trigger_cmd, + .ack_event = wl18xx_ack_event, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 2916d6939d44..53987997f78f 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -113,6 +113,22 @@ #define CHIP_ID_185x_PG10 (0x06030101) +/* + * Host Command Interrupt. Setting this bit masks + * the interrupt that the host issues to inform + * the FW that it has sent a command + * to the Wlan hardware Command Mailbox. + */ +#define WL18XX_INTR_TRIG_CMD BIT(28) + +/* + * Host Event Acknowlegde Interrupt. The host + * sets this bit to acknowledge that it received + * the unsolicited information from the event + * mailbox. + */ +#define WL18XX_INTR_TRIG_EVENT_ACK BIT(29) + /* TODO: maybe move elsewhere? */ #define NUM_OF_CHANNELS_11_ABG 150 #define NUM_OF_CHANNELS_11_P 7 diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h new file mode 100644 index 000000000000..58709bb88b7b --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -0,0 +1,33 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL18XX_PRIV_H__ +#define __WL18XX_PRIV_H__ + + +#define WL18XX_CMD_MAX_SIZE 740 + +struct wl18xx_priv { + /* buffer for sending commands to FW */ + u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; +}; + +#endif /* __WL18XX_PRIV_H__ */ -- GitLab From 9d1c973a7b569652cea0ea00dc7ac409b08a8381 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:14 +0300 Subject: [PATCH 0518/6849] wl18xx: create per-chip-family private storage Make use of the wlcore provided private storage in the 18xx low-level driver. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 6a487c83752d..b298e0121377 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -313,8 +313,9 @@ int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; struct ieee80211_hw *hw; + struct wl18xx_priv *priv; - hw = wlcore_alloc_hw(0); + hw = wlcore_alloc_hw(sizeof(*priv)); if (IS_ERR(hw)) { wl1271_error("can't allocate hw"); return PTR_ERR(hw); -- GitLab From cb7b5d86c8283482bbf26398e83d2cbc5e36e193 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:15 +0300 Subject: [PATCH 0519/6849] wl18xx: set the number of Tx descriptors Initialize the number of Tx-descriptors for the 18xx family. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b298e0121377..68f5e09be508 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -325,6 +325,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->ops = &wl18xx_ops; wl->ptable = wl18xx_ptable; wl->rtable = wl18xx_rtable; + wl->num_tx_desc = 32; return wlcore_probe(wl, pdev); } -- GitLab From 1349c4212aacde0d26b20e9ff2ba7501d6e33d3c Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:16 +0300 Subject: [PATCH 0520/6849] wl18xx: set normal/GEM Tx spare block counts Initialize the Tx spare block counts for all operating modes in the 18xx card. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 68f5e09be508..70683adc9cf3 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -32,6 +32,9 @@ #include "conf.h" #include "wl18xx.h" +#define WL18XX_TX_HW_BLOCK_SPARE 1 +#define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 + static struct wl18xx_conf wl18xx_default_conf = { .phy = { .phy_standalone = 0x00, @@ -326,6 +329,8 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->ptable = wl18xx_ptable; wl->rtable = wl18xx_rtable; wl->num_tx_desc = 32; + wl->normal_tx_spare = WL18XX_TX_HW_BLOCK_SPARE; + wl->gem_tx_spare = WL18XX_TX_HW_GEM_BLOCK_SPARE; return wlcore_probe(wl, pdev); } -- GitLab From 624845b31cae0bf6671c3d0cbbec8214cf7d8584 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:17 +0300 Subject: [PATCH 0521/6849] wl18xx: implement hw op for calculating hw block count per packet Implement the calc_tx_blocks op for the 18xx family. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 70683adc9cf3..055b194827b3 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -34,6 +34,7 @@ #define WL18XX_TX_HW_BLOCK_SPARE 1 #define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 +#define WL18XX_TX_HW_BLOCK_SIZE 268 static struct wl18xx_conf wl18xx_default_conf = { .phy = { @@ -305,11 +306,18 @@ static void wl18xx_ack_event(struct wl1271 *wl) wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK); } +static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) +{ + u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE; + return (len + blk_size - 1) / blk_size + spare_blks; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, .trigger_cmd = wl18xx_trigger_cmd, .ack_event = wl18xx_ack_event, + .calc_tx_blocks = wl18xx_calc_tx_blocks, }; int __devinit wl18xx_probe(struct platform_device *pdev) -- GitLab From fb0f2e4ac0635549ce035c461d5050643ea5684c Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:18 +0300 Subject: [PATCH 0522/6849] wl18xx: implement hw op for setting blocks in hw_tx_desc Add the 18xx variant to the HW Tx descriptor union and set the 18xx specific values during Tx. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 10 ++++++++++ drivers/net/wireless/ti/wlcore/tx.h | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 055b194827b3..c85492ead0f9 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -26,6 +26,7 @@ #include "../wlcore/debug.h" #include "../wlcore/io.h" #include "../wlcore/acx.h" +#include "../wlcore/tx.h" #include "../wlcore/boot.h" #include "reg.h" @@ -312,12 +313,21 @@ static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) return (len + blk_size - 1) / blk_size + spare_blks; } +static void +wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, + u32 blks, u32 spare_blks) +{ + desc->wl18xx_mem.total_mem_blocks = blks; + desc->wl18xx_mem.reserved = 0; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, .trigger_cmd = wl18xx_trigger_cmd, .ack_event = wl18xx_ack_event, .calc_tx_blocks = wl18xx_calc_tx_blocks, + .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 2fd6e5dc6f75..e440c313537d 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -85,6 +85,19 @@ struct wl128x_tx_mem { u8 extra_bytes; } __packed; +struct wl18xx_tx_mem { + /* + * Total number of memory blocks allocated by the host for + * this packet. + */ + u8 total_mem_blocks; + + /* + * always zero + */ + u8 reserved; +} __packed; + /* * On wl128x based devices, when TX packets are aggregated, each packet * size must be aligned to the SDIO block size. The maximum block size @@ -100,6 +113,7 @@ struct wl1271_tx_hw_descr { union { struct wl127x_tx_mem wl127x_mem; struct wl128x_tx_mem wl128x_mem; + struct wl18xx_tx_mem wl18xx_mem; } __packed; /* Device time (in us) when the packet arrived to the driver */ __le32 start_time; -- GitLab From d2361c5140694c39add831693abcf82ad87fe31e Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:19 +0300 Subject: [PATCH 0523/6849] wl18xx: implement hw op for setting frame length in tx_hw_desc Set the frame length during Tx in a way compatible with the 18xx FW. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index c85492ead0f9..0a5422c88183 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -321,6 +321,19 @@ wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, desc->wl18xx_mem.reserved = 0; } +static void +wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +{ + desc->length = cpu_to_le16(skb->len); + + wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " + "len: %d life: %d mem: %d", desc->hlid, + le16_to_cpu(desc->length), + le16_to_cpu(desc->life_time), + desc->wl18xx_mem.total_mem_blocks); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -328,6 +341,7 @@ static struct wlcore_ops wl18xx_ops = { .ack_event = wl18xx_ack_event, .calc_tx_blocks = wl18xx_calc_tx_blocks, .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, + .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, }; int __devinit wl18xx_probe(struct platform_device *pdev) -- GitLab From f648eab75815086328ea92f31b10df16cf090075 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:20 +0300 Subject: [PATCH 0524/6849] wl18xx: define HW-rate translation elements/tables Define HW-rate conversion tables for the 18xx chip. Initialize the appropriate wlcore elements with these tables and values to allow conversion of HW-rates. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 115 ++++++++++++++++++++++++++ drivers/net/wireless/ti/wlcore/conf.h | 10 ++- 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 0a5422c88183..7dcb8327b17f 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -37,6 +37,118 @@ #define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 #define WL18XX_TX_HW_BLOCK_SIZE 268 +static const u8 wl18xx_rate_to_idx_2ghz[] = { + /* MCS rates are used only with 11n */ + 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ + 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */ + 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */ + 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */ + 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */ + 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */ + 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */ + 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */ + 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */ + 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */ + 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */ + 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */ + 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */ + 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */ + 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */ + 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */ + + 11, /* WL18XX_CONF_HW_RXTX_RATE_54 */ + 10, /* WL18XX_CONF_HW_RXTX_RATE_48 */ + 9, /* WL18XX_CONF_HW_RXTX_RATE_36 */ + 8, /* WL18XX_CONF_HW_RXTX_RATE_24 */ + + /* TI-specific rate */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */ + + 7, /* WL18XX_CONF_HW_RXTX_RATE_18 */ + 6, /* WL18XX_CONF_HW_RXTX_RATE_12 */ + 3, /* WL18XX_CONF_HW_RXTX_RATE_11 */ + 5, /* WL18XX_CONF_HW_RXTX_RATE_9 */ + 4, /* WL18XX_CONF_HW_RXTX_RATE_6 */ + 2, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */ + 1, /* WL18XX_CONF_HW_RXTX_RATE_2 */ + 0 /* WL18XX_CONF_HW_RXTX_RATE_1 */ +}; + +static const u8 wl18xx_rate_to_idx_5ghz[] = { + /* MCS rates are used only with 11n */ + 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ + 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */ + 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */ + 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */ + 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */ + 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */ + 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */ + 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */ + 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */ + 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */ + 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */ + 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */ + 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */ + 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */ + 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */ + 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */ + + 7, /* WL18XX_CONF_HW_RXTX_RATE_54 */ + 6, /* WL18XX_CONF_HW_RXTX_RATE_48 */ + 5, /* WL18XX_CONF_HW_RXTX_RATE_36 */ + 4, /* WL18XX_CONF_HW_RXTX_RATE_24 */ + + /* TI-specific rate */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */ + + 3, /* WL18XX_CONF_HW_RXTX_RATE_18 */ + 2, /* WL18XX_CONF_HW_RXTX_RATE_12 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11 */ + 1, /* WL18XX_CONF_HW_RXTX_RATE_9 */ + 0, /* WL18XX_CONF_HW_RXTX_RATE_6 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2 */ + CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1 */ +}; + +static const u8 *wl18xx_band_rate_to_idx[] = { + [IEEE80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz, + [IEEE80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz +}; + +enum wl18xx_hw_rates { + WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0, + WL18XX_CONF_HW_RXTX_RATE_MCS14, + WL18XX_CONF_HW_RXTX_RATE_MCS13, + WL18XX_CONF_HW_RXTX_RATE_MCS12, + WL18XX_CONF_HW_RXTX_RATE_MCS11, + WL18XX_CONF_HW_RXTX_RATE_MCS10, + WL18XX_CONF_HW_RXTX_RATE_MCS9, + WL18XX_CONF_HW_RXTX_RATE_MCS8, + WL18XX_CONF_HW_RXTX_RATE_MCS7, + WL18XX_CONF_HW_RXTX_RATE_MCS6, + WL18XX_CONF_HW_RXTX_RATE_MCS5, + WL18XX_CONF_HW_RXTX_RATE_MCS4, + WL18XX_CONF_HW_RXTX_RATE_MCS3, + WL18XX_CONF_HW_RXTX_RATE_MCS2, + WL18XX_CONF_HW_RXTX_RATE_MCS1, + WL18XX_CONF_HW_RXTX_RATE_MCS0, + WL18XX_CONF_HW_RXTX_RATE_54, + WL18XX_CONF_HW_RXTX_RATE_48, + WL18XX_CONF_HW_RXTX_RATE_36, + WL18XX_CONF_HW_RXTX_RATE_24, + WL18XX_CONF_HW_RXTX_RATE_22, + WL18XX_CONF_HW_RXTX_RATE_18, + WL18XX_CONF_HW_RXTX_RATE_12, + WL18XX_CONF_HW_RXTX_RATE_11, + WL18XX_CONF_HW_RXTX_RATE_9, + WL18XX_CONF_HW_RXTX_RATE_6, + WL18XX_CONF_HW_RXTX_RATE_5_5, + WL18XX_CONF_HW_RXTX_RATE_2, + WL18XX_CONF_HW_RXTX_RATE_1, + WL18XX_CONF_HW_RXTX_RATE_MAX, +}; + static struct wl18xx_conf wl18xx_default_conf = { .phy = { .phy_standalone = 0x00, @@ -363,6 +475,9 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->num_tx_desc = 32; wl->normal_tx_spare = WL18XX_TX_HW_BLOCK_SPARE; wl->gem_tx_spare = WL18XX_TX_HW_GEM_BLOCK_SPARE; + wl->band_rate_to_idx = wl18xx_band_rate_to_idx; + wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; + wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; return wlcore_probe(wl, pdev); } diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index fef0db4213bc..0798c1e88814 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -45,7 +45,15 @@ enum { CONF_HW_BIT_RATE_MCS_4 = BIT(17), CONF_HW_BIT_RATE_MCS_5 = BIT(18), CONF_HW_BIT_RATE_MCS_6 = BIT(19), - CONF_HW_BIT_RATE_MCS_7 = BIT(20) + CONF_HW_BIT_RATE_MCS_7 = BIT(20), + CONF_HW_BIT_RATE_MCS_8 = BIT(21), + CONF_HW_BIT_RATE_MCS_9 = BIT(22), + CONF_HW_BIT_RATE_MCS_10 = BIT(23), + CONF_HW_BIT_RATE_MCS_11 = BIT(24), + CONF_HW_BIT_RATE_MCS_12 = BIT(25), + CONF_HW_BIT_RATE_MCS_13 = BIT(26), + CONF_HW_BIT_RATE_MCS_14 = BIT(27), + CONF_HW_BIT_RATE_MCS_15 = BIT(28), }; enum { -- GitLab From 1fab39dc4a5fbd241787eb964d911d0aecbbcb84 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:21 +0300 Subject: [PATCH 0525/6849] wl18xx: add fw_status private data The wl18xx chip passes extra information in the firmware status to the driver. Add a private data section to handle that. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 2 +- drivers/net/wireless/ti/wl18xx/wl18xx.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 7dcb8327b17f..4a5ef6e53954 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -478,7 +478,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->band_rate_to_idx = wl18xx_band_rate_to_idx; wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; - + wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); return wlcore_probe(wl, pdev); } diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index 58709bb88b7b..68ef5ba2f607 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -30,4 +30,22 @@ struct wl18xx_priv { u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; }; +#define WL18XX_FW_MAX_TX_STATUS_DESC 33 + +struct wl18xx_fw_status_priv { + /* + * Index in released_tx_desc for first byte that holds + * released tx host desc + */ + u8 fw_release_idx; + + /* + * Array of host Tx descriptors, where fw_release_idx + * indicated the first released idx. + */ + u8 released_tx_desc[WL18XX_FW_MAX_TX_STATUS_DESC]; + + u8 padding[2]; +}; + #endif /* __WL18XX_PRIV_H__ */ -- GitLab From 7cfefd1f2acbd5ff2a1a8846de058064bd63550a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:22 +0300 Subject: [PATCH 0526/6849] wl18xx: set Rx block-size alignment quirk The 18xx FW sends Rx blocks with aligned length. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 4a5ef6e53954..a074d811fef0 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -243,7 +243,8 @@ static int wl18xx_identify_chip(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", wl->chip.id); wl->sr_fw_name = WL18XX_FW_NAME; - wl->quirks |= WLCORE_QUIRK_NO_ELP; + wl->quirks |= WLCORE_QUIRK_NO_ELP | + WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; /* TODO: need to blocksize alignment for RX/TX separately? */ break; -- GitLab From 9c809f888370d87129d17028d515bb025fe94175 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:23 +0300 Subject: [PATCH 0527/6849] wl18xx: implement hw op for getting rx buffer data alignment Implement the HW op for getting alignment state in wl18xx. The FW aligns the Rx Ethernet payload data. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 13 +++++++++++++ drivers/net/wireless/ti/wlcore/rx.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index a074d811fef0..fef872608e00 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -27,6 +27,8 @@ #include "../wlcore/io.h" #include "../wlcore/acx.h" #include "../wlcore/tx.h" +#include "../wlcore/rx.h" +#include "../wlcore/io.h" #include "../wlcore/boot.h" #include "reg.h" @@ -447,6 +449,16 @@ wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, desc->wl18xx_mem.total_mem_blocks); } +static enum wl_rx_buf_align +wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc) +{ + if (rx_desc & RX_BUF_PADDED_PAYLOAD) + return WLCORE_RX_BUF_PADDED; + + return WLCORE_RX_BUF_ALIGNED; +} + + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -455,6 +467,7 @@ static struct wlcore_ops wl18xx_ops = { .calc_tx_blocks = wl18xx_calc_tx_blocks, .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, + .get_rx_buf_align = wl18xx_get_rx_buf_align, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h index e9a162a864ca..277936e14137 100644 --- a/drivers/net/wireless/ti/wlcore/rx.h +++ b/drivers/net/wireless/ti/wlcore/rx.h @@ -102,6 +102,9 @@ /* If set, the start of IP payload is not 4 bytes aligned */ #define RX_BUF_UNALIGNED_PAYLOAD BIT(20) +/* If set, the buffer was padded by the FW to be 4 bytes aligned */ +#define RX_BUF_PADDED_PAYLOAD BIT(30) + /* Describes the alignment state of a Rx buffer */ enum wl_rx_buf_align { WLCORE_RX_BUF_ALIGNED, -- GitLab From 30e2dd798dbd5929f981ec0c77ab8567e8859ad9 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:24 +0300 Subject: [PATCH 0528/6849] wl18xx: implement hw op for getting rx packet data length Implement the 18xx-specific way for getting the length of a Rx packet. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index fef872608e00..40ed53c02866 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -458,6 +458,17 @@ wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc) return WLCORE_RX_BUF_ALIGNED; } +static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, + u32 data_len) +{ + struct wl1271_rx_descriptor *desc = rx_data; + + /* invalid packet */ + if (data_len < sizeof(*desc)) + return 0; + + return data_len - sizeof(*desc); +} static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, @@ -468,6 +479,7 @@ static struct wlcore_ops wl18xx_ops = { .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, .get_rx_buf_align = wl18xx_get_rx_buf_align, + .get_rx_packet_len = wl18xx_get_rx_packet_len, }; int __devinit wl18xx_probe(struct platform_device *pdev) -- GitLab From 872b345fbaef290f890d0bbd34b78ab50269980f Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:25 +0300 Subject: [PATCH 0529/6849] wl18xx: implement immediate Tx completion Implement immediate Tx completion for the 18xx family. Move 18xx specific Tx code to new tx.c/h files and create helper header files for definitions. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/Makefile | 2 +- drivers/net/wireless/ti/wl18xx/main.c | 11 ++- drivers/net/wireless/ti/wl18xx/tx.c | 126 ++++++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/tx.h | 36 +++++++ drivers/net/wireless/ti/wl18xx/wl18xx.h | 3 + drivers/net/wireless/ti/wlcore/tx.c | 4 +- drivers/net/wireless/ti/wlcore/tx.h | 1 + 7 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 drivers/net/wireless/ti/wl18xx/tx.c create mode 100644 drivers/net/wireless/ti/wl18xx/tx.h diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile index d187037bef70..dd3b4c13fa3c 100644 --- a/drivers/net/wireless/ti/wl18xx/Makefile +++ b/drivers/net/wireless/ti/wl18xx/Makefile @@ -1,3 +1,3 @@ -wl18xx-objs = main.o +wl18xx-objs = main.o tx.o obj-$(CONFIG_WL18XX) += wl18xx.o diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 40ed53c02866..ae71131a4bba 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -33,11 +33,9 @@ #include "reg.h" #include "conf.h" +#include "tx.h" #include "wl18xx.h" -#define WL18XX_TX_HW_BLOCK_SPARE 1 -#define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 -#define WL18XX_TX_HW_BLOCK_SIZE 268 static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -470,6 +468,11 @@ static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, return data_len - sizeof(*desc); } +static void wl18xx_tx_immediate_completion(struct wl1271 *wl) +{ + wl18xx_tx_immediate_complete(wl); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -480,6 +483,8 @@ static struct wlcore_ops wl18xx_ops = { .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, .get_rx_buf_align = wl18xx_get_rx_buf_align, .get_rx_packet_len = wl18xx_get_rx_packet_len, + .tx_immediate_compl = wl18xx_tx_immediate_completion, + .tx_delayed_compl = NULL, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c new file mode 100644 index 000000000000..4e12f56b394f --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/tx.c @@ -0,0 +1,126 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "../wlcore/wlcore.h" +#include "../wlcore/cmd.h" +#include "../wlcore/debug.h" +#include "../wlcore/acx.h" +#include "../wlcore/tx.h" + +#include "wl18xx.h" +#include "tx.h" + +static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) +{ + struct ieee80211_tx_info *info; + struct sk_buff *skb; + int id = tx_stat_byte & WL18XX_TX_STATUS_DESC_ID_MASK; + bool tx_success; + + /* check for id legality */ + if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) { + wl1271_warning("illegal id in tx completion: %d", id); + return; + } + + /* a zero bit indicates Tx success */ + tx_success = !(tx_stat_byte & BIT(WL18XX_TX_STATUS_STAT_BIT_IDX)); + + + skb = wl->tx_frames[id]; + info = IEEE80211_SKB_CB(skb); + + if (wl12xx_is_dummy_packet(wl, skb)) { + wl1271_free_tx_id(wl, id); + return; + } + + /* update the TX status info */ + if (tx_success && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) + info->flags |= IEEE80211_TX_STAT_ACK; + + /* no real data about Tx completion */ + info->status.rates[0].idx = -1; + info->status.rates[0].count = 0; + info->status.rates[0].flags = 0; + info->status.ack_signal = -1; + + if (!tx_success) + wl->stats.retry_count++; + + /* + * TODO: update sequence number for encryption? seems to be + * unsupported for now. needed for recovery with encryption. + */ + + /* remove private header from packet */ + skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); + + /* remove TKIP header space if present */ + if (info->control.hw_key && + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { + int hdrlen = ieee80211_get_hdrlen_from_skb(skb); + memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, hdrlen); + skb_pull(skb, WL1271_EXTRA_SPACE_TKIP); + } + + wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p success %d", + id, skb, tx_success); + + /* return the packet to the stack */ + skb_queue_tail(&wl->deferred_tx_queue, skb); + queue_work(wl->freezable_wq, &wl->netstack_work); + wl1271_free_tx_id(wl, id); +} + +void wl18xx_tx_immediate_complete(struct wl1271 *wl) +{ + struct wl18xx_fw_status_priv *status_priv = + (struct wl18xx_fw_status_priv *)wl->fw_status->priv; + struct wl18xx_priv *priv = wl->priv; + u8 i; + + /* nothing to do here */ + if (priv->last_fw_rls_idx == status_priv->fw_release_idx) + return; + + /* freed Tx descriptors */ + wl1271_debug(DEBUG_TX, "last released desc = %d, current idx = %d", + priv->last_fw_rls_idx, status_priv->fw_release_idx); + + if (status_priv->fw_release_idx >= WL18XX_FW_MAX_TX_STATUS_DESC) { + wl1271_error("invalid desc release index %d", + status_priv->fw_release_idx); + WARN_ON(1); + return; + } + + for (i = priv->last_fw_rls_idx; + i != status_priv->fw_release_idx; + i = (i + 1) % WL18XX_FW_MAX_TX_STATUS_DESC) { + wl18xx_tx_complete_packet(wl, + status_priv->released_tx_desc[i]); + + wl->tx_results_count++; + } + + priv->last_fw_rls_idx = status_priv->fw_release_idx; +} diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h new file mode 100644 index 000000000000..a91eb10a42f2 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/tx.h @@ -0,0 +1,36 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL18XX_TX_H__ +#define __WL18XX_TX_H__ + +#include "../wlcore/wlcore.h" + +#define WL18XX_TX_HW_BLOCK_SPARE 1 +#define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 +#define WL18XX_TX_HW_BLOCK_SIZE 268 + +#define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F +#define WL18XX_TX_STATUS_STAT_BIT_IDX 7 + +void wl18xx_tx_immediate_complete(struct wl1271 *wl); + +#endif /* __WL12XX_TX_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index 68ef5ba2f607..d24f9c0fd277 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -28,6 +28,9 @@ struct wl18xx_priv { /* buffer for sending commands to FW */ u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; + + /* Index of last released Tx desc in FW */ + u8 last_fw_rls_idx; }; #define WL18XX_FW_MAX_TX_STATUS_DESC 33 diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 6893bc207994..b4e02ef22fc5 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -72,7 +72,7 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb) return id; } -static void wl1271_free_tx_id(struct wl1271 *wl, int id) +void wl1271_free_tx_id(struct wl1271 *wl, int id) { if (__test_and_clear_bit(id, wl->tx_frames_map)) { if (unlikely(wl->tx_frames_cnt == wl->num_tx_desc)) @@ -82,6 +82,7 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id) wl->tx_frames_cnt--; } } +EXPORT_SYMBOL(wl1271_free_tx_id); static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, struct sk_buff *skb) @@ -127,6 +128,7 @@ bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) { return wl->dummy_packet == skb; } +EXPORT_SYMBOL(wl12xx_is_dummy_packet); u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct sk_buff *skb) diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index e440c313537d..220727421fa2 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -237,6 +237,7 @@ bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, unsigned int packet_length); +void wl1271_free_tx_id(struct wl1271 *wl, int id); /* from main.c */ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); -- GitLab From b8422dcb865befc5d2d7c21e8427eedf32558fea Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:26 +0300 Subject: [PATCH 0530/6849] wl18xx: add hw_init operation Add wl18xx-specific HW initialization operation and create acx.[ch] files to support that. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/Makefile | 2 +- drivers/net/wireless/ti/wl18xx/acx.c | 57 +++++++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/acx.h | 52 ++++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/main.c | 32 ++++++++++++++ drivers/net/wireless/ti/wlcore/acx.h | 2 + 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ti/wl18xx/acx.c create mode 100644 drivers/net/wireless/ti/wl18xx/acx.h diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile index dd3b4c13fa3c..764d598bc968 100644 --- a/drivers/net/wireless/ti/wl18xx/Makefile +++ b/drivers/net/wireless/ti/wl18xx/Makefile @@ -1,3 +1,3 @@ -wl18xx-objs = main.o tx.o +wl18xx-objs = main.o acx.o tx.o obj-$(CONFIG_WL18XX) += wl18xx.o diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c new file mode 100644 index 000000000000..aed8d0dff91b --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/acx.c @@ -0,0 +1,57 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "../wlcore/cmd.h" +#include "../wlcore/debug.h" +#include "../wlcore/acx.h" + +#include "acx.h" + +int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, + u32 sdio_blk_size, u32 extra_mem_blks, + u32 len_field_size) +{ + struct wl18xx_acx_host_config_bitmap *bitmap_conf; + int ret; + + bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); + if (!bitmap_conf) { + ret = -ENOMEM; + goto out; + } + + bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap); + bitmap_conf->host_sdio_block_size = cpu_to_le32(sdio_blk_size); + bitmap_conf->extra_mem_blocks = cpu_to_le32(extra_mem_blks); + bitmap_conf->length_field_size = cpu_to_le32(len_field_size); + + ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP, + bitmap_conf, sizeof(*bitmap_conf)); + if (ret < 0) { + wl1271_warning("wl1271 bitmap config opt failed: %d", ret); + goto out; + } + +out: + kfree(bitmap_conf); + + return ret; +} diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h new file mode 100644 index 000000000000..c8eebd8500c1 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -0,0 +1,52 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL18XX_ACX_H__ +#define __WL18XX_ACX_H__ + +#include "../wlcore/wlcore.h" + +/* numbers of bits the length field takes (add 1 for the actual number) */ +#define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 + +struct wl18xx_acx_host_config_bitmap { + struct acx_header header; + + __le32 host_cfg_bitmap; + + __le32 host_sdio_block_size; + + /* extra mem blocks per frame in TX. */ + __le32 extra_mem_blocks; + + /* + * number of bits of the length field in the first TX word + * (up to 15 - for using the entire 16 bits). + */ + __le32 length_field_size; + +} __packed; + +int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, + u32 sdio_blk_size, u32 extra_mem_blks, + u32 len_field_size); + +#endif /* __WL12XX_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index ae71131a4bba..1e0719c7ccb9 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -33,6 +33,7 @@ #include "reg.h" #include "conf.h" +#include "acx.h" #include "tx.h" #include "wl18xx.h" @@ -473,6 +474,36 @@ static void wl18xx_tx_immediate_completion(struct wl1271 *wl) wl18xx_tx_immediate_complete(wl); } +static int wl18xx_hw_init(struct wl1271 *wl) +{ + int ret; + u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE | + HOST_IF_CFG_ADD_RX_ALIGNMENT; + + u32 sdio_align_size = 0; + + /* Enable Tx SDIO padding */ + if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) { + host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; + sdio_align_size = WL12XX_BUS_BLOCK_SIZE; + } + + /* Enable Rx SDIO padding */ + if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) { + host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK; + sdio_align_size = WL12XX_BUS_BLOCK_SIZE; + } + + ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, + sdio_align_size, + WL18XX_TX_HW_BLOCK_SPARE, + WL18XX_HOST_IF_LEN_SIZE_FIELD); + if (ret < 0) + return ret; + + return ret; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -485,6 +516,7 @@ static struct wlcore_ops wl18xx_ops = { .get_rx_packet_len = wl18xx_get_rx_packet_len, .tx_immediate_compl = wl18xx_tx_immediate_completion, .tx_delayed_compl = NULL, + .hw_init = wl18xx_hw_init, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index e6a74869a5ff..2d1302d23ac8 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -828,6 +828,8 @@ struct wl1271_acx_keep_alive_config { #define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) #define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) #define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) +#define HOST_IF_CFG_RX_PAD_TO_SDIO_BLK BIT(4) +#define HOST_IF_CFG_ADD_RX_ALIGNMENT BIT(6) enum { WL1271_ACX_TRIG_TYPE_LEVEL = 0, -- GitLab From 2fc28de5989e1c40fee4e92e2a8f3bdd47b1b34a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:27 +0300 Subject: [PATCH 0531/6849] wlcore/wl18xx: add hw op for setting Tx HW checksum Some chip families are capable of checksumming certain classes of Tx packets in HW. Indicate this fact in the netdev features and perform the HW checksum by protocol type for the 18xx family. Fix the location of the skb network header when we move it so we can rely on it when setting the checksum. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 8 +++++++ drivers/net/wireless/ti/wl18xx/acx.c | 26 +++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/acx.h | 16 +++++++++++++ drivers/net/wireless/ti/wl18xx/main.c | 31 +++++++++++++++++++++++++ drivers/net/wireless/ti/wlcore/acx.h | 1 + drivers/net/wireless/ti/wlcore/hw_ops.h | 11 +++++++++ drivers/net/wireless/ti/wlcore/tx.c | 3 ++- drivers/net/wireless/ti/wlcore/tx.h | 11 ++++++++- drivers/net/wireless/ti/wlcore/wlcore.h | 3 +++ 9 files changed, 108 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index d7dd3def07b5..8141447e8f96 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1288,6 +1288,13 @@ static void wl12xx_get_mac(struct wl1271 *wl) wl12xx_get_fuse_mac(wl); } +static void wl12xx_set_tx_desc_csum(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +{ + desc->wl12xx_reserved = 0; +} + static struct wlcore_ops wl12xx_ops = { .identify_chip = wl12xx_identify_chip, .identify_fw = wl12xx_identify_fw, @@ -1306,6 +1313,7 @@ static struct wlcore_ops wl12xx_ops = { .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask, .get_pg_ver = wl12xx_get_pg_ver, .get_mac = wl12xx_get_mac, + .set_tx_desc_csum = wl12xx_set_tx_desc_csum, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c index aed8d0dff91b..3379db23a165 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.c +++ b/drivers/net/wireless/ti/wl18xx/acx.c @@ -55,3 +55,29 @@ out: return ret; } + +int wl18xx_acx_set_checksum_state(struct wl1271 *wl) +{ + struct wl18xx_acx_checksum_state *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx checksum state"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->checksum_state = CHECKSUM_OFFLOAD_ENABLED; + + ret = wl1271_cmd_configure(wl, ACX_CHECKSUM_CONFIG, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("failed to set Tx checksum state: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index c8eebd8500c1..544db6ef3841 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -45,8 +45,24 @@ struct wl18xx_acx_host_config_bitmap { } __packed; +enum { + CHECKSUM_OFFLOAD_DISABLED = 0, + CHECKSUM_OFFLOAD_ENABLED = 1, + CHECKSUM_OFFLOAD_FAKE_RX = 2, + CHECKSUM_OFFLOAD_INVALID = 0xFF +}; + +struct wl18xx_acx_checksum_state { + struct acx_header header; + + /* enum acx_checksum_state */ + u8 checksum_state; + u8 pad[3]; +} __packed; + int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, u32 sdio_blk_size, u32 extra_mem_blks, u32 len_field_size); +int wl18xx_acx_set_checksum_state(struct wl1271 *wl); #endif /* __WL12XX_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 1e0719c7ccb9..c47f52c81a72 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -21,6 +21,7 @@ #include #include +#include #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" @@ -501,9 +502,38 @@ static int wl18xx_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl18xx_acx_set_checksum_state(wl); + if (ret != 0) + return ret; + return ret; } +static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +{ + u32 ip_hdr_offset; + struct iphdr *ip_hdr; + + if (skb->ip_summed != CHECKSUM_PARTIAL) { + desc->wl18xx_checksum_data = 0; + return; + } + + ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb); + if (WARN_ON(ip_hdr_offset >= (1<<7))) { + desc->wl18xx_checksum_data = 0; + return; + } + + desc->wl18xx_checksum_data = ip_hdr_offset << 1; + + /* FW is interested only in the LSB of the protocol TCP=0 UDP=1 */ + ip_hdr = (void *)skb_network_header(skb); + desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -517,6 +547,7 @@ static struct wlcore_ops wl18xx_ops = { .tx_immediate_compl = wl18xx_tx_immediate_completion, .tx_delayed_compl = NULL, .hw_init = wl18xx_hw_init, + .set_tx_desc_csum = wl18xx_set_tx_desc_csum, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 2d1302d23ac8..ff0c5ba8e8ff 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -1245,6 +1245,7 @@ enum { ACX_CONFIG_HANGOVER = 0x0042, ACX_FEATURE_CFG = 0x0043, ACX_PROTECTION_CFG = 0x0044, + ACX_CHECKSUM_CONFIG = 0x0045, }; diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 9384b4d56c24..4573249ea89f 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -119,4 +119,15 @@ static inline int wlcore_identify_fw(struct wl1271 *wl) return 0; } +static inline void +wlcore_hw_set_tx_desc_csum(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +{ + if (!wl->ops->set_tx_desc_csum) + BUG_ON(1); + + wl->ops->set_tx_desc_csum(wl, desc, skb); +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index b4e02ef22fc5..44e4e7bb29bd 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -270,6 +270,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (extra) { int hdrlen = ieee80211_hdrlen(frame_control); memmove(frame_start, hdr, hdrlen); + skb_set_network_header(skb, skb_network_offset(skb) + extra); } /* configure packet life time */ @@ -332,9 +333,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, ieee80211_has_protected(frame_control)) tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; - desc->reserved = 0; desc->tx_attr = cpu_to_le16(tx_attr); + wlcore_hw_set_tx_desc_csum(wl, desc, skb); wlcore_hw_set_tx_desc_data_len(wl, desc, skb); } diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 220727421fa2..e24c436bf65f 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -130,7 +130,16 @@ struct wl1271_tx_hw_descr { u8 tid; /* host link ID (HLID) */ u8 hlid; - u8 reserved; + + union { + u8 wl12xx_reserved; + + /* + * bit 0 -> 0 = udp, 1 = tcp + * bit 1:7 -> IP header offset + */ + u8 wl18xx_checksum_data; + } __packed; } __packed; enum wl1271_tx_hw_res_status { diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 0b3f0b586f4b..c062d304ab0d 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -61,6 +61,9 @@ struct wlcore_ops { struct wl12xx_vif *wlvif); s8 (*get_pg_ver)(struct wl1271 *wl); void (*get_mac)(struct wl1271 *wl); + void (*set_tx_desc_csum)(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb); }; enum wlcore_partitions { -- GitLab From 169da04f523bafee46993b1efbddb913641aad56 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:28 +0300 Subject: [PATCH 0532/6849] wlcore/wl18xx: add hw op for Rx HW checksum Some chip families can checksum certain classes of Rx packets in FW. Implement the Rx-checksum feature as a HW-op. For the 18xx chip-family, set Rx-checsum according to indication from FW. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 1 + drivers/net/wireless/ti/wl18xx/main.c | 11 +++++++++++ drivers/net/wireless/ti/wlcore/hw_ops.h | 9 +++++++++ drivers/net/wireless/ti/wlcore/rx.c | 1 + drivers/net/wireless/ti/wlcore/wlcore.h | 4 ++++ 5 files changed, 26 insertions(+) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 8141447e8f96..a3336534eb2a 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1314,6 +1314,7 @@ static struct wlcore_ops wl12xx_ops = { .get_pg_ver = wl12xx_get_pg_ver, .get_mac = wl12xx_get_mac, .set_tx_desc_csum = wl12xx_set_tx_desc_csum, + .set_rx_csum = NULL, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index c47f52c81a72..90fccb775727 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -39,6 +39,8 @@ #include "wl18xx.h" +#define WL18XX_RX_CHECKSUM_MASK 0x40 + static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ @@ -534,6 +536,14 @@ static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01); } +static void wl18xx_set_rx_csum(struct wl1271 *wl, + struct wl1271_rx_descriptor *desc, + struct sk_buff *skb) +{ + if (desc->status & WL18XX_RX_CHECKSUM_MASK) + skb->ip_summed = CHECKSUM_UNNECESSARY; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -548,6 +558,7 @@ static struct wlcore_ops wl18xx_ops = { .tx_delayed_compl = NULL, .hw_init = wl18xx_hw_init, .set_tx_desc_csum = wl18xx_set_tx_desc_csum, + .set_rx_csum = wl18xx_set_rx_csum, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 4573249ea89f..80f3d75ceddf 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -130,4 +130,13 @@ wlcore_hw_set_tx_desc_csum(struct wl1271 *wl, wl->ops->set_tx_desc_csum(wl, desc, skb); } +static inline void +wlcore_hw_set_rx_csum(struct wl1271 *wl, + struct wl1271_rx_descriptor *desc, + struct sk_buff *skb) +{ + if (wl->ops->set_rx_csum) + wl->ops->set_rx_csum(wl, desc, skb); +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index d6a3c6b07827..2672b1d16cef 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -186,6 +186,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, is_data = 1; wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); + wlcore_hw_set_rx_csum(wl, desc, skb); seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d hlid %d", skb, diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index c062d304ab0d..2922d8aec699 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -33,6 +33,7 @@ /* forward declaration */ struct wl1271_tx_hw_descr; enum wl_rx_buf_align; +struct wl1271_rx_descriptor; struct wlcore_ops { int (*identify_chip)(struct wl1271 *wl); @@ -64,6 +65,9 @@ struct wlcore_ops { void (*set_tx_desc_csum)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, struct sk_buff *skb); + void (*set_rx_csum)(struct wl1271 *wl, + struct wl1271_rx_descriptor *desc, + struct sk_buff *skb); }; enum wlcore_partitions { -- GitLab From 23ee9bf8c3cb57768bba31a8cc62b87d39ca4e56 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:29 +0300 Subject: [PATCH 0533/6849] wl18xx: add runtime configuration parameters Now wlcore requires the lower drivers to set the correct configuration. Move the existing private configuration to the proper place and add all generic configuration parameters. The important changes are in Tx interrupt pacing and Rx BA window size. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/conf.h | 4 +- drivers/net/wireless/ti/wl18xx/main.c | 381 ++++++++++++++++++++++-- drivers/net/wireless/ti/wl18xx/wl18xx.h | 3 + 3 files changed, 360 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index 7cd7bf16879e..d2b097e4d24e 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -48,9 +48,7 @@ struct wl18xx_conf_phy { u8 secondary_clock_setting_time; }; -struct wl18xx_conf { - /* TODO: move the wlcore conf here? */ - +struct wl18xx_priv_conf { struct wl18xx_conf_phy phy; }; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 90fccb775727..fd7a803ff98c 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -153,7 +153,324 @@ enum wl18xx_hw_rates { WL18XX_CONF_HW_RXTX_RATE_MAX, }; -static struct wl18xx_conf wl18xx_default_conf = { +static struct wlcore_conf wl18xx_conf = { + .sg = { + .params = { + [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10, + [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180, + [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10, + [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180, + [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10, + [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80, + [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10, + [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80, + [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8, + [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8, + [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20, + [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20, + [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20, + [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35, + [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16, + [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35, + [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32, + [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50, + [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28, + [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50, + [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10, + [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20, + [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75, + [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15, + [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27, + [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17, + /* active scan params */ + [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, + [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, + [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, + /* passive scan params */ + [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800, + [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200, + [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, + /* passive scan in dual antenna params */ + [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0, + [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0, + [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0, + /* general params */ + [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1, + [CONF_SG_ANTENNA_CONFIGURATION] = 0, + [CONF_SG_BEACON_MISS_PERCENT] = 60, + [CONF_SG_DHCP_TIME] = 5000, + [CONF_SG_RXT] = 1200, + [CONF_SG_TXT] = 1000, + [CONF_SG_ADAPTIVE_RXT_TXT] = 1, + [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3, + [CONF_SG_HV3_MAX_SERVED] = 6, + [CONF_SG_PS_POLL_TIMEOUT] = 10, + [CONF_SG_UPSD_TIMEOUT] = 10, + [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2, + [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5, + [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30, + /* AP params */ + [CONF_AP_BEACON_MISS_TX] = 3, + [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10, + [CONF_AP_BEACON_WINDOW_INTERVAL] = 2, + [CONF_AP_CONNECTION_PROTECTION_TIME] = 0, + [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25, + [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25, + /* CTS Diluting params */ + [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0, + [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0, + }, + .state = CONF_SG_PROTECTIVE, + }, + .rx = { + .rx_msdu_life_time = 512000, + .packet_detection_threshold = 0, + .ps_poll_timeout = 15, + .upsd_timeout = 15, + .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD, + .rx_cca_threshold = 0, + .irq_blk_threshold = 0xFFFF, + .irq_pkt_threshold = 0, + .irq_timeout = 600, + .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, + }, + .tx = { + .tx_energy_detection = 0, + .sta_rc_conf = { + .enabled_rates = 0, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + .ac_conf_count = 4, + .ac_conf = { + [CONF_TX_AC_BE] = { + .ac = CONF_TX_AC_BE, + .cw_min = 15, + .cw_max = 63, + .aifsn = 3, + .tx_op_limit = 0, + }, + [CONF_TX_AC_BK] = { + .ac = CONF_TX_AC_BK, + .cw_min = 15, + .cw_max = 63, + .aifsn = 7, + .tx_op_limit = 0, + }, + [CONF_TX_AC_VI] = { + .ac = CONF_TX_AC_VI, + .cw_min = 15, + .cw_max = 63, + .aifsn = CONF_TX_AIFS_PIFS, + .tx_op_limit = 3008, + }, + [CONF_TX_AC_VO] = { + .ac = CONF_TX_AC_VO, + .cw_min = 15, + .cw_max = 63, + .aifsn = CONF_TX_AIFS_PIFS, + .tx_op_limit = 1504, + }, + }, + .max_tx_retries = 100, + .ap_aging_period = 300, + .tid_conf_count = 4, + .tid_conf = { + [CONF_TX_AC_BE] = { + .queue_id = CONF_TX_AC_BE, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_BE, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + [CONF_TX_AC_BK] = { + .queue_id = CONF_TX_AC_BK, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_BK, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + [CONF_TX_AC_VI] = { + .queue_id = CONF_TX_AC_VI, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VI, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + [CONF_TX_AC_VO] = { + .queue_id = CONF_TX_AC_VO, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VO, + .ps_scheme = CONF_PS_SCHEME_LEGACY, + .ack_policy = CONF_ACK_POLICY_LEGACY, + .apsd_conf = {0, 0}, + }, + }, + .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, + .tx_compl_timeout = 350, + .tx_compl_threshold = 10, + .basic_rate = CONF_HW_BIT_RATE_1MBPS, + .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, + .tmpl_short_retry_limit = 10, + .tmpl_long_retry_limit = 10, + .tx_watchdog_timeout = 5000, + }, + .conn = { + .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, + .listen_interval = 1, + .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, + .suspend_listen_interval = 3, + .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, + .bcn_filt_ie_count = 2, + .bcn_filt_ie = { + [0] = { + .ie = WLAN_EID_CHANNEL_SWITCH, + .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, + }, + [1] = { + .ie = WLAN_EID_HT_OPERATION, + .rule = CONF_BCN_RULE_PASS_ON_CHANGE, + }, + }, + .synch_fail_thold = 10, + .bss_lose_timeout = 100, + .beacon_rx_timeout = 10000, + .broadcast_timeout = 20000, + .rx_broadcast_in_ps = 1, + .ps_poll_threshold = 10, + .bet_enable = CONF_BET_MODE_ENABLE, + .bet_max_consecutive = 50, + .psm_entry_retries = 8, + .psm_exit_retries = 16, + .psm_entry_nullfunc_retries = 3, + .dynamic_ps_timeout = 40, + .forced_ps = false, + .keep_alive_interval = 55000, + .max_listen_interval = 20, + }, + .itrim = { + .enable = false, + .timeout = 50000, + }, + .pm_config = { + .host_clk_settling_time = 5000, + .host_fast_wakeup_support = false + }, + .roam_trigger = { + .trigger_pacing = 1, + .avg_weight_rssi_beacon = 20, + .avg_weight_rssi_data = 10, + .avg_weight_snr_beacon = 20, + .avg_weight_snr_data = 10, + }, + .scan = { + .min_dwell_time_active = 7500, + .max_dwell_time_active = 30000, + .min_dwell_time_passive = 100000, + .max_dwell_time_passive = 100000, + .num_probe_reqs = 2, + .split_scan_timeout = 50000, + }, + .sched_scan = { + /* + * Values are in TU/1000 but since sched scan FW command + * params are in TUs rounding up may occur. + */ + .base_dwell_time = 7500, + .max_dwell_time_delta = 22500, + /* based on 250bits per probe @1Mbps */ + .dwell_time_delta_per_probe = 2000, + /* based on 250bits per probe @6Mbps (plus a bit more) */ + .dwell_time_delta_per_probe_5 = 350, + .dwell_time_passive = 100000, + .dwell_time_dfs = 150000, + .num_probe_reqs = 2, + .rssi_threshold = -90, + .snr_threshold = 0, + }, + .ht = { + .rx_ba_win_size = 10, + .tx_ba_win_size = 10, + .inactivity_timeout = 10000, + .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP, + }, + .mem = { + .num_stations = 1, + .ssid_profiles = 1, + .rx_block_num = 40, + .tx_min_block_num = 40, + .dynamic_memory = 1, + .min_req_tx_blocks = 45, + .min_req_rx_blocks = 22, + .tx_min = 27, + }, + .fm_coex = { + .enable = true, + .swallow_period = 5, + .n_divider_fref_set_1 = 0xff, /* default */ + .n_divider_fref_set_2 = 12, + .m_divider_fref_set_1 = 148, + .m_divider_fref_set_2 = 0xffff, /* default */ + .coex_pll_stabilization_time = 0xffffffff, /* default */ + .ldo_stabilization_time = 0xffff, /* default */ + .fm_disturbed_band_margin = 0xff, /* default */ + .swallow_clk_diff = 0xff, /* default */ + }, + .rx_streaming = { + .duration = 150, + .queues = 0x1, + .interval = 20, + .always = 0, + }, + .fwlog = { + .mode = WL12XX_FWLOG_ON_DEMAND, + .mem_blocks = 2, + .severity = 0, + .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, + .output = WL12XX_FWLOG_OUTPUT_HOST, + .threshold = 0, + }, + .rate = { + .rate_retry_score = 32000, + .per_add = 8192, + .per_th1 = 2048, + .per_th2 = 4096, + .max_per = 8100, + .inverse_curiosity_factor = 5, + .tx_fail_low_th = 4, + .tx_fail_high_th = 10, + .per_alpha_shift = 4, + .per_add_shift = 13, + .per_beta1_shift = 10, + .per_beta2_shift = 8, + .rate_check_up = 2, + .rate_check_down = 12, + .rate_retry_policy = { + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + }, + }, + .hangover = { + .recover_time = 0, + .hangover_period = 20, + .dynamic_mode = 1, + .early_termination_mode = 1, + .max_period = 20, + .min_period = 1, + .increase_delta = 1, + .decrease_delta = 2, + .quiet_time = 4, + .increase_time = 1, + .window_size = 16, + }, +}; + +static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .phy = { .phy_standalone = 0x00, .primary_clock_setting_time = 0x05, @@ -323,42 +640,43 @@ static void wl18xx_pre_upload(struct wl1271 *wl) static void wl18xx_set_mac_and_phy(struct wl1271 *wl) { + struct wl18xx_priv *priv = wl->priv; + struct wl18xx_conf_phy *phy = &priv->conf.phy; struct wl18xx_mac_and_phy_params params; memset(¶ms, 0, sizeof(params)); - params.phy_standalone = wl18xx_default_conf.phy.phy_standalone; - params.rdl = wl18xx_default_conf.phy.rdl; - params.enable_clpc = wl18xx_default_conf.phy.enable_clpc; + params.phy_standalone = phy->phy_standalone; + params.rdl = phy->rdl; + params.enable_clpc = phy->enable_clpc; params.enable_tx_low_pwr_on_siso_rdl = - wl18xx_default_conf.phy.enable_tx_low_pwr_on_siso_rdl; - params.auto_detect = wl18xx_default_conf.phy.auto_detect; - params.dedicated_fem = wl18xx_default_conf.phy.dedicated_fem; - params.low_band_component = wl18xx_default_conf.phy.low_band_component; + phy->enable_tx_low_pwr_on_siso_rdl; + params.auto_detect = phy->auto_detect; + params.dedicated_fem = phy->dedicated_fem; + params.low_band_component = phy->low_band_component; params.low_band_component_type = - wl18xx_default_conf.phy.low_band_component_type; - params.high_band_component = - wl18xx_default_conf.phy.high_band_component; + phy->low_band_component_type; + params.high_band_component = phy->high_band_component; params.high_band_component_type = - wl18xx_default_conf.phy.high_band_component_type; + phy->high_band_component_type; params.number_of_assembled_ant2_4 = - wl18xx_default_conf.phy.number_of_assembled_ant2_4; + phy->number_of_assembled_ant2_4; params.number_of_assembled_ant5 = - wl18xx_default_conf.phy.number_of_assembled_ant5; - params.external_pa_dc2dc = wl18xx_default_conf.phy.external_pa_dc2dc; - params.tcxo_ldo_voltage = wl18xx_default_conf.phy.tcxo_ldo_voltage; - params.xtal_itrim_val = wl18xx_default_conf.phy.xtal_itrim_val; - params.srf_state = wl18xx_default_conf.phy.srf_state; - params.io_configuration = wl18xx_default_conf.phy.io_configuration; - params.sdio_configuration = wl18xx_default_conf.phy.sdio_configuration; - params.settings = wl18xx_default_conf.phy.settings; - params.rx_profile = wl18xx_default_conf.phy.rx_profile; + phy->number_of_assembled_ant5; + params.external_pa_dc2dc = phy->external_pa_dc2dc; + params.tcxo_ldo_voltage = phy->tcxo_ldo_voltage; + params.xtal_itrim_val = phy->xtal_itrim_val; + params.srf_state = phy->srf_state; + params.io_configuration = phy->io_configuration; + params.sdio_configuration = phy->sdio_configuration; + params.settings = phy->settings; + params.rx_profile = phy->rx_profile; params.primary_clock_setting_time = - wl18xx_default_conf.phy.primary_clock_setting_time; + phy->primary_clock_setting_time; params.clock_valid_on_wake_up = - wl18xx_default_conf.phy.clock_valid_on_wake_up; + phy->clock_valid_on_wake_up; params.secondary_clock_setting_time = - wl18xx_default_conf.phy.secondary_clock_setting_time; + phy->secondary_clock_setting_time; /* TODO: hardcoded for now */ params.board_type = BOARD_TYPE_DVP_EVB_18XX; @@ -544,6 +862,17 @@ static void wl18xx_set_rx_csum(struct wl1271 *wl, skb->ip_summed = CHECKSUM_UNNECESSARY; } +static void wl18xx_conf_init(struct wl1271 *wl) +{ + struct wl18xx_priv *priv = wl->priv; + + /* apply driver default configuration */ + memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf)); + + /* apply default private configuration */ + memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -584,6 +913,8 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); + wl18xx_conf_init(wl); + return wlcore_probe(wl, pdev); } diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index d24f9c0fd277..c9bf5c6559f8 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -22,6 +22,7 @@ #ifndef __WL18XX_PRIV_H__ #define __WL18XX_PRIV_H__ +#include "conf.h" #define WL18XX_CMD_MAX_SIZE 740 @@ -29,6 +30,8 @@ struct wl18xx_priv { /* buffer for sending commands to FW */ u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; + struct wl18xx_priv_conf conf; + /* Index of last released Tx desc in FW */ u8 last_fw_rls_idx; }; -- GitLab From 83d08d3ff385c810a341a5c1b97a8c81df96673d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:30 +0300 Subject: [PATCH 0534/6849] wlcore: track current channel type per vif Track the current 802.11 channel type, defaulting to a NO_HT channel. Update the channel type element when changed by mac80211. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 9 ++++++++- drivers/net/wireless/ti/wlcore/wl12xx.h | 1 + drivers/net/wireless/ti/wlcore/wlcore.h | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index acef93390d3d..6f0361b23611 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1767,6 +1767,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl->rx_counter = 0; wl->power_level = WL1271_DEFAULT_POWER_LEVEL; + wl->channel_type = NL80211_CHAN_NO_HT; wl->tx_blocks_available = 0; wl->tx_allocated_blocks = 0; wl->tx_results_count = 0; @@ -1919,6 +1920,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) wlvif->band = wl->band; wlvif->channel = wl->channel; wlvif->power_level = wl->power_level; + wlvif->channel_type = wl->channel_type; INIT_WORK(&wlvif->rx_streaming_enable_work, wl1271_rx_streaming_enable_work); @@ -2469,11 +2471,13 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, /* if the channel changes while joined, join again */ if (changed & IEEE80211_CONF_CHANGE_CHANNEL && ((wlvif->band != conf->channel->band) || - (wlvif->channel != channel))) { + (wlvif->channel != channel) || + (wlvif->channel_type != conf->channel_type))) { /* send all pending packets */ wl1271_tx_work_locked(wl); wlvif->band = conf->channel->band; wlvif->channel = channel; + wlvif->channel_type = conf->channel_type; if (!is_ap) { /* @@ -2593,6 +2597,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { wl->band = conf->channel->band; wl->channel = channel; + wl->channel_type = conf->channel_type; } if (changed & IEEE80211_CONF_CHANGE_POWER) @@ -3704,6 +3709,7 @@ sta_not_found: u32 rates; int ieoffset; wlvif->aid = bss_conf->aid; + wlvif->channel_type = bss_conf->channel_type; wlvif->beacon_int = bss_conf->beacon_int; do_join = true; set_assoc = true; @@ -5117,6 +5123,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) wl->rx_counter = 0; wl->power_level = WL1271_DEFAULT_POWER_LEVEL; wl->band = IEEE80211_BAND_2GHZ; + wl->channel_type = NL80211_CHAN_NO_HT; wl->flags = 0; wl->sg_enabled = true; wl->hw_pg_ver = -1; diff --git a/drivers/net/wireless/ti/wlcore/wl12xx.h b/drivers/net/wireless/ti/wlcore/wl12xx.h index f12bdf745180..05e6f74e4d25 100644 --- a/drivers/net/wireless/ti/wlcore/wl12xx.h +++ b/drivers/net/wireless/ti/wlcore/wl12xx.h @@ -367,6 +367,7 @@ struct wl12xx_vif { /* The current band */ enum ieee80211_band band; int channel; + enum nl80211_channel_type channel_type; u32 bitrate_masks[IEEE80211_NUM_BANDS]; u32 basic_rate_set; diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 2922d8aec699..83c43c9b10ed 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -362,6 +362,9 @@ struct wl1271 { /* RX Data filter rule state - enabled/disabled */ bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; + + /* the current channel type */ + enum nl80211_channel_type channel_type; }; int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); -- GitLab From a6298dbe95b5121dfc74102e7a113001859a1335 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:31 +0300 Subject: [PATCH 0535/6849] wl18xx: send channel type to FW on role start Translate the NL80211 channel type to a FW-specific channel type and send it to the FW as part of the role-start command. For wl12xx this has no effect - this element is treated as padding. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.c | 19 +++++++++++++++++++ drivers/net/wireless/ti/wlcore/cmd.h | 11 ++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 5b128a971449..8450f0eecc9b 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -291,6 +291,23 @@ static int wl12xx_get_new_session_id(struct wl1271 *wl, return wlvif->session_counter; } +static u8 wlcore_get_native_channel_type(u8 nl_channel_type) +{ + switch (nl_channel_type) { + case NL80211_CHAN_NO_HT: + return WLCORE_CHAN_NO_HT; + case NL80211_CHAN_HT20: + return WLCORE_CHAN_HT20; + case NL80211_CHAN_HT40MINUS: + return WLCORE_CHAN_HT40MINUS; + case NL80211_CHAN_HT40PLUS: + return WLCORE_CHAN_HT40PLUS; + default: + WARN_ON(1); + return WLCORE_CHAN_NO_HT; + } +} + static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) { @@ -407,6 +424,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len); memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN); cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); + cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); @@ -519,6 +537,7 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) /* FIXME: Change when adding DFS */ cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ cmd->channel = wlvif->channel; + cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); if (!bss_conf->hidden_ssid) { /* take the SSID from the beacon for backward compatibility */ diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index a46ae07cb77e..2aafe3df0fb0 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h @@ -266,13 +266,22 @@ enum wlcore_band { WLCORE_BAND_MAX_RADIO = 0x7F, }; +enum wlcore_channel_type { + WLCORE_CHAN_NO_HT, + WLCORE_CHAN_HT20, + WLCORE_CHAN_HT40MINUS, + WLCORE_CHAN_HT40PLUS +}; + struct wl12xx_cmd_role_start { struct wl1271_cmd_header header; u8 role_id; u8 band; u8 channel; - u8 padding; + + /* enum wlcore_channel_type */ + u8 channel_type; union { struct { -- GitLab From f13af3484f04f61794d90dbdab28df8bf8b9d667 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:32 +0300 Subject: [PATCH 0536/6849] wl18xx: ipmlement ap_rate_mask hw op Enable wide-chan or MIMO rates when appropriate. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 18 ++++++++++++++++++ drivers/net/wireless/ti/wl18xx/tx.h | 6 ++++++ drivers/net/wireless/ti/wlcore/conf.h | 6 ++++++ 3 files changed, 30 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index fd7a803ff98c..77840ddd3129 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -862,6 +862,23 @@ static void wl18xx_set_rx_csum(struct wl1271 *wl, skb->ip_summed = CHECKSUM_UNNECESSARY; } +static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, + struct wl12xx_vif *wlvif) +{ + u32 hw_rate_set = wlvif->rate_set; + + if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || + wlvif->channel_type == NL80211_CHAN_HT40PLUS) { + wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); + hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN; + + /* we don't support MIMO in wide-channel mode */ + hw_rate_set &= ~CONF_TX_MIMO_RATES; + } + + return hw_rate_set; +} + static void wl18xx_conf_init(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; @@ -888,6 +905,7 @@ static struct wlcore_ops wl18xx_ops = { .hw_init = wl18xx_hw_init, .set_tx_desc_csum = wl18xx_set_tx_desc_csum, .set_rx_csum = wl18xx_set_rx_csum, + .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h index a91eb10a42f2..2417262de207 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.h +++ b/drivers/net/wireless/ti/wl18xx/tx.h @@ -31,6 +31,12 @@ #define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F #define WL18XX_TX_STATUS_STAT_BIT_IDX 7 +/* + * The FW uses a special bit to indicate a wide channel should be used in + * the rate policy. + */ +#define CONF_TX_RATE_USE_WIDE_CHAN BIT(31) + void wl18xx_tx_immediate_complete(struct wl1271 *wl); #endif /* __WL12XX_TX_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 0798c1e88814..14dd361fa828 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -443,6 +443,12 @@ struct conf_rx_settings { CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 | \ CONF_HW_BIT_RATE_MCS_7) +#define CONF_TX_MIMO_RATES (CONF_HW_BIT_RATE_MCS_8 | \ + CONF_HW_BIT_RATE_MCS_9 | CONF_HW_BIT_RATE_MCS_10 | \ + CONF_HW_BIT_RATE_MCS_11 | CONF_HW_BIT_RATE_MCS_12 | \ + CONF_HW_BIT_RATE_MCS_13 | CONF_HW_BIT_RATE_MCS_14 | \ + CONF_HW_BIT_RATE_MCS_15) + /* * Default rates for management traffic when operating in AP mode. This * should be configured according to the basic rate set of the AP -- GitLab From b3a47ee0ec07b16f68c38052e8cd1b5cb417bdca Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:33 +0300 Subject: [PATCH 0537/6849] wlcore: support peer MIMO rates Parse the peer ht_cap element containing MCS8-MCS15 rates and pass it to the FW. Rates unsupported by the HW will be sanitized by mac80211 before reaching us. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.c | 4 +++- drivers/net/wireless/ti/wlcore/main.c | 3 ++- drivers/net/wireless/ti/wlcore/tx.c | 4 ++-- drivers/net/wireless/ti/wlcore/wl12xx.h | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 8450f0eecc9b..0dec46586ad5 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -1371,7 +1371,9 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, sta_rates = sta->supp_rates[wlvif->band]; if (sta->ht_cap.ht_supported) - sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; + sta_rates |= + (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | + (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 6f0361b23611..47dfc9d1295c 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -3696,7 +3696,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; if (sta->ht_cap.ht_supported) sta_rate_set |= - (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); + (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | + (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); sta_ht_cap = sta->ht_cap; sta_exists = true; diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 44e4e7bb29bd..200d091db6f9 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -428,10 +428,10 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, rate_set >>= 1; } - /* MCS rates indication are on bits 16 - 23 */ + /* MCS rates indication are on bits 16 - 31 */ rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; - for (bit = 0; bit < 8; bit++) { + for (bit = 0; bit < 16; bit++) { if (rate_set & 0x1) enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); rate_set >>= 1; diff --git a/drivers/net/wireless/ti/wlcore/wl12xx.h b/drivers/net/wireless/ti/wlcore/wl12xx.h index 05e6f74e4d25..571a4ef34a32 100644 --- a/drivers/net/wireless/ti/wlcore/wl12xx.h +++ b/drivers/net/wireless/ti/wlcore/wl12xx.h @@ -502,6 +502,7 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter, /* Macros to handle wl1271.sta_rate_set */ #define HW_BG_RATES_MASK 0xffff #define HW_HT_RATES_OFFSET 16 +#define HW_MIMO_RATES_OFFSET 24 #define WL12XX_HW_BLOCK_SIZE 256 -- GitLab From ebc7e57ddd01ffa4c996dde7095746259693755d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:34 +0300 Subject: [PATCH 0538/6849] wlcore/wl18xx: enable MIMO/wide-chan rates in AP-mode rate config Add a HW op to add extra enabled rates for AP-mode data-rates. Since the rates might depend on channel properties, reconfigure AP-mode rates when these change. Implement the HW op for the 18xx family, where MIMO or wide-chan rates can be added. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 1 + drivers/net/wireless/ti/wl18xx/main.c | 14 ++++++++++++++ drivers/net/wireless/ti/wlcore/hw_ops.h | 10 ++++++++++ drivers/net/wireless/ti/wlcore/init.c | 3 +++ drivers/net/wireless/ti/wlcore/main.c | 7 ++++++- drivers/net/wireless/ti/wlcore/wlcore.h | 2 ++ 6 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index a3336534eb2a..ad760a329c6a 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1315,6 +1315,7 @@ static struct wlcore_ops wl12xx_ops = { .get_mac = wl12xx_get_mac, .set_tx_desc_csum = wl12xx_set_tx_desc_csum, .set_rx_csum = NULL, + .ap_get_mimo_wide_rate_mask = NULL, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 77840ddd3129..9da94e62b7ac 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -879,6 +879,19 @@ static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, return hw_rate_set; } +static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, + struct wl12xx_vif *wlvif) +{ + if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || + wlvif->channel_type == NL80211_CHAN_HT40PLUS) { + wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); + return CONF_TX_RATE_USE_WIDE_CHAN; + } else { + wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); + return CONF_TX_MIMO_RATES; + } +} + static void wl18xx_conf_init(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; @@ -906,6 +919,7 @@ static struct wlcore_ops wl18xx_ops = { .set_tx_desc_csum = wl18xx_set_tx_desc_csum, .set_rx_csum = wl18xx_set_rx_csum, .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, + .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, }; int __devinit wl18xx_probe(struct platform_device *pdev) diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 80f3d75ceddf..6d3e378bd0c7 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -139,4 +139,14 @@ wlcore_hw_set_rx_csum(struct wl1271 *wl, wl->ops->set_rx_csum(wl, desc, skb); } +static inline u32 +wlcore_hw_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, + struct wl12xx_vif *wlvif) +{ + if (wl->ops->ap_get_mimo_wide_rate_mask) + return wl->ops->ap_get_mimo_wide_rate_mask(wl, wlvif); + + return 0; +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 9f89255eb6e6..645abd4b660d 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -460,6 +460,9 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) /* unconditionally enable HT rates */ supported_rates |= CONF_TX_MCS_RATES; + /* get extra MIMO or wide-chan rates where the HW supports it */ + supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); + /* configure unicast TX rate classes */ for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { rc.enabled_rates = supported_rates; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 47dfc9d1295c..03d4a4b1f59c 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2479,7 +2479,12 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, wlvif->channel = channel; wlvif->channel_type = conf->channel_type; - if (!is_ap) { + if (is_ap) { + ret = wl1271_init_ap_rates(wl, wlvif); + if (ret < 0) + wl1271_error("AP rate policy change failed %d", + ret); + } else { /* * FIXME: the mac80211 should really provide a fixed * rate to use here. for now, just use the smallest diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 83c43c9b10ed..f9ec84da3f79 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -68,6 +68,8 @@ struct wlcore_ops { void (*set_rx_csum)(struct wl1271 *wl, struct wl1271_rx_descriptor *desc, struct sk_buff *skb); + u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl, + struct wl12xx_vif *wlvif); }; enum wlcore_partitions { -- GitLab From 0e0f5a3b5c6f1b0e435a315a9cbe8a8de0c93630 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:35 +0300 Subject: [PATCH 0539/6849] wl18xx: set HT capabilities Define the default HT capabilities of the 18xx chip family - these include support for wide-channel. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 9da94e62b7ac..a0bec8f6c4ed 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -922,6 +922,20 @@ static struct wlcore_ops wl18xx_ops = { .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, }; +/* HT cap appropriate for wide channels */ +static struct ieee80211_sta_ht_cap wl18xx_ht_cap = { + .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, + .ht_supported = true, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .mcs = { + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(150), + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, +}; + int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -945,6 +959,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); + memcpy(&wl->ht_cap, &wl18xx_ht_cap, sizeof(wl18xx_ht_cap)); wl18xx_conf_init(wl); return wlcore_probe(wl, pdev); -- GitLab From 3a8ddb61764a4ee0f6d2eb1fc650f41c4057ecc2 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:36 +0300 Subject: [PATCH 0540/6849] wl18xx: add module param for overriding HT caps Set an alternate HT cap allowing MIMO rates (but only 20mhz) channels, when the module is loaded with ht_mode=mimo. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index a0bec8f6c4ed..17792e2a9849 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -41,6 +41,8 @@ #define WL18XX_RX_CHECKSUM_MASK 0x40 +static char *ht_mode_param; + static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ @@ -936,6 +938,19 @@ static struct ieee80211_sta_ht_cap wl18xx_ht_cap = { }, }; +/* HT cap appropriate for MIMO rates in 20mhz channel */ +static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap = { + .cap = IEEE80211_HT_CAP_SGI_20, + .ht_supported = true, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .mcs = { + .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(144), + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, +}; + int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -960,6 +975,10 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); memcpy(&wl->ht_cap, &wl18xx_ht_cap, sizeof(wl18xx_ht_cap)); + if (ht_mode_param && !strcmp(ht_mode_param, "mimo")) + memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, + sizeof(wl18xx_mimo_ht_cap)); + wl18xx_conf_init(wl); return wlcore_probe(wl, pdev); @@ -993,6 +1012,9 @@ static void __exit wl18xx_exit(void) } module_exit(wl18xx_exit); +module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); +MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or mimo"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From a9c130d522ddef8673728fa9738f4f3f8e61f9b9 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:37 +0300 Subject: [PATCH 0541/6849] wl18xx: add board type module argument Different board types (ie. FPGA, HDK and DVP/EVB) require slightly different init configuration options. Since we cannot probe the type of board from the actual hardware, we need to pass it as an option during module load. This patch adds a module parameters that accepts the 3 different board types, with DVP/EVB as the default, and uses this value where needed. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 26 +++++++++++++++++++++++-- drivers/net/wireless/ti/wl18xx/wl18xx.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 17792e2a9849..e5ebf4a14ba1 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -42,6 +42,7 @@ #define WL18XX_RX_CHECKSUM_MASK 0x40 static char *ht_mode_param; +static char *board_type_param; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -680,8 +681,7 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) params.secondary_clock_setting_time = phy->secondary_clock_setting_time; - /* TODO: hardcoded for now */ - params.board_type = BOARD_TYPE_DVP_EVB_18XX; + params.board_type = priv->board_type; wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)¶ms, @@ -964,6 +964,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) } wl = hw->priv; + priv = wl->priv; wl->ops = &wl18xx_ops; wl->ptable = wl18xx_ptable; wl->rtable = wl18xx_rtable; @@ -979,6 +980,24 @@ int __devinit wl18xx_probe(struct platform_device *pdev) memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, sizeof(wl18xx_mimo_ht_cap)); + if (!board_type_param) { + board_type_param = kstrdup("dvp_evb", GFP_KERNEL); + priv->board_type = BOARD_TYPE_DVP_EVB_18XX; + } else { + if (!strcmp(board_type_param, "fpga")) + priv->board_type = BOARD_TYPE_FPGA_18XX; + else if (!strcmp(board_type_param, "hdk")) + priv->board_type = BOARD_TYPE_HDK_18XX; + else if (!strcmp(board_type_param, "dvp_evb")) + priv->board_type = BOARD_TYPE_DVP_EVB_18XX; + else { + wl1271_error("invalid board type '%s'", + board_type_param); + wlcore_free_hw(wl); + return -EINVAL; + } + } + wl18xx_conf_init(wl); return wlcore_probe(wl, pdev); @@ -1015,6 +1034,9 @@ module_exit(wl18xx_exit); module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or mimo"); +module_param_named(board_type, board_type_param, charp, S_IRUSR); +MODULE_PARM_DESC(board_type, "Board type: fpga, hdk or dvp_evb (default)"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index c9bf5c6559f8..5bcc7f09f8ca 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -34,6 +34,8 @@ struct wl18xx_priv { /* Index of last released Tx desc in FW */ u8 last_fw_rls_idx; + + u8 board_type; }; #define WL18XX_FW_MAX_TX_STATUS_DESC 33 -- GitLab From d5b592764f5b21979f6260869bd96e69aa0536bb Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:38 +0300 Subject: [PATCH 0542/6849] wl18xx: translate and write the board type to SCR_PAD2 The firmware uses the SCR_PAD2 register to read the board type passed from the driver. The values don't match the ones used in the mac and phy configuration, so we need to map them before writing. This commit adds a translation table that is used when writing the board type to SCR_PAD2. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 16 +++++++++++----- drivers/net/wireless/ti/wl18xx/reg.h | 9 +++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index e5ebf4a14ba1..5214334c72c2 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -44,6 +44,12 @@ static char *ht_mode_param; static char *board_type_param; +static const u32 wl18xx_board_type_to_scrpad2[NUM_BOARD_TYPES] = { + [BOARD_TYPE_FPGA_18XX] = SCR_PAD2_BOARD_TYPE_FPGA, + [BOARD_TYPE_HDK_18XX] = SCR_PAD2_BOARD_TYPE_HDK, + [BOARD_TYPE_DVP_EVB_18XX] = SCR_PAD2_BOARD_TYPE_DVP_EVB, +}; + static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ @@ -584,11 +590,11 @@ out: static void wl18xx_set_clk(struct wl1271 *wl) { - /* - * TODO: this is hardcoded just for DVP/EVB, fix according to - * new unified_drv. - */ - wl1271_write32(wl, WL18XX_SCR_PAD2, 0xB3); + struct wl18xx_priv *priv = wl->priv; + + /* write the translated board type to SCR_PAD2 */ + wl1271_write32(wl, WL18XX_SCR_PAD2, + wl18xx_board_type_to_scrpad2[priv->board_type]); wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); wl1271_write32(wl, 0x00A02360, 0xD0078); diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 53987997f78f..e0170aeba05c 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -154,6 +154,15 @@ enum { BOARD_TYPE_FPGA_18XX = 0, BOARD_TYPE_HDK_18XX = 1, BOARD_TYPE_DVP_EVB_18XX = 2, + + NUM_BOARD_TYPES, +}; + +/* board type values used by the firmware in the SCR_PAD2 register */ +enum { + SCR_PAD2_BOARD_TYPE_FPGA = 0xB1, + SCR_PAD2_BOARD_TYPE_HDK = 0xB2, + SCR_PAD2_BOARD_TYPE_DVP_EVB = 0xB3, }; struct wl18xx_mac_and_phy_params { -- GitLab From 1c351da6673b2806ade099aa8204c262df5d91ac Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:39 +0300 Subject: [PATCH 0543/6849] wl18xx: read FW pc on recovery Define the FW pc in the 18xx register translation table. This specific register is only valid in the boot partition, so change the momentarily change partitions. This doesn't damage 12xx cards, where the FW pc is accessible via boot partition as well. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 2 +- drivers/net/wireless/ti/wlcore/main.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 5214334c72c2..82403e356eb8 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -549,7 +549,7 @@ static const int wl18xx_rtable[REG_TABLE_LEN] = { [REG_EVENT_MAILBOX_PTR] = WL18XX_REG_EVENT_MAILBOX_PTR, [REG_INTERRUPT_TRIG] = WL18XX_REG_INTERRUPT_TRIG_H, [REG_INTERRUPT_MASK] = WL18XX_REG_INTERRUPT_MASK, - [REG_PC_ON_RECOVERY] = 0, /* TODO: where is the PC? */ + [REG_PC_ON_RECOVERY] = WL18XX_SCR_PAD4, [REG_CHIP_ID_B] = WL18XX_REG_CHIP_ID_B, [REG_CMD_MBOX_ADDRESS] = WL18XX_CMD_MBOX_ADDRESS, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 03d4a4b1f59c..dfa87b4d3bb2 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -872,9 +872,12 @@ static void wl1271_recovery_work(struct work_struct *work) wl12xx_read_fwlog_panic(wl); + /* change partitions momentarily so we can read the FW pc */ + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wlcore_read_reg(wl, REG_PC_ON_RECOVERY)); + wlcore_set_partition(wl, &wl->ptable[PART_WORK]); BUG_ON(bug_on_recovery && !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); -- GitLab From d9fedea2a31476e7d11b3cc80c843de6cf135bd9 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:40 +0300 Subject: [PATCH 0544/6849] wl18xx: disable FW log functionality Currently (Fw .67) appears to do more harm than good. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 82403e356eb8..0f078860804d 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -574,6 +574,7 @@ static int wl18xx_identify_chip(struct wl1271 *wl) wl->chip.id); wl->sr_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | + WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; /* TODO: need to blocksize alignment for RX/TX separately? */ -- GitLab From be65202a610ca96aa945789c8b0a7bc3529b556e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:41 +0300 Subject: [PATCH 0545/6849] wl18xx: read clock frequency and do top init accordingly Instead of using hardcoded values for a single frequency, we need to read the frequency and use the appropriate values for it in the top initialization. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/Makefile | 2 +- drivers/net/wireless/ti/wl18xx/io.c | 60 +++++++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/io.h | 28 ++++++++++++ drivers/net/wireless/ti/wl18xx/main.c | 51 +++++++++++++++++++-- drivers/net/wireless/ti/wl18xx/reg.h | 22 +++++++++ drivers/net/wireless/ti/wl18xx/wl18xx.h | 22 +++++++++ 6 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/ti/wl18xx/io.c create mode 100644 drivers/net/wireless/ti/wl18xx/io.h diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile index 764d598bc968..abd881f4ea01 100644 --- a/drivers/net/wireless/ti/wl18xx/Makefile +++ b/drivers/net/wireless/ti/wl18xx/Makefile @@ -1,3 +1,3 @@ -wl18xx-objs = main.o acx.o tx.o +wl18xx-objs = main.o acx.o tx.o io.o obj-$(CONFIG_WL18XX) += wl18xx.o diff --git a/drivers/net/wireless/ti/wl18xx/io.c b/drivers/net/wireless/ti/wl18xx/io.c new file mode 100644 index 000000000000..598c057e722b --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/io.c @@ -0,0 +1,60 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "../wlcore/wlcore.h" +#include "../wlcore/io.h" + +#include "io.h" + +void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) +{ + u32 tmp; + + if (WARN_ON(addr % 2)) + return; + + if ((addr % 4) == 0) { + tmp = wl1271_read32(wl, addr); + tmp = (tmp & 0xffff0000) | val; + wl1271_write32(wl, addr, tmp); + } else { + tmp = wl1271_read32(wl, addr - 2); + tmp = (tmp & 0xffff) | (val << 16); + wl1271_write32(wl, addr - 2, tmp); + } +} + +u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr) +{ + u32 val; + + if (WARN_ON(addr % 2)) + return 0; + + if ((addr % 4) == 0) { + /* address is 4-bytes aligned */ + val = wl1271_read32(wl, addr); + return val & 0xffff; + } else { + val = wl1271_read32(wl, addr - 2); + return (val & 0xffff0000) >> 16; + } +} diff --git a/drivers/net/wireless/ti/wl18xx/io.h b/drivers/net/wireless/ti/wl18xx/io.h new file mode 100644 index 000000000000..be4e126ff617 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/io.h @@ -0,0 +1,28 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2011 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL18XX_IO_H__ +#define __WL18XX_IO_H__ + +void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); +u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr); + +#endif /* __WL18XX_IO_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 0f078860804d..ce132494ebed 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -37,6 +37,7 @@ #include "acx.h" #include "tx.h" #include "wl18xx.h" +#include "io.h" #define WL18XX_RX_CHECKSUM_MASK 0x40 @@ -561,6 +562,18 @@ static const int wl18xx_rtable[REG_TABLE_LEN] = { [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR, }; +static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = { + [CLOCK_CONFIG_16_2_M] = { 7, 104, 801, 4, true }, + [CLOCK_CONFIG_16_368_M] = { 9, 132, 3751, 4, true }, + [CLOCK_CONFIG_16_8_M] = { 7, 100, 0, 0, false }, + [CLOCK_CONFIG_19_2_M] = { 8, 100, 0, 0, false }, + [CLOCK_CONFIG_26_M] = { 13, 120, 0, 0, false }, + [CLOCK_CONFIG_32_736_M] = { 9, 132, 3751, 4, true }, + [CLOCK_CONFIG_33_6_M] = { 7, 100, 0, 0, false }, + [CLOCK_CONFIG_38_468_M] = { 8, 100, 0, 0, false }, + [CLOCK_CONFIG_52_M] = { 13, 120, 0, 0, false }, +}; + /* TODO: maybe move to a new header file? */ #define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw.bin" @@ -592,15 +605,47 @@ out: static void wl18xx_set_clk(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; + u32 clk_freq; /* write the translated board type to SCR_PAD2 */ wl1271_write32(wl, WL18XX_SCR_PAD2, wl18xx_board_type_to_scrpad2[priv->board_type]); wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - wl1271_write32(wl, 0x00A02360, 0xD0078); - wl1271_write32(wl, 0x00A0236c, 0x12); - wl1271_write32(wl, 0x00A02390, 0x20118); + + /* TODO: PG2: apparently we need to read the clk type */ + + clk_freq = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT); + wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq, + wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m, + wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q, + wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit"); + + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, wl18xx_clk_table[clk_freq].n); + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, wl18xx_clk_table[clk_freq].m); + + if (wl18xx_clk_table[clk_freq].swallow) { + /* first the 16 lower bits */ + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, + wl18xx_clk_table[clk_freq].q & + PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); + /* then the 16 higher bits, masked out */ + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, + (wl18xx_clk_table[clk_freq].q >> 16) & + PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); + + /* first the 16 lower bits */ + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, + wl18xx_clk_table[clk_freq].p & + PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); + /* then the 16 higher bits, masked out */ + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, + (wl18xx_clk_table[clk_freq].p >> 16) & + PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); + } else { + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, + PLLSH_WCS_PLL_SWALLOW_EN_VAL2); + } } static void wl18xx_boot_soft_reset(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index e0170aeba05c..1ea3393cff2c 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -107,6 +107,28 @@ #define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100) #define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C) +/* PRCM registers */ +#define PLATFORM_DETECTION 0xA0E3E0 +#define OCS_EN 0xA02080 +#define PRIMARY_CLK_DETECT 0xA020A6 +#define PLLSH_WCS_PLL_N 0xA02362 +#define PLLSH_WCS_PLL_M 0xA02360 +#define PLLSH_WCS_PLL_Q_FACTOR_CFG_1 0xA02364 +#define PLLSH_WCS_PLL_Q_FACTOR_CFG_2 0xA02366 +#define PLLSH_WCS_PLL_P_FACTOR_CFG_1 0xA02368 +#define PLLSH_WCS_PLL_P_FACTOR_CFG_2 0xA0236A +#define PLLSH_WCS_PLL_SWALLOW_EN 0xA0236C +#define PLLSH_WL_PLL_EN 0xA02392 + +#define PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK 0xFFFF +#define PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK 0x007F +#define PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK 0xFFFF +#define PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK 0x000F + +#define PLLSH_WCS_PLL_SWALLOW_EN_VAL1 0x1 +#define PLLSH_WCS_PLL_SWALLOW_EN_VAL2 0x12 + + #define WL18XX_CMD_MBOX_ADDRESS 0xB007B4 #define WL18XX_FW_STATUS_ADDR 0x50F8 diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index 5bcc7f09f8ca..75abb5b48c6e 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -56,4 +56,26 @@ struct wl18xx_fw_status_priv { u8 padding[2]; }; +struct wl18xx_clk_cfg { + u32 n; + u32 m; + u32 p; + u32 q; + bool swallow; +}; + +enum { + CLOCK_CONFIG_16_2_M = 1, + CLOCK_CONFIG_16_368_M, + CLOCK_CONFIG_16_8_M, + CLOCK_CONFIG_19_2_M, + CLOCK_CONFIG_26_M, + CLOCK_CONFIG_32_736_M, + CLOCK_CONFIG_33_6_M, + CLOCK_CONFIG_38_468_M, + CLOCK_CONFIG_52_M, + + NUM_CLOCK_CONFIGS, +}; + #endif /* __WL18XX_PRIV_H__ */ -- GitLab From 8388569a34396fccee22ae8348ca624959694ce0 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:42 +0300 Subject: [PATCH 0546/6849] wlcore: rename wl12xx.h to wlcore_i.h The wl12xx.h file now contains mostly definitions that are internal to wlcore. Still, some things need to me moved to the public header, so for now we keep including it in wlcore.h. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/wlcore.h | 2 +- drivers/net/wireless/ti/wlcore/{wl12xx.h => wlcore_i.h} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename drivers/net/wireless/ti/wlcore/{wl12xx.h => wlcore_i.h} (99%) diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index f9ec84da3f79..8f724daf4208 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -24,7 +24,7 @@ #include -#include "wl12xx.h" +#include "wlcore_i.h" #include "event.h" /* The maximum number of Tx descriptors in all chip families */ diff --git a/drivers/net/wireless/ti/wlcore/wl12xx.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h similarity index 99% rename from drivers/net/wireless/ti/wlcore/wl12xx.h rename to drivers/net/wireless/ti/wlcore/wlcore_i.h index 571a4ef34a32..819c97cdc162 100644 --- a/drivers/net/wireless/ti/wlcore/wl12xx.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -22,8 +22,8 @@ * */ -#ifndef __WL12XX_H__ -#define __WL12XX_H__ +#ifndef __WLCORE_I_H__ +#define __WLCORE_I_H__ #include #include @@ -506,4 +506,4 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter, #define WL12XX_HW_BLOCK_SIZE 256 -#endif +#endif /* __WLCORE_I_H__ */ -- GitLab From a5d751bb9298360f5547d30734aed4a54a8af3e4 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:43 +0300 Subject: [PATCH 0547/6849] wlcore/wl12xx: move ref_clock and tcxo_clock elements to wl12xx Only wl12xx needs to get the ref_clock anc tcxo_clock values from the platform data. Move these elements from the wl1271 structure to wl12xx's private data. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/cmd.c | 8 ++- drivers/net/wireless/ti/wl12xx/main.c | 88 ++++++++++++++++++++---- drivers/net/wireless/ti/wl12xx/wl12xx.h | 3 + drivers/net/wireless/ti/wlcore/debugfs.c | 3 +- drivers/net/wireless/ti/wlcore/main.c | 2 - drivers/net/wireless/ti/wlcore/wlcore.h | 3 - 6 files changed, 82 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c index 8ffaeb5f2147..50ba7480b790 100644 --- a/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/drivers/net/wireless/ti/wl12xx/cmd.c @@ -65,6 +65,7 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) struct wl1271_general_parms_cmd *gen_parms; struct wl1271_ini_general_params *gp = &((struct wl1271_nvs_file *)wl->nvs)->general_params; + struct wl12xx_priv *priv = wl->priv; bool answer = false; int ret; @@ -88,7 +89,7 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) answer = true; /* Override the REF CLK from the NVS with the one from platform data */ - gen_parms->general_params.ref_clock = wl->ref_clock; + gen_parms->general_params.ref_clock = priv->ref_clock; ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); if (ret < 0) { @@ -118,6 +119,7 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) struct wl128x_general_parms_cmd *gen_parms; struct wl128x_ini_general_params *gp = &((struct wl128x_nvs_file *)wl->nvs)->general_params; + struct wl12xx_priv *priv = wl->priv; bool answer = false; int ret; @@ -141,8 +143,8 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) answer = true; /* Replace REF and TCXO CLKs with the ones from platform data */ - gen_parms->general_params.ref_clock = wl->ref_clock; - gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock; + gen_parms->general_params.ref_clock = priv->ref_clock; + gen_parms->general_params.tcxo_ref_clock = priv->tcxo_clock; ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); if (ret < 0) { diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index ad760a329c6a..962d85d625de 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -40,6 +40,9 @@ #include "cmd.h" #include "acx.h" +static char *fref_param; +static char *tcxo_param; + static struct wlcore_conf wl12xx_conf = { .sg = { .params = { @@ -773,6 +776,7 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) u16 spare_reg; u16 pll_config; u8 input_freq; + struct wl12xx_priv *priv = wl->priv; /* Mask bits [3:1] in the sys_clk_cfg register */ spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); @@ -782,8 +786,8 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); /* Handle special cases of the TCXO clock */ - if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || - wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6) + if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || + priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6) return wl128x_manually_configure_mcs_pll(wl); /* Set the input frequency according to the selected clock source */ @@ -808,11 +812,12 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) */ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) { + struct wl12xx_priv *priv = wl->priv; u16 sys_clk_cfg; /* For XTAL-only modes, FREF will be used after switching from TCXO */ - if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL || - wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) { + if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL || + priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) { if (!wl128x_switch_tcxo_to_fref(wl)) return -EINVAL; goto fref_clk; @@ -826,8 +831,8 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) goto fref_clk; /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */ - if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 || - wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) { + if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 || + priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) { if (!wl128x_switch_tcxo_to_fref(wl)) return -EINVAL; goto fref_clk; @@ -836,14 +841,14 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) /* TCXO clock is selected */ if (!wl128x_is_tcxo_valid(wl)) return -EINVAL; - *selected_clock = wl->tcxo_clock; + *selected_clock = priv->tcxo_clock; goto config_mcs_pll; fref_clk: /* FREF clock is selected */ if (!wl128x_is_fref_valid(wl)) return -EINVAL; - *selected_clock = wl->ref_clock; + *selected_clock = priv->ref_clock; config_mcs_pll: return wl128x_configure_mcs_pll(wl, *selected_clock); @@ -851,25 +856,26 @@ config_mcs_pll: static int wl127x_boot_clk(struct wl1271 *wl) { + struct wl12xx_priv *priv = wl->priv; u32 pause; u32 clk; if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION; - if (wl->ref_clock == CONF_REF_CLK_19_2_E || - wl->ref_clock == CONF_REF_CLK_38_4_E || - wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL) + if (priv->ref_clock == CONF_REF_CLK_19_2_E || + priv->ref_clock == CONF_REF_CLK_38_4_E || + priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL) /* ref clk: 19.2/38.4/38.4-XTAL */ clk = 0x3; - else if (wl->ref_clock == CONF_REF_CLK_26_E || - wl->ref_clock == CONF_REF_CLK_52_E) + else if (priv->ref_clock == CONF_REF_CLK_26_E || + priv->ref_clock == CONF_REF_CLK_52_E) /* ref clk: 26/52 */ clk = 0x5; else return -EINVAL; - if (wl->ref_clock != CONF_REF_CLK_19_2_E) { + if (priv->ref_clock != CONF_REF_CLK_19_2_E) { u16 val; /* Set clock type (open drain) */ val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE); @@ -939,6 +945,7 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) static int wl12xx_pre_boot(struct wl1271 *wl) { + struct wl12xx_priv *priv = wl->priv; int ret = 0; u32 clk; int selected_clock = -1; @@ -970,7 +977,7 @@ static int wl12xx_pre_boot(struct wl1271 *wl) if (wl->chip.id == CHIP_ID_1283_PG20) clk |= ((selected_clock & 0x3) << 1) << 4; else - clk |= (wl->ref_clock << 1) << 4; + clk |= (priv->ref_clock << 1) << 4; wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); @@ -1333,6 +1340,7 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { static int __devinit wl12xx_probe(struct platform_device *pdev) { + struct wl12xx_platform_data *pdata = pdev->dev.platform_data; struct wl1271 *wl; struct ieee80211_hw *hw; struct wl12xx_priv *priv; @@ -1344,6 +1352,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) } wl = hw->priv; + priv = wl->priv; wl->ops = &wl12xx_ops; wl->ptable = wl12xx_ptable; wl->rtable = wl12xx_rtable; @@ -1357,6 +1366,48 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap)); wl12xx_conf_init(wl); + if (!fref_param) { + priv->ref_clock = pdata->board_ref_clock; + } else { + if (!strcmp(fref_param, "19.2")) + priv->ref_clock = WL12XX_REFCLOCK_19; + else if (!strcmp(fref_param, "26")) + priv->ref_clock = WL12XX_REFCLOCK_26; + else if (!strcmp(fref_param, "26x")) + priv->ref_clock = WL12XX_REFCLOCK_26_XTAL; + else if (!strcmp(fref_param, "38.4")) + priv->ref_clock = WL12XX_REFCLOCK_38; + else if (!strcmp(fref_param, "38.4x")) + priv->ref_clock = WL12XX_REFCLOCK_38_XTAL; + else if (!strcmp(fref_param, "52")) + priv->ref_clock = WL12XX_REFCLOCK_52; + else + wl1271_error("Invalid fref parameter %s", fref_param); + } + + if (!tcxo_param) { + priv->tcxo_clock = pdata->board_tcxo_clock; + } else { + if (!strcmp(tcxo_param, "19.2")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2; + else if (!strcmp(tcxo_param, "26")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_26; + else if (!strcmp(tcxo_param, "38.4")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4; + else if (!strcmp(tcxo_param, "52")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_52; + else if (!strcmp(tcxo_param, "16.368")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368; + else if (!strcmp(tcxo_param, "32.736")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736; + else if (!strcmp(tcxo_param, "16.8")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8; + else if (!strcmp(tcxo_param, "33.6")) + priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6; + else + wl1271_error("Invalid tcxo parameter %s", tcxo_param); + } + return wlcore_probe(wl, pdev); } @@ -1388,6 +1439,13 @@ static void __exit wl12xx_exit(void) } module_exit(wl12xx_exit); +module_param_named(fref, fref_param, charp, 0); +MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52"); + +module_param_named(tcxo, tcxo_param, charp, 0); +MODULE_PARM_DESC(tcxo, + "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h index 74cd332e23ef..0d81c1e00b4a 100644 --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h @@ -26,6 +26,9 @@ struct wl12xx_priv { struct wl12xx_priv_conf conf; + + int ref_clock; + int tcxo_clock; }; #endif /* __WL12XX_PRIV_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index d5aea1ff5ad1..d3775198d265 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -535,8 +535,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, DRIVER_STATE_PRINT_LHEX(ap_ps_map); DRIVER_STATE_PRINT_HEX(quirks); DRIVER_STATE_PRINT_HEX(irq); - DRIVER_STATE_PRINT_HEX(ref_clock); - DRIVER_STATE_PRINT_HEX(tcxo_clock); + /* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */ DRIVER_STATE_PRINT_HEX(hw_pg_ver); DRIVER_STATE_PRINT_HEX(platform_quirks); DRIVER_STATE_PRINT_HEX(chip.id); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index dfa87b4d3bb2..cd73dfe42448 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5295,8 +5295,6 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) wlcore_adjust_conf(wl); wl->irq = platform_get_irq(pdev, 0); - wl->ref_clock = pdata->board_ref_clock; - wl->tcxo_clock = pdata->board_tcxo_clock; wl->platform_quirks = pdata->platform_quirks; wl->set_power = pdata->set_power; wl->dev = &pdev->dev; diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 8f724daf4208..89abbced7bae 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -130,7 +130,6 @@ struct wl1271 { void (*set_power)(bool enable); int irq; - int ref_clock; spinlock_t wl_lock; @@ -288,8 +287,6 @@ struct wl1271 { /* bands supported by this instance of wl12xx */ struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; - int tcxo_clock; - /* * wowlan trigger was configured during suspend. * (currently, only "ANY" trigger is supported) -- GitLab From 549562946fab225439bd6878982031ad6ce2aab9 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:44 +0300 Subject: [PATCH 0548/6849] wl18xx: implement hw op to read PG version Read the HW PG version of the 18xx chip from FUSE. Based on an earlier patch by Luciano Coelho . Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 17 +++++++++++++++-- drivers/net/wireless/ti/wl18xx/reg.h | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index ce132494ebed..9aae0af25fef 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -659,8 +659,6 @@ static void wl18xx_boot_soft_reset(struct wl1271 *wl) static int wl18xx_pre_boot(struct wl1271 *wl) { - /* TODO: add hw_pg_ver reading */ - wl18xx_set_clk(wl); /* Continue the ELP wake up sequence */ @@ -946,6 +944,20 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, } } +static s8 wl18xx_get_pg_ver(struct wl1271 *wl) +{ + u32 fuse; + + wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + + fuse = wl1271_read32(wl, WL18XX_REG_FUSE_DATA_1_3); + fuse = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; + + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + + return (s8)fuse; +} + static void wl18xx_conf_init(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; @@ -971,6 +983,7 @@ static struct wlcore_ops wl18xx_ops = { .tx_delayed_compl = NULL, .hw_init = wl18xx_hw_init, .set_tx_desc_csum = wl18xx_set_tx_desc_csum, + .get_pg_ver = wl18xx_get_pg_ver, .set_rx_csum = wl18xx_set_rx_csum, .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 1ea3393cff2c..43c480fb837f 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -128,6 +128,9 @@ #define PLLSH_WCS_PLL_SWALLOW_EN_VAL1 0x1 #define PLLSH_WCS_PLL_SWALLOW_EN_VAL2 0x12 +#define WL18XX_REG_FUSE_DATA_1_3 0xA0260C +#define WL18XX_PG_VER_MASK 0x70 +#define WL18XX_PG_VER_OFFSET 4 #define WL18XX_CMD_MBOX_ADDRESS 0xB007B4 -- GitLab From 4b4887e9710158dca6efd3646ba87f1da03ebe8b Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:45 +0300 Subject: [PATCH 0549/6849] wlcore/wl12xx: move rx_mem_pool_addr element to wl12xx Only wl127x chips use the rx_mem_pool_addr values, which need to be given to the firmware as part of the RX path. Move this from core to the wl12xx driver. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/main.c | 2 +- drivers/net/wireless/ti/wl12xx/wl12xx.h | 5 +++++ drivers/net/wireless/ti/wlcore/wlcore.h | 3 --- drivers/net/wireless/ti/wlcore/wlcore_i.h | 5 ----- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 962d85d625de..02668557fef0 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -596,7 +596,7 @@ static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) { if (wl->chip.id != CHIP_ID_1283_PG20) { struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; - struct wl1271_rx_mem_pool_addr rx_mem_addr; + struct wl127x_rx_mem_pool_addr rx_mem_addr; /* * Choose the block we want to read diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h index 0d81c1e00b4a..de1132410876 100644 --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h @@ -24,6 +24,11 @@ #include "conf.h" +struct wl127x_rx_mem_pool_addr { + u32 addr; + u32 addr_extra; +}; + struct wl12xx_priv { struct wl12xx_priv_conf conf; diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 89abbced7bae..f62152e35f3c 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -213,9 +213,6 @@ struct wl1271 { /* FW Rx counter */ u32 rx_counter; - /* Rx memory pool address */ - struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; - /* Intermediate buffer, used for packet aggregation */ u8 *aggr_buf; diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 819c97cdc162..53263a978a75 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -194,11 +194,6 @@ struct wl_fw_status { u8 priv[0]; } __packed; -struct wl1271_rx_mem_pool_addr { - u32 addr; - u32 addr_extra; -}; - #define WL1271_MAX_CHANNELS 64 struct wl1271_scan { struct cfg80211_scan_request *req; -- GitLab From f2baf075c5121b30922751f34920815743d7ee67 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:46 +0300 Subject: [PATCH 0550/6849] wl18xx: init Tx-released index to 0 on HW init This ensures the index is 0 on FW recovery and prevents spurious error prints - "WARNING illegal id in tx completion". Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 9aae0af25fef..a8b9ceacd9c2 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -850,11 +850,15 @@ static void wl18xx_tx_immediate_completion(struct wl1271 *wl) static int wl18xx_hw_init(struct wl1271 *wl) { int ret; + struct wl18xx_priv *priv = wl->priv; u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE | HOST_IF_CFG_ADD_RX_ALIGNMENT; u32 sdio_align_size = 0; + /* (re)init private structures. Relevant on recovery as well. */ + priv->last_fw_rls_idx = 0; + /* Enable Tx SDIO padding */ if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) { host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; -- GitLab From 2f1d74e6e7f26df2665b7df5ff912bc1d3ae75dc Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:47 +0300 Subject: [PATCH 0551/6849] wl18xx: don't upload NVS to FW In this chip family the NVS file should not be uploaded to FW. In fact, we encounter strange bugs (sdio errors) when trying to upload it with certain parameters. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index a8b9ceacd9c2..ddd11d00f033 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -755,10 +755,6 @@ static int wl18xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - ret = wlcore_boot_upload_nvs(wl); - if (ret < 0) - goto out; - wl18xx_pre_upload(wl); ret = wlcore_boot_upload_firmware(wl); -- GitLab From 05057c0621dea083b617e7c35437faa9db7b7104 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:48 +0300 Subject: [PATCH 0552/6849] wl18xx: change board type enum according to new FW Add more board types and remove a now unneeded write to SCR_PAD2 setting the board type. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 43 +++++++++++---------------- drivers/net/wireless/ti/wl18xx/reg.h | 15 ++++------ 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index ddd11d00f033..f892d37443e2 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -45,12 +45,6 @@ static char *ht_mode_param; static char *board_type_param; -static const u32 wl18xx_board_type_to_scrpad2[NUM_BOARD_TYPES] = { - [BOARD_TYPE_FPGA_18XX] = SCR_PAD2_BOARD_TYPE_FPGA, - [BOARD_TYPE_HDK_18XX] = SCR_PAD2_BOARD_TYPE_HDK, - [BOARD_TYPE_DVP_EVB_18XX] = SCR_PAD2_BOARD_TYPE_DVP_EVB, -}; - static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ @@ -604,13 +598,8 @@ out: static void wl18xx_set_clk(struct wl1271 *wl) { - struct wl18xx_priv *priv = wl->priv; u32 clk_freq; - /* write the translated board type to SCR_PAD2 */ - wl1271_write32(wl, WL18XX_SCR_PAD2, - wl18xx_board_type_to_scrpad2[priv->board_type]); - wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); /* TODO: PG2: apparently we need to read the clk type */ @@ -1046,21 +1035,22 @@ int __devinit wl18xx_probe(struct platform_device *pdev) sizeof(wl18xx_mimo_ht_cap)); if (!board_type_param) { - board_type_param = kstrdup("dvp_evb", GFP_KERNEL); - priv->board_type = BOARD_TYPE_DVP_EVB_18XX; + board_type_param = kstrdup("dvp", GFP_KERNEL); + priv->board_type = BOARD_TYPE_DVP_18XX; + } else if (!strcmp(board_type_param, "fpga")) { + priv->board_type = BOARD_TYPE_FPGA_18XX; + } else if (!strcmp(board_type_param, "hdk")) { + priv->board_type = BOARD_TYPE_HDK_18XX; + } else if (!strcmp(board_type_param, "dvp")) { + priv->board_type = BOARD_TYPE_DVP_18XX; + } else if (!strcmp(board_type_param, "evb")) { + priv->board_type = BOARD_TYPE_EVB_18XX; + } else if (!strcmp(board_type_param, "com8")) { + priv->board_type = BOARD_TYPE_COM8_18XX; } else { - if (!strcmp(board_type_param, "fpga")) - priv->board_type = BOARD_TYPE_FPGA_18XX; - else if (!strcmp(board_type_param, "hdk")) - priv->board_type = BOARD_TYPE_HDK_18XX; - else if (!strcmp(board_type_param, "dvp_evb")) - priv->board_type = BOARD_TYPE_DVP_EVB_18XX; - else { - wl1271_error("invalid board type '%s'", - board_type_param); - wlcore_free_hw(wl); - return -EINVAL; - } + wl1271_error("invalid board type '%s'", board_type_param); + wlcore_free_hw(wl); + return -EINVAL; } wl18xx_conf_init(wl); @@ -1100,7 +1090,8 @@ module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or mimo"); module_param_named(board_type, board_type_param, charp, S_IRUSR); -MODULE_PARM_DESC(board_type, "Board type: fpga, hdk or dvp_evb (default)"); +MODULE_PARM_DESC(board_type, "Board type: fpga, hdk, evb, com8 or " + "dvp (default)"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 43c480fb837f..1674c1ad002e 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -176,20 +176,15 @@ enum { }; enum { - BOARD_TYPE_FPGA_18XX = 0, - BOARD_TYPE_HDK_18XX = 1, - BOARD_TYPE_DVP_EVB_18XX = 2, + BOARD_TYPE_EVB_18XX = 0, + BOARD_TYPE_DVP_18XX = 1, + BOARD_TYPE_HDK_18XX = 2, + BOARD_TYPE_FPGA_18XX = 3, + BOARD_TYPE_COM8_18XX = 4, NUM_BOARD_TYPES, }; -/* board type values used by the firmware in the SCR_PAD2 register */ -enum { - SCR_PAD2_BOARD_TYPE_FPGA = 0xB1, - SCR_PAD2_BOARD_TYPE_HDK = 0xB2, - SCR_PAD2_BOARD_TYPE_DVP_EVB = 0xB3, -}; - struct wl18xx_mac_and_phy_params { u8 phy_standalone; u8 rdl; -- GitLab From c331b344d5def33194427b24cb2190ff345f7f55 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:49 +0300 Subject: [PATCH 0553/6849] wlcore/wl12xx: add plt_init op and move the code to wl12xx PLT mode needs to be initialized differently for each chip. This patch adds an operation to init PLT and moves the existing PLT initialization into the wl12xx driver. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/main.c | 57 ++++++++++++++++++++++++ drivers/net/wireless/ti/wlcore/acx.c | 4 ++ drivers/net/wireless/ti/wlcore/cmd.c | 1 + drivers/net/wireless/ti/wlcore/main.c | 59 +------------------------ drivers/net/wireless/ti/wlcore/wlcore.h | 1 + 5 files changed, 64 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 02668557fef0..1d097c1bcace 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1302,10 +1302,67 @@ static void wl12xx_set_tx_desc_csum(struct wl1271 *wl, desc->wl12xx_reserved = 0; } +static int wl12xx_plt_init(struct wl1271 *wl) +{ + int ret; + + ret = wl->ops->boot(wl); + if (ret < 0) + goto out; + + ret = wl->ops->hw_init(wl); + if (ret < 0) + goto out_irq_disable; + + ret = wl1271_acx_init_mem_config(wl); + if (ret < 0) + goto out_irq_disable; + + ret = wl12xx_acx_mem_cfg(wl); + if (ret < 0) + goto out_free_memmap; + + /* Enable data path */ + ret = wl1271_cmd_data_path(wl, 1); + if (ret < 0) + goto out_free_memmap; + + /* Configure for CAM power saving (ie. always active) */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + if (ret < 0) + goto out_free_memmap; + + /* configure PM */ + ret = wl1271_acx_pm_config(wl); + if (ret < 0) + goto out_free_memmap; + + goto out; + +out_free_memmap: + kfree(wl->target_mem_map); + wl->target_mem_map = NULL; + +out_irq_disable: + mutex_unlock(&wl->mutex); + /* Unlocking the mutex in the middle of handling is + inherently unsafe. In this case we deem it safe to do, + because we need to let any possibly pending IRQ out of + the system (and while we are WL1271_STATE_OFF the IRQ + work function will not do anything.) Also, any other + possible concurrent operations will fail due to the + current state, hence the wl1271 struct should be safe. */ + wlcore_disable_interrupts(wl); + mutex_lock(&wl->mutex); +out: + return ret; +} + static struct wlcore_ops wl12xx_ops = { .identify_chip = wl12xx_identify_chip, .identify_fw = wl12xx_identify_fw, .boot = wl12xx_boot, + .plt_init = wl12xx_plt_init, .trigger_cmd = wl12xx_trigger_cmd, .ack_event = wl12xx_ack_event, .calc_tx_blocks = wl12xx_calc_tx_blocks, diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index f3d6fa508269..fd33be7d5c94 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -86,6 +86,7 @@ out: kfree(auth); return ret; } +EXPORT_SYMBOL_GPL(wl1271_acx_sleep_auth); int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif, int power) @@ -997,6 +998,7 @@ out: kfree(mem_conf); return ret; } +EXPORT_SYMBOL_GPL(wl12xx_acx_mem_cfg); int wl1271_acx_init_mem_config(struct wl1271 *wl) { @@ -1027,6 +1029,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl) return 0; } +EXPORT_SYMBOL_GPL(wl1271_acx_init_mem_config); int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) { @@ -1150,6 +1153,7 @@ out: kfree(acx); return ret; } +EXPORT_SYMBOL_GPL(wl1271_acx_pm_config); int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool enable) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 0dec46586ad5..5c4756047098 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -816,6 +816,7 @@ out: kfree(cmd); return ret; } +EXPORT_SYMBOL_GPL(wl1271_cmd_data_path); int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 ps_mode, u16 auto_ps_timeout) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index cd73dfe42448..373be7f667ed 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -320,46 +320,6 @@ static void wlcore_adjust_conf(struct wl1271 *wl) } } -static int wl1271_plt_init(struct wl1271 *wl) -{ - int ret; - - ret = wl->ops->hw_init(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_init_mem_config(wl); - if (ret < 0) - return ret; - - ret = wl12xx_acx_mem_cfg(wl); - if (ret < 0) - goto out_free_memmap; - - /* Enable data path */ - ret = wl1271_cmd_data_path(wl, 1); - if (ret < 0) - goto out_free_memmap; - - /* Configure for CAM power saving (ie. always active) */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - goto out_free_memmap; - - /* configure PM */ - ret = wl1271_acx_pm_config(wl); - if (ret < 0) - goto out_free_memmap; - - return 0; - - out_free_memmap: - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - - return ret; -} - static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid, u8 tx_pkts) @@ -1042,14 +1002,10 @@ int wl1271_plt_start(struct wl1271 *wl) if (ret < 0) goto power_off; - ret = wl->ops->boot(wl); + ret = wl->ops->plt_init(wl); if (ret < 0) goto power_off; - ret = wl1271_plt_init(wl); - if (ret < 0) - goto irq_disable; - wl->plt = true; wl->state = WL1271_STATE_ON; wl1271_notice("firmware booted in PLT mode (%s)", @@ -1062,19 +1018,6 @@ int wl1271_plt_start(struct wl1271 *wl) goto out; -irq_disable: - mutex_unlock(&wl->mutex); - /* Unlocking the mutex in the middle of handling is - inherently unsafe. In this case we deem it safe to do, - because we need to let any possibly pending IRQ out of - the system (and while we are WL1271_STATE_OFF the IRQ - work function will not do anything.) Also, any other - possible concurrent operations will fail due to the - current state, hence the wl1271 struct should be safe. */ - wlcore_disable_interrupts(wl); - wl1271_flush_deferred_work(wl); - cancel_work_sync(&wl->netstack_work); - mutex_lock(&wl->mutex); power_off: wl1271_power_off(wl); } diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index f62152e35f3c..1fc3c77c10a3 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -39,6 +39,7 @@ struct wlcore_ops { int (*identify_chip)(struct wl1271 *wl); int (*identify_fw)(struct wl1271 *wl); int (*boot)(struct wl1271 *wl); + int (*plt_init)(struct wl1271 *wl); void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, void *buf, size_t len); void (*ack_event)(struct wl1271 *wl); -- GitLab From be42aee6df93597f669b4d20e7a32c8fc144f104 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:50 +0300 Subject: [PATCH 0554/6849] wl18xx: add plt_init operation Add the correct FW name for PLT (which is the same as the normal firmware) and implement the plt_init operation. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 10 ++++++++++ drivers/net/wireless/ti/wl18xx/reg.h | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index f892d37443e2..59408291d30d 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -580,6 +580,8 @@ static int wl18xx_identify_chip(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", wl->chip.id); wl->sr_fw_name = WL18XX_FW_NAME; + /* wl18xx uses the same firmware for PLT */ + wl->plt_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; @@ -958,9 +960,17 @@ static void wl18xx_conf_init(struct wl1271 *wl) memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); } +static int wl18xx_plt_init(struct wl1271 *wl) +{ + wl1271_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); + + return wl->ops->boot(wl); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, + .plt_init = wl18xx_plt_init, .trigger_cmd = wl18xx_trigger_cmd, .ack_event = wl18xx_ack_event, .calc_tx_blocks = wl18xx_calc_tx_blocks, diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 1674c1ad002e..aaedf91ed7b7 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -154,6 +154,12 @@ */ #define WL18XX_INTR_TRIG_EVENT_ACK BIT(29) +/* + * To boot the firmware in PLT mode we need to write this value in + * SCR_PAD8 before starting. + */ +#define WL18XX_SCR_PAD8_PLT 0xBABABEBE + /* TODO: maybe move elsewhere? */ #define NUM_OF_CHANNELS_11_ABG 150 #define NUM_OF_CHANNELS_11_P 7 -- GitLab From 0a1569f82b5ee4281c5c71e7bb4a285267158ce3 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:51 +0300 Subject: [PATCH 0555/6849] wl18xx: change the low_band_component_type for HDK boards Currently, all HDK boards use low_band_component_type 0x06. In the future this may change, but for now, we hardcode this value when the board_type is set to HDK. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 59408291d30d..f14141b3dbe4 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1051,6 +1051,8 @@ int __devinit wl18xx_probe(struct platform_device *pdev) priv->board_type = BOARD_TYPE_FPGA_18XX; } else if (!strcmp(board_type_param, "hdk")) { priv->board_type = BOARD_TYPE_HDK_18XX; + /* HACK! Just for now we hardcode HDK to 0x06 */ + priv->conf.phy.low_band_component_type = 0x06; } else if (!strcmp(board_type_param, "dvp")) { priv->board_type = BOARD_TYPE_DVP_18XX; } else if (!strcmp(board_type_param, "evb")) { -- GitLab From e9258815a8e21e34395d5b6a4da27f1bfcbdca11 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:52 +0300 Subject: [PATCH 0556/6849] wl18xx: add number of antennas and dc2dc type as module params We need to specify the number of 2.4GHz and 5GHz antennas and whether the board has an internal or external DC2DC. Add some module parameters that allow changing that. In the future this will come from the "NVS" file. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/conf.h | 3 --- drivers/net/wireless/ti/wl18xx/main.c | 21 +++++++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index d2b097e4d24e..a6058fb86e7f 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -33,9 +33,6 @@ struct wl18xx_conf_phy { u8 low_band_component_type; u8 high_band_component; u8 high_band_component_type; - u8 number_of_assembled_ant2_4; - u8 number_of_assembled_ant5; - u8 external_pa_dc2dc; u8 tcxo_ldo_voltage; u8 xtal_itrim_val; u8 srf_state; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index f14141b3dbe4..2f0cbf8f202c 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -44,6 +44,9 @@ static char *ht_mode_param; static char *board_type_param; +static bool dc2dc_param = false; +static int n_antennas_2_param = 1; +static int n_antennas_5_param = 1; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -487,9 +490,6 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .low_band_component_type = 0x05, .high_band_component = COMPONENT_2_WAY_SWITCH, .high_band_component_type = 0x09, - .number_of_assembled_ant2_4 = 0x01, - .number_of_assembled_ant5 = 0x01, - .external_pa_dc2dc = 0x00, .tcxo_ldo_voltage = 0x00, .xtal_itrim_val = 0x04, .srf_state = 0x00, @@ -704,10 +704,10 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) params.high_band_component_type = phy->high_band_component_type; params.number_of_assembled_ant2_4 = - phy->number_of_assembled_ant2_4; + n_antennas_2_param; params.number_of_assembled_ant5 = - phy->number_of_assembled_ant5; - params.external_pa_dc2dc = phy->external_pa_dc2dc; + n_antennas_5_param; + params.external_pa_dc2dc = dc2dc_param; params.tcxo_ldo_voltage = phy->tcxo_ldo_voltage; params.xtal_itrim_val = phy->xtal_itrim_val; params.srf_state = phy->srf_state; @@ -1105,6 +1105,15 @@ module_param_named(board_type, board_type_param, charp, S_IRUSR); MODULE_PARM_DESC(board_type, "Board type: fpga, hdk, evb, com8 or " "dvp (default)"); +module_param_named(dc2dc, dc2dc_param, bool, S_IRUSR); +MODULE_PARM_DESC(dc2dc, "External DC2DC: boolean (defaults to false)"); + +module_param_named(n_antennas_2, n_antennas_2_param, uint, S_IRUSR); +MODULE_PARM_DESC(n_antennas_2, "Number of installed 2.4GHz antennas: 1 (default) or 2"); + +module_param_named(n_antennas_5, n_antennas_5_param, uint, S_IRUSR); +MODULE_PARM_DESC(n_antennas_5, "Number of installed 5GHz antennas: 1 (default) or 2"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From 102165c6d2b8d73a25a1567fcac496addc15aba7 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:53 +0300 Subject: [PATCH 0557/6849] wl18xx: add module parameter to disable TCP checksum Add a new module parameter to disable TCP checksum offload. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 2f0cbf8f202c..b76b6ac348da 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -47,6 +47,7 @@ static char *board_type_param; static bool dc2dc_param = false; static int n_antennas_2_param = 1; static int n_antennas_5_param = 1; +static bool checksum_param = true; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -865,9 +866,11 @@ static int wl18xx_hw_init(struct wl1271 *wl) if (ret < 0) return ret; - ret = wl18xx_acx_set_checksum_state(wl); - if (ret != 0) - return ret; + if (checksum_param) { + ret = wl18xx_acx_set_checksum_state(wl); + if (ret != 0) + return ret; + } return ret; } @@ -879,6 +882,11 @@ static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, u32 ip_hdr_offset; struct iphdr *ip_hdr; + if (!checksum_param) { + desc->wl18xx_checksum_data = 0; + return; + } + if (skb->ip_summed != CHECKSUM_PARTIAL) { desc->wl18xx_checksum_data = 0; return; @@ -1065,6 +1073,11 @@ int __devinit wl18xx_probe(struct platform_device *pdev) return -EINVAL; } + if (!checksum_param) { + wl18xx_ops.set_rx_csum = NULL; + wl18xx_ops.init_vif = NULL; + } + wl18xx_conf_init(wl); return wlcore_probe(wl, pdev); @@ -1114,6 +1127,9 @@ MODULE_PARM_DESC(n_antennas_2, "Number of installed 2.4GHz antennas: 1 (default) module_param_named(n_antennas_5, n_antennas_5_param, uint, S_IRUSR); MODULE_PARM_DESC(n_antennas_5, "Number of installed 5GHz antennas: 1 (default) or 2"); +module_param_named(checksum, checksum_param, bool, S_IRUSR); +MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to true)"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From 0afd04e5e5d8db505fbb0f98c6306242c0006503 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 12:13:54 +0300 Subject: [PATCH 0558/6849] wlcore/wl12xx/18xx: split fw_status struct into two The number of RX packet descriptors may vary from chip to chip and in different firmware versions. Unfortunately, the array that contains the actual descriptors is in the middle of the fw_status structure. To manage this, we split the struct into two so we can calculate the offset of what comes after the array and access the last elements more easily. [Changed the STATUS_LEN macro to be placement agnostic - Arik] Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/main.c | 4 +- drivers/net/wireless/ti/wl18xx/main.c | 1 + drivers/net/wireless/ti/wl18xx/tx.c | 2 +- drivers/net/wireless/ti/wlcore/main.c | 64 +++++++++++++---------- drivers/net/wireless/ti/wlcore/rx.c | 10 ++-- drivers/net/wireless/ti/wlcore/rx.h | 4 +- drivers/net/wireless/ti/wlcore/wlcore.h | 5 +- drivers/net/wireless/ti/wlcore/wlcore_i.h | 18 +++++-- 8 files changed, 66 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 1d097c1bcace..82e0c6a6ac89 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1156,7 +1156,8 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, static void wl12xx_tx_delayed_compl(struct wl1271 *wl) { - if (wl->fw_status->tx_results_counter == (wl->tx_results_count & 0xff)) + if (wl->fw_status_1->tx_results_counter == + (wl->tx_results_count & 0xff)) return; wl1271_tx_complete(wl); @@ -1414,6 +1415,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) wl->ptable = wl12xx_ptable; wl->rtable = wl12xx_rtable; wl->num_tx_desc = 16; + wl->num_rx_desc = 8; wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE; wl->band_rate_to_idx = wl12xx_band_rate_to_idx; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b76b6ac348da..df407be9ed44 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1041,6 +1041,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->ptable = wl18xx_ptable; wl->rtable = wl18xx_rtable; wl->num_tx_desc = 32; + wl->num_rx_desc = 16; wl->normal_tx_spare = WL18XX_TX_HW_BLOCK_SPARE; wl->gem_tx_spare = WL18XX_TX_HW_GEM_BLOCK_SPARE; wl->band_rate_to_idx = wl18xx_band_rate_to_idx; diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c index 4e12f56b394f..4de00b901505 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.c +++ b/drivers/net/wireless/ti/wl18xx/tx.c @@ -94,7 +94,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) void wl18xx_tx_immediate_complete(struct wl1271 *wl) { struct wl18xx_fw_status_priv *status_priv = - (struct wl18xx_fw_status_priv *)wl->fw_status->priv; + (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; struct wl18xx_priv *priv = wl->priv; u8 i; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 373be7f667ed..395da0b3377b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -347,7 +347,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, static void wl12xx_irq_update_links_status(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct wl_fw_status *status) + struct wl_fw_status_2 *status) { struct wl1271_link *lnk; u32 cur_fw_ps_map; @@ -379,7 +379,8 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, } static void wl12xx_fw_status(struct wl1271 *wl, - struct wl_fw_status *status) + struct wl_fw_status_1 *status_1, + struct wl_fw_status_2 *status_2) { struct wl12xx_vif *wlvif; struct timespec ts; @@ -388,37 +389,38 @@ static void wl12xx_fw_status(struct wl1271 *wl, int i; size_t status_len; - status_len = sizeof(*status) + wl->fw_status_priv_len; + status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + + sizeof(*status_2) + wl->fw_status_priv_len; - wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status, + wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, status_len, false); wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " "drv_rx_counter = %d, tx_results_counter = %d)", - status->intr, - status->fw_rx_counter, - status->drv_rx_counter, - status->tx_results_counter); + status_1->intr, + status_1->fw_rx_counter, + status_1->drv_rx_counter, + status_1->tx_results_counter); for (i = 0; i < NUM_TX_QUEUES; i++) { /* prevent wrap-around in freed-packets counter */ wl->tx_allocated_pkts[i] -= - (status->counters.tx_released_pkts[i] - + (status_2->counters.tx_released_pkts[i] - wl->tx_pkts_freed[i]) & 0xff; - wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i]; + wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i]; } /* prevent wrap-around in total blocks counter */ if (likely(wl->tx_blocks_freed <= - le32_to_cpu(status->total_released_blks))) - freed_blocks = le32_to_cpu(status->total_released_blks) - + le32_to_cpu(status_2->total_released_blks))) + freed_blocks = le32_to_cpu(status_2->total_released_blks) - wl->tx_blocks_freed; else freed_blocks = 0x100000000LL - wl->tx_blocks_freed + - le32_to_cpu(status->total_released_blks); + le32_to_cpu(status_2->total_released_blks); - wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks); + wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks); wl->tx_allocated_blocks -= freed_blocks; @@ -434,7 +436,7 @@ static void wl12xx_fw_status(struct wl1271 *wl, cancel_delayed_work(&wl->tx_watchdog_work); } - avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; + avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks; /* * The FW might change the total number of TX memblocks before @@ -453,13 +455,13 @@ static void wl12xx_fw_status(struct wl1271 *wl, /* for AP update num of allocated TX blocks per link and ps status */ wl12xx_for_each_wlvif_ap(wl, wlvif) { - wl12xx_irq_update_links_status(wl, wlvif, status); + wl12xx_irq_update_links_status(wl, wlvif, status_2); } /* update the host-chipset time offset */ getnstimeofday(&ts); wl->time_offset = (timespec_to_ns(&ts) >> 10) - - (s64)le32_to_cpu(status->fw_localtime); + (s64)le32_to_cpu(status_2->fw_localtime); } static void wl1271_flush_deferred_work(struct wl1271 *wl) @@ -528,11 +530,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); smp_mb__after_clear_bit(); - wl12xx_fw_status(wl, wl->fw_status); + wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); wlcore_hw_tx_immediate_compl(wl); - intr = le32_to_cpu(wl->fw_status->intr); + intr = le32_to_cpu(wl->fw_status_1->intr); intr &= WL1271_INTR_MASK; if (!intr) { done = true; @@ -551,7 +553,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (likely(intr & WL1271_ACX_INTR_DATA)) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); - wl12xx_rx(wl, wl->fw_status); + wl12xx_rx(wl, wl->fw_status_1); /* Check if any tx blocks were freed */ spin_lock_irqsave(&wl->wl_lock, flags); @@ -786,8 +788,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) wl12xx_cmd_stop_fwlog(wl); /* Read the first memory block address */ - wl12xx_fw_status(wl, wl->fw_status); - first_addr = le32_to_cpu(wl->fw_status->log_start_addr); + wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); + first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr); if (!first_addr) goto out; @@ -901,13 +903,18 @@ static void wl1271_fw_wakeup(struct wl1271 *wl) static int wl1271_setup(struct wl1271 *wl) { - wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL); - if (!wl->fw_status) + wl->fw_status_1 = kmalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + + sizeof(*wl->fw_status_2), GFP_KERNEL); + if (!wl->fw_status_1) return -ENOMEM; + wl->fw_status_2 = (struct wl_fw_status_2 *) + (((u8 *) wl->fw_status_1) + + WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc)); + wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); if (!wl->tx_res_if) { - kfree(wl->fw_status); + kfree(wl->fw_status_1); return -ENOMEM; } @@ -1746,8 +1753,9 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl1271_debugfs_reset(wl); - kfree(wl->fw_status); - wl->fw_status = NULL; + kfree(wl->fw_status_1); + wl->fw_status_1 = NULL; + wl->fw_status_2 = NULL; kfree(wl->tx_res_if); wl->tx_res_if = NULL; kfree(wl->target_mem_map); @@ -5181,7 +5189,7 @@ int wlcore_free_hw(struct wl1271 *wl) kfree(wl->nvs); wl->nvs = NULL; - kfree(wl->fw_status); + kfree(wl->fw_status_1); kfree(wl->tx_res_if); destroy_workqueue(wl->freezable_wq); diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index 2672b1d16cef..78200dcacfca 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -200,12 +200,12 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, return is_data; } -void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) +void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) { unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; u32 buf_size; - u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; - u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc; + u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc; u32 rx_counter; u32 pkt_len, align_pkt_len; u32 pkt_offset, des; @@ -224,7 +224,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) break; buf_size += align_pkt_len; rx_counter++; - rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + rx_counter %= wl->num_rx_desc; } if (buf_size == 0) { @@ -264,7 +264,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) wl->rx_counter++; drv_rx_counter++; - drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + drv_rx_counter %= wl->num_rx_desc; pkt_offset += wlcore_rx_get_align_buf_size(wl, pkt_len); } } diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h index 277936e14137..9be780179456 100644 --- a/drivers/net/wireless/ti/wlcore/rx.h +++ b/drivers/net/wireless/ti/wlcore/rx.h @@ -38,8 +38,6 @@ #define RX_DESC_PACKETID_SHIFT 11 #define RX_MAX_PACKET_ID 3 -#define NUM_RX_PKT_DESC_MOD_MASK 7 - #define RX_DESC_VALID_FCS 0x0001 #define RX_DESC_MATCH_RXADDR1 0x0002 #define RX_DESC_MCAST 0x0004 @@ -139,7 +137,7 @@ struct wl1271_rx_descriptor { u8 reserved; } __packed; -void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status); +void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 1fc3c77c10a3..9ca382918184 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -269,7 +269,8 @@ struct wl1271 { u32 buffer_cmd; u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; - struct wl_fw_status *fw_status; + struct wl_fw_status_1 *fw_status_1; + struct wl_fw_status_2 *fw_status_2; struct wl1271_tx_hw_res_if *tx_res_if; /* Current chipset configuration */ @@ -337,6 +338,8 @@ struct wl1271 { /* number of TX descriptors the HW supports. */ u32 num_tx_desc; + /* number of RX descriptors the HW supports. */ + u32 num_rx_desc; /* spare Tx blocks for normal/GEM operating modes */ u32 normal_tx_spare; diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 53263a978a75..0422753f673c 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -141,7 +141,6 @@ struct wl1271_stats { }; #define NUM_TX_QUEUES 4 -#define NUM_RX_PKT_DESC 8 #define AP_MAX_STATIONS 8 @@ -159,13 +158,26 @@ struct wl_fw_packet_counters { } __packed; /* FW status registers */ -struct wl_fw_status { +struct wl_fw_status_1 { __le32 intr; u8 fw_rx_counter; u8 drv_rx_counter; u8 reserved; u8 tx_results_counter; - __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; + __le32 rx_pkt_descs[0]; +} __packed; + +/* + * Each HW arch has a different number of Rx descriptors. + * The length of the status depends on it, since it holds an array + * of descriptors. + */ +#define WLCORE_FW_STATUS_1_LEN(num_rx_desc) \ + (sizeof(struct wl_fw_status_1) + \ + (sizeof(((struct wl_fw_status_1 *)0)->rx_pkt_descs[0])) * \ + num_rx_desc) + +struct wl_fw_status_2 { __le32 fw_localtime; /* -- GitLab From a5114d9c0def1286aa1d565280b350fee4d1c75b Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:55 +0300 Subject: [PATCH 0559/6849] wl18xx: derive the MAC address from the BD_ADDR in fuse ROM Add the get_mac operation in order to fetch the BD_ADDR from fuse ROM, so that we can derive the WLAN MAC addresses from it. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 18 ++++++++++++++++++ drivers/net/wireless/ti/wl18xx/reg.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index df407be9ed44..52d63ff1d352 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -975,6 +975,23 @@ static int wl18xx_plt_init(struct wl1271 *wl) return wl->ops->boot(wl); } +static void wl18xx_get_mac(struct wl1271 *wl) +{ + u32 mac1, mac2; + + wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + + mac1 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1); + mac2 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2); + + /* these are the two parts of the BD_ADDR */ + wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + + ((mac1 & 0xff000000) >> 24); + wl->fuse_nic_addr = (mac1 & 0xffffff); + + wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -994,6 +1011,7 @@ static struct wlcore_ops wl18xx_ops = { .set_rx_csum = wl18xx_set_rx_csum, .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, + .get_mac = wl18xx_get_mac, }; /* HT cap appropriate for wide channels */ diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index aaedf91ed7b7..43863d35feb2 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -132,6 +132,9 @@ #define WL18XX_PG_VER_MASK 0x70 #define WL18XX_PG_VER_OFFSET 4 +#define WL18XX_REG_FUSE_BD_ADDR_1 0xA02602 +#define WL18XX_REG_FUSE_BD_ADDR_2 0xA02606 + #define WL18XX_CMD_MBOX_ADDRESS 0xB007B4 #define WL18XX_FW_STATUS_ADDR 0x50F8 -- GitLab From 1ddbc7d4c744eb24aa0d51ab1f4ad6b5c0fd0c02 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:56 +0300 Subject: [PATCH 0560/6849] wl18xx: add a module parameter to control 11a support In wl18xx we don't have an NVS yet, so we need to control whether 11a is supported with a module parameter for now. 11a support is enabled by default and can be changed by setting enable_11a to false when loading the module. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 52d63ff1d352..d4e331fb73e3 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -48,6 +48,7 @@ static bool dc2dc_param = false; static int n_antennas_2_param = 1; static int n_antennas_5_param = 1; static bool checksum_param = true; +static bool enable_11a_param = true; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -1097,6 +1098,8 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl18xx_ops.init_vif = NULL; } + wl->enable_11a = enable_11a_param; + wl18xx_conf_init(wl); return wlcore_probe(wl, pdev); @@ -1149,6 +1152,9 @@ MODULE_PARM_DESC(n_antennas_5, "Number of installed 5GHz antennas: 1 (default) o module_param_named(checksum, checksum_param, bool, S_IRUSR); MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to true)"); +module_param_named(enable_11a, enable_11a_param, bool, S_IRUSR); +MODULE_PARM_DESC(enable_11a, "Enable 11a (5GHz): boolean (defaults to true)"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From df472894ab21814edf54a3cd81c8ae7066365e0e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:57 +0300 Subject: [PATCH 0561/6849] wlcore: add module parameter to dump SDIO reads and writes In some cases we may want to dump all the SDIO data in order to get detailed information for debugging the communication with the firmware. Add printks to dump the data and a module parameter to enable/disable it. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/sdio.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 1082e394e8f7..c67ec482e445 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "wlcore.h" #include "wl12xx_80211.h" @@ -46,6 +47,8 @@ #define SDIO_DEVICE_ID_TI_WL1271 0x4076 #endif +static bool dump = false; + struct wl12xx_sdio_glue { struct device *dev; struct platform_device *core; @@ -77,6 +80,13 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, sdio_claim_host(func); + if (unlikely(dump)) { + printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr); + print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ", + DUMP_PREFIX_OFFSET, 16, 1, + buf, len, false); + } + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", @@ -106,6 +116,13 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, sdio_claim_host(func); + if (unlikely(dump)) { + printk(KERN_DEBUG "wlcore_sdio: WRITE to 0x%04x\n", addr); + print_hex_dump(KERN_DEBUG, "wlcore_sdio: WRITE ", + DUMP_PREFIX_OFFSET, 16, 1, + buf, len, false); + } + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", @@ -380,6 +397,9 @@ static void __exit wl1271_exit(void) module_init(wl1271_init); module_exit(wl1271_exit); +module_param(dump, bool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); -- GitLab From 776f030aa0ed65fbc266219fb858bbfc909d97d2 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:58 +0300 Subject: [PATCH 0562/6849] wl18xx: copy the default configuration before checking the board_type We were changing the low_band_component_type in the private configuration structure before copying the default values to it, so the change was overwritten and only took effect after HW recovery. Reported-by: Dror Erez Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index d4e331fb73e3..f5ec6f60db33 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1072,6 +1072,8 @@ int __devinit wl18xx_probe(struct platform_device *pdev) memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, sizeof(wl18xx_mimo_ht_cap)); + wl18xx_conf_init(wl); + if (!board_type_param) { board_type_param = kstrdup("dvp", GFP_KERNEL); priv->board_type = BOARD_TYPE_DVP_18XX; @@ -1100,8 +1102,6 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->enable_11a = enable_11a_param; - wl18xx_conf_init(wl); - return wlcore_probe(wl, pdev); } -- GitLab From 4b9d2365d51e9726cd288dbeebf20a80d3ac8a38 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:13:59 +0300 Subject: [PATCH 0563/6849] wl18xx: changed default board_type to HDK Since the most common board we're using now is an HDK board, change the default board_type to hdk. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index f5ec6f60db33..aa227a17187e 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -43,7 +43,7 @@ #define WL18XX_RX_CHECKSUM_MASK 0x40 static char *ht_mode_param; -static char *board_type_param; +static char *board_type_param = "hdk"; static bool dc2dc_param = false; static int n_antennas_2_param = 1; static int n_antennas_5_param = 1; @@ -1074,10 +1074,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl18xx_conf_init(wl); - if (!board_type_param) { - board_type_param = kstrdup("dvp", GFP_KERNEL); - priv->board_type = BOARD_TYPE_DVP_18XX; - } else if (!strcmp(board_type_param, "fpga")) { + if (!strcmp(board_type_param, "fpga")) { priv->board_type = BOARD_TYPE_FPGA_18XX; } else if (!strcmp(board_type_param, "hdk")) { priv->board_type = BOARD_TYPE_HDK_18XX; @@ -1137,8 +1134,8 @@ module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or mimo"); module_param_named(board_type, board_type_param, charp, S_IRUSR); -MODULE_PARM_DESC(board_type, "Board type: fpga, hdk, evb, com8 or " - "dvp (default)"); +MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " + "dvp"); module_param_named(dc2dc, dc2dc_param, bool, S_IRUSR); MODULE_PARM_DESC(dc2dc, "External DC2DC: boolean (defaults to false)"); -- GitLab From 4f64a1e93f4749ea2ecacb7e93485ef9607b4e48 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:00 +0300 Subject: [PATCH 0564/6849] wlcore: add space for private area when allocating fw_status When allocating the fw_status structure, the space for the lower-driver private area was missing. This was causing an illegal write outside the allocated area, which was causing random oopses around the kernel. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 395da0b3377b..bc33ee25f7d1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -904,7 +904,8 @@ static void wl1271_fw_wakeup(struct wl1271 *wl) static int wl1271_setup(struct wl1271 *wl) { wl->fw_status_1 = kmalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + - sizeof(*wl->fw_status_2), GFP_KERNEL); + sizeof(*wl->fw_status_2) + + wl->fw_status_priv_len, GFP_KERNEL); if (!wl->fw_status_1) return -ENOMEM; -- GitLab From 73d8a42464d3fd8de907d032a7dafa1d23d88490 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:01 +0300 Subject: [PATCH 0565/6849] wl18xx: change low_band_component_type value for COM8 Like HDK, COM8 uses 0x06 for the low_band_component_type as well. Hardcode the value for COM8 until this configuration can be done in the external configuration binary (to be implemented). Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index aa227a17187e..6047a6d90975 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1086,6 +1086,8 @@ int __devinit wl18xx_probe(struct platform_device *pdev) priv->board_type = BOARD_TYPE_EVB_18XX; } else if (!strcmp(board_type_param, "com8")) { priv->board_type = BOARD_TYPE_COM8_18XX; + /* HACK! Just for now we hardcode COM8 to 0x06 */ + priv->conf.phy.low_band_component_type = 0x06; } else { wl1271_error("invalid board type '%s'", board_type_param); wlcore_free_hw(wl); -- GitLab From 4afc37a0c1c58415ac3ad1c07afd8ebf81cb90c5 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:02 +0300 Subject: [PATCH 0566/6849] wlcore: reorder identify_chip and get_hw_info We can do get the HW information and identify the chip already at probe time. This makes it easier to mangle with the parameters during identify chip before registering the hardware with mac80211. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index bc33ee25f7d1..2e77f731c0a1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -962,10 +962,6 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) if (wl1271_set_block_size(wl)) wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; - ret = wl->ops->identify_chip(wl); - if (ret < 0) - goto out; - /* TODO: make sure the lower driver has set things up correctly */ ret = wl1271_setup(wl); @@ -4872,12 +4868,6 @@ static int wl1271_register_hw(struct wl1271 *wl) if (wl->mac80211_registered) return 0; - ret = wl12xx_get_hw_info(wl); - if (ret < 0) { - wl1271_error("couldn't get hw info"); - goto out; - } - ret = wl1271_fetch_nvs(wl); if (ret == 0) { /* NOTE: The wl->nvs->nvs element must be first, in @@ -5282,6 +5272,16 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) } disable_irq(wl->irq); + ret = wl12xx_get_hw_info(wl); + if (ret < 0) { + wl1271_error("couldn't get hw info"); + goto out; + } + + ret = wl->ops->identify_chip(wl); + if (ret < 0) + goto out; + ret = wl1271_init_ieee80211(wl); if (ret) goto out_irq; -- GitLab From 7ae25da3967298199881c72ee476a1f9ec682fd8 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:03 +0300 Subject: [PATCH 0567/6849] wl18xx: disable MCS_13 for wl18xx PG 1.0 There are some problems with MCS_13 in PG 1.0 hardware. So we disable it when PG 1.0 is detected. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 6047a6d90975..afa2334d0aea 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -588,6 +588,9 @@ static int wl18xx_identify_chip(struct wl1271 *wl) WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; + /* PG 1.0 has some problems with MCS_13, so disable it */ + wl->ht_cap.mcs.rx_mask[1] &= ~BIT(5); + /* TODO: need to blocksize alignment for RX/TX separately? */ break; default: @@ -914,6 +917,10 @@ static void wl18xx_set_rx_csum(struct wl1271 *wl, skb->ip_summed = CHECKSUM_UNNECESSARY; } +/* + * TODO: instead of having these two functions to get the rate mask, + * we should modify the wlvif->rate_set instead + */ static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif) { @@ -940,6 +947,17 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, return CONF_TX_RATE_USE_WIDE_CHAN; } else { wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); + + /* + * PG 1.0 has some problems with MCS_13, so disable it + * + * TODO: instead of hacking this in here, we should + * make it more general and change a bit in the + * wlvif->rate_set instead. + */ + if (wl->chip.id == CHIP_ID_185x_PG10) + return CONF_TX_MIMO_RATES & ~CONF_HW_BIT_RATE_MCS_13; + return CONF_TX_MIMO_RATES; } } -- GitLab From 62c2e579e008784b929abef27f5728db2a1d88bf Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:04 +0300 Subject: [PATCH 0568/6849] wlcore: update beacon and probe_resp templates when rates change When the data rates change, we get BSS_CHANGED_BASIC_RATES. At this point, we should update all the templates to match the new rates. We were changing some of the templates, but the beacon and the probe response templates were missing. [Remove redundant min_rate variable - Arik] Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/main.c | 173 +++++++++++++++----------- 1 file changed, 100 insertions(+), 73 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 2e77f731c0a1..c9ccf2757e2a 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -3277,8 +3277,15 @@ static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates, skb->data, skb->len, 0, rates); - dev_kfree_skb(skb); + + if (ret < 0) + goto out; + + wl1271_debug(DEBUG_AP, "probe response updated"); + set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags); + +out: return ret; } @@ -3383,6 +3390,87 @@ out: return ret; } +static int wlcore_set_beacon_template(struct wl1271 *wl, + struct ieee80211_vif *vif, + bool is_ap) +{ + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); + struct ieee80211_hdr *hdr; + u32 min_rate; + int ret; + int ieoffset = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); + u16 tmpl_id; + + if (!beacon) { + ret = -EINVAL; + goto out; + } + + wl1271_debug(DEBUG_MASTER, "beacon updated"); + + ret = wl1271_ssid_set(vif, beacon, ieoffset); + if (ret < 0) { + dev_kfree_skb(beacon); + goto out; + } + min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); + tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : + CMD_TEMPL_BEACON; + ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id, + beacon->data, + beacon->len, 0, + min_rate); + if (ret < 0) { + dev_kfree_skb(beacon); + goto out; + } + + /* + * In case we already have a probe-resp beacon set explicitly + * by usermode, don't use the beacon data. + */ + if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags)) + goto end_bcn; + + /* remove TIM ie from probe response */ + wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); + + /* + * remove p2p ie from probe response. + * the fw reponds to probe requests that don't include + * the p2p ie. probe requests with p2p ie will be passed, + * and will be responded by the supplicant (the spec + * forbids including the p2p ie when responding to probe + * requests that didn't include it). + */ + wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, + WLAN_OUI_TYPE_WFA_P2P, ieoffset); + + hdr = (struct ieee80211_hdr *) beacon->data; + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_PROBE_RESP); + if (is_ap) + ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif, + beacon->data, + beacon->len, + min_rate); + else + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_PROBE_RESPONSE, + beacon->data, + beacon->len, 0, + min_rate); +end_bcn: + dev_kfree_skb(beacon); + if (ret < 0) + goto out; + +out: + return ret; +} + static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -3401,81 +3489,12 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) { u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); - if (!wl1271_ap_set_probe_resp_tmpl(wl, rate, vif)) { - wl1271_debug(DEBUG_AP, "probe response updated"); - set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags); - } + + wl1271_ap_set_probe_resp_tmpl(wl, rate, vif); } if ((changed & BSS_CHANGED_BEACON)) { - struct ieee80211_hdr *hdr; - u32 min_rate; - int ieoffset = offsetof(struct ieee80211_mgmt, - u.beacon.variable); - struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); - u16 tmpl_id; - - if (!beacon) { - ret = -EINVAL; - goto out; - } - - wl1271_debug(DEBUG_MASTER, "beacon updated"); - - ret = wl1271_ssid_set(vif, beacon, ieoffset); - if (ret < 0) { - dev_kfree_skb(beacon); - goto out; - } - min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); - tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : - CMD_TEMPL_BEACON; - ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id, - beacon->data, - beacon->len, 0, - min_rate); - if (ret < 0) { - dev_kfree_skb(beacon); - goto out; - } - - /* - * In case we already have a probe-resp beacon set explicitly - * by usermode, don't use the beacon data. - */ - if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags)) - goto end_bcn; - - /* remove TIM ie from probe response */ - wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); - - /* - * remove p2p ie from probe response. - * the fw reponds to probe requests that don't include - * the p2p ie. probe requests with p2p ie will be passed, - * and will be responded by the supplicant (the spec - * forbids including the p2p ie when responding to probe - * requests that didn't include it). - */ - wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, - WLAN_OUI_TYPE_WFA_P2P, ieoffset); - - hdr = (struct ieee80211_hdr *) beacon->data; - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); - if (is_ap) - ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif, - beacon->data, - beacon->len, - min_rate); - else - ret = wl1271_cmd_template_set(wl, wlvif->role_id, - CMD_TEMPL_PROBE_RESPONSE, - beacon->data, - beacon->len, 0, - min_rate); -end_bcn: - dev_kfree_skb(beacon); + ret = wlcore_set_beacon_template(wl, vif, is_ap); if (ret < 0) goto out; } @@ -3512,6 +3531,14 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, ret = wl1271_ap_init_templates(wl, vif); if (ret < 0) goto out; + + ret = wl1271_ap_set_probe_resp_tmpl(wl, wlvif->basic_rate, vif); + if (ret < 0) + goto out; + + ret = wlcore_set_beacon_template(wl, vif, true); + if (ret < 0) + goto out; } ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed); -- GitLab From 15e05bc0593328149f872a86fa2bb048b9997402 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:05 +0300 Subject: [PATCH 0569/6849] wlcore: use all AP basic rates as default Sometimes we get a BSS_CHANGED_BEACON_ENABLED event before the basic rates have been properly set. To avoid problems with the firmware not expecting to receive frames at rates that are not set during CMD_START_ROLE, we now start with all basic rates by default. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index c9ccf2757e2a..9589aa956bf7 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1846,6 +1846,9 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx); wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx); wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx); + wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC; + wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC; + wlvif->rate_set = CONF_TX_RATE_MASK_BASIC; } else { /* init ap data */ wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; @@ -1855,13 +1858,19 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) wl12xx_allocate_rate_policy(wl, &wlvif->ap.ucast_rate_idx[i]); + wlvif->basic_rate_set = CONF_TX_AP_ENABLED_RATES; + /* + * TODO: check if basic_rate shouldn't be + * wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); + * instead (the same thing for STA above). + */ + wlvif->basic_rate = CONF_TX_AP_ENABLED_RATES; + /* TODO: this seems to be used only for STA, check it */ + wlvif->rate_set = CONF_TX_AP_ENABLED_RATES; } wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; wlvif->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; - wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC; - wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC; - wlvif->rate_set = CONF_TX_RATE_MASK_BASIC; wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT; /* -- GitLab From 4987257c304bf5d12e7a5cedde1100ba7f14a8a3 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:06 +0300 Subject: [PATCH 0570/6849] wlcore: abstract debugfs fw_stats to be handled by the lower drivers The FW statistics differ from hardware to hardware. This commit prepares for hardware-specific implementation of the FW statistics debugfs entries. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/acx.c | 4 +- drivers/net/wireless/ti/wlcore/acx.h | 224 +---------------- drivers/net/wireless/ti/wlcore/debugfs.c | 279 ++-------------------- drivers/net/wireless/ti/wlcore/debugfs.h | 60 +++++ drivers/net/wireless/ti/wlcore/hw_ops.h | 9 + drivers/net/wireless/ti/wlcore/wlcore.h | 10 + drivers/net/wireless/ti/wlcore/wlcore_i.h | 8 - 7 files changed, 104 insertions(+), 490 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index fd33be7d5c94..b9ec42c83757 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -709,14 +709,14 @@ out: return ret; } -int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) +int wl1271_acx_statistics(struct wl1271 *wl, void *stats) { int ret; wl1271_debug(DEBUG_ACX, "acx statistics"); ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, - sizeof(*stats)); + wl->stats.fw_stats_len); if (ret < 0) { wl1271_warning("acx statistics failed: %d", ret); return -ENOMEM; diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index ff0c5ba8e8ff..8b3807b879d3 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -417,228 +417,6 @@ struct acx_ctsprotect { u8 padding[2]; } __packed; -struct acx_tx_statistics { - __le32 internal_desc_overflow; -} __packed; - -struct acx_rx_statistics { - __le32 out_of_mem; - __le32 hdr_overflow; - __le32 hw_stuck; - __le32 dropped; - __le32 fcs_err; - __le32 xfr_hint_trig; - __le32 path_reset; - __le32 reset_counter; -} __packed; - -struct acx_dma_statistics { - __le32 rx_requested; - __le32 rx_errors; - __le32 tx_requested; - __le32 tx_errors; -} __packed; - -struct acx_isr_statistics { - /* host command complete */ - __le32 cmd_cmplt; - - /* fiqisr() */ - __le32 fiqs; - - /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ - __le32 rx_headers; - - /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ - __le32 rx_completes; - - /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ - __le32 rx_mem_overflow; - - /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ - __le32 rx_rdys; - - /* irqisr() */ - __le32 irqs; - - /* (INT_STS_ND & INT_TRIG_TX_PROC) */ - __le32 tx_procs; - - /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ - __le32 decrypt_done; - - /* (INT_STS_ND & INT_TRIG_DMA0) */ - __le32 dma0_done; - - /* (INT_STS_ND & INT_TRIG_DMA1) */ - __le32 dma1_done; - - /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ - __le32 tx_exch_complete; - - /* (INT_STS_ND & INT_TRIG_COMMAND) */ - __le32 commands; - - /* (INT_STS_ND & INT_TRIG_RX_PROC) */ - __le32 rx_procs; - - /* (INT_STS_ND & INT_TRIG_PM_802) */ - __le32 hw_pm_mode_changes; - - /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ - __le32 host_acknowledges; - - /* (INT_STS_ND & INT_TRIG_PM_PCI) */ - __le32 pci_pm; - - /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ - __le32 wakeups; - - /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ - __le32 low_rssi; -} __packed; - -struct acx_wep_statistics { - /* WEP address keys configured */ - __le32 addr_key_count; - - /* default keys configured */ - __le32 default_key_count; - - __le32 reserved; - - /* number of times that WEP key not found on lookup */ - __le32 key_not_found; - - /* number of times that WEP key decryption failed */ - __le32 decrypt_fail; - - /* WEP packets decrypted */ - __le32 packets; - - /* WEP decrypt interrupts */ - __le32 interrupt; -} __packed; - -#define ACX_MISSED_BEACONS_SPREAD 10 - -struct acx_pwr_statistics { - /* the amount of enters into power save mode (both PD & ELP) */ - __le32 ps_enter; - - /* the amount of enters into ELP mode */ - __le32 elp_enter; - - /* the amount of missing beacon interrupts to the host */ - __le32 missing_bcns; - - /* the amount of wake on host-access times */ - __le32 wake_on_host; - - /* the amount of wake on timer-expire */ - __le32 wake_on_timer_exp; - - /* the number of packets that were transmitted with PS bit set */ - __le32 tx_with_ps; - - /* the number of packets that were transmitted with PS bit clear */ - __le32 tx_without_ps; - - /* the number of received beacons */ - __le32 rcvd_beacons; - - /* the number of entering into PowerOn (power save off) */ - __le32 power_save_off; - - /* the number of entries into power save mode */ - __le16 enable_ps; - - /* - * the number of exits from power save, not including failed PS - * transitions - */ - __le16 disable_ps; - - /* - * the number of times the TSF counter was adjusted because - * of drift - */ - __le32 fix_tsf_ps; - - /* Gives statistics about the spread continuous missed beacons. - * The 16 LSB are dedicated for the PS mode. - * The 16 MSB are dedicated for the PS mode. - * cont_miss_bcns_spread[0] - single missed beacon. - * cont_miss_bcns_spread[1] - two continuous missed beacons. - * cont_miss_bcns_spread[2] - three continuous missed beacons. - * ... - * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. - */ - __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; - - /* the number of beacons in awake mode */ - __le32 rcvd_awake_beacons; -} __packed; - -struct acx_mic_statistics { - __le32 rx_pkts; - __le32 calc_failure; -} __packed; - -struct acx_aes_statistics { - __le32 encrypt_fail; - __le32 decrypt_fail; - __le32 encrypt_packets; - __le32 decrypt_packets; - __le32 encrypt_interrupt; - __le32 decrypt_interrupt; -} __packed; - -struct acx_event_statistics { - __le32 heart_beat; - __le32 calibration; - __le32 rx_mismatch; - __le32 rx_mem_empty; - __le32 rx_pool; - __le32 oom_late; - __le32 phy_transmit_error; - __le32 tx_stuck; -} __packed; - -struct acx_ps_statistics { - __le32 pspoll_timeouts; - __le32 upsd_timeouts; - __le32 upsd_max_sptime; - __le32 upsd_max_apturn; - __le32 pspoll_max_apturn; - __le32 pspoll_utilization; - __le32 upsd_utilization; -} __packed; - -struct acx_rxpipe_statistics { - __le32 rx_prep_beacon_drop; - __le32 descr_host_int_trig_rx_data; - __le32 beacon_buffer_thres_host_int_trig_rx_data; - __le32 missed_beacon_host_int_trig_rx_data; - __le32 tx_xfr_host_int_trig_rx_data; -} __packed; - -struct acx_statistics { - struct acx_header header; - - struct acx_tx_statistics tx; - struct acx_rx_statistics rx; - struct acx_dma_statistics dma; - struct acx_isr_statistics isr; - struct acx_wep_statistics wep; - struct acx_pwr_statistics pwr; - struct acx_aes_statistics aes; - struct acx_mic_statistics mic; - struct acx_event_statistics event; - struct acx_ps_statistics ps; - struct acx_rxpipe_statistics rxpipe; -} __packed; - struct acx_rate_class { __le32 enabled_rates; u8 short_retry_limit; @@ -1284,7 +1062,7 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif, enum acx_preamble_type preamble); int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif, enum acx_ctsprotect_type ctsprotect); -int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); +int wl1271_acx_statistics(struct wl1271 *wl, void *stats); int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif); int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, u8 idx); diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index d3775198d265..57c1eae24d63 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -25,6 +25,7 @@ #include #include +#include #include "wlcore.h" #include "debug.h" @@ -32,14 +33,15 @@ #include "ps.h" #include "io.h" #include "tx.h" +#include "hw_ops.h" /* ms */ #define WL1271_DEBUGFS_STATS_LIFETIME 1000 /* debugfs macros idea from mac80211 */ #define DEBUGFS_FORMAT_BUFFER_SIZE 100 -static int wl1271_format_buffer(char __user *userbuf, size_t count, - loff_t *ppos, char *fmt, ...) +int wl1271_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...) { va_list args; char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; @@ -51,59 +53,9 @@ static int wl1271_format_buffer(char __user *userbuf, size_t count, return simple_read_from_buffer(userbuf, count, ppos, buf, res); } +EXPORT_SYMBOL_GPL(wl1271_format_buffer); -#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ -static ssize_t name## _read(struct file *file, char __user *userbuf, \ - size_t count, loff_t *ppos) \ -{ \ - struct wl1271 *wl = file->private_data; \ - return wl1271_format_buffer(userbuf, count, ppos, \ - fmt "\n", ##value); \ -} \ - \ -static const struct file_operations name## _ops = { \ - .read = name## _read, \ - .open = simple_open, \ - .llseek = generic_file_llseek, \ -}; - -#define DEBUGFS_ADD(name, parent) \ - entry = debugfs_create_file(#name, 0400, parent, \ - wl, &name## _ops); \ - if (!entry || IS_ERR(entry)) \ - goto err; \ - -#define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ - do { \ - entry = debugfs_create_file(#name, 0400, parent, \ - wl, &prefix## _## name## _ops); \ - if (!entry || IS_ERR(entry)) \ - goto err; \ - } while (0); - -#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ -static ssize_t sub## _ ##name## _read(struct file *file, \ - char __user *userbuf, \ - size_t count, loff_t *ppos) \ -{ \ - struct wl1271 *wl = file->private_data; \ - \ - wl1271_debugfs_update_stats(wl); \ - \ - return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ - wl->stats.fw_stats->sub.name); \ -} \ - \ -static const struct file_operations sub## _ ##name## _ops = { \ - .read = sub## _ ##name## _read, \ - .open = simple_open, \ - .llseek = generic_file_llseek, \ -}; - -#define DEBUGFS_FWSTATS_ADD(sub, name) \ - DEBUGFS_ADD(sub## _ ##name, stats) - -static void wl1271_debugfs_update_stats(struct wl1271 *wl) +void wl1271_debugfs_update_stats(struct wl1271 *wl) { int ret; @@ -125,97 +77,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) out: mutex_unlock(&wl->mutex); } - -DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); - -DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); -DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); -DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); -DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); -DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); -DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); - -DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); -DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); - -DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); -DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); -DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); -DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); -DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); -DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); -DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); -DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); -DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); - -DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); -DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); -/* skipping wep.reserved */ -DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); -DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); -DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); -DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); - -DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); -/* skipping cont_miss_bcns_spread for now */ -DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); - -DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); -DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); - -DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); - -DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); -DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); -DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); -DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); -DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); - -DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); - -DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); +EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats); DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); DEBUGFS_READONLY_FILE(excessive_retries, "%u", @@ -1002,107 +864,10 @@ static const struct file_operations beacon_filtering_ops = { }; static int wl1271_debugfs_add_files(struct wl1271 *wl, - struct dentry *rootdir) + struct dentry *rootdir) { int ret = 0; - struct dentry *entry, *stats, *streaming; - - stats = debugfs_create_dir("fw-statistics", rootdir); - if (!stats || IS_ERR(stats)) { - entry = stats; - goto err; - } - - DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); - - DEBUGFS_FWSTATS_ADD(rx, out_of_mem); - DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); - DEBUGFS_FWSTATS_ADD(rx, hw_stuck); - DEBUGFS_FWSTATS_ADD(rx, dropped); - DEBUGFS_FWSTATS_ADD(rx, fcs_err); - DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); - DEBUGFS_FWSTATS_ADD(rx, path_reset); - DEBUGFS_FWSTATS_ADD(rx, reset_counter); - - DEBUGFS_FWSTATS_ADD(dma, rx_requested); - DEBUGFS_FWSTATS_ADD(dma, rx_errors); - DEBUGFS_FWSTATS_ADD(dma, tx_requested); - DEBUGFS_FWSTATS_ADD(dma, tx_errors); - - DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); - DEBUGFS_FWSTATS_ADD(isr, fiqs); - DEBUGFS_FWSTATS_ADD(isr, rx_headers); - DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); - DEBUGFS_FWSTATS_ADD(isr, rx_rdys); - DEBUGFS_FWSTATS_ADD(isr, irqs); - DEBUGFS_FWSTATS_ADD(isr, tx_procs); - DEBUGFS_FWSTATS_ADD(isr, decrypt_done); - DEBUGFS_FWSTATS_ADD(isr, dma0_done); - DEBUGFS_FWSTATS_ADD(isr, dma1_done); - DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); - DEBUGFS_FWSTATS_ADD(isr, commands); - DEBUGFS_FWSTATS_ADD(isr, rx_procs); - DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); - DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); - DEBUGFS_FWSTATS_ADD(isr, pci_pm); - DEBUGFS_FWSTATS_ADD(isr, wakeups); - DEBUGFS_FWSTATS_ADD(isr, low_rssi); - - DEBUGFS_FWSTATS_ADD(wep, addr_key_count); - DEBUGFS_FWSTATS_ADD(wep, default_key_count); - /* skipping wep.reserved */ - DEBUGFS_FWSTATS_ADD(wep, key_not_found); - DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); - DEBUGFS_FWSTATS_ADD(wep, packets); - DEBUGFS_FWSTATS_ADD(wep, interrupt); - - DEBUGFS_FWSTATS_ADD(pwr, ps_enter); - DEBUGFS_FWSTATS_ADD(pwr, elp_enter); - DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); - DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); - DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); - DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); - DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); - DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); - DEBUGFS_FWSTATS_ADD(pwr, power_save_off); - DEBUGFS_FWSTATS_ADD(pwr, enable_ps); - DEBUGFS_FWSTATS_ADD(pwr, disable_ps); - DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); - /* skipping cont_miss_bcns_spread for now */ - DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); - - DEBUGFS_FWSTATS_ADD(mic, rx_pkts); - DEBUGFS_FWSTATS_ADD(mic, calc_failure); - - DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); - DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); - - DEBUGFS_FWSTATS_ADD(event, heart_beat); - DEBUGFS_FWSTATS_ADD(event, calibration); - DEBUGFS_FWSTATS_ADD(event, rx_mismatch); - DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); - DEBUGFS_FWSTATS_ADD(event, rx_pool); - DEBUGFS_FWSTATS_ADD(event, oom_late); - DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); - DEBUGFS_FWSTATS_ADD(event, tx_stuck); - - DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); - DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); - DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); - DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); - DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); - DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); - DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); - - DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); - DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); + struct dentry *entry, *streaming; DEBUGFS_ADD(tx_queue_len, rootdir); DEBUGFS_ADD(retry_count, rootdir); @@ -1144,7 +909,7 @@ void wl1271_debugfs_reset(struct wl1271 *wl) if (!wl->stats.fw_stats) return; - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); + memset(wl->stats.fw_stats, 0, wl->stats.fw_stats_len); wl->stats.retry_count = 0; wl->stats.excessive_retries = 0; } @@ -1159,34 +924,34 @@ int wl1271_debugfs_init(struct wl1271 *wl) if (IS_ERR(rootdir)) { ret = PTR_ERR(rootdir); - goto err; + goto out; } - wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), - GFP_KERNEL); - + wl->stats.fw_stats = kzalloc(wl->stats.fw_stats_len, GFP_KERNEL); if (!wl->stats.fw_stats) { ret = -ENOMEM; - goto err_fw; + goto out_remove; } wl->stats.fw_stats_update = jiffies; ret = wl1271_debugfs_add_files(wl, rootdir); + if (ret < 0) + goto out_exit; + ret = wlcore_debugfs_init(wl, rootdir); if (ret < 0) - goto err_file; + goto out_exit; - return 0; + goto out; -err_file: - kfree(wl->stats.fw_stats); - wl->stats.fw_stats = NULL; +out_exit: + wl1271_debugfs_exit(wl); -err_fw: +out_remove: debugfs_remove_recursive(rootdir); -err: +out: return ret; } diff --git a/drivers/net/wireless/ti/wlcore/debugfs.h b/drivers/net/wireless/ti/wlcore/debugfs.h index a8d3aef011ff..e1a5bf1972bb 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.h +++ b/drivers/net/wireless/ti/wlcore/debugfs.h @@ -26,8 +26,68 @@ #include "wlcore.h" +int wl1271_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...); + int wl1271_debugfs_init(struct wl1271 *wl); void wl1271_debugfs_exit(struct wl1271 *wl); void wl1271_debugfs_reset(struct wl1271 *wl); +void wl1271_debugfs_update_stats(struct wl1271 *wl); + +#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ +static ssize_t name## _read(struct file *file, char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1271 *wl = file->private_data; \ + return wl1271_format_buffer(userbuf, count, ppos, \ + fmt "\n", ##value); \ +} \ + \ +static const struct file_operations name## _ops = { \ + .read = name## _read, \ + .open = simple_open, \ + .llseek = generic_file_llseek, \ +}; + +#define DEBUGFS_ADD(name, parent) \ + do { \ + entry = debugfs_create_file(#name, 0400, parent, \ + wl, &name## _ops); \ + if (!entry || IS_ERR(entry)) \ + goto err; \ + } while (0); + + +#define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ + do { \ + entry = debugfs_create_file(#name, 0400, parent, \ + wl, &prefix## _## name## _ops); \ + if (!entry || IS_ERR(entry)) \ + goto err; \ + } while (0); + +#define DEBUGFS_FWSTATS_FILE(sub, name, fmt, struct_type) \ +static ssize_t sub## _ ##name## _read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1271 *wl = file->private_data; \ + struct struct_type *stats = wl->stats.fw_stats; \ + \ + wl1271_debugfs_update_stats(wl); \ + \ + return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ + stats->sub.name); \ +} \ + \ +static const struct file_operations sub## _ ##name## _ops = { \ + .read = sub## _ ##name## _read, \ + .open = simple_open, \ + .llseek = generic_file_llseek, \ +}; + +#define DEBUGFS_FWSTATS_ADD(sub, name) \ + DEBUGFS_ADD(sub## _ ##name, stats) + #endif /* WL1271_DEBUGFS_H */ diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 6d3e378bd0c7..1555c3e12c1b 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -149,4 +149,13 @@ wlcore_hw_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, return 0; } +static inline int +wlcore_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) +{ + if (wl->ops->debugfs_init) + return wl->ops->debugfs_init(wl, rootdir); + + return 0; +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 9ca382918184..85fd3d9a5471 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -71,6 +71,7 @@ struct wlcore_ops { struct sk_buff *skb); u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl, struct wl12xx_vif *wlvif); + int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); }; enum wlcore_partitions { @@ -119,6 +120,15 @@ enum wlcore_registers { REG_TABLE_LEN, }; +struct wl1271_stats { + void *fw_stats; + unsigned long fw_stats_update; + size_t fw_stats_len; + + unsigned int retry_count; + unsigned int excessive_retries; +}; + struct wl1271 { struct ieee80211_hw *hw; bool mac80211_registered; diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 0422753f673c..45c07dc0df5d 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -132,14 +132,6 @@ struct wl1271_chip { unsigned int fw_ver[NUM_FW_VER]; }; -struct wl1271_stats { - struct acx_statistics *fw_stats; - unsigned long fw_stats_update; - - unsigned int retry_count; - unsigned int excessive_retries; -}; - #define NUM_TX_QUEUES 4 #define AP_MAX_STATIONS 8 -- GitLab From bcca1bbdd412fb6be32d04fc2407c81239de5f8c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:07 +0300 Subject: [PATCH 0571/6849] wlcore: add debugfs macro to help print fw statistics arrays Add a macro to make it easy to print arrays from the FW statistics array in debugfs. At the same time, increase the buffer size so arrays fit more easily. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/debugfs.c | 1 - drivers/net/wireless/ti/wlcore/debugfs.h | 27 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 57c1eae24d63..fc44262e4cf0 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -39,7 +39,6 @@ #define WL1271_DEBUGFS_STATS_LIFETIME 1000 /* debugfs macros idea from mac80211 */ -#define DEBUGFS_FORMAT_BUFFER_SIZE 100 int wl1271_format_buffer(char __user *userbuf, size_t count, loff_t *ppos, char *fmt, ...) { diff --git a/drivers/net/wireless/ti/wlcore/debugfs.h b/drivers/net/wireless/ti/wlcore/debugfs.h index e1a5bf1972bb..f7381dd69009 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.h +++ b/drivers/net/wireless/ti/wlcore/debugfs.h @@ -34,6 +34,8 @@ void wl1271_debugfs_exit(struct wl1271 *wl); void wl1271_debugfs_reset(struct wl1271 *wl); void wl1271_debugfs_update_stats(struct wl1271 *wl); +#define DEBUGFS_FORMAT_BUFFER_SIZE 256 + #define DEBUGFS_READONLY_FILE(name, fmt, value...) \ static ssize_t name## _read(struct file *file, char __user *userbuf, \ size_t count, loff_t *ppos) \ @@ -86,6 +88,31 @@ static const struct file_operations sub## _ ##name## _ops = { \ .llseek = generic_file_llseek, \ }; +#define DEBUGFS_FWSTATS_FILE_ARRAY(sub, name, len, struct_type) \ +static ssize_t sub## _ ##name## _read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1271 *wl = file->private_data; \ + struct struct_type *stats = wl->stats.fw_stats; \ + char buf[DEBUGFS_FORMAT_BUFFER_SIZE] = ""; \ + int res, i; \ + \ + wl1271_debugfs_update_stats(wl); \ + \ + for (i = 0; i < len; i++) \ + res = snprintf(buf, sizeof(buf), "%s[%d] = %d\n", \ + buf, i, stats->sub.name[i]); \ + \ + return wl1271_format_buffer(userbuf, count, ppos, "%s", buf); \ +} \ + \ +static const struct file_operations sub## _ ##name## _ops = { \ + .read = sub## _ ##name## _read, \ + .open = simple_open, \ + .llseek = generic_file_llseek, \ +}; + #define DEBUGFS_FWSTATS_ADD(sub, name) \ DEBUGFS_ADD(sub## _ ##name, stats) -- GitLab From 10b1e8a27a45559df7d02c864081e929369d83bf Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:08 +0300 Subject: [PATCH 0572/6849] wl12xx: implement fw status debugfs entries Implement the operations that are necessary to fetch the wl12xx-specific FW statistics. Re-add some of the code removed from wlcore. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/Makefile | 2 +- drivers/net/wireless/ti/wl12xx/acx.h | 223 +++++++++++++++++++++ drivers/net/wireless/ti/wl12xx/debugfs.c | 236 +++++++++++++++++++++++ drivers/net/wireless/ti/wl12xx/debugfs.h | 28 +++ drivers/net/wireless/ti/wl12xx/main.c | 8 + 5 files changed, 496 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ti/wl12xx/debugfs.c create mode 100644 drivers/net/wireless/ti/wl12xx/debugfs.h diff --git a/drivers/net/wireless/ti/wl12xx/Makefile b/drivers/net/wireless/ti/wl12xx/Makefile index 87f64b14db35..da509aa7d009 100644 --- a/drivers/net/wireless/ti/wl12xx/Makefile +++ b/drivers/net/wireless/ti/wl12xx/Makefile @@ -1,3 +1,3 @@ -wl12xx-objs = main.o cmd.o acx.o +wl12xx-objs = main.o cmd.o acx.o debugfs.o obj-$(CONFIG_WL12XX) += wl12xx.o diff --git a/drivers/net/wireless/ti/wl12xx/acx.h b/drivers/net/wireless/ti/wl12xx/acx.h index d1f5aba0afce..1be0f2d31b19 100644 --- a/drivers/net/wireless/ti/wl12xx/acx.h +++ b/drivers/net/wireless/ti/wl12xx/acx.h @@ -24,6 +24,7 @@ #define __WL12XX_ACX_H__ #include "../wlcore/wlcore.h" +#include "../wlcore/acx.h" struct wl1271_acx_host_config_bitmap { struct acx_header header; @@ -31,6 +32,228 @@ struct wl1271_acx_host_config_bitmap { __le32 host_cfg_bitmap; } __packed; +struct wl12xx_acx_tx_statistics { + __le32 internal_desc_overflow; +} __packed; + +struct wl12xx_acx_rx_statistics { + __le32 out_of_mem; + __le32 hdr_overflow; + __le32 hw_stuck; + __le32 dropped; + __le32 fcs_err; + __le32 xfr_hint_trig; + __le32 path_reset; + __le32 reset_counter; +} __packed; + +struct wl12xx_acx_dma_statistics { + __le32 rx_requested; + __le32 rx_errors; + __le32 tx_requested; + __le32 tx_errors; +} __packed; + +struct wl12xx_acx_isr_statistics { + /* host command complete */ + __le32 cmd_cmplt; + + /* fiqisr() */ + __le32 fiqs; + + /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ + __le32 rx_headers; + + /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ + __le32 rx_completes; + + /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ + __le32 rx_mem_overflow; + + /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ + __le32 rx_rdys; + + /* irqisr() */ + __le32 irqs; + + /* (INT_STS_ND & INT_TRIG_TX_PROC) */ + __le32 tx_procs; + + /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ + __le32 decrypt_done; + + /* (INT_STS_ND & INT_TRIG_DMA0) */ + __le32 dma0_done; + + /* (INT_STS_ND & INT_TRIG_DMA1) */ + __le32 dma1_done; + + /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ + __le32 tx_exch_complete; + + /* (INT_STS_ND & INT_TRIG_COMMAND) */ + __le32 commands; + + /* (INT_STS_ND & INT_TRIG_RX_PROC) */ + __le32 rx_procs; + + /* (INT_STS_ND & INT_TRIG_PM_802) */ + __le32 hw_pm_mode_changes; + + /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ + __le32 host_acknowledges; + + /* (INT_STS_ND & INT_TRIG_PM_PCI) */ + __le32 pci_pm; + + /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ + __le32 wakeups; + + /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ + __le32 low_rssi; +} __packed; + +struct wl12xx_acx_wep_statistics { + /* WEP address keys configured */ + __le32 addr_key_count; + + /* default keys configured */ + __le32 default_key_count; + + __le32 reserved; + + /* number of times that WEP key not found on lookup */ + __le32 key_not_found; + + /* number of times that WEP key decryption failed */ + __le32 decrypt_fail; + + /* WEP packets decrypted */ + __le32 packets; + + /* WEP decrypt interrupts */ + __le32 interrupt; +} __packed; + +#define ACX_MISSED_BEACONS_SPREAD 10 + +struct wl12xx_acx_pwr_statistics { + /* the amount of enters into power save mode (both PD & ELP) */ + __le32 ps_enter; + + /* the amount of enters into ELP mode */ + __le32 elp_enter; + + /* the amount of missing beacon interrupts to the host */ + __le32 missing_bcns; + + /* the amount of wake on host-access times */ + __le32 wake_on_host; + + /* the amount of wake on timer-expire */ + __le32 wake_on_timer_exp; + + /* the number of packets that were transmitted with PS bit set */ + __le32 tx_with_ps; + + /* the number of packets that were transmitted with PS bit clear */ + __le32 tx_without_ps; + + /* the number of received beacons */ + __le32 rcvd_beacons; + + /* the number of entering into PowerOn (power save off) */ + __le32 power_save_off; + + /* the number of entries into power save mode */ + __le16 enable_ps; + + /* + * the number of exits from power save, not including failed PS + * transitions + */ + __le16 disable_ps; + + /* + * the number of times the TSF counter was adjusted because + * of drift + */ + __le32 fix_tsf_ps; + + /* Gives statistics about the spread continuous missed beacons. + * The 16 LSB are dedicated for the PS mode. + * The 16 MSB are dedicated for the PS mode. + * cont_miss_bcns_spread[0] - single missed beacon. + * cont_miss_bcns_spread[1] - two continuous missed beacons. + * cont_miss_bcns_spread[2] - three continuous missed beacons. + * ... + * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. + */ + __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; + + /* the number of beacons in awake mode */ + __le32 rcvd_awake_beacons; +} __packed; + +struct wl12xx_acx_mic_statistics { + __le32 rx_pkts; + __le32 calc_failure; +} __packed; + +struct wl12xx_acx_aes_statistics { + __le32 encrypt_fail; + __le32 decrypt_fail; + __le32 encrypt_packets; + __le32 decrypt_packets; + __le32 encrypt_interrupt; + __le32 decrypt_interrupt; +} __packed; + +struct wl12xx_acx_event_statistics { + __le32 heart_beat; + __le32 calibration; + __le32 rx_mismatch; + __le32 rx_mem_empty; + __le32 rx_pool; + __le32 oom_late; + __le32 phy_transmit_error; + __le32 tx_stuck; +} __packed; + +struct wl12xx_acx_ps_statistics { + __le32 pspoll_timeouts; + __le32 upsd_timeouts; + __le32 upsd_max_sptime; + __le32 upsd_max_apturn; + __le32 pspoll_max_apturn; + __le32 pspoll_utilization; + __le32 upsd_utilization; +} __packed; + +struct wl12xx_acx_rxpipe_statistics { + __le32 rx_prep_beacon_drop; + __le32 descr_host_int_trig_rx_data; + __le32 beacon_buffer_thres_host_int_trig_rx_data; + __le32 missed_beacon_host_int_trig_rx_data; + __le32 tx_xfr_host_int_trig_rx_data; +} __packed; + +struct wl12xx_acx_statistics { + struct acx_header header; + + struct wl12xx_acx_tx_statistics tx; + struct wl12xx_acx_rx_statistics rx; + struct wl12xx_acx_dma_statistics dma; + struct wl12xx_acx_isr_statistics isr; + struct wl12xx_acx_wep_statistics wep; + struct wl12xx_acx_pwr_statistics pwr; + struct wl12xx_acx_aes_statistics aes; + struct wl12xx_acx_mic_statistics mic; + struct wl12xx_acx_event_statistics event; + struct wl12xx_acx_ps_statistics ps; + struct wl12xx_acx_rxpipe_statistics rxpipe; +} __packed; + int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap); #endif /* __WL12XX_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wl12xx/debugfs.c b/drivers/net/wireless/ti/wl12xx/debugfs.c new file mode 100644 index 000000000000..9cc79d8e647b --- /dev/null +++ b/drivers/net/wireless/ti/wl12xx/debugfs.c @@ -0,0 +1,236 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2011-2012 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "../wlcore/debugfs.h" +#include "../wlcore/wlcore.h" + +#include "wl12xx.h" +#include "acx.h" + +#define WL12XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ + DEBUGFS_FWSTATS_FILE(a, b, c, wl12xx_acx_statistics) + +WL12XX_DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); +/* skipping wep.reserved */ +WL12XX_DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); +/* skipping cont_miss_bcns_spread for now */ +WL12XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); + +WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, + "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); +WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); + +int wl12xx_debugfs_add_files(struct wl1271 *wl, + struct dentry *rootdir) +{ + int ret = 0; + struct dentry *entry, *stats; + + stats = debugfs_create_dir("wl12xx_fw_stats", rootdir); + if (!stats || IS_ERR(stats)) { + entry = stats; + goto err; + } + + DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); + + DEBUGFS_FWSTATS_ADD(rx, out_of_mem); + DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); + DEBUGFS_FWSTATS_ADD(rx, hw_stuck); + DEBUGFS_FWSTATS_ADD(rx, dropped); + DEBUGFS_FWSTATS_ADD(rx, fcs_err); + DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); + DEBUGFS_FWSTATS_ADD(rx, path_reset); + DEBUGFS_FWSTATS_ADD(rx, reset_counter); + + DEBUGFS_FWSTATS_ADD(dma, rx_requested); + DEBUGFS_FWSTATS_ADD(dma, rx_errors); + DEBUGFS_FWSTATS_ADD(dma, tx_requested); + DEBUGFS_FWSTATS_ADD(dma, tx_errors); + + DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); + DEBUGFS_FWSTATS_ADD(isr, fiqs); + DEBUGFS_FWSTATS_ADD(isr, rx_headers); + DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); + DEBUGFS_FWSTATS_ADD(isr, rx_rdys); + DEBUGFS_FWSTATS_ADD(isr, irqs); + DEBUGFS_FWSTATS_ADD(isr, tx_procs); + DEBUGFS_FWSTATS_ADD(isr, decrypt_done); + DEBUGFS_FWSTATS_ADD(isr, dma0_done); + DEBUGFS_FWSTATS_ADD(isr, dma1_done); + DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); + DEBUGFS_FWSTATS_ADD(isr, commands); + DEBUGFS_FWSTATS_ADD(isr, rx_procs); + DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); + DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); + DEBUGFS_FWSTATS_ADD(isr, pci_pm); + DEBUGFS_FWSTATS_ADD(isr, wakeups); + DEBUGFS_FWSTATS_ADD(isr, low_rssi); + + DEBUGFS_FWSTATS_ADD(wep, addr_key_count); + DEBUGFS_FWSTATS_ADD(wep, default_key_count); + /* skipping wep.reserved */ + DEBUGFS_FWSTATS_ADD(wep, key_not_found); + DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); + DEBUGFS_FWSTATS_ADD(wep, packets); + DEBUGFS_FWSTATS_ADD(wep, interrupt); + + DEBUGFS_FWSTATS_ADD(pwr, ps_enter); + DEBUGFS_FWSTATS_ADD(pwr, elp_enter); + DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); + DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); + DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); + DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); + DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); + DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); + DEBUGFS_FWSTATS_ADD(pwr, power_save_off); + DEBUGFS_FWSTATS_ADD(pwr, enable_ps); + DEBUGFS_FWSTATS_ADD(pwr, disable_ps); + DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); + /* skipping cont_miss_bcns_spread for now */ + DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); + + DEBUGFS_FWSTATS_ADD(mic, rx_pkts); + DEBUGFS_FWSTATS_ADD(mic, calc_failure); + + DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); + DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); + + DEBUGFS_FWSTATS_ADD(event, heart_beat); + DEBUGFS_FWSTATS_ADD(event, calibration); + DEBUGFS_FWSTATS_ADD(event, rx_mismatch); + DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); + DEBUGFS_FWSTATS_ADD(event, rx_pool); + DEBUGFS_FWSTATS_ADD(event, oom_late); + DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); + DEBUGFS_FWSTATS_ADD(event, tx_stuck); + + DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); + DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); + DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); + DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); + DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); + DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); + DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); + + DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); + DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); + + return 0; + +err: + if (IS_ERR(entry)) + ret = PTR_ERR(entry); + else + ret = -ENOMEM; + + return ret; +} diff --git a/drivers/net/wireless/ti/wl12xx/debugfs.h b/drivers/net/wireless/ti/wl12xx/debugfs.h new file mode 100644 index 000000000000..96898e291b78 --- /dev/null +++ b/drivers/net/wireless/ti/wl12xx/debugfs.h @@ -0,0 +1,28 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2012 Texas Instruments. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL12XX_DEBUGFS_H__ +#define __WL12XX_DEBUGFS_H__ + +int wl12xx_debugfs_add_files(struct wl1271 *wl, + struct dentry *rootdir); + +#endif /* __WL12XX_DEBUGFS_H__ */ diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 82e0c6a6ac89..2ac840783551 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -39,6 +39,7 @@ #include "reg.h" #include "cmd.h" #include "acx.h" +#include "debugfs.h" static char *fref_param; static char *tcxo_param; @@ -1359,6 +1360,11 @@ out: return ret; } +static int wl12xx_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) +{ + return wl12xx_debugfs_add_files(wl, rootdir); +} + static struct wlcore_ops wl12xx_ops = { .identify_chip = wl12xx_identify_chip, .identify_fw = wl12xx_identify_fw, @@ -1381,6 +1387,7 @@ static struct wlcore_ops wl12xx_ops = { .set_tx_desc_csum = wl12xx_set_tx_desc_csum, .set_rx_csum = NULL, .ap_get_mimo_wide_rate_mask = NULL, + .debugfs_init = wl12xx_debugfs_init, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { @@ -1422,6 +1429,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = 0; + wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap)); wl12xx_conf_init(wl); -- GitLab From 8c0ea1021c38cfd2f0ba5d8fdd48a9e9827bbc03 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:09 +0300 Subject: [PATCH 0573/6849] wl18xx: implement fw status debugfs entries Implement the operations that are necessary to fetch the wl18xx-specific FW statistics and export them in debugfs. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/debugfs.c | 1 + drivers/net/wireless/ti/wl18xx/Makefile | 2 +- drivers/net/wireless/ti/wl18xx/acx.h | 199 ++++++++++++- drivers/net/wireless/ti/wl18xx/debugfs.c | 345 +++++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/debugfs.h | 28 ++ drivers/net/wireless/ti/wl18xx/main.c | 9 +- 6 files changed, 581 insertions(+), 3 deletions(-) create mode 100644 drivers/net/wireless/ti/wl18xx/debugfs.c create mode 100644 drivers/net/wireless/ti/wl18xx/debugfs.h diff --git a/drivers/net/wireless/ti/wl12xx/debugfs.c b/drivers/net/wireless/ti/wl12xx/debugfs.c index 9cc79d8e647b..311703d5af84 100644 --- a/drivers/net/wireless/ti/wl12xx/debugfs.c +++ b/drivers/net/wireless/ti/wl12xx/debugfs.c @@ -25,6 +25,7 @@ #include "wl12xx.h" #include "acx.h" +#include "debugfs.h" #define WL12XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ DEBUGFS_FWSTATS_FILE(a, b, c, wl12xx_acx_statistics) diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile index abd881f4ea01..67c098734c7f 100644 --- a/drivers/net/wireless/ti/wl18xx/Makefile +++ b/drivers/net/wireless/ti/wl18xx/Makefile @@ -1,3 +1,3 @@ -wl18xx-objs = main.o acx.o tx.o io.o +wl18xx-objs = main.o acx.o tx.o io.o debugfs.o obj-$(CONFIG_WL18XX) += wl18xx.o diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index 544db6ef3841..c2ccf70bcfb3 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -23,6 +23,7 @@ #define __WL18XX_ACX_H__ #include "../wlcore/wlcore.h" +#include "../wlcore/acx.h" /* numbers of bits the length field takes (add 1 for the actual number) */ #define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 @@ -60,9 +61,205 @@ struct wl18xx_acx_checksum_state { u8 pad[3]; } __packed; +struct wl18xx_acx_debug_stats { + u32 debug1; + u32 debug2; + u32 debug3; + u32 debug4; + u32 debug5; + u32 debug6; +} __packed; + +struct wl18xx_acx_ring_stats { + u32 tx_procs; + u32 prepared_descs; + u32 tx_xfr; + u32 tx_dma; + u32 tx_cmplt; + u32 rx_procs; + u32 rx_data; +} __packed; + +struct wl18xx_acx_tx_stats { + u32 tx_template_prepared; + u32 tx_data_prepared; + u32 tx_template_programmed; + u32 tx_data_programmed; + u32 tx_burst_programmed; + u32 tx_starts; + u32 tx_imm_resp; + u32 tx_start_templates; + u32 tx_start_int_templates; + u32 tx_start_fw_gen; + u32 tx_start_data; + u32 tx_start_null_frame; + u32 tx_exch; + u32 tx_retry_template; + u32 tx_retry_data; + u32 tx_exch_pending; + u32 tx_exch_expiry; + u32 tx_exch_mismatch; + u32 tx_done_template; + u32 tx_done_data; + u32 tx_done_int_template; + u32 tx_pre_xfr; + u32 tx_xfr; + u32 tx_xfr_out_of_mem; + u32 tx_dma_programmed; + u32 tx_dma_done; +} __packed; + +struct wl18xx_acx_rx_stats { + u32 rx_out_of_mem; + u32 rx_hdr_overflow; + u32 rx_hw_stuck; + u32 rx_dropped_frame; + u32 rx_complete_dropped_frame; + u32 rx_alloc_frame; + u32 rx_done_queue; + u32 rx_done; + u32 rx_defrag; + u32 rx_defrag_end; + u32 rx_mic; + u32 rx_mic_end; + u32 rx_xfr; + u32 rx_xfr_end; + u32 rx_cmplt; + u32 rx_pre_complt; + u32 rx_cmplt_task; + u32 rx_phy_hdr; + u32 rx_timeout; +} __packed; + +struct wl18xx_acx_dma_stats { + u32 rx_dma_errors; + u32 tx_dma_errors; +} __packed; + +struct wl18xx_acx_isr_stats { + u32 irqs; +} __packed; + +struct wl18xx_acx_wep_stats { + u32 wep_add_key_count; + u32 wep_default_key_count; + u32 wep_key_not_found; + u32 wep_decrypt_fail; + u32 wep_encrypt_fail; + u32 wep_dec_packets; + u32 wep_dec_interrupt; + u32 wep_enc_packets; + u32 wep_enc_interrupts; +} __packed; + +#define PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD 10 + +struct wl18xx_acx_pwr_stats { + u32 missing_bcns_cnt; + u32 rcvd_bcns_cnt; + u32 connection_out_of_sync; + u32 cont_miss_bcns_spread[PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD]; + u32 rcvd_awake_bcns_cnt; +} __packed; + +struct wl18xx_acx_mic_stats { + u32 mic_rx_pkts; + u32 mic_calc_failure; +} __packed; + +struct wl18xx_acx_aes_stats { + u32 aes_encrypt_fail; + u32 aes_decrypt_fail; + u32 aes_encrypt_packets; + u32 aes_decrypt_packets; + u32 aes_encrypt_interrupt; + u32 aes_decrypt_interrupt; +} __packed; + +struct wl18xx_acx_gem_stats { + u32 gem_encrypt_fail; + u32 gem_decrypt_fail; + u32 gem_encrypt_packets; + u32 gem_decrypt_packets; + u32 gem_encrypt_interrupt; + u32 gem_decrypt_interrupt; +} __packed; + +struct wl18xx_acx_event_stats { + u32 calibration; + u32 rx_mismatch; + u32 rx_mem_empty; +} __packed; + +struct wl18xx_acx_ps_poll_stats { + u32 ps_poll_timeouts; + u32 upsd_timeouts; + u32 upsd_max_ap_turn; + u32 ps_poll_max_ap_turn; + u32 ps_poll_utilization; + u32 upsd_utilization; +} __packed; + +struct wl18xx_acx_rx_filter_stats { + u32 beacon_filter; + u32 arp_filter; + u32 mc_filter; + u32 dup_filter; + u32 data_filter; + u32 ibss_filter; + u32 protection_filter; +} __packed; + +struct wl18xx_acx_calibration_stats { + u32 init_cal_total; + u32 init_radio_bands_fail; + u32 init_set_params; + u32 init_tx_clpc_fail; + u32 init_rx_iw_mm_fail; + u32 tune_cal_total; + u32 tune_drpw_rtrim_fail; + u32 tune_drpw_pd_buf_fail; + u32 tune_drpw_tx_mix_freq_fail; + u32 tune_drpw_ta_cal; + u32 tune_drpw_rx_if_2_gain; + u32 tune_drpw_rx_dac; + u32 tune_drpw_chan_tune; + u32 tune_drpw_rx_tx_lpf; + u32 tune_drpw_lna_tank; + u32 tune_tx_lo_leak_fail; + u32 tune_tx_iq_mm_fail; + u32 tune_tx_pdet_fail; + u32 tune_tx_ppa_fail; + u32 tune_tx_clpc_fail; + u32 tune_rx_ana_dc_fail; + u32 tune_rx_dig_dc_fail; /* check if this is needed */ + u32 tune_rx_iq_mm_fail; + u32 cal_state_fail; +} __packed; + +struct wl18xx_acx_statistics { + struct acx_header header; + + struct wl18xx_acx_ring_stats ring; + struct wl18xx_acx_debug_stats debug; + struct wl18xx_acx_tx_stats tx; + struct wl18xx_acx_rx_stats rx; + struct wl18xx_acx_dma_stats dma; + struct wl18xx_acx_isr_stats isr; + struct wl18xx_acx_wep_stats wep; + struct wl18xx_acx_pwr_stats pwr; + struct wl18xx_acx_aes_stats aes; + struct wl18xx_acx_mic_stats mic; + struct wl18xx_acx_event_stats event; + struct wl18xx_acx_ps_poll_stats ps_poll; + struct wl18xx_acx_rx_filter_stats rx_filter; + struct wl18xx_acx_calibration_stats calibration; + struct wl18xx_acx_gem_stats gem; +} __packed; + int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, u32 sdio_blk_size, u32 extra_mem_blks, u32 len_field_size); int wl18xx_acx_set_checksum_state(struct wl1271 *wl); -#endif /* __WL12XX_ACX_H__ */ +#endif /* __WL18XX_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c new file mode 100644 index 000000000000..8354dfc64bd8 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -0,0 +1,345 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2011-2012 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "../wlcore/debugfs.h" +#include "../wlcore/wlcore.h" + +#include "wl18xx.h" +#include "acx.h" +#include "debugfs.h" + +#define WL18XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ + DEBUGFS_FWSTATS_FILE(a, b, c, wl18xx_acx_statistics) +#define WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c) \ + DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c, wl18xx_acx_statistics) + +WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug1, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug2, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug3, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug4, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug5, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug6, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_procs, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ring, prepared_descs, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_xfr, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_dma, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_cmplt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ring, rx_procs, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ring, rx_data, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_prepared, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_prepared, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_programmed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_programmed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_burst_programmed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_starts, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_imm_resp, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_templates, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_int_templates, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_fw_gen, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_data, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_null_frame, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_template, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_data, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_pending, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_expiry, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_mismatch, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_template, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_data, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_int_template, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_pre_xfr, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_xfr, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_xfr_out_of_mem, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_dma_programmed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_dma_done, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_out_of_mem, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hdr_overflow, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hw_stuck, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_dropped_frame, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_complete_dropped_frame, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_alloc_frame, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done_queue, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag_end, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_mic, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_mic_end, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_xfr, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_xfr_end, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_pre_complt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt_task, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_phy_hdr, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(dma, rx_dma_errors, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(dma, tx_dma_errors, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_add_key_count, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_default_key_count, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_key_not_found, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_decrypt_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_encrypt_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_dec_packets, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_dec_interrupt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_enc_packets, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_enc_interrupts, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, missing_bcns_cnt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_bcns_cnt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, connection_out_of_sync, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pwr, cont_miss_bcns_spread, + PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_bcns_cnt, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(mic, mic_rx_pkts, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(mic, mic_calc_failure, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_encrypt_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_decrypt_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_encrypt_packets, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_decrypt_packets, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_encrypt_interrupt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_decrypt_interrupt, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_encrypt_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_decrypt_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_encrypt_packets, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_decrypt_packets, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_encrypt_interrupt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_decrypt_interrupt, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_timeouts, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_timeouts, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_max_ap_turn, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_max_ap_turn, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_utilization, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_utilization, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, beacon_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, arp_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, mc_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, dup_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, data_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, ibss_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, protection_filter, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_cal_total, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_radio_bands_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_set_params, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_tx_clpc_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_rx_iw_mm_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_cal_total, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rtrim_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_pd_buf_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_tx_mix_freq_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_ta_cal, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rx_if_2_gain, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rx_dac, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_chan_tune, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rx_tx_lpf, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_lna_tank, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_lo_leak_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_iq_mm_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_pdet_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_ppa_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_clpc_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_rx_ana_dc_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_rx_dig_dc_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_rx_iq_mm_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(calibration, cal_state_fail, "%u"); + +int wl18xx_debugfs_add_files(struct wl1271 *wl, + struct dentry *rootdir) +{ + int ret = 0; + struct dentry *entry, *stats; + + stats = debugfs_create_dir("wl18xx_fw_stats", rootdir); + if (!stats || IS_ERR(stats)) { + entry = stats; + goto err; + } + + DEBUGFS_FWSTATS_ADD(debug, debug1); + DEBUGFS_FWSTATS_ADD(debug, debug2); + DEBUGFS_FWSTATS_ADD(debug, debug3); + DEBUGFS_FWSTATS_ADD(debug, debug4); + DEBUGFS_FWSTATS_ADD(debug, debug5); + DEBUGFS_FWSTATS_ADD(debug, debug6); + + DEBUGFS_FWSTATS_ADD(ring, tx_procs); + DEBUGFS_FWSTATS_ADD(ring, prepared_descs); + DEBUGFS_FWSTATS_ADD(ring, tx_xfr); + DEBUGFS_FWSTATS_ADD(ring, tx_dma); + DEBUGFS_FWSTATS_ADD(ring, tx_cmplt); + DEBUGFS_FWSTATS_ADD(ring, rx_procs); + DEBUGFS_FWSTATS_ADD(ring, rx_data); + + DEBUGFS_FWSTATS_ADD(tx, tx_template_prepared); + DEBUGFS_FWSTATS_ADD(tx, tx_data_prepared); + DEBUGFS_FWSTATS_ADD(tx, tx_template_programmed); + DEBUGFS_FWSTATS_ADD(tx, tx_data_programmed); + DEBUGFS_FWSTATS_ADD(tx, tx_burst_programmed); + DEBUGFS_FWSTATS_ADD(tx, tx_starts); + DEBUGFS_FWSTATS_ADD(tx, tx_imm_resp); + DEBUGFS_FWSTATS_ADD(tx, tx_start_templates); + DEBUGFS_FWSTATS_ADD(tx, tx_start_int_templates); + DEBUGFS_FWSTATS_ADD(tx, tx_start_fw_gen); + DEBUGFS_FWSTATS_ADD(tx, tx_start_data); + DEBUGFS_FWSTATS_ADD(tx, tx_start_null_frame); + DEBUGFS_FWSTATS_ADD(tx, tx_exch); + DEBUGFS_FWSTATS_ADD(tx, tx_retry_template); + DEBUGFS_FWSTATS_ADD(tx, tx_retry_data); + DEBUGFS_FWSTATS_ADD(tx, tx_exch_pending); + DEBUGFS_FWSTATS_ADD(tx, tx_exch_expiry); + DEBUGFS_FWSTATS_ADD(tx, tx_exch_mismatch); + DEBUGFS_FWSTATS_ADD(tx, tx_done_template); + DEBUGFS_FWSTATS_ADD(tx, tx_done_data); + DEBUGFS_FWSTATS_ADD(tx, tx_done_int_template); + DEBUGFS_FWSTATS_ADD(tx, tx_pre_xfr); + DEBUGFS_FWSTATS_ADD(tx, tx_xfr); + DEBUGFS_FWSTATS_ADD(tx, tx_xfr_out_of_mem); + DEBUGFS_FWSTATS_ADD(tx, tx_dma_programmed); + DEBUGFS_FWSTATS_ADD(tx, tx_dma_done); + + DEBUGFS_FWSTATS_ADD(rx, rx_out_of_mem); + DEBUGFS_FWSTATS_ADD(rx, rx_hdr_overflow); + DEBUGFS_FWSTATS_ADD(rx, rx_hw_stuck); + DEBUGFS_FWSTATS_ADD(rx, rx_dropped_frame); + DEBUGFS_FWSTATS_ADD(rx, rx_complete_dropped_frame); + DEBUGFS_FWSTATS_ADD(rx, rx_alloc_frame); + DEBUGFS_FWSTATS_ADD(rx, rx_done_queue); + DEBUGFS_FWSTATS_ADD(rx, rx_done); + DEBUGFS_FWSTATS_ADD(rx, rx_defrag); + DEBUGFS_FWSTATS_ADD(rx, rx_defrag_end); + DEBUGFS_FWSTATS_ADD(rx, rx_mic); + DEBUGFS_FWSTATS_ADD(rx, rx_mic_end); + DEBUGFS_FWSTATS_ADD(rx, rx_xfr); + DEBUGFS_FWSTATS_ADD(rx, rx_xfr_end); + DEBUGFS_FWSTATS_ADD(rx, rx_cmplt); + DEBUGFS_FWSTATS_ADD(rx, rx_pre_complt); + DEBUGFS_FWSTATS_ADD(rx, rx_cmplt_task); + DEBUGFS_FWSTATS_ADD(rx, rx_phy_hdr); + DEBUGFS_FWSTATS_ADD(rx, rx_timeout); + + DEBUGFS_FWSTATS_ADD(dma, rx_dma_errors); + DEBUGFS_FWSTATS_ADD(dma, tx_dma_errors); + + DEBUGFS_FWSTATS_ADD(isr, irqs); + + DEBUGFS_FWSTATS_ADD(wep, wep_add_key_count); + DEBUGFS_FWSTATS_ADD(wep, wep_default_key_count); + DEBUGFS_FWSTATS_ADD(wep, wep_key_not_found); + DEBUGFS_FWSTATS_ADD(wep, wep_decrypt_fail); + DEBUGFS_FWSTATS_ADD(wep, wep_encrypt_fail); + DEBUGFS_FWSTATS_ADD(wep, wep_dec_packets); + DEBUGFS_FWSTATS_ADD(wep, wep_dec_interrupt); + DEBUGFS_FWSTATS_ADD(wep, wep_enc_packets); + DEBUGFS_FWSTATS_ADD(wep, wep_enc_interrupts); + + DEBUGFS_FWSTATS_ADD(pwr, missing_bcns_cnt); + DEBUGFS_FWSTATS_ADD(pwr, rcvd_bcns_cnt); + DEBUGFS_FWSTATS_ADD(pwr, connection_out_of_sync); + DEBUGFS_FWSTATS_ADD(pwr, cont_miss_bcns_spread); + DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_bcns_cnt); + + DEBUGFS_FWSTATS_ADD(mic, mic_rx_pkts); + DEBUGFS_FWSTATS_ADD(mic, mic_calc_failure); + + DEBUGFS_FWSTATS_ADD(aes, aes_encrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, aes_decrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, aes_encrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, aes_decrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, aes_encrypt_interrupt); + DEBUGFS_FWSTATS_ADD(aes, aes_decrypt_interrupt); + + DEBUGFS_FWSTATS_ADD(gem, gem_encrypt_fail); + DEBUGFS_FWSTATS_ADD(gem, gem_decrypt_fail); + DEBUGFS_FWSTATS_ADD(gem, gem_encrypt_packets); + DEBUGFS_FWSTATS_ADD(gem, gem_decrypt_packets); + DEBUGFS_FWSTATS_ADD(gem, gem_encrypt_interrupt); + DEBUGFS_FWSTATS_ADD(gem, gem_decrypt_interrupt); + + DEBUGFS_FWSTATS_ADD(event, calibration); + DEBUGFS_FWSTATS_ADD(event, rx_mismatch); + DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); + + DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_timeouts); + DEBUGFS_FWSTATS_ADD(ps_poll, upsd_timeouts); + DEBUGFS_FWSTATS_ADD(ps_poll, upsd_max_ap_turn); + DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_max_ap_turn); + DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_utilization); + DEBUGFS_FWSTATS_ADD(ps_poll, upsd_utilization); + + DEBUGFS_FWSTATS_ADD(rx_filter, beacon_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, arp_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, mc_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, dup_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, data_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, ibss_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, protection_filter); + + DEBUGFS_FWSTATS_ADD(calibration, init_cal_total); + DEBUGFS_FWSTATS_ADD(calibration, init_radio_bands_fail); + DEBUGFS_FWSTATS_ADD(calibration, init_set_params); + DEBUGFS_FWSTATS_ADD(calibration, init_tx_clpc_fail); + DEBUGFS_FWSTATS_ADD(calibration, init_rx_iw_mm_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_cal_total); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rtrim_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_pd_buf_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_tx_mix_freq_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_ta_cal); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rx_if_2_gain); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rx_dac); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_chan_tune); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rx_tx_lpf); + DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_lna_tank); + DEBUGFS_FWSTATS_ADD(calibration, tune_tx_lo_leak_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_tx_iq_mm_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_tx_pdet_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_tx_ppa_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_tx_clpc_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_rx_ana_dc_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_rx_dig_dc_fail); + DEBUGFS_FWSTATS_ADD(calibration, tune_rx_iq_mm_fail); + DEBUGFS_FWSTATS_ADD(calibration, cal_state_fail); + + return 0; + +err: + if (IS_ERR(entry)) + ret = PTR_ERR(entry); + else + ret = -ENOMEM; + + return ret; +} diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.h b/drivers/net/wireless/ti/wl18xx/debugfs.h new file mode 100644 index 000000000000..ed679bebf620 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/debugfs.h @@ -0,0 +1,28 @@ +/* + * This file is part of wl18xx + * + * Copyright (C) 2012 Texas Instruments. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL18XX_DEBUGFS_H__ +#define __WL18XX_DEBUGFS_H__ + +int wl18xx_debugfs_add_files(struct wl1271 *wl, + struct dentry *rootdir); + +#endif /* __WL18XX_DEBUGFS_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index afa2334d0aea..24673e37a1dd 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -38,7 +38,7 @@ #include "tx.h" #include "wl18xx.h" #include "io.h" - +#include "debugfs.h" #define WL18XX_RX_CHECKSUM_MASK 0x40 @@ -1011,6 +1011,11 @@ static void wl18xx_get_mac(struct wl1271 *wl) wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); } +static int wl18xx_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) +{ + return wl18xx_debugfs_add_files(wl, rootdir); +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -1031,6 +1036,7 @@ static struct wlcore_ops wl18xx_ops = { .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, .get_mac = wl18xx_get_mac, + .debugfs_init = wl18xx_debugfs_init, }; /* HT cap appropriate for wide channels */ @@ -1085,6 +1091,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); + wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); memcpy(&wl->ht_cap, &wl18xx_ht_cap, sizeof(wl18xx_ht_cap)); if (ht_mode_param && !strcmp(ht_mode_param, "mimo")) memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, -- GitLab From 7140df6e51ecca70e8963f18e9836e62090221c2 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:10 +0300 Subject: [PATCH 0574/6849] wlcore: create private static_data area and add operation to parse it The wl18xx firmware has more information in the static_data than wl12xx. To be able to parse that in an abstracted way, this patch adds a priv area to the static data struct and an operation that allows the lower driver to parse it if necessary. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/boot.c | 53 ++++++++++++++----------- drivers/net/wireless/ti/wlcore/boot.h | 1 + drivers/net/wireless/ti/wlcore/hw_ops.h | 9 +++++ drivers/net/wireless/ti/wlcore/wlcore.h | 6 +++ 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 9b98230f84ce..ed718f7ddcce 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -45,10 +45,17 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); } -static int wlcore_parse_fw_ver(struct wl1271 *wl) +static int wlcore_boot_parse_fw_ver(struct wl1271 *wl, + struct wl1271_static_data *static_data) { int ret; + strncpy(wl->chip.fw_ver_str, static_data->fw_version, + sizeof(wl->chip.fw_ver_str)); + + /* make sure the string is NULL-terminated */ + wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0'; + ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u", &wl->chip.fw_ver[0], &wl->chip.fw_ver[1], &wl->chip.fw_ver[2], &wl->chip.fw_ver[3], @@ -57,43 +64,43 @@ static int wlcore_parse_fw_ver(struct wl1271 *wl) if (ret != 5) { wl1271_warning("fw version incorrect value"); memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver)); - return -EINVAL; + ret = -EINVAL; + goto out; } ret = wlcore_identify_fw(wl); if (ret < 0) - return ret; - - return 0; + goto out; +out: + return ret; } -static int wlcore_boot_fw_version(struct wl1271 *wl) +static int wlcore_boot_static_data(struct wl1271 *wl) { struct wl1271_static_data *static_data; + size_t len = sizeof(*static_data) + wl->static_data_priv_len; int ret; - static_data = kmalloc(sizeof(*static_data), GFP_KERNEL | GFP_DMA); + static_data = kmalloc(len, GFP_KERNEL); if (!static_data) { - wl1271_error("Couldn't allocate memory for static data!"); - return -ENOMEM; + ret = -ENOMEM; + goto out; } - wl1271_read(wl, wl->cmd_box_addr, static_data, sizeof(*static_data), - false); + wl1271_read(wl, wl->cmd_box_addr, static_data, len, false); - strncpy(wl->chip.fw_ver_str, static_data->fw_version, - sizeof(wl->chip.fw_ver_str)); - - kfree(static_data); - - /* make sure the string is NULL-terminated */ - wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0'; + ret = wlcore_boot_parse_fw_ver(wl, static_data); + if (ret < 0) + goto out_free; - ret = wlcore_parse_fw_ver(wl); + ret = wlcore_handle_static_data(wl, static_data); if (ret < 0) - return ret; + goto out_free; - return 0; +out_free: + kfree(static_data); +out: + return ret; } static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, @@ -400,9 +407,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", wl->mbox_ptr[0], wl->mbox_ptr[1]); - ret = wlcore_boot_fw_version(wl); + ret = wlcore_boot_static_data(wl); if (ret < 0) { - wl1271_error("couldn't boot firmware"); + wl1271_error("error getting static data"); return ret; } diff --git a/drivers/net/wireless/ti/wlcore/boot.h b/drivers/net/wireless/ti/wlcore/boot.h index 094981dd2227..a525225f990c 100644 --- a/drivers/net/wireless/ti/wlcore/boot.h +++ b/drivers/net/wireless/ti/wlcore/boot.h @@ -40,6 +40,7 @@ struct wl1271_static_data { u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; u32 hw_version; u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; + u8 priv[0]; }; /* number of times we try to read the INIT interrupt */ diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 1555c3e12c1b..c590b6f529d1 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -158,4 +158,13 @@ wlcore_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) return 0; } +static inline int +wlcore_handle_static_data(struct wl1271 *wl, void *static_data) +{ + if (wl->ops->handle_static_data) + return wl->ops->handle_static_data(wl, static_data); + + return 0; +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 85fd3d9a5471..19678738a069 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -26,6 +26,7 @@ #include "wlcore_i.h" #include "event.h" +#include "boot.h" /* The maximum number of Tx descriptors in all chip families */ #define WLCORE_MAX_TX_DESCRIPTORS 32 @@ -72,6 +73,8 @@ struct wlcore_ops { u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl, struct wl12xx_vif *wlvif); int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); + int (*handle_static_data)(struct wl1271 *wl, + struct wl1271_static_data *static_data); }; enum wlcore_partitions { @@ -373,6 +376,9 @@ struct wl1271 { /* RX Data filter rule state - enabled/disabled */ bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; + /* size of the private static data */ + size_t static_data_priv_len; + /* the current channel type */ enum nl80211_channel_type channel_type; }; -- GitLab From 283e8c425f6eab2002457c27a5182869bb414771 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:11 +0300 Subject: [PATCH 0575/6849] wl18xx: print the PHY firmware version from the private static data The wl18xx firmware writes the PHY firmware version in the static data. Add an operation to parse the static data and print the PHY firmware version when booting. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 13 +++++++++++++ drivers/net/wireless/ti/wl18xx/wl18xx.h | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 24673e37a1dd..8262a4f7a10f 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1016,6 +1016,17 @@ static int wl18xx_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) return wl18xx_debugfs_add_files(wl, rootdir); } +static int wl18xx_handle_static_data(struct wl1271 *wl, + struct wl1271_static_data *static_data) +{ + struct wl18xx_static_data_priv *static_data_priv = + (struct wl18xx_static_data_priv *) static_data->priv; + + wl1271_info("PHY firmware version: %s", static_data_priv->phy_version); + + return 0; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -1037,6 +1048,7 @@ static struct wlcore_ops wl18xx_ops = { .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, .get_mac = wl18xx_get_mac, .debugfs_init = wl18xx_debugfs_init, + .handle_static_data = wl18xx_handle_static_data, }; /* HT cap appropriate for wide channels */ @@ -1092,6 +1104,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); + wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); memcpy(&wl->ht_cap, &wl18xx_ht_cap, sizeof(wl18xx_ht_cap)); if (ht_mode_param && !strcmp(ht_mode_param, "mimo")) memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index 75abb5b48c6e..34e202bc2bb3 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -56,6 +56,12 @@ struct wl18xx_fw_status_priv { u8 padding[2]; }; +#define WL18XX_PHY_VERSION_MAX_LEN 20 + +struct wl18xx_static_data_priv { + char phy_version[WL18XX_PHY_VERSION_MAX_LEN]; +}; + struct wl18xx_clk_cfg { u32 n; u32 m; -- GitLab From 06bba80e711b9b66e9316d4d228b55f768c27749 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:12 +0300 Subject: [PATCH 0576/6849] wlcore: print the interrupt status when recovery is triggered In some cases it may be useful for debugging to check what is the status of the interrupt register when a hardware recovery happens. Print the contents of REG_INTERRUPT_NO_CLEAR (aka. HINT_STS_RAW) when recovery starts. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 9589aa956bf7..00a482199a32 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -836,9 +836,11 @@ static void wl1271_recovery_work(struct work_struct *work) /* change partitions momentarily so we can read the FW pc */ wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", + wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x " + "hint_sts: 0x%08x", wl->chip.fw_ver_str, - wlcore_read_reg(wl, REG_PC_ON_RECOVERY)); + wlcore_read_reg(wl, REG_PC_ON_RECOVERY), + wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR)); wlcore_set_partition(wl, &wl->ptable[PART_WORK]); BUG_ON(bug_on_recovery && -- GitLab From 174a73034cdbe2bb2784c9963e75d196364c348e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:13 +0300 Subject: [PATCH 0577/6849] wl18xx: don't use MIMO when ht_mode is set to wide If the wl18xx module is loaded with ht_mode=wide (the default), we shouldn't use MIMO rates when the channel type is not HT40. Fix this by checking the ht_mode before deciding which rates to used. Additionally, set the ht_mode parameter explicitly to "wide" as the default. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 8262a4f7a10f..6a81edf702eb 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -42,7 +42,7 @@ #define WL18XX_RX_CHECKSUM_MASK 0x40 -static char *ht_mode_param; +static char *ht_mode_param = "wide"; static char *board_type_param = "hdk"; static bool dc2dc_param = false; static int n_antennas_2_param = 1; @@ -941,11 +941,12 @@ static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif) { - if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || - wlvif->channel_type == NL80211_CHAN_HT40PLUS) { + if ((wlvif->channel_type == NL80211_CHAN_HT40MINUS || + wlvif->channel_type == NL80211_CHAN_HT40PLUS) && + !strcmp(ht_mode_param, "wide")) { wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); return CONF_TX_RATE_USE_WIDE_CHAN; - } else { + } else if (!strcmp(ht_mode_param, "mimo")) { wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); /* @@ -959,6 +960,8 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, return CONF_TX_MIMO_RATES & ~CONF_HW_BIT_RATE_MCS_13; return CONF_TX_MIMO_RATES; + } else { + return 0; } } @@ -1106,7 +1109,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); memcpy(&wl->ht_cap, &wl18xx_ht_cap, sizeof(wl18xx_ht_cap)); - if (ht_mode_param && !strcmp(ht_mode_param, "mimo")) + if (!strcmp(ht_mode_param, "mimo")) memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, sizeof(wl18xx_mimo_ht_cap)); -- GitLab From 60462b4885450410df03cf3829367b285baf9ab8 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:14 +0300 Subject: [PATCH 0578/6849] wlcore: use proper values for supported local rates We were setting all the rates bits when starting the AP role. Instead of doing this, we should set only the rates we really support (eg. MIMO rates or wide-channel rates). This commit changes that so that we always use the default rates (basic rates + MCS0-7) and add the values returned by the ap_get_mimo_wide_rate_mask operation. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/cmd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 5c4756047098..5b14446ece4a 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -36,6 +36,7 @@ #include "cmd.h" #include "event.h" #include "tx.h" +#include "hw_ops.h" #define WL1271_CMD_FAST_POLL_COUNT 50 @@ -500,6 +501,7 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) struct wl12xx_cmd_role_start *cmd; struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + u32 supported_rates; int ret; wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); @@ -550,7 +552,13 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); } - cmd->ap.local_rates = cpu_to_le32(0xffffffff); + supported_rates = CONF_TX_AP_ENABLED_RATES | CONF_TX_MCS_RATES | + wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); + + wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x", + supported_rates); + + cmd->ap.local_rates = cpu_to_le32(supported_rates); switch (wlvif->band) { case IEEE80211_BAND_2GHZ: -- GitLab From 8334271882b46e4bc15337ed27428be121156165 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:15 +0300 Subject: [PATCH 0579/6849] wl18xx: add module parameter to force SISO 20MHz In some cases it may be useful to force narrow-band SISO channels. Add a new value to the ht_mode module parameter to force the device to operate in SISO 20MHz. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 38 ++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 6a81edf702eb..07955984face 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1055,7 +1055,7 @@ static struct wlcore_ops wl18xx_ops = { }; /* HT cap appropriate for wide channels */ -static struct ieee80211_sta_ht_cap wl18xx_ht_cap = { +static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = { .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, .ht_supported = true, @@ -1068,6 +1068,19 @@ static struct ieee80211_sta_ht_cap wl18xx_ht_cap = { }, }; +/* HT cap appropriate for SISO 20 */ +static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { + .cap = IEEE80211_HT_CAP_SGI_20, + .ht_supported = true, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .mcs = { + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(72), + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, +}; + /* HT cap appropriate for MIMO rates in 20mhz channel */ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap = { .cap = IEEE80211_HT_CAP_SGI_20, @@ -1108,10 +1121,20 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); - memcpy(&wl->ht_cap, &wl18xx_ht_cap, sizeof(wl18xx_ht_cap)); - if (!strcmp(ht_mode_param, "mimo")) + + if (!strcmp(ht_mode_param, "wide")) { + memcpy(&wl->ht_cap, &wl18xx_siso40_ht_cap, + sizeof(wl18xx_siso40_ht_cap)); + } else if (!strcmp(ht_mode_param, "mimo")) { memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, sizeof(wl18xx_mimo_ht_cap)); + } else if (!strcmp(ht_mode_param, "siso20")) { + memcpy(&wl->ht_cap, &wl18xx_siso20_ht_cap, + sizeof(wl18xx_siso20_ht_cap)); + } else { + wl1271_error("invalid ht_mode '%s'", ht_mode_param); + goto out_free; + } wl18xx_conf_init(wl); @@ -1131,8 +1154,7 @@ int __devinit wl18xx_probe(struct platform_device *pdev) priv->conf.phy.low_band_component_type = 0x06; } else { wl1271_error("invalid board type '%s'", board_type_param); - wlcore_free_hw(wl); - return -EINVAL; + goto out_free; } if (!checksum_param) { @@ -1143,6 +1165,10 @@ int __devinit wl18xx_probe(struct platform_device *pdev) wl->enable_11a = enable_11a_param; return wlcore_probe(wl, pdev); + +out_free: + wlcore_free_hw(wl); + return -EINVAL; } static const struct platform_device_id wl18xx_id_table[] __devinitconst = { @@ -1174,7 +1200,7 @@ static void __exit wl18xx_exit(void) module_exit(wl18xx_exit); module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); -MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or mimo"); +MODULE_PARM_DESC(ht_mode, "Force HT mode: wide (default), mimo or siso20"); module_param_named(board_type, board_type_param, charp, S_IRUSR); MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " -- GitLab From 5add82edd14d9bf051e06588ac65c7e2182bd330 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:16 +0300 Subject: [PATCH 0580/6849] wl18xx: add power limit reference value to mac_and_phy settings With more recent PHY firmware versions (>8.1.0.0.116), we need to use the correct value for the pwr_limit_reference_11_abg parameter when setting the mac_and_phy options. For now we use a hardcoded 0xc8 as the value. This will be moved to the configuration binary when it gets implemented. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/conf.h | 1 + drivers/net/wireless/ti/wl18xx/main.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index a6058fb86e7f..ffad302b6cb7 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -43,6 +43,7 @@ struct wl18xx_conf_phy { u8 primary_clock_setting_time; u8 clock_valid_on_wake_up; u8 secondary_clock_setting_time; + u8 pwr_limit_reference_11_abg; }; struct wl18xx_priv_conf { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 07955984face..ab3dd118f7de 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -501,6 +501,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .enable_clpc = 0x00, .enable_tx_low_pwr_on_siso_rdl = 0x00, .rx_profile = 0x00, + .pwr_limit_reference_11_abg = 0xc8, }, }; @@ -726,6 +727,8 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) phy->clock_valid_on_wake_up; params.secondary_clock_setting_time = phy->secondary_clock_setting_time; + params.pwr_limit_reference_11_abg = + phy->pwr_limit_reference_11_abg; params.board_type = priv->board_type; -- GitLab From 858403ab4434a3acd59eb892a49e1dbea30a2fcf Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:17 +0300 Subject: [PATCH 0581/6849] wl18xx: export low/high band component values as module params We use hardcoded values for the different board types. In some cases we may need to override the defaults, so export the values as module params. If not defined, the defaults for the specified board type will be used. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index ab3dd118f7de..6baeb26b79c8 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -49,6 +49,10 @@ static int n_antennas_2_param = 1; static int n_antennas_5_param = 1; static bool checksum_param = true; static bool enable_11a_param = true; +static int low_band_component = -1; +static int low_band_component_type = -1; +static int high_band_component = -1; +static int high_band_component_type = -1; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -1160,6 +1164,32 @@ int __devinit wl18xx_probe(struct platform_device *pdev) goto out_free; } + /* + * If the module param is not set, update it with the one from + * conf. If it is set, overwrite conf with it. + */ + if (low_band_component == -1) + low_band_component = priv->conf.phy.low_band_component; + else + priv->conf.phy.low_band_component = low_band_component; + if (low_band_component_type == -1) + low_band_component_type = + priv->conf.phy.low_band_component_type; + else + priv->conf.phy.low_band_component_type = + low_band_component_type; + + if (high_band_component == -1) + high_band_component = priv->conf.phy.high_band_component; + else + priv->conf.phy.high_band_component = high_band_component; + if (high_band_component_type == -1) + high_band_component_type = + priv->conf.phy.high_band_component_type; + else + priv->conf.phy.high_band_component_type = + high_band_component_type; + if (!checksum_param) { wl18xx_ops.set_rx_csum = NULL; wl18xx_ops.init_vif = NULL; @@ -1224,6 +1254,22 @@ MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to true)"); module_param_named(enable_11a, enable_11a_param, bool, S_IRUSR); MODULE_PARM_DESC(enable_11a, "Enable 11a (5GHz): boolean (defaults to true)"); +module_param(low_band_component, uint, S_IRUSR); +MODULE_PARM_DESC(low_band_component, "Low band component: u8 " + "(default is 0x01)"); + +module_param(low_band_component_type, uint, S_IRUSR); +MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " + "(default is 0x05 or 0x06 depending on the board_type)"); + +module_param(high_band_component, uint, S_IRUSR); +MODULE_PARM_DESC(high_band_component, "High band component: u8, " + "(default is 0x01)"); + +module_param(high_band_component_type, uint, S_IRUSR); +MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " + "(default is 0x09)"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From 7b03c306da4a5ae415036a16b1a5844ca42e2778 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:18 +0300 Subject: [PATCH 0582/6849] wl18xx: export pwr_limit_reference_11_abg value as a module parameter Yet another temporary module parameter requested by the firmware team. This will be replaced by the conf binary. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 6baeb26b79c8..524f44c4b991 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -53,6 +53,7 @@ static int low_band_component = -1; static int low_band_component_type = -1; static int high_band_component = -1; static int high_band_component_type = -1; +static int pwr_limit_reference_11_abg = -1; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -1190,6 +1191,13 @@ int __devinit wl18xx_probe(struct platform_device *pdev) priv->conf.phy.high_band_component_type = high_band_component_type; + if (pwr_limit_reference_11_abg == -1) + pwr_limit_reference_11_abg = + priv->conf.phy.pwr_limit_reference_11_abg; + else + priv->conf.phy.pwr_limit_reference_11_abg = + pwr_limit_reference_11_abg; + if (!checksum_param) { wl18xx_ops.set_rx_csum = NULL; wl18xx_ops.init_vif = NULL; @@ -1270,6 +1278,10 @@ module_param(high_band_component_type, uint, S_IRUSR); MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " "(default is 0x09)"); +module_param(pwr_limit_reference_11_abg, uint, S_IRUSR); +MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " + "(default is 0xc8)"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From ad62d81a9e5262555de0501329bd635f5886124f Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:19 +0300 Subject: [PATCH 0583/6849] wlcore/wl12xx/wl18xx: move lower driver debugfs to a subdir Instead of adding more files from the lower drivers into the same directory in debugfs as wlcore, we now add a subdirectory for the lower driver. This makes things a bit easier, because we can quickly see where the debugfs entry is implemented and what is specific to the lower driver. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl12xx/debugfs.c | 10 ++++++++-- drivers/net/wireless/ti/wl12xx/main.c | 7 +------ drivers/net/wireless/ti/wl18xx/debugfs.c | 10 ++++++++-- drivers/net/wireless/ti/wl18xx/main.c | 7 +------ 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/debugfs.c b/drivers/net/wireless/ti/wl12xx/debugfs.c index 311703d5af84..0521cbf858cf 100644 --- a/drivers/net/wireless/ti/wl12xx/debugfs.c +++ b/drivers/net/wireless/ti/wl12xx/debugfs.c @@ -126,9 +126,15 @@ int wl12xx_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { int ret = 0; - struct dentry *entry, *stats; + struct dentry *entry, *stats, *moddir; - stats = debugfs_create_dir("wl12xx_fw_stats", rootdir); + moddir = debugfs_create_dir(KBUILD_MODNAME, rootdir); + if (!moddir || IS_ERR(moddir)) { + entry = moddir; + goto err; + } + + stats = debugfs_create_dir("fw_stats", moddir); if (!stats || IS_ERR(stats)) { entry = stats; goto err; diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 2ac840783551..ba5afa46a430 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1360,11 +1360,6 @@ out: return ret; } -static int wl12xx_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) -{ - return wl12xx_debugfs_add_files(wl, rootdir); -} - static struct wlcore_ops wl12xx_ops = { .identify_chip = wl12xx_identify_chip, .identify_fw = wl12xx_identify_fw, @@ -1387,7 +1382,7 @@ static struct wlcore_ops wl12xx_ops = { .set_tx_desc_csum = wl12xx_set_tx_desc_csum, .set_rx_csum = NULL, .ap_get_mimo_wide_rate_mask = NULL, - .debugfs_init = wl12xx_debugfs_init, + .debugfs_init = wl12xx_debugfs_add_files, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c index 8354dfc64bd8..f4127bfb9642 100644 --- a/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -181,9 +181,15 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { int ret = 0; - struct dentry *entry, *stats; + struct dentry *entry, *stats, *moddir; - stats = debugfs_create_dir("wl18xx_fw_stats", rootdir); + moddir = debugfs_create_dir(KBUILD_MODNAME, rootdir); + if (!moddir || IS_ERR(moddir)) { + entry = moddir; + goto err; + } + + stats = debugfs_create_dir("fw_stats", moddir); if (!stats || IS_ERR(stats)) { entry = stats; goto err; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 524f44c4b991..27cd9b8a6e85 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1022,11 +1022,6 @@ static void wl18xx_get_mac(struct wl1271 *wl) wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); } -static int wl18xx_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) -{ - return wl18xx_debugfs_add_files(wl, rootdir); -} - static int wl18xx_handle_static_data(struct wl1271 *wl, struct wl1271_static_data *static_data) { @@ -1058,7 +1053,7 @@ static struct wlcore_ops wl18xx_ops = { .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, .get_mac = wl18xx_get_mac, - .debugfs_init = wl18xx_debugfs_init, + .debugfs_init = wl18xx_debugfs_add_files, .handle_static_data = wl18xx_handle_static_data, }; -- GitLab From 5a7589be344580f0ed186ab66819bf5671d3f145 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:20 +0300 Subject: [PATCH 0584/6849] wlcore: increase aggregation buffer size by one page With 4 pages (16Kb), we can't fit 10 frames in the aggregation buffer during iperf. This is the optimal for the firmware. Thus, increase the buffer size by one page. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/wlcore_i.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 45c07dc0df5d..83c9869105c3 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -89,7 +89,7 @@ #define WL1271_AP_BSS_INDEX 0 #define WL1271_AP_DEF_BEACON_EXP 20 -#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) +#define WL1271_AGGR_BUFFER_SIZE (5 * PAGE_SIZE) enum wl1271_state { WL1271_STATE_OFF, -- GitLab From 3507efa08417f416a8b8a64ab701ad5df37ae077 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:21 +0300 Subject: [PATCH 0585/6849] wl18xx: increase tx_ba_win_size to 64 Now the firmware can support TX block ack sessions with 64 frames. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 27cd9b8a6e85..5053c054aaad 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -408,7 +408,7 @@ static struct wlcore_conf wl18xx_conf = { }, .ht = { .rx_ba_win_size = 10, - .tx_ba_win_size = 10, + .tx_ba_win_size = 64, .inactivity_timeout = 10000, .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP, }, -- GitLab From c5d94169e8189d02dfbd6143411908357865d777 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 May 2012 12:14:22 +0300 Subject: [PATCH 0586/6849] wl18xx: use new fw stats structures Some of the structures were updated, other structures had a few missing values and a few new ones were added. Change the driver structs accordingly. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wl18xx/acx.h | 156 ++++++-------- drivers/net/wireless/ti/wl18xx/debugfs.c | 248 ++++++++++------------- 2 files changed, 169 insertions(+), 235 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index c2ccf70bcfb3..cb6fd85d077f 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -71,13 +71,8 @@ struct wl18xx_acx_debug_stats { } __packed; struct wl18xx_acx_ring_stats { - u32 tx_procs; u32 prepared_descs; - u32 tx_xfr; - u32 tx_dma; u32 tx_cmplt; - u32 rx_procs; - u32 rx_data; } __packed; struct wl18xx_acx_tx_stats { @@ -98,60 +93,53 @@ struct wl18xx_acx_tx_stats { u32 tx_retry_data; u32 tx_exch_pending; u32 tx_exch_expiry; - u32 tx_exch_mismatch; u32 tx_done_template; u32 tx_done_data; u32 tx_done_int_template; - u32 tx_pre_xfr; - u32 tx_xfr; - u32 tx_xfr_out_of_mem; - u32 tx_dma_programmed; - u32 tx_dma_done; + u32 tx_frame_checksum; + u32 tx_checksum_result; + u32 frag_called; + u32 frag_mpdu_alloc_failed; + u32 frag_init_called; + u32 frag_in_process_called; + u32 frag_tkip_called; + u32 frag_key_not_found; + u32 frag_need_fragmentation; + u32 frag_bad_mblk_num; + u32 frag_failed; + u32 frag_cache_hit; + u32 frag_cache_miss; } __packed; struct wl18xx_acx_rx_stats { u32 rx_out_of_mem; u32 rx_hdr_overflow; - u32 rx_hw_stuck; u32 rx_dropped_frame; - u32 rx_complete_dropped_frame; - u32 rx_alloc_frame; - u32 rx_done_queue; + u32 rx_done_stage; u32 rx_done; u32 rx_defrag; u32 rx_defrag_end; - u32 rx_mic; - u32 rx_mic_end; - u32 rx_xfr; - u32 rx_xfr_end; u32 rx_cmplt; u32 rx_pre_complt; u32 rx_cmplt_task; u32 rx_phy_hdr; u32 rx_timeout; -} __packed; - -struct wl18xx_acx_dma_stats { - u32 rx_dma_errors; - u32 tx_dma_errors; + u32 rx_frame_checksum; + u32 rx_checksum_result; + u32 defrag_called; + u32 defrag_init_called; + u32 defrag_in_process_called; + u32 defrag_tkip_called; + u32 defrag_need_defrag; + u32 defrag_decrypt_failed; + u32 decrypt_key_not_found; + u32 defrag_need_decrypt; } __packed; struct wl18xx_acx_isr_stats { u32 irqs; } __packed; -struct wl18xx_acx_wep_stats { - u32 wep_add_key_count; - u32 wep_default_key_count; - u32 wep_key_not_found; - u32 wep_decrypt_fail; - u32 wep_encrypt_fail; - u32 wep_dec_packets; - u32 wep_dec_interrupt; - u32 wep_enc_packets; - u32 wep_enc_interrupts; -} __packed; - #define PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD 10 struct wl18xx_acx_pwr_stats { @@ -162,29 +150,6 @@ struct wl18xx_acx_pwr_stats { u32 rcvd_awake_bcns_cnt; } __packed; -struct wl18xx_acx_mic_stats { - u32 mic_rx_pkts; - u32 mic_calc_failure; -} __packed; - -struct wl18xx_acx_aes_stats { - u32 aes_encrypt_fail; - u32 aes_decrypt_fail; - u32 aes_encrypt_packets; - u32 aes_decrypt_packets; - u32 aes_encrypt_interrupt; - u32 aes_decrypt_interrupt; -} __packed; - -struct wl18xx_acx_gem_stats { - u32 gem_encrypt_fail; - u32 gem_decrypt_fail; - u32 gem_encrypt_packets; - u32 gem_decrypt_packets; - u32 gem_encrypt_interrupt; - u32 gem_decrypt_interrupt; -} __packed; - struct wl18xx_acx_event_stats { u32 calibration; u32 rx_mismatch; @@ -210,31 +175,44 @@ struct wl18xx_acx_rx_filter_stats { u32 protection_filter; } __packed; -struct wl18xx_acx_calibration_stats { - u32 init_cal_total; - u32 init_radio_bands_fail; - u32 init_set_params; - u32 init_tx_clpc_fail; - u32 init_rx_iw_mm_fail; - u32 tune_cal_total; - u32 tune_drpw_rtrim_fail; - u32 tune_drpw_pd_buf_fail; - u32 tune_drpw_tx_mix_freq_fail; - u32 tune_drpw_ta_cal; - u32 tune_drpw_rx_if_2_gain; - u32 tune_drpw_rx_dac; - u32 tune_drpw_chan_tune; - u32 tune_drpw_rx_tx_lpf; - u32 tune_drpw_lna_tank; - u32 tune_tx_lo_leak_fail; - u32 tune_tx_iq_mm_fail; - u32 tune_tx_pdet_fail; - u32 tune_tx_ppa_fail; - u32 tune_tx_clpc_fail; - u32 tune_rx_ana_dc_fail; - u32 tune_rx_dig_dc_fail; /* check if this is needed */ - u32 tune_rx_iq_mm_fail; - u32 cal_state_fail; +struct wl18xx_acx_rx_rate_stats { + u32 rx_frames_per_rates[50]; +} __packed; + +#define AGGR_STATS_TX_SIZE_LEN 11 +#define AGGR_STATS_RX_SIZE_LEN 11 + +struct wl18xx_acx_aggr_stats { + u32 tx_size[AGGR_STATS_TX_SIZE_LEN]; + u32 rx_size[AGGR_STATS_RX_SIZE_LEN]; +} __packed; + +struct wl18xx_acx_pipeline_stats { + u32 hs_tx_stat_fifo_int; + u32 hs_rx_stat_fifo_int; + u32 tcp_tx_stat_fifo_int; + u32 tcp_rx_stat_fifo_int; + u32 enc_tx_stat_fifo_int; + u32 enc_rx_stat_fifo_int; + u32 rx_complete_stat_fifo_int; + u32 pre_proc_swi; + u32 post_proc_swi; + u32 sec_frag_swi; + u32 pre_to_defrag_swi; + u32 defrag_to_csum_swi; + u32 csum_to_rx_xfer_swi; + u32 dec_packet_in; + u32 dec_packet_in_fifo_full; + u32 dec_packet_out; + u32 cs_rx_packet_in; + u32 cs_rx_packet_out; +} __packed; + +struct wl18xx_acx_mem_stats { + u32 rx_free_mem_blks; + u32 tx_free_mem_blks; + u32 fwlog_free_mem_blks; + u32 fw_gen_free_mem_blks; } __packed; struct wl18xx_acx_statistics { @@ -244,17 +222,15 @@ struct wl18xx_acx_statistics { struct wl18xx_acx_debug_stats debug; struct wl18xx_acx_tx_stats tx; struct wl18xx_acx_rx_stats rx; - struct wl18xx_acx_dma_stats dma; struct wl18xx_acx_isr_stats isr; - struct wl18xx_acx_wep_stats wep; struct wl18xx_acx_pwr_stats pwr; - struct wl18xx_acx_aes_stats aes; - struct wl18xx_acx_mic_stats mic; struct wl18xx_acx_event_stats event; struct wl18xx_acx_ps_poll_stats ps_poll; struct wl18xx_acx_rx_filter_stats rx_filter; - struct wl18xx_acx_calibration_stats calibration; - struct wl18xx_acx_gem_stats gem; + struct wl18xx_acx_rx_rate_stats rx_rate; + struct wl18xx_acx_aggr_stats aggr_size; + struct wl18xx_acx_pipeline_stats pipeline; + struct wl18xx_acx_mem_stats mem; } __packed; int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c index f4127bfb9642..93c625b23a2f 100644 --- a/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -32,6 +32,7 @@ #define WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c) \ DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c, wl18xx_acx_statistics) + WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug1, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug2, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug3, "%u"); @@ -39,13 +40,8 @@ WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug4, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug5, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug6, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_procs, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(ring, prepared_descs, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_xfr, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_dma, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_cmplt, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, rx_procs, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, rx_data, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_prepared, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_prepared, "%u"); @@ -64,51 +60,47 @@ WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_template, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_data, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_pending, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_expiry, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_mismatch, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_template, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_data, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_int_template, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_pre_xfr, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_xfr, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_xfr_out_of_mem, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_dma_programmed, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_dma_done, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_frame_checksum, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_checksum_result, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_mpdu_alloc_failed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_init_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_in_process_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_tkip_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_key_not_found, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_need_fragmentation, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_bad_mblk_num, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_failed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_hit, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_miss, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_out_of_mem, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hdr_overflow, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hw_stuck, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_dropped_frame, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_complete_dropped_frame, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_alloc_frame, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done_queue, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag_end, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_mic, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_mic_end, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_xfr, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_xfr_end, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_pre_complt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt_task, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_phy_hdr, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout, "%u"); - -WL18XX_DEBUGFS_FWSTATS_FILE(dma, rx_dma_errors, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(dma, tx_dma_errors, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_frame_checksum, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_checksum_result, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_init_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_in_process_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_tkip_called, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_defrag, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_decrypt_failed, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, decrypt_key_not_found, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_decrypt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_add_key_count, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_default_key_count, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_key_not_found, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_decrypt_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_encrypt_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_dec_packets, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_dec_interrupt, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_enc_packets, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(wep, wep_enc_interrupts, "%u"); - WL18XX_DEBUGFS_FWSTATS_FILE(pwr, missing_bcns_cnt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_bcns_cnt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pwr, connection_out_of_sync, "%u"); @@ -116,22 +108,6 @@ WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pwr, cont_miss_bcns_spread, PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD); WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_bcns_cnt, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(mic, mic_rx_pkts, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(mic, mic_calc_failure, "%u"); - -WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_encrypt_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_decrypt_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_encrypt_packets, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_decrypt_packets, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_encrypt_interrupt, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(aes, aes_decrypt_interrupt, "%u"); - -WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_encrypt_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_decrypt_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_encrypt_packets, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_decrypt_packets, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_encrypt_interrupt, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(gem, gem_decrypt_interrupt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); @@ -152,30 +128,35 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, data_filter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, ibss_filter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, protection_filter, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_cal_total, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_radio_bands_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_set_params, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_tx_clpc_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, init_rx_iw_mm_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_cal_total, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rtrim_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_pd_buf_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_tx_mix_freq_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_ta_cal, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rx_if_2_gain, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rx_dac, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_chan_tune, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_rx_tx_lpf, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_drpw_lna_tank, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_lo_leak_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_iq_mm_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_pdet_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_ppa_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_tx_clpc_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_rx_ana_dc_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_rx_dig_dc_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, tune_rx_iq_mm_fail, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(calibration, cal_state_fail, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_rate, rx_frames_per_rates, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_size, + AGGR_STATS_TX_SIZE_LEN); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, rx_size, + AGGR_STATS_RX_SIZE_LEN); + +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, hs_tx_stat_fifo_int, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, tcp_tx_stat_fifo_int, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, tcp_rx_stat_fifo_int, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_tx_stat_fifo_int, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_rx_stat_fifo_int, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, rx_complete_stat_fifo_int, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_proc_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, post_proc_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, sec_frag_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_to_defrag_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, defrag_to_csum_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, csum_to_rx_xfer_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in_fifo_full, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_out, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_in, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_out, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(mem, rx_free_mem_blks, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(mem, tx_free_mem_blks, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(mem, fwlog_free_mem_blks, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(mem, fw_gen_free_mem_blks, "%u"); int wl18xx_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) @@ -202,13 +183,8 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(debug, debug5); DEBUGFS_FWSTATS_ADD(debug, debug6); - DEBUGFS_FWSTATS_ADD(ring, tx_procs); DEBUGFS_FWSTATS_ADD(ring, prepared_descs); - DEBUGFS_FWSTATS_ADD(ring, tx_xfr); - DEBUGFS_FWSTATS_ADD(ring, tx_dma); DEBUGFS_FWSTATS_ADD(ring, tx_cmplt); - DEBUGFS_FWSTATS_ADD(ring, rx_procs); - DEBUGFS_FWSTATS_ADD(ring, rx_data); DEBUGFS_FWSTATS_ADD(tx, tx_template_prepared); DEBUGFS_FWSTATS_ADD(tx, tx_data_prepared); @@ -227,74 +203,53 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(tx, tx_retry_data); DEBUGFS_FWSTATS_ADD(tx, tx_exch_pending); DEBUGFS_FWSTATS_ADD(tx, tx_exch_expiry); - DEBUGFS_FWSTATS_ADD(tx, tx_exch_mismatch); DEBUGFS_FWSTATS_ADD(tx, tx_done_template); DEBUGFS_FWSTATS_ADD(tx, tx_done_data); DEBUGFS_FWSTATS_ADD(tx, tx_done_int_template); - DEBUGFS_FWSTATS_ADD(tx, tx_pre_xfr); - DEBUGFS_FWSTATS_ADD(tx, tx_xfr); - DEBUGFS_FWSTATS_ADD(tx, tx_xfr_out_of_mem); - DEBUGFS_FWSTATS_ADD(tx, tx_dma_programmed); - DEBUGFS_FWSTATS_ADD(tx, tx_dma_done); + DEBUGFS_FWSTATS_ADD(tx, tx_frame_checksum); + DEBUGFS_FWSTATS_ADD(tx, tx_checksum_result); + DEBUGFS_FWSTATS_ADD(tx, frag_called); + DEBUGFS_FWSTATS_ADD(tx, frag_mpdu_alloc_failed); + DEBUGFS_FWSTATS_ADD(tx, frag_init_called); + DEBUGFS_FWSTATS_ADD(tx, frag_in_process_called); + DEBUGFS_FWSTATS_ADD(tx, frag_tkip_called); + DEBUGFS_FWSTATS_ADD(tx, frag_key_not_found); + DEBUGFS_FWSTATS_ADD(tx, frag_need_fragmentation); + DEBUGFS_FWSTATS_ADD(tx, frag_bad_mblk_num); + DEBUGFS_FWSTATS_ADD(tx, frag_failed); + DEBUGFS_FWSTATS_ADD(tx, frag_cache_hit); + DEBUGFS_FWSTATS_ADD(tx, frag_cache_miss); DEBUGFS_FWSTATS_ADD(rx, rx_out_of_mem); DEBUGFS_FWSTATS_ADD(rx, rx_hdr_overflow); - DEBUGFS_FWSTATS_ADD(rx, rx_hw_stuck); DEBUGFS_FWSTATS_ADD(rx, rx_dropped_frame); - DEBUGFS_FWSTATS_ADD(rx, rx_complete_dropped_frame); - DEBUGFS_FWSTATS_ADD(rx, rx_alloc_frame); - DEBUGFS_FWSTATS_ADD(rx, rx_done_queue); DEBUGFS_FWSTATS_ADD(rx, rx_done); DEBUGFS_FWSTATS_ADD(rx, rx_defrag); DEBUGFS_FWSTATS_ADD(rx, rx_defrag_end); - DEBUGFS_FWSTATS_ADD(rx, rx_mic); - DEBUGFS_FWSTATS_ADD(rx, rx_mic_end); - DEBUGFS_FWSTATS_ADD(rx, rx_xfr); - DEBUGFS_FWSTATS_ADD(rx, rx_xfr_end); DEBUGFS_FWSTATS_ADD(rx, rx_cmplt); DEBUGFS_FWSTATS_ADD(rx, rx_pre_complt); DEBUGFS_FWSTATS_ADD(rx, rx_cmplt_task); DEBUGFS_FWSTATS_ADD(rx, rx_phy_hdr); DEBUGFS_FWSTATS_ADD(rx, rx_timeout); - - DEBUGFS_FWSTATS_ADD(dma, rx_dma_errors); - DEBUGFS_FWSTATS_ADD(dma, tx_dma_errors); + DEBUGFS_FWSTATS_ADD(rx, rx_frame_checksum); + DEBUGFS_FWSTATS_ADD(rx, rx_checksum_result); + DEBUGFS_FWSTATS_ADD(rx, defrag_called); + DEBUGFS_FWSTATS_ADD(rx, defrag_init_called); + DEBUGFS_FWSTATS_ADD(rx, defrag_in_process_called); + DEBUGFS_FWSTATS_ADD(rx, defrag_tkip_called); + DEBUGFS_FWSTATS_ADD(rx, defrag_need_defrag); + DEBUGFS_FWSTATS_ADD(rx, defrag_decrypt_failed); + DEBUGFS_FWSTATS_ADD(rx, decrypt_key_not_found); + DEBUGFS_FWSTATS_ADD(rx, defrag_need_decrypt); DEBUGFS_FWSTATS_ADD(isr, irqs); - DEBUGFS_FWSTATS_ADD(wep, wep_add_key_count); - DEBUGFS_FWSTATS_ADD(wep, wep_default_key_count); - DEBUGFS_FWSTATS_ADD(wep, wep_key_not_found); - DEBUGFS_FWSTATS_ADD(wep, wep_decrypt_fail); - DEBUGFS_FWSTATS_ADD(wep, wep_encrypt_fail); - DEBUGFS_FWSTATS_ADD(wep, wep_dec_packets); - DEBUGFS_FWSTATS_ADD(wep, wep_dec_interrupt); - DEBUGFS_FWSTATS_ADD(wep, wep_enc_packets); - DEBUGFS_FWSTATS_ADD(wep, wep_enc_interrupts); - DEBUGFS_FWSTATS_ADD(pwr, missing_bcns_cnt); DEBUGFS_FWSTATS_ADD(pwr, rcvd_bcns_cnt); DEBUGFS_FWSTATS_ADD(pwr, connection_out_of_sync); DEBUGFS_FWSTATS_ADD(pwr, cont_miss_bcns_spread); DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_bcns_cnt); - DEBUGFS_FWSTATS_ADD(mic, mic_rx_pkts); - DEBUGFS_FWSTATS_ADD(mic, mic_calc_failure); - - DEBUGFS_FWSTATS_ADD(aes, aes_encrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, aes_decrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, aes_encrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, aes_decrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, aes_encrypt_interrupt); - DEBUGFS_FWSTATS_ADD(aes, aes_decrypt_interrupt); - - DEBUGFS_FWSTATS_ADD(gem, gem_encrypt_fail); - DEBUGFS_FWSTATS_ADD(gem, gem_decrypt_fail); - DEBUGFS_FWSTATS_ADD(gem, gem_encrypt_packets); - DEBUGFS_FWSTATS_ADD(gem, gem_decrypt_packets); - DEBUGFS_FWSTATS_ADD(gem, gem_encrypt_interrupt); - DEBUGFS_FWSTATS_ADD(gem, gem_decrypt_interrupt); - DEBUGFS_FWSTATS_ADD(event, calibration); DEBUGFS_FWSTATS_ADD(event, rx_mismatch); DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); @@ -314,30 +269,33 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx_filter, ibss_filter); DEBUGFS_FWSTATS_ADD(rx_filter, protection_filter); - DEBUGFS_FWSTATS_ADD(calibration, init_cal_total); - DEBUGFS_FWSTATS_ADD(calibration, init_radio_bands_fail); - DEBUGFS_FWSTATS_ADD(calibration, init_set_params); - DEBUGFS_FWSTATS_ADD(calibration, init_tx_clpc_fail); - DEBUGFS_FWSTATS_ADD(calibration, init_rx_iw_mm_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_cal_total); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rtrim_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_pd_buf_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_tx_mix_freq_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_ta_cal); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rx_if_2_gain); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rx_dac); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_chan_tune); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_rx_tx_lpf); - DEBUGFS_FWSTATS_ADD(calibration, tune_drpw_lna_tank); - DEBUGFS_FWSTATS_ADD(calibration, tune_tx_lo_leak_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_tx_iq_mm_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_tx_pdet_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_tx_ppa_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_tx_clpc_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_rx_ana_dc_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_rx_dig_dc_fail); - DEBUGFS_FWSTATS_ADD(calibration, tune_rx_iq_mm_fail); - DEBUGFS_FWSTATS_ADD(calibration, cal_state_fail); + DEBUGFS_FWSTATS_ADD(rx_rate, rx_frames_per_rates); + + DEBUGFS_FWSTATS_ADD(aggr_size, tx_size); + DEBUGFS_FWSTATS_ADD(aggr_size, rx_size); + + DEBUGFS_FWSTATS_ADD(pipeline, hs_tx_stat_fifo_int); + DEBUGFS_FWSTATS_ADD(pipeline, tcp_tx_stat_fifo_int); + DEBUGFS_FWSTATS_ADD(pipeline, tcp_rx_stat_fifo_int); + DEBUGFS_FWSTATS_ADD(pipeline, enc_tx_stat_fifo_int); + DEBUGFS_FWSTATS_ADD(pipeline, enc_rx_stat_fifo_int); + DEBUGFS_FWSTATS_ADD(pipeline, rx_complete_stat_fifo_int); + DEBUGFS_FWSTATS_ADD(pipeline, pre_proc_swi); + DEBUGFS_FWSTATS_ADD(pipeline, post_proc_swi); + DEBUGFS_FWSTATS_ADD(pipeline, sec_frag_swi); + DEBUGFS_FWSTATS_ADD(pipeline, pre_to_defrag_swi); + DEBUGFS_FWSTATS_ADD(pipeline, defrag_to_csum_swi); + DEBUGFS_FWSTATS_ADD(pipeline, csum_to_rx_xfer_swi); + DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in); + DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in_fifo_full); + DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_out); + DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_in); + DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_out); + + DEBUGFS_FWSTATS_ADD(mem, rx_free_mem_blks); + DEBUGFS_FWSTATS_ADD(mem, tx_free_mem_blks); + DEBUGFS_FWSTATS_ADD(mem, fwlog_free_mem_blks); + DEBUGFS_FWSTATS_ADD(mem, fw_gen_free_mem_blks); return 0; -- GitLab From 3d62eb5a7eb8d0be68442e119583508926731887 Mon Sep 17 00:00:00 2001 From: Assaf Azulay Date: Thu, 10 May 2012 12:14:23 +0300 Subject: [PATCH 0587/6849] wl18xx: change default tcp_checksum to false as tcp check sum is going to be removed from firmware, and as there is a problem with getting dns in security when checksum is enabled, it was decided to disable it by default. for none security modes it can be enabled by module paramenter. Signed-off-by: Assaf Azulay Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 5053c054aaad..dda9c18e5506 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -47,7 +47,7 @@ static char *board_type_param = "hdk"; static bool dc2dc_param = false; static int n_antennas_2_param = 1; static int n_antennas_5_param = 1; -static bool checksum_param = true; +static bool checksum_param = false; static bool enable_11a_param = true; static int low_band_component = -1; static int low_band_component_type = -1; @@ -1252,7 +1252,7 @@ module_param_named(n_antennas_5, n_antennas_5_param, uint, S_IRUSR); MODULE_PARM_DESC(n_antennas_5, "Number of installed 5GHz antennas: 1 (default) or 2"); module_param_named(checksum, checksum_param, bool, S_IRUSR); -MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to true)"); +MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); module_param_named(enable_11a, enable_11a_param, bool, S_IRUSR); MODULE_PARM_DESC(enable_11a, "Enable 11a (5GHz): boolean (defaults to true)"); -- GitLab From b5d6d9b28ca1fac178e05f185ee38e9c0770e268 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 5 Jun 2012 00:02:25 +0300 Subject: [PATCH 0588/6849] wlcore/wl12xx/wl18xx: don't use TX align quirk for wl127x Commit 4afc37 (wlcore: reorder identify_chip and get_hw_info) broke support for wl127x chips. When we moved the identify_chip operation to an earlier stage (ie. to the probe function), we broke wl127x support because during HW init we would set the WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN. To avoid this, set this quirk in the identify_chip operations and only force it to be unset if the bus module doesn't support it. We were doing the opposite and setting the flag if the bus module supports it. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 10 ++++------ drivers/net/wireless/ti/wl18xx/main.c | 5 +++-- drivers/net/wireless/ti/wlcore/main.c | 7 +++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index ba5afa46a430..67974f6c635a 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -625,9 +625,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", wl->chip.id); - /* clear the alignment quirk, since we don't support it */ - wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; - wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->mr_fw_name = WL127X_FW_NAME_MULTI; @@ -643,9 +640,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", wl->chip.id); - /* clear the alignment quirk, since we don't support it */ - wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; - wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; wl->plt_fw_name = WL127X_PLT_FW_NAME; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; @@ -664,6 +658,10 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->plt_fw_name = WL128X_PLT_FW_NAME; wl->sr_fw_name = WL128X_FW_NAME_SINGLE; wl->mr_fw_name = WL128X_FW_NAME_MULTI; + + /* wl128x requires TX blocksize alignment */ + wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; + break; case CHIP_ID_1283_PG10: default: diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index dda9c18e5506..2e9b3cb6e074 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -591,8 +591,9 @@ static int wl18xx_identify_chip(struct wl1271 *wl) /* wl18xx uses the same firmware for PLT */ wl->plt_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | - WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | - WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; + WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | + WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | + WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; /* PG 1.0 has some problems with MCS_13, so disable it */ wl->ht_cap.mcs.rx_mask[1] &= ~BIT(5); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 00a482199a32..af00dabf96b7 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -960,9 +960,12 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) * simplify the code and since the performance impact is * negligible, we use the same block size for all different * chip types. + * + * Check if the bus supports blocksize alignment and, if it + * doesn't, make sure we don't have the quirk. */ - if (wl1271_set_block_size(wl)) - wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; + if (!wl1271_set_block_size(wl)) + wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; /* TODO: make sure the lower driver has set things up correctly */ -- GitLab From 92eca8faad2d1b136c939bc122842dcdabd6ff46 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Sun, 20 May 2012 13:13:28 +0900 Subject: [PATCH 0589/6849] KVM: Separate out dirty_bitmap allocation code as kvm_kvzalloc() Will be used for lpage_info allocation later. Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- virt/kvm/kvm_main.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7e140683ff14..1148c96a4817 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -516,16 +516,32 @@ out_err_nodisable: return ERR_PTR(r); } +/* + * Avoid using vmalloc for a small buffer. + * Should not be used when the size is statically known. + */ +static void *kvm_kvzalloc(unsigned long size) +{ + if (size > PAGE_SIZE) + return vzalloc(size); + else + return kzalloc(size, GFP_KERNEL); +} + +static void kvm_kvfree(const void *addr) +{ + if (is_vmalloc_addr(addr)) + vfree(addr); + else + kfree(addr); +} + static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) { if (!memslot->dirty_bitmap) return; - if (2 * kvm_dirty_bitmap_bytes(memslot) > PAGE_SIZE) - vfree(memslot->dirty_bitmap); - else - kfree(memslot->dirty_bitmap); - + kvm_kvfree(memslot->dirty_bitmap); memslot->dirty_bitmap = NULL; } @@ -617,11 +633,7 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) #ifndef CONFIG_S390 unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot); - if (dirty_bytes > PAGE_SIZE) - memslot->dirty_bitmap = vzalloc(dirty_bytes); - else - memslot->dirty_bitmap = kzalloc(dirty_bytes, GFP_KERNEL); - + memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes); if (!memslot->dirty_bitmap) return -ENOMEM; -- GitLab From c1a7b32a14138f908df52d7c53b5ce3415ec6b50 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Sun, 20 May 2012 13:15:07 +0900 Subject: [PATCH 0590/6849] KVM: Avoid wasting pages for small lpage_info arrays lpage_info is created for each large level even when the memory slot is not for RAM. This means that when we add one slot for a PCI device, we end up allocating at least KVM_NR_PAGE_SIZES - 1 pages by vmalloc(). To make things worse, there is an increasing number of devices which would result in more pages being wasted this way. This patch mitigates this problem by using kvm_kvzalloc(). Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 ++-- include/linux/kvm_host.h | 3 +++ virt/kvm/kvm_main.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index be6d54929fa7..f12a52408cda 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6304,7 +6304,7 @@ void kvm_arch_free_memslot(struct kvm_memory_slot *free, for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) { - vfree(free->arch.lpage_info[i]); + kvm_kvfree(free->arch.lpage_info[i]); free->arch.lpage_info[i] = NULL; } } @@ -6323,7 +6323,7 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) slot->base_gfn, level) + 1; slot->arch.lpage_info[i] = - vzalloc(lpages * sizeof(*slot->arch.lpage_info[i])); + kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i])); if (!slot->arch.lpage_info[i]) goto out_free; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index c4464356b35b..19b83f6efa49 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -535,6 +535,9 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); void kvm_free_physmem(struct kvm *kvm); +void *kvm_kvzalloc(unsigned long size); +void kvm_kvfree(const void *addr); + #ifndef __KVM_HAVE_ARCH_VM_ALLOC static inline struct kvm *kvm_arch_alloc_vm(void) { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 1148c96a4817..02cb440f802d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -520,7 +520,7 @@ out_err_nodisable: * Avoid using vmalloc for a small buffer. * Should not be used when the size is statically known. */ -static void *kvm_kvzalloc(unsigned long size) +void *kvm_kvzalloc(unsigned long size) { if (size > PAGE_SIZE) return vzalloc(size); @@ -528,7 +528,7 @@ static void *kvm_kvzalloc(unsigned long size) return kzalloc(size, GFP_KERNEL); } -static void kvm_kvfree(const void *addr) +void kvm_kvfree(const void *addr) { if (is_vmalloc_addr(addr)) vfree(addr); -- GitLab From aaf07bc291c828189ae5221b370905a89bbb859d Mon Sep 17 00:00:00 2001 From: Xudong Hao Date: Mon, 28 May 2012 19:33:34 +0800 Subject: [PATCH 0591/6849] KVM: VMX: Add EPT A/D bits definitions Signed-off-by: Haitao Shan Signed-off-by: Xudong Hao Signed-off-by: Avi Kivity --- arch/x86/include/asm/vmx.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 31f180c21ce9..de007c272730 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -404,6 +404,7 @@ enum vmcs_field { #define VMX_EPTP_WB_BIT (1ull << 14) #define VMX_EPT_2MB_PAGE_BIT (1ull << 16) #define VMX_EPT_1GB_PAGE_BIT (1ull << 17) +#define VMX_EPT_AD_BIT (1ull << 21) #define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) @@ -415,11 +416,14 @@ enum vmcs_field { #define VMX_EPT_MAX_GAW 0x4 #define VMX_EPT_MT_EPTE_SHIFT 3 #define VMX_EPT_GAW_EPTP_SHIFT 3 +#define VMX_EPT_AD_ENABLE_BIT (1ull << 6) #define VMX_EPT_DEFAULT_MT 0x6ull #define VMX_EPT_READABLE_MASK 0x1ull #define VMX_EPT_WRITABLE_MASK 0x2ull #define VMX_EPT_EXECUTABLE_MASK 0x4ull #define VMX_EPT_IPAT_BIT (1ull << 6) +#define VMX_EPT_ACCESS_BIT (1ull << 8) +#define VMX_EPT_DIRTY_BIT (1ull << 9) #define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul -- GitLab From 83c3a3312235220476d3c207f67bd17be6e17ff9 Mon Sep 17 00:00:00 2001 From: Xudong Hao Date: Mon, 28 May 2012 19:33:35 +0800 Subject: [PATCH 0592/6849] KVM: VMX: Add parameter to control A/D bits support, default is on Add kernel parameter to control A/D bits support, it's on by default. Signed-off-by: Haitao Shan Signed-off-by: Xudong Hao Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 32eb58866292..18590e003bd2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -71,6 +71,9 @@ static bool __read_mostly enable_unrestricted_guest = 1; module_param_named(unrestricted_guest, enable_unrestricted_guest, bool, S_IRUGO); +static bool __read_mostly enable_ept_ad_bits = 1; +module_param_named(eptad, enable_ept_ad_bits, bool, S_IRUGO); + static bool __read_mostly emulate_invalid_guest_state = 0; module_param(emulate_invalid_guest_state, bool, S_IRUGO); @@ -789,6 +792,11 @@ static inline bool cpu_has_vmx_ept_4levels(void) return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT; } +static inline bool cpu_has_vmx_ept_ad_bits(void) +{ + return vmx_capability.ept & VMX_EPT_AD_BIT; +} + static inline bool cpu_has_vmx_invept_individual_addr(void) { return vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT; @@ -2645,8 +2653,12 @@ static __init int hardware_setup(void) !cpu_has_vmx_ept_4levels()) { enable_ept = 0; enable_unrestricted_guest = 0; + enable_ept_ad_bits = 0; } + if (!cpu_has_vmx_ept_ad_bits()) + enable_ept_ad_bits = 0; + if (!cpu_has_vmx_unrestricted_guest()) enable_unrestricted_guest = 0; -- GitLab From b38f99347871d7fc49e6367395dce0d757f6ab8d Mon Sep 17 00:00:00 2001 From: Xudong Hao Date: Mon, 28 May 2012 19:33:36 +0800 Subject: [PATCH 0593/6849] KVM: VMX: Enable EPT A/D bits if supported by turning on relevant bit in EPTP In EPT page structure entry, Enable EPT A/D bits if processor supported. Signed-off-by: Haitao Shan Signed-off-by: Xudong Hao Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 18590e003bd2..d392e5427ca0 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3039,6 +3039,8 @@ static u64 construct_eptp(unsigned long root_hpa) /* TODO write the value reading from MSR */ eptp = VMX_EPT_DEFAULT_MT | VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT; + if (enable_ept_ad_bits) + eptp |= VMX_EPT_AD_ENABLE_BIT; eptp |= (root_hpa & PAGE_MASK); return eptp; -- GitLab From 3f6d8c8a478dd1ab2a4944b0d65474df06ecd882 Mon Sep 17 00:00:00 2001 From: Xudong Hao Date: Tue, 22 May 2012 11:23:15 +0800 Subject: [PATCH 0594/6849] KVM: VMX: Use EPT Access bit in response to memory notifiers Signed-off-by: Haitao Shan Signed-off-by: Xudong Hao Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 14 ++++++++------ arch/x86/kvm/vmx.c | 6 ++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index be3cea4407ff..d07e436b7a42 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1242,7 +1242,8 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, int young = 0; /* - * Emulate the accessed bit for EPT, by checking if this page has + * In case of absence of EPT Access and Dirty Bits supports, + * emulate the accessed bit for EPT, by checking if this page has * an EPT mapping, and clearing it if it does. On the next access, * a new EPT mapping will be established. * This has some overhead, but not as much as the cost of swapping @@ -1253,11 +1254,12 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, for (sptep = rmap_get_first(*rmapp, &iter); sptep; sptep = rmap_get_next(&iter)) { - BUG_ON(!(*sptep & PT_PRESENT_MASK)); + BUG_ON(!is_shadow_present_pte(*sptep)); - if (*sptep & PT_ACCESSED_MASK) { + if (*sptep & shadow_accessed_mask) { young = 1; - clear_bit(PT_ACCESSED_SHIFT, (unsigned long *)sptep); + clear_bit((ffs(shadow_accessed_mask) - 1), + (unsigned long *)sptep); } } @@ -1281,9 +1283,9 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, for (sptep = rmap_get_first(*rmapp, &iter); sptep; sptep = rmap_get_next(&iter)) { - BUG_ON(!(*sptep & PT_PRESENT_MASK)); + BUG_ON(!is_shadow_present_pte(*sptep)); - if (*sptep & PT_ACCESSED_MASK) { + if (*sptep & shadow_accessed_mask) { young = 1; break; } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d392e5427ca0..396148ab089b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -7289,8 +7289,10 @@ static int __init vmx_init(void) vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); if (enable_ept) { - kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, - VMX_EPT_EXECUTABLE_MASK); + kvm_mmu_set_mask_ptes(0ull, + (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull, + (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull, + 0ull, VMX_EPT_EXECUTABLE_MASK); ept_set_mmio_spte_mask(); kvm_enable_tdp(); } else -- GitLab From a6bb7929677aacfce3f864c3cdacaa7d527945d5 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 17 May 2012 13:14:08 +0300 Subject: [PATCH 0595/6849] KVM: ia64: Mark ia64 KVM as BROKEN Practically all patches to ia64 KVM are build fixes; numerous warnings remain; the last patch from the maintainer was committed more than three years ago. It is clear that no one is using this thing. Mark as BROKEN to ensure people don't get hit by pointless build problems. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/ia64/kvm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 9806e55f91be..df5351e3eed7 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig @@ -19,6 +19,7 @@ if VIRTUALIZATION config KVM tristate "Kernel-based Virtual Machine (KVM) support" + depends on BROKEN depends on HAVE_KVM && MODULES && EXPERIMENTAL # for device assignment: depends on PCI -- GitLab From bfd6185ddecc6e6f6bd654c053c307c9e49ca391 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 14:29:36 +0100 Subject: [PATCH 0596/6849] regmap: Don't try to map non-existant IRQs If the driver supplied an empty entry in the array of IRQs then return an error rather than trying to do the mapping. This is intended for use with handling chip variants and similar situations. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-irq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 4fac4b9be88f..b74e14c4dff4 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -346,6 +346,10 @@ EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); */ int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) { + /* Handle holes in the IRQ list */ + if (!data->chip->irqs[irq].mask) + return -EINVAL; + return irq_create_mapping(data->domain, irq); } EXPORT_SYMBOL_GPL(regmap_irq_get_virq); -- GitLab From a43fd50dc99a5f65505f174eca5a421707d73b4c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 14:34:03 +0100 Subject: [PATCH 0597/6849] regmap: Implement support for wake IRQs Allow chips to provide a bank of registers for controlling the wake state in a similar fashion to the masks and propagate the wake count to the parent interrupt controller. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-irq.c | 47 ++++++++++++++++++++++++++++++++ include/linux/regmap.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index b74e14c4dff4..b480b529f020 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -29,9 +29,13 @@ struct regmap_irq_chip_data { int irq_base; struct irq_domain *domain; + int irq; + int wake_count; + unsigned int *status_buf; unsigned int *mask_buf; unsigned int *mask_buf_def; + unsigned int *wake_buf; unsigned int irq_reg_stride; }; @@ -71,6 +75,16 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->chip->mask_base + (i * map->reg_stride)); } + /* If we've changed our wakeup count propagate it to the parent */ + if (d->wake_count < 0) + for (i = d->wake_count; i < 0; i++) + irq_set_irq_wake(d->irq, 0); + else if (d->wake_count > 0) + for (i = 0; i < d->wake_count; i++) + irq_set_irq_wake(d->irq, 1); + + d->wake_count = 0; + mutex_unlock(&d->lock); } @@ -92,12 +106,35 @@ static void regmap_irq_disable(struct irq_data *data) d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; } +static int regmap_irq_set_wake(struct irq_data *data, unsigned int on) +{ + struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); + struct regmap *map = d->map; + const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); + + if (!d->chip->wake_base) + return -EINVAL; + + if (on) { + d->wake_buf[irq_data->reg_offset / map->reg_stride] + &= ~irq_data->mask; + d->wake_count++; + } else { + d->wake_buf[irq_data->reg_offset / map->reg_stride] + |= irq_data->mask; + d->wake_count--; + } + + return 0; +} + static struct irq_chip regmap_irq_chip = { .name = "regmap", .irq_bus_lock = regmap_irq_lock, .irq_bus_sync_unlock = regmap_irq_sync_unlock, .irq_disable = regmap_irq_disable, .irq_enable = regmap_irq_enable, + .irq_set_wake = regmap_irq_set_wake, }; static irqreturn_t regmap_irq_thread(int irq, void *d) @@ -240,6 +277,14 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, if (!d->mask_buf_def) goto err_alloc; + if (chip->wake_base) { + d->wake_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, + GFP_KERNEL); + if (!d->wake_buf) + goto err_alloc; + } + + d->irq = irq; d->map = map; d->chip = chip; d->irq_base = irq_base; @@ -294,6 +339,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, err_domain: /* Should really dispose of the domain but... */ err_alloc: + kfree(d->wake_buf); kfree(d->mask_buf_def); kfree(d->mask_buf); kfree(d->status_buf); @@ -315,6 +361,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) free_irq(irq, d); /* We should unmap the domain but... */ + kfree(d->wake_buf); kfree(d->mask_buf_def); kfree(d->mask_buf); kfree(d->status_buf); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 56af22ec9aba..58ec0cba0ae6 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -219,6 +219,7 @@ struct regmap_irq { * @status_base: Base status register address. * @mask_base: Base mask register address. * @ack_base: Base ack address. If zero then the chip is clear on read. + * @wake_base: Base address for wake enables. If zero unsupported. * @irq_reg_stride: Stride to use for chips where registers are not contiguous. * * @num_regs: Number of registers in each control bank. @@ -232,6 +233,7 @@ struct regmap_irq_chip { unsigned int status_base; unsigned int mask_base; unsigned int ack_base; + unsigned int wake_base; unsigned int irq_reg_stride; int num_regs; -- GitLab From d35dc739f6a0b3680a591bd4e831fd3afa912632 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 15 May 2012 17:08:51 +0300 Subject: [PATCH 0598/6849] wlcore: fix sparse warnings related to static functions The "static" modifier was mistakenly forgotten for some functions. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 2e9b3cb6e074..31cd4cc3c1b2 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1098,7 +1098,7 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap = { }, }; -int __devinit wl18xx_probe(struct platform_device *pdev) +static int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; struct ieee80211_hw *hw; -- GitLab From 1ab0f212629462ae2600bb3523dc75b96e8544eb Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 17:08:52 +0300 Subject: [PATCH 0599/6849] wlcore: use the original elp time in forced_ps mode The dynamic PS timeout is meaningless in forced PS mode. Signed-off-by: Eliad Peller Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/ps.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c index 756eee2257b4..958535dee9f3 100644 --- a/drivers/net/wireless/ti/wlcore/ps.c +++ b/drivers/net/wireless/ti/wlcore/ps.c @@ -28,6 +28,8 @@ #define WL1271_WAKEUP_TIMEOUT 500 +#define ELP_ENTRY_DELAY 5 + void wl1271_elp_work(struct work_struct *work) { struct delayed_work *dwork; @@ -72,6 +74,7 @@ out: void wl1271_ps_elp_sleep(struct wl1271 *wl) { struct wl12xx_vif *wlvif; + u32 timeout; if (wl->quirks & WLCORE_QUIRK_NO_ELP) return; @@ -89,8 +92,13 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) return; } + if (wl->conf.conn.forced_ps) + timeout = ELP_ENTRY_DELAY; + else + timeout = wl->conf.conn.dynamic_ps_timeout; + ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, - msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout)); + msecs_to_jiffies(timeout)); } int wl1271_ps_elp_wakeup(struct wl1271 *wl) -- GitLab From 6e066921b3970232d5faadcdf33a92f43ec84334 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 15 May 2012 17:08:53 +0300 Subject: [PATCH 0600/6849] wlcore: fix dynamic_ps_timeout time regression In patch d7b63b9fc7ee73e75a4c7fdb899 we have raised the dynamic PS timeout to 200ms to improve user experience. Re-apply the change, since it was reverted in the wlcore split. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 2 +- drivers/net/wireless/ti/wl18xx/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 67974f6c635a..ba14acae1d59 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -238,7 +238,7 @@ static struct wlcore_conf wl12xx_conf = { .psm_entry_retries = 8, .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, - .dynamic_ps_timeout = 40, + .dynamic_ps_timeout = 200, .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 31cd4cc3c1b2..bbd935fb5f64 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -361,7 +361,7 @@ static struct wlcore_conf wl18xx_conf = { .psm_entry_retries = 8, .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, - .dynamic_ps_timeout = 40, + .dynamic_ps_timeout = 200, .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, -- GitLab From 6b8bf5bc5e99f52334bec1b06b14d28dc595c95a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 15 May 2012 17:08:54 +0300 Subject: [PATCH 0601/6849] wlcore: fixes for connection_loss_work We can't use cancel_delayed_work_sync() from functions that take the wl->mutex, since connection_loss_work also takes the mutex. This might result in a deadlock. Restructure the code so the work is synchronously canceled before taking the mutex. Avoid a bug where we would indefinitely delay the connection loss indication by re-queuing the connection loss work on consecutive beacon loss events. Cc: bartosz.markowski Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/event.c | 15 ++++++++++++--- drivers/net/wireless/ti/wlcore/main.c | 10 +++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 28e2a633c3be..4ed835799178 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -148,15 +148,24 @@ static int wl1271_event_process(struct wl1271 *wl) int delay = wl->conf.conn.synch_fail_thold * wl->conf.conn.bss_lose_timeout; wl1271_info("Beacon loss detected."); - cancel_delayed_work_sync(&wl->connection_loss_work); + + /* + * if the work is already queued, it should take place. We + * don't want to delay the connection loss indication + * any more. + */ ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work, - msecs_to_jiffies(delay)); + msecs_to_jiffies(delay)); } if (vector & REGAINED_BSS_EVENT_ID) { /* TODO: check for multi-role */ wl1271_info("Beacon regained."); - cancel_delayed_work_sync(&wl->connection_loss_work); + cancel_delayed_work(&wl->connection_loss_work); + + /* sanity check - we can't lose and gain the beacon together */ + WARN(vector & BSS_LOSE_EVENT_ID, + "Concurrent beacon loss and gain from FW"); } if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index af00dabf96b7..4be62c93808b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -3712,9 +3712,6 @@ sta_not_found: do_join = true; set_assoc = true; - /* Cancel connection_loss_work */ - cancel_delayed_work_sync(&wl->connection_loss_work); - /* * use basic rates from AP, and determine lowest rate * to use with control frames. @@ -3964,6 +3961,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", (int)changed); + /* + * make sure to cancel pending disconnections if our association + * state changed + */ + if (!is_ap && (changed & BSS_CHANGED_ASSOC)) + cancel_delayed_work_sync(&wl->connection_loss_work); + mutex_lock(&wl->mutex); if (unlikely(wl->state == WL1271_STATE_OFF)) -- GitLab From 45b60f7ddd05e38a6835fb93e8dbcc6ef9bf12fa Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 17:08:55 +0300 Subject: [PATCH 0602/6849] wlcore: use correct link for bcast/multicast frames Multicast management frames (e.g. global deauth) should be sent out on the bcast link, rather than the global, which should be used only for pre-added stations (e.g. for auth/assoc resp). Signed-off-by: Eliad Peller Signed-off-by: Eyal Shapira Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/tx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 200d091db6f9..e8a2998408b6 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -148,10 +148,10 @@ u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, return wl->system_hlid; hdr = (struct ieee80211_hdr *)skb->data; - if (ieee80211_is_mgmt(hdr->frame_control)) - return wlvif->ap.global_hlid; - else + if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) return wlvif->ap.bcast_hlid; + else + return wlvif->ap.global_hlid; } } -- GitLab From b515d83a2998c991171e2c533ea06ff723d355a6 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 17:08:56 +0300 Subject: [PATCH 0603/6849] wlcore: flush before stopping AP Make sure the deauth bcast gets sent [Make sure we are AP as well before the flush - Arik] Signed-off-by: Eliad Peller Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 4be62c93808b..1974be0ccd58 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -3968,6 +3968,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (!is_ap && (changed & BSS_CHANGED_ASSOC)) cancel_delayed_work_sync(&wl->connection_loss_work); + if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) && + !bss_conf->enable_beacon) + wl1271_tx_flush(wl); + mutex_lock(&wl->mutex); if (unlikely(wl->state == WL1271_STATE_OFF)) -- GitLab From 7b052214e59450b5ed6c708903a7dd9f15f6c12d Mon Sep 17 00:00:00 2001 From: Igal Chernobelsky Date: Tue, 15 May 2012 17:08:57 +0300 Subject: [PATCH 0604/6849] wlcore: modify bss loss parameters Modify default parameters to reduce firmware BSS lose probability in congested environment. [Applied to 18xx configuration as well - Arik] Signed-off-by: Igal Chernobelsky Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 4 ++-- drivers/net/wireless/ti/wl18xx/main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index ba14acae1d59..e400d1987e6c 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -227,8 +227,8 @@ static struct wlcore_conf wl12xx_conf = { .rule = CONF_BCN_RULE_PASS_ON_CHANGE, }, }, - .synch_fail_thold = 10, - .bss_lose_timeout = 100, + .synch_fail_thold = 12, + .bss_lose_timeout = 400, .beacon_rx_timeout = 10000, .broadcast_timeout = 20000, .rx_broadcast_in_ps = 1, diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index bbd935fb5f64..5a6c4cc9577e 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -350,8 +350,8 @@ static struct wlcore_conf wl18xx_conf = { .rule = CONF_BCN_RULE_PASS_ON_CHANGE, }, }, - .synch_fail_thold = 10, - .bss_lose_timeout = 100, + .synch_fail_thold = 12, + .bss_lose_timeout = 400, .beacon_rx_timeout = 10000, .broadcast_timeout = 20000, .rx_broadcast_in_ps = 1, -- GitLab From 0a15d9b5896f54f4ad164fd072891019a8a8cfb2 Mon Sep 17 00:00:00 2001 From: Assaf Azulay Date: Tue, 15 May 2012 17:08:58 +0300 Subject: [PATCH 0605/6849] wlcore: increase number of BA sessions to 3 With the new FW (sigle role X.3.8.0.108, multi role X.5.4.0.21) we are supporting 3 RX BA sessions, this change is to support this new ability. Signed-off-by: Assaf Azulay Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/acx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 8b3807b879d3..46c300d4dea4 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -726,7 +726,7 @@ struct wl1271_acx_ht_information { u8 padding[2]; } __packed; -#define RX_BA_MAX_SESSIONS 2 +#define RX_BA_MAX_SESSIONS 3 struct wl1271_acx_ba_initiator_policy { struct acx_header header; -- GitLab From a121a5b8aba4294b1557e1099c4eaa7c6578d7ce Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 15 May 2012 17:08:59 +0300 Subject: [PATCH 0606/6849] wl18xx: add dependency on mac80211 Add a dependency on mac80211 in Kconfig, and also replace some spaces with tabs. Reported-by: Arend van Spriel Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/Kconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/Kconfig b/drivers/net/wireless/ti/wl18xx/Kconfig index 1451d1f377c9..1cfdb2548821 100644 --- a/drivers/net/wireless/ti/wl18xx/Kconfig +++ b/drivers/net/wireless/ti/wl18xx/Kconfig @@ -1,6 +1,7 @@ config WL18XX - tristate "TI wl18xx support" - select WLCORE - ---help--- + tristate "TI wl18xx support" + depends on MAC80211 + select WLCORE + ---help--- This module adds support for wireless adapters based on TI WiLink 8 chipsets. -- GitLab From bfb92ca1332ce0073cfba5d8a7caee214ed3a787 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 17:09:00 +0300 Subject: [PATCH 0607/6849] wlcore: set wl->ht_cap per-band Save the ht_cap IE per-band, so we can configure different params to BG and A bands (we currently don't support MIMO on A band) [Small fix for rx_highest - Arik] Signed-off-by: Eliad Peller Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 5 +++- drivers/net/wireless/ti/wl18xx/main.c | 36 ++++++++++++++++++++----- drivers/net/wireless/ti/wlcore/main.c | 10 ++++--- drivers/net/wireless/ti/wlcore/wlcore.h | 2 +- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index e400d1987e6c..774a1b71e84e 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1423,7 +1423,10 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = 0; wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); - memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl12xx_ht_cap, + sizeof(wl12xx_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], &wl12xx_ht_cap, + sizeof(wl12xx_ht_cap)); wl12xx_conf_init(wl); if (!fref_param) { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 5a6c4cc9577e..6cd61186d06c 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -596,7 +596,7 @@ static int wl18xx_identify_chip(struct wl1271 *wl) WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; /* PG 1.0 has some problems with MCS_13, so disable it */ - wl->ht_cap.mcs.rx_mask[1] &= ~BIT(5); + wl->ht_cap[IEEE80211_BAND_2GHZ].mcs.rx_mask[1] &= ~BIT(5); /* TODO: need to blocksize alignment for RX/TX separately? */ break; @@ -1086,7 +1086,7 @@ static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { }; /* HT cap appropriate for MIMO rates in 20mhz channel */ -static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap = { +static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { .cap = IEEE80211_HT_CAP_SGI_20, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, @@ -1098,6 +1098,18 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap = { }, }; +static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_5ghz = { + .cap = IEEE80211_HT_CAP_SGI_20, + .ht_supported = true, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .mcs = { + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(72), + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, +}; + static int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -1127,13 +1139,25 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); if (!strcmp(ht_mode_param, "wide")) { - memcpy(&wl->ht_cap, &wl18xx_siso40_ht_cap, + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], + &wl18xx_siso40_ht_cap, + sizeof(wl18xx_siso40_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], + &wl18xx_siso40_ht_cap, sizeof(wl18xx_siso40_ht_cap)); } else if (!strcmp(ht_mode_param, "mimo")) { - memcpy(&wl->ht_cap, &wl18xx_mimo_ht_cap, - sizeof(wl18xx_mimo_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], + &wl18xx_mimo_ht_cap_2ghz, + sizeof(wl18xx_mimo_ht_cap_2ghz)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], + &wl18xx_mimo_ht_cap_5ghz, + sizeof(wl18xx_mimo_ht_cap_5ghz)); } else if (!strcmp(ht_mode_param, "siso20")) { - memcpy(&wl->ht_cap, &wl18xx_siso20_ht_cap, + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], + &wl18xx_siso20_ht_cap, + sizeof(wl18xx_siso20_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], + &wl18xx_siso20_ht_cap, sizeof(wl18xx_siso20_ht_cap)); } else { wl1271_error("invalid ht_mode '%s'", ht_mode_param); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 1974be0ccd58..c08df334b9d5 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5031,12 +5031,14 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) */ memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz, sizeof(wl1271_band_2ghz)); - memcpy(&wl->bands[IEEE80211_BAND_2GHZ].ht_cap, &wl->ht_cap, - sizeof(wl->ht_cap)); + memcpy(&wl->bands[IEEE80211_BAND_2GHZ].ht_cap, + &wl->ht_cap[IEEE80211_BAND_2GHZ], + sizeof(*wl->ht_cap)); memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz, sizeof(wl1271_band_5ghz)); - memcpy(&wl->bands[IEEE80211_BAND_5GHZ].ht_cap, &wl->ht_cap, - sizeof(wl->ht_cap)); + memcpy(&wl->bands[IEEE80211_BAND_5GHZ].ht_cap, + &wl->ht_cap[IEEE80211_BAND_5GHZ], + sizeof(*wl->ht_cap)); wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl->bands[IEEE80211_BAND_2GHZ]; diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 19678738a069..37a80f4bf5bb 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -368,7 +368,7 @@ struct wl1271 { u8 hw_min_ht_rate; /* HW HT (11n) capabilities */ - struct ieee80211_sta_ht_cap ht_cap; + struct ieee80211_sta_ht_cap ht_cap[IEEE80211_NUM_BANDS]; /* size of the private FW status data */ size_t fw_status_priv_len; -- GitLab From 1952639665e92481c34c34c3e2a71bf3e66ba362 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Mon, 4 Jun 2012 14:53:23 +0300 Subject: [PATCH 0608/6849] KVM: MMU: do not iterate over all VMs in mmu_shrink() mmu_shrink() needlessly iterates over all VMs even though it will not attempt to free mmu pages from more than one on them. Fix that and also check used mmu pages count outside of VM lock to skip inactive VMs faster. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index d07e436b7a42..1ca7164a74f1 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3944,7 +3944,6 @@ static void kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm, static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) { struct kvm *kvm; - struct kvm *kvm_freed = NULL; int nr_to_scan = sc->nr_to_scan; if (nr_to_scan == 0) @@ -3956,22 +3955,30 @@ static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) int idx; LIST_HEAD(invalid_list); + /* + * n_used_mmu_pages is accessed without holding kvm->mmu_lock + * here. We may skip a VM instance errorneosly, but we do not + * want to shrink a VM that only started to populate its MMU + * anyway. + */ + if (kvm->arch.n_used_mmu_pages > 0) { + if (!nr_to_scan--) + break; + continue; + } + idx = srcu_read_lock(&kvm->srcu); spin_lock(&kvm->mmu_lock); - if (!kvm_freed && nr_to_scan > 0 && - kvm->arch.n_used_mmu_pages > 0) { - kvm_mmu_remove_some_alloc_mmu_pages(kvm, - &invalid_list); - kvm_freed = kvm; - } - nr_to_scan--; + kvm_mmu_remove_some_alloc_mmu_pages(kvm, &invalid_list); kvm_mmu_commit_zap_page(kvm, &invalid_list); + spin_unlock(&kvm->mmu_lock); srcu_read_unlock(&kvm->srcu, idx); + + list_move_tail(&kvm->vm_list, &vm_list); + break; } - if (kvm_freed) - list_move_tail(&kvm_freed->vm_list, &vm_list); raw_spin_unlock(&kvm_lock); -- GitLab From b246dd5df139501b974bd6b28f7815e53b3a792f Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Thu, 31 May 2012 14:49:22 +0300 Subject: [PATCH 0609/6849] KVM: VMX: Fix KVM_SET_SREGS with big real mode segments For example migration between Westmere and Nehelem hosts, caught in big real mode. The code that fixes the segments for real mode guest was moved from enter_rmode to vmx_set_segments. enter_rmode calls vmx_set_segments for each segment. Signed-off-by: Orit Wasserman Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 70 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 396148ab089b..f78662ec8677 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -618,6 +618,10 @@ static void kvm_cpu_vmxon(u64 addr); static void kvm_cpu_vmxoff(void); static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); +static void vmx_set_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg); +static void vmx_get_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg); static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); @@ -2782,6 +2786,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu) { unsigned long flags; struct vcpu_vmx *vmx = to_vmx(vcpu); + struct kvm_segment var; if (enable_unrestricted_guest) return; @@ -2825,20 +2830,23 @@ static void enter_rmode(struct kvm_vcpu *vcpu) if (emulate_invalid_guest_state) goto continue_rmode; - vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4); - vmcs_write32(GUEST_SS_LIMIT, 0xffff); - vmcs_write32(GUEST_SS_AR_BYTES, 0xf3); + vmx_get_segment(vcpu, &var, VCPU_SREG_SS); + vmx_set_segment(vcpu, &var, VCPU_SREG_SS); + + vmx_get_segment(vcpu, &var, VCPU_SREG_CS); + vmx_set_segment(vcpu, &var, VCPU_SREG_CS); + + vmx_get_segment(vcpu, &var, VCPU_SREG_ES); + vmx_set_segment(vcpu, &var, VCPU_SREG_ES); - vmcs_write32(GUEST_CS_AR_BYTES, 0xf3); - vmcs_write32(GUEST_CS_LIMIT, 0xffff); - if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000) - vmcs_writel(GUEST_CS_BASE, 0xf0000); - vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4); + vmx_get_segment(vcpu, &var, VCPU_SREG_DS); + vmx_set_segment(vcpu, &var, VCPU_SREG_DS); - fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es); - fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds); - fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs); - fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs); + vmx_get_segment(vcpu, &var, VCPU_SREG_GS); + vmx_set_segment(vcpu, &var, VCPU_SREG_GS); + + vmx_get_segment(vcpu, &var, VCPU_SREG_FS); + vmx_set_segment(vcpu, &var, VCPU_SREG_FS); continue_rmode: kvm_mmu_reset_context(vcpu); @@ -3243,6 +3251,44 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, vmcs_write32(sf->ar_bytes, ar); __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); + + /* + * Fix segments for real mode guest in hosts that don't have + * "unrestricted_mode" or it was disabled. + * This is done to allow migration of the guests from hosts with + * unrestricted guest like Westmere to older host that don't have + * unrestricted guest like Nehelem. + */ + if (!enable_unrestricted_guest && vmx->rmode.vm86_active) { + switch (seg) { + case VCPU_SREG_CS: + vmcs_write32(GUEST_CS_AR_BYTES, 0xf3); + vmcs_write32(GUEST_CS_LIMIT, 0xffff); + if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000) + vmcs_writel(GUEST_CS_BASE, 0xf0000); + vmcs_write16(GUEST_CS_SELECTOR, + vmcs_readl(GUEST_CS_BASE) >> 4); + break; + case VCPU_SREG_ES: + fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es); + break; + case VCPU_SREG_DS: + fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds); + break; + case VCPU_SREG_GS: + fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs); + break; + case VCPU_SREG_FS: + fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs); + break; + case VCPU_SREG_SS: + vmcs_write16(GUEST_SS_SELECTOR, + vmcs_readl(GUEST_SS_BASE) >> 4); + vmcs_write32(GUEST_SS_LIMIT, 0xffff); + vmcs_write32(GUEST_SS_AR_BYTES, 0xf3); + break; + } + } } static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) -- GitLab From 4ee0444bebf3d0399c93841d98826ade193e6330 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:15:56 +0800 Subject: [PATCH 0610/6849] hexagon: SMP: Remove call to ipi_call_lock()/ipi_call_unlock() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: Richard Kuo Cc: linux-hexagon@vger.kernel.org Link: http://lkml.kernel.org/r/1338275765-3217-2-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/hexagon/kernel/smp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c index f7264621e58d..149fbefc1a4d 100644 --- a/arch/hexagon/kernel/smp.c +++ b/arch/hexagon/kernel/smp.c @@ -180,9 +180,7 @@ void __cpuinit start_secondary(void) notify_cpu_starting(cpu); - ipi_call_lock(); set_cpu_online(cpu, true); - ipi_call_unlock(); local_irq_enable(); -- GitLab From 4cbd19fcf9d49f28766415b96eb6201bc263d817 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:15:57 +0800 Subject: [PATCH 0611/6849] mn10300: SMP: Remove call to ipi_call_lock()/ipi_call_unlock() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: David Howells Cc: Koichi Yasutake Cc: linux-am33-list@redhat.com Link: http://lkml.kernel.org/r/1338275765-3217-3-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/mn10300/kernel/smp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index 090d35d36973..e62c223e4c45 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c @@ -876,9 +876,7 @@ static void __init smp_online(void) notify_cpu_starting(cpu); - ipi_call_lock(); set_cpu_online(cpu, true); - ipi_call_unlock(); local_irq_enable(); } -- GitLab From ac4216d6922f90c459d531e051c832dadde3a8f7 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:15:58 +0800 Subject: [PATCH 0612/6849] parisc: Smp: remove call to ipi_call_lock()/ipi_call_unlock() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: James E.J. Bottomley Cc: Helge Deller Cc: linux-parisc@vger.kernel.org Link: http://lkml.kernel.org/r/1338275765-3217-4-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/parisc/kernel/smp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index a47828d31fe6..6266730efd61 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -300,9 +300,7 @@ smp_cpu_init(int cpunum) notify_cpu_starting(cpunum); - ipi_call_lock(); set_cpu_online(cpunum, true); - ipi_call_unlock(); /* Initialise the idle task for this CPU */ atomic_inc(&init_mm.mm_count); -- GitLab From 46ce7fbfdbe0be6aaf0e816331aac08a74a00e5a Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:15:59 +0800 Subject: [PATCH 0613/6849] S390: Smp: remove call to ipi_call_lock()/ipi_call_unlock() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: linux390@de.ibm.com Cc: linux-s390@vger.kernel.org Link: http://lkml.kernel.org/r/1338275765-3217-5-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/s390/kernel/smp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 15cca26ccb6c..8dca9c248ac7 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -717,9 +717,7 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) init_cpu_vtimer(); pfault_init(); notify_cpu_starting(smp_processor_id()); - ipi_call_lock(); set_cpu_online(smp_processor_id(), true); - ipi_call_unlock(); local_irq_enable(); /* cpu_idle will call schedule for us */ cpu_idle(); -- GitLab From 8efdfc3a4ed009c978dab6609d15fb958e7cff12 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:16:00 +0800 Subject: [PATCH 0614/6849] tile: SMP: Remove call to ipi_call_lock()/ipi_call_unlock() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: Chris Metcalf Link: http://lkml.kernel.org/r/1338275765-3217-6-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/tile/kernel/smpboot.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c index 84873fbe8f27..e686c5ac90be 100644 --- a/arch/tile/kernel/smpboot.c +++ b/arch/tile/kernel/smpboot.c @@ -198,17 +198,7 @@ void __cpuinit online_secondary(void) notify_cpu_starting(smp_processor_id()); - /* - * We need to hold call_lock, so there is no inconsistency - * between the time smp_call_function() determines number of - * IPI recipients, and the time when the determination is made - * for which cpus receive the IPI. Holding this - * lock helps us to not include this cpu in a currently in progress - * smp_call_function(). - */ - ipi_call_lock(); set_cpu_online(smp_processor_id(), 1); - ipi_call_unlock(); __get_cpu_var(cpu_state) = CPU_ONLINE; /* Set up tile-specific state for this cpu. */ -- GitLab From 3b6f70fd7dd4e19fc674ec99e389bf0da5589525 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:16:01 +0800 Subject: [PATCH 0615/6849] x86-smp-remove-call-to-ipi_call_lock-ipi_call_unlock ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: Konrad Rzeszutek Wilk Cc: Jeremy Fitzhardinge Cc: Ingo Molnar Cc: "H. Peter Anvin" Link: http://lkml.kernel.org/r/1338275765-3217-7-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/x86/kernel/smpboot.c | 9 --------- arch/x86/xen/smp.c | 2 -- 2 files changed, 11 deletions(-) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index f56f96da77f5..b2fd28ff84b5 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -255,22 +255,13 @@ notrace static void __cpuinit start_secondary(void *unused) check_tsc_sync_target(); /* - * We need to hold call_lock, so there is no inconsistency - * between the time smp_call_function() determines number of - * IPI recipients, and the time when the determination is made - * for which cpus receive the IPI. Holding this - * lock helps us to not include this cpu in a currently in progress - * smp_call_function(). - * * We need to hold vector_lock so there the set of online cpus * does not change while we are assigning vectors to cpus. Holding * this lock ensures we don't half assign or remove an irq from a cpu. */ - ipi_call_lock(); lock_vector_lock(); set_cpu_online(smp_processor_id(), true); unlock_vector_lock(); - ipi_call_unlock(); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; x86_platform.nmi_init(); diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index afb250d22a6b..f58dca7a6e52 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -80,9 +80,7 @@ static void __cpuinit cpu_bringup(void) notify_cpu_starting(cpu); - ipi_call_lock(); set_cpu_online(cpu, true); - ipi_call_unlock(); this_cpu_write(cpu_state, CPU_ONLINE); -- GitLab From 459165e25030c0023cb54f73c14261a3d2f4a244 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:16:02 +0800 Subject: [PATCH 0616/6849] ia64: SMP: Remove call to ipi_call_lock_irq()/ipi_call_unlock_irq() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: Tony Luck Cc: Fenghua Yu Cc: linux-ia64@vger.kernel.org Link: http://lkml.kernel.org/r/1338275765-3217-8-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/ia64/kernel/smpboot.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 1113b8aba07f..963d2db53bfa 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -382,7 +382,6 @@ smp_callin (void) set_numa_node(cpu_to_node_map[cpuid]); set_numa_mem(local_memory_node(cpu_to_node_map[cpuid])); - ipi_call_lock_irq(); spin_lock(&vector_lock); /* Setup the per cpu irq handling data structures */ __setup_vector_irq(cpuid); @@ -390,7 +389,6 @@ smp_callin (void) set_cpu_online(cpuid, true); per_cpu(cpu_state, cpuid) = CPU_ONLINE; spin_unlock(&vector_lock); - ipi_call_unlock_irq(); smp_setup_percpu_timer(); -- GitLab From bc6833009583bd5b096ef7aa2bb006854a5a2dce Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 16:27:33 +0800 Subject: [PATCH 0617/6849] SPARC: SMP: Remove call to ipi_call_lock_irq()/ipi_call_unlock_irq() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. Delay irq enable to after set_cpu_online(). [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: sparclinux@vger.kernel.org Link: http://lkml.kernel.org/r/20120529082732.GA4250@zhy Acked-by: "David S. Miller" Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/sparc/kernel/smp_64.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index f591598d92f6..781bcb10b8bd 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -103,8 +103,6 @@ void __cpuinit smp_callin(void) if (cheetah_pcache_forced_on) cheetah_enable_pcache(); - local_irq_enable(); - callin_flag = 1; __asm__ __volatile__("membar #Sync\n\t" "flush %%g6" : : : "memory"); @@ -124,9 +122,8 @@ void __cpuinit smp_callin(void) while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) rmb(); - ipi_call_lock_irq(); set_cpu_online(cpuid, true); - ipi_call_unlock_irq(); + local_irq_enable(); /* idle thread is expected to have preempt disabled */ preempt_disable(); @@ -1308,9 +1305,7 @@ int __cpu_disable(void) mdelay(1); local_irq_disable(); - ipi_call_lock(); set_cpu_online(cpu, false); - ipi_call_unlock(); cpu_map_rebuild(); -- GitLab From 72ec61a9e8347375e37c05e23511173d8451c3d4 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:16:04 +0800 Subject: [PATCH 0618/6849] POWERPC: Smp: remove call to ipi_call_lock()/ipi_call_unlock() ipi_call_lock/unlock() lock resp. unlock call_function.lock. This lock protects only the call_function data structure itself, but it's completely unrelated to cpu_online_mask. The mask to which the IPIs are sent is calculated before call_function.lock is taken in smp_call_function_many(), so the locking around set_cpu_online() is pointless and can be removed. [ tglx: Massaged changelog ] Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: peterz@infradead.org Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/1338275765-3217-10-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/powerpc/kernel/smp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index e4cb34322de4..e1417c42155c 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -571,7 +571,6 @@ void __devinit start_secondary(void *unused) if (system_state == SYSTEM_RUNNING) vdso_data->processorCount++; #endif - ipi_call_lock(); notify_cpu_starting(cpu); set_cpu_online(cpu, true); /* Update sibling maps */ @@ -601,7 +600,6 @@ void __devinit start_secondary(void *unused) of_node_put(np); } of_node_put(l2_cache); - ipi_call_unlock(); local_irq_enable(); -- GitLab From 8feb8e896d77439146d2e2ab3d0ab55bb5baf5fc Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Tue, 29 May 2012 15:16:05 +0800 Subject: [PATCH 0619/6849] smp: Remove ipi_call_lock[_irq]()/ipi_call_unlock[_irq]() There is no user of those APIs anymore, just remove it. Signed-off-by: Yong Zhang Cc: ralf@linux-mips.org Cc: sshtylyov@mvista.com Cc: david.daney@cavium.com Cc: nikunj@linux.vnet.ibm.com Cc: paulmck@linux.vnet.ibm.com Cc: axboe@kernel.dk Cc: Andrew Morton Link: http://lkml.kernel.org/r/1338275765-3217-11-git-send-email-yong.zhang0@gmail.com Acked-by: Srivatsa S. Bhat Acked-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- include/linux/smp.h | 4 ---- kernel/smp.c | 20 -------------------- 2 files changed, 24 deletions(-) diff --git a/include/linux/smp.h b/include/linux/smp.h index 717fb746c9a8..a34d4f15430d 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -90,10 +90,6 @@ void kick_all_cpus_sync(void); void __init call_function_init(void); void generic_smp_call_function_single_interrupt(void); void generic_smp_call_function_interrupt(void); -void ipi_call_lock(void); -void ipi_call_unlock(void); -void ipi_call_lock_irq(void); -void ipi_call_unlock_irq(void); #else static inline void call_function_init(void) { } #endif diff --git a/kernel/smp.c b/kernel/smp.c index d0ae5b24875e..29dd40a9f2f4 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -581,26 +581,6 @@ int smp_call_function(smp_call_func_t func, void *info, int wait) return 0; } EXPORT_SYMBOL(smp_call_function); - -void ipi_call_lock(void) -{ - raw_spin_lock(&call_function.lock); -} - -void ipi_call_unlock(void) -{ - raw_spin_unlock(&call_function.lock); -} - -void ipi_call_lock_irq(void) -{ - raw_spin_lock_irq(&call_function.lock); -} - -void ipi_call_unlock_irq(void) -{ - raw_spin_unlock_irq(&call_function.lock); -} #endif /* USE_GENERIC_SMP_HELPERS */ /* Setup configured maximum number of CPUs to activate */ -- GitLab From 43cc7e86f3200b094e2960b732623aeec00b482d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 May 2012 17:26:16 +0200 Subject: [PATCH 0620/6849] smp: Remove num_booting_cpus() No users. Signed-off-by: Thomas Gleixner Cc: Srivatsa S. Bhat Cc: Rusty Russell --- arch/m32r/include/asm/smp.h | 5 ----- arch/x86/include/asm/smp.h | 5 ----- include/linux/smp.h | 1 - 3 files changed, 11 deletions(-) diff --git a/arch/m32r/include/asm/smp.h b/arch/m32r/include/asm/smp.h index cf7829a61551..c689b828dfe2 100644 --- a/arch/m32r/include/asm/smp.h +++ b/arch/m32r/include/asm/smp.h @@ -79,11 +79,6 @@ static __inline__ int cpu_number_map(int cpu) return cpu; } -static __inline__ unsigned int num_booting_cpus(void) -{ - return cpumask_weight(&cpu_callout_map); -} - extern void smp_send_timer(void); extern unsigned long send_IPI_mask_phys(const cpumask_t*, int, int); diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index f48394513c37..2ffa95dc2333 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -169,11 +169,6 @@ void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); void smp_store_cpu_info(int id); #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) -/* We don't mark CPUs online until __cpu_up(), so we need another measure */ -static inline int num_booting_cpus(void) -{ - return cpumask_weight(cpu_callout_mask); -} #else /* !CONFIG_SMP */ #define wbinvd_on_cpu(cpu) wbinvd() static inline int wbinvd_on_all_cpus(void) diff --git a/include/linux/smp.h b/include/linux/smp.h index a34d4f15430d..dd6f06be3c9f 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -177,7 +177,6 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info) } while (0) static inline void smp_send_reschedule(int cpu) { } -#define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) #define smp_call_function_many(mask, func, info, wait) \ (up_smp_call_function(func, info)) -- GitLab From 223f18e4482fd90b7cdabb222fad5ca502dc0028 Mon Sep 17 00:00:00 2001 From: Raymond Yau Date: Mon, 4 Jun 2012 14:59:55 +0800 Subject: [PATCH 0621/6849] ALSA: au88x0 - Remove unused "Master Mono" Playback Volume and Playback Switch of ac97 codec Remove "Master Mono Playback Volume" and "Master Mono Playback Switch" of ac97 mixer since au88x0 does no use "Master Mono Pin" of AC97 codec even au88x0 support mono playback Signed-off-by: Raymond Yau Signed-off-by: Takashi Iwai --- sound/pci/au88x0/au88x0_mixer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c index 557c782ae4fc..fa13efbebdaf 100644 --- a/sound/pci/au88x0/au88x0_mixer.c +++ b/sound/pci/au88x0/au88x0_mixer.c @@ -10,6 +10,15 @@ #include #include "au88x0.h" +static int remove_ctl(struct snd_card *card, const char *name) +{ + struct snd_ctl_elem_id id; + memset(&id, 0, sizeof(id)); + strcpy(id.name, name); + id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + return snd_ctl_remove_id(card, &id); +} + static int __devinit snd_vortex_mixer(vortex_t * vortex) { struct snd_ac97_bus *pbus; @@ -28,5 +37,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex) ac97.scaps = AC97_SCAP_NO_SPDIF; err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); + remove_ctl(vortex->card, "Master Mono Playback Volume"); + remove_ctl(vortex->card, "Master Mono Playback Switch"); return err; } -- GitLab From 2e42c203a9a825d04da400bd45b601f94c0cf362 Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Tue, 8 May 2012 14:02:11 +0300 Subject: [PATCH 0622/6849] wlcore: use psd_type indexing according to spec In ieee80211.h the uapsd bit mask is defined such that VO=BIT(0), VI=BIT(1), BK=BIT(2), BE=BIT(3). The firmware uses the indexing as defined in the ieee80211 spec, meaning that VO=3, VI=2, BK=1, BE=0. In AP mode when adding peer wlcore needs to convert the indexing accordingly. Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 5b14446ece4a..e8c650dec18c 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -1374,9 +1374,12 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) if (sta->wme && (sta->uapsd_queues & BIT(i))) - cmd->psd_type[i] = WL1271_PSD_UPSD_TRIGGER; + cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] = + WL1271_PSD_UPSD_TRIGGER; else - cmd->psd_type[i] = WL1271_PSD_LEGACY; + cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] = + WL1271_PSD_LEGACY; + sta_rates = sta->supp_rates[wlvif->band]; if (sta->ht_cap.ht_supported) -- GitLab From 4a6c789b731a095da745d513f9ea0b5531acc9c7 Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Tue, 8 May 2012 14:02:12 +0300 Subject: [PATCH 0623/6849] wl12xx: set the irq polarity before loading the fw The polarity should be set before the firmware is loaded since the firmware touches the same register. Access of the firmware and driver to the same register will cause a collision since there is no exclusion scheme. Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 774a1b71e84e..a5af2b1ec863 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -995,7 +995,7 @@ out: static void wl12xx_pre_upload(struct wl1271 *wl) { - u32 tmp; + u32 tmp, polarity; /* write firmware's last address (ie. it's length) to * ACX_EEPROMLESS_IND_REG */ @@ -1015,18 +1015,18 @@ static void wl12xx_pre_upload(struct wl1271 *wl) if (wl->chip.id == CHIP_ID_1283_PG20) wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); -} - -static void wl12xx_enable_interrupts(struct wl1271 *wl) -{ - u32 polarity; + /* polarity must be set before the firmware is loaded */ polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY); /* We use HIGH polarity, so unset the LOW bit */ polarity &= ~POLARITY_LOW; wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); +} + +static void wl12xx_enable_interrupts(struct wl1271 *wl) +{ wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); wlcore_enable_interrupts(wl); -- GitLab From feb47eb86b44fb420c7fe92726e5f359bcea4bdf Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Tue, 8 May 2012 14:02:14 +0300 Subject: [PATCH 0624/6849] wlcore: fix the CONF_TX_AC_ANY_TID to be 0xff In the enum conf_tx_ac CONF_TX_AC_ANY_TID should be 0xff to match the firmware's implementation. Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 14dd361fa828..d2c4885d0d77 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -518,7 +518,7 @@ enum conf_tx_ac { CONF_TX_AC_VI = 2, /* video */ CONF_TX_AC_VO = 3, /* voice */ CONF_TX_AC_CTS2SELF = 4, /* fictitious AC, follows AC_VO */ - CONF_TX_AC_ANY_TID = 0x1f + CONF_TX_AC_ANY_TID = 0xff }; struct conf_tx_ac_category { -- GitLab From d1bcb53f91ed6838dccb04aa5cf71ea8a98770f2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 16:46:56 +0300 Subject: [PATCH 0625/6849] wlcore: flush tx on CHANGE_CHANNEL On CHANGE_CHANNEL indication, we should flush all the queued tx frames, so they will be sent on the correct (current) channel. Signed-off-by: Eliad Peller Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index c08df334b9d5..b0607f6e4e4e 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2557,8 +2557,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) * frames, such as the deauth. To make sure those frames reach the air, * wait here until the TX queue is fully flushed. */ - if ((changed & IEEE80211_CONF_CHANGE_IDLE) && - (conf->flags & IEEE80211_CONF_IDLE)) + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || + ((changed & IEEE80211_CONF_CHANGE_IDLE) && + (conf->flags & IEEE80211_CONF_IDLE))) wl1271_tx_flush(wl); mutex_lock(&wl->mutex); -- GitLab From 0c2129843502833c6e4117db8f312b625a23ef15 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 16:46:57 +0300 Subject: [PATCH 0626/6849] wlcore: increase WL1271_EVENT_TIMEOUT In some cases, the ROC_COMPLETE event might exceed the current timeout (750 msec). Increase it to 1 sec. Signed-off-by: Eliad Peller Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index 2aafe3df0fb0..85171f2bf68e 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h @@ -192,7 +192,7 @@ enum cmd_templ { #define WL1271_COMMAND_TIMEOUT 2000 #define WL1271_CMD_TEMPL_DFLT_SIZE 252 #define WL1271_CMD_TEMPL_MAX_SIZE 512 -#define WL1271_EVENT_TIMEOUT 750 +#define WL1271_EVENT_TIMEOUT 1000 struct wl1271_cmd_header { __le16 id; -- GitLab From 5a344b87ce1f27dade9f320aeb08ba7401d8c984 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 15 May 2012 16:46:58 +0300 Subject: [PATCH 0627/6849] wlcore: remove duplicate BUG_ON during recovery This BUG_ON also ignored the INTENDED_FW_RECOVERY flag. This would result in a BUG() when using the bug_on_recovery module parameter during multi-role. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index b0607f6e4e4e..414fde41072c 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -852,8 +852,6 @@ static void wl1271_recovery_work(struct work_struct *work) goto out_unlock; } - BUG_ON(bug_on_recovery); - /* * Advance security sequence number to overcome potential progress * in the firmware during recovery. This doens't hurt if the network is -- GitLab From 836d3f2058ca42eda96dcf187cd72a0ea2a5bf6c Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Thu, 10 May 2012 17:08:33 +0300 Subject: [PATCH 0628/6849] wl12xx: fix fm_coex parameters configuration Wrong fm_coex parameters were set during wl12xx init phase, fix it. Signed-off-by: Ziv Riesel Signed-off-by: Victor Goldenshtein Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index a5af2b1ec863..77e0f318aa67 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -309,8 +309,8 @@ static struct wlcore_conf wl12xx_conf = { .swallow_period = 5, .n_divider_fref_set_1 = 0xff, /* default */ .n_divider_fref_set_2 = 12, - .m_divider_fref_set_1 = 148, - .m_divider_fref_set_2 = 0xffff, /* default */ + .m_divider_fref_set_1 = 0xffff, + .m_divider_fref_set_2 = 148, /* default */ .coex_pll_stabilization_time = 0xffffffff, /* default */ .ldo_stabilization_time = 0xffff, /* default */ .fm_disturbed_band_margin = 0xff, /* default */ -- GitLab From 461b958fd62c62b61d27e0f567128eb2170c0cf2 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Tue, 15 May 2012 17:15:40 +0300 Subject: [PATCH 0629/6849] wl18xx: fix fm_coex parameters configuration Wrong fm_coex parameters were set during wl18xx init phase, fix it. Signed-off-by: Ziv Riesel Signed-off-by: Victor Goldenshtein Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 6cd61186d06c..d67be3eae3d9 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -427,8 +427,8 @@ static struct wlcore_conf wl18xx_conf = { .swallow_period = 5, .n_divider_fref_set_1 = 0xff, /* default */ .n_divider_fref_set_2 = 12, - .m_divider_fref_set_1 = 148, - .m_divider_fref_set_2 = 0xffff, /* default */ + .m_divider_fref_set_1 = 0xffff, + .m_divider_fref_set_2 = 148, /* default */ .coex_pll_stabilization_time = 0xffffffff, /* default */ .ldo_stabilization_time = 0xffff, /* default */ .fm_disturbed_band_margin = 0xff, /* default */ -- GitLab From e832837bbb91ae8610fa0a0f3d243d42823ec815 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Mon, 14 May 2012 13:55:47 +0300 Subject: [PATCH 0630/6849] wlcore: don't enable BET for high basic rates The beacon early termination is not relevant for high basic rates, which doesn't contribute anything to the PS and only adds unnecessary FW work. Enable BET only if the basic rate is less than 9 Mbps. Signed-off-by: Ziv Riesel Signed-off-by: Victor Goldenshtein Signed-off-by: Igal Chernobelsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/ps.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c index 958535dee9f3..47e81b32f7da 100644 --- a/drivers/net/wireless/ti/wlcore/ps.c +++ b/drivers/net/wireless/ti/wlcore/ps.c @@ -193,8 +193,12 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); - /* enable beacon early termination. Not relevant for 5GHz */ - if (wlvif->band == IEEE80211_BAND_2GHZ) { + /* + * enable beacon early termination. + * Not relevant for 5GHz and for high rates. + */ + if ((wlvif->band == IEEE80211_BAND_2GHZ) && + (wlvif->basic_rate < CONF_HW_BIT_RATE_9MBPS)) { ret = wl1271_acx_bet_enable(wl, wlvif, true); if (ret < 0) return ret; @@ -204,7 +208,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_PSM, "leaving psm"); /* disable beacon early termination */ - if (wlvif->band == IEEE80211_BAND_2GHZ) { + if ((wlvif->band == IEEE80211_BAND_2GHZ) && + (wlvif->basic_rate < CONF_HW_BIT_RATE_9MBPS)) { ret = wl1271_acx_bet_enable(wl, wlvif, false); if (ret < 0) return ret; -- GitLab From a4203c6453afcd21b3a6f0be592bf74951e80c72 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Mon, 14 May 2012 16:07:38 +0300 Subject: [PATCH 0631/6849] wlcore: wait for roc complete only for the first roc command In some multi role scenarios the driver might send multi roc requests without sending a croc first, the fw queues those requests and starts service the next roc request as soon as the driver sends a croc for the previous one. So, if the fw rocs on channel X and driver asks to roc also on channel Y, the fw will not start service Y (and will not send roc complete event for this request) until the driver releases the fw with croc X. Signed-off-by: Victor Goldenshtein Signed-off-by: Igal Chernobelsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index e8c650dec18c..df8d672b1f06 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -1606,19 +1606,25 @@ out: int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id) { int ret = 0; + bool is_first_roc; if (WARN_ON(test_bit(role_id, wl->roc_map))) return 0; + is_first_roc = (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= + WL12XX_MAX_ROLES); + ret = wl12xx_cmd_roc(wl, wlvif, role_id); if (ret < 0) goto out; - ret = wl1271_cmd_wait_for_event(wl, - REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID); - if (ret < 0) { - wl1271_error("cmd roc event completion error"); - goto out; + if (is_first_roc) { + ret = wl1271_cmd_wait_for_event(wl, + REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID); + if (ret < 0) { + wl1271_error("cmd roc event completion error"); + goto out; + } } __set_bit(role_id, wl->roc_map); -- GitLab From 72d7872852e1734e94686012a2e9deade3457329 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 10 May 2012 16:18:26 +0300 Subject: [PATCH 0632/6849] mac80211: allow low-level drivers to set netdev feature bits Low level drivers can now set certain netdev feature bits in netdev_features member of the ieee80211_hw struct. These will be propagated to every netdev created from this HW. The white-listed features currently include only ones related to HW checksumming. Signed-off-by: Arik Nemtsov Signed-off-by: John W. Linville --- include/net/mac80211.h | 5 +++++ net/mac80211/iface.c | 2 ++ net/mac80211/main.c | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1937c7d98304..0286c0476e44 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1297,6 +1297,10 @@ enum ieee80211_hw_flags { * reports, by default it is set to _MCS, _GI and _BW but doesn't * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only * adding _BW is supported today. + * + * @netdev_features: netdev features to be set in each netdev created + * from this HW. Note only HW checksum features are currently + * compatible with mac80211. Other feature bits will be rejected. */ struct ieee80211_hw { struct ieee80211_conf conf; @@ -1319,6 +1323,7 @@ struct ieee80211_hw { u8 max_tx_aggregation_subframes; u8 offchannel_tx_hw_queue; u8 radiotap_mcs_details; + netdev_features_t netdev_features; }; /** diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d4c19a7773db..f970e0b3c4b9 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1352,6 +1352,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, sdata->u.mgd.use_4addr = params->use_4addr; } + ndev->features |= local->hw.netdev_features; + ret = register_netdevice(ndev); if (ret) goto fail; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index f5548e953259..779ac613ee57 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -682,6 +682,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) enum ieee80211_band band; int channels, max_bitrates; bool supp_ht; + netdev_features_t feature_whitelist; static const u32 cipher_suites[] = { /* keep WEP first, it may be removed below */ WLAN_CIPHER_SUITE_WEP40, @@ -708,6 +709,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) return -EINVAL; + /* Only HW csum features are currently compatible with mac80211 */ + feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_HW_CSUM; + if (WARN_ON(hw->netdev_features & ~feature_whitelist)) + return -EINVAL; + if (hw->max_report_rates == 0) hw->max_report_rates = hw->max_rates; -- GitLab From c53f7e150e178b62b9904428ccbe3ae6f3553fdd Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 13 May 2012 16:47:05 +0300 Subject: [PATCH 0633/6849] mac80211: use offchannel queue only when supported Commit 3a25a8c ("mac80211: add improved HW queue control") added support for offchannel queue mapping. However, this mapping is only valid when the driver supports IEEE80211_HW_QUEUE_CONTROL. Check whether the driver supports IEEE80211_HW_QUEUE_CONTROL before setting the hw_queue to the mapped offchannel queue. (This patch doesn't have any actual effect, because hw_queue is overridden in ieee80211_tx() anyway, so this is merely some cleanup) Signed-off-by: Eliad Peller Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 495831ee48f1..7ad542363f0b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2304,7 +2304,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, IEEE80211_SKB_CB(skb)->flags = flags; - if (flags & IEEE80211_TX_CTL_TX_OFFCHAN) + if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL && + flags & IEEE80211_TX_CTL_TX_OFFCHAN) IEEE80211_SKB_CB(skb)->hw_queue = local->hw.offchannel_tx_hw_queue; @@ -2349,8 +2350,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, /* modify cookie to prevent API mismatches */ *cookie ^= 2; IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; - IEEE80211_SKB_CB(skb)->hw_queue = - local->hw.offchannel_tx_hw_queue; + if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) + IEEE80211_SKB_CB(skb)->hw_queue = + local->hw.offchannel_tx_hw_queue; local->hw_roc_skb = skb; local->hw_roc_skb_for_status = skb; mutex_unlock(&local->mtx); -- GitLab From dac211ec10d268b9d09000093a9fa2ac1773894f Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 13 May 2012 18:07:04 +0300 Subject: [PATCH 0634/6849] mac80211: fail authentication when AP denied authentication ieee80211_rx_mgmt_auth() doesn't handle denied authentication properly - it authenticates the station and waits for association (for 5 seconds) instead of failing the authentication. Fix it by destroying auth_data and bailing out instead. Signed-off-by: Eliad Peller Acked-by: Johannes Berg Cc: stable@vger.kernel.org #3.4 Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 04c306308987..a2f18b7e6858 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1791,7 +1791,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, if (status_code != WLAN_STATUS_SUCCESS) { printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n", sdata->name, mgmt->sa, status_code); - goto out; + ieee80211_destroy_auth_data(sdata, false); + return RX_MGMT_CFG80211_RX_AUTH; } switch (ifmgd->auth_data->algorithm) { @@ -1813,7 +1814,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, } printk(KERN_DEBUG "%s: authenticated\n", sdata->name); - out: ifmgd->auth_data->done = true; ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); -- GitLab From be0f42377ffbc7fbb8bda74755048712a4ee8d8e Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Sun, 13 May 2012 22:24:08 -0700 Subject: [PATCH 0635/6849] mac80211: allow channel change while mesh is down Allow channel change on a mesh interface if the interface is up and no mesh is started. Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- net/mac80211/chan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index c76cf7230c7d..f0f87e5a1d35 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -41,6 +41,10 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local, if (!sdata->u.ap.beacon) continue; break; + case NL80211_IFTYPE_MESH_POINT: + if (!sdata->wdev.mesh_id_len) + continue; + break; default: break; } -- GitLab From 8fd9d059af12786341dec5a688e607bcdb372238 Mon Sep 17 00:00:00 2001 From: Albert Pool Date: Mon, 14 May 2012 18:08:32 +0200 Subject: [PATCH 0636/6849] rt2800usb: 2001:3c17 is an RT3370 device D-Link DWA-123 rev A1 Signed-off-by: Albert Pool Cc: Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index bf78317a6adb..20a504072895 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1137,6 +1137,8 @@ static struct usb_device_id rt2800usb_device_table[] = { #ifdef CONFIG_RT2800USB_RT33XX /* Belkin */ { USB_DEVICE(0x050d, 0x945b) }, + /* D-Link */ + { USB_DEVICE(0x2001, 0x3c17) }, /* Panasonic */ { USB_DEVICE(0x083a, 0xb511) }, /* Philips */ @@ -1237,7 +1239,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* D-Link */ { USB_DEVICE(0x07d1, 0x3c0b) }, { USB_DEVICE(0x07d1, 0x3c17) }, - { USB_DEVICE(0x2001, 0x3c17) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1) }, /* Gemtek */ -- GitLab From 9be02923371718265ea050a5415dc4fefc4e6a64 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 14 May 2012 23:57:29 +0300 Subject: [PATCH 0637/6849] brcm80211: remove an unneeded NULL check This code causes a static checker warning because "pi" gets dereferenced before it is checked. The dereference is inside the write_phy_reg() function which is called from wlc_phy_write_txmacreg_nphy(). This code is only called from wlc_phy_init_nphy() and "pi" is a valid pointer so we can remove the check for NULL. Signed-off-by: Dan Carpenter Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index 13b261517cce..366718146418 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -14358,7 +14358,7 @@ void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs) wlc_phy_write_txmacreg_nphy(pi, holdoff, delay); - if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) + if (pi->sh && (pi->sh->_rifs_phy != rifs)) pi->sh->_rifs_phy = rifs; } -- GitLab From 1dacd1980d5ba732de1b69999fd8995b3b2b724b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 15 May 2012 12:00:27 +0300 Subject: [PATCH 0638/6849] brcm80211: brcmu_pkt_buf_free_skb() should handle NULL This is potentially called with NULL pointers, for example, look at brcmf_c_prec_enq(). Since it's a free() function, probably people expect it to handle NULL pointers. Signed-off-by: Dan Carpenter Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmutil/utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index b45ab34cdfdc..3e6405e06ac0 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -43,6 +43,8 @@ EXPORT_SYMBOL(brcmu_pkt_buf_get_skb); /* Free the driver packet. Free the tag if present */ void brcmu_pkt_buf_free_skb(struct sk_buff *skb) { + if (!skb) + return; WARN_ON(skb->next); if (skb->destructor) /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if -- GitLab From d25360b19008e59585defb16823804c40d4723ab Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 15 May 2012 15:24:47 +0530 Subject: [PATCH 0639/6849] ath9k: Fix modal EEPROM dump we provide excess buffer size for 'simple_read_from_buffer' for modal EEPROM dump. This results in trailing NULL bytes at the end of EEPROM dump, fix this. Cc: Rajkumar Manoharan Reported-by: Holger Schurig Signed-off-by: Mohammed Shafi Shajakhan Tested-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 ++-- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_def.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index dfb0441f406c..f794828c08e2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3412,11 +3412,11 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, if (!dump_base_hdr) { len += snprintf(buf + len, size - len, "%20s :\n", "2GHz modal Header"); - len += ar9003_dump_modal_eeprom(buf, len, size, + len = ar9003_dump_modal_eeprom(buf, len, size, &eep->modalHeader2G); len += snprintf(buf + len, size - len, "%20s :\n", "5GHz modal Header"); - len += ar9003_dump_modal_eeprom(buf, len, size, + len = ar9003_dump_modal_eeprom(buf, len, size, &eep->modalHeader5G); goto out; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 4322ac80c203..a850f44fa767 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -135,7 +135,7 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, if (!dump_base_hdr) { len += snprintf(buf + len, size - len, "%20s :\n", "2GHz modal Header"); - len += ath9k_dump_4k_modal_eeprom(buf, len, size, + len = ath9k_dump_4k_modal_eeprom(buf, len, size, &eep->modalHeader); goto out; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index aa614767adff..cd742fb944c2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -132,7 +132,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, if (!dump_base_hdr) { len += snprintf(buf + len, size - len, "%20s :\n", "2GHz modal Header"); - len += ar9287_dump_modal_eeprom(buf, len, size, + len = ar9287_dump_modal_eeprom(buf, len, size, &eep->modalHeader); goto out; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index b5fba8b18b8b..56290f318520 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -211,11 +211,11 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, if (!dump_base_hdr) { len += snprintf(buf + len, size - len, "%20s :\n", "2GHz modal Header"); - len += ath9k_def_dump_modal_eeprom(buf, len, size, + len = ath9k_def_dump_modal_eeprom(buf, len, size, &eep->modalHeader[0]); len += snprintf(buf + len, size - len, "%20s :\n", "5GHz modal Header"); - len += ath9k_def_dump_modal_eeprom(buf, len, size, + len = ath9k_def_dump_modal_eeprom(buf, len, size, &eep->modalHeader[1]); goto out; } -- GitLab From 5dad021dee7c3c601a9e17d86139e586c05c2ee2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 14:50:58 +0300 Subject: [PATCH 0640/6849] nl80211: add new rssi event to indicate beacon loss Tell userspace about beacon loss event. This event doesn't replace the deauth/disassoc that might come if the AP is not available. The driver can send this event in order to hint userspace what might follow (which in turn can use it as roaming trigger). Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index a6959f72745e..6930dddad18a 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -2534,10 +2534,14 @@ enum nl80211_attr_cqm { * configured threshold * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the * configured threshold + * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: The device experienced beacon loss. + * (Note that deauth/disassoc will still follow if the AP is not + * available. This event might get used as roaming event, etc.) */ enum nl80211_cqm_rssi_threshold_event { NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + NL80211_CQM_RSSI_BEACON_LOSS_EVENT, }; -- GitLab From 6efb71b01e37296eb0bcd6c63f7fa3b2d996d589 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Tue, 15 May 2012 15:38:59 +0200 Subject: [PATCH 0641/6849] mac80211: send beacon loss events to userspace Send beacon loss events to userspace, so it will be able to initiate roaming before disconnection Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a2f18b7e6858..4ef22a49870f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1572,6 +1572,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", sdata->name); #endif + ieee80211_cqm_rssi_notify(&sdata->vif, + NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); /* * The driver/our work has already reported this event or the -- GitLab From f0d232080fa5d040aaf73a39d127b003cdd2d0ae Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 May 2012 14:20:30 -0700 Subject: [PATCH 0642/6849] net: mac80211: Convert printk(KERN_DEBUG to pr_debug Standardize the debugging to be able to use dynamic_debug. Coalesce formats, align arguments. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- net/mac80211/agg-rx.c | 20 +++--- net/mac80211/agg-tx.c | 68 ++++++++---------- net/mac80211/cfg.c | 4 +- net/mac80211/debugfs_netdev.c | 2 +- net/mac80211/ibss.c | 88 ++++++++++------------- net/mac80211/iface.c | 4 +- net/mac80211/mesh.c | 3 +- net/mac80211/mesh_hwmp.c | 2 +- net/mac80211/mesh_pathtbl.c | 2 +- net/mac80211/mesh_plink.c | 2 +- net/mac80211/mesh_sync.c | 2 +- net/mac80211/mlme.c | 131 +++++++++++++++------------------- net/mac80211/rx.c | 22 +++--- net/mac80211/sta_info.c | 21 +++--- net/mac80211/status.c | 2 +- net/mac80211/tkip.c | 21 +++--- net/mac80211/tx.c | 14 ++-- 17 files changed, 181 insertions(+), 227 deletions(-) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 26ddb699d693..ec55f42705b7 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -75,17 +75,16 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG - "Rx BA session stop requested for %pM tid %u %s reason: %d\n", - sta->sta.addr, tid, - initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", - (int)reason); + pr_debug("Rx BA session stop requested for %pM tid %u %s reason: %d\n", + sta->sta.addr, tid, + initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", + (int)reason); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, &sta->sta, tid, NULL, 0)) - printk(KERN_DEBUG "HW problem - can not stop rx " - "aggregation for tid %d\n", tid); + pr_debug("HW problem - can not stop rx aggregation for tid %d\n", + tid); /* check if this is a self generated aggregation halt */ if (initiator == WLAN_BACK_RECIPIENT && tx) @@ -156,7 +155,7 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) } #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); + pr_debug("rx session timer expired on tid %d\n", (u16)*ptid); #endif set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); @@ -245,8 +244,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Suspend in progress. " - "Denying ADDBA request\n"); + pr_debug("Suspend in progress - Denying ADDBA request\n"); #endif goto end_no_lock; } @@ -320,7 +318,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, &sta->sta, tid, &start_seq_num, 0); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); + pr_debug("Rx A-MPDU request on tid %d result %d\n", tid, ret); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (ret) { diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 7cf07158805c..90b2c0ffd5b0 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -185,8 +185,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, spin_unlock_bh(&sta->lock); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", - sta->sta.addr, tid); + pr_debug("Tx BA session stop requested for %pM tid %u\n", + sta->sta.addr, tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ del_timer_sync(&tid_tx->addba_resp_timer); @@ -254,15 +254,14 @@ static void sta_addba_resp_timer_expired(unsigned long data) test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { rcu_read_unlock(); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "timer expired on tid %d but we are not " - "(or no longer) expecting addBA response there\n", - tid); + pr_debug("timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", + tid); #endif return; } #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); + pr_debug("addBA response timer expired on tid %d\n", tid); #endif ieee80211_stop_tx_ba_session(&sta->sta, tid); @@ -373,8 +372,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) &sta->sta, tid, &start_seq_num, 0); if (ret) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "BA request denied - HW unavailable for" - " tid %d\n", tid); + pr_debug("BA request denied - HW unavailable for tid %d\n", + tid); #endif spin_lock_bh(&sta->lock); ieee80211_agg_splice_packets(sdata, tid_tx, tid); @@ -389,7 +388,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) /* activate the timer for the recipient's addBA response */ mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); + pr_debug("activated addBA response timer on tid %d\n", tid); #endif spin_lock_bh(&sta->lock); @@ -438,7 +437,7 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) rcu_read_unlock(); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid); + pr_debug("tx session timer expired on tid %d\n", (u16)*ptid); #endif ieee80211_stop_tx_ba_session(&sta->sta, *ptid); @@ -464,8 +463,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, return -EINVAL; #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", - pubsta->addr, tid); + pr_debug("Open BA session requested for %pM tid %u\n", + pubsta->addr, tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (sdata->vif.type != NL80211_IFTYPE_STATION && @@ -477,8 +476,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "BA sessions blocked. " - "Denying BA session request\n"); + pr_debug("BA sessions blocked - Denying BA session request\n"); #endif return -EINVAL; } @@ -498,8 +496,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && !sta->sta.ht_cap.ht_supported) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "BA request denied - IBSS STA %pM" - "does not advertise HT support\n", pubsta->addr); + pr_debug("BA request denied - IBSS STA %pM does not advertise HT support\n", + pubsta->addr); #endif /* CONFIG_MAC80211_HT_DEBUG */ return -EINVAL; } @@ -521,10 +519,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + HT_AGG_RETRIES_PERIOD)) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "BA request denied - " - "waiting a grace period after %d failed requests " - "on tid %u\n", - sta->ampdu_mlme.addba_req_num[tid], tid); + pr_debug("BA request denied - waiting a grace period after %d failed requests on tid %u\n", + sta->ampdu_mlme.addba_req_num[tid], tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ ret = -EBUSY; goto err_unlock_sta; @@ -534,8 +530,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, /* check if the TID is not in aggregation flow already */ if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "BA request denied - session is not " - "idle on tid %u\n", tid); + pr_debug("BA request denied - session is not idle on tid %u\n", + tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ ret = -EAGAIN; goto err_unlock_sta; @@ -592,7 +588,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid); + pr_debug("Aggregation is on for tid %d\n", tid); #endif drv_ampdu_action(local, sta->sdata, @@ -628,8 +624,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) if (tid >= STA_TID_NUM) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", - tid, STA_TID_NUM); + pr_debug("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); #endif return; } @@ -639,7 +634,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) if (!sta) { mutex_unlock(&local->sta_mtx); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Could not find station: %pM\n", ra); + pr_debug("Could not find station: %pM\n", ra); #endif return; } @@ -649,7 +644,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) if (WARN_ON(!tid_tx)) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "addBA was not requested!\n"); + pr_debug("addBA was not requested!\n"); #endif goto unlock; } @@ -751,15 +746,13 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) if (tid >= STA_TID_NUM) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", - tid, STA_TID_NUM); + pr_debug("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); #endif return; } #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n", - ra, tid); + pr_debug("Stopping Tx BA session for %pM tid %d\n", ra, tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ mutex_lock(&local->sta_mtx); @@ -767,7 +760,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) sta = sta_info_get_bss(sdata, ra); if (!sta) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Could not find station: %pM\n", ra); + pr_debug("Could not find station: %pM\n", ra); #endif goto unlock; } @@ -778,7 +771,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); + pr_debug("unexpected callback to A-MPDU stop\n"); #endif goto unlock_sta; } @@ -856,7 +849,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); + pr_debug("wrong addBA response token, tid %d\n", tid); #endif goto out; } @@ -864,7 +857,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, del_timer_sync(&tid_tx->addba_resp_timer); #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); + pr_debug("switched off addBA timer for tid %d\n", tid); #endif /* @@ -875,9 +868,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG - "got addBA resp for tid %d but we already gave up\n", - tid); + pr_debug("got addBA resp for tid %d but we already gave up\n", + tid); #endif goto out; } diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7ad542363f0b..f099cf4d12bc 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2679,7 +2679,7 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG - printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer); + pr_debug("TDLS mgmt action %d peer %pM\n", action_code, peer); #endif skb = dev_alloc_skb(local->hw.extra_tx_headroom + @@ -2790,7 +2790,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG - printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer); + pr_debug("TDLS oper %d peer %pM\n", oper, peer); #endif switch (oper) { diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 7ed433c66d68..1a3b36154e73 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -685,6 +685,6 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) sprintf(buf, "netdev:%s", sdata->name); if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) - printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " + pr_err("mac80211: debugfs: failed to rename debugfs " "dir to %s\n", buf); } diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 33d9d0c3e3d0..148c27553024 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -282,9 +282,8 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, return sta_info_get(sdata, addr); if (auth) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM" - "(auth_transaction=1)\n", sdata->vif.addr, - sdata->u.ibss.bssid, addr); + pr_debug("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", + sdata->vif.addr, sdata->u.ibss.bssid, addr); #endif ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, addr, sdata->u.ibss.bssid, NULL, 0, 0); @@ -356,9 +355,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) return; #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM." - "(auth_transaction=%d)\n", - sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); + pr_debug("%s: RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", + sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, + auth_transaction); #endif sta_info_destroy_addr(sdata, mgmt->sa); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); @@ -423,13 +422,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, if (sta->sta.supp_rates[band] != prev_rates) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG - "%s: updated supp_rates set " - "for %pM based on beacon" - "/probe_resp (0x%x -> 0x%x)\n", - sdata->name, sta->sta.addr, - prev_rates, - sta->sta.supp_rates[band]); + pr_debug("%s: updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", + sdata->name, sta->sta.addr, + prev_rates, + sta->sta.supp_rates[band]); #endif rates_updated = true; } @@ -546,20 +542,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, } #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" - "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", - mgmt->sa, mgmt->bssid, - (unsigned long long)rx_timestamp, - (unsigned long long)beacon_timestamp, - (unsigned long long)(rx_timestamp - beacon_timestamp), - jiffies); + pr_debug("RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", + mgmt->sa, mgmt->bssid, + (unsigned long long)rx_timestamp, + (unsigned long long)beacon_timestamp, + (unsigned long long)(rx_timestamp - beacon_timestamp), + jiffies); #endif if (beacon_timestamp > rx_timestamp) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: beacon TSF higher than " - "local TSF - IBSS merge with BSSID %pM\n", - sdata->name, mgmt->bssid); + pr_debug("%s: beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", + sdata->name, mgmt->bssid); #endif ieee80211_sta_join_ibss(sdata, bss); supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); @@ -662,8 +656,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) if (ifibss->fixed_channel) return; - printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " - "IBSS networks with same SSID (merge)\n", sdata->name); + pr_debug("%s: No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n", + sdata->name); ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len, NULL); @@ -691,8 +685,8 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) bssid[0] |= 0x02; } - printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", - sdata->name, bssid); + pr_debug("%s: Creating new IBSS network, BSSID %pM\n", + sdata->name, bssid); capability = WLAN_CAPABILITY_IBSS; @@ -724,8 +718,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) active_ibss = ieee80211_sta_active_ibss(sdata); #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", - sdata->name, active_ibss); + pr_debug("%s: sta_find_ibss (active_ibss=%d)\n", + sdata->name, active_ibss); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (active_ibss) @@ -750,13 +744,12 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) bss = (void *)cbss->priv; #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG " sta_find_ibss: selected %pM current " - "%pM\n", cbss->bssid, ifibss->bssid); + pr_debug(" sta_find_ibss: selected %pM current %pM\n", + cbss->bssid, ifibss->bssid); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" - " based on configured SSID\n", - sdata->name, cbss->bssid); + pr_debug("%s: Selected IBSS BSSID %pM based on configured SSID\n", + sdata->name, cbss->bssid); ieee80211_sta_join_ibss(sdata, bss); ieee80211_rx_bss_put(local, bss); @@ -764,14 +757,14 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) } #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG " did not try to join ibss\n"); + pr_debug(" did not try to join ibss\n"); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ /* Selected IBSS not found in current scan results - try to scan */ if (time_after(jiffies, ifibss->last_scan_completed + IEEE80211_SCAN_INTERVAL)) { - printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " - "join\n", sdata->name); + pr_debug("%s: Trigger new scan to find an IBSS to join\n", + sdata->name); ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len, @@ -785,9 +778,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) ieee80211_sta_create_ibss(sdata); return; } - printk(KERN_DEBUG "%s: IBSS not allowed on" - " %d MHz\n", sdata->name, - local->hw.conf.channel->center_freq); + pr_debug("%s: IBSS not allowed on %d MHz\n", + sdata->name, + local->hw.conf.channel->center_freq); /* No IBSS found - decrease scan interval and continue * scanning. */ @@ -823,10 +816,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, tx_last_beacon = drv_tx_last_beacon(local); #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" - " (tx_last_beacon=%d)\n", - sdata->name, mgmt->sa, mgmt->da, - mgmt->bssid, tx_last_beacon); + pr_debug("%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", + sdata->name, mgmt->sa, mgmt->da, + mgmt->bssid, tx_last_beacon); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) @@ -841,9 +833,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, if (pos[0] != WLAN_EID_SSID || pos + 2 + pos[1] > end) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " - "from %pM\n", - sdata->name, mgmt->sa); + pr_debug("%s: Invalid SSID IE in ProbeReq from %pM\n", + sdata->name, mgmt->sa); #endif return; } @@ -862,8 +853,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, resp = (struct ieee80211_mgmt *) skb->data; memcpy(resp->da, mgmt->sa, ETH_ALEN); #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", - sdata->name, resp->da); + pr_debug("%s: Sending ProbeResp to %pM\n", sdata->name, resp->da); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; ieee80211_tx_skb(sdata, skb); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index f970e0b3c4b9..bebc45db9c7a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -58,7 +58,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); + pr_debug("%s: setting MTU %d\n", dev->name, new_mtu); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ dev->mtu = new_mtu; return 0; @@ -1226,7 +1226,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { /* not a contiguous mask ... not handled now! */ - printk(KERN_DEBUG "not contiguous\n"); + pr_debug("not contiguous\n"); break; } diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2913113c5833..7cf19509fb68 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -524,8 +524,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, bool free_plinks; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: running mesh housekeeping\n", - sdata->name); + pr_debug("%s: running mesh housekeeping\n", sdata->name); #endif ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 9b59658e8650..fa7c58035246 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -15,7 +15,7 @@ #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG #define mhwmp_dbg(fmt, args...) \ - printk(KERN_DEBUG "Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) + pr_debug("Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) #else #define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) #endif diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index b39224d8255c..572f706fd65b 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -19,7 +19,7 @@ #include "mesh.h" #ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG -#define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) +#define mpath_dbg(fmt, args...) pr_debug(fmt, ##args) #else #define mpath_dbg(fmt, args...) do { (void)(0); } while (0) #endif diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 60ef235c9d9b..be4fad128c34 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -14,7 +14,7 @@ #include "mesh.h" #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG -#define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) +#define mpl_dbg(fmt, args...) pr_debug(fmt, ##args) #else #define mpl_dbg(fmt, args...) do { (void)(0); } while (0) #endif diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 38d30e8ce6dc..0ccdad49f987 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c @@ -14,7 +14,7 @@ #ifdef CONFIG_MAC80211_VERBOSE_MESH_SYNC_DEBUG #define msync_dbg(fmt, args...) \ - printk(KERN_DEBUG "Mesh sync (%s): " fmt "\n", sdata->name, ##args) + pr_debug("Mesh sync (%s): " fmt "\n", sdata->name, ##args) #else #define msync_dbg(fmt, args...) do { (void)(0); } while (0) #endif diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4ef22a49870f..419301c69582 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1656,8 +1656,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); - printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n", - sdata->name, bssid); + pr_debug("%s: Connection to AP %pM lost\n", sdata->name, bssid); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, @@ -1791,8 +1790,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (status_code != WLAN_STATUS_SUCCESS) { - printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n", - sdata->name, mgmt->sa, status_code); + pr_debug("%s: %pM denied authentication (status %d)\n", + sdata->name, mgmt->sa, status_code); ieee80211_destroy_auth_data(sdata, false); return RX_MGMT_CFG80211_RX_AUTH; } @@ -1815,7 +1814,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; } - printk(KERN_DEBUG "%s: authenticated\n", sdata->name); + pr_debug("%s: authenticated\n", sdata->name); ifmgd->auth_data->done = true; ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -1828,8 +1827,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, goto out_err; } if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { - printk(KERN_DEBUG "%s: failed moving %pM to auth\n", - sdata->name, bssid); + pr_debug("%s: failed moving %pM to auth\n", sdata->name, bssid); goto out_err; } mutex_unlock(&sdata->local->sta_mtx); @@ -1863,8 +1861,8 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", - sdata->name, bssid, reason_code); + pr_debug("%s: deauthenticated from %pM (Reason: %u)\n", + sdata->name, bssid, reason_code); ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -1894,8 +1892,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", - sdata->name, mgmt->sa, reason_code); + pr_debug("%s: disassociated from %pM (Reason: %u)\n", + sdata->name, mgmt->sa, reason_code); ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -1987,17 +1985,15 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - printk(KERN_DEBUG - "%s: invalid AID value 0x%x; bits 15:14 not set\n", - sdata->name, aid); + pr_debug("%s: invalid AID value 0x%x; bits 15:14 not set\n", + sdata->name, aid); aid &= ~(BIT(15) | BIT(14)); ifmgd->broken_ap = false; if (aid == 0 || aid > IEEE80211_MAX_AID) { - printk(KERN_DEBUG - "%s: invalid AID value %d (out of range), turn off PS\n", - sdata->name, aid); + pr_debug("%s: invalid AID value %d (out of range), turn off PS\n", + sdata->name, aid); aid = 0; ifmgd->broken_ap = true; } @@ -2006,8 +2002,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.supp_rates) { - printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", - sdata->name); + pr_debug("%s: no SuppRates element in AssocResp\n", + sdata->name); return false; } @@ -2047,9 +2043,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); if (err) { - printk(KERN_DEBUG - "%s: failed to move station %pM to desired state\n", - sdata->name, sta->sta.addr); + pr_debug("%s: failed to move station %pM to desired state\n", + sdata->name, sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); mutex_unlock(&sdata->local->sta_mtx); return false; @@ -2132,10 +2127,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); aid = le16_to_cpu(mgmt->u.assoc_resp.aid); - printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " - "status=%d aid=%d)\n", - sdata->name, reassoc ? "Rea" : "A", mgmt->sa, - capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); + pr_debug("%s: RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", + sdata->name, reassoc ? "Rea" : "A", mgmt->sa, + capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); pos = mgmt->u.assoc_resp.variable; ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); @@ -2146,9 +2140,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, u32 tu, ms; tu = get_unaligned_le32(elems.timeout_int + 1); ms = tu * 1024 / 1000; - printk(KERN_DEBUG "%s: %pM rejected association temporarily; " - "comeback duration %u TU (%u ms)\n", - sdata->name, mgmt->sa, tu, ms); + pr_debug("%s: %pM rejected association temporarily; comeback duration %u TU (%u ms)\n", + sdata->name, mgmt->sa, tu, ms); assoc_data->timeout = jiffies + msecs_to_jiffies(ms); if (ms > IEEE80211_ASSOC_TIMEOUT) run_again(ifmgd, assoc_data->timeout); @@ -2158,11 +2151,11 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, *bss = assoc_data->bss; if (status_code != WLAN_STATUS_SUCCESS) { - printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n", - sdata->name, mgmt->sa, status_code); + pr_debug("%s: %pM denied association (code=%d)\n", + sdata->name, mgmt->sa, status_code); ieee80211_destroy_assoc_data(sdata, false); } else { - printk(KERN_DEBUG "%s: associated\n", sdata->name); + pr_debug("%s: associated\n", sdata->name); if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { /* oops -- internal error -- send timeout for now */ @@ -2270,7 +2263,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { /* got probe response, continue with auth */ - printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); + pr_debug("%s: direct probe responded\n", sdata->name); ifmgd->auth_data->tries = 0; ifmgd->auth_data->timeout = jiffies; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -2631,8 +2624,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) auth_data->tries++; if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { - printk(KERN_DEBUG "%s: authentication with %pM timed out\n", - sdata->name, auth_data->bss->bssid); + pr_debug("%s: authentication with %pM timed out\n", + sdata->name, auth_data->bss->bssid); /* * Most likely AP is not in the range so remove the @@ -2644,9 +2637,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) } if (auth_data->bss->proberesp_ies) { - printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n", - sdata->name, auth_data->bss->bssid, auth_data->tries, - IEEE80211_AUTH_MAX_TRIES); + pr_debug("%s: send auth to %pM (try %d/%d)\n", + sdata->name, auth_data->bss->bssid, auth_data->tries, + IEEE80211_AUTH_MAX_TRIES); auth_data->expected_transaction = 2; ieee80211_send_auth(sdata, 1, auth_data->algorithm, @@ -2656,9 +2649,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) } else { const u8 *ssidie; - printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n", - sdata->name, auth_data->bss->bssid, auth_data->tries, - IEEE80211_AUTH_MAX_TRIES); + pr_debug("%s: direct probe to %pM (try %d/%i)\n", + sdata->name, auth_data->bss->bssid, auth_data->tries, + IEEE80211_AUTH_MAX_TRIES); ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); if (!ssidie) @@ -2686,8 +2679,8 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) assoc_data->tries++; if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { - printk(KERN_DEBUG "%s: association with %pM timed out\n", - sdata->name, assoc_data->bss->bssid); + pr_debug("%s: association with %pM timed out\n", + sdata->name, assoc_data->bss->bssid); /* * Most likely AP is not in the range so remove the @@ -2698,9 +2691,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) return -ETIMEDOUT; } - printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n", - sdata->name, assoc_data->bss->bssid, assoc_data->tries, - IEEE80211_ASSOC_MAX_TRIES); + pr_debug("%s: associate with %pM (try %d/%d)\n", + sdata->name, assoc_data->bss->bssid, assoc_data->tries, + IEEE80211_ASSOC_MAX_TRIES); ieee80211_send_assoc(sdata); assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; @@ -3069,13 +3062,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, * since we look at probe response/beacon data here * it should be OK. */ - printk(KERN_DEBUG - "%s: Wrong control channel: center-freq: %d" - " ht-cfreq: %d ht->primary_chan: %d" - " band: %d. Disabling HT.\n", - sdata->name, cbss->channel->center_freq, - ht_cfreq, ht_oper->primary_chan, - cbss->channel->band); + pr_debug("%s: Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", + sdata->name, cbss->channel->center_freq, + ht_cfreq, ht_oper->primary_chan, + cbss->channel->band); ht_oper = NULL; } } @@ -3099,9 +3089,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, if (!ieee80211_set_channel_type(local, sdata, channel_type)) { /* can only fail due to HT40+/- mismatch */ channel_type = NL80211_CHAN_HT20; - printk(KERN_DEBUG - "%s: disabling 40 MHz due to multi-vif mismatch\n", - sdata->name); + pr_debug("%s: disabling 40 MHz due to multi-vif mismatch\n", + sdata->name); ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); @@ -3130,9 +3119,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, * we can connect -- with a warning. */ if (!basic_rates && min_rate_index >= 0) { - printk(KERN_DEBUG - "%s: No basic rates, using min rate instead.\n", - sdata->name); + pr_debug("%s: No basic rates, using min rate instead\n", + sdata->name); basic_rates = BIT(min_rate_index); } @@ -3158,9 +3146,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, err = sta_info_insert(sta); sta = NULL; if (err) { - printk(KERN_DEBUG - "%s: failed to insert STA entry for the AP (error %d)\n", - sdata->name, err); + pr_debug("%s: failed to insert STA entry for the AP (error %d)\n", + sdata->name, err); return err; } } else @@ -3238,8 +3225,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, if (ifmgd->associated) ieee80211_set_disassoc(sdata, 0, 0, false, NULL); - printk(KERN_DEBUG "%s: authenticate with %pM\n", - sdata->name, req->bss->bssid); + pr_debug("%s: authenticate with %pM\n", sdata->name, req->bss->bssid); err = ieee80211_prep_connection(sdata, req->bss, false); if (err) @@ -3409,8 +3395,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, * Wait up to one beacon interval ... * should this be more if we miss one? */ - printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", - sdata->name, ifmgd->bssid); + pr_debug("%s: waiting for beacon from %pM\n", + sdata->name, ifmgd->bssid); assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); } else { assoc_data->have_beacon = true; @@ -3429,8 +3415,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, corrupt_type = "beacon"; } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) corrupt_type = "probe response"; - printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n", - sdata->name, corrupt_type); + pr_debug("%s: associating with AP with corrupt %s\n", + sdata->name, corrupt_type); } err = 0; @@ -3459,9 +3445,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, return 0; } - printk(KERN_DEBUG - "%s: deauthenticating from %pM by local choice (reason=%d)\n", - sdata->name, req->bssid, req->reason_code); + pr_debug("%s: deauthenticating from %pM by local choice (reason=%d)\n", + sdata->name, req->bssid, req->reason_code); if (ifmgd->associated && ether_addr_equal(ifmgd->associated->bssid, req->bssid)) @@ -3503,8 +3488,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, return -ENOLINK; } - printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", - sdata->name, req->bss->bssid, req->reason_code); + pr_debug("%s: disassociating from %pM by local choice (reason=%d)\n", + sdata->name, req->bss->bssid, req->reason_code); memcpy(bssid, req->bss->bssid, ETH_ALEN); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7bcecf73aafb..6fd2cb0838c4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1137,22 +1137,22 @@ static void ap_sta_ps_start(struct sta_info *sta) if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", - sdata->name, sta->sta.addr, sta->sta.aid); + pr_debug("%s: STA %pM aid %d enters power save mode\n", + sdata->name, sta->sta.addr, sta->sta.aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ } static void ap_sta_ps_end(struct sta_info *sta) { #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", - sta->sdata->name, sta->sta.addr, sta->sta.aid); + pr_debug("%s: STA %pM aid %d exits power save mode\n", + sta->sdata->name, sta->sta.addr, sta->sta.aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", - sta->sdata->name, sta->sta.addr, sta->sta.aid); + pr_debug("%s: STA %pM aid %d driver-ps-blocked\n", + sta->sdata->name, sta->sta.addr, sta->sta.aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ return; } @@ -1387,12 +1387,10 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, #ifdef CONFIG_MAC80211_VERBOSE_DEBUG struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) entry->skb_list.next->data; - printk(KERN_DEBUG "%s: RX reassembly removed oldest " - "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " - "addr1=%pM addr2=%pM\n", - sdata->name, idx, - jiffies - entry->first_frag_time, entry->seq, - entry->last_frag, hdr->addr1, hdr->addr2); + pr_debug("%s: RX reassembly removed oldest fragment entry (idx=%d age=%lu seq=%d last_frag=%d addr1=%pM addr2=%pM\n", + sdata->name, idx, + jiffies - entry->first_frag_time, entry->seq, + entry->last_frag, hdr->addr1, hdr->addr2); #endif __skb_queue_purge(&entry->skb_list); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f5b1638fbf80..4be509807607 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -333,9 +333,8 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, } if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - printk(KERN_DEBUG - "%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway.\n", - sdata->name, sta->sta.addr, state + 1, err); + pr_debug("%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", + sdata->name, sta->sta.addr, state + 1, err); err = 0; } @@ -619,8 +618,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, local->total_ps_buffered--; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", - sta->sta.addr); + pr_debug("Buffered frame expired (STA %pM)\n", sta->sta.addr); #endif dev_kfree_skb(skb); } @@ -890,8 +888,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, if (time_after(jiffies, sta->last_rx + exp_time)) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", - sdata->name, sta->sta.addr); + pr_debug("%s: expiring inactive STA %pM\n", + sdata->name, sta->sta.addr); #endif WARN_ON(__sta_info_destroy(sta)); } @@ -991,9 +989,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) sta_info_recalc_tim(sta); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " - "since STA not sleeping anymore\n", sdata->name, - sta->sta.addr, sta->sta.aid, filtered, buffered); + pr_debug("%s: STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", + sdata->name, sta->sta.addr, sta->sta.aid, filtered, buffered); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ } @@ -1385,8 +1382,8 @@ int sta_info_move_state(struct sta_info *sta, } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: moving STA %pM to state %d\n", - sta->sdata->name, sta->sta.addr, new_state); + pr_debug("%s: moving STA %pM to state %d\n", + sta->sdata->name, sta->sta.addr, new_state); #endif /* diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 28cfa981cfb1..63a769015068 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -589,7 +589,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) /* send frame to monitor interfaces now */ rtap_len = ieee80211_tx_radiotap_len(info); if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { - printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); + pr_err("ieee80211_tx_status: headroom too small\n"); dev_kfree_skb(skb); return; } diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 51077a956a83..68be47ca208f 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -263,12 +263,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, #ifdef CONFIG_MAC80211_TKIP_DEBUG { int i; - printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); + pr_debug("TKIP decrypt: data(len=%zd)", payload_len); for (i = 0; i < payload_len; i++) printk(" %02x", payload[i]); printk("\n"); - printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", - iv16, iv32); + pr_debug("TKIP decrypt: iv16=%04x iv32=%08x\n", iv16, iv32); } #endif @@ -283,11 +282,10 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, (iv32 == key->u.tkip.rx[queue].iv32 && iv16 <= key->u.tkip.rx[queue].iv16))) { #ifdef CONFIG_MAC80211_TKIP_DEBUG - printk(KERN_DEBUG "TKIP replay detected for RX frame from " - "%pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", - ta, - iv32, iv16, key->u.tkip.rx[queue].iv32, - key->u.tkip.rx[queue].iv16); + pr_debug("TKIP replay detected for RX frame from %pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", + ta, iv32, iv16, + key->u.tkip.rx[queue].iv32, + key->u.tkip.rx[queue].iv16); #endif return TKIP_DECRYPT_REPLAY; } @@ -306,13 +304,12 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, { int i; u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; - printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%pM" - " TK=", ta); + pr_debug("TKIP decrypt: Phase1 TA=%pM TK=", ta); for (i = 0; i < 16; i++) printk("%02x ", key->conf.key[key_offset + i]); printk("\n"); - printk(KERN_DEBUG "TKIP decrypt: P1K="); + pr_debug("TKIP decrypt: P1K="); for (i = 0; i < 5; i++) printk("%04x ", key->u.tkip.rx[queue].p1k[i]); printk("\n"); @@ -336,7 +333,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, #ifdef CONFIG_MAC80211_TKIP_DEBUG { int i; - printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); + pr_debug("TKIP decrypt: Phase2 rc4key="); for (i = 0; i < 16; i++) printk("%02x ", rc4key[i]); printk("\n"); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 847215bb2a6f..0c3476530339 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -297,9 +297,8 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) if (unlikely(!assoc && ieee80211_is_data(hdr->frame_control))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: dropped data frame to not " - "associated station %pM\n", - tx->sdata->name, hdr->addr1); + pr_debug("%s: dropped data frame to not associated station %pM\n", + tx->sdata->name, hdr->addr1); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); return TX_DROP; @@ -467,8 +466,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) } #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n", - sta->sta.addr, sta->sta.aid, ac); + pr_debug("STA %pM aid %d: PS buffer for AC %d\n", + sta->sta.addr, sta->sta.aid, ac); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) purge_old_ps_buffers(tx->local); @@ -502,9 +501,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) } #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { - printk(KERN_DEBUG - "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", - tx->sdata->name, sta->sta.addr); + pr_debug("%s: STA %pM in PS mode, but polling/in SP -> send frame\n", + tx->sdata->name, sta->sta.addr); } #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ -- GitLab From d63e9ae3b12fd0c6a3795c9b08de6b476f80b8c3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 May 2012 14:20:31 -0700 Subject: [PATCH 0643/6849] net: mac80211: Add and use ht_vdbg debugging macro Simplify the use of #ifdef CONFIG_MAC80211_HT_DEBUG/#endif by adding a logging macro to encapsulate the test. Convert the appropriate uses too. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- include/net/mac80211.h | 13 ++++++ net/mac80211/agg-rx.c | 24 ++++------ net/mac80211/agg-tx.c | 103 ++++++++++++----------------------------- 3 files changed, 50 insertions(+), 90 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0286c0476e44..808462e2a71d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3844,4 +3844,17 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, */ int ieee80211_ave_rssi(struct ieee80211_vif *vif); +/* Extra debugging macros */ + +#ifdef CONFIG_MAC80211_HT_DEBUG +#define ht_vdbg(fmt, ...) \ + pr_debug(fmt, ##__VA_ARGS__) +#else +#define ht_vdbg(fmt, ...) \ +do { \ + if (0) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) +#endif + #endif /* MAC80211_H */ diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index ec55f42705b7..a096b0dae37d 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -74,12 +74,10 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Rx BA session stop requested for %pM tid %u %s reason: %d\n", - sta->sta.addr, tid, - initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", - (int)reason); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("Rx BA session stop requested for %pM tid %u %s reason: %d\n", + sta->sta.addr, tid, + initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", + (int)reason); if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, &sta->sta, tid, NULL, 0)) @@ -154,9 +152,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) return; } -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("rx session timer expired on tid %d\n", (u16)*ptid); -#endif + ht_vdbg("rx session timer expired on tid %d\n", (u16)*ptid); + set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); } @@ -243,9 +240,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, status = WLAN_STATUS_REQUEST_DECLINED; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Suspend in progress - Denying ADDBA request\n"); -#endif + ht_vdbg("Suspend in progress - Denying ADDBA request\n"); goto end_no_lock; } @@ -317,10 +312,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, &sta->sta, tid, &start_seq_num, 0); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Rx A-MPDU request on tid %d result %d\n", tid, ret); -#endif /* CONFIG_MAC80211_HT_DEBUG */ - + ht_vdbg("Rx A-MPDU request on tid %d result %d\n", tid, ret); if (ret) { kfree(tid_agg_rx->reorder_buf); kfree(tid_agg_rx->reorder_time); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 90b2c0ffd5b0..da07f01cfe4d 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -184,10 +184,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, spin_unlock_bh(&sta->lock); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Tx BA session stop requested for %pM tid %u\n", - sta->sta.addr, tid); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("Tx BA session stop requested for %pM tid %u\n", + sta->sta.addr, tid); del_timer_sync(&tid_tx->addba_resp_timer); del_timer_sync(&tid_tx->session_timer); @@ -253,16 +251,12 @@ static void sta_addba_resp_timer_expired(unsigned long data) if (!tid_tx || test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { rcu_read_unlock(); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", - tid); -#endif + ht_vdbg("timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", + tid); return; } -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("addBA response timer expired on tid %d\n", tid); -#endif + ht_vdbg("addBA response timer expired on tid %d\n", tid); ieee80211_stop_tx_ba_session(&sta->sta, tid); rcu_read_unlock(); @@ -371,10 +365,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, &sta->sta, tid, &start_seq_num, 0); if (ret) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("BA request denied - HW unavailable for tid %d\n", - tid); -#endif + ht_vdbg("BA request denied - HW unavailable for tid %d\n", tid); spin_lock_bh(&sta->lock); ieee80211_agg_splice_packets(sdata, tid_tx, tid); ieee80211_assign_tid_tx(sta, tid, NULL); @@ -387,9 +378,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) /* activate the timer for the recipient's addBA response */ mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("activated addBA response timer on tid %d\n", tid); -#endif + ht_vdbg("activated addBA response timer on tid %d\n", tid); spin_lock_bh(&sta->lock); sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; @@ -436,9 +425,7 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) rcu_read_unlock(); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("tx session timer expired on tid %d\n", (u16)*ptid); -#endif + ht_vdbg("tx session timer expired on tid %d\n", (u16)*ptid); ieee80211_stop_tx_ba_session(&sta->sta, *ptid); } @@ -462,10 +449,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) return -EINVAL; -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Open BA session requested for %pM tid %u\n", - pubsta->addr, tid); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("Open BA session requested for %pM tid %u\n", + pubsta->addr, tid); if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_MESH_POINT && @@ -475,9 +460,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, return -EINVAL; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("BA sessions blocked - Denying BA session request\n"); -#endif + ht_vdbg("BA sessions blocked - Denying BA session request\n"); return -EINVAL; } @@ -495,10 +478,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, */ if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && !sta->sta.ht_cap.ht_supported) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("BA request denied - IBSS STA %pM does not advertise HT support\n", - pubsta->addr); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("BA request denied - IBSS STA %pM does not advertise HT support\n", + pubsta->addr); return -EINVAL; } @@ -518,10 +499,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + HT_AGG_RETRIES_PERIOD)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("BA request denied - waiting a grace period after %d failed requests on tid %u\n", - sta->ampdu_mlme.addba_req_num[tid], tid); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("BA request denied - waiting a grace period after %d failed requests on tid %u\n", + sta->ampdu_mlme.addba_req_num[tid], tid); ret = -EBUSY; goto err_unlock_sta; } @@ -529,10 +508,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); /* check if the TID is not in aggregation flow already */ if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("BA request denied - session is not idle on tid %u\n", - tid); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("BA request denied - session is not idle on tid %u\n", + tid); ret = -EAGAIN; goto err_unlock_sta; } @@ -587,9 +564,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Aggregation is on for tid %d\n", tid); -#endif + ht_vdbg("Aggregation is on for tid %d\n", tid); drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_OPERATIONAL, @@ -623,9 +598,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) trace_api_start_tx_ba_cb(sdata, ra, tid); if (tid >= STA_TID_NUM) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); -#endif + ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); return; } @@ -633,9 +606,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) sta = sta_info_get_bss(sdata, ra); if (!sta) { mutex_unlock(&local->sta_mtx); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Could not find station: %pM\n", ra); -#endif + ht_vdbg("Could not find station: %pM\n", ra); return; } @@ -643,9 +614,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (WARN_ON(!tid_tx)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("addBA was not requested!\n"); -#endif + ht_vdbg("addBA was not requested!\n"); goto unlock; } @@ -745,23 +714,17 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) trace_api_stop_tx_ba_cb(sdata, ra, tid); if (tid >= STA_TID_NUM) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); -#endif + ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); return; } -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Stopping Tx BA session for %pM tid %d\n", ra, tid); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_vdbg("Stopping Tx BA session for %pM tid %d\n", ra, tid); mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, ra); if (!sta) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("Could not find station: %pM\n", ra); -#endif + ht_vdbg("Could not find station: %pM\n", ra); goto unlock; } @@ -770,9 +733,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("unexpected callback to A-MPDU stop\n"); -#endif + ht_vdbg("unexpected callback to A-MPDU stop\n"); goto unlock_sta; } @@ -848,17 +809,13 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, goto out; if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("wrong addBA response token, tid %d\n", tid); -#endif + ht_vdbg("wrong addBA response token, tid %d\n", tid); goto out; } del_timer_sync(&tid_tx->addba_resp_timer); -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("switched off addBA timer for tid %d\n", tid); -#endif + ht_vdbg("switched off addBA timer for tid %d\n", tid); /* * addba_resp_timer may have fired before we got here, and @@ -867,10 +824,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, */ if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - pr_debug("got addBA resp for tid %d but we already gave up\n", - tid); -#endif + ht_vdbg("got addBA resp for tid %d but we already gave up\n", + tid); goto out; } -- GitLab From 499f42bb03a9bd8a23f73e7c3886f70f52e7edc5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 15 May 2012 14:20:32 -0700 Subject: [PATCH 0644/6849] net: mac80211: Add and use ibss_vdbg debugging macro Simplify the use of #ifdef CONFIG_MAC80211_IBSS_DEBUG/#endif by adding a logging macro to encapsulate the test. Convert the appropriate uses too. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- include/net/mac80211.h | 11 ++++++ net/mac80211/ibss.c | 79 +++++++++++++++-------------------------- net/mac80211/sta_info.c | 6 ++-- 3 files changed, 41 insertions(+), 55 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 808462e2a71d..98da61e52a45 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3857,4 +3857,15 @@ do { \ } while (0) #endif +#ifdef CONFIG_MAC80211_IBSS_DEBUG +#define ibss_vdbg(fmt, ...) \ + pr_debug(fmt, ##__VA_ARGS__) +#else +#define ibss_vdbg(fmt, ...) \ +do { \ + if (0) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) +#endif + #endif /* MAC80211_H */ diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 148c27553024..0bc47a825692 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -281,10 +281,8 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, if (sta_info_insert_rcu(sta)) return sta_info_get(sdata, addr); if (auth) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", - sdata->vif.addr, sdata->u.ibss.bssid, addr); -#endif + ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", + sdata->vif.addr, sdata->u.ibss.bssid, addr); ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, addr, sdata->u.ibss.bssid, NULL, 0, 0); } @@ -354,11 +352,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) return; -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", - sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, - auth_transaction); -#endif + ibss_vdbg("%s: RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", + sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, + auth_transaction); sta_info_destroy_addr(sdata, mgmt->sa); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); rcu_read_unlock(); @@ -421,12 +417,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, ieee80211_mandatory_rates(local, band); if (sta->sta.supp_rates[band] != prev_rates) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", - sdata->name, sta->sta.addr, - prev_rates, - sta->sta.supp_rates[band]); -#endif + ibss_vdbg("%s: updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", + sdata->name, sta->sta.addr, + prev_rates, + sta->sta.supp_rates[band]); rates_updated = true; } } else { @@ -541,20 +535,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, rx_timestamp = drv_get_tsf(local, sdata); } -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", - mgmt->sa, mgmt->bssid, - (unsigned long long)rx_timestamp, - (unsigned long long)beacon_timestamp, - (unsigned long long)(rx_timestamp - beacon_timestamp), - jiffies); -#endif + ibss_vdbg("RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", + mgmt->sa, mgmt->bssid, + (unsigned long long)rx_timestamp, + (unsigned long long)beacon_timestamp, + (unsigned long long)(rx_timestamp - beacon_timestamp), + jiffies); if (beacon_timestamp > rx_timestamp) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", - sdata->name, mgmt->bssid); -#endif + ibss_vdbg("%s: beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", + sdata->name, mgmt->bssid); ieee80211_sta_join_ibss(sdata, bss); supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, @@ -717,10 +707,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&ifibss->mtx); active_ibss = ieee80211_sta_active_ibss(sdata); -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: sta_find_ibss (active_ibss=%d)\n", - sdata->name, active_ibss); -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ + ibss_vdbg("%s: sta_find_ibss (active_ibss=%d)\n", + sdata->name, active_ibss); if (active_ibss) return; @@ -743,11 +731,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) struct ieee80211_bss *bss; bss = (void *)cbss->priv; -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug(" sta_find_ibss: selected %pM current %pM\n", - cbss->bssid, ifibss->bssid); -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ - + ibss_vdbg(" sta_find_ibss: selected %pM current %pM\n", + cbss->bssid, ifibss->bssid); pr_debug("%s: Selected IBSS BSSID %pM based on configured SSID\n", sdata->name, cbss->bssid); @@ -756,9 +741,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) return; } -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug(" did not try to join ibss\n"); -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ + ibss_vdbg(" did not try to join ibss\n"); /* Selected IBSS not found in current scan results - try to scan */ if (time_after(jiffies, ifibss->last_scan_completed + @@ -815,11 +798,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, tx_last_beacon = drv_tx_last_beacon(local); -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", - sdata->name, mgmt->sa, mgmt->da, - mgmt->bssid, tx_last_beacon); -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ + ibss_vdbg("%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", + sdata->name, mgmt->sa, mgmt->da, + mgmt->bssid, tx_last_beacon); if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; @@ -832,10 +813,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, pos = mgmt->u.probe_req.variable; if (pos[0] != WLAN_EID_SSID || pos + 2 + pos[1] > end) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: Invalid SSID IE in ProbeReq from %pM\n", - sdata->name, mgmt->sa); -#endif + ibss_vdbg("%s: Invalid SSID IE in ProbeReq from %pM\n", + sdata->name, mgmt->sa); return; } if (pos[1] != 0 && @@ -852,9 +831,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, resp = (struct ieee80211_mgmt *) skb->data; memcpy(resp->da, mgmt->sa, ETH_ALEN); -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: Sending ProbeResp to %pM\n", sdata->name, resp->da); -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ + ibss_vdbg("%s: Sending ProbeResp to %pM\n", sdata->name, resp->da); IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; ieee80211_tx_skb(sdata, skb); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 4be509807607..0a70f797dcf1 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -887,10 +887,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, continue; if (time_after(jiffies, sta->last_rx + exp_time)) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - pr_debug("%s: expiring inactive STA %pM\n", - sdata->name, sta->sta.addr); -#endif + ibss_vdbg("%s: expiring inactive STA %pM\n", + sdata->name, sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); } } -- GitLab From b90bd9d14f866318497acee571f79e621a735d69 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 15 May 2012 15:33:25 -0700 Subject: [PATCH 0645/6849] ath9k: Support ethtool getstats api. This returns many of the values that formerly could only be obtained from debugfs. This should be an improvement when trying to access these counters programatically. Currently this support is only enabled when DEBUGFS is enabled because otherwise these stats are not accumulated. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 134 ++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4de4473776ac..cfbcc047c61e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2389,6 +2389,134 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) return 0; } +#ifdef CONFIG_ATH9K_DEBUGFS + +/* Ethtool support for get-stats */ + +#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" +static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { + "tx_pkts_nic", + "tx_bytes_nic", + "rx_pkts_nic", + "rx_bytes_nic", + AMKSTR(d_tx_pkts), + AMKSTR(d_tx_bytes), + AMKSTR(d_tx_mpdus_queued), + AMKSTR(d_tx_mpdus_completed), + AMKSTR(d_tx_mpdu_xretries), + AMKSTR(d_tx_aggregates), + AMKSTR(d_tx_ampdus_queued_hw), + AMKSTR(d_tx_ampdus_queued_sw), + AMKSTR(d_tx_ampdus_completed), + AMKSTR(d_tx_ampdu_retries), + AMKSTR(d_tx_ampdu_xretries), + AMKSTR(d_tx_fifo_underrun), + AMKSTR(d_tx_op_exceeded), + AMKSTR(d_tx_timer_expiry), + AMKSTR(d_tx_desc_cfg_err), + AMKSTR(d_tx_data_underrun), + AMKSTR(d_tx_delim_underrun), + + "d_rx_decrypt_crc_err", + "d_rx_phy_err", + "d_rx_mic_err", + "d_rx_pre_delim_crc_err", + "d_rx_post_delim_crc_err", + "d_rx_decrypt_busy_err", + + "d_rx_phyerr_radar", + "d_rx_phyerr_ofdm_timing", + "d_rx_phyerr_cck_timing", + +}; +#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats) + +static void ath9k_get_et_strings(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 sset, u8 *data) +{ + if (sset == ETH_SS_STATS) + memcpy(data, *ath9k_gstrings_stats, + sizeof(ath9k_gstrings_stats)); +} + +static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, int sset) +{ + if (sset == ETH_SS_STATS) + return ATH9K_SSTATS_LEN; + return 0; +} + +#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) +#define AWDATA(elem) \ + do { \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ + } while (0) + +#define AWDATA_RX(elem) \ + do { \ + data[i++] = sc->debug.stats.rxstats.elem; \ + } while (0) + +static void ath9k_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + struct ath_softc *sc = hw->priv; + int i = 0; + + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); + AWDATA_RX(rx_pkts_all); + AWDATA_RX(rx_bytes_all); + + AWDATA(tx_pkts_all); + AWDATA(tx_bytes_all); + AWDATA(queued); + AWDATA(completed); + AWDATA(xretries); + AWDATA(a_aggr); + AWDATA(a_queued_hw); + AWDATA(a_queued_sw); + AWDATA(a_completed); + AWDATA(a_retries); + AWDATA(a_xretries); + AWDATA(fifo_underrun); + AWDATA(xtxop); + AWDATA(timer_exp); + AWDATA(desc_cfg_err); + AWDATA(data_underrun); + AWDATA(delim_underrun); + + AWDATA_RX(decrypt_crc_err); + AWDATA_RX(phy_err); + AWDATA_RX(mic_err); + AWDATA_RX(pre_delim_crc_err); + AWDATA_RX(post_delim_crc_err); + AWDATA_RX(decrypt_busy_err); + + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]); + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]); + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]); + + WARN_ON(i != ATH9K_SSTATS_LEN); +} + +/* End of ethtool get-stats functions */ + +#endif + + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2417,4 +2545,10 @@ struct ieee80211_ops ath9k_ops = { .get_stats = ath9k_get_stats, .set_antenna = ath9k_set_antenna, .get_antenna = ath9k_get_antenna, + +#ifdef CONFIG_ATH9K_DEBUGFS + .get_et_sset_count = ath9k_get_et_sset_count, + .get_et_stats = ath9k_get_et_stats, + .get_et_strings = ath9k_get_et_strings, +#endif }; -- GitLab From 51ca9d8db280b960345e7306e6a036dd3880ecff Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 16 May 2012 19:09:48 +0300 Subject: [PATCH 0646/6849] mac80211: remove ieee80211_get_operstate() ieee80211_get_operstate() was used by drivers in order to know whether the sta link is up, but it's no longer needed (nor used) as mac80211 notifies the drivers about authorization changes (via the sta_state callback) Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- include/net/mac80211.h | 10 ---------- net/mac80211/mlme.c | 7 ------- 2 files changed, 17 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 98da61e52a45..d2ed86da8e4c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3555,16 +3555,6 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); -/** - * ieee80211_get_operstate - get the operstate of the vif - * - * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * - * The driver might need to know the operstate of the net_device - * (specifically, whether the link is IF_OPER_UP after resume) - */ -unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif); - /** * ieee80211_chswitch_done - Complete channel switch process * @vif: &struct ieee80211_vif pointer from the add_interface callback. diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 419301c69582..0c4e26ff7d91 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3530,10 +3530,3 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); } EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); - -unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif) -{ - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); - return sdata->dev->operstate; -} -EXPORT_SYMBOL(ieee80211_get_operstate); -- GitLab From ccf91bd678d74e1e98a153539cd07a62991d6610 Mon Sep 17 00:00:00 2001 From: "villacis@palosanto.com" Date: Wed, 16 May 2012 21:07:12 +0200 Subject: [PATCH 0647/6849] rt2x00: Add support for RT5360 based PCI devices. This chip is used at least by the D-Link DWA-525 adapter. Signed-off-by: Alex Villacs Lasso Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 2 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 5 +++++ drivers/net/wireless/rt2x00/rt2800pci.c | 1 + 3 files changed, 8 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9348521e0832..6403f49da419 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -51,6 +51,7 @@ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) + * RF5360 2.4G 1T1R * RF5370 2.4G 1T1R * RF5390 2.4G 1T1R */ @@ -67,6 +68,7 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3053 0x000d +#define RF5360 0x5360 #define RF5370 0x5370 #define RF5372 0x5372 #define RF5390 0x5390 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index dfc90d34be6d..11488e743f08 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2060,6 +2060,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF3052: rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); break; + case RF5360: case RF5370: case RF5372: case RF5390: @@ -2549,6 +2550,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); break; + case RF5360: case RF5370: case RF5372: case RF5390: @@ -4263,6 +4265,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3022: case RF3052: case RF3320: + case RF5360: case RF5370: case RF5372: case RF5390: @@ -4577,6 +4580,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || rt2x00_rf(rt2x00dev, RF3320) || + rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5370) || rt2x00_rf(rt2x00dev, RF5372) || rt2x00_rf(rt2x00dev, RF5390)) { @@ -4662,6 +4666,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3022: case RF3320: case RF3052: + case RF5360: case RF5370: case RF5372: case RF5390: diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cad25bfebd7a..206158b67426 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1188,6 +1188,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x3593) }, #endif #ifdef CONFIG_RT2800PCI_RT53XX + { PCI_DEVICE(0x1814, 0x5360) }, { PCI_DEVICE(0x1814, 0x5362) }, { PCI_DEVICE(0x1814, 0x5390) }, { PCI_DEVICE(0x1814, 0x5392) }, -- GitLab From 726f23fdeb003eee1d2b0eb14503591175746c70 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 16 May 2012 22:40:49 +0200 Subject: [PATCH 0648/6849] iwlwifi: fix prints in iwl_rx_handle The debug prints were wrong and buggy. The HW pointer wasn't printed correctly, it was mixed up with the pointer to the rxbuf. Signed-off-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 08517d3c80bb..1a7eb2a5dec3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -497,7 +497,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) /* Rx interrupt, but nothing sent from uCode */ if (i == r) - IWL_DEBUG_RX(trans, "r = %d, i = %d\n", r, i); + IWL_DEBUG_RX(trans, "HW = SW = %d\n", r); /* calculate total frames need to be restock after handling RX */ total_empty = r - rxq->write_actual; @@ -513,8 +513,8 @@ static void iwl_rx_handle(struct iwl_trans *trans) rxb = rxq->queue[i]; rxq->queue[i] = NULL; - IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb); - + IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", + r, i, rxb); iwl_rx_handle_rxbuf(trans, rxb); i = (i + 1) & RX_QUEUE_MASK; -- GitLab From a35e270881a5db1ec9ac8bc6d61ebc3e85c14f33 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 16 May 2012 22:40:50 +0200 Subject: [PATCH 0649/6849] iwlwifi: fix debug print in iwl_sta_calc_ht_flags We missed passing an argument to the debug print. Fix it. Cc: stable@kernel.org Signed-off-by: Meenakshi Venkataraman Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index aea07aab3c9e..36055ed1c069 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -236,6 +236,7 @@ static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", + sta->addr, (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" : (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? -- GitLab From 142fb5b733d377dedd930ae53332b6a6ccb622f5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:05:09 +0200 Subject: [PATCH 0650/6849] iwlwifi: add __printf argument checking Joe Perches suggested adding the __printf attribute to the __iwl_dbg function to check arguments; add it to all of the logging functions (err, warn, info, dbg and crit.) Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debug.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 8376b842bdba..f6bf91c8f773 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -38,10 +38,10 @@ static inline bool iwl_have_debug_level(u32 level) } void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace, - const char *fmt, ...); -void __iwl_warn(struct device *dev, const char *fmt, ...); -void __iwl_info(struct device *dev, const char *fmt, ...); -void __iwl_crit(struct device *dev, const char *fmt, ...); + const char *fmt, ...) __printf(4, 5); +void __iwl_warn(struct device *dev, const char *fmt, ...) __printf(2, 3); +void __iwl_info(struct device *dev, const char *fmt, ...) __printf(2, 3); +void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3); /* No matter what is m (priv, bus, trans), this will work */ #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a) @@ -52,9 +52,9 @@ void __iwl_crit(struct device *dev, const char *fmt, ...); #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) void __iwl_dbg(struct device *dev, u32 level, bool limit, const char *function, - const char *fmt, ...); + const char *fmt, ...) __printf(5, 6); #else -static inline void +__printf(5, 6) static inline void __iwl_dbg(struct device *dev, u32 level, bool limit, const char *function, const char *fmt, ...) -- GitLab From bc2529c337fe7ea1a37cd5cdc17586f7ef73c4f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 16 May 2012 22:54:22 +0200 Subject: [PATCH 0651/6849] iwlwifi: s/iwlagn_txq_free_tfd/iwl_txq_free_tfd Signed-off-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index e959207c630a..ccb97b9da4c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -346,8 +346,8 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, int tx_fifo_id, bool active); void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); -void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - enum dma_data_direction dma_dir); +void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, + enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, struct sk_buff_head *skbs); int iwl_queue_space(const struct iwl_queue *q); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index a8750238ee09..cf8f3cfff1e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -209,7 +209,7 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, } /** - * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] + * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * @trans - transport private data * @txq - tx queue * @dma_dir - the direction of the DMA mapping @@ -217,8 +217,8 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - enum dma_data_direction dma_dir) +void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, + enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; @@ -979,7 +979,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, iwlagn_txq_inval_byte_cnt_tbl(trans, txq); - iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE); + iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); freed++; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec6fb395b84d..c11911864e62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -435,7 +435,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - iwlagn_txq_free_tfd(trans, txq, dma_dir); + iwl_txq_free_tfd(trans, txq, dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); -- GitLab From eec373f026f445191e6cc4a3fda7eb6b291144b1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 16 May 2012 22:54:23 +0200 Subject: [PATCH 0652/6849] iwlwifi: s/iwlagn_unmap_tfd/iwl_unmap_tfd Signed-off-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- .../net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index cf8f3cfff1e1..e727c4f506c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -178,8 +178,8 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) return tfd->num_tbs & 0x1f; } -static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, - struct iwl_tfd *tfd, enum dma_data_direction dma_dir) +static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, + struct iwl_tfd *tfd, enum dma_data_direction dma_dir) { int i; int num_tbs; @@ -229,8 +229,8 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, lockdep_assert_held(&txq->lock); /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ - iwlagn_unmap_tfd(trans, &txq->entries[idx].meta, - &tfd_tmp[rd_ptr], dma_dir); + iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], + dma_dir); /* free SKB */ if (txq->entries) { @@ -647,9 +647,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) (void *)cmd->data[i], cmd->len[i], DMA_BIDIRECTIONAL); if (dma_mapping_error(trans->dev, phys_addr)) { - iwlagn_unmap_tfd(trans, out_meta, - &txq->tfds[q->write_ptr], - DMA_BIDIRECTIONAL); + iwl_unmap_tfd(trans, out_meta, + &txq->tfds[q->write_ptr], + DMA_BIDIRECTIONAL); idx = -ENOMEM; goto out; } @@ -784,8 +784,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, cmd = txq->entries[cmd_index].cmd; meta = &txq->entries[cmd_index].meta; - iwlagn_unmap_tfd(trans, meta, &txq->tfds[index], - DMA_BIDIRECTIONAL); + iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { -- GitLab From ff110c8f93cb7e2bd83f52a176e33c3573163f0a Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Wed, 16 May 2012 22:54:24 +0200 Subject: [PATCH 0653/6849] iwlwifi: Move IWL_MASK macro to transport. This macro is needed by other transports besides PCIe, thus moving to a common location. Signed-off-by: Gregory Greenman Reviewed-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 -- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index c11911864e62..12d84e9a2d64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -78,8 +78,6 @@ /* FIXME: need to abstract out TX command (once we know what it looks like) */ #include "iwl-commands.h" -#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) - #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ (((1<cfg->base_params->num_of_queues) - 1) &\ (~(1<<(trans_pcie)->cmd_queue))) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 79a1e7ae4995..78b89f1f4b08 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -280,6 +280,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) #define MAX_NO_RECLAIM_CMDS 6 +#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) + /* * Maximum number of HW queues the transport layer * currently supports -- GitLab From 76ed2edd5b2143856915560accf54ca9c1a4c792 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 22:54:25 +0200 Subject: [PATCH 0654/6849] iwlwifi: properly handle device_set_wakeup_enable This is intended to be set whenever wakeup will be needed upon suspend, not only when suspending, so use the new callbacks to set it then. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index ab2f4d7500a4..ff66200b8eaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -417,8 +417,6 @@ int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (ret) goto error; - device_set_wakeup_enable(priv->trans->dev, true); - iwl_trans_wowlan_suspend(priv->trans); goto out; @@ -485,8 +483,6 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) priv->wowlan = false; - device_set_wakeup_enable(priv->trans->dev, false); - iwlagn_prepare_restart(priv); memset((void *)&ctx->active, 0, sizeof(ctx->active)); @@ -501,6 +497,12 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) return 1; } +static void iwlagn_mac_set_wakeup(struct ieee80211_hw *hw, bool enabled) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + + device_set_wakeup_enable(priv->trans->dev, enabled); +} #endif void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) @@ -1581,6 +1583,7 @@ struct ieee80211_ops iwlagn_hw_ops = { #ifdef CONFIG_PM_SLEEP .suspend = iwlagn_mac_suspend, .resume = iwlagn_mac_resume, + .set_wakeup = iwlagn_mac_set_wakeup, #endif .add_interface = iwlagn_mac_add_interface, .remove_interface = iwlagn_mac_remove_interface, -- GitLab From c08ce20c7eedb9406c55a1c59acc2c84812c8e82 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 22:54:26 +0200 Subject: [PATCH 0655/6849] iwlwifi: move IWL_CMD_FAILED_MSK This is common, not uCode API specific, so move it to the transport together with the command header struct definition. Reviewed-by: Meenakshi Venkataraman Reviewed-by: Guy Cohen Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 3 --- drivers/net/wireless/iwlwifi/iwl-trans.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 9af6a239b384..b9f7361d2426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -197,9 +197,6 @@ enum { * *****************************************************************************/ -/* iwl_cmd_header flags value */ -#define IWL_CMD_FAILED_MSK 0x40 - /** * iwlagn rate_n_flags bit fields * diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 78b89f1f4b08..0aeeb7ce91c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -154,6 +154,9 @@ struct iwl_cmd_header { __le16 sequence; } __packed; +/* iwl_cmd_header flags value */ +#define IWL_CMD_FAILED_MSK 0x40 + #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ #define FH_RSCSR_FRAME_INVALID 0x55550000 -- GitLab From cc5f7e39761382d3a44be70bb665c2c78ae15dac Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 16 May 2012 22:54:27 +0200 Subject: [PATCH 0656/6849] iwlwifi: implement dynamic opmode loading This is the next step in splitting up the driver, making the uCode API dependent pieces of it live in separate modules. Right now there's only one so it's not user-selectable, but we're actively working on more. Reviewed-by: Emmanuel Grumbach Signed-off-by: Don Fry Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 5 + drivers/net/wireless/iwlwifi/Makefile | 32 +++--- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +-- drivers/net/wireless/iwlwifi/iwl-debug.c | 6 ++ drivers/net/wireless/iwlwifi/iwl-devtrace.c | 5 + drivers/net/wireless/iwlwifi/iwl-drv.c | 112 +++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-io.c | 19 ++++ drivers/net/wireless/iwlwifi/iwl-op-mode.h | 3 + 8 files changed, 172 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 2463c0626438..727fbb5db9da 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -6,6 +6,7 @@ config IWLWIFI select LEDS_CLASS select LEDS_TRIGGERS select MAC80211_LEDS + select IWLDVM ---help--- Select to build the driver supporting the: @@ -41,6 +42,10 @@ config IWLWIFI say M here and read . The module will be called iwlwifi. +config IWLDVM + tristate "Intel Wireless WiFi" + depends on IWLWIFI + menu "Debugging Options" depends on IWLWIFI diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index d615eacbf050..f284ea850bb2 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,27 +1,31 @@ +# DVM +obj-$(CONFIG_IWLDVM) += iwldvm.o +iwldvm-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o +iwldvm-objs += iwl-ucode.o iwl-agn-tx.o +iwldvm-objs += iwl-agn-lib.o iwl-agn-calib.o +iwldvm-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o +iwldvm-objs += iwl-eeprom.o iwl-power.o +iwldvm-objs += iwl-scan.o iwl-led.o +iwldvm-objs += iwl-agn-rxon.o iwl-agn-devices.o +iwldvm-objs += iwl-notif-wait.o + +iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o +iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o + +CFLAGS_iwl-devtrace.o := -I$(src) + # WIFI obj-$(CONFIG_IWLWIFI) += iwlwifi.o -iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o -iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwl-debug.o -iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o -iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o - -iwlwifi-objs += iwl-eeprom.o iwl-power.o -iwlwifi-objs += iwl-scan.o iwl-led.o -iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o iwlwifi-objs += iwl-5000.o iwlwifi-objs += iwl-6000.o iwlwifi-objs += iwl-1000.o iwlwifi-objs += iwl-2000.o +iwlwifi-objs += iwl-io.o iwlwifi-objs += iwl-pci.o iwlwifi-objs += iwl-drv.o -iwlwifi-objs += iwl-notif-wait.o +iwlwifi-objs += iwl-debug.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o - -iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o -iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o - -CFLAGS_iwl-devtrace.o := -I$(src) ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ec36e2b020b6..5149e6f72945 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -78,7 +78,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); -MODULE_ALIAS("iwlagn"); void iwl_update_chain_flags(struct iwl_priv *priv) { @@ -2344,24 +2343,25 @@ static int __init iwl_init(void) goto error_rc_register; } - ret = iwl_pci_register_driver(); - if (ret) - goto error_pci_register; + ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops); + if (ret) { + pr_err("Unable to register op_mode: %d\n", ret); + goto error_opmode_register; + } return ret; -error_pci_register: +error_opmode_register: iwlagn_rate_control_unregister(); error_rc_register: kmem_cache_destroy(iwl_tx_cmd_pool); return ret; } +module_init(iwl_init); static void __exit iwl_exit(void) { - iwl_pci_unregister_driver(); + iwl_opmode_deregister("iwldvm"); iwlagn_rate_control_unregister(); kmem_cache_destroy(iwl_tx_cmd_pool); } - module_exit(iwl_exit); -module_init(iwl_init); diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 2d1b42847b9b..0f8fcd1d4fe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -62,6 +62,7 @@ *****************************************************************************/ #include +#include #include "iwl-debug.h" #include "iwl-devtrace.h" @@ -81,8 +82,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ } __iwl_fn(warn) +EXPORT_SYMBOL_GPL(__iwl_warn); __iwl_fn(info) +EXPORT_SYMBOL_GPL(__iwl_info); __iwl_fn(crit) +EXPORT_SYMBOL_GPL(__iwl_crit); void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, const char *fmt, ...) @@ -103,6 +107,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, trace_iwlwifi_err(&vaf); va_end(args); } +EXPORT_SYMBOL_GPL(__iwl_err); #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) void __iwl_dbg(struct device *dev, @@ -125,4 +130,5 @@ void __iwl_dbg(struct device *dev, trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); va_end(args); } +EXPORT_SYMBOL_GPL(__iwl_dbg); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 91f45e71e0a2..70191ddbd8f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -42,4 +42,9 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_info); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_warn); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_crit); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_err); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dbg); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index d742900969ea..cdfdfaec395e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -77,8 +77,33 @@ /* private includes */ #include "iwl-fw-file.h" +/****************************************************************************** + * + * module boiler plate + * + ******************************************************************************/ + +/* + * module name, copyright, version, etc. + */ +#define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux" + +#ifdef CONFIG_IWLWIFI_DEBUG +#define VD "d" +#else +#define VD +#endif + +#define DRV_VERSION IWLWIFI_VERSION VD + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_LICENSE("GPL"); + /** * struct iwl_drv - drv common data + * @list: list of drv structures using this opmode * @fw: the iwl_fw structure * @op_mode: the running op_mode * @trans: transport layer @@ -89,6 +114,7 @@ * @request_firmware_complete: the firmware has been obtained from user space */ struct iwl_drv { + struct list_head list; struct iwl_fw fw; struct iwl_op_mode *op_mode; @@ -102,7 +128,17 @@ struct iwl_drv { struct completion request_firmware_complete; }; +#define DVM_OP_MODE 0 +#define MVM_OP_MODE 1 +static struct iwlwifi_opmode_table { + const char *name; /* name: iwldvm, iwlmvm, etc */ + const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */ + struct list_head drv; /* list of devices using this op_mode */ +} iwlwifi_opmode_table[] = { /* ops set when driver is initialized */ + { .name = "iwldvm", .ops = NULL }, + { .name = "iwlmvm", .ops = NULL }, +}; /* * struct fw_sec: Just for the image parsing proccess. @@ -721,7 +757,6 @@ static int validate_sec_sizes(struct iwl_drv *drv, return 0; } - /** * iwl_ucode_callback - callback when firmware was loaded * @@ -733,6 +768,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) struct iwl_drv *drv = context; struct iwl_fw *fw = &drv->fw; struct iwl_ucode_header *ucode; + struct iwlwifi_opmode_table *op; int err; struct iwl_firmware_pieces pieces; const unsigned int api_max = drv->cfg->ucode_api_max; @@ -863,10 +899,17 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) release_firmware(ucode_raw); complete(&drv->request_firmware_complete); - drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); + op = &iwlwifi_opmode_table[DVM_OP_MODE]; - if (!drv->op_mode) - goto out_free_fw; + /* add this device to the list of devices using this op_mode */ + list_add_tail(&drv->list, &op->drv); + + if (op->ops) { + const struct iwl_op_mode_ops *ops = op->ops; + drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); + } else { + request_module_nowait("%s", op->name); + } return; @@ -938,6 +981,67 @@ struct iwl_mod_params iwlwifi_mod_params = { .auto_agg = true, /* the rest are 0 by default */ }; +EXPORT_SYMBOL_GPL(iwlwifi_mod_params); + +int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) +{ + int i; + struct iwl_drv *drv; + + for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { + if (strcmp(iwlwifi_opmode_table[i].name, name)) + continue; + iwlwifi_opmode_table[i].ops = ops; + list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) + drv->op_mode = ops->start(drv->trans, drv->cfg, + &drv->fw); + return 0; + } + return -EIO; +} +EXPORT_SYMBOL_GPL(iwl_opmode_register); + +void iwl_opmode_deregister(const char *name) +{ + int i; + struct iwl_drv *drv; + + for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { + if (strcmp(iwlwifi_opmode_table[i].name, name)) + continue; + iwlwifi_opmode_table[i].ops = NULL; + + /* call the stop routine for all devices */ + list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) { + if (drv->op_mode) { + iwl_op_mode_stop(drv->op_mode); + drv->op_mode = NULL; + } + } + return; + } +} +EXPORT_SYMBOL_GPL(iwl_opmode_deregister); + +static int __init iwl_drv_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) + INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); + + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); + pr_info(DRV_COPYRIGHT "\n"); + + return iwl_pci_register_driver(); +} +module_init(iwl_drv_init); + +static void __exit iwl_drv_exit(void) +{ + iwl_pci_unregister_driver(); +} +module_exit(iwl_drv_exit); #ifdef CONFIG_IWLWIFI_DEBUG module_param_named(debug, iwlwifi_mod_params.debug_level, uint, diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 081dd34d2387..ee93274214d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -27,6 +27,7 @@ *****************************************************************************/ #include #include +#include #include "iwl-io.h" #include"iwl-csr.h" @@ -52,6 +53,7 @@ void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) __iwl_set_bit(trans, reg, mask); spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_set_bit); void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { @@ -61,6 +63,7 @@ void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) __iwl_clear_bit(trans, reg, mask); spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_clear_bit); int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) @@ -76,6 +79,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, return -ETIMEDOUT; } +EXPORT_SYMBOL_GPL(iwl_poll_bit); int iwl_grab_nic_access_silent(struct iwl_trans *trans) { @@ -117,6 +121,7 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) return 0; } +EXPORT_SYMBOL_GPL(iwl_grab_nic_access_silent); bool iwl_grab_nic_access(struct iwl_trans *trans) { @@ -130,6 +135,7 @@ bool iwl_grab_nic_access(struct iwl_trans *trans) return true; } +EXPORT_SYMBOL_GPL(iwl_grab_nic_access); void iwl_release_nic_access(struct iwl_trans *trans) { @@ -144,6 +150,7 @@ void iwl_release_nic_access(struct iwl_trans *trans) */ mmiowb(); } +EXPORT_SYMBOL_GPL(iwl_release_nic_access); u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { @@ -158,6 +165,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) return value; } +EXPORT_SYMBOL_GPL(iwl_read_direct32); void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) { @@ -170,6 +178,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) } spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_write_direct32); int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout) @@ -185,6 +194,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, return -ETIMEDOUT; } +EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) { @@ -211,6 +221,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 reg) spin_unlock_irqrestore(&trans->reg_lock, flags); return val; } +EXPORT_SYMBOL_GPL(iwl_read_prph); void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { @@ -223,6 +234,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) } spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_write_prph); void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { @@ -236,6 +248,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) } spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_set_bits_prph); void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask) @@ -250,6 +263,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, } spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { @@ -264,6 +278,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) } spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) @@ -281,6 +296,7 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, } spin_unlock_irqrestore(&trans->reg_lock, flags); } +EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_words); u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) { @@ -290,6 +306,7 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) return value; } +EXPORT_SYMBOL_GPL(iwl_read_targ_mem); int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) @@ -310,8 +327,10 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, return result; } +EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_words); int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) { return _iwl_write_targ_mem_words(trans, addr, &val, 1); } +EXPORT_SYMBOL_GPL(iwl_write_targ_mem); diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 4ef742b28e08..cec133c87ad8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -145,6 +145,9 @@ struct iwl_op_mode_ops { void (*wimax_active)(struct iwl_op_mode *op_mode); }; +int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops); +void iwl_opmode_deregister(const char *name); + /** * struct iwl_op_mode - operational mode * -- GitLab From ac91f910455f0ff323d965123b76d112afb49dd6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 22:54:28 +0200 Subject: [PATCH 0657/6849] iwlwifi: move notification wait into core This code is a library to be used by multiple opmodes, so move it into the iwlwifi module. Reviewed-by: Donald H Fry Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index f284ea850bb2..931002738c9f 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -7,7 +7,6 @@ iwldvm-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o iwldvm-objs += iwl-eeprom.o iwl-power.o iwldvm-objs += iwl-scan.o iwl-led.o iwldvm-objs += iwl-agn-rxon.o iwl-agn-devices.o -iwldvm-objs += iwl-notif-wait.o iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o @@ -24,6 +23,7 @@ iwlwifi-objs += iwl-io.o iwlwifi-objs += iwl-pci.o iwlwifi-objs += iwl-drv.o iwlwifi-objs += iwl-debug.o +iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index 0066b899fe5c..5cfed29b1b18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -61,6 +61,7 @@ * *****************************************************************************/ #include +#include #include "iwl-notif-wait.h" @@ -71,6 +72,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) INIT_LIST_HEAD(¬if_wait->notif_waits); init_waitqueue_head(¬if_wait->notif_waitq); } +EXPORT_SYMBOL_GPL(iwl_notification_wait_init); void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt) @@ -115,6 +117,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, if (triggered) wake_up_all(¬if_wait->notif_waitq); } +EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) { @@ -128,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) wake_up_all(¬if_wait->notif_waitq); } - +EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); void iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, @@ -152,6 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, list_add(&wait_entry->list, ¬if_wait->notif_waits); spin_unlock_bh(¬if_wait->notif_wait_lock); } +EXPORT_SYMBOL_GPL(iwl_init_notification_wait); int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, struct iwl_notification_wait *wait_entry, @@ -175,6 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, return -ETIMEDOUT; return 0; } +EXPORT_SYMBOL_GPL(iwl_wait_notification); void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, struct iwl_notification_wait *wait_entry) @@ -183,3 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, list_del(&wait_entry->list); spin_unlock_bh(¬if_wait->notif_wait_lock); } +EXPORT_SYMBOL_GPL(iwl_remove_notification); -- GitLab From 20d3b6475226fbde372b1ce51f26b5379e340759 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 22:54:29 +0200 Subject: [PATCH 0658/6849] iwlwifi: clean up coding style in PCIe transport Mostly clean up indentation around parentheses after if, function calls, etc. and also a few unneeded line breaks and some other things. Reviewed-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- .../net/wireless/iwlwifi/iwl-trans-pcie-int.h | 8 +- .../net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 67 +++--- .../net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 68 +++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 203 +++++++++--------- 4 files changed, 161 insertions(+), 185 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index ccb97b9da4c3..f027769933d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -313,7 +313,7 @@ void iwl_bg_rx_replenish(struct work_struct *data); void iwl_irq_tasklet(struct iwl_trans *trans); void iwlagn_rx_replenish(struct iwl_trans *trans); void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, - struct iwl_rx_queue *q); + struct iwl_rx_queue *q); /***************************************************** * ICT @@ -328,7 +328,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data); * TX / HCMD ******************************************************/ void iwl_txq_update_write_ptr(struct iwl_trans *trans, - struct iwl_tx_queue *txq); + struct iwl_tx_queue *txq); int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, dma_addr_t addr, u16 len, u8 reset); @@ -337,8 +337,8 @@ int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, int handler_status); void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, - struct iwl_tx_queue *txq, - u16 byte_cnt); + struct iwl_tx_queue *txq, + u16 byte_cnt); void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int queue); void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 1a7eb2a5dec3..98605fc7ad37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -130,7 +130,7 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q) * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue */ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, - struct iwl_rx_queue *q) + struct iwl_rx_queue *q) { unsigned long flags; u32 reg; @@ -201,9 +201,7 @@ static inline __le32 iwlagn_dma_addr2rbd_ptr(dma_addr_t dma_addr) */ static void iwlagn_rx_queue_restock(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; struct list_head *element; struct iwl_rx_mem_buffer *rxb; @@ -253,9 +251,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans) */ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; struct list_head *element; struct iwl_rx_mem_buffer *rxb; @@ -278,8 +274,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) gfp_mask |= __GFP_COMP; /* Alloc a new receive buffer */ - page = alloc_pages(gfp_mask, - trans_pcie->rx_page_order); + page = alloc_pages(gfp_mask, trans_pcie->rx_page_order); if (!page) { if (net_ratelimit()) IWL_DEBUG_INFO(trans, "alloc_pages failed, " @@ -315,9 +310,10 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) BUG_ON(rxb->page); rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = dma_map_page(trans->dev, page, 0, - PAGE_SIZE << trans_pcie->rx_page_order, - DMA_FROM_DEVICE); + rxb->page_dma = + dma_map_page(trans->dev, page, 0, + PAGE_SIZE << trans_pcie->rx_page_order, + DMA_FROM_DEVICE); /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -465,8 +461,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, if (rxb->page != NULL) { rxb->page_dma = dma_map_page(trans->dev, rxb->page, 0, - PAGE_SIZE << trans_pcie->rx_page_order, - DMA_FROM_DEVICE); + PAGE_SIZE << trans_pcie->rx_page_order, + DMA_FROM_DEVICE); list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; } else @@ -546,12 +542,12 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ if (trans->cfg->internal_wimax_coex && (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & - APMS_CLK_VAL_MRB_FUNC_MODE) || + APMS_CLK_VAL_MRB_FUNC_MODE) || (iwl_read_prph(trans, APMG_PS_CTRL_REG) & - APMG_PS_CTRL_VAL_RESET_REQ))) { - struct iwl_trans_pcie *trans_pcie; + APMG_PS_CTRL_VAL_RESET_REQ))) { + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); - trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); iwl_op_mode_wimax_active(trans->op_mode); wake_up(&trans->wait_command_queue); @@ -567,6 +563,8 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) /* tasklet for iwlagn interrupt */ void iwl_irq_tasklet(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct isr_statistics *isr_stats = &trans_pcie->isr_stats; u32 inta = 0; u32 handled = 0; unsigned long flags; @@ -575,10 +573,6 @@ void iwl_irq_tasklet(struct iwl_trans *trans) u32 inta_mask; #endif - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct isr_statistics *isr_stats = &trans_pcie->isr_stats; - - spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Ack/clear/reset pending uCode interrupts. @@ -593,7 +587,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * interrupt coalescing can still be achieved. */ iwl_write32(trans, CSR_INT, - trans_pcie->inta | ~trans_pcie->inta_mask); + trans_pcie->inta | ~trans_pcie->inta_mask); inta = trans_pcie->inta; @@ -602,7 +596,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* just for debug */ inta_mask = iwl_read32(trans, CSR_INT_MASK); IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", - inta, inta_mask); + inta, inta_mask); } #endif @@ -651,7 +645,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) hw_rfkill = iwl_is_rfkill_set(trans); IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", - hw_rfkill ? "disable radio" : "enable radio"); + hw_rfkill ? "disable radio" : "enable radio"); isr_stats->rfkill++; @@ -693,7 +687,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * Rx "responses" (frame-received notification), and other * notifications from uCode come through here*/ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX | - CSR_INT_BIT_RX_PERIODIC)) { + CSR_INT_BIT_RX_PERIODIC)) { IWL_DEBUG_ISR(trans, "Rx interrupt\n"); if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); @@ -733,7 +727,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) */ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) iwl_write8(trans, CSR_INT_PERIODIC_REG, - CSR_INT_PERIODIC_ENA); + CSR_INT_PERIODIC_ENA); isr_stats->rx++; } @@ -782,8 +776,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* Free dram table */ void iwl_free_isr_ict(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (trans_pcie->ict_tbl) { dma_free_coherent(trans->dev, ICT_SIZE, @@ -802,8 +795,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans) */ int iwl_alloc_isr_ict(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->ict_tbl = dma_alloc_coherent(trans->dev, ICT_SIZE, @@ -837,10 +829,9 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) */ void iwl_reset_ict(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 val; unsigned long flags; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); if (!trans_pcie->ict_tbl) return; @@ -868,9 +859,7 @@ void iwl_reset_ict(struct iwl_trans *trans) /* Device is going down disable ict interrupt usage */ void iwl_disable_ict(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); unsigned long flags; spin_lock_irqsave(&trans_pcie->irq_lock, flags); @@ -934,7 +923,7 @@ static irqreturn_t iwl_isr(int irq, void *data) if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && - !trans_pcie->inta) + !trans_pcie->inta) iwl_enable_interrupts(trans); unplugged: @@ -945,7 +934,7 @@ static irqreturn_t iwl_isr(int irq, void *data) /* re-enable interrupts here since we don't have anything to service. */ /* only Re-enable if disabled by irq and no schedules tasklet. */ if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && - !trans_pcie->inta) + !trans_pcie->inta) iwl_enable_interrupts(trans); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); @@ -1036,7 +1025,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) inta = (0xff & val) | ((0xff00 & val) << 16); IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", - inta, inta_mask, val); + inta, inta_mask, val); inta &= trans_pcie->inta_mask; trans_pcie->inta |= inta; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index e727c4f506c7..6f601cd05a94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -47,12 +47,11 @@ * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, - struct iwl_tx_queue *txq, - u16 byte_cnt) + struct iwl_tx_queue *txq, + u16 byte_cnt) { struct iwlagn_scd_bc_tbl *scd_bc_tbl; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int write_ptr = txq->q.write_ptr; int txq_id = txq->q.id; u8 sec_ctl = 0; @@ -270,7 +269,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, /* Each TFD can point to a maximum 20 Tx buffers */ if (num_tbs >= IWL_NUM_OF_TBS) { IWL_ERR(trans, "Error can not send more than %d chunks\n", - IWL_NUM_OF_TBS); + IWL_NUM_OF_TBS); return -EINVAL; } @@ -279,7 +278,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, if (unlikely(addr & ~IWL_TX_DMA_MASK)) IWL_ERR(trans, "Unaligned address = %llx\n", - (unsigned long long)addr); + (unsigned long long)addr); iwl_tfd_set_tb(tfd, num_tbs, addr, len); @@ -383,15 +382,13 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, } static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, - u16 txq_id) + u16 txq_id) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 tbl_dw_addr; u32 tbl_dw; u16 scd_q2ratid; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK; tbl_dw_addr = trans_pcie->scd_base_addr + @@ -419,12 +416,11 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); } -void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, - int txq_id, u32 index) +void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) { IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d\n", txq_id, index & 0xff); iwl_write_direct32(trans, HBUS_TARG_WRPTR, - (index & 0xff) | (txq_id << 8)); + (index & 0xff) | (txq_id << 8)); iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); } @@ -615,13 +611,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) } IWL_DEBUG_HC(trans, - "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", - trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), - out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, - q->write_ptr, idx, trans_pcie->cmd_queue); + "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", + trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), + out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), + cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, - DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { idx = -ENOMEM; goto out; @@ -630,8 +626,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) dma_unmap_addr_set(out_meta, mapping, phys_addr); dma_unmap_len_set(out_meta, len, copy_size); - iwlagn_txq_attach_buf_to_tfd(trans, txq, - phys_addr, copy_size, 1); + iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); #ifdef CONFIG_IWLWIFI_DEVICE_TRACING trace_bufs[0] = &out_cmd->hdr; trace_lens[0] = copy_size; @@ -643,8 +638,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) continue; if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - phys_addr = dma_map_single(trans->dev, - (void *)cmd->data[i], + phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], cmd->len[i], DMA_BIDIRECTIONAL); if (dma_mapping_error(trans->dev, phys_addr)) { iwl_unmap_tfd(trans, out_meta, @@ -723,9 +717,10 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, lockdep_assert_held(&txq->lock); if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { - IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " - "index %d is out of range [0-%d] %d %d.\n", __func__, - txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr); + IWL_ERR(trans, + "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", + __func__, txq_id, idx, q->n_bd, + q->write_ptr, q->read_ptr); return; } @@ -733,8 +728,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { if (nfreed++ > 0) { - IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx, - q->write_ptr, q->read_ptr); + IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", + idx, q->write_ptr, q->read_ptr); iwl_op_mode_nic_error(trans->op_mode); } @@ -771,9 +766,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, * in the queue management code. */ if (WARN(txq_id != trans_pcie->cmd_queue, "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", - txq_id, trans_pcie->cmd_queue, sequence, - trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, - trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { + txq_id, trans_pcie->cmd_queue, sequence, + trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, + trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { iwl_print_hex_error(trans, pkt, 32); return; } @@ -869,8 +864,9 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) } ret = wait_event_timeout(trans->wait_command_queue, - !test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status), - HOST_COMPLETE_TIMEOUT); + !test_bit(STATUS_HCMD_ACTIVE, + &trans_pcie->status), + HOST_COMPLETE_TIMEOUT); if (!ret) { if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { struct iwl_tx_queue *txq = @@ -955,10 +951,10 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, if ((index >= q->n_bd) || (iwl_queue_used(q, last_to_free) == 0)) { - IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " - "last_to_free %d is out of range [0-%d] %d %d.\n", - __func__, txq_id, last_to_free, q->n_bd, - q->write_ptr, q->read_ptr); + IWL_ERR(trans, + "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", + __func__, txq_id, last_to_free, q->n_bd, + q->write_ptr, q->read_ptr); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 12d84e9a2d64..02ef48c64011 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -84,8 +84,7 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; struct device *dev = trans->dev; @@ -112,7 +111,7 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) err_rb_stts: dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, - rxq->bd, rxq->bd_dma); + rxq->bd, rxq->bd_dma); memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); rxq->bd = NULL; err_bd: @@ -121,8 +120,7 @@ err_bd: static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; int i; @@ -132,8 +130,8 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].page != NULL) { dma_unmap_page(trans->dev, rxq->pool[i].page_dma, - PAGE_SIZE << trans_pcie->rx_page_order, - DMA_FROM_DEVICE); + PAGE_SIZE << trans_pcie->rx_page_order, + DMA_FROM_DEVICE); __free_pages(rxq->pool[i].page, trans_pcie->rx_page_order); rxq->pool[i].page = NULL; @@ -191,8 +189,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, static int iwl_rx_init(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; int i, err; @@ -234,10 +231,8 @@ static int iwl_rx_init(struct iwl_trans *trans) static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - unsigned long flags; /*if rxq->bd is NULL, it means that nothing has been allocated, @@ -272,11 +267,11 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans) /* stop Rx DMA */ iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, - FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); + FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); } -static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, - struct iwl_dma_ptr *ptr, size_t size) +static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, + struct iwl_dma_ptr *ptr, size_t size) { if (WARN_ON(ptr->addr)) return -EINVAL; @@ -289,8 +284,8 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, return 0; } -static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, - struct iwl_dma_ptr *ptr) +static void iwlagn_free_dma_ptr(struct iwl_trans *trans, + struct iwl_dma_ptr *ptr) { if (unlikely(!ptr->addr)) return; @@ -327,12 +322,12 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) } static int iwl_trans_txq_alloc(struct iwl_trans *trans, - struct iwl_tx_queue *txq, int slots_num, - u32 txq_id) + struct iwl_tx_queue *txq, int slots_num, + u32 txq_id) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; int i; - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (WARN_ON(txq->entries || txq->tfds)) return -EINVAL; @@ -453,6 +448,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; struct device *dev = trans->dev; int i; + if (WARN_ON(!txq)) return; @@ -572,11 +568,11 @@ error: } static int iwl_tx_init(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; int txq_id, slots_num; unsigned long flags; bool alloc = false; - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (!trans_pcie->txq) { ret = iwl_trans_tx_alloc(trans); @@ -641,10 +637,9 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int pos; u16 pci_lnk_ctl; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); struct pci_dev *pci_dev = trans_pcie->pci_dev; @@ -698,14 +693,14 @@ static int iwl_apm_init(struct iwl_trans *trans) /* Disable L0S exit timer (platform NMI Work/Around) */ iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); + CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); /* * Disable L0s without affecting L1; * don't wait for ICH L0s (ICH bug W/A) */ iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); + CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); /* Set FH wait threshold to maximum (HW error during stress W/A) */ iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); @@ -715,7 +710,7 @@ static int iwl_apm_init(struct iwl_trans *trans) * wake device's PCI Express link L1a -> L0s */ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); + CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); iwl_apm_config(trans); @@ -736,8 +731,8 @@ static int iwl_apm_init(struct iwl_trans *trans) * and accesses to uCode SRAM. */ ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) { IWL_DEBUG_INFO(trans, "Failed to init the card\n"); goto out; @@ -771,8 +766,8 @@ static int iwl_apm_stop_master(struct iwl_trans *trans) iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); ret = iwl_poll_bit(trans, CSR_RESET, - CSR_RESET_REG_FLAG_MASTER_DISABLED, - CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); + CSR_RESET_REG_FLAG_MASTER_DISABLED, + CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); if (ret) IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); @@ -814,8 +809,7 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_apm_init(trans); /* Set interrupt coalescing calibration timer to default (512 usecs) */ - iwl_write8(trans, CSR_INT_COALESCING, - IWL_HOST_INT_CALIB_TIMEOUT_DEF); + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); @@ -834,8 +828,7 @@ static int iwl_nic_init(struct iwl_trans *trans) if (trans->cfg->base_params->shadow_reg_enable) { /* enable shadow regs in HW */ - iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, - 0x800FFFFF); + iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); } return 0; @@ -849,13 +842,13 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) int ret; iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); /* See if we got it */ ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, - CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, - HW_READY_TIMEOUT); + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, + HW_READY_TIMEOUT); IWL_DEBUG_INFO(trans, "hardware%s ready\n", ret < 0 ? " not" : ""); return ret; @@ -875,11 +868,11 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans) /* If HW is not ready, prepare the conditions to check again */ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_PREPARE); + CSR_HW_IF_CONFIG_REG_PREPARE); ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, - ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, - CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); + ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, + CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); if (ret < 0) return ret; @@ -906,32 +899,33 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num, trans_pcie->ucode_write_complete = false; iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); iwl_write_direct32(trans, - FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); + FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), + dst_addr); iwl_write_direct32(trans, FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); iwl_write_direct32(trans, - FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), - (iwl_get_dma_hi_addr(phy_addr) - << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); + FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), + (iwl_get_dma_hi_addr(phy_addr) + << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | - FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); + FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | + FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | - FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | + FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", section_num); @@ -1068,7 +1062,7 @@ static void iwl_tx_start(struct iwl_trans *trans) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, - SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); + SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); iwl_write_prph(trans, SCD_AGGR_SEL, 0); /* initiate the queues */ @@ -1089,7 +1083,7 @@ static void iwl_tx_start(struct iwl_trans *trans) } iwl_write_prph(trans, SCD_INTERRUPT_MASK, - IWL_MASK(0, trans->cfg->base_params->num_of_queues)); + IWL_MASK(0, trans->cfg->base_params->num_of_queues)); /* Activate all Tx DMA/FIFO channels */ iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); @@ -1113,7 +1107,7 @@ static void iwl_tx_start(struct iwl_trans *trans) /* Enable L1-Active */ iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, - APMG_PCIDEV_STT_VAL_L1_ACT_DIS); + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) @@ -1127,9 +1121,9 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) */ static int iwl_trans_tx_stop(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ch, txq_id, ret; unsigned long flags; - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); /* Turn off all Tx DMA fifos */ spin_lock_irqsave(&trans_pcie->irq_lock, flags); @@ -1141,13 +1135,13 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, - FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), - 1000); + FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); if (ret < 0) - IWL_ERR(trans, "Failing on timeout while stopping" - " DMA channel %d [0x%08x]", ch, - iwl_read_direct32(trans, - FH_TSSR_TX_STATUS_REG)); + IWL_ERR(trans, + "Failing on timeout while stopping DMA channel %d [0x%08x]", + ch, + iwl_read_direct32(trans, + FH_TSSR_TX_STATUS_REG)); } spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); @@ -1166,8 +1160,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) { - unsigned long flags; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + unsigned long flags; /* tell the device to stop sending interrupts */ spin_lock_irqsave(&trans_pcie->irq_lock, flags); @@ -1197,7 +1191,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) /* Make sure (redundant) we've released our request to stay awake */ iwl_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ iwl_apm_stop(trans); @@ -1271,8 +1265,9 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq->entries[q->write_ptr].cmd = dev_cmd; dev_cmd->hdr.cmd = REPLY_TX; - dev_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | - INDEX_TO_SEQ(q->write_ptr))); + dev_cmd->hdr.sequence = + cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | + INDEX_TO_SEQ(q->write_ptr))); /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_meta = &txq->entries[q->write_ptr].meta; @@ -1337,7 +1332,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, /* take back ownership of DMA buffer to enable update */ dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); @@ -1349,7 +1344,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(trans->dev, &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], @@ -1388,8 +1383,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int err; bool hw_rfkill; @@ -1402,7 +1396,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_alloc_isr_ict(trans); err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, - DRV_NAME, trans); + DRV_NAME, trans); if (err) { IWL_ERR(trans, "Error allocating IRQ %d\n", trans_pcie->irq); @@ -1440,9 +1434,9 @@ error: static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, bool op_mode_leaving) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; unsigned long flags; - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); iwl_apm_stop(trans); @@ -1546,8 +1540,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, void iwl_trans_pcie_free(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); iwl_trans_pcie_tx_free(trans); #ifndef CONFIG_IWLWIFI_IDI @@ -1809,8 +1802,8 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ }; static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) + char __user *user_buf, + size_t count, loff_t *ppos) { struct iwl_trans *trans = file->private_data; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1846,11 +1839,11 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, } static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) { + char __user *user_buf, + size_t count, loff_t *ppos) +{ struct iwl_trans *trans = file->private_data; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; char buf[256]; int pos = 0; @@ -1874,11 +1867,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, static ssize_t iwl_dbgfs_interrupt_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) { - + size_t count, loff_t *ppos) +{ struct iwl_trans *trans = file->private_data; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct isr_statistics *isr_stats = &trans_pcie->isr_stats; int pos = 0; @@ -1936,8 +1928,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, size_t count, loff_t *ppos) { struct iwl_trans *trans = file->private_data; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct isr_statistics *isr_stats = &trans_pcie->isr_stats; char buf[8]; @@ -1957,8 +1948,8 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, } static ssize_t iwl_dbgfs_csr_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { struct iwl_trans *trans = file->private_data; char buf[8]; @@ -1978,8 +1969,8 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, } static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) + char __user *user_buf, + size_t count, loff_t *ppos) { struct iwl_trans *trans = file->private_data; char *buf; @@ -2022,7 +2013,7 @@ DEBUGFS_WRITE_FILE_OPS(fw_restart); * */ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, - struct dentry *dir) + struct dentry *dir) { DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); @@ -2034,9 +2025,10 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, } #else static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, - struct dentry *dir) -{ return 0; } - + struct dentry *dir) +{ + return 0; +} #endif /*CONFIG_IWLWIFI_DEBUGFS */ static const struct iwl_trans_ops trans_ops_pcie = { @@ -2081,7 +2073,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, int err; trans = kzalloc(sizeof(struct iwl_trans) + - sizeof(struct iwl_trans_pcie), GFP_KERNEL); + sizeof(struct iwl_trans_pcie), GFP_KERNEL); if (WARN_ON(!trans)) return NULL; @@ -2097,7 +2089,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, /* W/A - seems to solve weird behavior. We need to remove this if we * don't want to stay in L1 all the time. This wastes a lot of power */ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); + PCIE_LINK_STATE_CLKPM); if (pci_enable_device(pdev)) { err = -ENODEV; @@ -2113,7 +2105,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (!err) err = pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(32)); + DMA_BIT_MASK(32)); /* both attempts failed: */ if (err) { dev_printk(KERN_ERR, &pdev->dev, @@ -2136,13 +2128,13 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, } dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); + "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_base = %p\n", trans_pcie->hw_base); + "pci_resource_base = %p\n", trans_pcie->hw_base); dev_printk(KERN_INFO, &pdev->dev, - "HW Revision ID = 0x%X\n", pdev->revision); + "HW Revision ID = 0x%X\n", pdev->revision); /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ @@ -2151,7 +2143,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, err = pci_enable_msi(pdev); if (err) dev_printk(KERN_ERR, &pdev->dev, - "pci_enable_msi failed(0X%x)", err); + "pci_enable_msi failed(0X%x)", err); trans->dev = &pdev->dev; trans_pcie->irq = pdev->irq; @@ -2183,4 +2175,3 @@ out_no_pci: kfree(trans); return NULL; } - -- GitLab From d38069d1e3989f0358109ee4d4f72bcaf555813e Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 16 May 2012 22:54:30 +0200 Subject: [PATCH 0659/6849] iwlwifi: add debugging to shadow registers and fix typo Add a debugging log when using shadow registers. Also fix a minor typo in this connection. Signed-off-by: Meenakshi Venkataraman Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-config.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 67b28aa7f9be..a52818bbfe98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -143,7 +143,7 @@ enum iwl_led_mode { * @chain_noise_scale: default chain noise scale used for gain computation * @wd_timeout: TX queues watchdog timeout * @max_event_log_size: size of event log buffer size for ucode event logging - * @shadow_reg_enable: HW shadhow register bit + * @shadow_reg_enable: HW shadow register support * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up * @no_idle_support: do not support idle mode */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 02ef48c64011..1e50401023e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -829,6 +829,7 @@ static int iwl_nic_init(struct iwl_trans *trans) if (trans->cfg->base_params->shadow_reg_enable) { /* enable shadow regs in HW */ iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); + IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n"); } return 0; -- GitLab From 35b2a113cb0298d4f9a1263338b456094a414057 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:40:18 +0200 Subject: [PATCH 0660/6849] wireless: remove wext sysfs The only user of this was hal prior to its 0.5.12 release which happened over two years ago, so I'm sure this can be removed without issues. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/feature-removal-schedule.txt | 9 --- net/core/net-sysfs.c | 74 ---------------------- net/wireless/Kconfig | 13 ---- 3 files changed, 96 deletions(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 56000b33340b..0258e3d06280 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -249,15 +249,6 @@ Who: Ravikiran Thirumalai --------------------------- -What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS - (in net/core/net-sysfs.c) -When: 3.5 -Why: Over 1K .text/.data size reduction, data is available in other - ways (ioctls) -Who: Johannes Berg - ---------------------------- - What: sysfs ui for changing p4-clockmod parameters When: September 2009 Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index fdf9e61d0651..72607174ea5a 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -417,72 +417,6 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; - -#ifdef CONFIG_WIRELESS_EXT_SYSFS -/* helper function that does all the locking etc for wireless stats */ -static ssize_t wireless_show(struct device *d, char *buf, - ssize_t (*format)(const struct iw_statistics *, - char *)) -{ - struct net_device *dev = to_net_dev(d); - const struct iw_statistics *iw; - ssize_t ret = -EINVAL; - - if (!rtnl_trylock()) - return restart_syscall(); - if (dev_isalive(dev)) { - iw = get_wireless_stats(dev); - if (iw) - ret = (*format)(iw, buf); - } - rtnl_unlock(); - - return ret; -} - -/* show function template for wireless fields */ -#define WIRELESS_SHOW(name, field, format_string) \ -static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \ -{ \ - return sprintf(buf, format_string, iw->field); \ -} \ -static ssize_t show_iw_##name(struct device *d, \ - struct device_attribute *attr, char *buf) \ -{ \ - return wireless_show(d, buf, format_iw_##name); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL) - -WIRELESS_SHOW(status, status, fmt_hex); -WIRELESS_SHOW(link, qual.qual, fmt_dec); -WIRELESS_SHOW(level, qual.level, fmt_dec); -WIRELESS_SHOW(noise, qual.noise, fmt_dec); -WIRELESS_SHOW(nwid, discard.nwid, fmt_dec); -WIRELESS_SHOW(crypt, discard.code, fmt_dec); -WIRELESS_SHOW(fragment, discard.fragment, fmt_dec); -WIRELESS_SHOW(misc, discard.misc, fmt_dec); -WIRELESS_SHOW(retries, discard.retries, fmt_dec); -WIRELESS_SHOW(beacon, miss.beacon, fmt_dec); - -static struct attribute *wireless_attrs[] = { - &dev_attr_status.attr, - &dev_attr_link.attr, - &dev_attr_level.attr, - &dev_attr_noise.attr, - &dev_attr_nwid.attr, - &dev_attr_crypt.attr, - &dev_attr_fragment.attr, - &dev_attr_retries.attr, - &dev_attr_misc.attr, - &dev_attr_beacon.attr, - NULL -}; - -static struct attribute_group wireless_group = { - .name = "wireless", - .attrs = wireless_attrs, -}; -#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1463,14 +1397,6 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; -#ifdef CONFIG_WIRELESS_EXT_SYSFS - if (net->ieee80211_ptr) - *groups++ = &wireless_group; -#ifdef CONFIG_WIRELESS_EXT - else if (net->wireless_handlers) - *groups++ = &wireless_group; -#endif -#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 2e4444fedbe0..8dba3c60794a 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -119,19 +119,6 @@ config CFG80211_WEXT Enable this option if you need old userspace for wireless extensions with cfg80211-based drivers. -config WIRELESS_EXT_SYSFS - bool "Wireless extensions sysfs files" - depends on WEXT_CORE && SYSFS - help - This option enables the deprecated wireless statistics - files in /sys/class/net/*/wireless/. The same information - is available via the ioctls as well. - - Say N. If you know you have ancient tools requiring it, - like very old versions of hal (prior to 0.5.12 release), - say Y and update the tools as soon as possible as this - option will be removed soon. - config LIB80211 tristate "Common routines for IEEE802.11 drivers" default n -- GitLab From 10bab00afed042c1a38ed5ffb135e2aea5ce1277 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:40:19 +0200 Subject: [PATCH 0661/6849] cfg80211: deprecate CFG80211_WEXT Almost all wireless tools have transitioned to or at least added compatibility with nl80211 so there's no real need for CONFIG_CFG80211_WEXT any more. Mark it for removal, and also change the default to not be enabled. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/feature-removal-schedule.txt | 13 +++++++++++++ net/wireless/Kconfig | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 0258e3d06280..dec901554ef7 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -440,6 +440,19 @@ Who: Hans Verkuil ---------------------------- +What: CONFIG_CFG80211_WEXT +When: as soon as distributions ship new wireless tools, ie. wpa_supplicant 1.0 + and NetworkManager/connman/etc. that are able to use nl80211 +Why: Wireless extensions are deprecated, and userland tools are moving to + using nl80211. New drivers are no longer using wireless extensions, + and while there might still be old drivers, both new drivers and new + userland no longer needs them and they can't be used for an feature + developed in the past couple of years. As such, compatibility with + wireless extensions in new drivers will be removed. +Who: Johannes Berg + +---------------------------- + What: g_file_storage driver When: 3.8 Why: This driver has been superseded by g_mass_storage. diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 8dba3c60794a..4d2b1ec6516f 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -114,7 +114,6 @@ config CFG80211_WEXT bool "cfg80211 wireless extensions compatibility" depends on CFG80211 select WEXT_CORE - default y help Enable this option if you need old userspace for wireless extensions with cfg80211-based drivers. -- GitLab From 9dde64232586bd35c8454615266d209106b73c0f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:43:19 +0200 Subject: [PATCH 0662/6849] mac80211: simplify association HT parameters Instead of passing around the entire HT information IE, extract only the HT parameters field and disable HT if the HT information IE isn't present and well- formed. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/mlme.c | 26 +++++++++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3f3cd50fff16..8c026abcb8d9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -399,7 +399,6 @@ struct ieee80211_mgd_auth_data { struct ieee80211_mgd_assoc_data { struct cfg80211_bss *bss; const u8 *supp_rates; - const u8 *ht_operation_ie; unsigned long timeout; int tries; @@ -414,6 +413,8 @@ struct ieee80211_mgd_assoc_data { bool sent_assoc; bool synced; + u8 ap_ht_param; + size_t ie_len; u8 ie[]; }; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0c4e26ff7d91..7c077158eb88 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -258,12 +258,11 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len, } static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, const u8 *ht_oper_ie, + struct sk_buff *skb, u8 ap_ht_param, struct ieee80211_supported_band *sband, struct ieee80211_channel *channel, enum ieee80211_smps_mode smps) { - struct ieee80211_ht_operation *ht_oper; u8 *pos; u32 flags = channel->flags; u16 cap; @@ -271,21 +270,13 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); - if (!ht_oper_ie) - return; - - if (ht_oper_ie[1] < sizeof(struct ieee80211_ht_operation)) - return; - memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); ieee80211_apply_htcap_overrides(sdata, &ht_cap); - ht_oper = (struct ieee80211_ht_operation *)(ht_oper_ie + 2); - /* determine capability flags */ cap = ht_cap.cap; - switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { + switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: if (flags & IEEE80211_CHAN_NO_HT40PLUS) { cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; @@ -509,7 +500,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) } if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) - ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_operation_ie, + ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, sband, local->oper_channel, ifmgd->ap_smps); /* if present, add any custom non-vendor IEs that go after HT */ @@ -3260,7 +3251,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_bss *bss = (void *)req->bss->priv; struct ieee80211_mgd_assoc_data *assoc_data; struct ieee80211_supported_band *sband; - const u8 *ssidie; + const u8 *ssidie, *ht_ie; int i, err; ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); @@ -3347,8 +3338,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, (local->hw.queues >= IEEE80211_NUM_ACS); assoc_data->supp_rates = bss->supp_rates; assoc_data->supp_rates_len = bss->supp_rates_len; - assoc_data->ht_operation_ie = - ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); + + ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); + if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation)) + assoc_data->ap_ht_param = + ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; + else + ifmgd->flags |= IEEE80211_STA_DISABLE_11N; if (bss->wmm_used && bss->uapsd_supported && (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { -- GitLab From 8a2ac260bb89dc34bd31d694e885164a3b78c4d9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:50:15 +0200 Subject: [PATCH 0663/6849] mac80211: clean up ieee80211_set_channel There's no need for ieee80211_set_channel to check whether a change in configuration happened since ieee80211_hw_config() auto-detects it. Additionally, it's wrong to pretend the HT config for the BSS changed, it didn't, the BSS can't be up & running (AP beaconing etc.) when the channel type is changed anyway. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f099cf4d12bc..bb04f4a707e7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1684,9 +1684,6 @@ static int ieee80211_set_channel(struct wiphy *wiphy, { struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_sub_if_data *sdata = NULL; - struct ieee80211_channel *old_oper; - enum nl80211_channel_type old_oper_type; - enum nl80211_channel_type old_vif_oper_type= NL80211_CHAN_NO_HT; if (netdev) sdata = IEEE80211_DEV_TO_SUB_IF(netdev); @@ -1704,24 +1701,13 @@ static int ieee80211_set_channel(struct wiphy *wiphy, break; } - if (sdata) - old_vif_oper_type = sdata->vif.bss_conf.channel_type; - old_oper_type = local->_oper_channel_type; - if (!ieee80211_set_channel_type(local, sdata, channel_type)) return -EBUSY; - old_oper = local->oper_channel; local->oper_channel = chan; - /* Update driver if changes were actually made. */ - if ((old_oper != local->oper_channel) || - (old_oper_type != local->_oper_channel_type)) - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - - if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR && - old_vif_oper_type != sdata->vif.bss_conf.channel_type) - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); + /* auto-detects changes */ + ieee80211_hw_config(local, 0); return 0; } -- GitLab From 3d9e6e12077d2611749ba3145bc4934aae461425 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:50:16 +0200 Subject: [PATCH 0664/6849] mac80211: move ieee80211_set_channel function Move the set_channel function up so it can be used by other code in this file in the future. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 70 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bb04f4a707e7..9aab849fd6cf 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -674,6 +674,41 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, return ret; } +static int ieee80211_set_channel(struct wiphy *wiphy, + struct net_device *netdev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_sub_if_data *sdata = NULL; + + if (netdev) + sdata = IEEE80211_DEV_TO_SUB_IF(netdev); + + switch (ieee80211_get_channel_mode(local, NULL)) { + case CHAN_MODE_HOPPING: + return -EBUSY; + case CHAN_MODE_FIXED: + if (local->oper_channel != chan) + return -EBUSY; + if (!sdata && local->_oper_channel_type == channel_type) + return 0; + break; + case CHAN_MODE_UNDEFINED: + break; + } + + if (!ieee80211_set_channel_type(local, sdata, channel_type)) + return -EBUSY; + + local->oper_channel = chan; + + /* auto-detects changes */ + ieee80211_hw_config(local, 0); + + return 0; +} + static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, const u8 *resp, size_t resp_len) { @@ -1677,41 +1712,6 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, return 0; } -static int ieee80211_set_channel(struct wiphy *wiphy, - struct net_device *netdev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -{ - struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata = NULL; - - if (netdev) - sdata = IEEE80211_DEV_TO_SUB_IF(netdev); - - switch (ieee80211_get_channel_mode(local, NULL)) { - case CHAN_MODE_HOPPING: - return -EBUSY; - case CHAN_MODE_FIXED: - if (local->oper_channel != chan) - return -EBUSY; - if (!sdata && local->_oper_channel_type == channel_type) - return 0; - break; - case CHAN_MODE_UNDEFINED: - break; - } - - if (!ieee80211_set_channel_type(local, sdata, channel_type)) - return -EBUSY; - - local->oper_channel = chan; - - /* auto-detects changes */ - ieee80211_hw_config(local, 0); - - return 0; -} - #ifdef CONFIG_PM static int ieee80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan) -- GitLab From d58e7e37aac0465b08527adadc8016421bd4060e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:50:17 +0200 Subject: [PATCH 0665/6849] cfg80211: simplify cfg80211_can_beacon_sec_chan API Change cfg80211_can_beacon_sec_chan() to return true if there is no secondary channel to simplify all the current users of it. They all check the channel type before calling the function because it returns false if there's no secondary channel. Also actually document the return value. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 5 ++++- net/mac80211/ibss.c | 3 +-- net/wireless/chan.c | 22 ++++++---------------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0289d4ce7070..a8496f4ff5f1 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3359,11 +3359,14 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, const u8 *frame, size_t len, int freq, int sig_dbm, gfp_t gfp); -/* +/** * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used * @wiphy: the wiphy * @chan: main channel * @channel_type: HT mode + * + * This function returns true if there is no secondary channel or the secondary + * channel can be used for beaconing (i.e. is not a radar channel etc.) */ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, struct ieee80211_channel *chan, diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 0bc47a825692..725cb4be229d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -82,8 +82,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, local->oper_channel = chan; channel_type = ifibss->channel_type; - if (channel_type > NL80211_CHAN_HT20 && - !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) + if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) channel_type = NL80211_CHAN_HT20; if (!ieee80211_set_channel_type(local, sdata, channel_type)) { /* can only fail due to HT40+/- mismatch */ diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 884801ac4dd0..20b87d895722 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -60,7 +60,7 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, diff = -20; break; default: - return false; + return true; } sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); @@ -107,21 +107,11 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev, wdev->iftype == NL80211_IFTYPE_AP || wdev->iftype == NL80211_IFTYPE_AP_VLAN || wdev->iftype == NL80211_IFTYPE_MESH_POINT || - wdev->iftype == NL80211_IFTYPE_P2P_GO)) { - switch (channel_type) { - case NL80211_CHAN_HT40PLUS: - case NL80211_CHAN_HT40MINUS: - if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan, - channel_type)) { - printk(KERN_DEBUG - "cfg80211: Secondary channel not " - "allowed to initiate communication\n"); - return -EINVAL; - } - break; - default: - break; - } + wdev->iftype == NL80211_IFTYPE_P2P_GO) && + !cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan, channel_type)) { + printk(KERN_DEBUG + "cfg80211: Secondary channel not allowed to beacon\n"); + return -EINVAL; } result = rdev->ops->set_channel(&rdev->wiphy, -- GitLab From aa430da41019c1694f6a8e3b8bef1d12ed52b0ad Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:50:18 +0200 Subject: [PATCH 0666/6849] cfg80211: provide channel to start_ap function Instead of setting the channel first and then starting the AP, let cfg80211 store the channel and provide it as one of the AP settings. This means that now you have to set the channel before you can start an AP interface, but since hostapd/wpa_supplicant always do that we're OK with this change. Alternatively, it's now possible to give the channel as an attribute to the start-ap nl80211 command, overriding any preset channel. Cc: Kalle Valo Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 36 ++------------- drivers/net/wireless/ath/ath6kl/core.h | 3 -- drivers/net/wireless/ath/ath6kl/main.c | 1 - include/linux/nl80211.h | 2 + include/net/cfg80211.h | 12 ++++- net/mac80211/cfg.c | 5 ++ net/wireless/nl80211.c | 53 +++++++++++++++++++++- 7 files changed, 72 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index b869a358ce43..f27e9732951d 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2585,35 +2585,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif, return 0; } -static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -{ - struct ath6kl_vif *vif; - - /* - * 'dev' could be NULL if a channel change is required for the hardware - * device itself, instead of a particular VIF. - * - * FIXME: To be handled properly when monitor mode is supported. - */ - if (!dev) - return -EBUSY; - - vif = netdev_priv(dev); - - if (!ath6kl_cfg80211_ready(vif)) - return -EIO; - - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n", - __func__, chan->center_freq, chan->hw_value); - vif->next_chan = chan->center_freq; - vif->next_ch_type = channel_type; - vif->next_ch_band = chan->band; - - return 0; -} - static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, u8 *rsn_capab) { @@ -2791,7 +2762,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, p.ssid_len = vif->ssid_len; memcpy(p.ssid, vif->ssid, vif->ssid_len); p.dot11_auth_mode = vif->dot11_auth_mode; - p.ch = cpu_to_le16(vif->next_chan); + p.ch = cpu_to_le16(info->channel->center_freq); /* Enable uAPSD support by default */ res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); @@ -2815,8 +2786,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, return res; } - if (ath6kl_set_htcap(vif, vif->next_ch_band, - vif->next_ch_type != NL80211_CHAN_NO_HT)) + if (ath6kl_set_htcap(vif, info->channel->band, + info->channel_type != NL80211_CHAN_NO_HT)) return -EIO; /* @@ -3271,7 +3242,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .suspend = __ath6kl_cfg80211_suspend, .resume = __ath6kl_cfg80211_resume, #endif - .set_channel = ath6kl_set_channel, .start_ap = ath6kl_start_ap, .change_beacon = ath6kl_change_beacon, .stop_ap = ath6kl_stop_ap, diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 4d9c6f142698..8443b2a4133e 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -553,9 +553,6 @@ struct ath6kl_vif { u32 last_cancel_roc_id; u32 send_action_id; bool probe_req_report; - u16 next_chan; - enum nl80211_channel_type next_ch_type; - enum ieee80211_band next_ch_band; u16 assoc_bss_beacon_int; u16 listen_intvl_t; u16 bmiss_time_t; diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index e5524470529c..b836f2795114 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -598,7 +598,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) struct ath6kl *ar = vif->ar; - vif->next_chan = channel; vif->profile.ch = cpu_to_le16(channel); switch (vif->nw_type) { diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 6930dddad18a..85e5037a218d 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -170,6 +170,8 @@ * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. + * The channel to use can be set on the interface or be given using the + * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_CHANNEL_TYPE attrs. * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a8496f4ff5f1..a54fb895f613 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -404,6 +404,8 @@ struct cfg80211_beacon_data { * * Used to configure an AP interface. * + * @channel: the channel to start the AP on + * @channel_type: the channel type to use * @beacon: beacon data * @beacon_interval: beacon interval * @dtim_period: DTIM period @@ -417,6 +419,9 @@ struct cfg80211_beacon_data { * @inactivity_timeout: time in seconds to determine station's inactivity. */ struct cfg80211_ap_settings { + struct ieee80211_channel *channel; + enum nl80211_channel_type channel_type; + struct cfg80211_beacon_data beacon; int beacon_interval, dtim_period; @@ -2263,7 +2268,10 @@ struct cfg80211_cached_keys; * @netdev: (private) Used to reference back to the netdev * @current_bss: (private) Used by the internal configuration code * @channel: (private) Used by the internal configuration code to track - * user-set AP, monitor and WDS channels for wireless extensions + * the user-set AP, monitor and WDS channel + * @preset_chan: (private) Used by the internal configuration code to + * track the channel to be used for AP later + * @preset_chantype: (private) the corresponding channel type * @bssid: (private) Used by the internal configuration code * @ssid: (private) Used by the internal configuration code * @ssid_len: (private) Used by the internal configuration code @@ -2314,6 +2322,8 @@ struct wireless_dev { struct cfg80211_internal_bss *current_bss; /* associated / joined */ struct ieee80211_channel *channel; + struct ieee80211_channel *preset_chan; + enum nl80211_channel_type preset_chantype; bool ps; int ps_timeout; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9aab849fd6cf..8e9d525c4653 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -823,6 +823,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, if (old) return -EALREADY; + err = ieee80211_set_channel(wiphy, dev, params->channel, + params->channel_type); + if (err) + return err; + /* * Apply control port protocol, this allows us to * not encrypt dynamic WEP control frames. diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 206465dc0cab..74f4a8f93935 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -921,7 +921,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) goto nla_put_failure; } - CMD(set_channel, SET_CHANNEL); + if (dev->ops->set_channel || dev->ops->start_ap) { + i++; + if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) + goto nla_put_failure; + } CMD(set_wds_peer, SET_WDS_PEER); if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { CMD(tdls_mgmt, TDLS_MGMT); @@ -1170,6 +1174,9 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) * Monitors are special as they are normally slaved to * whatever else is going on, so they behave as though * you tried setting the wiphy channel itself. + * + * For AP/GO modes, it's only for compatibility, you can + * also give the channel to the start-AP command. */ return !wdev || wdev->iftype == NL80211_IFTYPE_AP || @@ -1204,6 +1211,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, struct genl_info *info) { + struct ieee80211_channel *channel; enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; u32 freq; int result; @@ -1221,7 +1229,25 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); mutex_lock(&rdev->devlist_mtx); - if (wdev) { + if (wdev) switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + if (wdev->beacon_interval) { + result = -EBUSY; + break; + } + channel = rdev_freq_to_chan(rdev, freq, channel_type); + if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, + channel, + channel_type)) { + result = -EINVAL; + break; + } + wdev->preset_chan = channel; + wdev->preset_chantype = channel_type; + result = 0; + break; + default: wdev_lock(wdev); result = cfg80211_set_freq(rdev, wdev, freq, channel_type); wdev_unlock(wdev); @@ -2299,6 +2325,29 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); } + if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { + enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; + + if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && + !nl80211_valid_channel_type(info, &channel_type)) + return -EINVAL; + + params.channel = rdev_freq_to_chan(rdev, + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]), + channel_type); + if (!params.channel) + return -EINVAL; + params.channel_type = channel_type; + } else if (wdev->preset_chan) { + params.channel = wdev->preset_chan; + params.channel_type = wdev->preset_chantype; + } else + return -EINVAL; + + if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, + params.channel_type)) + return -EINVAL; + err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); if (!err) wdev->beacon_interval = params.beacon_interval; -- GitLab From 685d12a1929f274bd91497e33b4255fe164ac8ec Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:50:19 +0200 Subject: [PATCH 0667/6849] cfg80211: disallow setting channel on WDS interfaces If it worked (Felix says it doesn't right now), the typical use-case for WDS interfaces would be to be slaved to AP mode interfaces. Therefore, it isn't necessary to set the channel on WDS interfaces. As they don't support powersave or anything like that, they also couldn't use a different channel anyway. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 5 ++--- net/wireless/wext-compat.c | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 74f4a8f93935..089a5204dad5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1166,8 +1166,8 @@ static int parse_txq_params(struct nlattr *tb[], static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) { /* - * You can only set the channel explicitly for AP, mesh - * and WDS type interfaces; all others have their channel + * You can only set the channel explicitly for AP and + * mesh type interfaces; all others have their channel * managed via their respective "establish a connection" * command (connect, join, ...) * @@ -1180,7 +1180,6 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) */ return !wdev || wdev->iftype == NL80211_IFTYPE_AP || - wdev->iftype == NL80211_IFTYPE_WDS || wdev->iftype == NL80211_IFTYPE_MESH_POINT || wdev->iftype == NL80211_IFTYPE_MONITOR || wdev->iftype == NL80211_IFTYPE_P2P_GO; diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 6a6181a673ca..b082fcc26f06 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -796,7 +796,6 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, case NL80211_IFTYPE_ADHOC: return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra); case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); if (freq < 0) -- GitLab From cc1d2806bf06ab92268343d26eb3d8d8f00f8bc9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:50:20 +0200 Subject: [PATCH 0668/6849] cfg80211: provide channel to join_mesh function Just like the AP mode patch, instead of setting the channel and then joining the mesh network, provide the channel to join the network on to the join_mesh() function. Like in AP mode, you can also give the channel to the join-mesh nl80211 command now. Unlike AP mode, it picks a default channel if none was given. As libertas uses mesh mode interfaces but has no join_mesh callback and we can't simply break it, keep some compatibility code for that case and configure the channel directly for it. In the non-libertas case, where we store the channel until join, allow setting it while the interface is down. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 4 ++ net/mac80211/cfg.c | 6 +++ net/wireless/core.h | 7 ++- net/wireless/mesh.c | 91 +++++++++++++++++++++++++++++++++++++- net/wireless/nl80211.c | 43 +++++++++++++----- net/wireless/wext-compat.c | 12 ++++- 6 files changed, 148 insertions(+), 15 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a54fb895f613..4c90c44b8b75 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -831,6 +831,8 @@ struct mesh_config { /** * struct mesh_setup - 802.11s mesh setup configuration + * @channel: the channel to start the mesh network on + * @channel_type: the channel type to use * @mesh_id: the mesh ID * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes * @sync_method: which synchronization method to use @@ -845,6 +847,8 @@ struct mesh_config { * These parameters are fixed when the mesh is created. */ struct mesh_setup { + struct ieee80211_channel *channel; + enum nl80211_channel_type channel_type; const u8 *mesh_id; u8 mesh_id_len; u8 sync_method; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8e9d525c4653..f47af8b3185e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1598,6 +1598,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, err = copy_mesh_setup(ifmsh, setup); if (err) return err; + + err = ieee80211_set_channel(wiphy, dev, setup->channel, + setup->channel_type); + if (err) + return err; + ieee80211_start_mesh(sdata); return 0; diff --git a/net/wireless/core.h b/net/wireless/core.h index 8523f3878677..1d3d24126946 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -303,14 +303,17 @@ extern const struct mesh_config default_mesh_config; extern const struct mesh_setup default_mesh_setup; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const struct mesh_setup *setup, + struct mesh_setup *setup, const struct mesh_config *conf); int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const struct mesh_setup *setup, + struct mesh_setup *setup, const struct mesh_config *conf); int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev); +int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, int freq, + enum nl80211_channel_type channel_type); /* MLME */ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 2749cb86b462..2e3b700eba32 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -65,6 +65,9 @@ const struct mesh_config default_mesh_config = { }; const struct mesh_setup default_mesh_setup = { + /* cfg80211_join_mesh() will pick a channel if needed */ + .channel = NULL, + .channel_type = NL80211_CHAN_NO_HT, .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, .path_metric = IEEE80211_PATH_METRIC_AIRTIME, @@ -75,7 +78,7 @@ const struct mesh_setup default_mesh_setup = { int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const struct mesh_setup *setup, + struct mesh_setup *setup, const struct mesh_config *conf) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -101,6 +104,51 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (!rdev->ops->join_mesh) return -EOPNOTSUPP; + if (!setup->channel) { + /* if no channel explicitly given, use preset channel */ + setup->channel = wdev->preset_chan; + setup->channel_type = wdev->preset_chantype; + } + + if (!setup->channel) { + /* if we don't have that either, use the first usable channel */ + enum ieee80211_band band; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + int i; + + sband = rdev->wiphy.bands[band]; + if (!sband) + continue; + + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; + if (chan->flags & (IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | + IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_RADAR)) + continue; + setup->channel = chan; + break; + } + + if (setup->channel) + break; + } + + /* no usable channel ... */ + if (!setup->channel) + return -EINVAL; + + setup->channel_type = NL80211_CHAN_NO_HT; + } + + if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel, + setup->channel_type)) + return -EINVAL; + err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); if (!err) { memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); @@ -112,7 +160,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev, - const struct mesh_setup *setup, + struct mesh_setup *setup, const struct mesh_config *conf) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -125,6 +173,45 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, return err; } +int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, int freq, + enum nl80211_channel_type channel_type) +{ + struct ieee80211_channel *channel; + + /* + * Workaround for libertas (only!), it puts the interface + * into mesh mode but doesn't implement join_mesh. Instead, + * it is configured via sysfs and then joins the mesh when + * you set the channel. Note that the libertas mesh isn't + * compatible with 802.11 mesh. + */ + if (!rdev->ops->join_mesh) { + int err; + + if (!netif_running(wdev->netdev)) + return -ENETDOWN; + wdev_lock(wdev); + err = cfg80211_set_freq(rdev, wdev, freq, channel_type); + wdev_unlock(wdev); + + return err; + } + + if (wdev->mesh_id_len) + return -EBUSY; + + channel = rdev_freq_to_chan(rdev, freq, channel_type); + if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, + channel, + channel_type)) { + return -EINVAL; + } + wdev->preset_chan = channel; + wdev->preset_chantype = channel_type; + return 0; +} + void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 089a5204dad5..b22f1f876881 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -921,7 +921,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) goto nla_put_failure; } - if (dev->ops->set_channel || dev->ops->start_ap) { + if (dev->ops->set_channel || dev->ops->start_ap || + dev->ops->join_mesh) { i++; if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) goto nla_put_failure; @@ -1166,17 +1167,19 @@ static int parse_txq_params(struct nlattr *tb[], static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) { /* - * You can only set the channel explicitly for AP and - * mesh type interfaces; all others have their channel - * managed via their respective "establish a connection" - * command (connect, join, ...) + * You can only set the channel explicitly for WDS interfaces, + * all others have their channel managed via their respective + * "establish a connection" command (connect, join, ...) + * + * For AP/GO and mesh mode, the channel can be set with the + * channel userspace API, but is only stored and passed to the + * low-level driver when the AP starts or the mesh is joined. + * This is for backward compatibility, userspace can also give + * the channel in the start-ap or join-mesh commands instead. * * Monitors are special as they are normally slaved to * whatever else is going on, so they behave as though * you tried setting the wiphy channel itself. - * - * For AP/GO modes, it's only for compatibility, you can - * also give the channel to the start-AP command. */ return !wdev || wdev->iftype == NL80211_IFTYPE_AP || @@ -1246,6 +1249,9 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, wdev->preset_chantype = channel_type; result = 0; break; + case NL80211_IFTYPE_MESH_POINT: + result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); + break; default: wdev_lock(wdev); result = cfg80211_set_freq(rdev, wdev, freq, channel_type); @@ -1335,8 +1341,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) result = 0; mutex_lock(&rdev->mtx); - } else if (netif_running(netdev) && - nl80211_can_set_dev_channel(netdev->ieee80211_ptr)) + } else if (nl80211_can_set_dev_channel(netdev->ieee80211_ptr)) wdev = netdev->ieee80211_ptr; else wdev = NULL; @@ -6080,6 +6085,24 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) return err; } + if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { + enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; + + if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && + !nl80211_valid_channel_type(info, &channel_type)) + return -EINVAL; + + setup.channel = rdev_freq_to_chan(rdev, + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]), + channel_type); + if (!setup.channel) + return -EINVAL; + setup.channel_type = channel_type; + } else { + /* cfg80211_join_mesh() will sort it out */ + setup.channel = NULL; + } + return cfg80211_join_mesh(rdev, dev, &setup, &cfg); } diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index b082fcc26f06..faeb03548aa4 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -796,7 +796,6 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, case NL80211_IFTYPE_ADHOC: return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra); case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_MESH_POINT: freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); if (freq < 0) return freq; @@ -808,6 +807,17 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, wdev_unlock(wdev); mutex_unlock(&rdev->devlist_mtx); return err; + case NL80211_IFTYPE_MESH_POINT: + freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); + if (freq < 0) + return freq; + if (freq == 0) + return -EINVAL; + mutex_lock(&rdev->devlist_mtx); + err = cfg80211_set_mesh_freq(rdev, wdev, freq, + NL80211_CHAN_NO_HT); + mutex_unlock(&rdev->devlist_mtx); + return err; default: return -EOPNOTSUPP; } -- GitLab From aa4bbbe44880a625ef065f0ebbbcc6adf34e03a6 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 16 May 2012 21:24:54 -0700 Subject: [PATCH 0669/6849] mwifiex: invalidate bss config before setting channel for uAP Mark bss_config parameters as invalid before setting AP channel. This prevents from setting invalid parameters while setting AP channel to FW. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/uap_cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 76dfbc42a732..e9482c97e779 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -416,6 +416,7 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) if (!bss_cfg) return -ENOMEM; + mwifiex_set_sys_config_invalid_data(bss_cfg); bss_cfg->band_cfg = BAND_CONFIG_MANUAL; bss_cfg->channel = channel; -- GitLab From 605b73af3273336b2465962d99a937069710e104 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 16 May 2012 21:24:55 -0700 Subject: [PATCH 0670/6849] mwifiex: support NL80211_HIDDEN_SSID_ZERO_LEN for uAP mwifiex uAP supports NL80211_HIDDEN_SSID_ZERO_LEN type of hidden SSID only. NL80211_HIDDEN_SSID_ZERO_CONTENTS is not supported. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 13 +++++++++++++ drivers/net/wireless/mwifiex/fw.h | 6 ++++++ drivers/net/wireless/mwifiex/uap_cmd.c | 9 +++++++++ 3 files changed, 28 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 87671446e24b..015fec3371a0 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -948,6 +948,19 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, bss_cfg->ssid.ssid_len = params->ssid_len; } + switch (params->hidden_ssid) { + case NL80211_HIDDEN_SSID_NOT_IN_USE: + bss_cfg->bcast_ssid_ctl = 1; + break; + case NL80211_HIDDEN_SSID_ZERO_LEN: + bss_cfg->bcast_ssid_ctl = 0; + break; + case NL80211_HIDDEN_SSID_ZERO_CONTENTS: + /* firmware doesn't support this type of hidden SSID */ + default: + return -EINVAL; + } + if (mwifiex_set_secure_params(priv, bss_cfg, params)) { kfree(bss_cfg); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 9f674bbebe65..561452a5c818 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -122,6 +122,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) +#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) @@ -1209,6 +1210,11 @@ struct host_cmd_tlv_ssid { u8 ssid[0]; } __packed; +struct host_cmd_tlv_bcast_ssid { + struct host_cmd_tlv tlv; + u8 bcast_ctl; +} __packed; + struct host_cmd_tlv_beacon_period { struct host_cmd_tlv tlv; __le16 period; diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index e9482c97e779..8173ab66066d 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -132,6 +132,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_dtim_period *dtim_period; struct host_cmd_tlv_beacon_period *beacon_period; struct host_cmd_tlv_ssid *ssid; + struct host_cmd_tlv_bcast_ssid *bcast_ssid; struct host_cmd_tlv_channel_band *chan_band; struct host_cmd_tlv_frag_threshold *frag_threshold; struct host_cmd_tlv_rts_threshold *rts_threshold; @@ -153,6 +154,14 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) cmd_size += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; + + bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv; + bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID); + bcast_ssid->tlv.len = + cpu_to_le16(sizeof(bcast_ssid->bcast_ctl)); + bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl; + cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid); + tlv += sizeof(struct host_cmd_tlv_bcast_ssid); } if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) { chan_band = (struct host_cmd_tlv_channel_band *)tlv; -- GitLab From fdbfff73408f99799724f583cbc2a0ce3263c6a7 Mon Sep 17 00:00:00 2001 From: Stanislav Yakovlev Date: Thu, 17 May 2012 15:56:35 -0400 Subject: [PATCH 0671/6849] net/wireless: ipw2200: introduce ipw_read_eeprom function We separate reading of device's eeprom content from writing it back to the device's sram. Signed-off-by: Stanislav Yakovlev Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2200.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 0036737fe8e3..254b89223276 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2701,6 +2701,20 @@ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6); } +static void ipw_read_eeprom(struct ipw_priv *priv) +{ + int i; + __le16 *eeprom = (__le16 *) priv->eeprom; + + IPW_DEBUG_TRACE(">>\n"); + + /* read entire contents of eeprom into private buffer */ + for (i = 0; i < 128; i++) + eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i)); + + IPW_DEBUG_TRACE("<<\n"); +} + /* * Either the device driver (i.e. the host) or the firmware can * load eeprom data into the designated region in SRAM. If neither @@ -2712,14 +2726,9 @@ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) static void ipw_eeprom_init_sram(struct ipw_priv *priv) { int i; - __le16 *eeprom = (__le16 *) priv->eeprom; IPW_DEBUG_TRACE(">>\n"); - /* read entire contents of eeprom into private buffer */ - for (i = 0; i < 128; i++) - eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i)); - /* If the data looks correct, then copy it to our private copy. Otherwise let the firmware know to perform the operation @@ -3643,8 +3652,10 @@ static int ipw_load(struct ipw_priv *priv) /* ack fw init done interrupt */ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); - /* read eeprom data and initialize the eeprom region of sram */ + /* read eeprom data */ priv->eeprom_delay = 1; + ipw_read_eeprom(priv); + /* initialize the eeprom region of sram */ ipw_eeprom_init_sram(priv); /* enable interrupts */ -- GitLab From 2281a0f3346ae891e3c2216ad05359e0b7934bf0 Mon Sep 17 00:00:00 2001 From: Jan Ceuleers Date: Tue, 5 Jun 2012 03:42:11 +0000 Subject: [PATCH 0672/6849] gianfar: whitespace cleanup - pointers and multiplications Signed-off-by: Jan Ceuleers Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 0741aded9eb0..5ca7b9eaa84a 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -266,8 +266,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) tx_queue->tx_bd_dma_base = addr; tx_queue->dev = ndev; /* enet DMA only understands physical addresses */ - addr += sizeof(struct txbd8) *tx_queue->tx_ring_size; - vaddr += sizeof(struct txbd8) *tx_queue->tx_ring_size; + addr += sizeof(struct txbd8) * tx_queue->tx_ring_size; + vaddr += sizeof(struct txbd8) * tx_queue->tx_ring_size; } /* Start the rx descriptor ring where the tx ring leaves off */ @@ -276,8 +276,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) rx_queue->rx_bd_base = vaddr; rx_queue->rx_bd_dma_base = addr; rx_queue->dev = ndev; - addr += sizeof (struct rxbd8) * rx_queue->rx_ring_size; - vaddr += sizeof (struct rxbd8) * rx_queue->rx_ring_size; + addr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; + vaddr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; } /* Setup the skbuff rings */ @@ -2590,7 +2590,7 @@ static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, gfar_init_rxbdp(rx_queue, bdp, buf); } -static struct sk_buff * gfar_alloc_skb(struct net_device *dev) +static struct sk_buff *gfar_alloc_skb(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct sk_buff *skb = NULL; @@ -2604,7 +2604,7 @@ static struct sk_buff * gfar_alloc_skb(struct net_device *dev) return skb; } -struct sk_buff * gfar_new_skb(struct net_device *dev) +struct sk_buff *gfar_new_skb(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct sk_buff *skb = NULL; @@ -2728,8 +2728,8 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, } /* gfar_clean_rx_ring() -- Processes each frame in the rx ring - * until the budget/quota has been reached. Returns the number - * of frames handled + * until the budget/quota has been reached. Returns the number + * of frames handled */ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) { -- GitLab From 0977f817df4d0f629952b4c31d650640188b4e45 Mon Sep 17 00:00:00 2001 From: Jan Ceuleers Date: Tue, 5 Jun 2012 03:42:12 +0000 Subject: [PATCH 0673/6849] gianfar: comment cleanup Signed-off-by: Jan Ceuleers Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 155 ++++++++++++----------- 1 file changed, 83 insertions(+), 72 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 5ca7b9eaa84a..314456000335 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1,5 +1,4 @@ -/* - * drivers/net/ethernet/freescale/gianfar.c +/* drivers/net/ethernet/freescale/gianfar.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers @@ -405,7 +404,8 @@ static void gfar_init_mac(struct net_device *ndev) gfar_write(®s->attreli, attrs); /* Start with defaults, and add stashing or locking - * depending on the approprate variables */ + * depending on the approprate variables + */ attrs = ATTR_INIT_SETTINGS; if (priv->bd_stash_en) @@ -652,7 +652,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) priv->num_rx_queues = num_rx_qs; priv->num_grps = 0x0; - /* Init Rx queue filer rule set linked list*/ + /* Init Rx queue filer rule set linked list */ INIT_LIST_HEAD(&priv->rx_list.list); priv->rx_list.count = 0; mutex_init(&priv->rx_queue_access); @@ -960,7 +960,8 @@ static void gfar_detect_errata(struct gfar_private *priv) } /* Set up the ethernet device structure, private data, - * and anything else we need before we start */ + * and anything else we need before we start + */ static int gfar_probe(struct platform_device *ofdev) { u32 tempval; @@ -991,8 +992,9 @@ static int gfar_probe(struct platform_device *ofdev) gfar_detect_errata(priv); - /* Stop the DMA engine now, in case it was running before */ - /* (The firmware could have used it, and left it running). */ + /* Stop the DMA engine now, in case it was running before + * (The firmware could have used it, and left it running). + */ gfar_halt(dev); /* Reset MAC layer */ @@ -1098,7 +1100,8 @@ static int gfar_probe(struct platform_device *ofdev) /* Need to reverse the bit maps as bit_map's MSB is q0 * but, for_each_set_bit parses from right to left, which - * basically reverses the queue numbers */ + * basically reverses the queue numbers + */ for (i = 0; i< priv->num_grps; i++) { priv->gfargrp[i].tx_bit_map = reverse_bitmap( priv->gfargrp[i].tx_bit_map, MAX_TX_QS); @@ -1107,7 +1110,8 @@ static int gfar_probe(struct platform_device *ofdev) } /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values, - * also assign queues to groups */ + * also assign queues to groups + */ for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { priv->gfargrp[grp_idx].num_rx_queues = 0x0; for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map, @@ -1149,7 +1153,7 @@ static int gfar_probe(struct platform_device *ofdev) priv->rx_queue[i]->rxic = DEFAULT_RXIC; } - /* always enable rx filer*/ + /* always enable rx filer */ priv->rx_filer_enable = 1; /* Enable most messages by default */ priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; @@ -1189,8 +1193,9 @@ static int gfar_probe(struct platform_device *ofdev) /* Print out the device info */ netdev_info(dev, "mac: %pM\n", dev->dev_addr); - /* Even more device info helps when determining which kernel */ - /* provided which set of benchmarks. */ + /* Even more device info helps when determining which kernel + * provided which set of benchmarks. + */ netdev_info(dev, "Running with NAPI enabled\n"); for (i = 0; i < priv->num_rx_queues; i++) netdev_info(dev, "RX BD ring size for Q[%d]: %d\n", @@ -1398,8 +1403,7 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) else { phy_interface_t interface = priv->interface; - /* - * This isn't autodetected right now, so it must + /* This isn't autodetected right now, so it must * be set by the device tree or platform code. */ if (interface == PHY_INTERFACE_MODE_RGMII_ID) @@ -1453,8 +1457,7 @@ static int init_phy(struct net_device *dev) return 0; } -/* - * Initialize TBI PHY interface for communicating with the +/* Initialize TBI PHY interface for communicating with the * SERDES lynx PHY on the chip. We communicate with this PHY * through the MDIO bus on each controller, treating it as a * "normal" PHY at the address found in the TBIPA register. We assume @@ -1479,8 +1482,7 @@ static void gfar_configure_serdes(struct net_device *dev) return; } - /* - * If the link is already up, we must already be ok, and don't need to + /* If the link is already up, we must already be ok, and don't need to * configure and reset the TBI<->SerDes link. Maybe U-Boot configured * everything for us? Resetting it takes the link down and requires * several seconds for it to come back. @@ -1554,15 +1556,13 @@ static int __gfar_is_rx_idle(struct gfar_private *priv) { u32 res; - /* - * Normaly TSEC should not hang on GRS commands, so we should + /* Normaly TSEC should not hang on GRS commands, so we should * actually wait for IEVENT_GRSC flag. */ if (likely(!gfar_has_errata(priv, GFAR_ERRATA_A002))) return 0; - /* - * Read the eTSEC register at offset 0xD1C. If bits 7-14 are + /* Read the eTSEC register at offset 0xD1C. If bits 7-14 are * the same as bits 23-30, the eTSEC Rx is assumed to be idle * and the Rx can be safely reset. */ @@ -1718,7 +1718,8 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) } /* If there are any tx skbs or rx skbs still around, free them. - * Then free tx_skbuff and rx_skbuff */ + * Then free tx_skbuff and rx_skbuff + */ static void free_skb_resources(struct gfar_private *priv) { struct gfar_priv_tx_q *tx_queue = NULL; @@ -1827,10 +1828,12 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) int err; /* If the device has multiple interrupts, register for - * them. Otherwise, only register for the one */ + * them. Otherwise, only register for the one + */ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { /* Install our interrupt handlers for Error, - * Transmit, and Receive */ + * Transmit, and Receive + */ if ((err = request_irq(grp->interruptError, gfar_error, 0, grp->int_name_er,grp)) < 0) { netif_err(priv, intr, dev, "Can't get IRQ %d\n", @@ -1914,8 +1917,9 @@ irq_fail: return err; } -/* Called when something needs to use the ethernet device */ -/* Returns 0 for success. */ +/* Called when something needs to use the ethernet device + * Returns 0 for success. + */ static int gfar_enet_open(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); @@ -1970,8 +1974,9 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, */ flags = TXFCB_DEFAULT; - /* Tell the controller what the protocol is */ - /* And provide the already calculated phcs */ + /* Tell the controller what the protocol is + * And provide the already calculated phcs + */ if (ip_hdr(skb)->protocol == IPPROTO_UDP) { flags |= TXFCB_UDP; fcb->phcs = udp_hdr(skb)->check; @@ -1981,7 +1986,8 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, /* l3os is the distance between the start of the * frame (skb->data) and the start of the IP hdr. * l4os is the distance between the start of the - * l3 hdr and the l4 hdr */ + * l3 hdr and the l4 hdr + */ fcb->l3os = (u16)(skb_network_offset(skb) - fcb_length); fcb->l4os = skb_network_header_len(skb); @@ -2008,8 +2014,9 @@ static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base, return skip_txbd(bdp, 1, base, ring_size); } -/* This is called by the kernel when a frame is ready for transmission. */ -/* It is pointed to by the dev->hard_start_xmit function pointer */ +/* This is called by the kernel when a frame is ready for transmission. + * It is pointed to by the dev->hard_start_xmit function pointer + */ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); @@ -2024,8 +2031,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; - /* - * TOE=1 frames larger than 2500 bytes may see excess delays + /* TOE=1 frames larger than 2500 bytes may see excess delays * before start of transmission. */ if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) && @@ -2177,8 +2183,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); - /* - * If time stamping is requested one additional TxBD must be set up. The + /* If time stamping is requested one additional TxBD must be set up. The * first TxBD points to the FCB and must have a data length of * GMAC_FCB_LEN. The second TxBD points to the actual frame data with * the full frame length. @@ -2194,8 +2199,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_sent_queue(txq, skb->len); - /* - * We can work in parallel with gfar_clean_tx_ring(), except + /* We can work in parallel with gfar_clean_tx_ring(), except * when modifying num_txbdfree. Note that we didn't grab the lock * when we were reading the num_txbdfree and checking for available * space, that's because outside of this function it can only grow, @@ -2208,8 +2212,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) */ spin_lock_irqsave(&tx_queue->txlock, flags); - /* - * The powerpc-specific eieio() is used, as wmb() has too strong + /* The powerpc-specific eieio() is used, as wmb() has too strong * semantics (it requires synchronization between cacheable and * uncacheable mappings, which eieio doesn't provide and which we * don't need), thus requiring a more expensive sync instruction. At @@ -2225,7 +2228,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; /* Update the current skb pointer to the next entry we will use - * (wrapping if necessary) */ + * (wrapping if necessary) + */ tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & TX_RING_MOD_MASK(tx_queue->tx_ring_size); @@ -2235,7 +2239,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_queue->num_txbdfree -= (nr_txbds); /* If the next BD still needs to be cleaned up, then the bds - are full. We need to tell the kernel to stop sending us stuff. */ + * are full. We need to tell the kernel to stop sending us stuff. + */ if (!tx_queue->num_txbdfree) { netif_tx_stop_queue(txq); @@ -2365,7 +2370,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) INCREMENTAL_BUFFER_SIZE; /* Only stop and start the controller if it isn't already - * stopped, and we changed something */ + * stopped, and we changed something + */ if ((oldsize != tempsize) && (dev->flags & IFF_UP)) stop_gfar(dev); @@ -2378,7 +2384,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) /* If the mtu is larger than the max size for standard * ethernet frames (ie, a jumbo frame), then set maccfg2 - * to allow huge frames, and to check the length */ + * to allow huge frames, and to check the length + */ tempval = gfar_read(®s->maccfg2); if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || @@ -2464,8 +2471,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) frags = skb_shinfo(skb)->nr_frags; - /* - * When time stamping, one additional TxBD must be freed. + /* When time stamping, one additional TxBD must be freed. * Also, we need to dma_unmap_single() the TxPAL. */ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) @@ -2516,8 +2522,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) bytes_sent += skb->len; - /* - * If there's room in the queue (limit it to rx_buffer_size) + /* If there's room in the queue (limit it to rx_buffer_size) * we add this skb back into the pool, if it's the right size */ if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size && @@ -2561,8 +2566,7 @@ static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp) gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED); __napi_schedule(&gfargrp->napi); } else { - /* - * Clear IEVENT, so interrupts aren't called again + /* Clear IEVENT, so interrupts aren't called again * because of the packets that have already arrived. */ gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK); @@ -2622,8 +2626,7 @@ static inline void count_errors(unsigned short status, struct net_device *dev) struct net_device_stats *stats = &dev->stats; struct gfar_extra_stats *estats = &priv->extra_stats; - /* If the packet was truncated, none of the other errors - * matter */ + /* If the packet was truncated, none of the other errors matter */ if (status & RXBD_TRUNCATED) { stats->rx_length_errors++; @@ -2664,7 +2667,8 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) { /* If valid headers were found, and valid sums * were verified, then we tell the kernel that no - * checksumming is necessary. Otherwise, it is */ + * checksumming is necessary. Otherwise, it is [FIXME] + */ if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) skb->ip_summed = CHECKSUM_UNNECESSARY; else @@ -2672,8 +2676,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) } -/* gfar_process_frame() -- handle one incoming packet if skb - * isn't NULL. */ +/* gfar_process_frame() -- handle one incoming packet if skb isn't NULL. */ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int amount_pull, struct napi_struct *napi) { @@ -2685,8 +2688,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, /* fcb is at the beginning if exists */ fcb = (struct rxfcb *)skb->data; - /* Remove the FCB from the skb */ - /* Remove the padded bytes, if there are any */ + /* Remove the FCB from the skb + * Remove the padded bytes, if there are any + */ if (amount_pull) { skb_record_rx_queue(skb, fcb->rq); skb_pull(skb, amount_pull); @@ -2709,8 +2713,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, /* Tell the skb what kind of packet this is */ skb->protocol = eth_type_trans(skb, dev); - /* - * There's need to check for NETIF_F_HW_VLAN_RX here. + /* There's need to check for NETIF_F_HW_VLAN_RX here. * Even if vlan rx accel is disabled, on some chips * RXFCB_VLN is pseudo randomly set. */ @@ -2831,7 +2834,8 @@ static int gfar_poll(struct napi_struct *napi, int budget) budget_per_queue = budget/num_queues; /* Clear IEVENT, so interrupts aren't called again - * because of the packets that have already arrived */ + * because of the packets that have already arrived + */ gfar_write(®s->ievent, IEVENT_RTX_MASK); while (num_queues && left_over_budget) { @@ -2869,8 +2873,9 @@ static int gfar_poll(struct napi_struct *napi, int budget) gfar_write(®s->imask, IMASK_DEFAULT); - /* If we are coalescing interrupts, update the timer */ - /* Otherwise, clear it */ + /* If we are coalescing interrupts, update the timer + * Otherwise, clear it + */ gfar_configure_coalescing(priv, gfargrp->rx_bit_map, gfargrp->tx_bit_map); } @@ -2879,8 +2884,7 @@ static int gfar_poll(struct napi_struct *napi, int budget) } #ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling 'interrupt' - used by things like netconsole to send skbs +/* Polling 'interrupt' - used by things like netconsole to send skbs * without having to re-enable interrupts. It's not called while * the interrupt routine is executing. */ @@ -2957,7 +2961,8 @@ static void adjust_link(struct net_device *dev) u32 ecntrl = gfar_read(®s->ecntrl); /* Now we make sure that we can be in full duplex mode. - * If not, we operate in half-duplex mode. */ + * If not, we operate in half-duplex mode. + */ if (phydev->duplex != priv->oldduplex) { new_state = 1; if (!(phydev->duplex)) @@ -2983,7 +2988,8 @@ static void adjust_link(struct net_device *dev) ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); /* Reduced mode distinguishes - * between 10 and 100 */ + * between 10 and 100 + */ if (phydev->speed == SPEED_100) ecntrl |= ECNTRL_R100; else @@ -3022,7 +3028,8 @@ static void adjust_link(struct net_device *dev) /* Update the hash table based on the current list of multicast * addresses we subscribe to. Also, change the promiscuity of * the device based on the flags (this function is called - * whenever dev->flags is changed */ + * whenever dev->flags is changed + */ static void gfar_set_multi(struct net_device *dev) { struct netdev_hw_addr *ha; @@ -3084,7 +3091,8 @@ static void gfar_set_multi(struct net_device *dev) /* If we have extended hash tables, we need to * clear the exact match registers to prepare for - * setting them */ + * setting them + */ if (priv->extended_hash) { em_num = GFAR_EM_NUM + 1; gfar_clear_exact_match(dev); @@ -3110,7 +3118,8 @@ static void gfar_set_multi(struct net_device *dev) /* Clears each of the exact match registers to zero, so they - * don't interfere with normal reception */ + * don't interfere with normal reception + */ static void gfar_clear_exact_match(struct net_device *dev) { int idx; @@ -3132,7 +3141,8 @@ static void gfar_clear_exact_match(struct net_device *dev) * hash index which gaddr register to use, and the 5 other bits * indicate which bit (assuming an IBM numbering scheme, which * for PowerPC (tm) is usually the case) in the register holds - * the entry. */ + * the entry. + */ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr) { u32 tempval; @@ -3164,8 +3174,9 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, macptr += num*2; - /* Now copy it into the mac registers backwards, cuz */ - /* little endian is silly */ + /* Now copy it into the mac registers backwards, cuz + * little endian is silly + */ for (idx = 0; idx < ETH_ALEN; idx++) tmpbuf[ETH_ALEN - 1 - idx] = addr[idx]; -- GitLab From bc4598bc076fcafa662c82b8ad3ace2d1b5fbdc1 Mon Sep 17 00:00:00 2001 From: Jan Ceuleers Date: Tue, 5 Jun 2012 03:42:13 +0000 Subject: [PATCH 0674/6849] gianfar: various coding style and whitespace cleanups Signed-off-by: Jan Ceuleers Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 298 ++++++++++++----------- 1 file changed, 154 insertions(+), 144 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 314456000335..ed0b1369a5d9 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -113,7 +113,7 @@ static void gfar_timeout(struct net_device *dev); static int gfar_close(struct net_device *dev); struct sk_buff *gfar_new_skb(struct net_device *dev); static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, - struct sk_buff *skb); + struct sk_buff *skb); static int gfar_set_mac_address(struct net_device *dev); static int gfar_change_mtu(struct net_device *dev, int new_mtu); static irqreturn_t gfar_error(int irq, void *dev_id); @@ -265,8 +265,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) tx_queue->tx_bd_dma_base = addr; tx_queue->dev = ndev; /* enet DMA only understands physical addresses */ - addr += sizeof(struct txbd8) * tx_queue->tx_ring_size; - vaddr += sizeof(struct txbd8) * tx_queue->tx_ring_size; + addr += sizeof(struct txbd8) * tx_queue->tx_ring_size; + vaddr += sizeof(struct txbd8) * tx_queue->tx_ring_size; } /* Start the rx descriptor ring where the tx ring leaves off */ @@ -275,15 +275,16 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) rx_queue->rx_bd_base = vaddr; rx_queue->rx_bd_dma_base = addr; rx_queue->dev = ndev; - addr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; - vaddr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; + addr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; + vaddr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; } /* Setup the skbuff rings */ for (i = 0; i < priv->num_tx_queues; i++) { tx_queue = priv->tx_queue[i]; tx_queue->tx_skbuff = kmalloc(sizeof(*tx_queue->tx_skbuff) * - tx_queue->tx_ring_size, GFP_KERNEL); + tx_queue->tx_ring_size, + GFP_KERNEL); if (!tx_queue->tx_skbuff) { netif_err(priv, ifup, ndev, "Could not allocate tx_skbuff\n"); @@ -297,7 +298,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) for (i = 0; i < priv->num_rx_queues; i++) { rx_queue = priv->rx_queue[i]; rx_queue->rx_skbuff = kmalloc(sizeof(*rx_queue->rx_skbuff) * - rx_queue->rx_ring_size, GFP_KERNEL); + rx_queue->rx_ring_size, + GFP_KERNEL); if (!rx_queue->rx_skbuff) { netif_err(priv, ifup, ndev, @@ -326,15 +328,15 @@ static void gfar_init_tx_rx_base(struct gfar_private *priv) int i; baddr = ®s->tbase0; - for(i = 0; i < priv->num_tx_queues; i++) { + for (i = 0; i < priv->num_tx_queues; i++) { gfar_write(baddr, priv->tx_queue[i]->tx_bd_dma_base); - baddr += 2; + baddr += 2; } baddr = ®s->rbase0; - for(i = 0; i < priv->num_rx_queues; i++) { + for (i = 0; i < priv->num_rx_queues; i++) { gfar_write(baddr, priv->rx_queue[i]->rx_bd_dma_base); - baddr += 2; + baddr += 2; } } @@ -430,12 +432,12 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev) for (i = 0; i < priv->num_rx_queues; i++) { rx_packets += priv->rx_queue[i]->stats.rx_packets; - rx_bytes += priv->rx_queue[i]->stats.rx_bytes; + rx_bytes += priv->rx_queue[i]->stats.rx_bytes; rx_dropped += priv->rx_queue[i]->stats.rx_dropped; } dev->stats.rx_packets = rx_packets; - dev->stats.rx_bytes = rx_bytes; + dev->stats.rx_bytes = rx_bytes; dev->stats.rx_dropped = rx_dropped; for (i = 0; i < priv->num_tx_queues; i++) { @@ -443,7 +445,7 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev) tx_packets += priv->tx_queue[i]->stats.tx_packets; } - dev->stats.tx_bytes = tx_bytes; + dev->stats.tx_bytes = tx_bytes; dev->stats.tx_packets = tx_packets; return &dev->stats; @@ -508,8 +510,8 @@ static bool gfar_is_vlan_on(struct gfar_private *priv) static inline int gfar_uses_fcb(struct gfar_private *priv) { return gfar_is_vlan_on(priv) || - (priv->ndev->features & NETIF_F_RXCSUM) || - (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); + (priv->ndev->features & NETIF_F_RXCSUM) || + (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); } static void free_tx_pointers(struct gfar_private *priv) @@ -554,7 +556,7 @@ static void enable_napi(struct gfar_private *priv) } static int gfar_parse_group(struct device_node *np, - struct gfar_private *priv, const char *model) + struct gfar_private *priv, const char *model) { u32 *queue_mask; @@ -580,15 +582,13 @@ static int gfar_parse_group(struct device_node *np, priv->gfargrp[priv->num_grps].grp_id = priv->num_grps; priv->gfargrp[priv->num_grps].priv = priv; spin_lock_init(&priv->gfargrp[priv->num_grps].grplock); - if(priv->mode == MQ_MG_MODE) { - queue_mask = (u32 *)of_get_property(np, - "fsl,rx-bit-map", NULL); - priv->gfargrp[priv->num_grps].rx_bit_map = - queue_mask ? *queue_mask :(DEFAULT_MAPPING >> priv->num_grps); - queue_mask = (u32 *)of_get_property(np, - "fsl,tx-bit-map", NULL); - priv->gfargrp[priv->num_grps].tx_bit_map = - queue_mask ? *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); + if (priv->mode == MQ_MG_MODE) { + queue_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL); + priv->gfargrp[priv->num_grps].rx_bit_map = queue_mask ? + *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); + queue_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL); + priv->gfargrp[priv->num_grps].tx_bit_map = queue_mask ? + *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); } else { priv->gfargrp[priv->num_grps].rx_bit_map = 0xFF; priv->gfargrp[priv->num_grps].tx_bit_map = 0xFF; @@ -673,7 +673,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) } else { priv->mode = SQ_SG_MODE; err = gfar_parse_group(np, priv, model); - if(err) + if (err) goto err_grp_init; } @@ -730,27 +730,27 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING; mac_addr = of_get_mac_address(np); + if (mac_addr) memcpy(dev->dev_addr, mac_addr, ETH_ALEN); if (model && !strcasecmp(model, "TSEC")) - priv->device_flags = - FSL_GIANFAR_DEV_HAS_GIGABIT | - FSL_GIANFAR_DEV_HAS_COALESCE | - FSL_GIANFAR_DEV_HAS_RMON | - FSL_GIANFAR_DEV_HAS_MULTI_INTR; + priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | + FSL_GIANFAR_DEV_HAS_COALESCE | + FSL_GIANFAR_DEV_HAS_RMON | + FSL_GIANFAR_DEV_HAS_MULTI_INTR; + if (model && !strcasecmp(model, "eTSEC")) - priv->device_flags = - FSL_GIANFAR_DEV_HAS_GIGABIT | - FSL_GIANFAR_DEV_HAS_COALESCE | - FSL_GIANFAR_DEV_HAS_RMON | - FSL_GIANFAR_DEV_HAS_MULTI_INTR | - FSL_GIANFAR_DEV_HAS_PADDING | - FSL_GIANFAR_DEV_HAS_CSUM | - FSL_GIANFAR_DEV_HAS_VLAN | - FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | - FSL_GIANFAR_DEV_HAS_EXTENDED_HASH | - FSL_GIANFAR_DEV_HAS_TIMER; + priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | + FSL_GIANFAR_DEV_HAS_COALESCE | + FSL_GIANFAR_DEV_HAS_RMON | + FSL_GIANFAR_DEV_HAS_MULTI_INTR | + FSL_GIANFAR_DEV_HAS_PADDING | + FSL_GIANFAR_DEV_HAS_CSUM | + FSL_GIANFAR_DEV_HAS_VLAN | + FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH | + FSL_GIANFAR_DEV_HAS_TIMER; ctype = of_get_property(np, "phy-connection-type", NULL); @@ -781,7 +781,7 @@ err_grp_init: } static int gfar_hwtstamp_ioctl(struct net_device *netdev, - struct ifreq *ifr, int cmd) + struct ifreq *ifr, int cmd) { struct hwtstamp_config config; struct gfar_private *priv = netdev_priv(netdev); @@ -851,6 +851,7 @@ static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs) { unsigned int new_bit_map = 0x0; int mask = 0x1 << (max_qs - 1), i; + for (i = 0; i < max_qs; i++) { if (bit_map & mask) new_bit_map = new_bit_map + (1 << i); @@ -936,22 +937,22 @@ static void gfar_detect_errata(struct gfar_private *priv) /* MPC8313 Rev 2.0 and higher; All MPC837x */ if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) || - (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) + (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) priv->errata |= GFAR_ERRATA_74; /* MPC8313 and MPC837x all rev */ if ((pvr == 0x80850010 && mod == 0x80b0) || - (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) + (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) priv->errata |= GFAR_ERRATA_76; /* MPC8313 and MPC837x all rev */ if ((pvr == 0x80850010 && mod == 0x80b0) || - (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) + (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) priv->errata |= GFAR_ERRATA_A002; /* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */ if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) || - (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)) + (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)) priv->errata |= GFAR_ERRATA_12; if (priv->errata) @@ -1028,13 +1029,14 @@ static int gfar_probe(struct platform_device *ofdev) /* Register for napi ...We are registering NAPI for each grp */ for (i = 0; i < priv->num_grps; i++) - netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, GFAR_DEV_WEIGHT); + netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, + GFAR_DEV_WEIGHT); if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_RXCSUM; + NETIF_F_RXCSUM; dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_RXCSUM | NETIF_F_HIGHDMA; + NETIF_F_RXCSUM | NETIF_F_HIGHDMA; } if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { @@ -1083,7 +1085,7 @@ static int gfar_probe(struct platform_device *ofdev) priv->padding = 0; if (dev->features & NETIF_F_IP_CSUM || - priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) + priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) dev->needed_headroom = GMAC_FCB_LEN; /* Program the isrg regs only if number of grps > 1 */ @@ -1103,10 +1105,10 @@ static int gfar_probe(struct platform_device *ofdev) * basically reverses the queue numbers */ for (i = 0; i< priv->num_grps; i++) { - priv->gfargrp[i].tx_bit_map = reverse_bitmap( - priv->gfargrp[i].tx_bit_map, MAX_TX_QS); - priv->gfargrp[i].rx_bit_map = reverse_bitmap( - priv->gfargrp[i].rx_bit_map, MAX_RX_QS); + priv->gfargrp[i].tx_bit_map = + reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS); + priv->gfargrp[i].rx_bit_map = + reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS); } /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values, @@ -1114,16 +1116,18 @@ static int gfar_probe(struct platform_device *ofdev) */ for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { priv->gfargrp[grp_idx].num_rx_queues = 0x0; + for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map, - priv->num_rx_queues) { + priv->num_rx_queues) { priv->gfargrp[grp_idx].num_rx_queues++; priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx]; rstat = rstat | (RSTAT_CLEAR_RHALT >> i); rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i); } priv->gfargrp[grp_idx].num_tx_queues = 0x0; + for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map, - priv->num_tx_queues) { + priv->num_tx_queues) { priv->gfargrp[grp_idx].num_tx_queues++; priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx]; tstat = tstat | (TSTAT_CLEAR_THALT >> i); @@ -1169,7 +1173,8 @@ static int gfar_probe(struct platform_device *ofdev) } device_init_wakeup(&dev->dev, - priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); + priv->device_flags & + FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); /* fill out IRQ number and name fields */ for (i = 0; i < priv->num_grps; i++) { @@ -1200,7 +1205,7 @@ static int gfar_probe(struct platform_device *ofdev) for (i = 0; i < priv->num_rx_queues; i++) netdev_info(dev, "RX BD ring size for Q[%d]: %d\n", i, priv->rx_queue[i]->rx_ring_size); - for(i = 0; i < priv->num_tx_queues; i++) + for (i = 0; i < priv->num_tx_queues; i++) netdev_info(dev, "TX BD ring size for Q[%d]: %d\n", i, priv->tx_queue[i]->tx_ring_size); @@ -1247,7 +1252,8 @@ static int gfar_suspend(struct device *dev) u32 tempval; int magic_packet = priv->wol_en && - (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); + (priv->device_flags & + FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); netif_device_detach(ndev); @@ -1299,7 +1305,8 @@ static int gfar_resume(struct device *dev) unsigned long flags; u32 tempval; int magic_packet = priv->wol_en && - (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); + (priv->device_flags & + FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); if (!netif_running(ndev)) { netif_device_attach(ndev); @@ -1398,8 +1405,9 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) } if (ecntrl & ECNTRL_REDUCED_MODE) { - if (ecntrl & ECNTRL_REDUCED_MII_MODE) + if (ecntrl & ECNTRL_REDUCED_MII_MODE) { return PHY_INTERFACE_MODE_RMII; + } else { phy_interface_t interface = priv->interface; @@ -1494,11 +1502,12 @@ static void gfar_configure_serdes(struct net_device *dev) phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT); phy_write(tbiphy, MII_ADVERTISE, - ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | - ADVERTISE_1000XPSE_ASYM); + ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | + ADVERTISE_1000XPSE_ASYM); - phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE | - BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); + phy_write(tbiphy, MII_BMCR, + BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | + BMCR_SPEED1000); } static void init_registers(struct net_device *dev) @@ -1594,8 +1603,8 @@ static void gfar_halt_nodisable(struct net_device *dev) regs = priv->gfargrp[0].regs; /* Stop the DMA, and wait for it to stop */ tempval = gfar_read(®s->dmactrl); - if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) - != (DMACTRL_GRS | DMACTRL_GTS)) { + if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) != + (DMACTRL_GRS | DMACTRL_GTS)) { int ret; tempval |= (DMACTRL_GRS | DMACTRL_GTS); @@ -1660,7 +1669,7 @@ void stop_gfar(struct net_device *dev) } else { for (i = 0; i < priv->num_grps; i++) free_irq(priv->gfargrp[i].interruptTransmit, - &priv->gfargrp[i]); + &priv->gfargrp[i]); } free_skb_resources(priv); @@ -1679,13 +1688,13 @@ static void free_skb_tx_queue(struct gfar_priv_tx_q *tx_queue) continue; dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr, - txbdp->length, DMA_TO_DEVICE); + txbdp->length, DMA_TO_DEVICE); txbdp->lstatus = 0; for (j = 0; j < skb_shinfo(tx_queue->tx_skbuff[i])->nr_frags; - j++) { + j++) { txbdp++; dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr, - txbdp->length, DMA_TO_DEVICE); + txbdp->length, DMA_TO_DEVICE); } txbdp++; dev_kfree_skb_any(tx_queue->tx_skbuff[i]); @@ -1705,8 +1714,8 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) for (i = 0; i < rx_queue->rx_ring_size; i++) { if (rx_queue->rx_skbuff[i]) { dma_unmap_single(&priv->ofdev->dev, - rxbdp->bufPtr, priv->rx_buffer_size, - DMA_FROM_DEVICE); + rxbdp->bufPtr, priv->rx_buffer_size, + DMA_FROM_DEVICE); dev_kfree_skb_any(rx_queue->rx_skbuff[i]); rx_queue->rx_skbuff[i] = NULL; } @@ -1729,24 +1738,25 @@ static void free_skb_resources(struct gfar_private *priv) /* Go through all the buffer descriptors and free their data buffers */ for (i = 0; i < priv->num_tx_queues; i++) { struct netdev_queue *txq; + tx_queue = priv->tx_queue[i]; txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex); - if(tx_queue->tx_skbuff) + if (tx_queue->tx_skbuff) free_skb_tx_queue(tx_queue); netdev_tx_reset_queue(txq); } for (i = 0; i < priv->num_rx_queues; i++) { rx_queue = priv->rx_queue[i]; - if(rx_queue->rx_skbuff) + if (rx_queue->rx_skbuff) free_skb_rx_queue(rx_queue); } dma_free_coherent(&priv->ofdev->dev, - sizeof(struct txbd8) * priv->total_tx_ring_size + - sizeof(struct rxbd8) * priv->total_rx_ring_size, - priv->tx_queue[0]->tx_bd_base, - priv->tx_queue[0]->tx_bd_dma_base); + sizeof(struct txbd8) * priv->total_tx_ring_size + + sizeof(struct rxbd8) * priv->total_rx_ring_size, + priv->tx_queue[0]->tx_bd_base, + priv->tx_queue[0]->tx_bd_dma_base); skb_queue_purge(&priv->rx_recycle); } @@ -1785,7 +1795,7 @@ void gfar_start(struct net_device *dev) } void gfar_configure_coalescing(struct gfar_private *priv, - unsigned long tx_mask, unsigned long rx_mask) + unsigned long tx_mask, unsigned long rx_mask) { struct gfar __iomem *regs = priv->gfargrp[0].regs; u32 __iomem *baddr; @@ -1795,11 +1805,11 @@ void gfar_configure_coalescing(struct gfar_private *priv, * multiple queues, there's only single reg to program */ gfar_write(®s->txic, 0); - if(likely(priv->tx_queue[0]->txcoalescing)) + if (likely(priv->tx_queue[0]->txcoalescing)) gfar_write(®s->txic, priv->tx_queue[0]->txic); gfar_write(®s->rxic, 0); - if(unlikely(priv->rx_queue[0]->rxcoalescing)) + if (unlikely(priv->rx_queue[0]->rxcoalescing)) gfar_write(®s->rxic, priv->rx_queue[0]->rxic); if (priv->mode == MQ_MG_MODE) { @@ -1834,8 +1844,8 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) /* Install our interrupt handlers for Error, * Transmit, and Receive */ - if ((err = request_irq(grp->interruptError, gfar_error, 0, - grp->int_name_er,grp)) < 0) { + if ((err = request_irq(grp->interruptError, gfar_error, + 0, grp->int_name_er, grp)) < 0) { netif_err(priv, intr, dev, "Can't get IRQ %d\n", grp->interruptError); @@ -1843,21 +1853,21 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) } if ((err = request_irq(grp->interruptTransmit, gfar_transmit, - 0, grp->int_name_tx, grp)) < 0) { + 0, grp->int_name_tx, grp)) < 0) { netif_err(priv, intr, dev, "Can't get IRQ %d\n", grp->interruptTransmit); goto tx_irq_fail; } - if ((err = request_irq(grp->interruptReceive, gfar_receive, 0, - grp->int_name_rx, grp)) < 0) { + if ((err = request_irq(grp->interruptReceive, gfar_receive, + 0, grp->int_name_rx, grp)) < 0) { netif_err(priv, intr, dev, "Can't get IRQ %d\n", grp->interruptReceive); goto rx_irq_fail; } } else { - if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, 0, - grp->int_name_tx, grp)) < 0) { + if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, + 0, grp->int_name_tx, grp)) < 0) { netif_err(priv, intr, dev, "Can't get IRQ %d\n", grp->interruptTransmit); goto err_irq_fail; @@ -1964,7 +1974,7 @@ static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb) } static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, - int fcb_length) + int fcb_length) { u8 flags = 0; @@ -2001,7 +2011,7 @@ void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb) } static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, - struct txbd8 *base, int ring_size) + struct txbd8 *base, int ring_size) { struct txbd8 *new_bd = bdp + stride; @@ -2009,7 +2019,7 @@ static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, } static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base, - int ring_size) + int ring_size) { return skip_txbd(bdp, 1, base, ring_size); } @@ -2035,8 +2045,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) * before start of transmission. */ if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) && - skb->ip_summed == CHECKSUM_PARTIAL && - skb->len > 2500)) { + skb->ip_summed == CHECKSUM_PARTIAL && + skb->len > 2500)) { int ret; ret = skb_checksum_help(skb); @@ -2052,16 +2062,16 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* check if time stamp should be generated */ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && - priv->hwts_tx_en)) { + priv->hwts_tx_en)) { do_tstamp = 1; fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN; } /* make space for additional header when fcb is needed */ if (((skb->ip_summed == CHECKSUM_PARTIAL) || - vlan_tx_tag_present(skb) || - unlikely(do_tstamp)) && - (skb_headroom(skb) < fcb_length)) { + vlan_tx_tag_present(skb) || + unlikely(do_tstamp)) && + (skb_headroom(skb) < fcb_length)) { struct sk_buff *skb_new; skb_new = skb_realloc_headroom(skb, fcb_length); @@ -2105,12 +2115,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Time stamp insertion requires one additional TxBD */ if (unlikely(do_tstamp)) txbdp_tstamp = txbdp = next_txbd(txbdp, base, - tx_queue->tx_ring_size); + tx_queue->tx_ring_size); if (nr_frags == 0) { if (unlikely(do_tstamp)) txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_LAST | - TXBD_INTERRUPT); + TXBD_INTERRUPT); else lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT); } else { @@ -2122,7 +2132,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) length = skb_shinfo(skb)->frags[i].size; lstatus = txbdp->lstatus | length | - BD_LFLAG(TXBD_READY); + BD_LFLAG(TXBD_READY); /* Handle the last BD specially */ if (i == nr_frags - 1) @@ -2152,8 +2162,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) if (CHECKSUM_PARTIAL == skb->ip_summed) { fcb = gfar_add_fcb(skb); /* as specified by errata */ - if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) - && ((unsigned long)fcb % 0x20) > 0x18)) { + if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) && + ((unsigned long)fcb % 0x20) > 0x18)) { __skb_pull(skb, GMAC_FCB_LEN); skb_checksum_help(skb); } else { @@ -2181,7 +2191,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); + skb_headlen(skb), DMA_TO_DEVICE); /* If time stamping is requested one additional TxBD must be set up. The * first TxBD points to the FCB and must have a data length of @@ -2191,7 +2201,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(do_tstamp)) { txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length; txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) | - (skb_headlen(skb) - fcb_length); + (skb_headlen(skb) - fcb_length); lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN; } else { lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); @@ -2231,7 +2241,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) * (wrapping if necessary) */ tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & - TX_RING_MOD_MASK(tx_queue->tx_ring_size); + TX_RING_MOD_MASK(tx_queue->tx_ring_size); tx_queue->cur_tx = next_txbd(txbdp, base, tx_queue->tx_ring_size); @@ -2365,9 +2375,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) frame_size += priv->padding; - tempsize = - (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + - INCREMENTAL_BUFFER_SIZE; + tempsize = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + + INCREMENTAL_BUFFER_SIZE; /* Only stop and start the controller if it isn't already * stopped, and we changed something @@ -2389,7 +2398,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) tempval = gfar_read(®s->maccfg2); if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || - gfar_has_errata(priv, GFAR_ERRATA_74)) + gfar_has_errata(priv, GFAR_ERRATA_74)) tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); else tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); @@ -2410,7 +2419,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) static void gfar_reset_task(struct work_struct *work) { struct gfar_private *priv = container_of(work, struct gfar_private, - reset_task); + reset_task); struct net_device *dev = priv->ndev; if (dev->flags & IFF_UP) { @@ -2437,7 +2446,7 @@ static void gfar_align_skb(struct sk_buff *skb) * as many bytes as needed to align the data properly */ skb_reserve(skb, RXBUF_ALIGNMENT - - (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1))); + (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1))); } /* Interrupt Handler for Transmit complete */ @@ -2485,7 +2494,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) /* Only clean completed frames */ if ((lstatus & BD_LFLAG(TXBD_READY)) && - (lstatus & BD_LENGTH_MASK)) + (lstatus & BD_LENGTH_MASK)) break; if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { @@ -2495,11 +2504,12 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) buflen = bdp->length; dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, - buflen, DMA_TO_DEVICE); + buflen, DMA_TO_DEVICE); if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { struct skb_shared_hwtstamps shhwtstamps; u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); shhwtstamps.hwtstamp = ns_to_ktime(*ns); skb_pull(skb, GMAC_FCB_LEN + GMAC_TXPAL_LEN); @@ -2512,10 +2522,8 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) bdp = next_txbd(bdp, base, tx_ring_size); for (i = 0; i < frags; i++) { - dma_unmap_page(&priv->ofdev->dev, - bdp->bufPtr, - bdp->length, - DMA_TO_DEVICE); + dma_unmap_page(&priv->ofdev->dev, bdp->bufPtr, + bdp->length, DMA_TO_DEVICE); bdp->lstatus &= BD_LFLAG(TXBD_WRAP); bdp = next_txbd(bdp, base, tx_ring_size); } @@ -2526,8 +2534,8 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) * we add this skb back into the pool, if it's the right size */ if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size && - skb_recycle_check(skb, priv->rx_buffer_size + - RXBUF_ALIGNMENT)) { + skb_recycle_check(skb, priv->rx_buffer_size + + RXBUF_ALIGNMENT)) { gfar_align_skb(skb); skb_queue_head(&priv->rx_recycle, skb); } else @@ -2536,7 +2544,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) tx_queue->tx_skbuff[skb_dirtytx] = NULL; skb_dirtytx = (skb_dirtytx + 1) & - TX_RING_MOD_MASK(tx_ring_size); + TX_RING_MOD_MASK(tx_ring_size); howmany++; spin_lock_irqsave(&tx_queue->txlock, flags); @@ -2583,7 +2591,7 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id) } static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, - struct sk_buff *skb) + struct sk_buff *skb) { struct net_device *dev = rx_queue->dev; struct gfar_private *priv = netdev_priv(dev); @@ -2700,6 +2708,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, if (priv->hwts_rx_en) { struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); u64 *ns = (u64 *) skb->data; + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); shhwtstamps->hwtstamp = ns_to_ktime(*ns); } @@ -2752,6 +2761,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) { struct sk_buff *newskb; + rmb(); /* Add another skb for the future */ @@ -2760,15 +2770,15 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) skb = rx_queue->rx_skbuff[rx_queue->skb_currx]; dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, - priv->rx_buffer_size, DMA_FROM_DEVICE); + priv->rx_buffer_size, DMA_FROM_DEVICE); if (unlikely(!(bdp->status & RXBD_ERR) && - bdp->length > priv->rx_buffer_size)) + bdp->length > priv->rx_buffer_size)) bdp->status = RXBD_LARGE; /* We drop the frame if we failed to allocate a new buffer */ if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || - bdp->status & RXBD_ERR)) { + bdp->status & RXBD_ERR)) { count_errors(bdp->status, dev); if (unlikely(!newskb)) @@ -2787,7 +2797,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) rx_queue->stats.rx_bytes += pkt_len; skb_record_rx_queue(skb, rx_queue->qindex); gfar_process_frame(dev, skb, amount_pull, - &rx_queue->grp->napi); + &rx_queue->grp->napi); } else { netif_warn(priv, rx_err, dev, "Missing skb!\n"); @@ -2806,9 +2816,8 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) bdp = next_bd(bdp, base, rx_queue->rx_ring_size); /* update to point at the next skb */ - rx_queue->skb_currx = - (rx_queue->skb_currx + 1) & - RX_RING_MOD_MASK(rx_queue->rx_ring_size); + rx_queue->skb_currx = (rx_queue->skb_currx + 1) & + RX_RING_MOD_MASK(rx_queue->rx_ring_size); } /* Update the current rxbd pointer to be the next one */ @@ -2819,8 +2828,8 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) static int gfar_poll(struct napi_struct *napi, int budget) { - struct gfar_priv_grp *gfargrp = container_of(napi, - struct gfar_priv_grp, napi); + struct gfar_priv_grp *gfargrp = + container_of(napi, struct gfar_priv_grp, napi); struct gfar_private *priv = gfargrp->priv; struct gfar __iomem *regs = gfargrp->regs; struct gfar_priv_tx_q *tx_queue = NULL; @@ -2839,7 +2848,6 @@ static int gfar_poll(struct napi_struct *napi, int budget) gfar_write(®s->ievent, IEVENT_RTX_MASK); while (num_queues && left_over_budget) { - budget_per_queue = left_over_budget/num_queues; left_over_budget = 0; @@ -2850,12 +2858,13 @@ static int gfar_poll(struct napi_struct *napi, int budget) tx_queue = priv->tx_queue[rx_queue->qindex]; tx_cleaned += gfar_clean_tx_ring(tx_queue); - rx_cleaned_per_queue = gfar_clean_rx_ring(rx_queue, - budget_per_queue); + rx_cleaned_per_queue = + gfar_clean_rx_ring(rx_queue, budget_per_queue); rx_cleaned += rx_cleaned_per_queue; - if(rx_cleaned_per_queue < budget_per_queue) { + if (rx_cleaned_per_queue < budget_per_queue) { left_over_budget = left_over_budget + - (budget_per_queue - rx_cleaned_per_queue); + (budget_per_queue - + rx_cleaned_per_queue); set_bit(i, &serviced_queues); num_queues--; } @@ -2876,8 +2885,8 @@ static int gfar_poll(struct napi_struct *napi, int budget) /* If we are coalescing interrupts, update the timer * Otherwise, clear it */ - gfar_configure_coalescing(priv, - gfargrp->rx_bit_map, gfargrp->tx_bit_map); + gfar_configure_coalescing(priv, gfargrp->rx_bit_map, + gfargrp->tx_bit_map); } return rx_cleaned; @@ -2900,7 +2909,7 @@ static void gfar_netpoll(struct net_device *dev) disable_irq(priv->gfargrp[i].interruptReceive); disable_irq(priv->gfargrp[i].interruptError); gfar_interrupt(priv->gfargrp[i].interruptTransmit, - &priv->gfargrp[i]); + &priv->gfargrp[i]); enable_irq(priv->gfargrp[i].interruptError); enable_irq(priv->gfargrp[i].interruptReceive); enable_irq(priv->gfargrp[i].interruptTransmit); @@ -2909,7 +2918,7 @@ static void gfar_netpoll(struct net_device *dev) for (i = 0; i < priv->num_grps; i++) { disable_irq(priv->gfargrp[i].interruptTransmit); gfar_interrupt(priv->gfargrp[i].interruptTransmit, - &priv->gfargrp[i]); + &priv->gfargrp[i]); enable_irq(priv->gfargrp[i].interruptTransmit); } } @@ -3125,7 +3134,7 @@ static void gfar_clear_exact_match(struct net_device *dev) int idx; static const u8 zero_arr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - for(idx = 1;idx < GFAR_EM_NUM + 1;idx++) + for (idx = 1; idx < GFAR_EM_NUM + 1; idx++) gfar_set_mac_for_addr(dev, idx, zero_arr); } @@ -3208,7 +3217,8 @@ static irqreturn_t gfar_error(int irq, void *grp_id) /* Hmm... */ if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) - netdev_dbg(dev, "error interrupt (ievent=0x%08x imask=0x%08x)\n", + netdev_dbg(dev, + "error interrupt (ievent=0x%08x imask=0x%08x)\n", events, gfar_read(®s->imask)); /* Update the error counters */ -- GitLab From 3a2e16c816017d952ed5f29ca9d6f5136ced5f21 Mon Sep 17 00:00:00 2001 From: Jan Ceuleers Date: Tue, 5 Jun 2012 03:42:14 +0000 Subject: [PATCH 0675/6849] gianfar: Remove superfluous initialisations Signed-off-by: Jan Ceuleers Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 30 +++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index ed0b1369a5d9..f00a095f37b4 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -428,7 +428,7 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev) struct gfar_private *priv = netdev_priv(dev); unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; unsigned long tx_packets = 0, tx_bytes = 0; - int i = 0; + int i; for (i = 0; i < priv->num_rx_queues; i++) { rx_packets += priv->rx_queue[i]->stats.rx_packets; @@ -470,7 +470,7 @@ static const struct net_device_ops gfar_netdev_ops = { void lock_rx_qs(struct gfar_private *priv) { - int i = 0x0; + int i; for (i = 0; i < priv->num_rx_queues; i++) spin_lock(&priv->rx_queue[i]->rxlock); @@ -478,7 +478,7 @@ void lock_rx_qs(struct gfar_private *priv) void lock_tx_qs(struct gfar_private *priv) { - int i = 0x0; + int i; for (i = 0; i < priv->num_tx_queues; i++) spin_lock(&priv->tx_queue[i]->txlock); @@ -486,7 +486,7 @@ void lock_tx_qs(struct gfar_private *priv) void unlock_rx_qs(struct gfar_private *priv) { - int i = 0x0; + int i; for (i = 0; i < priv->num_rx_queues; i++) spin_unlock(&priv->rx_queue[i]->rxlock); @@ -494,7 +494,7 @@ void unlock_rx_qs(struct gfar_private *priv) void unlock_tx_qs(struct gfar_private *priv) { - int i = 0x0; + int i; for (i = 0; i < priv->num_tx_queues; i++) spin_unlock(&priv->tx_queue[i]->txlock); @@ -516,7 +516,7 @@ static inline int gfar_uses_fcb(struct gfar_private *priv) static void free_tx_pointers(struct gfar_private *priv) { - int i = 0; + int i; for (i = 0; i < priv->num_tx_queues; i++) kfree(priv->tx_queue[i]); @@ -524,7 +524,7 @@ static void free_tx_pointers(struct gfar_private *priv) static void free_rx_pointers(struct gfar_private *priv) { - int i = 0; + int i; for (i = 0; i < priv->num_rx_queues; i++) kfree(priv->rx_queue[i]); @@ -532,7 +532,7 @@ static void free_rx_pointers(struct gfar_private *priv) static void unmap_group_regs(struct gfar_private *priv) { - int i = 0; + int i; for (i = 0; i < MAXGROUPS; i++) if (priv->gfargrp[i].regs) @@ -541,7 +541,7 @@ static void unmap_group_regs(struct gfar_private *priv) static void disable_napi(struct gfar_private *priv) { - int i = 0; + int i; for (i = 0; i < priv->num_grps; i++) napi_disable(&priv->gfargrp[i].napi); @@ -549,7 +549,7 @@ static void disable_napi(struct gfar_private *priv) static void enable_napi(struct gfar_private *priv) { - int i = 0; + int i; for (i = 0; i < priv->num_grps; i++) napi_enable(&priv->gfargrp[i].napi); @@ -1514,7 +1514,7 @@ static void init_registers(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = NULL; - int i = 0; + int i; for (i = 0; i < priv->num_grps; i++) { regs = priv->gfargrp[i].regs; @@ -1589,7 +1589,7 @@ static void gfar_halt_nodisable(struct net_device *dev) struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = NULL; u32 tempval; - int i = 0; + int i; for (i = 0; i < priv->num_grps; i++) { regs = priv->gfargrp[i].regs; @@ -1976,13 +1976,11 @@ static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb) static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, int fcb_length) { - u8 flags = 0; - /* If we're here, it's a IP packet with a TCP or UDP * payload. We set it to checksum, using a pseudo-header * we provide */ - flags = TXFCB_DEFAULT; + u8 flags = TXFCB_DEFAULT; /* Tell the controller what the protocol is * And provide the already calculated phcs @@ -2900,7 +2898,7 @@ static int gfar_poll(struct napi_struct *napi, int budget) static void gfar_netpoll(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); - int i = 0; + int i; /* If the device has multiple interrupts, run tx/rx */ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { -- GitLab From cbfc60717b69fb479861f336d42bde640f650ea0 Mon Sep 17 00:00:00 2001 From: Jan Ceuleers Date: Tue, 5 Jun 2012 03:42:15 +0000 Subject: [PATCH 0676/6849] gianfar_ethtool: coding style and whitespace cleanups Signed-off-by: Jan Ceuleers Signed-off-by: David S. Miller --- .../net/ethernet/freescale/gianfar_ethtool.c | 420 ++++++++++-------- 1 file changed, 224 insertions(+), 196 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 8a025570d97e..8971921cc1c8 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -46,18 +46,24 @@ #include "gianfar.h" extern void gfar_start(struct net_device *dev); -extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); +extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, + int rx_work_limit); #define GFAR_MAX_COAL_USECS 0xffff #define GFAR_MAX_COAL_FRAMES 0xff static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, - u64 * buf); + u64 *buf); static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); -static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); -static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); -static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals); -static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals); -static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); +static int gfar_gcoalesce(struct net_device *dev, + struct ethtool_coalesce *cvals); +static int gfar_scoalesce(struct net_device *dev, + struct ethtool_coalesce *cvals); +static void gfar_gringparam(struct net_device *dev, + struct ethtool_ringparam *rvals); +static int gfar_sringparam(struct net_device *dev, + struct ethtool_ringparam *rvals); +static void gfar_gdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo); static const char stat_gstrings[][ETH_GSTRING_LEN] = { "rx-dropped-by-kernel", @@ -130,14 +136,15 @@ static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); else memcpy(buf, stat_gstrings, - GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN); + GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN); } /* Fill in an array of 64-bit statistics from various sources. * This array will be appended to the end of the ethtool_stats * structure, and returned to user space */ -static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) +static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, + u64 *buf) { int i; struct gfar_private *priv = netdev_priv(dev); @@ -174,8 +181,8 @@ static int gfar_sset_count(struct net_device *dev, int sset) } /* Fills in the drvinfo structure with some basic info */ -static void gfar_gdrvinfo(struct net_device *dev, struct - ethtool_drvinfo *drvinfo) +static void gfar_gdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) { strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); @@ -226,7 +233,8 @@ static int gfar_reglen(struct net_device *dev) } /* Return a dump of the GFAR register space */ -static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) +static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *regbuf) { int i; struct gfar_private *priv = netdev_priv(dev); @@ -239,7 +247,8 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, voi /* Convert microseconds to ethernet clock ticks, which changes * depending on what speed the controller is running at */ -static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs) +static unsigned int gfar_usecs2ticks(struct gfar_private *priv, + unsigned int usecs) { unsigned int count; @@ -263,7 +272,8 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use } /* Convert ethernet clock ticks to microseconds */ -static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int ticks) +static unsigned int gfar_ticks2usecs(struct gfar_private *priv, + unsigned int ticks) { unsigned int count; @@ -288,7 +298,8 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic /* Get the coalescing parameters, and put them in the cvals * structure. */ -static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) +static int gfar_gcoalesce(struct net_device *dev, + struct ethtool_coalesce *cvals) { struct gfar_private *priv = netdev_priv(dev); struct gfar_priv_rx_q *rx_queue = NULL; @@ -353,7 +364,8 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals * Both cvals->*_usecs and cvals->*_frames have to be > 0 * in order for coalescing to be active */ -static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) +static int gfar_scoalesce(struct net_device *dev, + struct ethtool_coalesce *cvals) { struct gfar_private *priv = netdev_priv(dev); int i = 0; @@ -364,7 +376,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals /* Set up rx coalescing */ /* As of now, we will enable/disable coalescing for all * queues together in case of eTSEC2, this will be modified - * along with the ethtool interface */ + * along with the ethtool interface + */ if ((cvals->rx_coalesce_usecs == 0) || (cvals->rx_max_coalesced_frames == 0)) { for (i = 0; i < priv->num_rx_queues; i++) @@ -433,7 +446,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals /* Fills in rvals with the current ring parameters. Currently, * rx, rx_mini, and rx_jumbo rings are the same size, as mini and * jumbo are ignored by the driver */ -static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) +static void gfar_gringparam(struct net_device *dev, + struct ethtool_ringparam *rvals) { struct gfar_private *priv = netdev_priv(dev); struct gfar_priv_tx_q *tx_queue = NULL; @@ -459,8 +473,10 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv /* Change the current ring parameters, stopping the controller if * necessary so that we don't mess things up while we're in * motion. We wait for the ring to be clean before reallocating - * the rings. */ -static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) + * the rings. + */ +static int gfar_sringparam(struct net_device *dev, + struct ethtool_ringparam *rvals) { struct gfar_private *priv = netdev_priv(dev); int err = 0, i = 0; @@ -486,7 +502,8 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva unsigned long flags; /* Halt TX and RX, and process the frames which - * have already been received */ + * have already been received + */ local_irq_save(flags); lock_tx_qs(priv); lock_rx_qs(priv); @@ -499,7 +516,7 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva for (i = 0; i < priv->num_rx_queues; i++) gfar_clean_rx_ring(priv->rx_queue[i], - priv->rx_queue[i]->rx_ring_size); + priv->rx_queue[i]->rx_ring_size); /* Now we take down the rings to rebuild them */ stop_gfar(dev); @@ -509,7 +526,8 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva for (i = 0; i < priv->num_rx_queues; i++) { priv->rx_queue[i]->rx_ring_size = rvals->rx_pending; priv->tx_queue[i]->tx_ring_size = rvals->tx_pending; - priv->tx_queue[i]->num_txbdfree = priv->tx_queue[i]->tx_ring_size; + priv->tx_queue[i]->num_txbdfree = + priv->tx_queue[i]->tx_ring_size; } /* Rebuild the rings with the new size */ @@ -535,7 +553,8 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) if (dev->flags & IFF_UP) { /* Halt TX and RX, and process the frames which - * have already been received */ + * have already been received + */ local_irq_save(flags); lock_tx_qs(priv); lock_rx_qs(priv); @@ -548,7 +567,7 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) for (i = 0; i < priv->num_rx_queues; i++) gfar_clean_rx_ring(priv->rx_queue[i], - priv->rx_queue[i]->rx_ring_size); + priv->rx_queue[i]->rx_ring_size); /* Now we take down the rings to rebuild them */ stop_gfar(dev); @@ -564,12 +583,14 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) static uint32_t gfar_get_msglevel(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); + return priv->msg_enable; } static void gfar_set_msglevel(struct net_device *dev, uint32_t data) { struct gfar_private *priv = netdev_priv(dev); + priv->msg_enable = data; } @@ -614,14 +635,14 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & RXH_L2DA) { fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH | - RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); priv->cur_filer_idx = priv->cur_filer_idx - 1; fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH | - RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); @@ -630,7 +651,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & RXH_VLAN) { fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH | - RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_AND | RQFCR_HASHTBL_0; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; @@ -639,7 +660,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & RXH_IP_SRC) { fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | - RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); @@ -648,7 +669,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & (RXH_IP_DST)) { fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | - RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); @@ -657,7 +678,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & RXH_L3_PROTO) { fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH | - RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); @@ -666,7 +687,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & RXH_L4_B_0_1) { fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | - RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); @@ -675,7 +696,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) if (ethflow & RXH_L4_B_2_3) { fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | - RQFCR_AND | RQFCR_HASHTBL_0; + RQFCR_AND | RQFCR_HASHTBL_0; priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); @@ -683,7 +704,8 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) } } -static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class) +static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, + u64 class) { unsigned int last_rule_idx = priv->cur_filer_idx; unsigned int cmp_rqfpr; @@ -694,9 +716,9 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u int ret = 1; local_rqfpr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), - GFP_KERNEL); + GFP_KERNEL); local_rqfcr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), - GFP_KERNEL); + GFP_KERNEL); if (!local_rqfpr || !local_rqfcr) { pr_err("Out of memory\n"); ret = 0; @@ -726,9 +748,9 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u local_rqfpr[j] = priv->ftp_rqfpr[i]; local_rqfcr[j] = priv->ftp_rqfcr[i]; j--; - if ((priv->ftp_rqfcr[i] == (RQFCR_PID_PARSE | - RQFCR_CLE |RQFCR_AND)) && - (priv->ftp_rqfpr[i] == cmp_rqfpr)) + if ((priv->ftp_rqfcr[i] == + (RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND)) && + (priv->ftp_rqfpr[i] == cmp_rqfpr)) break; } @@ -743,12 +765,12 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u */ for (l = i+1; l < MAX_FILER_IDX; l++) { if ((priv->ftp_rqfcr[l] & RQFCR_CLE) && - !(priv->ftp_rqfcr[l] & RQFCR_AND)) { + !(priv->ftp_rqfcr[l] & RQFCR_AND)) { priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT | - RQFCR_HASHTBL_0 | RQFCR_PID_MASK; + RQFCR_HASHTBL_0 | RQFCR_PID_MASK; priv->ftp_rqfpr[l] = FPR_FILER_MASK; gfar_write_filer(priv, l, priv->ftp_rqfcr[l], - priv->ftp_rqfpr[l]); + priv->ftp_rqfpr[l]); break; } @@ -773,7 +795,7 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k]; priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k]; gfar_write_filer(priv, priv->cur_filer_idx, - local_rqfcr[k], local_rqfpr[k]); + local_rqfcr[k], local_rqfpr[k]); if (!priv->cur_filer_idx) break; priv->cur_filer_idx = priv->cur_filer_idx - 1; @@ -785,7 +807,8 @@ err: return ret; } -static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) +static int gfar_set_hash_opts(struct gfar_private *priv, + struct ethtool_rxnfc *cmd) { /* write the filer rules here */ if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) @@ -810,10 +833,10 @@ static int gfar_check_filer_hardware(struct gfar_private *priv) i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM; if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) { netdev_info(priv->ndev, - "Receive Queue Filtering enabled\n"); + "Receive Queue Filtering enabled\n"); } else { netdev_warn(priv->ndev, - "Receive Queue Filtering disabled\n"); + "Receive Queue Filtering disabled\n"); return -EOPNOTSUPP; } } @@ -823,16 +846,17 @@ static int gfar_check_filer_hardware(struct gfar_private *priv) i &= RCTRL_PRSDEP_MASK; if (i == RCTRL_PRSDEP_MASK) { netdev_info(priv->ndev, - "Receive Queue Filtering enabled\n"); + "Receive Queue Filtering enabled\n"); } else { netdev_warn(priv->ndev, - "Receive Queue Filtering disabled\n"); + "Receive Queue Filtering disabled\n"); return -EOPNOTSUPP; } } /* Sets the properties for arbitrary filer rule - * to the first 4 Layer 4 Bytes */ + * to the first 4 Layer 4 Bytes + */ regs->rbifx = 0xC0C1C2C3; return 0; } @@ -870,14 +894,14 @@ static void gfar_set_mask(u32 mask, struct filer_table *tab) static void gfar_set_parse_bits(u32 value, u32 mask, struct filer_table *tab) { gfar_set_mask(mask, tab); - tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE - | RQFCR_AND; + tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | + RQFCR_AND; tab->fe[tab->index].prop = value; tab->index++; } static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, - struct filer_table *tab) + struct filer_table *tab) { gfar_set_mask(mask, tab); tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag; @@ -885,8 +909,7 @@ static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, tab->index++; } -/* - * For setting a tuple of value and mask of type flag +/* For setting a tuple of value and mask of type flag * Example: * IP-Src = 10.0.0.0/255.0.0.0 * value: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4 @@ -901,7 +924,7 @@ static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, * Further the all masks are one-padded for better hardware efficiency. */ static void gfar_set_attribute(u32 value, u32 mask, u32 flag, - struct filer_table *tab) + struct filer_table *tab) { switch (flag) { /* 3bit */ @@ -959,7 +982,8 @@ static void gfar_set_attribute(u32 value, u32 mask, u32 flag, /* Translates value and mask for UDP, TCP or SCTP */ static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, - struct ethtool_tcpip4_spec *mask, struct filer_table *tab) + struct ethtool_tcpip4_spec *mask, + struct filer_table *tab) { gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); @@ -970,97 +994,92 @@ static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, /* Translates value and mask for RAW-IP4 */ static void gfar_set_user_ip(struct ethtool_usrip4_spec *value, - struct ethtool_usrip4_spec *mask, struct filer_table *tab) + struct ethtool_usrip4_spec *mask, + struct filer_table *tab) { gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); gfar_set_attribute(value->proto, mask->proto, RQFCR_PID_L4P, tab); gfar_set_attribute(value->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB, - tab); + tab); } /* Translates value and mask for ETHER spec */ static void gfar_set_ether(struct ethhdr *value, struct ethhdr *mask, - struct filer_table *tab) + struct filer_table *tab) { u32 upper_temp_mask = 0; u32 lower_temp_mask = 0; + /* Source address */ if (!is_broadcast_ether_addr(mask->h_source)) { - if (is_zero_ether_addr(mask->h_source)) { upper_temp_mask = 0xFFFFFFFF; lower_temp_mask = 0xFFFFFFFF; } else { - upper_temp_mask = mask->h_source[0] << 16 - | mask->h_source[1] << 8 - | mask->h_source[2]; - lower_temp_mask = mask->h_source[3] << 16 - | mask->h_source[4] << 8 - | mask->h_source[5]; + upper_temp_mask = mask->h_source[0] << 16 | + mask->h_source[1] << 8 | + mask->h_source[2]; + lower_temp_mask = mask->h_source[3] << 16 | + mask->h_source[4] << 8 | + mask->h_source[5]; } /* Upper 24bit */ - gfar_set_attribute( - value->h_source[0] << 16 | value->h_source[1] - << 8 | value->h_source[2], - upper_temp_mask, RQFCR_PID_SAH, tab); + gfar_set_attribute(value->h_source[0] << 16 | + value->h_source[1] << 8 | + value->h_source[2], + upper_temp_mask, RQFCR_PID_SAH, tab); /* And the same for the lower part */ - gfar_set_attribute( - value->h_source[3] << 16 | value->h_source[4] - << 8 | value->h_source[5], - lower_temp_mask, RQFCR_PID_SAL, tab); + gfar_set_attribute(value->h_source[3] << 16 | + value->h_source[4] << 8 | + value->h_source[5], + lower_temp_mask, RQFCR_PID_SAL, tab); } /* Destination address */ if (!is_broadcast_ether_addr(mask->h_dest)) { - /* Special for destination is limited broadcast */ - if ((is_broadcast_ether_addr(value->h_dest) - && is_zero_ether_addr(mask->h_dest))) { + if ((is_broadcast_ether_addr(value->h_dest) && + is_zero_ether_addr(mask->h_dest))) { gfar_set_parse_bits(RQFPR_EBC, RQFPR_EBC, tab); } else { - if (is_zero_ether_addr(mask->h_dest)) { upper_temp_mask = 0xFFFFFFFF; lower_temp_mask = 0xFFFFFFFF; } else { - upper_temp_mask = mask->h_dest[0] << 16 - | mask->h_dest[1] << 8 - | mask->h_dest[2]; - lower_temp_mask = mask->h_dest[3] << 16 - | mask->h_dest[4] << 8 - | mask->h_dest[5]; + upper_temp_mask = mask->h_dest[0] << 16 | + mask->h_dest[1] << 8 | + mask->h_dest[2]; + lower_temp_mask = mask->h_dest[3] << 16 | + mask->h_dest[4] << 8 | + mask->h_dest[5]; } /* Upper 24bit */ - gfar_set_attribute( - value->h_dest[0] << 16 - | value->h_dest[1] << 8 - | value->h_dest[2], - upper_temp_mask, RQFCR_PID_DAH, tab); + gfar_set_attribute(value->h_dest[0] << 16 | + value->h_dest[1] << 8 | + value->h_dest[2], + upper_temp_mask, RQFCR_PID_DAH, tab); /* And the same for the lower part */ - gfar_set_attribute( - value->h_dest[3] << 16 - | value->h_dest[4] << 8 - | value->h_dest[5], - lower_temp_mask, RQFCR_PID_DAL, tab); + gfar_set_attribute(value->h_dest[3] << 16 | + value->h_dest[4] << 8 | + value->h_dest[5], + lower_temp_mask, RQFCR_PID_DAL, tab); } } gfar_set_attribute(value->h_proto, mask->h_proto, RQFCR_PID_ETY, tab); - } /* Convert a rule to binary filter format of gianfar */ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, - struct filer_table *tab) + struct filer_table *tab) { u32 vlan = 0, vlan_mask = 0; u32 id = 0, id_mask = 0; u32 cfi = 0, cfi_mask = 0; u32 prio = 0, prio_mask = 0; - u32 old_index = tab->index; /* Check if vlan is wanted */ @@ -1076,13 +1095,16 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, id_mask = rule->m_ext.vlan_tci & VLAN_VID_MASK; cfi = rule->h_ext.vlan_tci & VLAN_CFI_MASK; cfi_mask = rule->m_ext.vlan_tci & VLAN_CFI_MASK; - prio = (rule->h_ext.vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; - prio_mask = (rule->m_ext.vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + prio = (rule->h_ext.vlan_tci & VLAN_PRIO_MASK) >> + VLAN_PRIO_SHIFT; + prio_mask = (rule->m_ext.vlan_tci & VLAN_PRIO_MASK) >> + VLAN_PRIO_SHIFT; if (cfi == VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { vlan |= RQFPR_CFI; vlan_mask |= RQFPR_CFI; - } else if (cfi != VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { + } else if (cfi != VLAN_TAG_PRESENT && + cfi_mask == VLAN_TAG_PRESENT) { vlan_mask |= RQFPR_CFI; } } @@ -1090,34 +1112,36 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, switch (rule->flow_type & ~FLOW_EXT) { case TCP_V4_FLOW: gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan, - RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab); + RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab); gfar_set_basic_ip(&rule->h_u.tcp_ip4_spec, - &rule->m_u.tcp_ip4_spec, tab); + &rule->m_u.tcp_ip4_spec, tab); break; case UDP_V4_FLOW: gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan, - RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab); + RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab); gfar_set_basic_ip(&rule->h_u.udp_ip4_spec, - &rule->m_u.udp_ip4_spec, tab); + &rule->m_u.udp_ip4_spec, tab); break; case SCTP_V4_FLOW: gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, - tab); + tab); gfar_set_attribute(132, 0, RQFCR_PID_L4P, tab); - gfar_set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u, - (struct ethtool_tcpip4_spec *) &rule->m_u, tab); + gfar_set_basic_ip((struct ethtool_tcpip4_spec *)&rule->h_u, + (struct ethtool_tcpip4_spec *)&rule->m_u, + tab); break; case IP_USER_FLOW: gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, - tab); + tab); gfar_set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u, - (struct ethtool_usrip4_spec *) &rule->m_u, tab); + (struct ethtool_usrip4_spec *) &rule->m_u, + tab); break; case ETHER_FLOW: if (vlan) gfar_set_parse_bits(vlan, vlan_mask, tab); gfar_set_ether((struct ethhdr *) &rule->h_u, - (struct ethhdr *) &rule->m_u, tab); + (struct ethhdr *) &rule->m_u, tab); break; default: return -1; @@ -1152,7 +1176,9 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, tab->fe[tab->index - 1].ctrl |= RQFCR_CLE; } - /* In rare cases the cache can be full while there is free space in hw */ + /* In rare cases the cache can be full while there is + * free space in hw + */ if (tab->index > MAX_FILER_CACHE_IDX - 1) return -EBUSY; @@ -1161,7 +1187,7 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, /* Copy size filer entries */ static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], - struct gfar_filer_entry src[0], s32 size) + struct gfar_filer_entry src[0], s32 size) { while (size > 0) { size--; @@ -1171,10 +1197,12 @@ static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], } /* Delete the contents of the filer-table between start and end - * and collapse them */ + * and collapse them + */ static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) { int length; + if (end > MAX_FILER_CACHE_IDX || end < begin) return -EINVAL; @@ -1200,14 +1228,14 @@ static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) /* Make space on the wanted location */ static int gfar_expand_filer_entries(u32 begin, u32 length, - struct filer_table *tab) + struct filer_table *tab) { - if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || begin - > MAX_FILER_CACHE_IDX) + if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || + begin > MAX_FILER_CACHE_IDX) return -EINVAL; gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]), - tab->index - length + 1); + tab->index - length + 1); tab->index += length; return 0; @@ -1215,9 +1243,10 @@ static int gfar_expand_filer_entries(u32 begin, u32 length, static int gfar_get_next_cluster_start(int start, struct filer_table *tab) { - for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { - if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) - == (RQFCR_AND | RQFCR_CLE)) + for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); + start++) { + if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) == + (RQFCR_AND | RQFCR_CLE)) return start; } return -1; @@ -1225,16 +1254,16 @@ static int gfar_get_next_cluster_start(int start, struct filer_table *tab) static int gfar_get_next_cluster_end(int start, struct filer_table *tab) { - for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { - if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) - == (RQFCR_CLE)) + for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); + start++) { + if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) == + (RQFCR_CLE)) return start; } return -1; } -/* - * Uses hardwares clustering option to reduce +/* Uses hardwares clustering option to reduce * the number of filer table entries */ static void gfar_cluster_filer(struct filer_table *tab) @@ -1244,8 +1273,7 @@ static void gfar_cluster_filer(struct filer_table *tab) while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) { j = i; while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) { - /* - * The cluster entries self and the previous one + /* The cluster entries self and the previous one * (a mask) must be identical! */ if (tab->fe[i].ctrl != tab->fe[j].ctrl) @@ -1260,21 +1288,21 @@ static void gfar_cluster_filer(struct filer_table *tab) jend = gfar_get_next_cluster_end(j, tab); if (jend == -1 || iend == -1) break; - /* - * First we make some free space, where our cluster + + /* First we make some free space, where our cluster * element should be. Then we copy it there and finally * delete in from its old location. */ - - if (gfar_expand_filer_entries(iend, (jend - j), tab) - == -EINVAL) + if (gfar_expand_filer_entries(iend, (jend - j), tab) == + -EINVAL) break; gfar_copy_filer_entries(&(tab->fe[iend + 1]), - &(tab->fe[jend + 1]), jend - j); + &(tab->fe[jend + 1]), jend - j); if (gfar_trim_filer_entries(jend - 1, - jend + (jend - j), tab) == -EINVAL) + jend + (jend - j), + tab) == -EINVAL) return; /* Mask out cluster bit */ @@ -1285,8 +1313,9 @@ static void gfar_cluster_filer(struct filer_table *tab) /* Swaps the masked bits of a1<>a2 and b1<>b2 */ static void gfar_swap_bits(struct gfar_filer_entry *a1, - struct gfar_filer_entry *a2, struct gfar_filer_entry *b1, - struct gfar_filer_entry *b2, u32 mask) + struct gfar_filer_entry *a2, + struct gfar_filer_entry *b1, + struct gfar_filer_entry *b2, u32 mask) { u32 temp[4]; temp[0] = a1->ctrl & mask; @@ -1305,13 +1334,12 @@ static void gfar_swap_bits(struct gfar_filer_entry *a1, b2->ctrl |= temp[2]; } -/* - * Generate a list consisting of masks values with their start and +/* Generate a list consisting of masks values with their start and * end of validity and block as indicator for parts belonging * together (glued by ANDs) in mask_table */ static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, - struct filer_table *tab) + struct filer_table *tab) { u32 i, and_index = 0, block_index = 1; @@ -1327,13 +1355,13 @@ static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, and_index++; } /* cluster starts and ends will be separated because they should - * hold their position */ + * hold their position + */ if (tab->fe[i].ctrl & RQFCR_CLE) block_index++; /* A not set AND indicates the end of a depended block */ if (!(tab->fe[i].ctrl & RQFCR_AND)) block_index++; - } mask_table[and_index - 1].end = i - 1; @@ -1341,14 +1369,13 @@ static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, return and_index; } -/* - * Sorts the entries of mask_table by the values of the masks. +/* Sorts the entries of mask_table by the values of the masks. * Important: The 0xFF80 flags of the first and last entry of a * block must hold their position (which queue, CLusterEnable, ReJEct, * AND) */ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, - struct filer_table *temp_table, u32 and_index) + struct filer_table *temp_table, u32 and_index) { /* Pointer to compare function (_asc or _desc) */ int (*gfar_comp)(const void *, const void *); @@ -1359,16 +1386,16 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, gfar_comp = &gfar_comp_desc; for (i = 0; i < and_index; i++) { - if (prev != mask_table[i].block) { old_first = mask_table[start].start + 1; old_last = mask_table[i - 1].end; sort(mask_table + start, size, - sizeof(struct gfar_mask_entry), - gfar_comp, &gfar_swap); + sizeof(struct gfar_mask_entry), + gfar_comp, &gfar_swap); /* Toggle order for every block. This makes the - * thing more efficient! */ + * thing more efficient! + */ if (gfar_comp == gfar_comp_desc) gfar_comp = &gfar_comp_asc; else @@ -1378,12 +1405,11 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, new_last = mask_table[i - 1].end; gfar_swap_bits(&temp_table->fe[new_first], - &temp_table->fe[old_first], - &temp_table->fe[new_last], - &temp_table->fe[old_last], - RQFCR_QUEUE | RQFCR_CLE | - RQFCR_RJE | RQFCR_AND - ); + &temp_table->fe[old_first], + &temp_table->fe[new_last], + &temp_table->fe[old_last], + RQFCR_QUEUE | RQFCR_CLE | + RQFCR_RJE | RQFCR_AND); start = i; size = 0; @@ -1391,11 +1417,9 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, size++; prev = mask_table[i].block; } - } -/* - * Reduces the number of masks needed in the filer table to save entries +/* Reduces the number of masks needed in the filer table to save entries * This is done by sorting the masks of a depended block. A depended block is * identified by gluing ANDs or CLE. The sorting order toggles after every * block. Of course entries in scope of a mask must change their location with @@ -1410,13 +1434,14 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) s32 ret = 0; /* We need a copy of the filer table because - * we want to change its order */ + * we want to change its order + */ temp_table = kmemdup(tab, sizeof(*temp_table), GFP_KERNEL); if (temp_table == NULL) return -ENOMEM; mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, - sizeof(struct gfar_mask_entry), GFP_KERNEL); + sizeof(struct gfar_mask_entry), GFP_KERNEL); if (mask_table == NULL) { ret = -ENOMEM; @@ -1428,7 +1453,8 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) gfar_sort_mask_table(mask_table, temp_table, and_index); /* Now we can copy the data from our duplicated filer table to - * the real one in the order the mask table says */ + * the real one in the order the mask table says + */ for (i = 0; i < and_index; i++) { size = mask_table[i].end - mask_table[i].start + 1; gfar_copy_filer_entries(&(tab->fe[j]), @@ -1437,7 +1463,8 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) } /* And finally we just have to check for duplicated masks and drop the - * second ones */ + * second ones + */ for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { if (tab->fe[i].ctrl == 0x80) { previous_mask = i++; @@ -1448,7 +1475,8 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) if (tab->fe[i].ctrl == 0x80) { if (tab->fe[i].prop == tab->fe[previous_mask].prop) { /* Two identical ones found! - * So drop the second one! */ + * So drop the second one! + */ gfar_trim_filer_entries(i, i, tab); } else /* Not identical! */ @@ -1463,7 +1491,7 @@ end: kfree(temp_table); /* Write the bit-pattern from software's buffer to hardware registers */ static int gfar_write_filer_table(struct gfar_private *priv, - struct filer_table *tab) + struct filer_table *tab) { u32 i = 0; if (tab->index > MAX_FILER_IDX - 1) @@ -1473,13 +1501,15 @@ static int gfar_write_filer_table(struct gfar_private *priv, lock_rx_qs(priv); /* Fill regular entries */ - for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); i++) + for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); + i++) gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop); /* Fill the rest with fall-troughs */ for (; i < MAX_FILER_IDX - 1; i++) gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF); /* Last entry must be default accept - * because that's what people expect */ + * because that's what people expect + */ gfar_write_filer(priv, i, 0x20, 0x0); unlock_rx_qs(priv); @@ -1488,21 +1518,21 @@ static int gfar_write_filer_table(struct gfar_private *priv, } static int gfar_check_capability(struct ethtool_rx_flow_spec *flow, - struct gfar_private *priv) + struct gfar_private *priv) { if (flow->flow_type & FLOW_EXT) { if (~flow->m_ext.data[0] || ~flow->m_ext.data[1]) netdev_warn(priv->ndev, - "User-specific data not supported!\n"); + "User-specific data not supported!\n"); if (~flow->m_ext.vlan_etype) netdev_warn(priv->ndev, - "VLAN-etype not supported!\n"); + "VLAN-etype not supported!\n"); } if (flow->flow_type == IP_USER_FLOW) if (flow->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4) netdev_warn(priv->ndev, - "IP-Version differing from IPv4 not supported!\n"); + "IP-Version differing from IPv4 not supported!\n"); return 0; } @@ -1520,15 +1550,18 @@ static int gfar_process_filer_changes(struct gfar_private *priv) return -ENOMEM; /* Now convert the existing filer data from flow_spec into - * filer tables binary format */ + * filer tables binary format + */ list_for_each_entry(j, &priv->rx_list.list, list) { ret = gfar_convert_to_filer(&j->fs, tab); if (ret == -EBUSY) { - netdev_err(priv->ndev, "Rule not added: No free space!\n"); + netdev_err(priv->ndev, + "Rule not added: No free space!\n"); goto end; } if (ret == -1) { - netdev_err(priv->ndev, "Rule not added: Unsupported Flow-type!\n"); + netdev_err(priv->ndev, + "Rule not added: Unsupported Flow-type!\n"); goto end; } } @@ -1540,9 +1573,9 @@ static int gfar_process_filer_changes(struct gfar_private *priv) gfar_optimize_filer_masks(tab); pr_debug("\n\tSummary:\n" - "\tData on hardware: %d\n" - "\tCompression rate: %d%%\n", - tab->index, 100 - (100 * tab->index) / i); + "\tData on hardware: %d\n" + "\tCompression rate: %d%%\n", + tab->index, 100 - (100 * tab->index) / i); /* Write everything to hardware */ ret = gfar_write_filer_table(priv, tab); @@ -1551,7 +1584,8 @@ static int gfar_process_filer_changes(struct gfar_private *priv) goto end; } -end: kfree(tab); +end: + kfree(tab); return ret; } @@ -1569,7 +1603,7 @@ static void gfar_invert_masks(struct ethtool_rx_flow_spec *flow) } static int gfar_add_cls(struct gfar_private *priv, - struct ethtool_rx_flow_spec *flow) + struct ethtool_rx_flow_spec *flow) { struct ethtool_flow_spec_container *temp, *comp; int ret = 0; @@ -1591,7 +1625,6 @@ static int gfar_add_cls(struct gfar_private *priv, list_add(&temp->list, &priv->rx_list.list); goto process; } else { - list_for_each_entry(comp, &priv->rx_list.list, list) { if (comp->fs.location > flow->location) { list_add_tail(&temp->list, &comp->list); @@ -1599,8 +1632,8 @@ static int gfar_add_cls(struct gfar_private *priv, } if (comp->fs.location == flow->location) { netdev_err(priv->ndev, - "Rule not added: ID %d not free!\n", - flow->location); + "Rule not added: ID %d not free!\n", + flow->location); ret = -EBUSY; goto clean_mem; } @@ -1642,7 +1675,6 @@ static int gfar_del_cls(struct gfar_private *priv, u32 loc) } return ret; - } static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) @@ -1663,7 +1695,7 @@ static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) } static int gfar_get_cls_all(struct gfar_private *priv, - struct ethtool_rxnfc *cmd, u32 *rule_locs) + struct ethtool_rxnfc *cmd, u32 *rule_locs) { struct ethtool_flow_spec_container *comp; u32 i = 0; @@ -1714,7 +1746,7 @@ static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) } static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, - u32 *rule_locs) + u32 *rule_locs) { struct gfar_private *priv = netdev_priv(dev); int ret = 0; @@ -1748,23 +1780,19 @@ static int gfar_get_ts_info(struct net_device *dev, struct gfar_private *priv = netdev_priv(dev); if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)) { - info->so_timestamping = - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE; + info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; info->phc_index = -1; return 0; } - info->so_timestamping = - SOF_TIMESTAMPING_TX_HARDWARE | - SOF_TIMESTAMPING_RX_HARDWARE | - SOF_TIMESTAMPING_RAW_HARDWARE; + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; info->phc_index = gfar_phc_index; - info->tx_types = - (1 << HWTSTAMP_TX_OFF) | - (1 << HWTSTAMP_TX_ON); - info->rx_filters = - (1 << HWTSTAMP_FILTER_NONE) | - (1 << HWTSTAMP_FILTER_ALL); + info->tx_types = (1 << HWTSTAMP_TX_OFF) | + (1 << HWTSTAMP_TX_ON); + info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_ALL); return 0; } -- GitLab From 27e1f9d1cc87be4e53c6eb7158cafc21c4b85a14 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 5 Jun 2012 13:36:44 +0200 Subject: [PATCH 0677/6849] blkcg: drop local variable @q from blkg_destroy() blkg_destroy() caches @blkg->q in local variable @q. While there are two places which needs @blkg->q, only lockdep_assert_held() used the local variable leading to unused local variable warning if lockdep is configured out. Drop the local variable and just use @blkg->q directly. Signed-off-by: Tejun Heo Reported-by: Rakesh Iyer Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 4ab7420ba465..e7dee617358e 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -241,10 +241,9 @@ EXPORT_SYMBOL_GPL(blkg_lookup_create); static void blkg_destroy(struct blkcg_gq *blkg) { - struct request_queue *q = blkg->q; struct blkcg *blkcg = blkg->blkcg; - lockdep_assert_held(q->queue_lock); + lockdep_assert_held(blkg->q->queue_lock); lockdep_assert_held(&blkcg->lock); /* Something wrong if we are trying to remove same group twice */ -- GitLab From 7db971b235480849aa5b9209b67b62e987b3181b Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Sun, 3 Jun 2012 01:11:34 +0300 Subject: [PATCH 0678/6849] x86/platform: Introduce APIC post-initialization callback Some subarchitectures (such as vSMP) need to slightly adjust the underlying APIC structure. Add an APIC post-initialization callback to 'struct x86_platform_ops' for this purpose and use it for adjusting the APIC structure on vSMP systems. Signed-off-by: Ido Yariv Acked-by: Shai Fultheim Link: http://lkml.kernel.org/r/1338675095-27260-1-git-send-email-ido@wizery.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/x86_init.h | 2 ++ arch/x86/kernel/apic/probe_32.c | 3 +++ arch/x86/kernel/apic/probe_64.c | 11 ++--------- arch/x86/kernel/vsmp_64.c | 13 +++++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index c090af10ac7d..c377d9ccb696 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -164,6 +164,7 @@ struct x86_cpuinit_ops { * @i8042_detect pre-detect if i8042 controller exists * @save_sched_clock_state: save state for sched_clock() on suspend * @restore_sched_clock_state: restore state for sched_clock() on resume + * @apic_post_init: adjust apic if neeeded */ struct x86_platform_ops { unsigned long (*calibrate_tsc)(void); @@ -177,6 +178,7 @@ struct x86_platform_ops { int (*i8042_detect)(void); void (*save_sched_clock_state)(void); void (*restore_sched_clock_state)(void); + void (*apic_post_init)(void); }; struct pci_dev; diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 1b291da09e60..8616d5198e16 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -208,6 +208,9 @@ void __init default_setup_apic_routing(void) if (apic->setup_apic_routing) apic->setup_apic_routing(); + + if (x86_platform.apic_post_init) + x86_platform.apic_post_init(); } void __init generic_apic_probe(void) diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 3fe986698929..1793dba7a741 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -23,11 +23,6 @@ #include #include -static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) -{ - return hard_smp_processor_id() >> index_msb; -} - /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ @@ -48,10 +43,8 @@ void __init default_setup_apic_routing(void) } } - if (is_vsmp_box()) { - /* need to update phys_pkg_id */ - apic->phys_pkg_id = apicid_phys_pkg_id; - } + if (x86_platform.apic_post_init) + x86_platform.apic_post_init(); } /* Same for both flat and physical. */ diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 8eeb55a551b4..59eea855f451 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -187,12 +187,25 @@ static void __init vsmp_cap_cpus(void) #endif } +static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) +{ + return hard_smp_processor_id() >> index_msb; +} + +static void vsmp_apic_post_init(void) +{ + /* need to update phys_pkg_id */ + apic->phys_pkg_id = apicid_phys_pkg_id; +} + void __init vsmp_init(void) { detect_vsmp_box(); if (!is_vsmp_box()) return; + x86_platform.apic_post_init = vsmp_apic_post_init; + vsmp_cap_cpus(); set_vsmp_pv_ops(); -- GitLab From c767a54ba0657e52e6edaa97cbe0b0a8bf1c1655 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 21 May 2012 19:50:07 -0700 Subject: [PATCH 0679/6849] x86/debug: Add KERN_ to bare printks, convert printks to pr_ Use a more current logging style: - Bare printks should have a KERN_ for consistency's sake - Add pr_fmt where appropriate - Neaten some macro definitions - Convert some Ok output to OK - Use "%s: ", __func__ in pr_fmt for summit - Convert some printks to pr_ Message output is not identical in all cases. Signed-off-by: Joe Perches Cc: levinsasha928@gmail.com Link: http://lkml.kernel.org/r/1337655007.24226.10.camel@joe2Laptop [ merged two similar patches, tidied up the changelog ] Signed-off-by: Ingo Molnar --- arch/x86/include/asm/floppy.h | 2 +- arch/x86/include/asm/pci_x86.h | 8 ++- arch/x86/include/asm/pgtable-2level.h | 4 +- arch/x86/include/asm/pgtable-3level.h | 6 +- arch/x86/include/asm/pgtable_64.h | 8 +-- arch/x86/kernel/alternative.c | 17 +++-- arch/x86/kernel/amd_nb.c | 10 +-- arch/x86/kernel/apic/io_apic.c | 38 +++++----- arch/x86/kernel/apic/summit_32.c | 22 +++--- arch/x86/kernel/apm_32.c | 29 ++++---- arch/x86/kernel/cpu/bugs.c | 20 +++--- arch/x86/kernel/cpu/mcheck/mce.c | 22 +++--- arch/x86/kernel/cpu/perf_event_intel.c | 14 ++-- arch/x86/kernel/dumpstack.c | 4 +- arch/x86/kernel/dumpstack_32.c | 24 +++---- arch/x86/kernel/dumpstack_64.c | 20 +++--- arch/x86/kernel/irq.c | 4 +- arch/x86/kernel/module.c | 32 +++++---- arch/x86/kernel/pci-calgary_64.c | 34 +++++---- arch/x86/kernel/process.c | 34 +++++---- arch/x86/kernel/process_64.c | 8 +-- arch/x86/kernel/reboot.c | 14 ++-- arch/x86/kernel/signal.c | 5 +- arch/x86/kernel/smpboot.c | 97 ++++++++++++-------------- arch/x86/kernel/traps.c | 19 ++--- arch/x86/kernel/tsc.c | 50 +++++++------ arch/x86/kernel/vm86_32.c | 6 +- arch/x86/kernel/vsyscall_64.c | 17 ++--- arch/x86/kernel/xsave.c | 12 ++-- 29 files changed, 301 insertions(+), 279 deletions(-) diff --git a/arch/x86/include/asm/floppy.h b/arch/x86/include/asm/floppy.h index dbe82a5c5eac..d3d74698dce9 100644 --- a/arch/x86/include/asm/floppy.h +++ b/arch/x86/include/asm/floppy.h @@ -99,7 +99,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) virtual_dma_residue += virtual_dma_count; virtual_dma_count = 0; #ifdef TRACE_FLPY_INT - printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", + printk(KERN_DEBUG "count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", virtual_dma_count, virtual_dma_residue, calls, bytes, dma_wait); calls = 0; diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b3a531746026..5ad24a89b19b 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -7,9 +7,13 @@ #undef DEBUG #ifdef DEBUG -#define DBG(x...) printk(x) +#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__) #else -#define DBG(x...) +#define DBG(fmt, ...) \ +do { \ + if (0) \ + printk(fmt, ##__VA_ARGS__); \ +} while (0) #endif #define PCI_PROBE_BIOS 0x0001 diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index 98391db840c6..f2b489cf1602 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h @@ -2,9 +2,9 @@ #define _ASM_X86_PGTABLE_2LEVEL_H #define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) + pr_err("%s:%d: bad pte %08lx\n", __FILE__, __LINE__, (e).pte_low) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + pr_err("%s:%d: bad pgd %08lx\n", __FILE__, __LINE__, pgd_val(e)) /* * Certain architectures need to do special things when PTEs diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 43876f16caf1..f824cfbaa9d4 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h @@ -9,13 +9,13 @@ */ #define pte_ERROR(e) \ - printk("%s:%d: bad pte %p(%08lx%08lx).\n", \ + pr_err("%s:%d: bad pte %p(%08lx%08lx)\n", \ __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low) #define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %p(%016Lx).\n", \ + pr_err("%s:%d: bad pmd %p(%016Lx)\n", \ __FILE__, __LINE__, &(e), pmd_val(e)) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %p(%016Lx).\n", \ + pr_err("%s:%d: bad pgd %p(%016Lx)\n", \ __FILE__, __LINE__, &(e), pgd_val(e)) /* Rules for using set_pte: the pte being assigned *must* be diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 975f709e09ae..8251be02301e 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -26,16 +26,16 @@ extern pgd_t init_level4_pgt[]; extern void paging_init(void); #define pte_ERROR(e) \ - printk("%s:%d: bad pte %p(%016lx).\n", \ + pr_err("%s:%d: bad pte %p(%016lx)\n", \ __FILE__, __LINE__, &(e), pte_val(e)) #define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %p(%016lx).\n", \ + pr_err("%s:%d: bad pmd %p(%016lx)\n", \ __FILE__, __LINE__, &(e), pmd_val(e)) #define pud_ERROR(e) \ - printk("%s:%d: bad pud %p(%016lx).\n", \ + pr_err("%s:%d: bad pud %p(%016lx)\n", \ __FILE__, __LINE__, &(e), pud_val(e)) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %p(%016lx).\n", \ + pr_err("%s:%d: bad pgd %p(%016lx)\n", \ __FILE__, __LINE__, &(e), pgd_val(e)) struct mm_struct; diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 1f84794f0759..1729d720299a 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) "SMP alternatives: " fmt + #include #include #include @@ -63,8 +65,11 @@ static int __init setup_noreplace_paravirt(char *str) __setup("noreplace-paravirt", setup_noreplace_paravirt); #endif -#define DPRINTK(fmt, args...) if (debug_alternative) \ - printk(KERN_DEBUG fmt, args) +#define DPRINTK(fmt, ...) \ +do { \ + if (debug_alternative) \ + printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ +} while (0) /* * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes @@ -428,7 +433,7 @@ void alternatives_smp_switch(int smp) * If this still occurs then you should see a hang * or crash shortly after this line: */ - printk("lockdep: fixing up alternatives.\n"); + pr_info("lockdep: fixing up alternatives\n"); #endif if (noreplace_smp || smp_alt_once || skip_smp_alternatives) @@ -444,14 +449,14 @@ void alternatives_smp_switch(int smp) if (smp == smp_mode) { /* nothing */ } else if (smp) { - printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); + pr_info("switching to SMP code\n"); clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP); list_for_each_entry(mod, &smp_alt_modules, next) alternatives_smp_lock(mod->locks, mod->locks_end, mod->text, mod->text_end); } else { - printk(KERN_INFO "SMP alternatives: switching to UP code\n"); + pr_info("switching to UP code\n"); set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); list_for_each_entry(mod, &smp_alt_modules, next) @@ -546,7 +551,7 @@ void __init alternative_instructions(void) #ifdef CONFIG_SMP if (smp_alt_once) { if (1 == num_possible_cpus()) { - printk(KERN_INFO "SMP alternatives: switching to UP code\n"); + pr_info("switching to UP code\n"); set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index be16854591cc..f29f6dd6bc08 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -2,6 +2,9 @@ * Shared support code for AMD K8 northbridges and derivates. * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -258,7 +261,7 @@ void amd_flush_garts(void) } spin_unlock_irqrestore(&gart_lock, flags); if (!flushed) - printk("nothing to flush?\n"); + pr_notice("nothing to flush?\n"); } EXPORT_SYMBOL_GPL(amd_flush_garts); @@ -269,11 +272,10 @@ static __init int init_amd_nbs(void) err = amd_cache_northbridges(); if (err < 0) - printk(KERN_NOTICE "AMD NB: Cannot enumerate AMD northbridges.\n"); + pr_notice("Cannot enumerate AMD northbridges\n"); if (amd_cache_gart() < 0) - printk(KERN_NOTICE "AMD NB: Cannot initialize GART flush words, " - "GART support disabled.\n"); + pr_notice("Cannot initialize GART flush words, GART support disabled\n"); return err; } diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ac96561d1a99..5155d6f806f5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -448,8 +448,8 @@ static int __add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pi entry = alloc_irq_pin_list(node); if (!entry) { - printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n", - node, apic, pin); + pr_err("can not alloc irq_pin_list (%d,%d,%d)\n", + node, apic, pin); return -ENOMEM; } entry->apic = apic; @@ -661,7 +661,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) ioapic_mask_entry(apic, pin); entry = ioapic_read_entry(apic, pin); if (entry.irr) - printk(KERN_ERR "Unable to reset IRR for apic: %d, pin :%d\n", + pr_err("Unable to reset IRR for apic: %d, pin :%d\n", mpc_ioapic_id(apic), pin); } @@ -895,7 +895,7 @@ static int irq_polarity(int idx) } case 2: /* reserved */ { - printk(KERN_WARNING "broken BIOS!!\n"); + pr_warn("broken BIOS!!\n"); polarity = 1; break; } @@ -906,7 +906,7 @@ static int irq_polarity(int idx) } default: /* invalid */ { - printk(KERN_WARNING "broken BIOS!!\n"); + pr_warn("broken BIOS!!\n"); polarity = 1; break; } @@ -948,7 +948,7 @@ static int irq_trigger(int idx) } default: { - printk(KERN_WARNING "broken BIOS!!\n"); + pr_warn("broken BIOS!!\n"); trigger = 1; break; } @@ -962,7 +962,7 @@ static int irq_trigger(int idx) } case 2: /* reserved */ { - printk(KERN_WARNING "broken BIOS!!\n"); + pr_warn("broken BIOS!!\n"); trigger = 1; break; } @@ -973,7 +973,7 @@ static int irq_trigger(int idx) } default: /* invalid */ { - printk(KERN_WARNING "broken BIOS!!\n"); + pr_warn("broken BIOS!!\n"); trigger = 0; break; } @@ -991,7 +991,7 @@ static int pin_2_irq(int idx, int apic, int pin) * Debugging check, we are in big trouble if this message pops up! */ if (mp_irqs[idx].dstirq != pin) - printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); + pr_err("broken BIOS or MPTABLE parser, ayiee!!\n"); if (test_bit(bus, mp_bus_not_pci)) { irq = mp_irqs[idx].srcbusirq; @@ -1521,7 +1521,6 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) reg_03.raw = io_apic_read(ioapic_idx, 3); raw_spin_unlock_irqrestore(&ioapic_lock, flags); - printk("\n"); printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(ioapic_idx)); printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); @@ -1578,7 +1577,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) i, ir_entry->index ); - printk("%1d %1d %1d %1d %1d " + pr_cont("%1d %1d %1d %1d %1d " "%1d %1d %X %02X\n", ir_entry->format, ir_entry->mask, @@ -1598,7 +1597,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) i, entry.dest ); - printk("%1d %1d %1d %1d %1d " + pr_cont("%1d %1d %1d %1d %1d " "%1d %1d %02X\n", entry.mask, entry.trigger, @@ -1651,8 +1650,8 @@ __apicdebuginit(void) print_IO_APICs(void) continue; printk(KERN_DEBUG "IRQ%d ", irq); for_each_irq_pin(entry, cfg->irq_2_pin) - printk("-> %d:%d", entry->apic, entry->pin); - printk("\n"); + pr_cont("-> %d:%d", entry->apic, entry->pin); + pr_cont("\n"); } printk(KERN_INFO ".................................... done.\n"); @@ -1665,9 +1664,9 @@ __apicdebuginit(void) print_APIC_field(int base) printk(KERN_DEBUG); for (i = 0; i < 8; i++) - printk(KERN_CONT "%08x", apic_read(base + i*0x10)); + pr_cont("%08x", apic_read(base + i*0x10)); - printk(KERN_CONT "\n"); + pr_cont("\n"); } __apicdebuginit(void) print_local_APIC(void *dummy) @@ -1769,7 +1768,7 @@ __apicdebuginit(void) print_local_APIC(void *dummy) printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v); } } - printk("\n"); + pr_cont("\n"); } __apicdebuginit(void) print_local_APICs(int maxcpu) @@ -2065,7 +2064,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) reg_00.raw = io_apic_read(ioapic_idx, 0); raw_spin_unlock_irqrestore(&ioapic_lock, flags); if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx)) - printk("could not set ID!\n"); + pr_cont("could not set ID!\n"); else apic_printk(APIC_VERBOSE, " ok.\n"); } @@ -3563,7 +3562,8 @@ static int __init io_apic_get_unique_id(int ioapic, int apic_id) /* Sanity check */ if (reg_00.bits.ID != apic_id) { - printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); + pr_err("IOAPIC[%d]: Unable to change apic_id!\n", + ioapic); return -1; } } diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 659897c00755..e97d542ccdd0 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -26,6 +26,8 @@ * */ +#define pr_fmt(fmt) "summit: %s: " fmt, __func__ + #include #include #include @@ -235,8 +237,8 @@ static int summit_apic_id_registered(void) static void summit_setup_apic_routing(void) { - printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", - nr_ioapics); + pr_info("Enabling APIC mode: Summit. Using %d I/O APICs\n", + nr_ioapics); } static int summit_cpu_present_to_apicid(int mps_cpu) @@ -275,7 +277,7 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk("%s: Not a valid mask!\n", __func__); + pr_err("Not a valid mask!\n"); return BAD_APICID; } apicid |= new_apicid; @@ -355,7 +357,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) } } if (i == rio_table_hdr->num_rio_dev) { - printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__); + pr_err("Couldn't find owner Cyclone for Winnipeg!\n"); return last_bus; } @@ -366,7 +368,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) } } if (i == rio_table_hdr->num_scal_dev) { - printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__); + pr_err("Couldn't find owner Twister for Cyclone!\n"); return last_bus; } @@ -396,7 +398,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) num_buses = 9; break; default: - printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__); + pr_info("Unsupported Winnipeg type!\n"); return last_bus; } @@ -411,13 +413,15 @@ static int build_detail_arrays(void) int i, scal_detail_size, rio_detail_size; if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) { - printk(KERN_WARNING "%s: MAX_NUMNODES too low! Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev); + pr_warn("MAX_NUMNODES too low! Defined as %d, but system has %d nodes\n", + MAX_NUMNODES, rio_table_hdr->num_scal_dev); return 0; } switch (rio_table_hdr->version) { default: - printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version); + pr_warn("Invalid Rio Grande Table Version: %d\n", + rio_table_hdr->version); return 0; case 2: scal_detail_size = 11; @@ -462,7 +466,7 @@ void setup_summit(void) offset = *((unsigned short *)(ptr + offset)); } if (!rio_table_hdr) { - printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__); + pr_err("Unable to locate Rio Grande Table in EBDA - bailing!\n"); return; } diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 07b0c0db466c..d65464e43503 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -201,6 +201,8 @@ * http://www.microsoft.com/whdc/archive/amp_12.mspx] */ +#define pr_fmt(fmt) "apm: " fmt + #include #include @@ -485,11 +487,11 @@ static void apm_error(char *str, int err) if (error_table[i].key == err) break; if (i < ERROR_COUNT) - printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg); + pr_notice("%s: %s\n", str, error_table[i].msg); else if (err < 0) - printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err); + pr_notice("%s: linux error code %i\n", str, err); else - printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n", + pr_notice("%s: unknown error code %#2.2x\n", str, err); } @@ -1184,7 +1186,7 @@ static void queue_event(apm_event_t event, struct apm_user *sender) static int notified; if (notified++ == 0) - printk(KERN_ERR "apm: an event queue overflowed\n"); + pr_err("an event queue overflowed\n"); if (++as->event_tail >= APM_MAX_EVENTS) as->event_tail = 0; } @@ -1447,7 +1449,7 @@ static void apm_mainloop(void) static int check_apm_user(struct apm_user *as, const char *func) { if (as == NULL || as->magic != APM_BIOS_MAGIC) { - printk(KERN_ERR "apm: %s passed bad filp\n", func); + pr_err("%s passed bad filp\n", func); return 1; } return 0; @@ -1586,7 +1588,7 @@ static int do_release(struct inode *inode, struct file *filp) as1 = as1->next) ; if (as1 == NULL) - printk(KERN_ERR "apm: filp not in user list\n"); + pr_err("filp not in user list\n"); else as1->next = as->next; } @@ -1600,11 +1602,9 @@ static int do_open(struct inode *inode, struct file *filp) struct apm_user *as; as = kmalloc(sizeof(*as), GFP_KERNEL); - if (as == NULL) { - printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", - sizeof(*as)); + if (as == NULL) return -ENOMEM; - } + as->magic = APM_BIOS_MAGIC; as->event_tail = as->event_head = 0; as->suspends_pending = as->standbys_pending = 0; @@ -2313,16 +2313,16 @@ static int __init apm_init(void) } if (apm_info.disabled) { - printk(KERN_NOTICE "apm: disabled on user request.\n"); + pr_notice("disabled on user request.\n"); return -ENODEV; } if ((num_online_cpus() > 1) && !power_off && !smp) { - printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n"); + pr_notice("disabled - APM is not SMP safe.\n"); apm_info.disabled = 1; return -ENODEV; } if (!acpi_disabled) { - printk(KERN_NOTICE "apm: overridden by ACPI.\n"); + pr_notice("overridden by ACPI.\n"); apm_info.disabled = 1; return -ENODEV; } @@ -2356,8 +2356,7 @@ static int __init apm_init(void) kapmd_task = kthread_create(apm, NULL, "kapmd"); if (IS_ERR(kapmd_task)) { - printk(KERN_ERR "apm: disabled - Unable to start kernel " - "thread.\n"); + pr_err("disabled - Unable to start kernel thread\n"); err = PTR_ERR(kapmd_task); kapmd_task = NULL; remove_proc_entry("apm", NULL); diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 46674fbb62ba..c97bb7b5a9f8 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -55,8 +55,8 @@ static void __init check_fpu(void) if (!boot_cpu_data.hard_math) { #ifndef CONFIG_MATH_EMULATION - printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); - printk(KERN_EMERG "Giving up.\n"); + pr_emerg("No coprocessor found and no math emulation present\n"); + pr_emerg("Giving up\n"); for (;;) ; #endif return; @@ -86,7 +86,7 @@ static void __init check_fpu(void) boot_cpu_data.fdiv_bug = fdiv_bug; if (boot_cpu_data.fdiv_bug) - printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n"); + pr_warn("Hmm, FPU with FDIV bug\n"); } static void __init check_hlt(void) @@ -94,16 +94,16 @@ static void __init check_hlt(void) if (boot_cpu_data.x86 >= 5 || paravirt_enabled()) return; - printk(KERN_INFO "Checking 'hlt' instruction... "); + pr_info("Checking 'hlt' instruction... "); if (!boot_cpu_data.hlt_works_ok) { - printk("disabled\n"); + pr_cont("disabled\n"); return; } halt(); halt(); halt(); halt(); - printk(KERN_CONT "OK.\n"); + pr_cont("OK\n"); } /* @@ -116,7 +116,7 @@ static void __init check_popad(void) #ifndef CONFIG_X86_POPAD_OK int res, inp = (int) &res; - printk(KERN_INFO "Checking for popad bug... "); + pr_info("Checking for popad bug... "); __asm__ __volatile__( "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " : "=&a" (res) @@ -127,9 +127,9 @@ static void __init check_popad(void) * CPU hard. Too bad. */ if (res != 12345678) - printk(KERN_CONT "Buggy.\n"); + pr_cont("Buggy\n"); else - printk(KERN_CONT "OK.\n"); + pr_cont("OK\n"); #endif } @@ -161,7 +161,7 @@ void __init check_bugs(void) { identify_boot_cpu(); #ifndef CONFIG_SMP - printk(KERN_INFO "CPU: "); + pr_info("CPU: "); print_cpu_info(&boot_cpu_data); #endif check_config(); diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 0a687fd185e6..5623b4b5d511 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -7,6 +7,9 @@ * Copyright 2008 Intel Corporation * Author: Andi Kleen */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -210,7 +213,7 @@ static void drain_mcelog_buffer(void) cpu_relax(); if (!m->finished && retries >= 4) { - pr_err("MCE: skipping error being logged currently!\n"); + pr_err("skipping error being logged currently!\n"); break; } } @@ -1167,8 +1170,9 @@ int memory_failure(unsigned long pfn, int vector, int flags) { /* mce_severity() should not hand us an ACTION_REQUIRED error */ BUG_ON(flags & MF_ACTION_REQUIRED); - printk(KERN_ERR "Uncorrected memory error in page 0x%lx ignored\n" - "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", pfn); + pr_err("Uncorrected memory error in page 0x%lx ignored\n" + "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", + pfn); return 0; } @@ -1358,11 +1362,10 @@ static int __cpuinit __mcheck_cpu_cap_init(void) b = cap & MCG_BANKCNT_MASK; if (!banks) - printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b); + pr_info("CPU supports %d MCE banks\n", b); if (b > MAX_NR_BANKS) { - printk(KERN_WARNING - "MCE: Using only %u machine check banks out of %u\n", + pr_warn("Using only %u machine check banks out of %u\n", MAX_NR_BANKS, b); b = MAX_NR_BANKS; } @@ -1419,7 +1422,7 @@ static void __mcheck_cpu_init_generic(void) static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) { if (c->x86_vendor == X86_VENDOR_UNKNOWN) { - pr_info("MCE: unknown CPU type - not enabling MCE support.\n"); + pr_info("unknown CPU type - not enabling MCE support\n"); return -EOPNOTSUPP; } @@ -1574,7 +1577,7 @@ static void __mcheck_cpu_init_timer(void) /* Handle unconfigured int18 (should never happen) */ static void unexpected_machine_check(struct pt_regs *regs, long error_code) { - printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", + pr_err("CPU#%d: Unexpected int18 (Machine Check)\n", smp_processor_id()); } @@ -1893,8 +1896,7 @@ static int __init mcheck_enable(char *str) get_option(&str, &monarch_timeout); } } else { - printk(KERN_INFO "mce argument %s ignored. Please use /sys\n", - str); + pr_info("mce argument %s ignored. Please use /sys\n", str); return 0; } return 1; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 166546ec6aef..9e3f5d6e3d20 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -5,6 +5,8 @@ * among events on a single PMU. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1000,7 +1002,7 @@ static void intel_pmu_reset(void) local_irq_save(flags); - printk("clearing PMU state on CPU#%d\n", smp_processor_id()); + pr_info("clearing PMU state on CPU#%d\n", smp_processor_id()); for (idx = 0; idx < x86_pmu.num_counters; idx++) { checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); @@ -1638,14 +1640,14 @@ static __init void intel_clovertown_quirk(void) * But taken together it might just make sense to not enable PEBS on * these chips. */ - printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); + pr_warn("PEBS disabled due to CPU errata\n"); x86_pmu.pebs = 0; x86_pmu.pebs_constraints = NULL; } static __init void intel_sandybridge_quirk(void) { - printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); + pr_warn("PEBS disabled due to CPU errata\n"); x86_pmu.pebs = 0; x86_pmu.pebs_constraints = NULL; } @@ -1667,8 +1669,8 @@ static __init void intel_arch_events_quirk(void) /* disable event that reported as not presend by cpuid */ for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) { intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0; - printk(KERN_WARNING "CPUID marked event: \'%s\' unavailable\n", - intel_arch_events_map[bit].name); + pr_warn("CPUID marked event: \'%s\' unavailable\n", + intel_arch_events_map[bit].name); } } @@ -1687,7 +1689,7 @@ static __init void intel_nehalem_quirk(void) intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; ebx.split.no_branch_misses_retired = 0; x86_pmu.events_maskl = ebx.full; - printk(KERN_INFO "CPU erratum AAJ80 worked around\n"); + pr_info("CPU erratum AAJ80 worked around\n"); } } diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 571246d81edf..87d3b5d663cd 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -27,8 +27,8 @@ static int die_counter; void printk_address(unsigned long address, int reliable) { - printk(" [<%p>] %s%pB\n", (void *) address, - reliable ? "" : "? ", (void *) address); + pr_cont(" [<%p>] %s%pB\n", + (void *)address, reliable ? "" : "? ", (void *)address); } #ifdef CONFIG_FUNCTION_GRAPH_TRACER diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index e0b1d783daab..3a8aced11ae9 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -73,11 +73,11 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, if (kstack_end(stack)) break; if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - printk(KERN_CONT "\n"); - printk(KERN_CONT " %08lx", *stack++); + pr_cont("\n"); + pr_cont(" %08lx", *stack++); touch_nmi_watchdog(); } - printk(KERN_CONT "\n"); + pr_cont("\n"); show_trace_log_lvl(task, regs, sp, bp, log_lvl); } @@ -89,9 +89,9 @@ void show_regs(struct pt_regs *regs) print_modules(); __show_regs(regs, !user_mode_vm(regs)); - printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", - TASK_COMM_LEN, current->comm, task_pid_nr(current), - current_thread_info(), current, task_thread_info(current)); + pr_emerg("Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", + TASK_COMM_LEN, current->comm, task_pid_nr(current), + current_thread_info(), current, task_thread_info(current)); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. @@ -102,10 +102,10 @@ void show_regs(struct pt_regs *regs) unsigned char c; u8 *ip; - printk(KERN_EMERG "Stack:\n"); + pr_emerg("Stack:\n"); show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); - printk(KERN_EMERG "Code: "); + pr_emerg("Code:"); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { @@ -116,16 +116,16 @@ void show_regs(struct pt_regs *regs) for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - printk(KERN_CONT " Bad EIP value."); + pr_cont(" Bad EIP value."); break; } if (ip == (u8 *)regs->ip) - printk(KERN_CONT "<%02x> ", c); + pr_cont(" <%02x>", c); else - printk(KERN_CONT "%02x ", c); + pr_cont(" %02x", c); } } - printk(KERN_CONT "\n"); + pr_cont("\n"); } int is_valid_bugaddr(unsigned long ip) diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 791b76122aa8..c582e9c5bd1a 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -228,20 +228,20 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, if (stack >= irq_stack && stack <= irq_stack_end) { if (stack == irq_stack_end) { stack = (unsigned long *) (irq_stack_end[-1]); - printk(KERN_CONT " "); + pr_cont(" "); } } else { if (((long) stack & (THREAD_SIZE-1)) == 0) break; } if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - printk(KERN_CONT "\n"); - printk(KERN_CONT " %016lx", *stack++); + pr_cont("\n"); + pr_cont(" %016lx", *stack++); touch_nmi_watchdog(); } preempt_enable(); - printk(KERN_CONT "\n"); + pr_cont("\n"); show_trace_log_lvl(task, regs, sp, bp, log_lvl); } @@ -256,8 +256,8 @@ void show_regs(struct pt_regs *regs) printk("CPU %d ", cpu); print_modules(); __show_regs(regs, 1); - printk("Process %s (pid: %d, threadinfo %p, task %p)\n", - cur->comm, cur->pid, task_thread_info(cur), cur); + printk(KERN_DEFAULT "Process %s (pid: %d, threadinfo %p, task %p)\n", + cur->comm, cur->pid, task_thread_info(cur), cur); /* * When in-kernel, we also print out the stack and code at the @@ -284,16 +284,16 @@ void show_regs(struct pt_regs *regs) for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - printk(KERN_CONT " Bad RIP value."); + pr_cont(" Bad RIP value."); break; } if (ip == (u8 *)regs->ip) - printk(KERN_CONT "<%02x> ", c); + pr_cont("<%02x> ", c); else - printk(KERN_CONT "%02x ", c); + pr_cont("%02x ", c); } } - printk(KERN_CONT "\n"); + pr_cont("\n"); } int is_valid_bugaddr(unsigned long ip) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3dafc6003b7c..1f5f1d5d2a02 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -294,9 +294,9 @@ void fixup_irqs(void) raw_spin_unlock(&desc->lock); if (break_affinity && set_affinity) - printk("Broke affinity for irq %i\n", irq); + pr_notice("Broke affinity for irq %i\n", irq); else if (!set_affinity) - printk("Cannot set affinity for irq %i\n", irq); + pr_notice("Cannot set affinity for irq %i\n", irq); } /* diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index f21fd94ac897..202494d2ec6e 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -15,6 +15,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -30,9 +33,14 @@ #include #if 0 -#define DEBUGP printk +#define DEBUGP(fmt, ...) \ + printk(KERN_DEBUG fmt, ##__VA_ARGS__) #else -#define DEBUGP(fmt...) +#define DEBUGP(fmt, ...) \ +do { \ + if (0) \ + printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ +} while (0) #endif void *module_alloc(unsigned long size) @@ -56,8 +64,8 @@ int apply_relocate(Elf32_Shdr *sechdrs, Elf32_Sym *sym; uint32_t *location; - DEBUGP("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); + DEBUGP("Applying relocate section %u to %u\n", + relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr @@ -77,7 +85,7 @@ int apply_relocate(Elf32_Shdr *sechdrs, *location += sym->st_value - (uint32_t)location; break; default: - printk(KERN_ERR "module %s: Unknown relocation: %u\n", + pr_err("%s: Unknown relocation: %u\n", me->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -97,8 +105,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, void *loc; u64 val; - DEBUGP("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); + DEBUGP("Applying relocate section %u to %u\n", + relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr @@ -110,8 +118,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, + ELF64_R_SYM(rel[i].r_info); DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n", - (int)ELF64_R_TYPE(rel[i].r_info), - sym->st_value, rel[i].r_addend, (u64)loc); + (int)ELF64_R_TYPE(rel[i].r_info), + sym->st_value, rel[i].r_addend, (u64)loc); val = sym->st_value + rel[i].r_addend; @@ -140,7 +148,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, #endif break; default: - printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n", + pr_err("%s: Unknown rela relocation: %llu\n", me->name, ELF64_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -148,9 +156,9 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return 0; overflow: - printk(KERN_ERR "overflow in relocation type %d val %Lx\n", + pr_err("overflow in relocation type %d val %Lx\n", (int)ELF64_R_TYPE(rel[i].r_info), val); - printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n", + pr_err("`%s' likely not compiled with -mcmodel=kernel\n", me->name); return -ENOEXEC; } diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index b72838bae64a..299d49302e7d 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -22,6 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define pr_fmt(fmt) "Calgary: " fmt + #include #include #include @@ -245,7 +247,7 @@ static unsigned long iommu_range_alloc(struct device *dev, offset = iommu_area_alloc(tbl->it_map, tbl->it_size, 0, npages, 0, boundary_size, 0); if (offset == ~0UL) { - printk(KERN_WARNING "Calgary: IOMMU full.\n"); + pr_warn("IOMMU full\n"); spin_unlock_irqrestore(&tbl->it_lock, flags); if (panic_on_overflow) panic("Calgary: fix the allocator.\n"); @@ -271,8 +273,8 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl, entry = iommu_range_alloc(dev, tbl, npages); if (unlikely(entry == DMA_ERROR_CODE)) { - printk(KERN_WARNING "Calgary: failed to allocate %u pages in " - "iommu %p\n", npages, tbl); + pr_warn("failed to allocate %u pages in iommu %p\n", + npages, tbl); return DMA_ERROR_CODE; } @@ -561,8 +563,7 @@ static void calgary_tce_cache_blast(struct iommu_table *tbl) i++; } while ((val & 0xff) != 0xff && i < 100); if (i == 100) - printk(KERN_WARNING "Calgary: PCI bus not quiesced, " - "continuing anyway\n"); + pr_warn("PCI bus not quiesced, continuing anyway\n"); /* invalidate TCE cache */ target = calgary_reg(bbar, tar_offset(tbl->it_busno)); @@ -604,8 +605,7 @@ begin: i++; } while ((val64 & 0xff) != 0xff && i < 100); if (i == 100) - printk(KERN_WARNING "CalIOC2: PCI bus not quiesced, " - "continuing anyway\n"); + pr_warn("CalIOC2: PCI bus not quiesced, continuing anyway\n"); /* 3. poll Page Migration DEBUG for SoftStopFault */ target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG); @@ -617,8 +617,7 @@ begin: if (++count < 100) goto begin; else { - printk(KERN_WARNING "CalIOC2: too many SoftStopFaults, " - "aborting TCE cache flush sequence!\n"); + pr_warn("CalIOC2: too many SoftStopFaults, aborting TCE cache flush sequence!\n"); return; /* pray for the best */ } } @@ -840,8 +839,8 @@ static void calgary_dump_error_regs(struct iommu_table *tbl) plssr = be32_to_cpu(readl(target)); /* If no error, the agent ID in the CSR is not valid */ - printk(KERN_EMERG "Calgary: DMA error on Calgary PHB 0x%x, " - "0x%08x@CSR 0x%08x@PLSSR\n", tbl->it_busno, csr, plssr); + pr_emerg("DMA error on Calgary PHB 0x%x, 0x%08x@CSR 0x%08x@PLSSR\n", + tbl->it_busno, csr, plssr); } static void calioc2_dump_error_regs(struct iommu_table *tbl) @@ -867,22 +866,21 @@ static void calioc2_dump_error_regs(struct iommu_table *tbl) target = calgary_reg(bbar, phboff | 0x800); mck = be32_to_cpu(readl(target)); - printk(KERN_EMERG "Calgary: DMA error on CalIOC2 PHB 0x%x\n", - tbl->it_busno); + pr_emerg("DMA error on CalIOC2 PHB 0x%x\n", tbl->it_busno); - printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", - csr, plssr, csmr, mck); + pr_emerg("0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", + csr, plssr, csmr, mck); /* dump rest of error regs */ - printk(KERN_EMERG "Calgary: "); + pr_emerg(""); for (i = 0; i < ARRAY_SIZE(errregs); i++) { /* err regs are at 0x810 - 0x870 */ erroff = (0x810 + (i * 0x10)); target = calgary_reg(bbar, phboff | erroff); errregs[i] = be32_to_cpu(readl(target)); - printk("0x%08x@0x%lx ", errregs[i], erroff); + pr_cont("0x%08x@0x%lx ", errregs[i], erroff); } - printk("\n"); + pr_cont("\n"); /* root complex status */ target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 735279e54e59..ef6a8456f719 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -145,16 +147,14 @@ void show_regs_common(void) /* Board Name is optional */ board = dmi_get_system_info(DMI_BOARD_NAME); - printk(KERN_CONT "\n"); - printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s", - current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - printk(KERN_CONT " %s %s", vendor, product); - if (board) - printk(KERN_CONT "/%s", board); - printk(KERN_CONT "\n"); + printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s %s%s%s\n", + current->pid, current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version, + vendor, product, + board ? "/" : "", + board ? board : ""); } void flush_thread(void) @@ -645,7 +645,7 @@ static void amd_e400_idle(void) amd_e400_c1e_detected = true; if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) mark_tsc_unstable("TSC halt in AMD C1E"); - printk(KERN_INFO "System has AMD C1E enabled\n"); + pr_info("System has AMD C1E enabled\n"); } } @@ -659,8 +659,7 @@ static void amd_e400_idle(void) */ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &cpu); - printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", - cpu); + pr_info("Switch to broadcast mode on CPU%d\n", cpu); } clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); @@ -681,8 +680,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP if (pm_idle == poll_idle && smp_num_siblings > 1) { - printk_once(KERN_WARNING "WARNING: polling idle and HT enabled," - " performance may degrade.\n"); + pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n"); } #endif if (pm_idle) @@ -692,11 +690,11 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) /* * One CPU supports mwait => All CPUs supports mwait */ - printk(KERN_INFO "using mwait in idle threads.\n"); + pr_info("using mwait in idle threads\n"); pm_idle = mwait_idle; } else if (cpu_has_amd_erratum(amd_erratum_400)) { /* E400: APIC timer interrupt does not wake up CPU from C1e */ - printk(KERN_INFO "using AMD E400 aware idle routine\n"); + pr_info("using AMD E400 aware idle routine\n"); pm_idle = amd_e400_idle; } else pm_idle = default_idle; @@ -715,7 +713,7 @@ static int __init idle_setup(char *str) return -EINVAL; if (!strcmp(str, "poll")) { - printk("using polling idle threads.\n"); + pr_info("using polling idle threads\n"); pm_idle = poll_idle; boot_option_idle_override = IDLE_POLL; } else if (!strcmp(str, "mwait")) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 61cdf7fdf099..85151f3e36e2 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -117,10 +117,10 @@ void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { if (dead_task->mm->context.size) { - printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", - dead_task->comm, - dead_task->mm->context.ldt, - dead_task->mm->context.size); + pr_warn("WARNING: dead process %8s still has LDT? <%p/%d>\n", + dead_task->comm, + dead_task->mm->context.ldt, + dead_task->mm->context.size); BUG(); } } diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 79c45af81604..ab3f06260712 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -152,7 +154,8 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) { if (reboot_type != BOOT_BIOS) { reboot_type = BOOT_BIOS; - printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident); + pr_info("%s series board detected. Selecting %s-method for reboots.\n", + "BIOS", d->ident); } return 0; } @@ -207,8 +210,8 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) { if (reboot_type != BOOT_CF9) { reboot_type = BOOT_CF9; - printk(KERN_INFO "%s series board detected. " - "Selecting PCI-method for reboots.\n", d->ident); + pr_info("%s series board detected. Selecting %s-method for reboots.\n", + "PCI", d->ident); } return 0; } @@ -217,7 +220,8 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) { if (reboot_type != BOOT_KBD) { reboot_type = BOOT_KBD; - printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident); + pr_info("%s series board detected. Selecting %s-method for reboot.\n", + "KBD", d->ident); } return 0; } @@ -668,7 +672,7 @@ static void __machine_emergency_restart(int emergency) static void native_machine_restart(char *__unused) { - printk("machine restart\n"); + pr_notice("machine restart\n"); if (!reboot_force) machine_shutdown(); diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 21af737053aa..b280908a376e 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -6,6 +6,9 @@ * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2002 x86-64 support by Andi Kleen */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -814,7 +817,7 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) me->comm, me->pid, where, frame, regs->ip, regs->sp, regs->orig_ax); print_vma_addr(" in ", regs->ip); - printk(KERN_CONT "\n"); + pr_cont("\n"); } force_sig(SIGSEGV, me); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index fd019d78b1f4..456d64806c8f 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1,4 +1,4 @@ -/* + /* * x86 SMP booting functions * * (c) 1995 Alan Cox, Building #3 @@ -39,6 +39,8 @@ * Glauber Costa : i386 and x86_64 integration */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -184,7 +186,7 @@ static void __cpuinit smp_callin(void) * boards) */ - pr_debug("CALLIN, before setup_local_APIC().\n"); + pr_debug("CALLIN, before setup_local_APIC()\n"); if (apic->smp_callin_clear_local_apic) apic->smp_callin_clear_local_apic(); setup_local_APIC(); @@ -420,17 +422,16 @@ static void impress_friends(void) /* * Allow the user to impress friends. */ - pr_debug("Before bogomips.\n"); + pr_debug("Before bogomips\n"); for_each_possible_cpu(cpu) if (cpumask_test_cpu(cpu, cpu_callout_mask)) bogosum += cpu_data(cpu).loops_per_jiffy; - printk(KERN_INFO - "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", + pr_info("Total of %d processors activated (%lu.%02lu BogoMIPS)\n", num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); - pr_debug("Before bogocount - setting activated=1.\n"); + pr_debug("Before bogocount - setting activated=1\n"); } void __inquire_remote_apic(int apicid) @@ -440,18 +441,17 @@ void __inquire_remote_apic(int apicid) int timeout; u32 status; - printk(KERN_INFO "Inquiring remote APIC 0x%x...\n", apicid); + pr_info("Inquiring remote APIC 0x%x...\n", apicid); for (i = 0; i < ARRAY_SIZE(regs); i++) { - printk(KERN_INFO "... APIC 0x%x %s: ", apicid, names[i]); + pr_info("... APIC 0x%x %s: ", apicid, names[i]); /* * Wait for idle. */ status = safe_apic_wait_icr_idle(); if (status) - printk(KERN_CONT - "a previous APIC delivery may have failed\n"); + pr_cont("a previous APIC delivery may have failed\n"); apic_icr_write(APIC_DM_REMRD | regs[i], apicid); @@ -464,10 +464,10 @@ void __inquire_remote_apic(int apicid) switch (status) { case APIC_ICR_RR_VALID: status = apic_read(APIC_RRR); - printk(KERN_CONT "%08x\n", status); + pr_cont("%08x\n", status); break; default: - printk(KERN_CONT "failed\n"); + pr_cont("failed\n"); } } } @@ -501,12 +501,12 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) apic_write(APIC_ESR, 0); accept_status = (apic_read(APIC_ESR) & 0xEF); } - pr_debug("NMI sent.\n"); + pr_debug("NMI sent\n"); if (send_status) - printk(KERN_ERR "APIC never delivered???\n"); + pr_err("APIC never delivered???\n"); if (accept_status) - printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); + pr_err("APIC delivery error (%lx)\n", accept_status); return (send_status | accept_status); } @@ -528,7 +528,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) apic_read(APIC_ESR); } - pr_debug("Asserting INIT.\n"); + pr_debug("Asserting INIT\n"); /* * Turn INIT on target chip @@ -544,7 +544,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) mdelay(10); - pr_debug("Deasserting INIT.\n"); + pr_debug("Deasserting INIT\n"); /* Target chip */ /* Send IPI */ @@ -577,14 +577,14 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) /* * Run STARTUP IPI loop. */ - pr_debug("#startup loops: %d.\n", num_starts); + pr_debug("#startup loops: %d\n", num_starts); for (j = 1; j <= num_starts; j++) { - pr_debug("Sending STARTUP #%d.\n", j); + pr_debug("Sending STARTUP #%d\n", j); if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ apic_write(APIC_ESR, 0); apic_read(APIC_ESR); - pr_debug("After apic_write.\n"); + pr_debug("After apic_write\n"); /* * STARTUP IPI @@ -601,7 +601,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) */ udelay(300); - pr_debug("Startup point 1.\n"); + pr_debug("Startup point 1\n"); pr_debug("Waiting for send to finish...\n"); send_status = safe_apic_wait_icr_idle(); @@ -616,12 +616,12 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) if (send_status || accept_status) break; } - pr_debug("After Startup.\n"); + pr_debug("After Startup\n"); if (send_status) - printk(KERN_ERR "APIC never delivered???\n"); + pr_err("APIC never delivered???\n"); if (accept_status) - printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); + pr_err("APIC delivery error (%lx)\n", accept_status); return (send_status | accept_status); } @@ -635,11 +635,11 @@ static void __cpuinit announce_cpu(int cpu, int apicid) if (system_state == SYSTEM_BOOTING) { if (node != current_node) { if (current_node > (-1)) - pr_cont(" Ok.\n"); + pr_cont(" OK\n"); current_node = node; pr_info("Booting Node %3d, Processors ", node); } - pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " Ok.\n" : ""); + pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " OK\n" : ""); return; } else pr_info("Booting Node %d Processor %d APIC 0x%x\n", @@ -719,9 +719,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) /* * allow APs to start initializing. */ - pr_debug("Before Callout %d.\n", cpu); + pr_debug("Before Callout %d\n", cpu); cpumask_set_cpu(cpu, cpu_callout_mask); - pr_debug("After Callout %d.\n", cpu); + pr_debug("After Callout %d\n", cpu); /* * Wait 5s total for a response @@ -749,7 +749,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) pr_err("CPU%d: Stuck ??\n", cpu); else /* trampoline code not run */ - pr_err("CPU%d: Not responding.\n", cpu); + pr_err("CPU%d: Not responding\n", cpu); if (apic->inquire_remote_apic) apic->inquire_remote_apic(apicid); } @@ -794,7 +794,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid || !physid_isset(apicid, phys_cpu_present_map) || !apic->apic_id_valid(apicid)) { - printk(KERN_ERR "%s: bad cpu %d\n", __func__, cpu); + pr_err("%s: bad cpu %d\n", __func__, cpu); return -EINVAL; } @@ -875,9 +875,8 @@ static int __init smp_sanity_check(unsigned max_cpus) unsigned int cpu; unsigned nr; - printk(KERN_WARNING - "More than 8 CPUs detected - skipping them.\n" - "Use CONFIG_X86_BIGSMP.\n"); + pr_warn("More than 8 CPUs detected - skipping them\n" + "Use CONFIG_X86_BIGSMP\n"); nr = 0; for_each_present_cpu(cpu) { @@ -898,8 +897,7 @@ static int __init smp_sanity_check(unsigned max_cpus) #endif if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { - printk(KERN_WARNING - "weird, boot CPU (#%d) not listed by the BIOS.\n", + pr_warn("weird, boot CPU (#%d) not listed by the BIOS\n", hard_smp_processor_id()); physid_set(hard_smp_processor_id(), phys_cpu_present_map); @@ -911,11 +909,10 @@ static int __init smp_sanity_check(unsigned max_cpus) */ if (!smp_found_config && !acpi_lapic) { preempt_enable(); - printk(KERN_NOTICE "SMP motherboard not detected.\n"); + pr_notice("SMP motherboard not detected\n"); disable_smp(); if (APIC_init_uniprocessor()) - printk(KERN_NOTICE "Local APIC not detected." - " Using dummy APIC emulation.\n"); + pr_notice("Local APIC not detected. Using dummy APIC emulation.\n"); return -1; } @@ -924,9 +921,8 @@ static int __init smp_sanity_check(unsigned max_cpus) * CPU too, but we do it for the sake of robustness anyway. */ if (!apic->check_phys_apicid_present(boot_cpu_physical_apicid)) { - printk(KERN_NOTICE - "weird, boot CPU (#%d) not listed by the BIOS.\n", - boot_cpu_physical_apicid); + pr_notice("weird, boot CPU (#%d) not listed by the BIOS\n", + boot_cpu_physical_apicid); physid_set(hard_smp_processor_id(), phys_cpu_present_map); } preempt_enable(); @@ -939,8 +935,7 @@ static int __init smp_sanity_check(unsigned max_cpus) if (!disable_apic) { pr_err("BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); - pr_err("... forcing use of dummy APIC emulation." - "(tell your hw vendor)\n"); + pr_err("... forcing use of dummy APIC emulation (tell your hw vendor)\n"); } smpboot_clear_io_apic(); disable_ioapic_support(); @@ -953,7 +948,7 @@ static int __init smp_sanity_check(unsigned max_cpus) * If SMP should be disabled, then really disable it! */ if (!max_cpus) { - printk(KERN_INFO "SMP mode deactivated.\n"); + pr_info("SMP mode deactivated\n"); smpboot_clear_io_apic(); connect_bsp_APIC(); @@ -1005,7 +1000,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) if (smp_sanity_check(max_cpus) < 0) { - printk(KERN_INFO "SMP disabled\n"); + pr_info("SMP disabled\n"); disable_smp(); goto out; } @@ -1043,7 +1038,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) * Set up local APIC timer on boot CPU. */ - printk(KERN_INFO "CPU%d: ", 0); + pr_info("CPU%d: ", 0); print_cpu_info(&cpu_data(0)); x86_init.timers.setup_percpu_clockev(); @@ -1093,7 +1088,7 @@ void __init native_smp_prepare_boot_cpu(void) void __init native_smp_cpus_done(unsigned int max_cpus) { - pr_debug("Boot done.\n"); + pr_debug("Boot done\n"); nmi_selftest(); impress_friends(); @@ -1154,8 +1149,7 @@ __init void prefill_possible_map(void) /* nr_cpu_ids could be reduced via nr_cpus= */ if (possible > nr_cpu_ids) { - printk(KERN_WARNING - "%d Processors exceeds NR_CPUS limit of %d\n", + pr_warn("%d Processors exceeds NR_CPUS limit of %d\n", possible, nr_cpu_ids); possible = nr_cpu_ids; } @@ -1164,13 +1158,12 @@ __init void prefill_possible_map(void) if (!setup_max_cpus) #endif if (possible > i) { - printk(KERN_WARNING - "%d Processors exceeds max_cpus limit of %u\n", + pr_warn("%d Processors exceeds max_cpus limit of %u\n", possible, setup_max_cpus); possible = i; } - printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", + pr_info("Allowing %d CPUs, %d hotplug CPUs\n", possible, max_t(int, possible - num_processors, 0)); for (i = 0; i < possible; i++) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 05b31d92f69c..b481341c9369 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -9,6 +9,9 @@ /* * Handle hardware traps and faults. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -143,12 +146,11 @@ trap_signal: #ifdef CONFIG_X86_64 if (show_unhandled_signals && unhandled_signal(tsk, signr) && printk_ratelimit()) { - printk(KERN_INFO - "%s[%d] trap %s ip:%lx sp:%lx error:%lx", - tsk->comm, tsk->pid, str, - regs->ip, regs->sp, error_code); + pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", + tsk->comm, tsk->pid, str, + regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); - printk("\n"); + pr_cont("\n"); } #endif @@ -269,12 +271,11 @@ do_general_protection(struct pt_regs *regs, long error_code) if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && printk_ratelimit()) { - printk(KERN_INFO - "%s[%d] general protection ip:%lx sp:%lx error:%lx", + pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); - printk("\n"); + pr_cont("\n"); } force_sig(SIGSEGV, tsk); @@ -570,7 +571,7 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) conditional_sti(regs); #if 0 /* No need to warn about this any longer. */ - printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); + pr_info("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); #endif } diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index fc0a147e3727..cfa5d4f7ca56 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -84,8 +86,7 @@ EXPORT_SYMBOL_GPL(check_tsc_unstable); #ifdef CONFIG_X86_TSC int __init notsc_setup(char *str) { - printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " - "cannot disable TSC completely.\n"); + pr_warn("Kernel compiled with CONFIG_X86_TSC, cannot disable TSC completely\n"); tsc_disabled = 1; return 1; } @@ -373,7 +374,7 @@ static unsigned long quick_pit_calibrate(void) goto success; } } - printk("Fast TSC calibration failed\n"); + pr_err("Fast TSC calibration failed\n"); return 0; success: @@ -392,7 +393,7 @@ success: */ delta *= PIT_TICK_RATE; do_div(delta, i*256*1000); - printk("Fast TSC calibration using PIT\n"); + pr_info("Fast TSC calibration using PIT\n"); return delta; } @@ -487,9 +488,8 @@ unsigned long native_calibrate_tsc(void) * use the reference value, as it is more precise. */ if (delta >= 90 && delta <= 110) { - printk(KERN_INFO - "TSC: PIT calibration matches %s. %d loops\n", - hpet ? "HPET" : "PMTIMER", i + 1); + pr_info("PIT calibration matches %s. %d loops\n", + hpet ? "HPET" : "PMTIMER", i + 1); return tsc_ref_min; } @@ -511,38 +511,36 @@ unsigned long native_calibrate_tsc(void) */ if (tsc_pit_min == ULONG_MAX) { /* PIT gave no useful value */ - printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n"); + pr_warn("Unable to calibrate against PIT\n"); /* We don't have an alternative source, disable TSC */ if (!hpet && !ref1 && !ref2) { - printk("TSC: No reference (HPET/PMTIMER) available\n"); + pr_notice("No reference (HPET/PMTIMER) available\n"); return 0; } /* The alternative source failed as well, disable TSC */ if (tsc_ref_min == ULONG_MAX) { - printk(KERN_WARNING "TSC: HPET/PMTIMER calibration " - "failed.\n"); + pr_warn("HPET/PMTIMER calibration failed\n"); return 0; } /* Use the alternative source */ - printk(KERN_INFO "TSC: using %s reference calibration\n", - hpet ? "HPET" : "PMTIMER"); + pr_info("using %s reference calibration\n", + hpet ? "HPET" : "PMTIMER"); return tsc_ref_min; } /* We don't have an alternative source, use the PIT calibration value */ if (!hpet && !ref1 && !ref2) { - printk(KERN_INFO "TSC: Using PIT calibration value\n"); + pr_info("Using PIT calibration value\n"); return tsc_pit_min; } /* The alternative source failed, use the PIT calibration value */ if (tsc_ref_min == ULONG_MAX) { - printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. " - "Using PIT calibration\n"); + pr_warn("HPET/PMTIMER calibration failed. Using PIT calibration.\n"); return tsc_pit_min; } @@ -551,9 +549,9 @@ unsigned long native_calibrate_tsc(void) * the PIT value as we know that there are PMTIMERs around * running at double speed. At least we let the user know: */ - printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n", - hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); - printk(KERN_INFO "TSC: Using PIT calibration value\n"); + pr_warn("PIT calibration deviates from %s: %lu %lu\n", + hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); + pr_info("Using PIT calibration value\n"); return tsc_pit_min; } @@ -785,7 +783,7 @@ void mark_tsc_unstable(char *reason) tsc_unstable = 1; sched_clock_stable = 0; disable_sched_clock_irqtime(); - printk(KERN_INFO "Marking TSC unstable due to %s\n", reason); + pr_info("Marking TSC unstable due to %s\n", reason); /* Change only the rating, when not registered */ if (clocksource_tsc.mult) clocksource_mark_unstable(&clocksource_tsc); @@ -912,9 +910,9 @@ static void tsc_refine_calibration_work(struct work_struct *work) goto out; tsc_khz = freq; - printk(KERN_INFO "Refined TSC clocksource calibration: " - "%lu.%03lu MHz.\n", (unsigned long)tsc_khz / 1000, - (unsigned long)tsc_khz % 1000); + pr_info("Refined TSC clocksource calibration: %lu.%03lu MHz\n", + (unsigned long)tsc_khz / 1000, + (unsigned long)tsc_khz % 1000); out: clocksource_register_khz(&clocksource_tsc, tsc_khz); @@ -970,9 +968,9 @@ void __init tsc_init(void) return; } - printk("Detected %lu.%03lu MHz processor.\n", - (unsigned long)cpu_khz / 1000, - (unsigned long)cpu_khz % 1000); + pr_info("Detected %lu.%03lu MHz processor\n", + (unsigned long)cpu_khz / 1000, + (unsigned long)cpu_khz % 1000); /* * Secondary CPUs do not run through tsc_init(), so set up diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 255f58ae71e8..54abcc0baf23 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -28,6 +28,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -137,14 +139,14 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) local_irq_enable(); if (!current->thread.vm86_info) { - printk("no vm86_info: BAD\n"); + pr_alert("no vm86_info: BAD\n"); do_exit(SIGSEGV); } set_flags(regs->pt.flags, VEFLAGS, X86_EFLAGS_VIF | current->thread.v86mask); tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs, regs); tmp += put_user(current->thread.screen_bitmap, ¤t->thread.vm86_info->screen_bitmap); if (tmp) { - printk("vm86: could not access userspace vm86_info\n"); + pr_alert("could not access userspace vm86_info\n"); do_exit(SIGSEGV); } diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 7515cf0e1805..acdc125ad44e 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -18,6 +18,8 @@ * use the vDSO. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -111,18 +113,13 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, const char *message) { - static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); - struct task_struct *tsk; - - if (!show_unhandled_signals || !__ratelimit(&rs)) + if (!show_unhandled_signals) return; - tsk = current; - - printk("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", - level, tsk->comm, task_pid_nr(tsk), - message, regs->ip, regs->cs, - regs->sp, regs->ax, regs->si, regs->di); + pr_notice_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", + level, current->comm, task_pid_nr(current), + message, regs->ip, regs->cs, + regs->sp, regs->ax, regs->si, regs->di); } static int addr_to_vsyscall_nr(unsigned long addr) diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index bd18149b2b0f..3d3e20709119 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -3,6 +3,9 @@ * * Author: Suresh Siddha */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -162,7 +165,7 @@ int save_i387_xstate(void __user *buf) BUG_ON(sig_xstate_size < xstate_size); if ((unsigned long)buf % 64) - printk("save_i387_xstate: bad fpstate %p\n", buf); + pr_err("%s: bad fpstate %p\n", __func__, buf); if (!used_math()) return 0; @@ -422,7 +425,7 @@ static void __init xstate_enable_boot_cpu(void) pcntxt_mask = eax + ((u64)edx << 32); if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) { - printk(KERN_ERR "FP/SSE not shown under xsave features 0x%llx\n", + pr_err("FP/SSE not shown under xsave features 0x%llx\n", pcntxt_mask); BUG(); } @@ -445,9 +448,8 @@ static void __init xstate_enable_boot_cpu(void) setup_xstate_init(); - printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%llx, " - "cntxt size 0x%x\n", - pcntxt_mask, xstate_size); + pr_info("enabled xstate_bv 0x%llx, cntxt size 0x%x\n", + pcntxt_mask, xstate_size); } /* -- GitLab From 332afa656e76458ee9cf0f0d123016a0658539e4 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Mon, 21 May 2012 16:58:01 -0700 Subject: [PATCH 0680/6849] x86/irq: Update irq_cfg domain unless the new affinity is a subset of the current domain Until now, irq_cfg domain is mostly static. Either all CPU's (used by flat mode) or one CPU (first CPU in the irq afffinity mask) to which irq is being migrated (this is used by the rest of apic modes). Upcoming x2apic cluster mode optimization patch allows the irq to be sent to any CPU in the x2apic cluster (if supported by the HW). So irq_cfg domain changes on the fly (depending on which CPU in the x2apic cluster is online). Instead of checking for any intersection between the new irq affinity mask and the current irq_cfg domain, check if the new irq affinity mask is a subset of the current irq_cfg domain. Otherwise proceed with updating the irq_cfg domain aswell as assigning vector's on all the CPUs specified in the new mask. This also cleans up a workaround in updating irq_cfg domain for legacy irq's that are handled by the IO-APIC. Signed-off-by: Suresh Siddha Cc: yinghai@kernel.org Cc: gorcunov@openvz.org Cc: agordeev@redhat.com Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1337644682-19854-1-git-send-email-suresh.b.siddha@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/io_apic.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ac96561d1a99..910a3118438b 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1126,8 +1126,7 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) old_vector = cfg->vector; if (old_vector) { cpumask_and(tmp_mask, mask, cpu_online_mask); - cpumask_and(tmp_mask, cfg->domain, tmp_mask); - if (!cpumask_empty(tmp_mask)) { + if (cpumask_subset(tmp_mask, cfg->domain)) { free_cpumask_var(tmp_mask); return 0; } @@ -1141,6 +1140,11 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) apic->vector_allocation_domain(cpu, tmp_mask); + if (cpumask_subset(tmp_mask, cfg->domain)) { + free_cpumask_var(tmp_mask); + return 0; + } + vector = current_vector; offset = current_offset; next: @@ -1346,13 +1350,6 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, if (!IO_APIC_IRQ(irq)) return; - /* - * For legacy irqs, cfg->domain starts with cpu 0 for legacy - * controllers like 8259. Now that IO-APIC can handle this irq, update - * the cfg->domain. - */ - if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain)) - apic->vector_allocation_domain(0, cfg->domain); if (assign_irq_vector(irq, cfg, apic->target_cpus())) return; -- GitLab From 0b8255e660a0c229ebfe8f9fde12a8d4d34c50e0 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Mon, 21 May 2012 16:58:02 -0700 Subject: [PATCH 0681/6849] x86/x2apic/cluster: Use all the members of one cluster specified in the smp_affinity mask for the interrupt destination If the HW implements round-robin interrupt delivery, this enables multiple cpu's (which are part of the user specified interrupt smp_affinity mask and belong to the same x2apic cluster) to service the interrupt. Also if the platform supports Power Aware Interrupt Routing, then this enables the interrupt to be routed to an idle cpu or a busy cpu depending on the perf/power bias tunable. We are now grouping all the cpu's in a cluster to one vector domain. So that will limit the total number of interrupt sources handled by Linux. Previously we support "cpu-count * available-vectors-per-cpu" interrupt sources but this will now reduce to "cpu-count/16 * available-vectors-per-cpu". Signed-off-by: Suresh Siddha Cc: yinghai@kernel.org Cc: gorcunov@openvz.org Cc: agordeev@redhat.com Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1337644682-19854-2-git-send-email-suresh.b.siddha@intel.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/x2apic.h | 9 ----- arch/x86/kernel/apic/x2apic_cluster.c | 56 +++++++++++++++++++-------- arch/x86/kernel/apic/x2apic_phys.c | 9 +++++ 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/arch/x86/include/asm/x2apic.h b/arch/x86/include/asm/x2apic.h index 92e54abf89e0..7a5a832a99b6 100644 --- a/arch/x86/include/asm/x2apic.h +++ b/arch/x86/include/asm/x2apic.h @@ -28,15 +28,6 @@ static int x2apic_apic_id_registered(void) return 1; } -/* - * For now each logical cpu is in its own vector allocation domain. - */ -static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) { diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index ff35cff0e1a7..90d999c7f2ea 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -98,34 +98,47 @@ static void x2apic_send_IPI_all(int vector) static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) { - /* - * We're using fixed IRQ delivery, can only return one logical APIC ID. - * May as well be the first. - */ int cpu = cpumask_first(cpumask); + u32 dest = 0; + int i; - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_logical_apicid, cpu); - else + if (cpu > nr_cpu_ids) return BAD_APICID; + + for_each_cpu_and(i, cpumask, per_cpu(cpus_in_cluster, cpu)) + dest |= per_cpu(x86_cpu_to_logical_apicid, i); + + return dest; } static unsigned int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask) { - int cpu; + u32 dest = 0; + u16 cluster; + int i; - /* - * We're using fixed IRQ delivery, can only return one logical APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; + for_each_cpu_and(i, cpumask, andmask) { + if (!cpumask_test_cpu(i, cpu_online_mask)) + continue; + dest = per_cpu(x86_cpu_to_logical_apicid, i); + cluster = x2apic_cluster(i); + break; } - return per_cpu(x86_cpu_to_logical_apicid, cpu); + if (!dest) + return BAD_APICID; + + for_each_cpu_and(i, cpumask, andmask) { + if (!cpumask_test_cpu(i, cpu_online_mask)) + continue; + if (cluster != x2apic_cluster(i)) + continue; + dest |= per_cpu(x86_cpu_to_logical_apicid, i); + } + + return dest; } static void init_x2apic_ldr(void) @@ -208,6 +221,15 @@ static int x2apic_cluster_probe(void) return 0; } +/* + * Each x2apic cluster is an allocation domain. + */ +static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_copy(retmask, per_cpu(cpus_in_cluster, cpu)); +} + static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", @@ -225,7 +247,7 @@ static struct apic apic_x2apic_cluster = { .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = x2apic_vector_allocation_domain, + .vector_allocation_domain = cluster_vector_allocation_domain, .init_apic_ldr = init_x2apic_ldr, .ioapic_phys_id_map = NULL, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index c17e982db275..93b25706f177 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -120,6 +120,15 @@ static int x2apic_phys_probe(void) return apic == &apic_x2apic_phys; } +/* + * Each logical cpu is in its own vector allocation domain. + */ +static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + static struct apic apic_x2apic_phys = { .name = "physical x2apic", -- GitLab From 6dbc10c61d5841f64945fd94977fa8fa1c0192da Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Feb 2012 11:58:14 +0200 Subject: [PATCH 0682/6849] usb: dwc3: gadget: drop useless code We never set CMDIOC bit for Start Transfer command, so that code will never be used. Tested-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 854f3a3c8832..056ace8ab97d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1765,9 +1765,6 @@ static void dwc3_ep_cmd_compl(struct dwc3_ep *dep, case DWC3_DEPCMD_ENDTRANSFER: dwc3_process_ep_cmd_complete(dep, event); break; - case DWC3_DEPCMD_STARTTRANSFER: - dep->res_trans_idx = param & 0x7f; - break; default: printk(KERN_ERR "%s() unknown /unexpected type: %d\n", __func__, cmd_type); -- GitLab From 49d0c7a0a425a89190b7c3b1445faba9eb227bec Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 5 Jun 2012 13:23:15 +0200 Subject: [PATCH 0683/6849] x86/apic: Trivial whitespace fixes Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120605112310.GA11443@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/apic_flat_64.c | 2 +- arch/x86/kernel/apic/io_apic.c | 4 ++-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 0e881c46e8c8..de279b32ceb1 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -92,7 +92,7 @@ static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector) } static void - flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) +flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { unsigned long mask = cpumask_bits(cpumask)[0]; int cpu = smp_processor_id(); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 910a3118438b..74c569791e75 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1363,7 +1363,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, cfg->vector, irq, attr->trigger, attr->polarity, dest); if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) { - pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", + pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); __clear_irq_vector(irq, cfg); @@ -1466,7 +1466,7 @@ void setup_IO_APIC_irq_extra(u32 gsi) * Set up the timer pin, possibly with the 8259A-master behind. */ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, - unsigned int pin, int vector) + unsigned int pin, int vector) { struct IO_APIC_route_entry entry; diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 90d999c7f2ea..2919e45d30c3 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -81,7 +81,7 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) } static void - x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) +x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) { __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); } -- GitLab From bf721d3a3bc7a731add45c8078b142b494ab413e Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 5 Jun 2012 13:23:29 +0200 Subject: [PATCH 0684/6849] x86/apic: Factor out default target_cpus() operation Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120605112324.GA11449@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 5 +++++ arch/x86/include/asm/x2apic.h | 9 --------- arch/x86/kernel/apic/apic_flat_64.c | 14 ++------------ arch/x86/kernel/apic/apic_numachip.c | 7 +------ arch/x86/kernel/apic/bigsmp_32.c | 11 +---------- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 +------ 8 files changed, 12 insertions(+), 45 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index eaff4790ed96..fc38195d6405 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -537,6 +537,11 @@ static inline const struct cpumask *default_target_cpus(void) #endif } +static inline const struct cpumask *online_target_cpus(void) +{ + return cpu_online_mask; +} + DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); diff --git a/arch/x86/include/asm/x2apic.h b/arch/x86/include/asm/x2apic.h index 7a5a832a99b6..f90f0a587c66 100644 --- a/arch/x86/include/asm/x2apic.h +++ b/arch/x86/include/asm/x2apic.h @@ -9,15 +9,6 @@ #include #include -/* - * Need to use more than cpu 0, because we need more vectors - * when MSI-X are used. - */ -static const struct cpumask *x2apic_target_cpus(void) -{ - return cpu_online_mask; -} - static int x2apic_apic_id_valid(int apicid) { return 1; diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index de279b32ceb1..61ac1afeff07 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -36,11 +36,6 @@ static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 1; } -static const struct cpumask *flat_target_cpus(void) -{ - return cpu_online_mask; -} - static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask) { /* Careful. Some cpus do not strictly honor the set of cpus @@ -186,7 +181,7 @@ static struct apic apic_flat = { .irq_delivery_mode = dest_LowestPrio, .irq_dest_mode = 1, /* logical */ - .target_cpus = flat_target_cpus, + .target_cpus = online_target_cpus, .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, .check_apicid_used = NULL, @@ -262,11 +257,6 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } -static const struct cpumask *physflat_target_cpus(void) -{ - return cpu_online_mask; -} - static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask) { cpumask_clear(retmask); @@ -345,7 +335,7 @@ static struct apic apic_physflat = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = physflat_target_cpus, + .target_cpus = online_target_cpus, .disable_esr = 0, .dest_logical = 0, .check_apicid_used = NULL, diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 6ec6d5d297c3..3255a60fcc95 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -72,11 +72,6 @@ static int numachip_phys_pkg_id(int initial_apic_id, int index_msb) return initial_apic_id >> index_msb; } -static const struct cpumask *numachip_target_cpus(void) -{ - return cpu_online_mask; -} - static void numachip_vector_allocation_domain(int cpu, struct cpumask *retmask) { cpumask_clear(retmask); @@ -253,7 +248,7 @@ static struct apic apic_numachip __refconst = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = numachip_target_cpus, + .target_cpus = online_target_cpus, .disable_esr = 0, .dest_logical = 0, .check_apicid_used = NULL, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 31fbdbfbf960..c288e81e00ff 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -26,15 +26,6 @@ static int bigsmp_apic_id_registered(void) return 1; } -static const struct cpumask *bigsmp_target_cpus(void) -{ -#ifdef CONFIG_SMP - return cpu_online_mask; -#else - return cpumask_of(0); -#endif -} - static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid) { return 0; @@ -205,7 +196,7 @@ static struct apic apic_bigsmp = { /* phys delivery to target CPU: */ .irq_dest_mode = 0, - .target_cpus = bigsmp_target_cpus, + .target_cpus = default_target_cpus, .disable_esr = 1, .dest_logical = 0, .check_apicid_used = bigsmp_check_apicid_used, diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 2919e45d30c3..612622c47dfb 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -241,7 +241,7 @@ static struct apic apic_x2apic_cluster = { .irq_delivery_mode = dest_LowestPrio, .irq_dest_mode = 1, /* logical */ - .target_cpus = x2apic_target_cpus, + .target_cpus = online_target_cpus, .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, .check_apicid_used = NULL, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 93b25706f177..b1a8b39e3c3f 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -140,7 +140,7 @@ static struct apic apic_x2apic_phys = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = x2apic_target_cpus, + .target_cpus = online_target_cpus, .disable_esr = 0, .dest_logical = 0, .check_apicid_used = NULL, diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index c6d03f7a4401..16efb92bfea5 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -185,11 +185,6 @@ EXPORT_SYMBOL_GPL(uv_possible_blades); unsigned long sn_rtc_cycles_per_second; EXPORT_SYMBOL(sn_rtc_cycles_per_second); -static const struct cpumask *uv_target_cpus(void) -{ - return cpu_online_mask; -} - static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) { cpumask_clear(retmask); @@ -362,7 +357,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .irq_delivery_mode = dest_Fixed, .irq_dest_mode = 0, /* physical */ - .target_cpus = uv_target_cpus, + .target_cpus = online_target_cpus, .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, .check_apicid_used = NULL, -- GitLab From 6398268d2bc454735f11e08705e858f9fdf5c750 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 5 Jun 2012 13:23:44 +0200 Subject: [PATCH 0685/6849] x86/apic: Factor out default cpu_mask_to_apicid() operations Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120605112340.GA11454@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 13 ++++++--- arch/x86/kernel/apic/apic.c | 28 +++++++++++++++++++ arch/x86/kernel/apic/apic_flat_64.c | 40 +++------------------------- arch/x86/kernel/apic/apic_noop.c | 4 +-- arch/x86/kernel/apic/apic_numachip.c | 36 ++----------------------- arch/x86/kernel/apic/bigsmp_32.c | 30 ++------------------- arch/x86/kernel/apic/probe_32.c | 4 +-- arch/x86/kernel/apic/x2apic_phys.c | 36 ++----------------------- 8 files changed, 52 insertions(+), 139 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index fc38195d6405..bef571769e68 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -592,14 +592,14 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) #endif static inline unsigned int -default_cpu_mask_to_apicid(const struct cpumask *cpumask) +flat_cpu_mask_to_apicid(const struct cpumask *cpumask) { return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; } static inline unsigned int -default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) +flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) { unsigned long mask1 = cpumask_bits(cpumask)[0]; unsigned long mask2 = cpumask_bits(andmask)[0]; @@ -608,6 +608,13 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, return (unsigned int)(mask1 & mask2 & mask3); } +extern unsigned int +default_cpu_mask_to_apicid(const struct cpumask *cpumask); + +extern unsigned int +default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask); + static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) { return physid_isset(apicid, *map); diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 39a222e094af..96a2608252f1 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2123,6 +2123,34 @@ void default_init_apic_ldr(void) apic_write(APIC_LDR, val); } +unsigned int default_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + cpu = cpumask_first(cpumask); + if (likely((unsigned)cpu < nr_cpu_ids)) + return per_cpu(x86_cpu_to_apicid, cpu); + + return BAD_APICID; +} + +unsigned int +default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + return per_cpu(x86_cpu_to_apicid, cpu); +} + /* * Power management */ diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 61ac1afeff07..55b97ce4fa19 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -205,8 +205,8 @@ static struct apic apic_flat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = flat_send_IPI_mask, .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, @@ -284,38 +284,6 @@ static void physflat_send_IPI_all(int vector) physflat_send_IPI_mask(cpu_online_mask, vector); } -static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - cpu = cpumask_first(cpumask); - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - else - return BAD_APICID; -} - -static unsigned int -physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - return per_cpu(x86_cpu_to_apicid, cpu); -} - static int physflat_probe(void) { if (apic == &apic_physflat || num_possible_cpus() > 8) @@ -360,8 +328,8 @@ static struct apic apic_physflat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = physflat_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = physflat_send_IPI_mask, .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself, diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index a6e4c6e06c08..7c3dd4fe0686 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -159,8 +159,8 @@ struct apic apic_noop = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = noop_send_IPI_mask, .send_IPI_mask_allbutself = noop_send_IPI_mask_allbutself, diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 3255a60fcc95..dba4bf2ed566 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -152,38 +152,6 @@ static void numachip_send_IPI_self(int vector) __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); } -static unsigned int numachip_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - cpu = cpumask_first(cpumask); - if (likely((unsigned)cpu < nr_cpu_ids)) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; -} - -static unsigned int -numachip_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - return per_cpu(x86_cpu_to_apicid, cpu); -} - static int __init numachip_probe(void) { return apic == &apic_numachip; @@ -272,8 +240,8 @@ static struct apic apic_numachip __refconst = { .set_apic_id = set_apic_id, .apic_id_mask = 0xffU << 24, - .cpu_mask_to_apicid = numachip_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = numachip_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = numachip_send_IPI_mask, .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index c288e81e00ff..907aa3d112a6 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -96,32 +96,6 @@ static int bigsmp_check_phys_apicid_present(int phys_apicid) return 1; } -/* As we are using single CPU as destination, pick only one CPU here */ -static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - int cpu = cpumask_first(cpumask); - - if (cpu < nr_cpu_ids) - return cpu_physical_id(cpu); - return BAD_APICID; -} - -static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - return cpu_physical_id(cpu); - } - return BAD_APICID; -} - static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) { return cpuid_apic >> index_msb; @@ -220,8 +194,8 @@ static struct apic apic_bigsmp = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, - .cpu_mask_to_apicid = bigsmp_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = bigsmp_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = bigsmp_send_IPI_mask, .send_IPI_mask_allbutself = NULL, diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 1b291da09e60..71b6ac48ab26 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -123,8 +123,8 @@ static struct apic apic_default = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = default_send_IPI_mask_logical, .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index b1a8b39e3c3f..f730269edef2 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -76,38 +76,6 @@ static void x2apic_send_IPI_all(int vector) __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); } -static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - int cpu = cpumask_first(cpumask); - - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - else - return BAD_APICID; -} - -static unsigned int -x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - - return per_cpu(x86_cpu_to_apicid, cpu); -} - static void init_x2apic_ldr(void) { } @@ -164,8 +132,8 @@ static struct apic apic_x2apic_phys = { .set_apic_id = x2apic_set_apic_id, .apic_id_mask = 0xFFFFFFFFu, - .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = x2apic_send_IPI_mask, .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, -- GitLab From ea53b8828c50b7a5138a8931c41b2671682c86b5 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Feb 2012 12:10:04 +0200 Subject: [PATCH 0686/6849] usb: dwc3: gadget: don't wait for ep cmd IRQ That IRQ is causing way too much trouble. We have a different handling which was agreed with IP provider and has been tested with FPGA and OMAP5. Tested-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 66 ++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 056ace8ab97d..0f19978d4840 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -555,9 +555,34 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) { struct dwc3_request *req; - if (!list_empty(&dep->req_queued)) + if (!list_empty(&dep->req_queued)) { dwc3_stop_active_transfer(dwc, dep->number); + /* + * NOTICE: We are violating what the Databook says about the + * EndTransfer command. Ideally we would _always_ wait for the + * EndTransfer Command Completion IRQ, but that's causing too + * much trouble synchronizing between us and gadget driver. + * + * We have discussed this with the IP Provider and it was + * suggested to giveback all requests here, but give HW some + * extra time to synchronize with the interconnect. We're using + * an arbitraty 100us delay for that. + * + * Note also that a similar handling was tested by Synopsys + * (thanks a lot Paul) and nothing bad has come out of it. + * In short, what we're doing is: + * + * - Issue EndTransfer WITH CMDIOC bit set + * - Wait 100us + * - giveback all requests to gadget driver + */ + udelay(100); + + req = next_request(&dep->req_queued); + dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + } + while (!list_empty(&dep->request_list)) { req = next_request(&dep->request_list); @@ -1735,43 +1760,6 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, } } -static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep, - const struct dwc3_event_depevt *event) -{ - struct dwc3 *dwc = dep->dwc; - struct dwc3_event_depevt mod_ev = *event; - - /* - * We were asked to remove one request. It is possible that this - * request and a few others were started together and have the same - * transfer index. Since we stopped the complete endpoint we don't - * know how many requests were already completed (and not yet) - * reported and how could be done (later). We purge them all until - * the end of the list. - */ - mod_ev.status = DEPEVT_STATUS_LST; - dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN); - dep->flags &= ~DWC3_EP_BUSY; - /* pending requests are ignored and are queued on XferNotReady */ -} - -static void dwc3_ep_cmd_compl(struct dwc3_ep *dep, - const struct dwc3_event_depevt *event) -{ - u32 param = event->parameters; - u32 cmd_type = (param >> 8) & ((1 << 5) - 1); - - switch (cmd_type) { - case DWC3_DEPCMD_ENDTRANSFER: - dwc3_process_ep_cmd_complete(dep, event); - break; - default: - printk(KERN_ERR "%s() unknown /unexpected type: %d\n", - __func__, cmd_type); - break; - }; -} - static void dwc3_endpoint_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { @@ -1853,7 +1841,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); break; case DWC3_DEPEVT_EPCMDCMPLT: - dwc3_ep_cmd_compl(dep, event); + dev_vdbg(dwc->dev, "Endpoint Command Complete\n"); break; } } -- GitLab From 1e2360eadaa33c09bb72afb14f74b6c6ab2aca66 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Jun 2012 09:18:12 +0300 Subject: [PATCH 0687/6849] usb: dwc3: gadget: don't call stop_active_transfers() on disconnect In case we get disconnected, we will call gadget driver's disconnect method, which should make sure to disable all endpoints. At that point we will call stop_active_transfers() to make sure we didn't leave any pending request on the controller. Tested-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0f19978d4840..52d0f67e33d5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1927,7 +1927,6 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) reg &= ~DWC3_DCTL_INITU2ENA; dwc3_writel(dwc->regs, DWC3_DCTL, reg); - dwc3_stop_active_transfers(dwc); dwc3_disconnect_gadget(dwc); dwc->start_config_issued = false; -- GitLab From 3336abb5b608300550136ddab7a7101b30d45fa7 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Jun 2012 09:19:35 +0300 Subject: [PATCH 0688/6849] usb: dwc3: gadget: ignore endpoint IRQs when endpoint is disabled By the time we're disabling the endpoint, HW could already have posted more events to our event buffer. In that case, we will receive endpoint events for a disabled endpoint. In order to protect ourselves from that situation, we simply ignore endpoint interrupts whenever the endpoint is disabled. Tested-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 52d0f67e33d5..8e00756ee522 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1768,6 +1768,9 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dep = dwc->eps[epnum]; + if (!(dep->flags & DWC3_EP_ENABLED)) + return; + dev_vdbg(dwc->dev, "%s: %s\n", dep->name, dwc3_ep_event_string(event->endpoint_event)); -- GitLab From f968cabcb1cd0c253fa25850970e5376f9eef065 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 01:42:20 -0700 Subject: [PATCH 0689/6849] ARM: OMAP: Fix MMC_OMAP build when only MMC_OMAP_HS is selected If CONFIG_MMC_OMAP is not set and CONFIG_MMC_OMAP_HS is set, we can get error: redefinition of `omap242x_init_mmc' error. Fix it by removing MMC_OMAP_HS from MMC_OMAP ifdefs as they do not depend on each other. While at it, also prettify the formatting a bit. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/mmc.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index a7754a886d42..5493bd95da5e 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -172,8 +172,7 @@ struct omap_mmc_platform_data { extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ - defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); @@ -185,7 +184,6 @@ static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) { } - #endif extern int omap_msdi_reset(struct omap_hwmod *oh); -- GitLab From 00d6bfaf20e723e3f4c9aa6bc0fb6636785a0701 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 01:42:20 -0700 Subject: [PATCH 0690/6849] ARM: OMAP3: Fix omap3_l3_block_irq warning when CONFIG_BUG is not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we will get: arch/arm/mach-omap2/omap_l3_smx.c: In function ‘omap3_l3_block_irq’: arch/arm/mach-omap2/omap_l3_smx.c:156: warning: unused variable ‘address’ arch/arm/mach-omap2/omap_l3_smx.c:155: warning: unused variable ‘multi’ arch/arm/mach-omap2/omap_l3_smx.c:154: warning: unused variable ‘initid’ arch/arm/mach-omap2/omap_l3_smx.c:153: warning: unused variable ‘code’ arch/arm/mach-omap2/omap_l3_smx.c: At top level: arch/arm/mach-omap2/omap_l3_smx.c:68: warning: ‘omap3_l3_code_string’ defined but not used arch/arm/mach-omap2/omap_l3_smx.c:90: warning: ‘omap3_l3_initiator_string’ defined but not used Fix it by always showing the L3 error. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_l3_smx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c index a05a62f9ee5b..acc216491b8a 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.c +++ b/arch/arm/mach-omap2/omap_l3_smx.c @@ -155,10 +155,11 @@ static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3, u8 multi = error & L3_ERROR_LOG_MULTI; u32 address = omap3_l3_decode_addr(error_addr); - WARN(true, "%s seen by %s %s at address %x\n", + pr_err("%s seen by %s %s at address %x\n", omap3_l3_code_string(code), omap3_l3_initiator_string(initid), multi ? "Multiple Errors" : "", address); + WARN_ON(1); return IRQ_HANDLED; } -- GitLab From febe9e02d63ed8a42e7e9c75ea16117821f90f07 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 01:42:20 -0700 Subject: [PATCH 0691/6849] ARM: OMAP2+: Fix compile for CONFIG_TIDSPBRIDGE platform init code Commit 7f28427b (ARM: OMAP2+: Move omap_dsp_reserve_sdram_memblock() to mach-omap2) moved DSP platform init code, but failed to include memblock.h causing: arch/arm/mach-omap2/dsp.c: In function 'omap_dsp_reserve_sdram_memblock': arch/arm/mach-omap2/dsp.c:58: error: implicit declaration of function 'arm_memblock_steal' Reported-by: Russell King Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/dsp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c index 845309f146fe..88ffa1e645cd 100644 --- a/arch/arm/mach-omap2/dsp.c +++ b/arch/arm/mach-omap2/dsp.c @@ -20,6 +20,9 @@ #include #include + +#include + #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #ifdef CONFIG_BRIDGE_DVFS -- GitLab From fbd24153c48b8425b09c161a020483cd77da870e Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 30 May 2012 18:40:03 -0600 Subject: [PATCH 0692/6849] x86/early_printk: Replace obsolete simple_strtoul() usage with kstrtoint() Change early_serial_init() to call kstrtoul() instead of calling obsoleted simple_strtoul(). Signed-off-by: Shuah Khan Cc: Joe Perches Link: http://lkml.kernel.org/r/1338424803.3569.5.camel@lorien2 Signed-off-by: Ingo Molnar --- arch/x86/kernel/early_printk.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 9b9f18b49918..5e4771266f1a 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -119,7 +119,7 @@ static __init void early_serial_init(char *s) unsigned char c; unsigned divisor; unsigned baud = DEFAULT_BAUD; - char *e; + ssize_t ret; if (*s == ',') ++s; @@ -127,14 +127,14 @@ static __init void early_serial_init(char *s) if (*s) { unsigned port; if (!strncmp(s, "0x", 2)) { - early_serial_base = simple_strtoul(s, &e, 16); + ret = kstrtoint(s, 16, &early_serial_base); } else { static const int __initconst bases[] = { 0x3f8, 0x2f8 }; if (!strncmp(s, "ttyS", 4)) s += 4; - port = simple_strtoul(s, &e, 10); - if (port > 1 || s == e) + ret = kstrtouint(s, 10, &port); + if (ret || port > 1) port = 0; early_serial_base = bases[port]; } @@ -149,8 +149,8 @@ static __init void early_serial_init(char *s) outb(0x3, early_serial_base + MCR); /* DTR + RTS */ if (*s) { - baud = simple_strtoul(s, &e, 0); - if (baud == 0 || s == e) + ret = kstrtouint(s, 0, &baud); + if (ret || baud == 0) baud = DEFAULT_BAUD; } -- GitLab From bacef661acdb634170a8faddbc1cf28e8f8b9eee Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 25 May 2012 16:20:31 +0100 Subject: [PATCH 0693/6849] x86-64/efi: Use EFI to deal with platform wall clock Other than ix86, x86-64 on EFI so far didn't set the {g,s}et_wallclock accessors to the EFI routines, thus incorrectly using raw RTC accesses instead. Simply removing the #ifdef around the respective code isn't enough, however: While so far early get-time calls were done in physical mode, this doesn't work properly for x86-64, as virtual addresses would still need to be set up for all runtime regions (which wasn't the case on the system I have access to), so instead the patch moves the call to efi_enter_virtual_mode() ahead (which in turn allows to drop all code related to calling efi-get-time in physical mode). Additionally the earlier calling of efi_set_executable() requires the CPA code to cope, i.e. during early boot it must be avoided to call cpa_flush_array(), as the first thing this function does is a BUG_ON(irqs_disabled()). Also make the two EFI functions in question here static - they're not being referenced elsewhere. Signed-off-by: Jan Beulich Tested-by: Matt Fleming Acked-by: Matthew Garrett Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/4FBFBF5F020000780008637F@nat28.tlf.novell.com Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 10 ++++++---- arch/x86/platform/efi/efi.c | 30 ++++-------------------------- include/linux/efi.h | 2 -- init/main.c | 8 ++++---- 4 files changed, 14 insertions(+), 36 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index e1ebde315210..ee09aca63998 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -919,11 +919,13 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, /* * On success we use clflush, when the CPU supports it to - * avoid the wbindv. If the CPU does not support it and in the - * error case we fall back to cpa_flush_all (which uses - * wbindv): + * avoid the wbindv. If the CPU does not support it, in the + * error case, and during early boot (for EFI) we fall back + * to cpa_flush_all (which uses wbinvd): */ - if (!ret && cpu_has_clflush) { + if (early_boot_irqs_disabled) + __cpa_flush_all((void *)(long)cache); + else if (!ret && cpu_has_clflush) { if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { cpa_flush_array(addr, numpages, cache, cpa.flags, pages); diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 92660edaa1e7..2dc29f51e75a 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -234,22 +234,7 @@ static efi_status_t __init phys_efi_set_virtual_address_map( return status; } -static efi_status_t __init phys_efi_get_time(efi_time_t *tm, - efi_time_cap_t *tc) -{ - unsigned long flags; - efi_status_t status; - - spin_lock_irqsave(&rtc_lock, flags); - efi_call_phys_prelog(); - status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm), - virt_to_phys(tc)); - efi_call_phys_epilog(); - spin_unlock_irqrestore(&rtc_lock, flags); - return status; -} - -int efi_set_rtc_mmss(unsigned long nowtime) +static int efi_set_rtc_mmss(unsigned long nowtime) { int real_seconds, real_minutes; efi_status_t status; @@ -278,7 +263,7 @@ int efi_set_rtc_mmss(unsigned long nowtime) return 0; } -unsigned long efi_get_time(void) +static unsigned long efi_get_time(void) { efi_status_t status; efi_time_t eft; @@ -621,18 +606,13 @@ static int __init efi_runtime_init(void) } /* * We will only need *early* access to the following - * two EFI runtime services before set_virtual_address_map + * EFI runtime service before set_virtual_address_map * is invoked. */ - efi_phys.get_time = (efi_get_time_t *)runtime->get_time; efi_phys.set_virtual_address_map = (efi_set_virtual_address_map_t *) runtime->set_virtual_address_map; - /* - * Make efi_get_time can be called before entering - * virtual mode. - */ - efi.get_time = phys_efi_get_time; + early_iounmap(runtime, sizeof(efi_runtime_services_t)); return 0; @@ -720,12 +700,10 @@ void __init efi_init(void) efi_enabled = 0; return; } -#ifdef CONFIG_X86_32 if (efi_native) { x86_platform.get_wallclock = efi_get_time; x86_platform.set_wallclock = efi_set_rtc_mmss; } -#endif #if EFI_DEBUG print_efi_memmap(); diff --git a/include/linux/efi.h b/include/linux/efi.h index ec45ccd8708a..103adc6d7e3a 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -503,8 +503,6 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); extern int __init efi_uart_console_only (void); extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource, struct resource *bss_resource); -extern unsigned long efi_get_time(void); -extern int efi_set_rtc_mmss(unsigned long nowtime); extern void efi_reserve_boot_services(void); extern struct efi_memory_map memmap; diff --git a/init/main.c b/init/main.c index 1ca6b32c4828..eef30128321a 100644 --- a/init/main.c +++ b/init/main.c @@ -460,6 +460,10 @@ static void __init mm_init(void) percpu_init_late(); pgtable_cache_init(); vmalloc_init(); +#ifdef CONFIG_X86 + if (efi_enabled) + efi_enter_virtual_mode(); +#endif } asmlinkage void __init start_kernel(void) @@ -601,10 +605,6 @@ asmlinkage void __init start_kernel(void) calibrate_delay(); pidmap_init(); anon_vma_init(); -#ifdef CONFIG_X86 - if (efi_enabled) - efi_enter_virtual_mode(); -#endif thread_info_cache_init(); cred_init(); fork_init(totalram_pages); -- GitLab From 09eeff52bf20d485bcafc441f01c142c59c3da16 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 1 Jun 2012 10:39:45 -0400 Subject: [PATCH 0694/6849] mmc: sdhci: Use DBG() instead of pr_warning() on large timeout 3bdc9ba892d6 ("mmc: use really long write timeout to deal with crappy cards") in 3.4 increased the write timeout that the core sends to host drivers to 3 seconds. This makes sdhci's "requested timeout too large" warning trigger on every write; so, change this pr_warning() to a DBG(). Reported-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e626732aff77..f4b8b4db3a9a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -680,8 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) } if (count >= 0xF) { - pr_warning("%s: Too large timeout 0x%x requested for CMD%d!\n", - mmc_hostname(host->mmc), count, cmd->opcode); + DBG("%s: Too large timeout 0x%x requested for CMD%d!\n", + mmc_hostname(host->mmc), count, cmd->opcode); count = 0xE; } -- GitLab From b87cc1b5d3a96ef9f1b3a4f8ce7aaff18e96c994 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Wed, 23 May 2012 15:52:15 +0200 Subject: [PATCH 0695/6849] mmc: atmel-mci: fix data timeout issue The data timeout timer was configured after mmc_add_host call. So, with bad timings, it was possible to have a mmc request causing mod_timer call on a non setup timer. Signed-off-by: Ludovic Desroches Signed-off-by: Chris Ball --- drivers/mmc/host/atmel-mci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 420aca642b14..456c077455cb 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -2314,6 +2314,8 @@ static int __init atmci_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); + setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); + /* We need at least one slot to succeed */ nr_slots = 0; ret = -ENODEV; @@ -2352,8 +2354,6 @@ static int __init atmci_probe(struct platform_device *pdev) } } - setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); - dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", host->mapbase, irq, nr_slots); -- GitLab From ce63f3ba256a48023b425a4a6792f8da03d00948 Mon Sep 17 00:00:00 2001 From: Wang Xingchao Date: Wed, 6 Jun 2012 13:49:44 +0800 Subject: [PATCH 0696/6849] ALSA: hda - add power states information in proc add more power states information: - reset status - clock stop ok - power states error Output like: Power: setting=D0, actual=D0, Error, Clock-stop-OK, Setting-reset Signed-off-by: Wang Xingchao Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.h | 3 +++ sound/pci/hda/hda_proc.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 4fc3960c8591..71864cddcb9d 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -323,6 +323,9 @@ enum { #define AC_PWRST_D1 0x01 #define AC_PWRST_D2 0x02 #define AC_PWRST_D3 0x03 +#define AC_PWRST_ERROR (1<<8) +#define AC_PWRST_CLK_STOP_OK (1<<9) +#define AC_PWRST_SETTING_RESET (1<<10) /* Processing capabilies */ #define AC_PCAP_BENIGN (1<<0) diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index e59e2f059b6e..fb9ef132f13b 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -455,10 +455,17 @@ static void print_power_state(struct snd_info_buffer *buffer, snd_iprintf(buffer, " Power states: %s\n", bits_names(sup, names, ARRAY_SIZE(names))); - snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", + snd_iprintf(buffer, " Power: setting=%s, actual=%s", get_pwr_state(pwr & AC_PWRST_SETTING), get_pwr_state((pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT)); + if (pwr & AC_PWRST_ERROR) + snd_iprintf(buffer, ", Error"); + if (pwr & AC_PWRST_CLK_STOP_OK) + snd_iprintf(buffer, ", Clock-stop-OK"); + if (pwr & AC_PWRST_SETTING_RESET) + snd_iprintf(buffer, ", Setting-reset"); + snd_iprintf(buffer, "\n"); } static void print_unsol_cap(struct snd_info_buffer *buffer, -- GitLab From 167d2d55bfb4628169a57e3adbb1e5b097dca0f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 6 Jun 2012 12:17:20 +0200 Subject: [PATCH 0697/6849] ALSA: hda - Show D3cold state in proc files Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index fb9ef132f13b..1dd9dbeeef6e 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -426,10 +426,10 @@ static void print_digital_conv(struct snd_info_buffer *buffer, static const char *get_pwr_state(u32 state) { - static const char * const buf[4] = { - "D0", "D1", "D2", "D3" + static const char * const buf[] = { + "D0", "D1", "D2", "D3", "D3cold" }; - if (state < 4) + if (state < ARRAY_SIZE(buf)) return buf[state]; return "UNKNOWN"; } -- GitLab From 0a305e496059a113f93bdd3ad27a5aaa917fe34d Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 6 Jun 2012 11:17:59 +0100 Subject: [PATCH 0698/6849] GFS2: Extend the life of the reservations This patch lengthens the lifespan of the reservations structure for inodes. Before, they were allocated and deallocated for every write operation. With this patch, they are allocated when the first write occurs, and deallocated when the last process closes the file. It's more efficient to do it this way because it saves GFS2 a lot of unnecessary allocates and frees. It also gives us more flexibility for the future: (1) we can now fold the qadata structure back into the structure and save those alloc/frees, (2) we can use this for multi-block reservations. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/aops.c | 2 +- fs/gfs2/file.c | 23 ++++++++++++++--- fs/gfs2/inode.c | 23 ++++++++++++++++- fs/gfs2/quota.c | 13 ++++++++-- fs/gfs2/rgrp.c | 68 +++++++++++++++++++++++++++---------------------- fs/gfs2/rgrp.h | 10 ++++++++ fs/gfs2/super.c | 2 ++ fs/gfs2/trans.h | 2 +- 8 files changed, 104 insertions(+), 39 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index e80a464850c8..aba77b5720bc 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -878,7 +878,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, brelse(dibh); failed: gfs2_trans_end(sdp); - if (ip->i_res) + if (gfs2_mb_reserved(ip)) gfs2_inplace_release(ip); if (qa) { gfs2_quota_unlock(ip); diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 31b199f6efc1..37906174d417 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -376,6 +376,10 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) */ vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); + ret = gfs2_rs_alloc(ip); + if (ret) + return ret; + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); ret = gfs2_glock_nq(&gh); if (ret) @@ -569,10 +573,15 @@ static int gfs2_release(struct inode *inode, struct file *file) { struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; struct gfs2_file *fp; + struct gfs2_inode *ip = GFS2_I(inode); fp = file->private_data; file->private_data = NULL; + if ((file->f_mode & FMODE_WRITE) && ip->i_res && + (atomic_read(&inode->i_writecount) == 1)) + gfs2_rs_delete(ip); + if (gfs2_assert_warn(sdp, fp)) return -EIO; @@ -653,12 +662,16 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; + struct dentry *dentry = file->f_dentry; + struct gfs2_inode *ip = GFS2_I(dentry->d_inode); + int ret; + + ret = gfs2_rs_alloc(ip); + if (ret) + return ret; if (file->f_flags & O_APPEND) { - struct dentry *dentry = file->f_dentry; - struct gfs2_inode *ip = GFS2_I(dentry->d_inode); struct gfs2_holder gh; - int ret; ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); if (ret) @@ -774,6 +787,10 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, if (bytes == 0) bytes = sdp->sd_sb.sb_bsize; + error = gfs2_rs_alloc(ip); + if (error) + return error; + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); error = gfs2_glock_nq(&ip->i_gh); if (unlikely(error)) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index a9ba2444e077..2a1b4b5a648c 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -667,6 +667,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, if (!name->len || name->len > GFS2_FNAMESIZE) return -ENAMETOOLONG; + error = gfs2_rs_alloc(dip); + if (error) + return error; + error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); if (error) goto fail; @@ -704,6 +708,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, if (error) goto fail_gunlock2; + /* the new inode needs a reservation so it can allocate xattrs. */ + error = gfs2_rs_alloc(GFS2_I(inode)); + if (error) + goto fail_gunlock2; + error = gfs2_acl_create(dip, inode); if (error) goto fail_gunlock2; @@ -722,7 +731,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, gfs2_trans_end(sdp); /* Check if we reserved space in the rgrp. Function link_dinode may not, depending on whether alloc is required. */ - if (dip->i_res) + if (gfs2_mb_reserved(dip)) gfs2_inplace_release(dip); gfs2_quota_unlock(dip); gfs2_qadata_put(dip); @@ -819,6 +828,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, if (S_ISDIR(inode->i_mode)) return -EPERM; + error = gfs2_rs_alloc(dip); + if (error) + return error; + gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); @@ -1234,6 +1247,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, if (error) return error; + error = gfs2_rs_alloc(ndip); + if (error) + return error; + if (odip != ndip) { error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0, &r_gh); @@ -1644,6 +1661,10 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) struct gfs2_holder i_gh; int error; + error = gfs2_rs_alloc(ip); + if (error) + return error; + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); if (error) return error; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index b97178e7d397..197cc2dade7f 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -764,6 +764,10 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) unsigned int nalloc = 0, blocks; int error; + error = gfs2_rs_alloc(ip); + if (error) + return error; + gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), &data_blocks, &ind_blocks); @@ -1549,10 +1553,14 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, if (error) return error; + error = gfs2_rs_alloc(ip); + if (error) + goto out_put; + mutex_lock(&ip->i_inode.i_mutex); error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh); if (error) - goto out_put; + goto out_unlockput; error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); if (error) goto out_q; @@ -1609,8 +1617,9 @@ out_i: gfs2_glock_dq_uninit(&i_gh); out_q: gfs2_glock_dq_uninit(&q_gh); -out_put: +out_unlockput: mutex_unlock(&ip->i_inode.i_mutex); +out_put: qd_put(qd); return error; } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index f74fb9bd1973..e944fefbc9a8 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -417,6 +417,39 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) } } +/** + * gfs2_rs_alloc - make sure we have a reservation assigned to the inode + * @ip: the inode for this reservation + */ +int gfs2_rs_alloc(struct gfs2_inode *ip) +{ + int error = 0; + + down_write(&ip->i_rw_mutex); + if (!ip->i_res) { + ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); + if (!ip->i_res) + error = -ENOMEM; + } + up_write(&ip->i_rw_mutex); + return error; +} + +/** + * gfs2_rs_delete - delete a reservation + * @ip: The inode for this reservation + * + */ +void gfs2_rs_delete(struct gfs2_inode *ip) +{ + down_write(&ip->i_rw_mutex); + if (ip->i_res) { + kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); + ip->i_res = NULL; + } + up_write(&ip->i_rw_mutex); +} + void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) { struct rb_node *n; @@ -992,22 +1025,6 @@ struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip) return ip->i_qadata; } -/** - * gfs2_blkrsv_get - get the struct gfs2_blkreserv structure for an inode - * @ip: the incore GFS2 inode structure - * - * Returns: the struct gfs2_qadata - */ - -static int gfs2_blkrsv_get(struct gfs2_inode *ip) -{ - BUG_ON(ip->i_res != NULL); - ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); - if (!ip->i_res) - return -ENOMEM; - return 0; -} - /** * try_rgrp_fit - See if a given reservation will fit in a given RG * @rgd: the RG data @@ -1162,13 +1179,6 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) return -ENOSPC; } -static void gfs2_blkrsv_put(struct gfs2_inode *ip) -{ - BUG_ON(ip->i_res == NULL); - kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); - ip->i_res = NULL; -} - /** * gfs2_inplace_reserve - Reserve space in the filesystem * @ip: the inode to reserve space for @@ -1181,14 +1191,10 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_blkreserv *rs; - int error; + int error = 0; u64 last_unlinked = NO_BLOCK; int tries = 0; - error = gfs2_blkrsv_get(ip); - if (error) - return error; - rs = ip->i_res; rs->rs_requested = requested; if (gfs2_assert_warn(sdp, requested)) { @@ -1213,7 +1219,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) out: if (error) - gfs2_blkrsv_put(ip); + rs->rs_requested = 0; return error; } @@ -1230,7 +1236,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip) if (rs->rs_rgd_gh.gh_gl) gfs2_glock_dq_uninit(&rs->rs_rgd_gh); - gfs2_blkrsv_put(ip); + rs->rs_requested = 0; } /** @@ -1496,7 +1502,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, /* Only happens if there is a bug in gfs2, return something distinctive * to ensure that it is noticed. */ - if (ip->i_res == NULL) + if (ip->i_res->rs_requested == 0) return -ECANCELED; rgd = ip->i_rgd; diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index b4b10f4de25f..d9eda5f9ef2a 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h @@ -43,6 +43,8 @@ extern void gfs2_inplace_release(struct gfs2_inode *ip); extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, bool dinode, u64 *generation); +extern int gfs2_rs_alloc(struct gfs2_inode *ip); +extern void gfs2_rs_delete(struct gfs2_inode *ip); extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); @@ -68,4 +70,12 @@ extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed); extern int gfs2_fitrim(struct file *filp, void __user *argp); +/* This is how to tell if a reservation is "inplace" reserved: */ +static inline int gfs2_mb_reserved(struct gfs2_inode *ip) +{ + if (ip->i_res && ip->i_res->rs_requested) + return 1; + return 0; +} + #endif /* __RGRP_DOT_H__ */ diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 713e621c240b..65578df29446 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1554,6 +1554,7 @@ out_unlock: out: /* Case 3 starts here */ truncate_inode_pages(&inode->i_data, 0); + gfs2_rs_delete(ip); clear_inode(inode); gfs2_dir_hash_inval(ip); ip->i_gl->gl_object = NULL; @@ -1576,6 +1577,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb) ip->i_flags = 0; ip->i_gl = NULL; ip->i_rgd = NULL; + ip->i_res = NULL; } return &ip->i_inode; } diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h index 125d4572e1c0..41f42cdccbb8 100644 --- a/fs/gfs2/trans.h +++ b/fs/gfs2/trans.h @@ -31,7 +31,7 @@ struct gfs2_glock; static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip) { const struct gfs2_blkreserv *rs = ip->i_res; - if (rs->rs_requested < ip->i_rgd->rd_length) + if (rs && rs->rs_requested < ip->i_rgd->rd_length) return rs->rs_requested + 1; return ip->i_rgd->rd_length; } -- GitLab From 5407e24229408d7586ee451a384fc13e4a2332be Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Fri, 18 May 2012 09:28:23 -0400 Subject: [PATCH 0699/6849] GFS2: Fold quota data into the reservations struct This patch moves the ancillary quota data structures into the block reservations structure. This saves GFS2 some time and effort in allocating and deallocating the qadata structure. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/aops.c | 16 ++----------- fs/gfs2/bmap.c | 18 ++++----------- fs/gfs2/dir.c | 9 +------- fs/gfs2/file.c | 22 +++++------------- fs/gfs2/incore.h | 13 ++++------- fs/gfs2/inode.c | 44 ++++-------------------------------- fs/gfs2/main.c | 1 - fs/gfs2/quota.c | 59 ++++++++++++++++++++++++------------------------ fs/gfs2/rgrp.c | 19 ---------------- fs/gfs2/rgrp.h | 8 ------- fs/gfs2/super.c | 9 +------- fs/gfs2/xattr.c | 24 ++------------------ 12 files changed, 56 insertions(+), 186 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index aba77b5720bc..d6526347d386 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -614,7 +614,6 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, unsigned int data_blocks = 0, ind_blocks = 0, rblocks; int alloc_required; int error = 0; - struct gfs2_qadata *qa = NULL; pgoff_t index = pos >> PAGE_CACHE_SHIFT; unsigned from = pos & (PAGE_CACHE_SIZE - 1); struct page *page; @@ -638,15 +637,9 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); if (alloc_required) { - qa = gfs2_qadata_get(ip); - if (!qa) { - error = -ENOMEM; - goto out_unlock; - } - error = gfs2_quota_lock_check(ip); if (error) - goto out_alloc_put; + goto out_unlock; error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); if (error) @@ -708,8 +701,6 @@ out_trans_fail: gfs2_inplace_release(ip); out_qunlock: gfs2_quota_unlock(ip); -out_alloc_put: - gfs2_qadata_put(ip); } out_unlock: if (&ip->i_inode == sdp->sd_rindex) { @@ -846,7 +837,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); struct buffer_head *dibh; - struct gfs2_qadata *qa = ip->i_qadata; unsigned int from = pos & (PAGE_CACHE_SIZE - 1); unsigned int to = from + len; int ret; @@ -880,10 +870,8 @@ failed: gfs2_trans_end(sdp); if (gfs2_mb_reserved(ip)) gfs2_inplace_release(ip); - if (qa) { + if (ip->i_res->rs_qa_qd_num) gfs2_quota_unlock(ip); - gfs2_qadata_put(ip); - } if (inode == sdp->sd_rindex) { gfs2_glock_dq(&m_ip->i_gh); gfs2_holder_uninit(&m_ip->i_gh); diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index dab54099dd98..6d957a86482b 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1045,12 +1045,13 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size) lblock = (size - 1) >> sdp->sd_sb.sb_bsize_shift; find_metapath(sdp, lblock, &mp, ip->i_height); - if (!gfs2_qadata_get(ip)) - return -ENOMEM; + error = gfs2_rindex_update(sdp); + if (error) + return error; error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) - goto out; + return error; while (height--) { struct strip_mine sm; @@ -1064,8 +1065,6 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size) gfs2_quota_unhold(ip); -out: - gfs2_qadata_put(ip); return error; } @@ -1167,19 +1166,14 @@ static int do_grow(struct inode *inode, u64 size) struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct buffer_head *dibh; - struct gfs2_qadata *qa = NULL; int error; int unstuff = 0; if (gfs2_is_stuffed(ip) && (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) { - qa = gfs2_qadata_get(ip); - if (qa == NULL) - return -ENOMEM; - error = gfs2_quota_lock_check(ip); if (error) - goto do_grow_alloc_put; + return error; error = gfs2_inplace_reserve(ip, 1); if (error) @@ -1214,8 +1208,6 @@ do_grow_release: gfs2_inplace_release(ip); do_grow_qunlock: gfs2_quota_unlock(ip); -do_grow_alloc_put: - gfs2_qadata_put(ip); } return error; } diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 8aaeb07a07b5..259b088cfc4c 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1854,14 +1854,9 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, if (!ht) return -ENOMEM; - if (!gfs2_qadata_get(dip)) { - error = -ENOMEM; - goto out; - } - error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) - goto out_put; + goto out; /* Count the number of leaves */ bh = leaf_bh; @@ -1942,8 +1937,6 @@ out_rg_gunlock: out_rlist: gfs2_rlist_free(&rlist); gfs2_quota_unhold(dip); -out_put: - gfs2_qadata_put(dip); out: kfree(ht); return error; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 37906174d417..26e2905070ed 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -366,7 +366,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) u64 pos = page->index << PAGE_CACHE_SHIFT; unsigned int data_blocks, ind_blocks, rblocks; struct gfs2_holder gh; - struct gfs2_qadata *qa; loff_t size; int ret; @@ -397,14 +396,13 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) goto out_unlock; } - ret = -ENOMEM; - qa = gfs2_qadata_get(ip); - if (qa == NULL) + ret = gfs2_rindex_update(sdp); + if (ret) goto out_unlock; ret = gfs2_quota_lock_check(ip); if (ret) - goto out_alloc_put; + goto out_unlock; gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); if (ret) @@ -451,8 +449,6 @@ out_trans_fail: gfs2_inplace_release(ip); out_quota_unlock: gfs2_quota_unlock(ip); -out_alloc_put: - gfs2_qadata_put(ip); out_unlock: gfs2_glock_dq(&gh); out: @@ -764,7 +760,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, struct gfs2_inode *ip = GFS2_I(inode); unsigned int data_blocks = 0, ind_blocks = 0, rblocks; loff_t bytes, max_bytes; - struct gfs2_qadata *qa; int error; const loff_t pos = offset; const loff_t count = len; @@ -804,15 +799,13 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, offset += bytes; continue; } - qa = gfs2_qadata_get(ip); - if (!qa) { - error = -ENOMEM; + error = gfs2_rindex_update(sdp); + if (error) goto out_unlock; - } error = gfs2_quota_lock_check(ip); if (error) - goto out_alloc_put; + goto out_unlock; retry: gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); @@ -852,7 +845,6 @@ retry: offset += max_bytes; gfs2_inplace_release(ip); gfs2_quota_unlock(ip); - gfs2_qadata_put(ip); } if (error == 0) @@ -863,8 +855,6 @@ out_trans_fail: gfs2_inplace_release(ip); out_qunlock: gfs2_quota_unlock(ip); -out_alloc_put: - gfs2_qadata_put(ip); out_unlock: gfs2_glock_dq(&ip->i_gh); out_uninit: diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 67fd6beffece..5cda51a3e3bd 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -289,16 +289,14 @@ struct gfs2_glock { #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */ -struct gfs2_qadata { /* quota allocation data */ - /* Quota stuff */ - struct gfs2_quota_data *qa_qd[2*MAXQUOTAS]; - struct gfs2_holder qa_qd_ghs[2*MAXQUOTAS]; - unsigned int qa_qd_num; -}; - struct gfs2_blkreserv { u32 rs_requested; /* Filled in by caller of gfs2_inplace_reserve() */ struct gfs2_holder rs_rgd_gh; /* Filled in by gfs2_inplace_reserve() */ + + /* ancillary quota stuff */ + struct gfs2_quota_data *rs_qa_qd[2 * MAXQUOTAS]; + struct gfs2_holder rs_qa_qd_ghs[2 * MAXQUOTAS]; + unsigned int rs_qa_qd_num; }; enum { @@ -319,7 +317,6 @@ struct gfs2_inode { struct gfs2_glock *i_gl; /* Move into i_gh? */ struct gfs2_holder i_iopen_gh; struct gfs2_holder i_gh; /* for prepare/commit_write only */ - struct gfs2_qadata *i_qadata; /* quota allocation data */ struct gfs2_blkreserv *i_res; /* resource group block reservation */ struct gfs2_rgrpd *i_rgd; u64 i_goal; /* goal block for allocations */ diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 2a1b4b5a648c..2b035e0959b2 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -521,12 +521,10 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, int error; munge_mode_uid_gid(dip, &mode, &uid, &gid); - if (!gfs2_qadata_get(dip)) - return -ENOMEM; error = gfs2_quota_lock(dip, uid, gid); if (error) - goto out; + return error; error = gfs2_quota_check(dip, uid, gid); if (error) @@ -542,8 +540,6 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, out_quota: gfs2_quota_unlock(dip); -out: - gfs2_qadata_put(dip); return error; } @@ -551,15 +547,10 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); - struct gfs2_qadata *qa; int alloc_required; struct buffer_head *dibh; int error; - qa = gfs2_qadata_get(dip); - if (!qa) - return -ENOMEM; - error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) goto fail; @@ -611,7 +602,6 @@ fail_quota_locks: gfs2_quota_unlock(dip); fail: - gfs2_qadata_put(dip); return error; } @@ -734,7 +724,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, if (gfs2_mb_reserved(dip)) gfs2_inplace_release(dip); gfs2_quota_unlock(dip); - gfs2_qadata_put(dip); mark_inode_dirty(inode); gfs2_glock_dq_uninit_m(2, ghs); d_instantiate(dentry, inode); @@ -883,16 +872,9 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, error = 0; if (alloc_required) { - struct gfs2_qadata *qa = gfs2_qadata_get(dip); - - if (!qa) { - error = -ENOMEM; - goto out_gunlock; - } - error = gfs2_quota_lock_check(dip); if (error) - goto out_alloc; + goto out_gunlock; error = gfs2_inplace_reserve(dip, sdp->sd_max_dirres); if (error) @@ -935,9 +917,6 @@ out_ipres: out_gunlock_q: if (alloc_required) gfs2_quota_unlock(dip); -out_alloc: - if (alloc_required) - gfs2_qadata_put(dip); out_gunlock: gfs2_glock_dq(ghs + 1); out_child: @@ -1374,16 +1353,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, goto out_gunlock; if (alloc_required) { - struct gfs2_qadata *qa = gfs2_qadata_get(ndip); - - if (!qa) { - error = -ENOMEM; - goto out_gunlock; - } - error = gfs2_quota_lock_check(ndip); if (error) - goto out_alloc; + goto out_gunlock; error = gfs2_inplace_reserve(ndip, sdp->sd_max_dirres); if (error) @@ -1444,9 +1416,6 @@ out_ipreserv: out_gunlock_q: if (alloc_required) gfs2_quota_unlock(ndip); -out_alloc: - if (alloc_required) - gfs2_qadata_put(ndip); out_gunlock: while (x--) { gfs2_glock_dq(ghs + x); @@ -1607,12 +1576,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) ogid = ngid = NO_QUOTA_CHANGE; - if (!gfs2_qadata_get(ip)) - return -ENOMEM; - error = gfs2_quota_lock(ip, nuid, ngid); if (error) - goto out_alloc; + return error; if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { error = gfs2_quota_check(ip, nuid, ngid); @@ -1638,8 +1604,6 @@ out_end_trans: gfs2_trans_end(sdp); out_gunlock_q: gfs2_quota_unlock(ip); -out_alloc: - gfs2_qadata_put(ip); return error; } diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 6cdb0f2a1b09..e04d0e09ee7b 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -43,7 +43,6 @@ static void gfs2_init_inode_once(void *foo) inode_init_once(&ip->i_inode); init_rwsem(&ip->i_rw_mutex); INIT_LIST_HEAD(&ip->i_trunc_list); - ip->i_qadata = NULL; ip->i_res = NULL; ip->i_hash_cache = NULL; } diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 197cc2dade7f..7d1ede7b66fc 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -494,11 +494,15 @@ static void qdsb_put(struct gfs2_quota_data *qd) int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_qadata *qa = ip->i_qadata; - struct gfs2_quota_data **qd = qa->qa_qd; + struct gfs2_quota_data **qd; int error; - if (gfs2_assert_warn(sdp, !qa->qa_qd_num) || + if (ip->i_res == NULL) + gfs2_rs_alloc(ip); + + qd = ip->i_res->rs_qa_qd; + + if (gfs2_assert_warn(sdp, !ip->i_res->rs_qa_qd_num) || gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) return -EIO; @@ -508,20 +512,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); if (error) goto out; - qa->qa_qd_num++; + ip->i_res->rs_qa_qd_num++; qd++; error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); if (error) goto out; - qa->qa_qd_num++; + ip->i_res->rs_qa_qd_num++; qd++; if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { error = qdsb_get(sdp, QUOTA_USER, uid, qd); if (error) goto out; - qa->qa_qd_num++; + ip->i_res->rs_qa_qd_num++; qd++; } @@ -529,7 +533,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); if (error) goto out; - qa->qa_qd_num++; + ip->i_res->rs_qa_qd_num++; qd++; } @@ -542,16 +546,17 @@ out: void gfs2_quota_unhold(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_qadata *qa = ip->i_qadata; unsigned int x; + if (ip->i_res == NULL) + return; gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); - for (x = 0; x < qa->qa_qd_num; x++) { - qdsb_put(qa->qa_qd[x]); - qa->qa_qd[x] = NULL; + for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { + qdsb_put(ip->i_res->rs_qa_qd[x]); + ip->i_res->rs_qa_qd[x] = NULL; } - qa->qa_qd_num = 0; + ip->i_res->rs_qa_qd_num = 0; } static int sort_qd(const void *a, const void *b) @@ -919,7 +924,6 @@ fail: int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_qadata *qa = ip->i_qadata; struct gfs2_quota_data *qd; unsigned int x; int error = 0; @@ -932,15 +936,15 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) sdp->sd_args.ar_quota != GFS2_QUOTA_ON) return 0; - sort(qa->qa_qd, qa->qa_qd_num, sizeof(struct gfs2_quota_data *), - sort_qd, NULL); + sort(ip->i_res->rs_qa_qd, ip->i_res->rs_qa_qd_num, + sizeof(struct gfs2_quota_data *), sort_qd, NULL); - for (x = 0; x < qa->qa_qd_num; x++) { + for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { int force = NO_FORCE; - qd = qa->qa_qd[x]; + qd = ip->i_res->rs_qa_qd[x]; if (test_and_clear_bit(QDF_REFRESH, &qd->qd_flags)) force = FORCE; - error = do_glock(qd, force, &qa->qa_qd_ghs[x]); + error = do_glock(qd, force, &ip->i_res->rs_qa_qd_ghs[x]); if (error) break; } @@ -949,7 +953,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) set_bit(GIF_QD_LOCKED, &ip->i_flags); else { while (x--) - gfs2_glock_dq_uninit(&qa->qa_qd_ghs[x]); + gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); gfs2_quota_unhold(ip); } @@ -994,7 +998,6 @@ static int need_sync(struct gfs2_quota_data *qd) void gfs2_quota_unlock(struct gfs2_inode *ip) { - struct gfs2_qadata *qa = ip->i_qadata; struct gfs2_quota_data *qda[4]; unsigned int count = 0; unsigned int x; @@ -1002,14 +1005,14 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) goto out; - for (x = 0; x < qa->qa_qd_num; x++) { + for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { struct gfs2_quota_data *qd; int sync; - qd = qa->qa_qd[x]; + qd = ip->i_res->rs_qa_qd[x]; sync = need_sync(qd); - gfs2_glock_dq_uninit(&qa->qa_qd_ghs[x]); + gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); if (sync && qd_trylock(qd)) qda[count++] = qd; @@ -1042,7 +1045,6 @@ static int print_message(struct gfs2_quota_data *qd, char *type) int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_qadata *qa = ip->i_qadata; struct gfs2_quota_data *qd; s64 value; unsigned int x; @@ -1054,8 +1056,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) return 0; - for (x = 0; x < qa->qa_qd_num; x++) { - qd = qa->qa_qd[x]; + for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { + qd = ip->i_res->rs_qa_qd[x]; if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) @@ -1093,7 +1095,6 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) void gfs2_quota_change(struct gfs2_inode *ip, s64 change, u32 uid, u32 gid) { - struct gfs2_qadata *qa = ip->i_qadata; struct gfs2_quota_data *qd; unsigned int x; @@ -1102,8 +1103,8 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, if (ip->i_diskflags & GFS2_DIF_SYSTEM) return; - for (x = 0; x < qa->qa_qd_num; x++) { - qd = qa->qa_qd[x]; + for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { + qd = ip->i_res->rs_qa_qd[x]; if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index e944fefbc9a8..9eca6a9cff8f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1006,25 +1006,6 @@ out: return ret; } -/** - * gfs2_qadata_get - get the struct gfs2_qadata structure for an inode - * @ip: the incore GFS2 inode structure - * - * Returns: the struct gfs2_qadata - */ - -struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip) -{ - struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - int error; - BUG_ON(ip->i_qadata != NULL); - ip->i_qadata = kzalloc(sizeof(struct gfs2_qadata), GFP_NOFS); - error = gfs2_rindex_update(sdp); - if (error) - fs_warn(sdp, "rindex update returns %d\n", error); - return ip->i_qadata; -} - /** * try_rgrp_fit - See if a given reservation will fit in a given RG * @rgd: the RG data diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index d9eda5f9ef2a..5d8314dbc899 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h @@ -29,14 +29,6 @@ extern void gfs2_free_clones(struct gfs2_rgrpd *rgd); extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh); extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh); -extern struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip); -static inline void gfs2_qadata_put(struct gfs2_inode *ip) -{ - BUG_ON(ip->i_qadata == NULL); - kfree(ip->i_qadata); - ip->i_qadata = NULL; -} - extern int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested); extern void gfs2_inplace_release(struct gfs2_inode *ip); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 65578df29446..81fc76264ed4 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1399,7 +1399,6 @@ static void gfs2_final_release_pages(struct gfs2_inode *ip) static int gfs2_dinode_dealloc(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_qadata *qa; struct gfs2_rgrpd *rgd; struct gfs2_holder gh; int error; @@ -1409,13 +1408,9 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip) return -EIO; } - qa = gfs2_qadata_get(ip); - if (!qa) - return -ENOMEM; - error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) - goto out; + return error; rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1); if (!rgd) { @@ -1443,8 +1438,6 @@ out_rg_gunlock: gfs2_glock_dq_uninit(&gh); out_qs: gfs2_quota_unhold(ip); -out: - gfs2_qadata_put(ip); return error; } diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 927f4df874ae..523c0de0d805 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -325,13 +325,8 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, struct gfs2_ea_header *ea, struct gfs2_ea_header *prev, int leave) { - struct gfs2_qadata *qa; int error; - qa = gfs2_qadata_get(ip); - if (!qa) - return -ENOMEM; - error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) goto out_alloc; @@ -340,7 +335,6 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, gfs2_quota_unhold(ip); out_alloc: - gfs2_qadata_put(ip); return error; } @@ -713,17 +707,12 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, unsigned int blks, ea_skeleton_call_t skeleton_call, void *private) { - struct gfs2_qadata *qa; struct buffer_head *dibh; int error; - qa = gfs2_qadata_get(ip); - if (!qa) - return -ENOMEM; - error = gfs2_quota_lock_check(ip); if (error) - goto out; + return error; error = gfs2_inplace_reserve(ip, blks); if (error) @@ -753,8 +742,6 @@ out_ipres: gfs2_inplace_release(ip); out_gunlock_q: gfs2_quota_unlock(ip); -out: - gfs2_qadata_put(ip); return error; } @@ -1494,16 +1481,11 @@ out_gunlock: int gfs2_ea_dealloc(struct gfs2_inode *ip) { - struct gfs2_qadata *qa; int error; - qa = gfs2_qadata_get(ip); - if (!qa) - return -ENOMEM; - error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) - goto out_alloc; + return error; error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); if (error) @@ -1519,8 +1501,6 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip) out_quota: gfs2_quota_unhold(ip); -out_alloc: - gfs2_qadata_put(ip); return error; } -- GitLab From 23d0bb834e264f38335f19fe601564b8422431e7 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 28 May 2012 15:26:56 +0100 Subject: [PATCH 0700/6849] GFS2: Add "top dir" flag support This patch adds support for the "top dir" flag. Currently this is unused but a subsequent patch is planned which will add support for the Orlov allocation policy when allocating subdirectories in a parent with this flag set. In order to ensure backward compatible behaviour, mkfs.gfs2 does not currently tag the root directory with this flag, it must always be set manually. Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 4 ++++ include/linux/gfs2_ondisk.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 26e2905070ed..6fbf3cbd974d 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -142,6 +142,7 @@ static const u32 fsflags_to_gfs2[32] = { [7] = GFS2_DIF_NOATIME, [12] = GFS2_DIF_EXHASH, [14] = GFS2_DIF_INHERIT_JDATA, + [17] = GFS2_DIF_TOPDIR, }; static const u32 gfs2_to_fsflags[32] = { @@ -150,6 +151,7 @@ static const u32 gfs2_to_fsflags[32] = { [gfs2fl_AppendOnly] = FS_APPEND_FL, [gfs2fl_NoAtime] = FS_NOATIME_FL, [gfs2fl_ExHash] = FS_INDEX_FL, + [gfs2fl_TopLevel] = FS_TOPDIR_FL, [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, }; @@ -203,6 +205,7 @@ void gfs2_set_inode_flags(struct inode *inode) GFS2_DIF_NOATIME| \ GFS2_DIF_SYNC| \ GFS2_DIF_SYSTEM| \ + GFS2_DIF_TOPDIR| \ GFS2_DIF_INHERIT_JDATA) /** @@ -298,6 +301,7 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); if (!S_ISDIR(inode->i_mode)) { + gfsflags &= ~GFS2_DIF_TOPDIR; if (gfsflags & GFS2_DIF_INHERIT_JDATA) gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); return do_gfs2_set_flags(filp, gfsflags, ~0); diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index fa98bdb073b9..e8ccf6ff3b4d 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -214,6 +214,7 @@ enum { gfs2fl_NoAtime = 7, gfs2fl_Sync = 8, gfs2fl_System = 9, + gfs2fl_TopLevel = 10, gfs2fl_TruncInProg = 29, gfs2fl_InheritDirectio = 30, gfs2fl_InheritJdata = 31, @@ -230,8 +231,9 @@ enum { #define GFS2_DIF_NOATIME 0x00000080 #define GFS2_DIF_SYNC 0x00000100 #define GFS2_DIF_SYSTEM 0x00000200 /* New in gfs2 */ +#define GFS2_DIF_TOPDIR 0x00000400 /* New in gfs2 */ #define GFS2_DIF_TRUNC_IN_PROG 0x20000000 /* New in gfs2 */ -#define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 +#define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 /* only in gfs1 */ #define GFS2_DIF_INHERIT_JDATA 0x80000000 struct gfs2_dinode { -- GitLab From 1b8ba31a88c5115687095ca2a01bfcaecb489b5a Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 29 May 2012 10:47:51 +0100 Subject: [PATCH 0701/6849] GFS2: Fix error handling when reading an invalid block from the journal When we read an invalid block from the journal, we should not call withdraw, but simply print a message and return an error. It is up to the caller to then handle that error. In the case of mount that means a failed mount, rather than a withdraw (requiring a reboot). In the case of recovering another nodes journal then we return an error via the uevent. Signed-off-by: Steven Whitehouse --- fs/gfs2/lops.c | 9 +++++++-- fs/gfs2/util.h | 18 +++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 852c1be1dd3b..8ff95a2d54ee 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -401,9 +401,14 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); - gfs2_meta_check(sdp, bd->bd_bh); - gfs2_pin(sdp, bd->bd_bh); mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; + if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) { + printk(KERN_ERR + "Attempting to add uninitialised block to journal (inplace block=%lld)\n", + (unsigned long long)bd->bd_bh->b_blocknr); + BUG(); + } + gfs2_pin(sdp, bd->bd_bh); mh->__pad0 = cpu_to_be64(0); mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); sdp->sd_log_num_buf++; diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 3586b0dd6aa7..80535739ac7b 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h @@ -79,23 +79,19 @@ int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, const char *type, const char *function, char *file, unsigned int line); -static inline int gfs2_meta_check_i(struct gfs2_sbd *sdp, - struct buffer_head *bh, - const char *function, - char *file, unsigned int line) +static inline int gfs2_meta_check(struct gfs2_sbd *sdp, + struct buffer_head *bh) { struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; u32 magic = be32_to_cpu(mh->mh_magic); - if (unlikely(magic != GFS2_MAGIC)) - return gfs2_meta_check_ii(sdp, bh, "magic number", function, - file, line); + if (unlikely(magic != GFS2_MAGIC)) { + printk(KERN_ERR "GFS2: Magic number missing at %llu\n", + (unsigned long long)bh->b_blocknr); + return -EIO; + } return 0; } -#define gfs2_meta_check(sdp, bh) \ -gfs2_meta_check_i((sdp), (bh), __func__, __FILE__, __LINE__) - - int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, u16 type, u16 t, const char *function, -- GitLab From 4ae57b6cfe67d12c9ba340cf172dc4e38a651ec5 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 5 Jun 2012 13:05:02 +0200 Subject: [PATCH 0702/6849] KVM: s390: Change maintainer Since Carsten is now working on a different project, Cornelia will work as the 2nd s390/kvm maintainer. Signed-off-by: Christian Borntraeger CC: Carsten Otte CC: Cornelia Huck Signed-off-by: Avi Kivity --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6a52bb4a4fc7..4023d0b4e9db 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3987,8 +3987,8 @@ F: arch/ia64/include/asm/kvm* F: arch/ia64/kvm/ KERNEL VIRTUAL MACHINE for s390 (KVM/s390) -M: Carsten Otte M: Christian Borntraeger +M: Cornelia Huck M: linux390@de.ibm.com L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ -- GitLab From e19ebcab01cc130fa832764d453b263460ec3b91 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Thu, 10 May 2012 15:53:14 +0300 Subject: [PATCH 0703/6849] iwlwifi: Check BSS ctx active before call mac80211 It is possible that the BSS context is not active (for example when the current mode is set to GO), or that the vif->type is different than station. In such a case we cannot call mac80211 to report the average rssi for the interface (the function assumes that the vif is valid and that the type is station). Reviewed-by: Emmanuel Grumbach Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e55ec6c8a920..c31072d42791 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -617,6 +617,11 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int ave_rssi; + if (!ctx->vif || (ctx->vif->type != NL80211_IFTYPE_STATION)) { + IWL_DEBUG_INFO(priv, "BSS ctx not active or not in sta mode\n"); + return false; + } + ave_rssi = ieee80211_ave_rssi(ctx->vif); if (!ave_rssi) { /* no rssi data, no changes to reduce tx power */ -- GitLab From 622a9268231bd6b486ec058a28f773fa89926012 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 9 May 2012 16:11:55 +0300 Subject: [PATCH 0704/6849] iwlwifi: handle race condition in ROC flow When a remain on channel request from mac80211 is followed by a request to tx a mgmt frame offchannel, it is possible that the remain on channel expires before the device reported the tx status for the frame. This causes a race condition in mac80211. To fix this, delay the ROC notification to mac80211 until the device reported the Tx status for all frames in the aux queue. Reviewed-by: Emmanuel Grumbach Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 18 ++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++ drivers/net/wireless/iwlwifi/iwl-agn.h | 5 +++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-scan.c | 51 ++++++++++++++++++----- 5 files changed, 68 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 3366e2e2f00f..ad1d36fa7642 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -486,6 +486,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (sta_priv && sta_priv->client && !is_agg) atomic_inc(&sta_priv->pending_frames); + if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) + iwl_scan_offchannel_skb(priv); + return 0; drop_unlock_sta: @@ -1136,6 +1139,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct sk_buff *skb; struct iwl_rxon_context *ctx; bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); + bool is_offchannel_skb; tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> IWLAGN_TX_RES_TID_POS; @@ -1149,6 +1153,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, __skb_queue_head_init(&skbs); + is_offchannel_skb = false; + if (tx_resp->frame_count == 1) { u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); @@ -1225,10 +1231,19 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, if (!is_agg) iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); + is_offchannel_skb = + (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); freed++; } WARN_ON(!is_agg && freed != 1); + + /* + * An offchannel frame can be send only on the AUX queue, where + * there is no aggregation (and reordering) so it only is single + * skb is expected to be processed. + */ + WARN_ON(is_offchannel_skb && freed != 1); } iwl_check_abort_status(priv, tx_resp->frame_count, status); @@ -1239,6 +1254,9 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, ieee80211_tx_status(priv->hw, skb); } + if (is_offchannel_skb) + iwl_scan_offchannel_skb_status(priv); + return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5149e6f72945..cd95a240511a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -931,6 +931,9 @@ void iwl_down(struct iwl_priv *priv) priv->ucode_loaded = false; iwl_trans_stop_device(priv->trans); + /* Set num_aux_in_flight must be done after the transport is stopped */ + atomic_set(&priv->num_aux_in_flight, 0); + /* Clear out all status bits but a few that are stable across reset */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 79c0fe06f4db..5c1693f2573b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -101,6 +101,7 @@ extern struct iwl_lib_ops iwl6030_lib; #define STATUS_CHANNEL_SWITCH_PENDING 11 #define STATUS_SCAN_COMPLETE 12 #define STATUS_POWER_PMI 13 +#define STATUS_SCAN_ROC_EXPIRED 14 struct iwl_ucode_capabilities; @@ -255,6 +256,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, enum iwl_scan_type scan_type, enum ieee80211_band band); +void iwl_scan_roc_expired(struct iwl_priv *priv); +void iwl_scan_offchannel_skb(struct iwl_priv *priv); +void iwl_scan_offchannel_skb_status(struct iwl_priv *priv); + /* For faster active scanning, scan will move to the next channel if fewer than * PLCP_QUIET_THRESH packets are heard on this channel within * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 70062379d0ec..a4936a134162 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -846,6 +846,7 @@ struct iwl_priv { struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; unsigned long ucode_key_table; struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; + atomic_t num_aux_in_flight; u8 mac80211_registered; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 031d8e21f82f..eb0ded7a8a99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -101,11 +101,8 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) ieee80211_scan_completed(priv->hw, aborted); } - if (priv->scan_type == IWL_SCAN_ROC) { - ieee80211_remain_on_channel_expired(priv->hw); - priv->hw_roc_channel = NULL; - schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); - } + if (priv->scan_type == IWL_SCAN_ROC) + iwl_scan_roc_expired(priv); priv->scan_type = IWL_SCAN_NORMAL; priv->scan_vif = NULL; @@ -134,11 +131,8 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) goto out_settings; } - if (priv->scan_type == IWL_SCAN_ROC) { - ieee80211_remain_on_channel_expired(priv->hw); - priv->hw_roc_channel = NULL; - schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); - } + if (priv->scan_type == IWL_SCAN_ROC) + iwl_scan_roc_expired(priv); if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { int err; @@ -1158,3 +1152,40 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) mutex_unlock(&priv->mutex); } } + +void iwl_scan_roc_expired(struct iwl_priv *priv) +{ + /* + * The status bit should be set here, to prevent a race + * where the atomic_read returns 1, but before the execution continues + * iwl_scan_offchannel_skb_status() checks if the status bit is set + */ + set_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status); + + if (atomic_read(&priv->num_aux_in_flight) == 0) { + ieee80211_remain_on_channel_expired(priv->hw); + priv->hw_roc_channel = NULL; + schedule_delayed_work(&priv->hw_roc_disable_work, + 10 * HZ); + + clear_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status); + } else { + IWL_DEBUG_SCAN(priv, "ROC done with %d frames in aux\n", + atomic_read(&priv->num_aux_in_flight)); + } +} + +void iwl_scan_offchannel_skb(struct iwl_priv *priv) +{ + WARN_ON(!priv->hw_roc_start_notified); + atomic_inc(&priv->num_aux_in_flight); +} + +void iwl_scan_offchannel_skb_status(struct iwl_priv *priv) +{ + if (atomic_dec_return(&priv->num_aux_in_flight) == 0 && + test_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status)) { + IWL_DEBUG_SCAN(priv, "0 aux frames. Calling ROC expired\n"); + iwl_scan_roc_expired(priv); + } +} -- GitLab From aca86268faad5caed582de463c96061605c8ad60 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 14 May 2012 09:08:50 +0200 Subject: [PATCH 0705/6849] iwlwifi: make a lot of functions static A lot of functions were temporarily made non-static for experimental work, make them static again now. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 21 ++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 32 +++--- drivers/net/wireless/iwlwifi/iwl-agn.h | 81 --------------- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 106 ++++++++++---------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- 5 files changed, 82 insertions(+), 160 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 0a3aa7c83003..7fc8c25c7d41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -175,7 +175,8 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, return ret; } -void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +static void iwlagn_update_qos(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int ret; @@ -202,8 +203,8 @@ void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); } -int iwlagn_update_beacon(struct iwl_priv *priv, - struct ieee80211_vif *vif) +static int iwlagn_update_beacon(struct iwl_priv *priv, + struct ieee80211_vif *vif) { lockdep_assert_held(&priv->mutex); @@ -215,7 +216,7 @@ int iwlagn_update_beacon(struct iwl_priv *priv, } static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) + struct iwl_rxon_context *ctx) { int ret = 0; struct iwl_rxon_assoc_cmd rxon_assoc; @@ -863,8 +864,8 @@ static int iwl_check_rxon_cmd(struct iwl_priv *priv, * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ -int iwl_full_rxon_required(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) +static int iwl_full_rxon_required(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { const struct iwl_rxon_cmd *staging = &ctx->staging; const struct iwl_rxon_cmd *active = &ctx->active; @@ -1294,9 +1295,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) return ret; } -void iwlagn_check_needed_chains(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_bss_conf *bss_conf) +static void iwlagn_check_needed_chains(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_bss_conf *bss_conf) { struct ieee80211_vif *vif = ctx->vif; struct iwl_rxon_context *tmp; @@ -1388,7 +1389,7 @@ void iwlagn_check_needed_chains(struct iwl_priv *priv, ht_conf->single_chain_sufficient = !need_multiple; } -void iwlagn_chain_noise_reset(struct iwl_priv *priv) +static void iwlagn_chain_noise_reset(struct iwl_priv *priv) { struct iwl_chain_noise_data *data = &priv->chain_noise_data; int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cd95a240511a..fa007176bad2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -577,7 +577,7 @@ static const u8 iwlagn_pan_ac_to_queue[] = { 7, 6, 5, 4, }; -void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) +static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) { int i; @@ -644,7 +644,7 @@ void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); } -void iwl_rf_kill_ct_config(struct iwl_priv *priv) +static void iwl_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; struct iwl_ct_kill_throttling_config adv_cmd; @@ -725,7 +725,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) } } -void iwl_send_bt_config(struct iwl_priv *priv) +static void iwl_send_bt_config(struct iwl_priv *priv) { struct iwl_bt_cmd bt_cmd = { .lead_time = BT_LEAD_TIME_DEF, @@ -1080,7 +1080,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work) * *****************************************************************************/ -void iwl_setup_deferred_work(struct iwl_priv *priv) +static void iwl_setup_deferred_work(struct iwl_priv *priv) { priv->workqueue = create_singlethread_workqueue(DRV_NAME); @@ -1331,7 +1331,7 @@ static void iwl_free_geos(struct iwl_priv *priv) clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } -int iwl_init_drv(struct iwl_priv *priv) +static int iwl_init_drv(struct iwl_priv *priv) { int ret; @@ -1394,7 +1394,7 @@ err: return ret; } -void iwl_uninit_drv(struct iwl_priv *priv) +static void iwl_uninit_drv(struct iwl_priv *priv) { iwl_free_geos(priv); iwl_free_channel_map(priv); @@ -1407,7 +1407,7 @@ void iwl_uninit_drv(struct iwl_priv *priv) #endif } -void iwl_set_hw_params(struct iwl_priv *priv) +static void iwl_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->ht_params) priv->hw_params.use_rts_for_aggregation = @@ -1423,7 +1423,7 @@ void iwl_set_hw_params(struct iwl_priv *priv) /* show what optional capabilities we have */ -void iwl_option_config(struct iwl_priv *priv) +static void iwl_option_config(struct iwl_priv *priv) { #ifdef CONFIG_IWLWIFI_DEBUG IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n"); @@ -1722,7 +1722,7 @@ out: return op_mode; } -void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) +static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); @@ -2187,7 +2187,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) } } -void iwl_nic_error(struct iwl_op_mode *op_mode) +static void iwl_nic_error(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); @@ -2200,7 +2200,7 @@ void iwl_nic_error(struct iwl_op_mode *op_mode) iwlagn_fw_error(priv, false); } -void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) +static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); @@ -2210,7 +2210,7 @@ void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) } } -void iwl_nic_config(struct iwl_op_mode *op_mode) +static void iwl_nic_config(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); @@ -2225,7 +2225,7 @@ static void iwl_wimax_active(struct iwl_op_mode *op_mode) IWL_ERR(priv, "RF is used by WiMAX\n"); } -void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) +static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); int mq = priv->queue_to_mac80211[queue]; @@ -2244,7 +2244,7 @@ void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) ieee80211_stop_queue(priv->hw, mq); } -void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) +static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); int mq = priv->queue_to_mac80211[queue]; @@ -2284,7 +2284,7 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) priv->passive_no_rx = false; } -void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) +static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) { struct ieee80211_tx_info *info; @@ -2293,7 +2293,7 @@ void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) dev_kfree_skb_any(skb); } -void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) +static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5c1693f2573b..3f3607fd7dad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -523,85 +523,4 @@ static inline const char *iwl_dvm_get_cmd_string(u8 cmd) return s; return "UNKNOWN"; } - -/* API method exported for mvm hybrid state */ -void iwl_setup_deferred_work(struct iwl_priv *priv); -int iwl_send_wimax_coex(struct iwl_priv *priv); -int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); -void iwl_option_config(struct iwl_priv *priv); -void iwl_set_hw_params(struct iwl_priv *priv); -void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); -int iwl_init_drv(struct iwl_priv *priv); -void iwl_uninit_drv(struct iwl_priv *priv); -void iwl_send_bt_config(struct iwl_priv *priv); -void iwl_rf_kill_ct_config(struct iwl_priv *priv); -int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -void iwl_teardown_interface(struct iwl_priv *priv, - struct ieee80211_vif *vif, - bool mode_change); -int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -void iwlagn_check_needed_chains(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_bss_conf *bss_conf); -void iwlagn_chain_noise_reset(struct iwl_priv *priv); -int iwlagn_update_beacon(struct iwl_priv *priv, - struct ieee80211_vif *vif); -void iwl_tt_handler(struct iwl_priv *priv); -void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode); -void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue); -void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); -void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); -void iwl_nic_error(struct iwl_op_mode *op_mode); -void iwl_cmd_queue_full(struct iwl_op_mode *op_mode); -void iwl_nic_config(struct iwl_op_mode *op_mode); -int iwlagn_mac_set_tim(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, bool set); -void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, - enum ieee80211_rssi_event rssi_event); -int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw); -int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw); -void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop); -void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue); -void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, - struct ieee80211_channel_switch *ch_switch); -int iwlagn_mac_sta_state(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - enum ieee80211_sta_state old_state, - enum ieee80211_sta_state new_state); -int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn, - u8 buf_size); -int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req); -void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta); -void iwlagn_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast); -int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u16 queue, - const struct ieee80211_tx_queue_params *params); -void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_gtk_rekey_data *data); -void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, - u32 iv32, u16 *phase1key); -int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); -void iwlagn_mac_stop(struct ieee80211_hw *hw); -void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index ff66200b8eaa..d0b64cd95fc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -338,7 +338,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) return 0; } -void iwlagn_mac_stop(struct ieee80211_hw *hw) +static void iwlagn_mac_stop(struct ieee80211_hw *hw) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -366,9 +366,9 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_gtk_rekey_data *data) +static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -394,7 +394,8 @@ void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, #ifdef CONFIG_PM_SLEEP -int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) +static int iwlagn_mac_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; @@ -505,7 +506,7 @@ static void iwlagn_mac_set_wakeup(struct ieee80211_hw *hw, bool enabled) } #endif -void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -516,21 +517,21 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); } -void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, - u32 iv32, u16 *phase1key) +static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); } -int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; @@ -630,11 +631,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn, - u8 buf_size) +static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int ret = -EINVAL; @@ -756,11 +757,11 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, return ret; } -int iwlagn_mac_sta_state(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - enum ieee80211_sta_state old_state, - enum ieee80211_sta_state new_state) +static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; @@ -839,8 +840,8 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, return ret; } -void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, - struct ieee80211_channel_switch *ch_switch) +static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_channel_switch *ch_switch) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); const struct iwl_channel_info *ch_info; @@ -934,10 +935,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) ieee80211_chswitch_done(ctx->vif, is_success); } -void iwlagn_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) +static void iwlagn_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); __le32 filter_or = 0, filter_nand = 0; @@ -984,7 +985,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw, FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; } -void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) +static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -1111,7 +1112,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, return err; } -int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) +static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -1128,8 +1129,8 @@ int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return 0; } -void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, - enum ieee80211_rssi_event rssi_event) +static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, + enum ieee80211_rssi_event rssi_event) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -1153,8 +1154,8 @@ void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -int iwlagn_mac_set_tim(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, bool set) +static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, bool set) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -1163,9 +1164,9 @@ int iwlagn_mac_set_tim(struct ieee80211_hw *hw, return 0; } -int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u16 queue, - const struct ieee80211_tx_queue_params *params) +static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u16 queue, + const struct ieee80211_tx_queue_params *params) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; @@ -1207,7 +1208,7 @@ int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, return 0; } -int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) +static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); @@ -1223,7 +1224,8 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return iwlagn_commit_rxon(priv, ctx); } -int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +static int iwl_setup_interface(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { struct ieee80211_vif *vif = ctx->vif; int err, ac; @@ -1343,9 +1345,9 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, return err; } -void iwl_teardown_interface(struct iwl_priv *priv, - struct ieee80211_vif *vif, - bool mode_change) +static void iwl_teardown_interface(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool mode_change) { struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); @@ -1486,9 +1488,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, return err; } -int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req) +static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_scan_request *req) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int ret; @@ -1543,10 +1545,10 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) iwl_send_add_sta(priv, &cmd, CMD_ASYNC); } -void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta) +static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index bc40dc68b0f4..d14e633bebc9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -177,7 +177,7 @@ int iwl_init_alive_start(struct iwl_priv *priv) return 0; } -int iwl_send_wimax_coex(struct iwl_priv *priv) +static int iwl_send_wimax_coex(struct iwl_priv *priv) { struct iwl_wimax_coex_cmd coex_cmd; -- GitLab From 7ad580c2e6d918379b89668ea4e58a3599e27ee5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 15:40:11 +0200 Subject: [PATCH 0706/6849] iwlwifi: use mac80211 channel in connection init mac80211 guarantees that the channel pointer is always valid, so we can use that instead of our own channel list. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 7fc8c25c7d41..c570318a2375 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -37,8 +37,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - const struct iwl_channel_info *ch_info; - memset(&ctx->staging, 0, sizeof(ctx->staging)); if (!ctx->vif) { @@ -80,14 +78,8 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif - ch_info = iwl_get_channel_info(priv, priv->band, - le16_to_cpu(ctx->active.channel)); - - if (!ch_info) - ch_info = &priv->channel_info[0]; - - ctx->staging.channel = cpu_to_le16(ch_info->channel); - priv->band = ch_info->band; + ctx->staging.channel = cpu_to_le16(priv->hw->conf.channel->hw_value); + priv->band = priv->hw->conf.channel->band; iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); -- GitLab From 9dc216d740e1210ccb3da533e2dab99a156300f9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 15:42:56 +0200 Subject: [PATCH 0707/6849] iwlwifi: trust mac80211 channel setting mac80211 will never set, switch to, or scan on an invalid channel, so remove the code to validate the channels against the driver channel list. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 9 --------- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-scan.c | 12 +----------- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c570318a2375..36b4965527c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -1182,7 +1182,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) struct iwl_rxon_context *ctx; struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = conf->channel; - const struct iwl_channel_info *ch_info; int ret = 0; IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); @@ -1216,14 +1215,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ch_info = iwl_get_channel_info(priv, channel->band, - channel->hw_value); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); - ret = -EINVAL; - goto out; - } - for_each_context(priv, ctx) { /* Configure HT40 channels */ if (ctx->ht.enabled != conf_is_ht(conf)) diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index d0b64cd95fc5..19e5235fba7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -844,7 +844,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - const struct iwl_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = ch_switch->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; @@ -881,12 +880,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, if (le16_to_cpu(ctx->active.channel) == ch) goto out; - ch_info = iwl_get_channel_info(priv, channel->band, ch); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "invalid channel\n"); - goto out; - } - priv->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index eb0ded7a8a99..ea05ae8280e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -534,7 +534,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, { struct ieee80211_channel *chan; const struct ieee80211_supported_band *sband; - const struct iwl_channel_info *ch_info; u16 passive_dwell = 0; u16 active_dwell = 0; int added, i; @@ -559,16 +558,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, channel = chan->hw_value; scan_ch->channel = cpu_to_le16(channel); - ch_info = iwl_get_channel_info(priv, band, channel); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN(priv, - "Channel %d is INVALID for this band.\n", - channel); - continue; - } - - if (!is_active || is_channel_passive(ch_info) || - (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) + if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; else scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; -- GitLab From d9b9d940ac2d1c03ec955dc921dd12e432a64e5c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 15:44:27 +0200 Subject: [PATCH 0708/6849] iwlwifi: use mac80211 channels for reset scan Instead of iterating our own channel list, use the mac80211 channel list since that's already processed per band and thus makes for less code. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-scan.c | 28 +++++++------------------ 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index ea05ae8280e1..069849e66234 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -447,27 +447,17 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, /* Return valid, unused, channel for a passive scan to reset the RF */ static u8 iwl_get_single_channel_number(struct iwl_priv *priv, - enum ieee80211_band band) + enum ieee80211_band band) { - const struct iwl_channel_info *ch_info; - int i; - u8 channel = 0; - u8 min, max; + struct ieee80211_supported_band *sband = priv->hw->wiphy->bands[band]; struct iwl_rxon_context *ctx; + int i; - if (band == IEEE80211_BAND_5GHZ) { - min = 14; - max = priv->channel_count; - } else { - min = 0; - max = 14; - } - - for (i = min; i < max; i++) { + for (i = 0; i < sband->n_channels; i++) { bool busy = false; for_each_context(priv, ctx) { - busy = priv->channel_info[i].channel == + busy = sband->channels[i].hw_value == le16_to_cpu(ctx->staging.channel); if (busy) break; @@ -476,13 +466,11 @@ static u8 iwl_get_single_channel_number(struct iwl_priv *priv, if (busy) continue; - channel = priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, band, channel); - if (is_channel_valid(ch_info)) - break; + if (!(sband->channels[i].flags & IEEE80211_CHAN_DISABLED)) + return sband->channels[i].hw_value; } - return channel; + return 0; } static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, -- GitLab From cc66880ba58ef6b9ee645fa1e1c074746ff03ce4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 16:37:57 +0200 Subject: [PATCH 0709/6849] iwlwifi: use mac80211 channel for radar check In channel switch, instead of relying on our internal channel database, just use the mac80211 channel that we filled with that information on startup. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- .../net/wireless/iwlwifi/iwl-agn-devices.c | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c index 48533b3a0f9a..529cdac6f739 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c @@ -455,7 +455,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl5000_channel_switch_cmd cmd; - const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; @@ -505,14 +504,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", cmd.switch_time); - ch_info = iwl_get_channel_info(priv, priv->band, ch); - if (ch_info) - cmd.expect_beacon = is_channel_radar(ch_info); - else { - IWL_ERR(priv, "invalid channel switch from %u to %u\n", - ctx->active.channel, ch); - return -EFAULT; - } + cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; return iwl_dvm_send_cmd(priv, &hcmd); } @@ -654,7 +646,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl6000_channel_switch_cmd cmd; - const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; @@ -704,14 +695,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", cmd.switch_time); - ch_info = iwl_get_channel_info(priv, priv->band, ch); - if (ch_info) - cmd.expect_beacon = is_channel_radar(ch_info); - else { - IWL_ERR(priv, "invalid channel switch from %u to %u\n", - ctx->active.channel, ch); - return -EFAULT; - } + cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; return iwl_dvm_send_cmd(priv, &hcmd); } -- GitLab From 53e1116ebd3c0bab4d6daf0da4492f813b778cf8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 23:59:03 +0200 Subject: [PATCH 0710/6849] iwlwifi: give HT format to mac80211/radiotap We know whether we received a frame in GF format or not, add it to the radiotap information. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 403de96f9747..5035d2db14b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1012,6 +1012,8 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, rx_status.flag |= RX_FLAG_40MHZ; if (rate_n_flags & RATE_MCS_SGI_MSK) rx_status.flag |= RX_FLAG_SHORT_GI; + if (rate_n_flags & RATE_MCS_GF_MSK) + rx_status.flag |= RX_FLAG_HT_GF; iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, rxb, &rx_status); diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 19e5235fba7c..26a87c2b1653 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -154,6 +155,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, IEEE80211_HW_SCAN_WHILE_IDLE; hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; + hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT; /* * Including the following line will crash some AP's. This -- GitLab From 76a3aa89937cf0b9a560e4c778e54e993018da60 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Thu, 17 May 2012 12:42:59 +0300 Subject: [PATCH 0711/6849] iwlwifi: clear STATUS_SCAN_HW when PAN_PARAMS fails The STATUS_SCAN_HW is set before calling iwlagn_set_pan_params (used as an input to calculate slot time allocation). The bit needs to be cleared in case sending the command fails. Reviewed-by: Emmanuel Grumbach Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-scan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 069849e66234..a32b35ea9e60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -966,8 +966,10 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) set_bit(STATUS_SCAN_HW, &priv->status); ret = iwlagn_set_pan_params(priv); - if (ret) + if (ret) { + clear_bit(STATUS_SCAN_HW, &priv->status); return ret; + } ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) { -- GitLab From 6468a01a7181f3572a3e686910016f89ee71ff45 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 19:13:54 +0200 Subject: [PATCH 0712/6849] iwlwifi: move PCIe into subdirectory Structure the code a bit more and move all PCIe code including the hardware configuration files into a PCIe specific subdirectory. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 10 +++------- .../net/wireless/iwlwifi/{iwl-1000.c => pcie/1000.c} | 2 +- .../net/wireless/iwlwifi/{iwl-2000.c => pcie/2000.c} | 2 +- .../net/wireless/iwlwifi/{iwl-5000.c => pcie/5000.c} | 2 +- .../net/wireless/iwlwifi/{iwl-6000.c => pcie/6000.c} | 2 +- drivers/net/wireless/iwlwifi/{iwl-cfg.h => pcie/cfg.h} | 0 drivers/net/wireless/iwlwifi/{iwl-pci.c => pcie/drv.c} | 5 +++-- .../iwlwifi/{iwl-trans-pcie-int.h => pcie/internal.h} | 0 .../iwlwifi/{iwl-trans-pcie-rx.c => pcie/rx.c} | 2 +- .../iwlwifi/{iwl-trans-pcie.c => pcie/trans.c} | 2 +- .../iwlwifi/{iwl-trans-pcie-tx.c => pcie/tx.c} | 2 +- 11 files changed, 13 insertions(+), 16 deletions(-) rename drivers/net/wireless/iwlwifi/{iwl-1000.c => pcie/1000.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-2000.c => pcie/2000.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-5000.c => pcie/5000.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-6000.c => pcie/6000.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-cfg.h => pcie/cfg.h} (100%) rename drivers/net/wireless/iwlwifi/{iwl-pci.c => pcie/drv.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-trans-pcie-int.h => pcie/internal.h} (100%) rename drivers/net/wireless/iwlwifi/{iwl-trans-pcie-rx.c => pcie/rx.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-trans-pcie.c => pcie/trans.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-trans-pcie-tx.c => pcie/tx.c} (99%) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 931002738c9f..f155126e9a21 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -15,17 +15,13 @@ CFLAGS_iwl-devtrace.o := -I$(src) # WIFI obj-$(CONFIG_IWLWIFI) += iwlwifi.o -iwlwifi-objs += iwl-5000.o -iwlwifi-objs += iwl-6000.o -iwlwifi-objs += iwl-1000.o -iwlwifi-objs += iwl-2000.o iwlwifi-objs += iwl-io.o -iwlwifi-objs += iwl-pci.o iwlwifi-objs += iwl-drv.o iwlwifi-objs += iwl-debug.o iwlwifi-objs += iwl-notif-wait.o -iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o +iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o +iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o -ccflags-y += -D__CHECK_ENDIAN__ +ccflags-y += -D__CHECK_ENDIAN__ -I$(src) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-1000.c rename to drivers/net/wireless/iwlwifi/pcie/1000.c index 2629a6602dfa..0cfbf9fb74d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/pcie/1000.c @@ -27,9 +27,9 @@ #include #include #include "iwl-config.h" -#include "iwl-cfg.h" #include "iwl-csr.h" #include "iwl-agn-hw.h" +#include "cfg.h" /* Highest firmware API version supported */ #define IWL1000_UCODE_API_MAX 5 diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-2000.c rename to drivers/net/wireless/iwlwifi/pcie/2000.c index 8133105ac645..f6efa122336b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c @@ -27,8 +27,8 @@ #include #include #include "iwl-config.h" -#include "iwl-cfg.h" #include "iwl-agn-hw.h" +#include "cfg.h" #include "iwl-commands.h" /* needed for BT for now */ /* Highest firmware API version supported */ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-5000.c rename to drivers/net/wireless/iwlwifi/pcie/5000.c index 8e26bc825f23..92e502e6e7e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/pcie/5000.c @@ -27,9 +27,9 @@ #include #include #include "iwl-config.h" -#include "iwl-cfg.h" #include "iwl-agn-hw.h" #include "iwl-csr.h" +#include "cfg.h" /* Highest firmware API version supported */ #define IWL5000_UCODE_API_MAX 5 diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-6000.c rename to drivers/net/wireless/iwlwifi/pcie/6000.c index 19f7ee84ae89..7360cd9e0148 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c @@ -27,8 +27,8 @@ #include #include #include "iwl-config.h" -#include "iwl-cfg.h" #include "iwl-agn-hw.h" +#include "cfg.h" #include "iwl-commands.h" /* needed for BT for now */ /* Highest firmware API version supported */ diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h similarity index 100% rename from drivers/net/wireless/iwlwifi/iwl-cfg.h rename to drivers/net/wireless/iwlwifi/pcie/cfg.h diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/pcie/drv.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-pci.c rename to drivers/net/wireless/iwlwifi/pcie/drv.c index 0c8a1c2d8847..f4c3500b68c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -68,10 +68,11 @@ #include #include "iwl-trans.h" -#include "iwl-cfg.h" #include "iwl-drv.h" #include "iwl-trans.h" -#include "iwl-trans-pcie-int.h" + +#include "cfg.h" +#include "internal.h" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/pcie/internal.h similarity index 100% rename from drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h rename to drivers/net/wireless/iwlwifi/pcie/internal.h diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c rename to drivers/net/wireless/iwlwifi/pcie/rx.c index 98605fc7ad37..d6860c070c16 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -32,7 +32,7 @@ #include "iwl-prph.h" #include "iwl-io.h" -#include "iwl-trans-pcie-int.h" +#include "internal.h" #include "iwl-op-mode.h" #ifdef CONFIG_IWLWIFI_IDI diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/pcie/trans.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-trans-pcie.c rename to drivers/net/wireless/iwlwifi/pcie/trans.c index 1e50401023e0..e8a04a18a7d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -70,11 +70,11 @@ #include "iwl-drv.h" #include "iwl-trans.h" -#include "iwl-trans-pcie-int.h" #include "iwl-csr.h" #include "iwl-prph.h" #include "iwl-eeprom.h" #include "iwl-agn-hw.h" +#include "internal.h" /* FIXME: need to abstract out TX command (once we know what it looks like) */ #include "iwl-commands.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c rename to drivers/net/wireless/iwlwifi/pcie/tx.c index 6f601cd05a94..0b8bbb0afcab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -36,7 +36,7 @@ #include "iwl-io.h" #include "iwl-agn-hw.h" #include "iwl-op-mode.h" -#include "iwl-trans-pcie-int.h" +#include "internal.h" /* FIXME: need to abstract out TX command (once we know what it looks like) */ #include "iwl-commands.h" -- GitLab From 20041ea622fcb1992df536d253de5120808e64a5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 21 May 2012 12:56:31 +0200 Subject: [PATCH 0713/6849] iwlwifi: trust mac80211 HT40 setting When mac80211 asks us to do HT40, it'll not do so on a channel that we marked as not having HT40+/- with IEEE80211_CHAN_NO_HT40PLUS (or MINUS). Thus, there's no need to verify it again in the driver. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 24 +--------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 36055ed1c069..01fbf06980c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -171,26 +171,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, return cmd.handler_status; } -static bool iwl_is_channel_extension(struct iwl_priv *priv, - enum ieee80211_band band, - u16 channel, u8 extension_chan_offset) -{ - const struct iwl_channel_info *ch_info; - - ch_info = iwl_get_channel_info(priv, band, channel); - if (!is_channel_valid(ch_info)) - return false; - - if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) - return !(ch_info->ht40_extension_channel & - IEEE80211_CHAN_NO_HT40PLUS); - else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) - return !(ch_info->ht40_extension_channel & - IEEE80211_CHAN_NO_HT40MINUS); - - return false; -} - bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_sta_ht_cap *ht_cap) @@ -210,9 +190,7 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, return false; #endif - return iwl_is_channel_extension(priv, priv->band, - le16_to_cpu(ctx->staging.channel), - ctx->ht.extension_chan_offset); + return true; } static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, -- GitLab From 1023fdc4858b6b8cb88ff28cafd425b77555be9f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 15 May 2012 12:16:34 +0200 Subject: [PATCH 0714/6849] iwlwifi: move DVM code into subdirectory Since we're working on another mode/driver inside iwlwifi, move the current one into a subdirectory to more cleanly separate the code. While at it, rename all the files. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 15 ++------------- drivers/net/wireless/iwlwifi/dvm/Makefile | 13 +++++++++++++ .../wireless/iwlwifi/{iwl-agn.h => dvm/agn.h} | 3 ++- .../iwlwifi/{iwl-agn-calib.c => dvm/calib.c} | 7 ++++--- .../iwlwifi/{iwl-agn-calib.h => dvm/calib.h} | 4 ++-- .../{iwl-commands.h => dvm/commands.h} | 4 ++-- .../iwlwifi/{iwl-debugfs.c => dvm/debugfs.c} | 8 ++------ .../wireless/iwlwifi/{iwl-dev.h => dvm/dev.h} | 19 ++++++++++--------- .../{iwl-agn-devices.c => dvm/devices.c} | 7 ++++--- .../iwlwifi/{iwl-eeprom.c => dvm/eeprom.c} | 10 ++++------ .../iwlwifi/{iwl-eeprom.h => dvm/eeprom.h} | 0 .../wireless/iwlwifi/{iwl-led.c => dvm/led.c} | 5 ++--- .../wireless/iwlwifi/{iwl-led.h => dvm/led.h} | 0 .../iwlwifi/{iwl-agn-lib.c => dvm/lib.c} | 5 +++-- .../{iwl-mac80211.c => dvm/mac80211.c} | 9 +++++---- .../iwlwifi/{iwl-agn.c => dvm/main.c} | 9 +++++---- .../iwlwifi/{iwl-power.c => dvm/power.c} | 12 +++++------- .../iwlwifi/{iwl-power.h => dvm/power.h} | 2 +- .../iwlwifi/{iwl-agn-rs.c => dvm/rs.c} | 6 ++---- .../iwlwifi/{iwl-agn-rs.h => dvm/rs.h} | 3 ++- .../iwlwifi/{iwl-agn-rx.c => dvm/rx.c} | 9 ++++----- .../iwlwifi/{iwl-agn-rxon.c => dvm/rxon.c} | 6 +++--- .../iwlwifi/{iwl-scan.c => dvm/scan.c} | 8 +++----- .../iwlwifi/{iwl-agn-sta.c => dvm/sta.c} | 5 ++--- .../{iwl-testmode.c => dvm/testmode.c} | 11 +++++------ .../{iwl-testmode.h => dvm/testmode.h} | 0 .../iwlwifi/{iwl-agn-tt.c => dvm/tt.c} | 14 ++++++-------- .../iwlwifi/{iwl-agn-tt.h => dvm/tt.h} | 2 +- .../iwlwifi/{iwl-agn-tx.c => dvm/tx.c} | 7 +++---- .../iwlwifi/{iwl-ucode.c => dvm/ucode.c} | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 1 + drivers/net/wireless/iwlwifi/pcie/2000.c | 2 +- drivers/net/wireless/iwlwifi/pcie/6000.c | 2 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 +-- drivers/net/wireless/iwlwifi/pcie/tx.c | 3 +-- 35 files changed, 106 insertions(+), 115 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/dvm/Makefile rename drivers/net/wireless/iwlwifi/{iwl-agn.h => dvm/agn.h} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-calib.c => dvm/calib.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-calib.h => dvm/calib.h} (98%) rename drivers/net/wireless/iwlwifi/{iwl-commands.h => dvm/commands.h} (99%) rename drivers/net/wireless/iwlwifi/{iwl-debugfs.c => dvm/debugfs.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-dev.h => dvm/dev.h} (98%) rename drivers/net/wireless/iwlwifi/{iwl-agn-devices.c => dvm/devices.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-eeprom.c => dvm/eeprom.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-eeprom.h => dvm/eeprom.h} (100%) rename drivers/net/wireless/iwlwifi/{iwl-led.c => dvm/led.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-led.h => dvm/led.h} (100%) rename drivers/net/wireless/iwlwifi/{iwl-agn-lib.c => dvm/lib.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-mac80211.c => dvm/mac80211.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn.c => dvm/main.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-power.c => dvm/power.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-power.h => dvm/power.h} (98%) rename drivers/net/wireless/iwlwifi/{iwl-agn-rs.c => dvm/rs.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-rs.h => dvm/rs.h} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-rx.c => dvm/rx.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-rxon.c => dvm/rxon.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-scan.c => dvm/scan.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-sta.c => dvm/sta.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-testmode.c => dvm/testmode.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-testmode.h => dvm/testmode.h} (100%) rename drivers/net/wireless/iwlwifi/{iwl-agn-tt.c => dvm/tt.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-tt.h => dvm/tt.h} (99%) rename drivers/net/wireless/iwlwifi/{iwl-agn-tx.c => dvm/tx.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-ucode.c => dvm/ucode.c} (99%) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index f155126e9a21..7ba6b8dc1cbd 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,19 +1,8 @@ -# DVM -obj-$(CONFIG_IWLDVM) += iwldvm.o -iwldvm-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o -iwldvm-objs += iwl-ucode.o iwl-agn-tx.o -iwldvm-objs += iwl-agn-lib.o iwl-agn-calib.o -iwldvm-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o -iwldvm-objs += iwl-eeprom.o iwl-power.o -iwldvm-objs += iwl-scan.o iwl-led.o -iwldvm-objs += iwl-agn-rxon.o iwl-agn-devices.o - -iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o -iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o +obj-$(CONFIG_IWLDVM) += dvm/ CFLAGS_iwl-devtrace.o := -I$(src) -# WIFI +# common obj-$(CONFIG_IWLWIFI) += iwlwifi.o iwlwifi-objs += iwl-io.o iwlwifi-objs += iwl-drv.o diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile new file mode 100644 index 000000000000..13f8282f4d0e --- /dev/null +++ b/drivers/net/wireless/iwlwifi/dvm/Makefile @@ -0,0 +1,13 @@ +# DVM +obj-$(CONFIG_IWLDVM) += iwldvm.o +iwldvm-objs += main.o rs.o mac80211.o ucode.o tx.o +iwldvm-objs += lib.o calib.o tt.o sta.o rx.o + +iwldvm-objs += eeprom.o power.o +iwldvm-objs += scan.o led.o +iwldvm-objs += rxon.o devices.o + +iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o +iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o + +ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn.h rename to drivers/net/wireless/iwlwifi/dvm/agn.h index 3f3607fd7dad..9a8dd1a579d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -63,9 +63,10 @@ #ifndef __iwl_agn_h__ #define __iwl_agn_h__ -#include "iwl-dev.h" #include "iwl-config.h" +#include "dev.h" + /* The first 11 queues (0-10) are used otherwise */ #define IWLAGN_FIRST_AMPDU_QUEUE 11 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-calib.c rename to drivers/net/wireless/iwlwifi/dvm/calib.c index 95f27f1a423b..7eb3fa3df7c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c @@ -63,10 +63,11 @@ #include #include -#include "iwl-dev.h" -#include "iwl-agn-calib.h" #include "iwl-trans.h" -#include "iwl-agn.h" + +#include "dev.h" +#include "calib.h" +#include "agn.h" /***************************************************************************** * INIT calibrations framework diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h similarity index 98% rename from drivers/net/wireless/iwlwifi/iwl-agn-calib.h rename to drivers/net/wireless/iwlwifi/dvm/calib.h index dbe13787f272..2349f393cc42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h @@ -62,8 +62,8 @@ #ifndef __iwl_calib_h__ #define __iwl_calib_h__ -#include "iwl-dev.h" -#include "iwl-commands.h" +#include "dev.h" +#include "commands.h" void iwl_chain_noise_calibration(struct iwl_priv *priv); void iwl_sensitivity_calibration(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-commands.h rename to drivers/net/wireless/iwlwifi/dvm/commands.h index b9f7361d2426..64811cd91635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -61,9 +61,9 @@ * *****************************************************************************/ /* - * Please use this file (iwl-commands.h) only for uCode API definitions. + * Please use this file (commands.h) only for uCode API definitions. * Please use iwl-xxxx-hw.h for hardware-related definitions. - * Please use iwl-dev.h for driver implementation definitions. + * Please use dev.h for driver implementation definitions. */ #ifndef __iwl_commands_h__ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-debugfs.c rename to drivers/net/wireless/iwlwifi/dvm/debugfs.c index e7c157e5ebeb..2268adddf4c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -30,16 +30,12 @@ #include #include #include - #include #include - - -#include "iwl-dev.h" #include "iwl-debug.h" #include "iwl-io.h" -#include "iwl-agn.h" -#include "iwl-modparams.h" +#include "dev.h" +#include "agn.h" /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h similarity index 98% rename from drivers/net/wireless/iwlwifi/iwl-dev.h rename to drivers/net/wireless/iwlwifi/dvm/dev.h index a4936a134162..2880a0a3da68 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -24,8 +24,8 @@ * *****************************************************************************/ /* - * Please use this file (iwl-dev.h) for driver implementation definitions. - * Please use iwl-commands.h for uCode API definitions. + * Please use this file (dev.h) for driver implementation definitions. + * Please use commands.h for uCode API definitions. */ #ifndef __iwl_dev_h__ @@ -39,17 +39,18 @@ #include #include "iwl-fw.h" -#include "iwl-eeprom.h" #include "iwl-csr.h" #include "iwl-debug.h" #include "iwl-agn-hw.h" -#include "iwl-led.h" -#include "iwl-power.h" -#include "iwl-agn-rs.h" -#include "iwl-agn-tt.h" -#include "iwl-trans.h" #include "iwl-op-mode.h" #include "iwl-notif-wait.h" +#include "iwl-trans.h" + +#include "eeprom.h" +#include "led.h" +#include "power.h" +#include "rs.h" +#include "tt.h" /* CT-KILL constants */ #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ @@ -664,7 +665,7 @@ struct iwl_lib_ops { /* device specific configuration */ void (*nic_config)(struct iwl_priv *priv); - /* eeprom operations (as defined in iwl-eeprom.h) */ + /* eeprom operations (as defined in eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; /* temperature */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-devices.c rename to drivers/net/wireless/iwlwifi/dvm/devices.c index 529cdac6f739..ac5675d86ec3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -27,12 +27,13 @@ /* * DVM device-specific data & functions */ -#include "iwl-agn.h" -#include "iwl-dev.h" -#include "iwl-commands.h" #include "iwl-io.h" #include "iwl-prph.h" +#include "agn.h" +#include "dev.h" +#include "commands.h" + /* * 1000 series * =========== diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/dvm/eeprom.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-eeprom.c rename to drivers/net/wireless/iwlwifi/dvm/eeprom.c index 50c58911e718..69d280f8db33 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/dvm/eeprom.c @@ -65,15 +65,13 @@ #include #include #include - #include - -#include "iwl-dev.h" -#include "iwl-debug.h" -#include "iwl-agn.h" -#include "iwl-eeprom.h" #include "iwl-io.h" #include "iwl-prph.h" +#include "iwl-debug.h" +#include "dev.h" +#include "agn.h" +#include "eeprom.h" /************************** EEPROM BANDS **************************** * diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/dvm/eeprom.h similarity index 100% rename from drivers/net/wireless/iwlwifi/iwl-eeprom.h rename to drivers/net/wireless/iwlwifi/dvm/eeprom.h diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/dvm/led.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-led.c rename to drivers/net/wireless/iwlwifi/dvm/led.c index 47000419f916..bf479f709091 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/dvm/led.c @@ -34,12 +34,11 @@ #include #include #include - -#include "iwl-dev.h" -#include "iwl-agn.h" #include "iwl-io.h" #include "iwl-trans.h" #include "iwl-modparams.h" +#include "dev.h" +#include "agn.h" /* Throughput OFF time(ms) ON time (ms) * >300 25 25 diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/dvm/led.h similarity index 100% rename from drivers/net/wireless/iwlwifi/iwl-led.h rename to drivers/net/wireless/iwlwifi/dvm/led.h diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-lib.c rename to drivers/net/wireless/iwlwifi/dvm/lib.c index c31072d42791..4ac9af7eb853 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -33,13 +33,14 @@ #include #include -#include "iwl-dev.h" #include "iwl-io.h" #include "iwl-agn-hw.h" -#include "iwl-agn.h" #include "iwl-trans.h" #include "iwl-modparams.h" +#include "dev.h" +#include "agn.h" + int iwlagn_hw_valid_rtc_data_addr(u32 addr) { return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) && diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-mac80211.c rename to drivers/net/wireless/iwlwifi/dvm/mac80211.c index 26a87c2b1653..33603c5a24a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -43,15 +43,16 @@ #include -#include "iwl-eeprom.h" -#include "iwl-dev.h" #include "iwl-io.h" -#include "iwl-agn-calib.h" -#include "iwl-agn.h" #include "iwl-trans.h" #include "iwl-op-mode.h" #include "iwl-modparams.h" +#include "eeprom.h" +#include "dev.h" +#include "calib.h" +#include "agn.h" + /***************************************************************************** * * mac80211 entry point functions diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/dvm/main.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn.c rename to drivers/net/wireless/iwlwifi/dvm/main.c index fa007176bad2..d67ae99c00b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -44,16 +44,17 @@ #include -#include "iwl-eeprom.h" -#include "iwl-dev.h" #include "iwl-io.h" -#include "iwl-agn-calib.h" -#include "iwl-agn.h" #include "iwl-trans.h" #include "iwl-op-mode.h" #include "iwl-drv.h" #include "iwl-modparams.h" +#include "eeprom.h" +#include "dev.h" +#include "calib.h" +#include "agn.h" + /****************************************************************************** * * module boiler plate diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/dvm/power.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-power.c rename to drivers/net/wireless/iwlwifi/dvm/power.c index 544ddf17f5bd..72c940759ac7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c @@ -31,18 +31,16 @@ #include #include #include - #include - -#include "iwl-eeprom.h" -#include "iwl-dev.h" -#include "iwl-agn.h" #include "iwl-io.h" -#include "iwl-commands.h" #include "iwl-debug.h" -#include "iwl-power.h" #include "iwl-trans.h" #include "iwl-modparams.h" +#include "eeprom.h" +#include "dev.h" +#include "agn.h" +#include "commands.h" +#include "power.h" /* * Setting power level allows the card to go to sleep when not busy. diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/dvm/power.h similarity index 98% rename from drivers/net/wireless/iwlwifi/iwl-power.h rename to drivers/net/wireless/iwlwifi/dvm/power.h index 21afc92efacb..a2cee7f04848 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/dvm/power.h @@ -28,7 +28,7 @@ #ifndef __iwl_power_setting_h__ #define __iwl_power_setting_h__ -#include "iwl-commands.h" +#include "commands.h" struct iwl_power_mgr { struct iwl_powertable_cmd sleep_cmd; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-rs.c rename to drivers/net/wireless/iwlwifi/dvm/rs.c index 8cebd7c363fc..af102910e689 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c @@ -35,10 +35,8 @@ #include -#include "iwl-dev.h" -#include "iwl-agn.h" -#include "iwl-op-mode.h" -#include "iwl-modparams.h" +#include "dev.h" +#include "agn.h" #define RS_NAME "iwl-agn-rs" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-rs.h rename to drivers/net/wireless/iwlwifi/dvm/rs.h index 82d02e1ae89f..ad3aea8f626a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/dvm/rs.h @@ -29,9 +29,10 @@ #include -#include "iwl-commands.h" #include "iwl-config.h" +#include "commands.h" + struct iwl_rate_info { u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-rx.c rename to drivers/net/wireless/iwlwifi/dvm/rx.c index 5035d2db14b1..d61980248408 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c @@ -32,12 +32,11 @@ #include #include #include -#include "iwl-eeprom.h" -#include "iwl-dev.h" #include "iwl-io.h" -#include "iwl-agn-calib.h" -#include "iwl-agn.h" -#include "iwl-modparams.h" +#include "eeprom.h" +#include "dev.h" +#include "calib.h" +#include "agn.h" #define IWL_CMD_ENTRY(x) [x] = #x diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-rxon.c rename to drivers/net/wireless/iwlwifi/dvm/rxon.c index 36b4965527c2..4f55689ac6a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -25,11 +25,11 @@ *****************************************************************************/ #include -#include "iwl-dev.h" -#include "iwl-agn.h" -#include "iwl-agn-calib.h" #include "iwl-trans.h" #include "iwl-modparams.h" +#include "dev.h" +#include "agn.h" +#include "calib.h" /* * initialize rxon structure with default values from eeprom diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-scan.c rename to drivers/net/wireless/iwlwifi/dvm/scan.c index a32b35ea9e60..7ee7f32b0fab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -30,11 +30,9 @@ #include #include -#include "iwl-eeprom.h" -#include "iwl-dev.h" -#include "iwl-io.h" -#include "iwl-agn.h" -#include "iwl-trans.h" +#include "eeprom.h" +#include "dev.h" +#include "agn.h" /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after * sending probe req. This should be set long enough to hear probe responses diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-sta.c rename to drivers/net/wireless/iwlwifi/dvm/sta.c index 01fbf06980c8..c6b343fdf5f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -28,10 +28,9 @@ *****************************************************************************/ #include #include - -#include "iwl-dev.h" -#include "iwl-agn.h" #include "iwl-trans.h" +#include "dev.h" +#include "agn.h" const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-testmode.c rename to drivers/net/wireless/iwlwifi/dvm/testmode.c index 060aac3e22f1..59cfe9a8eea5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c @@ -69,15 +69,14 @@ #include #include #include - -#include "iwl-dev.h" #include "iwl-debug.h" #include "iwl-io.h" -#include "iwl-agn.h" -#include "iwl-testmode.h" #include "iwl-trans.h" #include "iwl-fh.h" #include "iwl-prph.h" +#include "dev.h" +#include "agn.h" +#include "testmode.h" /* Periphery registers absolute lower bound. This is used in order to @@ -89,7 +88,7 @@ /* The TLVs used in the gnl message policy between the kernel module and * user space application. iwl_testmode_gnl_msg_policy is to be carried * through the NL80211_CMD_TESTMODE channel regulated by nl80211. - * See iwl-testmode.h + * See testmode.h */ static struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { @@ -129,7 +128,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { }; /* - * See the struct iwl_rx_packet in iwl-commands.h for the format of the + * See the struct iwl_rx_packet in commands.h for the format of the * received events from the device */ static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/dvm/testmode.h similarity index 100% rename from drivers/net/wireless/iwlwifi/iwl-testmode.h rename to drivers/net/wireless/iwlwifi/dvm/testmode.h diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-tt.c rename to drivers/net/wireless/iwlwifi/dvm/tt.c index a5cfe0aceedb..55418899bc4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c @@ -31,17 +31,15 @@ #include #include #include - #include - -#include "iwl-agn.h" -#include "iwl-eeprom.h" -#include "iwl-dev.h" #include "iwl-io.h" -#include "iwl-commands.h" -#include "iwl-debug.h" -#include "iwl-agn-tt.h" #include "iwl-modparams.h" +#include "iwl-debug.h" +#include "agn.h" +#include "eeprom.h" +#include "dev.h" +#include "commands.h" +#include "tt.h" /* default Thermal Throttling transaction table * Current state | Throttling Down | Throttling Up diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/dvm/tt.h similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-tt.h rename to drivers/net/wireless/iwlwifi/dvm/tt.h index 86bbf47501c1..44c7c8f30a2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/dvm/tt.h @@ -28,7 +28,7 @@ #ifndef __iwl_tt_setting_h__ #define __iwl_tt_setting_h__ -#include "iwl-commands.h" +#include "commands.h" #define IWL_ABSOLUTE_ZERO 0 #define IWL_ABSOLUTE_MAX 0xFFFFFFFF diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-agn-tx.c rename to drivers/net/wireless/iwlwifi/dvm/tx.c index ad1d36fa7642..52f2cae080c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -32,12 +32,11 @@ #include #include #include - -#include "iwl-dev.h" #include "iwl-io.h" -#include "iwl-agn-hw.h" -#include "iwl-agn.h" #include "iwl-trans.h" +#include "iwl-agn-hw.h" +#include "dev.h" +#include "agn.h" static const u8 tid_to_ac[] = { IEEE80211_AC_BE, diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-ucode.c rename to drivers/net/wireless/iwlwifi/dvm/ucode.c index d14e633bebc9..5a2e186c7ded 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -30,15 +30,16 @@ #include #include -#include "iwl-dev.h" #include "iwl-io.h" #include "iwl-agn-hw.h" -#include "iwl-agn.h" -#include "iwl-agn-calib.h" #include "iwl-trans.h" #include "iwl-fh.h" #include "iwl-op-mode.h" +#include "dev.h" +#include "agn.h" +#include "calib.h" + /****************************************************************************** * * uCode download functions diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 06203d6a1d86..65364793021f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -28,6 +28,7 @@ #define __IWLWIFI_DEVICE_TRACE #include +#include #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c index f6efa122336b..062c07b17056 100644 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c @@ -29,7 +29,7 @@ #include "iwl-config.h" #include "iwl-agn-hw.h" #include "cfg.h" -#include "iwl-commands.h" /* needed for BT for now */ +#include "dvm/commands.h" /* needed for BT for now */ /* Highest firmware API version supported */ #define IWL2030_UCODE_API_MAX 6 diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c index 7360cd9e0148..f9e396182ef3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c @@ -29,7 +29,7 @@ #include "iwl-config.h" #include "iwl-agn-hw.h" #include "cfg.h" -#include "iwl-commands.h" /* needed for BT for now */ +#include "dvm/commands.h" /* needed for BT for now */ /* Highest firmware API version supported */ #define IWL6000_UCODE_API_MAX 6 diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index e8a04a18a7d0..a19ce40c0092 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -72,11 +72,10 @@ #include "iwl-trans.h" #include "iwl-csr.h" #include "iwl-prph.h" -#include "iwl-eeprom.h" #include "iwl-agn-hw.h" #include "internal.h" /* FIXME: need to abstract out TX command (once we know what it looks like) */ -#include "iwl-commands.h" +#include "dvm/commands.h" #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ (((1<cfg->base_params->num_of_queues) - 1) &\ diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 0b8bbb0afcab..583451c710e3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -34,11 +34,10 @@ #include "iwl-csr.h" #include "iwl-prph.h" #include "iwl-io.h" -#include "iwl-agn-hw.h" #include "iwl-op-mode.h" #include "internal.h" /* FIXME: need to abstract out TX command (once we know what it looks like) */ -#include "iwl-commands.h" +#include "dvm/commands.h" #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 -- GitLab From 2587d36b1e121b84993e66dc8624c60793e25921 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 21 May 2012 20:18:19 +0200 Subject: [PATCH 0715/6849] iwlwifi: unify tx_chains_num setting There's no need to copy the same code for all devices since none of the 5000 series devices (that don't have the RX SISO override) don't set the rx_with_siso_diversity variable. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/devices.c | 34 ---------------------- drivers/net/wireless/iwlwifi/dvm/eeprom.c | 8 +++++ 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index ac5675d86ec3..7d3bb1e2d196 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -173,14 +173,6 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) { priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); - priv->hw_params.tx_chains_num = - num_of_ant(priv->hw_params.valid_tx_ant); - if (priv->cfg->rx_with_siso_diversity) - priv->hw_params.rx_chains_num = 1; - else - priv->hw_params.rx_chains_num = - num_of_ant(priv->hw_params.valid_rx_ant); - iwl1000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -254,14 +246,6 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) { priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); - priv->hw_params.tx_chains_num = - num_of_ant(priv->hw_params.valid_tx_ant); - if (priv->cfg->rx_with_siso_diversity) - priv->hw_params.rx_chains_num = 1; - else - priv->hw_params.rx_chains_num = - num_of_ant(priv->hw_params.valid_rx_ant); - iwl2000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -408,11 +392,6 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.tx_chains_num = - num_of_ant(priv->hw_params.valid_tx_ant); - priv->hw_params.rx_chains_num = - num_of_ant(priv->hw_params.valid_rx_ant); - iwl5000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -424,11 +403,6 @@ static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.tx_chains_num = - num_of_ant(priv->hw_params.valid_tx_ant); - priv->hw_params.rx_chains_num = - num_of_ant(priv->hw_params.valid_rx_ant); - iwl5150_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -623,14 +597,6 @@ static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.tx_chains_num = - num_of_ant(priv->hw_params.valid_tx_ant); - if (priv->cfg->rx_with_siso_diversity) - priv->hw_params.rx_chains_num = 1; - else - priv->hw_params.rx_chains_num = - num_of_ant(priv->hw_params.valid_rx_ant); - iwl6000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ diff --git a/drivers/net/wireless/iwlwifi/dvm/eeprom.c b/drivers/net/wireless/iwlwifi/dvm/eeprom.c index 69d280f8db33..b4da76d5d97e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/eeprom.c +++ b/drivers/net/wireless/iwlwifi/dvm/eeprom.c @@ -285,6 +285,14 @@ int iwl_eeprom_init_hw_params(struct iwl_priv *priv) return -EINVAL; } + priv->hw_params.tx_chains_num = + num_of_ant(priv->hw_params.valid_tx_ant); + if (priv->cfg->rx_with_siso_diversity) + priv->hw_params.rx_chains_num = 1; + else + priv->hw_params.rx_chains_num = + num_of_ant(priv->hw_params.valid_rx_ant); + IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant); -- GitLab From d370493f9be79530950dfab23b980ce60bc84f34 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 21 May 2012 20:03:01 +0200 Subject: [PATCH 0716/6849] iwlwifi: move ht40 bitmap into config There's no need to dynamically fill the HT40 band bitmap as it's a device parameter, just put it into the HT configuration. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/dev.h | 2 -- drivers/net/wireless/iwlwifi/dvm/devices.c | 13 ------------- drivers/net/wireless/iwlwifi/dvm/main.c | 9 ++++++--- drivers/net/wireless/iwlwifi/iwl-config.h | 5 ++++- drivers/net/wireless/iwlwifi/pcie/1000.c | 1 + drivers/net/wireless/iwlwifi/pcie/2000.c | 1 + drivers/net/wireless/iwlwifi/pcie/5000.c | 1 + drivers/net/wireless/iwlwifi/pcie/6000.c | 1 + 8 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 2880a0a3da68..af9de9542922 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -635,7 +635,6 @@ enum iwl_scan_type { * @rx_chains_num: Number of RX chains * @valid_tx_ant: usable antennas for TX * @valid_rx_ant: usable antennas for RX - * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) * @sku: sku read from EEPROM * @ct_kill_threshold: temperature threshold - in hw dependent unit * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit @@ -648,7 +647,6 @@ struct iwl_hw_params { u8 rx_chains_num; u8 valid_tx_ant; u8 valid_rx_ant; - u8 ht40_channel; bool use_rts_for_aggregation; u16 sku; u32 ct_kill_threshold; diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 7d3bb1e2d196..ddf053c5713d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -171,8 +171,6 @@ static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) { - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); - iwl1000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -244,8 +242,6 @@ static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) { - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); - iwl2000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -389,9 +385,6 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) { - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | - BIT(IEEE80211_BAND_5GHZ); - iwl5000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -400,9 +393,6 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) { - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | - BIT(IEEE80211_BAND_5GHZ); - iwl5150_set_ct_threshold(priv); /* Set initial sensitivity parameters */ @@ -594,9 +584,6 @@ static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) { - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | - BIT(IEEE80211_BAND_5GHZ); - iwl6000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index d67ae99c00b9..441188725985 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -1157,16 +1157,19 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, u8 tx_chains_num = priv->hw_params.tx_chains_num; ht_info->cap = 0; + ht_info->ht_supported = false; memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); + if (!priv->cfg->ht_params) + return; + ht_info->ht_supported = true; - if (priv->cfg->ht_params && - priv->cfg->ht_params->ht_greenfield_support) + if (priv->cfg->ht_params->ht_greenfield_support) ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; ht_info->cap |= IEEE80211_HT_CAP_SGI_20; max_bit_rate = MAX_BIT_RATE_20_MHZ; - if (priv->hw_params.ht40_channel & BIT(band)) { + if (priv->cfg->ht_params->ht40_bands & BIT(band)) { ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; ht_info->cap |= IEEE80211_HT_CAP_SGI_40; ht_info->mcs.rx_mask[4] = 0x01; diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index a52818bbfe98..af3a46126f01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -182,13 +182,16 @@ struct iwl_bt_params { bool bt_sco_disable; bool bt_session_2; }; + /* * @use_rts_for_aggregation: use rts/cts protection for HT traffic + * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 */ struct iwl_ht_params { + enum ieee80211_smps_mode smps_mode; const bool ht_greenfield_support; /* if used set to true */ bool use_rts_for_aggregation; - enum ieee80211_smps_mode smps_mode; + u8 ht40_bands; }; /** diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c index 0cfbf9fb74d5..174cf5e38962 100644 --- a/drivers/net/wireless/iwlwifi/pcie/1000.c +++ b/drivers/net/wireless/iwlwifi/pcie/1000.c @@ -71,6 +71,7 @@ static const struct iwl_base_params iwl1000_base_params = { static const struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ), }; #define IWL_DEVICE_1000 \ diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c index 062c07b17056..8d4d7295aa46 100644 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c @@ -104,6 +104,7 @@ static const struct iwl_base_params iwl2030_base_params = { static const struct iwl_ht_params iwl2000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ), }; static const struct iwl_bt_params iwl2030_bt_params = { diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c index 92e502e6e7e5..75d90a9c184a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/5000.c +++ b/drivers/net/wireless/iwlwifi/pcie/5000.c @@ -69,6 +69,7 @@ static const struct iwl_base_params iwl5000_base_params = { static const struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), }; #define IWL_DEVICE_5000 \ diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c index f9e396182ef3..7b9c02cc67e5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c @@ -124,6 +124,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { static const struct iwl_ht_params iwl6000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), }; static const struct iwl_bt_params iwl6000_bt_params = { -- GitLab From 588d932044169979bf028eab2155f9acd1d0418d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 28 May 2012 16:33:48 +0300 Subject: [PATCH 0717/6849] iwlwifi: SCD_INT_MSK is obsolete - don't update it The scheduler can issue an interrupt when moving the read pointer. To get this interrupt, the driver needs to configure what queue can issue an interrupt when its read pointer moves in the scheduler: this is the SCD_INT_MSK. The driver also needs to enable the interrupt in CSR_INT_MASK (bit CSR_INT_BIT_SCD). Since we don't enable the scheduler interrupt in CSR_INT_MASK, there is no point in requesting an interrupt from the scheduler: it will be masked anyway. So don't configure the scheduler to issue interrupts at all. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 --- drivers/net/wireless/iwlwifi/pcie/tx.c | 4 ---- 2 files changed, 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index a19ce40c0092..a267fda69f36 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1082,9 +1082,6 @@ static void iwl_tx_start(struct iwl_trans *trans) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); } - iwl_write_prph(trans, SCD_INTERRUPT_MASK, - IWL_MASK(0, trans->cfg->base_params->num_of_queues)); - /* Activate all Tx DMA/FIFO channels */ iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 583451c710e3..8a331a90f28e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -480,8 +480,6 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); - /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], fifo, true); @@ -506,8 +504,6 @@ void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int txq_id) trans_pcie->txq[txq_id].q.write_ptr = 0; iwl_trans_set_wr_ptrs(trans, txq_id, 0); - iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, BIT(txq_id)); - iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, false); } -- GitLab From fc248615314c41abc2d6957e095c418ea9b12412 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 28 May 2012 16:46:20 +0300 Subject: [PATCH 0718/6849] iwlwifi: first config the SCD queues, then activate them The DMA channels of the FH should be activated after the configuration of the SCD queues too. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index a267fda69f36..2d330158e7b9 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1030,6 +1030,10 @@ static void iwl_tx_start(struct iwl_trans *trans) spin_lock_irqsave(&trans_pcie->irq_lock, flags); + /* make sure all queue are not stopped/used */ + memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); + memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); + trans_pcie->scd_base_addr = iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; @@ -1050,17 +1054,6 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); - /* Enable DMA channel */ - for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) - iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); - - /* Update FH chicken bits */ - reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, - reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); iwl_write_prph(trans, SCD_AGGR_SEL, 0); @@ -1082,15 +1075,8 @@ static void iwl_tx_start(struct iwl_trans *trans) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); } - /* Activate all Tx DMA/FIFO channels */ - iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); - iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); - /* make sure all queue are not stopped/used */ - memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); - memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); - for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { int fifo = trans_pcie->setup_q_to_fifo[i]; @@ -1100,6 +1086,20 @@ static void iwl_tx_start(struct iwl_trans *trans) fifo, true); } + /* Activate all Tx DMA/FIFO channels */ + iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); + + /* Enable DMA channel */ + for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); + + /* Update FH chicken bits */ + reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); + iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, + reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* Enable L1-Active */ -- GitLab From 559b1a257ddeac637b8bb3a2c2469aaa2bde5383 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 28 May 2012 18:49:40 +0300 Subject: [PATCH 0719/6849] iwlwifi: use iwl_trans_set_wr_ptrs to init the queues This functions does the job so use it instead of duplicating the code. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 2d330158e7b9..0d0c7d8fea46 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1060,8 +1060,7 @@ static void iwl_tx_start(struct iwl_trans *trans) /* initiate the queues */ for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { - iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); - iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); + iwl_trans_set_wr_ptrs(trans, i, 0); iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i), 0); iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + @@ -1075,8 +1074,6 @@ static void iwl_tx_start(struct iwl_trans *trans) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); } - iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); - for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { int fifo = trans_pcie->setup_q_to_fifo[i]; -- GitLab From d0624be65ade709ef1a4220451a474be1ad01af9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 29 May 2012 13:07:30 +0300 Subject: [PATCH 0720/6849] iwlwifi: s/txq_agg_disable/txq_disable We need to be able to enable / disable Tx queues in HW dynamically. So this function is no longer related to AGG only. It can do the job for any queue, even AC ones. Change the name to better reflect its role. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/tx.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 ++++---- drivers/net/wireless/iwlwifi/pcie/internal.h | 2 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +- drivers/net/wireless/iwlwifi/pcie/tx.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 52f2cae080c3..494a25c2f8aa 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -599,7 +599,7 @@ turn_off: * time, or we hadn't time to drain the AC queues. */ if (agg_state == IWL_AGG_ON) - iwl_trans_tx_agg_disable(priv->trans, txq_id); + iwl_trans_txq_disable(priv->trans, txq_id); else IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", agg_state); @@ -755,8 +755,8 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) IWL_DEBUG_TX_QUEUES(priv, "Can continue DELBA flow ssn = next_recl =" " %d", tid_data->next_reclaimed); - iwl_trans_tx_agg_disable(priv->trans, - tid_data->agg.txq_id); + iwl_trans_txq_disable(priv->trans, + tid_data->agg.txq_id); iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); tid_data->agg.state = IWL_AGG_OFF; ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0aeeb7ce91c7..1fff285b6435 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -358,7 +358,7 @@ struct iwl_trans; * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is * ready and a successful ADDBA response has been received. * May sleep - * @tx_agg_disable: de-configure a Tx queue to send AMPDUs + * @txq_disable: de-configure a Tx queue to send AMPDUs * Must be atomic * @wait_tx_queue_empty: wait until all tx queues are empty * May sleep @@ -393,7 +393,7 @@ struct iwl_trans_ops { void (*tx_agg_setup)(struct iwl_trans *trans, int queue, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); - void (*tx_agg_disable)(struct iwl_trans *trans, int queue); + void (*txq_disable)(struct iwl_trans *trans, int queue); int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); int (*wait_tx_queue_empty)(struct iwl_trans *trans); @@ -543,12 +543,12 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, trans->ops->reclaim(trans, queue, ssn, skbs); } -static inline void iwl_trans_tx_agg_disable(struct iwl_trans *trans, int queue) +static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) { WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, "%s bad state = %d", __func__, trans->state); - trans->ops->tx_agg_disable(trans, queue); + trans->ops->txq_disable(trans, queue); } static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int queue, diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index f027769933d9..f802b5ac4a68 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -339,7 +339,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); -void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int queue); +void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, struct iwl_tx_queue *txq, diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 0d0c7d8fea46..7c7702a48399 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -2039,7 +2039,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { .tx = iwl_trans_pcie_tx, .reclaim = iwl_trans_pcie_reclaim, - .tx_agg_disable = iwl_trans_pcie_tx_agg_disable, + .txq_disable = iwl_trans_pcie_txq_disable, .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, .dbgfs_register = iwl_trans_pcie_dbgfs_register, diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8a331a90f28e..98ddc802213e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -487,7 +487,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } -void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int txq_id) +void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -- GitLab From 4beaf6c2f8af52902bcd55b51f9ff8c8f547d485 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 29 May 2012 11:29:10 +0300 Subject: [PATCH 0721/6849] iwlwifi: s/txq_setup/txq_enable We need to be able to enable / disable Tx queues in HW dynamically. So this function is no longer related to AGG only. It can do the job for any queue, even AC ones. Change the name to better reflect its role. Also use the new function to configure the AC / CMD queues in tx_start. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/dvm/tx.c | 5 +-- drivers/net/wireless/iwlwifi/iwl-trans.h | 14 +++---- drivers/net/wireless/iwlwifi/pcie/internal.h | 7 +++- drivers/net/wireless/iwlwifi/pcie/trans.c | 29 ++----------- drivers/net/wireless/iwlwifi/pcie/tx.c | 43 ++++++++++++++------ 6 files changed, 50 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 33603c5a24a8..32a823d7497f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -665,7 +665,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwl_sta_rx_agg_stop(priv, sta, tid); break; case IEEE80211_AMPDU_TX_START: - if (!priv->trans->ops->tx_agg_setup) + if (!priv->trans->ops->txq_enable) break; if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) break; diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 494a25c2f8aa..7fdbd175c551 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -688,9 +688,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; - iwl_trans_tx_agg_setup(priv->trans, q, fifo, - sta_priv->sta_id, tid, - buf_size, ssn); + iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid, + buf_size, ssn); /* * If the limit is 0, then it wasn't initialised yet, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 1fff285b6435..90ef0dc5f275 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -355,7 +355,7 @@ struct iwl_trans; * Must be atomic * @reclaim: free packet until ssn. Returns a list of freed packets. * Must be atomic - * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is + * @txq_enable: setup a tx queue for AMPDU - will be called once the HW is * ready and a successful ADDBA response has been received. * May sleep * @txq_disable: de-configure a Tx queue to send AMPDUs @@ -391,8 +391,8 @@ struct iwl_trans_ops { void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, struct sk_buff_head *skbs); - void (*tx_agg_setup)(struct iwl_trans *trans, int queue, int fifo, - int sta_id, int tid, int frame_limit, u16 ssn); + void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo, + int sta_id, int tid, int frame_limit, u16 ssn); void (*txq_disable)(struct iwl_trans *trans, int queue); int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); @@ -551,16 +551,16 @@ static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) trans->ops->txq_disable(trans, queue); } -static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int queue, - int fifo, int sta_id, int tid, - int frame_limit, u16 ssn) +static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, + int fifo, int sta_id, int tid, + int frame_limit, u16 ssn) { might_sleep(); WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, "%s bad state = %d", __func__, trans->state); - trans->ops->tx_agg_setup(trans, queue, fifo, sta_id, tid, + trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, frame_limit, ssn); } diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index f802b5ac4a68..94201c4d6227 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -344,8 +344,11 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, struct iwl_tx_queue *txq, int tx_fifo_id, bool active); -void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, - int sta_id, int tid, int frame_limit, u16 ssn); +void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, + int fifo, int sta_id, int tid, + int frame_limit, u16 ssn); +void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, + int sta_id, int tid, int frame_limit, u16 ssn); void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 7c7702a48399..0f59e1f2bcac 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1054,33 +1054,12 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); - iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, - SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); - iwl_write_prph(trans, SCD_AGGR_SEL, 0); - - /* initiate the queues */ - for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { - iwl_trans_set_wr_ptrs(trans, i, 0); - iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + - SCD_CONTEXT_QUEUE_OFFSET(i), 0); - iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + - SCD_CONTEXT_QUEUE_OFFSET(i) + - sizeof(u32), - ((SCD_WIN_SIZE << - SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & - SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | - ((SCD_FRAME_LIMIT << - SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & - SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - } - for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { int fifo = trans_pcie->setup_q_to_fifo[i]; - set_bit(i, trans_pcie->queue_used); - - iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[i], - fifo, true); + __iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, + IWL_TID_NON_QOS, + SCD_FRAME_LIMIT, 0); } /* Activate all Tx DMA/FIFO channels */ @@ -2040,7 +2019,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { .reclaim = iwl_trans_pcie_reclaim, .txq_disable = iwl_trans_pcie_txq_disable, - .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, + .txq_enable = iwl_trans_pcie_txq_enable, .dbgfs_register = iwl_trans_pcie_dbgfs_register, diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 98ddc802213e..35e82161ca43 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -442,29 +442,34 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); } -void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, - int sta_id, int tid, int frame_limit, u16 ssn) +void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, + int fifo, int sta_id, int tid, + int frame_limit, u16 ssn) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - unsigned long flags; - u16 ra_tid = BUILD_RAxTID(sta_id, tid); + + lockdep_assert_held(&trans_pcie->irq_lock); if (test_and_set_bit(txq_id, trans_pcie->queue_used)) WARN_ONCE(1, "queue %d already used - expect issues", txq_id); - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - /* Stop this Tx queue before configuring it */ iwlagn_tx_queue_stop_scheduler(trans, txq_id); - /* Map receiver-address / traffic-ID to this queue */ - iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); + /* Set this queue as a chain-building queue unless it is CMD queue */ + if (txq_id != trans_pcie->cmd_queue) + iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); + + /* If this queue is mapped to a certain station: it is an AGG queue */ + if (sta_id != IWL_INVALID_STATION) { + u16 ra_tid = BUILD_RAxTID(sta_id, tid); - /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); + /* Map receiver-address / traffic-ID to this queue */ + iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); - /* enable aggregations for the queue */ - iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); + /* enable aggregations for the queue */ + iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); + } /* Place first TFD at index corresponding to start sequence number. * Assumes that ssn_idx is valid (!= 0xFFF) */ @@ -473,6 +478,8 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, iwl_trans_set_wr_ptrs(trans, txq_id, ssn); /* Set up Tx window size and frame limit for this queue */ + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + + SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & @@ -483,6 +490,18 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], fifo, true); +} + +void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, + int sta_id, int tid, int frame_limit, u16 ssn) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + unsigned long flags; + + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + + __iwl_trans_pcie_txq_enable(trans, txq_id, fifo, sta_id, + tid, frame_limit, ssn); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } -- GitLab From cde5b48700bde6edc24c26d3d1bbec219e0ef2a1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 28 May 2012 16:55:34 +0300 Subject: [PATCH 0722/6849] iwlwifi: update mask value for SCD queue config Although we don't use bit 24, this bit is valid, but bit 23 is not. Update the mask accordingly. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-prph.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 3b1069290fa9..a9f0415916c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -187,7 +187,7 @@ #define SCD_QUEUE_STTS_REG_POS_ACTIVE (3) #define SCD_QUEUE_STTS_REG_POS_WSL (4) #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) -#define SCD_QUEUE_STTS_REG_MSK (0x00FF0000) +#define SCD_QUEUE_STTS_REG_MSK (0x017F0000) #define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) #define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) -- GitLab From 59c647b6266506cbbceadfabfd01168148f026c5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 24 May 2012 19:24:34 +0300 Subject: [PATCH 0723/6849] iwlwifi: allocate Tx cmd pool per device Different transports will have different needs: New tranports need headroom for their own use before the Tx cmd. So allocate the Tx cmd pool in the transport and give it a unique name based on dev_name. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/dev.h | 2 -- drivers/net/wireless/iwlwifi/dvm/main.c | 22 ++++------------- drivers/net/wireless/iwlwifi/dvm/tx.c | 12 +++++----- drivers/net/wireless/iwlwifi/iwl-trans.h | 29 +++++++++++++++++++++++ drivers/net/wireless/iwlwifi/pcie/trans.c | 19 +++++++++++++++ 5 files changed, 58 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index af9de9542922..c29e6378a11d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -1001,8 +1001,6 @@ struct iwl_priv { enum iwl_ucode_type cur_ucode; }; /*iwl_priv */ -extern struct kmem_cache *iwl_tx_cmd_pool; - static inline struct iwl_rxon_context * iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 441188725985..6cca1f403da3 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2290,10 +2290,11 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) { + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); struct ieee80211_tx_info *info; info = IEEE80211_SKB_CB(skb); - kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); + iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); dev_kfree_skb_any(skb); } @@ -2328,9 +2329,6 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { * driver and module entry point * *****************************************************************************/ - -struct kmem_cache *iwl_tx_cmd_pool; - static int __init iwl_init(void) { @@ -2338,29 +2336,18 @@ static int __init iwl_init(void) pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); pr_info(DRV_COPYRIGHT "\n"); - iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", - sizeof(struct iwl_device_cmd), - sizeof(void *), 0, NULL); - if (!iwl_tx_cmd_pool) - return -ENOMEM; - ret = iwlagn_rate_control_register(); if (ret) { pr_err("Unable to register rate control algorithm: %d\n", ret); - goto error_rc_register; + return ret; } ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops); if (ret) { pr_err("Unable to register op_mode: %d\n", ret); - goto error_opmode_register; + iwlagn_rate_control_unregister(); } - return ret; -error_opmode_register: - iwlagn_rate_control_unregister(); -error_rc_register: - kmem_cache_destroy(iwl_tx_cmd_pool); return ret; } module_init(iwl_init); @@ -2369,6 +2356,5 @@ static void __exit iwl_exit(void) { iwl_opmode_deregister("iwldvm"); iwlagn_rate_control_unregister(); - kmem_cache_destroy(iwl_tx_cmd_pool); } module_exit(iwl_exit); diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 7fdbd175c551..7e3bd6281551 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -295,7 +295,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_station_priv *sta_priv = NULL; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl_device_cmd *dev_cmd = NULL; + struct iwl_device_cmd *dev_cmd; struct iwl_tx_cmd *tx_cmd; __le16 fc; u8 hdr_len; @@ -377,7 +377,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_AMPDU) is_agg = true; - dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); + dev_cmd = iwl_trans_alloc_tx_cmd(priv->trans); if (unlikely(!dev_cmd)) goto drop_unlock_priv; @@ -492,7 +492,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) drop_unlock_sta: if (dev_cmd) - kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); + iwl_trans_free_tx_cmd(priv->trans, dev_cmd); spin_unlock(&priv->sta_lock); drop_unlock_priv: return -1; @@ -1193,8 +1193,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, info = IEEE80211_SKB_CB(skb); ctx = info->driver_data[0]; - kmem_cache_free(iwl_tx_cmd_pool, - (info->driver_data[1])); + iwl_trans_free_tx_cmd(priv->trans, + info->driver_data[1]); memset(&info->status, 0, sizeof(info->status)); @@ -1357,7 +1357,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, WARN_ON_ONCE(1); info = IEEE80211_SKB_CB(skb); - kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); + iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); if (freed == 1) { /* this is the first skb we deliver in this batch */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 90ef0dc5f275..00efde8e5536 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -433,6 +433,11 @@ enum iwl_trans_state { * @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 * @wait_command_queue: the wait_queue for SYNC host commands + * @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 + * device_cmd for Tx - for internal use only + * The user should use iwl_trans_{alloc,free}_tx_cmd. */ struct iwl_trans { const struct iwl_trans_ops *ops; @@ -450,6 +455,10 @@ struct iwl_trans { wait_queue_head_t wait_command_queue; + /* The following fields are internal only */ + struct kmem_cache *dev_cmd_pool; + size_t dev_cmd_headroom; + /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char trans_specific[0] __aligned(sizeof(void *)); @@ -525,6 +534,26 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, return trans->ops->send_cmd(trans, cmd); } +static inline struct iwl_device_cmd * +iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) +{ + u8 *dev_cmd_ptr = kmem_cache_alloc(trans->dev_cmd_pool, GFP_ATOMIC); + + if (unlikely(dev_cmd_ptr == NULL)) + return NULL; + + return (struct iwl_device_cmd *) + (dev_cmd_ptr + trans->dev_cmd_headroom); +} + +static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, + struct iwl_device_cmd *dev_cmd) +{ + u8 *dev_cmd_ptr = (u8 *)dev_cmd - trans->dev_cmd_headroom; + + kmem_cache_free(trans->dev_cmd_pool, dev_cmd_ptr); +} + static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, int queue) { diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 0f59e1f2bcac..1eabb834e32a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1528,6 +1528,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) iounmap(trans_pcie->hw_base); pci_release_regions(trans_pcie->pci_dev); pci_disable_device(trans_pcie->pci_dev); + kmem_cache_destroy(trans->dev_cmd_pool); kfree(trans); } @@ -2042,6 +2043,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, { struct iwl_trans_pcie *trans_pcie; struct iwl_trans *trans; + char cmd_pool_name[100]; u16 pci_cmd; int err; @@ -2138,8 +2140,25 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, init_waitqueue_head(&trans->wait_command_queue); spin_lock_init(&trans->reg_lock); + snprintf(cmd_pool_name, sizeof(cmd_pool_name), "iwl_cmd_pool:%s", + dev_name(trans->dev)); + + trans->dev_cmd_headroom = 0; + trans->dev_cmd_pool = + kmem_cache_create(cmd_pool_name, + sizeof(struct iwl_device_cmd) + + trans->dev_cmd_headroom, + sizeof(void *), + SLAB_HWCACHE_ALIGN, + NULL); + + if (!trans->dev_cmd_pool) + goto out_pci_disable_msi; + return trans; +out_pci_disable_msi: + pci_disable_msi(pdev); out_pci_release_regions: pci_release_regions(pdev); out_pci_disable_device: -- GitLab From 2baa2e57a9add3f6e5add31f28404ca7b8efecb4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 29 May 2012 14:47:30 +0200 Subject: [PATCH 0724/6849] iwlwifi: add iwl_set_bits_mask In a few cases we need to set a value in a certain mask inside a register, add the function iwl_set_bits_mask() to make such code easy. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-io.c | 18 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-io.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index ee93274214d6..5f2df70b73c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -65,6 +65,24 @@ void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) } EXPORT_SYMBOL_GPL(iwl_clear_bit); +void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value) +{ + unsigned long flags; + u32 v; + +#ifdef CONFIG_IWLWIFI_DEBUG + WARN_ON_ONCE(value & ~mask); +#endif + + spin_lock_irqsave(&trans->reg_lock, flags); + v = iwl_read32(trans, reg); + v &= ~mask; + v |= value; + iwl_write32(trans, reg, v); + spin_unlock_irqrestore(&trans->reg_lock, flags); +} +EXPORT_SYMBOL_GPL(iwl_set_bits_mask); + int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index abb3250164ba..4a9a45f771ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -54,6 +54,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); + int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout); int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, -- GitLab From 7b6a2be9e40c9ff7909fdf39d20ad78ba7822040 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 29 May 2012 17:30:43 +0300 Subject: [PATCH 0725/6849] iwlwifi: fix rf configuration Johannes noticed this was completely messed up. We got confused between masks and bit position. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/eeprom.c | 17 +++++++++++++---- drivers/net/wireless/iwlwifi/iwl-csr.h | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/eeprom.c b/drivers/net/wireless/iwlwifi/dvm/eeprom.c index b4da76d5d97e..b382b16b89d7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/eeprom.c +++ b/drivers/net/wireless/iwlwifi/dvm/eeprom.c @@ -1136,10 +1136,19 @@ void iwl_rf_config(struct iwl_priv *priv) /* write radio config values to register */ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + u32 reg_val = + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | + EEPROM_RF_CFG_DASH_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; + + iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | + CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | + CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); + IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", EEPROM_RF_CFG_TYPE_MSK(radio_cfg), EEPROM_RF_CFG_STEP_MSK(radio_cfg), diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 59750543fce7..41dc6911b164 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -155,9 +155,21 @@ #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) /* Bits for CSR_HW_IF_CONFIG_REG */ -#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) -#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) +#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003) +#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C) +#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0) +#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) +#define CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE (0x00000C00) +#define CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH (0x00003000) +#define CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP (0x0000C000) + +#define CSR_HW_IF_CONFIG_REG_POS_MAC_DASH (0) +#define CSR_HW_IF_CONFIG_REG_POS_MAC_STEP (2) +#define CSR_HW_IF_CONFIG_REG_POS_BOARD_VER (6) +#define CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE (10) +#define CSR_HW_IF_CONFIG_REG_POS_PHY_DASH (12) +#define CSR_HW_IF_CONFIG_REG_POS_PHY_STEP (14) #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) -- GitLab From 08838cdeca65e754af5c755a05f6cdb1c632eda8 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 29 May 2012 17:48:08 +0300 Subject: [PATCH 0726/6849] iwlwifi: configure the SKU in the HW This was missing. Fix the mask of the REV_TYPE on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/main.c | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-csr.h | 12 ++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 6cca1f403da3..10a2800687bc 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2218,6 +2218,15 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + /* SKU Control */ + iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | + CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP, + (CSR_HW_REV_STEP(priv->trans->hw_rev) << + CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) | + (CSR_HW_REV_DASH(priv->trans->hw_rev) << + CSR_HW_IF_CONFIG_REG_POS_MAC_DASH)); + priv->lib->nic_config(priv); } diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 41dc6911b164..34a5287dfc2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -97,13 +97,10 @@ /* * Hardware revision info * Bit fields: - * 31-8: Reserved - * 7-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions + * 31-16: Reserved + * 15-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D * 1-0: "Dash" (-) value, as in A-1, etc. - * - * NOTE: Revision step affects calculation of CCK txpower for 4965. - * NOTE: See also CSR_HW_REV_WA_REG (work-around for bug in 4965). */ #define CSR_HW_REV (CSR_BASE+0x028) @@ -282,7 +279,10 @@ /* HW REV */ -#define CSR_HW_REV_TYPE_MSK (0x00001F0) +#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) +#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) + +#define CSR_HW_REV_TYPE_MSK (0x000FFF0) #define CSR_HW_REV_TYPE_5300 (0x0000020) #define CSR_HW_REV_TYPE_5350 (0x0000030) #define CSR_HW_REV_TYPE_5100 (0x0000050) -- GitLab From 26a7ca9a71a3f7e1826de96b1a1e907123e11b07 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 21 May 2012 11:55:54 +0200 Subject: [PATCH 0727/6849] iwlwifi: refactor EEPROM reading/parsing The EEPROM reading/parsing code is all mixed in the driver today, and the EEPROM is parsed only when we access data from it. This is problematic because the NVM needs to be parsed and that is independent of reading it. Also, the NVM format for new devices will be different and probably require a new parser. Therefore refactor the reading and parsing and create two independent components. Reading the EEPROM requires direct hardware accesses and therefore access to the transport, but parsing is independent and can be done on an NVM blob. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/dvm/Makefile | 2 +- drivers/net/wireless/iwlwifi/dvm/agn.h | 5 +- drivers/net/wireless/iwlwifi/dvm/calib.c | 17 +- drivers/net/wireless/iwlwifi/dvm/debugfs.c | 23 +- drivers/net/wireless/iwlwifi/dvm/dev.h | 128 +- drivers/net/wireless/iwlwifi/dvm/devices.c | 128 +- drivers/net/wireless/iwlwifi/dvm/eeprom.c | 1163 ----------------- drivers/net/wireless/iwlwifi/dvm/eeprom.h | 269 ---- drivers/net/wireless/iwlwifi/dvm/lib.c | 8 +- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 9 +- drivers/net/wireless/iwlwifi/dvm/main.c | 301 +---- drivers/net/wireless/iwlwifi/dvm/power.c | 1 - drivers/net/wireless/iwlwifi/dvm/rs.c | 44 +- drivers/net/wireless/iwlwifi/dvm/rx.c | 1 - drivers/net/wireless/iwlwifi/dvm/rxon.c | 4 +- drivers/net/wireless/iwlwifi/dvm/scan.c | 10 +- drivers/net/wireless/iwlwifi/dvm/sta.c | 30 +- drivers/net/wireless/iwlwifi/dvm/testmode.c | 10 +- drivers/net/wireless/iwlwifi/dvm/tt.c | 1 - drivers/net/wireless/iwlwifi/dvm/tx.c | 10 +- drivers/net/wireless/iwlwifi/dvm/ucode.c | 25 +- drivers/net/wireless/iwlwifi/iwl-config.h | 19 + drivers/net/wireless/iwlwifi/iwl-debug.h | 5 +- .../net/wireless/iwlwifi/iwl-eeprom-parse.c | 900 +++++++++++++ .../net/wireless/iwlwifi/iwl-eeprom-parse.h | 138 ++ .../net/wireless/iwlwifi/iwl-eeprom-read.c | 463 +++++++ .../net/wireless/iwlwifi/iwl-eeprom-read.h | 70 + drivers/net/wireless/iwlwifi/pcie/1000.c | 14 + drivers/net/wireless/iwlwifi/pcie/2000.c | 17 + drivers/net/wireless/iwlwifi/pcie/5000.c | 15 + drivers/net/wireless/iwlwifi/pcie/6000.c | 19 + 32 files changed, 1854 insertions(+), 1996 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/dvm/eeprom.c delete mode 100644 drivers/net/wireless/iwlwifi/dvm/eeprom.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-eeprom-read.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-eeprom-read.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 7ba6b8dc1cbd..98c8f6449649 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -8,6 +8,7 @@ iwlwifi-objs += iwl-io.o iwlwifi-objs += iwl-drv.o iwlwifi-objs += iwl-debug.o iwlwifi-objs += iwl-notif-wait.o +iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile index 13f8282f4d0e..5ff76b204141 100644 --- a/drivers/net/wireless/iwlwifi/dvm/Makefile +++ b/drivers/net/wireless/iwlwifi/dvm/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_IWLDVM) += iwldvm.o iwldvm-objs += main.o rs.o mac80211.o ucode.o tx.o iwldvm-objs += lib.o calib.o tt.o sta.o rx.o -iwldvm-objs += eeprom.o power.o +iwldvm-objs += power.o iwldvm-objs += scan.o led.o iwldvm-objs += rxon.o devices.o diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 9a8dd1a579d0..2ae3608472a6 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -92,7 +92,6 @@ extern struct iwl_lib_ops iwl6030_lib; #define STATUS_CT_KILL 1 #define STATUS_ALIVE 2 #define STATUS_READY 3 -#define STATUS_GEO_CONFIGURED 4 #define STATUS_EXIT_PENDING 5 #define STATUS_STATISTICS 6 #define STATUS_SCANNING 7 @@ -443,10 +442,8 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, static inline int iwl_is_ready(struct iwl_priv *priv) { - /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are - * set but EXIT_PENDING is not */ + /* The adapter is 'ready' if READY EXIT_PENDING is not set */ return test_bit(STATUS_READY, &priv->status) && - test_bit(STATUS_GEO_CONFIGURED, &priv->status) && !test_bit(STATUS_EXIT_PENDING, &priv->status); } diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 7eb3fa3df7c4..f2dd671d7dc8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c @@ -833,14 +833,14 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * To be safe, simply mask out any chains that we know * are not on the device. */ - active_chains &= priv->hw_params.valid_rx_ant; + active_chains &= priv->eeprom_data->valid_rx_ant; num_tx_chains = 0; for (i = 0; i < NUM_RX_CHAINS; i++) { /* loops on all the bits of * priv->hw_setting.valid_tx_ant */ u8 ant_msk = (1 << i); - if (!(priv->hw_params.valid_tx_ant & ant_msk)) + if (!(priv->eeprom_data->valid_tx_ant & ant_msk)) continue; num_tx_chains++; @@ -854,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * connect the first valid tx chain */ first_chain = - find_first_chain(priv->hw_params.valid_tx_ant); + find_first_chain(priv->eeprom_data->valid_tx_ant); data->disconn_array[first_chain] = 0; active_chains |= BIT(first_chain); IWL_DEBUG_CALIB(priv, @@ -864,13 +864,13 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, } } - if (active_chains != priv->hw_params.valid_rx_ant && + if (active_chains != priv->eeprom_data->valid_rx_ant && active_chains != priv->chain_noise_data.active_chains) IWL_DEBUG_CALIB(priv, "Detected that not all antennas are connected! " "Connected: %#x, valid: %#x.\n", active_chains, - priv->hw_params.valid_rx_ant); + priv->eeprom_data->valid_rx_ant); /* Save for use within RXON, TX, SCAN commands, etc. */ data->active_chains = active_chains; @@ -1055,7 +1055,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) priv->cfg->bt_params->advanced_bt_coexist) { /* Disable disconnected antenna algorithm for advanced bt coex, assuming valid antennas are connected */ - data->active_chains = priv->hw_params.valid_rx_ant; + data->active_chains = priv->eeprom_data->valid_rx_ant; for (i = 0; i < NUM_RX_CHAINS; i++) if (!(data->active_chains & (1<disconn_array[i] = 1; @@ -1084,8 +1084,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", min_average_noise, min_average_noise_antenna_i); - iwlagn_gain_computation(priv, average_noise, - find_first_chain(priv->hw_params.valid_rx_ant)); + iwlagn_gain_computation( + priv, average_noise, + find_first_chain(priv->eeprom_data->valid_rx_ant)); /* Some power changes may have been made during the calibration. * Update and commit the RXON diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 2268adddf4c0..8a2d9e643b14 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -303,13 +303,13 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, const u8 *ptr; char *buf; u16 eeprom_ver; - size_t eeprom_len = priv->cfg->base_params->eeprom_size; + size_t eeprom_len = priv->eeprom_blob_size; buf_size = 4 * eeprom_len + 256; if (eeprom_len % 16) return -ENODATA; - ptr = priv->eeprom; + ptr = priv->eeprom_blob; if (!ptr) return -ENOMEM; @@ -318,11 +318,9 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, if (!buf) return -ENOMEM; - eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); - pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " - "version: 0x%x\n", - (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) - ? "OTP" : "EEPROM", eeprom_ver); + eeprom_ver = priv->eeprom_data->eeprom_version; + pos += scnprintf(buf + pos, buf_size - pos, + "NVM version: 0x%x\n", eeprom_ver); for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, @@ -347,9 +345,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, char *buf; ssize_t ret; - if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) - return -EAGAIN; - buf = kzalloc(bufsz, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -422,8 +417,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, test_bit(STATUS_ALIVE, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", test_bit(STATUS_READY, &priv->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", - test_bit(STATUS_GEO_CONFIGURED, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", test_bit(STATUS_EXIT_PENDING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", @@ -1337,17 +1330,17 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { pos += scnprintf(buf + pos, bufsz - pos, "tx power: (1/2 dB step)\n"); - if ((priv->hw_params.valid_tx_ant & ANT_A) && + if ((priv->eeprom_data->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna A:", tx->tx_power.ant_a); - if ((priv->hw_params.valid_tx_ant & ANT_B) && + if ((priv->eeprom_data->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna B:", tx->tx_power.ant_b); - if ((priv->hw_params.valid_tx_ant & ANT_C) && + if ((priv->eeprom_data->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna C:", diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index c29e6378a11d..89f2e1040e7f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -39,6 +39,7 @@ #include #include "iwl-fw.h" +#include "iwl-eeprom-parse.h" #include "iwl-csr.h" #include "iwl-debug.h" #include "iwl-agn-hw.h" @@ -46,7 +47,6 @@ #include "iwl-notif-wait.h" #include "iwl-trans.h" -#include "eeprom.h" #include "led.h" #include "power.h" #include "rs.h" @@ -88,33 +88,6 @@ #define IWL_NUM_SCAN_RATES (2) -/* - * One for each channel, holds all channel setup data - * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant - * with one another! - */ -struct iwl_channel_info { - struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ - struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for - * HT40 channel */ - - u8 channel; /* channel number */ - u8 flags; /* flags copied from EEPROM */ - s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ - s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) limit */ - s8 min_power; /* always 0 */ - s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ - - u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ - u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ - enum ieee80211_band band; - - /* HT40 channel info */ - s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ - u8 ht40_flags; /* flags copied from EEPROM */ - u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ -}; - /* * Minimum number of queues. MAX_NUM is defined in hw specific files. * Set the minimum to accommodate @@ -154,29 +127,6 @@ union iwl_ht_rate_supp { }; }; -#define CFG_HT_RX_AMPDU_FACTOR_8K (0x0) -#define CFG_HT_RX_AMPDU_FACTOR_16K (0x1) -#define CFG_HT_RX_AMPDU_FACTOR_32K (0x2) -#define CFG_HT_RX_AMPDU_FACTOR_64K (0x3) -#define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K -#define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K -#define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K - -/* - * Maximal MPDU density for TX aggregation - * 4 - 2us density - * 5 - 4us density - * 6 - 8us density - * 7 - 16us density - */ -#define CFG_HT_MPDU_DENSITY_2USEC (0x4) -#define CFG_HT_MPDU_DENSITY_4USEC (0x5) -#define CFG_HT_MPDU_DENSITY_8USEC (0x6) -#define CFG_HT_MPDU_DENSITY_16USEC (0x7) -#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC -#define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC -#define CFG_HT_MPDU_DENSITY_MIN (0x1) - struct iwl_ht_config { bool single_chain_sufficient; enum ieee80211_smps_mode smps; /* current smps mode */ @@ -446,23 +396,6 @@ enum { MEASUREMENT_ACTIVE = (1 << 1), }; -enum iwl_nvm_type { - NVM_DEVICE_TYPE_EEPROM = 0, - NVM_DEVICE_TYPE_OTP, -}; - -/* - * Two types of OTP memory access modes - * IWL_OTP_ACCESS_ABSOLUTE - absolute address mode, - * based on physical memory addressing - * IWL_OTP_ACCESS_RELATIVE - relative address mode, - * based on logical memory addressing - */ -enum iwl_access_mode { - IWL_OTP_ACCESS_ABSOLUTE, - IWL_OTP_ACCESS_RELATIVE, -}; - /* reply_tx_statistics (for _agn devices) */ struct reply_tx_error_statistics { u32 pp_delay; @@ -633,8 +566,6 @@ enum iwl_scan_type { * * @tx_chains_num: Number of TX chains * @rx_chains_num: Number of RX chains - * @valid_tx_ant: usable antennas for TX - * @valid_rx_ant: usable antennas for RX * @sku: sku read from EEPROM * @ct_kill_threshold: temperature threshold - in hw dependent unit * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit @@ -645,8 +576,6 @@ enum iwl_scan_type { struct iwl_hw_params { u8 tx_chains_num; u8 rx_chains_num; - u8 valid_tx_ant; - u8 valid_rx_ant; bool use_rts_for_aggregation; u16 sku; u32 ct_kill_threshold; @@ -663,9 +592,6 @@ struct iwl_lib_ops { /* device specific configuration */ void (*nic_config)(struct iwl_priv *priv); - /* eeprom operations (as defined in eeprom.h) */ - struct iwl_eeprom_ops eeprom_ops; - /* temperature */ void (*temperature)(struct iwl_priv *priv); }; @@ -734,8 +660,6 @@ struct iwl_priv { /* ieee device used by generic ieee processing code */ struct ieee80211_hw *hw; - struct ieee80211_channel *ieee_channels; - struct ieee80211_rate *ieee_rates; struct list_head calib_results; @@ -754,8 +678,6 @@ struct iwl_priv { struct iwl_notif_wait_data notif_wait; - struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; - /* spectrum measurement report caching */ struct iwl_spectrum_notification measure_report; u8 measurement_status; @@ -786,11 +708,6 @@ struct iwl_priv { bool ucode_loaded; bool init_ucode_run; /* Don't run init uCode again */ - /* we allocate array of iwl_channel_info for NIC's valid channels. - * Access via channel # using indirect index array */ - struct iwl_channel_info *channel_info; /* channel info array */ - u8 channel_count; /* # of channels */ - u8 plcp_delta_threshold; /* thermal calibration */ @@ -950,10 +867,8 @@ struct iwl_priv { struct delayed_work scan_check; - /* TX Power */ + /* TX Power settings */ s8 tx_power_user_lmt; - s8 tx_power_device_lmt; - s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */ s8 tx_power_next; #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -964,9 +879,10 @@ struct iwl_priv { void *wowlan_sram; #endif /* CONFIG_IWLWIFI_DEBUGFS */ - /* eeprom -- this is in the card's little endian byte order */ - u8 *eeprom; - enum iwl_nvm_type nvm_device_type; + struct iwl_eeprom_data *eeprom_data; + /* eeprom blob for debugfs/testmode */ + u8 *eeprom_blob; + size_t eeprom_blob_size; struct work_struct txpower_work; u32 calib_disabled; @@ -1034,36 +950,4 @@ static inline int iwl_is_any_associated(struct iwl_priv *priv) return false; } -static inline int is_channel_valid(const struct iwl_channel_info *ch_info) -{ - if (ch_info == NULL) - return 0; - return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; -} - -static inline int is_channel_radar(const struct iwl_channel_info *ch_info) -{ - return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; -} - -static inline u8 is_channel_a_band(const struct iwl_channel_info *ch_info) -{ - return ch_info->band == IEEE80211_BAND_5GHZ; -} - -static inline u8 is_channel_bg_band(const struct iwl_channel_info *ch_info) -{ - return ch_info->band == IEEE80211_BAND_2GHZ; -} - -static inline int is_channel_passive(const struct iwl_channel_info *ch) -{ - return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; -} - -static inline int is_channel_ibss(const struct iwl_channel_info *ch) -{ - return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; -} - #endif /* __iwl_dev_h__ */ diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index ddf053c5713d..747e576950f4 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -29,11 +29,48 @@ */ #include "iwl-io.h" #include "iwl-prph.h" +#include "iwl-eeprom-parse.h" #include "agn.h" #include "dev.h" #include "commands.h" + +#define EEPROM_RF_CONFIG_TYPE_MAX 0x3 + +static void iwl_rf_config(struct iwl_priv *priv) +{ + u16 radio_cfg = priv->eeprom_data->radio_cfg; + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { + u32 reg_val = + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | + EEPROM_RF_CFG_DASH_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; + + iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | + CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | + CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); + + IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", + EEPROM_RF_CFG_TYPE_MSK(radio_cfg), + EEPROM_RF_CFG_STEP_MSK(radio_cfg), + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + } else { + WARN_ON(1); + } + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); +} + /* * 1000 series * =========== @@ -180,17 +217,6 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) struct iwl_lib_ops iwl1000_lib = { .set_hw_params = iwl1000_hw_set_hw_params, .nic_config = iwl1000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - }, .temperature = iwlagn_temperature, }; @@ -251,36 +277,12 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) struct iwl_lib_ops iwl2000_lib = { .set_hw_params = iwl2000_hw_set_hw_params, .nic_config = iwl2000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .enhanced_txpower = true, - }, .temperature = iwlagn_temperature, }; struct iwl_lib_ops iwl2030_lib = { .set_hw_params = iwl2000_hw_set_hw_params, .nic_config = iwl2000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .enhanced_txpower = true, - }, .temperature = iwlagn_temperature, }; @@ -357,11 +359,9 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = { static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) { u16 temperature, voltage; - __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv, - EEPROM_KELVIN_TEMPERATURE); - temperature = le16_to_cpu(temp_calib[0]); - voltage = le16_to_cpu(temp_calib[1]); + temperature = le16_to_cpu(priv->eeprom_data->kelvin_temperature); + voltage = le16_to_cpu(priv->eeprom_data->kelvin_voltage); /* offset = temp - volt / coeff */ return (s32)(temperature - @@ -478,17 +478,6 @@ struct iwl_lib_ops iwl5000_lib = { .set_hw_params = iwl5000_hw_set_hw_params, .set_channel_switch = iwl5000_hw_channel_switch, .nic_config = iwl5000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - }, .temperature = iwlagn_temperature, }; @@ -496,17 +485,6 @@ struct iwl_lib_ops iwl5150_lib = { .set_hw_params = iwl5150_hw_set_hw_params, .set_channel_switch = iwl5000_hw_channel_switch, .nic_config = iwl5000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - }, .temperature = iwl5150_temperature, }; @@ -541,13 +519,13 @@ static void iwl6000_nic_config(struct iwl_priv *priv) break; case IWL_DEVICE_FAMILY_6050: /* Indicate calibration version to uCode. */ - if (iwl_eeprom_calib_version(priv) >= 6) + if (priv->eeprom_data->calib_version >= 6) iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); break; case IWL_DEVICE_FAMILY_6150: /* Indicate calibration version to uCode. */ - if (iwl_eeprom_calib_version(priv) >= 6) + if (priv->eeprom_data->calib_version >= 6) iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, @@ -658,18 +636,6 @@ struct iwl_lib_ops iwl6000_lib = { .set_hw_params = iwl6000_hw_set_hw_params, .set_channel_switch = iwl6000_hw_channel_switch, .nic_config = iwl6000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - .enhanced_txpower = true, - }, .temperature = iwlagn_temperature, }; @@ -677,17 +643,5 @@ struct iwl_lib_ops iwl6030_lib = { .set_hw_params = iwl6000_hw_set_hw_params, .set_channel_switch = iwl6000_hw_channel_switch, .nic_config = iwl6000_nic_config, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - .enhanced_txpower = true, - }, .temperature = iwlagn_temperature, }; diff --git a/drivers/net/wireless/iwlwifi/dvm/eeprom.c b/drivers/net/wireless/iwlwifi/dvm/eeprom.c deleted file mode 100644 index b382b16b89d7..000000000000 --- a/drivers/net/wireless/iwlwifi/dvm/eeprom.c +++ /dev/null @@ -1,1163 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - - -#include -#include -#include -#include -#include -#include "iwl-io.h" -#include "iwl-prph.h" -#include "iwl-debug.h" -#include "dev.h" -#include "agn.h" -#include "eeprom.h" - -/************************** EEPROM BANDS **************************** - * - * The iwl_eeprom_band definitions below provide the mapping from the - * EEPROM contents to the specific channel number supported for each - * band. - * - * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 - * definition below maps to physical channel 42 in the 5.2GHz spectrum. - * The specific geography and calibration information for that channel - * is contained in the eeprom map itself. - * - * During init, we copy the eeprom information and channel map - * information into priv->channel_info_24/52 and priv->channel_map_24/52 - * - * channel_map_24/52 provides the index in the channel_info array for a - * given channel. We have to have two separate maps as there is channel - * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and - * band_2 - * - * A value of 0xff stored in the channel_map indicates that the channel - * is not supported by the hardware at all. - * - * A value of 0xfe in the channel_map indicates that the channel is not - * valid for Tx with the current hardware. This means that - * while the system can tune and receive on a given channel, it may not - * be able to associate or transmit any frames on that - * channel. There is no corresponding channel information for that - * entry. - * - *********************************************************************/ - -/* 2.4 GHz */ -const u8 iwl_eeprom_band_1[14] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 -}; - -/* 5.2 GHz bands */ -static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ - 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 -}; - -static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ - 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 -}; - -static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ - 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 -}; - -static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ - 145, 149, 153, 157, 161, 165 -}; - -static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ - 1, 2, 3, 4, 5, 6, 7 -}; - -static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ - 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 -}; - -/****************************************************************************** - * - * generic NVM functions - * -******************************************************************************/ - -/* - * The device's EEPROM semaphore prevents conflicts between driver and uCode - * when accessing the EEPROM; each access is a series of pulses to/from the - * EEPROM chip, not a single event, so even reads could conflict if they - * weren't arbitrated by the semaphore. - */ - -#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ -#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ - -static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) -{ - u16 count; - int ret; - - for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { - /* Request semaphore */ - iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - - /* See if we got it */ - ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, - EEPROM_SEM_TIMEOUT); - if (ret >= 0) { - IWL_DEBUG_EEPROM(trans, - "Acquired semaphore after %d tries.\n", - count+1); - return ret; - } - } - - return ret; -} - -static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) -{ - iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - -} - -static int iwl_eeprom_verify_signature(struct iwl_priv *priv) -{ - u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP) & - CSR_EEPROM_GP_VALID_MSK; - int ret = 0; - - IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); - switch (gp) { - case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: - if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { - IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", - gp); - ret = -ENOENT; - } - break; - case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: - case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: - if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { - IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); - ret = -ENOENT; - } - break; - case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: - default: - IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " - "EEPROM_GP=0x%08x\n", - (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) - ? "OTP" : "EEPROM", gp); - ret = -ENOENT; - break; - } - return ret; -} - -u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset) -{ - if (!priv->eeprom) - return 0; - return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); -} - -int iwl_eeprom_check_version(struct iwl_priv *priv) -{ - u16 eeprom_ver; - u16 calib_ver; - - eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); - calib_ver = iwl_eeprom_calib_version(priv); - - if (eeprom_ver < priv->cfg->eeprom_ver || - calib_ver < priv->cfg->eeprom_calib_ver) - goto err; - - IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", - eeprom_ver, calib_ver); - - return 0; -err: - IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " - "CALIB=0x%x < 0x%x\n", - eeprom_ver, priv->cfg->eeprom_ver, - calib_ver, priv->cfg->eeprom_calib_ver); - return -EINVAL; - -} - -int iwl_eeprom_init_hw_params(struct iwl_priv *priv) -{ - u16 radio_cfg; - - priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); - if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && - !priv->cfg->ht_params) { - IWL_ERR(priv, "Invalid 11n configuration\n"); - return -EINVAL; - } - - if (!priv->hw_params.sku) { - IWL_ERR(priv, "Invalid device sku\n"); - return -EINVAL; - } - - IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - priv->hw_params.valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); - priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); - - /* check overrides (some devices have wrong EEPROM) */ - if (priv->cfg->valid_tx_ant) - priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; - if (priv->cfg->valid_rx_ant) - priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - - if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) { - IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", - priv->hw_params.valid_tx_ant, - priv->hw_params.valid_rx_ant); - return -EINVAL; - } - - priv->hw_params.tx_chains_num = - num_of_ant(priv->hw_params.valid_tx_ant); - if (priv->cfg->rx_with_siso_diversity) - priv->hw_params.rx_chains_num = 1; - else - priv->hw_params.rx_chains_num = - num_of_ant(priv->hw_params.valid_rx_ant); - - IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", - priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant); - - return 0; -} - -u16 iwl_eeprom_calib_version(struct iwl_priv *priv) -{ - struct iwl_eeprom_calib_hdr *hdr; - - hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, - EEPROM_CALIB_ALL); - return hdr->version; -} - -static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address) -{ - u16 offset = 0; - - if ((address & INDIRECT_ADDRESS) == 0) - return address; - - switch (address & INDIRECT_TYPE_MSK) { - case INDIRECT_HOST: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST); - break; - case INDIRECT_GENERAL: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL); - break; - case INDIRECT_REGULATORY: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); - break; - case INDIRECT_TXP_LIMIT: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); - break; - case INDIRECT_TXP_LIMIT_SIZE: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); - break; - case INDIRECT_CALIBRATION: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); - break; - case INDIRECT_PROCESS_ADJST: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST); - break; - case INDIRECT_OTHERS: - offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS); - break; - default: - IWL_ERR(priv, "illegal indirect type: 0x%X\n", - address & INDIRECT_TYPE_MSK); - break; - } - - /* translate the offset from words to byte */ - return (address & ADDRESS_MSK) + (offset << 1); -} - -const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset) -{ - u32 address = eeprom_indirect_address(priv, offset); - BUG_ON(address >= priv->cfg->base_params->eeprom_size); - return &priv->eeprom[address]; -} - -void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac) -{ - const u8 *addr = iwl_eeprom_query_addr(priv, - EEPROM_MAC_ADDRESS); - memcpy(mac, addr, ETH_ALEN); -} - -/****************************************************************************** - * - * OTP related functions - * -******************************************************************************/ - -static void iwl_set_otp_access(struct iwl_trans *trans, - enum iwl_access_mode mode) -{ - iwl_read32(trans, CSR_OTP_GP_REG); - - if (mode == IWL_OTP_ACCESS_ABSOLUTE) - iwl_clear_bit(trans, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_OTP_ACCESS_MODE); - else - iwl_set_bit(trans, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_OTP_ACCESS_MODE); -} - -static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev) -{ - u32 otpgp; - int nvm_type; - - /* OTP only valid for CP/PP and after */ - switch (hw_rev & CSR_HW_REV_TYPE_MSK) { - case CSR_HW_REV_TYPE_NONE: - IWL_ERR(trans, "Unknown hardware type\n"); - return -ENOENT; - case CSR_HW_REV_TYPE_5300: - case CSR_HW_REV_TYPE_5350: - case CSR_HW_REV_TYPE_5100: - case CSR_HW_REV_TYPE_5150: - nvm_type = NVM_DEVICE_TYPE_EEPROM; - break; - default: - otpgp = iwl_read32(trans, CSR_OTP_GP_REG); - if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) - nvm_type = NVM_DEVICE_TYPE_OTP; - else - nvm_type = NVM_DEVICE_TYPE_EEPROM; - break; - } - return nvm_type; -} - -static int iwl_init_otp_access(struct iwl_trans *trans) -{ - int ret; - - /* Enable 40MHz radio clock */ - iwl_write32(trans, CSR_GP_CNTRL, - iwl_read32(trans, CSR_GP_CNTRL) | - CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - - /* wait for clock to be ready */ - ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - 25000); - if (ret < 0) - IWL_ERR(trans, "Time out access OTP\n"); - else { - iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_RESET_REQ); - udelay(5); - iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_RESET_REQ); - - /* - * CSR auto clock gate disable bit - - * this is only applicable for HW with OTP shadow RAM - */ - if (trans->cfg->base_params->shadow_ram_support) - iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, - CSR_RESET_LINK_PWR_MGMT_DISABLED); - } - return ret; -} - -static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, - __le16 *eeprom_data) -{ - int ret = 0; - u32 r; - u32 otpgp; - - iwl_write32(trans, CSR_EEPROM_REG, - CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(trans, CSR_EEPROM_REG, - CSR_EEPROM_REG_READ_VALID_MSK, - CSR_EEPROM_REG_READ_VALID_MSK, - IWL_EEPROM_ACCESS_TIMEOUT); - if (ret < 0) { - IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); - return ret; - } - r = iwl_read32(trans, CSR_EEPROM_REG); - /* check for ECC errors: */ - otpgp = iwl_read32(trans, CSR_OTP_GP_REG); - if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { - /* stop in this case */ - /* set the uncorrectable OTP ECC bit for acknowledgement */ - iwl_set_bit(trans, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); - IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); - return -EINVAL; - } - if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { - /* continue in this case */ - /* set the correctable OTP ECC bit for acknowledgement */ - iwl_set_bit(trans, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); - IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); - } - *eeprom_data = cpu_to_le16(r >> 16); - return 0; -} - -/* - * iwl_is_otp_empty: check for empty OTP - */ -static bool iwl_is_otp_empty(struct iwl_trans *trans) -{ - u16 next_link_addr = 0; - __le16 link_value; - bool is_empty = false; - - /* locate the beginning of OTP link list */ - if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { - if (!link_value) { - IWL_ERR(trans, "OTP is empty\n"); - is_empty = true; - } - } else { - IWL_ERR(trans, "Unable to read first block of OTP list.\n"); - is_empty = true; - } - - return is_empty; -} - - -/* - * iwl_find_otp_image: find EEPROM image in OTP - * finding the OTP block that contains the EEPROM image. - * the last valid block on the link list (the block _before_ the last block) - * is the block we should read and used to configure the device. - * If all the available OTP blocks are full, the last block will be the block - * we should read and used to configure the device. - * only perform this operation if shadow RAM is disabled - */ -static int iwl_find_otp_image(struct iwl_trans *trans, - u16 *validblockaddr) -{ - u16 next_link_addr = 0, valid_addr; - __le16 link_value = 0; - int usedblocks = 0; - - /* set addressing mode to absolute to traverse the link list */ - iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE); - - /* checking for empty OTP or error */ - if (iwl_is_otp_empty(trans)) - return -EINVAL; - - /* - * start traverse link list - * until reach the max number of OTP blocks - * different devices have different number of OTP blocks - */ - do { - /* save current valid block address - * check for more block on the link list - */ - valid_addr = next_link_addr; - next_link_addr = le16_to_cpu(link_value) * sizeof(u16); - IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n", - usedblocks, next_link_addr); - if (iwl_read_otp_word(trans, next_link_addr, &link_value)) - return -EINVAL; - if (!link_value) { - /* - * reach the end of link list, return success and - * set address point to the starting address - * of the image - */ - *validblockaddr = valid_addr; - /* skip first 2 bytes (link list pointer) */ - *validblockaddr += 2; - return 0; - } - /* more in the link list, continue */ - usedblocks++; - } while (usedblocks <= trans->cfg->base_params->max_ll_items); - - /* OTP has no valid blocks */ - IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n"); - return -EINVAL; -} - -/****************************************************************************** - * - * Tx Power related functions - * -******************************************************************************/ -/** - * iwl_get_max_txpower_avg - get the highest tx power from all chains. - * find the highest tx power from all chains for the channel - */ -static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int element, s8 *max_txpower_in_half_dbm) -{ - s8 max_txpower_avg = 0; /* (dBm) */ - - /* Take the highest tx power from any valid chains */ - if ((cfg->valid_tx_ant & ANT_A) && - (enhanced_txpower[element].chain_a_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_a_max; - if ((cfg->valid_tx_ant & ANT_B) && - (enhanced_txpower[element].chain_b_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_b_max; - if ((cfg->valid_tx_ant & ANT_C) && - (enhanced_txpower[element].chain_c_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_c_max; - if (((cfg->valid_tx_ant == ANT_AB) | - (cfg->valid_tx_ant == ANT_BC) | - (cfg->valid_tx_ant == ANT_AC)) && - (enhanced_txpower[element].mimo2_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo2_max; - if ((cfg->valid_tx_ant == ANT_ABC) && - (enhanced_txpower[element].mimo3_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo3_max; - - /* - * max. tx power in EEPROM is in 1/2 dBm format - * convert from 1/2 dBm to dBm (round-up convert) - * but we also do not want to loss 1/2 dBm resolution which - * will impact performance - */ - *max_txpower_in_half_dbm = max_txpower_avg; - return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); -} - -static void -iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *txp, - s8 max_txpower_avg) -{ - int ch_idx; - bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; - enum ieee80211_band band; - - band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? - IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; - - for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { - struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; - - /* update matching channel or from common data only */ - if (txp->channel != 0 && ch_info->channel != txp->channel) - continue; - - /* update matching band only */ - if (band != ch_info->band) - continue; - - if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { - ch_info->max_power_avg = max_txpower_avg; - ch_info->curr_txpow = max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - - if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) - ch_info->ht40_max_power_avg = max_txpower_avg; - } -} - -#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) -#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) -#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) - -#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ - ? # x " " : "") - -static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) -{ - struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; - int idx, entries; - __le16 *txp_len; - s8 max_txp_avg, max_txp_avg_halfdbm; - - BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); - - /* the length is in 16-bit words, but we want entries */ - txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); - entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; - - txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); - - for (idx = 0; idx < entries; idx++) { - txp = &txp_array[idx]; - /* skip invalid entries */ - if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) - continue; - - IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", - (txp->channel && (txp->flags & - IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? - "Common " : (txp->channel) ? - "Channel" : "Common", - (txp->channel), - TXP_CHECK_AND_PRINT(VALID), - TXP_CHECK_AND_PRINT(BAND_52G), - TXP_CHECK_AND_PRINT(OFDM), - TXP_CHECK_AND_PRINT(40MHZ), - TXP_CHECK_AND_PRINT(HT_AP), - TXP_CHECK_AND_PRINT(RES1), - TXP_CHECK_AND_PRINT(RES2), - TXP_CHECK_AND_PRINT(COMMON_TYPE), - txp->flags); - IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x " - "chain_B: 0X%02x chain_C: 0X%02x\n", - txp->chain_a_max, txp->chain_b_max, - txp->chain_c_max); - IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x " - "MIMO3: 0x%02x High 20_on_40: 0x%02x " - "Low 20_on_40: 0x%02x\n", - txp->mimo2_max, txp->mimo3_max, - ((txp->delta_20_in_40 & 0xf0) >> 4), - (txp->delta_20_in_40 & 0x0f)); - - max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, - &max_txp_avg_halfdbm); - - /* - * Update the user limit values values to the highest - * power supported by any channel - */ - if (max_txp_avg > priv->tx_power_user_lmt) - priv->tx_power_user_lmt = max_txp_avg; - if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) - priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; - - iwl_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); - } -} - -/** - * iwl_eeprom_init - read EEPROM contents - * - * Load the EEPROM contents from adapter into priv->eeprom - * - * NOTE: This routine uses the non-debug IO access functions. - */ -int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) -{ - __le16 *e; - u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP); - int sz; - int ret; - u16 addr; - u16 validblockaddr = 0; - u16 cache_addr = 0; - - priv->nvm_device_type = iwl_get_nvm_type(priv->trans, hw_rev); - if (priv->nvm_device_type == -ENOENT) - return -ENOENT; - /* allocate eeprom */ - sz = priv->cfg->base_params->eeprom_size; - IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); - priv->eeprom = kzalloc(sz, GFP_KERNEL); - if (!priv->eeprom) { - ret = -ENOMEM; - goto alloc_err; - } - e = (__le16 *)priv->eeprom; - - ret = iwl_eeprom_verify_signature(priv); - if (ret < 0) { - IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); - ret = -ENOENT; - goto err; - } - - /* Make sure driver (instead of uCode) is allowed to read EEPROM */ - ret = iwl_eeprom_acquire_semaphore(priv->trans); - if (ret < 0) { - IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); - ret = -ENOENT; - goto err; - } - - if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { - - ret = iwl_init_otp_access(priv->trans); - if (ret) { - IWL_ERR(priv, "Failed to initialize OTP access.\n"); - ret = -ENOENT; - goto done; - } - iwl_write32(priv->trans, CSR_EEPROM_GP, - iwl_read32(priv->trans, CSR_EEPROM_GP) & - ~CSR_EEPROM_GP_IF_OWNER_MSK); - - iwl_set_bit(priv->trans, CSR_OTP_GP_REG, - CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | - CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); - /* traversing the linked list if no shadow ram supported */ - if (!priv->cfg->base_params->shadow_ram_support) { - if (iwl_find_otp_image(priv->trans, &validblockaddr)) { - ret = -ENOENT; - goto done; - } - } - for (addr = validblockaddr; addr < validblockaddr + sz; - addr += sizeof(u16)) { - __le16 eeprom_data; - - ret = iwl_read_otp_word(priv->trans, addr, - &eeprom_data); - if (ret) - goto done; - e[cache_addr / 2] = eeprom_data; - cache_addr += sizeof(u16); - } - } else { - /* eeprom is an array of 16bit values */ - for (addr = 0; addr < sz; addr += sizeof(u16)) { - u32 r; - - iwl_write32(priv->trans, CSR_EEPROM_REG, - CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - - ret = iwl_poll_bit(priv->trans, CSR_EEPROM_REG, - CSR_EEPROM_REG_READ_VALID_MSK, - CSR_EEPROM_REG_READ_VALID_MSK, - IWL_EEPROM_ACCESS_TIMEOUT); - if (ret < 0) { - IWL_ERR(priv, - "Time out reading EEPROM[%d]\n", addr); - goto done; - } - r = iwl_read32(priv->trans, CSR_EEPROM_REG); - e[addr / 2] = cpu_to_le16(r >> 16); - } - } - - IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", - (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) - ? "OTP" : "EEPROM", - iwl_eeprom_query16(priv, EEPROM_VERSION)); - - ret = 0; -done: - iwl_eeprom_release_semaphore(priv->trans); - -err: - if (ret) - iwl_eeprom_free(priv); -alloc_err: - return ret; -} - -void iwl_eeprom_free(struct iwl_priv *priv) -{ - kfree(priv->eeprom); - priv->eeprom = NULL; -} - -static void iwl_init_band_reference(struct iwl_priv *priv, - int eep_band, int *eeprom_ch_count, - const struct iwl_eeprom_channel **eeprom_ch_info, - const u8 **eeprom_ch_index) -{ - u32 offset = priv->lib-> - eeprom_ops.regulatory_bands[eep_band - 1]; - switch (eep_band) { - case 1: /* 2.4GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_1; - break; - case 2: /* 4.9GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_2; - break; - case 3: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_3; - break; - case 4: /* 5.5GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_4; - break; - case 5: /* 5.7GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_5; - break; - case 6: /* 2.4GHz ht40 channels */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_6; - break; - case 7: /* 5 GHz ht40 channels */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); - *eeprom_ch_info = (struct iwl_eeprom_channel *) - iwl_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_7; - break; - default: - BUG(); - return; - } -} - -#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ - ? # x " " : "") -/** - * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. - * - * Does not set up a command, or touch hardware. - */ -static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, - enum ieee80211_band band, u16 channel, - const struct iwl_eeprom_channel *eeprom_ch, - u8 clear_ht40_extension_channel) -{ - struct iwl_channel_info *ch_info; - - ch_info = (struct iwl_channel_info *) - iwl_get_channel_info(priv, band, channel); - - if (!is_channel_valid(ch_info)) - return -1; - - IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" - " Ad-Hoc %ssupported\n", - ch_info->channel, - is_channel_a_band(ch_info) ? - "5.2" : "2.4", - CHECK_AND_PRINT(IBSS), - CHECK_AND_PRINT(ACTIVE), - CHECK_AND_PRINT(RADAR), - CHECK_AND_PRINT(WIDE), - CHECK_AND_PRINT(DFS), - eeprom_ch->flags, - eeprom_ch->max_power_avg, - ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) - && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? - "" : "not "); - - ch_info->ht40_eeprom = *eeprom_ch; - ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; - ch_info->ht40_flags = eeprom_ch->flags; - if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) - ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; - - return 0; -} - -#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ - ? # x " " : "") - -/** - * iwl_init_channel_map - Set up driver's info for all possible channels - */ -int iwl_init_channel_map(struct iwl_priv *priv) -{ - int eeprom_ch_count = 0; - const u8 *eeprom_ch_index = NULL; - const struct iwl_eeprom_channel *eeprom_ch_info = NULL; - int band, ch; - struct iwl_channel_info *ch_info; - - if (priv->channel_count) { - IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n"); - return 0; - } - - IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n"); - - priv->channel_count = - ARRAY_SIZE(iwl_eeprom_band_1) + - ARRAY_SIZE(iwl_eeprom_band_2) + - ARRAY_SIZE(iwl_eeprom_band_3) + - ARRAY_SIZE(iwl_eeprom_band_4) + - ARRAY_SIZE(iwl_eeprom_band_5); - - IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n", - priv->channel_count); - - priv->channel_info = kcalloc(priv->channel_count, - sizeof(struct iwl_channel_info), - GFP_KERNEL); - if (!priv->channel_info) { - IWL_ERR(priv, "Could not allocate channel_info\n"); - priv->channel_count = 0; - return -ENOMEM; - } - - ch_info = priv->channel_info; - - /* Loop through the 5 EEPROM bands adding them in order to the - * channel map we maintain (that contains additional information than - * what just in the EEPROM) */ - for (band = 1; band <= 5; band++) { - - iwl_init_band_reference(priv, band, &eeprom_ch_count, - &eeprom_ch_info, &eeprom_ch_index); - - /* Loop through each band adding each of the channels */ - for (ch = 0; ch < eeprom_ch_count; ch++) { - ch_info->channel = eeprom_ch_index[ch]; - ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : - IEEE80211_BAND_5GHZ; - - /* permanently store EEPROM's channel regulatory flags - * and max power in channel info database. */ - ch_info->eeprom = eeprom_ch_info[ch]; - - /* Copy the run-time flags so they are there even on - * invalid channels */ - ch_info->flags = eeprom_ch_info[ch].flags; - /* First write that ht40 is not enabled, and then enable - * one by one */ - ch_info->ht40_extension_channel = - IEEE80211_CHAN_NO_HT40; - - if (!(is_channel_valid(ch_info))) { - IWL_DEBUG_EEPROM(priv, - "Ch. %d Flags %x [%sGHz] - " - "No traffic\n", - ch_info->channel, - ch_info->flags, - is_channel_a_band(ch_info) ? - "5.2" : "2.4"); - ch_info++; - continue; - } - - /* Initialize regulatory-based run-time data */ - ch_info->max_power_avg = ch_info->curr_txpow = - eeprom_ch_info[ch].max_power_avg; - ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; - ch_info->min_power = 0; - - IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] " - "%s%s%s%s%s%s(0x%02x %ddBm):" - " Ad-Hoc %ssupported\n", - ch_info->channel, - is_channel_a_band(ch_info) ? - "5.2" : "2.4", - CHECK_AND_PRINT_I(VALID), - CHECK_AND_PRINT_I(IBSS), - CHECK_AND_PRINT_I(ACTIVE), - CHECK_AND_PRINT_I(RADAR), - CHECK_AND_PRINT_I(WIDE), - CHECK_AND_PRINT_I(DFS), - eeprom_ch_info[ch].flags, - eeprom_ch_info[ch].max_power_avg, - ((eeprom_ch_info[ch]. - flags & EEPROM_CHANNEL_IBSS) - && !(eeprom_ch_info[ch]. - flags & EEPROM_CHANNEL_RADAR)) - ? "" : "not "); - - ch_info++; - } - } - - /* Check if we do have HT40 channels */ - if (priv->lib->eeprom_ops.regulatory_bands[5] == - EEPROM_REGULATORY_BAND_NO_HT40 && - priv->lib->eeprom_ops.regulatory_bands[6] == - EEPROM_REGULATORY_BAND_NO_HT40) - return 0; - - /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ - for (band = 6; band <= 7; band++) { - enum ieee80211_band ieeeband; - - iwl_init_band_reference(priv, band, &eeprom_ch_count, - &eeprom_ch_info, &eeprom_ch_index); - - /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ - ieeeband = - (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - - /* Loop through each band adding each of the channels */ - for (ch = 0; ch < eeprom_ch_count; ch++) { - /* Set up driver's info for lower half */ - iwl_mod_ht40_chan_info(priv, ieeeband, - eeprom_ch_index[ch], - &eeprom_ch_info[ch], - IEEE80211_CHAN_NO_HT40PLUS); - - /* Set up driver's info for upper half */ - iwl_mod_ht40_chan_info(priv, ieeeband, - eeprom_ch_index[ch] + 4, - &eeprom_ch_info[ch], - IEEE80211_CHAN_NO_HT40MINUS); - } - } - - /* for newer device (6000 series and up) - * EEPROM contain enhanced tx power information - * driver need to process addition information - * to determine the max channel tx power limits - */ - if (priv->lib->eeprom_ops.enhanced_txpower) - iwl_eeprom_enhanced_txpower(priv); - - return 0; -} - -/* - * iwl_free_channel_map - undo allocations in iwl_init_channel_map - */ -void iwl_free_channel_map(struct iwl_priv *priv) -{ - kfree(priv->channel_info); - priv->channel_count = 0; -} - -/** - * iwl_get_channel_info - Find driver's private channel info - * - * Based on band and channel number. - */ -const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, - enum ieee80211_band band, u16 channel) -{ - int i; - - switch (band) { - case IEEE80211_BAND_5GHZ: - for (i = 14; i < priv->channel_count; i++) { - if (priv->channel_info[i].channel == channel) - return &priv->channel_info[i]; - } - break; - case IEEE80211_BAND_2GHZ: - if (channel >= 1 && channel <= 14) - return &priv->channel_info[channel - 1]; - break; - default: - BUG(); - } - - return NULL; -} - -void iwl_rf_config(struct iwl_priv *priv) -{ - u16 radio_cfg; - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - u32 reg_val = - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << - CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) << - CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | - EEPROM_RF_CFG_DASH_MSK(radio_cfg) << - CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; - - iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | - CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | - CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); - - IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", - EEPROM_RF_CFG_TYPE_MSK(radio_cfg), - EEPROM_RF_CFG_STEP_MSK(radio_cfg), - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - } else - WARN_ON(1); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); -} diff --git a/drivers/net/wireless/iwlwifi/dvm/eeprom.h b/drivers/net/wireless/iwlwifi/dvm/eeprom.h deleted file mode 100644 index 64bfd947caeb..000000000000 --- a/drivers/net/wireless/iwlwifi/dvm/eeprom.h +++ /dev/null @@ -1,269 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -#ifndef __iwl_eeprom_h__ -#define __iwl_eeprom_h__ - -#include - -struct iwl_priv; - -/* - * EEPROM access time values: - * - * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. - * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). - * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. - * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. - */ -#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ - -#define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ -#define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ - - -/* - * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags. - * - * IBSS and/or AP operation is allowed *only* on those channels with - * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because - * RADAR detection is not supported by the 4965 driver, but is a - * requirement for establishing a new network for legal operation on channels - * requiring RADAR detection or restricting ACTIVE scanning. - * - * NOTE: "WIDE" flag does not indicate anything about "HT40" 40 MHz channels. - * It only indicates that 20 MHz channel use is supported; HT40 channel - * usage is indicated by a separate set of regulatory flags for each - * HT40 channel pair. - * - * NOTE: Using a channel inappropriately will result in a uCode error! - */ -#define IWL_NUM_TX_CALIB_GROUPS 5 -enum { - EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ - EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ - /* Bit 2 Reserved */ - EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ - EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ - EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ - /* Bit 6 Reserved (was Narrow Channel) */ - EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ -}; - -/* SKU Capabilities */ -#define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) -#define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) -#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) -#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) -#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) - -/* *regulatory* channel data format in eeprom, one for each channel. - * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ -struct iwl_eeprom_channel { - u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */ - s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ -} __packed; - -enum iwl_eeprom_enhanced_txpwr_flags { - IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), - IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), - IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), - IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), - IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), - IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), - IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), - IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), -}; - -/** - * iwl_eeprom_enhanced_txpwr structure - * This structure presents the enhanced regulatory tx power limit layout - * in eeprom image - * Enhanced regulatory tx power portion of eeprom image can be broken down - * into individual structures; each one is 8 bytes in size and contain the - * following information - * @flags: entry flags - * @channel: channel number - * @chain_a_max_pwr: chain a max power in 1/2 dBm - * @chain_b_max_pwr: chain b max power in 1/2 dBm - * @chain_c_max_pwr: chain c max power in 1/2 dBm - * @delta_20_in_40: 20-in-40 deltas (hi/lo) - * @mimo2_max_pwr: mimo2 max power in 1/2 dBm - * @mimo3_max_pwr: mimo3 max power in 1/2 dBm - * - */ -struct iwl_eeprom_enhanced_txpwr { - u8 flags; - u8 channel; - s8 chain_a_max; - s8 chain_b_max; - s8 chain_c_max; - u8 delta_20_in_40; - s8 mimo2_max; - s8 mimo3_max; -} __packed; - -/* calibration */ -struct iwl_eeprom_calib_hdr { - u8 version; - u8 pa_type; - __le16 voltage; -} __packed; - -#define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) -#define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) - -/* temperature */ -#define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) -#define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) - - -/* agn links */ -#define EEPROM_LINK_HOST (2*0x64) -#define EEPROM_LINK_GENERAL (2*0x65) -#define EEPROM_LINK_REGULATORY (2*0x66) -#define EEPROM_LINK_CALIBRATION (2*0x67) -#define EEPROM_LINK_PROCESS_ADJST (2*0x68) -#define EEPROM_LINK_OTHERS (2*0x69) -#define EEPROM_LINK_TXP_LIMIT (2*0x6a) -#define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) - -/* agn regulatory - indirect access */ -#define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */ -#define EEPROM_REG_BAND_2_CHANNELS ((0x26)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */ -#define EEPROM_REG_BAND_3_CHANNELS ((0x42)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ -#define EEPROM_REG_BAND_4_CHANNELS ((0x5C)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ -#define EEPROM_REG_BAND_5_CHANNELS ((0x74)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */ -#define EEPROM_REG_BAND_24_HT40_CHANNELS ((0x82)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ -#define EEPROM_REG_BAND_52_HT40_CHANNELS ((0x92)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ - -/* 6000 regulatory - indirect access */ -#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ - | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ -/* 2.4 GHz */ -extern const u8 iwl_eeprom_band_1[14]; - -#define ADDRESS_MSK 0x0000FFFF -#define INDIRECT_TYPE_MSK 0x000F0000 -#define INDIRECT_HOST 0x00010000 -#define INDIRECT_GENERAL 0x00020000 -#define INDIRECT_REGULATORY 0x00030000 -#define INDIRECT_CALIBRATION 0x00040000 -#define INDIRECT_PROCESS_ADJST 0x00050000 -#define INDIRECT_OTHERS 0x00060000 -#define INDIRECT_TXP_LIMIT 0x00070000 -#define INDIRECT_TXP_LIMIT_SIZE 0x00080000 -#define INDIRECT_ADDRESS 0x00100000 - -/* General */ -#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ -#define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ -#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ -#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ -#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ -#define EEPROM_VERSION (2*0x44) /* 2 bytes */ -#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ -#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ -#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ -#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ - -/* The following masks are to be applied on EEPROM_RADIO_CONFIG */ -#define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ -#define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ -#define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ -#define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ -#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ -#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ - -#define EEPROM_RF_CONFIG_TYPE_MAX 0x3 - -#define EEPROM_REGULATORY_BAND_NO_HT40 (0) - -struct iwl_eeprom_ops { - const u32 regulatory_bands[7]; - bool enhanced_txpower; -}; - - -int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); -void iwl_eeprom_free(struct iwl_priv *priv); -int iwl_eeprom_check_version(struct iwl_priv *priv); -int iwl_eeprom_init_hw_params(struct iwl_priv *priv); -u16 iwl_eeprom_calib_version(struct iwl_priv *priv); -const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset); -u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset); -void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac); -int iwl_init_channel_map(struct iwl_priv *priv); -void iwl_free_channel_map(struct iwl_priv *priv); -const struct iwl_channel_info *iwl_get_channel_info( - const struct iwl_priv *priv, - enum ieee80211_band band, u16 channel); -void iwl_rf_config(struct iwl_priv *priv); - -#endif /* __iwl_eeprom_h__ */ diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 4ac9af7eb853..cb1ca7a25dd5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -59,8 +59,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) /* half dBm need to multiply */ tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); - if (priv->tx_power_lmt_in_half_dbm && - priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) { + if (tx_power_cmd.global_lmt > priv->eeprom_data->max_tx_pwr_half_dbm) { /* * For the newer devices which using enhanced/extend tx power * table in EEPROM, the format is in half dBm. driver need to @@ -72,7 +71,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) * "tx_power_user_lmt" is higher than EEPROM value (in * half-dBm format), lower the tx power based on EEPROM */ - tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; + tx_power_cmd.global_lmt = + priv->eeprom_data->max_tx_pwr_half_dbm; } tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; @@ -824,7 +824,7 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (priv->chain_noise_data.active_chains) active_chains = priv->chain_noise_data.active_chains; else - active_chains = priv->hw_params.valid_rx_ant; + active_chains = priv->eeprom_data->valid_rx_ant; if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 32a823d7497f..f60be3993e81 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -48,7 +48,6 @@ #include "iwl-op-mode.h" #include "iwl-modparams.h" -#include "eeprom.h" #include "dev.h" #include "calib.h" #include "agn.h" @@ -238,12 +237,12 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; - if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) + if (priv->eeprom_data->bands[IEEE80211_BAND_2GHZ].n_channels) priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = - &priv->bands[IEEE80211_BAND_2GHZ]; - if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) + &priv->eeprom_data->bands[IEEE80211_BAND_2GHZ]; + if (priv->eeprom_data->bands[IEEE80211_BAND_5GHZ].n_channels) priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &priv->bands[IEEE80211_BAND_5GHZ]; + &priv->eeprom_data->bands[IEEE80211_BAND_5GHZ]; hw->wiphy->hw_version = priv->trans->hw_id; diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 10a2800687bc..ebdc8b93bc04 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -44,13 +44,14 @@ #include +#include "iwl-eeprom-read.h" +#include "iwl-eeprom-parse.h" #include "iwl-io.h" #include "iwl-trans.h" #include "iwl-op-mode.h" #include "iwl-drv.h" #include "iwl-modparams.h" -#include "eeprom.h" #include "dev.h" #include "calib.h" #include "agn.h" @@ -180,7 +181,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) rate = info->control.rates[0].idx; priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, - priv->hw_params.valid_tx_ant); + priv->eeprom_data->valid_tx_ant); rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); /* In mac80211, rates for 5 GHz start at 0 */ @@ -814,7 +815,7 @@ int iwl_alive_start(struct iwl_priv *priv) ieee80211_wake_queues(priv->hw); /* Configure Tx antenna selection based on H/W config */ - iwlagn_send_tx_ant_config(priv, priv->hw_params.valid_tx_ant); + iwlagn_send_tx_ant_config(priv, priv->eeprom_data->valid_tx_ant); if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { struct iwl_rxon_cmd *active_rxon = @@ -938,8 +939,6 @@ void iwl_down(struct iwl_priv *priv) /* Clear out all status bits but a few that are stable across reset */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | test_bit(STATUS_FW_ERROR, &priv->status) << STATUS_FW_ERROR | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -1126,227 +1125,14 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) del_timer_sync(&priv->ucode_trace); } -static void iwl_init_hw_rates(struct ieee80211_rate *rates) -{ - int i; - - for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { - rates[i].bitrate = iwl_rates[i].ieee * 5; - rates[i].hw_value = i; /* Rate scaling will work on indexes */ - rates[i].hw_value_short = i; - rates[i].flags = 0; - if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) { - /* - * If CCK != 1M then set short preamble rate flag. - */ - rates[i].flags |= - (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ? - 0 : IEEE80211_RATE_SHORT_PREAMBLE; - } - } -} - -#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ -#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ -static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, - struct ieee80211_sta_ht_cap *ht_info, - enum ieee80211_band band) -{ - u16 max_bit_rate = 0; - u8 rx_chains_num = priv->hw_params.rx_chains_num; - u8 tx_chains_num = priv->hw_params.tx_chains_num; - - ht_info->cap = 0; - ht_info->ht_supported = false; - memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); - - if (!priv->cfg->ht_params) - return; - - ht_info->ht_supported = true; - - if (priv->cfg->ht_params->ht_greenfield_support) - ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; - ht_info->cap |= IEEE80211_HT_CAP_SGI_20; - max_bit_rate = MAX_BIT_RATE_20_MHZ; - if (priv->cfg->ht_params->ht40_bands & BIT(band)) { - ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; - ht_info->cap |= IEEE80211_HT_CAP_SGI_40; - ht_info->mcs.rx_mask[4] = 0x01; - max_bit_rate = MAX_BIT_RATE_40_MHZ; - } - - if (iwlwifi_mod_params.amsdu_size_8K) - ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; - - ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; - ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; - - ht_info->mcs.rx_mask[0] = 0xFF; - if (rx_chains_num >= 2) - ht_info->mcs.rx_mask[1] = 0xFF; - if (rx_chains_num >= 3) - ht_info->mcs.rx_mask[2] = 0xFF; - - /* Highest supported Rx data rate */ - max_bit_rate *= rx_chains_num; - WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); - ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); - - /* Tx MCS capabilities */ - ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; - if (tx_chains_num != rx_chains_num) { - ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; - ht_info->mcs.tx_params |= ((tx_chains_num - 1) << - IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); - } -} - -/** - * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom - */ -static int iwl_init_geos(struct iwl_priv *priv) -{ - struct iwl_channel_info *ch; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *channels; - struct ieee80211_channel *geo_ch; - struct ieee80211_rate *rates; - int i = 0; - s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN; - - if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || - priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { - IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); - set_bit(STATUS_GEO_CONFIGURED, &priv->status); - return 0; - } - - channels = kcalloc(priv->channel_count, - sizeof(struct ieee80211_channel), GFP_KERNEL); - if (!channels) - return -ENOMEM; - - rates = kcalloc(IWL_RATE_COUNT_LEGACY, sizeof(struct ieee80211_rate), - GFP_KERNEL); - if (!rates) { - kfree(channels); - return -ENOMEM; - } - - /* 5.2GHz channels start after the 2.4GHz channels */ - sband = &priv->bands[IEEE80211_BAND_5GHZ]; - sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; - /* just OFDM */ - sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; - sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; - - if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) - iwl_init_ht_hw_capab(priv, &sband->ht_cap, - IEEE80211_BAND_5GHZ); - - sband = &priv->bands[IEEE80211_BAND_2GHZ]; - sband->channels = channels; - /* OFDM & CCK */ - sband->bitrates = rates; - sband->n_bitrates = IWL_RATE_COUNT_LEGACY; - - if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) - iwl_init_ht_hw_capab(priv, &sband->ht_cap, - IEEE80211_BAND_2GHZ); - - priv->ieee_channels = channels; - priv->ieee_rates = rates; - - for (i = 0; i < priv->channel_count; i++) { - ch = &priv->channel_info[i]; - - /* FIXME: might be removed if scan is OK */ - if (!is_channel_valid(ch)) - continue; - - sband = &priv->bands[ch->band]; - - geo_ch = &sband->channels[sband->n_channels++]; - - geo_ch->center_freq = - ieee80211_channel_to_frequency(ch->channel, ch->band); - geo_ch->max_power = ch->max_power_avg; - geo_ch->max_antenna_gain = 0xff; - geo_ch->hw_value = ch->channel; - - if (is_channel_valid(ch)) { - if (!(ch->flags & EEPROM_CHANNEL_IBSS)) - geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; - - if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) - geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; - - if (ch->flags & EEPROM_CHANNEL_RADAR) - geo_ch->flags |= IEEE80211_CHAN_RADAR; - - geo_ch->flags |= ch->ht40_extension_channel; - - if (ch->max_power_avg > max_tx_power) - max_tx_power = ch->max_power_avg; - } else { - geo_ch->flags |= IEEE80211_CHAN_DISABLED; - } - - IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", - ch->channel, geo_ch->center_freq, - is_channel_a_band(ch) ? "5.2" : "2.4", - geo_ch->flags & IEEE80211_CHAN_DISABLED ? - "restricted" : "valid", - geo_ch->flags); - } - - priv->tx_power_device_lmt = max_tx_power; - priv->tx_power_user_lmt = max_tx_power; - priv->tx_power_next = max_tx_power; - - if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && - priv->hw_params.sku & EEPROM_SKU_CAP_BAND_52GHZ) { - IWL_INFO(priv, "Incorrectly detected BG card as ABG. " - "Please send your %s to maintainer.\n", - priv->trans->hw_id_str); - priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; - } - - if (iwlwifi_mod_params.disable_5ghz) - priv->bands[IEEE80211_BAND_5GHZ].n_channels = 0; - - IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", - priv->bands[IEEE80211_BAND_2GHZ].n_channels, - priv->bands[IEEE80211_BAND_5GHZ].n_channels); - - set_bit(STATUS_GEO_CONFIGURED, &priv->status); - - return 0; -} - -/* - * iwl_free_geos - undo allocations in iwl_init_geos - */ -static void iwl_free_geos(struct iwl_priv *priv) -{ - kfree(priv->ieee_channels); - kfree(priv->ieee_rates); - clear_bit(STATUS_GEO_CONFIGURED, &priv->status); -} - static int iwl_init_drv(struct iwl_priv *priv) { - int ret; - spin_lock_init(&priv->sta_lock); mutex_init(&priv->mutex); INIT_LIST_HEAD(&priv->calib_results); - priv->ieee_channels = NULL; - priv->ieee_rates = NULL; priv->band = IEEE80211_BAND_2GHZ; priv->plcp_delta_threshold = @@ -1377,31 +1163,11 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; } - ret = iwl_init_channel_map(priv); - if (ret) { - IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); - goto err; - } - - ret = iwl_init_geos(priv); - if (ret) { - IWL_ERR(priv, "initializing geos failed: %d\n", ret); - goto err_free_channel_map; - } - iwl_init_hw_rates(priv->ieee_rates); - return 0; - -err_free_channel_map: - iwl_free_channel_map(priv); -err: - return ret; } static void iwl_uninit_drv(struct iwl_priv *priv) { - iwl_free_geos(priv); - iwl_free_channel_map(priv); kfree(priv->scan_cmd); kfree(priv->beacon_cmd); kfree(rcu_dereference_raw(priv->noa_data)); @@ -1460,6 +1226,42 @@ static void iwl_option_config(struct iwl_priv *priv) #endif } +static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) +{ + u16 radio_cfg; + + priv->hw_params.sku = priv->eeprom_data->sku; + + if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && + !priv->cfg->ht_params) { + IWL_ERR(priv, "Invalid 11n configuration\n"); + return -EINVAL; + } + + if (!priv->hw_params.sku) { + IWL_ERR(priv, "Invalid device sku\n"); + return -EINVAL; + } + + IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); + + radio_cfg = priv->eeprom_data->radio_cfg; + + priv->hw_params.tx_chains_num = + num_of_ant(priv->eeprom_data->valid_tx_ant); + if (priv->cfg->rx_with_siso_diversity) + priv->hw_params.rx_chains_num = 1; + else + priv->hw_params.rx_chains_num = + num_of_ant(priv->eeprom_data->valid_rx_ant); + + IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", + priv->eeprom_data->valid_tx_ant, + priv->eeprom_data->valid_rx_ant); + + return 0; +} + static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, const struct iwl_fw *fw) @@ -1605,25 +1407,33 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, goto out_free_hw; /* Read the EEPROM */ - if (iwl_eeprom_init(priv, priv->trans->hw_rev)) { + if (iwl_read_eeprom(priv->trans, &priv->eeprom_blob, + &priv->eeprom_blob_size)) { IWL_ERR(priv, "Unable to init EEPROM\n"); goto out_free_hw; } + /* Reset chip to save power until we load uCode during "up". */ iwl_trans_stop_hw(priv->trans, false); - if (iwl_eeprom_check_version(priv)) + priv->eeprom_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg, + priv->eeprom_blob, + priv->eeprom_blob_size); + if (!priv->eeprom_data) + goto out_free_eeprom_blob; + + if (iwl_eeprom_check_version(priv->eeprom_data, priv->trans)) goto out_free_eeprom; if (iwl_eeprom_init_hw_params(priv)) goto out_free_eeprom; /* extract MAC Address */ - iwl_eeprom_get_mac(priv, priv->addresses[0].addr); + memcpy(priv->addresses[0].addr, priv->eeprom_data->hw_addr, ETH_ALEN); IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); priv->hw->wiphy->addresses = priv->addresses; priv->hw->wiphy->n_addresses = 1; - num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); + num_mac = priv->eeprom_data->n_hw_addrs; if (num_mac > 1) { memcpy(priv->addresses[1].addr, priv->addresses[0].addr, ETH_ALEN); @@ -1717,8 +1527,10 @@ out_destroy_workqueue: destroy_workqueue(priv->workqueue); priv->workqueue = NULL; iwl_uninit_drv(priv); +out_free_eeprom_blob: + kfree(priv->eeprom_blob); out_free_eeprom: - iwl_eeprom_free(priv); + iwl_free_eeprom_data(priv->eeprom_data); out_free_hw: ieee80211_free_hw(priv->hw); out: @@ -1743,7 +1555,8 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) priv->ucode_loaded = false; iwl_trans_stop_device(priv->trans); - iwl_eeprom_free(priv); + kfree(priv->eeprom_blob); + iwl_free_eeprom_data(priv->eeprom_data); /*netif_stop_queue(dev); */ flush_workqueue(priv->workqueue); diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c index 72c940759ac7..518cf3715809 100644 --- a/drivers/net/wireless/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c @@ -36,7 +36,6 @@ #include "iwl-debug.h" #include "iwl-trans.h" #include "iwl-modparams.h" -#include "eeprom.h" #include "dev.h" #include "agn.h" #include "commands.h" diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index af102910e689..6fddd2785e6e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c @@ -817,7 +817,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, if (num_of_ant(tbl->ant_type) > 1) tbl->ant_type = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); tbl->is_ht40 = 0; tbl->is_SGI = 0; @@ -1445,7 +1445,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret = 0; u8 update_search_tbl_counter = 0; @@ -1463,7 +1463,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ valid_tx_ant = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && tbl->action != IWL_LEGACY_SWITCH_SISO) tbl->action = IWL_LEGACY_SWITCH_SISO; @@ -1487,7 +1487,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) tbl->action = IWL_LEGACY_SWITCH_SISO; valid_tx_ant = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); } start_action = tbl->action; @@ -1621,7 +1621,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 update_search_tbl_counter = 0; int ret; @@ -1639,7 +1639,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ valid_tx_ant = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) tbl->action = IWL_SISO_SWITCH_ANTENNA1; break; @@ -1657,7 +1657,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, /* configure as 1x1 if bt full concurrency */ if (priv->bt_full_concurrent) { valid_tx_ant = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) tbl->action = IWL_SISO_SWITCH_ANTENNA1; } @@ -1793,7 +1793,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 update_search_tbl_counter = 0; int ret; @@ -1963,7 +1963,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret; u8 update_search_tbl_counter = 0; @@ -2697,7 +2697,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, i = lq_sta->last_txrate_idx; - valid_tx_ant = priv->hw_params.valid_tx_ant; + valid_tx_ant = priv->eeprom_data->valid_tx_ant; if (!lq_sta->search_better_tbl) active_tbl = lq_sta->active_tbl; @@ -2891,15 +2891,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i /* These values will be overridden later */ lq_sta->lq.general_params.single_stream_ant_msk = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); lq_sta->lq.general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant & - ~first_antenna(priv->hw_params.valid_tx_ant); + priv->eeprom_data->valid_tx_ant & + ~first_antenna(priv->eeprom_data->valid_tx_ant); if (!lq_sta->lq.general_params.dual_stream_ant_msk) { lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; - } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { + } else if (num_of_ant(priv->eeprom_data->valid_tx_ant) == 2) { lq_sta->lq.general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant; + priv->eeprom_data->valid_tx_ant; } /* as default allow aggregation for all tids */ @@ -2945,7 +2945,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, if (priv && priv->bt_full_concurrent) { /* 1x1 only */ tbl_type.ant_type = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); } /* How many times should we repeat the initial rate? */ @@ -2977,7 +2977,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, if (priv->bt_full_concurrent) valid_tx_ant = ANT_A; else - valid_tx_ant = priv->hw_params.valid_tx_ant; + valid_tx_ant = priv->eeprom_data->valid_tx_ant; } /* Fill rest of rate table */ @@ -3011,7 +3011,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, if (priv && priv->bt_full_concurrent) { /* 1x1 only */ tbl_type.ant_type = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); } /* Indicate to uCode which entries might be MIMO. @@ -3098,7 +3098,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, u8 ant_sel_tx; priv = lq_sta->drv; - valid_tx_ant = priv->hw_params.valid_tx_ant; + valid_tx_ant = priv->eeprom_data->valid_tx_ant; if (lq_sta->dbg_fixed_rate) { ant_sel_tx = ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) @@ -3169,9 +3169,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, desc += sprintf(buff+desc, "fixed rate 0x%X\n", lq_sta->dbg_fixed_rate); desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", - (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", - (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", - (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : ""); + (priv->eeprom_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", + (priv->eeprom_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", + (priv->eeprom_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); desc += sprintf(buff+desc, "lq type %s\n", (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); if (is_Ht(tbl->lq_type)) { diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index d61980248408..0ed90bb8b56a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c @@ -33,7 +33,6 @@ #include #include #include "iwl-io.h" -#include "eeprom.h" #include "dev.h" #include "calib.h" #include "agn.h" diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 4f55689ac6a7..6ee940f497f9 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -420,10 +420,10 @@ static int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) return -EINVAL; } - if (tx_power > priv->tx_power_device_lmt) { + if (tx_power > DIV_ROUND_UP(priv->eeprom_data->max_tx_pwr_half_dbm, 2)) { IWL_WARN(priv, "Requested user TXPOWER %d above upper limit %d.\n", - tx_power, priv->tx_power_device_lmt); + tx_power, priv->eeprom_data->max_tx_pwr_half_dbm); return -EINVAL; } diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 7ee7f32b0fab..2f271c96ed39 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -30,7 +30,6 @@ #include #include -#include "eeprom.h" #include "dev.h" #include "agn.h" @@ -65,7 +64,6 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) * to receive scan abort command or it does not perform * hardware scan currently */ if (!test_bit(STATUS_READY, &priv->status) || - !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || !test_bit(STATUS_SCAN_HW, &priv->status) || test_bit(STATUS_FW_ERROR, &priv->status)) return -EIO; @@ -648,12 +646,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u16 rx_chain = 0; enum ieee80211_band band; u8 n_probes = 0; - u8 rx_ant = priv->hw_params.valid_rx_ant; + u8 rx_ant = priv->eeprom_data->valid_rx_ant; u8 rate; bool is_active = false; int chan_mod; u8 active_chains; - u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; + u8 scan_tx_antennas = priv->eeprom_data->valid_tx_ant; int ret; int scan_cmd_size = sizeof(struct iwl_scan_cmd) + MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) + @@ -863,7 +861,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) /* MIMO is not used here, but value is required */ rx_chain |= - priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; + priv->eeprom_data->valid_rx_ant << RXON_RX_CHAIN_VALID_POS; rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; @@ -980,7 +978,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) void iwl_init_scan_params(struct iwl_priv *priv) { - u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; + u8 ant_idx = fls(priv->eeprom_data->valid_tx_ant) - 1; if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index c6b343fdf5f9..286ce4e18068 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -177,17 +177,23 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, if (!ctx->ht.enabled || !ctx->ht.is_40mhz) return false; +#ifdef CONFIG_IWLWIFI_DEBUGFS + if (priv->disable_ht40) + return false; +#endif + /* - * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 - * the bit will not set if it is pure 40MHz case + * Remainder of this function checks ht_cap, but if it's + * NULL then we can do HT40 (special case for RXON) */ - if (ht_cap && !ht_cap->ht_supported) + if (!ht_cap) + return true; + + if (!ht_cap->ht_supported) return false; -#ifdef CONFIG_IWLWIFI_DEBUGFS - if (priv->disable_ht40) + if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) return false; -#endif return true; } @@ -627,23 +633,23 @@ static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) rate_flags |= RATE_MCS_CCK_MSK; - rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << + rate_flags |= first_antenna(priv->eeprom_data->valid_tx_ant) << RATE_MCS_ANT_POS; rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) link_cmd->rs_table[i].rate_n_flags = rate_n_flags; link_cmd->general_params.single_stream_ant_msk = - first_antenna(priv->hw_params.valid_tx_ant); + first_antenna(priv->eeprom_data->valid_tx_ant); link_cmd->general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant & - ~first_antenna(priv->hw_params.valid_tx_ant); + priv->eeprom_data->valid_tx_ant & + ~first_antenna(priv->eeprom_data->valid_tx_ant); if (!link_cmd->general_params.dual_stream_ant_msk) { link_cmd->general_params.dual_stream_ant_msk = ANT_AB; - } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { + } else if (num_of_ant(priv->eeprom_data->valid_tx_ant) == 2) { link_cmd->general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant; + priv->eeprom_data->valid_tx_ant; } link_cmd->agg_params.agg_dis_start_th = diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index 59cfe9a8eea5..a7b59590bb53 100644 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c @@ -534,9 +534,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) break; case IWL_TM_CMD_APP2DEV_GET_EEPROM: - if (priv->eeprom) { + if (priv->eeprom_blob) { skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - priv->cfg->base_params->eeprom_size + 20); + priv->eeprom_blob_size + 20); if (!skb) { IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; @@ -544,15 +544,15 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_EEPROM_RSP) || nla_put(skb, IWL_TM_ATTR_EEPROM, - priv->cfg->base_params->eeprom_size, - priv->eeprom)) + priv->eeprom_blob_size, + priv->eeprom_blob)) goto nla_put_failure; status = cfg80211_testmode_reply(skb); if (status < 0) IWL_ERR(priv, "Error sending msg : %d\n", status); } else - return -EFAULT; + return -ENODATA; break; case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index 55418899bc4e..eb864433e59d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c @@ -36,7 +36,6 @@ #include "iwl-modparams.h" #include "iwl-debug.h" #include "agn.h" -#include "eeprom.h" #include "dev.h" #include "commands.h" #include "tt.h" diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 7e3bd6281551..0dfaf649b257 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -186,7 +186,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, rate_idx = info->control.rates[0].idx; if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) - rate_idx = rate_lowest_index(&priv->bands[info->band], + rate_idx = rate_lowest_index( + &priv->eeprom_data->bands[info->band], info->control.sta); /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ if (info->band == IEEE80211_BAND_5GHZ) @@ -206,10 +207,11 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, - first_antenna(priv->hw_params.valid_tx_ant)); + first_antenna(priv->eeprom_data->valid_tx_ant)); } else - priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, - priv->hw_params.valid_tx_ant); + priv->mgmt_tx_ant = iwl_toggle_tx_ant( + priv, priv->mgmt_tx_ant, + priv->eeprom_data->valid_tx_ant); rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); /* Set the rate in the TX cmd */ diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 5a2e186c7ded..b3a314ba48c7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -61,8 +61,7 @@ iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) static int iwl_set_Xtal_calib(struct iwl_priv *priv) { struct iwl_calib_xtal_freq_cmd cmd; - __le16 *xtal_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); + __le16 *xtal_calib = priv->eeprom_data->xtal_calib; iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); @@ -73,12 +72,10 @@ static int iwl_set_Xtal_calib(struct iwl_priv *priv) static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_cmd cmd; - __le16 *offset_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); - memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(*offset_calib)); + cmd.radio_sensor_offset = priv->eeprom_data->raw_temperature; if (!(cmd.radio_sensor_offset)) cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; @@ -90,27 +87,17 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_v2_cmd cmd; - __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, - EEPROM_KELVIN_TEMPERATURE); - __le16 *offset_calib_low = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); - struct iwl_eeprom_calib_hdr *hdr; memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); - hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, - EEPROM_CALIB_ALL); - memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, - sizeof(*offset_calib_high)); - memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, - sizeof(*offset_calib_low)); - if (!(cmd.radio_sensor_offset_low)) { + cmd.radio_sensor_offset_high = priv->eeprom_data->kelvin_temperature; + cmd.radio_sensor_offset_low = priv->eeprom_data->raw_temperature; + if (!cmd.radio_sensor_offset_low) { IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; } - memcpy(&cmd.burntVoltageRef, &hdr->voltage, - sizeof(hdr->voltage)); + cmd.burntVoltageRef = priv->eeprom_data->calib_voltage; IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", le16_to_cpu(cmd.radio_sensor_offset_high)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index af3a46126f01..e9accfccc050 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -194,6 +194,24 @@ struct iwl_ht_params { u8 ht40_bands; }; +/* + * information on how to parse the EEPROM + */ +#define EEPROM_REG_BAND_1_CHANNELS 0x08 +#define EEPROM_REG_BAND_2_CHANNELS 0x26 +#define EEPROM_REG_BAND_3_CHANNELS 0x42 +#define EEPROM_REG_BAND_4_CHANNELS 0x5C +#define EEPROM_REG_BAND_5_CHANNELS 0x74 +#define EEPROM_REG_BAND_24_HT40_CHANNELS 0x82 +#define EEPROM_REG_BAND_52_HT40_CHANNELS 0x92 +#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS 0x80 +#define EEPROM_REGULATORY_BAND_NO_HT40 0 + +struct iwl_eeprom_params { + const u8 regulatory_bands[7]; + bool enhanced_txpower; +}; + /** * struct iwl_cfg * @name: Offical name of the device @@ -246,6 +264,7 @@ struct iwl_cfg { /* params likely to change within a device family */ const struct iwl_ht_params *ht_params; const struct iwl_bt_params *bt_params; + const struct iwl_eeprom_params *eeprom_params; const bool need_temp_offset_calib; /* if used set to true */ const bool no_xtal_calib; enum iwl_led_mode led_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index f6bf91c8f773..42b20b0e83bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -45,6 +45,7 @@ void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3); /* No matter what is m (priv, bus, trans), this will work */ #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a) +#define IWL_ERR_DEV(d, f, a...) __iwl_err((d), false, false, f, ## a) #define IWL_WARN(m, f, a...) __iwl_warn((m)->dev, f, ## a) #define IWL_INFO(m, f, a...) __iwl_info((m)->dev, f, ## a) #define IWL_CRIT(m, f, a...) __iwl_crit((m)->dev, f, ## a) @@ -69,6 +70,8 @@ do { \ #define IWL_DEBUG(m, level, fmt, args...) \ __iwl_dbg((m)->dev, level, false, __func__, fmt, ##args) +#define IWL_DEBUG_DEV(dev, level, fmt, args...) \ + __iwl_dbg((dev), level, false, __func__, fmt, ##args) #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ __iwl_dbg((m)->dev, level, true, __func__, fmt, ##args) @@ -153,7 +156,7 @@ do { \ #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) -#define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) +#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c new file mode 100644 index 000000000000..c87a05cbec12 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -0,0 +1,900 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +#include +#include +#include +#include "iwl-modparams.h" +#include "iwl-eeprom-parse.h" + +/* EEPROM offset definitions */ + +/* indirect access definitions */ +#define ADDRESS_MSK 0x0000FFFF +#define INDIRECT_TYPE_MSK 0x000F0000 +#define INDIRECT_HOST 0x00010000 +#define INDIRECT_GENERAL 0x00020000 +#define INDIRECT_REGULATORY 0x00030000 +#define INDIRECT_CALIBRATION 0x00040000 +#define INDIRECT_PROCESS_ADJST 0x00050000 +#define INDIRECT_OTHERS 0x00060000 +#define INDIRECT_TXP_LIMIT 0x00070000 +#define INDIRECT_TXP_LIMIT_SIZE 0x00080000 +#define INDIRECT_ADDRESS 0x00100000 + +/* corresponding link offsets in EEPROM */ +#define EEPROM_LINK_HOST (2*0x64) +#define EEPROM_LINK_GENERAL (2*0x65) +#define EEPROM_LINK_REGULATORY (2*0x66) +#define EEPROM_LINK_CALIBRATION (2*0x67) +#define EEPROM_LINK_PROCESS_ADJST (2*0x68) +#define EEPROM_LINK_OTHERS (2*0x69) +#define EEPROM_LINK_TXP_LIMIT (2*0x6a) +#define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) + +/* General */ +#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ +#define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ +#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ +#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ +#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ +#define EEPROM_VERSION (2*0x44) /* 2 bytes */ +#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ +#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ +#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ +#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ + +/* calibration */ +struct iwl_eeprom_calib_hdr { + u8 version; + u8 pa_type; + __le16 voltage; +} __packed; + +#define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) +#define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) + +/* temperature */ +#define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) +#define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) + +/* + * EEPROM bands + * These are the channel numbers from each band in the order + * that they are stored in the EEPROM band information. Note + * that EEPROM bands aren't the same as mac80211 bands, and + * there are even special "ht40 bands" in the EEPROM. + */ +static const u8 iwl_eeprom_band_1[14] = { /* 2.4 GHz */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +}; + +static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ + 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 +}; + +static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ + 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 +}; + +static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 +}; + +static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ + 145, 149, 153, 157, 161, 165 +}; + +static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ + 1, 2, 3, 4, 5, 6, 7 +}; + +static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ + 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 +}; + +#define IWL_NUM_CHANNELS (ARRAY_SIZE(iwl_eeprom_band_1) + \ + ARRAY_SIZE(iwl_eeprom_band_2) + \ + ARRAY_SIZE(iwl_eeprom_band_3) + \ + ARRAY_SIZE(iwl_eeprom_band_4) + \ + ARRAY_SIZE(iwl_eeprom_band_5)) + +/* rate data (static) */ +static struct ieee80211_rate iwl_cfg80211_rates[] = { + { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, }, + { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3, + .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, + { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, }, + { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, }, + { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, }, + { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, }, + { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, }, + { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, }, + { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, }, + { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, }, +}; +#define RATES_24_OFFS 0 +#define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates) +#define RATES_52_OFFS 4 +#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS) + +/* EEPROM reading functions */ + +static u16 iwl_eeprom_query16(const u8 *eeprom, size_t eeprom_size, int offset) +{ + if (WARN_ON(offset + sizeof(u16) > eeprom_size)) + return 0; + return le16_to_cpup((__le16 *)(eeprom + offset)); +} + +static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size, + u32 address) +{ + u16 offset = 0; + + if ((address & INDIRECT_ADDRESS) == 0) + return address; + + switch (address & INDIRECT_TYPE_MSK) { + case INDIRECT_HOST: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_HOST); + break; + case INDIRECT_GENERAL: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_GENERAL); + break; + case INDIRECT_REGULATORY: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_REGULATORY); + break; + case INDIRECT_TXP_LIMIT: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_TXP_LIMIT); + break; + case INDIRECT_TXP_LIMIT_SIZE: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_TXP_LIMIT_SIZE); + break; + case INDIRECT_CALIBRATION: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_CALIBRATION); + break; + case INDIRECT_PROCESS_ADJST: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_PROCESS_ADJST); + break; + case INDIRECT_OTHERS: + offset = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_LINK_OTHERS); + break; + default: + WARN_ON(1); + break; + } + + /* translate the offset from words to byte */ + return (address & ADDRESS_MSK) + (offset << 1); +} + +static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size, + u32 offset) +{ + u32 address = eeprom_indirect_address(eeprom, eeprom_size, offset); + + if (WARN_ON(address >= eeprom_size)) + return NULL; + + return &eeprom[address]; +} + +static int iwl_eeprom_read_calib(const u8 *eeprom, size_t eeprom_size, + struct iwl_eeprom_data *data) +{ + struct iwl_eeprom_calib_hdr *hdr; + + hdr = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, + EEPROM_CALIB_ALL); + if (!hdr) + return -ENODATA; + data->calib_version = hdr->version; + data->calib_voltage = hdr->voltage; + + return 0; +} + +/** + * enum iwl_eeprom_channel_flags - channel flags in EEPROM + * @EEPROM_CHANNEL_VALID: channel is usable for this SKU/geo + * @EEPROM_CHANNEL_IBSS: usable as an IBSS channel + * @EEPROM_CHANNEL_ACTIVE: active scanning allowed + * @EEPROM_CHANNEL_RADAR: radar detection required + * @EEPROM_CHANNEL_WIDE: 20 MHz channel okay (?) + * @EEPROM_CHANNEL_DFS: dynamic freq selection candidate + */ +enum iwl_eeprom_channel_flags { + EEPROM_CHANNEL_VALID = BIT(0), + EEPROM_CHANNEL_IBSS = BIT(1), + EEPROM_CHANNEL_ACTIVE = BIT(3), + EEPROM_CHANNEL_RADAR = BIT(4), + EEPROM_CHANNEL_WIDE = BIT(5), + EEPROM_CHANNEL_DFS = BIT(7), +}; + +/** + * struct iwl_eeprom_channel - EEPROM channel data + * @flags: %EEPROM_CHANNEL_* flags + * @max_power_avg: max power (in dBm) on this channel, at most 31 dBm + */ +struct iwl_eeprom_channel { + u8 flags; + s8 max_power_avg; +} __packed; + + +enum iwl_eeprom_enhanced_txpwr_flags { + IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), + IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), + IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), + IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), + IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), + IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), + IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), +}; + +/** + * iwl_eeprom_enhanced_txpwr structure + * @flags: entry flags + * @channel: channel number + * @chain_a_max_pwr: chain a max power in 1/2 dBm + * @chain_b_max_pwr: chain b max power in 1/2 dBm + * @chain_c_max_pwr: chain c max power in 1/2 dBm + * @delta_20_in_40: 20-in-40 deltas (hi/lo) + * @mimo2_max_pwr: mimo2 max power in 1/2 dBm + * @mimo3_max_pwr: mimo3 max power in 1/2 dBm + * + * This structure presents the enhanced regulatory tx power limit layout + * in an EEPROM image. + */ +struct iwl_eeprom_enhanced_txpwr { + u8 flags; + u8 channel; + s8 chain_a_max; + s8 chain_b_max; + s8 chain_c_max; + u8 delta_20_in_40; + s8 mimo2_max; + s8 mimo3_max; +} __packed; + +static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_eeprom_data *data, + struct iwl_eeprom_enhanced_txpwr *txp) +{ + s8 result = 0; /* (.5 dBm) */ + + /* Take the highest tx power from any valid chains */ + if (data->valid_tx_ant & ANT_A && txp->chain_a_max > result) + result = txp->chain_a_max; + + if (data->valid_tx_ant & ANT_B && txp->chain_b_max > result) + result = txp->chain_b_max; + + if (data->valid_tx_ant & ANT_C && txp->chain_c_max > result) + result = txp->chain_c_max; + + if ((data->valid_tx_ant == ANT_AB || + data->valid_tx_ant == ANT_BC || + data->valid_tx_ant == ANT_AC) && txp->mimo2_max > result) + result = txp->mimo2_max; + + if (data->valid_tx_ant == ANT_ABC && txp->mimo3_max > result) + result = txp->mimo3_max; + + return result; +} + +#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) +#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) +#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) + +#define TXP_CHECK_AND_PRINT(x) \ + ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) ? # x " " : "") + +static void +iwl_eeprom_enh_txp_read_element(struct iwl_eeprom_data *data, + struct iwl_eeprom_enhanced_txpwr *txp, + int n_channels, s8 max_txpower_avg) +{ + int ch_idx; + enum ieee80211_band band; + + band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? + IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; + + for (ch_idx = 0; ch_idx < n_channels; ch_idx++) { + struct ieee80211_channel *chan = &data->channels[ch_idx]; + + /* update matching channel or from common data only */ + if (txp->channel != 0 && chan->hw_value != txp->channel) + continue; + + /* update matching band only */ + if (band != chan->band) + continue; + + if (chan->max_power < max_txpower_avg && + !(txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ)) + chan->max_power = max_txpower_avg; + } +} + +static void iwl_eeprom_enhanced_txpower(struct device *dev, + struct iwl_eeprom_data *data, + const u8 *eeprom, size_t eeprom_size, + int n_channels) +{ + struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; + int idx, entries; + __le16 *txp_len; + s8 max_txp_avg_halfdbm; + + BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); + + /* the length is in 16-bit words, but we want entries */ + txp_len = (__le16 *)iwl_eeprom_query_addr(eeprom, eeprom_size, + EEPROM_TXP_SZ_OFFS); + entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; + + txp_array = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, + EEPROM_TXP_OFFS); + + for (idx = 0; idx < entries; idx++) { + txp = &txp_array[idx]; + /* skip invalid entries */ + if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) + continue; + + IWL_DEBUG_EEPROM(dev, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", + (txp->channel && (txp->flags & + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? + "Common " : (txp->channel) ? + "Channel" : "Common", + (txp->channel), + TXP_CHECK_AND_PRINT(VALID), + TXP_CHECK_AND_PRINT(BAND_52G), + TXP_CHECK_AND_PRINT(OFDM), + TXP_CHECK_AND_PRINT(40MHZ), + TXP_CHECK_AND_PRINT(HT_AP), + TXP_CHECK_AND_PRINT(RES1), + TXP_CHECK_AND_PRINT(RES2), + TXP_CHECK_AND_PRINT(COMMON_TYPE), + txp->flags); + IWL_DEBUG_EEPROM(dev, + "\t\t chain_A: 0x%02x chain_B: 0X%02x chain_C: 0X%02x\n", + txp->chain_a_max, txp->chain_b_max, + txp->chain_c_max); + IWL_DEBUG_EEPROM(dev, + "\t\t MIMO2: 0x%02x MIMO3: 0x%02x High 20_on_40: 0x%02x Low 20_on_40: 0x%02x\n", + txp->mimo2_max, txp->mimo3_max, + ((txp->delta_20_in_40 & 0xf0) >> 4), + (txp->delta_20_in_40 & 0x0f)); + + max_txp_avg_halfdbm = iwl_get_max_txpwr_half_dbm(data, txp); + + iwl_eeprom_enh_txp_read_element(data, txp, n_channels, + DIV_ROUND_UP(max_txp_avg_halfdbm, 2)); + + if (max_txp_avg_halfdbm > data->max_tx_pwr_half_dbm) + data->max_tx_pwr_half_dbm = max_txp_avg_halfdbm; + } +} + +static void iwl_init_band_reference(const struct iwl_cfg *cfg, + const u8 *eeprom, size_t eeprom_size, + int eeprom_band, int *eeprom_ch_count, + const struct iwl_eeprom_channel **ch_info, + const u8 **eeprom_ch_array) +{ + u32 offset = cfg->eeprom_params->regulatory_bands[eeprom_band - 1]; + + offset |= INDIRECT_ADDRESS | INDIRECT_REGULATORY; + + *ch_info = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, offset); + + switch (eeprom_band) { + case 1: /* 2.4GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); + *eeprom_ch_array = iwl_eeprom_band_1; + break; + case 2: /* 4.9GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); + *eeprom_ch_array = iwl_eeprom_band_2; + break; + case 3: /* 5.2GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); + *eeprom_ch_array = iwl_eeprom_band_3; + break; + case 4: /* 5.5GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); + *eeprom_ch_array = iwl_eeprom_band_4; + break; + case 5: /* 5.7GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); + *eeprom_ch_array = iwl_eeprom_band_5; + break; + case 6: /* 2.4GHz ht40 channels */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); + *eeprom_ch_array = iwl_eeprom_band_6; + break; + case 7: /* 5 GHz ht40 channels */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); + *eeprom_ch_array = iwl_eeprom_band_7; + break; + default: + *eeprom_ch_count = 0; + *eeprom_ch_array = NULL; + WARN_ON(1); + } +} + +#define CHECK_AND_PRINT(x) \ + ((eeprom_ch->flags & EEPROM_CHANNEL_##x) ? # x " " : "") + +static void iwl_mod_ht40_chan_info(struct device *dev, + struct iwl_eeprom_data *data, int n_channels, + enum ieee80211_band band, u16 channel, + const struct iwl_eeprom_channel *eeprom_ch, + u8 clear_ht40_extension_channel) +{ + struct ieee80211_channel *chan = NULL; + int i; + + for (i = 0; i < n_channels; i++) { + if (data->channels[i].band != band) + continue; + if (data->channels[i].hw_value != channel) + continue; + chan = &data->channels[i]; + break; + } + + if (!chan) + return; + + IWL_DEBUG_EEPROM(dev, + "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", + channel, + band == IEEE80211_BAND_5GHZ ? "5.2" : "2.4", + CHECK_AND_PRINT(IBSS), + CHECK_AND_PRINT(ACTIVE), + CHECK_AND_PRINT(RADAR), + CHECK_AND_PRINT(WIDE), + CHECK_AND_PRINT(DFS), + eeprom_ch->flags, + eeprom_ch->max_power_avg, + ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) && + !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? "" + : "not "); + + if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) + chan->flags &= ~clear_ht40_extension_channel; +} + +#define CHECK_AND_PRINT_I(x) \ + ((eeprom_ch_info[ch_idx].flags & EEPROM_CHANNEL_##x) ? # x " " : "") + +static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, + struct iwl_eeprom_data *data, + const u8 *eeprom, size_t eeprom_size) +{ + int band, ch_idx; + const struct iwl_eeprom_channel *eeprom_ch_info; + const u8 *eeprom_ch_array; + int eeprom_ch_count; + int n_channels = 0; + + /* + * Loop through the 5 EEPROM bands and add them to the parse list + */ + for (band = 1; band <= 5; band++) { + struct ieee80211_channel *channel; + + iwl_init_band_reference(cfg, eeprom, eeprom_size, band, + &eeprom_ch_count, &eeprom_ch_info, + &eeprom_ch_array); + + /* Loop through each band adding each of the channels */ + for (ch_idx = 0; ch_idx < eeprom_ch_count; ch_idx++) { + const struct iwl_eeprom_channel *eeprom_ch; + + eeprom_ch = &eeprom_ch_info[ch_idx]; + + if (!(eeprom_ch->flags & EEPROM_CHANNEL_VALID)) { + IWL_DEBUG_EEPROM(dev, + "Ch. %d Flags %x [%sGHz] - No traffic\n", + eeprom_ch_array[ch_idx], + eeprom_ch_info[ch_idx].flags, + (band != 1) ? "5.2" : "2.4"); + continue; + } + + channel = &data->channels[n_channels]; + n_channels++; + + channel->hw_value = eeprom_ch_array[ch_idx]; + channel->band = (band == 1) ? IEEE80211_BAND_2GHZ + : IEEE80211_BAND_5GHZ; + channel->center_freq = + ieee80211_channel_to_frequency( + channel->hw_value, channel->band); + + /* set no-HT40, will enable as appropriate later */ + channel->flags = IEEE80211_CHAN_NO_HT40; + + if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) + channel->flags |= IEEE80211_CHAN_NO_IBSS; + + if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) + channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) + channel->flags |= IEEE80211_CHAN_RADAR; + + /* Initialize regulatory-based run-time data */ + channel->max_power = + eeprom_ch_info[ch_idx].max_power_avg; + IWL_DEBUG_EEPROM(dev, + "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", + channel->hw_value, + (band != 1) ? "5.2" : "2.4", + CHECK_AND_PRINT_I(VALID), + CHECK_AND_PRINT_I(IBSS), + CHECK_AND_PRINT_I(ACTIVE), + CHECK_AND_PRINT_I(RADAR), + CHECK_AND_PRINT_I(WIDE), + CHECK_AND_PRINT_I(DFS), + eeprom_ch_info[ch_idx].flags, + eeprom_ch_info[ch_idx].max_power_avg, + ((eeprom_ch_info[ch_idx].flags & + EEPROM_CHANNEL_IBSS) && + !(eeprom_ch_info[ch_idx].flags & + EEPROM_CHANNEL_RADAR)) + ? "" : "not "); + } + } + + if (cfg->eeprom_params->enhanced_txpower) { + /* + * for newer device (6000 series and up) + * EEPROM contain enhanced tx power information + * driver need to process addition information + * to determine the max channel tx power limits + */ + iwl_eeprom_enhanced_txpower(dev, data, eeprom, eeprom_size, + n_channels); + } else { + /* All others use data from channel map */ + int i; + + data->max_tx_pwr_half_dbm = -128; + + for (i = 0; i < n_channels; i++) + data->max_tx_pwr_half_dbm = + max_t(s8, data->max_tx_pwr_half_dbm, + data->channels[i].max_power * 2); + } + + /* Check if we do have HT40 channels */ + if (cfg->eeprom_params->regulatory_bands[5] == + EEPROM_REGULATORY_BAND_NO_HT40 && + cfg->eeprom_params->regulatory_bands[6] == + EEPROM_REGULATORY_BAND_NO_HT40) + return n_channels; + + /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ + for (band = 6; band <= 7; band++) { + enum ieee80211_band ieeeband; + + iwl_init_band_reference(cfg, eeprom, eeprom_size, band, + &eeprom_ch_count, &eeprom_ch_info, + &eeprom_ch_array); + + /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ + ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ + : IEEE80211_BAND_5GHZ; + + /* Loop through each band adding each of the channels */ + for (ch_idx = 0; ch_idx < eeprom_ch_count; ch_idx++) { + /* Set up driver's info for lower half */ + iwl_mod_ht40_chan_info(dev, data, n_channels, ieeeband, + eeprom_ch_array[ch_idx], + &eeprom_ch_info[ch_idx], + IEEE80211_CHAN_NO_HT40PLUS); + + /* Set up driver's info for upper half */ + iwl_mod_ht40_chan_info(dev, data, n_channels, ieeeband, + eeprom_ch_array[ch_idx] + 4, + &eeprom_ch_info[ch_idx], + IEEE80211_CHAN_NO_HT40MINUS); + } + } + + return n_channels; +} + +static int iwl_init_sband_channels(struct iwl_eeprom_data *data, + struct ieee80211_supported_band *sband, + int n_channels, enum ieee80211_band band) +{ + struct ieee80211_channel *chan = &data->channels[0]; + int n = 0, idx = 0; + + while (chan->band != band && idx < n_channels) + chan = &data->channels[++idx]; + + sband->channels = &data->channels[idx]; + + while (chan->band == band && idx < n_channels) { + chan = &data->channels[++idx]; + n++; + } + + sband->n_channels = n; + + return n; +} + +#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ +#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ + +static void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, + struct iwl_eeprom_data *data, + struct ieee80211_sta_ht_cap *ht_info, + enum ieee80211_band band) +{ + int max_bit_rate = 0; + u8 rx_chains; + u8 tx_chains; + + tx_chains = hweight8(data->valid_tx_ant); + if (cfg->rx_with_siso_diversity) + rx_chains = 1; + else + rx_chains = hweight8(data->valid_rx_ant); + + if (!(data->sku & EEPROM_SKU_CAP_11N_ENABLE) || !cfg->ht_params) { + ht_info->ht_supported = false; + return; + } + + ht_info->ht_supported = true; + ht_info->cap = 0; + + if (iwlwifi_mod_params.amsdu_size_8K) + ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; + + ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; + + ht_info->mcs.rx_mask[0] = 0xFF; + if (rx_chains >= 2) + ht_info->mcs.rx_mask[1] = 0xFF; + if (rx_chains >= 3) + ht_info->mcs.rx_mask[2] = 0xFF; + + if (cfg->ht_params->ht_greenfield_support) + ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; + ht_info->cap |= IEEE80211_HT_CAP_SGI_20; + + max_bit_rate = MAX_BIT_RATE_20_MHZ; + + if (cfg->ht_params->ht40_bands & BIT(band)) { + ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + ht_info->cap |= IEEE80211_HT_CAP_SGI_40; + ht_info->mcs.rx_mask[4] = 0x01; + max_bit_rate = MAX_BIT_RATE_40_MHZ; + } + + /* Highest supported Rx data rate */ + max_bit_rate *= rx_chains; + WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); + ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); + + /* Tx MCS capabilities */ + ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + if (tx_chains != rx_chains) { + ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; + ht_info->mcs.tx_params |= ((tx_chains - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); + } +} + +static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, + struct iwl_eeprom_data *data, + const u8 *eeprom, size_t eeprom_size) +{ + int n_channels = iwl_init_channel_map(dev, cfg, data, + eeprom, eeprom_size); + int n_used = 0; + struct ieee80211_supported_band *sband; + + sband = &data->bands[IEEE80211_BAND_2GHZ]; + sband->band = IEEE80211_BAND_2GHZ; + sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; + sband->n_bitrates = N_RATES_24; + n_used += iwl_init_sband_channels(data, sband, n_channels, + IEEE80211_BAND_2GHZ); + iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); + + sband = &data->bands[IEEE80211_BAND_5GHZ]; + sband->band = IEEE80211_BAND_5GHZ; + sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS]; + sband->n_bitrates = N_RATES_52; + n_used += iwl_init_sband_channels(data, sband, n_channels, + IEEE80211_BAND_5GHZ); + iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); + + if (n_channels != n_used) + IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n", + n_used, n_channels); +} + +/* EEPROM data functions */ + +struct iwl_eeprom_data * +iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, + const u8 *eeprom, size_t eeprom_size) +{ + struct iwl_eeprom_data *data; + const void *tmp; + + if (WARN_ON(!cfg || !cfg->eeprom_params)) + return NULL; + + data = kzalloc(sizeof(*data) + + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, + GFP_KERNEL); + if (!data) + return NULL; + + /* get MAC address(es) */ + tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_MAC_ADDRESS); + if (!tmp) + goto err_free; + memcpy(data->hw_addr, tmp, ETH_ALEN); + data->n_hw_addrs = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_NUM_MAC_ADDRESS); + + if (iwl_eeprom_read_calib(eeprom, eeprom_size, data)) + goto err_free; + + tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_XTAL); + if (!tmp) + goto err_free; + memcpy(data->xtal_calib, tmp, sizeof(data->xtal_calib)); + + tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, + EEPROM_RAW_TEMPERATURE); + if (!tmp) + goto err_free; + data->raw_temperature = *(__le16 *)tmp; + + tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, + EEPROM_KELVIN_TEMPERATURE); + if (!tmp) + goto err_free; + data->kelvin_temperature = *(__le16 *)tmp; + data->kelvin_voltage = *((__le16 *)tmp + 1); + + data->radio_cfg = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_RADIO_CONFIG); + data->sku = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_SKU_CAP); + data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size, + EEPROM_VERSION); + + data->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(data->radio_cfg); + data->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(data->radio_cfg); + + /* check overrides (some devices have wrong EEPROM) */ + if (cfg->valid_tx_ant) + data->valid_tx_ant = cfg->valid_tx_ant; + if (cfg->valid_rx_ant) + data->valid_rx_ant = cfg->valid_rx_ant; + + if (!data->valid_tx_ant || !data->valid_rx_ant) { + IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n", + data->valid_tx_ant, data->valid_rx_ant); + goto err_free; + } + + iwl_init_sbands(dev, cfg, data, eeprom, eeprom_size); + + return data; + err_free: + kfree(data); + return NULL; +} +EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); + +/* helper functions */ +int iwl_eeprom_check_version(struct iwl_eeprom_data *data, + struct iwl_trans *trans) +{ + if (data->eeprom_version >= trans->cfg->eeprom_ver || + data->calib_version >= trans->cfg->eeprom_calib_ver) { + IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", + data->eeprom_version, data->calib_version); + return 0; + } + + IWL_ERR(trans, + "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", + data->eeprom_version, trans->cfg->eeprom_ver, + data->calib_version, trans->cfg->eeprom_calib_ver); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(iwl_eeprom_check_version); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h new file mode 100644 index 000000000000..9c07c670a1ce --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h @@ -0,0 +1,138 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +#ifndef __iwl_eeprom_parse_h__ +#define __iwl_eeprom_parse_h__ + +#include +#include +#include "iwl-trans.h" + +/* SKU Capabilities (actual values from EEPROM definition) */ +#define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) +#define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) +#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) +#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) +#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) + +/* radio config bits (actual values from EEPROM definition) */ +#define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ +#define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ +#define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ +#define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ +#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ +#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ + +struct iwl_eeprom_data { + int n_hw_addrs; + u8 hw_addr[ETH_ALEN]; + + u16 radio_config; + + u8 calib_version; + __le16 calib_voltage; + + __le16 raw_temperature; + __le16 kelvin_temperature; + __le16 kelvin_voltage; + __le16 xtal_calib[2]; + + u16 sku; + u16 radio_cfg; + u16 eeprom_version; + s8 max_tx_pwr_half_dbm; + + u8 valid_tx_ant, valid_rx_ant; + + struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; + struct ieee80211_channel channels[]; +}; + +/** + * iwl_parse_eeprom_data - parse EEPROM data and return values + * + * @dev: device pointer we're parsing for, for debug only + * @cfg: device configuration for parsing and overrides + * @eeprom: the EEPROM data + * @eeprom_size: length of the EEPROM data + * + * This function parses all EEPROM values we need and then + * returns a (newly allocated) struct containing all the + * relevant values for driver use. The struct must be freed + * later with iwl_free_eeprom_data(). + */ +struct iwl_eeprom_data * +iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, + const u8 *eeprom, size_t eeprom_size); + +/** + * iwl_free_eeprom_data - free EEPROM data + * @data: the data to free + */ +static inline void iwl_free_eeprom_data(struct iwl_eeprom_data *data) +{ + kfree(data); +} + +int iwl_eeprom_check_version(struct iwl_eeprom_data *data, + struct iwl_trans *trans); + +#endif /* __iwl_eeprom_parse_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c new file mode 100644 index 000000000000..27c7da3c6ed1 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c @@ -0,0 +1,463 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +#include +#include +#include + +#include "iwl-debug.h" +#include "iwl-eeprom-read.h" +#include "iwl-io.h" +#include "iwl-prph.h" +#include "iwl-csr.h" + +/* + * EEPROM access time values: + * + * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. + * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). + * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. + * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. + */ +#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ + +#define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ +#define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ + + +/* + * The device's EEPROM semaphore prevents conflicts between driver and uCode + * when accessing the EEPROM; each access is a series of pulses to/from the + * EEPROM chip, not a single event, so even reads could conflict if they + * weren't arbitrated by the semaphore. + */ + +#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ +#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ + +static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) +{ + u16 count; + int ret; + + for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { + /* Request semaphore */ + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + + /* See if we got it */ + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + EEPROM_SEM_TIMEOUT); + if (ret >= 0) { + IWL_DEBUG_EEPROM(trans->dev, + "Acquired semaphore after %d tries.\n", + count+1); + return ret; + } + } + + return ret; +} + +static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) +{ + iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); +} + +static int iwl_eeprom_verify_signature(struct iwl_trans *trans, bool nvm_is_otp) +{ + u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; + + IWL_DEBUG_EEPROM(trans->dev, "EEPROM signature=0x%08x\n", gp); + + switch (gp) { + case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: + if (!nvm_is_otp) { + IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", + gp); + return -ENOENT; + } + return 0; + case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: + case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: + if (nvm_is_otp) { + IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); + return -ENOENT; + } + return 0; + case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: + default: + IWL_ERR(trans, + "bad EEPROM/OTP signature, type=%s, EEPROM_GP=0x%08x\n", + nvm_is_otp ? "OTP" : "EEPROM", gp); + return -ENOENT; + } +} + +/****************************************************************************** + * + * OTP related functions + * +******************************************************************************/ + +static void iwl_set_otp_access_absolute(struct iwl_trans *trans) +{ + iwl_read32(trans, CSR_OTP_GP_REG); + + iwl_clear_bit(trans, CSR_OTP_GP_REG, + CSR_OTP_GP_REG_OTP_ACCESS_MODE); +} + +static int iwl_nvm_is_otp(struct iwl_trans *trans) +{ + u32 otpgp; + + /* OTP only valid for CP/PP and after */ + switch (trans->hw_rev & CSR_HW_REV_TYPE_MSK) { + case CSR_HW_REV_TYPE_NONE: + IWL_ERR(trans, "Unknown hardware type\n"); + return -EIO; + case CSR_HW_REV_TYPE_5300: + case CSR_HW_REV_TYPE_5350: + case CSR_HW_REV_TYPE_5100: + case CSR_HW_REV_TYPE_5150: + return 0; + default: + otpgp = iwl_read32(trans, CSR_OTP_GP_REG); + if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) + return 1; + return 0; + } +} + +static int iwl_init_otp_access(struct iwl_trans *trans) +{ + int ret; + + /* Enable 40MHz radio clock */ + iwl_write32(trans, CSR_GP_CNTRL, + iwl_read32(trans, CSR_GP_CNTRL) | + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + + /* wait for clock to be ready */ + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + 25000); + if (ret < 0) { + IWL_ERR(trans, "Time out access OTP\n"); + } else { + iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_RESET_REQ); + udelay(5); + iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_RESET_REQ); + + /* + * CSR auto clock gate disable bit - + * this is only applicable for HW with OTP shadow RAM + */ + if (trans->cfg->base_params->shadow_ram_support) + iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, + CSR_RESET_LINK_PWR_MGMT_DISABLED); + } + return ret; +} + +static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, + __le16 *eeprom_data) +{ + int ret = 0; + u32 r; + u32 otpgp; + + iwl_write32(trans, CSR_EEPROM_REG, + CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); + ret = iwl_poll_bit(trans, CSR_EEPROM_REG, + CSR_EEPROM_REG_READ_VALID_MSK, + CSR_EEPROM_REG_READ_VALID_MSK, + IWL_EEPROM_ACCESS_TIMEOUT); + if (ret < 0) { + IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); + return ret; + } + r = iwl_read32(trans, CSR_EEPROM_REG); + /* check for ECC errors: */ + otpgp = iwl_read32(trans, CSR_OTP_GP_REG); + if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { + /* stop in this case */ + /* set the uncorrectable OTP ECC bit for acknowledgement */ + iwl_set_bit(trans, CSR_OTP_GP_REG, + CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); + IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); + return -EINVAL; + } + if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { + /* continue in this case */ + /* set the correctable OTP ECC bit for acknowledgement */ + iwl_set_bit(trans, CSR_OTP_GP_REG, + CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); + IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); + } + *eeprom_data = cpu_to_le16(r >> 16); + return 0; +} + +/* + * iwl_is_otp_empty: check for empty OTP + */ +static bool iwl_is_otp_empty(struct iwl_trans *trans) +{ + u16 next_link_addr = 0; + __le16 link_value; + bool is_empty = false; + + /* locate the beginning of OTP link list */ + if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { + if (!link_value) { + IWL_ERR(trans, "OTP is empty\n"); + is_empty = true; + } + } else { + IWL_ERR(trans, "Unable to read first block of OTP list.\n"); + is_empty = true; + } + + return is_empty; +} + + +/* + * iwl_find_otp_image: find EEPROM image in OTP + * finding the OTP block that contains the EEPROM image. + * the last valid block on the link list (the block _before_ the last block) + * is the block we should read and used to configure the device. + * If all the available OTP blocks are full, the last block will be the block + * we should read and used to configure the device. + * only perform this operation if shadow RAM is disabled + */ +static int iwl_find_otp_image(struct iwl_trans *trans, + u16 *validblockaddr) +{ + u16 next_link_addr = 0, valid_addr; + __le16 link_value = 0; + int usedblocks = 0; + + /* set addressing mode to absolute to traverse the link list */ + iwl_set_otp_access_absolute(trans); + + /* checking for empty OTP or error */ + if (iwl_is_otp_empty(trans)) + return -EINVAL; + + /* + * start traverse link list + * until reach the max number of OTP blocks + * different devices have different number of OTP blocks + */ + do { + /* save current valid block address + * check for more block on the link list + */ + valid_addr = next_link_addr; + next_link_addr = le16_to_cpu(link_value) * sizeof(u16); + IWL_DEBUG_EEPROM(trans->dev, "OTP blocks %d addr 0x%x\n", + usedblocks, next_link_addr); + if (iwl_read_otp_word(trans, next_link_addr, &link_value)) + return -EINVAL; + if (!link_value) { + /* + * reach the end of link list, return success and + * set address point to the starting address + * of the image + */ + *validblockaddr = valid_addr; + /* skip first 2 bytes (link list pointer) */ + *validblockaddr += 2; + return 0; + } + /* more in the link list, continue */ + usedblocks++; + } while (usedblocks <= trans->cfg->base_params->max_ll_items); + + /* OTP has no valid blocks */ + IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n"); + return -EINVAL; +} + +/** + * iwl_read_eeprom - read EEPROM contents + * + * Load the EEPROM contents from adapter and return it + * and its size. + * + * NOTE: This routine uses the non-debug IO access functions. + */ +int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) +{ + __le16 *e; + u32 gp = iwl_read32(trans, CSR_EEPROM_GP); + int sz; + int ret; + u16 addr; + u16 validblockaddr = 0; + u16 cache_addr = 0; + int nvm_is_otp; + + if (!eeprom || !eeprom_size) + return -EINVAL; + + nvm_is_otp = iwl_nvm_is_otp(trans); + if (nvm_is_otp < 0) + return nvm_is_otp; + + sz = trans->cfg->base_params->eeprom_size; + IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); + + e = kmalloc(sz, GFP_KERNEL); + if (!e) + return -ENOMEM; + + ret = iwl_eeprom_verify_signature(trans, nvm_is_otp); + if (ret < 0) { + IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); + goto err_free; + } + + /* Make sure driver (instead of uCode) is allowed to read EEPROM */ + ret = iwl_eeprom_acquire_semaphore(trans); + if (ret < 0) { + IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); + goto err_free; + } + + if (nvm_is_otp) { + ret = iwl_init_otp_access(trans); + if (ret) { + IWL_ERR(trans, "Failed to initialize OTP access.\n"); + goto err_unlock; + } + + iwl_write32(trans, CSR_EEPROM_GP, + iwl_read32(trans, CSR_EEPROM_GP) & + ~CSR_EEPROM_GP_IF_OWNER_MSK); + + iwl_set_bit(trans, CSR_OTP_GP_REG, + CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | + CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); + /* traversing the linked list if no shadow ram supported */ + if (!trans->cfg->base_params->shadow_ram_support) { + ret = iwl_find_otp_image(trans, &validblockaddr); + if (ret) + goto err_unlock; + } + for (addr = validblockaddr; addr < validblockaddr + sz; + addr += sizeof(u16)) { + __le16 eeprom_data; + + ret = iwl_read_otp_word(trans, addr, &eeprom_data); + if (ret) + goto err_unlock; + e[cache_addr / 2] = eeprom_data; + cache_addr += sizeof(u16); + } + } else { + /* eeprom is an array of 16bit values */ + for (addr = 0; addr < sz; addr += sizeof(u16)) { + u32 r; + + iwl_write32(trans, CSR_EEPROM_REG, + CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); + + ret = iwl_poll_bit(trans, CSR_EEPROM_REG, + CSR_EEPROM_REG_READ_VALID_MSK, + CSR_EEPROM_REG_READ_VALID_MSK, + IWL_EEPROM_ACCESS_TIMEOUT); + if (ret < 0) { + IWL_ERR(trans, + "Time out reading EEPROM[%d]\n", addr); + goto err_unlock; + } + r = iwl_read32(trans, CSR_EEPROM_REG); + e[addr / 2] = cpu_to_le16(r >> 16); + } + } + + IWL_DEBUG_EEPROM(trans->dev, "NVM Type: %s\n", + nvm_is_otp ? "OTP" : "EEPROM"); + + iwl_eeprom_release_semaphore(trans); + + *eeprom_size = sz; + *eeprom = (u8 *)e; + return 0; + + err_unlock: + iwl_eeprom_release_semaphore(trans); + err_free: + kfree(e); + + return ret; +} +EXPORT_SYMBOL_GPL(iwl_read_eeprom); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h new file mode 100644 index 000000000000..1337c9d36fee --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_eeprom_h__ +#define __iwl_eeprom_h__ + +#include "iwl-trans.h" + +int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size); + +#endif /* __iwl_eeprom_h__ */ diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c index 174cf5e38962..0269ea6a5c35 100644 --- a/drivers/net/wireless/iwlwifi/pcie/1000.c +++ b/drivers/net/wireless/iwlwifi/pcie/1000.c @@ -74,6 +74,18 @@ static const struct iwl_ht_params iwl1000_ht_params = { .ht40_bands = BIT(IEEE80211_BAND_2GHZ), }; +static const struct iwl_eeprom_params iwl1000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + } +}; + #define IWL_DEVICE_1000 \ .fw_name_pre = IWL1000_FW_PRE, \ .ucode_api_max = IWL1000_UCODE_API_MAX, \ @@ -85,6 +97,7 @@ static const struct iwl_ht_params iwl1000_ht_params = { .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ .base_params = &iwl1000_base_params, \ + .eeprom_params = &iwl1000_eeprom_params, \ .led_mode = IWL_LED_BLINK const struct iwl_cfg iwl1000_bgn_cfg = { @@ -109,6 +122,7 @@ const struct iwl_cfg iwl1000_bg_cfg = { .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ .base_params = &iwl1000_base_params, \ + .eeprom_params = &iwl1000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c index 8d4d7295aa46..fd4e78f56fa6 100644 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c @@ -117,6 +117,19 @@ static const struct iwl_bt_params iwl2030_bt_params = { .bt_session_2 = true, }; +static const struct iwl_eeprom_params iwl20x0_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + }, + .enhanced_txpower = true, +}; + #define IWL_DEVICE_2000 \ .fw_name_pre = IWL2000_FW_PRE, \ .ucode_api_max = IWL2000_UCODE_API_MAX, \ @@ -128,6 +141,7 @@ static const struct iwl_bt_params iwl2030_bt_params = { .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .base_params = &iwl2000_base_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ .need_temp_offset_calib = true, \ .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE @@ -156,6 +170,7 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .base_params = &iwl2030_base_params, \ .bt_params = &iwl2030_bt_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ .need_temp_offset_calib = true, \ .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ @@ -178,6 +193,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .base_params = &iwl2000_base_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ .need_temp_offset_calib = true, \ .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ @@ -208,6 +224,7 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .base_params = &iwl2030_base_params, \ .bt_params = &iwl2030_bt_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ .need_temp_offset_calib = true, \ .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c index 75d90a9c184a..745a358ab8e8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/5000.c +++ b/drivers/net/wireless/iwlwifi/pcie/5000.c @@ -72,6 +72,18 @@ static const struct iwl_ht_params iwl5000_ht_params = { .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), }; +static const struct iwl_eeprom_params iwl5000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, +}; + #define IWL_DEVICE_5000 \ .fw_name_pre = IWL5000_FW_PRE, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \ @@ -83,6 +95,7 @@ static const struct iwl_ht_params iwl5000_ht_params = { .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ .base_params = &iwl5000_base_params, \ + .eeprom_params = &iwl5000_eeprom_params, \ .led_mode = IWL_LED_BLINK const struct iwl_cfg iwl5300_agn_cfg = { @@ -129,6 +142,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, .base_params = &iwl5000_base_params, + .eeprom_params = &iwl5000_eeprom_params, .ht_params = &iwl5000_ht_params, .led_mode = IWL_LED_BLINK, .internal_wimax_coex = true, @@ -145,6 +159,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ .base_params = &iwl5000_base_params, \ + .eeprom_params = &iwl5000_eeprom_params, \ .no_xtal_calib = true, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c index 7b9c02cc67e5..8dd8a6fe61e8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c @@ -136,6 +136,19 @@ static const struct iwl_bt_params iwl6000_bt_params = { .bt_sco_disable = true, }; +static const struct iwl_eeprom_params iwl6000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, + .enhanced_txpower = true, +}; + #define IWL_DEVICE_6005 \ .fw_name_pre = IWL6005_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ @@ -147,6 +160,7 @@ static const struct iwl_bt_params iwl6000_bt_params = { .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ .base_params = &iwl6000_g2_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE @@ -202,6 +216,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ .base_params = &iwl6000_g2_base_params, \ .bt_params = &iwl6000_bt_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true \ @@ -274,6 +289,7 @@ const struct iwl_cfg iwl130_bg_cfg = { .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ .base_params = &iwl6000_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK const struct iwl_cfg iwl6000i_2agn_cfg = { @@ -304,6 +320,7 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ .base_params = &iwl6050_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true @@ -328,6 +345,7 @@ const struct iwl_cfg iwl6050_2abg_cfg = { .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ .base_params = &iwl6050_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true @@ -354,6 +372,7 @@ const struct iwl_cfg iwl6000_3agn_cfg = { .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .base_params = &iwl6000_base_params, + .eeprom_params = &iwl6000_eeprom_params, .ht_params = &iwl6000_ht_params, .led_mode = IWL_LED_BLINK, }; -- GitLab From 6de4902ee8e07252d335b16810cb73432cf0d514 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 30 May 2012 09:14:41 +0200 Subject: [PATCH 0728/6849] iwlwifi: fix typo 'IWL_WATCHHDOG_DISABLED' Commit 7c5ba4a830cbb730770129b0004e2a06e47dbac5 ("iwlwifi: move queue watchdog into transport") introduced the named constant 'IWL_WATCHHDOG_DISABLED'. Rename it to 'IWL_WATCHDOG_DISABLED'. Signed-off-by: Paul Bolle Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/main.c | 2 +- drivers/net/wireless/iwlwifi/iwl-config.h | 2 +- drivers/net/wireless/iwlwifi/pcie/1000.c | 2 +- drivers/net/wireless/iwlwifi/pcie/5000.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index ebdc8b93bc04..c91b66c77972 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -1347,7 +1347,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, trans_cfg.queue_watchdog_timeout = priv->cfg->base_params->wd_timeout; else - trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED; + trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; trans_cfg.command_names = iwl_dvm_cmd_strings; ucode_flags = fw->ucode_capa.flags; diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index e9accfccc050..10e47938b635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -113,7 +113,7 @@ enum iwl_led_mode { #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE 0 /* TX queue watchdog timeouts in mSecs */ -#define IWL_WATCHHDOG_DISABLED 0 +#define IWL_WATCHDOG_DISABLED 0 #define IWL_DEF_WD_TIMEOUT 2000 #define IWL_LONG_WD_TIMEOUT 10000 #define IWL_MAX_WD_TIMEOUT 120000 diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c index 0269ea6a5c35..81b83f484f08 100644 --- a/drivers/net/wireless/iwlwifi/pcie/1000.c +++ b/drivers/net/wireless/iwlwifi/pcie/1000.c @@ -64,7 +64,7 @@ static const struct iwl_base_params iwl1000_base_params = { .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, - .wd_timeout = IWL_WATCHHDOG_DISABLED, + .wd_timeout = IWL_WATCHDOG_DISABLED, .max_event_log_size = 128, }; diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c index 745a358ab8e8..d1665fa6d15a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/5000.c +++ b/drivers/net/wireless/iwlwifi/pcie/5000.c @@ -62,7 +62,7 @@ static const struct iwl_base_params iwl5000_base_params = { .led_compensation = 51, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, - .wd_timeout = IWL_WATCHHDOG_DISABLED, + .wd_timeout = IWL_WATCHDOG_DISABLED, .max_event_log_size = 512, .no_idle_support = true, }; -- GitLab From 12b78246aa49b72f665601fdc7a44eb75fcf593b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 May 2012 12:31:23 +0200 Subject: [PATCH 0729/6849] iwlwifi: configure PHY version for 1000 series We should also configure the PHY version in the CSR_HW_IF_CONFIG_REG register for 1000 series devices, not just for the other devices. Reviewed-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/devices.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 747e576950f4..d12f0631b67a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -96,10 +96,7 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 1000 series */ static void iwl1000_nic_config(struct iwl_priv *priv) { - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + iwl_rf_config(priv); /* Setting digital SVR for 1000 card to 1.32V */ /* locking is acquired in iwl_set_bits_mask_prph() function */ -- GitLab From 1280d428ad0f134d1e370a0a0b70793ebcf56742 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 May 2012 12:36:23 +0200 Subject: [PATCH 0730/6849] iwlwifi: move RF config into NIC config Since the RF config is done for all devices, there's no need to keep a separate function that is called for all devices, move it into the general NIC config function. Reviewed-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/devices.c | 43 ---------------------- drivers/net/wireless/iwlwifi/dvm/main.c | 31 ++++++++++++++++ 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index d12f0631b67a..0521a6be09d2 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -36,41 +36,6 @@ #include "commands.h" -#define EEPROM_RF_CONFIG_TYPE_MAX 0x3 - -static void iwl_rf_config(struct iwl_priv *priv) -{ - u16 radio_cfg = priv->eeprom_data->radio_cfg; - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - u32 reg_val = - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << - CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) << - CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | - EEPROM_RF_CFG_DASH_MSK(radio_cfg) << - CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; - - iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | - CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | - CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); - - IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", - EEPROM_RF_CFG_TYPE_MSK(radio_cfg), - EEPROM_RF_CFG_STEP_MSK(radio_cfg), - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - } else { - WARN_ON(1); - } - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); -} - /* * 1000 series * =========== @@ -96,8 +61,6 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 1000 series */ static void iwl1000_nic_config(struct iwl_priv *priv) { - iwl_rf_config(priv); - /* Setting digital SVR for 1000 card to 1.32V */ /* locking is acquired in iwl_set_bits_mask_prph() function */ iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG, @@ -233,8 +196,6 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 2000 series */ static void iwl2000_nic_config(struct iwl_priv *priv) { - iwl_rf_config(priv); - iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); } @@ -291,8 +252,6 @@ struct iwl_lib_ops iwl2030_lib = { /* NIC configuration for 5000 series */ static void iwl5000_nic_config(struct iwl_priv *priv) { - iwl_rf_config(priv); - /* W/A : NIC is stuck in a reset state after Early PCIe power off * (PCIe power is lost before PERST# is asserted), * causing ME FW to lose ownership and not being able to obtain it back. @@ -502,8 +461,6 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { - iwl_rf_config(priv); - switch (priv->cfg->device_family) { case IWL_DEVICE_FAMILY_6005: case IWL_DEVICE_FAMILY_6030: diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index c91b66c77972..ec0b77b862a8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2027,9 +2027,12 @@ static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) } } +#define EEPROM_RF_CONFIG_TYPE_MAX 0x3 + static void iwl_nic_config(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + u16 radio_cfg = priv->eeprom_data->radio_cfg; /* SKU Control */ iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, @@ -2040,6 +2043,34 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode) (CSR_HW_REV_DASH(priv->trans->hw_rev) << CSR_HW_IF_CONFIG_REG_POS_MAC_DASH)); + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { + u32 reg_val = + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | + EEPROM_RF_CFG_DASH_MSK(radio_cfg) << + CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; + + iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | + CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | + CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); + + IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", + EEPROM_RF_CFG_TYPE_MSK(radio_cfg), + EEPROM_RF_CFG_STEP_MSK(radio_cfg), + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + } else { + WARN_ON(1); + } + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + priv->lib->nic_config(priv); } -- GitLab From b1abedada3fd0aa100723aa9b60b7e31c17945cb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 31 May 2012 13:54:56 +0200 Subject: [PATCH 0731/6849] iwlwifi: remove extern opmode ops declarations There's no need to declare the opmode ops as extern since they're now dynamically registered. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/main.c | 4 +++- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 5 ----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index ec0b77b862a8..1c2d0233a405 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -81,6 +81,8 @@ MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); +static const struct iwl_op_mode_ops iwl_dvm_ops; + void iwl_update_chain_flags(struct iwl_priv *priv) { struct iwl_rxon_context *ctx; @@ -2163,7 +2165,7 @@ static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); } -const struct iwl_op_mode_ops iwl_dvm_ops = { +static const struct iwl_op_mode_ops iwl_dvm_ops = { .start = iwl_op_mode_dvm_start, .stop = iwl_op_mode_dvm_stop, .rx = iwl_rx_dispatch, diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index cec133c87ad8..cd9ef114d3a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -221,9 +221,4 @@ static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) op_mode->ops->wimax_active(op_mode); } -/***************************************************** -* Op mode layers implementations -******************************************************/ -extern const struct iwl_op_mode_ops iwl_dvm_ops; - #endif /* __iwl_op_mode_h__ */ -- GitLab From ec44bc7acc3687ba6ae8154b4b5a845b70279237 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 25 May 2012 22:08:57 +0000 Subject: [PATCH 0732/6849] timers: Create detach_if_pending() and use it Most callers of detach_timer() have the same pattern around them. Check whether the timer is pending and eventually updating base->next_timer. Create detach_if_pending() and replace the duplicated code. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Gilad Ben-Yossef Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/20120525214819.131246037@linutronix.de --- kernel/timer.c | 56 +++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index 6ec7e7e0db43..0f70deb20151 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -654,8 +654,7 @@ void init_timer_deferrable_key(struct timer_list *timer, } EXPORT_SYMBOL(init_timer_deferrable_key); -static inline void detach_timer(struct timer_list *timer, - int clear_pending) +static inline void detach_timer(struct timer_list *timer, bool clear_pending) { struct list_head *entry = &timer->entry; @@ -667,6 +666,19 @@ static inline void detach_timer(struct timer_list *timer, entry->prev = LIST_POISON2; } +static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, + bool clear_pending) +{ + if (!timer_pending(timer)) + return 0; + + detach_timer(timer, clear_pending); + if (timer->expires == base->next_timer && + !tbase_get_deferrable(timer->base)) + base->next_timer = base->timer_jiffies; + return 1; +} + /* * We are using hashed locking: holding per_cpu(tvec_bases).lock * means that all timers which are tied to this base via timer->base are @@ -712,16 +724,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires, base = lock_timer_base(timer, &flags); - if (timer_pending(timer)) { - detach_timer(timer, 0); - if (timer->expires == base->next_timer && - !tbase_get_deferrable(timer->base)) - base->next_timer = base->timer_jiffies; - ret = 1; - } else { - if (pending_only) - goto out_unlock; - } + ret = detach_if_pending(timer, base, false); + if (!ret && pending_only) + goto out_unlock; debug_activate(timer, expires); @@ -959,13 +964,7 @@ int del_timer(struct timer_list *timer) timer_stats_timer_clear_start_info(timer); if (timer_pending(timer)) { base = lock_timer_base(timer, &flags); - if (timer_pending(timer)) { - detach_timer(timer, 1); - if (timer->expires == base->next_timer && - !tbase_get_deferrable(timer->base)) - base->next_timer = base->timer_jiffies; - ret = 1; - } + ret = detach_if_pending(timer, base, true); spin_unlock_irqrestore(&base->lock, flags); } @@ -990,19 +989,10 @@ int try_to_del_timer_sync(struct timer_list *timer) base = lock_timer_base(timer, &flags); - if (base->running_timer == timer) - goto out; - - timer_stats_timer_clear_start_info(timer); - ret = 0; - if (timer_pending(timer)) { - detach_timer(timer, 1); - if (timer->expires == base->next_timer && - !tbase_get_deferrable(timer->base)) - base->next_timer = base->timer_jiffies; - ret = 1; + if (base->running_timer != timer) { + timer_stats_timer_clear_start_info(timer); + ret = detach_if_pending(timer, base, true); } -out: spin_unlock_irqrestore(&base->lock, flags); return ret; @@ -1178,7 +1168,7 @@ static inline void __run_timers(struct tvec_base *base) timer_stats_account_timer(timer); base->running_timer = timer; - detach_timer(timer, 1); + detach_timer(timer, true); spin_unlock_irq(&base->lock); call_timer_fn(timer, fn, data); @@ -1714,7 +1704,7 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea while (!list_empty(head)) { timer = list_first_entry(head, struct timer_list, entry); - detach_timer(timer, 0); + detach_timer(timer, false); timer_set_base(timer, new_base); if (time_before(timer->expires, new_base->next_timer) && !tbase_get_deferrable(timer->base)) -- GitLab From facbb4a7efbd658046bf615f03cd97a1504785d8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 25 May 2012 22:08:57 +0000 Subject: [PATCH 0733/6849] timers: Consolidate base->next_timer update Another bunch of mindlessly copied code. All callers of internal_add_timer() except the recascading code updates base->next_timer. Move this into internal_add_timer() and let the cascading code call __internal_add_timer(). Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Gilad Ben-Yossef Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/20120525214819.189946224@linutronix.de --- kernel/timer.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index 0f70deb20151..7207690b5353 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -330,7 +330,8 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) } EXPORT_SYMBOL_GPL(set_timer_slack); -static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) +static void +__internal_add_timer(struct tvec_base *base, struct timer_list *timer) { unsigned long expires = timer->expires; unsigned long idx = expires - base->timer_jiffies; @@ -372,6 +373,17 @@ static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) list_add_tail(&timer->entry, vec); } +static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) +{ + __internal_add_timer(base, timer); + /* + * Update base->next_timer if this is the earliest one. + */ + if (time_before(timer->expires, base->next_timer) && + !tbase_get_deferrable(timer->base)) + base->next_timer = timer->expires; +} + #ifdef CONFIG_TIMER_STATS void __timer_stats_timer_set_start_info(struct timer_list *timer, void *addr) { @@ -757,9 +769,6 @@ __mod_timer(struct timer_list *timer, unsigned long expires, } timer->expires = expires; - if (time_before(timer->expires, base->next_timer) && - !tbase_get_deferrable(timer->base)) - base->next_timer = timer->expires; internal_add_timer(base, timer); out_unlock: @@ -925,9 +934,6 @@ void add_timer_on(struct timer_list *timer, int cpu) spin_lock_irqsave(&base->lock, flags); timer_set_base(timer, base); debug_activate(timer, timer->expires); - if (time_before(timer->expires, base->next_timer) && - !tbase_get_deferrable(timer->base)) - base->next_timer = timer->expires; internal_add_timer(base, timer); /* * Check whether the other CPU is idle and needs to be @@ -1079,7 +1085,8 @@ static int cascade(struct tvec_base *base, struct tvec *tv, int index) */ list_for_each_entry_safe(timer, tmp, &tv_list, entry) { BUG_ON(tbase_get_base(timer->base) != base); - internal_add_timer(base, timer); + /* No accounting, while moving them */ + __internal_add_timer(base, timer); } return index; @@ -1706,9 +1713,6 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea timer = list_first_entry(head, struct timer_list, entry); detach_timer(timer, false); timer_set_base(timer, new_base); - if (time_before(timer->expires, new_base->next_timer) && - !tbase_get_deferrable(timer->base)) - new_base->next_timer = timer->expires; internal_add_timer(new_base, timer); } } -- GitLab From 99d5f3aac674fe081ffddd2dbb8946ccbc14c410 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 25 May 2012 22:08:58 +0000 Subject: [PATCH 0734/6849] timers: Add accounting of non deferrable timers The code in get_next_timer_interrupt() is suboptimal as it has to run through the cascade to find the next expiring timer. On a completely idle core we should only do that when there is an active timer enqueued and base->next_timer does not give us a fast answer. Add accounting of the active timers to the now consolidated attach/detach code. I deliberately avoided sanity checks because the code is fully symetric and any fiddling with timers w/o using the API functions will lead to cute explosions anyway. ulong is big enough even on 32bit and if we really run into the situation to have more than 1<<32 timers enqueued there, then we are definitely not in a state to go idle and run through that code. This allows us to fix another shortcoming of get_next_timer_interrupt(). Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Gilad Ben-Yossef Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/20120525214819.236377028@linutronix.de --- kernel/timer.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index 7207690b5353..7fada698bd1a 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -77,6 +77,7 @@ struct tvec_base { struct timer_list *running_timer; unsigned long timer_jiffies; unsigned long next_timer; + unsigned long active_timers; struct tvec_root tv1; struct tvec tv2; struct tvec tv3; @@ -377,11 +378,13 @@ static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) { __internal_add_timer(base, timer); /* - * Update base->next_timer if this is the earliest one. + * Update base->active_timers and base->next_timer */ - if (time_before(timer->expires, base->next_timer) && - !tbase_get_deferrable(timer->base)) - base->next_timer = timer->expires; + if (!tbase_get_deferrable(timer->base)) { + if (time_before(timer->expires, base->next_timer)) + base->next_timer = timer->expires; + base->active_timers++; + } } #ifdef CONFIG_TIMER_STATS @@ -678,6 +681,14 @@ static inline void detach_timer(struct timer_list *timer, bool clear_pending) entry->prev = LIST_POISON2; } +static inline void +detach_expired_timer(struct timer_list *timer, struct tvec_base *base) +{ + detach_timer(timer, true); + if (!tbase_get_deferrable(timer->base)) + timer->base->active_timers--; +} + static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, bool clear_pending) { @@ -685,9 +696,11 @@ static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, return 0; detach_timer(timer, clear_pending); - if (timer->expires == base->next_timer && - !tbase_get_deferrable(timer->base)) - base->next_timer = base->timer_jiffies; + if (!tbase_get_deferrable(timer->base)) { + timer->base->active_timers--; + if (timer->expires == base->next_timer) + base->next_timer = base->timer_jiffies; + } return 1; } @@ -1175,7 +1188,7 @@ static inline void __run_timers(struct tvec_base *base) timer_stats_account_timer(timer); base->running_timer = timer; - detach_timer(timer, true); + detach_expired_timer(timer, base); spin_unlock_irq(&base->lock); call_timer_fn(timer, fn, data); @@ -1701,6 +1714,7 @@ static int __cpuinit init_timers_cpu(int cpu) base->timer_jiffies = jiffies; base->next_timer = base->timer_jiffies; + base->active_timers = 0; return 0; } @@ -1711,6 +1725,7 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea while (!list_empty(head)) { timer = list_first_entry(head, struct timer_list, entry); + /* We ignore the accounting on the dying cpu */ detach_timer(timer, false); timer_set_base(timer, new_base); internal_add_timer(new_base, timer); -- GitLab From e40468a54882ef7411fb178dbf2e465ec2349af7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 25 May 2012 22:08:59 +0000 Subject: [PATCH 0735/6849] timers: Improve get_next_timer_interrupt() Gilad reported at http://lkml.kernel.org/r/1336056962-10465-2-git-send-email-gilad@benyossef.com "Current timer code fails to correctly return a value meaning that there is no future timer event, with the result that the timer keeps getting re-armed in HZ one shot mode even when we could turn it off, generating unneeded interrupts. What is happening is that when __next_timer_interrupt() wishes to return a value that signifies "there is no future timer event", it returns (base->timer_jiffies + NEXT_TIMER_MAX_DELTA). However, the code in tick_nohz_stop_sched_tick(), which called __next_timer_interrupt() via get_next_timer_interrupt(), compares the return value to (last_jiffies + NEXT_TIMER_MAX_DELTA) to see if the timer needs to be re-armed. base->timer_jiffies != last_jiffies and so tick_nohz_stop_sched_tick() interperts the return value as indication that there is a distant future event 12 days from now and programs the timer to fire next after KTIME_MAX nsecs instead of avoiding to arm it. This ends up causing a needless interrupt once every KTIME_MAX nsecs." Fix this by using the new active timer accounting. This avoids scans when no active timer is enqueued completely, so we don't have to rely on base->timer_next and base->timer_jiffies anymore. Reported-by: Gilad Ben-Yossef Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/20120525214819.317535385@linutronix.de --- kernel/timer.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index 7fada698bd1a..a61c09374eba 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1326,18 +1326,21 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now, unsigned long get_next_timer_interrupt(unsigned long now) { struct tvec_base *base = __this_cpu_read(tvec_bases); - unsigned long expires; + unsigned long expires = now + NEXT_TIMER_MAX_DELTA; /* * Pretend that there is no timer pending if the cpu is offline. * Possible pending timers will be migrated later to an active cpu. */ if (cpu_is_offline(smp_processor_id())) - return now + NEXT_TIMER_MAX_DELTA; + return expires; + spin_lock(&base->lock); - if (time_before_eq(base->next_timer, base->timer_jiffies)) - base->next_timer = __next_timer_interrupt(base); - expires = base->next_timer; + if (base->active_timers) { + if (time_before_eq(base->next_timer, base->timer_jiffies)) + base->next_timer = __next_timer_interrupt(base); + expires = base->next_timer; + } spin_unlock(&base->lock); if (time_before_eq(expires, now)) -- GitLab From a737f256bf14adf94920aa70d150ab4dcd145109 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Sun, 3 Jun 2012 21:17:48 +0300 Subject: [PATCH 0736/6849] KVM: Cleanup the kvm_print functions and introduce pr_XX wrappers Introduces a couple of print functions, which are essentially wrappers around standard printk functions, with a KVM: prefix. Functions introduced or modified are: - kvm_err(fmt, ...) - kvm_info(fmt, ...) - kvm_debug(fmt, ...) - kvm_pr_unimpl(fmt, ...) - pr_unimpl(vcpu, fmt, ...) -> vcpu_unimpl(vcpu, fmt, ...) Signed-off-by: Christoffer Dall Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 6 ++--- arch/x86/kvm/vmx.c | 2 +- arch/x86/kvm/x86.c | 54 ++++++++++++++++++++-------------------- include/linux/kvm_host.h | 18 +++++++++----- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f75af406b268..7a418783259d 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3185,8 +3185,8 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) break; case MSR_IA32_DEBUGCTLMSR: if (!boot_cpu_has(X86_FEATURE_LBRV)) { - pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n", - __func__, data); + vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n", + __func__, data); break; } if (data & DEBUGCTL_RESERVED_BITS) @@ -3205,7 +3205,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) case MSR_VM_CR: return svm_set_vm_cr(vcpu, data); case MSR_VM_IGNNE: - pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); + vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); break; default: return kvm_set_msr_common(vcpu, ecx, data); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f78662ec8677..eeeb4a25aed6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4549,7 +4549,7 @@ static int handle_cr(struct kvm_vcpu *vcpu) break; } vcpu->run->exit_reason = 0; - pr_unimpl(vcpu, "unhandled control register: op %d cr %d\n", + vcpu_unimpl(vcpu, "unhandled control register: op %d cr %d\n", (int)(exit_qualification >> 4) & 3, cr); return 0; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f12a52408cda..a01a4241bc6b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1437,8 +1437,8 @@ static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data) break; } default: - pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x " - "data 0x%llx\n", msr, data); + vcpu_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x " + "data 0x%llx\n", msr, data); return 1; } return 0; @@ -1470,8 +1470,8 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data) case HV_X64_MSR_TPR: return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data); default: - pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x " - "data 0x%llx\n", msr, data); + vcpu_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x " + "data 0x%llx\n", msr, data); return 1; } @@ -1551,15 +1551,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) data &= ~(u64)0x100; /* ignore ignne emulation enable */ data &= ~(u64)0x8; /* ignore TLB cache disable */ if (data != 0) { - pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n", - data); + vcpu_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n", + data); return 1; } break; case MSR_FAM10H_MMIO_CONF_BASE: if (data != 0) { - pr_unimpl(vcpu, "unimplemented MMIO_CONF_BASE wrmsr: " - "0x%llx\n", data); + vcpu_unimpl(vcpu, "unimplemented MMIO_CONF_BASE wrmsr: " + "0x%llx\n", data); return 1; } break; @@ -1574,8 +1574,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) thus reserved and should throw a #GP */ return 1; } - pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n", - __func__, data); + vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n", + __func__, data); break; case MSR_IA32_UCODE_REV: case MSR_IA32_UCODE_WRITE: @@ -1671,8 +1671,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_K7_EVNTSEL2: case MSR_K7_EVNTSEL3: if (data != 0) - pr_unimpl(vcpu, "unimplemented perfctr wrmsr: " - "0x%x data 0x%llx\n", msr, data); + vcpu_unimpl(vcpu, "unimplemented perfctr wrmsr: " + "0x%x data 0x%llx\n", msr, data); break; /* at least RHEL 4 unconditionally writes to the perfctr registers, * so we ignore writes to make it happy. @@ -1681,8 +1681,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_K7_PERFCTR1: case MSR_K7_PERFCTR2: case MSR_K7_PERFCTR3: - pr_unimpl(vcpu, "unimplemented perfctr wrmsr: " - "0x%x data 0x%llx\n", msr, data); + vcpu_unimpl(vcpu, "unimplemented perfctr wrmsr: " + "0x%x data 0x%llx\n", msr, data); break; case MSR_P6_PERFCTR0: case MSR_P6_PERFCTR1: @@ -1693,8 +1693,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) return kvm_pmu_set_msr(vcpu, msr, data); if (pr || data != 0) - pr_unimpl(vcpu, "disabled perfctr wrmsr: " - "0x%x data 0x%llx\n", msr, data); + vcpu_unimpl(vcpu, "disabled perfctr wrmsr: " + "0x%x data 0x%llx\n", msr, data); break; case MSR_K7_CLK_CTL: /* @@ -1720,7 +1720,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) /* Drop writes to this legacy MSR -- see rdmsr * counterpart for further detail. */ - pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", msr, data); + vcpu_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", msr, data); break; case MSR_AMD64_OSVW_ID_LENGTH: if (!guest_cpuid_has_osvw(vcpu)) @@ -1738,12 +1738,12 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) if (kvm_pmu_msr(vcpu, msr)) return kvm_pmu_set_msr(vcpu, msr, data); if (!ignore_msrs) { - pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", - msr, data); + vcpu_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", + msr, data); return 1; } else { - pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", - msr, data); + vcpu_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", + msr, data); break; } } @@ -1846,7 +1846,7 @@ static int get_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) data = kvm->arch.hv_hypercall; break; default: - pr_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); + vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); return 1; } @@ -1877,7 +1877,7 @@ static int get_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) data = vcpu->arch.hv_vapic; break; default: - pr_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); + vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); return 1; } *pdata = data; @@ -2030,10 +2030,10 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) if (kvm_pmu_msr(vcpu, msr)) return kvm_pmu_get_msr(vcpu, msr, pdata); if (!ignore_msrs) { - pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); + vcpu_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); return 1; } else { - pr_unimpl(vcpu, "ignored rdmsr: 0x%x\n", msr); + vcpu_unimpl(vcpu, "ignored rdmsr: 0x%x\n", msr); data = 0; } break; @@ -4116,7 +4116,7 @@ static unsigned long emulator_get_cr(struct x86_emulate_ctxt *ctxt, int cr) value = kvm_get_cr8(vcpu); break; default: - vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); + kvm_err("%s: unexpected cr %u\n", __func__, cr); return 0; } @@ -4145,7 +4145,7 @@ static int emulator_set_cr(struct x86_emulate_ctxt *ctxt, int cr, ulong val) res = kvm_set_cr8(vcpu, val); break; default: - vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); + kvm_err("%s: unexpected cr %u\n", __func__, cr); res = -1; } diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 19b83f6efa49..27ac8a4767fa 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -314,13 +314,19 @@ struct kvm { long tlbs_dirty; }; -/* The guest did something we don't support. */ -#define pr_unimpl(vcpu, fmt, ...) \ - pr_err_ratelimited("kvm: %i: cpu%i " fmt, \ - current->tgid, (vcpu)->vcpu_id , ## __VA_ARGS__) +#define kvm_err(fmt, ...) \ + pr_err("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__) +#define kvm_info(fmt, ...) \ + pr_info("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__) +#define kvm_debug(fmt, ...) \ + pr_debug("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__) +#define kvm_pr_unimpl(fmt, ...) \ + pr_err_ratelimited("kvm [%i]: " fmt, \ + task_tgid_nr(current), ## __VA_ARGS__) -#define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt) -#define vcpu_printf(vcpu, fmt...) kvm_printf(vcpu->kvm, fmt) +/* The guest did something we don't support. */ +#define vcpu_unimpl(vcpu, fmt, ...) \ + kvm_pr_unimpl("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__) static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) { -- GitLab From 79f702a6d18c75760c68202007265b2310d6f44e Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 3 Jun 2012 11:34:08 +0300 Subject: [PATCH 0737/6849] KVM: disable uninitialized var warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I see this in 3.5-rc1: arch/x86/kvm/mmu.c: In function ‘kvm_test_age_rmapp’: arch/x86/kvm/mmu.c:1271: warning: ‘iter.desc’ may be used uninitialized in this function The line in question was introduced by commit 1e3f42f03c38c29c1814199a6f0a2f01b919ea3f static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, unsigned long data) { - u64 *spte; + u64 *sptep; + struct rmap_iterator iter; <- line 1271 int young = 0; /* The reason I think is that the compiler assumes that the rmap value could be 0, so static u64 *rmap_get_first(unsigned long rmap, struct rmap_iterator *iter) { if (!rmap) return NULL; if (!(rmap & 1)) { iter->desc = NULL; return (u64 *)rmap; } iter->desc = (struct pte_list_desc *)(rmap & ~1ul); iter->pos = 0; return iter->desc->sptes[iter->pos]; } will not initialize iter.desc, but the compiler isn't smart enough to see that for (sptep = rmap_get_first(*rmapp, &iter); sptep; sptep = rmap_get_next(&iter)) { will immediately exit in this case. I checked by adding if (!*rmapp) goto out; on top which is clearly equivalent but disables the warning. This patch uses uninitialized_var to disable the warning without increasing code size. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 1ca7164a74f1..24dd43d45ae4 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1238,7 +1238,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, unsigned long data) { u64 *sptep; - struct rmap_iterator iter; + struct rmap_iterator uninitialized_var(iter); int young = 0; /* -- GitLab From 693e5e2025278d90e1427f037e5ec8ea1ec7d5c4 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 6 Jun 2012 12:19:44 +0200 Subject: [PATCH 0738/6849] mmc: atmel-mci: fix burst/chunk size modification The use of DMA slave config operation requires that the burst size (aka chunk size) is specified through this interface. Modify atmel-mci slave driver to use this specification on its side. Signed-off-by: Nicolas Ferre Signed-off-by: Ludovic Desroches Signed-off-by: Chris Ball --- drivers/mmc/host/atmel-mci-regs.h | 14 ++++++++++++++ drivers/mmc/host/atmel-mci.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index 787aba1682bb..ab56f7db5315 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h @@ -140,4 +140,18 @@ #define atmci_writel(port,reg,value) \ __raw_writel((value), (port)->regs + reg) +/* + * Fix sconfig's burst size according to atmel MCI. We need to convert them as: + * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. + * + * This can be done by finding most significant bit set. + */ +static inline unsigned int atmci_convert_chksize(unsigned int maxburst) +{ + if (maxburst > 1) + return fls(maxburst) - 2; + else + return 0; +} + #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 456c077455cb..f2c115e06438 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -910,6 +910,7 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) enum dma_data_direction direction; enum dma_transfer_direction slave_dirn; unsigned int sglen; + u32 maxburst; u32 iflags; data->error = -EINPROGRESS; @@ -943,17 +944,18 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) if (!chan) return -ENODEV; - if (host->caps.has_dma) - atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN); - if (data->flags & MMC_DATA_READ) { direction = DMA_FROM_DEVICE; host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM; + maxburst = atmci_convert_chksize(host->dma_conf.src_maxburst); } else { direction = DMA_TO_DEVICE; host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV; + maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst); } + atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN); + sglen = dma_map_sg(chan->device->dev, data->sg, data->sg_len, direction); -- GitLab From 2a0fe914a38745f5b03534c4e4f4056cbd6978b8 Mon Sep 17 00:00:00 2001 From: Yong Ding Date: Tue, 15 May 2012 13:09:43 +0800 Subject: [PATCH 0739/6849] mmc: sdio: fix setting card data bus width as 4-bit SDIO_CCCR_IF[1:0] in SDIO card is used for card data bus width setting as below: 00b: 1-bit bus 01b: Reserved 10b: 4-bit bus 11b: 8-bit bus (only for embedded SDIO) And sdio_enable_wide is for setting data bus width as 4-bit. But currently, it first reads the register, second OR' 1b with SDIO_CCCR_IF[1], and then writes it back. As we can see, this is based on such assumption that the SDIO_CCCR_IF[0] is always 0. Apparently, this is not right. Signed-off-by: Yong Ding Acked-by: Philip Rakity Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 6 ++++++ include/linux/mmc/sdio.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 13d0e95380ab..41c5fd8848f4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -218,6 +218,12 @@ static int sdio_enable_wide(struct mmc_card *card) if (ret) return ret; + if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) + pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", + mmc_hostname(card->host), ctrl); + + /* set as 4-bit bus width */ + ctrl &= ~SDIO_BUS_WIDTH_MASK; ctrl |= SDIO_BUS_WIDTH_4BIT; ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index c9fe66c58f8f..17446d3c3602 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h @@ -98,7 +98,9 @@ #define SDIO_CCCR_IF 0x07 /* bus interface controls */ +#define SDIO_BUS_WIDTH_MASK 0x03 /* data bus width setting */ #define SDIO_BUS_WIDTH_1BIT 0x00 +#define SDIO_BUS_WIDTH_RESERVED 0x01 #define SDIO_BUS_WIDTH_4BIT 0x02 #define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */ #define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */ -- GitLab From eed6c63cefaf935e6fb28c4dd9977a280ae544a8 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Sun, 20 May 2012 13:27:21 +0900 Subject: [PATCH 0740/6849] mmc: dw_mmc: fix the transmission handling in IDMAC DTO interrupt can be later than transmit interrupt(IDMAC) in case of write. Current handling of IDMAC interrupt sets EVENT_DATA_COMPLETE as well as EVENT_XFER_COMPLETE regardless of DTO rising. This makes the current request finish in tasklet and permits the next request even though current data transfer is still in progress. As a result, sequence is broken and lock-up happens. Setting EVENT_DATA_COMPLETE is not proper after IDMAC interrupt. It should be taken after DTO interrupt is generated. Reported-by: Dmitry Shmidt Signed-off-by: Seungwon Jeon Signed-off-by: Hyeonsu Kim Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 9bbf45f8c538..b46faf0cfb27 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1623,7 +1623,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); - set_bit(EVENT_DATA_COMPLETE, &host->pending_events); host->dma_ops->complete(host); } #endif -- GitLab From 141a712a4eb09639dd4973a7c5e6999e3b8ae04a Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 22 May 2012 13:01:03 +0900 Subject: [PATCH 0741/6849] mmc: dw_mmc: fix the IDMAC sw reset IDMAC may not be cleaned in driver probe if it has been already used in boot time. So IDMAC needs sw reset newly. And DMA interface reset precedes the internal DMAC reset. Additionally SDMMC_IDMAC_SWRESET is replaced with magic code. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index b46faf0cfb27..98fe02347d59 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -418,6 +418,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) p->des3 = host->sg_dma; p->des0 = IDMAC_DES0_ER; + mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET); + /* Mask out interrupts - get Tx & Rx complete only */ mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); @@ -1724,7 +1726,8 @@ static void dw_mci_work_routine_card(struct work_struct *work) #ifdef CONFIG_MMC_DW_IDMAC ctrl = mci_readl(host, BMOD); - ctrl |= 0x01; /* Software reset of DMA */ + /* Software reset of DMA */ + ctrl |= SDMMC_IDMAC_SWRESET; mci_writel(host, BMOD, ctrl); #endif @@ -1949,10 +1952,6 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); - - host->dma_ops = host->pdata->dma_ops; - dw_mci_init_dma(host); - /* * Get the host data width - this assumes that HCON has been set with * the correct values. @@ -1980,10 +1979,11 @@ int dw_mci_probe(struct dw_mci *host) } /* Reset all blocks */ - if (!mci_wait_reset(&host->dev, host)) { - ret = -ENODEV; - goto err_dmaunmap; - } + if (!mci_wait_reset(&host->dev, host)) + return -ENODEV; + + host->dma_ops = host->pdata->dma_ops; + dw_mci_init_dma(host); /* Clear the interrupts for the host controller */ mci_writel(host, RINTSTS, 0xFFFFFFFF); @@ -2169,14 +2169,14 @@ int dw_mci_resume(struct dw_mci *host) if (host->vmmc) regulator_enable(host->vmmc); - if (host->dma_ops->init) - host->dma_ops->init(host); - if (!mci_wait_reset(&host->dev, host)) { ret = -ENODEV; return ret; } + if (host->dma_ops->init) + host->dma_ops->init(host); + /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host->fifoth_val); -- GitLab From fda5f736864c46324dbc50246ef1ca0e84ebf4ae Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 22 May 2012 13:01:13 +0900 Subject: [PATCH 0742/6849] mmc: dw_mmc: fix incorrect setting of host->data of NULL Setting host->data to NULL is incorrect sequence in dw_mci_command_complete. This early setting makes the skip of dma_unmap_sg in dw_mci_dma_cleanup. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 98fe02347d59..b070ee542c8e 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -941,8 +941,8 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd mdelay(20); if (cmd->data) { - host->data = NULL; dw_mci_stop_dma(host); + host->data = NULL; } } } -- GitLab From e419990b5e811027b1552cbc5b76a6cc180f7f48 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 22 May 2012 13:01:21 +0900 Subject: [PATCH 0743/6849] mmc: dw_mmc: correct the calculation for CLKDIV In case of "host->bus_hz < slot->clock", divider value is miscalculated. And clock divider register value is multiple of 2. If calculated divider value is odd number, result can be over-clocking. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index b070ee542c8e..1ca5e72ceb65 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -617,14 +617,15 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) u32 div; if (slot->clock != host->current_speed) { - if (host->bus_hz % slot->clock) + div = host->bus_hz / slot->clock; + if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) /* * move the + 1 after the divide to prevent * over-clocking the card. */ - div = ((host->bus_hz / slot->clock) >> 1) + 1; - else - div = (host->bus_hz / slot->clock) >> 1; + div += 1; + + div = (host->bus_hz != slot->clock) ? DIV_ROUND_UP(div, 2) : 0; dev_info(&slot->mmc->class_dev, "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" -- GitLab From 4f837791d90bca76384b665eb2649feab169cc13 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 09:44:09 -0400 Subject: [PATCH 0744/6849] mmc: omap: Fix a section warning regression Commit b6e0703b (mmc: omap: make it behave well as a module) made some __devinit changes but missed one function causing a section warning: WARNING: vmlinux.o(.devinit.text+0x8604): Section mismatch in reference from the function mmc_omap_probe) The function __devinit mmc_omap_probe() references a function __init mmc_omap_new_slot(). Signed-off-by: Tony Lindgren Acked-by: Felipe Balbi Signed-off-by: Chris Ball --- drivers/mmc/host/omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 552196c764d4..feda3064b2cd 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1300,7 +1300,7 @@ static const struct mmc_host_ops mmc_omap_ops = { .set_ios = mmc_omap_set_ios, }; -static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) +static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id) { struct mmc_omap_slot *slot = NULL; struct mmc_host *mmc; -- GitLab From 3caf41406dd67b412abae7df86cc2a09bef9621f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 09:45:50 -0400 Subject: [PATCH 0745/6849] mmc: omap: Fix NULL pointer dereference if mmc_omap_new_slot() fails Commit b01a4f1c (mmc: omap: convert to per instance workqueue) initializes the workqueue too late causing the following: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 Not tainted (3.4.0-08218-gb48b2c3 #158) PC is at __queue_work+0x8/0x46c LR is at queue_work_on+0x38/0x40 pc : [] lr : [] psr: 60000193 sp : c0691e1c ip : 00000000 fp : c07374ac r10: c7aae400 r9 : c0395700 r8 : 00000100 r7 : c0691e70 r6 : 00000000 r5 : 00000000 r4 : c7aae440 r3 : 00000001 r2 : c7aae440 r1 : 00000000 r0 : 00000000 Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 00c5387d Table: 80004000 DAC: 00000017 Process swapper/0 (pid: 0, stack limit = 0xc06902f8) Stack: (0xc0691e1c to 0xc0692000) Fix this by initializing the workqueue before mmc_omap_remove_slot() get called. Tested on n770, looks like n800 at least still has some other issue with MMC. Signed-off-by: Tony Lindgren Signed-off-by: Chris Ball --- drivers/mmc/host/omap.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index feda3064b2cd..6b07730598da 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1485,24 +1485,27 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; + + host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); + if (!host->mmc_omap_wq) + goto err_plat_cleanup; + for (i = 0; i < pdata->nr_slots; i++) { ret = mmc_omap_new_slot(host, i); if (ret < 0) { while (--i >= 0) mmc_omap_remove_slot(host->slots[i]); - goto err_plat_cleanup; + goto err_destroy_wq; } } host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); - host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); - if (!host->mmc_omap_wq) - goto err_plat_cleanup; - return 0; +err_destroy_wq: + destroy_workqueue(host->mmc_omap_wq); err_plat_cleanup: if (pdata->cleanup) pdata->cleanup(&pdev->dev); -- GitLab From ebbe6f889f36d35f4d1757ba2ecc0af6150bf12b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 09:47:49 -0400 Subject: [PATCH 0746/6849] mmc: omap: Fix broken reg_shift initialization Commit fa550189 (mmc: core: Prevent eMMC VCC supply to be cut from late init) slightly affected timings for how things are done for the omap MMC driver causing the MMC cards not getting detected any longer. Turns out this was caused by buggy reg_shift initialization in the omap MMC driver that was happening after mmc_add_host() was being called. Fix this by initializing reg_shift before mmc_add_host() is called. Signed-off-by: Tony Lindgren Cc: Signed-off-by: Chris Ball --- drivers/mmc/host/omap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 6b07730598da..3e8dcf8d2e05 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1485,6 +1485,7 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; + host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); if (!host->mmc_omap_wq) @@ -1500,8 +1501,6 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } } - host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); - return 0; err_destroy_wq: -- GitLab From 85e727edb963459d13cdd9ce84c335d251a005a7 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 31 May 2012 20:31:47 +0900 Subject: [PATCH 0747/6849] mmc: core: return an error on suspend if mmc_deselect_cards fails When mmc_host is not spi mode, mmc/sd is doing mmc_deselect_cards(). mmc_deselect_cards could be returned error. If returned error, we can know something wrong when enter suspend. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Acked-by: Ulf Hansson Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 2 +- drivers/mmc/core/sd.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 2d4a4b746750..258b203397aa 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1326,7 +1326,7 @@ static int mmc_suspend(struct mmc_host *host) if (!err) mmc_card_set_sleep(host->card); } else if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); mmc_release_host(host); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c272c6868ecf..b2b43f624b9e 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1075,16 +1075,18 @@ static void mmc_sd_detect(struct mmc_host *host) */ static int mmc_sd_suspend(struct mmc_host *host) { + int err = 0; + BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - return 0; + return err; } /* -- GitLab From 81ec1daa118ec9a04c0a907883872ae2996372bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 15:29:55 +0200 Subject: [PATCH 0748/6849] mmc: sdhci-s3c: pass IRQF ONESHOT to request threaded irq Fix a boot regression in existing kernels causing: genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq XXX caused by 1c6c6952 (genirq: Reject bogus threaded irq requests). Signed-off-by: Heiko Stuebner Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-s3c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 55a164fcaa15..a50c205ea208 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -404,7 +404,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) if (sc->ext_cd_irq && request_threaded_irq(sc->ext_cd_irq, NULL, sdhci_s3c_gpio_card_detect_thread, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), sc) == 0) { int status = gpio_get_value(sc->ext_cd_gpio); if (pdata->ext_cd_gpio_invert) -- GitLab From 7e39b817ee64a8b67282c76f52aaabddc8a5cd26 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Wed, 6 Jun 2012 19:18:29 +0530 Subject: [PATCH 0749/6849] usb: dwc3: Correct DWC3_DCTL_HIRD_THRES definition The definition of DWC3_DCTL_HIRD_THRES macro is completely wrong. It will only work for when we want to read the register's contents for that bitfield. Change the macro so that it can be used to writing to the register, and when we need to read, we can add extra right shift of 24 bits. Signed-off-by: Pratyush Anand [ balbi@ti.com: add a commit log ] Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index fcb8be2ec1c9..d3e56cfb29c3 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -223,7 +223,7 @@ #define DWC3_DCTL_LSFTRST (1 << 29) #define DWC3_DCTL_HIRD_THRES_MASK (0x1f << 24) -#define DWC3_DCTL_HIRD_THRES(n) (((n) & DWC3_DCTL_HIRD_THRES_MASK) >> 24) +#define DWC3_DCTL_HIRD_THRES(n) ((n) << 24) #define DWC3_DCTL_APPL1RES (1 << 23) -- GitLab From 4db703ead4535792ea54dba7275fdd1527848e74 Mon Sep 17 00:00:00 2001 From: Austin Hendrix Date: Mon, 4 Jun 2012 15:27:51 -0700 Subject: [PATCH 0750/6849] HID: multitouch: add support for Novatek touchscreen Add support for a Novatek touchscreen panel as a generic HID multitouch panel. Signed-off-by: Austin Hendrix Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-multitouch.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9373f535dfe9..734a2b986502 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -564,6 +564,9 @@ #define USB_VENDOR_ID_NINTENDO 0x057e #define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 +#define USB_VENDOR_ID_NOVATEK 0x0603 +#define USB_DEVICE_ID_NOVATEK_PCT 0x0600 + #define USB_VENDOR_ID_NTRIG 0x1b96 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 6e3332a99976..fae08dfd18bf 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -951,6 +951,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) }, + /* Novatek Panel */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_NOVATEK, + USB_DEVICE_ID_NOVATEK_PCT) }, + /* PenMount panels */ { .driver_data = MT_CLS_CONFIDENCE, MT_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, -- GitLab From a3e545e9ab26892641ecac7cee30ea4b4e87977e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 21 May 2012 06:33:27 +0200 Subject: [PATCH 0751/6849] mmc: mxs-mmc: Move of_match_table out of CONFIG_PM Signed-off-by: Marek Vasut Acked-by: Shawn Guo Signed-off-by: Chris Ball --- drivers/mmc/host/mxs-mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 34a90266ab11..277161d279b8 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -894,8 +894,8 @@ static struct platform_driver mxs_mmc_driver = { .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &mxs_mmc_pm_ops, - .of_match_table = mxs_mmc_dt_ids, #endif + .of_match_table = mxs_mmc_dt_ids, }, }; -- GitLab From 4380d8198845da88915c93a4b3f9cb2fa0f917be Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 6 Jun 2012 16:28:33 +0200 Subject: [PATCH 0752/6849] HID: multitouch: fix entry for Novatek Touchscreen Since Henrik's autoloading changes, the proper macro for device entry is MT_USB_DEVICE(). Reported-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index fae08dfd18bf..61cc4cbe0f3e 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -953,7 +953,7 @@ static const struct hid_device_id mt_devices[] = { /* Novatek Panel */ { .driver_data = MT_CLS_DEFAULT, - HID_USB_DEVICE(USB_VENDOR_ID_NOVATEK, + MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_PCT) }, /* PenMount panels */ -- GitLab From dcae3573b98b2205961bfa5821427f5664422cd8 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Wed, 6 Jun 2012 19:36:17 +0530 Subject: [PATCH 0753/6849] usb: dwc3: resume phy during gadget initialization on recent cores It is needed to enumerate recent cores like 2.10a. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8e00756ee522..38cd13ffae9d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2449,8 +2449,8 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_DCTL, reg); - dwc3_gadget_usb2_phy_suspend(dwc, true); - dwc3_gadget_usb3_phy_suspend(dwc, true); + dwc3_gadget_usb2_phy_suspend(dwc, false); + dwc3_gadget_usb3_phy_suspend(dwc, false); } ret = device_register(&dwc->gadget.dev); -- GitLab From c00b275043adc14d668f36266b890f0c53d46640 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:27:44 +0200 Subject: [PATCH 0754/6849] uprobes: Optimize is_swbp_at_addr() for current->mm Change is_swbp_at_addr() to try to avoid the costly read_opcode() if mm == current->mm, __copy_from_user_inatomic() should succeed in the likely case. Currently this optimization is not important, but we are going to add more is_swbp_at_addr(current->mm) callers. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529192744.GA8057@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 985be4d80fe8..d0f5ec0dcdea 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -333,10 +333,20 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) uprobe_opcode_t opcode; int result; + if (current->mm == mm) { + pagefault_disable(); + result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, + sizeof(opcode)); + pagefault_enable(); + + if (likely(result == 0)) + goto out; + } + result = read_opcode(mm, vaddr, &opcode); if (result) return result; - +out: if (is_swbp_insn(&opcode)) return 1; -- GitLab From a3d7bb47937b3a40b9f0c75655e97b3bb6407cbe Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:27:59 +0200 Subject: [PATCH 0755/6849] uprobes: Change read_opcode() to use FOLL_FORCE set_orig_insn()->read_opcode() should not fail if the probed task did mprotect() after uprobe_register(), change it to use FOLL_FORCE. Without FOLL_WRITE this doesn't have any "side" effect but allows to read the !VM_READ memory. There is another reason for this change, we are going to use is_swbp_at_addr() from handle_swbp() which can race with another thread doing mprotect(). Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529192759.GB8057@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index d0f5ec0dcdea..a0dbc87a2ec6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -312,7 +312,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_ void *vaddr_new; int ret; - ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL); + ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); if (ret <= 0) return ret; -- GitLab From 3a9ea0520f38def4a3915b91f82455b749f07d88 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:28:57 +0200 Subject: [PATCH 0756/6849] uprobes: Introduce find_active_uprobe() helper No functional changes. Move the "find uprobe" code from handle_swbp() to the new helper, find_active_uprobe(). Note: with or without this change, the find-active-uprobe logic is not exactly right. We can race with another thread which unmaps the memory with the valid uprobe before we take mm->mmap_sem. We can't find this uprobe simply because find_vma() fails. In this case we wrongly assume that this trap was not caused by uprobe and send the erroneous SIGTRAP. See the next changes. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529192857.GC8057@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 47 ++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index a0dbc87a2ec6..eaf4d55fd424 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1489,38 +1489,47 @@ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs) return false; } -/* - * Run handler and ask thread to singlestep. - * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. - */ -static void handle_swbp(struct pt_regs *regs) +static struct uprobe *find_active_uprobe(unsigned long bp_vaddr) { + struct mm_struct *mm = current->mm; + struct uprobe *uprobe = NULL; struct vm_area_struct *vma; - struct uprobe_task *utask; - struct uprobe *uprobe; - struct mm_struct *mm; - unsigned long bp_vaddr; - uprobe = NULL; - bp_vaddr = uprobe_get_swbp_addr(regs); - mm = current->mm; down_read(&mm->mmap_sem); vma = find_vma(mm, bp_vaddr); - if (vma && vma->vm_start <= bp_vaddr && valid_vma(vma, false)) { - struct inode *inode; - loff_t offset; + if (vma && vma->vm_start <= bp_vaddr) { + if (valid_vma(vma, false)) { + struct inode *inode; + loff_t offset; - inode = vma->vm_file->f_mapping->host; - offset = bp_vaddr - vma->vm_start; - offset += (vma->vm_pgoff << PAGE_SHIFT); - uprobe = find_uprobe(inode, offset); + inode = vma->vm_file->f_mapping->host; + offset = bp_vaddr - vma->vm_start; + offset += (vma->vm_pgoff << PAGE_SHIFT); + uprobe = find_uprobe(inode, offset); + } } srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id); current->uprobe_srcu_id = -1; up_read(&mm->mmap_sem); + return uprobe; +} + +/* + * Run handler and ask thread to singlestep. + * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. + */ +static void handle_swbp(struct pt_regs *regs) +{ + struct uprobe_task *utask; + struct uprobe *uprobe; + unsigned long bp_vaddr; + + bp_vaddr = uprobe_get_swbp_addr(regs); + uprobe = find_active_uprobe(bp_vaddr); + if (!uprobe) { /* No matching uprobe; signal SIGTRAP. */ send_sig(SIGTRAP, current, 0); -- GitLab From d790d34653ab20c74034902f5f0889bba807949a Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:29:14 +0200 Subject: [PATCH 0757/6849] uprobes: Teach find_active_uprobe() to provide the "is_swbp" info A separate patch to simplify the review, and for the documentation. The patch adds another "int *is_swbp" argument to find_active_uprobe(), so far its only caller doesn't use this info. With this patch find_active_uprobe() additionally does: - if find_vma() + ->vm_start check fails, *is_swbp = -EFAULT - otherwise, if valid_vma() + find_uprobe() fails, it holds the result of is_swbp_at_addr(), can be negative too. The latter is only possible if we raced with another thread which did munmap/etc after we hit this bp. IOW. If find_active_uprobe(&is_swbp) returns NULL, the caller can look at is_swbp to figure out whether the current insn is bp or not, or detect the race with another thread if it is negative. Note: I think that performance-wise this change is fine. This adds is_swbp_at_addr(), but only if we raced with uprobe_unregister() or if we hit the "normal" int3 but this mm has uprobes as well. And even in this case the slow read_opcode() path is very unlikely, this insn recently triggered do_int3(), __copy_from_user_inatomic() shouldn't fail in the likely case. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529192914.GD8057@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index eaf4d55fd424..ee3df704e78a 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1489,7 +1489,7 @@ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs) return false; } -static struct uprobe *find_active_uprobe(unsigned long bp_vaddr) +static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) { struct mm_struct *mm = current->mm; struct uprobe *uprobe = NULL; @@ -1497,7 +1497,6 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr) down_read(&mm->mmap_sem); vma = find_vma(mm, bp_vaddr); - if (vma && vma->vm_start <= bp_vaddr) { if (valid_vma(vma, false)) { struct inode *inode; @@ -1508,6 +1507,11 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr) offset += (vma->vm_pgoff << PAGE_SHIFT); uprobe = find_uprobe(inode, offset); } + + if (!uprobe) + *is_swbp = is_swbp_at_addr(mm, bp_vaddr); + } else { + *is_swbp = -EFAULT; } srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id); @@ -1526,9 +1530,10 @@ static void handle_swbp(struct pt_regs *regs) struct uprobe_task *utask; struct uprobe *uprobe; unsigned long bp_vaddr; + int is_swbp; bp_vaddr = uprobe_get_swbp_addr(regs); - uprobe = find_active_uprobe(bp_vaddr); + uprobe = find_active_uprobe(bp_vaddr, &is_swbp); if (!uprobe) { /* No matching uprobe; signal SIGTRAP. */ -- GitLab From 77fc4af1b59d12ab3b1467adf0a5204806853123 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:29:28 +0200 Subject: [PATCH 0758/6849] uprobes: Change register_for_each_vma() to take mm->mmap_sem for writing Change register_for_each_vma() to take mm->mmap_sem for writing. This is a bit unfortunate but hopefully not too bad, this is the slow path anyway. This is needed to ensure that find_active_uprobe() can not race with uprobe_register() which adds the new bp at the same bp_vaddr, after find_uprobe() fails and before is_swbp_at_addr_fast() checks the memory. IOW, this is needed to ensure that if find_active_uprobe() returns NULL but is_swbp == true, we can safely assume that it was the "normal" int3 and we should send SIGTRAP. There is another reason for this change. We are going to replace uprobes_state->count with MMF_ flags set by register/unregister and cleared by find_active_uprobe(), and set/clear shouldn't race with each other. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529192928.GE8057@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index ee3df704e78a..a2ed82b4808c 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -853,12 +853,12 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) } mm = vi->mm; - down_read(&mm->mmap_sem); + down_write(&mm->mmap_sem); vma = find_vma(mm, (unsigned long)vi->vaddr); if (!vma || !valid_vma(vma, is_register)) { list_del(&vi->probe_list); kfree(vi); - up_read(&mm->mmap_sem); + up_write(&mm->mmap_sem); mmput(mm); continue; } @@ -867,7 +867,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) vaddr != vi->vaddr) { list_del(&vi->probe_list); kfree(vi); - up_read(&mm->mmap_sem); + up_write(&mm->mmap_sem); mmput(mm); continue; } @@ -877,7 +877,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) else remove_breakpoint(uprobe, mm, vi->vaddr); - up_read(&mm->mmap_sem); + up_write(&mm->mmap_sem); mmput(mm); if (is_register) { if (ret && ret == -EEXIST) -- GitLab From 56bb4cf6475d702d2fb00fc641aa6441097c0330 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:29:47 +0200 Subject: [PATCH 0759/6849] uprobes: Teach handle_swbp() to rely on "is_swbp" rather than uprobes_srcu Currently handle_swbp() assumes that it can't race with unregister, so it roughly does: if (find_uprobe(vaddr)) process_uprobe(); else send_sig(SIGTRAP); This relies on the not-really-working uprobes_srcu code we are going to remove, see the next patch. With this patch we rely on the result of is_swbp_at_addr(bp_vaddr) if find_uprobe() fails. If is_swbp == 1, then we hit the normal int3, we should send SIGTRAP. If is_swbp == 0, we raced with uprobe_unregister(), we simply restart this insn again. The "difficult" case is is_swbp == -EFAULT, when we can't read this memory. In this case I think we should restart too, and this is more correct compared to the current code which sends SIGTRAP. Ignoring ENOMEM/etc from get_user_pages(), this can only happen if another thread unmaps this memory before find_active_uprobe() takes mmap_sem. It would be better to pretend it was unmapped before this insn was executed, restart, and get SIGSEGV. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529192947.GF8057@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index a2ed82b4808c..1f02e3bbfc1d 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1530,14 +1530,26 @@ static void handle_swbp(struct pt_regs *regs) struct uprobe_task *utask; struct uprobe *uprobe; unsigned long bp_vaddr; - int is_swbp; + int uninitialized_var(is_swbp); bp_vaddr = uprobe_get_swbp_addr(regs); uprobe = find_active_uprobe(bp_vaddr, &is_swbp); if (!uprobe) { - /* No matching uprobe; signal SIGTRAP. */ - send_sig(SIGTRAP, current, 0); + if (is_swbp > 0) { + /* No matching uprobe; signal SIGTRAP. */ + send_sig(SIGTRAP, current, 0); + } else { + /* + * Either we raced with uprobe_unregister() or we can't + * access this memory. The latter is only possible if + * another thread plays with our ->mm. In both cases + * we can simply restart. If this vma was unmapped we + * can pretend this insn was not executed yet and get + * the (correct) SIGSEGV after restart. + */ + instruction_pointer_set(regs, bp_vaddr); + } return; } -- GitLab From 778b032d96909690c19d84f8d17c13be65ed6f8e Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 May 2012 21:30:08 +0200 Subject: [PATCH 0760/6849] uprobes: Kill uprobes_srcu/uprobe_srcu_id Kill the no longer needed uprobes_srcu/uprobe_srcu_id code. It doesn't really work anyway. synchronize_srcu() can only synchronize with the code "inside" the srcu_read_lock/srcu_read_unlock section, while uprobe_pre_sstep_notifier() does srcu_read_lock() _after_ we already hit the breakpoint. I guess this probably works "in practice". synchronize_srcu() is slow and it implies synchronize_sched(), and the probed task enters the non- preemptible section at the start of exception handler. Still this is not right at least in theory, and task->uprobe_srcu_id blows task_struct. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120529193008.GG8057@redhat.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 - kernel/events/uprobes.c | 22 +++------------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 6029d8c54476..6bd19655c1a7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1569,7 +1569,6 @@ struct task_struct { #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask; - int uprobe_srcu_id; #endif }; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 1f02e3bbfc1d..8c5e043cd309 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -38,7 +38,6 @@ #define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES) #define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE -static struct srcu_struct uprobes_srcu; static struct rb_root uprobes_tree = RB_ROOT; static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */ @@ -738,20 +737,14 @@ remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr) } /* - * There could be threads that have hit the breakpoint and are entering the - * notifier code and trying to acquire the uprobes_treelock. The thread - * calling delete_uprobe() that is removing the uprobe from the rb_tree can - * race with these threads and might acquire the uprobes_treelock compared - * to some of the breakpoint hit threads. In such a case, the breakpoint - * hit threads will not find the uprobe. The current unregistering thread - * waits till all other threads have hit a breakpoint, to acquire the - * uprobes_treelock before the uprobe is removed from the rbtree. + * There could be threads that have already hit the breakpoint. They + * will recheck the current insn and restart if find_uprobe() fails. + * See find_active_uprobe(). */ static void delete_uprobe(struct uprobe *uprobe) { unsigned long flags; - synchronize_srcu(&uprobes_srcu); spin_lock_irqsave(&uprobes_treelock, flags); rb_erase(&uprobe->rb_node, &uprobes_tree); spin_unlock_irqrestore(&uprobes_treelock, flags); @@ -1388,9 +1381,6 @@ void uprobe_free_utask(struct task_struct *t) { struct uprobe_task *utask = t->utask; - if (t->uprobe_srcu_id != -1) - srcu_read_unlock_raw(&uprobes_srcu, t->uprobe_srcu_id); - if (!utask) return; @@ -1408,7 +1398,6 @@ void uprobe_free_utask(struct task_struct *t) void uprobe_copy_process(struct task_struct *t) { t->utask = NULL; - t->uprobe_srcu_id = -1; } /* @@ -1513,9 +1502,6 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) } else { *is_swbp = -EFAULT; } - - srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id); - current->uprobe_srcu_id = -1; up_read(&mm->mmap_sem); return uprobe; @@ -1656,7 +1642,6 @@ int uprobe_pre_sstep_notifier(struct pt_regs *regs) utask->state = UTASK_BP_HIT; set_thread_flag(TIF_UPROBE); - current->uprobe_srcu_id = srcu_read_lock_raw(&uprobes_srcu); return 1; } @@ -1691,7 +1676,6 @@ static int __init init_uprobes(void) mutex_init(&uprobes_mutex[i]); mutex_init(&uprobes_mmap_mutex[i]); } - init_srcu_struct(&uprobes_srcu); return register_die_notifier(&uprobe_exception_nb); } -- GitLab From 5a425294ee7d4ab5a374248e85838dfd450caf75 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Jun 2012 15:30:31 +0200 Subject: [PATCH 0761/6849] perf/x86: Fix Intel shared extra MSR allocation Zheng Yan reported that event group validation can wreck event state when Intel extra_reg allocation changes event state. Validation shouldn't change any persistent state. Cloning events in validate_{event,group}() isn't really pretty either, so add a few special cases to avoid modifying the event state. The code is restructured to minimize the special case impact. Reported-by: Zheng Yan Acked-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1338903031.28282.175.camel@twins Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 1 + arch/x86/kernel/cpu/perf_event.h | 1 + arch/x86/kernel/cpu/perf_event_intel.c | 92 ++++++++++++++++++-------- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index e049d6da0183..cb608383e4f6 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1496,6 +1496,7 @@ static struct cpu_hw_events *allocate_fake_cpuc(void) if (!cpuc->shared_regs) goto error; } + cpuc->is_fake = 1; return cpuc; error: free_fake_cpuc(cpuc); diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 6638aaf54493..83794d8e6af0 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -117,6 +117,7 @@ struct cpu_hw_events { struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ unsigned int group_flag; + int is_fake; /* * Intel DebugStore bits diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 166546ec6aef..965baa2fa790 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1119,27 +1119,33 @@ intel_bts_constraints(struct perf_event *event) return NULL; } -static bool intel_try_alt_er(struct perf_event *event, int orig_idx) +static int intel_alt_er(int idx) { if (!(x86_pmu.er_flags & ERF_HAS_RSP_1)) - return false; + return idx; - if (event->hw.extra_reg.idx == EXTRA_REG_RSP_0) { - event->hw.config &= ~INTEL_ARCH_EVENT_MASK; - event->hw.config |= 0x01bb; - event->hw.extra_reg.idx = EXTRA_REG_RSP_1; - event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; - } else if (event->hw.extra_reg.idx == EXTRA_REG_RSP_1) { + if (idx == EXTRA_REG_RSP_0) + return EXTRA_REG_RSP_1; + + if (idx == EXTRA_REG_RSP_1) + return EXTRA_REG_RSP_0; + + return idx; +} + +static void intel_fixup_er(struct perf_event *event, int idx) +{ + event->hw.extra_reg.idx = idx; + + if (idx == EXTRA_REG_RSP_0) { event->hw.config &= ~INTEL_ARCH_EVENT_MASK; event->hw.config |= 0x01b7; - event->hw.extra_reg.idx = EXTRA_REG_RSP_0; event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; + } else if (idx == EXTRA_REG_RSP_1) { + event->hw.config &= ~INTEL_ARCH_EVENT_MASK; + event->hw.config |= 0x01bb; + event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; } - - if (event->hw.extra_reg.idx == orig_idx) - return false; - - return true; } /* @@ -1157,14 +1163,18 @@ __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, struct event_constraint *c = &emptyconstraint; struct er_account *era; unsigned long flags; - int orig_idx = reg->idx; + int idx = reg->idx; - /* already allocated shared msr */ - if (reg->alloc) + /* + * reg->alloc can be set due to existing state, so for fake cpuc we + * need to ignore this, otherwise we might fail to allocate proper fake + * state for this extra reg constraint. Also see the comment below. + */ + if (reg->alloc && !cpuc->is_fake) return NULL; /* call x86_get_event_constraint() */ again: - era = &cpuc->shared_regs->regs[reg->idx]; + era = &cpuc->shared_regs->regs[idx]; /* * we use spin_lock_irqsave() to avoid lockdep issues when * passing a fake cpuc @@ -1173,6 +1183,29 @@ again: if (!atomic_read(&era->ref) || era->config == reg->config) { + /* + * If its a fake cpuc -- as per validate_{group,event}() we + * shouldn't touch event state and we can avoid doing so + * since both will only call get_event_constraints() once + * on each event, this avoids the need for reg->alloc. + * + * Not doing the ER fixup will only result in era->reg being + * wrong, but since we won't actually try and program hardware + * this isn't a problem either. + */ + if (!cpuc->is_fake) { + if (idx != reg->idx) + intel_fixup_er(event, idx); + + /* + * x86_schedule_events() can call get_event_constraints() + * multiple times on events in the case of incremental + * scheduling(). reg->alloc ensures we only do the ER + * allocation once. + */ + reg->alloc = 1; + } + /* lock in msr value */ era->config = reg->config; era->reg = reg->reg; @@ -1180,17 +1213,17 @@ again: /* one more user */ atomic_inc(&era->ref); - /* no need to reallocate during incremental event scheduling */ - reg->alloc = 1; - /* * need to call x86_get_event_constraint() * to check if associated event has constraints */ c = NULL; - } else if (intel_try_alt_er(event, orig_idx)) { - raw_spin_unlock_irqrestore(&era->lock, flags); - goto again; + } else { + idx = intel_alt_er(idx); + if (idx != reg->idx) { + raw_spin_unlock_irqrestore(&era->lock, flags); + goto again; + } } raw_spin_unlock_irqrestore(&era->lock, flags); @@ -1204,11 +1237,14 @@ __intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc, struct er_account *era; /* - * only put constraint if extra reg was actually - * allocated. Also takes care of event which do - * not use an extra shared reg + * Only put constraint if extra reg was actually allocated. Also takes + * care of event which do not use an extra shared reg. + * + * Also, if this is a fake cpuc we shouldn't touch any event state + * (reg->alloc) and we don't care about leaving inconsistent cpuc state + * either since it'll be thrown out. */ - if (!reg->alloc) + if (!reg->alloc || cpuc->is_fake) return; era = &cpuc->shared_regs->regs[reg->idx]; -- GitLab From 0780c927a02492f917a74f51f3c801c76a637c57 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Jun 2012 10:26:43 +0200 Subject: [PATCH 0762/6849] perf/x86: Implement cycles:p for SNB/IVB Now that there's finally a chip with working PEBS (IvyBridge), we can enable the hardware and implement cycles:p for SNB/IVB. Cc: Stephane Eranian Requested-and-tested-by: Linus Torvalds Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1338884803.28282.153.camel@twins Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.h | 1 + arch/x86/kernel/cpu/perf_event_intel.c | 50 +++++++++++++++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 83794d8e6af0..7241e2fc3c17 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -365,6 +365,7 @@ struct x86_pmu { int pebs_record_size; void (*drain_pebs)(struct pt_regs *regs); struct event_constraint *pebs_constraints; + void (*pebs_aliases)(struct perf_event *event); /* * Intel LBR diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 965baa2fa790..2312c1ff1b19 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1336,15 +1336,9 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc, intel_put_shared_regs_event_constraints(cpuc, event); } -static int intel_pmu_hw_config(struct perf_event *event) +static void intel_pebs_aliases_core2(struct perf_event *event) { - int ret = x86_pmu_hw_config(event); - - if (ret) - return ret; - - if (event->attr.precise_ip && - (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { + if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { /* * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P * (0x003c) so that we can use it with PEBS. @@ -1365,10 +1359,48 @@ static int intel_pmu_hw_config(struct perf_event *event) */ u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16); + alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); + event->hw.config = alt_config; + } +} + +static void intel_pebs_aliases_snb(struct perf_event *event) +{ + if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { + /* + * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P + * (0x003c) so that we can use it with PEBS. + * + * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't + * PEBS capable. However we can use UOPS_RETIRED.ALL + * (0x01c2), which is a PEBS capable event, to get the same + * count. + * + * UOPS_RETIRED.ALL counts the number of cycles that retires + * CNTMASK micro-ops. By setting CNTMASK to a value (16) + * larger than the maximum number of micro-ops that can be + * retired per cycle (4) and then inverting the condition, we + * count all cycles that retire 16 or less micro-ops, which + * is every cycle. + * + * Thereby we gain a PEBS capable cycle counter. + */ + u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16); alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); event->hw.config = alt_config; } +} + +static int intel_pmu_hw_config(struct perf_event *event) +{ + int ret = x86_pmu_hw_config(event); + + if (ret) + return ret; + + if (event->attr.precise_ip && x86_pmu.pebs_aliases) + x86_pmu.pebs_aliases(event); if (intel_pmu_needs_lbr_smpl(event)) { ret = intel_pmu_setup_lbr_filter(event); @@ -1643,6 +1675,7 @@ static __initconst const struct x86_pmu intel_pmu = { .max_period = (1ULL << 31) - 1, .get_event_constraints = intel_get_event_constraints, .put_event_constraints = intel_put_event_constraints, + .pebs_aliases = intel_pebs_aliases_core2, .format_attrs = intel_arch3_formats_attr, @@ -1885,6 +1918,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_snb_event_constraints; x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; + x86_pmu.pebs_aliases = intel_pebs_aliases_snb; x86_pmu.extra_regs = intel_snb_extra_regs; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; -- GitLab From 47a8863dbb11745446314ca126593789ab74d93a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Jun 2012 10:26:43 +0200 Subject: [PATCH 0763/6849] perf/x86: Enable/Add IvyBridge hardware support Implement rudimentary IVB perf support. The SDM states its identical to SNB with exception of the exact event tables, but a quick look suggests they're similar enough. Also mark SNB-EP as broken for now. Requested-and-tested-by: Linus Torvalds Cc: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1338884803.28282.153.camel@twins Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 2312c1ff1b19..187c294bc658 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1909,8 +1909,9 @@ __init int intel_pmu_init(void) break; case 42: /* SandyBridge */ - x86_add_quirk(intel_sandybridge_quirk); case 45: /* SandyBridge, "Romely-EP" */ + x86_add_quirk(intel_sandybridge_quirk); + case 58: /* IvyBridge */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); -- GitLab From 212d95dfdb66e5c81879b08e4f7fbfc8498b1ab5 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Jun 2012 10:26:43 +0200 Subject: [PATCH 0764/6849] perf/x86: Update SNB PEBS constraints Afaict there's no need to (incompletely) iterate the MEM_UOPS_RETIRED.* umask state. Signed-off-by: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1338884803.28282.153.camel@twins Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 5a3edc27f6e5..35e2192df9f4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -400,14 +400,7 @@ struct event_constraint intel_snb_pebs_event_constraints[] = { INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */ - INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS_LOADS */ - INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS_STORES */ - INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOP_RETIRED.LOCK_LOADS */ - INTEL_UEVENT_CONSTRAINT(0x22d0, 0xf), /* MEM_UOP_RETIRED.LOCK_STORES */ - INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOP_RETIRED.SPLIT_LOADS */ - INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf), /* MEM_UOP_RETIRED.SPLIT_STORES */ - INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOP_RETIRED.ANY_LOADS */ - INTEL_UEVENT_CONSTRAINT(0x82d0, 0xf), /* MEM_UOP_RETIRED.ANY_STORES */ + INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ INTEL_UEVENT_CONSTRAINT(0x02d4, 0xf), /* MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS */ -- GitLab From 1c2ac3fde3e35279958e7b0408e2dcf866465301 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 14 May 2012 15:25:34 +0200 Subject: [PATCH 0765/6849] perf/x86: Fix wrmsrl() debug wrapper Move the wrmslr() debug wrapper to the common header now that all the include games are gone. Also clean it up a bit to avoid multiple evaluation of the argument. Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-l4gkfnivwv4yi5mqxjlovymx@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 11 ----------- arch/x86/kernel/cpu/perf_event.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c4706cf9c011..43c2017347e7 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -35,17 +35,6 @@ #include "perf_event.h" -#if 0 -#undef wrmsrl -#define wrmsrl(msr, val) \ -do { \ - trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\ - (unsigned long)(val)); \ - native_write_msr((msr), (u32)((u64)(val)), \ - (u32)((u64)(val) >> 32)); \ -} while (0) -#endif - struct x86_pmu x86_pmu __read_mostly; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 7241e2fc3c17..23b5710b1747 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -14,6 +14,18 @@ #include +#if 0 +#undef wrmsrl +#define wrmsrl(msr, val) \ +do { \ + unsigned int _msr = (msr); \ + u64 _val = (val); \ + trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr), \ + (unsigned long long)(_val)); \ + native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32)); \ +} while (0) +#endif + /* * | NHM/WSM | SNB | * register ------------------------------- -- GitLab From 1ff4d58a192aea7f245981e2579765f961f6eb9c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jun 2012 17:56:50 -0700 Subject: [PATCH 0766/6849] x86: Add rdpmcl() Add a version of rdpmc() that directly reads into a u64 Signed-off-by: Andi Kleen Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1338944211-28275-4-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/msr.h | 2 ++ arch/x86/include/asm/paravirt.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 084ef95274cd..e489c1475be9 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -237,6 +237,8 @@ do { \ (high) = (u32)(_l >> 32); \ } while (0) +#define rdpmcl(counter, val) ((val) = native_read_pmc(counter)) + #define rdtscp(low, high, aux) \ do { \ unsigned long long _val = native_read_tscp(&(aux)); \ diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 6cbbabf52707..14ce05dfe04e 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -252,6 +252,8 @@ do { \ high = _l >> 32; \ } while (0) +#define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter)) + static inline unsigned long long paravirt_rdtscp(unsigned int *aux) { return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); -- GitLab From c48b60538c3ba05a7a2713c4791b25405525431b Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Thu, 1 Mar 2012 17:28:14 -0500 Subject: [PATCH 0767/6849] perf/x86: Use rdpmc() rather than rdmsr() when possible in the kernel The rdpmc instruction is faster than the equivelant rdmsr call, so use it when possible in the kernel. The perfctr kernel patches did this, after extensive testing showed rdpmc to always be faster (One can look in etc/costs in the perfctr-2.6 package to see a historical list of the overhead). I have done some tests on a 3.2 kernel, the kernel module I used was included in the first posting of this patch: rdmsr rdpmc Core2 T9900: 203.9 cycles 30.9 cycles AMD fam0fh: 56.2 cycles 9.8 cycles Atom 6/28/2: 129.7 cycles 50.6 cycles The speedup of using rdpmc is large. [ It's probably possible (and desirable) to do this without requiring a new field in the hw_perf_event structure, but the fixed events make this tricky. ] Signed-off-by: Vince Weaver Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/alpine.DEB.2.00.1203011724030.26934@cl320.eecs.utk.edu Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 4 +++- include/linux/perf_event.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 43c2017347e7..000a4746c7ce 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -75,7 +75,7 @@ u64 x86_perf_event_update(struct perf_event *event) */ again: prev_raw_count = local64_read(&hwc->prev_count); - rdmsrl(hwc->event_base, new_raw_count); + rdpmcl(hwc->event_base_rdpmc, new_raw_count); if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, new_raw_count) != prev_raw_count) @@ -819,9 +819,11 @@ static inline void x86_assign_hw_event(struct perf_event *event, } else if (hwc->idx >= X86_PMC_IDX_FIXED) { hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - X86_PMC_IDX_FIXED); + hwc->event_base_rdpmc = (hwc->idx - X86_PMC_IDX_FIXED) | 1<<30; } else { hwc->config_base = x86_pmu_config_addr(hwc->idx); hwc->event_base = x86_pmu_event_addr(hwc->idx); + hwc->event_base_rdpmc = x86_pmu_addr_offset(hwc->idx); } } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 45db49f64bb4..1ce887abcc5c 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -677,6 +677,7 @@ struct hw_perf_event { u64 last_tag; unsigned long config_base; unsigned long event_base; + int event_base_rdpmc; int idx; int last_cpu; -- GitLab From 70ab7003dec58afeae7f5d681dfa309b3a259f03 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jun 2012 17:56:48 -0700 Subject: [PATCH 0768/6849] perf/x86: Don't assume there can be only 4 PEBS events On Sandy Bridge in non HT mode there are 8 counters available. Since every counter can write a PEBS record assuming there are 4 max is incorrect. Use the reported counter number -- with an upper limit for a static array -- instead. Also I made the warning messages a bit more informational. Signed-off-by: Andi Kleen Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1338944211-28275-2-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.h | 3 ++- arch/x86/kernel/cpu/perf_event_intel.c | 2 ++ arch/x86/kernel/cpu/perf_event_intel_ds.c | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 23b5710b1747..3df3de9452a9 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -69,7 +69,7 @@ struct amd_nb { }; /* The maximal number of PEBS events: */ -#define MAX_PEBS_EVENTS 4 +#define MAX_PEBS_EVENTS 8 /* * A debug store configuration. @@ -378,6 +378,7 @@ struct x86_pmu { void (*drain_pebs)(struct pt_regs *regs); struct event_constraint *pebs_constraints; void (*pebs_aliases)(struct perf_event *event); + int max_pebs_events; /* * Intel LBR diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 187c294bc658..e23e71f25264 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1800,6 +1800,8 @@ __init int intel_pmu_init(void) x86_pmu.events_maskl = ebx.full; x86_pmu.events_mask_len = eax.split.mask_length; + x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); + /* * Quirk: v2 perfmon does not report fixed-purpose events, so * assume at least 3 events: diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 35e2192df9f4..026373edef7f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -620,7 +620,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) * Should not happen, we program the threshold at 1 and do not * set a reset value. */ - WARN_ON_ONCE(n > 1); + WARN_ONCE(n > 1, "bad leftover pebs %d\n", n); at += n - 1; __intel_pmu_pebs_event(event, iregs, at); @@ -651,10 +651,10 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) * Should not happen, we program the threshold at 1 and do not * set a reset value. */ - WARN_ON_ONCE(n > MAX_PEBS_EVENTS); + WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n); for ( ; at < top; at++) { - for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { + for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) { event = cpuc->events[bit]; if (!test_bit(bit, cpuc->active_mask)) continue; @@ -670,7 +670,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) break; } - if (!event || bit >= MAX_PEBS_EVENTS) + if (!event || bit >= x86_pmu.max_pebs_events) continue; __intel_pmu_pebs_event(event, iregs, at); -- GitLab From 1d1e9a467c7a478d24a1af39e467a414a8363661 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:17 +0000 Subject: [PATCH 0769/6849] be2net: don't call vid_config() when there's no vlan config be_vid_config() is called from be_setup() to replay config cmds after a card reset. Skip calling it when no vlans are configured. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 08efd308d78a..f1b092692aa5 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2762,7 +2762,8 @@ static int be_setup(struct be_adapter *adapter) be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); - be_vid_config(adapter, false, 0); + if (adapter->vlans_added) + be_vid_config(adapter, false, 0); be_set_rx_mode(adapter->netdev); -- GitLab From 10329df8f9b90e27ef63d89f9d58fed8d466f943 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:18 +0000 Subject: [PATCH 0770/6849] be2net: cleanup be_vid_config() - get rid of 2 unused arguments to the routine and some unused code - don't use the term "vlan_tag" in place of "vid" as they are different Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 25 ++++++++------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index f1b092692aa5..cfbec8b495cb 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -785,19 +785,12 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu) * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE. * If the user configures more, place BE in vlan promiscuous mode. */ -static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) +static int be_vid_config(struct be_adapter *adapter) { - struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf_num]; - u16 vtag[BE_NUM_VLANS_SUPPORTED]; - u16 ntags = 0, i; + u16 vids[BE_NUM_VLANS_SUPPORTED]; + u16 num = 0, i; int status = 0; - if (vf) { - vtag[0] = cpu_to_le16(vf_cfg->vlan_tag); - status = be_cmd_vlan_config(adapter, vf_cfg->if_handle, vtag, - 1, 1, 0); - } - /* No need to further configure vids if in promiscuous mode */ if (adapter->promiscuous) return 0; @@ -808,10 +801,10 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) /* Construct VLAN Table to give to HW */ for (i = 0; i < VLAN_N_VID; i++) if (adapter->vlan_tag[i]) - vtag[ntags++] = cpu_to_le16(i); + vids[num++] = cpu_to_le16(i); status = be_cmd_vlan_config(adapter, adapter->if_handle, - vtag, ntags, 1, 0); + vids, num, 1, 0); /* Set to VLAN promisc mode as setting VLAN filter failed */ if (status) { @@ -840,7 +833,7 @@ static int be_vlan_add_vid(struct net_device *netdev, u16 vid) adapter->vlan_tag[vid] = 1; if (adapter->vlans_added <= (adapter->max_vlans + 1)) - status = be_vid_config(adapter, false, 0); + status = be_vid_config(adapter); if (!status) adapter->vlans_added++; @@ -862,7 +855,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, u16 vid) adapter->vlan_tag[vid] = 0; if (adapter->vlans_added <= adapter->max_vlans) - status = be_vid_config(adapter, false, 0); + status = be_vid_config(adapter); if (!status) adapter->vlans_added--; @@ -889,7 +882,7 @@ static void be_set_rx_mode(struct net_device *netdev) be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); if (adapter->vlans_added) - be_vid_config(adapter, false, 0); + be_vid_config(adapter); } /* Enable multicast promisc if num configured exceeds what we support */ @@ -2763,7 +2756,7 @@ static int be_setup(struct be_adapter *adapter) be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); if (adapter->vlans_added) - be_vid_config(adapter, false, 0); + be_vid_config(adapter); be_set_rx_mode(adapter->netdev); -- GitLab From 0513ac3d2212072c6694430b1003ad4246a35466 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:19 +0000 Subject: [PATCH 0771/6849] be2net: do not modify PCI MaxReadReq size Setting the PCI MRRS to a value of 4096 (overriding the system decided value) had provided perf improvement in TX. But, IBM has provided feedback that on POWER platforms, this value is set by the system firmware, and drivers modifying this value can cause unpredictable results (like EEH errors.) So, backing off this change. On POWER7 platforms most slots, it seems, do get a MRRS of 4096. This patch reverts the following commit: "be2net: Modified PCI MaxReadReq size to 4096 bytes" commit 5a56eb10babbcd7b3796dc3c28c271260aa3608d. Suggested-by: Brian King Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index cfbec8b495cb..695c3cf76e8d 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2766,8 +2766,6 @@ static int be_setup(struct be_adapter *adapter) be_cmd_set_flow_control(adapter, adapter->tx_fc, adapter->rx_fc); - pcie_set_readrq(adapter->pdev, 4096); - if (be_physfn(adapter) && num_vfs) { if (adapter->dev_num_vfs) be_vf_setup(adapter); -- GitLab From 7f6400626631454f5b535eb92c09a35390777a52 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:20 +0000 Subject: [PATCH 0772/6849] be2net: fix reporting number of actual rx queues Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 695c3cf76e8d..3aa478f50358 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1890,6 +1890,12 @@ static int be_rx_cqs_create(struct be_adapter *adapter) */ adapter->num_rx_qs = (num_irqs(adapter) > 1) ? num_irqs(adapter) + 1 : 1; + if (adapter->num_rx_qs != MAX_RX_QS) { + rtnl_lock(); + netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_qs); + rtnl_unlock(); + } adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; for_all_rx_queues(adapter, rxo, i) { @@ -3740,7 +3746,7 @@ static int __devinit be_probe(struct pci_dev *pdev, goto disable_dev; pci_set_master(pdev); - netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS); + netdev = alloc_etherdev_mqs(sizeof(*adapter), MAX_TX_QS, MAX_RX_QS); if (netdev == NULL) { status = -ENOMEM; goto rel_reg; -- GitLab From 421737bdd51912d136ca3e554f54731039d95847 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:21 +0000 Subject: [PATCH 0773/6849] be2net: remove unnecessary usage of unlikely() Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 3aa478f50358..42ee75b794b6 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -719,8 +719,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, * 60 bytes long. * As a workaround disable TX vlan offloading in such cases. */ - if (unlikely(vlan_tx_tag_present(skb) && - (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) { + if (vlan_tx_tag_present(skb) && + (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60)) { skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) goto tx_drop; -- GitLab From d79c0a207aa3be002e1d9473ea98cc4f838e5a8b Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:22 +0000 Subject: [PATCH 0774/6849] be2net: do not use SCRATCHPAD register The CUST_SCRATCHPAD_CSR register is used for marking if FW cleanup is needed. This is used in a crash kernel scenario. Do no use this register as it is not available for some functions. Instead, always issue an FLR when a function is probed *except* when VFs are preset (enabled in the previous PF load). Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_hw.h | 2 -- drivers/net/ethernet/emulex/benet/be_main.c | 10 +++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index d9fb0c501fa1..7c8a710eac2f 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h @@ -58,8 +58,6 @@ #define SLI_PORT_CONTROL_IP_MASK 0x08000000 -#define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC - /********* Memory BAR register ************/ #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 42ee75b794b6..f29827f657eb 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1049,6 +1049,8 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state) u16 offset, stride; pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) + return 0; pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset); pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride); @@ -2542,7 +2544,6 @@ static int be_clear(struct be_adapter *adapter) be_cmd_fw_clean(adapter); be_msix_disable(adapter); - pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0); return 0; } @@ -2785,8 +2786,6 @@ static int be_setup(struct be_adapter *adapter) schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; - - pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1); return 0; err: be_clear(adapter); @@ -3724,10 +3723,7 @@ reschedule: static bool be_reset_required(struct be_adapter *adapter) { - u32 reg; - - pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®); - return reg; + return be_find_vfs(adapter, ENABLED) > 0 ? false : true; } static int __devinit be_probe(struct pci_dev *pdev, -- GitLab From 20d5ec435c5fba8142eb7df692a5f54fbb26e892 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Jun 2012 19:37:23 +0000 Subject: [PATCH 0775/6849] be2net: update driver version Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index c5c4c0e83bd1..7b5cc2b212e5 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -34,7 +34,7 @@ #include "be_hw.h" #include "be_roce.h" -#define DRV_VER "4.2.220u" +#define DRV_VER "4.2.248.0u" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" -- GitLab From 2c0133a437905591cdaa39cf65a3f7188d20a094 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 18 May 2012 07:46:36 +0300 Subject: [PATCH 0776/6849] wlcore/wl12xx/wl18xx: introduce quirk to remove TKIP header space 18xx chips do not require extra space in the TKIP header. Introduce a new HW quirk to allow us to make this feature arch-specific. 12xx chip will now have this quirk. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 9 ++++++--- drivers/net/wireless/ti/wl18xx/tx.c | 3 ++- drivers/net/wireless/ti/wlcore/cmd.c | 5 +++-- drivers/net/wireless/ti/wlcore/main.c | 8 +++++--- drivers/net/wireless/ti/wlcore/tx.c | 9 ++++++--- drivers/net/wireless/ti/wlcore/wlcore.h | 3 +++ 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 77e0f318aa67..d33117efec79 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -625,7 +625,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", wl->chip.id); - wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; + wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | + WLCORE_QUIRK_TKIP_HEADER_SPACE; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->mr_fw_name = WL127X_FW_NAME_MULTI; memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x, @@ -640,7 +641,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", wl->chip.id); - wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; + wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | + WLCORE_QUIRK_TKIP_HEADER_SPACE; wl->plt_fw_name = WL127X_PLT_FW_NAME; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->mr_fw_name = WL127X_FW_NAME_MULTI; @@ -660,7 +662,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->mr_fw_name = WL128X_FW_NAME_MULTI; /* wl128x requires TX blocksize alignment */ - wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; + wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | + WLCORE_QUIRK_TKIP_HEADER_SPACE; break; case CHIP_ID_1283_PG10: diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c index 4de00b901505..5b1fb10d9fd7 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.c +++ b/drivers/net/wireless/ti/wl18xx/tx.c @@ -75,7 +75,8 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); /* remove TKIP header space if present */ - if (info->control.hw_key && + if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && + info->control.hw_key && info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, hdrlen); diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index df8d672b1f06..885364ca4344 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -1046,7 +1046,7 @@ out: int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) { - int ret, extra; + int ret, extra = 0; u16 fc; struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); struct sk_buff *skb; @@ -1085,7 +1085,8 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) /* encryption space */ switch (wlvif->encryption_type) { case KEY_TKIP: - extra = WL1271_EXTRA_SPACE_TKIP; + if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) + extra = WL1271_EXTRA_SPACE_TKIP; break; case KEY_AES: extra = WL1271_EXTRA_SPACE_AES; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 414fde41072c..5ac062831666 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4975,9 +4975,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) WL1271_CIPHER_SUITE_GEM, }; - /* The tx descriptor buffer and the TKIP space. */ - wl->hw->extra_tx_headroom = WL1271_EXTRA_SPACE_TKIP + - sizeof(struct wl1271_tx_hw_descr); + /* The tx descriptor buffer */ + wl->hw->extra_tx_headroom = sizeof(struct wl1271_tx_hw_descr); + + if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) + wl->hw->extra_tx_headroom += WL1271_EXTRA_SPACE_TKIP; /* unit us */ /* FIXME: find a proper value */ diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index e8a2998408b6..6b68e29a1e92 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -358,7 +358,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, /* TODO: handle dummy packets on multi-vifs */ is_dummy = wl12xx_is_dummy_packet(wl, skb); - if (info->control.hw_key && + if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && + info->control.hw_key && info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) extra = WL1271_EXTRA_SPACE_TKIP; @@ -852,7 +853,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); /* remove TKIP header space if present */ - if (info->control.hw_key && + if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && + info->control.hw_key && info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, @@ -1001,7 +1003,8 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) */ info = IEEE80211_SKB_CB(skb); skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); - if (info->control.hw_key && + if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && + info->control.hw_key && info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 37a80f4bf5bb..16c28bbd1b20 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -411,6 +411,9 @@ int wlcore_free_hw(struct wl1271 *wl); /* Some firmwares may not support ELP */ #define WLCORE_QUIRK_NO_ELP BIT(6) +/* extra header space is required for TKIP */ +#define WLCORE_QUIRK_TKIP_HEADER_SPACE BIT(8) + /* TODO: move to the lower drivers when all usages are abstracted */ #define CHIP_ID_1271_PG10 (0x4030101) #define CHIP_ID_1271_PG20 (0x4030111) -- GitLab From 32bb2c03f990d015c0fec67e9134ea8625aaf784 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 18 May 2012 07:46:37 +0300 Subject: [PATCH 0777/6849] wlcore/wl12xx/wl18xx: handle spare blocks spacial cases per arch Add a HW op for getting spare blocks. 12xx cards require 2 spare blocks for GEM encrypted SKBs, regardless of VIFs or keys programmed into the FW. 18xx cards require 2 spare blocks when there are any connected TKIP or GEM VIFs. For now always return 2 spare blocks, as this works with all networks. The special case TKIP/GEM functionality is added at a later patch. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 11 +++++++++-- drivers/net/wireless/ti/wl18xx/main.c | 11 ++++++++--- drivers/net/wireless/ti/wl18xx/tx.h | 3 ++- drivers/net/wireless/ti/wlcore/debugfs.c | 1 - drivers/net/wireless/ti/wlcore/hw_ops.h | 9 +++++++++ drivers/net/wireless/ti/wlcore/main.c | 11 ----------- drivers/net/wireless/ti/wlcore/tx.c | 20 ++++++++++---------- drivers/net/wireless/ti/wlcore/wlcore.h | 5 +---- drivers/net/wireless/ti/wlcore/wlcore_i.h | 3 --- 9 files changed, 39 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index d33117efec79..03ff1ce56bb4 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1361,6 +1361,14 @@ out: return ret; } +static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) +{ + if (is_gem) + return WL12XX_TX_HW_BLOCK_GEM_SPARE; + + return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; +} + static struct wlcore_ops wl12xx_ops = { .identify_chip = wl12xx_identify_chip, .identify_fw = wl12xx_identify_fw, @@ -1384,6 +1392,7 @@ static struct wlcore_ops wl12xx_ops = { .set_rx_csum = NULL, .ap_get_mimo_wide_rate_mask = NULL, .debugfs_init = wl12xx_debugfs_add_files, + .get_spare_blocks = wl12xx_get_spare_blocks, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { @@ -1419,8 +1428,6 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) wl->rtable = wl12xx_rtable; wl->num_tx_desc = 16; wl->num_rx_desc = 8; - wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; - wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE; wl->band_rate_to_idx = wl12xx_band_rate_to_idx; wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index d67be3eae3d9..c651f872d7d5 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -874,7 +874,7 @@ static int wl18xx_hw_init(struct wl1271 *wl) ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, sdio_align_size, - WL18XX_TX_HW_BLOCK_SPARE, + WL18XX_TX_HW_EXTRA_BLOCK_SPARE, WL18XX_HOST_IF_LEN_SIZE_FIELD); if (ret < 0) return ret; @@ -1034,6 +1034,12 @@ static int wl18xx_handle_static_data(struct wl1271 *wl, return 0; } +static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) +{ + /* TODO: dynamically change to extra only when we have GEM or TKIP */ + return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -1056,6 +1062,7 @@ static struct wlcore_ops wl18xx_ops = { .get_mac = wl18xx_get_mac, .debugfs_init = wl18xx_debugfs_add_files, .handle_static_data = wl18xx_handle_static_data, + .get_spare_blocks = wl18xx_get_spare_blocks, }; /* HT cap appropriate for wide channels */ @@ -1129,8 +1136,6 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) wl->rtable = wl18xx_rtable; wl->num_tx_desc = 32; wl->num_rx_desc = 16; - wl->normal_tx_spare = WL18XX_TX_HW_BLOCK_SPARE; - wl->gem_tx_spare = WL18XX_TX_HW_GEM_BLOCK_SPARE; wl->band_rate_to_idx = wl18xx_band_rate_to_idx; wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h index 2417262de207..8aecaf09da9c 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.h +++ b/drivers/net/wireless/ti/wl18xx/tx.h @@ -25,7 +25,8 @@ #include "../wlcore/wlcore.h" #define WL18XX_TX_HW_BLOCK_SPARE 1 -#define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 +/* for special cases - namely, TKIP and GEM */ +#define WL18XX_TX_HW_EXTRA_BLOCK_SPARE 2 #define WL18XX_TX_HW_BLOCK_SIZE 268 #define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index fc44262e4cf0..fcd60636e9d1 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -507,7 +507,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf, VIF_STATE_PRINT_INT(last_rssi_event); VIF_STATE_PRINT_INT(ba_support); VIF_STATE_PRINT_INT(ba_allowed); - VIF_STATE_PRINT_INT(is_gem); VIF_STATE_PRINT_LLHEX(tx_security_seq); VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); } diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index c590b6f529d1..2cb35218ba47 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -167,4 +167,13 @@ wlcore_handle_static_data(struct wl1271 *wl, void *static_data) return 0; } +static inline int +wlcore_hw_get_spare_blocks(struct wl1271 *wl, bool is_gem) +{ + if (!wl->ops->get_spare_blocks) + BUG_ON(1); + + return wl->ops->get_spare_blocks(wl, is_gem); +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 5ac062831666..0f25d4eea037 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2799,17 +2799,6 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, int ret; bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); - /* - * A role set to GEM cipher requires different Tx settings (namely - * spare blocks). Note when we are in this mode so the HW can adjust. - */ - if (key_type == KEY_GEM) { - if (action == KEY_ADD_OR_REPLACE) - wlvif->is_gem = true; - else if (action == KEY_REMOVE) - wlvif->is_gem = false; - } - if (is_ap) { struct wl1271_station *wl_sta; u8 hlid; diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 6b68e29a1e92..0949ab1f5972 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -187,28 +187,24 @@ EXPORT_SYMBOL(wlcore_calc_packet_alignment); static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct sk_buff *skb, u32 extra, u32 buf_offset, - u8 hlid) + u8 hlid, bool is_gem) { struct wl1271_tx_hw_descr *desc; u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; u32 total_blocks; int id, ret = -EBUSY, ac; - u32 spare_blocks = wl->normal_tx_spare; - bool is_dummy = false; + u32 spare_blocks; if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) return -EAGAIN; + spare_blocks = wlcore_hw_get_spare_blocks(wl, is_gem); + /* allocate free identifier for the packet */ id = wl1271_alloc_tx_id(wl, skb); if (id < 0) return id; - if (unlikely(wl12xx_is_dummy_packet(wl, skb))) - is_dummy = true; - else if (wlvif->is_gem) - spare_blocks = wl->gem_tx_spare; - total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); if (total_blocks <= wl->tx_blocks_available) { @@ -230,7 +226,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); wl->tx_allocated_pkts[ac]++; - if (!is_dummy && wlvif && + if (!wl12xx_is_dummy_packet(wl, skb) && wlvif && wlvif->bss_type == BSS_TYPE_AP_BSS && test_bit(hlid, wlvif->ap.sta_hlid_map)) wl->links[hlid].allocated_pkts++; @@ -349,6 +345,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, u32 total_len; u8 hlid; bool is_dummy; + bool is_gem = false; if (!skb) return -EINVAL; @@ -377,6 +374,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, return ret; wlvif->default_key = idx; } + + is_gem = (cipher == WL1271_CIPHER_SUITE_GEM); } hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); if (hlid == WL12XX_INVALID_LINK_ID) { @@ -384,7 +383,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, return -EINVAL; } - ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid); + ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid, + is_gem); if (ret < 0) return ret; diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 16c28bbd1b20..5274ace6c8e4 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -75,6 +75,7 @@ struct wlcore_ops { int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); int (*handle_static_data)(struct wl1271 *wl, struct wl1271_static_data *static_data); + int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); }; enum wlcore_partitions { @@ -354,10 +355,6 @@ struct wl1271 { /* number of RX descriptors the HW supports. */ u32 num_rx_desc; - /* spare Tx blocks for normal/GEM operating modes */ - u32 normal_tx_spare; - u32 gem_tx_spare; - /* translate HW Tx rates to standard rate-indices */ const u8 **band_rate_to_idx; diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 83c9869105c3..8260b1e9288a 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -417,9 +417,6 @@ struct wl12xx_vif { struct work_struct rx_streaming_disable_work; struct timer_list rx_streaming_timer; - /* does the current role use GEM for encryption (AP or STA) */ - bool is_gem; - /* * This struct must be last! * data that has to be saved acrossed reconfigs (e.g. recovery) -- GitLab From 6639611467f34038aa63c5cb9f8d9e48171d6022 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 18 May 2012 07:46:38 +0300 Subject: [PATCH 0778/6849] wlcore: add stop reason bitmap for waking/starting queues Allow the driver to wake/stop the queues for multiple reasons. A queue is started when no stop-reasons exist. Convert all wake/stop queue calls to use the new API. Before, a stopped queue was almost synonymous a high-watermark on Tx. Remove a bit of code in wl12xx_tx_reset() that relied on it. Internal packets arriving from mac80211 are also discarded when a queue is stopped. A notable exception to this is the watermark reason, which is a "soft"-stop reason. We allow traffic to gradually come to a halt, but we don't mind spurious packets here and there. This is merely a flow regulation mechanism. Based on a similar patch by Eliad Peller . Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 21 +++-- drivers/net/wireless/ti/wlcore/tx.c | 109 +++++++++++++++++++++--- drivers/net/wireless/ti/wlcore/tx.h | 21 ++++- drivers/net/wireless/ti/wlcore/wlcore.h | 2 +- 4 files changed, 132 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0f25d4eea037..bbab19a1ce8a 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -865,7 +865,7 @@ static void wl1271_recovery_work(struct work_struct *work) } /* Prevent spurious TX during FW restart */ - ieee80211_stop_queues(wl->hw); + wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); if (wl->sched_scanning) { ieee80211_sched_scan_stopped(wl->hw); @@ -890,7 +890,7 @@ static void wl1271_recovery_work(struct work_struct *work) * Its safe to enable TX now - the queues are stopped after a request * to restart the HW. */ - ieee80211_wake_queues(wl->hw); + wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); return; out_unlock: mutex_unlock(&wl->mutex); @@ -1107,9 +1107,16 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) spin_lock_irqsave(&wl->wl_lock, flags); - /* queue the packet */ + /* + * drop the packet if the link is invalid or the queue is stopped + * for any reason but watermark. Watermark is a "soft"-stop so we + * allow these packets through. + */ if (hlid == WL12XX_INVALID_LINK_ID || - (wlvif && !test_bit(hlid, wlvif->links_map))) { + (wlvif && !test_bit(hlid, wlvif->links_map)) || + (wlcore_is_queue_stopped(wl, q) && + !wlcore_is_queue_stopped_by_reason(wl, q, + WLCORE_QUEUE_STOP_REASON_WATERMARK))) { wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q); ieee80211_free_txskb(hw, skb); goto out; @@ -1127,8 +1134,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) */ if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK) { wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q); - ieee80211_stop_queue(wl->hw, mapping); - set_bit(q, &wl->stopped_queues_map); + wlcore_stop_queue_locked(wl, q, + WLCORE_QUEUE_STOP_REASON_WATERMARK); } /* @@ -1711,7 +1718,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&wl->connection_loss_work); /* let's notify MAC80211 about the remaining pending TX frames */ - wl12xx_tx_reset(wl, true); + wl12xx_tx_reset(wl); mutex_lock(&wl->mutex); wl1271_power_off(wl); diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 0949ab1f5972..f68567b1524c 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -443,18 +443,15 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, void wl1271_handle_tx_low_watermark(struct wl1271 *wl) { - unsigned long flags; int i; for (i = 0; i < NUM_TX_QUEUES; i++) { - if (test_bit(i, &wl->stopped_queues_map) && + if (wlcore_is_queue_stopped_by_reason(wl, i, + WLCORE_QUEUE_STOP_REASON_WATERMARK) && wl->tx_queue_count[i] <= WL1271_TX_QUEUE_LOW_WATERMARK) { /* firmware buffer has space, restart queues */ - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queue(wl->hw, - wl1271_tx_get_mac80211_queue(i)); - clear_bit(i, &wl->stopped_queues_map); - spin_unlock_irqrestore(&wl->wl_lock, flags); + wlcore_wake_queue(wl, i, + WLCORE_QUEUE_STOP_REASON_WATERMARK); } } } @@ -963,7 +960,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) } /* caller must hold wl->mutex and TX must be stopped */ -void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) +void wl12xx_tx_reset(struct wl1271 *wl) { int i; struct sk_buff *skb; @@ -978,15 +975,12 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) wl->tx_queue_count[i] = 0; } - wl->stopped_queues_map = 0; - /* * Make sure the driver is at a consistent state, in case this * function is called from a context other than interface removal. * This call will always wake the TX queues. */ - if (reset_tx_queues) - wl1271_handle_tx_low_watermark(wl); + wl1271_handle_tx_low_watermark(wl); for (i = 0; i < wl->num_tx_desc; i++) { if (wl->tx_frames[i] == NULL) @@ -1060,3 +1054,94 @@ u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) return BIT(__ffs(rate_set)); } + +void wlcore_stop_queue_locked(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason) +{ + bool stopped = !!wl->queue_stop_reasons[queue]; + + /* queue should not be stopped for this reason */ + WARN_ON(test_and_set_bit(reason, &wl->queue_stop_reasons[queue])); + + if (stopped) + return; + + ieee80211_stop_queue(wl->hw, wl1271_tx_get_mac80211_queue(queue)); +} + +void wlcore_stop_queue(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason) +{ + unsigned long flags; + + spin_lock_irqsave(&wl->wl_lock, flags); + wlcore_stop_queue_locked(wl, queue, reason); + spin_unlock_irqrestore(&wl->wl_lock, flags); +} + +void wlcore_wake_queue(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason) +{ + unsigned long flags; + + spin_lock_irqsave(&wl->wl_lock, flags); + + /* queue should not be clear for this reason */ + WARN_ON(!test_and_clear_bit(reason, &wl->queue_stop_reasons[queue])); + + if (wl->queue_stop_reasons[queue]) + goto out; + + ieee80211_wake_queue(wl->hw, wl1271_tx_get_mac80211_queue(queue)); + +out: + spin_unlock_irqrestore(&wl->wl_lock, flags); +} + +void wlcore_stop_queues(struct wl1271 *wl, + enum wlcore_queue_stop_reason reason) +{ + int i; + + for (i = 0; i < NUM_TX_QUEUES; i++) + wlcore_stop_queue(wl, i, reason); +} + +void wlcore_wake_queues(struct wl1271 *wl, + enum wlcore_queue_stop_reason reason) +{ + int i; + + for (i = 0; i < NUM_TX_QUEUES; i++) + wlcore_wake_queue(wl, i, reason); +} + +void wlcore_reset_stopped_queues(struct wl1271 *wl) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&wl->wl_lock, flags); + + for (i = 0; i < NUM_TX_QUEUES; i++) { + if (!wl->queue_stop_reasons[i]) + continue; + + wl->queue_stop_reasons[i] = 0; + ieee80211_wake_queue(wl->hw, + wl1271_tx_get_mac80211_queue(i)); + } + + spin_unlock_irqrestore(&wl->wl_lock, flags); +} + +bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason) +{ + return test_bit(reason, &wl->queue_stop_reasons[queue]); +} + +bool wlcore_is_queue_stopped(struct wl1271 *wl, u8 queue) +{ + return !!wl->queue_stop_reasons[queue]; +} diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index e24c436bf65f..6bf695681762 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -184,6 +184,11 @@ struct wl1271_tx_hw_res_if { struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; } __packed; +enum wlcore_queue_stop_reason { + WLCORE_QUEUE_STOP_REASON_WATERMARK, + WLCORE_QUEUE_STOP_REASON_FW_RESTART, +}; + static inline int wl1271_tx_get_queue(int queue) { switch (queue) { @@ -230,7 +235,7 @@ void wl1271_tx_work(struct work_struct *work); void wl1271_tx_work_locked(struct wl1271 *wl); void wl1271_tx_complete(struct wl1271 *wl); void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); -void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues); +void wl12xx_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band); u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, @@ -247,6 +252,20 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, unsigned int packet_length); void wl1271_free_tx_id(struct wl1271 *wl, int id); +void wlcore_stop_queue_locked(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason); +void wlcore_stop_queue(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason); +void wlcore_wake_queue(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason); +void wlcore_stop_queues(struct wl1271 *wl, + enum wlcore_queue_stop_reason reason); +void wlcore_wake_queues(struct wl1271 *wl, + enum wlcore_queue_stop_reason reason); +void wlcore_reset_stopped_queues(struct wl1271 *wl); +bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl, u8 queue, + enum wlcore_queue_stop_reason reason); +bool wlcore_is_queue_stopped(struct wl1271 *wl, u8 queue); /* from main.c */ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 5274ace6c8e4..681054331fd2 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -209,7 +209,7 @@ struct wl1271 { /* Frames scheduled for transmission, not handled yet */ int tx_queue_count[NUM_TX_QUEUES]; - long stopped_queues_map; + unsigned long queue_stop_reasons[NUM_TX_QUEUES]; /* Frames received, not handled yet by mac80211 */ struct sk_buff_head deferred_rx_queue; -- GitLab From 2c38849f4a247673c8203a569444042e32d82410 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 18 May 2012 07:46:39 +0300 Subject: [PATCH 0779/6849] wlcore: stop queues on Tx flush Stop network queues during Tx flush, and also drop other internal mac80211 packets (mgmt) that may arrive when the queues are stopped. When flush is done all driver queues are clear, forcefully if needed. Protect the Tx flush operation with a new mutex, to prevent concurrency that can mess us queue state. Based on a patch by Eliad Peller Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 1 + drivers/net/wireless/ti/wlcore/tx.c | 11 ++++++++++- drivers/net/wireless/ti/wlcore/tx.h | 1 + drivers/net/wireless/ti/wlcore/wlcore.h | 3 +++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index bbab19a1ce8a..d81c86cbbf71 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5148,6 +5148,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) wl->state = WL1271_STATE_OFF; wl->fw_type = WL12XX_FW_TYPE_NONE; mutex_init(&wl->mutex); + mutex_init(&wl->flush_mutex); order = get_order(WL1271_AGGR_BUFFER_SIZE); wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index f68567b1524c..78bf1b9208a9 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -1024,6 +1024,11 @@ void wl1271_tx_flush(struct wl1271 *wl) int i; timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); + /* only one flush should be in progress, for consistent queue state */ + mutex_lock(&wl->flush_mutex); + + wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); + while (!time_after(jiffies, timeout)) { mutex_lock(&wl->mutex); wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d", @@ -1032,7 +1037,7 @@ void wl1271_tx_flush(struct wl1271 *wl) if ((wl->tx_frames_cnt == 0) && (wl1271_tx_total_queue_count(wl) == 0)) { mutex_unlock(&wl->mutex); - return; + goto out; } mutex_unlock(&wl->mutex); msleep(1); @@ -1045,6 +1050,10 @@ void wl1271_tx_flush(struct wl1271 *wl) for (i = 0; i < WL12XX_MAX_LINKS; i++) wl1271_tx_reset_link_queues(wl, i); mutex_unlock(&wl->mutex); + +out: + wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); + mutex_unlock(&wl->flush_mutex); } u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 6bf695681762..e058a55f533d 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -187,6 +187,7 @@ struct wl1271_tx_hw_res_if { enum wlcore_queue_stop_reason { WLCORE_QUEUE_STOP_REASON_WATERMARK, WLCORE_QUEUE_STOP_REASON_FW_RESTART, + WLCORE_QUEUE_STOP_REASON_FLUSH, }; static inline int wl1271_tx_get_queue(int queue) diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 681054331fd2..99a061950a3a 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -378,6 +378,9 @@ struct wl1271 { /* the current channel type */ enum nl80211_channel_type channel_type; + + /* mutex for protecting the tx_flush function */ + struct mutex flush_mutex; }; int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); -- GitLab From a1c597f2b22cdc228de3c58784b00e80b9b53e03 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 18 May 2012 07:46:40 +0300 Subject: [PATCH 0780/6849] wlcore/wl12xx/wl18xx: implement op_set_key per HW arch The 12xx set_key just calls the common wlcore_set_key function, in order to program the keys into the FW. The 18xx variant changes the spare block count when a GEM or TKIP key is set. Also modify the get_spare_blocks HW op for 18xx to return the correct numbers of spare blocks, according to what is currently set in FW. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 9 +++ drivers/net/wireless/ti/wl18xx/acx.c | 4 ++ drivers/net/wireless/ti/wl18xx/main.c | 96 +++++++++++++++++++++---- drivers/net/wireless/ti/wl18xx/wl18xx.h | 3 + drivers/net/wireless/ti/wlcore/hw_ops.h | 12 ++++ drivers/net/wireless/ti/wlcore/main.c | 14 +++- drivers/net/wireless/ti/wlcore/tx.c | 3 + drivers/net/wireless/ti/wlcore/tx.h | 1 + drivers/net/wireless/ti/wlcore/wlcore.h | 8 +++ 9 files changed, 136 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 03ff1ce56bb4..2f6a39bfcf18 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1369,6 +1369,14 @@ static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; } +static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf) +{ + return wlcore_set_key(wl, cmd, vif, sta, key_conf); +} + static struct wlcore_ops wl12xx_ops = { .identify_chip = wl12xx_identify_chip, .identify_fw = wl12xx_identify_fw, @@ -1393,6 +1401,7 @@ static struct wlcore_ops wl12xx_ops = { .ap_get_mimo_wide_rate_mask = NULL, .debugfs_init = wl12xx_debugfs_add_files, .get_spare_blocks = wl12xx_get_spare_blocks, + .set_key = wl12xx_set_key, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c index 3379db23a165..01ba40321435 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.c +++ b/drivers/net/wireless/ti/wl18xx/acx.c @@ -32,6 +32,10 @@ int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, struct wl18xx_acx_host_config_bitmap *bitmap_conf; int ret; + wl1271_debug(DEBUG_ACX, "acx cfg bitmap %d blk %d spare %d field %d", + host_cfg_bitmap, sdio_blk_size, extra_mem_blks, + len_field_size); + bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); if (!bitmap_conf) { ret = -ENOMEM; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index c651f872d7d5..9e5ce569f8da 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -848,17 +848,12 @@ static void wl18xx_tx_immediate_completion(struct wl1271 *wl) wl18xx_tx_immediate_complete(wl); } -static int wl18xx_hw_init(struct wl1271 *wl) +static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk) { int ret; - struct wl18xx_priv *priv = wl->priv; - u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE | - HOST_IF_CFG_ADD_RX_ALIGNMENT; - u32 sdio_align_size = 0; - - /* (re)init private structures. Relevant on recovery as well. */ - priv->last_fw_rls_idx = 0; + u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE | + HOST_IF_CFG_ADD_RX_ALIGNMENT; /* Enable Tx SDIO padding */ if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) { @@ -873,12 +868,28 @@ static int wl18xx_hw_init(struct wl1271 *wl) } ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, - sdio_align_size, - WL18XX_TX_HW_EXTRA_BLOCK_SPARE, + sdio_align_size, extra_mem_blk, WL18XX_HOST_IF_LEN_SIZE_FIELD); if (ret < 0) return ret; + return 0; +} + +static int wl18xx_hw_init(struct wl1271 *wl) +{ + int ret; + struct wl18xx_priv *priv = wl->priv; + + /* (re)init private structures. Relevant on recovery as well. */ + priv->last_fw_rls_idx = 0; + priv->extra_spare_vif_count = 0; + + /* set the default amount of spare blocks in the bitmap */ + ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE); + if (ret < 0) + return ret; + if (checksum_param) { ret = wl18xx_acx_set_checksum_state(wl); if (ret != 0) @@ -1036,8 +1047,68 @@ static int wl18xx_handle_static_data(struct wl1271 *wl, static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) { - /* TODO: dynamically change to extra only when we have GEM or TKIP */ - return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; + struct wl18xx_priv *priv = wl->priv; + + /* If we have VIFs requiring extra spare, indulge them */ + if (priv->extra_spare_vif_count) + return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; + + return WL18XX_TX_HW_BLOCK_SPARE; +} + +static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf) +{ + struct wl18xx_priv *priv = wl->priv; + bool change_spare = false; + int ret; + + /* + * when adding the first or removing the last GEM/TKIP interface, + * we have to adjust the number of spare blocks. + */ + change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM || + key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) && + ((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) || + (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY)); + + /* no need to change spare - just regular set_key */ + if (!change_spare) + return wlcore_set_key(wl, cmd, vif, sta, key_conf); + + /* + * stop the queues and flush to ensure the next packets are + * in sync with FW spare block accounting + */ + wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK); + wl1271_tx_flush(wl); + + ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); + if (ret < 0) + goto out; + + /* key is now set, change the spare blocks */ + if (cmd == SET_KEY) { + ret = wl18xx_set_host_cfg_bitmap(wl, + WL18XX_TX_HW_EXTRA_BLOCK_SPARE); + if (ret < 0) + goto out; + + priv->extra_spare_vif_count++; + } else { + ret = wl18xx_set_host_cfg_bitmap(wl, + WL18XX_TX_HW_BLOCK_SPARE); + if (ret < 0) + goto out; + + priv->extra_spare_vif_count--; + } + +out: + wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK); + return ret; } static struct wlcore_ops wl18xx_ops = { @@ -1063,6 +1134,7 @@ static struct wlcore_ops wl18xx_ops = { .debugfs_init = wl18xx_debugfs_add_files, .handle_static_data = wl18xx_handle_static_data, .get_spare_blocks = wl18xx_get_spare_blocks, + .set_key = wl18xx_set_key, }; /* HT cap appropriate for wide channels */ diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index 34e202bc2bb3..b9c43097d2f6 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -36,6 +36,9 @@ struct wl18xx_priv { u8 last_fw_rls_idx; u8 board_type; + + /* number of VIFs requiring extra spare mem-blocks */ + int extra_spare_vif_count; }; #define WL18XX_FW_MAX_TX_STATUS_DESC 33 diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 2cb35218ba47..34e0498727fc 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -176,4 +176,16 @@ wlcore_hw_get_spare_blocks(struct wl1271 *wl, bool is_gem) return wl->ops->get_spare_blocks(wl, is_gem); } +static inline int +wlcore_hw_set_key(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf) +{ + if (!wl->ops->set_key) + BUG_ON(1); + + return wl->ops->set_key(wl, cmd, vif, sta, key_conf); +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index d81c86cbbf71..7c4f78136bb1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2883,12 +2883,21 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, return 0; } -static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, +static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key_conf) { struct wl1271 *wl = hw->priv; + + return wlcore_hw_set_key(wl, cmd, vif, sta, key_conf); +} + +int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf) +{ struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); int ret; u32 tx_seq_32 = 0; @@ -2999,6 +3008,7 @@ out_unlock: return ret; } +EXPORT_SYMBOL_GPL(wlcore_set_key); static int wl1271_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -4643,7 +4653,7 @@ static const struct ieee80211_ops wl1271_ops = { .prepare_multicast = wl1271_op_prepare_multicast, .configure_filter = wl1271_op_configure_filter, .tx = wl1271_op_tx, - .set_key = wl1271_op_set_key, + .set_key = wlcore_op_set_key, .hw_scan = wl1271_op_hw_scan, .cancel_hw_scan = wl1271_op_cancel_hw_scan, .sched_scan_start = wl1271_op_sched_scan_start, diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 78bf1b9208a9..da9a07d2cf4b 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -1055,6 +1055,7 @@ out: wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); mutex_unlock(&wl->flush_mutex); } +EXPORT_SYMBOL_GPL(wl1271_tx_flush); u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) { @@ -1115,6 +1116,7 @@ void wlcore_stop_queues(struct wl1271 *wl, for (i = 0; i < NUM_TX_QUEUES; i++) wlcore_stop_queue(wl, i, reason); } +EXPORT_SYMBOL_GPL(wlcore_stop_queues); void wlcore_wake_queues(struct wl1271 *wl, enum wlcore_queue_stop_reason reason) @@ -1124,6 +1126,7 @@ void wlcore_wake_queues(struct wl1271 *wl, for (i = 0; i < NUM_TX_QUEUES; i++) wlcore_wake_queue(wl, i, reason); } +EXPORT_SYMBOL_GPL(wlcore_wake_queues); void wlcore_reset_stopped_queues(struct wl1271 *wl) { diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index e058a55f533d..49e441f34839 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -188,6 +188,7 @@ enum wlcore_queue_stop_reason { WLCORE_QUEUE_STOP_REASON_WATERMARK, WLCORE_QUEUE_STOP_REASON_FW_RESTART, WLCORE_QUEUE_STOP_REASON_FLUSH, + WLCORE_QUEUE_STOP_REASON_SPARE_BLK, /* 18xx specific */ }; static inline int wl1271_tx_get_queue(int queue) diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 99a061950a3a..4ca968fac0eb 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -76,6 +76,10 @@ struct wlcore_ops { int (*handle_static_data)(struct wl1271 *wl, struct wl1271_static_data *static_data); int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); + int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf); }; enum wlcore_partitions { @@ -387,6 +391,10 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); int __devexit wlcore_remove(struct platform_device *pdev); struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); int wlcore_free_hw(struct wl1271 *wl); +int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf); /* Firmware image load chunk size */ #define CHUNK_SIZE 16384 -- GitLab From afbe37185c0ecad3442791be666b6851eba52318 Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Wed, 16 May 2012 11:34:18 +0300 Subject: [PATCH 0781/6849] wlcore: do not send stop fwlog cmd if fw is hanged If the driver received a watchdog interrupt then the assumption is that the fw is hanged. Avoid sending the stop fwlog command in case of a watchdog recovey to avoid waiting for the 2 seconds timeout of the command. Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 9 +++++++-- drivers/net/wireless/ti/wlcore/wlcore.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 7c4f78136bb1..54da16501e42 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -544,6 +544,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { wl1271_error("watchdog interrupt received! " "starting recovery."); + wl->watchdog_recovery = true; wl12xx_queue_recovery_work(wl); /* restarting the chip. ignore any other interrupt. */ @@ -782,10 +783,12 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) /* * Make sure the chip is awake and the logger isn't active. - * This might fail if the firmware hanged. + * Do not send a stop fwlog command if the fw is hanged. */ - if (!wl1271_ps_elp_wakeup(wl)) + if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery) wl12xx_cmd_stop_fwlog(wl); + else + goto out; /* Read the first memory block address */ wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); @@ -879,6 +882,7 @@ static void wl1271_recovery_work(struct work_struct *work) vif = wl12xx_wlvif_to_vif(wlvif); __wl1271_op_remove_interface(wl, vif, false); } + wl->watchdog_recovery = false; mutex_unlock(&wl->mutex); wl1271_op_stop(wl->hw); @@ -893,6 +897,7 @@ static void wl1271_recovery_work(struct work_struct *work) wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); return; out_unlock: + wl->watchdog_recovery = false; mutex_unlock(&wl->mutex); } diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 4ca968fac0eb..e63450072f4d 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -252,6 +252,7 @@ struct wl1271 { /* Hardware recovery work */ struct work_struct recovery_work; + bool watchdog_recovery; /* Pointer that holds DMA-friendly block for the mailbox */ struct event_mailbox *mbox; -- GitLab From 9f5b424d6c44db1e02744ddc10c569dc7eb1c100 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 14:53:17 +0300 Subject: [PATCH 0782/6849] wl12xx: send beacon loss events to userspace Send beacon loss events to userspace, so it will be able to initiate roaming before disconnection Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/event.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 4ed835799178..c976f0409865 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -156,6 +156,15 @@ static int wl1271_event_process(struct wl1271 *wl) */ ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work, msecs_to_jiffies(delay)); + + wl12xx_for_each_wlvif_sta(wl, wlvif) { + vif = wl12xx_wlvif_to_vif(wlvif); + + ieee80211_cqm_rssi_notify( + vif, + NL80211_CQM_RSSI_BEACON_LOSS_EVENT, + GFP_KERNEL); + } } if (vector & REGAINED_BSS_EVENT_ID) { -- GitLab From 186b5a7c938b13b9f6ee2532a13596556c224df0 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 16:35:20 +0300 Subject: [PATCH 0783/6849] wl12xx/wl18xx: add erp protection IE to the beacon filter We have to reconfigure the fw when erp protection should be enabled/disabled. Pass beacons containing changes in the ERP protection IE, so we could analyze them. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 6 +++++- drivers/net/wireless/ti/wl18xx/main.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 2f6a39bfcf18..41017baaf253 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -216,7 +216,7 @@ static struct wlcore_conf wl12xx_conf = { .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, .suspend_listen_interval = 3, .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, - .bcn_filt_ie_count = 2, + .bcn_filt_ie_count = 3, .bcn_filt_ie = { [0] = { .ie = WLAN_EID_CHANNEL_SWITCH, @@ -226,6 +226,10 @@ static struct wlcore_conf wl12xx_conf = { .ie = WLAN_EID_HT_OPERATION, .rule = CONF_BCN_RULE_PASS_ON_CHANGE, }, + [2] = { + .ie = WLAN_EID_ERP_INFO, + .rule = CONF_BCN_RULE_PASS_ON_CHANGE, + }, }, .synch_fail_thold = 12, .bss_lose_timeout = 400, diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 9e5ce569f8da..c8d45f011c63 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -339,7 +339,7 @@ static struct wlcore_conf wl18xx_conf = { .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, .suspend_listen_interval = 3, .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, - .bcn_filt_ie_count = 2, + .bcn_filt_ie_count = 3, .bcn_filt_ie = { [0] = { .ie = WLAN_EID_CHANNEL_SWITCH, @@ -349,6 +349,10 @@ static struct wlcore_conf wl18xx_conf = { .ie = WLAN_EID_HT_OPERATION, .rule = CONF_BCN_RULE_PASS_ON_CHANGE, }, + [2] = { + .ie = WLAN_EID_ERP_INFO, + .rule = CONF_BCN_RULE_PASS_ON_CHANGE, + }, }, .synch_fail_thold = 12, .bss_lose_timeout = 400, -- GitLab From 6469933605a3ecdfa66b98160cde98ecd256cb3f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 4 Jun 2012 12:44:16 +0000 Subject: [PATCH 0784/6849] ethernet: Remove casts to same type Adding casts of objects to the same type is unnecessary and confusing for a human reader. For example, this cast: int y; int *p = (int *)&y; I used the coccinelle script below to find and remove these unnecessary casts. I manually removed the conversions this script produces of casts with __force, __iomem and __user. @@ type T; T *p; @@ - (T *)p + p A function in atl1e_main.c was passed a const pointer when it actually modified elements of the structure. Change the argument to a non-const pointer. A function in stmmac needed a __force to avoid a sparse warning. Added it. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/8390/apne.c | 2 +- drivers/net/ethernet/aeroflex/greth.c | 8 ++--- drivers/net/ethernet/amd/declance.c | 4 +-- drivers/net/ethernet/apple/macmace.c | 2 +- drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | 6 ++-- .../net/ethernet/atheros/atl1c/atl1c_main.c | 9 +++-- .../ethernet/atheros/atl1e/atl1e_ethtool.c | 2 +- .../net/ethernet/atheros/atl1e/atl1e_main.c | 35 ++++++++----------- drivers/net/ethernet/atheros/atlx/atl1.c | 2 +- drivers/net/ethernet/broadcom/bnx2.c | 3 +- drivers/net/ethernet/broadcom/cnic.c | 12 +++---- drivers/net/ethernet/brocade/bna/cna_fwimg.c | 4 +-- .../ethernet/chelsio/cxgb3/cxgb3_offload.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +- .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 5 ++- drivers/net/ethernet/dec/tulip/de4x5.c | 2 +- drivers/net/ethernet/freescale/ucc_geth.c | 2 +- drivers/net/ethernet/hp/hp100.c | 6 ++-- drivers/net/ethernet/i825xx/lp486e.c | 8 ++--- drivers/net/ethernet/i825xx/sun3_82586.c | 4 +-- drivers/net/ethernet/marvell/mv643xx_eth.c | 4 +-- drivers/net/ethernet/marvell/pxa168_eth.c | 4 +-- .../ethernet/mellanox/mlx4/resource_tracker.c | 4 +-- drivers/net/ethernet/neterion/s2io.c | 14 ++++---- .../net/ethernet/neterion/vxge/vxge-config.c | 8 ++--- .../net/ethernet/neterion/vxge/vxge-config.h | 2 +- .../net/ethernet/neterion/vxge/vxge-main.c | 8 ++--- .../net/ethernet/neterion/vxge/vxge-traffic.c | 5 ++- drivers/net/ethernet/sgi/ioc3-eth.c | 4 +-- drivers/net/ethernet/smsc/smsc9420.c | 3 +- .../ethernet/stmicro/stmmac/stmmac_platform.c | 2 +- drivers/net/ethernet/sun/sunqe.c | 2 +- drivers/net/ethernet/via/via-velocity.c | 2 +- 34 files changed, 87 insertions(+), 97 deletions(-) diff --git a/drivers/net/ethernet/8390/apne.c b/drivers/net/ethernet/8390/apne.c index 923959275a82..912ed7a5f33a 100644 --- a/drivers/net/ethernet/8390/apne.c +++ b/drivers/net/ethernet/8390/apne.c @@ -454,7 +454,7 @@ apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int rin buf[count-1] = inb(NE_BASE + NE_DATAPORT); } } else { - ptrc = (char*)buf; + ptrc = buf; for (cnt = 0; cnt < count; cnt++) *ptrc++ = inb(NE_BASE + NE_DATAPORT); } diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 348501178089..9c77c736f171 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1014,7 +1014,7 @@ static int greth_set_mac_add(struct net_device *dev, void *p) struct greth_regs *regs; greth = netdev_priv(dev); - regs = (struct greth_regs *) greth->regs; + regs = greth->regs; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; @@ -1036,7 +1036,7 @@ static void greth_set_hash_filter(struct net_device *dev) { struct netdev_hw_addr *ha; struct greth_private *greth = netdev_priv(dev); - struct greth_regs *regs = (struct greth_regs *) greth->regs; + struct greth_regs *regs = greth->regs; u32 mc_filter[2]; unsigned int bitnr; @@ -1055,7 +1055,7 @@ static void greth_set_multicast_list(struct net_device *dev) { int cfg; struct greth_private *greth = netdev_priv(dev); - struct greth_regs *regs = (struct greth_regs *) greth->regs; + struct greth_regs *regs = greth->regs; cfg = GRETH_REGLOAD(regs->control); if (dev->flags & IFF_PROMISC) @@ -1414,7 +1414,7 @@ static int __devinit greth_of_probe(struct platform_device *ofdev) goto error1; } - regs = (struct greth_regs *) greth->regs; + regs = greth->regs; greth->irq = ofdev->archdata.irqs[0]; dev_set_drvdata(greth->dev, dev); diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index 75299f500ee5..7203b522f234 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -623,7 +623,7 @@ static int lance_rx(struct net_device *dev) skb_put(skb, len); /* make room */ cp_from_buf(lp->type, skb->data, - (char *)lp->rx_buf_ptr_cpu[entry], len); + lp->rx_buf_ptr_cpu[entry], len); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); @@ -919,7 +919,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; - cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, len); + cp_to_buf(lp->type, lp->tx_buf_ptr_cpu[entry], skb->data, len); /* Now, give the packet to the lance */ *lib_ptr(ib, btx_ring[entry].tmd1, lp->type) = diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index ab7ff8645ab1..a92ddee7f665 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -228,7 +228,7 @@ static int __devinit mace_probe(struct platform_device *pdev) * bits are reversed. */ - addr = (void *)MACE_PROM; + addr = MACE_PROM; for (j = 0; j < 6; ++j) { u8 v = bitrev8(addr[j<<4]); diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index ff9c73859d45..801f0126512d 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c @@ -602,7 +602,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw) int atl1c_phy_init(struct atl1c_hw *hw) { - struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; + struct atl1c_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; int ret_val; u16 mii_bmcr_data = BMCR_RESET; @@ -696,7 +696,7 @@ int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex) /* select one link mode to get lower power consumption */ int atl1c_phy_to_ps_link(struct atl1c_hw *hw) { - struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; + struct atl1c_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; int ret = 0; u16 autoneg_advertised = ADVERTISED_10baseT_Half; @@ -768,7 +768,7 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw) int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc) { - struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; + struct atl1c_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; u32 master_ctrl, mac_ctrl, phy_ctrl; u32 wol_ctrl, speed; diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 9cc15701101b..85717cb306d1 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -989,12 +989,12 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter) } for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { tpd_ring[i].buffer_info = - (struct atl1c_buffer *) (tpd_ring->buffer_info + count); + (tpd_ring->buffer_info + count); count += tpd_ring[i].count; } rfd_ring->buffer_info = - (struct atl1c_buffer *) (tpd_ring->buffer_info + count); + (tpd_ring->buffer_info + count); count += rfd_ring->count; rx_desc_count += rfd_ring->count; @@ -1227,7 +1227,7 @@ static void atl1c_start_mac(struct atl1c_adapter *adapter) */ static int atl1c_reset_mac(struct atl1c_hw *hw) { - struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; + struct atl1c_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; u32 ctrl_data = 0; @@ -1531,8 +1531,7 @@ static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter) static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, enum atl1c_trans_queue type) { - struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) - &adapter->tpd_ring[type]; + struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; struct atl1c_buffer *buffer_info; struct pci_dev *pdev = adapter->pdev; u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c index 6e61f9f9ebb5..82b23861bf55 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c @@ -268,7 +268,7 @@ static int atl1e_set_eeprom(struct net_device *netdev, if (eeprom_buff == NULL) return -ENOMEM; - ptr = (u32 *)eeprom_buff; + ptr = eeprom_buff; if (eeprom->offset & 3) { /* need read/modify/write of first changed EEPROM word */ diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 1220e511ced6..0aed82e1bb3e 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -641,8 +641,7 @@ static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter) */ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) { - struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *) - &adapter->tx_ring; + struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; struct atl1e_tx_buffer *tx_buffer = NULL; struct pci_dev *pdev = adapter->pdev; u16 index, ring_count; @@ -686,7 +685,7 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter) { struct atl1e_rx_ring *rx_ring = - (struct atl1e_rx_ring *)&adapter->rx_ring; + &adapter->rx_ring; struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc; u16 i, j; @@ -884,14 +883,12 @@ failed: return err; } -static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter) +static inline void atl1e_configure_des_ring(struct atl1e_adapter *adapter) { - struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; - struct atl1e_rx_ring *rx_ring = - (struct atl1e_rx_ring *)&adapter->rx_ring; - struct atl1e_tx_ring *tx_ring = - (struct atl1e_tx_ring *)&adapter->tx_ring; + struct atl1e_hw *hw = &adapter->hw; + struct atl1e_rx_ring *rx_ring = &adapter->rx_ring; + struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; struct atl1e_rx_page_desc *rx_page_desc = NULL; int i, j; @@ -932,7 +929,7 @@ static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter) static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) { - struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; + struct atl1e_hw *hw = &adapter->hw; u32 dev_ctrl_data = 0; u32 max_pay_load = 0; u32 jumbo_thresh = 0; @@ -975,7 +972,7 @@ static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) static inline void atl1e_configure_rx(struct atl1e_adapter *adapter) { - struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; + struct atl1e_hw *hw = &adapter->hw; u32 rxf_len = 0; u32 rxf_low = 0; u32 rxf_high = 0; @@ -1224,8 +1221,7 @@ static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter) static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter) { - struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *) - &adapter->tx_ring; + struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; struct atl1e_tx_buffer *tx_buffer = NULL; u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX); u16 next_to_clean = atomic_read(&tx_ring->next_to_clean); @@ -1384,15 +1380,14 @@ static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter, (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc; u8 rx_using = rx_page_desc[que].rx_using; - return (struct atl1e_rx_page *)&(rx_page_desc[que].rx_page[rx_using]); + return &(rx_page_desc[que].rx_page[rx_using]); } static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, int *work_done, int work_to_do) { struct net_device *netdev = adapter->netdev; - struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *) - &adapter->rx_ring; + struct atl1e_rx_ring *rx_ring = &adapter->rx_ring; struct atl1e_rx_page_desc *rx_page_desc = (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc; struct sk_buff *skb = NULL; @@ -1576,7 +1571,7 @@ static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter) tx_ring->next_to_use = 0; memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc)); - return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use]; + return &tx_ring->desc[next_to_use]; } static struct atl1e_tx_buffer * @@ -2061,8 +2056,8 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) if (wufc) { /* get link status */ - atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); - atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); + atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data); + atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data); mii_advertise_data = ADVERTISE_10HALF; @@ -2086,7 +2081,7 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { msleep(100); atl1e_read_phy_reg(hw, MII_BMSR, - (u16 *)&mii_bmsr_data); + &mii_bmsr_data); if (mii_bmsr_data & BMSR_LSTATUS) break; } diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 5d10884e5080..149a294d54e9 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -1061,7 +1061,7 @@ static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) goto err_nomem; } rfd_ring->buffer_info = - (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count); + (tpd_ring->buffer_info + tpd_ring->count); /* * real ring DMA buffer diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index ac7b74488531..ff5d3c1f1217 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -872,8 +872,7 @@ bnx2_alloc_mem(struct bnx2 *bp) bnapi = &bp->bnx2_napi[i]; - sblk = (void *) (status_blk + - BNX2_SBLK_MSIX_ALIGN_SIZE * i); + sblk = (status_blk + BNX2_SBLK_MSIX_ALIGN_SIZE * i); bnapi->status_blk.msix = sblk; bnapi->hw_tx_cons_ptr = &sblk->status_tx_quick_consumer_index; diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index c95e7b5e2b85..65e66caea50d 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -2585,7 +2585,7 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe) return; } - cqes[0] = (struct kcqe *) &kcqe; + cqes[0] = &kcqe; cnic_reply_bnx2x_kcqes(dev, ulp_type, cqes, 1); } @@ -4665,9 +4665,9 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) cp->kcq1.sw_prod_idx = 0; cp->kcq1.hw_prod_idx_ptr = - (u16 *) &sblk->status_completion_producer_index; + &sblk->status_completion_producer_index; - cp->kcq1.status_idx_ptr = (u16 *) &sblk->status_idx; + cp->kcq1.status_idx_ptr = &sblk->status_idx; /* Initialize the kernel complete queue context. */ val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | @@ -4693,9 +4693,9 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id); cp->kcq1.hw_prod_idx_ptr = - (u16 *) &msblk->status_completion_producer_index; - cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx; - cp->kwq_con_idx_ptr = (u16 *) &msblk->status_cmd_consumer_index; + &msblk->status_completion_producer_index; + cp->kcq1.status_idx_ptr = &msblk->status_idx; + cp->kwq_con_idx_ptr = &msblk->status_cmd_consumer_index; cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT; cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); diff --git a/drivers/net/ethernet/brocade/bna/cna_fwimg.c b/drivers/net/ethernet/brocade/bna/cna_fwimg.c index cfc22a64157e..6a68e8d93309 100644 --- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c +++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c @@ -67,10 +67,10 @@ bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off) { switch (asic_gen) { case BFI_ASIC_GEN_CT: - return (u32 *)(bfi_image_ct_cna + off); + return (bfi_image_ct_cna + off); break; case BFI_ASIC_GEN_CT2: - return (u32 *)(bfi_image_ct2_cna + off); + return (bfi_image_ct2_cna + off); break; default: return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c index 65e4b280619a..55cf72af69ce 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c @@ -575,7 +575,7 @@ static void t3_process_tid_release_list(struct work_struct *work) if (!skb) { spin_lock_bh(&td->tid_release_lock); p->ctx = (void *)td->tid_release_list; - td->tid_release_list = (struct t3c_tid_entry *)p; + td->tid_release_list = p; break; } mk_tid_release(skb, p - td->tid_maps.tid_tab); diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index e111d974afd8..8596acaa402b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -753,7 +753,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, end = (void *)q->desc + part1; } if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ - *(u64 *)end = 0; + *end = 0; } /** diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 25e3308fc9d8..9dad56101e23 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -418,7 +418,7 @@ static int fwevtq_handler(struct sge_rspq *rspq, const __be64 *rsp, * restart a TX Ethernet Queue which was stopped for lack of * free TX Queue Descriptors ... */ - const struct cpl_sge_egr_update *p = (void *)cpl; + const struct cpl_sge_egr_update *p = cpl; unsigned int qid = EGR_QID(be32_to_cpu(p->opcode_qid)); struct sge *s = &adapter->sge; struct sge_txq *tq; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 0bd585bba39d..f2d1ecdcaf98 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -934,7 +934,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *tq, end = (void *)tq->desc + part1; } if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ - *(u64 *)end = 0; + *end = 0; } /** @@ -1323,8 +1323,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) */ if (unlikely((void *)sgl == (void *)tq->stat)) { sgl = (void *)tq->desc; - end = (void *)((void *)tq->desc + - ((void *)end - (void *)tq->stat)); + end = ((void *)tq->desc + ((void *)end - (void *)tq->stat)); } write_sgl(skb, tq, sgl, end, 0, addr); diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c index d3cd489d11a2..f879e9224846 100644 --- a/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/drivers/net/ethernet/dec/tulip/de4x5.c @@ -3973,7 +3973,7 @@ DevicePresent(struct net_device *dev, u_long aprom_addr) tmp = srom_rd(aprom_addr, i); *p++ = cpu_to_le16(tmp); } - de4x5_dbg_srom((struct de4x5_srom *)&lp->srom); + de4x5_dbg_srom(&lp->srom); } } diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 9ac14f804851..21c6574c5f15 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -185,7 +185,7 @@ static void mem_disp(u8 *addr, int size) for (; (u32) i < (u32) addr + size4Aling; i += 4) printk("%08x ", *((u32 *) (i))); for (; (u32) i < (u32) addr + size; i++) - printk("%02x", *((u8 *) (i))); + printk("%02x", *((i))); if (notAlign == 1) printk("\r\n"); } diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index d496673f0908..3f4391bede81 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c @@ -1217,7 +1217,7 @@ static int hp100_init_rxpdl(struct net_device *dev, ringptr->pdl = pdlptr + 1; ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1); - ringptr->skb = (void *) NULL; + ringptr->skb = NULL; /* * Write address and length of first PDL Fragment (which is used for @@ -1243,7 +1243,7 @@ static int hp100_init_txpdl(struct net_device *dev, ringptr->pdl = pdlptr; /* +1; */ ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr); /* +1 */ - ringptr->skb = (void *) NULL; + ringptr->skb = NULL; return roundup(MAX_TX_FRAG * 2 + 2, 4); } @@ -1628,7 +1628,7 @@ static void hp100_clean_txring(struct net_device *dev) /* Conversion to new PCI API : NOP */ pci_unmap_single(lp->pci_dev, (dma_addr_t) lp->txrhead->pdl[1], lp->txrhead->pdl[2], PCI_DMA_TODEVICE); dev_kfree_skb_any(lp->txrhead->skb); - lp->txrhead->skb = (void *) NULL; + lp->txrhead->skb = NULL; lp->txrhead = lp->txrhead->next; lp->txrcommit--; } diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c index 6c2952c8ea15..3735bfa53600 100644 --- a/drivers/net/ethernet/i825xx/lp486e.c +++ b/drivers/net/ethernet/i825xx/lp486e.c @@ -629,10 +629,10 @@ init_i596(struct net_device *dev) { memcpy ((void *)lp->eth_addr, dev->dev_addr, 6); lp->set_add.command = CmdIASetup; - i596_add_cmd(dev, (struct i596_cmd *)&lp->set_add); + i596_add_cmd(dev, &lp->set_add); lp->tdr.command = CmdTDR; - i596_add_cmd(dev, (struct i596_cmd *)&lp->tdr); + i596_add_cmd(dev, &lp->tdr); if (lp->scb.command && i596_timeout(dev, "i82596 init", 200)) return 1; @@ -737,7 +737,7 @@ i596_cleanup_cmd(struct net_device *dev) { lp = netdev_priv(dev); while (lp->cmd_head) { - cmd = (struct i596_cmd *)lp->cmd_head; + cmd = lp->cmd_head; lp->cmd_head = pa_to_va(lp->cmd_head->pa_next); lp->cmd_backlog--; @@ -1281,7 +1281,7 @@ static void set_multicast_list(struct net_device *dev) { lp->i596_config[8] |= 0x01; } - i596_add_cmd(dev, (struct i596_cmd *) &lp->set_conf); + i596_add_cmd(dev, &lp->set_conf); } } diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c index cae17f4bc93e..353f57f675d0 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.c +++ b/drivers/net/ethernet/i825xx/sun3_82586.c @@ -571,7 +571,7 @@ static int init586(struct net_device *dev) } #endif - ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ + ptr = alloc_rfa(dev,ptr); /* init receive-frame-area */ /* * alloc xmit-buffs / init xmit_cmds @@ -584,7 +584,7 @@ static int init586(struct net_device *dev) ptr = (char *) ptr + XMIT_BUFF_SIZE; p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */ ptr = (char *) ptr + sizeof(struct tbd_struct); - if((void *)ptr > (void *)dev->mem_end) + if(ptr > (void *)dev->mem_end) { printk("%s: not enough shared-mem for your configuration!\n",dev->name); return 1; diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 04d901d0ff63..ec85bf1bffd1 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -1894,7 +1894,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) goto out_free; } - rx_desc = (struct rx_desc *)rxq->rx_desc_area; + rx_desc = rxq->rx_desc_area; for (i = 0; i < rxq->rx_ring_size; i++) { int nexti; @@ -1999,7 +1999,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) txq->tx_desc_area_size = size; - tx_desc = (struct tx_desc *)txq->tx_desc_area; + tx_desc = txq->tx_desc_area; for (i = 0; i < txq->tx_ring_size; i++) { struct tx_desc *txd = tx_desc + i; int nexti; diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 1db023b075a1..59489722e898 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1032,7 +1032,7 @@ static int rxq_init(struct net_device *dev) } memset((void *)pep->p_rx_desc_area, 0, size); /* initialize the next_desc_ptr links in the Rx descriptors ring */ - p_rx_desc = (struct rx_desc *)pep->p_rx_desc_area; + p_rx_desc = pep->p_rx_desc_area; for (i = 0; i < rx_desc_num; i++) { p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma + ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); @@ -1095,7 +1095,7 @@ static int txq_init(struct net_device *dev) } memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); /* Initialize the next_desc_ptr links in the Tx descriptors ring */ - p_tx_desc = (struct tx_desc *)pep->p_tx_desc_area; + p_tx_desc = pep->p_tx_desc_area; for (i = 0; i < tx_desc_num; i++) { p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma + ((i + 1) % tx_desc_num) * sizeof(struct tx_desc); diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b45d0e7f6ab0..766b8c5a235e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -779,7 +779,7 @@ static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn, r->com.to_state = state; r->com.state = RES_QP_BUSY; if (qp) - *qp = (struct res_qp *)r; + *qp = r; } } @@ -832,7 +832,7 @@ static int mr_res_start_move_to(struct mlx4_dev *dev, int slave, int index, r->com.to_state = state; r->com.state = RES_MPT_BUSY; if (mpt) - *mpt = (struct res_mpt *)r; + *mpt = r; } } diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index bb367582c1e8..e7cd587d8ae7 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -6946,9 +6946,9 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) if (sp->rxd_mode == RXD_MODE_3B) ba = &ring->ba[j][k]; if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb, - (u64 *)&temp0_64, - (u64 *)&temp1_64, - (u64 *)&temp2_64, + &temp0_64, + &temp1_64, + &temp2_64, size) == -ENOMEM) { return 0; } @@ -7149,7 +7149,7 @@ static int s2io_card_up(struct s2io_nic *sp) int i, ret = 0; struct config_param *config; struct mac_info *mac_control; - struct net_device *dev = (struct net_device *)sp->dev; + struct net_device *dev = sp->dev; u16 interruptible; /* Initialize the H/W I/O registers */ @@ -7325,7 +7325,7 @@ static void s2io_tx_watchdog(struct net_device *dev) static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) { struct s2io_nic *sp = ring_data->nic; - struct net_device *dev = (struct net_device *)ring_data->dev; + struct net_device *dev = ring_data->dev; struct sk_buff *skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); int ring_no = ring_data->ring_no; @@ -7508,7 +7508,7 @@ aggregate: static void s2io_link(struct s2io_nic *sp, int link) { - struct net_device *dev = (struct net_device *)sp->dev; + struct net_device *dev = sp->dev; struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; if (link != sp->last_link_state) { @@ -8280,7 +8280,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, return -1; } - *ip = (struct iphdr *)((u8 *)buffer + ip_off); + *ip = (struct iphdr *)(buffer + ip_off); ip_len = (u8)((*ip)->ihl); ip_len <<= 2; *tcp = (struct tcphdr *)((unsigned long)*ip + ip_len); diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c index 98e2c10ae08b..32d06824fe3e 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-config.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c @@ -2346,7 +2346,7 @@ void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool) for (i = 0; i < nreq; i++) vxge_os_dma_malloc_async( - ((struct __vxge_hw_device *)blockpool->hldev)->pdev, + (blockpool->hldev)->pdev, blockpool->hldev, VXGE_HW_BLOCK_SIZE); } @@ -2428,13 +2428,13 @@ __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool) break; pci_unmap_single( - ((struct __vxge_hw_device *)blockpool->hldev)->pdev, + (blockpool->hldev)->pdev, ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, ((struct __vxge_hw_blockpool_entry *)p)->length, PCI_DMA_BIDIRECTIONAL); vxge_os_dma_free( - ((struct __vxge_hw_device *)blockpool->hldev)->pdev, + (blockpool->hldev)->pdev, ((struct __vxge_hw_blockpool_entry *)p)->memblock, &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); @@ -4059,7 +4059,7 @@ __vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id) enum vxge_hw_status status = VXGE_HW_OK; struct __vxge_hw_virtualpath *vpath; - vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id]; + vpath = &hldev->virtual_paths[vp_id]; if (vpath->ringh) { status = __vxge_hw_ring_reset(vpath->ringh); diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.h b/drivers/net/ethernet/neterion/vxge/vxge-config.h index 5046a64f0fe8..9e0c1eed5dc5 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-config.h +++ b/drivers/net/ethernet/neterion/vxge/vxge-config.h @@ -1922,7 +1922,7 @@ realloc: /* misaligned, free current one and try allocating * size + VXGE_CACHE_LINE_SIZE memory */ - kfree((void *) vaddr); + kfree(vaddr); size += VXGE_CACHE_LINE_SIZE; realloc_flag = 1; goto realloc; diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 51387c31914b..2578eb1f025d 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -1134,7 +1134,7 @@ static void vxge_set_multicast(struct net_device *dev) "%s:%d", __func__, __LINE__); vdev = netdev_priv(dev); - hldev = (struct __vxge_hw_device *)vdev->devh; + hldev = vdev->devh; if (unlikely(!is_vxge_card_up(vdev))) return; @@ -3989,16 +3989,16 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask) continue; vxge_debug_ll_config(VXGE_TRACE, "%s: MTU size - %d", vdev->ndev->name, - ((struct __vxge_hw_device *)(vdev->devh))-> + ((vdev->devh))-> config.vp_config[i].mtu); vxge_debug_init(VXGE_TRACE, "%s: VLAN tag stripping %s", vdev->ndev->name, - ((struct __vxge_hw_device *)(vdev->devh))-> + ((vdev->devh))-> config.vp_config[i].rpa_strip_vlan_tag ? "Enabled" : "Disabled"); vxge_debug_ll_config(VXGE_TRACE, "%s: Max frags : %d", vdev->ndev->name, - ((struct __vxge_hw_device *)(vdev->devh))-> + ((vdev->devh))-> config.vp_config[i].fifo.max_frags); break; } diff --git a/drivers/net/ethernet/neterion/vxge/vxge-traffic.c b/drivers/net/ethernet/neterion/vxge/vxge-traffic.c index 5954fa264da1..99749bd07d72 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-traffic.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-traffic.c @@ -533,8 +533,7 @@ __vxge_hw_device_handle_error(struct __vxge_hw_device *hldev, u32 vp_id, /* notify driver */ if (hldev->uld_callbacks->crit_err) - hldev->uld_callbacks->crit_err( - (struct __vxge_hw_device *)hldev, + hldev->uld_callbacks->crit_err(hldev, type, vp_id); out: @@ -1322,7 +1321,7 @@ enum vxge_hw_status vxge_hw_ring_rxd_next_completed( /* check whether it is not the end */ if (!own || *t_code == VXGE_HW_RING_T_CODE_FRM_DROP) { - vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control != + vxge_assert((rxdp)->host_control != 0); ++ring->cmpl_cnt; diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index ac149d99f78f..b5ba3084c7fc 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c @@ -583,7 +583,7 @@ static inline void ioc3_rx(struct net_device *dev) unsigned long *rxr; u32 w0, err; - rxr = (unsigned long *) ip->rxr; /* Ring base */ + rxr = ip->rxr; /* Ring base */ rx_entry = ip->rx_ci; /* RX consume index */ n_entry = ip->rx_pi; @@ -903,7 +903,7 @@ static void ioc3_alloc_rings(struct net_device *dev) if (ip->rxr == NULL) { /* Allocate and initialize rx ring. 4kb = 512 entries */ ip->rxr = (unsigned long *) get_zeroed_page(GFP_ATOMIC); - rxr = (unsigned long *) ip->rxr; + rxr = ip->rxr; if (!rxr) printk("ioc3_alloc_rings(): get_zeroed_page() failed!\n"); diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index fd33b21f6c96..1fcd914ec39b 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -1640,8 +1640,7 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_free_io_4; /* descriptors are aligned due to the nature of pci_alloc_consistent */ - pd->tx_ring = (struct smsc9420_dma_desc *) - (pd->rx_ring + RX_RING_SIZE); + pd->tx_ring = (pd->rx_ring + RX_RING_SIZE); pd->tx_dma_addr = pd->rx_dma_addr + sizeof(struct smsc9420_dma_desc) * RX_RING_SIZE; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 3dd8f0803808..df4774d5f6a7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -190,7 +190,7 @@ static int stmmac_pltfr_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - iounmap((void *)priv->ioaddr); + iounmap((void __force __iomem *)priv->ioaddr); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index 7d4a040d84a2..aeded7ff1c8f 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -441,7 +441,7 @@ static void qe_rx(struct sunqe *qep) } else { skb_reserve(skb, 2); skb_put(skb, len); - skb_copy_to_linear_data(skb, (unsigned char *) this_qbuf, + skb_copy_to_linear_data(skb, this_qbuf, len); skb->protocol = eth_type_trans(skb, qep->dev); netif_rx(skb); diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index ea3e0a21ba74..a46c19859683 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -486,7 +486,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname); velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname); velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname); - velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname); + velocity_set_int_opt(&opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname); opts->numrx = (opts->numrx & ~3); } -- GitLab From 2c208890c6d4e16076c6664137703ec813e8fa6c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 4 Jun 2012 12:44:17 +0000 Subject: [PATCH 0785/6849] wireless: Remove casts to same type Adding casts of objects to the same type is unnecessary and confusing for a human reader. For example, this cast: int y; int *p = (int *)&y; I used the coccinelle script below to find and remove these unnecessary casts. I manually removed the conversions this script produces of casts with __force, __iomem and __user. @@ type T; T *p; @@ - (T *)p + p Neatened the mwifiex_deauthenticate_infra function which was doing odd things with array pointers and not using is_zero_ether_addr. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wireless/adm8211.c | 3 +- drivers/net/wireless/airo.c | 4 +- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 4 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 3 +- drivers/net/wireless/ath/ath9k/eeprom_def.c | 3 +- drivers/net/wireless/ath/carl9170/cmd.c | 2 +- drivers/net/wireless/ath/carl9170/rx.c | 4 +- drivers/net/wireless/atmel.c | 4 +- drivers/net/wireless/b43legacy/dma.c | 2 +- drivers/net/wireless/b43legacy/xmit.c | 6 +-- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 4 +- drivers/net/wireless/brcm80211/brcmsmac/dma.c | 2 +- .../net/wireless/brcm80211/brcmsmac/main.c | 2 +- drivers/net/wireless/hostap/hostap_proc.c | 3 +- drivers/net/wireless/ipw2x00/ipw2200.c | 4 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 +- drivers/net/wireless/libertas/debugfs.c | 4 +- drivers/net/wireless/libertas/if_usb.c | 2 +- drivers/net/wireless/libertas_tf/if_usb.c | 2 +- drivers/net/wireless/mwifiex/11n.c | 14 ++---- drivers/net/wireless/mwifiex/11n.h | 3 +- drivers/net/wireless/mwifiex/11n_rxreorder.c | 18 ++------ drivers/net/wireless/mwifiex/cfg80211.c | 2 +- drivers/net/wireless/mwifiex/join.c | 20 +++----- drivers/net/wireless/mwifiex/scan.c | 24 ++++------ drivers/net/wireless/mwifiex/sta_cmd.c | 16 ++----- drivers/net/wireless/mwifiex/sta_cmdresp.c | 24 ++++------ drivers/net/wireless/mwifiex/sta_event.c | 2 +- drivers/net/wireless/p54/eeprom.c | 2 +- drivers/net/wireless/p54/fwio.c | 2 +- drivers/net/wireless/prism54/islpci_eth.c | 2 +- drivers/net/wireless/ray_cs.c | 2 +- drivers/net/wireless/rtlwifi/base.c | 2 +- drivers/net/wireless/rtlwifi/cam.c | 2 +- drivers/net/wireless/rtlwifi/core.c | 14 +++--- drivers/net/wireless/rtlwifi/efuse.c | 4 +- drivers/net/wireless/rtlwifi/pci.c | 14 +++--- drivers/net/wireless/rtlwifi/ps.c | 10 ++-- .../net/wireless/rtlwifi/rtl8192c/dm_common.c | 5 +- .../net/wireless/rtlwifi/rtl8192c/fw_common.c | 4 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 43 +++++++++-------- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 4 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 43 +++++++++-------- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 6 +-- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 34 +++++++------- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 6 +-- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 46 +++++++++---------- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +- drivers/net/wireless/ti/wlcore/tx.c | 3 +- drivers/net/wireless/zd1211rw/zd_chip.h | 2 +- drivers/net/wireless/zd1211rw/zd_usb.h | 2 +- 55 files changed, 198 insertions(+), 247 deletions(-) diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 0ac09a2bd144..97afcec24759 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -1738,8 +1738,7 @@ static int adm8211_alloc_rings(struct ieee80211_hw *dev) return -ENOMEM; } - priv->tx_ring = (struct adm8211_desc *)(priv->rx_ring + - priv->rx_ring_size); + priv->tx_ring = priv->rx_ring + priv->rx_ring_size; priv->tx_ring_dma = priv->rx_ring_dma + sizeof(struct adm8211_desc) * priv->rx_ring_size; diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 520a4b2eb9cc..252c2c2d76c1 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -1997,7 +1997,7 @@ static int mpi_send_packet (struct net_device *dev) * ------------------------------------------------ */ - memcpy((char *)ai->txfids[0].virtual_host_addr, + memcpy(ai->txfids[0].virtual_host_addr, (char *)&wifictlhdr8023, sizeof(wifictlhdr8023)); payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr + @@ -4212,7 +4212,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid, airo_print_err(ai->dev->name, "%s: len=%d", __func__, len); rc = -1; } else { - memcpy((char *)ai->config_desc.virtual_host_addr, + memcpy(ai->config_desc.virtual_host_addr, pBuf, len); rc = issuecommand(ai, &cmd, &rsp); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index dfb0441f406c..ca881558da78 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3178,7 +3178,7 @@ static int ar9300_compress_decision(struct ath_hw *ah, mdata_size, length); return -1; } - memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); + memcpy(mptr, word + COMP_HDR_LEN, length); ath_dbg(common, EEPROM, "restored eeprom %d: uncompressed, length %d\n", it, length); @@ -3199,7 +3199,7 @@ static int ar9300_compress_decision(struct ath_hw *ah, "restore eeprom %d: block, reference %d, length %d\n", it, reference, length); ar9300_uncompress_block(ah, mptr, mdata_size, - (u8 *) (word + COMP_HDR_LEN), length); + (word + COMP_HDR_LEN), length); break; default: ath_dbg(common, EEPROM, "unknown compression code %d\n", code); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 4322ac80c203..92543d166fe9 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -188,8 +188,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) { #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) struct ath_common *common = ath9k_hw_common(ah); - struct ar5416_eeprom_4k *eep = - (struct ar5416_eeprom_4k *) &ah->eeprom.map4k; + struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; u16 *eepdata, temp, magic, magic2; u32 sum = 0, el; bool need_swap = false; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index b5fba8b18b8b..a9f071bc643a 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -264,8 +264,7 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) { - struct ar5416_eeprom_def *eep = - (struct ar5416_eeprom_def *) &ah->eeprom.def; + struct ar5416_eeprom_def *eep = &ah->eeprom.def; struct ath_common *common = ath9k_hw_common(ah); u16 *eepdata, temp, magic, magic2; u32 sum = 0, el; diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c index 195dc6538110..39a63874b275 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.c +++ b/drivers/net/wireless/ath/carl9170/cmd.c @@ -138,7 +138,7 @@ int carl9170_reboot(struct ar9170 *ar) if (!cmd) return -ENOMEM; - err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true); + err = __carl9170_exec_cmd(ar, cmd, true); return err; } diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 84b22eec7abd..7a8e90eaad83 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -161,7 +161,7 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer) void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) { - struct carl9170_rsp *cmd = (void *) buf; + struct carl9170_rsp *cmd = buf; struct ieee80211_vif *vif; if (carl9170_check_sequence(ar, cmd->hdr.seq)) @@ -520,7 +520,7 @@ static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie) */ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) { - struct ieee80211_hdr *hdr = (void *) data; + struct ieee80211_hdr *hdr = data; struct ieee80211_tim_ie *tim_ie; u8 *tim; u8 tim_len; diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index d07c0301da6a..4a4e98f71807 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -2952,10 +2952,10 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) /* current AP address - only in reassoc frame */ if (is_reassoc) { memcpy(body.ap, priv->CurrentBSSID, 6); - ssid_el_p = (u8 *)&body.ssid_el_id; + ssid_el_p = &body.ssid_el_id; bodysize = 18 + priv->SSID_size; } else { - ssid_el_p = (u8 *)&body.ap[0]; + ssid_el_p = &body.ap[0]; bodysize = 12 + priv->SSID_size; } diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index f1f8bd09bd87..ff50cb4290e4 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -52,7 +52,7 @@ struct b43legacy_dmadesc32 *op32_idx2desc(struct b43legacy_dmaring *ring, desc = ring->descbase; desc = &(desc[slot]); - return (struct b43legacy_dmadesc32 *)desc; + return desc; } static void op32_fill_descriptor(struct b43legacy_dmaring *ring, diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index a8012f2749ee..b8ffea6f5c64 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -269,8 +269,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) (&txhdr->plcp), plcp_fragment_len, rate); - b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) - (&txhdr->plcp_fb), plcp_fragment_len, + b43legacy_generate_plcp_hdr(&txhdr->plcp_fb, plcp_fragment_len, rate_fb->hw_value); /* PHY TX Control word */ @@ -340,8 +339,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) (&txhdr->rts_plcp), len, rts_rate); - b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) - (&txhdr->rts_plcp_fb), + b43legacy_generate_plcp_hdr(&txhdr->rts_plcp_fb, len, rts_rate_fb); hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame); txhdr->rts_dur_fb = hdr->duration_id; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 1dbf2be478c8..4deae28fc211 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2502,7 +2502,7 @@ clkwait: int ret, i; ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf, + SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, (u32) bus->ctrl_frame_len); if (ret < 0) { @@ -3327,7 +3327,7 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus); if (len > 0 && len < MEMBLOCK) { - bufp = (char *)memblock; + bufp = memblock; bufp[len] = 0; len = brcmf_process_nvram_vars(bufp, len); bufp += len; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 11054ae9d4f6..7516639412ec 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -1433,7 +1433,7 @@ void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) struct ieee80211_tx_info *tx_info; while (i != end) { - skb = (struct sk_buff *)di->txp[i]; + skb = di->txp[i]; if (skb != NULL) { tx_info = (struct ieee80211_tx_info *)skb->cb; (callback_fnc)(tx_info, arg_a); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 19db4052c44c..e67556780a31 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -8318,7 +8318,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, struct brcms_pub *pub; /* allocate struct brcms_c_info state and its substructures */ - wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, 0); + wlc = brcms_c_attach_malloc(unit, &err, 0); if (wlc == NULL) goto fail; wlc->wiphy = wl->wiphy; diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index 75ef8f04aabe..dc447c1b5abe 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c @@ -58,8 +58,7 @@ static int prism2_stats_proc_read(char *page, char **start, off_t off, { char *p = page; local_info_t *local = (local_info_t *) data; - struct comm_tallies_sums *sums = (struct comm_tallies_sums *) - &local->comm_tallies; + struct comm_tallies_sums *sums = &local->comm_tallies; if (off != 0) { *eof = 1; diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 0036737fe8e3..afdec4a0d9a0 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -7069,9 +7069,7 @@ static int ipw_qos_activate(struct ipw_priv *priv, } IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); - err = ipw_send_qos_params_command(priv, - (struct libipw_qos_parameters *) - &(qos_parameters[0])); + err = ipw_send_qos_params_command(priv, &qos_parameters[0]); if (err) IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 060aac3e22f1..492e64fb9f3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -170,7 +170,7 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, void *data; int length; - data = (void *)rxb_addr(rxb); + data = rxb_addr(rxb); length = get_event_length(rxb); if (!data || length == 0) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec6fb395b84d..b849528d48dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1354,7 +1354,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(trans->dev, - &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], + &txq->tfds[txq->q.write_ptr], sizeof(struct iwl_tfd), &dev_cmd->hdr, firstlen, skb->data + hdr_len, secondlen); diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index a06cc283e23d..668dd27616a0 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -483,7 +483,7 @@ static ssize_t lbs_rdmac_write(struct file *file, res = -EFAULT; goto out_unlock; } - priv->mac_offset = simple_strtoul((char *)buf, NULL, 16); + priv->mac_offset = simple_strtoul(buf, NULL, 16); res = count; out_unlock: free_page(addr); @@ -565,7 +565,7 @@ static ssize_t lbs_rdbbp_write(struct file *file, res = -EFAULT; goto out_unlock; } - priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16); + priv->bbp_offset = simple_strtoul(buf, NULL, 16); res = count; out_unlock: free_page(addr); diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index cd3b0d400618..64b7dc5de126 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -302,7 +302,7 @@ error: static void if_usb_disconnect(struct usb_interface *intf) { struct if_usb_card *cardp = usb_get_intfdata(intf); - struct lbs_private *priv = (struct lbs_private *) cardp->priv; + struct lbs_private *priv = cardp->priv; lbs_deb_enter(LBS_DEB_MAIN); diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 19a5a92dd779..d576dd6665d3 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -253,7 +253,7 @@ lbtf_deb_leave(LBTF_DEB_MAIN); static void if_usb_disconnect(struct usb_interface *intf) { struct if_usb_card *cardp = usb_get_intfdata(intf); - struct lbtf_private *priv = (struct lbtf_private *) cardp->priv; + struct lbtf_private *priv = cardp->priv; lbtf_deb_enter(LBTF_DEB_MAIN); diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index fe8ebfebcc0e..e535c937628b 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -101,8 +101,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, { int tid; struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; - struct host_cmd_ds_11n_delba *del_ba = - (struct host_cmd_ds_11n_delba *) &resp->params.del_ba; + struct host_cmd_ds_11n_delba *del_ba = &resp->params.del_ba; uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set); tid = del_ba_param_set >> DELBA_TID_POS; @@ -147,8 +146,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { int tid; - struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = - (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp; + struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) @@ -412,7 +410,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, memcpy((u8 *) bss_co_2040 + sizeof(struct mwifiex_ie_types_header), - (u8 *) bss_desc->bcn_bss_co_2040 + + bss_desc->bcn_bss_co_2040 + sizeof(struct ieee_types_header), le16_to_cpu(bss_co_2040->header.len)); @@ -426,10 +424,8 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY); ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap)); - memcpy((u8 *) ext_cap + - sizeof(struct mwifiex_ie_types_header), - (u8 *) bss_desc->bcn_ext_cap + - sizeof(struct ieee_types_header), + memcpy((u8 *)ext_cap + sizeof(struct mwifiex_ie_types_header), + bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header), le16_to_cpu(ext_cap->header.len)); *buffer += sizeof(struct mwifiex_ie_types_extcap); diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 77646d777dce..28366e9211fb 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -105,8 +105,7 @@ static inline u8 mwifiex_space_avail_for_new_ba_stream( priv = adapter->priv[i]; if (priv) ba_stream_num += mwifiex_wmm_list_len( - (struct list_head *) - &priv->tx_ba_stream_tbl_ptr); + &priv->tx_ba_stream_tbl_ptr); } return ((ba_stream_num < diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 9c44088054dd..89f7c570cd2e 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -296,9 +296,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, */ int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) { - struct host_cmd_ds_11n_addba_req *add_ba_req = - (struct host_cmd_ds_11n_addba_req *) - &cmd->params.add_ba_req; + struct host_cmd_ds_11n_addba_req *add_ba_req = &cmd->params.add_ba_req; cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ); cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN); @@ -320,9 +318,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, struct host_cmd_ds_11n_addba_req *cmd_addba_req) { - struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = - (struct host_cmd_ds_11n_addba_rsp *) - &cmd->params.add_ba_rsp; + struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &cmd->params.add_ba_rsp; u8 tid; int win_size; uint16_t block_ack_param_set; @@ -367,8 +363,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, */ int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) { - struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) - &cmd->params.del_ba; + struct host_cmd_ds_11n_delba *del_ba = &cmd->params.del_ba; cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA); cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN); @@ -398,8 +393,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, int start_win, end_win, win_size; u16 pkt_index; - tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, - tid, ta); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); if (!tbl) { if (pkt_type != PKT_TYPE_BAR) mwifiex_process_rx_packet(priv->adapter, payload); @@ -520,9 +514,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = - (struct host_cmd_ds_11n_addba_rsp *) - &resp->params.add_ba_rsp; + struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; int tid, win_size; struct mwifiex_rx_reorder_tbl *tbl; uint16_t block_ack_param_set; diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 87671446e24b..42c1af943111 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1703,7 +1703,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wdev_priv = wiphy_priv(wiphy); *(unsigned long *)wdev_priv = (unsigned long)adapter; - set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev); + set_wiphy_dev(wiphy, priv->adapter->dev); ret = wiphy_register(wiphy); if (ret < 0) { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index d6b4fb04011f..82e63cee1e97 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -1349,22 +1349,16 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) { u8 mac_address[ETH_ALEN]; int ret; - u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - if (mac) { - if (!memcmp(mac, zero_mac, sizeof(zero_mac))) - memcpy((u8 *) &mac_address, - (u8 *) &priv->curr_bss_params.bss_descriptor. - mac_address, ETH_ALEN); - else - memcpy((u8 *) &mac_address, (u8 *) mac, ETH_ALEN); - } else { - memcpy((u8 *) &mac_address, (u8 *) &priv->curr_bss_params. - bss_descriptor.mac_address, ETH_ALEN); - } + if (!mac || is_zero_ether_addr(mac)) + memcpy(mac_address, + priv->curr_bss_params.bss_descriptor.mac_address, + ETH_ALEN); + else + memcpy(mac_address, mac, ETH_ALEN); ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, - HostCmd_ACT_GEN_SET, 0, &mac_address); + HostCmd_ACT_GEN_SET, 0, mac_address); return ret; } diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 74f045715723..8fa763fa629a 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1014,14 +1014,12 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, case TLV_TYPE_TSFTIMESTAMP: dev_dbg(adapter->dev, "info: SCAN_RESP: TSF " "timestamp TLV, len = %d\n", tlv_len); - *tlv_data = (struct mwifiex_ie_types_data *) - current_tlv; + *tlv_data = current_tlv; break; case TLV_TYPE_CHANNELBANDLIST: dev_dbg(adapter->dev, "info: SCAN_RESP: channel" " band list TLV, len = %d\n", tlv_len); - *tlv_data = (struct mwifiex_ie_types_data *) - current_tlv; + *tlv_data = current_tlv; break; default: dev_err(adapter->dev, @@ -1226,15 +1224,15 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->beacon_buf); break; case WLAN_EID_BSS_COEX_2040: - bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr + - sizeof(struct ieee_types_header)); + bss_entry->bcn_bss_co_2040 = current_ptr + + sizeof(struct ieee_types_header); bss_entry->bss_co_2040_offset = (u16) (current_ptr + sizeof(struct ieee_types_header) - bss_entry->beacon_buf); break; case WLAN_EID_EXT_CAPABILITY: - bss_entry->bcn_ext_cap = (u8 *) (current_ptr + - sizeof(struct ieee_types_header)); + bss_entry->bcn_ext_cap = current_ptr + + sizeof(struct ieee_types_header); bss_entry->ext_cap_offset = (u16) (current_ptr + sizeof(struct ieee_types_header) - bss_entry->beacon_buf); @@ -1683,8 +1681,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, goto done; } if (element_id == WLAN_EID_DS_PARAMS) { - channel = *(u8 *) (current_ptr + - sizeof(struct ieee_types_header)); + channel = *(current_ptr + sizeof(struct ieee_types_header)); break; } @@ -2010,12 +2007,11 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) if (curr_bss->bcn_bss_co_2040) curr_bss->bcn_bss_co_2040 = - (u8 *) (curr_bss->beacon_buf + - curr_bss->bss_co_2040_offset); + (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset); if (curr_bss->bcn_ext_cap) - curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf + - curr_bss->ext_cap_offset); + curr_bss->bcn_ext_cap = curr_bss->beacon_buf + + curr_bss->ext_cap_offset; } /* diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 40e025da6bc2..1ff1362d8cdf 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -793,8 +793,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_mac_reg_access *mac_reg; cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); - mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> - params.mac_reg; + mac_reg = &cmd->params.mac_reg; mac_reg->action = cpu_to_le16(cmd_action); mac_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -806,8 +805,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_bbp_reg_access *bbp_reg; cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); - bbp_reg = (struct host_cmd_ds_bbp_reg_access *) - &cmd->params.bbp_reg; + bbp_reg = &cmd->params.bbp_reg; bbp_reg->action = cpu_to_le16(cmd_action); bbp_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -819,8 +817,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *rf_reg; cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); - rf_reg = (struct host_cmd_ds_rf_reg_access *) - &cmd->params.rf_reg; + rf_reg = &cmd->params.rf_reg; rf_reg->action = cpu_to_le16(cmd_action); rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); rf_reg->value = (u8) le32_to_cpu(reg_rw->value); @@ -831,8 +828,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_pmic_reg_access *pmic_reg; cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); - pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd-> - params.pmic_reg; + pmic_reg = &cmd->params.pmic_reg; pmic_reg->action = cpu_to_le16(cmd_action); pmic_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -844,8 +840,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *cau_reg; cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); - cau_reg = (struct host_cmd_ds_rf_reg_access *) - &cmd->params.rf_reg; + cau_reg = &cmd->params.rf_reg; cau_reg->action = cpu_to_le16(cmd_action); cau_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -856,7 +851,6 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, { struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf; struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = - (struct host_cmd_ds_802_11_eeprom_access *) &cmd->params.eeprom; cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index a79ed9bd9695..bd40541ebd5a 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -227,7 +227,7 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *stats) { struct host_cmd_ds_802_11_get_log *get_log = - (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; + &resp->params.get_log; if (stats) { stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); @@ -282,7 +282,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, u32 i; int ret = 0; - tlv_buf = (u8 *) ((u8 *) rate_cfg) + + tlv_buf = ((u8 *)rate_cfg) + sizeof(struct host_cmd_ds_tx_rate_cfg); tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16)); @@ -679,39 +679,33 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, eeprom = data_buf; switch (type) { case HostCmd_CMD_MAC_REG_ACCESS: - r.mac = (struct host_cmd_ds_mac_reg_access *) - &resp->params.mac_reg; + r.mac = &resp->params.mac_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); reg_rw->value = r.mac->value; break; case HostCmd_CMD_BBP_REG_ACCESS: - r.bbp = (struct host_cmd_ds_bbp_reg_access *) - &resp->params.bbp_reg; + r.bbp = &resp->params.bbp_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); reg_rw->value = cpu_to_le32((u32) r.bbp->value); break; case HostCmd_CMD_RF_REG_ACCESS: - r.rf = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; + r.rf = &resp->params.rf_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); reg_rw->value = cpu_to_le32((u32) r.bbp->value); break; case HostCmd_CMD_PMIC_REG_ACCESS: - r.pmic = (struct host_cmd_ds_pmic_reg_access *) - &resp->params.pmic_reg; + r.pmic = &resp->params.pmic_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); reg_rw->value = cpu_to_le32((u32) r.pmic->value); break; case HostCmd_CMD_CAU_REG_ACCESS: - r.rf = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; + r.rf = &resp->params.rf_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); reg_rw->value = cpu_to_le32((u32) r.rf->value); break; case HostCmd_CMD_802_11_EEPROM_ACCESS: - r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) - &resp->params.eeprom; + r.eeprom = &resp->params.eeprom; pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); if (le16_to_cpu(eeprom->byte_count) < le16_to_cpu(r.eeprom->byte_count)) { @@ -787,7 +781,7 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv, struct mwifiex_ds_misc_subsc_evt *sub_event) { struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event = - (struct host_cmd_ds_802_11_subsc_evt *)&resp->params.subsc_evt; + &resp->params.subsc_evt; /* For every subscribe event command (Get/Set/Clear), FW reports the * current set of subscribed events*/ diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 4ace5a3dcd23..e8b27c305367 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -422,7 +422,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) if (len != -1) { sinfo.filled = STATION_INFO_ASSOC_REQ_IES; - sinfo.assoc_req_ies = (u8 *)&event->data[len]; + sinfo.assoc_req_ies = &event->data[len]; len = (u8 *)sinfo.assoc_req_ies - (u8 *)&event->frame_control; sinfo.assoc_req_ies_len = diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index fa8ce5104781..636daf2860cc 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -905,7 +905,7 @@ int p54_read_eeprom(struct ieee80211_hw *dev) while (eeprom_size) { blocksize = min(eeprom_size, maxblocksize); - ret = p54_download_eeprom(priv, (void *) (eeprom + offset), + ret = p54_download_eeprom(priv, eeprom + offset, offset, blocksize); if (unlikely(ret)) goto free; diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 18e82b31afa6..9ba85106eec0 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -478,7 +478,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { memcpy(&body->longbow.curve_data, - (void *) entry + sizeof(__le16), + entry + sizeof(__le16), priv->curve_data->entry_size); } else { struct p54_scan_body *chan = &body->normal; diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 266d45bf86f5..799e148d0370 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -455,7 +455,7 @@ islpci_eth_receive(islpci_private *priv) "Error mapping DMA address\n"); /* free the skbuf structure before aborting */ - dev_kfree_skb_irq((struct sk_buff *) skb); + dev_kfree_skb_irq(skb); skb = NULL; break; } diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 86a738bf591c..598ca1cafb95 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -1849,7 +1849,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) pr_debug("ray_cs: interrupt for *dev=%p\n", dev); local = netdev_priv(dev); - link = (struct pcmcia_device *)local->finder; + link = local->finder; if (!pcmcia_dev_present(link)) { pr_debug( "ray_cs interrupt from device not present or suspended.\n"); diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index f4c852c6749b..58e1f7bb4df1 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -907,7 +907,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) struct ieee80211_hdr *hdr = rtl_get_hdr(skb); struct rtl_priv *rtlpriv = rtl_priv(hw); __le16 fc = hdr->frame_control; - u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); + u8 *act = (u8 *)skb->data + MAC80211_3ADDR_LEN; u8 category; if (!ieee80211_is_action(fc)) diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 3d8cc4a0c86d..2d1a8220d5c0 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -146,7 +146,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, } rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, - (u8 *) key_content, us_config); + key_content, us_config); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n"); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 278e9f957e0d..a18ad2a98938 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -680,7 +680,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->short_preamble = bss_conf->use_short_preamble; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, - (u8 *) (&mac->short_preamble)); + &mac->short_preamble); } if (changed & BSS_CHANGED_ERP_SLOT) { @@ -693,7 +693,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->slot_time = RTL_SLOT_TIME_20; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *) (&mac->slot_time)); + &mac->slot_time); } if (changed & BSS_CHANGED_HT) { @@ -713,7 +713,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rcu_read_unlock(); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, - (u8 *) (&mac->max_mss_density)); + &mac->max_mss_density); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR, &mac->current_ampdu_factor); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE, @@ -801,7 +801,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, u8 mstatus = RT_MEDIA_CONNECT; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_JOINBSSRPT, - (u8 *) (&mstatus)); + &mstatus); ppsc->report_linked = true; } } else { @@ -809,7 +809,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, u8 mstatus = RT_MEDIA_DISCONNECT; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_JOINBSSRPT, - (u8 *)(&mstatus)); + &mstatus); ppsc->report_linked = false; } } @@ -836,7 +836,7 @@ static void rtl_op_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; mac->tsf = tsf; - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, &bibss); } static void rtl_op_reset_tsf(struct ieee80211_hw *hw, @@ -845,7 +845,7 @@ static void rtl_op_reset_tsf(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmp = 0; - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, &tmp); } static void rtl_op_sta_notify(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 1f143800a8d7..8e2f9afb125a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -352,7 +352,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_utilized); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, - (u8 *)&efuse_usage); + &efuse_usage); done: for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) kfree(efuse_word[i]); @@ -409,7 +409,7 @@ void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, else if (type == 2) efuse_shadow_read_2byte(hw, offset, (u16 *) value); else if (type == 4) - efuse_shadow_read_4byte(hw, offset, (u32 *) value); + efuse_shadow_read_4byte(hw, offset, value); } diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 2062ea1d7c80..82d3afcfecd1 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -756,10 +756,10 @@ done: if (index == rtlpci->rxringcount - 1) rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXERO, - (u8 *)&tmp_one); + &tmp_one); rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, - (u8 *)&tmp_one); + &tmp_one); index = (index + 1) % rtlpci->rxringcount; } @@ -934,7 +934,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) __skb_queue_tail(&ring->queue, pskb); rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, - (u8 *)&temp_one); + &temp_one); return; } @@ -1126,11 +1126,11 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) rxbuffersize); rtlpriv->cfg->ops->set_desc((u8 *) entry, false, HW_DESC_RXOWN, - (u8 *)&tmp_one); + &tmp_one); } rtlpriv->cfg->ops->set_desc((u8 *) entry, false, - HW_DESC_RXERO, (u8 *)&tmp_one); + HW_DESC_RXERO, &tmp_one); } return 0; } @@ -1263,7 +1263,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) rtlpriv->cfg->ops->set_desc((u8 *) entry, false, HW_DESC_RXOWN, - (u8 *)&tmp_one); + &tmp_one); } rtlpci->rx_ring[rx_queue_idx].idx = 0; } @@ -1422,7 +1422,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, __skb_queue_tail(&ring->queue, skb); rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, - HW_DESC_OWN, (u8 *)&temp_one); + HW_DESC_OWN, &temp_one); if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 5ae26647f340..13ad33e85577 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -333,10 +333,10 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) rpwm_val = 0x0C; /* RF on */ fw_pwrmode = FW_PS_ACTIVE_MODE; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, - (u8 *) (&rpwm_val)); + &rpwm_val); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, - (u8 *) (&fw_pwrmode)); + &fw_pwrmode); fw_current_inps = false; rtlpriv->cfg->ops->set_hw_reg(hw, @@ -356,11 +356,11 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) (u8 *) (&fw_current_inps)); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, - (u8 *) (&ppsc->fwctrl_psmode)); + &ppsc->fwctrl_psmode); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, - (u8 *) (&rpwm_val)); + &rpwm_val); } else { /* Reset the power save related parameters. */ ppsc->dot11_psmode = EACTIVE; @@ -446,7 +446,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct ieee80211_hdr *hdr = (void *) data; + struct ieee80211_hdr *hdr = data; struct ieee80211_tim_ie *tim_ie; u8 *tim; u8 tim_len; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index f7f48c7ac854..a45afda8259c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -656,9 +656,8 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) } else { if (rtlpriv->dm.current_turbo_edca) { u8 tmp = AC0_BE; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&tmp)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + &tmp); rtlpriv->dm.current_turbo_edca = false; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 692c8ef5ee89..44febfde9493 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -168,7 +168,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 *bufferPtr = (u8 *) buffer; + u8 *bufferPtr = buffer; RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size); @@ -262,7 +262,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) return 1; pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; - pfwdata = (u8 *) rtlhal->pfirmware; + pfwdata = rtlhal->pfirmware; fwsize = rtlhal->fwsize; if (IS_FW_HEADER_EXIST(pfwheader)) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 5c4d9bc040f1..bd0da7ef290b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -214,13 +214,13 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) for (e_aci = 0; e_aci < AC_MAX; e_aci++) { rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, - (u8 *) (&e_aci)); + &e_aci); } break; } case HW_VAR_ACK_PREAMBLE:{ u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); + u8 short_preamble = (bool)*val; reg_tmp = (mac->cur_40_prime_sc) << 5; if (short_preamble) reg_tmp |= 0x80; @@ -232,7 +232,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 min_spacing_to_set; u8 sec_min_space; - min_spacing_to_set = *((u8 *) val); + min_spacing_to_set = *val; if (min_spacing_to_set <= 7) { sec_min_space = 0; @@ -257,7 +257,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_SHORTGI_DENSITY:{ u8 density_to_set; - density_to_set = *((u8 *) val); + density_to_set = *val; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, @@ -284,7 +284,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) else p_regtoset = regtoset_normal; - factor_toset = *((u8 *) val); + factor_toset = *(val); if (factor_toset <= 3) { factor_toset = (1 << (factor_toset + 2)); if (factor_toset > 0xf) @@ -316,17 +316,17 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_AC_PARAM:{ - u8 e_aci = *((u8 *) val); + u8 e_aci = *(val); rtl92c_dm_init_edca_turbo(hw); if (rtlpci->acm_method != eAcmWay2_SW) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, - (u8 *) (&e_aci)); + (&e_aci)); break; } case HW_VAR_ACM_CTRL:{ - u8 e_aci = *((u8 *) val); + u8 e_aci = *(val); union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&(mac->ac[0].aifs)); u8 acm = p_aci_aifsn->f.acm; @@ -382,7 +382,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_RETRY_LIMIT:{ - u8 retry_limit = ((u8 *) (val))[0]; + u8 retry_limit = val[0]; rtl_write_word(rtlpriv, REG_RL, retry_limit << RETRY_LIMIT_SHORT_SHIFT | @@ -396,13 +396,13 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtlefuse->efuse_usedbytes = *((u16 *) val); break; case HW_VAR_EFUSE_USAGE: - rtlefuse->efuse_usedpercentage = *((u8 *) val); + rtlefuse->efuse_usedpercentage = *val; break; case HW_VAR_IO_CMD: rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); break; case HW_VAR_WPA_CONFIG: - rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + rtl_write_byte(rtlpriv, REG_SECCFG, *val); break; case HW_VAR_SET_RPWM:{ u8 rpwm_val; @@ -411,31 +411,30 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) udelay(1); if (rpwm_val & BIT(7)) { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - (*(u8 *) val)); + rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); } else { rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - ((*(u8 *) val) | BIT(7))); + *val | BIT(7)); } break; } case HW_VAR_H2C_FW_PWRMODE:{ - u8 psmode = (*(u8 *) val); + u8 psmode = *val; if ((psmode != FW_PS_ACTIVE_MODE) && (!IS_92C_SERIAL(rtlhal->version))) { rtl92c_dm_rf_saving(hw, true); } - rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); + rtl92c_set_fw_pwrmode_cmd(hw, *val); break; } case HW_VAR_FW_PSMODE_STATUS: ppsc->fw_current_inpsmode = *((bool *) val); break; case HW_VAR_H2C_FW_JOINBSSRPT:{ - u8 mstatus = (*(u8 *) val); + u8 mstatus = *val; u8 tmp_regcr, tmp_reg422; bool recover = false; @@ -472,7 +471,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0)))); } - rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + rtl92c_set_fw_joinbss_report_cmd(hw, *val); break; } @@ -486,7 +485,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_CORRECT_TSF:{ - u8 btype_ibss = ((u8 *) (val))[0]; + u8 btype_ibss = val[0]; if (btype_ibss) _rtl92ce_stop_tx_beacon(hw); @@ -1589,10 +1588,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag, hwinfo); - rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->eeprom_channelplan = *&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; rtlefuse->txpwr_fromeprom = true; - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMER_ID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); @@ -1939,7 +1938,7 @@ void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) u16 sifs_timer; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); + &mac->slot_time); if (!mac->ht_enable) sifs_timer = 0x0a0a; else diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 3af874e69595..52166640f167 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -605,7 +605,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool defaultadapter = true; struct ieee80211_sta *sta; - u8 *pdesc = (u8 *) pdesc_tx; + u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue); @@ -806,7 +806,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, SET_TX_DESC_OWN(pdesc, 1); - SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len)); SET_TX_DESC_FIRST_SEG(pdesc, 1); SET_TX_DESC_LAST_SEG(pdesc, 1); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 0c74d4f2eeb4..4bbb711a36c5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -381,11 +381,11 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n", rtlefuse->eeprom_vid, rtlefuse->eeprom_did); - rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_version = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]); rtlefuse->txpwr_fromeprom = true; - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); if (rtlhal->oem_id == RT_CID_DEFAULT) { @@ -1660,7 +1660,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, - (u8 *)(&e_aci)); + &e_aci); } else { u8 sifstime = 0; u8 u1bAIFS; @@ -1685,7 +1685,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } case HW_VAR_ACK_PREAMBLE:{ u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); + u8 short_preamble = (bool)*val; reg_tmp = 0; if (short_preamble) reg_tmp |= 0x80; @@ -1696,7 +1696,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 min_spacing_to_set; u8 sec_min_space; - min_spacing_to_set = *((u8 *) val); + min_spacing_to_set = *val; if (min_spacing_to_set <= 7) { switch (rtlpriv->sec.pairwise_enc_algorithm) { case NO_ENCRYPTION: @@ -1729,7 +1729,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_SHORTGI_DENSITY:{ u8 density_to_set; - density_to_set = *((u8 *) val); + density_to_set = *val; density_to_set &= 0x1f; mac->min_space_cfg &= 0x07; mac->min_space_cfg |= (density_to_set << 3); @@ -1747,7 +1747,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 index = 0; p_regtoset = regtoset_normal; - factor_toset = *((u8 *) val); + factor_toset = *val; if (factor_toset <= 3) { factor_toset = (1 << (factor_toset + 2)); if (factor_toset > 0xf) @@ -1774,7 +1774,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_AC_PARAM:{ - u8 e_aci = *((u8 *) val); + u8 e_aci = *val; u32 u4b_ac_param; u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); @@ -1814,11 +1814,11 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } if (rtlusb->acm_method != eAcmWay2_SW) rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_ACM_CTRL, (u8 *)(&e_aci)); + HW_VAR_ACM_CTRL, &e_aci); break; } case HW_VAR_ACM_CTRL:{ - u8 e_aci = *((u8 *) val); + u8 e_aci = *val; union aci_aifsn *p_aci_aifsn = (union aci_aifsn *) (&(mac->ac[0].aifs)); u8 acm = p_aci_aifsn->f.acm; @@ -1874,7 +1874,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_RETRY_LIMIT:{ - u8 retry_limit = ((u8 *) (val))[0]; + u8 retry_limit = val[0]; rtl_write_word(rtlpriv, REG_RL, retry_limit << RETRY_LIMIT_SHORT_SHIFT | @@ -1891,39 +1891,38 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtlefuse->efuse_usedbytes = *((u16 *) val); break; case HW_VAR_EFUSE_USAGE: - rtlefuse->efuse_usedpercentage = *((u8 *) val); + rtlefuse->efuse_usedpercentage = *val; break; case HW_VAR_IO_CMD: rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); break; case HW_VAR_WPA_CONFIG: - rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + rtl_write_byte(rtlpriv, REG_SECCFG, *val); break; case HW_VAR_SET_RPWM:{ u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); if (rpwm_val & BIT(7)) - rtl_write_byte(rtlpriv, REG_USB_HRPWM, - (*(u8 *)val)); + rtl_write_byte(rtlpriv, REG_USB_HRPWM, *val); else rtl_write_byte(rtlpriv, REG_USB_HRPWM, - ((*(u8 *)val) | BIT(7))); + *val | BIT(7)); break; } case HW_VAR_H2C_FW_PWRMODE:{ - u8 psmode = (*(u8 *) val); + u8 psmode = *val; if ((psmode != FW_PS_ACTIVE_MODE) && (!IS_92C_SERIAL(rtlhal->version))) rtl92c_dm_rf_saving(hw, true); - rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); + rtl92c_set_fw_pwrmode_cmd(hw, (*val)); break; } case HW_VAR_FW_PSMODE_STATUS: ppsc->fw_current_inpsmode = *((bool *) val); break; case HW_VAR_H2C_FW_JOINBSSRPT:{ - u8 mstatus = (*(u8 *) val); + u8 mstatus = *val; u8 tmp_reg422; bool recover = false; @@ -1948,7 +1947,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) tmp_reg422 | BIT(6)); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); } - rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + rtl92c_set_fw_joinbss_report_cmd(hw, (*val)); break; } case HW_VAR_AID:{ @@ -1961,7 +1960,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_CORRECT_TSF:{ - u8 btype_ibss = ((u8 *) (val))[0]; + u8 btype_ibss = val[0]; if (btype_ibss) _rtl92cu_stop_tx_beacon(hw); @@ -2184,7 +2183,7 @@ void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) u16 sifs_timer; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); + &mac->slot_time); if (!mac->ht_enable) sifs_timer = 0x0a0a; else diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 21bc827c5fa6..2e6eb356a93e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -668,7 +668,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, SET_TX_DESC_RATE_ID(pdesc, 7); SET_TX_DESC_MACID(pdesc, 0); SET_TX_DESC_OWN(pdesc, 1); - SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + SET_TX_DESC_PKT_SIZE(pdesc, (u16)skb->len); SET_TX_DESC_FIRST_SEG(pdesc, 1); SET_TX_DESC_LAST_SEG(pdesc, 1); SET_TX_DESC_OFFSET(pdesc, 0x20); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index a7d63a84551a..c0201ed69dd7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -696,7 +696,7 @@ static void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw) if (rtlpriv->dm.current_turbo_edca) { u8 tmp = AC0_BE; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, - (u8 *) (&tmp)); + &tmp); rtlpriv->dm.current_turbo_edca = false; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index f548a8d0068d..895ae6c1f354 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -120,7 +120,7 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 *bufferPtr = (u8 *) buffer; + u8 *bufferPtr = buffer; u32 pagenums, remainSize; u32 page, offset; @@ -256,8 +256,8 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; fwsize = rtlhal->fwsize; - pfwheader = (u8 *) rtlhal->pfirmware; - pfwdata = (u8 *) rtlhal->pfirmware; + pfwheader = rtlhal->pfirmware; + pfwdata = rtlhal->pfirmware; rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index b338d526c422..f4051f4f0390 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -235,12 +235,12 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, - (u8 *) (&e_aci)); + (&e_aci)); break; } case HW_VAR_ACK_PREAMBLE: { u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); + u8 short_preamble = (bool) (*val); reg_tmp = (mac->cur_40_prime_sc) << 5; if (short_preamble) @@ -252,7 +252,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 min_spacing_to_set; u8 sec_min_space; - min_spacing_to_set = *((u8 *) val); + min_spacing_to_set = *val; if (min_spacing_to_set <= 7) { sec_min_space = 0; if (min_spacing_to_set < sec_min_space) @@ -271,7 +271,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_SHORTGI_DENSITY: { u8 density_to_set; - density_to_set = *((u8 *) val); + density_to_set = *val; mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, @@ -293,7 +293,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) regtoSet = 0x66626641; else regtoSet = 0xb972a841; - factor_toset = *((u8 *) val); + factor_toset = *val; if (factor_toset <= 3) { factor_toset = (1 << (factor_toset + 2)); if (factor_toset > 0xf) @@ -316,15 +316,15 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_AC_PARAM: { - u8 e_aci = *((u8 *) val); + u8 e_aci = *val; rtl92d_dm_init_edca_turbo(hw); if (rtlpci->acm_method != eAcmWay2_SW) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, - (u8 *) (&e_aci)); + &e_aci); break; } case HW_VAR_ACM_CTRL: { - u8 e_aci = *((u8 *) val); + u8 e_aci = *val; union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&(mac->ac[0].aifs)); u8 acm = p_aci_aifsn->f.acm; @@ -376,7 +376,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtlpci->receive_config = ((u32 *) (val))[0]; break; case HW_VAR_RETRY_LIMIT: { - u8 retry_limit = ((u8 *) (val))[0]; + u8 retry_limit = val[0]; rtl_write_word(rtlpriv, REG_RL, retry_limit << RETRY_LIMIT_SHORT_SHIFT | @@ -390,16 +390,16 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtlefuse->efuse_usedbytes = *((u16 *) val); break; case HW_VAR_EFUSE_USAGE: - rtlefuse->efuse_usedpercentage = *((u8 *) val); + rtlefuse->efuse_usedpercentage = *val; break; case HW_VAR_IO_CMD: rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val)); break; case HW_VAR_WPA_CONFIG: - rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + rtl_write_byte(rtlpriv, REG_SECCFG, *val); break; case HW_VAR_SET_RPWM: - rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (u8 *) (val)); + rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (val)); break; case HW_VAR_H2C_FW_PWRMODE: break; @@ -407,7 +407,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) ppsc->fw_current_inpsmode = *((bool *) val); break; case HW_VAR_H2C_FW_JOINBSSRPT: { - u8 mstatus = (*(u8 *) val); + u8 mstatus = (*val); u8 tmp_regcr, tmp_reg422; bool recover = false; @@ -435,7 +435,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0)))); } - rtl92d_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + rtl92d_set_fw_joinbss_report_cmd(hw, (*val)); break; } case HW_VAR_AID: { @@ -447,7 +447,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_CORRECT_TSF: { - u8 btype_ibss = ((u8 *) (val))[0]; + u8 btype_ibss = val[0]; if (btype_ibss) _rtl92de_stop_tx_beacon(hw); @@ -1794,7 +1794,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) "RTL819X Not boot from eeprom, check it !!\n"); return; } - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; _rtl92de_read_macphymode_and_bandtype(hw, hwinfo); /* VID, DID SE 0xA-D */ @@ -2115,7 +2115,7 @@ void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw) u16 sifs_timer; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); + &mac->slot_time); if (!mac->ht_enable) sifs_timer = 0x0a0a; else diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 1666ef7fd87b..f80690d82c11 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -560,7 +560,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct ieee80211_sta *sta = info->control.sta; - u8 *pdesc = (u8 *) pdesc_tx; + u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; unsigned int buf_len = 0; @@ -761,11 +761,11 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); SET_TX_DESC_FIRST_SEG(pdesc, 1); SET_TX_DESC_LAST_SEG(pdesc, 1); - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)skb->len); SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); SET_TX_DESC_RATE_ID(pdesc, 7); SET_TX_DESC_MACID(pdesc, 0); - SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len)); SET_TX_DESC_FIRST_SEG(pdesc, 1); SET_TX_DESC_LAST_SEG(pdesc, 1); SET_TX_DESC_OFFSET(pdesc, 0x20); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 2e1158026fb7..465f58157101 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -146,7 +146,7 @@ static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw) if (rtlpriv->dm.current_turbo_edca) { u8 tmp = AC0_BE; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, - (u8 *)(&tmp)); + &tmp); rtlpriv->dm.current_turbo_edca = false; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index b141c35bf926..4542e6952b97 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -145,13 +145,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) for (e_aci = 0; e_aci < AC_MAX; e_aci++) { rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, - (u8 *)(&e_aci)); + (&e_aci)); } break; } case HW_VAR_ACK_PREAMBLE:{ u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); + u8 short_preamble = (bool) (*val); reg_tmp = (mac->cur_40_prime_sc) << 5; if (short_preamble) reg_tmp |= 0x80; @@ -163,7 +163,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 min_spacing_to_set; u8 sec_min_space; - min_spacing_to_set = *((u8 *)val); + min_spacing_to_set = *val; if (min_spacing_to_set <= 7) { if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) @@ -194,7 +194,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_SHORTGI_DENSITY:{ u8 density_to_set; - density_to_set = *((u8 *) val); + density_to_set = *val; mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; mac->min_space_cfg |= (density_to_set << 3); @@ -216,7 +216,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 15, 15, 15, 15, 0}; u8 index = 0; - factor_toset = *((u8 *) val); + factor_toset = *val; if (factor_toset <= 3) { factor_toset = (1 << (factor_toset + 2)); if (factor_toset > 0xf) @@ -248,17 +248,17 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_AC_PARAM:{ - u8 e_aci = *((u8 *) val); + u8 e_aci = *val; rtl92s_dm_init_edca_turbo(hw); if (rtlpci->acm_method != eAcmWay2_SW) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, - (u8 *)(&e_aci)); + &e_aci); break; } case HW_VAR_ACM_CTRL:{ - u8 e_aci = *((u8 *) val); + u8 e_aci = *val; union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&( mac->ac[0].aifs)); u8 acm = p_aci_aifsn->f.acm; @@ -313,7 +313,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_RETRY_LIMIT:{ - u8 retry_limit = ((u8 *) (val))[0]; + u8 retry_limit = val[0]; rtl_write_word(rtlpriv, RETRY_LIMIT, retry_limit << RETRY_LIMIT_SHORT_SHIFT | @@ -328,14 +328,14 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_EFUSE_USAGE: { - rtlefuse->efuse_usedpercentage = *((u8 *) val); + rtlefuse->efuse_usedpercentage = *val; break; } case HW_VAR_IO_CMD: { break; } case HW_VAR_WPA_CONFIG: { - rtl_write_byte(rtlpriv, REG_SECR, *((u8 *) val)); + rtl_write_byte(rtlpriv, REG_SECR, *val); break; } case HW_VAR_SET_RPWM:{ @@ -1813,8 +1813,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) else index = 2; - tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF + - index]) & 0xff; + tempval = hwinfo[EEPROM_TX_PWR_HT20_DIFF + index] & 0xff; rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = ((tempval >> 4) & 0xF); @@ -1830,14 +1829,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) else index = 1; - tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index]) - & 0xff; + tempval = hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index] & 0xff; rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = ((tempval >> 4) & 0xF); - tempval = (*(u8 *)&hwinfo[TX_PWR_SAFETY_CHK]); + tempval = hwinfo[TX_PWR_SAFETY_CHK]; rtlefuse->txpwr_safetyflag = (tempval & 0x01); } @@ -1876,7 +1874,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) /* Read RF-indication and Tx Power gain * index diff of legacy to HT OFDM rate. */ - tempval = (*(u8 *)&hwinfo[EEPROM_RFIND_POWERDIFF]) & 0xff; + tempval = hwinfo[EEPROM_RFIND_POWERDIFF] & 0xff; rtlefuse->eeprom_txpowerdiff = tempval; rtlefuse->legacy_httxpowerdiff = rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; @@ -1887,7 +1885,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) /* Get TSSI value for each path. */ usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8); - usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B]; + usvalue = hwinfo[EEPROM_TSSI_B]; rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", @@ -1896,7 +1894,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) /* Read antenna tx power offset of B/C/D to A from EEPROM */ /* and read ThermalMeter from EEPROM */ - tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER]; + tempval = hwinfo[EEPROM_THERMALMETER]; rtlefuse->eeprom_thermalmeter = tempval; RTPRINT(rtlpriv, FINIT, INIT_TxPower, "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); @@ -1906,20 +1904,20 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; /* Read CrystalCap from EEPROM */ - tempval = (*(u8 *)&hwinfo[EEPROM_CRYSTALCAP]) >> 4; + tempval = hwinfo[EEPROM_CRYSTALCAP] >> 4; rtlefuse->eeprom_crystalcap = tempval; /* CrystalCap, BIT(12)~15 */ rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; /* Read IC Version && Channel Plan */ /* Version ID, Channel plan */ - rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->txpwr_fromeprom = true; RTPRINT(rtlpriv, FINIT, INIT_TxPower, "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); /* Read Customer ID or Board Type!!! */ - tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE]; + tempval = hwinfo[EEPROM_BOARDTYPE]; /* Change RF type definition */ if (tempval == 0) rtlphy->rf_type = RF_2T2R; @@ -1941,7 +1939,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) } } rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID]; + rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x", rtlefuse->eeprom_oemid); @@ -2251,7 +2249,7 @@ void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw) u16 sifs_timer; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); + &mac->slot_time); sifs_timer = 0x0e0e; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 812b5858f14a..36d1cb3aef8a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -599,7 +599,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct ieee80211_sta *sta = info->control.sta; - u8 *pdesc = (u8 *) pdesc_tx; + u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; u8 reserved_macid = 0; diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 6893bc207994..3fb595546538 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -871,8 +871,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, /* Called upon reception of a TX complete interrupt */ void wl1271_tx_complete(struct wl1271 *wl) { - struct wl1271_acx_mem_map *memmap = - (struct wl1271_acx_mem_map *)wl->target_mem_map; + struct wl1271_acx_mem_map *memmap = wl->target_mem_map; u32 count, fw_counter; u32 i; diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 117c4123943c..7ab922209b25 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -827,7 +827,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value, const zd_addr_t addr) { - return zd_ioread32v_locked(chip, value, (const zd_addr_t *)&addr, 1); + return zd_ioread32v_locked(chip, value, &addr, 1); } static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value, diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 99193b456a79..45e3bb28a01c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -274,7 +274,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, const zd_addr_t addr) { - return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); + return zd_usb_ioread16v(usb, value, &addr, 1); } void zd_usb_iowrite16v_async_start(struct zd_usb *usb); -- GitLab From c2fd03a0115a244c5f622453b2b1f038ed5700a6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 4 Jun 2012 12:44:18 +0000 Subject: [PATCH 0786/6849] drivers: net: Remove casts to same type Adding casts of objects to the same type is unnecessary and confusing for a human reader. For example, this cast: int y; int *p = (int *)&y; I used the coccinelle script below to find and remove these unnecessary casts. I manually removed the conversions this script produces of casts with __force, __iomem and __user. @@ type T; T *p; @@ - (T *)p + p Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/appletalk/cops.c | 2 +- drivers/net/can/bfin_can.c | 2 +- drivers/net/can/mcp251x.c | 3 +-- drivers/net/fddi/defxx.c | 4 ++-- drivers/net/fddi/skfp/pmf.c | 8 ++++---- drivers/net/hamradio/mkiss.c | 8 ++++---- drivers/net/hyperv/netvsc.c | 2 +- drivers/net/irda/ali-ircc.c | 6 +++--- drivers/net/irda/au1k_ir.c | 2 +- drivers/net/slip/slip.c | 4 ++-- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- drivers/net/wan/x25_asy.c | 2 +- drivers/net/wimax/i2400m/fw.c | 2 +- 13 files changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index dd5e04813b76..545c09ed9079 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -936,7 +936,7 @@ static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct cops_local *lp = netdev_priv(dev); struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; - struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; + struct atalk_addr *aa = &lp->node_addr; switch(cmd) { diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 3f88473423e9..ea3143895e6d 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -597,7 +597,7 @@ static int __devinit bfin_can_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s device registered" "(®_base=%p, rx_irq=%d, tx_irq=%d, err_irq=%d, sclk=%d)\n", - DRV_NAME, (void *)priv->membase, priv->rx_irq, + DRV_NAME, priv->membase, priv->rx_irq, priv->tx_irq, priv->err_irq, priv->can.clock.freq); return 0; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 346785c56a25..9120a36ec702 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -1020,8 +1020,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) GFP_DMA); if (priv->spi_tx_buf) { - priv->spi_rx_buf = (u8 *)(priv->spi_tx_buf + - (PAGE_SIZE / 2)); + priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2)); priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma + (PAGE_SIZE / 2)); } else { diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index 4ad80f771099..6695a1dadf4e 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -2962,7 +2962,7 @@ static int dfx_rcv_init(DFX_board_t *bp, int get_buffers) bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP | ((PI_RCV_DATA_K_SIZE_MAX / PI_ALIGN_K_RCV_DATA_BUFF) << PI_RCV_DESCR_V_SEG_LEN)); bp->descr_block_virt->rcv_data[i+j].long_1 = (u32) (bp->rcv_block_phys + (i * PI_RCV_DATA_K_SIZE_MAX)); - bp->p_rcv_buff_va[i+j] = (char *) (bp->rcv_block_virt + (i * PI_RCV_DATA_K_SIZE_MAX)); + bp->p_rcv_buff_va[i+j] = (bp->rcv_block_virt + (i * PI_RCV_DATA_K_SIZE_MAX)); } #endif } @@ -3030,7 +3030,7 @@ static void dfx_rcv_queue_process( #ifdef DYNAMIC_BUFFERS p_buff = (char *) (((struct sk_buff *)bp->p_rcv_buff_va[entry])->data); #else - p_buff = (char *) bp->p_rcv_buff_va[entry]; + p_buff = bp->p_rcv_buff_va[entry]; #endif memcpy(&descr, p_buff + RCV_BUFF_K_DESCR, sizeof(u32)); diff --git a/drivers/net/fddi/skfp/pmf.c b/drivers/net/fddi/skfp/pmf.c index 9ac4665d7411..24d8566cfd8b 100644 --- a/drivers/net/fddi/skfp/pmf.c +++ b/drivers/net/fddi/skfp/pmf.c @@ -1242,7 +1242,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, if (len < 8) goto len_error ; if (set) - memcpy((char *) to,(char *) from+2,6) ; + memcpy(to,from+2,6) ; to += 8 ; from += 8 ; len -= 8 ; @@ -1251,7 +1251,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, if (len < 4) goto len_error ; if (set) - memcpy((char *) to,(char *) from,4) ; + memcpy(to,from,4) ; to += 4 ; from += 4 ; len -= 4 ; @@ -1260,7 +1260,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, if (len < 8) goto len_error ; if (set) - memcpy((char *) to,(char *) from,8) ; + memcpy(to,from,8) ; to += 8 ; from += 8 ; len -= 8 ; @@ -1269,7 +1269,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, if (len < 32) goto len_error ; if (set) - memcpy((char *) to,(char *) from,32) ; + memcpy(to,from,32) ; to += 32 ; from += 32 ; len -= 32 ; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index aed1a6105b24..2c0894a92abd 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -485,7 +485,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) return; default: - count = kiss_esc(p, (unsigned char *)ax->xbuff, len); + count = kiss_esc(p, ax->xbuff, len); } } else { unsigned short crc; @@ -497,7 +497,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) case CRC_MODE_SMACK: *p |= 0x80; crc = swab16(crc16(0, p, len)); - count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2); + count = kiss_esc_crc(p, ax->xbuff, crc, len+2); break; case CRC_MODE_FLEX_TEST: ax->crcmode = CRC_MODE_NONE; @@ -506,11 +506,11 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) case CRC_MODE_FLEX: *p |= 0x20; crc = calc_crc_flex(p, len); - count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2); + count = kiss_esc_crc(p, ax->xbuff, crc, len+2); break; default: - count = kiss_esc(p, (unsigned char *)ax->xbuff, len); + count = kiss_esc(p, ax->xbuff, len); } } spin_unlock_bh(&ax->buflock); diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 8b919471472f..4363c76e0d63 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -614,7 +614,7 @@ retry_send_cmplt: static void netvsc_receive_completion(void *context) { struct hv_netvsc_packet *packet = context; - struct hv_device *device = (struct hv_device *)packet->device; + struct hv_device *device = packet->device; struct netvsc_device *net_device; u64 transaction_id = 0; bool fsend_receive_comp = false; diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index dcc80d652b78..84872043b5c6 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -1017,7 +1017,7 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) { int iobase; - struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; + struct ali_ircc_cb *self = priv; struct net_device *dev; IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); @@ -1052,7 +1052,7 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) */ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) { - struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; + struct ali_ircc_cb *self = priv; unsigned long flags; int iobase; int fcr; /* FIFO control reg */ @@ -1121,7 +1121,7 @@ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed) { - struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; + struct ali_ircc_cb *self = priv; int iobase,dongle_id; int tmp = 0; diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index fc503aa5288e..e09417df8f39 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -794,7 +794,7 @@ static int __devinit au1k_irda_net_init(struct net_device *dev) /* allocate the data buffers */ aup->db[0].vaddr = - (void *)dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp); + dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp); if (!aup->db[0].vaddr) goto out3; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index d4c9db3da22a..a34d6bf5e43b 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -390,10 +390,10 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) #endif #ifdef CONFIG_SLIP_MODE_SLIP6 if (sl->mode & SL_MODE_SLIP6) - count = slip_esc6(p, (unsigned char *) sl->xbuff, len); + count = slip_esc6(p, sl->xbuff, len); else #endif - count = slip_esc(p, (unsigned char *) sl->xbuff, len); + count = slip_esc(p, sl->xbuff, len); /* Order of next two lines is *very* important. * When we are sending a little amount of data, diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3f04ba0a5454..93e0cfb739b8 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1037,7 +1037,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, #endif dev_dbg(&adapter->netdev->dev, "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n", - (u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd - + (u32)(ctx.sop_txd - tq->tx_ring.base), le64_to_cpu(gdesc->txd.addr), le32_to_cpu(gdesc->dword[2]), le32_to_cpu(gdesc->dword[3])); diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index d7a65e141d1a..44db8b75a531 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -231,7 +231,7 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len) } p = icp; - count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len); + count = x25_asy_esc(p, sl->xbuff, len); /* Order of next two lines is *very* important. * When we are sending a little amount of data, diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 7cbd7d231e11..d09e44970e63 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -1268,7 +1268,7 @@ int i2400m_fw_check(struct i2400m *i2400m, const void *bcf, size_t bcf_size) size_t leftover, offset, header_len, size; leftover = top - itr; - offset = itr - (const void *) bcf; + offset = itr - bcf; if (leftover <= sizeof(*bcf_hdr)) { dev_err(dev, "firmware %s: %zu B left at @%zx, " "not enough for BCF header\n", -- GitLab From 78f85f5066b721666f869d537eaca6a0818aa301 Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Wed, 16 May 2012 11:34:17 +0300 Subject: [PATCH 0787/6849] wlcore: add role_id to all the sched_scan commands Due to a need by the firmware when working in multirole the role id needs to be added to the structs of the following commands: CMD_CONNECTION_SCAN_CFG, CMD_CONNECTION_SCAN_SSID_CFG, CMD_START_PERIODIC_SCAN, CMD_STOP_PERIODIC_SCAN Signed-off-by: Yoni Divinsky Signed-off-by: Igal Chernobelsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 5 +++-- drivers/net/wireless/ti/wlcore/scan.c | 9 +++++++-- drivers/net/wireless/ti/wlcore/scan.h | 14 +++++++++----- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 54da16501e42..8800a63539e3 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2421,7 +2421,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, } else { /* The current firmware only supports sched_scan in idle */ if (wl->sched_scanning) { - wl1271_scan_sched_scan_stop(wl); + wl1271_scan_sched_scan_stop(wl, wlvif); ieee80211_sched_scan_stopped(wl->hw); } @@ -3152,6 +3152,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct wl1271 *wl = hw->priv; + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); int ret; wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop"); @@ -3165,7 +3166,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, if (ret < 0) goto out; - wl1271_scan_sched_scan_stop(wl); + wl1271_scan_sched_scan_stop(wl, wlvif); wl1271_ps_elp_sleep(wl); out: diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index ade21a011c45..94668d8ba14e 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c @@ -537,6 +537,7 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, /* Returns the scan type to be used or a negative value on error */ static int wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, + struct wl12xx_vif *wlvif, struct cfg80211_sched_scan_request *req) { struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; @@ -565,6 +566,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, goto out; } + cmd->role_id = wlvif->dev_role_id; if (!n_match_ssids) { /* No filter, with ssids */ type = SCAN_SSID_FILTER_DISABLED; @@ -652,6 +654,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, if (!cfg) return -ENOMEM; + cfg->role_id = wlvif->dev_role_id; cfg->rssi_threshold = c->rssi_threshold; cfg->snr_threshold = c->snr_threshold; cfg->n_probe_reqs = c->num_probe_reqs; @@ -669,7 +672,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, cfg->intervals[i] = cpu_to_le32(req->interval); cfg->ssid_len = 0; - ret = wl12xx_scan_sched_scan_ssid_list(wl, req); + ret = wl12xx_scan_sched_scan_ssid_list(wl, wlvif, req); if (ret < 0) goto out; @@ -741,6 +744,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) if (!start) return -ENOMEM; + start->role_id = wlvif->dev_role_id; start->tag = WL1271_SCAN_DEFAULT_TAG; ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start, @@ -762,7 +766,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl) ieee80211_sched_scan_results(wl->hw); } -void wl1271_scan_sched_scan_stop(struct wl1271 *wl) +void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif) { struct wl1271_cmd_sched_scan_stop *stop; int ret = 0; @@ -776,6 +780,7 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl) return; } + stop->role_id = wlvif->dev_role_id; stop->tag = WL1271_SCAN_DEFAULT_TAG; ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop, diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h index 81ee36ac2078..5b6a609fb460 100644 --- a/drivers/net/wireless/ti/wlcore/scan.h +++ b/drivers/net/wireless/ti/wlcore/scan.h @@ -40,7 +40,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct ieee80211_sched_scan_ies *ies); int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif); -void wl1271_scan_sched_scan_stop(struct wl1271 *wl); +void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); void wl1271_scan_sched_scan_results(struct wl1271 *wl); #define WL1271_SCAN_MAX_CHANNELS 24 @@ -185,7 +185,8 @@ struct wl1271_cmd_sched_scan_config { u8 dfs; - u8 padding[3]; + u8 role_id; + u8 padding[2]; struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ]; struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ]; @@ -212,21 +213,24 @@ struct wl1271_cmd_sched_scan_ssid_list { u8 n_ssids; struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS]; - u8 padding[3]; + u8 role_id; + u8 padding[2]; } __packed; struct wl1271_cmd_sched_scan_start { struct wl1271_cmd_header header; u8 tag; - u8 padding[3]; + u8 role_id; + u8 padding[2]; } __packed; struct wl1271_cmd_sched_scan_stop { struct wl1271_cmd_header header; u8 tag; - u8 padding[3]; + u8 role_id; + u8 padding[2]; } __packed; -- GitLab From 587cc286c8a8e22bbe4521c331b88d62d0cb1076 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 15 May 2012 18:31:58 +0300 Subject: [PATCH 0788/6849] wlcore: compare ssid_len before comparing ssids When comparing 2 ssids the ssid_len must be taken into account. Otherwise, a substring will be treated as equal. This bug might cause ssids to get scanned as public ssids (rather than hidden), resulting in broadcast probe request (instead of ssid-specific ones) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/scan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index 94668d8ba14e..e1dbe812615f 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c @@ -605,7 +605,9 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, continue; for (j = 0; j < cmd->n_ssids; j++) - if (!memcmp(req->ssids[i].ssid, + if ((req->ssids[i].ssid_len == + req->ssids[j].ssid_len) && + !memcmp(req->ssids[i].ssid, cmd->ssids[j].ssid, req->ssids[i].ssid_len)) { cmd->ssids[j].type = -- GitLab From 97511b15b1926337f90226b3cb735e52f2dc8a85 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Tue, 15 May 2012 17:04:40 +0300 Subject: [PATCH 0789/6849] wlcore: set channels 12-14 as pactive for sched scan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce “pactive” scan mode – which instructs the fw to perform a passive scan until an activity/energy is detected on these channels, once energy detected the channel becomes active. Signed-off-by: Victor Goldenshtein Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/scan.c | 39 ++++++++++++++++++++++----- drivers/net/wireless/ti/wlcore/scan.h | 7 +++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index e1dbe812615f..d9daed53ceb7 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c @@ -411,7 +411,8 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct conn_scan_ch_params *channels, u32 band, bool radar, bool passive, - int start, int max_channels) + int start, int max_channels, + u8 *n_pactive_ch) { struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, j; @@ -479,6 +480,23 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, channels[j].tx_power_att = req->channels[i]->max_power; channels[j].channel = req->channels[i]->hw_value; + if ((band == IEEE80211_BAND_2GHZ) && + (channels[j].channel >= 12) && + (channels[j].channel <= 14) && + (flags & IEEE80211_CHAN_PASSIVE_SCAN) && + !force_passive) { + /* pactive channels treated as DFS */ + channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; + + /* + * n_pactive_ch is counted down from the end of + * the passive channel list + */ + (*n_pactive_ch)++; + wl1271_debug(DEBUG_SCAN, "n_pactive_ch = %d", + *n_pactive_ch); + } + j++; } } @@ -491,38 +509,47 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct wl1271_cmd_sched_scan_config *cfg) { + u8 n_pactive_ch = 0; + cfg->passive[0] = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, IEEE80211_BAND_2GHZ, false, true, 0, - MAX_CHANNELS_2GHZ); + MAX_CHANNELS_2GHZ, + &n_pactive_ch); cfg->active[0] = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, IEEE80211_BAND_2GHZ, false, false, cfg->passive[0], - MAX_CHANNELS_2GHZ); + MAX_CHANNELS_2GHZ, + &n_pactive_ch); cfg->passive[1] = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, IEEE80211_BAND_5GHZ, false, true, 0, - MAX_CHANNELS_5GHZ); + MAX_CHANNELS_5GHZ, + &n_pactive_ch); cfg->dfs = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, IEEE80211_BAND_5GHZ, true, true, cfg->passive[1], - MAX_CHANNELS_5GHZ); + MAX_CHANNELS_5GHZ, + &n_pactive_ch); cfg->active[1] = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, IEEE80211_BAND_5GHZ, false, false, cfg->passive[1] + cfg->dfs, - MAX_CHANNELS_5GHZ); + MAX_CHANNELS_5GHZ, + &n_pactive_ch); /* 802.11j channels are not supported yet */ cfg->passive[2] = 0; cfg->active[2] = 0; + cfg->n_pactive_ch = n_pactive_ch; + wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", cfg->active[0], cfg->passive[0]); wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h index 5b6a609fb460..29f3c8d6b046 100644 --- a/drivers/net/wireless/ti/wlcore/scan.h +++ b/drivers/net/wireless/ti/wlcore/scan.h @@ -142,7 +142,8 @@ enum { SCAN_BSS_TYPE_ANY, }; -#define SCAN_CHANNEL_FLAGS_DFS BIT(0) +#define SCAN_CHANNEL_FLAGS_DFS BIT(0) /* channel is passive until an + activity is detected on it */ #define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1) struct conn_scan_ch_params { @@ -185,8 +186,10 @@ struct wl1271_cmd_sched_scan_config { u8 dfs; + u8 n_pactive_ch; /* number of pactive (passive until fw detects energy) + channels in BG band */ u8 role_id; - u8 padding[2]; + u8 padding[1]; struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ]; struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ]; -- GitLab From 4bfaddf15bac7afa7048d105864dab65c5d1f9e7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Jun 2012 21:26:30 +0000 Subject: [PATCH 0790/6849] x86 bpf_jit: support BPF_S_ANC_ALU_XOR_X instruction commit ffe06c17afbb (filter: add XOR operation) added generic support for XOR operation. This patch implements the XOR instruction in x86 jit. Signed-off-by: Eric Dumazet Cc: Jiri Pirko Signed-off-by: David S. Miller --- arch/x86/net/bpf_jit_comp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 0597f95b6da6..33643a8bcbbb 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -309,6 +309,10 @@ void bpf_jit_compile(struct sk_filter *fp) else EMIT1_off32(0x0d, K); /* or imm32,%eax */ break; + case BPF_S_ANC_ALU_XOR_X: /* A ^= X; */ + seen |= SEEN_XREG; + EMIT2(0x31, 0xd8); /* xor %ebx,%eax */ + break; case BPF_S_ALU_LSH_X: /* A <<= X; */ seen |= SEEN_XREG; EMIT4(0x89, 0xd9, 0xd3, 0xe0); /* mov %ebx,%ecx; shl %cl,%eax */ -- GitLab From d7ce8a5f63838d99726ec81f666075d65361325b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 6 Jun 2012 10:20:21 -0700 Subject: [PATCH 0791/6849] sparc bpf_jit: support BPF_S_ANC_ALU_XOR_X instruction Signed-off-by: David S. Miller --- arch/sparc/net/bpf_jit_comp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 1a69244e785b..e9073e9501b3 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -96,6 +96,7 @@ static void bpf_flush_icache(void *start_, void *end_) #define AND F3(2, 0x01) #define ANDCC F3(2, 0x11) #define OR F3(2, 0x02) +#define XOR F3(2, 0x03) #define SUB F3(2, 0x04) #define SUBCC F3(2, 0x14) #define MUL F3(2, 0x0a) /* umul */ @@ -462,6 +463,9 @@ void bpf_jit_compile(struct sk_filter *fp) case BPF_S_ALU_OR_K: /* A |= K */ emit_alu_K(OR, K); break; + case BPF_S_ANC_ALU_XOR_X: /* A ^= X; */ + emit_alu_X(XOR); + break; case BPF_S_ALU_LSH_X: /* A <<= X */ emit_alu_X(SLL); break; -- GitLab From e8c9bd5b8d807cfe6c923265969a523b1ba1e6c2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Jun 2012 08:18:22 +0200 Subject: [PATCH 0792/6849] cfg80211: clarify set_channel APIs Now that we've removed all uses of the set_channel API except for the monitor channel and in libertas, clarify this. Split the libertas mesh use into a new libertas_set_mesh_channel() operation, just to keep backward compatibility, and rename the normal set_channel() to set_monitor_channel(). Also describe the desired set_monitor_channel() semantics more clearly. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 39 ++++++++++++++++++------- drivers/net/wireless/libertas/dev.h | 1 + drivers/net/wireless/libertas/mesh.c | 7 ++--- drivers/net/wireless/orinoco/cfg.c | 9 +++--- include/net/cfg80211.h | 24 ++++++++++------ net/mac80211/cfg.c | 9 +++++- net/wireless/chan.c | 43 ++++------------------------ net/wireless/core.h | 5 ++-- net/wireless/mesh.c | 26 ++++++++--------- net/wireless/mlme.c | 2 -- net/wireless/nl80211.c | 21 ++++++++------ net/wireless/wext-compat.c | 10 ++----- net/wireless/wext-sme.c | 10 +++++-- 13 files changed, 100 insertions(+), 106 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 2fa879b015b6..f4a203049fb4 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -435,24 +435,40 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) * Set Channel */ -static int lbs_cfg_set_channel(struct wiphy *wiphy, - struct net_device *netdev, - struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type) +static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) { struct lbs_private *priv = wiphy_priv(wiphy); int ret = -ENOTSUPP; - lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d, type %d", - netdev_name(netdev), channel->center_freq, channel_type); + lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", + channel->center_freq, channel_type); if (channel_type != NL80211_CHAN_NO_HT) goto out; - if (netdev == priv->mesh_dev) - ret = lbs_mesh_set_channel(priv, channel->hw_value); - else - ret = lbs_set_channel(priv, channel->hw_value); + ret = lbs_set_channel(priv, channel->hw_value); + + out: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + +static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy, + struct net_device *netdev, + struct ieee80211_channel *channel) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + int ret = -ENOTSUPP; + + lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d", + netdev_name(netdev), channel->center_freq); + + if (netdev != priv->mesh_dev) + goto out; + + ret = lbs_mesh_set_channel(priv, channel->hw_value); out: lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); @@ -2029,7 +2045,8 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) */ static struct cfg80211_ops lbs_cfg80211_ops = { - .set_channel = lbs_cfg_set_channel, + .set_monitor_channel = lbs_cfg_set_monitor_channel, + .libertas_set_mesh_channel = lbs_cfg_set_mesh_channel, .scan = lbs_cfg_scan, .connect = lbs_cfg_connect, .disconnect = lbs_cfg_disconnect, diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 672005430aca..60996ce89f77 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -58,6 +58,7 @@ struct lbs_private { uint16_t mesh_tlv; u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1]; u8 mesh_ssid_len; + u8 mesh_channel; #endif /* Debugfs */ diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index e87c031b298f..97807751ebcf 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -131,16 +131,13 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel) { + priv->mesh_channel = channel; return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel); } static uint16_t lbs_mesh_get_channel(struct lbs_private *priv) { - struct wireless_dev *mesh_wdev = priv->mesh_dev->ieee80211_ptr; - if (mesh_wdev->channel) - return mesh_wdev->channel->hw_value; - else - return 1; + return priv->mesh_channel ?: 1; } /*************************************************************************** diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c index f7b15b8934fa..e15675585fb1 100644 --- a/drivers/net/wireless/orinoco/cfg.c +++ b/drivers/net/wireless/orinoco/cfg.c @@ -160,10 +160,9 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev, return err; } -static int orinoco_set_channel(struct wiphy *wiphy, - struct net_device *netdev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) +static int orinoco_set_monitor_channel(struct wiphy *wiphy, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) { struct orinoco_private *priv = wiphy_priv(wiphy); int err = 0; @@ -286,7 +285,7 @@ static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed) const struct cfg80211_ops orinoco_cfg_ops = { .change_virtual_intf = orinoco_change_vif, - .set_channel = orinoco_set_channel, + .set_monitor_channel = orinoco_set_monitor_channel, .scan = orinoco_scan, .set_wiphy_params = orinoco_set_wiphy_params, }; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4c90c44b8b75..7319f25250b6 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1420,11 +1420,14 @@ struct cfg80211_gtk_rekey_data { * * @set_txq_params: Set TX queue parameters * - * @set_channel: Set channel for a given wireless interface. Some devices - * may support multi-channel operation (by channel hopping) so cfg80211 - * doesn't verify much. Note, however, that the passed netdev may be - * %NULL as well if the user requested changing the channel for the - * device itself, or for a monitor interface. + * @libertas_set_mesh_channel: Only for backward compatibility for libertas, + * as it doesn't implement join_mesh and needs to set the channel to + * join the mesh instead. + * + * @set_monitor_channel: Set the monitor mode channel for the device. If other + * interfaces are active this callback should reject the configuration. + * If no interfaces are active or the device is down, the channel should + * be stored for when a monitor interface becomes active. * @get_channel: Get the current operating channel, should return %NULL if * there's no single defined operating channel if for example the * device implements channel hopping for multi-channel virtual interfaces. @@ -1614,9 +1617,13 @@ struct cfg80211_ops { int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_txq_params *params); - int (*set_channel)(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type); + int (*libertas_set_mesh_channel)(struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_channel *chan); + + int (*set_monitor_channel)(struct wiphy *wiphy, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type); int (*scan)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request); @@ -2325,7 +2332,6 @@ struct wireless_dev { spinlock_t event_lock; struct cfg80211_internal_bss *current_bss; /* associated / joined */ - struct ieee80211_channel *channel; struct ieee80211_channel *preset_chan; enum nl80211_channel_type preset_chantype; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 50aea1ac7e03..d99359a6f76d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -709,6 +709,13 @@ static int ieee80211_set_channel(struct wiphy *wiphy, return 0; } +static int ieee80211_set_monitor_channel(struct wiphy *wiphy, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) +{ + return ieee80211_set_channel(wiphy, NULL, chan, channel_type); +} + static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, const u8 *resp, size_t resp_len) { @@ -2932,7 +2939,7 @@ struct cfg80211_ops mac80211_config_ops = { #endif .change_bss = ieee80211_change_bss, .set_txq_params = ieee80211_set_txq_params, - .set_channel = ieee80211_set_channel, + .set_monitor_channel = ieee80211_set_monitor_channel, .suspend = ieee80211_suspend, .resume = ieee80211_resume, .scan = ieee80211_scan, diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 20b87d895722..c1999e45a07c 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -78,50 +78,17 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, } EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); -int cfg80211_set_freq(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, int freq, - enum nl80211_channel_type channel_type) +int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, + int freq, enum nl80211_channel_type chantype) { struct ieee80211_channel *chan; - int result; - if (wdev && wdev->iftype == NL80211_IFTYPE_MONITOR) - wdev = NULL; - - if (wdev) { - ASSERT_WDEV_LOCK(wdev); - - if (!netif_running(wdev->netdev)) - return -ENETDOWN; - } - - if (!rdev->ops->set_channel) + if (!rdev->ops->set_monitor_channel) return -EOPNOTSUPP; - chan = rdev_freq_to_chan(rdev, freq, channel_type); + chan = rdev_freq_to_chan(rdev, freq, chantype); if (!chan) return -EINVAL; - /* Both channels should be able to initiate communication */ - if (wdev && (wdev->iftype == NL80211_IFTYPE_ADHOC || - wdev->iftype == NL80211_IFTYPE_AP || - wdev->iftype == NL80211_IFTYPE_AP_VLAN || - wdev->iftype == NL80211_IFTYPE_MESH_POINT || - wdev->iftype == NL80211_IFTYPE_P2P_GO) && - !cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan, channel_type)) { - printk(KERN_DEBUG - "cfg80211: Secondary channel not allowed to beacon\n"); - return -EINVAL; - } - - result = rdev->ops->set_channel(&rdev->wiphy, - wdev ? wdev->netdev : NULL, - chan, channel_type); - if (result) - return result; - - if (wdev) - wdev->channel = chan; - - return 0; + return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); } diff --git a/net/wireless/core.h b/net/wireless/core.h index 1d3d24126946..9348a47562a4 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -444,9 +444,8 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, struct ieee80211_channel * rdev_freq_to_chan(struct cfg80211_registered_device *rdev, int freq, enum nl80211_channel_type channel_type); -int cfg80211_set_freq(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, int freq, - enum nl80211_channel_type channel_type); +int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, + int freq, enum nl80211_channel_type chantype); int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, const u8 *rates, unsigned int n_rates, diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 2e3b700eba32..b44c736bf9cf 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -179,6 +179,13 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, { struct ieee80211_channel *channel; + channel = rdev_freq_to_chan(rdev, freq, channel_type); + if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, + channel, + channel_type)) { + return -EINVAL; + } + /* * Workaround for libertas (only!), it puts the interface * into mesh mode but doesn't implement join_mesh. Instead, @@ -186,27 +193,20 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, * you set the channel. Note that the libertas mesh isn't * compatible with 802.11 mesh. */ - if (!rdev->ops->join_mesh) { - int err; + if (rdev->ops->libertas_set_mesh_channel) { + if (channel_type != NL80211_CHAN_NO_HT) + return -EINVAL; if (!netif_running(wdev->netdev)) return -ENETDOWN; - wdev_lock(wdev); - err = cfg80211_set_freq(rdev, wdev, freq, channel_type); - wdev_unlock(wdev); - - return err; + return rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, + wdev->netdev, + channel); } if (wdev->mesh_id_len) return -EBUSY; - channel = rdev_freq_to_chan(rdev, freq, channel_type); - if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, - channel, - channel_type)) { - return -EINVAL; - } wdev->preset_chan = channel; wdev->preset_chantype = channel_type; return 0; diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index eb90988bbd36..da4406f11929 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -947,8 +947,6 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, if (WARN_ON(!chan)) goto out; - wdev->channel = chan; - nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL); out: wdev_unlock(wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b22f1f876881..5e29bd38e7df 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -921,7 +921,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) goto nla_put_failure; } - if (dev->ops->set_channel || dev->ops->start_ap || + if (dev->ops->set_monitor_channel || dev->ops->start_ap || dev->ops->join_mesh) { i++; if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) @@ -1178,8 +1178,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) * the channel in the start-ap or join-mesh commands instead. * * Monitors are special as they are normally slaved to - * whatever else is going on, so they behave as though - * you tried setting the wiphy channel itself. + * whatever else is going on, so they have their own special + * operation to set the monitor channel if possible. */ return !wdev || wdev->iftype == NL80211_IFTYPE_AP || @@ -1217,6 +1217,10 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; u32 freq; int result; + enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; + + if (wdev) + iftype = wdev->iftype; if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) return -EINVAL; @@ -1231,7 +1235,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); mutex_lock(&rdev->devlist_mtx); - if (wdev) switch (wdev->iftype) { + switch (iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: if (wdev->beacon_interval) { @@ -1252,12 +1256,11 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_MESH_POINT: result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); break; + case NL80211_IFTYPE_MONITOR: + result = cfg80211_set_monitor_channel(rdev, freq, channel_type); + break; default: - wdev_lock(wdev); - result = cfg80211_set_freq(rdev, wdev, freq, channel_type); - wdev_unlock(wdev); - } else { - result = cfg80211_set_freq(rdev, NULL, freq, channel_type); + result = -EINVAL; } mutex_unlock(&rdev->devlist_mtx); diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index faeb03548aa4..bc879833b21f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -802,9 +802,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, if (freq == 0) return -EINVAL; mutex_lock(&rdev->devlist_mtx); - wdev_lock(wdev); - err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT); - wdev_unlock(wdev); + err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); mutex_unlock(&rdev->devlist_mtx); return err; case NL80211_IFTYPE_MESH_POINT: @@ -848,11 +846,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, freq->e = 6; return 0; default: - if (!wdev->channel) - return -EINVAL; - freq->m = wdev->channel->center_freq; - freq->e = 6; - return 0; + return -EINVAL; } } diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 7decbd357d51..1f773f668d1a 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -111,9 +111,15 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, wdev->wext.connect.channel = chan; - /* SSID is not set, we just want to switch channel */ + /* + * SSID is not set, we just want to switch monitor channel, + * this is really just backward compatibility, if the SSID + * is set then we use the channel to select the BSS to use + * to connect to instead. If we were connected on another + * channel we disconnected above and reconnect below. + */ if (chan && !wdev->wext.connect.ssid_len) { - err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT); + err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); goto out; } -- GitLab From 27e49ca95570c4685a32be9d4664f2b0b6d89368 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 23 May 2012 14:11:52 +0800 Subject: [PATCH 0793/6849] rfkill: Add the capability to switch all devices of all type in __rfkill_switch_all(). __rfkill_switch_all() switches the state of devices of a given type; however, it does not switch devices of all type (RFKILL_TYPE_ALL). As a result, it ignores the keycode "KEY_RFKILL" from another module, i.e. eeepc-wmi. This fix is to make __rfkill_switch_all() to be able to switch not only devices of a given type but also all devices. Signed-off-by: Alex Hung Signed-off-by: John W. Linville --- net/rfkill/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rfkill/core.c b/net/rfkill/core.c index f974961754ca..752b72360ebc 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -325,7 +325,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, bool blocked) rfkill_global_states[type].cur = blocked; list_for_each_entry(rfkill, &rfkill_list, node) { - if (rfkill->type != type) + if (rfkill->type != type && type != RFKILL_TYPE_ALL) continue; rfkill_set_block(rfkill, blocked); -- GitLab From 620a55687b20c23ca7b8d8560b0e8fb3ca13869a Mon Sep 17 00:00:00 2001 From: Zefir Kurtisi Date: Wed, 23 May 2012 13:34:31 +0200 Subject: [PATCH 0794/6849] ath9k: fix/add bits for spectral scanning Updates for spectral scanning register modification for AR93x: * fix bits for spectral_scan_count * add bits for new parameters Signed-off-by: Zefir Kurtisi Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 32 +++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7268a48a92a1..ed662c3bae5b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -820,18 +820,26 @@ #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 #define AR_PHY_RX_DELAY_DELAY 0x00003FFF #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 -#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 -#define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 -#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 -#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 -#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 -#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 -#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 -#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 -#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 -#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 -#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 -#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 + +#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 +#define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 +#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 +#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 +#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 +#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 +#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 +#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 +#define AR_PHY_SPECTRAL_SCAN_COUNT 0x0FFF0000 +#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 +#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x10000000 +#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 28 +#define AR_PHY_SPECTRAL_SCAN_PRIORITY 0x20000000 +#define AR_PHY_SPECTRAL_SCAN_PRIORITY_S 29 +#define AR_PHY_SPECTRAL_SCAN_USE_ERR5 0x40000000 +#define AR_PHY_SPECTRAL_SCAN_USE_ERR5_S 30 +#define AR_PHY_SPECTRAL_SCAN_COMPRESSED_RPT 0x80000000 +#define AR_PHY_SPECTRAL_SCAN_COMPRESSED_RPT_S 31 + #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001 #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0 -- GitLab From 6851dff3e6b858f2759fc9ecebc4ec608df81805 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 May 2012 11:53:11 +0200 Subject: [PATCH 0795/6849] rt2x00: claim RSN IBSS support Similar like other drivers, do not configure group keys to the hardware (on Ad-Hoc mode) to make IBSS RSN work. Signed-off-by: Stanislaw Gruszka Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 ++ drivers/net/wireless/rt2x00/rt2x00mac.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e5404e576251..a6b88bd4a1a5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1161,6 +1161,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_WDS); + rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + /* * Initialize work. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index dd24b2663b5e..4ff26c2159bf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -506,9 +506,19 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; - else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) + + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) + return -EOPNOTSUPP; + + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -EOPNOTSUPP; - else if (key->keylen > 32) + + if (key->keylen > 32) return -ENOSPC; memset(&crypto, 0, sizeof(crypto)); -- GitLab From d7fbcada37ec71b61901bf4344ca832a1bb9f5d1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 May 2012 11:54:11 +0200 Subject: [PATCH 0796/6849] iwl4965: claim RSN IBSS support Similar like other drivers including iwl3945, do not configure group keys to the hardware (on Ad-Hoc mode) to make IBSS RSN work. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 509301a5e7e2..d24eaf89ffb5 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5724,7 +5724,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->flags |= - WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; + WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | + WIPHY_FLAG_IBSS_RSN; /* * For now, disable PS by default because it affects @@ -5873,6 +5874,16 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + D_MAC80211("leave - ad-hoc group key\n"); + return -EOPNOTSUPP; + } + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return -EINVAL; -- GitLab From cff3d1f0931d0e6189f5ee718112b235bad1bf99 Mon Sep 17 00:00:00 2001 From: "Zero.Lin" Date: Tue, 29 May 2012 16:11:09 +0800 Subject: [PATCH 0797/6849] rt2x00:Add RT5392 chipset support Signed-off-by: Zero.Lin Reviewed-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 6 ++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 6403f49da419..1ca88cdc6ece 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -72,6 +72,7 @@ #define RF5370 0x5370 #define RF5372 0x5372 #define RF5390 0x5390 +#define RF5392 0x5392 /* * Chipset revisions. @@ -1945,6 +1946,11 @@ struct mac_iveiv_entry { */ #define RFCSR49_TX FIELD8(0x3f) +/* + * RFCSR 50: + */ +#define RFCSR50_TX FIELD8(0x3f) + /* * RF registers */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 11488e743f08..4d3747c3010b 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1958,7 +1958,22 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); + if (info->default_power1 > RT5390_POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR50_TX, + RT5390_POWER_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR50_TX, + info->default_power2); + rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); + } + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); + } rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); @@ -2064,6 +2079,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF5370: case RF5372: case RF5390: + case RF5392: rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); break; default: @@ -2554,6 +2570,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) case RF5370: case RF5372: case RF5390: + case RF5392: rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); @@ -4269,6 +4286,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF5370: case RF5372: case RF5390: + case RF5392: break; default: ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", @@ -4583,7 +4601,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5370) || rt2x00_rf(rt2x00dev, RF5372) || - rt2x00_rf(rt2x00dev, RF5390)) { + rt2x00_rf(rt2x00dev, RF5390) || + rt2x00_rf(rt2x00dev, RF5392)) { spec->num_channels = 14; spec->channels = rf_vals_3x; } else if (rt2x00_rf(rt2x00dev, RF3052)) { @@ -4670,6 +4689,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF5370: case RF5372: case RF5390: + case RF5392: __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); break; } -- GitLab From d202caff28d69f4ec6cf56568f79b0916294cade Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Tue, 29 May 2012 15:59:55 +0530 Subject: [PATCH 0798/6849] ath9k: Ensure a fair beacon distribution in IBSS mode Configure CWmin based on slot time for IBSS mode. This helps in increasing the beacon distribution of ath9k to accepted levels in 11a mode. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 11bc55e3d697..70b802529123 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -48,7 +48,10 @@ int ath_beaconq_config(struct ath_softc *sc) txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; + if (ah->slottime == ATH9K_SLOT_TIME_20) + qi.tqi_cwmin = 2*qi_be.tqi_cwmin; + else + qi.tqi_cwmin = 4*qi_be.tqi_cwmin; qi.tqi_cwmax = qi_be.tqi_cwmax; } -- GitLab From a8ce85442e8ed7ae3c05e7e3b7e42adb32a371ec Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 30 May 2012 10:56:46 +0200 Subject: [PATCH 0799/6849] mac80211: configure 11b/g channel access rules for legacy APs For each EDCA TX queue change default settings (in STA mode) to conform old 802.11b/g channel access rules. This is needed for drivers that do not have QoS enable/disable "switch" (like rt2x00) to make them work properly with legacy APs. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- net/mac80211/util.c | 80 ++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8dd4712620ff..b007c6861032 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -804,7 +804,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_tx_queue_params qparam; int ac; - bool use_11b; + bool use_11b, enable_qos; int aCWmin, aCWmax; if (!local->ops->conf_tx) @@ -818,6 +818,13 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); + /* + * By default disable QoS in STA mode for old access points, which do + * not support 802.11e. New APs will provide proper queue parameters, + * that we will configure later. + */ + enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { /* Set defaults according to 802.11-2007 Table 7-37 */ aCWmax = 1023; @@ -826,38 +833,47 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, else aCWmin = 15; - switch (ac) { - case IEEE80211_AC_BK: - qparam.cw_max = aCWmax; - qparam.cw_min = aCWmin; - qparam.txop = 0; - qparam.aifs = 7; - break; - default: /* never happens but let's not leave undefined */ - case IEEE80211_AC_BE: + if (enable_qos) { + switch (ac) { + case IEEE80211_AC_BK: + qparam.cw_max = aCWmax; + qparam.cw_min = aCWmin; + qparam.txop = 0; + qparam.aifs = 7; + break; + /* never happens but let's not leave undefined */ + default: + case IEEE80211_AC_BE: + qparam.cw_max = aCWmax; + qparam.cw_min = aCWmin; + qparam.txop = 0; + qparam.aifs = 3; + break; + case IEEE80211_AC_VI: + qparam.cw_max = aCWmin; + qparam.cw_min = (aCWmin + 1) / 2 - 1; + if (use_11b) + qparam.txop = 6016/32; + else + qparam.txop = 3008/32; + qparam.aifs = 2; + break; + case IEEE80211_AC_VO: + qparam.cw_max = (aCWmin + 1) / 2 - 1; + qparam.cw_min = (aCWmin + 1) / 4 - 1; + if (use_11b) + qparam.txop = 3264/32; + else + qparam.txop = 1504/32; + qparam.aifs = 2; + break; + } + } else { + /* Confiure old 802.11b/g medium access rules. */ qparam.cw_max = aCWmax; qparam.cw_min = aCWmin; qparam.txop = 0; - qparam.aifs = 3; - break; - case IEEE80211_AC_VI: - qparam.cw_max = aCWmin; - qparam.cw_min = (aCWmin + 1) / 2 - 1; - if (use_11b) - qparam.txop = 6016/32; - else - qparam.txop = 3008/32; - qparam.aifs = 2; - break; - case IEEE80211_AC_VO: - qparam.cw_max = (aCWmin + 1) / 2 - 1; - qparam.cw_min = (aCWmin + 1) / 4 - 1; - if (use_11b) - qparam.txop = 3264/32; - else - qparam.txop = 1504/32; qparam.aifs = 2; - break; } qparam.uapsd = false; @@ -866,12 +882,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, drv_conf_tx(local, sdata, ac, &qparam); } - /* after reinitialize QoS TX queues setting to default, - * disable QoS at all */ - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { - sdata->vif.bss_conf.qos = - sdata->vif.type != NL80211_IFTYPE_STATION; + sdata->vif.bss_conf.qos = enable_qos; if (bss_notify) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); -- GitLab From 1c4cb928e1b7c6ad30a9b7d3e720f26156d92925 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 May 2012 15:57:00 +0200 Subject: [PATCH 0800/6849] mac80211: print info when disabling HT Make mac80211 print a message when it disables HT due to the connection using WEP/TKIP or due to the AP not supporting WMM/QoS. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index da6bd81fec6d..e7c4ec4ce166 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3317,11 +3317,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, * We can set this to true for non-11n hardware, that'll be checked * separately along with the peer capabilities. */ - for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) + for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) { if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || - req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) + req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { ifmgd->flags |= IEEE80211_STA_DISABLE_11N; + netdev_info(sdata->dev, + "disabling HT due to WEP/TKIP use\n"); + } + } if (req->flags & ASSOC_REQ_DISABLE_HT) ifmgd->flags |= IEEE80211_STA_DISABLE_11N; @@ -3329,8 +3333,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, /* Also disable HT if we don't support it or the AP doesn't use WMM */ sband = local->hw.wiphy->bands[req->bss->channel->band]; if (!sband->ht_cap.ht_supported || - local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) + local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { ifmgd->flags |= IEEE80211_STA_DISABLE_11N; + netdev_info(sdata->dev, + "disabling HT as WMM/QoS is not supported\n"); + } memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, -- GitLab From 8c06e8c08e25da6c147c30717aecfcfe3bdcb758 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Thu, 31 May 2012 18:17:30 +0800 Subject: [PATCH 0801/6849] mac80211: Add missing mesh parameter dot11MeshForwarding for debugfs Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- net/mac80211/debugfs_netdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 1a3b36154e73..d4272ff43f71 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -607,6 +607,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(min_discovery_timeout); MESHPARAMS_ADD(dot11MeshHWMPRootMode); MESHPARAMS_ADD(dot11MeshHWMPRannInterval); + MESHPARAMS_ADD(dot11MeshForwarding); MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); MESHPARAMS_ADD(rssi_threshold); MESHPARAMS_ADD(ht_opmode); -- GitLab From 3b08cf6bd2763bfe9d04fad4d7de29ee7735cd76 Mon Sep 17 00:00:00 2001 From: Pontus Fuchs Date: Thu, 31 May 2012 12:34:47 +0200 Subject: [PATCH 0802/6849] mac80211: Clear wowlan flag when drv_suspend returns failure drv_resume can get called without a prior call to drv_suspend. Consider the following steps: 1. Suspend is started but driver's drv_suspend returns error. 2. Suspend is aborted. local->wowlan flag is left set. 3. Interface is removed. 4. Suspend again. This time open_count is 0 so drv_suspend is not called and local->wowlan not cleared. 5. On resume ieee80211_reconfig will call drv_resume since local->wowlan is set. Signed-off-by: Pontus Fuchs Signed-off-by: John W. Linville --- net/mac80211/pm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index af1c4e26e965..98c128be3827 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -77,6 +77,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) int err = drv_suspend(local, wowlan); if (err < 0) { local->quiescing = false; + local->wowlan = false; return err; } else if (err > 0) { WARN_ON(err != 1); -- GitLab From ccaf8c32d5ed08bfb4c45492f8f1c145fd45f4e8 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 31 May 2012 22:38:22 +0200 Subject: [PATCH 0803/6849] ssb: recognize ARM Cortex M3 I found this core on a BCM4322, a PCI card in the Linksys WRT610N V1. This core is not used by the driver, this patch just makes ssb show the correct name. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/ssb/scan.c | 2 ++ include/linux/ssb/ssb.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 266c7c5c86dc..ab4627cf1114 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -90,6 +90,8 @@ const char *ssb_core_name(u16 coreid) return "ARM 1176"; case SSB_DEV_ARM_7TDMI: return "ARM 7TDMI"; + case SSB_DEV_ARM_CM3: + return "ARM Cortex M3"; } return "UNKNOWN"; } diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index bc14bd738ade..bb674c02f306 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -243,6 +243,7 @@ struct ssb_bus_ops { #define SSB_DEV_MINI_MACPHY 0x823 #define SSB_DEV_ARM_1176 0x824 #define SSB_DEV_ARM_7TDMI 0x825 +#define SSB_DEV_ARM_CM3 0x82A /* Vendor-ID values */ #define SSB_VENDOR_BROADCOM 0x4243 -- GitLab From ebf348fcd088e3ffc6e76f6f349e27d30604865b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Jun 2012 12:50:54 +0200 Subject: [PATCH 0804/6849] cfg80211: validate remain-on-channel time better The remain-on-channel time validation shouldn't depend on the value of HZ, as it does now with the check against jiffies, since then you might use a value that works on one system but not on another. Fix it by checking against a minimum that's fixed. Also add validation of the wait duration for a management frame TX since this also translates into remain-on-channel internally. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ net/wireless/nl80211.c | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 85e5037a218d..970afdf5a605 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1522,6 +1522,8 @@ enum nl80211_attrs { #define NL80211_MAX_NR_CIPHER_SUITES 5 #define NL80211_MAX_NR_AKM_SUITES 2 +#define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10 + /** * enum nl80211_iftype - (virtual) interface types * diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5e29bd38e7df..7ae54b82291f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5545,18 +5545,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); + if (!rdev->ops->remain_on_channel || + !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)) + return -EOPNOTSUPP; + /* - * We should be on that channel for at least one jiffie, - * and more than 5 seconds seems excessive. + * We should be on that channel for at least a minimum amount of + * time (10ms) but no longer than the driver supports. */ - if (!duration || !msecs_to_jiffies(duration) || + if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || duration > rdev->wiphy.max_remain_on_channel_duration) return -EINVAL; - if (!rdev->ops->remain_on_channel || - !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)) - return -EOPNOTSUPP; - if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && !nl80211_valid_channel_type(info, &channel_type)) return -EINVAL; @@ -5827,6 +5827,15 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) return -EINVAL; wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); + + /* + * We should wait on the channel for at least a minimum amount + * of time (10ms) but no longer than the driver supports. + */ + if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || + wait > rdev->wiphy.max_remain_on_channel_duration) + return -EINVAL; + } if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { -- GitLab From 2b0446c4205fb3e77b205276ecd36d30b82cbb84 Mon Sep 17 00:00:00 2001 From: Chris Yungmann Date: Sun, 3 Jun 2012 00:57:57 -0500 Subject: [PATCH 0805/6849] brcm80211: brcmsmac: fixed checkpatch and sparse warnings Fixed checkpatch and sparse warnings related to aiutils.* Signed-off-by: Chris Yungmann Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | 3 +-- drivers/net/wireless/brcm80211/brcmsmac/aiutils.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index 6d8b7213643a..3c6f9b1e8d05 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -631,9 +631,8 @@ uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val) cc = sii->icbus->drv_cc.core; /* mask and set */ - if (mask || val) { + if (mask || val) bcma_maskset32(cc, regoff, ~mask, val); - } /* readback */ w = bcma_read32(cc, regoff); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index d9f04a683bdb..d6fa9829af9a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h @@ -193,7 +193,7 @@ extern void ai_detach(struct si_pub *sih); extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); extern void ai_clkctl_init(struct si_pub *sih); extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); -extern bool ai_clkctl_cc(struct si_pub *sih, uint mode); +extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode); extern bool ai_deviceremoved(struct si_pub *sih); extern void ai_pci_down(struct si_pub *sih); -- GitLab From 2e8d397eeeb1f5bd932d20d6abc020afe7e63b0b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 3 Jun 2012 23:31:56 +0300 Subject: [PATCH 0806/6849] mac80211: add stations after AP start on reconfig When performing a HW restart for an AP mode interface, add stations back only after the AP is beaconing. This mimics the normal flow of STA addition on AP. Some devices (wlcore) do not support adding stations before beaconing, so this has the added benefit of making recovery work for them. Signed-off-by: Arik Nemtsov Signed-off-by: John W. Linville --- net/mac80211/util.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b007c6861032..1df4019f294b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1279,14 +1279,19 @@ int ieee80211_reconfig(struct ieee80211_local *local) /* add STAs back */ mutex_lock(&local->sta_mtx); list_for_each_entry(sta, &local->sta_list, list) { - if (sta->uploaded) { - enum ieee80211_sta_state state; + enum ieee80211_sta_state state; - for (state = IEEE80211_STA_NOTEXIST; - state < sta->sta_state; state++) - WARN_ON(drv_sta_state(local, sta->sdata, sta, - state, state + 1)); - } + if (!sta->uploaded) + continue; + + /* AP-mode stations will be added later */ + if (sta->sdata->vif.type == NL80211_IFTYPE_AP) + continue; + + for (state = IEEE80211_STA_NOTEXIST; + state < sta->sta_state; state++) + WARN_ON(drv_sta_state(local, sta->sdata, sta, state, + state + 1)); } mutex_unlock(&local->sta_mtx); @@ -1383,6 +1388,24 @@ int ieee80211_reconfig(struct ieee80211_local *local) } } + /* APs are now beaconing, add back stations */ + mutex_lock(&local->sta_mtx); + list_for_each_entry(sta, &local->sta_list, list) { + enum ieee80211_sta_state state; + + if (!sta->uploaded) + continue; + + if (sta->sdata->vif.type != NL80211_IFTYPE_AP) + continue; + + for (state = IEEE80211_STA_NOTEXIST; + state < sta->sta_state; state++) + WARN_ON(drv_sta_state(local, sta->sdata, sta, state, + state + 1)); + } + mutex_unlock(&local->sta_mtx); + /* add back keys */ list_for_each_entry(sdata, &local->interfaces, list) if (ieee80211_sdata_running(sdata)) -- GitLab From aaa1ec46b3be258b851477024fb41e140b14d1a6 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:08 +0530 Subject: [PATCH 0807/6849] ath9k: Prune ath9k_init_device Instead of cluttering ath9k_init_device() with 'ath_softc' specific initialization code, use ath9k_init_softc() to setup driver-specific work routines, timers etc. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index dee9e092449a..3e2283970ee3 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -489,6 +489,7 @@ static void ath9k_init_misc(struct ath_softc *sc) setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); + sc->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->config.txpowlimit = ATH_TXPOWER_MAX; memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); sc->beacon.slottime = ATH9K_SLOT_TIME_9; @@ -560,6 +561,12 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, (unsigned long)sc); + INIT_WORK(&sc->hw_reset_work, ath_reset_work); + INIT_WORK(&sc->hw_check_work, ath_hw_check); + INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); + INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); + setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); + /* * Cache line size is used to size and align various * structures used to communicate with the hardware. @@ -782,11 +789,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, ARRAY_SIZE(ath9k_tpt_blink)); #endif - INIT_WORK(&sc->hw_reset_work, ath_reset_work); - INIT_WORK(&sc->hw_check_work, ath_hw_check); - INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); - /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) @@ -805,9 +807,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, goto error_world; } - setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); - sc->last_rssi = ATH_RSSI_DUMMY_MARKER; - ath_init_leds(sc); ath_start_rfkill_poll(sc); -- GitLab From d09f5f4cfb9f4c6aa8c18ea522e824660d4096d7 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:14 +0530 Subject: [PATCH 0808/6849] ath9k: Handle ASPM properly ASPM has to be disabled when BTCOEX is in use, do this properly by calling the bus-specific ASPM init routine after the BTCOEX scheme has been determined. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 11 ----------- drivers/net/wireless/ath/ath9k/init.c | 3 +++ drivers/net/wireless/ath/ath9k/pci.c | 5 +++++ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7db1890448f2..febf6971b40a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -390,14 +390,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); } -static void ath9k_hw_aspm_init(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - - if (common->bus_ops->aspm_init) - common->bus_ops->aspm_init(common); -} - /* This should work for all families including legacy */ static bool ath9k_hw_chip_test(struct ath_hw *ah) { @@ -693,9 +685,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (r) return r; - if (ah->is_pciexpress) - ath9k_hw_aspm_init(ah); - r = ath9k_hw_init_macaddr(ah); if (r) { ath_err(common, "Failed to initialize MAC address\n"); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 3e2283970ee3..9dfce1a69c73 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -597,6 +597,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ath9k_cmn_init_crypto(sc->sc_ah); ath9k_init_misc(sc); + if (common->bus_ops->aspm_init) + common->bus_ops->aspm_init(common); + return 0; err_btcoex: diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index a856b51255f4..6ec9f88712d0 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -115,6 +115,9 @@ static void ath_pci_aspm_init(struct ath_common *common) int pos; u8 aspm; + if (!ah->is_pciexpress) + return; + pos = pci_pcie_cap(pdev); if (!pos) return; @@ -138,6 +141,7 @@ static void ath_pci_aspm_init(struct ath_common *common) aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); + ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); return; } @@ -147,6 +151,7 @@ static void ath_pci_aspm_init(struct ath_common *common) ah->aspm_enabled = true; /* Initialize PCIe PM and SERDES registers. */ ath9k_hw_configpcipowersave(ah, false); + ath_info(common, "ASPM enabled: 0x%x\n", aspm); } } -- GitLab From e270e776a0985511146555e79edbe53539809adb Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:19 +0530 Subject: [PATCH 0809/6849] ath9k: Setup MCI interrupts properly MCI interrupts have to be enabled only when BTCOEX is actually in use. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 +-- drivers/net/wireless/ath/ath9k/mci.c | 11 +++++++++++ drivers/net/wireless/ath/ath9k/mci.h | 11 ++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index cfbcc047c61e..3809fc8ec8a4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1045,8 +1045,7 @@ static int ath9k_start(struct ieee80211_hw *hw) if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) ah->imask |= ATH9K_INT_CST; - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) - ah->imask |= ATH9K_INT_MCI; + ath_mci_enable(sc); sc->sc_flags &= ~SC_OP_INVALID; sc->sc_ah->is_monitoring = false; diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 29fe52d69973..7b553f6a97b1 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -538,3 +538,14 @@ void ath_mci_intr(struct ath_softc *sc) mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); } + +void ath_mci_enable(struct ath_softc *sc) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + if (!common->btcoex_enabled) + return; + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) + sc->sc_ah->imask |= ATH9K_INT_MCI; +} diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h index c841444f53c2..fc14eea034eb 100644 --- a/drivers/net/wireless/ath/ath9k/mci.h +++ b/drivers/net/wireless/ath/ath9k/mci.h @@ -130,4 +130,13 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci); int ath_mci_setup(struct ath_softc *sc); void ath_mci_cleanup(struct ath_softc *sc); void ath_mci_intr(struct ath_softc *sc); -#endif + +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT +void ath_mci_enable(struct ath_softc *sc); +#else +static inline void ath_mci_enable(struct ath_softc *sc) +{ +} +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ + +#endif /* MCI_H*/ -- GitLab From 83c7a52dcce256fc20cd43dbf6866e3e05f2bf71 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:25 +0530 Subject: [PATCH 0810/6849] ath9k_hw: Fix AR_RTC_KEEP_AWAKE usage The default value that is being programmed to AR_RTC_KEEP_AWAKE is 0x2, there is no need to program it manually in various functions. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 1 - drivers/net/wireless/ath/ath9k/hw.c | 11 ----------- 2 files changed, 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index ffbb180f91e1..9331d73f69aa 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -330,7 +330,6 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah) } mci->ready = false; - REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); } static void ar9003_mci_disable_interrupt(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index febf6971b40a..42cf3c8db95b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1432,9 +1432,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) break; } - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) - REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); - return ret; } @@ -2167,10 +2164,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) switch (mode) { case ATH9K_PM_AWAKE: status = ath9k_hw_set_power_awake(ah, setChip); - - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) - REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); - break; case ATH9K_PM_FULL_SLEEP: if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) @@ -2180,10 +2173,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) ah->chip_fullsleep = true; break; case ATH9K_PM_NETWORK_SLEEP: - - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) - REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); - ath9k_set_power_network_sleep(ah, setChip); break; default: -- GitLab From 5955b2b0ef208e03188ef1c2810c004bde493253 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:30 +0530 Subject: [PATCH 0811/6849] ath9k_hw: Fix MCI usage MCI has to be handled only when BTCOEX is actually enabled. Check for this condition before calling MCI related functions from various reset/calibration call-sites. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 5 ++--- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 8 -------- drivers/net/wireless/ath/ath9k/hw.c | 15 +++++++-------- drivers/net/wireless/ath/ath9k/hw.h | 9 +++++++++ 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 9fdd70fcaf5b..f83a4a2e1da2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -901,7 +901,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, bool is_reusable = true, status = true; bool run_rtt_cal = false, run_agc_cal; bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); - bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | AR_PHY_AGC_CONTROL_FLTR_CAL | AR_PHY_AGC_CONTROL_PKDET_CAL; @@ -970,7 +969,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, } else if (caldata && !caldata->done_txiqcal_once) run_agc_cal = true; - if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) + if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) ar9003_mci_init_cal_req(ah, &is_reusable); if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) { @@ -993,7 +992,7 @@ skip_tx_iqcal: 0, AH_WAIT_TIMEOUT); } - if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) + if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) ar9003_mci_init_cal_done(ah); if (rtt && !run_rtt_cal) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 4842f6c06b8c..652ab8c39e2b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -273,10 +273,6 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT -static inline bool ar9003_mci_is_ready(struct ath_hw *ah) -{ - return ah->btcoex_hw.mci.ready; -} void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); void ar9003_mci_init_cal_done(struct ath_hw *ah); @@ -292,10 +288,6 @@ void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); #else -static inline bool ar9003_mci_is_ready(struct ath_hw *ah) -{ - return false; -} static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) { } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 42cf3c8db95b..a7231cadec40 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1707,7 +1707,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah, true); - if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) + if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_2g5g_switch(ah, true); if (AR_SREV_9271(ah)) @@ -1728,10 +1728,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, u64 tsf = 0; int i, r; bool start_mci_reset = false; - bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); bool save_fullsleep = ah->chip_fullsleep; - if (mci) { + if (ath9k_hw_mci_is_enabled(ah)) { start_mci_reset = ar9003_mci_start_reset(ah, chan); if (start_mci_reset) return 0; @@ -1760,7 +1759,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, return r; } - if (mci) + if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_stop_bt(ah, save_fullsleep); saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); @@ -1818,7 +1817,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (r) return r; - if (mci) + if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); /* @@ -1937,7 +1936,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_loadnf(ah, chan); ath9k_hw_start_nfcal(ah, true); - if (mci && ar9003_mci_end_reset(ah, chan, caldata)) + if (ath9k_hw_mci_is_enabled(ah) && ar9003_mci_end_reset(ah, chan, caldata)) return -EIO; ENABLE_REGWRITE_BUFFER(ah); @@ -1982,7 +1981,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (ath9k_hw_btcoex_is_enabled(ah)) ath9k_hw_btcoex_enable(ah); - if (mci) + if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_check_bt(ah); if (AR_SREV_9300_20_OR_LATER(ah)) { @@ -2166,7 +2165,7 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) status = ath9k_hw_set_power_awake(ah, setChip); break; case ATH9K_PM_FULL_SLEEP: - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) + if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_set_full_sleep(ah); ath9k_set_power_sleep(ah, setChip); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b620c557c2a6..3740aab864f4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1037,6 +1037,11 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) { return ah->btcoex_hw.enabled; } +static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) +{ + return ah->btcoex_hw.enabled && (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); + +} void ath9k_hw_btcoex_enable(struct ath_hw *ah); static inline enum ath_btcoex_scheme ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) @@ -1048,6 +1053,10 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) { return false; } +static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) +{ + return false; +} static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah) { } -- GitLab From 31604cf0a73ffd63929f3a646d5402d5901c6e4b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:36 +0530 Subject: [PATCH 0812/6849] ath9k_hw: Cleanup power mode API The 'setChip' variable is unused, remove it and simplify the functions. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 175 ++++++++++++++-------------- 1 file changed, 85 insertions(+), 90 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a7231cadec40..9f0f5f74f17a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2004,39 +2004,38 @@ EXPORT_SYMBOL(ath9k_hw_reset); * Notify Power Mgt is disabled in self-generated frames. * If requested, force chip to sleep. */ -static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) +static void ath9k_set_power_sleep(struct ath_hw *ah) { REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); - if (setChip) { - if (AR_SREV_9462(ah)) { - REG_WRITE(ah, AR_TIMER_MODE, - REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); - REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah, - AR_NDP2_TIMER_MODE) & 0xFFFFFF00); - REG_WRITE(ah, AR_SLP32_INC, - REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); - /* xxx Required for WLAN only case ? */ - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); - udelay(100); - } - /* - * Clear the RTC force wake bit to allow the - * mac to go to sleep. - */ - REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); + if (AR_SREV_9462(ah)) { + REG_WRITE(ah, AR_TIMER_MODE, + REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); + REG_WRITE(ah, AR_NDP2_TIMER_MODE, + REG_READ(ah, AR_NDP2_TIMER_MODE) & 0xFFFFFF00); + REG_WRITE(ah, AR_SLP32_INC, + REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); + /* xxx Required for WLAN only case ? */ + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); + udelay(100); + } - if (AR_SREV_9462(ah)) - udelay(100); + /* + * Clear the RTC force wake bit to allow the + * mac to go to sleep. + */ + REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); - if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) - REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); + if (AR_SREV_9462(ah)) + udelay(100); - /* Shutdown chip. Active low */ - if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { - REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); - udelay(2); - } + if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) + REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); + + /* Shutdown chip. Active low */ + if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { + REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); + udelay(2); } /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ @@ -2049,44 +2048,42 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) * frames. If request, set power mode of chip to * auto/normal. Duration in units of 128us (1/8 TU). */ -static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) +static void ath9k_set_power_network_sleep(struct ath_hw *ah) { + struct ath9k_hw_capabilities *pCap = &ah->caps; u32 val; REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); - if (setChip) { - struct ath9k_hw_capabilities *pCap = &ah->caps; - if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { - /* Set WakeOnInterrupt bit; clear ForceWake bit */ - REG_WRITE(ah, AR_RTC_FORCE_WAKE, - AR_RTC_FORCE_WAKE_ON_INT); - } else { + if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { + /* Set WakeOnInterrupt bit; clear ForceWake bit */ + REG_WRITE(ah, AR_RTC_FORCE_WAKE, + AR_RTC_FORCE_WAKE_ON_INT); + } else { - /* When chip goes into network sleep, it could be waken - * up by MCI_INT interrupt caused by BT's HW messages - * (LNA_xxx, CONT_xxx) which chould be in a very fast - * rate (~100us). This will cause chip to leave and - * re-enter network sleep mode frequently, which in - * consequence will have WLAN MCI HW to generate lots of - * SYS_WAKING and SYS_SLEEPING messages which will make - * BT CPU to busy to process. - */ - if (AR_SREV_9462(ah)) { - val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & - ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); - } - /* - * Clear the RTC force wake bit to allow the - * mac to go to sleep. - */ - REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, - AR_RTC_FORCE_WAKE_EN); - - if (AR_SREV_9462(ah)) - udelay(30); + /* When chip goes into network sleep, it could be waken + * up by MCI_INT interrupt caused by BT's HW messages + * (LNA_xxx, CONT_xxx) which chould be in a very fast + * rate (~100us). This will cause chip to leave and + * re-enter network sleep mode frequently, which in + * consequence will have WLAN MCI HW to generate lots of + * SYS_WAKING and SYS_SLEEPING messages which will make + * BT CPU to busy to process. + */ + if (AR_SREV_9462(ah)) { + val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & + ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); } + /* + * Clear the RTC force wake bit to allow the + * mac to go to sleep. + */ + REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, + AR_RTC_FORCE_WAKE_EN); + + if (AR_SREV_9462(ah)) + udelay(30); } /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ @@ -2094,7 +2091,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); } -static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) +static bool ath9k_hw_set_power_awake(struct ath_hw *ah) { u32 val; int i; @@ -2105,37 +2102,35 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) udelay(10); } - if (setChip) { - if ((REG_READ(ah, AR_RTC_STATUS) & - AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { - if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { - return false; - } - if (!AR_SREV_9300_20_OR_LATER(ah)) - ath9k_hw_init_pll(ah, NULL); + if ((REG_READ(ah, AR_RTC_STATUS) & + AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { + return false; } - if (AR_SREV_9100(ah)) - REG_SET_BIT(ah, AR_RTC_RESET, - AR_RTC_RESET_EN); + if (!AR_SREV_9300_20_OR_LATER(ah)) + ath9k_hw_init_pll(ah, NULL); + } + if (AR_SREV_9100(ah)) + REG_SET_BIT(ah, AR_RTC_RESET, + AR_RTC_RESET_EN); + REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, + AR_RTC_FORCE_WAKE_EN); + udelay(50); + + for (i = POWER_UP_TIME / 50; i > 0; i--) { + val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; + if (val == AR_RTC_STATUS_ON) + break; + udelay(50); REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); - udelay(50); - - for (i = POWER_UP_TIME / 50; i > 0; i--) { - val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; - if (val == AR_RTC_STATUS_ON) - break; - udelay(50); - REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, - AR_RTC_FORCE_WAKE_EN); - } - if (i == 0) { - ath_err(ath9k_hw_common(ah), - "Failed to wakeup in %uus\n", - POWER_UP_TIME / 20); - return false; - } + } + if (i == 0) { + ath_err(ath9k_hw_common(ah), + "Failed to wakeup in %uus\n", + POWER_UP_TIME / 20); + return false; } REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); @@ -2146,7 +2141,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) { struct ath_common *common = ath9k_hw_common(ah); - int status = true, setChip = true; + int status = true; static const char *modes[] = { "AWAKE", "FULL-SLEEP", @@ -2162,17 +2157,17 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) switch (mode) { case ATH9K_PM_AWAKE: - status = ath9k_hw_set_power_awake(ah, setChip); + status = ath9k_hw_set_power_awake(ah); break; case ATH9K_PM_FULL_SLEEP: if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_set_full_sleep(ah); - ath9k_set_power_sleep(ah, setChip); + ath9k_set_power_sleep(ah); ah->chip_fullsleep = true; break; case ATH9K_PM_NETWORK_SLEEP: - ath9k_set_power_network_sleep(ah, setChip); + ath9k_set_power_network_sleep(ah); break; default: ath_err(common, "Unknown power mode %u\n", mode); -- GitLab From 97ba515a201bc61c7d36c41ad728b0a7debd5d88 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:41 +0530 Subject: [PATCH 0813/6849] ath9k: Add MCI interrupt to debugfs statistics Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 3 +++ drivers/net/wireless/ath/ath9k/debug.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index fde700c4e490..c134ddaa10a1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -374,6 +374,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) sc->debug.stats.istats.dtim++; if (status & ATH9K_INT_TSFOOR) sc->debug.stats.istats.tsfoor++; + if (status & ATH9K_INT_MCI) + sc->debug.stats.istats.mci++; } static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, @@ -418,6 +420,7 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, PR_IS("DTIMSYNC", dtimsync); PR_IS("DTIM", dtim); PR_IS("TSFOOR", tsfoor); + PR_IS("MCI", mci); PR_IS("TOTAL", total); len += snprintf(buf + len, mxlen - len, diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index c34da09d9103..d0f851cea43a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -86,6 +86,7 @@ struct ath_interrupt_stats { u32 dtim; u32 bb_watchdog; u32 tsfoor; + u32 mci; /* Sync-cause stats */ u32 sync_cause_all; -- GitLab From 2fd5d35bc87a301d5c10397c5b38a4ec8532a975 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:47 +0530 Subject: [PATCH 0814/6849] ath9k_hw: Fix variable usage Exposed by sparse: ar9003_mci.c:1134:31: warning: Using plain integer as NULL pointer Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 9331d73f69aa..b501bf143437 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1131,7 +1131,7 @@ void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable) if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) { ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n"); } else { - is_reusable = false; + *is_reusable = false; ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n"); } } -- GitLab From 4cb54fa3a2456e66d8e3bae663d66f00cbb9e483 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:52 +0530 Subject: [PATCH 0815/6849] ath9k: Remove SC_OP_OFFCHANNEL mac80211's IEEE80211_CONF_OFFCHANNEL can be used directly to track offchannel state. Also pass the correct boolean value to ath9k_hw_startpcureceive(). Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 13 ++++++------- drivers/net/wireless/ath/ath9k/main.c | 11 +++-------- drivers/net/wireless/ath/ath9k/recv.c | 4 ++-- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a277cf6f339d..e204648a84fe 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -586,13 +586,12 @@ struct ath_ant_comb { #define SC_OP_INVALID BIT(0) #define SC_OP_BEACONS BIT(1) -#define SC_OP_OFFCHANNEL BIT(2) -#define SC_OP_RXFLUSH BIT(3) -#define SC_OP_TSF_RESET BIT(4) -#define SC_OP_BT_PRIORITY_DETECTED BIT(5) -#define SC_OP_BT_SCAN BIT(6) -#define SC_OP_ANI_RUN BIT(7) -#define SC_OP_PRIM_STA_VIF BIT(8) +#define SC_OP_RXFLUSH BIT(2) +#define SC_OP_TSF_RESET BIT(3) +#define SC_OP_BT_PRIORITY_DETECTED BIT(4) +#define SC_OP_BT_SCAN BIT(5) +#define SC_OP_ANI_RUN BIT(6) +#define SC_OP_PRIM_STA_VIF BIT(7) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3809fc8ec8a4..d739c8e6a012 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -152,7 +152,7 @@ void ath_start_ani(struct ath_common *common) if (!(sc->sc_flags & SC_OP_ANI_RUN)) return; - if (sc->sc_flags & SC_OP_OFFCHANNEL) + if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) return; common->ani.longcal_timer = timestamp; @@ -282,7 +282,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath9k_hw_set_interrupts(ah); ath9k_hw_enable_interrupts(ah); - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { + if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { if (sc->sc_flags & SC_OP_BEACONS) ath_set_beacon(sc); @@ -328,7 +328,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, spin_lock_bh(&sc->sc_pcu_lock); - if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) { + if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { fastcc = false; caldata = &sc->caldata; } @@ -1626,11 +1626,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (ah->curchan) old_pos = ah->curchan - &ah->channels[0]; - if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) - sc->sc_flags |= SC_OP_OFFCHANNEL; - else - sc->sc_flags &= ~SC_OP_OFFCHANNEL; - ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", curchan->center_freq, conf->channel_type); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index e1fcc68124dc..18acdbcbb03f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -303,7 +303,7 @@ static void ath_edma_start_recv(struct ath_softc *sc) ath_opmode_init(sc); - ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); + ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); spin_unlock_bh(&sc->rx.rxbuflock); } @@ -500,7 +500,7 @@ int ath_startrecv(struct ath_softc *sc) start_recv: ath_opmode_init(sc); - ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); + ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); spin_unlock_bh(&sc->rx.rxbuflock); -- GitLab From e6930c4b32aaa30fb9510984509afcc9f61fa39c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 16:27:58 +0530 Subject: [PATCH 0816/6849] ath9k: Use separate operational flags for BTCOEX Also, use atomic operations to check the flags. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 12 ++++++++---- drivers/net/wireless/ath/ath9k/gpio.c | 23 ++++++++++++----------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index e204648a84fe..ee946b8fe00c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -441,12 +441,18 @@ void ath_start_ani(struct ath_common *common); /* BTCOEX */ /**********/ +enum bt_op_flags { + BT_OP_PRIORITY_DETECTED, + BT_OP_SCAN, +}; + struct ath_btcoex { bool hw_timer_enabled; spinlock_t btcoex_lock; struct timer_list period_timer; /* Timer for BT period */ u32 bt_priority_cnt; unsigned long bt_priority_time; + unsigned long op_flags; int bt_stomp_type; /* Types of BT stomping */ u32 btcoex_no_stomp; /* in usec */ u32 btcoex_period; /* in usec */ @@ -588,10 +594,8 @@ struct ath_ant_comb { #define SC_OP_BEACONS BIT(1) #define SC_OP_RXFLUSH BIT(2) #define SC_OP_TSF_RESET BIT(3) -#define SC_OP_BT_PRIORITY_DETECTED BIT(4) -#define SC_OP_BT_SCAN BIT(5) -#define SC_OP_ANI_RUN BIT(6) -#define SC_OP_PRIM_STA_VIF BIT(7) +#define SC_OP_ANI_RUN BIT(4) +#define SC_OP_PRIM_STA_VIF BIT(5) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 281a9af0f1b6..9397a6d2ed5d 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -132,17 +132,18 @@ static void ath_detect_bt_priority(struct ath_softc *sc) if (time_after(jiffies, btcoex->bt_priority_time + msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { - sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); + clear_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); + clear_bit(BT_OP_SCAN, &btcoex->op_flags); /* Detect if colocated bt started scanning */ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, "BT scan detected\n"); - sc->sc_flags |= (SC_OP_BT_SCAN | - SC_OP_BT_PRIORITY_DETECTED); + set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); + set_bit(BT_OP_SCAN, &btcoex->op_flags); } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, "BT priority traffic detected\n"); - sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; + set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); } btcoex->bt_priority_cnt = 0; @@ -196,7 +197,7 @@ static void ath_btcoex_period_timer(unsigned long data) ath9k_ps_wakeup(sc); if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) ath_detect_bt_priority(sc); - is_btscan = sc->sc_flags & SC_OP_BT_SCAN; + is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); spin_lock_bh(&btcoex->btcoex_lock); @@ -219,8 +220,7 @@ static void ath_btcoex_period_timer(unsigned long data) ath9k_ps_restore(sc); timer_period = btcoex->btcoex_period / 1000; - mod_timer(&btcoex->period_timer, jiffies + - msecs_to_jiffies(timer_period)); + mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); } /* @@ -233,14 +233,14 @@ static void ath_btcoex_no_stomp_timer(void *arg) struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; struct ath_common *common = ath9k_hw_common(ah); - bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; ath_dbg(common, BTCOEX, "no stomp timer running\n"); ath9k_ps_wakeup(sc); spin_lock_bh(&btcoex->btcoex_lock); - if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) + if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || + test_bit(BT_OP_SCAN, &btcoex->op_flags)) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); @@ -292,7 +292,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) btcoex->bt_priority_cnt = 0; btcoex->bt_priority_time = jiffies; - sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); + btcoex->op_flags &= ~(BT_OP_PRIORITY_DETECTED | BT_OP_SCAN); mod_timer(&btcoex->period_timer, jiffies); } @@ -316,12 +316,13 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) { + struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &sc->btcoex.mci; u16 aggr_limit = 0; if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; - else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) + else if (test_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags)) aggr_limit = min((max_4ms_framelen * 3) / 8, (u32)ATH_AMPDU_LIMIT_MAX); -- GitLab From 5d294a168012ec9a5258efae0a1282e94691a5d4 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:03 +0530 Subject: [PATCH 0817/6849] ath9k_hw: update ar9462 initval table to fix rx The wrong ADC sample phase that happen between awake and network/full sleep will lead to improper rx noisefloor calibration. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1d6658e139b5..a10ece0cb6cd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -958,7 +958,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { {0x0001604c, 0x2699e04f}, {0x00016050, 0x6db6db6c}, {0x00016058, 0x6c200000}, - {0x00016080, 0x00040000}, + {0x00016080, 0x000c0000}, {0x00016084, 0x9a68048c}, {0x00016088, 0x54214514}, {0x0001608c, 0x1203040b}, @@ -981,7 +981,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { {0x00016144, 0x02084080}, {0x00016148, 0x000080c0}, {0x00016280, 0x050a0001}, - {0x00016284, 0x3d841400}, + {0x00016284, 0x3d841418}, {0x00016288, 0x00000000}, {0x0001628c, 0xe3000000}, {0x00016290, 0xa1005080}, -- GitLab From 4f6bd1a8dfcc649912310777a44c49849ae2a63d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:08 +0530 Subject: [PATCH 0818/6849] ath9k: cleanup MCI indentation Fix bad indentation & if nesting to lose about two levels of unnecessary indentation. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 435 ++++++++++---------- 1 file changed, 215 insertions(+), 220 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index b501bf143437..854dff66a63f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -35,31 +35,30 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address, struct ath_common *common = ath9k_hw_common(ah); while (time_out) { - if (REG_READ(ah, address) & bit_position) { - REG_WRITE(ah, address, bit_position); - - if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) { - if (bit_position & - AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) - ar9003_mci_reset_req_wakeup(ah); - - if (bit_position & - (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | - AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) - REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, - AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); - - REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, - AR_MCI_INTERRUPT_RX_MSG); - } - break; - } + if (!(REG_READ(ah, address) & bit_position)) { + udelay(10); + time_out -= 10; - udelay(10); - time_out -= 10; + if (time_out < 0) + break; + else + continue; + } + REG_WRITE(ah, address, bit_position); - if (time_out < 0) + if (address != AR_MCI_INTERRUPT_RX_MSG_RAW) break; + + if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) + ar9003_mci_reset_req_wakeup(ah); + + if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | + AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) + REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, + AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); + + REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG); + break; } if (time_out <= 0) { @@ -127,14 +126,13 @@ static void ar9003_mci_send_coex_version_query(struct ath_hw *ah, struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; - if (!mci->bt_version_known && - (mci->bt_state != MCI_BT_SLEEP)) { - MCI_GPM_SET_TYPE_OPCODE(payload, - MCI_GPM_COEX_AGENT, - MCI_GPM_COEX_VERSION_QUERY); - ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, - wait_done, true); - } + if (mci->bt_version_known || + (mci->bt_state == MCI_BT_SLEEP)) + return; + + MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_VERSION_QUERY); + ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); } static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, @@ -158,15 +156,14 @@ static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah, struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 *payload = &mci->wlan_channels[0]; - if ((mci->wlan_channels_update == true) && - (mci->bt_state != MCI_BT_SLEEP)) { - MCI_GPM_SET_TYPE_OPCODE(payload, - MCI_GPM_COEX_AGENT, - MCI_GPM_COEX_WLAN_CHANNELS); - ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, - wait_done, true); - MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); - } + if (!mci->wlan_channels_update || + (mci->bt_state == MCI_BT_SLEEP)) + return; + + MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_WLAN_CHANNELS); + ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); + MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); } static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, @@ -174,29 +171,30 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; - bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | - MCI_GPM_COEX_QUERY_BT_TOPOLOGY)); + bool query_btinfo; - if (mci->bt_state != MCI_BT_SLEEP) { - - MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, - MCI_GPM_COEX_STATUS_QUERY); + if (mci->bt_state == MCI_BT_SLEEP) + return; - *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; + query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | + MCI_GPM_COEX_QUERY_BT_TOPOLOGY)); + MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_STATUS_QUERY); - /* - * If bt_status_query message is not sent successfully, - * then need_flush_btinfo should be set again. - */ - if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, - wait_done, true)) { - if (query_btinfo) - mci->need_flush_btinfo = true; - } + *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; + /* + * If bt_status_query message is not sent successfully, + * then need_flush_btinfo should be set again. + */ + if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, + wait_done, true)) { if (query_btinfo) - mci->query_bt = false; + mci->need_flush_btinfo = true; } + + if (query_btinfo) + mci->query_bt = false; } static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, @@ -241,73 +239,73 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) ar9003_mci_remote_reset(ah, true); ar9003_mci_send_req_wake(ah, true); - if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { + if (!ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) + goto clear_redunt; - mci->bt_state = MCI_BT_AWAKE; + mci->bt_state = MCI_BT_AWAKE; - /* - * we don't need to send more remote_reset at this moment. - * If BT receive first remote_reset, then BT HW will - * be cleaned up and will be able to receive req_wake - * and BT HW will respond sys_waking. - * In this case, WLAN will receive BT's HW sys_waking. - * Otherwise, if BT SW missed initial remote_reset, - * that remote_reset will still clean up BT MCI RX, - * and the req_wake will wake BT up, - * and BT SW will respond this req_wake with a remote_reset and - * sys_waking. In this case, WLAN will receive BT's SW - * sys_waking. In either case, BT's RX is cleaned up. So we - * don't need to reply BT's remote_reset now, if any. - * Similarly, if in any case, WLAN can receive BT's sys_waking, - * that means WLAN's RX is also fine. - */ - ar9003_mci_send_sys_waking(ah, true); - udelay(10); + /* + * we don't need to send more remote_reset at this moment. + * If BT receive first remote_reset, then BT HW will + * be cleaned up and will be able to receive req_wake + * and BT HW will respond sys_waking. + * In this case, WLAN will receive BT's HW sys_waking. + * Otherwise, if BT SW missed initial remote_reset, + * that remote_reset will still clean up BT MCI RX, + * and the req_wake will wake BT up, + * and BT SW will respond this req_wake with a remote_reset and + * sys_waking. In this case, WLAN will receive BT's SW + * sys_waking. In either case, BT's RX is cleaned up. So we + * don't need to reply BT's remote_reset now, if any. + * Similarly, if in any case, WLAN can receive BT's sys_waking, + * that means WLAN's RX is also fine. + */ + ar9003_mci_send_sys_waking(ah, true); + udelay(10); - /* - * Set BT priority interrupt value to be 0xff to - * avoid having too many BT PRIORITY interrupts. - */ - REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); - REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); - REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); - REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); - REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); + /* + * Set BT priority interrupt value to be 0xff to + * avoid having too many BT PRIORITY interrupts. + */ + REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); + REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); + REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); + REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); + REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); - /* - * A contention reset will be received after send out - * sys_waking. Also BT priority interrupt bits will be set. - * Clear those bits before the next step. - */ + /* + * A contention reset will be received after send out + * sys_waking. Also BT priority interrupt bits will be set. + * Clear those bits before the next step. + */ - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_CONT_RST); - REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, - AR_MCI_INTERRUPT_BT_PRI); + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_CONT_RST); + REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); - if (mci->is_2g) { - ar9003_mci_send_lna_transfer(ah, true); - udelay(5); - } + if (mci->is_2g) { + ar9003_mci_send_lna_transfer(ah, true); + udelay(5); + } - if ((mci->is_2g && !mci->update_2g5g)) { - if (ar9003_mci_wait_for_interrupt(ah, - AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, - mci_timeout)) - ath_dbg(common, MCI, - "MCI WLAN has control over the LNA & BT obeys it\n"); - else - ath_dbg(common, MCI, - "MCI BT didn't respond to LNA_TRANS\n"); - } + if ((mci->is_2g && !mci->update_2g5g)) { + if (ar9003_mci_wait_for_interrupt(ah, + AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, + mci_timeout)) + ath_dbg(common, MCI, + "MCI WLAN has control over the LNA & BT obeys it\n"); + else + ath_dbg(common, MCI, + "MCI BT didn't respond to LNA_TRANS\n"); } +clear_redunt: /* Clear the extra redundant SYS_WAKING from BT */ if ((mci->bt_state == MCI_BT_AWAKE) && - (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && + (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, @@ -614,9 +612,9 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, } break; } - } else if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) { + } else if ((recv_type == gpm_type) && + (recv_opcode == gpm_opcode)) break; - } /* * check if it's cal_grant @@ -730,38 +728,38 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP)) goto exit; - if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || - ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) { + if (!ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) && + !ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) + goto exit; - /* - * BT is sleeping. Check if BT wakes up during - * WLAN calibration. If BT wakes up during - * WLAN calibration, need to go through all - * message exchanges again and recal. - */ - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | - AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); + /* + * BT is sleeping. Check if BT wakes up during + * WLAN calibration. If BT wakes up during + * WLAN calibration, need to go through all + * message exchanges again and recal. + */ + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | + AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)); - ar9003_mci_remote_reset(ah, true); - ar9003_mci_send_sys_waking(ah, true); - udelay(1); + ar9003_mci_remote_reset(ah, true); + ar9003_mci_send_sys_waking(ah, true); + udelay(1); - if (IS_CHAN_2GHZ(chan)) - ar9003_mci_send_lna_transfer(ah, true); + if (IS_CHAN_2GHZ(chan)) + ar9003_mci_send_lna_transfer(ah, true); - mci_hw->bt_state = MCI_BT_AWAKE; + mci_hw->bt_state = MCI_BT_AWAKE; - if (caldata) { - caldata->done_txiqcal_once = false; - caldata->done_txclcal_once = false; - caldata->rtt_done = false; - } + if (caldata) { + caldata->done_txiqcal_once = false; + caldata->done_txclcal_once = false; + caldata->rtt_done = false; + } - if (!ath9k_hw_init_cal(ah, chan)) - return -EIO; + if (!ath9k_hw_init_cal(ah, chan)) + return -EIO; - } exit: ar9003_mci_enable_interrupt(ah); return 0; @@ -797,29 +795,27 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 thresh; - if (enable) { - REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, - AR_MCI_SCHD_TABLE_2_HW_BASED, 1); - REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, - AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); - - if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { - thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_AGGR_THRESH, thresh); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); - } else { - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); - } - - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); - } else { + if (!enable) { REG_CLR_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); + return; } + REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1); + REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, + AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); + + if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { + thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_AGGR_THRESH, thresh); + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); + } else + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); + + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); } void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, @@ -942,26 +938,27 @@ static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done) struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 new_flags, to_set, to_clear; - if (mci->update_2g5g && (mci->bt_state != MCI_BT_SLEEP)) { - if (mci->is_2g) { - new_flags = MCI_2G_FLAGS; - to_clear = MCI_2G_FLAGS_CLEAR_MASK; - to_set = MCI_2G_FLAGS_SET_MASK; - } else { - new_flags = MCI_5G_FLAGS; - to_clear = MCI_5G_FLAGS_CLEAR_MASK; - to_set = MCI_5G_FLAGS_SET_MASK; - } + if (!mci->update_2g5g || (mci->bt_state == MCI_BT_SLEEP)) + return; - if (to_clear) - ar9003_mci_send_coex_bt_flags(ah, wait_done, + if (mci->is_2g) { + new_flags = MCI_2G_FLAGS; + to_clear = MCI_2G_FLAGS_CLEAR_MASK; + to_set = MCI_2G_FLAGS_SET_MASK; + } else { + new_flags = MCI_5G_FLAGS; + to_clear = MCI_5G_FLAGS_CLEAR_MASK; + to_set = MCI_5G_FLAGS_SET_MASK; + } + + if (to_clear) + ar9003_mci_send_coex_bt_flags(ah, wait_done, MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear); - if (to_set) - ar9003_mci_send_coex_bt_flags(ah, wait_done, + if (to_set) + ar9003_mci_send_coex_bt_flags(ah, wait_done, MCI_GPM_COEX_BT_FLAGS_SET, to_set); - } } static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, @@ -1017,34 +1014,34 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (mci->update_2g5g) { - if (mci->is_2g) { - ar9003_mci_send_2g5g_status(ah, true); - ar9003_mci_send_lna_transfer(ah, true); - udelay(5); + if (!mci->update_2g5g) + return; - REG_CLR_BIT(ah, AR_MCI_TX_CTRL, - AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); - REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, - AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); + if (mci->is_2g) { + ar9003_mci_send_2g5g_status(ah, true); + ar9003_mci_send_lna_transfer(ah, true); + udelay(5); - if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { - REG_SET_BIT(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - } - } else { - ar9003_mci_send_lna_take(ah, true); - udelay(5); - - REG_SET_BIT(ah, AR_MCI_TX_CTRL, - AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); - REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, - AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); - REG_CLR_BIT(ah, AR_BTCOEX_CTRL, + REG_CLR_BIT(ah, AR_MCI_TX_CTRL, + AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); + REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, + AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); + + if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) + REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); + } else { + ar9003_mci_send_lna_take(ah, true); + udelay(5); - ar9003_mci_send_2g5g_status(ah, true); - } + REG_SET_BIT(ah, AR_MCI_TX_CTRL, + AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); + REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, + AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); + REG_CLR_BIT(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); + + ar9003_mci_send_2g5g_status(ah, true); } } @@ -1258,12 +1255,12 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) } if (p_data) *p_data = more_gpm; - } + } - if (value != MCI_GPM_INVALID) - value <<= 4; + if (value != MCI_GPM_INVALID) + value <<= 4; - break; + break; case MCI_STATE_LAST_SCHD_MSG_OFFSET: value = MS(REG_READ(ah, AR_MCI_RX_STATUS), AR_MCI_RX_LAST_SCHD_MSG_INDEX); @@ -1358,24 +1355,22 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) ar9003_mci_send_coex_bt_status_query(ah, true, query_type); break; case MCI_STATE_NEED_FLUSH_BT_INFO: - /* - * btcoex_hw.mci.unhalt_bt_gpm means whether it's - * needed to send UNHALT message. It's set whenever - * there's a request to send HALT message. - * mci_halted_bt_gpm means whether HALT message is sent - * out successfully. - * - * Checking (mci_unhalt_bt_gpm == false) instead of - * checking (ah->mci_halted_bt_gpm == false) will make - * sure currently is in UNHALT-ed mode and BT can - * respond to status query. - */ - value = (!mci->unhalt_bt_gpm && - mci->need_flush_btinfo) ? 1 : 0; - if (p_data) - mci->need_flush_btinfo = - (*p_data != 0) ? true : false; - break; + /* + * btcoex_hw.mci.unhalt_bt_gpm means whether it's + * needed to send UNHALT message. It's set whenever + * there's a request to send HALT message. + * mci_halted_bt_gpm means whether HALT message is sent + * out successfully. + * + * Checking (mci_unhalt_bt_gpm == false) instead of + * checking (ah->mci_halted_bt_gpm == false) will make + * sure currently is in UNHALT-ed mode and BT can + * respond to status query. + */ + value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0; + if (p_data) + mci->need_flush_btinfo = (*p_data != 0) ? true : false; + break; case MCI_STATE_RECOVER_RX: ar9003_mci_prep_interface(ah); mci->query_bt = true; -- GitLab From 4fb7175bbd6a32899617b96b0b73c2ad651dfd03 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:14 +0530 Subject: [PATCH 0819/6849] ath9k_hw: fix IQ calibration chain index The chain index to perform IQ calibration is counted to number of valid tx chains and then used for indexing chain specific registers. If the chainmask is set to 0x2 (i.e chain 1 only), still it accesses chain 0 registers for chain 1. So use real chain index instead sequential one. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index f83a4a2e1da2..d7deb8c9f299 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -653,7 +653,6 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, } static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, - u8 num_chains, struct coeff *coeff, bool is_reusable) { @@ -677,7 +676,9 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, } /* Load the average of 2 passes */ - for (i = 0; i < num_chains; i++) { + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (!(ah->txchainmask & (1 << i))) + continue; nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0, AR_PHY_CALIBRATED_GAINS_0); @@ -767,16 +768,13 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) }; struct coeff coeff; s32 iq_res[6]; - u8 num_chains = 0; int i, im, j; int nmeasurement; for (i = 0; i < AR9300_MAX_CHAINS; i++) { - if (ah->txchainmask & (1 << i)) - num_chains++; - } + if (!(ah->txchainmask & (1 << i))) + continue; - for (i = 0; i < num_chains; i++) { nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0, AR_PHY_CALIBRATED_GAINS_0); @@ -839,8 +837,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) coeff.phs_coeff[i][im] -= 128; } } - ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, - &coeff, is_reusable); + ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); return; -- GitLab From 9dc08eceb7491331e81acde625e0d9c82aa86a16 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:20 +0530 Subject: [PATCH 0820/6849] ath9k_hw: program BT to control SPDT program BT to control SPDT everytime while loading switch table from eeprom. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index f794828c08e2..2cdf82bdb11d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3613,6 +3613,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) value = ar9003_switch_com_spdt_get(ah, is2ghz); REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_SWITCH_TABLE_COM_SPDT_ALL, value); + REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE); } value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); -- GitLab From c8b6fbe1f1d38aa19882263d6b0c644269e94244 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:25 +0530 Subject: [PATCH 0821/6849] ath9k_hw: configure ar9462 switching regulator Enable WLAN and BT mode for switching regulator discontinuous orverride for AR9462 chips. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 4 ++++ drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/reg.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 11abb972be1f..d6baf69cdc14 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -676,6 +676,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, if (chan->channel == 2484) ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); + if (AR_SREV_9462(ah)) + REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, + AR_GLB_SWREG_DISCONT_EN_BT_WLAN); + ah->modes_index = modesIndex; ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 3740aab864f4..03d590924c64 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -824,7 +824,6 @@ struct ath_hw { struct ar5416IniArray ini_japan2484; struct ar5416IniArray iniModes_9271_ANI_reg; struct ar5416IniArray ini_radio_post_sys2ant; - struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 458f81b4a7cb..560d6effac7a 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -2211,5 +2211,7 @@ enum { #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0 +#define AR_GLB_SWREG_DISCONT_MODE 0x2002c +#define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3 #endif -- GitLab From 99922a45e96b22df387823ad5ecfe4dc26a96c9e Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:31 +0530 Subject: [PATCH 0822/6849] ath9k_hw: fix BT RF performance When software rfkill is triggered, before put the chip in reset state, give LNA and SPDT control to BT to make sure BT can have good RF performance. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 16 ++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 + drivers/net/wireless/ath/ath9k/hw.c | 3 +++ 3 files changed, 20 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 854dff66a63f..8b09a8239c1c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1391,3 +1391,19 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) return value; } EXPORT_SYMBOL(ar9003_mci_state); + +void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + + ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n"); + + REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); + mci->is_2g = false; + mci->update_2g5g = true; + ar9003_mci_send_2g5g_status(ah, true); + + /* Force another 2g5g update at next scanning */ + mci->update_2g5g = true; +} diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 652ab8c39e2b..f4a6a4450ba8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -266,6 +266,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); +void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); /* * These functions are used by ath9k_hw. diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9f0f5f74f17a..98478fd5d284 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2737,6 +2737,9 @@ EXPORT_SYMBOL(ath9k_hw_setrxfilter); bool ath9k_hw_phy_disable(struct ath_hw *ah) { + if (ath9k_hw_mci_is_enabled(ah)) + ar9003_mci_bt_gain_ctrl(ah); + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) return false; -- GitLab From 0603143e47a34d0485a13fd7f46e56a97e687e34 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:36 +0530 Subject: [PATCH 0823/6849] ath9k: BT coex performance tuning for AR9462 Use smaller aggregation limit and increasing aggregation threshold for osla that could improve wlan performance when there is HID profile. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 3 -- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 - drivers/net/wireless/ath/ath9k/mci.c | 54 +++++++++++++-------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 8b09a8239c1c..b1ced2a76da3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1381,9 +1381,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) case MCI_STATE_NEED_FTP_STOMP: value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); break; - case MCI_STATE_NEED_TUNING: - value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING); - break; default: break; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index f4a6a4450ba8..10282e2bcdc9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -212,7 +212,6 @@ enum mci_state_type { MCI_STATE_SET_CONCUR_TX_PRI, MCI_STATE_RECOVER_RX, MCI_STATE_NEED_FTP_STOMP, - MCI_STATE_NEED_TUNING, MCI_STATE_DEBUG, MCI_STATE_MAX }; diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 7b553f6a97b1..49137f477b05 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -116,42 +116,58 @@ static void ath_mci_update_scheme(struct ath_softc *sc) struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; + struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; struct ath_mci_profile_info *info; u32 num_profile = NUM_PROF(mci); + if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) + goto skip_tuning; + if (num_profile == 1) { info = list_first_entry(&mci->info, struct ath_mci_profile_info, list); - if (mci->num_sco && info->T == 12) { - mci->aggr_limit = 8; + if (mci->num_sco) { + if (info->T == 12) + mci->aggr_limit = 8; + else if (info->T == 6) { + mci->aggr_limit = 6; + btcoex->duty_cycle = 30; + } ath_dbg(common, MCI, - "Single SCO, aggregation limit 2 ms\n"); - } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && - !info->master) { - btcoex->btcoex_period = 60; + "Single SCO, aggregation limit %d 1/4 ms\n", + mci->aggr_limit); + } else if (mci->num_pan || mci->num_other_acl) { + /* + * For single PAN/FTP profile, allocate 35% for BT + * to improve WLAN throughput. + */ + btcoex->duty_cycle = 35; + btcoex->btcoex_period = 53; ath_dbg(common, MCI, - "Single slave PAN/FTP, bt period 60 ms\n"); - } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && - (info->T > 0 && info->T < 50) && - (info->A > 1 || info->W > 1)) { + "Single PAN/FTP bt period %d ms dutycycle %d\n", + btcoex->duty_cycle, btcoex->btcoex_period); + } else if (mci->num_hid) { btcoex->duty_cycle = 30; - mci->aggr_limit = 8; + mci->aggr_limit = 6; ath_dbg(common, MCI, "Multiple attempt/timeout single HID " - "aggregation limit 2 ms dutycycle 30%%\n"); + "aggregation limit 1.5 ms dutycycle 30%%\n"); } - } else if ((num_profile == 2) && (mci->num_hid == 2)) { - btcoex->duty_cycle = 30; - mci->aggr_limit = 8; - ath_dbg(common, MCI, - "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); - } else if (num_profile > 3) { + } else if (num_profile == 2) { + if (mci->num_hid == 2) + btcoex->duty_cycle = 30; mci->aggr_limit = 6; ath_dbg(common, MCI, - "Three or more profiles aggregation limit 1.5 ms\n"); + "Two BT profiles aggr limit 1.5 ms dutycycle %d%%\n", + btcoex->duty_cycle); + } else if (num_profile >= 3) { + mci->aggr_limit = 4; + ath_dbg(common, MCI, + "Three or more profiles aggregation limit 1 ms\n"); } +skip_tuning: if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { if (IS_CHAN_HT(sc->sc_ah->curchan)) ath_mci_adjust_aggr_limit(btcoex); -- GitLab From c9ae6ab4c7d7aa29f9607ac69daafbc241fc123e Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:41 +0530 Subject: [PATCH 0824/6849] ath: do not update cycle counters with sleep mode When the chip is waking up from sleep state, the cycle counters might have incorrect readings. So it is better not to update those readings with software counters. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d739c8e6a012..623b04f63fe4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -101,6 +101,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc) spin_lock(&common->cc_lock); ath_hw_cycle_counters_update(common); memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + memset(&common->cc_ani, 0, sizeof(common->cc_ani)); spin_unlock(&common->cc_lock); } -- GitLab From 153dccd467b818b1dd3a6801b14e94a7a48ef859 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:47 +0530 Subject: [PATCH 0825/6849] ath9k_hw: fix power state for MCI Program MCI related power registers only if MCI interrupts are enabled. This could help to reduce power consumptions when WLAN alone is enabled in BT coex chips. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 98478fd5d284..45e670087e1c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2009,12 +2009,9 @@ static void ath9k_set_power_sleep(struct ath_hw *ah) REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); if (AR_SREV_9462(ah)) { - REG_WRITE(ah, AR_TIMER_MODE, - REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); - REG_WRITE(ah, AR_NDP2_TIMER_MODE, - REG_READ(ah, AR_NDP2_TIMER_MODE) & 0xFFFFFF00); - REG_WRITE(ah, AR_SLP32_INC, - REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); + REG_CLR_BIT(ah, AR_TIMER_MODE, 0xff); + REG_CLR_BIT(ah, AR_NDP2_TIMER_MODE, 0xff); + REG_CLR_BIT(ah, AR_SLP32_INC, 0xfffff); /* xxx Required for WLAN only case ? */ REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); udelay(100); @@ -2026,7 +2023,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah) */ REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); - if (AR_SREV_9462(ah)) + if (ath9k_hw_mci_is_enabled(ah)) udelay(100); if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) @@ -2051,7 +2048,6 @@ static void ath9k_set_power_sleep(struct ath_hw *ah) static void ath9k_set_power_network_sleep(struct ath_hw *ah) { struct ath9k_hw_capabilities *pCap = &ah->caps; - u32 val; REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); @@ -2070,19 +2066,16 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah) * SYS_WAKING and SYS_SLEEPING messages which will make * BT CPU to busy to process. */ - if (AR_SREV_9462(ah)) { - val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & - ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); - } + if (ath9k_hw_mci_is_enabled(ah)) + REG_CLR_BIT(ah, AR_MCI_INTERRUPT_RX_MSG_EN, + AR_MCI_INTERRUPT_RX_HW_MSG_MASK); /* * Clear the RTC force wake bit to allow the * mac to go to sleep. */ - REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, - AR_RTC_FORCE_WAKE_EN); + REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); - if (AR_SREV_9462(ah)) + if (ath9k_hw_mci_is_enabled(ah)) udelay(30); } -- GitLab From 6995fb805ed5de852a7d49413730980bc7173e82 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Jun 2012 16:28:52 +0530 Subject: [PATCH 0826/6849] ath9k: improve BT FTP/PAN performance When BT FTP/PAN transmits while WLAN is idle, the one of 9462 chain often picks up BT's tx signal and starts receiving. If the current weight is set to be higher than BT tx, BT tx will be aborted and this also degrades BT performance. Hence lower WLAN rx priority in this case only when there are no WLAN traffic. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/btcoex.c | 10 ++++++++-- drivers/net/wireless/ath/ath9k/btcoex.h | 4 ++++ drivers/net/wireless/ath/ath9k/gpio.c | 13 +++++++++++++ drivers/net/wireless/ath/ath9k/recv.c | 1 + 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index ee946b8fe00c..ce10d1a9e493 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -307,6 +307,7 @@ struct ath_rx { u8 defant; u8 rxotherant; u32 *rxlink; + u32 num_pkts; unsigned int rxfilter; spinlock_t rxbuflock; struct list_head rxbuf; @@ -458,6 +459,7 @@ struct ath_btcoex { u32 btcoex_period; /* in usec */ u32 btscan_no_stomp; /* in usec */ u32 duty_cycle; + u32 bt_wait_time; struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ struct ath_mci_profile mci; }; diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index 1ca6da80d4ad..acd437384fe4 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -336,10 +336,16 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type) { struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; - const u32 *weight = AR_SREV_9462(ah) ? ar9003_wlan_weights[stomp_type] : - ar9462_wlan_weights[stomp_type]; + const u32 *weight = ar9003_wlan_weights[stomp_type]; int i; + if (AR_SREV_9462(ah)) { + if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && + btcoex->mci.stomp_ftp) + stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; + weight = ar9462_wlan_weights[stomp_type]; + } + for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { btcoex->bt_weight[i] = AR9300_BT_WGHT; btcoex->wlan_weight[i] = weight[i]; diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 3a1e1cfabd5e..20092f98658f 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h @@ -36,6 +36,9 @@ #define ATH_BT_CNT_THRESHOLD 3 #define ATH_BT_CNT_SCAN_THRESHOLD 15 +#define ATH_BTCOEX_RX_WAIT_TIME 100 +#define ATH_BTCOEX_STOMP_FTP_THRESH 5 + #define AR9300_NUM_BT_WEIGHTS 4 #define AR9300_NUM_WLAN_WEIGHTS 4 /* Defines the BT AR_BT_COEX_WGHT used */ @@ -80,6 +83,7 @@ struct ath9k_hw_mci { u8 bt_ver_major; u8 bt_ver_minor; u8 bt_state; + u8 stomp_ftp; }; struct ath_btcoex_hw { diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 9397a6d2ed5d..af6d27350291 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -191,6 +191,7 @@ static void ath_btcoex_period_timer(unsigned long data) struct ath_softc *sc = (struct ath_softc *) data; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_mci_profile *mci = &btcoex->mci; u32 timer_period; bool is_btscan; @@ -199,6 +200,18 @@ static void ath_btcoex_period_timer(unsigned long data) ath_detect_bt_priority(sc); is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); + btcoex->bt_wait_time += btcoex->btcoex_period; + if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { + if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP, NULL) && + (mci->num_pan || mci->num_other_acl)) + ah->btcoex_hw.mci.stomp_ftp = + (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); + else + ah->btcoex_hw.mci.stomp_ftp = false; + btcoex->bt_wait_time = 0; + sc->rx.num_pkts = 0; + } + spin_lock_bh(&btcoex->btcoex_lock); ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 18acdbcbb03f..611be4f934e7 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1841,6 +1841,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) else rs.is_mybeacon = false; + sc->rx.num_pkts++; ath_debug_stat_rx(sc, &rs); /* -- GitLab From ef1b6cd9a1ba06a3daf9a03aa8f25d52d1f2c31a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:23:37 +0530 Subject: [PATCH 0827/6849] ath9k: Group link monitoring logic Add link.c and move all the link/connection monitoring code to it. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/ath9k.h | 13 +- drivers/net/wireless/ath/ath9k/link.c | 497 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/main.c | 431 -------------------- drivers/net/wireless/ath/ath9k/xmit.c | 46 +-- 5 files changed, 511 insertions(+), 479 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/link.c diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 3f0b84723789..4d60fa84cbb4 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -3,7 +3,8 @@ ath9k-y += beacon.o \ init.o \ main.o \ recv.o \ - xmit.o + xmit.o \ + link.o ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index ce10d1a9e493..d804416092ce 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -326,6 +326,9 @@ int ath_rx_init(struct ath_softc *sc, int nbufs); void ath_rx_cleanup(struct ath_softc *sc); int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); +void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq); +void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq); +void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq); void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); void ath_draintxq(struct ath_softc *sc, @@ -415,9 +418,9 @@ int ath_beaconq_config(struct ath_softc *sc); void ath_set_beacon(struct ath_softc *sc); void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); -/*******/ -/* ANI */ -/*******/ +/*******************/ +/* Link Monitoring */ +/*******************/ #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ @@ -429,6 +432,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); #define ATH_PAPRD_TIMEOUT 100 /* msecs */ +void ath_tx_complete_poll_work(struct work_struct *work); void ath_reset_work(struct work_struct *work); void ath_hw_check(struct work_struct *work); void ath_hw_pll_work(struct work_struct *work); @@ -437,6 +441,8 @@ void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); void ath_paprd_calibrate(struct work_struct *work); void ath_ani_calibrate(unsigned long data); void ath_start_ani(struct ath_common *common); +int ath_update_survey_stats(struct ath_softc *sc); +void ath_update_survey_nf(struct ath_softc *sc, int channel); /**********/ /* BTCOEX */ @@ -741,5 +747,4 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath9k_vif_iter_data *iter_data); - #endif /* ATH9K_H */ diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c new file mode 100644 index 000000000000..7368b9630b99 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2012 Qualcomm Atheros, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ath9k.h" + +/* + * TX polling - checks if the TX engine is stuck somewhere + * and issues a chip reset if so. + */ +void ath_tx_complete_poll_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, + tx_complete_work.work); + struct ath_txq *txq; + int i; + bool needreset = false; +#ifdef CONFIG_ATH9K_DEBUGFS + sc->tx_complete_poll_work_seen++; +#endif + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) + if (ATH_TXQ_SETUP(sc, i)) { + txq = &sc->tx.txq[i]; + ath_txq_lock(sc, txq); + if (txq->axq_depth) { + if (txq->axq_tx_inprogress) { + needreset = true; + ath_txq_unlock(sc, txq); + break; + } else { + txq->axq_tx_inprogress = true; + } + } + ath_txq_unlock_complete(sc, txq); + } + + if (needreset) { + ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, + "tx hung, resetting the chip\n"); + RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); + } + + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, + msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); +} + +/* + * Checks if the BB/MAC is hung. + */ +void ath_hw_check(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + unsigned long flags; + int busy; + u8 is_alive, nbeacon = 1; + + ath9k_ps_wakeup(sc); + is_alive = ath9k_hw_check_alive(sc->sc_ah); + + if (is_alive && !AR_SREV_9300(sc->sc_ah)) + goto out; + else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { + ath_dbg(common, RESET, + "DCU stuck is detected. Schedule chip reset\n"); + RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); + goto sched_reset; + } + + spin_lock_irqsave(&common->cc_lock, flags); + busy = ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + + ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", + busy, sc->hw_busy_count + 1); + if (busy >= 99) { + if (++sc->hw_busy_count >= 3) { + RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); + goto sched_reset; + } + } else if (busy >= 0) { + sc->hw_busy_count = 0; + nbeacon = 3; + } + + ath_start_rx_poll(sc, nbeacon); + goto out; + +sched_reset: + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); +out: + ath9k_ps_restore(sc); +} + +/* + * PLL-WAR for AR9485. + */ +static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) +{ + static int count; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + if (pll_sqsum >= 0x40000) { + count++; + if (count == 3) { + /* Rx is hung for more than 500ms. Reset it */ + ath_dbg(common, RESET, "Possible RX hang, resetting\n"); + RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); + count = 0; + } + } else + count = 0; +} + +void ath_hw_pll_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, + hw_pll_work.work); + u32 pll_sqsum; + + if (AR_SREV_9485(sc->sc_ah)) { + ath9k_ps_wakeup(sc); + pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); + ath9k_ps_restore(sc); + ath_hw_pll_rx_hang_check(sc, pll_sqsum); + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); + } +} + +/* + * RX Polling - monitors baseband hangs. + */ +void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) +{ + if (!AR_SREV_9300(sc->sc_ah)) + return; + + if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) + return; + + mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies + (nbeacon * sc->cur_beacon_conf.beacon_interval)); +} + +void ath_rx_poll(unsigned long data) +{ + struct ath_softc *sc = (struct ath_softc *)data; + + ieee80211_queue_work(sc->hw, &sc->hw_check_work); +} + +/* + * PA Pre-distortion. + */ +static void ath_paprd_activate(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_hw_cal_data *caldata = ah->caldata; + int chain; + + if (!caldata || !caldata->paprd_done) + return; + + ath9k_ps_wakeup(sc); + ar9003_paprd_enable(ah, false); + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { + if (!(ah->txchainmask & BIT(chain))) + continue; + + ar9003_paprd_populate_single_table(ah, caldata, chain); + } + + ar9003_paprd_enable(ah, true); + ath9k_ps_restore(sc); +} + +static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) +{ + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ath_tx_control txctl; + int time_left; + + memset(&txctl, 0, sizeof(txctl)); + txctl.txq = sc->tx.txq_map[WME_AC_BE]; + + memset(tx_info, 0, sizeof(*tx_info)); + tx_info->band = hw->conf.channel->band; + tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; + tx_info->control.rates[0].idx = 0; + tx_info->control.rates[0].count = 1; + tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; + tx_info->control.rates[1].idx = -1; + + init_completion(&sc->paprd_complete); + txctl.paprd = BIT(chain); + + if (ath_tx_start(hw, skb, &txctl) != 0) { + ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); + dev_kfree_skb_any(skb); + return false; + } + + time_left = wait_for_completion_timeout(&sc->paprd_complete, + msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); + + if (!time_left) + ath_dbg(common, CALIBRATE, + "Timeout waiting for paprd training on TX chain %d\n", + chain); + + return !!time_left; +} + +void ath_paprd_calibrate(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); + struct ieee80211_hw *hw = sc->hw; + struct ath_hw *ah = sc->sc_ah; + struct ieee80211_hdr *hdr; + struct sk_buff *skb = NULL; + struct ath9k_hw_cal_data *caldata = ah->caldata; + struct ath_common *common = ath9k_hw_common(ah); + int ftype; + int chain_ok = 0; + int chain; + int len = 1800; + + if (!caldata) + return; + + ath9k_ps_wakeup(sc); + + if (ar9003_paprd_init_table(ah) < 0) + goto fail_paprd; + + skb = alloc_skb(len, GFP_KERNEL); + if (!skb) + goto fail_paprd; + + skb_put(skb, len); + memset(skb->data, 0, len); + hdr = (struct ieee80211_hdr *)skb->data; + ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; + hdr->frame_control = cpu_to_le16(ftype); + hdr->duration_id = cpu_to_le16(10); + memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); + memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); + memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); + + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { + if (!(ah->txchainmask & BIT(chain))) + continue; + + chain_ok = 0; + + ath_dbg(common, CALIBRATE, + "Sending PAPRD frame for thermal measurement on chain %d\n", + chain); + if (!ath_paprd_send_frame(sc, skb, chain)) + goto fail_paprd; + + ar9003_paprd_setup_gain_table(ah, chain); + + ath_dbg(common, CALIBRATE, + "Sending PAPRD training frame on chain %d\n", chain); + if (!ath_paprd_send_frame(sc, skb, chain)) + goto fail_paprd; + + if (!ar9003_paprd_is_done(ah)) { + ath_dbg(common, CALIBRATE, + "PAPRD not yet done on chain %d\n", chain); + break; + } + + if (ar9003_paprd_create_curve(ah, caldata, chain)) { + ath_dbg(common, CALIBRATE, + "PAPRD create curve failed on chain %d\n", + chain); + break; + } + + chain_ok = 1; + } + kfree_skb(skb); + + if (chain_ok) { + caldata->paprd_done = true; + ath_paprd_activate(sc); + } + +fail_paprd: + ath9k_ps_restore(sc); +} + +/* + * ANI performs periodic noise floor calibration + * that is used to adjust and optimize the chip performance. This + * takes environmental changes (location, temperature) into account. + * When the task is complete, it reschedules itself depending on the + * appropriate interval that was calculated. + */ +void ath_ani_calibrate(unsigned long data) +{ + struct ath_softc *sc = (struct ath_softc *)data; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + bool longcal = false; + bool shortcal = false; + bool aniflag = false; + unsigned int timestamp = jiffies_to_msecs(jiffies); + u32 cal_interval, short_cal_interval, long_cal_interval; + unsigned long flags; + + if (ah->caldata && ah->caldata->nfcal_interference) + long_cal_interval = ATH_LONG_CALINTERVAL_INT; + else + long_cal_interval = ATH_LONG_CALINTERVAL; + + short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? + ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; + + /* Only calibrate if awake */ + if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) + goto set_timer; + + ath9k_ps_wakeup(sc); + + /* Long calibration runs independently of short calibration. */ + if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { + longcal = true; + common->ani.longcal_timer = timestamp; + } + + /* Short calibration applies only while caldone is false */ + if (!common->ani.caldone) { + if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { + shortcal = true; + common->ani.shortcal_timer = timestamp; + common->ani.resetcal_timer = timestamp; + } + } else { + if ((timestamp - common->ani.resetcal_timer) >= + ATH_RESTART_CALINTERVAL) { + common->ani.caldone = ath9k_hw_reset_calvalid(ah); + if (common->ani.caldone) + common->ani.resetcal_timer = timestamp; + } + } + + /* Verify whether we must check ANI */ + if (sc->sc_ah->config.enable_ani + && (timestamp - common->ani.checkani_timer) >= + ah->config.ani_poll_interval) { + aniflag = true; + common->ani.checkani_timer = timestamp; + } + + /* Call ANI routine if necessary */ + if (aniflag) { + spin_lock_irqsave(&common->cc_lock, flags); + ath9k_hw_ani_monitor(ah, ah->curchan); + ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + } + + /* Perform calibration if necessary */ + if (longcal || shortcal) { + common->ani.caldone = + ath9k_hw_calibrate(ah, ah->curchan, + ah->rxchainmask, longcal); + } + + ath_dbg(common, ANI, + "Calibration @%lu finished: %s %s %s, caldone: %s\n", + jiffies, + longcal ? "long" : "", shortcal ? "short" : "", + aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); + + ath9k_ps_restore(sc); + +set_timer: + /* + * Set timer interval based on previous results. + * The interval must be the shortest necessary to satisfy ANI, + * short calibration and long calibration. + */ + ath9k_debug_samp_bb_mac(sc); + cal_interval = ATH_LONG_CALINTERVAL; + if (sc->sc_ah->config.enable_ani) + cal_interval = min(cal_interval, + (u32)ah->config.ani_poll_interval); + if (!common->ani.caldone) + cal_interval = min(cal_interval, (u32)short_cal_interval); + + mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { + if (!ah->caldata->paprd_done) + ieee80211_queue_work(sc->hw, &sc->paprd_work); + else if (!ah->paprd_table_write_done) + ath_paprd_activate(sc); + } +} + +void ath_start_ani(struct ath_common *common) +{ + struct ath_hw *ah = common->ah; + unsigned long timestamp = jiffies_to_msecs(jiffies); + struct ath_softc *sc = (struct ath_softc *) common->priv; + + if (!(sc->sc_flags & SC_OP_ANI_RUN)) + return; + + if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) + return; + + common->ani.longcal_timer = timestamp; + common->ani.shortcal_timer = timestamp; + common->ani.checkani_timer = timestamp; + + mod_timer(&common->ani.timer, + jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); +} + +void ath_update_survey_nf(struct ath_softc *sc, int channel) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_channel *chan = &ah->channels[channel]; + struct survey_info *survey = &sc->survey[channel]; + + if (chan->noisefloor) { + survey->filled |= SURVEY_INFO_NOISE_DBM; + survey->noise = ath9k_hw_getchan_noise(ah, chan); + } +} + +/* + * Updates the survey statistics and returns the busy time since last + * update in %, if the measurement duration was long enough for the + * result to be useful, -1 otherwise. + */ +int ath_update_survey_stats(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + int pos = ah->curchan - &ah->channels[0]; + struct survey_info *survey = &sc->survey[pos]; + struct ath_cycle_counters *cc = &common->cc_survey; + unsigned int div = common->clockrate * 1000; + int ret = 0; + + if (!ah->curchan) + return -1; + + if (ah->power_mode == ATH9K_PM_AWAKE) + ath_hw_cycle_counters_update(common); + + if (cc->cycles > 0) { + survey->filled |= SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_RX | + SURVEY_INFO_CHANNEL_TIME_TX; + survey->channel_time += cc->cycles / div; + survey->channel_time_busy += cc->rx_busy / div; + survey->channel_time_rx += cc->rx_frame / div; + survey->channel_time_tx += cc->tx_frame / div; + } + + if (cc->cycles < div) + return -1; + + if (cc->cycles > 0) + ret = cc->rx_busy * 100 / cc->cycles; + + memset(cc, 0, sizeof(*cc)); + + ath_update_survey_nf(sc, pos); + + return ret; +} diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 623b04f63fe4..304769a3e179 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -144,84 +144,6 @@ void ath9k_ps_restore(struct ath_softc *sc) spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } -void ath_start_ani(struct ath_common *common) -{ - struct ath_hw *ah = common->ah; - unsigned long timestamp = jiffies_to_msecs(jiffies); - struct ath_softc *sc = (struct ath_softc *) common->priv; - - if (!(sc->sc_flags & SC_OP_ANI_RUN)) - return; - - if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) - return; - - common->ani.longcal_timer = timestamp; - common->ani.shortcal_timer = timestamp; - common->ani.checkani_timer = timestamp; - - mod_timer(&common->ani.timer, - jiffies + - msecs_to_jiffies((u32)ah->config.ani_poll_interval)); -} - -static void ath_update_survey_nf(struct ath_softc *sc, int channel) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath9k_channel *chan = &ah->channels[channel]; - struct survey_info *survey = &sc->survey[channel]; - - if (chan->noisefloor) { - survey->filled |= SURVEY_INFO_NOISE_DBM; - survey->noise = ath9k_hw_getchan_noise(ah, chan); - } -} - -/* - * Updates the survey statistics and returns the busy time since last - * update in %, if the measurement duration was long enough for the - * result to be useful, -1 otherwise. - */ -static int ath_update_survey_stats(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - int pos = ah->curchan - &ah->channels[0]; - struct survey_info *survey = &sc->survey[pos]; - struct ath_cycle_counters *cc = &common->cc_survey; - unsigned int div = common->clockrate * 1000; - int ret = 0; - - if (!ah->curchan) - return -1; - - if (ah->power_mode == ATH9K_PM_AWAKE) - ath_hw_cycle_counters_update(common); - - if (cc->cycles > 0) { - survey->filled |= SURVEY_INFO_CHANNEL_TIME | - SURVEY_INFO_CHANNEL_TIME_BUSY | - SURVEY_INFO_CHANNEL_TIME_RX | - SURVEY_INFO_CHANNEL_TIME_TX; - survey->channel_time += cc->cycles / div; - survey->channel_time_busy += cc->rx_busy / div; - survey->channel_time_rx += cc->rx_frame / div; - survey->channel_time_tx += cc->tx_frame / div; - } - - if (cc->cycles < div) - return -1; - - if (cc->cycles > 0) - ret = cc->rx_busy * 100 / cc->cycles; - - memset(cc, 0, sizeof(*cc)); - - ath_update_survey_nf(sc, pos); - - return ret; -} - static void __ath_cancel_work(struct ath_softc *sc) { cancel_work_sync(&sc->paprd_work); @@ -380,258 +302,6 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, return r; } -static void ath_paprd_activate(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath9k_hw_cal_data *caldata = ah->caldata; - int chain; - - if (!caldata || !caldata->paprd_done) - return; - - ath9k_ps_wakeup(sc); - ar9003_paprd_enable(ah, false); - for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->txchainmask & BIT(chain))) - continue; - - ar9003_paprd_populate_single_table(ah, caldata, chain); - } - - ar9003_paprd_enable(ah, true); - ath9k_ps_restore(sc); -} - -static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) -{ - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ath_tx_control txctl; - int time_left; - - memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[WME_AC_BE]; - - memset(tx_info, 0, sizeof(*tx_info)); - tx_info->band = hw->conf.channel->band; - tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; - tx_info->control.rates[0].idx = 0; - tx_info->control.rates[0].count = 1; - tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; - tx_info->control.rates[1].idx = -1; - - init_completion(&sc->paprd_complete); - txctl.paprd = BIT(chain); - - if (ath_tx_start(hw, skb, &txctl) != 0) { - ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); - dev_kfree_skb_any(skb); - return false; - } - - time_left = wait_for_completion_timeout(&sc->paprd_complete, - msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); - - if (!time_left) - ath_dbg(common, CALIBRATE, - "Timeout waiting for paprd training on TX chain %d\n", - chain); - - return !!time_left; -} - -void ath_paprd_calibrate(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); - struct ieee80211_hw *hw = sc->hw; - struct ath_hw *ah = sc->sc_ah; - struct ieee80211_hdr *hdr; - struct sk_buff *skb = NULL; - struct ath9k_hw_cal_data *caldata = ah->caldata; - struct ath_common *common = ath9k_hw_common(ah); - int ftype; - int chain_ok = 0; - int chain; - int len = 1800; - - if (!caldata) - return; - - ath9k_ps_wakeup(sc); - - if (ar9003_paprd_init_table(ah) < 0) - goto fail_paprd; - - skb = alloc_skb(len, GFP_KERNEL); - if (!skb) - goto fail_paprd; - - skb_put(skb, len); - memset(skb->data, 0, len); - hdr = (struct ieee80211_hdr *)skb->data; - ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; - hdr->frame_control = cpu_to_le16(ftype); - hdr->duration_id = cpu_to_le16(10); - memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); - memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); - memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); - - for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->txchainmask & BIT(chain))) - continue; - - chain_ok = 0; - - ath_dbg(common, CALIBRATE, - "Sending PAPRD frame for thermal measurement on chain %d\n", - chain); - if (!ath_paprd_send_frame(sc, skb, chain)) - goto fail_paprd; - - ar9003_paprd_setup_gain_table(ah, chain); - - ath_dbg(common, CALIBRATE, - "Sending PAPRD training frame on chain %d\n", chain); - if (!ath_paprd_send_frame(sc, skb, chain)) - goto fail_paprd; - - if (!ar9003_paprd_is_done(ah)) { - ath_dbg(common, CALIBRATE, - "PAPRD not yet done on chain %d\n", chain); - break; - } - - if (ar9003_paprd_create_curve(ah, caldata, chain)) { - ath_dbg(common, CALIBRATE, - "PAPRD create curve failed on chain %d\n", - chain); - break; - } - - chain_ok = 1; - } - kfree_skb(skb); - - if (chain_ok) { - caldata->paprd_done = true; - ath_paprd_activate(sc); - } - -fail_paprd: - ath9k_ps_restore(sc); -} - -/* - * This routine performs the periodic noise floor calibration function - * that is used to adjust and optimize the chip performance. This - * takes environmental changes (location, temperature) into account. - * When the task is complete, it reschedules itself depending on the - * appropriate interval that was calculated. - */ -void ath_ani_calibrate(unsigned long data) -{ - struct ath_softc *sc = (struct ath_softc *)data; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - bool longcal = false; - bool shortcal = false; - bool aniflag = false; - unsigned int timestamp = jiffies_to_msecs(jiffies); - u32 cal_interval, short_cal_interval, long_cal_interval; - unsigned long flags; - - if (ah->caldata && ah->caldata->nfcal_interference) - long_cal_interval = ATH_LONG_CALINTERVAL_INT; - else - long_cal_interval = ATH_LONG_CALINTERVAL; - - short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? - ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; - - /* Only calibrate if awake */ - if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) - goto set_timer; - - ath9k_ps_wakeup(sc); - - /* Long calibration runs independently of short calibration. */ - if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { - longcal = true; - common->ani.longcal_timer = timestamp; - } - - /* Short calibration applies only while caldone is false */ - if (!common->ani.caldone) { - if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { - shortcal = true; - common->ani.shortcal_timer = timestamp; - common->ani.resetcal_timer = timestamp; - } - } else { - if ((timestamp - common->ani.resetcal_timer) >= - ATH_RESTART_CALINTERVAL) { - common->ani.caldone = ath9k_hw_reset_calvalid(ah); - if (common->ani.caldone) - common->ani.resetcal_timer = timestamp; - } - } - - /* Verify whether we must check ANI */ - if (sc->sc_ah->config.enable_ani - && (timestamp - common->ani.checkani_timer) >= - ah->config.ani_poll_interval) { - aniflag = true; - common->ani.checkani_timer = timestamp; - } - - /* Call ANI routine if necessary */ - if (aniflag) { - spin_lock_irqsave(&common->cc_lock, flags); - ath9k_hw_ani_monitor(ah, ah->curchan); - ath_update_survey_stats(sc); - spin_unlock_irqrestore(&common->cc_lock, flags); - } - - /* Perform calibration if necessary */ - if (longcal || shortcal) { - common->ani.caldone = - ath9k_hw_calibrate(ah, ah->curchan, - ah->rxchainmask, longcal); - } - - ath_dbg(common, ANI, - "Calibration @%lu finished: %s %s %s, caldone: %s\n", - jiffies, - longcal ? "long" : "", shortcal ? "short" : "", - aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); - - ath9k_ps_restore(sc); - -set_timer: - /* - * Set timer interval based on previous results. - * The interval must be the shortest necessary to satisfy ANI, - * short calibration and long calibration. - */ - ath9k_debug_samp_bb_mac(sc); - cal_interval = ATH_LONG_CALINTERVAL; - if (sc->sc_ah->config.enable_ani) - cal_interval = min(cal_interval, - (u32)ah->config.ani_poll_interval); - if (!common->ani.caldone) - cal_interval = min(cal_interval, (u32)short_cal_interval); - - mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { - if (!ah->caldata->paprd_done) - ieee80211_queue_work(sc->hw, &sc->paprd_work); - else if (!ah->paprd_table_write_done) - ath_paprd_activate(sc); - } -} - static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { @@ -669,7 +339,6 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) ath_tx_node_cleanup(sc, an); } - void ath9k_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; @@ -903,87 +572,6 @@ void ath_reset_work(struct work_struct *work) ath_reset(sc, true); } -void ath_hw_check(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - unsigned long flags; - int busy; - u8 is_alive, nbeacon = 1; - - ath9k_ps_wakeup(sc); - is_alive = ath9k_hw_check_alive(sc->sc_ah); - - if (is_alive && !AR_SREV_9300(sc->sc_ah)) - goto out; - else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { - ath_dbg(common, RESET, - "DCU stuck is detected. Schedule chip reset\n"); - RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); - goto sched_reset; - } - - spin_lock_irqsave(&common->cc_lock, flags); - busy = ath_update_survey_stats(sc); - spin_unlock_irqrestore(&common->cc_lock, flags); - - ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", - busy, sc->hw_busy_count + 1); - if (busy >= 99) { - if (++sc->hw_busy_count >= 3) { - RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); - goto sched_reset; - } - } else if (busy >= 0) { - sc->hw_busy_count = 0; - nbeacon = 3; - } - - ath_start_rx_poll(sc, nbeacon); - goto out; - -sched_reset: - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); -out: - ath9k_ps_restore(sc); -} - -static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) -{ - static int count; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - - if (pll_sqsum >= 0x40000) { - count++; - if (count == 3) { - /* Rx is hung for more than 500ms. Reset it */ - ath_dbg(common, RESET, "Possible RX hang, resetting\n"); - RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - count = 0; - } - } else - count = 0; -} - -void ath_hw_pll_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, - hw_pll_work.work); - u32 pll_sqsum; - - if (AR_SREV_9485(sc->sc_ah)) { - - ath9k_ps_wakeup(sc); - pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); - ath9k_ps_restore(sc); - - ath_hw_pll_rx_hang_check(sc, pll_sqsum); - - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); - } -} - /**********************/ /* mac80211 callbacks */ /**********************/ @@ -1389,25 +977,6 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, } } -void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) -{ - if (!AR_SREV_9300(sc->sc_ah)) - return; - - if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) - return; - - mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies - (nbeacon * sc->cur_beacon_conf.beacon_interval)); -} - -void ath_rx_poll(unsigned long data) -{ - struct ath_softc *sc = (struct ath_softc *)data; - - ieee80211_queue_work(sc->hw, &sc->hw_check_work); -} - static int ath9k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d59dd01d6cde..6619a39b8c27 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -105,19 +105,19 @@ static int ath_max_4ms_framelen[4][32] = { /* Aggregation logic */ /*********************/ -static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) +void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) __acquires(&txq->axq_lock) { spin_lock_bh(&txq->axq_lock); } -static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) +void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) __releases(&txq->axq_lock) { spin_unlock_bh(&txq->axq_lock); } -static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) +void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) __releases(&txq->axq_lock) { struct sk_buff_head q; @@ -2231,46 +2231,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ath_txq_unlock_complete(sc, txq); } -static void ath_tx_complete_poll_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, - tx_complete_work.work); - struct ath_txq *txq; - int i; - bool needreset = false; -#ifdef CONFIG_ATH9K_DEBUGFS - sc->tx_complete_poll_work_seen++; -#endif - - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) - if (ATH_TXQ_SETUP(sc, i)) { - txq = &sc->tx.txq[i]; - ath_txq_lock(sc, txq); - if (txq->axq_depth) { - if (txq->axq_tx_inprogress) { - needreset = true; - ath_txq_unlock(sc, txq); - break; - } else { - txq->axq_tx_inprogress = true; - } - } - ath_txq_unlock_complete(sc, txq); - } - - if (needreset) { - ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, - "tx hung, resetting the chip\n"); - RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - } - - ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, - msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); -} - - - void ath_tx_tasklet(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; -- GitLab From af68abadac378f7a4a44fe766383e7b88c7f9c3b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:23:43 +0530 Subject: [PATCH 0828/6849] ath9k: Fix work handling * Currently, there is no synchronization between the reset work and the tx-poll work. Fix this and make sure that we bail out properly if a reset work is in progress. * Cleanup the PLL WAR and enable it for AR9340 too and use a helper for restarting work/timers after a reset. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/link.c | 33 +++++++++++++++----------- drivers/net/wireless/ath/ath9k/main.c | 22 +++++++++++++---- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d804416092ce..2faa181d8fcf 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -431,6 +431,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ #define ATH_PAPRD_TIMEOUT 100 /* msecs */ +#define ATH_PLL_WORK_INTERVAL 100 void ath_tx_complete_poll_work(struct work_struct *work); void ath_reset_work(struct work_struct *work); diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 7368b9630b99..89b38a9ab7c5 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -52,6 +52,7 @@ void ath_tx_complete_poll_work(struct work_struct *work) "tx hung, resetting the chip\n"); RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); + return; } ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, @@ -107,9 +108,9 @@ out: } /* - * PLL-WAR for AR9485. + * PLL-WAR for AR9485/AR9340 */ -static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) +static bool ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) { static int count; struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -117,29 +118,33 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) if (pll_sqsum >= 0x40000) { count++; if (count == 3) { - /* Rx is hung for more than 500ms. Reset it */ - ath_dbg(common, RESET, "Possible RX hang, resetting\n"); + ath_dbg(common, RESET, "PLL WAR, resetting the chip\n"); RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); count = 0; + return true; } - } else + } else { count = 0; + } + + return false; } void ath_hw_pll_work(struct work_struct *work) { + u32 pll_sqsum; struct ath_softc *sc = container_of(work, struct ath_softc, hw_pll_work.work); - u32 pll_sqsum; - if (AR_SREV_9485(sc->sc_ah)) { - ath9k_ps_wakeup(sc); - pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); - ath9k_ps_restore(sc); - ath_hw_pll_rx_hang_check(sc, pll_sqsum); - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); - } + ath9k_ps_wakeup(sc); + pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); + ath9k_ps_restore(sc); + if (ath_hw_pll_rx_hang_check(sc, pll_sqsum)) + return; + + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, + msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); } /* @@ -293,7 +298,7 @@ void ath_paprd_calibrate(struct work_struct *work) if (ar9003_paprd_create_curve(ah, caldata, chain)) { ath_dbg(common, CALIBRATE, "PAPRD create curve failed on chain %d\n", - chain); + chain); break; } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 304769a3e179..b228aff481e1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -158,6 +158,22 @@ static void ath_cancel_work(struct ath_softc *sc) cancel_work_sync(&sc->hw_reset_work); } +static void ath_restart_work(struct ath_softc *sc) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + + if (AR_SREV_9485(sc->sc_ah) || AR_SREV_9340(sc->sc_ah)) + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, + msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); + + ath_start_rx_poll(sc, 3); + + if (!common->disable_ani) + ath_start_ani(common); +} + static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) { struct ath_hw *ah = sc->sc_ah; @@ -209,11 +225,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) if (sc->sc_flags & SC_OP_BEACONS) ath_set_beacon(sc); - ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); - ath_start_rx_poll(sc, 3); - if (!common->disable_ani) - ath_start_ani(common); + ath_restart_work(sc); } if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { -- GitLab From 8da07830e10a91cbe7badf9767230aafdd520b9c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:23:49 +0530 Subject: [PATCH 0829/6849] ath9k: Move LNA code to antenna.c And use a helper function to setup antennae after a reset. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/antenna.c | 776 +++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ath9k.h | 7 +- drivers/net/wireless/ath/ath9k/main.c | 17 +- drivers/net/wireless/ath/ath9k/recv.c | 740 --------------------- 5 files changed, 786 insertions(+), 757 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/antenna.c diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4d60fa84cbb4..9c41232b0cd0 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -4,7 +4,8 @@ ath9k-y += beacon.o \ main.o \ recv.o \ xmit.o \ - link.o + link.o \ + antenna.o ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c new file mode 100644 index 000000000000..bbcfeb3b2a60 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/antenna.c @@ -0,0 +1,776 @@ +/* + * Copyright (c) 2012 Qualcomm Atheros, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ath9k.h" + +static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, + int mindelta, int main_rssi_avg, + int alt_rssi_avg, int pkt_count) +{ + return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + maxdelta)) || + (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); +} + +static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, + int curr_main_set, int curr_alt_set, + int alt_rssi_avg, int main_rssi_avg) +{ + bool result = false; + switch (div_group) { + case 0: + if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) + result = true; + break; + case 1: + case 2: + if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && + (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && + (alt_rssi_avg >= (main_rssi_avg - 5))) || + ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && + (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && + (alt_rssi_avg >= (main_rssi_avg - 2)))) && + (alt_rssi_avg >= 4)) + result = true; + else + result = false; + break; + } + + return result; +} + +static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, + struct ath_hw_antcomb_conf ant_conf, + int main_rssi_avg) +{ + antcomb->quick_scan_cnt = 0; + + if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = main_rssi_avg; + else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = main_rssi_avg; + + switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { + case 0x10: /* LNA2 A-B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; + break; + case 0x20: /* LNA1 A-B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; + break; + case 0x21: /* LNA1 LNA2 */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case 0x12: /* LNA2 LNA1 */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case 0x13: /* LNA2 A+B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; + break; + case 0x23: /* LNA1 A+B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; + break; + default: + break; + } +} + +static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, + struct ath_hw_antcomb_conf *div_ant_conf, + int main_rssi_avg, int alt_rssi_avg, + int alt_ratio) +{ + /* alt_good */ + switch (antcomb->quick_scan_cnt) { + case 0: + /* set alt to main, and alt to first conf */ + div_ant_conf->main_lna_conf = antcomb->main_conf; + div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; + break; + case 1: + /* set alt to main, and alt to first conf */ + div_ant_conf->main_lna_conf = antcomb->main_conf; + div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; + antcomb->rssi_first = main_rssi_avg; + antcomb->rssi_second = alt_rssi_avg; + + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { + /* main is LNA1 */ + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_HI, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_MID, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } else { + if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || + (alt_rssi_avg > main_rssi_avg)) && + (antcomb->total_pkt_count > 50)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } + break; + case 2: + antcomb->alt_good = false; + antcomb->scan_not_start = false; + antcomb->scan = false; + antcomb->rssi_first = main_rssi_avg; + antcomb->rssi_third = alt_rssi_avg; + + if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = alt_rssi_avg; + else if (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = alt_rssi_avg; + else if (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = main_rssi_avg; + else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = main_rssi_avg; + } + + if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) + div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; + else + div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; + + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_HI, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_MID, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } else { + if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || + (alt_rssi_avg > main_rssi_avg)) && + (antcomb->total_pkt_count > 50)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } + + /* set alt to the conf with maximun ratio */ + if (antcomb->first_ratio && antcomb->second_ratio) { + if (antcomb->rssi_second > antcomb->rssi_third) { + /* first alt*/ + if ((antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2*/ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->first_quick_scan_conf; + } else if ((antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) { + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } else { + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->second_quick_scan_conf; + } + } else if (antcomb->first_ratio) { + /* first alt */ + if ((antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->first_quick_scan_conf; + } else if (antcomb->second_ratio) { + /* second alt */ + if ((antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->second_quick_scan_conf; + } else { + /* main is largest */ + if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || + (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = antcomb->main_conf; + } + break; + default: + break; + } +} + +static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, + struct ath_ant_comb *antcomb, + int alt_ratio) +{ + if (ant_conf->div_group == 0) { + /* Adjust the fast_div_bias based on main and alt lna conf */ + switch ((ant_conf->main_lna_conf << 4) | + ant_conf->alt_lna_conf) { + case 0x01: /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x3b; + break; + case 0x02: /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x3d; + break; + case 0x03: /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + break; + case 0x10: /* LNA2 A-B */ + ant_conf->fast_div_bias = 0x7; + break; + case 0x12: /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x2; + break; + case 0x13: /* LNA2 A+B */ + ant_conf->fast_div_bias = 0x7; + break; + case 0x20: /* LNA1 A-B */ + ant_conf->fast_div_bias = 0x6; + break; + case 0x21: /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x0; + break; + case 0x23: /* LNA1 A+B */ + ant_conf->fast_div_bias = 0x6; + break; + case 0x30: /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + break; + case 0x31: /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x3b; + break; + case 0x32: /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x3d; + break; + default: + break; + } + } else if (ant_conf->div_group == 1) { + /* Adjust the fast_div_bias based on main and alt_lna_conf */ + switch ((ant_conf->main_lna_conf << 4) | + ant_conf->alt_lna_conf) { + case 0x01: /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x02: /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x03: /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x10: /* LNA2 A-B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x12: /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x13: /* LNA2 A+B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x20: /* LNA1 A-B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x21: /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x23: /* LNA1 A+B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x30: /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x31: /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x32: /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + default: + break; + } + } else if (ant_conf->div_group == 2) { + /* Adjust the fast_div_bias based on main and alt_lna_conf */ + switch ((ant_conf->main_lna_conf << 4) | + ant_conf->alt_lna_conf) { + case 0x01: /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x02: /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x03: /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x10: /* LNA2 A-B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x1; + else + ant_conf->fast_div_bias = 0x2; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x12: /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x13: /* LNA2 A+B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x1; + else + ant_conf->fast_div_bias = 0x2; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x20: /* LNA1 A-B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x1; + else + ant_conf->fast_div_bias = 0x2; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x21: /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x23: /* LNA1 A+B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x1; + else + ant_conf->fast_div_bias = 0x2; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x30: /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x31: /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x32: /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + default: + break; + } + } +} + +void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) +{ + struct ath_hw_antcomb_conf div_ant_conf; + struct ath_ant_comb *antcomb = &sc->ant_comb; + int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; + int curr_main_set; + int main_rssi = rs->rs_rssi_ctl0; + int alt_rssi = rs->rs_rssi_ctl1; + int rx_ant_conf, main_ant_conf; + bool short_scan = false; + + rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & + ATH_ANT_RX_MASK; + main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & + ATH_ANT_RX_MASK; + + /* Record packet only when both main_rssi and alt_rssi is positive */ + if (main_rssi > 0 && alt_rssi > 0) { + antcomb->total_pkt_count++; + antcomb->main_total_rssi += main_rssi; + antcomb->alt_total_rssi += alt_rssi; + if (main_ant_conf == rx_ant_conf) + antcomb->main_recv_cnt++; + else + antcomb->alt_recv_cnt++; + } + + /* Short scan check */ + if (antcomb->scan && antcomb->alt_good) { + if (time_after(jiffies, antcomb->scan_start_time + + msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) + short_scan = true; + else + if (antcomb->total_pkt_count == + ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { + alt_ratio = ((antcomb->alt_recv_cnt * 100) / + antcomb->total_pkt_count); + if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) + short_scan = true; + } + } + + if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || + rs->rs_moreaggr) && !short_scan) + return; + + if (antcomb->total_pkt_count) { + alt_ratio = ((antcomb->alt_recv_cnt * 100) / + antcomb->total_pkt_count); + main_rssi_avg = (antcomb->main_total_rssi / + antcomb->total_pkt_count); + alt_rssi_avg = (antcomb->alt_total_rssi / + antcomb->total_pkt_count); + } + + + ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); + curr_alt_set = div_ant_conf.alt_lna_conf; + curr_main_set = div_ant_conf.main_lna_conf; + + antcomb->count++; + + if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { + if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { + ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, + main_rssi_avg); + antcomb->alt_good = true; + } else { + antcomb->alt_good = false; + } + + antcomb->count = 0; + antcomb->scan = true; + antcomb->scan_not_start = true; + } + + if (!antcomb->scan) { + if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, + alt_ratio, curr_main_set, curr_alt_set, + alt_rssi_avg, main_rssi_avg)) { + if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { + /* Switch main and alt LNA */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + + goto div_comb_done; + } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && + (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { + /* Set alt to another LNA */ + if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + + goto div_comb_done; + } + + if ((alt_rssi_avg < (main_rssi_avg + + div_ant_conf.lna1_lna2_delta))) + goto div_comb_done; + } + + if (!antcomb->scan_not_start) { + switch (curr_alt_set) { + case ATH_ANT_DIV_COMB_LNA2: + antcomb->rssi_lna2 = alt_rssi_avg; + antcomb->rssi_lna1 = main_rssi_avg; + antcomb->scan = true; + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1: + antcomb->rssi_lna1 = alt_rssi_avg; + antcomb->rssi_lna2 = main_rssi_avg; + antcomb->scan = true; + /* set to A+B */ + div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: + antcomb->rssi_add = alt_rssi_avg; + antcomb->scan = true; + /* set to A-B */ + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: + antcomb->rssi_sub = alt_rssi_avg; + antcomb->scan = false; + if (antcomb->rssi_lna2 > + (antcomb->rssi_lna1 + + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { + /* use LNA2 as main LNA */ + if ((antcomb->rssi_add > antcomb->rssi_lna1) && + (antcomb->rssi_add > antcomb->rssi_sub)) { + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + } else if (antcomb->rssi_sub > + antcomb->rssi_lna1) { + /* set to A-B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + } else { + /* set to LNA1 */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } + } else { + /* use LNA1 as main LNA */ + if ((antcomb->rssi_add > antcomb->rssi_lna2) && + (antcomb->rssi_add > antcomb->rssi_sub)) { + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + } else if (antcomb->rssi_sub > + antcomb->rssi_lna1) { + /* set to A-B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + } else { + /* set to LNA2 */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + } + break; + default: + break; + } + } else { + if (!antcomb->alt_good) { + antcomb->scan_not_start = false; + /* Set alt to another LNA */ + if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + goto div_comb_done; + } + } + + ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, + main_rssi_avg, alt_rssi_avg, + alt_ratio); + + antcomb->quick_scan_cnt++; + +div_comb_done: + ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); + ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); + + antcomb->scan_start_time = jiffies; + antcomb->total_pkt_count = 0; + antcomb->main_total_rssi = 0; + antcomb->alt_total_rssi = 0; + antcomb->main_recv_cnt = 0; + antcomb->alt_recv_cnt = 0; +} + +void ath_ant_comb_update(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_hw_antcomb_conf div_ant_conf; + u8 lna_conf; + + ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); + + if (sc->ant_rx == 1) + lna_conf = ATH_ANT_DIV_COMB_LNA1; + else + lna_conf = ATH_ANT_DIV_COMB_LNA2; + + div_ant_conf.main_lna_conf = lna_conf; + div_ant_conf.alt_lna_conf = lna_conf; + + ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); +} diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 2faa181d8fcf..4c2ce453af22 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -528,8 +528,10 @@ static inline void ath_deinit_leds(struct ath_softc *sc) } #endif - +/*******************************/ /* Antenna diversity/combining */ +/*******************************/ + #define ATH_ANT_RX_CURRENT_SHIFT 4 #define ATH_ANT_RX_MAIN_SHIFT 2 #define ATH_ANT_RX_MASK 0x3 @@ -582,6 +584,9 @@ struct ath_ant_comb { unsigned long scan_start_time; }; +void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); +void ath_ant_comb_update(struct ath_softc *sc); + /********************/ /* Main driver core */ /********************/ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b228aff481e1..66f215ca9969 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -228,21 +228,8 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath_restart_work(sc); } - if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { - struct ath_hw_antcomb_conf div_ant_conf; - u8 lna_conf; - - ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); - - if (sc->ant_rx == 1) - lna_conf = ATH_ANT_DIV_COMB_LNA1; - else - lna_conf = ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.main_lna_conf = lna_conf; - div_ant_conf.alt_lna_conf = lna_conf; - - ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); - } + if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) + ath_ant_comb_update(sc); ieee80211_wake_queues(sc->hw); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 611be4f934e7..c2f5fd1c8b87 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -20,43 +20,6 @@ #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) -static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, - int mindelta, int main_rssi_avg, - int alt_rssi_avg, int pkt_count) -{ - return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && - (alt_rssi_avg > main_rssi_avg + maxdelta)) || - (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); -} - -static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, - int curr_main_set, int curr_alt_set, - int alt_rssi_avg, int main_rssi_avg) -{ - bool result = false; - switch (div_group) { - case 0: - if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) - result = true; - break; - case 1: - case 2: - if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && - (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && - (alt_rssi_avg >= (main_rssi_avg - 5))) || - ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && - (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && - (alt_rssi_avg >= (main_rssi_avg - 2)))) && - (alt_rssi_avg >= 4)) - result = true; - else - result = false; - break; - } - - return result; -} - static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) { return sc->ps_enabled && @@ -1067,709 +1030,6 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, rxs->flag &= ~RX_FLAG_DECRYPTED; } -static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, - struct ath_hw_antcomb_conf ant_conf, - int main_rssi_avg) -{ - antcomb->quick_scan_cnt = 0; - - if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) - antcomb->rssi_lna2 = main_rssi_avg; - else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) - antcomb->rssi_lna1 = main_rssi_avg; - - switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { - case 0x10: /* LNA2 A-B */ - antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - antcomb->first_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; - break; - case 0x20: /* LNA1 A-B */ - antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - antcomb->first_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; - break; - case 0x21: /* LNA1 LNA2 */ - antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; - antcomb->first_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - antcomb->second_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - break; - case 0x12: /* LNA2 LNA1 */ - antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; - antcomb->first_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - antcomb->second_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - break; - case 0x13: /* LNA2 A+B */ - antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - antcomb->first_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; - break; - case 0x23: /* LNA1 A+B */ - antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - antcomb->first_quick_scan_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; - break; - default: - break; - } -} - -static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, - struct ath_hw_antcomb_conf *div_ant_conf, - int main_rssi_avg, int alt_rssi_avg, - int alt_ratio) -{ - /* alt_good */ - switch (antcomb->quick_scan_cnt) { - case 0: - /* set alt to main, and alt to first conf */ - div_ant_conf->main_lna_conf = antcomb->main_conf; - div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; - break; - case 1: - /* set alt to main, and alt to first conf */ - div_ant_conf->main_lna_conf = antcomb->main_conf; - div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; - antcomb->rssi_first = main_rssi_avg; - antcomb->rssi_second = alt_rssi_avg; - - if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { - /* main is LNA1 */ - if (ath_is_alt_ant_ratio_better(alt_ratio, - ATH_ANT_DIV_COMB_LNA1_DELTA_HI, - ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, - main_rssi_avg, alt_rssi_avg, - antcomb->total_pkt_count)) - antcomb->first_ratio = true; - else - antcomb->first_ratio = false; - } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { - if (ath_is_alt_ant_ratio_better(alt_ratio, - ATH_ANT_DIV_COMB_LNA1_DELTA_MID, - ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, - main_rssi_avg, alt_rssi_avg, - antcomb->total_pkt_count)) - antcomb->first_ratio = true; - else - antcomb->first_ratio = false; - } else { - if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && - (alt_rssi_avg > main_rssi_avg + - ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || - (alt_rssi_avg > main_rssi_avg)) && - (antcomb->total_pkt_count > 50)) - antcomb->first_ratio = true; - else - antcomb->first_ratio = false; - } - break; - case 2: - antcomb->alt_good = false; - antcomb->scan_not_start = false; - antcomb->scan = false; - antcomb->rssi_first = main_rssi_avg; - antcomb->rssi_third = alt_rssi_avg; - - if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) - antcomb->rssi_lna1 = alt_rssi_avg; - else if (antcomb->second_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA2) - antcomb->rssi_lna2 = alt_rssi_avg; - else if (antcomb->second_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { - if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) - antcomb->rssi_lna2 = main_rssi_avg; - else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) - antcomb->rssi_lna1 = main_rssi_avg; - } - - if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + - ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) - div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; - else - div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; - - if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { - if (ath_is_alt_ant_ratio_better(alt_ratio, - ATH_ANT_DIV_COMB_LNA1_DELTA_HI, - ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, - main_rssi_avg, alt_rssi_avg, - antcomb->total_pkt_count)) - antcomb->second_ratio = true; - else - antcomb->second_ratio = false; - } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { - if (ath_is_alt_ant_ratio_better(alt_ratio, - ATH_ANT_DIV_COMB_LNA1_DELTA_MID, - ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, - main_rssi_avg, alt_rssi_avg, - antcomb->total_pkt_count)) - antcomb->second_ratio = true; - else - antcomb->second_ratio = false; - } else { - if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && - (alt_rssi_avg > main_rssi_avg + - ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || - (alt_rssi_avg > main_rssi_avg)) && - (antcomb->total_pkt_count > 50)) - antcomb->second_ratio = true; - else - antcomb->second_ratio = false; - } - - /* set alt to the conf with maximun ratio */ - if (antcomb->first_ratio && antcomb->second_ratio) { - if (antcomb->rssi_second > antcomb->rssi_third) { - /* first alt*/ - if ((antcomb->first_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA1) || - (antcomb->first_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA2)) - /* Set alt LNA1 or LNA2*/ - if (div_ant_conf->main_lna_conf == - ATH_ANT_DIV_COMB_LNA2) - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - else - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - else - /* Set alt to A+B or A-B */ - div_ant_conf->alt_lna_conf = - antcomb->first_quick_scan_conf; - } else if ((antcomb->second_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA1) || - (antcomb->second_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA2)) { - /* Set alt LNA1 or LNA2 */ - if (div_ant_conf->main_lna_conf == - ATH_ANT_DIV_COMB_LNA2) - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - else - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - } else { - /* Set alt to A+B or A-B */ - div_ant_conf->alt_lna_conf = - antcomb->second_quick_scan_conf; - } - } else if (antcomb->first_ratio) { - /* first alt */ - if ((antcomb->first_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA1) || - (antcomb->first_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA2)) - /* Set alt LNA1 or LNA2 */ - if (div_ant_conf->main_lna_conf == - ATH_ANT_DIV_COMB_LNA2) - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - else - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - else - /* Set alt to A+B or A-B */ - div_ant_conf->alt_lna_conf = - antcomb->first_quick_scan_conf; - } else if (antcomb->second_ratio) { - /* second alt */ - if ((antcomb->second_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA1) || - (antcomb->second_quick_scan_conf == - ATH_ANT_DIV_COMB_LNA2)) - /* Set alt LNA1 or LNA2 */ - if (div_ant_conf->main_lna_conf == - ATH_ANT_DIV_COMB_LNA2) - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - else - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - else - /* Set alt to A+B or A-B */ - div_ant_conf->alt_lna_conf = - antcomb->second_quick_scan_conf; - } else { - /* main is largest */ - if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || - (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) - /* Set alt LNA1 or LNA2 */ - if (div_ant_conf->main_lna_conf == - ATH_ANT_DIV_COMB_LNA2) - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - else - div_ant_conf->alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - else - /* Set alt to A+B or A-B */ - div_ant_conf->alt_lna_conf = antcomb->main_conf; - } - break; - default: - break; - } -} - -static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, - struct ath_ant_comb *antcomb, int alt_ratio) -{ - if (ant_conf->div_group == 0) { - /* Adjust the fast_div_bias based on main and alt lna conf */ - switch ((ant_conf->main_lna_conf << 4) | - ant_conf->alt_lna_conf) { - case 0x01: /* A-B LNA2 */ - ant_conf->fast_div_bias = 0x3b; - break; - case 0x02: /* A-B LNA1 */ - ant_conf->fast_div_bias = 0x3d; - break; - case 0x03: /* A-B A+B */ - ant_conf->fast_div_bias = 0x1; - break; - case 0x10: /* LNA2 A-B */ - ant_conf->fast_div_bias = 0x7; - break; - case 0x12: /* LNA2 LNA1 */ - ant_conf->fast_div_bias = 0x2; - break; - case 0x13: /* LNA2 A+B */ - ant_conf->fast_div_bias = 0x7; - break; - case 0x20: /* LNA1 A-B */ - ant_conf->fast_div_bias = 0x6; - break; - case 0x21: /* LNA1 LNA2 */ - ant_conf->fast_div_bias = 0x0; - break; - case 0x23: /* LNA1 A+B */ - ant_conf->fast_div_bias = 0x6; - break; - case 0x30: /* A+B A-B */ - ant_conf->fast_div_bias = 0x1; - break; - case 0x31: /* A+B LNA2 */ - ant_conf->fast_div_bias = 0x3b; - break; - case 0x32: /* A+B LNA1 */ - ant_conf->fast_div_bias = 0x3d; - break; - default: - break; - } - } else if (ant_conf->div_group == 1) { - /* Adjust the fast_div_bias based on main and alt_lna_conf */ - switch ((ant_conf->main_lna_conf << 4) | - ant_conf->alt_lna_conf) { - case 0x01: /* A-B LNA2 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x02: /* A-B LNA1 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x03: /* A-B A+B */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x10: /* LNA2 A-B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x3f; - else - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x12: /* LNA2 LNA1 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x13: /* LNA2 A+B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x3f; - else - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x20: /* LNA1 A-B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x3f; - else - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x21: /* LNA1 LNA2 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x23: /* LNA1 A+B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x3f; - else - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x30: /* A+B A-B */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x31: /* A+B LNA2 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x32: /* A+B LNA1 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - default: - break; - } - } else if (ant_conf->div_group == 2) { - /* Adjust the fast_div_bias based on main and alt_lna_conf */ - switch ((ant_conf->main_lna_conf << 4) | - ant_conf->alt_lna_conf) { - case 0x01: /* A-B LNA2 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x02: /* A-B LNA1 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x03: /* A-B A+B */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x10: /* LNA2 A-B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x1; - else - ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x12: /* LNA2 LNA1 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x13: /* LNA2 A+B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x1; - else - ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x20: /* LNA1 A-B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x1; - else - ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x21: /* LNA1 LNA2 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x23: /* LNA1 A+B */ - if (!(antcomb->scan) && - (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) - ant_conf->fast_div_bias = 0x1; - else - ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x30: /* A+B A-B */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x31: /* A+B LNA2 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - case 0x32: /* A+B LNA1 */ - ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; - break; - default: - break; - } - } -} - -/* Antenna diversity and combining */ -static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) -{ - struct ath_hw_antcomb_conf div_ant_conf; - struct ath_ant_comb *antcomb = &sc->ant_comb; - int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; - int curr_main_set; - int main_rssi = rs->rs_rssi_ctl0; - int alt_rssi = rs->rs_rssi_ctl1; - int rx_ant_conf, main_ant_conf; - bool short_scan = false; - - rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & - ATH_ANT_RX_MASK; - main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & - ATH_ANT_RX_MASK; - - /* Record packet only when both main_rssi and alt_rssi is positive */ - if (main_rssi > 0 && alt_rssi > 0) { - antcomb->total_pkt_count++; - antcomb->main_total_rssi += main_rssi; - antcomb->alt_total_rssi += alt_rssi; - if (main_ant_conf == rx_ant_conf) - antcomb->main_recv_cnt++; - else - antcomb->alt_recv_cnt++; - } - - /* Short scan check */ - if (antcomb->scan && antcomb->alt_good) { - if (time_after(jiffies, antcomb->scan_start_time + - msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) - short_scan = true; - else - if (antcomb->total_pkt_count == - ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { - alt_ratio = ((antcomb->alt_recv_cnt * 100) / - antcomb->total_pkt_count); - if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) - short_scan = true; - } - } - - if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || - rs->rs_moreaggr) && !short_scan) - return; - - if (antcomb->total_pkt_count) { - alt_ratio = ((antcomb->alt_recv_cnt * 100) / - antcomb->total_pkt_count); - main_rssi_avg = (antcomb->main_total_rssi / - antcomb->total_pkt_count); - alt_rssi_avg = (antcomb->alt_total_rssi / - antcomb->total_pkt_count); - } - - - ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); - curr_alt_set = div_ant_conf.alt_lna_conf; - curr_main_set = div_ant_conf.main_lna_conf; - - antcomb->count++; - - if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { - if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { - ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, - main_rssi_avg); - antcomb->alt_good = true; - } else { - antcomb->alt_good = false; - } - - antcomb->count = 0; - antcomb->scan = true; - antcomb->scan_not_start = true; - } - - if (!antcomb->scan) { - if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, - alt_ratio, curr_main_set, curr_alt_set, - alt_rssi_avg, main_rssi_avg)) { - if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { - /* Switch main and alt LNA */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - } - - goto div_comb_done; - } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && - (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { - /* Set alt to another LNA */ - if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - - goto div_comb_done; - } - - if ((alt_rssi_avg < (main_rssi_avg + - div_ant_conf.lna1_lna2_delta))) - goto div_comb_done; - } - - if (!antcomb->scan_not_start) { - switch (curr_alt_set) { - case ATH_ANT_DIV_COMB_LNA2: - antcomb->rssi_lna2 = alt_rssi_avg; - antcomb->rssi_lna1 = main_rssi_avg; - antcomb->scan = true; - /* set to A+B */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - break; - case ATH_ANT_DIV_COMB_LNA1: - antcomb->rssi_lna1 = alt_rssi_avg; - antcomb->rssi_lna2 = main_rssi_avg; - antcomb->scan = true; - /* set to A+B */ - div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - break; - case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: - antcomb->rssi_add = alt_rssi_avg; - antcomb->scan = true; - /* set to A-B */ - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - break; - case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: - antcomb->rssi_sub = alt_rssi_avg; - antcomb->scan = false; - if (antcomb->rssi_lna2 > - (antcomb->rssi_lna1 + - ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { - /* use LNA2 as main LNA */ - if ((antcomb->rssi_add > antcomb->rssi_lna1) && - (antcomb->rssi_add > antcomb->rssi_sub)) { - /* set to A+B */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - } else if (antcomb->rssi_sub > - antcomb->rssi_lna1) { - /* set to A-B */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - } else { - /* set to LNA1 */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - } - } else { - /* use LNA1 as main LNA */ - if ((antcomb->rssi_add > antcomb->rssi_lna2) && - (antcomb->rssi_add > antcomb->rssi_sub)) { - /* set to A+B */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; - } else if (antcomb->rssi_sub > - antcomb->rssi_lna1) { - /* set to A-B */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; - } else { - /* set to LNA2 */ - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - } - } - break; - default: - break; - } - } else { - if (!antcomb->alt_good) { - antcomb->scan_not_start = false; - /* Set alt to another LNA */ - if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { - div_ant_conf.main_lna_conf = - ATH_ANT_DIV_COMB_LNA1; - div_ant_conf.alt_lna_conf = - ATH_ANT_DIV_COMB_LNA2; - } - goto div_comb_done; - } - } - - ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, - main_rssi_avg, alt_rssi_avg, - alt_ratio); - - antcomb->quick_scan_cnt++; - -div_comb_done: - ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); - ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); - - antcomb->scan_start_time = jiffies; - antcomb->total_pkt_count = 0; - antcomb->main_total_rssi = 0; - antcomb->alt_total_rssi = 0; - antcomb->main_recv_cnt = 0; - antcomb->alt_recv_cnt = 0; -} - int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) { struct ath_buf *bf; -- GitLab From 781b14a3153a722fec820374271316537881076e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:23:55 +0530 Subject: [PATCH 0830/6849] ath9k: Use atomic operations The 'sc_flags' variable is being used in a number of places with no locking whatsoever. This patch converts the usage of sc_flags to atomic ops. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ahb.c | 2 +- drivers/net/wireless/ath/ath9k/ath9k.h | 16 +++++----- drivers/net/wireless/ath/ath9k/beacon.c | 18 +++++------ drivers/net/wireless/ath/ath9k/debug.c | 6 ++-- drivers/net/wireless/ath/ath9k/link.c | 4 +-- drivers/net/wireless/ath/ath9k/main.c | 42 ++++++++++++------------- drivers/net/wireless/ath/ath9k/pci.c | 2 +- drivers/net/wireless/ath/ath9k/recv.c | 10 +++--- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 9 files changed, 52 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 5e47ca6d16a8..4a4e8a2b9d2c 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -126,7 +126,7 @@ static int ath_ahb_probe(struct platform_device *pdev) sc->irq = irq; /* Will be cleared in ath9k_start() */ - sc->sc_flags |= SC_OP_INVALID; + set_bit(SC_OP_INVALID, &sc->sc_flags); ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); if (ret) { diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4c2ce453af22..ae43de1cbb03 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -604,12 +604,14 @@ void ath_ant_comb_update(struct ath_softc *sc); #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ #define ATH_RATE_DUMMY_MARKER 0 -#define SC_OP_INVALID BIT(0) -#define SC_OP_BEACONS BIT(1) -#define SC_OP_RXFLUSH BIT(2) -#define SC_OP_TSF_RESET BIT(3) -#define SC_OP_ANI_RUN BIT(4) -#define SC_OP_PRIM_STA_VIF BIT(5) +enum sc_op_flags { + SC_OP_INVALID, + SC_OP_BEACONS, + SC_OP_RXFLUSH, + SC_OP_TSF_RESET, + SC_OP_ANI_RUN, + SC_OP_PRIM_STA_VIF, +}; /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) @@ -655,9 +657,9 @@ struct ath_softc { struct completion paprd_complete; unsigned int hw_busy_count; + unsigned long sc_flags; u32 intrstatus; - u32 sc_flags; /* SC_OP_* */ u16 ps_flags; /* PS_* */ u16 curtxpow; bool ps_enabled; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 70b802529123..40775da8941e 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -390,7 +390,7 @@ void ath_beacon_tasklet(unsigned long data) } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); sc->beacon.bmisscnt = 0; - sc->sc_flags |= SC_OP_TSF_RESET; + set_bit(SC_OP_TSF_RESET, &sc->sc_flags); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); } @@ -480,16 +480,16 @@ static void ath9k_beacon_init(struct ath_softc *sc, u32 next_beacon, u32 beacon_period) { - if (sc->sc_flags & SC_OP_TSF_RESET) { + if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { ath9k_ps_wakeup(sc); ath9k_hw_reset_tsf(sc->sc_ah); } ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); - if (sc->sc_flags & SC_OP_TSF_RESET) { + if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { ath9k_ps_restore(sc); - sc->sc_flags &= ~SC_OP_TSF_RESET; + clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); } } @@ -519,7 +519,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, /* Set the computed AP beacon timers */ ath9k_hw_disable_interrupts(ah); - sc->sc_flags |= SC_OP_TSF_RESET; + set_bit(SC_OP_TSF_RESET, &sc->sc_flags); ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah); @@ -662,7 +662,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, u32 tsf, intval, nexttbtt; ath9k_reset_beacon_status(sc); - if (!(sc->sc_flags & SC_OP_BEACONS)) + if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp); intval = TU_TO_USEC(conf->beacon_interval); @@ -727,7 +727,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, */ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && (vif->type == NL80211_IFTYPE_STATION) && - (sc->sc_flags & SC_OP_BEACONS) && + test_bit(SC_OP_BEACONS, &sc->sc_flags) && !avp->primary_sta_vif) { ath_dbg(common, CONFIG, "Beacon already configured for a station interface\n"); @@ -813,7 +813,7 @@ void ath_set_beacon(struct ath_softc *sc) return; } - sc->sc_flags |= SC_OP_BEACONS; + set_bit(SC_OP_BEACONS, &sc->sc_flags); } void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) @@ -821,7 +821,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) struct ath_hw *ah = sc->sc_ah; if (!ath_has_valid_bslot(sc)) { - sc->sc_flags &= ~SC_OP_BEACONS; + clear_bit(SC_OP_BEACONS, &sc->sc_flags); return; } diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c134ddaa10a1..2831258d9507 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -205,10 +205,10 @@ static ssize_t write_file_disable_ani(struct file *file, common->disable_ani = !!disable_ani; if (disable_ani) { - sc->sc_flags &= ~SC_OP_ANI_RUN; + clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); del_timer_sync(&common->ani.timer); } else { - sc->sc_flags |= SC_OP_ANI_RUN; + set_bit(SC_OP_ANI_RUN, &sc->sc_flags); ath_start_ani(common); } @@ -1321,7 +1321,7 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file) u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; u8 nread; - if (sc->sc_flags & SC_OP_INVALID) + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) return -EAGAIN; buf = vmalloc(size); diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 89b38a9ab7c5..0cc4c70f7f0c 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -155,7 +155,7 @@ void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) if (!AR_SREV_9300(sc->sc_ah)) return; - if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) + if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) return; mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies @@ -430,7 +430,7 @@ void ath_start_ani(struct ath_common *common) unsigned long timestamp = jiffies_to_msecs(jiffies); struct ath_softc *sc = (struct ath_softc *) common->priv; - if (!(sc->sc_flags & SC_OP_ANI_RUN)) + if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) return; if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 66f215ca9969..e4f7d0ea5f20 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -222,7 +222,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath9k_hw_enable_interrupts(ah); if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { - if (sc->sc_flags & SC_OP_BEACONS) + if (test_bit(SC_OP_BEACONS, &sc->sc_flags)) ath_set_beacon(sc); ath_restart_work(sc); @@ -293,7 +293,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, { int r; - if (sc->sc_flags & SC_OP_INVALID) + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) return -EIO; r = ath_reset_internal(sc, hchan, false); @@ -435,7 +435,7 @@ irqreturn_t ath_isr(int irq, void *dev) * touch anything. Note this can happen early * on if the IRQ is shared. */ - if (sc->sc_flags & SC_OP_INVALID) + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) return IRQ_NONE; @@ -635,7 +635,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ath_mci_enable(sc); - sc->sc_flags &= ~SC_OP_INVALID; + clear_bit(SC_OP_INVALID, &sc->sc_flags); sc->sc_ah->is_monitoring = false; if (!ath_complete_reset(sc, false)) { @@ -754,7 +754,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath_cancel_work(sc); del_timer_sync(&sc->rx_poll_timer); - if (sc->sc_flags & SC_OP_INVALID) { + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { ath_dbg(common, ANY, "Device not present\n"); mutex_unlock(&sc->mutex); return; @@ -811,7 +811,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath9k_ps_restore(sc); - sc->sc_flags |= SC_OP_INVALID; + set_bit(SC_OP_INVALID, &sc->sc_flags); sc->ps_idle = prev_idle; mutex_unlock(&sc->mutex); @@ -915,11 +915,11 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, /* Set op-mode & TSF */ if (iter_data.naps > 0) { ath9k_hw_set_tsfadjust(ah, 1); - sc->sc_flags |= SC_OP_TSF_RESET; + set_bit(SC_OP_TSF_RESET, &sc->sc_flags); ah->opmode = NL80211_IFTYPE_AP; } else { ath9k_hw_set_tsfadjust(ah, 0); - sc->sc_flags &= ~SC_OP_TSF_RESET; + clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); if (iter_data.nmeshes) ah->opmode = NL80211_IFTYPE_MESH_POINT; @@ -950,12 +950,12 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; if (!common->disable_ani) { - sc->sc_flags |= SC_OP_ANI_RUN; + set_bit(SC_OP_ANI_RUN, &sc->sc_flags); ath_start_ani(common); } } else { - sc->sc_flags &= ~SC_OP_ANI_RUN; + clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); del_timer_sync(&common->ani.timer); } } @@ -1479,11 +1479,11 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) * Skip iteration if primary station vif's bss info * was not changed */ - if (sc->sc_flags & SC_OP_PRIM_STA_VIF) + if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) return; if (bss_conf->assoc) { - sc->sc_flags |= SC_OP_PRIM_STA_VIF; + set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); avp->primary_sta_vif = true; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); common->curaid = bss_conf->aid; @@ -1504,7 +1504,7 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) ath_start_rx_poll(sc, 3); if (!common->disable_ani) { - sc->sc_flags |= SC_OP_ANI_RUN; + set_bit(SC_OP_ANI_RUN, &sc->sc_flags); ath_start_ani(common); } @@ -1524,7 +1524,8 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) if (avp->primary_sta_vif && !bss_conf->assoc) { ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", common->curaid, common->curbssid); - sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); + clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); + clear_bit(SC_OP_BEACONS, &sc->sc_flags); avp->primary_sta_vif = false; memset(common->curbssid, 0, ETH_ALEN); common->curaid = 0; @@ -1537,10 +1538,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) * None of station vifs are associated. * Clear bssid & aid */ - if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { + if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { ath9k_hw_write_associd(sc->sc_ah); - /* Stop ANI */ - sc->sc_flags &= ~SC_OP_ANI_RUN; + clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); del_timer_sync(&common->ani.timer); del_timer_sync(&sc->rx_poll_timer); memset(&sc->caldata, 0, sizeof(sc->caldata)); @@ -1578,12 +1578,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; if (!common->disable_ani) { - sc->sc_flags |= SC_OP_ANI_RUN; + set_bit(SC_OP_ANI_RUN, &sc->sc_flags); ath_start_ani(common); } } else { - sc->sc_flags &= ~SC_OP_ANI_RUN; + clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); del_timer_sync(&common->ani.timer); del_timer_sync(&sc->rx_poll_timer); } @@ -1595,7 +1595,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, */ if ((changed & BSS_CHANGED_BEACON_INT) && (vif->type == NL80211_IFTYPE_AP)) - sc->sc_flags |= SC_OP_TSF_RESET; + set_bit(SC_OP_TSF_RESET, &sc->sc_flags); /* Configure beaconing (AP, IBSS, MESH) */ if (ath9k_uses_beacons(vif->type) && @@ -1787,7 +1787,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) return; } - if (sc->sc_flags & SC_OP_INVALID) { + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { ath_dbg(common, ANY, "Device not present\n"); mutex_unlock(&sc->mutex); return; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 6ec9f88712d0..aa0e83ac51f4 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -251,7 +251,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) sc->mem = mem; /* Will be cleared in ath9k_start() */ - sc->sc_flags |= SC_OP_INVALID; + set_bit(SC_OP_INVALID, &sc->sc_flags); ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); if (ret) { diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c2f5fd1c8b87..b54e15941ba4 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -285,8 +285,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) int error = 0; spin_lock_init(&sc->sc_pcu_lock); - sc->sc_flags &= ~SC_OP_RXFLUSH; spin_lock_init(&sc->rx.rxbuflock); + clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + sc->sc_ah->caps.rx_status_len; @@ -498,11 +498,11 @@ bool ath_stoprecv(struct ath_softc *sc) void ath_flushrecv(struct ath_softc *sc) { - sc->sc_flags |= SC_OP_RXFLUSH; + set_bit(SC_OP_RXFLUSH, &sc->sc_flags); if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ath_rx_tasklet(sc, 1, true); ath_rx_tasklet(sc, 1, false); - sc->sc_flags &= ~SC_OP_RXFLUSH; + clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); } static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) @@ -1063,7 +1063,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) do { /* If handling rx interrupt and flush is in progress => exit */ - if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) + if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) break; memset(&rs, 0, sizeof(rs)); @@ -1108,7 +1108,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) * If we're asked to flush receive queue, directly * chain it back at the queue without processing it. */ - if (sc->sc_flags & SC_OP_RXFLUSH) { + if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { RX_STAT_INC(rx_drop_rxflush); goto requeue_drop_frag; } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6619a39b8c27..bb74780903d5 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1536,7 +1536,7 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) int i; u32 npend = 0; - if (sc->sc_flags & SC_OP_INVALID) + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) return true; ath9k_hw_abort_tx_dma(ah); -- GitLab From b74713d04effbacd3d126ce94cec18742187b6ce Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:24:01 +0530 Subject: [PATCH 0831/6849] ath9k: Handle fatal interrupts properly When a fatal interrupt is received or it is detected that the baseband has hung, the chip has to be reset immediately. Otherwise, we end up processing spurious interrupts. Ensure that we bail out properly in the ISR when the reset work hasn't completed yet. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index ae43de1cbb03..02fc1c1e5eeb 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -611,6 +611,7 @@ enum sc_op_flags { SC_OP_TSF_RESET, SC_OP_ANI_RUN, SC_OP_PRIM_STA_VIF, + SC_OP_HW_RESET, }; /* Powersave flags */ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e4f7d0ea5f20..34d6f26c6bc7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -218,6 +218,8 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath9k_cmn_update_txpow(ah, sc->curtxpow, sc->config.txpowlimit, &sc->curtxpow); + + clear_bit(SC_OP_HW_RESET, &sc->sc_flags); ath9k_hw_set_interrupts(ah); ath9k_hw_enable_interrupts(ah); @@ -362,6 +364,7 @@ void ath9k_tasklet(unsigned long data) RESET_STAT_INC(sc, type); #endif + set_bit(SC_OP_HW_RESET, &sc->sc_flags); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); goto out; } @@ -438,12 +441,14 @@ irqreturn_t ath_isr(int irq, void *dev) if (test_bit(SC_OP_INVALID, &sc->sc_flags)) return IRQ_NONE; - /* shared irq, not for us */ if (!ath9k_hw_intrpend(ah)) return IRQ_NONE; + if(test_bit(SC_OP_HW_RESET, &sc->sc_flags)) + return IRQ_HANDLED; + /* * Figure out the reason(s) for the interrupt. Note * that the hal returns a pseudo-ISR that may include -- GitLab From 07c15a3ffd68ff1a3276daa26885b277f19e4abd Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:24:07 +0530 Subject: [PATCH 0832/6849] ath9k: Fix powersave locking The 'ps_flags' is used/accessed in a variety of contexts and requires proper locking. Use 'sc_pm_lock' appropriately. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 14 ++++++++++++-- drivers/net/wireless/ath/ath9k/recv.c | 13 ++++++------- drivers/net/wireless/ath/ath9k/xmit.c | 3 +++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 34d6f26c6bc7..88f7ad106e05 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -345,7 +345,7 @@ void ath9k_tasklet(unsigned long data) struct ath_softc *sc = (struct ath_softc *)data; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - + unsigned long flags; u32 status = sc->intrstatus; u32 rxmask; @@ -369,6 +369,7 @@ void ath9k_tasklet(unsigned long data) goto out; } + spin_lock_irqsave(&sc->sc_pm_lock, flags); if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { /* * TSF sync does not look correct; remain awake to sync with @@ -377,6 +378,7 @@ void ath9k_tasklet(unsigned long data) ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n"); sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; } + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | @@ -526,8 +528,10 @@ irqreturn_t ath_isr(int irq, void *dev) /* Clear RxAbort bit so that we can * receive frames */ ath9k_setpower(sc, ATH9K_PM_AWAKE); + spin_lock(&sc->sc_pm_lock); ath9k_hw_setrxabort(sc->sc_ah, 0); sc->ps_flags |= PS_WAIT_FOR_BEACON; + spin_unlock(&sc->sc_pm_lock); } chip_reset: @@ -682,6 +686,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_tx_control txctl; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + unsigned long flags; if (sc->ps_enabled) { /* @@ -704,6 +709,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * completed and if needed, also for RX of buffered frames. */ ath9k_ps_wakeup(sc); + spin_lock_irqsave(&sc->sc_pm_lock, flags); if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) ath9k_hw_setrxabort(sc->sc_ah, 0); if (ieee80211_is_pspoll(hdr->frame_control)) { @@ -719,6 +725,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * the ps_flags bit is cleared. We are just dropping * the ps_usecount here. */ + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); ath9k_ps_restore(sc); } @@ -1479,7 +1486,7 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct ath_vif *avp = (void *)vif->drv_priv; - + unsigned long flags; /* * Skip iteration if primary station vif's bss info * was not changed @@ -1501,7 +1508,10 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) * on the receipt of the first Beacon frame (i.e., * after time sync with the AP). */ + spin_lock_irqsave(&sc->sc_pm_lock, flags); sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + /* Reset rssi stats */ sc->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index b54e15941ba4..fbdcc80437fe 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -587,13 +587,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) /* Process Beacon and CAB receive in PS state */ if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc)) - && mybeacon) + && mybeacon) { ath_rx_ps_beacon(sc, skb); - else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && - (ieee80211_is_data(hdr->frame_control) || - ieee80211_is_action(hdr->frame_control)) && - is_multicast_ether_addr(hdr->addr1) && - !ieee80211_has_moredata(hdr->frame_control)) { + } else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && + (ieee80211_is_data(hdr->frame_control) || + ieee80211_is_action(hdr->frame_control)) && + is_multicast_ether_addr(hdr->addr1) && + !ieee80211_has_moredata(hdr->frame_control)) { /* * No more broadcast/multicast frames to be received at this * point. @@ -1229,7 +1229,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) skb_trim(skb, skb->len - 8); spin_lock_irqsave(&sc->sc_pm_lock, flags); - if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA)) || diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index bb74780903d5..f777ddcd1172 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1994,6 +1994,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; int q, padpos, padsize; + unsigned long flags; ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); @@ -2012,6 +2013,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, skb_pull(skb, padsize); } + spin_lock_irqsave(&sc->sc_pm_lock, flags); if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; ath_dbg(common, PS, @@ -2021,6 +2023,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, PS_WAIT_FOR_PSPOLL_DATA | PS_WAIT_FOR_TX_ACK)); } + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); q = skb_get_queue_mapping(skb); if (txq == sc->tx.txq_map[q]) { -- GitLab From 196fb860ceb6b937cbe608ea3ea0209bd4edf3b2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Jun 2012 20:24:13 +0530 Subject: [PATCH 0833/6849] ath9k: Resync beacons properly After a chip reset, the beacon timers have to re-programmed correctly for a station in associated state. Use the PS flags to ensure that this is done after a TSF sync happens, otherwise the driver ends up using incorrect values for TBTT/DTIM in powersave mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 88f7ad106e05..c0f478b0a9a2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -210,6 +210,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); + unsigned long flags; if (ath_startrecv(sc) != 0) { ath_err(common, "Unable to restart recv logic\n"); @@ -224,9 +225,18 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath9k_hw_enable_interrupts(ah); if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { - if (test_bit(SC_OP_BEACONS, &sc->sc_flags)) - ath_set_beacon(sc); + if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) + goto work; + + ath_set_beacon(sc); + if (ah->opmode == NL80211_IFTYPE_STATION && + test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { + spin_lock_irqsave(&sc->sc_pm_lock, flags); + sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + } + work: ath_restart_work(sc); } -- GitLab From 491b26b40222cc769c163e77177697dd7a63c316 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Jun 2012 14:21:14 +0200 Subject: [PATCH 0834/6849] wireless: update wireless URLs The preferred URL is http://wireless.kernel.org/ rather than http://linuxwireless.org/, update all URLs to point there. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- MAINTAINERS | 18 +++++++++--------- drivers/net/wireless/b43legacy/main.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 55f0fda602ec..c5fd905206e7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -329,7 +329,7 @@ F: drivers/hwmon/adm1029.c ADM8211 WIRELESS DRIVER L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/ +W: http://wireless.kernel.org/ S: Orphan F: drivers/net/wireless/adm8211.* @@ -1423,7 +1423,7 @@ B43 WIRELESS DRIVER M: Stefano Brivio L: linux-wireless@vger.kernel.org L: b43-dev@lists.infradead.org -W: http://linuxwireless.org/en/users/Drivers/b43 +W: http://wireless.kernel.org/en/users/Drivers/b43 S: Maintained F: drivers/net/wireless/b43/ @@ -1432,7 +1432,7 @@ M: Larry Finger M: Stefano Brivio L: linux-wireless@vger.kernel.org L: b43-dev@lists.infradead.org -W: http://linuxwireless.org/en/users/Drivers/b43 +W: http://wireless.kernel.org/en/users/Drivers/b43 S: Maintained F: drivers/net/wireless/b43legacy/ @@ -4339,7 +4339,7 @@ F: arch/m68k/hp300/ MAC80211 M: Johannes Berg L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/ +W: http://wireless.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git S: Maintained F: Documentation/networking/mac80211-injection.txt @@ -4350,7 +4350,7 @@ MAC80211 PID RATE CONTROL M: Stefano Brivio M: Mattias Nissler L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID +W: http://wireless.kernel.org/en/developers/Documentation/mac80211/RateControl/PID T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git S: Maintained F: net/mac80211/rc80211_pid* @@ -5027,7 +5027,7 @@ F: fs/ocfs2/ ORINOCO DRIVER L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/en/users/Drivers/orinoco +W: http://wireless.kernel.org/en/users/Drivers/orinoco W: http://www.nongnu.org/orinoco/ S: Orphan F: drivers/net/wireless/orinoco/ @@ -5729,7 +5729,7 @@ F: net/rose/ RTL8180 WIRELESS DRIVER M: "John W. Linville" L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/ +W: http://wireless.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/rtl818x/rtl8180/ @@ -5739,7 +5739,7 @@ M: Herton Ronaldo Krzesinski M: Hin-Tak Leung M: Larry Finger L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/ +W: http://wireless.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/rtl818x/rtl8187/ @@ -5748,7 +5748,7 @@ RTL8192CE WIRELESS DRIVER M: Larry Finger M: Chaoming Li L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/ +W: http://wireless.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/rtlwifi/ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index cd9c9bc186d9..8b06ca56125e 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1508,7 +1508,7 @@ static void b43legacy_release_firmware(struct b43legacy_wldev *dev) static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl) { - b43legacyerr(wl, "You must go to http://linuxwireless.org/en/users/" + b43legacyerr(wl, "You must go to http://wireless.kernel.org/en/users/" "Drivers/b43#devicefirmware " "and download the correct firmware (version 3).\n"); } -- GitLab From 196ac1c13d4db6c276dbb1c9190c8d7d45a83f1f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Jun 2012 14:28:40 +0200 Subject: [PATCH 0835/6849] mac80211: do remain-on-channel while idle The IDLE handling in HW off-channel is broken right now since we turn off IDLE only when the off-channel period already started. Therefore, all drivers that use it today (only iwlwifi!) must support off-channel while idle, so playing with idle isn't needed at all. Off-channel in general, since it's no longer used for authentication/association, shouldn't affect PS, so also remove that logic. Also document a small caveat for reporting TX status from off-channel frames in HW remain-on-channel. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 8 +++++++- net/mac80211/cfg.c | 7 +++---- net/mac80211/iface.c | 17 +++++++---------- net/mac80211/mlme.c | 6 ------ net/mac80211/offchannel.c | 4 ---- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d2ed86da8e4c..6e700bf8d4a5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2183,7 +2183,13 @@ enum ieee80211_rate_control_changed { * offload. Frames to transmit on the off-channel channel are transmitted * normally except for the %IEEE80211_TX_CTL_TX_OFFCHAN flag. When the * duration (which will always be non-zero) expires, the driver must call - * ieee80211_remain_on_channel_expired(). This callback may sleep. + * ieee80211_remain_on_channel_expired(). + * The driver must not call ieee80211_remain_on_channel_expired() before + * the TX status for a frame that was sent off-channel, otherwise the TX + * status is reported to userspace in an invalid way. + * Note that this callback may be called while the device is in IDLE and + * must be accepted in this case. + * This callback may sleep. * @cancel_remain_on_channel: Requests that an ongoing off-channel period is * aborted before it expires. This callback may sleep. * diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d99359a6f76d..a16907919709 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2187,8 +2187,6 @@ static int ieee80211_cancel_remain_on_channel_hw(struct ieee80211_local *local, local->hw_roc_cookie = 0; local->hw_roc_channel = NULL; - ieee80211_recalc_idle(local); - return 0; } @@ -2248,7 +2246,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_work *wk; const struct ieee80211_mgmt *mgmt = (void *)buf; u32 flags; - bool is_offchan = false; + bool is_offchan = false, in_hw_roc = false; if (dont_wait_for_ack) flags = IEEE80211_TX_CTL_NO_ACK; @@ -2268,6 +2266,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, if (chan == local->hw_roc_channel) { /* TODO: check channel type? */ is_offchan = false; + in_hw_roc = true; flags |= IEEE80211_TX_CTL_TX_OFFCHAN; } @@ -2370,7 +2369,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, * wait is involved, we might otherwise not be on * the right channel for long enough! */ - if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) { + if (!is_offchan && !wait && (in_hw_roc || !sdata->vif.bss_conf.idle)) { ieee80211_tx_skb(sdata, skb); return 0; } diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ede5f4959904..968d71c50713 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1456,7 +1456,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int count = 0; - bool working = false, scanning = false, hw_roc = false; + bool working = false, scanning = false; struct ieee80211_work *wk; unsigned int led_trig_start = 0, led_trig_stop = 0; @@ -1493,9 +1493,11 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) count++; } - list_for_each_entry(wk, &local->work_list, list) { - working = true; - wk->sdata->vif.bss_conf.idle = false; + if (!local->ops->remain_on_channel) { + list_for_each_entry(wk, &local->work_list, list) { + working = true; + wk->sdata->vif.bss_conf.idle = false; + } } if (local->scan_sdata && @@ -1504,9 +1506,6 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) local->scan_sdata->vif.bss_conf.idle = false; } - if (local->hw_roc_channel) - hw_roc = true; - list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) @@ -1518,7 +1517,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); } - if (working || scanning || hw_roc) + if (working || scanning) led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; else led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; @@ -1530,8 +1529,6 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); - if (hw_roc) - return ieee80211_idle_off(local, "hw remain-on-channel"); if (working) return ieee80211_idle_off(local, "working"); if (scanning) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e7c4ec4ce166..0f45d02e0ba7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -930,11 +930,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) return; } - if (!list_empty(&local->work_list)) { - local->ps_sdata = NULL; - goto change; - } - list_for_each_entry(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; @@ -1007,7 +1002,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) local->ps_sdata = NULL; } - change: ieee80211_change_ps(local); } diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 935aa4b6deee..8f482b15bc51 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -207,8 +207,6 @@ static void ieee80211_hw_roc_start(struct work_struct *work) GFP_KERNEL); } - ieee80211_recalc_idle(local); - mutex_unlock(&local->mtx); } @@ -260,8 +258,6 @@ static void ieee80211_hw_roc_done(struct work_struct *work) local->hw_roc_channel = NULL; local->hw_roc_cookie = 0; - ieee80211_recalc_idle(local); - mutex_unlock(&local->mtx); } -- GitLab From 2eb278e083549f4eb29838037004054b3b55df62 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Jun 2012 14:28:42 +0200 Subject: [PATCH 0836/6849] mac80211: unify SW/offload remain-on-channel Redesign all the off-channel code, getting rid of the generic off-channel work concept, replacing it with a simple remain-on-channel list. This fixes a number of small issues with the ROC implementation: * offloaded remain-on-channel couldn't be queued, now we can queue it as well, if needed * in iwlwifi (the only user) offloaded ROC is mutually exclusive with scanning, use the new queue to handle that case -- I expect that it will later depend on a HW flag The bigger issue though is that there's a bad bug in the current implementation: if we get a mgmt TX request while HW roc is active, and this new request has a wait time, we actually schedule a software ROC instead since we can't guarantee the existing offloaded ROC will still be that long. To fix this, the queuing mechanism was needed. The queuing mechanism for offloaded ROC isn't yet optimal, ideally we should add API to have the HW extend the ROC if needed. We could add that later but for now use a software implementation. Overall, this unifies the behaviour between the offloaded and software-implemented case as much as possible. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 3 - net/mac80211/Makefile | 1 - net/mac80211/cfg.c | 478 ++++++++++++++++++++----------------- net/mac80211/ieee80211_i.h | 89 ++----- net/mac80211/iface.c | 23 +- net/mac80211/main.c | 10 +- net/mac80211/offchannel.c | 280 ++++++++++++++++++---- net/mac80211/scan.c | 4 +- net/mac80211/status.c | 28 +-- net/mac80211/work.c | 370 ---------------------------- 10 files changed, 532 insertions(+), 754 deletions(-) delete mode 100644 net/mac80211/work.c diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 6e700bf8d4a5..d152f54064fd 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2184,9 +2184,6 @@ enum ieee80211_rate_control_changed { * normally except for the %IEEE80211_TX_CTL_TX_OFFCHAN flag. When the * duration (which will always be non-zero) expires, the driver must call * ieee80211_remain_on_channel_expired(). - * The driver must not call ieee80211_remain_on_channel_expired() before - * the TX status for a frame that was sent off-channel, otherwise the TX - * status is reported to userspace in an invalid way. * Note that this callback may be called while the device is in IDLE and * must be accepted in this case. * This callback may sleep. diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 3e9d931bba35..2b1470bac178 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -9,7 +9,6 @@ mac80211-y := \ scan.o offchannel.o \ ht.o agg-tx.o agg-rx.o \ ibss.o \ - work.o \ iface.o \ rate.o \ michael.o \ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a16907919709..498c94e34427 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2112,35 +2112,171 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, return 0; } -static int ieee80211_remain_on_channel_hw(struct ieee80211_local *local, - struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type chantype, - unsigned int duration, u64 *cookie) -{ +static int ieee80211_start_roc_work(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type, + unsigned int duration, u64 *cookie, + struct sk_buff *txskb) +{ + struct ieee80211_roc_work *roc, *tmp; + bool queued = false; int ret; - u32 random_cookie; lockdep_assert_held(&local->mtx); - if (local->hw_roc_cookie) - return -EBUSY; - /* must be nonzero */ - random_cookie = random32() | 1; - - *cookie = random_cookie; - local->hw_roc_dev = dev; - local->hw_roc_cookie = random_cookie; - local->hw_roc_channel = chan; - local->hw_roc_channel_type = chantype; - local->hw_roc_duration = duration; - ret = drv_remain_on_channel(local, chan, chantype, duration); + roc = kzalloc(sizeof(*roc), GFP_KERNEL); + if (!roc) + return -ENOMEM; + + roc->chan = channel; + roc->chan_type = channel_type; + roc->duration = duration; + roc->req_duration = duration; + roc->frame = txskb; + roc->mgmt_tx_cookie = (unsigned long)txskb; + roc->sdata = sdata; + INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); + INIT_LIST_HEAD(&roc->dependents); + + /* if there's one pending or we're scanning, queue this one */ + if (!list_empty(&local->roc_list) || local->scanning) + goto out_check_combine; + + /* if not HW assist, just queue & schedule work */ + if (!local->ops->remain_on_channel) { + ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); + goto out_queue; + } + + /* otherwise actually kick it off here (for error handling) */ + + /* + * If the duration is zero, then the driver + * wouldn't actually do anything. Set it to + * 10 for now. + * + * TODO: cancel the off-channel operation + * when we get the SKB's TX status and + * the wait time was zero before. + */ + if (!duration) + duration = 10; + + ret = drv_remain_on_channel(local, channel, channel_type, duration); if (ret) { - local->hw_roc_channel = NULL; - local->hw_roc_cookie = 0; + kfree(roc); + return ret; } - return ret; + roc->started = true; + goto out_queue; + + out_check_combine: + list_for_each_entry(tmp, &local->roc_list, list) { + if (tmp->chan != channel || tmp->chan_type != channel_type) + continue; + + /* + * Extend this ROC if possible: + * + * If it hasn't started yet, just increase the duration + * and add the new one to the list of dependents. + */ + if (!tmp->started) { + list_add_tail(&roc->list, &tmp->dependents); + tmp->duration = max(tmp->duration, roc->duration); + queued = true; + break; + } + + /* If it has already started, it's more difficult ... */ + if (local->ops->remain_on_channel) { + unsigned long j = jiffies; + + /* + * In the offloaded ROC case, if it hasn't begun, add + * this new one to the dependent list to be handled + * when the the master one begins. If it has begun, + * check that there's still a minimum time left and + * if so, start this one, transmitting the frame, but + * add it to the list directly after this one with a + * a reduced time so we'll ask the driver to execute + * it right after finishing the previous one, in the + * hope that it'll also be executed right afterwards, + * effectively extending the old one. + * If there's no minimum time left, just add it to the + * normal list. + */ + if (!tmp->hw_begun) { + list_add_tail(&roc->list, &tmp->dependents); + queued = true; + break; + } + + if (time_before(j + IEEE80211_ROC_MIN_LEFT, + tmp->hw_start_time + + msecs_to_jiffies(tmp->duration))) { + int new_dur; + + ieee80211_handle_roc_started(roc); + + new_dur = roc->duration - + jiffies_to_msecs(tmp->hw_start_time + + msecs_to_jiffies( + tmp->duration) - + j); + + if (new_dur > 0) { + /* add right after tmp */ + list_add(&roc->list, &tmp->list); + } else { + list_add_tail(&roc->list, + &tmp->dependents); + } + queued = true; + } + } else if (del_timer_sync(&tmp->work.timer)) { + unsigned long new_end; + + /* + * In the software ROC case, cancel the timer, if + * that fails then the finish work is already + * queued/pending and thus we queue the new ROC + * normally, if that succeeds then we can extend + * the timer duration and TX the frame (if any.) + */ + + list_add_tail(&roc->list, &tmp->dependents); + queued = true; + + new_end = jiffies + msecs_to_jiffies(roc->duration); + + /* ok, it was started & we canceled timer */ + if (time_after(new_end, tmp->work.timer.expires)) + mod_timer(&tmp->work.timer, new_end); + else + add_timer(&tmp->work.timer); + + ieee80211_handle_roc_started(roc); + } + break; + } + + out_queue: + if (!queued) + list_add_tail(&roc->list, &local->roc_list); + + /* + * cookie is either the roc (for normal roc) + * or the SKB (for mgmt TX) + */ + if (txskb) + *cookie = (unsigned long)txskb; + else + *cookie = (unsigned long)roc; + + return 0; } static int ieee80211_remain_on_channel(struct wiphy *wiphy, @@ -2152,84 +2288,76 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; + int ret; - if (local->ops->remain_on_channel) { - int ret; - - mutex_lock(&local->mtx); - ret = ieee80211_remain_on_channel_hw(local, dev, - chan, channel_type, - duration, cookie); - local->hw_roc_for_tx = false; - mutex_unlock(&local->mtx); - - return ret; - } + mutex_lock(&local->mtx); + ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, + duration, cookie, NULL); + mutex_unlock(&local->mtx); - return ieee80211_wk_remain_on_channel(sdata, chan, channel_type, - duration, cookie); + return ret; } -static int ieee80211_cancel_remain_on_channel_hw(struct ieee80211_local *local, - u64 cookie) +static int ieee80211_cancel_roc(struct ieee80211_local *local, + u64 cookie, bool mgmt_tx) { + struct ieee80211_roc_work *roc, *tmp, *found = NULL; int ret; - lockdep_assert_held(&local->mtx); + mutex_lock(&local->mtx); + list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { + if (!mgmt_tx && (unsigned long)roc != cookie) + continue; + else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) + continue; - if (local->hw_roc_cookie != cookie) - return -ENOENT; + found = roc; + break; + } - ret = drv_cancel_remain_on_channel(local); - if (ret) - return ret; + if (!found) { + mutex_unlock(&local->mtx); + return -ENOENT; + } - local->hw_roc_cookie = 0; - local->hw_roc_channel = NULL; + if (local->ops->remain_on_channel) { + if (found->started) { + ret = drv_cancel_remain_on_channel(local); + if (WARN_ON_ONCE(ret)) { + mutex_unlock(&local->mtx); + return ret; + } + } - return 0; -} + list_del(&found->list); -static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, - struct net_device *dev, - u64 cookie) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; + ieee80211_run_deferred_scan(local); + ieee80211_start_next_roc(local); + mutex_unlock(&local->mtx); - if (local->ops->cancel_remain_on_channel) { - int ret; + ieee80211_roc_notify_destroy(found); + } else { + /* work may be pending so use it all the time */ + found->abort = true; + ieee80211_queue_delayed_work(&local->hw, &found->work, 0); - mutex_lock(&local->mtx); - ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); mutex_unlock(&local->mtx); - return ret; + /* work will clean up etc */ + flush_delayed_work(&found->work); } - return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); + return 0; } -static enum work_done_result -ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb) +static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie) { - /* - * Use the data embedded in the work struct for reporting - * here so if the driver mangled the SKB before dropping - * it (which is the only way we really should get here) - * then we don't report mangled data. - * - * If there was no wait time, then by the time we get here - * the driver will likely not have reported the status yet, - * so in that case userspace will have to deal with it. - */ - - if (wk->offchan_tx.wait && !wk->offchan_tx.status) - cfg80211_mgmt_tx_status(wk->sdata->dev, - (unsigned long) wk->offchan_tx.frame, - wk->data, wk->data_len, false, GFP_KERNEL); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; - return WORK_DONE_DESTROY; + return ieee80211_cancel_roc(local, cookie, false); } static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, @@ -2243,10 +2371,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct sta_info *sta; - struct ieee80211_work *wk; const struct ieee80211_mgmt *mgmt = (void *)buf; + bool need_offchan = false; u32 flags; - bool is_offchan = false, in_hw_roc = false; + int ret; if (dont_wait_for_ack) flags = IEEE80211_TX_CTL_NO_ACK; @@ -2254,34 +2382,28 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | IEEE80211_TX_CTL_REQ_TX_STATUS; - /* Check that we are on the requested channel for transmission */ - if (chan != local->tmp_channel && - chan != local->oper_channel) - is_offchan = true; - if (channel_type_valid && - (channel_type != local->tmp_channel_type && - channel_type != local->_oper_channel_type)) - is_offchan = true; - - if (chan == local->hw_roc_channel) { - /* TODO: check channel type? */ - is_offchan = false; - in_hw_roc = true; - flags |= IEEE80211_TX_CTL_TX_OFFCHAN; - } - if (no_cck) flags |= IEEE80211_TX_CTL_NO_CCK_RATE; - if (is_offchan && !offchan) - return -EBUSY; - switch (sdata->vif.type) { case NL80211_IFTYPE_ADHOC: + if (!sdata->vif.bss_conf.ibss_joined) + need_offchan = true; + /* fall through */ +#ifdef CONFIG_MAC80211_MESH + case NL80211_IFTYPE_MESH_POINT: + if (ieee80211_vif_is_mesh(&sdata->vif) && + !sdata->u.mesh.mesh_id_len) + need_offchan = true; + /* fall through */ +#endif case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_MESH_POINT: + if (sdata->vif.type != NL80211_IFTYPE_ADHOC && + !ieee80211_vif_is_mesh(&sdata->vif) && + !rcu_access_pointer(sdata->bss->beacon)) + need_offchan = true; if (!ieee80211_is_action(mgmt->frame_control) || mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) break; @@ -2293,105 +2415,60 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: + if (!sdata->u.mgd.associated) + need_offchan = true; break; default: return -EOPNOTSUPP; } + mutex_lock(&local->mtx); + + /* Check if the operating channel is the requested channel */ + if (!need_offchan) { + need_offchan = chan != local->oper_channel; + if (channel_type_valid && + channel_type != local->_oper_channel_type) + need_offchan = true; + } + + if (need_offchan && !offchan) { + ret = -EBUSY; + goto out_unlock; + } + skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); - if (!skb) - return -ENOMEM; + if (!skb) { + ret = -ENOMEM; + goto out_unlock; + } skb_reserve(skb, local->hw.extra_tx_headroom); memcpy(skb_put(skb, len), buf, len); IEEE80211_SKB_CB(skb)->flags = flags; - if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL && - flags & IEEE80211_TX_CTL_TX_OFFCHAN) - IEEE80211_SKB_CB(skb)->hw_queue = - local->hw.offchannel_tx_hw_queue; - skb->dev = sdata->dev; - *cookie = (unsigned long) skb; - - if (is_offchan && local->ops->remain_on_channel) { - unsigned int duration; - int ret; - - mutex_lock(&local->mtx); - /* - * If the duration is zero, then the driver - * wouldn't actually do anything. Set it to - * 100 for now. - * - * TODO: cancel the off-channel operation - * when we get the SKB's TX status and - * the wait time was zero before. - */ - duration = 100; - if (wait) - duration = wait; - ret = ieee80211_remain_on_channel_hw(local, dev, chan, - channel_type, - duration, cookie); - if (ret) { - kfree_skb(skb); - mutex_unlock(&local->mtx); - return ret; - } - - local->hw_roc_for_tx = true; - local->hw_roc_duration = wait; - - /* - * queue up frame for transmission after - * ieee80211_ready_on_channel call - */ - - /* modify cookie to prevent API mismatches */ - *cookie ^= 2; - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; - if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) - IEEE80211_SKB_CB(skb)->hw_queue = - local->hw.offchannel_tx_hw_queue; - local->hw_roc_skb = skb; - local->hw_roc_skb_for_status = skb; - mutex_unlock(&local->mtx); - - return 0; - } - - /* - * Can transmit right away if the channel was the - * right one and there's no wait involved... If a - * wait is involved, we might otherwise not be on - * the right channel for long enough! - */ - if (!is_offchan && !wait && (in_hw_roc || !sdata->vif.bss_conf.idle)) { + if (!need_offchan) { ieee80211_tx_skb(sdata, skb); - return 0; - } - - wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL); - if (!wk) { - kfree_skb(skb); - return -ENOMEM; + ret = 0; + goto out_unlock; } - wk->type = IEEE80211_WORK_OFFCHANNEL_TX; - wk->chan = chan; - wk->chan_type = channel_type; - wk->sdata = sdata; - wk->done = ieee80211_offchan_tx_done; - wk->offchan_tx.frame = skb; - wk->offchan_tx.wait = wait; - wk->data_len = len; - memcpy(wk->data, buf, len); + IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; + if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) + IEEE80211_SKB_CB(skb)->hw_queue = + local->hw.offchannel_tx_hw_queue; - ieee80211_add_work(wk); - return 0; + /* This will handle all kinds of coalescing and immediate TX */ + ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, + wait, cookie, skb); + if (ret) + kfree_skb(skb); + out_unlock: + mutex_unlock(&local->mtx); + return ret; } static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, @@ -2400,45 +2477,8 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; - struct ieee80211_work *wk; - int ret = -ENOENT; - mutex_lock(&local->mtx); - - if (local->ops->cancel_remain_on_channel) { - cookie ^= 2; - ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); - - if (ret == 0) { - kfree_skb(local->hw_roc_skb); - local->hw_roc_skb = NULL; - local->hw_roc_skb_for_status = NULL; - } - - mutex_unlock(&local->mtx); - - return ret; - } - - list_for_each_entry(wk, &local->work_list, list) { - if (wk->sdata != sdata) - continue; - - if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) - continue; - - if (cookie != (unsigned long) wk->offchan_tx.frame) - continue; - - wk->timeout = jiffies; - - ieee80211_queue_work(&local->hw, &local->work_work); - ret = 0; - break; - } - mutex_unlock(&local->mtx); - - return ret; + return ieee80211_cancel_roc(local, cookie, true); } static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c026abcb8d9..e6cbf5b68c89 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -317,55 +317,30 @@ struct mesh_preq_queue { u8 flags; }; -enum ieee80211_work_type { - IEEE80211_WORK_ABORT, - IEEE80211_WORK_REMAIN_ON_CHANNEL, - IEEE80211_WORK_OFFCHANNEL_TX, -}; - -/** - * enum work_done_result - indicates what to do after work was done - * - * @WORK_DONE_DESTROY: This work item is no longer needed, destroy. - * @WORK_DONE_REQUEUE: This work item was reset to be reused, and - * should be requeued. - */ -enum work_done_result { - WORK_DONE_DESTROY, - WORK_DONE_REQUEUE, -}; +#if HZ/100 == 0 +#define IEEE80211_ROC_MIN_LEFT 1 +#else +#define IEEE80211_ROC_MIN_LEFT (HZ/100) +#endif -struct ieee80211_work { +struct ieee80211_roc_work { struct list_head list; + struct list_head dependents; - struct rcu_head rcu_head; + struct delayed_work work; struct ieee80211_sub_if_data *sdata; - enum work_done_result (*done)(struct ieee80211_work *wk, - struct sk_buff *skb); - struct ieee80211_channel *chan; enum nl80211_channel_type chan_type; - unsigned long timeout; - enum ieee80211_work_type type; + bool started, abort, hw_begun, notified; - bool started; + unsigned long hw_start_time; - union { - struct { - u32 duration; - } remain; - struct { - struct sk_buff *frame; - u32 wait; - bool status; - } offchan_tx; - }; - - size_t data_len; - u8 data[]; + u32 duration, req_duration; + struct sk_buff *frame; + u64 mgmt_tx_cookie; }; /* flags used in struct ieee80211_if_managed.flags */ @@ -847,13 +822,6 @@ struct ieee80211_local { const struct ieee80211_ops *ops; - /* - * work stuff, potentially off-channel (in the future) - */ - struct list_head work_list; - struct timer_list work_timer; - struct work_struct work_work; - /* * private workqueue to mac80211. mac80211 makes this accessible * via ieee80211_queue_work() @@ -1088,14 +1056,12 @@ struct ieee80211_local { } debugfs; #endif - struct ieee80211_channel *hw_roc_channel; - struct net_device *hw_roc_dev; - struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status; + /* + * Remain-on-channel support + */ + struct list_head roc_list; struct work_struct hw_roc_start, hw_roc_done; - enum nl80211_channel_type hw_roc_channel_type; - unsigned int hw_roc_duration; - u32 hw_roc_cookie; - bool hw_roc_for_tx; + unsigned long hw_roc_start_time; struct idr ack_status_frames; spinlock_t ack_status_lock; @@ -1291,7 +1257,12 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, bool offchannel_ps_enable); void ieee80211_offchannel_return(struct ieee80211_local *local, bool offchannel_ps_disable); -void ieee80211_hw_roc_setup(struct ieee80211_local *local); +void ieee80211_roc_setup(struct ieee80211_local *local); +void ieee80211_start_next_roc(struct ieee80211_local *local); +void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); +void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc); +void ieee80211_sw_roc_work(struct work_struct *work); +void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); /* interface handling */ int ieee80211_iface_init(void); @@ -1501,18 +1472,6 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, enum nl80211_channel_type channel_type, u16 prot_mode); -/* internal work items */ -void ieee80211_work_init(struct ieee80211_local *local); -void ieee80211_add_work(struct ieee80211_work *wk); -void free_work(struct ieee80211_work *wk); -void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata); -int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - unsigned int duration, u64 *cookie); -int ieee80211_wk_cancel_remain_on_channel( - struct ieee80211_sub_if_data *sdata, u64 cookie); - /* channel management */ enum ieee80211_chan_mode { CHAN_MODE_UNDEFINED, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 968d71c50713..87aeb4f21ffd 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -528,10 +528,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, */ netif_tx_stop_all_queues(sdata->dev); - /* - * Purge work for this interface. - */ - ieee80211_work_purge(sdata); + ieee80211_roc_purge(sdata); /* * Remove all stations associated with this interface. @@ -637,18 +634,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_configure_filter(local); break; default: - mutex_lock(&local->mtx); - if (local->hw_roc_dev == sdata->dev && - local->hw_roc_channel) { - /* ignore return value since this is racy */ - drv_cancel_remain_on_channel(local); - ieee80211_queue_work(&local->hw, &local->hw_roc_done); - } - mutex_unlock(&local->mtx); - - flush_work(&local->hw_roc_start); - flush_work(&local->hw_roc_done); - flush_work(&sdata->work); /* * When we get here, the interface is marked down. @@ -1457,8 +1442,8 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) struct ieee80211_sub_if_data *sdata; int count = 0; bool working = false, scanning = false; - struct ieee80211_work *wk; unsigned int led_trig_start = 0, led_trig_stop = 0; + struct ieee80211_roc_work *roc; #ifdef CONFIG_PROVE_LOCKING WARN_ON(debug_locks && !lockdep_rtnl_is_held() && @@ -1494,9 +1479,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) } if (!local->ops->remain_on_channel) { - list_for_each_entry(wk, &local->work_list, list) { + list_for_each_entry(roc, &local->roc_list, list) { working = true; - wk->sdata->vif.bss_conf.idle = false; + roc->sdata->vif.bss_conf.idle = false; } } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 779ac613ee57..d81c178c7712 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -625,8 +625,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); - ieee80211_work_init(local); - INIT_WORK(&local->restart_work, ieee80211_restart_work); INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); @@ -669,7 +667,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, ieee80211_led_names(local); - ieee80211_hw_roc_setup(local); + ieee80211_roc_setup(local); return &local->hw; } @@ -1016,12 +1014,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) rtnl_unlock(); - /* - * Now all work items will be gone, but the - * timer might still be armed, so delete it - */ - del_timer_sync(&local->work_timer); - cancel_work_sync(&local->restart_work); cancel_work_sync(&local->reconfig_filter); diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 8f482b15bc51..abb226dc4753 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -16,6 +16,7 @@ #include #include "ieee80211_i.h" #include "driver-trace.h" +#include "driver-ops.h" /* * Tell our hardware to disable PS. @@ -181,32 +182,58 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, mutex_unlock(&local->iflist_mtx); } +void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) +{ + if (roc->notified) + return; + + if (roc->mgmt_tx_cookie) { + if (!WARN_ON(!roc->frame)) { + ieee80211_tx_skb(roc->sdata, roc->frame); + roc->frame = NULL; + } + } else { + cfg80211_ready_on_channel(roc->sdata->dev, (unsigned long)roc, + roc->chan, roc->chan_type, + roc->req_duration, GFP_KERNEL); + } + + roc->notified = true; +} + static void ieee80211_hw_roc_start(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, hw_roc_start); - struct ieee80211_sub_if_data *sdata; + struct ieee80211_roc_work *roc, *dep, *tmp; mutex_lock(&local->mtx); - if (!local->hw_roc_channel) { - mutex_unlock(&local->mtx); - return; - } + if (list_empty(&local->roc_list)) + goto out_unlock; - if (local->hw_roc_skb) { - sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); - ieee80211_tx_skb(sdata, local->hw_roc_skb); - local->hw_roc_skb = NULL; - } else { - cfg80211_ready_on_channel(local->hw_roc_dev, - local->hw_roc_cookie, - local->hw_roc_channel, - local->hw_roc_channel_type, - local->hw_roc_duration, - GFP_KERNEL); - } + roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, + list); + + if (!roc->started) + goto out_unlock; + + roc->hw_begun = true; + roc->hw_start_time = local->hw_roc_start_time; + ieee80211_handle_roc_started(roc); + list_for_each_entry_safe(dep, tmp, &roc->dependents, list) { + ieee80211_handle_roc_started(dep); + + if (dep->duration > roc->duration) { + u32 dur = dep->duration; + dep->duration = dur - roc->duration; + roc->duration = dur; + list_del(&dep->list); + list_add(&dep->list, &roc->list); + } + } + out_unlock: mutex_unlock(&local->mtx); } @@ -214,50 +241,179 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); + local->hw_roc_start_time = jiffies; + trace_api_ready_on_channel(local); ieee80211_queue_work(hw, &local->hw_roc_start); } EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); -static void ieee80211_hw_roc_done(struct work_struct *work) +void ieee80211_start_next_roc(struct ieee80211_local *local) { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, hw_roc_done); + struct ieee80211_roc_work *roc; - mutex_lock(&local->mtx); + lockdep_assert_held(&local->mtx); - if (!local->hw_roc_channel) { - mutex_unlock(&local->mtx); + if (list_empty(&local->roc_list)) { + ieee80211_run_deferred_scan(local); return; } - /* was never transmitted */ - if (local->hw_roc_skb) { - u64 cookie; + roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, + list); - cookie = local->hw_roc_cookie ^ 2; + if (local->ops->remain_on_channel) { + int ret, duration = roc->duration; - cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie, - local->hw_roc_skb->data, - local->hw_roc_skb->len, false, - GFP_KERNEL); + /* XXX: duplicated, see ieee80211_start_roc_work() */ + if (!duration) + duration = 10; - kfree_skb(local->hw_roc_skb); - local->hw_roc_skb = NULL; - local->hw_roc_skb_for_status = NULL; + ret = drv_remain_on_channel(local, roc->chan, + roc->chan_type, + duration); + + roc->started = true; + + if (ret) { + wiphy_warn(local->hw.wiphy, + "failed to start next HW ROC (%d)\n", ret); + /* + * queue the work struct again to avoid recursion + * when multiple failures occur + */ + ieee80211_remain_on_channel_expired(&local->hw); + } + } else { + /* delay it a bit */ + ieee80211_queue_delayed_work(&local->hw, &roc->work, + round_jiffies_relative(HZ/2)); + } +} + +void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) +{ + struct ieee80211_roc_work *dep, *tmp; + + /* was never transmitted */ + if (roc->frame) { + cfg80211_mgmt_tx_status(roc->sdata->dev, + (unsigned long)roc->frame, + roc->frame->data, roc->frame->len, + false, GFP_KERNEL); + kfree_skb(roc->frame); } - if (!local->hw_roc_for_tx) - cfg80211_remain_on_channel_expired(local->hw_roc_dev, - local->hw_roc_cookie, - local->hw_roc_channel, - local->hw_roc_channel_type, + if (!roc->mgmt_tx_cookie) + cfg80211_remain_on_channel_expired(roc->sdata->dev, + (unsigned long)roc, + roc->chan, roc->chan_type, GFP_KERNEL); - local->hw_roc_channel = NULL; - local->hw_roc_cookie = 0; + list_for_each_entry_safe(dep, tmp, &roc->dependents, list) + ieee80211_roc_notify_destroy(dep); + + kfree(roc); +} + +void ieee80211_sw_roc_work(struct work_struct *work) +{ + struct ieee80211_roc_work *roc = + container_of(work, struct ieee80211_roc_work, work.work); + struct ieee80211_sub_if_data *sdata = roc->sdata; + struct ieee80211_local *local = sdata->local; + + mutex_lock(&local->mtx); + + if (roc->abort) + goto finish; + + if (WARN_ON(list_empty(&local->roc_list))) + goto out_unlock; + + if (WARN_ON(roc != list_first_entry(&local->roc_list, + struct ieee80211_roc_work, + list))) + goto out_unlock; + + if (!roc->started) { + struct ieee80211_roc_work *dep; + + /* start this ROC */ + /* switch channel etc */ + ieee80211_recalc_idle(local); + + local->tmp_channel = roc->chan; + local->tmp_channel_type = roc->chan_type; + ieee80211_hw_config(local, 0); + + /* tell userspace or send frame */ + ieee80211_handle_roc_started(roc); + list_for_each_entry(dep, &roc->dependents, list) + ieee80211_handle_roc_started(dep); + + /* if it was pure TX, just finish right away */ + if (!roc->duration) + goto finish; + + roc->started = true; + ieee80211_queue_delayed_work(&local->hw, &roc->work, + msecs_to_jiffies(roc->duration)); + } else { + /* finish this ROC */ + finish: + list_del(&roc->list); + ieee80211_roc_notify_destroy(roc); + + if (roc->started) { + drv_flush(local, false); + + local->tmp_channel = NULL; + ieee80211_hw_config(local, 0); + + ieee80211_offchannel_return(local, true); + } + + ieee80211_recalc_idle(local); + + ieee80211_start_next_roc(local); + ieee80211_run_deferred_scan(local); + } + + out_unlock: + mutex_unlock(&local->mtx); +} + +static void ieee80211_hw_roc_done(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, hw_roc_done); + struct ieee80211_roc_work *roc; + + mutex_lock(&local->mtx); + + if (list_empty(&local->roc_list)) + goto out_unlock; + + roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, + list); + + if (!roc->started) + goto out_unlock; + + list_del(&roc->list); + + ieee80211_roc_notify_destroy(roc); + + /* if there's another roc, start it now */ + ieee80211_start_next_roc(local); + + /* or scan maybe */ + ieee80211_run_deferred_scan(local); + + out_unlock: mutex_unlock(&local->mtx); } @@ -271,8 +427,48 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw) } EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); -void ieee80211_hw_roc_setup(struct ieee80211_local *local) +void ieee80211_roc_setup(struct ieee80211_local *local) { INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); + INIT_LIST_HEAD(&local->roc_list); +} + +void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_roc_work *roc, *tmp; + LIST_HEAD(tmp_list); + + mutex_lock(&local->mtx); + list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { + if (roc->sdata != sdata) + continue; + + if (roc->started && local->ops->remain_on_channel) { + /* can race, so ignore return value */ + drv_cancel_remain_on_channel(local); + } + + list_move_tail(&roc->list, &tmp_list); + roc->abort = true; + } + + ieee80211_start_next_roc(local); + ieee80211_run_deferred_scan(local); + mutex_unlock(&local->mtx); + + list_for_each_entry_safe(roc, tmp, &tmp_list, list) { + if (local->ops->remain_on_channel) { + list_del(&roc->list); + ieee80211_roc_notify_destroy(roc); + } else { + ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); + + /* work will clean up etc */ + flush_delayed_work(&roc->work); + } + } + + WARN_ON_ONCE(!list_empty(&tmp_list)); } diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 169da0742c81..379f178eab5f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -323,7 +323,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, ieee80211_mlme_notify_scan_completed(local); ieee80211_ibss_notify_scan_completed(local); ieee80211_mesh_notify_scan_completed(local); - ieee80211_queue_work(&local->hw, &local->work_work); + ieee80211_start_next_roc(local); } void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) @@ -376,7 +376,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) static bool ieee80211_can_scan(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { - if (!list_empty(&local->work_list)) + if (!list_empty(&local->roc_list)) return false; if (sdata->vif.type == NL80211_IFTYPE_STATION && diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 63a769015068..6b4f42527887 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -520,36 +520,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { u64 cookie = (unsigned long)skb; + acked = info->flags & IEEE80211_TX_STAT_ACK; if (ieee80211_is_nullfunc(hdr->frame_control) || - ieee80211_is_qos_nullfunc(hdr->frame_control)) { - acked = info->flags & IEEE80211_TX_STAT_ACK; - + ieee80211_is_qos_nullfunc(hdr->frame_control)) cfg80211_probe_status(skb->dev, hdr->addr1, cookie, acked, GFP_ATOMIC); - } else { - struct ieee80211_work *wk; - - rcu_read_lock(); - list_for_each_entry_rcu(wk, &local->work_list, list) { - if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) - continue; - if (wk->offchan_tx.frame != skb) - continue; - wk->offchan_tx.status = true; - break; - } - rcu_read_unlock(); - if (local->hw_roc_skb_for_status == skb) { - cookie = local->hw_roc_cookie ^ 2; - local->hw_roc_skb_for_status = NULL; - } - + else cfg80211_mgmt_tx_status( skb->dev, cookie, skb->data, skb->len, - !!(info->flags & IEEE80211_TX_STAT_ACK), - GFP_ATOMIC); - } + acked, GFP_ATOMIC); } if (unlikely(info->ack_frame_id)) { diff --git a/net/mac80211/work.c b/net/mac80211/work.c deleted file mode 100644 index b2650a9d45ff..000000000000 --- a/net/mac80211/work.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * mac80211 work implementation - * - * Copyright 2003-2008, Jouni Malinen - * Copyright 2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * Copyright 2006-2007 Jiri Benc - * Copyright 2007, Michael Wu - * Copyright 2009, Johannes Berg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211_i.h" -#include "rate.h" -#include "driver-ops.h" - -enum work_action { - WORK_ACT_NONE, - WORK_ACT_TIMEOUT, -}; - - -/* utils */ -static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) -{ - lockdep_assert_held(&local->mtx); -} - -/* - * We can have multiple work items (and connection probing) - * scheduling this timer, but we need to take care to only - * reschedule it when it should fire _earlier_ than it was - * asked for before, or if it's not pending right now. This - * function ensures that. Note that it then is required to - * run this function for all timeouts after the first one - * has happened -- the work that runs from this timer will - * do that. - */ -static void run_again(struct ieee80211_local *local, - unsigned long timeout) -{ - ASSERT_WORK_MTX(local); - - if (!timer_pending(&local->work_timer) || - time_before(timeout, local->work_timer.expires)) - mod_timer(&local->work_timer, timeout); -} - -void free_work(struct ieee80211_work *wk) -{ - kfree_rcu(wk, rcu_head); -} - -static enum work_action __must_check -ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) -{ - /* - * First time we run, do nothing -- the generic code will - * have switched to the right channel etc. - */ - if (!wk->started) { - wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration); - - cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk, - wk->chan, wk->chan_type, - wk->remain.duration, GFP_KERNEL); - - return WORK_ACT_NONE; - } - - return WORK_ACT_TIMEOUT; -} - -static enum work_action __must_check -ieee80211_offchannel_tx(struct ieee80211_work *wk) -{ - if (!wk->started) { - wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait); - - /* - * After this, offchan_tx.frame remains but now is no - * longer a valid pointer -- we still need it as the - * cookie for canceling this work/status matching. - */ - ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); - - return WORK_ACT_NONE; - } - - return WORK_ACT_TIMEOUT; -} - -static void ieee80211_work_timer(unsigned long data) -{ - struct ieee80211_local *local = (void *) data; - - if (local->quiescing) - return; - - ieee80211_queue_work(&local->hw, &local->work_work); -} - -static void ieee80211_work_work(struct work_struct *work) -{ - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, work_work); - struct ieee80211_work *wk, *tmp; - LIST_HEAD(free_work); - enum work_action rma; - bool remain_off_channel = false; - - /* - * ieee80211_queue_work() should have picked up most cases, - * here we'll pick the rest. - */ - if (WARN(local->suspended, "work scheduled while going to suspend\n")) - return; - - mutex_lock(&local->mtx); - - if (local->scanning) { - mutex_unlock(&local->mtx); - return; - } - - ieee80211_recalc_idle(local); - - list_for_each_entry_safe(wk, tmp, &local->work_list, list) { - bool started = wk->started; - - /* mark work as started if it's on the current off-channel */ - if (!started && local->tmp_channel && - wk->chan == local->tmp_channel && - wk->chan_type == local->tmp_channel_type) { - started = true; - wk->timeout = jiffies; - } - - if (!started && !local->tmp_channel) { - ieee80211_offchannel_stop_vifs(local, true); - - local->tmp_channel = wk->chan; - local->tmp_channel_type = wk->chan_type; - - ieee80211_hw_config(local, 0); - - started = true; - wk->timeout = jiffies; - } - - /* don't try to work with items that aren't started */ - if (!started) - continue; - - if (time_is_after_jiffies(wk->timeout)) { - /* - * This work item isn't supposed to be worked on - * right now, but take care to adjust the timer - * properly. - */ - run_again(local, wk->timeout); - continue; - } - - switch (wk->type) { - default: - WARN_ON(1); - /* nothing */ - rma = WORK_ACT_NONE; - break; - case IEEE80211_WORK_ABORT: - rma = WORK_ACT_TIMEOUT; - break; - case IEEE80211_WORK_REMAIN_ON_CHANNEL: - rma = ieee80211_remain_on_channel_timeout(wk); - break; - case IEEE80211_WORK_OFFCHANNEL_TX: - rma = ieee80211_offchannel_tx(wk); - break; - } - - wk->started = started; - - switch (rma) { - case WORK_ACT_NONE: - /* might have changed the timeout */ - run_again(local, wk->timeout); - break; - case WORK_ACT_TIMEOUT: - list_del_rcu(&wk->list); - synchronize_rcu(); - list_add(&wk->list, &free_work); - break; - default: - WARN(1, "unexpected: %d", rma); - } - } - - list_for_each_entry(wk, &local->work_list, list) { - if (!wk->started) - continue; - if (wk->chan != local->tmp_channel || - wk->chan_type != local->tmp_channel_type) - continue; - remain_off_channel = true; - } - - if (!remain_off_channel && local->tmp_channel) { - local->tmp_channel = NULL; - ieee80211_hw_config(local, 0); - - ieee80211_offchannel_return(local, true); - - /* give connection some time to breathe */ - run_again(local, jiffies + HZ/2); - } - - ieee80211_recalc_idle(local); - ieee80211_run_deferred_scan(local); - - mutex_unlock(&local->mtx); - - list_for_each_entry_safe(wk, tmp, &free_work, list) { - wk->done(wk, NULL); - list_del(&wk->list); - kfree(wk); - } -} - -void ieee80211_add_work(struct ieee80211_work *wk) -{ - struct ieee80211_local *local; - - if (WARN_ON(!wk->chan)) - return; - - if (WARN_ON(!wk->sdata)) - return; - - if (WARN_ON(!wk->done)) - return; - - if (WARN_ON(!ieee80211_sdata_running(wk->sdata))) - return; - - wk->started = false; - - local = wk->sdata->local; - mutex_lock(&local->mtx); - list_add_tail(&wk->list, &local->work_list); - mutex_unlock(&local->mtx); - - ieee80211_queue_work(&local->hw, &local->work_work); -} - -void ieee80211_work_init(struct ieee80211_local *local) -{ - INIT_LIST_HEAD(&local->work_list); - setup_timer(&local->work_timer, ieee80211_work_timer, - (unsigned long)local); - INIT_WORK(&local->work_work, ieee80211_work_work); -} - -void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_work *wk; - bool cleanup = false; - - mutex_lock(&local->mtx); - list_for_each_entry(wk, &local->work_list, list) { - if (wk->sdata != sdata) - continue; - cleanup = true; - wk->type = IEEE80211_WORK_ABORT; - wk->started = true; - wk->timeout = jiffies; - } - mutex_unlock(&local->mtx); - - /* run cleanups etc. */ - if (cleanup) - ieee80211_work_work(&local->work_work); - - mutex_lock(&local->mtx); - list_for_each_entry(wk, &local->work_list, list) { - if (wk->sdata != sdata) - continue; - WARN_ON(1); - break; - } - mutex_unlock(&local->mtx); -} - -static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk, - struct sk_buff *skb) -{ - /* - * We are done serving the remain-on-channel command. - */ - cfg80211_remain_on_channel_expired(wk->sdata->dev, (unsigned long) wk, - wk->chan, wk->chan_type, - GFP_KERNEL); - - return WORK_DONE_DESTROY; -} - -int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - unsigned int duration, u64 *cookie) -{ - struct ieee80211_work *wk; - - wk = kzalloc(sizeof(*wk), GFP_KERNEL); - if (!wk) - return -ENOMEM; - - wk->type = IEEE80211_WORK_REMAIN_ON_CHANNEL; - wk->chan = chan; - wk->chan_type = channel_type; - wk->sdata = sdata; - wk->done = ieee80211_remain_done; - - wk->remain.duration = duration; - - *cookie = (unsigned long) wk; - - ieee80211_add_work(wk); - - return 0; -} - -int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, - u64 cookie) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_work *wk, *tmp; - bool found = false; - - mutex_lock(&local->mtx); - list_for_each_entry_safe(wk, tmp, &local->work_list, list) { - if ((unsigned long) wk == cookie) { - wk->timeout = jiffies; - found = true; - break; - } - } - mutex_unlock(&local->mtx); - - if (!found) - return -ENOENT; - - ieee80211_queue_work(&local->hw, &local->work_work); - - return 0; -} -- GitLab From 967db0ea65b0bf8507a7643ac8f296c4f2c0a834 Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Wed, 6 Jun 2012 18:51:35 -0700 Subject: [PATCH 0837/6849] cgroup: make sure that decisions in __css_put are atomic __css_put is using atomic_dec on the ref count, and then looking at the ref count to make decisions. This is prone to races, as someone else may decrement ref count between our decrement and our decision. Instead, we should base our decisions on the value that we decremented the ref count to. (This results in an actual race on Google's kernel which I haven't been able to reproduce on the upstream kernel. Having said that, it's still incorrect by inspection). Signed-off-by: Salman Qazi Acked-by: Li Zefan Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org --- kernel/cgroup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 72fcd3069a90..ceeafe874b3f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4984,8 +4984,7 @@ void __css_put(struct cgroup_subsys_state *css) struct cgroup *cgrp = css->cgroup; rcu_read_lock(); - atomic_dec(&css->refcnt); - switch (css_refcnt(css)) { + switch (atomic_dec_return(&css->refcnt)) { case 1: if (notify_on_release(cgrp)) { set_bit(CGRP_RELEASABLE, &cgrp->flags); -- GitLab From 6be96a5c905178637ec06a5d456a76b2b304fca3 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 6 Jun 2012 19:12:30 -0700 Subject: [PATCH 0838/6849] cgroup: remove hierarchy_mutex It was introduced for memcg to iterate cgroup hierarchy without holding cgroup_mutex, but soon after that it was replaced with a lockless way in memcg. No one used hierarchy_mutex since that, so remove it. Signed-off-by: Li Zefan Signed-off-by: Tejun Heo --- Documentation/cgroups/cgroups.txt | 2 +- include/linux/cgroup.h | 17 ++---------- kernel/cgroup.c | 45 ------------------------------- 3 files changed, 3 insertions(+), 61 deletions(-) diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index 8e74980ab385..e86faaea7d66 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -656,7 +656,7 @@ example in cpusets, no task may attach before 'cpus' and 'mems' are set up. void bind(struct cgroup *root) -(cgroup_mutex and ss->hierarchy_mutex held by caller) +(cgroup_mutex held by caller) Called when a cgroup subsystem is rebound to a different hierarchy and root cgroup. Currently this will only involve movement between diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index d3f5fba2c159..c90eaa803440 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -499,22 +499,9 @@ struct cgroup_subsys { #define MAX_CGROUP_TYPE_NAMELEN 32 const char *name; - /* - * Protects sibling/children links of cgroups in this - * hierarchy, plus protects which hierarchy (or none) the - * subsystem is a part of (i.e. root/sibling). To avoid - * potential deadlocks, the following operations should not be - * undertaken while holding any hierarchy_mutex: - * - * - allocating memory - * - initiating hotplug events - */ - struct mutex hierarchy_mutex; - struct lock_class_key subsys_key; - /* * Link to parent, and list entry in parent's children. - * Protected by this->hierarchy_mutex and cgroup_lock() + * Protected by cgroup_lock() */ struct cgroupfs_root *root; struct list_head sibling; @@ -602,7 +589,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); * the lifetime of cgroup_subsys_state is subsys's matter. * * Looking up and scanning function should be called under rcu_read_lock(). - * Taking cgroup_mutex()/hierarchy_mutex() is not necessary for following calls. + * Taking cgroup_mutex is not necessary for following calls. * But the css returned by this routine can be "not populated yet" or "being * destroyed". The caller should check css and cgroup's status. */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ceeafe874b3f..dec62f5936ef 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1073,28 +1073,24 @@ static int rebind_subsystems(struct cgroupfs_root *root, BUG_ON(cgrp->subsys[i]); BUG_ON(!dummytop->subsys[i]); BUG_ON(dummytop->subsys[i]->cgroup != dummytop); - mutex_lock(&ss->hierarchy_mutex); cgrp->subsys[i] = dummytop->subsys[i]; cgrp->subsys[i]->cgroup = cgrp; list_move(&ss->sibling, &root->subsys_list); ss->root = root; if (ss->bind) ss->bind(cgrp); - mutex_unlock(&ss->hierarchy_mutex); /* refcount was already taken, and we're keeping it */ } else if (bit & removed_bits) { /* We're removing this subsystem */ BUG_ON(ss == NULL); BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]); BUG_ON(cgrp->subsys[i]->cgroup != cgrp); - mutex_lock(&ss->hierarchy_mutex); if (ss->bind) ss->bind(dummytop); dummytop->subsys[i]->cgroup = dummytop; cgrp->subsys[i] = NULL; subsys[i]->root = &rootnode; list_move(&ss->sibling, &rootnode.subsys_list); - mutex_unlock(&ss->hierarchy_mutex); /* subsystem is now free - drop reference on module */ module_put(ss->module); } else if (bit & final_bits) { @@ -3917,37 +3913,6 @@ static void init_cgroup_css(struct cgroup_subsys_state *css, set_bit(CSS_CLEAR_CSS_REFS, &css->flags); } -static void cgroup_lock_hierarchy(struct cgroupfs_root *root) -{ - /* We need to take each hierarchy_mutex in a consistent order */ - int i; - - /* - * No worry about a race with rebind_subsystems that might mess up the - * locking order, since both parties are under cgroup_mutex. - */ - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - if (ss == NULL) - continue; - if (ss->root == root) - mutex_lock(&ss->hierarchy_mutex); - } -} - -static void cgroup_unlock_hierarchy(struct cgroupfs_root *root) -{ - int i; - - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - if (ss == NULL) - continue; - if (ss->root == root) - mutex_unlock(&ss->hierarchy_mutex); - } -} - /* * cgroup_create - create a cgroup * @parent: cgroup that will be parent of the new cgroup @@ -4008,9 +3973,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, ss->post_clone(cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); - cgroup_unlock_hierarchy(root); root->number_of_cgroups++; err = cgroup_create_dir(cgrp, dentry, mode); @@ -4037,9 +4000,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, err_remove: - cgroup_lock_hierarchy(root); list_del(&cgrp->sibling); - cgroup_unlock_hierarchy(root); root->number_of_cgroups--; err_destroy: @@ -4247,10 +4208,8 @@ again: list_del_init(&cgrp->release_list); raw_spin_unlock(&release_list_lock); - cgroup_lock_hierarchy(cgrp->root); /* delete this cgroup from parent->children */ list_del_init(&cgrp->sibling); - cgroup_unlock_hierarchy(cgrp->root); list_del_init(&cgrp->allcg_node); @@ -4324,8 +4283,6 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) * need to invoke fork callbacks here. */ BUG_ON(!list_empty(&init_task.tasks)); - mutex_init(&ss->hierarchy_mutex); - lockdep_set_class(&ss->hierarchy_mutex, &ss->subsys_key); ss->active = 1; /* this function shouldn't be used with modular subsystems, since they @@ -4452,8 +4409,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) } write_unlock(&css_set_lock); - mutex_init(&ss->hierarchy_mutex); - lockdep_set_class(&ss->hierarchy_mutex, &ss->subsys_key); ss->active = 1; /* success! */ -- GitLab From 7721d652c716af3f4c78a84c380822fdbb148d54 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Jun 2012 11:44:27 +0530 Subject: [PATCH 0839/6849] Staging: ipack: Remove version.h header file inclusion version.h header file is no longer required. Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 0b547eedddc2..eedb00756206 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -14,7 +14,6 @@ #ifndef _TPCI200_H_ #define _TPCI200_H_ -#include #include #include #include -- GitLab From 862fe87a8bace8b3eb463d117d455d56c5a24488 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:40 +0200 Subject: [PATCH 0840/6849] Staging: ipack/bridges/tpci200: delete sysfs files To perform the installation of a mezzanine it was needed to write on these files, now it is not needed at all as the device model is properly implemented. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 225 ++---------------------- 1 file changed, 12 insertions(+), 213 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index ad2870750235..75ed600ecc77 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -365,207 +365,9 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) return ret; } -#ifdef CONFIG_SYSFS - -static struct ipack_device *tpci200_slot_register(unsigned int tpci200_number, - unsigned int slot_position) -{ - int found = 0; - struct ipack_device *dev; - struct tpci200_board *tpci200; - - list_for_each_entry(tpci200, &tpci200_list, list) { - if (tpci200->number == tpci200_number) { - found = 1; - break; - } - } - - if (!found) { - pr_err("carrier board not found for the device\n"); - return NULL; - } - - if (slot_position >= TPCI200_NB_SLOT) { - pr_info("Slot [%d:%d] doesn't exist!\n", tpci200_number, - slot_position); - return NULL; - } - - if (mutex_lock_interruptible(&tpci200->mutex)) - return NULL; - - if (tpci200->slots[slot_position].dev != NULL) { - pr_err("Slot [%d:%d] already installed !\n", tpci200_number, - slot_position); - goto err_unlock; - } - - /* - * Give the same IRQ number as the slot number. - * The TPCI200 has assigned his own two IRQ by PCI bus driver - */ - dev = ipack_device_register(tpci200->info->ipack_bus, - slot_position, slot_position); - if (dev == NULL) { - pr_info("Slot [%d:%d] Unable to register an ipack device\n", - tpci200_number, slot_position); - goto err_unlock; - } - - tpci200->slots[slot_position].dev = dev; - mutex_unlock(&tpci200->mutex); - return dev; - -err_unlock: - mutex_unlock(&tpci200->mutex); - return NULL; -} - -static ssize_t tpci200_store_board(struct device *pdev, const char *buf, - size_t count, int slot) -{ - struct tpci200_board *card = dev_get_drvdata(pdev); - struct ipack_device *dev = card->slots[slot].dev; - - if (dev != NULL) - return -EBUSY; - - dev = tpci200_slot_register(card->number, slot); - if (dev == NULL) - return -ENODEV; - - return count; -} - -static ssize_t tpci200_show_board(struct device *pdev, char *buf, int slot) -{ - struct tpci200_board *card = dev_get_drvdata(pdev); - struct ipack_device *dev = card->slots[slot].dev; - - if (dev != NULL) - return snprintf(buf, PAGE_SIZE, "%s\n", dev_name(&dev->dev)); - else - return snprintf(buf, PAGE_SIZE, "none\n"); -} - -static ssize_t tpci200_show_description(struct device *pdev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, - "TEWS tpci200 carrier PCI for Industry-pack mezzanines.\n"); -} - -static ssize_t tpci200_show_board_slot0(struct device *pdev, - struct device_attribute *attr, - char *buf) -{ - return tpci200_show_board(pdev, buf, 0); -} - -static ssize_t tpci200_store_board_slot0(struct device *pdev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return tpci200_store_board(pdev, buf, count, 0); -} - -static ssize_t tpci200_show_board_slot1(struct device *pdev, - struct device_attribute *attr, - char *buf) -{ - return tpci200_show_board(pdev, buf, 1); -} - -static ssize_t tpci200_store_board_slot1(struct device *pdev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return tpci200_store_board(pdev, buf, count, 1); -} - -static ssize_t tpci200_show_board_slot2(struct device *pdev, - struct device_attribute *attr, - char *buf) -{ - return tpci200_show_board(pdev, buf, 2); -} - -static ssize_t tpci200_store_board_slot2(struct device *pdev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return tpci200_store_board(pdev, buf, count, 2); -} - - -static ssize_t tpci200_show_board_slot3(struct device *pdev, - struct device_attribute *attr, - char *buf) -{ - return tpci200_show_board(pdev, buf, 3); -} - -static ssize_t tpci200_store_board_slot3(struct device *pdev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return tpci200_store_board(pdev, buf, count, 3); -} - -/* Declaration of the device attributes for the TPCI200 */ -static DEVICE_ATTR(description, S_IRUGO, - tpci200_show_description, NULL); -static DEVICE_ATTR(board_slot0, S_IRUGO | S_IWUSR, - tpci200_show_board_slot0, tpci200_store_board_slot0); -static DEVICE_ATTR(board_slot1, S_IRUGO | S_IWUSR, - tpci200_show_board_slot1, tpci200_store_board_slot1); -static DEVICE_ATTR(board_slot2, S_IRUGO | S_IWUSR, - tpci200_show_board_slot2, tpci200_store_board_slot2); -static DEVICE_ATTR(board_slot3, S_IRUGO | S_IWUSR, - tpci200_show_board_slot3, tpci200_store_board_slot3); - -static struct attribute *tpci200_attrs[] = { - &dev_attr_description.attr, - &dev_attr_board_slot0.attr, - &dev_attr_board_slot1.attr, - &dev_attr_board_slot2.attr, - &dev_attr_board_slot3.attr, - NULL, -}; - -static struct attribute_group tpci200_attr_group = { - .attrs = tpci200_attrs, -}; - -static int tpci200_create_sysfs_files(struct tpci200_board *card) -{ - return sysfs_create_group(&card->info->pdev->dev.kobj, - &tpci200_attr_group); -} - -static void tpci200_remove_sysfs_files(struct tpci200_board *card) -{ - sysfs_remove_group(&card->info->pdev->dev.kobj, &tpci200_attr_group); -} - -#else - -static int tpci200_create_sysfs_files(struct tpci200_board *card) -{ - return 0; -} - -static void tpci200_remove_sysfs_files(struct tpci200_board *card) -{ -} - -#endif /* CONFIG_SYSFS */ - static int tpci200_register(struct tpci200_board *tpci200) { - int i; + int i; int res; unsigned long ioidint_base; unsigned long mem_base; @@ -574,12 +376,6 @@ static int tpci200_register(struct tpci200_board *tpci200) if (pci_enable_device(tpci200->info->pdev) < 0) return -ENODEV; - if (tpci200_create_sysfs_files(tpci200) < 0) { - pr_err("failed creating sysfs files\n"); - res = -EFAULT; - goto out_disable_pci; - } - /* Request IP interface register (Bar 2) */ res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, "Carrier IP interface registers"); @@ -587,7 +383,7 @@ static int tpci200_register(struct tpci200_board *tpci200) pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_remove_sysfs; + goto out_disable_pci; } /* Request IO ID INT space (Bar 3) */ @@ -668,8 +464,7 @@ static int tpci200_register(struct tpci200_board *tpci200) pr_err("(bn 0x%X, sn 0x%X) unable to register IRQ !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - tpci200_unregister(tpci200); - goto out_err; + goto out_release_ioid_int_space; } return 0; @@ -678,11 +473,8 @@ out_release_ioid_int_space: pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); out_release_ip_space: pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); -out_remove_sysfs: - tpci200_remove_sysfs_files(tpci200); out_disable_pci: pci_disable_device(tpci200->info->pdev); -out_err: return res; } @@ -1038,7 +830,7 @@ out_err: static int tpci200_pciprobe(struct pci_dev *pdev, const struct pci_device_id *id) { - int ret; + int ret, i; struct tpci200_board *tpci200; tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); @@ -1081,13 +873,20 @@ static int tpci200_pciprobe(struct pci_dev *pdev, dev_set_drvdata(&pdev->dev, tpci200); /* add the registered device in an internal linked list */ list_add_tail(&tpci200->list, &tpci200_list); + + /* + * Give the same IRQ number as the slot number. + * The TPCI200 has assigned his own two IRQ by PCI bus driver + */ + for (i = 0; i < TPCI200_NB_SLOT; i++) + tpci200->slots[i].dev = + ipack_device_register(tpci200->info->ipack_bus, i, i); return ret; } static void __tpci200_pci_remove(struct tpci200_board *tpci200) { tpci200_uninstall(tpci200); - tpci200_remove_sysfs_files(tpci200); list_del(&tpci200->list); ipack_bus_unregister(tpci200->info->ipack_bus); kfree(tpci200->info); -- GitLab From be98cc1daa0419f31472c21e45aec30d24fa5931 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:41 +0200 Subject: [PATCH 0841/6849] Staging: ipack: return proper value in match() function It should return the same value given by the match function of the ipack_driver that has been called. Returning 0 here, means that the match has failed and it could be succeed. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 2b4fa51bf167..e6dc21a47a0a 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -48,7 +48,7 @@ static int ipack_bus_match(struct device *device, struct device_driver *driver) if (ret) dev->driver = drv; - return 0; + return ret; } static int ipack_bus_probe(struct device *device) -- GitLab From 38f1c53df288b56ad4b8421b13fbdb7232e92270 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:42 +0200 Subject: [PATCH 0842/6849] Staging: ipack/bridges/tpci200: tpci200_slot_unmap_space() should return 0 if succeed. tpci200_slot_unmap_space() should return 0 if the operation was properly done. If not, the caller will think that something wrong happened. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 75ed600ecc77..85560c729703 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -551,20 +551,15 @@ out: static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) { - int res; struct ipack_addr_space *virt_addr_space; struct tpci200_board *tpci200; tpci200 = check_slot(dev); - if (tpci200 == NULL) { - res = -EINVAL; - goto out; - } + if (tpci200 == NULL) + return -EINVAL; - if (mutex_lock_interruptible(&tpci200->mutex)) { - res = -ERESTARTSYS; - goto out; - } + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; switch (space) { case IPACK_IO_SPACE: @@ -594,9 +589,8 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) default: pr_err("Slot [%d:%d] space number %d doesn't exist !\n", dev->bus_nr, dev->slot, space); - res = -EINVAL; - goto out_unlock; - break; + mutex_unlock(&tpci200->mutex); + return -EINVAL; } iounmap(virt_addr_space->address); @@ -605,8 +599,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) virt_addr_space->size = 0; out_unlock: mutex_unlock(&tpci200->mutex); -out: - return res; + return 0; } static int tpci200_slot_unregister(struct ipack_device *dev) -- GitLab From 6ad0c486a4e702fa059ea24c2585c416f01f4664 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:43 +0200 Subject: [PATCH 0843/6849] Staging: ipack/bridges/tpci200: tpci200_slot_map_space() should return 0 if succeed. tpci200_slot_map_space() should return 0 if the operation was properly done. If not, the caller will think that something wrong happened. This patch establish the returned value to 0. It is overwritten in case of error. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 85560c729703..0c2a50a1ec00 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -628,7 +628,7 @@ static int tpci200_slot_unregister(struct ipack_device *dev) static int tpci200_slot_map_space(struct ipack_device *dev, unsigned int memory_size, int space) { - int res; + int res = 0; unsigned int size_to_map; void __iomem *phys_address; struct ipack_addr_space *virt_addr_space; -- GitLab From 786d986ea25632e3d8e7ad5ac2780861ff2b654f Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:44 +0200 Subject: [PATCH 0844/6849] Staging: ipack/bridges/tpci200: check if the remove function is available To avoid a dereference of a NULL pointer, the availability of the function is checked before its use. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 0c2a50a1ec00..ee26d9a7e370 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -764,6 +764,8 @@ out: static void tpci200_slot_remove(struct tpci200_slot *slot) { if ((slot->dev == NULL) || + (slot->dev->driver == NULL) || + (slot->dev->driver->ops == NULL) || (slot->dev->driver->ops->remove == NULL)) return; -- GitLab From e149ef80b08d92a27a9a8333719fe392955af798 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:45 +0200 Subject: [PATCH 0845/6849] Staging: ipack/bridges/tpci200: fix indention. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index ee26d9a7e370..24070a3ff210 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -582,7 +582,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) if (dev->mem_space.address == NULL) { pr_info("Slot [%d:%d] MEM space not mapped !\n", dev->bus_nr, dev->slot); - goto out_unlock; + goto out_unlock; } virt_addr_space = &dev->mem_space; break; -- GitLab From 1fc75280f1e48d8f941dfea881d0f5b53fca27f6 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:46 +0200 Subject: [PATCH 0846/6849] Staging: ipack/bridges/tpci200: remove name field from slot_irq This field is not needed at all, as the IRQ is registered for the carrier not for the mezzanine. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 1 - drivers/staging/ipack/bridges/tpci200.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 24070a3ff210..96bfe5b3ca23 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -750,7 +750,6 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, slot_irq->vector = vector; slot_irq->handler = handler; slot_irq->arg = arg; - slot_irq->name = dev_name(&dev->dev); tpci200->slots[dev->slot].irq = slot_irq; res = __tpci200_request_irq(tpci200, dev); diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index eedb00756206..97ff0d6636b6 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -105,14 +105,12 @@ * @vector Vector number * @handler Handler called when IRQ arrives * @arg Handler argument - * @name IRQ name * */ struct slot_irq { int vector; int (*handler)(void *); void *arg; - const char *name; }; /** -- GitLab From 65260291c13d148a7b7f86f3a99af14c43599fa9 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 23 May 2012 15:54:47 +0200 Subject: [PATCH 0847/6849] Staging: ipack/bridges/tpci200: removed check of tpci200->slots[dev->slot].dev When ipack_device_register() is called, the variable tpci200->slots[dev->slot].dev has not assigned a value and it gives an error when the mezzanine driver is reading a register from the board for the match() function, as all the I/O functions call check_slot(). Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 96bfe5b3ca23..67516255480b 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -59,13 +59,6 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) return NULL; } - BUG_ON(tpci200->slots == NULL); - if (tpci200->slots[dev->slot].dev == NULL) { - pr_info("Slot [%d:%d] is not registered !\n", dev->bus_nr, - dev->slot); - return NULL; - } - return tpci200; } -- GitLab From 3b86bb2e11d854d258c5e05d709865ca3d3c8951 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 10:03:01 +0200 Subject: [PATCH 0848/6849] Staging: ipack: use idr interface for numbering buses Use idr interface to give the bus number. That way, we remove the limitation of 64 buses. The mutex is removed because the ida interface uses spinlocks inside, so it is not needed an extra lock. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 40 ++++++----------------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index e6dc21a47a0a..e97be9960098 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -12,22 +12,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include +#include #include "ipack.h" #define to_ipack_dev(device) container_of(device, struct ipack_device, dev) #define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) -/* used when allocating bus numbers */ -#define IPACK_MAXBUS 64 - -static DEFINE_MUTEX(ipack_mutex); - -struct ipack_busmap { - unsigned long busmap[IPACK_MAXBUS / (8*sizeof(unsigned long))]; -}; -static struct ipack_busmap busmap; +static DEFINE_IDA(ipack_ida); static void ipack_device_release(struct device *dev) { @@ -79,26 +71,6 @@ static struct bus_type ipack_bus_type = { .remove = ipack_bus_remove, }; -static int ipack_assign_bus_number(void) -{ - int busnum; - - mutex_lock(&ipack_mutex); - busnum = find_next_zero_bit(busmap.busmap, IPACK_MAXBUS, 1); - - if (busnum >= IPACK_MAXBUS) { - pr_err("too many buses\n"); - busnum = -1; - goto error_find_busnum; - } - - set_bit(busnum, busmap.busmap); - -error_find_busnum: - mutex_unlock(&ipack_mutex); - return busnum; -} - struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, struct ipack_bus_ops *ops) { @@ -109,7 +81,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, if (!bus) return NULL; - bus_nr = ipack_assign_bus_number(); + bus_nr = ida_simple_get(&ipack_ida, 0, 0, GFP_KERNEL); if (bus_nr < 0) { kfree(bus); return NULL; @@ -125,9 +97,7 @@ EXPORT_SYMBOL_GPL(ipack_bus_register); int ipack_bus_unregister(struct ipack_bus_device *bus) { - mutex_lock(&ipack_mutex); - clear_bit(bus->bus_nr, busmap.busmap); - mutex_unlock(&ipack_mutex); + ida_simple_remove(&ipack_ida, bus->bus_nr); kfree(bus); return 0; } @@ -189,12 +159,14 @@ EXPORT_SYMBOL_GPL(ipack_device_unregister); static int __init ipack_init(void) { + ida_init(&ipack_ida); return bus_register(&ipack_bus_type); } static void __exit ipack_exit(void) { bus_unregister(&ipack_bus_type); + ida_destroy(&ipack_ida); } module_init(ipack_init); -- GitLab From b2bc13c5e07501a0a4427b6a9eff8162aef5560a Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 10:03:02 +0200 Subject: [PATCH 0849/6849] Staging: ipack: delete the call to remove() in ipack_driver_register When a bus driver calls ipack_driver_register(), it should manages the returning NULL value to undo all the operations it did before this call, and print the corresponding trace. It is not a task for the ipack driver to call the remove() function here. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index e97be9960098..a1448e68fd7a 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -141,8 +141,6 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, ret = device_register(&dev->dev); if (ret < 0) { - pr_err("error registering the device.\n"); - dev->driver->ops->remove(dev); kfree(dev); return NULL; } -- GitLab From 597d473f163a1672262b845ede8a65afdf1b27c6 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 10:03:03 +0200 Subject: [PATCH 0850/6849] Staging: ipack/devices/ipoctal: avoid kernel oops when uninstalling When uninstalling a device, there is a loop of calls that produces, at the end, two calls to __ipoctal_remove() function with the same ipack_device argument. The first time works fine, but the second will fail in tty_unregister_driver() To avoid this situation, the call to __ipoctal_remove() it is done only from the ipack bus driver and not from the ipack device driver. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 29f6fa841d23..a6f424e65e39 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -853,11 +853,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) tty_unregister_driver(ipoctal->tty_drv); put_tty_driver(ipoctal->tty_drv); - - /* Tell the carrier board to free all the resources for this device */ - if (ipoctal->dev->bus->ops->remove_device != NULL) - ipoctal->dev->bus->ops->remove_device(ipoctal->dev); - list_del(&ipoctal->list); kfree(ipoctal); } @@ -889,7 +884,7 @@ static void __exit ipoctal_exit(void) struct ipoctal *p, *next; list_for_each_entry_safe(p, next, &ipoctal_list, list) - __ipoctal_remove(p); + p->dev->bus->ops->remove_device(p->dev); ipack_driver_unregister(&driver); } -- GitLab From ca2d2bb6618396ec0a79b182fcd1591ef62b07cb Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 10:03:04 +0200 Subject: [PATCH 0851/6849] Staging: ipack/bridges/tpci200: avoid dereference of a freed tpci200->info tpci200->info is used later when uninstalling the module. As there is another kfree in the proper place, this patch removes the wrong one. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 67516255480b..e04cb8ade9e7 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -290,8 +290,6 @@ static void tpci200_unregister(struct tpci200_board *tpci200) pci_disable_device(tpci200->info->pdev); pci_dev_put(tpci200->info->pdev); - kfree(tpci200->info); - for (i = 0; i < TPCI200_NB_SLOT; i++) { tpci200->slots[i].io_phys.address = NULL; tpci200->slots[i].io_phys.size = 0; -- GitLab From 20cf70082440ffabbec5c275726f68fe53872c94 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 10:03:05 +0200 Subject: [PATCH 0852/6849] Staging: ipack/bridges/tpci200: fix kernel oops when uninstalling a device When uninstalling a device, the call to the ipack_bus_ops remove() frees resources in the ipack device driver but without unregistering the device. It generates a kernel oops when somebody wants to unregister the device. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index e04cb8ade9e7..46127bca1af2 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -751,23 +751,12 @@ out: return res; } -static void tpci200_slot_remove(struct tpci200_slot *slot) -{ - if ((slot->dev == NULL) || - (slot->dev->driver == NULL) || - (slot->dev->driver->ops == NULL) || - (slot->dev->driver->ops->remove == NULL)) - return; - - slot->dev->driver->ops->remove(slot->dev); -} - static void tpci200_uninstall(struct tpci200_board *tpci200) { int i; for (i = 0; i < TPCI200_NB_SLOT; i++) - tpci200_slot_remove(&tpci200->slots[i]); + tpci200_slot_unregister(tpci200->slots[i].dev); tpci200_unregister(tpci200); kfree(tpci200->slots); -- GitLab From a23d32037073bbc818263ac26077a9981218a0d0 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 13:08:12 +0200 Subject: [PATCH 0853/6849] Staging: ipack/bridges/tpci200: change pr_* usage for dev_* functions Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 126 +++++++++++++----------- 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 46127bca1af2..c39499a81f6c 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -11,8 +11,6 @@ * Software Foundation; version 2 of the License. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include "tpci200.h" @@ -36,10 +34,8 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) struct tpci200_board *tpci200; int found = 0; - if (dev == NULL) { - pr_info("Slot doesn't exist.\n"); + if (dev == NULL) return NULL; - } list_for_each_entry(tpci200, &tpci200_list, list) { if (tpci200->number == dev->bus_nr) { @@ -49,13 +45,14 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) } if (!found) { - pr_err("Carrier not found\n"); + dev_err(&dev->dev, "Carrier not found\n"); return NULL; } if (dev->slot >= TPCI200_NB_SLOT) { - pr_info("Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", - dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1); + dev_info(&dev->dev, + "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", + dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1); return NULL; } @@ -116,14 +113,15 @@ static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev, addr = &dev->mem_space; break; default: - pr_err("Slot [%d:%d] space number %d doesn't exist !\n", - dev->bus_nr, dev->slot, space); + dev_err(&dev->dev, + "Slot [%d:%d] space number %d doesn't exist !\n", + dev->bus_nr, dev->slot, space); return NULL; break; } if ((addr->size == 0) || (addr->address == NULL)) { - pr_err("Error, slot space not mapped !\n"); + dev_err(&dev->dev, "Error, slot space not mapped !\n"); return NULL; } @@ -145,7 +143,7 @@ static int tpci200_read8(struct ipack_device *dev, int space, return -EINVAL; if (offset >= addr->size) { - pr_err("Error, slot space offset error !\n"); + dev_err(&dev->dev, "Error, slot space offset error !\n"); return -EFAULT; } @@ -169,7 +167,7 @@ static int tpci200_read16(struct ipack_device *dev, int space, return -EINVAL; if ((offset+2) >= addr->size) { - pr_err("Error, slot space offset error !\n"); + dev_err(&dev->dev, "Error, slot space offset error !\n"); return -EFAULT; } *value = __tpci200_read16(addr->address, offset); @@ -192,7 +190,7 @@ static int tpci200_read32(struct ipack_device *dev, int space, return -EINVAL; if ((offset+4) >= addr->size) { - pr_err("Error, slot space offset error !\n"); + dev_err(&dev->dev, "Error, slot space offset error !\n"); return -EFAULT; } @@ -216,7 +214,7 @@ static int tpci200_write8(struct ipack_device *dev, int space, return -EINVAL; if (offset >= addr->size) { - pr_err("Error, slot space offset error !\n"); + dev_err(&dev->dev, "Error, slot space offset error !\n"); return -EFAULT; } @@ -240,7 +238,7 @@ static int tpci200_write16(struct ipack_device *dev, int space, return -EINVAL; if ((offset+2) >= addr->size) { - pr_err("Error, slot space offset error !\n"); + dev_err(&dev->dev, "Error, slot space offset error !\n"); return -EFAULT; } @@ -264,7 +262,7 @@ static int tpci200_write32(struct ipack_device *dev, int space, return -EINVAL; if ((offset+4) >= addr->size) { - pr_err("Error, slot space offset error !\n"); + dev_err(&dev->dev, "Error, slot space offset error !\n"); return -EFAULT; } @@ -338,8 +336,9 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) if (unhandled_ints) { for (i = 0; i < TPCI200_NB_SLOT; i++) { if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) { - pr_info("No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", - tpci200->number, i); + dev_info(&tpci200->slots[i].dev->dev, + "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", + tpci200->number, i); reg_value = readw( tpci200->info->interface_regs + control_reg[i]); @@ -371,9 +370,10 @@ static int tpci200_register(struct tpci200_board *tpci200) res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, "Carrier IP interface registers"); if (res) { - pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); goto out_disable_pci; } @@ -382,9 +382,10 @@ static int tpci200_register(struct tpci200_board *tpci200) TPCI200_IO_ID_INT_SPACES_BAR, "Carrier IO ID INT space"); if (res) { - pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); goto out_release_ip_space; } @@ -392,9 +393,10 @@ static int tpci200_register(struct tpci200_board *tpci200) res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, "Carrier MEM space"); if (res) { - pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); goto out_release_ioid_int_space; } @@ -452,9 +454,10 @@ static int tpci200_register(struct tpci200_board *tpci200) tpci200_interrupt, IRQF_SHARED, KBUILD_MODNAME, (void *) tpci200); if (res) { - pr_err("(bn 0x%X, sn 0x%X) unable to register IRQ !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) unable to register IRQ !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); goto out_release_ioid_int_space; } @@ -555,31 +558,35 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) switch (space) { case IPACK_IO_SPACE: if (dev->io_space.address == NULL) { - pr_info("Slot [%d:%d] IO space not mapped !\n", - dev->bus_nr, dev->slot); + dev_info(&dev->dev, + "Slot [%d:%d] IO space not mapped !\n", + dev->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->io_space; break; case IPACK_ID_SPACE: if (dev->id_space.address == NULL) { - pr_info("Slot [%d:%d] ID space not mapped !\n", - dev->bus_nr, dev->slot); + dev_info(&dev->dev, + "Slot [%d:%d] ID space not mapped !\n", + dev->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->id_space; break; case IPACK_MEM_SPACE: if (dev->mem_space.address == NULL) { - pr_info("Slot [%d:%d] MEM space not mapped !\n", - dev->bus_nr, dev->slot); + dev_info(&dev->dev, + "Slot [%d:%d] MEM space not mapped !\n", + dev->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->mem_space; break; default: - pr_err("Slot [%d:%d] space number %d doesn't exist !\n", - dev->bus_nr, dev->slot, space); + dev_err(&dev->dev, + "Slot [%d:%d] space number %d doesn't exist !\n", + dev->bus_nr, dev->slot, space); mutex_unlock(&tpci200->mutex); return -EINVAL; } @@ -639,8 +646,9 @@ static int tpci200_slot_map_space(struct ipack_device *dev, switch (space) { case IPACK_IO_SPACE: if (dev->io_space.address != NULL) { - pr_err("Slot [%d:%d] IO space already mapped !\n", - tpci200->number, dev->slot); + dev_err(&dev->dev, + "Slot [%d:%d] IO space already mapped !\n", + tpci200->number, dev->slot); res = -EINVAL; goto out_unlock; } @@ -651,8 +659,9 @@ static int tpci200_slot_map_space(struct ipack_device *dev, break; case IPACK_ID_SPACE: if (dev->id_space.address != NULL) { - pr_err("Slot [%d:%d] ID space already mapped !\n", - tpci200->number, dev->slot); + dev_err(&dev->dev, + "Slot [%d:%d] ID space already mapped !\n", + tpci200->number, dev->slot); res = -EINVAL; goto out_unlock; } @@ -663,17 +672,19 @@ static int tpci200_slot_map_space(struct ipack_device *dev, break; case IPACK_MEM_SPACE: if (dev->mem_space.address != NULL) { - pr_err("Slot [%d:%d] MEM space already mapped !\n", - tpci200->number, dev->slot); + dev_err(&dev->dev, + "Slot [%d:%d] MEM space already mapped !\n", + tpci200->number, dev->slot); res = -EINVAL; goto out_unlock; } virt_addr_space = &dev->mem_space; if (memory_size > tpci200->slots[dev->slot].mem_phys.size) { - pr_err("Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n", - dev->bus_nr, dev->slot, memory_size, - tpci200->slots[dev->slot].mem_phys.size); + dev_err(&dev->dev, + "Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n", + dev->bus_nr, dev->slot, memory_size, + tpci200->slots[dev->slot].mem_phys.size); res = -EINVAL; goto out_unlock; } @@ -682,8 +693,8 @@ static int tpci200_slot_map_space(struct ipack_device *dev, size_to_map = memory_size; break; default: - pr_err("Slot [%d:%d] space %d doesn't exist !\n", - tpci200->number, dev->slot, space); + dev_err(&dev->dev, "Slot [%d:%d] space %d doesn't exist !\n", + tpci200->number, dev->slot, space); res = -EINVAL; goto out_unlock; break; @@ -718,16 +729,18 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, } if (tpci200->slots[dev->slot].irq != NULL) { - pr_err("Slot [%d:%d] IRQ already registered !\n", dev->bus_nr, - dev->slot); + dev_err(&dev->dev, + "Slot [%d:%d] IRQ already registered !\n", dev->bus_nr, + dev->slot); res = -EINVAL; goto out_unlock; } slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); if (slot_irq == NULL) { - pr_err("Slot [%d:%d] unable to allocate memory for IRQ !\n", - dev->bus_nr, dev->slot); + dev_err(&dev->dev, + "Slot [%d:%d] unable to allocate memory for IRQ !\n", + dev->bus_nr, dev->slot); res = -ENOMEM; goto out_unlock; } @@ -824,7 +837,7 @@ static int tpci200_pciprobe(struct pci_dev *pdev, /* register the device and initialize it */ ret = tpci200_install(tpci200); if (ret) { - pr_err("Error during tpci200 install !\n"); + dev_err(&pdev->dev, "Error during tpci200 install !\n"); kfree(tpci200->info); kfree(tpci200); return -ENODEV; @@ -835,7 +848,8 @@ static int tpci200_pciprobe(struct pci_dev *pdev, TPCI200_NB_SLOT, &tpci200_bus_ops); if (!tpci200->info->ipack_bus) { - pr_err("error registering the carrier on ipack driver\n"); + dev_err(&pdev->dev, + "error registering the carrier on ipack driver\n"); tpci200_uninstall(tpci200); kfree(tpci200->info); kfree(tpci200); -- GitLab From 42b38207c36890ead05ab1c0002714c48b9b996a Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 25 May 2012 13:08:13 +0200 Subject: [PATCH 0854/6849] Staging: ipack/devices/ipoctal: change pr_* usage for dev_* functions Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index a6f424e65e39..17aa35a9de63 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -11,8 +11,6 @@ * Software Foundation; version 2 of the License. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -116,7 +114,8 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) ipoctal = ipoctal_find_board(tty); if (ipoctal == NULL) { - pr_err("Device not found. Major %d\n", tty->driver->major); + dev_err(tty->dev, "Device not found. Major %d\n", + tty->driver->major); return -ENODEV; } @@ -136,7 +135,8 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file) ipoctal = ipoctal_find_board(tty); if (ipoctal == NULL) { - pr_err("Device not found. Major %d\n", tty->driver->major); + dev_err(tty->dev, "Device not found. Major %d\n", + tty->driver->major); return -ENODEV; } @@ -381,7 +381,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, IPACK_ID_SPACE); if (res) { - pr_err("Unable to map slot [%d:%d] ID space!\n", bus_nr, slot); + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] ID space!\n", + bus_nr, slot); return res; } @@ -396,14 +398,18 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, IPACK_IO_SPACE); if (res) { - pr_err("Unable to map slot [%d:%d] IO space!\n", bus_nr, slot); + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] IO space!\n", + bus_nr, slot); goto out_unregister_id_space; } res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0x8000, IPACK_MEM_SPACE); if (res) { - pr_err("Unable to map slot [%d:%d] MEM space!\n", bus_nr, slot); + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] MEM space!\n", + bus_nr, slot); goto out_unregister_io_space; } @@ -472,7 +478,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, tty_set_operations(tty, &ipoctal_fops); res = tty_register_driver(tty); if (res) { - pr_err("Can't register tty driver.\n"); + dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); put_tty_driver(tty); goto out_unregister_slot_unmap; } -- GitLab From a21e6bfeb40eddf365d3e7841b37f3708fa6b13f Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 5 Jun 2012 11:52:18 +0200 Subject: [PATCH 0855/6849] iio: adf4350: fix compiler warning [-Wuninitialized] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/iio/frequency/adf4350.c:316:32: warning: ‘val’ may be used uninitialized in this function [-Wuninitialized] Signed-off-by: Michael Hennerich Reported-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/iio/frequency/adf4350.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index fd4c8501aba9..2d09f82d9752 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -310,6 +310,8 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, case ADF4350_PWRDOWN: val = !!(st->regs[ADF4350_REG2] & ADF4350_REG2_POWER_DOWN_EN); break; + default: + ret = -ENODEV; } mutex_unlock(&indio_dev->mlock); -- GitLab From 74dcd439bf8c16b01f9f5a9dffb2b171ed94e2e5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 5 Jun 2012 18:24:12 +0200 Subject: [PATCH 0856/6849] iio: iio_enum_available_read: Prevent possible buffer overflow Use scnprint instead of snprintf, because snprintf returns the number of bytes that would have been written to the buffer if there was enough space, and as a result writing to buf[len-1] might cause a access beyond the buffers limits. Reported-by: Dan Carpenter Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 56a3c0bc996c..cf9ecd0ae7c9 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -300,7 +300,7 @@ ssize_t iio_enum_available_read(struct iio_dev *indio_dev, return 0; for (i = 0; i < e->num_items; ++i) - len += snprintf(buf + len, PAGE_SIZE - len, "%s ", e->items[i]); + len += scnprintf(buf + len, PAGE_SIZE - len, "%s ", e->items[i]); /* replace last space with a newline */ buf[len - 1] = '\n'; -- GitLab From 040f3e5833b9426aaeead6da8957a9b87f3ca9e8 Mon Sep 17 00:00:00 2001 From: Leed Aguilar Date: Wed, 6 Jun 2012 16:14:56 -0400 Subject: [PATCH 0857/6849] staging:iio:magnetometer:ak8975: set power-down mode after reading fuse ROM data Fuse ROM data access mode is the only mode which does not transition to power-down mode automatically. As per the AK8975 data sheet, it is recomended to set the power-down mode first before attempting to change into another mode. Signed-off-by: Leed Aguilar Acked-by: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 7562cafb26bb..001b3bff4765 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -194,6 +194,17 @@ static int ak8975_setup(struct i2c_client *client) return ret; } + /* After reading fuse ROM data set power-down mode */ + ret = ak8975_write_data(client, + AK8975_REG_CNTL, + AK8975_REG_CNTL_MODE_POWER_DOWN, + AK8975_REG_CNTL_MODE_MASK, + AK8975_REG_CNTL_MODE_SHIFT); + if (ret < 0) { + dev_err(&client->dev, "Error in setting power-down mode\n"); + return ret; + } + /* * Precalculate scale factor (in Gauss units) for each axis and * store in the device data. -- GitLab From 82f2acdce16ad7f124b6bb38c10a1894aa534864 Mon Sep 17 00:00:00 2001 From: Leed Aguilar Date: Wed, 6 Jun 2012 16:15:40 -0400 Subject: [PATCH 0858/6849] staging:iio:magnetometer:ak8975: use gpio_request_one api Use gpio_request_one api, it looks cleaner. Signed-off-by: Leed Aguilar Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/Kconfig | 2 +- drivers/staging/iio/magnetometer/ak8975.c | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig index b9d932595ba9..df5e0d4ea295 100644 --- a/drivers/staging/iio/magnetometer/Kconfig +++ b/drivers/staging/iio/magnetometer/Kconfig @@ -6,7 +6,7 @@ menu "Magnetometer sensors" config SENSORS_AK8975 tristate "Asahi Kasei AK8975 3-Axis Magnetometer" depends on I2C - depends on GENERIC_GPIO + depends on GPIOLIB help Say yes here to build support for Asahi Kasei AK8975 3-Axis Magnetometer. diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 001b3bff4765..11bde3fd93b5 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -499,21 +499,13 @@ static int __devinit ak8975_probe(struct i2c_client *client, /* We may not have a GPIO based IRQ to scan, that is fine, we will poll if so */ if (gpio_is_valid(eoc_gpio)) { - err = gpio_request(eoc_gpio, "ak_8975"); + err = gpio_request_one(eoc_gpio, GPIOF_IN, "ak_8975"); if (err < 0) { dev_err(&client->dev, "failed to request GPIO %d, error %d\n", eoc_gpio, err); goto exit; } - - err = gpio_direction_input(eoc_gpio); - if (err < 0) { - dev_err(&client->dev, - "Failed to configure input direction for GPIO %d, error %d\n", - eoc_gpio, err); - goto exit_gpio; - } } /* Register with IIO */ -- GitLab From 4bf8523df925869d4d27478105f23656a2411ce0 Mon Sep 17 00:00:00 2001 From: Leed Aguilar Date: Wed, 6 Jun 2012 16:16:02 -0400 Subject: [PATCH 0859/6849] staging:iio:magnetometer:ak8975: remove 'mode' attribute The raw data reading process (ak8975_read_axis) sets the single measurement mode to take a sample and once the conversion is completed the device enters into power-down mode automatically, therefore there is no need to enable a flag for this to happen. Signed-off-by: Leed Aguilar Acked-by: Jonathan Cameron Acked-by: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 73 ----------------------- 1 file changed, 73 deletions(-) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 11bde3fd93b5..01b4b07c227b 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -92,7 +92,6 @@ struct ak8975_data { struct mutex lock; u8 asa[3]; long raw_to_gauss[3]; - bool mode; u8 reg_cache[AK8975_MAX_REGS]; int eoc_gpio; int eoc_irq; @@ -247,60 +246,6 @@ static int ak8975_setup(struct i2c_client *client) return 0; } -/* - * Shows the device's mode. 0 = off, 1 = on. - */ -static ssize_t show_mode(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ak8975_data *data = iio_priv(indio_dev); - - return sprintf(buf, "%u\n", data->mode); -} - -/* - * Sets the device's mode. 0 = off, 1 = on. The device's mode must be on - * for the magn raw attributes to be available. - */ -static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ak8975_data *data = iio_priv(indio_dev); - struct i2c_client *client = data->client; - bool value; - int ret; - - /* Convert mode string and do some basic sanity checking on it. - only 0 or 1 are valid. */ - ret = strtobool(buf, &value); - if (ret < 0) - return ret; - - mutex_lock(&data->lock); - - /* Write the mode to the device. */ - if (data->mode != value) { - ret = ak8975_write_data(client, - AK8975_REG_CNTL, - (u8)value, - AK8975_REG_CNTL_MODE_MASK, - AK8975_REG_CNTL_MODE_SHIFT); - - if (ret < 0) { - dev_err(&client->dev, "Error in setting mode\n"); - mutex_unlock(&data->lock); - return ret; - } - data->mode = value; - } - - mutex_unlock(&data->lock); - - return count; -} - static int wait_conversion_complete_gpio(struct ak8975_data *data) { struct i2c_client *client = data->client; @@ -368,12 +313,6 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val) mutex_lock(&data->lock); - if (data->mode == 0) { - dev_err(&client->dev, "Operating mode is in power down mode\n"); - ret = -EBUSY; - goto exit; - } - /* Set up the device for taking a sample. */ ret = ak8975_write_data(client, AK8975_REG_CNTL, @@ -465,19 +404,7 @@ static const struct iio_chan_spec ak8975_channels[] = { AK8975_CHANNEL(X, 0), AK8975_CHANNEL(Y, 1), AK8975_CHANNEL(Z, 2), }; -static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode, 0); - -static struct attribute *ak8975_attr[] = { - &iio_dev_attr_mode.dev_attr.attr, - NULL -}; - -static struct attribute_group ak8975_attr_group = { - .attrs = ak8975_attr, -}; - static const struct iio_info ak8975_info = { - .attrs = &ak8975_attr_group, .read_raw = &ak8975_read_raw, .driver_module = THIS_MODULE, }; -- GitLab From 279bf2e57c30c9a4482b2b6ede11b31c41e35e78 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 5 Jun 2012 18:16:31 +0200 Subject: [PATCH 0860/6849] staging:iio:ad7606: Re-add missing scale attribute Commit 50ac23be ("staging:iio:adc:ad7606 add local define for chan_spec structures.") accidentally removed the scale info_mask flag. This patch adds it back again. Signed-off-by: Lars-Peter Clausen Cc: stable [3.2+] Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7606_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 10ab6dc823b9..a13afff2dfe6 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -235,7 +235,8 @@ static const struct attribute_group ad7606_attribute_group_range = { .indexed = 1, \ .channel = num, \ .address = num, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_index = num, \ .scan_type = IIO_ST('s', 16, 16, 0), \ } -- GitLab From 33f8100977693fa09c2a32b1ca6dbf4d6eabdd0c Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Tue, 29 May 2012 11:13:15 +0530 Subject: [PATCH 0861/6849] can: c_can: Move overlay structure to array with offset as index c_can uses overlay structure for accessing c_can module registers. With this kind of implementation it is difficult to add one more ip which is similar to c_can in functionality but different register offsets. This patch changes the overlay structure implementation to an array with register offset as index. This way we can overcome the above limitation. Signed-off-by: AnilKumar Ch Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 120 +++++++++++++------------ drivers/net/can/c_can/c_can.h | 118 ++++++++++++++++-------- drivers/net/can/c_can/c_can_platform.c | 23 ++--- 3 files changed, 154 insertions(+), 107 deletions(-) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 8dc84d66eea1..e2ce508c2753 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -41,6 +41,10 @@ #include "c_can.h" +/* Number of interface registers */ +#define IF_ENUM_REG_LEN 11 +#define C_CAN_IFACE(reg, iface) (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN) + /* control register */ #define CONTROL_TEST BIT(7) #define CONTROL_CCE BIT(6) @@ -209,10 +213,10 @@ static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) C_CAN_MSG_OBJ_TX_FIRST; } -static u32 c_can_read_reg32(struct c_can_priv *priv, void *reg) +static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) { - u32 val = priv->read_reg(priv, reg); - val |= ((u32) priv->read_reg(priv, reg + 2)) << 16; + u32 val = priv->read_reg(priv, index); + val |= ((u32) priv->read_reg(priv, index + 1)) << 16; return val; } @@ -220,14 +224,14 @@ static void c_can_enable_all_interrupts(struct c_can_priv *priv, int enable) { unsigned int cntrl_save = priv->read_reg(priv, - &priv->regs->control); + C_CAN_CTRL_REG); if (enable) cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); else cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); - priv->write_reg(priv, &priv->regs->control, cntrl_save); + priv->write_reg(priv, C_CAN_CTRL_REG, cntrl_save); } static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) @@ -235,7 +239,7 @@ static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) int count = MIN_TIMEOUT_VALUE; while (count && priv->read_reg(priv, - &priv->regs->ifregs[iface].com_req) & + C_CAN_IFACE(COMREQ_REG, iface)) & IF_COMR_BUSY) { count--; udelay(1); @@ -258,9 +262,9 @@ static inline void c_can_object_get(struct net_device *dev, * register and message RAM must be complete in 6 CAN-CLK * period. */ - priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, + priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), IFX_WRITE_LOW_16BIT(mask)); - priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, + priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), IFX_WRITE_LOW_16BIT(objno)); if (c_can_msg_obj_is_busy(priv, iface)) @@ -278,9 +282,9 @@ static inline void c_can_object_put(struct net_device *dev, * register and message RAM must be complete in 6 CAN-CLK * period. */ - priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, + priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); - priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, + priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), IFX_WRITE_LOW_16BIT(objno)); if (c_can_msg_obj_is_busy(priv, iface)) @@ -306,18 +310,18 @@ static void c_can_write_msg_object(struct net_device *dev, flags |= IF_ARB_MSGVAL; - priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, + priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), IFX_WRITE_LOW_16BIT(id)); - priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, flags | + priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags | IFX_WRITE_HIGH_16BIT(id)); for (i = 0; i < frame->can_dlc; i += 2) { - priv->write_reg(priv, &priv->regs->ifregs[iface].data[i / 2], + priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, frame->data[i] | (frame->data[i + 1] << 8)); } /* enable interrupt for this message object */ - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | frame->can_dlc); c_can_object_put(dev, iface, objno, IF_COMM_ALL); @@ -329,7 +333,7 @@ static inline void c_can_mark_rx_msg_obj(struct net_device *dev, { struct c_can_priv *priv = netdev_priv(dev); - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); @@ -343,7 +347,7 @@ static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, struct c_can_priv *priv = netdev_priv(dev); for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); c_can_object_put(dev, iface, i, IF_COMM_CONTROL); @@ -356,7 +360,7 @@ static inline void c_can_activate_rx_msg_obj(struct net_device *dev, { struct c_can_priv *priv = netdev_priv(dev); - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); @@ -374,7 +378,7 @@ static void c_can_handle_lost_msg_obj(struct net_device *dev, c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), IF_MCONT_CLR_MSGLST); c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); @@ -410,8 +414,8 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) frame->can_dlc = get_can_dlc(ctrl & 0x0F); - flags = priv->read_reg(priv, &priv->regs->ifregs[iface].arb2); - val = priv->read_reg(priv, &priv->regs->ifregs[iface].arb1) | + flags = priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)); + val = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)) | (flags << 16); if (flags & IF_ARB_MSGXTD) @@ -424,7 +428,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) else { for (i = 0; i < frame->can_dlc; i += 2) { data = priv->read_reg(priv, - &priv->regs->ifregs[iface].data[i / 2]); + C_CAN_IFACE(DATA1_REG, iface) + i / 2); frame->data[i] = data; frame->data[i + 1] = data >> 8; } @@ -444,40 +448,40 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface, { struct c_can_priv *priv = netdev_priv(dev); - priv->write_reg(priv, &priv->regs->ifregs[iface].mask1, + priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), IFX_WRITE_LOW_16BIT(mask)); - priv->write_reg(priv, &priv->regs->ifregs[iface].mask2, + priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), IFX_WRITE_HIGH_16BIT(mask)); - priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, + priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), IFX_WRITE_LOW_16BIT(id)); - priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, + priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, mcont); + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont); c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, - c_can_read_reg32(priv, &priv->regs->msgval1)); + c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); } static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) { struct c_can_priv *priv = netdev_priv(dev); - priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, 0); - priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, 0); - priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, 0); + priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0); + priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0); + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0); c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, - c_can_read_reg32(priv, &priv->regs->msgval1)); + c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); } static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) { - int val = c_can_read_reg32(priv, &priv->regs->txrqst1); + int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); /* * as transmission request register's bit n-1 corresponds to @@ -540,12 +544,12 @@ static int c_can_set_bittiming(struct net_device *dev) netdev_info(dev, "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); - ctrl_save = priv->read_reg(priv, &priv->regs->control); - priv->write_reg(priv, &priv->regs->control, + ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); + priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save | CONTROL_CCE | CONTROL_INIT); - priv->write_reg(priv, &priv->regs->btr, reg_btr); - priv->write_reg(priv, &priv->regs->brp_ext, reg_brpe); - priv->write_reg(priv, &priv->regs->control, ctrl_save); + priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); + priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); + priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); return 0; } @@ -587,36 +591,36 @@ static void c_can_chip_config(struct net_device *dev) struct c_can_priv *priv = netdev_priv(dev); /* enable automatic retransmission */ - priv->write_reg(priv, &priv->regs->control, + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR); if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ - priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); - priv->write_reg(priv, &priv->regs->test, + priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT); } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { /* loopback mode : useful for self-test function */ - priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); - priv->write_reg(priv, &priv->regs->test, TEST_LBACK); + priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK); } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { /* silent mode : bus-monitoring mode */ - priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); - priv->write_reg(priv, &priv->regs->test, TEST_SILENT); + priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT); } else /* normal mode*/ - priv->write_reg(priv, &priv->regs->control, + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | CONTROL_SIE | CONTROL_IE); /* configure message objects */ c_can_configure_msg_objects(dev); /* set a `lec` value so that we can check for updates later */ - priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); + priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); /* set bittiming params */ c_can_set_bittiming(dev); @@ -669,7 +673,7 @@ static int c_can_get_berr_counter(const struct net_device *dev, unsigned int reg_err_counter; struct c_can_priv *priv = netdev_priv(dev); - reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); + reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> ERR_CNT_REC_SHIFT; bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; @@ -697,12 +701,12 @@ static void c_can_do_tx(struct net_device *dev) for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); - val = c_can_read_reg32(priv, &priv->regs->txrqst1); + val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); if (!(val & (1 << (msg_obj_no - 1)))) { can_get_echo_skb(dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); stats->tx_bytes += priv->read_reg(priv, - &priv->regs->ifregs[0].msg_cntrl) + C_CAN_IFACE(MSGCTRL_REG, 0)) & IF_MCONT_DLC_MASK; stats->tx_packets++; c_can_inval_msg_object(dev, 0, msg_obj_no); @@ -744,11 +748,11 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) u32 num_rx_pkts = 0; unsigned int msg_obj, msg_ctrl_save; struct c_can_priv *priv = netdev_priv(dev); - u32 val = c_can_read_reg32(priv, &priv->regs->intpnd1); + u32 val = c_can_read_reg32(priv, C_CAN_INTPND1_REG); for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; - val = c_can_read_reg32(priv, &priv->regs->intpnd1), + val = c_can_read_reg32(priv, C_CAN_INTPND1_REG), msg_obj++) { /* * as interrupt pending register's bit n-1 corresponds to @@ -758,7 +762,7 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & ~IF_COMM_TXRQST); msg_ctrl_save = priv->read_reg(priv, - &priv->regs->ifregs[0].msg_cntrl); + C_CAN_IFACE(MSGCTRL_REG, 0)); if (msg_ctrl_save & IF_MCONT_EOB) return num_rx_pkts; @@ -819,7 +823,7 @@ static int c_can_handle_state_change(struct net_device *dev, return 0; c_can_get_berr_counter(dev, &bec); - reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); + reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> ERR_CNT_RP_SHIFT; @@ -935,7 +939,7 @@ static int c_can_handle_bus_err(struct net_device *dev, } /* set a `lec` value so that we can check for updates later */ - priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); + priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); netif_receive_skb(skb); stats->rx_packets++; @@ -959,15 +963,15 @@ static int c_can_poll(struct napi_struct *napi, int quota) /* status events have the highest priority */ if (irqstatus == STATUS_INTERRUPT) { priv->current_status = priv->read_reg(priv, - &priv->regs->status); + C_CAN_STS_REG); /* handle Tx/Rx events */ if (priv->current_status & STATUS_TXOK) - priv->write_reg(priv, &priv->regs->status, + priv->write_reg(priv, C_CAN_STS_REG, priv->current_status & ~STATUS_TXOK); if (priv->current_status & STATUS_RXOK) - priv->write_reg(priv, &priv->regs->status, + priv->write_reg(priv, C_CAN_STS_REG, priv->current_status & ~STATUS_RXOK); /* handle state changes */ @@ -1033,7 +1037,7 @@ static irqreturn_t c_can_isr(int irq, void *dev_id) struct net_device *dev = (struct net_device *)dev_id; struct c_can_priv *priv = netdev_priv(dev); - priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + priv->irqstatus = priv->read_reg(priv, C_CAN_INT_REG); if (!priv->irqstatus) return IRQ_NONE; diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 5f32d34af507..d1e141e3b99c 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -22,43 +22,84 @@ #ifndef C_CAN_H #define C_CAN_H -/* c_can IF registers */ -struct c_can_if_regs { - u16 com_req; - u16 com_mask; - u16 mask1; - u16 mask2; - u16 arb1; - u16 arb2; - u16 msg_cntrl; - u16 data[4]; - u16 _reserved[13]; +enum reg { + C_CAN_CTRL_REG = 0, + C_CAN_STS_REG, + C_CAN_ERR_CNT_REG, + C_CAN_BTR_REG, + C_CAN_INT_REG, + C_CAN_TEST_REG, + C_CAN_BRPEXT_REG, + C_CAN_IF1_COMREQ_REG, + C_CAN_IF1_COMMSK_REG, + C_CAN_IF1_MASK1_REG, + C_CAN_IF1_MASK2_REG, + C_CAN_IF1_ARB1_REG, + C_CAN_IF1_ARB2_REG, + C_CAN_IF1_MSGCTRL_REG, + C_CAN_IF1_DATA1_REG, + C_CAN_IF1_DATA2_REG, + C_CAN_IF1_DATA3_REG, + C_CAN_IF1_DATA4_REG, + C_CAN_IF2_COMREQ_REG, + C_CAN_IF2_COMMSK_REG, + C_CAN_IF2_MASK1_REG, + C_CAN_IF2_MASK2_REG, + C_CAN_IF2_ARB1_REG, + C_CAN_IF2_ARB2_REG, + C_CAN_IF2_MSGCTRL_REG, + C_CAN_IF2_DATA1_REG, + C_CAN_IF2_DATA2_REG, + C_CAN_IF2_DATA3_REG, + C_CAN_IF2_DATA4_REG, + C_CAN_TXRQST1_REG, + C_CAN_TXRQST2_REG, + C_CAN_NEWDAT1_REG, + C_CAN_NEWDAT2_REG, + C_CAN_INTPND1_REG, + C_CAN_INTPND2_REG, + C_CAN_MSGVAL1_REG, + C_CAN_MSGVAL2_REG, }; -/* c_can hardware registers */ -struct c_can_regs { - u16 control; - u16 status; - u16 err_cnt; - u16 btr; - u16 interrupt; - u16 test; - u16 brp_ext; - u16 _reserved1; - struct c_can_if_regs ifregs[2]; /* [0] = IF1 and [1] = IF2 */ - u16 _reserved2[8]; - u16 txrqst1; - u16 txrqst2; - u16 _reserved3[6]; - u16 newdat1; - u16 newdat2; - u16 _reserved4[6]; - u16 intpnd1; - u16 intpnd2; - u16 _reserved5[6]; - u16 msgval1; - u16 msgval2; - u16 _reserved6[6]; +static const u16 reg_map_c_can[] = { + [C_CAN_CTRL_REG] = 0x00, + [C_CAN_STS_REG] = 0x02, + [C_CAN_ERR_CNT_REG] = 0x04, + [C_CAN_BTR_REG] = 0x06, + [C_CAN_INT_REG] = 0x08, + [C_CAN_TEST_REG] = 0x0A, + [C_CAN_BRPEXT_REG] = 0x0C, + [C_CAN_IF1_COMREQ_REG] = 0x10, + [C_CAN_IF1_COMMSK_REG] = 0x12, + [C_CAN_IF1_MASK1_REG] = 0x14, + [C_CAN_IF1_MASK2_REG] = 0x16, + [C_CAN_IF1_ARB1_REG] = 0x18, + [C_CAN_IF1_ARB2_REG] = 0x1A, + [C_CAN_IF1_MSGCTRL_REG] = 0x1C, + [C_CAN_IF1_DATA1_REG] = 0x1E, + [C_CAN_IF1_DATA2_REG] = 0x20, + [C_CAN_IF1_DATA3_REG] = 0x22, + [C_CAN_IF1_DATA4_REG] = 0x24, + [C_CAN_IF2_COMREQ_REG] = 0x40, + [C_CAN_IF2_COMMSK_REG] = 0x42, + [C_CAN_IF2_MASK1_REG] = 0x44, + [C_CAN_IF2_MASK2_REG] = 0x46, + [C_CAN_IF2_ARB1_REG] = 0x48, + [C_CAN_IF2_ARB2_REG] = 0x4A, + [C_CAN_IF2_MSGCTRL_REG] = 0x4C, + [C_CAN_IF2_DATA1_REG] = 0x4E, + [C_CAN_IF2_DATA2_REG] = 0x50, + [C_CAN_IF2_DATA3_REG] = 0x52, + [C_CAN_IF2_DATA4_REG] = 0x54, + [C_CAN_TXRQST1_REG] = 0x80, + [C_CAN_TXRQST2_REG] = 0x82, + [C_CAN_NEWDAT1_REG] = 0x90, + [C_CAN_NEWDAT2_REG] = 0x92, + [C_CAN_INTPND1_REG] = 0xA0, + [C_CAN_INTPND2_REG] = 0xA2, + [C_CAN_MSGVAL1_REG] = 0xB0, + [C_CAN_MSGVAL2_REG] = 0xB2, }; /* c_can private data structure */ @@ -69,9 +110,10 @@ struct c_can_priv { int tx_object; int current_status; int last_status; - u16 (*read_reg) (struct c_can_priv *priv, void *reg); - void (*write_reg) (struct c_can_priv *priv, void *reg, u16 val); - struct c_can_regs __iomem *regs; + u16 (*read_reg) (struct c_can_priv *priv, enum reg index); + void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val); + void __iomem *base; + const u16 *regs; unsigned long irq_flags; /* for request_irq() */ unsigned int tx_next; unsigned int tx_echo; diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 5e1a5ff6476e..a6e9b937683a 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -42,27 +42,27 @@ * Handle the same by providing a common read/write interface. */ static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv, - void *reg) + enum reg index) { - return readw(reg); + return readw(priv->base + priv->regs[index]); } static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv, - void *reg, u16 val) + enum reg index, u16 val) { - writew(val, reg); + writew(val, priv->base + priv->regs[index]); } static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv, - void *reg) + enum reg index) { - return readw(reg + (long)reg - (long)priv->regs); + return readw(priv->base + 2 * priv->regs[index]); } static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, - void *reg, u16 val) + enum reg index, u16 val) { - writew(val, reg + (long)reg - (long)priv->regs); + writew(val, priv->base + 2 * priv->regs[index]); } static int __devinit c_can_plat_probe(struct platform_device *pdev) @@ -115,9 +115,10 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) } priv = netdev_priv(dev); + priv->regs = reg_map_c_can; dev->irq = irq; - priv->regs = addr; + priv->base = addr; #ifdef CONFIG_HAVE_CLK priv->can.clock.freq = clk_get_rate(clk); priv->priv = clk; @@ -146,7 +147,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) } dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", - KBUILD_MODNAME, priv->regs, dev->irq); + KBUILD_MODNAME, priv->base, dev->irq); return 0; exit_free_device: @@ -176,7 +177,7 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); free_c_can_dev(dev); - iounmap(priv->regs); + iounmap(priv->base); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, resource_size(mem)); -- GitLab From 69927fccd96b15bd228bb82d356a7a2a0cfaeefb Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Tue, 29 May 2012 11:13:16 +0530 Subject: [PATCH 0862/6849] can: c_can: Add support for Bosch D_CAN controller This patch adds the support for D_CAN controller driver to the existing C_CAN driver. Bosch D_CAN controller is a full-CAN implementation which is compliant to CAN protocol version 2.0 part A and B. Bosch D_CAN user manual can be obtained from: http://www.semiconductors.bosch.de/media/en/pdf/ ipmodules_1/can/d_can_users_manual_111.pdf A new array is added for accessing the d_can registers, according to d_can controller register space. Current D_CAN implementation has following limitations, this is done to avoid large changes to the C_CAN driver. 1. Message objects are limited to 32, 16 for RX and 16 for TX. C_CAN IP supports upto 32 message objects but in case of D_CAN we can configure upto 128 message objects. 2. Using two 16bit reads/writes for accessing the 32bit D_CAN registers. 3. These patches have been tested on little endian machine, there might be some hidden endian-related issues due to the nature of the accesses (32-bit registers accessed as 2 16-bit registers). However, I do not have a big-endian D_CAN implementation to confirm. Signed-off-by: AnilKumar Ch Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/Kconfig | 13 +++--- drivers/net/can/c_can/c_can.h | 45 +++++++++++++++++++++ drivers/net/can/c_can/c_can_platform.c | 55 ++++++++++++++++++++------ 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig index ffb9773d102d..25d371cf98dd 100644 --- a/drivers/net/can/c_can/Kconfig +++ b/drivers/net/can/c_can/Kconfig @@ -1,15 +1,16 @@ menuconfig CAN_C_CAN - tristate "Bosch C_CAN devices" + tristate "Bosch C_CAN/D_CAN devices" depends on CAN_DEV && HAS_IOMEM if CAN_C_CAN config CAN_C_CAN_PLATFORM - tristate "Generic Platform Bus based C_CAN driver" + tristate "Generic Platform Bus based C_CAN/D_CAN driver" ---help--- - This driver adds support for the C_CAN chips connected to - the "platform bus" (Linux abstraction for directly to the + This driver adds support for the C_CAN/D_CAN chips connected + to the "platform bus" (Linux abstraction for directly to the processor attached devices) which can be found on various - boards from ST Microelectronics (http://www.st.com) - like the SPEAr1310 and SPEAr320 evaluation boards. + boards from ST Microelectronics (http://www.st.com) like the + SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com) + boards like am335x, dm814x, dm813x and dm811x. endif diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index d1e141e3b99c..01a7049ab990 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -102,6 +102,51 @@ static const u16 reg_map_c_can[] = { [C_CAN_MSGVAL2_REG] = 0xB2, }; +static const u16 reg_map_d_can[] = { + [C_CAN_CTRL_REG] = 0x00, + [C_CAN_STS_REG] = 0x04, + [C_CAN_ERR_CNT_REG] = 0x08, + [C_CAN_BTR_REG] = 0x0C, + [C_CAN_BRPEXT_REG] = 0x0E, + [C_CAN_INT_REG] = 0x10, + [C_CAN_TEST_REG] = 0x14, + [C_CAN_TXRQST1_REG] = 0x88, + [C_CAN_TXRQST2_REG] = 0x8A, + [C_CAN_NEWDAT1_REG] = 0x9C, + [C_CAN_NEWDAT2_REG] = 0x9E, + [C_CAN_INTPND1_REG] = 0xB0, + [C_CAN_INTPND2_REG] = 0xB2, + [C_CAN_MSGVAL1_REG] = 0xC4, + [C_CAN_MSGVAL2_REG] = 0xC6, + [C_CAN_IF1_COMREQ_REG] = 0x100, + [C_CAN_IF1_COMMSK_REG] = 0x102, + [C_CAN_IF1_MASK1_REG] = 0x104, + [C_CAN_IF1_MASK2_REG] = 0x106, + [C_CAN_IF1_ARB1_REG] = 0x108, + [C_CAN_IF1_ARB2_REG] = 0x10A, + [C_CAN_IF1_MSGCTRL_REG] = 0x10C, + [C_CAN_IF1_DATA1_REG] = 0x110, + [C_CAN_IF1_DATA2_REG] = 0x112, + [C_CAN_IF1_DATA3_REG] = 0x114, + [C_CAN_IF1_DATA4_REG] = 0x116, + [C_CAN_IF2_COMREQ_REG] = 0x120, + [C_CAN_IF2_COMMSK_REG] = 0x122, + [C_CAN_IF2_MASK1_REG] = 0x124, + [C_CAN_IF2_MASK2_REG] = 0x126, + [C_CAN_IF2_ARB1_REG] = 0x128, + [C_CAN_IF2_ARB2_REG] = 0x12A, + [C_CAN_IF2_MSGCTRL_REG] = 0x12C, + [C_CAN_IF2_DATA1_REG] = 0x130, + [C_CAN_IF2_DATA2_REG] = 0x132, + [C_CAN_IF2_DATA3_REG] = 0x134, + [C_CAN_IF2_DATA4_REG] = 0x136, +}; + +enum c_can_dev_id { + C_CAN_DEVTYPE, + D_CAN_DEVTYPE, +}; + /* c_can private data structure */ struct c_can_priv { struct can_priv can; /* must be the first member */ diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index a6e9b937683a..f0921d16f0a9 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -71,6 +71,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) void __iomem *addr; struct net_device *dev; struct c_can_priv *priv; + const struct platform_device_id *id; struct resource *mem; int irq; #ifdef CONFIG_HAVE_CLK @@ -115,7 +116,32 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) } priv = netdev_priv(dev); - priv->regs = reg_map_c_can; + id = platform_get_device_id(pdev); + switch (id->driver_data) { + case C_CAN_DEVTYPE: + priv->regs = reg_map_c_can; + switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { + case IORESOURCE_MEM_32BIT: + priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; + priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; + break; + case IORESOURCE_MEM_16BIT: + default: + priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; + priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; + break; + } + break; + case D_CAN_DEVTYPE: + priv->regs = reg_map_d_can; + priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; + priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; + priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; + break; + default: + ret = -EINVAL; + goto exit_free_device; + } dev->irq = irq; priv->base = addr; @@ -124,18 +150,6 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) priv->priv = clk; #endif - switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { - case IORESOURCE_MEM_32BIT: - priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; - priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; - break; - case IORESOURCE_MEM_16BIT: - default: - priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; - priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; - break; - } - platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -189,6 +203,20 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id c_can_id_table[] = { + { + .name = KBUILD_MODNAME, + .driver_data = C_CAN_DEVTYPE, + }, { + .name = "c_can", + .driver_data = C_CAN_DEVTYPE, + }, { + .name = "d_can", + .driver_data = D_CAN_DEVTYPE, + }, { + } +}; + static struct platform_driver c_can_plat_driver = { .driver = { .name = KBUILD_MODNAME, @@ -196,6 +224,7 @@ static struct platform_driver c_can_plat_driver = { }, .probe = c_can_plat_probe, .remove = __devexit_p(c_can_plat_remove), + .id_table = c_can_id_table, }; module_platform_driver(c_can_plat_driver); -- GitLab From 30c1dc0ff30b5552e8af555265dbeac5637cbb48 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Wed, 23 May 2012 16:47:31 +0530 Subject: [PATCH 0863/6849] dmaengine: pl330: dont complete descriptor for cyclic dma Commit eab215855803 ("dmaengine: pl330: dont complete descriptor for cyclic dma") wrongly completes descriptor for cyclic dma, hence following BUG_ON is still hit with cyclic DMA operations. kernel BUG at drivers/dma/dmaengine.h:53! Signed-off-by: Tushar Behera Acked-by: Jassi Brar Signed-off-by: Vinod Koul Cc: stable --- drivers/dma/pl330.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index cbcc28e79be6..6d550421da7a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2321,7 +2321,7 @@ static void pl330_tasklet(unsigned long data) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - if (pch->cyclic) + if (!pch->cyclic) dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); } -- GitLab From 8e2e27c7444ba7880aa0a4cb07a79de130d0ed93 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Mon, 4 Jun 2012 09:17:24 +0800 Subject: [PATCH 0864/6849] dma: imx-sdma: buf_tail should be initialize in prepare function This fix audio underrun issue. When SNDRV_PCM_TRIGGER_STOP and SNDRV_PCM_TRIGGER_START, it calls prepare again. buf_tail should be reset to zero. So move buf_tail initialization into prepare function. Signed-off-by: Richard Zhao Acked-by: Shawn Guo Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fb4f4990f5eb..1dc2a4ad0026 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -815,8 +815,6 @@ static int sdma_request_channel(struct sdma_channel *sdmac) init_completion(&sdmac->done); - sdmac->buf_tail = 0; - return 0; out: @@ -927,6 +925,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( sdmac->flags = 0; + sdmac->buf_tail = 0; + dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n", sg_len, channel); @@ -1027,6 +1027,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( sdmac->status = DMA_IN_PROGRESS; + sdmac->buf_tail = 0; + sdmac->flags |= IMX_DMA_SG_LOOP; sdmac->direction = direction; ret = sdma_load_context(sdmac); -- GitLab From 5a67ac572e102f7d877b8a3a18a59315186e3e99 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Jun 2012 17:09:45 +0530 Subject: [PATCH 0865/6849] DMA: PL330: Add missing static storage class specifier Fixes the following sparse warning: drivers/dma/pl330.c:2542:5: warning: symbol 'add_desc' was not declared. Should it be static? Signed-off-by: Sachin Kamat Signed-off-by: Vinod Koul --- drivers/dma/pl330.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6d550421da7a..3ce7d553a746 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2539,7 +2539,7 @@ static inline void _init_desc(struct dma_pl330_desc *desc) } /* Returns the number of descriptors added to the DMAC pool */ -int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +static int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) { struct dma_pl330_desc *desc; unsigned long flags; -- GitLab From f5c55847f7ae31275c3305c997330e5fefa9fa0e Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Wed, 6 Jun 2012 21:22:59 -0400 Subject: [PATCH 0866/6849] dma: enable mxs-dma for imx6q enable the mxs-dma for imx6q. Also remove the unused header file. Signed-off-by: Huang Shijie Acked-by: Shawn Guo Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 2 +- drivers/dma/mxs-dma.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index aadeb5be9dba..c8416d54f917 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -237,7 +237,7 @@ config IMX_DMA config MXS_DMA bool "MXS DMA support" - depends on SOC_IMX23 || SOC_IMX28 + depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q select STMP_DEVICE select DMA_ENGINE help diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index c96ab15319f2..90b980d014aa 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c @@ -29,7 +29,6 @@ #include #include -#include #include "dmaengine.h" -- GitLab From 0c7f46ad927cbd29965d4971730de713b478d270 Mon Sep 17 00:00:00 2001 From: Wang Xingchao Date: Wed, 6 Jun 2012 22:02:48 +0800 Subject: [PATCH 0867/6849] ALSA: hda - check supported power states Add function to check whether power states supported by specific codec node. Signed-off-by: Wang Xingchao Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 41ca803a1fff..b89c8ecc819a 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3504,6 +3504,22 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, } EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); +/* + * supported power states check + */ +static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg, + unsigned int power_state) +{ + int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); + + if (sup < 0) + return false; + if (sup & power_state) + return true; + else + return false; +} + /* * set power state of the codec */ -- GitLab From 0f4ccbb02533276ab750961e150aeee06492ed7c Mon Sep 17 00:00:00 2001 From: Wang Xingchao Date: Thu, 7 Jun 2012 16:51:33 +0800 Subject: [PATCH 0868/6849] ALSA: hda - reduce msleep time if EPSS power states supported if EPSS supported, transition from D3 state to D0 state in less than 10ms Signed-off-by: Wang Xingchao Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b89c8ecc819a..fedbfae978af 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3532,8 +3532,11 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, } /* this delay seems necessary to avoid click noise at power-down */ - if (power_state == AC_PWRST_D3) - msleep(100); + if (power_state == AC_PWRST_D3) { + /* transition time less than 10ms for power down */ + bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS); + msleep(epss ? 10 : 100); + } snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, power_state); snd_hda_codec_set_power_to_all(codec, fg, power_state, true); -- GitLab From e076eb5c952c0f724980b44a77902a2ff93d098c Mon Sep 17 00:00:00 2001 From: Wang Xingchao Date: Thu, 7 Jun 2012 16:52:07 +0800 Subject: [PATCH 0869/6849] ALSA: hda - check proper return value snd_hda_param_read() return value -1 means error, others are responses Signed-off-by: Wang Xingchao Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 1dd9dbeeef6e..7e46258fc700 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -451,7 +451,7 @@ static void print_power_state(struct snd_info_buffer *buffer, int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); int pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); - if (sup) + if (sup != -1) snd_iprintf(buffer, " Power states: %s\n", bits_names(sup, names, ARRAY_SIZE(names))); -- GitLab From f2f12b6fc032c7b1419fd6db84e2868b5f05a878 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 6 Jun 2012 10:50:06 -0600 Subject: [PATCH 0870/6849] iommu/amd: Fix missing iommu_shutdown initialization in passthrough mode The iommu_shutdown callback is not initialized when the AMD IOMMU driver runs in passthrough mode. Fix that by moving the callback initialization before the check for passthrough mode. Signed-off-by: Shuah Khan Cc: stable@vger.kernel.org Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 542024ba6dba..c04ddca7f12f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -1641,6 +1641,8 @@ static int __init amd_iommu_init(void) amd_iommu_init_api(); + x86_platform.iommu_shutdown = disable_iommus; + if (iommu_pass_through) goto out; @@ -1649,8 +1651,6 @@ static int __init amd_iommu_init(void) else printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n"); - x86_platform.iommu_shutdown = disable_iommus; - out: return ret; -- GitLab From 24214449b00b94328e239d3c35cda3e6fe0f931b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 4 May 2012 18:28:21 +0200 Subject: [PATCH 0871/6849] x86, amd_nb: Export model 0x10 and later PCI id Add the F3 PCI id of F15h, model 0x10 to pci_ids.h and to the amd_nb code which generates the list of northbridges on an AMD box. Shorten define name while at it so that it fits into pci_ids.h. Acked-by: Clemens Ladisch Cc: Bjorn Helgaas Acked-by: Andreas Herrmann Signed-off-by: Borislav Petkov --- arch/x86/kernel/amd_nb.c | 1 + drivers/hwmon/k10temp.c | 5 +---- include/linux/pci_ids.h | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index be16854591cc..153a0ee88fb1 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -16,6 +16,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, {} }; EXPORT_SYMBOL(amd_nb_misc_ids); diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 7356b5ec8f67..f2fe8078633b 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -33,9 +33,6 @@ static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); -/* PCI-IDs for Northbridge devices not used anywhere else */ -#define PCI_DEVICE_ID_AMD_15H_M10H_NB_F3 0x1403 - /* CPUID function 0x80000001, ebx */ #define CPUID_PKGTYPE_MASK 0xf0000000 #define CPUID_PKGTYPE_F 0x00000000 @@ -213,7 +210,7 @@ static DEFINE_PCI_DEVICE_TABLE(k10temp_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_NB_F3) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab741b0d0074..05fd02e44993 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -517,6 +517,7 @@ #define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302 #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 +#define PCI_DEVICE_ID_AMD_15H_M10H_F3 0x1403 #define PCI_DEVICE_ID_AMD_15H_NB_F0 0x1600 #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 -- GitLab From 92e26e2a1a7d5fe6538e4a676f9c383966f894a7 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 2 May 2012 16:20:49 +0200 Subject: [PATCH 0872/6849] x86, MCE, AMD: Remove shared banks sysfs linking The code used to create a symlink on all non-BSP cores of a node when the MCi_MISCj bank is present once per node. (This is generally the case with bank 4 on AMD). However, these sysfs links cause a bunch of problems with cpu off-/onlining testing and are, as such, a bit overengineered. IOW, there's nothing wrong with having normal sysfs files for the shared banks since the corresponding MSRs are replicated across each core anyway. Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 105 ++------------------------- 1 file changed, 7 insertions(+), 98 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index f4873a64f46d..2a5dd30f9969 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -60,7 +60,6 @@ struct threshold_block { struct threshold_bank { struct kobject *kobj; struct threshold_block *blocks; - cpumask_var_t cpus; }; static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks); @@ -224,8 +223,6 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) if (!block) per_cpu(bank_map, cpu) |= (1 << bank); - if (shared_bank[bank] && c->cpu_core_id) - break; memset(&b, 0, sizeof(b)); b.cpu = cpu; @@ -555,89 +552,35 @@ local_allocate_threshold_blocks(int cpu, unsigned int bank) MSR_IA32_MC0_MISC + bank * 4); } -/* symlinks sibling shared banks to first core. first core owns dir/files. */ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) { - int i, err = 0; - struct threshold_bank *b = NULL; struct device *dev = per_cpu(mce_device, cpu); + struct threshold_bank *b = NULL; char name[32]; + int err = 0; sprintf(name, "threshold_bank%i", bank); -#ifdef CONFIG_SMP - if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */ - i = cpumask_first(cpu_llc_shared_mask(cpu)); - - /* first core not up yet */ - if (cpu_data(i).cpu_core_id) - goto out; - - /* already linked */ - if (per_cpu(threshold_banks, cpu)[bank]) - goto out; - - b = per_cpu(threshold_banks, i)[bank]; - - if (!b) - goto out; - - err = sysfs_create_link(&dev->kobj, b->kobj, name); - if (err) - goto out; - - cpumask_copy(b->cpus, cpu_llc_shared_mask(cpu)); - per_cpu(threshold_banks, cpu)[bank] = b; - - goto out; - } -#endif - b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL); if (!b) { err = -ENOMEM; goto out; } - if (!zalloc_cpumask_var(&b->cpus, GFP_KERNEL)) { - kfree(b); - err = -ENOMEM; - goto out; - } b->kobj = kobject_create_and_add(name, &dev->kobj); - if (!b->kobj) + if (!b->kobj) { + err = -EINVAL; goto out_free; - -#ifndef CONFIG_SMP - cpumask_setall(b->cpus); -#else - cpumask_set_cpu(cpu, b->cpus); -#endif + } per_cpu(threshold_banks, cpu)[bank] = b; err = local_allocate_threshold_blocks(cpu, bank); - if (err) - goto out_free; - - for_each_cpu(i, b->cpus) { - if (i == cpu) - continue; - - dev = per_cpu(mce_device, i); - if (dev) - err = sysfs_create_link(&dev->kobj,b->kobj, name); - if (err) - goto out; - - per_cpu(threshold_banks, i)[bank] = b; - } - - goto out; + if (!err) + goto out; out_free: per_cpu(threshold_banks, cpu)[bank] = NULL; - free_cpumask_var(b->cpus); kfree(b); out: return err; @@ -660,12 +603,6 @@ static __cpuinit int threshold_create_device(unsigned int cpu) return err; } -/* - * let's be hotplug friendly. - * in case of multiple core processors, the first core always takes ownership - * of shared sysfs dir/files, and rest of the cores will be symlinked to it. - */ - static void deallocate_threshold_block(unsigned int cpu, unsigned int bank) { @@ -689,9 +626,6 @@ static void deallocate_threshold_block(unsigned int cpu, static void threshold_remove_bank(unsigned int cpu, int bank) { struct threshold_bank *b; - struct device *dev; - char name[32]; - int i = 0; b = per_cpu(threshold_banks, cpu)[bank]; if (!b) @@ -699,36 +633,11 @@ static void threshold_remove_bank(unsigned int cpu, int bank) if (!b->blocks) goto free_out; - sprintf(name, "threshold_bank%i", bank); - -#ifdef CONFIG_SMP - /* sibling symlink */ - if (shared_bank[bank] && b->blocks->cpu != cpu) { - dev = per_cpu(mce_device, cpu); - sysfs_remove_link(&dev->kobj, name); - per_cpu(threshold_banks, cpu)[bank] = NULL; - - return; - } -#endif - - /* remove all sibling symlinks before unregistering */ - for_each_cpu(i, b->cpus) { - if (i == cpu) - continue; - - dev = per_cpu(mce_device, i); - if (dev) - sysfs_remove_link(&dev->kobj, name); - per_cpu(threshold_banks, i)[bank] = NULL; - } - deallocate_threshold_block(cpu, bank); free_out: kobject_del(b->kobj); kobject_put(b->kobj); - free_cpumask_var(b->cpus); kfree(b); per_cpu(threshold_banks, cpu)[bank] = NULL; } -- GitLab From 26ab256eaac7af26ecd9ba893b5159a3b38c8a1c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 2 May 2012 16:43:02 +0200 Subject: [PATCH 0873/6849] x86, MCE, AMD: Remove local_allocate_... wrapper It is unneeded now so drop it. Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 2a5dd30f9969..7fd02cac962b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -61,6 +61,7 @@ struct threshold_bank { struct kobject *kobj; struct threshold_block *blocks; }; + static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks); static unsigned char shared_bank[NR_BANKS] = { @@ -545,13 +546,6 @@ out_free: return err; } -static __cpuinit long -local_allocate_threshold_blocks(int cpu, unsigned int bank) -{ - return allocate_threshold_blocks(cpu, bank, 0, - MSR_IA32_MC0_MISC + bank * 4); -} - static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) { struct device *dev = per_cpu(mce_device, cpu); @@ -575,7 +569,8 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) per_cpu(threshold_banks, cpu)[bank] = b; - err = local_allocate_threshold_blocks(cpu, bank); + err = allocate_threshold_blocks(cpu, bank, 0, + MSR_IA32_MC0_MISC + bank * 4); if (!err) goto out; -- GitLab From 019f34fccfd5cf5ff1e722dafd9fe2bd54434e66 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 2 May 2012 17:16:59 +0200 Subject: [PATCH 0874/6849] x86, MCE, AMD: Move shared bank to node descriptor Well, instead of having a real bank 4 on the BSP of each node and symlinks on the remaining cores, we push it up into the amd_northbridge descriptor which now contains a pointer to the northbridge bank 4 because the bank is one per northbridge and, as such, belongs in the NB descriptor anyway. Each time we hotplug CPUs, we use the northbridge pointer to copy the shared bank into the per-CPU array of threshold_banks pointers, or destroy it when the last CPU on the node goes offline, or create it when the first comes online. Signed-off-by: Borislav Petkov --- arch/x86/include/asm/amd_nb.h | 21 ++++++ arch/x86/kernel/cpu/mcheck/mce_amd.c | 107 ++++++++++++++++++++++----- 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 49ad773f4b9f..b3341e9cd8fd 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -26,10 +26,31 @@ struct amd_l3_cache { u8 subcaches[4]; }; +struct threshold_block { + unsigned int block; + unsigned int bank; + unsigned int cpu; + u32 address; + u16 interrupt_enable; + bool interrupt_capable; + u16 threshold_limit; + struct kobject kobj; + struct list_head miscj; +}; + +struct threshold_bank { + struct kobject *kobj; + struct threshold_block *blocks; + + /* initialized to the number of CPUs on the node sharing this bank */ + atomic_t cpus; +}; + struct amd_northbridge { struct pci_dev *misc; struct pci_dev *link; struct amd_l3_cache l3_cache; + struct threshold_bank *bank4; }; struct amd_northbridge_info { diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 7fd02cac962b..d67c9e56d609 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -45,23 +46,6 @@ #define MASK_BLKPTR_LO 0xFF000000 #define MCG_XBLK_ADDR 0xC0000400 -struct threshold_block { - unsigned int block; - unsigned int bank; - unsigned int cpu; - u32 address; - u16 interrupt_enable; - bool interrupt_capable; - u16 threshold_limit; - struct kobject kobj; - struct list_head miscj; -}; - -struct threshold_bank { - struct kobject *kobj; - struct threshold_block *blocks; -}; - static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks); static unsigned char shared_bank[NR_BANKS] = { @@ -546,15 +530,62 @@ out_free: return err; } +static __cpuinit int __threshold_add_blocks(struct threshold_bank *b) +{ + struct list_head *head = &b->blocks->miscj; + struct threshold_block *pos = NULL; + struct threshold_block *tmp = NULL; + int err = 0; + + err = kobject_add(&b->blocks->kobj, b->kobj, b->blocks->kobj.name); + if (err) + return err; + + list_for_each_entry_safe(pos, tmp, head, miscj) { + + err = kobject_add(&pos->kobj, b->kobj, pos->kobj.name); + if (err) { + list_for_each_entry_safe_reverse(pos, tmp, head, miscj) + kobject_del(&pos->kobj); + + return err; + } + } + return err; +} + static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) { struct device *dev = per_cpu(mce_device, cpu); + struct amd_northbridge *nb = NULL; struct threshold_bank *b = NULL; char name[32]; int err = 0; sprintf(name, "threshold_bank%i", bank); + if (shared_bank[bank]) { + + nb = node_to_amd_nb(amd_get_nb_id(cpu)); + WARN_ON(!nb); + + /* threshold descriptor already initialized on this node? */ + if (nb->bank4) { + /* yes, use it */ + b = nb->bank4; + err = kobject_add(b->kobj, &dev->kobj, name); + if (err) + goto out; + + per_cpu(threshold_banks, cpu)[bank] = b; + atomic_inc(&b->cpus); + + err = __threshold_add_blocks(b); + + goto out; + } + } + b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL); if (!b) { err = -ENOMEM; @@ -569,15 +600,23 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) per_cpu(threshold_banks, cpu)[bank] = b; + if (shared_bank[bank]) { + atomic_set(&b->cpus, 1); + + /* nb is already initialized, see above */ + WARN_ON(nb->bank4); + nb->bank4 = b; + } + err = allocate_threshold_blocks(cpu, bank, 0, MSR_IA32_MC0_MISC + bank * 4); if (!err) goto out; -out_free: - per_cpu(threshold_banks, cpu)[bank] = NULL; + out_free: kfree(b); -out: + + out: return err; } @@ -618,16 +657,44 @@ static void deallocate_threshold_block(unsigned int cpu, per_cpu(threshold_banks, cpu)[bank]->blocks = NULL; } +static void __threshold_remove_blocks(struct threshold_bank *b) +{ + struct threshold_block *pos = NULL; + struct threshold_block *tmp = NULL; + + kobject_del(b->kobj); + + list_for_each_entry_safe(pos, tmp, &b->blocks->miscj, miscj) + kobject_del(&pos->kobj); +} + static void threshold_remove_bank(unsigned int cpu, int bank) { + struct amd_northbridge *nb; struct threshold_bank *b; b = per_cpu(threshold_banks, cpu)[bank]; if (!b) return; + if (!b->blocks) goto free_out; + if (shared_bank[bank]) { + if (!atomic_dec_and_test(&b->cpus)) { + __threshold_remove_blocks(b); + per_cpu(threshold_banks, cpu)[bank] = NULL; + return; + } else { + /* + * the last CPU on this node using the shared bank is + * going away, remove that bank now. + */ + nb = node_to_amd_nb(amd_get_nb_id(cpu)); + nb->bank4 = NULL; + } + } + deallocate_threshold_block(cpu, bank); free_out: -- GitLab From 18c20f373b76a64270a991396b06542abaf9f530 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 27 Apr 2012 12:31:34 +0200 Subject: [PATCH 0875/6849] x86, MCE, AMD: Print decimal thresholding values If one sets the threshold limit, say to 25: $ echo 25 > machinecheck0/threshold_bank4/misc0/threshold_limit and then reads it back again, it gives $ cat machinecheck0/threshold_bank4/misc0/threshold_limit 19 which is actually 0x19 but we don't know that. Make all output decimal. Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index d67c9e56d609..0b1bb0e15881 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -308,7 +308,7 @@ struct threshold_attr { #define SHOW_FIELDS(name) \ static ssize_t show_ ## name(struct threshold_block *b, char *buf) \ { \ - return sprintf(buf, "%lx\n", (unsigned long) b->name); \ + return sprintf(buf, "%lu\n", (unsigned long) b->name); \ } SHOW_FIELDS(interrupt_enable) SHOW_FIELDS(threshold_limit) @@ -379,7 +379,7 @@ static ssize_t show_error_count(struct threshold_block *b, char *buf) struct threshold_block_cross_cpu tbcc = { .tb = b, }; smp_call_function_single(b->cpu, local_error_count_handler, &tbcc, 1); - return sprintf(buf, "%lx\n", tbcc.retval); + return sprintf(buf, "%lu\n", tbcc.retval); } static ssize_t store_error_count(struct threshold_block *b, -- GitLab From 2c9c42fa98c283961b7f6b6542fb4bf0c0539e15 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 27 Apr 2012 12:53:59 +0200 Subject: [PATCH 0876/6849] x86, MCE, AMD: Cleanup reading of error_count We have rdmsr_on_cpu() now so remove locally defined solution in favor of the generic one. No functionality change. Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 0b1bb0e15881..a7204ef37223 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -359,27 +359,14 @@ store_threshold_limit(struct threshold_block *b, const char *buf, size_t size) return size; } -struct threshold_block_cross_cpu { - struct threshold_block *tb; - long retval; -}; - -static void local_error_count_handler(void *_tbcc) -{ - struct threshold_block_cross_cpu *tbcc = _tbcc; - struct threshold_block *b = tbcc->tb; - u32 low, high; - - rdmsr(b->address, low, high); - tbcc->retval = (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit); -} - static ssize_t show_error_count(struct threshold_block *b, char *buf) { - struct threshold_block_cross_cpu tbcc = { .tb = b, }; + u32 lo, hi; + + rdmsr_on_cpu(b->cpu, b->address, &lo, &hi); - smp_call_function_single(b->cpu, local_error_count_handler, &tbcc, 1); - return sprintf(buf, "%lu\n", tbcc.retval); + return sprintf(buf, "%u\n", ((hi & THRESHOLD_MAX) - + (THRESHOLD_MAX - b->threshold_limit))); } static ssize_t store_error_count(struct threshold_block *b, -- GitLab From 6e927361bd403dbf5f6a2668a2a07df1f1b2daff Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 27 Apr 2012 15:37:25 +0200 Subject: [PATCH 0877/6849] x86, MCE, AMD: Make error_count read only Until now, writing to error count caused the code to reset the thresholding bank to the current thresholding limit and start counting errors from the beginning. This is misleading and unclear, and can be accomplished by writing the old thresholding limit into ->threshold_limit. Make error_count read-only with the functionality to show the current error count. Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index a7204ef37223..e5ed2c7cb4de 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -369,14 +369,10 @@ static ssize_t show_error_count(struct threshold_block *b, char *buf) (THRESHOLD_MAX - b->threshold_limit))); } -static ssize_t store_error_count(struct threshold_block *b, - const char *buf, size_t count) -{ - struct thresh_restart tr = { .b = b, .reset = 1, .old_limit = 0 }; - - smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1); - return 1; -} +static struct threshold_attr error_count = { + .attr = {.name = __stringify(error_count), .mode = 0444 }, + .show = show_error_count, +}; #define RW_ATTR(val) \ static struct threshold_attr val = { \ @@ -387,7 +383,6 @@ static struct threshold_attr val = { \ RW_ATTR(interrupt_enable); RW_ATTR(threshold_limit); -RW_ATTR(error_count); static struct attribute *default_attrs[] = { &threshold_limit.attr, -- GitLab From 336d335a963a5a4f5d7f915b4d74ada5d7b4d05b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 4 May 2012 17:05:27 +0200 Subject: [PATCH 0878/6849] x86, MCE, AMD: Give proper names to the thresholding banks Having the banks numbered is ok but having real names which mean something to the user makes a lot more sense: /sys/devices/system/machinecheck/machinecheck0/ |-- bank0 |-- bank1 |-- bank2 |-- bank3 |-- bank4 |-- bank5 |-- bank6 |-- check_interval |-- cmci_disabled |-- combined_unit | |-- combined_unit | |-- error_count | |-- threshold_limit |-- dont_log_ce |-- execution_unit | |-- execution_unit | |-- error_count | |-- threshold_limit |-- ignore_ce |-- insn_fetch | |-- insn_fetch | |-- error_count | |-- threshold_limit |-- load_store | |-- load_store | |-- error_count | |-- threshold_limit |-- monarch_timeout |-- northbridge | |-- dram | | |-- error_count | | |-- interrupt_enable | | |-- threshold_limit | |-- ht_links | | |-- error_count | | |-- interrupt_enable | | |-- threshold_limit | |-- l3_cache | |-- error_count | |-- interrupt_enable | |-- threshold_limit ... Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index e5ed2c7cb4de..e20bdf8d7c59 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -46,6 +46,15 @@ #define MASK_BLKPTR_LO 0xFF000000 #define MCG_XBLK_ADDR 0xC0000400 +static const char * const th_names[] = { + "load_store", + "insn_fetch", + "combined_unit", + "", + "northbridge", + "execution_unit", +}; + static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks); static unsigned char shared_bank[NR_BANKS] = { @@ -68,6 +77,26 @@ struct thresh_restart { u16 old_limit; }; +static const char * const bank4_names(struct threshold_block *b) +{ + switch (b->address) { + /* MSR4_MISC0 */ + case 0x00000413: + return "dram"; + + case 0xc0000408: + return "ht_links"; + + case 0xc0000409: + return "l3_cache"; + + default: + WARN(1, "Funny MSR: 0x%08x\n", b->address); + return ""; + } +}; + + static bool lvt_interrupt_supported(unsigned int bank, u32 msr_high_bits) { /* @@ -481,7 +510,7 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, err = kobject_init_and_add(&b->kobj, &threshold_ktype, per_cpu(threshold_banks, cpu)[bank]->kobj, - "misc%i", block); + (bank == 4 ? bank4_names(b) : th_names[bank])); if (err) goto out_free; recurse: @@ -541,11 +570,9 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) struct device *dev = per_cpu(mce_device, cpu); struct amd_northbridge *nb = NULL; struct threshold_bank *b = NULL; - char name[32]; + const char *name = th_names[bank]; int err = 0; - sprintf(name, "threshold_bank%i", bank); - if (shared_bank[bank]) { nb = node_to_amd_nb(amd_get_nb_id(cpu)); -- GitLab From 11122570193a429f72014703ce6b849640f8d7e5 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 7 May 2012 18:22:16 +0200 Subject: [PATCH 0879/6849] x86, MCE, AMD: Update copyrights and boilerplate Jacob is doing something else now so add myself as the loser who provides support. Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index e20bdf8d7c59..671b95a2ffb5 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -1,15 +1,17 @@ /* - * (c) 2005, 2006 Advanced Micro Devices, Inc. + * (c) 2005-2012 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html * * Written by Jacob Shin - AMD, Inc. * - * Support : jacob.shin@amd.com + * Support: borislav.petkov@amd.com * * April 2006 * - added support for AMD Family 0x10 processors + * May 2012 + * - major scrubbing * * All MC4_MISCi registers are shared between multi-cores */ -- GitLab From df5d2f5560a9c33129391a136ed9f0ac26abe69b Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 7 Jun 2012 13:30:16 +0100 Subject: [PATCH 0880/6849] GFS2: Increase buffer size for glocks and glstats debugfs files As per Al Viro's suggestion, this increases the buffer size used for these two files. This provides a speed up of slightly less than 8x (i.e. proportional to the buffer size) for cases when we have large numbers of glocks. Cc: Al Viro Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index dab2526071cc..1c4cddf42a66 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1972,6 +1972,9 @@ static int gfs2_glocks_open(struct inode *inode, struct file *file) struct seq_file *seq = file->private_data; struct gfs2_glock_iter *gi = seq->private; gi->sdp = inode->i_private; + seq->buf = kmalloc(8*PAGE_SIZE, GFP_KERNEL | __GFP_NOWARN); + if (seq->buf) + seq->size = 8*PAGE_SIZE; } return ret; } @@ -1984,6 +1987,9 @@ static int gfs2_glstats_open(struct inode *inode, struct file *file) struct seq_file *seq = file->private_data; struct gfs2_glock_iter *gi = seq->private; gi->sdp = inode->i_private; + seq->buf = kmalloc(8*PAGE_SIZE, GFP_KERNEL | __GFP_NOWARN); + if (seq->buf) + seq->size = 8*PAGE_SIZE; } return ret; } -- GitLab From 7a74c1a18d1f03462f9f766ee8213535ce131b0f Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Sat, 19 May 2012 04:39:00 +0000 Subject: [PATCH 0881/6849] netfilter: remove include/linux/netfilter_ipv4/ipt_addrtype.h It was scheduled to be removed. Acked-by: Florian Westphal Signed-off-by: Cong Wang Signed-off-by: Pablo Neira Ayuso --- Documentation/feature-removal-schedule.txt | 8 ------ include/linux/netfilter_ipv4/Kbuild | 1 - include/linux/netfilter_ipv4/ipt_addrtype.h | 27 --------------------- 3 files changed, 36 deletions(-) delete mode 100644 include/linux/netfilter_ipv4/ipt_addrtype.h diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 56000b33340b..08e7e71b266c 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -421,14 +421,6 @@ Files: net/netfilter/xt_connlimit.c ---------------------------- -What: ipt_addrtype match include file -When: 2012 -Why: superseded by xt_addrtype -Who: Florian Westphal -Files: include/linux/netfilter_ipv4/ipt_addrtype.h - ----------------------------- - What: i2c_driver.attach_adapter i2c_driver.detach_adapter When: September 2011 diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild index c61b8fb1a9ef..8ba0c5b72ea9 100644 --- a/include/linux/netfilter_ipv4/Kbuild +++ b/include/linux/netfilter_ipv4/Kbuild @@ -5,7 +5,6 @@ header-y += ipt_LOG.h header-y += ipt_REJECT.h header-y += ipt_TTL.h header-y += ipt_ULOG.h -header-y += ipt_addrtype.h header-y += ipt_ah.h header-y += ipt_ecn.h header-y += ipt_ttl.h diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h deleted file mode 100644 index 0da42237c8da..000000000000 --- a/include/linux/netfilter_ipv4/ipt_addrtype.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _IPT_ADDRTYPE_H -#define _IPT_ADDRTYPE_H - -#include - -enum { - IPT_ADDRTYPE_INVERT_SOURCE = 0x0001, - IPT_ADDRTYPE_INVERT_DEST = 0x0002, - IPT_ADDRTYPE_LIMIT_IFACE_IN = 0x0004, - IPT_ADDRTYPE_LIMIT_IFACE_OUT = 0x0008, -}; - -struct ipt_addrtype_info_v1 { - __u16 source; /* source-type mask */ - __u16 dest; /* dest-type mask */ - __u32 flags; -}; - -/* revision 0 */ -struct ipt_addrtype_info { - __u16 source; /* source-type mask */ - __u16 dest; /* dest-type mask */ - __u32 invert_source; - __u32 invert_dest; -}; - -#endif -- GitLab From 68c07cb6d8aa05daf38ab47d5bb674d81a2066fb Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Sat, 19 May 2012 04:39:01 +0000 Subject: [PATCH 0882/6849] netfilter: xt_connlimit: remove revision 0 It was scheduled to be removed. Cc: Jan Engelhardt Signed-off-by: Cong Wang Signed-off-by: Pablo Neira Ayuso --- Documentation/feature-removal-schedule.txt | 7 ----- include/linux/netfilter/xt_connlimit.h | 9 ++---- net/netfilter/xt_connlimit.c | 35 +++++++--------------- 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 08e7e71b266c..24ac00f4ae4b 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -414,13 +414,6 @@ Who: Jean Delvare ---------------------------- -What: xt_connlimit rev 0 -When: 2012 -Who: Jan Engelhardt -Files: net/netfilter/xt_connlimit.c - ----------------------------- - What: i2c_driver.attach_adapter i2c_driver.detach_adapter When: September 2011 diff --git a/include/linux/netfilter/xt_connlimit.h b/include/linux/netfilter/xt_connlimit.h index d1366f05d1b2..f1656096121e 100644 --- a/include/linux/netfilter/xt_connlimit.h +++ b/include/linux/netfilter/xt_connlimit.h @@ -22,13 +22,8 @@ struct xt_connlimit_info { #endif }; unsigned int limit; - union { - /* revision 0 */ - unsigned int inverse; - - /* revision 1 */ - __u32 flags; - }; + /* revision 1 */ + __u32 flags; /* Used internally by the kernel */ struct xt_connlimit_data *data __attribute__((aligned(8))); diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index c6d5a83450c9..70b5591a2586 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -274,38 +274,25 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) kfree(info->data); } -static struct xt_match connlimit_mt_reg[] __read_mostly = { - { - .name = "connlimit", - .revision = 0, - .family = NFPROTO_UNSPEC, - .checkentry = connlimit_mt_check, - .match = connlimit_mt, - .matchsize = sizeof(struct xt_connlimit_info), - .destroy = connlimit_mt_destroy, - .me = THIS_MODULE, - }, - { - .name = "connlimit", - .revision = 1, - .family = NFPROTO_UNSPEC, - .checkentry = connlimit_mt_check, - .match = connlimit_mt, - .matchsize = sizeof(struct xt_connlimit_info), - .destroy = connlimit_mt_destroy, - .me = THIS_MODULE, - }, +static struct xt_match connlimit_mt_reg __read_mostly = { + .name = "connlimit", + .revision = 1, + .family = NFPROTO_UNSPEC, + .checkentry = connlimit_mt_check, + .match = connlimit_mt, + .matchsize = sizeof(struct xt_connlimit_info), + .destroy = connlimit_mt_destroy, + .me = THIS_MODULE, }; static int __init connlimit_mt_init(void) { - return xt_register_matches(connlimit_mt_reg, - ARRAY_SIZE(connlimit_mt_reg)); + return xt_register_match(&connlimit_mt_reg); } static void __exit connlimit_mt_exit(void) { - xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg)); + xt_unregister_match(&connlimit_mt_reg); } module_init(connlimit_mt_init); -- GitLab From fdb694a01f1fcd30fd16d8aa290c34699fe98a17 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Thu, 24 May 2012 03:56:44 +0000 Subject: [PATCH 0883/6849] netfilter: Add fail-open support Implement a new "fail-open" mode where packets are not dropped upon queue-full condition. This mode can be enabled/disabled per queue using netlink NFQA_CFG_FLAGS & NFQA_CFG_MASK attributes. Signed-off-by: Krishna Kumar Signed-off-by: Vivek Kashyap Signed-off-by: Sridhar Samudrala --- include/linux/netfilter/nfnetlink_queue.h | 5 +++ net/netfilter/nfnetlink_queue.c | 40 +++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/include/linux/netfilter/nfnetlink_queue.h b/include/linux/netfilter/nfnetlink_queue.h index 24b32e6c009e..a6c1ddac05cc 100644 --- a/include/linux/netfilter/nfnetlink_queue.h +++ b/include/linux/netfilter/nfnetlink_queue.h @@ -84,8 +84,13 @@ enum nfqnl_attr_config { NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */ NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */ NFQA_CFG_QUEUE_MAXLEN, /* __u32 */ + NFQA_CFG_MASK, /* identify which flags to change */ + NFQA_CFG_FLAGS, /* value of these flags (__u32) */ __NFQA_CFG_MAX }; #define NFQA_CFG_MAX (__NFQA_CFG_MAX-1) +/* Flags for NFQA_CFG_FLAGS */ +#define NFQA_CFG_F_FAIL_OPEN (1 << 0) + #endif /* _NFNETLINK_QUEUE_H */ diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 4162437b8361..630da3d2c62a 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -52,6 +52,7 @@ struct nfqnl_instance { u_int16_t queue_num; /* number of this queue */ u_int8_t copy_mode; + u_int32_t flags; /* Set using NFQA_CFG_FLAGS */ /* * Following fields are dirtied for each queued packet, * keep them in same cache line if possible. @@ -406,6 +407,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) struct nfqnl_instance *queue; int err = -ENOBUFS; __be32 *packet_id_ptr; + int failopen = 0; /* rcu_read_lock()ed by nf_hook_slow() */ queue = instance_lookup(queuenum); @@ -431,9 +433,14 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) goto err_out_free_nskb; } if (queue->queue_total >= queue->queue_maxlen) { - queue->queue_dropped++; - net_warn_ratelimited("nf_queue: full at %d entries, dropping packets(s)\n", - queue->queue_total); + if (queue->flags & NFQA_CFG_F_FAIL_OPEN) { + failopen = 1; + err = 0; + } else { + queue->queue_dropped++; + net_warn_ratelimited("nf_queue: full at %d entries, dropping packets(s)\n", + queue->queue_total); + } goto err_out_free_nskb; } entry->id = ++queue->id_sequence; @@ -455,6 +462,8 @@ err_out_free_nskb: kfree_skb(nskb); err_out_unlock: spin_unlock_bh(&queue->lock); + if (failopen) + nf_reinject(entry, NF_ACCEPT); err_out: return err; } @@ -858,6 +867,31 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, spin_unlock_bh(&queue->lock); } + if (nfqa[NFQA_CFG_FLAGS]) { + __u32 flags, mask; + + if (!queue) { + ret = -ENODEV; + goto err_out_unlock; + } + + if (!nfqa[NFQA_CFG_MASK]) { + /* A mask is needed to specify which flags are being + * changed. + */ + ret = -EINVAL; + goto err_out_unlock; + } + + flags = ntohl(nla_get_be32(nfqa[NFQA_CFG_FLAGS])); + mask = ntohl(nla_get_be32(nfqa[NFQA_CFG_MASK])); + + spin_lock_bh(&queue->lock); + queue->flags &= ~mask; + queue->flags |= flags & mask; + spin_unlock_bh(&queue->lock); + } + err_out_unlock: rcu_read_unlock(); return ret; -- GitLab From 2c352f444ccfa966a1aa4fd8e9ee29381c467448 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:09 +0000 Subject: [PATCH 0884/6849] netfilter: nf_conntrack: prepare namespace support for l4 protocol trackers This patch prepares the namespace support for layer 4 protocol trackers. Basically, this modifies the following interfaces: * nf_ct_[un]register_sysctl * nf_conntrack_l4proto_[un]register to include the namespace parameter. We still use init_net in this patch to prepare the ground for follow-up patches for each layer 4 protocol tracker. We add a new net_id field to struct nf_conntrack_l4proto that is used to store the pernet_operations id for each layer 4 protocol tracker. Note that AF_INET6's protocols do not need to do sysctl compat. Thus, we only register compat sysctl when l4proto.l3proto != AF_INET6. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_l4proto.h | 11 +- include/net/netns/conntrack.h | 12 ++ .../netfilter/nf_conntrack_l3proto_ipv4.c | 18 +-- .../netfilter/nf_conntrack_l3proto_ipv6.c | 18 +-- net/netfilter/nf_conntrack_proto.c | 143 +++++++++++++----- net/netfilter/nf_conntrack_proto_dccp.c | 10 +- net/netfilter/nf_conntrack_proto_gre.c | 6 +- net/netfilter/nf_conntrack_proto_sctp.c | 10 +- net/netfilter/nf_conntrack_proto_udplite.c | 10 +- 9 files changed, 159 insertions(+), 79 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 3b572bb20aa2..d621c91de5c8 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -12,6 +12,7 @@ #include #include #include +#include struct seq_file; @@ -103,6 +104,10 @@ struct nf_conntrack_l4proto { struct ctl_table *ctl_compat_table; #endif #endif + int *net_id; + /* Init l4proto pernet data */ + int (*init_net)(struct net *net); + /* Protocol name */ const char *name; @@ -123,8 +128,10 @@ nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto); extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p); /* Protocol registration. */ -extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto); -extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto); +extern int nf_conntrack_l4proto_register(struct net *net, + struct nf_conntrack_l4proto *proto); +extern void nf_conntrack_l4proto_unregister(struct net *net, + struct nf_conntrack_l4proto *proto); /* Generic netlink helpers */ extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index a053a19870cf..1f53038b0d1b 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -8,6 +8,18 @@ struct ctl_table_header; struct nf_conntrack_ecache; +struct nf_proto_net { +#ifdef CONFIG_SYSCTL + struct ctl_table_header *ctl_table_header; + struct ctl_table *ctl_table; +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + struct ctl_table_header *ctl_compat_header; + struct ctl_table *ctl_compat_table; +#endif +#endif + unsigned int users; +}; + struct netns_ct { atomic_t count; unsigned int expect_count; diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 91747d4ebc26..46ec515db129 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -391,19 +391,19 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) return ret; } - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_tcp4); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register tcp.\n"); goto cleanup_sockopt; } - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udp4); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register udp.\n"); goto cleanup_tcp; } - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_icmp); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register icmp.\n"); goto cleanup_udp; @@ -434,11 +434,11 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) cleanup_ipv4: nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); cleanup_icmp: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp); cleanup_udp: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4); cleanup_tcp: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4); cleanup_sockopt: nf_unregister_sockopt(&so_getorigdst); return ret; @@ -452,9 +452,9 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void) #endif nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4); nf_unregister_sockopt(&so_getorigdst); } diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 3224ef90a21a..51ad9f104421 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -340,19 +340,19 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) need_conntrack(); nf_defrag_ipv6_enable(); - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_tcp6); if (ret < 0) { pr_err("nf_conntrack_ipv6: can't register tcp.\n"); return ret; } - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udp6); if (ret < 0) { pr_err("nf_conntrack_ipv6: can't register udp.\n"); goto cleanup_tcp; } - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_icmpv6); if (ret < 0) { pr_err("nf_conntrack_ipv6: can't register icmpv6.\n"); goto cleanup_udp; @@ -376,11 +376,11 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) cleanup_ipv6: nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); cleanup_icmpv6: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6); cleanup_udp: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6); cleanup_tcp: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6); return ret; } @@ -389,9 +389,9 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) synchronize_net(); nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6); } module_init(nf_conntrack_l3proto_ipv6_init); diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 8b631b07a645..7ee31ac0a12c 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -36,28 +36,35 @@ static DEFINE_MUTEX(nf_ct_proto_mutex); #ifdef CONFIG_SYSCTL static int -nf_ct_register_sysctl(struct ctl_table_header **header, const char *path, - struct ctl_table *table, unsigned int *users) +nf_ct_register_sysctl(struct net *net, + struct ctl_table_header **header, + const char *path, + struct ctl_table *table, + unsigned int *users) { if (*header == NULL) { - *header = register_net_sysctl(&init_net, path, table); + *header = register_net_sysctl(net, path, table); if (*header == NULL) return -ENOMEM; } if (users != NULL) (*users)++; + return 0; } static void nf_ct_unregister_sysctl(struct ctl_table_header **header, - struct ctl_table *table, unsigned int *users) + struct ctl_table **table, + unsigned int *users) { if (users != NULL && --*users > 0) return; unregister_net_sysctl_table(*header); + kfree(*table); *header = NULL; + *table = NULL; } #endif @@ -167,7 +174,8 @@ static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) #ifdef CONFIG_SYSCTL if (l3proto->ctl_table != NULL) { - err = nf_ct_register_sysctl(&l3proto->ctl_table_header, + err = nf_ct_register_sysctl(&init_net, + &l3proto->ctl_table_header, l3proto->ctl_table_path, l3proto->ctl_table, NULL); } @@ -180,7 +188,7 @@ static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto #ifdef CONFIG_SYSCTL if (l3proto->ctl_table_header != NULL) nf_ct_unregister_sysctl(&l3proto->ctl_table_header, - l3proto->ctl_table, NULL); + &l3proto->ctl_table, NULL); #endif } @@ -243,29 +251,54 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) } EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); -static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto) +static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, + struct nf_conntrack_l4proto *l4proto) +{ + if (l4proto->net_id) + return net_generic(net, *l4proto->net_id); + else + return NULL; +} + +static +int nf_ct_l4proto_register_sysctl(struct net *net, + struct nf_conntrack_l4proto *l4proto) { int err = 0; + struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); + if (pn == NULL) + return 0; #ifdef CONFIG_SYSCTL - if (l4proto->ctl_table != NULL) { - err = nf_ct_register_sysctl(l4proto->ctl_table_header, + if (pn->ctl_table != NULL) { + err = nf_ct_register_sysctl(net, + &pn->ctl_table_header, "net/netfilter", - l4proto->ctl_table, - l4proto->ctl_table_users); - if (err < 0) + pn->ctl_table, + &pn->users); + if (err < 0) { + if (!pn->users) { + kfree(pn->ctl_table); + pn->ctl_table = NULL; + } goto out; + } } #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - if (l4proto->ctl_compat_table != NULL) { - err = nf_ct_register_sysctl(&l4proto->ctl_compat_table_header, + if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_table != NULL) { + err = nf_ct_register_sysctl(net, + &pn->ctl_compat_header, "net/ipv4/netfilter", - l4proto->ctl_compat_table, NULL); + pn->ctl_compat_table, + NULL); if (err == 0) goto out; - nf_ct_unregister_sysctl(l4proto->ctl_table_header, - l4proto->ctl_table, - l4proto->ctl_table_users); + + kfree(pn->ctl_compat_table); + pn->ctl_compat_table = NULL; + nf_ct_unregister_sysctl(&pn->ctl_table_header, + &pn->ctl_table, + &pn->users); } #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ out: @@ -273,25 +306,34 @@ out: return err; } -static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto) +static +void nf_ct_l4proto_unregister_sysctl(struct net *net, + struct nf_conntrack_l4proto *l4proto) { + struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); + if (pn == NULL) + return; #ifdef CONFIG_SYSCTL - if (l4proto->ctl_table_header != NULL && - *l4proto->ctl_table_header != NULL) - nf_ct_unregister_sysctl(l4proto->ctl_table_header, - l4proto->ctl_table, - l4proto->ctl_table_users); + if (pn->ctl_table_header != NULL) + nf_ct_unregister_sysctl(&pn->ctl_table_header, + &pn->ctl_table, + &pn->users); + #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - if (l4proto->ctl_compat_table_header != NULL) - nf_ct_unregister_sysctl(&l4proto->ctl_compat_table_header, - l4proto->ctl_compat_table, NULL); + if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_header != NULL) + nf_ct_unregister_sysctl(&pn->ctl_compat_header, + &pn->ctl_compat_table, + NULL); #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ +#else + pn->users--; #endif /* CONFIG_SYSCTL */ } /* FIXME: Allow NULL functions and sub in pointers to generic for them. --RR */ -int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) +static int +nf_conntrack_l4proto_register_net(struct nf_conntrack_l4proto *l4proto) { int ret = 0; @@ -333,10 +375,6 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) goto out_unlock; } - ret = nf_ct_l4proto_register_sysctl(l4proto); - if (ret < 0) - goto out_unlock; - l4proto->nla_size = 0; if (l4proto->nlattr_size) l4proto->nla_size += l4proto->nlattr_size(); @@ -345,17 +383,34 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], l4proto); - out_unlock: mutex_unlock(&nf_ct_proto_mutex); return ret; } -EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); -void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) +int nf_conntrack_l4proto_register(struct net *net, + struct nf_conntrack_l4proto *l4proto) { - struct net *net; + int ret = 0; + if (net == &init_net) + ret = nf_conntrack_l4proto_register_net(l4proto); + + if (ret < 0) + return ret; + + if (l4proto->init_net) + ret = l4proto->init_net(net); + if (ret < 0) + return ret; + + return nf_ct_l4proto_register_sysctl(net, l4proto); +} +EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); + +static void +nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto) +{ BUG_ON(l4proto->l3proto >= PF_MAX); mutex_lock(&nf_ct_proto_mutex); @@ -365,15 +420,21 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) ) != l4proto); rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], &nf_conntrack_l4proto_generic); - nf_ct_l4proto_unregister_sysctl(l4proto); mutex_unlock(&nf_ct_proto_mutex); synchronize_rcu(); +} +void nf_conntrack_l4proto_unregister(struct net *net, + struct nf_conntrack_l4proto *l4proto) +{ + if (net == &init_net) + nf_conntrack_l4proto_unregister_net(l4proto); + + nf_ct_l4proto_unregister_sysctl(net, l4proto); /* Remove all contrack entries for this protocol */ rtnl_lock(); - for_each_net(net) - nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); + nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); rtnl_unlock(); } EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); @@ -383,7 +444,7 @@ int nf_conntrack_proto_init(void) unsigned int i; int err; - err = nf_ct_l4proto_register_sysctl(&nf_conntrack_l4proto_generic); + err = nf_ct_l4proto_register_sysctl(&init_net, &nf_conntrack_l4proto_generic); if (err < 0) return err; @@ -397,7 +458,7 @@ void nf_conntrack_proto_fini(void) { unsigned int i; - nf_ct_l4proto_unregister_sysctl(&nf_conntrack_l4proto_generic); + nf_ct_l4proto_unregister_sysctl(&init_net, &nf_conntrack_l4proto_generic); /* free l3proto protocol tables */ for (i = 0; i < PF_MAX; i++) diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index ef706a485be1..5a8e03724289 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -945,17 +945,17 @@ static int __init nf_conntrack_proto_dccp_init(void) if (err < 0) goto err1; - err = nf_conntrack_l4proto_register(&dccp_proto4); + err = nf_conntrack_l4proto_register(&init_net, &dccp_proto4); if (err < 0) goto err2; - err = nf_conntrack_l4proto_register(&dccp_proto6); + err = nf_conntrack_l4proto_register(&init_net, &dccp_proto6); if (err < 0) goto err3; return 0; err3: - nf_conntrack_l4proto_unregister(&dccp_proto4); + nf_conntrack_l4proto_unregister(&init_net, &dccp_proto4); err2: unregister_pernet_subsys(&dccp_net_ops); err1: @@ -965,8 +965,8 @@ err1: static void __exit nf_conntrack_proto_dccp_fini(void) { unregister_pernet_subsys(&dccp_net_ops); - nf_conntrack_l4proto_unregister(&dccp_proto6); - nf_conntrack_l4proto_unregister(&dccp_proto4); + nf_conntrack_l4proto_unregister(&init_net, &dccp_proto6); + nf_conntrack_l4proto_unregister(&init_net, &dccp_proto4); } module_init(nf_conntrack_proto_dccp_init); diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 4bf6b4e4b776..132f0d2d82cc 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -396,18 +396,18 @@ static int __init nf_ct_proto_gre_init(void) { int rv; - rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4); + rv = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_gre4); if (rv < 0) return rv; rv = register_pernet_subsys(&proto_gre_net_ops); if (rv < 0) - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_gre4); return rv; } static void __exit nf_ct_proto_gre_fini(void) { - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_gre4); unregister_pernet_subsys(&proto_gre_net_ops); } diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 996db2fa21f7..97bbc20e1a2b 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -791,12 +791,12 @@ static int __init nf_conntrack_proto_sctp_init(void) { int ret; - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp4); if (ret) { pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n"); goto out; } - ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6); + ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp6); if (ret) { pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n"); goto cleanup_sctp4; @@ -805,15 +805,15 @@ static int __init nf_conntrack_proto_sctp_init(void) return ret; cleanup_sctp4: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4); out: return ret; } static void __exit nf_conntrack_proto_sctp_fini(void) { - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4); } module_init(nf_conntrack_proto_sctp_init); diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index 4d60a5376aa6..fa142a81496c 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -299,23 +299,23 @@ static int __init nf_conntrack_proto_udplite_init(void) { int err; - err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4); + err = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udplite4); if (err < 0) goto err1; - err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6); + err = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udplite6); if (err < 0) goto err2; return 0; err2: - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite4); err1: return err; } static void __exit nf_conntrack_proto_udplite_exit(void) { - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6); - nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite6); + nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite4); } module_init(nf_conntrack_proto_udplite_init); -- GitLab From 524a53e5ad5f34f64ed34281e8b0eca19437db5b Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:10 +0000 Subject: [PATCH 0885/6849] netfilter: nf_conntrack: prepare namespace support for l3 protocol trackers This patch prepares the namespace support for layer 3 protocol trackers. Basically, this modifies the following interfaces: * nf_ct_l3proto_[un]register_sysctl. * nf_conntrack_l3proto_[un]register. We add a new nf_ct_l3proto_net is used to get the pernet data of l3proto. This adds rhe new struct nf_ip_net that is used to store the sysctl header and l3proto_ipv4,l4proto_tcp(6),l4proto_udp(6),l4proto_icmp(v6) because the protos such tcp and tcp6 use the same data,so making nf_ip_net as a field of netns_ct is the easiest way to manager it. This patch also adds init_net to struct nf_conntrack_l3proto to initial the layer 3 protocol pernet data. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_l3proto.h | 9 +- include/net/netns/conntrack.h | 8 ++ .../netfilter/nf_conntrack_l3proto_ipv4.c | 6 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 6 +- net/netfilter/nf_conntrack_proto.c | 92 ++++++++++++++----- 5 files changed, 91 insertions(+), 30 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 9699c028b74b..d6df8c71a7fe 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -69,6 +69,9 @@ struct nf_conntrack_l3proto { struct ctl_table *ctl_table; #endif /* CONFIG_SYSCTL */ + /* Init l3proto pernet data */ + int (*init_net)(struct net *net); + /* Module (if any) which this is connected to. */ struct module *me; }; @@ -76,8 +79,10 @@ struct nf_conntrack_l3proto { extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX]; /* Protocol registration. */ -extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto); -extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); +extern int nf_conntrack_l3proto_register(struct net *net, + struct nf_conntrack_l3proto *proto); +extern void nf_conntrack_l3proto_unregister(struct net *net, + struct nf_conntrack_l3proto *proto); extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 1f53038b0d1b..b2dbcc5cd813 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -20,6 +20,13 @@ struct nf_proto_net { unsigned int users; }; +struct nf_ip_net { +#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) + struct ctl_table_header *ctl_table_header; + struct ctl_table *ctl_table; +#endif +}; + struct netns_ct { atomic_t count; unsigned int expect_count; @@ -40,6 +47,7 @@ struct netns_ct { unsigned int sysctl_log_invalid; /* Log invalid packets */ int sysctl_auto_assign_helper; bool auto_assign_helper_warned; + struct nf_ip_net nf_ct_proto; #ifdef CONFIG_SYSCTL struct ctl_table_header *sysctl_header; struct ctl_table_header *acct_sysctl_header; diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 46ec515db129..0c0fb906c19d 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -409,7 +409,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) goto cleanup_udp; } - ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4); + ret = nf_conntrack_l3proto_register(&init_net, &nf_conntrack_l3proto_ipv4); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register ipv4\n"); goto cleanup_icmp; @@ -432,7 +432,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); #endif cleanup_ipv4: - nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); + nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv4); cleanup_icmp: nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp); cleanup_udp: @@ -451,7 +451,7 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void) nf_conntrack_ipv4_compat_fini(); #endif nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); - nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); + nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv4); nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp); nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4); nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4); diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 51ad9f104421..7334cbfd6003 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -358,7 +358,7 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) goto cleanup_udp; } - ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6); + ret = nf_conntrack_l3proto_register(&init_net, &nf_conntrack_l3proto_ipv6); if (ret < 0) { pr_err("nf_conntrack_ipv6: can't register ipv6\n"); goto cleanup_icmpv6; @@ -374,7 +374,7 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) return ret; cleanup_ipv6: - nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); + nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv6); cleanup_icmpv6: nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6); cleanup_udp: @@ -388,7 +388,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) { synchronize_net(); nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); - nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); + nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv6); nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6); nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6); nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6); diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 7ee31ac0a12c..a8daf0faadb7 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -168,31 +168,57 @@ static int kill_l4proto(struct nf_conn *i, void *data) nf_ct_l3num(i) == l4proto->l3proto; } -static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) +static struct nf_ip_net *nf_ct_l3proto_net(struct net *net, + struct nf_conntrack_l3proto *l3proto) +{ + if (l3proto->l3proto == PF_INET) + return &net->ct.nf_ct_proto; + else + return NULL; +} + +static int nf_ct_l3proto_register_sysctl(struct net *net, + struct nf_conntrack_l3proto *l3proto) { int err = 0; + struct nf_ip_net *in = nf_ct_l3proto_net(net, l3proto); + /* nf_conntrack_l3proto_ipv6 doesn't support sysctl */ + if (in == NULL) + return 0; -#ifdef CONFIG_SYSCTL - if (l3proto->ctl_table != NULL) { - err = nf_ct_register_sysctl(&init_net, - &l3proto->ctl_table_header, +#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) + if (in->ctl_table != NULL) { + err = nf_ct_register_sysctl(net, + &in->ctl_table_header, l3proto->ctl_table_path, - l3proto->ctl_table, NULL); + in->ctl_table, + NULL); + if (err < 0) { + kfree(in->ctl_table); + in->ctl_table = NULL; + } } #endif return err; } -static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto) +static void nf_ct_l3proto_unregister_sysctl(struct net *net, + struct nf_conntrack_l3proto *l3proto) { -#ifdef CONFIG_SYSCTL - if (l3proto->ctl_table_header != NULL) - nf_ct_unregister_sysctl(&l3proto->ctl_table_header, - &l3proto->ctl_table, NULL); + struct nf_ip_net *in = nf_ct_l3proto_net(net, l3proto); + + if (in == NULL) + return; +#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) + if (in->ctl_table_header != NULL) + nf_ct_unregister_sysctl(&in->ctl_table_header, + &in->ctl_table, + NULL); #endif } -int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) +static int +nf_conntrack_l3proto_register_net(struct nf_conntrack_l3proto *proto) { int ret = 0; struct nf_conntrack_l3proto *old; @@ -211,10 +237,6 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) goto out_unlock; } - ret = nf_ct_l3proto_register_sysctl(proto); - if (ret < 0) - goto out_unlock; - if (proto->nlattr_tuple_size) proto->nla_size = 3 * proto->nlattr_tuple_size(); @@ -223,13 +245,32 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) out_unlock: mutex_unlock(&nf_ct_proto_mutex); return ret; + } -EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); -void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) +int nf_conntrack_l3proto_register(struct net *net, + struct nf_conntrack_l3proto *proto) { - struct net *net; + int ret = 0; + + if (net == &init_net) + ret = nf_conntrack_l3proto_register_net(proto); + if (ret < 0) + return ret; + + if (proto->init_net) { + ret = proto->init_net(net); + if (ret < 0) + return ret; + } + return nf_ct_l3proto_register_sysctl(net, proto); +} +EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); + +static void +nf_conntrack_l3proto_unregister_net(struct nf_conntrack_l3proto *proto) +{ BUG_ON(proto->l3proto >= AF_MAX); mutex_lock(&nf_ct_proto_mutex); @@ -238,15 +279,22 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) ) != proto); rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], &nf_conntrack_l3proto_generic); - nf_ct_l3proto_unregister_sysctl(proto); mutex_unlock(&nf_ct_proto_mutex); synchronize_rcu(); +} + +void nf_conntrack_l3proto_unregister(struct net *net, + struct nf_conntrack_l3proto *proto) +{ + if (net == &init_net) + nf_conntrack_l3proto_unregister_net(proto); + + nf_ct_l3proto_unregister_sysctl(net, proto); /* Remove all contrack entries for this protocol */ rtnl_lock(); - for_each_net(net) - nf_ct_iterate_cleanup(net, kill_l3proto, proto); + nf_ct_iterate_cleanup(net, kill_l3proto, proto); rtnl_unlock(); } EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); -- GitLab From 15f585bd76b6bd2974b23c9e69ff038a0826a0be Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:11 +0000 Subject: [PATCH 0886/6849] netfilter: nf_ct_generic: add namespace support This patch adds namespace support for the generic layer 4 protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_core.h | 4 +- include/net/netns/conntrack.h | 6 +++ net/netfilter/nf_conntrack_core.c | 17 +++----- net/netfilter/nf_conntrack_proto.c | 46 ++++++++++++++-------- net/netfilter/nf_conntrack_proto_generic.c | 38 ++++++++++++++++-- 5 files changed, 78 insertions(+), 33 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index aced085132e7..d8f5b9f52169 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -28,8 +28,8 @@ extern unsigned int nf_conntrack_in(struct net *net, extern int nf_conntrack_init(struct net *net); extern void nf_conntrack_cleanup(struct net *net); -extern int nf_conntrack_proto_init(void); -extern void nf_conntrack_proto_fini(void); +extern int nf_conntrack_proto_init(struct net *net); +extern void nf_conntrack_proto_fini(struct net *net); extern bool nf_ct_get_tuple(const struct sk_buff *skb, diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index b2dbcc5cd813..0ef8592d48bf 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -20,7 +20,13 @@ struct nf_proto_net { unsigned int users; }; +struct nf_generic_net { + struct nf_proto_net pn; + unsigned int timeout; +}; + struct nf_ip_net { + struct nf_generic_net generic; #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) struct ctl_table_header *ctl_table_header; struct ctl_table *ctl_table; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ac3af97cc468..068f2e0ec58e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1333,7 +1333,6 @@ static void nf_conntrack_cleanup_init_net(void) while (untrack_refs() > 0) schedule(); - nf_conntrack_proto_fini(); #ifdef CONFIG_NF_CONNTRACK_ZONES nf_ct_extend_unregister(&nf_ct_zone_extend); #endif @@ -1372,7 +1371,7 @@ void nf_conntrack_cleanup(struct net *net) netfilter framework. Roll on, two-stage module delete... */ synchronize_net(); - + nf_conntrack_proto_fini(net); nf_conntrack_cleanup_net(net); if (net_eq(net, &init_net)) { @@ -1496,11 +1495,6 @@ static int nf_conntrack_init_init_net(void) printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n", NF_CONNTRACK_VERSION, nf_conntrack_htable_size, nf_conntrack_max); - - ret = nf_conntrack_proto_init(); - if (ret < 0) - goto err_proto; - #ifdef CONFIG_NF_CONNTRACK_ZONES ret = nf_ct_extend_register(&nf_ct_zone_extend); if (ret < 0) @@ -1518,9 +1512,7 @@ static int nf_conntrack_init_init_net(void) #ifdef CONFIG_NF_CONNTRACK_ZONES err_extend: - nf_conntrack_proto_fini(); #endif -err_proto: return ret; } @@ -1583,9 +1575,7 @@ static int nf_conntrack_init_net(struct net *net) ret = nf_conntrack_helper_init(net); if (ret < 0) goto err_helper; - return 0; - err_helper: nf_conntrack_timeout_fini(net); err_timeout: @@ -1622,6 +1612,9 @@ int nf_conntrack_init(struct net *net) if (ret < 0) goto out_init_net; } + ret = nf_conntrack_proto_init(net); + if (ret < 0) + goto out_proto; ret = nf_conntrack_init_net(net); if (ret < 0) goto out_net; @@ -1637,6 +1630,8 @@ int nf_conntrack_init(struct net *net) return 0; out_net: + nf_conntrack_proto_fini(net); +out_proto: if (net_eq(net, &init_net)) nf_conntrack_cleanup_init_net(); out_init_net: diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index a8daf0faadb7..b095b4aefd7c 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -302,10 +302,16 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, struct nf_conntrack_l4proto *l4proto) { - if (l4proto->net_id) - return net_generic(net, *l4proto->net_id); - else - return NULL; + switch (l4proto->l4proto) { + case 255: /* l4proto_generic */ + return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; + default: + if (l4proto->net_id) + return net_generic(net, *l4proto->net_id); + else + return NULL; + } + return NULL; } static @@ -487,28 +493,34 @@ void nf_conntrack_l4proto_unregister(struct net *net, } EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); -int nf_conntrack_proto_init(void) +int nf_conntrack_proto_init(struct net *net) { unsigned int i; int err; - - err = nf_ct_l4proto_register_sysctl(&init_net, &nf_conntrack_l4proto_generic); + err = nf_conntrack_l4proto_generic.init_net(net); + if (err < 0) + return err; + err = nf_ct_l4proto_register_sysctl(net, + &nf_conntrack_l4proto_generic); if (err < 0) return err; - for (i = 0; i < AF_MAX; i++) - rcu_assign_pointer(nf_ct_l3protos[i], - &nf_conntrack_l3proto_generic); + if (net == &init_net) { + for (i = 0; i < AF_MAX; i++) + rcu_assign_pointer(nf_ct_l3protos[i], + &nf_conntrack_l3proto_generic); + } return 0; } -void nf_conntrack_proto_fini(void) +void nf_conntrack_proto_fini(struct net *net) { unsigned int i; - - nf_ct_l4proto_unregister_sysctl(&init_net, &nf_conntrack_l4proto_generic); - - /* free l3proto protocol tables */ - for (i = 0; i < PF_MAX; i++) - kfree(nf_ct_protos[i]); + nf_ct_l4proto_unregister_sysctl(net, + &nf_conntrack_l4proto_generic); + if (net == &init_net) { + /* free l3proto protocol tables */ + for (i = 0; i < PF_MAX; i++) + kfree(nf_ct_protos[i]); + } } diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index d8923d54b358..19bc880eb4e2 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -14,6 +14,11 @@ static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; +static inline struct nf_generic_net *generic_pernet(struct net *net) +{ + return &net->ct.nf_ct_proto.generic; +} + static bool generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) @@ -42,7 +47,7 @@ static int generic_print_tuple(struct seq_file *s, static unsigned int *generic_get_timeouts(struct net *net) { - return &nf_ct_generic_timeout; + return &(generic_pernet(net)->timeout); } /* Returns verdict for packet, or -1 for invalid. */ @@ -110,7 +115,6 @@ static struct ctl_table_header *generic_sysctl_header; static struct ctl_table generic_sysctl_table[] = { { .procname = "nf_conntrack_generic_timeout", - .data = &nf_ct_generic_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -121,7 +125,6 @@ static struct ctl_table generic_sysctl_table[] = { static struct ctl_table generic_compat_sysctl_table[] = { { .procname = "ip_conntrack_generic_timeout", - .data = &nf_ct_generic_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -131,6 +134,34 @@ static struct ctl_table generic_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ +static int generic_init_net(struct net *net) +{ + struct nf_generic_net *gn = generic_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)gn; + gn->timeout = nf_ct_generic_timeout; +#ifdef CONFIG_SYSCTL + pn->ctl_table = kmemdup(generic_sysctl_table, + sizeof(generic_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + pn->ctl_table[0].data = &gn->timeout; + +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table, + sizeof(generic_compat_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_compat_table) { + kfree(pn->ctl_table); + pn->ctl_table = NULL; + return -ENOMEM; + } + pn->ctl_compat_table[0].data = &gn->timeout; +#endif +#endif + return 0; +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = { .l3proto = PF_UNSPEC, @@ -158,4 +189,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = .ctl_compat_table = generic_compat_sysctl_table, #endif #endif + .init_net = generic_init_net, }; -- GitLab From d2ba1fde42af44fbce361202e9af13daff9e4381 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:12 +0000 Subject: [PATCH 0887/6849] netfilter: nf_ct_tcp: add namespace support This patch adds namespace support for TCP protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netns/conntrack.h | 10 ++ net/netfilter/nf_conntrack_proto.c | 2 + net/netfilter/nf_conntrack_proto_tcp.c | 162 ++++++++++++++++++++----- 3 files changed, 145 insertions(+), 29 deletions(-) diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 0ef8592d48bf..680d799ece8b 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -4,6 +4,7 @@ #include #include #include +#include struct ctl_table_header; struct nf_conntrack_ecache; @@ -25,8 +26,17 @@ struct nf_generic_net { unsigned int timeout; }; +struct nf_tcp_net { + struct nf_proto_net pn; + unsigned int timeouts[TCP_CONNTRACK_TIMEOUT_MAX]; + unsigned int tcp_loose; + unsigned int tcp_be_liberal; + unsigned int tcp_max_retrans; +}; + struct nf_ip_net { struct nf_generic_net generic; + struct nf_tcp_net tcp; #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) struct ctl_table_header *ctl_table_header; struct ctl_table *ctl_table; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index b095b4aefd7c..8a71e8bb0d6c 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -303,6 +303,8 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, struct nf_conntrack_l4proto *l4proto) { switch (l4proto->l4proto) { + case IPPROTO_TCP: + return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp; case 255: /* l4proto_generic */ return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; default: diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 21ff1a99f534..a053f6786b3c 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -270,6 +270,11 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { } }; +static inline struct nf_tcp_net *tcp_pernet(struct net *net) +{ + return &net->ct.nf_ct_proto.tcp; +} + static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) { @@ -516,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct, u_int8_t pf) { struct net *net = nf_ct_net(ct); + struct nf_tcp_net *tn = tcp_pernet(net); struct ip_ct_tcp_state *sender = &state->seen[dir]; struct ip_ct_tcp_state *receiver = &state->seen[!dir]; const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; @@ -720,7 +726,7 @@ static bool tcp_in_window(const struct nf_conn *ct, } else { res = false; if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || - nf_ct_tcp_be_liberal) + tn->tcp_be_liberal) res = true; if (!res && LOG_INVALID(net, IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, @@ -828,6 +834,7 @@ static int tcp_packet(struct nf_conn *ct, unsigned int *timeouts) { struct net *net = nf_ct_net(ct); + struct nf_tcp_net *tn = tcp_pernet(net); struct nf_conntrack_tuple *tuple; enum tcp_conntrack new_state, old_state; enum ip_conntrack_dir dir; @@ -1020,7 +1027,7 @@ static int tcp_packet(struct nf_conn *ct, && new_state == TCP_CONNTRACK_FIN_WAIT) ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; - if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans && + if (ct->proto.tcp.retrans >= tn->tcp_max_retrans && timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) timeout = timeouts[TCP_CONNTRACK_RETRANS]; else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) & @@ -1065,6 +1072,8 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb, enum tcp_conntrack new_state; const struct tcphdr *th; struct tcphdr _tcph; + struct net *net = nf_ct_net(ct); + struct nf_tcp_net *tn = tcp_pernet(net); const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0]; const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1]; @@ -1093,7 +1102,7 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb, ct->proto.tcp.seen[0].td_end; tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]); - } else if (nf_ct_tcp_loose == 0) { + } else if (tn->tcp_loose == 0) { /* Don't try to pick up connections. */ return false; } else { @@ -1360,91 +1369,78 @@ static struct ctl_table_header *tcp_sysctl_header; static struct ctl_table tcp_sysctl_table[] = { { .procname = "nf_conntrack_tcp_timeout_syn_sent", - .data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_syn_recv", - .data = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_established", - .data = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_fin_wait", - .data = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_close_wait", - .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_last_ack", - .data = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_time_wait", - .data = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_close", - .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_max_retrans", - .data = &tcp_timeouts[TCP_CONNTRACK_RETRANS], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_timeout_unacknowledged", - .data = &tcp_timeouts[TCP_CONNTRACK_UNACK], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_tcp_loose", - .data = &nf_ct_tcp_loose, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec, }, { .procname = "nf_conntrack_tcp_be_liberal", - .data = &nf_ct_tcp_be_liberal, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec, }, { .procname = "nf_conntrack_tcp_max_retrans", - .data = &nf_ct_tcp_max_retrans, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec, @@ -1456,91 +1452,78 @@ static struct ctl_table tcp_sysctl_table[] = { static struct ctl_table tcp_compat_sysctl_table[] = { { .procname = "ip_conntrack_tcp_timeout_syn_sent", - .data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_syn_sent2", - .data = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT2], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_syn_recv", - .data = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_established", - .data = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_fin_wait", - .data = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_close_wait", - .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_last_ack", - .data = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_time_wait", - .data = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_close", - .data = &tcp_timeouts[TCP_CONNTRACK_CLOSE], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_timeout_max_retrans", - .data = &tcp_timeouts[TCP_CONNTRACK_RETRANS], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_tcp_loose", - .data = &nf_ct_tcp_loose, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec, }, { .procname = "ip_conntrack_tcp_be_liberal", - .data = &nf_ct_tcp_be_liberal, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec, }, { .procname = "ip_conntrack_tcp_max_retrans", - .data = &nf_ct_tcp_max_retrans, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec, @@ -1550,6 +1533,125 @@ static struct ctl_table tcp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ +static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn) +{ +#ifdef CONFIG_SYSCTL + struct nf_tcp_net *tn = (struct nf_tcp_net *)pn; + + if (pn->ctl_table) + return 0; + + pn->ctl_table = kmemdup(tcp_sysctl_table, + sizeof(tcp_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + + pn->ctl_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT]; + pn->ctl_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV]; + pn->ctl_table[2].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED]; + pn->ctl_table[3].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT]; + pn->ctl_table[4].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT]; + pn->ctl_table[5].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK]; + pn->ctl_table[6].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT]; + pn->ctl_table[7].data = &tn->timeouts[TCP_CONNTRACK_CLOSE]; + pn->ctl_table[8].data = &tn->timeouts[TCP_CONNTRACK_RETRANS]; + pn->ctl_table[9].data = &tn->timeouts[TCP_CONNTRACK_UNACK]; + pn->ctl_table[10].data = &tn->tcp_loose; + pn->ctl_table[11].data = &tn->tcp_be_liberal; + pn->ctl_table[12].data = &tn->tcp_max_retrans; +#endif + return 0; +} + +static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) +{ +#ifdef CONFIG_SYSCTL +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + struct nf_tcp_net *tn = (struct nf_tcp_net *)pn; + pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table, + sizeof(tcp_compat_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_compat_table) + return -ENOMEM; + + pn->ctl_compat_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT]; + pn->ctl_compat_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT2]; + pn->ctl_compat_table[2].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV]; + pn->ctl_compat_table[3].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED]; + pn->ctl_compat_table[4].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT]; + pn->ctl_compat_table[5].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT]; + pn->ctl_compat_table[6].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK]; + pn->ctl_compat_table[7].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT]; + pn->ctl_compat_table[8].data = &tn->timeouts[TCP_CONNTRACK_CLOSE]; + pn->ctl_compat_table[9].data = &tn->timeouts[TCP_CONNTRACK_RETRANS]; + pn->ctl_compat_table[10].data = &tn->tcp_loose; + pn->ctl_compat_table[11].data = &tn->tcp_be_liberal; + pn->ctl_compat_table[12].data = &tn->tcp_max_retrans; +#endif +#endif + return 0; +} + +static int tcpv4_init_net(struct net *net) +{ + int i; + int ret = 0; + struct nf_tcp_net *tn = tcp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)tn; + +#ifdef CONFIG_SYSCTL + if (!pn->ctl_table) { +#else + if (!pn->user++) { +#endif + for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) + tn->timeouts[i] = tcp_timeouts[i]; + + tn->tcp_loose = nf_ct_tcp_loose; + tn->tcp_be_liberal = nf_ct_tcp_be_liberal; + tn->tcp_max_retrans = nf_ct_tcp_max_retrans; + } + + ret = tcp_kmemdup_compat_sysctl_table(pn); + + if (ret < 0) + return ret; + + ret = tcp_kmemdup_sysctl_table(pn); + +#ifdef CONFIG_SYSCTL +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + if (ret < 0) { + kfree(pn->ctl_compat_table); + pn->ctl_compat_table = NULL; + } +#endif +#endif + return ret; +} + +static int tcpv6_init_net(struct net *net) +{ + int i; + struct nf_tcp_net *tn = tcp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)tn; + +#ifdef CONFIG_SYSCTL + if (!pn->ctl_table) { +#else + if (!pn->user++) { +#endif + for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) + tn->timeouts[i] = tcp_timeouts[i]; + tn->tcp_loose = nf_ct_tcp_loose; + tn->tcp_be_liberal = nf_ct_tcp_be_liberal; + tn->tcp_max_retrans = nf_ct_tcp_max_retrans; + } + + return tcp_kmemdup_sysctl_table(pn); +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = { .l3proto = PF_INET, @@ -1590,6 +1692,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = .ctl_compat_table = tcp_compat_sysctl_table, #endif #endif + .init_net = tcpv4_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4); @@ -1630,5 +1733,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly = .ctl_table_header = &tcp_sysctl_header, .ctl_table = tcp_sysctl_table, #endif + .init_net = tcpv6_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6); -- GitLab From 0ce490ad4387a67ee8ca5253476272d508fc0b6f Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:13 +0000 Subject: [PATCH 0888/6849] netfilter: nf_ct_udp: add namespace support This patch adds namespace support for UDP protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netns/conntrack.h | 12 +++ net/netfilter/nf_conntrack_proto.c | 2 + net/netfilter/nf_conntrack_proto_udp.c | 100 ++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 11 deletions(-) diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 680d799ece8b..7bd14ab8ce1c 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -34,9 +34,21 @@ struct nf_tcp_net { unsigned int tcp_max_retrans; }; +enum udp_conntrack { + UDP_CT_UNREPLIED, + UDP_CT_REPLIED, + UDP_CT_MAX +}; + +struct nf_udp_net { + struct nf_proto_net pn; + unsigned int timeouts[UDP_CT_MAX]; +}; + struct nf_ip_net { struct nf_generic_net generic; struct nf_tcp_net tcp; + struct nf_udp_net udp; #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) struct ctl_table_header *ctl_table_header; struct ctl_table *ctl_table; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 8a71e8bb0d6c..9c6aee51dea2 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -305,6 +305,8 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, switch (l4proto->l4proto) { case IPPROTO_TCP: return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp; + case IPPROTO_UDP: + return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp; case 255: /* l4proto_generic */ return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; default: diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 7259a6bdeb49..f56c8905ddfb 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -25,17 +25,16 @@ #include #include -enum udp_conntrack { - UDP_CT_UNREPLIED, - UDP_CT_REPLIED, - UDP_CT_MAX -}; - static unsigned int udp_timeouts[UDP_CT_MAX] = { [UDP_CT_UNREPLIED] = 30*HZ, [UDP_CT_REPLIED] = 180*HZ, }; +static inline struct nf_udp_net *udp_pernet(struct net *net) +{ + return &net->ct.nf_ct_proto.udp; +} + static bool udp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) @@ -73,7 +72,7 @@ static int udp_print_tuple(struct seq_file *s, static unsigned int *udp_get_timeouts(struct net *net) { - return udp_timeouts; + return udp_pernet(net)->timeouts; } /* Returns verdict for packet, and may modify conntracktype */ @@ -205,14 +204,12 @@ static struct ctl_table_header *udp_sysctl_header; static struct ctl_table udp_sysctl_table[] = { { .procname = "nf_conntrack_udp_timeout", - .data = &udp_timeouts[UDP_CT_UNREPLIED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_udp_timeout_stream", - .data = &udp_timeouts[UDP_CT_REPLIED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -223,14 +220,12 @@ static struct ctl_table udp_sysctl_table[] = { static struct ctl_table udp_compat_sysctl_table[] = { { .procname = "ip_conntrack_udp_timeout", - .data = &udp_timeouts[UDP_CT_UNREPLIED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_udp_timeout_stream", - .data = &udp_timeouts[UDP_CT_REPLIED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -240,6 +235,87 @@ static struct ctl_table udp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ +static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn) +{ +#ifdef CONFIG_SYSCTL + struct nf_udp_net *un = (struct nf_udp_net *)pn; + if (pn->ctl_table) + return 0; + pn->ctl_table = kmemdup(udp_sysctl_table, + sizeof(udp_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + pn->ctl_table[0].data = &un->timeouts[UDP_CT_UNREPLIED]; + pn->ctl_table[1].data = &un->timeouts[UDP_CT_REPLIED]; +#endif + return 0; +} + +static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) +{ +#ifdef CONFIG_SYSCTL +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + struct nf_udp_net *un = (struct nf_udp_net *)pn; + pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table, + sizeof(udp_compat_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_compat_table) + return -ENOMEM; + + pn->ctl_compat_table[0].data = &un->timeouts[UDP_CT_UNREPLIED]; + pn->ctl_compat_table[1].data = &un->timeouts[UDP_CT_REPLIED]; +#endif +#endif + return 0; +} + +static void udp_init_net_data(struct nf_udp_net *un) +{ + int i; +#ifdef CONFIG_SYSCTL + if (!un->pn.ctl_table) { +#else + if (!un->pn.user++) { +#endif + for (i = 0; i < UDP_CT_MAX; i++) + un->timeouts[i] = udp_timeouts[i]; + } +} + +static int udpv4_init_net(struct net *net) +{ + int ret; + struct nf_udp_net *un = udp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)un; + + udp_init_net_data(un); + + ret = udp_kmemdup_compat_sysctl_table(pn); + if (ret < 0) + return ret; + + ret = udp_kmemdup_sysctl_table(pn); +#ifdef CONFIG_SYSCTL +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + if (ret < 0) { + kfree(pn->ctl_compat_table); + pn->ctl_compat_table = NULL; + } +#endif +#endif + return ret; +} + +static int udpv6_init_net(struct net *net) +{ + struct nf_udp_net *un = udp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)un; + + udp_init_net_data(un); + return udp_kmemdup_sysctl_table(pn); +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = { .l3proto = PF_INET, @@ -275,6 +351,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = .ctl_compat_table = udp_compat_sysctl_table, #endif #endif + .init_net = udpv4_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4); @@ -310,5 +387,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly = .ctl_table_header = &udp_sysctl_header, .ctl_table = udp_sysctl_table, #endif + .init_net = udpv6_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6); -- GitLab From 4b626b9c5d35b4f99b073dc5d6457abddcbcf429 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:14 +0000 Subject: [PATCH 0889/6849] netfilter: nf_ct_icmp: add namespace support This patch adds namespace support for ICMP protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netns/conntrack.h | 6 ++++ net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 38 ++++++++++++++++++-- net/netfilter/nf_conntrack_proto.c | 2 ++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 7bd14ab8ce1c..3d8e9e3b08a6 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -45,10 +45,16 @@ struct nf_udp_net { unsigned int timeouts[UDP_CT_MAX]; }; +struct nf_icmp_net { + struct nf_proto_net pn; + unsigned int timeout; +}; + struct nf_ip_net { struct nf_generic_net generic; struct nf_tcp_net tcp; struct nf_udp_net udp; + struct nf_icmp_net icmp; #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) struct ctl_table_header *ctl_table_header; struct ctl_table *ctl_table; diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 0847e373d33c..a0eabeb36b9f 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -23,6 +23,11 @@ static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ; +static inline struct nf_icmp_net *icmp_pernet(struct net *net) +{ + return &net->ct.nf_ct_proto.icmp; +} + static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) { @@ -77,7 +82,7 @@ static int icmp_print_tuple(struct seq_file *s, static unsigned int *icmp_get_timeouts(struct net *net) { - return &nf_ct_icmp_timeout; + return &icmp_pernet(net)->timeout; } /* Returns verdict for packet, or -1 for invalid. */ @@ -312,7 +317,6 @@ static struct ctl_table_header *icmp_sysctl_header; static struct ctl_table icmp_sysctl_table[] = { { .procname = "nf_conntrack_icmp_timeout", - .data = &nf_ct_icmp_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -323,7 +327,6 @@ static struct ctl_table icmp_sysctl_table[] = { static struct ctl_table icmp_compat_sysctl_table[] = { { .procname = "ip_conntrack_icmp_timeout", - .data = &nf_ct_icmp_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -333,6 +336,34 @@ static struct ctl_table icmp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ +static int icmp_init_net(struct net *net) +{ + struct nf_icmp_net *in = icmp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)in; + in->timeout = nf_ct_icmp_timeout; + +#ifdef CONFIG_SYSCTL + pn->ctl_table = kmemdup(icmp_sysctl_table, + sizeof(icmp_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + pn->ctl_table[0].data = &in->timeout; +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + pn->ctl_compat_table = kmemdup(icmp_compat_sysctl_table, + sizeof(icmp_compat_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_compat_table) { + kfree(pn->ctl_table); + pn->ctl_table = NULL; + return -ENOMEM; + } + pn->ctl_compat_table[0].data = &in->timeout; +#endif +#endif + return 0; +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = { .l3proto = PF_INET, @@ -369,4 +400,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = .ctl_compat_table = icmp_compat_sysctl_table, #endif #endif + .init_net = icmp_init_net, }; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 9c6aee51dea2..dbade5f2b1d3 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -307,6 +307,8 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, return (struct nf_proto_net *)&net->ct.nf_ct_proto.tcp; case IPPROTO_UDP: return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp; + case IPPROTO_ICMP: + return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmp; case 255: /* l4proto_generic */ return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; default: -- GitLab From 7080ba0955438ecd2885c1b73fbd9760b1594a41 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:15 +0000 Subject: [PATCH 0890/6849] netfilter: nf_ct_icmp: add namespace support This patch adds namespace support for ICMPv6 protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netns/conntrack.h | 1 + .../netfilter/nf_conntrack_proto_icmpv6.c | 25 +++++++++++++++++-- net/netfilter/nf_conntrack_proto.c | 2 ++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 3d8e9e3b08a6..3aecdc7a84fb 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -55,6 +55,7 @@ struct nf_ip_net { struct nf_tcp_net tcp; struct nf_udp_net udp; struct nf_icmp_net icmp; + struct nf_icmp_net icmpv6; #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) struct ctl_table_header *ctl_table_header; struct ctl_table *ctl_table; diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 3e81904fbbcd..f606355200d8 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -29,6 +29,11 @@ static unsigned int nf_ct_icmpv6_timeout __read_mostly = 30*HZ; +static inline struct nf_icmp_net *icmpv6_pernet(struct net *net) +{ + return &net->ct.nf_ct_proto.icmpv6; +} + static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) @@ -90,7 +95,7 @@ static int icmpv6_print_tuple(struct seq_file *s, static unsigned int *icmpv6_get_timeouts(struct net *net) { - return &nf_ct_icmpv6_timeout; + return &icmpv6_pernet(net)->timeout; } /* Returns verdict for packet, or -1 for invalid. */ @@ -319,7 +324,6 @@ static struct ctl_table_header *icmpv6_sysctl_header; static struct ctl_table icmpv6_sysctl_table[] = { { .procname = "nf_conntrack_icmpv6_timeout", - .data = &nf_ct_icmpv6_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -328,6 +332,22 @@ static struct ctl_table icmpv6_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ +static int icmpv6_init_net(struct net *net) +{ + struct nf_icmp_net *in = icmpv6_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)in; + in->timeout = nf_ct_icmpv6_timeout; +#ifdef CONFIG_SYSCTL + pn->ctl_table = kmemdup(icmpv6_sysctl_table, + sizeof(icmpv6_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + pn->ctl_table[0].data = &in->timeout; +#endif + return 0; +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = { .l3proto = PF_INET6, @@ -359,4 +379,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = .ctl_table_header = &icmpv6_sysctl_header, .ctl_table = icmpv6_sysctl_table, #endif + .init_net = icmpv6_init_net, }; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index dbade5f2b1d3..1ea919450fc3 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -309,6 +309,8 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp; case IPPROTO_ICMP: return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmp; + case IPPROTO_ICMPV6: + return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmpv6; case 255: /* l4proto_generic */ return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic; default: -- GitLab From 3ea04dd3a78916db9186a602b6ce974d36a33fbb Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:16 +0000 Subject: [PATCH 0891/6849] netfilter: nf_ct_ipv4: add namespace support This patch adds namespace support for IPv4 protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- .../netfilter/nf_conntrack_l3proto_ipv4.c | 123 ++++++++++++------ 1 file changed, 85 insertions(+), 38 deletions(-) diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 0c0fb906c19d..5c66203af51c 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -207,35 +207,30 @@ static int log_invalid_proto_max = 255; static ctl_table ip_ct_sysctl_table[] = { { .procname = "ip_conntrack_max", - .data = &nf_conntrack_max, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, { .procname = "ip_conntrack_count", - .data = &init_net.ct.count, .maxlen = sizeof(int), .mode = 0444, .proc_handler = proc_dointvec, }, { .procname = "ip_conntrack_buckets", - .data = &init_net.ct.htable_size, .maxlen = sizeof(unsigned int), .mode = 0444, .proc_handler = proc_dointvec, }, { .procname = "ip_conntrack_checksum", - .data = &init_net.ct.sysctl_checksum, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, { .procname = "ip_conntrack_log_invalid", - .data = &init_net.ct.sysctl_log_invalid, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_minmax, @@ -351,6 +346,25 @@ static struct nf_sockopt_ops so_getorigdst = { .owner = THIS_MODULE, }; +static int ipv4_init_net(struct net *net) +{ +#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) + struct nf_ip_net *in = &net->ct.nf_ct_proto; + in->ctl_table = kmemdup(ip_ct_sysctl_table, + sizeof(ip_ct_sysctl_table), + GFP_KERNEL); + if (!in->ctl_table) + return -ENOMEM; + + in->ctl_table[0].data = &nf_conntrack_max; + in->ctl_table[1].data = &net->ct.count; + in->ctl_table[2].data = &net->ct.htable_size; + in->ctl_table[3].data = &net->ct.sysctl_checksum; + in->ctl_table[4].data = &net->ct.sysctl_log_invalid; +#endif + return 0; +} + struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .l3proto = PF_INET, .name = "ipv4", @@ -368,6 +382,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .ctl_table_path = "net/ipv4/netfilter", .ctl_table = ip_ct_sysctl_table, #endif + .init_net = ipv4_init_net, .me = THIS_MODULE, }; @@ -378,6 +393,65 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); MODULE_ALIAS("ip_conntrack"); MODULE_LICENSE("GPL"); +static int ipv4_net_init(struct net *net) +{ + int ret = 0; + + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_tcp4); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_tcp4 :protocol register failed\n"); + goto out_tcp; + } + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_udp4); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_udp4 :protocol register failed\n"); + goto out_udp; + } + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_icmp); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n"); + goto out_icmp; + } + ret = nf_conntrack_l3proto_register(net, + &nf_conntrack_l3proto_ipv4); + if (ret < 0) { + pr_err("nf_conntrack_l3proto_ipv4 :protocol register failed\n"); + goto out_ipv4; + } + return 0; +out_ipv4: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_icmp); +out_icmp: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_udp4); +out_udp: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_tcp4); +out_tcp: + return ret; +} + +static void ipv4_net_exit(struct net *net) +{ + nf_conntrack_l3proto_unregister(net, + &nf_conntrack_l3proto_ipv4); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_icmp); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_udp4); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_tcp4); +} + +static struct pernet_operations ipv4_net_ops = { + .init = ipv4_net_init, + .exit = ipv4_net_exit, +}; + static int __init nf_conntrack_l3proto_ipv4_init(void) { int ret = 0; @@ -391,35 +465,17 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) return ret; } - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_tcp4); + ret = register_pernet_subsys(&ipv4_net_ops); if (ret < 0) { - pr_err("nf_conntrack_ipv4: can't register tcp.\n"); + pr_err("nf_conntrack_ipv4: can't register pernet ops\n"); goto cleanup_sockopt; } - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udp4); - if (ret < 0) { - pr_err("nf_conntrack_ipv4: can't register udp.\n"); - goto cleanup_tcp; - } - - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_icmp); - if (ret < 0) { - pr_err("nf_conntrack_ipv4: can't register icmp.\n"); - goto cleanup_udp; - } - - ret = nf_conntrack_l3proto_register(&init_net, &nf_conntrack_l3proto_ipv4); - if (ret < 0) { - pr_err("nf_conntrack_ipv4: can't register ipv4\n"); - goto cleanup_icmp; - } - ret = nf_register_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register hooks.\n"); - goto cleanup_ipv4; + goto cleanup_pernet; } #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) ret = nf_conntrack_ipv4_compat_init(); @@ -431,14 +487,8 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) cleanup_hooks: nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); #endif - cleanup_ipv4: - nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv4); - cleanup_icmp: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp); - cleanup_udp: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4); - cleanup_tcp: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4); + cleanup_pernet: + unregister_pernet_subsys(&ipv4_net_ops); cleanup_sockopt: nf_unregister_sockopt(&so_getorigdst); return ret; @@ -451,10 +501,7 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void) nf_conntrack_ipv4_compat_fini(); #endif nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); - nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv4); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4); + unregister_pernet_subsys(&ipv4_net_ops); nf_unregister_sockopt(&so_getorigdst); } -- GitLab From a7c439d3968e67c426f75fe7d455f214e52f1ab0 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:17 +0000 Subject: [PATCH 0892/6849] netfilter: nf_ct_ipv6: add namespace support This patch adds namespace support for IPv6 protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- .../netfilter/nf_conntrack_l3proto_ipv6.c | 88 +++++++++++++------ 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 7334cbfd6003..fca10da80ea7 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -333,37 +333,75 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI "); -static int __init nf_conntrack_l3proto_ipv6_init(void) +static int ipv6_net_init(struct net *net) { int ret = 0; - need_conntrack(); - nf_defrag_ipv6_enable(); - - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_tcp6); + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_tcp6); if (ret < 0) { - pr_err("nf_conntrack_ipv6: can't register tcp.\n"); - return ret; + printk(KERN_ERR "nf_conntrack_l4proto_tcp6: protocol register failed\n"); + goto out; } - - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udp6); + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_udp6); if (ret < 0) { - pr_err("nf_conntrack_ipv6: can't register udp.\n"); - goto cleanup_tcp; + printk(KERN_ERR "nf_conntrack_l4proto_udp6: protocol register failed\n"); + goto cleanup_tcp6; } - - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_icmpv6); + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_icmpv6); if (ret < 0) { - pr_err("nf_conntrack_ipv6: can't register icmpv6.\n"); - goto cleanup_udp; + printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n"); + goto cleanup_udp6; } - - ret = nf_conntrack_l3proto_register(&init_net, &nf_conntrack_l3proto_ipv6); + ret = nf_conntrack_l3proto_register(net, + &nf_conntrack_l3proto_ipv6); if (ret < 0) { - pr_err("nf_conntrack_ipv6: can't register ipv6\n"); + printk(KERN_ERR "nf_conntrack_l3proto_ipv6: protocol register failed\n"); goto cleanup_icmpv6; } + return 0; + cleanup_icmpv6: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_icmpv6); + cleanup_udp6: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_udp6); + cleanup_tcp6: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_tcp6); + out: + return ret; +} +static void ipv6_net_exit(struct net *net) +{ + nf_conntrack_l3proto_unregister(net, + &nf_conntrack_l3proto_ipv6); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_icmpv6); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_udp6); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_tcp6); +} + +static struct pernet_operations ipv6_net_ops = { + .init = ipv6_net_init, + .exit = ipv6_net_exit, +}; + +static int __init nf_conntrack_l3proto_ipv6_init(void) +{ + int ret = 0; + + need_conntrack(); + nf_defrag_ipv6_enable(); + + ret = register_pernet_subsys(&ipv6_net_ops); + if (ret < 0) + goto cleanup_pernet; ret = nf_register_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); if (ret < 0) { @@ -374,13 +412,8 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) return ret; cleanup_ipv6: - nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv6); - cleanup_icmpv6: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6); - cleanup_udp: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6); - cleanup_tcp: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6); + unregister_pernet_subsys(&ipv6_net_ops); + cleanup_pernet: return ret; } @@ -388,10 +421,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) { synchronize_net(); nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); - nf_conntrack_l3proto_unregister(&init_net, &nf_conntrack_l3proto_ipv6); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6); + unregister_pernet_subsys(&ipv6_net_ops); } module_init(nf_conntrack_l3proto_ipv6_init); -- GitLab From 49d485a30f3058b2633f86f85efae04c824ceffe Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:18 +0000 Subject: [PATCH 0893/6849] netfilter: nf_ct_sctp: add namespace support This patch adds namespace support for SCTP protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_sctp.c | 175 ++++++++++++++++++++---- 1 file changed, 146 insertions(+), 29 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 97bbc20e1a2b..9e5738db34df 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -127,6 +127,17 @@ static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { } }; +static int sctp_net_id __read_mostly; +struct sctp_net { + struct nf_proto_net pn; + unsigned int timeouts[SCTP_CONNTRACK_MAX]; +}; + +static inline struct sctp_net *sctp_pernet(struct net *net) +{ + return net_generic(net, sctp_net_id); +} + static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) { @@ -281,7 +292,7 @@ static int sctp_new_state(enum ip_conntrack_dir dir, static unsigned int *sctp_get_timeouts(struct net *net) { - return sctp_timeouts; + return sctp_pernet(net)->timeouts; } /* Returns verdict for packet, or -NF_ACCEPT for invalid. */ @@ -604,49 +615,42 @@ static struct ctl_table_header *sctp_sysctl_header; static struct ctl_table sctp_sysctl_table[] = { { .procname = "nf_conntrack_sctp_timeout_closed", - .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_cookie_wait", - .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_cookie_echoed", - .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_established", - .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_shutdown_sent", - .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_shutdown_recd", - .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", - .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -658,49 +662,42 @@ static struct ctl_table sctp_sysctl_table[] = { static struct ctl_table sctp_compat_sysctl_table[] = { { .procname = "ip_conntrack_sctp_timeout_closed", - .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_cookie_wait", - .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_cookie_echoed", - .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_established", - .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_shutdown_sent", - .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_shutdown_recd", - .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent", - .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -710,6 +707,101 @@ static struct ctl_table sctp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif +static void sctp_init_net_data(struct sctp_net *sn) +{ + int i; +#ifdef CONFIG_SYSCTL + if (!sn->pn.ctl_table) { +#else + if (!sn->pn.users++) { +#endif + for (i = 0; i < SCTP_CONNTRACK_MAX; i++) + sn->timeouts[i] = sctp_timeouts[i]; + } +} + +static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn) +{ +#ifdef CONFIG_SYSCTL + struct sctp_net *sn = (struct sctp_net *)pn; + if (pn->ctl_table) + return 0; + + pn->ctl_table = kmemdup(sctp_sysctl_table, + sizeof(sctp_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + + pn->ctl_table[0].data = &sn->timeouts[SCTP_CONNTRACK_CLOSED]; + pn->ctl_table[1].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_WAIT]; + pn->ctl_table[2].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_ECHOED]; + pn->ctl_table[3].data = &sn->timeouts[SCTP_CONNTRACK_ESTABLISHED]; + pn->ctl_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT]; + pn->ctl_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD]; + pn->ctl_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]; +#endif + return 0; +} + +static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) +{ +#ifdef CONFIG_SYSCTL +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + struct sctp_net *sn = (struct sctp_net *)pn; + pn->ctl_compat_table = kmemdup(sctp_compat_sysctl_table, + sizeof(sctp_compat_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_compat_table) + return -ENOMEM; + + pn->ctl_compat_table[0].data = &sn->timeouts[SCTP_CONNTRACK_CLOSED]; + pn->ctl_compat_table[1].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_WAIT]; + pn->ctl_compat_table[2].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_ECHOED]; + pn->ctl_compat_table[3].data = &sn->timeouts[SCTP_CONNTRACK_ESTABLISHED]; + pn->ctl_compat_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT]; + pn->ctl_compat_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD]; + pn->ctl_compat_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]; +#endif +#endif + return 0; +} + +static int sctpv4_init_net(struct net *net) +{ + int ret; + struct sctp_net *sn = sctp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)sn; + + sctp_init_net_data(sn); + + ret = sctp_kmemdup_compat_sysctl_table(pn); + if (ret < 0) + return ret; + + ret = sctp_kmemdup_sysctl_table(pn); + +#ifdef CONFIG_SYSCTL +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + if (ret < 0) { + + kfree(pn->ctl_compat_table); + pn->ctl_compat_table = NULL; + } +#endif +#endif + return ret; +} + +static int sctpv6_init_net(struct net *net) +{ + struct sctp_net *sn = sctp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)sn; + + sctp_init_net_data(sn); + return sctp_kmemdup_sysctl_table(pn); +} + static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_SCTP, @@ -748,6 +840,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { .ctl_compat_table = sctp_compat_sysctl_table, #endif #endif + .net_id = &sctp_net_id, + .init_net = sctpv4_init_net, }; static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { @@ -785,35 +879,58 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { .ctl_table_header = &sctp_sysctl_header, .ctl_table = sctp_sysctl_table, #endif + .net_id = &sctp_net_id, + .init_net = sctpv6_init_net, }; -static int __init nf_conntrack_proto_sctp_init(void) +static int sctp_net_init(struct net *net) { - int ret; + int ret = 0; - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp4); - if (ret) { - pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n"); + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_sctp4); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_sctp4 :protocol register failed.\n"); goto out; } - ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp6); - if (ret) { - pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n"); + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_sctp6); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_sctp6 :protocol register failed.\n"); goto cleanup_sctp4; } + return 0; +cleanup_sctp4: + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_sctp4); +out: return ret; +} - cleanup_sctp4: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4); - out: - return ret; +static void sctp_net_exit(struct net *net) +{ + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_sctp6); + nf_conntrack_l4proto_unregister(net, + &nf_conntrack_l4proto_sctp4); +} + +static struct pernet_operations sctp_net_ops = { + .init = sctp_net_init, + .exit = sctp_net_exit, + .id = &sctp_net_id, + .size = sizeof(struct sctp_net), +}; + +static int __init nf_conntrack_proto_sctp_init(void) +{ + return register_pernet_subsys(&sctp_net_ops); } static void __exit nf_conntrack_proto_sctp_fini(void) { - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp6); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4); + unregister_pernet_subsys(&sctp_net_ops); } module_init(nf_conntrack_proto_sctp_init); -- GitLab From a8021feddafe3d1b5cfe10fe1acfe77433638ea4 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:19 +0000 Subject: [PATCH 0894/6849] netfilter: nf_ct_udplite: add namespace support This patch adds namespace support for UDPlite protocol tracker. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_udplite.c | 98 ++++++++++++++++++---- 1 file changed, 80 insertions(+), 18 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index fa142a81496c..7f85b0850a44 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -35,6 +35,17 @@ static unsigned int udplite_timeouts[UDPLITE_CT_MAX] = { [UDPLITE_CT_REPLIED] = 180*HZ, }; +static int udplite_net_id __read_mostly; +struct udplite_net { + struct nf_proto_net pn; + unsigned int timeouts[UDPLITE_CT_MAX]; +}; + +static inline struct udplite_net *udplite_pernet(struct net *net) +{ + return net_generic(net, udplite_net_id); +} + static bool udplite_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) @@ -70,7 +81,7 @@ static int udplite_print_tuple(struct seq_file *s, static unsigned int *udplite_get_timeouts(struct net *net) { - return udplite_timeouts; + return udplite_pernet(net)->timeouts; } /* Returns verdict for packet, and may modify conntracktype */ @@ -209,14 +220,12 @@ static struct ctl_table_header *udplite_sysctl_header; static struct ctl_table udplite_sysctl_table[] = { { .procname = "nf_conntrack_udplite_timeout", - .data = &udplite_timeouts[UDPLITE_CT_UNREPLIED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "nf_conntrack_udplite_timeout_stream", - .data = &udplite_timeouts[UDPLITE_CT_REPLIED], .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -225,6 +234,31 @@ static struct ctl_table udplite_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ +static int udplite_init_net(struct net *net) +{ + int i; + struct udplite_net *un = udplite_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)un; +#ifdef CONFIG_SYSCTL + if (!pn->ctl_table) { +#else + if (!pn->users++) { +#endif + for (i = 0 ; i < UDPLITE_CT_MAX; i++) + un->timeouts[i] = udplite_timeouts[i]; +#ifdef CONFIG_SYSCTL + pn->ctl_table = kmemdup(udplite_sysctl_table, + sizeof(udplite_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED]; + pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED]; +#endif + } + return 0; +} + static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = { .l3proto = PF_INET, @@ -258,6 +292,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = .ctl_table_header = &udplite_sysctl_header, .ctl_table = udplite_sysctl_table, #endif + .net_id = &udplite_net_id, + .init_net = udplite_init_net, }; static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = @@ -293,29 +329,55 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = .ctl_table_header = &udplite_sysctl_header, .ctl_table = udplite_sysctl_table, #endif + .net_id = &udplite_net_id, + .init_net = udplite_init_net, }; -static int __init nf_conntrack_proto_udplite_init(void) +static int udplite_net_init(struct net *net) { - int err; - - err = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udplite4); - if (err < 0) - goto err1; - err = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udplite6); - if (err < 0) - goto err2; + int ret = 0; + + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_udplite4); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n"); + goto out; + } + ret = nf_conntrack_l4proto_register(net, + &nf_conntrack_l4proto_udplite6); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n"); + goto cleanup_udplite4; + } return 0; -err2: - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite4); -err1: - return err; + +cleanup_udplite4: + nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4); +out: + return ret; +} + +static void udplite_net_exit(struct net *net) +{ + nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite6); + nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4); +} + +static struct pernet_operations udplite_net_ops = { + .init = udplite_net_init, + .exit = udplite_net_exit, + .id = &udplite_net_id, + .size = sizeof(struct udplite_net), +}; + +static int __init nf_conntrack_proto_udplite_init(void) +{ + return register_pernet_subsys(&udplite_net_ops); } static void __exit nf_conntrack_proto_udplite_exit(void) { - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite6); - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite4); + unregister_pernet_subsys(&udplite_net_ops); } module_init(nf_conntrack_proto_udplite_init); -- GitLab From 84c394511fd77df7afcfa0e051137f61b08e9636 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:20 +0000 Subject: [PATCH 0895/6849] netfilter: nf_ct_dccp: use new namespace support This patch modifies the DCCP protocol tracker to use the new namespace infrastructure for nf_conntrack. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_dccp.c | 132 ++++++++++++------------ 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index 5a8e03724289..8d798a613e3f 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -387,12 +387,9 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = /* this module per-net specifics */ static int dccp_net_id __read_mostly; struct dccp_net { + struct nf_proto_net np; int dccp_loose; unsigned int dccp_timeout[CT_DCCP_MAX + 1]; -#ifdef CONFIG_SYSCTL - struct ctl_table_header *sysctl_header; - struct ctl_table *sysctl_table; -#endif }; static inline struct dccp_net *dccp_pernet(struct net *net) @@ -817,6 +814,45 @@ static struct ctl_table dccp_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ +static int dccp_init_net(struct net *net) +{ + struct dccp_net *dn = dccp_pernet(net); + struct nf_proto_net *pn = (struct nf_proto_net *)dn; + +#ifdef CONFIG_SYSCTL + if (!pn->ctl_table) { +#else + if (!pn->users++) { +#endif + /* default values */ + dn->dccp_loose = 1; + dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL; + dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL; + dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL; + dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ; + dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ; + dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ; + dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL; +#ifdef CONFIG_SYSCTL + pn->ctl_table = kmemdup(dccp_sysctl_table, + sizeof(dccp_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + + pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; + pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; + pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; + pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; + pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; + pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; + pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; + pn->ctl_table[7].data = &dn->dccp_loose; +#endif + } + return 0; +} + static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { .l3proto = AF_INET, .l4proto = IPPROTO_DCCP, @@ -847,6 +883,8 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { .nla_policy = dccp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ + .net_id = &dccp_net_id, + .init_net = dccp_init_net, }; static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { @@ -879,55 +917,39 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { .nla_policy = dccp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ + .net_id = &dccp_net_id, + .init_net = dccp_init_net, }; static __net_init int dccp_net_init(struct net *net) { - struct dccp_net *dn = dccp_pernet(net); - - /* default values */ - dn->dccp_loose = 1; - dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL; - dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL; - dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL; - dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ; - dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ; - dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ; - dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL; - -#ifdef CONFIG_SYSCTL - dn->sysctl_table = kmemdup(dccp_sysctl_table, - sizeof(dccp_sysctl_table), GFP_KERNEL); - if (!dn->sysctl_table) - return -ENOMEM; - - dn->sysctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; - dn->sysctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; - dn->sysctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; - dn->sysctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; - dn->sysctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; - dn->sysctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; - dn->sysctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; - dn->sysctl_table[7].data = &dn->dccp_loose; - - dn->sysctl_header = register_net_sysctl(net, "net/netfilter", - dn->sysctl_table); - if (!dn->sysctl_header) { - kfree(dn->sysctl_table); - return -ENOMEM; + int ret = 0; + ret = nf_conntrack_l4proto_register(net, + &dccp_proto4); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_dccp4 :protocol register failed.\n"); + goto out; + } + ret = nf_conntrack_l4proto_register(net, + &dccp_proto6); + if (ret < 0) { + pr_err("nf_conntrack_l4proto_dccp6 :protocol register failed.\n"); + goto cleanup_dccp4; } -#endif - return 0; +cleanup_dccp4: + nf_conntrack_l4proto_unregister(net, + &dccp_proto4); +out: + return ret; } static __net_exit void dccp_net_exit(struct net *net) { - struct dccp_net *dn = dccp_pernet(net); -#ifdef CONFIG_SYSCTL - unregister_net_sysctl_table(dn->sysctl_header); - kfree(dn->sysctl_table); -#endif + nf_conntrack_l4proto_unregister(net, + &dccp_proto6); + nf_conntrack_l4proto_unregister(net, + &dccp_proto4); } static struct pernet_operations dccp_net_ops = { @@ -939,34 +961,12 @@ static struct pernet_operations dccp_net_ops = { static int __init nf_conntrack_proto_dccp_init(void) { - int err; - - err = register_pernet_subsys(&dccp_net_ops); - if (err < 0) - goto err1; - - err = nf_conntrack_l4proto_register(&init_net, &dccp_proto4); - if (err < 0) - goto err2; - - err = nf_conntrack_l4proto_register(&init_net, &dccp_proto6); - if (err < 0) - goto err3; - return 0; - -err3: - nf_conntrack_l4proto_unregister(&init_net, &dccp_proto4); -err2: - unregister_pernet_subsys(&dccp_net_ops); -err1: - return err; + return register_pernet_subsys(&dccp_net_ops); } static void __exit nf_conntrack_proto_dccp_fini(void) { unregister_pernet_subsys(&dccp_net_ops); - nf_conntrack_l4proto_unregister(&init_net, &dccp_proto6); - nf_conntrack_l4proto_unregister(&init_net, &dccp_proto4); } module_init(nf_conntrack_proto_dccp_init); -- GitLab From 4f71d80fc00a8c8859329ff282167fd4549b2b9f Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:21 +0000 Subject: [PATCH 0896/6849] netfilter: nf_ct_gre: use new namespace support This patch modifies the GRE protocol tracker, which partially supported namespace before this patch, to use the new namespace infrastructure for nf_conntrack. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_gre.c | 55 ++++++++++++++++---------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 132f0d2d82cc..e36973f9ef59 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -54,13 +54,20 @@ static unsigned int gre_timeouts[GRE_CT_MAX] = { static int proto_gre_net_id __read_mostly; struct netns_proto_gre { + struct nf_proto_net nf; rwlock_t keymap_lock; struct list_head keymap_list; + unsigned int gre_timeouts[GRE_CT_MAX]; }; +static inline struct netns_proto_gre *gre_pernet(struct net *net) +{ + return net_generic(net, proto_gre_net_id); +} + void nf_ct_gre_keymap_flush(struct net *net) { - struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); + struct netns_proto_gre *net_gre = gre_pernet(net); struct nf_ct_gre_keymap *km, *tmp; write_lock_bh(&net_gre->keymap_lock); @@ -85,7 +92,7 @@ static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km, /* look up the source key for a given tuple */ static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t) { - struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); + struct netns_proto_gre *net_gre = gre_pernet(net); struct nf_ct_gre_keymap *km; __be16 key = 0; @@ -109,7 +116,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, struct nf_conntrack_tuple *t) { struct net *net = nf_ct_net(ct); - struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); + struct netns_proto_gre *net_gre = gre_pernet(net); struct nf_conn_help *help = nfct_help(ct); struct nf_ct_gre_keymap **kmp, *km; @@ -150,7 +157,7 @@ EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add); void nf_ct_gre_keymap_destroy(struct nf_conn *ct) { struct net *net = nf_ct_net(ct); - struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); + struct netns_proto_gre *net_gre = gre_pernet(net); struct nf_conn_help *help = nfct_help(ct); enum ip_conntrack_dir dir; @@ -237,7 +244,7 @@ static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct) static unsigned int *gre_get_timeouts(struct net *net) { - return gre_timeouts; + return gre_pernet(net)->gre_timeouts; } /* Returns verdict for packet, and may modify conntrack */ @@ -339,6 +346,19 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = { }; #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ +static int gre_init_net(struct net *net) +{ + struct netns_proto_gre *net_gre = gre_pernet(net); + int i; + + rwlock_init(&net_gre->keymap_lock); + INIT_LIST_HEAD(&net_gre->keymap_list); + for (i = 0; i < GRE_CT_MAX; i++) + net_gre->gre_timeouts[i] = gre_timeouts[i]; + + return 0; +} + /* protocol helper struct */ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = { .l3proto = AF_INET, @@ -368,20 +388,22 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = { .nla_policy = gre_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ + .net_id = &proto_gre_net_id, + .init_net = gre_init_net, }; static int proto_gre_net_init(struct net *net) { - struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); - - rwlock_init(&net_gre->keymap_lock); - INIT_LIST_HEAD(&net_gre->keymap_list); - - return 0; + int ret = 0; + ret = nf_conntrack_l4proto_register(net, &nf_conntrack_l4proto_gre4); + if (ret < 0) + pr_err("nf_conntrack_l4proto_gre4 :protocol register failed.\n"); + return ret; } static void proto_gre_net_exit(struct net *net) { + nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_gre4); nf_ct_gre_keymap_flush(net); } @@ -394,20 +416,11 @@ static struct pernet_operations proto_gre_net_ops = { static int __init nf_ct_proto_gre_init(void) { - int rv; - - rv = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_gre4); - if (rv < 0) - return rv; - rv = register_pernet_subsys(&proto_gre_net_ops); - if (rv < 0) - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_gre4); - return rv; + return register_pernet_subsys(&proto_gre_net_ops); } static void __exit nf_ct_proto_gre_fini(void) { - nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_gre4); unregister_pernet_subsys(&proto_gre_net_ops); } -- GitLab From e76d0af5e45f4152e3fdcc103b753a8aff93fcb5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 5 Jun 2012 18:35:48 +0200 Subject: [PATCH 0897/6849] netfilter: nf_conntrack: remove now unused sysctl for nf_conntrack_l[3|4]proto Since the sysctl data for l[3|4]proto now resides in pernet nf_proto_net. We can now remove this unused fields from struct nf_contrack_l[3,4]proto. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_l3proto.h | 2 -- include/net/netfilter/nf_conntrack_l4proto.h | 10 ---------- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 1 - net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 8 -------- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 5 ----- net/netfilter/nf_conntrack_proto_generic.c | 8 -------- net/netfilter/nf_conntrack_proto_sctp.c | 15 --------------- net/netfilter/nf_conntrack_proto_tcp.c | 15 --------------- net/netfilter/nf_conntrack_proto_udp.c | 15 --------------- net/netfilter/nf_conntrack_proto_udplite.c | 12 ------------ 10 files changed, 91 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index d6df8c71a7fe..6f7c13f4ac03 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -64,9 +64,7 @@ struct nf_conntrack_l3proto { size_t nla_size; #ifdef CONFIG_SYSCTL - struct ctl_table_header *ctl_table_header; const char *ctl_table_path; - struct ctl_table *ctl_table; #endif /* CONFIG_SYSCTL */ /* Init l3proto pernet data */ diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index d621c91de5c8..cfa2f89b031d 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -93,16 +93,6 @@ struct nf_conntrack_l4proto { unsigned int nlattr_max; const struct nla_policy *nla_policy; } ctnl_timeout; -#endif - -#ifdef CONFIG_SYSCTL - struct ctl_table_header **ctl_table_header; - struct ctl_table *ctl_table; - unsigned int *ctl_table_users; -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - struct ctl_table_header *ctl_compat_table_header; - struct ctl_table *ctl_compat_table; -#endif #endif int *net_id; /* Init l4proto pernet data */ diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 5c66203af51c..d79b961a8009 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -380,7 +380,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { #endif #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) .ctl_table_path = "net/ipv4/netfilter", - .ctl_table = ip_ct_sysctl_table, #endif .init_net = ipv4_init_net, .me = THIS_MODULE, diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index a0eabeb36b9f..2bca7a5e422b 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -313,7 +313,6 @@ icmp_timeout_nla_policy[CTA_TIMEOUT_ICMP_MAX+1] = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #ifdef CONFIG_SYSCTL -static struct ctl_table_header *icmp_sysctl_header; static struct ctl_table icmp_sysctl_table[] = { { .procname = "nf_conntrack_icmp_timeout", @@ -393,12 +392,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = .nla_policy = icmp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_header = &icmp_sysctl_header, - .ctl_table = icmp_sysctl_table, -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - .ctl_compat_table = icmp_compat_sysctl_table, -#endif -#endif .init_net = icmp_init_net, }; diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index f606355200d8..1b7818f15f3d 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -320,7 +320,6 @@ icmpv6_timeout_nla_policy[CTA_TIMEOUT_ICMPV6_MAX+1] = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #ifdef CONFIG_SYSCTL -static struct ctl_table_header *icmpv6_sysctl_header; static struct ctl_table icmpv6_sysctl_table[] = { { .procname = "nf_conntrack_icmpv6_timeout", @@ -375,9 +374,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = .nla_policy = icmpv6_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_header = &icmpv6_sysctl_header, - .ctl_table = icmpv6_sysctl_table, -#endif .init_net = icmpv6_init_net, }; diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index 19bc880eb4e2..e4e2d2a38d3f 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -111,7 +111,6 @@ generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #ifdef CONFIG_SYSCTL -static struct ctl_table_header *generic_sysctl_header; static struct ctl_table generic_sysctl_table[] = { { .procname = "nf_conntrack_generic_timeout", @@ -182,12 +181,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = .nla_policy = generic_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_header = &generic_sysctl_header, - .ctl_table = generic_sysctl_table, -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - .ctl_compat_table = generic_compat_sysctl_table, -#endif -#endif .init_net = generic_init_net, }; diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 9e5738db34df..d785f2c4182b 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -610,8 +610,6 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = { #ifdef CONFIG_SYSCTL -static unsigned int sctp_sysctl_table_users; -static struct ctl_table_header *sctp_sysctl_header; static struct ctl_table sctp_sysctl_table[] = { { .procname = "nf_conntrack_sctp_timeout_closed", @@ -832,14 +830,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { .nla_policy = sctp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &sctp_sysctl_table_users, - .ctl_table_header = &sctp_sysctl_header, - .ctl_table = sctp_sysctl_table, -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - .ctl_compat_table = sctp_compat_sysctl_table, -#endif -#endif .net_id = &sctp_net_id, .init_net = sctpv4_init_net, }; @@ -873,11 +863,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { .nla_policy = sctp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#endif -#ifdef CONFIG_SYSCTL - .ctl_table_users = &sctp_sysctl_table_users, - .ctl_table_header = &sctp_sysctl_header, - .ctl_table = sctp_sysctl_table, #endif .net_id = &sctp_net_id, .init_net = sctpv6_init_net, diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index a053f6786b3c..e57f2a888dae 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1364,8 +1364,6 @@ static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #ifdef CONFIG_SYSCTL -static unsigned int tcp_sysctl_table_users; -static struct ctl_table_header *tcp_sysctl_header; static struct ctl_table tcp_sysctl_table[] = { { .procname = "nf_conntrack_tcp_timeout_syn_sent", @@ -1684,14 +1682,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = .nla_policy = tcp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &tcp_sysctl_table_users, - .ctl_table_header = &tcp_sysctl_header, - .ctl_table = tcp_sysctl_table, -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - .ctl_compat_table = tcp_compat_sysctl_table, -#endif -#endif .init_net = tcpv4_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4); @@ -1728,11 +1718,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly = .nla_policy = tcp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &tcp_sysctl_table_users, - .ctl_table_header = &tcp_sysctl_header, - .ctl_table = tcp_sysctl_table, -#endif .init_net = tcpv6_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6); diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index f56c8905ddfb..db7abad44bc5 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -199,8 +199,6 @@ udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #ifdef CONFIG_SYSCTL -static unsigned int udp_sysctl_table_users; -static struct ctl_table_header *udp_sysctl_header; static struct ctl_table udp_sysctl_table[] = { { .procname = "nf_conntrack_udp_timeout", @@ -343,14 +341,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = .nla_policy = udp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &udp_sysctl_table_users, - .ctl_table_header = &udp_sysctl_header, - .ctl_table = udp_sysctl_table, -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - .ctl_compat_table = udp_compat_sysctl_table, -#endif -#endif .init_net = udpv4_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4); @@ -382,11 +372,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly = .nla_policy = udp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &udp_sysctl_table_users, - .ctl_table_header = &udp_sysctl_header, - .ctl_table = udp_sysctl_table, -#endif .init_net = udpv6_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6); diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index 7f85b0850a44..2e25e985e8cf 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -215,8 +215,6 @@ udplite_timeout_nla_policy[CTA_TIMEOUT_UDPLITE_MAX+1] = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #ifdef CONFIG_SYSCTL -static unsigned int udplite_sysctl_table_users; -static struct ctl_table_header *udplite_sysctl_header; static struct ctl_table udplite_sysctl_table[] = { { .procname = "nf_conntrack_udplite_timeout", @@ -287,11 +285,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = .nla_policy = udplite_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &udplite_sysctl_table_users, - .ctl_table_header = &udplite_sysctl_header, - .ctl_table = udplite_sysctl_table, -#endif .net_id = &udplite_net_id, .init_net = udplite_init_net, }; @@ -324,11 +317,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = .nla_policy = udplite_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -#ifdef CONFIG_SYSCTL - .ctl_table_users = &udplite_sysctl_table_users, - .ctl_table_header = &udplite_sysctl_header, - .ctl_table = udplite_sysctl_table, -#endif .net_id = &udplite_net_id, .init_net = udplite_init_net, }; -- GitLab From 8264deb81853462da5cbcfb19b54c4fd9f3d88ba Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 28 May 2012 21:04:23 +0000 Subject: [PATCH 0898/6849] netfilter: nf_conntrack: add namespace support for cttimeout This patch adds namespace support for cttimeout. Acked-by: Eric W. Biederman Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_l4proto.h | 3 ++- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 6 ++++-- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 6 ++++-- net/netfilter/nf_conntrack_proto_dccp.c | 5 +++-- net/netfilter/nf_conntrack_proto_generic.c | 6 ++++-- net/netfilter/nf_conntrack_proto_gre.c | 8 +++++--- net/netfilter/nf_conntrack_proto_sctp.c | 6 ++++-- net/netfilter/nf_conntrack_proto_tcp.c | 6 ++++-- net/netfilter/nf_conntrack_proto_udp.c | 8 +++++--- net/netfilter/nf_conntrack_proto_udplite.c | 8 +++++--- net/netfilter/nfnetlink_cttimeout.c | 13 ++++++++----- 11 files changed, 48 insertions(+), 27 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index cfa2f89b031d..81c52b5205f2 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -87,7 +87,8 @@ struct nf_conntrack_l4proto { #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) struct { size_t obj_size; - int (*nlattr_to_obj)(struct nlattr *tb[], void *data); + int (*nlattr_to_obj)(struct nlattr *tb[], + struct net *net, void *data); int (*obj_to_nlattr)(struct sk_buff *skb, const void *data); unsigned int nlattr_max; diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 2bca7a5e422b..041923cb67ad 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -279,16 +279,18 @@ static int icmp_nlattr_tuple_size(void) #include #include -static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeout = data; + struct nf_icmp_net *in = icmp_pernet(net); if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) { *timeout = ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMP_TIMEOUT])) * HZ; } else { /* Set default ICMP timeout. */ - *timeout = nf_ct_icmp_timeout; + *timeout = in->timeout; } return 0; } diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 1b7818f15f3d..63ed0121836c 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -286,16 +286,18 @@ static int icmpv6_nlattr_tuple_size(void) #include #include -static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeout = data; + struct nf_icmp_net *in = icmpv6_pernet(net); if (tb[CTA_TIMEOUT_ICMPV6_TIMEOUT]) { *timeout = ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMPV6_TIMEOUT])) * HZ; } else { /* Set default ICMPv6 timeout. */ - *timeout = nf_ct_icmpv6_timeout; + *timeout = in->timeout; } return 0; } diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index 8d798a613e3f..c33f76af913f 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -712,9 +712,10 @@ static int dccp_nlattr_size(void) #include #include -static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { - struct dccp_net *dn = dccp_pernet(&init_net); + struct dccp_net *dn = dccp_pernet(net); unsigned int *timeouts = data; int i; diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index e4e2d2a38d3f..bb0e74fe0fae 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -75,16 +75,18 @@ static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb, #include #include -static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeout = data; + struct nf_generic_net *gn = generic_pernet(net); if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT]) *timeout = ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ; else { /* Set default generic timeout. */ - *timeout = nf_ct_generic_timeout; + *timeout = gn->timeout; } return 0; diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index e36973f9ef59..25ba5a2f5edc 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -304,13 +304,15 @@ static void gre_destroy(struct nf_conn *ct) #include #include -static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeouts = data; + struct netns_proto_gre *net_gre = gre_pernet(net); /* set default timeouts for GRE. */ - timeouts[GRE_CT_UNREPLIED] = gre_timeouts[GRE_CT_UNREPLIED]; - timeouts[GRE_CT_REPLIED] = gre_timeouts[GRE_CT_REPLIED]; + timeouts[GRE_CT_UNREPLIED] = net_gre->gre_timeouts[GRE_CT_UNREPLIED]; + timeouts[GRE_CT_REPLIED] = net_gre->gre_timeouts[GRE_CT_REPLIED]; if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) { timeouts[GRE_CT_UNREPLIED] = diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index d785f2c4182b..8fb0582ad397 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -562,14 +562,16 @@ static int sctp_nlattr_size(void) #include #include -static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeouts = data; + struct sctp_net *sn = sctp_pernet(net); int i; /* set default SCTP timeouts. */ for (i=0; itimeouts[i]; /* there's a 1:1 mapping between attributes and protocol states. */ for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i #include -static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeouts = data; + struct nf_tcp_net *tn = tcp_pernet(net); int i; /* set default TCP timeouts. */ for (i=0; itimeouts[i]; if (tb[CTA_TIMEOUT_TCP_SYN_SENT]) { timeouts[TCP_CONNTRACK_SYN_SENT] = diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index db7abad44bc5..360565a95de4 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -156,13 +156,15 @@ static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, #include #include -static int udp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int udp_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeouts = data; + struct nf_udp_net *un = udp_pernet(net); /* set default timeouts for UDP. */ - timeouts[UDP_CT_UNREPLIED] = udp_timeouts[UDP_CT_UNREPLIED]; - timeouts[UDP_CT_REPLIED] = udp_timeouts[UDP_CT_REPLIED]; + timeouts[UDP_CT_UNREPLIED] = un->timeouts[UDP_CT_UNREPLIED]; + timeouts[UDP_CT_REPLIED] = un->timeouts[UDP_CT_REPLIED]; if (tb[CTA_TIMEOUT_UDP_UNREPLIED]) { timeouts[UDP_CT_UNREPLIED] = diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index 2e25e985e8cf..b32e700f8dde 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -172,13 +172,15 @@ static int udplite_error(struct net *net, struct nf_conn *tmpl, #include #include -static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) +static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], + struct net *net, void *data) { unsigned int *timeouts = data; + struct udplite_net *un = udplite_pernet(net); /* set default timeouts for UDPlite. */ - timeouts[UDPLITE_CT_UNREPLIED] = udplite_timeouts[UDPLITE_CT_UNREPLIED]; - timeouts[UDPLITE_CT_REPLIED] = udplite_timeouts[UDPLITE_CT_REPLIED]; + timeouts[UDPLITE_CT_UNREPLIED] = un->timeouts[UDPLITE_CT_UNREPLIED]; + timeouts[UDPLITE_CT_REPLIED] = un->timeouts[UDPLITE_CT_REPLIED]; if (tb[CTA_TIMEOUT_UDPLITE_UNREPLIED]) { timeouts[UDPLITE_CT_UNREPLIED] = diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 3e655288d1d6..cdecbc8fe965 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -49,8 +49,9 @@ static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { static int ctnl_timeout_parse_policy(struct ctnl_timeout *timeout, - struct nf_conntrack_l4proto *l4proto, - const struct nlattr *attr) + struct nf_conntrack_l4proto *l4proto, + struct net *net, + const struct nlattr *attr) { int ret = 0; @@ -60,7 +61,8 @@ ctnl_timeout_parse_policy(struct ctnl_timeout *timeout, nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max, attr, l4proto->ctnl_timeout.nla_policy); - ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, &timeout->data); + ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, + &timeout->data); } return ret; } @@ -74,6 +76,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb, __u8 l4num; struct nf_conntrack_l4proto *l4proto; struct ctnl_timeout *timeout, *matching = NULL; + struct net *net = sock_net(skb->sk); char *name; int ret; @@ -117,7 +120,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb, goto err_proto_put; } - ret = ctnl_timeout_parse_policy(matching, l4proto, + ret = ctnl_timeout_parse_policy(matching, l4proto, net, cda[CTA_TIMEOUT_DATA]); return ret; } @@ -132,7 +135,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb, goto err_proto_put; } - ret = ctnl_timeout_parse_policy(timeout, l4proto, + ret = ctnl_timeout_parse_policy(timeout, l4proto, net, cda[CTA_TIMEOUT_DATA]); if (ret < 0) goto err; -- GitLab From 1da6dd07989869fa4f8ec1f47d610d12f96eb04d Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 4 Jun 2012 02:53:54 +0000 Subject: [PATCH 0899/6849] netfilter: NFQUEUE: don't xor src/dst ip address for load distribution because reply packets need to go to the same nfqueue, src/dst ip address were xor'd prior to jhash(). However, this causes bad distribution for some workloads, e.g. flows a.b.1.{1,n} -> a.b.2.{1,n} all share the same hash value. Avoid this by hashing both. To get same hash for replies, first argument is the smaller address. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/xt_NFQUEUE.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c index 95237c89607a..7babe7d68716 100644 --- a/net/netfilter/xt_NFQUEUE.c +++ b/net/netfilter/xt_NFQUEUE.c @@ -41,26 +41,36 @@ nfqueue_tg(struct sk_buff *skb, const struct xt_action_param *par) static u32 hash_v4(const struct sk_buff *skb) { const struct iphdr *iph = ip_hdr(skb); - __be32 ipaddr; /* packets in either direction go into same queue */ - ipaddr = iph->saddr ^ iph->daddr; + if (iph->saddr < iph->daddr) + return jhash_3words((__force u32)iph->saddr, + (__force u32)iph->daddr, iph->protocol, jhash_initval); - return jhash_2words((__force u32)ipaddr, iph->protocol, jhash_initval); + return jhash_3words((__force u32)iph->daddr, + (__force u32)iph->saddr, iph->protocol, jhash_initval); } #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) static u32 hash_v6(const struct sk_buff *skb) { const struct ipv6hdr *ip6h = ipv6_hdr(skb); - __be32 addr[4]; + u32 a, b, c; + + if (ip6h->saddr.s6_addr32[3] < ip6h->daddr.s6_addr32[3]) { + a = (__force u32) ip6h->saddr.s6_addr32[3]; + b = (__force u32) ip6h->daddr.s6_addr32[3]; + } else { + b = (__force u32) ip6h->saddr.s6_addr32[3]; + a = (__force u32) ip6h->daddr.s6_addr32[3]; + } - addr[0] = ip6h->saddr.s6_addr32[0] ^ ip6h->daddr.s6_addr32[0]; - addr[1] = ip6h->saddr.s6_addr32[1] ^ ip6h->daddr.s6_addr32[1]; - addr[2] = ip6h->saddr.s6_addr32[2] ^ ip6h->daddr.s6_addr32[2]; - addr[3] = ip6h->saddr.s6_addr32[3] ^ ip6h->daddr.s6_addr32[3]; + if (ip6h->saddr.s6_addr32[1] < ip6h->daddr.s6_addr32[1]) + c = (__force u32) ip6h->saddr.s6_addr32[1]; + else + c = (__force u32) ip6h->daddr.s6_addr32[1]; - return jhash2((__force u32 *)addr, ARRAY_SIZE(addr), jhash_initval); + return jhash_3words(a, b, c, jhash_initval); } #endif -- GitLab From efdedd5426a94b00d23483a1bcb4af3a91c894db Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Thu, 17 May 2012 23:08:57 +0300 Subject: [PATCH 0900/6849] netfilter: xt_recent: add address masking option The mask option allows you put all address belonging that mask into the same recent slot. This can be useful in case that recent is used to detect attacks from the same network segment. Tested for backward compatibility. Signed-off-by: Denys Fedoryshchenko Signed-off-by: Pablo Neira Ayuso --- Documentation/feature-removal-schedule.txt | 7 +++ include/linux/netfilter.h | 10 ++++ include/linux/netfilter/xt_recent.h | 10 ++++ net/netfilter/xt_recent.c | 62 ++++++++++++++++++---- 4 files changed, 80 insertions(+), 9 deletions(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 24ac00f4ae4b..bc4b9c6eb80e 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -574,6 +574,13 @@ Why: Remount currently allows changing bound subsystems and ---------------------------- +What: xt_recent rev 0 +When: 2013 +Who: Pablo Neira Ayuso +Files: net/netfilter/xt_recent.c + +---------------------------- + What: KVM debugfs statistics When: 2013 Why: KVM tracepoints provide mostly equivalent information in a much more diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index ff9c84c29b28..4541f33dbfc3 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -94,6 +94,16 @@ static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1, a1->all[3] == a2->all[3]; } +static inline void nf_inet_addr_mask(const union nf_inet_addr *a1, + union nf_inet_addr *result, + const union nf_inet_addr *mask) +{ + result->all[0] = a1->all[0] & mask->all[0]; + result->all[1] = a1->all[1] & mask->all[1]; + result->all[2] = a1->all[2] & mask->all[2]; + result->all[3] = a1->all[3] & mask->all[3]; +} + extern void netfilter_init(void); /* Largest hook number + 1 */ diff --git a/include/linux/netfilter/xt_recent.h b/include/linux/netfilter/xt_recent.h index 83318e01425e..6ef36c113e89 100644 --- a/include/linux/netfilter/xt_recent.h +++ b/include/linux/netfilter/xt_recent.h @@ -32,4 +32,14 @@ struct xt_recent_mtinfo { __u8 side; }; +struct xt_recent_mtinfo_v1 { + __u32 seconds; + __u32 hit_count; + __u8 check_set; + __u8 invert; + char name[XT_RECENT_NAME_LEN]; + __u8 side; + union nf_inet_addr mask; +}; + #endif /* _LINUX_NETFILTER_XT_RECENT_H */ diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index fc0d6dbe5d17..ae2ad1eec8d0 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -75,6 +75,7 @@ struct recent_entry { struct recent_table { struct list_head list; char name[XT_RECENT_NAME_LEN]; + union nf_inet_addr mask; unsigned int refcnt; unsigned int entries; struct list_head lru_list; @@ -228,10 +229,10 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = dev_net(par->in ? par->in : par->out); struct recent_net *recent_net = recent_pernet(net); - const struct xt_recent_mtinfo *info = par->matchinfo; + const struct xt_recent_mtinfo_v1 *info = par->matchinfo; struct recent_table *t; struct recent_entry *e; - union nf_inet_addr addr = {}; + union nf_inet_addr addr = {}, addr_mask; u_int8_t ttl; bool ret = info->invert; @@ -261,12 +262,15 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par) spin_lock_bh(&recent_lock); t = recent_table_lookup(recent_net, info->name); - e = recent_entry_lookup(t, &addr, par->family, + + nf_inet_addr_mask(&addr, &addr_mask, &t->mask); + + e = recent_entry_lookup(t, &addr_mask, par->family, (info->check_set & XT_RECENT_TTL) ? ttl : 0); if (e == NULL) { if (!(info->check_set & XT_RECENT_SET)) goto out; - e = recent_entry_init(t, &addr, par->family, ttl); + e = recent_entry_init(t, &addr_mask, par->family, ttl); if (e == NULL) par->hotdrop = true; ret = !ret; @@ -306,10 +310,10 @@ out: return ret; } -static int recent_mt_check(const struct xt_mtchk_param *par) +static int recent_mt_check(const struct xt_mtchk_param *par, + const struct xt_recent_mtinfo_v1 *info) { struct recent_net *recent_net = recent_pernet(par->net); - const struct xt_recent_mtinfo *info = par->matchinfo; struct recent_table *t; #ifdef CONFIG_PROC_FS struct proc_dir_entry *pde; @@ -361,6 +365,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par) goto out; } t->refcnt = 1; + + memcpy(&t->mask, &info->mask, sizeof(t->mask)); strcpy(t->name, info->name); INIT_LIST_HEAD(&t->lru_list); for (i = 0; i < ip_list_hash_size; i++) @@ -385,10 +391,28 @@ out: return ret; } +static int recent_mt_check_v0(const struct xt_mtchk_param *par) +{ + const struct xt_recent_mtinfo_v0 *info_v0 = par->matchinfo; + struct xt_recent_mtinfo_v1 info_v1; + + /* Copy revision 0 structure to revision 1 */ + memcpy(&info_v1, info_v0, sizeof(struct xt_recent_mtinfo)); + /* Set default mask to ensure backward compatible behaviour */ + memset(info_v1.mask.all, 0xFF, sizeof(info_v1.mask.all)); + + return recent_mt_check(par, &info_v1); +} + +static int recent_mt_check_v1(const struct xt_mtchk_param *par) +{ + return recent_mt_check(par, par->matchinfo); +} + static void recent_mt_destroy(const struct xt_mtdtor_param *par) { struct recent_net *recent_net = recent_pernet(par->net); - const struct xt_recent_mtinfo *info = par->matchinfo; + const struct xt_recent_mtinfo_v1 *info = par->matchinfo; struct recent_table *t; mutex_lock(&recent_mutex); @@ -625,7 +649,7 @@ static struct xt_match recent_mt_reg[] __read_mostly = { .family = NFPROTO_IPV4, .match = recent_mt, .matchsize = sizeof(struct xt_recent_mtinfo), - .checkentry = recent_mt_check, + .checkentry = recent_mt_check_v0, .destroy = recent_mt_destroy, .me = THIS_MODULE, }, @@ -635,10 +659,30 @@ static struct xt_match recent_mt_reg[] __read_mostly = { .family = NFPROTO_IPV6, .match = recent_mt, .matchsize = sizeof(struct xt_recent_mtinfo), - .checkentry = recent_mt_check, + .checkentry = recent_mt_check_v0, + .destroy = recent_mt_destroy, + .me = THIS_MODULE, + }, + { + .name = "recent", + .revision = 1, + .family = NFPROTO_IPV4, + .match = recent_mt, + .matchsize = sizeof(struct xt_recent_mtinfo_v1), + .checkentry = recent_mt_check_v1, .destroy = recent_mt_destroy, .me = THIS_MODULE, }, + { + .name = "recent", + .revision = 1, + .family = NFPROTO_IPV6, + .match = recent_mt, + .matchsize = sizeof(struct xt_recent_mtinfo_v1), + .checkentry = recent_mt_check_v1, + .destroy = recent_mt_destroy, + .me = THIS_MODULE, + } }; static int __init recent_mt_init(void) -- GitLab From 3d33bf2bd83b27707f4bd31ba988bd4d4b92c7ad Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 14 May 2012 03:56:35 +0000 Subject: [PATCH 0901/6849] netfilter: decnet: switch hook PFs to nfproto This patch is a cleanup. Use NFPROTO_* for consistency with other netfilter code. Signed-off-by: Alban Crequy Reviewed-by: Javier Martinez Canillas Reviewed-by: Vincent Sanders Signed-off-by: Pablo Neira Ayuso --- net/decnet/netfilter/dn_rtmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index 44b890936fc0..e6f886255cde 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -117,7 +117,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) static struct nf_hook_ops dnrmg_ops __read_mostly = { .hook = dnrmg_hook, - .pf = PF_DECnet, + .pf = NFPROTO_DECNET, .hooknum = NF_DN_ROUTE, .priority = NF_DN_PRI_DNRTMSG, }; -- GitLab From aa740f46fbf3b1121a25d77c019e1ed3cc1260db Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 14 May 2012 03:56:36 +0000 Subject: [PATCH 0902/6849] netfilter: bridge: switch hook PFs to nfproto This patch is a cleanup. Use NFPROTO_* for consistency with other netfilter code. Signed-off-by: Alban Crequy Reviewed-by: Javier Martinez Canillas Reviewed-by: Vincent Sanders Signed-off-by: Pablo Neira Ayuso --- net/bridge/br_netfilter.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index e41456bd3cc6..20fa719889ee 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -764,9 +764,9 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, return NF_DROP; if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) - pf = PF_INET; + pf = NFPROTO_IPV4; else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) - pf = PF_INET6; + pf = NFPROTO_IPV6; else return NF_ACCEPT; @@ -778,13 +778,13 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, nf_bridge->mask |= BRNF_PKT_TYPE; } - if (pf == PF_INET && br_parse_ip_options(skb)) + if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb)) return NF_DROP; /* The physdev module checks on this */ nf_bridge->mask |= BRNF_BRIDGED; nf_bridge->physoutdev = skb->dev; - if (pf == PF_INET) + if (pf == NFPROTO_IPV4) skb->protocol = htons(ETH_P_IP); else skb->protocol = htons(ETH_P_IPV6); @@ -871,9 +871,9 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, return NF_DROP; if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) - pf = PF_INET; + pf = NFPROTO_IPV4; else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) - pf = PF_INET6; + pf = NFPROTO_IPV6; else return NF_ACCEPT; @@ -886,7 +886,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, nf_bridge_pull_encap_header(skb); nf_bridge_save_header(skb); - if (pf == PF_INET) + if (pf == NFPROTO_IPV4) skb->protocol = htons(ETH_P_IP); else skb->protocol = htons(ETH_P_IPV6); @@ -919,49 +919,49 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { { .hook = br_nf_pre_routing, .owner = THIS_MODULE, - .pf = PF_BRIDGE, + .pf = NFPROTO_BRIDGE, .hooknum = NF_BR_PRE_ROUTING, .priority = NF_BR_PRI_BRNF, }, { .hook = br_nf_local_in, .owner = THIS_MODULE, - .pf = PF_BRIDGE, + .pf = NFPROTO_BRIDGE, .hooknum = NF_BR_LOCAL_IN, .priority = NF_BR_PRI_BRNF, }, { .hook = br_nf_forward_ip, .owner = THIS_MODULE, - .pf = PF_BRIDGE, + .pf = NFPROTO_BRIDGE, .hooknum = NF_BR_FORWARD, .priority = NF_BR_PRI_BRNF - 1, }, { .hook = br_nf_forward_arp, .owner = THIS_MODULE, - .pf = PF_BRIDGE, + .pf = NFPROTO_BRIDGE, .hooknum = NF_BR_FORWARD, .priority = NF_BR_PRI_BRNF, }, { .hook = br_nf_post_routing, .owner = THIS_MODULE, - .pf = PF_BRIDGE, + .pf = NFPROTO_BRIDGE, .hooknum = NF_BR_POST_ROUTING, .priority = NF_BR_PRI_LAST, }, { .hook = ip_sabotage_in, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP_PRI_FIRST, }, { .hook = ip_sabotage_in, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP6_PRI_FIRST, }, -- GitLab From 89a48e35f54aebe83133d5ce450f0ced6551b5b8 Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 14 May 2012 03:56:37 +0000 Subject: [PATCH 0903/6849] netfilter: ipv4, defrag: switch hook PFs to nfproto This patch is a cleanup. Use NFPROTO_* for consistency with other netfilter code. Signed-off-by: Alban Crequy Reviewed-by: Javier Martinez Canillas Reviewed-by: Vincent Sanders --- net/ipv4/netfilter/nf_defrag_ipv4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index 9bb1b8a37a22..742815518b0f 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c @@ -94,14 +94,14 @@ static struct nf_hook_ops ipv4_defrag_ops[] = { { .hook = ipv4_conntrack_defrag, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP_PRI_CONNTRACK_DEFRAG, }, { .hook = ipv4_conntrack_defrag, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_CONNTRACK_DEFRAG, }, -- GitLab From 4c809d630c17af0e8112d5362367ced9b44b009b Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 14 May 2012 03:56:38 +0000 Subject: [PATCH 0904/6849] netfilter: ipvs: switch hook PFs to nfproto This patch is a cleanup. Use NFPROTO_* for consistency with other netfilter code. Signed-off-by: Alban Crequy Reviewed-by: Javier Martinez Canillas Reviewed-by: Vincent Sanders Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipvs/ip_vs_core.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index a54b018c6eea..b54eccef40b5 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -1742,7 +1742,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_reply4, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_NAT_SRC - 2, }, @@ -1752,7 +1752,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_remote_request4, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_NAT_SRC - 1, }, @@ -1760,7 +1760,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_local_reply4, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_NAT_DST + 1, }, @@ -1768,7 +1768,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_local_request4, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_NAT_DST + 2, }, @@ -1777,7 +1777,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_forward_icmp, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_FORWARD, .priority = 99, }, @@ -1785,7 +1785,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_reply4, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_FORWARD, .priority = 100, }, @@ -1794,7 +1794,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_reply6, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP6_PRI_NAT_SRC - 2, }, @@ -1804,7 +1804,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_remote_request6, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP6_PRI_NAT_SRC - 1, }, @@ -1812,7 +1812,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_local_reply6, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_NAT_DST + 1, }, @@ -1820,7 +1820,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_local_request6, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_NAT_DST + 2, }, @@ -1829,7 +1829,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_forward_icmp_v6, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_FORWARD, .priority = 99, }, @@ -1837,7 +1837,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { { .hook = ip_vs_reply6, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_FORWARD, .priority = 100, }, -- GitLab From 2597a8344ce051d0afe331706bcb4660bbdb9861 Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 14 May 2012 03:56:39 +0000 Subject: [PATCH 0905/6849] netfilter: selinux: switch hook PFs to nfproto This patch is a cleanup. Use NFPROTO_* for consistency with other netfilter code. Signed-off-by: Alban Crequy Reviewed-by: Javier Martinez Canillas Reviewed-by: Vincent Sanders Signed-off-by: Pablo Neira Ayuso --- security/selinux/hooks.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 372ec6502aa8..4ee6f2370016 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5763,21 +5763,21 @@ static struct nf_hook_ops selinux_ipv4_ops[] = { { .hook = selinux_ipv4_postroute, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_POST_ROUTING, .priority = NF_IP_PRI_SELINUX_LAST, }, { .hook = selinux_ipv4_forward, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_FORWARD, .priority = NF_IP_PRI_SELINUX_FIRST, }, { .hook = selinux_ipv4_output, .owner = THIS_MODULE, - .pf = PF_INET, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_SELINUX_FIRST, } @@ -5789,14 +5789,14 @@ static struct nf_hook_ops selinux_ipv6_ops[] = { { .hook = selinux_ipv6_postroute, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_POST_ROUTING, .priority = NF_IP6_PRI_SELINUX_LAST, }, { .hook = selinux_ipv6_forward, .owner = THIS_MODULE, - .pf = PF_INET6, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_FORWARD, .priority = NF_IP6_PRI_SELINUX_FIRST, } -- GitLab From aa29cab3f12b14020011bcad28cc11f50725d68f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 20 May 2012 14:11:24 -0300 Subject: [PATCH 0906/6849] ARM: mx31: Add pinctrl_provide_dummies() commit a2aa65a (ARM: imx: enable pinctrl dummy states) missed to add pinctrl_provide_dummies() for mx31. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mm-imx3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 967ed5b35a45..0b211f63981f 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -179,6 +179,8 @@ void __init imx31_soc_init(void) mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); + pinctrl_provide_dummies(); + if (to_version == 1) { strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin", strlen(imx31_sdma_pdata.fw_name)); -- GitLab From eb5558dd46dab1e3023f052f99979b0e2bfd1b19 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 20 May 2012 14:21:09 -0300 Subject: [PATCH 0907/6849] ARM: mx51: Add pinctrl_provide_dummies() commit a2aa65a (ARM: imx: enable pinctrl dummy states) missed to add pinctrl_provide_dummies() for mx51. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mm-imx5.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index feeee17da96b..1d003053d562 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -202,6 +202,8 @@ void __init imx51_soc_init(void) mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); + pinctrl_provide_dummies(); + /* i.mx51 has the i.mx35 type sdma */ imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); -- GitLab From 602bf40971d7f9a1ec0b7ba2b7e6427849828651 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 22 May 2012 22:13:46 +0800 Subject: [PATCH 0908/6849] ARM: imx6: exit coherency when shutting down a cpu There is a system hang issue on imx6q which can easily be seen with running a cpu hotplug stress testing (hotplug secondary cores from user space via sysfs interface for thousands iterations). It turns out that the issue is caused by coherency of the cpu that is being shut down. When shutting down a cpu, we need to have the cpu exit coherency to prevent it from receiving cache, TLB, or BTB maintenance operations broadcast by other CPUs in the cluster. Copy cpu_enter_lowpower() and cpu_leave_lowpower() from mach-vexpress to have coherency properly handled in platform_cpu_die(), thus fix the issue. Signed-off-by: Shawn Guo Cc: stable@kernel.org --- arch/arm/mach-imx/hotplug.c | 42 ++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 89493abd497c..20ed2d56c1af 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -12,6 +12,7 @@ #include #include +#include #include int platform_cpu_kill(unsigned int cpu) @@ -19,6 +20,44 @@ int platform_cpu_kill(unsigned int cpu) return 1; } +static inline void cpu_enter_lowpower(void) +{ + unsigned int v; + + flush_cache_all(); + asm volatile( + "mcr p15, 0, %1, c7, c5, 0\n" + " mcr p15, 0, %1, c7, c10, 4\n" + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %3\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0), "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} + +static inline void cpu_leave_lowpower(void) +{ + unsigned int v; + + asm volatile( + "mrc p15, 0, %0, c1, c0, 0\n" + " orr %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + " mrc p15, 0, %0, c1, c0, 1\n" + " orr %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} + /* * platform-specific code to shutdown a CPU * @@ -26,9 +65,10 @@ int platform_cpu_kill(unsigned int cpu) */ void platform_cpu_die(unsigned int cpu) { - flush_cache_all(); + cpu_enter_lowpower(); imx_enable_cpu(cpu, false); cpu_do_idle(); + cpu_leave_lowpower(); /* We should never return from idle */ panic("cpu %d unexpectedly exit from shutdown\n", cpu); -- GitLab From 7fbb98c5cb07563d3ee08714073a8e5452a96be2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 7 Jun 2012 10:21:21 -0400 Subject: [PATCH 0909/6849] x86: Save cr2 in NMI in case NMIs take a page fault Avi Kivity reported that page faults in NMIs could cause havic if the NMI preempted another page fault handler: The recent changes to NMI allow exceptions to take place in NMI handlers, but I think that a #PF (say, due to access to vmalloc space) is still problematic. Consider the sequence #PF (cr2 set by processor) NMI ... #PF (cr2 clobbered) do_page_fault() IRET ... IRET do_page_fault() address = read_cr2() The last line reads the overwritten cr2 value. Originally I wrote a patch to solve this by saving the cr2 on the stack. Brian Gerst suggested to save it in the r12 register as both r12 and rbx are saved by the do_nmi handler as required by the C standard. But rbx is already used for saving if swapgs needs to be run on exit of the NMI handler. Link: http://lkml.kernel.org/r/4FBB8C40.6080304@redhat.com Link: http://lkml.kernel.org/r/1337763411.13348.140.camel@gandalf.stny.rr.com Reported-by: Avi Kivity Cc: Linus Torvalds Cc: H. Peter Anvin Cc: Thomas Gleixner Suggested-by: Brian Gerst Signed-off-by: Steven Rostedt --- arch/x86/kernel/entry_64.S | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 7d65133b51be..111f6bbd8b38 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1758,10 +1758,30 @@ end_repeat_nmi: */ call save_paranoid DEFAULT_FRAME 0 + + /* + * Save off the CR2 register. If we take a page fault in the NMI then + * it could corrupt the CR2 value. If the NMI preempts a page fault + * handler before it was able to read the CR2 register, and then the + * NMI itself takes a page fault, the page fault that was preempted + * will read the information from the NMI page fault and not the + * origin fault. Save it off and restore it if it changes. + * Use the r12 callee-saved register. + */ + movq %cr2, %r12 + /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi movq $-1,%rsi call do_nmi + + /* Did the NMI take a page fault? Restore cr2 if it did */ + movq %cr2, %rcx + cmpq %rcx, %r12 + je 1f + movq %r12, %cr2 +1: + testl %ebx,%ebx /* swapgs needed? */ jnz nmi_restore nmi_swapgs: -- GitLab From 4085f641e704b1ff1a60f62756f49281a181f707 Mon Sep 17 00:00:00 2001 From: Ido Reis Date: Sun, 13 May 2012 15:27:17 +0300 Subject: [PATCH 0910/6849] wl18xx: fix PHY_INIT addresses mem size was hardcoded 252, now uses the parameters struct size. Signed-off-by: Ido Reis Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index c8d45f011c63..e030b1297a2b 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -540,8 +540,8 @@ static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { .mem3 = { .start = 0x00000000, .size = 0x00000000 }, }, [PART_PHY_INIT] = { - /* TODO: use the phy_conf struct size here */ - .mem = { .start = 0x80926000, .size = 252 }, + .mem = { .start = 0x80926000, + .size = sizeof(struct wl18xx_mac_and_phy_params) }, .reg = { .start = 0x00000000, .size = 0x00000000 }, .mem2 = { .start = 0x00000000, .size = 0x00000000 }, .mem3 = { .start = 0x00000000, .size = 0x00000000 }, -- GitLab From 73395a79df00c3e0101bd7a0229dbbcc065b606a Mon Sep 17 00:00:00 2001 From: Ido Reis Date: Sun, 22 Apr 2012 20:45:52 +0300 Subject: [PATCH 0911/6849] wl18xx: support PG2 version of the chip PG2 has a unique chip id. It supports similar HW quirks. Signed-off-by: Ido Reis Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 12 +++++++++++- drivers/net/wireless/ti/wl18xx/reg.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index e030b1297a2b..57b4a1089d0d 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -588,6 +588,17 @@ static int wl18xx_identify_chip(struct wl1271 *wl) int ret = 0; switch (wl->chip.id) { + case CHIP_ID_185x_PG20: + wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)", + wl->chip.id); + wl->sr_fw_name = WL18XX_FW_NAME; + /* wl18xx uses the same firmware for PLT */ + wl->plt_fw_name = WL18XX_FW_NAME; + wl->quirks |= WLCORE_QUIRK_NO_ELP | + WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | + WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; + + break; case CHIP_ID_185x_PG10: wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", wl->chip.id); @@ -602,7 +613,6 @@ static int wl18xx_identify_chip(struct wl1271 *wl) /* PG 1.0 has some problems with MCS_13, so disable it */ wl->ht_cap[IEEE80211_BAND_2GHZ].mcs.rx_mask[1] &= ~BIT(5); - /* TODO: need to blocksize alignment for RX/TX separately? */ break; default: wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index 43863d35feb2..e81f60913e88 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -140,6 +140,7 @@ #define WL18XX_FW_STATUS_ADDR 0x50F8 #define CHIP_ID_185x_PG10 (0x06030101) +#define CHIP_ID_185x_PG20 (0x06030111) /* * Host Command Interrupt. Setting this bit masks -- GitLab From 16ea4733210d741eeb5413acd261e675a12f980e Mon Sep 17 00:00:00 2001 From: Ido Reis Date: Mon, 23 Apr 2012 16:49:19 +0300 Subject: [PATCH 0912/6849] wl18xx: FW/PHY arguments added for PG2 PG2 requires 4 new parameters that to be passed to the PHY. Use the actual PHY initialization struct size for the mem size of the PHY_INIT section, to account for additions in params. [Make sure PG1 still gets the original struct - Arik] Signed-off-by: Ido Reis Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/conf.h | 4 ++++ drivers/net/wireless/ti/wl18xx/main.c | 19 ++++++++++++++++++- drivers/net/wireless/ti/wl18xx/reg.h | 6 ++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index ffad302b6cb7..4e0f189b2539 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -44,6 +44,10 @@ struct wl18xx_conf_phy { u8 clock_valid_on_wake_up; u8 secondary_clock_setting_time; u8 pwr_limit_reference_11_abg; + u8 psat; + s8 low_power_val; + s8 med_power_val; + s8 high_power_val; }; struct wl18xx_priv_conf { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 57b4a1089d0d..bdf4ee12914d 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -511,6 +511,10 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .enable_tx_low_pwr_on_siso_rdl = 0x00, .rx_profile = 0x00, .pwr_limit_reference_11_abg = 0xc8, + .psat = 0, + .low_power_val = 0x00, + .med_power_val = 0x0a, + .high_power_val = 0x1e, }, }; @@ -713,6 +717,7 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) struct wl18xx_priv *priv = wl->priv; struct wl18xx_conf_phy *phy = &priv->conf.phy; struct wl18xx_mac_and_phy_params params; + size_t len; memset(¶ms, 0, sizeof(params)); @@ -752,9 +757,21 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) params.board_type = priv->board_type; + /* for PG2 only */ + params.psat = phy->psat; + params.low_power_val = phy->low_power_val; + params.med_power_val = phy->med_power_val; + params.high_power_val = phy->high_power_val; + + /* the parameters struct is smaller for PG1 */ + if (wl->chip.id == CHIP_ID_185x_PG10) + len = offsetof(struct wl18xx_mac_and_phy_params, psat) + 1; + else + len = sizeof(params); + wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)¶ms, - sizeof(params), false); + len, false); } static void wl18xx_enable_interrupts(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index e81f60913e88..a824b26702a8 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -236,6 +236,12 @@ struct wl18xx_mac_and_phy_params { u8 clock_valid_on_wake_up; u8 secondary_clock_setting_time; u8 board_type; + /* enable point saturation */ + u8 psat; + /* low/medium/high Tx power in dBm */ + s8 low_power_val; + s8 med_power_val; + s8 high_power_val; u8 padding[1]; } __packed; -- GitLab From f5755fe96cb010031a50458e6d1391377d94c275 Mon Sep 17 00:00:00 2001 From: Ido Reis Date: Mon, 23 Apr 2012 17:35:25 +0300 Subject: [PATCH 0913/6849] wl18xx: PG2.0 HW Watch dog interrupt support In PG2, the HW watchdog interrupt occupies bit0 of the event vector, and the SW watchdog is relocated to bit9. We perform the relocation globally, as there's only one watchdog bit on previous platforms (bit0). [Only mask in the new bit9 for platforms supporting it. This avoids spurious events on other platforms - Arik] Signed-off-by: Orit Brayer Signed-off-by: Ido Reis Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/acx.h | 14 ++++++++++++++ drivers/net/wireless/ti/wl12xx/main.c | 4 ++-- drivers/net/wireless/ti/wl18xx/acx.h | 20 ++++++++++++++++++++ drivers/net/wireless/ti/wl18xx/main.c | 14 ++++++++++++-- drivers/net/wireless/ti/wlcore/acx.h | 27 ++++++++++++--------------- drivers/net/wireless/ti/wlcore/main.c | 13 +++++++++++-- 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/acx.h b/drivers/net/wireless/ti/wl12xx/acx.h index 1be0f2d31b19..2a26868b837d 100644 --- a/drivers/net/wireless/ti/wl12xx/acx.h +++ b/drivers/net/wireless/ti/wl12xx/acx.h @@ -26,6 +26,20 @@ #include "../wlcore/wlcore.h" #include "../wlcore/acx.h" +#define WL12XX_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_INIT_COMPLETE | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_CMD_COMPLETE | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +#define WL12XX_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + struct wl1271_acx_host_config_bitmap { struct acx_header header; diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 41017baaf253..f74d76c95a7f 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1034,11 +1034,11 @@ static void wl12xx_pre_upload(struct wl1271 *wl) static void wl12xx_enable_interrupts(struct wl1271 *wl) { - wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); + wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL12XX_ACX_ALL_EVENTS_VECTOR); wlcore_enable_interrupts(wl); wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); + WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); } diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index cb6fd85d077f..7d74b031f114 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -28,6 +28,26 @@ /* numbers of bits the length field takes (add 1 for the actual number) */ #define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 +#define WL18XX_ACX_EVENTS_VECTOR_PG1 (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_INIT_COMPLETE | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_CMD_COMPLETE | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +#define WL18XX_ACX_EVENTS_VECTOR_PG2 (WL18XX_ACX_EVENTS_VECTOR_PG1 | \ + WL1271_ACX_SW_INTR_WATCHDOG) + +#define WL18XX_INTR_MASK_PG1 (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +#define WL18XX_INTR_MASK_PG2 (WL18XX_INTR_MASK_PG1 | \ + WL1271_ACX_SW_INTR_WATCHDOG) + struct wl18xx_acx_host_config_bitmap { struct acx_header header; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index bdf4ee12914d..84f8e27c29ab 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -776,11 +776,21 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) static void wl18xx_enable_interrupts(struct wl1271 *wl) { - wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); + u32 event_mask, intr_mask; + + if (wl->chip.id == CHIP_ID_185x_PG10) { + event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1; + intr_mask = WL18XX_INTR_MASK_PG1; + } else { + event_mask = WL18XX_ACX_EVENTS_VECTOR_PG2; + intr_mask = WL18XX_INTR_MASK_PG2; + } + + wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); wlcore_enable_interrupts(wl); wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); + WL1271_ACX_INTR_ALL & ~intr_mask); } static int wl18xx_boot(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 46c300d4dea4..c0181258b722 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -51,21 +51,18 @@ #define WL1271_ACX_INTR_TRACE_A BIT(7) /* Trace message on MBOX #B */ #define WL1271_ACX_INTR_TRACE_B BIT(8) - -#define WL1271_ACX_INTR_ALL 0xFFFFFFFF -#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_INIT_COMPLETE | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_CMD_COMPLETE | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) +/* SW FW Initiated interrupt Watchdog timer expiration */ +#define WL1271_ACX_SW_INTR_WATCHDOG BIT(9) + +#define WL1271_ACX_INTR_ALL 0xFFFFFFFF + +/* all possible interrupts - only appropriate ones will be masked in */ +#define WLCORE_ALL_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA | \ + WL1271_ACX_SW_INTR_WATCHDOG) /* Target's information element */ struct acx_header { diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 8800a63539e3..176a3117889b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -535,14 +535,23 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) wlcore_hw_tx_immediate_compl(wl); intr = le32_to_cpu(wl->fw_status_1->intr); - intr &= WL1271_INTR_MASK; + intr &= WLCORE_ALL_INTR_MASK; if (!intr) { done = true; continue; } if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { - wl1271_error("watchdog interrupt received! " + wl1271_error("HW watchdog interrupt received! starting recovery."); + wl->watchdog_recovery = true; + wl12xx_queue_recovery_work(wl); + + /* restarting the chip. ignore any other interrupt. */ + goto out; + } + + if (unlikely(intr & WL1271_ACX_SW_INTR_WATCHDOG)) { + wl1271_error("SW watchdog interrupt received! " "starting recovery."); wl->watchdog_recovery = true; wl12xx_queue_recovery_work(wl); -- GitLab From 9fccc82e19db0d63741cd6c3d2a8829fc8854406 Mon Sep 17 00:00:00 2001 From: Ido Reis Date: Sun, 13 May 2012 14:53:40 +0300 Subject: [PATCH 0914/6849] wl18xx: pad only last frame in aggregration buffer for PG2 In PG2 only the last frame in the aggregate buffer should be aligned to the sdio block size. This frame's header msb should be set to 0, while in all the previous frames in the aggregation buffer, this bit should be set to 1. [Add a HW op for setting the frame ctrl bit only for 18xx. Other minor cleanups - Arik] [Make the pre_pkt_send operation optional -- Luca] Signed-off-by: Ido Reis Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 1 + drivers/net/wireless/ti/wl18xx/main.c | 30 +++++++++++++++++++++++-- drivers/net/wireless/ti/wl18xx/tx.h | 3 +++ drivers/net/wireless/ti/wlcore/hw_ops.h | 9 ++++++++ drivers/net/wireless/ti/wlcore/tx.c | 16 ++++++++----- drivers/net/wireless/ti/wlcore/tx.h | 4 ++-- drivers/net/wireless/ti/wlcore/wlcore.h | 4 ++++ 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index f74d76c95a7f..364fb2feffce 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1406,6 +1406,7 @@ static struct wlcore_ops wl12xx_ops = { .debugfs_init = wl12xx_debugfs_add_files, .get_spare_blocks = wl12xx_get_spare_blocks, .set_key = wl12xx_set_key, + .pre_pkt_send = NULL, }; static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 84f8e27c29ab..fd02795f830c 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -600,7 +600,8 @@ static int wl18xx_identify_chip(struct wl1271 *wl) wl->plt_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | - WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; + WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | + WLCORE_QUIRK_TX_PAD_LAST_FRAME; break; case CHIP_ID_185x_PG10: @@ -847,7 +848,6 @@ wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, u32 blks, u32 spare_blks) { desc->wl18xx_mem.total_mem_blocks = blks; - desc->wl18xx_mem.reserved = 0; } static void @@ -856,6 +856,12 @@ wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, { desc->length = cpu_to_le16(skb->len); + /* if only the last frame is to be padded, we unset this bit on Tx */ + if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) + desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED; + else + desc->wl18xx_mem.ctrl = 0; + wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " "len: %d life: %d mem: %d", desc->hlid, le16_to_cpu(desc->length), @@ -1152,6 +1158,25 @@ out: return ret; } +static u32 wl18xx_pre_pkt_send(struct wl1271 *wl, + u32 buf_offset, u32 last_len) +{ + if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) { + struct wl1271_tx_hw_descr *last_desc; + + /* get the last TX HW descriptor written to the aggr buf */ + last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf + + buf_offset - last_len); + + /* the last frame is padded up to an SDIO block */ + last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED; + return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE); + } + + /* no modifications */ + return buf_offset; +} + static struct wlcore_ops wl18xx_ops = { .identify_chip = wl18xx_identify_chip, .boot = wl18xx_boot, @@ -1176,6 +1201,7 @@ static struct wlcore_ops wl18xx_ops = { .handle_static_data = wl18xx_handle_static_data, .get_spare_blocks = wl18xx_get_spare_blocks, .set_key = wl18xx_set_key, + .pre_pkt_send = wl18xx_pre_pkt_send, }; /* HT cap appropriate for wide channels */ diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h index 8aecaf09da9c..ccddc548e44a 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.h +++ b/drivers/net/wireless/ti/wl18xx/tx.h @@ -32,6 +32,9 @@ #define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F #define WL18XX_TX_STATUS_STAT_BIT_IDX 7 +/* Indicates this TX HW frame is not padded to SDIO block size */ +#define WL18XX_TX_CTRL_NOT_PADDED BIT(7) + /* * The FW uses a special bit to indicate a wide channel should be used in * the rate policy. diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 34e0498727fc..9e7787ba9610 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -188,4 +188,13 @@ wlcore_hw_set_key(struct wl1271 *wl, enum set_key_cmd cmd, return wl->ops->set_key(wl, cmd, vif, sta, key_conf); } +static inline u32 +wlcore_hw_pre_pkt_send(struct wl1271 *wl, u32 buf_offset, u32 last_len) +{ + if (wl->ops->pre_pkt_send) + return wl->ops->pre_pkt_send(wl, buf_offset, last_len); + + return buf_offset; +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index da9a07d2cf4b..6983e7a829d0 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -178,10 +178,11 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, unsigned int packet_length) { - if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) - return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); - else + if ((wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) || + !(wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)) return ALIGN(packet_length, WL1271_TX_ALIGN_TO); + else + return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); } EXPORT_SYMBOL(wlcore_calc_packet_alignment); @@ -662,7 +663,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) struct wl12xx_vif *wlvif; struct sk_buff *skb; struct wl1271_tx_hw_descr *desc; - u32 buf_offset = 0; + u32 buf_offset = 0, last_len = 0; bool sent_packets = false; unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; int ret; @@ -686,6 +687,9 @@ void wl1271_tx_work_locked(struct wl1271 *wl) * Flush buffer and try again. */ wl1271_skb_queue_head(wl, wlvif, skb); + + buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, + last_len); wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, buf_offset, true); sent_packets = true; @@ -711,7 +715,8 @@ void wl1271_tx_work_locked(struct wl1271 *wl) ieee80211_free_txskb(wl->hw, skb); goto out_ack; } - buf_offset += ret; + last_len = ret; + buf_offset += last_len; wl->tx_packets_count++; if (has_data) { desc = (struct wl1271_tx_hw_descr *) skb->data; @@ -721,6 +726,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) out_ack: if (buf_offset) { + buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, buf_offset, true); sent_packets = true; diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 49e441f34839..fa4be1b91135 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -93,9 +93,9 @@ struct wl18xx_tx_mem { u8 total_mem_blocks; /* - * always zero + * control bits */ - u8 reserved; + u8 ctrl; } __packed; /* diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index e63450072f4d..761a72f4b8d1 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -80,6 +80,7 @@ struct wlcore_ops { struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key_conf); + u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len); }; enum wlcore_partitions { @@ -420,6 +421,9 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, /* Some firmwares may not support ELP */ #define WLCORE_QUIRK_NO_ELP BIT(6) +/* pad only the last frame in the aggregate buffer */ +#define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7) + /* extra header space is required for TKIP */ #define WLCORE_QUIRK_TKIP_HEADER_SPACE BIT(8) -- GitLab From e16de2c4fc674f5558fd87f57c6a8e5156b22c21 Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Fri, 1 Jun 2012 09:19:01 -0700 Subject: [PATCH 0915/6849] wl12xx: Add support for an external 26 MHz crystal source Add support for an external 26 MHz crystal source. [Changed wl->ref_clock to priv->ref_clock -- Luca.] Signed-off-by: Grant Erickson Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 364fb2feffce..8338045d226f 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -875,6 +875,7 @@ static int wl127x_boot_clk(struct wl1271 *wl) /* ref clk: 19.2/38.4/38.4-XTAL */ clk = 0x3; else if (priv->ref_clock == CONF_REF_CLK_26_E || + priv->ref_clock == CONF_REF_CLK_26_M_XTAL || priv->ref_clock == CONF_REF_CLK_52_E) /* ref clk: 26/52 */ clk = 0x5; -- GitLab From 1f975f78c84c852e09463a2dfa57e3174e5c719e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 1 Jun 2012 16:52:35 +0200 Subject: [PATCH 0916/6849] x86, pvops: Remove hooks for {rd,wr}msr_safe_regs There were paravirt_ops hooks for the full register set variant of {rd,wr}msr_safe which are actually not used by anyone anymore. Remove them to make the code cleaner and avoid silent breakages when the pvops members were uninitialized. This has been boot-tested natively and under Xen with PVOPS enabled and disabled on one machine. Signed-off-by: Andre Przywara Link: http://lkml.kernel.org/r/1338562358-28182-2-git-send-email-bp@amd64.org Acked-by: Konrad Rzeszutek Wilk Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/msr.h | 67 +++++++++++---------------- arch/x86/include/asm/paravirt.h | 39 ---------------- arch/x86/include/asm/paravirt_types.h | 2 - arch/x86/kernel/paravirt.c | 2 - arch/x86/lib/msr-reg-export.c | 4 +- arch/x86/lib/msr-reg.S | 10 ++-- arch/x86/xen/enlighten.c | 2 - 7 files changed, 35 insertions(+), 91 deletions(-) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 084ef95274cd..81860cc012d1 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -115,8 +115,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr, extern unsigned long long native_read_tsc(void); -extern int native_rdmsr_safe_regs(u32 regs[8]); -extern int native_wrmsr_safe_regs(u32 regs[8]); +extern int rdmsr_safe_regs(u32 regs[8]); +extern int wrmsr_safe_regs(u32 regs[8]); static __always_inline unsigned long long __native_read_tsc(void) { @@ -187,43 +187,6 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) return err; } -static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) -{ - u32 gprs[8] = { 0 }; - int err; - - gprs[1] = msr; - gprs[7] = 0x9c5a203a; - - err = native_rdmsr_safe_regs(gprs); - - *p = gprs[0] | ((u64)gprs[2] << 32); - - return err; -} - -static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) -{ - u32 gprs[8] = { 0 }; - - gprs[0] = (u32)val; - gprs[1] = msr; - gprs[2] = val >> 32; - gprs[7] = 0x9c5a203a; - - return native_wrmsr_safe_regs(gprs); -} - -static inline int rdmsr_safe_regs(u32 regs[8]) -{ - return native_rdmsr_safe_regs(regs); -} - -static inline int wrmsr_safe_regs(u32 regs[8]) -{ - return native_wrmsr_safe_regs(regs); -} - #define rdtscl(low) \ ((low) = (u32)__native_read_tsc()) @@ -248,6 +211,32 @@ do { \ #endif /* !CONFIG_PARAVIRT */ +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = rdmsr_safe_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return wrmsr_safe_regs(gprs); +} #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ (u32)((val) >> 32)) diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 6cbbabf52707..ebb0cdb60a89 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -128,21 +128,11 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err) return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); } -static inline int paravirt_rdmsr_regs(u32 *regs) -{ - return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs); -} - static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) { return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); } -static inline int paravirt_wrmsr_regs(u32 *regs) -{ - return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs); -} - /* These should all do BUG_ON(_err), but our headers are too tangled. */ #define rdmsr(msr, val1, val2) \ do { \ @@ -176,9 +166,6 @@ do { \ _err; \ }) -#define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs) -#define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs) - static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) { int err; @@ -186,32 +173,6 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) *p = paravirt_read_msr(msr, &err); return err; } -static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) -{ - u32 gprs[8] = { 0 }; - int err; - - gprs[1] = msr; - gprs[7] = 0x9c5a203a; - - err = paravirt_rdmsr_regs(gprs); - - *p = gprs[0] | ((u64)gprs[2] << 32); - - return err; -} - -static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) -{ - u32 gprs[8] = { 0 }; - - gprs[0] = (u32)val; - gprs[1] = msr; - gprs[2] = val >> 32; - gprs[7] = 0x9c5a203a; - - return paravirt_wrmsr_regs(gprs); -} static inline u64 paravirt_read_tsc(void) { diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 8e8b9a4987ee..8613cbb7ba41 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -153,9 +153,7 @@ struct pv_cpu_ops { /* MSR, PMC and TSR operations. err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ u64 (*read_msr)(unsigned int msr, int *err); - int (*rdmsr_regs)(u32 *regs); int (*write_msr)(unsigned int msr, unsigned low, unsigned high); - int (*wrmsr_regs)(u32 *regs); u64 (*read_tsc)(void); u64 (*read_pmc)(int counter); diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 9ce885996fd7..17fff18a1031 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -352,9 +352,7 @@ struct pv_cpu_ops pv_cpu_ops = { #endif .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, - .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = native_write_msr_safe, - .wrmsr_regs = native_wrmsr_safe_regs, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, .read_tscp = native_read_tscp, diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c index a311cc59b65d..8d6ef78b5d01 100644 --- a/arch/x86/lib/msr-reg-export.c +++ b/arch/x86/lib/msr-reg-export.c @@ -1,5 +1,5 @@ #include #include -EXPORT_SYMBOL(native_rdmsr_safe_regs); -EXPORT_SYMBOL(native_wrmsr_safe_regs); +EXPORT_SYMBOL(rdmsr_safe_regs); +EXPORT_SYMBOL(wrmsr_safe_regs); diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S index 69fa10623f21..f6d13eefad10 100644 --- a/arch/x86/lib/msr-reg.S +++ b/arch/x86/lib/msr-reg.S @@ -6,13 +6,13 @@ #ifdef CONFIG_X86_64 /* - * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); + * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); * * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] * */ .macro op_safe_regs op -ENTRY(native_\op\()_safe_regs) +ENTRY(\op\()_safe_regs) CFI_STARTPROC pushq_cfi %rbx pushq_cfi %rbp @@ -45,13 +45,13 @@ ENTRY(native_\op\()_safe_regs) _ASM_EXTABLE(1b, 3b) CFI_ENDPROC -ENDPROC(native_\op\()_safe_regs) +ENDPROC(\op\()_safe_regs) .endm #else /* X86_32 */ .macro op_safe_regs op -ENTRY(native_\op\()_safe_regs) +ENTRY(\op\()_safe_regs) CFI_STARTPROC pushl_cfi %ebx pushl_cfi %ebp @@ -92,7 +92,7 @@ ENTRY(native_\op\()_safe_regs) _ASM_EXTABLE(1b, 3b) CFI_ENDPROC -ENDPROC(native_\op\()_safe_regs) +ENDPROC(\op\()_safe_regs) .endm #endif diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e74df9548a02..60f1131eb94f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1116,9 +1116,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, - .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = xen_write_msr_safe, - .wrmsr_regs = native_wrmsr_safe_regs, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, -- GitLab From ecd431d95aa04257e977fd6878e4203ce462e7e9 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 1 Jun 2012 16:52:36 +0200 Subject: [PATCH 0917/6849] x86, cpu: Fix show_msr MSR accessing function There's no real reason why, when showing the MSRs on a CPU at boottime, we should be using the AMD-specific variant. Simply use the generic safe one which handles #GPs just fine. Cc: Yinghai Lu Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1338562358-28182-3-git-send-email-bp@amd64.org Acked-by: Konrad Rzeszutek Wilk Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6b9333b429ba..5bbc082c47ad 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -947,7 +947,7 @@ static void __cpuinit __print_cpu_msr(void) index_max = msr_range_array[i].max; for (index = index_min; index < index_max; index++) { - if (rdmsrl_amd_safe(index, &val)) + if (rdmsrl_safe(index, &val)) continue; printk(KERN_INFO " MSR%08x: %016llx\n", index, val); } -- GitLab From 169e9cbd77db23fe50bc8ba68bf081adb67b4220 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 1 Jun 2012 16:52:37 +0200 Subject: [PATCH 0918/6849] x86, cpu, amd: Fix crash as Xen Dom0 on AMD Trinity systems f7f286a910221 ("x86/amd: Re-enable CPU topology extensions in case BIOS has disabled it") wrongfully added code which used the AMD-specific {rd,wr}msr variants for no real reason. This caused boot panics on xen which wasn't initializing the {rd,wr}msr_safe_regs pv_ops members properly. This, in turn, caused a heated discussion leading to us reviewing all uses of the AMD-specific variants and removing them where unneeded (almost everywhere except an obscure K8 BIOS fix, see 6b0f43ddfa358). Finally, this patch switches to the standard {rd,wr}msr*_safe* variants which should've been used in the first place anyway and avoided unneeded excitation with xen. Signed-off-by: Andre Przywara Link: http://lkml.kernel.org/r/1338562358-28182-4-git-send-email-bp@amd64.org Cc: Andreas Herrmann Link: [Boris: correct and expand commit message] Signed-off-by: Borislav Petkov Acked-by: Konrad Rzeszutek Wilk Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 146bb6218eec..80ccd99542e6 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -586,9 +586,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) !cpu_has(c, X86_FEATURE_TOPOEXT)) { u64 val; - if (!rdmsrl_amd_safe(0xc0011005, &val)) { + if (!rdmsrl_safe(0xc0011005, &val)) { val |= 1ULL << 54; - wrmsrl_amd_safe(0xc0011005, val); + checking_wrmsrl(0xc0011005, val); rdmsrl(0xc0011005, val); if (val & (1ULL << 54)) { set_cpu_cap(c, X86_FEATURE_TOPOEXT); -- GitLab From 2c929ce6f1ed1302be225512b433e6a6554f71a4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 1 Jun 2012 16:52:38 +0200 Subject: [PATCH 0919/6849] x86, cpu, amd: Deprecate AMD-specific MSR variants Now that all users of {rd,wr}msr_amd_safe have been fixed, deprecate its use by making them private to amd.c and adding warnings when used on anything else beside K8. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1338562358-28182-5-git-send-email-bp@amd64.org Acked-by: Konrad Rzeszutek Wilk Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/msr.h | 27 --------------------------- arch/x86/kernel/cpu/amd.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 81860cc012d1..cb33b5f00267 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -211,33 +211,6 @@ do { \ #endif /* !CONFIG_PARAVIRT */ -static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) -{ - u32 gprs[8] = { 0 }; - int err; - - gprs[1] = msr; - gprs[7] = 0x9c5a203a; - - err = rdmsr_safe_regs(gprs); - - *p = gprs[0] | ((u64)gprs[2] << 32); - - return err; -} - -static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) -{ - u32 gprs[8] = { 0 }; - - gprs[0] = (u32)val; - gprs[1] = msr; - gprs[2] = val >> 32; - gprs[7] = 0x9c5a203a; - - return wrmsr_safe_regs(gprs); -} - #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ (u32)((val) >> 32)) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 80ccd99542e6..c928eb26ada6 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -19,6 +19,39 @@ #include "cpu.h" +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); + u32 gprs[8] = { 0 }; + int err; + + WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = rdmsr_safe_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); + u32 gprs[8] = { 0 }; + + WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return wrmsr_safe_regs(gprs); +} + #ifdef CONFIG_X86_32 /* * B step AMD K6 before B 9730xxxx have hardware bugs that can cause -- GitLab From 350ab15bb2ffe7103bc6bf6c634f3c5b286eaf2a Mon Sep 17 00:00:00 2001 From: Jaccon Bastiaansen Date: Mon, 30 Apr 2012 11:53:43 +0200 Subject: [PATCH 0920/6849] ARM i.MX imx21ads: Fix overlapping static i/o mappings The statically defined I/O memory regions for the i.MX21 on chip peripherals and the on board I/O peripherals of the i.MX21ADS board overlap. This results in a kernel crash during startup. This is fixed by reducing the memory range for the on board I/O peripherals to the actually required range. Signed-off-by: Jaccon Bastiaansen Signed-off-by: Sascha Hauer Cc: stable --- arch/arm/mach-imx/mach-mx21ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index e432d4acee1f..4460d25faae1 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -32,7 +32,7 @@ * Memory-mapped I/O on MX21ADS base board */ #define MX21ADS_MMIO_BASE_ADDR 0xf5000000 -#define MX21ADS_MMIO_SIZE SZ_16M +#define MX21ADS_MMIO_SIZE 0xc00000 #define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \ (MX21ADS_MMIO_BASE_ADDR + (offset)) -- GitLab From c3001b773bb63afd403bae37febf3f09826912cb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 5 Jun 2012 20:31:29 +0000 Subject: [PATCH 0921/6849] net/ethernet: ks8851_mll unregister_netdev() before freeing We added another error condition here, but if we were to hit it then we need to unregister_netdev() before doing the free_netdev(). Otherwise we would hit the BUG_ON() in free_netdev(): BUG_ON(dev->reg_state != NETREG_UNREGISTERED); Signed-off-by: Dan Carpenter Tested-by: Raffaele Recalcati Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851_mll.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 70bd329882c6..875dd5e264eb 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1606,7 +1606,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev) if (!pdata) { netdev_err(netdev, "No platform data\n"); err = -ENODEV; - goto err_register; + goto err_pdata; } memcpy(ks->mac_addr, pdata->mac_addr, 6); if (!is_valid_ether_addr(ks->mac_addr)) { @@ -1626,6 +1626,8 @@ static int __devinit ks8851_probe(struct platform_device *pdev) (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); return 0; +err_pdata: + unregister_netdev(netdev); err_register: err_get_irq: iounmap(ks->hw_addr_cmd); -- GitLab From cae82d499979d99fc061f939d451244971024864 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Wed, 6 Jun 2012 07:35:06 +0000 Subject: [PATCH 0922/6849] qlcnic: Fix estimation of recv MSS in case of LRO o Linux stack estimates MSS from skb->len or skb_shinfo(skb)->gso_size. In case of LRO skb->len is aggregate of len of number of packets hence MSS obtained using skb->len would be incorrect. Incorrect estimation of recv MSS would lead to delayed acks in some traffic patterns (which sends two or three packets and wait for ack and only then send remaining packets). This leads to drop in performance. Hence we need to set gso_size to MSS obtained from firmware. o This is fixed recently in firmware hence the MSS is obtained based on capability. If fw is capable of sending the MSS then only driver sets the gso_size. Signed-off-by: Rajesh Borundia Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 7 +++++++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 3 +++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | 1 + drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | 3 +++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 9 +++++++++ 5 files changed, 23 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 8680a5dae4a2..520ff031cfaa 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -258,6 +258,8 @@ struct rcv_desc { (((sts_data) >> 52) & 0x1) #define qlcnic_get_lro_sts_seq_number(sts_data) \ ((sts_data) & 0x0FFFFFFFF) +#define qlcnic_get_lro_sts_mss(sts_data1) \ + ((sts_data1 >> 32) & 0x0FFFF) struct status_desc { @@ -623,6 +625,7 @@ struct qlcnic_recv_context { #define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) #define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) #define QLCNIC_CAP0_VALIDOFF (1 << 11) +#define QLCNIC_CAP0_LRO_MSS (1 << 21) /* * Context state @@ -829,6 +832,9 @@ struct qlcnic_mac_list_s { #define QLCNIC_FW_CAPABILITY_FVLANTX BIT_9 #define QLCNIC_FW_CAPABILITY_HW_LRO BIT_10 #define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK BIT_27 +#define QLCNIC_FW_CAPABILITY_MORE_CAPS BIT_31 + +#define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG BIT_2 /* module types */ #define LINKEVENT_MODULE_NOT_PRESENT 1 @@ -918,6 +924,7 @@ struct qlcnic_ipaddr { #define QLCNIC_NEED_FLR 0x1000 #define QLCNIC_FW_RESET_OWNER 0x2000 #define QLCNIC_FW_HANG 0x4000 +#define QLCNIC_FW_LRO_MSS_CAP 0x8000 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 8db85244e8ad..cfa174d3a3b1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -237,6 +237,9 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | QLCNIC_CAP0_VALIDOFF); cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); + if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) + cap |= QLCNIC_CAP0_LRO_MSS; + prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx, msix_handler); prq->txrx_sds_binding = nsds_rings - 1; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index 6ced3195aad3..28a6b28192e3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h @@ -588,6 +588,7 @@ enum { #define CRB_DRIVER_VERSION (QLCNIC_REG(0x2a0)) #define CRB_FW_CAPABILITIES_1 (QLCNIC_CAM_RAM(0x128)) +#define CRB_FW_CAPABILITIES_2 (QLCNIC_CAM_RAM(0x12c)) #define CRB_MAC_BLOCK_START (QLCNIC_CAM_RAM(0x1c0)) /* diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index 799fd40ed03a..8620b696aca8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c @@ -1653,6 +1653,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, length = skb->len; + if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) + skb_shinfo(skb)->gso_size = qlcnic_get_lro_sts_mss(sts_data1); + if (vid != 0xffff) __vlan_hwaccel_put_tag(skb, vid); netif_receive_skb(skb); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2c5121..707b5ca3ddde 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -1136,6 +1136,8 @@ static int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) { int ring; + u32 capab2; + struct qlcnic_host_rds_ring *rds_ring; if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) @@ -1146,6 +1148,12 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) if (qlcnic_set_eswitch_port_config(adapter)) return -EIO; + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) { + capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2); + if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) + adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; + } + if (qlcnic_fw_create_ctx(adapter)) return -EIO; @@ -1215,6 +1223,7 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) qlcnic_napi_disable(adapter); qlcnic_fw_destroy_ctx(adapter); + adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP; qlcnic_reset_rx_buffers_list(adapter); qlcnic_release_tx_buffers(adapter); -- GitLab From e42ede226c067fef541e4240f919ed2baf25d268 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Wed, 6 Jun 2012 07:35:07 +0000 Subject: [PATCH 0923/6849] qlcnic: fix unsupported CDRP command error message. Add debug messages for FW CDRP command failure. Signed-off-by: Jitendra Kalsaria Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 +++ .../net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 34 ++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 520ff031cfaa..df4552f15693 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -612,7 +612,11 @@ struct qlcnic_recv_context { #define QLCNIC_CDRP_CMD_GET_MAC_STATS 0x00000037 #define QLCNIC_RCODE_SUCCESS 0 +#define QLCNIC_RCODE_INVALID_ARGS 6 #define QLCNIC_RCODE_NOT_SUPPORTED 9 +#define QLCNIC_RCODE_NOT_PERMITTED 10 +#define QLCNIC_RCODE_NOT_IMPL 15 +#define QLCNIC_RCODE_INVALID 16 #define QLCNIC_RCODE_TIMEOUT 17 #define QLCNIC_DESTROY_CTX_RESET 0 diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index cfa174d3a3b1..b8ead696141e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -53,12 +53,39 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd) rsp = qlcnic_poll_rsp(adapter); if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { - dev_err(&pdev->dev, "card response timeout.\n"); + dev_err(&pdev->dev, "CDRP response timeout.\n"); cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT; } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); - dev_err(&pdev->dev, "failed card response code:0x%x\n", + switch (cmd->rsp.cmd) { + case QLCNIC_RCODE_INVALID_ARGS: + dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n", cmd->rsp.cmd); + break; + case QLCNIC_RCODE_NOT_SUPPORTED: + case QLCNIC_RCODE_NOT_IMPL: + dev_err(&pdev->dev, + "CDRP command not supported: 0x%x.\n", + cmd->rsp.cmd); + break; + case QLCNIC_RCODE_NOT_PERMITTED: + dev_err(&pdev->dev, + "CDRP requested action not permitted: 0x%x.\n", + cmd->rsp.cmd); + break; + case QLCNIC_RCODE_INVALID: + dev_err(&pdev->dev, + "CDRP invalid or unknown cmd received: 0x%x.\n", + cmd->rsp.cmd); + break; + case QLCNIC_RCODE_TIMEOUT: + dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n", + cmd->rsp.cmd); + break; + default: + dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n", + cmd->rsp.cmd); + } } else if (rsp == QLCNIC_CDRP_RSP_OK) { cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS; if (cmd->rsp.arg2) @@ -957,9 +984,6 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber); mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped); mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error); - } else { - dev_info(&adapter->pdev->dev, - "%s: Get mac stats failed =%d.\n", __func__, err); } dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, -- GitLab From 0bb79565aaa4d917a14c87deae8b98a61833307a Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Wed, 6 Jun 2012 07:35:08 +0000 Subject: [PATCH 0924/6849] qlcnic: Fix protcol type in case of inband vlan. o Use correct l3 (ETH_IP or ETH_IPV6)protcol in case of inband vlan. Because of incorrect protcol type driver was setting incorrect opcode. This resulted in adapter calculating checksum incorrectly. o Updated driver version to 5.0.29 Signed-off-by: Rajesh Borundia Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index df4552f15693..eaa1db9fec32 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -36,8 +36,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 28 -#define QLCNIC_LINUX_VERSIONID "5.0.28" +#define _QLCNIC_LINUX_SUBVERSION 29 +#define QLCNIC_LINUX_VERSIONID "5.0.29" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 707b5ca3ddde..33c3e46e59c4 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2033,6 +2033,7 @@ qlcnic_tx_pkt(struct qlcnic_adapter *adapter, vh = (struct vlan_ethhdr *)skb->data; flags = FLAGS_VLAN_TAGGED; vlan_tci = vh->h_vlan_TCI; + protocol = ntohs(vh->h_vlan_encapsulated_proto); } else if (vlan_tx_tag_present(skb)) { flags = FLAGS_VLAN_OOB; vlan_tci = vlan_tx_tag_get(skb); -- GitLab From 94b6042cfed02229b05e04002ab00085b60f8213 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 6 Jun 2012 15:23:37 +0000 Subject: [PATCH 0925/6849] net: Update kernel-doc for __alloc_skb() __alloc_skb() now extends tailroom to allow the use of padding added by the heap allocator. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/skbuff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 016694d62484..1d74cea22aaa 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -160,8 +160,8 @@ static void skb_under_panic(struct sk_buff *skb, int sz, void *here) * @node: numa node to allocate memory on * * Allocate a new &sk_buff. The returned buffer has no headroom and a - * tail room of size bytes. The object has a reference count of one. - * The return is the buffer. On a failure the return is %NULL. + * tail room of at least size bytes. The object has a reference count + * of one. The return is the buffer. On a failure the return is %NULL. * * Buffers may only be allocated from interrupts using a @gfp_mask of * %GFP_ATOMIC. -- GitLab From 80f12eccce775dc6bb93dba9b52529740f929237 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 6 Jun 2012 17:13:06 +0000 Subject: [PATCH 0926/6849] Added kernel support in EEE Ethtool commands This patch extends the kernel's ethtool interface by adding support for 2 new EEE commands - get_eee and set_eee. Thanks goes to Giuseppe Cavallaro for his original patch adding this support. Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 35 +++++++++++++++++++++++++++++++++++ net/core/ethtool.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index e17fa7140588..297370a6cb18 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -136,6 +136,35 @@ struct ethtool_eeprom { __u8 data[0]; }; +/** + * struct ethtool_eee - Energy Efficient Ethernet information + * @cmd: ETHTOOL_{G,S}EEE + * @supported: Mask of %SUPPORTED_* flags for the speed/duplex combinations + * for which there is EEE support. + * @advertised: Mask of %ADVERTISED_* flags for the speed/duplex combinations + * advertised as eee capable. + * @lp_advertised: Mask of %ADVERTISED_* flags for the speed/duplex + * combinations advertised by the link partner as eee capable. + * @eee_active: Result of the eee auto negotiation. + * @eee_enabled: EEE configured mode (enabled/disabled). + * @tx_lpi_enabled: Whether the interface should assert its tx lpi, given + * that eee was negotiated. + * @tx_lpi_timer: Time in microseconds the interface delays prior to asserting + * its tx lpi (after reaching 'idle' state). Effective only when eee + * was negotiated and tx_lpi_enabled was set. + */ +struct ethtool_eee { + __u32 cmd; + __u32 supported; + __u32 advertised; + __u32 lp_advertised; + __u32 eee_active; + __u32 eee_enabled; + __u32 tx_lpi_enabled; + __u32 tx_lpi_timer; + __u32 reserved[2]; +}; + /** * struct ethtool_modinfo - plugin module eeprom information * @cmd: %ETHTOOL_GMODULEINFO @@ -945,6 +974,8 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) * @get_module_info: Get the size and type of the eeprom contained within * a plug-in module. * @get_module_eeprom: Get the eeprom information from the plug-in module + * @get_eee: Get Energy-Efficient (EEE) supported and status. + * @set_eee: Set EEE status (enable/disable) as well as LPI timers. * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -1011,6 +1042,8 @@ struct ethtool_ops { struct ethtool_modinfo *); int (*get_module_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*get_eee)(struct net_device *, struct ethtool_eee *); + int (*set_eee)(struct net_device *, struct ethtool_eee *); }; @@ -1089,6 +1122,8 @@ struct ethtool_ops { #define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */ #define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */ #define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */ +#define ETHTOOL_GEEE 0x00000044 /* Get EEE settings */ +#define ETHTOOL_SEEE 0x00000045 /* Set EEE settings */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 9c2afb480270..c73d0a59212c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -729,6 +729,40 @@ static int ethtool_set_wol(struct net_device *dev, char __user *useraddr) return dev->ethtool_ops->set_wol(dev, &wol); } +static int ethtool_get_eee(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_eee edata; + int rc; + + if (!dev->ethtool_ops->get_eee) + return -EOPNOTSUPP; + + memset(&edata, 0, sizeof(struct ethtool_eee)); + edata.cmd = ETHTOOL_GEEE; + rc = dev->ethtool_ops->get_eee(dev, &edata); + + if (rc) + return rc; + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + + return 0; +} + +static int ethtool_set_eee(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_eee edata; + + if (!dev->ethtool_ops->set_eee) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_eee(dev, &edata); +} + static int ethtool_nway_reset(struct net_device *dev) { if (!dev->ethtool_ops->nway_reset) @@ -1471,6 +1505,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) rc = ethtool_set_value_void(dev, useraddr, dev->ethtool_ops->set_msglevel); break; + case ETHTOOL_GEEE: + rc = ethtool_get_eee(dev, useraddr); + break; + case ETHTOOL_SEEE: + rc = ethtool_set_eee(dev, useraddr); + break; case ETHTOOL_NWAY_RST: rc = ethtool_nway_reset(dev); break; -- GitLab From c8c60d88c59cbb48737732ba948663a3efe882aa Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 6 Jun 2012 17:13:07 +0000 Subject: [PATCH 0927/6849] bnx2x: Added EEE support This patch adds energy efficient energy support (802.3az) to bnx2x boards with 84833 phys (and sufficiently new BC and external FW). Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 61 +++- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 323 +++++++++++++++++- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 26 ++ .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 23 +- .../net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 123 +++++++ .../net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 4 + .../net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 2 + 7 files changed, 552 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index a440a8ba85f2..c61aa37298a3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -1067,8 +1067,18 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ uses the same defines as link_config */ u32 mfw_wol_link_cfg2; /* 0x480 */ - u32 Reserved2[17]; /* 0x484 */ + /* EEE power saving mode */ + u32 eee_power_mode; /* 0x484 */ + #define PORT_FEAT_CFG_EEE_POWER_MODE_MASK 0x000000FF + #define PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT 0 + #define PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED 0x00000000 + #define PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED 0x00000001 + #define PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE 0x00000002 + #define PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY 0x00000003 + + + u32 Reserved2[16]; /* 0x488 */ }; @@ -1255,6 +1265,8 @@ struct drv_func_mb { #define DRV_MSG_CODE_DRV_INFO_ACK 0xd8000000 #define DRV_MSG_CODE_DRV_INFO_NACK 0xd9000000 + #define DRV_MSG_CODE_EEE_RESULTS_ACK 0xda000000 + #define DRV_MSG_CODE_SET_MF_BW 0xe0000000 #define REQ_BC_VER_4_SET_MF_BW 0x00060202 #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 @@ -1320,6 +1332,8 @@ struct drv_func_mb { #define FW_MSG_CODE_DRV_INFO_ACK 0xd8100000 #define FW_MSG_CODE_DRV_INFO_NACK 0xd9100000 + #define FW_MSG_CODE_EEE_RESULS_ACK 0xda100000 + #define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000 #define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000 @@ -1383,6 +1397,8 @@ struct drv_func_mb { #define DRV_STATUS_DRV_INFO_REQ 0x04000000 + #define DRV_STATUS_EEE_NEGOTIATION_RESULTS 0x08000000 + u32 virt_mac_upper; #define VIRT_MAC_SIGN_MASK 0xffff0000 #define VIRT_MAC_SIGNATURE 0x564d0000 @@ -1613,6 +1629,11 @@ struct fw_flr_mb { struct fw_flr_ack ack; }; +struct eee_remote_vals { + u32 tx_tw; + u32 rx_tw; +}; + /**** SUPPORT FOR SHMEM ARRRAYS *** * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to * define arrays with storage types smaller then unsigned dwords. @@ -2053,6 +2074,41 @@ struct shmem2_region { #define DRV_INFO_CONTROL_OP_CODE_MASK 0x0000ff00 #define DRV_INFO_CONTROL_OP_CODE_SHIFT 8 u32 ibft_host_addr; /* initialized by option ROM */ + struct eee_remote_vals eee_remote_vals[PORT_MAX]; + u32 reserved[E2_FUNC_MAX]; + + + /* the status of EEE auto-negotiation + * bits 15:0 the configured tx-lpi entry timer value. Depends on bit 31. + * bits 19:16 the supported modes for EEE. + * bits 23:20 the speeds advertised for EEE. + * bits 27:24 the speeds the Link partner advertised for EEE. + * The supported/adv. modes in bits 27:19 originate from the + * SHMEM_EEE_XXX_ADV definitions (where XXX is replaced by speed). + * bit 28 when 1'b1 EEE was requested. + * bit 29 when 1'b1 tx lpi was requested. + * bit 30 when 1'b1 EEE was negotiated. Tx lpi will be asserted iff + * 30:29 are 2'b11. + * bit 31 when 1'b0 bits 15:0 contain a PORT_FEAT_CFG_EEE_ define as + * value. When 1'b1 those bits contains a value times 16 microseconds. + */ + u32 eee_status[PORT_MAX]; + #define SHMEM_EEE_TIMER_MASK 0x0000ffff + #define SHMEM_EEE_SUPPORTED_MASK 0x000f0000 + #define SHMEM_EEE_SUPPORTED_SHIFT 16 + #define SHMEM_EEE_ADV_STATUS_MASK 0x00f00000 + #define SHMEM_EEE_100M_ADV (1<<0) + #define SHMEM_EEE_1G_ADV (1<<1) + #define SHMEM_EEE_10G_ADV (1<<2) + #define SHMEM_EEE_ADV_STATUS_SHIFT 20 + #define SHMEM_EEE_LP_ADV_STATUS_MASK 0x0f000000 + #define SHMEM_EEE_LP_ADV_STATUS_SHIFT 24 + #define SHMEM_EEE_REQUESTED_BIT 0x10000000 + #define SHMEM_EEE_LPI_REQUESTED_BIT 0x20000000 + #define SHMEM_EEE_ACTIVE_BIT 0x40000000 + #define SHMEM_EEE_TIME_OUTPUT_BIT 0x80000000 + + u32 sizeof_port_stats; }; @@ -2599,6 +2655,9 @@ struct host_port_stats { u32 pfc_frames_tx_lo; u32 pfc_frames_rx_hi; u32 pfc_frames_rx_lo; + + u32 eee_lpi_count_hi; + u32 eee_lpi_count_lo; }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index a3fb7215cd89..c7c814db027d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -1305,6 +1305,94 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) return 0; } + +/******************************************************************/ +/* EEE section */ +/******************************************************************/ +static u8 bnx2x_eee_has_cap(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + + if (REG_RD(bp, params->shmem2_base) <= + offsetof(struct shmem2_region, eee_status[params->port])) + return 0; + + return 1; +} + +static int bnx2x_eee_nvram_to_time(u32 nvram_mode, u32 *idle_timer) +{ + switch (nvram_mode) { + case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED: + *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME; + break; + case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE: + *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME; + break; + case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY: + *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME; + break; + default: + *idle_timer = 0; + break; + } + + return 0; +} + +static int bnx2x_eee_time_to_nvram(u32 idle_timer, u32 *nvram_mode) +{ + switch (idle_timer) { + case EEE_MODE_NVRAM_BALANCED_TIME: + *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED; + break; + case EEE_MODE_NVRAM_AGGRESSIVE_TIME: + *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE; + break; + case EEE_MODE_NVRAM_LATENCY_TIME: + *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY; + break; + default: + *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED; + break; + } + + return 0; +} + +static u32 bnx2x_eee_calc_timer(struct link_params *params) +{ + u32 eee_mode, eee_idle; + struct bnx2x *bp = params->bp; + + if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) { + if (params->eee_mode & EEE_MODE_OUTPUT_TIME) { + /* time value in eee_mode --> used directly*/ + eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK; + } else { + /* hsi value in eee_mode --> time */ + if (bnx2x_eee_nvram_to_time(params->eee_mode & + EEE_MODE_NVRAM_MASK, + &eee_idle)) + return 0; + } + } else { + /* hsi values in nvram --> time*/ + eee_mode = ((REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port]. + eee_power_mode)) & + PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >> + PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT); + + if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle)) + return 0; + } + + return eee_idle; +} + + /******************************************************************/ /* PFC section */ /******************************************************************/ @@ -1729,6 +1817,14 @@ static int bnx2x_xmac_enable(struct link_params *params, /* update PFC */ bnx2x_update_pfc_xmac(params, vars, 0); + if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) { + DP(NETIF_MSG_LINK, "Setting XMAC for EEE\n"); + REG_WR(bp, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008); + REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x1); + } else { + REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x0); + } + /* Enable TX and RX */ val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; @@ -2439,6 +2535,16 @@ static void bnx2x_update_mng(struct link_params *params, u32 link_status) port_mb[params->port].link_status), link_status); } +static void bnx2x_update_mng_eee(struct link_params *params, u32 eee_status) +{ + struct bnx2x *bp = params->bp; + + if (bnx2x_eee_has_cap(params)) + REG_WR(bp, params->shmem2_base + + offsetof(struct shmem2_region, + eee_status[params->port]), eee_status); +} + static void bnx2x_update_pfc_nig(struct link_params *params, struct link_vars *vars, struct bnx2x_nig_brb_pfc_port_params *nig_params) @@ -3950,6 +4056,20 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); + /* Enable LPI pass through */ + if ((params->eee_mode & EEE_MODE_ADV_LPI) && + (phy->flags & FLAGS_EEE_10GBT) && + (!(params->eee_mode & EEE_MODE_ENABLE_LPI) || + bnx2x_eee_calc_timer(params)) && + (params->req_duplex[bnx2x_phy_selection(params)] == DUPLEX_FULL)) { + DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n"); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_EEE_COMBO_CONTROL0, + 0x7c); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC5, 0xc000); + } + /* 10G XFI Full Duplex */ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100); @@ -6462,6 +6582,15 @@ static int bnx2x_update_link_down(struct link_params *params, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); } if (CHIP_IS_E3(bp)) { + REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), + 0); + REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0); + REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2), + 0); + vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | + SHMEM_EEE_ACTIVE_BIT); + + bnx2x_update_mng_eee(params, vars->eee_status); bnx2x_xmac_disable(params); bnx2x_umac_disable(params); } @@ -6501,6 +6630,16 @@ static int bnx2x_update_link_up(struct link_params *params, bnx2x_umac_enable(params, vars, 0); bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); + + if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) && + (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) { + DP(NETIF_MSG_LINK, "Enabling LPI assertion\n"); + REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + + (params->port << 2), 1); + REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 1); + REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + + (params->port << 2), 0xfc20); + } } if ((CHIP_IS_E1x(bp) || CHIP_IS_E2(bp))) { @@ -6538,7 +6677,7 @@ static int bnx2x_update_link_up(struct link_params *params, /* update shared memory */ bnx2x_update_mng(params, vars->link_status); - + bnx2x_update_mng_eee(params, vars->eee_status); /* Check remote fault */ for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { @@ -6582,6 +6721,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) phy_vars[phy_index].phy_link_up = 0; phy_vars[phy_index].link_up = 0; phy_vars[phy_index].fault_detected = 0; + /* different consideration, since vars holds inner state */ + phy_vars[phy_index].eee_status = vars->eee_status; } if (USES_WARPCORE(bp)) @@ -6711,6 +6852,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) vars->link_status |= LINK_STATUS_SERDES_LINK; else vars->link_status &= ~LINK_STATUS_SERDES_LINK; + + vars->eee_status = phy_vars[active_external_phy].eee_status; + DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", active_external_phy); } @@ -9579,9 +9723,9 @@ static int bnx2x_8481_config_init(struct bnx2x_phy *phy, static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, struct link_params *params, u16 fw_cmd, - u16 cmd_args[]) + u16 cmd_args[], int argc) { - u32 idx; + int idx; u16 val; struct bnx2x *bp = params->bp; /* Write CMD_OPEN_OVERRIDE to STATUS reg */ @@ -9601,7 +9745,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, } /* Prepare argument(s) and issue command */ - for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) { + for (idx = 0; idx < argc; idx++) { bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, MDIO_84833_CMD_HDLR_DATA1 + idx, cmd_args[idx]); @@ -9622,7 +9766,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, return -EINVAL; } /* Gather returning data */ - for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) { + for (idx = 0; idx < argc; idx++) { bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, MDIO_84833_CMD_HDLR_DATA1 + idx, &cmd_args[idx]); @@ -9656,7 +9800,7 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, data[1] = (u16)pair_swap; status = bnx2x_84833_cmd_hdlr(phy, params, - PHY84833_CMD_SET_PAIR_SWAP, data); + PHY84833_CMD_SET_PAIR_SWAP, data, PHY84833_CMDHDLR_MAX_ARGS); if (status == 0) DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); @@ -9734,6 +9878,95 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy, return 0; } +static int bnx2x_8483x_eee_timers(struct link_params *params, + struct link_vars *vars) +{ + u32 eee_idle = 0, eee_mode; + struct bnx2x *bp = params->bp; + + eee_idle = bnx2x_eee_calc_timer(params); + + if (eee_idle) { + REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2), + eee_idle); + } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) && + (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) && + (params->eee_mode & EEE_MODE_OUTPUT_TIME)) { + DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n"); + return -EINVAL; + } + + vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT); + if (params->eee_mode & EEE_MODE_OUTPUT_TIME) { + /* eee_idle in 1u --> eee_status in 16u */ + eee_idle >>= 4; + vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) | + SHMEM_EEE_TIME_OUTPUT_BIT; + } else { + if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode)) + return -EINVAL; + vars->eee_status |= eee_mode; + } + + return 0; +} + +static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + int rc; + struct bnx2x *bp = params->bp; + u16 cmd_args = 0; + + DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n"); + + /* Make Certain LPI is disabled */ + REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0); + REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0); + + /* Prevent Phy from working in EEE and advertising it */ + rc = bnx2x_84833_cmd_hdlr(phy, params, + PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1); + if (rc != 0) { + DP(NETIF_MSG_LINK, "EEE disable failed.\n"); + return rc; + } + + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0); + vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK; + + return 0; +} + +static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + int rc; + struct bnx2x *bp = params->bp; + u16 cmd_args = 1; + + DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n"); + + rc = bnx2x_84833_cmd_hdlr(phy, params, + PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1); + if (rc != 0) { + DP(NETIF_MSG_LINK, "EEE enable failed.\n"); + return rc; + } + + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x8); + + /* Mask events preventing LPI generation */ + REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20); + + vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK; + vars->eee_status |= (SHMEM_EEE_10G_ADV << SHMEM_EEE_ADV_STATUS_SHIFT); + + return 0; +} + #define PHY84833_CONSTANT_LATENCY 1193 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_params *params, @@ -9833,7 +10066,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1; cmd_args[3] = PHY84833_CONSTANT_LATENCY; rc = bnx2x_84833_cmd_hdlr(phy, params, - PHY84833_CMD_SET_EEE_MODE, cmd_args); + PHY84833_CMD_SET_EEE_MODE, cmd_args, + PHY84833_CMDHDLR_MAX_ARGS); if (rc != 0) DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); } @@ -9858,6 +10092,48 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, MDIO_CTL_REG_84823_USER_CTRL_REG, val); } + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_FW_REV, &val); + + /* Configure EEE support */ + if ((val >= MDIO_84833_TOP_CFG_FW_EEE) && bnx2x_eee_has_cap(params)) { + phy->flags |= FLAGS_EEE_10GBT; + vars->eee_status |= SHMEM_EEE_10G_ADV << + SHMEM_EEE_SUPPORTED_SHIFT; + /* Propogate params' bits --> vars (for migration exposure) */ + if (params->eee_mode & EEE_MODE_ENABLE_LPI) + vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT; + else + vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT; + + if (params->eee_mode & EEE_MODE_ADV_LPI) + vars->eee_status |= SHMEM_EEE_REQUESTED_BIT; + else + vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT; + + rc = bnx2x_8483x_eee_timers(params, vars); + if (rc != 0) { + DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n"); + bnx2x_8483x_disable_eee(phy, params, vars); + return rc; + } + + if ((params->req_duplex[actual_phy_selection] == DUPLEX_FULL) && + (params->eee_mode & EEE_MODE_ADV_LPI) && + (bnx2x_eee_calc_timer(params) || + !(params->eee_mode & EEE_MODE_ENABLE_LPI))) + rc = bnx2x_8483x_enable_eee(phy, params, vars); + else + rc = bnx2x_8483x_disable_eee(phy, params, vars); + if (rc != 0) { + DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); + return rc; + } + } else { + phy->flags &= ~FLAGS_EEE_10GBT; + vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK; + } + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { /* Bring PHY out of super isolate mode as the final step. */ bnx2x_cl45_read(bp, phy, @@ -9989,6 +10265,31 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, if (val & (1<<11)) vars->link_status |= LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE; + + /* Determine if EEE was negotiated */ + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { + u32 eee_shmem = 0; + + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, + MDIO_AN_REG_EEE_ADV, &val1); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, + MDIO_AN_REG_LP_EEE_ADV, &val2); + if ((val1 & val2) & 0x8) { + DP(NETIF_MSG_LINK, "EEE negotiated\n"); + vars->eee_status |= SHMEM_EEE_ACTIVE_BIT; + } + + if (val2 & 0x12) + eee_shmem |= SHMEM_EEE_100M_ADV; + if (val2 & 0x4) + eee_shmem |= SHMEM_EEE_1G_ADV; + if (val2 & 0x68) + eee_shmem |= SHMEM_EEE_10G_ADV; + + vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK; + vars->eee_status |= (eee_shmem << + SHMEM_EEE_LP_ADV_STATUS_SHIFT); + } } return link_up; @@ -11243,7 +11544,8 @@ static struct bnx2x_phy phy_84833 = { .def_md_devad = 0, .flags = (FLAGS_FAN_FAILURE_DET_REQ | FLAGS_REARM_LATCH_SIGNAL | - FLAGS_TX_ERROR_CHECK), + FLAGS_TX_ERROR_CHECK | + FLAGS_EEE_10GBT), .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -12011,6 +12313,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) break; } bnx2x_update_mng(params, vars->link_status); + + bnx2x_update_mng_eee(params, vars->eee_status); return 0; } @@ -12023,6 +12327,9 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /* disable attentions */ vars->link_status = 0; bnx2x_update_mng(params, vars->link_status); + vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | + SHMEM_EEE_ACTIVE_BIT); + bnx2x_update_mng_eee(params, vars->eee_status); bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, (NIG_MASK_XGXS0_LINK_STATUS | NIG_MASK_XGXS0_LINK10G | diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index ea4371f4335f..e920800a7bc5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -149,6 +149,7 @@ struct bnx2x_phy { #define FLAGS_DUMMY_READ (1<<9) #define FLAGS_MDC_MDIO_WA_B0 (1<<10) #define FLAGS_TX_ERROR_CHECK (1<<12) +#define FLAGS_EEE_10GBT (1<<13) /* preemphasis values for the rx side */ u16 rx_preemphasis[4]; @@ -265,6 +266,30 @@ struct link_params { u8 num_phys; u8 rsrv; + + /* Used to configure the EEE Tx LPI timer, has several modes of + * operation, according to bits 29:28 - + * 2'b00: Timer will be configured by nvram, output will be the value + * from nvram. + * 2'b01: Timer will be configured by nvram, output will be in + * microseconds. + * 2'b10: bits 1:0 contain an nvram value which will be used instead + * of the one located in the nvram. Output will be that value. + * 2'b11: bits 19:0 contain the idle timer in microseconds; output + * will be in microseconds. + * Bits 31:30 should be 2'b11 in order for EEE to be enabled. + */ + u32 eee_mode; +#define EEE_MODE_NVRAM_BALANCED_TIME (0xa00) +#define EEE_MODE_NVRAM_AGGRESSIVE_TIME (0x100) +#define EEE_MODE_NVRAM_LATENCY_TIME (0x6000) +#define EEE_MODE_NVRAM_MASK (0x3) +#define EEE_MODE_TIMER_MASK (0xfffff) +#define EEE_MODE_OUTPUT_TIME (1<<28) +#define EEE_MODE_OVERRIDE_NVRAM (1<<29) +#define EEE_MODE_ENABLE_LPI (1<<30) +#define EEE_MODE_ADV_LPI (1<<31) + u16 hw_led_mode; /* part of the hw_config read from the shmem */ u32 multi_phy_config; @@ -301,6 +326,7 @@ struct link_vars { /* The same definitions as the shmem parameter */ u32 link_status; + u32 eee_status; u8 fault_detected; u8 rsrv1; u16 periodic_flags; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f755a665dab3..a622bb7bf21d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -3176,6 +3176,12 @@ static void bnx2x_set_mf_bw(struct bnx2x *bp) bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); } +static void bnx2x_handle_eee_event(struct bnx2x *bp) +{ + DP(BNX2X_MSG_MCP, "EEE - LLDP event\n"); + bnx2x_fw_command(bp, DRV_MSG_CODE_EEE_RESULTS_ACK, 0); +} + static void bnx2x_handle_drv_info_req(struct bnx2x *bp) { enum drv_info_opcode op_code; @@ -3742,6 +3748,8 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if (val & DRV_STATUS_AFEX_EVENT_MASK) bnx2x_handle_afex_cmd(bp, val & DRV_STATUS_AFEX_EVENT_MASK); + if (val & DRV_STATUS_EEE_NEGOTIATION_RESULTS) + bnx2x_handle_eee_event(bp); if (bp->link_vars.periodic_flags & PERIODIC_FLAGS_LINK_EVENT) { /* sync with link */ @@ -10082,7 +10090,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) { int port = BP_PORT(bp); u32 config; - u32 ext_phy_type, ext_phy_config; + u32 ext_phy_type, ext_phy_config, eee_mode; bp->link_params.bp = bp; bp->link_params.port = port; @@ -10149,6 +10157,19 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, bp->common.shmem_base, bp->common.shmem2_base); + + /* Configure link feature according to nvram value */ + eee_mode = (((SHMEM_RD(bp, dev_info. + port_feature_config[port].eee_power_mode)) & + PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >> + PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT); + if (eee_mode != PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED) { + bp->link_params.eee_mode = EEE_MODE_ADV_LPI | + EEE_MODE_ENABLE_LPI | + EEE_MODE_OUTPUT_TIME; + } else { + bp->link_params.eee_mode = 0; + } } void bnx2x_get_iscsi_info(struct bnx2x *bp) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index bbd387492a80..bfef98f666c9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -1488,6 +1488,121 @@ * 2:1 - otp_misc_do[51:50]; 0 - otp_misc_do[1]. */ #define MISC_REG_CHIP_TYPE 0xac60 #define MISC_REG_CHIP_TYPE_57811_MASK (1<<1) +#define MISC_REG_CPMU_LP_DR_ENABLE 0xa858 +/* [RW 1] FW EEE LPI Enable. When 1 indicates that EEE LPI mode is enabled + * by FW. When 0 indicates that the EEE LPI mode is disabled by FW. Clk + * 25MHz. Reset on hard reset. */ +#define MISC_REG_CPMU_LP_FW_ENABLE_P0 0xa84c +/* [RW 32] EEE LPI Idle Threshold. The threshold value for the idle EEE LPI + * counter. Timer tick is 1 us. Clock 25MHz. Reset on hard reset. */ +#define MISC_REG_CPMU_LP_IDLE_THR_P0 0xa8a0 +/* [RW 18] LPI entry events mask. [0] - Vmain SM Mask. When 1 indicates that + * the Vmain SM end state is disabled. When 0 indicates that the Vmain SM + * end state is enabled. [1] - FW Queues Empty Mask. When 1 indicates that + * the FW command that all Queues are empty is disabled. When 0 indicates + * that the FW command that all Queues are empty is enabled. [2] - FW Early + * Exit Mask / Reserved (Entry mask). When 1 indicates that the FW Early + * Exit command is disabled. When 0 indicates that the FW Early Exit command + * is enabled. This bit applicable only in the EXIT Events Mask registers. + * [3] - PBF Request Mask. When 1 indicates that the PBF Request indication + * is disabled. When 0 indicates that the PBF Request indication is enabled. + * [4] - Tx Request Mask. When =1 indicates that the Tx other Than PBF + * Request indication is disabled. When 0 indicates that the Tx Other Than + * PBF Request indication is enabled. [5] - Rx EEE LPI Status Mask. When 1 + * indicates that the RX EEE LPI Status indication is disabled. When 0 + * indicates that the RX EEE LPI Status indication is enabled. In the EXIT + * Events Masks registers; this bit masks the falling edge detect of the LPI + * Status (Rx LPI is on - off). [6] - Tx Pause Mask. When 1 indicates that + * the Tx Pause indication is disabled. When 0 indicates that the Tx Pause + * indication is enabled. [7] - BRB1 Empty Mask. When 1 indicates that the + * BRB1 EMPTY indication is disabled. When 0 indicates that the BRB1 EMPTY + * indication is enabled. [8] - QM Idle Mask. When 1 indicates that the QM + * IDLE indication is disabled. When 0 indicates that the QM IDLE indication + * is enabled. (One bit for both VOQ0 and VOQ1). [9] - QM LB Idle Mask. When + * 1 indicates that the QM IDLE indication for LOOPBACK is disabled. When 0 + * indicates that the QM IDLE indication for LOOPBACK is enabled. [10] - L1 + * Status Mask. When 1 indicates that the L1 Status indication from the PCIE + * CORE is disabled. When 0 indicates that the RX EEE LPI Status indication + * from the PCIE CORE is enabled. In the EXIT Events Masks registers; this + * bit masks the falling edge detect of the L1 status (L1 is on - off). [11] + * - P0 E0 EEE EEE LPI REQ Mask. When =1 indicates that the P0 E0 EEE EEE + * LPI REQ indication is disabled. When =0 indicates that the P0 E0 EEE LPI + * REQ indication is enabled. [12] - P1 E0 EEE LPI REQ Mask. When =1 + * indicates that the P0 EEE LPI REQ indication is disabled. When =0 + * indicates that the P0 EEE LPI REQ indication is enabled. [13] - P0 E1 EEE + * LPI REQ Mask. When =1 indicates that the P0 EEE LPI REQ indication is + * disabled. When =0 indicates that the P0 EEE LPI REQ indication is + * enabled. [14] - P1 E1 EEE LPI REQ Mask. When =1 indicates that the P0 EEE + * LPI REQ indication is disabled. When =0 indicates that the P0 EEE LPI REQ + * indication is enabled. [15] - L1 REQ Mask. When =1 indicates that the L1 + * REQ indication is disabled. When =0 indicates that the L1 indication is + * enabled. [16] - Rx EEE LPI Status Edge Detect Mask. When =1 indicates + * that the RX EEE LPI Status Falling Edge Detect indication is disabled (Rx + * EEE LPI is on - off). When =0 indicates that the RX EEE LPI Status + * Falling Edge Detec indication is enabled (Rx EEE LPI is on - off). This + * bit is applicable only in the EXIT Events Masks registers. [17] - L1 + * Status Edge Detect Mask. When =1 indicates that the L1 Status Falling + * Edge Detect indication from the PCIE CORE is disabled (L1 is on - off). + * When =0 indicates that the L1 Status Falling Edge Detect indication from + * the PCIE CORE is enabled (L1 is on - off). This bit is applicable only in + * the EXIT Events Masks registers. Clock 25MHz. Reset on hard reset. */ +#define MISC_REG_CPMU_LP_MASK_ENT_P0 0xa880 +/* [RW 18] EEE LPI exit events mask. [0] - Vmain SM Mask. When 1 indicates + * that the Vmain SM end state is disabled. When 0 indicates that the Vmain + * SM end state is enabled. [1] - FW Queues Empty Mask. When 1 indicates + * that the FW command that all Queues are empty is disabled. When 0 + * indicates that the FW command that all Queues are empty is enabled. [2] - + * FW Early Exit Mask / Reserved (Entry mask). When 1 indicates that the FW + * Early Exit command is disabled. When 0 indicates that the FW Early Exit + * command is enabled. This bit applicable only in the EXIT Events Mask + * registers. [3] - PBF Request Mask. When 1 indicates that the PBF Request + * indication is disabled. When 0 indicates that the PBF Request indication + * is enabled. [4] - Tx Request Mask. When =1 indicates that the Tx other + * Than PBF Request indication is disabled. When 0 indicates that the Tx + * Other Than PBF Request indication is enabled. [5] - Rx EEE LPI Status + * Mask. When 1 indicates that the RX EEE LPI Status indication is disabled. + * When 0 indicates that the RX LPI Status indication is enabled. In the + * EXIT Events Masks registers; this bit masks the falling edge detect of + * the EEE LPI Status (Rx EEE LPI is on - off). [6] - Tx Pause Mask. When 1 + * indicates that the Tx Pause indication is disabled. When 0 indicates that + * the Tx Pause indication is enabled. [7] - BRB1 Empty Mask. When 1 + * indicates that the BRB1 EMPTY indication is disabled. When 0 indicates + * that the BRB1 EMPTY indication is enabled. [8] - QM Idle Mask. When 1 + * indicates that the QM IDLE indication is disabled. When 0 indicates that + * the QM IDLE indication is enabled. (One bit for both VOQ0 and VOQ1). [9] + * - QM LB Idle Mask. When 1 indicates that the QM IDLE indication for + * LOOPBACK is disabled. When 0 indicates that the QM IDLE indication for + * LOOPBACK is enabled. [10] - L1 Status Mask. When 1 indicates that the L1 + * Status indication from the PCIE CORE is disabled. When 0 indicates that + * the RX EEE LPI Status indication from the PCIE CORE is enabled. In the + * EXIT Events Masks registers; this bit masks the falling edge detect of + * the L1 status (L1 is on - off). [11] - P0 E0 EEE EEE LPI REQ Mask. When + * =1 indicates that the P0 E0 EEE EEE LPI REQ indication is disabled. When + * =0 indicates that the P0 E0 EEE LPI REQ indication is enabled. [12] - P1 + * E0 EEE LPI REQ Mask. When =1 indicates that the P0 EEE LPI REQ indication + * is disabled. When =0 indicates that the P0 EEE LPI REQ indication is + * enabled. [13] - P0 E1 EEE LPI REQ Mask. When =1 indicates that the P0 EEE + * LPI REQ indication is disabled. When =0 indicates that the P0 EEE LPI REQ + * indication is enabled. [14] - P1 E1 EEE LPI REQ Mask. When =1 indicates + * that the P0 EEE LPI REQ indication is disabled. When =0 indicates that + * the P0 EEE LPI REQ indication is enabled. [15] - L1 REQ Mask. When =1 + * indicates that the L1 REQ indication is disabled. When =0 indicates that + * the L1 indication is enabled. [16] - Rx EEE LPI Status Edge Detect Mask. + * When =1 indicates that the RX EEE LPI Status Falling Edge Detect + * indication is disabled (Rx EEE LPI is on - off). When =0 indicates that + * the RX EEE LPI Status Falling Edge Detec indication is enabled (Rx EEE + * LPI is on - off). This bit is applicable only in the EXIT Events Masks + * registers. [17] - L1 Status Edge Detect Mask. When =1 indicates that the + * L1 Status Falling Edge Detect indication from the PCIE CORE is disabled + * (L1 is on - off). When =0 indicates that the L1 Status Falling Edge + * Detect indication from the PCIE CORE is enabled (L1 is on - off). This + * bit is applicable only in the EXIT Events Masks registers.Clock 25MHz. + * Reset on hard reset. */ +#define MISC_REG_CPMU_LP_MASK_EXT_P0 0xa888 +/* [RW 16] EEE LPI Entry Events Counter. A statistic counter with the number + * of counts that the SM entered the EEE LPI state. Clock 25MHz. Read only + * register. Reset on hard reset. */ +#define MISC_REG_CPMU_LP_SM_ENT_CNT_P0 0xa8b8 /* [RW 32] The following driver registers(1...16) represent 16 drivers and 32 clients. Each client can be controlled by one driver only. One in each bit represent that this driver control the appropriate client (Ex: bit 5 @@ -5372,6 +5487,8 @@ /* [RW 32] Lower 48 bits of ctrl_sa register. Used as the SA in PAUSE/PFC * packets transmitted by the MAC */ #define XMAC_REG_CTRL_SA_LO 0x28 +#define XMAC_REG_EEE_CTRL 0xd8 +#define XMAC_REG_EEE_TIMERS_HI 0xe4 #define XMAC_REG_PAUSE_CTRL 0x68 #define XMAC_REG_PFC_CTRL 0x70 #define XMAC_REG_PFC_CTRL_HI 0x74 @@ -6813,6 +6930,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_LP_AUTO_NEG 0x0013 #define MDIO_AN_REG_LP_AUTO_NEG2 0x0014 #define MDIO_AN_REG_MASTER_STATUS 0x0021 +#define MDIO_AN_REG_EEE_ADV 0x003c +#define MDIO_AN_REG_LP_EEE_ADV 0x003d /*bcm*/ #define MDIO_AN_REG_LINK_STATUS 0x8304 #define MDIO_AN_REG_CL37_CL73 0x8370 @@ -6866,6 +6985,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080 /* BCM84833 only */ +#define MDIO_84833_TOP_CFG_FW_REV 0x400f +#define MDIO_84833_TOP_CFG_FW_EEE 0x10b1 #define MDIO_84833_TOP_CFG_XGPHY_STRAP1 0x401a #define MDIO_84833_SUPER_ISOLATE 0x8000 /* These are mailbox register set used by 84833. */ @@ -6993,11 +7114,13 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_WC_REG_DIGITAL3_UP1 0x8329 #define MDIO_WC_REG_DIGITAL3_LP_UP1 0x832c #define MDIO_WC_REG_DIGITAL4_MISC3 0x833c +#define MDIO_WC_REG_DIGITAL4_MISC5 0x833e #define MDIO_WC_REG_DIGITAL5_MISC6 0x8345 #define MDIO_WC_REG_DIGITAL5_MISC7 0x8349 #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED 0x834e #define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL 0x8350 #define MDIO_WC_REG_CL49_USERB0_CTRL 0x8368 +#define MDIO_WC_REG_EEE_COMBO_CONTROL0 0x8390 #define MDIO_WC_REG_TX66_CONTROL 0x83b0 #define MDIO_WC_REG_RX66_CONTROL 0x83c0 #define MDIO_WC_REG_RX66_SCW0 0x83c2 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 1e2785cd11d0..0e8bdcb9c748 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -785,6 +785,10 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) pstats->host_port_stats_counter++; + if (CHIP_IS_E3(bp)) + estats->eee_tx_lpi += REG_RD(bp, + MISC_REG_CPMU_LP_SM_ENT_CNT_P0); + if (!BP_NOMCP(bp)) { u32 nig_timer_max = SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 93e689fdfeda..24b8e505b60c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -203,6 +203,8 @@ struct bnx2x_eth_stats { /* Recovery */ u32 recoverable_error; u32 unrecoverable_error; + /* src: Clear-on-Read register; Will not survive PMF Migration */ + u32 eee_tx_lpi; }; -- GitLab From e9939c80e9cb51f0da7d6e70838fd6c90248439f Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 6 Jun 2012 17:13:08 +0000 Subject: [PATCH 0928/6849] bnx2x: Added EEE Ethtool support. This patch extends the bnx2x's ethtool interface to enable control in the eee feature, as well as report statistic information about it. Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index ddc18ee5c5ae..bf30e2829285 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -177,6 +177,8 @@ static const struct { 4, STATS_FLAGS_FUNC, "recoverable_errors" }, { STATS_OFFSET32(unrecoverable_error), 4, STATS_FLAGS_FUNC, "unrecoverable_errors" }, + { STATS_OFFSET32(eee_tx_lpi), + 4, STATS_FLAGS_PORT, "Tx LPI entry count"} }; #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) @@ -1543,6 +1545,136 @@ static const struct { { "idle check (online)" } }; +static u32 bnx2x_eee_to_adv(u32 eee_adv) +{ + u32 modes = 0; + + if (eee_adv & SHMEM_EEE_100M_ADV) + modes |= ADVERTISED_100baseT_Full; + if (eee_adv & SHMEM_EEE_1G_ADV) + modes |= ADVERTISED_1000baseT_Full; + if (eee_adv & SHMEM_EEE_10G_ADV) + modes |= ADVERTISED_10000baseT_Full; + + return modes; +} + +static u32 bnx2x_adv_to_eee(u32 modes, u32 shift) +{ + u32 eee_adv = 0; + if (modes & ADVERTISED_100baseT_Full) + eee_adv |= SHMEM_EEE_100M_ADV; + if (modes & ADVERTISED_1000baseT_Full) + eee_adv |= SHMEM_EEE_1G_ADV; + if (modes & ADVERTISED_10000baseT_Full) + eee_adv |= SHMEM_EEE_10G_ADV; + + return eee_adv << shift; +} + +static int bnx2x_get_eee(struct net_device *dev, struct ethtool_eee *edata) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 eee_cfg; + + if (!SHMEM2_HAS(bp, eee_status[BP_PORT(bp)])) { + DP(BNX2X_MSG_ETHTOOL, "BC Version does not support EEE\n"); + return -EOPNOTSUPP; + } + + eee_cfg = SHMEM2_RD(bp, eee_status[BP_PORT(bp)]); + + edata->supported = + bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_SUPPORTED_MASK) >> + SHMEM_EEE_SUPPORTED_SHIFT); + + edata->advertised = + bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_ADV_STATUS_MASK) >> + SHMEM_EEE_ADV_STATUS_SHIFT); + edata->lp_advertised = + bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_LP_ADV_STATUS_MASK) >> + SHMEM_EEE_LP_ADV_STATUS_SHIFT); + + /* SHMEM value is in 16u units --> Convert to 1u units. */ + edata->tx_lpi_timer = (eee_cfg & SHMEM_EEE_TIMER_MASK) << 4; + + edata->eee_enabled = (eee_cfg & SHMEM_EEE_REQUESTED_BIT) ? 1 : 0; + edata->eee_active = (eee_cfg & SHMEM_EEE_ACTIVE_BIT) ? 1 : 0; + edata->tx_lpi_enabled = (eee_cfg & SHMEM_EEE_LPI_REQUESTED_BIT) ? 1 : 0; + + return 0; +} + +static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 eee_cfg; + u32 advertised; + + if (IS_MF(bp)) + return 0; + + if (!SHMEM2_HAS(bp, eee_status[BP_PORT(bp)])) { + DP(BNX2X_MSG_ETHTOOL, "BC Version does not support EEE\n"); + return -EOPNOTSUPP; + } + + eee_cfg = SHMEM2_RD(bp, eee_status[BP_PORT(bp)]); + + if (!(eee_cfg & SHMEM_EEE_SUPPORTED_MASK)) { + DP(BNX2X_MSG_ETHTOOL, "Board does not support EEE!\n"); + return -EOPNOTSUPP; + } + + advertised = bnx2x_adv_to_eee(edata->advertised, + SHMEM_EEE_ADV_STATUS_SHIFT); + if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { + DP(BNX2X_MSG_ETHTOOL, + "Direct manipulation of EEE advertisment is not supported\n"); + return -EINVAL; + } + + if (edata->tx_lpi_timer > EEE_MODE_TIMER_MASK) { + DP(BNX2X_MSG_ETHTOOL, + "Maximal Tx Lpi timer supported is %x(u)\n", + EEE_MODE_TIMER_MASK); + return -EINVAL; + } + if (edata->tx_lpi_enabled && + (edata->tx_lpi_timer < EEE_MODE_NVRAM_AGGRESSIVE_TIME)) { + DP(BNX2X_MSG_ETHTOOL, + "Minimal Tx Lpi timer supported is %d(u)\n", + EEE_MODE_NVRAM_AGGRESSIVE_TIME); + return -EINVAL; + } + + /* All is well; Apply changes*/ + if (edata->eee_enabled) + bp->link_params.eee_mode |= EEE_MODE_ADV_LPI; + else + bp->link_params.eee_mode &= ~EEE_MODE_ADV_LPI; + + if (edata->tx_lpi_enabled) + bp->link_params.eee_mode |= EEE_MODE_ENABLE_LPI; + else + bp->link_params.eee_mode &= ~EEE_MODE_ENABLE_LPI; + + bp->link_params.eee_mode &= ~EEE_MODE_TIMER_MASK; + bp->link_params.eee_mode |= (edata->tx_lpi_timer & + EEE_MODE_TIMER_MASK) | + EEE_MODE_OVERRIDE_NVRAM | + EEE_MODE_OUTPUT_TIME; + + /* Restart link to propogate changes */ + if (netif_running(dev)) { + bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_link_set(bp); + } + + return 0; +} + + enum { BNX2X_CHIP_E1_OFST = 0, BNX2X_CHIP_E1H_OFST, @@ -2472,6 +2604,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, .get_rxfh_indir = bnx2x_get_rxfh_indir, .set_rxfh_indir = bnx2x_set_rxfh_indir, + .get_eee = bnx2x_get_eee, + .set_eee = bnx2x_set_eee, }; void bnx2x_set_ethtool_ops(struct net_device *netdev) -- GitLab From ccf7e72b54253f926a35fdfa0366e0cb9ba72ffd Mon Sep 17 00:00:00 2001 From: Hong zhi guo Date: Wed, 6 Jun 2012 22:36:27 +0000 Subject: [PATCH 0929/6849] macvtap: use prepare_to_wait/finish_wait to ensure mb instead of raw assignment to current->state Signed-off-by: Hong Zhiguo Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 2ee56de7b0ca..0737bd4d1669 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -847,13 +847,12 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, const struct iovec *iv, unsigned long len, int noblock) { - DECLARE_WAITQUEUE(wait, current); + DEFINE_WAIT(wait); struct sk_buff *skb; ssize_t ret = 0; - add_wait_queue(sk_sleep(&q->sk), &wait); while (len) { - current->state = TASK_INTERRUPTIBLE; + prepare_to_wait(sk_sleep(&q->sk), &wait, TASK_INTERRUPTIBLE); /* Read frames from the queue */ skb = skb_dequeue(&q->sk.sk_receive_queue); @@ -875,8 +874,7 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, break; } - current->state = TASK_RUNNING; - remove_wait_queue(sk_sleep(&q->sk), &wait); + finish_wait(sk_sleep(&q->sk), &wait); return ret; } -- GitLab From 1578e7778fa04eb7e32da561effee6cd38139b0f Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Thu, 7 Jun 2012 04:37:08 +0000 Subject: [PATCH 0930/6849] be2net: Fix driver load for VFs for Lancer Permanent MAC is wrongly supplied in create iface command. Call the command with no MAC address and then MAC address should be later queried and applied. Signed-off-by: Padmanabh Ratnakar Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 21 ++--- drivers/net/ethernet/emulex/benet/be_cmds.h | 8 +- drivers/net/ethernet/emulex/benet/be_main.c | 98 +++++++++++---------- 3 files changed, 66 insertions(+), 61 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 8d06ea381741..f8997521b147 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1132,7 +1132,7 @@ err: * Uses MCCQ */ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, - u8 *mac, u32 *if_handle, u32 *pmac_id, u32 domain) + u32 *if_handle, u32 domain) { struct be_mcc_wrb *wrb; struct be_cmd_req_if_create *req; @@ -1152,17 +1152,13 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, req->hdr.domain = domain; req->capability_flags = cpu_to_le32(cap_flags); req->enable_flags = cpu_to_le32(en_flags); - if (mac) - memcpy(req->mac_addr, mac, ETH_ALEN); - else - req->pmac_invalid = true; + + req->pmac_invalid = true; status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_if_create *resp = embedded_payload(wrb); *if_handle = le32_to_cpu(resp->interface_id); - if (mac) - *pmac_id = le32_to_cpu(resp->pmac_id); } err: @@ -2330,8 +2326,8 @@ err: } /* Uses synchronous MCCQ */ -int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, - bool *pmac_id_active, u32 *pmac_id, u8 *mac) +int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, + bool *pmac_id_active, u32 *pmac_id, u8 domain) { struct be_mcc_wrb *wrb; struct be_cmd_req_get_mac_list *req; @@ -2376,8 +2372,9 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, get_mac_list_cmd.va; mac_count = resp->true_mac_count + resp->pseudo_mac_count; /* Mac list returned could contain one or more active mac_ids - * or one or more pseudo permanant mac addresses. If an active - * mac_id is present, return first active mac_id found + * or one or more true or pseudo permanant mac addresses. + * If an active mac_id is present, return first active mac_id + * found. */ for (i = 0; i < mac_count; i++) { struct get_list_macaddr *mac_entry; @@ -2396,7 +2393,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, goto out; } } - /* If no active mac_id found, return first pseudo mac addr */ + /* If no active mac_id found, return first mac addr */ *pmac_id_active = false; memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr, ETH_ALEN); diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 9625bf420c16..2f6bb06df9c6 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1664,8 +1664,7 @@ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 domain); extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, - u32 en_flags, u8 *mac, u32 *if_handle, u32 *pmac_id, - u32 domain); + u32 en_flags, u32 *if_handle, u32 domain); extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle, u32 domain); extern int be_cmd_eq_create(struct be_adapter *adapter, @@ -1751,8 +1750,9 @@ extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); extern int be_cmd_req_native_mode(struct be_adapter *adapter); extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); -extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, - bool *pmac_id_active, u32 *pmac_id, u8 *mac); +extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, + bool *pmac_id_active, u32 *pmac_id, + u8 domain); extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, u8 mac_count, u32 domain); extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index f29827f657eb..896f283967d4 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2601,8 +2601,8 @@ static int be_vf_setup(struct be_adapter *adapter) cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; for_all_vfs(adapter, vf_cfg, vf) { - status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL, - &vf_cfg->if_handle, NULL, vf + 1); + status = be_cmd_if_create(adapter, cap_flags, en_flags, + &vf_cfg->if_handle, vf + 1); if (status) goto err; } @@ -2642,29 +2642,43 @@ static void be_setup_init(struct be_adapter *adapter) adapter->phy.forced_port_speed = -1; } -static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac) +static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle, + bool *active_mac, u32 *pmac_id) { - u32 pmac_id; - int status; - bool pmac_id_active; + int status = 0; - status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active, - &pmac_id, mac); - if (status != 0) - goto do_none; + if (!is_zero_ether_addr(adapter->netdev->perm_addr)) { + memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN); + if (!lancer_chip(adapter) && !be_physfn(adapter)) + *active_mac = true; + else + *active_mac = false; - if (pmac_id_active) { - status = be_cmd_mac_addr_query(adapter, mac, - MAC_ADDRESS_TYPE_NETWORK, - false, adapter->if_handle, pmac_id); + return status; + } - if (!status) - adapter->pmac_id[0] = pmac_id; + if (lancer_chip(adapter)) { + status = be_cmd_get_mac_from_list(adapter, mac, + active_mac, pmac_id, 0); + if (*active_mac) { + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, + false, if_handle, + *pmac_id); + } + } else if (be_physfn(adapter)) { + /* For BE3, for PF get permanent MAC */ + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, true, + 0, 0); + *active_mac = false; } else { - status = be_cmd_pmac_add(adapter, mac, - adapter->if_handle, &adapter->pmac_id[0], 0); + /* For BE3, for VF get soft MAC assigned by PF*/ + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, false, + if_handle, 0); + *active_mac = true; } -do_none: return status; } @@ -2685,12 +2699,12 @@ static int be_get_config(struct be_adapter *adapter) static int be_setup(struct be_adapter *adapter) { - struct net_device *netdev = adapter->netdev; struct device *dev = &adapter->pdev->dev; u32 cap_flags, en_flags; u32 tx_fc, rx_fc; int status; u8 mac[ETH_ALEN]; + bool active_mac; be_setup_init(adapter); @@ -2716,14 +2730,6 @@ static int be_setup(struct be_adapter *adapter) if (status) goto err; - memset(mac, 0, ETH_ALEN); - status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, - true /*permanent */, 0, 0); - if (status) - return status; - memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); - memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); - en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | @@ -2733,27 +2739,29 @@ static int be_setup(struct be_adapter *adapter) cap_flags |= BE_IF_FLAGS_RSS; en_flags |= BE_IF_FLAGS_RSS; } + status = be_cmd_if_create(adapter, cap_flags, en_flags, - netdev->dev_addr, &adapter->if_handle, - &adapter->pmac_id[0], 0); + &adapter->if_handle, 0); if (status != 0) goto err; - /* The VF's permanent mac queried from card is incorrect. - * For BEx: Query the mac configued by the PF using if_handle - * For Lancer: Get and use mac_list to obtain mac address. - */ - if (!be_physfn(adapter)) { - if (lancer_chip(adapter)) - status = be_add_mac_from_list(adapter, mac); - else - status = be_cmd_mac_addr_query(adapter, mac, - MAC_ADDRESS_TYPE_NETWORK, false, - adapter->if_handle, 0); - if (!status) { - memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); - memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); - } + memset(mac, 0, ETH_ALEN); + active_mac = false; + status = be_get_mac_addr(adapter, mac, adapter->if_handle, + &active_mac, &adapter->pmac_id[0]); + if (status != 0) + goto err; + + if (!active_mac) { + status = be_cmd_pmac_add(adapter, mac, adapter->if_handle, + &adapter->pmac_id[0], 0); + if (status != 0) + goto err; + } + + if (is_zero_ether_addr(adapter->netdev->dev_addr)) { + memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); + memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); } status = be_tx_qs_create(adapter); -- GitLab From 715c85b1fc824e9cd0ea07d6ceb80d2262f32e90 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 7 Jun 2012 13:32:04 -0700 Subject: [PATCH 0931/6849] x86, cpu: Rename checking_wrmsrl() to wrmsrl_safe() Rename checking_wrmsrl() to wrmsrl_safe(), to match the naming convention used by all the other MSR access functions/macros. Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/msr.h | 2 +- arch/x86/kernel/cpu/amd.c | 4 ++-- arch/x86/kernel/cpu/perf_event.c | 2 +- arch/x86/kernel/cpu/perf_event_intel.c | 6 +++--- arch/x86/kernel/cpu/perf_event_p4.c | 14 +++++++------- arch/x86/kernel/cpu/perf_event_p6.c | 4 ++-- arch/x86/kernel/process_64.c | 4 ++-- arch/x86/vdso/vdso32-setup.c | 6 +++--- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index cb33b5f00267..fe83d74a920d 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -211,7 +211,7 @@ do { \ #endif /* !CONFIG_PARAVIRT */ -#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ +#define wrmsrl_safe(msr, val) wrmsr_safe((msr), (u32)(val), \ (u32)((val) >> 32)) #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index c928eb26ada6..9d92e19039f0 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -621,7 +621,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) if (!rdmsrl_safe(0xc0011005, &val)) { val |= 1ULL << 54; - checking_wrmsrl(0xc0011005, val); + wrmsrl_safe(0xc0011005, val); rdmsrl(0xc0011005, val); if (val & (1ULL << 54)) { set_cpu_cap(c, X86_FEATURE_TOPOEXT); @@ -712,7 +712,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); if (err == 0) { mask |= (1 << 10); - checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); + wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask); } } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index e049d6da0183..4e3ba9cb5a4e 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -222,7 +222,7 @@ static bool check_hw_exists(void) * that don't trap on the MSR access and always return 0s. */ val = 0xabcdUL; - ret = checking_wrmsrl(x86_pmu_event_addr(0), val); + ret = wrmsrl_safe(x86_pmu_event_addr(0), val); ret |= rdmsrl_safe(x86_pmu_event_addr(0), &val_new); if (ret || val != val_new) goto msr_fail; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 166546ec6aef..7789aa37c746 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1003,11 +1003,11 @@ static void intel_pmu_reset(void) printk("clearing PMU state on CPU#%d\n", smp_processor_id()); for (idx = 0; idx < x86_pmu.num_counters; idx++) { - checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); - checking_wrmsrl(x86_pmu_event_addr(idx), 0ull); + wrmsrl_safe(x86_pmu_config_addr(idx), 0ull); + wrmsrl_safe(x86_pmu_event_addr(idx), 0ull); } for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) - checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); + wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); if (ds) ds->bts_index = ds->bts_buffer_base; diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 47124a73dd73..6c82e4037989 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -895,8 +895,8 @@ static void p4_pmu_disable_pebs(void) * So at moment let leave metrics turned on forever -- it's * ok for now but need to be revisited! * - * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0); - * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0); + * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)0); + * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)0); */ } @@ -909,7 +909,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) * state we need to clear P4_CCCR_OVF, otherwise interrupt get * asserted again and again */ - (void)checking_wrmsrl(hwc->config_base, + (void)wrmsrl_safe(hwc->config_base, (u64)(p4_config_unpack_cccr(hwc->config)) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); } @@ -943,8 +943,8 @@ static void p4_pmu_enable_pebs(u64 config) bind = &p4_pebs_bind_map[idx]; - (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); - (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); + (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); + (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); } static void p4_pmu_enable_event(struct perf_event *event) @@ -978,8 +978,8 @@ static void p4_pmu_enable_event(struct perf_event *event) */ p4_pmu_enable_pebs(hwc->config); - (void)checking_wrmsrl(escr_addr, escr_conf); - (void)checking_wrmsrl(hwc->config_base, + (void)wrmsrl_safe(escr_addr, escr_conf); + (void)wrmsrl_safe(hwc->config_base, (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); } diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 32bcfc7dd230..e4dd0f7a0453 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -71,7 +71,7 @@ p6_pmu_disable_event(struct perf_event *event) if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)checking_wrmsrl(hwc->config_base, val); + (void)wrmsrl_safe(hwc->config_base, val); } static void p6_pmu_enable_event(struct perf_event *event) @@ -84,7 +84,7 @@ static void p6_pmu_enable_event(struct perf_event *event) if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)checking_wrmsrl(hwc->config_base, val); + (void)wrmsrl_safe(hwc->config_base, val); } PMU_FORMAT_ATTR(event, "config:0-7" ); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 61cdf7fdf099..3e215ba68766 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -466,7 +466,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) task->thread.gs = addr; if (doit) { load_gs_index(0); - ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); + ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr); } } put_cpu(); @@ -494,7 +494,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) /* set the selector to 0 to not confuse __switch_to */ loadsegment(fs, 0); - ret = checking_wrmsrl(MSR_FS_BASE, addr); + ret = wrmsrl_safe(MSR_FS_BASE, addr); } } put_cpu(); diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index 66e6d9359826..0faad646f5fd 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c @@ -205,9 +205,9 @@ void syscall32_cpu_init(void) { /* Load these always in case some future AMD CPU supports SYSENTER from compat mode too. */ - checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); - checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); - checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); + wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); + wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); + wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); wrmsrl(MSR_CSTAR, ia32_cstar_target); } -- GitLab From a265367ccbe72010757a56e5776fcf9a49370181 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 31 May 2012 14:47:46 +0100 Subject: [PATCH 0932/6849] ASoC: max98095: Staticise non-exported functions and export jack detect Signed-off-by: Mark Brown --- sound/soc/codecs/max98095.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 35179e2c23c9..7cd508e16a5c 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2216,7 +2216,7 @@ static irqreturn_t max98095_report_jack(int irq, void *data) return IRQ_HANDLED; } -int max98095_jack_detect_enable(struct snd_soc_codec *codec) +static int max98095_jack_detect_enable(struct snd_soc_codec *codec) { struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); int ret = 0; @@ -2245,7 +2245,7 @@ int max98095_jack_detect_enable(struct snd_soc_codec *codec) return ret; } -int max98095_jack_detect_disable(struct snd_soc_codec *codec) +static int max98095_jack_detect_disable(struct snd_soc_codec *codec) { int ret = 0; @@ -2286,6 +2286,7 @@ int max98095_jack_detect(struct snd_soc_codec *codec, max98095_report_jack(client->irq, codec); return 0; } +EXPORT_SYMBOL_GPL(max98095_jack_detect); #ifdef CONFIG_PM static int max98095_suspend(struct snd_soc_codec *codec) -- GitLab From 40820105d4caef1489edd56e9dc2b85871b65308 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 7 Jun 2012 15:38:37 +0300 Subject: [PATCH 0933/6849] ASoC: isabelle: using an uninitialized variable We should set "isabelle_regmap" before using it. GCC complains. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- sound/soc/codecs/isabelle.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index bcc77ef0eda2..0d62f3b0f474 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1126,8 +1126,6 @@ static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, struct regmap *isabelle_regmap; int ret = 0; - i2c_set_clientdata(i2c, isabelle_regmap); - isabelle_regmap = devm_regmap_init_i2c(i2c, &isabelle_regmap_config); if (IS_ERR(isabelle_regmap)) { ret = PTR_ERR(isabelle_regmap); @@ -1135,6 +1133,7 @@ static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, ret); return ret; } + i2c_set_clientdata(i2c, isabelle_regmap); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_isabelle, isabelle_dai, -- GitLab From d392dead724935ad45c42e1a802d0f1de478c0d2 Mon Sep 17 00:00:00 2001 From: M R Swami Reddy Date: Thu, 7 Jun 2012 18:37:54 +0530 Subject: [PATCH 0934/6849] ASoC: MAINTAINERS: Add maintainer for TI Isabelle Audio driver Vishwas and I support the TI Isabelle audio driver. Signed-off-by: Vishwas A Deshpande Signed-off-by: M R Swami Reddy Signed-off-by: Mark Brown --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 55f0fda602ec..d0526640f717 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6723,9 +6723,11 @@ F: include/linux/tifm.h TI LM49xxx FAMILY ASoC CODEC DRIVERS M: M R Swami Reddy +M: Vishwas A Deshpande L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained F: sound/soc/codecs/lm49453* +F: sound/soc/codecs/isabelle* TI TWL4030 SERIES SOC CODEC DRIVER M: Peter Ujfalusi -- GitLab From 9515c1010c98347ec92d923bd3e23793fa6dc6fe Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Jun 2012 17:15:07 -0600 Subject: [PATCH 0935/6849] ASoC: tegra: add .stream_name to CPU DAIs This is certainly required if the I2S and SPDIF controllers are converted to be CODECs, and is probably good practice irrespective. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 2 ++ sound/soc/tegra/tegra20_spdif.c | 1 + sound/soc/tegra/tegra30_i2s.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0c7af63d444b..9d5d4704da29 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -261,12 +261,14 @@ static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = { static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { .probe = tegra20_i2s_probe, .playback = { + .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { + .stream_name = "Capture", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index f9b57418bd08..ffbd99c4106e 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -181,6 +181,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { .name = DRV_NAME, .probe = tegra20_spdif_probe, .playback = { + .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 8596032985dc..9c5c0e6819eb 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -320,12 +320,14 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { .probe = tegra30_i2s_probe, .playback = { + .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { + .stream_name = "Capture", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, -- GitLab From 408dafc4235e393036708126057e4d643f579486 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Jun 2012 17:15:48 -0600 Subject: [PATCH 0936/6849] ASoC: tegra: statically define DAI link format Define the DAI format statically in the dai_link, rather than executing code to set it each time the hw params are set. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 22 +++------------------- sound/soc/tegra/trimslice.c | 22 +++------------------- 2 files changed, 6 insertions(+), 38 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 1fd71e5a9eb9..087d3d8d6c06 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -58,7 +58,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); @@ -86,24 +85,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, return err; } - err = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (err < 0) { - dev_err(card->dev, "codec_dai fmt not set\n"); - return err; - } - - err = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (err < 0) { - dev_err(card->dev, "cpu_dai fmt not set\n"); - return err; - } - err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { @@ -240,6 +221,9 @@ static struct snd_soc_dai_link tegra_wm8903_dai = { .codec_dai_name = "wm8903-hifi", .init = tegra_wm8903_init, .ops = &tegra_wm8903_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, }; static struct snd_soc_card snd_soc_tegra_wm8903 = { diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 5815430e8521..62bb805022dd 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -52,7 +52,6 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); @@ -68,24 +67,6 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream, return err; } - err = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (err < 0) { - dev_err(card->dev, "codec_dai fmt not set\n"); - return err; - } - - err = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (err < 0) { - dev_err(card->dev, "cpu_dai fmt not set\n"); - return err; - } - err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { @@ -121,6 +102,9 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { .cpu_dai_name = "tegra20-i2s.0", .codec_dai_name = "tlv320aic23-hifi", .ops = &trimslice_asoc_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, }; static struct snd_soc_card snd_soc_trimslice = { -- GitLab From 40db77a0c4223d0b87c4b61ae38760d47593b7a5 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Jun 2012 17:15:49 -0600 Subject: [PATCH 0937/6849] ASoC: tegra: remove usage of rtd->codec rtd->codec_dai->codec can be used instead. This is a slight step along the way to not needing the rtd->codec field any more. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_alc5632.c | 5 +++-- sound/soc/tegra/tegra_wm8753.c | 2 +- sound/soc/tegra/tegra_wm8903.c | 5 +++-- sound/soc/tegra/trimslice.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 417b09b83fdf..d684df294c0c 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -43,7 +43,7 @@ static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); int srate, mclk; @@ -105,7 +105,8 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = { static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 02bd5a8e8544..ea9166d5c4eb 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -57,7 +57,7 @@ static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 087d3d8d6c06..08b5fef67b31 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -58,7 +58,7 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; @@ -181,7 +181,8 @@ static const struct snd_kcontrol_new tegra_wm8903_controls[] = { static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 62bb805022dd..e69a4f7000d6 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -52,7 +52,7 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); int srate, mclk; -- GitLab From c92a40e3a163b6708e0dd82ba4612f79df846912 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Jun 2012 17:15:05 -0600 Subject: [PATCH 0938/6849] ASoC: tegra: use DAI's not card's dev for dev_err This is the actual device of the I2S or SPDIF controller reporting the problem. If a future change converts these controllers to be CODECs, then there may be no pcm associated with the substream, so this change avoids a crash. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 2 +- sound/soc/tegra/tegra20_spdif.c | 2 +- sound/soc/tegra/tegra30_i2s.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 9d5d4704da29..647daf610e4a 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -138,7 +138,7 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct device *dev = substream->pcm->card->dev; + struct device *dev = dai->dev; struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); u32 reg; int ret, sample_size, srate, i2sclock, bitcnt; diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index ffbd99c4106e..f774a2d5e585 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -77,7 +77,7 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct device *dev = substream->pcm->card->dev; + struct device *dev = dai->dev; struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); int ret, spdifclock; diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 9c5c0e6819eb..2327f62e8a8c 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -181,7 +181,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct device *dev = substream->pcm->card->dev; + struct device *dev = dai->dev; struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); u32 val; int ret, sample_size, srate, i2sclock, bitcnt; -- GitLab From 0f163546a772d62250f59bad6a9338a0e3a2605c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 6 Jun 2012 17:15:06 -0600 Subject: [PATCH 0939/6849] ASoC: tegra: use regmap more directly Stop open-coding the caching of the ctrl registers; instead, use regmap_update_bits() to update parts of the register from different places. The removal of the open-coded cache will allow controls to be created which touch registers, which will be necessary if any of these modules are converted to CODECs. Get rid of tegra*_read/write; just call regmap_read/write directly. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 90 ++++++++++++++++----------------- sound/soc/tegra/tegra20_i2s.h | 1 - sound/soc/tegra/tegra20_spdif.c | 33 +++++------- sound/soc/tegra/tegra20_spdif.h | 1 - sound/soc/tegra/tegra30_i2s.c | 81 +++++++++++++++-------------- sound/soc/tegra/tegra30_i2s.h | 1 - 6 files changed, 95 insertions(+), 112 deletions(-) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 647daf610e4a..c5fc6b1404f6 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -46,18 +46,6 @@ #define DRV_NAME "tegra20-i2s" -static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val) -{ - regmap_write(i2s->regmap, reg, val); -} - -static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg) -{ - u32 val; - regmap_read(i2s->regmap, reg, &val); - return val; -} - static int tegra20_i2s_runtime_suspend(struct device *dev) { struct tegra20_i2s *i2s = dev_get_drvdata(dev); @@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); + unsigned int mask, val; switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: @@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, return -EINVAL; } - i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; + mask = TEGRA20_I2S_CTRL_MASTER_ENABLE; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; + val = TEGRA20_I2S_CTRL_MASTER_ENABLE; break; case SND_SOC_DAIFMT_CBM_CFM: break; @@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, return -EINVAL; } - i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | - TEGRA20_I2S_CTRL_LRCK_MASK); + mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | + TEGRA20_I2S_CTRL_LRCK_MASK; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_A: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; + val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; break; case SND_SOC_DAIFMT_DSP_B: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; + val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; + val |= TEGRA20_I2S_CTRL_LRCK_R_LOW; break; case SND_SOC_DAIFMT_I2S: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; + val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; break; case SND_SOC_DAIFMT_RIGHT_J: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; + val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; break; case SND_SOC_DAIFMT_LEFT_J: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; + val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; break; default: return -EINVAL; } + regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); + return 0; } @@ -140,27 +131,32 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, { struct device *dev = dai->dev; struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); - u32 reg; + unsigned int mask, val; int ret, sample_size, srate, i2sclock, bitcnt; - i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; + mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; + val = TEGRA20_I2S_CTRL_BIT_SIZE_16; sample_size = 16; break; case SNDRV_PCM_FORMAT_S24_LE: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; + val = TEGRA20_I2S_CTRL_BIT_SIZE_24; sample_size = 24; break; case SNDRV_PCM_FORMAT_S32_LE: - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; + val = TEGRA20_I2S_CTRL_BIT_SIZE_32; sample_size = 32; break; default: return -EINVAL; } + mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK; + val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; + + regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); + srate = params_rate(params); /* Final "* 2" required by Tegra hardware */ @@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, bitcnt = (i2sclock / (2 * srate)) - 1; if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) return -EINVAL; - reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; + val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; if (i2sclock % (2 * srate)) - reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; + val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; - tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); + regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val); - tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, - TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | - TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); + regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR, + TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | + TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); return 0; } static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) { - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; - tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, + TEGRA20_I2S_CTRL_FIFO1_ENABLE, + TEGRA20_I2S_CTRL_FIFO1_ENABLE); } static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) { - i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; - tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, + TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0); } static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) { - i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; - tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, + TEGRA20_I2S_CTRL_FIFO2_ENABLE, + TEGRA20_I2S_CTRL_FIFO2_ENABLE); } static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) { - i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; - tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, + TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0); } static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, @@ -414,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) i2s->playback_dma_data.width = 32; i2s->playback_dma_data.req_sel = dma_ch; - i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; - pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra20_i2s_runtime_resume(&pdev->dev); diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h index a57efc6a597e..c27069d24d77 100644 --- a/sound/soc/tegra/tegra20_i2s.h +++ b/sound/soc/tegra/tegra20_i2s.h @@ -158,7 +158,6 @@ struct tegra20_i2s { struct tegra_pcm_dma_params capture_dma_data; struct tegra_pcm_dma_params playback_dma_data; struct regmap *regmap; - u32 reg_ctrl; }; #endif diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index f774a2d5e585..5c33c618929d 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -37,19 +37,6 @@ #define DRV_NAME "tegra20-spdif" -static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg, - u32 val) -{ - regmap_write(spdif->regmap, reg, val); -} - -static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg) -{ - u32 val; - regmap_read(spdif->regmap, reg, &val); - return val; -} - static int tegra20_spdif_runtime_suspend(struct device *dev) { struct tegra20_spdif *spdif = dev_get_drvdata(dev); @@ -79,19 +66,22 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, { struct device *dev = dai->dev; struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); + unsigned int mask, val; int ret, spdifclock; - spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; - spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; + mask = TEGRA20_SPDIF_CTRL_PACK | + TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; - spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; + val = TEGRA20_SPDIF_CTRL_PACK | + TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; break; default: return -EINVAL; } + regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val); + switch (params_rate(params)) { case 32000: spdifclock = 4096000; @@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) { - spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; - tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); + regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, + TEGRA20_SPDIF_CTRL_TX_EN, + TEGRA20_SPDIF_CTRL_TX_EN); } static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) { - spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; - tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); + regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, + TEGRA20_SPDIF_CTRL_TX_EN, 0); } static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h index ed756527efea..b48d699fd583 100644 --- a/sound/soc/tegra/tegra20_spdif.h +++ b/sound/soc/tegra/tegra20_spdif.h @@ -465,7 +465,6 @@ struct tegra20_spdif { struct tegra_pcm_dma_params capture_dma_data; struct tegra_pcm_dma_params playback_dma_data; struct regmap *regmap; - u32 reg_ctrl; }; #endif diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 2327f62e8a8c..b68e27a14608 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -44,18 +44,6 @@ #define DRV_NAME "tegra30-i2s" -static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val) -{ - regmap_write(i2s->regmap, reg, val); -} - -static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg) -{ - u32 val; - regmap_read(i2s->regmap, reg, &val); - return val; -} - static int tegra30_i2s_runtime_suspend(struct device *dev) { struct tegra30_i2s *i2s = dev_get_drvdata(dev); @@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); + unsigned int mask, val; switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: @@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, return -EINVAL; } - i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; + mask = TEGRA30_I2S_CTRL_MASTER_ENABLE; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; + val = TEGRA30_I2S_CTRL_MASTER_ENABLE; break; case SND_SOC_DAIFMT_CBM_CFM: break; @@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, return -EINVAL; } - i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | - TEGRA30_I2S_CTRL_LRCK_MASK); + mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | + TEGRA30_I2S_CTRL_LRCK_MASK; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_A: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; + val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; break; case SND_SOC_DAIFMT_DSP_B: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; + val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; + val |= TEGRA30_I2S_CTRL_LRCK_R_LOW; break; case SND_SOC_DAIFMT_I2S: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; + val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; break; case SND_SOC_DAIFMT_RIGHT_J: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; + val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; break; case SND_SOC_DAIFMT_LEFT_J: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; + val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; + val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; break; default: return -EINVAL; } + pm_runtime_get_sync(dai->dev); + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); + pm_runtime_put(dai->dev); + return 0; } @@ -183,22 +176,24 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, { struct device *dev = dai->dev; struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); - u32 val; + unsigned int mask, val, reg; int ret, sample_size, srate, i2sclock, bitcnt; if (params_channels(params) != 2) return -EINVAL; - i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; + mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; + val = TEGRA30_I2S_CTRL_BIT_SIZE_16; sample_size = 16; break; default: return -EINVAL; } + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); + srate = params_rate(params); /* Final "* 2" required by Tegra hardware */ @@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, if (i2sclock % (2 * srate)) val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; - tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); + regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val); val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | @@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); + reg = TEGRA30_I2S_CIF_RX_CTRL; } else { val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); + reg = TEGRA30_I2S_CIF_RX_CTRL; } + regmap_write(i2s->regmap, reg, val); + val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); - tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); + regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val); return 0; } @@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) { tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, + TEGRA30_I2S_CTRL_XFER_EN_TX, + TEGRA30_I2S_CTRL_XFER_EN_TX); } static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) { tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); - i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, + TEGRA30_I2S_CTRL_XFER_EN_TX, 0); } static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) { tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, + TEGRA30_I2S_CTRL_XFER_EN_RX, + TEGRA30_I2S_CTRL_XFER_EN_RX); } static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) { tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); - i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, + TEGRA30_I2S_CTRL_XFER_EN_RX, 0); } static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index 91adf29c7a87..34dc47b9581c 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h @@ -236,7 +236,6 @@ struct tegra30_i2s { enum tegra30_ahub_txcif playback_fifo_cif; struct tegra_pcm_dma_params playback_dma_data; struct regmap *regmap; - u32 reg_ctrl; }; #endif -- GitLab From 5a6881e8e134ea636bbc8423049e84638dbb7106 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 10:05:14 +0800 Subject: [PATCH 0940/6849] regulator: core: Handle fixed voltage in map_voltage_linear Fixed voltage is a kind of linear mapping where n_voltages is 1. This change allows [list|map]_voltage_linear to be used for fixed voltage. For fixed voltage, n_voltages is 1 and the only valid selector is 0. Thus we actually don't care the uV_step setting. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8521e0d6b3bc..5c6aedaa934d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2070,6 +2070,14 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev, { int ret, voltage; + /* Allow uV_step to be 0 for fixed voltage */ + if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { + if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) + return 0; + else + return -EINVAL; + } + if (!rdev->desc->uV_step) { BUG_ON(!rdev->desc->uV_step); return -EINVAL; -- GitLab From 985f769c89aedcae2981080051fc85b4ed035a9b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 10:06:40 +0800 Subject: [PATCH 0941/6849] regulator: isl6271a: Use regulator_[list|map]_voltage_linear for isl_fixed_ops Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/isl6271a-regulator.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 56d273f25603..4a11b82a6d57 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -75,19 +75,13 @@ static struct regulator_ops isl_core_ops = { static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) { - int id = rdev_get_id(dev); - return (id == 1) ? 1100000 : 1300000; -} - -static int isl6271a_list_fixed_voltage(struct regulator_dev *dev, unsigned selector) -{ - int id = rdev_get_id(dev); - return (id == 1) ? 1100000 : 1300000; + return dev->desc->min_uV; } static struct regulator_ops isl_fixed_ops = { .get_voltage = isl6271a_get_fixed_voltage, - .list_voltage = isl6271a_list_fixed_voltage, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, }; static const struct regulator_desc isl_rd[] = { @@ -107,6 +101,7 @@ static const struct regulator_desc isl_rd[] = { .ops = &isl_fixed_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = 1100000, }, { .name = "LDO2", .id = 2, @@ -114,6 +109,7 @@ static const struct regulator_desc isl_rd[] = { .ops = &isl_fixed_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = 1300000, }, }; -- GitLab From ee3ed6effd8cc4c0cbfa35307cfc5fcec75b5e12 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 10:38:30 +0800 Subject: [PATCH 0942/6849] regulator: da903x: Don't read/write to DA9030_INVAL/DA9034_INVAL address For fixed voltage, DA9030_LDO13 and DA9034_LDO5, the info->vol_reg is DA9030_INVAL/DA9034_INVAL. It does not make sense to read/write to DA9030_INVAL/DA9034_INVAL address. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/da903x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 1005f5f7e603..36c5b92fe0af 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -107,6 +107,9 @@ static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; + if (rdev->desc->n_voltages == 1) + return -EINVAL; + val = selector << info->vol_shift; mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; @@ -120,6 +123,9 @@ static int da903x_get_voltage_sel(struct regulator_dev *rdev) uint8_t val, mask; int ret; + if (rdev->desc->n_voltages == 1) + return 0; + ret = da903x_read(da9034_dev, info->vol_reg, &val); if (ret) return ret; -- GitLab From 1acb645ebfe3a008e3c3350918d7d29974b1eaec Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 16:38:09 +0800 Subject: [PATCH 0943/6849] regulator: rc5t583: Simplify rc5t583_set_voltage_time_sel implementation For linear mappings, we can use below equation to get the voltage difference between new_selector and old_selector: abs(new_selector - old_selector) * rdev->desc->uV_step Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/rc5t583-regulator.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 1d34e64a1307..332eae897dab 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -70,18 +70,10 @@ static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); - int old_uV, new_uV; - old_uV = regulator_list_voltage_linear(rdev, old_selector); - if (old_uV < 0) - return old_uV; - - new_uV = regulator_list_voltage_linear(rdev, new_selector); - if (new_uV < 0) - return new_uV; - - return DIV_ROUND_UP(abs(old_uV - new_uV), - reg->reg_info->change_uv_per_us); + return DIV_ROUND_UP(abs(new_selector - old_selector) * + rdev->desc->uV_step, + reg->reg_info->change_uv_per_us); } -- GitLab From 999f0c7cb8e7c378bd1f3fcd56cf8dc5a30c83e4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 17:08:21 +0800 Subject: [PATCH 0944/6849] regulator: palmas: Clear PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK bits in palmas_set_mode_smps Current code actually clears more bits than PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK bits. Signed-off-by: Axel Lin Acked-by: Graeme Gregory Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index b4e10b0b36d4..1a0924d81b2a 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -257,8 +257,7 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) unsigned int reg; palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - reg &= ~PALMAS_SMPS12_CTRL_STATUS_MASK; - reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; + reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; switch (mode) { case REGULATOR_MODE_NORMAL: -- GitLab From fedd89b1aafd6b2bf7c0b4009fd616a02484ae80 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 6 Jun 2012 20:01:38 +0800 Subject: [PATCH 0945/6849] regulator: palmas: Slightly code change for better readability It's a little bit hard to read that the "else" case means id == PALMAS_REG_SMPS10. if (id != PALMAS_REG_SMPS10){ do something for the cases id != PALMAS_REG_SMPS10; } else { do something for the case id == PALMAS_REG_SMPS10; } This patch changes above syntax to switch statement. Signed-off-by: Axel Lin Acked-by: Graeme Gregory Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 1a0924d81b2a..55267bbfcd9c 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -516,7 +516,15 @@ static int palmas_smps_init(struct palmas *palmas, int id, if (ret) return ret; - if (id != PALMAS_REG_SMPS10) { + switch (id) { + case PALMAS_REG_SMPS10: + if (reg_init->mode_sleep) { + reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK; + reg |= reg_init->mode_sleep << + PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT; + } + break; + default: if (reg_init->warm_reset) reg |= PALMAS_SMPS12_CTRL_WR_S; @@ -528,14 +536,8 @@ static int palmas_smps_init(struct palmas *palmas, int id, reg |= reg_init->mode_sleep << PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT; } - } else { - if (reg_init->mode_sleep) { - reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK; - reg |= reg_init->mode_sleep << - PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT; - } - } + ret = palmas_smps_write(palmas, addr, reg); if (ret) return ret; @@ -659,10 +661,8 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].name = palmas_regs_info[id].name; pmic->desc[id].id = id; - if (id != PALMAS_REG_SMPS10) { - pmic->desc[id].ops = &palmas_ops_smps; - pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; - } else { + switch (id) { + case PALMAS_REG_SMPS10: pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; pmic->desc[id].ops = &palmas_ops_smps10; pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; @@ -671,6 +671,10 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].enable_mask = SMPS10_BOOST_EN; pmic->desc[id].min_uV = 3750000; pmic->desc[id].uV_step = 1250000; + break; + default: + pmic->desc[id].ops = &palmas_ops_smps; + pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; } pmic->desc[id].type = REGULATOR_VOLTAGE; -- GitLab From c49af95631a46e8a2664ae2067c900905c39f2b2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 6 Jun 2012 08:36:37 +0800 Subject: [PATCH 0946/6849] regulator: pcap: Convert to regulator_list_voltage_table Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/pcap-regulator.c | 95 +++++++++++++----------------- 1 file changed, 42 insertions(+), 53 deletions(-) diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 8211101121f0..68777acc099f 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -18,80 +18,80 @@ #include #include -static const u16 V1_table[] = { - 2775, 1275, 1600, 1725, 1825, 1925, 2075, 2275, +static const unsigned int V1_table[] = { + 2775000, 1275000, 1600000, 1725000, 1825000, 1925000, 2075000, 2275000, }; -static const u16 V2_table[] = { - 2500, 2775, +static const unsigned int V2_table[] = { + 2500000, 2775000, }; -static const u16 V3_table[] = { - 1075, 1275, 1550, 1725, 1876, 1950, 2075, 2275, +static const unsigned int V3_table[] = { + 1075000, 1275000, 1550000, 1725000, 1876000, 1950000, 2075000, 2275000, }; -static const u16 V4_table[] = { - 1275, 1550, 1725, 1875, 1950, 2075, 2275, 2775, +static const unsigned int V4_table[] = { + 1275000, 1550000, 1725000, 1875000, 1950000, 2075000, 2275000, 2775000, }; -static const u16 V5_table[] = { - 1875, 2275, 2475, 2775, +static const unsigned int V5_table[] = { + 1875000, 2275000, 2475000, 2775000, }; -static const u16 V6_table[] = { - 2475, 2775, +static const unsigned int V6_table[] = { + 2475000, 2775000, }; -static const u16 V7_table[] = { - 1875, 2775, +static const unsigned int V7_table[] = { + 1875000, 2775000, }; #define V8_table V4_table -static const u16 V9_table[] = { - 1575, 1875, 2475, 2775, +static const unsigned int V9_table[] = { + 1575000, 1875000, 2475000, 2775000, }; -static const u16 V10_table[] = { - 5000, +static const unsigned int V10_table[] = { + 5000000, }; -static const u16 VAUX1_table[] = { - 1875, 2475, 2775, 3000, +static const unsigned int VAUX1_table[] = { + 1875000, 2475000, 2775000, 3000000, }; #define VAUX2_table VAUX1_table -static const u16 VAUX3_table[] = { - 1200, 1200, 1200, 1200, 1400, 1600, 1800, 2000, - 2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600, +static const unsigned int VAUX3_table[] = { + 1200000, 1200000, 1200000, 1200000, 1400000, 1600000, 1800000, 2000000, + 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, }; -static const u16 VAUX4_table[] = { - 1800, 1800, 3000, 5000, +static const unsigned int VAUX4_table[] = { + 1800000, 1800000, 3000000, 5000000, }; -static const u16 VSIM_table[] = { - 1875, 3000, +static const unsigned int VSIM_table[] = { + 1875000, 3000000, }; -static const u16 VSIM2_table[] = { - 1875, +static const unsigned int VSIM2_table[] = { + 1875000, }; -static const u16 VVIB_table[] = { - 1300, 1800, 2000, 3000, +static const unsigned int VVIB_table[] = { + 1300000, 1800000, 2000000, 3000000, }; -static const u16 SW1_table[] = { - 900, 950, 1000, 1050, 1100, 1150, 1200, 1250, - 1300, 1350, 1400, 1450, 1500, 1600, 1875, 2250, +static const unsigned int SW1_table[] = { + 900000, 950000, 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, + 1300000, 1350000, 1400000, 1450000, 1500000, 1600000, 1875000, 2250000, }; #define SW2_table SW1_table -static const u16 SW3_table[] = { - 4000, 4500, 5000, 5500, +static const unsigned int SW3_table[] = { + 4000000, 4500000, 5000000, 5500000, }; struct pcap_regulator { @@ -100,8 +100,6 @@ struct pcap_regulator { const u8 index; const u8 stby; const u8 lowpwr; - const u8 n_voltages; - const u16 *voltage_table; }; #define NA 0xff @@ -113,8 +111,6 @@ struct pcap_regulator { .index = _index, \ .stby = _stby, \ .lowpwr = _lowpwr, \ - .n_voltages = ARRAY_SIZE(_vreg##_table), \ - .voltage_table = _vreg##_table, \ } static struct pcap_regulator vreg_table[] = { @@ -157,11 +153,11 @@ static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev, void *pcap = rdev_get_drvdata(rdev); /* the regulator doesn't support voltage switching */ - if (vreg->n_voltages == 1) + if (rdev->desc->n_voltages == 1) return -EINVAL; return ezx_pcap_set_bits(pcap, vreg->reg, - (vreg->n_voltages - 1) << vreg->index, + (rdev->desc->n_voltages - 1) << vreg->index, selector << vreg->index); } @@ -171,11 +167,11 @@ static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev) void *pcap = rdev_get_drvdata(rdev); u32 tmp; - if (vreg->n_voltages == 1) + if (rdev->desc->n_voltages == 1) return 0; ezx_pcap_read(pcap, vreg->reg, &tmp); - tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1)); + tmp = ((tmp >> vreg->index) & (rdev->desc->n_voltages - 1)); return tmp; } @@ -214,16 +210,8 @@ static int pcap_regulator_is_enabled(struct regulator_dev *rdev) return (tmp >> vreg->en) & 1; } -static int pcap_regulator_list_voltage(struct regulator_dev *rdev, - unsigned int index) -{ - struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)]; - - return vreg->voltage_table[index] * 1000; -} - static struct regulator_ops pcap_regulator_ops = { - .list_voltage = pcap_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, .set_voltage_sel = pcap_regulator_set_voltage_sel, .get_voltage_sel = pcap_regulator_get_voltage_sel, .enable = pcap_regulator_enable, @@ -236,6 +224,7 @@ static struct regulator_ops pcap_regulator_ops = { .name = #_vreg, \ .id = _vreg, \ .n_voltages = ARRAY_SIZE(_vreg##_table), \ + .volt_table = _vreg##_table, \ .ops = &pcap_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ -- GitLab From f46470379342033bdd9f740ce483c96f5c20eab2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Jun 2012 22:52:06 +0800 Subject: [PATCH 0947/6849] regulator: tps6586x: Convert to regulator_list_voltage_table Also adds tps6586x_ldo0_voltages mapping table for LDO0, so we can remove the hack in tps6586x_list_voltage() and convert it to regulator_list_voltage_table. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6586x-regulator.c | 61 +++++++++++--------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index c0a214575380..c0ac2418d6ab 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -63,8 +63,6 @@ struct tps6586x_regulator { int enable_bit[2]; int enable_reg[2]; - int *voltages; - /* for DVM regulators */ int go_reg; int go_bit; @@ -75,19 +73,6 @@ static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev) return rdev_get_dev(rdev)->parent->parent; } -static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector) -{ - struct tps6586x_regulator *info = rdev_get_drvdata(rdev); - int rid = rdev_get_id(rdev); - - /* LDO0 has minimal voltage 1.2V rather than 1.25V */ - if ((rid == TPS6586X_ID_LDO_0) && (selector == 0)) - return (info->voltages[0] - 50) * 1000; - - return info->voltages[selector] * 1000; -} - - static int tps6586x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { @@ -168,7 +153,7 @@ static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev) } static struct regulator_ops tps6586x_regulator_ops = { - .list_voltage = tps6586x_list_voltage, + .list_voltage = regulator_list_voltage_table, .get_voltage_sel = tps6586x_get_voltage_sel, .set_voltage_sel = tps6586x_set_voltage_sel, @@ -177,29 +162,33 @@ static struct regulator_ops tps6586x_regulator_ops = { .disable = tps6586x_regulator_disable, }; -static int tps6586x_ldo_voltages[] = { - 1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300, +static const unsigned int tps6586x_ldo0_voltages[] = { + 1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, +}; + +static const unsigned int tps6586x_ldo4_voltages[] = { + 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000, + 1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000, + 2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000, + 2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000, }; -static int tps6586x_ldo4_voltages[] = { - 1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875, - 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075, - 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275, - 2300, 2325, 2350, 2375, 2400, 2425, 2450, 2475, +static const unsigned int tps6586x_ldo_voltages[] = { + 1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, }; -static int tps6586x_sm2_voltages[] = { - 3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350, - 3400, 3450, 3500, 3550, 3600, 3650, 3700, 3750, - 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, - 4200, 4250, 4300, 4350, 4400, 4450, 4500, 4550, +static const unsigned int tps6586x_sm2_voltages[] = { + 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000, + 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000, + 3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000, + 4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000, }; -static int tps6586x_dvm_voltages[] = { - 725, 750, 775, 800, 825, 850, 875, 900, - 925, 950, 975, 1000, 1025, 1050, 1075, 1100, - 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, - 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, +static const unsigned int tps6586x_dvm_voltages[] = { + 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, + 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, + 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, + 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, }; #define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ @@ -210,6 +199,7 @@ static int tps6586x_dvm_voltages[] = { .type = REGULATOR_VOLTAGE, \ .id = TPS6586X_ID_##_id, \ .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ + .volt_table = tps6586x_##vdata##_voltages, \ .owner = THIS_MODULE, \ }, \ .volt_reg = TPS6586X_##vreg, \ @@ -218,8 +208,7 @@ static int tps6586x_dvm_voltages[] = { .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ .enable_bit[0] = (ebit0), \ .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ - .enable_bit[1] = (ebit1), \ - .voltages = tps6586x_##vdata##_voltages, + .enable_bit[1] = (ebit1), #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ .go_reg = TPS6586X_##goreg, \ @@ -241,7 +230,7 @@ static int tps6586x_dvm_voltages[] = { } static struct tps6586x_regulator tps6586x_regulator[] = { - TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), + TPS6586X_LDO(LDO_0, ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), TPS6586X_LDO(LDO_3, ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), -- GitLab From 93f5de5c58a863b48a8c44d70c4f7e3d0c7af50e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 08:25:41 +0800 Subject: [PATCH 0948/6849] regulator: max1586: Convert max1586_v3_ops to regulator_list_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max1586.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 126c7d8f31c6..a54771e4d960 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -63,14 +63,6 @@ static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; * R24 and R25=100kOhm as described in the data sheet. * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm */ -static int max1586_v3_calc_voltage(struct max1586_data *max1586, - unsigned selector) -{ - unsigned range_uV = max1586->max_uV - max1586->min_uV; - - return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL); -} - static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { @@ -86,25 +78,16 @@ static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV, *selector = DIV_ROUND_UP((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL, range_uV); - if (max1586_v3_calc_voltage(max1586, *selector) > max_uV) + if (regulator_list_voltage_linear(rdev, *selector) > max_uV) return -EINVAL; dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", - max1586_v3_calc_voltage(max1586, *selector) / 1000); + regulator_list_voltage_linear(rdev, *selector) / 1000); v3_prog = I2C_V3_SELECT | (u8) *selector; return i2c_smbus_write_byte(client, v3_prog); } -static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector) -{ - struct max1586_data *max1586 = rdev_get_drvdata(rdev); - - if (selector > MAX1586_V3_MAX_VSEL) - return -EINVAL; - return max1586_v3_calc_voltage(max1586, selector); -} - static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) { @@ -124,7 +107,7 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, */ static struct regulator_ops max1586_v3_ops = { .set_voltage = max1586_v3_set, - .list_voltage = max1586_v3_list, + .list_voltage = regulator_list_voltage_linear, }; static struct regulator_ops max1586_v6_ops = { @@ -132,7 +115,7 @@ static struct regulator_ops max1586_v6_ops = { .list_voltage = regulator_list_voltage_table, }; -static const struct regulator_desc max1586_reg[] = { +static struct regulator_desc max1586_reg[] = { { .name = "Output_V3", .id = MAX1586_V3, @@ -185,6 +168,13 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, goto err; } + if (id == MAX1586_V3) { + max1586_reg[id].min_uV = max1586->min_uV; + max1586_reg[id].uV_step = + (max1586->max_uV - max1586->min_uV) / + MAX1586_V3_MAX_VSEL; + } + config.dev = &client->dev; config.init_data = pdata->subdevs[i].platform_data; config.driver_data = max1586; -- GitLab From 9b558950bb652a85861fef28172e134c367dab1a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 08:26:44 +0800 Subject: [PATCH 0949/6849] regulator: max1586: Convert max1586_v3_ops to set_voltage_sel and map_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max1586.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index a54771e4d960..f67af3c1b963 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -63,28 +63,17 @@ static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; * R24 and R25=100kOhm as described in the data sheet. * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm */ -static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV, - unsigned *selector) +static int max1586_v3_set_voltage_sel(struct regulator_dev *rdev, + unsigned selector) { struct max1586_data *max1586 = rdev_get_drvdata(rdev); struct i2c_client *client = max1586->client; - unsigned range_uV = max1586->max_uV - max1586->min_uV; u8 v3_prog; - if (min_uV > max1586->max_uV || max_uV < max1586->min_uV) - return -EINVAL; - if (min_uV < max1586->min_uV) - min_uV = max1586->min_uV; - - *selector = DIV_ROUND_UP((min_uV - max1586->min_uV) * - MAX1586_V3_MAX_VSEL, range_uV); - if (regulator_list_voltage_linear(rdev, *selector) > max_uV) - return -EINVAL; - dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", - regulator_list_voltage_linear(rdev, *selector) / 1000); + regulator_list_voltage_linear(rdev, selector) / 1000); - v3_prog = I2C_V3_SELECT | (u8) *selector; + v3_prog = I2C_V3_SELECT | (u8) selector; return i2c_smbus_write_byte(client, v3_prog); } @@ -106,8 +95,9 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, * the set up value. */ static struct regulator_ops max1586_v3_ops = { - .set_voltage = max1586_v3_set, + .set_voltage_sel = max1586_v3_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, }; static struct regulator_ops max1586_v6_ops = { -- GitLab From 476585ecf08067ac4e81d1a4cb19e2caf2093471 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 6 Jun 2012 18:54:15 +0800 Subject: [PATCH 0950/6849] Bluetooth: Fix SMP pairing method selection The tk_request function takes the local IO capability as the second last parameter and the remote IO capability as the last parameter. They were previously swapped: when we receive a pairing response req->io_capability contains the local one and rsp->io_capability the remote one. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6fc7c4708f3e..c4ac2849d9c2 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -648,7 +648,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; - ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability); + ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); if (ret) return SMP_UNSPECIFIED; -- GitLab From 4fd1e324b7b5f80bd521b58593ada74ef89e80c4 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 6 Jun 2012 10:55:26 +0530 Subject: [PATCH 0951/6849] dma: dmaengine: add slave req id in slave_config The DMA controller like Nvidia's Tegra Dma controller supports the different slave requestor id from different slave. This need to be configure in dma controller to handle the request properly. Adding the slave-id in the slave configuration so that information can be passed from client when configuring for slave. Signed-off-by: Laxman Dewangan Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 56377df39124..ccec62f8e501 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -338,6 +338,9 @@ enum dma_slave_buswidth { * @device_fc: Flow Controller Settings. Only valid for slave channels. Fill * with 'true' if peripheral should be flow controller. Direction will be * selected at Runtime. + * @slave_id: Slave requester id. Only valid for slave channels. The dma + * slave peripheral will have unique id as dma requester which need to be + * pass as slave config. * * This struct is passed in as configuration data to a DMA engine * in order to set up a certain channel for DMA transport at runtime. @@ -365,6 +368,7 @@ struct dma_slave_config { u32 src_maxburst; u32 dst_maxburst; bool device_fc; + unsigned int slave_id; }; static inline const char *dma_chan_name(struct dma_chan *chan) -- GitLab From ec8a1586780cbb437aeb2006957c5bbe113c7046 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 6 Jun 2012 10:55:27 +0530 Subject: [PATCH 0952/6849] dma: tegra: add dmaengine based dma driver Add dmaengine based NVIDIA's Tegra APB DMA driver. This driver support the slave mode of data transfer from peripheral to memory and vice versa. The driver supports for the cyclic and non-cyclic mode of data transfer. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 14 + drivers/dma/Makefile | 1 + drivers/dma/tegra20-apb-dma.c | 1410 +++++++++++++++++++++++++++++++++ 3 files changed, 1425 insertions(+) create mode 100644 drivers/dma/tegra20-apb-dma.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index c8416d54f917..b3761153649d 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -148,6 +148,20 @@ config TXX9_DMAC Support the TXx9 SoC internal DMA controller. This can be integrated in chips such as the Toshiba TX4927/38/39. +config TEGRA20_APB_DMA + bool "NVIDIA Tegra20 APB DMA support" + depends on ARCH_TEGRA + select DMA_ENGINE + help + Support for the NVIDIA Tegra20 APB DMA controller driver. The + DMA controller is having multiple DMA channel which can be + configured for different peripherals like audio, UART, SPI, + I2C etc which is in APB bus. + This DMA controller transfers data from memory to peripheral fifo + or vice versa. It does not support memory to memory data transfer. + + + config SH_DMAE tristate "Renesas SuperH DMAC support" depends on (SUPERH && SH_DMA) || (ARM && ARCH_SHMOBILE) diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 86b795baba98..d679ea3f6ab0 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_MXS_DMA) += mxs-dma.o obj-$(CONFIG_TIMB_DMA) += timb_dma.o obj-$(CONFIG_SIRF_DMA) += sirf-dma.o obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o +obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o obj-$(CONFIG_PL330_DMA) += pl330.o obj-$(CONFIG_PCH_DMA) += pch_dma.o obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c new file mode 100644 index 000000000000..134ea7cfc795 --- /dev/null +++ b/drivers/dma/tegra20-apb-dma.c @@ -0,0 +1,1410 @@ +/* + * DMA driver for Nvidia's Tegra20 APB DMA controller. + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dmaengine.h" + +#define TEGRA_APBDMA_GENERAL 0x0 +#define TEGRA_APBDMA_GENERAL_ENABLE BIT(31) + +#define TEGRA_APBDMA_CONTROL 0x010 +#define TEGRA_APBDMA_IRQ_MASK 0x01c +#define TEGRA_APBDMA_IRQ_MASK_SET 0x020 + +/* CSR register */ +#define TEGRA_APBDMA_CHAN_CSR 0x00 +#define TEGRA_APBDMA_CSR_ENB BIT(31) +#define TEGRA_APBDMA_CSR_IE_EOC BIT(30) +#define TEGRA_APBDMA_CSR_HOLD BIT(29) +#define TEGRA_APBDMA_CSR_DIR BIT(28) +#define TEGRA_APBDMA_CSR_ONCE BIT(27) +#define TEGRA_APBDMA_CSR_FLOW BIT(21) +#define TEGRA_APBDMA_CSR_REQ_SEL_SHIFT 16 +#define TEGRA_APBDMA_CSR_WCOUNT_MASK 0xFFFC + +/* STATUS register */ +#define TEGRA_APBDMA_CHAN_STATUS 0x004 +#define TEGRA_APBDMA_STATUS_BUSY BIT(31) +#define TEGRA_APBDMA_STATUS_ISE_EOC BIT(30) +#define TEGRA_APBDMA_STATUS_HALT BIT(29) +#define TEGRA_APBDMA_STATUS_PING_PONG BIT(28) +#define TEGRA_APBDMA_STATUS_COUNT_SHIFT 2 +#define TEGRA_APBDMA_STATUS_COUNT_MASK 0xFFFC + +/* AHB memory address */ +#define TEGRA_APBDMA_CHAN_AHBPTR 0x010 + +/* AHB sequence register */ +#define TEGRA_APBDMA_CHAN_AHBSEQ 0x14 +#define TEGRA_APBDMA_AHBSEQ_INTR_ENB BIT(31) +#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_8 (0 << 28) +#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_16 (1 << 28) +#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32 (2 << 28) +#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_64 (3 << 28) +#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_128 (4 << 28) +#define TEGRA_APBDMA_AHBSEQ_DATA_SWAP BIT(27) +#define TEGRA_APBDMA_AHBSEQ_BURST_1 (4 << 24) +#define TEGRA_APBDMA_AHBSEQ_BURST_4 (5 << 24) +#define TEGRA_APBDMA_AHBSEQ_BURST_8 (6 << 24) +#define TEGRA_APBDMA_AHBSEQ_DBL_BUF BIT(19) +#define TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT 16 +#define TEGRA_APBDMA_AHBSEQ_WRAP_NONE 0 + +/* APB address */ +#define TEGRA_APBDMA_CHAN_APBPTR 0x018 + +/* APB sequence register */ +#define TEGRA_APBDMA_CHAN_APBSEQ 0x01c +#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_8 (0 << 28) +#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_16 (1 << 28) +#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32 (2 << 28) +#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_64 (3 << 28) +#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_128 (4 << 28) +#define TEGRA_APBDMA_APBSEQ_DATA_SWAP BIT(27) +#define TEGRA_APBDMA_APBSEQ_WRAP_WORD_1 (1 << 16) + +/* + * If any burst is in flight and DMA paused then this is the time to complete + * on-flight burst and update DMA status register. + */ +#define TEGRA_APBDMA_BURST_COMPLETE_TIME 20 + +/* Channel base address offset from APBDMA base address */ +#define TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET 0x1000 + +/* DMA channel register space size */ +#define TEGRA_APBDMA_CHANNEL_REGISTER_SIZE 0x20 + +struct tegra_dma; + +/* + * tegra_dma_chip_data Tegra chip specific DMA data + * @nr_channels: Number of channels available in the controller. + * @max_dma_count: Maximum DMA transfer count supported by DMA controller. + */ +struct tegra_dma_chip_data { + int nr_channels; + int max_dma_count; +}; + +/* DMA channel registers */ +struct tegra_dma_channel_regs { + unsigned long csr; + unsigned long ahb_ptr; + unsigned long apb_ptr; + unsigned long ahb_seq; + unsigned long apb_seq; +}; + +/* + * tegra_dma_sg_req: Dma request details to configure hardware. This + * contains the details for one transfer to configure DMA hw. + * The client's request for data transfer can be broken into multiple + * sub-transfer as per requester details and hw support. + * This sub transfer get added in the list of transfer and point to Tegra + * DMA descriptor which manages the transfer details. + */ +struct tegra_dma_sg_req { + struct tegra_dma_channel_regs ch_regs; + int req_len; + bool configured; + bool last_sg; + bool half_done; + struct list_head node; + struct tegra_dma_desc *dma_desc; +}; + +/* + * tegra_dma_desc: Tegra DMA descriptors which manages the client requests. + * This descriptor keep track of transfer status, callbacks and request + * counts etc. + */ +struct tegra_dma_desc { + struct dma_async_tx_descriptor txd; + int bytes_requested; + int bytes_transferred; + enum dma_status dma_status; + struct list_head node; + struct list_head tx_list; + struct list_head cb_node; + int cb_count; +}; + +struct tegra_dma_channel; + +typedef void (*dma_isr_handler)(struct tegra_dma_channel *tdc, + bool to_terminate); + +/* tegra_dma_channel: Channel specific information */ +struct tegra_dma_channel { + struct dma_chan dma_chan; + bool config_init; + int id; + int irq; + unsigned long chan_base_offset; + spinlock_t lock; + bool busy; + struct tegra_dma *tdma; + bool cyclic; + + /* Different lists for managing the requests */ + struct list_head free_sg_req; + struct list_head pending_sg_req; + struct list_head free_dma_desc; + struct list_head cb_desc; + + /* ISR handler and tasklet for bottom half of isr handling */ + dma_isr_handler isr_handler; + struct tasklet_struct tasklet; + dma_async_tx_callback callback; + void *callback_param; + + /* Channel-slave specific configuration */ + struct dma_slave_config dma_sconfig; +}; + +/* tegra_dma: Tegra DMA specific information */ +struct tegra_dma { + struct dma_device dma_dev; + struct device *dev; + struct clk *dma_clk; + spinlock_t global_lock; + void __iomem *base_addr; + struct tegra_dma_chip_data *chip_data; + + /* Some register need to be cache before suspend */ + u32 reg_gen; + + /* Last member of the structure */ + struct tegra_dma_channel channels[0]; +}; + +static inline void tdma_write(struct tegra_dma *tdma, u32 reg, u32 val) +{ + writel(val, tdma->base_addr + reg); +} + +static inline u32 tdma_read(struct tegra_dma *tdma, u32 reg) +{ + return readl(tdma->base_addr + reg); +} + +static inline void tdc_write(struct tegra_dma_channel *tdc, + u32 reg, u32 val) +{ + writel(val, tdc->tdma->base_addr + tdc->chan_base_offset + reg); +} + +static inline u32 tdc_read(struct tegra_dma_channel *tdc, u32 reg) +{ + return readl(tdc->tdma->base_addr + tdc->chan_base_offset + reg); +} + +static inline struct tegra_dma_channel *to_tegra_dma_chan(struct dma_chan *dc) +{ + return container_of(dc, struct tegra_dma_channel, dma_chan); +} + +static inline struct tegra_dma_desc *txd_to_tegra_dma_desc( + struct dma_async_tx_descriptor *td) +{ + return container_of(td, struct tegra_dma_desc, txd); +} + +static inline struct device *tdc2dev(struct tegra_dma_channel *tdc) +{ + return &tdc->dma_chan.dev->device; +} + +static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *tx); +static int tegra_dma_runtime_suspend(struct device *dev); +static int tegra_dma_runtime_resume(struct device *dev); + +/* Get DMA desc from free list, if not there then allocate it. */ +static struct tegra_dma_desc *tegra_dma_desc_get( + struct tegra_dma_channel *tdc) +{ + struct tegra_dma_desc *dma_desc; + unsigned long flags; + + spin_lock_irqsave(&tdc->lock, flags); + + /* Do not allocate if desc are waiting for ack */ + list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) { + if (async_tx_test_ack(&dma_desc->txd)) { + list_del(&dma_desc->node); + spin_unlock_irqrestore(&tdc->lock, flags); + return dma_desc; + } + } + + spin_unlock_irqrestore(&tdc->lock, flags); + + /* Allocate DMA desc */ + dma_desc = kzalloc(sizeof(*dma_desc), GFP_ATOMIC); + if (!dma_desc) { + dev_err(tdc2dev(tdc), "dma_desc alloc failed\n"); + return NULL; + } + + dma_async_tx_descriptor_init(&dma_desc->txd, &tdc->dma_chan); + dma_desc->txd.tx_submit = tegra_dma_tx_submit; + dma_desc->txd.flags = 0; + return dma_desc; +} + +static void tegra_dma_desc_put(struct tegra_dma_channel *tdc, + struct tegra_dma_desc *dma_desc) +{ + unsigned long flags; + + spin_lock_irqsave(&tdc->lock, flags); + if (!list_empty(&dma_desc->tx_list)) + list_splice_init(&dma_desc->tx_list, &tdc->free_sg_req); + list_add_tail(&dma_desc->node, &tdc->free_dma_desc); + spin_unlock_irqrestore(&tdc->lock, flags); +} + +static struct tegra_dma_sg_req *tegra_dma_sg_req_get( + struct tegra_dma_channel *tdc) +{ + struct tegra_dma_sg_req *sg_req = NULL; + unsigned long flags; + + spin_lock_irqsave(&tdc->lock, flags); + if (!list_empty(&tdc->free_sg_req)) { + sg_req = list_first_entry(&tdc->free_sg_req, + typeof(*sg_req), node); + list_del(&sg_req->node); + spin_unlock_irqrestore(&tdc->lock, flags); + return sg_req; + } + spin_unlock_irqrestore(&tdc->lock, flags); + + sg_req = kzalloc(sizeof(struct tegra_dma_sg_req), GFP_ATOMIC); + if (!sg_req) + dev_err(tdc2dev(tdc), "sg_req alloc failed\n"); + return sg_req; +} + +static int tegra_dma_slave_config(struct dma_chan *dc, + struct dma_slave_config *sconfig) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + + if (!list_empty(&tdc->pending_sg_req)) { + dev_err(tdc2dev(tdc), "Configuration not allowed\n"); + return -EBUSY; + } + + memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); + tdc->config_init = true; + return 0; +} + +static void tegra_dma_global_pause(struct tegra_dma_channel *tdc, + bool wait_for_burst_complete) +{ + struct tegra_dma *tdma = tdc->tdma; + + spin_lock(&tdma->global_lock); + tdma_write(tdma, TEGRA_APBDMA_GENERAL, 0); + if (wait_for_burst_complete) + udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME); +} + +static void tegra_dma_global_resume(struct tegra_dma_channel *tdc) +{ + struct tegra_dma *tdma = tdc->tdma; + + tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); + spin_unlock(&tdma->global_lock); +} + +static void tegra_dma_stop(struct tegra_dma_channel *tdc) +{ + u32 csr; + u32 status; + + /* Disable interrupts */ + csr = tdc_read(tdc, TEGRA_APBDMA_CHAN_CSR); + csr &= ~TEGRA_APBDMA_CSR_IE_EOC; + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, csr); + + /* Disable DMA */ + csr &= ~TEGRA_APBDMA_CSR_ENB; + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, csr); + + /* Clear interrupt status if it is there */ + status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); + if (status & TEGRA_APBDMA_STATUS_ISE_EOC) { + dev_dbg(tdc2dev(tdc), "%s():clearing interrupt\n", __func__); + tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status); + } + tdc->busy = false; +} + +static void tegra_dma_start(struct tegra_dma_channel *tdc, + struct tegra_dma_sg_req *sg_req) +{ + struct tegra_dma_channel_regs *ch_regs = &sg_req->ch_regs; + + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, ch_regs->csr); + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBSEQ, ch_regs->apb_seq); + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, ch_regs->apb_ptr); + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBSEQ, ch_regs->ahb_seq); + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, ch_regs->ahb_ptr); + + /* Start DMA */ + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, + ch_regs->csr | TEGRA_APBDMA_CSR_ENB); +} + +static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc, + struct tegra_dma_sg_req *nsg_req) +{ + unsigned long status; + + /* + * The DMA controller reloads the new configuration for next transfer + * after last burst of current transfer completes. + * If there is no IEC status then this makes sure that last burst + * has not be completed. There may be case that last burst is on + * flight and so it can complete but because DMA is paused, it + * will not generates interrupt as well as not reload the new + * configuration. + * If there is already IEC status then interrupt handler need to + * load new configuration. + */ + tegra_dma_global_pause(tdc, false); + status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); + + /* + * If interrupt is pending then do nothing as the ISR will handle + * the programing for new request. + */ + if (status & TEGRA_APBDMA_STATUS_ISE_EOC) { + dev_err(tdc2dev(tdc), + "Skipping new configuration as interrupt is pending\n"); + tegra_dma_global_resume(tdc); + return; + } + + /* Safe to program new configuration */ + tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, nsg_req->ch_regs.apb_ptr); + tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, nsg_req->ch_regs.ahb_ptr); + tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, + nsg_req->ch_regs.csr | TEGRA_APBDMA_CSR_ENB); + nsg_req->configured = true; + + tegra_dma_global_resume(tdc); +} + +static void tdc_start_head_req(struct tegra_dma_channel *tdc) +{ + struct tegra_dma_sg_req *sg_req; + + if (list_empty(&tdc->pending_sg_req)) + return; + + sg_req = list_first_entry(&tdc->pending_sg_req, + typeof(*sg_req), node); + tegra_dma_start(tdc, sg_req); + sg_req->configured = true; + tdc->busy = true; +} + +static void tdc_configure_next_head_desc(struct tegra_dma_channel *tdc) +{ + struct tegra_dma_sg_req *hsgreq; + struct tegra_dma_sg_req *hnsgreq; + + if (list_empty(&tdc->pending_sg_req)) + return; + + hsgreq = list_first_entry(&tdc->pending_sg_req, typeof(*hsgreq), node); + if (!list_is_last(&hsgreq->node, &tdc->pending_sg_req)) { + hnsgreq = list_first_entry(&hsgreq->node, + typeof(*hnsgreq), node); + tegra_dma_configure_for_next(tdc, hnsgreq); + } +} + +static inline int get_current_xferred_count(struct tegra_dma_channel *tdc, + struct tegra_dma_sg_req *sg_req, unsigned long status) +{ + return sg_req->req_len - (status & TEGRA_APBDMA_STATUS_COUNT_MASK) - 4; +} + +static void tegra_dma_abort_all(struct tegra_dma_channel *tdc) +{ + struct tegra_dma_sg_req *sgreq; + struct tegra_dma_desc *dma_desc; + + while (!list_empty(&tdc->pending_sg_req)) { + sgreq = list_first_entry(&tdc->pending_sg_req, + typeof(*sgreq), node); + list_del(&sgreq->node); + list_add_tail(&sgreq->node, &tdc->free_sg_req); + if (sgreq->last_sg) { + dma_desc = sgreq->dma_desc; + dma_desc->dma_status = DMA_ERROR; + list_add_tail(&dma_desc->node, &tdc->free_dma_desc); + + /* Add in cb list if it is not there. */ + if (!dma_desc->cb_count) + list_add_tail(&dma_desc->cb_node, + &tdc->cb_desc); + dma_desc->cb_count++; + } + } + tdc->isr_handler = NULL; +} + +static bool handle_continuous_head_request(struct tegra_dma_channel *tdc, + struct tegra_dma_sg_req *last_sg_req, bool to_terminate) +{ + struct tegra_dma_sg_req *hsgreq = NULL; + + if (list_empty(&tdc->pending_sg_req)) { + dev_err(tdc2dev(tdc), "Dma is running without req\n"); + tegra_dma_stop(tdc); + return false; + } + + /* + * Check that head req on list should be in flight. + * If it is not in flight then abort transfer as + * looping of transfer can not continue. + */ + hsgreq = list_first_entry(&tdc->pending_sg_req, typeof(*hsgreq), node); + if (!hsgreq->configured) { + tegra_dma_stop(tdc); + dev_err(tdc2dev(tdc), "Error in dma transfer, aborting dma\n"); + tegra_dma_abort_all(tdc); + return false; + } + + /* Configure next request */ + if (!to_terminate) + tdc_configure_next_head_desc(tdc); + return true; +} + +static void handle_once_dma_done(struct tegra_dma_channel *tdc, + bool to_terminate) +{ + struct tegra_dma_sg_req *sgreq; + struct tegra_dma_desc *dma_desc; + + tdc->busy = false; + sgreq = list_first_entry(&tdc->pending_sg_req, typeof(*sgreq), node); + dma_desc = sgreq->dma_desc; + dma_desc->bytes_transferred += sgreq->req_len; + + list_del(&sgreq->node); + if (sgreq->last_sg) { + dma_desc->dma_status = DMA_SUCCESS; + dma_cookie_complete(&dma_desc->txd); + if (!dma_desc->cb_count) + list_add_tail(&dma_desc->cb_node, &tdc->cb_desc); + dma_desc->cb_count++; + list_add_tail(&dma_desc->node, &tdc->free_dma_desc); + } + list_add_tail(&sgreq->node, &tdc->free_sg_req); + + /* Do not start DMA if it is going to be terminate */ + if (to_terminate || list_empty(&tdc->pending_sg_req)) + return; + + tdc_start_head_req(tdc); + return; +} + +static void handle_cont_sngl_cycle_dma_done(struct tegra_dma_channel *tdc, + bool to_terminate) +{ + struct tegra_dma_sg_req *sgreq; + struct tegra_dma_desc *dma_desc; + bool st; + + sgreq = list_first_entry(&tdc->pending_sg_req, typeof(*sgreq), node); + dma_desc = sgreq->dma_desc; + dma_desc->bytes_transferred += sgreq->req_len; + + /* Callback need to be call */ + if (!dma_desc->cb_count) + list_add_tail(&dma_desc->cb_node, &tdc->cb_desc); + dma_desc->cb_count++; + + /* If not last req then put at end of pending list */ + if (!list_is_last(&sgreq->node, &tdc->pending_sg_req)) { + list_del(&sgreq->node); + list_add_tail(&sgreq->node, &tdc->pending_sg_req); + sgreq->configured = false; + st = handle_continuous_head_request(tdc, sgreq, to_terminate); + if (!st) + dma_desc->dma_status = DMA_ERROR; + } + return; +} + +static void tegra_dma_tasklet(unsigned long data) +{ + struct tegra_dma_channel *tdc = (struct tegra_dma_channel *)data; + dma_async_tx_callback callback = NULL; + void *callback_param = NULL; + struct tegra_dma_desc *dma_desc; + unsigned long flags; + int cb_count; + + spin_lock_irqsave(&tdc->lock, flags); + while (!list_empty(&tdc->cb_desc)) { + dma_desc = list_first_entry(&tdc->cb_desc, + typeof(*dma_desc), cb_node); + list_del(&dma_desc->cb_node); + callback = dma_desc->txd.callback; + callback_param = dma_desc->txd.callback_param; + cb_count = dma_desc->cb_count; + dma_desc->cb_count = 0; + spin_unlock_irqrestore(&tdc->lock, flags); + while (cb_count-- && callback) + callback(callback_param); + spin_lock_irqsave(&tdc->lock, flags); + } + spin_unlock_irqrestore(&tdc->lock, flags); +} + +static irqreturn_t tegra_dma_isr(int irq, void *dev_id) +{ + struct tegra_dma_channel *tdc = dev_id; + unsigned long status; + unsigned long flags; + + spin_lock_irqsave(&tdc->lock, flags); + + status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); + if (status & TEGRA_APBDMA_STATUS_ISE_EOC) { + tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status); + tdc->isr_handler(tdc, false); + tasklet_schedule(&tdc->tasklet); + spin_unlock_irqrestore(&tdc->lock, flags); + return IRQ_HANDLED; + } + + spin_unlock_irqrestore(&tdc->lock, flags); + dev_info(tdc2dev(tdc), + "Interrupt already served status 0x%08lx\n", status); + return IRQ_NONE; +} + +static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *txd) +{ + struct tegra_dma_desc *dma_desc = txd_to_tegra_dma_desc(txd); + struct tegra_dma_channel *tdc = to_tegra_dma_chan(txd->chan); + unsigned long flags; + dma_cookie_t cookie; + + spin_lock_irqsave(&tdc->lock, flags); + dma_desc->dma_status = DMA_IN_PROGRESS; + cookie = dma_cookie_assign(&dma_desc->txd); + list_splice_tail_init(&dma_desc->tx_list, &tdc->pending_sg_req); + spin_unlock_irqrestore(&tdc->lock, flags); + return cookie; +} + +static void tegra_dma_issue_pending(struct dma_chan *dc) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + unsigned long flags; + + spin_lock_irqsave(&tdc->lock, flags); + if (list_empty(&tdc->pending_sg_req)) { + dev_err(tdc2dev(tdc), "No DMA request\n"); + goto end; + } + if (!tdc->busy) { + tdc_start_head_req(tdc); + + /* Continuous single mode: Configure next req */ + if (tdc->cyclic) { + /* + * Wait for 1 burst time for configure DMA for + * next transfer. + */ + udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME); + tdc_configure_next_head_desc(tdc); + } + } +end: + spin_unlock_irqrestore(&tdc->lock, flags); + return; +} + +static void tegra_dma_terminate_all(struct dma_chan *dc) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + struct tegra_dma_sg_req *sgreq; + struct tegra_dma_desc *dma_desc; + unsigned long flags; + unsigned long status; + bool was_busy; + + spin_lock_irqsave(&tdc->lock, flags); + if (list_empty(&tdc->pending_sg_req)) { + spin_unlock_irqrestore(&tdc->lock, flags); + return; + } + + if (!tdc->busy) + goto skip_dma_stop; + + /* Pause DMA before checking the queue status */ + tegra_dma_global_pause(tdc, true); + + status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); + if (status & TEGRA_APBDMA_STATUS_ISE_EOC) { + dev_dbg(tdc2dev(tdc), "%s():handling isr\n", __func__); + tdc->isr_handler(tdc, true); + status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); + } + + was_busy = tdc->busy; + tegra_dma_stop(tdc); + + if (!list_empty(&tdc->pending_sg_req) && was_busy) { + sgreq = list_first_entry(&tdc->pending_sg_req, + typeof(*sgreq), node); + sgreq->dma_desc->bytes_transferred += + get_current_xferred_count(tdc, sgreq, status); + } + tegra_dma_global_resume(tdc); + +skip_dma_stop: + tegra_dma_abort_all(tdc); + + while (!list_empty(&tdc->cb_desc)) { + dma_desc = list_first_entry(&tdc->cb_desc, + typeof(*dma_desc), cb_node); + list_del(&dma_desc->cb_node); + dma_desc->cb_count = 0; + } + spin_unlock_irqrestore(&tdc->lock, flags); +} + +static enum dma_status tegra_dma_tx_status(struct dma_chan *dc, + dma_cookie_t cookie, struct dma_tx_state *txstate) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + struct tegra_dma_desc *dma_desc; + struct tegra_dma_sg_req *sg_req; + enum dma_status ret; + unsigned long flags; + + spin_lock_irqsave(&tdc->lock, flags); + + ret = dma_cookie_status(dc, cookie, txstate); + if (ret == DMA_SUCCESS) { + dma_set_residue(txstate, 0); + spin_unlock_irqrestore(&tdc->lock, flags); + return ret; + } + + /* Check on wait_ack desc status */ + list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) { + if (dma_desc->txd.cookie == cookie) { + dma_set_residue(txstate, + dma_desc->bytes_requested - + dma_desc->bytes_transferred); + ret = dma_desc->dma_status; + spin_unlock_irqrestore(&tdc->lock, flags); + return ret; + } + } + + /* Check in pending list */ + list_for_each_entry(sg_req, &tdc->pending_sg_req, node) { + dma_desc = sg_req->dma_desc; + if (dma_desc->txd.cookie == cookie) { + dma_set_residue(txstate, + dma_desc->bytes_requested - + dma_desc->bytes_transferred); + ret = dma_desc->dma_status; + spin_unlock_irqrestore(&tdc->lock, flags); + return ret; + } + } + + dev_dbg(tdc2dev(tdc), "cookie %d does not found\n", cookie); + spin_unlock_irqrestore(&tdc->lock, flags); + return ret; +} + +static int tegra_dma_device_control(struct dma_chan *dc, enum dma_ctrl_cmd cmd, + unsigned long arg) +{ + switch (cmd) { + case DMA_SLAVE_CONFIG: + return tegra_dma_slave_config(dc, + (struct dma_slave_config *)arg); + + case DMA_TERMINATE_ALL: + tegra_dma_terminate_all(dc); + return 0; + + default: + break; + } + + return -ENXIO; +} + +static inline int get_bus_width(struct tegra_dma_channel *tdc, + enum dma_slave_buswidth slave_bw) +{ + switch (slave_bw) { + case DMA_SLAVE_BUSWIDTH_1_BYTE: + return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_8; + case DMA_SLAVE_BUSWIDTH_2_BYTES: + return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_16; + case DMA_SLAVE_BUSWIDTH_4_BYTES: + return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32; + case DMA_SLAVE_BUSWIDTH_8_BYTES: + return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_64; + default: + dev_warn(tdc2dev(tdc), + "slave bw is not supported, using 32bits\n"); + return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32; + } +} + +static inline int get_burst_size(struct tegra_dma_channel *tdc, + u32 burst_size, enum dma_slave_buswidth slave_bw, int len) +{ + int burst_byte; + int burst_ahb_width; + + /* + * burst_size from client is in terms of the bus_width. + * convert them into AHB memory width which is 4 byte. + */ + burst_byte = burst_size * slave_bw; + burst_ahb_width = burst_byte / 4; + + /* If burst size is 0 then calculate the burst size based on length */ + if (!burst_ahb_width) { + if (len & 0xF) + return TEGRA_APBDMA_AHBSEQ_BURST_1; + else if ((len >> 4) & 0x1) + return TEGRA_APBDMA_AHBSEQ_BURST_4; + else + return TEGRA_APBDMA_AHBSEQ_BURST_8; + } + if (burst_ahb_width < 4) + return TEGRA_APBDMA_AHBSEQ_BURST_1; + else if (burst_ahb_width < 8) + return TEGRA_APBDMA_AHBSEQ_BURST_4; + else + return TEGRA_APBDMA_AHBSEQ_BURST_8; +} + +static int get_transfer_param(struct tegra_dma_channel *tdc, + enum dma_transfer_direction direction, unsigned long *apb_addr, + unsigned long *apb_seq, unsigned long *csr, unsigned int *burst_size, + enum dma_slave_buswidth *slave_bw) +{ + + switch (direction) { + case DMA_MEM_TO_DEV: + *apb_addr = tdc->dma_sconfig.dst_addr; + *apb_seq = get_bus_width(tdc, tdc->dma_sconfig.dst_addr_width); + *burst_size = tdc->dma_sconfig.dst_maxburst; + *slave_bw = tdc->dma_sconfig.dst_addr_width; + *csr = TEGRA_APBDMA_CSR_DIR; + return 0; + + case DMA_DEV_TO_MEM: + *apb_addr = tdc->dma_sconfig.src_addr; + *apb_seq = get_bus_width(tdc, tdc->dma_sconfig.src_addr_width); + *burst_size = tdc->dma_sconfig.src_maxburst; + *slave_bw = tdc->dma_sconfig.src_addr_width; + *csr = 0; + return 0; + + default: + dev_err(tdc2dev(tdc), "Dma direction is not supported\n"); + return -EINVAL; + } + return -EINVAL; +} + +static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( + struct dma_chan *dc, struct scatterlist *sgl, unsigned int sg_len, + enum dma_transfer_direction direction, unsigned long flags, + void *context) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + struct tegra_dma_desc *dma_desc; + unsigned int i; + struct scatterlist *sg; + unsigned long csr, ahb_seq, apb_ptr, apb_seq; + struct list_head req_list; + struct tegra_dma_sg_req *sg_req = NULL; + u32 burst_size; + enum dma_slave_buswidth slave_bw; + int ret; + + if (!tdc->config_init) { + dev_err(tdc2dev(tdc), "dma channel is not configured\n"); + return NULL; + } + if (sg_len < 1) { + dev_err(tdc2dev(tdc), "Invalid segment length %d\n", sg_len); + return NULL; + } + + ret = get_transfer_param(tdc, direction, &apb_ptr, &apb_seq, &csr, + &burst_size, &slave_bw); + if (ret < 0) + return NULL; + + INIT_LIST_HEAD(&req_list); + + ahb_seq = TEGRA_APBDMA_AHBSEQ_INTR_ENB; + ahb_seq |= TEGRA_APBDMA_AHBSEQ_WRAP_NONE << + TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT; + ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; + + csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; + csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; + if (flags & DMA_PREP_INTERRUPT) + csr |= TEGRA_APBDMA_CSR_IE_EOC; + + apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; + + dma_desc = tegra_dma_desc_get(tdc); + if (!dma_desc) { + dev_err(tdc2dev(tdc), "Dma descriptors not available\n"); + return NULL; + } + INIT_LIST_HEAD(&dma_desc->tx_list); + INIT_LIST_HEAD(&dma_desc->cb_node); + dma_desc->cb_count = 0; + dma_desc->bytes_requested = 0; + dma_desc->bytes_transferred = 0; + dma_desc->dma_status = DMA_IN_PROGRESS; + + /* Make transfer requests */ + for_each_sg(sgl, sg, sg_len, i) { + u32 len, mem; + + mem = sg_phys(sg); + len = sg_dma_len(sg); + + if ((len & 3) || (mem & 3) || + (len > tdc->tdma->chip_data->max_dma_count)) { + dev_err(tdc2dev(tdc), + "Dma length/memory address is not supported\n"); + tegra_dma_desc_put(tdc, dma_desc); + return NULL; + } + + sg_req = tegra_dma_sg_req_get(tdc); + if (!sg_req) { + dev_err(tdc2dev(tdc), "Dma sg-req not available\n"); + tegra_dma_desc_put(tdc, dma_desc); + return NULL; + } + + ahb_seq |= get_burst_size(tdc, burst_size, slave_bw, len); + dma_desc->bytes_requested += len; + + sg_req->ch_regs.apb_ptr = apb_ptr; + sg_req->ch_regs.ahb_ptr = mem; + sg_req->ch_regs.csr = csr | ((len - 4) & 0xFFFC); + sg_req->ch_regs.apb_seq = apb_seq; + sg_req->ch_regs.ahb_seq = ahb_seq; + sg_req->configured = false; + sg_req->last_sg = false; + sg_req->dma_desc = dma_desc; + sg_req->req_len = len; + + list_add_tail(&sg_req->node, &dma_desc->tx_list); + } + sg_req->last_sg = true; + if (flags & DMA_CTRL_ACK) + dma_desc->txd.flags = DMA_CTRL_ACK; + + /* + * Make sure that mode should not be conflicting with currently + * configured mode. + */ + if (!tdc->isr_handler) { + tdc->isr_handler = handle_once_dma_done; + tdc->cyclic = false; + } else { + if (tdc->cyclic) { + dev_err(tdc2dev(tdc), "DMA configured in cyclic mode\n"); + tegra_dma_desc_put(tdc, dma_desc); + return NULL; + } + } + + return &dma_desc->txd; +} + +struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( + struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len, + size_t period_len, enum dma_transfer_direction direction, + void *context) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + struct tegra_dma_desc *dma_desc = NULL; + struct tegra_dma_sg_req *sg_req = NULL; + unsigned long csr, ahb_seq, apb_ptr, apb_seq; + int len; + size_t remain_len; + dma_addr_t mem = buf_addr; + u32 burst_size; + enum dma_slave_buswidth slave_bw; + int ret; + + if (!buf_len || !period_len) { + dev_err(tdc2dev(tdc), "Invalid buffer/period len\n"); + return NULL; + } + + if (!tdc->config_init) { + dev_err(tdc2dev(tdc), "DMA slave is not configured\n"); + return NULL; + } + + /* + * We allow to take more number of requests till DMA is + * not started. The driver will loop over all requests. + * Once DMA is started then new requests can be queued only after + * terminating the DMA. + */ + if (tdc->busy) { + dev_err(tdc2dev(tdc), "Request not allowed when dma running\n"); + return NULL; + } + + /* + * We only support cycle transfer when buf_len is multiple of + * period_len. + */ + if (buf_len % period_len) { + dev_err(tdc2dev(tdc), "buf_len is not multiple of period_len\n"); + return NULL; + } + + len = period_len; + if ((len & 3) || (buf_addr & 3) || + (len > tdc->tdma->chip_data->max_dma_count)) { + dev_err(tdc2dev(tdc), "Req len/mem address is not correct\n"); + return NULL; + } + + ret = get_transfer_param(tdc, direction, &apb_ptr, &apb_seq, &csr, + &burst_size, &slave_bw); + if (ret < 0) + return NULL; + + + ahb_seq = TEGRA_APBDMA_AHBSEQ_INTR_ENB; + ahb_seq |= TEGRA_APBDMA_AHBSEQ_WRAP_NONE << + TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT; + ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; + + csr |= TEGRA_APBDMA_CSR_FLOW | TEGRA_APBDMA_CSR_IE_EOC; + csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; + + apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; + + dma_desc = tegra_dma_desc_get(tdc); + if (!dma_desc) { + dev_err(tdc2dev(tdc), "not enough descriptors available\n"); + return NULL; + } + + INIT_LIST_HEAD(&dma_desc->tx_list); + INIT_LIST_HEAD(&dma_desc->cb_node); + dma_desc->cb_count = 0; + + dma_desc->bytes_transferred = 0; + dma_desc->bytes_requested = buf_len; + remain_len = buf_len; + + /* Split transfer equal to period size */ + while (remain_len) { + sg_req = tegra_dma_sg_req_get(tdc); + if (!sg_req) { + dev_err(tdc2dev(tdc), "Dma sg-req not available\n"); + tegra_dma_desc_put(tdc, dma_desc); + return NULL; + } + + ahb_seq |= get_burst_size(tdc, burst_size, slave_bw, len); + sg_req->ch_regs.apb_ptr = apb_ptr; + sg_req->ch_regs.ahb_ptr = mem; + sg_req->ch_regs.csr = csr | ((len - 4) & 0xFFFC); + sg_req->ch_regs.apb_seq = apb_seq; + sg_req->ch_regs.ahb_seq = ahb_seq; + sg_req->configured = false; + sg_req->half_done = false; + sg_req->last_sg = false; + sg_req->dma_desc = dma_desc; + sg_req->req_len = len; + + list_add_tail(&sg_req->node, &dma_desc->tx_list); + remain_len -= len; + mem += len; + } + sg_req->last_sg = true; + dma_desc->txd.flags = DMA_CTRL_ACK; + + /* + * Make sure that mode should not be conflicting with currently + * configured mode. + */ + if (!tdc->isr_handler) { + tdc->isr_handler = handle_cont_sngl_cycle_dma_done; + tdc->cyclic = true; + } else { + if (!tdc->cyclic) { + dev_err(tdc2dev(tdc), "DMA configuration conflict\n"); + tegra_dma_desc_put(tdc, dma_desc); + return NULL; + } + } + + return &dma_desc->txd; +} + +static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + + dma_cookie_init(&tdc->dma_chan); + tdc->config_init = false; + return 0; +} + +static void tegra_dma_free_chan_resources(struct dma_chan *dc) +{ + struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + + struct tegra_dma_desc *dma_desc; + struct tegra_dma_sg_req *sg_req; + struct list_head dma_desc_list; + struct list_head sg_req_list; + unsigned long flags; + + INIT_LIST_HEAD(&dma_desc_list); + INIT_LIST_HEAD(&sg_req_list); + + dev_dbg(tdc2dev(tdc), "Freeing channel %d\n", tdc->id); + + if (tdc->busy) + tegra_dma_terminate_all(dc); + + spin_lock_irqsave(&tdc->lock, flags); + list_splice_init(&tdc->pending_sg_req, &sg_req_list); + list_splice_init(&tdc->free_sg_req, &sg_req_list); + list_splice_init(&tdc->free_dma_desc, &dma_desc_list); + INIT_LIST_HEAD(&tdc->cb_desc); + tdc->config_init = false; + spin_unlock_irqrestore(&tdc->lock, flags); + + while (!list_empty(&dma_desc_list)) { + dma_desc = list_first_entry(&dma_desc_list, + typeof(*dma_desc), node); + list_del(&dma_desc->node); + kfree(dma_desc); + } + + while (!list_empty(&sg_req_list)) { + sg_req = list_first_entry(&sg_req_list, typeof(*sg_req), node); + list_del(&sg_req->node); + kfree(sg_req); + } +} + +/* Tegra20 specific DMA controller information */ +static struct tegra_dma_chip_data tegra20_dma_chip_data = { + .nr_channels = 16, + .max_dma_count = 1024UL * 64, +}; + +#if defined(CONFIG_OF) +/* Tegra30 specific DMA controller information */ +static struct tegra_dma_chip_data tegra30_dma_chip_data = { + .nr_channels = 32, + .max_dma_count = 1024UL * 64, +}; + +static const struct of_device_id tegra_dma_of_match[] __devinitconst = { + { + .compatible = "nvidia,tegra30-apbdma-new", + .data = &tegra30_dma_chip_data, + }, { + .compatible = "nvidia,tegra20-apbdma-new", + .data = &tegra20_dma_chip_data, + }, { + }, +}; +MODULE_DEVICE_TABLE(of, tegra_dma_of_match); +#endif + +static int __devinit tegra_dma_probe(struct platform_device *pdev) +{ + struct resource *res; + struct tegra_dma *tdma; + int ret; + int i; + struct tegra_dma_chip_data *cdata = NULL; + + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_device(of_match_ptr(tegra_dma_of_match), + &pdev->dev); + if (!match) { + dev_err(&pdev->dev, "Error: No device match found\n"); + return -ENODEV; + } + cdata = match->data; + } else { + /* If no device tree then fallback to tegra20 */ + cdata = &tegra20_dma_chip_data; + } + + tdma = devm_kzalloc(&pdev->dev, sizeof(*tdma) + cdata->nr_channels * + sizeof(struct tegra_dma_channel), GFP_KERNEL); + if (!tdma) { + dev_err(&pdev->dev, "Error: memory allocation failed\n"); + return -ENOMEM; + } + + tdma->dev = &pdev->dev; + tdma->chip_data = cdata; + platform_set_drvdata(pdev, tdma); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "No mem resource for DMA\n"); + return -EINVAL; + } + + tdma->base_addr = devm_request_and_ioremap(&pdev->dev, res); + if (!tdma->base_addr) { + dev_err(&pdev->dev, + "Cannot request memregion/iomap dma address\n"); + return -EADDRNOTAVAIL; + } + + tdma->dma_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(tdma->dma_clk)) { + dev_err(&pdev->dev, "Error: Missing controller clock\n"); + return PTR_ERR(tdma->dma_clk); + } + + spin_lock_init(&tdma->global_lock); + + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) { + ret = tegra_dma_runtime_resume(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "dma_runtime_resume failed %d\n", + ret); + goto err_pm_disable; + } + } + + /* Reset DMA controller */ + tegra_periph_reset_assert(tdma->dma_clk); + udelay(2); + tegra_periph_reset_deassert(tdma->dma_clk); + + /* Enable global DMA registers */ + tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); + tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); + tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); + + INIT_LIST_HEAD(&tdma->dma_dev.channels); + for (i = 0; i < cdata->nr_channels; i++) { + struct tegra_dma_channel *tdc = &tdma->channels[i]; + char irq_name[30]; + + tdc->chan_base_offset = TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET + + i * TEGRA_APBDMA_CHANNEL_REGISTER_SIZE; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, i); + if (!res) { + ret = -EINVAL; + dev_err(&pdev->dev, "No irq resource for chan %d\n", i); + goto err_irq; + } + tdc->irq = res->start; + snprintf(irq_name, sizeof(irq_name), "apbdma.%d", i); + ret = devm_request_irq(&pdev->dev, tdc->irq, + tegra_dma_isr, 0, irq_name, tdc); + if (ret) { + dev_err(&pdev->dev, + "request_irq failed with err %d channel %d\n", + i, ret); + goto err_irq; + } + + tdc->dma_chan.device = &tdma->dma_dev; + dma_cookie_init(&tdc->dma_chan); + list_add_tail(&tdc->dma_chan.device_node, + &tdma->dma_dev.channels); + tdc->tdma = tdma; + tdc->id = i; + + tasklet_init(&tdc->tasklet, tegra_dma_tasklet, + (unsigned long)tdc); + spin_lock_init(&tdc->lock); + + INIT_LIST_HEAD(&tdc->pending_sg_req); + INIT_LIST_HEAD(&tdc->free_sg_req); + INIT_LIST_HEAD(&tdc->free_dma_desc); + INIT_LIST_HEAD(&tdc->cb_desc); + } + + dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask); + dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask); + tdma->dma_dev.dev = &pdev->dev; + tdma->dma_dev.device_alloc_chan_resources = + tegra_dma_alloc_chan_resources; + tdma->dma_dev.device_free_chan_resources = + tegra_dma_free_chan_resources; + tdma->dma_dev.device_prep_slave_sg = tegra_dma_prep_slave_sg; + tdma->dma_dev.device_prep_dma_cyclic = tegra_dma_prep_dma_cyclic; + tdma->dma_dev.device_control = tegra_dma_device_control; + tdma->dma_dev.device_tx_status = tegra_dma_tx_status; + tdma->dma_dev.device_issue_pending = tegra_dma_issue_pending; + + ret = dma_async_device_register(&tdma->dma_dev); + if (ret < 0) { + dev_err(&pdev->dev, + "Tegra20 APB DMA driver registration failed %d\n", ret); + goto err_irq; + } + + dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n", + cdata->nr_channels); + return 0; + +err_irq: + while (--i >= 0) { + struct tegra_dma_channel *tdc = &tdma->channels[i]; + tasklet_kill(&tdc->tasklet); + } + +err_pm_disable: + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_dma_runtime_suspend(&pdev->dev); + return ret; +} + +static int __devexit tegra_dma_remove(struct platform_device *pdev) +{ + struct tegra_dma *tdma = platform_get_drvdata(pdev); + int i; + struct tegra_dma_channel *tdc; + + dma_async_device_unregister(&tdma->dma_dev); + + for (i = 0; i < tdma->chip_data->nr_channels; ++i) { + tdc = &tdma->channels[i]; + tasklet_kill(&tdc->tasklet); + } + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_dma_runtime_suspend(&pdev->dev); + + return 0; +} + +static int tegra_dma_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tegra_dma *tdma = platform_get_drvdata(pdev); + + clk_disable(tdma->dma_clk); + return 0; +} + +static int tegra_dma_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tegra_dma *tdma = platform_get_drvdata(pdev); + int ret; + + ret = clk_enable(tdma->dma_clk); + if (ret < 0) { + dev_err(dev, "clk_enable failed: %d\n", ret); + return ret; + } + return 0; +} + +static const struct dev_pm_ops tegra_dma_dev_pm_ops __devinitconst = { +#ifdef CONFIG_PM_RUNTIME + .runtime_suspend = tegra_dma_runtime_suspend, + .runtime_resume = tegra_dma_runtime_resume, +#endif +}; + +static struct platform_driver tegra_dmac_driver = { + .driver = { + .name = "tegra20-apbdma", + .owner = THIS_MODULE, + .pm = &tegra_dma_dev_pm_ops, + .of_match_table = of_match_ptr(tegra_dma_of_match), + }, + .probe = tegra_dma_probe, + .remove = __devexit_p(tegra_dma_remove), +}; + +module_platform_driver(tegra_dmac_driver); + +MODULE_ALIAS("platform:tegra20-apbdma"); +MODULE_DESCRIPTION("NVIDIA Tegra APB DMA Controller driver"); +MODULE_AUTHOR("Laxman Dewangan "); +MODULE_LICENSE("GPL v2"); -- GitLab From 8e56130dcbcc0608c2531c61f93175e36a300e58 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 6 Jun 2012 17:20:10 -0500 Subject: [PATCH 0953/6849] ARM: highbank: Add smc calls to enable/disable the L2 Linux runs in non-secure mode on highbank, so we need secure monitor calls to enable and disable the PL310. Rather than invent new smc calls, the same calling convention used by OMAP is used here. Signed-off-by: Rob Herring Signed-off-by: Olof Johansson --- arch/arm/mach-highbank/Makefile | 6 +++++- arch/arm/mach-highbank/core.h | 1 + arch/arm/mach-highbank/highbank.c | 14 ++++++++++++++ arch/arm/mach-highbank/smc.S | 27 +++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-highbank/smc.S diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile index f8437dd238c2..ded4652ada80 100644 --- a/arch/arm/mach-highbank/Makefile +++ b/arch/arm/mach-highbank/Makefile @@ -1,4 +1,8 @@ -obj-y := clock.o highbank.o system.o +obj-y := clock.o highbank.o system.o smc.o + +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) + obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h index d8e2d0be64ac..141ed5171826 100644 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@ -8,3 +8,4 @@ extern void highbank_lluart_map_io(void); static inline void highbank_lluart_map_io(void) {} #endif +extern void highbank_smc1(int fn, int arg); diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 410a112bb52e..8777612b1a42 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -85,10 +85,24 @@ const static struct of_device_id irq_match[] = { {} }; +#ifdef CONFIG_CACHE_L2X0 +static void highbank_l2x0_disable(void) +{ + /* Disable PL310 L2 Cache controller */ + highbank_smc1(0x102, 0x0); +} +#endif + static void __init highbank_init_irq(void) { of_irq_init(irq_match); + +#ifdef CONFIG_CACHE_L2X0 + /* Enable PL310 L2 Cache controller */ + highbank_smc1(0x102, 0x1); l2x0_of_init(0, ~0UL); + outer_cache.disable = highbank_l2x0_disable; +#endif } static void __init highbank_timer_init(void) diff --git a/arch/arm/mach-highbank/smc.S b/arch/arm/mach-highbank/smc.S new file mode 100644 index 000000000000..407d17baaaa9 --- /dev/null +++ b/arch/arm/mach-highbank/smc.S @@ -0,0 +1,27 @@ +/* + * Copied from omap44xx-smc.S Copyright (C) 2010 Texas Instruments, Inc. + * Copyright 2012 Calxeda, Inc. + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. + * Function signature : void highbank_smc1(u32 fn, u32 arg) + */ + +ENTRY(highbank_smc1) + stmfd sp!, {r4-r11, lr} + mov r12, r0 + mov r0, r1 + dsb + smc #0 + ldmfd sp!, {r4-r11, pc} +ENDPROC(highbank_smc1) -- GitLab From 4c47d7396420160d27209f578680141874c0110b Mon Sep 17 00:00:00 2001 From: Vishal Agarwal Date: Thu, 7 Jun 2012 20:27:35 +0530 Subject: [PATCH 0954/6849] Bluetooth: Fix LE pairing completion on connection failure For BR/EDR pairing is assumed to be finished when connection is done. For LE if connection is successful it did not necessarily mean that pairing is also done but if the connection is unsuccessful it should be assumed that pairing procedure is also finished. This patch registers a new function with connect_cfm_cb callback for LE link which sends the pairing complete signal to user space if connection is unsuccessful. Signed-off-by: Vishal Agarwal Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 25d220776079..991d5b667674 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1873,6 +1873,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) pairing_complete(cmd, mgmt_status(status)); } +static void le_connect_complete_cb(struct hci_conn *conn, u8 status) +{ + struct pending_cmd *cmd; + + BT_DBG("status %u", status); + + if (!status) + return; + + cmd = find_pairing(conn); + if (!cmd) + BT_DBG("Unable to find a pending command"); + else + pairing_complete(cmd, mgmt_status(status)); +} + static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { @@ -1934,6 +1950,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, /* For LE, just connecting isn't a proof that the pairing finished */ if (cp->addr.type == BDADDR_BREDR) conn->connect_cfm_cb = pairing_complete_cb; + else + conn->connect_cfm_cb = le_connect_complete_cb; conn->security_cfm_cb = pairing_complete_cb; conn->disconn_cfm_cb = pairing_complete_cb; -- GitLab From bc8e261233cf0f1ad838f60bac782df3a5bc6bac Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Thu, 7 Jun 2012 23:39:20 +0300 Subject: [PATCH 0955/6849] wlcore: add support macros to easily add conf debugfs entries The current debugfs code contains too much code duplication of bolierplate code. Add some macro magic to avoid this and enable adding new debugfs entries by using just a few lines. Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/debugfs.c | 75 ++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index fcd60636e9d1..50300ff0acb4 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -102,6 +102,81 @@ static const struct file_operations tx_queue_len_ops = { .llseek = default_llseek, }; +static void chip_op_handler(struct wl1271 *wl, unsigned long value, + void *arg) +{ + int ret; + int (*chip_op) (struct wl1271 *wl); + + if (!arg) { + wl1271_warning("debugfs chip_op_handler with no callback"); + return; + } + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + return; + + chip_op = arg; + chip_op(wl); + + wl1271_ps_elp_sleep(wl); +} + + +static inline void no_write_handler(struct wl1271 *wl, + unsigned long value, + unsigned long param) +{ +} + +#define WL12XX_CONF_DEBUGFS(param, conf_sub_struct, \ + min_val, max_val, write_handler_locked, \ + write_handler_arg) \ + static ssize_t param##_read(struct file *file, \ + char __user *user_buf, \ + size_t count, loff_t *ppos) \ + { \ + struct wl1271 *wl = file->private_data; \ + return wl1271_format_buffer(user_buf, count, \ + ppos, "%d\n", \ + wl->conf.conf_sub_struct.param); \ + } \ + \ + static ssize_t param##_write(struct file *file, \ + const char __user *user_buf, \ + size_t count, loff_t *ppos) \ + { \ + struct wl1271 *wl = file->private_data; \ + unsigned long value; \ + int ret; \ + \ + ret = kstrtoul_from_user(user_buf, count, 10, &value); \ + if (ret < 0) { \ + wl1271_warning("illegal value for " #param); \ + return -EINVAL; \ + } \ + \ + if (value < min_val || value > max_val) { \ + wl1271_warning(#param " is not in valid range"); \ + return -ERANGE; \ + } \ + \ + mutex_lock(&wl->mutex); \ + wl->conf.conf_sub_struct.param = value; \ + \ + write_handler_locked(wl, value, write_handler_arg); \ + \ + mutex_unlock(&wl->mutex); \ + return count; \ + } \ + \ + static const struct file_operations param##_ops = { \ + .read = param##_read, \ + .write = param##_write, \ + .open = simple_open, \ + .llseek = default_llseek, \ + }; static ssize_t gpio_power_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { -- GitLab From 3e8d69352bd9ac7287ab735d45582d79c1f9f2d9 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Thu, 7 Jun 2012 23:39:21 +0300 Subject: [PATCH 0956/6849] wlcore: add debugfs control over rx interrupt pacing Add control over several conf fields which combined control the rx interrupt pacing mechanism, that is avoiding getting an interrupt following a single frame rx but instead have the FW trigger the interrupt only after a certain amount of frames received or a timeout. Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/debugfs.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 50300ff0acb4..827a728fd663 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -177,6 +177,14 @@ static inline void no_write_handler(struct wl1271 *wl, .open = simple_open, \ .llseek = default_llseek, \ }; + +WL12XX_CONF_DEBUGFS(irq_pkt_threshold, rx, 0, 65535, + chip_op_handler, wl1271_acx_init_rx_interrupt) +WL12XX_CONF_DEBUGFS(irq_blk_threshold, rx, 0, 65535, + chip_op_handler, wl1271_acx_init_rx_interrupt) +WL12XX_CONF_DEBUGFS(irq_timeout, rx, 0, 100, + chip_op_handler, wl1271_acx_init_rx_interrupt) + static ssize_t gpio_power_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -957,6 +965,9 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(dynamic_ps_timeout, rootdir); DEBUGFS_ADD(forced_ps, rootdir); DEBUGFS_ADD(split_scan_timeout, rootdir); + DEBUGFS_ADD(irq_pkt_threshold, rootdir); + DEBUGFS_ADD(irq_blk_threshold, rootdir); + DEBUGFS_ADD(irq_timeout, rootdir); streaming = debugfs_create_dir("rx_streaming", rootdir); if (!streaming || IS_ERR(streaming)) -- GitLab From f74ea74b82cf6b6aeef1e46d68fbbb02d2bce8b7 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:22 +0300 Subject: [PATCH 0957/6849] wl18xx: add support to clear FW statistics This patch calls ACX_CLEAR_STATISTICS to clear the firmware statistics. The trigger is a new debugfs file called clear_fw_statistics in the fw_stats directory. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/acx.c | 24 +++++++++++++++++++ drivers/net/wireless/ti/wl18xx/acx.h | 9 +++++++ drivers/net/wireless/ti/wl18xx/debugfs.c | 30 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c index 01ba40321435..72840e23bf59 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.c +++ b/drivers/net/wireless/ti/wl18xx/acx.c @@ -85,3 +85,27 @@ out: kfree(acx); return ret; } + +int wl18xx_acx_clear_statistics(struct wl1271 *wl) +{ + struct wl18xx_acx_clear_statistics *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx clear statistics"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + ret = wl1271_cmd_configure(wl, ACX_CLEAR_STATISTICS, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("failed to clear firmware statistics: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index 7d74b031f114..3e5cd9fddcf1 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -25,6 +25,10 @@ #include "../wlcore/wlcore.h" #include "../wlcore/acx.h" +enum { + ACX_CLEAR_STATISTICS = 0x0047, +}; + /* numbers of bits the length field takes (add 1 for the actual number) */ #define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 @@ -253,9 +257,14 @@ struct wl18xx_acx_statistics { struct wl18xx_acx_mem_stats mem; } __packed; +struct wl18xx_acx_clear_statistics { + struct acx_header header; +}; + int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, u32 sdio_blk_size, u32 extra_mem_blks, u32 len_field_size); int wl18xx_acx_set_checksum_state(struct wl1271 *wl); +int wl18xx_acx_clear_statistics(struct wl1271 *wl); #endif /* __WL18XX_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c index 93c625b23a2f..468651c2f54c 100644 --- a/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -158,6 +158,34 @@ WL18XX_DEBUGFS_FWSTATS_FILE(mem, tx_free_mem_blks, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(mem, fwlog_free_mem_blks, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(mem, fw_gen_free_mem_blks, "%u"); +static ssize_t clear_fw_stats_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + int ret; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) + goto out; + + ret = wl18xx_acx_clear_statistics(wl); + if (ret < 0) { + count = ret; + goto out; + } +out: + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations clear_fw_stats_ops = { + .write = clear_fw_stats_write, + .open = simple_open, + .llseek = default_llseek, +}; + int wl18xx_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -176,6 +204,8 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, goto err; } + DEBUGFS_ADD(clear_fw_stats, stats); + DEBUGFS_FWSTATS_ADD(debug, debug1); DEBUGFS_FWSTATS_ADD(debug, debug2); DEBUGFS_FWSTATS_ADD(debug, debug3); -- GitLab From 9c6ead570c6b88b865fca15bdc0d09e2d90d2130 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:23 +0300 Subject: [PATCH 0958/6849] wlcore: export raw binary with the FW statistics in debugfs Instead of parsing all the binary data returned by the firmware, we should simply export the binary and let the userspace do the parsing. This commit adds a new file to debugfs to do that. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/debugfs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 827a728fd663..689a847005c9 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -944,6 +944,25 @@ static const struct file_operations beacon_filtering_ops = { .llseek = default_llseek, }; +static ssize_t fw_stats_raw_read(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + + wl1271_debugfs_update_stats(wl); + + return simple_read_from_buffer(userbuf, count, ppos, + wl->stats.fw_stats, + wl->stats.fw_stats_len); +} + +static const struct file_operations fw_stats_raw_ops = { + .read = fw_stats_raw_read, + .open = simple_open, + .llseek = default_llseek, +}; + static int wl1271_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -968,6 +987,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(irq_pkt_threshold, rootdir); DEBUGFS_ADD(irq_blk_threshold, rootdir); DEBUGFS_ADD(irq_timeout, rootdir); + DEBUGFS_ADD(fw_stats_raw, rootdir); streaming = debugfs_create_dir("rx_streaming", rootdir); if (!streaming || IS_ERR(streaming)) -- GitLab From 648f6ed9f7f0e4d56d65266734e748a02f8e2df7 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:24 +0300 Subject: [PATCH 0959/6849] wlcore/wl18xx/wl12xx: use u8 instead of bool for host_fast_wakeup_support The conf structure is going to be exported to a file, so we should use only well defined types. bool is not well defined and may vary from platform to platform, so change the host_fast_wakeup_support type to u8 instead. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 2 +- drivers/net/wireless/ti/wl18xx/main.c | 2 +- drivers/net/wireless/ti/wlcore/conf.h | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 8338045d226f..85d1600ee340 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -253,7 +253,7 @@ static struct wlcore_conf wl12xx_conf = { }, .pm_config = { .host_clk_settling_time = 5000, - .host_fast_wakeup_support = false + .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE, }, .roam_trigger = { .trigger_pacing = 1, diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index fd02795f830c..b6a80cd5e9ef 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -376,7 +376,7 @@ static struct wlcore_conf wl18xx_conf = { }, .pm_config = { .host_clk_settling_time = 5000, - .host_fast_wakeup_support = false + .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE, }, .roam_trigger = { .trigger_pacing = 1, diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index d2c4885d0d77..2e84ae113fce 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -981,6 +981,11 @@ struct conf_itrim_settings { u32 timeout; }; +enum conf_fast_wakeup { + CONF_FAST_WAKEUP_ENABLE, + CONF_FAST_WAKEUP_DISABLE, +}; + struct conf_pm_config_settings { /* * Host clock settling time @@ -992,9 +997,9 @@ struct conf_pm_config_settings { /* * Host fast wakeup support * - * Range: true, false + * Range: enum conf_fast_wakeup */ - bool host_fast_wakeup_support; + u8 host_fast_wakeup_support; }; struct conf_roam_trigger_settings { -- GitLab From b551a3c9eb625326b11154a604fce2108f70fb96 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:25 +0300 Subject: [PATCH 0960/6849] wlcore: use u8 instead of enum for bcn_filt_mode Since we will export the conf structure as a file, we need to use well defined types. Instead of using enum, whose size may vary, use u8 for bcn_filt_mode instead. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 2e84ae113fce..0950bd22f4d9 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -824,7 +824,7 @@ struct conf_conn_settings { * * Range: CONF_BCN_FILT_MODE_* */ - enum conf_bcn_filt_mode bcn_filt_mode; + u8 bcn_filt_mode; /* * Configure Beacon filter pass-thru rules. -- GitLab From 34bacf73c62cd71542ee12eba5896e1f360faa9b Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:26 +0300 Subject: [PATCH 0961/6849] wlcore/wl18xx: the conf structs must be packed so they can be exported Since we are now going to export the conf structure and read it from a file, it should be packed to avoid surprises with padding bytes. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/conf.h | 4 +-- drivers/net/wireless/ti/wlcore/conf.h | 44 +++++++++++++-------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index 4e0f189b2539..b75a6d359712 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -48,10 +48,10 @@ struct wl18xx_conf_phy { s8 low_power_val; s8 med_power_val; s8 high_power_val; -}; +} __packed; struct wl18xx_priv_conf { struct wl18xx_conf_phy phy; -}; +} __packed; #endif /* __WL18XX_CONF_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 0950bd22f4d9..27d919fa997f 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -318,7 +318,7 @@ enum { struct conf_sg_settings { u32 params[CONF_SG_PARAMS_MAX]; u8 state; -}; +} __packed; enum conf_rx_queue_type { CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */ @@ -402,7 +402,7 @@ struct conf_rx_settings { * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY, */ u8 queue_type; -}; +} __packed; #define CONF_TX_MAX_RATE_CLASSES 10 @@ -501,7 +501,7 @@ struct conf_tx_rate_class { * the policy (0 - long preamble, 1 - short preamble. */ u8 aflags; -}; +} __packed; #define CONF_TX_MAX_AC_COUNT 4 @@ -558,7 +558,7 @@ struct conf_tx_ac_category { * Range: u16 */ u16 tx_op_limit; -}; +} __packed; #define CONF_TX_MAX_TID_COUNT 8 @@ -592,7 +592,7 @@ struct conf_tx_tid { u8 ps_scheme; u8 ack_policy; u32 apsd_conf[2]; -}; +} __packed; struct conf_tx_settings { /* @@ -678,7 +678,7 @@ struct conf_tx_settings { /* Time in ms for Tx watchdog timer to expire */ u32 tx_watchdog_timeout; -}; +} __packed; enum { CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/ @@ -725,7 +725,7 @@ struct conf_bcn_filt_rule { * Version for the vendor specifie IE (221) */ u8 version[CONF_BCN_IE_VER_LEN]; -}; +} __packed; #define CONF_MAX_RSSI_SNR_TRIGGERS 8 @@ -776,7 +776,7 @@ struct conf_sig_weights { * Range: u8 */ u8 snr_pkt_avg_weight; -}; +} __packed; enum conf_bcn_filt_mode { CONF_BCN_FILT_MODE_DISABLED = 0, @@ -951,7 +951,7 @@ struct conf_conn_settings { * Range: u16 */ u8 max_listen_interval; -}; +} __packed; enum { CONF_REF_CLK_19_2_E, @@ -979,7 +979,7 @@ struct conf_itrim_settings { /* moderation timeout in microsecs from the last TX */ u32 timeout; -}; +} __packed; enum conf_fast_wakeup { CONF_FAST_WAKEUP_ENABLE, @@ -1000,7 +1000,7 @@ struct conf_pm_config_settings { * Range: enum conf_fast_wakeup */ u8 host_fast_wakeup_support; -}; +} __packed; struct conf_roam_trigger_settings { /* @@ -1037,7 +1037,7 @@ struct conf_roam_trigger_settings { * Range: 0 - 255 */ u8 avg_weight_snr_data; -}; +} __packed; struct conf_scan_settings { /* @@ -1083,7 +1083,7 @@ struct conf_scan_settings { * Range: u32 Microsecs */ u32 split_scan_timeout; -}; +} __packed; struct conf_sched_scan_settings { /* @@ -1121,7 +1121,7 @@ struct conf_sched_scan_settings { /* SNR threshold to be used for filtering */ s8 snr_threshold; -}; +} __packed; struct conf_ht_setting { u8 rx_ba_win_size; @@ -1130,7 +1130,7 @@ struct conf_ht_setting { /* bitmap of enabled TIDs for TX BA sessions */ u8 tx_ba_tid_bitmap; -}; +} __packed; struct conf_memory_settings { /* Number of stations supported in IBSS mode */ @@ -1170,7 +1170,7 @@ struct conf_memory_settings { * Range: 0-120 */ u8 tx_min; -}; +} __packed; struct conf_fm_coex { u8 enable; @@ -1183,7 +1183,7 @@ struct conf_fm_coex { u16 ldo_stabilization_time; u8 fm_disturbed_band_margin; u8 swallow_clk_diff; -}; +} __packed; struct conf_rx_streaming_settings { /* @@ -1212,7 +1212,7 @@ struct conf_rx_streaming_settings { * enable rx streaming also when there is no coex activity */ u8 always; -}; +} __packed; struct conf_fwlog { /* Continuous or on-demand */ @@ -1236,7 +1236,7 @@ struct conf_fwlog { /* Regulates the frequency of log messages */ u8 threshold; -}; +} __packed; #define ACX_RATE_MGMT_NUM_OF_RATES 13 struct conf_rate_policy_settings { @@ -1255,7 +1255,7 @@ struct conf_rate_policy_settings { u8 rate_check_up; u8 rate_check_down; u8 rate_retry_policy[ACX_RATE_MGMT_NUM_OF_RATES]; -}; +} __packed; struct conf_hangover_settings { u32 recover_time; @@ -1269,7 +1269,7 @@ struct conf_hangover_settings { u8 quiet_time; u8 increase_time; u8 window_size; -}; +} __packed; struct wlcore_conf { struct conf_sg_settings sg; @@ -1288,6 +1288,6 @@ struct wlcore_conf { struct conf_fwlog fwlog; struct conf_rate_policy_settings rate; struct conf_hangover_settings hangover; -}; +} __packed; #endif -- GitLab From 18b70ac9c7fd640cbd5921b5ca2705db0f8b9d83 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:27 +0300 Subject: [PATCH 0962/6849] wlcore/wl18xx: export conf struct in a debugfs file Add conf file header structure, magic and version values and export the entire conf struct in debugfs. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/conf.h | 6 ++++ drivers/net/wireless/ti/wl18xx/debugfs.c | 44 ++++++++++++++++++++++++ drivers/net/wireless/ti/wlcore/conf.h | 22 ++++++++++++ 3 files changed, 72 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index b75a6d359712..130546aa970d 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -22,6 +22,12 @@ #ifndef __WL18XX_CONF_H__ #define __WL18XX_CONF_H__ +#define WL18XX_CONF_MAGIC 0x10e100ca +#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0001) +#define WL18XX_CONF_MASK 0x0000ffff +#define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ + sizeof(struct wl18xx_priv_conf)) + struct wl18xx_conf_phy { u8 phy_standalone; u8 rdl; diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c index 468651c2f54c..96b149662906 100644 --- a/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -158,6 +158,48 @@ WL18XX_DEBUGFS_FWSTATS_FILE(mem, tx_free_mem_blks, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(mem, fwlog_free_mem_blks, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(mem, fw_gen_free_mem_blks, "%u"); +static ssize_t conf_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + struct wl18xx_priv *priv = wl->priv; + struct wlcore_conf_header header; + char *buf, *pos; + size_t len; + int ret; + + len = WL18XX_CONF_SIZE; + buf = kmalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + header.magic = cpu_to_le32(WL18XX_CONF_MAGIC); + header.version = cpu_to_le32(WL18XX_CONF_VERSION); + header.checksum = 0; + + mutex_lock(&wl->mutex); + + pos = buf; + memcpy(pos, &header, sizeof(header)); + pos += sizeof(header); + memcpy(pos, &wl->conf, sizeof(wl->conf)); + pos += sizeof(wl->conf); + memcpy(pos, &priv->conf, sizeof(priv->conf)); + + mutex_unlock(&wl->mutex); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + + kfree(buf); + return ret; +} + +static const struct file_operations conf_ops = { + .read = conf_read, + .open = simple_open, + .llseek = default_llseek, +}; + static ssize_t clear_fw_stats_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -327,6 +369,8 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(mem, fwlog_free_mem_blks); DEBUGFS_FWSTATS_ADD(mem, fw_gen_free_mem_blks); + DEBUGFS_ADD(conf, moddir); + return 0; err: diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 27d919fa997f..03c635872335 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -1271,6 +1271,22 @@ struct conf_hangover_settings { u8 window_size; } __packed; +/* + * The conf version consists of 4 bytes. The two MSB are the wlcore + * version, the two LSB are the lower driver's private conf + * version. + */ +#define WLCORE_CONF_VERSION (0x0001 << 16) +#define WLCORE_CONF_MASK 0xffff0000 +#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \ + sizeof(struct wlcore_conf)) + +struct wlcore_conf_header { + __le32 magic; + __le32 version; + __le32 checksum; +} __packed; + struct wlcore_conf { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1290,4 +1306,10 @@ struct wlcore_conf { struct conf_hangover_settings hangover; } __packed; +struct wlcore_conf_file { + struct wlcore_conf_header header; + struct wlcore_conf core; + u8 priv[0]; +} __packed; + #endif -- GitLab From 640dfb9b85bc80c607c07531dc5428418ef39974 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 7 Jun 2012 23:39:28 +0300 Subject: [PATCH 0963/6849] wl18xx: read configuration structure from a binary file Instead of using the hardcoded configuration structure, try to read it from a "firmware" file called wl18xx-conf.bin. If the file doesn't exist, fall back to the hardcoded version. If the file exists but is illegal, bail out. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 68 +++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b6a80cd5e9ef..9cdf24f70964 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" @@ -1046,15 +1047,65 @@ static s8 wl18xx_get_pg_ver(struct wl1271 *wl) return (s8)fuse; } -static void wl18xx_conf_init(struct wl1271 *wl) +#define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin" +static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) { struct wl18xx_priv *priv = wl->priv; + struct wlcore_conf_file *conf_file; + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, WL18XX_CONF_FILE_NAME, dev); + if (ret < 0) { + wl1271_error("could not get configuration binary %s: %d", + WL18XX_CONF_FILE_NAME, ret); + goto out_fallback; + } + + if (fw->size != WL18XX_CONF_SIZE) { + wl1271_error("configuration binary file size is wrong, " + "expected %d got %d", WL18XX_CONF_SIZE, fw->size); + ret = -EINVAL; + goto out; + } + + conf_file = (struct wlcore_conf_file *) fw->data; + + if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) { + wl1271_error("configuration binary file magic number mismatch, " + "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC, + conf_file->header.magic); + ret = -EINVAL; + goto out; + } + + if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) { + wl1271_error("configuration binary file version not supported, " + "expected 0x%08x got 0x%08x", + WL18XX_CONF_VERSION, conf_file->header.version); + ret = -EINVAL; + goto out; + } + + memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf)); + memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf)); + + goto out; + +out_fallback: + wl1271_warning("falling back to default config"); /* apply driver default configuration */ memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf)); - /* apply default private configuration */ memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); + + /* For now we just fallback */ + return 0; + +out: + release_firmware(fw); + return ret; } static int wl18xx_plt_init(struct wl1271 *wl) @@ -1261,11 +1312,13 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) struct wl1271 *wl; struct ieee80211_hw *hw; struct wl18xx_priv *priv; + int ret; hw = wlcore_alloc_hw(sizeof(*priv)); if (IS_ERR(hw)) { wl1271_error("can't allocate hw"); - return PTR_ERR(hw); + ret = PTR_ERR(hw); + goto out; } wl = hw->priv; @@ -1305,10 +1358,13 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) sizeof(wl18xx_siso20_ht_cap)); } else { wl1271_error("invalid ht_mode '%s'", ht_mode_param); + ret = -EINVAL; goto out_free; } - wl18xx_conf_init(wl); + ret = wl18xx_conf_init(wl, &pdev->dev); + if (ret < 0) + goto out_free; if (!strcmp(board_type_param, "fpga")) { priv->board_type = BOARD_TYPE_FPGA_18XX; @@ -1326,6 +1382,7 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) priv->conf.phy.low_band_component_type = 0x06; } else { wl1271_error("invalid board type '%s'", board_type_param); + ret = -EINVAL; goto out_free; } @@ -1373,7 +1430,8 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) out_free: wlcore_free_hw(wl); - return -EINVAL; +out: + return ret; } static const struct platform_device_id wl18xx_id_table[] __devinitconst = { -- GitLab From e27454b01304188205190238791b31efbfecfc04 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 May 2012 08:39:43 +0300 Subject: [PATCH 0964/6849] wl18xx: allow FW-log by default for PG2.0 This is supported by new FW versions (.88+). Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 9cdf24f70964..c26015b8830c 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -600,7 +600,6 @@ static int wl18xx_identify_chip(struct wl1271 *wl) /* wl18xx uses the same firmware for PLT */ wl->plt_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | - WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | WLCORE_QUIRK_TX_PAD_LAST_FRAME; -- GitLab From d06cc416f517a25713dedd9e2a9ccf4f3086c09a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 6 Jun 2012 18:44:11 +0800 Subject: [PATCH 0965/6849] Bluetooth: Fix deadlock and crash when SMP pairing times out The l2cap_conn_del function tries to cancel_sync the security timer, but when it's called from the timeout function itself a deadlock occurs. Subsequently the "hcon->l2cap_data = NULL" that's supposed to protect multiple calls to l2cap_conn_del never gets cleared and when the connection finally drops we double free's etc which will crash the kernel. This patch fixes the issue by using the HCI_CONN_LE_SMP_PEND for protecting against this. The same flag is also used for the same purpose in other places in the SMP code. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 24f144b72a96..8394e3615ef6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1295,7 +1295,12 @@ static void security_timeout(struct work_struct *work) struct l2cap_conn *conn = container_of(work, struct l2cap_conn, security_timer.work); - l2cap_conn_del(conn->hcon, ETIMEDOUT); + BT_DBG("conn %p", conn); + + if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { + smp_chan_destroy(conn); + l2cap_conn_del(conn->hcon, ETIMEDOUT); + } } static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) -- GitLab From 8dd8e53c6f0a5116b988445484b1d68d8e22ced9 Mon Sep 17 00:00:00 2001 From: Ido Reis Date: Tue, 22 May 2012 12:34:10 +0300 Subject: [PATCH 0966/6849] wl18xx: update fw statistics Aligned to the struct in FW 8.2.0.0.91 and updated the debugfs entries accordingly. Signed-off-by: Ido Reis Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/acx.h | 33 +++++++++++--- drivers/net/wireless/ti/wl18xx/debugfs.c | 56 ++++++++++++++++-------- 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index 3e5cd9fddcf1..ebbaf611e97b 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -85,6 +85,15 @@ struct wl18xx_acx_checksum_state { u8 pad[3]; } __packed; + +struct wl18xx_acx_error_stats { + u32 error_frame; + u32 error_null_Frame_tx_start; + u32 error_numll_frame_cts_start; + u32 error_bar_retry; + u32 error_frame_cts_nul_flid; +} __packed; + struct wl18xx_acx_debug_stats { u32 debug1; u32 debug2; @@ -100,6 +109,8 @@ struct wl18xx_acx_ring_stats { } __packed; struct wl18xx_acx_tx_stats { + u32 tx_prepared_descs; + u32 tx_cmplt; u32 tx_template_prepared; u32 tx_data_prepared; u32 tx_template_programmed; @@ -136,7 +147,8 @@ struct wl18xx_acx_tx_stats { } __packed; struct wl18xx_acx_rx_stats { - u32 rx_out_of_mem; + u32 rx_beacon_early_term; + u32 rx_out_of_mpdu_nodes; u32 rx_hdr_overflow; u32 rx_dropped_frame; u32 rx_done_stage; @@ -148,6 +160,9 @@ struct wl18xx_acx_rx_stats { u32 rx_cmplt_task; u32 rx_phy_hdr; u32 rx_timeout; + u32 rx_timeout_wa; + u32 rx_wa_density_dropped_frame; + u32 rx_wa_ba_not_expected; u32 rx_frame_checksum; u32 rx_checksum_result; u32 defrag_called; @@ -158,6 +173,7 @@ struct wl18xx_acx_rx_stats { u32 defrag_decrypt_failed; u32 decrypt_key_not_found; u32 defrag_need_decrypt; + u32 rx_tkip_replays; } __packed; struct wl18xx_acx_isr_stats { @@ -197,20 +213,25 @@ struct wl18xx_acx_rx_filter_stats { u32 data_filter; u32 ibss_filter; u32 protection_filter; + u32 accum_arp_pend_requests; + u32 max_arp_queue_dep; } __packed; struct wl18xx_acx_rx_rate_stats { u32 rx_frames_per_rates[50]; } __packed; -#define AGGR_STATS_TX_SIZE_LEN 11 -#define AGGR_STATS_RX_SIZE_LEN 11 +#define AGGR_STATS_TX_AGG 16 +#define AGGR_STATS_TX_RATE 16 +#define AGGR_STATS_RX_SIZE_LEN 16 struct wl18xx_acx_aggr_stats { - u32 tx_size[AGGR_STATS_TX_SIZE_LEN]; + u32 tx_agg_vs_rate[AGGR_STATS_TX_AGG * AGGR_STATS_TX_RATE]; u32 rx_size[AGGR_STATS_RX_SIZE_LEN]; } __packed; +#define PIPE_STATS_HW_FIFO 11 + struct wl18xx_acx_pipeline_stats { u32 hs_tx_stat_fifo_int; u32 hs_rx_stat_fifo_int; @@ -230,6 +251,7 @@ struct wl18xx_acx_pipeline_stats { u32 dec_packet_out; u32 cs_rx_packet_in; u32 cs_rx_packet_out; + u16 pipeline_fifo_full[PIPE_STATS_HW_FIFO]; } __packed; struct wl18xx_acx_mem_stats { @@ -242,13 +264,12 @@ struct wl18xx_acx_mem_stats { struct wl18xx_acx_statistics { struct acx_header header; - struct wl18xx_acx_ring_stats ring; + struct wl18xx_acx_error_stats error; struct wl18xx_acx_debug_stats debug; struct wl18xx_acx_tx_stats tx; struct wl18xx_acx_rx_stats rx; struct wl18xx_acx_isr_stats isr; struct wl18xx_acx_pwr_stats pwr; - struct wl18xx_acx_event_stats event; struct wl18xx_acx_ps_poll_stats ps_poll; struct wl18xx_acx_rx_filter_stats rx_filter; struct wl18xx_acx_rx_rate_stats rx_rate; diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c index 96b149662906..3ce6f1039af3 100644 --- a/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -40,9 +40,14 @@ WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug4, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug5, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug6, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, prepared_descs, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ring, tx_cmplt, "%u"); - +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_null_Frame_tx_start, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_numll_frame_cts_start, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_bar_retry, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_cts_nul_flid, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_prepared_descs, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cmplt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_prepared, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_prepared, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_programmed, "%u"); @@ -77,7 +82,8 @@ WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_failed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_hit, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_miss, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_out_of_mem, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_beacon_early_term, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_out_of_mpdu_nodes, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hdr_overflow, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_dropped_frame, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done, "%u"); @@ -88,6 +94,9 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_pre_complt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt_task, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_phy_hdr, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout_wa, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_wa_density_dropped_frame, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_wa_ba_not_expected, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_frame_checksum, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_checksum_result, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_called, "%u"); @@ -98,6 +107,7 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_defrag, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_decrypt_failed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, decrypt_key_not_found, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_decrypt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_tkip_replays, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); @@ -109,10 +119,6 @@ WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pwr, cont_miss_bcns_spread, WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_bcns_cnt, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); - WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_timeouts, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_timeouts, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_max_ap_turn, "%u"); @@ -127,11 +133,13 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, dup_filter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, data_filter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, ibss_filter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, protection_filter, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, accum_arp_pend_requests, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, max_arp_queue_dep, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_rate, rx_frames_per_rates, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_size, - AGGR_STATS_TX_SIZE_LEN); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_vs_rate, + AGGR_STATS_TX_AGG*AGGR_STATS_TX_RATE); WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, rx_size, AGGR_STATS_RX_SIZE_LEN); @@ -153,6 +161,9 @@ WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_out, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_in, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_out, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pipeline, pipeline_fifo_full, + PIPE_STATS_HW_FIFO); + WL18XX_DEBUGFS_FWSTATS_FILE(mem, rx_free_mem_blks, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(mem, tx_free_mem_blks, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(mem, fwlog_free_mem_blks, "%u"); @@ -255,9 +266,14 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(debug, debug5); DEBUGFS_FWSTATS_ADD(debug, debug6); - DEBUGFS_FWSTATS_ADD(ring, prepared_descs); - DEBUGFS_FWSTATS_ADD(ring, tx_cmplt); + DEBUGFS_FWSTATS_ADD(error, error_frame); + DEBUGFS_FWSTATS_ADD(error, error_null_Frame_tx_start); + DEBUGFS_FWSTATS_ADD(error, error_numll_frame_cts_start); + DEBUGFS_FWSTATS_ADD(error, error_bar_retry); + DEBUGFS_FWSTATS_ADD(error, error_frame_cts_nul_flid); + DEBUGFS_FWSTATS_ADD(tx, tx_prepared_descs); + DEBUGFS_FWSTATS_ADD(tx, tx_cmplt); DEBUGFS_FWSTATS_ADD(tx, tx_template_prepared); DEBUGFS_FWSTATS_ADD(tx, tx_data_prepared); DEBUGFS_FWSTATS_ADD(tx, tx_template_programmed); @@ -292,7 +308,8 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(tx, frag_cache_hit); DEBUGFS_FWSTATS_ADD(tx, frag_cache_miss); - DEBUGFS_FWSTATS_ADD(rx, rx_out_of_mem); + DEBUGFS_FWSTATS_ADD(rx, rx_beacon_early_term); + DEBUGFS_FWSTATS_ADD(rx, rx_out_of_mpdu_nodes); DEBUGFS_FWSTATS_ADD(rx, rx_hdr_overflow); DEBUGFS_FWSTATS_ADD(rx, rx_dropped_frame); DEBUGFS_FWSTATS_ADD(rx, rx_done); @@ -303,6 +320,9 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx, rx_cmplt_task); DEBUGFS_FWSTATS_ADD(rx, rx_phy_hdr); DEBUGFS_FWSTATS_ADD(rx, rx_timeout); + DEBUGFS_FWSTATS_ADD(rx, rx_timeout_wa); + DEBUGFS_FWSTATS_ADD(rx, rx_wa_density_dropped_frame); + DEBUGFS_FWSTATS_ADD(rx, rx_wa_ba_not_expected); DEBUGFS_FWSTATS_ADD(rx, rx_frame_checksum); DEBUGFS_FWSTATS_ADD(rx, rx_checksum_result); DEBUGFS_FWSTATS_ADD(rx, defrag_called); @@ -313,6 +333,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx, defrag_decrypt_failed); DEBUGFS_FWSTATS_ADD(rx, decrypt_key_not_found); DEBUGFS_FWSTATS_ADD(rx, defrag_need_decrypt); + DEBUGFS_FWSTATS_ADD(rx, rx_tkip_replays); DEBUGFS_FWSTATS_ADD(isr, irqs); @@ -322,10 +343,6 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(pwr, cont_miss_bcns_spread); DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_bcns_cnt); - DEBUGFS_FWSTATS_ADD(event, calibration); - DEBUGFS_FWSTATS_ADD(event, rx_mismatch); - DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); - DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_timeouts); DEBUGFS_FWSTATS_ADD(ps_poll, upsd_timeouts); DEBUGFS_FWSTATS_ADD(ps_poll, upsd_max_ap_turn); @@ -340,10 +357,12 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx_filter, data_filter); DEBUGFS_FWSTATS_ADD(rx_filter, ibss_filter); DEBUGFS_FWSTATS_ADD(rx_filter, protection_filter); + DEBUGFS_FWSTATS_ADD(rx_filter, accum_arp_pend_requests); + DEBUGFS_FWSTATS_ADD(rx_filter, max_arp_queue_dep); DEBUGFS_FWSTATS_ADD(rx_rate, rx_frames_per_rates); - DEBUGFS_FWSTATS_ADD(aggr_size, tx_size); + DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_vs_rate); DEBUGFS_FWSTATS_ADD(aggr_size, rx_size); DEBUGFS_FWSTATS_ADD(pipeline, hs_tx_stat_fifo_int); @@ -363,6 +382,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_out); DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_in); DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_out); + DEBUGFS_FWSTATS_ADD(pipeline, pipeline_fifo_full); DEBUGFS_FWSTATS_ADD(mem, rx_free_mem_blks); DEBUGFS_FWSTATS_ADD(mem, tx_free_mem_blks); -- GitLab From d61c6b5550c759728e702e68c8423a23a6991fc3 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 29 May 2012 12:40:50 +0300 Subject: [PATCH 0967/6849] wl18xx: align wl18xx_conf_phy with FW variant and remove it wl18xx_conf_phy represents part of the FW native wl18xx_mac_and_phy_params structure. Remove it and replace the phy part of the wl18xx conf with the FW bound structure. This allows us to set/override all members. Increment the wlconf version to ensure compatibility with the new structure Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/conf.h | 37 +++++++++++++++-- drivers/net/wireless/ti/wl18xx/main.c | 52 ++---------------------- drivers/net/wireless/ti/wl18xx/reg.h | 57 --------------------------- 3 files changed, 36 insertions(+), 110 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index 130546aa970d..fac0b7e87e75 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h @@ -23,41 +23,70 @@ #define __WL18XX_CONF_H__ #define WL18XX_CONF_MAGIC 0x10e100ca -#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0001) +#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0002) #define WL18XX_CONF_MASK 0x0000ffff #define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ sizeof(struct wl18xx_priv_conf)) -struct wl18xx_conf_phy { +#define NUM_OF_CHANNELS_11_ABG 150 +#define NUM_OF_CHANNELS_11_P 7 +#define WL18XX_NUM_OF_SUB_BANDS 9 +#define SRF_TABLE_LEN 16 +#define PIN_MUXING_SIZE 2 + +struct wl18xx_mac_and_phy_params { u8 phy_standalone; u8 rdl; u8 enable_clpc; u8 enable_tx_low_pwr_on_siso_rdl; u8 auto_detect; u8 dedicated_fem; + u8 low_band_component; + + /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ u8 low_band_component_type; + u8 high_band_component; + + /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ u8 high_band_component_type; + u8 number_of_assembled_ant2_4; + u8 number_of_assembled_ant5; + u8 pin_muxing_platform_options[PIN_MUXING_SIZE]; + u8 external_pa_dc2dc; u8 tcxo_ldo_voltage; u8 xtal_itrim_val; u8 srf_state; + u8 srf1[SRF_TABLE_LEN]; + u8 srf2[SRF_TABLE_LEN]; + u8 srf3[SRF_TABLE_LEN]; u8 io_configuration; u8 sdio_configuration; u8 settings; u8 rx_profile; + u8 per_chan_pwr_limit_arr_11abg[NUM_OF_CHANNELS_11_ABG]; + u8 pwr_limit_reference_11_abg; + u8 per_chan_pwr_limit_arr_11p[NUM_OF_CHANNELS_11_P]; + u8 pwr_limit_reference_11p; + u8 per_sub_band_tx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; + u8 per_sub_band_rx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; u8 primary_clock_setting_time; u8 clock_valid_on_wake_up; u8 secondary_clock_setting_time; - u8 pwr_limit_reference_11_abg; + u8 board_type; + /* enable point saturation */ u8 psat; + /* low/medium/high Tx power in dBm */ s8 low_power_val; s8 med_power_val; s8 high_power_val; + u8 padding[1]; } __packed; struct wl18xx_priv_conf { - struct wl18xx_conf_phy phy; + /* this structure is copied wholesale to FW */ + struct wl18xx_mac_and_phy_params phy; } __packed; #endif /* __WL18XX_CONF_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index c26015b8830c..78b2e54a0be7 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -716,63 +716,17 @@ static void wl18xx_pre_upload(struct wl1271 *wl) static void wl18xx_set_mac_and_phy(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; - struct wl18xx_conf_phy *phy = &priv->conf.phy; - struct wl18xx_mac_and_phy_params params; size_t len; - memset(¶ms, 0, sizeof(params)); - - params.phy_standalone = phy->phy_standalone; - params.rdl = phy->rdl; - params.enable_clpc = phy->enable_clpc; - params.enable_tx_low_pwr_on_siso_rdl = - phy->enable_tx_low_pwr_on_siso_rdl; - params.auto_detect = phy->auto_detect; - params.dedicated_fem = phy->dedicated_fem; - params.low_band_component = phy->low_band_component; - params.low_band_component_type = - phy->low_band_component_type; - params.high_band_component = phy->high_band_component; - params.high_band_component_type = - phy->high_band_component_type; - params.number_of_assembled_ant2_4 = - n_antennas_2_param; - params.number_of_assembled_ant5 = - n_antennas_5_param; - params.external_pa_dc2dc = dc2dc_param; - params.tcxo_ldo_voltage = phy->tcxo_ldo_voltage; - params.xtal_itrim_val = phy->xtal_itrim_val; - params.srf_state = phy->srf_state; - params.io_configuration = phy->io_configuration; - params.sdio_configuration = phy->sdio_configuration; - params.settings = phy->settings; - params.rx_profile = phy->rx_profile; - params.primary_clock_setting_time = - phy->primary_clock_setting_time; - params.clock_valid_on_wake_up = - phy->clock_valid_on_wake_up; - params.secondary_clock_setting_time = - phy->secondary_clock_setting_time; - params.pwr_limit_reference_11_abg = - phy->pwr_limit_reference_11_abg; - - params.board_type = priv->board_type; - - /* for PG2 only */ - params.psat = phy->psat; - params.low_power_val = phy->low_power_val; - params.med_power_val = phy->med_power_val; - params.high_power_val = phy->high_power_val; - /* the parameters struct is smaller for PG1 */ if (wl->chip.id == CHIP_ID_185x_PG10) len = offsetof(struct wl18xx_mac_and_phy_params, psat) + 1; else - len = sizeof(params); + len = sizeof(struct wl18xx_mac_and_phy_params); wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); - wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)¶ms, - len, false); + wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, len, + false); } static void wl18xx_enable_interrupts(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index a824b26702a8..937b71d8783f 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -164,13 +164,6 @@ */ #define WL18XX_SCR_PAD8_PLT 0xBABABEBE -/* TODO: maybe move elsewhere? */ -#define NUM_OF_CHANNELS_11_ABG 150 -#define NUM_OF_CHANNELS_11_P 7 -#define WL18XX_NUM_OF_SUB_BANDS 9 -#define SRF_TABLE_LEN 16 -#define PIN_MUXING_SIZE 2 - enum { COMPONENT_NO_SWITCH = 0x0, COMPONENT_2_WAY_SWITCH = 0x1, @@ -195,54 +188,4 @@ enum { NUM_BOARD_TYPES, }; -struct wl18xx_mac_and_phy_params { - u8 phy_standalone; - u8 rdl; - u8 enable_clpc; - u8 enable_tx_low_pwr_on_siso_rdl; - u8 auto_detect; - u8 dedicated_fem; - - u8 low_band_component; - - /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ - u8 low_band_component_type; - - u8 high_band_component; - - /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ - u8 high_band_component_type; - u8 number_of_assembled_ant2_4; - u8 number_of_assembled_ant5; - u8 pin_muxing_platform_options[PIN_MUXING_SIZE]; - u8 external_pa_dc2dc; - u8 tcxo_ldo_voltage; - u8 xtal_itrim_val; - u8 srf_state; - u8 srf1[SRF_TABLE_LEN]; - u8 srf2[SRF_TABLE_LEN]; - u8 srf3[SRF_TABLE_LEN]; - u8 io_configuration; - u8 sdio_configuration; - u8 settings; - u8 rx_profile; - u8 per_chan_pwr_limit_arr_11abg[NUM_OF_CHANNELS_11_ABG]; - u8 pwr_limit_reference_11_abg; - u8 per_chan_pwr_limit_arr_11p[NUM_OF_CHANNELS_11_P]; - u8 pwr_limit_reference_11p; - u8 per_sub_band_tx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; - u8 per_sub_band_rx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; - u8 primary_clock_setting_time; - u8 clock_valid_on_wake_up; - u8 secondary_clock_setting_time; - u8 board_type; - /* enable point saturation */ - u8 psat; - /* low/medium/high Tx power in dBm */ - s8 low_power_val; - s8 med_power_val; - s8 high_power_val; - u8 padding[1]; -} __packed; - #endif /* __REG_H__ */ -- GitLab From 17d97719dc2fe2b9c13831dc2c8572b54efe00b4 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 29 May 2012 12:44:12 +0300 Subject: [PATCH 0968/6849] wl18xx: clean up phy module parameters Give all wl18xx phy module paramters -1 as a default value, indicating the paramter was not set. Add previous default values to the default 18xx priv conf structure. Remove the board_type field from wl18xx priv. The field with the same name inside the phy conf is good enough for our purposes. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 112 ++++++++++++------------ drivers/net/wireless/ti/wl18xx/wl18xx.h | 2 - 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 78b2e54a0be7..b2ccff7d6188 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -45,16 +45,18 @@ static char *ht_mode_param = "wide"; static char *board_type_param = "hdk"; -static bool dc2dc_param = false; -static int n_antennas_2_param = 1; -static int n_antennas_5_param = 1; static bool checksum_param = false; static bool enable_11a_param = true; -static int low_band_component = -1; -static int low_band_component_type = -1; -static int high_band_component = -1; -static int high_band_component_type = -1; -static int pwr_limit_reference_11_abg = -1; + +/* phy paramters */ +static int dc2dc_param = -1; +static int n_antennas_2_param = -1; +static int n_antennas_5_param = -1; +static int low_band_component_param = -1; +static int low_band_component_type_param = -1; +static int high_band_component_param = -1; +static int high_band_component_type_param = -1; +static int pwr_limit_reference_11_abg_param = -1; static const u8 wl18xx_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ @@ -516,6 +518,9 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .low_power_val = 0x00, .med_power_val = 0x0a, .high_power_val = 0x1e, + .external_pa_dc2dc = 0, + .number_of_assembled_ant2_4 = 1, + .number_of_assembled_ant5 = 1, }, }; @@ -1320,17 +1325,17 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) goto out_free; if (!strcmp(board_type_param, "fpga")) { - priv->board_type = BOARD_TYPE_FPGA_18XX; + priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX; } else if (!strcmp(board_type_param, "hdk")) { - priv->board_type = BOARD_TYPE_HDK_18XX; + priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX; /* HACK! Just for now we hardcode HDK to 0x06 */ priv->conf.phy.low_band_component_type = 0x06; } else if (!strcmp(board_type_param, "dvp")) { - priv->board_type = BOARD_TYPE_DVP_18XX; + priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX; } else if (!strcmp(board_type_param, "evb")) { - priv->board_type = BOARD_TYPE_EVB_18XX; + priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX; } else if (!strcmp(board_type_param, "com8")) { - priv->board_type = BOARD_TYPE_COM8_18XX; + priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX; /* HACK! Just for now we hardcode COM8 to 0x06 */ priv->conf.phy.low_band_component_type = 0x06; } else { @@ -1339,38 +1344,26 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) goto out_free; } - /* - * If the module param is not set, update it with the one from - * conf. If it is set, overwrite conf with it. - */ - if (low_band_component == -1) - low_band_component = priv->conf.phy.low_band_component; - else - priv->conf.phy.low_band_component = low_band_component; - if (low_band_component_type == -1) - low_band_component_type = - priv->conf.phy.low_band_component_type; - else + /* If the module param is set, update it in conf */ + if (low_band_component_param != -1) + priv->conf.phy.low_band_component = low_band_component_param; + if (low_band_component_type_param != -1) priv->conf.phy.low_band_component_type = - low_band_component_type; - - if (high_band_component == -1) - high_band_component = priv->conf.phy.high_band_component; - else - priv->conf.phy.high_band_component = high_band_component; - if (high_band_component_type == -1) - high_band_component_type = - priv->conf.phy.high_band_component_type; - else + low_band_component_type_param; + if (high_band_component_param != -1) + priv->conf.phy.high_band_component = high_band_component_param; + if (high_band_component_type_param != -1) priv->conf.phy.high_band_component_type = - high_band_component_type; - - if (pwr_limit_reference_11_abg == -1) - pwr_limit_reference_11_abg = - priv->conf.phy.pwr_limit_reference_11_abg; - else + high_band_component_type_param; + if (pwr_limit_reference_11_abg_param != -1) priv->conf.phy.pwr_limit_reference_11_abg = - pwr_limit_reference_11_abg; + pwr_limit_reference_11_abg_param; + if (n_antennas_2_param != -1) + priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param; + if (n_antennas_5_param != -1) + priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param; + if (dc2dc_param != -1) + priv->conf.phy.external_pa_dc2dc = dc2dc_param; if (!checksum_param) { wl18xx_ops.set_rx_csum = NULL; @@ -1422,38 +1415,45 @@ module_param_named(board_type, board_type_param, charp, S_IRUSR); MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " "dvp"); -module_param_named(dc2dc, dc2dc_param, bool, S_IRUSR); -MODULE_PARM_DESC(dc2dc, "External DC2DC: boolean (defaults to false)"); - -module_param_named(n_antennas_2, n_antennas_2_param, uint, S_IRUSR); -MODULE_PARM_DESC(n_antennas_2, "Number of installed 2.4GHz antennas: 1 (default) or 2"); - -module_param_named(n_antennas_5, n_antennas_5_param, uint, S_IRUSR); -MODULE_PARM_DESC(n_antennas_5, "Number of installed 5GHz antennas: 1 (default) or 2"); - module_param_named(checksum, checksum_param, bool, S_IRUSR); MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); module_param_named(enable_11a, enable_11a_param, bool, S_IRUSR); MODULE_PARM_DESC(enable_11a, "Enable 11a (5GHz): boolean (defaults to true)"); -module_param(low_band_component, uint, S_IRUSR); +module_param_named(dc2dc, dc2dc_param, int, S_IRUSR); +MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); + +module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR); +MODULE_PARM_DESC(n_antennas_2, + "Number of installed 2.4GHz antennas: 1 (default) or 2"); + +module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR); +MODULE_PARM_DESC(n_antennas_5, + "Number of installed 5GHz antennas: 1 (default) or 2"); + +module_param_named(low_band_component, low_band_component_param, int, + S_IRUSR); MODULE_PARM_DESC(low_band_component, "Low band component: u8 " "(default is 0x01)"); -module_param(low_band_component_type, uint, S_IRUSR); +module_param_named(low_band_component_type, low_band_component_type_param, + int, S_IRUSR); MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " "(default is 0x05 or 0x06 depending on the board_type)"); -module_param(high_band_component, uint, S_IRUSR); +module_param_named(high_band_component, high_band_component_param, int, + S_IRUSR); MODULE_PARM_DESC(high_band_component, "High band component: u8, " "(default is 0x01)"); -module_param(high_band_component_type, uint, S_IRUSR); +module_param_named(high_band_component_type, high_band_component_type_param, + int, S_IRUSR); MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " "(default is 0x09)"); -module_param(pwr_limit_reference_11_abg, uint, S_IRUSR); +module_param_named(pwr_limit_reference_11_abg, + pwr_limit_reference_11_abg_param, int, S_IRUSR); MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " "(default is 0xc8)"); diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h index b9c43097d2f6..bc67a4750615 100644 --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h @@ -35,8 +35,6 @@ struct wl18xx_priv { /* Index of last released Tx desc in FW */ u8 last_fw_rls_idx; - u8 board_type; - /* number of VIFs requiring extra spare mem-blocks */ int extra_spare_vif_count; }; -- GitLab From 3e3947fffc2ebe8c52891b3fca195172875dc951 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 29 May 2012 18:38:05 +0300 Subject: [PATCH 0969/6849] wlcore/wl12xx/wl18xx: make NVS file optional for wl18xx Don't spew errors when we can't find the NVS file in wlcore. Instead fail the wl12xx boot HW op if the NVS isn't found. Take this opportunity to remove some dead code from register_hw() which looks for the NVS again needlessly. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/boot.c | 4 +++- drivers/net/wireless/ti/wlcore/main.c | 22 ++++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index ed718f7ddcce..0fda500c01c9 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -211,8 +211,10 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) u32 dest_addr, val; u8 *nvs_ptr, *nvs_aligned; - if (wl->nvs == NULL) + if (wl->nvs == NULL) { + wl1271_error("NVS file is needed during boot"); return -ENODEV; + } if (wl->quirks & WLCORE_QUIRK_LEGACY_NVS) { struct wl1271_nvs_file *nvs = diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 176a3117889b..1156e3f578c1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -715,7 +715,7 @@ out: return ret; } -static int wl1271_fetch_nvs(struct wl1271 *wl) +static void wl1271_fetch_nvs(struct wl1271 *wl) { const struct firmware *fw; int ret; @@ -723,16 +723,15 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev); if (ret < 0) { - wl1271_error("could not get nvs file %s: %d", WL12XX_NVS_NAME, - ret); - return ret; + wl1271_debug(DEBUG_BOOT, "could not get nvs file %s: %d", + WL12XX_NVS_NAME, ret); + return; } wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL); if (!wl->nvs) { wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; goto out; } @@ -740,8 +739,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) out: release_firmware(fw); - - return ret; } void wl12xx_queue_recovery_work(struct wl1271 *wl) @@ -989,13 +986,6 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) if (ret < 0) goto out; - /* No NVS from netlink, try to get it from the filesystem */ - if (wl->nvs == NULL) { - ret = wl1271_fetch_nvs(wl); - if (ret < 0) - goto out; - } - out: return ret; } @@ -4937,8 +4927,8 @@ static int wl1271_register_hw(struct wl1271 *wl) if (wl->mac80211_registered) return 0; - ret = wl1271_fetch_nvs(wl); - if (ret == 0) { + wl1271_fetch_nvs(wl); + if (wl->nvs != NULL) { /* NOTE: The wl->nvs->nvs element must be first, in * order to simplify the casting, we assume it is at * the beginning of the wl->nvs structure. -- GitLab From 4dab786482d706a2a41cd16cf174671d640a9870 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Jun 2012 14:58:37 +0800 Subject: [PATCH 0970/6849] Bluetooth: Fix SMP security elevation from medium to high If we have an unauthenticated key it is not sufficient to acheive high security. Therefore, when deciding whether to encrypt the link or request pairing, it is essential to in addition to checking the existence of a key to also check whether it is authenticated or not. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/smp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index c4ac2849d9c2..37df4e9b3896 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -703,7 +703,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) return 0; } -static u8 smp_ltk_encrypt(struct l2cap_conn *conn) +static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) { struct smp_ltk *key; struct hci_conn *hcon = conn->hcon; @@ -712,6 +712,9 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn) if (!key) return 0; + if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) + return 0; + if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) return 1; @@ -732,7 +735,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); - if (smp_ltk_encrypt(conn)) + if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) return 0; if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) @@ -771,7 +774,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) return 1; if (hcon->link_mode & HCI_LM_MASTER) - if (smp_ltk_encrypt(conn)) + if (smp_ltk_encrypt(conn, sec_level)) goto done; if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) -- GitLab From 09617ce4774ebf30a55b8451f4b35031f626f763 Mon Sep 17 00:00:00 2001 From: Wang Xingchao Date: Fri, 8 Jun 2012 10:26:08 +0800 Subject: [PATCH 0971/6849] ALSA: hda - power setting error check codec may reject power state transition requests(reporting PS-ERROR set), in that case we re-issue a power state setting and check error bit again. Signed-off-by: Wang Xingchao Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fedbfae978af..851e6ecfa011 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3526,6 +3526,9 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) { + int count; + unsigned int state; + if (codec->patch_ops.set_power_state) { codec->patch_ops.set_power_state(codec, fg, power_state); return; @@ -3537,9 +3540,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS); msleep(epss ? 10 : 100); } - snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, - power_state); - snd_hda_codec_set_power_to_all(codec, fg, power_state, true); + + /* repeat power states setting at most 10 times*/ + for (count = 0; count < 10; count++) { + snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, + power_state); + snd_hda_codec_set_power_to_all(codec, fg, power_state, true); + state = snd_hda_codec_read(codec, fg, 0, + AC_VERB_GET_POWER_STATE, 0); + if (!(state & AC_PWRST_ERROR)) + break; + } } #ifdef CONFIG_SND_HDA_HWDEP -- GitLab From c1dcad2d32d0252e8a3023d20311b52a187ecda3 Mon Sep 17 00:00:00 2001 From: Bernhard Seibold Date: Wed, 15 Feb 2012 13:40:43 +0100 Subject: [PATCH 0972/6849] HID: Driver for Lenovo Keyboard with Trackpoint This driver for the "Lenovo ThinkPad USB Keyboard with Trackpoint" supports setting various device attributes, controlling mute and microphone mute LEDs and enables use of the microphone mute key. Signed-off-by: Bernhard Seibold Signed-off-by: Jiri Kosina --- .../ABI/testing/sysfs-driver-hid-lenovo-tpkbd | 38 ++ drivers/hid/Kconfig | 12 + drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 + drivers/hid/hid-lenovo-tpkbd.c | 564 ++++++++++++++++++ 6 files changed, 619 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-lenovo-tpkbd create mode 100644 drivers/hid/hid-lenovo-tpkbd.c diff --git a/Documentation/ABI/testing/sysfs-driver-hid-lenovo-tpkbd b/Documentation/ABI/testing/sysfs-driver-hid-lenovo-tpkbd new file mode 100644 index 000000000000..57b92cbdceae --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-lenovo-tpkbd @@ -0,0 +1,38 @@ +What: /sys/bus/usb/devices/-:./::./press_to_select +Date: July 2011 +Contact: linux-input@vger.kernel.org +Description: This controls if mouse clicks should be generated if the trackpoint is quickly pressed. How fast this press has to be + is being controlled by press_speed. + Values are 0 or 1. + +What: /sys/bus/usb/devices/-:./::./dragging +Date: July 2011 +Contact: linux-input@vger.kernel.org +Description: If this setting is enabled, it is possible to do dragging by pressing the trackpoint. This requires press_to_select to be enabled. + Values are 0 or 1. + +What: /sys/bus/usb/devices/-:./::./release_to_select +Date: July 2011 +Contact: linux-input@vger.kernel.org +Description: For details regarding this setting please refer to http://www.pc.ibm.com/ww/healthycomputing/trkpntb.html + Values are 0 or 1. + +What: /sys/bus/usb/devices/-:./::./select_right +Date: July 2011 +Contact: linux-input@vger.kernel.org +Description: This setting controls if the mouse click events generated by pressing the trackpoint (if press_to_select is enabled) generate + a left or right mouse button click. + Values are 0 or 1. + +What: /sys/bus/usb/devices/-:./::./sensitivity +Date: July 2011 +Contact: linux-input@vger.kernel.org +Description: This file contains the trackpoint sensitivity. + Values are decimal integers from 1 (lowest sensitivity) to 255 (highest sensitivity). + +What: /sys/bus/usb/devices/-:./::./press_speed +Date: July 2011 +Contact: linux-input@vger.kernel.org +Description: This setting controls how fast the trackpoint needs to be pressed to generate a mouse click if press_to_select is enabled. + Values are decimal integers from 1 (slowest) to 255 (fastest). + diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e9c68fedfcff..ca7e76cab83d 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -268,6 +268,18 @@ config HID_LCPOWER ---help--- Support for LC-Power RC1000MCE RF remote control. +config HID_LENOVO_TPKBD + tristate "Lenovo ThinkPad USB Keyboard with TrackPoint" + depends on USB_HID + select LEDS_CLASS + ---help--- + Support for the Lenovo ThinkPad USB Keyboard with TrackPoint. + + Say Y here if you have a Lenovo ThinkPad USB Keyboard with TrackPoint + and would like to use device-specific features like changing the + sensitivity of the trackpoint, using the microphone mute button or + controlling the mute and microphone mute LEDs. + config HID_LOGITECH tristate "Logitech devices" if EXPERT depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index ca6cc9f0485c..05913c533ec5 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o obj-$(CONFIG_HID_KYE) += hid-kye.o obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o +obj-$(CONFIG_HID_LENOVO_TPKBD) += hid-lenovo-tpkbd.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8e3a6b261477..f69568032c04 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1544,6 +1544,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9373f535dfe9..c607e6f33953 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -473,6 +473,9 @@ #define USB_DEVICE_ID_LD_HYBRID 0x2090 #define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0 +#define USB_VENDOR_ID_LENOVO 0x17ef +#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 + #define USB_VENDOR_ID_LG 0x1fd2 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c new file mode 100644 index 000000000000..77d2df04c97b --- /dev/null +++ b/drivers/hid/hid-lenovo-tpkbd.c @@ -0,0 +1,564 @@ +/* + * HID driver for Lenovo ThinkPad USB Keyboard with TrackPoint + * + * Copyright (c) 2012 Bernhard Seibold + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "usbhid/usbhid.h" + +#include "hid-ids.h" + +/* This is only used for the trackpoint part of the driver, hence _tp */ +struct tpkbd_data_pointer { + int led_state; + struct led_classdev led_mute; + struct led_classdev led_micmute; + int press_to_select; + int dragging; + int release_to_select; + int select_right; + int sensitivity; + int press_speed; +}; + +#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) + +static int tpkbd_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +{ + struct usbhid_device *uhdev; + + uhdev = (struct usbhid_device *) hdev->driver_data; + if (uhdev->ifnum == 1 && usage->hid == (HID_UP_BUTTON | 0x0010)) { + map_key_clear(KEY_MICMUTE); + return 1; + } + return 0; +} + +#undef map_key_clear + +static int tpkbd_features_set(struct hid_device *hdev) +{ + struct hid_report *report; + struct tpkbd_data_pointer *data_pointer; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4]; + + report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02; + report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08; + report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20; + report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40; + report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver + report->field[2]->value[0] = data_pointer->sensitivity; + report->field[3]->value[0] = data_pointer->press_speed; + + usbhid_submit_report(hdev, report, USB_DIR_OUT); + return 0; +} + +static ssize_t pointer_press_to_select_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select); +} + +static ssize_t pointer_press_to_select_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int value; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (kstrtoint(buf, 10, &value)) + return -EINVAL; + if (value < 0 || value > 1) + return -EINVAL; + + data_pointer->press_to_select = value; + tpkbd_features_set(hdev); + + return count; +} + +static ssize_t pointer_dragging_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging); +} + +static ssize_t pointer_dragging_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int value; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (kstrtoint(buf, 10, &value)) + return -EINVAL; + if (value < 0 || value > 1) + return -EINVAL; + + data_pointer->dragging = value; + tpkbd_features_set(hdev); + + return count; +} + +static ssize_t pointer_release_to_select_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select); +} + +static ssize_t pointer_release_to_select_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int value; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (kstrtoint(buf, 10, &value)) + return -EINVAL; + if (value < 0 || value > 1) + return -EINVAL; + + data_pointer->release_to_select = value; + tpkbd_features_set(hdev); + + return count; +} + +static ssize_t pointer_select_right_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right); +} + +static ssize_t pointer_select_right_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int value; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (kstrtoint(buf, 10, &value)) + return -EINVAL; + if (value < 0 || value > 1) + return -EINVAL; + + data_pointer->select_right = value; + tpkbd_features_set(hdev); + + return count; +} + +static ssize_t pointer_sensitivity_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + data_pointer->sensitivity); +} + +static ssize_t pointer_sensitivity_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int value; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) + return -EINVAL; + + data_pointer->sensitivity = value; + tpkbd_features_set(hdev); + + return count; +} + +static ssize_t pointer_press_speed_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + data_pointer->press_speed); +} + +static ssize_t pointer_press_speed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int value; + + hdev = container_of(dev, struct hid_device, dev); + if (hdev == NULL) + return -ENODEV; + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) + return -EINVAL; + + data_pointer->press_speed = value; + tpkbd_features_set(hdev); + + return count; +} + +static struct device_attribute dev_attr_pointer_press_to_select = + __ATTR(press_to_select, S_IWUSR | S_IRUGO, + pointer_press_to_select_show, + pointer_press_to_select_store); + +static struct device_attribute dev_attr_pointer_dragging = + __ATTR(dragging, S_IWUSR | S_IRUGO, + pointer_dragging_show, + pointer_dragging_store); + +static struct device_attribute dev_attr_pointer_release_to_select = + __ATTR(release_to_select, S_IWUSR | S_IRUGO, + pointer_release_to_select_show, + pointer_release_to_select_store); + +static struct device_attribute dev_attr_pointer_select_right = + __ATTR(select_right, S_IWUSR | S_IRUGO, + pointer_select_right_show, + pointer_select_right_store); + +static struct device_attribute dev_attr_pointer_sensitivity = + __ATTR(sensitivity, S_IWUSR | S_IRUGO, + pointer_sensitivity_show, + pointer_sensitivity_store); + +static struct device_attribute dev_attr_pointer_press_speed = + __ATTR(press_speed, S_IWUSR | S_IRUGO, + pointer_press_speed_show, + pointer_press_speed_store); + +static struct attribute *tpkbd_attributes_pointer[] = { + &dev_attr_pointer_press_to_select.attr, + &dev_attr_pointer_dragging.attr, + &dev_attr_pointer_release_to_select.attr, + &dev_attr_pointer_select_right.attr, + &dev_attr_pointer_sensitivity.attr, + &dev_attr_pointer_press_speed.attr, + NULL +}; + +static const struct attribute_group tpkbd_attr_group_pointer = { + .attrs = tpkbd_attributes_pointer, +}; + +static enum led_brightness tpkbd_led_brightness_get( + struct led_classdev *led_cdev) +{ + struct device *dev; + struct hid_device *hdev; + struct tpkbd_data_pointer *data_pointer; + int led_nr = 0; + + dev = led_cdev->dev->parent; + hdev = container_of(dev, struct hid_device, dev); + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (led_cdev == &data_pointer->led_micmute) + led_nr = 1; + + return data_pointer->led_state & (1 << led_nr) + ? LED_FULL + : LED_OFF; +} + +static void tpkbd_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct device *dev; + struct hid_device *hdev; + struct hid_report *report; + struct tpkbd_data_pointer *data_pointer; + int led_nr = 0; + + dev = led_cdev->dev->parent; + hdev = container_of(dev, struct hid_device, dev); + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + if (led_cdev == &data_pointer->led_micmute) + led_nr = 1; + + if (value == LED_OFF) + data_pointer->led_state &= ~(1 << led_nr); + else + data_pointer->led_state |= 1 << led_nr; + + report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; + report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; + report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; + usbhid_submit_report(hdev, report, USB_DIR_OUT); +} + +static int tpkbd_probe_tp(struct hid_device *hdev) +{ + struct device *dev = &hdev->dev; + struct tpkbd_data_pointer *data_pointer; + size_t name_sz = strlen(dev_name(dev)) + 16; + char *name_mute, *name_micmute; + int ret; + + if (sysfs_create_group(&hdev->dev.kobj, + &tpkbd_attr_group_pointer)) { + hid_warn(hdev, "Could not create sysfs group\n"); + } + + data_pointer = kzalloc(sizeof(struct tpkbd_data_pointer), GFP_KERNEL); + if (data_pointer == NULL) { + hid_err(hdev, "Could not allocate memory for driver data\n"); + return -ENOMEM; + } + + // set same default values as windows driver + data_pointer->sensitivity = 0xa0; + data_pointer->press_speed = 0x38; + + name_mute = kzalloc(name_sz, GFP_KERNEL); + if (name_mute == NULL) { + hid_err(hdev, "Could not allocate memory for led data\n"); + ret = -ENOMEM; + goto err; + } + snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev)); + + name_micmute = kzalloc(name_sz, GFP_KERNEL); + if (name_micmute == NULL) { + hid_err(hdev, "Could not allocate memory for led data\n"); + ret = -ENOMEM; + goto err2; + } + snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev)); + + hid_set_drvdata(hdev, data_pointer); + + data_pointer->led_mute.name = name_mute; + data_pointer->led_mute.brightness_get = tpkbd_led_brightness_get; + data_pointer->led_mute.brightness_set = tpkbd_led_brightness_set; + data_pointer->led_mute.dev = dev; + led_classdev_register(dev, &data_pointer->led_mute); + + data_pointer->led_micmute.name = name_micmute; + data_pointer->led_micmute.brightness_get = tpkbd_led_brightness_get; + data_pointer->led_micmute.brightness_set = tpkbd_led_brightness_set; + data_pointer->led_micmute.dev = dev; + led_classdev_register(dev, &data_pointer->led_micmute); + + tpkbd_features_set(hdev); + + return 0; + +err2: + kfree(name_mute); +err: + kfree(data_pointer); + return ret; +} + +static int tpkbd_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + struct usbhid_device *uhdev; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "hid_parse failed\n"); + goto err_free; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hid_hw_start failed\n"); + goto err_free; + } + + uhdev = (struct usbhid_device *) hdev->driver_data; + + if (uhdev->ifnum == 1) + return tpkbd_probe_tp(hdev); + + return 0; +err_free: + return ret; +} + +static void tpkbd_remove_tp(struct hid_device *hdev) +{ + struct tpkbd_data_pointer *data_pointer; + + sysfs_remove_group(&hdev->dev.kobj, + &tpkbd_attr_group_pointer); + + data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev); + + led_classdev_unregister(&data_pointer->led_micmute); + led_classdev_unregister(&data_pointer->led_mute); + + hid_set_drvdata(hdev, NULL); + kfree(data_pointer); +} + +static void tpkbd_remove(struct hid_device *hdev) +{ + struct usbhid_device *uhdev; + + uhdev = (struct usbhid_device *) hdev->driver_data; + if (uhdev->ifnum == 1) + tpkbd_remove_tp(hdev); + + hid_hw_stop(hdev); +} + +static const struct hid_device_id tpkbd_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, + { } +}; + +MODULE_DEVICE_TABLE(hid, tpkbd_devices); + +static struct hid_driver tpkbd_driver = { + .name = "lenovo_tpkbd", + .id_table = tpkbd_devices, + .input_mapping = tpkbd_input_mapping, + .probe = tpkbd_probe, + .remove = tpkbd_remove, +}; + +static int __init tpkbd_init(void) +{ + return hid_register_driver(&tpkbd_driver); +} + +static void __exit tpkbd_exit(void) +{ + hid_unregister_driver(&tpkbd_driver); +} + +module_init(tpkbd_init); +module_exit(tpkbd_exit); + +MODULE_LICENSE("GPL"); -- GitLab From 9d8e10667624ea6411f04495aef1fa4a8a778ee8 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 7 Jun 2012 15:14:49 +0200 Subject: [PATCH 0973/6849] x86/apic: Factor out default vector_allocation_domain() operation Signed-off-by: Alexander Gordeev Acked-by: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120607131449.GC4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 21 +++++++++++++++++++++ arch/x86/kernel/apic/apic_flat_64.c | 22 +--------------------- arch/x86/kernel/apic/apic_noop.c | 3 +-- arch/x86/kernel/apic/apic_numachip.c | 8 +------- arch/x86/kernel/apic/bigsmp_32.c | 8 +------- arch/x86/kernel/apic/es7000_32.c | 19 ++----------------- arch/x86/kernel/apic/numaq_32.c | 16 +--------------- arch/x86/kernel/apic/probe_32.c | 17 +---------------- arch/x86/kernel/apic/summit_32.c | 16 +--------------- arch/x86/kernel/apic/x2apic_phys.c | 11 +---------- arch/x86/kernel/apic/x2apic_uv_x.c | 8 +------- 11 files changed, 32 insertions(+), 117 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index bef571769e68..feb2dbdae9ec 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -615,6 +615,27 @@ extern unsigned int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask); +static inline void +flat_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + +static inline void +default_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_copy(retmask, cpumask_of(cpu)); +} + static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) { return physid_isset(apicid, *map); diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 55b97ce4fa19..bddc92566d0a 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -36,20 +36,6 @@ static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 1; } -static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} - /* * Set up the logical destination ID. * @@ -257,12 +243,6 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } -static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector) { default_send_IPI_mask_sequence_phys(cpumask, vector); @@ -309,7 +289,7 @@ static struct apic apic_physflat = { .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = physflat_vector_allocation_domain, + .vector_allocation_domain = default_vector_allocation_domain, /* not needed, but shouldn't hurt: */ .init_apic_ldr = flat_init_apic_ldr, diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 7c3dd4fe0686..3e43cf528939 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -104,8 +104,7 @@ static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) { if (cpu != 0) pr_warning("APIC: Vector allocated for non-BSP cpu\n"); - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); + cpumask_copy(retmask, cpumask_of(cpu)); } static u32 noop_apic_read(u32 reg) diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index dba4bf2ed566..c028132ad358 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -72,12 +72,6 @@ static int numachip_phys_pkg_id(int initial_apic_id, int index_msb) return initial_apic_id >> index_msb; } -static void numachip_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - static int __cpuinit numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip) { union numachip_csr_g3_ext_irq_gen int_gen; @@ -222,7 +216,7 @@ static struct apic apic_numachip __refconst = { .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = numachip_vector_allocation_domain, + .vector_allocation_domain = default_vector_allocation_domain, .init_apic_ldr = flat_init_apic_ldr, .ioapic_phys_id_map = NULL, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 907aa3d112a6..df342fe4d6aa 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -142,12 +142,6 @@ static const struct dmi_system_id bigsmp_dmi_table[] = { { } /* NULL entry stops DMI scanning */ }; -static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - static int probe_bigsmp(void) { if (def_to_bigsmp) @@ -176,7 +170,7 @@ static struct apic apic_bigsmp = { .check_apicid_used = bigsmp_check_apicid_used, .check_apicid_present = bigsmp_check_apicid_present, - .vector_allocation_domain = bigsmp_vector_allocation_domain, + .vector_allocation_domain = default_vector_allocation_domain, .init_apic_ldr = bigsmp_init_apic_ldr, .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index db4ab1be3c79..3c42865757e2 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -394,21 +394,6 @@ static void es7000_enable_apic_mode(void) WARN(1, "Command failed, status = %x\n", mip_status); } -static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} - - static void es7000_wait_for_init_deassert(atomic_t *deassert) { while (!atomic_read(deassert)) @@ -638,7 +623,7 @@ static struct apic __refdata apic_es7000_cluster = { .check_apicid_used = es7000_check_apicid_used, .check_apicid_present = es7000_check_apicid_present, - .vector_allocation_domain = es7000_vector_allocation_domain, + .vector_allocation_domain = flat_vector_allocation_domain, .init_apic_ldr = es7000_init_apic_ldr_cluster, .ioapic_phys_id_map = es7000_ioapic_phys_id_map, @@ -705,7 +690,7 @@ static struct apic __refdata apic_es7000 = { .check_apicid_used = es7000_check_apicid_used, .check_apicid_present = es7000_check_apicid_present, - .vector_allocation_domain = es7000_vector_allocation_domain, + .vector_allocation_domain = flat_vector_allocation_domain, .init_apic_ldr = es7000_init_apic_ldr, .ioapic_phys_id_map = es7000_ioapic_phys_id_map, diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index f00a68cca37a..eb2d466fd81a 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -441,20 +441,6 @@ static int probe_numaq(void) return found_numaq; } -static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} - static void numaq_setup_portio_remap(void) { int num_quads = num_online_nodes(); @@ -491,7 +477,7 @@ static struct apic __refdata apic_numaq = { .check_apicid_used = numaq_check_apicid_used, .check_apicid_present = numaq_check_apicid_present, - .vector_allocation_domain = numaq_vector_allocation_domain, + .vector_allocation_domain = flat_vector_allocation_domain, .init_apic_ldr = numaq_init_apic_ldr, .ioapic_phys_id_map = numaq_ioapic_phys_id_map, diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 71b6ac48ab26..2c6f003b2e4b 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -66,21 +66,6 @@ static void setup_apic_flat_routing(void) #endif } -static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* - * Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} - /* should be called last. */ static int probe_default(void) { @@ -105,7 +90,7 @@ static struct apic apic_default = { .check_apicid_used = default_check_apicid_used, .check_apicid_present = default_check_apicid_present, - .vector_allocation_domain = default_vector_allocation_domain, + .vector_allocation_domain = flat_vector_allocation_domain, .init_apic_ldr = default_init_apic_ldr, .ioapic_phys_id_map = default_ioapic_phys_id_map, diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 659897c00755..35d254c1fec2 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -320,20 +320,6 @@ static int probe_summit(void) return 0; } -static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} - #ifdef CONFIG_X86_SUMMIT_NUMA static struct rio_table_hdr *rio_table_hdr; static struct scal_detail *scal_devs[MAX_NUMNODES]; @@ -509,7 +495,7 @@ static struct apic apic_summit = { .check_apicid_used = summit_check_apicid_used, .check_apicid_present = summit_check_apicid_present, - .vector_allocation_domain = summit_vector_allocation_domain, + .vector_allocation_domain = flat_vector_allocation_domain, .init_apic_ldr = summit_init_apic_ldr, .ioapic_phys_id_map = summit_ioapic_phys_id_map, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index f730269edef2..f109388a0e80 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -88,15 +88,6 @@ static int x2apic_phys_probe(void) return apic == &apic_x2apic_phys; } -/* - * Each logical cpu is in its own vector allocation domain. - */ -static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - static struct apic apic_x2apic_phys = { .name = "physical x2apic", @@ -114,7 +105,7 @@ static struct apic apic_x2apic_phys = { .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = x2apic_vector_allocation_domain, + .vector_allocation_domain = default_vector_allocation_domain, .init_apic_ldr = init_x2apic_ldr, .ioapic_phys_id_map = NULL, diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 16efb92bfea5..df89a7d78748 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -185,12 +185,6 @@ EXPORT_SYMBOL_GPL(uv_possible_blades); unsigned long sn_rtc_cycles_per_second; EXPORT_SYMBOL(sn_rtc_cycles_per_second); -static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) { #ifdef CONFIG_SMP @@ -363,7 +357,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .check_apicid_used = NULL, .check_apicid_present = NULL, - .vector_allocation_domain = uv_vector_allocation_domain, + .vector_allocation_domain = default_vector_allocation_domain, .init_apic_ldr = uv_init_apic_ldr, .ioapic_phys_id_map = NULL, -- GitLab From 1bccd58bfffc5a677051937b332b71f0686187c1 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 7 Jun 2012 15:15:15 +0200 Subject: [PATCH 0974/6849] x86/apic: Try to spread IRQ vectors to different priority levels When assigning a new vector it is primarially done by adding 8 to the previously given out vector number. Hence, two consequently allocated vector numbers would likely fall into the same priority level. Try to spread vector numbers to different priority levels better by changing the step from 8 to 16. Signed-off-by: Alexander Gordeev Acked-by: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120607131514.GD4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/io_apic.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 74c569791e75..05af3d341aaa 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1112,7 +1112,7 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) * 0x80, because int 0x80 is hm, kind of importantish. ;) */ static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; - static int current_offset = VECTOR_OFFSET_START % 8; + static int current_offset = VECTOR_OFFSET_START % 16; unsigned int old_vector; int cpu, err; cpumask_var_t tmp_mask; @@ -1148,10 +1148,9 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) vector = current_vector; offset = current_offset; next: - vector += 8; + vector += 16; if (vector >= first_system_vector) { - /* If out of vectors on large boxen, must share them. */ - offset = (offset + 1) % 8; + offset = (offset + 1) % 16; vector = FIRST_EXTERNAL_VECTOR + offset; } if (unlikely(current_vector == vector)) -- GitLab From 8637e38aff14d048b649075114023023a2e80fba Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 7 Jun 2012 15:15:44 +0200 Subject: [PATCH 0975/6849] x86/apic: Avoid useless scanning thru a cpumask in assign_irq_vector() In case of static vector allocation domains (i.e. flat) if all vector numbers are exhausted, an attempt to assign a new vector will lead to useless scans through all CPUs in the cpumask, even though it is known that each new pass would fail. Make this corner case less painful by letting report whether the vector allocation domain depends on passed arguments or not and stop scanning early. The same could have been achived by introducing a static flag to the apic operations. But let's allow vector_allocation_domain() have more intelligence here and decide dynamically, in case we would need it in the future. Signed-off-by: Alexander Gordeev Acked-by: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120607131542.GE4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 8 +++++--- arch/x86/kernel/apic/apic_noop.c | 3 ++- arch/x86/kernel/apic/io_apic.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index feb2dbdae9ec..e3fecd50d5ca 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -306,7 +306,7 @@ struct apic { unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); unsigned long (*check_apicid_present)(int apicid); - void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); + bool (*vector_allocation_domain)(int cpu, struct cpumask *retmask); void (*init_apic_ldr)(void); void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); @@ -615,7 +615,7 @@ extern unsigned int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask); -static inline void +static inline bool flat_vector_allocation_domain(int cpu, struct cpumask *retmask) { /* Careful. Some cpus do not strictly honor the set of cpus @@ -628,12 +628,14 @@ flat_vector_allocation_domain(int cpu, struct cpumask *retmask) */ cpumask_clear(retmask); cpumask_bits(retmask)[0] = APIC_ALL_CPUS; + return false; } -static inline void +static inline bool default_vector_allocation_domain(int cpu, struct cpumask *retmask) { cpumask_copy(retmask, cpumask_of(cpu)); + return true; } static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 3e43cf528939..ac9edf247b15 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -100,11 +100,12 @@ static unsigned long noop_check_apicid_present(int bit) return physid_isset(bit, phys_cpu_present_map); } -static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) +static bool noop_vector_allocation_domain(int cpu, struct cpumask *retmask) { if (cpu != 0) pr_warning("APIC: Vector allocated for non-BSP cpu\n"); cpumask_copy(retmask, cpumask_of(cpu)); + return true; } static u32 noop_apic_read(u32 reg) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 05af3d341aaa..4061a7dee5c9 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1137,8 +1137,9 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) for_each_cpu_and(cpu, mask, cpu_online_mask) { int new_cpu; int vector, offset; + bool more_domains; - apic->vector_allocation_domain(cpu, tmp_mask); + more_domains = apic->vector_allocation_domain(cpu, tmp_mask); if (cpumask_subset(tmp_mask, cfg->domain)) { free_cpumask_var(tmp_mask); @@ -1153,8 +1154,13 @@ next: offset = (offset + 1) % 16; vector = FIRST_EXTERNAL_VECTOR + offset; } - if (unlikely(current_vector == vector)) - continue; + + if (unlikely(current_vector == vector)) { + if (more_domains) + continue; + else + break; + } if (test_bit(vector, used_vectors)) goto next; -- GitLab From ff164324123c0fe181d8de7dadcc7b3fbe25f2cf Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 7 Jun 2012 15:15:59 +0200 Subject: [PATCH 0976/6849] x86/apic: Make cpu_mask_to_apicid() operations return error code Current cpu_mask_to_apicid() and cpu_mask_to_apicid_and() implementations have few shortcomings: 1. A value returned by cpu_mask_to_apicid() is written to hardware registers unconditionally. Should BAD_APICID get ever returned it will be written to a hardware too. But the value of BAD_APICID is not universal across all hardware in all modes and might cause unexpected results, i.e. interrupts might get routed to CPUs that are not configured to receive it. 2. Because the value of BAD_APICID is not universal it is counter- intuitive to return it for a hardware where it does not make sense (i.e. x2apic). 3. cpu_mask_to_apicid_and() operation is thought as an complement to cpu_mask_to_apicid() that only applies a AND mask on top of a cpumask being passed. Yet, as consequence of 18374d8 commit the two operations are inconsistent in that of: cpu_mask_to_apicid() should not get a offline CPU with the cpumask cpu_mask_to_apicid_and() should not fail and return BAD_APICID These limitations are impossible to realize just from looking at the operations prototypes. Most of these shortcomings are resolved by returning a error code instead of BAD_APICID. As the result, faults are reported back early rather than possibilities to cause a unexpected behaviour exist (in case of [1]). The only exception is setup_timer_IRQ0_pin() routine. Although obviously controversial to this fix, its existing behaviour is preserved to not break the fragile check_timer() and would better addressed in a separate fix. Signed-off-by: Alexander Gordeev Acked-by: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120607131559.GF4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 44 ++++++++++---- arch/x86/kernel/apic/apic.c | 33 +++++----- arch/x86/kernel/apic/es7000_32.c | 21 ++++--- arch/x86/kernel/apic/io_apic.c | 88 +++++++++++++++++---------- arch/x86/kernel/apic/numaq_32.c | 14 +++-- arch/x86/kernel/apic/summit_32.c | 22 ++++--- arch/x86/kernel/apic/x2apic_cluster.c | 24 +++++--- arch/x86/kernel/apic/x2apic_uv_x.c | 27 +++++--- arch/x86/platform/uv/uv_irq.c | 7 ++- drivers/iommu/intel_irq_remapping.c | 13 +++- 10 files changed, 188 insertions(+), 105 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index e3fecd50d5ca..ae91f9c7e360 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -331,9 +331,11 @@ struct apic { unsigned long (*set_apic_id)(unsigned int id); unsigned long apic_id_mask; - unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); - unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, - const struct cpumask *andmask); + int (*cpu_mask_to_apicid)(const struct cpumask *cpumask, + unsigned int *apicid); + int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, + const struct cpumask *andmask, + unsigned int *apicid); /* ipi */ void (*send_IPI_mask)(const struct cpumask *mask, int vector); @@ -591,29 +593,45 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) #endif -static inline unsigned int -flat_cpu_mask_to_apicid(const struct cpumask *cpumask) +static inline int +__flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid) { - return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; + cpu_mask &= APIC_ALL_CPUS; + if (likely(cpu_mask)) { + *apicid = (unsigned int)cpu_mask; + return 0; + } else { + return -EINVAL; + } } -static inline unsigned int +static inline int +flat_cpu_mask_to_apicid(const struct cpumask *cpumask, + unsigned int *apicid) +{ + return __flat_cpu_mask_to_apicid(cpumask_bits(cpumask)[0], apicid); +} + +static inline int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) + const struct cpumask *andmask, + unsigned int *apicid) { unsigned long mask1 = cpumask_bits(cpumask)[0]; unsigned long mask2 = cpumask_bits(andmask)[0]; unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; - return (unsigned int)(mask1 & mask2 & mask3); + return __flat_cpu_mask_to_apicid(mask1 & mask2 & mask3, apicid); } -extern unsigned int -default_cpu_mask_to_apicid(const struct cpumask *cpumask); +extern int +default_cpu_mask_to_apicid(const struct cpumask *cpumask, + unsigned int *apicid); -extern unsigned int +extern int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask); + const struct cpumask *andmask, + unsigned int *apicid); static inline bool flat_vector_allocation_domain(int cpu, struct cpumask *retmask) diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 96a2608252f1..b8d92606f84f 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2123,24 +2123,26 @@ void default_init_apic_ldr(void) apic_write(APIC_LDR, val); } -unsigned int default_cpu_mask_to_apicid(const struct cpumask *cpumask) +static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid) { - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - cpu = cpumask_first(cpumask); - if (likely((unsigned)cpu < nr_cpu_ids)) - return per_cpu(x86_cpu_to_apicid, cpu); + if (likely((unsigned int)cpu < nr_cpu_ids)) { + *apicid = per_cpu(x86_cpu_to_apicid, cpu); + return 0; + } else { + return -EINVAL; + } +} - return BAD_APICID; +int default_cpu_mask_to_apicid(const struct cpumask *cpumask, + unsigned int *apicid) +{ + int cpu = cpumask_first(cpumask); + return __default_cpu_to_apicid(cpu, apicid); } -unsigned int -default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) +int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask, + unsigned int *apicid) { int cpu; @@ -2148,7 +2150,8 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - return per_cpu(x86_cpu_to_apicid, cpu); + + return __default_cpu_to_apicid(cpu, apicid); } /* diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 3c42865757e2..515ebb00a9fc 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -525,7 +525,8 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) return 1; } -static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) +static int +es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) { unsigned int round = 0; int cpu, uninitialized_var(apicid); @@ -539,31 +540,33 @@ static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { WARN(1, "Not a valid mask!"); - return BAD_APICID; + return -EINVAL; } apicid = new_apicid; round++; } - return apicid; + *dest_id = apicid; + return 0; } -static unsigned int +static int es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, - const struct cpumask *andmask) + const struct cpumask *andmask, + unsigned int *apicid) { - int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); + *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); cpumask_var_t cpumask; if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) - return apicid; + return 0; cpumask_and(cpumask, inmask, andmask); cpumask_and(cpumask, cpumask, cpu_online_mask); - apicid = es7000_cpu_mask_to_apicid(cpumask); + es7000_cpu_mask_to_apicid(cpumask, apicid); free_cpumask_var(cpumask); - return apicid; + return 0; } static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 4061a7dee5c9..0deb773404e5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1359,7 +1359,14 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, if (assign_irq_vector(irq, cfg, apic->target_cpus())) return; - dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); + if (apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus(), + &dest)) { + pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n", + mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); + __clear_irq_vector(irq, cfg); + + return; + } apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " @@ -1474,6 +1481,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, unsigned int pin, int vector) { struct IO_APIC_route_entry entry; + unsigned int dest; if (irq_remapping_enabled) return; @@ -1484,9 +1492,12 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, * We use logical delivery to get the timer IRQ * to the first CPU. */ + if (unlikely(apic->cpu_mask_to_apicid(apic->target_cpus(), &dest))) + dest = BAD_APICID; + entry.dest_mode = apic->irq_dest_mode; entry.mask = 0; /* don't mask IRQ for edge */ - entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); + entry.dest = dest; entry.delivery_mode = apic->irq_delivery_mode; entry.polarity = 0; entry.trigger = 0; @@ -2245,16 +2256,25 @@ int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, unsigned int *dest_id) { struct irq_cfg *cfg = data->chip_data; + unsigned int irq = data->irq; + int err; if (!cpumask_intersects(mask, cpu_online_mask)) - return -1; + return -EINVAL; - if (assign_irq_vector(data->irq, data->chip_data, mask)) - return -1; + err = assign_irq_vector(irq, cfg, mask); + if (err) + return err; + + err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id); + if (err) { + if (assign_irq_vector(irq, cfg, data->affinity)) + pr_err("Failed to recover vector for irq %d\n", irq); + return err; + } cpumask_copy(data->affinity, mask); - *dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain); return 0; } @@ -3040,7 +3060,10 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, if (err) return err; - dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); + err = apic->cpu_mask_to_apicid_and(cfg->domain, + apic->target_cpus(), &dest); + if (err) + return err; if (irq_remapped(cfg)) { compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); @@ -3361,6 +3384,8 @@ static struct irq_chip ht_irq_chip = { int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) { struct irq_cfg *cfg; + struct ht_irq_msg msg; + unsigned dest; int err; if (disable_apic) @@ -3368,36 +3393,37 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) cfg = irq_cfg(irq); err = assign_irq_vector(irq, cfg, apic->target_cpus()); - if (!err) { - struct ht_irq_msg msg; - unsigned dest; + if (err) + return err; - dest = apic->cpu_mask_to_apicid_and(cfg->domain, - apic->target_cpus()); + err = apic->cpu_mask_to_apicid_and(cfg->domain, + apic->target_cpus(), &dest); + if (err) + return err; - msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); + msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); - msg.address_lo = - HT_IRQ_LOW_BASE | - HT_IRQ_LOW_DEST_ID(dest) | - HT_IRQ_LOW_VECTOR(cfg->vector) | - ((apic->irq_dest_mode == 0) ? - HT_IRQ_LOW_DM_PHYSICAL : - HT_IRQ_LOW_DM_LOGICAL) | - HT_IRQ_LOW_RQEOI_EDGE | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - HT_IRQ_LOW_MT_FIXED : - HT_IRQ_LOW_MT_ARBITRATED) | - HT_IRQ_LOW_IRQ_MASKED; + msg.address_lo = + HT_IRQ_LOW_BASE | + HT_IRQ_LOW_DEST_ID(dest) | + HT_IRQ_LOW_VECTOR(cfg->vector) | + ((apic->irq_dest_mode == 0) ? + HT_IRQ_LOW_DM_PHYSICAL : + HT_IRQ_LOW_DM_LOGICAL) | + HT_IRQ_LOW_RQEOI_EDGE | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + HT_IRQ_LOW_MT_FIXED : + HT_IRQ_LOW_MT_ARBITRATED) | + HT_IRQ_LOW_IRQ_MASKED; - write_ht_irq_msg(irq, &msg); + write_ht_irq_msg(irq, &msg); - irq_set_chip_and_handler_name(irq, &ht_irq_chip, - handle_edge_irq, "edge"); + irq_set_chip_and_handler_name(irq, &ht_irq_chip, + handle_edge_irq, "edge"); - dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); - } - return err; + dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); + + return 0; } #endif /* CONFIG_HT_IRQ */ diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index eb2d466fd81a..2b55514c328b 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -406,16 +406,20 @@ static inline int numaq_check_phys_apicid_present(int phys_apicid) * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ -static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask) +static int +numaq_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) { - return 0x0F; + *apicid = 0x0F; + return 0; } -static inline unsigned int +static int numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) + const struct cpumask *andmask, + unsigned int *apicid) { - return 0x0F; + *apicid = 0x0F; + return 0; } /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 35d254c1fec2..5766d84f12d6 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -263,7 +263,8 @@ static int summit_check_phys_apicid_present(int physical_apicid) return 1; } -static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) +static int +summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) { unsigned int round = 0; int cpu, apicid = 0; @@ -276,30 +277,33 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { printk("%s: Not a valid mask!\n", __func__); - return BAD_APICID; + return -EINVAL; } apicid |= new_apicid; round++; } - return apicid; + *dest_id = apicid; + return 0; } -static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, - const struct cpumask *andmask) +static int +summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, + const struct cpumask *andmask, + unsigned int *apicid) { - int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); + *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); cpumask_var_t cpumask; if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) - return apicid; + return 0; cpumask_and(cpumask, inmask, andmask); cpumask_and(cpumask, cpumask, cpu_online_mask); - apicid = summit_cpu_mask_to_apicid(cpumask); + summit_cpu_mask_to_apicid(cpumask, apicid); free_cpumask_var(cpumask); - return apicid; + return 0; } /* diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 612622c47dfb..5f86f79335f4 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -96,24 +96,26 @@ static void x2apic_send_IPI_all(int vector) __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); } -static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) +static int +x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) { int cpu = cpumask_first(cpumask); - u32 dest = 0; int i; - if (cpu > nr_cpu_ids) - return BAD_APICID; + if (cpu >= nr_cpu_ids) + return -EINVAL; + *apicid = 0; for_each_cpu_and(i, cpumask, per_cpu(cpus_in_cluster, cpu)) - dest |= per_cpu(x86_cpu_to_logical_apicid, i); + *apicid |= per_cpu(x86_cpu_to_logical_apicid, i); - return dest; + return 0; } -static unsigned int +static int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) + const struct cpumask *andmask, + unsigned int *apicid) { u32 dest = 0; u16 cluster; @@ -128,7 +130,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, } if (!dest) - return BAD_APICID; + return -EINVAL; for_each_cpu_and(i, cpumask, andmask) { if (!cpumask_test_cpu(i, cpu_online_mask)) @@ -138,7 +140,9 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, dest |= per_cpu(x86_cpu_to_logical_apicid, i); } - return dest; + *apicid = dest; + + return 0; } static void init_x2apic_ldr(void) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index df89a7d78748..2f3030fef31e 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -269,23 +269,31 @@ static void uv_init_apic_ldr(void) { } -static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask) +static inline int __uv_cpu_to_apicid(int cpu, unsigned int *apicid) +{ + if (likely((unsigned int)cpu < nr_cpu_ids)) { + *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; + return 0; + } else { + return -EINVAL; + } +} + +static int +uv_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) { /* * We're using fixed IRQ delivery, can only return one phys APIC ID. * May as well be the first. */ int cpu = cpumask_first(cpumask); - - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; - else - return BAD_APICID; + return __uv_cpu_to_apicid(cpu, apicid); } -static unsigned int +static int uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) + const struct cpumask *andmask, + unsigned int *apicid) { int cpu; @@ -297,7 +305,8 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; + + return __uv_cpu_to_apicid(cpu, apicid); } static unsigned int x2apic_get_apic_id(unsigned long x) diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c index f25c2765a5c9..dd1ff39a464c 100644 --- a/arch/x86/platform/uv/uv_irq.c +++ b/arch/x86/platform/uv/uv_irq.c @@ -135,6 +135,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, unsigned long mmr_value; struct uv_IO_APIC_route_entry *entry; int mmr_pnode, err; + unsigned int dest; BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); @@ -143,6 +144,10 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, if (err != 0) return err; + err = apic->cpu_mask_to_apicid(eligible_cpu, &dest); + if (err != 0) + return err; + if (limit == UV_AFFINITY_CPU) irq_set_status_flags(irq, IRQ_NO_BALANCING); else @@ -159,7 +164,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, entry->polarity = 0; entry->trigger = 0; entry->mask = 0; - entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); + entry->dest = dest; mmr_pnode = uv_blade_to_pnode(mmr_blade); uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 6d347064b8b0..dafbad06390a 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -924,6 +924,7 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irq_cfg *cfg = data->chip_data; unsigned int dest, irq = data->irq; struct irte irte; + int err; if (!cpumask_intersects(mask, cpu_online_mask)) return -EINVAL; @@ -931,10 +932,16 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, if (get_irte(irq, &irte)) return -EBUSY; - if (assign_irq_vector(irq, cfg, mask)) - return -EBUSY; + err = assign_irq_vector(irq, cfg, mask); + if (err) + return err; - dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); + err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest); + if (err) { + if (assign_irq_vector(irq, cfg, data->affinity)); + pr_err("Failed to recover vector for irq %d\n", irq); + return err; + } irte.vector = cfg->vector; irte.dest_id = IRTE_DEST(dest); -- GitLab From 4988a40c3981212fa8c64da68722affc1cb6697a Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 7 Jun 2012 15:16:25 +0200 Subject: [PATCH 0977/6849] x86/apic: Make cpu_mask_to_apicid() operations check cpu_online_mask Currently cpu_mask_to_apicid() should not get a offline CPU with the cpumask. Otherwise some apic drivers might try to access non-existent per-cpu variables (i.e. x2apic). In that regard cpu_mask_to_apicid() and cpu_mask_to_apicid_and() operations are inconsistent. This fix makes the two operations do not rely on calling functions and always return the apicid for only online CPUs. As result, the meaning and implementations of cpu_mask_to_apicid() and cpu_mask_to_apicid_and() operations become straight. Signed-off-by: Alexander Gordeev Acked-by: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120607131624.GG4759@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 6 ++---- arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/apic/es7000_32.c | 3 +-- arch/x86/kernel/apic/summit_32.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 2 +- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index ae91f9c7e360..1ed3eead2039 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -596,7 +596,7 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) static inline int __flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid) { - cpu_mask &= APIC_ALL_CPUS; + cpu_mask = cpu_mask & APIC_ALL_CPUS & cpumask_bits(cpu_online_mask)[0]; if (likely(cpu_mask)) { *apicid = (unsigned int)cpu_mask; return 0; @@ -619,9 +619,7 @@ flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, { unsigned long mask1 = cpumask_bits(cpumask)[0]; unsigned long mask2 = cpumask_bits(andmask)[0]; - unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; - - return __flat_cpu_mask_to_apicid(mask1 & mask2 & mask3, apicid); + return __flat_cpu_mask_to_apicid(mask1 & mask2, apicid); } extern int diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index b8d92606f84f..7e9bbe73bc5a 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2136,7 +2136,7 @@ static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid) int default_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) { - int cpu = cpumask_first(cpumask); + int cpu = cpumask_first_and(cpumask, cpu_online_mask); return __default_cpu_to_apicid(cpu, apicid); } diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 515ebb00a9fc..b35cfb9b6962 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -534,7 +534,7 @@ es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) /* * The cpus in the mask must all be on the apic cluster. */ - for_each_cpu(cpu, cpumask) { + for_each_cpu_and(cpu, cpumask, cpu_online_mask) { int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { @@ -561,7 +561,6 @@ es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, return 0; cpumask_and(cpumask, inmask, andmask); - cpumask_and(cpumask, cpumask, cpu_online_mask); es7000_cpu_mask_to_apicid(cpumask, apicid); free_cpumask_var(cpumask); diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 5766d84f12d6..79d360f6729e 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -272,7 +272,7 @@ summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) /* * The cpus in the mask must all be on the apic cluster. */ - for_each_cpu(cpu, cpumask) { + for_each_cpu_and(cpu, cpumask, cpu_online_mask) { int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { @@ -298,7 +298,6 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, return 0; cpumask_and(cpumask, inmask, andmask); - cpumask_and(cpumask, cpumask, cpu_online_mask); summit_cpu_mask_to_apicid(cpumask, apicid); free_cpumask_var(cpumask); diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 5f86f79335f4..23a46cf5b6fd 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -99,7 +99,7 @@ static void x2apic_send_IPI_all(int vector) static int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) { - int cpu = cpumask_first(cpumask); + int cpu = cpumask_first_and(cpumask, cpu_online_mask); int i; if (cpu >= nr_cpu_ids) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 2f3030fef31e..307aa076bd62 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -286,7 +286,7 @@ uv_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) * We're using fixed IRQ delivery, can only return one phys APIC ID. * May as well be the first. */ - int cpu = cpumask_first(cpumask); + int cpu = cpumask_first_and(cpumask, cpu_online_mask); return __uv_cpu_to_apicid(cpu, apicid); } -- GitLab From bf947fcb77ff858f223c49c76e2d130095fa2585 Mon Sep 17 00:00:00 2001 From: Donald Dutile Date: Mon, 4 Jun 2012 17:29:01 -0400 Subject: [PATCH 0978/6849] iommu/dmar: Replace printks with appropriate pr_*() Just some cleanup so next patch can keep the info printing the same way throughout the file. Replace printk(KERN_* with pr_*() functions. Signed-off-by: Donald Dutile Cc: iommu@lists.linux-foundation.org Cc: chrisw@redhat.com Cc: suresh.b.siddha@intel.com Cc: dwmw2@infradead.org Link: http://lkml.kernel.org/r/1338845342-12464-2-git-send-email-ddutile@redhat.com Signed-off-by: Ingo Molnar --- drivers/iommu/dmar.c | 83 +++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 3a74e4410fc0..1e5a10de3471 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -83,15 +83,14 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, * ignore it */ if (!bus) { - printk(KERN_WARNING - PREFIX "Device scope bus [%d] not found\n", - scope->bus); + pr_warn(PREFIX "Device scope bus [%d] not found\n", + scope->bus); break; } pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn)); if (!pdev) { - printk(KERN_WARNING PREFIX - "Device scope device [%04x:%02x:%02x.%02x] not found\n", + pr_warn(PREFIX "Device scope device" + "[%04x:%02x:%02x.%02x] not found\n", segment, bus->number, path->dev, path->fn); break; } @@ -100,9 +99,9 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, bus = pdev->subordinate; } if (!pdev) { - printk(KERN_WARNING PREFIX - "Device scope device [%04x:%02x:%02x.%02x] not found\n", - segment, scope->bus, path->dev, path->fn); + pr_warn(PREFIX + "Device scope device [%04x:%02x:%02x.%02x] not found\n", + segment, scope->bus, path->dev, path->fn); *dev = NULL; return 0; } @@ -110,8 +109,7 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, pdev->subordinate) || (scope->entry_type == \ ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) { pci_dev_put(pdev); - printk(KERN_WARNING PREFIX - "Device scope type does not match for %s\n", + pr_warn(PREFIX "Device scope type does not match for %s\n", pci_name(pdev)); return -EINVAL; } @@ -134,8 +132,7 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) (*cnt)++; else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) { - printk(KERN_WARNING PREFIX - "Unsupported device scope\n"); + pr_warn(PREFIX "Unsupported device scope\n"); } start += scope->length; } @@ -261,25 +258,23 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) case ACPI_DMAR_TYPE_HARDWARE_UNIT: drhd = container_of(header, struct acpi_dmar_hardware_unit, header); - printk (KERN_INFO PREFIX - "DRHD base: %#016Lx flags: %#x\n", + pr_info(PREFIX "DRHD base: %#016Lx flags: %#x\n", (unsigned long long)drhd->address, drhd->flags); break; case ACPI_DMAR_TYPE_RESERVED_MEMORY: rmrr = container_of(header, struct acpi_dmar_reserved_memory, header); - printk (KERN_INFO PREFIX - "RMRR base: %#016Lx end: %#016Lx\n", + pr_info(PREFIX "RMRR base: %#016Lx end: %#016Lx\n", (unsigned long long)rmrr->base_address, (unsigned long long)rmrr->end_address); break; case ACPI_DMAR_TYPE_ATSR: atsr = container_of(header, struct acpi_dmar_atsr, header); - printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags); + pr_info(PREFIX "ATSR flags: %#x\n", atsr->flags); break; case ACPI_DMAR_HARDWARE_AFFINITY: rhsa = container_of(header, struct acpi_dmar_rhsa, header); - printk(KERN_INFO PREFIX "RHSA base: %#016Lx proximity domain: %#x\n", + pr_info(PREFIX "RHSA base: %#016Lx proximity domain: %#x\n", (unsigned long long)rhsa->base_address, rhsa->proximity_domain); break; @@ -299,7 +294,7 @@ static int __init dmar_table_detect(void) &dmar_tbl_size); if (ACPI_SUCCESS(status) && !dmar_tbl) { - printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); + pr_warn(PREFIX "Unable to map DMAR\n"); status = AE_NOT_FOUND; } @@ -333,20 +328,18 @@ parse_dmar_table(void) return -ENODEV; if (dmar->width < PAGE_SHIFT - 1) { - printk(KERN_WARNING PREFIX "Invalid DMAR haw\n"); + pr_warn(PREFIX "Invalid DMAR haw\n"); return -EINVAL; } - printk (KERN_INFO PREFIX "Host address width %d\n", - dmar->width + 1); + pr_info(PREFIX "Host address width %d\n", dmar->width + 1); entry_header = (struct acpi_dmar_header *)(dmar + 1); while (((unsigned long)entry_header) < (((unsigned long)dmar) + dmar_tbl->length)) { /* Avoid looping forever on bad ACPI tables */ if (entry_header->length == 0) { - printk(KERN_WARNING PREFIX - "Invalid 0-length structure\n"); + pr_warn(PREFIX "Invalid 0-length structure\n"); ret = -EINVAL; break; } @@ -369,8 +362,7 @@ parse_dmar_table(void) #endif break; default: - printk(KERN_WARNING PREFIX - "Unknown DMAR structure type %d\n", + pr_warn(PREFIX "Unknown DMAR structure type %d\n", entry_header->type); ret = 0; /* for forward compatibility */ break; @@ -469,12 +461,12 @@ int __init dmar_table_init(void) ret = parse_dmar_table(); if (ret) { if (ret != -ENODEV) - printk(KERN_INFO PREFIX "parse DMAR table failure.\n"); + pr_info(PREFIX "parse DMAR table failure.\n"); return ret; } if (list_empty(&dmar_drhd_units)) { - printk(KERN_INFO PREFIX "No DMAR devices found\n"); + pr_info(PREFIX "No DMAR devices found\n"); return -ENODEV; } @@ -506,8 +498,7 @@ int __init check_zero_address(void) (((unsigned long)dmar) + dmar_tbl->length)) { /* Avoid looping forever on bad ACPI tables */ if (entry_header->length == 0) { - printk(KERN_WARNING PREFIX - "Invalid 0-length structure\n"); + pr_warn(PREFIX "Invalid 0-length structure\n"); return 0; } @@ -558,8 +549,8 @@ int __init detect_intel_iommu(void) if (ret && irq_remapping_enabled && cpu_has_x2apic && dmar->flags & 0x1) - printk(KERN_INFO - "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); + pr_info("Queued invalidation will be enabled to " + "support x2apic and Intr-remapping.\n"); if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { iommu_detected = 1; @@ -602,7 +593,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE); if (!iommu->reg) { - printk(KERN_ERR "IOMMU: can't map the region\n"); + pr_err("IOMMU: can't map the region\n"); goto error; } iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); @@ -615,15 +606,13 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) agaw = iommu_calculate_agaw(iommu); if (agaw < 0) { - printk(KERN_ERR - "Cannot get a valid agaw for iommu (seq_id = %d)\n", - iommu->seq_id); + pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", + iommu->seq_id); goto err_unmap; } msagaw = iommu_calculate_max_sagaw(iommu); if (msagaw < 0) { - printk(KERN_ERR - "Cannot get a valid max agaw for iommu (seq_id = %d)\n", + pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n", iommu->seq_id); goto err_unmap; } @@ -640,7 +629,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iounmap(iommu->reg); iommu->reg = ioremap(drhd->reg_base_addr, map_size); if (!iommu->reg) { - printk(KERN_ERR "IOMMU: can't map the region\n"); + pr_err("IOMMU: can't map the region\n"); goto error; } } @@ -710,7 +699,7 @@ static int qi_check_fault(struct intel_iommu *iommu, int index) if (fault & DMA_FSTS_IQE) { head = readl(iommu->reg + DMAR_IQH_REG); if ((head >> DMAR_IQ_SHIFT) == index) { - printk(KERN_ERR "VT-d detected invalid descriptor: " + pr_err("VT-d detected invalid descriptor: " "low=%llx, high=%llx\n", (unsigned long long)qi->desc[index].low, (unsigned long long)qi->desc[index].high); @@ -1129,15 +1118,14 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type, reason = dmar_get_fault_reason(fault_reason, &fault_type); if (fault_type == INTR_REMAP) - printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] " + pr_err("INTR-REMAP: Request device [[%02x:%02x.%d] " "fault index %llx\n" "INTR-REMAP:[fault reason %02d] %s\n", (source_id >> 8), PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr >> 48, fault_reason, reason); else - printk(KERN_ERR - "DMAR:[%s] Request device [%02x:%02x.%d] " + pr_err("DMAR:[%s] Request device [%02x:%02x.%d] " "fault addr %llx \n" "DMAR:[fault reason %02d] %s\n", (type ? "DMA Read" : "DMA Write"), @@ -1157,8 +1145,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id) raw_spin_lock_irqsave(&iommu->register_lock, flag); fault_status = readl(iommu->reg + DMAR_FSTS_REG); if (fault_status) - printk(KERN_ERR "DRHD: handling fault status reg %x\n", - fault_status); + pr_err("DRHD: handling fault status reg %x\n", fault_status); /* TBD: ignore advanced fault log currently */ if (!(fault_status & DMA_FSTS_PPF)) @@ -1224,7 +1211,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) irq = create_irq(); if (!irq) { - printk(KERN_ERR "IOMMU: no free vectors\n"); + pr_err("IOMMU: no free vectors\n"); return -EINVAL; } @@ -1241,7 +1228,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); if (ret) - printk(KERN_ERR "IOMMU: can't request irq\n"); + pr_err("IOMMU: can't request irq\n"); return ret; } @@ -1258,7 +1245,7 @@ int __init enable_drhd_fault_handling(void) ret = dmar_set_interrupt(iommu); if (ret) { - printk(KERN_ERR "DRHD %Lx: failed to enable fault, " + pr_err("DRHD %Lx: failed to enable fault, " " interrupt, ret %d\n", (unsigned long long)drhd->reg_base_addr, ret); return -1; -- GitLab From 6f5cf52114dd87f9ed091678f7dfc8ff21bbe2b3 Mon Sep 17 00:00:00 2001 From: Donald Dutile Date: Mon, 4 Jun 2012 17:29:02 -0400 Subject: [PATCH 0979/6849] iommu/dmar: Reserve mmio space used by the IOMMU, if the BIOS forgets to Intel-iommu initialization doesn't currently reserve the memory used for the IOMMU registers. This can allow the pci resource allocator to assign a device BAR to the same address as the IOMMU registers. This can cause some not so nice side affects when the driver ioremap's that region. Introduced two helper functions to map & unmap the IOMMU registers as well as simplify the init and exit paths. Signed-off-by: Donald Dutile Acked-by: Chris Wright Cc: iommu@lists.linux-foundation.org Cc: suresh.b.siddha@intel.com Cc: dwmw2@infradead.org Link: http://lkml.kernel.org/r/1338845342-12464-3-git-send-email-ddutile@redhat.com Signed-off-by: Ingo Molnar --- drivers/iommu/dmar.c | 111 +++++++++++++++++++++++++++--------- include/linux/intel-iommu.h | 2 + 2 files changed, 86 insertions(+), 27 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 1e5a10de3471..9ab6ebf46f7a 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -570,14 +570,89 @@ int __init detect_intel_iommu(void) } +static void unmap_iommu(struct intel_iommu *iommu) +{ + iounmap(iommu->reg); + release_mem_region(iommu->reg_phys, iommu->reg_size); +} + +/** + * map_iommu: map the iommu's registers + * @iommu: the iommu to map + * @phys_addr: the physical address of the base resgister + * + * Memory map the iommu's registers. Start w/ a single page, and + * possibly expand if that turns out to be insufficent. + */ +static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) +{ + int map_size, err=0; + + iommu->reg_phys = phys_addr; + iommu->reg_size = VTD_PAGE_SIZE; + + if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) { + pr_err("IOMMU: can't reserve memory\n"); + err = -EBUSY; + goto out; + } + + iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); + if (!iommu->reg) { + pr_err("IOMMU: can't map the region\n"); + err = -ENOMEM; + goto release; + } + + iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); + iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); + + if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { + err = -EINVAL; + warn_invalid_dmar(phys_addr, " returns all ones"); + goto unmap; + } + + /* the registers might be more than one page */ + map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), + cap_max_fault_reg_offset(iommu->cap)); + map_size = VTD_PAGE_ALIGN(map_size); + if (map_size > iommu->reg_size) { + iounmap(iommu->reg); + release_mem_region(iommu->reg_phys, iommu->reg_size); + iommu->reg_size = map_size; + if (!request_mem_region(iommu->reg_phys, iommu->reg_size, + iommu->name)) { + pr_err("IOMMU: can't reserve memory\n"); + err = -EBUSY; + goto out; + } + iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); + if (!iommu->reg) { + pr_err("IOMMU: can't map the region\n"); + err = -ENOMEM; + goto release; + } + } + err = 0; + goto out; + +unmap: + iounmap(iommu->reg); +release: + release_mem_region(iommu->reg_phys, iommu->reg_size); +out: + return err; +} + int alloc_iommu(struct dmar_drhd_unit *drhd) { struct intel_iommu *iommu; - int map_size; u32 ver; static int iommu_allocated = 0; int agaw = 0; int msagaw = 0; + int err; if (!drhd->reg_base_addr) { warn_invalid_dmar(0, ""); @@ -591,19 +666,13 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->seq_id = iommu_allocated++; sprintf (iommu->name, "dmar%d", iommu->seq_id); - iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE); - if (!iommu->reg) { - pr_err("IOMMU: can't map the region\n"); + err = map_iommu(iommu, drhd->reg_base_addr); + if (err) { + pr_err("IOMMU: failed to map %s\n", iommu->name); goto error; } - iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); - iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); - - if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { - warn_invalid_dmar(drhd->reg_base_addr, " returns all ones"); - goto err_unmap; - } + err = -EINVAL; agaw = iommu_calculate_agaw(iommu); if (agaw < 0) { pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", @@ -621,19 +690,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->node = -1; - /* the registers might be more than one page */ - map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), - cap_max_fault_reg_offset(iommu->cap)); - map_size = VTD_PAGE_ALIGN(map_size); - if (map_size > VTD_PAGE_SIZE) { - iounmap(iommu->reg); - iommu->reg = ioremap(drhd->reg_base_addr, map_size); - if (!iommu->reg) { - pr_err("IOMMU: can't map the region\n"); - goto error; - } - } - ver = readl(iommu->reg + DMAR_VER_REG); pr_info("IOMMU %d: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", iommu->seq_id, @@ -648,10 +704,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) return 0; err_unmap: - iounmap(iommu->reg); + unmap_iommu(iommu); error: kfree(iommu); - return -1; + return err; } void free_iommu(struct intel_iommu *iommu) @@ -662,7 +718,8 @@ void free_iommu(struct intel_iommu *iommu) free_dmar_iommu(iommu); if (iommu->reg) - iounmap(iommu->reg); + unmap_iommu(iommu); + kfree(iommu); } diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index e6ca56de9936..78e2ada50cd5 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -308,6 +308,8 @@ enum { struct intel_iommu { void __iomem *reg; /* Pointer to hardware regs, virtual addr */ + u64 reg_phys; /* physical address of hw register set */ + u64 reg_size; /* size of hw register set */ u64 cap; u64 ecap; u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ -- GitLab From ba1ddcb6ca0c46edd275790d1e4e2cfd6219ce19 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 8 Jun 2012 11:16:22 +0100 Subject: [PATCH 0980/6849] GFS2: Cache last hash bucket for glock seq_files For the glocks and glstats seq_files, which are exposed via debugfs we should cache the most recent hash bucket, along with the offset into that bucket. This allows us to restart from that point, rather than having to begin at the beginning each time. This is an idea from Eric Dumazet, however I've slightly extended it so that if the position from which we are due to start is at any point beyond the last cached point, we start from the last cached point, plus whatever is the appropriate offset. I don't really expect people to be lseeking around these files, but if they did so with only positive offsets, then we'd still get some of the benefit of using a cached offset. With my simple test of around 200k entries in the file, I'm seeing an approx 10x speed up. Cc: Eric Dumazet Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 1c4cddf42a66..3ad8cb3eeb88 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -46,10 +46,12 @@ #include "trace_gfs2.h" struct gfs2_glock_iter { - int hash; /* hash bucket index */ - struct gfs2_sbd *sdp; /* incore superblock */ - struct gfs2_glock *gl; /* current glock struct */ - char string[512]; /* scratch space */ + int hash; /* hash bucket index */ + unsigned nhash; /* Index within current bucket */ + struct gfs2_sbd *sdp; /* incore superblock */ + struct gfs2_glock *gl; /* current glock struct */ + loff_t last_pos; /* last position */ + char string[512]; /* scratch space */ }; typedef void (*glock_examiner) (struct gfs2_glock * gl); @@ -950,7 +952,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) if (seq) { struct gfs2_glock_iter *gi = seq->private; vsprintf(gi->string, fmt, args); - seq_printf(seq, gi->string); + seq_puts(seq, gi->string); } else { vaf.fmt = fmt; vaf.va = &args; @@ -1854,8 +1856,14 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) gl = gi->gl; if (gl) { gi->gl = glock_hash_next(gl); + gi->nhash++; } else { + if (gi->hash >= GFS2_GL_HASH_SIZE) { + rcu_read_unlock(); + return 1; + } gi->gl = glock_hash_chain(gi->hash); + gi->nhash = 0; } while (gi->gl == NULL) { gi->hash++; @@ -1864,6 +1872,7 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) return 1; } gi->gl = glock_hash_chain(gi->hash); + gi->nhash = 0; } /* Skip entries for other sb and dead entries */ } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0); @@ -1876,7 +1885,12 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) struct gfs2_glock_iter *gi = seq->private; loff_t n = *pos; - gi->hash = 0; + if (gi->last_pos <= *pos) + n = gi->nhash + (*pos - gi->last_pos); + else + gi->hash = 0; + + gi->nhash = 0; rcu_read_lock(); do { @@ -1884,6 +1898,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) return NULL; } while (n--); + gi->last_pos = *pos; return gi->gl; } @@ -1893,7 +1908,7 @@ static void *gfs2_glock_seq_next(struct seq_file *seq, void *iter_ptr, struct gfs2_glock_iter *gi = seq->private; (*pos)++; - + gi->last_pos = *pos; if (gfs2_glock_iter_next(gi)) return NULL; -- GitLab From 7eb9ba5ed312ec6ed9d22259c5da1acb7cf4bd29 Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Fri, 8 Jun 2012 15:02:57 +0530 Subject: [PATCH 0981/6849] uprobes: Pass probed vaddr to arch_uprobe_analyze_insn() On RISC architectures like powerpc, instructions are fixed size. Instruction analysis on such platforms is just a matter of (insn % 4). Pass the vaddr at which the uprobe is to be inserted so that arch_uprobe_analyze_insn() can flag misaligned registration requests. Signed-off-by: Ananth N Mavinakaynahalli Cc: michael@ellerman.id.au Cc: antonb@thinktux.localdomain Cc: Paul Mackerras Cc: benh@kernel.crashing.org Cc: peterz@infradead.org Cc: Srikar Dronamraju Cc: Jim Keniston Cc: oleg@redhat.com Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/20120608093257.GG13409@in.ibm.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uprobes.h | 2 +- arch/x86/kernel/uprobes.c | 3 ++- kernel/events/uprobes.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h index 1e9bed14f7ae..f3971bbcd1de 100644 --- a/arch/x86/include/asm/uprobes.h +++ b/arch/x86/include/asm/uprobes.h @@ -48,7 +48,7 @@ struct arch_uprobe_task { #endif }; -extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm); +extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index dc4e910a7d96..36fd42091fa7 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -409,9 +409,10 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. * @mm: the probed address space. * @arch_uprobe: the probepoint information. + * @addr: virtual address at which to install the probepoint * Return 0 on success or a -ve number on error. */ -int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm) +int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr) { int ret; struct insn insn; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 8c5e043cd309..b52376d02332 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -706,7 +706,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) return -EEXIST; - ret = arch_uprobe_analyze_insn(&uprobe->arch, mm); + ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, addr); if (ret) return ret; -- GitLab From 90306c41dc3d8e5f12ecd0193dae99e0e7f6e896 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 29 May 2012 23:01:09 -0500 Subject: [PATCH 0982/6849] GFS2: Use lvbs for storing rgrp information with mount option Instead of reading in the resource groups when gfs2 is checking for free space to allocate from, gfs2 can store the necessary infromation in the resource group's lvb. Also, instead of searching for unlinked inodes in every resource group that's checked for free space, gfs2 can store the number of unlinked but inodes in the lvb, and only check for unlinked inodes if it will find some. The first time a resource group is locked, the lvb must initialized. Since this involves counting the unlinked inodes in the resource group, this takes a little extra time. But after that, if the resource group is locked with GL_SKIP, the buffer head won't be read in unless it's actually needed. Enabling the resource groups lvbs is done via the rgrplvb mount option. If this option isn't set, the lvbs will still be set and updated, but they won't be verfied or used by the filesystem. To safely turn on this option, all of the nodes mounting the filesystem must be running code with this patch, and the filesystem must have been completely unmounted since they were updated. Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 1 + fs/gfs2/incore.h | 2 + fs/gfs2/rgrp.c | 147 +++++++++++++++++++++++++++++++++--- fs/gfs2/super.c | 12 +++ include/linux/gfs2_ondisk.h | 10 +++ 5 files changed, 163 insertions(+), 9 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 3ad8cb3eeb88..10ae1645d9a5 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -769,6 +769,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, gl->gl_stats.stats[GFS2_LKS_DCOUNT] = 0; gl->gl_stats.stats[GFS2_LKS_QCOUNT] = 0; memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb)); + memset(gl->gl_lvb, 0, 32 * sizeof(char)); gl->gl_lksb.sb_lvbptr = gl->gl_lvb; gl->gl_tchange = jiffies; gl->gl_object = NULL; diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 5cda51a3e3bd..dc730700b3b4 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -89,6 +89,7 @@ struct gfs2_rgrpd { u64 rd_igeneration; struct gfs2_bitmap *rd_bits; struct gfs2_sbd *rd_sbd; + struct gfs2_rgrp_lvb *rd_rgl; u32 rd_last_alloc; u32 rd_flags; #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ @@ -470,6 +471,7 @@ struct gfs2_args { unsigned int ar_discard:1; /* discard requests */ unsigned int ar_errors:2; /* errors=withdraw | panic */ unsigned int ar_nobarrier:1; /* do not send barriers */ + unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */ int ar_commit; /* Commit interval */ int ar_statfs_quantum; /* The fast statfs interval */ int ar_quota_quantum; /* The quota interval */ diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 9eca6a9cff8f..3c6f7ed16a3b 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -660,6 +660,7 @@ static int read_rindex_entry(struct gfs2_inode *ip) goto fail; rgd->rd_gl->gl_object = rgd; + rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lvb; rgd->rd_flags &= ~GFS2_RDF_UPTODATE; if (rgd->rd_data > sdp->sd_max_rg_data) sdp->sd_max_rg_data = rgd->rd_data; @@ -769,9 +770,65 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); } +static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd) +{ + struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; + struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bits[0].bi_bh->b_data; + + if (rgl->rl_flags != str->rg_flags || rgl->rl_free != str->rg_free || + rgl->rl_dinodes != str->rg_dinodes || + rgl->rl_igeneration != str->rg_igeneration) + return 0; + return 1; +} + +static void gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb *rgl, const void *buf) +{ + const struct gfs2_rgrp *str = buf; + + rgl->rl_magic = cpu_to_be32(GFS2_MAGIC); + rgl->rl_flags = str->rg_flags; + rgl->rl_free = str->rg_free; + rgl->rl_dinodes = str->rg_dinodes; + rgl->rl_igeneration = str->rg_igeneration; + rgl->__pad = 0UL; +} + +static void update_rgrp_lvb_unlinked(struct gfs2_rgrpd *rgd, u32 change) +{ + struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; + u32 unlinked = be32_to_cpu(rgl->rl_unlinked) + change; + rgl->rl_unlinked = cpu_to_be32(unlinked); +} + +static u32 count_unlinked(struct gfs2_rgrpd *rgd) +{ + struct gfs2_bitmap *bi; + const u32 length = rgd->rd_length; + const u8 *buffer = NULL; + u32 i, goal, count = 0; + + for (i = 0, bi = rgd->rd_bits; i < length; i++, bi++) { + goal = 0; + buffer = bi->bi_bh->b_data + bi->bi_offset; + WARN_ON(!buffer_uptodate(bi->bi_bh)); + while (goal < bi->bi_len * GFS2_NBBY) { + goal = gfs2_bitfit(buffer, bi->bi_len, goal, + GFS2_BLKST_UNLINKED); + if (goal == BFITNOENT) + break; + count++; + goal++; + } + } + + return count; +} + + /** - * gfs2_rgrp_go_lock - Read in a RG's header and bitmaps - * @gh: The glock holder for the resource group + * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps + * @rgd: the struct gfs2_rgrpd describing the RG to read in * * Read in all of a Resource Group's header and bitmap blocks. * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. @@ -779,9 +836,8 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) * Returns: errno */ -int gfs2_rgrp_go_lock(struct gfs2_holder *gh) +int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) { - struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_glock *gl = rgd->rd_gl; unsigned int length = rgd->rd_length; @@ -789,6 +845,9 @@ int gfs2_rgrp_go_lock(struct gfs2_holder *gh) unsigned int x, y; int error; + if (rgd->rd_bits[0].bi_bh != NULL) + return 0; + for (x = 0; x < length; x++) { bi = rgd->rd_bits + x; error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); @@ -815,7 +874,20 @@ int gfs2_rgrp_go_lock(struct gfs2_holder *gh) rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); rgd->rd_free_clone = rgd->rd_free; } - + if (be32_to_cpu(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) { + rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd)); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, + rgd->rd_bits[0].bi_bh->b_data); + } + else if (sdp->sd_args.ar_rgrplvb) { + if (!gfs2_rgrp_lvb_valid(rgd)){ + gfs2_consist_rgrpd(rgd); + error = -EIO; + goto fail; + } + if (rgd->rd_rgl->rl_unlinked == 0) + rgd->rd_flags &= ~GFS2_RDF_CHECK; + } return 0; fail: @@ -829,6 +901,39 @@ fail: return error; } +int update_rgrp_lvb(struct gfs2_rgrpd *rgd) +{ + u32 rl_flags; + + if (rgd->rd_flags & GFS2_RDF_UPTODATE) + return 0; + + if (be32_to_cpu(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) + return gfs2_rgrp_bh_get(rgd); + + rl_flags = be32_to_cpu(rgd->rd_rgl->rl_flags); + rl_flags &= ~GFS2_RDF_MASK; + rgd->rd_flags &= GFS2_RDF_MASK; + rgd->rd_flags |= (rl_flags | GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); + if (rgd->rd_rgl->rl_unlinked == 0) + rgd->rd_flags &= ~GFS2_RDF_CHECK; + rgd->rd_free = be32_to_cpu(rgd->rd_rgl->rl_free); + rgd->rd_free_clone = rgd->rd_free; + rgd->rd_dinodes = be32_to_cpu(rgd->rd_rgl->rl_dinodes); + rgd->rd_igeneration = be64_to_cpu(rgd->rd_rgl->rl_igeneration); + return 0; +} + +int gfs2_rgrp_go_lock(struct gfs2_holder *gh) +{ + struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; + struct gfs2_sbd *sdp = rgd->rd_sbd; + + if (gh->gh_flags & GL_SKIP && sdp->sd_args.ar_rgrplvb) + return 0; + return gfs2_rgrp_bh_get((struct gfs2_rgrpd *)gh->gh_gl->gl_object); +} + /** * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get() * @gh: The glock holder for the resource group @@ -842,8 +947,10 @@ void gfs2_rgrp_go_unlock(struct gfs2_holder *gh) for (x = 0; x < length; x++) { struct gfs2_bitmap *bi = rgd->rd_bits + x; - brelse(bi->bi_bh); - bi->bi_bh = NULL; + if (bi->bi_bh) { + brelse(bi->bi_bh); + bi->bi_bh = NULL; + } } } @@ -987,6 +1094,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) rgd->rd_flags |= GFS2_RGF_TRIMMED; gfs2_trans_add_bh(rgd->rd_gl, bh, 1); gfs2_rgrp_out(rgd, bh->b_data); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, bh->b_data); gfs2_trans_end(sdp); } } @@ -1116,6 +1224,9 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) int error, rg_locked, flags = LM_FLAG_TRY; int loops = 0; + if (sdp->sd_args.ar_rgrplvb) + flags |= GL_SKIP; + if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) rgd = begin = ip->i_rgd; else @@ -1133,22 +1244,34 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) } else { error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, &rs->rs_rgd_gh); + if (!error && sdp->sd_args.ar_rgrplvb) { + error = update_rgrp_lvb(rgd); + if (error) { + gfs2_glock_dq_uninit(&rs->rs_rgd_gh); + return error; + } + } } switch (error) { case 0: if (try_rgrp_fit(rgd, ip)) { + if (sdp->sd_args.ar_rgrplvb) + gfs2_rgrp_bh_get(rgd); ip->i_rgd = rgd; return 0; } - if (rgd->rd_flags & GFS2_RDF_CHECK) + if (rgd->rd_flags & GFS2_RDF_CHECK) { + if (sdp->sd_args.ar_rgrplvb) + gfs2_rgrp_bh_get(rgd); try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); + } if (!rg_locked) gfs2_glock_dq_uninit(&rs->rs_rgd_gh); /* fall through */ case GLR_TRYFAILED: rgd = gfs2_rgrpd_get_next(rgd); if (rgd == begin) { - flags = 0; + flags &= ~LM_FLAG_TRY; loops++; } break; @@ -1529,6 +1652,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); if (dinode) @@ -1575,6 +1699,7 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta) rgd->rd_flags &= ~GFS2_RGF_TRIMMED; gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); /* Directories keep their data in the metadata address space */ if (meta || ip->i_depth) @@ -1611,6 +1736,8 @@ void gfs2_unlink_di(struct inode *inode) trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED); gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); + update_rgrp_lvb_unlinked(rgd, 1); } static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) @@ -1630,6 +1757,8 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); + update_rgrp_lvb_unlinked(rgd, -1); gfs2_statfs_change(sdp, 0, +1, -1); } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 81fc76264ed4..788068758f3a 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -78,6 +78,8 @@ enum { Opt_quota_quantum, Opt_barrier, Opt_nobarrier, + Opt_rgrplvb, + Opt_norgrplvb, Opt_error, }; @@ -115,6 +117,8 @@ static const match_table_t tokens = { {Opt_quota_quantum, "quota_quantum=%d"}, {Opt_barrier, "barrier"}, {Opt_nobarrier, "nobarrier"}, + {Opt_rgrplvb, "rgrplvb"}, + {Opt_norgrplvb, "norgrplvb"}, {Opt_error, NULL} }; @@ -267,6 +271,12 @@ int gfs2_mount_args(struct gfs2_args *args, char *options) case Opt_nobarrier: args->ar_nobarrier = 1; break; + case Opt_rgrplvb: + args->ar_rgrplvb = 1; + break; + case Opt_norgrplvb: + args->ar_rgrplvb = 0; + break; case Opt_error: default: printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o); @@ -1379,6 +1389,8 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",nobarrier"); if (test_bit(SDF_DEMOTE, &sdp->sd_flags)) seq_printf(s, ",demote_interface_used"); + if (args->ar_rgrplvb) + seq_printf(s, ",rgrplvb"); return 0; } diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index e8ccf6ff3b4d..b2de1f9a88d6 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -170,6 +170,16 @@ struct gfs2_rindex { #define GFS2_RGF_NOALLOC 0x00000008 #define GFS2_RGF_TRIMMED 0x00000010 +struct gfs2_rgrp_lvb { + __be32 rl_magic; + __be32 rl_flags; + __be32 rl_free; + __be32 rl_dinodes; + __be64 rl_igeneration; + __be32 rl_unlinked; + __be32 __pad; +}; + struct gfs2_rgrp { struct gfs2_meta_header rg_header; -- GitLab From 934b9d1ed71cca5a220ec13e3f76d6aebf5183da Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 8 Jun 2012 14:24:53 -0400 Subject: [PATCH 0983/6849] wl18xx: avoid some -Wformat warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC drivers/net/wireless/ti/wl18xx/main.o drivers/net/wireless/ti/wl18xx/main.c: In function ‘wl18xx_conf_init’: drivers/net/wireless/ti/wl18xx/main.c:1024:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat] drivers/net/wireless/ti/wl18xx/main.c:1024:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t’ [-Wformat] Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl18xx/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b2ccff7d6188..ed9c3650e08a 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1022,7 +1022,8 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) if (fw->size != WL18XX_CONF_SIZE) { wl1271_error("configuration binary file size is wrong, " - "expected %d got %d", WL18XX_CONF_SIZE, fw->size); + "expected %ld got %zd", + WL18XX_CONF_SIZE, fw->size); ret = -EINVAL; goto out; } -- GitLab From c8a627ed06d6d49bf65015a2185c519335c4c83f Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 8 Jun 2012 01:20:41 +0000 Subject: [PATCH 0984/6849] inetpeer: add namespace support for inetpeer now inetpeer doesn't support namespace,the information will be leaking across namespace. this patch move the global vars v4_peers and v6_peers to netns_ipv4 and netns_ipv6 as a field peers. add struct pernet_operations inetpeer_ops to initial pernet inetpeer data. and change family_to_base and inet_getpeer to support namespace. Signed-off-by: Gao feng Signed-off-by: David S. Miller --- include/net/inetpeer.h | 10 +++--- include/net/netns/ipv4.h | 2 +- include/net/netns/ipv6.h | 1 + net/ipv4/inetpeer.c | 68 +++++++++++++++++++++++++++++----------- net/ipv4/route.c | 2 +- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 2040bff945d4..fef9dfab5d45 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -75,7 +75,9 @@ static inline bool inet_metrics_new(const struct inet_peer *p) } /* can be called with or without local BH being disabled */ -struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create); +struct inet_peer *inet_getpeer(struct net *net, + const struct inetpeer_addr *daddr, + int create); static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) { @@ -83,7 +85,7 @@ static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) daddr.addr.a4 = v4daddr; daddr.family = AF_INET; - return inet_getpeer(&daddr, create); + return inet_getpeer(&init_net, &daddr, create); } static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, int create) @@ -92,14 +94,14 @@ static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, *(struct in6_addr *)daddr.addr.a6 = *v6daddr; daddr.family = AF_INET6; - return inet_getpeer(&daddr, create); + return inet_getpeer(&init_net, &daddr, create); } /* can be called from BH context or outside */ extern void inet_putpeer(struct inet_peer *p); extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); -extern void inetpeer_invalidate_tree(int family); +extern void inetpeer_invalidate_tree(struct net *net, int family); /* * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index bbd023a1c9b9..227f0cd9d3f6 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -30,7 +30,7 @@ struct netns_ipv4 { struct sock **icmp_sk; struct sock *tcp_sock; - + struct inet_peer_base *peers; struct netns_frags frags; #ifdef CONFIG_NETFILTER struct xt_table *iptable_filter; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index b42be53587ba..df0a5456a3fd 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -33,6 +33,7 @@ struct netns_ipv6 { struct netns_sysctl_ipv6 sysctl; struct ipv6_devconf *devconf_all; struct ipv6_devconf *devconf_dflt; + struct inet_peer_base *peers; struct netns_frags frags; #ifdef CONFIG_NETFILTER struct xt_table *ip6table_filter; diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index dfba343b2509..1c8527349c86 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -88,18 +88,6 @@ struct inet_peer_base { int total; }; -static struct inet_peer_base v4_peers = { - .root = peer_avl_empty_rcu, - .lock = __SEQLOCK_UNLOCKED(v4_peers.lock), - .total = 0, -}; - -static struct inet_peer_base v6_peers = { - .root = peer_avl_empty_rcu, - .lock = __SEQLOCK_UNLOCKED(v6_peers.lock), - .total = 0, -}; - #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ /* Exported for sysctl_net_ipv4. */ @@ -153,6 +141,46 @@ static void inetpeer_gc_worker(struct work_struct *work) schedule_delayed_work(&gc_work, gc_delay); } +static int __net_init inetpeer_net_init(struct net *net) +{ + net->ipv4.peers = kzalloc(sizeof(struct inet_peer_base), + GFP_KERNEL); + if (net->ipv4.peers == NULL) + return -ENOMEM; + + net->ipv4.peers->root = peer_avl_empty_rcu; + seqlock_init(&net->ipv4.peers->lock); + + net->ipv6.peers = kzalloc(sizeof(struct inet_peer_base), + GFP_KERNEL); + if (net->ipv6.peers == NULL) + goto out_ipv6; + + net->ipv6.peers->root = peer_avl_empty_rcu; + seqlock_init(&net->ipv6.peers->lock); + + return 0; +out_ipv6: + kfree(net->ipv4.peers); + return -ENOMEM; +} + +static void __net_exit inetpeer_net_exit(struct net *net) +{ + inetpeer_invalidate_tree(net, AF_INET); + kfree(net->ipv4.peers); + net->ipv4.peers = NULL; + + inetpeer_invalidate_tree(net, AF_INET6); + kfree(net->ipv6.peers); + net->ipv6.peers = NULL; +} + +static struct pernet_operations inetpeer_ops = { + .init = inetpeer_net_init, + .exit = inetpeer_net_exit, +}; + /* Called from ip_output.c:ip_init */ void __init inet_initpeers(void) { @@ -177,6 +205,7 @@ void __init inet_initpeers(void) NULL); INIT_DELAYED_WORK_DEFERRABLE(&gc_work, inetpeer_gc_worker); + register_pernet_subsys(&inetpeer_ops); } static int addr_compare(const struct inetpeer_addr *a, @@ -401,9 +430,10 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base, call_rcu(&p->rcu, inetpeer_free_rcu); } -static struct inet_peer_base *family_to_base(int family) +static struct inet_peer_base *family_to_base(struct net *net, + int family) { - return family == AF_INET ? &v4_peers : &v6_peers; + return family == AF_INET ? net->ipv4.peers : net->ipv6.peers; } /* perform garbage collect on all items stacked during a lookup */ @@ -443,10 +473,12 @@ static int inet_peer_gc(struct inet_peer_base *base, return cnt; } -struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create) +struct inet_peer *inet_getpeer(struct net *net, + const struct inetpeer_addr *daddr, + int create) { struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; - struct inet_peer_base *base = family_to_base(daddr->family); + struct inet_peer_base *base = family_to_base(net, daddr->family); struct inet_peer *p; unsigned int sequence; int invalidated, gccnt = 0; @@ -571,10 +603,10 @@ static void inetpeer_inval_rcu(struct rcu_head *head) schedule_delayed_work(&gc_work, gc_delay); } -void inetpeer_invalidate_tree(int family) +void inetpeer_invalidate_tree(struct net *net, int family) { struct inet_peer *old, *new, *prev; - struct inet_peer_base *base = family_to_base(family); + struct inet_peer_base *base = family_to_base(net, family); write_seqlock_bh(&base->lock); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 98b30d08efe9..006c21cc2324 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -938,7 +938,7 @@ static void rt_cache_invalidate(struct net *net) get_random_bytes(&shuffle, sizeof(shuffle)); atomic_add(shuffle + 1U, &net->ipv4.rt_genid); - inetpeer_invalidate_tree(AF_INET); + inetpeer_invalidate_tree(net, AF_INET); } /* -- GitLab From 54db0cc2ba0d38166acc2d6bae21721405305537 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 8 Jun 2012 01:21:40 +0000 Subject: [PATCH 0985/6849] inetpeer: add parameter net for inet_getpeer_v4,v6 add struct net as a parameter of inet_getpeer_v[4,6], use net to replace &init_net. and modify some places to provide net for inet_getpeer_v[4,6] Signed-off-by: Gao feng Signed-off-by: David S. Miller --- include/net/inetpeer.h | 12 ++++++++---- net/ipv4/inet_fragment.c | 2 +- net/ipv4/ip_fragment.c | 6 +++++- net/ipv4/route.c | 8 +++++--- net/ipv4/tcp_ipv4.c | 6 ++++-- net/ipv6/route.c | 3 ++- net/ipv6/tcp_ipv6.c | 6 ++++-- 7 files changed, 29 insertions(+), 14 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index fef9dfab5d45..20e67db69ac9 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -79,22 +79,26 @@ struct inet_peer *inet_getpeer(struct net *net, const struct inetpeer_addr *daddr, int create); -static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) +static inline struct inet_peer *inet_getpeer_v4(struct net *net, + __be32 v4daddr, + int create) { struct inetpeer_addr daddr; daddr.addr.a4 = v4daddr; daddr.family = AF_INET; - return inet_getpeer(&init_net, &daddr, create); + return inet_getpeer(net, &daddr, create); } -static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, int create) +static inline struct inet_peer *inet_getpeer_v6(struct net *net, + const struct in6_addr *v6daddr, + int create) { struct inetpeer_addr daddr; *(struct in6_addr *)daddr.addr.a6 = *v6daddr; daddr.family = AF_INET6; - return inet_getpeer(&init_net, &daddr, create); + return inet_getpeer(net, &daddr, create); } /* can be called from BH context or outside */ diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 5ff2a51b6d0c..85190e69297b 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -243,12 +243,12 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, if (q == NULL) return NULL; + q->net = nf; f->constructor(q, arg); atomic_add(f->qsize, &nf->mem); setup_timer(&q->timer, f->frag_expire, (unsigned long)q); spin_lock_init(&q->lock); atomic_set(&q->refcnt, 1); - q->net = nf; return q; } diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 9dbd3dd6022d..22c6bab9717a 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -171,6 +171,10 @@ static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb) static void ip4_frag_init(struct inet_frag_queue *q, void *a) { struct ipq *qp = container_of(q, struct ipq, q); + struct netns_ipv4 *ipv4 = container_of(q->net, struct netns_ipv4, + frags); + struct net *net = container_of(ipv4, struct net, ipv4); + struct ip4_create_arg *arg = a; qp->protocol = arg->iph->protocol; @@ -180,7 +184,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a) qp->daddr = arg->iph->daddr; qp->user = arg->user; qp->peer = sysctl_ipfrag_max_dist ? - inet_getpeer_v4(arg->iph->saddr, 1) : NULL; + inet_getpeer_v4(net, arg->iph->saddr, 1) : NULL; } static __inline__ void ip4_frag_free(struct inet_frag_queue *q) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 006c21cc2324..2c9f73f3b7cc 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1328,9 +1328,10 @@ static u32 rt_peer_genid(void) void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) { + struct net *net = dev_net(rt->dst.dev); struct inet_peer *peer; - peer = inet_getpeer_v4(daddr, create); + peer = inet_getpeer_v4(net, daddr, create); if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) inet_putpeer(peer); @@ -1694,7 +1695,7 @@ unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, unsigned short est_mtu = 0; struct inet_peer *peer; - peer = inet_getpeer_v4(iph->daddr, 1); + peer = inet_getpeer_v4(net, iph->daddr, 1); if (peer) { unsigned short mtu = new_mtu; @@ -1935,6 +1936,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, struct fib_info *fi) { + struct net *net = dev_net(rt->dst.dev); struct inet_peer *peer; int create = 0; @@ -1944,7 +1946,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS)) create = 1; - rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create); + rt->peer = peer = inet_getpeer_v4(net, rt->rt_dst, create); if (peer) { rt->rt_peer_genid = rt_peer_genid(); if (inet_metrics_new(peer)) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3d9c1a4b8819..f485b451f928 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1824,11 +1824,12 @@ struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it) { struct rtable *rt = (struct rtable *) __sk_dst_get(sk); struct inet_sock *inet = inet_sk(sk); + struct net *net = sock_net(sk); struct inet_peer *peer; if (!rt || inet->cork.fl.u.ip4.daddr != inet->inet_daddr) { - peer = inet_getpeer_v4(inet->inet_daddr, 1); + peer = inet_getpeer_v4(net, inet->inet_daddr, 1); *release_it = true; } else { if (!rt->peer) @@ -1844,8 +1845,9 @@ EXPORT_SYMBOL(tcp_v4_get_peer); void *tcp_v4_tw_get_peer(struct sock *sk) { const struct inet_timewait_sock *tw = inet_twsk(sk); + struct net *net = sock_net(sk); - return inet_getpeer_v4(tw->tw_daddr, 1); + return inet_getpeer_v4(net, tw->tw_daddr, 1); } EXPORT_SYMBOL(tcp_v4_tw_get_peer); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 999a982ad3fd..4eca0130cce7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -306,9 +306,10 @@ static u32 rt6_peer_genid(void) void rt6_bind_peer(struct rt6_info *rt, int create) { + struct net *net = dev_net(rt->dst.dev); struct inet_peer *peer; - peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); + peer = inet_getpeer_v6(net, &rt->rt6i_dst.addr, create); if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) inet_putpeer(peer); else diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 80758255556c..1a9cdd09f11c 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1736,11 +1736,12 @@ static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) { struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk); struct ipv6_pinfo *np = inet6_sk(sk); + struct net *net = sock_net(sk); struct inet_peer *peer; if (!rt || !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) { - peer = inet_getpeer_v6(&np->daddr, 1); + peer = inet_getpeer_v6(net, &np->daddr, 1); *release_it = true; } else { if (!rt->rt6i_peer) @@ -1756,11 +1757,12 @@ static void *tcp_v6_tw_get_peer(struct sock *sk) { const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); const struct inet_timewait_sock *tw = inet_twsk(sk); + struct net *net = sock_net(sk); if (tw->tw_family == AF_INET) return tcp_v4_tw_get_peer(sk); - return inet_getpeer_v6(&tw6->tw_v6_daddr, 1); + return inet_getpeer_v6(net, &tw6->tw_v6_daddr, 1); } static struct timewait_sock_ops tcp6_timewait_sock_ops = { -- GitLab From 7123aaa3a1416529ce461e98108e6b343b294643 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 8 Jun 2012 05:03:21 +0000 Subject: [PATCH 0986/6849] af_unix: speedup /proc/net/unix /proc/net/unix has quadratic behavior, and can hold unix_table_lock for a while if high number of unix sockets are alive. (90 ms for 200k sockets...) We already have a hash table, so its quite easy to use it. Problem is unbound sockets are still hashed in a single hash slot (unix_socket_table[UNIX_HASH_TABLE]) This patch also spreads unbound sockets to 256 hash slots, to speedup both /proc/net/unix and unix_diag. Time to read /proc/net/unix with 200k unix sockets : (time dd if=/proc/net/unix of=/dev/null bs=4k) before : 520 secs after : 2 secs Signed-off-by: Eric Dumazet Cc: Steven Whitehouse Cc: Pavel Emelyanov Signed-off-by: David S. Miller --- include/net/af_unix.h | 3 +- net/unix/af_unix.c | 110 ++++++++++++++++++++++++------------------ net/unix/diag.c | 6 ++- 3 files changed, 70 insertions(+), 49 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 2ee33da36a7a..b5f8988e4283 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -14,10 +14,11 @@ extern struct sock *unix_get_socket(struct file *filp); extern struct sock *unix_peer_get(struct sock *); #define UNIX_HASH_SIZE 256 +#define UNIX_HASH_BITS 8 extern unsigned int unix_tot_inflight; extern spinlock_t unix_table_lock; -extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; +extern struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE]; struct unix_address { atomic_t refcnt; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 641f2e47f165..cf83f6b5ac91 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -115,15 +115,24 @@ #include #include -struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; +struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE]; EXPORT_SYMBOL_GPL(unix_socket_table); DEFINE_SPINLOCK(unix_table_lock); EXPORT_SYMBOL_GPL(unix_table_lock); static atomic_long_t unix_nr_socks; -#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) -#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) +static struct hlist_head *unix_sockets_unbound(void *addr) +{ + unsigned long hash = (unsigned long)addr; + + hash ^= hash >> 16; + hash ^= hash >> 8; + hash %= UNIX_HASH_SIZE; + return &unix_socket_table[UNIX_HASH_SIZE + hash]; +} + +#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash < UNIX_HASH_SIZE) #ifdef CONFIG_SECURITY_NETWORK static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) @@ -645,7 +654,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock) INIT_LIST_HEAD(&u->link); mutex_init(&u->readlock); /* single task reading lock */ init_waitqueue_head(&u->peer_wait); - unix_insert_socket(unix_sockets_unbound, sk); + unix_insert_socket(unix_sockets_unbound(sk), sk); out: if (sk == NULL) atomic_long_dec(&unix_nr_socks); @@ -2239,47 +2248,58 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, } #ifdef CONFIG_PROC_FS -static struct sock *first_unix_socket(int *i) -{ - for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) { - if (!hlist_empty(&unix_socket_table[*i])) - return __sk_head(&unix_socket_table[*i]); - } - return NULL; -} -static struct sock *next_unix_socket(int *i, struct sock *s) -{ - struct sock *next = sk_next(s); - /* More in this chain? */ - if (next) - return next; - /* Look for next non-empty chain. */ - for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { - if (!hlist_empty(&unix_socket_table[*i])) - return __sk_head(&unix_socket_table[*i]); - } - return NULL; -} +#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1) + +#define get_bucket(x) ((x) >> BUCKET_SPACE) +#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1)) +#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o)) struct unix_iter_state { struct seq_net_private p; - int i; }; -static struct sock *unix_seq_idx(struct seq_file *seq, loff_t pos) +static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos) { - struct unix_iter_state *iter = seq->private; - loff_t off = 0; - struct sock *s; + unsigned long offset = get_offset(*pos); + unsigned long bucket = get_bucket(*pos); + struct sock *sk; + unsigned long count = 0; - for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) { - if (sock_net(s) != seq_file_net(seq)) + for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) { + if (sock_net(sk) != seq_file_net(seq)) continue; - if (off == pos) - return s; - ++off; + if (++count == offset) + break; } + + return sk; +} + +static struct sock *unix_next_socket(struct seq_file *seq, + struct sock *sk, + loff_t *pos) +{ + unsigned long bucket; + + while (sk > (struct sock *)SEQ_START_TOKEN) { + sk = sk_next(sk); + if (!sk) + goto next_bucket; + if (sock_net(sk) == seq_file_net(seq)) + return sk; + } + + do { + sk = unix_from_bucket(seq, pos); + if (sk) + return sk; + +next_bucket: + bucket = get_bucket(*pos) + 1; + *pos = set_bucket_offset(bucket, 1); + } while (bucket < ARRAY_SIZE(unix_socket_table)); + return NULL; } @@ -2287,22 +2307,20 @@ static void *unix_seq_start(struct seq_file *seq, loff_t *pos) __acquires(unix_table_lock) { spin_lock(&unix_table_lock); - return *pos ? unix_seq_idx(seq, *pos - 1) : SEQ_START_TOKEN; + + if (!*pos) + return SEQ_START_TOKEN; + + if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table)) + return NULL; + + return unix_next_socket(seq, NULL, pos); } static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct unix_iter_state *iter = seq->private; - struct sock *sk = v; ++*pos; - - if (v == SEQ_START_TOKEN) - sk = first_unix_socket(&iter->i); - else - sk = next_unix_socket(&iter->i, sk); - while (sk && (sock_net(sk) != seq_file_net(seq))) - sk = next_unix_socket(&iter->i, sk); - return sk; + return unix_next_socket(seq, v, pos); } static void unix_seq_stop(struct seq_file *seq, void *v) diff --git a/net/unix/diag.c b/net/unix/diag.c index 47d3002737f5..7e8a24bff34a 100644 --- a/net/unix/diag.c +++ b/net/unix/diag.c @@ -195,7 +195,9 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) num = s_num = cb->args[1]; spin_lock(&unix_table_lock); - for (slot = s_slot; slot <= UNIX_HASH_SIZE; s_num = 0, slot++) { + for (slot = s_slot; + slot < ARRAY_SIZE(unix_socket_table); + s_num = 0, slot++) { struct sock *sk; struct hlist_node *node; @@ -228,7 +230,7 @@ static struct sock *unix_lookup_by_ino(int ino) struct sock *sk; spin_lock(&unix_table_lock); - for (i = 0; i <= UNIX_HASH_SIZE; i++) { + for (i = 0; i < ARRAY_SIZE(unix_socket_table); i++) { struct hlist_node *node; sk_for_each(sk, node, &unix_socket_table[i]) -- GitLab From c7d65a78fc18ed70353baeb7497ec71a7c775ac5 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 7 Jun 2012 11:03:00 -0400 Subject: [PATCH 0987/6849] x86: Remove cmpxchg from i386 NMI nesting code I've been informed by someone on LWN called 'slashdot' that some i386 machines do not support a true cmpxchg. The cmpxchg used by the i386 NMI nesting code must be a true cmpxchg as disabling interrupts will not work for NMIs (which is the work around for i386s that do not have a true cmpxchg). This 'slashdot' character also suggested a fix to the issue. As the state of the nesting NMIs goes as follows: NOT_RUNNING -> EXECUTING EXECUTING -> NOT_RUNNING EXECUTING -> LATCHED LATCHED -> EXECUTING Having these states as enum values of: NOT_RUNNING = 0 EXECUTING = 1 LATCHED = 2 Instead of a cmpxchg to make EXECUTING -> NOT_RUNNING a dec_and_test() would work as well. If the dec_and_test brings the state to NOT_RUNNING, that is the same as a cmpxchg succeeding to change EXECUTING to NOT_RUNNING. If a nested NMI were to come in and change it to LATCHED, the dec_and_test() would convert the state to EXECUTING (what we want it to be in such a case anyway). I asked 'slashdot' to post this as a patch, but it never came to be. I decided to do the work instead. Thanks to H. Peter Anvin for suggesting to use this_cpu_dec_and_return() instead of local_dec_and_test(&__get_cpu_var()). Link: http://lwn.net/Articles/484932/ Cc: H. Peter Anvin Signed-off-by: Steven Rostedt --- arch/x86/kernel/nmi.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index a0b2f84457be..a15a88800661 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -365,8 +365,9 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) #ifdef CONFIG_X86_32 /* * For i386, NMIs use the same stack as the kernel, and we can - * add a workaround to the iret problem in C. Simply have 3 states - * the NMI can be in. + * add a workaround to the iret problem in C (preventing nested + * NMIs if an NMI takes a trap). Simply have 3 states the NMI + * can be in: * * 1) not running * 2) executing @@ -383,13 +384,20 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) * If an NMI hits a breakpoint that executes an iret, another * NMI can preempt it. We do not want to allow this new NMI * to run, but we want to execute it when the first one finishes. - * We set the state to "latched", and the first NMI will perform - * an cmpxchg on the state, and if it doesn't successfully - * reset the state to "not running" it will restart the next - * NMI. + * We set the state to "latched", and the exit of the first NMI will + * perform a dec_return, if the result is zero (NOT_RUNNING), then + * it will simply exit the NMI handler. If not, the dec_return + * would have set the state to NMI_EXECUTING (what we want it to + * be when we are running). In this case, we simply jump back + * to rerun the NMI handler again, and restart the 'latched' NMI. + * + * No trap (breakpoint or page fault) should be hit before nmi_restart, + * thus there is no race between the first check of state for NOT_RUNNING + * and setting it to NMI_EXECUTING. The HW will prevent nested NMIs + * at this point. */ enum nmi_states { - NMI_NOT_RUNNING, + NMI_NOT_RUNNING = 0, NMI_EXECUTING, NMI_LATCHED, }; @@ -397,18 +405,17 @@ static DEFINE_PER_CPU(enum nmi_states, nmi_state); #define nmi_nesting_preprocess(regs) \ do { \ - if (__get_cpu_var(nmi_state) != NMI_NOT_RUNNING) { \ - __get_cpu_var(nmi_state) = NMI_LATCHED; \ + if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) { \ + this_cpu_write(nmi_state, NMI_LATCHED); \ return; \ } \ - nmi_restart: \ - __get_cpu_var(nmi_state) = NMI_EXECUTING; \ - } while (0) + this_cpu_write(nmi_state, NMI_EXECUTING); \ + } while (0); \ + nmi_restart: #define nmi_nesting_postprocess() \ do { \ - if (cmpxchg(&__get_cpu_var(nmi_state), \ - NMI_EXECUTING, NMI_NOT_RUNNING) != NMI_EXECUTING) \ + if (this_cpu_dec_return(nmi_state)) \ goto nmi_restart; \ } while (0) #else /* x86_64 */ -- GitLab From 70fb74a5420f9caa3e001d65004e4b669124283e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 7 Jun 2012 11:54:37 -0400 Subject: [PATCH 0988/6849] x86: Save cr2 in NMI in case NMIs take a page fault (for i386) Avi Kivity reported that page faults in NMIs could cause havic if the NMI preempted another page fault handler: The recent changes to NMI allow exceptions to take place in NMI handlers, but I think that a #PF (say, due to access to vmalloc space) is still problematic. Consider the sequence #PF (cr2 set by processor) NMI ... #PF (cr2 clobbered) do_page_fault() IRET ... IRET do_page_fault() address = read_cr2() The last line reads the overwritten cr2 value. This is the i386 version, which has the luxury of doing the work in C code. Link: http://lkml.kernel.org/r/4FBB8C40.6080304@redhat.com Reported-by: Avi Kivity Cc: Linus Torvalds Cc: H. Peter Anvin Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- arch/x86/kernel/nmi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index a15a88800661..f84f5c57de35 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -395,6 +395,14 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) * thus there is no race between the first check of state for NOT_RUNNING * and setting it to NMI_EXECUTING. The HW will prevent nested NMIs * at this point. + * + * In case the NMI takes a page fault, we need to save off the CR2 + * because the NMI could have preempted another page fault and corrupt + * the CR2 that is about to be read. As nested NMIs must be restarted + * and they can not take breakpoints or page faults, the update of the + * CR2 must be done before converting the nmi state back to NOT_RUNNING. + * Otherwise, there would be a race of another nested NMI coming in + * after setting state to NOT_RUNNING but before updating the nmi_cr2. */ enum nmi_states { NMI_NOT_RUNNING = 0, @@ -402,6 +410,7 @@ enum nmi_states { NMI_LATCHED, }; static DEFINE_PER_CPU(enum nmi_states, nmi_state); +static DEFINE_PER_CPU(unsigned long, nmi_cr2); #define nmi_nesting_preprocess(regs) \ do { \ @@ -410,11 +419,14 @@ static DEFINE_PER_CPU(enum nmi_states, nmi_state); return; \ } \ this_cpu_write(nmi_state, NMI_EXECUTING); \ + this_cpu_write(nmi_cr2, read_cr2()); \ } while (0); \ nmi_restart: #define nmi_nesting_postprocess() \ do { \ + if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) \ + write_cr2(this_cpu_read(nmi_cr2)); \ if (this_cpu_dec_return(nmi_state)) \ goto nmi_restart; \ } while (0) -- GitLab From 1c2e004183178e1947882cd2e74f37826f45230e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Jun 2012 23:31:13 +0800 Subject: [PATCH 0989/6849] Bluetooth: Add support for encryption key refresh With LE/SMP the completion of a security level elavation from medium to high is indicated by a HCI Encryption Key Refresh Complete event. The necessary behavior upon receiving this event is a mix of what's done for auth_complete and encryption_change, which is also where most of the event handling code has been copied from. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 6 +++++ net/bluetooth/hci_event.c | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 66a7b579e31c..3def64ba77fa 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1144,6 +1144,12 @@ struct extended_inquiry_info { __u8 data[240]; } __packed; +#define HCI_EV_KEY_REFRESH_COMPLETE 0x30 +struct hci_ev_key_refresh_complete { + __u8 status; + __le16 handle; +} __packed; + #define HCI_EV_IO_CAPA_REQUEST 0x31 struct hci_ev_io_capa_request { bdaddr_t bdaddr; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4eefb7f65cf6..94ad124a4ea3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3043,6 +3043,50 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct hci_dev_unlock(hdev); } +static void hci_key_refresh_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_ev_key_refresh_complete *ev = (void *) skb->data; + struct hci_conn *conn; + + BT_DBG("%s status %u handle %u", hdev->name, ev->status, + __le16_to_cpu(ev->handle)); + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); + if (!conn) + goto unlock; + + if (!ev->status) + conn->sec_level = conn->pending_sec_level; + + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); + + if (ev->status && conn->state == BT_CONNECTED) { + hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE); + hci_conn_put(conn); + goto unlock; + } + + if (conn->state == BT_CONFIG) { + if (!ev->status) + conn->state = BT_CONNECTED; + + hci_proto_connect_cfm(conn, ev->status); + hci_conn_put(conn); + } else { + hci_auth_cfm(conn, ev->status); + + hci_conn_hold(conn); + conn->disc_timeout = HCI_DISCONN_TIMEOUT; + hci_conn_put(conn); + } + +unlock: + hci_dev_unlock(hdev); +} + static inline u8 hci_get_auth_req(struct hci_conn *conn) { /* If remote requests dedicated bonding follow that lead */ @@ -3559,6 +3603,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_extended_inquiry_result_evt(hdev, skb); break; + case HCI_EV_KEY_REFRESH_COMPLETE: + hci_key_refresh_complete_evt(hdev, skb); + break; + case HCI_EV_IO_CAPA_REQUEST: hci_io_capa_request_evt(hdev, skb); break; -- GitLab From 7d116684945459e98538c797dca37c54ddd89906 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 10:21:16 +0800 Subject: [PATCH 0990/6849] ASoC: wm8903: Convert to devm_regmap_init_i2c() Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 304b5cff3482..3abd450842ee 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -2124,7 +2124,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, return -ENOMEM; wm8903->dev = &i2c->dev; - wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); + wm8903->regmap = devm_regmap_init_i2c(i2c, &wm8903_regmap); if (IS_ERR(wm8903->regmap)) { ret = PTR_ERR(wm8903->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", @@ -2191,7 +2191,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, return 0; err: - regmap_exit(wm8903->regmap); return ret; } @@ -2200,7 +2199,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client) struct wm8903_priv *wm8903 = i2c_get_clientdata(client); wm8903_free_gpio(wm8903); - regmap_exit(wm8903->regmap); snd_soc_unregister_codec(&client->dev); return 0; -- GitLab From 8cb28fd6d1e98fe4cf232d7803093a3b7b46e969 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:57:50 +0800 Subject: [PATCH 0991/6849] ASoC: wm8904: Convert to module_i2c_driver() Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index db94d10b5c1a..02bc2caac83a 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2313,23 +2313,7 @@ static struct i2c_driver wm8904_i2c_driver = { .id_table = wm8904_i2c_id, }; -static int __init wm8904_modinit(void) -{ - int ret = 0; - ret = i2c_add_driver(&wm8904_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", - ret); - } - return ret; -} -module_init(wm8904_modinit); - -static void __exit wm8904_exit(void) -{ - i2c_del_driver(&wm8904_i2c_driver); -} -module_exit(wm8904_exit); +module_i2c_driver(wm8904_i2c_driver); MODULE_DESCRIPTION("ASoC WM8904 driver"); MODULE_AUTHOR("Mark Brown "); -- GitLab From d633edd95dc938f3f5f0d4e431932f4ca042bffb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:26:01 +0800 Subject: [PATCH 0992/6849] ASoC: wm8904: Convert to devm_regmap_init_i2c() Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 02bc2caac83a..560a9a47596b 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2263,7 +2263,7 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, if (wm8904 == NULL) return -ENOMEM; - wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap); + wm8904->regmap = devm_regmap_init_i2c(i2c, &wm8904_regmap); if (IS_ERR(wm8904->regmap)) { ret = PTR_ERR(wm8904->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", @@ -2283,15 +2283,12 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, return 0; err: - regmap_exit(wm8904->regmap); return ret; } static __devexit int wm8904_i2c_remove(struct i2c_client *client) { - struct wm8904_priv *wm8904 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); - regmap_exit(wm8904->regmap); return 0; } -- GitLab From fbfe95a42e90b3dd079cc9019ba7d7700feee0f6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 8 Jun 2012 23:24:18 -0700 Subject: [PATCH 0993/6849] inet: Create and use rt{,6}_get_peer_create(). There's a lot of places that open-code rt{,6}_get_peer() only because they want to set 'create' to one. So add an rt{,6}_get_peer_create() for their sake. There were also a few spots open-coding plain rt{,6}_get_peer() and those are transformed here as well. Signed-off-by: David S. Miller --- include/net/ip6_route.h | 17 +++++++++++++---- include/net/route.h | 14 ++++++++++++-- net/ipv4/icmp.c | 5 ++--- net/ipv4/route.c | 35 +++++++++-------------------------- net/ipv4/tcp_ipv4.c | 4 +--- net/ipv6/icmp.c | 6 +++--- net/ipv6/ip6_output.c | 11 ++++------- net/ipv6/ndisc.c | 6 +++--- net/ipv6/route.c | 5 +---- net/ipv6/tcp_ipv6.c | 4 +--- 10 files changed, 49 insertions(+), 58 deletions(-) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 37c1a1ed82c1..73d750288121 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -53,18 +53,27 @@ static inline unsigned int rt6_flags2srcprefs(int flags) return (flags >> 3) & 7; } -extern void rt6_bind_peer(struct rt6_info *rt, - int create); +extern void rt6_bind_peer(struct rt6_info *rt, int create); -static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt) +static inline struct inet_peer *__rt6_get_peer(struct rt6_info *rt, int create) { if (rt->rt6i_peer) return rt->rt6i_peer; - rt6_bind_peer(rt, 0); + rt6_bind_peer(rt, create); return rt->rt6i_peer; } +static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt) +{ + return __rt6_get_peer(rt, 0); +} + +static inline struct inet_peer *rt6_get_peer_create(struct rt6_info *rt) +{ + return __rt6_get_peer(rt, 1); +} + extern void ip6_route_input(struct sk_buff *skb); extern struct dst_entry * ip6_route_output(struct net *net, diff --git a/include/net/route.h b/include/net/route.h index ed2b78e2375d..433fc6c1d404 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -296,15 +296,25 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create); -static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) +static inline struct inet_peer *__rt_get_peer(struct rtable *rt, __be32 daddr, int create) { if (rt->peer) return rt->peer; - rt_bind_peer(rt, daddr, 0); + rt_bind_peer(rt, daddr, create); return rt->peer; } +static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) +{ + return __rt_get_peer(rt, daddr, 0); +} + +static inline struct inet_peer *rt_get_peer_create(struct rtable *rt, __be32 daddr) +{ + return __rt_get_peer(rt, daddr, 1); +} + static inline int inet_iif(const struct sk_buff *skb) { return skb_rtable(skb)->rt_iif; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c75efbdc71cb..0c78ef1e5dde 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -253,9 +253,8 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, /* Limit if icmp type is enabled in ratemask. */ if ((1 << type) & net->ipv4.sysctl_icmp_ratemask) { - if (!rt->peer) - rt_bind_peer(rt, fl4->daddr, 1); - rc = inet_peer_xrlim_allow(rt->peer, + struct inet_peer *peer = rt_get_peer_create(rt, fl4->daddr); + rc = inet_peer_xrlim_allow(peer, net->ipv4.sysctl_icmp_ratelimit); } out: diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 2c9f73f3b7cc..7a4d724765e6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -162,10 +162,7 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old) struct inet_peer *peer; u32 *p = NULL; - if (!rt->peer) - rt_bind_peer(rt, rt->rt_dst, 1); - - peer = rt->peer; + peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { u32 *old_p = __DST_METRICS_PTR(old); unsigned long prev, new; @@ -1364,14 +1361,13 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) struct rtable *rt = (struct rtable *) dst; if (rt && !(rt->dst.flags & DST_NOPEER)) { - if (rt->peer == NULL) - rt_bind_peer(rt, rt->rt_dst, 1); + struct inet_peer *peer = rt_get_peer_create(rt, rt->rt_dst); /* If peer is attached to destination, it is never detached, so that we need not to grab a lock to dereference it. */ - if (rt->peer) { - iph->id = htons(inet_getid(rt->peer, more)); + if (peer) { + iph->id = htons(inet_getid(peer, more)); return; } } else if (!rt) @@ -1481,10 +1477,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rt->rt_gateway != old_gw) continue; - if (!rt->peer) - rt_bind_peer(rt, rt->rt_dst, 1); - - peer = rt->peer; + peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { if (peer->redirect_learned.a4 != new_gw) { peer->redirect_learned.a4 = new_gw; @@ -1579,9 +1572,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) log_martians = IN_DEV_LOG_MARTIANS(in_dev); rcu_read_unlock(); - if (!rt->peer) - rt_bind_peer(rt, rt->rt_dst, 1); - peer = rt->peer; + peer = rt_get_peer_create(rt, rt->rt_dst); if (!peer) { icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); return; @@ -1646,9 +1637,7 @@ static int ip_error(struct sk_buff *skb) break; } - if (!rt->peer) - rt_bind_peer(rt, rt->rt_dst, 1); - peer = rt->peer; + peer = rt_get_peer_create(rt, rt->rt_dst); send = true; if (peer) { @@ -1754,9 +1743,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) dst_confirm(dst); - if (!rt->peer) - rt_bind_peer(rt, rt->rt_dst, 1); - peer = rt->peer; + peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires); @@ -1782,12 +1769,8 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) static void ipv4_validate_peer(struct rtable *rt) { if (rt->rt_peer_genid != rt_peer_genid()) { - struct inet_peer *peer; - - if (!rt->peer) - rt_bind_peer(rt, rt->rt_dst, 0); + struct inet_peer *peer = rt_get_peer(rt, rt->rt_dst); - peer = rt->peer; if (peer) { check_peer_pmtu(&rt->dst, peer); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index f485b451f928..833e8d96a636 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1832,9 +1832,7 @@ struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it) peer = inet_getpeer_v4(net, inet->inet_daddr, 1); *release_it = true; } else { - if (!rt->peer) - rt_bind_peer(rt, inet->inet_daddr, 1); - peer = rt->peer; + peer = rt_get_peer_create(rt, inet->inet_daddr); *release_it = false; } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 091a2971c7b7..ed89bba745a1 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -188,14 +188,14 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, } else { struct rt6_info *rt = (struct rt6_info *)dst; int tmo = net->ipv6.sysctl.icmpv6_time; + struct inet_peer *peer; /* Give more bandwidth to wider prefixes. */ if (rt->rt6i_dst.plen < 128) tmo >>= ((128 - rt->rt6i_dst.plen)>>5); - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); - res = inet_peer_xrlim_allow(rt->rt6i_peer, tmo); + peer = rt6_get_peer_create(rt); + res = inet_peer_xrlim_allow(peer, tmo); } dst_release(dst); return res; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 17b8c67998bb..62fcf3e48aca 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -463,6 +463,7 @@ int ip6_forward(struct sk_buff *skb) */ if (skb->dev == dst->dev && opt->srcrt == 0 && !skb_sec_path(skb)) { struct in6_addr *target = NULL; + struct inet_peer *peer; struct rt6_info *rt; /* @@ -476,13 +477,12 @@ int ip6_forward(struct sk_buff *skb) else target = &hdr->daddr; - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); + peer = rt6_get_peer_create(rt); /* Limit redirects both by destination (here) and by source (inside ndisc_send_redirect) */ - if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ)) + if (inet_peer_xrlim_allow(peer, 1*HZ)) ndisc_send_redirect(skb, target); } else { int addrtype = ipv6_addr_type(&hdr->saddr); @@ -602,11 +602,8 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) int old, new; if (rt && !(rt->dst.flags & DST_NOPEER)) { - struct inet_peer *peer; + struct inet_peer *peer = rt6_get_peer_create(rt); - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); - peer = rt->rt6i_peer; if (peer) { fhdr->identification = htonl(inet_getid(peer, 0)); return; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 54f62d3b8dd6..69a6330dea91 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1472,6 +1472,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) struct net *net = dev_net(dev); struct sock *sk = net->ipv6.ndisc_sk; int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr); + struct inet_peer *peer; struct sk_buff *buff; struct icmp6hdr *icmph; struct in6_addr saddr_buf; @@ -1518,9 +1519,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) "Redirect: destination is not a neighbour\n"); goto release; } - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); - if (!inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ)) + peer = rt6_get_peer_create(rt); + if (!inet_peer_xrlim_allow(peer, 1*HZ)) goto release; if (dev->addr_len) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4eca0130cce7..8a986be4aeda 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -99,10 +99,7 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old) if (!(rt->dst.flags & DST_HOST)) return NULL; - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); - - peer = rt->rt6i_peer; + peer = rt6_get_peer_create(rt); if (peer) { u32 *old_p = __DST_METRICS_PTR(old); unsigned long prev, new; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 1a9cdd09f11c..218433cb9928 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1744,9 +1744,7 @@ static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) peer = inet_getpeer_v6(net, &np->daddr, 1); *release_it = true; } else { - if (!rt->rt6i_peer) - rt6_bind_peer(rt, 1); - peer = rt->rt6i_peer; + peer = rt6_get_peer_create(rt); *release_it = false; } -- GitLab From 4670fd819e7f47392c7c6fc6168ea2857c66d163 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 01:25:47 -0700 Subject: [PATCH 0994/6849] tcp: Get rid of inetpeer special cases. The get_peer method TCP uses is full of special cases that make no sense accommodating, and it also gets in the way of doing more reasonable things here. First of all, if the socket doesn't have a usable cached route, there is no sense in trying to optimize timewait recycling. Likewise for the case where we have IP options, such as SRR enabled, that make the IP header destination address (and thus the destination address of the route key) differ from that of the connection's destination address. Just return a NULL peer in these cases, and thus we're also able to get rid of the clumsy inetpeer release logic. Signed-off-by: David S. Miller --- include/net/inet_connection_sock.h | 2 +- include/net/tcp.h | 2 +- net/ipv4/tcp_ipv4.c | 21 ++++++++------------- net/ipv4/tcp_minisocks.c | 5 +---- net/ipv6/tcp_ipv6.c | 21 ++++++++------------- 5 files changed, 19 insertions(+), 32 deletions(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 7d83f90f203f..e1b7734c456f 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -43,7 +43,7 @@ struct inet_connection_sock_af_ops { struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst); - struct inet_peer *(*get_peer)(struct sock *sk, bool *release_it); + struct inet_peer *(*get_peer)(struct sock *sk); u16 net_header_len; u16 net_frag_header_len; u16 sockaddr_len; diff --git a/include/net/tcp.h b/include/net/tcp.h index e79aa48d9fc1..424591866037 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -327,7 +327,7 @@ extern void tcp_shutdown (struct sock *sk, int how); extern int tcp_v4_rcv(struct sk_buff *skb); -extern struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it); +extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); extern void *tcp_v4_tw_get_peer(struct sock *sk); extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 833e8d96a636..77f049d00dbb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1820,23 +1820,18 @@ do_time_wait: goto discard_it; } -struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it) +struct inet_peer *tcp_v4_get_peer(struct sock *sk) { struct rtable *rt = (struct rtable *) __sk_dst_get(sk); struct inet_sock *inet = inet_sk(sk); - struct net *net = sock_net(sk); - struct inet_peer *peer; - - if (!rt || - inet->cork.fl.u.ip4.daddr != inet->inet_daddr) { - peer = inet_getpeer_v4(net, inet->inet_daddr, 1); - *release_it = true; - } else { - peer = rt_get_peer_create(rt, inet->inet_daddr); - *release_it = false; - } - return peer; + /* If we don't have a valid cached route, or we're doing IP + * options which make the IPv4 header destination address + * different from our peer's, do not bother with this. + */ + if (!rt || inet->cork.fl.u.ip4.daddr != inet->inet_daddr) + return NULL; + return rt_get_peer_create(rt, inet->inet_daddr); } EXPORT_SYMBOL(tcp_v4_get_peer); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index b85d9fe7d663..fef9dbf3af00 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -60,9 +60,8 @@ static bool tcp_remember_stamp(struct sock *sk) const struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); struct inet_peer *peer; - bool release_it; - peer = icsk->icsk_af_ops->get_peer(sk, &release_it); + peer = icsk->icsk_af_ops->get_peer(sk); if (peer) { if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 || ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && @@ -70,8 +69,6 @@ static bool tcp_remember_stamp(struct sock *sk) peer->tcp_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp; peer->tcp_ts = tp->rx_opt.ts_recent; } - if (release_it) - inet_putpeer(peer); return true; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 218433cb9928..b5ecf37b61a6 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1732,23 +1732,18 @@ do_time_wait: goto discard_it; } -static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) +static struct inet_peer *tcp_v6_get_peer(struct sock *sk) { struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk); struct ipv6_pinfo *np = inet6_sk(sk); - struct net *net = sock_net(sk); - struct inet_peer *peer; - - if (!rt || - !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) { - peer = inet_getpeer_v6(net, &np->daddr, 1); - *release_it = true; - } else { - peer = rt6_get_peer_create(rt); - *release_it = false; - } - return peer; + /* If we don't have a valid cached route, or we're doing IP + * options which make the IPv6 header destination address + * different from our peer's, do not bother with this. + */ + if (!rt || !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) + return NULL; + return rt6_get_peer_create(rt); } static void *tcp_v6_tw_get_peer(struct sock *sk) -- GitLab From d13e14148154e5ce58467e76321eef1dd912c416 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 9 Jun 2012 10:31:09 +0200 Subject: [PATCH 0995/6849] mac80211: add some missing kernel-doc Add a few kernel-doc descriptions that were missed during development. Reported-by: Randy Dunlap Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 ++++++ net/mac80211/sta_info.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1937c7d98304..95e39b6a02ec 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1940,6 +1940,11 @@ enum ieee80211_rate_control_changed { * to also unregister the device. If it returns 1, then mac80211 * will also go through the regular complete restart on resume. * + * @set_wakeup: Enable or disable wakeup when WoWLAN configuration is + * modified. The reason is that device_set_wakeup_enable() is + * supposed to be called when the configuration changes, not only + * in suspend(). + * * @add_interface: Called when a netdevice attached to the hardware is * enabled. Because it is not called for monitor mode devices, @start * and @stop must be implemented. @@ -2966,6 +2971,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, * ieee80211_generic_frame_duration - Calculate the duration field for a frame * @hw: pointer obtained from ieee80211_alloc_hw(). * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @band: the band to calculate the frame duration on * @frame_len: the length of the frame. * @rate: the rate at which the frame is going to be transmitted. * diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 3bb24a121c95..525ce5077e1c 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -278,6 +278,8 @@ struct sta_ampdu_mlme { * @sta: station information we share with the driver * @sta_state: duplicates information about station state (for debug) * @beacon_loss_count: number of times beacon loss has triggered + * @supports_40mhz: tracks whether the station advertised 40 MHz support + * as we overwrite its HT parameters with the currently used value */ struct sta_info { /* General information, mostly static */ -- GitLab From f8cdddb8d61d16a156229f0910f7ecfc7a82c003 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 8 Jun 2012 10:55:44 +0200 Subject: [PATCH 0996/6849] cfg80211: check iface combinations only when iface is running Don't validate interface combinations on a stopped interface. Otherwise we might end up being able to create a new interface with a certain type, but won't be able to change an existing interface into that type. This also skips some other functions when interface is stopped and changing interface type. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index 8f2d68fc3a44..316cfd00914f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -804,7 +804,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, ntype == NL80211_IFTYPE_P2P_CLIENT)) return -EBUSY; - if (ntype != otype) { + if (ntype != otype && netif_running(dev)) { err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, ntype); if (err) -- GitLab From e3f5d16120f5118e2f86f1f88deaa69e6843b31f Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Fri, 8 Jun 2012 13:30:24 -0700 Subject: [PATCH 0997/6849] mac80211: Remove unused variable Signed-off-by: Javier Cardona Reviewed-by: Jason Abele Signed-off-by: Johannes Berg --- net/mac80211/mesh_hwmp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index fa7c58035246..acbd1ad8eb33 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -323,7 +323,6 @@ void ieee80211s_update_metric(struct ieee80211_local *local, static u32 airtime_link_metric_get(struct ieee80211_local *local, struct sta_info *sta) { - struct ieee80211_supported_band *sband; struct rate_info rinfo; /* This should be adjusted for each device */ int device_constant = 1 << ARITH_SHIFT; @@ -333,8 +332,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, u32 tx_time, estimated_retx; u64 result; - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - if (sta->fail_avg >= 100) return MAX_METRIC; -- GitLab From 35b3fe1caa26e1ffc5144d3faadecdfa0a8a0f44 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Fri, 8 Jun 2012 13:30:25 -0700 Subject: [PATCH 0998/6849] mac80211: Rename stainfo variable for the more common sta Signed-off-by: Javier Cardona Reviewed-by: Jason Abele Signed-off-by: Johannes Berg --- net/mac80211/mesh.h | 2 +- net/mac80211/mesh_hwmp.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index e3642756f8f4..c7400a23b64b 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -245,7 +245,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); void ieee80211s_init(void); void ieee80211s_update_metric(struct ieee80211_local *local, - struct sta_info *stainfo, struct sk_buff *skb); + struct sta_info *sta, struct sk_buff *skb); void ieee80211s_stop(void); void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index acbd1ad8eb33..9b6da2de660d 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -303,7 +303,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, } void ieee80211s_update_metric(struct ieee80211_local *local, - struct sta_info *stainfo, struct sk_buff *skb) + struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; @@ -315,9 +315,9 @@ void ieee80211s_update_metric(struct ieee80211_local *local, failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); /* moving average, scaled to 100 */ - stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed); - if (stainfo->fail_avg > 95) - mesh_plink_broken(stainfo); + sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed); + if (sta->fail_avg > 95) + mesh_plink_broken(sta); } static u32 airtime_link_metric_get(struct ieee80211_local *local, -- GitLab From ea3b2ea24ef0f2ef9c6795b19cff456195b6728a Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Fri, 8 Jun 2012 18:29:06 +0300 Subject: [PATCH 0999/6849] mtd: nand: initialize bitflip_threshold prior to BBT scanning As of edbc454 [mtd: driver _read() returns max_bitflips; mtd_read() returns -EUCLEAN], 'mtd->bitflip_threshold' must be set for mtd devices having ECC, prior any 'mtd_read()' call. Otherwise, 'mtd_read()' will falsely return -EUCLEAN. Normally, 'mtd->bitflip_threshold' is initialized when the MTD is added. However, this is too late for NAND MTDs, as 'scan_bbt()' is invoked prior the existing initialization of 'mtd->bitflip_threshold'. This is a problem since 'scan_bbt()' calls 'mtd_read()', in the case of a flash-based bad block table. It resulted in a falsely reported bitflips indication during BBT read, which lead to constant scrubbing of the flash BBT blocks. Initialize 'mtd->bitflip_threshold' to its default value (if not already set by the driver), prior to invocation of 'scan_bbt()'. Reported-by: Sascha Hauer Tested-by: Sascha Hauer Signed-off-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d47586cf64ce..a11253a0fcab 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3501,6 +3501,13 @@ int nand_scan_tail(struct mtd_info *mtd) /* propagate ecc info to mtd_info */ mtd->ecclayout = chip->ecc.layout; mtd->ecc_strength = chip->ecc.strength; + /* + * Initialize bitflip_threshold to its default prior scan_bbt() call. + * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be + * properly set. + */ + if (!mtd->bitflip_threshold) + mtd->bitflip_threshold = mtd->ecc_strength; /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) -- GitLab From bcc2c9c3fff859e0eb019fe6fec26f9b8eba795c Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 31 May 2012 16:40:06 +0200 Subject: [PATCH 1000/6849] Tools: hv: verify origin of netlink connector message The SuSE security team suggested to use recvfrom instead of recv to be certain that the connector message is originated from kernel. CVE-2012-2669 Signed-off-by: Olaf Hering Signed-off-by: Marcus Meissner Signed-off-by: Sebastian Krahmer Signed-off-by: K. Y. Srinivasan Cc: stable Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_kvp_daemon.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 146fd6147e84..d9834b362943 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -701,14 +701,18 @@ int main(void) pfd.fd = fd; while (1) { + struct sockaddr *addr_p = (struct sockaddr *) &addr; + socklen_t addr_l = sizeof(addr); pfd.events = POLLIN; pfd.revents = 0; poll(&pfd, 1, -1); - len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0); + len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, + addr_p, &addr_l); - if (len < 0) { - syslog(LOG_ERR, "recv failed; error:%d", len); + if (len < 0 || addr.nl_pid) { + syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", + addr.nl_pid, errno, strerror(errno)); close(fd); return -1; } -- GitLab From 7d3da090cdcf400178b81f851c3721e2bbb9fce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 11:10:17 +0200 Subject: [PATCH 1001/6849] Staging: ipack/bridges/tpci200: remove gotos in tpci200_free_irq(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle error conditions with simple returns instead of usig gotos. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index c39499a81f6c..68bcc557cb47 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -512,24 +512,19 @@ static void __tpci200_free_irq(struct tpci200_board *tpci200, static int tpci200_free_irq(struct ipack_device *dev) { - int res; struct slot_irq *slot_irq; struct tpci200_board *tpci200; tpci200 = check_slot(dev); - if (tpci200 == NULL) { - res = -EINVAL; - goto out; - } + if (tpci200 == NULL) + return -EINVAL; - if (mutex_lock_interruptible(&tpci200->mutex)) { - res = -ERESTARTSYS; - goto out; - } + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; if (tpci200->slots[dev->slot].irq == NULL) { - res = -EINVAL; - goto out_unlock; + mutex_unlock(&tpci200->mutex); + return -EINVAL; } __tpci200_free_irq(tpci200, dev); @@ -537,10 +532,8 @@ static int tpci200_free_irq(struct ipack_device *dev) tpci200->slots[dev->slot].irq = NULL; kfree(slot_irq); -out_unlock: mutex_unlock(&tpci200->mutex); -out: - return res; + return 0; } static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) -- GitLab From 5e4be523981c7e63873b0321dee51bd94226fc99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:51 +0200 Subject: [PATCH 1002/6849] Staging: ipack/bridges/tpci200: remove "out" label in tpci200_slot_map_space() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the "out" label from tpci200_slot_map_space(), as it can directly return the error code instead of jumping. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 68bcc557cb47..7baa28a0caad 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -626,15 +626,11 @@ static int tpci200_slot_map_space(struct ipack_device *dev, struct tpci200_board *tpci200; tpci200 = check_slot(dev); - if (tpci200 == NULL) { - res = -EINVAL; - goto out; - } + if (tpci200 == NULL) + return -EINVAL; - if (mutex_lock_interruptible(&tpci200->mutex)) { - res = -ERESTARTSYS; - goto out; - } + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; switch (space) { case IPACK_IO_SPACE: @@ -699,7 +695,6 @@ static int tpci200_slot_map_space(struct ipack_device *dev, out_unlock: mutex_unlock(&tpci200->mutex); -out: return res; } -- GitLab From 14d9f9a3e1f9a962f5cc480dcf2ee72fb16031be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:52 +0200 Subject: [PATCH 1003/6849] Staging: ipack/bridges/tpci200: remove useless break in tpci200_slot_map_space() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 7baa28a0caad..f354b38b7fc6 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -686,7 +686,6 @@ static int tpci200_slot_map_space(struct ipack_device *dev, tpci200->number, dev->slot, space); res = -EINVAL; goto out_unlock; - break; } virt_addr_space->size = size_to_map; -- GitLab From f7986a9e7341e8f4c69cc36a60e1f778a01471ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:53 +0200 Subject: [PATCH 1004/6849] Staging: ipack/bridges/tpci200: remove "out" label in tpci200_request_irq() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the "out" label from tpci200_request_irq(), as it can directly return the error code instead of jumping. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index f354b38b7fc6..7616c4928c96 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -705,15 +705,11 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, struct tpci200_board *tpci200; tpci200 = check_slot(dev); - if (tpci200 == NULL) { - res = -EINVAL; - goto out; - } + if (tpci200 == NULL) + return -EINVAL; - if (mutex_lock_interruptible(&tpci200->mutex)) { - res = -ERESTARTSYS; - goto out; - } + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; if (tpci200->slots[dev->slot].irq != NULL) { dev_err(&dev->dev, @@ -747,7 +743,6 @@ static int tpci200_request_irq(struct ipack_device *dev, int vector, out_unlock: mutex_unlock(&tpci200->mutex); -out: return res; } -- GitLab From ec0ceb9e42ca9d7c65c1cbea585d8f5d61db7b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:54 +0200 Subject: [PATCH 1005/6849] Staging: ipack/bridges/tpci200: remove gotos in tpci200_install() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the gotos when handling error conditions, as the code gets clearer and the gotos are not really avoiding code replication. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 7616c4928c96..e692f1e13aa5 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -777,23 +777,18 @@ static int tpci200_install(struct tpci200_board *tpci200) tpci200->slots = kzalloc( TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); - if (tpci200->slots == NULL) { - res = -ENOMEM; - goto out_err; - } + if (tpci200->slots == NULL) + return -ENOMEM; res = tpci200_register(tpci200); - if (res) - goto out_free; + if (res) { + kfree(tpci200->slots); + tpci200->slots = NULL; + return res; + } mutex_init(&tpci200->mutex); return 0; - -out_free: - kfree(tpci200->slots); - tpci200->slots = NULL; -out_err: - return res; } static int tpci200_pciprobe(struct pci_dev *pdev, -- GitLab From 8ae7012d3ed3314cc1bf52bd6c51eaa4cc1609a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:55 +0200 Subject: [PATCH 1006/6849] Staging: ipack/devices/ipoctal: remove ipoctal_config structure. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The configuration of the communication channel is handled by the tty abstraction, so the ipoctal_config structure has become useless and it's only used to store values that are never accesed. Remove it. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 11 ----------- drivers/staging/ipack/devices/ipoctal.h | 17 ----------------- 2 files changed, 28 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 17aa35a9de63..ff88800ab05b 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -49,7 +49,6 @@ struct ipoctal { char *buffer[NR_CHANNELS]; unsigned int nb_bytes[NR_CHANNELS]; unsigned int count_wr[NR_CHANNELS]; - struct ipoctal_config chan_config[NR_CHANNELS]; wait_queue_head_t queue[NR_CHANNELS]; unsigned short error_flag[NR_CHANNELS]; spinlock_t lock[NR_CHANNELS]; @@ -671,22 +670,18 @@ static void ipoctal_set_termios(struct tty_struct *tty, if (cflag & CRTSCTS) { mr1 |= MR1_RxRTS_CONTROL_ON; mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON; - ipoctal->chan_config[channel].flow_control = 1; } else { mr1 |= MR1_RxRTS_CONTROL_OFF; mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; - ipoctal->chan_config[channel].flow_control = 0; } break; case IP_OCTAL_422_ID: mr1 |= MR1_RxRTS_CONTROL_OFF; mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; - ipoctal->chan_config[channel].flow_control = 0; break; case IP_OCTAL_485_ID: mr1 |= MR1_RxRTS_CONTROL_OFF; mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF; - ipoctal->chan_config[channel].flow_control = 0; break; default: return; @@ -750,12 +745,6 @@ static void ipoctal_set_termios(struct tty_struct *tty, ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr2); ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.csr, csr); - /* save the setup in the structure */ - ipoctal->chan_config[channel].baud = tty_get_baud_rate(tty); - ipoctal->chan_config[channel].bits_per_char = cflag & CSIZE; - ipoctal->chan_config[channel].parity = cflag & PARENB; - ipoctal->chan_config[channel].stop_bits = cflag & CSTOPB; - /* Enable again the RX */ ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, CR_ENABLE_RX); diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h index 266f3617069d..b3c901cf6d14 100644 --- a/drivers/staging/ipack/devices/ipoctal.h +++ b/drivers/staging/ipack/devices/ipoctal.h @@ -41,23 +41,6 @@ enum uart_error { UART_BREAK = 1 << 4, /* Received break */ }; -/** - * struct ipoctal_config - Serial configuration - * - * @baud: Baud rate - * @stop_bits: Stop bits (1 or 2) - * @bits_per_char: data size in bits - * @parity - * @flow_control: Flow control management (RTS/CTS) (0 disabled, 1 enabled) - */ -struct ipoctal_config { - unsigned int baud; - unsigned int stop_bits; - unsigned int bits_per_char; - unsigned short parity; - unsigned int flow_control; -}; - /** * struct ipoctal_stats -- Stats since last reset * -- GitLab From c15768bb0c346767eb54e01a7e772041f36eb65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:56 +0200 Subject: [PATCH 1007/6849] Staging: ipack/devices/ipoctal: remove error_flag field from ipoctal struct. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the error_flag field from the ipoctal structure, as the error code is handled through the tty abstraction. Remove the values definition as well. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 8 -------- drivers/staging/ipack/devices/ipoctal.h | 13 ------------- 2 files changed, 21 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index ff88800ab05b..29214677ea0c 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -50,7 +50,6 @@ struct ipoctal { unsigned int nb_bytes[NR_CHANNELS]; unsigned int count_wr[NR_CHANNELS]; wait_queue_head_t queue[NR_CHANNELS]; - unsigned short error_flag[NR_CHANNELS]; spinlock_t lock[NR_CHANNELS]; unsigned int pointer_read[NR_CHANNELS]; unsigned int pointer_write[NR_CHANNELS]; @@ -275,23 +274,19 @@ static int ipoctal_irq_handler(void *arg) CR_CMD_RESET_ERR_STATUS); if (sr & SR_OVERRUN_ERROR) { - ipoctal->error_flag[channel] |= UART_OVERRUN; ipoctal->chan_stats[channel].overrun_err++; /* Overrun doesn't affect the current character*/ tty_insert_flip_char(tty, 0, TTY_OVERRUN); } if (sr & SR_PARITY_ERROR) { - ipoctal->error_flag[channel] |= UART_PARITY; ipoctal->chan_stats[channel].parity_err++; flag = TTY_PARITY; } if (sr & SR_FRAMING_ERROR) { - ipoctal->error_flag[channel] |= UART_FRAMING; ipoctal->chan_stats[channel].framing_err++; flag = TTY_FRAME; } if (sr & SR_RECEIVED_BREAK) { - ipoctal->error_flag[channel] |= UART_BREAK; ipoctal->chan_stats[channel].rcv_break++; flag = TTY_BREAK; } @@ -493,7 +488,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, ipoctal_reset_stats(&ipoctal->chan_stats[i]); ipoctal->nb_bytes[i] = 0; init_waitqueue_head(&ipoctal->queue[i]); - ipoctal->error_flag[i] = UART_NOERROR; spin_lock_init(&ipoctal->lock[i]); ipoctal->pointer_read[i] = 0; @@ -552,8 +546,6 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, ipoctal_copy_write_buffer(ipoctal, channel, buf, count); - ipoctal->error_flag[channel] = UART_NOERROR; - /* As the IP-OCTAL 485 only supports half duplex, do it manually */ if (ipoctal->board_id == IP_OCTAL_485_ID) { ipoctal_write_io_reg(ipoctal, diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h index b3c901cf6d14..2aae170de613 100644 --- a/drivers/staging/ipack/devices/ipoctal.h +++ b/drivers/staging/ipack/devices/ipoctal.h @@ -28,19 +28,6 @@ enum uart_parity_e { UART_EVEN = 2, }; -/** - * enum uart_error - UART error type - * - */ -enum uart_error { - UART_NOERROR = 0, /* No error during transmission */ - UART_TIMEOUT = 1 << 0, /* Timeout error */ - UART_OVERRUN = 1 << 1, /* Overrun error */ - UART_PARITY = 1 << 2, /* Parity error */ - UART_FRAMING = 1 << 3, /* Framing error */ - UART_BREAK = 1 << 4, /* Received break */ -}; - /** * struct ipoctal_stats -- Stats since last reset * -- GitLab From 1be9bbddde32a0c414dd65220ca86f808aaeec5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:57 +0200 Subject: [PATCH 1008/6849] Staging: ipack/devices/ipoctal: remove unused enum uart_parity_e. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h index 2aae170de613..c5b4ed46516f 100644 --- a/drivers/staging/ipack/devices/ipoctal.h +++ b/drivers/staging/ipack/devices/ipoctal.h @@ -19,15 +19,6 @@ #define MAX_DEVICES (NR_CHANNELS * IPOCTAL_MAX_BOARDS) #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) -/** - * enum uart_parity_e - UART supported parity. - */ -enum uart_parity_e { - UART_NONE = 0, - UART_ODD = 1, - UART_EVEN = 2, -}; - /** * struct ipoctal_stats -- Stats since last reset * -- GitLab From 395350370010ab9693085ede5a1c08fb2faeb5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Thu, 7 Jun 2012 10:24:58 +0200 Subject: [PATCH 1009/6849] Staging: ipack/bridges/tpci200: change device table definition and export it. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use DEFINE_PCI_DEVICE_TABLE() to create the device table and add MODULE_DEVICE_TABLE() to export it. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index e692f1e13aa5..ae9f803db292 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -871,12 +871,14 @@ static void __devexit tpci200_pci_remove(struct pci_dev *dev) } } -static struct pci_device_id tpci200_idtable[2] = { +static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = { { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, TPCI200_SUBDEVICE_ID }, { 0, }, }; +MODULE_DEVICE_TABLE(pci, tpci200_idtable); + static struct pci_driver tpci200_pci_drv = { .name = "tpci200", .id_table = tpci200_idtable, -- GitLab From 2397849baa7c44c242e5d5142d5d16d1e7ed53d0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 14:56:12 -0700 Subject: [PATCH 1010/6849] [PATCH] tcp: Cache inetpeer in timewait socket, and only when necessary. Since it's guarenteed that we will access the inetpeer if we're trying to do timewait recycling and TCP options were enabled on the connection, just cache the peer in the timewait socket. In the future, inetpeer lookups will be context dependent (per routing realm), and this helps facilitate that as well. Signed-off-by: David S. Miller --- include/linux/tcp.h | 3 ++- include/net/tcp.h | 1 - include/net/timewait_sock.h | 8 -------- net/ipv4/tcp_ipv4.c | 10 ---------- net/ipv4/tcp_minisocks.c | 27 ++++++++++++++++++++------- net/ipv6/tcp_ipv6.c | 13 ------------- 6 files changed, 22 insertions(+), 40 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 4c5b63283377..23e8234f75a5 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -506,8 +506,9 @@ struct tcp_timewait_sock { u32 tw_rcv_wnd; u32 tw_ts_recent; long tw_ts_recent_stamp; + struct inet_peer *tw_peer; #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *tw_md5_key; + struct tcp_md5sig_key *tw_md5_key; #endif /* Few sockets in timewait have cookies; in that case, then this * object holds a reference to them (tw_cookie_values->kref). diff --git a/include/net/tcp.h b/include/net/tcp.h index 424591866037..9332f342259a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -328,7 +328,6 @@ extern void tcp_shutdown (struct sock *sk, int how); extern int tcp_v4_rcv(struct sk_buff *skb); extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); -extern void *tcp_v4_tw_get_peer(struct sock *sk); extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size); diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h index 8d6689cb2c66..68f0ecad6c6e 100644 --- a/include/net/timewait_sock.h +++ b/include/net/timewait_sock.h @@ -22,7 +22,6 @@ struct timewait_sock_ops { int (*twsk_unique)(struct sock *sk, struct sock *sktw, void *twp); void (*twsk_destructor)(struct sock *sk); - void *(*twsk_getpeer)(struct sock *sk); }; static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) @@ -41,11 +40,4 @@ static inline void twsk_destructor(struct sock *sk) sk->sk_prot->twsk_prot->twsk_destructor(sk); } -static inline void *twsk_getpeer(struct sock *sk) -{ - if (sk->sk_prot->twsk_prot->twsk_getpeer) - return sk->sk_prot->twsk_prot->twsk_getpeer(sk); - return NULL; -} - #endif /* _TIMEWAIT_SOCK_H */ diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 77f049d00dbb..fda2ca17135e 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1835,20 +1835,10 @@ struct inet_peer *tcp_v4_get_peer(struct sock *sk) } EXPORT_SYMBOL(tcp_v4_get_peer); -void *tcp_v4_tw_get_peer(struct sock *sk) -{ - const struct inet_timewait_sock *tw = inet_twsk(sk); - struct net *net = sock_net(sk); - - return inet_getpeer_v4(net, tw->tw_daddr, 1); -} -EXPORT_SYMBOL(tcp_v4_tw_get_peer); - static struct timewait_sock_ops tcp_timewait_sock_ops = { .twsk_obj_size = sizeof(struct tcp_timewait_sock), .twsk_unique = tcp_twsk_unique, .twsk_destructor= tcp_twsk_destructor, - .twsk_getpeer = tcp_v4_tw_get_peer, }; const struct inet_connection_sock_af_ops ipv4_specific = { diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index fef9dbf3af00..cb015317c9f7 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -77,20 +77,19 @@ static bool tcp_remember_stamp(struct sock *sk) static bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) { + const struct tcp_timewait_sock *tcptw; struct sock *sk = (struct sock *) tw; struct inet_peer *peer; - peer = twsk_getpeer(sk); + tcptw = tcp_twsk(sk); + peer = tcptw->tw_peer; if (peer) { - const struct tcp_timewait_sock *tcptw = tcp_twsk(sk); - if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 || ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) { peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp; peer->tcp_ts = tcptw->tw_ts_recent; } - inet_putpeer(peer); return true; } return false; @@ -314,9 +313,12 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); bool recycle_ok = false; + bool recycle_on = false; - if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) + if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) { recycle_ok = tcp_remember_stamp(sk); + recycle_on = true; + } if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets) tw = inet_twsk_alloc(sk, state); @@ -324,8 +326,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) if (tw != NULL) { struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); + struct inet_sock *inet = inet_sk(sk); + struct inet_peer *peer = NULL; - tw->tw_transparent = inet_sk(sk)->transparent; + tw->tw_transparent = inet->transparent; tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale; tcptw->tw_rcv_nxt = tp->rcv_nxt; tcptw->tw_snd_nxt = tp->snd_nxt; @@ -347,6 +351,12 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) } #endif + if (recycle_on) + peer = icsk->icsk_af_ops->get_peer(sk); + tcptw->tw_peer = peer; + if (peer) + atomic_inc(&peer->refcnt); + #ifdef CONFIG_TCP_MD5SIG /* * The timewait bucket does not have the key DB from the @@ -398,8 +408,11 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) void tcp_twsk_destructor(struct sock *sk) { -#ifdef CONFIG_TCP_MD5SIG struct tcp_timewait_sock *twsk = tcp_twsk(sk); + + if (twsk->tw_peer) + inet_putpeer(twsk->tw_peer); +#ifdef CONFIG_TCP_MD5SIG if (twsk->tw_md5_key) { tcp_free_md5sig_pool(); kfree_rcu(twsk->tw_md5_key, rcu); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b5ecf37b61a6..f91b0bfd12d5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1746,23 +1746,10 @@ static struct inet_peer *tcp_v6_get_peer(struct sock *sk) return rt6_get_peer_create(rt); } -static void *tcp_v6_tw_get_peer(struct sock *sk) -{ - const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); - const struct inet_timewait_sock *tw = inet_twsk(sk); - struct net *net = sock_net(sk); - - if (tw->tw_family == AF_INET) - return tcp_v4_tw_get_peer(sk); - - return inet_getpeer_v6(net, &tw6->tw_v6_daddr, 1); -} - static struct timewait_sock_ops tcp6_timewait_sock_ops = { .twsk_obj_size = sizeof(struct tcp6_timewait_sock), .twsk_unique = tcp_twsk_unique, .twsk_destructor= tcp_twsk_destructor, - .twsk_getpeer = tcp_v6_tw_get_peer, }; static const struct inet_connection_sock_af_ops ipv6_specific = { -- GitLab From 1d0c4da8f717937aeda47a72bc769d80f8776795 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Sat, 9 Jun 2012 19:22:42 -0300 Subject: [PATCH 1011/6849] Bluetooth: Fix style in hidp code Follow the net rules. Signed-off-by: Gustavo Padovan --- net/bluetooth/hidp/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 8a4afc7515a2..ccd985da6518 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -225,7 +225,8 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) } static int __hidp_send_ctrl_message(struct hidp_session *session, - unsigned char hdr, unsigned char *data, int size) + unsigned char hdr, unsigned char *data, + int size) { struct sk_buff *skb; -- GitLab From 6eda541d12116b4772baa09d3e8d7b0389df4289 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 8 Jun 2012 14:32:50 +0200 Subject: [PATCH 1012/6849] Bluetooth: Support AR3011 in Acer Iconia Tab W500 Acer used this chip connected via USB: Bus 005 Device 005: ID 0cf3:3005 Atheros Communications, Inc. AR3011 Bluetooth Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 224 Wireless bDeviceSubClass 1 Radio Frequency bDeviceProtocol 1 Bluetooth bMaxPacketSize0 64 idVendor 0x0cf3 Atheros Communications, Inc. idProduct 0x3005 AR3011 Bluetooth bcdDevice 0.01 iManufacturer 0 iProduct 0 iSerial 0 bNumConfigurations 1 Signed-off-by: Marek Vasut Cc: Gustavo Padovan Cc: Johan Hedberg Cc: Marcel Holtmann Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 1 + drivers/bluetooth/btusb.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ad591bd240ec..f0f62021227f 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, + { USB_DEVICE(0x0CF3, 0xE019) }, { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c9463af8e564..ff3eabc45ff5 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -125,6 +125,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, -- GitLab From c3426b47190d7c6785230c91a706fd42208b4120 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 16:27:05 -0700 Subject: [PATCH 1013/6849] inet: Initialize per-netns inetpeer roots in net/ipv{4,6}/route.c Instead of net/ipv4/inetpeer.c Signed-off-by: David S. Miller --- include/net/inetpeer.h | 9 ++++++ net/ipv4/inetpeer.c | 64 +++++++++++------------------------------- net/ipv4/route.c | 25 +++++++++++++++++ net/ipv6/route.c | 34 +++++++++++++++++++++- 4 files changed, 83 insertions(+), 49 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 20e67db69ac9..5a96c8edc526 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -65,6 +65,14 @@ struct inet_peer { atomic_t refcnt; }; +struct inet_peer_base { + struct inet_peer __rcu *root; + seqlock_t lock; + int total; +}; + +extern void inet_peer_base_init(struct inet_peer_base *); + void inet_initpeers(void) __init; #define INETPEER_METRICS_NEW (~(u32) 0) @@ -105,6 +113,7 @@ static inline struct inet_peer *inet_getpeer_v6(struct net *net, extern void inet_putpeer(struct inet_peer *p); extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); +extern void __inetpeer_invalidate_tree(struct inet_peer_base *); extern void inetpeer_invalidate_tree(struct net *net, int family); /* diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 1c8527349c86..d0d72f89b279 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -82,11 +82,13 @@ static const struct inet_peer peer_fake_node = { .avl_height = 0 }; -struct inet_peer_base { - struct inet_peer __rcu *root; - seqlock_t lock; - int total; -}; +void inet_peer_base_init(struct inet_peer_base *bp) +{ + bp->root = peer_avl_empty_rcu; + seqlock_init(&bp->lock); + bp->total = 0; +} +EXPORT_SYMBOL_GPL(inet_peer_base_init); #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ @@ -141,46 +143,6 @@ static void inetpeer_gc_worker(struct work_struct *work) schedule_delayed_work(&gc_work, gc_delay); } -static int __net_init inetpeer_net_init(struct net *net) -{ - net->ipv4.peers = kzalloc(sizeof(struct inet_peer_base), - GFP_KERNEL); - if (net->ipv4.peers == NULL) - return -ENOMEM; - - net->ipv4.peers->root = peer_avl_empty_rcu; - seqlock_init(&net->ipv4.peers->lock); - - net->ipv6.peers = kzalloc(sizeof(struct inet_peer_base), - GFP_KERNEL); - if (net->ipv6.peers == NULL) - goto out_ipv6; - - net->ipv6.peers->root = peer_avl_empty_rcu; - seqlock_init(&net->ipv6.peers->lock); - - return 0; -out_ipv6: - kfree(net->ipv4.peers); - return -ENOMEM; -} - -static void __net_exit inetpeer_net_exit(struct net *net) -{ - inetpeer_invalidate_tree(net, AF_INET); - kfree(net->ipv4.peers); - net->ipv4.peers = NULL; - - inetpeer_invalidate_tree(net, AF_INET6); - kfree(net->ipv6.peers); - net->ipv6.peers = NULL; -} - -static struct pernet_operations inetpeer_ops = { - .init = inetpeer_net_init, - .exit = inetpeer_net_exit, -}; - /* Called from ip_output.c:ip_init */ void __init inet_initpeers(void) { @@ -205,7 +167,6 @@ void __init inet_initpeers(void) NULL); INIT_DELAYED_WORK_DEFERRABLE(&gc_work, inetpeer_gc_worker); - register_pernet_subsys(&inetpeer_ops); } static int addr_compare(const struct inetpeer_addr *a, @@ -603,10 +564,9 @@ static void inetpeer_inval_rcu(struct rcu_head *head) schedule_delayed_work(&gc_work, gc_delay); } -void inetpeer_invalidate_tree(struct net *net, int family) +void __inetpeer_invalidate_tree(struct inet_peer_base *base) { struct inet_peer *old, *new, *prev; - struct inet_peer_base *base = family_to_base(net, family); write_seqlock_bh(&base->lock); @@ -625,4 +585,12 @@ void inetpeer_invalidate_tree(struct net *net, int family) out: write_sequnlock_bh(&base->lock); } +EXPORT_SYMBOL(__inetpeer_invalidate_tree); + +void inetpeer_invalidate_tree(struct net *net, int family) +{ + struct inet_peer_base *base = family_to_base(net, family); + + __inetpeer_invalidate_tree(base); +} EXPORT_SYMBOL(inetpeer_invalidate_tree); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 7a4d724765e6..4cd35c3904d4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3385,6 +3385,30 @@ static __net_initdata struct pernet_operations rt_genid_ops = { .init = rt_genid_init, }; +static int __net_init ipv4_inetpeer_init(struct net *net) +{ + struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL); + + if (!bp) + return -ENOMEM; + inet_peer_base_init(bp); + net->ipv4.peers = bp; + return 0; +} + +static void __net_exit ipv4_inetpeer_exit(struct net *net) +{ + struct inet_peer_base *bp = net->ipv4.peers; + + net->ipv4.peers = NULL; + __inetpeer_invalidate_tree(bp); + kfree(bp); +} + +static __net_initdata struct pernet_operations ipv4_inetpeer_ops = { + .init = ipv4_inetpeer_init, + .exit = ipv4_inetpeer_exit, +}; #ifdef CONFIG_IP_ROUTE_CLASSID struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; @@ -3465,6 +3489,7 @@ int __init ip_rt_init(void) register_pernet_subsys(&sysctl_route_ops); #endif register_pernet_subsys(&rt_genid_ops); + register_pernet_subsys(&ipv4_inetpeer_ops); return rc; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8a986be4aeda..3e1e4e0da096 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2996,6 +2996,31 @@ static struct pernet_operations ip6_route_net_ops = { .exit = ip6_route_net_exit, }; +static int __net_init ipv6_inetpeer_init(struct net *net) +{ + struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL); + + if (!bp) + return -ENOMEM; + inet_peer_base_init(bp); + net->ipv6.peers = bp; + return 0; +} + +static void __net_exit ipv6_inetpeer_exit(struct net *net) +{ + struct inet_peer_base *bp = net->ipv6.peers; + + net->ipv6.peers = NULL; + __inetpeer_invalidate_tree(bp); + kfree(bp); +} + +static __net_initdata struct pernet_operations ipv6_inetpeer_ops = { + .init = ipv6_inetpeer_init, + .exit = ipv6_inetpeer_exit, +}; + static struct notifier_block ip6_route_dev_notifier = { .notifier_call = ip6_route_dev_notify, .priority = 0, @@ -3020,6 +3045,10 @@ int __init ip6_route_init(void) if (ret) goto out_dst_entries; + ret = register_pernet_subsys(&ipv6_inetpeer_ops); + if (ret) + goto out_register_subsys; + ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; /* Registering of the loopback is done before this portion of code, @@ -3035,7 +3064,7 @@ int __init ip6_route_init(void) #endif ret = fib6_init(); if (ret) - goto out_register_subsys; + goto out_register_inetpeer; ret = xfrm6_init(); if (ret) @@ -3064,6 +3093,8 @@ xfrm6_init: xfrm6_fini(); out_fib6_init: fib6_gc_cleanup(); +out_register_inetpeer: + unregister_pernet_subsys(&ipv6_inetpeer_ops); out_register_subsys: unregister_pernet_subsys(&ip6_route_net_ops); out_dst_entries: @@ -3079,6 +3110,7 @@ void ip6_route_cleanup(void) fib6_rules_cleanup(); xfrm6_fini(); fib6_gc_cleanup(); + unregister_pernet_subsys(&ipv6_inetpeer_ops); unregister_pernet_subsys(&ip6_route_net_ops); dst_entries_destroy(&ip6_dst_blackhole_ops); kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); -- GitLab From 56a6b248eb345c1948ee60bf426de1ff7dd81509 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 16:32:41 -0700 Subject: [PATCH 1014/6849] inet: Consolidate inetpeer_invalidate_tree() interfaces. We only need one interface for this operation, since we always know which inetpeer root we want to flush. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 3 +-- net/ipv4/inetpeer.c | 10 +--------- net/ipv4/route.c | 4 ++-- net/ipv6/route.c | 2 +- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 5a96c8edc526..733edc641b76 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -113,8 +113,7 @@ static inline struct inet_peer *inet_getpeer_v6(struct net *net, extern void inet_putpeer(struct inet_peer *p); extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); -extern void __inetpeer_invalidate_tree(struct inet_peer_base *); -extern void inetpeer_invalidate_tree(struct net *net, int family); +extern void inetpeer_invalidate_tree(struct inet_peer_base *); /* * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index d0d72f89b279..9d89a381f0e1 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -564,7 +564,7 @@ static void inetpeer_inval_rcu(struct rcu_head *head) schedule_delayed_work(&gc_work, gc_delay); } -void __inetpeer_invalidate_tree(struct inet_peer_base *base) +void inetpeer_invalidate_tree(struct inet_peer_base *base) { struct inet_peer *old, *new, *prev; @@ -585,12 +585,4 @@ void __inetpeer_invalidate_tree(struct inet_peer_base *base) out: write_sequnlock_bh(&base->lock); } -EXPORT_SYMBOL(__inetpeer_invalidate_tree); - -void inetpeer_invalidate_tree(struct net *net, int family) -{ - struct inet_peer_base *base = family_to_base(net, family); - - __inetpeer_invalidate_tree(base); -} EXPORT_SYMBOL(inetpeer_invalidate_tree); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 4cd35c3904d4..cf78343940de 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -935,7 +935,7 @@ static void rt_cache_invalidate(struct net *net) get_random_bytes(&shuffle, sizeof(shuffle)); atomic_add(shuffle + 1U, &net->ipv4.rt_genid); - inetpeer_invalidate_tree(net, AF_INET); + inetpeer_invalidate_tree(net->ipv4.peers); } /* @@ -3401,7 +3401,7 @@ static void __net_exit ipv4_inetpeer_exit(struct net *net) struct inet_peer_base *bp = net->ipv4.peers; net->ipv4.peers = NULL; - __inetpeer_invalidate_tree(bp); + inetpeer_invalidate_tree(bp); kfree(bp); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3e1e4e0da096..7f346d7492d2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -3012,7 +3012,7 @@ static void __net_exit ipv6_inetpeer_exit(struct net *net) struct inet_peer_base *bp = net->ipv6.peers; net->ipv6.peers = NULL; - __inetpeer_invalidate_tree(bp); + inetpeer_invalidate_tree(bp); kfree(bp); } -- GitLab From 2b823f72585552ef6fb77d6c081e55e047e879f0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 19:00:16 -0700 Subject: [PATCH 1015/6849] ipv6: Do not mark ipv6_inetpeer_ops as __net_initdata. Signed-off-by: David S. Miller --- net/ipv6/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7f346d7492d2..9586c27e069c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -3016,7 +3016,7 @@ static void __net_exit ipv6_inetpeer_exit(struct net *net) kfree(bp); } -static __net_initdata struct pernet_operations ipv6_inetpeer_ops = { +static struct pernet_operations ipv6_inetpeer_ops = { .init = ipv6_inetpeer_init, .exit = ipv6_inetpeer_exit, }; -- GitLab From 8b51b064a6da90c68af5385a874968829a2a0ed7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 8 Jun 2012 22:10:20 +0000 Subject: [PATCH 1016/6849] af_unix: remove unix_iter_state As pointed out by Michael Tokarev , struct unix_iter_state is no longer needed. Suggested-by: Michael Tokarev Signed-off-by: Eric Dumazet Cc: Steven Whitehouse Cc: Pavel Emelyanov Signed-off-by: David S. Miller --- net/unix/af_unix.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index cf83f6b5ac91..79981d97bc9c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2255,10 +2255,6 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, #define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1)) #define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o)) -struct unix_iter_state { - struct seq_net_private p; -}; - static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos) { unsigned long offset = get_offset(*pos); @@ -2383,7 +2379,7 @@ static const struct seq_operations unix_seq_ops = { static int unix_seq_open(struct inode *inode, struct file *file) { return seq_open_net(inode, file, &unix_seq_ops, - sizeof(struct unix_iter_state)); + sizeof(struct seq_net_private)); } static const struct file_operations unix_seq_fops = { -- GitLab From c0efc887dcadbdbfe171f028acfab9c7c00e9dde Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 19:12:36 -0700 Subject: [PATCH 1017/6849] inet: Pass inetpeer root into inet_getpeer*() interfaces. Otherwise we reference potentially non-existing members when ipv6 is disabled. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 10 +++++----- net/ipv4/inetpeer.c | 9 +-------- net/ipv4/ip_fragment.c | 2 +- net/ipv4/route.c | 6 +++--- net/ipv6/route.c | 2 +- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 733edc641b76..b84b32fd5df1 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -83,11 +83,11 @@ static inline bool inet_metrics_new(const struct inet_peer *p) } /* can be called with or without local BH being disabled */ -struct inet_peer *inet_getpeer(struct net *net, +struct inet_peer *inet_getpeer(struct inet_peer_base *base, const struct inetpeer_addr *daddr, int create); -static inline struct inet_peer *inet_getpeer_v4(struct net *net, +static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base, __be32 v4daddr, int create) { @@ -95,10 +95,10 @@ static inline struct inet_peer *inet_getpeer_v4(struct net *net, daddr.addr.a4 = v4daddr; daddr.family = AF_INET; - return inet_getpeer(net, &daddr, create); + return inet_getpeer(base, &daddr, create); } -static inline struct inet_peer *inet_getpeer_v6(struct net *net, +static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base, const struct in6_addr *v6daddr, int create) { @@ -106,7 +106,7 @@ static inline struct inet_peer *inet_getpeer_v6(struct net *net, *(struct in6_addr *)daddr.addr.a6 = *v6daddr; daddr.family = AF_INET6; - return inet_getpeer(net, &daddr, create); + return inet_getpeer(base, &daddr, create); } /* can be called from BH context or outside */ diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 9d89a381f0e1..e4cba56a5349 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -391,12 +391,6 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base, call_rcu(&p->rcu, inetpeer_free_rcu); } -static struct inet_peer_base *family_to_base(struct net *net, - int family) -{ - return family == AF_INET ? net->ipv4.peers : net->ipv6.peers; -} - /* perform garbage collect on all items stacked during a lookup */ static int inet_peer_gc(struct inet_peer_base *base, struct inet_peer __rcu **stack[PEER_MAXDEPTH], @@ -434,12 +428,11 @@ static int inet_peer_gc(struct inet_peer_base *base, return cnt; } -struct inet_peer *inet_getpeer(struct net *net, +struct inet_peer *inet_getpeer(struct inet_peer_base *base, const struct inetpeer_addr *daddr, int create) { struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; - struct inet_peer_base *base = family_to_base(net, daddr->family); struct inet_peer *p; unsigned int sequence; int invalidated, gccnt = 0; diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 22c6bab9717a..8d07c973409c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -184,7 +184,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a) qp->daddr = arg->iph->daddr; qp->user = arg->user; qp->peer = sysctl_ipfrag_max_dist ? - inet_getpeer_v4(net, arg->iph->saddr, 1) : NULL; + inet_getpeer_v4(net->ipv4.peers, arg->iph->saddr, 1) : NULL; } static __inline__ void ip4_frag_free(struct inet_frag_queue *q) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index cf78343940de..2aa663a6ae9e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1328,7 +1328,7 @@ void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) struct net *net = dev_net(rt->dst.dev); struct inet_peer *peer; - peer = inet_getpeer_v4(net, daddr, create); + peer = inet_getpeer_v4(net->ipv4.peers, daddr, create); if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) inet_putpeer(peer); @@ -1684,7 +1684,7 @@ unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, unsigned short est_mtu = 0; struct inet_peer *peer; - peer = inet_getpeer_v4(net, iph->daddr, 1); + peer = inet_getpeer_v4(net->ipv4.peers, iph->daddr, 1); if (peer) { unsigned short mtu = new_mtu; @@ -1929,7 +1929,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS)) create = 1; - rt->peer = peer = inet_getpeer_v4(net, rt->rt_dst, create); + rt->peer = peer = inet_getpeer_v4(net->ipv4.peers, rt->rt_dst, create); if (peer) { rt->rt_peer_genid = rt_peer_genid(); if (inet_metrics_new(peer)) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9586c27e069c..8fc41d502bbd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -306,7 +306,7 @@ void rt6_bind_peer(struct rt6_info *rt, int create) struct net *net = dev_net(rt->dst.dev); struct inet_peer *peer; - peer = inet_getpeer_v6(net, &rt->rt6i_dst.addr, create); + peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, create); if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) inet_putpeer(peer); else -- GitLab From e981f6d41acda2ae8c05e60feb2cb97772b4a6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 10 Jun 2012 14:37:07 +0300 Subject: [PATCH 1018/6849] remoteproc: fix print format warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compile warnings from GCC 4.6.1 when printing values of type size_t. drivers/remoteproc/remoteproc_core.c:251:6: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘size_t’ [-Wformat] drivers/remoteproc/remoteproc_core.c:938:9: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 4 has type ‘size_t’ [-Wformat] drivers/remoteproc/remoteproc_core.c:1023:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t’ [-Wformat] Signed-off-by: Sjur Brændeland Signed-off-by: Ohad Ben-Cohen Cc: stable@vger.kernel.org --- drivers/remoteproc/remoteproc_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 8ea7bccc7100..cb13f1b74416 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -247,7 +247,7 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) } if (offset + filesz > len) { - dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", + dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", offset + filesz, len); ret = -EINVAL; break; @@ -934,7 +934,7 @@ static void rproc_resource_cleanup(struct rproc *rproc) unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); if (unmapped != entry->len) { /* nothing much to do besides complaining */ - dev_err(dev, "failed to unmap %u/%u\n", entry->len, + dev_err(dev, "failed to unmap %u/%zu\n", entry->len, unmapped); } @@ -1020,7 +1020,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) ehdr = (struct elf32_hdr *)fw->data; - dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); + dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size); /* * if enabling an IOMMU isn't relevant for this rproc, this is -- GitLab From 30338cf09f82523d8747670f7363cc8af347c79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 10 Jun 2012 14:37:51 +0300 Subject: [PATCH 1019/6849] remoteproc: fix missing fault indication in error-path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If rproc_find_rsc_table() fails, rproc_fw_boot() must set return-value before jumping to clean_up label. Otherwise no error value is returned. Signed-off-by: Sjur Brændeland Signed-off-by: Ohad Ben-Cohen Cc: stable@vger.kernel.org --- drivers/remoteproc/remoteproc_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index cb13f1b74416..66324ee4678f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1041,8 +1041,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) /* look for the resource table */ table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); - if (!table) + if (!table) { + ret = -EINVAL; goto clean_up; + } /* handle fw resources which are required to boot rproc */ ret = rproc_handle_boot_rsc(rproc, table, tablesz); -- GitLab From f52c44cd27b4a0be37ef97f0466e4095ebebef3f Mon Sep 17 00:00:00 2001 From: James Morris Date: Sun, 10 Jun 2012 22:48:36 +1000 Subject: [PATCH 1020/6849] Merge branches 'next-queue' and 'next' into next Pull in changes submitted during upstream merge window. -- GitLab From 056c78d3a28ab7c8438b42f4d0915030ca8f51b9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 9 Jan 2012 11:42:39 +0100 Subject: [PATCH 1021/6849] ARM: nomadik: register GPIOs dynamically Register the NHK8815 GPIO devices dynamically like the Ux500 does it. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/cpu-8815.c | 114 +++++++++++++------------------ 1 file changed, 47 insertions(+), 67 deletions(-) diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 27f43a46985e..b79b3846935a 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -35,86 +35,66 @@ #include "clock.h" #include "cpu-8815.h" -#define __MEM_4K_RESOURCE(x) \ - .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} - -/* The 8815 has 4 GPIO blocks, let's register them immediately */ - -#define GPIO_RESOURCE(block) \ - { \ - .start = NOMADIK_GPIO##block##_BASE, \ - .end = NOMADIK_GPIO##block##_BASE + SZ_4K - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - { \ - .start = IRQ_GPIO##block, \ - .end = IRQ_GPIO##block, \ - .flags = IORESOURCE_IRQ, \ - } - -#define GPIO_DEVICE(block) \ - { \ - .name = "gpio", \ - .id = block, \ - .num_resources = 2, \ - .resource = &cpu8815_gpio_resources[block * 2], \ - .dev = { \ - .platform_data = &cpu8815_gpio[block], \ - }, \ - } +static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL); -static struct nmk_gpio_platform_data cpu8815_gpio[] = { - { - .name = "GPIO-0-31", - .first_gpio = 0, - .first_irq = NOMADIK_GPIO_TO_IRQ(0), - }, { - .name = "GPIO-32-63", - .first_gpio = 32, - .first_irq = NOMADIK_GPIO_TO_IRQ(32), - }, { - .name = "GPIO-64-95", - .first_gpio = 64, - .first_irq = NOMADIK_GPIO_TO_IRQ(64), - }, { - .name = "GPIO-96-127", /* 124..127 not routed to pin */ - .first_gpio = 96, - .first_irq = NOMADIK_GPIO_TO_IRQ(96), - } +static struct amba_device *amba_devs[] __initdata = { + &cpu8815_amba_rng_device }; -static struct resource cpu8815_gpio_resources[] = { - GPIO_RESOURCE(0), - GPIO_RESOURCE(1), - GPIO_RESOURCE(2), - GPIO_RESOURCE(3), +/* The 8815 has 4 GPIO blocks, let's register them immediately */ +static resource_size_t __initdata cpu8815_gpio_base[] = { + NOMADIK_GPIO0_BASE, + NOMADIK_GPIO1_BASE, + NOMADIK_GPIO2_BASE, + NOMADIK_GPIO3_BASE, }; -static struct platform_device cpu8815_platform_gpio[] = { - GPIO_DEVICE(0), - GPIO_DEVICE(1), - GPIO_DEVICE(2), - GPIO_DEVICE(3), -}; +static struct platform_device * +cpu8815_add_gpio(int id, resource_size_t addr, int irq, + struct nmk_gpio_platform_data *pdata) +{ + struct resource resources[] = { + { + .start = addr, + .end = addr + 127, + .flags = IORESOURCE_MEM, + }, + { + .start = irq, + .end = irq, + .flags = IORESOURCE_IRQ, + } + }; + + return platform_device_register_resndata(NULL, "gpio", id, + resources, ARRAY_SIZE(resources), + pdata, sizeof(*pdata)); +} -static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL); +void cpu8815_add_gpios(resource_size_t *base, int num, int irq, + struct nmk_gpio_platform_data *pdata) +{ + int first = 0; + int i; -static struct platform_device *platform_devs[] __initdata = { - cpu8815_platform_gpio + 0, - cpu8815_platform_gpio + 1, - cpu8815_platform_gpio + 2, - cpu8815_platform_gpio + 3, -}; + for (i = 0; i < num; i++, first += 32, irq++) { + pdata->first_gpio = first; + pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); + pdata->num_gpio = 32; -static struct amba_device *amba_devs[] __initdata = { - &cpu8815_amba_rng_device -}; + cpu8815_add_gpio(i, base[i], irq, pdata); + } +} static int __init cpu8815_init(void) { int i; + struct nmk_gpio_platform_data pdata = { + /* No custom data yet */ + }; - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); + cpu8815_add_gpios(cpu8815_gpio_base, ARRAY_SIZE(cpu8815_gpio_base), + IRQ_GPIO0, &pdata); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) amba_device_register(amba_devs[i], &iomem_resource); return 0; -- GitLab From 7c77852d2f22cebd5ca7c4ded4c47284e67ed9b5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 9 Jan 2012 12:40:02 +0100 Subject: [PATCH 1022/6849] ARM: nomadik: register AMBA devices dynamically This makes AMBA devices on the Nomadik main CPU die register dynamically, and refactor the registration of the RNG to use this. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/board-nhk8815.c | 17 ++--------------- arch/arm/mach-nomadik/cpu-8815.c | 13 ++++--------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 2e8d3e176bc7..43b844eb9244 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -185,17 +185,6 @@ static void __init nhk8815_onenand_init(void) #endif } -static AMBA_APB_DEVICE(uart0, "uart0", 0, NOMADIK_UART0_BASE, - { IRQ_UART0 }, NULL); - -static AMBA_APB_DEVICE(uart1, "uart1", 0, NOMADIK_UART1_BASE, - { IRQ_UART1 }, NULL); - -static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - &uart1_device, -}; - static struct resource nhk8815_eth_resources[] = { { .name = "smc91x-regs", @@ -255,15 +244,13 @@ static struct sys_timer nomadik_timer = { static void __init nhk8815_platform_init(void) { - int i; - cpu8815_platform_init(); nhk8815_onenand_init(); platform_add_devices(nhk8815_platform_devices, ARRAY_SIZE(nhk8815_platform_devices)); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) - amba_device_register(amba_devs[i], &iomem_resource); + amba_apb_device_add(NULL, "uart0", NOMADIK_UART0_BASE, SZ_4K, IRQ_UART0, 0, NULL, 0); + amba_apb_device_add(NULL, "uart1", NOMADIK_UART1_BASE, SZ_4K, IRQ_UART1, 0, NULL, 0); } MACHINE_START(NOMADIK, "NHK8815") diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index b79b3846935a..c0f28a6d0d06 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include @@ -35,12 +38,6 @@ #include "clock.h" #include "cpu-8815.h" -static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL); - -static struct amba_device *amba_devs[] __initdata = { - &cpu8815_amba_rng_device -}; - /* The 8815 has 4 GPIO blocks, let's register them immediately */ static resource_size_t __initdata cpu8815_gpio_base[] = { NOMADIK_GPIO0_BASE, @@ -88,15 +85,13 @@ void cpu8815_add_gpios(resource_size_t *base, int num, int irq, static int __init cpu8815_init(void) { - int i; struct nmk_gpio_platform_data pdata = { /* No custom data yet */ }; cpu8815_add_gpios(cpu8815_gpio_base, ARRAY_SIZE(cpu8815_gpio_base), IRQ_GPIO0, &pdata); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) - amba_device_register(amba_devs[i], &iomem_resource); + amba_apb_device_add(NULL, "rng", NOMADIK_RNG_BASE, SZ_4K, 0, 0, NULL, 0); return 0; } arch_initcall(cpu8815_init); -- GitLab From b5111d9ed4cba9a29ee454db162c4a88c6b944bf Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 9 Jan 2012 14:17:01 +0100 Subject: [PATCH 1023/6849] ARM: nomadik: register PL031 RTC This registers the PL031 derivate found in the Nomadik 8815 SoCs. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/cpu-8815.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index c0f28a6d0d06..88511fef7987 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -92,6 +92,7 @@ static int __init cpu8815_init(void) cpu8815_add_gpios(cpu8815_gpio_base, ARRAY_SIZE(cpu8815_gpio_base), IRQ_GPIO0, &pdata); amba_apb_device_add(NULL, "rng", NOMADIK_RNG_BASE, SZ_4K, 0, 0, NULL, 0); + amba_apb_device_add(NULL, "rtc-pl031", NOMADIK_RTC_BASE, SZ_4K, IRQ_RTC_RTT, 0, NULL, 0); return 0; } arch_initcall(cpu8815_init); -- GitLab From 4a31bd28e86ac50eb620f6b5b36464c45b5fa38f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 11 Jan 2012 13:52:34 +0100 Subject: [PATCH 1024/6849] ARM: nomadik: convert to generic clock Remove more custom stuff by simply converting the Nomadik machine to use generic clocks and move the driver to drivers/clk. Acked-by: Arnd Bergmann Cc: Mike Turquette Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 2 +- arch/arm/mach-nomadik/Makefile | 2 - arch/arm/mach-nomadik/clock.c | 75 ----------------------- arch/arm/mach-nomadik/clock.h | 15 ----- arch/arm/mach-nomadik/cpu-8815.c | 4 +- drivers/clk/Makefile | 1 + drivers/clk/clk-nomadik.c | 47 ++++++++++++++ include/linux/platform_data/clk-nomadik.h | 2 + 8 files changed, 53 insertions(+), 95 deletions(-) delete mode 100644 arch/arm/mach-nomadik/clock.c delete mode 100644 arch/arm/mach-nomadik/clock.h create mode 100644 drivers/clk/clk-nomadik.c create mode 100644 include/linux/platform_data/clk-nomadik.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b649c5904a4f..e58bda6b6dde 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -912,7 +912,7 @@ config ARCH_NOMADIK select ARM_AMBA select ARM_VIC select CPU_ARM926T - select CLKDEV_LOOKUP + select COMMON_CLK select GENERIC_CLOCKEVENTS select PINCTRL select MIGHT_HAVE_CACHE_L2X0 diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile index a6bbd1a7b4e7..a42c9a33d3bf 100644 --- a/arch/arm/mach-nomadik/Makefile +++ b/arch/arm/mach-nomadik/Makefile @@ -7,8 +7,6 @@ # Object file lists. -obj-y += clock.o - # Cpu revision obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c deleted file mode 100644 index 48a59f24e10c..000000000000 --- a/arch/arm/mach-nomadik/clock.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * linux/arch/arm/mach-nomadik/clock.c - * - * Copyright (C) 2009 Alessandro Rubini - */ -#include -#include -#include -#include -#include -#include "clock.h" - -/* - * The nomadik board uses generic clocks, but the serial pl011 file - * calls clk_enable(), clk_disable(), clk_get_rate(), so we provide them - */ -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -/* enable and disable do nothing */ -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -static struct clk clk_24 = { - .rate = 2400000, -}; - -static struct clk clk_48 = { - .rate = 48 * 1000 * 1000, -}; - -/* - * Catch-all default clock to satisfy drivers using the clk API. We don't - * model the actual hardware clocks yet. - */ -static struct clk clk_default; - -#define CLK(_clk, dev) \ - { \ - .clk = _clk, \ - .dev_id = dev, \ - } - -static struct clk_lookup lookups[] = { - { - .con_id = "apb_pclk", - .clk = &clk_default, - }, - CLK(&clk_24, "mtu0"), - CLK(&clk_24, "mtu1"), - CLK(&clk_48, "uart0"), - CLK(&clk_48, "uart1"), - CLK(&clk_default, "gpio.0"), - CLK(&clk_default, "gpio.1"), - CLK(&clk_default, "gpio.2"), - CLK(&clk_default, "gpio.3"), - CLK(&clk_default, "rng"), -}; - -int __init clk_init(void) -{ - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - return 0; -} diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h deleted file mode 100644 index 78da2e7c3985..000000000000 --- a/arch/arm/mach-nomadik/clock.h +++ /dev/null @@ -1,15 +0,0 @@ - -/* - * linux/arch/arm/mach-nomadik/clock.h - * - * Copyright (C) 2009 Alessandro Rubini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -struct clk { - unsigned long rate; -}; - -int __init clk_init(void); diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 88511fef7987..6fd8e46567a4 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,6 @@ #include #include -#include "clock.h" #include "cpu-8815.h" /* The 8815 has 4 GPIO blocks, let's register them immediately */ @@ -123,7 +123,7 @@ void __init cpu8815_init_irq(void) * Init clocks here so that they are available for system timer * initialization. */ - clk_init(); + nomadik_clk_init(); } /* diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index b9a5158a30b1..26b6b92942e1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -3,5 +3,6 @@ obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ clk-mux.o clk-divider.o clk-fixed-factor.o # SoCs specific +obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c new file mode 100644 index 000000000000..517a8ff7121e --- /dev/null +++ b/drivers/clk/clk-nomadik.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +/* + * The Nomadik clock tree is described in the STN8815A12 DB V4.2 + * reference manual for the chip, page 94 ff. + */ + +void __init nomadik_clk_init(void) +{ + struct clk *clk; + + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + clk_register_clkdev(clk, NULL, "gpio.0"); + clk_register_clkdev(clk, NULL, "gpio.1"); + clk_register_clkdev(clk, NULL, "gpio.2"); + clk_register_clkdev(clk, NULL, "gpio.3"); + clk_register_clkdev(clk, NULL, "rng"); + + /* + * The 2.4 MHz TIMCLK reference clock is active at boot time, this is + * actually the MXTALCLK @19.2 MHz divided by 8. This clock is used + * by the timers and watchdog. See page 105 ff. + */ + clk = clk_register_fixed_rate(NULL, "TIMCLK", NULL, CLK_IS_ROOT, + 2400000); + clk_register_clkdev(clk, NULL, "mtu0"); + clk_register_clkdev(clk, NULL, "mtu1"); + + /* + * At boot time, PLL2 is set to generate a set of fixed clocks, + * one of them is CLK48, the 48 MHz clock, routed to the UART, MMC/SD + * I2C, IrDA, USB and SSP blocks. + */ + clk = clk_register_fixed_rate(NULL, "CLK48", NULL, CLK_IS_ROOT, + 48000000); + clk_register_clkdev(clk, NULL, "uart0"); + clk_register_clkdev(clk, NULL, "uart1"); + clk_register_clkdev(clk, NULL, "mmci"); + clk_register_clkdev(clk, NULL, "ssp"); + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); +} diff --git a/include/linux/platform_data/clk-nomadik.h b/include/linux/platform_data/clk-nomadik.h new file mode 100644 index 000000000000..5713c87b2477 --- /dev/null +++ b/include/linux/platform_data/clk-nomadik.h @@ -0,0 +1,2 @@ +/* Minimal platform data header */ +void nomadik_clk_init(void); -- GitLab From 661d414cb4492590f70f01c29212213947aea364 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 25 Jan 2012 14:34:52 +0100 Subject: [PATCH 1025/6849] ARM: nomadik: register all three I2C busses The Nomadik has two dedicated I2C bus blocks for I2C0 and I2C1, and a bitbanged GPIO connection on two pins for the USB portions of the STw4811 chip. Register all three as bit-banged GPIO for the moment. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/i2c-8815nhk.c | 38 +++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c index 0fc2f6f1cc97..6d14454d4609 100644 --- a/arch/arm/mach-nomadik/i2c-8815nhk.c +++ b/arch/arm/mach-nomadik/i2c-8815nhk.c @@ -5,6 +5,7 @@ #include #include #include +#include /* * There are two busses in the 8815NHK. @@ -12,19 +13,27 @@ * use bit-bang through GPIO by now, to keep things simple */ +/* I2C0 connected to the STw4811 power management chip */ static struct i2c_gpio_platform_data nhk8815_i2c_data0 = { /* keep defaults for timeouts; pins are push-pull bidirectional */ .scl_pin = 62, .sda_pin = 63, }; +/* I2C1 connected to various sensors */ static struct i2c_gpio_platform_data nhk8815_i2c_data1 = { /* keep defaults for timeouts; pins are push-pull bidirectional */ .scl_pin = 53, .sda_pin = 54, }; -/* first bus: GPIO XX and YY */ +/* I2C2 connected to the USB portions of the STw4811 only */ +static struct i2c_gpio_platform_data nhk8815_i2c_data2 = { + /* keep defaults for timeouts; pins are push-pull bidirectional */ + .scl_pin = 73, + .sda_pin = 74, +}; + static struct platform_device nhk8815_i2c_dev0 = { .name = "i2c-gpio", .id = 0, @@ -32,7 +41,7 @@ static struct platform_device nhk8815_i2c_dev0 = { .platform_data = &nhk8815_i2c_data0, }, }; -/* second bus: GPIO XX and YY */ + static struct platform_device nhk8815_i2c_dev1 = { .name = "i2c-gpio", .id = 1, @@ -41,15 +50,29 @@ static struct platform_device nhk8815_i2c_dev1 = { }, }; +static struct platform_device nhk8815_i2c_dev2 = { + .name = "i2c-gpio", + .id = 2, + .dev = { + .platform_data = &nhk8815_i2c_data2, + }, +}; + +static pin_cfg_t cpu8815_pins_i2c[] = { + PIN_CFG_INPUT(62, GPIO, PULLUP), + PIN_CFG_INPUT(63, GPIO, PULLUP), + PIN_CFG_INPUT(53, GPIO, PULLUP), + PIN_CFG_INPUT(54, GPIO, PULLUP), + PIN_CFG_INPUT(73, GPIO, PULLUP), + PIN_CFG_INPUT(74, GPIO, PULLUP), +}; + static int __init nhk8815_i2c_init(void) { - nmk_gpio_set_mode(nhk8815_i2c_data0.scl_pin, NMK_GPIO_ALT_GPIO); - nmk_gpio_set_mode(nhk8815_i2c_data0.sda_pin, NMK_GPIO_ALT_GPIO); + nmk_config_pins(cpu8815_pins_i2c, ARRAY_SIZE(cpu8815_pins_i2c)); platform_device_register(&nhk8815_i2c_dev0); - - nmk_gpio_set_mode(nhk8815_i2c_data1.scl_pin, NMK_GPIO_ALT_GPIO); - nmk_gpio_set_mode(nhk8815_i2c_data1.sda_pin, NMK_GPIO_ALT_GPIO); platform_device_register(&nhk8815_i2c_dev1); + platform_device_register(&nhk8815_i2c_dev2); return 0; } @@ -58,6 +81,7 @@ static void __exit nhk8815_i2c_exit(void) { platform_device_unregister(&nhk8815_i2c_dev0); platform_device_unregister(&nhk8815_i2c_dev1); + platform_device_unregister(&nhk8815_i2c_dev2); return; } -- GitLab From d088f671e413ec1a58ebf9adc288ca93346f9b8e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 25 Jan 2012 14:37:58 +0100 Subject: [PATCH 1026/6849] ARM: nomadik: register the I2C devices Add board data to register all the Nomadik I2C devices. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/board-nhk8815.c | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 43b844eb9244..029a741fd9f2 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -242,6 +243,30 @@ static struct sys_timer nomadik_timer = { .init = nomadik_timer_init, }; +static struct i2c_board_info __initdata nhk8815_i2c0_devices[] = { + { + I2C_BOARD_INFO("stw4811", 0x2d), + }, +}; + +static struct i2c_board_info __initdata nhk8815_i2c1_devices[] = { + { + I2C_BOARD_INFO("camera", 0x10), + }, + { + I2C_BOARD_INFO("stw5095", 0x1a), + }, + { + I2C_BOARD_INFO("lis3lv02dl", 0x1d), + }, +}; + +static struct i2c_board_info __initdata nhk8815_i2c2_devices[] = { + { + I2C_BOARD_INFO("stw4811-usb", 0x2d), + }, +}; + static void __init nhk8815_platform_init(void) { cpu8815_platform_init(); @@ -251,6 +276,13 @@ static void __init nhk8815_platform_init(void) amba_apb_device_add(NULL, "uart0", NOMADIK_UART0_BASE, SZ_4K, IRQ_UART0, 0, NULL, 0); amba_apb_device_add(NULL, "uart1", NOMADIK_UART1_BASE, SZ_4K, IRQ_UART1, 0, NULL, 0); + + i2c_register_board_info(0, nhk8815_i2c0_devices, + ARRAY_SIZE(nhk8815_i2c0_devices)); + i2c_register_board_info(1, nhk8815_i2c1_devices, + ARRAY_SIZE(nhk8815_i2c1_devices)); + i2c_register_board_info(2, nhk8815_i2c2_devices, + ARRAY_SIZE(nhk8815_i2c2_devices)); } MACHINE_START(NOMADIK, "NHK8815") -- GitLab From 171af7dcb8812f173f0a5a4ab79a88598586d394 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 9 Apr 2012 22:57:09 +0200 Subject: [PATCH 1027/6849] ARM: nomadik: register the MMC/SD device This registers the MMC device for the Nomadik so we can access MMC/SD cards, which is pretty nice. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/board-nhk8815.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 029a741fd9f2..f4535a7dadf5 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -186,6 +187,29 @@ static void __init nhk8815_onenand_init(void) #endif } +static struct mmci_platform_data mmcsd_plat_data = { + .ocr_mask = MMC_VDD_29_30, + .f_max = 48000000, + .gpio_wp = -1, + .gpio_cd = 111, + .cd_invert = true, + .capabilities = MMC_CAP_MMC_HIGHSPEED | + MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA, +}; + +static int __init nhk8815_mmcsd_init(void) +{ + int ret; + + ret = gpio_request(112, "card detect bias"); + if (ret) + return ret; + gpio_direction_output(112, 0); + amba_apb_device_add(NULL, "mmci", NOMADIK_SDI_BASE, SZ_4K, IRQ_SDMMC, 0, &mmcsd_plat_data, 0x10180180); + return 0; +} +module_init(nhk8815_mmcsd_init); + static struct resource nhk8815_eth_resources[] = { { .name = "smc91x-regs", -- GitLab From 688df8f0b57ae2db5c4b998a59737618b9031592 Mon Sep 17 00:00:00 2001 From: Todor Colov Date: Sun, 10 Jun 2012 15:44:08 +0300 Subject: [PATCH 1028/6849] arm: ep93xx: Enable i2c support for ep9302 Enable i2c support for ep9302. i2c support is needed when external RTC is used. Signed-off-by: Todor Colov Signed-off-by: Ryan Mallon --- arch/arm/mach-ep93xx/edb93xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index d74c5cddb98b..3bb8e56969a5 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -91,8 +91,8 @@ static void __init edb93xx_register_i2c(void) ep93xx_register_i2c(&edb93xx_i2c_gpio_data, edb93xxa_i2c_board_info, ARRAY_SIZE(edb93xxa_i2c_board_info)); - } else if (machine_is_edb9307() || machine_is_edb9312() || - machine_is_edb9315()) { + } else if (machine_is_edb9302() || machine_is_edb9307() + || machine_is_edb9312() || machine_is_edb9315()) { ep93xx_register_i2c(&edb93xx_i2c_gpio_data, edb93xx_i2c_board_info, ARRAY_SIZE(edb93xx_i2c_board_info)); -- GitLab From e4a99938706b080b562055f83bf29e28ce0770ad Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 10:04:42 +0800 Subject: [PATCH 1029/6849] regulator: isl6271a: Remove setting map_voltage callback for isl_fixed_ops isl_fixed_ops does not implement set_voltage_sel callback, adding map_voltage here is misleading. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/isl6271a-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 4a11b82a6d57..1d145a07ada9 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -81,7 +81,6 @@ static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) static struct regulator_ops isl_fixed_ops = { .get_voltage = isl6271a_get_fixed_voltage, .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, }; static const struct regulator_desc isl_rd[] = { -- GitLab From ea7e33045458ffd6d13175031527b6527807633c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 4 Jun 2012 12:44:15 +0800 Subject: [PATCH 1030/6849] regulator: twl: Convert twl6030ldo_ops to use regulator_list_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index c7390711d954..a1d07e517db3 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -577,13 +577,6 @@ static struct regulator_ops twl6030coresmps_ops = { .get_voltage = twl6030coresmps_get_voltage, }; -static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) -{ - struct twlreg_info *info = rdev_get_drvdata(rdev); - - return ((info->min_mV + (index * 100)) * 1000); -} - static int twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) @@ -621,7 +614,7 @@ static int twl6030ldo_get_voltage(struct regulator_dev *rdev) } static struct regulator_ops twl6030ldo_ops = { - .list_voltage = twl6030ldo_list_voltage, + .list_voltage = regulator_list_voltage_linear, .set_voltage = twl6030ldo_set_voltage, .get_voltage = twl6030ldo_get_voltage, @@ -959,6 +952,8 @@ static struct twlreg_info TWL6030_INFO_##label = { \ .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ + .min_uV = min_mVolts * 1000, \ + .uV_step = 100 * 1000, \ }, \ } @@ -974,6 +969,8 @@ static struct twlreg_info TWL6025_INFO_##label = { \ .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ + .min_uV = min_mVolts * 1000, \ + .uV_step = 100 * 1000, \ }, \ } -- GitLab From d01c3a1e1b1e4e417202adf1e9dec0730eb00e2b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 3 Jun 2012 23:02:34 +0800 Subject: [PATCH 1031/6849] regulator: anatop: Convert to set_voltage_sel and regulator_map_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 29 ++++++---------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index d04cf2113245..4324cea01141 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -43,33 +43,15 @@ struct anatop_regulator { struct regulator_init_data *initdata; }; -static int anatop_set_voltage(struct regulator_dev *reg, int min_uV, - int max_uV, unsigned *selector) +static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - u32 val, sel, mask; - int uv; - - uv = min_uV; - dev_dbg(®->dev, "%s: uv %d, min %d, max %d\n", __func__, - uv, anatop_reg->min_voltage, - anatop_reg->max_voltage); - - if (uv < anatop_reg->min_voltage) { - if (max_uV > anatop_reg->min_voltage) - uv = anatop_reg->min_voltage; - else - return -EINVAL; - } + u32 val, mask; if (!anatop_reg->control_reg) return -ENOTSUPP; - sel = DIV_ROUND_UP(uv - anatop_reg->min_voltage, 25000); - if (sel * 25000 + anatop_reg->min_voltage > anatop_reg->max_voltage) - return -EINVAL; - val = anatop_reg->min_bit_val + sel; - *selector = sel; + val = anatop_reg->min_bit_val + selector; dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); mask = ((1 << anatop_reg->vol_bit_width) - 1) << anatop_reg->vol_bit_shift; @@ -95,9 +77,10 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg) } static struct regulator_ops anatop_rops = { - .set_voltage = anatop_set_voltage, + .set_voltage_sel = anatop_set_voltage_sel, .get_voltage_sel = anatop_get_voltage_sel, - .list_voltage = regulator_list_voltage_linear, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, }; static int __devinit anatop_regulator_probe(struct platform_device *pdev) -- GitLab From ab0d1cbe55014ac65cfc317f8ef2cd5fa4b7d4da Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 12:03:04 +0800 Subject: [PATCH 1032/6849] regulator: max77686: Check pdata->num_regulators earlier If this driver only works when pdata->num_regulators == MAX77686_REGULATORS, let's check it earlier. Also remove unused num_regulators from struct max77686_data. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 43 ++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index b76a0389d0b8..b0c146df42d1 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -65,7 +65,6 @@ enum max77686_ramp_rate { struct max77686_data { struct device *dev; struct max77686_dev *iodev; - int num_regulators; struct regulator_dev **rdev; int ramp_delay; /* in mV/us */ }; @@ -235,6 +234,12 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s\n", __func__); + if (!pdata || pdata->num_regulators != MAX77686_REGULATORS) { + dev_err(&pdev->dev, + "Invalid initial data for regulator's initialiation\n"); + return -EINVAL; + } + max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data), GFP_KERNEL); if (!max77686) @@ -248,8 +253,6 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) rdev = max77686->rdev; max77686->dev = &pdev->dev; max77686->iodev = iodev; - if (pdata) - max77686->num_regulators = pdata->num_regulators; platform_set_drvdata(pdev, max77686); max77686->ramp_delay = RAMP_RATE_NO_CTRL; /* Set 0x3 for RAMP */ @@ -263,34 +266,26 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) MAX77686_REG_BUCK4CTRL1, MAX77686_RAMP_RATE_MASK, max77686->ramp_delay << 6); - if (pdata->num_regulators == MAX77686_REGULATORS) { - for (i = 0; i < MAX77686_REGULATORS; i++) { - config.dev = max77686->dev; - config.regmap = iodev->regmap; - config.driver_data = max77686; - config.init_data = pdata->regulators[i].initdata; - - rdev[i] = regulator_register(®ulators[i], &config); - - if (IS_ERR(rdev[i])) { - ret = PTR_ERR(rdev[i]); - dev_err(max77686->dev, + for (i = 0; i < MAX77686_REGULATORS; i++) { + config.dev = max77686->dev; + config.regmap = iodev->regmap; + config.driver_data = max77686; + config.init_data = pdata->regulators[i].initdata; + + rdev[i] = regulator_register(®ulators[i], &config); + if (IS_ERR(rdev[i])) { + ret = PTR_ERR(rdev[i]); + dev_err(max77686->dev, "regulator init failed for %d\n", i); rdev[i] = NULL; goto err; - } } - } else { - dev_err(max77686->dev, - "Lack of initial data for regulator's initialiation\n"); - return -EINVAL; } + return 0; err: - for (i = 0; i < MAX77686_REGULATORS; i++) { - if (rdev[i]) - regulator_unregister(rdev[i]); - } + while (--i >= 0) + regulator_unregister(rdev[i]); return ret; } -- GitLab From 98a175b60f46a80dfa44fb0e0807f2e5a351f35f Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Sat, 9 Jun 2012 16:40:38 +0530 Subject: [PATCH 1033/6849] regulator: core: Add regulator_set_voltage_time_sel to calculate ramp delay. This patch adds regulator_set_voltage_time_sel(), to move into core, the commonly used code by drivers to provide the .set_voltage_time_sel callback. It will also allow us to configure different ramp delay for different regulators easily. Signed-off-by: Yadwinder Singh Brar Signed-off-by: Mark Brown --- drivers/regulator/core.c | 24 ++++++++++++++++++++++++ include/linux/regulator/driver.h | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c6aedaa934d..ff76abde3ab3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2279,6 +2279,30 @@ int regulator_set_voltage_time(struct regulator *regulator, } EXPORT_SYMBOL_GPL(regulator_set_voltage_time); +/** + *regulator_set_voltage_time_sel - get raise/fall time + * @regulator: regulator source + * @old_selector: selector for starting voltage + * @new_selector: selector for target voltage + * + * Provided with the starting and target voltage selectors, this function + * returns time in microseconds required to rise or fall to this new voltage + * + * Drivers providing uV_step in their regulator_desc and ramp_delay in + * regulation_constraints can use this as their set_voltage_time_sel() + * operation. + */ +int regulator_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, + unsigned int new_selector) +{ + if (rdev->desc->ramp_delay && rdev->desc->uV_step) + return DIV_ROUND_UP(rdev->desc->uV_step * + abs(new_selector - old_selector), + rdev->desc->ramp_delay) * 1000; + return 0; +} + /** * regulator_sync_voltage - re-apply last regulator output voltage * @regulator: regulator source diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 80226383e561..ae5c25379237 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -170,6 +170,7 @@ enum regulator_type { * * @min_uV: Voltage given by the lowest selector (if linear mapping) * @uV_step: Voltage increase with each selector (if linear mapping) + * @ramp_delay: Time to settle down after voltage change (unit: mV/us) * @volt_table: Voltage mapping table (if table based mapping) * * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_ @@ -189,6 +190,7 @@ struct regulator_desc { unsigned int min_uV; unsigned int uV_step; + unsigned int ramp_delay; const unsigned int *volt_table; @@ -285,6 +287,9 @@ int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel); int regulator_is_enabled_regmap(struct regulator_dev *rdev); int regulator_enable_regmap(struct regulator_dev *rdev); int regulator_disable_regmap(struct regulator_dev *rdev); +int regulator_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, + unsigned int new_selector); void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); -- GitLab From 23ca6bf2318fecfbb9cd9d524e82d5029ef365bf Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 17:21:44 +0800 Subject: [PATCH 1034/6849] regulator: max77686: Fix the delay time for set_voltage_time_sel rdev->desc->uV_step * abs(new_selector - old_selector) returns uV. The unit of ramp_rate is mV/us. Thus 1000 should be multiplied. Signed-off-by: Axel Lin Reviewed-by: Yadwinder Singh Brar Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index b0c146df42d1..2dd4ac91d283 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -77,7 +77,7 @@ static int max77686_set_dvs_voltage_time_sel(struct regulator_dev *rdev, return DIV_ROUND_UP(rdev->desc->uV_step * abs(new_selector - old_selector), - ramp_rate[max77686->ramp_delay]); + ramp_rate[max77686->ramp_delay] * 1000); } static int max77686_set_voltage_time_sel(struct regulator_dev *rdev, @@ -85,7 +85,7 @@ static int max77686_set_voltage_time_sel(struct regulator_dev *rdev, { /* Unconditionally 100 mV/us */ return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), 100); + abs(new_selector - old_selector), 100 * 1000); } static struct regulator_ops max77686_ops = { -- GitLab From 601722157b3f6be73623644eeae6f14940f0bd8f Mon Sep 17 00:00:00 2001 From: Qiao Zhou Date: Mon, 4 Jun 2012 10:41:03 +0800 Subject: [PATCH 1035/6849] ARM: MMP: add pxa910-ssp into ssp_id_table add pxa910-ssp into ssp_id_table, and fix pxa-ssp compiling issue under mach-mmp architect. Signed-off-by: Qiao Zhou Acked-by: Haojian Zhuang Signed-off-by: Mark Brown --- arch/arm/plat-pxa/ssp.c | 1 + include/linux/pxa2xx_ssp.h | 1 + include/linux/spi/pxa2xx_spi.h | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 58b79809d20c..584c9bf8ed2d 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -193,6 +193,7 @@ static const struct platform_device_id ssp_id_table[] = { { "pxa25x-nssp", PXA25x_NSSP }, { "pxa27x-ssp", PXA27x_SSP }, { "pxa168-ssp", PXA168_SSP }, + { "pxa910-ssp", PXA910_SSP }, { }, }; diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 44835fb39793..f9fe15ec2b51 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -161,6 +161,7 @@ enum pxa_ssp_type { PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ PXA27x_SSP, PXA168_SSP, + PXA910_SSP, CE4100_SSP, }; diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index d3e1075f7b60..c73d1445c77e 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -43,7 +43,7 @@ struct pxa2xx_spi_chip { void (*cs_control)(u32 command); }; -#ifdef CONFIG_ARCH_PXA +#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) #include #include -- GitLab From 972a55b62d592cfcd6d73577df8a52f1251ea9a7 Mon Sep 17 00:00:00 2001 From: Qiao Zhou Date: Mon, 4 Jun 2012 10:41:04 +0800 Subject: [PATCH 1036/6849] ASoC: fix pxa-ssp compiling issue under mach-mmp pxa-ssp.c uses API like cpu_is_pxa3xx(), cpu_is_pxa2xx(), which is defined under arch-pxa architecture, and drivers under mach-mmp can't find it. so just use ssp->type to replace that API. Signed-off-by: Qiao Zhou Acked-by: Haojian Zhuang Signed-off-by: Mark Brown --- include/linux/pxa2xx_ssp.h | 1 + sound/soc/pxa/pxa-ssp.c | 38 +++++++++++--------------------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index f9fe15ec2b51..f36632061c66 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -160,6 +160,7 @@ enum pxa_ssp_type { PXA25x_SSP, /* pxa 210, 250, 255, 26x */ PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ PXA27x_SSP, + PXA3xx_SSP, PXA168_SSP, PXA910_SSP, CE4100_SSP, diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 1c2aa7fab3fd..4da5fc55c7ee 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -33,7 +33,6 @@ #include #include -#include #include "../../arm/pxa2xx-pcm.h" #include "pxa-ssp.h" @@ -194,7 +193,7 @@ static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div) { u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); - if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { + if (ssp->type == PXA25x_SSP) { sscr0 &= ~0x0000ff00; sscr0 |= ((div - 2)/2) << 8; /* 2..512 */ } else { @@ -212,7 +211,7 @@ static u32 pxa_ssp_get_scr(struct ssp_device *ssp) u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); u32 div; - if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) + if (ssp->type == PXA25x_SSP) div = ((sscr0 >> 8) & 0xff) * 2 + 2; else div = ((sscr0 >> 8) & 0xfff) + 1; @@ -242,7 +241,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, break; case PXA_SSP_CLK_PLL: /* Internal PLL is fixed */ - if (cpu_is_pxa25x()) + if (ssp->type == PXA25x_SSP) priv->sysclk = 1843200; else priv->sysclk = 13000000; @@ -266,11 +265,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, /* The SSP clock must be disabled when changing SSP clock mode * on PXA2xx. On PXA3xx it must be enabled when doing so. */ - if (!cpu_is_pxa3xx()) + if (ssp->type != PXA3xx_SSP) clk_disable(ssp->clk); val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; pxa_ssp_write_reg(ssp, SSCR0, val); - if (!cpu_is_pxa3xx()) + if (ssp->type != PXA3xx_SSP) clk_enable(ssp->clk); return 0; @@ -294,24 +293,20 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, case PXA_SSP_AUDIO_DIV_SCDB: val = pxa_ssp_read_reg(ssp, SSACD); val &= ~SSACD_SCDB; -#if defined(CONFIG_PXA3xx) - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) val &= ~SSACD_SCDX8; -#endif switch (div) { case PXA_SSP_CLK_SCDB_1: val |= SSACD_SCDB; break; case PXA_SSP_CLK_SCDB_4: break; -#if defined(CONFIG_PXA3xx) case PXA_SSP_CLK_SCDB_8: - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) val |= SSACD_SCDX8; else return -EINVAL; break; -#endif default: return -EINVAL; } @@ -337,10 +332,8 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, struct ssp_device *ssp = priv->ssp; u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; -#if defined(CONFIG_PXA3xx) - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) pxa_ssp_write_reg(ssp, SSACDD, 0); -#endif switch (freq_out) { case 5622000: @@ -365,11 +358,10 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, break; default: -#ifdef CONFIG_PXA3xx /* PXA3xx has a clock ditherer which can be used to generate * a wider range of frequencies - calculate a value for it. */ - if (cpu_is_pxa3xx()) { + if (ssp->type == PXA3xx_SSP) { u32 val; u64 tmp = 19968; tmp *= 1000000; @@ -386,7 +378,6 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, val, freq_out); break; } -#endif return -EINVAL; } @@ -590,10 +581,8 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, /* bit size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: -#ifdef CONFIG_PXA3xx - if (cpu_is_pxa3xx()) + if (ssp->type == PXA3xx_SSP) sscr0 |= SSCR0_FPCKE; -#endif sscr0 |= SSCR0_DataSize(16); break; case SNDRV_PCM_FORMAT_S24_LE: @@ -618,9 +607,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, * trying and failing a lot; some of the registers * needed for that mode are only available on PXA3xx. */ - -#ifdef CONFIG_PXA3xx - if (!cpu_is_pxa3xx()) + if (ssp->type != PXA3xx_SSP) return -EINVAL; sspsp |= SSPSP_SFRMWDTH(width * 2); @@ -628,9 +615,6 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, sspsp |= SSPSP_EDMYSTOP(3); sspsp |= SSPSP_DMYSTOP(3); sspsp |= SSPSP_DMYSTRT(1); -#else - return -EINVAL; -#endif } else { /* The frame width is the width the LRCLK is * asserted for; the delay is expressed in -- GitLab From 433897f7408b556f7dfbb98c94deea02e634d2a7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:38:12 +0800 Subject: [PATCH 1037/6849] ASoC: wm8904: Fix GPIO and MICBIAS initialisation for regmap conversion We no longer have a flat ASoC cache so can't peer directly into the array any more but should instead use the register I/O functions to update the cache. Signed-off-by: Mark Brown Cc: stable@vger.kernel.org (v3.4) --- sound/soc/codecs/wm8904.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 65d525d74c54..4e190b5950ba 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2084,7 +2084,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; - u16 *reg_cache = codec->reg_cache; int ret, i; codec->cache_sync = 1; @@ -2180,14 +2179,18 @@ static int wm8904_probe(struct snd_soc_codec *codec) if (!pdata->gpio_cfg[i]) continue; - reg_cache[WM8904_GPIO_CONTROL_1 + i] - = pdata->gpio_cfg[i] & 0xffff; + regmap_update_bits(wm8904->regmap, + WM8904_GPIO_CONTROL_1 + i, + 0xffff, + pdata->gpio_cfg[i]); } /* Zero is the default value for these anyway */ for (i = 0; i < WM8904_MIC_REGS; i++) - reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] - = pdata->mic_cfg[i]; + regmap_update_bits(wm8904->regmap, + WM8904_MIC_BIAS_CONTROL_0 + i, + 0xffff, + pdata->mic_cfg[i]); } /* Set Class W by default - this will be managed by the Class -- GitLab From c1b88ee2bbb82c56ac24c70850004de9a43915d5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:27:17 +0800 Subject: [PATCH 1038/6849] ASoC: wm8904: Fix cache only management We should be using the regmap API consistently for all the cache only configuration and we should be going cache only before we power down the supplies. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 4e190b5950ba..812acd83fb48 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1863,6 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, return ret; } + regcache_cache_only(wm8904->regmap, false); regcache_sync(wm8904->regmap); /* Enable bias */ @@ -1899,14 +1900,8 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, WM8904_BIAS_ENA, 0); -#ifdef CONFIG_REGULATOR - /* Post 2.6.34 we will be able to get a callback when - * the regulators are disabled which we can use but - * for now just assume that the power will be cut if - * the regulator API is in use. - */ - codec->cache_sync = 1; -#endif + regcache_cache_only(wm8904->regmap, true); + regcache_mark_dirty(wm8904->regmap); regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); @@ -2086,7 +2081,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) struct wm8904_pdata *pdata = wm8904->pdata; int ret, i; - codec->cache_sync = 1; codec->control_data = wm8904->regmap; switch (wm8904->devtype) { @@ -2149,6 +2143,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) goto err_enable; } + regcache_cache_only(wm8904->regmap, true); /* Change some default settings - latch VU and enable ZC */ snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, WM8904_ADC_VU, WM8904_ADC_VU); -- GitLab From 679d7abdc7543e56abc41b8f4858f31a91259b29 Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Thu, 7 Jun 2012 14:00:21 +0200 Subject: [PATCH 1039/6849] ASoC: codecs: Add AB8500 codec-driver Add codec-driver for ST-Ericsson AB8500 mixed-signal ASIC. Signed-off-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/ab8500-codec.c | 2521 +++++++++++++++++++++++++++++++ sound/soc/codecs/ab8500-codec.h | 590 ++++++++ 4 files changed, 3117 insertions(+) create mode 100644 sound/soc/codecs/ab8500-codec.c create mode 100644 sound/soc/codecs/ab8500-codec.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8b879c71c23c..f63776d422b3 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -12,6 +12,7 @@ config SND_SOC_ALL_CODECS tristate "Build all ASoC CODEC drivers" select SND_SOC_88PM860X if MFD_88PM860X select SND_SOC_L3 + select SND_SOC_AB8500_CODEC if ABX500_CORE select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS select SND_SOC_AD1836 if SPI_MASTER select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI @@ -132,6 +133,9 @@ config SND_SOC_WM_HUBS default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m +config SND_SOC_AB8500_CODEC + tristate + config SND_SOC_AC97_CODEC tristate select SND_AC97_CODEC diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index e50811b182a4..fc93b4b0c2c5 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -1,4 +1,5 @@ snd-soc-88pm860x-objs := 88pm860x-codec.o +snd-soc-ab8500-codec-objs := ab8500-codec.o snd-soc-ac97-objs := ac97.o snd-soc-ad1836-objs := ad1836.o snd-soc-ad193x-objs := ad193x.o @@ -109,6 +110,7 @@ snd-soc-max9877-objs := max9877.o snd-soc-tpa6130a2-objs := tpa6130a2.o obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o +obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c new file mode 100644 index 000000000000..95dc7d5bb076 --- /dev/null +++ b/sound/soc/codecs/ab8500-codec.c @@ -0,0 +1,2521 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja , + * Kristoffer Karlsson , + * Roger Nilsson , + * for ST-Ericsson. + * + * Based on the early work done by: + * Mikko J. Lehto , + * Mikko Sarmanne , + * Jarmo K. Kuronen , + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ab8500-codec.h" + +/* Macrocell value definitions */ +#define CLK_32K_OUT2_DISABLE 0x01 +#define INACTIVE_RESET_AUDIO 0x02 +#define ENABLE_AUDIO_CLK_TO_AUDIO_BLK 0x10 +#define ENABLE_VINTCORE12_SUPPLY 0x04 +#define GPIO27_DIR_OUTPUT 0x04 +#define GPIO29_DIR_OUTPUT 0x10 +#define GPIO31_DIR_OUTPUT 0x40 + +/* Macrocell register definitions */ +#define AB8500_CTRL3_REG 0x0200 +#define AB8500_GPIO_DIR4_REG 0x1013 + +/* Nr of FIR/IIR-coeff banks in ANC-block */ +#define AB8500_NR_OF_ANC_COEFF_BANKS 2 + +/* Minimum duration to keep ANC IIR Init bit high or +low before proceeding with the configuration sequence */ +#define AB8500_ANC_SM_DELAY 2000 + +#define AB8500_FILTER_CONTROL(xname, xcount, xmin, xmax) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .info = filter_control_info, \ + .get = filter_control_get, .put = filter_control_put, \ + .private_value = (unsigned long)&(struct filter_control) \ + {.count = xcount, .min = xmin, .max = xmax} } + +struct filter_control { + long min, max; + unsigned int count; + long value[128]; +}; + +/* Sidetone states */ +static const char * const enum_sid_state[] = { + "Unconfigured", + "Apply FIR", + "FIR is configured", +}; +enum sid_state { + SID_UNCONFIGURED = 0, + SID_APPLY_FIR = 1, + SID_FIR_CONFIGURED = 2, +}; + +static const char * const enum_anc_state[] = { + "Unconfigured", + "Apply FIR and IIR", + "FIR and IIR are configured", + "Apply FIR", + "FIR is configured", + "Apply IIR", + "IIR is configured" +}; +enum anc_state { + ANC_UNCONFIGURED = 0, + ANC_APPLY_FIR_IIR = 1, + ANC_FIR_IIR_CONFIGURED = 2, + ANC_APPLY_FIR = 3, + ANC_FIR_CONFIGURED = 4, + ANC_APPLY_IIR = 5, + ANC_IIR_CONFIGURED = 6 +}; + +/* Analog microphones */ +enum amic_idx { + AMIC_IDX_1A, + AMIC_IDX_1B, + AMIC_IDX_2 +}; + +struct ab8500_codec_drvdata_dbg { + struct regulator *vaud; + struct regulator *vamic1; + struct regulator *vamic2; + struct regulator *vdmic; +}; + +/* Private data for AB8500 device-driver */ +struct ab8500_codec_drvdata { + /* Sidetone */ + long *sid_fir_values; + enum sid_state sid_status; + + /* ANC */ + struct mutex anc_lock; + long *anc_fir_values; + long *anc_iir_values; + enum anc_state anc_status; +}; + +static inline const char *amic_micbias_str(enum amic_micbias micbias) +{ + switch (micbias) { + case AMIC_MICBIAS_VAMIC1: + return "VAMIC1"; + case AMIC_MICBIAS_VAMIC2: + return "VAMIC2"; + default: + return "Unknown"; + } +} + +static inline const char *amic_type_str(enum amic_type type) +{ + switch (type) { + case AMIC_TYPE_DIFFERENTIAL: + return "DIFFERENTIAL"; + case AMIC_TYPE_SINGLE_ENDED: + return "SINGLE ENDED"; + default: + return "Unknown"; + } +} + +/* + * Read'n'write functions + */ + +/* Read a register from the audio-bank of AB8500 */ +static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec, + unsigned int reg) +{ + int status; + unsigned int value = 0; + + u8 value8; + status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO, + reg, &value8); + if (status < 0) { + dev_err(codec->dev, + "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n", + __func__, (u8)AB8500_AUDIO, (u8)reg, status); + } else { + dev_dbg(codec->dev, + "%s: Read 0x%02x from register 0x%02x:0x%02x\n", + __func__, value8, (u8)AB8500_AUDIO, (u8)reg); + value = (unsigned int)value8; + } + + return value; +} + +/* Write to a register in the audio-bank of AB8500 */ +static int ab8500_codec_write_reg(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int status; + + status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO, + reg, value); + if (status < 0) + dev_err(codec->dev, + "%s: ERROR: Register (%02x:%02x) write failed (%d).\n", + __func__, (u8)AB8500_AUDIO, (u8)reg, status); + else + dev_dbg(codec->dev, + "%s: Wrote 0x%02x into register %02x:%02x\n", + __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg); + + return status; +} + +/* + * Controls - DAPM + */ + +/* Earpiece */ + +/* Earpiece source selector */ +static const char * const enum_ear_lineout_source[] = {"Headset Left", + "Speaker Left"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_ear_lineout_source, AB8500_DMICFILTCONF, + AB8500_DMICFILTCONF_DA3TOEAR, enum_ear_lineout_source); +static const struct snd_kcontrol_new dapm_ear_lineout_source = + SOC_DAPM_ENUM("Earpiece or LineOut Mono Source", + dapm_enum_ear_lineout_source); + +/* LineOut */ + +/* LineOut source selector */ +static const char * const enum_lineout_source[] = {"Mono Path", "Stereo Path"}; +static SOC_ENUM_DOUBLE_DECL(dapm_enum_lineout_source, AB8500_ANACONF5, + AB8500_ANACONF5_HSLDACTOLOL, + AB8500_ANACONF5_HSRDACTOLOR, enum_lineout_source); +static const struct snd_kcontrol_new dapm_lineout_source[] = { + SOC_DAPM_ENUM("LineOut Source", dapm_enum_lineout_source), +}; + +/* Handsfree */ + +/* Speaker Left - ANC selector */ +static const char * const enum_HFx_sel[] = {"Audio Path", "ANC"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_HFl_sel, AB8500_DIGMULTCONF2, + AB8500_DIGMULTCONF2_HFLSEL, enum_HFx_sel); +static const struct snd_kcontrol_new dapm_HFl_select[] = { + SOC_DAPM_ENUM("Speaker Left Source", dapm_enum_HFl_sel), +}; + +/* Speaker Right - ANC selector */ +static SOC_ENUM_SINGLE_DECL(dapm_enum_HFr_sel, AB8500_DIGMULTCONF2, + AB8500_DIGMULTCONF2_HFRSEL, enum_HFx_sel); +static const struct snd_kcontrol_new dapm_HFr_select[] = { + SOC_DAPM_ENUM("Speaker Right Source", dapm_enum_HFr_sel), +}; + +/* Mic 1 */ + +/* Mic 1 - Mic 1a or 1b selector */ +static const char * const enum_mic1ab_sel[] = {"Mic 1b", "Mic 1a"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_mic1ab_sel, AB8500_ANACONF3, + AB8500_ANACONF3_MIC1SEL, enum_mic1ab_sel); +static const struct snd_kcontrol_new dapm_mic1ab_mux[] = { + SOC_DAPM_ENUM("Mic 1a or 1b Select", dapm_enum_mic1ab_sel), +}; + +/* Mic 1 - AD3 - Mic 1 or DMic 3 selector */ +static const char * const enum_ad3_sel[] = {"Mic 1", "DMic 3"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_ad3_sel, AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_AD3SEL, enum_ad3_sel); +static const struct snd_kcontrol_new dapm_ad3_select[] = { + SOC_DAPM_ENUM("AD3 Source Select", dapm_enum_ad3_sel), +}; + +/* Mic 1 - AD6 - Mic 1 or DMic 6 selector */ +static const char * const enum_ad6_sel[] = {"Mic 1", "DMic 6"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_ad6_sel, AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_AD6SEL, enum_ad6_sel); +static const struct snd_kcontrol_new dapm_ad6_select[] = { + SOC_DAPM_ENUM("AD6 Source Select", dapm_enum_ad6_sel), +}; + +/* Mic 2 */ + +/* Mic 2 - AD5 - Mic 2 or DMic 5 selector */ +static const char * const enum_ad5_sel[] = {"Mic 2", "DMic 5"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_ad5_sel, AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_AD5SEL, enum_ad5_sel); +static const struct snd_kcontrol_new dapm_ad5_select[] = { + SOC_DAPM_ENUM("AD5 Source Select", dapm_enum_ad5_sel), +}; + +/* LineIn */ + +/* LineIn left - AD1 - LineIn Left or DMic 1 selector */ +static const char * const enum_ad1_sel[] = {"LineIn Left", "DMic 1"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_ad1_sel, AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_AD1SEL, enum_ad1_sel); +static const struct snd_kcontrol_new dapm_ad1_select[] = { + SOC_DAPM_ENUM("AD1 Source Select", dapm_enum_ad1_sel), +}; + +/* LineIn right - Mic 2 or LineIn Right selector */ +static const char * const enum_mic2lr_sel[] = {"Mic 2", "LineIn Right"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_mic2lr_sel, AB8500_ANACONF3, + AB8500_ANACONF3_LINRSEL, enum_mic2lr_sel); +static const struct snd_kcontrol_new dapm_mic2lr_select[] = { + SOC_DAPM_ENUM("Mic 2 or LINR Select", dapm_enum_mic2lr_sel), +}; + +/* LineIn right - AD2 - LineIn Right or DMic2 selector */ +static const char * const enum_ad2_sel[] = {"LineIn Right", "DMic 2"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_ad2_sel, AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_AD2SEL, enum_ad2_sel); +static const struct snd_kcontrol_new dapm_ad2_select[] = { + SOC_DAPM_ENUM("AD2 Source Select", dapm_enum_ad2_sel), +}; + + +/* ANC */ + +static const char * const enum_anc_in_sel[] = {"Mic 1 / DMic 6", + "Mic 2 / DMic 5"}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_in_sel, AB8500_DMICFILTCONF, + AB8500_DMICFILTCONF_ANCINSEL, enum_anc_in_sel); +static const struct snd_kcontrol_new dapm_anc_in_select[] = { + SOC_DAPM_ENUM("ANC Source", dapm_enum_anc_in_sel), +}; + +/* ANC - Enable/Disable */ +static const struct snd_kcontrol_new dapm_anc_enable[] = { + SOC_DAPM_SINGLE("Switch", AB8500_ANCCONF1, + AB8500_ANCCONF1_ENANC, 0, 0), +}; + +/* ANC to Earpiece - Mute */ +static const struct snd_kcontrol_new dapm_anc_ear_mute[] = { + SOC_DAPM_SINGLE("Switch", AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_ANCSEL, 1, 0), +}; + + + +/* Sidetone left */ + +/* Sidetone left - Input selector */ +static const char * const enum_stfir1_in_sel[] = { + "LineIn Left", "LineIn Right", "Mic 1", "Headset Left" +}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir1_in_sel, AB8500_DIGMULTCONF2, + AB8500_DIGMULTCONF2_FIRSID1SEL, enum_stfir1_in_sel); +static const struct snd_kcontrol_new dapm_stfir1_in_select[] = { + SOC_DAPM_ENUM("Sidetone Left Source", dapm_enum_stfir1_in_sel), +}; + +/* Sidetone right path */ + +/* Sidetone right - Input selector */ +static const char * const enum_stfir2_in_sel[] = { + "LineIn Right", "Mic 1", "DMic 4", "Headset Right" +}; +static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir2_in_sel, AB8500_DIGMULTCONF2, + AB8500_DIGMULTCONF2_FIRSID2SEL, enum_stfir2_in_sel); +static const struct snd_kcontrol_new dapm_stfir2_in_select[] = { + SOC_DAPM_ENUM("Sidetone Right Source", dapm_enum_stfir2_in_sel), +}; + +/* Vibra */ + +static const char * const enum_pwm2vibx[] = {"Audio Path", "PWM Generator"}; + +static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib1, AB8500_PWMGENCONF1, + AB8500_PWMGENCONF1_PWMTOVIB1, enum_pwm2vibx); + +static const struct snd_kcontrol_new dapm_pwm2vib1[] = { + SOC_DAPM_ENUM("Vibra 1 Controller", dapm_enum_pwm2vib1), +}; + +static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib2, AB8500_PWMGENCONF1, + AB8500_PWMGENCONF1_PWMTOVIB2, enum_pwm2vibx); + +static const struct snd_kcontrol_new dapm_pwm2vib2[] = { + SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2), +}; + +/* + * DAPM-widgets + */ + +static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { + + /* Clocks */ + SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"), + + /* Regulators */ + SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0), + SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0), + SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0), + SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0), + + /* Power */ + SND_SOC_DAPM_SUPPLY("Audio Power", + AB8500_POWERUP, AB8500_POWERUP_POWERUP, 0, + NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("Audio Analog Power", + AB8500_POWERUP, AB8500_POWERUP_ENANA, 0, + NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* Main supply node */ + SND_SOC_DAPM_SUPPLY("Main Supply", SND_SOC_NOPM, 0, 0, + NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* DA/AD */ + + SND_SOC_DAPM_INPUT("ADC Input"), + SND_SOC_DAPM_ADC("ADC", "ab8500_0c", SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_OUTPUT("DAC Output"), + + SND_SOC_DAPM_AIF_IN("DA_IN1", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("DA_IN2", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("DA_IN3", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("DA_IN4", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("DA_IN5", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("DA_IN6", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AD_OUT1", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AD_OUT2", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AD_OUT3", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AD_OUT57", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AD_OUT68", NULL, 0, SND_SOC_NOPM, 0, 0), + + /* Headset path */ + + SND_SOC_DAPM_SUPPLY("Charge Pump", AB8500_ANACONF5, + AB8500_ANACONF5_ENCPHS, 0, NULL, 0), + + SND_SOC_DAPM_DAC("DA1 Enable", "ab8500_0p", + AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA1, 0), + SND_SOC_DAPM_DAC("DA2 Enable", "ab8500_0p", + AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA2, 0), + + SND_SOC_DAPM_PGA("HSL Digital Volume", SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_PGA("HSR Digital Volume", SND_SOC_NOPM, 0, 0, + NULL, 0), + + SND_SOC_DAPM_DAC("HSL DAC", "ab8500_0p", + AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSL, 0), + SND_SOC_DAPM_DAC("HSR DAC", "ab8500_0p", + AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSR, 0), + SND_SOC_DAPM_MIXER("HSL DAC Mute", AB8500_MUTECONF, + AB8500_MUTECONF_MUTDACHSL, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("HSR DAC Mute", AB8500_MUTECONF, + AB8500_MUTECONF_MUTDACHSR, 1, + NULL, 0), + SND_SOC_DAPM_DAC("HSL DAC Driver", "ab8500_0p", + AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSL, 0), + SND_SOC_DAPM_DAC("HSR DAC Driver", "ab8500_0p", + AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSR, 0), + + SND_SOC_DAPM_MIXER("HSL Mute", + AB8500_MUTECONF, AB8500_MUTECONF_MUTHSL, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("HSR Mute", + AB8500_MUTECONF, AB8500_MUTECONF_MUTHSR, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("HSL Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENHSL, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("HSR Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENHSR, 0, + NULL, 0), + SND_SOC_DAPM_PGA("HSL Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_PGA("HSR Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + + SND_SOC_DAPM_OUTPUT("Headset Left"), + SND_SOC_DAPM_OUTPUT("Headset Right"), + + /* LineOut path */ + + SND_SOC_DAPM_MUX("LineOut Source", + SND_SOC_NOPM, 0, 0, dapm_lineout_source), + + SND_SOC_DAPM_MIXER("LOL Disable HFL", + AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("LOR Disable HFR", + AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 1, + NULL, 0), + + SND_SOC_DAPM_MIXER("LOL Enable", + AB8500_ANACONF5, AB8500_ANACONF5_ENLOL, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("LOR Enable", + AB8500_ANACONF5, AB8500_ANACONF5_ENLOR, 0, + NULL, 0), + + SND_SOC_DAPM_OUTPUT("LineOut Left"), + SND_SOC_DAPM_OUTPUT("LineOut Right"), + + /* Earpiece path */ + + SND_SOC_DAPM_MUX("Earpiece or LineOut Mono Source", + SND_SOC_NOPM, 0, 0, &dapm_ear_lineout_source), + SND_SOC_DAPM_MIXER("EAR DAC", + AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACEAR, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("EAR Mute", + AB8500_MUTECONF, AB8500_MUTECONF_MUTEAR, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("EAR Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENEAR, 0, + NULL, 0), + + SND_SOC_DAPM_OUTPUT("Earpiece"), + + /* Handsfree path */ + + SND_SOC_DAPM_MIXER("DA3 Channel Volume", + AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA3, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DA4 Channel Volume", + AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA4, 0, + NULL, 0), + SND_SOC_DAPM_MUX("Speaker Left Source", + SND_SOC_NOPM, 0, 0, dapm_HFl_select), + SND_SOC_DAPM_MUX("Speaker Right Source", + SND_SOC_NOPM, 0, 0, dapm_HFr_select), + SND_SOC_DAPM_MIXER("HFL DAC", AB8500_DAPATHCONF, + AB8500_DAPATHCONF_ENDACHFL, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("HFR DAC", + AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHFR, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DA4 or ANC path to HfR", + AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFREN, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DA3 or ANC path to HfL", + AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFLEN, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("HFL Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("HFR Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 0, + NULL, 0), + + SND_SOC_DAPM_OUTPUT("Speaker Left"), + SND_SOC_DAPM_OUTPUT("Speaker Right"), + + /* Vibrator path */ + + SND_SOC_DAPM_INPUT("PWMGEN1"), + SND_SOC_DAPM_INPUT("PWMGEN2"), + + SND_SOC_DAPM_MIXER("DA5 Channel Volume", + AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA5, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DA6 Channel Volume", + AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA6, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("VIB1 DAC", + AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB1, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("VIB2 DAC", + AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB2, 0, + NULL, 0), + SND_SOC_DAPM_MUX("Vibra 1 Controller", + SND_SOC_NOPM, 0, 0, dapm_pwm2vib1), + SND_SOC_DAPM_MUX("Vibra 2 Controller", + SND_SOC_NOPM, 0, 0, dapm_pwm2vib2), + SND_SOC_DAPM_MIXER("VIB1 Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENVIB1, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("VIB2 Enable", + AB8500_ANACONF4, AB8500_ANACONF4_ENVIB2, 0, + NULL, 0), + + SND_SOC_DAPM_OUTPUT("Vibra 1"), + SND_SOC_DAPM_OUTPUT("Vibra 2"), + + /* Mic 1 */ + + SND_SOC_DAPM_INPUT("Mic 1"), + + SND_SOC_DAPM_MUX("Mic 1a or 1b Select", + SND_SOC_NOPM, 0, 0, dapm_mic1ab_mux), + SND_SOC_DAPM_MIXER("MIC1 Mute", + AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC1, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("MIC1A V-AMICx Enable", + AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("MIC1B V-AMICx Enable", + AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("MIC1 ADC", + AB8500_ANACONF3, AB8500_ANACONF3_ENADCMIC, 0, + NULL, 0), + SND_SOC_DAPM_MUX("AD3 Source Select", + SND_SOC_NOPM, 0, 0, dapm_ad3_select), + SND_SOC_DAPM_MIXER("AD3 Channel Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD3 Enable", + AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, 0, + NULL, 0), + + /* Mic 2 */ + + SND_SOC_DAPM_INPUT("Mic 2"), + + SND_SOC_DAPM_MIXER("MIC2 Mute", + AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC2, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("MIC2 V-AMICx Enable", AB8500_ANACONF2, + AB8500_ANACONF2_ENMIC2, 0, + NULL, 0), + + /* LineIn */ + + SND_SOC_DAPM_INPUT("LineIn Left"), + SND_SOC_DAPM_INPUT("LineIn Right"), + + SND_SOC_DAPM_MIXER("LINL Mute", + AB8500_ANACONF2, AB8500_ANACONF2_MUTLINL, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("LINR Mute", + AB8500_ANACONF2, AB8500_ANACONF2_MUTLINR, 1, + NULL, 0), + SND_SOC_DAPM_MIXER("LINL Enable", AB8500_ANACONF2, + AB8500_ANACONF2_ENLINL, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("LINR Enable", AB8500_ANACONF2, + AB8500_ANACONF2_ENLINR, 0, + NULL, 0), + + /* LineIn Bypass path */ + SND_SOC_DAPM_MIXER("LINL to HSL Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("LINR to HSR Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + + /* LineIn, Mic 2 */ + SND_SOC_DAPM_MUX("Mic 2 or LINR Select", + SND_SOC_NOPM, 0, 0, dapm_mic2lr_select), + SND_SOC_DAPM_MIXER("LINL ADC", AB8500_ANACONF3, + AB8500_ANACONF3_ENADCLINL, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("LINR ADC", AB8500_ANACONF3, + AB8500_ANACONF3_ENADCLINR, 0, + NULL, 0), + SND_SOC_DAPM_MUX("AD1 Source Select", + SND_SOC_NOPM, 0, 0, dapm_ad1_select), + SND_SOC_DAPM_MUX("AD2 Source Select", + SND_SOC_NOPM, 0, 0, dapm_ad2_select), + SND_SOC_DAPM_MIXER("AD1 Channel Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD2 Channel Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + + SND_SOC_DAPM_MIXER("AD12 Enable", + AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD12, 0, + NULL, 0), + + /* HD Capture path */ + + SND_SOC_DAPM_MUX("AD5 Source Select", + SND_SOC_NOPM, 0, 0, dapm_ad5_select), + SND_SOC_DAPM_MUX("AD6 Source Select", + SND_SOC_NOPM, 0, 0, dapm_ad6_select), + SND_SOC_DAPM_MIXER("AD5 Channel Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD6 Channel Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD57 Enable", + AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD68 Enable", + AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0, + NULL, 0), + + /* Digital Microphone path */ + + SND_SOC_DAPM_INPUT("DMic 1"), + SND_SOC_DAPM_INPUT("DMic 2"), + SND_SOC_DAPM_INPUT("DMic 3"), + SND_SOC_DAPM_INPUT("DMic 4"), + SND_SOC_DAPM_INPUT("DMic 5"), + SND_SOC_DAPM_INPUT("DMic 6"), + + SND_SOC_DAPM_MIXER("DMIC1", + AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DMIC2", + AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DMIC3", + AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DMIC4", + AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DMIC5", + AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("DMIC6", + AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD4 Channel Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("AD4 Enable", + AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, + 0, NULL, 0), + + /* Acoustical Noise Cancellation path */ + + SND_SOC_DAPM_INPUT("ANC Configure Input"), + SND_SOC_DAPM_OUTPUT("ANC Configure Output"), + + SND_SOC_DAPM_MUX("ANC Source", + SND_SOC_NOPM, 0, 0, + dapm_anc_in_select), + SND_SOC_DAPM_SWITCH("ANC", + SND_SOC_NOPM, 0, 0, + dapm_anc_enable), + SND_SOC_DAPM_SWITCH("ANC to Earpiece", + SND_SOC_NOPM, 0, 0, + dapm_anc_ear_mute), + + /* Sidetone Filter path */ + + SND_SOC_DAPM_MUX("Sidetone Left Source", + SND_SOC_NOPM, 0, 0, + dapm_stfir1_in_select), + SND_SOC_DAPM_MUX("Sidetone Right Source", + SND_SOC_NOPM, 0, 0, + dapm_stfir2_in_select), + SND_SOC_DAPM_MIXER("STFIR1 Control", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("STFIR2 Control", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("STFIR1 Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_MIXER("STFIR2 Volume", + SND_SOC_NOPM, 0, 0, + NULL, 0), +}; + +/* + * DAPM-routes + */ +static const struct snd_soc_dapm_route ab8500_dapm_routes[] = { + /* Power AB8500 audio-block when AD/DA is active */ + {"Main Supply", NULL, "V-AUD"}, + {"Main Supply", NULL, "audioclk"}, + {"Main Supply", NULL, "Audio Power"}, + {"Main Supply", NULL, "Audio Analog Power"}, + + {"DAC", NULL, "ab8500_0p"}, + {"DAC", NULL, "Main Supply"}, + {"ADC", NULL, "ab8500_0c"}, + {"ADC", NULL, "Main Supply"}, + + /* ANC Configure */ + {"ANC Configure Input", NULL, "Main Supply"}, + {"ANC Configure Output", NULL, "ANC Configure Input"}, + + /* AD/DA */ + {"ADC", NULL, "ADC Input"}, + {"DAC Output", NULL, "DAC"}, + + /* Powerup charge pump if DA1/2 is in use */ + + {"DA_IN1", NULL, "ab8500_0p"}, + {"DA_IN1", NULL, "Charge Pump"}, + {"DA_IN2", NULL, "ab8500_0p"}, + {"DA_IN2", NULL, "Charge Pump"}, + + /* Headset path */ + + {"DA1 Enable", NULL, "DA_IN1"}, + {"DA2 Enable", NULL, "DA_IN2"}, + + {"HSL Digital Volume", NULL, "DA1 Enable"}, + {"HSR Digital Volume", NULL, "DA2 Enable"}, + + {"HSL DAC", NULL, "HSL Digital Volume"}, + {"HSR DAC", NULL, "HSR Digital Volume"}, + + {"HSL DAC Mute", NULL, "HSL DAC"}, + {"HSR DAC Mute", NULL, "HSR DAC"}, + + {"HSL DAC Driver", NULL, "HSL DAC Mute"}, + {"HSR DAC Driver", NULL, "HSR DAC Mute"}, + + {"HSL Mute", NULL, "HSL DAC Driver"}, + {"HSR Mute", NULL, "HSR DAC Driver"}, + + {"HSL Enable", NULL, "HSL Mute"}, + {"HSR Enable", NULL, "HSR Mute"}, + + {"HSL Volume", NULL, "HSL Enable"}, + {"HSR Volume", NULL, "HSR Enable"}, + + {"Headset Left", NULL, "HSL Volume"}, + {"Headset Right", NULL, "HSR Volume"}, + + /* HF or LineOut path */ + + {"DA_IN3", NULL, "ab8500_0p"}, + {"DA3 Channel Volume", NULL, "DA_IN3"}, + {"DA_IN4", NULL, "ab8500_0p"}, + {"DA4 Channel Volume", NULL, "DA_IN4"}, + + {"Speaker Left Source", "Audio Path", "DA3 Channel Volume"}, + {"Speaker Right Source", "Audio Path", "DA4 Channel Volume"}, + + {"DA3 or ANC path to HfL", NULL, "Speaker Left Source"}, + {"DA4 or ANC path to HfR", NULL, "Speaker Right Source"}, + + /* HF path */ + + {"HFL DAC", NULL, "DA3 or ANC path to HfL"}, + {"HFR DAC", NULL, "DA4 or ANC path to HfR"}, + + {"HFL Enable", NULL, "HFL DAC"}, + {"HFR Enable", NULL, "HFR DAC"}, + + {"Speaker Left", NULL, "HFL Enable"}, + {"Speaker Right", NULL, "HFR Enable"}, + + /* Earpiece path */ + + {"Earpiece or LineOut Mono Source", "Headset Left", + "HSL Digital Volume"}, + {"Earpiece or LineOut Mono Source", "Speaker Left", + "DA3 or ANC path to HfL"}, + + {"EAR DAC", NULL, "Earpiece or LineOut Mono Source"}, + + {"EAR Mute", NULL, "EAR DAC"}, + + {"EAR Enable", NULL, "EAR Mute"}, + + {"Earpiece", NULL, "EAR Enable"}, + + /* LineOut path stereo */ + + {"LineOut Source", "Stereo Path", "HSL DAC Driver"}, + {"LineOut Source", "Stereo Path", "HSR DAC Driver"}, + + /* LineOut path mono */ + + {"LineOut Source", "Mono Path", "EAR DAC"}, + + /* LineOut path */ + + {"LOL Disable HFL", NULL, "LineOut Source"}, + {"LOR Disable HFR", NULL, "LineOut Source"}, + + {"LOL Enable", NULL, "LOL Disable HFL"}, + {"LOR Enable", NULL, "LOR Disable HFR"}, + + {"LineOut Left", NULL, "LOL Enable"}, + {"LineOut Right", NULL, "LOR Enable"}, + + /* Vibrator path */ + + {"DA_IN5", NULL, "ab8500_0p"}, + {"DA5 Channel Volume", NULL, "DA_IN5"}, + {"DA_IN6", NULL, "ab8500_0p"}, + {"DA6 Channel Volume", NULL, "DA_IN6"}, + + {"VIB1 DAC", NULL, "DA5 Channel Volume"}, + {"VIB2 DAC", NULL, "DA6 Channel Volume"}, + + {"Vibra 1 Controller", "Audio Path", "VIB1 DAC"}, + {"Vibra 2 Controller", "Audio Path", "VIB2 DAC"}, + {"Vibra 1 Controller", "PWM Generator", "PWMGEN1"}, + {"Vibra 2 Controller", "PWM Generator", "PWMGEN2"}, + + {"VIB1 Enable", NULL, "Vibra 1 Controller"}, + {"VIB2 Enable", NULL, "Vibra 2 Controller"}, + + {"Vibra 1", NULL, "VIB1 Enable"}, + {"Vibra 2", NULL, "VIB2 Enable"}, + + + /* Mic 2 */ + + {"MIC2 V-AMICx Enable", NULL, "Mic 2"}, + + /* LineIn */ + {"LINL Mute", NULL, "LineIn Left"}, + {"LINR Mute", NULL, "LineIn Right"}, + + {"LINL Enable", NULL, "LINL Mute"}, + {"LINR Enable", NULL, "LINR Mute"}, + + /* LineIn, Mic 2 */ + {"Mic 2 or LINR Select", "LineIn Right", "LINR Enable"}, + {"Mic 2 or LINR Select", "Mic 2", "MIC2 V-AMICx Enable"}, + + {"LINL ADC", NULL, "LINL Enable"}, + {"LINR ADC", NULL, "Mic 2 or LINR Select"}, + + {"AD1 Source Select", "LineIn Left", "LINL ADC"}, + {"AD2 Source Select", "LineIn Right", "LINR ADC"}, + + {"AD1 Channel Volume", NULL, "AD1 Source Select"}, + {"AD2 Channel Volume", NULL, "AD2 Source Select"}, + + {"AD12 Enable", NULL, "AD1 Channel Volume"}, + {"AD12 Enable", NULL, "AD2 Channel Volume"}, + + {"AD_OUT1", NULL, "ab8500_0c"}, + {"AD_OUT1", NULL, "AD12 Enable"}, + {"AD_OUT2", NULL, "ab8500_0c"}, + {"AD_OUT2", NULL, "AD12 Enable"}, + + /* Mic 1 */ + + {"MIC1 Mute", NULL, "Mic 1"}, + + {"MIC1A V-AMICx Enable", NULL, "MIC1 Mute"}, + {"MIC1B V-AMICx Enable", NULL, "MIC1 Mute"}, + + {"Mic 1a or 1b Select", "Mic 1a", "MIC1A V-AMICx Enable"}, + {"Mic 1a or 1b Select", "Mic 1b", "MIC1B V-AMICx Enable"}, + + {"MIC1 ADC", NULL, "Mic 1a or 1b Select"}, + + {"AD3 Source Select", "Mic 1", "MIC1 ADC"}, + + {"AD3 Channel Volume", NULL, "AD3 Source Select"}, + + {"AD3 Enable", NULL, "AD3 Channel Volume"}, + + {"AD_OUT3", NULL, "ab8500_0c"}, + {"AD_OUT3", NULL, "AD3 Enable"}, + + /* HD Capture path */ + + {"AD5 Source Select", "Mic 2", "LINR ADC"}, + {"AD6 Source Select", "Mic 1", "MIC1 ADC"}, + + {"AD5 Channel Volume", NULL, "AD5 Source Select"}, + {"AD6 Channel Volume", NULL, "AD6 Source Select"}, + + {"AD57 Enable", NULL, "AD5 Channel Volume"}, + {"AD68 Enable", NULL, "AD6 Channel Volume"}, + + {"AD_OUT57", NULL, "ab8500_0c"}, + {"AD_OUT57", NULL, "AD57 Enable"}, + {"AD_OUT68", NULL, "ab8500_0c"}, + {"AD_OUT68", NULL, "AD68 Enable"}, + + /* Digital Microphone path */ + + {"DMic 1", NULL, "V-DMIC"}, + {"DMic 2", NULL, "V-DMIC"}, + {"DMic 3", NULL, "V-DMIC"}, + {"DMic 4", NULL, "V-DMIC"}, + {"DMic 5", NULL, "V-DMIC"}, + {"DMic 6", NULL, "V-DMIC"}, + + {"AD1 Source Select", NULL, "DMic 1"}, + {"AD2 Source Select", NULL, "DMic 2"}, + {"AD3 Source Select", NULL, "DMic 3"}, + {"AD5 Source Select", NULL, "DMic 5"}, + {"AD6 Source Select", NULL, "DMic 6"}, + + {"AD4 Channel Volume", NULL, "DMic 4"}, + {"AD4 Enable", NULL, "AD4 Channel Volume"}, + + {"AD_OUT4", NULL, "ab8500_0c"}, + {"AD_OUT4", NULL, "AD4 Enable"}, + + /* LineIn Bypass path */ + + {"LINL to HSL Volume", NULL, "LINL Enable"}, + {"LINR to HSR Volume", NULL, "LINR Enable"}, + + {"HSL DAC Driver", NULL, "LINL to HSL Volume"}, + {"HSR DAC Driver", NULL, "LINR to HSR Volume"}, + + /* ANC path (Acoustic Noise Cancellation) */ + + {"ANC Source", "Mic 2 / DMic 5", "AD5 Channel Volume"}, + {"ANC Source", "Mic 1 / DMic 6", "AD6 Channel Volume"}, + + {"ANC", "Switch", "ANC Source"}, + + {"Speaker Left Source", "ANC", "ANC"}, + {"Speaker Right Source", "ANC", "ANC"}, + {"ANC to Earpiece", "Switch", "ANC"}, + + {"HSL Digital Volume", NULL, "ANC to Earpiece"}, + + /* Sidetone Filter path */ + + {"Sidetone Left Source", "LineIn Left", "AD12 Enable"}, + {"Sidetone Left Source", "LineIn Right", "AD12 Enable"}, + {"Sidetone Left Source", "Mic 1", "AD3 Enable"}, + {"Sidetone Left Source", "Headset Left", "DA_IN1"}, + {"Sidetone Right Source", "LineIn Right", "AD12 Enable"}, + {"Sidetone Right Source", "Mic 1", "AD3 Enable"}, + {"Sidetone Right Source", "DMic 4", "AD4 Enable"}, + {"Sidetone Right Source", "Headset Right", "DA_IN2"}, + + {"STFIR1 Control", NULL, "Sidetone Left Source"}, + {"STFIR2 Control", NULL, "Sidetone Right Source"}, + + {"STFIR1 Volume", NULL, "STFIR1 Control"}, + {"STFIR2 Volume", NULL, "STFIR2 Control"}, + + {"DA1 Enable", NULL, "STFIR1 Volume"}, + {"DA2 Enable", NULL, "STFIR2 Volume"}, +}; + +static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1a_vamicx[] = { + {"MIC1A V-AMICx Enable", NULL, "V-AMIC1"}, + {"MIC1A V-AMICx Enable", NULL, "V-AMIC2"}, +}; + +static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1b_vamicx[] = { + {"MIC1B V-AMICx Enable", NULL, "V-AMIC1"}, + {"MIC1B V-AMICx Enable", NULL, "V-AMIC2"}, +}; + +static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = { + {"MIC2 V-AMICx Enable", NULL, "V-AMIC1"}, + {"MIC2 V-AMICx Enable", NULL, "V-AMIC2"}, +}; + +/* ANC FIR-coefficients configuration sequence */ +static void anc_fir(struct snd_soc_codec *codec, + unsigned int bnk, unsigned int par, unsigned int val) +{ + if (par == 0 && bnk == 0) + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ANCFIRUPDATE), + BIT(AB8500_ANCCONF1_ANCFIRUPDATE)); + + snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff); + snd_soc_write(codec, AB8500_ANCCONF6, val & 0xff); + + if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1) + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0); +} + +/* ANC IIR-coefficients configuration sequence */ +static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk, + unsigned int par, unsigned int val) +{ + if (par == 0) { + if (bnk == 0) { + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ANCIIRINIT), + BIT(AB8500_ANCCONF1_ANCIIRINIT)); + usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY); + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ANCIIRINIT), 0); + usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY); + } else { + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ANCIIRUPDATE), + BIT(AB8500_ANCCONF1_ANCIIRUPDATE)); + } + } else if (par > 3) { + snd_soc_write(codec, AB8500_ANCCONF7, 0); + snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff); + } + + snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff); + snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff); + + if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1) + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0); +} + +/* ANC IIR-/FIR-coefficients configuration sequence */ +static void anc_configure(struct snd_soc_codec *codec, + bool apply_fir, bool apply_iir) +{ + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); + unsigned int bnk, par, val; + + dev_dbg(codec->dev, "%s: Enter.\n", __func__); + + if (apply_fir) + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ENANC), 0); + + snd_soc_update_bits(codec, AB8500_ANCCONF1, + BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC)); + + if (apply_fir) + for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++) + for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) { + val = snd_soc_read(codec, + drvdata->anc_fir_values[par]); + anc_fir(codec, bnk, par, val); + } + + if (apply_iir) + for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++) + for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) { + val = snd_soc_read(codec, + drvdata->anc_iir_values[par]); + anc_iir(codec, bnk, par, val); + } + + dev_dbg(codec->dev, "%s: Exit.\n", __func__); +} + +/* + * Control-events + */ + +static int sid_status_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); + + mutex_lock(&codec->mutex); + ucontrol->value.integer.value[0] = drvdata->sid_status; + mutex_unlock(&codec->mutex); + + return 0; +} + +/* Write sidetone FIR-coefficients configuration sequence */ +static int sid_status_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); + unsigned int param, sidconf, val; + int status = 1; + + dev_dbg(codec->dev, "%s: Enter\n", __func__); + + if (ucontrol->value.integer.value[0] != SID_APPLY_FIR) { + dev_err(codec->dev, + "%s: ERROR: This control supports '%s' only!\n", + __func__, enum_sid_state[SID_APPLY_FIR]); + return -EIO; + } + + mutex_lock(&codec->mutex); + + sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF); + if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) { + if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) { + dev_err(codec->dev, "%s: Sidetone busy while off!\n", + __func__); + status = -EPERM; + } else { + status = -EBUSY; + } + goto out; + } + + snd_soc_write(codec, AB8500_SIDFIRADR, 0); + + for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) { + val = snd_soc_read(codec, drvdata->sid_fir_values[param]); + snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff); + snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff); + } + + snd_soc_update_bits(codec, AB8500_SIDFIRADR, + BIT(AB8500_SIDFIRADR_FIRSIDSET), + BIT(AB8500_SIDFIRADR_FIRSIDSET)); + snd_soc_update_bits(codec, AB8500_SIDFIRADR, + BIT(AB8500_SIDFIRADR_FIRSIDSET), 0); + + drvdata->sid_status = SID_FIR_CONFIGURED; + +out: + mutex_unlock(&codec->mutex); + + dev_dbg(codec->dev, "%s: Exit\n", __func__); + + return status; +} + +static int anc_status_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); + + mutex_lock(&codec->mutex); + ucontrol->value.integer.value[0] = drvdata->anc_status; + mutex_unlock(&codec->mutex); + + return 0; +} + +static int anc_status_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); + struct device *dev = codec->dev; + bool apply_fir, apply_iir; + int req, status; + + dev_dbg(dev, "%s: Enter.\n", __func__); + + mutex_lock(&drvdata->anc_lock); + + req = ucontrol->value.integer.value[0]; + if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR && + req != ANC_APPLY_IIR) { + dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n", + __func__, enum_anc_state[req]); + return -EINVAL; + } + apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR; + apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR; + + status = snd_soc_dapm_force_enable_pin(&codec->dapm, + "ANC Configure Input"); + if (status < 0) { + dev_err(dev, + "%s: ERROR: Failed to enable power (status = %d)!\n", + __func__, status); + goto cleanup; + } + snd_soc_dapm_sync(&codec->dapm); + + mutex_lock(&codec->mutex); + anc_configure(codec, apply_fir, apply_iir); + mutex_unlock(&codec->mutex); + + if (apply_fir) { + if (drvdata->anc_status == ANC_IIR_CONFIGURED) + drvdata->anc_status = ANC_FIR_IIR_CONFIGURED; + else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED) + drvdata->anc_status = ANC_FIR_CONFIGURED; + } + if (apply_iir) { + if (drvdata->anc_status == ANC_FIR_CONFIGURED) + drvdata->anc_status = ANC_FIR_IIR_CONFIGURED; + else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED) + drvdata->anc_status = ANC_IIR_CONFIGURED; + } + + status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); + snd_soc_dapm_sync(&codec->dapm); + +cleanup: + mutex_unlock(&drvdata->anc_lock); + + if (status < 0) + dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n", + __func__, status); + + dev_dbg(dev, "%s: Exit.\n", __func__); + + return (status < 0) ? status : 1; +} + +static int filter_control_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct filter_control *fc = + (struct filter_control *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = fc->count; + uinfo->value.integer.min = fc->min; + uinfo->value.integer.max = fc->max; + + return 0; +} + +static int filter_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct filter_control *fc = + (struct filter_control *)kcontrol->private_value; + unsigned int i; + + mutex_lock(&codec->mutex); + for (i = 0; i < fc->count; i++) + ucontrol->value.integer.value[i] = fc->value[i]; + mutex_unlock(&codec->mutex); + + return 0; +} + +static int filter_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct filter_control *fc = + (struct filter_control *)kcontrol->private_value; + unsigned int i; + + mutex_lock(&codec->mutex); + for (i = 0; i < fc->count; i++) + fc->value[i] = ucontrol->value.integer.value[i]; + mutex_unlock(&codec->mutex); + + return 0; +} + +/* + * Controls - Non-DAPM ASoC + */ + +static DECLARE_TLV_DB_SCALE(adx_dig_gain_tlv, -3200, 100, 1); +/* -32dB = Mute */ + +static DECLARE_TLV_DB_SCALE(dax_dig_gain_tlv, -6300, 100, 1); +/* -63dB = Mute */ + +static DECLARE_TLV_DB_SCALE(hs_ear_dig_gain_tlv, -100, 100, 1); +/* -1dB = Mute */ + +static const unsigned int hs_gain_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0, 3, TLV_DB_SCALE_ITEM(-3200, 400, 0), + 4, 15, TLV_DB_SCALE_ITEM(-1800, 200, 0), +}; + +static DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0); + +static DECLARE_TLV_DB_SCALE(lin_gain_tlv, -1000, 200, 0); + +static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1); +/* -38dB = Mute */ + +static const char * const enum_hsfadspeed[] = {"2ms", "0.5ms", "10.6ms", + "5ms"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_hsfadspeed, + AB8500_DIGMICCONF, AB8500_DIGMICCONF_HSFADSPEED, enum_hsfadspeed); + +static const char * const enum_envdetthre[] = { + "250mV", "300mV", "350mV", "400mV", + "450mV", "500mV", "550mV", "600mV", + "650mV", "700mV", "750mV", "800mV", + "850mV", "900mV", "950mV", "1.00V" }; +static SOC_ENUM_SINGLE_DECL(soc_enum_envdeththre, + AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETHTHRE, enum_envdetthre); +static SOC_ENUM_SINGLE_DECL(soc_enum_envdetlthre, + AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETLTHRE, enum_envdetthre); +static const char * const enum_envdettime[] = { + "26.6us", "53.2us", "106us", "213us", + "426us", "851us", "1.70ms", "3.40ms", + "6.81ms", "13.6ms", "27.2ms", "54.5ms", + "109ms", "218ms", "436ms", "872ms" }; +static SOC_ENUM_SINGLE_DECL(soc_enum_envdettime, + AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETTIME, enum_envdettime); + +static const char * const enum_sinc31[] = {"Sinc 3", "Sinc 1"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_hsesinc, AB8500_HSLEARDIGGAIN, + AB8500_HSLEARDIGGAIN_HSSINC1, enum_sinc31); + +static const char * const enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed, AB8500_HSRDIGGAIN, + AB8500_HSRDIGGAIN_FADESPEED, enum_fadespeed); + +/* Earpiece */ + +static const char * const enum_lowpow[] = {"Normal", "Low Power"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_eardaclowpow, AB8500_ANACONF1, + AB8500_ANACONF1_EARDACLOWPOW, enum_lowpow); +static SOC_ENUM_SINGLE_DECL(soc_enum_eardrvlowpow, AB8500_ANACONF1, + AB8500_ANACONF1_EARDRVLOWPOW, enum_lowpow); + +static const char * const enum_av_mode[] = {"Audio", "Voice"}; +static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12voice, AB8500_ADFILTCONF, + AB8500_ADFILTCONF_AD1VOICE, AB8500_ADFILTCONF_AD2VOICE, enum_av_mode); +static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34voice, AB8500_ADFILTCONF, + AB8500_ADFILTCONF_AD3VOICE, AB8500_ADFILTCONF_AD4VOICE, enum_av_mode); + +/* DA */ + +static SOC_ENUM_SINGLE_DECL(soc_enum_da12voice, + AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DA12VOICE, + enum_av_mode); +static SOC_ENUM_SINGLE_DECL(soc_enum_da34voice, + AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DA34VOICE, + enum_av_mode); +static SOC_ENUM_SINGLE_DECL(soc_enum_da56voice, + AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DA56VOICE, + enum_av_mode); + +static const char * const enum_da2hslr[] = {"Sidetone", "Audio Path"}; +static SOC_ENUM_DOUBLE_DECL(soc_enum_da2hslr, AB8500_DIGMULTCONF1, + AB8500_DIGMULTCONF1_DATOHSLEN, + AB8500_DIGMULTCONF1_DATOHSREN, enum_da2hslr); + +static const char * const enum_sinc53[] = {"Sinc 5", "Sinc 3"}; +static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic12sinc, AB8500_DMICFILTCONF, + AB8500_DMICFILTCONF_DMIC1SINC3, + AB8500_DMICFILTCONF_DMIC2SINC3, enum_sinc53); +static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic34sinc, AB8500_DMICFILTCONF, + AB8500_DMICFILTCONF_DMIC3SINC3, + AB8500_DMICFILTCONF_DMIC4SINC3, enum_sinc53); +static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic56sinc, AB8500_DMICFILTCONF, + AB8500_DMICFILTCONF_DMIC5SINC3, + AB8500_DMICFILTCONF_DMIC6SINC3, enum_sinc53); + +/* Digital interface - DA from slot mapping */ +static const char * const enum_da_from_slot_map[] = {"SLOT0", + "SLOT1", + "SLOT2", + "SLOT3", + "SLOT4", + "SLOT5", + "SLOT6", + "SLOT7", + "SLOT8", + "SLOT9", + "SLOT10", + "SLOT11", + "SLOT12", + "SLOT13", + "SLOT14", + "SLOT15", + "SLOT16", + "SLOT17", + "SLOT18", + "SLOT19", + "SLOT20", + "SLOT21", + "SLOT22", + "SLOT23", + "SLOT24", + "SLOT25", + "SLOT26", + "SLOT27", + "SLOT28", + "SLOT29", + "SLOT30", + "SLOT31"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_da1slotmap, + AB8500_DASLOTCONF1, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da2slotmap, + AB8500_DASLOTCONF2, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da3slotmap, + AB8500_DASLOTCONF3, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da4slotmap, + AB8500_DASLOTCONF4, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da5slotmap, + AB8500_DASLOTCONF5, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da6slotmap, + AB8500_DASLOTCONF6, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da7slotmap, + AB8500_DASLOTCONF7, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_da8slotmap, + AB8500_DASLOTCONF8, AB8500_DASLOTCONFX_SLTODAX_SHIFT, + enum_da_from_slot_map); + +/* Digital interface - AD to slot mapping */ +static const char * const enum_ad_to_slot_map[] = {"AD_OUT1", + "AD_OUT2", + "AD_OUT3", + "AD_OUT4", + "AD_OUT5", + "AD_OUT6", + "AD_OUT7", + "AD_OUT8", + "zeroes", + "tristate"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map, + AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot1map, + AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot2map, + AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot3map, + AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot4map, + AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot5map, + AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot6map, + AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot7map, + AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot8map, + AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot9map, + AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot10map, + AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot11map, + AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot12map, + AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot13map, + AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot14map, + AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot15map, + AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot16map, + AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot17map, + AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot18map, + AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot19map, + AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot20map, + AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot21map, + AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot22map, + AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot23map, + AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot24map, + AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot25map, + AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot26map, + AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot27map, + AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot28map, + AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot29map, + AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot30map, + AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_EVEN_SHIFT, + enum_ad_to_slot_map); +static SOC_ENUM_SINGLE_DECL(soc_enum_adslot31map, + AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_ODD_SHIFT, + enum_ad_to_slot_map); + +/* Digital interface - Burst mode */ +static const char * const enum_mask[] = {"Unmasked", "Masked"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomask, + AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOMASK, + enum_mask); +static const char * const enum_bitclk0[] = {"19_2_MHz", "38_4_MHz"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_bfifo19m2, + AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFO19M2, + enum_bitclk0); +static const char * const enum_slavemaster[] = {"Slave", "Master"}; +static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast, + AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT, + enum_slavemaster); + +/* Sidetone */ +static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state); + +/* ANC */ +static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_ancstate, enum_anc_state); + +static struct snd_kcontrol_new ab8500_ctrls[] = { + /* Charge pump */ + SOC_ENUM("Charge Pump High Threshold For Low Voltage", + soc_enum_envdeththre), + SOC_ENUM("Charge Pump Low Threshold For Low Voltage", + soc_enum_envdetlthre), + SOC_SINGLE("Charge Pump Envelope Detection Switch", + AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETCPEN, + 1, 0), + SOC_ENUM("Charge Pump Envelope Detection Decay Time", + soc_enum_envdettime), + + /* Headset */ + SOC_ENUM("Headset Mode", soc_enum_da12voice), + SOC_SINGLE("Headset High Pass Switch", + AB8500_ANACONF1, AB8500_ANACONF1_HSHPEN, + 1, 0), + SOC_SINGLE("Headset Low Power Switch", + AB8500_ANACONF1, AB8500_ANACONF1_HSLOWPOW, + 1, 0), + SOC_SINGLE("Headset DAC Low Power Switch", + AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW1, + 1, 0), + SOC_SINGLE("Headset DAC Drv Low Power Switch", + AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW0, + 1, 0), + SOC_ENUM("Headset Fade Speed", soc_enum_hsfadspeed), + SOC_ENUM("Headset Source", soc_enum_da2hslr), + SOC_ENUM("Headset Filter", soc_enum_hsesinc), + SOC_DOUBLE_R_TLV("Headset Master Volume", + AB8500_DADIGGAIN1, AB8500_DADIGGAIN2, + 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), + SOC_DOUBLE_R_TLV("Headset Digital Volume", + AB8500_HSLEARDIGGAIN, AB8500_HSRDIGGAIN, + 0, AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX, 1, hs_ear_dig_gain_tlv), + SOC_DOUBLE_TLV("Headset Volume", + AB8500_ANAGAIN3, + AB8500_ANAGAIN3_HSLGAIN, AB8500_ANAGAIN3_HSRGAIN, + AB8500_ANAGAIN3_HSXGAIN_MAX, 1, hs_gain_tlv), + + /* Earpiece */ + SOC_ENUM("Earpiece DAC Mode", + soc_enum_eardaclowpow), + SOC_ENUM("Earpiece DAC Drv Mode", + soc_enum_eardrvlowpow), + + /* HandsFree */ + SOC_ENUM("HF Mode", soc_enum_da34voice), + SOC_SINGLE("HF and Headset Swap Switch", + AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_SWAPDA12_34, + 1, 0), + SOC_DOUBLE("HF Low EMI Mode Switch", + AB8500_CLASSDCONF1, + AB8500_CLASSDCONF1_HFLSWAPEN, AB8500_CLASSDCONF1_HFRSWAPEN, + 1, 0), + SOC_DOUBLE("HF FIR Bypass Switch", + AB8500_CLASSDCONF2, + AB8500_CLASSDCONF2_FIRBYP0, AB8500_CLASSDCONF2_FIRBYP1, + 1, 0), + SOC_DOUBLE("HF High Volume Switch", + AB8500_CLASSDCONF2, + AB8500_CLASSDCONF2_HIGHVOLEN0, AB8500_CLASSDCONF2_HIGHVOLEN1, + 1, 0), + SOC_SINGLE("HF L and R Bridge Switch", + AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLHF, + 1, 0), + SOC_DOUBLE_R_TLV("HF Master Volume", + AB8500_DADIGGAIN3, AB8500_DADIGGAIN4, + 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), + + /* Vibra */ + SOC_DOUBLE("Vibra High Volume Switch", + AB8500_CLASSDCONF2, + AB8500_CLASSDCONF2_HIGHVOLEN2, AB8500_CLASSDCONF2_HIGHVOLEN3, + 1, 0), + SOC_DOUBLE("Vibra Low EMI Mode Switch", + AB8500_CLASSDCONF1, + AB8500_CLASSDCONF1_VIB1SWAPEN, AB8500_CLASSDCONF1_VIB2SWAPEN, + 1, 0), + SOC_DOUBLE("Vibra FIR Bypass Switch", + AB8500_CLASSDCONF2, + AB8500_CLASSDCONF2_FIRBYP2, AB8500_CLASSDCONF2_FIRBYP3, + 1, 0), + SOC_ENUM("Vibra Mode", soc_enum_da56voice), + SOC_DOUBLE_R("Vibra PWM Duty Cycle N", + AB8500_PWMGENCONF3, AB8500_PWMGENCONF5, + AB8500_PWMGENCONFX_PWMVIBXDUTCYC, + AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0), + SOC_DOUBLE_R("Vibra PWM Duty Cycle P", + AB8500_PWMGENCONF2, AB8500_PWMGENCONF4, + AB8500_PWMGENCONFX_PWMVIBXDUTCYC, + AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0), + SOC_SINGLE("Vibra 1 and 2 Bridge Switch", + AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLVIB, + 1, 0), + SOC_DOUBLE_R_TLV("Vibra Master Volume", + AB8500_DADIGGAIN5, AB8500_DADIGGAIN6, + 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), + + /* HandsFree, Vibra */ + SOC_SINGLE("ClassD High Pass Volume", + AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHHPGAIN, + AB8500_CLASSDCONF3_DITHHPGAIN_MAX, 0), + SOC_SINGLE("ClassD White Volume", + AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHWGAIN, + AB8500_CLASSDCONF3_DITHWGAIN_MAX, 0), + + /* Mic 1, Mic 2, LineIn */ + SOC_DOUBLE_R_TLV("Mic Master Volume", + AB8500_ADDIGGAIN3, AB8500_ADDIGGAIN4, + 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), + + /* Mic 1 */ + SOC_SINGLE_TLV("Mic 1", + AB8500_ANAGAIN1, + AB8500_ANAGAINX_MICXGAIN, + AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv), + SOC_SINGLE("Mic 1 Low Power Switch", + AB8500_ANAGAIN1, AB8500_ANAGAINX_LOWPOWMICX, + 1, 0), + + /* Mic 2 */ + SOC_DOUBLE("Mic High Pass Switch", + AB8500_ADFILTCONF, + AB8500_ADFILTCONF_AD3NH, AB8500_ADFILTCONF_AD4NH, + 1, 1), + SOC_ENUM("Mic Mode", soc_enum_ad34voice), + SOC_ENUM("Mic Filter", soc_enum_dmic34sinc), + SOC_SINGLE_TLV("Mic 2", + AB8500_ANAGAIN2, + AB8500_ANAGAINX_MICXGAIN, + AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv), + SOC_SINGLE("Mic 2 Low Power Switch", + AB8500_ANAGAIN2, AB8500_ANAGAINX_LOWPOWMICX, + 1, 0), + + /* LineIn */ + SOC_DOUBLE("LineIn High Pass Switch", + AB8500_ADFILTCONF, + AB8500_ADFILTCONF_AD1NH, AB8500_ADFILTCONF_AD2NH, + 1, 1), + SOC_ENUM("LineIn Filter", soc_enum_dmic12sinc), + SOC_ENUM("LineIn Mode", soc_enum_ad12voice), + SOC_DOUBLE_R_TLV("LineIn Master Volume", + AB8500_ADDIGGAIN1, AB8500_ADDIGGAIN2, + 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), + SOC_DOUBLE_TLV("LineIn", + AB8500_ANAGAIN4, + AB8500_ANAGAIN4_LINLGAIN, AB8500_ANAGAIN4_LINRGAIN, + AB8500_ANAGAIN4_LINXGAIN_MAX, 0, lin_gain_tlv), + SOC_DOUBLE_R_TLV("LineIn to Headset Volume", + AB8500_DIGLINHSLGAIN, AB8500_DIGLINHSRGAIN, + AB8500_DIGLINHSXGAIN_LINTOHSXGAIN, + AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX, + 1, lin2hs_gain_tlv), + + /* DMic */ + SOC_ENUM("DMic Filter", soc_enum_dmic56sinc), + SOC_DOUBLE_R_TLV("DMic Master Volume", + AB8500_ADDIGGAIN5, AB8500_ADDIGGAIN6, + 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), + + /* Digital gains */ + SOC_ENUM("Digital Gain Fade Speed", soc_enum_fadespeed), + + /* Analog loopback */ + SOC_DOUBLE_R_TLV("Analog Loopback Volume", + AB8500_ADDIGLOOPGAIN1, AB8500_ADDIGLOOPGAIN2, + 0, AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX, 1, dax_dig_gain_tlv), + + /* Digital interface - DA from slot mapping */ + SOC_ENUM("Digital Interface DA 1 From Slot Map", soc_enum_da1slotmap), + SOC_ENUM("Digital Interface DA 2 From Slot Map", soc_enum_da2slotmap), + SOC_ENUM("Digital Interface DA 3 From Slot Map", soc_enum_da3slotmap), + SOC_ENUM("Digital Interface DA 4 From Slot Map", soc_enum_da4slotmap), + SOC_ENUM("Digital Interface DA 5 From Slot Map", soc_enum_da5slotmap), + SOC_ENUM("Digital Interface DA 6 From Slot Map", soc_enum_da6slotmap), + SOC_ENUM("Digital Interface DA 7 From Slot Map", soc_enum_da7slotmap), + SOC_ENUM("Digital Interface DA 8 From Slot Map", soc_enum_da8slotmap), + + /* Digital interface - AD to slot mapping */ + SOC_ENUM("Digital Interface AD To Slot 0 Map", soc_enum_adslot0map), + SOC_ENUM("Digital Interface AD To Slot 1 Map", soc_enum_adslot1map), + SOC_ENUM("Digital Interface AD To Slot 2 Map", soc_enum_adslot2map), + SOC_ENUM("Digital Interface AD To Slot 3 Map", soc_enum_adslot3map), + SOC_ENUM("Digital Interface AD To Slot 4 Map", soc_enum_adslot4map), + SOC_ENUM("Digital Interface AD To Slot 5 Map", soc_enum_adslot5map), + SOC_ENUM("Digital Interface AD To Slot 6 Map", soc_enum_adslot6map), + SOC_ENUM("Digital Interface AD To Slot 7 Map", soc_enum_adslot7map), + SOC_ENUM("Digital Interface AD To Slot 8 Map", soc_enum_adslot8map), + SOC_ENUM("Digital Interface AD To Slot 9 Map", soc_enum_adslot9map), + SOC_ENUM("Digital Interface AD To Slot 10 Map", soc_enum_adslot10map), + SOC_ENUM("Digital Interface AD To Slot 11 Map", soc_enum_adslot11map), + SOC_ENUM("Digital Interface AD To Slot 12 Map", soc_enum_adslot12map), + SOC_ENUM("Digital Interface AD To Slot 13 Map", soc_enum_adslot13map), + SOC_ENUM("Digital Interface AD To Slot 14 Map", soc_enum_adslot14map), + SOC_ENUM("Digital Interface AD To Slot 15 Map", soc_enum_adslot15map), + SOC_ENUM("Digital Interface AD To Slot 16 Map", soc_enum_adslot16map), + SOC_ENUM("Digital Interface AD To Slot 17 Map", soc_enum_adslot17map), + SOC_ENUM("Digital Interface AD To Slot 18 Map", soc_enum_adslot18map), + SOC_ENUM("Digital Interface AD To Slot 19 Map", soc_enum_adslot19map), + SOC_ENUM("Digital Interface AD To Slot 20 Map", soc_enum_adslot20map), + SOC_ENUM("Digital Interface AD To Slot 21 Map", soc_enum_adslot21map), + SOC_ENUM("Digital Interface AD To Slot 22 Map", soc_enum_adslot22map), + SOC_ENUM("Digital Interface AD To Slot 23 Map", soc_enum_adslot23map), + SOC_ENUM("Digital Interface AD To Slot 24 Map", soc_enum_adslot24map), + SOC_ENUM("Digital Interface AD To Slot 25 Map", soc_enum_adslot25map), + SOC_ENUM("Digital Interface AD To Slot 26 Map", soc_enum_adslot26map), + SOC_ENUM("Digital Interface AD To Slot 27 Map", soc_enum_adslot27map), + SOC_ENUM("Digital Interface AD To Slot 28 Map", soc_enum_adslot28map), + SOC_ENUM("Digital Interface AD To Slot 29 Map", soc_enum_adslot29map), + SOC_ENUM("Digital Interface AD To Slot 30 Map", soc_enum_adslot30map), + SOC_ENUM("Digital Interface AD To Slot 31 Map", soc_enum_adslot31map), + + /* Digital interface - Loopback */ + SOC_SINGLE("Digital Interface AD 1 Loopback Switch", + AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DAI7TOADO1, + 1, 0), + SOC_SINGLE("Digital Interface AD 2 Loopback Switch", + AB8500_DASLOTCONF2, AB8500_DASLOTCONF2_DAI8TOADO2, + 1, 0), + SOC_SINGLE("Digital Interface AD 3 Loopback Switch", + AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DAI7TOADO3, + 1, 0), + SOC_SINGLE("Digital Interface AD 4 Loopback Switch", + AB8500_DASLOTCONF4, AB8500_DASLOTCONF4_DAI8TOADO4, + 1, 0), + SOC_SINGLE("Digital Interface AD 5 Loopback Switch", + AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DAI7TOADO5, + 1, 0), + SOC_SINGLE("Digital Interface AD 6 Loopback Switch", + AB8500_DASLOTCONF6, AB8500_DASLOTCONF6_DAI8TOADO6, + 1, 0), + SOC_SINGLE("Digital Interface AD 7 Loopback Switch", + AB8500_DASLOTCONF7, AB8500_DASLOTCONF7_DAI8TOADO7, + 1, 0), + SOC_SINGLE("Digital Interface AD 8 Loopback Switch", + AB8500_DASLOTCONF8, AB8500_DASLOTCONF8_DAI7TOADO8, + 1, 0), + + /* Digital interface - Burst FIFO */ + SOC_SINGLE("Digital Interface 0 FIFO Enable Switch", + AB8500_DIGIFCONF3, AB8500_DIGIFCONF3_IF0BFIFOEN, + 1, 0), + SOC_ENUM("Burst FIFO Mask", soc_enum_bfifomask), + SOC_ENUM("Burst FIFO Bit-clock Frequency", soc_enum_bfifo19m2), + SOC_SINGLE("Burst FIFO Threshold", + AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOINT_SHIFT, + AB8500_FIFOCONF1_BFIFOINT_MAX, 0), + SOC_SINGLE("Burst FIFO Length", + AB8500_FIFOCONF2, AB8500_FIFOCONF2_BFIFOTX_SHIFT, + AB8500_FIFOCONF2_BFIFOTX_MAX, 0), + SOC_SINGLE("Burst FIFO EOS Extra Slots", + AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOEXSL_SHIFT, + AB8500_FIFOCONF3_BFIFOEXSL_MAX, 0), + SOC_SINGLE("Burst FIFO FS Extra Bit-clocks", + AB8500_FIFOCONF3, AB8500_FIFOCONF3_PREBITCLK0_SHIFT, + AB8500_FIFOCONF3_PREBITCLK0_MAX, 0), + SOC_ENUM("Burst FIFO Interface Mode", soc_enum_bfifomast), + + SOC_SINGLE("Burst FIFO Interface Switch", + AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFORUN_SHIFT, + 1, 0), + SOC_SINGLE("Burst FIFO Switch Frame Number", + AB8500_FIFOCONF4, AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT, + AB8500_FIFOCONF4_BFIFOFRAMSW_MAX, 0), + SOC_SINGLE("Burst FIFO Wake Up Delay", + AB8500_FIFOCONF5, AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT, + AB8500_FIFOCONF5_BFIFOWAKEUP_MAX, 0), + SOC_SINGLE("Burst FIFO Samples In FIFO", + AB8500_FIFOCONF6, AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT, + AB8500_FIFOCONF6_BFIFOSAMPLE_MAX, 0), + + /* ANC */ + SOC_ENUM_EXT("ANC Status", soc_enum_ancstate, + anc_status_control_get, anc_status_control_put), + SOC_SINGLE_XR_SX("ANC Warp Delay Shift", + AB8500_ANCCONF2, 1, AB8500_ANCCONF2_SHIFT, + AB8500_ANCCONF2_MIN, AB8500_ANCCONF2_MAX, 0), + SOC_SINGLE_XR_SX("ANC FIR Output Shift", + AB8500_ANCCONF3, 1, AB8500_ANCCONF3_SHIFT, + AB8500_ANCCONF3_MIN, AB8500_ANCCONF3_MAX, 0), + SOC_SINGLE_XR_SX("ANC IIR Output Shift", + AB8500_ANCCONF4, 1, AB8500_ANCCONF4_SHIFT, + AB8500_ANCCONF4_MIN, AB8500_ANCCONF4_MAX, 0), + SOC_SINGLE_XR_SX("ANC Warp Delay", + AB8500_ANCCONF9, 2, AB8500_ANC_WARP_DELAY_SHIFT, + AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0), + + /* Sidetone */ + SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate, + sid_status_control_get, sid_status_control_put), + SOC_SINGLE_STROBE("Sidetone Reset", + AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0), +}; + +static struct snd_kcontrol_new ab8500_filter_controls[] = { + AB8500_FILTER_CONTROL("ANC FIR Coefficients", AB8500_ANC_FIR_COEFFS, + AB8500_ANC_FIR_COEFF_MIN, AB8500_ANC_FIR_COEFF_MAX), + AB8500_FILTER_CONTROL("ANC IIR Coefficients", AB8500_ANC_IIR_COEFFS, + AB8500_ANC_IIR_COEFF_MIN, AB8500_ANC_IIR_COEFF_MAX), + AB8500_FILTER_CONTROL("Sidetone FIR Coefficients", + AB8500_SID_FIR_COEFFS, AB8500_SID_FIR_COEFF_MIN, + AB8500_SID_FIR_COEFF_MAX) +}; +enum ab8500_filter { + AB8500_FILTER_ANC_FIR = 0, + AB8500_FILTER_ANC_IIR = 1, + AB8500_FILTER_SID_FIR = 2, +}; + +/* + * Extended interface for codec-driver + */ + +static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec) +{ + int status; + + dev_dbg(codec->dev, "%s: Enter.\n", __func__); + + /* Reset audio-registers and disable 32kHz-clock output 2 */ + status = ab8500_sysctrl_write(AB8500_STW4500CTRL3, + AB8500_STW4500CTRL3_CLK32KOUT2DIS | + AB8500_STW4500CTRL3_RESETAUDN, + AB8500_STW4500CTRL3_RESETAUDN); + if (status < 0) + return status; + + return 0; +} + +static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, + struct amic_settings *amics) +{ + u8 value8; + unsigned int value; + int status; + const struct snd_soc_dapm_route *route; + + dev_dbg(codec->dev, "%s: Enter.\n", __func__); + + /* Set DMic-clocks to outputs */ + status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC, + (u8)AB8500_GPIO_DIR4_REG, + &value8); + if (status < 0) + return status; + value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | + GPIO31_DIR_OUTPUT; + status = abx500_set_register_interruptible(codec->dev, + (u8)AB8500_MISC, + (u8)AB8500_GPIO_DIR4_REG, + value); + if (status < 0) + return status; + + /* Attach regulators to AMic DAPM-paths */ + dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__, + amic_micbias_str(amics->mic1a_micbias)); + route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias]; + status = snd_soc_dapm_add_routes(&codec->dapm, route, 1); + dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__, + amic_micbias_str(amics->mic1b_micbias)); + route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias]; + status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); + dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__, + amic_micbias_str(amics->mic2_micbias)); + route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias]; + status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); + if (status < 0) { + dev_err(codec->dev, + "%s: Failed to add AMic-regulator DAPM-routes (%d).\n", + __func__, status); + return status; + } + + /* Set AMic-configuration */ + dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__, + amic_type_str(amics->mic1_type)); + snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX, + amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ? + 0 : AB8500_ANAGAINX_ENSEMICX); + dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__, + amic_type_str(amics->mic2_type)); + snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX, + amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ? + 0 : AB8500_ANAGAINX_ENSEMICX); + + return 0; +} +EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics); + +static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec, + enum ear_cm_voltage ear_cmv) +{ + char *cmv_str; + + switch (ear_cmv) { + case EAR_CMV_0_95V: + cmv_str = "0.95V"; + break; + case EAR_CMV_1_10V: + cmv_str = "1.10V"; + break; + case EAR_CMV_1_27V: + cmv_str = "1.27V"; + break; + case EAR_CMV_1_58V: + cmv_str = "1.58V"; + break; + default: + dev_err(codec->dev, + "%s: Unknown earpiece CM-voltage (%d)!\n", + __func__, (int)ear_cmv); + return -EINVAL; + } + dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__, + cmv_str); + snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM, + ear_cmv); + + return 0; +} +EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv); + +static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, + unsigned int delay) +{ + unsigned int mask, val; + struct snd_soc_codec *codec = dai->codec; + + mask = BIT(AB8500_DIGIFCONF2_IF0DEL); + val = 0; + + switch (delay) { + case 0: + break; + case 1: + val |= BIT(AB8500_DIGIFCONF2_IF0DEL); + break; + default: + dev_err(dai->codec->dev, + "%s: ERROR: Unsupported bit-delay (0x%x)!\n", + __func__, delay); + return -EINVAL; + } + + dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n", + __func__, delay); + snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); + + return 0; +} + +/* Gates clocking according format mask */ +static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec, + unsigned int fmt) +{ + unsigned int mask; + unsigned int val; + + mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) | + BIT(AB8500_DIGIFCONF1_ENFSBITCLK0); + + val = BIT(AB8500_DIGIFCONF1_ENMASTGEN); + + switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { + case SND_SOC_DAIFMT_CONT: /* continuous clock */ + dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n", + __func__); + val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0); + break; + case SND_SOC_DAIFMT_GATED: /* clock is gated */ + dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n", + __func__); + break; + default: + dev_err(codec->dev, + "%s: ERROR: Unsupported clock mask (0x%x)!\n", + __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK); + return -EINVAL; + } + + snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); + + return 0; +} + +static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + unsigned int mask; + unsigned int val; + struct snd_soc_codec *codec = dai->codec; + int status; + + dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt); + + mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) | + BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) | + BIT(AB8500_DIGIFCONF3_IF0BFIFOEN) | + BIT(AB8500_DIGIFCONF3_IF0MASTER); + val = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */ + dev_dbg(dai->codec->dev, + "%s: IF0 Master-mode: AB8500 master.\n", __func__); + val |= BIT(AB8500_DIGIFCONF3_IF0MASTER); + break; + case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */ + dev_dbg(dai->codec->dev, + "%s: IF0 Master-mode: AB8500 slave.\n", __func__); + break; + case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */ + case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ + dev_err(dai->codec->dev, + "%s: ERROR: The device is either a master or a slave.\n", + __func__); + default: + dev_err(dai->codec->dev, + "%s: ERROR: Unsupporter master mask 0x%x\n", + __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); + return -EINVAL; + break; + } + + snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val); + + /* Set clock gating */ + status = ab8500_codec_set_dai_clock_gate(codec, fmt); + if (status) { + dev_err(dai->codec->dev, + "%s: ERRROR: Failed to set clock gate (%d).\n", + __func__, status); + return status; + } + + /* Setting data transfer format */ + + mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) | + BIT(AB8500_DIGIFCONF2_IF0FORMAT1) | + BIT(AB8500_DIGIFCONF2_FSYNC0P) | + BIT(AB8500_DIGIFCONF2_BITCLK0P); + val = 0; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: /* I2S mode */ + dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__); + val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1); + ab8500_audio_set_bit_delay(dai, 0); + break; + + case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */ + dev_dbg(dai->codec->dev, + "%s: IF0 Protocol: DSP A (TDM)\n", __func__); + val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0); + ab8500_audio_set_bit_delay(dai, 1); + break; + + case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */ + dev_dbg(dai->codec->dev, + "%s: IF0 Protocol: DSP B (TDM)\n", __func__); + val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0); + ab8500_audio_set_bit_delay(dai, 0); + break; + + default: + dev_err(dai->codec->dev, + "%s: ERROR: Unsupported format (0x%x)!\n", + __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ + dev_dbg(dai->codec->dev, + "%s: IF0: Normal bit clock, normal frame\n", + __func__); + break; + case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */ + dev_dbg(dai->codec->dev, + "%s: IF0: Normal bit clock, inverted frame\n", + __func__); + val |= BIT(AB8500_DIGIFCONF2_FSYNC0P); + break; + case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */ + dev_dbg(dai->codec->dev, + "%s: IF0: Inverted bit clock, normal frame\n", + __func__); + val |= BIT(AB8500_DIGIFCONF2_BITCLK0P); + break; + case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */ + dev_dbg(dai->codec->dev, + "%s: IF0: Inverted bit clock, inverted frame\n", + __func__); + val |= BIT(AB8500_DIGIFCONF2_FSYNC0P); + val |= BIT(AB8500_DIGIFCONF2_BITCLK0P); + break; + default: + dev_err(dai->codec->dev, + "%s: ERROR: Unsupported INV mask 0x%x\n", + __func__, fmt & SND_SOC_DAIFMT_INV_MASK); + return -EINVAL; + } + + snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); + + return 0; +} + +static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + struct snd_soc_codec *codec = dai->codec; + unsigned int val, mask, slots_active; + + mask = BIT(AB8500_DIGIFCONF2_IF0WL0) | + BIT(AB8500_DIGIFCONF2_IF0WL1); + val = 0; + + switch (slot_width) { + case 16: + break; + case 20: + val |= BIT(AB8500_DIGIFCONF2_IF0WL0); + break; + case 24: + val |= BIT(AB8500_DIGIFCONF2_IF0WL1); + break; + case 32: + val |= BIT(AB8500_DIGIFCONF2_IF0WL1) | + BIT(AB8500_DIGIFCONF2_IF0WL0); + break; + default: + dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n", + __func__, slot_width); + return -EINVAL; + } + + dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n", + __func__, slot_width); + snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); + + /* Setup TDM clocking according to slot count */ + dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots); + mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) | + BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); + switch (slots) { + case 2: + val = AB8500_MASK_NONE; + break; + case 4: + val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0); + break; + case 8: + val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); + break; + case 16: + val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) | + BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); + break; + default: + dev_err(dai->codec->dev, + "%s: ERROR: Unsupported number of slots (%d)!\n", + __func__, slots); + return -EINVAL; + } + snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); + + /* Setup TDM DA according to active tx slots */ + mask = AB8500_DASLOTCONFX_SLTODAX_MASK; + slots_active = hweight32(tx_mask); + dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__, + slots_active); + switch (slots_active) { + case 0: + break; + case 1: + /* Slot 9 -> DA_IN1 & DA_IN3 */ + snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11); + snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11); + snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); + snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); + break; + case 2: + /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */ + snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9); + snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9); + snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); + snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); + + break; + case 8: + dev_dbg(dai->codec->dev, + "%s: In 8-channel mode DA-from-slot mapping is set manually.", + __func__); + break; + default: + dev_err(dai->codec->dev, + "%s: Unsupported number of active TX-slots (%d)!\n", + __func__, slots_active); + return -EINVAL; + } + + /* Setup TDM AD according to active RX-slots */ + slots_active = hweight32(rx_mask); + dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__, + slots_active); + switch (slots_active) { + case 0: + break; + case 1: + /* AD_OUT3 -> slot 0 & 1 */ + snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL, + AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | + AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD); + break; + case 2: + /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ + snd_soc_update_bits(codec, + AB8500_ADSLOTSEL1, + AB8500_MASK_ALL, + AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | + AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD); + break; + case 8: + dev_dbg(dai->codec->dev, + "%s: In 8-channel mode AD-to-slot mapping is set manually.", + __func__); + break; + default: + dev_err(dai->codec->dev, + "%s: Unsupported number of active RX-slots (%d)!\n", + __func__, slots_active); + return -EINVAL; + } + + return 0; +} + +struct snd_soc_dai_driver ab8500_codec_dai[] = { + { + .name = "ab8500-codec-dai.0", + .id = 0, + .playback = { + .stream_name = "ab8500_0p", + .channels_min = 1, + .channels_max = 8, + .rates = AB8500_SUPPORTED_RATE, + .formats = AB8500_SUPPORTED_FMT, + }, + .ops = (struct snd_soc_dai_ops[]) { + { + .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, + .set_fmt = ab8500_codec_set_dai_fmt, + } + }, + .symmetric_rates = 1 + }, + { + .name = "ab8500-codec-dai.1", + .id = 1, + .capture = { + .stream_name = "ab8500_0c", + .channels_min = 1, + .channels_max = 8, + .rates = AB8500_SUPPORTED_RATE, + .formats = AB8500_SUPPORTED_FMT, + }, + .ops = (struct snd_soc_dai_ops[]) { + { + .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, + .set_fmt = ab8500_codec_set_dai_fmt, + } + }, + .symmetric_rates = 1 + } +}; + +static int ab8500_codec_probe(struct snd_soc_codec *codec) +{ + struct device *dev = codec->dev; + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); + struct ab8500_platform_data *pdata; + struct filter_control *fc; + int status; + + dev_dbg(dev, "%s: Enter.\n", __func__); + + /* Setup AB8500 according to board-settings */ + pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); + status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); + if (status < 0) { + pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); + return status; + } + status = ab8500_audio_set_ear_cmv(codec, pdata->codec->ear_cmv); + if (status < 0) { + pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n", + __func__, status); + return status; + } + + status = ab8500_audio_init_audioblock(codec); + if (status < 0) { + dev_err(dev, "%s: failed to init audio-block (%d)!\n", + __func__, status); + return status; + } + + /* Override HW-defaults */ + ab8500_codec_write_reg(codec, + AB8500_ANACONF5, + BIT(AB8500_ANACONF5_HSAUTOEN)); + ab8500_codec_write_reg(codec, + AB8500_SHORTCIRCONF, + BIT(AB8500_SHORTCIRCONF_HSZCDDIS)); + + /* Add filter controls */ + status = snd_soc_add_codec_controls(codec, ab8500_filter_controls, + ARRAY_SIZE(ab8500_filter_controls)); + if (status < 0) { + dev_err(dev, + "%s: failed to add ab8500 filter controls (%d).\n", + __func__, status); + return status; + } + fc = (struct filter_control *) + &ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value; + drvdata->anc_fir_values = (long *)fc->value; + fc = (struct filter_control *) + &ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value; + drvdata->anc_iir_values = (long *)fc->value; + fc = (struct filter_control *) + &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value; + drvdata->sid_fir_values = (long *)fc->value; + + (void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); + + mutex_init(&drvdata->anc_lock); + + return status; +} + +static struct snd_soc_codec_driver ab8500_codec_driver = { + .probe = ab8500_codec_probe, + .read = ab8500_codec_read_reg, + .write = ab8500_codec_write_reg, + .reg_word_size = sizeof(u8), + .controls = ab8500_ctrls, + .num_controls = ARRAY_SIZE(ab8500_ctrls), + .dapm_widgets = ab8500_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), + .dapm_routes = ab8500_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), +}; + +static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev) +{ + int status; + struct ab8500_codec_drvdata *drvdata; + + dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); + + /* Create driver private-data struct */ + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_codec_drvdata), + GFP_KERNEL); + drvdata->sid_status = SID_UNCONFIGURED; + drvdata->anc_status = ANC_UNCONFIGURED; + dev_set_drvdata(&pdev->dev, drvdata); + + dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__); + status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver, + ab8500_codec_dai, + ARRAY_SIZE(ab8500_codec_dai)); + if (status < 0) + dev_err(&pdev->dev, + "%s: Error: Failed to register codec (%d).\n", + __func__, status); + + return status; +} + +static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "%s Enter.\n", __func__); + + snd_soc_unregister_codec(&pdev->dev); + + return 0; +} + +static struct platform_driver ab8500_codec_platform_driver = { + .driver = { + .name = "ab8500-codec", + .owner = THIS_MODULE, + }, + .probe = ab8500_codec_driver_probe, + .remove = __devexit_p(ab8500_codec_driver_remove), + .suspend = NULL, + .resume = NULL, +}; +module_platform_driver(ab8500_codec_platform_driver); + +MODULE_LICENSE("GPLv2"); diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h new file mode 100644 index 000000000000..114f69a0c629 --- /dev/null +++ b/sound/soc/codecs/ab8500-codec.h @@ -0,0 +1,590 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja , + * Kristoffer Karlsson , + * Roger Nilsson , + * for ST-Ericsson. + * + * Based on the early work done by: + * Mikko J. Lehto , + * Mikko Sarmanne , + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef AB8500_CODEC_REGISTERS_H +#define AB8500_CODEC_REGISTERS_H + +#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000) +#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE) + +/* AB8500 audio bank (0x0d) register definitions */ + +#define AB8500_POWERUP 0x00 +#define AB8500_AUDSWRESET 0x01 +#define AB8500_ADPATHENA 0x02 +#define AB8500_DAPATHENA 0x03 +#define AB8500_ANACONF1 0x04 +#define AB8500_ANACONF2 0x05 +#define AB8500_DIGMICCONF 0x06 +#define AB8500_ANACONF3 0x07 +#define AB8500_ANACONF4 0x08 +#define AB8500_DAPATHCONF 0x09 +#define AB8500_MUTECONF 0x0A +#define AB8500_SHORTCIRCONF 0x0B +#define AB8500_ANACONF5 0x0C +#define AB8500_ENVCPCONF 0x0D +#define AB8500_SIGENVCONF 0x0E +#define AB8500_PWMGENCONF1 0x0F +#define AB8500_PWMGENCONF2 0x10 +#define AB8500_PWMGENCONF3 0x11 +#define AB8500_PWMGENCONF4 0x12 +#define AB8500_PWMGENCONF5 0x13 +#define AB8500_ANAGAIN1 0x14 +#define AB8500_ANAGAIN2 0x15 +#define AB8500_ANAGAIN3 0x16 +#define AB8500_ANAGAIN4 0x17 +#define AB8500_DIGLINHSLGAIN 0x18 +#define AB8500_DIGLINHSRGAIN 0x19 +#define AB8500_ADFILTCONF 0x1A +#define AB8500_DIGIFCONF1 0x1B +#define AB8500_DIGIFCONF2 0x1C +#define AB8500_DIGIFCONF3 0x1D +#define AB8500_DIGIFCONF4 0x1E +#define AB8500_ADSLOTSEL1 0x1F +#define AB8500_ADSLOTSEL2 0x20 +#define AB8500_ADSLOTSEL3 0x21 +#define AB8500_ADSLOTSEL4 0x22 +#define AB8500_ADSLOTSEL5 0x23 +#define AB8500_ADSLOTSEL6 0x24 +#define AB8500_ADSLOTSEL7 0x25 +#define AB8500_ADSLOTSEL8 0x26 +#define AB8500_ADSLOTSEL9 0x27 +#define AB8500_ADSLOTSEL10 0x28 +#define AB8500_ADSLOTSEL11 0x29 +#define AB8500_ADSLOTSEL12 0x2A +#define AB8500_ADSLOTSEL13 0x2B +#define AB8500_ADSLOTSEL14 0x2C +#define AB8500_ADSLOTSEL15 0x2D +#define AB8500_ADSLOTSEL16 0x2E +#define AB8500_ADSLOTHIZCTRL1 0x2F +#define AB8500_ADSLOTHIZCTRL2 0x30 +#define AB8500_ADSLOTHIZCTRL3 0x31 +#define AB8500_ADSLOTHIZCTRL4 0x32 +#define AB8500_DASLOTCONF1 0x33 +#define AB8500_DASLOTCONF2 0x34 +#define AB8500_DASLOTCONF3 0x35 +#define AB8500_DASLOTCONF4 0x36 +#define AB8500_DASLOTCONF5 0x37 +#define AB8500_DASLOTCONF6 0x38 +#define AB8500_DASLOTCONF7 0x39 +#define AB8500_DASLOTCONF8 0x3A +#define AB8500_CLASSDCONF1 0x3B +#define AB8500_CLASSDCONF2 0x3C +#define AB8500_CLASSDCONF3 0x3D +#define AB8500_DMICFILTCONF 0x3E +#define AB8500_DIGMULTCONF1 0x3F +#define AB8500_DIGMULTCONF2 0x40 +#define AB8500_ADDIGGAIN1 0x41 +#define AB8500_ADDIGGAIN2 0x42 +#define AB8500_ADDIGGAIN3 0x43 +#define AB8500_ADDIGGAIN4 0x44 +#define AB8500_ADDIGGAIN5 0x45 +#define AB8500_ADDIGGAIN6 0x46 +#define AB8500_DADIGGAIN1 0x47 +#define AB8500_DADIGGAIN2 0x48 +#define AB8500_DADIGGAIN3 0x49 +#define AB8500_DADIGGAIN4 0x4A +#define AB8500_DADIGGAIN5 0x4B +#define AB8500_DADIGGAIN6 0x4C +#define AB8500_ADDIGLOOPGAIN1 0x4D +#define AB8500_ADDIGLOOPGAIN2 0x4E +#define AB8500_HSLEARDIGGAIN 0x4F +#define AB8500_HSRDIGGAIN 0x50 +#define AB8500_SIDFIRGAIN1 0x51 +#define AB8500_SIDFIRGAIN2 0x52 +#define AB8500_ANCCONF1 0x53 +#define AB8500_ANCCONF2 0x54 +#define AB8500_ANCCONF3 0x55 +#define AB8500_ANCCONF4 0x56 +#define AB8500_ANCCONF5 0x57 +#define AB8500_ANCCONF6 0x58 +#define AB8500_ANCCONF7 0x59 +#define AB8500_ANCCONF8 0x5A +#define AB8500_ANCCONF9 0x5B +#define AB8500_ANCCONF10 0x5C +#define AB8500_ANCCONF11 0x5D +#define AB8500_ANCCONF12 0x5E +#define AB8500_ANCCONF13 0x5F +#define AB8500_ANCCONF14 0x60 +#define AB8500_SIDFIRADR 0x61 +#define AB8500_SIDFIRCOEF1 0x62 +#define AB8500_SIDFIRCOEF2 0x63 +#define AB8500_SIDFIRCONF 0x64 +#define AB8500_AUDINTMASK1 0x65 +#define AB8500_AUDINTSOURCE1 0x66 +#define AB8500_AUDINTMASK2 0x67 +#define AB8500_AUDINTSOURCE2 0x68 +#define AB8500_FIFOCONF1 0x69 +#define AB8500_FIFOCONF2 0x6A +#define AB8500_FIFOCONF3 0x6B +#define AB8500_FIFOCONF4 0x6C +#define AB8500_FIFOCONF5 0x6D +#define AB8500_FIFOCONF6 0x6E +#define AB8500_AUDREV 0x6F + +#define AB8500_FIRST_REG AB8500_POWERUP +#define AB8500_LAST_REG AB8500_AUDREV +#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1) + +#define AB8500_MASK_ALL 0xFF +#define AB8500_MASK_NONE 0x00 + +/* AB8500_POWERUP */ +#define AB8500_POWERUP_POWERUP 7 +#define AB8500_POWERUP_ENANA 3 + +/* AB8500_AUDSWRESET */ +#define AB8500_AUDSWRESET_SWRESET 7 + +/* AB8500_ADPATHENA */ +#define AB8500_ADPATHENA_ENAD12 7 +#define AB8500_ADPATHENA_ENAD34 5 +#define AB8500_ADPATHENA_ENAD5768 3 + +/* AB8500_DAPATHENA */ +#define AB8500_DAPATHENA_ENDA1 7 +#define AB8500_DAPATHENA_ENDA2 6 +#define AB8500_DAPATHENA_ENDA3 5 +#define AB8500_DAPATHENA_ENDA4 4 +#define AB8500_DAPATHENA_ENDA5 3 +#define AB8500_DAPATHENA_ENDA6 2 + +/* AB8500_ANACONF1 */ +#define AB8500_ANACONF1_HSLOWPOW 7 +#define AB8500_ANACONF1_DACLOWPOW1 6 +#define AB8500_ANACONF1_DACLOWPOW0 5 +#define AB8500_ANACONF1_EARDACLOWPOW 4 +#define AB8500_ANACONF1_EARSELCM 2 +#define AB8500_ANACONF1_HSHPEN 1 +#define AB8500_ANACONF1_EARDRVLOWPOW 0 + +/* AB8500_ANACONF2 */ +#define AB8500_ANACONF2_ENMIC1 7 +#define AB8500_ANACONF2_ENMIC2 6 +#define AB8500_ANACONF2_ENLINL 5 +#define AB8500_ANACONF2_ENLINR 4 +#define AB8500_ANACONF2_MUTMIC1 3 +#define AB8500_ANACONF2_MUTMIC2 2 +#define AB8500_ANACONF2_MUTLINL 1 +#define AB8500_ANACONF2_MUTLINR 0 + +/* AB8500_DIGMICCONF */ +#define AB8500_DIGMICCONF_ENDMIC1 7 +#define AB8500_DIGMICCONF_ENDMIC2 6 +#define AB8500_DIGMICCONF_ENDMIC3 5 +#define AB8500_DIGMICCONF_ENDMIC4 4 +#define AB8500_DIGMICCONF_ENDMIC5 3 +#define AB8500_DIGMICCONF_ENDMIC6 2 +#define AB8500_DIGMICCONF_HSFADSPEED 0 + +/* AB8500_ANACONF3 */ +#define AB8500_ANACONF3_MIC1SEL 7 +#define AB8500_ANACONF3_LINRSEL 6 +#define AB8500_ANACONF3_ENDRVHSL 5 +#define AB8500_ANACONF3_ENDRVHSR 4 +#define AB8500_ANACONF3_ENADCMIC 2 +#define AB8500_ANACONF3_ENADCLINL 1 +#define AB8500_ANACONF3_ENADCLINR 0 + +/* AB8500_ANACONF4 */ +#define AB8500_ANACONF4_DISPDVSS 7 +#define AB8500_ANACONF4_ENEAR 6 +#define AB8500_ANACONF4_ENHSL 5 +#define AB8500_ANACONF4_ENHSR 4 +#define AB8500_ANACONF4_ENHFL 3 +#define AB8500_ANACONF4_ENHFR 2 +#define AB8500_ANACONF4_ENVIB1 1 +#define AB8500_ANACONF4_ENVIB2 0 + +/* AB8500_DAPATHCONF */ +#define AB8500_DAPATHCONF_ENDACEAR 6 +#define AB8500_DAPATHCONF_ENDACHSL 5 +#define AB8500_DAPATHCONF_ENDACHSR 4 +#define AB8500_DAPATHCONF_ENDACHFL 3 +#define AB8500_DAPATHCONF_ENDACHFR 2 +#define AB8500_DAPATHCONF_ENDACVIB1 1 +#define AB8500_DAPATHCONF_ENDACVIB2 0 + +/* AB8500_MUTECONF */ +#define AB8500_MUTECONF_MUTEAR 6 +#define AB8500_MUTECONF_MUTHSL 5 +#define AB8500_MUTECONF_MUTHSR 4 +#define AB8500_MUTECONF_MUTDACEAR 2 +#define AB8500_MUTECONF_MUTDACHSL 1 +#define AB8500_MUTECONF_MUTDACHSR 0 + +/* AB8500_SHORTCIRCONF */ +#define AB8500_SHORTCIRCONF_ENSHORTPWD 7 +#define AB8500_SHORTCIRCONF_EARSHORTDIS 6 +#define AB8500_SHORTCIRCONF_HSSHORTDIS 5 +#define AB8500_SHORTCIRCONF_HSPULLDEN 4 +#define AB8500_SHORTCIRCONF_HSOSCEN 2 +#define AB8500_SHORTCIRCONF_HSFADDIS 1 +#define AB8500_SHORTCIRCONF_HSZCDDIS 0 +/* Zero cross should be disabled */ + +/* AB8500_ANACONF5 */ +#define AB8500_ANACONF5_ENCPHS 7 +#define AB8500_ANACONF5_HSLDACTOLOL 5 +#define AB8500_ANACONF5_HSRDACTOLOR 4 +#define AB8500_ANACONF5_ENLOL 3 +#define AB8500_ANACONF5_ENLOR 2 +#define AB8500_ANACONF5_HSAUTOEN 0 + +/* AB8500_ENVCPCONF */ +#define AB8500_ENVCPCONF_ENVDETHTHRE 4 +#define AB8500_ENVCPCONF_ENVDETLTHRE 0 +#define AB8500_ENVCPCONF_ENVDETHTHRE_MAX 0x0F +#define AB8500_ENVCPCONF_ENVDETLTHRE_MAX 0x0F + +/* AB8500_SIGENVCONF */ +#define AB8500_SIGENVCONF_CPLVEN 5 +#define AB8500_SIGENVCONF_ENVDETCPEN 4 +#define AB8500_SIGENVCONF_ENVDETTIME 0 +#define AB8500_SIGENVCONF_ENVDETTIME_MAX 0x0F + +/* AB8500_PWMGENCONF1 */ +#define AB8500_PWMGENCONF1_PWMTOVIB1 7 +#define AB8500_PWMGENCONF1_PWMTOVIB2 6 +#define AB8500_PWMGENCONF1_PWM1CTRL 5 +#define AB8500_PWMGENCONF1_PWM2CTRL 4 +#define AB8500_PWMGENCONF1_PWM1NCTRL 3 +#define AB8500_PWMGENCONF1_PWM1PCTRL 2 +#define AB8500_PWMGENCONF1_PWM2NCTRL 1 +#define AB8500_PWMGENCONF1_PWM2PCTRL 0 + +/* AB8500_PWMGENCONF2 */ +/* AB8500_PWMGENCONF3 */ +/* AB8500_PWMGENCONF4 */ +/* AB8500_PWMGENCONF5 */ +#define AB8500_PWMGENCONFX_PWMVIBXPOL 7 +#define AB8500_PWMGENCONFX_PWMVIBXDUTCYC 0 +#define AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX 0x64 + +/* AB8500_ANAGAIN1 */ +/* AB8500_ANAGAIN2 */ +#define AB8500_ANAGAINX_ENSEMICX 7 +#define AB8500_ANAGAINX_LOWPOWMICX 6 +#define AB8500_ANAGAINX_MICXGAIN 0 +#define AB8500_ANAGAINX_MICXGAIN_MAX 0x1F + +/* AB8500_ANAGAIN3 */ +#define AB8500_ANAGAIN3_HSLGAIN 4 +#define AB8500_ANAGAIN3_HSRGAIN 0 +#define AB8500_ANAGAIN3_HSXGAIN_MAX 0x0F + +/* AB8500_ANAGAIN4 */ +#define AB8500_ANAGAIN4_LINLGAIN 4 +#define AB8500_ANAGAIN4_LINRGAIN 0 +#define AB8500_ANAGAIN4_LINXGAIN_MAX 0x0F + +/* AB8500_DIGLINHSLGAIN */ +/* AB8500_DIGLINHSRGAIN */ +#define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN 0 +#define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX 0x13 + +/* AB8500_ADFILTCONF */ +#define AB8500_ADFILTCONF_AD1NH 7 +#define AB8500_ADFILTCONF_AD2NH 6 +#define AB8500_ADFILTCONF_AD3NH 5 +#define AB8500_ADFILTCONF_AD4NH 4 +#define AB8500_ADFILTCONF_AD1VOICE 3 +#define AB8500_ADFILTCONF_AD2VOICE 2 +#define AB8500_ADFILTCONF_AD3VOICE 1 +#define AB8500_ADFILTCONF_AD4VOICE 0 + +/* AB8500_DIGIFCONF1 */ +#define AB8500_DIGIFCONF1_ENMASTGEN 7 +#define AB8500_DIGIFCONF1_IF1BITCLKOS1 6 +#define AB8500_DIGIFCONF1_IF1BITCLKOS0 5 +#define AB8500_DIGIFCONF1_ENFSBITCLK1 4 +#define AB8500_DIGIFCONF1_IF0BITCLKOS1 2 +#define AB8500_DIGIFCONF1_IF0BITCLKOS0 1 +#define AB8500_DIGIFCONF1_ENFSBITCLK0 0 + +/* AB8500_DIGIFCONF2 */ +#define AB8500_DIGIFCONF2_FSYNC0P 6 +#define AB8500_DIGIFCONF2_BITCLK0P 5 +#define AB8500_DIGIFCONF2_IF0DEL 4 +#define AB8500_DIGIFCONF2_IF0FORMAT1 3 +#define AB8500_DIGIFCONF2_IF0FORMAT0 2 +#define AB8500_DIGIFCONF2_IF0WL1 1 +#define AB8500_DIGIFCONF2_IF0WL0 0 + +/* AB8500_DIGIFCONF3 */ +#define AB8500_DIGIFCONF3_IF0DATOIF1AD 7 +#define AB8500_DIGIFCONF3_IF0CLKTOIF1CLK 6 +#define AB8500_DIGIFCONF3_IF1MASTER 5 +#define AB8500_DIGIFCONF3_IF1DATOIF0AD 3 +#define AB8500_DIGIFCONF3_IF1CLKTOIF0CLK 2 +#define AB8500_DIGIFCONF3_IF0MASTER 1 +#define AB8500_DIGIFCONF3_IF0BFIFOEN 0 + +/* AB8500_DIGIFCONF4 */ +#define AB8500_DIGIFCONF4_FSYNC1P 6 +#define AB8500_DIGIFCONF4_BITCLK1P 5 +#define AB8500_DIGIFCONF4_IF1DEL 4 +#define AB8500_DIGIFCONF4_IF1FORMAT1 3 +#define AB8500_DIGIFCONF4_IF1FORMAT0 2 +#define AB8500_DIGIFCONF4_IF1WL1 1 +#define AB8500_DIGIFCONF4_IF1WL0 0 + +/* AB8500_ADSLOTSELX */ +#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00 +#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x01 +#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x02 +#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x03 +#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x04 +#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x05 +#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x06 +#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x07 +#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x08 +#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F +#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00 +#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10 +#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20 +#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30 +#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40 +#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50 +#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60 +#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70 +#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x80 +#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0xF0 +#define AB8500_ADSLOTSELX_EVEN_SHIFT 0 +#define AB8500_ADSLOTSELX_ODD_SHIFT 4 + +/* AB8500_ADSLOTHIZCTRL1 */ +/* AB8500_ADSLOTHIZCTRL2 */ +/* AB8500_ADSLOTHIZCTRL3 */ +/* AB8500_ADSLOTHIZCTRL4 */ +/* AB8500_DASLOTCONF1 */ +#define AB8500_DASLOTCONF1_DA12VOICE 7 +#define AB8500_DASLOTCONF1_SWAPDA12_34 6 +#define AB8500_DASLOTCONF1_DAI7TOADO1 5 + +/* AB8500_DASLOTCONF2 */ +#define AB8500_DASLOTCONF2_DAI8TOADO2 5 + +/* AB8500_DASLOTCONF3 */ +#define AB8500_DASLOTCONF3_DA34VOICE 7 +#define AB8500_DASLOTCONF3_DAI7TOADO3 5 + +/* AB8500_DASLOTCONF4 */ +#define AB8500_DASLOTCONF4_DAI8TOADO4 5 + +/* AB8500_DASLOTCONF5 */ +#define AB8500_DASLOTCONF5_DA56VOICE 7 +#define AB8500_DASLOTCONF5_DAI7TOADO5 5 + +/* AB8500_DASLOTCONF6 */ +#define AB8500_DASLOTCONF6_DAI8TOADO6 5 + +/* AB8500_DASLOTCONF7 */ +#define AB8500_DASLOTCONF7_DAI8TOADO7 5 + +/* AB8500_DASLOTCONF8 */ +#define AB8500_DASLOTCONF8_DAI7TOADO8 5 + +#define AB8500_DASLOTCONFX_SLTODAX_SHIFT 0 +#define AB8500_DASLOTCONFX_SLTODAX_MASK 0x1F + +/* AB8500_CLASSDCONF1 */ +#define AB8500_CLASSDCONF1_PARLHF 7 +#define AB8500_CLASSDCONF1_PARLVIB 6 +#define AB8500_CLASSDCONF1_VIB1SWAPEN 3 +#define AB8500_CLASSDCONF1_VIB2SWAPEN 2 +#define AB8500_CLASSDCONF1_HFLSWAPEN 1 +#define AB8500_CLASSDCONF1_HFRSWAPEN 0 + +/* AB8500_CLASSDCONF2 */ +#define AB8500_CLASSDCONF2_FIRBYP3 7 +#define AB8500_CLASSDCONF2_FIRBYP2 6 +#define AB8500_CLASSDCONF2_FIRBYP1 5 +#define AB8500_CLASSDCONF2_FIRBYP0 4 +#define AB8500_CLASSDCONF2_HIGHVOLEN3 3 +#define AB8500_CLASSDCONF2_HIGHVOLEN2 2 +#define AB8500_CLASSDCONF2_HIGHVOLEN1 1 +#define AB8500_CLASSDCONF2_HIGHVOLEN0 0 + +/* AB8500_CLASSDCONF3 */ +#define AB8500_CLASSDCONF3_DITHHPGAIN 4 +#define AB8500_CLASSDCONF3_DITHHPGAIN_MAX 0x0A +#define AB8500_CLASSDCONF3_DITHWGAIN 0 +#define AB8500_CLASSDCONF3_DITHWGAIN_MAX 0x0A + +/* AB8500_DMICFILTCONF */ +#define AB8500_DMICFILTCONF_ANCINSEL 7 +#define AB8500_DMICFILTCONF_DA3TOEAR 6 +#define AB8500_DMICFILTCONF_DMIC1SINC3 5 +#define AB8500_DMICFILTCONF_DMIC2SINC3 4 +#define AB8500_DMICFILTCONF_DMIC3SINC3 3 +#define AB8500_DMICFILTCONF_DMIC4SINC3 2 +#define AB8500_DMICFILTCONF_DMIC5SINC3 1 +#define AB8500_DMICFILTCONF_DMIC6SINC3 0 + +/* AB8500_DIGMULTCONF1 */ +#define AB8500_DIGMULTCONF1_DATOHSLEN 7 +#define AB8500_DIGMULTCONF1_DATOHSREN 6 +#define AB8500_DIGMULTCONF1_AD1SEL 5 +#define AB8500_DIGMULTCONF1_AD2SEL 4 +#define AB8500_DIGMULTCONF1_AD3SEL 3 +#define AB8500_DIGMULTCONF1_AD5SEL 2 +#define AB8500_DIGMULTCONF1_AD6SEL 1 +#define AB8500_DIGMULTCONF1_ANCSEL 0 + +/* AB8500_DIGMULTCONF2 */ +#define AB8500_DIGMULTCONF2_DATOHFREN 7 +#define AB8500_DIGMULTCONF2_DATOHFLEN 6 +#define AB8500_DIGMULTCONF2_HFRSEL 5 +#define AB8500_DIGMULTCONF2_HFLSEL 4 +#define AB8500_DIGMULTCONF2_FIRSID1SEL 2 +#define AB8500_DIGMULTCONF2_FIRSID2SEL 0 + +/* AB8500_ADDIGGAIN1 */ +/* AB8500_ADDIGGAIN2 */ +/* AB8500_ADDIGGAIN3 */ +/* AB8500_ADDIGGAIN4 */ +/* AB8500_ADDIGGAIN5 */ +/* AB8500_ADDIGGAIN6 */ +#define AB8500_ADDIGGAINX_FADEDISADX 6 +#define AB8500_ADDIGGAINX_ADXGAIN_MAX 0x3F + +/* AB8500_DADIGGAIN1 */ +/* AB8500_DADIGGAIN2 */ +/* AB8500_DADIGGAIN3 */ +/* AB8500_DADIGGAIN4 */ +/* AB8500_DADIGGAIN5 */ +/* AB8500_DADIGGAIN6 */ +#define AB8500_DADIGGAINX_FADEDISDAX 6 +#define AB8500_DADIGGAINX_DAXGAIN_MAX 0x3F + +/* AB8500_ADDIGLOOPGAIN1 */ +/* AB8500_ADDIGLOOPGAIN2 */ +#define AB8500_ADDIGLOOPGAINX_FADEDISADXL 6 +#define AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX 0x3F + +/* AB8500_HSLEARDIGGAIN */ +#define AB8500_HSLEARDIGGAIN_HSSINC1 7 +#define AB8500_HSLEARDIGGAIN_FADEDISHSL 4 +#define AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX 0x09 + +/* AB8500_HSRDIGGAIN */ +#define AB8500_HSRDIGGAIN_FADESPEED 6 +#define AB8500_HSRDIGGAIN_FADEDISHSR 4 +#define AB8500_HSRDIGGAIN_HSRDGAIN_MAX 0x09 + +/* AB8500_SIDFIRGAIN1 */ +/* AB8500_SIDFIRGAIN2 */ +#define AB8500_SIDFIRGAINX_FIRSIDXGAIN_MAX 0x1F + +/* AB8500_ANCCONF1 */ +#define AB8500_ANCCONF1_ANCIIRUPDATE 3 +#define AB8500_ANCCONF1_ENANC 2 +#define AB8500_ANCCONF1_ANCIIRINIT 1 +#define AB8500_ANCCONF1_ANCFIRUPDATE 0 + +/* AB8500_ANCCONF2 */ +#define AB8500_ANCCONF2_SHIFT 5 +#define AB8500_ANCCONF2_MIN -0x10 +#define AB8500_ANCCONF2_MAX 0xF + +/* AB8500_ANCCONF3 */ +#define AB8500_ANCCONF3_SHIFT 5 +#define AB8500_ANCCONF3_MIN -0x10 +#define AB8500_ANCCONF3_MAX 0xF + +/* AB8500_ANCCONF4 */ +#define AB8500_ANCCONF4_SHIFT 5 +#define AB8500_ANCCONF4_MIN -0x10 +#define AB8500_ANCCONF4_MAX 0xF + +/* AB8500_ANC_FIR_COEFFS */ +#define AB8500_ANC_FIR_COEFF_MIN -0x8000 +#define AB8500_ANC_FIR_COEFF_MAX 0x7FFF +#define AB8500_ANC_FIR_COEFFS 15 + +/* AB8500_ANC_IIR_COEFFS */ +#define AB8500_ANC_IIR_COEFF_MIN -0x800000 +#define AB8500_ANC_IIR_COEFF_MAX 0x7FFFFF +#define AB8500_ANC_IIR_COEFFS 24 +/* AB8500_ANC_WARP_DELAY */ +#define AB8500_ANC_WARP_DELAY_SHIFT 16 +#define AB8500_ANC_WARP_DELAY_MIN 0x0000 +#define AB8500_ANC_WARP_DELAY_MAX 0xFFFF + +/* AB8500_ANCCONF11 */ +/* AB8500_ANCCONF12 */ +/* AB8500_ANCCONF13 */ +/* AB8500_ANCCONF14 */ + +/* AB8500_SIDFIRADR */ +#define AB8500_SIDFIRADR_FIRSIDSET 7 +#define AB8500_SIDFIRADR_ADDRESS_SHIFT 0 +#define AB8500_SIDFIRADR_ADDRESS_MAX 0x7F + +/* AB8500_SIDFIRCOEF1 */ +/* AB8500_SIDFIRCOEF2 */ +#define AB8500_SID_FIR_COEFF_MIN 0 +#define AB8500_SID_FIR_COEFF_MAX 0xFFFF +#define AB8500_SID_FIR_COEFFS 128 + +/* AB8500_SIDFIRCONF */ +#define AB8500_SIDFIRCONF_ENFIRSIDS 2 +#define AB8500_SIDFIRCONF_FIRSIDSTOIF1 1 +#define AB8500_SIDFIRCONF_FIRSIDBUSY 0 + +/* AB8500_AUDINTMASK1 */ +/* AB8500_AUDINTSOURCE1 */ +/* AB8500_AUDINTMASK2 */ +/* AB8500_AUDINTSOURCE2 */ + +/* AB8500_FIFOCONF1 */ +#define AB8500_FIFOCONF1_BFIFOMASK 0x80 +#define AB8500_FIFOCONF1_BFIFO19M2 0x40 +#define AB8500_FIFOCONF1_BFIFOINT_SHIFT 0 +#define AB8500_FIFOCONF1_BFIFOINT_MAX 0x3F + +/* AB8500_FIFOCONF2 */ +#define AB8500_FIFOCONF2_BFIFOTX_SHIFT 0 +#define AB8500_FIFOCONF2_BFIFOTX_MAX 0xFF + +/* AB8500_FIFOCONF3 */ +#define AB8500_FIFOCONF3_BFIFOEXSL_SHIFT 5 +#define AB8500_FIFOCONF3_BFIFOEXSL_MAX 0x5 +#define AB8500_FIFOCONF3_PREBITCLK0_SHIFT 2 +#define AB8500_FIFOCONF3_PREBITCLK0_MAX 0x7 +#define AB8500_FIFOCONF3_BFIFOMAST_SHIFT 1 +#define AB8500_FIFOCONF3_BFIFORUN_SHIFT 0 + +/* AB8500_FIFOCONF4 */ +#define AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT 0 +#define AB8500_FIFOCONF4_BFIFOFRAMSW_MAX 0xFF + +/* AB8500_FIFOCONF5 */ +#define AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT 0 +#define AB8500_FIFOCONF5_BFIFOWAKEUP_MAX 0xFF + +/* AB8500_FIFOCONF6 */ +#define AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT 0 +#define AB8500_FIFOCONF6_BFIFOSAMPLE_MAX 0xFF + +/* AB8500_AUDREV */ + +#endif -- GitLab From 578df8babf3b1895d562e1ea0d3a81d1e77e0182 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 11 Jun 2012 13:14:50 +0800 Subject: [PATCH 1040/6849] regulator: core: Return correct delay time in regulator_set_voltage_time_sel rdev->desc->uV_step * abs(new_selector - old_selector) returns uV. The unit of ramp_delay is mV/us. Current code multiples 1000 at wrong place. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ff76abde3ab3..6ffca9b32388 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2299,7 +2299,7 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, if (rdev->desc->ramp_delay && rdev->desc->uV_step) return DIV_ROUND_UP(rdev->desc->uV_step * abs(new_selector - old_selector), - rdev->desc->ramp_delay) * 1000; + rdev->desc->ramp_delay * 1000); return 0; } -- GitLab From 3ddd53f392c4f8e19e1110d1bdef770008b128b8 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Mon, 11 Jun 2012 11:59:10 +0800 Subject: [PATCH 1041/6849] cfg80211: add missing kernel-doc for mesh configuration structure Add the missing kernel-doc for mesh configuration parameters as pointed out by Johannes Berg. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 59 +++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7319f25250b6..a129ee2f5483 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -790,26 +790,69 @@ struct bss_parameters { int ht_opmode; }; -/* +/** * struct mesh_config - 802.11s mesh configuration * * These parameters can be changed while the mesh is active. + * + * @dot11MeshRetryTimeout: the initial retry timeout in millisecond units used + * by the Mesh Peering Open message + * @dot11MeshConfirmTimeout: the initial retry timeout in millisecond units + * used by the Mesh Peering Open message + * @dot11MeshHoldingTimeout: the confirm timeout in millisecond units used by + * the mesh peering management to close a mesh peering + * @dot11MeshMaxPeerLinks: the maximum number of peer links allowed on this + * mesh interface + * @dot11MeshMaxRetries: the maximum number of peer link open retries that can + * be sent to establish a new peer link instance in a mesh + * @dot11MeshTTL: the value of TTL field set at a source mesh STA + * @element_ttl: the value of TTL field set at a mesh STA for path selection + * elements + * @auto_open_plinks: whether we should automatically open peer links when we + * detect compatible mesh peers + * @dot11MeshNbrOffsetMaxNeighbor: the maximum number of neighbors to + * synchronize to for 11s default synchronization method + * @dot11MeshHWMPmaxPREQretries: the number of action frames containing a PREQ + * that an originator mesh STA can send to a particular path target + * @path_refresh_time: how frequently to refresh mesh paths in milliseconds + * @min_discovery_timeout: the minimum length of time to wait until giving up on + * a path discovery in milliseconds + * @dot11MeshHWMPactivePathTimeout: the time (in TUs) for which mesh STAs + * receiving a PREQ shall consider the forwarding information from the + * root to be valid. (TU = time unit) + * @dot11MeshHWMPpreqMinInterval: the minimum interval of time (in TUs) during + * which a mesh STA can send only one action frame containing a PREQ + * element + * @dot11MeshHWMPperrMinInterval: the minimum interval of time (in TUs) during + * which a mesh STA can send only one Action frame containing a PERR + * element + * @dot11MeshHWMPnetDiameterTraversalTime: the interval of time (in TUs) that + * it takes for an HWMP information element to propagate across the mesh + * @dot11MeshHWMPRootMode: the configuration of a mesh STA as root mesh STA + * @dot11MeshHWMPRannInterval: the interval of time (in TUs) between root + * announcements are transmitted + * @dot11MeshGateAnnouncementProtocol: whether to advertise that this mesh + * station has access to a broader network beyond the MBSS. (This is + * missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol set to true + * only means that the station will announce others it's a mesh gate, but + * not necessarily using the gate announcement protocol. Still keeping the + * same nomenclature to be in sync with the spec) + * @dot11MeshForwarding: whether the Mesh STA is forwarding or non-forwarding + * entity (default is TRUE - forwarding entity) + * @rssi_threshold: the threshold for average signal strength of candidate + * station to establish a peer link + * @ht_opmode: mesh HT protection mode */ struct mesh_config { - /* Timeouts in ms */ - /* Mesh plink management parameters */ u16 dot11MeshRetryTimeout; u16 dot11MeshConfirmTimeout; u16 dot11MeshHoldingTimeout; u16 dot11MeshMaxPeerLinks; u8 dot11MeshMaxRetries; u8 dot11MeshTTL; - /* ttl used in path selection information elements */ u8 element_ttl; bool auto_open_plinks; - /* neighbor offset synchronization */ u32 dot11MeshNbrOffsetMaxNeighbor; - /* HWMP parameters */ u8 dot11MeshHWMPmaxPREQretries; u32 path_refresh_time; u16 min_discovery_timeout; @@ -819,10 +862,6 @@ struct mesh_config { u16 dot11MeshHWMPnetDiameterTraversalTime; u8 dot11MeshHWMPRootMode; u16 dot11MeshHWMPRannInterval; - /* This is missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol - * set to true only means that the station will announce others it's a - * mesh gate, but not necessarily using the gate announcement protocol. - * Still keeping the same nomenclature to be in sync with the spec. */ bool dot11MeshGateAnnouncementProtocol; bool dot11MeshForwarding; s32 rssi_threshold; -- GitLab From a4f606ea73d56d15f28653d2242e54d58bb612e5 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Mon, 11 Jun 2012 11:59:36 +0800 Subject: [PATCH 1042/6849] {nl,cfg,mac}80211: fix the coding style related to mesh parameters fix the coding style related to mesh parameters, especially the indentation, as pointed out by Johannes Berg. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 6 +-- include/linux/nl80211.h | 98 ++++++++++++++++++----------------- include/net/cfg80211.h | 12 ++--- net/mac80211/cfg.c | 3 +- net/mac80211/debugfs_netdev.c | 34 ++++++------ net/wireless/nl80211.c | 97 ++++++++++++++++++---------------- 6 files changed, 130 insertions(+), 120 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index ce9af8918514..f831078182de 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1443,7 +1443,7 @@ enum ieee80211_tdls_actioncode { * * @IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET: the default synchronization method * @IEEE80211_SYNC_METHOD_VENDOR: a vendor specific synchronization method - * that will be specified in a vendor specific information element + * that will be specified in a vendor specific information element */ enum { IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET = 1, @@ -1455,7 +1455,7 @@ enum { * * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will - * be specified in a vendor specific information element + * be specified in a vendor specific information element */ enum { IEEE80211_PATH_PROTOCOL_HWMP = 1, @@ -1467,7 +1467,7 @@ enum { * * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be - * specified in a vendor specific information element + * specified in a vendor specific information element */ enum { IEEE80211_PATH_METRIC_AIRTIME = 1, diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 970afdf5a605..c61e1621822c 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -2090,78 +2090,80 @@ enum nl80211_mntr_flags { * @__NL80211_MESHCONF_INVALID: internal use * * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in - * millisecond units, used by the Peer Link Open message + * millisecond units, used by the Peer Link Open message * * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in - * millisecond units, used by the peer link management to close a peer link + * millisecond units, used by the peer link management to close a peer link * * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in - * millisecond units + * millisecond units * * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed - * on this mesh interface + * on this mesh interface * * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link - * open retries that can be sent to establish a new peer link instance in a - * mesh + * open retries that can be sent to establish a new peer link instance in a + * mesh * * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh - * point. + * point. * * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically - * open peer links when we detect compatible mesh peers. + * open peer links when we detect compatible mesh peers. * * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames - * containing a PREQ that an MP can send to a particular destination (path - * target) + * containing a PREQ that an MP can send to a particular destination (path + * target) * * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths - * (in milliseconds) + * (in milliseconds) * * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait - * until giving up on a path discovery (in milliseconds) + * until giving up on a path discovery (in milliseconds) * * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh - * points receiving a PREQ shall consider the forwarding information from the - * root to be valid. (TU = time unit) + * points receiving a PREQ shall consider the forwarding information from + * the root to be valid. (TU = time unit) * * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in - * TUs) during which an MP can send only one action frame containing a PREQ - * reference element + * TUs) during which an MP can send only one action frame containing a PREQ + * reference element * * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) - * that it takes for an HWMP information element to propagate across the mesh + * that it takes for an HWMP information element to propagate across the + * mesh * * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not * * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a - * source mesh point for path selection elements. + * source mesh point for path selection elements. * * @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between - * root announcements are transmitted. + * root announcements are transmitted. * * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has - * access to a broader network beyond the MBSS. This is done via Root - * Announcement frames. + * access to a broader network beyond the MBSS. This is done via Root + * Announcement frames. * * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in - * TUs) during which a mesh STA can send only one Action frame containing a - * PERR element. + * TUs) during which a mesh STA can send only one Action frame containing a + * PERR element. * * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding - * or forwarding entity (default is TRUE - forwarding entity) + * or forwarding entity (default is TRUE - forwarding entity) * * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the - * threshold for average signal strength of candidate station to establish - * a peer link. - * - * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute + * threshold for average signal strength of candidate station to establish + * a peer link. * * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors - * to synchronize to for 11s default synchronization method (see 11C.12.2.2) + * to synchronize to for 11s default synchronization method + * (see 11C.12.2.2) * * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode. * + * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute + * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params { @@ -2203,34 +2205,36 @@ enum nl80211_meshconf_params { * @__NL80211_MESH_SETUP_INVALID: Internal use * * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a - * vendor specific path selection algorithm or disable it to use the default - * HWMP. + * vendor specific path selection algorithm or disable it to use the + * default HWMP. * * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a - * vendor specific path metric or disable it to use the default Airtime - * metric. + * vendor specific path metric or disable it to use the default Airtime + * metric. * * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a - * robust security network ie, or a vendor specific information element that - * vendors will use to identify the path selection methods and metrics in use. + * robust security network ie, or a vendor specific information element + * that vendors will use to identify the path selection methods and + * metrics in use. * * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication - * daemon will be authenticating mesh candidates. + * daemon will be authenticating mesh candidates. * * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication - * daemon will be securing peer link frames. AMPE is a secured version of Mesh - * Peering Management (MPM) and is implemented with the assistance of a - * userspace daemon. When this flag is set, the kernel will send peer - * management frames to a userspace daemon that will implement AMPE - * functionality (security capabilities selection, key confirmation, and key - * management). When the flag is unset (default), the kernel can autonomously - * complete (unsecured) mesh peering without the need of a userspace daemon. - * - * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number + * daemon will be securing peer link frames. AMPE is a secured version of + * Mesh Peering Management (MPM) and is implemented with the assistance of + * a userspace daemon. When this flag is set, the kernel will send peer + * management frames to a userspace daemon that will implement AMPE + * functionality (security capabilities selection, key confirmation, and + * key management). When the flag is unset (default), the kernel can + * autonomously complete (unsecured) mesh peering without the need of a + * userspace daemon. * * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a - * vendor specific synchronization method or disable it to use the default - * neighbor offset synchronization + * vendor specific synchronization method or disable it to use the default + * neighbor offset synchronization + * + * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a129ee2f5483..778e533a9734 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -848,21 +848,21 @@ struct mesh_config { u16 dot11MeshConfirmTimeout; u16 dot11MeshHoldingTimeout; u16 dot11MeshMaxPeerLinks; - u8 dot11MeshMaxRetries; - u8 dot11MeshTTL; - u8 element_ttl; + u8 dot11MeshMaxRetries; + u8 dot11MeshTTL; + u8 element_ttl; bool auto_open_plinks; u32 dot11MeshNbrOffsetMaxNeighbor; - u8 dot11MeshHWMPmaxPREQretries; + u8 dot11MeshHWMPmaxPREQretries; u32 path_refresh_time; u16 min_discovery_timeout; u32 dot11MeshHWMPactivePathTimeout; u16 dot11MeshHWMPpreqMinInterval; u16 dot11MeshHWMPperrMinInterval; u16 dot11MeshHWMPnetDiameterTraversalTime; - u8 dot11MeshHWMPRootMode; + u8 dot11MeshHWMPRootMode; u16 dot11MeshHWMPRannInterval; - bool dot11MeshGateAnnouncementProtocol; + bool dot11MeshGateAnnouncementProtocol; bool dot11MeshForwarding; s32 rssi_threshold; u16 ht_opmode; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 498c94e34427..f41f9bea242a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1571,10 +1571,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, conf->dot11MeshGateAnnouncementProtocol = nconf->dot11MeshGateAnnouncementProtocol; } - if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) { + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) conf->dot11MeshHWMPRannInterval = nconf->dot11MeshHWMPRannInterval; - } if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) conf->dot11MeshForwarding = nconf->dot11MeshForwarding; if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index d4272ff43f71..c429417e1322 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -468,45 +468,45 @@ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); IEEE80211_IF_FILE(dropped_frames_congestion, - u.mesh.mshstats.dropped_frames_congestion, DEC); + u.mesh.mshstats.dropped_frames_congestion, DEC); IEEE80211_IF_FILE(dropped_frames_no_route, - u.mesh.mshstats.dropped_frames_no_route, DEC); + u.mesh.mshstats.dropped_frames_no_route, DEC); IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); /* Mesh parameters */ IEEE80211_IF_FILE(dot11MeshMaxRetries, - u.mesh.mshcfg.dot11MeshMaxRetries, DEC); + u.mesh.mshcfg.dot11MeshMaxRetries, DEC); IEEE80211_IF_FILE(dot11MeshRetryTimeout, - u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); + u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); IEEE80211_IF_FILE(dot11MeshConfirmTimeout, - u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); + u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); IEEE80211_IF_FILE(dot11MeshHoldingTimeout, - u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); + u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, - u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); + u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, - u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); + u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, - u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); + u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, - u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); + u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, - u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); + u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, - u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); + u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); IEEE80211_IF_FILE(path_refresh_time, - u.mesh.mshcfg.path_refresh_time, DEC); + u.mesh.mshcfg.path_refresh_time, DEC); IEEE80211_IF_FILE(min_discovery_timeout, - u.mesh.mshcfg.min_discovery_timeout, DEC); + u.mesh.mshcfg.min_discovery_timeout, DEC); IEEE80211_IF_FILE(dot11MeshHWMPRootMode, - u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); + u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, - u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); + u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, - u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); + u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7ae54b82291f..dd94ee5fb40a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -115,7 +115,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, - .len = IEEE80211_MAX_MESH_ID_LEN }, + .len = IEEE80211_MAX_MESH_ID_LEN }, [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, @@ -3492,7 +3492,6 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, - [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, @@ -3504,8 +3503,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, - [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, - [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16}, + [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 }, + [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, }; static const struct nla_policy @@ -3515,7 +3514,7 @@ static const struct nla_policy [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, - .len = IEEE80211_MAX_DATA_LEN }, + .len = IEEE80211_MAX_DATA_LEN }, [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, }; @@ -3548,63 +3547,71 @@ do {\ /* Fill in the params struct */ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, - mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); + mask, NL80211_MESHCONF_RETRY_TIMEOUT, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, - mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16); + mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, - mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16); + mask, NL80211_MESHCONF_HOLDING_TIMEOUT, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, - mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16); + mask, NL80211_MESHCONF_MAX_PEER_LINKS, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, - mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8); + mask, NL80211_MESHCONF_MAX_RETRIES, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, - mask, NL80211_MESHCONF_TTL, nla_get_u8); + mask, NL80211_MESHCONF_TTL, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, - mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); + mask, NL80211_MESHCONF_ELEMENT_TTL, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, - mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, - mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, - nla_get_u32); + mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, + nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask, + NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, + nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, - mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, - nla_get_u8); + mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, - mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32); + mask, NL80211_MESHCONF_PATH_REFRESH_TIME, + nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, - mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, - mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, - nla_get_u32); + mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, + nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask, + NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, + nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, - mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, - nla_get_u16); + mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, - mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshHWMPnetDiameterTraversalTime, - mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshHWMPRootMode, mask, - NL80211_MESHCONF_HWMP_ROOTMODE, - nla_get_u8); + mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshHWMPRannInterval, mask, - NL80211_MESHCONF_HWMP_RANN_INTERVAL, - nla_get_u16); + dot11MeshHWMPnetDiameterTraversalTime, mask, + NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, + nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask, + NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask, + NL80211_MESHCONF_HWMP_RANN_INTERVAL, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshGateAnnouncementProtocol, mask, - NL80211_MESHCONF_GATE_ANNOUNCEMENTS, - nla_get_u8); + dot11MeshGateAnnouncementProtocol, mask, + NL80211_MESHCONF_GATE_ANNOUNCEMENTS, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, - mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); + mask, NL80211_MESHCONF_FORWARDING, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, - mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); + mask, NL80211_MESHCONF_RSSI_THRESHOLD, + nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, - mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16); + mask, NL80211_MESHCONF_HT_OPMODE, + nla_get_u16); if (mask_out) *mask_out = mask; -- GitLab From e9071b0be5e7ce4903b7f7c370769d485774d3e3 Mon Sep 17 00:00:00 2001 From: Donald Dutile Date: Fri, 8 Jun 2012 17:13:11 -0400 Subject: [PATCH 1043/6849] iommu/dmar: Use pr_format() instead of PREFIX to tidy up pr_*() calls Joe Perches recommended getting rid of the redundant formatting of adding "PREFIX" to all the uses of pr_*() calls. The recommendation helps to reduce source and improve readibility. While cleaning up the PREFIX's, I saw that one of the pr_warn() was redundant in dmar_parse_one_dev_scope(), since the same message was printed after breaking out of the while loop for the same condition, !pdev. So, to avoid a duplicate message, I removed the one in the while loop. Reported-by: Joe Perches Signed-off-by: Donald Dutile Cc: iommu@lists.linux-foundation.org Cc: chrisw@redhat.com Cc: suresh.b.siddha@intel.com Cc: dwmw2@infradead.org Link: http://lkml.kernel.org/r/1339189991-13129-1-git-send-email-ddutile@redhat.com [ Small whitespace fixes. ] Signed-off-by: Ingo Molnar --- drivers/iommu/dmar.c | 54 ++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 9ab6ebf46f7a..86e2f4a62b9a 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -26,6 +26,8 @@ * These routines are used by both DMA-remapping and Interrupt-remapping */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* has to precede printk.h */ + #include #include #include @@ -39,8 +41,6 @@ #include #include -#define PREFIX "DMAR: " - /* No locks are needed as DMA remapping hardware unit * list is constructed at boot time and hotplug of * these units are not supported by the architecture. @@ -83,15 +83,12 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, * ignore it */ if (!bus) { - pr_warn(PREFIX "Device scope bus [%d] not found\n", - scope->bus); + pr_warn("Device scope bus [%d] not found\n", scope->bus); break; } pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn)); if (!pdev) { - pr_warn(PREFIX "Device scope device" - "[%04x:%02x:%02x.%02x] not found\n", - segment, bus->number, path->dev, path->fn); + /* warning will be printed below */ break; } path ++; @@ -99,8 +96,7 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, bus = pdev->subordinate; } if (!pdev) { - pr_warn(PREFIX - "Device scope device [%04x:%02x:%02x.%02x] not found\n", + pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n", segment, scope->bus, path->dev, path->fn); *dev = NULL; return 0; @@ -109,8 +105,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, pdev->subordinate) || (scope->entry_type == \ ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) { pci_dev_put(pdev); - pr_warn(PREFIX "Device scope type does not match for %s\n", - pci_name(pdev)); + pr_warn("Device scope type does not match for %s\n", + pci_name(pdev)); return -EINVAL; } *dev = pdev; @@ -132,7 +128,7 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) (*cnt)++; else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) { - pr_warn(PREFIX "Unsupported device scope\n"); + pr_warn("Unsupported device scope\n"); } start += scope->length; } @@ -258,23 +254,23 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) case ACPI_DMAR_TYPE_HARDWARE_UNIT: drhd = container_of(header, struct acpi_dmar_hardware_unit, header); - pr_info(PREFIX "DRHD base: %#016Lx flags: %#x\n", + pr_info("DRHD base: %#016Lx flags: %#x\n", (unsigned long long)drhd->address, drhd->flags); break; case ACPI_DMAR_TYPE_RESERVED_MEMORY: rmrr = container_of(header, struct acpi_dmar_reserved_memory, header); - pr_info(PREFIX "RMRR base: %#016Lx end: %#016Lx\n", + pr_info("RMRR base: %#016Lx end: %#016Lx\n", (unsigned long long)rmrr->base_address, (unsigned long long)rmrr->end_address); break; case ACPI_DMAR_TYPE_ATSR: atsr = container_of(header, struct acpi_dmar_atsr, header); - pr_info(PREFIX "ATSR flags: %#x\n", atsr->flags); + pr_info("ATSR flags: %#x\n", atsr->flags); break; case ACPI_DMAR_HARDWARE_AFFINITY: rhsa = container_of(header, struct acpi_dmar_rhsa, header); - pr_info(PREFIX "RHSA base: %#016Lx proximity domain: %#x\n", + pr_info("RHSA base: %#016Lx proximity domain: %#x\n", (unsigned long long)rhsa->base_address, rhsa->proximity_domain); break; @@ -294,7 +290,7 @@ static int __init dmar_table_detect(void) &dmar_tbl_size); if (ACPI_SUCCESS(status) && !dmar_tbl) { - pr_warn(PREFIX "Unable to map DMAR\n"); + pr_warn("Unable to map DMAR\n"); status = AE_NOT_FOUND; } @@ -328,18 +324,18 @@ parse_dmar_table(void) return -ENODEV; if (dmar->width < PAGE_SHIFT - 1) { - pr_warn(PREFIX "Invalid DMAR haw\n"); + pr_warn("Invalid DMAR haw\n"); return -EINVAL; } - pr_info(PREFIX "Host address width %d\n", dmar->width + 1); + pr_info("Host address width %d\n", dmar->width + 1); entry_header = (struct acpi_dmar_header *)(dmar + 1); while (((unsigned long)entry_header) < (((unsigned long)dmar) + dmar_tbl->length)) { /* Avoid looping forever on bad ACPI tables */ if (entry_header->length == 0) { - pr_warn(PREFIX "Invalid 0-length structure\n"); + pr_warn("Invalid 0-length structure\n"); ret = -EINVAL; break; } @@ -362,7 +358,7 @@ parse_dmar_table(void) #endif break; default: - pr_warn(PREFIX "Unknown DMAR structure type %d\n", + pr_warn("Unknown DMAR structure type %d\n", entry_header->type); ret = 0; /* for forward compatibility */ break; @@ -461,12 +457,12 @@ int __init dmar_table_init(void) ret = parse_dmar_table(); if (ret) { if (ret != -ENODEV) - pr_info(PREFIX "parse DMAR table failure.\n"); + pr_info("parse DMAR table failure.\n"); return ret; } if (list_empty(&dmar_drhd_units)) { - pr_info(PREFIX "No DMAR devices found\n"); + pr_info("No DMAR devices found\n"); return -ENODEV; } @@ -498,7 +494,7 @@ int __init check_zero_address(void) (((unsigned long)dmar) + dmar_tbl->length)) { /* Avoid looping forever on bad ACPI tables */ if (entry_header->length == 0) { - pr_warn(PREFIX "Invalid 0-length structure\n"); + pr_warn("Invalid 0-length structure\n"); return 0; } @@ -549,8 +545,7 @@ int __init detect_intel_iommu(void) if (ret && irq_remapping_enabled && cpu_has_x2apic && dmar->flags & 0x1) - pr_info("Queued invalidation will be enabled to " - "support x2apic and Intr-remapping.\n"); + pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { iommu_detected = 1; @@ -580,9 +575,9 @@ static void unmap_iommu(struct intel_iommu *iommu) * map_iommu: map the iommu's registers * @iommu: the iommu to map * @phys_addr: the physical address of the base resgister - * + * * Memory map the iommu's registers. Start w/ a single page, and - * possibly expand if that turns out to be insufficent. + * possibly expand if that turns out to be insufficent. */ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) { @@ -1302,8 +1297,7 @@ int __init enable_drhd_fault_handling(void) ret = dmar_set_interrupt(iommu); if (ret) { - pr_err("DRHD %Lx: failed to enable fault, " - " interrupt, ret %d\n", + pr_err("DRHD %Lx: failed to enable fault, interrupt, ret %d\n", (unsigned long long)drhd->reg_base_addr, ret); return -1; } -- GitLab From e2b297fcf17fc03734e93387fb8195c782286b35 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Sun, 10 Jun 2012 21:13:41 -0600 Subject: [PATCH 1044/6849] perf/x86: Convert obsolete simple_strtoul() usage to kstrtoul() Signed-off-by: Shuah Khan Cc: Peter Zijlstra Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/1339384421.3025.8.camel@lorien2 Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 000a4746c7ce..766c76d5ec4c 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1640,7 +1640,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long val = simple_strtoul(buf, NULL, 0); + unsigned long val; + ssize_t ret; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; if (!!val != !!x86_pmu.attr_rdpmc) { x86_pmu.attr_rdpmc = !!val; -- GitLab From 110c1e1f1bf61e5dca53ff5c9dc75243ce87c002 Mon Sep 17 00:00:00 2001 From: Ravikiran Thirumalai Date: Sun, 3 Jun 2012 01:11:35 +0300 Subject: [PATCH 1045/6849] x86/vsmp: Ignore IOAPIC IRQ affinity if possible vSMP can route interrupts more optimally based on internal knowledge the OS does not have. In order to support this optimization, all CPUs must be able to handle all possible IOAPIC interrupts. Fix this by setting the vector allocation domain for all CPUs and by enabling this feature in vSMP. Signed-off-by: Ravikiran Thirumalai Signed-off-by: Shai Fultheim [ Rebased, simplified, and reworded the commit message. ] Signed-off-by: Ido Yariv Signed-off-by: Ingo Molnar --- arch/x86/kernel/vsmp_64.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 59eea855f451..6b96a7374f94 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -95,6 +96,15 @@ static void __init set_vsmp_pv_ops(void) ctl = readl(address + 4); printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n", cap, ctl); + + /* If possible, let the vSMP foundation route the interrupt optimally */ +#ifdef CONFIG_SMP + if (cap & ctl & BIT(8)) { + ctl &= ~BIT(8); + no_irq_affinity = 1; + } +#endif + if (cap & ctl & (1 << 4)) { /* Setup irq ops and turn on vSMP IRQ fastpath handling */ pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); @@ -102,12 +112,11 @@ static void __init set_vsmp_pv_ops(void) pv_irq_ops.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); pv_irq_ops.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); pv_init_ops.patch = vsmp_patch; - ctl &= ~(1 << 4); - writel(ctl, address + 4); - ctl = readl(address + 4); - printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl); } + writel(ctl, address + 4); + ctl = readl(address + 4); + pr_info("vSMP CTL: control set to:0x%08x\n", ctl); early_iounmap(address, 8); } @@ -192,10 +201,20 @@ static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) return hard_smp_processor_id() >> index_msb; } +/* + * In vSMP, all cpus should be capable of handling interrupts, regardless of + * the APIC used. + */ +static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_setall(retmask); +} + static void vsmp_apic_post_init(void) { /* need to update phys_pkg_id */ apic->phys_pkg_id = apicid_phys_pkg_id; + apic->vector_allocation_domain = fill_vector_allocation_domain; } void __init vsmp_init(void) -- GitLab From 97bab73f987e2781129cd6f4b6379bf44d808cc6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Jun 2012 22:36:36 -0700 Subject: [PATCH 1046/6849] inet: Hide route peer accesses behind helpers. We encode the pointer(s) into an unsigned long with one state bit. The state bit is used so we can store the inetpeer tree root to use when resolving the peer later. Later the peer roots will be per-FIB table, and this change works to facilitate that. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 54 +++++++++++++++++++++++++++++++++++++++ include/net/ip6_fib.h | 32 ++++++++++++++++++++++- include/net/ip6_route.h | 6 ++--- include/net/route.h | 42 ++++++++++++++++++++++++++++--- net/ipv4/route.c | 56 ++++++++++++++++++++++++----------------- net/ipv4/xfrm4_policy.c | 10 ++++---- net/ipv6/route.c | 42 ++++++++++++++++++------------- net/ipv6/xfrm6_policy.c | 10 ++++---- 8 files changed, 193 insertions(+), 59 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index b84b32fd5df1..d432489e7109 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -71,6 +71,60 @@ struct inet_peer_base { int total; }; +#define INETPEER_BASE_BIT 0x1UL + +static inline struct inet_peer *inetpeer_ptr(unsigned long val) +{ + BUG_ON(val & INETPEER_BASE_BIT); + return (struct inet_peer *) val; +} + +static inline struct inet_peer_base *inetpeer_base_ptr(unsigned long val) +{ + if (!(val & INETPEER_BASE_BIT)) + return NULL; + val &= ~INETPEER_BASE_BIT; + return (struct inet_peer_base *) val; +} + +static inline bool inetpeer_ptr_is_peer(unsigned long val) +{ + return !(val & INETPEER_BASE_BIT); +} + +static inline void __inetpeer_ptr_set_peer(unsigned long *val, struct inet_peer *peer) +{ + /* This implicitly clears INETPEER_BASE_BIT */ + *val = (unsigned long) peer; +} + +static inline bool inetpeer_ptr_set_peer(unsigned long *ptr, struct inet_peer *peer) +{ + unsigned long val = (unsigned long) peer; + unsigned long orig = *ptr; + + if (!(orig & INETPEER_BASE_BIT) || !val || + cmpxchg(ptr, orig, val) != orig) + return false; + return true; +} + +static inline void inetpeer_init_ptr(unsigned long *ptr, struct inet_peer_base *base) +{ + *ptr = (unsigned long) base | INETPEER_BASE_BIT; +} + +static inline void inetpeer_transfer_peer(unsigned long *to, unsigned long *from) +{ + unsigned long val = *from; + + *to = val; + if (inetpeer_ptr_is_peer(val)) { + struct inet_peer *peer = inetpeer_ptr(val); + atomic_inc(&peer->refcnt); + } +} + extern void inet_peer_base_init(struct inet_peer_base *); void inet_initpeers(void) __init; diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 0ae759a6c76e..3ac5f155c690 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -107,7 +107,7 @@ struct rt6_info { u32 rt6i_peer_genid; struct inet6_dev *rt6i_idev; - struct inet_peer *rt6i_peer; + unsigned long _rt6i_peer; #ifdef CONFIG_XFRM u32 rt6i_flow_cache_genid; @@ -118,6 +118,36 @@ struct rt6_info { u8 rt6i_protocol; }; +static inline struct inet_peer *rt6_peer_ptr(struct rt6_info *rt) +{ + return inetpeer_ptr(rt->_rt6i_peer); +} + +static inline bool rt6_has_peer(struct rt6_info *rt) +{ + return inetpeer_ptr_is_peer(rt->_rt6i_peer); +} + +static inline void __rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer) +{ + __inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer); +} + +static inline bool rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer) +{ + return inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer); +} + +static inline void rt6_init_peer(struct rt6_info *rt, struct inet_peer_base *base) +{ + inetpeer_init_ptr(&rt->_rt6i_peer, base); +} + +static inline void rt6_transfer_peer(struct rt6_info *rt, struct rt6_info *ort) +{ + inetpeer_transfer_peer(&rt->_rt6i_peer, &ort->_rt6i_peer); +} + static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) { return ((struct rt6_info *)dst)->rt6i_idev; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 73d750288121..f88a85cf31c3 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -57,11 +57,11 @@ extern void rt6_bind_peer(struct rt6_info *rt, int create); static inline struct inet_peer *__rt6_get_peer(struct rt6_info *rt, int create) { - if (rt->rt6i_peer) - return rt->rt6i_peer; + if (rt6_has_peer(rt)) + return rt6_peer_ptr(rt); rt6_bind_peer(rt, create); - return rt->rt6i_peer; + return rt6_peer_ptr(rt); } static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt) diff --git a/include/net/route.h b/include/net/route.h index 433fc6c1d404..6340c37677fc 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -67,10 +67,44 @@ struct rtable { /* Miscellaneous cached information */ __be32 rt_spec_dst; /* RFC1122 specific destination */ u32 rt_peer_genid; - struct inet_peer *peer; /* long-living peer info */ + unsigned long _peer; /* long-living peer info */ struct fib_info *fi; /* for client ref to shared metrics */ }; +static inline struct inet_peer *rt_peer_ptr(struct rtable *rt) +{ + return inetpeer_ptr(rt->_peer); +} + +static inline bool rt_has_peer(struct rtable *rt) +{ + return inetpeer_ptr_is_peer(rt->_peer); +} + +static inline void __rt_set_peer(struct rtable *rt, struct inet_peer *peer) +{ + __inetpeer_ptr_set_peer(&rt->_peer, peer); +} + +static inline bool rt_set_peer(struct rtable *rt, struct inet_peer *peer) +{ + return inetpeer_ptr_set_peer(&rt->_peer, peer); +} + +static inline void rt_init_peer(struct rtable *rt, struct inet_peer_base *base) +{ + inetpeer_init_ptr(&rt->_peer, base); +} + +static inline void rt_transfer_peer(struct rtable *rt, struct rtable *ort) +{ + rt->_peer = ort->_peer; + if (rt_has_peer(ort)) { + struct inet_peer *peer = rt_peer_ptr(ort); + atomic_inc(&peer->refcnt); + } +} + static inline bool rt_is_input_route(const struct rtable *rt) { return rt->rt_route_iif != 0; @@ -298,11 +332,11 @@ extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create); static inline struct inet_peer *__rt_get_peer(struct rtable *rt, __be32 daddr, int create) { - if (rt->peer) - return rt->peer; + if (rt_has_peer(rt)) + return rt_peer_ptr(rt); rt_bind_peer(rt, daddr, create); - return rt->peer; + return rt_peer_ptr(rt); } static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 2aa663a6ae9e..03e5b614370e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -677,7 +677,7 @@ static inline int rt_fast_clean(struct rtable *rth) static inline int rt_valuable(struct rtable *rth) { return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) || - (rth->peer && rth->peer->pmtu_expires); + (rt_has_peer(rth) && rt_peer_ptr(rth)->pmtu_expires); } static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2) @@ -1325,12 +1325,16 @@ static u32 rt_peer_genid(void) void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) { - struct net *net = dev_net(rt->dst.dev); + struct inet_peer_base *base; struct inet_peer *peer; - peer = inet_getpeer_v4(net->ipv4.peers, daddr, create); + base = inetpeer_base_ptr(rt->_peer); + if (!base) + return; + + peer = inet_getpeer_v4(base, daddr, create); - if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) + if (!rt_set_peer(rt, peer)) inet_putpeer(peer); else rt->rt_peer_genid = rt_peer_genid(); @@ -1533,8 +1537,10 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) rt_genid(dev_net(dst->dev))); rt_del(hash, rt); ret = NULL; - } else if (rt->peer && peer_pmtu_expired(rt->peer)) { - dst_metric_set(dst, RTAX_MTU, rt->peer->pmtu_orig); + } else if (rt_has_peer(rt)) { + struct inet_peer *peer = rt_peer_ptr(rt); + if (peer_pmtu_expired(peer)) + dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); } } return ret; @@ -1796,14 +1802,13 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) static void ipv4_dst_destroy(struct dst_entry *dst) { struct rtable *rt = (struct rtable *) dst; - struct inet_peer *peer = rt->peer; if (rt->fi) { fib_info_put(rt->fi); rt->fi = NULL; } - if (peer) { - rt->peer = NULL; + if (rt_has_peer(rt)) { + struct inet_peer *peer = rt_peer_ptr(rt); inet_putpeer(peer); } } @@ -1816,8 +1821,11 @@ static void ipv4_link_failure(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); rt = skb_rtable(skb); - if (rt && rt->peer && peer_pmtu_cleaned(rt->peer)) - dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig); + if (rt && rt_has_peer(rt)) { + struct inet_peer *peer = rt_peer_ptr(rt); + if (peer_pmtu_cleaned(peer)) + dst_metric_set(&rt->dst, RTAX_MTU, peer->pmtu_orig); + } } static int ip_rt_bug(struct sk_buff *skb) @@ -1919,7 +1927,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, struct fib_info *fi) { - struct net *net = dev_net(rt->dst.dev); + struct inet_peer_base *base; struct inet_peer *peer; int create = 0; @@ -1929,8 +1937,12 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS)) create = 1; - rt->peer = peer = inet_getpeer_v4(net->ipv4.peers, rt->rt_dst, create); + base = inetpeer_base_ptr(rt->_peer); + BUG_ON(!base); + + peer = inet_getpeer_v4(base, rt->rt_dst, create); if (peer) { + __rt_set_peer(rt, peer); rt->rt_peer_genid = rt_peer_genid(); if (inet_metrics_new(peer)) memcpy(peer->metrics, fi->fib_metrics, @@ -2046,7 +2058,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; - rth->peer = NULL; + rt_init_peer(rth, dev_net(dev)->ipv4.peers); rth->fi = NULL; if (our) { rth->dst.input= ip_local_deliver; @@ -2174,7 +2186,7 @@ static int __mkroute_input(struct sk_buff *skb, rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; - rth->peer = NULL; + rt_init_peer(rth, dev_net(rth->dst.dev)->ipv4.peers); rth->fi = NULL; rth->dst.input = ip_forward; @@ -2357,7 +2369,7 @@ local_input: rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; - rth->peer = NULL; + rt_init_peer(rth, net->ipv4.peers); rth->fi = NULL; if (res.type == RTN_UNREACHABLE) { rth->dst.input= ip_error; @@ -2561,7 +2573,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_gateway = fl4->daddr; rth->rt_spec_dst= fl4->saddr; rth->rt_peer_genid = 0; - rth->peer = NULL; + rt_init_peer(rth, dev_net(dev_out)->ipv4.peers); rth->fi = NULL; RT_CACHE_STAT_INC(out_slow_tot); @@ -2898,9 +2910,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or rt->rt_src = ort->rt_src; rt->rt_gateway = ort->rt_gateway; rt->rt_spec_dst = ort->rt_spec_dst; - rt->peer = ort->peer; - if (rt->peer) - atomic_inc(&rt->peer->refcnt); + rt_transfer_peer(rt, ort); rt->fi = ort->fi; if (rt->fi) atomic_inc(&rt->fi->fib_clntref); @@ -2938,7 +2948,6 @@ static int rt_fill_info(struct net *net, struct rtmsg *r; struct nlmsghdr *nlh; unsigned long expires = 0; - const struct inet_peer *peer = rt->peer; u32 id = 0, ts = 0, tsage = 0, error; nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); @@ -2994,8 +3003,9 @@ static int rt_fill_info(struct net *net, goto nla_put_failure; error = rt->dst.error; - if (peer) { - inet_peer_refcheck(rt->peer); + if (rt_has_peer(rt)) { + const struct inet_peer *peer = rt_peer_ptr(rt); + inet_peer_refcheck(peer); id = atomic_read(&peer->ip_id_count) & 0xffff; if (peer->tcp_ts_stamp) { ts = peer->tcp_ts; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 0d3426cb5c4f..8855d8268552 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -90,9 +90,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.dst.dev = dev; dev_hold(dev); - xdst->u.rt.peer = rt->peer; - if (rt->peer) - atomic_inc(&rt->peer->refcnt); + rt_transfer_peer(&xdst->u.rt, rt); /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ @@ -212,8 +210,10 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) dst_destroy_metrics_generic(dst); - if (likely(xdst->u.rt.peer)) - inet_putpeer(xdst->u.rt.peer); + if (rt_has_peer(&xdst->u.rt)) { + struct inet_peer *peer = rt_peer_ptr(&xdst->u.rt); + inet_putpeer(peer); + } xfrm_dst_destroy(xdst); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8fc41d502bbd..17a9b8687f29 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -258,16 +258,18 @@ static struct rt6_info ip6_blk_hole_entry_template = { #endif /* allocate dst with ip6_dst_ops */ -static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, +static inline struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev, int flags) { - struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); + struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, + 0, 0, flags); - if (rt) + if (rt) { memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); - + rt6_init_peer(rt, net->ipv6.peers); + } return rt; } @@ -275,7 +277,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) { struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; - struct inet_peer *peer = rt->rt6i_peer; if (!(rt->dst.flags & DST_HOST)) dst_destroy_metrics_generic(dst); @@ -288,8 +289,8 @@ static void ip6_dst_destroy(struct dst_entry *dst) if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) dst_release(dst->from); - if (peer) { - rt->rt6i_peer = NULL; + if (rt6_has_peer(rt)) { + struct inet_peer *peer = rt6_peer_ptr(rt); inet_putpeer(peer); } } @@ -303,11 +304,15 @@ static u32 rt6_peer_genid(void) void rt6_bind_peer(struct rt6_info *rt, int create) { - struct net *net = dev_net(rt->dst.dev); + struct inet_peer_base *base; struct inet_peer *peer; - peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, create); - if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) + base = inetpeer_base_ptr(rt->_rt6i_peer); + if (!base) + return; + + peer = inet_getpeer_v6(base, &rt->rt6i_dst.addr, create); + if (!rt6_set_peer(rt, peer)) inet_putpeer(peer); else rt->rt6i_peer_genid = rt6_peer_genid(); @@ -950,6 +955,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0); if (rt) { memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); + rt6_init_peer(rt, net->ipv6.peers); new = &rt->dst; @@ -994,7 +1000,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { if (rt->rt6i_peer_genid != rt6_peer_genid()) { - if (!rt->rt6i_peer) + if (!rt6_has_peer(rt)) rt6_bind_peer(rt, 0); rt->rt6i_peer_genid = rt6_peer_genid(); } @@ -1108,7 +1114,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, if (unlikely(!idev)) return ERR_PTR(-ENODEV); - rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); + rt = ip6_dst_alloc(net, dev, 0); if (unlikely(!rt)) { in6_dev_put(idev); dst = ERR_PTR(-ENOMEM); @@ -1290,7 +1296,7 @@ int ip6_route_add(struct fib6_config *cfg) if (!table) goto out; - rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT); + rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT); if (!rt) { err = -ENOMEM; @@ -1812,8 +1818,7 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, const struct in6_addr *dest) { struct net *net = dev_net(ort->dst.dev); - struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, - ort->dst.dev, 0); + struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0); if (rt) { rt->dst.input = ort->dst.input; @@ -2097,8 +2102,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, bool anycast) { struct net *net = dev_net(idev->dev); - struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, - net->loopback_dev, 0); + struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0); int err; if (!rt) { @@ -2519,7 +2523,9 @@ static int rt6_fill_node(struct net *net, else expires = INT_MAX; - peer = rt->rt6i_peer; + peer = NULL; + if (rt6_has_peer(rt)) + peer = rt6_peer_ptr(rt); ts = tsage = 0; if (peer && peer->tcp_ts_stamp) { ts = peer->tcp_ts; diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8625fba96db9..d7494845efbf 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -99,9 +99,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, if (!xdst->u.rt6.rt6i_idev) return -ENODEV; - xdst->u.rt6.rt6i_peer = rt->rt6i_peer; - if (rt->rt6i_peer) - atomic_inc(&rt->rt6i_peer->refcnt); + rt6_transfer_peer(&xdst->u.rt6, rt); /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ @@ -223,8 +221,10 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) if (likely(xdst->u.rt6.rt6i_idev)) in6_dev_put(xdst->u.rt6.rt6i_idev); dst_destroy_metrics_generic(dst); - if (likely(xdst->u.rt6.rt6i_peer)) - inet_putpeer(xdst->u.rt6.rt6i_peer); + if (rt6_has_peer(&xdst->u.rt6)) { + struct inet_peer *peer = rt6_peer_ptr(&xdst->u.rt6); + inet_putpeer(peer); + } xfrm_dst_destroy(xdst); } -- GitLab From 46517008e1168dc926cf2c47d529efc07eca85c0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jun 2012 00:04:12 -0700 Subject: [PATCH 1047/6849] ipv4: Kill ip_rt_frag_needed(). There is zero point to this function. It's only real substance is to perform an extremely outdated BSD4.2 ICMP check, which we can safely remove. If you really have a MTU limited link being routed by a BSD4.2 derived system, here's a nickel go buy yourself a real router. The other actions of ip_rt_frag_needed(), checking and conditionally updating the peer, are done by the per-protocol handlers of the ICMP event. TCP, UDP, et al. have a handler which will receive this event and transmit it back into the associated route via dst_ops->update_pmtu(). This simplification is important, because it eliminates the one place where we do not have a proper route context in which to make an inetpeer lookup. Signed-off-by: David S. Miller --- include/net/route.h | 2 -- net/ipv4/icmp.c | 4 +-- net/ipv4/route.c | 61 -------------------------------------------- net/rxrpc/ar-error.c | 4 --- 4 files changed, 1 insertion(+), 70 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 6340c37677fc..cc693a5bb20d 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -215,8 +215,6 @@ static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 s return ip_route_input_common(skb, dst, src, tos, devin, true); } -extern unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, - unsigned short new_mtu, struct net_device *dev); extern void ip_rt_send_redirect(struct sk_buff *skb); extern unsigned int inet_addr_type(struct net *net, __be32 addr); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 0c78ef1e5dde..e1caa1abe5d1 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -673,9 +673,7 @@ static void icmp_unreach(struct sk_buff *skb) LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"), &iph->daddr); } else { - info = ip_rt_frag_needed(net, iph, - ntohs(icmph->un.frag.mtu), - skb->dev); + info = ntohs(icmph->un.frag.mtu); if (!info) goto out; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 03e5b614370e..4f5834c4a667 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1664,67 +1664,6 @@ out: kfree_skb(skb); return 0; } -/* - * The last two values are not from the RFC but - * are needed for AMPRnet AX.25 paths. - */ - -static const unsigned short mtu_plateau[] = -{32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 }; - -static inline unsigned short guess_mtu(unsigned short old_mtu) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(mtu_plateau); i++) - if (old_mtu > mtu_plateau[i]) - return mtu_plateau[i]; - return 68; -} - -unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, - unsigned short new_mtu, - struct net_device *dev) -{ - unsigned short old_mtu = ntohs(iph->tot_len); - unsigned short est_mtu = 0; - struct inet_peer *peer; - - peer = inet_getpeer_v4(net->ipv4.peers, iph->daddr, 1); - if (peer) { - unsigned short mtu = new_mtu; - - if (new_mtu < 68 || new_mtu >= old_mtu) { - /* BSD 4.2 derived systems incorrectly adjust - * tot_len by the IP header length, and report - * a zero MTU in the ICMP message. - */ - if (mtu == 0 && - old_mtu >= 68 + (iph->ihl << 2)) - old_mtu -= iph->ihl << 2; - mtu = guess_mtu(old_mtu); - } - - if (mtu < ip_rt_min_pmtu) - mtu = ip_rt_min_pmtu; - if (!peer->pmtu_expires || mtu < peer->pmtu_learned) { - unsigned long pmtu_expires; - - pmtu_expires = jiffies + ip_rt_mtu_expires; - if (!pmtu_expires) - pmtu_expires = 1UL; - - est_mtu = mtu; - peer->pmtu_learned = mtu; - peer->pmtu_expires = pmtu_expires; - atomic_inc(&__rt_peer_genid); - } - - inet_putpeer(peer); - } - return est_mtu ? : new_mtu; -} - static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) { unsigned long expires = ACCESS_ONCE(peer->pmtu_expires); diff --git a/net/rxrpc/ar-error.c b/net/rxrpc/ar-error.c index 5d6b572a6704..a9206087b4d7 100644 --- a/net/rxrpc/ar-error.c +++ b/net/rxrpc/ar-error.c @@ -81,10 +81,6 @@ void rxrpc_UDP_error_report(struct sock *sk) _net("I/F MTU %u", mtu); } - /* ip_rt_frag_needed() may have eaten the info */ - if (mtu == 0) - mtu = ntohs(icmp_hdr(skb)->un.frag.mtu); - if (mtu == 0) { /* they didn't give us a size, estimate one */ if (mtu > 1500) { -- GitLab From b48c80ece973e9eddb042f6685b482b261ff0d47 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jun 2012 00:24:21 -0700 Subject: [PATCH 1048/6849] inet: Add family scope inetpeer flushes. This implementation can deal with having many inetpeer roots, which is a necessary prerequisite for per-FIB table rooted peer tables. Each family (AF_INET, AF_INET6) has a sequence number which we bump when we get a family invalidation request. Each peer lookup cheaply checks whether the flush sequence of the root we are using is out of date, and if so flushes it and updates the sequence number. Signed-off-by: David S. Miller --- include/net/inetpeer.h | 2 ++ net/ipv4/inetpeer.c | 28 ++++++++++++++++++++++++++++ net/ipv4/route.c | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index d432489e7109..e15c0862a686 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -68,6 +68,7 @@ struct inet_peer { struct inet_peer_base { struct inet_peer __rcu *root; seqlock_t lock; + u32 flush_seq; int total; }; @@ -168,6 +169,7 @@ extern void inet_putpeer(struct inet_peer *p); extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); extern void inetpeer_invalidate_tree(struct inet_peer_base *); +extern void inetpeer_invalidate_family(int family); /* * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index e4cba56a5349..cac02ad1425d 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -86,10 +86,36 @@ void inet_peer_base_init(struct inet_peer_base *bp) { bp->root = peer_avl_empty_rcu; seqlock_init(&bp->lock); + bp->flush_seq = ~0U; bp->total = 0; } EXPORT_SYMBOL_GPL(inet_peer_base_init); +static atomic_t v4_seq = ATOMIC_INIT(0); +static atomic_t v6_seq = ATOMIC_INIT(0); + +static atomic_t *inetpeer_seq_ptr(int family) +{ + return (family == AF_INET ? &v4_seq : &v6_seq); +} + +static inline void flush_check(struct inet_peer_base *base, int family) +{ + atomic_t *fp = inetpeer_seq_ptr(family); + + if (unlikely(base->flush_seq != atomic_read(fp))) { + inetpeer_invalidate_tree(base); + base->flush_seq = atomic_read(fp); + } +} + +void inetpeer_invalidate_family(int family) +{ + atomic_t *fp = inetpeer_seq_ptr(family); + + atomic_inc(fp); +} + #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ /* Exported for sysctl_net_ipv4. */ @@ -437,6 +463,8 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base, unsigned int sequence; int invalidated, gccnt = 0; + flush_check(base, daddr->family); + /* Attempt a lockless lookup first. * Because of a concurrent writer, we might not find an existing entry. */ diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 4f5834c4a667..456a9470fb54 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -935,7 +935,7 @@ static void rt_cache_invalidate(struct net *net) get_random_bytes(&shuffle, sizeof(shuffle)); atomic_add(shuffle + 1U, &net->ipv4.rt_genid); - inetpeer_invalidate_tree(net->ipv4.peers); + inetpeer_invalidate_family(AF_INET); } /* -- GitLab From 8e77327783c753689a1a766ab9d301b81c2529f1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 11 Jun 2012 00:01:52 -0700 Subject: [PATCH 1049/6849] inet: Add inetpeer tree roots to the FIB tables. Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 1 + include/net/ip_fib.h | 12 +++++++----- net/ipv4/fib_trie.c | 3 +++ net/ipv6/ip6_fib.c | 5 +++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 3ac5f155c690..a192f7807659 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -237,6 +237,7 @@ struct fib6_table { u32 tb6_id; rwlock_t tb6_lock; struct fib6_node tb6_root; + struct inet_peer_base tb6_peers; }; #define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 78df0866cc38..4b347c0ca094 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -19,6 +19,7 @@ #include #include #include +#include struct fib_config { u8 fc_dst_len; @@ -157,11 +158,12 @@ extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh); FIB_RES_SADDR(net, res)) struct fib_table { - struct hlist_node tb_hlist; - u32 tb_id; - int tb_default; - int tb_num_default; - unsigned long tb_data[0]; + struct hlist_node tb_hlist; + u32 tb_id; + int tb_default; + int tb_num_default; + struct inet_peer_base tb_peers; + unsigned long tb_data[0]; }; extern int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 18cbc15b20d5..9b0f25930fbc 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1843,6 +1843,8 @@ int fib_table_flush(struct fib_table *tb) if (ll && hlist_empty(&ll->list)) trie_leaf_remove(t, ll); + inetpeer_invalidate_tree(&tb->tb_peers); + pr_debug("trie_flush found=%d\n", found); return found; } @@ -1991,6 +1993,7 @@ struct fib_table *fib_trie_table(u32 id) tb->tb_id = id; tb->tb_default = -1; tb->tb_num_default = 0; + inet_peer_base_init(&tb->tb_peers); t = (struct trie *) tb->tb_data; memset(t, 0, sizeof(*t)); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 0c220a416626..7ef0743f06f0 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -197,6 +197,7 @@ static struct fib6_table *fib6_alloc_table(struct net *net, u32 id) table->tb6_id = id; table->tb6_root.leaf = net->ipv6.ip6_null_entry; table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + inet_peer_base_init(&table->tb6_peers); } return table; @@ -1633,6 +1634,7 @@ static int __net_init fib6_net_init(struct net *net) net->ipv6.fib6_main_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry; net->ipv6.fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + inet_peer_base_init(&net->ipv6.fib6_main_tbl->tb6_peers); #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl), @@ -1643,6 +1645,7 @@ static int __net_init fib6_net_init(struct net *net) net->ipv6.fib6_local_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry; net->ipv6.fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + inet_peer_base_init(&net->ipv6.fib6_local_tbl->tb6_peers); #endif fib6_tables_init(net); @@ -1666,8 +1669,10 @@ static void fib6_net_exit(struct net *net) del_timer_sync(&net->ipv6.ip6_fib_timer); #ifdef CONFIG_IPV6_MULTIPLE_TABLES + inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers); kfree(net->ipv6.fib6_local_tbl); #endif + inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers); kfree(net->ipv6.fib6_main_tbl); kfree(net->ipv6.fib_table_hash); kfree(net->ipv6.rt6_stats); -- GitLab From 8b96d22d7a6ec999ae53ae86d829137503ceda65 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 11 Jun 2012 02:01:56 -0700 Subject: [PATCH 1050/6849] inet: Use FIB table peer roots in routes. Signed-off-by: David S. Miller --- net/ipv4/route.c | 8 ++++++-- net/ipv6/route.c | 14 ++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 456a9470fb54..4c33ce3000ed 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2125,7 +2125,7 @@ static int __mkroute_input(struct sk_buff *skb, rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; - rt_init_peer(rth, dev_net(rth->dst.dev)->ipv4.peers); + rt_init_peer(rth, &res->table->tb_peers); rth->fi = NULL; rth->dst.input = ip_forward; @@ -2512,7 +2512,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_gateway = fl4->daddr; rth->rt_spec_dst= fl4->saddr; rth->rt_peer_genid = 0; - rt_init_peer(rth, dev_net(dev_out)->ipv4.peers); + rt_init_peer(rth, (res->table ? + &res->table->tb_peers : + dev_net(dev_out)->ipv4.peers)); rth->fi = NULL; RT_CACHE_STAT_INC(out_slow_tot); @@ -2561,6 +2563,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) int orig_oif; res.fi = NULL; + res.table = NULL; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif @@ -2666,6 +2669,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) if (fib_lookup(net, fl4, &res)) { res.fi = NULL; + res.table = NULL; if (fl4->flowi4_oif) { /* Apparently, routing tables are wrong. Assume, that the destination is on link. diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 17a9b8687f29..d9ba4808f26a 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -260,7 +260,8 @@ static struct rt6_info ip6_blk_hole_entry_template = { /* allocate dst with ip6_dst_ops */ static inline struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev, - int flags) + int flags, + struct fib6_table *table) { struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0, 0, flags); @@ -268,7 +269,7 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net, if (rt) { memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); - rt6_init_peer(rt, net->ipv6.peers); + rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); } return rt; } @@ -1114,7 +1115,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, if (unlikely(!idev)) return ERR_PTR(-ENODEV); - rt = ip6_dst_alloc(net, dev, 0); + rt = ip6_dst_alloc(net, dev, 0, NULL); if (unlikely(!rt)) { in6_dev_put(idev); dst = ERR_PTR(-ENOMEM); @@ -1296,7 +1297,7 @@ int ip6_route_add(struct fib6_config *cfg) if (!table) goto out; - rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT); + rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table); if (!rt) { err = -ENOMEM; @@ -1818,7 +1819,8 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, const struct in6_addr *dest) { struct net *net = dev_net(ort->dst.dev); - struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0); + struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0, + ort->rt6i_table); if (rt) { rt->dst.input = ort->dst.input; @@ -2102,7 +2104,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, bool anycast) { struct net *net = dev_net(idev->dev); - struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0); + struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); int err; if (!rt) { -- GitLab From 3a6490c0840c0ae67cc3a51e1b724bd7e460041e Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Sun, 3 Jun 2012 13:36:51 +0300 Subject: [PATCH 1051/6849] iwlwifi: refactor testmode Create an object that will enacpsulate the testmode functionality that is common to all op modes. * Copy definitions from dvm/dev.h * Copy the testmode logic from dvm/testmode.c * Link iwl-test object into the iwlwifi module * Modify DVM to use iwl-test object Reviewed-by: Amit Beka Reviewed-by: Emmanuel Grumbach Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/dvm/agn.h | 17 +- drivers/net/wireless/iwlwifi/dvm/dev.h | 26 +- drivers/net/wireless/iwlwifi/dvm/main.c | 2 +- drivers/net/wireless/iwlwifi/dvm/rx.c | 24 +- drivers/net/wireless/iwlwifi/dvm/testmode.c | 769 ++-------------- drivers/net/wireless/iwlwifi/iwl-test.c | 825 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-test.h | 125 +++ .../{dvm/testmode.h => iwl-testmode.h} | 0 9 files changed, 1027 insertions(+), 762 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-test.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-test.h rename drivers/net/wireless/iwlwifi/{dvm/testmode.h => iwl-testmode.h} (100%) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 98c8f6449649..afa9758364ea 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -13,5 +13,6 @@ iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o +iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o ccflags-y += -D__CHECK_ENDIAN__ -I$(src) diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 2ae3608472a6..6d102413dd94 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -395,8 +395,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) } extern int iwl_alive_start(struct iwl_priv *priv); -/* svtool */ + +/* testmode support */ #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE + extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, @@ -404,13 +406,16 @@ extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct netlink_callback *cb, void *data, int len); extern void iwl_testmode_init(struct iwl_priv *priv); -extern void iwl_testmode_cleanup(struct iwl_priv *priv); +extern void iwl_testmode_free(struct iwl_priv *priv); + #else + static inline int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) { return -ENOSYS; } + static inline int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, struct netlink_callback *cb, @@ -418,12 +423,12 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, { return -ENOSYS; } -static inline -void iwl_testmode_init(struct iwl_priv *priv) + +static inline void iwl_testmode_init(struct iwl_priv *priv) { } -static inline -void iwl_testmode_cleanup(struct iwl_priv *priv) + +static inline void iwl_testmode_free(struct iwl_priv *priv) { } #endif diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 89f2e1040e7f..4620b657948a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -52,6 +52,8 @@ #include "rs.h" #include "tt.h" +#include "iwl-test.h" + /* CT-KILL constants */ #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ #define CT_KILL_THRESHOLD 114 /* in Celsius */ @@ -596,24 +598,6 @@ struct iwl_lib_ops { void (*temperature)(struct iwl_priv *priv); }; -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE -struct iwl_testmode_trace { - u32 buff_size; - u32 total_size; - u32 num_chunks; - u8 *cpu_addr; - u8 *trace_addr; - dma_addr_t dma_addr; - bool trace_enabled; -}; -struct iwl_testmode_mem { - u32 buff_size; - u32 num_chunks; - u8 *buff_addr; - bool read_in_progress; -}; -#endif - struct iwl_wipan_noa_data { struct rcu_head rcu_head; u32 length; @@ -670,8 +654,6 @@ struct iwl_priv { enum ieee80211_band band; u8 valid_contexts; - void (*pre_rx_handler)(struct iwl_priv *priv, - struct iwl_rx_cmd_buffer *rxb); int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); @@ -895,9 +877,9 @@ struct iwl_priv { struct led_classdev led; unsigned long blink_on, blink_off; bool led_registered; + #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - struct iwl_testmode_trace testmode_trace; - struct iwl_testmode_mem testmode_mem; + struct iwl_test tst; u32 tm_fixed_rate; #endif diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 1c2d0233a405..656ed317c6d3 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -1548,7 +1548,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) iwl_dbgfs_unregister(priv); - iwl_testmode_cleanup(priv); + iwl_testmode_free(priv); iwlagn_mac_unregister(priv); iwl_tt_exit(priv); diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index 0ed90bb8b56a..afdacb25f344 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c @@ -1124,8 +1124,6 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - void (*pre_rx_handler)(struct iwl_priv *, - struct iwl_rx_cmd_buffer *); int err = 0; /* @@ -1135,19 +1133,19 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, */ iwl_notification_wait_notify(&priv->notif_wait, pkt); - /* RX data may be forwarded to userspace (using pre_rx_handler) in one - * of two cases: the first, that the user owns the uCode through - * testmode - in such case the pre_rx_handler is set and no further - * processing takes place. The other case is when the user want to - * monitor the rx w/o affecting the regular flow - the pre_rx_handler - * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow +#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE + /* + * RX data may be forwarded to userspace in one + * of two cases: the user owns the fw through testmode or when + * the user requested to monitor the rx w/o affecting the regular flow. + * In these cases the iwl_test object will handle forwarding the rx + * data to user space. + * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow * continues. - * We need to use ACCESS_ONCE to prevent a case where the handler - * changes between the check and the call. */ - pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); - if (pre_rx_handler) - pre_rx_handler(priv, rxb); + iwl_test_rx(&priv->tst, priv->hw, rxb); +#endif + if (priv->ucode_owner != IWL_OWNERSHIP_TM) { /* Based on type of command response or notification, * handle those that need handling via function in diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index a7b59590bb53..aa9518f13e89 100644 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c @@ -60,6 +60,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ + #include #include #include @@ -69,355 +70,55 @@ #include #include #include + #include "iwl-debug.h" -#include "iwl-io.h" #include "iwl-trans.h" -#include "iwl-fh.h" -#include "iwl-prph.h" #include "dev.h" #include "agn.h" -#include "testmode.h" - - -/* Periphery registers absolute lower bound. This is used in order to - * differentiate registery access through HBUS_TARG_PRPH_* and - * HBUS_TARG_MEM_* accesses. - */ -#define IWL_TM_ABS_PRPH_START (0xA00000) - -/* The TLVs used in the gnl message policy between the kernel module and - * user space application. iwl_testmode_gnl_msg_policy is to be carried - * through the NL80211_CMD_TESTMODE channel regulated by nl80211. - * See testmode.h - */ -static -struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { - [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, }, - - [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, }, - [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, }, - - [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, }, - [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, }, - [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, }, - - [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, - [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, +#include "iwl-test.h" +#include "iwl-testmode.h" - [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, - - [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, - [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, }, - [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, - - [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, - - [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, - - [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, }, - [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, }, - [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, }, - - [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, }, - [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, }, - [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, - [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, - [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, - - [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, -}; - -/* - * See the struct iwl_rx_packet in commands.h for the format of the - * received events from the device - */ -static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) +static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode, + struct iwl_host_cmd *cmd) { - struct iwl_rx_packet *pkt = rxb_addr(rxb); - if (pkt) - return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - else - return 0; + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + return iwl_dvm_send_cmd(priv, cmd); } - -/* - * This function multicasts the spontaneous messages from the device to the - * user space. It is invoked whenever there is a received messages - * from the device. This function is called within the ISR of the rx handlers - * in iwlagn driver. - * - * The parsing of the message content is left to the user space application, - * The message content is treated as unattacked raw data and is encapsulated - * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space. - * - * @priv: the instance of iwlwifi device - * @rxb: pointer to rx data content received by the ISR - * - * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[]. - * For the messages multicasting to the user application, the mandatory - * TLV fields are : - * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT - * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content - */ - -static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, - struct iwl_rx_cmd_buffer *rxb) +static bool iwl_testmode_valid_hw_addr(u32 addr) { - struct ieee80211_hw *hw = priv->hw; - struct sk_buff *skb; - void *data; - int length; - - data = (void *)rxb_addr(rxb); - length = get_event_length(rxb); + if (iwlagn_hw_valid_rtc_data_addr(addr)) + return true; - if (!data || length == 0) - return; + if (IWLAGN_RTC_INST_LOWER_BOUND <= addr && + addr < IWLAGN_RTC_INST_UPPER_BOUND) + return true; - skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length, - GFP_ATOMIC); - if (skb == NULL) { - IWL_ERR(priv, - "Run out of memory for messages to user space ?\n"); - return; - } - if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || - /* the length doesn't include len_n_flags field, so add it manually */ - nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data)) - goto nla_put_failure; - cfg80211_testmode_event(skb, GFP_ATOMIC); - return; - -nla_put_failure: - kfree_skb(skb); - IWL_ERR(priv, "Ouch, overran buffer, check allocation!\n"); + return false; } -void iwl_testmode_init(struct iwl_priv *priv) +static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode) { - priv->pre_rx_handler = NULL; - priv->testmode_trace.trace_enabled = false; - priv->testmode_mem.read_in_progress = false; -} - -static void iwl_mem_cleanup(struct iwl_priv *priv) -{ - if (priv->testmode_mem.read_in_progress) { - kfree(priv->testmode_mem.buff_addr); - priv->testmode_mem.buff_addr = NULL; - priv->testmode_mem.buff_size = 0; - priv->testmode_mem.num_chunks = 0; - priv->testmode_mem.read_in_progress = false; - } -} - -static void iwl_trace_cleanup(struct iwl_priv *priv) -{ - if (priv->testmode_trace.trace_enabled) { - if (priv->testmode_trace.cpu_addr && - priv->testmode_trace.dma_addr) - dma_free_coherent(priv->trans->dev, - priv->testmode_trace.total_size, - priv->testmode_trace.cpu_addr, - priv->testmode_trace.dma_addr); - priv->testmode_trace.trace_enabled = false; - priv->testmode_trace.cpu_addr = NULL; - priv->testmode_trace.trace_addr = NULL; - priv->testmode_trace.dma_addr = 0; - priv->testmode_trace.buff_size = 0; - priv->testmode_trace.total_size = 0; - } -} - - -void iwl_testmode_cleanup(struct iwl_priv *priv) -{ - iwl_trace_cleanup(priv); - iwl_mem_cleanup(priv); + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + return priv->fw->ucode_ver; } +static struct iwl_test_ops tst_ops = { + .send_cmd = iwl_testmode_send_cmd, + .valid_hw_addr = iwl_testmode_valid_hw_addr, + .get_fw_ver = iwl_testmode_get_fw_ver, +}; -/* - * This function handles the user application commands to the ucode. - * - * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and - * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the - * host command to the ucode. - * - * If any mandatory field is missing, -ENOMSG is replied to the user space - * application; otherwise, waits for the host command to be sent and checks - * the return code. In case or error, it is returned, otherwise a reply is - * allocated and the reply RX packet - * is returned. - * - * @hw: ieee80211_hw object that represents the device - * @tb: gnl message fields from the user space - */ -static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) +void iwl_testmode_init(struct iwl_priv *priv) { - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct iwl_host_cmd cmd; - struct iwl_rx_packet *pkt; - struct sk_buff *skb; - void *reply_buf; - u32 reply_len; - int ret; - bool cmd_want_skb; - - memset(&cmd, 0, sizeof(struct iwl_host_cmd)); - - if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] || - !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) { - IWL_ERR(priv, "Missing ucode command mandatory fields\n"); - return -ENOMSG; - } - - cmd.flags = CMD_ON_DEMAND | CMD_SYNC; - cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]); - if (cmd_want_skb) - cmd.flags |= CMD_WANT_SKB; - - cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); - cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); - cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); - cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," - " len %d\n", cmd.id, cmd.flags, cmd.len[0]); - - ret = iwl_dvm_send_cmd(priv, &cmd); - if (ret) { - IWL_ERR(priv, "Failed to send hcmd\n"); - return ret; - } - if (!cmd_want_skb) - return ret; - - /* Handling return of SKB to the user */ - pkt = cmd.resp_pkt; - if (!pkt) { - IWL_ERR(priv, "HCMD received a null response packet\n"); - return ret; - } - - reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20); - reply_buf = kmalloc(reply_len, GFP_KERNEL); - if (!skb || !reply_buf) { - kfree_skb(skb); - kfree(reply_buf); - return -ENOMEM; - } - - /* The reply is in a page, that we cannot send to user space. */ - memcpy(reply_buf, &(pkt->hdr), reply_len); - iwl_free_resp(&cmd); - - if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || - nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf)) - goto nla_put_failure; - return cfg80211_testmode_reply(skb); - -nla_put_failure: - IWL_DEBUG_INFO(priv, "Failed creating NL attributes\n"); - return -ENOMSG; + iwl_test_init(&priv->tst, priv->trans, &tst_ops); } - -/* - * This function handles the user application commands for register access. - * - * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the - * handlers respectively. - * - * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the - * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32, - * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating - * the success of the command execution. - * - * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read - * value is returned with IWL_TM_ATTR_REG_VALUE32. - * - * @hw: ieee80211_hw object that represents the device - * @tb: gnl message fields from the user space - */ -static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) +void iwl_testmode_free(struct iwl_priv *priv) { - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - u32 ofs, val32, cmd; - u8 val8; - struct sk_buff *skb; - int status = 0; - - if (!tb[IWL_TM_ATTR_REG_OFFSET]) { - IWL_ERR(priv, "Missing register offset\n"); - return -ENOMSG; - } - ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); - IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs); - - /* Allow access only to FH/CSR/HBUS in direct mode. - Since we don't have the upper bounds for the CSR and HBUS segments, - we will use only the upper bound of FH for sanity check. */ - cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); - if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 || - cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 || - cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) && - (ofs >= FH_MEM_UPPER_BOUND)) { - IWL_ERR(priv, "offset out of segment (0x0 - 0x%x)\n", - FH_MEM_UPPER_BOUND); - return -EINVAL; - } - - switch (cmd) { - case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - val32 = iwl_read_direct32(priv->trans, ofs); - IWL_INFO(priv, "32bit value to read 0x%x\n", val32); - - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - return -ENOMEM; - } - if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_ERR(priv, "Error sending msg : %d\n", status); - break; - case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: - if (!tb[IWL_TM_ATTR_REG_VALUE32]) { - IWL_ERR(priv, "Missing value to write\n"); - return -ENOMSG; - } else { - val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); - IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write_direct32(priv->trans, ofs, val32); - } - break; - case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: - if (!tb[IWL_TM_ATTR_REG_VALUE8]) { - IWL_ERR(priv, "Missing value to write\n"); - return -ENOMSG; - } else { - val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); - IWL_INFO(priv, "8bit value to write 0x%x\n", val8); - iwl_write8(priv->trans, ofs, val8); - } - break; - default: - IWL_ERR(priv, "Unknown testmode register command ID\n"); - return -ENOSYS; - } - - return status; - -nla_put_failure: - kfree_skb(skb); - return -EMSGSIZE; + iwl_test_free(&priv->tst); } - static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) { struct iwl_notification_wait calib_wait; @@ -469,7 +170,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) struct sk_buff *skb; unsigned char *rsp_data_ptr = NULL; int status = 0, rsp_data_len = 0; - u32 devid, inst_size = 0, data_size = 0; + u32 inst_size = 0, data_size = 0; const struct fw_img *img; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { @@ -563,39 +264,6 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); break; - case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: - IWL_INFO(priv, "uCode version raw: 0x%x\n", - priv->fw->ucode_ver); - - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - return -ENOMEM; - } - if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, - priv->fw->ucode_ver)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_ERR(priv, "Error sending msg : %d\n", status); - break; - - case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: - devid = priv->trans->hw_id; - IWL_INFO(priv, "hw version: 0x%x\n", devid); - - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - return -ENOMEM; - } - if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_ERR(priv, "Error sending msg : %d\n", status); - break; - case IWL_TM_CMD_APP2DEV_GET_FW_INFO: skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); if (!skb) { @@ -630,125 +298,6 @@ nla_put_failure: return -EMSGSIZE; } - -/* - * This function handles the user application commands for uCode trace - * - * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the - * handlers respectively. - * - * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned - * value of the actual command execution is replied to the user application. - * - * @hw: ieee80211_hw object that represents the device - * @tb: gnl message fields from the user space - */ -static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct sk_buff *skb; - int status = 0; - struct device *dev = priv->trans->dev; - - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { - case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: - if (priv->testmode_trace.trace_enabled) - return -EBUSY; - - if (!tb[IWL_TM_ATTR_TRACE_SIZE]) - priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF; - else - priv->testmode_trace.buff_size = - nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]); - if (!priv->testmode_trace.buff_size) - return -EINVAL; - if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN || - priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX) - return -EINVAL; - - priv->testmode_trace.total_size = - priv->testmode_trace.buff_size + TRACE_BUFF_PADD; - priv->testmode_trace.cpu_addr = - dma_alloc_coherent(dev, - priv->testmode_trace.total_size, - &priv->testmode_trace.dma_addr, - GFP_KERNEL); - if (!priv->testmode_trace.cpu_addr) - return -ENOMEM; - priv->testmode_trace.trace_enabled = true; - priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( - priv->testmode_trace.cpu_addr, 0x100); - memset(priv->testmode_trace.trace_addr, 0x03B, - priv->testmode_trace.buff_size); - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - sizeof(priv->testmode_trace.dma_addr) + 20); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - iwl_trace_cleanup(priv); - return -ENOMEM; - } - if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR, - sizeof(priv->testmode_trace.dma_addr), - (u64 *)&priv->testmode_trace.dma_addr)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) { - IWL_ERR(priv, "Error sending msg : %d\n", status); - } - priv->testmode_trace.num_chunks = - DIV_ROUND_UP(priv->testmode_trace.buff_size, - DUMP_CHUNK_SIZE); - break; - - case IWL_TM_CMD_APP2DEV_END_TRACE: - iwl_trace_cleanup(priv); - break; - default: - IWL_ERR(priv, "Unknown testmode mem command ID\n"); - return -ENOSYS; - } - return status; - -nla_put_failure: - kfree_skb(skb); - if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) == - IWL_TM_CMD_APP2DEV_BEGIN_TRACE) - iwl_trace_cleanup(priv); - return -EMSGSIZE; -} - -static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct netlink_callback *cb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - int idx, length; - - if (priv->testmode_trace.trace_enabled && - priv->testmode_trace.trace_addr) { - idx = cb->args[4]; - if (idx >= priv->testmode_trace.num_chunks) - return -ENOENT; - length = DUMP_CHUNK_SIZE; - if (((idx + 1) == priv->testmode_trace.num_chunks) && - (priv->testmode_trace.buff_size % DUMP_CHUNK_SIZE)) - length = priv->testmode_trace.buff_size % - DUMP_CHUNK_SIZE; - - if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length, - priv->testmode_trace.trace_addr + - (DUMP_CHUNK_SIZE * idx))) - goto nla_put_failure; - idx++; - cb->args[4] = idx; - return 0; - } else - return -EFAULT; - - nla_put_failure: - return -ENOBUFS; -} - /* * This function handles the user application switch ucode ownership. * @@ -777,10 +326,10 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); if (owner == IWL_OWNERSHIP_DRIVER) { priv->ucode_owner = owner; - priv->pre_rx_handler = NULL; + iwl_test_enable_notifications(&priv->tst, false); } else if (owner == IWL_OWNERSHIP_TM) { - priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; priv->ucode_owner = owner; + iwl_test_enable_notifications(&priv->tst, true); } else { IWL_ERR(priv, "Invalid owner\n"); return -EINVAL; @@ -788,180 +337,6 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) return 0; } -static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size) -{ - struct iwl_trans *trans = priv->trans; - unsigned long flags; - int i; - - if (size & 0x3) - return -EINVAL; - priv->testmode_mem.buff_size = size; - priv->testmode_mem.buff_addr = - kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL); - if (priv->testmode_mem.buff_addr == NULL) - return -ENOMEM; - - /* Hard-coded periphery absolute address */ - if (IWL_TM_ABS_PRPH_START <= addr && - addr < IWL_TM_ABS_PRPH_START + PRPH_END) { - spin_lock_irqsave(&trans->reg_lock, flags); - iwl_grab_nic_access(trans); - iwl_write32(trans, HBUS_TARG_PRPH_RADDR, - addr | (3 << 24)); - for (i = 0; i < size; i += 4) - *(u32 *)(priv->testmode_mem.buff_addr + i) = - iwl_read32(trans, HBUS_TARG_PRPH_RDAT); - iwl_release_nic_access(trans); - spin_unlock_irqrestore(&trans->reg_lock, flags); - } else { /* target memory (SRAM) */ - _iwl_read_targ_mem_words(trans, addr, - priv->testmode_mem.buff_addr, - priv->testmode_mem.buff_size / 4); - } - - priv->testmode_mem.num_chunks = - DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE); - priv->testmode_mem.read_in_progress = true; - return 0; - -} - -static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr, - u32 size, unsigned char *buf) -{ - struct iwl_trans *trans = priv->trans; - u32 val, i; - unsigned long flags; - - if (IWL_TM_ABS_PRPH_START <= addr && - addr < IWL_TM_ABS_PRPH_START + PRPH_END) { - /* Periphery writes can be 1-3 bytes long, or DWORDs */ - if (size < 4) { - memcpy(&val, buf, size); - spin_lock_irqsave(&trans->reg_lock, flags); - iwl_grab_nic_access(trans); - iwl_write32(trans, HBUS_TARG_PRPH_WADDR, - (addr & 0x0000FFFF) | - ((size - 1) << 24)); - iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); - iwl_release_nic_access(trans); - /* needed after consecutive writes w/o read */ - mmiowb(); - spin_unlock_irqrestore(&trans->reg_lock, flags); - } else { - if (size % 4) - return -EINVAL; - for (i = 0; i < size; i += 4) - iwl_write_prph(trans, addr+i, - *(u32 *)(buf+i)); - } - } else if (iwlagn_hw_valid_rtc_data_addr(addr) || - (IWLAGN_RTC_INST_LOWER_BOUND <= addr && - addr < IWLAGN_RTC_INST_UPPER_BOUND)) { - _iwl_write_targ_mem_words(trans, addr, buf, size/4); - } else - return -EINVAL; - return 0; -} - -/* - * This function handles the user application commands for SRAM data dump - * - * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and - * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading - * - * Several error will be retured, -EBUSY if the SRAM data retrieved by - * previous command has not been delivered to userspace, or -ENOMSG if - * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE) - * are missing, or -ENOMEM if the buffer allocation fails. - * - * Otherwise 0 is replied indicating the success of the SRAM reading. - * - * @hw: ieee80211_hw object that represents the device - * @tb: gnl message fields from the user space - */ -static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw, - struct nlattr **tb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - u32 addr, size, cmd; - unsigned char *buf; - - /* Both read and write should be blocked, for atomicity */ - if (priv->testmode_mem.read_in_progress) - return -EBUSY; - - cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); - if (!tb[IWL_TM_ATTR_MEM_ADDR]) { - IWL_ERR(priv, "Error finding memory offset address\n"); - return -ENOMSG; - } - addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]); - if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) { - IWL_ERR(priv, "Error finding size for memory reading\n"); - return -ENOMSG; - } - size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]); - - if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) - return iwl_testmode_indirect_read(priv, addr, size); - else { - if (!tb[IWL_TM_ATTR_BUFFER_DUMP]) - return -EINVAL; - buf = (unsigned char *) nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]); - return iwl_testmode_indirect_write(priv, addr, size, buf); - } -} - -static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct netlink_callback *cb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - int idx, length; - - if (priv->testmode_mem.read_in_progress) { - idx = cb->args[4]; - if (idx >= priv->testmode_mem.num_chunks) { - iwl_mem_cleanup(priv); - return -ENOENT; - } - length = DUMP_CHUNK_SIZE; - if (((idx + 1) == priv->testmode_mem.num_chunks) && - (priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE)) - length = priv->testmode_mem.buff_size % - DUMP_CHUNK_SIZE; - - if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length, - priv->testmode_mem.buff_addr + - (DUMP_CHUNK_SIZE * idx))) - goto nla_put_failure; - idx++; - cb->args[4] = idx; - return 0; - } else - return -EFAULT; - - nla_put_failure: - return -ENOBUFS; -} - -static int iwl_testmode_notifications(struct ieee80211_hw *hw, - struct nlattr **tb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - bool enable; - - enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); - if (enable) - priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; - else - priv->pre_rx_handler = NULL; - return 0; -} - - /* The testmode gnl message handler that takes the gnl message from the * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then * invoke the corresponding handlers. @@ -987,32 +362,27 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int result; - result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, - iwl_testmode_gnl_msg_policy); - if (result != 0) { - IWL_ERR(priv, "Error parsing the gnl message : %d\n", result); + result = iwl_test_parse(&priv->tst, tb, data, len); + if (result) return result; - } - /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ - if (!tb[IWL_TM_ATTR_COMMAND]) { - IWL_ERR(priv, "Missing testmode command type\n"); - return -ENOMSG; - } /* in case multiple accesses to the device happens */ mutex_lock(&priv->mutex); - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_UCODE: - IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n"); - result = iwl_testmode_ucode(hw, tb); - break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: - IWL_DEBUG_INFO(priv, "testmode cmd to register\n"); - result = iwl_testmode_reg(hw, tb); + case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: + case IWL_TM_CMD_APP2DEV_END_TRACE: + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: + case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: + case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: + case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: + result = iwl_test_handle_cmd(&priv->tst, hw, tb); break; + case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: @@ -1020,45 +390,25 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_GET_EEPROM: case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: - case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: - case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: case IWL_TM_CMD_APP2DEV_GET_FW_INFO: IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; - case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: - case IWL_TM_CMD_APP2DEV_END_TRACE: - case IWL_TM_CMD_APP2DEV_READ_TRACE: - IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n"); - result = iwl_testmode_trace(hw, tb); - break; - case IWL_TM_CMD_APP2DEV_OWNERSHIP: IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n"); result = iwl_testmode_ownership(hw, tb); break; - case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: - case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: - IWL_DEBUG_INFO(priv, "testmode indirect memory cmd " - "to driver\n"); - result = iwl_testmode_indirect_mem(hw, tb); - break; - - case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: - IWL_DEBUG_INFO(priv, "testmode notifications cmd " - "to driver\n"); - result = iwl_testmode_notifications(hw, tb); - break; - default: IWL_ERR(priv, "Unknown testmode command\n"); result = -ENOSYS; break; } - mutex_unlock(&priv->mutex); + + if (result) + IWL_ERR(priv, "Test cmd failed result=%d\n", result); return result; } @@ -1066,7 +416,6 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, struct netlink_callback *cb, void *data, int len) { - struct nlattr *tb[IWL_TM_ATTR_MAX]; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int result; u32 cmd; @@ -1075,39 +424,19 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, /* offset by 1 since commands start at 0 */ cmd = cb->args[3] - 1; } else { - result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, - iwl_testmode_gnl_msg_policy); - if (result) { - IWL_ERR(priv, - "Error parsing the gnl message : %d\n", result); + struct nlattr *tb[IWL_TM_ATTR_MAX]; + + result = iwl_test_parse(&priv->tst, tb, data, len); + if (result) return result; - } - /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ - if (!tb[IWL_TM_ATTR_COMMAND]) { - IWL_ERR(priv, "Missing testmode command type\n"); - return -ENOMSG; - } cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); cb->args[3] = cmd + 1; } /* in case multiple accesses to the device happens */ mutex_lock(&priv->mutex); - switch (cmd) { - case IWL_TM_CMD_APP2DEV_READ_TRACE: - IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); - result = iwl_testmode_trace_dump(hw, skb, cb); - break; - case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: - IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); - result = iwl_testmode_buffer_dump(hw, skb, cb); - break; - default: - result = -EINVAL; - break; - } - + result = iwl_test_dump(&priv->tst, cmd, skb, cb); mutex_unlock(&priv->mutex); return result; } diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c new file mode 100644 index 000000000000..76e18630f35d --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -0,0 +1,825 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +#include "iwl-io.h" +#include "iwl-fh.h" +#include "iwl-prph.h" +#include "iwl-trans.h" +#include "iwl-test.h" +#include "iwl-csr.h" +#include "iwl-testmode.h" + +/* + * Periphery registers absolute lower bound. This is used in order to + * differentiate registery access through HBUS_TARG_PRPH_* and + * HBUS_TARG_MEM_* accesses. + */ +#define IWL_ABS_PRPH_START (0xA00000) + +/* + * The TLVs used in the gnl message policy between the kernel module and + * user space application. iwl_testmode_gnl_msg_policy is to be carried + * through the NL80211_CMD_TESTMODE channel regulated by nl80211. + * See iwl-testmode.h + */ +static +struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { + [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, }, + [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, }, + + [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, }, + [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, }, + [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, + + [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, + + [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, + + [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, }, + [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, }, + + [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, }, + [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, +}; + +static inline void iwl_test_trace_clear(struct iwl_test *tst) +{ + memset(&tst->trace, 0, sizeof(struct iwl_test_trace)); +} + +static void iwl_test_trace_stop(struct iwl_test *tst) +{ + if (!tst->trace.enabled) + return; + + if (tst->trace.cpu_addr && tst->trace.dma_addr) + dma_free_coherent(tst->trans->dev, + tst->trace.tsize, + tst->trace.cpu_addr, + tst->trace.dma_addr); + + iwl_test_trace_clear(tst); +} + +static inline void iwl_test_mem_clear(struct iwl_test *tst) +{ + memset(&tst->mem, 0, sizeof(struct iwl_test_mem)); +} + +static inline void iwl_test_mem_stop(struct iwl_test *tst) +{ + if (!tst->mem.in_read) + return; + + iwl_test_mem_clear(tst); +} + +/* + * Initializes the test object + * During the lifetime of the test object it is assumed that the transport is + * started. The test object should be stopped before the transport is stopped. + */ +void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans, + struct iwl_test_ops *ops) +{ + tst->trans = trans; + tst->ops = ops; + + iwl_test_trace_clear(tst); + iwl_test_mem_clear(tst); +} +EXPORT_SYMBOL_GPL(iwl_test_init); + +/* + * Stop the test object + */ +void iwl_test_free(struct iwl_test *tst) +{ + iwl_test_mem_stop(tst); + iwl_test_trace_stop(tst); +} +EXPORT_SYMBOL_GPL(iwl_test_free); + +/* + * This function handles the user application commands to the fw. The fw + * commands are sent in a synchronuous manner. In case that the user requested + * to get commands response, it is send to the user. + */ +static int iwl_test_fw_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb) +{ + struct iwl_host_cmd cmd; + struct iwl_rx_packet *pkt; + struct sk_buff *skb; + void *reply_buf; + u32 reply_len; + int ret; + bool cmd_want_skb; + + memset(&cmd, 0, sizeof(struct iwl_host_cmd)); + + if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] || + !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) { + IWL_ERR(tst->trans, "Missing fw command mandatory fields\n"); + return -ENOMSG; + } + + cmd.flags = CMD_ON_DEMAND | CMD_SYNC; + cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]); + if (cmd_want_skb) + cmd.flags |= CMD_WANT_SKB; + + cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); + cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); + cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); + cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; + IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n", + cmd.id, cmd.flags, cmd.len[0]); + + ret = tst->ops->send_cmd(tst->trans->op_mode, &cmd); + if (ret) { + IWL_ERR(tst->trans, "Failed to send hcmd\n"); + return ret; + } + if (!cmd_want_skb) + return ret; + + /* Handling return of SKB to the user */ + pkt = cmd.resp_pkt; + if (!pkt) { + IWL_ERR(tst->trans, "HCMD received a null response packet\n"); + return ret; + } + + reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20); + reply_buf = kmalloc(reply_len, GFP_KERNEL); + if (!skb || !reply_buf) { + kfree_skb(skb); + kfree(reply_buf); + return -ENOMEM; + } + + /* The reply is in a page, that we cannot send to user space. */ + memcpy(reply_buf, &(pkt->hdr), reply_len); + iwl_free_resp(&cmd); + + if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, + IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || + nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf)) + goto nla_put_failure; + return cfg80211_testmode_reply(skb); + +nla_put_failure: + IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n"); + kfree(reply_buf); + kfree_skb(skb); + return -ENOMSG; +} + +/* + * Handles the user application commands for register access. + */ +static int iwl_test_reg(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb) +{ + u32 ofs, val32, cmd; + u8 val8; + struct sk_buff *skb; + int status = 0; + struct iwl_trans *trans = tst->trans; + + if (!tb[IWL_TM_ATTR_REG_OFFSET]) { + IWL_ERR(trans, "Missing reg offset\n"); + return -ENOMSG; + } + + ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); + IWL_DEBUG_INFO(trans, "test reg access cmd offset=0x%x\n", ofs); + + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + + /* + * Allow access only to FH/CSR/HBUS in direct mode. + * Since we don't have the upper bounds for the CSR and HBUS segments, + * we will use only the upper bound of FH for sanity check. + */ + if (ofs >= FH_MEM_UPPER_BOUND) { + IWL_ERR(trans, "offset out of segment (0x0 - 0x%x)\n", + FH_MEM_UPPER_BOUND); + return -EINVAL; + } + + switch (cmd) { + case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: + val32 = iwl_read_direct32(tst->trans, ofs); + IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32); + + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); + if (!skb) { + IWL_ERR(trans, "Memory allocation fail\n"); + return -ENOMEM; + } + if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32)) + goto nla_put_failure; + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_ERR(trans, "Error sending msg : %d\n", status); + break; + + case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: + if (!tb[IWL_TM_ATTR_REG_VALUE32]) { + IWL_ERR(trans, "Missing value to write\n"); + return -ENOMSG; + } else { + val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); + IWL_DEBUG_INFO(trans, "32b write val=0x%x\n", val32); + iwl_write_direct32(tst->trans, ofs, val32); + } + break; + + case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: + if (!tb[IWL_TM_ATTR_REG_VALUE8]) { + IWL_ERR(trans, "Missing value to write\n"); + return -ENOMSG; + } else { + val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); + IWL_DEBUG_INFO(trans, "8b write val=0x%x\n", val8); + iwl_write8(tst->trans, ofs, val8); + } + break; + + default: + IWL_ERR(trans, "Unknown test register cmd ID\n"); + return -ENOMSG; + } + + return status; + +nla_put_failure: + kfree_skb(skb); + return -EMSGSIZE; +} + +/* + * Handles the request to start FW tracing. Allocates of the trace buffer + * and sends a reply to user space with the address of the allocated buffer. + */ +static int iwl_test_trace_begin(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb) +{ + struct sk_buff *skb; + int status = 0; + + if (tst->trace.enabled) + return -EBUSY; + + if (!tb[IWL_TM_ATTR_TRACE_SIZE]) + tst->trace.size = TRACE_BUFF_SIZE_DEF; + else + tst->trace.size = + nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]); + + if (!tst->trace.size) + return -EINVAL; + + if (tst->trace.size < TRACE_BUFF_SIZE_MIN || + tst->trace.size > TRACE_BUFF_SIZE_MAX) + return -EINVAL; + + tst->trace.tsize = tst->trace.size + TRACE_BUFF_PADD; + tst->trace.cpu_addr = dma_alloc_coherent(tst->trans->dev, + tst->trace.tsize, + &tst->trace.dma_addr, + GFP_KERNEL); + if (!tst->trace.cpu_addr) + return -ENOMEM; + + tst->trace.enabled = true; + tst->trace.trace_addr = (u8 *)PTR_ALIGN(tst->trace.cpu_addr, 0x100); + + memset(tst->trace.trace_addr, 0x03B, tst->trace.size); + + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, + sizeof(tst->trace.dma_addr) + 20); + + if (!skb) { + IWL_ERR(tst->trans, "Memory allocation fail\n"); + iwl_test_trace_stop(tst); + return -ENOMEM; + } + + if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR, + sizeof(tst->trace.dma_addr), + (u64 *)&tst->trace.dma_addr)) + goto nla_put_failure; + + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_ERR(tst->trans, "Error sending msg : %d\n", status); + + tst->trace.nchunks = DIV_ROUND_UP(tst->trace.size, + DUMP_CHUNK_SIZE); + + return status; + +nla_put_failure: + kfree_skb(skb); + if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) == + IWL_TM_CMD_APP2DEV_BEGIN_TRACE) + iwl_test_trace_stop(tst); + return -EMSGSIZE; +} + +/* + * Handles indirect read from the periphery or the SRAM. The read is performed + * to a temporary buffer. The user space application should later issue a dump + */ +static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) +{ + struct iwl_trans *trans = tst->trans; + unsigned long flags; + int i; + + if (size & 0x3) + return -EINVAL; + + tst->mem.size = size; + tst->mem.addr = kmalloc(tst->mem.size, GFP_KERNEL); + if (tst->mem.addr == NULL) + return -ENOMEM; + + /* Hard-coded periphery absolute address */ + if (IWL_ABS_PRPH_START <= addr && + addr < IWL_ABS_PRPH_START + PRPH_END) { + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + iwl_write32(trans, HBUS_TARG_PRPH_RADDR, + addr | (3 << 24)); + for (i = 0; i < size; i += 4) + *(u32 *)(tst->mem.addr + i) = + iwl_read32(trans, HBUS_TARG_PRPH_RDAT); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); + } else { /* target memory (SRAM) */ + _iwl_read_targ_mem_words(trans, addr, + tst->mem.addr, + tst->mem.size / 4); + } + + tst->mem.nchunks = + DIV_ROUND_UP(tst->mem.size, DUMP_CHUNK_SIZE); + tst->mem.in_read = true; + return 0; + +} + +/* + * Handles indirect write to the periphery or SRAM. The is performed to a + * temporary buffer. + */ +static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, + u32 size, unsigned char *buf) +{ + struct iwl_trans *trans = tst->trans; + u32 val, i; + unsigned long flags; + + if (IWL_ABS_PRPH_START <= addr && + addr < IWL_ABS_PRPH_START + PRPH_END) { + /* Periphery writes can be 1-3 bytes long, or DWORDs */ + if (size < 4) { + memcpy(&val, buf, size); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + iwl_write32(trans, HBUS_TARG_PRPH_WADDR, + (addr & 0x0000FFFF) | + ((size - 1) << 24)); + iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); + iwl_release_nic_access(trans); + /* needed after consecutive writes w/o read */ + mmiowb(); + spin_unlock_irqrestore(&trans->reg_lock, flags); + } else { + if (size % 4) + return -EINVAL; + for (i = 0; i < size; i += 4) + iwl_write_prph(trans, addr+i, + *(u32 *)(buf+i)); + } + } else if (tst->ops->valid_hw_addr(addr)) { + _iwl_write_targ_mem_words(trans, addr, buf, size/4); + } else { + return -EINVAL; + } + return 0; +} + +/* + * Handles the user application commands for indirect read/write + * to/from the periphery or the SRAM. + */ +static int iwl_test_indirect_mem(struct iwl_test *tst, struct nlattr **tb) +{ + u32 addr, size, cmd; + unsigned char *buf; + + /* Both read and write should be blocked, for atomicity */ + if (tst->mem.in_read) + return -EBUSY; + + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + if (!tb[IWL_TM_ATTR_MEM_ADDR]) { + IWL_ERR(tst->trans, "Error finding memory offset address\n"); + return -ENOMSG; + } + addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]); + if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) { + IWL_ERR(tst->trans, "Error finding size for memory reading\n"); + return -ENOMSG; + } + size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]); + + if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) { + return iwl_test_indirect_read(tst, addr, size); + } else { + if (!tb[IWL_TM_ATTR_BUFFER_DUMP]) + return -EINVAL; + buf = (unsigned char *)nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]); + return iwl_test_indirect_write(tst, addr, size, buf); + } +} + +/* + * Enable notifications to user space + */ +static int iwl_test_notifications(struct iwl_test *tst, + struct nlattr **tb) +{ + tst->notify = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); + return 0; +} + +/* + * Handles the request to get the device id + */ +static int iwl_test_get_dev_id(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb) +{ + u32 devid = tst->trans->hw_id; + struct sk_buff *skb; + int status; + + IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid); + + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); + if (!skb) { + IWL_ERR(tst->trans, "Memory allocation fail\n"); + return -ENOMEM; + } + + if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid)) + goto nla_put_failure; + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_ERR(tst->trans, "Error sending msg : %d\n", status); + + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EMSGSIZE; +} + +/* + * Handles the request to get the FW version + */ +static int iwl_test_get_fw_ver(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb) +{ + struct sk_buff *skb; + int status; + u32 ver = tst->ops->get_fw_ver(tst->trans->op_mode); + + IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver); + + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); + if (!skb) { + IWL_ERR(tst->trans, "Memory allocation fail\n"); + return -ENOMEM; + } + + if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver)) + goto nla_put_failure; + + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_ERR(tst->trans, "Error sending msg : %d\n", status); + + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EMSGSIZE; +} + +/* + * Parse the netlink message and validate that the IWL_TM_ATTR_CMD exists + */ +int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, + void *data, int len) +{ + int result; + + result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, + iwl_testmode_gnl_msg_policy); + if (result) { + IWL_ERR(tst->trans, "Fail parse gnl msg: %d\n", result); + return result; + } + + /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ + if (!tb[IWL_TM_ATTR_COMMAND]) { + IWL_ERR(tst->trans, "Missing testmode command type\n"); + return -ENOMSG; + } + return 0; +} +EXPORT_SYMBOL_GPL(iwl_test_parse); + +/* + * Handle test commands. + * Returns 1 for unknown commands (not handled by the test object); negative + * value in case of error. + */ +int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb) +{ + int result; + + switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { + case IWL_TM_CMD_APP2DEV_UCODE: + IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n"); + result = iwl_test_fw_cmd(tst, hw, tb); + break; + + case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: + case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: + case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: + IWL_DEBUG_INFO(tst->trans, "test cmd to register\n"); + result = iwl_test_reg(tst, hw, tb); + break; + + case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: + IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n"); + result = iwl_test_trace_begin(tst, hw, tb); + break; + + case IWL_TM_CMD_APP2DEV_END_TRACE: + iwl_test_trace_stop(tst); + result = 0; + break; + + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: + IWL_DEBUG_INFO(tst->trans, "test indirect memory cmd\n"); + result = iwl_test_indirect_mem(tst, tb); + break; + + case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: + IWL_DEBUG_INFO(tst->trans, "test notifications cmd\n"); + result = iwl_test_notifications(tst, tb); + break; + + case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: + IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n"); + result = iwl_test_get_fw_ver(tst, hw, tb); + break; + + case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: + IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n"); + result = iwl_test_get_dev_id(tst, hw, tb); + break; + + default: + IWL_DEBUG_INFO(tst->trans, "Unknown test command\n"); + result = 1; + break; + } + return result; +} +EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); + +static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, + struct netlink_callback *cb) +{ + int idx, length; + + if (!tst->trace.enabled || !tst->trace.trace_addr) + return -EFAULT; + + idx = cb->args[4]; + if (idx >= tst->trace.nchunks) + return -ENOENT; + + length = DUMP_CHUNK_SIZE; + if (((idx + 1) == tst->trace.nchunks) && + (tst->trace.size % DUMP_CHUNK_SIZE)) + length = tst->trace.size % + DUMP_CHUNK_SIZE; + + if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length, + tst->trace.trace_addr + (DUMP_CHUNK_SIZE * idx))) + goto nla_put_failure; + + cb->args[4] = ++idx; + return 0; + + nla_put_failure: + return -ENOBUFS; +} + +static int iwl_test_buffer_dump(struct iwl_test *tst, struct sk_buff *skb, + struct netlink_callback *cb) +{ + int idx, length; + + if (!tst->mem.in_read) + return -EFAULT; + + idx = cb->args[4]; + if (idx >= tst->mem.nchunks) { + iwl_test_mem_stop(tst); + return -ENOENT; + } + + length = DUMP_CHUNK_SIZE; + if (((idx + 1) == tst->mem.nchunks) && + (tst->mem.size % DUMP_CHUNK_SIZE)) + length = tst->mem.size % DUMP_CHUNK_SIZE; + + if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length, + tst->mem.addr + (DUMP_CHUNK_SIZE * idx))) + goto nla_put_failure; + + cb->args[4] = ++idx; + return 0; + + nla_put_failure: + return -ENOBUFS; +} + +/* + * Handle dump commands. + * Returns 1 for unknown commands (not handled by the test object); negative + * value in case of error. + */ +int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, + struct netlink_callback *cb) +{ + int result; + + switch (cmd) { + case IWL_TM_CMD_APP2DEV_READ_TRACE: + IWL_DEBUG_INFO(tst->trans, "uCode trace cmd\n"); + result = iwl_test_trace_dump(tst, skb, cb); + break; + + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: + IWL_DEBUG_INFO(tst->trans, "testmode sram dump cmd\n"); + result = iwl_test_buffer_dump(tst, skb, cb); + break; + + default: + result = 1; + break; + } + return result; +} +EXPORT_SYMBOL_GPL(iwl_test_dump); + +/* + * Multicast a spontaneous messages from the device to the user space. + */ +static void iwl_test_send_rx(struct iwl_test *tst, struct ieee80211_hw *hw, + struct iwl_rx_cmd_buffer *rxb) +{ + struct sk_buff *skb; + struct iwl_rx_packet *data; + int length; + + data = rxb_addr(rxb); + length = le32_to_cpu(data->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + + /* the length doesn't include len_n_flags field, so add it manually */ + length += sizeof(__le32); + + skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length, + GFP_ATOMIC); + if (skb == NULL) { + IWL_ERR(tst->trans, "Out of memory for message to user\n"); + return; + } + + if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, + IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || + nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data)) + goto nla_put_failure; + + cfg80211_testmode_event(skb, GFP_ATOMIC); + return; + +nla_put_failure: + kfree_skb(skb); + IWL_ERR(tst->trans, "Ouch, overran buffer, check allocation!\n"); +} + +/* + * Called whenever a Rx frames is recevied from the device. If notifications to + * the user space are requested, sends the frames to the user. + */ +void iwl_test_rx(struct iwl_test *tst, struct ieee80211_hw *hw, + struct iwl_rx_cmd_buffer *rxb) +{ + if (tst->notify) + iwl_test_send_rx(tst, hw, rxb); +} +EXPORT_SYMBOL_GPL(iwl_test_rx); diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h new file mode 100644 index 000000000000..994615344955 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-test.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#ifndef __IWL_TEST_H__ +#define __IWL_TEST_H__ + +#include +#include "iwl-trans.h" + +struct iwl_test_trace { + u32 size; + u32 tsize; + u32 nchunks; + u8 *cpu_addr; + u8 *trace_addr; + dma_addr_t dma_addr; + bool enabled; +}; + +struct iwl_test_mem { + u32 size; + u32 nchunks; + u8 *addr; + bool in_read; +}; + +struct iwl_test_ops { + int (*send_cmd)(struct iwl_op_mode *op_modes, + struct iwl_host_cmd *cmd); + bool (*valid_hw_addr)(u32 addr); + u32 (*get_fw_ver)(struct iwl_op_mode *op_mode); +}; + +struct iwl_test { + struct iwl_trans *trans; + struct iwl_test_ops *ops; + struct iwl_test_trace trace; + struct iwl_test_mem mem; + bool notify; +}; + +void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans, + struct iwl_test_ops *ops); + +void iwl_test_free(struct iwl_test *tst); + +int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, + void *data, int len); + +int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, + struct nlattr **tb); + +int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, + struct netlink_callback *cb); + +void iwl_test_rx(struct iwl_test *tst, struct ieee80211_hw *hw, + struct iwl_rx_cmd_buffer *rxb); + +static inline void iwl_test_enable_notifications(struct iwl_test *tst, + bool enable) +{ + tst->notify = enable; +} + +#endif diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h similarity index 100% rename from drivers/net/wireless/iwlwifi/dvm/testmode.h rename to drivers/net/wireless/iwlwifi/iwl-testmode.h -- GitLab From c76fe6d19b8beffe792c390c0bd215d193512f1e Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 4 Jun 2012 19:39:30 +0300 Subject: [PATCH 1052/6849] iwlwifi: decouple testmode and iwl-test The iwl-test flows were based on the cfg80211 testmode APIs. To remove this coupling, the op mode (during the initialization of the iwl_test object) is responsible to set the callbacks that should be used by iwl-test to allocate skbs for events and replies and to send events and replies. The current op modes implement these callbacks based on the cfg80211 testmode APIs. Reviewed-by: Emmanuel Grumbach Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/rx.c | 2 +- drivers/net/wireless/iwlwifi/dvm/testmode.c | 31 +++++- drivers/net/wireless/iwlwifi/iwl-test.c | 109 +++++++++++++------- drivers/net/wireless/iwlwifi/iwl-test.h | 44 +++++++- 4 files changed, 141 insertions(+), 45 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index afdacb25f344..c1f7a18e08dd 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c @@ -1143,7 +1143,7 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow * continues. */ - iwl_test_rx(&priv->tst, priv->hw, rxb); + iwl_test_rx(&priv->tst, rxb); #endif if (priv->ucode_owner != IWL_OWNERSHIP_TM) { diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index aa9518f13e89..57b918ce3b5f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c @@ -103,10 +103,39 @@ static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode) return priv->fw->ucode_ver; } +static struct sk_buff* +iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len); +} + +static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb) +{ + return cfg80211_testmode_reply(skb); +} + +static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode, + int len) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len, + GFP_ATOMIC); +} + +static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb) +{ + return cfg80211_testmode_event(skb, GFP_ATOMIC); +} + static struct iwl_test_ops tst_ops = { .send_cmd = iwl_testmode_send_cmd, .valid_hw_addr = iwl_testmode_valid_hw_addr, .get_fw_ver = iwl_testmode_get_fw_ver, + .alloc_reply = iwl_testmode_alloc_reply, + .reply = iwl_testmode_reply, + .alloc_event = iwl_testmode_alloc_event, + .event = iwl_testmode_event, }; void iwl_testmode_init(struct iwl_priv *priv) @@ -380,7 +409,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: - result = iwl_test_handle_cmd(&priv->tst, hw, tb); + result = iwl_test_handle_cmd(&priv->tst, tb); break; case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index 76e18630f35d..7a264aee2534 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -61,7 +61,9 @@ * *****************************************************************************/ +#include #include + #include "iwl-io.h" #include "iwl-fh.h" #include "iwl-prph.h" @@ -178,13 +180,51 @@ void iwl_test_free(struct iwl_test *tst) } EXPORT_SYMBOL_GPL(iwl_test_free); +static inline int iwl_test_send_cmd(struct iwl_test *tst, + struct iwl_host_cmd *cmd) +{ + return tst->ops->send_cmd(tst->trans->op_mode, cmd); +} + +static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr) +{ + return tst->ops->valid_hw_addr(addr); +} + +static inline u32 iwl_test_fw_ver(struct iwl_test *tst) +{ + return tst->ops->get_fw_ver(tst->trans->op_mode); +} + +static inline struct sk_buff* +iwl_test_alloc_reply(struct iwl_test *tst, int len) +{ + return tst->ops->alloc_reply(tst->trans->op_mode, len); +} + +static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb) +{ + return tst->ops->reply(tst->trans->op_mode, skb); +} + +static inline struct sk_buff* +iwl_test_alloc_event(struct iwl_test *tst, int len) +{ + return tst->ops->alloc_event(tst->trans->op_mode, len); +} + +static inline void +iwl_test_event(struct iwl_test *tst, struct sk_buff *skb) +{ + return tst->ops->event(tst->trans->op_mode, skb); +} + /* * This function handles the user application commands to the fw. The fw * commands are sent in a synchronuous manner. In case that the user requested * to get commands response, it is send to the user. */ -static int iwl_test_fw_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb) +static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb) { struct iwl_host_cmd cmd; struct iwl_rx_packet *pkt; @@ -214,7 +254,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n", cmd.id, cmd.flags, cmd.len[0]); - ret = tst->ops->send_cmd(tst->trans->op_mode, &cmd); + ret = iwl_test_send_cmd(tst, &cmd); if (ret) { IWL_ERR(tst->trans, "Failed to send hcmd\n"); return ret; @@ -230,7 +270,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, } reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20); + skb = iwl_test_alloc_reply(tst, reply_len + 20); reply_buf = kmalloc(reply_len, GFP_KERNEL); if (!skb || !reply_buf) { kfree_skb(skb); @@ -246,7 +286,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf)) goto nla_put_failure; - return cfg80211_testmode_reply(skb); + return iwl_test_reply(tst, skb); nla_put_failure: IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n"); @@ -258,8 +298,7 @@ nla_put_failure: /* * Handles the user application commands for register access. */ -static int iwl_test_reg(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb) +static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb) { u32 ofs, val32, cmd; u8 val8; @@ -293,14 +332,14 @@ static int iwl_test_reg(struct iwl_test *tst, struct ieee80211_hw *hw, val32 = iwl_read_direct32(tst->trans, ofs); IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32); - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); + skb = iwl_test_alloc_reply(tst, 20); if (!skb) { IWL_ERR(trans, "Memory allocation fail\n"); return -ENOMEM; } if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32)) goto nla_put_failure; - status = cfg80211_testmode_reply(skb); + status = iwl_test_reply(tst, skb); if (status < 0) IWL_ERR(trans, "Error sending msg : %d\n", status); break; @@ -343,8 +382,7 @@ nla_put_failure: * Handles the request to start FW tracing. Allocates of the trace buffer * and sends a reply to user space with the address of the allocated buffer. */ -static int iwl_test_trace_begin(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb) +static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb) { struct sk_buff *skb; int status = 0; @@ -378,9 +416,7 @@ static int iwl_test_trace_begin(struct iwl_test *tst, struct ieee80211_hw *hw, memset(tst->trace.trace_addr, 0x03B, tst->trace.size); - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - sizeof(tst->trace.dma_addr) + 20); - + skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20); if (!skb) { IWL_ERR(tst->trans, "Memory allocation fail\n"); iwl_test_trace_stop(tst); @@ -392,7 +428,7 @@ static int iwl_test_trace_begin(struct iwl_test *tst, struct ieee80211_hw *hw, (u64 *)&tst->trace.dma_addr)) goto nla_put_failure; - status = cfg80211_testmode_reply(skb); + status = iwl_test_reply(tst, skb); if (status < 0) IWL_ERR(tst->trans, "Error sending msg : %d\n", status); @@ -485,7 +521,7 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, iwl_write_prph(trans, addr+i, *(u32 *)(buf+i)); } - } else if (tst->ops->valid_hw_addr(addr)) { + } else if (iwl_test_valid_hw_addr(tst, addr)) { _iwl_write_targ_mem_words(trans, addr, buf, size/4); } else { return -EINVAL; @@ -541,8 +577,7 @@ static int iwl_test_notifications(struct iwl_test *tst, /* * Handles the request to get the device id */ -static int iwl_test_get_dev_id(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb) +static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb) { u32 devid = tst->trans->hw_id; struct sk_buff *skb; @@ -550,7 +585,7 @@ static int iwl_test_get_dev_id(struct iwl_test *tst, struct ieee80211_hw *hw, IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid); - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); + skb = iwl_test_alloc_reply(tst, 20); if (!skb) { IWL_ERR(tst->trans, "Memory allocation fail\n"); return -ENOMEM; @@ -558,7 +593,7 @@ static int iwl_test_get_dev_id(struct iwl_test *tst, struct ieee80211_hw *hw, if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid)) goto nla_put_failure; - status = cfg80211_testmode_reply(skb); + status = iwl_test_reply(tst, skb); if (status < 0) IWL_ERR(tst->trans, "Error sending msg : %d\n", status); @@ -572,16 +607,15 @@ nla_put_failure: /* * Handles the request to get the FW version */ -static int iwl_test_get_fw_ver(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb) +static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb) { struct sk_buff *skb; int status; - u32 ver = tst->ops->get_fw_ver(tst->trans->op_mode); + u32 ver = iwl_test_fw_ver(tst); IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver); - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); + skb = iwl_test_alloc_reply(tst, 20); if (!skb) { IWL_ERR(tst->trans, "Memory allocation fail\n"); return -ENOMEM; @@ -590,7 +624,7 @@ static int iwl_test_get_fw_ver(struct iwl_test *tst, struct ieee80211_hw *hw, if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver)) goto nla_put_failure; - status = cfg80211_testmode_reply(skb); + status = iwl_test_reply(tst, skb); if (status < 0) IWL_ERR(tst->trans, "Error sending msg : %d\n", status); @@ -630,27 +664,26 @@ EXPORT_SYMBOL_GPL(iwl_test_parse); * Returns 1 for unknown commands (not handled by the test object); negative * value in case of error. */ -int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb) +int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb) { int result; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_UCODE: IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n"); - result = iwl_test_fw_cmd(tst, hw, tb); + result = iwl_test_fw_cmd(tst, tb); break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: IWL_DEBUG_INFO(tst->trans, "test cmd to register\n"); - result = iwl_test_reg(tst, hw, tb); + result = iwl_test_reg(tst, tb); break; case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n"); - result = iwl_test_trace_begin(tst, hw, tb); + result = iwl_test_trace_begin(tst, tb); break; case IWL_TM_CMD_APP2DEV_END_TRACE: @@ -671,12 +704,12 @@ int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n"); - result = iwl_test_get_fw_ver(tst, hw, tb); + result = iwl_test_get_fw_ver(tst, tb); break; case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n"); - result = iwl_test_get_dev_id(tst, hw, tb); + result = iwl_test_get_dev_id(tst, tb); break; default: @@ -779,7 +812,7 @@ EXPORT_SYMBOL_GPL(iwl_test_dump); /* * Multicast a spontaneous messages from the device to the user space. */ -static void iwl_test_send_rx(struct iwl_test *tst, struct ieee80211_hw *hw, +static void iwl_test_send_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb) { struct sk_buff *skb; @@ -792,8 +825,7 @@ static void iwl_test_send_rx(struct iwl_test *tst, struct ieee80211_hw *hw, /* the length doesn't include len_n_flags field, so add it manually */ length += sizeof(__le32); - skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length, - GFP_ATOMIC); + skb = iwl_test_alloc_event(tst, length + 20); if (skb == NULL) { IWL_ERR(tst->trans, "Out of memory for message to user\n"); return; @@ -804,7 +836,7 @@ static void iwl_test_send_rx(struct iwl_test *tst, struct ieee80211_hw *hw, nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data)) goto nla_put_failure; - cfg80211_testmode_event(skb, GFP_ATOMIC); + iwl_test_event(tst, skb); return; nla_put_failure: @@ -816,10 +848,9 @@ nla_put_failure: * Called whenever a Rx frames is recevied from the device. If notifications to * the user space are requested, sends the frames to the user. */ -void iwl_test_rx(struct iwl_test *tst, struct ieee80211_hw *hw, - struct iwl_rx_cmd_buffer *rxb) +void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb) { if (tst->notify) - iwl_test_send_rx(tst, hw, rxb); + iwl_test_send_rx(tst, rxb); } EXPORT_SYMBOL_GPL(iwl_test_rx); diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h index 994615344955..e13ffa8acc02 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.h +++ b/drivers/net/wireless/iwlwifi/iwl-test.h @@ -84,11 +84,49 @@ struct iwl_test_mem { bool in_read; }; +/* + * struct iwl_test_ops: callback to the op mode + * + * The structure defines the callbacks that the op_mode should handle, + * inorder to handle logic that is out of the scope of iwl_test. The + * op_mode must set all the callbacks. + + * @send_cmd: handler that is used by the test object to request the + * op_mode to send a command to the fw. + * + * @valid_hw_addr: handler that is used by the test object to request the + * op_mode to check if the given address is a valid address. + * + * @get_fw_ver: handler used to get the FW version. + * + * @alloc_reply: handler used by the test object to request the op_mode + * to allocate an skb for sending a reply to the user, and initialize + * the skb. It is assumed that the test object only fills the required + * attributes. + * + * @reply: handler used by the test object to request the op_mode to reply + * to a request. The skb is an skb previously allocated by the the + * alloc_reply callback. + I + * @alloc_event: handler used by the test object to request the op_mode + * to allocate an skb for sending an event, and initialize + * the skb. It is assumed that the test object only fills the required + * attributes. + * + * @reply: handler used by the test object to request the op_mode to send + * an event. The skb is an skb previously allocated by the the + * alloc_event callback. + */ struct iwl_test_ops { int (*send_cmd)(struct iwl_op_mode *op_modes, struct iwl_host_cmd *cmd); bool (*valid_hw_addr)(u32 addr); u32 (*get_fw_ver)(struct iwl_op_mode *op_mode); + + struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len); + int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb); + struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len); + void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb); }; struct iwl_test { @@ -107,14 +145,12 @@ void iwl_test_free(struct iwl_test *tst); int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, void *data, int len); -int iwl_test_handle_cmd(struct iwl_test *tst, struct ieee80211_hw *hw, - struct nlattr **tb); +int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb); int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, struct netlink_callback *cb); -void iwl_test_rx(struct iwl_test *tst, struct ieee80211_hw *hw, - struct iwl_rx_cmd_buffer *rxb); +void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb); static inline void iwl_test_enable_notifications(struct iwl_test *tst, bool enable) -- GitLab From a15687c487662c1cdcaf9d6f89270b616ccbad02 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 19 Apr 2012 00:39:19 +0200 Subject: [PATCH 1053/6849] ARM: nomadik: bump all IRQ numbers by one Since the VIC was converted to use generic IRQ domains IRQ 0 is silently ignored. This IRQ is used on the Nomadik so we're missing it now. Bump all IRQ numbers by one since they are now decoupled from the hardware IRQ numbers. Cc: Grant Likely Acked-by: Rob Herring Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/include/mach/irqs.h | 85 +++++++++++------------ 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/arch/arm/mach-nomadik/include/mach/irqs.h b/arch/arm/mach-nomadik/include/mach/irqs.h index 8faabc560398..a118e615f865 100644 --- a/arch/arm/mach-nomadik/include/mach/irqs.h +++ b/arch/arm/mach-nomadik/include/mach/irqs.h @@ -22,56 +22,56 @@ #include -#define IRQ_VIC_START 0 /* first VIC interrupt is 0 */ +#define IRQ_VIC_START 1 /* first VIC interrupt is 1 */ /* * Interrupt numbers generic for all Nomadik Chip cuts */ -#define IRQ_WATCHDOG 0 -#define IRQ_SOFTINT 1 -#define IRQ_CRYPTO 2 -#define IRQ_OWM 3 -#define IRQ_MTU0 4 -#define IRQ_MTU1 5 -#define IRQ_GPIO0 6 -#define IRQ_GPIO1 7 -#define IRQ_GPIO2 8 -#define IRQ_GPIO3 9 -#define IRQ_RTC_RTT 10 -#define IRQ_SSP 11 -#define IRQ_UART0 12 -#define IRQ_DMA1 13 -#define IRQ_CLCD_MDIF 14 -#define IRQ_DMA0 15 -#define IRQ_PWRFAIL 16 -#define IRQ_UART1 17 -#define IRQ_FIRDA 18 -#define IRQ_MSP0 19 -#define IRQ_I2C0 20 -#define IRQ_I2C1 21 -#define IRQ_SDMMC 22 -#define IRQ_USBOTG 23 -#define IRQ_SVA_IT0 24 -#define IRQ_SVA_IT1 25 -#define IRQ_SAA_IT0 26 -#define IRQ_SAA_IT1 27 -#define IRQ_UART2 28 -#define IRQ_MSP2 31 -#define IRQ_L2CC 48 -#define IRQ_HPI 49 -#define IRQ_SKE 50 -#define IRQ_KP 51 -#define IRQ_MEMST 54 -#define IRQ_SGA_IT 58 -#define IRQ_USBM 60 -#define IRQ_MSP1 62 +#define IRQ_WATCHDOG 1 +#define IRQ_SOFTINT 2 +#define IRQ_CRYPTO 3 +#define IRQ_OWM 4 +#define IRQ_MTU0 5 +#define IRQ_MTU1 6 +#define IRQ_GPIO0 7 +#define IRQ_GPIO1 8 +#define IRQ_GPIO2 9 +#define IRQ_GPIO3 10 +#define IRQ_RTC_RTT 11 +#define IRQ_SSP 12 +#define IRQ_UART0 13 +#define IRQ_DMA1 14 +#define IRQ_CLCD_MDIF 15 +#define IRQ_DMA0 16 +#define IRQ_PWRFAIL 17 +#define IRQ_UART1 18 +#define IRQ_FIRDA 19 +#define IRQ_MSP0 20 +#define IRQ_I2C0 21 +#define IRQ_I2C1 22 +#define IRQ_SDMMC 23 +#define IRQ_USBOTG 24 +#define IRQ_SVA_IT0 25 +#define IRQ_SVA_IT1 26 +#define IRQ_SAA_IT0 27 +#define IRQ_SAA_IT1 28 +#define IRQ_UART2 29 +#define IRQ_MSP2 30 +#define IRQ_L2CC 49 +#define IRQ_HPI 50 +#define IRQ_SKE 51 +#define IRQ_KP 52 +#define IRQ_MEMST 55 +#define IRQ_SGA_IT 59 +#define IRQ_USBM 61 +#define IRQ_MSP1 63 -#define NOMADIK_SOC_NR_IRQS 64 +#define NOMADIK_GPIO_OFFSET (IRQ_VIC_START+64) /* After chip-specific IRQ numbers we have the GPIO ones */ #define NOMADIK_NR_GPIO 128 /* last 4 not wired to pins */ -#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + NOMADIK_SOC_NR_IRQS) -#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - NOMADIK_SOC_NR_IRQS) +#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + NOMADIK_GPIO_OFFSET) +#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - NOMADIK_GPIO_OFFSET) #define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) /* Following two are used by entry_macro.S, to access our dual-vic */ @@ -79,4 +79,3 @@ #define VIC_REG_IRQSR1 0x20 #endif /* __ASM_ARCH_IRQS_H */ - -- GitLab From 754fdff86f956a91834887ad56ea292f5d2fa114 Mon Sep 17 00:00:00 2001 From: Annie Liu Date: Fri, 8 Jun 2012 19:18:39 +0800 Subject: [PATCH 1054/6849] ALSA: hda - add support for HD-Audio of VIA HDMI GFX Cards This is patch supporting HD-Audio function of VIA GFX cards which support HDMI. Those are integrated graphics of chipsets VX900 and VX11 separately. Signed-off-by: Annie Liu Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2b6392be451c..d49926e4d19f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -3338,6 +3338,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* VIA VT8251/VT8237A */ { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, + /* VIA GFX VT7122/VX900 */ + { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC }, + /* VIA GFX VT6122/VX11 */ + { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC }, /* SIS966 */ { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, /* ULI M5461 */ -- GitLab From 3de5ff88773d9f106b668937da2f36c97801b332 Mon Sep 17 00:00:00 2001 From: Annie Liu Date: Fri, 8 Jun 2012 19:18:42 +0800 Subject: [PATCH 1055/6849] ALSA: hda - add support for HD-Audio CODECes of VIA HDMI GFX Cards This is patch supporting the CODECes of HD-Audio function of VIA GFX cards which support HDMI. For CODECes 0x9f80/0x9f81, which belong to VX900, since the hardware is not fully compliant to HD-Audio 1.3, simple_i*() is adopted temporarily. Signed-off-by: Annie Liu Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index ad319d4dc32f..696681826b01 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1863,6 +1863,62 @@ static int patch_atihdmi(struct hda_codec *codec) return 0; } +/* VIA HDMI Implementation */ +#define VIAHDMI_CVT_NID 0x02 /* audio converter1 */ +#define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */ + +static struct hda_verb viahdmi_basic_init[] = { + /* enable digital output on pin widget */ + { VIAHDMI_PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + {} /* terminator */ +}; + +static int via_hdmi_init(struct hda_codec *codec) +{ + snd_hda_sequence_write(codec, viahdmi_basic_init); + return 0; +} + +static const struct hda_codec_ops via_hdmi_patch_ops = { + .build_controls = simple_playback_build_controls, + .build_pcms = simple_playback_build_pcms, + .init = via_hdmi_init, + .free = simple_playback_free, +}; + +static struct hda_pcm_stream via_hdmi_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = VIAHDMI_CVT_NID, /* NID to query formats and rates*/ + .ops = { + .open = simple_playback_pcm_open, + .close = simple_playback_pcm_close, + .prepare = simple_playback_pcm_prepare + }, +}; + +static int patch_via_hdmi(struct hda_codec *codec) +{ + struct hdmi_spec *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + spec->multiout.num_dacs = 0; /* no analog */ + spec->multiout.max_channels = 2; + spec->multiout.dig_out_nid = VIAHDMI_CVT_NID; /* pure-digital case */ + spec->num_cvts = 1; + spec->cvts[0].cvt_nid = VIAHDMI_CVT_NID; + spec->pins[0].pin_nid = VIAHDMI_PIN_NID; + spec->pcm_playback = &via_hdmi_digital_playback; + + codec->spec = spec; + codec->patch_ops = via_hdmi_patch_ops; + + return 0; +} /* * patch entries @@ -1904,6 +1960,10 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, +{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, +{ .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, +{ .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, @@ -1950,6 +2010,10 @@ MODULE_ALIAS("snd-hda-codec-id:10de0043"); MODULE_ALIAS("snd-hda-codec-id:10de0044"); MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de8001"); +MODULE_ALIAS("snd-hda-codec-id:11069f80"); +MODULE_ALIAS("snd-hda-codec-id:11069f81"); +MODULE_ALIAS("snd-hda-codec-id:11069f84"); +MODULE_ALIAS("snd-hda-codec-id:11069f85"); MODULE_ALIAS("snd-hda-codec-id:17e80047"); MODULE_ALIAS("snd-hda-codec-id:80860054"); MODULE_ALIAS("snd-hda-codec-id:80862801"); -- GitLab From b71dad181a55d2ad90bd03cd3216a5a8a31d9468 Mon Sep 17 00:00:00 2001 From: Mark Hills Date: Sat, 9 Jun 2012 13:16:38 +0100 Subject: [PATCH 1056/6849] ALSA: usb-audio: Use a table of mixer controls Allow mixer controls to be provided clearly in a table, to avoid quantity of error checking at each use. Signed-off-by: Mark Hills Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 105 ++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 56 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 41f4b6911920..ce7d96f91578 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -42,6 +42,13 @@ extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; +struct std_mono_table { + unsigned int unitid, control, cmask; + int val_type; + const char *name; + snd_kcontrol_tlv_rw_t *tlv_callback; +}; + /* private_free callback */ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) { @@ -113,6 +120,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, return 0; } +/* + * Create a set of standard UAC controls from a table + */ +static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, + struct std_mono_table *t) +{ + int err; + + while (t->name != NULL) { + err = snd_create_std_mono_ctl(mixer, t->unitid, t->control, + t->cmask, t->val_type, t->name, t->tlv_callback); + if (err < 0) + return err; + t++; + } + + return 0; +} + /* * Sound Blaster remote control configuration * @@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer) return 0; } - -/* - * Create mixer for Electrix Ebox-44 - * - * The mixer units from this device are corrupt, and even where they - * are valid they presents mono controls as L and R channels of - * stereo. So we create a good mixer in code. - */ - -static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer) -{ - int err; - - err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, - "Headphone Playback Switch", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16, - "Headphone A Mix Playback Volume", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16, - "Headphone B Mix Playback Volume", NULL); - if (err < 0) - return err; - - err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, - "Output Playback Switch", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16, - "Output A Playback Volume", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16, - "Output B Playback Volume", NULL); - if (err < 0) - return err; - - err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, - "Input Capture Switch", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16, - "Input A Capture Volume", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16, - "Input B Capture Volume", NULL); - if (err < 0) - return err; - - return 0; -} - void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, unsigned char samplerate_id) { @@ -990,6 +961,27 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, } } +/* + * The mixer units for Ebox-44 are corrupt, and even where they + * are valid they presents mono controls as L and R channels of + * stereo. So we provide a good mixer here. + */ +struct std_mono_table ebox44_table[] = { + { 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL }, + { 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL }, + { 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL }, + + { 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL }, + { 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL }, + { 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL }, + + { 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL }, + { 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL }, + { 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL }, + + { } +}; + int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) { int err = 0; @@ -1035,7 +1027,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) break; case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ - err = snd_ebox44_create_mixer(mixer); + /* detection is disabled in mixer_maps.c */ + err = snd_create_std_mono_table(mixer, ebox44_table); break; } -- GitLab From 989b01385fa3cc4eaa488068a0868ae4de5198a9 Mon Sep 17 00:00:00 2001 From: Mark Hills Date: Sat, 9 Jun 2012 13:16:39 +0100 Subject: [PATCH 1057/6849] ALSA: usb-audio: Convert table to preferred C99 format Signed-off-by: Mark Hills Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 74 ++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ce7d96f91578..690000db0ec0 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -967,19 +967,73 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, * stereo. So we provide a good mixer here. */ struct std_mono_table ebox44_table[] = { - { 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL }, - { 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL }, - { 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL }, + { + .unitid = 4, + .control = 1, + .cmask = 0x0, + .val_type = USB_MIXER_INV_BOOLEAN, + .name = "Headphone Playback Switch" + }, + { + .unitid = 4, + .control = 2, + .cmask = 0x1, + .val_type = USB_MIXER_S16, + .name = "Headphone A Mix Playback Volume" + }, + { + .unitid = 4, + .control = 2, + .cmask = 0x2, + .val_type = USB_MIXER_S16, + .name = "Headphone B Mix Playback Volume" + }, - { 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL }, - { 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL }, - { 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL }, + { + .unitid = 7, + .control = 1, + .cmask = 0x0, + .val_type = USB_MIXER_INV_BOOLEAN, + .name = "Output Playback Switch" + }, + { + .unitid = 7, + .control = 2, + .cmask = 0x1, + .val_type = USB_MIXER_S16, + .name = "Output A Playback Volume" + }, + { + .unitid = 7, + .control = 2, + .cmask = 0x2, + .val_type = USB_MIXER_S16, + .name = "Output B Playback Volume" + }, - { 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL }, - { 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL }, - { 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL }, + { + .unitid = 10, + .control = 1, + .cmask = 0x0, + .val_type = USB_MIXER_INV_BOOLEAN, + .name = "Input Capture Switch" + }, + { + .unitid = 10, + .control = 2, + .cmask = 0x1, + .val_type = USB_MIXER_S16, + .name = "Input A Capture Volume" + }, + { + .unitid = 10, + .control = 2, + .cmask = 0x2, + .val_type = USB_MIXER_S16, + .name = "Input B Capture Volume" + }, - { } + {} }; int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) -- GitLab From 7b34ca2ac7063f4ebf07f85fd75253ed84d5c648 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 11 Jun 2012 04:13:57 -0700 Subject: [PATCH 1058/6849] inet: Avoid potential NULL peer dereference. We handle NULL in rt{,6}_set_peer but then our caller will try to pass that NULL pointer into inet_putpeer() which isn't ready for it. Fix this by moving the NULL check one level up, and then remove the now unnecessary NULL check from inetpeer_ptr_set_peer(). Reported-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/inetpeer.h | 2 +- net/ipv4/route.c | 11 ++++++----- net/ipv6/route.c | 10 ++++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index e15c0862a686..c27c8f10ebdc 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -104,7 +104,7 @@ static inline bool inetpeer_ptr_set_peer(unsigned long *ptr, struct inet_peer *p unsigned long val = (unsigned long) peer; unsigned long orig = *ptr; - if (!(orig & INETPEER_BASE_BIT) || !val || + if (!(orig & INETPEER_BASE_BIT) || cmpxchg(ptr, orig, val) != orig) return false; return true; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 4c33ce3000ed..842510d50453 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1333,11 +1333,12 @@ void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) return; peer = inet_getpeer_v4(base, daddr, create); - - if (!rt_set_peer(rt, peer)) - inet_putpeer(peer); - else - rt->rt_peer_genid = rt_peer_genid(); + if (peer) { + if (!rt_set_peer(rt, peer)) + inet_putpeer(peer); + else + rt->rt_peer_genid = rt_peer_genid(); + } } /* diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d9ba4808f26a..58a3ec23da2f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -313,10 +313,12 @@ void rt6_bind_peer(struct rt6_info *rt, int create) return; peer = inet_getpeer_v6(base, &rt->rt6i_dst.addr, create); - if (!rt6_set_peer(rt, peer)) - inet_putpeer(peer); - else - rt->rt6i_peer_genid = rt6_peer_genid(); + if (peer) { + if (!rt6_set_peer(rt, peer)) + inet_putpeer(peer); + else + rt->rt6i_peer_genid = rt6_peer_genid(); + } } static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, -- GitLab From a4808147dcf1ecf2f76212a78fd9692b3c112f47 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 11 Jun 2012 13:16:35 +0100 Subject: [PATCH 1059/6849] seq_file: Add seq_vprintf function and export it The existing seq_printf function is rewritten in terms of the new seq_vprintf which is also exported to modules. This allows GFS2 (and potentially other seq_file users) to have a vprintf based interface and to avoid an extra copy into a temporary buffer in some cases. Signed-off-by: Steven Whitehouse Reported-by: Eric Dumazet Acked-by: Al Viro --- fs/seq_file.c | 18 ++++++++++++++---- include/linux/seq_file.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index 0cbd0494b79e..14cf9de1dbe1 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -385,15 +385,12 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc) } EXPORT_SYMBOL(seq_escape); -int seq_printf(struct seq_file *m, const char *f, ...) +int seq_vprintf(struct seq_file *m, const char *f, va_list args) { - va_list args; int len; if (m->count < m->size) { - va_start(args, f); len = vsnprintf(m->buf + m->count, m->size - m->count, f, args); - va_end(args); if (m->count + len < m->size) { m->count += len; return 0; @@ -402,6 +399,19 @@ int seq_printf(struct seq_file *m, const char *f, ...) seq_set_overflow(m); return -1; } +EXPORT_SYMBOL(seq_vprintf); + +int seq_printf(struct seq_file *m, const char *f, ...) +{ + int ret; + va_list args; + + va_start(args, f); + ret = seq_vprintf(m, f, args); + va_end(args); + + return ret; +} EXPORT_SYMBOL(seq_printf); /** diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index fc61854f6224..83c44eefe698 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -86,6 +86,7 @@ int seq_puts(struct seq_file *m, const char *s); int seq_write(struct seq_file *seq, const void *data, size_t len); __printf(2, 3) int seq_printf(struct seq_file *, const char *, ...); +__printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args); int seq_path(struct seq_file *, const struct path *, const char *); int seq_dentry(struct seq_file *, struct dentry *, const char *); -- GitLab From 90ba6859ce914feff3632eeb7227b9f99c030ca9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:15:50 +0800 Subject: [PATCH 1060/6849] ASoC: wm8996: Remove spurious regulator_bulk_free() We're using demv_regulator_bulk_get() so don't need to manually free and this is in the CODEC driver not the I2C driver anyway. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 8af422e38fd0..379bd1e49432 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -3051,7 +3051,6 @@ static int wm8996_remove(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) regulator_unregister_notifier(wm8996->supplies[i].consumer, &wm8996->disable_nb[i]); - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); return 0; } -- GitLab From db1334098392e1278a113e629a7ae58a7453f83f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:23:13 +0800 Subject: [PATCH 1061/6849] ASoC: wm8996: Move reset before the initial regulator disable If we don't have control over the LDO but do have control over the other regulators then we may end up trying to write to a powered off device. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 379bd1e49432..64d9cf7149de 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -3205,14 +3205,14 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, dev_info(&i2c->dev, "revision %c\n", (reg & WM8996_CHIP_REV_MASK) + 'A'); - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); - ret = wm8996_reset(wm8996); if (ret < 0) { dev_err(&i2c->dev, "Failed to issue reset\n"); goto err_regmap; } + regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); + wm8996_init_gpio(wm8996); ret = snd_soc_register_codec(&i2c->dev, -- GitLab From 9c699e0a9566cfb6245284ce4857d7a06b02f3b1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:20:02 +0800 Subject: [PATCH 1062/6849] ASoC: wm8996: Mark the CODEC as cache only when powering off on boot Otherwise we might try to write to a powered off device. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 64d9cf7149de..dc9b42b7fc4d 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2837,8 +2837,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) } } - regcache_cache_only(codec->control_data, true); - /* Apply platform data settings */ snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, @@ -3211,6 +3209,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, goto err_regmap; } + regcache_cache_only(wm8996->regmap, true); regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); wm8996_init_gpio(wm8996); -- GitLab From 66c2b7377a7cf22c48ebba7fdff5340ab492b7bc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:09:46 +0800 Subject: [PATCH 1063/6849] ASoC: wm8996: Remove write sequencer registers from the defaults table They aren't marked as readable and the feature is never used so they'll never get referenced. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 178 -------------------------------------- 1 file changed, 178 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index efc4e9d0903b..f24989f090ca 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -296,184 +296,6 @@ static struct reg_default wm8996_reg[] = { { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, - { WM8996_WRITE_SEQUENCER_0, 0x1 }, - { WM8996_WRITE_SEQUENCER_1, 0x1 }, - { WM8996_WRITE_SEQUENCER_3, 0x6 }, - { WM8996_WRITE_SEQUENCER_4, 0x40 }, - { WM8996_WRITE_SEQUENCER_5, 0x1 }, - { WM8996_WRITE_SEQUENCER_6, 0xf }, - { WM8996_WRITE_SEQUENCER_7, 0x6 }, - { WM8996_WRITE_SEQUENCER_8, 0x1 }, - { WM8996_WRITE_SEQUENCER_9, 0x3 }, - { WM8996_WRITE_SEQUENCER_10, 0x104 }, - { WM8996_WRITE_SEQUENCER_12, 0x60 }, - { WM8996_WRITE_SEQUENCER_13, 0x11 }, - { WM8996_WRITE_SEQUENCER_14, 0x401 }, - { WM8996_WRITE_SEQUENCER_16, 0x50 }, - { WM8996_WRITE_SEQUENCER_17, 0x3 }, - { WM8996_WRITE_SEQUENCER_18, 0x100 }, - { WM8996_WRITE_SEQUENCER_20, 0x51 }, - { WM8996_WRITE_SEQUENCER_21, 0x3 }, - { WM8996_WRITE_SEQUENCER_22, 0x104 }, - { WM8996_WRITE_SEQUENCER_23, 0xa }, - { WM8996_WRITE_SEQUENCER_24, 0x60 }, - { WM8996_WRITE_SEQUENCER_25, 0x3b }, - { WM8996_WRITE_SEQUENCER_26, 0x502 }, - { WM8996_WRITE_SEQUENCER_27, 0x100 }, - { WM8996_WRITE_SEQUENCER_28, 0x2fff }, - { WM8996_WRITE_SEQUENCER_32, 0x2fff }, - { WM8996_WRITE_SEQUENCER_36, 0x2fff }, - { WM8996_WRITE_SEQUENCER_40, 0x2fff }, - { WM8996_WRITE_SEQUENCER_44, 0x2fff }, - { WM8996_WRITE_SEQUENCER_48, 0x2fff }, - { WM8996_WRITE_SEQUENCER_52, 0x2fff }, - { WM8996_WRITE_SEQUENCER_56, 0x2fff }, - { WM8996_WRITE_SEQUENCER_60, 0x2fff }, - { WM8996_WRITE_SEQUENCER_64, 0x1 }, - { WM8996_WRITE_SEQUENCER_65, 0x1 }, - { WM8996_WRITE_SEQUENCER_67, 0x6 }, - { WM8996_WRITE_SEQUENCER_68, 0x40 }, - { WM8996_WRITE_SEQUENCER_69, 0x1 }, - { WM8996_WRITE_SEQUENCER_70, 0xf }, - { WM8996_WRITE_SEQUENCER_71, 0x6 }, - { WM8996_WRITE_SEQUENCER_72, 0x1 }, - { WM8996_WRITE_SEQUENCER_73, 0x3 }, - { WM8996_WRITE_SEQUENCER_74, 0x104 }, - { WM8996_WRITE_SEQUENCER_76, 0x60 }, - { WM8996_WRITE_SEQUENCER_77, 0x11 }, - { WM8996_WRITE_SEQUENCER_78, 0x401 }, - { WM8996_WRITE_SEQUENCER_80, 0x50 }, - { WM8996_WRITE_SEQUENCER_81, 0x3 }, - { WM8996_WRITE_SEQUENCER_82, 0x100 }, - { WM8996_WRITE_SEQUENCER_84, 0x60 }, - { WM8996_WRITE_SEQUENCER_85, 0x3b }, - { WM8996_WRITE_SEQUENCER_86, 0x502 }, - { WM8996_WRITE_SEQUENCER_87, 0x100 }, - { WM8996_WRITE_SEQUENCER_88, 0x2fff }, - { WM8996_WRITE_SEQUENCER_92, 0x2fff }, - { WM8996_WRITE_SEQUENCER_96, 0x2fff }, - { WM8996_WRITE_SEQUENCER_100, 0x2fff }, - { WM8996_WRITE_SEQUENCER_104, 0x2fff }, - { WM8996_WRITE_SEQUENCER_108, 0x2fff }, - { WM8996_WRITE_SEQUENCER_112, 0x2fff }, - { WM8996_WRITE_SEQUENCER_116, 0x2fff }, - { WM8996_WRITE_SEQUENCER_120, 0x2fff }, - { WM8996_WRITE_SEQUENCER_124, 0x2fff }, - { WM8996_WRITE_SEQUENCER_128, 0x1 }, - { WM8996_WRITE_SEQUENCER_129, 0x1 }, - { WM8996_WRITE_SEQUENCER_131, 0x6 }, - { WM8996_WRITE_SEQUENCER_132, 0x40 }, - { WM8996_WRITE_SEQUENCER_133, 0x1 }, - { WM8996_WRITE_SEQUENCER_134, 0xf }, - { WM8996_WRITE_SEQUENCER_135, 0x6 }, - { WM8996_WRITE_SEQUENCER_136, 0x1 }, - { WM8996_WRITE_SEQUENCER_137, 0x3 }, - { WM8996_WRITE_SEQUENCER_138, 0x106 }, - { WM8996_WRITE_SEQUENCER_140, 0x61 }, - { WM8996_WRITE_SEQUENCER_141, 0x11 }, - { WM8996_WRITE_SEQUENCER_142, 0x401 }, - { WM8996_WRITE_SEQUENCER_144, 0x50 }, - { WM8996_WRITE_SEQUENCER_145, 0x3 }, - { WM8996_WRITE_SEQUENCER_146, 0x102 }, - { WM8996_WRITE_SEQUENCER_148, 0x51 }, - { WM8996_WRITE_SEQUENCER_149, 0x3 }, - { WM8996_WRITE_SEQUENCER_150, 0x106 }, - { WM8996_WRITE_SEQUENCER_151, 0xa }, - { WM8996_WRITE_SEQUENCER_152, 0x61 }, - { WM8996_WRITE_SEQUENCER_153, 0x3b }, - { WM8996_WRITE_SEQUENCER_154, 0x502 }, - { WM8996_WRITE_SEQUENCER_155, 0x100 }, - { WM8996_WRITE_SEQUENCER_156, 0x2fff }, - { WM8996_WRITE_SEQUENCER_160, 0x2fff }, - { WM8996_WRITE_SEQUENCER_164, 0x2fff }, - { WM8996_WRITE_SEQUENCER_168, 0x2fff }, - { WM8996_WRITE_SEQUENCER_172, 0x2fff }, - { WM8996_WRITE_SEQUENCER_176, 0x2fff }, - { WM8996_WRITE_SEQUENCER_180, 0x2fff }, - { WM8996_WRITE_SEQUENCER_184, 0x2fff }, - { WM8996_WRITE_SEQUENCER_188, 0x2fff }, - { WM8996_WRITE_SEQUENCER_192, 0x1 }, - { WM8996_WRITE_SEQUENCER_193, 0x1 }, - { WM8996_WRITE_SEQUENCER_195, 0x6 }, - { WM8996_WRITE_SEQUENCER_196, 0x40 }, - { WM8996_WRITE_SEQUENCER_197, 0x1 }, - { WM8996_WRITE_SEQUENCER_198, 0xf }, - { WM8996_WRITE_SEQUENCER_199, 0x6 }, - { WM8996_WRITE_SEQUENCER_200, 0x1 }, - { WM8996_WRITE_SEQUENCER_201, 0x3 }, - { WM8996_WRITE_SEQUENCER_202, 0x106 }, - { WM8996_WRITE_SEQUENCER_204, 0x61 }, - { WM8996_WRITE_SEQUENCER_205, 0x11 }, - { WM8996_WRITE_SEQUENCER_206, 0x401 }, - { WM8996_WRITE_SEQUENCER_208, 0x50 }, - { WM8996_WRITE_SEQUENCER_209, 0x3 }, - { WM8996_WRITE_SEQUENCER_210, 0x102 }, - { WM8996_WRITE_SEQUENCER_212, 0x61 }, - { WM8996_WRITE_SEQUENCER_213, 0x3b }, - { WM8996_WRITE_SEQUENCER_214, 0x502 }, - { WM8996_WRITE_SEQUENCER_215, 0x100 }, - { WM8996_WRITE_SEQUENCER_216, 0x2fff }, - { WM8996_WRITE_SEQUENCER_220, 0x2fff }, - { WM8996_WRITE_SEQUENCER_224, 0x2fff }, - { WM8996_WRITE_SEQUENCER_228, 0x2fff }, - { WM8996_WRITE_SEQUENCER_232, 0x2fff }, - { WM8996_WRITE_SEQUENCER_236, 0x2fff }, - { WM8996_WRITE_SEQUENCER_240, 0x2fff }, - { WM8996_WRITE_SEQUENCER_244, 0x2fff }, - { WM8996_WRITE_SEQUENCER_248, 0x2fff }, - { WM8996_WRITE_SEQUENCER_252, 0x2fff }, - { WM8996_WRITE_SEQUENCER_256, 0x60 }, - { WM8996_WRITE_SEQUENCER_258, 0x601 }, - { WM8996_WRITE_SEQUENCER_260, 0x50 }, - { WM8996_WRITE_SEQUENCER_262, 0x100 }, - { WM8996_WRITE_SEQUENCER_264, 0x1 }, - { WM8996_WRITE_SEQUENCER_266, 0x104 }, - { WM8996_WRITE_SEQUENCER_267, 0x100 }, - { WM8996_WRITE_SEQUENCER_268, 0x2fff }, - { WM8996_WRITE_SEQUENCER_272, 0x2fff }, - { WM8996_WRITE_SEQUENCER_276, 0x2fff }, - { WM8996_WRITE_SEQUENCER_280, 0x2fff }, - { WM8996_WRITE_SEQUENCER_284, 0x2fff }, - { WM8996_WRITE_SEQUENCER_288, 0x2fff }, - { WM8996_WRITE_SEQUENCER_292, 0x2fff }, - { WM8996_WRITE_SEQUENCER_296, 0x2fff }, - { WM8996_WRITE_SEQUENCER_300, 0x2fff }, - { WM8996_WRITE_SEQUENCER_304, 0x2fff }, - { WM8996_WRITE_SEQUENCER_308, 0x2fff }, - { WM8996_WRITE_SEQUENCER_312, 0x2fff }, - { WM8996_WRITE_SEQUENCER_316, 0x2fff }, - { WM8996_WRITE_SEQUENCER_320, 0x61 }, - { WM8996_WRITE_SEQUENCER_322, 0x601 }, - { WM8996_WRITE_SEQUENCER_324, 0x50 }, - { WM8996_WRITE_SEQUENCER_326, 0x102 }, - { WM8996_WRITE_SEQUENCER_328, 0x1 }, - { WM8996_WRITE_SEQUENCER_330, 0x106 }, - { WM8996_WRITE_SEQUENCER_331, 0x100 }, - { WM8996_WRITE_SEQUENCER_332, 0x2fff }, - { WM8996_WRITE_SEQUENCER_336, 0x2fff }, - { WM8996_WRITE_SEQUENCER_340, 0x2fff }, - { WM8996_WRITE_SEQUENCER_344, 0x2fff }, - { WM8996_WRITE_SEQUENCER_348, 0x2fff }, - { WM8996_WRITE_SEQUENCER_352, 0x2fff }, - { WM8996_WRITE_SEQUENCER_356, 0x2fff }, - { WM8996_WRITE_SEQUENCER_360, 0x2fff }, - { WM8996_WRITE_SEQUENCER_364, 0x2fff }, - { WM8996_WRITE_SEQUENCER_368, 0x2fff }, - { WM8996_WRITE_SEQUENCER_372, 0x2fff }, - { WM8996_WRITE_SEQUENCER_376, 0x2fff }, - { WM8996_WRITE_SEQUENCER_380, 0x2fff }, - { WM8996_WRITE_SEQUENCER_384, 0x60 }, - { WM8996_WRITE_SEQUENCER_386, 0x601 }, - { WM8996_WRITE_SEQUENCER_388, 0x61 }, - { WM8996_WRITE_SEQUENCER_390, 0x601 }, - { WM8996_WRITE_SEQUENCER_392, 0x50 }, - { WM8996_WRITE_SEQUENCER_394, 0x300 }, - { WM8996_WRITE_SEQUENCER_396, 0x1 }, - { WM8996_WRITE_SEQUENCER_398, 0x304 }, - { WM8996_WRITE_SEQUENCER_400, 0x40 }, - { WM8996_WRITE_SEQUENCER_402, 0xf }, - { WM8996_WRITE_SEQUENCER_404, 0x1 }, - { WM8996_WRITE_SEQUENCER_407, 0x100 }, }; static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); -- GitLab From af691fb62c626fe374955ab306092b09f672e27d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:20:48 +0800 Subject: [PATCH 1064/6849] ASoC: wm8996: Convert to devm_regmap_init_i2c() Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index f24989f090ca..a6b5cffa498a 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -3000,7 +3000,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, msleep(5); } - wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); + wm8996->regmap = devm_regmap_init_i2c(i2c, &wm8996_regmap); if (IS_ERR(wm8996->regmap)) { ret = PTR_ERR(wm8996->regmap); dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); @@ -3049,7 +3049,6 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, err_gpiolib: wm8996_free_gpio(wm8996); err_regmap: - regmap_exit(wm8996->regmap); err_enable: if (wm8996->pdata.ldo_ena > 0) gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); @@ -3068,7 +3067,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); wm8996_free_gpio(wm8996); - regmap_exit(wm8996->regmap); if (wm8996->pdata.ldo_ena > 0) { gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); gpio_free(wm8996->pdata.ldo_ena); -- GitLab From 48e278746070b5fc62ec3da2e65f7cd511f6bbf4 Mon Sep 17 00:00:00 2001 From: Adam Thomson Date: Mon, 11 Jun 2012 13:15:27 +0100 Subject: [PATCH 1065/6849] ASoC: codecs: Add DA732x codec driver This patch adds support for Dialog DA732x audio codecs. Signed-off-by: Michal Hajduk Signed-off-by: Adam Thomson Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/da732x.c | 1627 +++++++++++++++++++++++++++++++++ sound/soc/codecs/da732x.h | 133 +++ sound/soc/codecs/da732x_reg.h | 654 +++++++++++++ 5 files changed, 2420 insertions(+) create mode 100644 sound/soc/codecs/da732x.c create mode 100644 sound/soc/codecs/da732x.h create mode 100644 sound/soc/codecs/da732x_reg.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f63776d422b3..43f5240e6942 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI select SND_SOC_CX20442 select SND_SOC_DA7210 if I2C + select SND_SOC_DA732X if I2C select SND_SOC_DFBMCS320 select SND_SOC_ISABELLE if I2C select SND_SOC_JZ4740_CODEC @@ -224,6 +225,9 @@ config SND_SOC_L3 config SND_SOC_DA7210 tristate +config SND_SOC_DA732X + tristate + config SND_SOC_DFBMCS320 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index fc93b4b0c2c5..3d30654f6fcc 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -22,6 +22,7 @@ snd-soc-cs4270-objs := cs4270.o snd-soc-cs4271-objs := cs4271.o snd-soc-cx20442-objs := cx20442.o snd-soc-da7210-objs := da7210.o +snd-soc-da732x-objs := da732x.o snd-soc-dfbmcs320-objs := dfbmcs320.o snd-soc-dmic-objs := dmic.o snd-soc-isabelle-objs := isabelle.o @@ -135,6 +136,7 @@ obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o +obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c new file mode 100644 index 000000000000..04af369f228c --- /dev/null +++ b/sound/soc/codecs/da732x.c @@ -0,0 +1,1627 @@ +/* + * da732x.c --- Dialog DA732X ALSA SoC Audio Driver + * + * Copyright (C) 2012 Dialog Semiconductor GmbH + * + * Author: Michal Hajduk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "da732x.h" +#include "da732x_reg.h" + + +struct da732x_priv { + struct regmap *regmap; + struct snd_soc_codec *codec; + + unsigned int sysclk; + bool pll_en; +}; + +/* + * da732x register cache - default settings + */ +static struct reg_default da732x_reg_cache[] = { + { DA732X_REG_REF1 , 0x02 }, + { DA732X_REG_BIAS_EN , 0x80 }, + { DA732X_REG_BIAS1 , 0x00 }, + { DA732X_REG_BIAS2 , 0x00 }, + { DA732X_REG_BIAS3 , 0x00 }, + { DA732X_REG_BIAS4 , 0x00 }, + { DA732X_REG_MICBIAS2 , 0x00 }, + { DA732X_REG_MICBIAS1 , 0x00 }, + { DA732X_REG_MICDET , 0x00 }, + { DA732X_REG_MIC1_PRE , 0x01 }, + { DA732X_REG_MIC1 , 0x40 }, + { DA732X_REG_MIC2_PRE , 0x01 }, + { DA732X_REG_MIC2 , 0x40 }, + { DA732X_REG_AUX1L , 0x75 }, + { DA732X_REG_AUX1R , 0x75 }, + { DA732X_REG_MIC3_PRE , 0x01 }, + { DA732X_REG_MIC3 , 0x40 }, + { DA732X_REG_INP_PINBIAS , 0x00 }, + { DA732X_REG_INP_ZC_EN , 0x00 }, + { DA732X_REG_INP_MUX , 0x50 }, + { DA732X_REG_HP_DET , 0x00 }, + { DA732X_REG_HPL_DAC_OFFSET , 0x00 }, + { DA732X_REG_HPL_DAC_OFF_CNTL , 0x00 }, + { DA732X_REG_HPL_OUT_OFFSET , 0x00 }, + { DA732X_REG_HPL , 0x40 }, + { DA732X_REG_HPL_VOL , 0x0F }, + { DA732X_REG_HPR_DAC_OFFSET , 0x00 }, + { DA732X_REG_HPR_DAC_OFF_CNTL , 0x00 }, + { DA732X_REG_HPR_OUT_OFFSET , 0x00 }, + { DA732X_REG_HPR , 0x40 }, + { DA732X_REG_HPR_VOL , 0x0F }, + { DA732X_REG_LIN2 , 0x4F }, + { DA732X_REG_LIN3 , 0x4F }, + { DA732X_REG_LIN4 , 0x4F }, + { DA732X_REG_OUT_ZC_EN , 0x00 }, + { DA732X_REG_HP_LIN1_GNDSEL , 0x00 }, + { DA732X_REG_CP_HP1 , 0x0C }, + { DA732X_REG_CP_HP2 , 0x03 }, + { DA732X_REG_CP_CTRL1 , 0x00 }, + { DA732X_REG_CP_CTRL2 , 0x99 }, + { DA732X_REG_CP_CTRL3 , 0x25 }, + { DA732X_REG_CP_LEVEL_MASK , 0x3F }, + { DA732X_REG_CP_DET , 0x00 }, + { DA732X_REG_CP_STATUS , 0x00 }, + { DA732X_REG_CP_THRESH1 , 0x00 }, + { DA732X_REG_CP_THRESH2 , 0x00 }, + { DA732X_REG_CP_THRESH3 , 0x00 }, + { DA732X_REG_CP_THRESH4 , 0x00 }, + { DA732X_REG_CP_THRESH5 , 0x00 }, + { DA732X_REG_CP_THRESH6 , 0x00 }, + { DA732X_REG_CP_THRESH7 , 0x00 }, + { DA732X_REG_CP_THRESH8 , 0x00 }, + { DA732X_REG_PLL_DIV_LO , 0x00 }, + { DA732X_REG_PLL_DIV_MID , 0x00 }, + { DA732X_REG_PLL_DIV_HI , 0x00 }, + { DA732X_REG_PLL_CTRL , 0x02 }, + { DA732X_REG_CLK_CTRL , 0xaa }, + { DA732X_REG_CLK_DSP , 0x07 }, + { DA732X_REG_CLK_EN1 , 0x00 }, + { DA732X_REG_CLK_EN2 , 0x00 }, + { DA732X_REG_CLK_EN3 , 0x00 }, + { DA732X_REG_CLK_EN4 , 0x00 }, + { DA732X_REG_CLK_EN5 , 0x00 }, + { DA732X_REG_AIF_MCLK , 0x00 }, + { DA732X_REG_AIFA1 , 0x02 }, + { DA732X_REG_AIFA2 , 0x00 }, + { DA732X_REG_AIFA3 , 0x08 }, + { DA732X_REG_AIFB1 , 0x02 }, + { DA732X_REG_AIFB2 , 0x00 }, + { DA732X_REG_AIFB3 , 0x08 }, + { DA732X_REG_PC_CTRL , 0xC0 }, + { DA732X_REG_DATA_ROUTE , 0x00 }, + { DA732X_REG_DSP_CTRL , 0x00 }, + { DA732X_REG_CIF_CTRL2 , 0x00 }, + { DA732X_REG_HANDSHAKE , 0x00 }, + { DA732X_REG_SPARE1_OUT , 0x00 }, + { DA732X_REG_SPARE2_OUT , 0x00 }, + { DA732X_REG_SPARE1_IN , 0x00 }, + { DA732X_REG_ADC1_PD , 0x00 }, + { DA732X_REG_ADC1_HPF , 0x00 }, + { DA732X_REG_ADC1_SEL , 0x00 }, + { DA732X_REG_ADC1_EQ12 , 0x00 }, + { DA732X_REG_ADC1_EQ34 , 0x00 }, + { DA732X_REG_ADC1_EQ5 , 0x00 }, + { DA732X_REG_ADC2_PD , 0x00 }, + { DA732X_REG_ADC2_HPF , 0x00 }, + { DA732X_REG_ADC2_SEL , 0x00 }, + { DA732X_REG_ADC2_EQ12 , 0x00 }, + { DA732X_REG_ADC2_EQ34 , 0x00 }, + { DA732X_REG_ADC2_EQ5 , 0x00 }, + { DA732X_REG_DAC1_HPF , 0x00 }, + { DA732X_REG_DAC1_L_VOL , 0x00 }, + { DA732X_REG_DAC1_R_VOL , 0x00 }, + { DA732X_REG_DAC1_SEL , 0x00 }, + { DA732X_REG_DAC1_SOFTMUTE , 0x00 }, + { DA732X_REG_DAC1_EQ12 , 0x00 }, + { DA732X_REG_DAC1_EQ34 , 0x00 }, + { DA732X_REG_DAC1_EQ5 , 0x00 }, + { DA732X_REG_DAC2_HPF , 0x00 }, + { DA732X_REG_DAC2_L_VOL , 0x00 }, + { DA732X_REG_DAC2_R_VOL , 0x00 }, + { DA732X_REG_DAC2_SEL , 0x00 }, + { DA732X_REG_DAC2_SOFTMUTE , 0x00 }, + { DA732X_REG_DAC2_EQ12 , 0x00 }, + { DA732X_REG_DAC2_EQ34 , 0x00 }, + { DA732X_REG_DAC2_EQ5 , 0x00 }, + { DA732X_REG_DAC3_HPF , 0x00 }, + { DA732X_REG_DAC3_VOL , 0x00 }, + { DA732X_REG_DAC3_SEL , 0x00 }, + { DA732X_REG_DAC3_SOFTMUTE , 0x00 }, + { DA732X_REG_DAC3_EQ12 , 0x00 }, + { DA732X_REG_DAC3_EQ34 , 0x00 }, + { DA732X_REG_DAC3_EQ5 , 0x00 }, + { DA732X_REG_BIQ_BYP , 0x00 }, + { DA732X_REG_DMA_CMD , 0x00 }, + { DA732X_REG_DMA_ADDR0 , 0x00 }, + { DA732X_REG_DMA_ADDR1 , 0x00 }, + { DA732X_REG_DMA_DATA0 , 0x00 }, + { DA732X_REG_DMA_DATA1 , 0x00 }, + { DA732X_REG_DMA_DATA2 , 0x00 }, + { DA732X_REG_DMA_DATA3 , 0x00 }, + { DA732X_REG_UNLOCK , 0x00 }, +}; + +static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk) +{ + int val; + int ret; + + if (sysclk < DA732X_MCLK_10MHZ) { + val = DA732X_MCLK_RET_0_10MHZ; + ret = DA732X_MCLK_VAL_0_10MHZ; + } else if ((sysclk >= DA732X_MCLK_10MHZ) && + (sysclk < DA732X_MCLK_20MHZ)) { + val = DA732X_MCLK_RET_10_20MHZ; + ret = DA732X_MCLK_VAL_10_20MHZ; + } else if ((sysclk >= DA732X_MCLK_20MHZ) && + (sysclk < DA732X_MCLK_40MHZ)) { + val = DA732X_MCLK_RET_20_40MHZ; + ret = DA732X_MCLK_VAL_20_40MHZ; + } else if ((sysclk >= DA732X_MCLK_40MHZ) && + (sysclk <= DA732X_MCLK_54MHZ)) { + val = DA732X_MCLK_RET_40_54MHZ; + ret = DA732X_MCLK_VAL_40_54MHZ; + } else { + return -EINVAL; + } + + snd_soc_write(codec, DA732X_REG_PLL_CTRL, val); + + return ret; +} + +static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state) +{ + switch (state) { + case DA732X_ENABLE_CP: + snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN); + snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN | + DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP); + snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN | + DA732X_CP_CTRL_CPVDD1); + snd_soc_write(codec, DA732X_REG_CP_CTRL2, + DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST); + snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ); + break; + case DA732X_DISABLE_CP: + snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS); + snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS); + snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS); + break; + default: + pr_err(KERN_ERR "Wrong charge pump state\n"); + break; + } +} + +static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN, + DA732X_MIC_PRE_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN, + DA732X_MIC_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN, + DA732X_AUX_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN, + DA732X_AUX_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN, + DA732X_LIN2_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN, + DA732X_LIN3_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN, + DA732X_LIN4_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN, + DA732X_ADC_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN, + DA732X_DAC_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN, + DA732X_EQ_BAND_VOL_DB_INC, 0); + +static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN, + DA732X_EQ_OVERALL_VOL_DB_INC, 0); + +/* High Pass Filter */ +static const char *da732x_hpf_mode[] = { + "Disable", "Music", "Voice", +}; + +static const char *da732x_hpf_music[] = { + "1.8Hz", "3.75Hz", "7.5Hz", "15Hz", +}; + +static const char *da732x_hpf_voice[] = { + "2.5Hz", "25Hz", "50Hz", "100Hz", + "150Hz", "200Hz", "300Hz", "400Hz" +}; + +static const struct soc_enum da732x_dac1_hpf_mode_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, + DA732X_HPF_MODE_MAX, da732x_hpf_mode) +}; + +static const struct soc_enum da732x_dac2_hpf_mode_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, + DA732X_HPF_MODE_MAX, da732x_hpf_mode) +}; + +static const struct soc_enum da732x_dac3_hpf_mode_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, + DA732X_HPF_MODE_MAX, da732x_hpf_mode) +}; + +static const struct soc_enum da732x_adc1_hpf_mode_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, + DA732X_HPF_MODE_MAX, da732x_hpf_mode) +}; + +static const struct soc_enum da732x_adc2_hpf_mode_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, + DA732X_HPF_MODE_MAX, da732x_hpf_mode) +}; + +static const struct soc_enum da732x_dac1_hp_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, + DA732X_HPF_MUSIC_MAX, da732x_hpf_music) +}; + +static const struct soc_enum da732x_dac2_hp_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, + DA732X_HPF_MUSIC_MAX, da732x_hpf_music) +}; + +static const struct soc_enum da732x_dac3_hp_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, + DA732X_HPF_MUSIC_MAX, da732x_hpf_music) +}; + +static const struct soc_enum da732x_adc1_hp_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, + DA732X_HPF_MUSIC_MAX, da732x_hpf_music) +}; + +static const struct soc_enum da732x_adc2_hp_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, + DA732X_HPF_MUSIC_MAX, da732x_hpf_music) +}; + +static const struct soc_enum da732x_dac1_voice_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, + DA732X_HPF_VOICE_MAX, da732x_hpf_voice) +}; + +static const struct soc_enum da732x_dac2_voice_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, + DA732X_HPF_VOICE_MAX, da732x_hpf_voice) +}; + +static const struct soc_enum da732x_dac3_voice_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, + DA732X_HPF_VOICE_MAX, da732x_hpf_voice) +}; + +static const struct soc_enum da732x_adc1_voice_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, + DA732X_HPF_VOICE_MAX, da732x_hpf_voice) +}; + +static const struct soc_enum da732x_adc2_voice_filter_enum[] = { + SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, + DA732X_HPF_VOICE_MAX, da732x_hpf_voice) +}; + + +static int da732x_hpf_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; + unsigned int reg = enum_ctrl->reg; + unsigned int sel = ucontrol->value.integer.value[0]; + unsigned int bits; + + switch (sel) { + case DA732X_HPF_DISABLED: + bits = DA732X_HPF_DIS; + break; + case DA732X_HPF_VOICE: + bits = DA732X_HPF_VOICE_EN; + break; + case DA732X_HPF_MUSIC: + bits = DA732X_HPF_MUSIC_EN; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits); + + return 0; +} + +static int da732x_hpf_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; + unsigned int reg = enum_ctrl->reg; + int val; + + val = snd_soc_read(codec, reg) & DA732X_HPF_MASK; + + switch (val) { + case DA732X_HPF_VOICE_EN: + ucontrol->value.integer.value[0] = DA732X_HPF_VOICE; + break; + case DA732X_HPF_MUSIC_EN: + ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC; + break; + default: + ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED; + break; + } + + return 0; +} + +static const struct snd_kcontrol_new da732x_snd_controls[] = { + /* Input PGAs */ + SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE, + DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, + DA732X_MICBOOST_MAX, 0, mic_boost_tlv), + SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE, + DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, + DA732X_MICBOOST_MAX, 0, mic_boost_tlv), + SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE, + DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, + DA732X_MICBOOST_MAX, 0, mic_boost_tlv), + + /* MICs */ + SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1, + DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, + DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), + SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2, + DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, + DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), + SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3, + DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, + DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), + + /* AUXs */ + SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L, + DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, + DA732X_NO_INVERT, aux_pga_tlv), + SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R, + DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, + DA732X_NO_INVERT, aux_pga_tlv), + + /* ADCs */ + SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL, + DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, + DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), + + SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL, + DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, + DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), + + /* DACs */ + SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL, + DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL, + DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT, + DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv), + SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL, + DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL, + DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, + DA732X_INVERT, dac_pga_tlv), + SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL, + DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL, + DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, + DA732X_INVERT, dac_pga_tlv), + SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL, + DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL, + DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, + DA732X_INVERT, dac_pga_tlv), + + /* High Pass Filters */ + SOC_ENUM_EXT("DAC1 High Pass Filter Mode", + da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), + SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum), + SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum), + + SOC_ENUM_EXT("DAC2 High Pass Filter Mode", + da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), + SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum), + SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum), + + SOC_ENUM_EXT("DAC3 High Pass Filter Mode", + da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), + SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum), + SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum), + + SOC_ENUM_EXT("ADC1 High Pass Filter Mode", + da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), + SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum), + SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum), + + SOC_ENUM_EXT("ADC2 High Pass Filter Mode", + da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), + SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum), + SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum), + + /* Equalizers */ + SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5, + DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), + SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12, + DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12, + DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34, + DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34, + DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5, + DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5, + DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, + DA732X_INVERT, eq_overall_tlv), + + SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5, + DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), + SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12, + DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12, + DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34, + DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34, + DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5, + DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5, + DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, + DA732X_INVERT, eq_overall_tlv), + + SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5, + DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), + SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12, + DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12, + DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34, + DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34, + DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5, + DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + + SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5, + DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), + SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12, + DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12, + DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34, + DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34, + DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5, + DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + + SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5, + DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), + SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12, + DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12, + DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34, + DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34, + DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5, + DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, + DA732X_INVERT, eq_band_pga_tlv), + + /* Lineout 2 Reciever*/ + SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2, + DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, + DA732X_NO_INVERT, lin2_pga_tlv), + + /* Lineout 3 SPEAKER*/ + SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3, + DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, + DA732X_NO_INVERT, lin3_pga_tlv), + + /* Lineout 4 */ + SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT, + DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4, + DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, + DA732X_NO_INVERT, lin4_pga_tlv), + + /* Headphones */ + SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL, + DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), + SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL, + DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT, + DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv), +}; + +static int da732x_adc_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + switch (w->reg) { + case DA732X_REG_ADC1_PD: + snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, + DA732X_ADCA_BB_CLK_EN, + DA732X_ADCA_BB_CLK_EN); + break; + case DA732X_REG_ADC2_PD: + snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, + DA732X_ADCC_BB_CLK_EN, + DA732X_ADCC_BB_CLK_EN); + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, + DA732X_ADC_SET_ACT); + snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, + DA732X_ADC_ON); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, + DA732X_ADC_OFF); + snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, + DA732X_ADC_SET_RST); + + switch (w->reg) { + case DA732X_REG_ADC1_PD: + snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, + DA732X_ADCA_BB_CLK_EN, 0); + break; + case DA732X_REG_ADC2_PD: + snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, + DA732X_ADCC_BB_CLK_EN, 0); + break; + default: + return -EINVAL; + } + + break; + default: + return -EINVAL; + } + + return 0; +} + +static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, w->reg, + (1 << w->shift) | DA732X_OUT_HIZ_EN, + (1 << w->shift) | DA732X_OUT_HIZ_EN); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, w->reg, + (1 << w->shift) | DA732X_OUT_HIZ_EN, + (1 << w->shift) | DA732X_OUT_HIZ_DIS); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const char *adcl_text[] = { + "AUX1L", "MIC1" +}; + +static const char *adcr_text[] = { + "AUX1R", "MIC2", "MIC3" +}; + +static const char *enable_text[] = { + "Disabled", + "Enabled" +}; + +/* ADC1LMUX */ +static const struct soc_enum adc1l_enum = + SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, + DA732X_ADCL_MUX_MAX, adcl_text); +static const struct snd_kcontrol_new adc1l_mux = + SOC_DAPM_ENUM("ADC Route", adc1l_enum); + +/* ADC1RMUX */ +static const struct soc_enum adc1r_enum = + SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, + DA732X_ADCR_MUX_MAX, adcr_text); +static const struct snd_kcontrol_new adc1r_mux = + SOC_DAPM_ENUM("ADC Route", adc1r_enum); + +/* ADC2LMUX */ +static const struct soc_enum adc2l_enum = + SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, + DA732X_ADCL_MUX_MAX, adcl_text); +static const struct snd_kcontrol_new adc2l_mux = + SOC_DAPM_ENUM("ADC Route", adc2l_enum); + +/* ADC2RMUX */ +static const struct soc_enum adc2r_enum = + SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, + DA732X_ADCR_MUX_MAX, adcr_text); + +static const struct snd_kcontrol_new adc2r_mux = + SOC_DAPM_ENUM("ADC Route", adc2r_enum); + +static const struct soc_enum da732x_hp_left_output = + SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, + DA732X_DAC_EN_MAX, enable_text); + +static const struct snd_kcontrol_new hpl_mux = + SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); + +static const struct soc_enum da732x_hp_right_output = + SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, + DA732X_DAC_EN_MAX, enable_text); + +static const struct snd_kcontrol_new hpr_mux = + SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); + +static const struct soc_enum da732x_speaker_output = + SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, + DA732X_DAC_EN_MAX, enable_text); + +static const struct snd_kcontrol_new spk_mux = + SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); + +static const struct soc_enum da732x_lout4_output = + SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, + DA732X_DAC_EN_MAX, enable_text); + +static const struct snd_kcontrol_new lout4_mux = + SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); + +static const struct soc_enum da732x_lout2_output = + SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, + DA732X_DAC_EN_MAX, enable_text); + +static const struct snd_kcontrol_new lout2_mux = + SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); + +static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { + /* Supplies */ + SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0, + DA732X_NO_INVERT, da732x_adc_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0, + DA732X_NO_INVERT, da732x_adc_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4, + DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT, + NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4, + DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT, + NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5, + DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT, + NULL, 0), + + /* Micbias */ + SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1, + DA732X_MICBIAS_EN_SHIFT, + DA732X_NO_INVERT, NULL, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2, + DA732X_MICBIAS_EN_SHIFT, + DA732X_NO_INVERT, NULL, 0), + + /* Inputs */ + SND_SOC_DAPM_INPUT("MIC1"), + SND_SOC_DAPM_INPUT("MIC2"), + SND_SOC_DAPM_INPUT("MIC3"), + SND_SOC_DAPM_INPUT("AUX1L"), + SND_SOC_DAPM_INPUT("AUX1R"), + + /* Outputs */ + SND_SOC_DAPM_OUTPUT("HPL"), + SND_SOC_DAPM_OUTPUT("HPR"), + SND_SOC_DAPM_OUTPUT("LOUTL"), + SND_SOC_DAPM_OUTPUT("LOUTR"), + SND_SOC_DAPM_OUTPUT("ClassD"), + + /* ADCs */ + SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL, + DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL, + DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL, + DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL, + DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), + + /* DACs */ + SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL, + DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL, + DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL, + DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL, + DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), + SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL, + DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), + + /* Input Pgas */ + SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT, + 0, NULL, 0), + SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT, + 0, NULL, 0), + SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT, + 0, NULL, 0), + SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT, + 0, NULL, 0), + SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT, + 0, NULL, 0), + + SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT, + 0, NULL, 0, da732x_out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT, + 0, NULL, 0, da732x_out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT, + 0, NULL, 0, da732x_out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT, + 0, NULL, 0, da732x_out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT, + 0, NULL, 0, da732x_out_pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* MUXs */ + SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux), + SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux), + SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux), + SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux), + + SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux), + SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux), + SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux), + SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux), + SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux), + + /* AIF interfaces */ + SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3, + DA732X_AIF_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3, + DA732X_AIF_EN_SHIFT, 0), + + SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3, + DA732X_AIF_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3, + DA732X_AIF_EN_SHIFT, 0), +}; + +static const struct snd_soc_dapm_route da732x_dapm_routes[] = { + /* Inputs */ + {"AUX1L PGA", "NULL", "AUX1L"}, + {"AUX1R PGA", "NULL", "AUX1R"}, + {"MIC1 PGA", NULL, "MIC1"}, + {"MIC2 PGA", "NULL", "MIC2"}, + {"MIC3 PGA", "NULL", "MIC3"}, + + /* Capture Path */ + {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, + {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"}, + + {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"}, + {"ADC1 Right MUX", "MIC2", "MIC2 PGA"}, + {"ADC1 Right MUX", "MIC3", "MIC3 PGA"}, + + {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"}, + {"ADC2 Left MUX", "MIC1", "MIC1 PGA"}, + + {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"}, + {"ADC2 Right MUX", "MIC2", "MIC2 PGA"}, + {"ADC2 Right MUX", "MIC3", "MIC3 PGA"}, + + {"ADC1L", NULL, "ADC1 Supply"}, + {"ADC1R", NULL, "ADC1 Supply"}, + {"ADC2L", NULL, "ADC2 Supply"}, + {"ADC2R", NULL, "ADC2 Supply"}, + + {"ADC1L", NULL, "ADC1 Left MUX"}, + {"ADC1R", NULL, "ADC1 Right MUX"}, + {"ADC2L", NULL, "ADC2 Left MUX"}, + {"ADC2R", NULL, "ADC2 Right MUX"}, + + {"AIFA Output", NULL, "ADC1L"}, + {"AIFA Output", NULL, "ADC1R"}, + {"AIFB Output", NULL, "ADC2L"}, + {"AIFB Output", NULL, "ADC2R"}, + + {"HP Left MUX", "Enabled", "AIFA Input"}, + {"HP Right MUX", "Enabled", "AIFA Input"}, + {"Speaker MUX", "Enabled", "AIFB Input"}, + {"LOUT2 MUX", "Enabled", "AIFB Input"}, + {"LOUT4 MUX", "Enabled", "AIFB Input"}, + + {"DAC1L", NULL, "DAC1 CLK"}, + {"DAC1R", NULL, "DAC1 CLK"}, + {"DAC2L", NULL, "DAC2 CLK"}, + {"DAC2R", NULL, "DAC2 CLK"}, + {"DAC3", NULL, "DAC3 CLK"}, + + {"DAC1L", NULL, "HP Left MUX"}, + {"DAC1R", NULL, "HP Right MUX"}, + {"DAC2L", NULL, "Speaker MUX"}, + {"DAC2R", NULL, "LOUT4 MUX"}, + {"DAC3", NULL, "LOUT2 MUX"}, + + /* Output Pgas */ + {"HP Left", NULL, "DAC1L"}, + {"HP Right", NULL, "DAC1R"}, + {"LIN3", NULL, "DAC2L"}, + {"LIN4", NULL, "DAC2R"}, + {"LIN2", NULL, "DAC3"}, + + /* Outputs */ + {"ClassD", NULL, "LIN3"}, + {"LOUTL", NULL, "LIN2"}, + {"LOUTR", NULL, "LIN4"}, + {"HPL", NULL, "HP Left"}, + {"HPR", NULL, "HP Right"}, +}; + +static int da732x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + u32 aif = 0; + u32 reg_aif; + u32 fs; + + reg_aif = dai->driver->base; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + aif |= DA732X_AIF_WORD_16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + aif |= DA732X_AIF_WORD_20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + aif |= DA732X_AIF_WORD_24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + aif |= DA732X_AIF_WORD_32; + break; + default: + return -EINVAL; + } + + switch (params_rate(params)) { + case 8000: + fs = DA732X_SR_8KHZ; + break; + case 11025: + fs = DA732X_SR_11_025KHZ; + break; + case 12000: + fs = DA732X_SR_12KHZ; + break; + case 16000: + fs = DA732X_SR_16KHZ; + break; + case 22050: + fs = DA732X_SR_22_05KHZ; + break; + case 24000: + fs = DA732X_SR_24KHZ; + break; + case 32000: + fs = DA732X_SR_32KHZ; + break; + case 44100: + fs = DA732X_SR_44_1KHZ; + break; + case 48000: + fs = DA732X_SR_48KHZ; + break; + case 88100: + fs = DA732X_SR_88_1KHZ; + break; + case 96000: + fs = DA732X_SR_96KHZ; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif); + snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs); + + return 0; +} + +static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt) +{ + struct snd_soc_codec *codec = dai->codec; + u32 aif_mclk, pc_count; + u32 reg_aif1, aif1; + u32 reg_aif3, aif3; + + switch (dai->id) { + case DA732X_DAI_ID1: + reg_aif1 = DA732X_REG_AIFA1; + reg_aif3 = DA732X_REG_AIFA3; + pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT | + DA732X_PC_SAME; + break; + case DA732X_DAI_ID2: + reg_aif1 = DA732X_REG_AIFB1; + reg_aif3 = DA732X_REG_AIFB3; + pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT | + DA732X_PC_SAME; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + aif1 = DA732X_AIF_SLAVE; + aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA; + break; + case SND_SOC_DAIFMT_CBM_CFM: + aif1 = DA732X_AIF_CLK_FROM_SRC; + aif_mclk = DA732X_CLK_GENERATION_AIF_A; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + aif3 = DA732X_AIF_I2S_MODE; + break; + case SND_SOC_DAIFMT_RIGHT_J: + aif3 = DA732X_AIF_RIGHT_J_MODE; + break; + case SND_SOC_DAIFMT_LEFT_J: + aif3 = DA732X_AIF_LEFT_J_MODE; + break; + case SND_SOC_DAIFMT_DSP_B: + aif3 = DA732X_AIF_DSP_MODE; + break; + default: + return -EINVAL; + } + + /* Clock inversion */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + aif3 |= DA732X_AIF_BCLK_INV; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + aif3 |= DA732X_AIF_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + aif3 |= DA732X_AIF_WCLK_INV; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk); + snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1); + snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV | + DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3); + snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count); + + return 0; +} + + + +static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id, + int source, unsigned int freq_in, + unsigned int freq_out) +{ + struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); + int fref, indiv; + u8 div_lo, div_mid, div_hi; + u64 frac_div; + + /* Disable PLL */ + if (freq_out == 0) { + snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, + DA732X_PLL_EN, 0); + da732x->pll_en = false; + return 0; + } + + if (da732x->pll_en) + return -EBUSY; + + if (source == DA732X_SRCCLK_MCLK) { + /* Validate Sysclk rate */ + switch (da732x->sysclk) { + case 11290000: + case 12288000: + case 22580000: + case 24576000: + case 45160000: + case 49152000: + snd_soc_write(codec, DA732X_REG_PLL_CTRL, + DA732X_PLL_BYPASS); + return 0; + default: + dev_err(codec->dev, + "Cannot use PLL Bypass, invalid SYSCLK rate\n"); + return -EINVAL; + } + } + + indiv = da732x_get_input_div(codec, da732x->sysclk); + if (indiv < 0) + return indiv; + + fref = (da732x->sysclk / indiv); + div_hi = freq_out / fref; + frac_div = (u64)(freq_out % fref) * 8192ULL; + do_div(frac_div, fref); + div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK; + div_lo = (frac_div) & DA732X_U8_MASK; + + snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo); + snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid); + snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi); + + snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN, + DA732X_PLL_EN); + + da732x->pll_en = true; + + return 0; +} + +static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); + + da732x->sysclk = freq; + + return 0; +} + +#define DA732X_RATES SNDRV_PCM_RATE_8000_96000 + +#define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops da732x_dai1_ops = { + .hw_params = da732x_hw_params, + .set_fmt = da732x_set_dai_fmt, + .set_sysclk = da732x_set_dai_sysclk, +}; + +static struct snd_soc_dai_ops da732x_dai2_ops = { + .hw_params = da732x_hw_params, + .set_fmt = da732x_set_dai_fmt, + .set_sysclk = da732x_set_dai_sysclk, +}; + +static struct snd_soc_dai_driver da732x_dai[] = { + { + .name = "DA732X_AIFA", + .id = DA732X_DAI_ID1, + .base = DA732X_REG_AIFA1, + .playback = { + .stream_name = "AIFA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = DA732X_RATES, + .formats = DA732X_FORMATS, + }, + .capture = { + .stream_name = "AIFA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = DA732X_RATES, + .formats = DA732X_FORMATS, + }, + .ops = &da732x_dai1_ops, + }, + { + .name = "DA732X_AIFB", + .id = DA732X_DAI_ID2, + .base = DA732X_REG_AIFB1, + .playback = { + .stream_name = "AIFB Playback", + .channels_min = 1, + .channels_max = 2, + .rates = DA732X_RATES, + .formats = DA732X_FORMATS, + }, + .capture = { + .stream_name = "AIFB Capture", + .channels_min = 1, + .channels_max = 2, + .rates = DA732X_RATES, + .formats = DA732X_FORMATS, + }, + .ops = &da732x_dai2_ops, + }, +}; + +static const struct regmap_config da732x_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = DA732X_MAX_REG, + .reg_defaults = da732x_reg_cache, + .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), + .cache_type = REGCACHE_RBTREE, +}; + + +static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) +{ + u8 offset[DA732X_HP_DACS]; + u8 sign[DA732X_HP_DACS]; + u8 step = DA732X_DAC_OFFSET_STEP; + + /* Initialize DAC offset calibration circuits and registers */ + snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, + DA732X_HP_DAC_OFFSET_TRIM_VAL); + snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, + DA732X_HP_DAC_OFFSET_TRIM_VAL); + snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, + DA732X_HP_DAC_OFF_CALIBRATION | + DA732X_HP_DAC_OFF_SCALE_STEPS); + snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, + DA732X_HP_DAC_OFF_CALIBRATION | + DA732X_HP_DAC_OFF_SCALE_STEPS); + + /* Wait for voltage stabilization */ + msleep(DA732X_WAIT_FOR_STABILIZATION); + + /* Check DAC offset sign */ + sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & + DA732X_HP_DAC_OFF_CNTL_COMPO); + sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & + DA732X_HP_DAC_OFF_CNTL_COMPO); + + /* Binary search DAC offset values (both channels at once) */ + offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT; + offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT; + + do { + offset[DA732X_HPL_DAC] |= step; + offset[DA732X_HPR_DAC] |= step; + snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, + ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); + snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, + ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); + + msleep(DA732X_WAIT_FOR_STABILIZATION); + + if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & + DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) + offset[DA732X_HPL_DAC] &= ~step; + if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & + DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) + offset[DA732X_HPR_DAC] &= ~step; + + step >>= 1; + } while (step); + + /* Write final DAC offsets to registers */ + snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, + ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); + snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, + ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); + + /* End DAC calibration mode */ + snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, + DA732X_HP_DAC_OFF_SCALE_STEPS); + snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, + DA732X_HP_DAC_OFF_SCALE_STEPS); +} + +static void da732x_output_offset_adjust(struct snd_soc_codec *codec) +{ + u8 offset[DA732X_HP_AMPS]; + u8 sign[DA732X_HP_AMPS]; + u8 step = DA732X_OUTPUT_OFFSET_STEP; + + offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL; + offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL; + + /* Initialize output offset calibration circuits and registers */ + snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); + snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); + snd_soc_write(codec, DA732X_REG_HPL, + DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); + snd_soc_write(codec, DA732X_REG_HPR, + DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); + + /* Wait for voltage stabilization */ + msleep(DA732X_WAIT_FOR_STABILIZATION); + + /* Check output offset sign */ + sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) & + DA732X_HP_OUT_COMPO; + sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) & + DA732X_HP_OUT_COMPO; + + snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | + (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | + DA732X_HP_OUT_EN); + snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP | + (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | + DA732X_HP_OUT_EN); + + /* Binary search output offset values (both channels at once) */ + do { + offset[DA732X_HPL_AMP] |= step; + offset[DA732X_HPR_AMP] |= step; + snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, + offset[DA732X_HPL_AMP]); + snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, + offset[DA732X_HPR_AMP]); + + msleep(DA732X_WAIT_FOR_STABILIZATION); + + if ((codec->hw_read(codec, DA732X_REG_HPL) & + DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) + offset[DA732X_HPL_AMP] &= ~step; + if ((codec->hw_read(codec, DA732X_REG_HPR) & + DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) + offset[DA732X_HPR_AMP] &= ~step; + + step >>= 1; + } while (step); + + /* Write final DAC offsets to registers */ + snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]); + snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]); +} + +static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec) +{ + /* Make sure that we have Soft Mute enabled */ + snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN | + DA732X_GAIN_RAMPED | DA732X_16_SAMPLES); + snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN | + DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM | + DA732X_DACL_MUTE | DA732X_DACR_MUTE); + snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN | + DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN); + snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN | + DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN); + + da732x_dac_offset_adjust(codec); + da732x_output_offset_adjust(codec); + + snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS); + snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS); + snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS); +} + +static int da732x_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, + DA732X_BIAS_BOOST_MASK, + DA732X_BIAS_BOOST_100PC); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + /* Init Codec */ + snd_soc_write(codec, DA732X_REG_REF1, + DA732X_VMID_FASTCHG); + snd_soc_write(codec, DA732X_REG_BIAS_EN, + DA732X_BIAS_EN); + + mdelay(DA732X_STARTUP_DELAY); + + /* Disable Fast Charge and enable DAC ref voltage */ + snd_soc_write(codec, DA732X_REG_REF1, + DA732X_REFBUFX2_EN); + + /* Enable bypass DSP routing */ + snd_soc_write(codec, DA732X_REG_DATA_ROUTE, + DA732X_BYPASS_DSP); + + /* Enable Digital subsystem */ + snd_soc_write(codec, DA732X_REG_DSP_CTRL, + DA732X_DIGITAL_EN); + + snd_soc_write(codec, DA732X_REG_SPARE1_OUT, + DA732X_HP_DRIVER_EN | + DA732X_HP_GATE_LOW | + DA732X_HP_LOOP_GAIN_CTRL); + snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL, + DA732X_HP_OUT_GNDSEL); + + da732x_set_charge_pump(codec, DA732X_ENABLE_CP); + + snd_soc_write(codec, DA732X_REG_CLK_EN1, + DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN); + + /* Enable Zero Crossing */ + snd_soc_write(codec, DA732X_REG_INP_ZC_EN, + DA732X_MIC1_PRE_ZC_EN | + DA732X_MIC1_ZC_EN | + DA732X_MIC2_PRE_ZC_EN | + DA732X_MIC2_ZC_EN | + DA732X_AUXL_ZC_EN | + DA732X_AUXR_ZC_EN | + DA732X_MIC3_PRE_ZC_EN | + DA732X_MIC3_ZC_EN); + snd_soc_write(codec, DA732X_REG_OUT_ZC_EN, + DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN | + DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN | + DA732X_LIN4_ZC_EN); + + da732x_hp_dc_offset_cancellation(codec); + + regcache_cache_only(codec->control_data, false); + regcache_sync(codec->control_data); + } else { + snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, + DA732X_BIAS_BOOST_MASK, + DA732X_BIAS_BOOST_50PC); + snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, + DA732X_PLL_EN, 0); + da732x->pll_en = false; + } + break; + case SND_SOC_BIAS_OFF: + regcache_cache_only(codec->control_data, true); + da732x_set_charge_pump(codec, DA732X_DISABLE_CP); + snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, + DA732X_BIAS_DIS); + da732x->pll_en = false; + break; + } + + codec->dapm.bias_level = level; + + return 0; +} + +static int da732x_probe(struct snd_soc_codec *codec) +{ + struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; + int ret = 0; + + da732x->codec = codec; + + dapm->idle_bias_off = false; + + codec->control_data = da732x->regmap; + + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); + if (ret != 0) { + dev_err(codec->dev, "Failed to register codec.\n"); + goto err; + } + + da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); +err: + return ret; +} + +static int da732x_remove(struct snd_soc_codec *codec) +{ + + da732x_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +struct snd_soc_codec_driver soc_codec_dev_da732x = { + .probe = da732x_probe, + .remove = da732x_remove, + .set_bias_level = da732x_set_bias_level, + .controls = da732x_snd_controls, + .num_controls = ARRAY_SIZE(da732x_snd_controls), + .dapm_widgets = da732x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), + .dapm_routes = da732x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), + .set_pll = da732x_set_dai_pll, + .reg_cache_size = ARRAY_SIZE(da732x_reg_cache), +}; + +static __devinit int da732x_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct da732x_priv *da732x; + unsigned int reg; + int ret; + + da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv), + GFP_KERNEL); + if (!da732x) + return -ENOMEM; + + i2c_set_clientdata(i2c, da732x); + + da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap); + if (IS_ERR(da732x->regmap)) { + ret = PTR_ERR(da732x->regmap); + dev_err(&i2c->dev, "Failed to initialize regmap\n"); + goto err; + } + + ret = regmap_read(da732x->regmap, DA732X_REG_ID, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); + goto err; + } + + dev_info(&i2c->dev, "Revision: %d.%d\n", + (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK)); + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x, + da732x_dai, ARRAY_SIZE(da732x_dai)); + if (ret != 0) + dev_err(&i2c->dev, "Failed to register codec.\n"); + +err: + return ret; +} + +static __devexit int da732x_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + + return 0; +} + +static const struct i2c_device_id da732x_i2c_id[] = { + { "da7320", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, da732x_i2c_id); + +static struct i2c_driver da732x_i2c_driver = { + .driver = { + .name = "da7320", + .owner = THIS_MODULE, + }, + .probe = da732x_i2c_probe, + .remove = __devexit_p(da732x_i2c_remove), + .id_table = da732x_i2c_id, +}; + +module_i2c_driver(da732x_i2c_driver); + + +MODULE_DESCRIPTION("ASoC DA732X driver"); +MODULE_AUTHOR("Michal Hajduk "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h new file mode 100644 index 000000000000..c8ce5475de22 --- /dev/null +++ b/sound/soc/codecs/da732x.h @@ -0,0 +1,133 @@ +/* + * da732x.h -- Dialog DA732X ALSA SoC Audio Driver Header File + * + * Copyright (C) 2012 Dialog Semiconductor GmbH + * + * Author: Michal Hajduk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DA732X_H_ +#define __DA732X_H + +#include + +/* General */ +#define DA732X_U8_MASK 0xFF +#define DA732X_4BYTES 4 +#define DA732X_3BYTES 3 +#define DA732X_2BYTES 2 +#define DA732X_1BYTE 1 +#define DA732X_1BYTE_SHIFT 8 +#define DA732X_2BYTES_SHIFT 16 +#define DA732X_3BYTES_SHIFT 24 +#define DA732X_4BYTES_SHIFT 32 + +#define DA732X_DACS_DIS 0x0 +#define DA732X_HP_DIS 0x0 +#define DA732X_CLEAR_REG 0x0 + +/* Calibration */ +#define DA732X_DAC_OFFSET_STEP 0x20 +#define DA732X_OUTPUT_OFFSET_STEP 0x80 +#define DA732X_HP_OUT_TRIM_VAL 0x0 +#define DA732X_WAIT_FOR_STABILIZATION 1 +#define DA732X_HPL_DAC 0 +#define DA732X_HPR_DAC 1 +#define DA732X_HP_DACS 2 +#define DA732X_HPL_AMP 0 +#define DA732X_HPR_AMP 1 +#define DA732X_HP_AMPS 2 + +/* Clock settings */ +#define DA732X_STARTUP_DELAY 100 +#define DA732X_PLL_OUT_196608 196608000 +#define DA732X_PLL_OUT_180634 180633600 +#define DA732X_PLL_OUT_SRM 188620800 +#define DA732X_MCLK_10MHZ 10000000 +#define DA732X_MCLK_20MHZ 20000000 +#define DA732X_MCLK_40MHZ 40000000 +#define DA732X_MCLK_54MHZ 54000000 +#define DA732X_MCLK_RET_0_10MHZ 0 +#define DA732X_MCLK_VAL_0_10MHZ 1 +#define DA732X_MCLK_RET_10_20MHZ 1 +#define DA732X_MCLK_VAL_10_20MHZ 2 +#define DA732X_MCLK_RET_20_40MHZ 2 +#define DA732X_MCLK_VAL_20_40MHZ 4 +#define DA732X_MCLK_RET_40_54MHZ 3 +#define DA732X_MCLK_VAL_40_54MHZ 8 +#define DA732X_DAI_ID1 0 +#define DA732X_DAI_ID2 1 +#define DA732X_SRCCLK_PLL 0 +#define DA732X_SRCCLK_MCLK 1 + +#define DA732X_LIN_LP_VOL 0x4F +#define DA732X_LP_VOL 0x40 + +/* Kcontrols */ +#define DA732X_DAC_EN_MAX 2 +#define DA732X_ADCL_MUX_MAX 2 +#define DA732X_ADCR_MUX_MAX 3 +#define DA732X_HPF_MODE_MAX 3 +#define DA732X_HPF_MODE_SHIFT 4 +#define DA732X_HPF_MUSIC_SHIFT 0 +#define DA732X_HPF_MUSIC_MAX 4 +#define DA732X_HPF_VOICE_SHIFT 4 +#define DA732X_HPF_VOICE_MAX 8 +#define DA732X_EQ_EN_MAX 1 +#define DA732X_HPF_VOICE 1 +#define DA732X_HPF_MUSIC 2 +#define DA732X_HPF_DISABLED 0 +#define DA732X_NO_INVERT 0 +#define DA732X_INVERT 1 +#define DA732X_SWITCH_MAX 1 +#define DA732X_ENABLE_CP 1 +#define DA732X_DISABLE_CP 0 +#define DA732X_DISABLE_ALL_CLKS 0 +#define DA732X_RESET_ADCS 0 + +/* dB values */ +#define DA732X_MIC_VOL_DB_MIN 0 +#define DA732X_MIC_VOL_DB_INC 50 +#define DA732X_MIC_PRE_VOL_DB_MIN 0 +#define DA732X_MIC_PRE_VOL_DB_INC 600 +#define DA732X_AUX_VOL_DB_MIN -6000 +#define DA732X_AUX_VOL_DB_INC 150 +#define DA732X_HP_VOL_DB_MIN -2250 +#define DA732X_HP_VOL_DB_INC 150 +#define DA732X_LIN2_VOL_DB_MIN -1650 +#define DA732X_LIN2_VOL_DB_INC 150 +#define DA732X_LIN3_VOL_DB_MIN -1650 +#define DA732X_LIN3_VOL_DB_INC 150 +#define DA732X_LIN4_VOL_DB_MIN -2250 +#define DA732X_LIN4_VOL_DB_INC 150 +#define DA732X_EQ_BAND_VOL_DB_MIN -1050 +#define DA732X_EQ_BAND_VOL_DB_INC 150 +#define DA732X_DAC_VOL_DB_MIN -7725 +#define DA732X_DAC_VOL_DB_INC 75 +#define DA732X_ADC_VOL_DB_MIN 0 +#define DA732X_ADC_VOL_DB_INC -1 +#define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 +#define DA732X_EQ_OVERALL_VOL_DB_INC 600 + +#define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \ + {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext} + +enum da732x_sysctl { + DA732X_SR_8KHZ = 0x1, + DA732X_SR_11_025KHZ = 0x2, + DA732X_SR_12KHZ = 0x3, + DA732X_SR_16KHZ = 0x5, + DA732X_SR_22_05KHZ = 0x6, + DA732X_SR_24KHZ = 0x7, + DA732X_SR_32KHZ = 0x9, + DA732X_SR_44_1KHZ = 0xA, + DA732X_SR_48KHZ = 0xB, + DA732X_SR_88_1KHZ = 0xE, + DA732X_SR_96KHZ = 0xF, +}; + +#endif /* __DA732X_H_ */ diff --git a/sound/soc/codecs/da732x_reg.h b/sound/soc/codecs/da732x_reg.h new file mode 100644 index 000000000000..bdd03ca4b2de --- /dev/null +++ b/sound/soc/codecs/da732x_reg.h @@ -0,0 +1,654 @@ +/* + * da732x_reg.h --- Dialog DA732X ALSA SoC Audio Registers Header File + * + * Copyright (C) 2012 Dialog Semiconductor GmbH + * + * Author: Michal Hajduk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DA732X_REG_H_ +#define __DA732X_REG_H_ + +/* DA732X registers */ +#define DA732X_REG_STATUS_EXT 0x00 +#define DA732X_REG_STATUS 0x01 +#define DA732X_REG_REF1 0x02 +#define DA732X_REG_BIAS_EN 0x03 +#define DA732X_REG_BIAS1 0x04 +#define DA732X_REG_BIAS2 0x05 +#define DA732X_REG_BIAS3 0x06 +#define DA732X_REG_BIAS4 0x07 +#define DA732X_REG_MICBIAS2 0x0F +#define DA732X_REG_MICBIAS1 0x10 +#define DA732X_REG_MICDET 0x11 +#define DA732X_REG_MIC1_PRE 0x12 +#define DA732X_REG_MIC1 0x13 +#define DA732X_REG_MIC2_PRE 0x14 +#define DA732X_REG_MIC2 0x15 +#define DA732X_REG_AUX1L 0x16 +#define DA732X_REG_AUX1R 0x17 +#define DA732X_REG_MIC3_PRE 0x18 +#define DA732X_REG_MIC3 0x19 +#define DA732X_REG_INP_PINBIAS 0x1A +#define DA732X_REG_INP_ZC_EN 0x1B +#define DA732X_REG_INP_MUX 0x1D +#define DA732X_REG_HP_DET 0x20 +#define DA732X_REG_HPL_DAC_OFFSET 0x21 +#define DA732X_REG_HPL_DAC_OFF_CNTL 0x22 +#define DA732X_REG_HPL_OUT_OFFSET 0x23 +#define DA732X_REG_HPL 0x24 +#define DA732X_REG_HPL_VOL 0x25 +#define DA732X_REG_HPR_DAC_OFFSET 0x26 +#define DA732X_REG_HPR_DAC_OFF_CNTL 0x27 +#define DA732X_REG_HPR_OUT_OFFSET 0x28 +#define DA732X_REG_HPR 0x29 +#define DA732X_REG_HPR_VOL 0x2A +#define DA732X_REG_LIN2 0x2B +#define DA732X_REG_LIN3 0x2C +#define DA732X_REG_LIN4 0x2D +#define DA732X_REG_OUT_ZC_EN 0x2E +#define DA732X_REG_HP_LIN1_GNDSEL 0x37 +#define DA732X_REG_CP_HP1 0x3A +#define DA732X_REG_CP_HP2 0x3B +#define DA732X_REG_CP_CTRL1 0x40 +#define DA732X_REG_CP_CTRL2 0x41 +#define DA732X_REG_CP_CTRL3 0x42 +#define DA732X_REG_CP_LEVEL_MASK 0x43 +#define DA732X_REG_CP_DET 0x44 +#define DA732X_REG_CP_STATUS 0x45 +#define DA732X_REG_CP_THRESH1 0x46 +#define DA732X_REG_CP_THRESH2 0x47 +#define DA732X_REG_CP_THRESH3 0x48 +#define DA732X_REG_CP_THRESH4 0x49 +#define DA732X_REG_CP_THRESH5 0x4A +#define DA732X_REG_CP_THRESH6 0x4B +#define DA732X_REG_CP_THRESH7 0x4C +#define DA732X_REG_CP_THRESH8 0x4D +#define DA732X_REG_PLL_DIV_LO 0x50 +#define DA732X_REG_PLL_DIV_MID 0x51 +#define DA732X_REG_PLL_DIV_HI 0x52 +#define DA732X_REG_PLL_CTRL 0x53 +#define DA732X_REG_CLK_CTRL 0x54 +#define DA732X_REG_CLK_DSP 0x5A +#define DA732X_REG_CLK_EN1 0x5B +#define DA732X_REG_CLK_EN2 0x5C +#define DA732X_REG_CLK_EN3 0x5D +#define DA732X_REG_CLK_EN4 0x5E +#define DA732X_REG_CLK_EN5 0x5F +#define DA732X_REG_AIF_MCLK 0x60 +#define DA732X_REG_AIFA1 0x61 +#define DA732X_REG_AIFA2 0x62 +#define DA732X_REG_AIFA3 0x63 +#define DA732X_REG_AIFB1 0x64 +#define DA732X_REG_AIFB2 0x65 +#define DA732X_REG_AIFB3 0x66 +#define DA732X_REG_PC_CTRL 0x6A +#define DA732X_REG_DATA_ROUTE 0x70 +#define DA732X_REG_DSP_CTRL 0x71 +#define DA732X_REG_CIF_CTRL2 0x74 +#define DA732X_REG_HANDSHAKE 0x75 +#define DA732X_REG_MBOX0 0x76 +#define DA732X_REG_MBOX1 0x77 +#define DA732X_REG_MBOX2 0x78 +#define DA732X_REG_MBOX_STATUS 0x79 +#define DA732X_REG_SPARE1_OUT 0x7D +#define DA732X_REG_SPARE2_OUT 0x7E +#define DA732X_REG_SPARE1_IN 0x7F +#define DA732X_REG_ID 0x81 +#define DA732X_REG_ADC1_PD 0x90 +#define DA732X_REG_ADC1_HPF 0x93 +#define DA732X_REG_ADC1_SEL 0x94 +#define DA732X_REG_ADC1_EQ12 0x95 +#define DA732X_REG_ADC1_EQ34 0x96 +#define DA732X_REG_ADC1_EQ5 0x97 +#define DA732X_REG_ADC2_PD 0x98 +#define DA732X_REG_ADC2_HPF 0x9B +#define DA732X_REG_ADC2_SEL 0x9C +#define DA732X_REG_ADC2_EQ12 0x9D +#define DA732X_REG_ADC2_EQ34 0x9E +#define DA732X_REG_ADC2_EQ5 0x9F +#define DA732X_REG_DAC1_HPF 0xA0 +#define DA732X_REG_DAC1_L_VOL 0xA1 +#define DA732X_REG_DAC1_R_VOL 0xA2 +#define DA732X_REG_DAC1_SEL 0xA3 +#define DA732X_REG_DAC1_SOFTMUTE 0xA4 +#define DA732X_REG_DAC1_EQ12 0xA5 +#define DA732X_REG_DAC1_EQ34 0xA6 +#define DA732X_REG_DAC1_EQ5 0xA7 +#define DA732X_REG_DAC2_HPF 0xB0 +#define DA732X_REG_DAC2_L_VOL 0xB1 +#define DA732X_REG_DAC2_R_VOL 0xB2 +#define DA732X_REG_DAC2_SEL 0xB3 +#define DA732X_REG_DAC2_SOFTMUTE 0xB4 +#define DA732X_REG_DAC2_EQ12 0xB5 +#define DA732X_REG_DAC2_EQ34 0xB6 +#define DA732X_REG_DAC2_EQ5 0xB7 +#define DA732X_REG_DAC3_HPF 0xC0 +#define DA732X_REG_DAC3_VOL 0xC1 +#define DA732X_REG_DAC3_SEL 0xC3 +#define DA732X_REG_DAC3_SOFTMUTE 0xC4 +#define DA732X_REG_DAC3_EQ12 0xC5 +#define DA732X_REG_DAC3_EQ34 0xC6 +#define DA732X_REG_DAC3_EQ5 0xC7 +#define DA732X_REG_BIQ_BYP 0xD2 +#define DA732X_REG_DMA_CMD 0xD3 +#define DA732X_REG_DMA_ADDR0 0xD4 +#define DA732X_REG_DMA_ADDR1 0xD5 +#define DA732X_REG_DMA_DATA0 0xD6 +#define DA732X_REG_DMA_DATA1 0xD7 +#define DA732X_REG_DMA_DATA2 0xD8 +#define DA732X_REG_DMA_DATA3 0xD9 +#define DA732X_REG_DMA_STATUS 0xDA +#define DA732X_REG_BROWNOUT 0xDF +#define DA732X_REG_UNLOCK 0xE0 + +#define DA732X_MAX_REG DA732X_REG_UNLOCK +/* + * Bits + */ + +/* DA732X_REG_STATUS_EXT (addr=0x00) */ +#define DA732X_STATUS_EXT_DSP (1 << 4) +#define DA732X_STATUS_EXT_CLEAR (0 << 0) + +/* DA732X_REG_STATUS (addr=0x01) */ +#define DA732X_STATUS_PLL_LOCK (1 << 0) +#define DA732X_STATUS_PLL_MCLK_DET (1 << 1) +#define DA732X_STATUS_HPDET_OUT (1 << 2) +#define DA732X_STATUS_INP_MIXDET_1 (1 << 3) +#define DA732X_STATUS_INP_MIXDET_2 (1 << 4) +#define DA732X_STATUS_BO_STATUS (1 << 5) + +/* DA732X_REG_REF1 (addr=0x02) */ +#define DA732X_VMID_FASTCHG (1 << 1) +#define DA732X_VMID_FASTDISCHG (1 << 2) +#define DA732X_REFBUFX2_EN (1 << 6) +#define DA732X_REFBUFX2_DIS (0 << 6) + +/* DA732X_REG_BIAS_EN (addr=0x03) */ +#define DA732X_BIAS_BOOST_MASK (3 << 0) +#define DA732X_BIAS_BOOST_100PC (0 << 0) +#define DA732X_BIAS_BOOST_133PC (1 << 0) +#define DA732X_BIAS_BOOST_88PC (2 << 0) +#define DA732X_BIAS_BOOST_50PC (3 << 0) +#define DA732X_BIAS_EN (1 << 7) +#define DA732X_BIAS_DIS (0 << 7) + +/* DA732X_REG_BIAS1 (addr=0x04) */ +#define DA732X_BIAS1_HP_DAC_BIAS_MASK (3 << 0) +#define DA732X_BIAS1_HP_DAC_BIAS_100PC (0 << 0) +#define DA732X_BIAS1_HP_DAC_BIAS_150PC (1 << 0) +#define DA732X_BIAS1_HP_DAC_BIAS_50PC (2 << 0) +#define DA732X_BIAS1_HP_DAC_BIAS_75PC (3 << 0) +#define DA732X_BIAS1_HP_OUT_BIAS_MASK (7 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_100PC (0 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_125PC (1 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_150PC (2 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_175PC (3 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_200PC (4 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_250PC (5 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_300PC (6 << 4) +#define DA732X_BIAS1_HP_OUT_BIAS_350PC (7 << 4) + +/* DA732X_REG_BIAS2 (addr=0x05) */ +#define DA732X_BIAS2_LINE2_DAC_BIAS_MASK (3 << 0) +#define DA732X_BIAS2_LINE2_DAC_BIAS_100PC (0 << 0) +#define DA732X_BIAS2_LINE2_DAC_BIAS_150PC (1 << 0) +#define DA732X_BIAS2_LINE2_DAC_BIAS_50PC (2 << 0) +#define DA732X_BIAS2_LINE2_DAC_BIAS_75PC (3 << 0) +#define DA732X_BIAS2_LINE2_OUT_BIAS_MASK (7 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_100PC (0 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_125PC (1 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_150PC (2 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_175PC (3 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_200PC (4 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_250PC (5 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_300PC (6 << 4) +#define DA732X_BIAS2_LINE2_OUT_BIAS_350PC (7 << 4) + +/* DA732X_REG_BIAS3 (addr=0x06) */ +#define DA732X_BIAS3_LINE3_DAC_BIAS_MASK (3 << 0) +#define DA732X_BIAS3_LINE3_DAC_BIAS_100PC (0 << 0) +#define DA732X_BIAS3_LINE3_DAC_BIAS_150PC (1 << 0) +#define DA732X_BIAS3_LINE3_DAC_BIAS_50PC (2 << 0) +#define DA732X_BIAS3_LINE3_DAC_BIAS_75PC (3 << 0) +#define DA732X_BIAS3_LINE3_OUT_BIAS_MASK (7 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_100PC (0 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_125PC (1 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_150PC (2 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_175PC (3 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_200PC (4 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_250PC (5 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_300PC (6 << 4) +#define DA732X_BIAS3_LINE3_OUT_BIAS_350PC (7 << 4) + +/* DA732X_REG_BIAS4 (addr=0x07) */ +#define DA732X_BIAS4_LINE4_DAC_BIAS_MASK (3 << 0) +#define DA732X_BIAS4_LINE4_DAC_BIAS_100PC (0 << 0) +#define DA732X_BIAS4_LINE4_DAC_BIAS_150PC (1 << 0) +#define DA732X_BIAS4_LINE4_DAC_BIAS_50PC (2 << 0) +#define DA732X_BIAS4_LINE4_DAC_BIAS_75PC (3 << 0) +#define DA732X_BIAS4_LINE4_OUT_BIAS_MASK (7 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_100PC (0 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_125PC (1 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_150PC (2 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_175PC (3 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_200PC (4 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_250PC (5 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_300PC (6 << 4) +#define DA732X_BIAS4_LINE4_OUT_BIAS_350PC (7 << 4) + +/* DA732X_REG_SIF_VDD_SEL (addr=0x08) */ +#define DA732X_SIF_VDD_SEL_AIFA_VDD2 (1 << 0) +#define DA732X_SIF_VDD_SEL_AIFB_VDD2 (1 << 1) +#define DA732X_SIF_VDD_SEL_CIFA_VDD2 (1 << 4) + +/* DA732X_REG_MICBIAS2/1 (addr=0x0F/0x10) */ +#define DA732X_MICBIAS_VOLTAGE_MASK (0x0F << 0) +#define DA732X_MICBIAS_VOLTAGE_2V (0x00 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V05 (0x01 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V1 (0x02 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V15 (0x03 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V2 (0x04 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V25 (0x05 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V3 (0x06 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V35 (0x07 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V4 (0x08 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V45 (0x09 << 0) +#define DA732X_MICBIAS_VOLTAGE_2V5 (0x0A << 0) +#define DA732X_MICBIAS_EN (1 << 7) +#define DA732X_MICBIAS_EN_SHIFT 7 +#define DA732X_MICBIAS_VOLTAGE_SHIFT 0 +#define DA732X_MICBIAS_VOLTAGE_MAX 0x0B + +/* DA732X_REG_MICDET (addr=0x11) */ +#define DA732X_MICDET_INP_MICRES (1 << 0) +#define DA732X_MICDET_INP_MICHOOK (1 << 1) +#define DA732X_MICDET_INP_DEBOUNCE_PRD_8MS (0 << 0) +#define DA732X_MICDET_INP_DEBOUNCE_PRD_16MS (1 << 0) +#define DA732X_MICDET_INP_DEBOUNCE_PRD_32MS (2 << 0) +#define DA732X_MICDET_INP_DEBOUNCE_PRD_64MS (3 << 0) +#define DA732X_MICDET_INP_MICDET_EN (1 << 7) + +/* DA732X_REG_MIC1/2/3_PRE (addr=0x11/0x14/0x18) */ +#define DA732X_MICBOOST_MASK 0x7 +#define DA732X_MICBOOST_SHIFT 0 +#define DA732X_MICBOOST_MIN 0x1 +#define DA732X_MICBOOST_MAX DA732X_MICBOOST_MASK + +/* DA732X_REG_MIC1/2/3 (addr=0x13/0x15/0x19) */ +#define DA732X_MIC_VOL_SHIFT 0 +#define DA732X_MIC_VOL_VAL_MASK 0x1F +#define DA732X_MIC_MUTE_SHIFT 6 +#define DA732X_MIC_EN_SHIFT 7 +#define DA732X_MIC_VOL_VAL_MIN 0x7 +#define DA732X_MIC_VOL_VAL_MAX DA732X_MIC_VOL_VAL_MASK + +/* DA732X_REG_AUX1L/R (addr=0x16/0x17) */ +#define DA732X_AUX_VOL_SHIFT 0 +#define DA732X_AUX_VOL_MASK 0x7 +#define DA732X_AUX_MUTE_SHIFT 6 +#define DA732X_AUX_EN_SHIFT 7 +#define DA732X_AUX_VOL_VAL_MAX DA732X_AUX_VOL_MASK + +/* DA732X_REG_INP_PINBIAS (addr=0x1A) */ +#define DA732X_INP_MICL_PINBIAS_EN (1 << 0) +#define DA732X_INP_MICR_PINBIAS_EN (1 << 1) +#define DA732X_INP_AUX1L_PINBIAS_EN (1 << 2) +#define DA732X_INP_AUX1R_PINBIAS_EN (1 << 3) +#define DA732X_INP_AUX2_PINBIAS_EN (1 << 4) + +/* DA732X_REG_INP_ZC_EN (addr=0x1B) */ +#define DA732X_MIC1_PRE_ZC_EN (1 << 0) +#define DA732X_MIC1_ZC_EN (1 << 1) +#define DA732X_MIC2_PRE_ZC_EN (1 << 2) +#define DA732X_MIC2_ZC_EN (1 << 3) +#define DA732X_AUXL_ZC_EN (1 << 4) +#define DA732X_AUXR_ZC_EN (1 << 5) +#define DA732X_MIC3_PRE_ZC_EN (1 << 6) +#define DA732X_MIC3_ZC_EN (1 << 7) + +/* DA732X_REG_INP_MUX (addr=0x1D) */ +#define DA732X_INP_ADC1L_MUX_SEL_AUX1L (0 << 0) +#define DA732X_INP_ADC1L_MUX_SEL_MIC1 (1 << 0) +#define DA732X_INP_ADC1R_MUX_SEL_MASK (3 << 2) +#define DA732X_INP_ADC1R_MUX_SEL_AUX1R (0 << 2) +#define DA732X_INP_ADC1R_MUX_SEL_MIC2 (1 << 2) +#define DA732X_INP_ADC1R_MUX_SEL_MIC3 (2 << 2) +#define DA732X_INP_ADC2L_MUX_SEL_AUX1L (0 << 4) +#define DA732X_INP_ADC2L_MUX_SEL_MICL (1 << 4) +#define DA732X_INP_ADC2R_MUX_SEL_MASK (3 << 6) +#define DA732X_INP_ADC2R_MUX_SEL_AUX1R (0 << 6) +#define DA732X_INP_ADC2R_MUX_SEL_MICR (1 << 6) +#define DA732X_INP_ADC2R_MUX_SEL_AUX2 (2 << 6) +#define DA732X_ADC1L_MUX_SEL_SHIFT 0 +#define DA732X_ADC1R_MUX_SEL_SHIFT 2 +#define DA732X_ADC2L_MUX_SEL_SHIFT 4 +#define DA732X_ADC2R_MUX_SEL_SHIFT 6 + +/* DA732X_REG_HP_DET (addr=0x20) */ +#define DA732X_HP_DET_AZ (1 << 0) +#define DA732X_HP_DET_SEL1 (1 << 1) +#define DA732X_HP_DET_IS_MASK (3 << 2) +#define DA732X_HP_DET_IS_0_5UA (0 << 2) +#define DA732X_HP_DET_IS_1UA (1 << 2) +#define DA732X_HP_DET_IS_2UA (2 << 2) +#define DA732X_HP_DET_IS_4UA (3 << 2) +#define DA732X_HP_DET_RS_MASK (3 << 4) +#define DA732X_HP_DET_RS_INFINITE (0 << 4) +#define DA732X_HP_DET_RS_100KOHM (1 << 4) +#define DA732X_HP_DET_RS_10KOHM (2 << 4) +#define DA732X_HP_DET_RS_1KOHM (3 << 4) +#define DA732X_HP_DET_EN (1 << 7) + +/* DA732X_REG_HPL_DAC_OFFSET (addr=0x21/0x26) */ +#define DA732X_HP_DAC_OFFSET_TRIM_MASK (0x3F << 0) +#define DA732X_HP_DAC_OFFSET_DAC_SIGN (1 << 6) + +/* DA732X_REG_HPL_DAC_OFF_CNTL (addr=0x22/0x27) */ +#define DA732X_HP_DAC_OFF_CNTL_CONT_MASK (7 << 0) +#define DA732X_HP_DAC_OFF_CNTL_COMPO (1 << 3) +#define DA732X_HP_DAC_OFF_CALIBRATION (1 << 0) +#define DA732X_HP_DAC_OFF_SCALE_STEPS (1 << 1) +#define DA732X_HP_DAC_OFF_MASK 0x7F +#define DA732X_HP_DAC_COMPO_SHIFT 3 + +/* DA732X_REG_HPL_OUT_OFFSET (addr=0x23/0x28) */ +#define DA732X_HP_OUT_OFFSET_MASK (0xFF << 0) +#define DA732X_HP_DAC_OFFSET_TRIM_VAL 0x7F + +/* DA732X_REG_HPL/R (addr=0x24/0x29) */ +#define DA732X_HP_OUT_SIGN (1 << 0) +#define DA732X_HP_OUT_COMP (1 << 1) +#define DA732X_HP_OUT_RESERVED (1 << 2) +#define DA732X_HP_OUT_COMPO (1 << 3) +#define DA732X_HP_OUT_DAC_EN (1 << 4) +#define DA732X_HP_OUT_HIZ_EN (1 << 5) +#define DA732X_HP_OUT_HIZ_DIS (0 << 5) +#define DA732X_HP_OUT_MUTE (1 << 6) +#define DA732X_HP_OUT_EN (1 << 7) +#define DA732X_HP_OUT_COMPO_SHIFT 3 +#define DA732X_HP_OUT_DAC_EN_SHIFT 4 +#define DA732X_HP_HIZ_SHIFT 5 +#define DA732X_HP_MUTE_SHIFT 6 +#define DA732X_HP_OUT_EN_SHIFT 7 + +#define DA732X_OUT_HIZ_EN (1 << 5) +#define DA732X_OUT_HIZ_DIS (0 << 5) + +/* DA732X_REG_HPL/R_VOL (addr=0x25/0x2A) */ +#define DA732X_HP_VOL_VAL_MASK 0xF +#define DA732X_HP_VOL_SHIFT 0 +#define DA732X_HP_VOL_VAL_MAX DA732X_HP_VOL_VAL_MASK + +/* DA732X_REG_LIN2/3/4 (addr=0x2B/0x2C/0x2D) */ +#define DA732X_LOUT_VOL_SHIFT 0 +#define DA732X_LOUT_VOL_MASK 0x0F +#define DA732X_LOUT_DAC_OFF (0 << 4) +#define DA732X_LOUT_DAC_EN (1 << 4) +#define DA732X_LOUT_HIZ_N_DIS (0 << 5) +#define DA732X_LOUT_HIZ_N_EN (1 << 5) +#define DA732X_LOUT_UNMUTED (0 << 6) +#define DA732X_LOUT_MUTED (1 << 6) +#define DA732X_LOUT_EN (0 << 7) +#define DA732X_LOUT_DIS (1 << 7) +#define DA732X_LOUT_DAC_EN_SHIFT 4 +#define DA732X_LOUT_MUTE_SHIFT 6 +#define DA732X_LIN_OUT_EN_SHIFT 7 +#define DA732X_LOUT_VOL_VAL_MAX DA732X_LOUT_VOL_MASK + +/* DA732X_REG_OUT_ZC_EN (addr=0x2E) */ +#define DA732X_HPL_ZC_EN_SHIFT 0 +#define DA732X_HPR_ZC_EN_SHIFT 1 +#define DA732X_HPL_ZC_EN (1 << 0) +#define DA732X_HPL_ZC_DIS (0 << 0) +#define DA732X_HPR_ZC_EN (1 << 1) +#define DA732X_HPR_ZC_DIS (0 << 1) +#define DA732X_LIN2_ZC_EN (1 << 2) +#define DA732X_LIN2_ZC_DIS (0 << 2) +#define DA732X_LIN3_ZC_EN (1 << 3) +#define DA732X_LIN3_ZC_DIS (0 << 3) +#define DA732X_LIN4_ZC_EN (1 << 4) +#define DA732X_LIN4_ZC_DIS (0 << 4) + +/* DA732X_REG_HP_LIN1_GNDSEL (addr=0x37) */ +#define DA732X_HP_OUT_GNDSEL (1 << 0) + +/* DA732X_REG_CP_HP2 (addr=0x3a) */ +#define DA732X_HP_CP_PULSESKIP (1 << 0) +#define DA732X_HP_CP_REG (1 << 1) +#define DA732X_HP_CP_EN (1 << 3) +#define DA732X_HP_CP_DIS (0 << 3) + +/* DA732X_REG_CP_CTRL1 (addr=0x40) */ +#define DA732X_CP_MODE_MASK (7 << 1) +#define DA732X_CP_CTRL_STANDBY (0 << 1) +#define DA732X_CP_CTRL_CPVDD6 (2 << 1) +#define DA732X_CP_CTRL_CPVDD5 (3 << 1) +#define DA732X_CP_CTRL_CPVDD4 (4 << 1) +#define DA732X_CP_CTRL_CPVDD3 (5 << 1) +#define DA732X_CP_CTRL_CPVDD2 (6 << 1) +#define DA732X_CP_CTRL_CPVDD1 (7 << 1) +#define DA723X_CP_DIS (0 << 7) +#define DA732X_CP_EN (1 << 7) + +/* DA732X_REG_CP_CTRL2 (addr=0x41) */ +#define DA732X_CP_BOOST (1 << 0) +#define DA732X_CP_MANAGE_MAGNITUDE (2 << 2) + +/* DA732X_REG_CP_CTRL3 (addr=0x42) */ +#define DA732X_CP_1MHZ (0 << 0) +#define DA732X_CP_500KHZ (1 << 0) +#define DA732X_CP_250KHZ (2 << 0) +#define DA732X_CP_125KHZ (3 << 0) +#define DA732X_CP_63KHZ (4 << 0) +#define DA732X_CP_0KHZ (5 << 0) + +/* DA732X_REG_PLL_CTRL (addr=0x53) */ +#define DA732X_PLL_INDIV_MASK (3 << 0) +#define DA732X_PLL_SRM_EN (1 << 2) +#define DA732X_PLL_EN (1 << 7) +#define DA732X_PLL_BYPASS (0 << 0) + +/* DA732X_REG_CLK_CTRL (addr=0x54) */ +#define DA732X_SR1_MASK (0xF) +#define DA732X_SR2_MASK (0xF0) + +/* DA732X_REG_CLK_DSP (addr=0x5A) */ +#define DA732X_DSP_FREQ_MASK (7 << 0) +#define DA732X_DSP_FREQ_12MHZ (0 << 0) +#define DA732X_DSP_FREQ_24MHZ (1 << 0) +#define DA732X_DSP_FREQ_36MHZ (2 << 0) +#define DA732X_DSP_FREQ_48MHZ (3 << 0) +#define DA732X_DSP_FREQ_60MHZ (4 << 0) +#define DA732X_DSP_FREQ_72MHZ (5 << 0) +#define DA732X_DSP_FREQ_84MHZ (6 << 0) +#define DA732X_DSP_FREQ_96MHZ (7 << 0) + +/* DA732X_REG_CLK_EN1 (addr=0x5B) */ +#define DA732X_DSP_CLK_EN (1 << 0) +#define DA732X_SYS3_CLK_EN (1 << 1) +#define DA732X_DSP12_CLK_EN (1 << 2) +#define DA732X_PC_CLK_EN (1 << 3) +#define DA732X_MCLK_SQR_EN (1 << 7) + +/* DA732X_REG_CLK_EN2 (addr=0x5C) */ +#define DA732X_UART_CLK_EN (1 << 1) +#define DA732X_CP_CLK_EN (1 << 2) +#define DA732X_CP_CLK_DIS (0 << 2) + +/* DA732X_REG_CLK_EN3 (addr=0x5D) */ +#define DA732X_ADCA_BB_CLK_EN (1 << 0) +#define DA732X_ADCC_BB_CLK_EN (1 << 4) + +/* DA732X_REG_CLK_EN4 (addr=0x5E) */ +#define DA732X_DACA_BB_CLK_EN (1 << 0) +#define DA732X_DACC_BB_CLK_EN (1 << 4) +#define DA732X_DACA_BB_CLK_SHIFT 0 +#define DA732X_DACC_BB_CLK_SHIFT 4 + +/* DA732X_REG_CLK_EN5 (addr=0x5F) */ +#define DA732X_DACE_BB_CLK_EN (1 << 0) +#define DA732X_DACE_BB_CLK_SHIFT 0 + +/* DA732X_REG_AIF_MCLK (addr=0x60) */ +#define DA732X_AIFM_FRAME_64 (1 << 2) +#define DA732X_AIFM_SRC_SEL_AIFA (1 << 6) +#define DA732X_CLK_GENERATION_AIF_A (1 << 4) +#define DA732X_NO_CLK_GENERATION 0x0 + +/* DA732X_REG_AIFA1 (addr=0x61) */ +#define DA732X_AIF_WORD_MASK (0x3 << 0) +#define DA732X_AIF_WORD_16 (0 << 0) +#define DA732X_AIF_WORD_20 (1 << 0) +#define DA732X_AIF_WORD_24 (2 << 0) +#define DA732X_AIF_WORD_32 (3 << 0) +#define DA732X_AIF_TDM_MONO_SHIFT (1 << 6) +#define DA732X_AIF1_CLK_MASK (1 << 7) +#define DA732X_AIF_SLAVE (0 << 7) +#define DA732X_AIF_CLK_FROM_SRC (1 << 7) + +/* DA732X_REG_AIFA3 (addr=0x63) */ +#define DA732X_AIF_MODE_SHIFT 0 +#define DA732X_AIF_MODE_MASK 0x3 +#define DA732X_AIF_I2S_MODE (0 << 0) +#define DA732X_AIF_LEFT_J_MODE (1 << 0) +#define DA732X_AIF_RIGHT_J_MODE (2 << 0) +#define DA732X_AIF_DSP_MODE (3 << 0) +#define DA732X_AIF_WCLK_INV (1 << 4) +#define DA732X_AIF_BCLK_INV (1 << 5) +#define DA732X_AIF_EN (1 << 7) +#define DA732X_AIF_EN_SHIFT 7 + +/* DA732X_REG_PC_CTRL (addr=0x6a) */ +#define DA732X_PC_PULSE_AIFA (0 << 0) +#define DA732X_PC_PULSE_AIFB (1 << 0) +#define DA732X_PC_RESYNC_AUT (1 << 6) +#define DA732X_PC_RESYNC_NOT_AUT (0 << 6) +#define DA732X_PC_SAME (1 << 7) + +/* DA732X_REG_DATA_ROUTE (addr=0x70) */ +#define DA732X_ADC1_TO_AIFA (0 << 0) +#define DA732X_DSP_TO_AIFA (1 << 0) +#define DA732X_ADC2_TO_AIFB (0 << 1) +#define DA732X_DSP_TO_AIFB (1 << 1) +#define DA732X_AIFA_TO_DAC1L (0 << 2) +#define DA732X_DSP_TO_DAC1L (1 << 2) +#define DA732X_AIFA_TO_DAC1R (0 << 3) +#define DA732X_DSP_TO_DAC1R (1 << 3) +#define DA732X_AIFB_TO_DAC2L (0 << 4) +#define DA732X_DSP_TO_DAC2L (1 << 4) +#define DA732X_AIFB_TO_DAC2R (0 << 5) +#define DA732X_DSP_TO_DAC2R (1 << 5) +#define DA732X_AIFB_TO_DAC3 (0 << 6) +#define DA732X_DSP_TO_DAC3 (1 << 6) +#define DA732X_BYPASS_DSP (0 << 0) +#define DA732X_ALL_TO_DSP (0x7F << 0) + +/* DA732X_REG_DSP_CTRL (addr=0x71) */ +#define DA732X_DIGITAL_EN (1 << 0) +#define DA732X_DIGITAL_RESET (0 << 0) +#define DA732X_DSP_CORE_EN (1 << 1) +#define DA732X_DSP_CORE_RESET (0 << 1) + +/* DA732X_REG_SPARE1_OUT (addr=0x7D)*/ +#define DA732X_HP_DRIVER_EN (1 << 0) +#define DA732X_HP_GATE_LOW (1 << 2) +#define DA732X_HP_LOOP_GAIN_CTRL (1 << 3) + +/* DA732X_REG_ID (addr=0x81)*/ +#define DA732X_ID_MINOR_MASK (0xF << 0) +#define DA732X_ID_MAJOR_MASK (0xF << 4) + +/* DA732X_REG_ADC1/2_PD (addr=0x90/0x98) */ +#define DA732X_ADC_RST_MASK (0x3 << 0) +#define DA732X_ADC_PD_MASK (0x3 << 2) +#define DA732X_ADC_SET_ACT (0x3 << 0) +#define DA732X_ADC_SET_RST (0x0 << 0) +#define DA732X_ADC_ON (0x3 << 2) +#define DA732X_ADC_OFF (0x0 << 2) + +/* DA732X_REG_ADC1/2_SEL (addr=0x94/0x9C) */ +#define DA732X_ADC_VOL_VAL_MASK 0x7 +#define DA732X_ADCL_VOL_SHIFT 0 +#define DA732X_ADCR_VOL_SHIFT 4 +#define DA732X_ADCL_EN_SHIFT 2 +#define DA732X_ADCR_EN_SHIFT 3 +#define DA732X_ADCL_EN (1 << 2) +#define DA732X_ADCR_EN (1 << 3) +#define DA732X_ADC_VOL_VAL_MAX DA732X_ADC_VOL_VAL_MASK + +/* + * DA732X_REG_ADC1/2_HPF (addr=0x93/0x9b) + * DA732x_REG_DAC1/2/3_HPG (addr=0xA5/0xB5/0xC5) + */ +#define DA732X_HPF_MUSIC_EN (1 << 3) +#define DA732X_HPF_VOICE_EN ((1 << 3) | (1 << 7)) +#define DA732X_HPF_MASK ((1 << 3) | (1 << 7)) +#define DA732X_HPF_DIS ((0 << 3) | (0 << 7)) + +/* DA732X_REG_DAC1/2/3_VOL */ +#define DA732X_DAC_VOL_VAL_MASK 0x7F +#define DA732X_DAC_VOL_SHIFT 0 +#define DA732X_DAC_VOL_VAL_MAX DA732X_DAC_VOL_VAL_MASK + +/* DA732X_REG_DAC1/2/3_SEL (addr=0xA3/0xB3/0xC3) */ +#define DA732X_DACL_EN_SHIFT 3 +#define DA732X_DACR_EN_SHIFT 7 +#define DA732X_DACL_MUTE_SHIFT 2 +#define DA732X_DACR_MUTE_SHIFT 6 +#define DA732X_DACL_EN (1 << 3) +#define DA732X_DACR_EN (1 << 7) +#define DA732X_DACL_SDM (1 << 0) +#define DA732X_DACR_SDM (1 << 4) +#define DA732X_DACL_MUTE (1 << 2) +#define DA732X_DACR_MUTE (1 << 6) + +/* DA732X_REG_DAC_SOFTMUTE (addr=0xA4/0xB4/0xC4) */ +#define DA732X_SOFTMUTE_EN (1 << 7) +#define DA732X_GAIN_RAMPED (1 << 6) +#define DA732X_16_SAMPLES (4 << 0) +#define DA732X_SOFTMUTE_MASK (1 << 7) +#define DA732X_SOFTMUTE_SHIFT 7 + +/* + * DA732x_REG_ADC1/2_EQ12 (addr=0x95/0x9D) + * DA732x_REG_ADC1/2_EQ34 (addr=0x96/0x9E) + * DA732x_REG_ADC1/2_EQ5 (addr=0x97/0x9F) + * DA732x_REG_DAC1/2/3_EQ12 (addr=0xA5/0xB5/0xC5) + * DA732x_REG_DAC1/2/3_EQ34 (addr=0xA6/0xB6/0xC6) + * DA732x_REG_DAC1/2/3_EQ5 (addr=0xA7/0xB7/0xB7) + */ +#define DA732X_EQ_VOL_VAL_MASK 0xF +#define DA732X_EQ_BAND1_SHIFT 0 +#define DA732X_EQ_BAND2_SHIFT 4 +#define DA732X_EQ_BAND3_SHIFT 0 +#define DA732X_EQ_BAND4_SHIFT 4 +#define DA732X_EQ_BAND5_SHIFT 0 +#define DA732X_EQ_OVERALL_SHIFT 4 +#define DA732X_EQ_OVERALL_VOL_VAL_MASK 0x3 +#define DA732X_EQ_DIS (0 << 7) +#define DA732X_EQ_EN (1 << 7) +#define DA732X_EQ_EN_SHIFT 7 +#define DA732X_EQ_VOL_VAL_MAX DA732X_EQ_VOL_VAL_MASK +#define DA732X_EQ_OVERALL_VOL_VAL_MAX DA732X_EQ_OVERALL_VOL_VAL_MASK + +/* DA732X_REG_DMA_CMD (addr=0xD3) */ +#define DA732X_SEL_DSP_DMA_MASK (3 << 0) +#define DA732X_SEL_DSP_DMA_DIS (0 << 0) +#define DA732X_SEL_DSP_DMA_PMEM (1 << 0) +#define DA732X_SEL_DSP_DMA_XMEM (2 << 0) +#define DA732X_SEL_DSP_DMA_YMEM (3 << 0) +#define DA732X_DSP_RW_MASK (1 << 4) +#define DA732X_DSP_DMA_WRITE (0 << 4) +#define DA732X_DSP_DMA_READ (1 << 4) + +/* DA732X_REG_DMA_STATUS (addr=0xDA) */ +#define DA732X_DSP_DMA_FREE (0 << 0) +#define DA732X_DSP_DMA_BUSY (1 << 0) + +#endif /* __DA732X_REG_H_ */ -- GitLab From 1bb49303b7a82eb9bce0595087523343683abdf0 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 11 Jun 2012 13:26:50 +0100 Subject: [PATCH 1066/6849] GFS2: Use seq_vprintf for glocks debugfs file Make use of the newly added seq_vprintf() function. Signed-off-by: Steven Whitehouse Reported-by: Eric Dumazet Acked-by: Al Viro --- fs/gfs2/glock.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 10ae1645d9a5..4d5d63d9d2c0 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -51,7 +51,6 @@ struct gfs2_glock_iter { struct gfs2_sbd *sdp; /* incore superblock */ struct gfs2_glock *gl; /* current glock struct */ loff_t last_pos; /* last position */ - char string[512]; /* scratch space */ }; typedef void (*glock_examiner) (struct gfs2_glock * gl); @@ -951,9 +950,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) va_start(args, fmt); if (seq) { - struct gfs2_glock_iter *gi = seq->private; - vsprintf(gi->string, fmt, args); - seq_puts(seq, gi->string); + seq_vprintf(seq, fmt, args); } else { vaf.fmt = fmt; vaf.va = &args; -- GitLab From 0fe2f1e929ecabf834f4af2ffd300fe70700f4b3 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 11 Jun 2012 13:49:47 +0100 Subject: [PATCH 1067/6849] GFS2: Size seq_file buffer more carefully This places a limit on the buffer size for archs with larger PAGE_SIZE. Signed-off-by: Steven Whitehouse Reported-by: Eric Dumazet --- fs/gfs2/glock.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 4d5d63d9d2c0..1ed81f40da0d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1977,6 +1977,8 @@ static const struct seq_operations gfs2_sbstats_seq_ops = { .show = gfs2_sbstats_seq_show, }; +#define GFS2_SEQ_GOODSIZE min(PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER, 65536UL) + static int gfs2_glocks_open(struct inode *inode, struct file *file) { int ret = seq_open_private(file, &gfs2_glock_seq_ops, @@ -1985,9 +1987,9 @@ static int gfs2_glocks_open(struct inode *inode, struct file *file) struct seq_file *seq = file->private_data; struct gfs2_glock_iter *gi = seq->private; gi->sdp = inode->i_private; - seq->buf = kmalloc(8*PAGE_SIZE, GFP_KERNEL | __GFP_NOWARN); + seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); if (seq->buf) - seq->size = 8*PAGE_SIZE; + seq->size = GFS2_SEQ_GOODSIZE; } return ret; } @@ -2000,9 +2002,9 @@ static int gfs2_glstats_open(struct inode *inode, struct file *file) struct seq_file *seq = file->private_data; struct gfs2_glock_iter *gi = seq->private; gi->sdp = inode->i_private; - seq->buf = kmalloc(8*PAGE_SIZE, GFP_KERNEL | __GFP_NOWARN); + seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); if (seq->buf) - seq->size = 8*PAGE_SIZE; + seq->size = GFS2_SEQ_GOODSIZE; } return ret; } -- GitLab From f1ff32e8a8672d4d59283fb7f61f1431c2b9e434 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 30 May 2012 01:58:39 -0700 Subject: [PATCH 1068/6849] ath6kl: Add missing newline terminations Messages without newlines can be interleaved. Avoid this by adding terminations. Signed-off-by: Joe Perches Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 6f20998beceb..d2129030fd73 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1001,7 +1001,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { - ath6kl_err("failed to set Probe Request appie for scan"); + ath6kl_err("failed to set Probe Request appie for scan\n"); return ret; } @@ -3288,7 +3288,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { - ath6kl_warn("Failed to set probe request IE for scheduled scan: %d", + ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n", ret); return ret; } -- GitLab From b871a42b6091b720e82ddff237659534c525c25b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 11 Jun 2012 15:07:08 +0200 Subject: [PATCH 1069/6849] smpboot: Remove leftover declaration Signed-off-by: Thomas Gleixner --- kernel/smpboot.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/smpboot.h b/kernel/smpboot.h index 80c0acfb8472..6ef9433e1c70 100644 --- a/kernel/smpboot.h +++ b/kernel/smpboot.h @@ -3,8 +3,6 @@ struct task_struct; -int smpboot_prepare(unsigned int cpu); - #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD struct task_struct *idle_thread_get(unsigned int cpu); void idle_thread_set_boot_cpu(void); -- GitLab From d154f32ebe3ffe9dea6ed0a91767883b1e7a6bc0 Mon Sep 17 00:00:00 2001 From: Etay Luz Date: Wed, 30 May 2012 11:35:08 +0300 Subject: [PATCH 1070/6849] ath6kl: support changing dtim period on AP mode This patch adds support for dtim_period configuration in beacon. kvalo: add a comment about ignoring the error, use vif_idx, add \n to the warning message Signed-off-by: Etay Luz Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 +++++++- drivers/net/wireless/ath/ath6kl/wmi.c | 16 ++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 5 +++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index d2129030fd73..f00d377343d9 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2783,9 +2783,15 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, /* TODO: * info->interval - * info->dtim_period */ + ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx, + info->dtim_period); + + /* ignore error, just print a warning and continue normally */ + if (ret) + ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret); + if (info->beacon.head == NULL) return -EINVAL; mgmt = (struct ieee80211_mgmt *) info->beacon.head; diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 43bce9c8a86f..a6caa673e8ad 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -752,6 +752,22 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) NO_SYNC_WMIFLAG); } +int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period) +{ + struct sk_buff *skb; + struct set_dtim_cmd *cmd; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct set_dtim_cmd *) skb->data; + + cmd->dtim_period = cpu_to_le32(dtim_period); + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG); +} + int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) { struct sk_buff *skb; diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 7c94fe3e9e6d..43339aca585d 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1617,6 +1617,10 @@ struct roam_ctrl_cmd { u8 roam_ctrl; } __packed; +struct set_dtim_cmd { + __le32 dtim_period; +} __packed; + /* BSS INFO HDR version 2.0 */ struct wmi_bss_info_hdr2 { __le16 ch; /* frequency in MHz */ @@ -2589,6 +2593,7 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); +int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); -- GitLab From 0faf745872f6d00afb318185e8fb181587974b5a Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 30 May 2012 12:27:11 +0530 Subject: [PATCH 1071/6849] ath6kl: Fix race in aggregation reorder logic There are many places where tid data are accessed without the lock (rxtid->lock), this can lead to a race condition when the timeout handler for aggregatin reorder and the receive function are getting executed at the same time. Fix this race, but still there are races which can not be fixed without rewriting the whole aggregation reorder logic, for now fix the obvious ones. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 12 +++++++++--- drivers/net/wireless/ath/ath6kl/txrx.c | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 17a44fad859b..12441f7d9036 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -273,9 +273,15 @@ struct rxtid { struct sk_buff_head q; /* - * FIXME: No clue what this should protect. Apparently it should - * protect some of the fields above but they are also accessed - * without taking the lock. + * lock mainly protects seq_next and hold_q. Movement of seq_next + * needs to be protected between aggr_timeout() and + * aggr_process_recv_frm(). hold_q will be holding the pending + * reorder frames and it's access should also be protected. + * Some of the other fields like hold_q_sz, win_sz and aggr are + * initialized/reset when receiving addba/delba req, also while + * deleting aggr state all the pending buffers are flushed before + * resetting these fields, so there should not be any race in accessing + * these fields. */ spinlock_t lock; }; diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 67206aedea6c..974c51053a71 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1036,6 +1036,7 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, rxtid = &agg_conn->rx_tid[tid]; stats = &agg_conn->stat[tid]; + spin_lock_bh(&rxtid->lock); idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); /* @@ -1054,8 +1055,6 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, seq_end = seq_no ? seq_no : rxtid->seq_next; idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz); - spin_lock_bh(&rxtid->lock); - do { node = &rxtid->hold_q[idx]; if ((order == 1) && (!node->skb)) @@ -1127,11 +1126,13 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, ((end > extended_end) && (cur > extended_end) && (cur < end))) { aggr_deque_frms(agg_conn, tid, 0, 0); + spin_lock_bh(&rxtid->lock); if (cur >= rxtid->hold_q_sz - 1) rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); else rxtid->seq_next = ATH6KL_MAX_SEQ_NO - (rxtid->hold_q_sz - 2 - cur); + spin_unlock_bh(&rxtid->lock); } else { /* * Dequeue only those frames that are outside the @@ -1186,7 +1187,8 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, if (agg_conn->timer_scheduled) rxtid->progress = true; - else + else { + spin_lock_bh(&rxtid->lock); for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { if (rxtid->hold_q[idx].skb) { /* @@ -1204,6 +1206,8 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, break; } } + spin_unlock_bh(&rxtid->lock); + } return is_queued; } @@ -1626,6 +1630,7 @@ static void aggr_timeout(unsigned long arg) rxtid = &aggr_conn->rx_tid[i]; if (rxtid->aggr && rxtid->hold_q) { + spin_lock_bh(&rxtid->lock); for (j = 0; j < rxtid->hold_q_sz; j++) { if (rxtid->hold_q[j].skb) { aggr_conn->timer_scheduled = true; @@ -1634,6 +1639,7 @@ static void aggr_timeout(unsigned long arg) break; } } + spin_unlock_bh(&rxtid->lock); if (j >= rxtid->hold_q_sz) rxtid->timer_mon = false; -- GitLab From 7940bad50859026c0f11d2b7766571175b5e55c3 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 30 May 2012 12:27:12 +0530 Subject: [PATCH 1072/6849] ath6kl: Fix unstable downlink throughput There is frequent downlink throughput drop to 0 when operating at the signal level between -42dBm to -53dBm. This has been root caused to the delay in releasing pending a-mpdu subframes in reorder buffer. Right now the timeout value is 400ms, there is also a race condition where timeout handler can be delayed to run at an extra timeout interval. This patch reduces the timout interval to reasonable 100ms and makes sure releasing pending frames are not skipped in the timeout handler by removing the flag (rxtid->progress) which can delay the timeout logic. Reported-by: Yu Yanzhi Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 3 +- drivers/net/wireless/ath/ath6kl/txrx.c | 42 +++++++++++--------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 12441f7d9036..b3eee10cf016 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -215,7 +215,7 @@ enum ath6kl_hw_flags { #define AGGR_NUM_OF_FREE_NETBUFS 16 -#define AGGR_RX_TIMEOUT 400 /* in ms */ +#define AGGR_RX_TIMEOUT 100 /* in ms */ #define WMI_TIMEOUT (2 * HZ) @@ -264,7 +264,6 @@ struct skb_hold_q { struct rxtid { bool aggr; - bool progress; bool timer_mon; u16 win_sz; u16 seq_next; diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 974c51053a71..7dfa0fd86d7b 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1186,28 +1186,25 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, aggr_deque_frms(agg_conn, tid, 0, 1); if (agg_conn->timer_scheduled) - rxtid->progress = true; - else { - spin_lock_bh(&rxtid->lock); - for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { - if (rxtid->hold_q[idx].skb) { - /* - * There is a frame in the queue and no - * timer so start a timer to ensure that - * the frame doesn't remain stuck - * forever. - */ - agg_conn->timer_scheduled = true; - mod_timer(&agg_conn->timer, - (jiffies + - HZ * (AGGR_RX_TIMEOUT) / 1000)); - rxtid->progress = false; - rxtid->timer_mon = true; - break; - } + return is_queued; + + spin_lock_bh(&rxtid->lock); + for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { + if (rxtid->hold_q[idx].skb) { + /* + * There is a frame in the queue and no + * timer so start a timer to ensure that + * the frame doesn't remain stuck + * forever. + */ + agg_conn->timer_scheduled = true; + mod_timer(&agg_conn->timer, + (jiffies + (HZ * AGGR_RX_TIMEOUT) / 1000)); + rxtid->timer_mon = true; + break; } - spin_unlock_bh(&rxtid->lock); } + spin_unlock_bh(&rxtid->lock); return is_queued; } @@ -1612,7 +1609,7 @@ static void aggr_timeout(unsigned long arg) rxtid = &aggr_conn->rx_tid[i]; stats = &aggr_conn->stat[i]; - if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) + if (!rxtid->aggr || !rxtid->timer_mon) continue; stats->num_timeouts++; @@ -1635,7 +1632,6 @@ static void aggr_timeout(unsigned long arg) if (rxtid->hold_q[j].skb) { aggr_conn->timer_scheduled = true; rxtid->timer_mon = true; - rxtid->progress = false; break; } } @@ -1666,7 +1662,6 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) aggr_deque_frms(aggr_conn, tid, 0, 0); rxtid->aggr = false; - rxtid->progress = false; rxtid->timer_mon = false; rxtid->win_sz = 0; rxtid->seq_next = 0; @@ -1745,7 +1740,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, for (i = 0; i < NUM_OF_TIDS; i++) { rxtid = &aggr_conn->rx_tid[i]; rxtid->aggr = false; - rxtid->progress = false; rxtid->timer_mon = false; skb_queue_head_init(&rxtid->q); spin_lock_init(&rxtid->lock); -- GitLab From b5b6f6a9a07ac230d54a85a9fb9e691c85f2eb0a Mon Sep 17 00:00:00 2001 From: Naveen Singh Date: Thu, 7 Jun 2012 00:44:02 -0700 Subject: [PATCH 1073/6849] ath6kl: use firmware version from FW IE Need to have different FW versioning for different FW binaries. This is handled by appending different meta data in firmware binaries. kvalo: add an empty line before a debug message, use '0' instead of '0x00', fix indentation Signed-off-by: Naveen Singh Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 8 ++++++++ drivers/net/wireless/ath/ath6kl/main.c | 22 +++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index daf24ee9d28a..62e25ccd1016 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -943,6 +943,14 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) } switch (ie_id) { + case ATH6KL_FW_IE_FW_VERSION: + strlcpy(ar->wiphy->fw_version, data, + sizeof(ar->wiphy->fw_version)); + + ath6kl_dbg(ATH6KL_DBG_BOOT, + "found fw version %s\n", + ar->wiphy->fw_version); + break; case ATH6KL_FW_IE_OTP_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", ie_len); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 3e6768ae80af..45621baca24a 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -554,20 +554,24 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, struct ath6kl *ar = devt; memcpy(ar->mac_addr, datap, ETH_ALEN); - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n", - __func__, ar->mac_addr); + + ath6kl_dbg(ATH6KL_DBG_BOOT, + "ready event mac addr %pM sw_ver 0x%x abi_ver 0x%x cap 0x%x\n", + ar->mac_addr, sw_ver, abi_ver, cap); ar->version.wlan_ver = sw_ver; ar->version.abi_ver = abi_ver; ar->hw.cap = cap; - snprintf(ar->wiphy->fw_version, - sizeof(ar->wiphy->fw_version), - "%u.%u.%u.%u", - (ar->version.wlan_ver & 0xf0000000) >> 28, - (ar->version.wlan_ver & 0x0f000000) >> 24, - (ar->version.wlan_ver & 0x00ff0000) >> 16, - (ar->version.wlan_ver & 0x0000ffff)); + if (strlen(ar->wiphy->fw_version) == 0) { + snprintf(ar->wiphy->fw_version, + sizeof(ar->wiphy->fw_version), + "%u.%u.%u.%u", + (ar->version.wlan_ver & 0xf0000000) >> 28, + (ar->version.wlan_ver & 0x0f000000) >> 24, + (ar->version.wlan_ver & 0x00ff0000) >> 16, + (ar->version.wlan_ver & 0x0000ffff)); + } /* indicate to the waiting thread that the ready event was received */ set_bit(WMI_READY, &ar->flag); -- GitLab From 80c0120a3cca30166c0ab8b24e44be67e97b79af Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 8 Jun 2012 11:47:51 -0300 Subject: [PATCH 1074/6849] perf tools: Fix endianity swapping for adds_features bitmask Based on Jiri's latest attempt: https://lkml.org/lkml/2012/5/16/61 Basically, adds_features should be byte swapped assuming unsigned longs are either 8-bytes (u64) or 4-bytes (u32). Fixes 32-bit ppc dumping 64-bit x86 feature data: ======== captured on: Sun May 20 19:23:23 2012 hostname : nxos-vdc-dev3 os release : 3.4.0-rc7+ perf version : 3.4.rc4.137.g978da3 arch : x86_64 nrcpus online : 16 nrcpus avail : 16 cpudesc : Intel(R) Xeon(R) CPU E5540 @ 2.53GHz cpuid : GenuineIntel,6,26,5 total memory : 24680324 kB ... Verified 64-bit x86 can still dump feature data for 32-bit ppc. Signed-off-by: David Ahern Reviewed-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/4FBBB539.5010805@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 16 +++++++++------- tools/perf/util/include/linux/bitops.h | 2 ++ tools/perf/util/session.c | 10 ++++++++++ tools/perf/util/session.h | 1 + 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 2dd5edf161b7..4f9b247fb312 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1942,7 +1942,6 @@ int perf_file_header__read(struct perf_file_header *header, else return -1; } else if (ph->needs_swap) { - unsigned int i; /* * feature bitmap is declared as an array of unsigned longs -- * not good since its size can differ between the host that @@ -1958,14 +1957,17 @@ int perf_file_header__read(struct perf_file_header *header, * file), punt and fallback to the original behavior -- * clearing all feature bits and setting buildid. */ - for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) - header->adds_features[i] = bswap_64(header->adds_features[i]); + mem_bswap_64(&header->adds_features, + BITS_TO_U64(HEADER_FEAT_BITS)); if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { - for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) { - header->adds_features[i] = bswap_64(header->adds_features[i]); - header->adds_features[i] = bswap_32(header->adds_features[i]); - } + /* unswap as u64 */ + mem_bswap_64(&header->adds_features, + BITS_TO_U64(HEADER_FEAT_BITS)); + + /* unswap as u32 */ + mem_bswap_32(&header->adds_features, + BITS_TO_U32(HEADER_FEAT_BITS)); } if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index f1584833bd22..587a230d2075 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h @@ -8,6 +8,8 @@ #define BITS_PER_LONG __WORDSIZE #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) +#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) #define for_each_set_bit(bit, addr, size) \ for ((bit) = find_first_bit((addr), (size)); \ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2600916efa83..c3e399bcf18d 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -442,6 +442,16 @@ static void perf_tool__fill_defaults(struct perf_tool *tool) tool->finished_round = process_finished_round_stub; } } + +void mem_bswap_32(void *src, int byte_size) +{ + u32 *m = src; + while (byte_size > 0) { + *m = bswap_32(*m); + byte_size -= sizeof(u32); + ++m; + } +} void mem_bswap_64(void *src, int byte_size) { diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7a5434c00565..0c702e3f0a36 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -80,6 +80,7 @@ struct branch_info *machine__resolve_bstack(struct machine *self, bool perf_session__has_traces(struct perf_session *self, const char *msg); void mem_bswap_64(void *src, int byte_size); +void mem_bswap_32(void *src, int byte_size); void perf_event__attr_swap(struct perf_event_attr *attr); int perf_session__create_kernel_maps(struct perf_session *self); -- GitLab From fc3e4d077d5c7a7bc1ad5bc143895b4e070e5a8b Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 15 May 2012 13:11:11 +0200 Subject: [PATCH 1075/6849] perf stat: Fix default output file The following commit: commit 56f3bae70638b33477a6015fd362ccfe354fd3ee Author: Jim Cromie Date: Wed Sep 7 17:14:00 2011 -0600 perf stat: Add --log-fd option to redirect stderr elsewhere introduced a bug in the way perf stat outputs the results by default, i.e., without the --log-fd or --output option. It would default to writing to file descriptor 0, i.e., stdin. Writing to stdin is allowed and is equivalent to writing to stdout. However, there is a major difference for any script that was already capturing the output of perf stat via redirection: perf stat >/tmp/log .... or perf stat 2>/tmp/log .... They would not capture anything anymore. They would have to do: perf stat 0>/tmp/log ... This breaks compatibility with existing scripts and does not look very natural. This patch fixes the problem by looking at output_fd only when it was modified by user (> 0). It also checks that the value if positive. Passing --log-fd 0 is ignored. I would also argue that defaulting to stderr for the results is not the right thing to do, though this patch does not address this specific issue. Signed-off-by: Stephane Eranian Cc: David Ahern Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Jim Cromie Link: http://lkml.kernel.org/r/20120515111111.GA9870@quad Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 262589991ea4..07b5c7703dd1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1179,6 +1179,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) fprintf(stderr, "cannot use both --output and --log-fd\n"); usage_with_options(stat_usage, options); } + + if (output_fd < 0) { + fprintf(stderr, "argument to --log-fd must be a > 0\n"); + usage_with_options(stat_usage, options); + } + if (!output) { struct timespec tm; mode = append_file ? "a" : "w"; @@ -1190,7 +1196,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) } clock_gettime(CLOCK_REALTIME, &tm); fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); - } else if (output_fd != 2) { + } else if (output_fd > 0) { mode = append_file ? "a" : "w"; output = fdopen(output_fd, mode); if (!output) { -- GitLab From 9c278d52903709543b4716b0e0d03ec58b179308 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 20 May 2012 07:46:40 +0900 Subject: [PATCH 1076/6849] ARM: EXYNOS: Add HSOTG support to Origen S3C-HSOTG device is added to Origen board. Signed-off-by: Sachin Kamat Signed-off-by: Tushar Behera Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/mach-origen.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 573be57d3d28..da025c8542bd 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -326,6 +326,7 @@ config MACH_ORIGEN select S3C_DEV_WDT select S3C_DEV_HSMMC select S3C_DEV_HSMMC2 + select S3C_DEV_USB_HSOTG select S5P_DEV_FIMC0 select S5P_DEV_FIMC1 select S5P_DEV_FIMC2 diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index f5572be9d7bf..9ed0229db8ae 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -499,6 +500,9 @@ static void __init origen_ohci_init(void) exynos4_ohci_set_platdata(pdata); } +/* USB OTG */ +static struct s3c_hsotg_plat origen_hsotg_pdata; + static struct gpio_keys_button origen_gpio_keys_table[] = { { .code = KEY_MENU, @@ -655,6 +659,7 @@ static struct platform_device *origen_devices[] __initdata = { &s3c_device_hsmmc0, &s3c_device_i2c0, &s3c_device_rtc, + &s3c_device_usb_hsotg, &s3c_device_wdt, &s5p_device_ehci, &s5p_device_fimc0, @@ -744,6 +749,7 @@ static void __init origen_machine_init(void) origen_ehci_init(); origen_ohci_init(); + s3c_hsotg_set_platdata(&origen_hsotg_pdata); clk_xusbxti.rate = 24000000; s5p_tv_setup(); -- GitLab From fb395c39307268baa324c2cdd009cd9b58fcf2ec Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 20 May 2012 07:46:44 +0900 Subject: [PATCH 1077/6849] ARM: EXYNOS: Add HSOTG support to SMDKV310 S3C-HSOTG device is added to SMDKV310 board. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/mach-smdkv310.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index da025c8542bd..f5fb6eaf9d85 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -207,6 +207,7 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S3C_DEV_USB_HSOTG select SAMSUNG_DEV_BACKLIGHT select EXYNOS_DEV_DRM select EXYNOS_DEV_SYSMMU diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index 262e9e446a96..7b1b86663e51 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -271,6 +272,9 @@ static void __init smdkv310_ohci_init(void) exynos4_ohci_set_platdata(pdata); } +/* USB OTG */ +static struct s3c_hsotg_plat smdkv310_hsotg_pdata; + static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_hsmmc0, &s3c_device_hsmmc1, @@ -279,6 +283,7 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_i2c1, &s5p_device_i2c_hdmiphy, &s3c_device_rtc, + &s3c_device_usb_hsotg, &s3c_device_wdt, &s5p_device_ehci, &s5p_device_fimc0, @@ -390,6 +395,7 @@ static void __init smdkv310_machine_init(void) smdkv310_ehci_init(); smdkv310_ohci_init(); + s3c_hsotg_set_platdata(&smdkv310_hsotg_pdata); clk_xusbxti.rate = 24000000; platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices)); -- GitLab From e35fca4791fcdd43dc1fd769797df40c562ab491 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Tue, 8 May 2012 20:40:12 -0300 Subject: [PATCH 1078/6849] edac: avoid mce decoding crash after edac driver unloaded Some edac drivers register themselves as mce decoders via notifier_chain. But in current notifier_chain implementation logic, it doesn't accept same notifier registered twice. If so, it will be wrong when adding/removing the element from the list. For example, on one SandyBridge platform, remove module sb_edac and then trigger one error, it will hit oops because it has no mce decoder registered but related notifier_chain still points to an invalid callback function. Here is an example: Call Trace: [] atomic_notifier_call_chain+0x1a/0x20 [] mce_log+0x46/0x180 [] apei_mce_report_mem_error+0x4a/0x60 [] ghes_do_proc+0x192/0x210 [] ghes_proc+0x46/0x70 [] ghes_notify_sci+0x48/0x80 [] notifier_call_chain+0x55/0x80 [] __blocking_notifier_call_chain+0x5a/0x80 [] ? acpi_os_wait_events_complete+0x23/0x23 [] blocking_notifier_call_chain+0x16/0x20 [] acpi_hed_notify+0x19/0x1b [] acpi_device_notify+0x19/0x1b [] acpi_ev_notify_dispatch+0x67/0x7f [] acpi_os_execute_deferred+0x29/0x36 [] process_one_work+0x132/0x450 [] worker_thread+0x17b/0x3c0 [] ? manage_workers+0x120/0x120 [] kthread+0x9e/0xb0 [] kernel_thread_helper+0x4/0x10 [] ? kthread_freezable_should_stop+0x70/0x70 [] ? gs_change+0x13/0x13 Code: f3 49 89 d4 45 85 ed 4d 89 c6 48 8b 0f 74 48 48 85 c9 75 17 eb 41 0f 1f 80 00 00 00 00 41 83 ed 01 4c 89 f9 74 22 4d 85 ff 74 1d <4c> 8b 79 08 4c 89 e2 48 89 de 48 89 cf ff 11 4d 85 f6 74 04 41 RIP [] notifier_call_chain+0x46/0x80 RSP CR2: ffffffffa01af838 ---[ end trace 0100930068e73e6f ]--- BUG: unable to handle kernel paging request at fffffffffffffff8 IP: [] kthread_data+0x10/0x20 PGD 1a0d067 PUD 1a0e067 PMD 0 Oops: 0000 [#2] SMP Only i7core_edac and sb_edac have such issues because they have more than one memory controller which means they have to register mce decoder many times. Cc: # 3.2 and upper Signed-off-by: Chen Gong Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 15 ++++----------- drivers/edac/sb_edac.c | 8 ++++---- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index d27778f65a5d..a499c7ed820a 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1814,12 +1814,6 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, if (mce->bank != 8) return NOTIFY_DONE; -#ifdef CONFIG_SMP - /* Only handle if it is the right mc controller */ - if (mce->socketid != pvt->i7core_dev->socket) - return NOTIFY_DONE; -#endif - smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { smp_wmb(); @@ -2116,8 +2110,6 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev) if (pvt->enable_scrub) disable_sdram_scrub_setting(mci); - mce_unregister_decode_chain(&i7_mce_dec); - /* Disable EDAC polling */ i7core_pci_ctl_release(pvt); @@ -2222,8 +2214,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev) /* DCLK for scrub rate setting */ pvt->dclk_freq = get_dclk_freq(); - mce_register_decode_chain(&i7_mce_dec); - return 0; fail0: @@ -2367,8 +2357,10 @@ static int __init i7core_init(void) pci_rc = pci_register_driver(&i7core_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&i7_mce_dec); return 0; + } i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -2384,6 +2376,7 @@ static void __exit i7core_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&i7core_driver); + mce_unregister_decode_chain(&i7_mce_dec); } module_init(i7core_init); diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 4adaf4b7da99..a21ace0b709d 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -1604,8 +1604,6 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", __func__, mci, &sbridge_dev->pdev[0]->dev); - mce_unregister_decode_chain(&sbridge_mce_dec); - /* Remove MC sysfs nodes */ edac_mc_del_mc(mci->dev); @@ -1682,7 +1680,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev) goto fail0; } - mce_register_decode_chain(&sbridge_mce_dec); return 0; fail0: @@ -1811,8 +1808,10 @@ static int __init sbridge_init(void) pci_rc = pci_register_driver(&sbridge_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&sbridge_mce_dec); return 0; + } sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -1828,6 +1827,7 @@ static void __exit sbridge_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&sbridge_driver); + mce_unregister_decode_chain(&sbridge_mce_dec); } module_init(sbridge_init); -- GitLab From 2cbb587d3bc41a305168e91b4f3c5b6944a12566 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Mon, 14 May 2012 05:51:26 -0300 Subject: [PATCH 1079/6849] edac: fix the error about memory type detection on SandyBridge On SandyBridge, DDRIOA(Dev: 17 Func: 0 Offset: 328) is used to detect whether DIMM is RDIMM/LRDIMM, not TA(Dev: 15 Func: 0). Signed-off-by: Chen Gong Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/sb_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index a21ace0b709d..36ad17e79d61 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -555,7 +555,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->is_close_pg = false; } - pci_read_config_dword(pvt->pci_ta, RANK_CFG_A, ®); + pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); if (IS_RDIMM_ENABLED(reg)) { /* FIXME: Can also be LRDIMM */ debugf0("Memory is registered\n"); -- GitLab From b9bc5ddb1b76d3f7ee14c533300aa95907c6969e Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 6 Jun 2012 19:49:42 -0500 Subject: [PATCH 1080/6849] mpc85xx_edac: fix error: too few arguments to function 'edac_mc_alloc' commit ca0907b "edac: Remove the legacy EDAC ABI" broke mpc85xx_edac in the following manner: mpc85xx_edac.c:983:35: error: too few arguments to function 'edac_mc_alloc' this patch puts back the missing 'layers' argument. [mchehab@redhat.com: As Ben sent a similar fix, I added his SOB on this patch] Signed-off-by: Kim Phillips Signed-off-by: Ben Collins Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/mpc85xx_edac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4c402353ba98..0e374625f6f8 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -980,7 +980,8 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = 1; layers[1].is_virt_csrow = false; - mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), sizeof(*pdata)); + mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers, + sizeof(*pdata)); if (!mci) { devres_release_group(&op->dev, mpc85xx_mc_err_probe); return -ENOMEM; -- GitLab From cef28271be62e672637f1ba2a019a5a9a981eb2d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 11 Jun 2012 11:34:18 +0200 Subject: [PATCH 1081/6849] mac80211: remove unneeded ieee80211_run_deferred_scan() Ilan pointed out to me that ieee80211_start_next_roc() already calls ieee80211_run_deferred_scan() if the list of ROC items is empty, so there's no need to call it again after calling ieee80211_start_next_roc(). Reported-by: Ilan Peer Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 1 - net/mac80211/offchannel.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f41f9bea242a..93d203cf8c12 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2330,7 +2330,6 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, list_del(&found->list); - ieee80211_run_deferred_scan(local); ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index abb226dc4753..fcb01ee8ee7b 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -379,7 +379,6 @@ void ieee80211_sw_roc_work(struct work_struct *work) ieee80211_recalc_idle(local); ieee80211_start_next_roc(local); - ieee80211_run_deferred_scan(local); } out_unlock: @@ -410,9 +409,6 @@ static void ieee80211_hw_roc_done(struct work_struct *work) /* if there's another roc, start it now */ ieee80211_start_next_roc(local); - /* or scan maybe */ - ieee80211_run_deferred_scan(local); - out_unlock: mutex_unlock(&local->mtx); } @@ -455,7 +451,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) } ieee80211_start_next_roc(local); - ieee80211_run_deferred_scan(local); mutex_unlock(&local->mtx); list_for_each_entry_safe(roc, tmp, &tmp_list, list) { -- GitLab From 5fcb08befaf57faa1b00e514915c1660252b8c26 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 11 Jun 2012 10:18:13 -0500 Subject: [PATCH 1082/6849] 9p: BUG before corrupting memory The BUG_ON() in pack_sg_list() would get triggered only one time after we've corrupted some memory by sg_set_buf() into an invalid sg buffer. I'm still working on figuring out why I manage to trigger that bug... Signed-off-by: Sasha Levin Signed-off-by: Eric Van Hensbergen --- net/9p/trans_virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 5af18d11b518..2a167658bb95 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -192,10 +192,10 @@ static int pack_sg_list(struct scatterlist *sg, int start, s = rest_of_page(data); if (s > count) s = count; + BUG_ON(index > limit); sg_set_buf(&sg[index++], data, s); count -= s; data += s; - BUG_ON(index > limit); } return index-start; -- GitLab From afb6a6a01b51b6712485ea045e2b882061d250d9 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 24 May 2012 11:44:22 -0500 Subject: [PATCH 1083/6849] staging: omapdrm: fix crash when freeing bad fb During unload, don't cleanup the framebuffer if it is not valid. Signed-off-by: Andy Gross Reviewed-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_fbdev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c index 11acd4c35ed2..8c6ed3b0c6f6 100644 --- a/drivers/staging/omapdrm/omap_fbdev.c +++ b/drivers/staging/omapdrm/omap_fbdev.c @@ -208,7 +208,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, */ ret = omap_gem_get_paddr(fbdev->bo, &paddr, true); if (ret) { - dev_err(dev->dev, "could not map (paddr)!\n"); + dev_err(dev->dev, + "could not map (paddr)! Skipping framebuffer alloc\n"); ret = -ENOMEM; goto fail; } @@ -388,8 +389,11 @@ void omap_fbdev_free(struct drm_device *dev) fbi = helper->fbdev; - unregister_framebuffer(fbi); - framebuffer_release(fbi); + /* only cleanup framebuffer if it is present */ + if (fbi) { + unregister_framebuffer(fbi); + framebuffer_release(fbi); + } drm_fb_helper_fini(helper); -- GitLab From 8447c4d15e357a458c9051ddc84aa6c8b9c27000 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 6 Jun 2012 13:11:05 -0400 Subject: [PATCH 1084/6849] edac: Do alignment logic properly in edac_align_ptr() The logic was checking the sizeof the structure being allocated to determine whether an alignment fixup was required. This isn't right; what we actually care about is the alignment of the actual pointer that's about to be returned. This became an issue recently because struct edac_mc_layer has a size that is not zero modulo eight, so we were taking the correctly-aligned pointer and forcing it to be misaligned. On Tile this caused an alignment exception. Signed-off-by: Chris Metcalf Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_mc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 10f375032e96..de5ba86e8b89 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -164,7 +164,7 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) else return (char *)ptr; - r = size % align; + r = (unsigned long)p % align; if (r == 0) return (char *)ptr; -- GitLab From ef4459341a600703e99a08584350809a96b62371 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 24 May 2012 11:43:32 -0500 Subject: [PATCH 1085/6849] staging: omapdrm: Fix error paths during dmm init Failures during the dmm probe can cause the kernel to crash. Moved the spinlock to a global and moved list initializations immediately after the allocation of the dmm private structure. Signed-off-by: Andy Gross Reviewed-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_priv.h | 1 - drivers/staging/omapdrm/omap_dmm_tiler.c | 44 +++++++++++++----------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h index 2f529ab4b7c7..08b22e9f0ed7 100644 --- a/drivers/staging/omapdrm/omap_dmm_priv.h +++ b/drivers/staging/omapdrm/omap_dmm_priv.h @@ -181,7 +181,6 @@ struct dmm { /* allocation list and lock */ struct list_head alloc_head; - spinlock_t list_lock; }; #endif diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 9d83060e753a..86197831f63e 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -40,6 +40,9 @@ static struct tcm *containers[TILFMT_NFORMATS]; static struct dmm *omap_dmm; +/* global spinlock for protecting lists */ +static DEFINE_SPINLOCK(list_lock); + /* Geometry table */ #define GEOM(xshift, yshift, bytes_per_pixel) { \ .x_shft = (xshift), \ @@ -147,13 +150,13 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm) down(&dmm->engine_sem); /* grab an idle engine */ - spin_lock(&dmm->list_lock); + spin_lock(&list_lock); if (!list_empty(&dmm->idle_head)) { engine = list_entry(dmm->idle_head.next, struct refill_engine, idle_node); list_del(&engine->idle_node); } - spin_unlock(&dmm->list_lock); + spin_unlock(&list_lock); BUG_ON(!engine); @@ -256,9 +259,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) } cleanup: - spin_lock(&dmm->list_lock); + spin_lock(&list_lock); list_add(&engine->idle_node, &dmm->idle_head); - spin_unlock(&dmm->list_lock); + spin_unlock(&list_lock); up(&omap_dmm->engine_sem); return ret; @@ -351,9 +354,9 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, } /* add to allocation list */ - spin_lock(&omap_dmm->list_lock); + spin_lock(&list_lock); list_add(&block->alloc_node, &omap_dmm->alloc_head); - spin_unlock(&omap_dmm->list_lock); + spin_unlock(&list_lock); return block; } @@ -374,9 +377,9 @@ struct tiler_block *tiler_reserve_1d(size_t size) return ERR_PTR(-ENOMEM); } - spin_lock(&omap_dmm->list_lock); + spin_lock(&list_lock); list_add(&block->alloc_node, &omap_dmm->alloc_head); - spin_unlock(&omap_dmm->list_lock); + spin_unlock(&list_lock); return block; } @@ -389,9 +392,9 @@ int tiler_release(struct tiler_block *block) if (block->area.tcm) dev_err(omap_dmm->dev, "failed to release block\n"); - spin_lock(&omap_dmm->list_lock); + spin_lock(&list_lock); list_del(&block->alloc_node); - spin_unlock(&omap_dmm->list_lock); + spin_unlock(&list_lock); kfree(block); return ret; @@ -479,13 +482,13 @@ static int omap_dmm_remove(struct platform_device *dev) if (omap_dmm) { /* free all area regions */ - spin_lock(&omap_dmm->list_lock); + spin_lock(&list_lock); list_for_each_entry_safe(block, _block, &omap_dmm->alloc_head, alloc_node) { list_del(&block->alloc_node); kfree(block); } - spin_unlock(&omap_dmm->list_lock); + spin_unlock(&list_lock); for (i = 0; i < omap_dmm->num_lut; i++) if (omap_dmm->tcm && omap_dmm->tcm[i]) @@ -503,7 +506,7 @@ static int omap_dmm_remove(struct platform_device *dev) vfree(omap_dmm->lut); - if (omap_dmm->irq != -1) + if (omap_dmm->irq > 0) free_irq(omap_dmm->irq, omap_dmm); iounmap(omap_dmm->base); @@ -527,6 +530,10 @@ static int omap_dmm_probe(struct platform_device *dev) goto fail; } + /* initialize lists */ + INIT_LIST_HEAD(&omap_dmm->alloc_head); + INIT_LIST_HEAD(&omap_dmm->idle_head); + /* lookup hwmod data - base address and irq */ mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!mem) { @@ -629,7 +636,6 @@ static int omap_dmm_probe(struct platform_device *dev) } sema_init(&omap_dmm->engine_sem, omap_dmm->num_engines); - INIT_LIST_HEAD(&omap_dmm->idle_head); for (i = 0; i < omap_dmm->num_engines; i++) { omap_dmm->engines[i].id = i; omap_dmm->engines[i].dmm = omap_dmm; @@ -672,9 +678,6 @@ static int omap_dmm_probe(struct platform_device *dev) containers[TILFMT_32BIT] = omap_dmm->tcm[0]; containers[TILFMT_PAGE] = omap_dmm->tcm[0]; - INIT_LIST_HEAD(&omap_dmm->alloc_head); - spin_lock_init(&omap_dmm->list_lock); - area = (struct tcm_area) { .is2d = true, .tcm = NULL, @@ -697,7 +700,8 @@ static int omap_dmm_probe(struct platform_device *dev) return 0; fail: - omap_dmm_remove(dev); + if (omap_dmm_remove(dev)) + dev_err(&dev->dev, "cleanup failed\n"); return ret; } @@ -810,7 +814,7 @@ int tiler_map_show(struct seq_file *s, void *arg) map[i] = global_map + i * (w_adj + 1); map[i][w_adj] = 0; } - spin_lock_irqsave(&omap_dmm->list_lock, flags); + spin_lock_irqsave(&list_lock, flags); list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { if (block->fmt != TILFMT_PAGE) { @@ -836,7 +840,7 @@ int tiler_map_show(struct seq_file *s, void *arg) } } - spin_unlock_irqrestore(&omap_dmm->list_lock, flags); + spin_unlock_irqrestore(&list_lock, flags); if (s) { seq_printf(s, "BEGIN DMM TILER MAP\n"); -- GitLab From 397d3e6029cb816d7a9a78531528a62d08c70d3f Mon Sep 17 00:00:00 2001 From: Adnan Ali Date: Fri, 25 May 2012 18:56:40 +0100 Subject: [PATCH 1086/6849] Staging: et131x: fix coding style issues This commit fixes coding style issues including braces position and line wrapping. Signed-off-by: Adnan Ali Reviewed-by: Jannis Pohlmann Acked-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 5b11c5e3622e..cf02336ffbdc 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -85,8 +85,7 @@ MODULE_AUTHOR("Victor Soriano "); MODULE_AUTHOR("Mark Einon "); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver " - "for the ET1310 by Agere Systems"); +MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere Systems"); /* EEPROM defines */ #define MAX_NUM_REGISTER_POLLS 1000 @@ -2967,11 +2966,10 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) (ring_index == 0 && buff_index > rx_local->fbr[1]->num_entries - 1) || (ring_index == 1 && - buff_index > rx_local->fbr[0]->num_entries - 1)) + buff_index > rx_local->fbr[0]->num_entries - 1)) { #else - if (ring_index != 1 || buff_index > rx_local->fbr[0]->num_entries - 1) + if (ring_index != 1 || buff_index > rx_local->fbr[0]->num_entries - 1) { #endif - { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&adapter->pdev->dev, "NICRxPkts PSR Entry %d indicates " @@ -4326,8 +4324,7 @@ static int et131x_mii_probe(struct net_device *netdev) phydev->advertising = phydev->supported; adapter->phydev = phydev; - dev_info(&adapter->pdev->dev, "attached PHY driver [%s] " - "(mii_bus:phy_addr=%s)\n", + dev_info(&adapter->pdev->dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", phydev->drv->name, dev_name(&phydev->dev)); return 0; -- GitLab From b5b86a4d99f48e5ac28c19ae2a00415e26a7ac1a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Jun 2012 12:17:01 +0300 Subject: [PATCH 1087/6849] Staging: et131x: fix | vs & typos These two places seem like they should be using bitwise OR instead of bitwise AND. The first one is a noop which is equivalent to: imr |= (0x0100 & 0x0004 & 0x0001); The second is sets lcr2 to zero instead of just clearing the high bits. lcr2 &= (0x00F0 & 0x000F); Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index cf02336ffbdc..8f3fc5f85ec9 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1766,8 +1766,8 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) /* Set the link status interrupt only. Bad behavior when link status * and auto neg are set, we run into a nested interrupt problem */ - imr |= (ET_PHY_INT_MASK_AUTONEGSTAT & - ET_PHY_INT_MASK_LINKSTAT & + imr |= (ET_PHY_INT_MASK_AUTONEGSTAT | + ET_PHY_INT_MASK_LINKSTAT | ET_PHY_INT_MASK_ENABLE); et131x_mii_write(adapter, PHY_INTERRUPT_MASK, imr); @@ -1783,7 +1783,7 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) if ((adapter->eeprom_data[1] & 0x4) == 0) { et131x_mii_read(adapter, PHY_LED_2, &lcr2); - lcr2 &= (ET_LED2_LED_100TX & ET_LED2_LED_1000T); + lcr2 &= (ET_LED2_LED_100TX | ET_LED2_LED_1000T); lcr2 |= (LED_VAL_LINKON_ACTIVE << LED_LINK_SHIFT); if ((adapter->eeprom_data[1] & 0x8) == 0) -- GitLab From c234434835b1f4bad9bdbae6710044cba387c9e5 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Fri, 8 Jun 2012 15:39:25 +0900 Subject: [PATCH 1088/6849] staging: zsmalloc: zsmalloc: use unsigned long instead of void * We should use unsigned long as handle instead of void * to avoid any confusion. Without this, users may just treat zs_malloc return value as a pointer and try to deference it. This patch passed compile test(zram, zcache and ramster) and zram is tested on qemu. changelog * from v2 - remove hval pointed out by Nitin - based on next-20120607 * from v1 - change zcache's zv_create return value - baesd on next-20120604 Cc: Dan Magenheimer Acked-by: Seth Jennings Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 12 +++++----- drivers/staging/zram/zram_drv.c | 16 +++++++------- drivers/staging/zram/zram_drv.h | 2 +- drivers/staging/zsmalloc/zsmalloc-main.c | 28 +++++++++++------------- drivers/staging/zsmalloc/zsmalloc.h | 8 +++---- 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 2734dacacbaf..d0141fbc649e 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -693,14 +693,14 @@ static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; static atomic_t zv_curr_dist_counts[NCHUNKS]; static atomic_t zv_cumul_dist_counts[NCHUNKS]; -static struct zv_hdr *zv_create(struct zs_pool *pool, uint32_t pool_id, +static unsigned long zv_create(struct zs_pool *pool, uint32_t pool_id, struct tmem_oid *oid, uint32_t index, void *cdata, unsigned clen) { struct zv_hdr *zv; u32 size = clen + sizeof(struct zv_hdr); int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - void *handle = NULL; + unsigned long handle = 0; BUG_ON(!irqs_disabled()); BUG_ON(chunks >= NCHUNKS); @@ -721,7 +721,7 @@ out: return handle; } -static void zv_free(struct zs_pool *pool, void *handle) +static void zv_free(struct zs_pool *pool, unsigned long handle) { unsigned long flags; struct zv_hdr *zv; @@ -743,7 +743,7 @@ static void zv_free(struct zs_pool *pool, void *handle) local_irq_restore(flags); } -static void zv_decompress(struct page *page, void *handle) +static void zv_decompress(struct page *page, unsigned long handle) { unsigned int clen = PAGE_SIZE; char *to_va; @@ -1247,7 +1247,7 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, int ret = 0; BUG_ON(is_ephemeral(pool)); - zv_decompress((struct page *)(data), pampd); + zv_decompress((struct page *)(data), (unsigned long)pampd); return ret; } @@ -1282,7 +1282,7 @@ static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, atomic_dec(&zcache_curr_eph_pampd_count); BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); } else { - zv_free(cli->zspool, pampd); + zv_free(cli->zspool, (unsigned long)pampd); atomic_dec(&zcache_curr_pers_pampd_count); BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); } diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 685d612a627b..abd69d13d0a1 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -135,7 +135,7 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes) static void zram_free_page(struct zram *zram, size_t index) { - void *handle = zram->table[index].handle; + unsigned long handle = zram->table[index].handle; if (unlikely(!handle)) { /* @@ -150,7 +150,7 @@ static void zram_free_page(struct zram *zram, size_t index) } if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - __free_page(handle); + __free_page((struct page *)handle); zram_clear_flag(zram, index, ZRAM_UNCOMPRESSED); zram_stat_dec(&zram->stats.pages_expand); goto out; @@ -166,7 +166,7 @@ out: zram->table[index].size); zram_stat_dec(&zram->stats.pages_stored); - zram->table[index].handle = NULL; + zram->table[index].handle = 0; zram->table[index].size = 0; } @@ -189,7 +189,7 @@ static void handle_uncompressed_page(struct zram *zram, struct bio_vec *bvec, unsigned char *user_mem, *cmem; user_mem = kmap_atomic(page); - cmem = kmap_atomic(zram->table[index].handle); + cmem = kmap_atomic((struct page *)zram->table[index].handle); memcpy(user_mem + bvec->bv_offset, cmem + offset, bvec->bv_len); kunmap_atomic(cmem); @@ -317,7 +317,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, int ret; u32 store_offset; size_t clen; - void *handle; + unsigned long handle; struct zobj_header *zheader; struct page *page, *page_store; unsigned char *user_mem, *cmem, *src, *uncmem = NULL; @@ -399,7 +399,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, store_offset = 0; zram_set_flag(zram, index, ZRAM_UNCOMPRESSED); zram_stat_inc(&zram->stats.pages_expand); - handle = page_store; + handle = (unsigned long)page_store; src = kmap_atomic(page); cmem = kmap_atomic(page_store); goto memstore; @@ -592,12 +592,12 @@ void __zram_reset_device(struct zram *zram) /* Free all pages that are still in this zram device */ for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) { - void *handle = zram->table[index].handle; + unsigned long handle = zram->table[index].handle; if (!handle) continue; if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) - __free_page(handle); + __free_page((struct page *)handle); else zs_free(zram->mem_pool, handle); } diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index fbe8ac98704c..7a7e25664826 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -81,7 +81,7 @@ enum zram_pageflags { /* Allocated for each disk page */ struct table { - void *handle; + unsigned long handle; u16 size; /* object size (excluding header) */ u8 count; /* object ref count (not yet used) */ u8 flags; diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 449673773286..8e830eeca729 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -247,13 +247,11 @@ static void *obj_location_to_handle(struct page *page, unsigned long obj_idx) } /* Decode pair from the given object handle */ -static void obj_handle_to_location(void *handle, struct page **page, +static void obj_handle_to_location(unsigned long handle, struct page **page, unsigned long *obj_idx) { - unsigned long hval = (unsigned long)handle; - - *page = pfn_to_page(hval >> OBJ_INDEX_BITS); - *obj_idx = hval & OBJ_INDEX_MASK; + *page = pfn_to_page(handle >> OBJ_INDEX_BITS); + *obj_idx = handle & OBJ_INDEX_MASK; } static unsigned long obj_idx_to_offset(struct page *page, @@ -568,12 +566,12 @@ EXPORT_SYMBOL_GPL(zs_destroy_pool); * @size: size of block to allocate * * On success, handle to the allocated object is returned, - * otherwise NULL. + * otherwise 0. * Allocation requests with size > ZS_MAX_ALLOC_SIZE will fail. */ -void *zs_malloc(struct zs_pool *pool, size_t size) +unsigned long zs_malloc(struct zs_pool *pool, size_t size) { - void *obj; + unsigned long obj; struct link_free *link; int class_idx; struct size_class *class; @@ -582,7 +580,7 @@ void *zs_malloc(struct zs_pool *pool, size_t size) unsigned long m_objidx, m_offset; if (unlikely(!size || size > ZS_MAX_ALLOC_SIZE)) - return NULL; + return 0; class_idx = get_size_class_index(size); class = &pool->size_class[class_idx]; @@ -595,14 +593,14 @@ void *zs_malloc(struct zs_pool *pool, size_t size) spin_unlock(&class->lock); first_page = alloc_zspage(class, pool->flags); if (unlikely(!first_page)) - return NULL; + return 0; set_zspage_mapping(first_page, class->index, ZS_EMPTY); spin_lock(&class->lock); class->pages_allocated += class->pages_per_zspage; } - obj = first_page->freelist; + obj = (unsigned long)first_page->freelist; obj_handle_to_location(obj, &m_page, &m_objidx); m_offset = obj_idx_to_offset(m_page, m_objidx, class->size); @@ -621,7 +619,7 @@ void *zs_malloc(struct zs_pool *pool, size_t size) } EXPORT_SYMBOL_GPL(zs_malloc); -void zs_free(struct zs_pool *pool, void *obj) +void zs_free(struct zs_pool *pool, unsigned long obj) { struct link_free *link; struct page *first_page, *f_page; @@ -648,7 +646,7 @@ void zs_free(struct zs_pool *pool, void *obj) + f_offset); link->next = first_page->freelist; kunmap_atomic(link); - first_page->freelist = obj; + first_page->freelist = (void *)obj; first_page->inuse--; fullness = fix_fullness_group(pool, first_page); @@ -672,7 +670,7 @@ EXPORT_SYMBOL_GPL(zs_free); * this function. When done with the object, it must be unmapped using * zs_unmap_object */ -void *zs_map_object(struct zs_pool *pool, void *handle) +void *zs_map_object(struct zs_pool *pool, unsigned long handle) { struct page *page; unsigned long obj_idx, off; @@ -712,7 +710,7 @@ void *zs_map_object(struct zs_pool *pool, void *handle) } EXPORT_SYMBOL_GPL(zs_map_object); -void zs_unmap_object(struct zs_pool *pool, void *handle) +void zs_unmap_object(struct zs_pool *pool, unsigned long handle) { struct page *page; unsigned long obj_idx, off; diff --git a/drivers/staging/zsmalloc/zsmalloc.h b/drivers/staging/zsmalloc/zsmalloc.h index 949384ee7491..485cbb1a5ac8 100644 --- a/drivers/staging/zsmalloc/zsmalloc.h +++ b/drivers/staging/zsmalloc/zsmalloc.h @@ -20,11 +20,11 @@ struct zs_pool; struct zs_pool *zs_create_pool(const char *name, gfp_t flags); void zs_destroy_pool(struct zs_pool *pool); -void *zs_malloc(struct zs_pool *pool, size_t size); -void zs_free(struct zs_pool *pool, void *obj); +unsigned long zs_malloc(struct zs_pool *pool, size_t size); +void zs_free(struct zs_pool *pool, unsigned long obj); -void *zs_map_object(struct zs_pool *pool, void *handle); -void zs_unmap_object(struct zs_pool *pool, void *handle); +void *zs_map_object(struct zs_pool *pool, unsigned long handle); +void zs_unmap_object(struct zs_pool *pool, unsigned long handle); u64 zs_get_total_size_bytes(struct zs_pool *pool); -- GitLab From 374a69191d12a0525b7ffe1197abc30c4795a230 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Fri, 8 Jun 2012 15:39:26 +0900 Subject: [PATCH 1089/6849] staging: zram: fix random data read fd1a30de makes a bug that it uses (struct page *) as zsmalloc's handle although it's a uncompressed page so that it can access random page, return random data or even crashed by get_first_page in zs_map_object. Cc: Seth Jennings Cc: Jerome Marchand Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index abd69d13d0a1..0cdc303ad565 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -280,26 +280,27 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) size_t clen = PAGE_SIZE; struct zobj_header *zheader; unsigned char *cmem; + unsigned long handle = zram->table[index].handle; - if (zram_test_flag(zram, index, ZRAM_ZERO) || - !zram->table[index].handle) { + if (zram_test_flag(zram, index, ZRAM_ZERO) || !handle) { memset(mem, 0, PAGE_SIZE); return 0; } - cmem = zs_map_object(zram->mem_pool, zram->table[index].handle); - /* Page is stored uncompressed since it's incompressible */ if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - memcpy(mem, cmem, PAGE_SIZE); - kunmap_atomic(cmem); + char *src = kmap_atomic((struct page *)handle); + memcpy(mem, src, PAGE_SIZE); + kunmap_atomic(src); return 0; } + cmem = zs_map_object(zram->mem_pool, handle); + ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), zram->table[index].size, mem, &clen); - zs_unmap_object(zram->mem_pool, zram->table[index].handle); + zs_unmap_object(zram->mem_pool, handle); /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret != LZO_E_OK)) { -- GitLab From 130f315a174d127cbb90d4d1a4a7088dbcf930b5 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Fri, 8 Jun 2012 15:39:27 +0900 Subject: [PATCH 1090/6849] staging: zram: remove special handle of uncompressed page xvmalloc can't handle PAGE_SIZE page so that zram have to handle it specially but zsmalloc can do it so let's remove unnecessary special handling code. Quote from Nitin "I think page vs handle distinction was added since xvmalloc could not handle full page allocation. Now that zsmalloc allows full page allocation, we can just use it for both cases. This would also allow removing the ZRAM_UNCOMPRESSED flag. The only downside will be slightly slower code path for full page allocation but this event is anyways supposed to be rare, so should be fine." 1. This patch reduces code very much. drivers/staging/zram/zram_drv.c | 104 +++++-------------------------------- drivers/staging/zram/zram_drv.h | 17 +----- drivers/staging/zram/zram_sysfs.c | 6 +-- 3 files changed, 15 insertions(+), 112 deletions(-) 2. change pages_expand with bad_compress so it can count bad compression(above 75%) ratio. 3. remove zobj_header which is for back-reference for defragmentation because firstly, it's not used at the moment and zsmalloc can't handle bigger size than PAGE_SIZE so zram can't do it any more without redesign. Cc: Seth Jennings Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 104 ++++-------------------------- drivers/staging/zram/zram_drv.h | 17 +---- drivers/staging/zram/zram_sysfs.c | 6 +- 3 files changed, 15 insertions(+), 112 deletions(-) diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 0cdc303ad565..2036a901628b 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -136,6 +136,7 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes) static void zram_free_page(struct zram *zram, size_t index) { unsigned long handle = zram->table[index].handle; + u16 size = zram->table[index].size; if (unlikely(!handle)) { /* @@ -149,19 +150,14 @@ static void zram_free_page(struct zram *zram, size_t index) return; } - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - __free_page((struct page *)handle); - zram_clear_flag(zram, index, ZRAM_UNCOMPRESSED); - zram_stat_dec(&zram->stats.pages_expand); - goto out; - } + if (unlikely(size > max_zpage_size)) + zram_stat_dec(&zram->stats.bad_compress); zs_free(zram->mem_pool, handle); - if (zram->table[index].size <= PAGE_SIZE / 2) + if (size <= PAGE_SIZE / 2) zram_stat_dec(&zram->stats.good_compress); -out: zram_stat64_sub(zram, &zram->stats.compr_size, zram->table[index].size); zram_stat_dec(&zram->stats.pages_stored); @@ -182,22 +178,6 @@ static void handle_zero_page(struct bio_vec *bvec) flush_dcache_page(page); } -static void handle_uncompressed_page(struct zram *zram, struct bio_vec *bvec, - u32 index, int offset) -{ - struct page *page = bvec->bv_page; - unsigned char *user_mem, *cmem; - - user_mem = kmap_atomic(page); - cmem = kmap_atomic((struct page *)zram->table[index].handle); - - memcpy(user_mem + bvec->bv_offset, cmem + offset, bvec->bv_len); - kunmap_atomic(cmem); - kunmap_atomic(user_mem); - - flush_dcache_page(page); -} - static inline int is_partial_io(struct bio_vec *bvec) { return bvec->bv_len != PAGE_SIZE; @@ -209,7 +189,6 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, int ret; size_t clen; struct page *page; - struct zobj_header *zheader; unsigned char *user_mem, *cmem, *uncmem = NULL; page = bvec->bv_page; @@ -227,12 +206,6 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, return 0; } - /* Page is stored uncompressed since it's incompressible */ - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - handle_uncompressed_page(zram, bvec, index, offset); - return 0; - } - if (is_partial_io(bvec)) { /* Use a temporary buffer to decompress the page */ uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); @@ -249,8 +222,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, cmem = zs_map_object(zram->mem_pool, zram->table[index].handle); - ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), - zram->table[index].size, + ret = lzo1x_decompress_safe(cmem, zram->table[index].size, uncmem, &clen); if (is_partial_io(bvec)) { @@ -278,7 +250,6 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) { int ret; size_t clen = PAGE_SIZE; - struct zobj_header *zheader; unsigned char *cmem; unsigned long handle = zram->table[index].handle; @@ -287,18 +258,8 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) return 0; } - /* Page is stored uncompressed since it's incompressible */ - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - char *src = kmap_atomic((struct page *)handle); - memcpy(mem, src, PAGE_SIZE); - kunmap_atomic(src); - return 0; - } - cmem = zs_map_object(zram->mem_pool, handle); - - ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), - zram->table[index].size, + ret = lzo1x_decompress_safe(cmem, zram->table[index].size, mem, &clen); zs_unmap_object(zram->mem_pool, handle); @@ -316,11 +277,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, int offset) { int ret; - u32 store_offset; size_t clen; unsigned long handle; - struct zobj_header *zheader; - struct page *page, *page_store; + struct page *page; unsigned char *user_mem, *cmem, *src, *uncmem = NULL; page = bvec->bv_page; @@ -382,31 +341,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, goto out; } - /* - * Page is incompressible. Store it as-is (uncompressed) - * since we do not want to return too many disk write - * errors which has side effect of hanging the system. - */ - if (unlikely(clen > max_zpage_size)) { - clen = PAGE_SIZE; - page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM); - if (unlikely(!page_store)) { - pr_info("Error allocating memory for " - "incompressible page: %u\n", index); - ret = -ENOMEM; - goto out; - } + if (unlikely(clen > max_zpage_size)) + zram_stat_inc(&zram->stats.bad_compress); - store_offset = 0; - zram_set_flag(zram, index, ZRAM_UNCOMPRESSED); - zram_stat_inc(&zram->stats.pages_expand); - handle = (unsigned long)page_store; - src = kmap_atomic(page); - cmem = kmap_atomic(page_store); - goto memstore; - } - - handle = zs_malloc(zram->mem_pool, clen + sizeof(*zheader)); + handle = zs_malloc(zram->mem_pool, clen); if (!handle) { pr_info("Error allocating memory for compressed " "page: %u, size=%zu\n", index, clen); @@ -415,24 +353,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, } cmem = zs_map_object(zram->mem_pool, handle); -memstore: -#if 0 - /* Back-reference needed for memory defragmentation */ - if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) { - zheader = (struct zobj_header *)cmem; - zheader->table_idx = index; - cmem += sizeof(*zheader); - } -#endif - memcpy(cmem, src, clen); - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - kunmap_atomic(cmem); - kunmap_atomic(src); - } else { - zs_unmap_object(zram->mem_pool, handle); - } + zs_unmap_object(zram->mem_pool, handle); zram->table[index].handle = handle; zram->table[index].size = clen; @@ -597,10 +520,7 @@ void __zram_reset_device(struct zram *zram) if (!handle) continue; - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) - __free_page((struct page *)handle); - else - zs_free(zram->mem_pool, handle); + zs_free(zram->mem_pool, handle); } vfree(zram->table); diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index 7a7e25664826..9711d1e281f1 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -26,18 +26,6 @@ */ static const unsigned max_num_devices = 32; -/* - * Stored at beginning of each compressed object. - * - * It stores back-reference to table entry which points to this - * object. This is required to support memory defragmentation. - */ -struct zobj_header { -#if 0 - u32 table_idx; -#endif -}; - /*-- Configurable parameters */ /* Default zram disk size: 25% of total RAM */ @@ -68,9 +56,6 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3; /* Flags for zram pages (table[page_no].flags) */ enum zram_pageflags { - /* Page is stored uncompressed */ - ZRAM_UNCOMPRESSED, - /* Page consists entirely of zeros */ ZRAM_ZERO, @@ -98,7 +83,7 @@ struct zram_stats { u32 pages_zero; /* no. of zero filled pages */ u32 pages_stored; /* no. of pages currently stored */ u32 good_compress; /* % of pages with compression ratio<=50% */ - u32 pages_expand; /* % of incompressible pages */ + u32 bad_compress; /* % of pages with compression ratio>=75% */ }; struct zram { diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index a7f377175525..edb0ed4125d5 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -186,10 +186,8 @@ static ssize_t mem_used_total_show(struct device *dev, u64 val = 0; struct zram *zram = dev_to_zram(dev); - if (zram->init_done) { - val = zs_get_total_size_bytes(zram->mem_pool) + - ((u64)(zram->stats.pages_expand) << PAGE_SHIFT); - } + if (zram->init_done) + val = zs_get_total_size_bytes(zram->mem_pool); return sprintf(buf, "%llu\n", val); } -- GitLab From 2db51dae56240b52fe08ddbb1a2eb47fe7cfd044 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Sat, 9 Jun 2012 17:41:14 -0700 Subject: [PATCH 1091/6849] staging: zsmalloc documentation Documentation of various struct page fields used by zsmalloc. Changes for v2: - Regroup descriptions as suggested by Konrad Signed-off-by: Nitin Gupta Acked-by: Konrad Rzeszutek Wilk Reviewed-by: Minchan Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zsmalloc/zsmalloc-main.c | 48 ++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 8e830eeca729..fb54a9b94c33 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -10,6 +10,54 @@ * Released under the terms of GNU General Public License Version 2.0 */ + +/* + * This allocator is designed for use with zcache and zram. Thus, the + * allocator is supposed to work well under low memory conditions. In + * particular, it never attempts higher order page allocation which is + * very likely to fail under memory pressure. On the other hand, if we + * just use single (0-order) pages, it would suffer from very high + * fragmentation -- any object of size PAGE_SIZE/2 or larger would occupy + * an entire page. This was one of the major issues with its predecessor + * (xvmalloc). + * + * To overcome these issues, zsmalloc allocates a bunch of 0-order pages + * and links them together using various 'struct page' fields. These linked + * pages act as a single higher-order page i.e. an object can span 0-order + * page boundaries. The code refers to these linked pages as a single entity + * called zspage. + * + * Following is how we use various fields and flags of underlying + * struct page(s) to form a zspage. + * + * Usage of struct page fields: + * page->first_page: points to the first component (0-order) page + * page->index (union with page->freelist): offset of the first object + * starting in this page. For the first page, this is + * always 0, so we use this field (aka freelist) to point + * to the first free object in zspage. + * page->lru: links together all component pages (except the first page) + * of a zspage + * + * For _first_ page only: + * + * page->private (union with page->first_page): refers to the + * component page after the first page + * page->freelist: points to the first free object in zspage. + * Free objects are linked together using in-place + * metadata. + * page->objects: maximum number of objects we can store in this + * zspage (class->zspage_order * PAGE_SIZE / class->size) + * page->lru: links together first pages of various zspages. + * Basically forming list of zspages in a fullness group. + * page->mapping: class index and fullness group of the zspage + * + * Usage of struct page flags: + * PG_private: identifies the first component page + * PG_private2: identifies the last component page + * + */ + #ifdef CONFIG_ZSMALLOC_DEBUG #define DEBUG #endif -- GitLab From 94b8435ff4d46dde75173da45564b0d65889dc64 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Thu, 7 Jun 2012 16:03:47 -0700 Subject: [PATCH 1092/6849] staging: zram: conventions pr_warning -> pr_warn() Porting zram to use the pr_warn() function instead of the deprecated pr_warning(). Signed-off-by: Sam Hansen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 2036a901628b..706cb625aae9 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -645,7 +645,7 @@ static int create_device(struct zram *zram, int device_id) zram->disk = alloc_disk(1); if (!zram->disk) { blk_cleanup_queue(zram->queue); - pr_warning("Error allocating disk structure for device %d\n", + pr_warn("Error allocating disk structure for device %d\n", device_id); ret = -ENOMEM; goto out; @@ -676,7 +676,7 @@ static int create_device(struct zram *zram, int device_id) ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj, &zram_disk_attr_group); if (ret < 0) { - pr_warning("Error creating sysfs group"); + pr_warn("Error creating sysfs group"); goto out; } @@ -710,7 +710,7 @@ static int __init zram_init(void) int ret, dev_id; if (num_devices > max_num_devices) { - pr_warning("Invalid value for num_devices: %u\n", + pr_warn("Invalid value for num_devices: %u\n", num_devices); ret = -EINVAL; goto out; @@ -718,7 +718,7 @@ static int __init zram_init(void) zram_major = register_blkdev(0, "zram"); if (zram_major <= 0) { - pr_warning("Unable to get major number\n"); + pr_warn("Unable to get major number\n"); ret = -EBUSY; goto out; } -- GitLab From 80677c2538283678c7b2ef7ebbd653a3fa54d086 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Thu, 7 Jun 2012 16:03:48 -0700 Subject: [PATCH 1093/6849] staging: zram: conventions, __aligned() attribute Using the __aligned() attribute in favor of __attribute__((aligned(size))) Signed-off-by: Sam Hansen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index 9711d1e281f1..572c0b1551d4 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -70,7 +70,7 @@ struct table { u16 size; /* object size (excluding header) */ u8 count; /* object ref count (not yet used) */ u8 flags; -} __attribute__((aligned(4))); +} __aligned(4); struct zram_stats { u64 compr_size; /* compressed size of pages stored */ -- GitLab From e034410a3dace8ee56906095e737281899126f44 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 1 Jun 2012 10:14:02 +0200 Subject: [PATCH 1094/6849] staging: usbip: userspace: include headers in release tarballs The header files should be included in generated tarballs for archives. Signed-off-by: Natanael Copa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/src/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/usbip/userspace/src/Makefile.am b/drivers/staging/usbip/userspace/src/Makefile.am index 3f09f6ad39f7..c365a3fada90 100644 --- a/drivers/staging/usbip/userspace/src/Makefile.am +++ b/drivers/staging/usbip/userspace/src/Makefile.am @@ -4,8 +4,9 @@ LDADD = $(top_builddir)/libsrc/libusbip.la @PACKAGE_LIBS@ sbin_PROGRAMS := usbip usbipd -usbip_SOURCES := usbip.c utils.c usbip_network.c \ +usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c -usbipd_SOURCES := usbipd.c usbip_network.c + +usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c -- GitLab From 6ab6827ee99937834cc268298ee4eab1a651569e Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 8 Jun 2012 21:25:25 +0530 Subject: [PATCH 1095/6849] RDMA/ocrdma: Fixed GID table for vlan and events 1. Fix reporting GID table addition events. 2. Enable vlan based GID entries only when VLAN is enabled at compile time (test CONFIG_VLAN_8021Q / CONFIG_VLAN_8021Q_MODULE). Signed-off-by: Parav Pandit Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_main.c | 63 ++++++++++++---------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 04fef3de6d75..b050e629e9c3 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, sgid->raw[15] = mac_addr[5]; } -static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, +static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, bool is_vlan, u16 vlan_id) { int i; - bool found = false; union ib_gid new_sgid; - int free_idx = OCRDMA_MAX_SGID; unsigned long flags; memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); @@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, sizeof(union ib_gid))) { /* found free entry */ - if (!found) { - free_idx = i; - found = true; - break; - } + memcpy(&dev->sgid_tbl[i], &new_sgid, + sizeof(union ib_gid)); + spin_unlock_irqrestore(&dev->sgid_lock, flags); + return true; } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, sizeof(union ib_gid))) { /* entry already present, no addition is required. */ spin_unlock_irqrestore(&dev->sgid_lock, flags); - return; + return false; } } - /* if entry doesn't exist and if table has some space, add entry */ - if (found) - memcpy(&dev->sgid_tbl[free_idx], &new_sgid, - sizeof(union ib_gid)); spin_unlock_irqrestore(&dev->sgid_lock, flags); + return false; } static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, @@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) ocrdma_get_guid(dev, &sgid->raw[8]); } -static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) { struct net_device *netdev, *tmp; u16 vlan_id; @@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) netdev = dev->nic_info.netdev; - ocrdma_add_default_sgid(dev); - rcu_read_lock(); for_each_netdev_rcu(&init_net, tmp) { if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { @@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) } } rcu_read_unlock(); +} +#else +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) +{ + +} +#endif /* VLAN */ + +static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +{ + ocrdma_add_default_sgid(dev); + ocrdma_add_vlan_sgids(dev); return 0; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ +defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) static int ocrdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, void *ptr) @@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, struct ib_event gid_event; struct ocrdma_dev *dev; bool found = false; + bool updated = false; bool is_vlan = false; u16 vid = 0; @@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, mutex_lock(&dev->dev_lock); switch (event) { case NETDEV_UP: - ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); + updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); break; case NETDEV_DOWN: - found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); - if (found) { - /* found the matching entry, notify - * the consumers about it - */ - gid_event.device = &dev->ibdev; - gid_event.element.port_num = 1; - gid_event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&gid_event); - } + updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); break; default: break; } + if (updated) { + /* GID table updated, notify the consumers about it */ + gid_event.device = &dev->ibdev; + gid_event.element.port_num = 1; + gid_event.event = IB_EVENT_GID_CHANGE; + ib_dispatch_event(&gid_event); + } mutex_unlock(&dev->dev_lock); return NOTIFY_OK; } @@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { .notifier_call = ocrdma_inet6addr_event }; -#endif /* IPV6 */ +#endif /* IPV6 and VLAN */ static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, u8 port_num) -- GitLab From 07bb54244e466f1517357f47a498574f97c31e08 Mon Sep 17 00:00:00 2001 From: Mahesh Vardhamanaiah Date: Fri, 8 Jun 2012 21:25:52 +0530 Subject: [PATCH 1096/6849] RDMA/ocrdma: Correct reported max queue sizes Fix code to read the max wqe and max rqe values from mailbox response. Signed-off-by: Mahesh Vardhamanaiah Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 15 +++++---------- drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 2 +- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 9343a1522977..7507968deb2c 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, struct ocrdma_dev_attr *attr, struct ocrdma_mbx_query_config *rsp) { - int max_q_mem; - attr->max_pd = (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; @@ -1037,18 +1035,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_inline_data = attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + sizeof(struct ocrdma_sge)); - max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); - /* hw can queue one less then the configured size, - * so publish less by one to stack. - */ if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; attr->ird = 1; attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; - } else - dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; - dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; + } + dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> + OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; + dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; } static int ocrdma_check_fw_config(struct ocrdma_dev *dev, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 7fd80cc0f037..84114416ce7c 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -458,7 +458,7 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << -- GitLab From 634c5796a5c60964faf9d51892571ffe36ad24d5 Mon Sep 17 00:00:00 2001 From: Mahesh Vardhamanaiah Date: Fri, 8 Jun 2012 21:26:11 +0530 Subject: [PATCH 1097/6849] RDMA/ocrdma: Correct queue SGE calculation Fix max sge calculation for sq, rq, srq for all hardware types. Signed-off-by: Mahesh Vardhamanaiah Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma.h | 1 + drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 3 +++ drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 3 +++ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 6 +++--- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 037f5cea85bd..48970af23679 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h @@ -61,6 +61,7 @@ struct ocrdma_dev_attr { u32 max_inline_data; int max_send_sge; int max_recv_sge; + int max_srq_sge; int max_mr; u64 max_mr_size; u32 max_num_mr_pbl; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 7507968deb2c..71942af4fce9 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -1002,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_recv_sge = (rsp->max_write_send_sge & OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; + attr->max_srq_sge = (rsp->max_srq_rqe_sge & + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 84114416ce7c..c75cbdfa87e7 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -418,6 +418,9 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index d16d172b6b6b..0e88088545ac 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_LOCAL_DMA_LKEY; - attr->max_sge = dev->attr.max_send_sge; - attr->max_sge_rd = dev->attr.max_send_sge; + attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge); + attr->max_sge_rd = 0; attr->max_cq = dev->attr.max_cq; attr->max_cqe = dev->attr.max_cqe; attr->max_mr = dev->attr.max_mr; @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_sge; + attr->max_srq_sge = attr->max_srq_sge; attr->max_srq_wr = dev->attr.max_rqe; attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = 0; -- GitLab From a3698a9b919d2a54e3348be48ab65d102b2f105d Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Mon, 11 Jun 2012 16:39:20 +0530 Subject: [PATCH 1098/6849] RDMA/ocrdma: Fixed RQ error CQE polling Fix RQ/SRQ error CQE polling. Return error CQE to consumer for error case which was not returned previously. Signed-off-by: Parav Pandit Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 0e88088545ac..d55d459b7fc8 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -2301,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, *stop = true; expand = false; } - } else + } else { + *polled = true; expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); + } return expand; } -- GitLab From 109cdbc223f6e2d6c80f8371f22415b50c18a366 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 18 May 2012 16:52:19 -0600 Subject: [PATCH 1099/6849] PCI: remove pci_bus_find_ext_capability() (unused) pci_bus_find_ext_capability() is unused, and this patch removes it. Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 43 ------------------------------------------- include/linux/pci.h | 2 -- 2 files changed, 45 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..de9386da2eb2 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -329,49 +329,6 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) } EXPORT_SYMBOL_GPL(pci_find_ext_capability); -/** - * pci_bus_find_ext_capability - find an extended capability - * @bus: the PCI bus to query - * @devfn: PCI device to query - * @cap: capability code - * - * Like pci_find_ext_capability() but works for pci devices that do not have a - * pci_dev structure set up yet. - * - * Returns the address of the requested capability structure within the - * device's PCI configuration space or 0 in case the device does not - * support it. - */ -int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn, - int cap) -{ - u32 header; - int ttl; - int pos = PCI_CFG_SPACE_SIZE; - - /* minimum 8 bytes per capability */ - ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; - - if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) - return 0; - if (header == 0xffffffff || header == 0) - return 0; - - while (ttl-- > 0) { - if (PCI_EXT_CAP_ID(header) == cap) - return pos; - - pos = PCI_EXT_CAP_NEXT(header); - if (pos < PCI_CFG_SPACE_SIZE) - break; - - if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) - break; - } - - return 0; -} - static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) { int rc, ttl = PCI_FIND_CAP_TTL; diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..2618ad996535 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -714,8 +714,6 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev); int pci_find_capability(struct pci_dev *dev, int cap); int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap); int pci_find_ext_capability(struct pci_dev *dev, int cap); -int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn, - int cap); int pci_find_ht_capability(struct pci_dev *dev, int ht_cap); int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); struct pci_bus *pci_find_next_bus(const struct pci_bus *from); -- GitLab From 533b6608b73669309becd90f11f939b60bb221be Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 18 May 2012 16:52:34 -0600 Subject: [PATCH 1100/6849] PCI: remove pci_max_busnr() (was already commented out) pci_max_busnr() has been commented out for years (since 54c762fe62), and this patch removes it completely. Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index de9386da2eb2..2cc53acad26a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -136,30 +136,6 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) EXPORT_SYMBOL_GPL(pci_ioremap_bar); #endif -#if 0 -/** - * pci_max_busnr - returns maximum PCI bus number - * - * Returns the highest PCI bus number present in the system global list of - * PCI buses. - */ -unsigned char __devinit -pci_max_busnr(void) -{ - struct pci_bus *bus = NULL; - unsigned char max, n; - - max = 0; - while ((bus = pci_find_next_bus(bus)) != NULL) { - n = pci_bus_max_busnr(bus); - if(n > max) - max = n; - } - return max; -} - -#endif /* 0 */ - #define PCI_FIND_CAP_TTL 48 static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, -- GitLab From 505cf30b7f4ef64c6db36f34adbe4a7ad9081fd3 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 18 May 2012 16:52:40 -0600 Subject: [PATCH 1101/6849] PCI/AER: use pci_is_pcie() instead of obsolete pci_dev.is_pcie Use pci_is_pcie() instead of looking at obsolete is_pcie field in struct pci_dev. CC: Huang Ying CC: Kenji Kaneshige Signed-off-by: Bjorn Helgaas --- drivers/pci/pcie/aer/aerdrv_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 275bf158ffa7..124f20ff11b2 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c @@ -59,7 +59,7 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data) p = (struct acpi_hest_aer_common *)(hest_hdr + 1); if (p->flags & ACPI_HEST_GLOBAL) { - if ((info->pci_dev->is_pcie && + if ((pci_is_pcie(info->pci_dev) && info->pci_dev->pcie_type == pcie_type) || bridge) ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); } else -- GitLab From dec195dc41bd678a5626cca5d6c14ee338b5df77 Mon Sep 17 00:00:00 2001 From: "hdoyu@nvidia.com" Date: Mon, 14 May 2012 06:21:18 +0000 Subject: [PATCH 1102/6849] amba: tegra-ahb: Remove empty *_remove() Remove unnecessary empty function. Signed-off-by: Hiroshi DOYU Signed-off-by: Stephen Warren --- drivers/amba/tegra-ahb.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index aa0b1f160528..0b6f0b28a487 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -264,11 +264,6 @@ static int __devinit tegra_ahb_probe(struct platform_device *pdev) return 0; } -static int __devexit tegra_ahb_remove(struct platform_device *pdev) -{ - return 0; -} - static const struct of_device_id tegra_ahb_of_match[] __devinitconst = { { .compatible = "nvidia,tegra30-ahb", }, { .compatible = "nvidia,tegra20-ahb", }, @@ -277,7 +272,6 @@ static const struct of_device_id tegra_ahb_of_match[] __devinitconst = { static struct platform_driver tegra_ahb_driver = { .probe = tegra_ahb_probe, - .remove = __devexit_p(tegra_ahb_remove), .driver = { .name = DRV_NAME, .owner = THIS_MODULE, -- GitLab From a9140aa51dede09cefd51a6f578a100572e693b3 Mon Sep 17 00:00:00 2001 From: "hdoyu@nvidia.com" Date: Wed, 16 May 2012 19:47:44 +0000 Subject: [PATCH 1103/6849] ARM: dt: tegra{20,30}.dtsi: Rename "mc" to "memory-controller" Use a more plain english name. Signed-off-by: Hiroshi DOYU [swarren: remove redundant unit address from tegra30.dtsi change] Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra20.dtsi | 2 +- arch/arm/boot/dts/tegra30.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index c417d67e9027..2d503d62ea3e 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -164,7 +164,7 @@ reg = <0x7000e400 0x400>; }; - mc { + memory-controller@0x7000f000 { compatible = "nvidia,tegra20-mc"; reg = <0x7000f000 0x024 0x7000f03c 0x3c4>; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 2dcc09e784b5..19479393842e 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -167,7 +167,7 @@ reg = <0x7000e400 0x400>; }; - mc { + memory-controller { compatible = "nvidia,tegra30-mc"; reg = <0x7000f000 0x010 0x7000f03c 0x1b4 -- GitLab From eed6e344aeacd7cddbffd8e6ff4432f339bcc2bb Mon Sep 17 00:00:00 2001 From: "hdoyu@nvidia.com" Date: Wed, 16 May 2012 19:47:45 +0000 Subject: [PATCH 1104/6849] ARM: tegra{20,30}: Rename "mc" to "memory-controller" Use a more plain english name. Signed-off-by: Hiroshi DOYU [swarren: remove redundant unit address from Tegra30 example] Signed-off-by: Stephen Warren --- .../devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt | 2 +- .../devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt index c25a0a55151d..866d93421eba 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt @@ -8,7 +8,7 @@ Required properties: - interrupts : Should contain MC General interrupt. Example: - mc { + memory-controller@0x7000f000 { compatible = "nvidia,tegra20-mc"; reg = <0x7000f000 0x024 0x7000f03c 0x3c4>; diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt index e47e73f612f4..bdf1a612422b 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt @@ -8,7 +8,7 @@ Required properties: - interrupts : Should contain MC General interrupt. Example: - mc { + memory-controller { compatible = "nvidia,tegra30-mc"; reg = <0x7000f000 0x010 0x7000f03c 0x1b4 -- GitLab From bfb3fe12667244d2c51699608a1591f1fdb774e5 Mon Sep 17 00:00:00 2001 From: "hdoyu@nvidia.com" Date: Wed, 16 May 2012 19:47:46 +0000 Subject: [PATCH 1105/6849] ARM: dt: tegra20: Rename "emc" to "memory-controller" Use a more plain english name. Signed-off-by: Hiroshi DOYU [swarren: also rename the node in tegra-seaboard.dts] Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra-seaboard.dts | 2 +- arch/arm/boot/dts/tegra20.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index 89cb7f2acd92..743ef653afc3 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -334,7 +334,7 @@ }; }; - emc { + memory-controller@0x7000f400 { emc-table@190000 { reg = <190000>; compatible = "nvidia,tegra20-emc-table"; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 2d503d62ea3e..59116b852434 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -177,7 +177,7 @@ 0x58000000 0x02000000>; /* GART aperture */ }; - emc { + memory-controller@0x7000f400 { compatible = "nvidia,tegra20-emc"; reg = <0x7000f400 0x200>; #address-cells = <1>; -- GitLab From 4c5ddd952ef1e534b45218cf4ad74b5496e6406c Mon Sep 17 00:00:00 2001 From: "hdoyu@nvidia.com" Date: Wed, 16 May 2012 19:47:47 +0000 Subject: [PATCH 1106/6849] ARM: tegra20: Rename "emc" to "memory-controller" Use a more plain english name. Signed-off-by: Hiroshi DOYU Signed-off-by: Stephen Warren --- Documentation/devicetree/bindings/arm/tegra/emc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt index 09335f8eee00..4c33b29dc660 100644 --- a/Documentation/devicetree/bindings/arm/tegra/emc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt @@ -15,7 +15,7 @@ Child device nodes describe the memory settings for different configurations and Example: - emc@7000f400 { + memory-controller@7000f400 { #address-cells = < 1 >; #size-cells = < 0 >; compatible = "nvidia,tegra20-emc"; -- GitLab From f3d549dd5b217d084c9fe6581e0430909440de2b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 16:05:45 -0600 Subject: [PATCH 1107/6849] dt: name all Tegra binding docs consistently Rename all Tegra binding documentation according to the first or primary compatible value they describe. This provides a clear naming scheme for the files, and prevents any naming conflicts should future SoC versions require their own binding. Signed-off-by: Stephen Warren --- .../bindings/arm/tegra/{emc.txt => nvidia,tegra20-emc.txt} | 0 .../bindings/gpio/{gpio_nvidia.txt => nvidia,tegra20-gpio.txt} | 0 .../bindings/input/{tegra-kbc.txt => nvidia,tegra20-kbc.txt} | 0 .../bindings/mmc/{nvidia-sdhci.txt => nvidia,tegra20-sdhci.txt} | 0 .../devicetree/bindings/nvec/{nvec_nvidia.txt => nvidia,nvec.txt} | 0 .../{tegra-audio-alc5632.txt => nvidia,tegra-audio-alc5632.txt} | 0 ...tegra-audio-trimslice.txt => nvidia,tegra-audio-trimslice.txt} | 0 .../{tegra-audio-wm8753.txt => nvidia,tegra-audio-wm8753.txt} | 0 .../{tegra-audio-wm8903.txt => nvidia,tegra-audio-wm8903.txt} | 0 .../bindings/sound/{tegra20-das.txt => nvidia,tegra20-das.txt} | 0 .../bindings/sound/{tegra20-i2s.txt => nvidia,tegra20-i2s.txt} | 0 .../bindings/spi/{spi_nvidia.txt => nvidia,tegra20-spi.txt} | 0 .../bindings/usb/{tegra-usb.txt => nvidia,tegra20-ehci.txt} | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename Documentation/devicetree/bindings/arm/tegra/{emc.txt => nvidia,tegra20-emc.txt} (100%) rename Documentation/devicetree/bindings/gpio/{gpio_nvidia.txt => nvidia,tegra20-gpio.txt} (100%) rename Documentation/devicetree/bindings/input/{tegra-kbc.txt => nvidia,tegra20-kbc.txt} (100%) rename Documentation/devicetree/bindings/mmc/{nvidia-sdhci.txt => nvidia,tegra20-sdhci.txt} (100%) rename Documentation/devicetree/bindings/nvec/{nvec_nvidia.txt => nvidia,nvec.txt} (100%) rename Documentation/devicetree/bindings/sound/{tegra-audio-alc5632.txt => nvidia,tegra-audio-alc5632.txt} (100%) rename Documentation/devicetree/bindings/sound/{tegra-audio-trimslice.txt => nvidia,tegra-audio-trimslice.txt} (100%) rename Documentation/devicetree/bindings/sound/{tegra-audio-wm8753.txt => nvidia,tegra-audio-wm8753.txt} (100%) rename Documentation/devicetree/bindings/sound/{tegra-audio-wm8903.txt => nvidia,tegra-audio-wm8903.txt} (100%) rename Documentation/devicetree/bindings/sound/{tegra20-das.txt => nvidia,tegra20-das.txt} (100%) rename Documentation/devicetree/bindings/sound/{tegra20-i2s.txt => nvidia,tegra20-i2s.txt} (100%) rename Documentation/devicetree/bindings/spi/{spi_nvidia.txt => nvidia,tegra20-spi.txt} (100%) rename Documentation/devicetree/bindings/usb/{tegra-usb.txt => nvidia,tegra20-ehci.txt} (100%) diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/tegra/emc.txt rename to Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt b/Documentation/devicetree/bindings/gpio/nvidia,tegra20-gpio.txt similarity index 100% rename from Documentation/devicetree/bindings/gpio/gpio_nvidia.txt rename to Documentation/devicetree/bindings/gpio/nvidia,tegra20-gpio.txt diff --git a/Documentation/devicetree/bindings/input/tegra-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt similarity index 100% rename from Documentation/devicetree/bindings/input/tegra-kbc.txt rename to Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt diff --git a/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt similarity index 100% rename from Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt rename to Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt diff --git a/Documentation/devicetree/bindings/nvec/nvec_nvidia.txt b/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt similarity index 100% rename from Documentation/devicetree/bindings/nvec/nvec_nvidia.txt rename to Documentation/devicetree/bindings/nvec/nvidia,nvec.txt diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt similarity index 100% rename from Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt rename to Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-trimslice.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt similarity index 100% rename from Documentation/devicetree/bindings/sound/tegra-audio-trimslice.txt rename to Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-wm8753.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt similarity index 100% rename from Documentation/devicetree/bindings/sound/tegra-audio-wm8753.txt rename to Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-wm8903.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt similarity index 100% rename from Documentation/devicetree/bindings/sound/tegra-audio-wm8903.txt rename to Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt diff --git a/Documentation/devicetree/bindings/sound/tegra20-das.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-das.txt similarity index 100% rename from Documentation/devicetree/bindings/sound/tegra20-das.txt rename to Documentation/devicetree/bindings/sound/nvidia,tegra20-das.txt diff --git a/Documentation/devicetree/bindings/sound/tegra20-i2s.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt similarity index 100% rename from Documentation/devicetree/bindings/sound/tegra20-i2s.txt rename to Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt diff --git a/Documentation/devicetree/bindings/spi/spi_nvidia.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-spi.txt similarity index 100% rename from Documentation/devicetree/bindings/spi/spi_nvidia.txt rename to Documentation/devicetree/bindings/spi/nvidia,tegra20-spi.txt diff --git a/Documentation/devicetree/bindings/usb/tegra-usb.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt similarity index 100% rename from Documentation/devicetree/bindings/usb/tegra-usb.txt rename to Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt -- GitLab From b4e395b2cb5ce871f23a176fed74316a7de64a97 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:44:40 +0530 Subject: [PATCH 1108/6849] ARM: tegra: Remove flow controller programming This particular code had no effect on WFI execution. It only asserts/de-asserts signal to tegra "legacy" CPU idle stats monitor, which we are no longer using (cpufreq is based on kernel s/w idle stats instead). Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/cpuidle.c | 6 +++--- arch/arm/mach-tegra/sleep.S | 29 ----------------------------- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index d83a8c0296f5..566e2f88899b 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c @@ -27,9 +27,9 @@ #include #include -#include +#include -extern void tegra_cpu_wfi(void); +#include static int tegra_idle_enter_lp3(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); @@ -64,7 +64,7 @@ static int tegra_idle_enter_lp3(struct cpuidle_device *dev, enter = ktime_get(); - tegra_cpu_wfi(); + cpu_do_idle(); exit = ktime_sub(ktime_get(), enter); us = ktime_to_us(exit); diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index 5b20197bae7f..d29b156a8011 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S @@ -62,32 +62,3 @@ movw \reg, #:lower16:\val movt \reg, #:upper16:\val .endm - -/* - * tegra_cpu_wfi - * - * puts current CPU in clock-gated wfi using the flow controller - * - * corrupts r0-r3 - * must be called with MMU on - */ - -ENTRY(tegra_cpu_wfi) - cpu_id r0 - cpu_to_halt_reg r1, r0 - cpu_to_csr_reg r2, r0 - mov32 r0, TEGRA_FLOW_CTRL_VIRT - mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG - str r3, [r0, r2] @ clear event & interrupt status - mov r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME - str r3, [r0, r1] @ put flow controller in wait irq mode - dsb - wfi - mov r3, #0 - str r3, [r0, r1] @ clear flow controller halt status - mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG - str r3, [r0, r2] @ clear event & interrupt status - dsb - mov pc, lr -ENDPROC(tegra_cpu_wfi) - -- GitLab From c11bd557903395f436d63bb6dfb0f4b86ea365d5 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 16:43:42 -0600 Subject: [PATCH 1109/6849] mmc: tegra: use bus-width property instead of support-8bit Update the driver to parse the new unified bus-width property introduced in commit 7f21779 "mmc: dt: Consolidate DT bindings", instead of the legacy support-8bit property. Signed-off-by: Stephen Warren Acked-by: Chris Ball --- drivers/mmc/host/sdhci-tegra.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index b38d8a78f6a0..6e5338a071ce 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -223,6 +223,7 @@ static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata( { struct tegra_sdhci_platform_data *plat; struct device_node *np = pdev->dev.of_node; + u32 bus_width; if (!np) return NULL; @@ -236,7 +237,9 @@ static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata( plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0); - if (of_find_property(np, "support-8bit", NULL)) + + if (of_property_read_u32(np, "bus-width", &bus_width) == 0 && + bus_width == 8) plat->is_8bit = 1; return plat; -- GitLab From 02e35c461daf78a093012ae2eb07535939f95c16 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 16:45:19 -0600 Subject: [PATCH 1110/6849] ARM: dt: tegra: remove legacy support-8bit property The driver supports the new bus-width property, so remove the legacy support-8bit property. Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra-cardhu.dts | 1 - arch/arm/boot/dts/tegra-harmony.dts | 1 - arch/arm/boot/dts/tegra-paz00.dts | 1 - arch/arm/boot/dts/tegra-seaboard.dts | 1 - arch/arm/boot/dts/tegra-ventana.dts | 1 - 5 files changed, 5 deletions(-) diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra-cardhu.dts index 36321bceec46..c169bced131e 100644 --- a/arch/arm/boot/dts/tegra-cardhu.dts +++ b/arch/arm/boot/dts/tegra-cardhu.dts @@ -144,7 +144,6 @@ sdhci@78000600 { status = "okay"; - support-8bit; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index 7de701365fce..f146dbf6f7f8 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -307,7 +307,6 @@ cd-gpios = <&gpio 58 0>; /* gpio PH2 */ wp-gpios = <&gpio 59 0>; /* gpio PH3 */ power-gpios = <&gpio 70 0>; /* gpio PI6 */ - support-8bit; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index bfeb117d5aea..684a9e1ff7e9 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -301,7 +301,6 @@ sdhci@c8000600 { status = "okay"; - support-8bit; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index 743ef653afc3..b797901d040d 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -397,7 +397,6 @@ sdhci@c8000600 { status = "okay"; - support-8bit; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index 445343b0fbdd..be90544e6b59 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -314,7 +314,6 @@ sdhci@c8000600 { status = "okay"; - support-8bit; bus-width = <8>; }; -- GitLab From 0336553e4a8c1fefc11aa5656cebf2ce80657322 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 14:51:19 -0600 Subject: [PATCH 1111/6849] ASoC: tegra: simplify Kconfig dependencies The Tegra ASoC machine drivers only depend on Tegra architecture support to compile, not specific board support. Remove Kconfig dependencies on any particular board. This is required since Kconfig options for boards are going away given the migration to device tree. Signed-off-by: Stephen Warren Acked-by: Mark Brown --- arch/arm/mach-tegra/Kconfig | 3 --- sound/soc/tegra/Kconfig | 10 +--------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 6a113a9bb87a..7c407393cd07 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -63,7 +63,6 @@ comment "Tegra board type" config MACH_HARMONY bool "Harmony board" depends on ARCH_TEGRA_2x_SOC - select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC help Support for nVidia Harmony development platform @@ -71,7 +70,6 @@ config MACH_KAEN bool "Kaen board" depends on ARCH_TEGRA_2x_SOC select MACH_SEABOARD - select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC help Support for the Kaen version of Seaboard @@ -84,7 +82,6 @@ config MACH_PAZ00 config MACH_SEABOARD bool "Seaboard board" depends on ARCH_TEGRA_2x_SOC - select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC help Support for nVidia Seaboard development platform. It will also be included for some of the derivative boards that diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index c1c8e955f4d3..76dc230f2bb0 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -58,17 +58,9 @@ config SND_SOC_TEGRA_WM8753 Say Y or M here if you want to add support for SoC audio on Tegra boards using the WM8753 codec, such as Whistler. -config MACH_HAS_SND_SOC_TEGRA_WM8903 - bool - help - Machines that use the SND_SOC_TEGRA_WM8903 driver should select - this config option, in order to allow the user to enable - SND_SOC_TEGRA_WM8903. - config SND_SOC_TEGRA_WM8903 tristate "SoC Audio support for Tegra boards using a WM8903 codec" depends on SND_SOC_TEGRA && I2C - depends on MACH_HAS_SND_SOC_TEGRA_WM8903 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_WM8903 @@ -79,7 +71,7 @@ config SND_SOC_TEGRA_WM8903 config SND_SOC_TEGRA_TRIMSLICE tristate "SoC Audio support for TrimSlice board" - depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C + depends on SND_SOC_TEGRA && I2C select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC select SND_SOC_TLV320AIC23 help -- GitLab From 6a5278d0715c5dfd42151bb6d7444db3f2ceed52 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:35 +0530 Subject: [PATCH 1112/6849] ARM: tegra: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Tested on Ventana and Cardhu. Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/cpu-tegra.c | 6 +++--- arch/arm/mach-tegra/dma.c | 2 +- arch/arm/mach-tegra/pcie.c | 6 +++--- arch/arm/mach-tegra/powergate.c | 4 ++-- arch/arm/mach-tegra/timer.c | 4 ++-- arch/arm/mach-tegra/usb_phy.c | 16 ++++++++-------- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index 7a065f0cf633..ceb52db1e2f1 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -189,8 +189,8 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) return PTR_ERR(emc_clk); } - clk_enable(emc_clk); - clk_enable(cpu_clk); + clk_prepare_enable(emc_clk); + clk_prepare_enable(cpu_clk); cpufreq_frequency_table_cpuinfo(policy, freq_table); cpufreq_frequency_table_get_attr(freq_table, policy->cpu); @@ -212,7 +212,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) static int tegra_cpu_exit(struct cpufreq_policy *policy) { cpufreq_frequency_table_cpuinfo(policy, freq_table); - clk_disable(emc_clk); + clk_disable_unprepare(emc_clk); clk_put(emc_clk); clk_put(cpu_clk); return 0; diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index abea4f6e2dd5..2698d7d5c9ca 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -720,7 +720,7 @@ int __init tegra_dma_init(void) ret = PTR_ERR(c); goto fail; } - ret = clk_enable(c); + ret = clk_prepare_enable(c); if (ret != 0) { pr_err("Unable to enable clock for APB DMA\n"); goto fail; diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index 0e09137506ec..d3ad5150d660 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -723,9 +723,9 @@ static int tegra_pcie_power_regate(void) tegra_pcie_xclk_clamp(false); - clk_enable(tegra_pcie.afi_clk); - clk_enable(tegra_pcie.pex_clk); - return clk_enable(tegra_pcie.pll_e); + clk_prepare_enable(tegra_pcie.afi_clk); + clk_prepare_enable(tegra_pcie.pex_clk); + return clk_prepare_enable(tegra_pcie.pll_e); } static int tegra_pcie_clocks_get(void) diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index f5b12fb4ff12..15d506501ccc 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -146,7 +146,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk) if (ret) goto err_power; - ret = clk_enable(clk); + ret = clk_prepare_enable(clk); if (ret) goto err_clk; @@ -162,7 +162,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk) return 0; err_clamp: - clk_disable(clk); + clk_disable_unprepare(clk); err_clk: tegra_powergate_power_off(id); err_power: diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index 315672c7bd48..57b5bdc13b9b 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c @@ -189,7 +189,7 @@ static void __init tegra_init_timer(void) " Assuming 12Mhz input clock.\n"); rate = 12000000; } else { - clk_enable(clk); + clk_prepare_enable(clk); rate = clk_get_rate(clk); } @@ -201,7 +201,7 @@ static void __init tegra_init_timer(void) if (IS_ERR(clk)) pr_warn("Unable to get rtc-tegra clock\n"); else - clk_enable(clk); + clk_prepare_enable(clk); switch (rate) { case 12000000: diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c index 54e353c8e304..022b33a05c3a 100644 --- a/arch/arm/mach-tegra/usb_phy.c +++ b/arch/arm/mach-tegra/usb_phy.c @@ -247,7 +247,7 @@ static void utmip_pad_power_on(struct tegra_usb_phy *phy) unsigned long val, flags; void __iomem *base = phy->pad_regs; - clk_enable(phy->pad_clk); + clk_prepare_enable(phy->pad_clk); spin_lock_irqsave(&utmip_pad_lock, flags); @@ -259,7 +259,7 @@ static void utmip_pad_power_on(struct tegra_usb_phy *phy) spin_unlock_irqrestore(&utmip_pad_lock, flags); - clk_disable(phy->pad_clk); + clk_disable_unprepare(phy->pad_clk); } static int utmip_pad_power_off(struct tegra_usb_phy *phy) @@ -272,7 +272,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy) return -EINVAL; } - clk_enable(phy->pad_clk); + clk_prepare_enable(phy->pad_clk); spin_lock_irqsave(&utmip_pad_lock, flags); @@ -284,7 +284,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy) spin_unlock_irqrestore(&utmip_pad_lock, flags); - clk_disable(phy->pad_clk); + clk_disable_unprepare(phy->pad_clk); return 0; } @@ -580,7 +580,7 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) msleep(5); gpio_direction_output(config->reset_gpio, 1); - clk_enable(phy->clk); + clk_prepare_enable(phy->clk); msleep(1); val = readl(base + USB_SUSP_CTRL); @@ -689,7 +689,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, err = PTR_ERR(phy->pll_u); goto err0; } - clk_enable(phy->pll_u); + clk_prepare_enable(phy->pll_u); parent_rate = clk_get_rate(clk_get_parent(phy->pll_u)); for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) { @@ -735,7 +735,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, return phy; err1: - clk_disable(phy->pll_u); + clk_disable_unprepare(phy->pll_u); clk_put(phy->pll_u); err0: kfree(phy); @@ -810,7 +810,7 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy) clk_put(phy->clk); else utmip_pad_close(phy); - clk_disable(phy->pll_u); + clk_disable_unprepare(phy->pll_u); clk_put(phy->pll_u); kfree(phy); } -- GitLab From 6f786aad108ba5479d93410fb47e0f51a79f34b1 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:36 +0530 Subject: [PATCH 1113/6849] i2c: tegra: Add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Cc: w.sang@pengutronix.de Cc: linux-i2c@vger.kernel.org Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- drivers/i2c/busses/i2c-tegra.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 8b2e555a9563..3da7ee3eb505 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -341,7 +341,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) u32 val; int err = 0; - clk_enable(i2c_dev->clk); + clk_prepare_enable(i2c_dev->clk); tegra_periph_reset_assert(i2c_dev->clk); udelay(2); @@ -372,7 +372,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) if (tegra_i2c_flush_fifos(i2c_dev)) err = -ETIMEDOUT; - clk_disable(i2c_dev->clk); + clk_disable_unprepare(i2c_dev->clk); if (i2c_dev->irq_disabled) { i2c_dev->irq_disabled = 0; @@ -546,14 +546,14 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (i2c_dev->is_suspended) return -EBUSY; - clk_enable(i2c_dev->clk); + clk_prepare_enable(i2c_dev->clk); for (i = 0; i < num; i++) { int stop = (i == (num - 1)) ? 1 : 0; ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], stop); if (ret) break; } - clk_disable(i2c_dev->clk); + clk_disable_unprepare(i2c_dev->clk); return ret ?: i; } @@ -666,7 +666,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) goto err_free; } - clk_enable(i2c_dev->i2c_clk); + clk_prepare_enable(i2c_dev->i2c_clk); i2c_set_adapdata(&i2c_dev->adapter, i2c_dev); i2c_dev->adapter.owner = THIS_MODULE; -- GitLab From 1e674bc6689e9aca5bd4355d1f87093636ed1c02 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:37 +0530 Subject: [PATCH 1114/6849] mmc: tegra: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Cc: cjb@laptop.org Cc: linux-mmc@vger.kernel.org Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- drivers/mmc/host/sdhci-tegra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index b38d8a78f6a0..278965695f00 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -334,7 +334,7 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev) rc = PTR_ERR(clk); goto err_clk_get; } - clk_enable(clk); + clk_prepare_enable(clk); pltfm_host->clk = clk; host->mmc->pm_caps = plat->pm_flags; @@ -349,7 +349,7 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev) return 0; err_add_host: - clk_disable(pltfm_host->clk); + clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); err_clk_get: if (gpio_is_valid(plat->wp_gpio)) @@ -390,7 +390,7 @@ static int __devexit sdhci_tegra_remove(struct platform_device *pdev) if (gpio_is_valid(plat->power_gpio)) gpio_free(plat->power_gpio); - clk_disable(pltfm_host->clk); + clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); sdhci_pltfm_free(pdev); -- GitLab From 20de12ccf900d71eee1344adc7ae0dcd7db9b4ab Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:38 +0530 Subject: [PATCH 1115/6849] USB: ehci-tegra: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Cc: stern@rowland.harvard.edu Cc: gregkh@linuxfoundation.org Cc: linux-usb@vger.kernel.org Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- drivers/usb/host/ehci-tegra.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 68548236ec42..ab8a3bf628e3 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -46,8 +46,8 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - clk_enable(tegra->emc_clk); - clk_enable(tegra->clk); + clk_prepare_enable(tegra->emc_clk); + clk_prepare_enable(tegra->clk); tegra_usb_phy_power_on(tegra->phy); tegra->host_resumed = 1; } @@ -58,8 +58,8 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd) tegra->host_resumed = 0; tegra_usb_phy_power_off(tegra->phy); - clk_disable(tegra->clk); - clk_disable(tegra->emc_clk); + clk_disable_unprepare(tegra->clk); + clk_disable_unprepare(tegra->emc_clk); } static int tegra_ehci_internal_port_reset( @@ -671,7 +671,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail_clk; } - err = clk_enable(tegra->clk); + err = clk_prepare_enable(tegra->clk); if (err) goto fail_clken; @@ -682,7 +682,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail_emc_clk; } - clk_enable(tegra->emc_clk); + clk_prepare_enable(tegra->emc_clk); clk_set_rate(tegra->emc_clk, 400000000); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -782,10 +782,10 @@ fail: fail_phy: iounmap(hcd->regs); fail_io: - clk_disable(tegra->emc_clk); + clk_disable_unprepare(tegra->emc_clk); clk_put(tegra->emc_clk); fail_emc_clk: - clk_disable(tegra->clk); + clk_disable_unprepare(tegra->clk); fail_clken: clk_put(tegra->clk); fail_clk: @@ -820,10 +820,10 @@ static int tegra_ehci_remove(struct platform_device *pdev) tegra_usb_phy_close(tegra->phy); iounmap(hcd->regs); - clk_disable(tegra->clk); + clk_disable_unprepare(tegra->clk); clk_put(tegra->clk); - clk_disable(tegra->emc_clk); + clk_disable_unprepare(tegra->emc_clk); clk_put(tegra->emc_clk); kfree(tegra); -- GitLab From 19f5f7364a1cc770b14692f609bb9b802fc334d5 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 27 Jul 2011 17:29:28 +0200 Subject: [PATCH 1116/6849] nohz: Separate idle sleeping time accounting from nohz logic As we plan to be able to stop the tick outside the idle task, we need to prepare for separating nohz logic from idle. As a start, this pulls the idle sleeping time accounting out of the tick stop/restart API to the callers on idle entry/exit. Signed-off-by: Frederic Weisbecker Cc: Alessio Igor Bogani Cc: Andrew Morton Cc: Avi Kivity Cc: Chris Metcalf Cc: Christoph Lameter Cc: Daniel Lezcano Cc: Geoff Levand Cc: Gilad Ben Yossef Cc: Hakan Akkan Cc: Ingo Molnar Cc: Kevin Hilman Cc: Max Krasnyansky Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Stephen Hemminger Cc: Steven Rostedt Cc: Sven-Thorsten Dietrich Cc: Thomas Gleixner --- kernel/time/tick-sched.c | 77 ++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index da70c6db496c..81409bba2425 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -271,10 +271,10 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time) } EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); -static void tick_nohz_stop_sched_tick(struct tick_sched *ts) +static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now) { unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; - ktime_t last_update, expires, now; + ktime_t last_update, expires; struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; u64 time_delta; int cpu; @@ -282,8 +282,6 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts) cpu = smp_processor_id(); ts = &per_cpu(tick_cpu_sched, cpu); - now = tick_nohz_start_idle(cpu, ts); - /* * If this cpu is offline and it is the one which updates * jiffies, then give up the assignment and let it be taken by @@ -444,6 +442,14 @@ out: ts->sleep_length = ktime_sub(dev->next_event, now); } +static void __tick_nohz_idle_enter(struct tick_sched *ts) +{ + ktime_t now; + + now = tick_nohz_start_idle(smp_processor_id(), ts); + tick_nohz_stop_sched_tick(ts, now); +} + /** * tick_nohz_idle_enter - stop the idle tick from the idle task * @@ -479,7 +485,7 @@ void tick_nohz_idle_enter(void) * update of the idle time accounting in tick_nohz_start_idle(). */ ts->inidle = 1; - tick_nohz_stop_sched_tick(ts); + __tick_nohz_idle_enter(ts); local_irq_enable(); } @@ -499,7 +505,7 @@ void tick_nohz_irq_exit(void) if (!ts->inidle) return; - tick_nohz_stop_sched_tick(ts); + __tick_nohz_idle_enter(ts); } /** @@ -540,39 +546,11 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) } } -/** - * tick_nohz_idle_exit - restart the idle tick from the idle task - * - * Restart the idle tick when the CPU is woken up from idle - * This also exit the RCU extended quiescent state. The CPU - * can use RCU again after this function is called. - */ -void tick_nohz_idle_exit(void) +static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) { - int cpu = smp_processor_id(); - struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); #ifndef CONFIG_VIRT_CPU_ACCOUNTING unsigned long ticks; #endif - ktime_t now; - - local_irq_disable(); - - WARN_ON_ONCE(!ts->inidle); - - ts->inidle = 0; - - if (ts->idle_active || ts->tick_stopped) - now = ktime_get(); - - if (ts->idle_active) - tick_nohz_stop_idle(cpu, now); - - if (!ts->tick_stopped) { - local_irq_enable(); - return; - } - /* Update jiffies first */ select_nohz_load_balancer(0); tick_do_update_jiffies64(now); @@ -600,6 +578,35 @@ void tick_nohz_idle_exit(void) ts->idle_exittime = now; tick_nohz_restart(ts, now); +} + +/** + * tick_nohz_idle_exit - restart the idle tick from the idle task + * + * Restart the idle tick when the CPU is woken up from idle + * This also exit the RCU extended quiescent state. The CPU + * can use RCU again after this function is called. + */ +void tick_nohz_idle_exit(void) +{ + int cpu = smp_processor_id(); + struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); + ktime_t now; + + local_irq_disable(); + + WARN_ON_ONCE(!ts->inidle); + + ts->inidle = 0; + + if (ts->idle_active || ts->tick_stopped) + now = ktime_get(); + + if (ts->idle_active) + tick_nohz_stop_idle(cpu, now); + + if (ts->tick_stopped) + tick_nohz_restart_sched_tick(ts, now); local_irq_enable(); } -- GitLab From 2ac0d98fd624ae50f5e6ae9c800977a9dbbfcde6 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 28 Jul 2011 04:00:47 +0200 Subject: [PATCH 1117/6849] nohz: Make nohz API agnostic against idle ticks cputime accounting When the timer tick fires, it accounts the new jiffy as either part of system, user or idle time. This is how we record the cputime statistics. But when the tick is stopped from the idle task, we still need to record the number of jiffies spent tickless until we restart the tick and fall back to traditional tick-based cputime accounting. To do this, we take a snapshot of jiffies when the tick is stopped and compute the difference against the new value of jiffies when the tick is restarted. Then we account this whole difference to the idle cputime. However we are preparing to be able to stop the tick from other places than idle. So this idle time accounting needs to be performed from the callers of nohz APIs, not from the nohz APIs themselves because we now want them to be agnostic against places that stop/restart tick. Therefore, we pull the tickless idle time accounting out of generic nohz helpers up to idle entry/exit callers. Signed-off-by: Frederic Weisbecker Cc: Alessio Igor Bogani Cc: Andrew Morton Cc: Avi Kivity Cc: Chris Metcalf Cc: Christoph Lameter Cc: Daniel Lezcano Cc: Geoff Levand Cc: Gilad Ben Yossef Cc: Hakan Akkan Cc: Ingo Molnar Cc: Kevin Hilman Cc: Max Krasnyansky Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Stephen Hemminger Cc: Steven Rostedt Cc: Sven-Thorsten Dietrich Cc: Thomas Gleixner --- kernel/time/tick-sched.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 81409bba2425..911834b33b8a 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -402,7 +402,6 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now) ts->idle_tick = hrtimer_get_expires(&ts->sched_timer); ts->tick_stopped = 1; - ts->idle_jiffies = last_jiffies; } ts->idle_sleeps++; @@ -445,9 +444,13 @@ out: static void __tick_nohz_idle_enter(struct tick_sched *ts) { ktime_t now; + int was_stopped = ts->tick_stopped; now = tick_nohz_start_idle(smp_processor_id(), ts); tick_nohz_stop_sched_tick(ts, now); + + if (!was_stopped && ts->tick_stopped) + ts->idle_jiffies = ts->last_jiffies; } /** @@ -548,15 +551,25 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) { -#ifndef CONFIG_VIRT_CPU_ACCOUNTING - unsigned long ticks; -#endif /* Update jiffies first */ select_nohz_load_balancer(0); tick_do_update_jiffies64(now); update_cpu_load_nohz(); + touch_softlockup_watchdog(); + /* + * Cancel the scheduled timer and restore the tick + */ + ts->tick_stopped = 0; + ts->idle_exittime = now; + + tick_nohz_restart(ts, now); +} + +static void tick_nohz_account_idle_ticks(struct tick_sched *ts) +{ #ifndef CONFIG_VIRT_CPU_ACCOUNTING + unsigned long ticks; /* * We stopped the tick in idle. Update process times would miss the * time we slept as update_process_times does only a 1 tick @@ -569,15 +582,6 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) if (ticks && ticks < LONG_MAX) account_idle_ticks(ticks); #endif - - touch_softlockup_watchdog(); - /* - * Cancel the scheduled timer and restore the tick - */ - ts->tick_stopped = 0; - ts->idle_exittime = now; - - tick_nohz_restart(ts, now); } /** @@ -605,8 +609,10 @@ void tick_nohz_idle_exit(void) if (ts->idle_active) tick_nohz_stop_idle(cpu, now); - if (ts->tick_stopped) + if (ts->tick_stopped) { tick_nohz_restart_sched_tick(ts, now); + tick_nohz_account_idle_ticks(ts); + } local_irq_enable(); } @@ -811,7 +817,8 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) */ if (ts->tick_stopped) { touch_softlockup_watchdog(); - ts->idle_jiffies++; + if (idle_cpu(cpu)) + ts->idle_jiffies++; } update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING); -- GitLab From f5d411c91ede162240f34e05a233f2759412988e Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 31 Jul 2011 17:44:12 +0200 Subject: [PATCH 1118/6849] nohz: Rename ts->idle_tick to ts->last_tick Now that idle and nohz logics are going to be independant each others, ts->idle_tick becomes too much a biased name to describe the field that saves the last scheduled tick on top of which we re-calculate the next tick to schedule when the timer is restarted. We want to reuse this even to stop the tick outside idle cases. So let's rename it to some more generic name: ts->last_tick. This changes a bit the timer list stat export so we need to increase its version. Signed-off-by: Frederic Weisbecker Cc: Alessio Igor Bogani Cc: Andrew Morton Cc: Avi Kivity Cc: Chris Metcalf Cc: Christoph Lameter Cc: Daniel Lezcano Cc: Geoff Levand Cc: Gilad Ben Yossef Cc: Hakan Akkan Cc: Ingo Molnar Cc: Kevin Hilman Cc: Max Krasnyansky Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Stephen Hemminger Cc: Steven Rostedt Cc: Sven-Thorsten Dietrich Cc: Thomas Gleixner --- include/linux/tick.h | 8 ++++---- kernel/time/tick-sched.c | 4 ++-- kernel/time/timer_list.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/linux/tick.h b/include/linux/tick.h index ab8be90b5cc9..f37fceb69b73 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -31,10 +31,10 @@ enum tick_nohz_mode { * struct tick_sched - sched tick emulation and no idle tick control/stats * @sched_timer: hrtimer to schedule the periodic tick in high * resolution mode - * @idle_tick: Store the last idle tick expiry time when the tick - * timer is modified for idle sleeps. This is necessary + * @last_tick: Store the last tick expiry time when the tick + * timer is modified for nohz sleeps. This is necessary * to resume the tick timer operation in the timeline - * when the CPU returns from idle + * when the CPU returns from nohz sleep. * @tick_stopped: Indicator that the idle tick has been stopped * @idle_jiffies: jiffies at the entry to idle for idle time accounting * @idle_calls: Total number of idle calls @@ -51,7 +51,7 @@ struct tick_sched { struct hrtimer sched_timer; unsigned long check_clocks; enum tick_nohz_mode nohz_mode; - ktime_t idle_tick; + ktime_t last_tick; int inidle; int tick_stopped; unsigned long idle_jiffies; diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 911834b33b8a..73cc4901336d 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -400,7 +400,7 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now) if (!ts->tick_stopped) { select_nohz_load_balancer(1); - ts->idle_tick = hrtimer_get_expires(&ts->sched_timer); + ts->last_tick = hrtimer_get_expires(&ts->sched_timer); ts->tick_stopped = 1; } @@ -526,7 +526,7 @@ ktime_t tick_nohz_get_sleep_length(void) static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) { hrtimer_cancel(&ts->sched_timer); - hrtimer_set_expires(&ts->sched_timer, ts->idle_tick); + hrtimer_set_expires(&ts->sched_timer, ts->last_tick); while (1) { /* Forward the time to expire in the future */ diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 3258455549f4..af5a7e9f164b 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c @@ -167,7 +167,7 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now) { struct tick_sched *ts = tick_get_tick_sched(cpu); P(nohz_mode); - P_ns(idle_tick); + P_ns(last_tick); P(tick_stopped); P(idle_jiffies); P(idle_calls); @@ -259,7 +259,7 @@ static int timer_list_show(struct seq_file *m, void *v) u64 now = ktime_to_ns(ktime_get()); int cpu; - SEQ_printf(m, "Timer List Version: v0.6\n"); + SEQ_printf(m, "Timer List Version: v0.7\n"); SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES); SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now); -- GitLab From 5b39939a40801f0c17e31adaf643d6e974227856 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 1 Aug 2011 00:06:10 +0200 Subject: [PATCH 1119/6849] nohz: Move ts->idle_calls incrementation into strict idle logic Since we want to prepare for making the nohz API to work further the idle case, we need to pull ts->idle_calls incrementation up to the callers in idle. To perform this, we split tick_nohz_stop_sched_tick() in two parts: a first one that checks if we can really stop the tick for idle, and another that actually stops it. Then from the callers in idle, we check if we can stop the tick and only then we increment idle_calls and finally relay to the nohz API that won't care about these details anymore. Signed-off-by: Frederic Weisbecker Cc: Alessio Igor Bogani Cc: Andrew Morton Cc: Avi Kivity Cc: Chris Metcalf Cc: Christoph Lameter Cc: Daniel Lezcano Cc: Geoff Levand Cc: Gilad Ben Yossef Cc: Hakan Akkan Cc: Ingo Molnar Cc: Kevin Hilman Cc: Max Krasnyansky Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Stephen Hemminger Cc: Steven Rostedt Cc: Sven-Thorsten Dietrich Cc: Thomas Gleixner --- kernel/time/tick-sched.c | 86 ++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 73cc4901336d..430e1b6901cc 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -271,47 +271,15 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time) } EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); -static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now) +static void tick_nohz_stop_sched_tick(struct tick_sched *ts, + ktime_t now, int cpu) { unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; ktime_t last_update, expires; struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; u64 time_delta; - int cpu; - - cpu = smp_processor_id(); - ts = &per_cpu(tick_cpu_sched, cpu); - - /* - * If this cpu is offline and it is the one which updates - * jiffies, then give up the assignment and let it be taken by - * the cpu which runs the tick timer next. If we don't drop - * this here the jiffies might be stale and do_timer() never - * invoked. - */ - if (unlikely(!cpu_online(cpu))) { - if (cpu == tick_do_timer_cpu) - tick_do_timer_cpu = TICK_DO_TIMER_NONE; - } - - if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) - return; - - if (need_resched()) - return; - if (unlikely(local_softirq_pending() && cpu_online(cpu))) { - static int ratelimit; - - if (ratelimit < 10) { - printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", - (unsigned int) local_softirq_pending()); - ratelimit++; - } - return; - } - ts->idle_calls++; /* Read jiffies and the time when jiffies were updated last */ do { seq = read_seqbegin(&xtime_lock); @@ -441,16 +409,56 @@ out: ts->sleep_length = ktime_sub(dev->next_event, now); } +static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) +{ + /* + * If this cpu is offline and it is the one which updates + * jiffies, then give up the assignment and let it be taken by + * the cpu which runs the tick timer next. If we don't drop + * this here the jiffies might be stale and do_timer() never + * invoked. + */ + if (unlikely(!cpu_online(cpu))) { + if (cpu == tick_do_timer_cpu) + tick_do_timer_cpu = TICK_DO_TIMER_NONE; + } + + if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) + return false; + + if (need_resched()) + return false; + + if (unlikely(local_softirq_pending() && cpu_online(cpu))) { + static int ratelimit; + + if (ratelimit < 10) { + printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", + (unsigned int) local_softirq_pending()); + ratelimit++; + } + return false; + } + + return true; +} + static void __tick_nohz_idle_enter(struct tick_sched *ts) { ktime_t now; - int was_stopped = ts->tick_stopped; + int cpu = smp_processor_id(); - now = tick_nohz_start_idle(smp_processor_id(), ts); - tick_nohz_stop_sched_tick(ts, now); + now = tick_nohz_start_idle(cpu, ts); - if (!was_stopped && ts->tick_stopped) - ts->idle_jiffies = ts->last_jiffies; + if (can_stop_idle_tick(cpu, ts)) { + int was_stopped = ts->tick_stopped; + + ts->idle_calls++; + tick_nohz_stop_sched_tick(ts, now, cpu); + + if (!was_stopped && ts->tick_stopped) + ts->idle_jiffies = ts->last_jiffies; + } } /** -- GitLab From 84bf1bccc60cc64376125ea2eae05e4ba12f795b Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 1 Aug 2011 01:25:38 +0200 Subject: [PATCH 1120/6849] nohz: Move next idle expiry time record into idle logic area The next idle expiry time record and idle sleeps tracking are statistics that only concern idle. Since we want the nohz APIs to become usable further idle context, let's pull up the handling of these statistics to the callers in idle. Signed-off-by: Frederic Weisbecker Cc: Alessio Igor Bogani Cc: Andrew Morton Cc: Avi Kivity Cc: Chris Metcalf Cc: Christoph Lameter Cc: Daniel Lezcano Cc: Geoff Levand Cc: Gilad Ben Yossef Cc: Hakan Akkan Cc: Ingo Molnar Cc: Kevin Hilman Cc: Max Krasnyansky Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Stephen Hemminger Cc: Steven Rostedt Cc: Sven-Thorsten Dietrich Cc: Thomas Gleixner --- kernel/time/tick-sched.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 430e1b6901cc..60c9c60e9108 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -271,11 +271,11 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time) } EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); -static void tick_nohz_stop_sched_tick(struct tick_sched *ts, - ktime_t now, int cpu) +static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, + ktime_t now, int cpu) { unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; - ktime_t last_update, expires; + ktime_t last_update, expires, ret = { .tv64 = 0 }; struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; u64 time_delta; @@ -358,6 +358,8 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, if (ts->tick_stopped && ktime_equal(expires, dev->next_event)) goto out; + ret = expires; + /* * nohz_stop_sched_tick can be called several times before * the nohz_restart_sched_tick is called. This happens when @@ -372,11 +374,6 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ts->tick_stopped = 1; } - ts->idle_sleeps++; - - /* Mark expires */ - ts->idle_expires = expires; - /* * If the expiration time == KTIME_MAX, then * in this case we simply stop the tick timer. @@ -407,6 +404,8 @@ out: ts->next_jiffies = next_jiffies; ts->last_jiffies = last_jiffies; ts->sleep_length = ktime_sub(dev->next_event, now); + + return ret; } static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) @@ -445,7 +444,7 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) static void __tick_nohz_idle_enter(struct tick_sched *ts) { - ktime_t now; + ktime_t now, expires; int cpu = smp_processor_id(); now = tick_nohz_start_idle(cpu, ts); @@ -454,7 +453,12 @@ static void __tick_nohz_idle_enter(struct tick_sched *ts) int was_stopped = ts->tick_stopped; ts->idle_calls++; - tick_nohz_stop_sched_tick(ts, now, cpu); + + expires = tick_nohz_stop_sched_tick(ts, now, cpu); + if (expires.tv64 > 0LL) { + ts->idle_sleeps++; + ts->idle_expires = expires; + } if (!was_stopped && ts->tick_stopped) ts->idle_jiffies = ts->last_jiffies; -- GitLab From af03891f61d7b69eebc79d07bf580faaa9636fbc Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 31 May 2012 18:51:05 -0300 Subject: [PATCH 1121/6849] [media] v4l: Correct create_bufs documentation Patch id 6016af82eafcb6e086a8f2a2197b46029a843d68 ("[media] v4l2: use __u32 rather than enums in ioctl() structs") unintentionally changes the type of the format field in struct v4l2_create_buffers from struct v4l2_format to __u32. Revert that change. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/vidioc-create-bufs.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml index 765549ff8a71..7cf3116c2cc5 100644 --- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml @@ -108,10 +108,9 @@ information. /> - __u32 + &v4l2-format; format - Filled in by the application, preserved by the driver. - See . + Filled in by the application, preserved by the driver. __u32 -- GitLab From d9762df4a9d0e412b6676a96135323d6924406b8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Jun 2012 02:17:16 -0300 Subject: [PATCH 1122/6849] [media] Fix vivi regression This patch fixes a regression introduced by commit 5126f2590bee412e3053de851cb07f531e4be36a: [media] v4l2-dev: add flag to have the core lock all file operations I forgot to add the locks to the vivi read operation. Regards, Hans Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0960d7f0d394..08c10240e70f 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1149,10 +1149,14 @@ static ssize_t vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { struct vivi_dev *dev = video_drvdata(file); + int err; dprintk(dev, 1, "read called\n"); - return vb2_read(&dev->vb_vidq, data, count, ppos, + mutex_lock(&dev->mutex); + err = vb2_read(&dev->vb_vidq, data, count, ppos, file->f_flags & O_NONBLOCK); + mutex_unlock(&dev->mutex); + return err; } static unsigned int -- GitLab From dbebe1589d3a86658f32e74396611452c5f34481 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 15:02:57 -0600 Subject: [PATCH 1123/6849] ARM: tegra: defconfig updates Enable: * SND_SOC_TEGRA_WM8753 (new feature) * TPS65910 (Cardhu regulator) * CONFIG_I2C_MUX (dependency of:) * CONFIG_I2C_MUX_PINCTRL (for Seaboard) Remove some deleted options: * MACH_KAEN * MACH_VENTANA * MACH_WARIO Signed-off-by: Laxman Dewangan Signed-off-by: Stephen Warren --- arch/arm/configs/tegra_defconfig | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 1198dd61c7c4..4be9c1e80ee6 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -1,4 +1,6 @@ CONFIG_EXPERIMENTAL=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y @@ -25,14 +27,9 @@ CONFIG_ARCH_TEGRA=y CONFIG_ARCH_TEGRA_2x_SOC=y CONFIG_ARCH_TEGRA_3x_SOC=y CONFIG_MACH_HARMONY=y -CONFIG_MACH_KAEN=y CONFIG_MACH_PAZ00=y CONFIG_MACH_TRIMSLICE=y -CONFIG_MACH_WARIO=y -CONFIG_MACH_VENTANA=y CONFIG_TEGRA_EMC_SCALING_ENABLE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_PREEMPT=y CONFIG_AEABI=y @@ -103,19 +100,24 @@ CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PINCTRL=y CONFIG_I2C_TEGRA=y CONFIG_SPI=y CONFIG_SPI_TEGRA=y +CONFIG_GPIO_TPS65910=y CONFIG_POWER_SUPPLY=y CONFIG_BATTERY_SBS=y CONFIG_SENSORS_LM90=y CONFIG_MFD_TPS6586X=y +CONFIG_MFD_TPS65910=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_VIRTUAL_CONSUMER=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_TPS62360=y CONFIG_REGULATOR_TPS6586X=y +CONFIG_REGULATOR_TPS65910=y CONFIG_SOUND=y CONFIG_SND=y # CONFIG_SND_SUPPORT_OLD_API is not set @@ -126,6 +128,7 @@ CONFIG_SND=y # CONFIG_SND_USB is not set CONFIG_SND_SOC=y CONFIG_SND_SOC_TEGRA=y +CONFIG_SND_SOC_TEGRA_WM8753=y CONFIG_SND_SOC_TEGRA_WM8903=y CONFIG_SND_SOC_TEGRA_TRIMSLICE=y CONFIG_SND_SOC_TEGRA_ALC5632=y -- GitLab From 2031b4c2b4904f7448ab9e4bc6b9bf16e32709f5 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 6 Jun 2012 10:33:10 +0530 Subject: [PATCH 1124/6849] ath9k: Fix a WARNING on suspend/resume with IBSS this patch is dependent on the patch "cfg80211: fix interface combinations" In ath9k currently we have ADHOC interface as a single incompatible interface. when drv_add_interface is called during resume we got to consider number of vifs already present in addition to checking the drivers 'opmode' information about ADHOC. we incorrectly assume an ADHOC interface is already present. Then we may miss some driver specific data for the ADHOC interface after resume. The above mentioned checks can be removed from the driver, as the patch 'cfg80211: fix interface combinations' ensures that if an interface type is not advertised by the driver in any of the interface combinations(via ieee80211_iface_combination) then it shall be treated as a single incompatible interface. Fixes the following warning on suspend/resume with ibss interface. ath: phy0: Cannot create ADHOC interface when other interfaces already exist. WARNING: at net/mac80211/driver-ops.h:12 ieee80211_reconfig+0x1882/0x1ca0 [mac80211]() Hardware name: 2842RK1 wlan2: Failed check-sdata-in-driver check, flags: 0x0 Call Trace: [] warn_slowpath_common+0x72/0xa0 [] ? ieee80211_reconfig+0x1882/0x1ca0 [mac80211] [] ? ieee80211_reconfig+0x1882/0x1ca0 [mac80211] [] warn_slowpath_fmt+0x33/0x40 [] ieee80211_reconfig+0x1882/0x1ca0 [mac80211] [] ? mutex_lock_nested+0x23a/0x2f0 [] ieee80211_resume+0x27/0x70 [mac80211] [] wiphy_resume+0x8f/0xa0 [cfg80211] Cc: stable@vger.kernel.org Cc: Rajkumar Manoharan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4de4473776ac..08506f190f27 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1443,15 +1443,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, } } - if ((ah->opmode == NL80211_IFTYPE_ADHOC) || - ((vif->type == NL80211_IFTYPE_ADHOC) && - sc->nvifs > 0)) { - ath_err(common, "Cannot create ADHOC interface when other" - " interfaces already exist.\n"); - ret = -EINVAL; - goto out; - } - ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->nvifs++; -- GitLab From a23415fd7ed4bfa8e203ecf141d43da7180193af Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 6 Jun 2012 10:33:42 +0530 Subject: [PATCH 1125/6849] ath9k: remove incompatible IBSS interface check in change_iface 'cfg80211: fix interface combinations' ensures that if an interface type is not advertised by the driver in any of the interface combinations (via ieee80211_iface_combination) then it shall be treated as a single incompatible interface. if there are more than one interfaces present and changing them to incompatible interface type is not possible. These checks will be properly handled by cfg80211_change_iface -> cfg80211_can_change_interface. this patch is dependent on 'cfg80211: fix interface combinations' Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 08506f190f27..ac41f1e3ab9f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1467,15 +1467,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); - /* See if new interface type is valid. */ - if ((new_type == NL80211_IFTYPE_ADHOC) && - (sc->nvifs > 1)) { - ath_err(common, "When using ADHOC, it must be the only" - " interface.\n"); - ret = -EINVAL; - goto out; - } - if (ath9k_uses_beacons(new_type) && !ath9k_uses_beacons(vif->type)) { if (sc->nbcnvifs >= ATH_BCBUF) { -- GitLab From b0fd49b7d7599dc87402df13ab6e571e2222601f Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 9 Jun 2012 18:45:20 +0300 Subject: [PATCH 1126/6849] rndis_wlan: fix matching bssid check in rndis_check_bssid_list() rndis_check_bssid_list() originally tried to check if bssid->mac and match_bssid are equal using compare_ether_addr() when it should use !compare_ether_addr(). This check was added by commit b5257c952dda24df7078c74b7b811b44c6e49206 as part of workaround for hardware issue. Commit 2e42e4747ea72943c21551d8a206b51a9893b1e0 that replaced compare_ether_addr with ether_addr_equal relieved that this compare to be inverse of what it should be. Compare was added as response to hardware bug, where bssid-list does not contain BSSID and other information of currently connected AP (spec insists that device must provide this information in the list when connected). Lack bssid-data on current connection then causes WARN_ON somewhere in cfg80211. Workaround was to check if bssid-list returns current bssid and if it does not, manually construct bssid information in other ways. And this workaround worked, with inverse check. Which must mean that when hardware is experiencing the problem, it's actually returning empty bssid-list and this check didn't make any difference for workaround. However inverse check causes workaround be activated when bssid-list returns only entry, currently connected BSSID. That does not cause problems in itself, just slightly more inaccurate information in scan-list. Cc: Joe Perches Cc: David S. Miller Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 2e9e6af21362..dfcd02ab6cae 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2110,7 +2110,7 @@ resize_buf: while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (!ether_addr_equal(bssid->mac, match_bssid)) + if (ether_addr_equal(bssid->mac, match_bssid)) *matched = true; } -- GitLab From 1761a110a9c36ad9ba26b104516677ad8cb38a08 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Jun 2012 11:20:31 -0300 Subject: [PATCH 1127/6849] [media] Fix regression in ioctl numbering Yuck. The VIDIOC_(TRY_)DECODER_CMD ioctls already had ioctl numbers 96 and 97, and after merging the timings API I forgot to continue numbering from 98. So now we have two ioctls with number 96 and two with 97. With the new table-driver ioctl handling in v4l2-ioctl.c it is essential that each ioctl has its own unique number, so let's fix this quickly for 3.5. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 370d11106c11..2039c5d3292e 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -2640,9 +2640,9 @@ struct v4l2_create_buffers { /* Experimental, these three ioctls may change over the next couple of kernel versions. */ -#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 96, struct v4l2_enum_dv_timings) -#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 97, struct v4l2_dv_timings) -#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 98, struct v4l2_dv_timings_cap) +#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) +#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) +#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) /* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */ -- GitLab From 0b5dabedcc9498013d7de2998f0828340657c8a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Jun 2012 12:32:07 -0300 Subject: [PATCH 1128/6849] [media] Fix query/enum_dv_timings regression Now query/enum_dv_timings finally work again. The timings API patches and the core ioctl changes clearly sailed right past each other without realizing that both needed to adapt to the other. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 5ccbd4629f9c..150020805681 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -679,6 +679,8 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); /* yes, really vidioc_subscribe_event */ SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); -- GitLab From 87736df2401f51e67e55b8d1e6aac98a7990002b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Jun 2012 17:48:46 -0300 Subject: [PATCH 1129/6849] [media] V4L2 spec fix Two small docbook fixes: - prepare-buf was not positioned in alphabetical order, moved to the right place. - the format field in create_bufs had the wrong type in the documentation Signed-off-by: Hans Verkuil Reviewed-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/v4l2.xml | 2 +- Documentation/DocBook/media/v4l/vidioc-create-bufs.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index 015c561754b7..008c2d73a484 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml @@ -560,6 +560,7 @@ and discussions on the V4L mailing list. &sub-g-tuner; &sub-log-status; &sub-overlay; + &sub-prepare-buf; &sub-qbuf; &sub-querybuf; &sub-querycap; @@ -567,7 +568,6 @@ and discussions on the V4L mailing list. &sub-query-dv-preset; &sub-query-dv-timings; &sub-querystd; - &sub-prepare-buf; &sub-reqbufs; &sub-s-hw-freq-seek; &sub-streamon; diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml index 7cf3116c2cc5..a2474ecb574a 100644 --- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml @@ -108,7 +108,7 @@ information. /> - &v4l2-format; + struct v4l2_format format Filled in by the application, preserved by the driver. -- GitLab From bffaecc75cc6cbbf1e46571256d7b137df61bff6 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 21 May 2012 12:28:14 -0300 Subject: [PATCH 1130/6849] [media] lg2160: fix off-by-one error in lg216x_write_regs Fix an off-by-one error in lg216x_write_regs, causing the last element of the lg216x init block to be ignored. Spotted by Dan Carpenter. Reported-by: Dan Carpenter Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lg2160.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb/frontends/lg2160.c index a3ab1a5b6597..cc11260e99df 100644 --- a/drivers/media/dvb/frontends/lg2160.c +++ b/drivers/media/dvb/frontends/lg2160.c @@ -126,7 +126,7 @@ static int lg216x_write_regs(struct lg216x_state *state, lg_reg("writing %d registers...\n", len); - for (i = 0; i < len - 1; i++) { + for (i = 0; i < len; i++) { ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); if (lg_fail(ret)) return ret; -- GitLab From 38e8b7d977786b0059c02744e4b96bc1e206d891 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 6 Jun 2012 21:12:40 -0700 Subject: [PATCH 1131/6849] mwifiex: shorten per channel scan time Currently the scan time per channel for active scanning is set to 200ms. It takes quite a while to finsh scanning on all channels, especially with a dual band configuration. Change the per channel scan time settings to the following values: passive scan: 110ms active scan: 30ms specific scan: 30ms Above settings have been tested on x86 and arm platforms. Signed-off-by: Bing Zhao Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index bd3b0bf94b9e..cbad00d7eb11 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -79,9 +79,9 @@ enum { #define SCAN_BEACON_ENTRY_PAD 6 -#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 200 -#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 200 -#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 110 +#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110 +#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30 +#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30 #define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) -- GitLab From 3249ba7376caa93af387d8e6b5e41b290934f88c Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 6 Jun 2012 21:12:41 -0700 Subject: [PATCH 1132/6849] mwifiex: fix simultaneous scan and Tx traffic problem If scan operation is started when Tx traffic is already running, driver locks Tx queue until it gets completed. With this logic there is a delay for Tx packets. This patch implements new approach to give Tx path higher priority in this case. Driver internally sends multiple synchronous scan commands to firmware when scan is requested by user. Now we will make sure that Tx queue is empty everytime before sending next scan command. If Tx queue isn't empty scan command will be postponsed by 20msec. This rule will be followed until Tx queue becomes empty or timeout of 1 second happens. In case of timeout scan operation will be aborted. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 65 +++++++++++++++++++++++++++++ drivers/net/wireless/mwifiex/main.c | 4 +- drivers/net/wireless/mwifiex/main.h | 5 +++ drivers/net/wireless/mwifiex/scan.c | 25 +++++++---- 4 files changed, 89 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index c1cb004db913..0f18ef6a30c8 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -57,6 +57,68 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) return 0; } +static void scan_delay_timer_fn(unsigned long data) +{ + struct mwifiex_private *priv = (struct mwifiex_private *)data; + struct mwifiex_adapter *adapter = priv->adapter; + struct cmd_ctrl_node *cmd_node, *tmp_node; + unsigned long flags; + + if (!mwifiex_wmm_lists_empty(adapter)) { + if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { + /* + * Abort scan operation by cancelling all pending scan + * command + */ + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + list_for_each_entry_safe(cmd_node, tmp_node, + &adapter->scan_pending_q, + list) { + list_del(&cmd_node->list); + cmd_node->wait_q_enabled = false; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + } + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, + flags); + + if (priv->user_scan_cfg) { + dev_dbg(priv->adapter->dev, + "info: %s: scan aborted\n", __func__); + cfg80211_scan_done(priv->scan_request, 1); + priv->scan_request = NULL; + kfree(priv->user_scan_cfg); + priv->user_scan_cfg = NULL; + } + } else { + /* + * Tx data queue is still not empty, delay scan + * operation further by 20msec. + */ + mod_timer(&priv->scan_delay_timer, jiffies + + msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); + adapter->scan_delay_cnt++; + } + } else { + /* + * Tx data queue is empty. Get scan command from scan_pending_q + * and put to cmd_pending_q to resume scan operation + */ + adapter->scan_delay_cnt = 0; + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + cmd_node = list_first_entry(&adapter->scan_pending_q, + struct cmd_ctrl_node, list); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + } +} + /* * This function initializes the private structure and sets default * values to the members. @@ -136,6 +198,9 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) priv->scan_block = false; + setup_timer(&priv->scan_delay_timer, scan_delay_timer_fn, + (unsigned long)priv); + return mwifiex_add_bss_prio_tbl(priv); } diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 3192855c31c0..0f06f07a70e6 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -244,8 +244,8 @@ process_start: } } - if (!adapter->scan_processing && !adapter->data_sent && - !mwifiex_wmm_lists_empty(adapter)) { + if ((!adapter->scan_processing || adapter->scan_delay_cnt) && + !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { mwifiex_wmm_process_tx(adapter); if (adapter->hs_activated) { adapter->is_hs_configured = false; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index cbad00d7eb11..5b32221077c4 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -87,6 +87,9 @@ enum { #define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) +#define MWIFIEX_MAX_SCAN_DELAY_CNT 50 +#define MWIFIEX_SCAN_DELAY_MSEC 20 + #define RSN_GTK_OUI_OFFSET 2 #define MWIFIEX_OUI_NOT_PRESENT 0 @@ -482,6 +485,7 @@ struct mwifiex_private { u16 proberesp_idx; u16 assocresp_idx; u16 rsn_idx; + struct timer_list scan_delay_timer; }; enum mwifiex_ba_status { @@ -686,6 +690,7 @@ struct mwifiex_adapter { struct completion fw_load; u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; u16 max_mgmt_ie_index; + u8 scan_delay_cnt; }; int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 74f045715723..ea2f1bdef8a2 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1772,14 +1772,23 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, priv->user_scan_cfg = NULL; } } else { - /* Get scan command from scan_pending_q and put to - cmd_pending_q */ - cmd_node = list_first_entry(&adapter->scan_pending_q, - struct cmd_ctrl_node, list); - list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - - mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + if (!mwifiex_wmm_lists_empty(adapter)) { + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + adapter->scan_delay_cnt = 1; + mod_timer(&priv->scan_delay_timer, jiffies + + msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); + } else { + /* Get scan command from scan_pending_q and put to + cmd_pending_q */ + cmd_node = list_first_entry(&adapter->scan_pending_q, + struct cmd_ctrl_node, list); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, + true); + } } done: -- GitLab From 658f37b736ce335edcdf1425228e8652ec6adf24 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 6 Jun 2012 21:12:42 -0700 Subject: [PATCH 1133/6849] mwifiex: scan less channels per scan command to improve Tx traffic Currently 4 channels are scanned per scan command. if scan request is issued by user during Tx traffic, radio will be out of channel for "4 * per_chan_scan_time" for each scan command and will not be able to receive Rx packets. This adds delay in data traffic. We can minimize it by reducing number of channels scanned per scan command in this scenario. We can not always scan 1 channel per scan command due to limitation of number of command buffers. So we add code to decide number of channels scanned per scan command in associated state. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/scan.c | 34 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index ea2f1bdef8a2..efaf26ccd6ba 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -28,7 +28,10 @@ /* The maximum number of channels the firmware can scan per command */ #define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14 -#define MWIFIEX_CHANNELS_PER_SCAN_CMD 4 +#define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD 4 +#define MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD 15 +#define MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD 27 +#define MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD 35 /* Memory needed to store a max sized Channel List TLV for a firmware scan */ #define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \ @@ -471,7 +474,7 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, * This routine is used for any scan that is not provided with a * specific channel list to scan. */ -static void +static int mwifiex_scan_create_channel_list(struct mwifiex_private *priv, const struct mwifiex_user_scan_cfg *user_scan_in, @@ -528,6 +531,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, } } + return chan_idx; } /* @@ -727,6 +731,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, u32 num_probes; u32 ssid_len; u32 chan_idx; + u32 chan_num; u32 scan_type; u16 scan_dur; u8 channel; @@ -850,7 +855,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, if (*filtered_scan) *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN; else - *max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD; + *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD; /* If the input config or adapter has the number of Probes set, add tlv */ @@ -962,13 +967,28 @@ mwifiex_config_scan(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: Scan: Scanning current channel only\n"); } - + chan_num = chan_idx; } else { dev_dbg(adapter->dev, "info: Scan: Creating full region channel list\n"); - mwifiex_scan_create_channel_list(priv, user_scan_in, - scan_chan_list, - *filtered_scan); + chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in, + scan_chan_list, + *filtered_scan); + } + + /* + * In associated state we will reduce the number of channels scanned per + * scan command to avoid any traffic delay/loss. This number is decided + * based on total number of channels to be scanned due to constraints + * of command buffers. + */ + if (priv->media_connected) { + if (chan_num < MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD) + *max_chan_per_scan = 1; + else if (chan_num < MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD) + *max_chan_per_scan = 2; + else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD) + *max_chan_per_scan = 3; } } -- GitLab From cba63e99e58231ecd665b0eddc9b73c65fe9c17c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 8 Jun 2012 13:24:55 +0530 Subject: [PATCH 1134/6849] ath9k_hw: Initvals update for AR9462 MSI is enabled by default for most of the 4th generation chips. Add this for AR9462 - this fixes PowerSave operation, the chip was not entering Network-Sleep mode earlier. With proper powering down of the MAC now, power consumption in associated state is reduced considerably. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index a10ece0cb6cd..4a93e1534c1d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -1007,6 +1007,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { static const u32 ar9462_2p0_soc_preamble[][2] = { /* Addr allmodes */ + {0x000040a4 ,0x00a0c1c9}, {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, -- GitLab From 7f0d9f430dc99303558adc30a75eef10c43f7bec Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Sun, 10 Jun 2012 22:11:56 +0200 Subject: [PATCH 1135/6849] ssb: add missing PCI ID for b/g/n single band BCM4322 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 14e4:432c is found on some bcm63xx devices. The device is working fine with b43. Reported-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski Signed-off-by: John W. Linville --- drivers/ssb/b43_pci_bridge.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index f551e5376147..266aa1648a02 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c @@ -36,6 +36,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, { 0, }, }; MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); -- GitLab From 110301833d6f6c74e4da3a31fc3d327eb3436812 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 15 May 2012 05:12:44 -0300 Subject: [PATCH 1136/6849] [media] radio/si470x: Add support for the Axentia ALERT FM USB Receiver Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 +++ drivers/media/radio/si470x/radio-si470x-usb.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 4da66b4b977c..20fecb8dd297 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1800,6 +1800,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, + { HID_USB_DEVICE(USB_VENDOR_ID_AXENTIA, USB_DEVICE_ID_AXENTIA_FM_RADIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e39aecb1f9f2..70298d13d3e9 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -157,6 +157,9 @@ #define USB_VENDOR_ID_AVERMEDIA 0x07ca #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 +#define USB_VENDOR_ID_AXENTIA 0x12cf +#define USB_DEVICE_ID_AXENTIA_FM_RADIO 0x7111 + #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index e9f638761296..f412f7ab270b 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -51,6 +51,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, + /* Axentia ALERT FM USB Receiver */ + { USB_DEVICE_AND_INTERFACE_INFO(0x12cf, 0x7111, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; -- GitLab From 0875eb755b66a6766be117133dbb6d8157ace337 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 18 May 2012 15:01:36 -0300 Subject: [PATCH 1137/6849] [media] snd_tea575x: Report correct frequency range for EU/US versus JA models My EU/US 5757 cannot tune below approx 86 Mhz, that is below that it does not even generate the standard not tuned to anything radio noise anymore, so clearly the 5757 cannot tune to the Japanese frequencies. This patch assumes that likewise the 5759 cannot tune to the EU/US frequencies. Signed-off-by: Hans de Goede CC: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- sound/i2c/other/tea575x-tuner.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 582aace20ea3..aa9900dff6e9 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -37,8 +37,8 @@ MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); MODULE_LICENSE("GPL"); -#define FREQ_LO (76U * 16000) -#define FREQ_HI (108U * 16000) +#define FREQ_LO ((tea->tea5759 ? 760 : 875) * 1600U) +#define FREQ_HI ((tea->tea5759 ? 910 : 1080) * 1600U) /* * definitions -- GitLab From 5daf53a6eb5c54c618c9def388d81c2769fd11a0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 May 2012 07:57:03 -0300 Subject: [PATCH 1138/6849] [media] snd_tea575x: Make the module using snd_tea575x the fops owner Before this patch the owner field of the /dev/radio# device fops was set to the snd-tea575x-tuner module itself. Meaning that the module which was using it could be rmmod-ed while the device is open, and then BAD things happen. I know, as I found out the hard way :) Note that there is no need to also somehow increase the refcount of the snd-tea575x-tuner module itself, since any drivers using it will have symbolic references to it. Signed-off-by: Hans de Goede CC: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-maxiradio.c | 2 +- drivers/media/radio/radio-sf16fmr2.c | 2 +- include/sound/tea575x-tuner.h | 3 ++- sound/i2c/other/tea575x-tuner.c | 7 ++++--- sound/pci/es1968.c | 2 +- sound/pci/fm801.c | 4 ++-- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 740a3d5520c7..b415211d0c4b 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -157,7 +157,7 @@ static int __devinit maxiradio_probe(struct pci_dev *pdev, const struct pci_devi goto err_out_free_region; dev->io = pci_resource_start(pdev, 0); - if (snd_tea575x_init(&dev->tea)) { + if (snd_tea575x_init(&dev->tea, THIS_MODULE)) { printk(KERN_ERR "radio-maxiradio: Unable to detect TEA575x tuner\n"); goto err_out_free_region; } diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52b8011f1b23..4efcbec74c52 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -238,7 +238,7 @@ static int __devinit fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s", fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev)); - if (snd_tea575x_init(&fmr2->tea)) { + if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) { printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); release_region(fmr2->io, 2); return -ENODEV; diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index ec3f910aa40b..0c3c2fb0f939 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h @@ -44,6 +44,7 @@ struct snd_tea575x_ops { struct snd_tea575x { struct v4l2_device *v4l2_dev; + struct v4l2_file_operations fops; struct video_device vd; /* video device */ int radio_nr; /* radio_nr */ bool tea5759; /* 5759 chip is present */ @@ -62,7 +63,7 @@ struct snd_tea575x { int (*ext_init)(struct snd_tea575x *tea); }; -int snd_tea575x_init(struct snd_tea575x *tea); +int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner); void snd_tea575x_exit(struct snd_tea575x *tea); #endif /* __SOUND_TEA575X_TUNER_H */ diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index aa9900dff6e9..ac62ee791a60 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -317,7 +317,6 @@ static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) } static const struct v4l2_file_operations tea575x_fops = { - .owner = THIS_MODULE, .unlocked_ioctl = video_ioctl2, .open = v4l2_fh_open, .release = v4l2_fh_release, @@ -337,7 +336,6 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { }; static const struct video_device tea575x_radio = { - .fops = &tea575x_fops, .ioctl_ops = &tea575x_ioctl_ops, .release = video_device_release_empty, }; @@ -349,7 +347,7 @@ static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { /* * initialize all the tea575x chips */ -int snd_tea575x_init(struct snd_tea575x *tea) +int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner) { int retval; @@ -374,6 +372,9 @@ int snd_tea575x_init(struct snd_tea575x *tea) tea->vd.lock = &tea->mutex; tea->vd.v4l2_dev = tea->v4l2_dev; tea->vd.ctrl_handler = &tea->ctrl_handler; + tea->fops = tea575x_fops; + tea->fops.owner = owner; + tea->vd.fops = &tea->fops; set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); /* disable hw_freq_seek if we can't use it */ if (tea->cannot_read_data) diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index a8faae1c85e4..0f2811eeeebd 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -2769,7 +2769,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, chip->tea.ops = &snd_es1968_tea_ops; strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); - if (!snd_tea575x_init(&chip->tea)) + if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) printk(KERN_INFO "es1968: detected TEA575x radio\n"); #endif diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index a416ea8af3e9..5265c576a26a 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1254,7 +1254,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && (tea575x_tuner & TUNER_TYPE_MASK) < 4) { - if (snd_tea575x_init(&chip->tea)) { + if (snd_tea575x_init(&chip->tea, THIS_MODULE)) { snd_printk(KERN_ERR "TEA575x radio not found\n"); snd_fm801_free(chip); return -ENODEV; @@ -1263,7 +1263,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, /* autodetect tuner connection */ for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { chip->tea575x_tuner = tea575x_tuner; - if (!snd_tea575x_init(&chip->tea)) { + if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { snd_printk(KERN_INFO "detected TEA575x radio type %s\n", get_tea575x_gpio(chip)->name); break; -- GitLab From 40e006aea811afb15e56164383b914cff7a078c7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 May 2012 11:19:06 -0300 Subject: [PATCH 1139/6849] [media] snd_tea575x: set_freq: update cached freq to the actual achieved frequency Signed-off-by: Hans de Goede CC: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- sound/i2c/other/tea575x-tuner.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index ac62ee791a60..7eca25fae413 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -120,9 +120,9 @@ static u32 snd_tea575x_read(struct snd_tea575x *tea) return data; } -static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) +static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val) { - u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; + u32 freq = val & TEA575X_BIT_FREQ_MASK; if (freq == 0) return freq; @@ -139,6 +139,11 @@ static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */ } +static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) +{ + return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea)); +} + static void snd_tea575x_set_freq(struct snd_tea575x *tea) { u32 freq = tea->freq; @@ -156,6 +161,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea) tea->val &= ~TEA575X_BIT_FREQ_MASK; tea->val |= freq & TEA575X_BIT_FREQ_MASK; snd_tea575x_write(tea, tea->val); + tea->freq = snd_tea575x_val_to_freq(tea, tea->val); } /* -- GitLab From 5c164646e25a5a073875c6ca346efa0d5afb6934 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 May 2012 08:11:04 -0300 Subject: [PATCH 1140/6849] [media] bttv: Use btv->has_radio rather then the card info when registering the tuner bttv_init_card2() sets btv->has_audio to a *default* value from the tvcards array and then may update it by reading a card specific eeprom or gpio detection. After bttv_init_card2(), bttv_init_tuner() gets called, and it should clearly use the updated, dynamic has_radio value from btv->has_radio, rather then the const value in the tvcards array. This fixes the radio not working on my Hauppauge WinTV. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index ff2933ab705f..1c030fecbf41 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -3649,7 +3649,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) struct tuner_setup tun_setup; /* Load tuner module before issuing tuner config call! */ - if (bttv_tvcards[btv->c.type].has_radio) + if (btv->has_radio) v4l2_i2c_new_subdev(&btv->c.v4l2_dev, &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); @@ -3664,7 +3664,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) tun_setup.type = btv->tuner_type; tun_setup.addr = addr; - if (bttv_tvcards[btv->c.type].has_radio) + if (btv->has_radio) tun_setup.mode_mask |= T_RADIO; bttv_call_all(btv, tuner, s_type_addr, &tun_setup); -- GitLab From 792a21b0def241e73345e366a456ae7e516ba2f5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 May 2012 12:05:30 -0300 Subject: [PATCH 1141/6849] [media] bttv: Remove unused needs_tvaudio card variable Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 76 -------------------------- drivers/media/video/bt8xx/bttv.h | 1 - 2 files changed, 77 deletions(-) diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 1c030fecbf41..959d4e15c98e 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -371,7 +371,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -384,7 +383,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -398,7 +396,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -414,7 +411,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -427,7 +423,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 1, 0, 1 }, .gpiomute = 3, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -440,7 +435,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0f, .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tvphone_audio, @@ -454,7 +448,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -469,7 +462,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0xc00, 0x800, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -482,7 +474,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 2, 3 }, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -496,7 +487,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -510,7 +500,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -524,7 +513,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -536,7 +524,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, - .needs_tvaudio = 1, .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -553,7 +540,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -567,7 +553,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 1, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -583,7 +568,6 @@ struct tvcard bttv_tvcards[] = { /* 2003-10-20 by "Anton A. Arapov" */ .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -597,7 +581,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1, 0), .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, .gpiomute = 0xcfa007, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .volume_gpio = winview_volume, @@ -611,7 +594,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0, 0, 0 }, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -660,7 +642,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 0x800, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -691,7 +672,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -706,7 +686,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -720,7 +699,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -748,7 +726,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, .gpiomute = 0x40000, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -793,7 +770,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, @@ -834,7 +810,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -847,7 +822,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0, 0x300, 0x900 }, .gpiomute = 0x900, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -874,7 +848,6 @@ struct tvcard bttv_tvcards[] = { Note: There exists another variant "Winfast 2000" with tv stereo !? Note: eeprom only contains FF and pci subsystem id 107d:6606 */ - .needs_tvaudio = 0, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ @@ -934,7 +907,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0x551400, 0x551200, 0, 0 }, .gpiomute = 0x551c00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -949,7 +921,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0xd0001, 0, 0 }, .gpiomute = 1, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -966,7 +937,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -980,7 +950,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 4, 11, 7 }, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -995,7 +964,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0}, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1066,7 +1034,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1084,7 +1051,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {2,0,0,0 }, .gpiomute = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1163,7 +1129,6 @@ struct tvcard bttv_tvcards[] = { MUX2 (mask 0x30000): 0,2,3= from MSP34xx 1= FM stereo Radio from Tuner */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1179,7 +1144,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0x10, 8 }, .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1218,7 +1182,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1250,7 +1213,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(3, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_ABSENT, @@ -1266,7 +1228,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0x800, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, @@ -1312,7 +1273,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2), .gpiomux = { }, .no_msp34xx = 1, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1329,7 +1289,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 1, 0, 4, 4 }, .gpiomute = 9, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1379,7 +1338,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x1800, .audio_mode_gpio= fv2000s_audio, .no_msp34xx = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1393,7 +1351,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, .gpiomute = 0x900, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1477,7 +1434,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ .gpiomute = 13, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, @@ -1514,7 +1470,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, .gpiomute = 0x09, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1540,7 +1495,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -1567,7 +1521,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 4, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1597,7 +1550,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1619,7 +1571,6 @@ struct tvcard bttv_tvcards[] = { * btwincap uses 0x80000/0x80003 */ .gpiomute = 4, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1655,7 +1606,6 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .muxsel = MUXSEL(2, 0, 1, 1), - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1875,7 +1825,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3}, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1902,7 +1851,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1920,7 +1868,6 @@ struct tvcard bttv_tvcards[] = { /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, .gpiomute = 0x0f, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, @@ -1936,7 +1883,6 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -2034,7 +1980,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -2049,7 +1994,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2062,7 +2006,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2079,7 +2022,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2094,7 +2036,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2118,7 +2059,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, /* card has no svhs */ - .needs_tvaudio = 0, .no_msp34xx = 1, .no_tda7432 = 1, .gpiomask = 0x00, @@ -2168,7 +2108,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 1, 1 }, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_35, @@ -2210,7 +2149,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, .no_tda7432 = 1, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -2222,7 +2160,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .svhs = 2, - .needs_tvaudio = 0, .gpiomask = 0x68, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, @@ -2241,7 +2178,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2265,7 +2201,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, - .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2358,7 +2293,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2405,7 +2339,6 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .gpiomask = 0x008007, .gpiomux = { 0, 0x000001,0,0 }, - .needs_tvaudio = 1, .has_radio = 1, }, [BTTV_BOARD_TIBET_CS16] = { @@ -2518,7 +2451,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, @@ -2534,7 +2466,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, @@ -2615,7 +2546,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -2714,7 +2644,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -2746,7 +2675,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ .gpiomute = 3, /* CONTVFMi */ - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2785,7 +2713,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(0, 2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2799,7 +2726,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2813,7 +2739,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(3, 2, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2877,7 +2802,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index c5171619ac79..acfe2f3b92d9 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -236,7 +236,6 @@ struct tvcard { /* i2c audio flags */ unsigned int no_msp34xx:1; unsigned int no_tda7432:1; - unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; /* Note: currently no card definition needs to mark the presence of a RDS saa6588 chip. If this is ever needed, then add a new -- GitLab From 7025e521b1b068af8a47a7625335a605bbd4d7ea Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 21 May 2012 07:46:22 -0300 Subject: [PATCH 1142/6849] [media] bttv: The Hauppauge 61334 needs the msp3410 to do radio demodulation The (radio) audio out from the tuner (which can also demod FM radio) does not seem to be hooked up to the msp3410 on this board in any way, so the only way to get sound from the radio part is to make the msp3410 do the FM radio demod. The msp3410 can handle this fine, but it is a bit weird compared to how it is handled on other boards. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 4 ++++ drivers/media/video/bt8xx/bttv-driver.c | 5 +++++ drivers/media/video/bt8xx/bttvp.h | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 959d4e15c98e..856ab962cd63 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -3648,6 +3648,10 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; } + + /* The 61334 needs the msp3410 to do the radio demod to get sound */ + if (tv.model == 61334) + btv->radio_uses_msp_demodulator = 1; } static int terratec_active_radio_upgrade(struct bttv *btv) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a9cfb0f4be48..ff7a589d8e0f 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -1218,6 +1218,11 @@ audio_mux(struct bttv *btv, int input, int mute) For now this is sufficient. */ switch (input) { case TVAUDIO_INPUT_RADIO: + /* Some boards need the msp do to the radio demod */ + if (btv->radio_uses_msp_demodulator) { + in = MSP_INPUT_DEFAULT; + break; + } in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index db943a8d580d..70fd4f23f605 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -440,6 +440,7 @@ struct bttv { /* radio data/state */ int has_radio; int radio_user; + int radio_uses_msp_demodulator; /* miro/pinnacle + Aimslab VHX philips matchbox (tea5757 radio tuner) support */ -- GitLab From b6fc2eb965726bf31bbbca6e7a833f98c03a6ce2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 May 2012 14:51:22 -0300 Subject: [PATCH 1143/6849] [media] gspca_pac7311: Correct number of controls This avoids the need for a re-alloc during init. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 2cb7d95f7be7..115da169f32a 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -418,7 +418,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_handler_init(hdl, 5); sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, 15, 1, 7); -- GitLab From bc378feeda46633cfa92dac7a7ef5df66047b0ef Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 May 2012 14:55:15 -0300 Subject: [PATCH 1144/6849] [media] gscpa_sn9c20x: Move clustering of controls to after error checking Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sn9c20x.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index ad098202d7f0..6c31e46a1fd2 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -1761,7 +1761,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_SATURATION, 0, 255, 1, 127); sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0); - v4l2_ctrl_cluster(4, &sd->brightness); sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, 0, 255, 1, 0x10); @@ -1770,7 +1769,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); - v4l2_ctrl_cluster(2, &sd->blue); if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && @@ -1779,7 +1777,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_HFLIP, 0, 1, 1, 0); sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_cluster(2, &sd->hflip); } if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && @@ -1794,6 +1791,20 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_GAIN, 0, 28, 1, 0); sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + } + + sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_cluster(4, &sd->brightness); + v4l2_ctrl_cluster(2, &sd->blue); + if (sd->hflip) + v4l2_ctrl_cluster(2, &sd->hflip); + if (sd->autogain) { if (sd->sensor == SENSOR_SOI968) /* this sensor doesn't have the exposure control and autogain is clustered with gain instead. This works @@ -1803,13 +1814,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) /* Otherwise autogain is clustered with exposure. */ v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); } - - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } return 0; } -- GitLab From cf3c1c319500e879daa1487f41bb094bd377566f Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 16 May 2012 18:42:45 -0300 Subject: [PATCH 1145/6849] [media] gspca_ov534: make AGC and AWB controls independent Even if the best results are indeed achieved with both AGC and AWB enabled, the webcam is capable of setting these independently, and the user can see the difference of any of the 4 combinations of these two boolean controls. Removing the dependency from one another simplifies the code and gives more control to the user. Signed-off-by: Antonio Ospite Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index b5acb1e4b4e7..c16bd1b7914a 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -96,7 +96,7 @@ static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setgain(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); -static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val); +static void setagc(struct gspca_dev *gspca_dev); static void setawb(struct gspca_dev *gspca_dev); static void setaec(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); @@ -189,7 +189,7 @@ static const struct ctrl sd_ctrls[] = { .step = 1, .default_value = 1, }, - .set = sd_setagc + .set_control = setagc }, [AWB] = { { @@ -1242,10 +1242,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->ctrls = sd->ctrls; - /* the auto white balance control works only when auto gain is set */ - if (sd_ctrls[AGC].qctrl.default_value == 0) - gspca_dev->ctrl_inac |= (1 << AWB); - cam->cam_mode = ov772x_mode; cam->nmodes = ARRAY_SIZE(ov772x_mode); @@ -1486,29 +1482,6 @@ scan_next: } while (remaining_len > 0); } -static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->ctrls[AGC].val = val; - - /* the auto white balance control works only - * when auto gain is set */ - if (val) { - gspca_dev->ctrl_inac &= ~(1 << AWB); - } else { - gspca_dev->ctrl_inac |= (1 << AWB); - if (sd->ctrls[AWB].val) { - sd->ctrls[AWB].val = 0; - if (gspca_dev->streaming) - setawb(gspca_dev); - } - } - if (gspca_dev->streaming) - setagc(gspca_dev); - return gspca_dev->usb_err; -} - static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { -- GitLab From af05ef01e9cde84620c6855a8d8ab9c8a1db9009 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 May 2012 11:24:05 -0300 Subject: [PATCH 1146/6849] [media] gspca-core: Fix buffers staying in queued state after a stream_off This fixes a regression introduced by commit f7059ea and should be backported to all supported stable kernels which have this commit. Signed-off-by: Hans de Goede Tested-by: Antonio Ospite CC: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 137166d73945..31721eadc597 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { struct gspca_dev *gspca_dev = video_drvdata(file); - int ret; + int i, ret; if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1678,6 +1678,8 @@ static int vidioc_streamoff(struct file *file, void *priv, wake_up_interruptible(&gspca_dev->wq); /* empty the transfer queues */ + for (i = 0; i < gspca_dev->nframes; i++) + gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; atomic_set(&gspca_dev->fr_q, 0); atomic_set(&gspca_dev->fr_i, 0); gspca_dev->fr_o = 0; -- GitLab From f19ed98111d508bafc1aa31478f2c612cbdc26b5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 28 May 2012 14:04:07 -0300 Subject: [PATCH 1147/6849] [media] gspca - ov534/ov534_9: Fix sccd_read/write errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ov534 bridge is too slow to handle the sensor accesses requested by fast hosts giving 'sccb_reg_write failed'. A small delay fixes the problem. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 1 + drivers/media/video/gspca/ov534_9.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index c16bd1b7914a..80c81dd6d68b 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -851,6 +851,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { + msleep(10); data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); switch (data) { diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index e6601b886032..0120f947e076 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c @@ -1008,6 +1008,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { + msleep(10); data = reg_r(gspca_dev, OV534_REG_STATUS); switch (data) { -- GitLab From f9798ef6342e6dad3fc3d7aa2ce2147469acf507 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 28 May 2012 14:05:25 -0300 Subject: [PATCH 1148/6849] [media] gspca - sonixj: Fix bad values of webcam 0458:7025 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The webcam 0458:7025 (Eye911Q) has: - an inverted power pin, - a sensor mi0360b which cannot be probed. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 4d1696d1a7f4..f38faa9b37c3 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -3120,7 +3120,7 @@ static const struct sd_desc sd_desc = { | (SENSOR_ ## sensor << 8) \ | (flags) static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, + {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)}, {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)}, {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)}, -- GitLab From 5cd0b50fddb6649bfd73648912464e1cc90bd0c1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 May 2012 02:41:39 -0300 Subject: [PATCH 1149/6849] [media] saa7146_fops: remove unused variable Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 7d42c11c8684..0cdbd742974a 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -198,7 +198,6 @@ static int fops_open(struct file *file) struct saa7146_dev *dev = video_drvdata(file); struct saa7146_fh *fh = NULL; int result = 0; - enum v4l2_buf_type type; DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); @@ -207,10 +206,6 @@ static int fops_open(struct file *file) DEB_D("using: %p\n", dev); - type = vdev->vfl_type == VFL_TYPE_GRABBER - ? V4L2_BUF_TYPE_VIDEO_CAPTURE - : V4L2_BUF_TYPE_VBI_CAPTURE; - /* check if an extension is registered */ if( NULL == dev->ext ) { DEB_S("no extension registered for this device\n"); -- GitLab From 91e0cd499fe8482d5104c1f8f49b478f76617b40 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 May 2012 02:48:37 -0300 Subject: [PATCH 1150/6849] [media] cx24110: fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v4l-dvb-git/drivers/media/dvb/frontends/cx24110.c: In function ‘cx24110_read_ucblocks’: v4l-dvb-git/drivers/media/dvb/frontends/cx24110.c:520:40: warning: value computed is not used [-Wunused-value] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cx24110.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 98ecaf0900d6..3180f5b2a6a6 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -516,9 +516,9 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) if(cx24110_readreg(state,0x10)&0x40) { /* the RS error counter has finished one counting window */ cx24110_writereg(state,0x10,0x60); /* select the byer reg */ - cx24110_readreg(state, 0x12) | + (void)(cx24110_readreg(state, 0x12) | (cx24110_readreg(state, 0x13) << 8) | - (cx24110_readreg(state, 0x14) << 16); + (cx24110_readreg(state, 0x14) << 16)); cx24110_writereg(state,0x10,0x70); /* select the bler reg */ state->lastbler=cx24110_readreg(state,0x12)| (cx24110_readreg(state,0x13)<<8)| -- GitLab From f9ac50c244f9030b300d6f390e838239612d7efa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 May 2012 06:32:52 -0300 Subject: [PATCH 1151/6849] [media] vino: fix compiler warnings v4l-dvb-git/drivers/media/video/vino.c: In function 'vino_acquire_input': v4l-dvb-git/drivers/media/video/vino.c:2602:18: warning: 'data_norm' may be used uninitialized in this function [-Wuninitialized] v4l-dvb-git/drivers/media/video/vino.c: In function 'vino_set_input': v4l-dvb-git/drivers/media/video/vino.c:2690:19: warning: 'data_norm' may be used uninitialized in this function [-Wuninitialized] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vino.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 4d7391ec8001..aae1720b2f2d 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -2561,7 +2561,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) } else if (vino_drvdata->decoder && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) { int input; - int data_norm; + int data_norm = 0; v4l2_std_id norm; input = VINO_INPUT_COMPOSITE; @@ -2651,7 +2651,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (vino_drvdata->decoder_owner == vcs->channel) { - int data_norm; + int data_norm = 0; v4l2_std_id norm; ret = decoder_call(video, s_routing, -- GitLab From 3e1141e2ce5667301a74ca2ef396d9bd5e995f7f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 25 May 2012 09:29:12 -0300 Subject: [PATCH 1152/6849] [media] smsusb: add autodetection support for USB ID 2040:f5a0 Signed-off-by: Michael Krufky Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 63c004a25e0b..664e460f247b 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -544,6 +544,8 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xc0a0), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xf5a0), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; -- GitLab From ef3835974103fc52c12962d91b224fbc2edcabe6 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:50:59 +0200 Subject: [PATCH 1153/6849] mm: frontswap: remove casting from function calls through ops structure Removes unneeded casts. Reviewed-by: Minchan Kim Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index e25025574a02..557e8af4a7d7 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -111,7 +111,7 @@ void __frontswap_init(unsigned type) if (sis->frontswap_map == NULL) return; if (frontswap_enabled) - (*frontswap_ops.init)(type); + frontswap_ops.init(type); } EXPORT_SYMBOL(__frontswap_init); @@ -134,7 +134,7 @@ int __frontswap_store(struct page *page) BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) dup = 1; - ret = (*frontswap_ops.store)(type, offset, page); + ret = frontswap_ops.store(type, offset, page); if (ret == 0) { frontswap_set(sis, offset); inc_frontswap_succ_stores(); @@ -173,7 +173,7 @@ int __frontswap_load(struct page *page) BUG_ON(!PageLocked(page)); BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) - ret = (*frontswap_ops.load)(type, offset, page); + ret = frontswap_ops.load(type, offset, page); if (ret == 0) inc_frontswap_loads(); return ret; @@ -190,7 +190,7 @@ void __frontswap_invalidate_page(unsigned type, pgoff_t offset) BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) { - (*frontswap_ops.invalidate_page)(type, offset); + frontswap_ops.invalidate_page(type, offset); atomic_dec(&sis->frontswap_pages); frontswap_clear(sis, offset); inc_frontswap_invalidates(); @@ -209,7 +209,7 @@ void __frontswap_invalidate_area(unsigned type) BUG_ON(sis == NULL); if (sis->frontswap_map == NULL) return; - (*frontswap_ops.invalidate_area)(type); + frontswap_ops.invalidate_area(type); atomic_set(&sis->frontswap_pages, 0); memset(sis->frontswap_map, 0, sis->max / sizeof(long)); } -- GitLab From 4bb3e31ef408a5ce460da3555c9f59dfe39636ff Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:51:00 +0200 Subject: [PATCH 1154/6849] mm: frontswap: trivial coding convention issues Reviewed-by: Minchan Kim Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index 557e8af4a7d7..7ec53d53c13a 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -148,8 +148,9 @@ int __frontswap_store(struct page *page) frontswap_clear(sis, offset); atomic_dec(&sis->frontswap_pages); inc_frontswap_failed_stores(); - } else + } else { inc_frontswap_failed_stores(); + } if (frontswap_writethrough_enabled) /* report failure so swap also writes to swap device */ ret = -1; @@ -250,9 +251,9 @@ void frontswap_shrink(unsigned long target_pages) for (type = swap_list.head; type >= 0; type = si->next) { si = swap_info[type]; si_frontswap_pages = atomic_read(&si->frontswap_pages); - if (total_pages_to_unuse < si_frontswap_pages) + if (total_pages_to_unuse < si_frontswap_pages) { pages = pages_to_unuse = total_pages_to_unuse; - else { + } else { pages = si_frontswap_pages; pages_to_unuse = 0; /* unuse all */ } -- GitLab From 96253444dbd90c6e9e9cfcb25315da5c412b058a Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:51:01 +0200 Subject: [PATCH 1155/6849] mm: frontswap: split out __frontswap_curr_pages Code was duplicated in two functions, clean it up. Also, assert that the deduplicated code runs under the swap spinlock. Reviewed-by: Minchan Kim Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index 7ec53d53c13a..5faf840f8726 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -216,6 +216,20 @@ void __frontswap_invalidate_area(unsigned type) } EXPORT_SYMBOL(__frontswap_invalidate_area); +static unsigned long __frontswap_curr_pages(void) +{ + int type; + unsigned long totalpages = 0; + struct swap_info_struct *si = NULL; + + assert_spin_locked(&swap_lock); + for (type = swap_list.head; type >= 0; type = si->next) { + si = swap_info[type]; + totalpages += atomic_read(&si->frontswap_pages); + } + return totalpages; +} + /* * Frontswap, like a true swap device, may unnecessarily retain pages * under certain circumstances; "shrink" frontswap is essentially a @@ -240,11 +254,7 @@ void frontswap_shrink(unsigned long target_pages) */ spin_lock(&swap_lock); locked = true; - total_pages = 0; - for (type = swap_list.head; type >= 0; type = si->next) { - si = swap_info[type]; - total_pages += atomic_read(&si->frontswap_pages); - } + total_pages = __frontswap_curr_pages(); if (total_pages <= target_pages) goto out; total_pages_to_unuse = total_pages - target_pages; @@ -282,16 +292,12 @@ EXPORT_SYMBOL(frontswap_shrink); */ unsigned long frontswap_curr_pages(void) { - int type; unsigned long totalpages = 0; - struct swap_info_struct *si = NULL; spin_lock(&swap_lock); - for (type = swap_list.head; type >= 0; type = si->next) { - si = swap_info[type]; - totalpages += atomic_read(&si->frontswap_pages); - } + totalpages = __frontswap_curr_pages(); spin_unlock(&swap_lock); + return totalpages; } EXPORT_SYMBOL(frontswap_curr_pages); -- GitLab From f116695a500cdd84cbeac68bc373e98ae729c24b Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:51:02 +0200 Subject: [PATCH 1156/6849] mm: frontswap: split out __frontswap_unuse_pages An attempt at making frontswap_shrink shorter and more readable. This patch splits out walking through the swap list to find an entry with enough pages to unuse. Also, assert that the internal __frontswap_unuse_pages is called under swap lock, since that part of code was previously directly happen inside the lock. Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 59 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index 5faf840f8726..faa43b7eea6f 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -230,6 +230,41 @@ static unsigned long __frontswap_curr_pages(void) return totalpages; } +static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused, + int *swapid) +{ + int ret = -EINVAL; + struct swap_info_struct *si = NULL; + int si_frontswap_pages; + unsigned long total_pages_to_unuse = total; + unsigned long pages = 0, pages_to_unuse = 0; + int type; + + assert_spin_locked(&swap_lock); + for (type = swap_list.head; type >= 0; type = si->next) { + si = swap_info[type]; + si_frontswap_pages = atomic_read(&si->frontswap_pages); + if (total_pages_to_unuse < si_frontswap_pages) { + pages = pages_to_unuse = total_pages_to_unuse; + } else { + pages = si_frontswap_pages; + pages_to_unuse = 0; /* unuse all */ + } + /* ensure there is enough RAM to fetch pages from frontswap */ + if (security_vm_enough_memory_mm(current->mm, pages)) { + ret = -ENOMEM; + continue; + } + vm_unacct_memory(pages); + *unused = pages_to_unuse; + *swapid = type; + ret = 0; + break; + } + + return ret; +} + /* * Frontswap, like a true swap device, may unnecessarily retain pages * under certain circumstances; "shrink" frontswap is essentially a @@ -240,11 +275,9 @@ static unsigned long __frontswap_curr_pages(void) */ void frontswap_shrink(unsigned long target_pages) { - struct swap_info_struct *si = NULL; - int si_frontswap_pages; unsigned long total_pages = 0, total_pages_to_unuse; - unsigned long pages = 0, pages_to_unuse = 0; - int type; + unsigned long pages_to_unuse = 0; + int type, ret; bool locked = false; /* @@ -258,22 +291,8 @@ void frontswap_shrink(unsigned long target_pages) if (total_pages <= target_pages) goto out; total_pages_to_unuse = total_pages - target_pages; - for (type = swap_list.head; type >= 0; type = si->next) { - si = swap_info[type]; - si_frontswap_pages = atomic_read(&si->frontswap_pages); - if (total_pages_to_unuse < si_frontswap_pages) { - pages = pages_to_unuse = total_pages_to_unuse; - } else { - pages = si_frontswap_pages; - pages_to_unuse = 0; /* unuse all */ - } - /* ensure there is enough RAM to fetch pages from frontswap */ - if (security_vm_enough_memory_mm(current->mm, pages)) - continue; - vm_unacct_memory(pages); - break; - } - if (type < 0) + ret = __frontswap_unuse_pages(total_pages_to_unuse, &pages_to_unuse, &type); + if (ret < 0) goto out; locked = false; spin_unlock(&swap_lock); -- GitLab From 69217b4cd044671b6dddcd9d33c8e4fdfd295ae3 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:51:03 +0200 Subject: [PATCH 1157/6849] mm: frontswap: split frontswap_shrink further to simplify locking Split frontswap_shrink to simplify the locking in the original code. Also, assert that the function that was split still runs under the swap spinlock. Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index faa43b7eea6f..e6353d9151ee 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -265,6 +265,24 @@ static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused, return ret; } +static int __frontswap_shrink(unsigned long target_pages, + unsigned long *pages_to_unuse, + int *type) +{ + unsigned long total_pages = 0, total_pages_to_unuse; + + assert_spin_locked(&swap_lock); + + total_pages = __frontswap_curr_pages(); + if (total_pages <= target_pages) { + /* Nothing to do */ + *pages_to_unuse = 0; + return 0; + } + total_pages_to_unuse = total_pages - target_pages; + return __frontswap_unuse_pages(total_pages_to_unuse, pages_to_unuse, type); +} + /* * Frontswap, like a true swap device, may unnecessarily retain pages * under certain circumstances; "shrink" frontswap is essentially a @@ -275,10 +293,8 @@ static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused, */ void frontswap_shrink(unsigned long target_pages) { - unsigned long total_pages = 0, total_pages_to_unuse; unsigned long pages_to_unuse = 0; int type, ret; - bool locked = false; /* * we don't want to hold swap_lock while doing a very @@ -286,20 +302,10 @@ void frontswap_shrink(unsigned long target_pages) * so restart scan from swap_list.head each time */ spin_lock(&swap_lock); - locked = true; - total_pages = __frontswap_curr_pages(); - if (total_pages <= target_pages) - goto out; - total_pages_to_unuse = total_pages - target_pages; - ret = __frontswap_unuse_pages(total_pages_to_unuse, &pages_to_unuse, &type); - if (ret < 0) - goto out; - locked = false; + ret = __frontswap_shrink(target_pages, &pages_to_unuse, &type); spin_unlock(&swap_lock); - try_to_unuse(type, true, pages_to_unuse); -out: - if (locked) - spin_unlock(&swap_lock); + if (ret == 0 && pages_to_unuse) + try_to_unuse(type, true, pages_to_unuse); return; } EXPORT_SYMBOL(frontswap_shrink); -- GitLab From d9674dda1c7ed49d503d3d7308c90a9f965f0783 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:51:04 +0200 Subject: [PATCH 1158/6849] mm: frontswap: make all branches of if statement in put page consistent Currently it has a complex structure where different things are compared at each branch. Simplify that and make both branches look similar. Reviewed-by: Minchan Kim Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index e6353d9151ee..d8dc9867b005 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -140,16 +140,16 @@ int __frontswap_store(struct page *page) inc_frontswap_succ_stores(); if (!dup) atomic_inc(&sis->frontswap_pages); - } else if (dup) { + } else { /* failed dup always results in automatic invalidate of the (older) page from frontswap */ - frontswap_clear(sis, offset); - atomic_dec(&sis->frontswap_pages); - inc_frontswap_failed_stores(); - } else { inc_frontswap_failed_stores(); + if (dup) { + frontswap_clear(sis, offset); + atomic_dec(&sis->frontswap_pages); + } } if (frontswap_writethrough_enabled) /* report failure so swap also writes to swap device */ -- GitLab From f9f08103ebd634999abfccc8ff94985530f14d74 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 10 Jun 2012 12:51:05 +0200 Subject: [PATCH 1159/6849] mm: frontswap: remove unnecessary check during initialization The check whether frontswap is enabled or not is done in the API functions in the frontswap header, before they are passed to the internal double-underscored frontswap functions. Remove the check from __frontswap_init for consistency. Reviewed-by: Minchan Kim Signed-off-by: Sasha Levin Signed-off-by: Konrad Rzeszutek Wilk --- mm/frontswap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/frontswap.c b/mm/frontswap.c index d8dc9867b005..7c26e899cec9 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -110,8 +110,7 @@ void __frontswap_init(unsigned type) BUG_ON(sis == NULL); if (sis->frontswap_map == NULL) return; - if (frontswap_enabled) - frontswap_ops.init(type); + frontswap_ops.init(type); } EXPORT_SYMBOL(__frontswap_init); -- GitLab From 9136461ab921fd5066ba6a0de08399e2172f4d71 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Jun 2012 06:36:13 +0000 Subject: [PATCH 1160/6849] net: keep name_hlist close to name __dev_get_by_name() is slow because pm_qos_req has been inserted between name[] and name_hlist, adding cache misses. pm_qos_req has nothing to do at the beginning of struct net_device Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d94cb1431519..a0b84e3b087c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1046,10 +1046,9 @@ struct net_device { */ char name[IFNAMSIZ]; - struct pm_qos_request pm_qos_req; - - /* device name hash chain */ + /* device name hash chain, please keep it close to name[] */ struct hlist_node name_hlist; + /* snmp alias */ char *ifalias; @@ -1322,6 +1321,8 @@ struct net_device { /* group the device belongs to */ int group; + + struct pm_qos_request pm_qos_req; }; #define to_net_dev(d) container_of(d, struct net_device, dev) -- GitLab From 0c142c86991551b8b9675ab72609f7a29ee2e1e3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 May 2012 11:51:31 -0300 Subject: [PATCH 1161/6849] [media] v4l2-ioctl: set readbuffers to 2 in g_parm If g_parm is handled automatically, then set readbuffers to 2, which is the minimum number of buffers videobuf uses. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 91be4e871f43..d7fa8962d8b3 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -1680,6 +1680,7 @@ static long __video_do_ioctl(struct file *file, break; ret = 0; + p->parm.capture.readbuffers = 2; if (ops->vidioc_g_std) ret = ops->vidioc_g_std(file, fh, &std); if (ret == 0) -- GitLab From a5ee6e41b2dee2aae2930278ba070ea8385db040 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 May 2012 11:58:06 -0300 Subject: [PATCH 1162/6849] [media] v4l2-dev.c: fix g_parm regression in determine_valid_ioctls() The field current_norm does not have to be set for g_parm to be a valid ioctl. Remove that check, but add a check whether this is a video node instead as g_parm only makes sense for those nodes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 150020805681..83dbb2ddff10 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -656,7 +656,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); - if (ops->vidioc_g_parm || vdev->current_norm) + if (ops->vidioc_g_parm || vdev->vfl_type == VFL_TYPE_GRABBER) set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); -- GitLab From c44ff8fa026ab34d95ce0805a56ca507c313a91d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 May 2012 12:01:40 -0300 Subject: [PATCH 1163/6849] [media] tuner-core: return the frequency range of the correct tuner The frequency range of the current tuner (radio or TV) was returned instead of the frequency range of the requested tuner (which depends on the device node). This bug caused the frequency range of the radio tuner to be returned when G_TUNER was called on a video node. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 3e050e12153b..1ad5ab6ce5cf 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1178,7 +1178,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (t->mode != V4L2_TUNER_RADIO) { + if (vt->type != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; vt->rangelow = tv_range[0] * 16; vt->rangehigh = tv_range[1] * 16; -- GitLab From 1c36dfc5c51b1406c2454fde922491ca6dab8513 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 May 2012 08:04:26 -0300 Subject: [PATCH 1164/6849] [media] ivtv: fix support for big-endian systems base_addr has type resource_size_t, which may be 64 bits on a 32-bit ppc. Tested on my ppc board. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 18 +++++++++--------- drivers/media/video/ivtv/ivtv-driver.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 057929e165ab..5462ce2f60ea 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -866,10 +866,10 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, pci_write_config_dword(pdev, 0x40, 0xffff); IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", + "irq: %d, latency: %d, memory: 0x%llx\n", pdev->device, pdev->revision, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev->irq, pci_latency, (unsigned long)itv->base_addr); + pdev->irq, pci_latency, (u64)itv->base_addr); return 0; } @@ -1007,7 +1007,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, itv->cxhdl.priv = itv; itv->cxhdl.func = ivtv_api_func; - IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); + IVTV_DEBUG_INFO("base addr: 0x%llx\n", (u64)itv->base_addr); /* PCI Device Setup */ retval = ivtv_setup_pci(itv, pdev, pci_id); @@ -1017,8 +1017,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, goto free_mem; /* map io memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); if (!itv->enc_mem) { @@ -1034,8 +1034,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } if (itv->has_cx23415) { - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); if (!itv->dec_mem) { @@ -1056,8 +1056,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } /* map registers memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); itv->reg_mem = ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (!itv->reg_mem) { diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 2e220028aad2..a7e00f8938f8 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -622,7 +622,7 @@ struct ivtv { struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ struct v4l2_subdev *sd_audio; /* controlling audio subdev */ struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */ - u32 base_addr; /* PCI resource base address */ + resource_size_t base_addr; /* PCI resource base address */ volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ volatile void __iomem *reg_mem; /* pointer to mapped registers */ -- GitLab From 42d0c3ad28837a4a475c18b69160053fdb562976 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 May 2012 08:07:03 -0300 Subject: [PATCH 1165/6849] [media] cx18: support big-endian systems base_addr has type resource_size_t, which may be 64 bits. Also fix a few endian issues related to mailboxes and firmware loading. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 10 +++++----- drivers/media/video/cx18/cx18-driver.h | 2 +- drivers/media/video/cx18/cx18-firmware.c | 9 +++++++-- drivers/media/video/cx18/cx18-mailbox.c | 15 ++++++++++----- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index b55d57cc1a1c..7e5ffd6f5178 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -838,10 +838,10 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, } CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", + "irq: %d, latency: %d, memory: 0x%llx\n", cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), - cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr); + cx->pci_dev->irq, pci_latency, (u64)cx->base_addr); return 0; } @@ -938,7 +938,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, if (retval) goto err; - CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); + CX18_DEBUG_INFO("base addr: 0x%llx\n", (u64)cx->base_addr); /* PCI Device Setup */ retval = cx18_setup_pci(cx, pci_dev, pci_id); @@ -946,8 +946,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_workqueues; /* map io memory */ - CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); + CX18_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); if (!cx->enc_mem) { diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 7a37e0ee136f..2767c64df0c8 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -622,7 +622,7 @@ struct cx18 { unique ID. Starts at 1, so 0 can be used as uninitialized value in the stream->id. */ - u32 base_addr; + resource_size_t base_addr; u8 card_rev; void __iomem *enc_mem, *reg_mem; diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 1b3fb502e6be..b85c292a849a 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -164,8 +164,13 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; while (offset + sizeof(seghdr) < fw->size) { - /* TODO: byteswapping */ - memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); + const u32 *shptr = src + offset / 4; + + seghdr.sync1 = le32_to_cpu(shptr[0]); + seghdr.sync2 = le32_to_cpu(shptr[1]); + seghdr.addr = le32_to_cpu(shptr[2]); + seghdr.size = le32_to_cpu(shptr[3]); + offset += sizeof(seghdr); if (seghdr.sync1 != APU_ROM_SYNC1 || seghdr.sync2 != APU_ROM_SYNC2) { diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index ed8118390b02..eabf00c6351b 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -434,6 +434,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) { u32 handle, mdl_ack_offset, mdl_ack_count; struct cx18_mailbox *mb; + int i; mb = &order->mb; handle = mb->args[0]; @@ -447,8 +448,9 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) return -1; } - cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset, - sizeof(struct cx18_mdl_ack) * mdl_ack_count); + for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32)) + ((u32 *)order->mdl_ack)[i / sizeof(u32)] = + cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i); if ((order->flags & CX18_F_EWO_MB_STALE) == 0) mb_ack_irq(cx, order); @@ -538,6 +540,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) struct cx18_mailbox *order_mb; struct cx18_in_work_order *order; int submit; + int i; switch (rpu) { case CPU: @@ -562,10 +565,12 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) order_mb = &order->mb; /* mb->cmd and mb->args[0] through mb->args[2] */ - cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32)); + for (i = 0; i < 4; i++) + (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i); + /* mb->request and mb->ack. N.B. we want to read mb->ack last */ - cx18_memcpy_fromio(cx, &order_mb->request, &mb->request, - 2 * sizeof(u32)); + for (i = 0; i < 2; i++) + (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i); if (order_mb->request == order_mb->ack) { CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " -- GitLab From 6ba4c432dcc8686b8493de5733ce7c986364730e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 May 2012 09:28:02 -0300 Subject: [PATCH 1166/6849] [media] cx88: fix firmware load on big-endian systems Tested with a HVR-1300. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-blackbird.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e46446a449c0..ed7b2aa1ed83 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -471,7 +471,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) dprintk(1,"Loading firmware ...\n"); dataptr = (u32*)firmware->data; for (i = 0; i < (firmware->size >> 2); i++) { - value = *dataptr; + value = le32_to_cpu(*dataptr); checksum += ~value; memory_write(dev->core, i, value); dataptr++; -- GitLab From de87897af08081aecb0c0bbc5fa01a8640e2d74c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Jun 2012 01:46:50 -0300 Subject: [PATCH 1167/6849] [media] bw-qcam: driver and pixfmt documentation fixes Fix the documentation of the Y4 and Y6 formats. Fix a poll() issue, add support for enum_frmsizes, set the proper parent device and fix a few compliance issues. Tested with an actual Connectix B&W parallel port webcam, both on a little-endian and a big-endian platform. This driver has never been so good, doing 320x240 at 1 frame per second :-) I know, nobody cares, but still it is cool that linux can still support this old webcam. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/pixfmt.xml | 4 +- drivers/media/video/bw-qcam.c | 47 +++++++++++++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml index f5ac15ed0549..e58934c92895 100644 --- a/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt.xml @@ -986,13 +986,13 @@ http://www.thedirks.org/winnov/ V4L2_PIX_FMT_Y4 'Y04 ' - Old 4-bit greyscale format. Only the least significant 4 bits of each byte are used, + Old 4-bit greyscale format. Only the most significant 4 bits of each byte are used, the other bits are set to 0. V4L2_PIX_FMT_Y6 'Y06 ' - Old 6-bit greyscale format. Only the least significant 6 bits of each byte are used, + Old 6-bit greyscale format. Only the most significant 6 bits of each byte are used, the other bits are set to 0. diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 2520219f01ba..5b75a64b199b 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -607,8 +607,9 @@ static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) } o = i * pixels_per_line + pixels_read + k; if (o < len) { + u8 ch = invert - buffer[k]; got++; - put_user((invert - buffer[k]) << shift, buf + o); + put_user(ch << shift, buf + o); } } pixels_read += bytes; @@ -648,8 +649,8 @@ static int qcam_querycap(struct file *file, void *priv, struct qcam *qcam = video_drvdata(file); strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); - strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); - strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); + strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card)); + strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info)); vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; @@ -688,8 +689,8 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f pix->height = qcam->height / qcam->transfer_scale; pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; pix->field = V4L2_FIELD_NONE; - pix->bytesperline = qcam->width; - pix->sizeimage = qcam->width * qcam->height; + pix->bytesperline = pix->width; + pix->sizeimage = pix->width * pix->height; /* Just a guess */ pix->colorspace = V4L2_COLORSPACE_SRGB; return 0; @@ -757,7 +758,7 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes "4-Bit Monochrome", V4L2_PIX_FMT_Y4, { 0, 0, 0, 0 } }, - { 0, 0, 0, + { 1, 0, 0, "6-Bit Monochrome", V4L2_PIX_FMT_Y6, { 0, 0, 0, 0 } }, @@ -772,6 +773,25 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes return 0; } +static int qcam_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + static const struct v4l2_frmsize_discrete sizes[] = { + { 80, 60 }, + { 160, 120 }, + { 320, 240 }, + }; + + if (fsize->index > 2) + return -EINVAL; + if (fsize->pixel_format != V4L2_PIX_FMT_Y4 && + fsize->pixel_format != V4L2_PIX_FMT_Y6) + return -EINVAL; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete = sizes[fsize->index]; + return 0; +} + static ssize_t qcam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -795,6 +815,11 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } +static unsigned int qcam_poll(struct file *filp, poll_table *wait) +{ + return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM; +} + static int qcam_s_ctrl(struct v4l2_ctrl *ctrl) { struct qcam *qcam = @@ -828,7 +853,7 @@ static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = v4l2_fh_release, - .poll = v4l2_ctrl_poll, + .poll = qcam_poll, .unlocked_ioctl = video_ioctl2, .read = qcam_read, }; @@ -839,6 +864,7 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = { .vidioc_s_input = qcam_s_input, .vidioc_enum_input = qcam_enum_input, .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, + .vidioc_enum_framesizes = qcam_enum_framesizes, .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, @@ -864,9 +890,9 @@ static struct qcam *qcam_init(struct parport *port) return NULL; v4l2_dev = &qcam->v4l2_dev; - strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); + snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams); - if (v4l2_device_register(NULL, v4l2_dev) < 0) { + if (v4l2_device_register(port->dev, v4l2_dev) < 0) { v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); kfree(qcam); return NULL; @@ -886,7 +912,7 @@ static struct qcam *qcam_init(struct parport *port) return NULL; } qcam->pport = port; - qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, + qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL, NULL, 0, NULL); if (qcam->pdev == NULL) { v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); @@ -975,6 +1001,7 @@ static int init_bwqcam(struct parport *port) return -ENODEV; } qc_calibrate(qcam); + v4l2_ctrl_handler_setup(&qcam->hdl); parport_release(qcam->pdev); -- GitLab From ae10ccdc3093486f8c2369d227583f9d79f628e5 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 4 Jun 2012 15:00:04 +0800 Subject: [PATCH 1168/6849] ACPI: Make acpi_skip_timer_override cover all source_irq==0 cases Currently when acpi_skip_timer_override is set, it only cover the (source_irq == 0 && global_irq == 2) cases. While there is also platform which need use this option and its global_irq is not 2. This patch will extend acpi_skip_timer_override to cover all timer overriding cases as long as the source irq is 0. This is the first part of a fix to kernel bug bugzilla 40002: "IRQ 0 assigned to VGA" https://bugzilla.kernel.org/show_bug.cgi?id=40002 Reported-and-tested-by: Szymon Kowalczyk Signed-off-by: Feng Tang Signed-off-by: Len Brown --- arch/x86/kernel/acpi/boot.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 8afb69319815..e7c698e9c7ec 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -422,12 +422,14 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, return 0; } - if (intsrc->source_irq == 0 && intsrc->global_irq == 2) { + if (intsrc->source_irq == 0) { if (acpi_skip_timer_override) { - printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); + printk(PREFIX "BIOS IRQ0 override ignored.\n"); return 0; } - if (acpi_fix_pin2_polarity && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { + + if ((intsrc->global_irq == 2) && acpi_fix_pin2_polarity + && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK; printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n"); } @@ -1334,7 +1336,7 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d) } /* - * Force ignoring BIOS IRQ0 pin2 override + * Force ignoring BIOS IRQ0 override */ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) { @@ -1344,7 +1346,7 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) */ if (!acpi_skip_timer_override) { WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n"); - pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", + pr_notice("%s detected: Ignoring BIOS IRQ0 override\n", d->ident); acpi_skip_timer_override = 1; } @@ -1438,7 +1440,7 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { * is enabled. This input is incorrectly designated the * ISA IRQ 0 via an interrupt source override even though * it is wired to the output of the master 8259A and INTIN0 - * is not connected at all. Force ignoring BIOS IRQ0 pin2 + * is not connected at all. Force ignoring BIOS IRQ0 * override in that cases. */ { -- GitLab From 7f68b4c2e158019c2ec494b5cfbd9c83b4e5b253 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 4 Jun 2012 15:00:05 +0800 Subject: [PATCH 1169/6849] ACPI: Remove one board specific WARN when ignoring timer overriding Current WARN msg is only for the ati_ixp4x0 board, while this function is used by mulitple platforms. So this one board specific warning is not appropriate any more. Signed-off-by: Feng Tang Signed-off-by: Len Brown --- arch/x86/kernel/acpi/boot.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index e7c698e9c7ec..3a6afba6eca7 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1340,12 +1340,7 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d) */ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) { - /* - * The ati_ixp4x0_rev() early PCI quirk should have set - * the acpi_skip_timer_override flag already: - */ if (!acpi_skip_timer_override) { - WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n"); pr_notice("%s detected: Ignoring BIOS IRQ0 override\n", d->ident); acpi_skip_timer_override = 1; -- GitLab From f6b54f083cc66cf9b11d2120d8df3c2ad4e0836d Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 4 Jun 2012 15:00:06 +0800 Subject: [PATCH 1170/6849] ACPI: Add a quirk for "AMILO PRO V2030" to ignore the timer overriding This is the 2nd part of fix for kernel bugzilla 40002: "IRQ 0 assigned to VGA" https://bugzilla.kernel.org/show_bug.cgi?id=40002 The root cause is the buggy FW, whose ACPI tables assign the GSI 16 to 2 irqs 0 and 16(VGA), and the VGA is the right owner of GSI 16. So add a quirk to ignore the irq0 overriding GSI 16 for the FUJITSU SIEMENS AMILO PRO V2030 platform will solve this issue. Reported-and-tested-by: Szymon Kowalczyk Signed-off-by: Feng Tang Signed-off-by: Len Brown --- arch/x86/kernel/acpi/boot.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 3a6afba6eca7..b2297e58c6ed 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1470,6 +1470,14 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), }, }, + { + .callback = dmi_ignore_irq0_timer_override, + .ident = "FUJITSU SIEMENS", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), + }, + }, {} }; -- GitLab From 352e04b9111d608bd89ba7bd8070846d4f97d104 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 11 Jun 2012 23:58:01 +0200 Subject: [PATCH 1171/6849] netfilter: nf_ct_tcp, udp: fix compilation with sysctl disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the compilation of the TCP and UDP trackers with sysctl compilation disabled: net/netfilter/nf_conntrack_proto_udp.c: In function ‘udp_init_net_data’: net/netfilter/nf_conntrack_proto_udp.c:279:13: error: ‘struct nf_proto_net’ has no member named ‘user’ net/netfilter/nf_conntrack_proto_tcp.c:1606:9: error: ‘struct nf_proto_net’ has no member named ‘user’ net/netfilter/nf_conntrack_proto_tcp.c:1643:9: error: ‘struct nf_proto_net’ has no member named ‘user’ Reported-by: Fengguang Wu Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_proto_tcp.c | 4 ++-- net/netfilter/nf_conntrack_proto_udp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 1cff854ccb88..99caa1304477 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1603,7 +1603,7 @@ static int tcpv4_init_net(struct net *net) #ifdef CONFIG_SYSCTL if (!pn->ctl_table) { #else - if (!pn->user++) { + if (!pn->users++) { #endif for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) tn->timeouts[i] = tcp_timeouts[i]; @@ -1640,7 +1640,7 @@ static int tcpv6_init_net(struct net *net) #ifdef CONFIG_SYSCTL if (!pn->ctl_table) { #else - if (!pn->user++) { + if (!pn->users++) { #endif for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) tn->timeouts[i] = tcp_timeouts[i]; diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 360565a95de4..a83cf93545cd 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -276,7 +276,7 @@ static void udp_init_net_data(struct nf_udp_net *un) #ifdef CONFIG_SYSCTL if (!un->pn.ctl_table) { #else - if (!un->pn.user++) { + if (!un->pn.users++) { #endif for (i = 0; i < UDP_CT_MAX; i++) un->timeouts[i] = udp_timeouts[i]; -- GitLab From 55afabaa0df0dd139c8796a71beb43d1216fbe43 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 11 Jun 2012 15:52:29 -0700 Subject: [PATCH 1172/6849] inet: Fix BUG triggered by __rt{,6}_get_peer(). If no peer actually gets attached (either because create is zero or the peer allocation fails) we'll trigger a BUG because we unconditionally do an rt{,6}_peer_ptr() afterwards. Fix this by guarding it with the proper check. Signed-off-by: David S. Miller --- include/net/ip6_route.h | 2 +- include/net/route.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index f88a85cf31c3..a2cda240ca95 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -61,7 +61,7 @@ static inline struct inet_peer *__rt6_get_peer(struct rt6_info *rt, int create) return rt6_peer_ptr(rt); rt6_bind_peer(rt, create); - return rt6_peer_ptr(rt); + return (rt6_has_peer(rt) ? rt6_peer_ptr(rt) : NULL); } static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt) diff --git a/include/net/route.h b/include/net/route.h index cc693a5bb20d..2bfbc9329ea9 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -334,7 +334,7 @@ static inline struct inet_peer *__rt_get_peer(struct rtable *rt, __be32 daddr, i return rt_peer_ptr(rt); rt_bind_peer(rt, daddr, create); - return rt_peer_ptr(rt); + return (rt_has_peer(rt) ? rt_peer_ptr(rt) : NULL); } static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) -- GitLab From bdd4034df8b37841eeaf7b05f86e732ab8e0b08a Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 23 Apr 2012 09:16:36 +0200 Subject: [PATCH 1173/6849] driver core: always handle dpm_order If !dev->class, device_move() does not respect the dpm_order. Fix it to do so. Acked-by: Rafael J. Wysocki Signed-off-by: Rabin Vincent Reviewed-by: Srinidhi Kasagar [Fixed a small dangling label compile warning] Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 346be8b78b24..846d12b5d579 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1754,25 +1754,25 @@ int device_move(struct device *dev, struct device *new_parent, set_dev_node(dev, dev_to_node(new_parent)); } - if (!dev->class) - goto out_put; - error = device_move_class_links(dev, old_parent, new_parent); - if (error) { - /* We ignore errors on cleanup since we're hosed anyway... */ - device_move_class_links(dev, new_parent, old_parent); - if (!kobject_move(&dev->kobj, &old_parent->kobj)) { - if (new_parent) - klist_remove(&dev->p->knode_parent); - dev->parent = old_parent; - if (old_parent) { - klist_add_tail(&dev->p->knode_parent, - &old_parent->p->klist_children); - set_dev_node(dev, dev_to_node(old_parent)); + if (dev->class) { + error = device_move_class_links(dev, old_parent, new_parent); + if (error) { + /* We ignore errors on cleanup since we're hosed anyway... */ + device_move_class_links(dev, new_parent, old_parent); + if (!kobject_move(&dev->kobj, &old_parent->kobj)) { + if (new_parent) + klist_remove(&dev->p->knode_parent); + dev->parent = old_parent; + if (old_parent) { + klist_add_tail(&dev->p->knode_parent, + &old_parent->p->klist_children); + set_dev_node(dev, dev_to_node(old_parent)); + } } + cleanup_glue_dir(dev, new_parent_kobj); + put_device(new_parent); + goto out; } - cleanup_glue_dir(dev, new_parent_kobj); - put_device(new_parent); - goto out; } switch (dpm_order) { case DPM_ORDER_NONE: @@ -1787,7 +1787,7 @@ int device_move(struct device *dev, struct device *new_parent, device_pm_move_last(dev); break; } -out_put: + put_device(old_parent); out: device_pm_unlock(); -- GitLab From a6e51c1e3425fe61040e9e770f514cfdf576a1f0 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 8 Jun 2012 12:22:46 +0200 Subject: [PATCH 1174/6849] staging: Delete if_strip.h Commit f80a3f62383bf673c310926d55142d51f118926d ("Staging: strip: delete the driver") left if_strip.h unused: nothing in the tree includes it anymore. It is still exported, but since nothing in the kernel uses struct MetricomAddress, that seems pointless. Delete this header too. Signed-off-by: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- include/linux/Kbuild | 1 - include/linux/if_strip.h | 27 --------------------------- 2 files changed, 28 deletions(-) delete mode 100644 include/linux/if_strip.h diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 8760be30b375..9366142ec7e5 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -183,7 +183,6 @@ header-y += if_ppp.h header-y += if_pppol2tp.h header-y += if_pppox.h header-y += if_slip.h -header-y += if_strip.h header-y += if_team.h header-y += if_tun.h header-y += if_tunnel.h diff --git a/include/linux/if_strip.h b/include/linux/if_strip.h deleted file mode 100644 index 6526a6235832..000000000000 --- a/include/linux/if_strip.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * if_strip.h -- - * - * Definitions for the STRIP interface - * - * Copyright 1996 The Board of Trustees of The Leland Stanford - * Junior University. All Rights Reserved. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. Stanford University - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#ifndef __LINUX_STRIP_H -#define __LINUX_STRIP_H - -#include - -typedef struct { - __u8 c[6]; -} MetricomAddress; - -#endif -- GitLab From 78b10615ad295393a7d66ea57218171c0a07c059 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 11 Jun 2012 16:35:50 -0700 Subject: [PATCH 1175/6849] staging/comedi: fix build for USB not enabled Calls to optional subsystems cannot be made indiscriminately. Enclose all of the usb helper functions inside #if IS_ENABLED(CONFIG_USB) to fix these build errors. (The pci helper functions are OK since there are stubs in linux/pci.h for the called functions when PCI is not enabled. Possibly the same could be done for the called USB functions.) ERROR: "usb_deregister" [drivers/staging/comedi/comedi.ko] undefined! ERROR: "usb_register_driver" [drivers/staging/comedi/comedi.ko] undefined! Signed-off-by: Randy Dunlap Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1c3d6386ea36..aeac1caba3f9 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -981,6 +982,8 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); +#if IS_ENABLED(CONFIG_USB) + static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { @@ -1043,3 +1046,5 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +#endif -- GitLab From 4bfa9b2ee16e73087435ac64a35f32140a385438 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 6 Jun 2012 13:43:55 +0100 Subject: [PATCH 1176/6849] staging: comedi: das08: Reduce conditional compilation This code is used by some combination of the CONFIG_COMEDI_DAS08_CS, CONFIG_COMEDI_DAS08_ISA, and CONFIG_COMEDI_DAS08_PCI and contains a lot of conditional compilation. Remove most of the conditional compilation, relying on the compiler to optimize out unused static functions and data. Use the '__maybe_unused' tag for those functions that cause compiler warnings as a result of this. Also change the DO_COMEDI_DRIVER_REGISTER macro from a conditionally defined macro to a manifest constant macro to allow it to be tested outside the preprocessor (although this is not currently needed). Signed-off-by: Ian Abbott Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 74 +++++++++++--------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index fa2784d65569..f99f72b9cdf3 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -60,9 +60,9 @@ #define DRV_NAME "das08" -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) || IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) -#define DO_COMEDI_DRIVER_REGISTER -#endif +#define DO_COMEDI_DRIVER_REGISTER \ + (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) || \ + IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_DEVICE_ID_PCIDAS08 0x29 @@ -341,22 +341,19 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return 2; } -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) -static int das08jr_di_rbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int __maybe_unused +das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { data[0] = 0; data[1] = inb(dev->iobase + DAS08JR_DIO); return 2; } -#endif -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) -static int das08jr_do_wbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int __maybe_unused +das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { struct das08_private_struct *devpriv = dev->private; @@ -370,12 +367,10 @@ static int das08jr_do_wbits(struct comedi_device *dev, return 2; } -#endif -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) -static int das08jr_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int __maybe_unused +das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { int n; int lsb, msb; @@ -401,7 +396,6 @@ static int das08jr_ao_winsn(struct comedi_device *dev, return n; } -#endif /* * @@ -409,10 +403,9 @@ static int das08jr_ao_winsn(struct comedi_device *dev, * a different method to force an update. * */ -#if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) -static int das08ao_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int __maybe_unused +das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { int n; int lsb, msb; @@ -438,7 +431,6 @@ static int das08ao_ao_winsn(struct comedi_device *dev, return n; } -#endif static unsigned int i8254_read_channel_low(unsigned int base, int chan) { @@ -570,7 +562,7 @@ static int das08_counter_config(struct comedi_device *dev, return 2; } -#ifdef DO_COMEDI_DRIVER_REGISTER +#if DO_COMEDI_DRIVER_REGISTER static const struct das08_board_struct das08_boards[] = { #if IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) { @@ -943,7 +935,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) } EXPORT_SYMBOL_GPL(das08_common_attach); -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static int das08_pci_attach_common(struct comedi_device *dev, struct pci_dev *pdev) { @@ -951,6 +942,9 @@ static int das08_pci_attach_common(struct comedi_device *dev, unsigned long pci_iobase; struct das08_private_struct *devpriv = dev->private; + if (!IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) + return -EINVAL; + devpriv->pdev = pdev; /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, dev->driver->driver_name)) { @@ -977,28 +971,28 @@ static int das08_pci_attach_common(struct comedi_device *dev, #endif return das08_common_attach(dev, iobase); } -#endif -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static const struct das08_board_struct * das08_find_pci_board(struct pci_dev *pdev) { +#if DO_COMEDI_DRIVER_REGISTER unsigned int i; for (i = 0; i < ARRAY_SIZE(das08_boards); i++) if (das08_boards[i].bustype == pci && pdev->device == das08_boards[i].id) return &das08_boards[i]; +#endif return NULL; } -#endif -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) /* only called in the PCI probe path, via comedi_pci_auto_config() */ -static int __devinit das08_attach_pci(struct comedi_device *dev, - struct pci_dev *pdev) +static int __devinit __maybe_unused +das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) { int ret; + if (!IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)) + return -EINVAL; ret = alloc_private(dev, sizeof(struct das08_private_struct)); if (ret < 0) return ret; @@ -1010,9 +1004,7 @@ static int __devinit das08_attach_pci(struct comedi_device *dev, } return das08_pci_attach_common(dev, pdev); } -#endif -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static struct pci_dev *das08_find_pci(struct comedi_device *dev, int bus, int slot) { @@ -1063,10 +1055,9 @@ static struct pci_dev *das08_find_pci(struct comedi_device *dev, thisboard->name); return NULL; } -#endif -#ifdef DO_COMEDI_DRIVER_REGISTER -static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int __maybe_unused +das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das08_board_struct *thisboard = comedi_board(dev); struct das08_private_struct *devpriv; @@ -1097,7 +1088,6 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else return -EIO; } -#endif /* DO_COMEDI_DRIVER_REGISTER */ void das08_common_detach(struct comedi_device *dev) { @@ -1106,8 +1096,7 @@ void das08_common_detach(struct comedi_device *dev) } EXPORT_SYMBOL_GPL(das08_common_detach); -#ifdef DO_COMEDI_DRIVER_REGISTER -static void das08_detach(struct comedi_device *dev) +static void __maybe_unused das08_detach(struct comedi_device *dev) { const struct das08_board_struct *thisboard = comedi_board(dev); struct das08_private_struct *devpriv = dev->private; @@ -1126,16 +1115,13 @@ static void das08_detach(struct comedi_device *dev) } } } -#endif /* DO_COMEDI_DRIVER_REGISTER */ -#ifdef DO_COMEDI_DRIVER_REGISTER +#if DO_COMEDI_DRIVER_REGISTER static struct comedi_driver das08_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, -#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) .attach_pci = das08_attach_pci, -#endif .detach = das08_detach, .board_name = &das08_boards[0].name, .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), @@ -1170,7 +1156,7 @@ static struct pci_driver das08_pci_driver = { }; #endif /* CONFIG_COMEDI_DAS08_PCI */ -#ifdef DO_COMEDI_DRIVER_REGISTER +#if DO_COMEDI_DRIVER_REGISTER #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) module_comedi_pci_driver(das08_driver, das08_pci_driver); #else -- GitLab From de74e92aa8a44d0b80a53601dc4f6dd6afcb8453 Mon Sep 17 00:00:00 2001 From: "danborkmann@iogearbox.net" Date: Sun, 10 Jun 2012 08:59:28 +0000 Subject: [PATCH 1177/6849] af_packet: use sizeof instead of constant in spkt_device This small patch removes access to the last element of the spkt_device array through a constant. Instead, it is accessed by sizeof() to respect possible changes in if_packet.h. Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller --- net/packet/af_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 71ac6559e0c6..8a10d5b3c832 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1475,7 +1475,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, * Find the device first to size check it */ - saddr->spkt_device[13] = 0; + saddr->spkt_device[sizeof(saddr->spkt_device) - 1] = 0; retry: rcu_read_lock(); dev = dev_get_by_name_rcu(sock_net(sk), saddr->spkt_device); -- GitLab From 4e2f002f7a9b316640eb06ef6df767f017e3e7b1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 6 Jun 2012 15:17:02 +0100 Subject: [PATCH 1178/6849] staging: comedi: describe comedi_recognize() Add a comment to comedi_recognize() to describe what it does as it's a bit confusing. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 9d2b206251ac..49e53eaa8e41 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -300,8 +300,32 @@ static int postconfig(struct comedi_device *dev) return 0; } -/* generic recognize function for drivers - * that register their supported board names */ +/* + * Generic recognize function for drivers that register their supported + * board names. + * + * 'driv->board_name' points to a 'const char *' member within the + * zeroth element of an array of some private board information + * structure, say 'struct foo_board' containing a member 'const char + * *board_name' that is initialized to point to a board name string that + * is one of the candidates matched against this function's 'name' + * parameter. + * + * 'driv->offset' is the size of the private board information + * structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is + * the length of the array of private board information structures. + * + * If one of the board names in the array of private board information + * structures matches the name supplied to this function, the function + * returns a pointer to the pointer to the board name, otherwise it + * returns NULL. The return value ends up in the 'board_ptr' member of + * a 'struct comedi_device' that the low-level comedi driver's + * 'attach()' hook can convert to a point to a particular element of its + * array of private board information structures by subtracting the + * offset of the member that points to the board name. (No subtraction + * is required if the board name pointer is the first member of the + * private board information structure, which is generally the case.) + */ static void *comedi_recognize(struct comedi_driver *driv, const char *name) { char **name_ptr = (char **)driv->board_name; -- GitLab From 72fd9facfb697d5f7b61958bb10efaabbd8461eb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Jun 2012 10:18:02 -0700 Subject: [PATCH 1179/6849] staging: comedi: cleanup sysfs functions Make the comedi sysfs functions a bit more concise by shortening some of the verbose variable names and reusing some of the variables that were used for intermediate calculations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 210 ++++++++++----------------- 1 file changed, 76 insertions(+), 134 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 76776571ed91..b3b86d48c771 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -172,28 +172,19 @@ static int resize_async_buffer(struct comedi_device *dev, /* sysfs attribute files */ -static const unsigned bytes_per_kibi = 1024; - static ssize_t show_max_read_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t retval; struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned max_buffer_size_kb = 0; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); + struct comedi_subdevice *s = comedi_get_read_subdevice(info); + unsigned int size = 0; mutex_lock(&info->device->mutex); - if (read_subdevice && - (read_subdevice->subdev_flags & SDF_CMD_READ) && - read_subdevice->async) { - max_buffer_size_kb = read_subdevice->async->max_bufsize / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); + if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) + size = s->async->max_bufsize / 1024; mutex_unlock(&info->device->mutex); - return retval; + return snprintf(buf, PAGE_SIZE, "%i\n", size); } static ssize_t store_max_read_buffer_kb(struct device *dev, @@ -201,52 +192,40 @@ static ssize_t store_max_read_buffer_kb(struct device *dev, const char *buf, size_t count) { struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_max_size_kb; - unsigned int new_max_size; - int ret; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - ret = kstrtouint(buf, 10, &new_max_size_kb); - if (ret) - return ret; - if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) + struct comedi_subdevice *s = comedi_get_read_subdevice(info); + unsigned int size; + int err; + + err = kstrtouint(buf, 10, &size); + if (err) + return err; + if (size > (UINT_MAX / 1024)) return -EINVAL; - new_max_size = new_max_size_kb * bytes_per_kibi; + size *= 1024; mutex_lock(&info->device->mutex); - if (read_subdevice == NULL || - (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || - read_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - read_subdevice->async->max_bufsize = new_max_size; + if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) + s->async->max_bufsize = size; + else + err = -EINVAL; mutex_unlock(&info->device->mutex); - return count; + return err ? err : count; } static ssize_t show_read_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t retval; struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned buffer_size_kb = 0; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); + struct comedi_subdevice *s = comedi_get_read_subdevice(info); + unsigned int size = 0; mutex_lock(&info->device->mutex); - if (read_subdevice && - (read_subdevice->subdev_flags & SDF_CMD_READ) && - read_subdevice->async) { - buffer_size_kb = read_subdevice->async->prealloc_bufsz / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); + if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) + size = s->async->prealloc_bufsz / 1024; mutex_unlock(&info->device->mutex); - return retval; + return snprintf(buf, PAGE_SIZE, "%i\n", size); } static ssize_t store_read_buffer_kb(struct device *dev, @@ -254,57 +233,41 @@ static ssize_t store_read_buffer_kb(struct device *dev, const char *buf, size_t count) { struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_size_kb; - unsigned int new_size; - int retval; - int ret; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - ret = kstrtouint(buf, 10, &new_size_kb); - if (ret) - return ret; - if (new_size_kb > (UINT_MAX / bytes_per_kibi)) + struct comedi_subdevice *s = comedi_get_read_subdevice(info); + unsigned int size; + int err; + + err = kstrtouint(buf, 10, &size); + if (err) + return err; + if (size > (UINT_MAX / 1024)) return -EINVAL; - new_size = new_size_kb * bytes_per_kibi; + size *= 1024; mutex_lock(&info->device->mutex); - if (read_subdevice == NULL || - (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || - read_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - retval = resize_async_buffer(info->device, read_subdevice, - read_subdevice->async, new_size); + if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) + err = resize_async_buffer(info->device, s, s->async, size); + else + err = -EINVAL; mutex_unlock(&info->device->mutex); - if (retval < 0) - return retval; - return count; + return err ? err : count; } static ssize_t show_max_write_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t retval; struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned max_buffer_size_kb = 0; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); + struct comedi_subdevice *s = comedi_get_write_subdevice(info); + unsigned int size = 0; mutex_lock(&info->device->mutex); - if (write_subdevice && - (write_subdevice->subdev_flags & SDF_CMD_WRITE) && - write_subdevice->async) { - max_buffer_size_kb = write_subdevice->async->max_bufsize / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); + if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) + size = s->async->max_bufsize / 1024; mutex_unlock(&info->device->mutex); - return retval; + return snprintf(buf, PAGE_SIZE, "%i\n", size); } static ssize_t store_max_write_buffer_kb(struct device *dev, @@ -312,52 +275,40 @@ static ssize_t store_max_write_buffer_kb(struct device *dev, const char *buf, size_t count) { struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_max_size_kb; - unsigned int new_max_size; - int ret; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - ret = kstrtouint(buf, 10, &new_max_size_kb); - if (ret) - return ret; - if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) + struct comedi_subdevice *s = comedi_get_write_subdevice(info); + unsigned int size; + int err; + + err = kstrtouint(buf, 10, &size); + if (err) + return err; + if (size > (UINT_MAX / 1024)) return -EINVAL; - new_max_size = new_max_size_kb * bytes_per_kibi; + size *= 1024; mutex_lock(&info->device->mutex); - if (write_subdevice == NULL || - (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || - write_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - write_subdevice->async->max_bufsize = new_max_size; + if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) + s->async->max_bufsize = size; + else + err = -EINVAL; mutex_unlock(&info->device->mutex); - return count; + return err ? err : count; } static ssize_t show_write_buffer_kb(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t retval; struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned buffer_size_kb = 0; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); + struct comedi_subdevice *s = comedi_get_write_subdevice(info); + unsigned int size = 0; mutex_lock(&info->device->mutex); - if (write_subdevice && - (write_subdevice->subdev_flags & SDF_CMD_WRITE) && - write_subdevice->async) { - buffer_size_kb = write_subdevice->async->prealloc_bufsz / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); + if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) + size = s->async->prealloc_bufsz / 1024; mutex_unlock(&info->device->mutex); - return retval; + return snprintf(buf, PAGE_SIZE, "%i\n", size); } static ssize_t store_write_buffer_kb(struct device *dev, @@ -365,34 +316,25 @@ static ssize_t store_write_buffer_kb(struct device *dev, const char *buf, size_t count) { struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_size_kb; - unsigned int new_size; - int retval; - int ret; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - ret = kstrtouint(buf, 10, &new_size_kb); - if (ret) - return ret; - if (new_size_kb > (UINT_MAX / bytes_per_kibi)) + struct comedi_subdevice *s = comedi_get_write_subdevice(info); + unsigned int size; + int err; + + err = kstrtouint(buf, 10, &size); + if (err) + return err; + if (size > (UINT_MAX / 1024)) return -EINVAL; - new_size = ((uint64_t) new_size_kb) * bytes_per_kibi; + size *= 1024; mutex_lock(&info->device->mutex); - if (write_subdevice == NULL || - (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || - write_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - retval = resize_async_buffer(info->device, write_subdevice, - write_subdevice->async, new_size); + if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) + err = resize_async_buffer(info->device, s, s->async, size); + else + err = -EINVAL; mutex_unlock(&info->device->mutex); - if (retval < 0) - return retval; - return count; + return err ? err : count; } static struct device_attribute comedi_dev_attrs[] = { -- GitLab From 513e48f90a9d092ffcf8301b6ed10a8d8a5ebe77 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Jun 2012 11:12:18 -0700 Subject: [PATCH 1180/6849] staging: comedi: ni_labpc: unlock spinlock on command error When starting the acquisition the labpc_ai_cmd function was exiting without unlocking the spinlock. This results in a sparse warning: warning: context imbalance in 'labpc_ai_cmd' - different lock contexts for basic block Add the missing spin_unlock_irqrestore calls. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 53349777246b..1d739b26e678 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1386,6 +1386,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; default: comedi_error(dev, "bug with start_src"); + spin_unlock_irqrestore(&dev->spinlock, flags); return -1; break; } @@ -1398,6 +1399,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; default: comedi_error(dev, "bug with stop_src"); + spin_unlock_irqrestore(&dev->spinlock, flags); return -1; } devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); -- GitLab From 91211dd13bec5e87490770f5b530b39b50f5d2f8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 6 Jun 2012 23:41:36 +0200 Subject: [PATCH 1181/6849] drivers/staging/comedi/drivers/me4000.c: adjust suspicious bit operation TRIG_ROUND_NEAREST is 0, so a bit-and with it is always false. The value TRIG_ROUND_MASK covers the bits of the TRIG_ROUND constants, so first pick those bits and then make the test using ==. The same is done for TRIG_ROUND_UP for symmetry, even though bit-and would be sufficient in this case. This problem was found using Coccinelle (http://coccinelle.lip6.fr/). Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index cb6bf8c5fb45..09890b8c586c 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -948,10 +948,10 @@ static int ai_round_cmd_args(struct comedi_device *dev, *init_ticks = (cmd->start_arg * 33) / 1000; rest = (cmd->start_arg * 33) % 1000; - if (cmd->flags & TRIG_ROUND_NEAREST) { + if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) { if (rest > 33) (*init_ticks)++; - } else if (cmd->flags & TRIG_ROUND_UP) { + } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) { if (rest) (*init_ticks)++; } @@ -961,10 +961,10 @@ static int ai_round_cmd_args(struct comedi_device *dev, *scan_ticks = (cmd->scan_begin_arg * 33) / 1000; rest = (cmd->scan_begin_arg * 33) % 1000; - if (cmd->flags & TRIG_ROUND_NEAREST) { + if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) { if (rest > 33) (*scan_ticks)++; - } else if (cmd->flags & TRIG_ROUND_UP) { + } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) { if (rest) (*scan_ticks)++; } @@ -974,10 +974,10 @@ static int ai_round_cmd_args(struct comedi_device *dev, *chan_ticks = (cmd->convert_arg * 33) / 1000; rest = (cmd->convert_arg * 33) % 1000; - if (cmd->flags & TRIG_ROUND_NEAREST) { + if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) { if (rest > 33) (*chan_ticks)++; - } else if (cmd->flags & TRIG_ROUND_UP) { + } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) { if (rest) (*chan_ticks)++; } -- GitLab From 47db6d58099437ddcec4fd2e572c95eba8c37cdd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 7 Jun 2012 17:05:27 -0700 Subject: [PATCH 1182/6849] staging: comedi: refactor comedi_fops to remove most of the forward declarations Move the comedi_unlocked_ioctl function in order to remove most of the forward declarations in this file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 214 ++++++++++++--------------- 1 file changed, 92 insertions(+), 122 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index b3b86d48c771..ad8634734194 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -92,36 +92,6 @@ static DEFINE_SPINLOCK(comedi_file_info_table_lock); static struct comedi_device_file_info *comedi_file_info_table[COMEDI_NUM_MINORS]; -static int do_devconfig_ioctl(struct comedi_device *dev, - struct comedi_devconfig __user *arg); -static int do_bufconfig_ioctl(struct comedi_device *dev, - struct comedi_bufconfig __user *arg); -static int do_devinfo_ioctl(struct comedi_device *dev, - struct comedi_devinfo __user *arg, - struct file *file); -static int do_subdinfo_ioctl(struct comedi_device *dev, - struct comedi_subdinfo __user *arg, void *file); -static int do_chaninfo_ioctl(struct comedi_device *dev, - struct comedi_chaninfo __user *arg); -static int do_bufinfo_ioctl(struct comedi_device *dev, - struct comedi_bufinfo __user *arg, void *file); -static int do_cmd_ioctl(struct comedi_device *dev, - struct comedi_cmd __user *arg, void *file); -static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, - void *file); -static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, - void *file); -static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, - void *file); -static int do_cmdtest_ioctl(struct comedi_device *dev, - struct comedi_cmd __user *arg, void *file); -static int do_insnlist_ioctl(struct comedi_device *dev, - struct comedi_insnlist __user *arg, void *file); -static int do_insn_ioctl(struct comedi_device *dev, - struct comedi_insn __user *arg, void *file); -static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, - void *file); - static void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s); static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s); @@ -349,98 +319,6 @@ static struct device_attribute comedi_dev_attrs[] = { __ATTR_NULL }; -static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - const unsigned minor = iminor(file->f_dentry->d_inode); - struct comedi_device_file_info *dev_file_info = - comedi_get_device_file_info(minor); - struct comedi_device *dev; - int rc; - - if (dev_file_info == NULL || dev_file_info->device == NULL) - return -ENODEV; - dev = dev_file_info->device; - - mutex_lock(&dev->mutex); - - /* Device config is special, because it must work on - * an unconfigured device. */ - if (cmd == COMEDI_DEVCONFIG) { - rc = do_devconfig_ioctl(dev, - (struct comedi_devconfig __user *)arg); - goto done; - } - - if (!dev->attached) { - DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor); - rc = -ENODEV; - goto done; - } - - switch (cmd) { - case COMEDI_BUFCONFIG: - rc = do_bufconfig_ioctl(dev, - (struct comedi_bufconfig __user *)arg); - break; - case COMEDI_DEVINFO: - rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg, - file); - break; - case COMEDI_SUBDINFO: - rc = do_subdinfo_ioctl(dev, - (struct comedi_subdinfo __user *)arg, - file); - break; - case COMEDI_CHANINFO: - rc = do_chaninfo_ioctl(dev, (void __user *)arg); - break; - case COMEDI_RANGEINFO: - rc = do_rangeinfo_ioctl(dev, (void __user *)arg); - break; - case COMEDI_BUFINFO: - rc = do_bufinfo_ioctl(dev, - (struct comedi_bufinfo __user *)arg, - file); - break; - case COMEDI_LOCK: - rc = do_lock_ioctl(dev, arg, file); - break; - case COMEDI_UNLOCK: - rc = do_unlock_ioctl(dev, arg, file); - break; - case COMEDI_CANCEL: - rc = do_cancel_ioctl(dev, arg, file); - break; - case COMEDI_CMD: - rc = do_cmd_ioctl(dev, (struct comedi_cmd __user *)arg, file); - break; - case COMEDI_CMDTEST: - rc = do_cmdtest_ioctl(dev, (struct comedi_cmd __user *)arg, - file); - break; - case COMEDI_INSNLIST: - rc = do_insnlist_ioctl(dev, - (struct comedi_insnlist __user *)arg, - file); - break; - case COMEDI_INSN: - rc = do_insn_ioctl(dev, (struct comedi_insn __user *)arg, - file); - break; - case COMEDI_POLL: - rc = do_poll_ioctl(dev, arg, file); - break; - default: - rc = -ENOTTY; - break; - } - -done: - mutex_unlock(&dev->mutex); - return rc; -} - /* COMEDI_DEVCONFIG device config ioctl @@ -1651,6 +1529,98 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, return -EINVAL; } +static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + const unsigned minor = iminor(file->f_dentry->d_inode); + struct comedi_device_file_info *dev_file_info = + comedi_get_device_file_info(minor); + struct comedi_device *dev; + int rc; + + if (dev_file_info == NULL || dev_file_info->device == NULL) + return -ENODEV; + dev = dev_file_info->device; + + mutex_lock(&dev->mutex); + + /* Device config is special, because it must work on + * an unconfigured device. */ + if (cmd == COMEDI_DEVCONFIG) { + rc = do_devconfig_ioctl(dev, + (struct comedi_devconfig __user *)arg); + goto done; + } + + if (!dev->attached) { + DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor); + rc = -ENODEV; + goto done; + } + + switch (cmd) { + case COMEDI_BUFCONFIG: + rc = do_bufconfig_ioctl(dev, + (struct comedi_bufconfig __user *)arg); + break; + case COMEDI_DEVINFO: + rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg, + file); + break; + case COMEDI_SUBDINFO: + rc = do_subdinfo_ioctl(dev, + (struct comedi_subdinfo __user *)arg, + file); + break; + case COMEDI_CHANINFO: + rc = do_chaninfo_ioctl(dev, (void __user *)arg); + break; + case COMEDI_RANGEINFO: + rc = do_rangeinfo_ioctl(dev, (void __user *)arg); + break; + case COMEDI_BUFINFO: + rc = do_bufinfo_ioctl(dev, + (struct comedi_bufinfo __user *)arg, + file); + break; + case COMEDI_LOCK: + rc = do_lock_ioctl(dev, arg, file); + break; + case COMEDI_UNLOCK: + rc = do_unlock_ioctl(dev, arg, file); + break; + case COMEDI_CANCEL: + rc = do_cancel_ioctl(dev, arg, file); + break; + case COMEDI_CMD: + rc = do_cmd_ioctl(dev, (struct comedi_cmd __user *)arg, file); + break; + case COMEDI_CMDTEST: + rc = do_cmdtest_ioctl(dev, (struct comedi_cmd __user *)arg, + file); + break; + case COMEDI_INSNLIST: + rc = do_insnlist_ioctl(dev, + (struct comedi_insnlist __user *)arg, + file); + break; + case COMEDI_INSN: + rc = do_insn_ioctl(dev, (struct comedi_insn __user *)arg, + file); + break; + case COMEDI_POLL: + rc = do_poll_ioctl(dev, arg, file); + break; + default: + rc = -ENOTTY; + break; + } + +done: + mutex_unlock(&dev->mutex); + return rc; +} + static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { int ret = 0; -- GitLab From 8d242488ce4627dd7e6333caab56df11ea25e239 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 9 Jun 2012 07:49:07 +0000 Subject: [PATCH 1183/6849] phy: Use pr_ Use a more current logging style. Add pr_fmt and missing newlines. Remove embedded prefixes. Neaten phy_print_status to avoid using KERN_CONT. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/phy/dp83640.c | 23 +++++++++++++---------- drivers/net/phy/fixed.c | 4 ++-- drivers/net/phy/mdio_bus.c | 5 ++++- drivers/net/phy/national.c | 8 ++++++-- drivers/net/phy/phy.c | 35 +++++++++++++++++------------------ drivers/net/phy/phy_device.c | 7 +++++-- drivers/net/phy/spi_ks8995.c | 4 +++- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 940b29022d0c..b0da0226661f 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -17,6 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -453,16 +456,16 @@ static void enable_status_frames(struct phy_device *phydev, bool on) ext_write(0, phydev, PAGE6, PSF_CFG1, ver); if (!phydev->attached_dev) { - pr_warning("dp83640: expected to find an attached netdevice\n"); + pr_warn("expected to find an attached netdevice\n"); return; } if (on) { if (dev_mc_add(phydev->attached_dev, status_frame_dst)) - pr_warning("dp83640: failed to add mc address\n"); + pr_warn("failed to add mc address\n"); } else { if (dev_mc_del(phydev->attached_dev, status_frame_dst)) - pr_warning("dp83640: failed to delete mc address\n"); + pr_warn("failed to delete mc address\n"); } } @@ -582,9 +585,9 @@ static void recalibrate(struct dp83640_clock *clock) * read out and correct offsets */ val = ext_read(master, PAGE4, PTP_STS); - pr_info("master PTP_STS 0x%04hx", val); + pr_info("master PTP_STS 0x%04hx\n", val); val = ext_read(master, PAGE4, PTP_ESTS); - pr_info("master PTP_ESTS 0x%04hx", val); + pr_info("master PTP_ESTS 0x%04hx\n", val); event_ts.ns_lo = ext_read(master, PAGE4, PTP_EDATA); event_ts.ns_hi = ext_read(master, PAGE4, PTP_EDATA); event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA); @@ -594,9 +597,9 @@ static void recalibrate(struct dp83640_clock *clock) list_for_each(this, &clock->phylist) { tmp = list_entry(this, struct dp83640_private, list); val = ext_read(tmp->phydev, PAGE4, PTP_STS); - pr_info("slave PTP_STS 0x%04hx", val); + pr_info("slave PTP_STS 0x%04hx\n", val); val = ext_read(tmp->phydev, PAGE4, PTP_ESTS); - pr_info("slave PTP_ESTS 0x%04hx", val); + pr_info("slave PTP_ESTS 0x%04hx\n", val); event_ts.ns_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); event_ts.ns_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA); event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); @@ -686,7 +689,7 @@ static void decode_rxts(struct dp83640_private *dp83640, prune_rx_ts(dp83640); if (list_empty(&dp83640->rxpool)) { - pr_debug("dp83640: rx timestamp pool is empty\n"); + pr_debug("rx timestamp pool is empty\n"); goto out; } rxts = list_first_entry(&dp83640->rxpool, struct rxts, list); @@ -709,7 +712,7 @@ static void decode_txts(struct dp83640_private *dp83640, skb = skb_dequeue(&dp83640->tx_queue); if (!skb) { - pr_debug("dp83640: have timestamp but tx_queue empty\n"); + pr_debug("have timestamp but tx_queue empty\n"); return; } ns = phy2txts(phy_txts); @@ -847,7 +850,7 @@ static void dp83640_free_clocks(void) list_for_each_safe(this, next, &phyter_clocks) { clock = list_entry(this, struct dp83640_clock, list); if (!list_empty(&clock->phylist)) { - pr_warning("phy list non-empty while unloading"); + pr_warn("phy list non-empty while unloading\n"); BUG(); } list_del(&clock->list); diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 633680d0828e..ba55adfc7aae 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -70,7 +70,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp) lpa |= LPA_10FULL; break; default: - printk(KERN_WARNING "fixed phy: unknown speed\n"); + pr_warn("fixed phy: unknown speed\n"); return -EINVAL; } } else { @@ -90,7 +90,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp) lpa |= LPA_10HALF; break; default: - printk(KERN_WARNING "fixed phy: unknown speed\n"); + pr_warn("fixed phy: unknown speed\n"); return -EINVAL; } } diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 683ef1ce5519..d4a4992b4935 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -13,6 +13,9 @@ * option) any later version. * */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -148,7 +151,7 @@ int mdiobus_register(struct mii_bus *bus) err = device_register(&bus->dev); if (err) { - printk(KERN_ERR "mii_bus %s failed to register\n", bus->id); + pr_err("mii_bus %s failed to register\n", bus->id); return -EINVAL; } diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index 04bb8fcc0cb5..9a5f234d95b0 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c @@ -15,6 +15,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -22,6 +24,8 @@ #include #include +#define DEBUG + /* DP83865 phy identifier values */ #define DP83865_PHY_ID 0x20005c7a @@ -112,8 +116,8 @@ static void ns_10_base_t_hdx_loopack(struct phy_device *phydev, int disable) ns_exp_write(phydev, 0x1c0, ns_exp_read(phydev, 0x1c0) & 0xfffe); - printk(KERN_DEBUG "DP83865 PHY: 10BASE-T HDX loopback %s\n", - (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on"); + pr_debug("10BASE-T HDX loopback %s\n", + (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on"); } static int ns_config_init(struct phy_device *phydev) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3cbda0851f83..2e1c23731ded 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -15,6 +15,9 @@ * option) any later version. * */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -44,18 +47,16 @@ */ void phy_print_status(struct phy_device *phydev) { - pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev), - phydev->link ? "Up" : "Down"); if (phydev->link) - printk(KERN_CONT " - %d/%s", phydev->speed, - DUPLEX_FULL == phydev->duplex ? - "Full" : "Half"); - - printk(KERN_CONT "\n"); + pr_info("%s - Link is Up - %d/%s\n", + dev_name(&phydev->dev), + phydev->speed, + DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); + else + pr_info("%s - Link is Down\n", dev_name(&phydev->dev)); } EXPORT_SYMBOL(phy_print_status); - /** * phy_clear_interrupt - Ack the phy device's interrupt * @phydev: the phy_device struct @@ -482,9 +483,8 @@ static void phy_force_reduction(struct phy_device *phydev) phydev->speed = settings[idx].speed; phydev->duplex = settings[idx].duplex; - pr_info("Trying %d/%s\n", phydev->speed, - DUPLEX_FULL == phydev->duplex ? - "FULL" : "HALF"); + pr_info("Trying %d/%s\n", + phydev->speed, DUPLEX_FULL == phydev->duplex ? "FULL" : "HALF"); } @@ -598,9 +598,8 @@ int phy_start_interrupts(struct phy_device *phydev) IRQF_SHARED, "phy_interrupt", phydev) < 0) { - printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", - phydev->bus->name, - phydev->irq); + pr_warn("%s: Can't get IRQ %d (PHY)\n", + phydev->bus->name, phydev->irq); phydev->irq = PHY_POLL; return 0; } @@ -838,10 +837,10 @@ void phy_state_machine(struct work_struct *work) phydev->autoneg = AUTONEG_DISABLE; - pr_info("Trying %d/%s\n", phydev->speed, - DUPLEX_FULL == - phydev->duplex ? - "FULL" : "HALF"); + pr_info("Trying %d/%s\n", + phydev->speed, + DUPLEX_FULL == phydev->duplex ? + "FULL" : "HALF"); } break; case PHY_NOLINK: diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index de86a5582224..18ab0daf4490 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -14,6 +14,9 @@ * option) any later version. * */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -975,8 +978,8 @@ int phy_driver_register(struct phy_driver *new_driver) retval = driver_register(&new_driver->driver); if (retval) { - printk(KERN_ERR "%s: Error %d in registering driver\n", - new_driver->name, retval); + pr_err("%s: Error %d in registering driver\n", + new_driver->name, retval); return retval; } diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index 4eb98bc52a0a..1c3abce78b6a 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c @@ -11,6 +11,8 @@ * by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -356,7 +358,7 @@ static struct spi_driver ks8995_driver = { static int __init ks8995_init(void) { - printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); + pr_info(DRV_DESC " version " DRV_VERSION "\n"); return spi_register_driver(&ks8995_driver); } -- GitLab From 0bdf8ec0a57e5c4f90f4d6e83938f24653360d84 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 7 Jun 2012 17:31:19 -0700 Subject: [PATCH 1184/6849] staging: comedi: adl_pci9118: if test should use logical AND not bitwise AND This quiets a couple sparse warnings about: warning: dubious: !x & y Also, remove the unnecessary parentheses around the variables. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 3670ebdbcd81..5a5c903f5e03 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1735,7 +1735,7 @@ static int check_channel_list(struct comedi_device *dev, "can't be mixtured!"); return 0; } - if ((!devpriv->usemux) & (differencial) & + if (!devpriv->usemux && differencial && (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) { comedi_error(dev, "If AREF_DIFF is used then is " -- GitLab From e26d925f42064a800c1226e15dbaa23da1721fb7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 7 Jun 2012 17:25:35 -0700 Subject: [PATCH 1185/6849] staging: comedi: pcl816: if test should use logical OR not bitwise OR This quiets a couple sparse warnings about: warning: dubious: !x | !y warning: dubious: x | !y Also, remove the unnecessary parentheses abound the variables. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 277a23ece6fa..845039cd6207 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -414,8 +414,8 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) } outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ - if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) | - (!devpriv->int816_mode)) { + if (!dev->irq || !devpriv->irq_free || !devpriv->irq_blocked || + !devpriv->int816_mode) { if (devpriv->irq_was_now_closed) { devpriv->irq_was_now_closed = 0; /* comedi_error(dev,"last IRQ.."); */ -- GitLab From 27494c092a81847fef515549b76251d96b760619 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 7 Jun 2012 17:14:25 -0700 Subject: [PATCH 1186/6849] staging: comedi: serial2002: quiet NULL pointer sparse noise Quiet a number of sparse warnings in this file: warning: Using plain integer as NULL pointer Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/serial2002.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 9200310dce5d..c25808c05251 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -643,7 +643,7 @@ err_alloc_configs: if (result) { if (devpriv->tty) { - filp_close(devpriv->tty, 0); + filp_close(devpriv->tty, NULL); devpriv->tty = NULL; } } @@ -653,8 +653,8 @@ err_alloc_configs: static void serial_2002_close(struct comedi_device *dev) { - if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) - filp_close(devpriv->tty, 0); + if (!IS_ERR(devpriv->tty) && devpriv->tty) + filp_close(devpriv->tty, NULL); } static int serial2002_di_rinsn(struct comedi_device *dev, @@ -819,7 +819,7 @@ static int serial2002_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 0; s->maxdata = 1; - s->range_table = 0; + s->range_table = NULL; s->insn_read = &serial2002_ai_rinsn; /* analog output subdevice */ @@ -828,7 +828,7 @@ static int serial2002_attach(struct comedi_device *dev, s->subdev_flags = SDF_WRITEABLE; s->n_chan = 0; s->maxdata = 1; - s->range_table = 0; + s->range_table = NULL; s->insn_write = &serial2002_ao_winsn; s->insn_read = &serial2002_ao_rinsn; @@ -838,7 +838,7 @@ static int serial2002_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_LSAMPL; s->n_chan = 0; s->maxdata = 1; - s->range_table = 0; + s->range_table = NULL; s->insn_read = &serial2002_ei_rinsn; return 1; -- GitLab From f59f231e3db835353d8d1ff91062d89140dc8be3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Jun 2012 09:52:58 +0300 Subject: [PATCH 1187/6849] staging: comedi: amplc_pci230: add a missing unlock This side of the if else statement returned with the lock held and IRQs disabled. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 30487be11650..f2ad35c6527d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -1387,6 +1387,8 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, /* Delay. Should driver be responsible for this? */ /* XXX TODO: See if DAC busy bit can be used. */ udelay(8); + } else { + spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); } return 1; -- GitLab From 83afda9d449c61b55881d50465833784d8fda786 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 8 Jun 2012 10:40:05 +0100 Subject: [PATCH 1188/6849] staging: comedi: amplc_pci230: Replace NULLFUNC The source code defines a macro NULLFUNC #define NULLFUNC 0 and uses it as a generic null function pointer constant. This is superfluous. Just use NULL instead. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index f2ad35c6527d..2a43df5d966e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -430,9 +430,6 @@ enum { /* Combine old and new bits. */ #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask))) -/* A generic null function pointer value. */ -#define NULLFUNC 0 - /* Current CPU. XXX should this be hard_smp_processor_id()? */ #define THISCPU smp_processor_id() @@ -1491,7 +1488,7 @@ static int pci230_ao_inttrig_start(struct comedi_device *dev, if (trig_num != 0) return -EINVAL; - s->async->inttrig = NULLFUNC; + s->async->inttrig = NULL; pci230_ao_start(dev, s); return 1; @@ -2292,7 +2289,7 @@ static int pci230_ai_inttrig_start(struct comedi_device *dev, if (trig_num != 0) return -EINVAL; - s->async->inttrig = NULLFUNC; + s->async->inttrig = NULL; pci230_ai_start(dev, s); return 1; -- GitLab From cbdfaffc461fd3df12f494655aca5cae68d6c7aa Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 8 Jun 2012 10:39:42 +0100 Subject: [PATCH 1189/6849] staging: comedi: amplc_pci224: Replace NULLFUNC The source code defines a macro NULLFUNC #define NULLFUNC 0 and uses it as a generic null function pointer constant. This is superfluous. Just use NULL instead. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 43f07f8f365e..a1e23bafabea 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -265,9 +265,6 @@ Caveats: /* Combine old and new bits. */ #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask))) -/* A generic null function pointer value. */ -#define NULLFUNC 0 - /* Current CPU. XXX should this be hard_smp_processor_id()? */ #define THISCPU smp_processor_id() @@ -703,7 +700,7 @@ pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s, if (trignum != 0) return -EINVAL; - s->async->inttrig = NULLFUNC; + s->async->inttrig = NULL; pci224_ao_start(dev, s); return 1; -- GitLab From f059077388b0c35cd47ee06ba5da3401a62dc657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Wed, 6 Jun 2012 16:22:04 +0200 Subject: [PATCH 1190/6849] Staging: xgifb: Remove #ifdef MODULE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check for MODULE is not needed. In a static compilation the parameters definition is valid and module_exit() does nothing. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 85dbf32b1f66..61dc7cb94ffb 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2325,8 +2325,6 @@ module_init(xgifb_init); /* MODULE */ /*****************************************************/ -#ifdef MODULE - MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("XGITECH , Others"); @@ -2359,5 +2357,3 @@ static void __exit xgifb_remove_module(void) } module_exit(xgifb_remove_module); - -#endif /* /MODULE */ -- GitLab From d049053ef052535c8986f104f904548dfcaa14aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Wed, 6 Jun 2012 16:22:05 +0200 Subject: [PATCH 1191/6849] Staging: xgifb: reorder the code a bit to be more module friendly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 51 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 61dc7cb94ffb..96abb23f6b42 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2306,49 +2306,44 @@ static struct pci_driver xgifb_driver = { .remove = __devexit_p(xgifb_remove) }; -static int __init xgifb_init(void) -{ - char *option = NULL; - - if (forcecrt2type != NULL) - XGIfb_search_crt2type(forcecrt2type); - if (fb_get_options("xgifb", &option)) - return -ENODEV; - XGIfb_setup(option); - - return pci_register_driver(&xgifb_driver); -} -module_init(xgifb_init); /*****************************************************/ /* MODULE */ /*****************************************************/ -MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("XGITECH , Others"); - module_param(mode, charp, 0); -module_param(vesa, int, 0); -module_param(filter, int, 0); -module_param(forcecrt2type, charp, 0); +MODULE_PARM_DESC(mode, + "\nSelects the desired default display mode in the format XxYxDepth,\n" + "eg. 1024x768x16.\n"); +module_param(forcecrt2type, charp, 0); MODULE_PARM_DESC(forcecrt2type, "\nForce the second display output type. Possible values are NONE,\n" "LCD, TV, VGA, SVIDEO or COMPOSITE.\n"); -MODULE_PARM_DESC(mode, - "\nSelects the desired default display mode in the format XxYxDepth,\n" - "eg. 1024x768x16.\n"); - +module_param(vesa, int, 0); MODULE_PARM_DESC(vesa, "\nSelects the desired default display mode by VESA mode number, eg.\n" "0x117.\n"); +module_param(filter, int, 0); MODULE_PARM_DESC(filter, - "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n" - "(Possible values 0-7, default: [no filter])\n"); + "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n" + "(Possible values 0-7, default: [no filter])\n"); + +static int __init xgifb_init(void) +{ + char *option = NULL; + + if (forcecrt2type != NULL) + XGIfb_search_crt2type(forcecrt2type); + if (fb_get_options("xgifb", &option)) + return -ENODEV; + XGIfb_setup(option); + + return pci_register_driver(&xgifb_driver); +} static void __exit xgifb_remove_module(void) { @@ -2356,4 +2351,8 @@ static void __exit xgifb_remove_module(void) pr_debug("Module unloaded\n"); } +MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("XGITECH , Others"); +module_init(xgifb_init); module_exit(xgifb_remove_module); -- GitLab From 05e06036ddffd3e285bddc23e4ce55f54cd27537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Wed, 6 Jun 2012 16:22:06 +0200 Subject: [PATCH 1192/6849] Staging: xgifb: disable pci device if there's an error after enabling it. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 96abb23f6b42..438781ff33a3 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1904,7 +1904,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (reg1 != 0xa1) { /*I/O error */ pr_err("I/O error!!!"); ret = -EIO; - goto error; + goto error_disable; } switch (xgifb_info->chip_id) { @@ -1927,7 +1927,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, break; default: ret = -ENODEV; - goto error; + goto error_disable; } pr_info("chipid = %x\n", xgifb_info->chip); @@ -1936,7 +1936,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (XGIfb_get_dram_size(xgifb_info)) { pr_err("Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; - goto error; + goto error_disable; } /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ @@ -1956,7 +1956,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, pr_err("Fatal error: Unable to reserve frame buffer memory\n"); pr_err("Is there another framebuffer driver active?\n"); ret = -ENODEV; - goto error; + goto error_disable; } if (!request_mem_region(xgifb_info->mmio_base, @@ -2271,6 +2271,8 @@ error_1: release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); error_0: release_mem_region(xgifb_info->video_base, xgifb_info->video_size); +error_disable: + pci_disable_device(pdev); error: framebuffer_release(fb_info); return ret; -- GitLab From bf55b48371d1ca6ee64152753b359924e3cfcbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Wed, 6 Jun 2012 16:22:07 +0200 Subject: [PATCH 1193/6849] Staging: xgifb: disable pci device on pci remove function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 438781ff33a3..033463d1966c 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2297,6 +2297,7 @@ static void __devexit xgifb_remove(struct pci_dev *pdev) iounmap(xgifb_info->video_vbase); release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size); release_mem_region(xgifb_info->video_base, xgifb_info->video_size); + pci_disable_device(pdev); framebuffer_release(fb_info); pci_set_drvdata(pdev, NULL); } -- GitLab From 08224262adefb5e6460888b2490a96e1bc28aef5 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Mon, 11 Jun 2012 12:13:08 -0400 Subject: [PATCH 1194/6849] staging: usbip: bugfix for stack corruption on 64-bit architectures Previously a 6 byte array (buf) was erroneously cast to a 8 byte long (event_bits) on 64-bit architectures which caused a stack corruption. Signed-off-by: Bart Westgeest Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index f708cbaee16b..117a7ad9fdb1 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -205,7 +205,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) int retval = 0; /* the enough buffer is allocated according to USB_MAXCHILDREN */ - unsigned long *event_bits = (unsigned long *) buf; + u32 *event_bits = (unsigned long *) buf; int rhport; int changed = 0; -- GitLab From 1132b9aafa61bb589a2c09980d13c154659bdb07 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Mon, 11 Jun 2012 16:57:30 -0400 Subject: [PATCH 1195/6849] staging: usbip: Updated comment describing VHCI_NPORTS Updated out-of-date comment describing VHCI_NPORT Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h index 88b32981cf1f..c66b8b3f97b4 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/staging/usbip/vhci.h @@ -71,12 +71,7 @@ struct vhci_unlink { unsigned long unlink_seqnum; }; -/* - * The number of ports is less than 16 ? - * USB_MAXCHILDREN is statically defined to 16 in usb.h. Its maximum value - * would be 31 because the event_bits[1] of struct usb_hub is defined as - * unsigned long in hub.h - */ +/* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ #define VHCI_NPORTS 8 /* for usb_bus.hcpriv */ -- GitLab From c475c06f4bb689d6ad87d7512e036d6dface3160 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 12 Jun 2012 08:27:04 +0800 Subject: [PATCH 1196/6849] hwrng: atmel-rng - fix data valid check Brown paper bag: Data valid is LSB of the ISR (status register), and NOT of ODATA (current random data word)! With this, rngtest is a lot happier. Before: rngtest 3 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warr. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 3 rngtest: FIPS 140-2 failures: 997 rngtest: FIPS 140-2(2001-10-10) Monobit: 604 rngtest: FIPS 140-2(2001-10-10) Poker: 996 rngtest: FIPS 140-2(2001-10-10) Runs: 36 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 117 rngtest: input channel speed: (min=622.371; avg=23682.481; max=28224.350)Kibitss rngtest: FIPS tests speed: (min=12.361; avg=12.718; max=12.861)Mibits/s rngtest: Program run time: 2331696 microsecondsx After: rngtest 3 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warr. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 999 rngtest: FIPS 140-2 failures: 1 rngtest: FIPS 140-2(2001-10-10) Monobit: 0 rngtest: FIPS 140-2(2001-10-10) Poker: 0 rngtest: FIPS 140-2(2001-10-10) Runs: 1 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 rngtest: input channel speed: (min=777.363; avg=43588.270; max=47870.711)Kibitss rngtest: FIPS tests speed: (min=11.943; avg=12.716; max=12.844)Mibits/s rngtest: Program run time: 1955282 microseconds Cc: stable@vger.kernel.org Signed-off-by: Peter Korsgaard Reported-by: George Pontis Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- drivers/char/hw_random/atmel-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 6289f0eee24c..731c9046cf7b 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -34,7 +34,7 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, u32 *data = buf; /* data ready? */ - if (readl(trng->base + TRNG_ODATA) & 1) { + if (readl(trng->base + TRNG_ISR) & 1) { *data = readl(trng->base + TRNG_ODATA); /* ensure data ready is only set again AFTER the next data -- GitLab From 12ea6cad1c7d046e21decc18b0e2170c6794dc51 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 11 Jun 2012 05:26:55 +0000 Subject: [PATCH 1197/6849] PCI: add PCI DMA source ID quirk DMA transactions are tagged with the source ID of the device making the request. Occasionally hardware screws this up and uses the source ID of a different device (often the wrong function number of a multifunction device). A specific Ricoh multifunction device is a prime example of this problem and included in this patch. Given a pci_dev, this function returns the pci_dev to use as the source ID for DMA. When hardware works correctly, this returns the input device. For the components of the Ricoh multifunction device, it returns the pci_dev for function 0. This will be used by IOMMU drivers for determining the boundaries of IOMMU groups as multiple devices using the same source ID must be contained within the same group. This can also be used by existing streaming DMA paths for the same purpose. [bhelgaas: fold in pci_dev_get() for !CONFIG_PCI] Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas --- drivers/pci/quirks.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 8 +++++++ 2 files changed, 59 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2a7521677541..acd3956b44bd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3179,3 +3179,54 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe) return -ENOTTY; } + +static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev) +{ + if (!PCI_FUNC(dev->devfn)) + return pci_dev_get(dev); + + return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); +} + +static const struct pci_dev_dma_source { + u16 vendor; + u16 device; + struct pci_dev *(*dma_source)(struct pci_dev *dev); +} pci_dev_dma_source[] = { + /* + * https://bugzilla.redhat.com/show_bug.cgi?id=605888 + * + * Some Ricoh devices use the function 0 source ID for DMA on + * other functions of a multifunction device. The DMA devices + * is therefore function 0, which will have implications of the + * iommu grouping of these devices. + */ + { PCI_VENDOR_ID_RICOH, 0xe822, pci_func_0_dma_source }, + { PCI_VENDOR_ID_RICOH, 0xe230, pci_func_0_dma_source }, + { PCI_VENDOR_ID_RICOH, 0xe832, pci_func_0_dma_source }, + { PCI_VENDOR_ID_RICOH, 0xe476, pci_func_0_dma_source }, + { 0 } +}; + +/* + * IOMMUs with isolation capabilities need to be programmed with the + * correct source ID of a device. In most cases, the source ID matches + * the device doing the DMA, but sometimes hardware is broken and will + * tag the DMA as being sourced from a different device. This function + * allows that translation. Note that the reference count of the + * returned device is incremented on all paths. + */ +struct pci_dev *pci_get_dma_source(struct pci_dev *dev) +{ + const struct pci_dev_dma_source *i; + + for (i = pci_dev_dma_source; i->dma_source; i++) { + if ((i->vendor == dev->vendor || + i->vendor == (u16)PCI_ANY_ID) && + (i->device == dev->device || + i->device == (u16)PCI_ANY_ID)) + return i->dma_source(dev); + } + + return pci_dev_get(dev); +} diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..39983be7b25b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1332,6 +1332,9 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } +static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) +{ return NULL; } + #define dev_is_pci(d) (false) #define dev_is_pf(d) (false) #define dev_num_vf(d) (0) @@ -1486,9 +1489,14 @@ enum pci_fixup_pass { #ifdef CONFIG_PCI_QUIRKS void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); +struct pci_dev *pci_get_dma_source(struct pci_dev *dev); #else static inline void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} +static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev) +{ + return pci_dev_get(dev); +} #endif void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); -- GitLab From 20c5fd399482ef5b87a41ab064b3255f1faaaee4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 10:03:20 +0800 Subject: [PATCH 1198/6849] ASoC: wm8903: Move pin configuration into I2C probe() function Ensure that the device pins are configured as soon as possible by moving the pin configration (including MICBIAS) into the I2C probe() function. This had been done in the CODEC probe() function when we were relying on the ASoC register I/O code. Signed-off-by: Mark Brown Tested-by: Stephen Warren --- sound/soc/codecs/wm8903.c | 92 ++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 3abd450842ee..64ca9042bad3 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1,7 +1,7 @@ /* * wm8903.c -- WM8903 ALSA SoC Audio driver * - * Copyright 2008-11 Wolfson Microelectronics + * Copyright 2008-12 Wolfson Microelectronics * Copyright 2011-2012 NVIDIA, Inc. * * Author: Mark Brown @@ -1880,10 +1880,9 @@ static int wm8903_probe(struct snd_soc_codec *codec) { struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); struct wm8903_platform_data *pdata = wm8903->pdata; - int ret, i; + int ret; int trigger, irq_pol; u16 val; - bool mic_gpio = false; wm8903->codec = codec; codec->control_data = wm8903->regmap; @@ -1894,47 +1893,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) return ret; } - /* Set up GPIOs, detect if any are MIC detect outputs */ - for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { - if ((!pdata->gpio_cfg[i]) || - (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO)) - continue; - - snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, - pdata->gpio_cfg[i] & 0x7fff); - - val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) - >> WM8903_GP1_FN_SHIFT; - - switch (val) { - case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: - case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: - mic_gpio = true; - break; - default: - break; - } - } - - /* Set up microphone detection */ - snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, - pdata->micdet_cfg); - - /* Microphone detection needs the WSEQ clock */ - if (pdata->micdet_cfg) - snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, - WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); - - /* If microphone detection is enabled by pdata but - * detected via IRQ then interrupts can be lost before - * the machine driver has set up microphone detection - * IRQs as the IRQs are clear on read. The detection - * will be enabled when the machine driver configures. - */ - WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); - - wm8903->mic_delay = pdata->micdet_delay; - if (wm8903->irq) { if (pdata->irq_active_low) { trigger = IRQF_TRIGGER_LOW; @@ -2115,8 +2073,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, { struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); struct wm8903_priv *wm8903; + bool mic_gpio = false; unsigned int val; - int ret; + int ret, i; wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), GFP_KERNEL); @@ -2160,6 +2119,8 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, } } + pdata = wm8903->pdata; + ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); if (ret != 0) { dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); @@ -2184,6 +2145,47 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, wm8903_init_gpio(wm8903); + /* Set up GPIO pin state, detect if any are MIC detect outputs */ + for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { + if ((!pdata->gpio_cfg[i]) || + (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO)) + continue; + + regmap_write(wm8903->regmap, WM8903_GPIO_CONTROL_1 + i, + pdata->gpio_cfg[i] & 0x7fff); + + val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) + >> WM8903_GP1_FN_SHIFT; + + switch (val) { + case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: + case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: + mic_gpio = true; + break; + default: + break; + } + } + + /* Set up microphone detection */ + regmap_write(wm8903->regmap, WM8903_MIC_BIAS_CONTROL_0, + pdata->micdet_cfg); + + /* Microphone detection needs the WSEQ clock */ + if (pdata->micdet_cfg) + regmap_update_bits(wm8903->regmap, WM8903_WRITE_SEQUENCER_0, + WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); + + /* If microphone detection is enabled by pdata but + * detected via IRQ then interrupts can be lost before + * the machine driver has set up microphone detection + * IRQs as the IRQs are clear on read. The detection + * will be enabled when the machine driver configures. + */ + WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); + + wm8903->mic_delay = pdata->micdet_delay; + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8903, &wm8903_dai, 1); if (ret != 0) -- GitLab From e373cbfb2f7d194e48d528794b3b99274d4c1a97 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 10:06:11 +0800 Subject: [PATCH 1199/6849] ASoC: wm8903: Make interrupt handler use regmap directly There's no urgent need for the interrupt handler to use the ASoC I/O functions and it'll support a further move in where we request the interrupt so call the regmap APIs directly. Signed-off-by: Mark Brown Tested-by: Stephen Warren --- sound/soc/codecs/wm8903.c | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 64ca9042bad3..f5d47c8e5402 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1636,17 +1636,27 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect); static irqreturn_t wm8903_irq(int irq, void *data) { - struct snd_soc_codec *codec = data; - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - int mic_report; - int int_pol; - int int_val = 0; - int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK); + struct wm8903_priv *wm8903 = data; + int mic_report, ret; + unsigned int int_val, mask, int_pol; + + ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1_MASK, + &mask); + if (ret != 0) { + dev_err(wm8903->dev, "Failed to read IRQ mask: %d\n", ret); + return IRQ_NONE; + } + + ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1, &int_val); + if (ret != 0) { + dev_err(wm8903->dev, "Failed to read IRQ status: %d\n", ret); + return IRQ_NONE; + } - int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; + int_val &= ~mask; if (int_val & WM8903_WSEQ_BUSY_EINT) { - dev_warn(codec->dev, "Write sequencer done\n"); + dev_warn(wm8903->dev, "Write sequencer done\n"); } /* @@ -1657,22 +1667,28 @@ static irqreturn_t wm8903_irq(int irq, void *data) * the polarity register. */ mic_report = wm8903->mic_last_report; - int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); + ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1, + &int_pol); + if (ret != 0) { + dev_err(wm8903->dev, "Failed to read interrupt polarity: %d\n", + ret); + return IRQ_HANDLED; + } #ifndef CONFIG_SND_SOC_WM8903_MODULE if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) - trace_snd_soc_jack_irq(dev_name(codec->dev)); + trace_snd_soc_jack_irq(dev_name(wm8903->dev)); #endif if (int_val & WM8903_MICSHRT_EINT) { - dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); + dev_dbg(wm8903->dev, "Microphone short (pol=%x)\n", int_pol); mic_report ^= wm8903->mic_short; int_pol ^= WM8903_MICSHRT_INV; } if (int_val & WM8903_MICDET_EINT) { - dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); + dev_dbg(wm8903->dev, "Microphone detect (pol=%x)\n", int_pol); mic_report ^= wm8903->mic_det; int_pol ^= WM8903_MICDET_INV; @@ -1680,8 +1696,8 @@ static irqreturn_t wm8903_irq(int irq, void *data) msleep(wm8903->mic_delay); } - snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1, - WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol); + regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1, + WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol); snd_soc_jack_report(wm8903->mic_jack, mic_report, wm8903->mic_short | wm8903->mic_det); @@ -1907,7 +1923,7 @@ static int wm8903_probe(struct snd_soc_codec *codec) ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq, trigger | IRQF_ONESHOT, - "wm8903", codec); + "wm8903", wm8903); if (ret != 0) { dev_err(codec->dev, "Failed to request IRQ: %d\n", ret); @@ -1963,7 +1979,7 @@ static int wm8903_remove(struct snd_soc_codec *codec) wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); if (wm8903->irq) - free_irq(wm8903->irq, codec); + free_irq(wm8903->irq, wm8903); return 0; } -- GitLab From b7c95d9146c8201740e2ce9dca7fb1eb8b7b0053 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 10:15:10 +0800 Subject: [PATCH 1200/6849] ASoC: wm8903: Move interrupt request to I2C probe There's no reason to defer requesting of the interrupt until the CODEC probe and doing so results in more work if we hit an error as we'll have registered the CODEC with the core. It's neater to acquire as many of the resources we'll need as we can in the bus probe function. Signed-off-by: Mark Brown Tested-by: Stephen Warren --- sound/soc/codecs/wm8903.c | 65 +++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index f5d47c8e5402..7261a68aac6f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1895,9 +1895,7 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903) static int wm8903_probe(struct snd_soc_codec *codec) { struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - struct wm8903_platform_data *pdata = wm8903->pdata; int ret; - int trigger, irq_pol; u16 val; wm8903->codec = codec; @@ -1909,32 +1907,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) return ret; } - if (wm8903->irq) { - if (pdata->irq_active_low) { - trigger = IRQF_TRIGGER_LOW; - irq_pol = WM8903_IRQ_POL; - } else { - trigger = IRQF_TRIGGER_HIGH; - irq_pol = 0; - } - - snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, - WM8903_IRQ_POL, irq_pol); - - ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq, - trigger | IRQF_ONESHOT, - "wm8903", wm8903); - if (ret != 0) { - dev_err(codec->dev, "Failed to request IRQ: %d\n", - ret); - return ret; - } - - /* Enable write sequencer interrupts */ - snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK, - WM8903_IM_WSEQ_BUSY_EINT, 0); - } - /* power on device */ wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1975,11 +1947,7 @@ static int wm8903_probe(struct snd_soc_codec *codec) /* power down chip */ static int wm8903_remove(struct snd_soc_codec *codec) { - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); - if (wm8903->irq) - free_irq(wm8903->irq, wm8903); return 0; } @@ -2089,8 +2057,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, { struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); struct wm8903_priv *wm8903; + int trigger; bool mic_gpio = false; - unsigned int val; + unsigned int val, irq_pol; int ret, i; wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), @@ -2108,7 +2077,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, } i2c_set_clientdata(i2c, wm8903); - wm8903->irq = i2c->irq; /* If no platform data was supplied, create storage for defaults */ if (pdata) { @@ -2202,6 +2170,33 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, wm8903->mic_delay = pdata->micdet_delay; + if (i2c->irq) { + if (pdata->irq_active_low) { + trigger = IRQF_TRIGGER_LOW; + irq_pol = WM8903_IRQ_POL; + } else { + trigger = IRQF_TRIGGER_HIGH; + irq_pol = 0; + } + + regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_CONTROL, + WM8903_IRQ_POL, irq_pol); + + ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq, + trigger | IRQF_ONESHOT, + "wm8903", wm8903); + if (ret != 0) { + dev_err(wm8903->dev, "Failed to request IRQ: %d\n", + ret); + return ret; + } + + /* Enable write sequencer interrupts */ + regmap_update_bits(wm8903->regmap, + WM8903_INTERRUPT_STATUS_1_MASK, + WM8903_IM_WSEQ_BUSY_EINT, 0); + } + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8903, &wm8903_dai, 1); if (ret != 0) @@ -2216,6 +2211,8 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client) { struct wm8903_priv *wm8903 = i2c_get_clientdata(client); + if (client->irq) + free_irq(client->irq, wm8903); wm8903_free_gpio(wm8903); snd_soc_unregister_codec(&client->dev); -- GitLab From a89c3e956ae78cec8926b92f2d61b7a5b675e787 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 10:30:34 +0800 Subject: [PATCH 1201/6849] ASoC: wm8903: Move register default changes to I2C probe Also convert to use update_bits() while we're at it. No great need to do this, it's just a bit neater to do as much as possible in the I2C probe. Signed-off-by: Mark Brown Tested-by: Stephen Warren --- sound/soc/codecs/wm8903.c | 63 +++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 7261a68aac6f..73f1c8d7bafb 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1896,7 +1896,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) { struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); int ret; - u16 val; wm8903->codec = codec; codec->control_data = wm8903->regmap; @@ -1910,37 +1909,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) /* power on device */ wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* Latch volume update bits */ - val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT); - val |= WM8903_ADCVU; - snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val); - snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val); - - val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT); - val |= WM8903_DACVU; - snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val); - snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val); - - val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT); - val |= WM8903_HPOUTVU; - snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val); - snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val); - - val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT); - val |= WM8903_LINEOUTVU; - snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val); - snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val); - - val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT); - val |= WM8903_SPKVU; - snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val); - snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); - - /* Enable DAC soft mute by default */ - snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, - WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, - WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); - return ret; } @@ -2197,6 +2165,37 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, WM8903_IM_WSEQ_BUSY_EINT, 0); } + /* Latch volume update bits */ + regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_LEFT, + WM8903_ADCVU, WM8903_ADCVU); + regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_RIGHT, + WM8903_ADCVU, WM8903_ADCVU); + + regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_LEFT, + WM8903_DACVU, WM8903_DACVU); + regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_RIGHT, + WM8903_DACVU, WM8903_DACVU); + + regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_LEFT, + WM8903_HPOUTVU, WM8903_HPOUTVU); + regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_RIGHT, + WM8903_HPOUTVU, WM8903_HPOUTVU); + + regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_LEFT, + WM8903_LINEOUTVU, WM8903_LINEOUTVU); + regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_RIGHT, + WM8903_LINEOUTVU, WM8903_LINEOUTVU); + + regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_LEFT, + WM8903_SPKVU, WM8903_SPKVU); + regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_RIGHT, + WM8903_SPKVU, WM8903_SPKVU); + + /* Enable DAC soft mute by default */ + regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_1, + WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, + WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8903, &wm8903_dai, 1); if (ret != 0) -- GitLab From c32823f82b42abc1f08b365085862fd1d57c0b61 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Fri, 1 Jun 2012 15:16:25 -0600 Subject: [PATCH 1202/6849] PCI: make pci_ltr_supported() static The PCI Express Latency Tolerance Reporting (LTR) feature's pci_ltr_supported() routine is currently only used within drivers/pci/pci.c so make it static. Acked-by: Donald Dutile Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 3 +-- include/linux/pci.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..847e0c35cdb7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2169,7 +2169,7 @@ EXPORT_SYMBOL(pci_disable_obff); * RETURNS: * True if @dev supports latency tolerance reporting, false otherwise. */ -bool pci_ltr_supported(struct pci_dev *dev) +static bool pci_ltr_supported(struct pci_dev *dev) { int pos; u32 cap; @@ -2185,7 +2185,6 @@ bool pci_ltr_supported(struct pci_dev *dev) return cap & PCI_EXP_DEVCAP2_LTR; } -EXPORT_SYMBOL(pci_ltr_supported); /** * pci_enable_ltr - enable latency tolerance reporting diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..b2bec26b7f0a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -875,7 +875,6 @@ enum pci_obff_signal_type { int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type); void pci_disable_obff(struct pci_dev *dev); -bool pci_ltr_supported(struct pci_dev *dev); int pci_enable_ltr(struct pci_dev *dev); void pci_disable_ltr(struct pci_dev *dev); int pci_set_ltr(struct pci_dev *dev, int snoop_lat_ns, int nosnoop_lat_ns); -- GitLab From 80feb89a0a1381642f1cce9036ef3bb22f13b40a Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Tue, 29 May 2012 23:54:26 +0900 Subject: [PATCH 1203/6849] KVM: MMU: Remove unused parameter from mmu_memory_cache_alloc() Size is not needed to return one from pre-allocated objects. Signed-off-by: Takuya Yoshikawa Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 24dd43d45ae4..b32a11dc884c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -652,8 +652,7 @@ static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) mmu_page_header_cache); } -static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc, - size_t size) +static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc) { void *p; @@ -664,8 +663,7 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc, static struct pte_list_desc *mmu_alloc_pte_list_desc(struct kvm_vcpu *vcpu) { - return mmu_memory_cache_alloc(&vcpu->arch.mmu_pte_list_desc_cache, - sizeof(struct pte_list_desc)); + return mmu_memory_cache_alloc(&vcpu->arch.mmu_pte_list_desc_cache); } static void mmu_free_pte_list_desc(struct pte_list_desc *pte_list_desc) @@ -1403,12 +1401,10 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, u64 *parent_pte, int direct) { struct kvm_mmu_page *sp; - sp = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache, - sizeof *sp); - sp->spt = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); + sp = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache); + sp->spt = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache); if (!direct) - sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, - PAGE_SIZE); + sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache); set_page_private(virt_to_page(sp->spt), (unsigned long)sp); list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); bitmap_zero(sp->slot_bitmap, KVM_MEM_SLOTS_NUM); -- GitLab From cb97ae3485955401d637bd269b0d24d3cd3fd3ec Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Fri, 1 Jun 2012 15:16:31 -0600 Subject: [PATCH 1204/6849] PCI: remove redundant checking in PCI Express capability routines There are a number of redundant pci_is_pcie() checks in various PCI Express capabilities related routines like the following: if (!pci_is_pcie(dev)) return false; pos = pci_pcie_cap(dev); if (!pos) return false; The current pci_is_pcie() implementation is merely: static inline bool pci_is_pcie(struct pci_dev *dev) { return !!pci_pcie_cap(dev); } so we can just drop the pci_is_pcie() test in such cases. Acked-by: Donald Dutile Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 847e0c35cdb7..766bb13bb0a3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1994,7 +1994,7 @@ void pci_enable_ari(struct pci_dev *dev) return; bridge = dev->bus->self; - if (!bridge || !pci_is_pcie(bridge)) + if (!bridge) return; pos = pci_pcie_cap(bridge); @@ -2054,9 +2054,6 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type) int pos; u16 ctrl; - if (!pci_is_pcie(dev)) - return; - pos = pci_pcie_cap(dev); if (!pos) return; @@ -2096,9 +2093,6 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) u16 ctrl; int ret; - if (!pci_is_pcie(dev)) - return -ENOTSUPP; - pos = pci_pcie_cap(dev); if (!pos) return -ENOTSUPP; @@ -2149,9 +2143,6 @@ void pci_disable_obff(struct pci_dev *dev) int pos; u16 ctrl; - if (!pci_is_pcie(dev)) - return; - pos = pci_pcie_cap(dev); if (!pos) return; @@ -2174,9 +2165,6 @@ static bool pci_ltr_supported(struct pci_dev *dev) int pos; u32 cap; - if (!pci_is_pcie(dev)) - return false; - pos = pci_pcie_cap(dev); if (!pos) return false; -- GitLab From c463b8cb9350cf1230cefe467a1cf279140a5437 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Fri, 1 Jun 2012 15:16:37 -0600 Subject: [PATCH 1205/6849] PCI: add pci_pcie_cap2() check for PCIe feature capabilities >= v2 This patch resolves potential issues when accessing PCI Express Capability structures. The makeup of the capability varies substantially between v1 and v2: Version 1 of the PCI Express Capability (defined by PCI Express 1.0 and 1.1 base) neither requires the endpoint to implement the entire PCIe capability structure nor specifies default values of registers that are not implemented by the device. Version 2 of the PCI Express Capability (defined by PCIe 1.1 Capability Structure Expansion ECN, PCIe 2.0, 2.1, and 3.0) added additional registers to the structure and requires all registers to be either implemented or hardwired to 0. Due to the differences in the capability structures, code dealing with capability features must be careful not to access the additional registers introduced with v2 unless the device is specifically known to be a v2 capable device. Otherwise, attempts to access non-existant registers will occur. This is a subtle issue that is hard to track down when it occurs (and it has - see commit 864d296cf94). To try and help mitigate such occurrences, this patch introduces pci_pcie_cap2() which is similar to pci_pcie_cap() but also checks that the PCIe capability version is >= 2. pci_pcie_cap2() should be used for qualifying PCIe capability features introduced after v1. Suggested by Don Dutile. Acked-by: Donald Dutile Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 65 ++++++++++++++++++++++++++++++---------- include/linux/pci_regs.h | 6 ++++ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 766bb13bb0a3..985df63aa59f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -277,6 +277,38 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) return pos; } +/** + * pci_pcie_cap2 - query for devices' PCI_CAP_ID_EXP v2 capability structure + * @dev: PCI device to check + * + * Like pci_pcie_cap() but also checks that the PCIe capability version is + * >= 2. Note that v1 capability structures could be sparse in that not + * all register fields were required. v2 requires the entire structure to + * be present size wise, while still allowing for non-implemented registers + * to exist but they must be hardwired to 0. + * + * Due to the differences in the versions of capability structures, one + * must be careful not to try and access non-existant registers that may + * exist in early versions - v1 - of Express devices. + * + * Returns the offset of the PCIe capability structure as long as the + * capability version is >= 2; otherwise 0 is returned. + */ +static int pci_pcie_cap2(struct pci_dev *dev) +{ + u16 flags; + int pos; + + pos = pci_pcie_cap(dev); + if (pos) { + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); + if ((flags & PCI_EXP_FLAGS_VERS) < 2) + pos = 0; + } + + return pos; +} + /** * pci_find_ext_capability - Find an extended capability * @dev: PCI device to query @@ -1983,7 +2015,7 @@ void pci_enable_ari(struct pci_dev *dev) { int pos; u32 cap; - u16 flags, ctrl; + u16 ctrl; struct pci_dev *bridge; if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) @@ -1997,15 +2029,11 @@ void pci_enable_ari(struct pci_dev *dev) if (!bridge) return; - pos = pci_pcie_cap(bridge); + /* ARI is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(bridge); if (!pos) return; - /* ARI is a PCIe v2 feature */ - pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); - if ((flags & PCI_EXP_FLAGS_VERS) < 2) - return; - pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); if (!(cap & PCI_EXP_DEVCAP2_ARI)) return; @@ -2018,7 +2046,7 @@ void pci_enable_ari(struct pci_dev *dev) } /** - * pci_enable_ido - enable ID-based ordering on a device + * pci_enable_ido - enable ID-based Ordering on a device * @dev: the PCI device * @type: which types of IDO to enable * @@ -2031,7 +2059,8 @@ void pci_enable_ido(struct pci_dev *dev, unsigned long type) int pos; u16 ctrl; - pos = pci_pcie_cap(dev); + /* ID-based Ordering is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return; @@ -2054,7 +2083,8 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type) int pos; u16 ctrl; - pos = pci_pcie_cap(dev); + /* ID-based Ordering is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return; @@ -2093,7 +2123,8 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) u16 ctrl; int ret; - pos = pci_pcie_cap(dev); + /* OBFF is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return -ENOTSUPP; @@ -2143,7 +2174,8 @@ void pci_disable_obff(struct pci_dev *dev) int pos; u16 ctrl; - pos = pci_pcie_cap(dev); + /* OBFF is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return; @@ -2165,7 +2197,8 @@ static bool pci_ltr_supported(struct pci_dev *dev) int pos; u32 cap; - pos = pci_pcie_cap(dev); + /* LTR is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return false; @@ -2193,7 +2226,8 @@ int pci_enable_ltr(struct pci_dev *dev) if (!pci_ltr_supported(dev)) return -ENOTSUPP; - pos = pci_pcie_cap(dev); + /* LTR is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return -ENOTSUPP; @@ -2228,7 +2262,8 @@ void pci_disable_ltr(struct pci_dev *dev) if (!pci_ltr_supported(dev)) return; - pos = pci_pcie_cap(dev); + /* LTR is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); if (!pos) return; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 4b608f543412..e7642f5bb12a 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -507,6 +507,12 @@ #define PCI_EXP_RTSTA 32 /* Root Status */ #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ +/* + * Note that the following PCI Express 'Capability Structure' registers + * were introduced with 'Capability Version' 0x2 (v2). These registers + * do not exist on devices with Capability Version 1. Use pci_pcie_cap2() + * to use these fields safely. + */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ #define PCI_EXP_DEVCAP2_LTR 0x800 /* Latency tolerance reporting */ -- GitLab From 9cb604ed45a31419bab3877472691a5da15a3c47 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Fri, 1 Jun 2012 15:16:43 -0600 Subject: [PATCH 1206/6849] PCI: remove redundant capabilities checking in pci_{save, restore}_pcie_state Unlike PCI Express v1's Capabilities Structure, v2's requires the entire structure to be implemented. In v2 structures, register fields that are not implemented are present but hardwired to 0x0. These may include: Link Capabilities, Status, and Control; Slot Capabilities, Status, and Control; Root Capabilities, Status, and Control; and all of the '2' (Device, Link, and Slot) Capabilities, Status, and Control registers. This patch removes the redundant capability checks corresponding to the Link 2's and Slot 2's, Capabilities, Status, and Control registers as they will be present if Device Capabilities 2's registers are (which explains why the macros for each of the three are identical). Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 985df63aa59f..fe26df7cf5cd 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -854,12 +854,6 @@ EXPORT_SYMBOL(pci_choose_state); ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ (type == PCI_EXP_TYPE_ROOT_PORT || \ type == PCI_EXP_TYPE_RC_EC)) -#define pcie_cap_has_devctl2(type, flags) \ - ((flags & PCI_EXP_FLAGS_VERS) > 1) -#define pcie_cap_has_lnkctl2(type, flags) \ - ((flags & PCI_EXP_FLAGS_VERS) > 1) -#define pcie_cap_has_sltctl2(type, flags) \ - ((flags & PCI_EXP_FLAGS_VERS) > 1) static struct pci_cap_saved_state *pci_find_saved_cap( struct pci_dev *pci_dev, char cap) @@ -902,13 +896,14 @@ static int pci_save_pcie_state(struct pci_dev *dev) pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); if (pcie_cap_has_rtctl(dev->pcie_type, flags)) pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); - if (pcie_cap_has_devctl2(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]); - if (pcie_cap_has_lnkctl2(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]); - if (pcie_cap_has_sltctl2(dev->pcie_type, flags)) - pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]); + pos = pci_pcie_cap2(dev); + if (!pos) + return 0; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]); + pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]); + pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]); return 0; } @@ -935,12 +930,14 @@ static void pci_restore_pcie_state(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); if (pcie_cap_has_rtctl(dev->pcie_type, flags)) pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); - if (pcie_cap_has_devctl2(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]); - if (pcie_cap_has_lnkctl2(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]); - if (pcie_cap_has_sltctl2(dev->pcie_type, flags)) - pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]); + + pos = pci_pcie_cap2(dev); + if (!pos) + return; + + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]); + pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]); + pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]); } -- GitLab From 8f321f853ea33330c7141977cd34804476e2e07e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 8 Jun 2012 11:33:33 +0200 Subject: [PATCH 1207/6849] Bluetooth: Fix using uninitialized option in RFCMode If remote device sends bogus RFC option with invalid length, undefined options values are used. Fix this by using defaults when remote misbehaves. This also fixes the following warning reported by gcc 4.7.0: net/bluetooth/l2cap_core.c: In function 'l2cap_config_rsp': net/bluetooth/l2cap_core.c:3302:13: warning: 'rfc.max_pdu_size' may be used uninitialized in this function [-Wmaybe-uninitialized] net/bluetooth/l2cap_core.c:3266:24: note: 'rfc.max_pdu_size' was declared here net/bluetooth/l2cap_core.c:3298:25: warning: 'rfc.monitor_timeout' may be used uninitialized in this function [-Wmaybe-uninitialized] net/bluetooth/l2cap_core.c:3266:24: note: 'rfc.monitor_timeout' was declared here net/bluetooth/l2cap_core.c:3297:25: warning: 'rfc.retrans_timeout' may be used uninitialized in this function [-Wmaybe-uninitialized] net/bluetooth/l2cap_core.c:3266:24: note: 'rfc.retrans_timeout' was declared here net/bluetooth/l2cap_core.c:3295:2: warning: 'rfc.mode' may be used uninitialized in this function [-Wmaybe-uninitialized] net/bluetooth/l2cap_core.c:3266:24: note: 'rfc.mode' was declared here Signed-off-by: Szymon Janc Signed-off-by: Gustavo Padovan --- net/bluetooth/l2cap_core.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8394e3615ef6..4554e80d16a3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2915,12 +2915,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); - switch (type) { - case L2CAP_CONF_RFC: - if (olen == sizeof(rfc)) - memcpy(&rfc, (void *)val, olen); - goto done; - } + if (type != L2CAP_CONF_RFC) + continue; + + if (olen != sizeof(rfc)) + break; + + memcpy(&rfc, (void *)val, olen); + goto done; } /* Use sane default values in case a misbehaving remote device -- GitLab From 6c4ae5c2e7bfbb7d10d73611f69ac8a8609d84fd Mon Sep 17 00:00:00 2001 From: Giancarlo Formicuccia Date: Sun, 10 Jun 2012 08:33:11 +0200 Subject: [PATCH 1208/6849] Bluetooth: add support for atheros 0930:0219 Add support for the AR3012 chip found on the Toshiba Sallite M840-1000-XQ. usb-devices shows: T: Bus=01 Lev=02 Prnt=02 Port=02 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0930 ProdID=0219 Rev=00.02 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb Signed-off-by: Giancarlo Formicuccia Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index f0f62021227f..10308cd8a7ed 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -78,6 +78,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, + { USB_DEVICE(0x0930, 0x0219) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -102,6 +103,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ff3eabc45ff5..83ebb241bfcc 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -140,6 +140,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, -- GitLab From 975b91bb17e70c0dc33ad07f16097106a9c2c6a2 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 11 Jun 2012 11:13:06 +0300 Subject: [PATCH 1209/6849] Bluetooth: Use standard HCI cmd timeout for RESET Remove magic and use standard HCI cmd timeout Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 08994ecc3b6a..471e4fb1b6e5 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -783,7 +783,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { set_bit(HCI_INIT, &hdev->flags); __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(250)); + msecs_to_jiffies(HCI_CMD_TIMEOUT)); clear_bit(HCI_INIT, &hdev->flags); } -- GitLab From 5f246e890502fed387e0f959e2224ea680c03423 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 11 Jun 2012 11:13:07 +0300 Subject: [PATCH 1210/6849] Bluetooth: Update HCI timeouts constants to use msecs_to_jiffies The HCI constants are always used in form of jiffies. So just include the conversion from msecs in the define itself. This has the advantage of making the code where the timeout is used more readable and avoiding unnecessary conversions. The patch is similar to commit ba13ccd9 doing the same job for L2CAP Reported-by: Marcel Holtmann Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 10 +++++----- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_core.c | 25 +++++++++++-------------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 2a6b0b8b7120..7dcd3495edde 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -139,11 +139,11 @@ enum { #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ -#define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ -#define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ -#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ -#define HCI_CMD_TIMEOUT (1000) /* 1 seconds */ -#define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */ +#define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ +#define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */ +#define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */ +#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 seconds */ +#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ /* HCI data types */ #define HCI_COMMAND_PKT 0x01 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 20fd57367ddc..75766b7f0dc7 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -598,7 +598,7 @@ static inline void hci_conn_put(struct hci_conn *conn) if (conn->type == ACL_LINK || conn->type == LE_LINK) { del_timer(&conn->idle_timer); if (conn->state == BT_CONNECTED) { - timeo = msecs_to_jiffies(conn->disc_timeout); + timeo = conn->disc_timeout; if (!conn->out) timeo *= 2; } else { diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 471e4fb1b6e5..e91bf7e15666 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -690,12 +690,11 @@ int hci_dev_open(__u16 dev) set_bit(HCI_INIT, &hdev->flags); hdev->init_last_cmd = 0; - ret = __hci_request(hdev, hci_init_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); if (lmp_host_le_capable(hdev)) ret = __hci_request(hdev, hci_le_init_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + HCI_INIT_TIMEOUT); clear_bit(HCI_INIT, &hdev->flags); } @@ -782,8 +781,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) if (!test_bit(HCI_RAW, &hdev->flags) && test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { set_bit(HCI_INIT, &hdev->flags); - __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(HCI_CMD_TIMEOUT)); + __hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); clear_bit(HCI_INIT, &hdev->flags); } @@ -872,8 +870,7 @@ int hci_dev_reset(__u16 dev) hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; if (!test_bit(HCI_RAW, &hdev->flags)) - ret = __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); done: hci_req_unlock(hdev); @@ -913,7 +910,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) switch (cmd) { case HCISETAUTH: err = hci_request(hdev, hci_auth_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + HCI_INIT_TIMEOUT); break; case HCISETENCRYPT: @@ -925,23 +922,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) if (!test_bit(HCI_AUTH, &hdev->flags)) { /* Auth must be enabled first */ err = hci_request(hdev, hci_auth_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + HCI_INIT_TIMEOUT); if (err) break; } err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + HCI_INIT_TIMEOUT); break; case HCISETSCAN: err = hci_request(hdev, hci_scan_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + HCI_INIT_TIMEOUT); break; case HCISETLINKPOL: err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + HCI_INIT_TIMEOUT); break; case HCISETLINKMODE: @@ -2455,7 +2452,7 @@ static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) /* ACL tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ if (!cnt && time_after(jiffies, hdev->acl_last_tx + - msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) + HCI_ACL_TX_TIMEOUT)) hci_link_tx_to(hdev, ACL_LINK); } } @@ -2839,7 +2836,7 @@ static void hci_cmd_work(struct work_struct *work) del_timer(&hdev->cmd_timer); else mod_timer(&hdev->cmd_timer, - jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); + jiffies + HCI_CMD_TIMEOUT); } else { skb_queue_head(&hdev->cmd_q, skb); queue_work(hdev->workqueue, &hdev->cmd_work); -- GitLab From bda4f23a5c20deabb07545591be872145528b4ed Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 11 Jun 2012 11:13:08 +0300 Subject: [PATCH 1211/6849] Bluetooth: Add opcode to error message Sometimes HCI command sending timeouts and gives error message without specifying which command causes error. Patch makes sure that opcode is printed to help debugging. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e91bf7e15666..88858963ec21 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1366,11 +1366,19 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) } /* HCI command timer function */ -static void hci_cmd_timer(unsigned long arg) +static void hci_cmd_timeout(unsigned long arg) { struct hci_dev *hdev = (void *) arg; - BT_ERR("%s command tx timeout", hdev->name); + if (hdev->sent_cmd) { + struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; + u16 opcode = __le16_to_cpu(sent->opcode); + + BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); + } else { + BT_ERR("%s command tx timeout", hdev->name); + } + atomic_set(&hdev->cmd_cnt, 1); queue_work(hdev->workqueue, &hdev->cmd_work); } @@ -1668,7 +1676,7 @@ struct hci_dev *hci_alloc_dev(void) init_waitqueue_head(&hdev->req_wait_q); - setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); + setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); hci_init_sysfs(hdev); discovery_init(hdev); -- GitLab From f0e0951007b051046587e73ffc9716caa024d537 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 11 Jun 2012 11:13:09 +0300 Subject: [PATCH 1212/6849] Bluetooth: Correct debug print specifier for u16 objects Some functions print u16 objects as "0xc03" others as "0x0c03". Patch ensures that opcodes printed are the in the same format and consistent with bluetooth code. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 88858963ec21..f7a35cc400cf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -61,7 +61,7 @@ static void hci_notify(struct hci_dev *hdev, int event) void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) { - BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); + BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result); /* If this is the init phase check if the completed command matches * the last init command, and if not just return. @@ -2092,7 +2092,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) struct hci_command_hdr *hdr; struct sk_buff *skb; - BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); + BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); skb = bt_skb_alloc(len, GFP_ATOMIC); if (!skb) { @@ -2134,7 +2134,7 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) if (hdr->opcode != cpu_to_le16(opcode)) return NULL; - BT_DBG("%s opcode 0x%x", hdev->name, opcode); + BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; } @@ -2204,7 +2204,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; - BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); + BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); skb->dev = (void *) hdev; @@ -2704,7 +2704,7 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) flags = hci_flags(handle); handle = hci_handle(handle); - BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, + BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, handle, flags); hdev->stat.acl_rx++; @@ -2746,7 +2746,7 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) handle = __le16_to_cpu(hdr->handle); - BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); + BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); hdev->stat.sco_rx++; -- GitLab From 11778716ededa873f24eebaae011e52f3d27dfca Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 11 Jun 2012 11:13:10 +0300 Subject: [PATCH 1213/6849] Bluetooth: Fix not setting HCI_RESET flag for AMP Move reset function to common initialization section fixing not setting HCI_RESET flag for amp_init. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f7a35cc400cf..a2bdf936ed46 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -188,12 +188,6 @@ static void bredr_init(struct hci_dev *hdev) /* Mandatory initialization */ - /* Reset */ - if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { - set_bit(HCI_RESET, &hdev->flags); - hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); - } - /* Read Local Supported Features */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); @@ -234,9 +228,6 @@ static void amp_init(struct hci_dev *hdev) { hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; - /* Reset */ - hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); - /* Read Local Version */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); @@ -262,6 +253,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) } skb_queue_purge(&hdev->driver_init); + /* Reset */ + if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) + hci_reset_req(hdev, 0); + switch (hdev->dev_type) { case HCI_BREDR: bredr_init(hdev); -- GitLab From 3419ae781f1592b3d367107db6500090495490cd Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 11 Jun 2012 11:27:19 -0600 Subject: [PATCH 1214/6849] ASoC: tegra+wm8903: turn of mic detect when card is removed If mic detect is left enabled and the WM8903 detects a status change, the WM8903 driver will make a callback against the free()d jack, which will cause a crash. This problem can be triggered by fully initializing an audio card, then removing and re-inserting the machine driver module. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0b0df49d9d33..3b6da91188a9 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -346,6 +346,17 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int tegra_wm8903_remove(struct snd_soc_card *card) +{ + struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]); + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; + + wm8903_mic_detect(codec, NULL, 0, 0); + + return 0; +} + static struct snd_soc_dai_link tegra_wm8903_dai = { .name = "WM8903", .stream_name = "WM8903 PCM", @@ -363,6 +374,8 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { .dai_link = &tegra_wm8903_dai, .num_links = 1, + .remove = tegra_wm8903_remove, + .controls = tegra_wm8903_controls, .num_controls = ARRAY_SIZE(tegra_wm8903_controls), .dapm_widgets = tegra_wm8903_dapm_widgets, -- GitLab From f242e50eee1ec7692c4854d94e8cd543991cce71 Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Thu, 7 Jun 2012 14:00:46 +0200 Subject: [PATCH 1215/6849] mfd/ab8500: Move platform-data for ab8500-codec into mfd-driver The platform-data used by the Ux500 ASoC-driver is moved from the machine-driver context into the codec-driver context. This means adding the platform-data for 'ab8500-codec' into the main AB8500 platform-data. Signed-off-by: Ola Lilja Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500.c | 14 +++++++ include/linux/mfd/abx500/ab8500-codec.h | 52 +++++++++++++++++++++++++ include/linux/mfd/abx500/ab8500.h | 2 + 3 files changed, 68 insertions(+) create mode 100644 include/linux/mfd/abx500/ab8500-codec.h diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 9c74ac545849..c8a8fde777bb 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,18 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { 0x7A, 0x00, 0x00}, }; +/* ab8500-codec */ +static struct ab8500_codec_platform_data ab8500_codec_pdata = { + .amics = { + .mic1_type = AMIC_TYPE_DIFFERENTIAL, + .mic2_type = AMIC_TYPE_DIFFERENTIAL, + .mic1a_micbias = AMIC_MICBIAS_VAMIC1, + .mic1b_micbias = AMIC_MICBIAS_VAMIC1, + .mic2_micbias = AMIC_MICBIAS_VAMIC2 + }, + .ear_cmv = EAR_CMV_0_95V +}; + static struct gpio_keys_button snowball_key_array[] = { { .gpio = 32, @@ -195,6 +208,7 @@ static struct ab8500_platform_data ab8500_platdata = { .regulator = ab8500_regulators, .num_regulator = ARRAY_SIZE(ab8500_regulators), .gpio = &ab8500_gpio_pdata, + .codec = &ab8500_codec_pdata, }; static struct resource ab8500_resources[] = { diff --git a/include/linux/mfd/abx500/ab8500-codec.h b/include/linux/mfd/abx500/ab8500-codec.h new file mode 100644 index 000000000000..dc6529202cdd --- /dev/null +++ b/include/linux/mfd/abx500/ab8500-codec.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef AB8500_CORE_CODEC_H +#define AB8500_CORE_CODEC_H + +/* Mic-types */ +enum amic_type { + AMIC_TYPE_SINGLE_ENDED, + AMIC_TYPE_DIFFERENTIAL +}; + +/* Mic-biases */ +enum amic_micbias { + AMIC_MICBIAS_VAMIC1, + AMIC_MICBIAS_VAMIC2 +}; + +/* Bias-voltage */ +enum ear_cm_voltage { + EAR_CMV_0_95V, + EAR_CMV_1_10V, + EAR_CMV_1_27V, + EAR_CMV_1_58V +}; + +/* Analog microphone settings */ +struct amic_settings { + enum amic_type mic1_type; + enum amic_type mic2_type; + enum amic_micbias mic1a_micbias; + enum amic_micbias mic1b_micbias; + enum amic_micbias mic2_micbias; +}; + +/* Platform data structure for the audio-parts of the AB8500 */ +struct ab8500_codec_platform_data { + struct amic_settings amics; + enum ear_cm_voltage ear_cmv; +}; + +#endif diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index 91dd3ef63e99..bc9b84b60ec6 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h @@ -266,6 +266,7 @@ struct ab8500 { struct regulator_reg_init; struct regulator_init_data; struct ab8500_gpio_platform_data; +struct ab8500_codec_platform_data; /** * struct ab8500_platform_data - AB8500 platform data @@ -284,6 +285,7 @@ struct ab8500_platform_data { int num_regulator; struct regulator_init_data *regulator; struct ab8500_gpio_platform_data *gpio; + struct ab8500_codec_platform_data *codec; }; extern int __devinit ab8500_init(struct ab8500 *ab8500, -- GitLab From 34ddeb035d704eafdcdb3cbc781894300136c3c4 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 12 Jun 2012 11:20:19 +0800 Subject: [PATCH 1216/6849] ACPI, APEI, Avoid too much error reporting in runtime This patch fixed the following bug. https://bugzilla.kernel.org/show_bug.cgi?id=43282 This is caused by a firmware bug checking (checking generic address register provided by firmware) in runtime. The checking should be done in address mapping time instead of runtime to avoid too much error reporting in runtime. Reported-by: Pawel Sikora Signed-off-by: Huang Ying Tested-by: Jean Delvare Cc: stable@vger.kernel.org Signed-off-by: Len Brown --- drivers/acpi/apei/apei-base.c | 17 +++++++++++++++-- drivers/acpi/apei/apei-internal.h | 9 +++++++++ drivers/acpi/apei/ghes.c | 6 +++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 5577762daee1..6686b1eaf13e 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - return acpi_os_map_generic_address(&entry->register_region); + return apei_map_generic_address(&entry->register_region); return 0; } @@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - acpi_os_unmap_generic_address(&entry->register_region); + apei_unmap_generic_address(&entry->register_region); return 0; } @@ -606,6 +606,19 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, return 0; } +int apei_map_generic_address(struct acpi_generic_address *reg) +{ + int rc; + u32 access_bit_width; + u64 address; + + rc = apei_check_gar(reg, &address, &access_bit_width); + if (rc) + return rc; + return acpi_os_map_generic_address(reg); +} +EXPORT_SYMBOL_GPL(apei_map_generic_address); + /* read GAR in interrupt (including NMI) or process context */ int apei_read(u64 *val, struct acpi_generic_address *reg) { diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index cca240a33038..f220d642136e 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -7,6 +7,8 @@ #define APEI_INTERNAL_H #include +#include +#include struct apei_exec_context; @@ -68,6 +70,13 @@ static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 actio /* IP has been set in instruction function */ #define APEI_EXEC_SET_IP 1 +int apei_map_generic_address(struct acpi_generic_address *reg); + +static inline void apei_unmap_generic_address(struct acpi_generic_address *reg) +{ + acpi_os_unmap_generic_address(reg); +} + int apei_read(u64 *val, struct acpi_generic_address *reg); int apei_write(u64 val, struct acpi_generic_address *reg); diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 9b3cac0abecc..1599566ed1fe 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -301,7 +301,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) if (!ghes) return ERR_PTR(-ENOMEM); ghes->generic = generic; - rc = acpi_os_map_generic_address(&generic->error_status_address); + rc = apei_map_generic_address(&generic->error_status_address); if (rc) goto err_free; error_block_length = generic->error_block_length; @@ -321,7 +321,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) return ghes; err_unmap: - acpi_os_unmap_generic_address(&generic->error_status_address); + apei_unmap_generic_address(&generic->error_status_address); err_free: kfree(ghes); return ERR_PTR(rc); @@ -330,7 +330,7 @@ err_free: static void ghes_fini(struct ghes *ghes) { kfree(ghes->estatus); - acpi_os_unmap_generic_address(&ghes->generic->error_status_address); + apei_unmap_generic_address(&ghes->generic->error_status_address); } enum { -- GitLab From 2177905ca7419c49910d47e38e44790affd918cc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 11 Jun 2012 23:56:09 -0700 Subject: [PATCH 1217/6849] Input: fix input.h kernel-doc warning Fix kernel-doc warning in input.h: Warning(include/linux/input.h:140): No description found for parameter 'len' Signed-off-by: Randy Dunlap Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/input.h b/include/linux/input.h index a81671453575..2740d080ec6b 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -116,6 +116,7 @@ struct input_keymap_entry { /** * EVIOCGMTSLOTS(len) - get MT slot values + * @len: size of the data buffer in bytes * * The ioctl buffer argument should be binary equivalent to * -- GitLab From 4eceb14f669cb9e9d189019e8fcbf73577fe77a7 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 11 Jun 2012 23:55:32 -0700 Subject: [PATCH 1218/6849] Input: gpio_keys - remove useless reinitialization of pdata->nbuttons pdata is zeroed using memset just a few lines before, so there is no need to set the nbuttons member to 0 again. Signed-off-by: Tobias Klauser Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 62bfce468f9f..cbb1add43d5e 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -559,7 +559,6 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, pdata->rep = !!of_get_property(node, "autorepeat", NULL); /* First count the subnodes */ - pdata->nbuttons = 0; pp = NULL; while ((pp = of_get_next_child(node, pp))) pdata->nbuttons++; -- GitLab From 03ecd229a5d05a5c62e7262d66ec6cd57d5eca6c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 12 Jun 2012 00:21:47 -0700 Subject: [PATCH 1219/6849] Input: ab8500-ponkey - add device tree support Allow the ab8500-ponkey driver to be probed during boot when Device Tree is enabled. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ab8500-ponkey.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 350fd0c385d2..84ec691c05aa 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -13,6 +13,7 @@ #include #include #include +#include #include /** @@ -131,10 +132,18 @@ static int __devexit ab8500_ponkey_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id ab8500_ponkey_match[] = { + { .compatible = "stericsson,ab8500-ponkey", }, + {} +}; +#endif + static struct platform_driver ab8500_ponkey_driver = { .driver = { .name = "ab8500-poweron-key", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ab8500_ponkey_match), }, .probe = ab8500_ponkey_probe, .remove = __devexit_p(ab8500_ponkey_remove), -- GitLab From ea2e60244573a9204c8cee9b4fb181106784c617 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 12 Jun 2012 00:14:12 -0700 Subject: [PATCH 1220/6849] Input: wacom - rearrange type enum So we can simplify a few type related if statements Signed-off-by: Ping Cheng Acked-by: Chris Bagwell Reviewed-by: Jason Gerecke Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 10 +++------- drivers/input/tablet/wacom_wac.c | 6 ++---- drivers/input/tablet/wacom_wac.h | 6 +++--- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b3a8bd3514b2..79b5cfbc1bc4 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -440,8 +440,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat /* ask to report Wacom data */ if (features->device_type == BTN_TOOL_FINGER) { /* if it is an MT Tablet PC touch */ - if (features->type == TABLETPC2FG || - features->type == MTSCREEN) { + if (features->type > TABLETPC) { do { rep_data[0] = 3; rep_data[1] = 4; @@ -460,7 +459,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); } - } else if (features->type != TABLETPC && + } else if (features->type <= BAMBOO_PT && features->type != WIRELESS && features->device_type == BTN_TOOL_PEN) { do { @@ -510,10 +509,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, } /* only devices that support touch need to retrieve the info */ - if (features->type != TABLETPC && - features->type != TABLETPC2FG && - features->type != BAMBOO_PT && - features->type != MTSCREEN) { + if (features->type < BAMBOO_PT) { goto out; } diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 004bc1bb1544..c40dcb7036b3 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1317,10 +1317,8 @@ void wacom_setup_device_quirks(struct wacom_features *features) } /* these device have multiple inputs */ - if (features->type == TABLETPC || features->type == TABLETPC2FG || - features->type == BAMBOO_PT || features->type == WIRELESS || - (features->type >= INTUOS5S && features->type <= INTUOS5L) || - features->type == MTSCREEN) + if (features->type >= WIRELESS || + (features->type >= INTUOS5S && features->type <= INTUOS5L)) features->quirks |= WACOM_QUIRK_MULTI_INPUT; /* quirk for bamboo touch with 2 low res touches */ diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 78fbd3f42009..87080435116c 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -62,8 +62,6 @@ enum { PTU, PL, DTU, - BAMBOO_PT, - WIRELESS, INTUOS, INTUOS3S, INTUOS3, @@ -79,7 +77,9 @@ enum { CINTIQ, WACOM_BEE, WACOM_MO, - TABLETPC, + WIRELESS, + BAMBOO_PT, + TABLETPC, /* add new TPC below */ TABLETPC2FG, MTSCREEN, MAX_TYPE -- GitLab From ac173837cd4b268a538235a1699b91457551a9a9 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 12 Jun 2012 00:15:06 -0700 Subject: [PATCH 1221/6849] Input: wacom - add two new devices (0xed and 0xef) 0xed supports pen and one finger touch; 0xef is pen only. Signed-off-by: Ping Cheng Acked-by: Chris Bagwell Reviewed-by: Jason Gerecke Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 13 ++++++++++++- drivers/input/tablet/wacom_wac.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c40dcb7036b3..fd0cf4d328a3 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -888,7 +888,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) prox = data[0] & 0x01; x = get_unaligned_le16(&data[1]); y = get_unaligned_le16(&data[3]); - } else { /* with capacity */ + } else { prox = data[1] & 0x01; x = le16_to_cpup((__le16 *)&data[2]); y = le16_to_cpup((__le16 *)&data[4]); @@ -961,6 +961,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) case WACOM_REPORT_TPC1FG: case WACOM_REPORT_TPCHID: case WACOM_REPORT_TPCST: + case WACOM_REPORT_TPC1FGE: return wacom_tpc_single_touch(wacom, len); case WACOM_REPORT_TPCMT: @@ -1244,6 +1245,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) break; case TABLETPC: + case TABLETPCE: case TABLETPC2FG: case MTSCREEN: sync = wacom_tpc_irq(wacom_wac, len); @@ -1569,6 +1571,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, /* fall through */ case TABLETPC: + case TABLETPCE: __clear_bit(ABS_MISC, input_dev->absbit); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); @@ -1886,6 +1889,12 @@ static const struct wacom_features wacom_features_0xE6 = static const struct wacom_features wacom_features_0xEC = { "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255, 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xED = + { "Wacom ISDv4 ED", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, + 0, TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xEF = + { "Wacom ISDv4 EF", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x47 = { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -2060,6 +2069,8 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xE5) }, { USB_DEVICE_WACOM(0xE6) }, { USB_DEVICE_WACOM(0xEC) }, + { USB_DEVICE_WACOM(0xED) }, + { USB_DEVICE_WACOM(0xEF) }, { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, { USB_DEVICE_LENOVO(0x6004) }, diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 87080435116c..bd5d37b28714 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -48,6 +48,7 @@ #define WACOM_REPORT_TPCMT 13 #define WACOM_REPORT_TPCHID 15 #define WACOM_REPORT_TPCST 16 +#define WACOM_REPORT_TPC1FGE 18 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT 0x0001 @@ -80,6 +81,7 @@ enum { WIRELESS, BAMBOO_PT, TABLETPC, /* add new TPC below */ + TABLETPCE, TABLETPC2FG, MTSCREEN, MAX_TYPE -- GitLab From b7af2bb84cea328c766c615aac45cdd498c50bc6 Mon Sep 17 00:00:00 2001 From: Chris Bagwell Date: Tue, 12 Jun 2012 00:25:23 -0700 Subject: [PATCH 1222/6849] Input: wacom - battery reporting improvements Do not register battery device until connected to a tablet. This prevents an empty battery icon from being shown when tablet is connected using USB cable. Also, call power_supply_powers() for apps that can make use of that info. And stop ignoring input registration failures. Signed-off-by: Chris Bagwell Reviewed-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 82 +++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 79b5cfbc1bc4..a48fcb76bb83 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -963,6 +963,10 @@ static int wacom_initialize_battery(struct wacom *wacom) error = power_supply_register(&wacom->usbdev->dev, &wacom->battery); + + if (!error) + power_supply_powers(&wacom->battery, + &wacom->usbdev->dev); } return error; @@ -970,8 +974,11 @@ static int wacom_initialize_battery(struct wacom *wacom) static void wacom_destroy_battery(struct wacom *wacom) { - if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) + if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR && + wacom->battery.dev) { power_supply_unregister(&wacom->battery); + wacom->battery.dev = NULL; + } } static int wacom_register_input(struct wacom *wacom) @@ -1018,23 +1025,30 @@ static void wacom_wireless_work(struct work_struct *work) struct wacom *wacom = container_of(work, struct wacom, work); struct usb_device *usbdev = wacom->usbdev; struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct wacom *wacom1, *wacom2; + struct wacom_wac *wacom_wac1, *wacom_wac2; + int error; /* * Regardless if this is a disconnect or a new tablet, - * remove any existing input devices. + * remove any existing input and battery devices. */ + wacom_destroy_battery(wacom); + /* Stylus interface */ - wacom = usb_get_intfdata(usbdev->config->interface[1]); - if (wacom->wacom_wac.input) - input_unregister_device(wacom->wacom_wac.input); - wacom->wacom_wac.input = NULL; + wacom1 = usb_get_intfdata(usbdev->config->interface[1]); + wacom_wac1 = &(wacom1->wacom_wac); + if (wacom_wac1->input) + input_unregister_device(wacom_wac1->input); + wacom_wac1->input = NULL; /* Touch interface */ - wacom = usb_get_intfdata(usbdev->config->interface[2]); - if (wacom->wacom_wac.input) - input_unregister_device(wacom->wacom_wac.input); - wacom->wacom_wac.input = NULL; + wacom2 = usb_get_intfdata(usbdev->config->interface[2]); + wacom_wac2 = &(wacom2->wacom_wac); + if (wacom_wac2->input) + input_unregister_device(wacom_wac2->input); + wacom_wac2->input = NULL; if (wacom_wac->pid == 0) { dev_info(&wacom->intf->dev, "wireless tablet disconnected\n"); @@ -1059,24 +1073,39 @@ static void wacom_wireless_work(struct work_struct *work) } /* Stylus interface */ - wacom = usb_get_intfdata(usbdev->config->interface[1]); - wacom_wac = &wacom->wacom_wac; - wacom_wac->features = + wacom_wac1->features = *((struct wacom_features *)id->driver_info); - wacom_wac->features.device_type = BTN_TOOL_PEN; - wacom_register_input(wacom); + wacom_wac1->features.device_type = BTN_TOOL_PEN; + error = wacom_register_input(wacom1); + if (error) + goto fail1; /* Touch interface */ - wacom = usb_get_intfdata(usbdev->config->interface[2]); - wacom_wac = &wacom->wacom_wac; - wacom_wac->features = + wacom_wac2->features = *((struct wacom_features *)id->driver_info); - wacom_wac->features.pktlen = WACOM_PKGLEN_BBTOUCH3; - wacom_wac->features.device_type = BTN_TOOL_FINGER; - wacom_set_phy_from_res(&wacom_wac->features); - wacom_wac->features.x_max = wacom_wac->features.y_max = 4096; - wacom_register_input(wacom); + wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; + wacom_wac2->features.device_type = BTN_TOOL_FINGER; + wacom_set_phy_from_res(&wacom_wac2->features); + wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; + error = wacom_register_input(wacom2); + if (error) + goto fail2; + + error = wacom_initialize_battery(wacom); + if (error) + goto fail3; } + + return; + +fail3: + input_unregister_device(wacom_wac2->input); + wacom_wac2->input = NULL; +fail2: + input_unregister_device(wacom_wac1->input); + wacom_wac1->input = NULL; +fail1: + return; } static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1179,14 +1208,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail4; - error = wacom_initialize_battery(wacom); - if (error) - goto fail5; - if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { error = wacom_register_input(wacom); if (error) - goto fail6; + goto fail5; } /* Note that if query fails it is not a hard failure */ @@ -1201,7 +1226,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i return 0; - fail6: wacom_destroy_battery(wacom); fail5: wacom_destroy_leds(wacom); fail4: wacom_remove_shared_data(wacom_wac); fail3: usb_free_urb(wacom->irq); -- GitLab From 6dc463511d4a690f01a9248df3b384db717e0b1c Mon Sep 17 00:00:00 2001 From: Chris Bagwell Date: Tue, 12 Jun 2012 00:25:48 -0700 Subject: [PATCH 1223/6849] Input: wacom - Bamboo One 1024 pressure fix Bamboo One's with ID of 0x6a and 0x6b were added with correct indication of 1024 pressure levels but the Graphire packet routine was only looking at 9 bits. Increased to 10 bits. This bug caused these devices to roll over to zero pressure at half way mark. The other devices using this routine only support 256 or 512 range and look to fix unused bits at zero. Signed-off-by: Chris Bagwell Reported-by: Tushant Mirchandani Reviewed-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index fd0cf4d328a3..4453864956b6 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -248,7 +248,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); if (wacom->tool[0] != BTN_TOOL_MOUSE) { - input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); + input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x03) << 8)); input_report_key(input, BTN_TOUCH, data[1] & 0x01); input_report_key(input, BTN_STYLUS, data[1] & 0x02); input_report_key(input, BTN_STYLUS2, data[1] & 0x04); -- GitLab From a19fc98685ad0b5bccc38ca17acb50a92915ec51 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Tue, 12 Jun 2012 00:27:53 -0700 Subject: [PATCH 1224/6849] Input: wacom - initialize and destroy LEDs for Intuos4 S tablets This case appears to have been missed in the original commit. Signed-off-by: Jason Gerecke Reviewed-by: Chris Bagwell Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a48fcb76bb83..a5d1c60e77ee 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -851,6 +851,7 @@ static int wacom_initialize_leds(struct wacom *wacom) /* Initialize default values */ switch (wacom->wacom_wac.features.type) { + case INTUOS4S: case INTUOS4: case INTUOS4L: wacom->led.select[0] = 0; @@ -904,6 +905,7 @@ static int wacom_initialize_leds(struct wacom *wacom) static void wacom_destroy_leds(struct wacom *wacom) { switch (wacom->wacom_wac.features.type) { + case INTUOS4S: case INTUOS4: case INTUOS4L: sysfs_remove_group(&wacom->intf->dev.kobj, -- GitLab From 32edbf562cabc0fb927692c86274c3cd2ccde0d0 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Tue, 12 Jun 2012 00:28:37 -0700 Subject: [PATCH 1225/6849] Input: wacom - remove code duplication Replaces code to calculate Intuos5 physical dimensions with a call to an existing function that performs the same task. Signed-off-by: Jason Gerecke Reviewed-by: Chris Bagwell Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a5d1c60e77ee..9e8fdcf005a3 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -1171,10 +1171,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i features->device_type = BTN_TOOL_FINGER; features->pktlen = WACOM_PKGLEN_BBTOUCH3; - features->x_phy = - (features->x_max * 100) / features->x_resolution; - features->y_phy = - (features->y_max * 100) / features->y_resolution; + wacom_set_phy_from_res(features); features->x_max = 4096; features->y_max = 4096; -- GitLab From e7ec014a47e4d68fc01561d0541a50650646317c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jun 2012 01:10:02 -0700 Subject: [PATCH 1226/6849] Input: twl6040-vibra - update for device tree support The twl6040 DT support implementation has been changed from the originally planned. None of the child devices going to have compatible_of property which means that the child devices of twl6040 will be created as traditional MFD devices. The mfd core driver will decide (based on the DT blob) to create a device for the twl6040-vibra or not. If the DT blob has 'vibra' section the device will be created without pdata. In this case the vibra driver will reach up to the parent node to get the needed properties. With DT booted kernel we no longer be able to link the regulators to the vibra driver, they can be only linked to the MFD device (probed via DT). From the vibra driver we ned to use pdev->dev.parent to get the regulators. Signed-off-by: Peter Ujfalusi Signed-off-by: Dmitry Torokhov --- .../bindings/input/twl6040-vibra.txt | 37 ---------------- drivers/input/misc/twl6040-vibra.c | 42 +++++++++++-------- 2 files changed, 24 insertions(+), 55 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/twl6040-vibra.txt diff --git a/Documentation/devicetree/bindings/input/twl6040-vibra.txt b/Documentation/devicetree/bindings/input/twl6040-vibra.txt deleted file mode 100644 index 5b1918b818fb..000000000000 --- a/Documentation/devicetree/bindings/input/twl6040-vibra.txt +++ /dev/null @@ -1,37 +0,0 @@ -Vibra driver for the twl6040 family - -The vibra driver is a child of the twl6040 MFD dirver. -Documentation/devicetree/bindings/mfd/twl6040.txt - -Required properties: -- compatible : Must be "ti,twl6040-vibra"; -- interrupts: 4, Vibra overcurrent interrupt -- vddvibl-supply: Regulator supplying the left vibra motor -- vddvibr-supply: Regulator supplying the right vibra motor -- vibldrv_res: Board specific left driver resistance -- vibrdrv_res: Board specific right driver resistance -- viblmotor_res: Board specific left motor resistance -- vibrmotor_res: Board specific right motor resistance - -Optional properties: -- vddvibl_uV: If the vddvibl default voltage need to be changed -- vddvibr_uV: If the vddvibr default voltage need to be changed - -Example: -/* - * 8-channel high quality low-power audio codec - * http://www.ti.com/lit/ds/symlink/twl6040.pdf - */ -twl6040: twl6040@4b { - ... - twl6040_vibra: twl6040@1 { - compatible = "ti,twl6040-vibra"; - interrupts = <4>; - vddvibl-supply = <&vbat>; - vddvibr-supply = <&vbat>; - vibldrv_res = <8>; - vibrdrv_res = <3>; - viblmotor_res = <10>; - vibrmotor_res = <10>; - }; -}; diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index c34f6c0371c4..c8a288ae1d5b 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -251,7 +251,6 @@ static int twl6040_vibra_suspend(struct device *dev) return 0; } - #endif static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); @@ -259,13 +258,19 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int __devinit twl6040_vibra_probe(struct platform_device *pdev) { struct twl6040_vibra_data *pdata = pdev->dev.platform_data; - struct device_node *node = pdev->dev.of_node; + struct device *twl6040_core_dev = pdev->dev.parent; + struct device_node *twl6040_core_node = NULL; struct vibra_info *info; int vddvibl_uV = 0; int vddvibr_uV = 0; int ret; - if (!pdata && !node) { +#ifdef CONFIG_OF + twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node, + "vibra"); +#endif + + if (!pdata && !twl6040_core_node) { dev_err(&pdev->dev, "platform_data not available\n"); return -EINVAL; } @@ -287,14 +292,18 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev) vddvibl_uV = pdata->vddvibl_uV; vddvibr_uV = pdata->vddvibr_uV; } else { - of_property_read_u32(node, "vibldrv_res", &info->vibldrv_res); - of_property_read_u32(node, "vibrdrv_res", &info->vibrdrv_res); - of_property_read_u32(node, "viblmotor_res", + of_property_read_u32(twl6040_core_node, "ti,vibldrv-res", + &info->vibldrv_res); + of_property_read_u32(twl6040_core_node, "ti,vibrdrv-res", + &info->vibrdrv_res); + of_property_read_u32(twl6040_core_node, "ti,viblmotor-res", &info->viblmotor_res); - of_property_read_u32(node, "vibrmotor_res", + of_property_read_u32(twl6040_core_node, "ti,vibrmotor-res", &info->vibrmotor_res); - of_property_read_u32(node, "vddvibl_uV", &vddvibl_uV); - of_property_read_u32(node, "vddvibr_uV", &vddvibr_uV); + of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV", + &vddvibl_uV); + of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV", + &vddvibr_uV); } if ((!info->vibldrv_res && !info->viblmotor_res) || @@ -351,8 +360,12 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev) info->supplies[0].supply = "vddvibl"; info->supplies[1].supply = "vddvibr"; - ret = regulator_bulk_get(info->dev, ARRAY_SIZE(info->supplies), - info->supplies); + /* + * When booted with Device tree the regulators are attached to the + * parent device (twl6040 MFD core) + */ + ret = regulator_bulk_get(pdata ? info->dev : twl6040_core_dev, + ARRAY_SIZE(info->supplies), info->supplies); if (ret) { dev_err(info->dev, "couldn't get regulators %d\n", ret); goto err_regulator; @@ -418,12 +431,6 @@ static int __devexit twl6040_vibra_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id twl6040_vibra_of_match[] = { - {.compatible = "ti,twl6040-vibra", }, - { }, -}; -MODULE_DEVICE_TABLE(of, twl6040_vibra_of_match); - static struct platform_driver twl6040_vibra_driver = { .probe = twl6040_vibra_probe, .remove = __devexit_p(twl6040_vibra_remove), @@ -431,7 +438,6 @@ static struct platform_driver twl6040_vibra_driver = { .name = "twl6040-vibra", .owner = THIS_MODULE, .pm = &twl6040_vibra_pm_ops, - .of_match_table = twl6040_vibra_of_match, }, }; module_platform_driver(twl6040_vibra_driver); -- GitLab From 65df57743924c3d13e1fa1bcf5bf70fe874fcdfd Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 24 May 2012 11:13:42 +0200 Subject: [PATCH 1227/6849] crypto: sha1 - use Kbuild supplied flags for AVX test Commit ea4d26ae ("raid5: add AVX optimized RAID5 checksumming") introduced x86/ arch wide defines for AFLAGS and CFLAGS indicating AVX support in binutils based on the same test we have in x86/crypto/ right now. To minimize duplication drop our implementation in favour to the one in x86/. Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 7 ------- arch/x86/crypto/sha1_ssse3_asm.S | 2 +- arch/x86/crypto/sha1_ssse3_glue.c | 6 +++--- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index e191ac048b59..479f95a744f7 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -34,12 +34,5 @@ salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o - ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o - -# enable AVX support only when $(AS) can actually assemble the instructions -ifeq ($(call as-instr,vpxor %xmm0$(comma)%xmm1$(comma)%xmm2,yes,no),yes) -AFLAGS_sha1_ssse3_asm.o += -DSHA1_ENABLE_AVX_SUPPORT -CFLAGS_sha1_ssse3_glue.o += -DSHA1_ENABLE_AVX_SUPPORT -endif sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S index b2c2f57d70e8..49d6987a73d9 100644 --- a/arch/x86/crypto/sha1_ssse3_asm.S +++ b/arch/x86/crypto/sha1_ssse3_asm.S @@ -468,7 +468,7 @@ W_PRECALC_SSSE3 */ SHA1_VECTOR_ASM sha1_transform_ssse3 -#ifdef SHA1_ENABLE_AVX_SUPPORT +#ifdef CONFIG_AS_AVX .macro W_PRECALC_AVX diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c index f916499d0abe..4a11a9d72451 100644 --- a/arch/x86/crypto/sha1_ssse3_glue.c +++ b/arch/x86/crypto/sha1_ssse3_glue.c @@ -35,7 +35,7 @@ asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data, unsigned int rounds); -#ifdef SHA1_ENABLE_AVX_SUPPORT +#ifdef CONFIG_AS_AVX asmlinkage void sha1_transform_avx(u32 *digest, const char *data, unsigned int rounds); #endif @@ -184,7 +184,7 @@ static struct shash_alg alg = { } }; -#ifdef SHA1_ENABLE_AVX_SUPPORT +#ifdef CONFIG_AS_AVX static bool __init avx_usable(void) { u64 xcr0; @@ -209,7 +209,7 @@ static int __init sha1_ssse3_mod_init(void) if (cpu_has_ssse3) sha1_transform_asm = sha1_transform_ssse3; -#ifdef SHA1_ENABLE_AVX_SUPPORT +#ifdef CONFIG_AS_AVX /* allow AVX to override SSSE3, it's a little faster */ if (avx_usable()) sha1_transform_asm = sha1_transform_avx; -- GitLab From a482b081a2d4d74d16bc9ea8779f9f6055f95852 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 25 May 2012 17:54:13 +0800 Subject: [PATCH 1228/6849] crypto: testmgr - Add new test cases for Blackfin CRC crypto driver Signed-off-by: Sonic Zhang Acked-by: Mike Frysinger Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 3 ++ crypto/testmgr.c | 9 +++++ crypto/testmgr.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 8f147bff0980..750cce44bad6 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1192,6 +1192,9 @@ static int do_test(int m) case 109: ret += tcrypt_test("vmac(aes)"); break; + case 110: + ret += tcrypt_test("hmac(crc32)"); + break; case 150: ret += tcrypt_test("ansi_cprng"); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 5674878ff6c1..eb6d20f8ec5d 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -2219,6 +2219,15 @@ static const struct alg_test_desc alg_test_descs[] = { .count = GHASH_TEST_VECTORS } } + }, { + .alg = "hmac(crc32)", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = bfin_crc_tv_template, + .count = BFIN_CRC_TEST_VECTORS + } + } }, { .alg = "hmac(md5)", .test = alg_test_hash, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 36e5a8ee0e1e..34a9d511deef 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -14858,4 +14858,94 @@ static struct hash_testvec crc32c_tv_template[] = { }, }; +/* + * Blakcifn CRC test vectors + */ +#define BFIN_CRC_TEST_VECTORS 6 + +static struct hash_testvec bfin_crc_tv_template[] = { + { + .psize = 0, + .digest = "\x00\x00\x00\x00", + }, + { + .key = "\x87\xa9\xcb\xed", + .ksize = 4, + .psize = 0, + .digest = "\x87\xa9\xcb\xed", + }, + { + .key = "\xff\xff\xff\xff", + .ksize = 4, + .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18" + "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" + "\x21\x22\x23\x24\x25\x26\x27\x28", + .psize = 40, + .digest = "\x84\x0c\x8d\xa2", + }, + { + .key = "\xff\xff\xff\xff", + .ksize = 4, + .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18" + "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" + "\x21\x22\x23\x24\x25\x26", + .psize = 38, + .digest = "\x8c\x58\xec\xb7", + }, + { + .key = "\xff\xff\xff\xff", + .ksize = 4, + .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18" + "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" + "\x21\x22\x23\x24\x25\x26\x27", + .psize = 39, + .digest = "\xdc\x50\x28\x7b", + }, + { + .key = "\xff\xff\xff\xff", + .ksize = 4, + .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18" + "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" + "\x21\x22\x23\x24\x25\x26\x27\x28" + "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30" + "\x31\x32\x33\x34\x35\x36\x37\x38" + "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40" + "\x41\x42\x43\x44\x45\x46\x47\x48" + "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" + "\x51\x52\x53\x54\x55\x56\x57\x58" + "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" + "\x61\x62\x63\x64\x65\x66\x67\x68" + "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73\x74\x75\x76\x77\x78" + "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80" + "\x81\x82\x83\x84\x85\x86\x87\x88" + "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90" + "\x91\x92\x93\x94\x95\x96\x97\x98" + "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0" + "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8" + "\xa9\xaa\xab\xac\xad\xae\xaf\xb0" + "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8" + "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0" + "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8" + "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0" + "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8" + "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0" + "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8" + "\xe9\xea\xeb\xec\xed\xee\xef\xf0", + .psize = 240, + .digest = "\x10\x19\x4a\x5c", + .np = 2, + .tap = { 31, 209 } + }, + +}; + #endif /* _CRYPTO_TESTMGR_H */ -- GitLab From b8840098b70c11d70c29263e0765f103e6cbe55e Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 4 Jun 2012 12:24:47 +0800 Subject: [PATCH 1229/6849] crypto: bfin_crc - CRC hardware driver for BF60x family processors. The CRC peripheral is a hardware block used to compute the CRC of the block of data. This is based on a CRC32 engine which computes the CRC value of 32b data words presented to it. For data words of < 32b in size, this driver pack 0 automatically into 32b data units. This driver implements the async hash crypto framework API. Signed-off-by: Sonic Zhang Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 7 + drivers/crypto/Makefile | 3 +- drivers/crypto/bfin_crc.c | 780 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 789 insertions(+), 1 deletion(-) create mode 100644 drivers/crypto/bfin_crc.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 1092a770482e..dd4d5af6c31f 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -325,4 +325,11 @@ if CRYPTO_DEV_UX500 source "drivers/crypto/ux500/Kconfig" endif # if CRYPTO_DEV_UX500 +config CRYPTO_DEV_BFIN_CRC + tristate "Support for Blackfin CRC hardware" + depends on BF60x + help + Newer Blackfin processors have CRC hardware. Select this if you + want to use the Blackfin CRC module. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 01390325d72d..d5062bb7a1f2 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -14,4 +14,5 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o -obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/ \ No newline at end of file +obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/ +obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o diff --git a/drivers/crypto/bfin_crc.c b/drivers/crypto/bfin_crc.c new file mode 100644 index 000000000000..5398580b4313 --- /dev/null +++ b/drivers/crypto/bfin_crc.c @@ -0,0 +1,780 @@ +/* + * Cryptographic API. + * + * Support Blackfin CRC HW acceleration. + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CRC_CCRYPTO_QUEUE_LENGTH 5 + +#define DRIVER_NAME "bfin-hmac-crc" +#define CHKSUM_DIGEST_SIZE 4 +#define CHKSUM_BLOCK_SIZE 1 + +#define CRC_MAX_DMA_DESC 100 + +#define CRC_CRYPTO_STATE_UPDATE 1 +#define CRC_CRYPTO_STATE_FINALUPDATE 2 +#define CRC_CRYPTO_STATE_FINISH 3 + +struct bfin_crypto_crc { + struct list_head list; + struct device *dev; + spinlock_t lock; + + int irq; + int dma_ch; + u32 poly; + volatile struct crc_register *regs; + + struct ahash_request *req; /* current request in operation */ + struct dma_desc_array *sg_cpu; /* virt addr of sg dma descriptors */ + dma_addr_t sg_dma; /* phy addr of sg dma descriptors */ + u8 *sg_mid_buf; + + struct tasklet_struct done_task; + struct crypto_queue queue; /* waiting requests */ + + u8 busy:1; /* crc device in operation flag */ +}; + +static struct bfin_crypto_crc_list { + struct list_head dev_list; + spinlock_t lock; +} crc_list; + +struct bfin_crypto_crc_reqctx { + struct bfin_crypto_crc *crc; + + unsigned int total; /* total request bytes */ + size_t sg_buflen; /* bytes for this update */ + unsigned int sg_nents; + struct scatterlist *sg; /* sg list head for this update*/ + struct scatterlist bufsl[2]; /* chained sg list */ + + size_t bufnext_len; + size_t buflast_len; + u8 bufnext[CHKSUM_DIGEST_SIZE]; /* extra bytes for next udpate */ + u8 buflast[CHKSUM_DIGEST_SIZE]; /* extra bytes from last udpate */ + + u8 flag; +}; + +struct bfin_crypto_crc_ctx { + struct bfin_crypto_crc *crc; + u32 key; +}; + + +/* + * derive number of elements in scatterlist + */ +static int sg_count(struct scatterlist *sg_list) +{ + struct scatterlist *sg = sg_list; + int sg_nents = 1; + + if (sg_list == NULL) + return 0; + + while (!sg_is_last(sg)) { + sg_nents++; + sg = scatterwalk_sg_next(sg); + } + + return sg_nents; +} + +/* + * get element in scatter list by given index + */ +static struct scatterlist *sg_get(struct scatterlist *sg_list, unsigned int nents, + unsigned int index) +{ + struct scatterlist *sg = NULL; + int i; + + for_each_sg(sg_list, sg, nents, i) + if (i == index) + break; + + return sg; +} + +static int bfin_crypto_crc_init_hw(struct bfin_crypto_crc *crc, u32 key) +{ + crc->regs->datacntrld = 0; + crc->regs->control = MODE_CALC_CRC << OPMODE_OFFSET; + crc->regs->curresult = key; + + /* setup CRC interrupts */ + crc->regs->status = CMPERRI | DCNTEXPI; + crc->regs->intrenset = CMPERRI | DCNTEXPI; + SSYNC(); + + return 0; +} + +static int bfin_crypto_crc_init(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct bfin_crypto_crc_ctx *crc_ctx = crypto_ahash_ctx(tfm); + struct bfin_crypto_crc_reqctx *ctx = ahash_request_ctx(req); + struct bfin_crypto_crc *crc; + + dev_dbg(crc->dev, "crc_init\n"); + spin_lock_bh(&crc_list.lock); + list_for_each_entry(crc, &crc_list.dev_list, list) { + crc_ctx->crc = crc; + break; + } + spin_unlock_bh(&crc_list.lock); + + if (sg_count(req->src) > CRC_MAX_DMA_DESC) { + dev_dbg(crc->dev, "init: requested sg list is too big > %d\n", + CRC_MAX_DMA_DESC); + return -EINVAL; + } + + ctx->crc = crc; + ctx->bufnext_len = 0; + ctx->buflast_len = 0; + ctx->sg_buflen = 0; + ctx->total = 0; + ctx->flag = 0; + + /* init crc results */ + put_unaligned_le32(crc_ctx->key, req->result); + + dev_dbg(crc->dev, "init: digest size: %d\n", + crypto_ahash_digestsize(tfm)); + + return bfin_crypto_crc_init_hw(crc, crc_ctx->key); +} + +static void bfin_crypto_crc_config_dma(struct bfin_crypto_crc *crc) +{ + struct scatterlist *sg; + struct bfin_crypto_crc_reqctx *ctx = ahash_request_ctx(crc->req); + int i = 0, j = 0; + unsigned long dma_config; + unsigned int dma_count; + unsigned int dma_addr; + unsigned int mid_dma_count = 0; + int dma_mod; + + dma_map_sg(crc->dev, ctx->sg, ctx->sg_nents, DMA_TO_DEVICE); + + for_each_sg(ctx->sg, sg, ctx->sg_nents, j) { + dma_config = DMAFLOW_ARRAY | RESTART | NDSIZE_3 | DMAEN | PSIZE_32; + dma_addr = sg_dma_address(sg); + /* deduce extra bytes in last sg */ + if (sg_is_last(sg)) + dma_count = sg_dma_len(sg) - ctx->bufnext_len; + else + dma_count = sg_dma_len(sg); + + if (mid_dma_count) { + /* Append last middle dma buffer to 4 bytes with first + bytes in current sg buffer. Move addr of current + sg and deduce the length of current sg. + */ + memcpy(crc->sg_mid_buf +((i-1) << 2) + mid_dma_count, + (void *)dma_addr, + CHKSUM_DIGEST_SIZE - mid_dma_count); + dma_addr += CHKSUM_DIGEST_SIZE - mid_dma_count; + dma_count -= CHKSUM_DIGEST_SIZE - mid_dma_count; + } + /* chop current sg dma len to multiple of 32 bits */ + mid_dma_count = dma_count % 4; + dma_count &= ~0x3; + + if (dma_addr % 4 == 0) { + dma_config |= WDSIZE_32; + dma_count >>= 2; + dma_mod = 4; + } else if (dma_addr % 2 == 0) { + dma_config |= WDSIZE_16; + dma_count >>= 1; + dma_mod = 2; + } else { + dma_config |= WDSIZE_8; + dma_mod = 1; + } + + crc->sg_cpu[i].start_addr = dma_addr; + crc->sg_cpu[i].cfg = dma_config; + crc->sg_cpu[i].x_count = dma_count; + crc->sg_cpu[i].x_modify = dma_mod; + dev_dbg(crc->dev, "%d: crc_dma: start_addr:0x%lx, " + "cfg:0x%lx, x_count:0x%lx, x_modify:0x%lx\n", + i, crc->sg_cpu[i].start_addr, + crc->sg_cpu[i].cfg, crc->sg_cpu[i].x_count, + crc->sg_cpu[i].x_modify); + i++; + + if (mid_dma_count) { + /* copy extra bytes to next middle dma buffer */ + dma_config = DMAFLOW_ARRAY | RESTART | NDSIZE_3 | + DMAEN | PSIZE_32 | WDSIZE_32; + memcpy(crc->sg_mid_buf + (i << 2), + (void *)(dma_addr + (dma_count << 2)), + mid_dma_count); + /* setup new dma descriptor for next middle dma */ + crc->sg_cpu[i].start_addr = dma_map_single(crc->dev, + crc->sg_mid_buf + (i << 2), + CHKSUM_DIGEST_SIZE, DMA_TO_DEVICE); + crc->sg_cpu[i].cfg = dma_config; + crc->sg_cpu[i].x_count = 1; + crc->sg_cpu[i].x_modify = CHKSUM_DIGEST_SIZE; + dev_dbg(crc->dev, "%d: crc_dma: start_addr:0x%lx, " + "cfg:0x%lx, x_count:0x%lx, x_modify:0x%lx\n", + i, crc->sg_cpu[i].start_addr, + crc->sg_cpu[i].cfg, crc->sg_cpu[i].x_count, + crc->sg_cpu[i].x_modify); + i++; + } + } + + dma_config = DMAFLOW_ARRAY | RESTART | NDSIZE_3 | DMAEN | PSIZE_32 | WDSIZE_32; + /* For final update req, append the buffer for next update as well*/ + if (ctx->bufnext_len && (ctx->flag == CRC_CRYPTO_STATE_FINALUPDATE || + ctx->flag == CRC_CRYPTO_STATE_FINISH)) { + crc->sg_cpu[i].start_addr = dma_map_single(crc->dev, ctx->bufnext, + CHKSUM_DIGEST_SIZE, DMA_TO_DEVICE); + crc->sg_cpu[i].cfg = dma_config; + crc->sg_cpu[i].x_count = 1; + crc->sg_cpu[i].x_modify = CHKSUM_DIGEST_SIZE; + dev_dbg(crc->dev, "%d: crc_dma: start_addr:0x%lx, " + "cfg:0x%lx, x_count:0x%lx, x_modify:0x%lx\n", + i, crc->sg_cpu[i].start_addr, + crc->sg_cpu[i].cfg, crc->sg_cpu[i].x_count, + crc->sg_cpu[i].x_modify); + i++; + } + + if (i == 0) + return; + + flush_dcache_range((unsigned int)crc->sg_cpu, + (unsigned int)crc->sg_cpu + + i * sizeof(struct dma_desc_array)); + + /* Set the last descriptor to stop mode */ + crc->sg_cpu[i - 1].cfg &= ~(DMAFLOW | NDSIZE); + crc->sg_cpu[i - 1].cfg |= DI_EN; + set_dma_curr_desc_addr(crc->dma_ch, (unsigned long *)crc->sg_dma); + set_dma_x_count(crc->dma_ch, 0); + set_dma_x_modify(crc->dma_ch, 0); + SSYNC(); + set_dma_config(crc->dma_ch, dma_config); +} + +static int bfin_crypto_crc_handle_queue(struct bfin_crypto_crc *crc, + struct ahash_request *req) +{ + struct crypto_async_request *async_req, *backlog; + struct bfin_crypto_crc_reqctx *ctx; + struct scatterlist *sg; + int ret = 0; + int nsg, i, j; + unsigned int nextlen; + unsigned long flags; + + spin_lock_irqsave(&crc->lock, flags); + if (req) + ret = ahash_enqueue_request(&crc->queue, req); + if (crc->busy) { + spin_unlock_irqrestore(&crc->lock, flags); + return ret; + } + backlog = crypto_get_backlog(&crc->queue); + async_req = crypto_dequeue_request(&crc->queue); + if (async_req) + crc->busy = 1; + spin_unlock_irqrestore(&crc->lock, flags); + + if (!async_req) + return ret; + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + req = ahash_request_cast(async_req); + crc->req = req; + ctx = ahash_request_ctx(req); + ctx->sg = NULL; + ctx->sg_buflen = 0; + ctx->sg_nents = 0; + + dev_dbg(crc->dev, "handling new req, flag=%u, nbytes: %d\n", + ctx->flag, req->nbytes); + + if (ctx->flag == CRC_CRYPTO_STATE_FINISH) { + if (ctx->bufnext_len == 0) { + crc->busy = 0; + return 0; + } + + /* Pack last crc update buffer to 32bit */ + memset(ctx->bufnext + ctx->bufnext_len, 0, + CHKSUM_DIGEST_SIZE - ctx->bufnext_len); + } else { + /* Pack small data which is less than 32bit to buffer for next update. */ + if (ctx->bufnext_len + req->nbytes < CHKSUM_DIGEST_SIZE) { + memcpy(ctx->bufnext + ctx->bufnext_len, + sg_virt(req->src), req->nbytes); + ctx->bufnext_len += req->nbytes; + if (ctx->flag == CRC_CRYPTO_STATE_FINALUPDATE && + ctx->bufnext_len) { + goto finish_update; + } else { + crc->busy = 0; + return 0; + } + } + + if (ctx->bufnext_len) { + /* Chain in extra bytes of last update */ + ctx->buflast_len = ctx->bufnext_len; + memcpy(ctx->buflast, ctx->bufnext, ctx->buflast_len); + + nsg = ctx->sg_buflen ? 2 : 1; + sg_init_table(ctx->bufsl, nsg); + sg_set_buf(ctx->bufsl, ctx->buflast, ctx->buflast_len); + if (nsg > 1) + scatterwalk_sg_chain(ctx->bufsl, nsg, + req->src); + ctx->sg = ctx->bufsl; + } else + ctx->sg = req->src; + + /* Chop crc buffer size to multiple of 32 bit */ + nsg = ctx->sg_nents = sg_count(ctx->sg); + ctx->sg_buflen = ctx->buflast_len + req->nbytes; + ctx->bufnext_len = ctx->sg_buflen % 4; + ctx->sg_buflen &= ~0x3; + + if (ctx->bufnext_len) { + /* copy extra bytes to buffer for next update */ + memset(ctx->bufnext, 0, CHKSUM_DIGEST_SIZE); + nextlen = ctx->bufnext_len; + for (i = nsg - 1; i >= 0; i--) { + sg = sg_get(ctx->sg, nsg, i); + j = min(nextlen, sg_dma_len(sg)); + memcpy(ctx->bufnext + nextlen - j, + sg_virt(sg) + sg_dma_len(sg) - j, j); + if (j == sg_dma_len(sg)) + ctx->sg_nents--; + nextlen -= j; + if (nextlen == 0) + break; + } + } + } + +finish_update: + if (ctx->bufnext_len && (ctx->flag == CRC_CRYPTO_STATE_FINALUPDATE || + ctx->flag == CRC_CRYPTO_STATE_FINISH)) + ctx->sg_buflen += CHKSUM_DIGEST_SIZE; + + /* set CRC data count before start DMA */ + crc->regs->datacnt = ctx->sg_buflen >> 2; + + /* setup and enable CRC DMA */ + bfin_crypto_crc_config_dma(crc); + + /* finally kick off CRC operation */ + crc->regs->control |= BLKEN; + SSYNC(); + + return -EINPROGRESS; +} + +static int bfin_crypto_crc_update(struct ahash_request *req) +{ + struct bfin_crypto_crc_reqctx *ctx = ahash_request_ctx(req); + + if (!req->nbytes) + return 0; + + dev_dbg(ctx->crc->dev, "crc_update\n"); + ctx->total += req->nbytes; + ctx->flag = CRC_CRYPTO_STATE_UPDATE; + + return bfin_crypto_crc_handle_queue(ctx->crc, req); +} + +static int bfin_crypto_crc_final(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct bfin_crypto_crc_ctx *crc_ctx = crypto_ahash_ctx(tfm); + struct bfin_crypto_crc_reqctx *ctx = ahash_request_ctx(req); + + dev_dbg(ctx->crc->dev, "crc_final\n"); + ctx->flag = CRC_CRYPTO_STATE_FINISH; + crc_ctx->key = 0; + + return bfin_crypto_crc_handle_queue(ctx->crc, req); +} + +static int bfin_crypto_crc_finup(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct bfin_crypto_crc_ctx *crc_ctx = crypto_ahash_ctx(tfm); + struct bfin_crypto_crc_reqctx *ctx = ahash_request_ctx(req); + + dev_dbg(ctx->crc->dev, "crc_finishupdate\n"); + ctx->total += req->nbytes; + ctx->flag = CRC_CRYPTO_STATE_FINALUPDATE; + crc_ctx->key = 0; + + return bfin_crypto_crc_handle_queue(ctx->crc, req); +} + +static int bfin_crypto_crc_digest(struct ahash_request *req) +{ + int ret; + + ret = bfin_crypto_crc_init(req); + if (ret) + return ret; + + return bfin_crypto_crc_finup(req); +} + +static int bfin_crypto_crc_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen) +{ + struct bfin_crypto_crc_ctx *crc_ctx = crypto_ahash_ctx(tfm); + + dev_dbg(crc_ctx->crc->dev, "crc_setkey\n"); + if (keylen != CHKSUM_DIGEST_SIZE) { + crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + crc_ctx->key = get_unaligned_le32(key); + + return 0; +} + +static int bfin_crypto_crc_cra_init(struct crypto_tfm *tfm) +{ + struct bfin_crypto_crc_ctx *crc_ctx = crypto_tfm_ctx(tfm); + + crc_ctx->key = 0; + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct bfin_crypto_crc_reqctx)); + + return 0; +} + +static void bfin_crypto_crc_cra_exit(struct crypto_tfm *tfm) +{ +} + +static struct ahash_alg algs = { + .init = bfin_crypto_crc_init, + .update = bfin_crypto_crc_update, + .final = bfin_crypto_crc_final, + .finup = bfin_crypto_crc_finup, + .digest = bfin_crypto_crc_digest, + .setkey = bfin_crypto_crc_setkey, + .halg.digestsize = CHKSUM_DIGEST_SIZE, + .halg.base = { + .cra_name = "hmac(crc32)", + .cra_driver_name = DRIVER_NAME, + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = CHKSUM_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct bfin_crypto_crc_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + .cra_init = bfin_crypto_crc_cra_init, + .cra_exit = bfin_crypto_crc_cra_exit, + } +}; + +static void bfin_crypto_crc_done_task(unsigned long data) +{ + struct bfin_crypto_crc *crc = (struct bfin_crypto_crc *)data; + + bfin_crypto_crc_handle_queue(crc, NULL); +} + +static irqreturn_t bfin_crypto_crc_handler(int irq, void *dev_id) +{ + struct bfin_crypto_crc *crc = dev_id; + + if (crc->regs->status & DCNTEXP) { + crc->regs->status = DCNTEXP; + SSYNC(); + + /* prepare results */ + put_unaligned_le32(crc->regs->result, crc->req->result); + + crc->regs->control &= ~BLKEN; + crc->busy = 0; + + if (crc->req->base.complete) + crc->req->base.complete(&crc->req->base, 0); + + tasklet_schedule(&crc->done_task); + + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + +#ifdef CONFIG_PM +/** + * bfin_crypto_crc_suspend - suspend crc device + * @pdev: device being suspended + * @state: requested suspend state + */ +static int bfin_crypto_crc_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct bfin_crypto_crc *crc = platform_get_drvdata(pdev); + int i = 100000; + + while ((crc->regs->control & BLKEN) && --i) + cpu_relax(); + + if (i == 0) + return -EBUSY; + + return 0; +} +#else +# define bfin_crypto_crc_suspend NULL +#endif + +#define bfin_crypto_crc_resume NULL + +/** + * bfin_crypto_crc_probe - Initialize module + * + */ +static int __devinit bfin_crypto_crc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + struct bfin_crypto_crc *crc; + unsigned int timeout = 100000; + int ret; + + crc = kzalloc(sizeof(*crc), GFP_KERNEL); + if (!crc) { + dev_err(&pdev->dev, "fail to malloc bfin_crypto_crc\n"); + return -ENOMEM; + } + + crc->dev = dev; + + INIT_LIST_HEAD(&crc->list); + spin_lock_init(&crc->lock); + tasklet_init(&crc->done_task, bfin_crypto_crc_done_task, (unsigned long)crc); + crypto_init_queue(&crc->queue, CRC_CCRYPTO_QUEUE_LENGTH); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); + ret = -ENOENT; + goto out_error_free_mem; + } + + crc->regs = ioremap(res->start, resource_size(res)); + if (!crc->regs) { + dev_err(&pdev->dev, "Cannot map CRC IO\n"); + ret = -ENXIO; + goto out_error_free_mem; + } + + crc->irq = platform_get_irq(pdev, 0); + if (crc->irq < 0) { + dev_err(&pdev->dev, "No CRC DCNTEXP IRQ specified\n"); + ret = -ENOENT; + goto out_error_unmap; + } + + ret = request_irq(crc->irq, bfin_crypto_crc_handler, IRQF_SHARED, dev_name(dev), crc); + if (ret) { + dev_err(&pdev->dev, "Unable to request blackfin crc irq\n"); + goto out_error_unmap; + } + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (res == NULL) { + dev_err(&pdev->dev, "No CRC DMA channel specified\n"); + ret = -ENOENT; + goto out_error_irq; + } + crc->dma_ch = res->start; + + ret = request_dma(crc->dma_ch, dev_name(dev)); + if (ret) { + dev_err(&pdev->dev, "Unable to attach Blackfin CRC DMA channel\n"); + goto out_error_irq; + } + + crc->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &crc->sg_dma, GFP_KERNEL); + if (crc->sg_cpu == NULL) { + ret = -ENOMEM; + goto out_error_dma; + } + /* + * need at most CRC_MAX_DMA_DESC sg + CRC_MAX_DMA_DESC middle + + * 1 last + 1 next dma descriptors + */ + crc->sg_mid_buf = (u8 *)(crc->sg_cpu + ((CRC_MAX_DMA_DESC + 1) << 1)); + + crc->regs->control = 0; + SSYNC(); + crc->regs->poly = crc->poly = (u32)pdev->dev.platform_data; + SSYNC(); + + while (!(crc->regs->status & LUTDONE) && (--timeout) > 0) + cpu_relax(); + + if (timeout == 0) + dev_info(&pdev->dev, "init crc poly timeout\n"); + + spin_lock(&crc_list.lock); + list_add(&crc->list, &crc_list.dev_list); + spin_unlock(&crc_list.lock); + + platform_set_drvdata(pdev, crc); + + ret = crypto_register_ahash(&algs); + if (ret) { + spin_lock(&crc_list.lock); + list_del(&crc->list); + spin_unlock(&crc_list.lock); + dev_err(&pdev->dev, "Cann't register crypto ahash device\n"); + goto out_error_dma; + } + + dev_info(&pdev->dev, "initialized\n"); + + return 0; + +out_error_dma: + if (crc->sg_cpu) + dma_free_coherent(&pdev->dev, PAGE_SIZE, crc->sg_cpu, crc->sg_dma); + free_dma(crc->dma_ch); +out_error_irq: + free_irq(crc->irq, crc->dev); +out_error_unmap: + iounmap((void *)crc->regs); +out_error_free_mem: + kfree(crc); + + return ret; +} + +/** + * bfin_crypto_crc_remove - Initialize module + * + */ +static int __devexit bfin_crypto_crc_remove(struct platform_device *pdev) +{ + struct bfin_crypto_crc *crc = platform_get_drvdata(pdev); + + if (!crc) + return -ENODEV; + + spin_lock(&crc_list.lock); + list_del(&crc->list); + spin_unlock(&crc_list.lock); + + crypto_unregister_ahash(&algs); + tasklet_kill(&crc->done_task); + iounmap((void *)crc->regs); + free_dma(crc->dma_ch); + if (crc->irq > 0) + free_irq(crc->irq, crc->dev); + kfree(crc); + + return 0; +} + +static struct platform_driver bfin_crypto_crc_driver = { + .probe = bfin_crypto_crc_probe, + .remove = __devexit_p(bfin_crypto_crc_remove), + .suspend = bfin_crypto_crc_suspend, + .resume = bfin_crypto_crc_resume, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +/** + * bfin_crypto_crc_mod_init - Initialize module + * + * Checks the module params and registers the platform driver. + * Real work is in the platform probe function. + */ +static int __init bfin_crypto_crc_mod_init(void) +{ + int ret; + + pr_info("Blackfin hardware CRC crypto driver\n"); + + INIT_LIST_HEAD(&crc_list.dev_list); + spin_lock_init(&crc_list.lock); + + ret = platform_driver_register(&bfin_crypto_crc_driver); + if (ret) { + pr_info(KERN_ERR "unable to register driver\n"); + return ret; + } + + return 0; +} + +/** + * bfin_crypto_crc_mod_exit - Deinitialize module + */ +static void __exit bfin_crypto_crc_mod_exit(void) +{ + platform_driver_unregister(&bfin_crypto_crc_driver); +} + +module_init(bfin_crypto_crc_mod_init); +module_exit(bfin_crypto_crc_mod_exit); + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Blackfin CRC hardware crypto driver"); +MODULE_LICENSE("GPL"); -- GitLab From 170dd56dfc3b13e7dafd48e27f67fddb3f17ef2a Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 25 May 2012 15:54:46 +0200 Subject: [PATCH 1230/6849] crypto: mv_cesa - add an expiry timer in case anything goes wrong The timer triggers when 500ms have gone by after triggering the engine and no completion interrupt was received. The callback then tries to sanitise things as well as possible. Signed-off-by: Phil Sutter Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 41 ++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 1cc6b3f3e262..b0b2f02518f8 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -24,6 +24,7 @@ #define MV_CESA "MV-CESA:" #define MAX_HW_HASH_SIZE 0xFFFF +#define MV_CESA_EXPIRE 500 /* msec */ /* * STM: @@ -87,6 +88,7 @@ struct crypto_priv { spinlock_t lock; struct crypto_queue queue; enum engine_status eng_st; + struct timer_list completion_timer; struct crypto_async_request *cur_req; struct req_progress p; int max_req_size; @@ -138,6 +140,29 @@ struct mv_req_hash_ctx { int count_add; }; +static void mv_completion_timer_callback(unsigned long unused) +{ + int active = readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_EN_SEC_ACCL0; + + printk(KERN_ERR MV_CESA + "completion timer expired (CESA %sactive), cleaning up.\n", + active ? "" : "in"); + + del_timer(&cpg->completion_timer); + writel(SEC_CMD_DISABLE_SEC, cpg->reg + SEC_ACCEL_CMD); + while(readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_DISABLE_SEC) + printk(KERN_INFO MV_CESA "%s: waiting for engine finishing\n", __func__); + cpg->eng_st = ENGINE_W_DEQUEUE; + wake_up_process(cpg->queue_th); +} + +static void mv_setup_timer(void) +{ + setup_timer(&cpg->completion_timer, &mv_completion_timer_callback, 0); + mod_timer(&cpg->completion_timer, + jiffies + msecs_to_jiffies(MV_CESA_EXPIRE)); +} + static void compute_aes_dec_key(struct mv_ctx *ctx) { struct crypto_aes_ctx gen_aes_key; @@ -273,12 +298,8 @@ static void mv_process_current_q(int first_block) sizeof(struct sec_accel_config)); /* GO */ + mv_setup_timer(); writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); - - /* - * XXX: add timer if the interrupt does not occur for some mystery - * reason - */ } static void mv_crypto_algo_completion(void) @@ -357,12 +378,8 @@ static void mv_process_hash_current(int first_block) memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); /* GO */ + mv_setup_timer(); writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); - - /* - * XXX: add timer if the interrupt does not occur for some mystery - * reason - */ } static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx, @@ -888,6 +905,10 @@ irqreturn_t crypto_int(int irq, void *priv) if (!(val & SEC_INT_ACCEL0_DONE)) return IRQ_NONE; + if (!del_timer(&cpg->completion_timer)) { + printk(KERN_WARNING MV_CESA + "got an interrupt but no pending timer?\n"); + } val &= ~SEC_INT_ACCEL0_DONE; writel(val, cpg->reg + FPGA_INT_STATUS); writel(val, cpg->reg + SEC_ACCEL_INT_STATUS); -- GitLab From 5741d2eeaee28b37a4711a1776f716b274f3d2e4 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 12 Jun 2012 16:41:21 +0800 Subject: [PATCH 1231/6849] crypto: mv_cesa - initialise the interrupt status field to zero Signed-off-by: Phil Sutter Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index b0b2f02518f8..904623d45c62 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -1082,6 +1082,7 @@ static int mv_probe(struct platform_device *pdev) if (!IS_ERR(cp->clk)) clk_prepare_enable(cp->clk); + writel(0, cpg->reg + SEC_ACCEL_INT_STATUS); writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK); writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG); writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); -- GitLab From 4d03c5047a07a62563e1a8fa798ea258f048bfde Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 25 May 2012 15:54:49 +0200 Subject: [PATCH 1232/6849] crypto: mv_cesa - fix for hash finalisation with data Since mv_hash_final_fallback() uses ctx->state, read out the digest state register before calling it. Signed-off-by: Phil Sutter Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 904623d45c62..0d4071754352 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -423,6 +423,15 @@ out: return rc; } +static void mv_save_digest_state(struct mv_req_hash_ctx *ctx) +{ + ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A); + ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B); + ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C); + ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D); + ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E); +} + static void mv_hash_algo_completion(void) { struct ahash_request *req = ahash_request_cast(cpg->cur_req); @@ -437,14 +446,12 @@ static void mv_hash_algo_completion(void) memcpy(req->result, cpg->sram + SRAM_DIGEST_BUF, crypto_ahash_digestsize(crypto_ahash_reqtfm (req))); - } else + } else { + mv_save_digest_state(ctx); mv_hash_final_fallback(req); + } } else { - ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A); - ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B); - ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C); - ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D); - ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E); + mv_save_digest_state(ctx); } } -- GitLab From 107778b592576c0c8e8d2ca7a2aa5415a4908223 Mon Sep 17 00:00:00 2001 From: Johannes Goetzfried Date: Mon, 28 May 2012 15:54:24 +0200 Subject: [PATCH 1233/6849] crypto: twofish - add x86_64/avx assembler implementation This patch adds a x86_64/avx assembler implementation of the Twofish block cipher. The implementation processes eight blocks in parallel (two 4 block chunk AVX operations). The table-lookups are done in general-purpose registers. For small blocksizes the 3way-parallel functions from the twofish-x86_64-3way module are called. A good performance increase is provided for blocksizes greater or equal to 128B. Patch has been tested with tcrypt and automated filesystem tests. Tcrypt benchmark results: Intel Core i5-2500 CPU (fam:6, model:42, step:7) twofish-avx-x86_64 vs. twofish-x86_64-3way 128bit key: (lrw:256bit) (xts:256bit) size ecb-enc ecb-dec cbc-enc cbc-dec ctr-enc ctr-dec lrw-enc lrw-dec xts-enc xts-dec 16B 0.96x 0.97x 1.00x 0.95x 0.97x 0.97x 0.96x 0.95x 0.95x 0.98x 64B 0.99x 0.99x 1.00x 0.99x 0.98x 0.98x 0.99x 0.98x 0.99x 0.98x 256B 1.20x 1.21x 1.00x 1.19x 1.15x 1.14x 1.19x 1.20x 1.18x 1.19x 1024B 1.29x 1.30x 1.00x 1.28x 1.23x 1.24x 1.26x 1.28x 1.26x 1.27x 8192B 1.31x 1.32x 1.00x 1.31x 1.25x 1.25x 1.28x 1.29x 1.28x 1.30x 256bit key: (lrw:384bit) (xts:512bit) size ecb-enc ecb-dec cbc-enc cbc-dec ctr-enc ctr-dec lrw-enc lrw-dec xts-enc xts-dec 16B 0.96x 0.96x 1.00x 0.96x 0.97x 0.98x 0.95x 0.95x 0.95x 0.96x 64B 1.00x 0.99x 1.00x 0.98x 0.98x 1.01x 0.98x 0.98x 0.98x 0.98x 256B 1.20x 1.21x 1.00x 1.21x 1.15x 1.15x 1.19x 1.20x 1.18x 1.19x 1024B 1.29x 1.30x 1.00x 1.28x 1.23x 1.23x 1.26x 1.27x 1.26x 1.27x 8192B 1.31x 1.33x 1.00x 1.31x 1.26x 1.26x 1.29x 1.29x 1.28x 1.30x twofish-avx-x86_64 vs aes-asm (8kB block): 128bit 256bit ecb-enc 1.19x 1.63x ecb-dec 1.18x 1.62x cbc-enc 0.75x 1.03x cbc-dec 1.23x 1.67x ctr-enc 1.24x 1.65x ctr-dec 1.24x 1.65x lrw-enc 1.15x 1.53x lrw-dec 1.14x 1.52x xts-enc 1.16x 1.56x xts-dec 1.16x 1.56x Signed-off-by: Johannes Goetzfried Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 2 + arch/x86/crypto/twofish-avx-x86_64-asm_64.S | 301 +++++ arch/x86/crypto/twofish_avx_glue.c | 1086 +++++++++++++++++++ arch/x86/crypto/twofish_glue_3way.c | 2 + crypto/Kconfig | 24 + crypto/tcrypt.c | 23 + crypto/testmgr.c | 60 + 7 files changed, 1498 insertions(+) create mode 100644 arch/x86/crypto/twofish-avx-x86_64-asm_64.S create mode 100644 arch/x86/crypto/twofish_avx_glue.c diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 479f95a744f7..3420feef0c70 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_CRYPTO_CAMELLIA_X86_64) += camellia-x86_64.o obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o +obj-$(CONFIG_CRYPTO_TWOFISH_AVX_X86_64) += twofish-avx-x86_64.o obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o @@ -30,6 +31,7 @@ camellia-x86_64-y := camellia-x86_64-asm_64.o camellia_glue.o blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o +twofish-avx-x86_64-y := twofish-avx-x86_64-asm_64.o twofish_avx_glue.o salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S new file mode 100644 index 000000000000..fc31b89ba4c3 --- /dev/null +++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S @@ -0,0 +1,301 @@ +/* + * Twofish Cipher 8-way parallel algorithm (AVX/x86_64) + * + * Copyright (C) 2012 Johannes Goetzfried + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +.file "twofish-avx-x86_64-asm_64.S" +.text + +/* structure of crypto context */ +#define s0 0 +#define s1 1024 +#define s2 2048 +#define s3 3072 +#define w 4096 +#define k 4128 + +/********************************************************************** + 8-way AVX twofish + **********************************************************************/ +#define CTX %rdi + +#define RA1 %xmm0 +#define RB1 %xmm1 +#define RC1 %xmm2 +#define RD1 %xmm3 + +#define RA2 %xmm4 +#define RB2 %xmm5 +#define RC2 %xmm6 +#define RD2 %xmm7 + +#define RX %xmm8 +#define RY %xmm9 + +#define RK1 %xmm10 +#define RK2 %xmm11 + +#define RID1 %rax +#define RID1b %al +#define RID2 %rbx +#define RID2b %bl + +#define RGI1 %rdx +#define RGI1bl %dl +#define RGI1bh %dh +#define RGI2 %rcx +#define RGI2bl %cl +#define RGI2bh %ch + +#define RGS1 %r8 +#define RGS1d %r8d +#define RGS2 %r9 +#define RGS2d %r9d +#define RGS3 %r10 +#define RGS3d %r10d + + +#define lookup_32bit(t0, t1, t2, t3, src, dst) \ + movb src ## bl, RID1b; \ + movb src ## bh, RID2b; \ + movl t0(CTX, RID1, 4), dst ## d; \ + xorl t1(CTX, RID2, 4), dst ## d; \ + shrq $16, src; \ + movb src ## bl, RID1b; \ + movb src ## bh, RID2b; \ + xorl t2(CTX, RID1, 4), dst ## d; \ + xorl t3(CTX, RID2, 4), dst ## d; + +#define G(a, x, t0, t1, t2, t3) \ + vmovq a, RGI1; \ + vpsrldq $8, a, x; \ + vmovq x, RGI2; \ + \ + lookup_32bit(t0, t1, t2, t3, RGI1, RGS1); \ + shrq $16, RGI1; \ + lookup_32bit(t0, t1, t2, t3, RGI1, RGS2); \ + shlq $32, RGS2; \ + orq RGS1, RGS2; \ + \ + lookup_32bit(t0, t1, t2, t3, RGI2, RGS1); \ + shrq $16, RGI2; \ + lookup_32bit(t0, t1, t2, t3, RGI2, RGS3); \ + shlq $32, RGS3; \ + orq RGS1, RGS3; \ + \ + vmovq RGS2, x; \ + vpinsrq $1, RGS3, x, x; + +#define encround(a, b, c, d, x, y) \ + G(a, x, s0, s1, s2, s3); \ + G(b, y, s1, s2, s3, s0); \ + vpaddd x, y, x; \ + vpaddd y, x, y; \ + vpaddd x, RK1, x; \ + vpaddd y, RK2, y; \ + vpxor x, c, c; \ + vpsrld $1, c, x; \ + vpslld $(32 - 1), c, c; \ + vpor c, x, c; \ + vpslld $1, d, x; \ + vpsrld $(32 - 1), d, d; \ + vpor d, x, d; \ + vpxor d, y, d; + +#define decround(a, b, c, d, x, y) \ + G(a, x, s0, s1, s2, s3); \ + G(b, y, s1, s2, s3, s0); \ + vpaddd x, y, x; \ + vpaddd y, x, y; \ + vpaddd y, RK2, y; \ + vpxor d, y, d; \ + vpsrld $1, d, y; \ + vpslld $(32 - 1), d, d; \ + vpor d, y, d; \ + vpslld $1, c, y; \ + vpsrld $(32 - 1), c, c; \ + vpor c, y, c; \ + vpaddd x, RK1, x; \ + vpxor x, c, c; + +#define encrypt_round(n, a, b, c, d) \ + vbroadcastss (k+4*(2*(n)))(CTX), RK1; \ + vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \ + encround(a ## 1, b ## 1, c ## 1, d ## 1, RX, RY); \ + encround(a ## 2, b ## 2, c ## 2, d ## 2, RX, RY); + +#define decrypt_round(n, a, b, c, d) \ + vbroadcastss (k+4*(2*(n)))(CTX), RK1; \ + vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \ + decround(a ## 1, b ## 1, c ## 1, d ## 1, RX, RY); \ + decround(a ## 2, b ## 2, c ## 2, d ## 2, RX, RY); + +#define encrypt_cycle(n) \ + encrypt_round((2*n), RA, RB, RC, RD); \ + encrypt_round(((2*n) + 1), RC, RD, RA, RB); + +#define decrypt_cycle(n) \ + decrypt_round(((2*n) + 1), RC, RD, RA, RB); \ + decrypt_round((2*n), RA, RB, RC, RD); + + +#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ + vpunpckldq x1, x0, t0; \ + vpunpckhdq x1, x0, t2; \ + vpunpckldq x3, x2, t1; \ + vpunpckhdq x3, x2, x3; \ + \ + vpunpcklqdq t1, t0, x0; \ + vpunpckhqdq t1, t0, x1; \ + vpunpcklqdq x3, t2, x2; \ + vpunpckhqdq x3, t2, x3; + +#define inpack_blocks(in, x0, x1, x2, x3, wkey, t0, t1, t2) \ + vpxor (0*4*4)(in), wkey, x0; \ + vpxor (1*4*4)(in), wkey, x1; \ + vpxor (2*4*4)(in), wkey, x2; \ + vpxor (3*4*4)(in), wkey, x3; \ + \ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) + +#define outunpack_blocks(out, x0, x1, x2, x3, wkey, t0, t1, t2) \ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ + \ + vpxor x0, wkey, x0; \ + vmovdqu x0, (0*4*4)(out); \ + vpxor x1, wkey, x1; \ + vmovdqu x1, (1*4*4)(out); \ + vpxor x2, wkey, x2; \ + vmovdqu x2, (2*4*4)(out); \ + vpxor x3, wkey, x3; \ + vmovdqu x3, (3*4*4)(out); + +#define outunpack_xor_blocks(out, x0, x1, x2, x3, wkey, t0, t1, t2) \ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ + \ + vpxor x0, wkey, x0; \ + vpxor (0*4*4)(out), x0, x0; \ + vmovdqu x0, (0*4*4)(out); \ + vpxor x1, wkey, x1; \ + vpxor (1*4*4)(out), x1, x1; \ + vmovdqu x1, (1*4*4)(out); \ + vpxor x2, wkey, x2; \ + vpxor (2*4*4)(out), x2, x2; \ + vmovdqu x2, (2*4*4)(out); \ + vpxor x3, wkey, x3; \ + vpxor (3*4*4)(out), x3, x3; \ + vmovdqu x3, (3*4*4)(out); + +.align 8 +.global __twofish_enc_blk_8way +.type __twofish_enc_blk_8way,@function; + +__twofish_enc_blk_8way: + /* input: + * %rdi: ctx, CTX + * %rsi: dst + * %rdx: src + * %rcx: bool, if true: xor output + */ + + pushq %rbx; + pushq %rcx; + + vmovdqu w(CTX), RK1; + + leaq (4*4*4)(%rdx), %rax; + inpack_blocks(%rdx, RA1, RB1, RC1, RD1, RK1, RX, RY, RK2); + inpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX, RY, RK2); + + xorq RID1, RID1; + xorq RID2, RID2; + + encrypt_cycle(0); + encrypt_cycle(1); + encrypt_cycle(2); + encrypt_cycle(3); + encrypt_cycle(4); + encrypt_cycle(5); + encrypt_cycle(6); + encrypt_cycle(7); + + vmovdqu (w+4*4)(CTX), RK1; + + popq %rcx; + popq %rbx; + + leaq (4*4*4)(%rsi), %rax; + leaq (4*4*4)(%rax), %rdx; + + testb %cl, %cl; + jnz __enc_xor8; + + outunpack_blocks(%rsi, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2); + outunpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2); + + ret; + +__enc_xor8: + outunpack_xor_blocks(%rsi, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2); + outunpack_xor_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2); + + ret; + +.align 8 +.global twofish_dec_blk_8way +.type twofish_dec_blk_8way,@function; + +twofish_dec_blk_8way: + /* input: + * %rdi: ctx, CTX + * %rsi: dst + * %rdx: src + */ + + pushq %rbx; + + vmovdqu (w+4*4)(CTX), RK1; + + leaq (4*4*4)(%rdx), %rax; + inpack_blocks(%rdx, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2); + inpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2); + + xorq RID1, RID1; + xorq RID2, RID2; + + decrypt_cycle(7); + decrypt_cycle(6); + decrypt_cycle(5); + decrypt_cycle(4); + decrypt_cycle(3); + decrypt_cycle(2); + decrypt_cycle(1); + decrypt_cycle(0); + + vmovdqu (w)(CTX), RK1; + + popq %rbx; + + leaq (4*4*4)(%rsi), %rax; + outunpack_blocks(%rsi, RA1, RB1, RC1, RD1, RK1, RX, RY, RK2); + outunpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX, RY, RK2); + + ret; diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c new file mode 100644 index 000000000000..599f19e4bef6 --- /dev/null +++ b/arch/x86/crypto/twofish_avx_glue.c @@ -0,0 +1,1086 @@ +/* + * Glue Code for AVX assembler version of Twofish Cipher + * + * Copyright (C) 2012 Johannes Goetzfried + * + * + * Glue code based on serpent_sse2_glue.c by: + * Copyright (C) 2011 Jussi Kivilinna + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define TWOFISH_PARALLEL_BLOCKS 8 + +/* regular block cipher functions from twofish_x86_64 module */ +asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); +asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); + +/* 3-way parallel cipher functions from twofish_x86_64-3way module */ +asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src, bool xor); +asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); + +static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src) +{ + __twofish_enc_blk_3way(ctx, dst, src, false); +} + +static inline void twofish_enc_blk_3way_xor(struct twofish_ctx *ctx, u8 *dst, + const u8 *src) +{ + __twofish_enc_blk_3way(ctx, dst, src, true); +} + +/* 8-way parallel cipher functions */ +asmlinkage void __twofish_enc_blk_8way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src, bool xor); +asmlinkage void twofish_dec_blk_8way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); + +static inline void twofish_enc_blk_xway(struct twofish_ctx *ctx, u8 *dst, + const u8 *src) +{ + __twofish_enc_blk_8way(ctx, dst, src, false); +} + +static inline void twofish_enc_blk_xway_xor(struct twofish_ctx *ctx, u8 *dst, + const u8 *src) +{ + __twofish_enc_blk_8way(ctx, dst, src, true); +} + +static inline void twofish_dec_blk_xway(struct twofish_ctx *ctx, u8 *dst, + const u8 *src) +{ + twofish_dec_blk_8way(ctx, dst, src); +} + + + +struct async_twofish_ctx { + struct cryptd_ablkcipher *cryptd_tfm; +}; + +static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes) +{ + if (fpu_enabled) + return true; + + /* AVX is only used when chunk to be processed is large enough, so + * do not enable FPU until it is necessary. + */ + if (nbytes < TF_BLOCK_SIZE * TWOFISH_PARALLEL_BLOCKS) + return false; + + kernel_fpu_begin(); + return true; +} + +static inline void twofish_fpu_end(bool fpu_enabled) +{ + if (fpu_enabled) + kernel_fpu_end(); +} + +static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, + bool enc) +{ + bool fpu_enabled = false; + struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = TF_BLOCK_SIZE; + unsigned int nbytes; + int err; + + err = blkcipher_walk_virt(desc, walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk->nbytes)) { + u8 *wsrc = walk->src.virt.addr; + u8 *wdst = walk->dst.virt.addr; + + fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes); + + /* Process multi-block batch */ + if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) { + do { + if (enc) + twofish_enc_blk_xway(ctx, wdst, wsrc); + else + twofish_dec_blk_xway(ctx, wdst, wsrc); + + wsrc += bsize * TWOFISH_PARALLEL_BLOCKS; + wdst += bsize * TWOFISH_PARALLEL_BLOCKS; + nbytes -= bsize * TWOFISH_PARALLEL_BLOCKS; + } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS); + + if (nbytes < bsize) + goto done; + } + + /* Process three block batch */ + if (nbytes >= bsize * 3) { + do { + if (enc) + twofish_enc_blk_3way(ctx, wdst, wsrc); + else + twofish_dec_blk_3way(ctx, wdst, wsrc); + + wsrc += bsize * 3; + wdst += bsize * 3; + nbytes -= bsize * 3; + } while (nbytes >= bsize * 3); + + if (nbytes < bsize) + goto done; + } + + /* Handle leftovers */ + do { + if (enc) + twofish_enc_blk(ctx, wdst, wsrc); + else + twofish_dec_blk(ctx, wdst, wsrc); + + wsrc += bsize; + wdst += bsize; + nbytes -= bsize; + } while (nbytes >= bsize); + +done: + err = blkcipher_walk_done(desc, walk, nbytes); + } + + twofish_fpu_end(fpu_enabled); + return err; +} + +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); + return ecb_crypt(desc, &walk, true); +} + +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); + return ecb_crypt(desc, &walk, false); +} + +static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = TF_BLOCK_SIZE; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 *iv = (u128 *)walk->iv; + + do { + u128_xor(dst, src, iv); + twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst); + iv = dst; + + src += 1; + dst += 1; + nbytes -= bsize; + } while (nbytes >= bsize); + + u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); + return nbytes; +} + +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while ((nbytes = walk.nbytes)) { + nbytes = __cbc_encrypt(desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} + +static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = TF_BLOCK_SIZE; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 ivs[TWOFISH_PARALLEL_BLOCKS - 1]; + u128 last_iv; + int i; + + /* Start of the last block. */ + src += nbytes / bsize - 1; + dst += nbytes / bsize - 1; + + last_iv = *src; + + /* Process multi-block batch */ + if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) { + do { + nbytes -= bsize * (TWOFISH_PARALLEL_BLOCKS - 1); + src -= TWOFISH_PARALLEL_BLOCKS - 1; + dst -= TWOFISH_PARALLEL_BLOCKS - 1; + + for (i = 0; i < TWOFISH_PARALLEL_BLOCKS - 1; i++) + ivs[i] = src[i]; + + twofish_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); + + for (i = 0; i < TWOFISH_PARALLEL_BLOCKS - 1; i++) + u128_xor(dst + (i + 1), dst + (i + 1), ivs + i); + + nbytes -= bsize; + if (nbytes < bsize) + goto done; + + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS); + + if (nbytes < bsize) + goto done; + } + + /* Process three block batch */ + if (nbytes >= bsize * 3) { + do { + nbytes -= bsize * (3 - 1); + src -= 3 - 1; + dst -= 3 - 1; + + ivs[0] = src[0]; + ivs[1] = src[1]; + + twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); + + u128_xor(dst + 1, dst + 1, ivs + 0); + u128_xor(dst + 2, dst + 2, ivs + 1); + + nbytes -= bsize; + if (nbytes < bsize) + goto done; + + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } while (nbytes >= bsize * 3); + + if (nbytes < bsize) + goto done; + } + + /* Handle leftovers */ + for (;;) { + twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src); + + nbytes -= bsize; + if (nbytes < bsize) + break; + + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } + +done: + u128_xor(dst, dst, (u128 *)walk->iv); + *(u128 *)walk->iv = last_iv; + + return nbytes; +} + +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + bool fpu_enabled = false; + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk.nbytes)) { + fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes); + nbytes = __cbc_decrypt(desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + twofish_fpu_end(fpu_enabled); + return err; +} + +static inline void u128_to_be128(be128 *dst, const u128 *src) +{ + dst->a = cpu_to_be64(src->a); + dst->b = cpu_to_be64(src->b); +} + +static inline void be128_to_u128(u128 *dst, const be128 *src) +{ + dst->a = be64_to_cpu(src->a); + dst->b = be64_to_cpu(src->b); +} + +static inline void u128_inc(u128 *i) +{ + i->b++; + if (!i->b) + i->a++; +} + +static void ctr_crypt_final(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + u8 *ctrblk = walk->iv; + u8 keystream[TF_BLOCK_SIZE]; + u8 *src = walk->src.virt.addr; + u8 *dst = walk->dst.virt.addr; + unsigned int nbytes = walk->nbytes; + + twofish_enc_blk(ctx, keystream, ctrblk); + crypto_xor(keystream, src, nbytes); + memcpy(dst, keystream, nbytes); + + crypto_inc(ctrblk, TF_BLOCK_SIZE); +} + +static unsigned int __ctr_crypt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = TF_BLOCK_SIZE; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 ctrblk; + be128 ctrblocks[TWOFISH_PARALLEL_BLOCKS]; + int i; + + be128_to_u128(&ctrblk, (be128 *)walk->iv); + + /* Process multi-block batch */ + if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) { + do { + /* create ctrblks for parallel encrypt */ + for (i = 0; i < TWOFISH_PARALLEL_BLOCKS; i++) { + if (dst != src) + dst[i] = src[i]; + + u128_to_be128(&ctrblocks[i], &ctrblk); + u128_inc(&ctrblk); + } + + twofish_enc_blk_xway_xor(ctx, (u8 *)dst, + (u8 *)ctrblocks); + + src += TWOFISH_PARALLEL_BLOCKS; + dst += TWOFISH_PARALLEL_BLOCKS; + nbytes -= bsize * TWOFISH_PARALLEL_BLOCKS; + } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS); + + if (nbytes < bsize) + goto done; + } + + /* Process three block batch */ + if (nbytes >= bsize * 3) { + do { + if (dst != src) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + } + + /* create ctrblks for parallel encrypt */ + u128_to_be128(&ctrblocks[0], &ctrblk); + u128_inc(&ctrblk); + u128_to_be128(&ctrblocks[1], &ctrblk); + u128_inc(&ctrblk); + u128_to_be128(&ctrblocks[2], &ctrblk); + u128_inc(&ctrblk); + + twofish_enc_blk_3way_xor(ctx, (u8 *)dst, + (u8 *)ctrblocks); + + src += 3; + dst += 3; + nbytes -= bsize * 3; + } while (nbytes >= bsize * 3); + + if (nbytes < bsize) + goto done; + } + + /* Handle leftovers */ + do { + if (dst != src) + *dst = *src; + + u128_to_be128(&ctrblocks[0], &ctrblk); + u128_inc(&ctrblk); + + twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); + u128_xor(dst, dst, (u128 *)ctrblocks); + + src += 1; + dst += 1; + nbytes -= bsize; + } while (nbytes >= bsize); + +done: + u128_to_be128((be128 *)walk->iv, &ctrblk); + return nbytes; +} + +static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + bool fpu_enabled = false; + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) { + fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes); + nbytes = __ctr_crypt(desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + twofish_fpu_end(fpu_enabled); + + if (walk.nbytes) { + ctr_crypt_final(desc, &walk); + err = blkcipher_walk_done(desc, &walk, 0); + } + + return err; +} + +struct crypt_priv { + struct twofish_ctx *ctx; + bool fpu_enabled; +}; + +static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) +{ + const unsigned int bsize = TF_BLOCK_SIZE; + struct crypt_priv *ctx = priv; + int i; + + ctx->fpu_enabled = twofish_fpu_begin(ctx->fpu_enabled, nbytes); + + if (nbytes == bsize * TWOFISH_PARALLEL_BLOCKS) { + twofish_enc_blk_xway(ctx->ctx, srcdst, srcdst); + return; + } + + for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) + twofish_enc_blk_3way(ctx->ctx, srcdst, srcdst); + + nbytes %= bsize * 3; + + for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) + twofish_enc_blk(ctx->ctx, srcdst, srcdst); +} + +static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) +{ + const unsigned int bsize = TF_BLOCK_SIZE; + struct crypt_priv *ctx = priv; + int i; + + ctx->fpu_enabled = twofish_fpu_begin(ctx->fpu_enabled, nbytes); + + if (nbytes == bsize * TWOFISH_PARALLEL_BLOCKS) { + twofish_dec_blk_xway(ctx->ctx, srcdst, srcdst); + return; + } + + for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) + twofish_dec_blk_3way(ctx->ctx, srcdst, srcdst); + + nbytes %= bsize * 3; + + for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) + twofish_dec_blk(ctx->ctx, srcdst, srcdst); +} + +struct twofish_lrw_ctx { + struct lrw_table_ctx lrw_table; + struct twofish_ctx twofish_ctx; +}; + +static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); + int err; + + err = __twofish_setkey(&ctx->twofish_ctx, key, + keylen - TF_BLOCK_SIZE, &tfm->crt_flags); + if (err) + return err; + + return lrw_init_table(&ctx->lrw_table, key + keylen - + TF_BLOCK_SIZE); +} + +static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[TWOFISH_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->twofish_ctx, + .fpu_enabled = false, + }; + struct lrw_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .table_ctx = &ctx->lrw_table, + .crypt_ctx = &crypt_ctx, + .crypt_fn = encrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = lrw_crypt(desc, dst, src, nbytes, &req); + twofish_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[TWOFISH_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->twofish_ctx, + .fpu_enabled = false, + }; + struct lrw_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .table_ctx = &ctx->lrw_table, + .crypt_ctx = &crypt_ctx, + .crypt_fn = decrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = lrw_crypt(desc, dst, src, nbytes, &req); + twofish_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static void lrw_exit_tfm(struct crypto_tfm *tfm) +{ + struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); + + lrw_free_table(&ctx->lrw_table); +} + +struct twofish_xts_ctx { + struct twofish_ctx tweak_ctx; + struct twofish_ctx crypt_ctx; +}; + +static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); + u32 *flags = &tfm->crt_flags; + int err; + + /* key consists of keys of equal size concatenated, therefore + * the length must be even + */ + if (keylen % 2) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + /* first half of xts-key is for crypt */ + err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); + if (err) + return err; + + /* second half of xts-key is for tweak */ + return __twofish_setkey(&ctx->tweak_ctx, + key + keylen / 2, keylen / 2, flags); +} + +static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[TWOFISH_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->crypt_ctx, + .fpu_enabled = false, + }; + struct xts_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .tweak_ctx = &ctx->tweak_ctx, + .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), + .crypt_ctx = &crypt_ctx, + .crypt_fn = encrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = xts_crypt(desc, dst, src, nbytes, &req); + twofish_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[TWOFISH_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->crypt_ctx, + .fpu_enabled = false, + }; + struct xts_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .tweak_ctx = &ctx->tweak_ctx, + .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), + .crypt_ctx = &crypt_ctx, + .crypt_fn = decrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = xts_crypt(desc, dst, src, nbytes, &req); + twofish_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len) +{ + struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; + int err; + + crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); + crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) + & CRYPTO_TFM_REQ_MASK); + err = crypto_ablkcipher_setkey(child, key, key_len); + crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) + & CRYPTO_TFM_RES_MASK); + return err; +} + +static int __ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct blkcipher_desc desc; + + desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); + desc.info = req->info; + desc.flags = 0; + + return crypto_blkcipher_crt(desc.tfm)->encrypt( + &desc, req->dst, req->src, req->nbytes); +} + +static int ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + if (!irq_fpu_usable()) { + struct ablkcipher_request *cryptd_req = + ablkcipher_request_ctx(req); + + memcpy(cryptd_req, req, sizeof(*req)); + ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + + return crypto_ablkcipher_encrypt(cryptd_req); + } else { + return __ablk_encrypt(req); + } +} + +static int ablk_decrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + if (!irq_fpu_usable()) { + struct ablkcipher_request *cryptd_req = + ablkcipher_request_ctx(req); + + memcpy(cryptd_req, req, sizeof(*req)); + ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + + return crypto_ablkcipher_decrypt(cryptd_req); + } else { + struct blkcipher_desc desc; + + desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); + desc.info = req->info; + desc.flags = 0; + + return crypto_blkcipher_crt(desc.tfm)->decrypt( + &desc, req->dst, req->src, req->nbytes); + } +} + +static void ablk_exit(struct crypto_tfm *tfm) +{ + struct async_twofish_ctx *ctx = crypto_tfm_ctx(tfm); + + cryptd_free_ablkcipher(ctx->cryptd_tfm); +} + +static int ablk_init(struct crypto_tfm *tfm) +{ + struct async_twofish_ctx *ctx = crypto_tfm_ctx(tfm); + struct cryptd_ablkcipher *cryptd_tfm; + char drv_name[CRYPTO_MAX_ALG_NAME]; + + snprintf(drv_name, sizeof(drv_name), "__driver-%s", + crypto_tfm_alg_driver_name(tfm)); + + cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); + + ctx->cryptd_tfm = cryptd_tfm; + tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + + crypto_ablkcipher_reqsize(&cryptd_tfm->base); + + return 0; +} + +static struct crypto_alg twofish_algs[10] = { { + .cra_name = "__ecb-twofish-avx", + .cra_driver_name = "__driver-ecb-twofish-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[0].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = TF_MIN_KEY_SIZE, + .max_keysize = TF_MAX_KEY_SIZE, + .setkey = twofish_setkey, + .encrypt = ecb_encrypt, + .decrypt = ecb_decrypt, + }, + }, +}, { + .cra_name = "__cbc-twofish-avx", + .cra_driver_name = "__driver-cbc-twofish-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[1].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = TF_MIN_KEY_SIZE, + .max_keysize = TF_MAX_KEY_SIZE, + .setkey = twofish_setkey, + .encrypt = cbc_encrypt, + .decrypt = cbc_decrypt, + }, + }, +}, { + .cra_name = "__ctr-twofish-avx", + .cra_driver_name = "__driver-ctr-twofish-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[2].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = TF_MIN_KEY_SIZE, + .max_keysize = TF_MAX_KEY_SIZE, + .ivsize = TF_BLOCK_SIZE, + .setkey = twofish_setkey, + .encrypt = ctr_crypt, + .decrypt = ctr_crypt, + }, + }, +}, { + .cra_name = "__lrw-twofish-avx", + .cra_driver_name = "__driver-lrw-twofish-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct twofish_lrw_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[3].cra_list), + .cra_exit = lrw_exit_tfm, + .cra_u = { + .blkcipher = { + .min_keysize = TF_MIN_KEY_SIZE + + TF_BLOCK_SIZE, + .max_keysize = TF_MAX_KEY_SIZE + + TF_BLOCK_SIZE, + .ivsize = TF_BLOCK_SIZE, + .setkey = lrw_twofish_setkey, + .encrypt = lrw_encrypt, + .decrypt = lrw_decrypt, + }, + }, +}, { + .cra_name = "__xts-twofish-avx", + .cra_driver_name = "__driver-xts-twofish-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct twofish_xts_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[4].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = TF_MIN_KEY_SIZE * 2, + .max_keysize = TF_MAX_KEY_SIZE * 2, + .ivsize = TF_BLOCK_SIZE, + .setkey = xts_twofish_setkey, + .encrypt = xts_encrypt, + .decrypt = xts_decrypt, + }, + }, +}, { + .cra_name = "ecb(twofish)", + .cra_driver_name = "ecb-twofish-avx", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[5].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = TF_MIN_KEY_SIZE, + .max_keysize = TF_MAX_KEY_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +}, { + .cra_name = "cbc(twofish)", + .cra_driver_name = "cbc-twofish-avx", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[6].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = TF_MIN_KEY_SIZE, + .max_keysize = TF_MAX_KEY_SIZE, + .ivsize = TF_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = __ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +}, { + .cra_name = "ctr(twofish)", + .cra_driver_name = "ctr-twofish-avx", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[7].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = TF_MIN_KEY_SIZE, + .max_keysize = TF_MAX_KEY_SIZE, + .ivsize = TF_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_encrypt, + .geniv = "chainiv", + }, + }, +}, { + .cra_name = "lrw(twofish)", + .cra_driver_name = "lrw-twofish-avx", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[8].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = TF_MIN_KEY_SIZE + + TF_BLOCK_SIZE, + .max_keysize = TF_MAX_KEY_SIZE + + TF_BLOCK_SIZE, + .ivsize = TF_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +}, { + .cra_name = "xts(twofish)", + .cra_driver_name = "xts-twofish-avx", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = TF_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(twofish_algs[9].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = TF_MIN_KEY_SIZE * 2, + .max_keysize = TF_MAX_KEY_SIZE * 2, + .ivsize = TF_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +} }; + +static int __init twofish_init(void) +{ + u64 xcr0; + + if (!cpu_has_avx || !cpu_has_osxsave) { + printk(KERN_INFO "AVX instructions are not detected.\n"); + return -ENODEV; + } + + xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); + if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) { + printk(KERN_INFO "AVX detected but unusable.\n"); + return -ENODEV; + } + + return crypto_register_algs(twofish_algs, ARRAY_SIZE(twofish_algs)); +} + +static void __exit twofish_exit(void) +{ + crypto_unregister_algs(twofish_algs, ARRAY_SIZE(twofish_algs)); +} + +module_init(twofish_init); +module_exit(twofish_exit); + +MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX optimized"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("twofish"); diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index 922ab24cce31..77e4e55a2660 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c @@ -45,8 +45,10 @@ asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, /* 3-way parallel cipher functions */ asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, const u8 *src, bool xor); +EXPORT_SYMBOL_GPL(__twofish_enc_blk_3way); asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, const u8 *src); +EXPORT_SYMBOL_GPL(twofish_dec_blk_3way); static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, const u8 *src) diff --git a/crypto/Kconfig b/crypto/Kconfig index 8e84225c096b..e00a4e49e013 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -913,6 +913,30 @@ config CRYPTO_TWOFISH_X86_64_3WAY See also: +config CRYPTO_TWOFISH_AVX_X86_64 + tristate "Twofish cipher algorithm (x86_64/AVX)" + depends on X86 && 64BIT + select CRYPTO_ALGAPI + select CRYPTO_CRYPTD + select CRYPTO_TWOFISH_COMMON + select CRYPTO_TWOFISH_X86_64 + select CRYPTO_TWOFISH_X86_64_3WAY + select CRYPTO_LRW + select CRYPTO_XTS + help + Twofish cipher algorithm (x86_64/AVX). + + Twofish was submitted as an AES (Advanced Encryption Standard) + candidate cipher by researchers at CounterPane Systems. It is a + 16 round block cipher supporting key sizes of 128, 192, and 256 + bits. + + This module provides the Twofish cipher algorithm that processes + eight blocks parallel using the AVX Instruction Set. + + See also: + + comment "Compression" config CRYPTO_DEFLATE diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 750cce44bad6..2af879786e75 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1566,6 +1566,29 @@ static int do_test(int m) speed_template_32_64); break; + case 504: + test_acipher_speed("ecb(twofish)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("ecb(twofish)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("cbc(twofish)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("ctr(twofish)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("ctr(twofish)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("lrw(twofish)", ENCRYPT, sec, NULL, 0, + speed_template_32_40_48); + test_acipher_speed("lrw(twofish)", DECRYPT, sec, NULL, 0, + speed_template_32_40_48); + test_acipher_speed("xts(twofish)", ENCRYPT, sec, NULL, 0, + speed_template_32_48_64); + test_acipher_speed("xts(twofish)", DECRYPT, sec, NULL, 0, + speed_template_32_48_64); + break; + case 1000: test_available(); break; diff --git a/crypto/testmgr.c b/crypto/testmgr.c index eb6d20f8ec5d..73b3ec6fe1a2 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1548,6 +1548,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "__cbc-twofish-avx", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "__driver-cbc-aes-aesni", .test = alg_test_null, @@ -1578,6 +1593,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "__driver-cbc-twofish-avx", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "__driver-ecb-aes-aesni", .test = alg_test_null, @@ -1608,6 +1638,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "__driver-ecb-twofish-avx", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "__ghash-pclmulqdqni", .test = alg_test_null, @@ -1805,6 +1850,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "cryptd(__driver-ecb-twofish-avx)", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "cryptd(__ghash-pclmulqdqni)", .test = alg_test_null, -- GitLab From 4da7de4d8be7d18559c56bca446b1161a3b63acc Mon Sep 17 00:00:00 2001 From: Johannes Goetzfried Date: Mon, 28 May 2012 15:55:38 +0200 Subject: [PATCH 1234/6849] crypto: testmgr - expand twofish test vectors The AVX implementation of the twofish cipher processes 8 blocks parallel, so we need to make test vectors larger to check parallel code paths. Test vectors are also large enough to deal with 16 block parallel implementations which may occur in the future. Signed-off-by: Johannes Goetzfried Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- crypto/testmgr.h | 928 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 896 insertions(+), 32 deletions(-) diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 34a9d511deef..4d84fe48df08 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -2765,8 +2765,62 @@ static struct cipher_testvec tf_enc_tv_template[] = { "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" - "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", - .ilen = 64, + "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7", + .ilen = 496, .result = "\x88\xCB\x1E\xC2\xAF\x8A\x97\xFF" "\xF6\x90\x46\x9C\x4A\x0F\x08\xDC" "\xDE\xAB\xAD\xFA\xFC\xA8\xC2\x3D" @@ -2774,8 +2828,62 @@ static struct cipher_testvec tf_enc_tv_template[] = { "\x34\x9E\xB6\x08\xB2\xDD\xA8\xF5" "\xDF\xFA\xC7\xE8\x09\x50\x76\x08" "\xA2\xB6\x6A\x59\xC0\x2B\x6D\x05" - "\x89\xF6\x82\xF0\xD3\xDB\x06\x02", - .rlen = 64, + "\x89\xF6\x82\xF0\xD3\xDB\x06\x02" + "\xB5\x11\x5C\x5E\x79\x1A\xAC\x43" + "\x5C\xC0\x30\x4B\x6B\x16\xA1\x40" + "\x80\x27\x88\xBA\x2C\x74\x42\xE0" + "\x1B\xA5\x85\x08\xB9\xE6\x22\x7A" + "\x36\x3B\x0D\x9F\xA0\x22\x6C\x2A" + "\x91\x75\x47\xBC\x67\x21\x4E\xF9" + "\xEA\xFF\xD9\xD5\xC0\xFC\x9E\x2C" + "\x3E\xAD\xC6\x61\x0E\x93\x7A\x22" + "\x09\xC8\x8D\xC1\x8E\xB4\x8B\x5C" + "\xC6\x24\x42\xB8\x23\x66\x80\xA9" + "\x32\x0B\x7A\x29\xBF\xB3\x0B\x63" + "\x43\x27\x13\xA9\xBE\xEB\xBD\xF3" + "\x33\x62\x70\xE2\x1B\x86\x7A\xA1" + "\x51\x4A\x16\xFE\x29\x63\x7E\xD0" + "\x7A\xA4\x6E\x2C\xF8\xC1\xDB\xE8" + "\xCB\x4D\xD2\x8C\x04\x14\xB4\x66" + "\x41\xB7\x3A\x96\x16\x7C\x1D\x5B" + "\xB6\x41\x42\x64\x43\xEE\x6E\x7C" + "\x8B\xAF\x01\x9C\xA4\x6E\x75\x8F" + "\xDE\x10\x9F\xA6\xE7\xD6\x44\x97" + "\x66\xA3\x96\x0F\x1C\x25\x60\xF5" + "\x3C\x2E\x32\x69\x0E\x82\xFF\x27" + "\x0F\xB5\x06\xDA\xD8\x31\x15\x6C" + "\xDF\x18\x6C\x87\xF5\x3B\x11\x9A" + "\x1B\x42\x1F\x5B\x29\x19\x96\x13" + "\x68\x2E\x5E\x08\x1C\x8F\x32\x4B" + "\x81\x77\x6D\xF4\xA0\x01\x42\xEC" + "\xDD\x5B\xFD\x3A\x8E\x6A\x14\xFB" + "\x83\x54\xDF\x0F\x86\xB7\xEA\x40" + "\x46\x39\xF7\x2A\x89\x8D\x4E\x96" + "\x5F\x5F\x6D\x76\xC6\x13\x9D\x3D" + "\x1D\x5F\x0C\x7D\xE2\xBC\xC2\x16" + "\x16\xBE\x89\x3E\xB0\x61\xA2\x5D" + "\xAF\xD1\x40\x5F\x1A\xB8\x26\x41" + "\xC6\xBD\x36\xEF\xED\x29\x50\x6D" + "\x10\xEF\x26\xE8\xA8\x93\x11\x3F" + "\x2D\x1F\x88\x20\x77\x45\xF5\x66" + "\x08\xB9\xF1\xEF\xB1\x93\xA8\x81" + "\x65\xC5\xCD\x3E\x8C\x06\x60\x2C" + "\xB2\x10\x7A\xCA\x05\x25\x59\xDB" + "\xC7\x28\xF5\x20\x35\x52\x9E\x62" + "\xF8\x88\x24\x1C\x4D\x84\x12\x39" + "\x39\xE4\x2E\xF4\xD4\x9D\x2B\xBC" + "\x87\x66\xE6\xC0\x6B\x31\x9A\x66" + "\x03\xDC\x95\xD8\x6B\xD0\x30\x8F" + "\xDF\x8F\x8D\xFA\xEC\x1F\x08\xBD" + "\xA3\x63\xE2\x71\x4F\x03\x94\x87" + "\x50\xDF\x15\x1F\xED\x3A\xA3\x7F" + "\x1F\x2A\xB5\xA1\x69\xAC\x4B\x0D" + "\x84\x9B\x2A\xE9\x55\xDD\x46\x91" + "\x15\x33\xF3\x2B\x9B\x46\x97\x00" + "\xF0\x29\xD8\x59\x5D\x33\x37\xF9" + "\x58\x33\x9B\x78\xC7\x58\x48\x6B" + "\x2C\x75\x64\xC4\xCA\xC1\x7E\xD5", + .rlen = 496, }, }; @@ -2822,8 +2930,62 @@ static struct cipher_testvec tf_dec_tv_template[] = { "\x34\x9E\xB6\x08\xB2\xDD\xA8\xF5" "\xDF\xFA\xC7\xE8\x09\x50\x76\x08" "\xA2\xB6\x6A\x59\xC0\x2B\x6D\x05" - "\x89\xF6\x82\xF0\xD3\xDB\x06\x02", - .ilen = 64, + "\x89\xF6\x82\xF0\xD3\xDB\x06\x02" + "\xB5\x11\x5C\x5E\x79\x1A\xAC\x43" + "\x5C\xC0\x30\x4B\x6B\x16\xA1\x40" + "\x80\x27\x88\xBA\x2C\x74\x42\xE0" + "\x1B\xA5\x85\x08\xB9\xE6\x22\x7A" + "\x36\x3B\x0D\x9F\xA0\x22\x6C\x2A" + "\x91\x75\x47\xBC\x67\x21\x4E\xF9" + "\xEA\xFF\xD9\xD5\xC0\xFC\x9E\x2C" + "\x3E\xAD\xC6\x61\x0E\x93\x7A\x22" + "\x09\xC8\x8D\xC1\x8E\xB4\x8B\x5C" + "\xC6\x24\x42\xB8\x23\x66\x80\xA9" + "\x32\x0B\x7A\x29\xBF\xB3\x0B\x63" + "\x43\x27\x13\xA9\xBE\xEB\xBD\xF3" + "\x33\x62\x70\xE2\x1B\x86\x7A\xA1" + "\x51\x4A\x16\xFE\x29\x63\x7E\xD0" + "\x7A\xA4\x6E\x2C\xF8\xC1\xDB\xE8" + "\xCB\x4D\xD2\x8C\x04\x14\xB4\x66" + "\x41\xB7\x3A\x96\x16\x7C\x1D\x5B" + "\xB6\x41\x42\x64\x43\xEE\x6E\x7C" + "\x8B\xAF\x01\x9C\xA4\x6E\x75\x8F" + "\xDE\x10\x9F\xA6\xE7\xD6\x44\x97" + "\x66\xA3\x96\x0F\x1C\x25\x60\xF5" + "\x3C\x2E\x32\x69\x0E\x82\xFF\x27" + "\x0F\xB5\x06\xDA\xD8\x31\x15\x6C" + "\xDF\x18\x6C\x87\xF5\x3B\x11\x9A" + "\x1B\x42\x1F\x5B\x29\x19\x96\x13" + "\x68\x2E\x5E\x08\x1C\x8F\x32\x4B" + "\x81\x77\x6D\xF4\xA0\x01\x42\xEC" + "\xDD\x5B\xFD\x3A\x8E\x6A\x14\xFB" + "\x83\x54\xDF\x0F\x86\xB7\xEA\x40" + "\x46\x39\xF7\x2A\x89\x8D\x4E\x96" + "\x5F\x5F\x6D\x76\xC6\x13\x9D\x3D" + "\x1D\x5F\x0C\x7D\xE2\xBC\xC2\x16" + "\x16\xBE\x89\x3E\xB0\x61\xA2\x5D" + "\xAF\xD1\x40\x5F\x1A\xB8\x26\x41" + "\xC6\xBD\x36\xEF\xED\x29\x50\x6D" + "\x10\xEF\x26\xE8\xA8\x93\x11\x3F" + "\x2D\x1F\x88\x20\x77\x45\xF5\x66" + "\x08\xB9\xF1\xEF\xB1\x93\xA8\x81" + "\x65\xC5\xCD\x3E\x8C\x06\x60\x2C" + "\xB2\x10\x7A\xCA\x05\x25\x59\xDB" + "\xC7\x28\xF5\x20\x35\x52\x9E\x62" + "\xF8\x88\x24\x1C\x4D\x84\x12\x39" + "\x39\xE4\x2E\xF4\xD4\x9D\x2B\xBC" + "\x87\x66\xE6\xC0\x6B\x31\x9A\x66" + "\x03\xDC\x95\xD8\x6B\xD0\x30\x8F" + "\xDF\x8F\x8D\xFA\xEC\x1F\x08\xBD" + "\xA3\x63\xE2\x71\x4F\x03\x94\x87" + "\x50\xDF\x15\x1F\xED\x3A\xA3\x7F" + "\x1F\x2A\xB5\xA1\x69\xAC\x4B\x0D" + "\x84\x9B\x2A\xE9\x55\xDD\x46\x91" + "\x15\x33\xF3\x2B\x9B\x46\x97\x00" + "\xF0\x29\xD8\x59\x5D\x33\x37\xF9" + "\x58\x33\x9B\x78\xC7\x58\x48\x6B" + "\x2C\x75\x64\xC4\xCA\xC1\x7E\xD5", + .ilen = 496, .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" @@ -2831,8 +2993,62 @@ static struct cipher_testvec tf_dec_tv_template[] = { "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" - "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", - .rlen = 64, + "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7", + .rlen = 496, }, }; @@ -2894,8 +3110,62 @@ static struct cipher_testvec tf_cbc_enc_tv_template[] = { "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" - "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", - .ilen = 64, + "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7", + .ilen = 496, .result = "\xC8\xFF\xF2\x53\xA6\x27\x09\xD1" "\x33\x38\xC2\xC0\x0C\x14\x7E\xB5" "\x26\x1B\x05\x0C\x05\x12\x3F\xC0" @@ -2903,8 +3173,62 @@ static struct cipher_testvec tf_cbc_enc_tv_template[] = { "\x3D\x32\xDF\xDA\x56\x00\x6E\xEE" "\x5B\x2A\x72\x9D\xC2\x4D\x19\xBC" "\x8C\x53\xFA\x87\x6F\xDD\x81\xA3" - "\xB1\xD3\x44\x65\xDF\xE7\x63\x38", - .rlen = 64, + "\xB1\xD3\x44\x65\xDF\xE7\x63\x38" + "\x4A\xFC\xDC\xEC\x3F\x26\x8E\xB8" + "\x43\xFC\xFE\x18\xB5\x11\x6D\x31" + "\x81\x8B\x0D\x75\xF6\x80\xEC\x84" + "\x04\xB9\xE6\x09\x63\xED\x39\xDB" + "\xC3\xF6\x14\xD6\x6E\x5E\x8B\xBD" + "\x3E\xFA\xD7\x98\x50\x6F\xD9\x63" + "\x02\xCD\x0D\x39\x4B\x0D\xEC\x80" + "\xE3\x6A\x17\xF4\xCC\xAD\xFF\x68" + "\x45\xDD\xC8\x83\x1D\x41\x96\x0D" + "\x91\x2E\x05\xD3\x59\x82\xE0\x43" + "\x90\x4F\xB9\xF7\xAD\x6B\x2E\xAF" + "\xA7\x84\x00\x53\xCD\x6F\xD1\x0C" + "\x4E\xF9\x5A\x23\xFB\xCA\xC7\xD3" + "\xA9\xAA\x9D\xB2\x3F\x66\xF1\xAC" + "\x25\x21\x8F\xF7\xEF\xF2\x6A\xDF" + "\xE8\xDA\x75\x1A\x8A\xF1\xDD\x38" + "\x1F\xF9\x3D\x68\x4A\xBB\x9E\x34" + "\x1F\x66\x1F\x9C\x2B\x54\xFF\x60" + "\x7F\x29\x4B\x55\x80\x8F\x4E\xA7" + "\xA6\x9A\x0A\xD9\x0D\x19\x00\xF8" + "\x1F\xBC\x0C\x40\x6B\xEC\x99\x25" + "\x94\x70\x74\x0E\x1D\xC5\xBC\x12" + "\xF3\x42\xBE\x95\xBF\xFB\x4E\x55" + "\x9A\xB9\xCE\x14\x16\x5B\xDC\xD3" + "\x75\x42\x62\x04\x31\x1F\x95\x7C" + "\x66\x1A\x97\xDC\x2F\x40\x5C\x39" + "\x78\xE6\x02\xDB\x49\xE1\xC6\x47" + "\xC2\x78\x9A\xBB\xF3\xBE\xCB\x93" + "\xD8\xB8\xE8\xBB\x8C\xB3\x9B\xA7" + "\xC2\x89\xF3\x91\x88\x83\x3D\xF0" + "\x29\xA2\xCD\xB5\x79\x16\xC2\x40" + "\x11\x03\x8E\x9C\xFD\xC9\x43\xC4" + "\xC2\x19\xF0\x4A\x32\xEF\x0C\x2B" + "\xD3\x2B\xE9\xD4\x4C\xDE\x95\xCF" + "\x04\x03\xD3\x2C\x7F\x82\xC8\xFA" + "\x0F\xD8\x7A\x39\x7B\x01\x41\x9C" + "\x78\xB6\xC9\xBF\xF9\x78\x57\x88" + "\xB1\xA5\xE1\xE0\xD9\x16\xD4\xC8" + "\xEE\xC4\xBE\x7B\x55\x59\x00\x48" + "\x1B\xBC\x14\xFA\x2A\x9D\xC9\x1C" + "\xFB\x28\x3F\x95\xDD\xB7\xD6\xCE" + "\x3A\x7F\x09\x0C\x0E\x69\x30\x7D" + "\xBC\x68\x9C\x91\x2A\x59\x57\x04" + "\xED\x1A\x1E\x00\xB1\x85\x92\x04" + "\x28\x8C\x0C\x3C\xC1\xD5\x12\xF7" + "\x4C\x3E\xB0\xE7\x86\x62\x68\x91" + "\xFC\xC4\xE2\xCE\xA6\xDC\x5E\x93" + "\x5D\x8D\x8C\x68\xB3\xB2\xB9\x64" + "\x16\xB8\xC8\x6F\xD8\xEE\x21\xBD" + "\xAC\x18\x0C\x7D\x0D\x05\xAB\xF1" + "\xFA\xDD\xE2\x48\xDF\x4C\x02\x39" + "\x69\xA1\x62\xBD\x49\x3A\x9D\x91" + "\x30\x70\x56\xA4\x37\xDD\x7C\xC0" + "\x0A\xA3\x30\x10\x26\x25\x41\x2C", + .rlen = 496, }, }; @@ -2966,8 +3290,62 @@ static struct cipher_testvec tf_cbc_dec_tv_template[] = { "\x3D\x32\xDF\xDA\x56\x00\x6E\xEE" "\x5B\x2A\x72\x9D\xC2\x4D\x19\xBC" "\x8C\x53\xFA\x87\x6F\xDD\x81\xA3" - "\xB1\xD3\x44\x65\xDF\xE7\x63\x38", - .ilen = 64, + "\xB1\xD3\x44\x65\xDF\xE7\x63\x38" + "\x4A\xFC\xDC\xEC\x3F\x26\x8E\xB8" + "\x43\xFC\xFE\x18\xB5\x11\x6D\x31" + "\x81\x8B\x0D\x75\xF6\x80\xEC\x84" + "\x04\xB9\xE6\x09\x63\xED\x39\xDB" + "\xC3\xF6\x14\xD6\x6E\x5E\x8B\xBD" + "\x3E\xFA\xD7\x98\x50\x6F\xD9\x63" + "\x02\xCD\x0D\x39\x4B\x0D\xEC\x80" + "\xE3\x6A\x17\xF4\xCC\xAD\xFF\x68" + "\x45\xDD\xC8\x83\x1D\x41\x96\x0D" + "\x91\x2E\x05\xD3\x59\x82\xE0\x43" + "\x90\x4F\xB9\xF7\xAD\x6B\x2E\xAF" + "\xA7\x84\x00\x53\xCD\x6F\xD1\x0C" + "\x4E\xF9\x5A\x23\xFB\xCA\xC7\xD3" + "\xA9\xAA\x9D\xB2\x3F\x66\xF1\xAC" + "\x25\x21\x8F\xF7\xEF\xF2\x6A\xDF" + "\xE8\xDA\x75\x1A\x8A\xF1\xDD\x38" + "\x1F\xF9\x3D\x68\x4A\xBB\x9E\x34" + "\x1F\x66\x1F\x9C\x2B\x54\xFF\x60" + "\x7F\x29\x4B\x55\x80\x8F\x4E\xA7" + "\xA6\x9A\x0A\xD9\x0D\x19\x00\xF8" + "\x1F\xBC\x0C\x40\x6B\xEC\x99\x25" + "\x94\x70\x74\x0E\x1D\xC5\xBC\x12" + "\xF3\x42\xBE\x95\xBF\xFB\x4E\x55" + "\x9A\xB9\xCE\x14\x16\x5B\xDC\xD3" + "\x75\x42\x62\x04\x31\x1F\x95\x7C" + "\x66\x1A\x97\xDC\x2F\x40\x5C\x39" + "\x78\xE6\x02\xDB\x49\xE1\xC6\x47" + "\xC2\x78\x9A\xBB\xF3\xBE\xCB\x93" + "\xD8\xB8\xE8\xBB\x8C\xB3\x9B\xA7" + "\xC2\x89\xF3\x91\x88\x83\x3D\xF0" + "\x29\xA2\xCD\xB5\x79\x16\xC2\x40" + "\x11\x03\x8E\x9C\xFD\xC9\x43\xC4" + "\xC2\x19\xF0\x4A\x32\xEF\x0C\x2B" + "\xD3\x2B\xE9\xD4\x4C\xDE\x95\xCF" + "\x04\x03\xD3\x2C\x7F\x82\xC8\xFA" + "\x0F\xD8\x7A\x39\x7B\x01\x41\x9C" + "\x78\xB6\xC9\xBF\xF9\x78\x57\x88" + "\xB1\xA5\xE1\xE0\xD9\x16\xD4\xC8" + "\xEE\xC4\xBE\x7B\x55\x59\x00\x48" + "\x1B\xBC\x14\xFA\x2A\x9D\xC9\x1C" + "\xFB\x28\x3F\x95\xDD\xB7\xD6\xCE" + "\x3A\x7F\x09\x0C\x0E\x69\x30\x7D" + "\xBC\x68\x9C\x91\x2A\x59\x57\x04" + "\xED\x1A\x1E\x00\xB1\x85\x92\x04" + "\x28\x8C\x0C\x3C\xC1\xD5\x12\xF7" + "\x4C\x3E\xB0\xE7\x86\x62\x68\x91" + "\xFC\xC4\xE2\xCE\xA6\xDC\x5E\x93" + "\x5D\x8D\x8C\x68\xB3\xB2\xB9\x64" + "\x16\xB8\xC8\x6F\xD8\xEE\x21\xBD" + "\xAC\x18\x0C\x7D\x0D\x05\xAB\xF1" + "\xFA\xDD\xE2\x48\xDF\x4C\x02\x39" + "\x69\xA1\x62\xBD\x49\x3A\x9D\x91" + "\x30\x70\x56\xA4\x37\xDD\x7C\xC0" + "\x0A\xA3\x30\x10\x26\x25\x41\x2C", + .ilen = 496, .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" @@ -2975,8 +3353,62 @@ static struct cipher_testvec tf_cbc_dec_tv_template[] = { "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" - "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", - .rlen = 64, + "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7", + .rlen = 496, }, }; @@ -2996,8 +3428,62 @@ static struct cipher_testvec tf_ctr_enc_tv_template[] = { "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" - "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", - .ilen = 64, + "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7", + .ilen = 496, .result = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE" "\x70\x9E\xC5\x4B\xC9\xD4\xA1\x30" "\x26\x9B\x89\xA1\xEE\x43\xE0\x52" @@ -3005,8 +3491,62 @@ static struct cipher_testvec tf_ctr_enc_tv_template[] = { "\x9F\x8D\x40\x9F\x24\xFD\x92\xA0" "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" - "\x01\x41\x21\x12\x38\xAB\x52\x4F", - .rlen = 64, + "\x01\x41\x21\x12\x38\xAB\x52\x4F" + "\xA8\x57\x20\xE0\x21\x6A\x17\x0D" + "\x0E\xF9\x8E\x49\x42\x00\x3C\x94" + "\x14\xC0\xD0\x8D\x8A\x98\xEB\x29" + "\xEC\xAE\x96\x44\xC0\x3C\x48\xDC" + "\x29\x35\x25\x2F\xE7\x11\x6C\x68" + "\xC8\x67\x0A\x2F\xF4\x07\xBE\xF9" + "\x2C\x31\x87\x40\xAB\xB2\xB6\xFA" + "\xD2\xC9\x6D\x5C\x50\xE9\xE6\x7E" + "\xE3\x0A\xD2\xD5\x6D\x8D\x64\x9E" + "\x70\xCE\x03\x76\xDD\xE0\xF0\x8C" + "\x84\x86\x8B\x6A\xFE\xC7\xF9\x69" + "\x2E\xFE\xFC\xC2\xC4\x1A\x55\x58" + "\xB3\xBE\xE2\x7E\xED\x39\x42\x6C" + "\xB4\x42\x97\x9A\xEC\xE1\x0A\x06" + "\x02\xC5\x03\x9D\xC4\x48\x15\x66" + "\x35\x6A\xC2\xC9\xA2\x26\x30\xBB" + "\xDB\x2D\xC8\x08\x2B\xA0\x29\x1A" + "\x23\x61\x48\xEA\x80\x04\x27\xAA" + "\x69\x49\xE8\xE8\x4A\x83\x6B\x5A" + "\xCA\x7C\xD3\xB1\xB5\x0B\xCC\x23" + "\x74\x1F\xA9\x87\xCD\xED\xC0\x2D" + "\xBF\xEB\xCF\x16\x2D\x2A\x2E\x1D" + "\x96\xBA\x36\x11\x45\x41\xDA\xCE" + "\xA4\x48\x80\x8B\x06\xF4\x98\x89" + "\x8B\x23\x08\x53\xF4\xD4\x5A\x24" + "\x8B\xF8\x43\x73\xD1\xEE\xC4\xB0" + "\xF8\xFE\x09\x0C\x75\x05\x38\x0B" + "\x7C\x81\xDE\x9D\xE4\x61\x37\x63" + "\x63\xAD\x12\xD2\x04\xB9\xCE\x45" + "\x5A\x1A\x6E\xB3\x78\x2A\xA4\x74" + "\x86\xD0\xE3\xFF\xDA\x38\x9C\xB5" + "\xB8\xB1\xDB\x38\x2F\xC5\x6A\xB4" + "\xEB\x6E\x96\xE8\x43\x80\xB5\x51" + "\x61\x2D\x48\xAA\x07\x65\x11\x8C" + "\x48\xE3\x90\x7E\x78\x3A\xEC\x97" + "\x05\x3D\x84\xE7\x90\x2B\xAA\xBD" + "\x83\x29\x0E\x1A\x81\x73\x7B\xE0" + "\x7A\x01\x4A\x37\x3B\x77\x7F\x8D" + "\x49\xA4\x2F\x6E\xBE\x68\x99\x08" + "\x99\xAA\x4C\x12\x04\xAE\x1F\x77" + "\x35\x88\xF1\x65\x06\x0A\x0B\x4D" + "\x47\xF9\x50\x38\x5D\x71\xF9\x6E" + "\xDE\xEC\x61\x35\x2C\x4C\x96\x50" + "\xE8\x28\x93\x9C\x7E\x01\xC6\x04" + "\xB2\xD6\xBC\x6C\x17\xEB\xC1\x7D" + "\x11\xE9\x43\x83\x76\xAA\x53\x37" + "\x0C\x1D\x39\x89\x53\x72\x09\x7E" + "\xD9\x85\x16\x04\xA5\x2C\x05\x6F" + "\x17\x0C\x6E\x66\xAA\x84\xA7\xD9" + "\xE2\xD9\xC4\xEB\x43\x3E\xB1\x8D" + "\x7C\x36\xC7\x71\x70\x9C\x10\xD8" + "\xE8\x47\x2A\x4D\xFD\xA1\xBC\xE3" + "\xB9\x32\xE2\xC1\x82\xAC\xFE\xCC" + "\xC5\xC9\x7F\x9E\xCF\x33\x7A\xDF", + .rlen = 496, }, { /* Generated with Crypto++ */ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" @@ -3023,8 +3563,62 @@ static struct cipher_testvec tf_ctr_enc_tv_template[] = { "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" - "\xC3\x37\xCE", - .ilen = 67, + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7" + "\x2B\xC2\x59", + .ilen = 499, .result = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE" "\x70\x9E\xC5\x4B\xC9\xD4\xA1\x30" "\x26\x9B\x89\xA1\xEE\x43\xE0\x52" @@ -3033,8 +3627,62 @@ static struct cipher_testvec tf_ctr_enc_tv_template[] = { "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" "\x01\x41\x21\x12\x38\xAB\x52\x4F" - "\xA8\x57\x20", - .rlen = 67, + "\xA8\x57\x20\xE0\x21\x6A\x17\x0D" + "\x0E\xF9\x8E\x49\x42\x00\x3C\x94" + "\x14\xC0\xD0\x8D\x8A\x98\xEB\x29" + "\xEC\xAE\x96\x44\xC0\x3C\x48\xDC" + "\x29\x35\x25\x2F\xE7\x11\x6C\x68" + "\xC8\x67\x0A\x2F\xF4\x07\xBE\xF9" + "\x2C\x31\x87\x40\xAB\xB2\xB6\xFA" + "\xD2\xC9\x6D\x5C\x50\xE9\xE6\x7E" + "\xE3\x0A\xD2\xD5\x6D\x8D\x64\x9E" + "\x70\xCE\x03\x76\xDD\xE0\xF0\x8C" + "\x84\x86\x8B\x6A\xFE\xC7\xF9\x69" + "\x2E\xFE\xFC\xC2\xC4\x1A\x55\x58" + "\xB3\xBE\xE2\x7E\xED\x39\x42\x6C" + "\xB4\x42\x97\x9A\xEC\xE1\x0A\x06" + "\x02\xC5\x03\x9D\xC4\x48\x15\x66" + "\x35\x6A\xC2\xC9\xA2\x26\x30\xBB" + "\xDB\x2D\xC8\x08\x2B\xA0\x29\x1A" + "\x23\x61\x48\xEA\x80\x04\x27\xAA" + "\x69\x49\xE8\xE8\x4A\x83\x6B\x5A" + "\xCA\x7C\xD3\xB1\xB5\x0B\xCC\x23" + "\x74\x1F\xA9\x87\xCD\xED\xC0\x2D" + "\xBF\xEB\xCF\x16\x2D\x2A\x2E\x1D" + "\x96\xBA\x36\x11\x45\x41\xDA\xCE" + "\xA4\x48\x80\x8B\x06\xF4\x98\x89" + "\x8B\x23\x08\x53\xF4\xD4\x5A\x24" + "\x8B\xF8\x43\x73\xD1\xEE\xC4\xB0" + "\xF8\xFE\x09\x0C\x75\x05\x38\x0B" + "\x7C\x81\xDE\x9D\xE4\x61\x37\x63" + "\x63\xAD\x12\xD2\x04\xB9\xCE\x45" + "\x5A\x1A\x6E\xB3\x78\x2A\xA4\x74" + "\x86\xD0\xE3\xFF\xDA\x38\x9C\xB5" + "\xB8\xB1\xDB\x38\x2F\xC5\x6A\xB4" + "\xEB\x6E\x96\xE8\x43\x80\xB5\x51" + "\x61\x2D\x48\xAA\x07\x65\x11\x8C" + "\x48\xE3\x90\x7E\x78\x3A\xEC\x97" + "\x05\x3D\x84\xE7\x90\x2B\xAA\xBD" + "\x83\x29\x0E\x1A\x81\x73\x7B\xE0" + "\x7A\x01\x4A\x37\x3B\x77\x7F\x8D" + "\x49\xA4\x2F\x6E\xBE\x68\x99\x08" + "\x99\xAA\x4C\x12\x04\xAE\x1F\x77" + "\x35\x88\xF1\x65\x06\x0A\x0B\x4D" + "\x47\xF9\x50\x38\x5D\x71\xF9\x6E" + "\xDE\xEC\x61\x35\x2C\x4C\x96\x50" + "\xE8\x28\x93\x9C\x7E\x01\xC6\x04" + "\xB2\xD6\xBC\x6C\x17\xEB\xC1\x7D" + "\x11\xE9\x43\x83\x76\xAA\x53\x37" + "\x0C\x1D\x39\x89\x53\x72\x09\x7E" + "\xD9\x85\x16\x04\xA5\x2C\x05\x6F" + "\x17\x0C\x6E\x66\xAA\x84\xA7\xD9" + "\xE2\xD9\xC4\xEB\x43\x3E\xB1\x8D" + "\x7C\x36\xC7\x71\x70\x9C\x10\xD8" + "\xE8\x47\x2A\x4D\xFD\xA1\xBC\xE3" + "\xB9\x32\xE2\xC1\x82\xAC\xFE\xCC" + "\xC5\xC9\x7F\x9E\xCF\x33\x7A\xDF" + "\x6C\x82\x9D", + .rlen = 499, }, }; @@ -3054,8 +3702,62 @@ static struct cipher_testvec tf_ctr_dec_tv_template[] = { "\x9F\x8D\x40\x9F\x24\xFD\x92\xA0" "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" - "\x01\x41\x21\x12\x38\xAB\x52\x4F", - .ilen = 64, + "\x01\x41\x21\x12\x38\xAB\x52\x4F" + "\xA8\x57\x20\xE0\x21\x6A\x17\x0D" + "\x0E\xF9\x8E\x49\x42\x00\x3C\x94" + "\x14\xC0\xD0\x8D\x8A\x98\xEB\x29" + "\xEC\xAE\x96\x44\xC0\x3C\x48\xDC" + "\x29\x35\x25\x2F\xE7\x11\x6C\x68" + "\xC8\x67\x0A\x2F\xF4\x07\xBE\xF9" + "\x2C\x31\x87\x40\xAB\xB2\xB6\xFA" + "\xD2\xC9\x6D\x5C\x50\xE9\xE6\x7E" + "\xE3\x0A\xD2\xD5\x6D\x8D\x64\x9E" + "\x70\xCE\x03\x76\xDD\xE0\xF0\x8C" + "\x84\x86\x8B\x6A\xFE\xC7\xF9\x69" + "\x2E\xFE\xFC\xC2\xC4\x1A\x55\x58" + "\xB3\xBE\xE2\x7E\xED\x39\x42\x6C" + "\xB4\x42\x97\x9A\xEC\xE1\x0A\x06" + "\x02\xC5\x03\x9D\xC4\x48\x15\x66" + "\x35\x6A\xC2\xC9\xA2\x26\x30\xBB" + "\xDB\x2D\xC8\x08\x2B\xA0\x29\x1A" + "\x23\x61\x48\xEA\x80\x04\x27\xAA" + "\x69\x49\xE8\xE8\x4A\x83\x6B\x5A" + "\xCA\x7C\xD3\xB1\xB5\x0B\xCC\x23" + "\x74\x1F\xA9\x87\xCD\xED\xC0\x2D" + "\xBF\xEB\xCF\x16\x2D\x2A\x2E\x1D" + "\x96\xBA\x36\x11\x45\x41\xDA\xCE" + "\xA4\x48\x80\x8B\x06\xF4\x98\x89" + "\x8B\x23\x08\x53\xF4\xD4\x5A\x24" + "\x8B\xF8\x43\x73\xD1\xEE\xC4\xB0" + "\xF8\xFE\x09\x0C\x75\x05\x38\x0B" + "\x7C\x81\xDE\x9D\xE4\x61\x37\x63" + "\x63\xAD\x12\xD2\x04\xB9\xCE\x45" + "\x5A\x1A\x6E\xB3\x78\x2A\xA4\x74" + "\x86\xD0\xE3\xFF\xDA\x38\x9C\xB5" + "\xB8\xB1\xDB\x38\x2F\xC5\x6A\xB4" + "\xEB\x6E\x96\xE8\x43\x80\xB5\x51" + "\x61\x2D\x48\xAA\x07\x65\x11\x8C" + "\x48\xE3\x90\x7E\x78\x3A\xEC\x97" + "\x05\x3D\x84\xE7\x90\x2B\xAA\xBD" + "\x83\x29\x0E\x1A\x81\x73\x7B\xE0" + "\x7A\x01\x4A\x37\x3B\x77\x7F\x8D" + "\x49\xA4\x2F\x6E\xBE\x68\x99\x08" + "\x99\xAA\x4C\x12\x04\xAE\x1F\x77" + "\x35\x88\xF1\x65\x06\x0A\x0B\x4D" + "\x47\xF9\x50\x38\x5D\x71\xF9\x6E" + "\xDE\xEC\x61\x35\x2C\x4C\x96\x50" + "\xE8\x28\x93\x9C\x7E\x01\xC6\x04" + "\xB2\xD6\xBC\x6C\x17\xEB\xC1\x7D" + "\x11\xE9\x43\x83\x76\xAA\x53\x37" + "\x0C\x1D\x39\x89\x53\x72\x09\x7E" + "\xD9\x85\x16\x04\xA5\x2C\x05\x6F" + "\x17\x0C\x6E\x66\xAA\x84\xA7\xD9" + "\xE2\xD9\xC4\xEB\x43\x3E\xB1\x8D" + "\x7C\x36\xC7\x71\x70\x9C\x10\xD8" + "\xE8\x47\x2A\x4D\xFD\xA1\xBC\xE3" + "\xB9\x32\xE2\xC1\x82\xAC\xFE\xCC" + "\xC5\xC9\x7F\x9E\xCF\x33\x7A\xDF", + .ilen = 496, .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" @@ -3063,8 +3765,62 @@ static struct cipher_testvec tf_ctr_dec_tv_template[] = { "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" - "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", - .rlen = 64, + "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7", + .rlen = 496, }, { /* Generated with Crypto++ */ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" @@ -3081,8 +3837,62 @@ static struct cipher_testvec tf_ctr_dec_tv_template[] = { "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" "\x01\x41\x21\x12\x38\xAB\x52\x4F" - "\xA8\x57\x20", - .ilen = 67, + "\xA8\x57\x20\xE0\x21\x6A\x17\x0D" + "\x0E\xF9\x8E\x49\x42\x00\x3C\x94" + "\x14\xC0\xD0\x8D\x8A\x98\xEB\x29" + "\xEC\xAE\x96\x44\xC0\x3C\x48\xDC" + "\x29\x35\x25\x2F\xE7\x11\x6C\x68" + "\xC8\x67\x0A\x2F\xF4\x07\xBE\xF9" + "\x2C\x31\x87\x40\xAB\xB2\xB6\xFA" + "\xD2\xC9\x6D\x5C\x50\xE9\xE6\x7E" + "\xE3\x0A\xD2\xD5\x6D\x8D\x64\x9E" + "\x70\xCE\x03\x76\xDD\xE0\xF0\x8C" + "\x84\x86\x8B\x6A\xFE\xC7\xF9\x69" + "\x2E\xFE\xFC\xC2\xC4\x1A\x55\x58" + "\xB3\xBE\xE2\x7E\xED\x39\x42\x6C" + "\xB4\x42\x97\x9A\xEC\xE1\x0A\x06" + "\x02\xC5\x03\x9D\xC4\x48\x15\x66" + "\x35\x6A\xC2\xC9\xA2\x26\x30\xBB" + "\xDB\x2D\xC8\x08\x2B\xA0\x29\x1A" + "\x23\x61\x48\xEA\x80\x04\x27\xAA" + "\x69\x49\xE8\xE8\x4A\x83\x6B\x5A" + "\xCA\x7C\xD3\xB1\xB5\x0B\xCC\x23" + "\x74\x1F\xA9\x87\xCD\xED\xC0\x2D" + "\xBF\xEB\xCF\x16\x2D\x2A\x2E\x1D" + "\x96\xBA\x36\x11\x45\x41\xDA\xCE" + "\xA4\x48\x80\x8B\x06\xF4\x98\x89" + "\x8B\x23\x08\x53\xF4\xD4\x5A\x24" + "\x8B\xF8\x43\x73\xD1\xEE\xC4\xB0" + "\xF8\xFE\x09\x0C\x75\x05\x38\x0B" + "\x7C\x81\xDE\x9D\xE4\x61\x37\x63" + "\x63\xAD\x12\xD2\x04\xB9\xCE\x45" + "\x5A\x1A\x6E\xB3\x78\x2A\xA4\x74" + "\x86\xD0\xE3\xFF\xDA\x38\x9C\xB5" + "\xB8\xB1\xDB\x38\x2F\xC5\x6A\xB4" + "\xEB\x6E\x96\xE8\x43\x80\xB5\x51" + "\x61\x2D\x48\xAA\x07\x65\x11\x8C" + "\x48\xE3\x90\x7E\x78\x3A\xEC\x97" + "\x05\x3D\x84\xE7\x90\x2B\xAA\xBD" + "\x83\x29\x0E\x1A\x81\x73\x7B\xE0" + "\x7A\x01\x4A\x37\x3B\x77\x7F\x8D" + "\x49\xA4\x2F\x6E\xBE\x68\x99\x08" + "\x99\xAA\x4C\x12\x04\xAE\x1F\x77" + "\x35\x88\xF1\x65\x06\x0A\x0B\x4D" + "\x47\xF9\x50\x38\x5D\x71\xF9\x6E" + "\xDE\xEC\x61\x35\x2C\x4C\x96\x50" + "\xE8\x28\x93\x9C\x7E\x01\xC6\x04" + "\xB2\xD6\xBC\x6C\x17\xEB\xC1\x7D" + "\x11\xE9\x43\x83\x76\xAA\x53\x37" + "\x0C\x1D\x39\x89\x53\x72\x09\x7E" + "\xD9\x85\x16\x04\xA5\x2C\x05\x6F" + "\x17\x0C\x6E\x66\xAA\x84\xA7\xD9" + "\xE2\xD9\xC4\xEB\x43\x3E\xB1\x8D" + "\x7C\x36\xC7\x71\x70\x9C\x10\xD8" + "\xE8\x47\x2A\x4D\xFD\xA1\xBC\xE3" + "\xB9\x32\xE2\xC1\x82\xAC\xFE\xCC" + "\xC5\xC9\x7F\x9E\xCF\x33\x7A\xDF" + "\x6C\x82\x9D", + .ilen = 499, .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" @@ -3091,8 +3901,62 @@ static struct cipher_testvec tf_ctr_dec_tv_template[] = { "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" - "\xC3\x37\xCE", - .rlen = 67, + "\xC3\x37\xCE\x65\xFC\x70\x07\x9E" + "\x12\xA9\x40\xD7\x4B\xE2\x79\x10" + "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F" + "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1" + "\x68\xFF\x73\x0A\xA1\x15\xAC\x43" + "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5" + "\x29\xC0\x57\xEE\x62\xF9\x90\x04" + "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76" + "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8" + "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A" + "\xF1\x65\xFC\x93\x07\x9E\x35\xCC" + "\x40\xD7\x6E\x05\x79\x10\xA7\x1B" + "\xB2\x49\xE0\x54\xEB\x82\x19\x8D" + "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF" + "\x96\x0A\xA1\x38\xCF\x43\xDA\x71" + "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3" + "\x57\xEE\x85\x1C\x90\x27\xBE\x32" + "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4" + "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16" + "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88" + "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA" + "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49" + "\xE0\x77\x0E\x82\x19\xB0\x24\xBB" + "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D" + "\xC4\x38\xCF\x66\xFD\x71\x08\x9F" + "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11" + "\x85\x1C\xB3\x27\xBE\x55\xEC\x60" + "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2" + "\x69\x00\x74\x0B\xA2\x16\xAD\x44" + "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6" + "\x2A\xC1\x58\xEF\x63\xFA\x91\x05" + "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77" + "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9" + "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B" + "\xF2\x66\xFD\x94\x08\x9F\x36\xCD" + "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C" + "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E" + "\x25\xBC\x30\xC7\x5E\xF5\x69\x00" + "\x97\x0B\xA2\x39\xD0\x44\xDB\x72" + "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4" + "\x58\xEF\x86\x1D\x91\x28\xBF\x33" + "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5" + "\x3C\xD3\x47\xDE\x75\x0C\x80\x17" + "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89" + "\x20\x94\x2B\xC2\x36\xCD\x64\xFB" + "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A" + "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC" + "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E" + "\xC5\x39\xD0\x67\xFE\x72\x09\xA0" + "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12" + "\x86\x1D\xB4\x28\xBF\x56\xED\x61" + "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3" + "\x6A\x01\x75\x0C\xA3\x17\xAE\x45" + "\xDC\x50\xE7\x7E\x15\x89\x20\xB7" + "\x2B\xC2\x59", + .rlen = 499, }, }; -- GitLab From 7efe4076725aeb01722445b56613681aa492c8d6 Mon Sep 17 00:00:00 2001 From: Johannes Goetzfried Date: Tue, 12 Jun 2012 16:47:43 +0800 Subject: [PATCH 1235/6849] crypto: serpent - add x86_64/avx assembler implementation This patch adds a x86_64/avx assembler implementation of the Serpent block cipher. The implementation is very similar to the sse2 implementation and processes eight blocks in parallel. Because of the new non-destructive three operand syntax all move-instructions can be removed and therefore a little performance increase is provided. Patch has been tested with tcrypt and automated filesystem tests. Tcrypt benchmark results: Intel Core i5-2500 CPU (fam:6, model:42, step:7) serpent-avx-x86_64 vs. serpent-sse2-x86_64 128bit key: (lrw:256bit) (xts:256bit) size ecb-enc ecb-dec cbc-enc cbc-dec ctr-enc ctr-dec lrw-enc lrw-dec xts-enc xts-dec 16B 1.03x 1.01x 1.01x 1.01x 1.00x 1.00x 1.00x 1.00x 1.00x 1.01x 64B 1.00x 1.00x 1.00x 1.00x 1.00x 0.99x 1.00x 1.01x 1.00x 1.00x 256B 1.05x 1.03x 1.00x 1.02x 1.05x 1.06x 1.05x 1.02x 1.05x 1.02x 1024B 1.05x 1.02x 1.00x 1.02x 1.05x 1.06x 1.05x 1.03x 1.05x 1.02x 8192B 1.05x 1.02x 1.00x 1.02x 1.06x 1.06x 1.04x 1.03x 1.04x 1.02x 256bit key: (lrw:384bit) (xts:512bit) size ecb-enc ecb-dec cbc-enc cbc-dec ctr-enc ctr-dec lrw-enc lrw-dec xts-enc xts-dec 16B 1.01x 1.00x 1.01x 1.01x 1.00x 1.00x 0.99x 1.03x 1.01x 1.01x 64B 1.00x 1.00x 1.00x 1.00x 1.00x 1.00x 1.00x 1.01x 1.00x 1.02x 256B 1.05x 1.02x 1.00x 1.02x 1.05x 1.02x 1.04x 1.05x 1.05x 1.02x 1024B 1.06x 1.02x 1.00x 1.02x 1.07x 1.06x 1.05x 1.04x 1.05x 1.02x 8192B 1.05x 1.02x 1.00x 1.02x 1.06x 1.06x 1.04x 1.05x 1.05x 1.02x serpent-avx-x86_64 vs aes-asm (8kB block): 128bit 256bit ecb-enc 1.26x 1.73x ecb-dec 1.20x 1.64x cbc-enc 0.33x 0.45x cbc-dec 1.24x 1.67x ctr-enc 1.32x 1.76x ctr-dec 1.32x 1.76x lrw-enc 1.20x 1.60x lrw-dec 1.15x 1.54x xts-enc 1.22x 1.64x xts-dec 1.17x 1.57x Signed-off-by: Johannes Goetzfried Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 2 + arch/x86/crypto/serpent-avx-x86_64-asm_64.S | 704 +++++++++++++++ arch/x86/crypto/serpent_avx_glue.c | 949 ++++++++++++++++++++ crypto/Kconfig | 20 + crypto/testmgr.c | 60 ++ 5 files changed, 1735 insertions(+) create mode 100644 arch/x86/crypto/serpent-avx-x86_64-asm_64.S create mode 100644 arch/x86/crypto/serpent_avx_glue.c diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 3420feef0c70..83caa4b948c8 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o obj-$(CONFIG_CRYPTO_TWOFISH_AVX_X86_64) += twofish-avx-x86_64.o obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o +obj-$(CONFIG_CRYPTO_SERPENT_AVX_X86_64) += serpent-avx-x86_64.o obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o @@ -34,6 +35,7 @@ twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o twofish-avx-x86_64-y := twofish-avx-x86_64-asm_64.o twofish_avx_glue.o salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o +serpent-avx-x86_64-y := serpent-avx-x86_64-asm_64.o serpent_avx_glue.o aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S new file mode 100644 index 000000000000..0ed47a124bac --- /dev/null +++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S @@ -0,0 +1,704 @@ +/* + * Serpent Cipher 8-way parallel algorithm (x86_64/AVX) + * + * Copyright (C) 2012 Johannes Goetzfried + * + * + * Based on arch/x86/crypto/serpent-sse2-x86_64-asm_64.S by + * Copyright (C) 2011 Jussi Kivilinna + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +.file "serpent-avx-x86_64-asm_64.S" +.text + +#define CTX %rdi + +/********************************************************************** + 8-way AVX serpent + **********************************************************************/ +#define RA1 %xmm0 +#define RB1 %xmm1 +#define RC1 %xmm2 +#define RD1 %xmm3 +#define RE1 %xmm4 + +#define tp %xmm5 + +#define RA2 %xmm6 +#define RB2 %xmm7 +#define RC2 %xmm8 +#define RD2 %xmm9 +#define RE2 %xmm10 + +#define RNOT %xmm11 + +#define RK0 %xmm12 +#define RK1 %xmm13 +#define RK2 %xmm14 +#define RK3 %xmm15 + + +#define S0_1(x0, x1, x2, x3, x4) \ + vpor x0, x3, tp; \ + vpxor x3, x0, x0; \ + vpxor x2, x3, x4; \ + vpxor RNOT, x4, x4; \ + vpxor x1, tp, x3; \ + vpand x0, x1, x1; \ + vpxor x4, x1, x1; \ + vpxor x0, x2, x2; +#define S0_2(x0, x1, x2, x3, x4) \ + vpxor x3, x0, x0; \ + vpor x0, x4, x4; \ + vpxor x2, x0, x0; \ + vpand x1, x2, x2; \ + vpxor x2, x3, x3; \ + vpxor RNOT, x1, x1; \ + vpxor x4, x2, x2; \ + vpxor x2, x1, x1; + +#define S1_1(x0, x1, x2, x3, x4) \ + vpxor x0, x1, tp; \ + vpxor x3, x0, x0; \ + vpxor RNOT, x3, x3; \ + vpand tp, x1, x4; \ + vpor tp, x0, x0; \ + vpxor x2, x3, x3; \ + vpxor x3, x0, x0; \ + vpxor x3, tp, x1; +#define S1_2(x0, x1, x2, x3, x4) \ + vpxor x4, x3, x3; \ + vpor x4, x1, x1; \ + vpxor x2, x4, x4; \ + vpand x0, x2, x2; \ + vpxor x1, x2, x2; \ + vpor x0, x1, x1; \ + vpxor RNOT, x0, x0; \ + vpxor x2, x0, x0; \ + vpxor x1, x4, x4; + +#define S2_1(x0, x1, x2, x3, x4) \ + vpxor RNOT, x3, x3; \ + vpxor x0, x1, x1; \ + vpand x2, x0, tp; \ + vpxor x3, tp, tp; \ + vpor x0, x3, x3; \ + vpxor x1, x2, x2; \ + vpxor x1, x3, x3; \ + vpand tp, x1, x1; +#define S2_2(x0, x1, x2, x3, x4) \ + vpxor x2, tp, tp; \ + vpand x3, x2, x2; \ + vpor x1, x3, x3; \ + vpxor RNOT, tp, tp; \ + vpxor tp, x3, x3; \ + vpxor tp, x0, x4; \ + vpxor x2, tp, x0; \ + vpor x2, x1, x1; + +#define S3_1(x0, x1, x2, x3, x4) \ + vpxor x3, x1, tp; \ + vpor x0, x3, x3; \ + vpand x0, x1, x4; \ + vpxor x2, x0, x0; \ + vpxor tp, x2, x2; \ + vpand x3, tp, x1; \ + vpxor x3, x2, x2; \ + vpor x4, x0, x0; \ + vpxor x3, x4, x4; +#define S3_2(x0, x1, x2, x3, x4) \ + vpxor x0, x1, x1; \ + vpand x3, x0, x0; \ + vpand x4, x3, x3; \ + vpxor x2, x3, x3; \ + vpor x1, x4, x4; \ + vpand x1, x2, x2; \ + vpxor x3, x4, x4; \ + vpxor x3, x0, x0; \ + vpxor x2, x3, x3; + +#define S4_1(x0, x1, x2, x3, x4) \ + vpand x0, x3, tp; \ + vpxor x3, x0, x0; \ + vpxor x2, tp, tp; \ + vpor x3, x2, x2; \ + vpxor x1, x0, x0; \ + vpxor tp, x3, x4; \ + vpor x0, x2, x2; \ + vpxor x1, x2, x2; +#define S4_2(x0, x1, x2, x3, x4) \ + vpand x0, x1, x1; \ + vpxor x4, x1, x1; \ + vpand x2, x4, x4; \ + vpxor tp, x2, x2; \ + vpxor x0, x4, x4; \ + vpor x1, tp, x3; \ + vpxor RNOT, x1, x1; \ + vpxor x0, x3, x3; + +#define S5_1(x0, x1, x2, x3, x4) \ + vpor x0, x1, tp; \ + vpxor tp, x2, x2; \ + vpxor RNOT, x3, x3; \ + vpxor x0, x1, x4; \ + vpxor x2, x0, x0; \ + vpand x4, tp, x1; \ + vpor x3, x4, x4; \ + vpxor x0, x4, x4; +#define S5_2(x0, x1, x2, x3, x4) \ + vpand x3, x0, x0; \ + vpxor x3, x1, x1; \ + vpxor x2, x3, x3; \ + vpxor x1, x0, x0; \ + vpand x4, x2, x2; \ + vpxor x2, x1, x1; \ + vpand x0, x2, x2; \ + vpxor x2, x3, x3; + +#define S6_1(x0, x1, x2, x3, x4) \ + vpxor x0, x3, x3; \ + vpxor x2, x1, tp; \ + vpxor x0, x2, x2; \ + vpand x3, x0, x0; \ + vpor x3, tp, tp; \ + vpxor RNOT, x1, x4; \ + vpxor tp, x0, x0; \ + vpxor x2, tp, x1; +#define S6_2(x0, x1, x2, x3, x4) \ + vpxor x4, x3, x3; \ + vpxor x0, x4, x4; \ + vpand x0, x2, x2; \ + vpxor x1, x4, x4; \ + vpxor x3, x2, x2; \ + vpand x1, x3, x3; \ + vpxor x0, x3, x3; \ + vpxor x2, x1, x1; + +#define S7_1(x0, x1, x2, x3, x4) \ + vpxor RNOT, x1, tp; \ + vpxor RNOT, x0, x0; \ + vpand x2, tp, x1; \ + vpxor x3, x1, x1; \ + vpor tp, x3, x3; \ + vpxor x2, tp, x4; \ + vpxor x3, x2, x2; \ + vpxor x0, x3, x3; \ + vpor x1, x0, x0; +#define S7_2(x0, x1, x2, x3, x4) \ + vpand x0, x2, x2; \ + vpxor x4, x0, x0; \ + vpxor x3, x4, x4; \ + vpand x0, x3, x3; \ + vpxor x1, x4, x4; \ + vpxor x4, x2, x2; \ + vpxor x1, x3, x3; \ + vpor x0, x4, x4; \ + vpxor x1, x4, x4; + +#define SI0_1(x0, x1, x2, x3, x4) \ + vpxor x0, x1, x1; \ + vpor x1, x3, tp; \ + vpxor x1, x3, x4; \ + vpxor RNOT, x0, x0; \ + vpxor tp, x2, x2; \ + vpxor x0, tp, x3; \ + vpand x1, x0, x0; \ + vpxor x2, x0, x0; +#define SI0_2(x0, x1, x2, x3, x4) \ + vpand x3, x2, x2; \ + vpxor x4, x3, x3; \ + vpxor x3, x2, x2; \ + vpxor x3, x1, x1; \ + vpand x0, x3, x3; \ + vpxor x0, x1, x1; \ + vpxor x2, x0, x0; \ + vpxor x3, x4, x4; + +#define SI1_1(x0, x1, x2, x3, x4) \ + vpxor x3, x1, x1; \ + vpxor x2, x0, tp; \ + vpxor RNOT, x2, x2; \ + vpor x1, x0, x4; \ + vpxor x3, x4, x4; \ + vpand x1, x3, x3; \ + vpxor x2, x1, x1; \ + vpand x4, x2, x2; +#define SI1_2(x0, x1, x2, x3, x4) \ + vpxor x1, x4, x4; \ + vpor x3, x1, x1; \ + vpxor tp, x3, x3; \ + vpxor tp, x2, x2; \ + vpor x4, tp, x0; \ + vpxor x4, x2, x2; \ + vpxor x0, x1, x1; \ + vpxor x1, x4, x4; + +#define SI2_1(x0, x1, x2, x3, x4) \ + vpxor x1, x2, x2; \ + vpxor RNOT, x3, tp; \ + vpor x2, tp, tp; \ + vpxor x3, x2, x2; \ + vpxor x0, x3, x4; \ + vpxor x1, tp, x3; \ + vpor x2, x1, x1; \ + vpxor x0, x2, x2; +#define SI2_2(x0, x1, x2, x3, x4) \ + vpxor x4, x1, x1; \ + vpor x3, x4, x4; \ + vpxor x3, x2, x2; \ + vpxor x2, x4, x4; \ + vpand x1, x2, x2; \ + vpxor x3, x2, x2; \ + vpxor x4, x3, x3; \ + vpxor x0, x4, x4; + +#define SI3_1(x0, x1, x2, x3, x4) \ + vpxor x1, x2, x2; \ + vpand x2, x1, tp; \ + vpxor x0, tp, tp; \ + vpor x1, x0, x0; \ + vpxor x3, x1, x4; \ + vpxor x3, x0, x0; \ + vpor tp, x3, x3; \ + vpxor x2, tp, x1; +#define SI3_2(x0, x1, x2, x3, x4) \ + vpxor x3, x1, x1; \ + vpxor x2, x0, x0; \ + vpxor x3, x2, x2; \ + vpand x1, x3, x3; \ + vpxor x0, x1, x1; \ + vpand x2, x0, x0; \ + vpxor x3, x4, x4; \ + vpxor x0, x3, x3; \ + vpxor x1, x0, x0; + +#define SI4_1(x0, x1, x2, x3, x4) \ + vpxor x3, x2, x2; \ + vpand x1, x0, tp; \ + vpxor x2, tp, tp; \ + vpor x3, x2, x2; \ + vpxor RNOT, x0, x4; \ + vpxor tp, x1, x1; \ + vpxor x2, tp, x0; \ + vpand x4, x2, x2; +#define SI4_2(x0, x1, x2, x3, x4) \ + vpxor x0, x2, x2; \ + vpor x4, x0, x0; \ + vpxor x3, x0, x0; \ + vpand x2, x3, x3; \ + vpxor x3, x4, x4; \ + vpxor x1, x3, x3; \ + vpand x0, x1, x1; \ + vpxor x1, x4, x4; \ + vpxor x3, x0, x0; + +#define SI5_1(x0, x1, x2, x3, x4) \ + vpor x2, x1, tp; \ + vpxor x1, x2, x2; \ + vpxor x3, tp, tp; \ + vpand x1, x3, x3; \ + vpxor x3, x2, x2; \ + vpor x0, x3, x3; \ + vpxor RNOT, x0, x0; \ + vpxor x2, x3, x3; \ + vpor x0, x2, x2; +#define SI5_2(x0, x1, x2, x3, x4) \ + vpxor tp, x1, x4; \ + vpxor x4, x2, x2; \ + vpand x0, x4, x4; \ + vpxor tp, x0, x0; \ + vpxor x3, tp, x1; \ + vpand x2, x0, x0; \ + vpxor x3, x2, x2; \ + vpxor x2, x0, x0; \ + vpxor x4, x2, x2; \ + vpxor x3, x4, x4; + +#define SI6_1(x0, x1, x2, x3, x4) \ + vpxor x2, x0, x0; \ + vpand x3, x0, tp; \ + vpxor x3, x2, x2; \ + vpxor x2, tp, tp; \ + vpxor x1, x3, x3; \ + vpor x0, x2, x2; \ + vpxor x3, x2, x2; \ + vpand tp, x3, x3; +#define SI6_2(x0, x1, x2, x3, x4) \ + vpxor RNOT, tp, tp; \ + vpxor x1, x3, x3; \ + vpand x2, x1, x1; \ + vpxor tp, x0, x4; \ + vpxor x4, x3, x3; \ + vpxor x2, x4, x4; \ + vpxor x1, tp, x0; \ + vpxor x0, x2, x2; + +#define SI7_1(x0, x1, x2, x3, x4) \ + vpand x0, x3, tp; \ + vpxor x2, x0, x0; \ + vpor x3, x2, x2; \ + vpxor x1, x3, x4; \ + vpxor RNOT, x0, x0; \ + vpor tp, x1, x1; \ + vpxor x0, x4, x4; \ + vpand x2, x0, x0; \ + vpxor x1, x0, x0; +#define SI7_2(x0, x1, x2, x3, x4) \ + vpand x2, x1, x1; \ + vpxor x2, tp, x3; \ + vpxor x3, x4, x4; \ + vpand x3, x2, x2; \ + vpor x0, x3, x3; \ + vpxor x4, x1, x1; \ + vpxor x4, x3, x3; \ + vpand x0, x4, x4; \ + vpxor x2, x4, x4; + +#define get_key(i, j, t) \ + vbroadcastss (4*(i)+(j))*4(CTX), t; + +#define K2(x0, x1, x2, x3, x4, i) \ + get_key(i, 0, RK0); \ + get_key(i, 1, RK1); \ + get_key(i, 2, RK2); \ + get_key(i, 3, RK3); \ + vpxor RK0, x0 ## 1, x0 ## 1; \ + vpxor RK1, x1 ## 1, x1 ## 1; \ + vpxor RK2, x2 ## 1, x2 ## 1; \ + vpxor RK3, x3 ## 1, x3 ## 1; \ + vpxor RK0, x0 ## 2, x0 ## 2; \ + vpxor RK1, x1 ## 2, x1 ## 2; \ + vpxor RK2, x2 ## 2, x2 ## 2; \ + vpxor RK3, x3 ## 2, x3 ## 2; + +#define LK2(x0, x1, x2, x3, x4, i) \ + vpslld $13, x0 ## 1, x4 ## 1; \ + vpsrld $(32 - 13), x0 ## 1, x0 ## 1; \ + vpor x4 ## 1, x0 ## 1, x0 ## 1; \ + vpxor x0 ## 1, x1 ## 1, x1 ## 1; \ + vpslld $3, x2 ## 1, x4 ## 1; \ + vpsrld $(32 - 3), x2 ## 1, x2 ## 1; \ + vpor x4 ## 1, x2 ## 1, x2 ## 1; \ + vpxor x2 ## 1, x1 ## 1, x1 ## 1; \ + vpslld $13, x0 ## 2, x4 ## 2; \ + vpsrld $(32 - 13), x0 ## 2, x0 ## 2; \ + vpor x4 ## 2, x0 ## 2, x0 ## 2; \ + vpxor x0 ## 2, x1 ## 2, x1 ## 2; \ + vpslld $3, x2 ## 2, x4 ## 2; \ + vpsrld $(32 - 3), x2 ## 2, x2 ## 2; \ + vpor x4 ## 2, x2 ## 2, x2 ## 2; \ + vpxor x2 ## 2, x1 ## 2, x1 ## 2; \ + vpslld $1, x1 ## 1, x4 ## 1; \ + vpsrld $(32 - 1), x1 ## 1, x1 ## 1; \ + vpor x4 ## 1, x1 ## 1, x1 ## 1; \ + vpslld $3, x0 ## 1, x4 ## 1; \ + vpxor x2 ## 1, x3 ## 1, x3 ## 1; \ + vpxor x4 ## 1, x3 ## 1, x3 ## 1; \ + get_key(i, 1, RK1); \ + vpslld $1, x1 ## 2, x4 ## 2; \ + vpsrld $(32 - 1), x1 ## 2, x1 ## 2; \ + vpor x4 ## 2, x1 ## 2, x1 ## 2; \ + vpslld $3, x0 ## 2, x4 ## 2; \ + vpxor x2 ## 2, x3 ## 2, x3 ## 2; \ + vpxor x4 ## 2, x3 ## 2, x3 ## 2; \ + get_key(i, 3, RK3); \ + vpslld $7, x3 ## 1, x4 ## 1; \ + vpsrld $(32 - 7), x3 ## 1, x3 ## 1; \ + vpor x4 ## 1, x3 ## 1, x3 ## 1; \ + vpslld $7, x1 ## 1, x4 ## 1; \ + vpxor x1 ## 1, x0 ## 1, x0 ## 1; \ + vpxor x3 ## 1, x0 ## 1, x0 ## 1; \ + vpxor x3 ## 1, x2 ## 1, x2 ## 1; \ + vpxor x4 ## 1, x2 ## 1, x2 ## 1; \ + get_key(i, 0, RK0); \ + vpslld $7, x3 ## 2, x4 ## 2; \ + vpsrld $(32 - 7), x3 ## 2, x3 ## 2; \ + vpor x4 ## 2, x3 ## 2, x3 ## 2; \ + vpslld $7, x1 ## 2, x4 ## 2; \ + vpxor x1 ## 2, x0 ## 2, x0 ## 2; \ + vpxor x3 ## 2, x0 ## 2, x0 ## 2; \ + vpxor x3 ## 2, x2 ## 2, x2 ## 2; \ + vpxor x4 ## 2, x2 ## 2, x2 ## 2; \ + get_key(i, 2, RK2); \ + vpxor RK1, x1 ## 1, x1 ## 1; \ + vpxor RK3, x3 ## 1, x3 ## 1; \ + vpslld $5, x0 ## 1, x4 ## 1; \ + vpsrld $(32 - 5), x0 ## 1, x0 ## 1; \ + vpor x4 ## 1, x0 ## 1, x0 ## 1; \ + vpslld $22, x2 ## 1, x4 ## 1; \ + vpsrld $(32 - 22), x2 ## 1, x2 ## 1; \ + vpor x4 ## 1, x2 ## 1, x2 ## 1; \ + vpxor RK0, x0 ## 1, x0 ## 1; \ + vpxor RK2, x2 ## 1, x2 ## 1; \ + vpxor RK1, x1 ## 2, x1 ## 2; \ + vpxor RK3, x3 ## 2, x3 ## 2; \ + vpslld $5, x0 ## 2, x4 ## 2; \ + vpsrld $(32 - 5), x0 ## 2, x0 ## 2; \ + vpor x4 ## 2, x0 ## 2, x0 ## 2; \ + vpslld $22, x2 ## 2, x4 ## 2; \ + vpsrld $(32 - 22), x2 ## 2, x2 ## 2; \ + vpor x4 ## 2, x2 ## 2, x2 ## 2; \ + vpxor RK0, x0 ## 2, x0 ## 2; \ + vpxor RK2, x2 ## 2, x2 ## 2; + +#define KL2(x0, x1, x2, x3, x4, i) \ + vpxor RK0, x0 ## 1, x0 ## 1; \ + vpxor RK2, x2 ## 1, x2 ## 1; \ + vpsrld $5, x0 ## 1, x4 ## 1; \ + vpslld $(32 - 5), x0 ## 1, x0 ## 1; \ + vpor x4 ## 1, x0 ## 1, x0 ## 1; \ + vpxor RK3, x3 ## 1, x3 ## 1; \ + vpxor RK1, x1 ## 1, x1 ## 1; \ + vpsrld $22, x2 ## 1, x4 ## 1; \ + vpslld $(32 - 22), x2 ## 1, x2 ## 1; \ + vpor x4 ## 1, x2 ## 1, x2 ## 1; \ + vpxor x3 ## 1, x2 ## 1, x2 ## 1; \ + vpxor RK0, x0 ## 2, x0 ## 2; \ + vpxor RK2, x2 ## 2, x2 ## 2; \ + vpsrld $5, x0 ## 2, x4 ## 2; \ + vpslld $(32 - 5), x0 ## 2, x0 ## 2; \ + vpor x4 ## 2, x0 ## 2, x0 ## 2; \ + vpxor RK3, x3 ## 2, x3 ## 2; \ + vpxor RK1, x1 ## 2, x1 ## 2; \ + vpsrld $22, x2 ## 2, x4 ## 2; \ + vpslld $(32 - 22), x2 ## 2, x2 ## 2; \ + vpor x4 ## 2, x2 ## 2, x2 ## 2; \ + vpxor x3 ## 2, x2 ## 2, x2 ## 2; \ + vpxor x3 ## 1, x0 ## 1, x0 ## 1; \ + vpslld $7, x1 ## 1, x4 ## 1; \ + vpxor x1 ## 1, x0 ## 1, x0 ## 1; \ + vpxor x4 ## 1, x2 ## 1, x2 ## 1; \ + vpsrld $1, x1 ## 1, x4 ## 1; \ + vpslld $(32 - 1), x1 ## 1, x1 ## 1; \ + vpor x4 ## 1, x1 ## 1, x1 ## 1; \ + vpxor x3 ## 2, x0 ## 2, x0 ## 2; \ + vpslld $7, x1 ## 2, x4 ## 2; \ + vpxor x1 ## 2, x0 ## 2, x0 ## 2; \ + vpxor x4 ## 2, x2 ## 2, x2 ## 2; \ + vpsrld $1, x1 ## 2, x4 ## 2; \ + vpslld $(32 - 1), x1 ## 2, x1 ## 2; \ + vpor x4 ## 2, x1 ## 2, x1 ## 2; \ + vpsrld $7, x3 ## 1, x4 ## 1; \ + vpslld $(32 - 7), x3 ## 1, x3 ## 1; \ + vpor x4 ## 1, x3 ## 1, x3 ## 1; \ + vpxor x0 ## 1, x1 ## 1, x1 ## 1; \ + vpslld $3, x0 ## 1, x4 ## 1; \ + vpxor x4 ## 1, x3 ## 1, x3 ## 1; \ + vpsrld $7, x3 ## 2, x4 ## 2; \ + vpslld $(32 - 7), x3 ## 2, x3 ## 2; \ + vpor x4 ## 2, x3 ## 2, x3 ## 2; \ + vpxor x0 ## 2, x1 ## 2, x1 ## 2; \ + vpslld $3, x0 ## 2, x4 ## 2; \ + vpxor x4 ## 2, x3 ## 2, x3 ## 2; \ + vpsrld $13, x0 ## 1, x4 ## 1; \ + vpslld $(32 - 13), x0 ## 1, x0 ## 1; \ + vpor x4 ## 1, x0 ## 1, x0 ## 1; \ + vpxor x2 ## 1, x1 ## 1, x1 ## 1; \ + vpxor x2 ## 1, x3 ## 1, x3 ## 1; \ + vpsrld $3, x2 ## 1, x4 ## 1; \ + vpslld $(32 - 3), x2 ## 1, x2 ## 1; \ + vpor x4 ## 1, x2 ## 1, x2 ## 1; \ + vpsrld $13, x0 ## 2, x4 ## 2; \ + vpslld $(32 - 13), x0 ## 2, x0 ## 2; \ + vpor x4 ## 2, x0 ## 2, x0 ## 2; \ + vpxor x2 ## 2, x1 ## 2, x1 ## 2; \ + vpxor x2 ## 2, x3 ## 2, x3 ## 2; \ + vpsrld $3, x2 ## 2, x4 ## 2; \ + vpslld $(32 - 3), x2 ## 2, x2 ## 2; \ + vpor x4 ## 2, x2 ## 2, x2 ## 2; + +#define S(SBOX, x0, x1, x2, x3, x4) \ + SBOX ## _1(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ + SBOX ## _2(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ + SBOX ## _1(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \ + SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); + +#define SP(SBOX, x0, x1, x2, x3, x4, i) \ + get_key(i, 0, RK0); \ + SBOX ## _1(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ + get_key(i, 2, RK2); \ + SBOX ## _2(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ + get_key(i, 3, RK3); \ + SBOX ## _1(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \ + get_key(i, 1, RK1); \ + SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \ + +#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ + vpunpckldq x1, x0, t0; \ + vpunpckhdq x1, x0, t2; \ + vpunpckldq x3, x2, t1; \ + vpunpckhdq x3, x2, x3; \ + \ + vpunpcklqdq t1, t0, x0; \ + vpunpckhqdq t1, t0, x1; \ + vpunpcklqdq x3, t2, x2; \ + vpunpckhqdq x3, t2, x3; + +#define read_blocks(in, x0, x1, x2, x3, t0, t1, t2) \ + vmovdqu (0*4*4)(in), x0; \ + vmovdqu (1*4*4)(in), x1; \ + vmovdqu (2*4*4)(in), x2; \ + vmovdqu (3*4*4)(in), x3; \ + \ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) + +#define write_blocks(out, x0, x1, x2, x3, t0, t1, t2) \ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ + \ + vmovdqu x0, (0*4*4)(out); \ + vmovdqu x1, (1*4*4)(out); \ + vmovdqu x2, (2*4*4)(out); \ + vmovdqu x3, (3*4*4)(out); + +#define xor_blocks(out, x0, x1, x2, x3, t0, t1, t2) \ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ + \ + vpxor (0*4*4)(out), x0, x0; \ + vmovdqu x0, (0*4*4)(out); \ + vpxor (1*4*4)(out), x1, x1; \ + vmovdqu x1, (1*4*4)(out); \ + vpxor (2*4*4)(out), x2, x2; \ + vmovdqu x2, (2*4*4)(out); \ + vpxor (3*4*4)(out), x3, x3; \ + vmovdqu x3, (3*4*4)(out); + +.align 8 +.global __serpent_enc_blk_8way +.type __serpent_enc_blk_8way,@function; + +__serpent_enc_blk_8way: + /* input: + * %rdi: ctx, CTX + * %rsi: dst + * %rdx: src + * %rcx: bool, if true: xor output + */ + + vpcmpeqd RNOT, RNOT, RNOT; + + leaq (4*4*4)(%rdx), %rax; + read_blocks(%rdx, RA1, RB1, RC1, RD1, RK0, RK1, RK2); + read_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); + + K2(RA, RB, RC, RD, RE, 0); + S(S0, RA, RB, RC, RD, RE); LK2(RC, RB, RD, RA, RE, 1); + S(S1, RC, RB, RD, RA, RE); LK2(RE, RD, RA, RC, RB, 2); + S(S2, RE, RD, RA, RC, RB); LK2(RB, RD, RE, RC, RA, 3); + S(S3, RB, RD, RE, RC, RA); LK2(RC, RA, RD, RB, RE, 4); + S(S4, RC, RA, RD, RB, RE); LK2(RA, RD, RB, RE, RC, 5); + S(S5, RA, RD, RB, RE, RC); LK2(RC, RA, RD, RE, RB, 6); + S(S6, RC, RA, RD, RE, RB); LK2(RD, RB, RA, RE, RC, 7); + S(S7, RD, RB, RA, RE, RC); LK2(RC, RA, RE, RD, RB, 8); + S(S0, RC, RA, RE, RD, RB); LK2(RE, RA, RD, RC, RB, 9); + S(S1, RE, RA, RD, RC, RB); LK2(RB, RD, RC, RE, RA, 10); + S(S2, RB, RD, RC, RE, RA); LK2(RA, RD, RB, RE, RC, 11); + S(S3, RA, RD, RB, RE, RC); LK2(RE, RC, RD, RA, RB, 12); + S(S4, RE, RC, RD, RA, RB); LK2(RC, RD, RA, RB, RE, 13); + S(S5, RC, RD, RA, RB, RE); LK2(RE, RC, RD, RB, RA, 14); + S(S6, RE, RC, RD, RB, RA); LK2(RD, RA, RC, RB, RE, 15); + S(S7, RD, RA, RC, RB, RE); LK2(RE, RC, RB, RD, RA, 16); + S(S0, RE, RC, RB, RD, RA); LK2(RB, RC, RD, RE, RA, 17); + S(S1, RB, RC, RD, RE, RA); LK2(RA, RD, RE, RB, RC, 18); + S(S2, RA, RD, RE, RB, RC); LK2(RC, RD, RA, RB, RE, 19); + S(S3, RC, RD, RA, RB, RE); LK2(RB, RE, RD, RC, RA, 20); + S(S4, RB, RE, RD, RC, RA); LK2(RE, RD, RC, RA, RB, 21); + S(S5, RE, RD, RC, RA, RB); LK2(RB, RE, RD, RA, RC, 22); + S(S6, RB, RE, RD, RA, RC); LK2(RD, RC, RE, RA, RB, 23); + S(S7, RD, RC, RE, RA, RB); LK2(RB, RE, RA, RD, RC, 24); + S(S0, RB, RE, RA, RD, RC); LK2(RA, RE, RD, RB, RC, 25); + S(S1, RA, RE, RD, RB, RC); LK2(RC, RD, RB, RA, RE, 26); + S(S2, RC, RD, RB, RA, RE); LK2(RE, RD, RC, RA, RB, 27); + S(S3, RE, RD, RC, RA, RB); LK2(RA, RB, RD, RE, RC, 28); + S(S4, RA, RB, RD, RE, RC); LK2(RB, RD, RE, RC, RA, 29); + S(S5, RB, RD, RE, RC, RA); LK2(RA, RB, RD, RC, RE, 30); + S(S6, RA, RB, RD, RC, RE); LK2(RD, RE, RB, RC, RA, 31); + S(S7, RD, RE, RB, RC, RA); K2(RA, RB, RC, RD, RE, 32); + + leaq (4*4*4)(%rsi), %rax; + + testb %cl, %cl; + jnz __enc_xor8; + + write_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2); + write_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); + + ret; + +__enc_xor8: + xor_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2); + xor_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); + + ret; + +.align 8 +.global serpent_dec_blk_8way +.type serpent_dec_blk_8way,@function; + +serpent_dec_blk_8way: + /* input: + * %rdi: ctx, CTX + * %rsi: dst + * %rdx: src + */ + + vpcmpeqd RNOT, RNOT, RNOT; + + leaq (4*4*4)(%rdx), %rax; + read_blocks(%rdx, RA1, RB1, RC1, RD1, RK0, RK1, RK2); + read_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); + + K2(RA, RB, RC, RD, RE, 32); + SP(SI7, RA, RB, RC, RD, RE, 31); KL2(RB, RD, RA, RE, RC, 31); + SP(SI6, RB, RD, RA, RE, RC, 30); KL2(RA, RC, RE, RB, RD, 30); + SP(SI5, RA, RC, RE, RB, RD, 29); KL2(RC, RD, RA, RE, RB, 29); + SP(SI4, RC, RD, RA, RE, RB, 28); KL2(RC, RA, RB, RE, RD, 28); + SP(SI3, RC, RA, RB, RE, RD, 27); KL2(RB, RC, RD, RE, RA, 27); + SP(SI2, RB, RC, RD, RE, RA, 26); KL2(RC, RA, RE, RD, RB, 26); + SP(SI1, RC, RA, RE, RD, RB, 25); KL2(RB, RA, RE, RD, RC, 25); + SP(SI0, RB, RA, RE, RD, RC, 24); KL2(RE, RC, RA, RB, RD, 24); + SP(SI7, RE, RC, RA, RB, RD, 23); KL2(RC, RB, RE, RD, RA, 23); + SP(SI6, RC, RB, RE, RD, RA, 22); KL2(RE, RA, RD, RC, RB, 22); + SP(SI5, RE, RA, RD, RC, RB, 21); KL2(RA, RB, RE, RD, RC, 21); + SP(SI4, RA, RB, RE, RD, RC, 20); KL2(RA, RE, RC, RD, RB, 20); + SP(SI3, RA, RE, RC, RD, RB, 19); KL2(RC, RA, RB, RD, RE, 19); + SP(SI2, RC, RA, RB, RD, RE, 18); KL2(RA, RE, RD, RB, RC, 18); + SP(SI1, RA, RE, RD, RB, RC, 17); KL2(RC, RE, RD, RB, RA, 17); + SP(SI0, RC, RE, RD, RB, RA, 16); KL2(RD, RA, RE, RC, RB, 16); + SP(SI7, RD, RA, RE, RC, RB, 15); KL2(RA, RC, RD, RB, RE, 15); + SP(SI6, RA, RC, RD, RB, RE, 14); KL2(RD, RE, RB, RA, RC, 14); + SP(SI5, RD, RE, RB, RA, RC, 13); KL2(RE, RC, RD, RB, RA, 13); + SP(SI4, RE, RC, RD, RB, RA, 12); KL2(RE, RD, RA, RB, RC, 12); + SP(SI3, RE, RD, RA, RB, RC, 11); KL2(RA, RE, RC, RB, RD, 11); + SP(SI2, RA, RE, RC, RB, RD, 10); KL2(RE, RD, RB, RC, RA, 10); + SP(SI1, RE, RD, RB, RC, RA, 9); KL2(RA, RD, RB, RC, RE, 9); + SP(SI0, RA, RD, RB, RC, RE, 8); KL2(RB, RE, RD, RA, RC, 8); + SP(SI7, RB, RE, RD, RA, RC, 7); KL2(RE, RA, RB, RC, RD, 7); + SP(SI6, RE, RA, RB, RC, RD, 6); KL2(RB, RD, RC, RE, RA, 6); + SP(SI5, RB, RD, RC, RE, RA, 5); KL2(RD, RA, RB, RC, RE, 5); + SP(SI4, RD, RA, RB, RC, RE, 4); KL2(RD, RB, RE, RC, RA, 4); + SP(SI3, RD, RB, RE, RC, RA, 3); KL2(RE, RD, RA, RC, RB, 3); + SP(SI2, RE, RD, RA, RC, RB, 2); KL2(RD, RB, RC, RA, RE, 2); + SP(SI1, RD, RB, RC, RA, RE, 1); KL2(RE, RB, RC, RA, RD, 1); + S(SI0, RE, RB, RC, RA, RD); K2(RC, RD, RB, RE, RA, 0); + + leaq (4*4*4)(%rsi), %rax; + write_blocks(%rsi, RC1, RD1, RB1, RE1, RK0, RK1, RK2); + write_blocks(%rax, RC2, RD2, RB2, RE2, RK0, RK1, RK2); + + ret; diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c new file mode 100644 index 000000000000..0dc7a26535e5 --- /dev/null +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -0,0 +1,949 @@ +/* + * Glue Code for AVX assembler versions of Serpent Cipher + * + * Copyright (C) 2012 Johannes Goetzfried + * + * + * Glue code based on serpent_sse2_glue.c by: + * Copyright (C) 2011 Jussi Kivilinna + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct async_serpent_ctx { + struct cryptd_ablkcipher *cryptd_tfm; +}; + +static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) +{ + if (fpu_enabled) + return true; + + /* AVX is only used when chunk to be processed is large enough, so + * do not enable FPU until it is necessary. + */ + if (nbytes < SERPENT_BLOCK_SIZE * SERPENT_PARALLEL_BLOCKS) + return false; + + kernel_fpu_begin(); + return true; +} + +static inline void serpent_fpu_end(bool fpu_enabled) +{ + if (fpu_enabled) + kernel_fpu_end(); +} + +static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, + bool enc) +{ + bool fpu_enabled = false; + struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = SERPENT_BLOCK_SIZE; + unsigned int nbytes; + int err; + + err = blkcipher_walk_virt(desc, walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk->nbytes)) { + u8 *wsrc = walk->src.virt.addr; + u8 *wdst = walk->dst.virt.addr; + + fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); + + /* Process multi-block batch */ + if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { + do { + if (enc) + serpent_enc_blk_xway(ctx, wdst, wsrc); + else + serpent_dec_blk_xway(ctx, wdst, wsrc); + + wsrc += bsize * SERPENT_PARALLEL_BLOCKS; + wdst += bsize * SERPENT_PARALLEL_BLOCKS; + nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; + } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); + + if (nbytes < bsize) + goto done; + } + + /* Handle leftovers */ + do { + if (enc) + __serpent_encrypt(ctx, wdst, wsrc); + else + __serpent_decrypt(ctx, wdst, wsrc); + + wsrc += bsize; + wdst += bsize; + nbytes -= bsize; + } while (nbytes >= bsize); + +done: + err = blkcipher_walk_done(desc, walk, nbytes); + } + + serpent_fpu_end(fpu_enabled); + return err; +} + +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); + return ecb_crypt(desc, &walk, true); +} + +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); + return ecb_crypt(desc, &walk, false); +} + +static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = SERPENT_BLOCK_SIZE; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 *iv = (u128 *)walk->iv; + + do { + u128_xor(dst, src, iv); + __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst); + iv = dst; + + src += 1; + dst += 1; + nbytes -= bsize; + } while (nbytes >= bsize); + + u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); + return nbytes; +} + +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while ((nbytes = walk.nbytes)) { + nbytes = __cbc_encrypt(desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} + +static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = SERPENT_BLOCK_SIZE; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; + u128 last_iv; + int i; + + /* Start of the last block. */ + src += nbytes / bsize - 1; + dst += nbytes / bsize - 1; + + last_iv = *src; + + /* Process multi-block batch */ + if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { + do { + nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1); + src -= SERPENT_PARALLEL_BLOCKS - 1; + dst -= SERPENT_PARALLEL_BLOCKS - 1; + + for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) + ivs[i] = src[i]; + + serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); + + for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) + u128_xor(dst + (i + 1), dst + (i + 1), ivs + i); + + nbytes -= bsize; + if (nbytes < bsize) + goto done; + + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); + + if (nbytes < bsize) + goto done; + } + + /* Handle leftovers */ + for (;;) { + __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src); + + nbytes -= bsize; + if (nbytes < bsize) + break; + + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } + +done: + u128_xor(dst, dst, (u128 *)walk->iv); + *(u128 *)walk->iv = last_iv; + + return nbytes; +} + +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + bool fpu_enabled = false; + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk.nbytes)) { + fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); + nbytes = __cbc_decrypt(desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + serpent_fpu_end(fpu_enabled); + return err; +} + +static inline void u128_to_be128(be128 *dst, const u128 *src) +{ + dst->a = cpu_to_be64(src->a); + dst->b = cpu_to_be64(src->b); +} + +static inline void be128_to_u128(u128 *dst, const be128 *src) +{ + dst->a = be64_to_cpu(src->a); + dst->b = be64_to_cpu(src->b); +} + +static inline void u128_inc(u128 *i) +{ + i->b++; + if (!i->b) + i->a++; +} + +static void ctr_crypt_final(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + u8 *ctrblk = walk->iv; + u8 keystream[SERPENT_BLOCK_SIZE]; + u8 *src = walk->src.virt.addr; + u8 *dst = walk->dst.virt.addr; + unsigned int nbytes = walk->nbytes; + + __serpent_encrypt(ctx, keystream, ctrblk); + crypto_xor(keystream, src, nbytes); + memcpy(dst, keystream, nbytes); + + crypto_inc(ctrblk, SERPENT_BLOCK_SIZE); +} + +static unsigned int __ctr_crypt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = SERPENT_BLOCK_SIZE; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 ctrblk; + be128 ctrblocks[SERPENT_PARALLEL_BLOCKS]; + int i; + + be128_to_u128(&ctrblk, (be128 *)walk->iv); + + /* Process multi-block batch */ + if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { + do { + /* create ctrblks for parallel encrypt */ + for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { + if (dst != src) + dst[i] = src[i]; + + u128_to_be128(&ctrblocks[i], &ctrblk); + u128_inc(&ctrblk); + } + + serpent_enc_blk_xway_xor(ctx, (u8 *)dst, + (u8 *)ctrblocks); + + src += SERPENT_PARALLEL_BLOCKS; + dst += SERPENT_PARALLEL_BLOCKS; + nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; + } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); + + if (nbytes < bsize) + goto done; + } + + /* Handle leftovers */ + do { + if (dst != src) + *dst = *src; + + u128_to_be128(&ctrblocks[0], &ctrblk); + u128_inc(&ctrblk); + + __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); + u128_xor(dst, dst, (u128 *)ctrblocks); + + src += 1; + dst += 1; + nbytes -= bsize; + } while (nbytes >= bsize); + +done: + u128_to_be128((be128 *)walk->iv, &ctrblk); + return nbytes; +} + +static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + bool fpu_enabled = false; + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) { + fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); + nbytes = __ctr_crypt(desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + serpent_fpu_end(fpu_enabled); + + if (walk.nbytes) { + ctr_crypt_final(desc, &walk); + err = blkcipher_walk_done(desc, &walk, 0); + } + + return err; +} + +struct crypt_priv { + struct serpent_ctx *ctx; + bool fpu_enabled; +}; + +static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) +{ + const unsigned int bsize = SERPENT_BLOCK_SIZE; + struct crypt_priv *ctx = priv; + int i; + + ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); + + if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { + serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst); + return; + } + + for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) + __serpent_encrypt(ctx->ctx, srcdst, srcdst); +} + +static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) +{ + const unsigned int bsize = SERPENT_BLOCK_SIZE; + struct crypt_priv *ctx = priv; + int i; + + ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); + + if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { + serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst); + return; + } + + for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) + __serpent_decrypt(ctx->ctx, srcdst, srcdst); +} + +struct serpent_lrw_ctx { + struct lrw_table_ctx lrw_table; + struct serpent_ctx serpent_ctx; +}; + +static int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm); + int err; + + err = __serpent_setkey(&ctx->serpent_ctx, key, keylen - + SERPENT_BLOCK_SIZE); + if (err) + return err; + + return lrw_init_table(&ctx->lrw_table, key + keylen - + SERPENT_BLOCK_SIZE); +} + +static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[SERPENT_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->serpent_ctx, + .fpu_enabled = false, + }; + struct lrw_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .table_ctx = &ctx->lrw_table, + .crypt_ctx = &crypt_ctx, + .crypt_fn = encrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = lrw_crypt(desc, dst, src, nbytes, &req); + serpent_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[SERPENT_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->serpent_ctx, + .fpu_enabled = false, + }; + struct lrw_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .table_ctx = &ctx->lrw_table, + .crypt_ctx = &crypt_ctx, + .crypt_fn = decrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = lrw_crypt(desc, dst, src, nbytes, &req); + serpent_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static void lrw_exit_tfm(struct crypto_tfm *tfm) +{ + struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm); + + lrw_free_table(&ctx->lrw_table); +} + +struct serpent_xts_ctx { + struct serpent_ctx tweak_ctx; + struct serpent_ctx crypt_ctx; +}; + +static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm); + u32 *flags = &tfm->crt_flags; + int err; + + /* key consists of keys of equal size concatenated, therefore + * the length must be even + */ + if (keylen % 2) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + /* first half of xts-key is for crypt */ + err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2); + if (err) + return err; + + /* second half of xts-key is for tweak */ + return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2); +} + +static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[SERPENT_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->crypt_ctx, + .fpu_enabled = false, + }; + struct xts_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .tweak_ctx = &ctx->tweak_ctx, + .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt), + .crypt_ctx = &crypt_ctx, + .crypt_fn = encrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = xts_crypt(desc, dst, src, nbytes, &req); + serpent_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + be128 buf[SERPENT_PARALLEL_BLOCKS]; + struct crypt_priv crypt_ctx = { + .ctx = &ctx->crypt_ctx, + .fpu_enabled = false, + }; + struct xts_crypt_req req = { + .tbuf = buf, + .tbuflen = sizeof(buf), + + .tweak_ctx = &ctx->tweak_ctx, + .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt), + .crypt_ctx = &crypt_ctx, + .crypt_fn = decrypt_callback, + }; + int ret; + + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + ret = xts_crypt(desc, dst, src, nbytes, &req); + serpent_fpu_end(crypt_ctx.fpu_enabled); + + return ret; +} + +static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len) +{ + struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; + int err; + + crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); + crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) + & CRYPTO_TFM_REQ_MASK); + err = crypto_ablkcipher_setkey(child, key, key_len); + crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) + & CRYPTO_TFM_RES_MASK); + return err; +} + +static int __ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct blkcipher_desc desc; + + desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); + desc.info = req->info; + desc.flags = 0; + + return crypto_blkcipher_crt(desc.tfm)->encrypt( + &desc, req->dst, req->src, req->nbytes); +} + +static int ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + if (!irq_fpu_usable()) { + struct ablkcipher_request *cryptd_req = + ablkcipher_request_ctx(req); + + memcpy(cryptd_req, req, sizeof(*req)); + ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + + return crypto_ablkcipher_encrypt(cryptd_req); + } else { + return __ablk_encrypt(req); + } +} + +static int ablk_decrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + if (!irq_fpu_usable()) { + struct ablkcipher_request *cryptd_req = + ablkcipher_request_ctx(req); + + memcpy(cryptd_req, req, sizeof(*req)); + ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + + return crypto_ablkcipher_decrypt(cryptd_req); + } else { + struct blkcipher_desc desc; + + desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); + desc.info = req->info; + desc.flags = 0; + + return crypto_blkcipher_crt(desc.tfm)->decrypt( + &desc, req->dst, req->src, req->nbytes); + } +} + +static void ablk_exit(struct crypto_tfm *tfm) +{ + struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); + + cryptd_free_ablkcipher(ctx->cryptd_tfm); +} + +static int ablk_init(struct crypto_tfm *tfm) +{ + struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); + struct cryptd_ablkcipher *cryptd_tfm; + char drv_name[CRYPTO_MAX_ALG_NAME]; + + snprintf(drv_name, sizeof(drv_name), "__driver-%s", + crypto_tfm_alg_driver_name(tfm)); + + cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); + + ctx->cryptd_tfm = cryptd_tfm; + tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + + crypto_ablkcipher_reqsize(&cryptd_tfm->base); + + return 0; +} + +static struct crypto_alg serpent_algs[10] = { { + .cra_name = "__ecb-serpent-avx", + .cra_driver_name = "__driver-ecb-serpent-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[0].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE, + .setkey = serpent_setkey, + .encrypt = ecb_encrypt, + .decrypt = ecb_decrypt, + }, + }, +}, { + .cra_name = "__cbc-serpent-avx", + .cra_driver_name = "__driver-cbc-serpent-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[1].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE, + .setkey = serpent_setkey, + .encrypt = cbc_encrypt, + .decrypt = cbc_decrypt, + }, + }, +}, { + .cra_name = "__ctr-serpent-avx", + .cra_driver_name = "__driver-ctr-serpent-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[2].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = serpent_setkey, + .encrypt = ctr_crypt, + .decrypt = ctr_crypt, + }, + }, +}, { + .cra_name = "__lrw-serpent-avx", + .cra_driver_name = "__driver-lrw-serpent-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct serpent_lrw_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[3].cra_list), + .cra_exit = lrw_exit_tfm, + .cra_u = { + .blkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE + + SERPENT_BLOCK_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE + + SERPENT_BLOCK_SIZE, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = lrw_serpent_setkey, + .encrypt = lrw_encrypt, + .decrypt = lrw_decrypt, + }, + }, +}, { + .cra_name = "__xts-serpent-avx", + .cra_driver_name = "__driver-xts-serpent-avx", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct serpent_xts_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[4].cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE * 2, + .max_keysize = SERPENT_MAX_KEY_SIZE * 2, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = xts_serpent_setkey, + .encrypt = xts_encrypt, + .decrypt = xts_decrypt, + }, + }, +}, { + .cra_name = "ecb(serpent)", + .cra_driver_name = "ecb-serpent-avx", + .cra_priority = 500, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[5].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +}, { + .cra_name = "cbc(serpent)", + .cra_driver_name = "cbc-serpent-avx", + .cra_priority = 500, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[6].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = __ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +}, { + .cra_name = "ctr(serpent)", + .cra_driver_name = "ctr-serpent-avx", + .cra_priority = 500, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[7].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_encrypt, + .geniv = "chainiv", + }, + }, +}, { + .cra_name = "lrw(serpent)", + .cra_driver_name = "lrw-serpent-avx", + .cra_priority = 500, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[8].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE + + SERPENT_BLOCK_SIZE, + .max_keysize = SERPENT_MAX_KEY_SIZE + + SERPENT_BLOCK_SIZE, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +}, { + .cra_name = "xts(serpent)", + .cra_driver_name = "xts-serpent-avx", + .cra_priority = 500, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = SERPENT_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(serpent_algs[9].cra_list), + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = SERPENT_MIN_KEY_SIZE * 2, + .max_keysize = SERPENT_MAX_KEY_SIZE * 2, + .ivsize = SERPENT_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + }, + }, +} }; + +static int __init serpent_init(void) +{ + u64 xcr0; + + if (!cpu_has_avx || !cpu_has_osxsave) { + printk(KERN_INFO "AVX instructions are not detected.\n"); + return -ENODEV; + } + + xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); + if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) { + printk(KERN_INFO "AVX detected but unusable.\n"); + return -ENODEV; + } + + return crypto_register_algs(serpent_algs, ARRAY_SIZE(serpent_algs)); +} + +static void __exit serpent_exit(void) +{ + crypto_unregister_algs(serpent_algs, ARRAY_SIZE(serpent_algs)); +} + +module_init(serpent_init); +module_exit(serpent_exit); + +MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("serpent"); diff --git a/crypto/Kconfig b/crypto/Kconfig index e00a4e49e013..2c1c2dfcc02a 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -821,6 +821,26 @@ config CRYPTO_SERPENT_SSE2_586 See also: +config CRYPTO_SERPENT_AVX_X86_64 + tristate "Serpent cipher algorithm (x86_64/AVX)" + depends on X86 && 64BIT + select CRYPTO_ALGAPI + select CRYPTO_CRYPTD + select CRYPTO_SERPENT + select CRYPTO_LRW + select CRYPTO_XTS + help + Serpent cipher algorithm, by Anderson, Biham & Knudsen. + + Keys are allowed to be from 0 to 256 bits in length, in steps + of 8 bits. + + This module provides the Serpent cipher algorithm that processes + eight blocks parallel using the AVX instruction set. + + See also: + + config CRYPTO_TEA tristate "TEA, XTEA and XETA cipher algorithms" select CRYPTO_ALGAPI diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 73b3ec6fe1a2..36748a5996e2 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1534,6 +1534,21 @@ static int alg_test_null(const struct alg_test_desc *desc, /* Please keep this list sorted by algorithm name. */ static const struct alg_test_desc alg_test_descs[] = { { + .alg = "__cbc-serpent-avx", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { .alg = "__cbc-serpent-sse2", .test = alg_test_null, .suite = { @@ -1578,6 +1593,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "__driver-cbc-serpent-avx", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "__driver-cbc-serpent-sse2", .test = alg_test_null, @@ -1623,6 +1653,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "__driver-ecb-serpent-avx", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "__driver-ecb-serpent-sse2", .test = alg_test_null, @@ -1835,6 +1880,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "cryptd(__driver-ecb-serpent-avx)", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "cryptd(__driver-ecb-serpent-sse2)", .test = alg_test_null, -- GitLab From 9102d8715e5c10db37d81ab75285a2f6746360b2 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 12 Jun 2012 10:44:55 +0200 Subject: [PATCH 1236/6849] dmaengine: at_hdmac: trivial: fix comment in header Not all Atmel SoCs were pointed out in header comment which was bringing confusion. Remove the truncated list of supported devices, replace by the only one that is not supported. Reported-by: Elen Song Signed-off-by: Nicolas Ferre Signed-off-by: Vinod Koul --- drivers/dma/at_hdmac.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 7292aa87b2dd..bb1601305d25 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -9,10 +9,9 @@ * (at your option) any later version. * * - * This supports the Atmel AHB DMA Controller, - * - * The driver has currently been tested with the Atmel AT91SAM9RL - * and AT91SAM9G45 series. + * This supports the Atmel AHB DMA Controller found in several Atmel SoCs. + * The only Atmel DMA Controller that is not covered by this driver is the one + * found on AT91SAM9263. */ #include -- GitLab From b785ea7ce662c47f6208071320638a4813722803 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Jun 2012 10:20:23 +0300 Subject: [PATCH 1237/6849] usb: gadget: composite: fix ep->maxburst initialization bMaxBurst field on endpoint companion descriptor is supposed to contain the number of burst minus 1. When passing that to controller drivers, we should be passing the real number instead (by incrementing 1). While doing that, also fix the assumption on dwc3 that value comes decremented by one. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- drivers/usb/gadget/composite.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3df1a1973b05..cc978d65a808 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -414,7 +414,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc)) | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc)) - | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst); + | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst - 1); params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | DWC3_DEPCFG_XFER_NOT_READY_EN; diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 390749bbb0c3..3f72110da1b0 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -117,6 +117,7 @@ int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, struct usb_ep *_ep) { + struct usb_composite_dev *cdev = get_gadget_data(g); struct usb_endpoint_descriptor *chosen_desc = NULL; struct usb_descriptor_header **speed_desc = NULL; @@ -180,10 +181,12 @@ ep_found: _ep->mult = comp_desc->bmAttributes & 0x3; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: - _ep->maxburst = comp_desc->bMaxBurst; + _ep->maxburst = comp_desc->bMaxBurst + 1; break; default: - /* Do nothing for control endpoints */ + if (comp_desc->bMaxBurst != 0) + ERROR(cdev, "ep0 bMaxBurst must be 0\n"); + _ep->maxburst = 1; break; } } -- GitLab From 1c7f6cd3f97b038e875094a8433e239f03d10955 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 25 May 2012 20:14:53 -0300 Subject: [PATCH 1238/6849] usb: fsl_mxc_udc.c : Use clk_prepare_enable/clk_disable_unprepare Prepare the clock before enabling it. Cc: Signed-off-by: Fabio Estevam Acked-by: Sascha Hauer Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_mxc_udc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index dcbc0a2e48dd..f4b5109feb3d 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c @@ -40,7 +40,7 @@ int fsl_udc_clk_init(struct platform_device *pdev) if (IS_ERR(mxc_ahb_clk)) return PTR_ERR(mxc_ahb_clk); - ret = clk_enable(mxc_ahb_clk); + ret = clk_prepare_enable(mxc_ahb_clk); if (ret < 0) { dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); goto eenahb; @@ -65,7 +65,7 @@ int fsl_udc_clk_init(struct platform_device *pdev) } } - ret = clk_enable(mxc_usb_clk); + ret = clk_prepare_enable(mxc_usb_clk); if (ret < 0) { dev_err(&pdev->dev, "clk_enable(\"usb_clk\") failed\n"); goto eenusb; @@ -79,7 +79,7 @@ eclkrate: mxc_usb_clk = NULL; egusb: if (!cpu_is_mx35()) - clk_disable(mxc_ahb_clk); + clk_disable_unprepare(mxc_ahb_clk); eenahb: if (!cpu_is_mx35()) clk_put(mxc_ahb_clk); @@ -104,7 +104,7 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) /* ULPI transceivers don't need usbpll */ if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { - clk_disable(mxc_usb_clk); + clk_disable_unprepare(mxc_usb_clk); clk_put(mxc_usb_clk); mxc_usb_clk = NULL; } @@ -113,11 +113,11 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) void fsl_udc_clk_release(void) { if (mxc_usb_clk) { - clk_disable(mxc_usb_clk); + clk_disable_unprepare(mxc_usb_clk); clk_put(mxc_usb_clk); } if (!cpu_is_mx35()) { - clk_disable(mxc_ahb_clk); + clk_disable_unprepare(mxc_ahb_clk); clk_put(mxc_ahb_clk); } } -- GitLab From 8194fea0fc308a7cdfc9333584d69cb5d428d47f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 25 May 2012 20:14:54 -0300 Subject: [PATCH 1239/6849] usb: imx_udc.c: Use clk_prepare_enable/clk_disable_unprepare Prepare the clock before enabling it. Cc: Signed-off-by: Fabio Estevam Acked-by: Sascha Hauer Signed-off-by: Felipe Balbi --- drivers/usb/gadget/imx_udc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 54034f84f992..dc5334856afe 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1432,7 +1432,7 @@ static int __init imx_udc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "can't get USB clock\n"); goto fail2; } - clk_enable(clk); + clk_prepare_enable(clk); if (clk_get_rate(clk) != 48000000) { D_INI(&pdev->dev, @@ -1496,7 +1496,7 @@ fail4: free_irq(imx_usb->usbd_int[i], imx_usb); fail3: clk_put(clk); - clk_disable(clk); + clk_disable_unprepare(clk); fail2: iounmap(base); fail1: @@ -1521,7 +1521,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev) free_irq(imx_usb->usbd_int[i], imx_usb); clk_put(imx_usb->clk); - clk_disable(imx_usb->clk); + clk_disable_unprepare(imx_usb->clk); iounmap(imx_usb->base); release_mem_region(imx_usb->res->start, resource_size(imx_usb->res)); -- GitLab From 2b97fb5a605635684f757080cdc405d8173838d5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 25 May 2012 20:14:55 -0300 Subject: [PATCH 1240/6849] usb: imx21-hcd.c: Use clk_prepare_enable/clk_disable_unprepare Prepare the clock before enabling it. Cc: Signed-off-by: Fabio Estevam Acked-by: Sascha Hauer Signed-off-by: Felipe Balbi --- drivers/usb/host/imx21-hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index ff471c1c165e..f19e2690c232 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1811,7 +1811,7 @@ static int imx21_remove(struct platform_device *pdev) usb_remove_hcd(hcd); if (res != NULL) { - clk_disable(imx21->clk); + clk_disable_unprepare(imx21->clk); clk_put(imx21->clk); iounmap(imx21->regs); release_mem_region(res->start, resource_size(res)); @@ -1884,7 +1884,7 @@ static int imx21_probe(struct platform_device *pdev) ret = clk_set_rate(imx21->clk, clk_round_rate(imx21->clk, 48000000)); if (ret) goto failed_clock_set; - ret = clk_enable(imx21->clk); + ret = clk_prepare_enable(imx21->clk); if (ret) goto failed_clock_enable; @@ -1900,7 +1900,7 @@ static int imx21_probe(struct platform_device *pdev) return 0; failed_add_hcd: - clk_disable(imx21->clk); + clk_disable_unprepare(imx21->clk); failed_clock_enable: failed_clock_set: clk_put(imx21->clk); -- GitLab From 2347fc440558993013e8132791c409239da4fc0d Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Sun, 10 Jun 2012 16:15:17 -0400 Subject: [PATCH 1241/6849] usb: gadget: Complete fsl qe/udc driver conversion commit ec39e2ae (usb: gadget: Update fsl_qe_udc to use usb_endpoint_descriptor inside the struct usb_ep) did not completely convert the fsl gadget drivers to use the desc in usb_ep as described in commit messages. Fix the macros that were still referencing the old pointer. Signed-off-by: Ben Collins Cc: Ido Shayevitz [ balbi@ti.com : brush up commit log a bit ] Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index 4c07ca9cebf3..7026919fc901 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -153,10 +153,10 @@ struct usb_ep_para{ #define USB_BUSMODE_DTB 0x02 /* Endpoint basic handle */ -#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF) +#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress & 0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN) : ((EP)->desc->bEndpointAddress \ + USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ & USB_DIR_IN) == USB_DIR_IN) /* ep0 transfer state */ -- GitLab From 535588e61a007416f46cf08b4ccb6cc73b3f6fb0 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Mon, 11 Jun 2012 18:14:16 -0700 Subject: [PATCH 1242/6849] ieee80211: definitions for Microsoft Vendor OUI and WPA OUI type Reference: http://standards.ieee.org/develop/regauth/oui/oui.txt Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index f831078182de..98c86ff657bb 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1589,6 +1589,8 @@ enum ieee80211_sa_query_action { #define WLAN_OUI_WFA 0x506f9a #define WLAN_OUI_TYPE_WFA_P2P 9 +#define WLAN_OUI_MICROSOFT 0x0050f2 +#define WLAN_OUI_TYPE_MICROSOFT_WPA 1 /* * WMM/802.11e Tspec Element -- GitLab From 1dd45581e6dc98467c539ea67ae5c847646f0efd Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Mon, 11 Jun 2012 10:23:35 -0700 Subject: [PATCH 1243/6849] mac80211: add missing kernel-doc Add a few kernel-doc descriptions that were missed during mesh development. Reported-by: Randy Dunlap Signed-off-by: Ashok Nagarajan Acked-by: Randy Dunlap Signed-off-by: Johannes Berg --- net/mac80211/sta_info.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 525ce5077e1c..a470e1123a55 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -271,6 +271,9 @@ struct sta_ampdu_mlme { * @plink_timer: peer link watch timer * @plink_timer_was_running: used by suspend/resume to restore timers * @t_offset: timing offset relative to this host + * @t_offset_setpoint: reference timing offset of this sta to be used when + * calculating clockdrift + * @ch_type: peer's channel type * @debugfs: debug filesystem info * @dead: set to true when sta is unlinked * @uploaded: set to true when sta is uploaded to the driver -- GitLab From 6878c32e5cc0e40980abe51d1f02fb453e27493e Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 25 May 2012 17:34:51 -0400 Subject: [PATCH 1244/6849] xen/blkfront: Add WARN to deal with misbehaving backends. Part of the ring structure is the 'id' field which is under control of the frontend. The frontend stamps it with "some" value (this some in this implementation being a value less than BLK_RING_SIZE), and when it gets a response expects said value to be in the response structure. We have a check for the id field when spolling new requests but not when de-spolling responses. We also add an extra check in add_id_to_freelist to make sure that the 'struct request' was not NULL - as we cannot pass a NULL to __blk_end_request_all, otherwise that crashes (and all the operations that the response is dealing with end up with __blk_end_request_all). Lastly we also print the name of the operation that failed. [v1: s/BUG/WARN/ suggested by Stefano] [v2: Add extra check in add_id_to_freelist] [v3: Redid op_name per Jan's suggestion] [v4: add const * and add WARN on failure returns] Acked-by: Jan Beulich Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 58 ++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 60eed4bdd2e4..e4fb3374dcd2 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -141,14 +141,36 @@ static int get_id_from_freelist(struct blkfront_info *info) return free; } -static void add_id_to_freelist(struct blkfront_info *info, +static int add_id_to_freelist(struct blkfront_info *info, unsigned long id) { + if (info->shadow[id].req.u.rw.id != id) + return -EINVAL; + if (info->shadow[id].request == NULL) + return -EINVAL; info->shadow[id].req.u.rw.id = info->shadow_free; info->shadow[id].request = NULL; info->shadow_free = id; + return 0; } +static const char *op_name(int op) +{ + static const char *const names[] = { + [BLKIF_OP_READ] = "read", + [BLKIF_OP_WRITE] = "write", + [BLKIF_OP_WRITE_BARRIER] = "barrier", + [BLKIF_OP_FLUSH_DISKCACHE] = "flush", + [BLKIF_OP_DISCARD] = "discard" }; + + if (op < 0 || op >= ARRAY_SIZE(names)) + return "unknown"; + + if (!names[op]) + return "reserved"; + + return names[op]; +} static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) { unsigned int end = minor + nr; @@ -746,20 +768,36 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; + /* + * The backend has messed up and given us an id that we would + * never have given to it (we stamp it up to BLK_RING_SIZE - + * look in get_id_from_freelist. + */ + if (id >= BLK_RING_SIZE) { + WARN(1, "%s: response to %s has incorrect id (%ld)\n", + info->gd->disk_name, op_name(bret->operation), id); + /* We can't safely get the 'struct request' as + * the id is busted. */ + continue; + } req = info->shadow[id].request; if (bret->operation != BLKIF_OP_DISCARD) blkif_completion(&info->shadow[id]); - add_id_to_freelist(info, id); + if (add_id_to_freelist(info, id)) { + WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n", + info->gd->disk_name, op_name(bret->operation), id); + continue; + } error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; switch (bret->operation) { case BLKIF_OP_DISCARD: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { struct request_queue *rq = info->rq; - printk(KERN_WARNING "blkfront: %s: discard op failed\n", - info->gd->disk_name); + printk(KERN_WARNING "blkfront: %s: %s op failed\n", + info->gd->disk_name, op_name(bret->operation)); error = -EOPNOTSUPP; info->feature_discard = 0; info->feature_secdiscard = 0; @@ -771,18 +809,14 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) case BLKIF_OP_FLUSH_DISKCACHE: case BLKIF_OP_WRITE_BARRIER: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { - printk(KERN_WARNING "blkfront: %s: write %s op failed\n", - info->flush_op == BLKIF_OP_WRITE_BARRIER ? - "barrier" : "flush disk cache", - info->gd->disk_name); + printk(KERN_WARNING "blkfront: %s: %s op failed\n", + info->gd->disk_name, op_name(bret->operation)); error = -EOPNOTSUPP; } if (unlikely(bret->status == BLKIF_RSP_ERROR && info->shadow[id].req.u.rw.nr_segments == 0)) { - printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n", - info->flush_op == BLKIF_OP_WRITE_BARRIER ? - "barrier" : "flush disk cache", - info->gd->disk_name); + printk(KERN_WARNING "blkfront: %s: empty %s op failed\n", + info->gd->disk_name, op_name(bret->operation)); error = -EOPNOTSUPP; } if (unlikely(error)) { -- GitLab From 4eccc579795290a58e2262fa4e9d083d7672e699 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 8 Jun 2012 13:18:51 +0200 Subject: [PATCH 1245/6849] drbd: fix access of unallocated pages and kernel panic BUG: unable to handle kernel NULL pointer dereference at (null) ... [] ? _drbd_bm_set_bits+0x151/0x240 [drbd] [] ? receive_bitmap+0x4f8/0xbc0 [drbd] This fixes an off-by-one error in the receive_bitmap() path, if run-length encoded bitmap transfer is enabled. If the bitmap is an exact multiple of PAGE_SIZE, which means the visible capacity of the drbd device is an exact multiple of 128 MiB (for 4k page size), and bitmap compression (use-rle) is enabled (which became default with 8.4), and the very last bit is dirty and reported in an rle comressed bitmap packet, we ended up trying to kmap_atomic a page pointer that does not exist (bitmap->bm_pages[last index + 1]). bug introduced by: Date: Fri Jul 24 15:33:24 2009 +0200 set bits: optimize for complete last word, fix off-by-one-word corner case made effective by: Date: Thu Dec 16 00:32:38 2010 +0100 drbd: get rid of unused debug code Long time ago, we had paranoia code in the bitmap that allocated one extra word, assigned a magic value, and checked on every occasion that the magic value was still unchanged. That debug code is unused, the extra long word complicates code a bit. Get rid of it. No-one triggered this bug in the last few years, because a large subset of our userbase is unaffected: * typically the last few blocks of a device are not modified frequently, and remain unset * use-rle was disabled by default in drbd < 8.4 * those with slightly "odd" device sizes, or * drbd internal meta data (which will skew the device size slightly, thus makes it harder to have a bug relevant device size) Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_bitmap.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index b5c5ff53cb57..fcb956bb4b4c 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -1475,10 +1475,17 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi first_word = 0; spin_lock_irq(&b->bm_lock); } - /* last page (respectively only page, for first page == last page) */ last_word = MLPP(el >> LN2_BPL); - bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); + + /* consider bitmap->bm_bits = 32768, bitmap->bm_number_of_pages = 1. (or multiples). + * ==> e = 32767, el = 32768, last_page = 2, + * and now last_word = 0. + * We do not want to touch last_page in this case, + * as we did not allocate it, it is not present in bitmap->bm_pages. + */ + if (last_word) + bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); /* possibly trailing bits. * example: (e & 63) == 63, el will be e+1. -- GitLab From 1ed25b269e3dd5ecc64f17beef9ea21745c39ca6 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 8 Jun 2012 14:09:54 +0200 Subject: [PATCH 1246/6849] drbd: fix list corruption by failing but already aborted reads If a read is aborted due to force-detach of a supposedly unresponsive local backing device, and retried on the peer, it can happen that the local request later still completes (hopefully with an error). As it may already have been completed to upper layers meanwhile, it must not be retried again now. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 9c5c84946b05..773f4e2d3c1b 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -472,12 +472,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + if (req->rq_state & RQ_LOCAL_ABORTED) { + _req_may_be_done(req, m); + break; + } __drbd_chk_io_error(mdev, false); goto_queue_for_net_read: + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + /* no point in retrying if there is no good remote data, * or we have no connection. */ if (mdev->state.pdsk != D_UP_TO_DATE) { -- GitLab From 0d5934e3c258fc5decc4103600c597086fd95a52 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 8 Jun 2012 14:17:36 +0200 Subject: [PATCH 1247/6849] drbd: fix null pointer dereference with on-congestion policy when diskless We must not look at mdev->actlog, unless we have a get_ldev() reference. It also does not make much sense to try to disconnect or pull-ahead of the peer, if we don't have good local data. Only even consider congestion policies, if our local disk is D_UP_TO_DATE. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c | 59 +++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 773f4e2d3c1b..8e93a6ac9bb6 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -770,6 +770,40 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); } +static void maybe_pull_ahead(struct drbd_conf *mdev) +{ + int congested = 0; + + /* If I don't even have good local storage, we can not reasonably try + * to pull ahead of the peer. We also need the local reference to make + * sure mdev->act_log is there. + * Note: caller has to make sure that net_conf is there. + */ + if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) + return; + + if (mdev->net_conf->cong_fill && + atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { + dev_info(DEV, "Congestion-fill threshold reached\n"); + congested = 1; + } + + if (mdev->act_log->used >= mdev->net_conf->cong_extents) { + dev_info(DEV, "Congestion-extents threshold reached\n"); + congested = 1; + } + + if (congested) { + queue_barrier(mdev); /* last barrier, after mirrored writes */ + + if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) + _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); + else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ + _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); + } + put_ldev(mdev); +} + static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) { const int rw = bio_rw(bio); @@ -977,29 +1011,8 @@ allocate_barrier: _req_mod(req, queue_for_send_oos); if (remote && - mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) { - int congested = 0; - - if (mdev->net_conf->cong_fill && - atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { - dev_info(DEV, "Congestion-fill threshold reached\n"); - congested = 1; - } - - if (mdev->act_log->used >= mdev->net_conf->cong_extents) { - dev_info(DEV, "Congestion-extents threshold reached\n"); - congested = 1; - } - - if (congested) { - queue_barrier(mdev); /* last barrier, after mirrored writes */ - - if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) - _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); - else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ - _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); - } - } + mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) + maybe_pull_ahead(mdev); spin_unlock_irq(&mdev->req_lock); kfree(b); /* if someone else has beaten us to it... */ -- GitLab From cb9dd49e11f83d548c822d7022ac180b0518b25c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 11 Jun 2012 19:03:32 -0300 Subject: [PATCH 1248/6849] perf tools: Fix synthesizing tracepoint names from the perf.data headers We need to use the per event info snapshoted at record time to synthesize the events name, so do it just after reading the perf.data headers, when we already processed the /sys events data, otherwise we'll end up using the local /sys that only by sheer luck will have the same tracepoint ID -> real event association. Example: # uname -a Linux felicio.ghostprotocols.net 3.4.0-rc5+ #1 SMP Sat May 19 15:27:11 BRT 2012 x86_64 x86_64 x86_64 GNU/Linux # perf record -e sched:sched_switch usleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.015 MB perf.data (~648 samples) ] # cat /t/events/sched/sched_switch/id 279 # perf evlist -v sched:sched_switch: sample_freq=1, type: 2, config: 279, size: 80, sample_type: 1159, read_format: 7, disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, sample_id_all: 1, exclude_guest: 1 # So on the above machine the sched:sched_switch has tracepoint id 279, but on the machine were we'll analyse it it has a different id: $ cat /t/events/sched/sched_switch/id 56 $ perf evlist -i /tmp/perf.data kmem:mm_balancedirty_writeout $ cat /t/events/kmem/mm_balancedirty_writeout/id 279 With this fix: $ perf evlist -i /tmp/perf.data sched:sched_switch Reported-by: Dmitry Antipov Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-auwks8fpuhmrdpiefs55o5oz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 4f9b247fb312..e909d43cf542 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2093,6 +2093,35 @@ static int read_attr(int fd, struct perf_header *ph, return ret <= 0 ? -1 : 0; } +static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) +{ + struct event_format *event = trace_find_event(evsel->attr.config); + char bf[128]; + + if (event == NULL) + return -1; + + snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); + evsel->name = strdup(bf); + if (event->name == NULL) + return -1; + + return 0; +} + +static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) +{ + struct perf_evsel *pos; + + list_for_each_entry(pos, &evlist->entries, node) { + if (pos->attr.type == PERF_TYPE_TRACEPOINT && + perf_evsel__set_tracepoint_name(pos)) + return -1; + } + + return 0; +} + int perf_session__read_header(struct perf_session *session, int fd) { struct perf_header *header = &session->header; @@ -2174,6 +2203,9 @@ int perf_session__read_header(struct perf_session *session, int fd) lseek(fd, header->data_offset, SEEK_SET); + if (perf_evlist__set_tracepoint_names(session->evlist)) + goto out_delete_evlist; + header->frozen = 1; return 0; out_errno: -- GitLab From 83452c6a43d06dfbc7f78b0eafe6664c95a3895c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:18 +0200 Subject: [PATCH 1249/6849] x86/PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Cc: x86@kernel.org Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- arch/x86/kernel/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 03920a15a632..1b27de563561 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -512,7 +512,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, #if defined(CONFIG_PCI) && defined(CONFIG_NUMA) /* Set correct numa_node information for AMD NB functions */ -static void __init quirk_amd_nb_node(struct pci_dev *dev) +static void __devinit quirk_amd_nb_node(struct pci_dev *dev) { struct pci_dev *nb_ht; unsigned int devfn; -- GitLab From b99ea85a3acff53151322a1c882f217375b1300e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:19 +0200 Subject: [PATCH 1250/6849] PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- drivers/pci/quirks.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2a7521677541..993cec88c5b4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx) * workaround applied too * [Info kindly provided by ALi] */ -static void __init quirk_alimagik(struct pci_dev *dev) +static void __devinit quirk_alimagik(struct pci_dev *dev) { if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) { dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n"); @@ -789,7 +789,7 @@ static void __devinit quirk_amd_ioapic(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic); -static void __init quirk_ioapic_rmw(struct pci_dev *dev) +static void __devinit quirk_ioapic_rmw(struct pci_dev *dev) { if (dev->devfn == 0 && dev->bus->number == 0) sis_apic_bug = 1; @@ -801,7 +801,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw); * Some settings of MMRBC can lead to data corruption so block changes. * See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide */ -static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev) +static void __devinit quirk_amd_8131_mmrbc(struct pci_dev *dev) { if (dev->subordinate && dev->revision <= 0x12) { dev_info(&dev->dev, "AMD8131 rev %x detected; " @@ -1082,7 +1082,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB /* * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same */ -static void __init quirk_ide_samemode(struct pci_dev *pdev) +static void __devinit quirk_ide_samemode(struct pci_dev *pdev) { u8 prog; @@ -1121,7 +1121,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, /* This was originally an Alpha specific thing, but it really fits here. * The i82375 PCI/EISA bridge appears as non-classified. Fix that. */ -static void __init quirk_eisa_bridge(struct pci_dev *dev) +static void __devinit quirk_eisa_bridge(struct pci_dev *dev) { dev->class = PCI_CLASS_BRIDGE_EISA << 8; } @@ -1155,7 +1155,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e */ static int asus_hides_smbus; -static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) +static void __devinit asus_hides_smbus_hostbridge(struct pci_dev *dev) { if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) { if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB) @@ -1538,7 +1538,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3 #endif #ifdef CONFIG_X86_IO_APIC -static void __init quirk_alder_ioapic(struct pci_dev *pdev) +static void __devinit quirk_alder_ioapic(struct pci_dev *pdev) { int i; @@ -1777,7 +1777,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS, qui * but the PIO transfers won't work if BAR0 falls at the odd 8 bytes. * Re-allocate the region if needed... */ -static void __init quirk_tc86c001_ide(struct pci_dev *dev) +static void __devinit quirk_tc86c001_ide(struct pci_dev *dev) { struct resource *r = &dev->resource[0]; @@ -2169,7 +2169,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1); * aware of it. Instead of setting the flag on all busses in the * machine, simply disable MSI globally. */ -static void __init quirk_disable_all_msi(struct pci_dev *dev) +static void __devinit quirk_disable_all_msi(struct pci_dev *dev) { pci_no_msi(); dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n"); -- GitLab From 8ff255afb022b8e183c7aa1ecc4ba8d0563e1e17 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:20 +0200 Subject: [PATCH 1251/6849] alpha/PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- arch/alpha/kernel/pci.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 1a629636cc16..026d49f28de3 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -59,15 +59,13 @@ struct pci_controller *pci_isa_hose; * Quirks. */ -static void __init -quirk_isa_bridge(struct pci_dev *dev) +static void __devinit quirk_isa_bridge(struct pci_dev *dev) { dev->class = PCI_CLASS_BRIDGE_ISA << 8; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_isa_bridge); -static void __init -quirk_cypress(struct pci_dev *dev) +static void __devinit quirk_cypress(struct pci_dev *dev) { /* The Notorious Cy82C693 chip. */ @@ -106,8 +104,7 @@ quirk_cypress(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, quirk_cypress); /* Called for each device after PCI setup is done. */ -static void __init -pcibios_fixup_final(struct pci_dev *dev) +static void __devinit pcibios_fixup_final(struct pci_dev *dev) { unsigned int class = dev->class >> 8; -- GitLab From f39acb1f00059a7fada1971dcd6374fbff9b3238 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:21 +0200 Subject: [PATCH 1252/6849] arm/PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Cc: Russell King Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- arch/arm/kernel/bios32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 25552508c3fd..1c1a0e237a33 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -253,7 +253,7 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); -static void __init pci_fixup_it8152(struct pci_dev *dev) +static void __devinit pci_fixup_it8152(struct pci_dev *dev) { int i; /* fixup for ITE 8152 devices */ -- GitLab From a9149164280718ac244d5b5a246de5746f6aad4b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:22 +0200 Subject: [PATCH 1253/6849] frv/PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Cc: David Howells Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- arch/frv/mb93090-mb00/pci-vdk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index 6b0b82ff4419..d04ed14bbf0c 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c @@ -268,7 +268,7 @@ static void __init pci_fixup_umc_ide(struct pci_dev *d) d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; } -static void __init pci_fixup_ide_bases(struct pci_dev *d) +static void __devinit pci_fixup_ide_bases(struct pci_dev *d) { int i; @@ -287,7 +287,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) } } -static void __init pci_fixup_ide_trash(struct pci_dev *d) +static void __devinit pci_fixup_ide_trash(struct pci_dev *d) { int i; -- GitLab From ad805758c0eb25bce7b2e3b298d63dc62a1bc71c Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 11 Jun 2012 05:27:07 +0000 Subject: [PATCH 1254/6849] PCI: add ACS validation utility In a PCI environment, transactions aren't always required to reach the root bus before being re-routed. Intermediate switches between an endpoint and the root bus can redirect DMA back downstream before things like IOMMUs have a chance to intervene. Legacy PCI is always susceptible to this as it operates on a shared bus. PCIe added a new capability to describe and control this behavior, Access Control Services, or ACS. The utility function pci_acs_enabled() allows us to test the ACS capabilities of an individual devices against a set of flags while pci_acs_path_enabled() tests a complete path from a given downstream device up to the specified upstream device. We also include the ability to add device specific tests as it's likely we'll see devices that do not implement ACS, but want to indicate support for various capabilities in this space. Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/quirks.c | 33 +++++++++++++++++++++ include/linux/pci.h | 10 ++++++- 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..1ccf7d49f522 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2359,6 +2359,75 @@ void pci_enable_acs(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); } +/** + * pci_acs_enabled - test ACS against required flags for a given device + * @pdev: device to test + * @acs_flags: required PCI ACS flags + * + * Return true if the device supports the provided flags. Automatically + * filters out flags that are not implemented on multifunction devices. + */ +bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags) +{ + int pos, ret; + u16 ctrl; + + ret = pci_dev_specific_acs_enabled(pdev, acs_flags); + if (ret >= 0) + return ret > 0; + + if (!pci_is_pcie(pdev)) + return false; + + /* Filter out flags not applicable to multifunction */ + if (pdev->multifunction) + acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | + PCI_ACS_EC | PCI_ACS_DT); + + if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM || + pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || + pdev->multifunction) { + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS); + if (!pos) + return false; + + pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl); + if ((ctrl & acs_flags) != acs_flags) + return false; + } + + return true; +} + +/** + * pci_acs_path_enable - test ACS flags from start to end in a hierarchy + * @start: starting downstream device + * @end: ending upstream device or NULL to search to the root bus + * @acs_flags: required flags + * + * Walk up a device tree from start to end testing PCI ACS support. If + * any step along the way does not support the required flags, return false. + */ +bool pci_acs_path_enabled(struct pci_dev *start, + struct pci_dev *end, u16 acs_flags) +{ + struct pci_dev *pdev, *parent = start; + + do { + pdev = parent; + + if (!pci_acs_enabled(pdev, acs_flags)) + return false; + + if (pci_is_root_bus(pdev->bus)) + return (end == NULL); + + parent = pdev->bus->self; + } while (pdev != end); + + return true; +} + /** * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge * @dev: the PCI device diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index acd3956b44bd..27e2c8f4ec73 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3230,3 +3230,36 @@ struct pci_dev *pci_get_dma_source(struct pci_dev *dev) return pci_dev_get(dev); } + +static const struct pci_dev_acs_enabled { + u16 vendor; + u16 device; + int (*acs_enabled)(struct pci_dev *dev, u16 acs_flags); +} pci_dev_acs_enabled[] = { + { 0 } +}; + +int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags) +{ + const struct pci_dev_acs_enabled *i; + int ret; + + /* + * Allow devices that do not expose standard PCIe ACS capabilities + * or control to indicate their support here. Multi-function express + * devices which do not allow internal peer-to-peer between functions, + * but do not implement PCIe ACS may wish to return true here. + */ + for (i = pci_dev_acs_enabled; i->acs_enabled; i++) { + if ((i->vendor == dev->vendor || + i->vendor == (u16)PCI_ANY_ID) && + (i->device == dev->device || + i->device == (u16)PCI_ANY_ID)) { + ret = i->acs_enabled(dev, acs_flags); + if (ret >= 0) + return ret; + } + } + + return -ENOTTY; +} diff --git a/include/linux/pci.h b/include/linux/pci.h index 39983be7b25b..dd7af0f37b3a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1490,6 +1490,7 @@ enum pci_fixup_pass { #ifdef CONFIG_PCI_QUIRKS void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); struct pci_dev *pci_get_dma_source(struct pci_dev *dev); +int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); #else static inline void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} @@ -1497,6 +1498,11 @@ static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev) { return pci_dev_get(dev); } +static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev, + u16 acs_flags) +{ + return -ENOTTY; +} #endif void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); @@ -1599,7 +1605,9 @@ static inline bool pci_is_pcie(struct pci_dev *dev) } void pci_request_acs(void); - +bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags); +bool pci_acs_path_enabled(struct pci_dev *start, + struct pci_dev *end, u16 acs_flags); #define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ #define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT) -- GitLab From c63587d7f5b9db84e71daf5962dc0394eb657da2 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 11 Jun 2012 05:27:19 +0000 Subject: [PATCH 1255/6849] PCI: export pci_user functions for use by other drivers VFIO PCI support will make use of these for user-initiated PCI config accesses. Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas --- drivers/pci/access.c | 6 ++++-- drivers/pci/pci.h | 7 ------- include/linux/pci.h | 8 ++++++++ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 2a581642c237..ba91a7e17519 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -162,7 +162,8 @@ int pci_user_read_config_##size \ if (ret > 0) \ ret = -EINVAL; \ return ret; \ -} +} \ +EXPORT_SYMBOL_GPL(pci_user_read_config_##size); /* Returns 0 on success, negative values indicate error. */ #define PCI_USER_WRITE_CONFIG(size,type) \ @@ -181,7 +182,8 @@ int pci_user_write_config_##size \ if (ret > 0) \ ret = -EINVAL; \ return ret; \ -} +} \ +EXPORT_SYMBOL_GPL(pci_user_write_config_##size); PCI_USER_READ_CONFIG(byte, u8) PCI_USER_READ_CONFIG(word, u16) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e4943479b234..f2dcc46bdece 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -86,13 +86,6 @@ static inline bool pci_is_bridge(struct pci_dev *pci_dev) return !!(pci_dev->subordinate); } -extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); -extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); -extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); -extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); -extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); -extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); - struct pci_vpd_ops { ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); diff --git a/include/linux/pci.h b/include/linux/pci.h index dd7af0f37b3a..9d04599c6bd9 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -777,6 +777,14 @@ static inline int pci_write_config_dword(const struct pci_dev *dev, int where, return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); } +/* user-space driven config access */ +int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); +int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); +int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); +int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); +int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); +int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); + int __must_check pci_enable_device(struct pci_dev *dev); int __must_check pci_enable_device_io(struct pci_dev *dev); int __must_check pci_enable_device_mem(struct pci_dev *dev); -- GitLab From a6961651408afa9387d6df43c4a1dc4fd35dcb1b Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 11 Jun 2012 05:27:33 +0000 Subject: [PATCH 1256/6849] PCI: create common pcibios_err_to_errno For returning errors out to non-PCI code. Re-name xen's version. Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas --- drivers/xen/xen-pciback/conf_space.c | 6 +++--- include/linux/pci.h | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c index 30d7be026c18..46ae0f9f02ad 100644 --- a/drivers/xen/xen-pciback/conf_space.c +++ b/drivers/xen/xen-pciback/conf_space.c @@ -124,7 +124,7 @@ static inline u32 merge_value(u32 val, u32 new_val, u32 new_val_mask, return val; } -static int pcibios_err_to_errno(int err) +static int xen_pcibios_err_to_errno(int err) { switch (err) { case PCIBIOS_SUCCESSFUL: @@ -202,7 +202,7 @@ out: pci_name(dev), size, offset, value); *ret_val = value; - return pcibios_err_to_errno(err); + return xen_pcibios_err_to_errno(err); } int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value) @@ -290,7 +290,7 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value) } } - return pcibios_err_to_errno(err); + return xen_pcibios_err_to_errno(err); } void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev) diff --git a/include/linux/pci.h b/include/linux/pci.h index 9d04599c6bd9..a691f62bcf89 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -474,6 +474,32 @@ static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev) { return false; #define PCIBIOS_SET_FAILED 0x88 #define PCIBIOS_BUFFER_TOO_SMALL 0x89 +/* + * Translate above to generic errno for passing back through non-pci. + */ +static inline int pcibios_err_to_errno(int err) +{ + if (err <= PCIBIOS_SUCCESSFUL) + return err; /* Assume already errno */ + + switch (err) { + case PCIBIOS_FUNC_NOT_SUPPORTED: + return -ENOENT; + case PCIBIOS_BAD_VENDOR_ID: + return -EINVAL; + case PCIBIOS_DEVICE_NOT_FOUND: + return -ENODEV; + case PCIBIOS_BAD_REGISTER_NUMBER: + return -EFAULT; + case PCIBIOS_SET_FAILED: + return -EIO; + case PCIBIOS_BUFFER_TOO_SMALL: + return -ENOSPC; + } + + return -ENOTTY; +} + /* Low-level architecture-dependent routines */ struct pci_ops { -- GitLab From a0dee2ed0cdc666b5622f1fc74979355a6b36850 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 11 Jun 2012 05:27:45 +0000 Subject: [PATCH 1257/6849] PCI: misc pci_reg additions Fill in many missing definitions and add sizeof fields for many sections allowing for more extensive config parsing. Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas --- include/linux/pci_regs.h | 113 ++++++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 12 deletions(-) diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 4b608f543412..526d2c4bc3a6 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -26,6 +26,7 @@ * Under PCI, each device has 256 bytes of configuration address space, * of which the first 64 bytes are standardized as follows: */ +#define PCI_STD_HEADER_SIZEOF 64 #define PCI_VENDOR_ID 0x00 /* 16 bits */ #define PCI_DEVICE_ID 0x02 /* 16 bits */ #define PCI_COMMAND 0x04 /* 16 bits */ @@ -209,9 +210,12 @@ #define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ #define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ +#define PCI_CAP_ID_SECDEV 0x0F /* Secure Device */ #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ +#define PCI_CAP_ID_SATA 0x12 /* SATA Data/Index Conf. */ #define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ +#define PCI_CAP_ID_MAX PCI_CAP_ID_AF #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ #define PCI_CAP_SIZEOF 4 @@ -276,6 +280,7 @@ #define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ #define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ #define PCI_VPD_DATA 4 /* 32-bits of data returned here */ +#define PCI_CAP_VPD_SIZEOF 8 /* Slot Identification */ @@ -297,8 +302,10 @@ #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ #define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */ +#define PCI_MSI_PENDING_32 16 /* Pending intrs for 32-bit devices */ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ #define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */ +#define PCI_MSI_PENDING_64 20 /* Pending intrs for 64-bit devices */ /* MSI-X registers */ #define PCI_MSIX_FLAGS 2 @@ -308,6 +315,7 @@ #define PCI_MSIX_TABLE 4 #define PCI_MSIX_PBA 8 #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) +#define PCI_CAP_MSIX_SIZEOF 12 /* size of MSIX registers */ /* MSI-X entry's format */ #define PCI_MSIX_ENTRY_SIZE 16 @@ -338,6 +346,7 @@ #define PCI_AF_CTRL_FLR 0x01 #define PCI_AF_STATUS 5 #define PCI_AF_STATUS_TP 0x01 +#define PCI_CAP_AF_SIZEOF 6 /* size of AF registers */ /* PCI-X registers */ @@ -374,6 +383,10 @@ #define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */ #define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ #define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ +#define PCI_X_ECC_CSR 8 /* ECC control and status */ +#define PCI_CAP_PCIX_SIZEOF_V0 8 /* size of registers for Version 0 */ +#define PCI_CAP_PCIX_SIZEOF_V1 24 /* size for Version 1 */ +#define PCI_CAP_PCIX_SIZEOF_V2 PCI_CAP_PCIX_SIZEOF_V1 /* Same for v2 */ /* PCI Bridge Subsystem ID registers */ @@ -462,6 +475,7 @@ #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ #define PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ #define PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20 /* v1 endpoints end here */ #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ #define PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */ #define PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */ @@ -521,6 +535,7 @@ #define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */ #define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */ #define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints end here */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ @@ -529,23 +544,43 @@ #define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) -#define PCI_EXT_CAP_ID_ERR 1 -#define PCI_EXT_CAP_ID_VC 2 -#define PCI_EXT_CAP_ID_DSN 3 -#define PCI_EXT_CAP_ID_PWR 4 -#define PCI_EXT_CAP_ID_VNDR 11 -#define PCI_EXT_CAP_ID_ACS 13 -#define PCI_EXT_CAP_ID_ARI 14 -#define PCI_EXT_CAP_ID_ATS 15 -#define PCI_EXT_CAP_ID_SRIOV 16 -#define PCI_EXT_CAP_ID_PRI 19 -#define PCI_EXT_CAP_ID_LTR 24 -#define PCI_EXT_CAP_ID_PASID 27 +#define PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */ +#define PCI_EXT_CAP_ID_VC 0x02 /* Virtual Channel Capability */ +#define PCI_EXT_CAP_ID_DSN 0x03 /* Device Serial Number */ +#define PCI_EXT_CAP_ID_PWR 0x04 /* Power Budgeting */ +#define PCI_EXT_CAP_ID_RCLD 0x05 /* Root Complex Link Declaration */ +#define PCI_EXT_CAP_ID_RCILC 0x06 /* Root Complex Internal Link Control */ +#define PCI_EXT_CAP_ID_RCEC 0x07 /* Root Complex Event Collector */ +#define PCI_EXT_CAP_ID_MFVC 0x08 /* Multi-Function VC Capability */ +#define PCI_EXT_CAP_ID_VC9 0x09 /* same as _VC */ +#define PCI_EXT_CAP_ID_RCRB 0x0A /* Root Complex RB? */ +#define PCI_EXT_CAP_ID_VNDR 0x0B /* Vendor Specific */ +#define PCI_EXT_CAP_ID_CAC 0x0C /* Config Access - obsolete */ +#define PCI_EXT_CAP_ID_ACS 0x0D /* Access Control Services */ +#define PCI_EXT_CAP_ID_ARI 0x0E /* Alternate Routing ID */ +#define PCI_EXT_CAP_ID_ATS 0x0F /* Address Translation Services */ +#define PCI_EXT_CAP_ID_SRIOV 0x10 /* Single Root I/O Virtualization */ +#define PCI_EXT_CAP_ID_MRIOV 0x11 /* Multi Root I/O Virtualization */ +#define PCI_EXT_CAP_ID_MCAST 0x12 /* Multicast */ +#define PCI_EXT_CAP_ID_PRI 0x13 /* Page Request Interface */ +#define PCI_EXT_CAP_ID_AMD_XXX 0x14 /* reserved for AMD */ +#define PCI_EXT_CAP_ID_REBAR 0x15 /* resizable BAR */ +#define PCI_EXT_CAP_ID_DPA 0x16 /* dynamic power alloc */ +#define PCI_EXT_CAP_ID_TPH 0x17 /* TPH request */ +#define PCI_EXT_CAP_ID_LTR 0x18 /* latency tolerance reporting */ +#define PCI_EXT_CAP_ID_SECPCI 0x19 /* Secondary PCIe */ +#define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */ +#define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PASID + +#define PCI_EXT_CAP_DSN_SIZEOF 12 +#define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ #define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ #define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ +#define PCI_ERR_UNC_SURPDN 0x00000020 /* Surprise Down */ #define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ #define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */ #define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */ @@ -555,6 +590,11 @@ #define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */ #define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */ #define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */ +#define PCI_ERR_UNC_ACSV 0x00200000 /* ACS Violation */ +#define PCI_ERR_UNC_INTN 0x00400000 /* internal error */ +#define PCI_ERR_UNC_MCBTLP 0x00800000 /* MC blocked TLP */ +#define PCI_ERR_UNC_ATOMEG 0x01000000 /* Atomic egress blocked */ +#define PCI_ERR_UNC_TLPPRE 0x02000000 /* TLP prefix blocked */ #define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */ /* Same bits as above */ #define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */ @@ -565,6 +605,9 @@ #define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */ #define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */ #define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */ +#define PCI_ERR_COR_ADV_NFAT 0x00002000 /* Advisory Non-Fatal */ +#define PCI_ERR_COR_INTERNAL 0x00004000 /* Corrected Internal */ +#define PCI_ERR_COR_LOG_OVER 0x00008000 /* Header Log Overflow */ #define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */ /* Same bits as above */ #define PCI_ERR_CAP 24 /* Advanced Error Capabilities */ @@ -596,12 +639,18 @@ /* Virtual Channel */ #define PCI_VC_PORT_REG1 4 +#define PCI_VC_REG1_EVCC 0x7 /* extended vc count */ #define PCI_VC_PORT_REG2 8 +#define PCI_VC_REG2_32_PHASE 0x2 +#define PCI_VC_REG2_64_PHASE 0x4 +#define PCI_VC_REG2_128_PHASE 0x8 #define PCI_VC_PORT_CTRL 12 #define PCI_VC_PORT_STATUS 14 #define PCI_VC_RES_CAP 16 #define PCI_VC_RES_CTRL 20 #define PCI_VC_RES_STATUS 26 +#define PCI_CAP_VC_BASE_SIZEOF 0x10 +#define PCI_CAP_VC_PER_VC_SIZEOF 0x0C /* Power Budgeting */ #define PCI_PWR_DSR 4 /* Data Select Register */ @@ -614,6 +663,7 @@ #define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */ #define PCI_PWR_CAP 12 /* Capability */ #define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ +#define PCI_EXT_CAP_PWR_SIZEOF 16 /* * Hypertransport sub capability types @@ -646,6 +696,8 @@ #define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */ #define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ #define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ +#define HT_CAP_SIZEOF_LONG 28 /* slave & primary */ +#define HT_CAP_SIZEOF_SHORT 24 /* host & secondary */ /* Alternative Routing-ID Interpretation */ #define PCI_ARI_CAP 0x04 /* ARI Capability Register */ @@ -656,6 +708,7 @@ #define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ #define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ #define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ +#define PCI_EXT_CAP_ARI_SIZEOF 8 /* Address Translation Service */ #define PCI_ATS_CAP 0x04 /* ATS Capability Register */ @@ -665,6 +718,7 @@ #define PCI_ATS_CTRL_ENABLE 0x8000 /* ATS Enable */ #define PCI_ATS_CTRL_STU(x) ((x) & 0x1f) /* Smallest Translation Unit */ #define PCI_ATS_MIN_STU 12 /* shift of minimum STU block */ +#define PCI_EXT_CAP_ATS_SIZEOF 8 /* Page Request Interface */ #define PCI_PRI_CTRL 0x04 /* PRI control register */ @@ -676,6 +730,7 @@ #define PCI_PRI_STATUS_STOPPED 0x100 /* PRI Stopped */ #define PCI_PRI_MAX_REQ 0x08 /* PRI max reqs supported */ #define PCI_PRI_ALLOC_REQ 0x0c /* PRI max reqs allowed */ +#define PCI_EXT_CAP_PRI_SIZEOF 16 /* PASID capability */ #define PCI_PASID_CAP 0x04 /* PASID feature register */ @@ -685,6 +740,7 @@ #define PCI_PASID_CTRL_ENABLE 0x01 /* Enable bit */ #define PCI_PASID_CTRL_EXEC 0x02 /* Exec permissions Enable */ #define PCI_PASID_CTRL_PRIV 0x04 /* Priviledge Mode Enable */ +#define PCI_EXT_CAP_PASID_SIZEOF 8 /* Single Root I/O Virtualization */ #define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */ @@ -716,12 +772,14 @@ #define PCI_SRIOV_VFM_MI 0x1 /* Dormant.MigrateIn */ #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ +#define PCI_EXT_CAP_SRIOV_SIZEOF 64 #define PCI_LTR_MAX_SNOOP_LAT 0x4 #define PCI_LTR_MAX_NOSNOOP_LAT 0x6 #define PCI_LTR_VALUE_MASK 0x000003ff #define PCI_LTR_SCALE_MASK 0x00001c00 #define PCI_LTR_SCALE_SHIFT 10 +#define PCI_EXT_CAP_LTR_SIZEOF 8 /* Access Control Service */ #define PCI_ACS_CAP 0x04 /* ACS Capability Register */ @@ -732,7 +790,38 @@ #define PCI_ACS_UF 0x10 /* Upstream Forwarding */ #define PCI_ACS_EC 0x20 /* P2P Egress Control */ #define PCI_ACS_DT 0x40 /* Direct Translated P2P */ +#define PCI_ACS_EGRESS_BITS 0x05 /* ACS Egress Control Vector Size */ #define PCI_ACS_CTRL 0x06 /* ACS Control Register */ #define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */ +#define PCI_VSEC_HDR 4 /* extended cap - vendor specific */ +#define PCI_VSEC_HDR_LEN_SHIFT 20 /* shift for length field */ + +/* sata capability */ +#define PCI_SATA_REGS 4 /* SATA REGs specifier */ +#define PCI_SATA_REGS_MASK 0xF /* location - BAR#/inline */ +#define PCI_SATA_REGS_INLINE 0xF /* REGS in config space */ +#define PCI_SATA_SIZEOF_SHORT 8 +#define PCI_SATA_SIZEOF_LONG 16 + +/* resizable BARs */ +#define PCI_REBAR_CTRL 8 /* control register */ +#define PCI_REBAR_CTRL_NBAR_MASK (7 << 5) /* mask for # bars */ +#define PCI_REBAR_CTRL_NBAR_SHIFT 5 /* shift for # bars */ + +/* dynamic power allocation */ +#define PCI_DPA_CAP 4 /* capability register */ +#define PCI_DPA_CAP_SUBSTATE_MASK 0x1F /* # substates - 1 */ +#define PCI_DPA_BASE_SIZEOF 16 /* size with 0 substates */ + +/* TPH Requester */ +#define PCI_TPH_CAP 4 /* capability register */ +#define PCI_TPH_CAP_LOC_MASK 0x600 /* location mask */ +#define PCI_TPH_LOC_NONE 0x000 /* no location */ +#define PCI_TPH_LOC_CAP 0x200 /* in capability */ +#define PCI_TPH_LOC_MSIX 0x400 /* in MSI-X */ +#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* st table mask */ +#define PCI_TPH_CAP_ST_SHIFT 16 /* st table shift */ +#define PCI_TPH_BASE_SIZEOF 12 /* size with no st table */ + #endif /* LINUX_PCI_REGS_H */ -- GitLab From f762470b522014ce4ebda3ecac74eb6658da7d9d Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:39 +0530 Subject: [PATCH 1258/6849] Input: tegra-kbc - add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren Acked-by: Dmitry Torokhov --- drivers/input/keyboard/tegra-kbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 4ffe64d53107..2c1c9ed1bd9f 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -492,7 +492,7 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) unsigned int debounce_cnt; u32 val = 0; - clk_enable(kbc->clk); + clk_prepare_enable(kbc->clk); /* Reset the KBC controller to clear all previous status.*/ tegra_periph_reset_assert(kbc->clk); @@ -556,7 +556,7 @@ static void tegra_kbc_stop(struct tegra_kbc *kbc) disable_irq(kbc->irq); del_timer_sync(&kbc->timer); - clk_disable(kbc->clk); + clk_disable_unprepare(kbc->clk); } static int tegra_kbc_open(struct input_dev *dev) -- GitLab From cb53417efc726f3c243eaaeb9fce1d15bda05521 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:40 +0530 Subject: [PATCH 1259/6849] spi/tegra: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Cc: grant.likely@secretlab.ca cc: spi-devel-general@lists.sourceforge.net Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- drivers/spi/spi-tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index ae6d78a3e912..7f99ff3553a6 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -261,7 +261,7 @@ static void spi_tegra_start_transfer(struct spi_device *spi, clk_set_rate(tspi->clk, speed); if (tspi->cur_speed == 0) - clk_enable(tspi->clk); + clk_prepare_enable(tspi->clk); tspi->cur_speed = speed; @@ -373,7 +373,7 @@ static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) spi = m->state; spi_tegra_start_message(spi, m); } else { - clk_disable(tspi->clk); + clk_disable_unprepare(tspi->clk); tspi->cur_speed = 0; } } -- GitLab From 61c3b1971ad4c71c99919da949ac2043dfac8ee7 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:41 +0530 Subject: [PATCH 1260/6849] staging: nvec: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Cc: gregkh@linuxfoundation.org Cc: ac100@lists.launchpad.net Cc: devel@driverdev.osuosl.org Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren Acked-by: Marc Dietrich --- drivers/staging/nvec/nvec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 3c60088871e0..9356886f489b 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -675,7 +675,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) { u32 val; - clk_enable(nvec->i2c_clk); + clk_prepare_enable(nvec->i2c_clk); tegra_periph_reset_assert(nvec->i2c_clk); udelay(2); @@ -695,14 +695,14 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) enable_irq(nvec->irq); - clk_disable(nvec->i2c_clk); + clk_disable_unprepare(nvec->i2c_clk); } static void nvec_disable_i2c_slave(struct nvec_chip *nvec) { disable_irq(nvec->irq); writel(I2C_SL_NEWSL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG); - clk_disable(nvec->i2c_clk); + clk_disable_unprepare(nvec->i2c_clk); } static void nvec_power_off(void) @@ -812,7 +812,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) tegra_init_i2c_slave(nvec); - clk_enable(i2c_clk); + clk_prepare_enable(i2c_clk); /* enable event reporting */ -- GitLab From 65d2bdd343bd07c8de7df7352186bfe57994b5e7 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:42 +0530 Subject: [PATCH 1261/6849] ASoC: tegra: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren Acked-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 4 ++-- sound/soc/tegra/tegra20_spdif.c | 4 ++-- sound/soc/tegra/tegra30_ahub.c | 8 ++++---- sound/soc/tegra/tegra30_i2s.c | 4 ++-- sound/soc/tegra/tegra_asoc_utils.c | 12 ++++++------ 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0c7af63d444b..1647dbfe74b5 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -62,7 +62,7 @@ static int tegra20_i2s_runtime_suspend(struct device *dev) { struct tegra20_i2s *i2s = dev_get_drvdata(dev); - clk_disable(i2s->clk_i2s); + clk_disable_unprepare(i2s->clk_i2s); return 0; } @@ -72,7 +72,7 @@ static int tegra20_i2s_runtime_resume(struct device *dev) struct tegra20_i2s *i2s = dev_get_drvdata(dev); int ret; - ret = clk_enable(i2s->clk_i2s); + ret = clk_prepare_enable(i2s->clk_i2s); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); return ret; diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index f9b57418bd08..2262e4fdec2a 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -54,7 +54,7 @@ static int tegra20_spdif_runtime_suspend(struct device *dev) { struct tegra20_spdif *spdif = dev_get_drvdata(dev); - clk_disable(spdif->clk_spdif_out); + clk_disable_unprepare(spdif->clk_spdif_out); return 0; } @@ -64,7 +64,7 @@ static int tegra20_spdif_runtime_resume(struct device *dev) struct tegra20_spdif *spdif = dev_get_drvdata(dev); int ret; - ret = clk_enable(spdif->clk_spdif_out); + ret = clk_prepare_enable(spdif->clk_spdif_out); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); return ret; diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 57cd419f743e..1efb822d3916 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -56,8 +56,8 @@ static int tegra30_ahub_runtime_suspend(struct device *dev) regcache_cache_only(ahub->regmap_apbif, true); regcache_cache_only(ahub->regmap_ahub, true); - clk_disable(ahub->clk_apbif); - clk_disable(ahub->clk_d_audio); + clk_disable_unprepare(ahub->clk_apbif); + clk_disable_unprepare(ahub->clk_d_audio); return 0; } @@ -77,12 +77,12 @@ static int tegra30_ahub_runtime_resume(struct device *dev) { int ret; - ret = clk_enable(ahub->clk_d_audio); + ret = clk_prepare_enable(ahub->clk_d_audio); if (ret) { dev_err(dev, "clk_enable d_audio failed: %d\n", ret); return ret; } - ret = clk_enable(ahub->clk_apbif); + ret = clk_prepare_enable(ahub->clk_apbif); if (ret) { dev_err(dev, "clk_enable apbif failed: %d\n", ret); clk_disable(ahub->clk_d_audio); diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 8596032985dc..d308faaae148 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -62,7 +62,7 @@ static int tegra30_i2s_runtime_suspend(struct device *dev) regcache_cache_only(i2s->regmap, true); - clk_disable(i2s->clk_i2s); + clk_disable_unprepare(i2s->clk_i2s); return 0; } @@ -72,7 +72,7 @@ static int tegra30_i2s_runtime_resume(struct device *dev) struct tegra30_i2s *i2s = dev_get_drvdata(dev); int ret; - ret = clk_enable(i2s->clk_i2s); + ret = clk_prepare_enable(i2s->clk_i2s); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); return ret; diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index 9515ce58ea02..6872c77a1196 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -69,9 +69,9 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, data->set_baseclock = 0; data->set_mclk = 0; - clk_disable(data->clk_cdev1); - clk_disable(data->clk_pll_a_out0); - clk_disable(data->clk_pll_a); + clk_disable_unprepare(data->clk_cdev1); + clk_disable_unprepare(data->clk_pll_a_out0); + clk_disable_unprepare(data->clk_pll_a); err = clk_set_rate(data->clk_pll_a, new_baseclock); if (err) { @@ -87,19 +87,19 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */ - err = clk_enable(data->clk_pll_a); + err = clk_prepare_enable(data->clk_pll_a); if (err) { dev_err(data->dev, "Can't enable pll_a: %d\n", err); return err; } - err = clk_enable(data->clk_pll_a_out0); + err = clk_prepare_enable(data->clk_pll_a_out0); if (err) { dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); return err; } - err = clk_enable(data->clk_cdev1); + err = clk_prepare_enable(data->clk_cdev1); if (err) { dev_err(data->dev, "Can't enable cdev1: %d\n", err); return err; -- GitLab From 0df1ed4b12840f1d17b373ee5c05877c375ddc3e Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Tue, 5 Jun 2012 09:59:43 +0530 Subject: [PATCH 1262/6849] crypto: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren Acked-by: Herbert Xu --- drivers/crypto/tegra-aes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c index 422a9766c7c9..ac236f6724f4 100644 --- a/drivers/crypto/tegra-aes.c +++ b/drivers/crypto/tegra-aes.c @@ -572,7 +572,7 @@ static void aes_workqueue_handler(struct work_struct *work) struct tegra_aes_dev *dd = aes_dev; int ret; - ret = clk_enable(dd->aes_clk); + ret = clk_prepare_enable(dd->aes_clk); if (ret) BUG_ON("clock enable failed"); @@ -581,7 +581,7 @@ static void aes_workqueue_handler(struct work_struct *work) ret = tegra_aes_handle_req(dd); } while (!ret); - clk_disable(dd->aes_clk); + clk_disable_unprepare(dd->aes_clk); } static irqreturn_t aes_irq(int irq, void *dev_id) @@ -673,7 +673,7 @@ static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata, /* take mutex to access the aes hw */ mutex_lock(&aes_lock); - ret = clk_enable(dd->aes_clk); + ret = clk_prepare_enable(dd->aes_clk); if (ret) return ret; @@ -700,7 +700,7 @@ static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata, } out: - clk_disable(dd->aes_clk); + clk_disable_unprepare(dd->aes_clk); mutex_unlock(&aes_lock); dev_dbg(dd->dev, "%s: done\n", __func__); @@ -758,7 +758,7 @@ static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed, dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; - ret = clk_enable(dd->aes_clk); + ret = clk_prepare_enable(dd->aes_clk); if (ret) return ret; @@ -788,7 +788,7 @@ static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed, memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ); out: - clk_disable(dd->aes_clk); + clk_disable_unprepare(dd->aes_clk); mutex_unlock(&aes_lock); dev_dbg(dd->dev, "%s: done\n", __func__); -- GitLab From 1caba565e13a867107ca78a316d6076c7b6a740c Mon Sep 17 00:00:00 2001 From: Adnan Ali Date: Mon, 28 May 2012 16:07:49 +0100 Subject: [PATCH 1263/6849] Staging: cptm1217: clearpad_tm1217: fix coding style issues This commit fixes coding style issues including quoted string across multiple lines. Signed-off-by: Adnan Ali Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cptm1217/clearpad_tm1217.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c index 5456f82c3066..0d924d3a2ab1 100644 --- a/drivers/staging/cptm1217/clearpad_tm1217.c +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -396,8 +396,8 @@ static int cp_tm1217_setup_gpio_irq(struct cp_tm1217_device *ts) retval = gpio_to_irq(ts->gpio); if (retval < 0) { - dev_err(ts->dev, "cp_tm1217: GPIO to IRQ failedi," - " error %d\n", retval); + dev_err(ts->dev, + "cp_tm1217: GPIO to IRQ failed, error %d\n", retval); gpio_free(ts->gpio); } dev_dbg(ts->dev, -- GitLab From 2e0bec91399bab115d2a3a60288ce94a977f49c1 Mon Sep 17 00:00:00 2001 From: Adnan Ali Date: Mon, 28 May 2012 17:11:29 +0100 Subject: [PATCH 1264/6849] Staging: sep: fix coding style issues This commit fixes coding style issues related to string split across the lines and space before tab at start of line. Signed-off-by: Adnan Ali Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_crypto.c | 4 ++-- drivers/staging/sep/sep_main.c | 37 +++++++++++++++++--------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c index 1cc790e9fa07..9fd9da84428e 100644 --- a/drivers/staging/sep/sep_crypto.c +++ b/drivers/staging/sep/sep_crypto.c @@ -1095,8 +1095,8 @@ static int sep_crypto_take_sep(struct this_task_ctx *ta_ctx) current->comm, sizeof(current->comm)); if (!ta_ctx->queue_elem) { - dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" - " status error\n", current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] updating queue status error\n", current->pid); return -EINVAL; } diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index df1d13e96fcd..ab351289d893 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -1436,8 +1436,9 @@ static int sep_lli_table_secure_dma(struct sep_device *sep, start_page = app_virt_addr >> PAGE_SHIFT; num_pages = end_page - start_page + 1; - dev_dbg(&sep->pdev->dev, "[PID%d] lock user pages" - " app_virt_addr is %x\n", current->pid, app_virt_addr); + dev_dbg(&sep->pdev->dev, + "[PID%d] lock user pages app_virt_addr is %x\n", + current->pid, app_virt_addr); dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n", current->pid, data_size); @@ -1931,9 +1932,9 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, void *dma_lli_table_alloc_addr = NULL; void *dma_in_lli_table_ptr = NULL; - dev_dbg(&sep->pdev->dev, "[PID%d] prepare intput dma " - "tbl data size: (hex) %x\n", - current->pid, data_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] prepare intput dma tbl data size: (hex) %x\n", + current->pid, data_size); dev_dbg(&sep->pdev->dev, "[PID%d] block_size is (hex) %x\n", current->pid, block_size); @@ -2542,17 +2543,18 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, } } - dev_dbg(&sep->pdev->dev, "[PID%d] After lock; prep input output dma " - "table sep_in_num_pages is (hex) %x\n", current->pid, + dev_dbg(&sep->pdev->dev, + "[PID%d] After lock; prep input output dma table sep_in_num_pages is (hex) %x\n", + current->pid, dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages); dev_dbg(&sep->pdev->dev, "[PID%d] sep_out_num_pages is (hex) %x\n", current->pid, dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages); - dev_dbg(&sep->pdev->dev, "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP" - " is (hex) %x\n", current->pid, - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is (hex) %x\n", + current->pid, SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); /* Call the fucntion that creates table from the lli arrays */ dev_dbg(&sep->pdev->dev, "[PID%d] calling create table from lli\n", @@ -3844,8 +3846,9 @@ static ssize_t sep_write(struct file *filp, * buffers created. Only SEP_DOUBLEBUF_USERS_LIMIT number * of threads can progress further at a time */ - dev_dbg(&sep->pdev->dev, "[PID%d] waiting for double buffering " - "region access\n", current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] waiting for double buffering region access\n", + current->pid); error = down_interruptible(&sep->sep_doublebuf); dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region start\n", current->pid); @@ -3889,8 +3892,8 @@ static ssize_t sep_write(struct file *filp, current->comm, sizeof(current->comm)); if (!my_queue_elem) { - dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" - "status error\n", current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] updating queue status error\n", current->pid); error = -ENOMEM; goto end_function_error_doublebuf; } @@ -4155,8 +4158,8 @@ static int __devinit sep_probe(struct pci_dev *pdev, INIT_LIST_HEAD(&sep->sep_queue_status); - dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, " - "device being prepared\n"); + dev_dbg(&sep->pdev->dev, + "sep probe: PCI obtained, device being prepared\n"); /* Set up our register area */ sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); @@ -4318,7 +4321,7 @@ static void sep_remove(struct pci_dev *pdev) static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0826)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08e9)}, - {0} + {0} }; /* Export our pci_device_id structure to user space */ -- GitLab From 6ee19aef7694e9533617573ebe8a0b379d5c75f4 Mon Sep 17 00:00:00 2001 From: Adnan Ali Date: Tue, 29 May 2012 11:33:03 +0100 Subject: [PATCH 1265/6849] Staging: ramster: r2net: fix coding style issues This commit fixes coding style issues related to string splite across multiple lines. Signed-off-by: Adnan Ali Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/r2net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ramster/r2net.c b/drivers/staging/ramster/r2net.c index 2ee02204c43d..fc830c3ac74b 100644 --- a/drivers/staging/ramster/r2net.c +++ b/drivers/staging/ramster/r2net.c @@ -266,8 +266,8 @@ int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size, static unsigned long cnt; cnt++; if (!(cnt&(cnt-1))) - pr_err("ramster_remote_put: message failed, " - "ret=%d, cnt=%lu\n", ret, cnt); + pr_err("ramster_remote_put: message failed, ret=%d, cnt=%lu\n", + ret, cnt); ret = -1; } #endif -- GitLab From ff5e4a1d2702582614996f6f6d005e9b5caadeb8 Mon Sep 17 00:00:00 2001 From: Adnan Ali Date: Thu, 31 May 2012 11:32:48 +0100 Subject: [PATCH 1266/6849] Staging: gdm72xx: gdm_usb: fix deprecated function kernel_thread This commit fixes deprecated function kernel_thread by replacing it with kthread_run. Signed-off-by: Adnan Ali Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 1e9dc0d90362..19533c6e055b 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "gdm_usb.h" #include "gdm_wimax.h" @@ -775,7 +776,7 @@ static struct usb_driver gdm_usb_driver = { static int __init usb_gdm_wimax_init(void) { #ifdef CONFIG_WIMAX_GDM72XX_K_MODE - kernel_thread(k_mode_thread, NULL, CLONE_KERNEL); + kthread_run(k_mode_thread, NULL, "WiMax_thread"); #endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ return usb_register(&gdm_usb_driver); } -- GitLab From dee0dc0d0649b028e16473a8e2410efd455135c2 Mon Sep 17 00:00:00 2001 From: Adnan Ali Date: Tue, 29 May 2012 15:21:20 +0100 Subject: [PATCH 1267/6849] Staging: rts5139: sd_cprm: fix coding style and deprecation issues This commit fixes coding style and deprecation issues which includes long lines, braces with single statments in if condition and deprecated min() function. Signed-off-by: Adnan Ali Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5139/sd_cprm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index f8c60711f710..0167f7f35c20 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -201,9 +201,8 @@ RTY_SEND_CMD: if (buf[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); } - if (buf[1] & 0x7F) { + if (buf[1] & 0x7F) TRACE_RET(chip, STATUS_FAIL); - } if (buf[2] & 0xF8) TRACE_RET(chip, STATUS_FAIL); @@ -224,7 +223,8 @@ RTY_SEND_CMD: return STATUS_SUCCESS; } -static int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) +static int ext_sd_get_rsp(struct rts51x_chip *chip, int len, + u8 *rsp, u8 rsp_type) { int retval, rsp_len; u16 reg_addr; @@ -844,7 +844,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) buf[15] = chip->max_lun; - len = min(18, (int)scsi_bufflen(srb)); + len = min_t(unsigned, 18, scsi_bufflen(srb)); rts51x_set_xfer_buf(buf, len, srb); return TRANSPORT_GOOD; -- GitLab From 02fd3b3670fb99017b17757d33a0a17e2405920c Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 28 May 2012 01:53:22 +0530 Subject: [PATCH 1268/6849] staging/gdm72xx: Remove version.h includes Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 1 - drivers/staging/gdm72xx/gdm_sdio.c | 1 - drivers/staging/gdm72xx/gdm_usb.c | 1 - drivers/staging/gdm72xx/gdm_wimax.c | 1 - drivers/staging/gdm72xx/gdm_wimax.h | 1 - drivers/staging/gdm72xx/netlink_k.c | 1 - drivers/staging/gdm72xx/sdio_boot.c | 1 - drivers/staging/gdm72xx/usb_boot.c | 1 - 8 files changed, 8 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 0217680ec545..e7134e28a06d 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -11,7 +11,6 @@ * GNU General Public License for more details. */ -#include #include #include diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index e1a3dd2fc4af..5e19b09e3bff 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 19533c6e055b..e201b341e52f 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index f1936b92533b..110bdbc9c899 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -11,7 +11,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/drivers/staging/gdm72xx/gdm_wimax.h b/drivers/staging/gdm72xx/gdm_wimax.h index 023e6492e33d..6ec0ab43e9cc 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.h +++ b/drivers/staging/gdm72xx/gdm_wimax.h @@ -15,7 +15,6 @@ #define __GDM_WIMAX_H__ #include -#include #include #include "wm_ioctl.h" #if defined(CONFIG_WIMAX_GDM72XX_QOS) diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 292af0f7f451..1c74b0875515 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -11,7 +11,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c index 6ff4dc372522..760efee23d4a 100644 --- a/drivers/staging/gdm72xx/sdio_boot.c +++ b/drivers/staging/gdm72xx/sdio_boot.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c index 5a0e030220dc..c163bcc437ed 100644 --- a/drivers/staging/gdm72xx/usb_boot.c +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include -- GitLab From ef73b7a45dfd3c4cdd447a6767422349e5fe7242 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 4 Jun 2012 07:46:52 -0700 Subject: [PATCH 1269/6849] staging: "sbe-2t3e3" Fix typos in sbe-2t3e3 Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sbe-2t3e3/dc.c | 2 +- drivers/staging/sbe-2t3e3/io.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/sbe-2t3e3/dc.c b/drivers/staging/sbe-2t3e3/dc.c index 9dc4ec2109eb..e897a4366620 100644 --- a/drivers/staging/sbe-2t3e3/dc.c +++ b/drivers/staging/sbe-2t3e3/dc.c @@ -81,7 +81,7 @@ void dc_init(struct channel *sc) SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS; dc_write(sc->addr, SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL, val); - /* prepare descriptors and data for receive and transmit procecsses */ + /* prepare descriptors and data for receive and transmit processes */ if (dc_init_descriptor_list(sc) != 0) return; diff --git a/drivers/staging/sbe-2t3e3/io.c b/drivers/staging/sbe-2t3e3/io.c index 9a50bcc59594..d2391cb23e64 100644 --- a/drivers/staging/sbe-2t3e3/io.c +++ b/drivers/staging/sbe-2t3e3/io.c @@ -17,7 +17,7 @@ /* All access to registers done via the 21143 on port 0 must be * protected via the card->bootrom_lock. */ -/* priviate define to be used here only - must be protected by card->bootrom_lock */ +/* private define to be used here only - must be protected by card->bootrom_lock */ #define cpld_write_nolock(channel, reg, val) \ bootrom_write((channel), CPLD_MAP_REG(reg, channel), val) -- GitLab From 8aac4d443980a4b5833b6896169c30d22e4cce74 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 6 Jun 2012 01:10:50 +0530 Subject: [PATCH 1270/6849] staging/wlan-ng: cfg80211.c coding style cleanup there are warnings that are reported by checkpatch.pl fixed the following problems drivers/staging/wlan-ng/cfg80211.c:130: WARNING: line over 80 characters drivers/staging/wlan-ng/cfg80211.c:366: WARNING: line over 80 characters drivers/staging/wlan-ng/cfg80211.c:543: WARNING: line over 80 characters drivers/staging/wlan-ng/cfg80211.c:665: WARNING: line over 80 characters drivers/staging/wlan-ng/cfg80211.c:692: WARNING: line over 80 characters drivers/staging/wlan-ng/cfg80211.c:735: WARNING: line over 80 characters Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/cfg80211.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 8bc562b8c4d9..fabff4d650ef 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -127,7 +127,9 @@ int prism2_change_virtual_intf(struct wiphy *wiphy, } /* Set Operation mode to the PORT TYPE RID */ - result = prism2_domibset_uint32(wlandev, DIDmib_p2_p2Static_p2CnfPortType, data); + result = prism2_domibset_uint32(wlandev, + DIDmib_p2_p2Static_p2CnfPortType, + data); if (result) err = -EFAULT; @@ -363,7 +365,8 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, if (request->n_ssids > 0) { msg1.scantype.data = P80211ENUM_scantype_active; msg1.ssid.data.len = request->ssids->ssid_len; - memcpy(msg1.ssid.data.data, request->ssids->ssid, request->ssids->ssid_len); + memcpy(msg1.ssid.data.data, + request->ssids->ssid, request->ssids->ssid_len); } else { msg1.scantype.data = 0; } @@ -540,7 +543,9 @@ int prism2_connect(struct wiphy *wiphy, struct net_device *dev, goto exit; } - result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *) sme->key); + result = prism2_domibset_pstr32(wlandev, + did, sme->key_len, + (u8 *)sme->key); if (result) goto exit; @@ -662,10 +667,11 @@ int prism2_get_tx_power(struct wiphy *wiphy, int *dbm) struct prism2_wiphy_private *priv = wiphy_priv(wiphy); wlandevice_t *wlandev = priv->wlandev; struct p80211msg_dot11req_mibget msg; - p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data; + p80211item_uint32_t *mibitem; int result; int err = 0; + mibitem = (p80211item_uint32_t *) &msg.mibattribute.data; msg.msgcode = DIDmsg_dot11req_mibget; mibitem->did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; @@ -689,7 +695,8 @@ exit: /* Interface callback functions, passing data back up to the cfg80211 layer */ void prism2_connect_result(wlandevice_t *wlandev, u8 failed) { - u16 status = failed ? WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS; + u16 status = failed ? + WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS; cfg80211_connect_result(wlandev->netdev, wlandev->bssid, NULL, 0, NULL, 0, status, GFP_KERNEL); @@ -732,7 +739,8 @@ struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev) { struct wiphy *wiphy; struct prism2_wiphy_private *priv; - wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(struct prism2_wiphy_private)); + + wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(*priv)); if (!wiphy) return NULL; -- GitLab From cf66823dd224294f40ad6ddced70e80bae940741 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 6 Jun 2012 01:12:06 +0530 Subject: [PATCH 1271/6849] staging/wlan-ng: prsim2fw.c coding style cleanup this patch fixes the coding style problems found by using checkpatch.pl drivers/staging/wlan-ng/prism2fw.c:175: ERROR: "foo * bar" should be "foo *bar" drivers/staging/wlan-ng/prism2fw.c:210: WARNING: line over 80 characters drivers/staging/wlan-ng/prism2fw.c:596: WARNING: line over 80 characters drivers/staging/wlan-ng/prism2fw.c:658: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2fw.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 3c40096f0c05..f13cdc9ab412 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -172,7 +172,7 @@ static int read_cardpda(struct pda *pda, wlandevice_t *wlandev); static int mkpdrlist(struct pda *pda); static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, - struct s3plugrec *s3plug, unsigned int ns3plug, struct pda * pda); + struct s3plugrec *s3plug, unsigned int ns3plug, struct pda *pda); static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, struct s3crcrec *s3crc, unsigned int ns3crc); @@ -207,7 +207,8 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) printk(KERN_INFO "prism2_usb: Checking for firmware %s\n", PRISM2_USB_FWFILE); - if (request_ihex_firmware(&fw_entry, PRISM2_USB_FWFILE, &udev->dev) != 0) { + if (request_ihex_firmware(&fw_entry, + PRISM2_USB_FWFILE, &udev->dev) != 0) { printk(KERN_INFO "prism2_usb: Firmware not available, but not essential\n"); printk(KERN_INFO @@ -593,7 +594,8 @@ int mkpdrlist(struct pda *pda) le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) { pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]); - if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) { + if (le16_to_cpu(pda->rec[pda->nrec]->code) == + HFA384x_PDR_NICID) { memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid, sizeof(nicid)); nicid.id = le16_to_cpu(nicid.id); @@ -655,7 +657,7 @@ int mkpdrlist(struct pda *pda) * ~0 failure ----------------------------------------------------------------*/ int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, - struct s3plugrec *s3plug, unsigned int ns3plug, struct pda * pda) + struct s3plugrec *s3plug, unsigned int ns3plug, struct pda *pda) { int result = 0; int i; /* plug index */ -- GitLab From 9b754b17f9ac5fbb9586ae6582de7ecbfc46b56d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 6 Jun 2012 14:46:44 -0700 Subject: [PATCH 1272/6849] staging: wlags49_h2: remove direct declarations of KERN_ prefixes Use the standard KERN_ #defines instead of "<.>" Signed-off-by: Joe Perches Cc: Kay Sievers Cc: Henk de Groot Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/hcf.c | 8 ++++---- drivers/staging/wlags49_h2/wl_main.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c index 366e4a4b75c5..423544634ae5 100644 --- a/drivers/staging/wlags49_h2/hcf.c +++ b/drivers/staging/wlags49_h2/hcf.c @@ -705,7 +705,7 @@ hcf_action( IFBP ifbp, hcf_16 action ) // 800 us latency before FW switches to high power MSF_WAIT(800); // MSF-defined function to wait n microseconds. //OOR if ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_DS_OOR ) { // OutOfRange -// printk( "<5>ACT_INT_OFF: Deepsleep phase terminated, enable and go to AwaitConnection\n" ); //;?remove me 1 day +// printk(KERN_NOTICE "ACT_INT_OFF: Deepsleep phase terminated, enable and go to AwaitConnection\n" ); //;?remove me 1 day // hcf_cntl( ifbp, HCF_CNTL_ENABLE ); // } // ifbp->IFB_DSLinkStat &= ~( CFG_LINK_STAT_DS_IR | CFG_LINK_STAT_DS_OOR); //clear IR/OOR state @@ -2979,7 +2979,7 @@ hcf_service_nic( IFBP ifbp, wci_bufp bufp, unsigned int len ) ltv.typ = CFG_DDS_TICK_TIME; ltv.tick_time = ( ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_TIMER ) + 0x10 ) *64; //78 is more right hcf_put_info( ifbp, (LTVP)<v ); - printk( "<5>Preparing for sleep, link_status: %04X, timer : %d\n", + printk(KERN_NOTICE "Preparing for sleep, link_status: %04X, timer : %d\n", ifbp->IFB_DSLinkStat, ltv.tick_time );//;?remove me 1 day ifbp->IFB_TickCnt++; //;?just to make sure we do not keep on printing above message if ( ltv.tick_time < 300 * 125 ) ifbp->IFB_DSLinkStat += 0x0010; @@ -4221,11 +4221,11 @@ isr_info( IFBP ifbp ) // /*4*/ if ( info[1] == CFG_LINK_STAT ) { // ifbp->IFB_DSLinkStat = IPW( HREG_DATA_1 ) | CFG_LINK_STAT_CHANGE; //corrupts BAP !! ;? // ifbp->IFB_LinkStat = ifbp->IFB_DSLinkStat & CFG_LINK_STAT_FW; //;? to be obsoleted -// printk( "<4>linkstatus: %04x\n", ifbp->IFB_DSLinkStat ); //;?remove me 1 day +// printk(KERN_ERR "linkstatus: %04x\n", ifbp->IFB_DSLinkStat ); //;?remove me 1 day // #if (HCF_SLEEP) & HCF_DDS // if ( ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_CONNECTED ) == 0 ) { //even values are disconnected etc. // ifbp->IFB_TickCnt = 0; //start 2 second period (with 1 tick uncertanty) -// printk( "<5>isr_info: AwaitConnection phase started, IFB_TickCnt = 0\n" ); //;?remove me 1 day +// printk(KERN_NOTICE "isr_info: AwaitConnection phase started, IFB_TickCnt = 0\n" ); //;?remove me 1 day // } // #endif // HCF_DDS // } diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c index d5bf0a7012f2..204107829577 100644 --- a/drivers/staging/wlags49_h2/wl_main.c +++ b/drivers/staging/wlags49_h2/wl_main.c @@ -3822,7 +3822,7 @@ static int write_int(struct file *file, const char *buffer, unsigned long count, lp->timer_oor.data = (unsigned long)lp; lp->timer_oor.expires = RUN_AT( 3 * HZ ); add_timer( &lp->timer_oor ); - printk( "<5>wl_enable: %ld\n", jiffies ); //;?remove me 1 day + printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day #endif //DN554 #ifdef DN554 /******************************************************************************* @@ -3852,7 +3852,7 @@ void timer_oor( u_long arg ) DBG_ENTER( DbgInfo ); DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg ); - printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day + printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day lp->timer_oor_cnt += 10; if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) { lp->timer_oor_cnt = 300; -- GitLab From 093abf11d3c4ecb8d8c57adec926dced532878ba Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 6 Jun 2012 22:54:27 -0400 Subject: [PATCH 1273/6849] Staging: bcm: Fix all whitespace issues in nvm.c This patch resolves all whitespace issues as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 4067 ++++++++++++++++++------------------- 1 file changed, 1980 insertions(+), 2087 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index f16d3bb54c3c..2bb87c93b0e9 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -29,8 +29,8 @@ static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); static INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); static INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, - FLASH2X_SECTION_VAL eFlash2xSectionVal, - UINT uiOffset, UINT uiNumBytes); + FLASH2X_SECTION_VAL eFlash2xSectionVal, + UINT uiOffset, UINT uiNumBytes); static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter); static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter); @@ -49,7 +49,7 @@ static INT BeceemFlashBulkWrite( static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); -static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData); +static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData, UINT dwNumData); // Procedure: ReadEEPROMStatusRegister // @@ -62,52 +62,52 @@ static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,UINT dwAddress, // //----------------------------------------------------------------------------- -static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter ) +static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) { UCHAR uiData = 0; - DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; UINT uiStatus = 0; UINT value = 0; UINT value1 = 0; /* Read the EEPROM status register */ - value = EEPROM_READ_STATUS_REGISTER ; - wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); + value = EEPROM_READ_STATUS_REGISTER; + wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - while ( dwRetries != 0 ) + while (dwRetries != 0) { - value=0; - uiStatus = 0 ; + value = 0; + uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if(Adapter->device_removed == TRUE) + if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting...."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting...."); break; } /* Wait for Avail bit to be set. */ - if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 ) + if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { /* Clear the Avail/Full bits - which ever is set. */ value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - value =0; + value = 0; rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); uiData = (UCHAR)value; break; } - dwRetries-- ; - if ( dwRetries == 0 ) + dwRetries--; + if (dwRetries == 0) { - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"0x3004 = %x 0x3008 = %x, retries = %d failed.\n",value,value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY); + rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x3004 = %x 0x3008 = %x, retries = %d failed.\n", value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); return uiData; } - if( !(dwRetries%RETRIES_PER_DELAY) ) + if (!(dwRetries%RETRIES_PER_DELAY)) msleep(1); uiStatus = 0 ; } @@ -129,68 +129,65 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter ) //----------------------------------------------------------------------------- INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, - DWORD dwAddress, - DWORD *pdwData, - DWORD dwNumWords - ) + DWORD dwAddress, + DWORD *pdwData, + DWORD dwNumWords) { DWORD dwIndex = 0; - DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; UINT uiStatus = 0; - UINT value= 0; + UINT value = 0; UINT value1 = 0; UCHAR *pvalue; /* Flush the read and cmd queue. */ - value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH ); - wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) ); - value=0; - wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + value = (EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH); + wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + value = 0; + wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); /* Clear the Avail/Full bits. */ - value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ); - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); - - value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ ); - wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); + value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - while ( dwRetries != 0 ) - { + value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ); + wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); + while (dwRetries != 0) + { uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if(Adapter->device_removed == TRUE) + if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop..."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop..."); return -ENODEV; } /* If we are reading 16 bytes we want to be sure that the queue * is full before we read. In the other cases we are ok if the * queue has data available */ - if ( dwNumWords == 4 ) + if (dwNumWords == 4) { - if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 ) + if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) { /* Clear the Avail/Full bits - which ever is set. */ - value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ; - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); break; } } - else if ( dwNumWords == 1 ) + else if (dwNumWords == 1) { - - if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 ) + if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { /* We just got Avail and we have to read 32bits so we * need this sleep for Cardbus kind of devices. */ - if (Adapter->chip_id == 0xBECE0210 ) - udelay(800); + if (Adapter->chip_id == 0xBECE0210) + udelay(800); /* Clear the Avail/Full bits - which ever is set. */ - value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ); - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); break; } } @@ -198,25 +195,27 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, uiStatus = 0; dwRetries--; - if(dwRetries == 0) + if (dwRetries == 0) { - value=0; - value1=0; + value = 0; + value1 = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", dwNumWords, value, value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", + dwNumWords, value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); return STATUS_FAILURE; } - if( !(dwRetries%RETRIES_PER_DELAY) ) + + if (!(dwRetries%RETRIES_PER_DELAY)) msleep(1); } - for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ ) + for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) { /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */ pvalue = (PUCHAR)(pdwData + dwIndex); - value =0; + value = 0; rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); pvalue[0] = value; @@ -226,7 +225,7 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, pvalue[1] = value; - value =0; + value = 0; rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); pvalue[2] = value; @@ -256,15 +255,14 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, //----------------------------------------------------------------------------- INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, - DWORD uiOffset, - DWORD *pBuffer - ) + DWORD uiOffset, + DWORD *pBuffer) { - UINT uiData[8] = {0}; + UINT uiData[8] = {0}; UINT uiByteOffset = 0; UINT uiTempOffset = 0; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> "); uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); uiByteOffset = uiOffset - uiTempOffset; @@ -273,18 +271,16 @@ INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, /* A word can overlap at most over 2 pages. In that case we read the * next page too. */ - if ( uiByteOffset > 12 ) + if (uiByteOffset > 12) { ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); } - memcpy( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4); + memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4); return STATUS_SUCCESS; } /* ReadBeceemEEPROM() */ - - INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) { INT Status; @@ -295,7 +291,7 @@ INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) INIT_PARAMS_1_MACADDRESS_ADDRESS, MAC_ADDRESS_SIZE); - if(Status == STATUS_SUCCESS) + if (Status == STATUS_SUCCESS) memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); return Status; @@ -317,62 +313,56 @@ INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) // - if failed. //----------------------------------------------------------------------------- -INT BeceemEEPROMBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) +INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) { - UINT uiData[4] = {0}; - //UINT uiAddress = 0; - UINT uiBytesRemaining = uiNumBytes; - UINT uiIndex = 0; - UINT uiTempOffset = 0; - UINT uiExtraBytes = 0; - UINT uiFailureRetries = 0; + UINT uiData[4] = {0}; + // UINT uiAddress = 0; + UINT uiBytesRemaining = uiNumBytes; + UINT uiIndex = 0; + UINT uiTempOffset = 0; + UINT uiExtraBytes = 0; + UINT uiFailureRetries = 0; PUCHAR pcBuff = (PUCHAR)pBuffer; - - if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining) + if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) { - uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE); - uiExtraBytes = uiOffset-uiTempOffset; - ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4); - if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) + uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); + uiExtraBytes = uiOffset - uiTempOffset; + ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); + if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) { - memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes); - + memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes); uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes); uiIndex += (MAX_RW_SIZE - uiExtraBytes); uiOffset += (MAX_RW_SIZE - uiExtraBytes); } else { - memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining); + memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining); uiIndex += uiBytesRemaining; uiOffset += uiBytesRemaining; uiBytesRemaining = 0; } - - } - - while(uiBytesRemaining && uiFailureRetries != 128) + while (uiBytesRemaining && uiFailureRetries != 128) { - if(Adapter->device_removed ) + if (Adapter->device_removed) { return -1; } - if(uiBytesRemaining >= MAX_RW_SIZE) + if (uiBytesRemaining >= MAX_RW_SIZE) { /* For the requests more than or equal to 16 bytes, use bulk * read function to make the access faster. * We read 4 Dwords of data */ - if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4)) + if (0 == ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4)) { - memcpy(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE); + memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE); uiOffset += MAX_RW_SIZE; uiBytesRemaining -= MAX_RW_SIZE; uiIndex += MAX_RW_SIZE; @@ -380,40 +370,39 @@ INT BeceemEEPROMBulkRead( else { uiFailureRetries++; - mdelay(3);//sleep for a while before retry... + mdelay(3); //sleep for a while before retry... } } - else if(uiBytesRemaining >= 4) + else if (uiBytesRemaining >= 4) { - if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0])) + if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { - memcpy(pcBuff+uiIndex,&uiData[0],4); + memcpy(pcBuff + uiIndex, &uiData[0], 4); uiOffset += 4; uiBytesRemaining -= 4; - uiIndex +=4; + uiIndex += 4; } else { uiFailureRetries++; - mdelay(3);//sleep for a while before retry... + mdelay(3); //sleep for a while before retry... } } else - { // Handle the reads less than 4 bytes... + { // Handle the reads less than 4 bytes... PUCHAR pCharBuff = (PUCHAR)pBuffer; pCharBuff += uiIndex; - if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0])) + if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { - memcpy(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested. + memcpy(pCharBuff, &uiData[0], uiBytesRemaining); //copy only bytes requested. uiBytesRemaining = 0; } else { uiFailureRetries++; - mdelay(3);//sleep for a while before retry... + mdelay(3); //sleep for a while before retry... } } - } return 0; @@ -435,11 +424,10 @@ INT BeceemEEPROMBulkRead( // - if failed. //----------------------------------------------------------------------------- -static INT BeceemFlashBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) +static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) { UINT uiIndex = 0; UINT uiBytesToRead = uiNumBytes; @@ -447,30 +435,30 @@ static INT BeceemFlashBulkRead( UINT uiPartOffset = 0; int bytes; - if(Adapter->device_removed ) + if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed"); return -ENODEV; } - //Adding flash Base address -// uiOffset = uiOffset + GetFlashBaseAddr(Adapter); -#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); - return Status; -#endif + // Adding flash Base address + // uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); + return Status; + #endif Adapter->SelectedChip = RESET_CHIP_SELECT; - if(uiOffset % MAX_RW_SIZE) + if (uiOffset % MAX_RW_SIZE) { - BcmDoChipSelect(Adapter,uiOffset); + BcmDoChipSelect(Adapter, uiOffset); uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE); - uiBytesToRead = MIN(uiNumBytes,uiBytesToRead); + uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE); + uiBytesToRead = MIN(uiNumBytes, uiBytesToRead); - bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer+uiIndex, uiBytesToRead); + bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); if (bytes < 0) { Status = bytes; Adapter->SelectedChip = RESET_CHIP_SELECT; @@ -482,24 +470,22 @@ static INT BeceemFlashBulkRead( uiNumBytes -= uiBytesToRead; } - while(uiNumBytes) + while (uiNumBytes) { - BcmDoChipSelect(Adapter,uiOffset); + BcmDoChipSelect(Adapter, uiOffset); uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE); + uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE); - bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer+uiIndex, uiBytesToRead); + bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); if (bytes < 0) { Status = bytes; break; } - uiIndex += uiBytesToRead; uiOffset += uiBytesToRead; uiNumBytes -= uiBytesToRead; - } Adapter->SelectedChip = RESET_CHIP_SELECT; return Status; @@ -520,12 +506,10 @@ static INT BeceemFlashBulkRead( static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) { - if(IsFlash2x(Adapter)) - return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); + if (IsFlash2x(Adapter)) + return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); else - return 32*1024; - - + return 32 * 1024; } //----------------------------------------------------------------------------- @@ -546,51 +530,48 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) UINT uiData = 0; UINT uiIndex = 0; -// -// if EEPROM is present and already Calibrated,it will have -// 'BECM' string at 0th offset. -// To find the EEPROM size read the possible boundaries of the -// EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will -// result in wrap around. So when we get the End of the EEPROM we will -// get 'BECM' string which is indeed at offset 0. -// - BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4); - if(uiData == BECM) + // + // if EEPROM is present and already Calibrated,it will have + // 'BECM' string at 0th offset. + // To find the EEPROM size read the possible boundaries of the + // EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will + // result in wrap around. So when we get the End of the EEPROM we will + // get 'BECM' string which is indeed at offset 0. + // + BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); + if (uiData == BECM) { - for(uiIndex = 2;uiIndex <=256; uiIndex*=2) + for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { - BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4); - if(uiData == BECM) + BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); + if (uiData == BECM) { - return uiIndex*1024; + return uiIndex * 1024; } } } else { -// -// EEPROM may not be present or not programmed -// - - uiData = 0xBABEFACE; - if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE)) + // + // EEPROM may not be present or not programmed + // + uiData = 0xBABEFACE; + if (0 == BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE)) { uiData = 0; - for(uiIndex = 2;uiIndex <=256; uiIndex*=2) + for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { - BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4); - if(uiData == 0xBABEFACE) + BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); + if (uiData == 0xBABEFACE) { - return uiIndex*1024; + return uiIndex * 1024; } } } - } return 0; } - //----------------------------------------------------------------------------- // Procedure: FlashSectorErase // @@ -606,17 +587,16 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) // //----------------------------------------------------------------------------- - static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, - UINT addr, - UINT numOfSectors) + UINT addr, + UINT numOfSectors) { UINT iIndex = 0, iRetries = 0; UINT uiStatus = 0; UINT value; int bytes; - for(iIndex=0;iIndex\n")); + // DumpDebug(NVM_RW,("flashWrite ====>\n")); value = (FLASH_CMD_WRITE_ENABLE << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); return STATUS_FAILURE; } - if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 ) + + if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); return STATUS_FAILURE; } value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 ) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } @@ -718,35 +695,33 @@ static INT flashByteWrite( do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; - } - //__udelay(1); + } + //__udelay(1); bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); return uiStatus; } - iRetries--; - if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); + iRetries--; + if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); - }while((uiStatus & 0x1) && (iRetries >0) ); + } while ((uiStatus & 0x1) && (iRetries > 0)); - if(uiStatus & 0x1) + if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE; } return STATUS_SUCCESS; } - - //----------------------------------------------------------------------------- // Procedure: flashWrite // @@ -761,11 +736,9 @@ static INT flashByteWrite( // //----------------------------------------------------------------------------- -static INT flashWrite( - struct bcm_mini_adapter *Adapter, - UINT uiOffset, - PVOID pData) - +static INT flashWrite(struct bcm_mini_adapter *Adapter, + UINT uiOffset, + PVOID pData) { //UINT uiStatus = 0; //INT iRetries = 0; @@ -773,14 +746,13 @@ static INT flashWrite( UINT uiStatus = 0; INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 - UINT value; - UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; -// -// need not write 0xFFFFFFFF because write requires an erase and erase will -// make whole sector 0xFFFFFFFF. -// + // + // need not write 0xFFFFFFFF because write requires an erase and erase will + // make whole sector 0xFFFFFFFF. + // if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) { return 0; @@ -788,14 +760,15 @@ static INT flashWrite( value = (FLASH_CMD_WRITE_ENABLE << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 ) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) + + if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails..."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); return STATUS_FAILURE; } @@ -803,12 +776,12 @@ static INT flashWrite( do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; - } - //__udelay(1); + } + //__udelay(1); bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; @@ -821,14 +794,14 @@ static INT flashWrite( //currently one rdm/wrm takes 125 us. //Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay) //Hence current implementation cycle will intoduce no delay in current path - if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); - }while((uiStatus & 0x1) && (iRetries > 0)); + if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); + } while ((uiStatus & 0x1) && (iRetries > 0)); - if(uiStatus & 0x1) + if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE; } return STATUS_SUCCESS; @@ -847,10 +820,9 @@ static INT flashWrite( // OSAL_STATUS_CODE // //----------------------------------------------------------------------------- -static INT flashByteWriteStatus( - struct bcm_mini_adapter *Adapter, - UINT uiOffset, - PVOID pData) +static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, + UINT uiOffset, + PVOID pData) { UINT uiStatus = 0; INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 @@ -858,12 +830,12 @@ static INT flashByteWriteStatus( UINT value; int bytes; -// -// need not write 0xFFFFFFFF because write requires an erase and erase will -// make whole sector 0xFFFFFFFF. -// + // + // need not write 0xFFFFFFFF because write requires an erase and erase will + // make whole sector 0xFFFFFFFF. + // - if(0xFF == ulData) + if (0xFF == ulData) { return STATUS_SUCCESS; } @@ -871,31 +843,31 @@ static INT flashByteWriteStatus( // DumpDebug(NVM_RW,("flashWrite ====>\n")); value = (FLASH_CMD_WRITE_ENABLE << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); return STATUS_SUCCESS; } - if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) + if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); return STATUS_FAILURE; } value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - //msleep(1); + //msleep(1); do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } //__udelay(1); @@ -907,18 +879,18 @@ static INT flashByteWriteStatus( } iRetries--; - if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); - }while((uiStatus & 0x1) && (iRetries > 0)); + if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); + + } while ((uiStatus & 0x1) && (iRetries > 0)); - if(uiStatus & 0x1) + if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE; } return STATUS_SUCCESS; - } //----------------------------------------------------------------------------- // Procedure: flashWriteStatus @@ -934,68 +906,69 @@ static INT flashByteWriteStatus( // //----------------------------------------------------------------------------- -static INT flashWriteStatus( - struct bcm_mini_adapter *Adapter, - UINT uiOffset, - PVOID pData) +static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, + UINT uiOffset, + PVOID pData) { UINT uiStatus = 0; INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 //UINT uiReadBack = 0; UINT value; - UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; -// -// need not write 0xFFFFFFFF because write requires an erase and erase will -// make whole sector 0xFFFFFFFF. -// - if (!memcmp(pData,uiErasePattern,MAX_RW_SIZE)) + // + // need not write 0xFFFFFFFF because write requires an erase and erase will + // make whole sector 0xFFFFFFFF. + // + if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) { return 0; } value = (FLASH_CMD_WRITE_ENABLE << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0) + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) + + if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails..."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); return STATUS_FAILURE; } - // __udelay(1); + // __udelay(1); do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails"); + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; - } - //__udelay(1); + } + //__udelay(1); bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); return uiStatus; } - iRetries--; - //this will ensure that in there will be no changes in the current path. - //currently one rdm/wrm takes 125 us. - //Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) - //Hence current implementation cycle will intoduce no delay in current path - if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); - }while((uiStatus & 0x1) && (iRetries >0)); + iRetries--; + // this will ensure that in there will be no changes in the current path. + // currently one rdm/wrm takes 125 us. + // Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) + // Hence current implementation cycle will intoduce no delay in current path + if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) + msleep(1); - if(uiStatus & 0x1) + } while ((uiStatus & 0x1) && (iRetries > 0)); + + if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); + return STATUS_FAILURE; } return STATUS_SUCCESS; @@ -1014,17 +987,18 @@ static INT flashWriteStatus( // //----------------------------------------------------------------------------- -static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter,ULONG ulWriteStatus) +static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) { UINT value; - value = (FLASH_CMD_WRITE_ENABLE<< 24); + value = (FLASH_CMD_WRITE_ENABLE << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); udelay(20); - value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16); + value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); udelay(20); } + //----------------------------------------------------------------------------- // Procedure: BcmFlashUnProtectBlock // @@ -1037,98 +1011,96 @@ static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter,ULONG // ULONG - Status value before UnProtect. // //----------------------------------------------------------------------------- -static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter,UINT uiOffset, UINT uiLength) + +static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOffset, UINT uiLength) { - ULONG ulStatus = 0; - ULONG ulWriteStatus = 0; + ULONG ulStatus = 0; + ULONG ulWriteStatus = 0; UINT value; - uiOffset = uiOffset&0x000FFFFF; -// -// Implemented only for 1MB Flash parts. -// - if(FLASH_PART_SST25VF080B == Adapter->ulFlashID) - { + uiOffset = uiOffset&0x000FFFFF; // - // Get Current BP status. + // Implemented only for 1MB Flash parts. // + if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) + { + // + // Get Current BP status. + // value = (FLASH_CMD_STATUS_REG_READ << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); udelay(10); - // - // Read status will be WWXXYYZZ. We have to take only WW. - // + // + // Read status will be WWXXYYZZ. We have to take only WW. + // rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus)); ulStatus >>= 24; ulWriteStatus = ulStatus; - - // - // Bits [5-2] give current block level protection status. - // Bit5: BP3 - DONT CARE - // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 - // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS - // - - if(ulStatus) + // + // Bits [5-2] give current block level protection status. + // Bit5: BP3 - DONT CARE + // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 + // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS + // + + if (ulStatus) { - if((uiOffset+uiLength) <= 0x80000) + if ((uiOffset+uiLength) <= 0x80000) { - // - // Offset comes in lower half of 1MB. Protect the upper half. - // Clear BP1 and BP0 and set BP2. - // + // + // Offset comes in lower half of 1MB. Protect the upper half. + // Clear BP1 and BP0 and set BP2. + // ulWriteStatus |= (0x4<<2); ulWriteStatus &= ~(0x3<<2); } - else if((uiOffset+uiLength) <= 0xC0000) + else if ((uiOffset + uiLength) <= 0xC0000) { - // - // Offset comes below Upper 1/4. Upper 1/4 can be protected. - // Clear BP2 and set BP1 and BP0. - // + // + // Offset comes below Upper 1/4. Upper 1/4 can be protected. + // Clear BP2 and set BP1 and BP0. + // ulWriteStatus |= (0x3<<2); ulWriteStatus &= ~(0x1<<4); } - else if((uiOffset+uiLength) <= 0xE0000) - { - // - // Offset comes below Upper 1/8. Upper 1/8 can be protected. - // Clear BP2 and BP0 and set BP1 - // - ulWriteStatus |= (0x1<<3); - ulWriteStatus &= ~(0x5<<2); - - } - else if((uiOffset+uiLength) <= 0xF0000) - { - // - // Offset comes below Upper 1/16. Only upper 1/16 can be protected. - // Set BP0 and Clear BP2,BP1. - // - ulWriteStatus |= (0x1<<2); - ulWriteStatus &= ~(0x3<<3); - } - else - { - // - // Unblock all. - // Clear BP2,BP1 and BP0. - // - ulWriteStatus &= ~(0x7<<2); - } - - value = (FLASH_CMD_WRITE_ENABLE<< 24); + else if ((uiOffset + uiLength) <= 0xE0000) + { + // + // Offset comes below Upper 1/8. Upper 1/8 can be protected. + // Clear BP2 and BP0 and set BP1 + // + ulWriteStatus |= (0x1<<3); + ulWriteStatus &= ~(0x5<<2); + } + else if ((uiOffset + uiLength) <= 0xF0000) + { + // + // Offset comes below Upper 1/16. Only upper 1/16 can be protected. + // Set BP0 and Clear BP2,BP1. + // + ulWriteStatus |= (0x1<<2); + ulWriteStatus &= ~(0x3<<3); + } + else + { + // + // Unblock all. + // Clear BP2,BP1 and BP0. + // + ulWriteStatus &= ~(0x7<<2); + } + + value = (FLASH_CMD_WRITE_ENABLE << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); udelay(20); - value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16); + value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); udelay(20); - } - } return ulStatus; } + //----------------------------------------------------------------------------- // Procedure: BeceemFlashBulkWrite // @@ -1136,7 +1108,7 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter,UINT uiOffs // // Arguments: // Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. +// pBuffer - Data to be written. // uiOffset - Offset of the flash where data needs to be written to. // uiNumBytes - Number of bytes to be written. // bVerify - read verify flag. @@ -1145,91 +1117,90 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter,UINT uiOffs // //----------------------------------------------------------------------------- -static INT BeceemFlashBulkWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify) +static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) { - PCHAR pTempBuff = NULL; - PUCHAR pcBuffer = (PUCHAR)pBuffer; - UINT uiIndex = 0; - UINT uiOffsetFromSectStart = 0; - UINT uiSectAlignAddr = 0; - UINT uiCurrSectOffsetAddr = 0; - UINT uiSectBoundary = 0; - UINT uiNumSectTobeRead = 0; - UCHAR ucReadBk[16] = {0}; - ULONG ulStatus = 0; - INT Status = STATUS_SUCCESS; - UINT uiTemp = 0; - UINT index = 0; - UINT uiPartOffset = 0; - -#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); - return Status; -#endif - - uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - - //Adding flash Base address -// uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); - uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; + PCHAR pTempBuff = NULL; + PUCHAR pcBuffer = (PUCHAR)pBuffer; + UINT uiIndex = 0; + UINT uiOffsetFromSectStart = 0; + UINT uiSectAlignAddr = 0; + UINT uiCurrSectOffsetAddr = 0; + UINT uiSectBoundary = 0; + UINT uiNumSectTobeRead = 0; + UCHAR ucReadBk[16] = {0}; + ULONG ulStatus = 0; + INT Status = STATUS_SUCCESS; + UINT uiTemp = 0; + UINT index = 0; + UINT uiPartOffset = 0; + + #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); + return Status; + #endif + + uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); + + // Adding flash Base address + // uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); + uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); + uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if(NULL == pTempBuff) + if (NULL == pTempBuff) goto BeceemFlashBulkWrite_EXIT; -// -// check if the data to be written is overlapped across sectors -// - if(uiOffset+uiNumBytes < uiSectBoundary) + // + // check if the data to be written is overlapped across sectors + // + if (uiOffset+uiNumBytes < uiSectBoundary) { uiNumSectTobeRead = 1; } else { - // Number of sectors = Last sector start address/First sector start address - uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize; - if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize) + // Number of sectors = Last sector start address/First sector start address + uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; + if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) { uiNumSectTobeRead++; } } - //Check whether Requested sector is writable or not in case of flash2x write. But if write call is + // Check whether Requested sector is writable or not in case of flash2x write. But if write call is // for DSD calibration, allow it without checking of sector permission - if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) + if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) { index = 0; - uiTemp = uiNumSectTobeRead ; - while(uiTemp) + uiTemp = uiNumSectTobeRead; + while (uiTemp) { - if(IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%X> is not writable", - (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); + if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable", + (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); Status = SECTOR_IS_NOT_WRITABLE; goto BeceemFlashBulkWrite_EXIT; - } - uiTemp = uiTemp - 1; - index = index + 1 ; + } + uiTemp = uiTemp - 1; + index = index + 1 ; } } Adapter->SelectedChip = RESET_CHIP_SELECT; - while(uiNumSectTobeRead) + while (uiNumSectTobeRead) { - //do_gettimeofday(&tv1); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); + // do_gettimeofday(&tv1); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - BcmDoChipSelect(Adapter,uiSectAlignAddr); + BcmDoChipSelect(Adapter, uiSectAlignAddr); - if(0 != BeceemFlashBulkRead(Adapter, + if (0 != BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, uiOffsetFromSectStart, Adapter->uiSectorSize)) @@ -1238,61 +1209,60 @@ static INT BeceemFlashBulkWrite( goto BeceemFlashBulkWrite_EXIT; } - //do_gettimeofday(&tr); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - - ulStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize); + // do_gettimeofday(&tr); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); + ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - if(uiNumSectTobeRead > 1) + if (uiNumSectTobeRead > 1) { - - memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); - pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr))); - uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); + pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); + uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); } else { - memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); + memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); } - if(IsFlash2x(Adapter)) + if (IsFlash2x(Adapter)) { - SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart); + SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); } - FlashSectorErase(Adapter,uiPartOffset,1); - //do_gettimeofday(&te); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); + FlashSectorErase(Adapter, uiPartOffset, 1); + // do_gettimeofday(&te); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); - for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize) + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { - if(Adapter->device_removed) + if (Adapter->device_removed) { Status = -1; goto BeceemFlashBulkWrite_EXIT; } - if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex]))) + + if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) { Status = -1; goto BeceemFlashBulkWrite_EXIT; } } - //do_gettimeofday(&tw); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); - for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE) + // do_gettimeofday(&tw); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { - if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE)) + if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { - if(Adapter->ulFlashWriteSize == 1) + if (Adapter->ulFlashWriteSize == 1) { UINT uiReadIndex = 0; - for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) + for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) { - if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex]) + if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) { - if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex])) + if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) { Status = STATUS_FAILURE; goto BeceemFlashBulkWrite_EXIT; @@ -1302,9 +1272,9 @@ static INT BeceemFlashBulkWrite( } else { - if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) + if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { - if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex])) + if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) { Status = STATUS_FAILURE; goto BeceemFlashBulkWrite_EXIT; @@ -1313,13 +1283,11 @@ static INT BeceemFlashBulkWrite( } } } - //do_gettimeofday(&twv); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); - - - if(ulStatus) + // do_gettimeofday(&twv); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); + if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter,ulStatus); + BcmRestoreBlockProtectStatus(Adapter, ulStatus); ulStatus = 0; } @@ -1329,119 +1297,117 @@ static INT BeceemFlashBulkWrite( uiOffsetFromSectStart += Adapter->uiSectorSize; uiNumSectTobeRead--; } - //do_gettimeofday(&tv2); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); -// -// Cleanup. -// -BeceemFlashBulkWrite_EXIT: - if(ulStatus) + // do_gettimeofday(&tv2); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); + // + // Cleanup. + // +BeceemFlashBulkWrite_EXIT : + if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter,ulStatus); + BcmRestoreBlockProtectStatus(Adapter, ulStatus); } - + kfree(pTempBuff); Adapter->SelectedChip = RESET_CHIP_SELECT; return Status; } - //----------------------------------------------------------------------------- // Procedure: BeceemFlashBulkWriteStatus // // Description: Writes to Flash. Checks the SPI status after each write. // // Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the flash where data needs to be written to. -// uiNumBytes - Number of bytes to be written. -// bVerify - read verify flag. +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the flash where data needs to be written to. +// uiNumBytes - Number of bytes to be written. +// bVerify - read verify flag. // Returns: // OSAL_STATUS_CODE // //----------------------------------------------------------------------------- -static INT BeceemFlashBulkWriteStatus( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify) +static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) { - PCHAR pTempBuff = NULL; - PUCHAR pcBuffer = (PUCHAR)pBuffer; - UINT uiIndex = 0; - UINT uiOffsetFromSectStart = 0; - UINT uiSectAlignAddr = 0; - UINT uiCurrSectOffsetAddr = 0; - UINT uiSectBoundary = 0; - UINT uiNumSectTobeRead = 0; - UCHAR ucReadBk[16] = {0}; - ULONG ulStatus = 0; - UINT Status = STATUS_SUCCESS; - UINT uiTemp = 0; - UINT index = 0; - UINT uiPartOffset = 0; - - uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - - //uiOffset += Adapter->ulFlashCalStart; - //Adding flash Base address -// uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); - uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; + PCHAR pTempBuff = NULL; + PUCHAR pcBuffer = (PUCHAR)pBuffer; + UINT uiIndex = 0; + UINT uiOffsetFromSectStart = 0; + UINT uiSectAlignAddr = 0; + UINT uiCurrSectOffsetAddr = 0; + UINT uiSectBoundary = 0; + UINT uiNumSectTobeRead = 0; + UCHAR ucReadBk[16] = {0}; + ULONG ulStatus = 0; + UINT Status = STATUS_SUCCESS; + UINT uiTemp = 0; + UINT index = 0; + UINT uiPartOffset = 0; + + uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); + + // uiOffset += Adapter->ulFlashCalStart; + // Adding flash Base address + // uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); + uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); + uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if(NULL == pTempBuff) + if (NULL == pTempBuff) goto BeceemFlashBulkWriteStatus_EXIT; -// -// check if the data to be written is overlapped across sectors -// - if(uiOffset+uiNumBytes < uiSectBoundary) + // + // check if the data to be written is overlapped across sectors + // + if (uiOffset+uiNumBytes < uiSectBoundary) { uiNumSectTobeRead = 1; } else { -// Number of sectors = Last sector start address/First sector start address - uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize; - if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize) + // Number of sectors = Last sector start address/First sector start address + uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; + if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) { uiNumSectTobeRead++; } } - if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) + if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) { index = 0; - uiTemp = uiNumSectTobeRead ; - while(uiTemp) + uiTemp = uiNumSectTobeRead; + while (uiTemp) { - if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable", - (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); + if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable", + (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); Status = SECTOR_IS_NOT_WRITABLE; goto BeceemFlashBulkWriteStatus_EXIT; - } - uiTemp = uiTemp - 1; - index = index + 1 ; + } + uiTemp = uiTemp - 1; + index = index + 1 ; } } Adapter->SelectedChip = RESET_CHIP_SELECT; - while(uiNumSectTobeRead) + while (uiNumSectTobeRead) { uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - BcmDoChipSelect(Adapter,uiSectAlignAddr); - if(0 != BeceemFlashBulkRead(Adapter, + BcmDoChipSelect(Adapter, uiSectAlignAddr); + if (0 != BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, uiOffsetFromSectStart, Adapter->uiSectorSize)) @@ -1450,64 +1416,59 @@ static INT BeceemFlashBulkWriteStatus( goto BeceemFlashBulkWriteStatus_EXIT; } - ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize); + ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize); - if(uiNumSectTobeRead > 1) + if (uiNumSectTobeRead > 1) { - - memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); - pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr))); - uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); + pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); + uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); } else { - memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); + memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); } - if(IsFlash2x(Adapter)) + if (IsFlash2x(Adapter)) { - SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart); + SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); } - FlashSectorErase(Adapter,uiPartOffset,1); - - for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize) + FlashSectorErase(Adapter, uiPartOffset, 1); + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { - if(Adapter->device_removed) + if (Adapter->device_removed) { Status = -1; goto BeceemFlashBulkWriteStatus_EXIT; } - if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex])) + if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) { Status = -1; goto BeceemFlashBulkWriteStatus_EXIT; } } - if(bVerify) + if (bVerify) { - for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE) + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { - - if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE)) + if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { - if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) + if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { Status = STATUS_FAILURE; goto BeceemFlashBulkWriteStatus_EXIT; } - } - } } - if(ulStatus) + if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter,ulStatus); + BcmRestoreBlockProtectStatus(Adapter, ulStatus); ulStatus = 0; } @@ -1520,16 +1481,15 @@ static INT BeceemFlashBulkWriteStatus( // // Cleanup. // -BeceemFlashBulkWriteStatus_EXIT: - if(ulStatus) +BeceemFlashBulkWriteStatus_EXIT : + if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter,ulStatus); + BcmRestoreBlockProtectStatus(Adapter, ulStatus); } kfree(pTempBuff); Adapter->SelectedChip = RESET_CHIP_SELECT; return Status; - } //----------------------------------------------------------------------------- @@ -1544,7 +1504,6 @@ BeceemFlashBulkWriteStatus_EXIT: // //----------------------------------------------------------------------------- - INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); @@ -1555,51 +1514,49 @@ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT value; INT Status = 0; - if(pBuff == NULL) + + if (pBuff == NULL) { return -1; } - if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4)) + if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { - kfree(pBuff); return -1; } uiEepromSize >>= 16; - if(uiEepromSize > 1024*1024) + if (uiEepromSize > 1024 * 1024) { kfree(pBuff); return -1; } + uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); - - while(uiBytesToCopy) + while (uiBytesToCopy) { - if(0 != BeceemEEPROMBulkRead(Adapter,(PUINT)pBuff,uiCalStartAddr,uiBytesToCopy)) + if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) { Status = -1; break; } - wrm(Adapter,uiMemoryLoc,(PCHAR)(((PULONG)pBuff)+uiIndex),uiBytesToCopy); + wrm(Adapter, uiMemoryLoc, (PCHAR)(((PULONG)pBuff) + uiIndex), uiBytesToCopy); uiMemoryLoc += uiBytesToCopy; uiEepromSize -= uiBytesToCopy; uiCalStartAddr += uiBytesToCopy; - uiIndex += uiBytesToCopy/4; - uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + uiIndex += uiBytesToCopy / 4; + uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); } value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value)); + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value)); + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); kfree(pBuff); return Status; - } //----------------------------------------------------------------------------- @@ -1624,36 +1581,37 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT value; INT Status = 0; -// -// Write the signature first. This will ensure firmware does not access EEPROM. -// + + // + // Write the signature first. This will ensure firmware does not access EEPROM. + // value = 0xbeadbead; wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); value = 0xbeadbead; wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4)) + if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { return -1; } uiEepromSize = ntohl(uiEepromSize); uiEepromSize >>= 16; -// -// subtract the auto init section size -// + // + // subtract the auto init section size + // uiEepromSize -= EEPROM_CALPARAM_START; - if(uiEepromSize > 1024*1024) + if (uiEepromSize > 1024 * 1024) { return -1; } pBuff = kmalloc(uiEepromSize, GFP_KERNEL); - if ( pBuff == NULL ) + if (pBuff == NULL) return -1; - if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize)) + if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) { kfree(pBuff); return -1; @@ -1661,26 +1619,25 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) pPtr = pBuff; - uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - while(uiBytesToCopy) + while (uiBytesToCopy) { - Status = wrm(Adapter,uiMemoryLoc,(PCHAR)pPtr,uiBytesToCopy); - if(Status) + Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrm failed with status :%d",Status); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status); break; } pPtr += uiBytesToCopy; uiEepromSize -= uiBytesToCopy; uiMemoryLoc += uiBytesToCopy; - uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); + uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); } kfree(pBuff); return Status; - } //----------------------------------------------------------------------------- @@ -1689,45 +1646,44 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) // Description: Read back the data written and verifies. // // Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the flash where data needs to be written to. -// uiNumBytes - Number of bytes to be written. +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the flash where data needs to be written to. +// uiNumBytes - Number of bytes to be written. // Returns: // OSAL_STATUS_CODE // //----------------------------------------------------------------------------- -static INT BeceemEEPROMReadBackandVerify( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) +static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) { - UINT uiRdbk = 0; - UINT uiIndex = 0; - UINT uiData = 0; - UINT auiData[4] = {0}; + UINT uiRdbk = 0; + UINT uiIndex = 0; + UINT uiData = 0; + UINT auiData[4] = {0}; - while(uiNumBytes) + while (uiNumBytes) { - if(Adapter->device_removed ) + if (Adapter->device_removed) { return -1; } - if(uiNumBytes >= MAX_RW_SIZE) - {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. - BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE); + if (uiNumBytes >= MAX_RW_SIZE) + { // for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. + BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) + if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { // re-write - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE); mdelay(3); - BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE); + BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) + if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { return -1; } @@ -1735,18 +1691,17 @@ static INT BeceemEEPROMReadBackandVerify( uiOffset += MAX_RW_SIZE; uiNumBytes -= MAX_RW_SIZE; uiIndex += 4; - } - else if(uiNumBytes >= 4) + else if (uiNumBytes >= 4) { - BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4); - if(uiData != pBuffer[uiIndex]) + BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); + if (uiData != pBuffer[uiIndex]) { - //re-write - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,4,FALSE); + // re-write + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE); mdelay(3); - BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4); - if(uiData != pBuffer[uiIndex]) + BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); + if (uiData != pBuffer[uiIndex]) { return -1; } @@ -1754,20 +1709,18 @@ static INT BeceemEEPROMReadBackandVerify( uiOffset += 4; uiNumBytes -= 4; uiIndex++; - } else { // Handle the reads less than 4 bytes... uiData = 0; - memcpy(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes); - BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4); + memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(UINT)), uiNumBytes); + BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); - if(memcmp(&uiData, &uiRdbk, uiNumBytes)) + if (memcmp(&uiData, &uiRdbk, uiNumBytes)) return -1; uiNumBytes = 0; } - } return 0; @@ -1775,7 +1728,7 @@ static INT BeceemEEPROMReadBackandVerify( static VOID BcmSwapWord(UINT *ptr1) { - UINT tempval = (UINT)*ptr1; + UINT tempval = (UINT)*ptr1; char *ptr2 = (char *)&tempval; char *ptr = (char *)ptr1; @@ -1791,95 +1744,95 @@ static VOID BcmSwapWord(UINT *ptr1) { // Description: Performs page write (16bytes) to the EEPROM // // Arguments: -// Adapter - ptr to Adapter object instance -// uiData - Data to be written. -// uiOffset - Offset of the EEPROM where data needs to be written to. +// Adapter - ptr to Adapter object instance +// uiData - Data to be written. +// uiOffset - Offset of the EEPROM where data needs to be written to. // Returns: // OSAL_STATUS_CODE // //----------------------------------------------------------------------------- -static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset ) + +static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset) { - UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + UINT uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; UINT uiStatus = 0; UCHAR uiEpromStatus = 0; - UINT value =0 ; + UINT value = 0; /* Flush the Write/Read/Cmd queues. */ - value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH ); - wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - value = 0 ; - wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) ); + value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH); + wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + value = 0; + wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); /* Clear the Empty/Avail/Full bits. After this it has been confirmed * that the bit was cleared by reading back the register. See NOTE below. * We also clear the Read queues as we do a EEPROM status register read * later. */ - value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ; - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); + value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); /* Enable write */ - value = EEPROM_WRITE_ENABLE ; - wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) ); + value = EEPROM_WRITE_ENABLE; + wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); /* We can write back to back 8bits * 16 into the queue and as we have * checked for the queue to be empty we can write in a burst. */ value = uiData[0]; BcmSwapWord(&value); - wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); value = uiData[1]; BcmSwapWord(&value); - wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); value = uiData[2]; BcmSwapWord(&value); - wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); value = uiData[3]; BcmSwapWord(&value); - wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); + wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG * shows that we see 7 for the EEPROM data write. Which means that * queue got full, also space is available as well as the queue is empty. * This may happen in sequence. */ - value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset ; - wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) ); + value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset; + wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); /* Ideally we should loop here without tries and eventually succeed. * What we are checking if the previous write has completed, and this * may take time. We should wait till the Empty bit is set. */ uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 ) + while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) { uiRetries--; - if ( uiRetries == 0 ) + if (uiRetries == 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY); - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); + return STATUS_FAILURE; } - if( !(uiRetries%RETRIES_PER_DELAY) ) - msleep(1); + if (!(uiRetries%RETRIES_PER_DELAY)) + msleep(1); uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if(Adapter->device_removed == TRUE) + if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop...."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop...."); return -ENODEV; } - } - if ( uiRetries != 0 ) + if (uiRetries != 0) { /* Clear the ones that are set - either, Empty/Full/Avail bits */ - value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) ); - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL)); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); } /* Here we should check if the EEPROM status register is correct before @@ -1887,82 +1840,79 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy * with the previous write. Note also that issuing this read finally * means the previous write to the EEPROM has completed. */ - uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY; + uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; uiEpromStatus = 0; - while ( uiRetries != 0 ) + while (uiRetries != 0) { - uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ; - if(Adapter->device_removed == TRUE) + uiEpromStatus = ReadEEPROMStatusRegister(Adapter); + if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); return -ENODEV; } - if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 ) + if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) ); - return STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries)); + return STATUS_SUCCESS; } uiRetries--; - if ( uiRetries == 0 ) + if (uiRetries == 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY); - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); + return STATUS_FAILURE; } uiEpromStatus = 0; - if( !(uiRetries%RETRIES_PER_DELAY) ) - msleep(1); + if (!(uiRetries%RETRIES_PER_DELAY)) + msleep(1); } - return STATUS_SUCCESS ; + return STATUS_SUCCESS; } /* BeceemEEPROMWritePage */ - //----------------------------------------------------------------------------- // Procedure: BeceemEEPROMBulkWrite // // Description: Performs write to the EEPROM // // Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the EEPROM where data needs to be written to. -// uiNumBytes - Number of bytes to be written. -// bVerify - read verify flag. +// Adapter - ptr to Adapter object instance +// pBuffer - Data to be written. +// uiOffset - Offset of the EEPROM where data needs to be written to. +// uiNumBytes - Number of bytes to be written. +// bVerify - read verify flag. // Returns: // OSAL_STATUS_CODE // //----------------------------------------------------------------------------- -INT BeceemEEPROMBulkWrite( - struct bcm_mini_adapter *Adapter, - PUCHAR pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify) +INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, + PUCHAR pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) { - UINT uiBytesToCopy = uiNumBytes; - //UINT uiRdbk = 0; - UINT uiData[4] = {0}; - UINT uiIndex = 0; - UINT uiTempOffset = 0; - UINT uiExtraBytes = 0; - //PUINT puiBuffer = (PUINT)pBuffer; - //INT value; + UINT uiBytesToCopy = uiNumBytes; + // UINT uiRdbk = 0; + UINT uiData[4] = {0}; + UINT uiIndex = 0; + UINT uiTempOffset = 0; + UINT uiExtraBytes = 0; + // PUINT puiBuffer = (PUINT)pBuffer; + // INT value; - if(uiOffset%MAX_RW_SIZE && uiBytesToCopy) + if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { - uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE); - uiExtraBytes = uiOffset-uiTempOffset; - + uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); + uiExtraBytes = uiOffset - uiTempOffset; - BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE); + BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE); - if(uiBytesToCopy >= (16 -uiExtraBytes)) + if (uiBytesToCopy >= (16 - uiExtraBytes)) { - memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes); + memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes); - if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) ) - return STATUS_FAILURE; + if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) + return STATUS_FAILURE; uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes); uiIndex += (MAX_RW_SIZE - uiExtraBytes); @@ -1970,50 +1920,46 @@ INT BeceemEEPROMBulkWrite( } else { - memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy); + memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy); - if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) ) - return STATUS_FAILURE; + if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) + return STATUS_FAILURE; uiIndex += uiBytesToCopy; uiOffset += uiBytesToCopy; uiBytesToCopy = 0; } - - } - while(uiBytesToCopy) + while (uiBytesToCopy) { - if(Adapter->device_removed) + if (Adapter->device_removed) { return -1; } - if(uiBytesToCopy >= MAX_RW_SIZE) + if (uiBytesToCopy >= MAX_RW_SIZE) { - - if (STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, (PUINT) &pBuffer[uiIndex], uiOffset ) ) - return STATUS_FAILURE; + if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset)) + return STATUS_FAILURE; uiIndex += MAX_RW_SIZE; uiOffset += MAX_RW_SIZE; - uiBytesToCopy -= MAX_RW_SIZE; + uiBytesToCopy -= MAX_RW_SIZE; } else { - // - // To program non 16byte aligned data, read 16byte and then update. - // - BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16); - memcpy(&uiData[0],pBuffer+uiIndex,uiBytesToCopy); + // + // To program non 16byte aligned data, read 16byte and then update. + // + BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16); + memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy); + if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset)) + return STATUS_FAILURE; - if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) ) - return STATUS_FAILURE; uiBytesToCopy = 0; } - } return 0; @@ -2035,40 +1981,41 @@ INT BeceemEEPROMBulkWrite( // - if failed. //----------------------------------------------------------------------------- -INT BeceemNVMRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) +INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes) { INT Status = 0; -#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT uiTemp = 0, value; -#endif - if(Adapter->eNVMType == NVM_FLASH) + #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT uiTemp = 0, value; + #endif + + if (Adapter->eNVMType == NVM_FLASH) { - if(Adapter->bFlashRawRead == FALSE) + if (Adapter->bFlashRawRead == FALSE) { - if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD)) - return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes); - uiOffset = uiOffset+ Adapter->ulFlashCalStart ; + if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) + return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes); + + uiOffset = uiOffset + Adapter->ulFlashCalStart; } -#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); -#else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); - Status = BeceemFlashBulkRead(Adapter, + #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); + #else + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); + Status = BeceemFlashBulkRead(Adapter, pBuffer, uiOffset, uiNumBytes); - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); -#endif + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + #endif } - else if(Adapter->eNVMType == NVM_EEPROM) + else if (Adapter->eNVMType == NVM_EEPROM) { Status = BeceemEEPROMBulkRead(Adapter, pBuffer, @@ -2079,6 +2026,7 @@ INT BeceemNVMRead( { Status = -1; } + return Status; } @@ -2098,72 +2046,72 @@ INT BeceemNVMRead( // - if failed. //----------------------------------------------------------------------------- -INT BeceemNVMWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify) +INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify) { INT Status = 0; UINT uiTemp = 0; UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT uiIndex = 0; -#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT value; -#endif + + #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT value; + #endif + UINT uiFlashOffset = 0; - if(Adapter->eNVMType == NVM_FLASH) + if (Adapter->eNVMType == NVM_FLASH) { - if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD)) - Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify); + if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) + Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify); else { uiFlashOffset = uiOffset + Adapter->ulFlashCalStart; -#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes); -#else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); + #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); + #else + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - if(Adapter->bStatusWrite == TRUE) - { - Status = BeceemFlashBulkWriteStatus(Adapter, - pBuffer, - uiFlashOffset, - uiNumBytes , - bVerify); - } - else - { + if (Adapter->bStatusWrite == TRUE) + { + Status = BeceemFlashBulkWriteStatus(Adapter, + pBuffer, + uiFlashOffset, + uiNumBytes , + bVerify); + } + else + { - Status = BeceemFlashBulkWrite(Adapter, - pBuffer, - uiFlashOffset, - uiNumBytes, - bVerify); - } -#endif + Status = BeceemFlashBulkWrite(Adapter, + pBuffer, + uiFlashOffset, + uiNumBytes, + bVerify); + } + #endif } - - if(uiOffset >= EEPROM_CALPARAM_START) + if (uiOffset >= EEPROM_CALPARAM_START) { uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START); - while(uiNumBytes) + while (uiNumBytes) { - if(uiNumBytes > BUFFER_4K) + if (uiNumBytes > BUFFER_4K) { - wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K); + wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K); uiNumBytes -= BUFFER_4K; uiIndex += BUFFER_4K; } else { - wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes); + wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes); uiNumBytes = 0; break; } @@ -2171,45 +2119,43 @@ INT BeceemNVMWrite( } else { - if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START) + if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) { ULONG ulBytesTobeSkipped = 0; - PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases. + PUCHAR pcBuffer = (PUCHAR)pBuffer; // char pointer to take care of odd byte cases. uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); uiOffset += (EEPROM_CALPARAM_START - uiOffset); - while(uiNumBytes) + while (uiNumBytes) { - if(uiNumBytes > BUFFER_4K) + if (uiNumBytes > BUFFER_4K) { - wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K); + wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K); uiNumBytes -= BUFFER_4K; uiIndex += BUFFER_4K; } else { - wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes); + wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes); uiNumBytes = 0; break; } } - } } - - // restore the values. - wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp)); + // restore the values. + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); } - else if(Adapter->eNVMType == NVM_EEPROM) + else if (Adapter->eNVMType == NVM_EEPROM) { Status = BeceemEEPROMBulkWrite(Adapter, (PUCHAR)pBuffer, uiOffset, uiNumBytes, bVerify); - if(bVerify) + if (bVerify) { - Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes); + Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes); } } else @@ -2233,47 +2179,41 @@ INT BeceemNVMWrite( // - if failed. //----------------------------------------------------------------------------- -INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize) +INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) { INT Status = -1; FLASH_CS_INFO sFlashCsInfo = {0}; UINT uiTemp = 0; - UINT uiSectorSig = 0; UINT uiCurrentSectorSize = 0; - UINT value; - - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); value = 0; - wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); -// -// Before updating the sector size in the reserved area, check if already present. -// - BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo)); + // + // Before updating the sector size in the reserved area, check if already present. + // + BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo)); uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); - if(uiSectorSig == FLASH_SECTOR_SIZE_SIG) + if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { - - if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) + if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) { - if(uiSectorSize == uiCurrentSectorSize) + if (uiSectorSize == uiCurrentSectorSize) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash"); Status = STATUS_SUCCESS; - goto Restore ; + goto Restore; } } } - if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) + if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) { - sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize); sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG); @@ -2282,17 +2222,13 @@ INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize) Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo), TRUE); - - } - Restore : +Restore: // restore the values. - wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp)); - + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); return Status; - } //----------------------------------------------------------------------------- @@ -2313,44 +2249,42 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe UINT uiSectorSize = 0; UINT uiSectorSig = 0; - if(Adapter->bSectorSizeOverride && + if (Adapter->bSectorSizeOverride && (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) { Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; } else { - uiSectorSig = FlashSectorSizeSig; - if(uiSectorSig == FLASH_SECTOR_SIZE_SIG) + if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { uiSectorSize = FlashSectorSize; - // - // If the sector size stored in the FLASH makes sense then use it. - // - if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) + // + // If the sector size stored in the FLASH makes sense then use it. + // + if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) { Adapter->uiSectorSize = uiSectorSize; } - //No valid size in FLASH, check if Config file has it. - else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) + //No valid size in FLASH, check if Config file has it. + else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; } - // Init to Default, if none of the above works. + // Init to Default, if none of the above works. else { Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; } - } else { - if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) + if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; } @@ -2361,7 +2295,8 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe } } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x \n", Adapter->uiSectorSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize); + return Adapter->uiSectorSize; } @@ -2383,20 +2318,20 @@ static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) /* CHIP Bug : Clear the Avail bits on the Read queue. The default * value on this register is supposed to be 0x00001102. * But we get 0x00001122. */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" ); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n"); value = EEPROM_READ_DATA_AVAIL; - wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); + wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); /* Flush the all the EEPROM queues. */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n"); - value =EEPROM_ALL_QUEUE_FLUSH ; - wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n"); + value = EEPROM_ALL_QUEUE_FLUSH; + wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); value = 0; - wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) ); + wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); /* Read the EEPROM Status Register. Just to see, no real purpose. */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) ); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter)); return STATUS_SUCCESS; } /* BcmInitEEPROMQueues() */ @@ -2418,15 +2353,15 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) BcmValidateNvmType(ps_adapter); BcmInitEEPROMQueues(ps_adapter); - if(ps_adapter->eNVMType == NVM_AUTODETECT) + if (ps_adapter->eNVMType == NVM_AUTODETECT) { ps_adapter->eNVMType = BcmGetNvmType(ps_adapter); - if(ps_adapter->eNVMType == NVM_UNKNOWN) + if (ps_adapter->eNVMType == NVM_UNKNOWN) { - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); } } - else if(ps_adapter->eNVMType == NVM_FLASH) + else if (ps_adapter->eNVMType == NVM_FLASH) { BcmGetFlashCSInfo(ps_adapter); } @@ -2435,6 +2370,7 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) return STATUS_SUCCESS; } + /***************************************************************************/ /*BcmGetNvmSize : set the EEPROM or flash size in Adapter. * @@ -2447,11 +2383,11 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) { - if(Adapter->eNVMType == NVM_EEPROM) + if (Adapter->eNVMType == NVM_EEPROM) { Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); } - else if(Adapter->eNVMType == NVM_FLASH) + else if (Adapter->eNVMType == NVM_FLASH) { Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter); } @@ -2469,21 +2405,22 @@ static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) // Returns: // //----------------------------------------------------------------------------- + static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) { - // // if forcing the FLASH through CFG file, we should ensure device really has a FLASH. // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. // - if(Adapter->eNVMType == NVM_FLASH && + if (Adapter->eNVMType == NVM_FLASH && Adapter->chip_id < 0xBECE3300) { Adapter->eNVMType = NVM_AUTODETECT; } } + //----------------------------------------------------------------------------- // Procedure: BcmReadFlashRDID // @@ -2495,55 +2432,56 @@ static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) // Returns: // Flash ID //----------------------------------------------------------------------------- + static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) { ULONG ulRDID = 0; UINT value; -// -// Read ID Instruction. -// - value = (FLASH_CMD_READ_ID<<24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)); -//Delay - udelay(10); -// -// Read SPI READQ REG. The output will be WWXXYYZZ. -// The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. -// - rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); + // + // Read ID Instruction. + // + value = (FLASH_CMD_READ_ID << 24); + wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - return (ulRDID >>8); + //Delay + udelay(10); + // + // Read SPI READQ REG. The output will be WWXXYYZZ. + // The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. + // + rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); + return (ulRDID >> 8); } INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { - if(psAdapter == NULL) + if (psAdapter == NULL) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL); - if(psAdapter->psFlashCSInfo == NULL) + if (psAdapter->psFlashCSInfo == NULL) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x"); return -ENOMEM; } psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL); - if(psAdapter->psFlash2xCSInfo == NULL) + if (psAdapter->psFlash2xCSInfo == NULL) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); return -ENOMEM; } psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL); - if(psAdapter->psFlash2xVendorInfo == NULL) + if (psAdapter->psFlash2xVendorInfo == NULL) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); kfree(psAdapter->psFlash2xCSInfo); return -ENOMEM; @@ -2554,89 +2492,91 @@ INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { - if(psAdapter == NULL) + if (psAdapter == NULL) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } kfree(psAdapter->psFlashCSInfo); kfree(psAdapter->psFlash2xCSInfo); kfree(psAdapter->psFlash2xVendorInfo); - return STATUS_SUCCESS ; + return STATUS_SUCCESS; } -static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,struct bcm_mini_adapter *Adapter) +static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) { UINT Index = 0; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware )); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); - for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); + + for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, (psFlash2xCSInfo->SectorAccessBitMap[Index])); } return STATUS_SUCCESS; } - -static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) +static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) { UINT Index = 0; + psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); - psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion); + psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion); //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion); - psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); + psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage); psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware ); + psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware); psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage); psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart); psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd); @@ -2675,51 +2615,51 @@ static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End); psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start); psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End); - for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++) + + for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) { - psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); + psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); } return STATUS_SUCCESS; } -static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) +static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) { //UINT Index = 0; - psFlashCSInfo->MagicNumber =ntohl(psFlashCSInfo->MagicNumber); - psFlashCSInfo->FlashLayoutVersion =ntohl(psFlashCSInfo->FlashLayoutVersion); - psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); + psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); + psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion); + psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); //won't convert according to old assumption - psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion); - - psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); - psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); - psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware ); - psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage); - psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart); - psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd); - psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart); - psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd); - psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart); - psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData); - psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout); - psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature); - psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig); - psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize); - psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize); - psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize); - psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr); - psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize); - psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig); - psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout); + psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion); + psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); + psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); + psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware); + psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage); + psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart); + psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd); + psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart); + psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd); + psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart); + psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData); + psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout); + psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature); + psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig); + psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize); + psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize); + psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize); + psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr); + psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize); + psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig); + psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout); return STATUS_SUCCESS; } static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section) { - return ( Adapter->uiVendorExtnFlag && - (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && - (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) ); + return (Adapter->uiVendorExtnFlag && + (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && + (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS)); } static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) @@ -2729,16 +2669,16 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) Adapter->uiVendorExtnFlag = FALSE; - for(i = 0;i < TOTAL_SECTIONS;i++) + for (i = 0; i < TOTAL_SECTIONS; i++) Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS; - if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo)) + if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo)) return; i = 0; - while(i < TOTAL_SECTIONS) + while (i < TOTAL_SECTIONS) { - if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) + if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) { i++; continue; @@ -2746,59 +2686,58 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) Adapter->uiVendorExtnFlag = TRUE; uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd - - Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); + Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); - switch(i) + switch (i) { - case DSD0: - if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; - break; + case DSD0: + if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; + break; - case DSD1: - if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; - break; + case DSD1: + if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; + break; - case DSD2: - if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; - break; - case VSA0: - if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; - break; + case DSD2: + if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; + break; + case VSA0: + if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; + break; - case VSA1: - if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; - break; - case VSA2: - if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; - break; + case VSA1: + if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; + break; + case VSA2: + if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; + break; - default: - break; + default: + break; } i++; } - } //----------------------------------------------------------------------------- @@ -2817,21 +2756,21 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) { //FLASH_CS_INFO sFlashCsInfo = {0}; -#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT value; -#endif + #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT value; + #endif + UINT uiFlashLayoutMajorVersion; Adapter->uiFlashLayoutMinorVersion = 0; Adapter->uiFlashLayoutMajorVersion = 0; Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; - Adapter->uiFlashBaseAdd = 0; Adapter->ulFlashCalStart = 0; - memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO)); - memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO)); + memset(Adapter->psFlashCSInfo, 0 , sizeof(FLASH_CS_INFO)); + memset(Adapter->psFlash2xCSInfo, 0 , sizeof(FLASH2X_CS_INFO)); - if(!Adapter->bDDRInitDone) + if (!Adapter->bDDRInitDone) { { value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; @@ -2839,17 +2778,16 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) } } - // Reading first 8 Bytes to get the Flash Layout // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) - BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8); + BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8); Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); - if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) + if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) { uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); @@ -2860,71 +2798,68 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) uiFlashLayoutMajorVersion = 0; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); - if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) + if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) { - BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO)); + BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(FLASH_CS_INFO)); ConvertEndianOfCSStructure(Adapter->psFlashCSInfo); Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart); - if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) + if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) { Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart; } - if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && - (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && - (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && - (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) + if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && + (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && + (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && + (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) { Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize); - Adapter->fpFlashWrite = flashByteWrite; - Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; + Adapter->fpFlashWrite = flashByteWrite; + Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; } else { Adapter->ulFlashWriteSize = MAX_RW_SIZE; Adapter->fpFlashWrite = flashWrite; - Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; + Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; } BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig), - (Adapter->psFlashCSInfo->FlashSectorSize)); - - + (Adapter->psFlashCSInfo->FlashSectorSize)); Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF; - - } else { - if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL, - Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO))) + if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL, + Adapter->ulFlashControlSectionStart, sizeof(FLASH2X_CS_INFO))) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n"); return STATUS_FAILURE; } + ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo); - BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter); - if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && - (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && - (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && - (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) + BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter); + if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && + (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && + (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && + (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) { Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize; - Adapter->fpFlashWrite = flashByteWrite; - Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; + Adapter->fpFlashWrite = flashByteWrite; + Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; } else { Adapter->ulFlashWriteSize = MAX_RW_SIZE; Adapter->fpFlashWrite = flashWrite; - Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; + Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; } BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig, - Adapter->psFlash2xCSInfo->FlashSectorSize); + Adapter->psFlash2xCSInfo->FlashSectorSize); UpdateVendorInfo(Adapter); @@ -2932,21 +2867,17 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) BcmGetActiveISO(Adapter); Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF; Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart; - } /* - Concerns: what if CS sector size does not match with this sector size ??? - what is the indication of AccessBitMap in CS in flash 2.x ???? + Concerns: what if CS sector size does not match with this sector size ??? + what is the indication of AccessBitMap in CS in flash 2.x ???? */ Adapter->ulFlashID = BcmReadFlashRDID(Adapter); - Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; - - return STATUS_SUCCESS ; + return STATUS_SUCCESS; } - //----------------------------------------------------------------------------- // Procedure: BcmGetNvmType // @@ -2964,33 +2895,33 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) { UINT uiData = 0; - BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4); - if(uiData == BECM) + BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); + if (uiData == BECM) { return NVM_EEPROM; } + // // Read control struct and get cal addresses before accessing the flash // BcmGetFlashCSInfo(Adapter); - BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4); - if(uiData == BECM) + BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4); + if (uiData == BECM) { return NVM_FLASH; } -// -// even if there is no valid signature on EEPROM/FLASH find out if they really exist. -// if exist select it. -// - if(BcmGetEEPROMSize(Adapter)) + + // + // even if there is no valid signature on EEPROM/FLASH find out if they really exist. + // if exist select it. + // + if (BcmGetEEPROMSize(Adapter)) { return NVM_EEPROM; } -//TBD for Flash. - - + //TBD for Flash. return NVM_UNKNOWN; } @@ -3007,84 +2938,85 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { /* - * Considering all the section for which end offset can be calculated or directly given - * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section - * endoffset can't be calculated or given in CS Structure. - */ + * Considering all the section for which end offset can be calculated or directly given + * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section + * endoffset can't be calculated or given in CS Structure. + */ - INT SectStartOffset = 0 ; + INT SectStartOffset = 0; - SectStartOffset = INVALID_OFFSET ; + SectStartOffset = INVALID_OFFSET; - if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal)) + if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal)) { return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart; } - switch(eFlashSectionVal) - { - case ISO_IMAGE1 : - if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - break; - case ISO_IMAGE2 : - if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - break; - case DSD0 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); - break; - case DSD1 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); - break; - case DSD2 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); - break; - case VSA0 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); - break; - case VSA1 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); - break; - case VSA2 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); - break; - case SCSI : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - break; - case CONTROL_SECTION : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); - break; - case ISO_IMAGE1_PART2 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); - break; - case ISO_IMAGE1_PART3 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - break; - case ISO_IMAGE2_PART2 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); - break; - case ISO_IMAGE2_PART3 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - break; - default : - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x"); - SectStartOffset = INVALID_OFFSET; + switch (eFlashSectionVal) + { + case ISO_IMAGE1: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); + break; + case ISO_IMAGE2: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); + break; + case DSD0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); + break; + case DSD1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); + break; + case DSD2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); + break; + case VSA0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); + break; + case VSA1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); + break; + case VSA2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); + break; + case SCSI: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); + break; + case CONTROL_SECTION: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); + break; + case ISO_IMAGE1_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); + break; + case ISO_IMAGE1_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + break; + case ISO_IMAGE2_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); + break; + case ISO_IMAGE2_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + break; + default: + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); + SectStartOffset = INVALID_OFFSET; } + return SectStartOffset; } @@ -3100,78 +3032,78 @@ INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { - INT SectEndOffset = 0 ; - SectEndOffset = INVALID_OFFSET; + INT SectEndOffset = 0; - if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal)) + SectEndOffset = INVALID_OFFSET; + if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) { return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd; } - switch(eFlash2xSectionVal) + switch (eFlash2xSectionVal) { - case ISO_IMAGE1 : - if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); - break; - case ISO_IMAGE2 : - if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) && + case ISO_IMAGE1: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) && (IsNonCDLessDevice(Adapter) == FALSE)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); - break; - case DSD0 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); + break; + case ISO_IMAGE2: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); + break; + case DSD0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); break; - case DSD1 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) + case DSD1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); break; - case DSD2 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) + case DSD2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); break; - case VSA0 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) + case VSA0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); break; - case VSA1 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) + case VSA1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); break; - case VSA2 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) + case VSA2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); break; - case SCSI : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + case SCSI: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + - (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); + (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); + break; + case CONTROL_SECTION: + //Not Clear So Putting failure. confirm and fix it. + SectEndOffset = STATUS_FAILURE; + case ISO_IMAGE1_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); + break; + case ISO_IMAGE1_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); + break; + case ISO_IMAGE2_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); break; - case CONTROL_SECTION : - //Not Clear So Putting failure. confirm and fix it. - SectEndOffset = STATUS_FAILURE; - case ISO_IMAGE1_PART2 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); - break; - case ISO_IMAGE1_PART3 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); - break; - case ISO_IMAGE2_PART2 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); - break; - case ISO_IMAGE2_PART3 : - if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); - break; - - default : + case ISO_IMAGE2_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); + break; + default: SectEndOffset = INVALID_OFFSET; } + return SectEndOffset ; } @@ -3187,57 +3119,54 @@ INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ * return true on success and STATUS_FAILURE on fail. */ -INT BcmFlash2xBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - FLASH2X_SECTION_VAL eFlash2xSectionVal, - UINT uiOffsetWithinSectionVal, - UINT uiNumBytes) +INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + FLASH2X_SECTION_VAL eFlash2xSectionVal, + UINT uiOffsetWithinSectionVal, + UINT uiNumBytes) { - INT Status = STATUS_SUCCESS; INT SectionStartOffset = 0; - UINT uiAbsoluteOffset = 0 ; - UINT uiTemp =0, value =0 ; - if(Adapter == NULL) + UINT uiAbsoluteOffset = 0; + UINT uiTemp = 0, value = 0; + + if (Adapter == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); return -EINVAL; } - if(Adapter->device_removed ) + if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); return -ENODEV; } //NO_SECTION_VAL means absolute offset is given. - if(eFlash2xSectionVal == NO_SECTION_VAL) + if (eFlash2xSectionVal == NO_SECTION_VAL) SectionStartOffset = 0; else - SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); + SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - if(SectionStartOffset == STATUS_FAILURE ) + if (SectionStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal); return -EINVAL; } - if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal)) - return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); + if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) + return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); //calculating the absolute offset from FLASH; uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset; rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); value = 0; - wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); - - Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ; - + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); + Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes); wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if(Status) + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); - return Status ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); + return Status; } return Status; @@ -3256,42 +3185,42 @@ INT BcmFlash2xBulkRead( * */ -INT BcmFlash2xBulkWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - FLASH2X_SECTION_VAL eFlash2xSectVal, - UINT uiOffset, - UINT uiNumBytes, - UINT bVerify) +INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, + PUINT pBuffer, + FLASH2X_SECTION_VAL eFlash2xSectVal, + UINT uiOffset, + UINT uiNumBytes, + UINT bVerify) { - - INT Status = STATUS_SUCCESS; + INT Status = STATUS_SUCCESS; UINT FlashSectValStartOffset = 0; UINT uiTemp = 0, value = 0; - if(Adapter == NULL) + + if (Adapter == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); return -EINVAL; } - if(Adapter->device_removed ) + + if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); return -ENODEV; } //NO_SECTION_VAL means absolute offset is given. - if(eFlash2xSectVal == NO_SECTION_VAL) + if (eFlash2xSectVal == NO_SECTION_VAL) FlashSectValStartOffset = 0; else - FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal); + FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal); - if(FlashSectValStartOffset == STATUS_FAILURE ) + if (FlashSectValStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal); return -EINVAL; } - if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal)) + if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal)) return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify); //calculating the absolute offset from FLASH; @@ -3299,19 +3228,18 @@ INT BcmFlash2xBulkWrite( rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); value = 0; - wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify); + Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify); wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if(Status) + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); - return Status ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); + return Status; } return Status; - } /** @@ -3322,35 +3250,36 @@ INT BcmFlash2xBulkWrite( * Return STATUS_SUCESS if get success in setting the right DSD else negaive error code * **/ + static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) { - FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ; + FLASH2X_SECTION_VAL uiHighestPriDSD = 0; uiHighestPriDSD = getHighestPriDSD(Adapter); Adapter->eActiveDSD = uiHighestPriDSD; - if(DSD0 == uiHighestPriDSD) + if (DSD0 == uiHighestPriDSD) Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; - if(DSD1 == uiHighestPriDSD) + if (DSD1 == uiHighestPriDSD) Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; - if(DSD2 == uiHighestPriDSD) + if (DSD2 == uiHighestPriDSD) Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; - if(Adapter->eActiveDSD) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); - if(Adapter->eActiveDSD == 0) + if (Adapter->eActiveDSD) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); + if (Adapter->eActiveDSD == 0) { //if No DSD gets Active, Make Active the DSD with WR permission - if(IsSectionWritable(Adapter,DSD2)) + if (IsSectionWritable(Adapter, DSD2)) { Adapter->eActiveDSD = DSD2; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; } - else if(IsSectionWritable(Adapter,DSD1)) + else if (IsSectionWritable(Adapter, DSD1)) { Adapter->eActiveDSD = DSD1; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; } - else if(IsSectionWritable(Adapter,DSD0)) + else if (IsSectionWritable(Adapter, DSD0)) { Adapter->eActiveDSD = DSD0; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; @@ -3360,7 +3289,6 @@ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) return STATUS_SUCCESS; } - /** * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue * @Adapter : Driver private Data Structure @@ -3373,18 +3301,18 @@ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter) { + INT HighestPriISO = 0; - INT HighestPriISO = 0 ; HighestPriISO = getHighestPriISO(Adapter); - Adapter->eActiveISO = HighestPriISO ; - if(Adapter->eActiveISO == ISO_IMAGE2) + Adapter->eActiveISO = HighestPriISO; + if (Adapter->eActiveISO == ISO_IMAGE2) Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - else if(Adapter->eActiveISO == ISO_IMAGE1) + else if (Adapter->eActiveISO == ISO_IMAGE1) Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - if(Adapter->eActiveISO) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO); + if (Adapter->eActiveISO) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO); return STATUS_SUCCESS; } @@ -3399,25 +3327,27 @@ static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter) * Failure:-FALSE, offset is RO * **/ + B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) { UINT uiSectorNum = 0; - UINT uiWordOfSectorPermission =0; + UINT uiWordOfSectorPermission = 0; UINT uiBitofSectorePermission = 0; B_UINT32 permissionBits = 0; + uiSectorNum = uiOffset/Adapter->uiSectorSize; - //calculating the word having this Sector Access permission from SectorAccessBitMap Array - uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16]; + // calculating the word having this Sector Access permission from SectorAccessBitMap Array + uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16]; - //calculating the bit index inside the word for this sector - uiBitofSectorePermission = 2*(15 - uiSectorNum %16); + // calculating the bit index inside the word for this sector + uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16); - //Setting Access permission - permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ; + // Setting Access permission + permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission); permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3; - if(permissionBits == SECTOR_READWRITE_PERMISSION) - return TRUE; + if (permissionBits == SECTOR_READWRITE_PERMISSION) + return TRUE; else return FALSE; } @@ -3425,17 +3355,18 @@ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0 :0X%x", psFlash2xBitMap->DSD0); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1 :0X%x", psFlash2xBitMap->DSD1); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2 :0X%x", psFlash2xBitMap->DSD2); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0 :0X%x", psFlash2xBitMap->VSA0); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1 :0X%x", psFlash2xBitMap->VSA1); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2 :0X%x", psFlash2xBitMap->VSA2); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI :0X%x", psFlash2xBitMap->SCSI); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION); return STATUS_SUCCESS; } @@ -3458,33 +3389,31 @@ static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap) { - - PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo; - FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ; - FLASH2X_SECTION_VAL uiHighestPriISO= 0 ; - BOOLEAN SetActiveDSDDone = FALSE ; - BOOLEAN SetActiveISODone = FALSE ; + FLASH2X_SECTION_VAL uiHighestPriDSD = 0; + FLASH2X_SECTION_VAL uiHighestPriISO = 0; + BOOLEAN SetActiveDSDDone = FALSE; + BOOLEAN SetActiveISODone = FALSE; - //For 1.x map all the section except DSD0 will be shown as not present - //This part will be used by calibration tool to detect the number of DSD present in Flash. - if(IsFlash2x(Adapter) == FALSE) + // For 1.x map all the section except DSD0 will be shown as not present + // This part will be used by calibration tool to detect the number of DSD present in Flash. + if (IsFlash2x(Adapter) == FALSE) { psFlash2xBitMap->ISO_IMAGE2 = 0; psFlash2xBitMap->ISO_IMAGE1 = 0; psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present) - psFlash2xBitMap->DSD1 = 0 ; - psFlash2xBitMap->DSD2 = 0 ; - psFlash2xBitMap->VSA0 = 0 ; - psFlash2xBitMap->VSA1 = 0 ; - psFlash2xBitMap->VSA2 = 0 ; - psFlash2xBitMap->CONTROL_SECTION = 0 ; - psFlash2xBitMap->SCSI= 0 ; - psFlash2xBitMap->Reserved0 = 0 ; - psFlash2xBitMap->Reserved1 = 0 ; - psFlash2xBitMap->Reserved2 = 0 ; - return STATUS_SUCCESS ; + psFlash2xBitMap->DSD1 = 0; + psFlash2xBitMap->DSD2 = 0; + psFlash2xBitMap->VSA0 = 0; + psFlash2xBitMap->VSA1 = 0; + psFlash2xBitMap->VSA2 = 0; + psFlash2xBitMap->CONTROL_SECTION = 0; + psFlash2xBitMap->SCSI = 0; + psFlash2xBitMap->Reserved0 = 0; + psFlash2xBitMap->Reserved1 = 0; + psFlash2xBitMap->Reserved2 = 0; + return STATUS_SUCCESS; } uiHighestPriDSD = getHighestPriDSD(Adapter); @@ -3493,76 +3422,70 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // IS0 IMAGE 2 /// - if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) { //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; + psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; - - if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER) + if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID; - - //Calculation for extrating the Access permission - if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE) + // Calculation for extrating the Access permission + if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE) psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; - if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) + if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) { - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ; + psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT; SetActiveISODone = TRUE; } - } /// // IS0 IMAGE 1 /// - if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. + // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; - if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) + if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID; - // Calculation for extrating the Access permission - if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE) + // Calculation for extrating the Access permission + if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE) psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; - if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) + if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) { - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ; + psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT; SetActiveISODone = TRUE; } } - - /// // DSD2 /// - if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) { //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; + psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; - if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER) + if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; - //Calculation for extrating the Access permission - if(IsSectionWritable(Adapter, DSD2) == FALSE) + // Calculation for extrating the Access permission + if (IsSectionWritable(Adapter, DSD2) == FALSE) { psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; - } else { //Means section is writable - if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) + if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) { - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ; - SetActiveDSDDone =TRUE ; + psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT; + SetActiveDSDDone = TRUE; } } } @@ -3570,178 +3493,163 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // DSD 1 /// - if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; - + // Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; - if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER) + if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; - //Calculation for extrating the Access permission - if(IsSectionWritable(Adapter, DSD1) == FALSE) + // Calculation for extrating the Access permission + if (IsSectionWritable(Adapter, DSD1) == FALSE) { psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; } else { - //Means section is writable - if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) + // Means section is writable + if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) { - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ; - SetActiveDSDDone =TRUE ; + psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT; + SetActiveDSDDone = TRUE; } } - } /// //For DSD 0 // - if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) { //Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; - if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER) + if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; - //Setting Access permission - if(IsSectionWritable(Adapter, DSD0) == FALSE) + // Setting Access permission + if (IsSectionWritable(Adapter, DSD0) == FALSE) { psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; } else { - //Means section is writable - if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0)) + // Means section is writable + if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) { - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ; - SetActiveDSDDone =TRUE ; + psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT; + SetActiveDSDDone = TRUE; } } } /// - // VSA 0 + // VSA 0 /// - if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; + // Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; - //Setting the Access Bit. Map is not defined hece setting it always valid + // Setting the Access Bit. Map is not defined hece setting it always valid psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID; - //Calculation for extrating the Access permission - if(IsSectionWritable(Adapter, VSA0) == FALSE) + // Calculation for extrating the Access permission + if (IsSectionWritable(Adapter, VSA0) == FALSE) psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO; - //By Default section is Active - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ; - + // By Default section is Active + psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT; } - /// - // VSA 1 + // VSA 1 /// - - if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; + // Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; - //Setting the Access Bit. Map is not defined hece setting it always valid - psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID; + // Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID; - //Checking For Access permission - if(IsSectionWritable(Adapter, VSA1) == FALSE) + // Checking For Access permission + if (IsSectionWritable(Adapter, VSA1) == FALSE) psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO; - //By Default section is Active - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ; - + // By Default section is Active + psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT; } - /// - // VSA 2 + // VSA 2 /// - - if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; - + // Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; - //Setting the Access Bit. Map is not defined hece setting it always valid + // Setting the Access Bit. Map is not defined hece setting it always valid psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID; - //Checking For Access permission - if(IsSectionWritable(Adapter, VSA2) == FALSE) + // Checking For Access permission + if (IsSectionWritable(Adapter, VSA2) == FALSE) psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO; - //By Default section is Active - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ; + // By Default section is Active + psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT; } /// // SCSI Section /// - if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. - psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; - + // Setting the 0th Bit representing the Section is present or not. + psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; - //Setting the Access Bit. Map is not defined hece setting it always valid - psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID; + // Setting the Access Bit. Map is not defined hece setting it always valid + psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID; - //Checking For Access permission - if(IsSectionWritable(Adapter, SCSI) == FALSE) + // Checking For Access permission + if (IsSectionWritable(Adapter, SCSI) == FALSE) psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO; - //By Default section is Active - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ; - + // By Default section is Active + psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT; } - /// - // Control Section + // Control Section /// - if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) + if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. + // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); - - //Setting the Access Bit. Map is not defined hece setting it always valid + // Setting the Access Bit. Map is not defined hece setting it always valid psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID; - //Checking For Access permission - if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE) + // Checking For Access permission + if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE) psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO; - //By Default section is Active - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ; - + // By Default section is Active + psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT; } /// - // For Reserved Sections + // For Reserved Sections /// psFlash2xBitMap->Reserved0 = 0; psFlash2xBitMap->Reserved0 = 0; psFlash2xBitMap->Reserved0 = 0; - BcmDumpFlash2xSectionBitMap(psFlash2xBitMap); - return STATUS_SUCCESS ; - + return STATUS_SUCCESS; } + /** BcmSetActiveSection :- Set Active section is used to make priority field highest over other section of same type. @@ -3752,49 +3660,48 @@ BcmSetActiveSection :- Set Active section is used to make priority field highest Return Value:- Make the priorit highest else return erorr code **/ + INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) { unsigned int SectImagePriority = 0; - INT Status =STATUS_SUCCESS; + INT Status = STATUS_SUCCESS; //DSD_HEADER sDSD = {0}; //ISO_HEADER sISO = {0}; INT HighestPriDSD = 0 ; INT HighestPriISO = 0; - - - Status = IsSectionWritable(Adapter,eFlash2xSectVal) ; - if(Status != TRUE ) + Status = IsSectionWritable(Adapter, eFlash2xSectVal); + if (Status != TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal); return STATUS_FAILURE; } - Adapter->bHeaderChangeAllowed = TRUE ; - switch(eFlash2xSectVal) + Adapter->bHeaderChangeAllowed = TRUE; + switch (eFlash2xSectVal) { - case ISO_IMAGE1 : - case ISO_IMAGE2 : - if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER ) + case ISO_IMAGE1: + case ISO_IMAGE2: + if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) { HighestPriISO = getHighestPriISO(Adapter); - if(HighestPriISO == eFlash2xSectVal ) + if (HighestPriISO == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal ); - Status = STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); + Status = STATUS_SUCCESS; break; } SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; - if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO)) + if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) { // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO // by user - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); SectImagePriority = htonl(0x1); Status = BcmFlash2xBulkWrite(Adapter, &SectImagePriority, @@ -3802,152 +3709,144 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), SIGNATURE_SIZE, TRUE); - - if(Status) + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); Status = STATUS_FAILURE; - break ; + break; } HighestPriISO = getHighestPriISO(Adapter); - if(HighestPriISO == eFlash2xSectVal ) + if (HighestPriISO == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal ); - Status = STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); + Status = STATUS_SUCCESS; break; } SectImagePriority = 2; - } - + } SectImagePriority = htonl(SectImagePriority); Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - eFlash2xSectVal, - 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), - SIGNATURE_SIZE, - TRUE); - if(Status) + &SectImagePriority, + eFlash2xSectVal, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly"); - break ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + break; } } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); + Status = STATUS_FAILURE; break; } break; - case DSD0 : - case DSD1 : - case DSD2 : - if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER) + case DSD0: + case DSD1: + case DSD2: + if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) { HighestPriDSD = getHighestPriDSD(Adapter); - - if((HighestPriDSD == eFlash2xSectVal)) + if ((HighestPriDSD == eFlash2xSectVal)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal); + Status = STATUS_SUCCESS; break; } - SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ; - if(SectImagePriority <= 0) + SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; + if (SectImagePriority <= 0) { // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD // by user - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); SectImagePriority = htonl(0x1); Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - - if(Status) + &SectImagePriority, + HighestPriDSD, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + break; } HighestPriDSD = getHighestPriDSD(Adapter); - if((HighestPriDSD == eFlash2xSectVal)) + if ((HighestPriDSD == eFlash2xSectVal)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); - Status = STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); + Status = STATUS_SUCCESS; break; } SectImagePriority = htonl(0x2); Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - - if(Status) + &SectImagePriority, + HighestPriDSD, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + break; } HighestPriDSD = getHighestPriDSD(Adapter); - - if((HighestPriDSD == eFlash2xSectVal)) + if ((HighestPriDSD == eFlash2xSectVal)) { - Status = STATUS_SUCCESS ; + Status = STATUS_SUCCESS; break; } - SectImagePriority = 3 ; + SectImagePriority = 3; } SectImagePriority = htonl(SectImagePriority); Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - eFlash2xSectVal, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), - SIGNATURE_SIZE , - TRUE); - if(Status) + &SectImagePriority, + eFlash2xSectVal, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly"); - Status = STATUS_FAILURE ; - break ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + Status = STATUS_FAILURE; + break; } } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); + Status = STATUS_FAILURE; break; } break; - case VSA0 : - case VSA1 : - case VSA2 : - //Has to be decided - break ; - default : - Status = STATUS_FAILURE ; - break; - + case VSA0: + case VSA1: + case VSA2: + // Has to be decided + break; + default: + Status = STATUS_FAILURE; + break; } - Adapter->bHeaderChangeAllowed = FALSE ; + Adapter->bHeaderChangeAllowed = FALSE; return Status; - } /** @@ -3958,325 +3857,315 @@ BcmCopyISO - Used only for copying the ISO section Return value:- SUCCESS if copies successfully else negative error code **/ + INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut) { - PCHAR Buff = NULL; - FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0; + FLASH2X_SECTION_VAL eISOReadPart = 0, eISOWritePart = 0; UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; UINT uiTotalDataToCopy = 0; - BOOLEAN IsThisHeaderSector = FALSE ; + BOOLEAN IsThisHeaderSector = FALSE; UINT sigOffset = 0; UINT ISOLength = 0; UINT Status = STATUS_SUCCESS; UINT SigBuff[MAX_RW_SIZE]; UINT i = 0; - if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) + if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); return STATUS_FAILURE; } Status = BcmFlash2xBulkRead(Adapter, - &ISOLength, - sCopySectStrut.SrcSection, - 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize), - 4); - - if(Status) + &ISOLength, + sCopySectStrut.SrcSection, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageSize), + 4); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); return Status; } ISOLength = htonl(ISOLength); - - if(ISOLength % Adapter->uiSectorSize) + if (ISOLength % Adapter->uiSectorSize) { - ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize); + ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize); } sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber); Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); - if(Buff == NULL) + if (Buff == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size"); - return -ENOMEM; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size"); + return -ENOMEM; } - if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2) + if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) { - eISOReadPart = ISO_IMAGE1 ; - eISOWritePart = ISO_IMAGE2 ; + eISOReadPart = ISO_IMAGE1; + eISOWritePart = ISO_IMAGE2; uiReadOffsetWithinPart = 0; - uiWriteOffsetWithinPart = 0 ; + uiWriteOffsetWithinPart = 0; - uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - if(uiTotalDataToCopy < ISOLength) + if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); Status = STATUS_FAILURE; goto out; } - uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - if(uiTotalDataToCopy < ISOLength) + if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); Status = STATUS_FAILURE; goto out; } uiTotalDataToCopy = ISOLength; - CorruptISOSig(Adapter,ISO_IMAGE2); - - while(uiTotalDataToCopy) + CorruptISOSig(Adapter, ISO_IMAGE2); + while (uiTotalDataToCopy) { - if(uiTotalDataToCopy == Adapter->uiSectorSize) + if (uiTotalDataToCopy == Adapter->uiSectorSize) { - //Setting for write of first sector. First sector is assumed to be written in last - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector"); - eISOReadPart = ISO_IMAGE1 ; + // Setting for write of first sector. First sector is assumed to be written in last + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); + eISOReadPart = ISO_IMAGE1; uiReadOffsetWithinPart = 0; eISOWritePart = ISO_IMAGE2; - uiWriteOffsetWithinPart = 0 ; - IsThisHeaderSector = TRUE ; - + uiWriteOffsetWithinPart = 0; + IsThisHeaderSector = TRUE; } else { - uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ; - uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ; + uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; + uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) )) + if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { - eISOReadPart = ISO_IMAGE1_PART2 ; + eISOReadPart = ISO_IMAGE1_PART2; uiReadOffsetWithinPart = 0; } - if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) + + if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { - eISOReadPart = ISO_IMAGE1_PART3 ; + eISOReadPart = ISO_IMAGE1_PART3; uiReadOffsetWithinPart = 0; } - if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) + + if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { - eISOWritePart = ISO_IMAGE2_PART2 ; + eISOWritePart = ISO_IMAGE2_PART2; uiWriteOffsetWithinPart = 0; } - if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) + + if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { - eISOWritePart = ISO_IMAGE2_PART3 ; + eISOWritePart = ISO_IMAGE2_PART3; uiWriteOffsetWithinPart = 0; } } Status = BcmFlash2xBulkRead(Adapter, - (PUINT)Buff, - eISOReadPart, - uiReadOffsetWithinPart, - Adapter->uiSectorSize - ); - - if(Status) + (PUINT)Buff, + eISOReadPart, + uiReadOffsetWithinPart, + Adapter->uiSectorSize); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); break; } - if(IsThisHeaderSector == TRUE) + if (IsThisHeaderSector == TRUE) { - //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig + // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); - for(i = 0; i < MAX_RW_SIZE;i++) + for (i = 0; i < MAX_RW_SIZE; i++) *(Buff + sigOffset + i) = 0xFF; } - Adapter->bHeaderChangeAllowed = TRUE ; - + Adapter->bHeaderChangeAllowed = TRUE; Status = BcmFlash2xBulkWrite(Adapter, - (PUINT)Buff, - eISOWritePart, - uiWriteOffsetWithinPart, - Adapter->uiSectorSize, - TRUE); - if(Status) + (PUINT)Buff, + eISOWritePart, + uiWriteOffsetWithinPart, + Adapter->uiSectorSize, + TRUE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); break; } Adapter->bHeaderChangeAllowed = FALSE; - - if(IsThisHeaderSector == TRUE) + if (IsThisHeaderSector == TRUE) { WriteToFlashWithoutSectorErase(Adapter, - SigBuff, - eISOWritePart, - sigOffset, - MAX_RW_SIZE); - IsThisHeaderSector = FALSE ; + SigBuff, + eISOWritePart, + sigOffset, + MAX_RW_SIZE); + IsThisHeaderSector = FALSE; } //subtracting the written Data - uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ; + uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; } - - } - if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1) + if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) { - eISOReadPart = ISO_IMAGE2 ; - eISOWritePart = ISO_IMAGE1 ; - uiReadOffsetWithinPart = 0; - uiWriteOffsetWithinPart = 0 ; + eISOReadPart = ISO_IMAGE2; + eISOWritePart = ISO_IMAGE1; + uiReadOffsetWithinPart = 0; + uiWriteOffsetWithinPart = 0; - uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - if(uiTotalDataToCopy < ISOLength) + if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); Status = STATUS_FAILURE; goto out; } - uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+ - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - + (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - if(uiTotalDataToCopy < ISOLength) + if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); Status = STATUS_FAILURE; goto out; } uiTotalDataToCopy = ISOLength; - CorruptISOSig(Adapter,ISO_IMAGE1); + CorruptISOSig(Adapter, ISO_IMAGE1); - while(uiTotalDataToCopy) + while (uiTotalDataToCopy) { - if(uiTotalDataToCopy == Adapter->uiSectorSize) + if (uiTotalDataToCopy == Adapter->uiSectorSize) { //Setting for write of first sector. First sector is assumed to be written in last - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector"); - eISOReadPart = ISO_IMAGE2 ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); + eISOReadPart = ISO_IMAGE2; uiReadOffsetWithinPart = 0; eISOWritePart = ISO_IMAGE1; - uiWriteOffsetWithinPart = 0 ; + uiWriteOffsetWithinPart = 0; IsThisHeaderSector = TRUE; - } else { - uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ; - uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ; + uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; + uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) )) + if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { - eISOReadPart = ISO_IMAGE2_PART2 ; + eISOReadPart = ISO_IMAGE2_PART2; uiReadOffsetWithinPart = 0; } - if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) + + if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { - eISOReadPart = ISO_IMAGE2_PART3 ; + eISOReadPart = ISO_IMAGE2_PART3; uiReadOffsetWithinPart = 0; } - if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) + + if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { - eISOWritePart = ISO_IMAGE1_PART2 ; + eISOWritePart = ISO_IMAGE1_PART2; uiWriteOffsetWithinPart = 0; } - if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) + + if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { - eISOWritePart = ISO_IMAGE1_PART3 ; + eISOWritePart = ISO_IMAGE1_PART3; uiWriteOffsetWithinPart = 0; } } Status = BcmFlash2xBulkRead(Adapter, - (PUINT)Buff, - eISOReadPart, - uiReadOffsetWithinPart, - Adapter->uiSectorSize - ); - if(Status) + (PUINT)Buff, + eISOReadPart, + uiReadOffsetWithinPart, + Adapter->uiSectorSize); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); break; } - if(IsThisHeaderSector == TRUE) + if (IsThisHeaderSector == TRUE) { - //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig + // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); - for(i = 0; i < MAX_RW_SIZE;i++) + for (i = 0; i < MAX_RW_SIZE; i++) *(Buff + sigOffset + i) = 0xFF; - } - Adapter->bHeaderChangeAllowed = TRUE ; + Adapter->bHeaderChangeAllowed = TRUE; Status = BcmFlash2xBulkWrite(Adapter, - (PUINT)Buff, - eISOWritePart, - uiWriteOffsetWithinPart, - Adapter->uiSectorSize, - TRUE); - - if(Status) + (PUINT)Buff, + eISOWritePart, + uiWriteOffsetWithinPart, + Adapter->uiSectorSize, + TRUE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); break; } - Adapter->bHeaderChangeAllowed = FALSE ; - - if(IsThisHeaderSector == TRUE) + Adapter->bHeaderChangeAllowed = FALSE; + if (IsThisHeaderSector == TRUE) { WriteToFlashWithoutSectorErase(Adapter, - SigBuff, - eISOWritePart, - sigOffset, - MAX_RW_SIZE); - IsThisHeaderSector = FALSE ; + SigBuff, + eISOWritePart, + sigOffset, + MAX_RW_SIZE); + + IsThisHeaderSector = FALSE; } - //subtracting the written Data - uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ; + // subtracting the written Data + uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; } - - } - out: kfree(Buff); return Status; } + /** BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. It will corrupt the sig, if Section is writable, by making first bytes as zero. @@ -4289,27 +4178,29 @@ Return Value :- **/ + INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { + INT Status = STATUS_SUCCESS; - INT Status = STATUS_SUCCESS ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal); - if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) + if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) { Status = CorruptDSDSig(Adapter, eFlash2xSectionVal); } - else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) + else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) { Status = CorruptISOSig(Adapter, eFlash2xSectionVal); } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal); return STATUS_SUCCESS; } return Status; } + /** BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has header and Write Permission. @@ -4321,69 +4212,68 @@ Return Value :- Failure :-Return negative error code **/ + INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { - - UINT uiSignature = 0 ; + UINT uiSignature = 0; UINT uiOffset = 0; - //DSD_HEADER dsdHeader = {0}; - if(Adapter->bSigCorrupted == FALSE) + // DSD_HEADER dsdHeader = {0}; + if (Adapter->bSigCorrupted == FALSE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n"); return STATUS_SUCCESS; } - if(Adapter->bAllDSDWriteAllow == FALSE) + + if (Adapter->bAllDSDWriteAllow == FALSE) { - if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE) + if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature"); return SECTOR_IS_NOT_WRITABLE; } } - if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) + + if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) { - uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ; - uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ; + uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER); + uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader; - uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber); + uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber); - if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) + if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig"); return STATUS_FAILURE; } - } - else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) + else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) { uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); - //uiOffset = 0; - uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber); - if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) + // uiOffset = 0; + uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber); + if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig"); return STATUS_FAILURE; } } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); return STATUS_FAILURE; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature"); - + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature"); Adapter->bHeaderChangeAllowed = TRUE; Adapter->bSigCorrupted = FALSE; - BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE); + BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE); Adapter->bHeaderChangeAllowed = FALSE; - - return STATUS_SUCCESS; } + /** validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. if requested Bytes goes beyond the Requested section, it reports error. @@ -4394,61 +4284,62 @@ Return values:-Return TRUE is request is valid else FALSE. **/ -INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) + +INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) { - UINT uiNumOfBytes = 0 ; - UINT uiSectStartOffset = 0 ; + UINT uiNumOfBytes = 0; + UINT uiSectStartOffset = 0; UINT uiSectEndOffset = 0; + uiNumOfBytes = psFlash2xReadWrite->numOfBytes; - if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE) + if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section); return FALSE; } - uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section); - if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2)) + uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section); + if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) { - if(psFlash2xReadWrite->Section == ISO_IMAGE1) + if (psFlash2xReadWrite->Section == ISO_IMAGE1) { - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) - - BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+ - BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) - - BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+ - BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) - - BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3); + uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) - + BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) + + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) - + BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) + + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) - + BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3); } - else if(psFlash2xReadWrite->Section == ISO_IMAGE2) + else if (psFlash2xReadWrite->Section == ISO_IMAGE2) { - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) - - BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+ - BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) - - BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+ - BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) - - BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3); - + uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) - + BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) + + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) - + BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) + + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) - + BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3); } - //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset - //it should be added in startoffset. so that check done in last of this function can be valued. - uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ; + // since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset + // it should be added in startoffset. so that check done in last of this function can be valued. + uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset); } else - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset); + uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); - //Checking the boundary condition - if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) + // Checking the boundary condition + if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) return TRUE; else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request...."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); return FALSE; } - } /** @@ -4461,11 +4352,12 @@ Return value:- INT IsFlash2x(struct bcm_mini_adapter *Adapter) { - if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) - return TRUE ; + if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) + return TRUE; else return FALSE; } + /** GetFlashBaseAddr :- Calculate the Flash Base address @Adapater :- Bcm Driver Private Data Structure @@ -4476,38 +4368,36 @@ Return Value:- static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) { - UINT uiBaseAddr = 0; - if(Adapter->bDDRInitDone) + if (Adapter->bDDRInitDone) { /* - For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - In case of Raw Read... use the default value + For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr + In case of Raw Read... use the default value */ - if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && - !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)) - ) - uiBaseAddr = Adapter->uiFlashBaseAdd ; + if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && + !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) + uiBaseAddr = Adapter->uiFlashBaseAdd; else uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; } else { /* - For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - In case of Raw Read... use the default value + For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr + In case of Raw Read... use the default value */ - if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && - !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)) - ) + if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && + !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; else uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; } - return uiBaseAddr ; + return uiBaseAddr; } + /** BcmCopySection :- This API is used to copy the One section in another. Both section should be contiuous and of same size. Hence this Will not be applicabe to copy ISO. @@ -4525,108 +4415,108 @@ Return Values- **/ -INT BcmCopySection(struct bcm_mini_adapter *Adapter, - FLASH2X_SECTION_VAL SrcSection, - FLASH2X_SECTION_VAL DstSection, - UINT offset, - UINT numOfBytes) +INT BcmCopySection(struct bcm_mini_adapter *Adapter, + FLASH2X_SECTION_VAL SrcSection, + FLASH2X_SECTION_VAL DstSection, + UINT offset, + UINT numOfBytes) { - UINT BuffSize = 0 ; + UINT BuffSize = 0; UINT BytesToBeCopied = 0; - PUCHAR pBuff = NULL ; - INT Status = STATUS_SUCCESS ; - if(SrcSection == DstSection) + PUCHAR pBuff = NULL; + INT Status = STATUS_SUCCESS; + + if (SrcSection == DstSection) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again"); return -EINVAL; } - if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) + + if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection"); - return -EINVAL; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection"); + return -EINVAL; } - if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) + + if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection"); - return -EINVAL; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection"); + return -EINVAL; } - //if offset zero means have to copy complete secton - - if(numOfBytes == 0) + // if offset zero means have to copy complete secton + if (numOfBytes == 0) { - numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection) - - BcmGetSectionValStartOffset(Adapter,SrcSection); + numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection) + - BcmGetSectionValStartOffset(Adapter, SrcSection); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes); } - if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection) - - BcmGetSectionValStartOffset(Adapter,SrcSection)) + if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection) + - BcmGetSectionValStartOffset(Adapter, SrcSection)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n", - offset, numOfBytes); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n", + offset, numOfBytes); return -EINVAL; } - if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection) - - BcmGetSectionValStartOffset(Adapter,DstSection)) + if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection) + - BcmGetSectionValStartOffset(Adapter, DstSection)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", - offset, numOfBytes); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", + offset, numOfBytes); return -EINVAL; } - - if(numOfBytes > Adapter->uiSectorSize ) + if (numOfBytes > Adapter->uiSectorSize) BuffSize = Adapter->uiSectorSize; else - BuffSize = numOfBytes ; + BuffSize = numOfBytes; pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL); - if(pBuff == NULL) + if (pBuff == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); return -ENOMEM; } - - BytesToBeCopied = Adapter->uiSectorSize ; - if(offset % Adapter->uiSectorSize) + BytesToBeCopied = Adapter->uiSectorSize; + if (offset % Adapter->uiSectorSize) BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize); - if(BytesToBeCopied > numOfBytes) - BytesToBeCopied = numOfBytes ; - - + if (BytesToBeCopied > numOfBytes) + BytesToBeCopied = numOfBytes; Adapter->bHeaderChangeAllowed = TRUE; do { - Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied); - if(Status) + Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied); break; } - Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE); - if(Status) + Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE); + if (Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied); break; } offset = offset + BytesToBeCopied; - numOfBytes = numOfBytes - BytesToBeCopied ; - if(numOfBytes) + numOfBytes = numOfBytes - BytesToBeCopied; + if (numOfBytes) { - if(numOfBytes > Adapter->uiSectorSize ) + if (numOfBytes > Adapter->uiSectorSize) BytesToBeCopied = Adapter->uiSectorSize; else BytesToBeCopied = numOfBytes; } - }while(numOfBytes > 0) ; + } while (numOfBytes > 0); + kfree(pBuff); - Adapter->bHeaderChangeAllowed = FALSE ; + Adapter->bHeaderChangeAllowed = FALSE; + return Status; } @@ -4644,68 +4534,66 @@ Return value :- INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset) { - UINT offsetToProtect = 0,HeaderSizeToProtect =0; - BOOLEAN bHasHeader = FALSE ; - PUCHAR pTempBuff =NULL; + UINT offsetToProtect = 0, HeaderSizeToProtect = 0; + BOOLEAN bHasHeader = FALSE; + PUCHAR pTempBuff = NULL; UINT uiSectAlignAddr = 0; UINT sig = 0; //making the offset sector aligned uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - - if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)|| - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)|| - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize)) + if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) || + (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) || + (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) { - - //offset from the sector boundary having the header map + // offset from the sector boundary having the header map offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; HeaderSizeToProtect = sizeof(DSD_HEADER); - bHasHeader = TRUE ; + bHasHeader = TRUE; } - if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) || - uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)) + if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) || + uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) { offsetToProtect = 0; HeaderSizeToProtect = sizeof(ISO_HEADER); bHasHeader = TRUE; } - //If Header is present overwrite passed buffer with this - if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) + // If Header is present overwrite passed buffer with this + if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) { pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL); - if(pTempBuff == NULL) + if (pTempBuff == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); return -ENOMEM; } - //Read header - BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect); + // Read header + BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect); + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect); //Replace Buffer content with Header - memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect); + memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect); kfree(pTempBuff); } - if(bHasHeader && Adapter->bSigCorrupted) + if (bHasHeader && Adapter->bSigCorrupted) { - sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber))); + sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber))); sig = ntohl(sig); - if((sig & 0xFF000000) != CORRUPTED_PATTERN) + if ((sig & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore"); Adapter->bSigCorrupted = FALSE; return STATUS_SUCCESS; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig); - *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig); + *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only"); Adapter->bSigCorrupted = FALSE; } - return STATUS_SUCCESS ; + return STATUS_SUCCESS; } /** @@ -4722,7 +4610,7 @@ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) UINT GPIOConfig = 0; UINT PartNum = 0; - ChipNum = offset / FLASH_PART_SIZE ; + ChipNum = offset / FLASH_PART_SIZE; // // Chip Select mapping to enable flash0. @@ -4733,363 +4621,369 @@ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) // /* - SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured - if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) - Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from - power down modes (Idle mode/shutdown mode), the values in the register will be different. + SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured + if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) + Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from + power down modes (Idle mode/shutdown mode), the values in the register will be different. */ - if(Adapter->SelectedChip == ChipNum) - return STATUS_SUCCESS; + if (Adapter->SelectedChip == ChipNum) + return STATUS_SUCCESS; - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); - Adapter->SelectedChip = ChipNum ; + // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); + Adapter->SelectedChip = ChipNum; - //bit[13..12] will select the appropriate chip + // bit[13..12] will select the appropriate chip rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); - { - switch(ChipNum) + switch (ChipNum) { - case 0: - PartNum = 0; - break; - case 1: - PartNum = 3; - GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); - break; - case 2: - PartNum = 1; - GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); - break; - case 3: - PartNum = 2; - GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); - break; + case 0: + PartNum = 0; + break; + case 1: + PartNum = 3; + GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); + break; + case 2: + PartNum = 1; + GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); + break; + case 3: + PartNum = 2; + GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); + break; } } /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, - nothing to do... can return immediately. - ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. - Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. - These values are not written by host other than during CHIP_SELECT. + nothing to do... can return immediately. + ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. + Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. + These values are not written by host other than during CHIP_SELECT. */ - if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) + if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) return STATUS_SUCCESS; - //clearing the bit[13..12] + // clearing the bit[13..12] FlashConfig &= 0xFFFFCFFF; - FlashConfig = (FlashConfig | (PartNum<psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber), - SIGNATURE_SIZE); + if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs"); + return STATUS_FAILURE; + } + BcmFlash2xBulkRead(Adapter, + &uiDSDsig, + dsd, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber), + SIGNATURE_SIZE); - uiDSDsig = ntohl(uiDSDsig); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig); + uiDSDsig = ntohl(uiDSDsig); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig); - return uiDSDsig ; + return uiDSDsig; } + INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { - //UINT priOffsetInMap = 0 ; + // UINT priOffsetInMap = 0 ; unsigned int uiDSDPri = STATUS_FAILURE; - //DSD_HEADER dsdHeader = {0}; - //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; - if(IsSectionWritable(Adapter,dsd)) + // DSD_HEADER dsdHeader = {0}; + // priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; + if (IsSectionWritable(Adapter, dsd)) { - if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER) + if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) { BcmFlash2xBulkRead(Adapter, - &uiDSDPri, - dsd, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), - 4); + &uiDSDPri, + dsd, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + 4); uiDSDPri = ntohl(uiDSDPri); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri); - + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri); } } + return uiDSDPri; } + FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter) { INT DSDHighestPri = STATUS_FAILURE; - INT DsdPri= 0 ; - FLASH2X_SECTION_VAL HighestPriDSD = 0 ; + INT DsdPri = 0; + FLASH2X_SECTION_VAL HighestPriDSD = 0; - if(IsSectionWritable(Adapter,DSD2)) + if (IsSectionWritable(Adapter, DSD2)) { - DSDHighestPri = ReadDSDPriority(Adapter,DSD2); - HighestPriDSD = DSD2 ; + DSDHighestPri = ReadDSDPriority(Adapter, DSD2); + HighestPriDSD = DSD2; } - if(IsSectionWritable(Adapter,DSD1)) + + if (IsSectionWritable(Adapter, DSD1)) { - DsdPri = ReadDSDPriority(Adapter,DSD1); - if(DSDHighestPri < DsdPri) - { - DSDHighestPri = DsdPri ; + DsdPri = ReadDSDPriority(Adapter, DSD1); + if (DSDHighestPri < DsdPri) + { + DSDHighestPri = DsdPri; HighestPriDSD = DSD1; - } + } } - if(IsSectionWritable(Adapter,DSD0)) + + if (IsSectionWritable(Adapter, DSD0)) { - DsdPri = ReadDSDPriority(Adapter,DSD0); - if(DSDHighestPri < DsdPri) - { - DSDHighestPri = DsdPri ; + DsdPri = ReadDSDPriority(Adapter, DSD0); + if (DSDHighestPri < DsdPri) + { + DSDHighestPri = DsdPri; HighestPriDSD = DSD0; - } + } } - if(HighestPriDSD) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri); - return HighestPriDSD ; + if (HighestPriDSD) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri); + + return HighestPriDSD; } INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { - UINT uiISOsig = 0; - //UINT sigoffsetInMap = 0; - //ISO_HEADER ISOHeader = {0}; + UINT uiISOsig = 0; + //UINT sigoffsetInMap = 0; + //ISO_HEADER ISOHeader = {0}; + //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; + if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs"); + return STATUS_FAILURE; + } + BcmFlash2xBulkRead(Adapter, + &uiISOsig, + iso, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber), + SIGNATURE_SIZE); - //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; - - if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs"); - return STATUS_FAILURE; - } - BcmFlash2xBulkRead(Adapter, - &uiISOsig, - iso, - 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber), - SIGNATURE_SIZE); - - uiISOsig = ntohl(uiISOsig); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig); + uiISOsig = ntohl(uiISOsig); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig); - return uiISOsig ; + return uiISOsig; } + INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { - unsigned int ISOPri = STATUS_FAILURE; - if(IsSectionWritable(Adapter,iso)) + if (IsSectionWritable(Adapter, iso)) { - if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER) + if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) { BcmFlash2xBulkRead(Adapter, - &ISOPri, - iso, - 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), - 4); + &ISOPri, + iso, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + 4); ISOPri = ntohl(ISOPri); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri); - + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri); } } + return ISOPri; } + FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter) { INT ISOHighestPri = STATUS_FAILURE; - INT ISOPri= 0 ; - FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ; + INT ISOPri = 0; + FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL; - if(IsSectionWritable(Adapter,ISO_IMAGE2)) + if (IsSectionWritable(Adapter, ISO_IMAGE2)) { - ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2); - HighestPriISO = ISO_IMAGE2 ; + ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2); + HighestPriISO = ISO_IMAGE2; } - if(IsSectionWritable(Adapter,ISO_IMAGE1)) + + if (IsSectionWritable(Adapter, ISO_IMAGE1)) { - ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1); - if(ISOHighestPri < ISOPri) - { - ISOHighestPri = ISOPri ; + ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1); + if (ISOHighestPri < ISOPri) + { + ISOHighestPri = ISOPri; HighestPriISO = ISO_IMAGE1; - } + } } - if(HighestPriISO) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri); - return HighestPriISO ; + if (HighestPriISO) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri); + + return HighestPriISO; } + INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, - PUINT pBuff, - FLASH2X_SECTION_VAL eFlash2xSectionVal, - UINT uiOffset, - UINT uiNumBytes - ) + PUINT pBuff, + FLASH2X_SECTION_VAL eFlash2xSectionVal, + UINT uiOffset, + UINT uiNumBytes) { -#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT uiTemp = 0, value = 0 ; - UINT i = 0; - UINT uiPartOffset = 0; -#endif + #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) + UINT uiTemp = 0, value = 0; + UINT i = 0; + UINT uiPartOffset = 0; + #endif UINT uiStartOffset = 0; - //Adding section start address + // Adding section start address INT Status = STATUS_SUCCESS; PUCHAR pcBuff = (PUCHAR)pBuff; - if(uiNumBytes % Adapter->ulFlashWriteSize) + if (uiNumBytes % Adapter->ulFlashWriteSize) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); return STATUS_FAILURE; } - uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); + uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal)) + if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) { return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes); } uiOffset = uiOffset + uiStartOffset; -#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes); -#else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80,&value, sizeof(value)); + #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) + Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes); + #else + rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + value = 0; + wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - Adapter->SelectedChip = RESET_CHIP_SELECT; - BcmDoChipSelect(Adapter,uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); + Adapter->SelectedChip = RESET_CHIP_SELECT; + BcmDoChipSelect(Adapter, uiOffset); + uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize) - { - if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) - Status = flashByteWrite(Adapter,uiPartOffset, pcBuff); - else - Status = flashWrite(Adapter,uiPartOffset, pcBuff); + for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) + { + if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) + Status = flashByteWrite(Adapter, uiPartOffset, pcBuff); + else + Status = flashWrite(Adapter, uiPartOffset, pcBuff); - if(Status != STATUS_SUCCESS) - break; + if (Status != STATUS_SUCCESS) + break; - pcBuff = pcBuff + Adapter->ulFlashWriteSize; - uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize; - } - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - Adapter->SelectedChip = RESET_CHIP_SELECT; -#endif + pcBuff = pcBuff + Adapter->ulFlashWriteSize; + uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize; + } + wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); + Adapter->SelectedChip = RESET_CHIP_SELECT; + #endif return Status; } BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section) { + BOOLEAN SectionPresent = FALSE; - BOOLEAN SectionPresent = FALSE ; - - switch(section) + switch (section) { - - case ISO_IMAGE1 : - if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectionPresent = TRUE ; - break; - case ISO_IMAGE2 : - if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectionPresent = TRUE ; - break; - case DSD0 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case DSD1 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case DSD2 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case VSA0 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case VSA1 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case VSA2 : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case SCSI : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - case CONTROL_SECTION : - if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE ; - break; - default : - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x"); + case ISO_IMAGE1: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectionPresent = TRUE; + break; + case ISO_IMAGE2: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectionPresent = TRUE; + break; + case DSD0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case DSD1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case DSD2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case VSA0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case VSA1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case VSA2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case SCSI: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case CONTROL_SECTION: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + default: + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); SectionPresent = FALSE; } - return SectionPresent ; + + return SectionPresent; } + INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section) { - INT offset = STATUS_FAILURE; - INT Status = FALSE; - if(IsSectionExistInFlash(Adapter,Section) == FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section); - return FALSE; - } - offset = BcmGetSectionValStartOffset(Adapter,Section); - if(offset == INVALID_OFFSET) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section); - return FALSE; - } + INT offset = STATUS_FAILURE; + INT Status = FALSE; - if(IsSectionExistInVendorInfo(Adapter,Section)) - { - return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); - } + if (IsSectionExistInFlash(Adapter, Section) == FALSE) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section); + return FALSE; + } + + offset = BcmGetSectionValStartOffset(Adapter, Section); + if (offset == INVALID_OFFSET) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section); + return FALSE; + } + + if (IsSectionExistInVendorInfo(Adapter, Section)) + { + return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); + } - Status = IsOffsetWritable(Adapter,offset); - return Status ; + Status = IsOffsetWritable(Adapter, offset); + return Status; } static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { - PUCHAR pBuff = NULL; UINT sig = 0; UINT uiOffset = 0; @@ -5097,126 +4991,125 @@ static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e UINT uiSectAlignAddr = 0; Adapter->bSigCorrupted = FALSE; - - if(Adapter->bAllDSDWriteAllow == FALSE) + if (Adapter->bAllDSDWriteAllow == FALSE) { - if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE) + if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Corrupt signature"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); return SECTOR_IS_NOT_WRITABLE; } } pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if(pBuff == NULL) + if (pBuff == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); - return -ENOMEM ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); + return -ENOMEM; } uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER); - uiOffset -= MAX_RW_SIZE ; - - BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE); + uiOffset -= MAX_RW_SIZE; + BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); - sig = *((PUINT)(pBuff +12)); - sig =ntohl(sig); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE); - //Now corrupting the sig by corrupting 4th last Byte. + sig = *((PUINT)(pBuff + 12)); + sig = ntohl(sig); + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); + // Now corrupting the sig by corrupting 4th last Byte. *(pBuff + 12) = 0; - if(sig == DSD_IMAGE_MAGIC_NUMBER) + if (sig == DSD_IMAGE_MAGIC_NUMBER) { Adapter->bSigCorrupted = TRUE; - if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) + if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) { - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1); - BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize); + uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); + BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal, - (uiOffset + 12),BYTE_WRITE_SUPPORT); - if(BlockStatus) + WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal, + (uiOffset + 12), BYTE_WRITE_SUPPORT); + if (BlockStatus) { - BcmRestoreBlockProtectStatus(Adapter,BlockStatus); + BcmRestoreBlockProtectStatus(Adapter, BlockStatus); BlockStatus = 0; } } else { - WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal, - uiOffset ,MAX_RW_SIZE); + WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, + uiOffset, MAX_RW_SIZE); } } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); kfree(pBuff); + return STATUS_FAILURE; } kfree(pBuff); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature"); - return STATUS_SUCCESS ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); + + return STATUS_SUCCESS; } static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { - PUCHAR pBuff = NULL; UINT sig = 0; UINT uiOffset = 0; Adapter->bSigCorrupted = FALSE; - if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE) + if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Corrupt signature"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); return SECTOR_IS_NOT_WRITABLE; } pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if(pBuff == NULL) + if (pBuff == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey"); - return -ENOMEM ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); + return -ENOMEM; } uiOffset = 0; - BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE); + BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); sig = *((PUINT)pBuff); - sig =ntohl(sig); + sig = ntohl(sig); - //corrupt signature + // corrupt signature *pBuff = 0; - if(sig == ISO_IMAGE_MAGIC_NUMBER) + if (sig == ISO_IMAGE_MAGIC_NUMBER) { Adapter->bSigCorrupted = TRUE; - WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal, - uiOffset ,Adapter->ulFlashWriteSize); + WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, + uiOffset, Adapter->ulFlashWriteSize); } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); kfree(pBuff); + return STATUS_FAILURE; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature"); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); kfree(pBuff); - return STATUS_SUCCESS ; + return STATUS_SUCCESS; } BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter) { - if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) + if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) return TRUE; else - return FALSE ; + return FALSE; } - -- GitLab From a2940b635bbe6bc4b7d6156eddc92fdbe1037bd9 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 6 Jun 2012 22:54:28 -0400 Subject: [PATCH 1274/6849] Staging: bcm: Properly format braces in nvm.c This patch cuddles braces as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 1784 ++++++++++++++----------------------- 1 file changed, 659 insertions(+), 1125 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 2bb87c93b0e9..66001fcd4402 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -74,20 +74,17 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) value = EEPROM_READ_STATUS_REGISTER; wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - while (dwRetries != 0) - { + while (dwRetries != 0) { value = 0; uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) - { + if (Adapter->device_removed == TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting...."); break; } /* Wait for Avail bit to be set. */ - if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) - { + if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { /* Clear the Avail/Full bits - which ever is set. */ value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); @@ -100,8 +97,7 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) } dwRetries--; - if (dwRetries == 0) - { + if (dwRetries == 0) { rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x3004 = %x 0x3008 = %x, retries = %d failed.\n", value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); @@ -153,12 +149,10 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ); wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - while (dwRetries != 0) - { + while (dwRetries != 0) { uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) - { + if (Adapter->device_removed == TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop..."); return -ENODEV; } @@ -166,20 +160,15 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, /* If we are reading 16 bytes we want to be sure that the queue * is full before we read. In the other cases we are ok if the * queue has data available */ - if (dwNumWords == 4) - { - if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) - { + if (dwNumWords == 4) { + if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) { /* Clear the Avail/Full bits - which ever is set. */ value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); break; } - } - else if (dwNumWords == 1) - { - if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) - { + } else if (dwNumWords == 1) { + if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { /* We just got Avail and we have to read 32bits so we * need this sleep for Cardbus kind of devices. */ if (Adapter->chip_id == 0xBECE0210) @@ -195,8 +184,7 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, uiStatus = 0; dwRetries--; - if (dwRetries == 0) - { + if (dwRetries == 0) { value = 0; value1 = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); @@ -210,8 +198,7 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, msleep(1); } - for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) - { + for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) { /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */ pvalue = (PUCHAR)(pdwData + dwIndex); @@ -272,9 +259,7 @@ INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, /* A word can overlap at most over 2 pages. In that case we read the * next page too. */ if (uiByteOffset > 12) - { ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); - } memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4); @@ -327,20 +312,16 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, UINT uiFailureRetries = 0; PUCHAR pcBuff = (PUCHAR)pBuffer; - if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) - { + if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) { uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); uiExtraBytes = uiOffset - uiTempOffset; ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); - if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) - { + if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) { memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes); uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes); uiIndex += (MAX_RW_SIZE - uiExtraBytes); uiOffset += (MAX_RW_SIZE - uiExtraBytes); - } - else - { + } else { memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining); uiIndex += uiBytesRemaining; uiOffset += uiBytesRemaining; @@ -348,57 +329,41 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, } } - while (uiBytesRemaining && uiFailureRetries != 128) - { + while (uiBytesRemaining && uiFailureRetries != 128) { if (Adapter->device_removed) - { return -1; - } - if (uiBytesRemaining >= MAX_RW_SIZE) - { + if (uiBytesRemaining >= MAX_RW_SIZE) { /* For the requests more than or equal to 16 bytes, use bulk * read function to make the access faster. * We read 4 Dwords of data */ - if (0 == ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4)) - { + if (0 == ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4)) { memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE); uiOffset += MAX_RW_SIZE; uiBytesRemaining -= MAX_RW_SIZE; uiIndex += MAX_RW_SIZE; - } - else - { + } else { uiFailureRetries++; mdelay(3); //sleep for a while before retry... } - } - else if (uiBytesRemaining >= 4) - { - if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) - { + } else if (uiBytesRemaining >= 4) { + if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { memcpy(pcBuff + uiIndex, &uiData[0], 4); uiOffset += 4; uiBytesRemaining -= 4; uiIndex += 4; - } - else - { + } else { uiFailureRetries++; mdelay(3); //sleep for a while before retry... } - } - else - { // Handle the reads less than 4 bytes... + } else { + // Handle the reads less than 4 bytes... PUCHAR pCharBuff = (PUCHAR)pBuffer; pCharBuff += uiIndex; - if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) - { + if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { memcpy(pCharBuff, &uiData[0], uiBytesRemaining); //copy only bytes requested. uiBytesRemaining = 0; - } - else - { + } else { uiFailureRetries++; mdelay(3); //sleep for a while before retry... } @@ -435,8 +400,7 @@ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, UINT uiPartOffset = 0; int bytes; - if (Adapter->device_removed) - { + if (Adapter->device_removed) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed"); return -ENODEV; } @@ -450,8 +414,7 @@ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, Adapter->SelectedChip = RESET_CHIP_SELECT; - if (uiOffset % MAX_RW_SIZE) - { + if (uiOffset % MAX_RW_SIZE) { BcmDoChipSelect(Adapter, uiOffset); uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); @@ -470,8 +433,7 @@ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, uiNumBytes -= uiBytesToRead; } - while (uiNumBytes) - { + while (uiNumBytes) { BcmDoChipSelect(Adapter, uiOffset); uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); @@ -539,33 +501,23 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) // get 'BECM' string which is indeed at offset 0. // BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); - if (uiData == BECM) - { - for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) - { + if (uiData == BECM) { + for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); if (uiData == BECM) - { return uiIndex * 1024; - } } - } - else - { + } else { // // EEPROM may not be present or not programmed // uiData = 0xBABEFACE; - if (0 == BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE)) - { + if (0 == BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE)) { uiData = 0; - for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) - { + for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); if (uiData == 0xBABEFACE) - { return uiIndex * 1024; - } } } } @@ -596,8 +548,7 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, UINT value; int bytes; - for (iIndex = 0; iIndex < numOfSectors; iIndex++) - { + for (iIndex = 0; iIndex < numOfSectors; iIndex++) { value = 0x06000000; wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); @@ -605,11 +556,9 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); iRetries = 0; - do - { + do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } @@ -627,8 +576,7 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, msleep(10); } while ((uiStatus & 0x1) && (iRetries < 400)); - if (uiStatus & 0x1) - { + if (uiStatus & 0x1) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n"); return STATUS_FAILURE; } @@ -666,37 +614,30 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, // if (0xFF == ulData) - { return STATUS_SUCCESS; - } // DumpDebug(NVM_RW,("flashWrite ====>\n")); value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); return STATUS_FAILURE; } - if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) - { + if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); return STATUS_FAILURE; } value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } //__udelay(950); - do - { + do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } @@ -713,8 +654,7 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, } while ((uiStatus & 0x1) && (iRetries > 0)); - if (uiStatus & 0x1) - { + if (uiStatus & 0x1) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); return STATUS_FAILURE; } @@ -754,30 +694,24 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, // make whole sector 0xFFFFFFFF. // if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) - { return 0; - } value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) - { + if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); return STATUS_FAILURE; } //__udelay(950); - do - { + do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } @@ -798,8 +732,7 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, msleep(1); } while ((uiStatus & 0x1) && (iRetries > 0)); - if (uiStatus & 0x1) - { + if (uiStatus & 0x1) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); return STATUS_FAILURE; } @@ -836,37 +769,30 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, // if (0xFF == ulData) - { return STATUS_SUCCESS; - } // DumpDebug(NVM_RW,("flashWrite ====>\n")); value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); return STATUS_SUCCESS; } - if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) - { + if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); return STATUS_FAILURE; } value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } //msleep(1); - do - { + do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } @@ -884,8 +810,7 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, } while ((uiStatus & 0x1) && (iRetries > 0)); - if (uiStatus & 0x1) - { + if (uiStatus & 0x1) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); return STATUS_FAILURE; } @@ -922,29 +847,23 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, // make whole sector 0xFFFFFFFF. // if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) - { return 0; - } value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) - { + if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); return STATUS_FAILURE; } // __udelay(1); - do - { + do { value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) - { + if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } @@ -965,8 +884,7 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, } while ((uiStatus & 0x1) && (iRetries > 0)); - if (uiStatus & 0x1) - { + if (uiStatus & 0x1) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); return STATUS_FAILURE; } @@ -1022,8 +940,7 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOff // // Implemented only for 1MB Flash parts. // - if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) - { + if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) { // // Get Current BP status. // @@ -1043,46 +960,36 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOff // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS // - if (ulStatus) - { - if ((uiOffset+uiLength) <= 0x80000) - { + if (ulStatus) { + if ((uiOffset+uiLength) <= 0x80000) { // // Offset comes in lower half of 1MB. Protect the upper half. // Clear BP1 and BP0 and set BP2. // ulWriteStatus |= (0x4<<2); ulWriteStatus &= ~(0x3<<2); - } - else if ((uiOffset + uiLength) <= 0xC0000) - { + } else if ((uiOffset + uiLength) <= 0xC0000) { // // Offset comes below Upper 1/4. Upper 1/4 can be protected. // Clear BP2 and set BP1 and BP0. // ulWriteStatus |= (0x3<<2); ulWriteStatus &= ~(0x1<<4); - } - else if ((uiOffset + uiLength) <= 0xE0000) - { + } else if ((uiOffset + uiLength) <= 0xE0000) { // // Offset comes below Upper 1/8. Upper 1/8 can be protected. // Clear BP2 and BP0 and set BP1 // ulWriteStatus |= (0x1<<3); ulWriteStatus &= ~(0x5<<2); - } - else if ((uiOffset + uiLength) <= 0xF0000) - { + } else if ((uiOffset + uiLength) <= 0xF0000) { // // Offset comes below Upper 1/16. Only upper 1/16 can be protected. // Set BP0 and Clear BP2,BP1. // ulWriteStatus |= (0x1<<2); ulWriteStatus &= ~(0x3<<3); - } - else - { + } else { // // Unblock all. // Clear BP2,BP1 and BP0. @@ -1158,30 +1065,22 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, // // check if the data to be written is overlapped across sectors // - if (uiOffset+uiNumBytes < uiSectBoundary) - { + if (uiOffset+uiNumBytes < uiSectBoundary) { uiNumSectTobeRead = 1; - } - else - { + } else { // Number of sectors = Last sector start address/First sector start address uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) - { uiNumSectTobeRead++; - } } // Check whether Requested sector is writable or not in case of flash2x write. But if write call is // for DSD calibration, allow it without checking of sector permission - if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) - { + if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) { index = 0; uiTemp = uiNumSectTobeRead; - while (uiTemp) - { - if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) - { + while (uiTemp) { + if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable", (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); Status = SECTOR_IS_NOT_WRITABLE; @@ -1192,8 +1091,7 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, } } Adapter->SelectedChip = RESET_CHIP_SELECT; - while (uiNumSectTobeRead) - { + while (uiNumSectTobeRead) { // do_gettimeofday(&tv1); // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); @@ -1203,8 +1101,7 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, if (0 != BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, uiOffsetFromSectStart, - Adapter->uiSectorSize)) - { + Adapter->uiSectorSize)) { Status = -1; goto BeceemFlashBulkWrite_EXIT; } @@ -1214,36 +1111,28 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - if (uiNumSectTobeRead > 1) - { + if (uiNumSectTobeRead > 1) { memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - } - else - { + } else { memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); } if (IsFlash2x(Adapter)) - { SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); - } FlashSectorErase(Adapter, uiPartOffset, 1); // do_gettimeofday(&te); // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) - { - if (Adapter->device_removed) - { + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { + if (Adapter->device_removed) { Status = -1; goto BeceemFlashBulkWrite_EXIT; } - if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) - { + if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) { Status = -1; goto BeceemFlashBulkWrite_EXIT; } @@ -1251,31 +1140,21 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, // do_gettimeofday(&tw); // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) - { - if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) - { - if (Adapter->ulFlashWriteSize == 1) - { + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { + if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { + if (Adapter->ulFlashWriteSize == 1) { UINT uiReadIndex = 0; - for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) - { - if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) - { - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) - { + for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) { + if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) { + if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) { Status = STATUS_FAILURE; goto BeceemFlashBulkWrite_EXIT; } } } - } - else - { - if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) - { - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) - { + } else { + if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { + if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) { Status = STATUS_FAILURE; goto BeceemFlashBulkWrite_EXIT; } @@ -1285,8 +1164,7 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, } // do_gettimeofday(&twv); // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); - if (ulStatus) - { + if (ulStatus) { BcmRestoreBlockProtectStatus(Adapter, ulStatus); ulStatus = 0; } @@ -1305,9 +1183,7 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, // BeceemFlashBulkWrite_EXIT : if (ulStatus) - { BcmRestoreBlockProtectStatus(Adapter, ulStatus); - } kfree(pTempBuff); @@ -1369,28 +1245,20 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, // // check if the data to be written is overlapped across sectors // - if (uiOffset+uiNumBytes < uiSectBoundary) - { + if (uiOffset+uiNumBytes < uiSectBoundary) { uiNumSectTobeRead = 1; - } - else - { + } else { // Number of sectors = Last sector start address/First sector start address uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) - { uiNumSectTobeRead++; - } } - if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) - { + if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) { index = 0; uiTemp = uiNumSectTobeRead; - while (uiTemp) - { - if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) - { + while (uiTemp) { + if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable", (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); Status = SECTOR_IS_NOT_WRITABLE; @@ -1402,63 +1270,49 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, } Adapter->SelectedChip = RESET_CHIP_SELECT; - while (uiNumSectTobeRead) - { + while (uiNumSectTobeRead) { uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); BcmDoChipSelect(Adapter, uiSectAlignAddr); if (0 != BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, uiOffsetFromSectStart, - Adapter->uiSectorSize)) - { + Adapter->uiSectorSize)) { Status = -1; goto BeceemFlashBulkWriteStatus_EXIT; } ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize); - if (uiNumSectTobeRead > 1) - { + if (uiNumSectTobeRead > 1) { memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - } - else - { + } else { memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); } if (IsFlash2x(Adapter)) - { SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); - } FlashSectorErase(Adapter, uiPartOffset, 1); - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) - { - if (Adapter->device_removed) - { + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { + if (Adapter->device_removed) { Status = -1; goto BeceemFlashBulkWriteStatus_EXIT; } - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) - { + if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) { Status = -1; goto BeceemFlashBulkWriteStatus_EXIT; } } - if (bVerify) - { - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) - { - if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) - { - if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) - { + if (bVerify) { + for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { + if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { + if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { Status = STATUS_FAILURE; goto BeceemFlashBulkWriteStatus_EXIT; } @@ -1466,8 +1320,7 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, } } - if (ulStatus) - { + if (ulStatus) { BcmRestoreBlockProtectStatus(Adapter, ulStatus); ulStatus = 0; } @@ -1483,9 +1336,7 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, // BeceemFlashBulkWriteStatus_EXIT : if (ulStatus) - { BcmRestoreBlockProtectStatus(Adapter, ulStatus); - } kfree(pTempBuff); Adapter->SelectedChip = RESET_CHIP_SELECT; @@ -1516,29 +1367,23 @@ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) INT Status = 0; if (pBuff == NULL) - { return -1; - } - if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) - { + if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { kfree(pBuff); return -1; } uiEepromSize >>= 16; - if (uiEepromSize > 1024 * 1024) - { + if (uiEepromSize > 1024 * 1024) { kfree(pBuff); return -1; } uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - while (uiBytesToCopy) - { - if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) - { + while (uiBytesToCopy) { + if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) { Status = -1; break; } @@ -1591,9 +1436,8 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) - { return -1; - } + uiEepromSize = ntohl(uiEepromSize); uiEepromSize >>= 16; @@ -1603,16 +1447,13 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) uiEepromSize -= EEPROM_CALPARAM_START; if (uiEepromSize > 1024 * 1024) - { return -1; - } pBuff = kmalloc(uiEepromSize, GFP_KERNEL); if (pBuff == NULL) return -1; - if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) - { + if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) { kfree(pBuff); return -1; } @@ -1621,11 +1462,9 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - while (uiBytesToCopy) - { + while (uiBytesToCopy) { Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status); break; } @@ -1665,53 +1504,41 @@ static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, UINT uiData = 0; UINT auiData[4] = {0}; - while (uiNumBytes) - { + while (uiNumBytes) { if (Adapter->device_removed) - { return -1; - } - if (uiNumBytes >= MAX_RW_SIZE) - { // for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. + if (uiNumBytes >= MAX_RW_SIZE) { + // for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) - { + if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { // re-write BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE); mdelay(3); BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) - { return -1; - } } uiOffset += MAX_RW_SIZE; uiNumBytes -= MAX_RW_SIZE; uiIndex += 4; - } - else if (uiNumBytes >= 4) - { + } else if (uiNumBytes >= 4) { BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); - if (uiData != pBuffer[uiIndex]) - { + if (uiData != pBuffer[uiIndex]) { // re-write BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE); mdelay(3); BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); if (uiData != pBuffer[uiIndex]) - { return -1; - } } uiOffset += 4; uiNumBytes -= 4; uiIndex++; - } - else - { // Handle the reads less than 4 bytes... + } else { + // Handle the reads less than 4 bytes... uiData = 0; memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(UINT)), uiNumBytes); BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); @@ -1726,8 +1553,8 @@ static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, return 0; } -static VOID BcmSwapWord(UINT *ptr1) { - +static VOID BcmSwapWord(UINT *ptr1) +{ UINT tempval = (UINT)*ptr1; char *ptr2 = (char *)&tempval; char *ptr = (char *)ptr1; @@ -1807,11 +1634,9 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] * may take time. We should wait till the Empty bit is set. */ uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) - { + while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) { uiRetries--; - if (uiRetries == 0) - { + if (uiRetries == 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); return STATUS_FAILURE; } @@ -1821,15 +1646,13 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) - { + if (Adapter->device_removed == TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop...."); return -ENODEV; } } - if (uiRetries != 0) - { + if (uiRetries != 0) { /* Clear the ones that are set - either, Empty/Full/Avail bits */ value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL)); wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); @@ -1842,22 +1665,18 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] * means the previous write to the EEPROM has completed. */ uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; uiEpromStatus = 0; - while (uiRetries != 0) - { + while (uiRetries != 0) { uiEpromStatus = ReadEEPROMStatusRegister(Adapter); - if (Adapter->device_removed == TRUE) - { + if (Adapter->device_removed == TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); return -ENODEV; } - if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) - { + if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries)); return STATUS_SUCCESS; } uiRetries--; - if (uiRetries == 0) - { + if (uiRetries == 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); return STATUS_FAILURE; } @@ -1900,15 +1719,13 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, // PUINT puiBuffer = (PUINT)pBuffer; // INT value; - if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) - { + if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); uiExtraBytes = uiOffset - uiTempOffset; BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE); - if (uiBytesToCopy >= (16 - uiExtraBytes)) - { + if (uiBytesToCopy >= (16 - uiExtraBytes)) { memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes); if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) @@ -1917,9 +1734,7 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes); uiIndex += (MAX_RW_SIZE - uiExtraBytes); uiOffset += (MAX_RW_SIZE - uiExtraBytes); - } - else - { + } else { memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy); if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) @@ -1931,24 +1746,18 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, } } - while (uiBytesToCopy) - { + while (uiBytesToCopy) { if (Adapter->device_removed) - { return -1; - } - if (uiBytesToCopy >= MAX_RW_SIZE) - { + if (uiBytesToCopy >= MAX_RW_SIZE) { if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset)) return STATUS_FAILURE; uiIndex += MAX_RW_SIZE; uiOffset += MAX_RW_SIZE; uiBytesToCopy -= MAX_RW_SIZE; - } - else - { + } else { // // To program non 16byte aligned data, read 16byte and then update. // @@ -1992,10 +1801,8 @@ INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, UINT uiTemp = 0, value; #endif - if (Adapter->eNVMType == NVM_FLASH) - { - if (Adapter->bFlashRawRead == FALSE) - { + if (Adapter->eNVMType == NVM_FLASH) { + if (Adapter->bFlashRawRead == FALSE) { if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes); @@ -2014,16 +1821,12 @@ INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, uiNumBytes); wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); #endif - } - else if (Adapter->eNVMType == NVM_EEPROM) - { + } else if (Adapter->eNVMType == NVM_EEPROM) { Status = BeceemEEPROMBulkRead(Adapter, pBuffer, uiOffset, uiNumBytes); - } - else - { + } else { Status = -1; } @@ -2063,12 +1866,10 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, UINT uiFlashOffset = 0; - if (Adapter->eNVMType == NVM_FLASH) - { + if (Adapter->eNVMType == NVM_FLASH) { if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify); - else - { + else { uiFlashOffset = uiOffset + Adapter->ulFlashCalStart; #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) @@ -2079,63 +1880,47 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); if (Adapter->bStatusWrite == TRUE) - { Status = BeceemFlashBulkWriteStatus(Adapter, pBuffer, uiFlashOffset, uiNumBytes , bVerify); - } else - { Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiFlashOffset, uiNumBytes, bVerify); - } #endif } - if (uiOffset >= EEPROM_CALPARAM_START) - { + if (uiOffset >= EEPROM_CALPARAM_START) { uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START); - while (uiNumBytes) - { - if (uiNumBytes > BUFFER_4K) - { + while (uiNumBytes) { + if (uiNumBytes > BUFFER_4K) { wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K); uiNumBytes -= BUFFER_4K; uiIndex += BUFFER_4K; - } - else - { + } else { wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes); uiNumBytes = 0; break; } } - } - else - { - if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) - { + } else { + if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) { ULONG ulBytesTobeSkipped = 0; PUCHAR pcBuffer = (PUCHAR)pBuffer; // char pointer to take care of odd byte cases. uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); uiOffset += (EEPROM_CALPARAM_START - uiOffset); - while (uiNumBytes) - { - if (uiNumBytes > BUFFER_4K) - { + while (uiNumBytes) { + if (uiNumBytes > BUFFER_4K) { wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K); uiNumBytes -= BUFFER_4K; uiIndex += BUFFER_4K; - } - else - { + } else { wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes); uiNumBytes = 0; break; @@ -2145,21 +1930,15 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, } // restore the values. wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - } - else if (Adapter->eNVMType == NVM_EEPROM) - { + } else if (Adapter->eNVMType == NVM_EEPROM) { Status = BeceemEEPROMBulkWrite(Adapter, (PUCHAR)pBuffer, uiOffset, uiNumBytes, bVerify); if (bVerify) - { Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes); - } - } - else - { + } else { Status = -1; } return Status; @@ -2199,12 +1978,9 @@ INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); - if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) - { - if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) - { - if (uiSectorSize == uiCurrentSectorSize) - { + if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { + if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) { + if (uiSectorSize == uiCurrentSectorSize) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash"); Status = STATUS_SUCCESS; goto Restore; @@ -2212,8 +1988,7 @@ INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) } } - if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) - { + if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) { sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize); sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG); @@ -2251,47 +2026,32 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe if (Adapter->bSectorSizeOverride && (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) - { + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) { Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } - else - { + } else { uiSectorSig = FlashSectorSizeSig; - if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) - { + if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { uiSectorSize = FlashSectorSize; // // If the sector size stored in the FLASH makes sense then use it. // - if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) - { + if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) { Adapter->uiSectorSize = uiSectorSize; - } - //No valid size in FLASH, check if Config file has it. - else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) - { + } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && + Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { + //No valid size in FLASH, check if Config file has it. Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } - // Init to Default, if none of the above works. - else - { + } else { + // Init to Default, if none of the above works. Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; } - } - else - { + } else { if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) - { Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } else - { Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; - } } } @@ -2353,16 +2113,11 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) BcmValidateNvmType(ps_adapter); BcmInitEEPROMQueues(ps_adapter); - if (ps_adapter->eNVMType == NVM_AUTODETECT) - { + if (ps_adapter->eNVMType == NVM_AUTODETECT) { ps_adapter->eNVMType = BcmGetNvmType(ps_adapter); if (ps_adapter->eNVMType == NVM_UNKNOWN) - { BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); - } - } - else if (ps_adapter->eNVMType == NVM_FLASH) - { + } else if (ps_adapter->eNVMType == NVM_FLASH) { BcmGetFlashCSInfo(ps_adapter); } @@ -2384,13 +2139,10 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) { if (Adapter->eNVMType == NVM_EEPROM) - { Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); - } else if (Adapter->eNVMType == NVM_FLASH) - { Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter); - } + return 0; } @@ -2416,9 +2168,7 @@ static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) if (Adapter->eNVMType == NVM_FLASH && Adapter->chip_id < 0xBECE3300) - { Adapter->eNVMType = NVM_AUTODETECT; - } } //----------------------------------------------------------------------------- @@ -2458,29 +2208,25 @@ static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { - if (psAdapter == NULL) - { + if (psAdapter == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL); - if (psAdapter->psFlashCSInfo == NULL) - { + if (psAdapter->psFlashCSInfo == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x"); return -ENOMEM; } psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL); - if (psAdapter->psFlash2xCSInfo == NULL) - { + if (psAdapter->psFlash2xCSInfo == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); return -ENOMEM; } psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL); - if (psAdapter->psFlash2xVendorInfo == NULL) - { + if (psAdapter->psFlash2xVendorInfo == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); kfree(psAdapter->psFlash2xCSInfo); @@ -2492,8 +2238,7 @@ INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { - if (psAdapter == NULL) - { + if (psAdapter == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } @@ -2557,10 +2302,8 @@ static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bc BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) - { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, (psFlash2xCSInfo->SectorAccessBitMap[Index])); - } return STATUS_SUCCESS; } @@ -2617,9 +2360,8 @@ static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End); for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) - { psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); - } + return STATUS_SUCCESS; } @@ -2676,10 +2418,8 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) return; i = 0; - while (i < TOTAL_SECTIONS) - { - if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) - { + while (i < TOTAL_SECTIONS) { + if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) { i++; continue; } @@ -2688,53 +2428,52 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd - Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); - switch (i) - { - case DSD0: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; - break; + switch (i) { + case DSD0: + if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; + break; - case DSD1: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; - break; + case DSD1: + if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; + break; - case DSD2: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; - break; - case VSA0: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; - break; + case DSD2: + if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) && + (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; + break; + case VSA0: + if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; + break; - case VSA1: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; - break; - case VSA2: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; - break; + case VSA1: + if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; + break; + case VSA2: + if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; + else + Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; + break; - default: - break; + default: + break; } i++; } @@ -2770,12 +2509,9 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) memset(Adapter->psFlashCSInfo, 0 , sizeof(FLASH_CS_INFO)); memset(Adapter->psFlash2xCSInfo, 0 , sizeof(FLASH2X_CS_INFO)); - if (!Adapter->bDDRInitDone) - { - { - value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); - } + if (!Adapter->bDDRInitDone) { + value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; + wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); } // Reading first 8 Bytes to get the Flash Layout @@ -2787,41 +2523,32 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); - if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) - { + if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) { uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); - } - else - { + } else { Adapter->uiFlashLayoutMinorVersion = 0; uiFlashLayoutMajorVersion = 0; } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); - if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) - { + if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) { BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(FLASH_CS_INFO)); ConvertEndianOfCSStructure(Adapter->psFlashCSInfo); Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart); if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - { Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart; - } if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && - (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) - { + (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) { Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize); Adapter->fpFlashWrite = flashByteWrite; Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; - } - else - { + } else { Adapter->ulFlashWriteSize = MAX_RW_SIZE; Adapter->fpFlashWrite = flashWrite; Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; @@ -2830,12 +2557,9 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig), (Adapter->psFlashCSInfo->FlashSectorSize)); Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF; - } - else - { + } else { if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL, - Adapter->ulFlashControlSectionStart, sizeof(FLASH2X_CS_INFO))) - { + Adapter->ulFlashControlSectionStart, sizeof(FLASH2X_CS_INFO))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n"); return STATUS_FAILURE; } @@ -2845,14 +2569,11 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && - (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) - { + (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) { Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize; Adapter->fpFlashWrite = flashByteWrite; Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; - } - else - { + } else { Adapter->ulFlashWriteSize = MAX_RW_SIZE; Adapter->fpFlashWrite = flashWrite; Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; @@ -2897,9 +2618,7 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); if (uiData == BECM) - { return NVM_EEPROM; - } // // Read control struct and get cal addresses before accessing the flash @@ -2908,18 +2627,14 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4); if (uiData == BECM) - { return NVM_FLASH; - } // // even if there is no valid signature on EEPROM/FLASH find out if they really exist. // if exist select it. // if (BcmGetEEPROMSize(Adapter)) - { return NVM_EEPROM; - } //TBD for Flash. return NVM_UNKNOWN; @@ -2948,73 +2663,70 @@ INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO SectStartOffset = INVALID_OFFSET; if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal)) - { return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart; - } - switch (eFlashSectionVal) - { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - break; - case CONTROL_SECTION: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); - break; - case ISO_IMAGE1_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); - break; - case ISO_IMAGE1_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - break; - case ISO_IMAGE2_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); - break; - case ISO_IMAGE2_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); - SectStartOffset = INVALID_OFFSET; + switch (eFlashSectionVal) { + case ISO_IMAGE1: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); + break; + case ISO_IMAGE2: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); + break; + case DSD0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); + break; + case DSD1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); + break; + case DSD2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); + break; + case VSA0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); + break; + case VSA1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); + break; + case VSA2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); + break; + case SCSI: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); + break; + case CONTROL_SECTION: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); + break; + case ISO_IMAGE1_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); + break; + case ISO_IMAGE1_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); + break; + case ISO_IMAGE2_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); + break; + case ISO_IMAGE2_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) + SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); + break; + default: + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); + SectStartOffset = INVALID_OFFSET; } return SectStartOffset; @@ -3036,72 +2748,69 @@ INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ SectEndOffset = INVALID_OFFSET; if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - { return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd; - } - switch (eFlash2xSectionVal) - { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + - (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); - break; - case CONTROL_SECTION: - //Not Clear So Putting failure. confirm and fix it. - SectEndOffset = STATUS_FAILURE; - case ISO_IMAGE1_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); - break; - case ISO_IMAGE1_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); - break; - case ISO_IMAGE2_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); - break; - case ISO_IMAGE2_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); - break; - default: - SectEndOffset = INVALID_OFFSET; + switch (eFlash2xSectionVal) { + case ISO_IMAGE1: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); + break; + case ISO_IMAGE2: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); + break; + case DSD0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); + break; + case DSD1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); + break; + case DSD2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); + break; + case VSA0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); + break; + case VSA1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); + break; + case VSA2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); + break; + case SCSI: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + + (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); + break; + case CONTROL_SECTION: + //Not Clear So Putting failure. confirm and fix it. + SectEndOffset = STATUS_FAILURE; + case ISO_IMAGE1_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); + break; + case ISO_IMAGE1_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); + break; + case ISO_IMAGE2_PART2: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); + break; + case ISO_IMAGE2_PART3: + if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS) + SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); + break; + default: + SectEndOffset = INVALID_OFFSET; } return SectEndOffset ; @@ -3130,13 +2839,11 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, UINT uiAbsoluteOffset = 0; UINT uiTemp = 0, value = 0; - if (Adapter == NULL) - { + if (Adapter == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); return -EINVAL; } - if (Adapter->device_removed) - { + if (Adapter->device_removed) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); return -ENODEV; } @@ -3147,8 +2854,7 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, else SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - if (SectionStartOffset == STATUS_FAILURE) - { + if (SectionStartOffset == STATUS_FAILURE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal); return -EINVAL; } @@ -3163,8 +2869,7 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes); wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); return Status; } @@ -3196,14 +2901,12 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, UINT FlashSectValStartOffset = 0; UINT uiTemp = 0, value = 0; - if (Adapter == NULL) - { + if (Adapter == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); return -EINVAL; } - if (Adapter->device_removed) - { + if (Adapter->device_removed) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); return -ENODEV; } @@ -3214,8 +2917,7 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, else FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal); - if (FlashSectValStartOffset == STATUS_FAILURE) - { + if (FlashSectValStartOffset == STATUS_FAILURE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal); return -EINVAL; } @@ -3233,8 +2935,7 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify); wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); return Status; } @@ -3266,21 +2967,15 @@ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; if (Adapter->eActiveDSD) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); - if (Adapter->eActiveDSD == 0) - { + if (Adapter->eActiveDSD == 0) { //if No DSD gets Active, Make Active the DSD with WR permission - if (IsSectionWritable(Adapter, DSD2)) - { + if (IsSectionWritable(Adapter, DSD2)) { Adapter->eActiveDSD = DSD2; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; - } - else if (IsSectionWritable(Adapter, DSD1)) - { + } else if (IsSectionWritable(Adapter, DSD1)) { Adapter->eActiveDSD = DSD1; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; - } - else if (IsSectionWritable(Adapter, DSD0)) - { + } else if (IsSectionWritable(Adapter, DSD0)) { Adapter->eActiveDSD = DSD0; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; } @@ -3397,8 +3092,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM // For 1.x map all the section except DSD0 will be shown as not present // This part will be used by calibration tool to detect the number of DSD present in Flash. - if (IsFlash2x(Adapter) == FALSE) - { + if (IsFlash2x(Adapter) == FALSE) { psFlash2xBitMap->ISO_IMAGE2 = 0; psFlash2xBitMap->ISO_IMAGE1 = 0; psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present) @@ -3422,8 +3116,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // IS0 IMAGE 2 /// - if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) { //Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; @@ -3434,8 +3127,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE) psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; - if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) - { + if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) { psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT; SetActiveISODone = TRUE; } @@ -3444,8 +3136,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // IS0 IMAGE 1 /// - if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; @@ -3456,8 +3147,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE) psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; - if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) - { + if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) { psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT; SetActiveISODone = TRUE; } @@ -3466,8 +3156,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // DSD2 /// - if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) { //Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; @@ -3475,15 +3164,11 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; // Calculation for extrating the Access permission - if (IsSectionWritable(Adapter, DSD2) == FALSE) - { + if (IsSectionWritable(Adapter, DSD2) == FALSE) { psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; - } - else - { + } else { //Means section is writable - if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) - { + if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) { psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT; SetActiveDSDDone = TRUE; } @@ -3493,8 +3178,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // DSD 1 /// - if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; @@ -3502,15 +3186,11 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; // Calculation for extrating the Access permission - if (IsSectionWritable(Adapter, DSD1) == FALSE) - { + if (IsSectionWritable(Adapter, DSD1) == FALSE) { psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; - } - else - { + } else { // Means section is writable - if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) - { + if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) { psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT; SetActiveDSDDone = TRUE; } @@ -3520,8 +3200,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// //For DSD 0 // - if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) { //Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; @@ -3529,15 +3208,11 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; // Setting Access permission - if (IsSectionWritable(Adapter, DSD0) == FALSE) - { + if (IsSectionWritable(Adapter, DSD0) == FALSE) { psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; - } - else - { + } else { // Means section is writable - if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) - { + if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) { psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT; SetActiveDSDDone = TRUE; } @@ -3547,8 +3222,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // VSA 0 /// - if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; @@ -3566,8 +3240,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // VSA 1 /// - if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; @@ -3585,8 +3258,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // VSA 2 /// - if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; @@ -3604,8 +3276,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // SCSI Section /// - if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; @@ -3623,8 +3294,7 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM /// // Control Section /// - if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) - { + if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) { // Setting the 0th Bit representing the Section is present or not. psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); @@ -3672,177 +3342,157 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF INT HighestPriISO = 0; Status = IsSectionWritable(Adapter, eFlash2xSectVal); - if (Status != TRUE) - { + if (Status != TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal); return STATUS_FAILURE; } Adapter->bHeaderChangeAllowed = TRUE; - switch (eFlash2xSectVal) - { - case ISO_IMAGE1: - case ISO_IMAGE2: - if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) - { + switch (eFlash2xSectVal) { + case ISO_IMAGE1: + case ISO_IMAGE2: + if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) { + HighestPriISO = getHighestPriISO(Adapter); + + if (HighestPriISO == eFlash2xSectVal) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); + Status = STATUS_SUCCESS; + break; + } + + SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; + + if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) { + // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. + // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO + // by user + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); + SectImagePriority = htonl(0x1); + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + HighestPriISO, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + Status = STATUS_FAILURE; + break; + } + HighestPriISO = getHighestPriISO(Adapter); - if (HighestPriISO == eFlash2xSectVal) - { + if (HighestPriISO == eFlash2xSectVal) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); Status = STATUS_SUCCESS; break; } - SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; - - if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) - { - // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. - // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO - // by user - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); - SectImagePriority = htonl(0x1); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriISO, - 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - Status = STATUS_FAILURE; - break; - } - - HighestPriISO = getHighestPriISO(Adapter); + SectImagePriority = 2; + } - if (HighestPriISO == eFlash2xSectVal) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } + SectImagePriority = htonl(SectImagePriority); - SectImagePriority = 2; - } + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + eFlash2xSectVal, + 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); + break; + } + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); + Status = STATUS_FAILURE; + break; + } + break; + case DSD0: + case DSD1: + case DSD2: + if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) { + HighestPriDSD = getHighestPriDSD(Adapter); + if ((HighestPriDSD == eFlash2xSectVal)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal); + Status = STATUS_SUCCESS; + break; + } - SectImagePriority = htonl(SectImagePriority); + SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; + if (SectImagePriority <= 0) { + // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. + // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD + // by user + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); + SectImagePriority = htonl(0x1); Status = BcmFlash2xBulkWrite(Adapter, &SectImagePriority, - eFlash2xSectVal, - 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority), + HighestPriDSD, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), SIGNATURE_SIZE, TRUE); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); break; } - } - else - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE; - break; - } - break; - case DSD0: - case DSD1: - case DSD2: - if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) - { + HighestPriDSD = getHighestPriDSD(Adapter); - if ((HighestPriDSD == eFlash2xSectVal)) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal); + + if ((HighestPriDSD == eFlash2xSectVal)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); Status = STATUS_SUCCESS; break; } - SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; - if (SectImagePriority <= 0) - { - // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. - // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD - // by user - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); - SectImagePriority = htonl(0x1); - - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - - HighestPriDSD = getHighestPriDSD(Adapter); - - if ((HighestPriDSD == eFlash2xSectVal)) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = htonl(0x2); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - - HighestPriDSD = getHighestPriDSD(Adapter); - if ((HighestPriDSD == eFlash2xSectVal)) - { - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = 3; - } - SectImagePriority = htonl(SectImagePriority); + SectImagePriority = htonl(0x2); Status = BcmFlash2xBulkWrite(Adapter, &SectImagePriority, - eFlash2xSectVal, + HighestPriDSD, Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), SIGNATURE_SIZE, TRUE); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - Status = STATUS_FAILURE; break; } + + HighestPriDSD = getHighestPriDSD(Adapter); + if ((HighestPriDSD == eFlash2xSectVal)) { + Status = STATUS_SUCCESS; + break; + } + + SectImagePriority = 3; } - else - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); + SectImagePriority = htonl(SectImagePriority); + Status = BcmFlash2xBulkWrite(Adapter, + &SectImagePriority, + eFlash2xSectVal, + Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority), + SIGNATURE_SIZE, + TRUE); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); Status = STATUS_FAILURE; break; } - break; - case VSA0: - case VSA1: - case VSA2: - // Has to be decided - break; - default: + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); Status = STATUS_FAILURE; break; + } + break; + case VSA0: + case VSA1: + case VSA2: + // Has to be decided + break; + default: + Status = STATUS_FAILURE; + break; } Adapter->bHeaderChangeAllowed = FALSE; @@ -3871,8 +3521,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS UINT SigBuff[MAX_RW_SIZE]; UINT i = 0; - if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) - { + if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); return STATUS_FAILURE; } @@ -3882,30 +3531,25 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS sCopySectStrut.SrcSection, 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageSize), 4); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); return Status; } ISOLength = htonl(ISOLength); if (ISOLength % Adapter->uiSectorSize) - { ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize); - } sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber); Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (Buff == NULL) - { + if (Buff == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size"); return -ENOMEM; } - if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) - { + if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) { eISOReadPart = ISO_IMAGE1; eISOWritePart = ISO_IMAGE2; uiReadOffsetWithinPart = 0; @@ -3918,8 +3562,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - if (uiTotalDataToCopy < ISOLength) - { + if (uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); Status = STATUS_FAILURE; goto out; @@ -3932,8 +3575,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - if (uiTotalDataToCopy < ISOLength) - { + if (uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); Status = STATUS_FAILURE; goto out; @@ -3942,10 +3584,8 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS uiTotalDataToCopy = ISOLength; CorruptISOSig(Adapter, ISO_IMAGE2); - while (uiTotalDataToCopy) - { - if (uiTotalDataToCopy == Adapter->uiSectorSize) - { + while (uiTotalDataToCopy) { + if (uiTotalDataToCopy == Adapter->uiSectorSize) { // Setting for write of first sector. First sector is assumed to be written in last BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); eISOReadPart = ISO_IMAGE1; @@ -3953,32 +3593,26 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS eISOWritePart = ISO_IMAGE2; uiWriteOffsetWithinPart = 0; IsThisHeaderSector = TRUE; - } - else - { + } else { uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) - { + if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { eISOReadPart = ISO_IMAGE1_PART2; uiReadOffsetWithinPart = 0; } - if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) - { + if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { eISOReadPart = ISO_IMAGE1_PART3; uiReadOffsetWithinPart = 0; } - if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) - { + if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { eISOWritePart = ISO_IMAGE2_PART2; uiWriteOffsetWithinPart = 0; } - if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) - { + if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { eISOWritePart = ISO_IMAGE2_PART3; uiWriteOffsetWithinPart = 0; } @@ -3989,14 +3623,12 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS eISOReadPart, uiReadOffsetWithinPart, Adapter->uiSectorSize); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); break; } - if (IsThisHeaderSector == TRUE) - { + if (IsThisHeaderSector == TRUE) { // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); @@ -4010,15 +3642,13 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS uiWriteOffsetWithinPart, Adapter->uiSectorSize, TRUE); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); break; } Adapter->bHeaderChangeAllowed = FALSE; - if (IsThisHeaderSector == TRUE) - { + if (IsThisHeaderSector == TRUE) { WriteToFlashWithoutSectorErase(Adapter, SigBuff, eISOWritePart, @@ -4031,8 +3661,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS } } - if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) - { + if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) { eISOReadPart = ISO_IMAGE2; eISOWritePart = ISO_IMAGE1; uiReadOffsetWithinPart = 0; @@ -4045,8 +3674,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - if (uiTotalDataToCopy < ISOLength) - { + if (uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); Status = STATUS_FAILURE; goto out; @@ -4059,8 +3687,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - if (uiTotalDataToCopy < ISOLength) - { + if (uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); Status = STATUS_FAILURE; goto out; @@ -4070,10 +3697,8 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS CorruptISOSig(Adapter, ISO_IMAGE1); - while (uiTotalDataToCopy) - { - if (uiTotalDataToCopy == Adapter->uiSectorSize) - { + while (uiTotalDataToCopy) { + if (uiTotalDataToCopy == Adapter->uiSectorSize) { //Setting for write of first sector. First sector is assumed to be written in last BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); eISOReadPart = ISO_IMAGE2; @@ -4081,32 +3706,26 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS eISOWritePart = ISO_IMAGE1; uiWriteOffsetWithinPart = 0; IsThisHeaderSector = TRUE; - } - else - { + } else { uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) - { + if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { eISOReadPart = ISO_IMAGE2_PART2; uiReadOffsetWithinPart = 0; } - if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) - { + if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { eISOReadPart = ISO_IMAGE2_PART3; uiReadOffsetWithinPart = 0; } - if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) - { + if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { eISOWritePart = ISO_IMAGE1_PART2; uiWriteOffsetWithinPart = 0; } - if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) - { + if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { eISOWritePart = ISO_IMAGE1_PART3; uiWriteOffsetWithinPart = 0; } @@ -4117,14 +3736,12 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS eISOReadPart, uiReadOffsetWithinPart, Adapter->uiSectorSize); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); break; } - if (IsThisHeaderSector == TRUE) - { + if (IsThisHeaderSector == TRUE) { // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); @@ -4138,15 +3755,13 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS uiWriteOffsetWithinPart, Adapter->uiSectorSize, TRUE); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); break; } Adapter->bHeaderChangeAllowed = FALSE; - if (IsThisHeaderSector == TRUE) - { + if (IsThisHeaderSector == TRUE) { WriteToFlashWithoutSectorErase(Adapter, SigBuff, eISOWritePart, @@ -4185,16 +3800,11 @@ INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal); - if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) - { + if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) { Status = CorruptDSDSig(Adapter, eFlash2xSectionVal); - } - else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) - { + } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) { Status = CorruptISOSig(Adapter, eFlash2xSectionVal); - } - else - { + } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal); return STATUS_SUCCESS; } @@ -4219,47 +3829,37 @@ INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl UINT uiOffset = 0; // DSD_HEADER dsdHeader = {0}; - if (Adapter->bSigCorrupted == FALSE) - { + if (Adapter->bSigCorrupted == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n"); return STATUS_SUCCESS; } - if (Adapter->bAllDSDWriteAllow == FALSE) - { - if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) - { + if (Adapter->bAllDSDWriteAllow == FALSE) { + if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature"); return SECTOR_IS_NOT_WRITABLE; } } - if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) - { + if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) { uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER); uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader; uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber); - if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) - { + if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig"); return STATUS_FAILURE; } - } - else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) - { + } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) { uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); // uiOffset = 0; uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber); - if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) - { + if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig"); return STATUS_FAILURE; } - } - else - { + } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); return STATUS_FAILURE; } @@ -4293,26 +3893,21 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT uiNumOfBytes = psFlash2xReadWrite->numOfBytes; - if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) - { + if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section); return FALSE; } uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section); - if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) - { - if (psFlash2xReadWrite->Section == ISO_IMAGE1) - { + if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) { + if (psFlash2xReadWrite->Section == ISO_IMAGE1) { uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3); - } - else if (psFlash2xReadWrite->Section == ISO_IMAGE2) - { + } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) { uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) + BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) - @@ -4326,8 +3921,7 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset); - } - else + } else uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); @@ -4335,8 +3929,7 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT // Checking the boundary condition if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) return TRUE; - else - { + else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); return FALSE; } @@ -4370,8 +3963,7 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) { UINT uiBaseAddr = 0; - if (Adapter->bDDRInitDone) - { + if (Adapter->bDDRInitDone) { /* For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr In case of Raw Read... use the default value @@ -4381,9 +3973,7 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) uiBaseAddr = Adapter->uiFlashBaseAdd; else uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; - } - else - { + } else { /* For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr In case of Raw Read... use the default value @@ -4426,27 +4016,23 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, PUCHAR pBuff = NULL; INT Status = STATUS_SUCCESS; - if (SrcSection == DstSection) - { + if (SrcSection == DstSection) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again"); return -EINVAL; } - if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) - { + if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection"); return -EINVAL; } - if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) - { + if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection"); return -EINVAL; } // if offset zero means have to copy complete secton - if (numOfBytes == 0) - { + if (numOfBytes == 0) { numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection) - BcmGetSectionValStartOffset(Adapter, SrcSection); @@ -4454,16 +4040,14 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, } if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection) - - BcmGetSectionValStartOffset(Adapter, SrcSection)) - { + - BcmGetSectionValStartOffset(Adapter, SrcSection)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n", offset, numOfBytes); return -EINVAL; } if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection) - - BcmGetSectionValStartOffset(Adapter, DstSection)) - { + - BcmGetSectionValStartOffset(Adapter, DstSection)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", offset, numOfBytes); return -EINVAL; @@ -4475,8 +4059,7 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, BuffSize = numOfBytes; pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL); - if (pBuff == NULL) - { + if (pBuff == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); return -ENOMEM; } @@ -4489,24 +4072,20 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, Adapter->bHeaderChangeAllowed = TRUE; - do - { + do { Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied); break; } Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE); - if (Status) - { + if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied); break; } offset = offset + BytesToBeCopied; numOfBytes = numOfBytes - BytesToBeCopied; - if (numOfBytes) - { + if (numOfBytes) { if (numOfBytes > Adapter->uiSectorSize) BytesToBeCopied = Adapter->uiSectorSize; else @@ -4545,8 +4124,7 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) || (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) || - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) - { + (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) { // offset from the sector boundary having the header map offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; HeaderSizeToProtect = sizeof(DSD_HEADER); @@ -4554,18 +4132,15 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO } if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) || - uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) - { + uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) { offsetToProtect = 0; HeaderSizeToProtect = sizeof(ISO_HEADER); bHasHeader = TRUE; } // If Header is present overwrite passed buffer with this - if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) - { + if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) { pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL); - if (pTempBuff == NULL) - { + if (pTempBuff == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); return -ENOMEM; } @@ -4577,12 +4152,10 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO kfree(pTempBuff); } - if (bHasHeader && Adapter->bSigCorrupted) - { + if (bHasHeader && Adapter->bSigCorrupted) { sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber))); sig = ntohl(sig); - if ((sig & 0xFF000000) != CORRUPTED_PATTERN) - { + if ((sig & 0xFF000000) != CORRUPTED_PATTERN) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore"); Adapter->bSigCorrupted = FALSE; return STATUS_SUCCESS; @@ -4637,23 +4210,22 @@ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); { - switch (ChipNum) - { - case 0: - PartNum = 0; - break; - case 1: - PartNum = 3; - GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); - break; - case 2: - PartNum = 1; - GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); - break; - case 3: - PartNum = 2; - GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); - break; + switch (ChipNum) { + case 0: + PartNum = 0; + break; + case 1: + PartNum = 3; + GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); + break; + case 2: + PartNum = 1; + GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); + break; + case 3: + PartNum = 2; + GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); + break; } } /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, @@ -4687,8 +4259,7 @@ INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; - if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) - { + if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs"); return STATUS_FAILURE; } @@ -4710,10 +4281,8 @@ INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) unsigned int uiDSDPri = STATUS_FAILURE; // DSD_HEADER dsdHeader = {0}; // priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; - if (IsSectionWritable(Adapter, dsd)) - { - if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) - { + if (IsSectionWritable(Adapter, dsd)) { + if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) { BcmFlash2xBulkRead(Adapter, &uiDSDPri, dsd, @@ -4734,27 +4303,22 @@ FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter) INT DsdPri = 0; FLASH2X_SECTION_VAL HighestPriDSD = 0; - if (IsSectionWritable(Adapter, DSD2)) - { + if (IsSectionWritable(Adapter, DSD2)) { DSDHighestPri = ReadDSDPriority(Adapter, DSD2); HighestPriDSD = DSD2; } - if (IsSectionWritable(Adapter, DSD1)) - { + if (IsSectionWritable(Adapter, DSD1)) { DsdPri = ReadDSDPriority(Adapter, DSD1); - if (DSDHighestPri < DsdPri) - { + if (DSDHighestPri < DsdPri) { DSDHighestPri = DsdPri; HighestPriDSD = DSD1; } } - if (IsSectionWritable(Adapter, DSD0)) - { + if (IsSectionWritable(Adapter, DSD0)) { DsdPri = ReadDSDPriority(Adapter, DSD0); - if (DSDHighestPri < DsdPri) - { + if (DSDHighestPri < DsdPri) { DSDHighestPri = DsdPri; HighestPriDSD = DSD0; } @@ -4772,8 +4336,7 @@ INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) //ISO_HEADER ISOHeader = {0}; //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; - if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) - { + if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs"); return STATUS_FAILURE; } @@ -4792,10 +4355,8 @@ INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { unsigned int ISOPri = STATUS_FAILURE; - if (IsSectionWritable(Adapter, iso)) - { - if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) - { + if (IsSectionWritable(Adapter, iso)) { + if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) { BcmFlash2xBulkRead(Adapter, &ISOPri, iso, @@ -4816,17 +4377,14 @@ FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter) INT ISOPri = 0; FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL; - if (IsSectionWritable(Adapter, ISO_IMAGE2)) - { + if (IsSectionWritable(Adapter, ISO_IMAGE2)) { ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2); HighestPriISO = ISO_IMAGE2; } - if (IsSectionWritable(Adapter, ISO_IMAGE1)) - { + if (IsSectionWritable(Adapter, ISO_IMAGE1)) { ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1); - if (ISOHighestPri < ISOPri) - { + if (ISOHighestPri < ISOPri) { ISOHighestPri = ISOPri; HighestPriISO = ISO_IMAGE1; } @@ -4853,8 +4411,7 @@ INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, INT Status = STATUS_SUCCESS; PUCHAR pcBuff = (PUCHAR)pBuff; - if (uiNumBytes % Adapter->ulFlashWriteSize) - { + if (uiNumBytes % Adapter->ulFlashWriteSize) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); return STATUS_FAILURE; } @@ -4862,9 +4419,7 @@ INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - { return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes); - } uiOffset = uiOffset + uiStartOffset; @@ -4879,8 +4434,7 @@ INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, BcmDoChipSelect(Adapter, uiOffset); uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) - { + for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) { if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) Status = flashByteWrite(Adapter, uiPartOffset, pcBuff); else @@ -4903,53 +4457,52 @@ BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ { BOOLEAN SectionPresent = FALSE; - switch (section) - { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectionPresent = TRUE; - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == FALSE)) - SectionPresent = TRUE; - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case CONTROL_SECTION: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); - SectionPresent = FALSE; + switch (section) { + case ISO_IMAGE1: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectionPresent = TRUE; + break; + case ISO_IMAGE2: + if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && + (IsNonCDLessDevice(Adapter) == FALSE)) + SectionPresent = TRUE; + break; + case DSD0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case DSD1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case DSD2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case VSA0: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case VSA1: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case VSA2: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case SCSI: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + case CONTROL_SECTION: + if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) + SectionPresent = TRUE; + break; + default: + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); + SectionPresent = FALSE; } return SectionPresent; @@ -4960,23 +4513,19 @@ INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Sect INT offset = STATUS_FAILURE; INT Status = FALSE; - if (IsSectionExistInFlash(Adapter, Section) == FALSE) - { + if (IsSectionExistInFlash(Adapter, Section) == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section); return FALSE; } offset = BcmGetSectionValStartOffset(Adapter, Section); - if (offset == INVALID_OFFSET) - { + if (offset == INVALID_OFFSET) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section); return FALSE; } if (IsSectionExistInVendorInfo(Adapter, Section)) - { return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); - } Status = IsOffsetWritable(Adapter, offset); return Status; @@ -4991,18 +4540,15 @@ static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e UINT uiSectAlignAddr = 0; Adapter->bSigCorrupted = FALSE; - if (Adapter->bAllDSDWriteAllow == FALSE) - { - if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) - { + if (Adapter->bAllDSDWriteAllow == FALSE) { + if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); return SECTOR_IS_NOT_WRITABLE; } } pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (pBuff == NULL) - { + if (pBuff == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); return -ENOMEM; } @@ -5018,30 +4564,23 @@ static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e // Now corrupting the sig by corrupting 4th last Byte. *(pBuff + 12) = 0; - if (sig == DSD_IMAGE_MAGIC_NUMBER) - { + if (sig == DSD_IMAGE_MAGIC_NUMBER) { Adapter->bSigCorrupted = TRUE; - if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) - { + if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) { uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal, (uiOffset + 12), BYTE_WRITE_SUPPORT); - if (BlockStatus) - { + if (BlockStatus) { BcmRestoreBlockProtectStatus(Adapter, BlockStatus); BlockStatus = 0; } - } - else - { + } else { WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); } - } - else - { + } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); kfree(pBuff); @@ -5062,15 +4601,13 @@ static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e Adapter->bSigCorrupted = FALSE; - if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) - { + if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); return SECTOR_IS_NOT_WRITABLE; } pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (pBuff == NULL) - { + if (pBuff == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); return -ENOMEM; } @@ -5085,14 +4622,11 @@ static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e // corrupt signature *pBuff = 0; - if (sig == ISO_IMAGE_MAGIC_NUMBER) - { + if (sig == ISO_IMAGE_MAGIC_NUMBER) { Adapter->bSigCorrupted = TRUE; WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, Adapter->ulFlashWriteSize); - } - else - { + } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); kfree(pBuff); -- GitLab From de443c96e5e62c5c32ae6fdfc44e12470bbf70b3 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 6 Jun 2012 22:54:29 -0400 Subject: [PATCH 1275/6849] Staging: bcm: Correctly format all comments in nvm.c This patch correctly formats all comments as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 1895 +++++++++++++++++++------------------ 1 file changed, 955 insertions(+), 940 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 66001fcd4402..cfc0458b6e0a 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -51,17 +51,15 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData, UINT dwNumData); -// Procedure: ReadEEPROMStatusRegister -// -// Description: Reads the standard EEPROM Status Register. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- - +/* Procedure: ReadEEPROMStatusRegister + * + * Description: Reads the standard EEPROM Status Register. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * Returns: + * OSAL_STATUS_CODE + */ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) { UCHAR uiData = 0; @@ -110,19 +108,19 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) return uiData; } /* ReadEEPROMStatusRegister */ -//----------------------------------------------------------------------------- -// Procedure: ReadBeceemEEPROMBulk -// -// Description: This routine reads 16Byte data from EEPROM -// -// Arguments: -// Adapter - ptr to Adapter object instance -// dwAddress - EEPROM Offset to read the data from. -// pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY. -// -// Returns: -// OSAL_STATUS_CODE: -//----------------------------------------------------------------------------- +/* + * Procedure: ReadBeceemEEPROMBulk + * + * Description: This routine reads 16Byte data from EEPROM + * + * Arguments: + * Adapter - ptr to Adapter object instance + * dwAddress - EEPROM Offset to read the data from. + * pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY. + * + * Returns: + * OSAL_STATUS_CODE: + */ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, DWORD dwAddress, @@ -159,7 +157,8 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, /* If we are reading 16 bytes we want to be sure that the queue * is full before we read. In the other cases we are ok if the - * queue has data available */ + * queue has data available + */ if (dwNumWords == 4) { if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) { /* Clear the Avail/Full bits - which ever is set. */ @@ -170,7 +169,8 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, } else if (dwNumWords == 1) { if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { /* We just got Avail and we have to read 32bits so we - * need this sleep for Cardbus kind of devices. */ + * need this sleep for Cardbus kind of devices. + */ if (Adapter->chip_id == 0xBECE0210) udelay(800); @@ -226,20 +226,20 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } /* ReadBeceemEEPROMBulk() */ -//----------------------------------------------------------------------------- -// Procedure: ReadBeceemEEPROM -// -// Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page -// reads to do this operation. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiOffset - EEPROM Offset to read the data from. -// pBuffer - Pointer to word where data needs to be stored in. -// -// Returns: -// OSAL_STATUS_CODE: -//----------------------------------------------------------------------------- +/* + * Procedure: ReadBeceemEEPROM + * + * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page + * reads to do this operation. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiOffset - EEPROM Offset to read the data from. + * pBuffer - Pointer to word where data needs to be stored in. + * + * Returns: + * OSAL_STATUS_CODE: + */ INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, DWORD uiOffset, @@ -257,7 +257,8 @@ INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); /* A word can overlap at most over 2 pages. In that case we read the - * next page too. */ + * next page too. + */ if (uiByteOffset > 12) ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); @@ -282,21 +283,21 @@ INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) return Status; } -//----------------------------------------------------------------------------- -// Procedure: BeceemEEPROMBulkRead -// -// Description: Reads the EEPROM and returns the Data. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Buffer to store the data read from EEPROM -// uiOffset - Offset of EEPROM from where data should be read -// uiNumBytes - Number of bytes to be read from the EEPROM. -// -// Returns: -// OSAL_STATUS_SUCCESS - if EEPROM read is successful. -// - if failed. -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemEEPROMBulkRead + * + * Description: Reads the EEPROM and returns the Data. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Buffer to store the data read from EEPROM + * uiOffset - Offset of EEPROM from where data should be read + * uiNumBytes - Number of bytes to be read from the EEPROM. + * + * Returns: + * OSAL_STATUS_SUCCESS - if EEPROM read is successful. + * - if failed. + */ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -304,7 +305,7 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, UINT uiNumBytes) { UINT uiData[4] = {0}; - // UINT uiAddress = 0; + /* UINT uiAddress = 0; */ UINT uiBytesRemaining = uiNumBytes; UINT uiIndex = 0; UINT uiTempOffset = 0; @@ -336,7 +337,8 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, if (uiBytesRemaining >= MAX_RW_SIZE) { /* For the requests more than or equal to 16 bytes, use bulk * read function to make the access faster. - * We read 4 Dwords of data */ + * We read 4 Dwords of data + */ if (0 == ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4)) { memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE); uiOffset += MAX_RW_SIZE; @@ -344,7 +346,7 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, uiIndex += MAX_RW_SIZE; } else { uiFailureRetries++; - mdelay(3); //sleep for a while before retry... + mdelay(3); /* sleep for a while before retry... */ } } else if (uiBytesRemaining >= 4) { if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { @@ -354,18 +356,18 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, uiIndex += 4; } else { uiFailureRetries++; - mdelay(3); //sleep for a while before retry... + mdelay(3); /* sleep for a while before retry... */ } } else { - // Handle the reads less than 4 bytes... + /* Handle the reads less than 4 bytes... */ PUCHAR pCharBuff = (PUCHAR)pBuffer; pCharBuff += uiIndex; if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { - memcpy(pCharBuff, &uiData[0], uiBytesRemaining); //copy only bytes requested. + memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */ uiBytesRemaining = 0; } else { uiFailureRetries++; - mdelay(3); //sleep for a while before retry... + mdelay(3); /* sleep for a while before retry... */ } } } @@ -373,21 +375,21 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, return 0; } -//----------------------------------------------------------------------------- -// Procedure: BeceemFlashBulkRead -// -// Description: Reads the FLASH and returns the Data. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Buffer to store the data read from FLASH -// uiOffset - Offset of FLASH from where data should be read -// uiNumBytes - Number of bytes to be read from the FLASH. -// -// Returns: -// OSAL_STATUS_SUCCESS - if FLASH read is successful. -// - if failed. -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemFlashBulkRead + * + * Description: Reads the FLASH and returns the Data. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Buffer to store the data read from FLASH + * uiOffset - Offset of FLASH from where data should be read + * uiNumBytes - Number of bytes to be read from the FLASH. + * + * Returns: + * OSAL_STATUS_SUCCESS - if FLASH read is successful. + * - if failed. + */ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -405,8 +407,9 @@ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, return -ENODEV; } - // Adding flash Base address - // uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + /* Adding flash Base address + * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + */ #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); return Status; @@ -453,18 +456,18 @@ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, return Status; } -//----------------------------------------------------------------------------- -// Procedure: BcmGetFlashSize -// -// Description: Finds the size of FLASH. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// UINT - size of the FLASH Storage. -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmGetFlashSize + * + * Description: Finds the size of FLASH. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * UINT - size of the FLASH Storage. + * + */ static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) { @@ -474,32 +477,32 @@ static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) return 32 * 1024; } -//----------------------------------------------------------------------------- -// Procedure: BcmGetEEPROMSize -// -// Description: Finds the size of EEPROM. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// UINT - size of the EEPROM Storage. -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmGetEEPROMSize + * + * Description: Finds the size of EEPROM. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * UINT - size of the EEPROM Storage. + * + */ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) { UINT uiData = 0; UINT uiIndex = 0; - // - // if EEPROM is present and already Calibrated,it will have - // 'BECM' string at 0th offset. - // To find the EEPROM size read the possible boundaries of the - // EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will - // result in wrap around. So when we get the End of the EEPROM we will - // get 'BECM' string which is indeed at offset 0. - // + /* + * if EEPROM is present and already Calibrated,it will have + * 'BECM' string at 0th offset. + * To find the EEPROM size read the possible boundaries of the + * EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will + * result in wrap around. So when we get the End of the EEPROM we will + * get 'BECM' string which is indeed at offset 0. + */ BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); if (uiData == BECM) { for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { @@ -508,9 +511,9 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) return uiIndex * 1024; } } else { - // - // EEPROM may not be present or not programmed - // + /* + * EEPROM may not be present or not programmed + */ uiData = 0xBABEFACE; if (0 == BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE)) { uiData = 0; @@ -524,20 +527,20 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) return 0; } -//----------------------------------------------------------------------------- -// Procedure: FlashSectorErase -// -// Description: Finds the sector size of the FLASH. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// addr - sector start address -// numOfSectors - number of sectors to be erased. -// -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: FlashSectorErase + * + * Description: Finds the sector size of the FLASH. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * addr - sector start address + * numOfSectors - number of sectors to be erased. + * + * Returns: + * OSAL_STATUS_CODE + * + */ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, UINT addr, @@ -570,9 +573,10 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, return uiStatus; } iRetries++; - // After every try lets make the CPU free for 10 ms. generally time taken by the - // the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms - // won't hamper performance in any case. + /* After every try lets make the CPU free for 10 ms. generally time taken by the + * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms + * won't hamper performance in any case. + */ msleep(10); } while ((uiStatus & 0x1) && (iRetries < 400)); @@ -585,38 +589,38 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, } return 0; } -//----------------------------------------------------------------------------- -// Procedure: flashByteWrite -// -// Description: Performs Byte by Byte write to flash -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiOffset - Offset of the flash where data needs to be written to. -// pData - Address of Data to be written. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: flashByteWrite + * + * Description: Performs Byte by Byte write to flash + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiOffset - Offset of the flash where data needs to be written to. + * pData - Address of Data to be written. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ UINT value; ULONG ulData = *(PUCHAR)pData; int bytes; - // - // need not write 0xFF because write requires an erase and erase will - // make whole sector 0xFF. - // + /* + * need not write 0xFF because write requires an erase and erase will + * make whole sector 0xFF. + */ if (0xFF == ulData) return STATUS_SUCCESS; - // DumpDebug(NVM_RW,("flashWrite ====>\n")); + /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ value = (FLASH_CMD_WRITE_ENABLE << 24); if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); @@ -633,7 +637,7 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, return STATUS_FAILURE; } - //__udelay(950); + /* __udelay(950); */ do { value = (FLASH_CMD_STATUS_REG_READ << 24); @@ -641,7 +645,7 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - //__udelay(1); + /* __udelay(1); */ bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; @@ -662,37 +666,37 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// Procedure: flashWrite -// -// Description: Performs write to flash -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiOffset - Offset of the flash where data needs to be written to. -// pData - Address of Data to be written. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: flashWrite + * + * Description: Performs write to flash + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiOffset - Offset of the flash where data needs to be written to. + * pData - Address of Data to be written. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT flashWrite(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { - //UINT uiStatus = 0; - //INT iRetries = 0; - //UINT uiReadBack = 0; - + /* UINT uiStatus = 0; + * INT iRetries = 0; + * UINT uiReadBack = 0; + */ UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ UINT value; UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; - // - // need not write 0xFFFFFFFF because write requires an erase and erase will - // make whole sector 0xFFFFFFFF. - // + /* + * need not write 0xFFFFFFFF because write requires an erase and erase will + * make whole sector 0xFFFFFFFF. + */ if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) return 0; @@ -708,14 +712,14 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, return STATUS_FAILURE; } - //__udelay(950); + /* __udelay(950); */ do { value = (FLASH_CMD_STATUS_REG_READ << 24); if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - //__udelay(1); + /* __udelay(1); */ bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; @@ -724,10 +728,11 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, } iRetries--; - //this will ensure that in there will be no changes in the current path. - //currently one rdm/wrm takes 125 us. - //Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay) - //Hence current implementation cycle will intoduce no delay in current path + /* this will ensure that in there will be no changes in the current path. + * currently one rdm/wrm takes 125 us. + * Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay) + * Hence current implementation cycle will intoduce no delay in current path + */ if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) msleep(1); } while ((uiStatus & 0x1) && (iRetries > 0)); @@ -740,38 +745,38 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// Procedure: flashByteWriteStatus -// -// Description: Performs byte by byte write to flash with write done status check -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiOffset - Offset of the flash where data needs to be written to. -// pData - Address of the Data to be written. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/*----------------------------------------------------------------------------- + * Procedure: flashByteWriteStatus + * + * Description: Performs byte by byte write to flash with write done status check + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiOffset - Offset of the flash where data needs to be written to. + * pData - Address of the Data to be written. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ ULONG ulData = *(PUCHAR)pData; UINT value; int bytes; - // - // need not write 0xFFFFFFFF because write requires an erase and erase will - // make whole sector 0xFFFFFFFF. - // + /* + * need not write 0xFFFFFFFF because write requires an erase and erase will + * make whole sector 0xFFFFFFFF. + */ if (0xFF == ulData) return STATUS_SUCCESS; - // DumpDebug(NVM_RW,("flashWrite ====>\n")); + /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ value = (FLASH_CMD_WRITE_ENABLE << 24); if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { @@ -788,7 +793,7 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, return STATUS_FAILURE; } - //msleep(1); + /* msleep(1); */ do { value = (FLASH_CMD_STATUS_REG_READ << 24); @@ -796,7 +801,7 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - //__udelay(1); + /* __udelay(1); */ bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; @@ -817,35 +822,35 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// Procedure: flashWriteStatus -// -// Description: Performs write to flash with write done status check -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiOffset - Offset of the flash where data needs to be written to. -// pData - Address of the Data to be written. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: flashWriteStatus + * + * Description: Performs write to flash with write done status check + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiOffset - Offset of the flash where data needs to be written to. + * pData - Address of the Data to be written. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3 - //UINT uiReadBack = 0; + INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ + /* UINT uiReadBack = 0; */ UINT value; UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; - // - // need not write 0xFFFFFFFF because write requires an erase and erase will - // make whole sector 0xFFFFFFFF. - // + /* + * need not write 0xFFFFFFFF because write requires an erase and erase will + * make whole sector 0xFFFFFFFF. + */ if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) return 0; @@ -859,7 +864,7 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); return STATUS_FAILURE; } - // __udelay(1); + /* __udelay(1); */ do { value = (FLASH_CMD_STATUS_REG_READ << 24); @@ -867,7 +872,7 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); return STATUS_FAILURE; } - //__udelay(1); + /* __udelay(1); */ bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); if (bytes < 0) { uiStatus = bytes; @@ -875,10 +880,11 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, return uiStatus; } iRetries--; - // this will ensure that in there will be no changes in the current path. - // currently one rdm/wrm takes 125 us. - // Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) - // Hence current implementation cycle will intoduce no delay in current path + /* this will ensure that in there will be no changes in the current path. + * currently one rdm/wrm takes 125 us. + * Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) + * Hence current implementation cycle will intoduce no delay in current path + */ if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) msleep(1); @@ -892,18 +898,18 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// Procedure: BcmRestoreBlockProtectStatus -// -// Description: Restores the original block protection status. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// ulWriteStatus -Original status -// Returns: -// -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmRestoreBlockProtectStatus + * + * Description: Restores the original block protection status. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * ulWriteStatus -Original status + * Returns: + * + * + */ static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) { @@ -917,18 +923,18 @@ static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG udelay(20); } -//----------------------------------------------------------------------------- -// Procedure: BcmFlashUnProtectBlock -// -// Description: UnProtects appropriate blocks for writing. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned. -// Returns: -// ULONG - Status value before UnProtect. -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmFlashUnProtectBlock + * + * Description: UnProtects appropriate blocks for writing. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned. + * Returns: + * ULONG - Status value before UnProtect. + * + */ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOffset, UINT uiLength) { @@ -937,63 +943,63 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOff UINT value; uiOffset = uiOffset&0x000FFFFF; - // - // Implemented only for 1MB Flash parts. - // + /* + * Implemented only for 1MB Flash parts. + */ if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) { - // - // Get Current BP status. - // + /* + * Get Current BP status. + */ value = (FLASH_CMD_STATUS_REG_READ << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); udelay(10); - // - // Read status will be WWXXYYZZ. We have to take only WW. - // + /* + * Read status will be WWXXYYZZ. We have to take only WW. + */ rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus)); ulStatus >>= 24; ulWriteStatus = ulStatus; - // - // Bits [5-2] give current block level protection status. - // Bit5: BP3 - DONT CARE - // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 - // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS - // + /* + * Bits [5-2] give current block level protection status. + * Bit5: BP3 - DONT CARE + * BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 + * 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS + */ if (ulStatus) { if ((uiOffset+uiLength) <= 0x80000) { - // - // Offset comes in lower half of 1MB. Protect the upper half. - // Clear BP1 and BP0 and set BP2. - // + /* + * Offset comes in lower half of 1MB. Protect the upper half. + * Clear BP1 and BP0 and set BP2. + */ ulWriteStatus |= (0x4<<2); ulWriteStatus &= ~(0x3<<2); } else if ((uiOffset + uiLength) <= 0xC0000) { - // - // Offset comes below Upper 1/4. Upper 1/4 can be protected. - // Clear BP2 and set BP1 and BP0. - // + /* + * Offset comes below Upper 1/4. Upper 1/4 can be protected. + * Clear BP2 and set BP1 and BP0. + */ ulWriteStatus |= (0x3<<2); ulWriteStatus &= ~(0x1<<4); } else if ((uiOffset + uiLength) <= 0xE0000) { - // - // Offset comes below Upper 1/8. Upper 1/8 can be protected. - // Clear BP2 and BP0 and set BP1 - // + /* + * Offset comes below Upper 1/8. Upper 1/8 can be protected. + * Clear BP2 and BP0 and set BP1 + */ ulWriteStatus |= (0x1<<3); ulWriteStatus &= ~(0x5<<2); } else if ((uiOffset + uiLength) <= 0xF0000) { - // - // Offset comes below Upper 1/16. Only upper 1/16 can be protected. - // Set BP0 and Clear BP2,BP1. - // + /* + * Offset comes below Upper 1/16. Only upper 1/16 can be protected. + * Set BP0 and Clear BP2,BP1. + */ ulWriteStatus |= (0x1<<2); ulWriteStatus &= ~(0x3<<3); } else { - // - // Unblock all. - // Clear BP2,BP1 and BP0. - // + /* + * Unblock all. + * Clear BP2,BP1 and BP0. + */ ulWriteStatus &= ~(0x7<<2); } @@ -1008,21 +1014,21 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOff return ulStatus; } -//----------------------------------------------------------------------------- -// Procedure: BeceemFlashBulkWrite -// -// Description: Performs write to the flash -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the flash where data needs to be written to. -// uiNumBytes - Number of bytes to be written. -// bVerify - read verify flag. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemFlashBulkWrite + * + * Description: Performs write to the flash + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Data to be written. + * uiOffset - Offset of the flash where data needs to be written to. + * uiNumBytes - Number of bytes to be written. + * bVerify - read verify flag. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -1052,8 +1058,9 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - // Adding flash Base address - // uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + /* Adding flash Base address + * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + */ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); @@ -1062,19 +1069,20 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); if (NULL == pTempBuff) goto BeceemFlashBulkWrite_EXIT; - // - // check if the data to be written is overlapped across sectors - // + /* + * check if the data to be written is overlapped across sectors + */ if (uiOffset+uiNumBytes < uiSectBoundary) { uiNumSectTobeRead = 1; } else { - // Number of sectors = Last sector start address/First sector start address + /* Number of sectors = Last sector start address/First sector start address */ uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) uiNumSectTobeRead++; } - // Check whether Requested sector is writable or not in case of flash2x write. But if write call is - // for DSD calibration, allow it without checking of sector permission + /* Check whether Requested sector is writable or not in case of flash2x write. But if write call is + * for DSD calibration, allow it without checking of sector permission + */ if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) { index = 0; @@ -1092,8 +1100,9 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, } Adapter->SelectedChip = RESET_CHIP_SELECT; while (uiNumSectTobeRead) { - // do_gettimeofday(&tv1); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); + /* do_gettimeofday(&tv1); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); + */ uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); BcmDoChipSelect(Adapter, uiSectAlignAddr); @@ -1106,9 +1115,9 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, goto BeceemFlashBulkWrite_EXIT; } - // do_gettimeofday(&tr); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - + /* do_gettimeofday(&tr); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); + */ ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); if (uiNumSectTobeRead > 1) { @@ -1123,9 +1132,9 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); FlashSectorErase(Adapter, uiPartOffset, 1); - // do_gettimeofday(&te); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); - + /* do_gettimeofday(&te); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); + */ for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { if (Adapter->device_removed) { Status = -1; @@ -1138,8 +1147,9 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, } } - // do_gettimeofday(&tw); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); + /* do_gettimeofday(&tw); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); + */ for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { if (Adapter->ulFlashWriteSize == 1) { @@ -1162,8 +1172,9 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, } } } - // do_gettimeofday(&twv); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); + /* do_gettimeofday(&twv); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); + */ if (ulStatus) { BcmRestoreBlockProtectStatus(Adapter, ulStatus); ulStatus = 0; @@ -1175,13 +1186,13 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, uiOffsetFromSectStart += Adapter->uiSectorSize; uiNumSectTobeRead--; } - // do_gettimeofday(&tv2); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - // - // Cleanup. - // -BeceemFlashBulkWrite_EXIT : + /* do_gettimeofday(&tv2); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); + * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); + * + * Cleanup. + */ +BeceemFlashBulkWrite_EXIT: if (ulStatus) BcmRestoreBlockProtectStatus(Adapter, ulStatus); @@ -1191,21 +1202,21 @@ BeceemFlashBulkWrite_EXIT : return Status; } -//----------------------------------------------------------------------------- -// Procedure: BeceemFlashBulkWriteStatus -// -// Description: Writes to Flash. Checks the SPI status after each write. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the flash where data needs to be written to. -// uiNumBytes - Number of bytes to be written. -// bVerify - read verify flag. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemFlashBulkWriteStatus + * + * Description: Writes to Flash. Checks the SPI status after each write. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Data to be written. + * uiOffset - Offset of the flash where data needs to be written to. + * uiNumBytes - Number of bytes to be written. + * bVerify - read verify flag. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -1230,10 +1241,10 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - // uiOffset += Adapter->ulFlashCalStart; - // Adding flash Base address - // uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - + /* uiOffset += Adapter->ulFlashCalStart; + * Adding flash Base address + * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); + */ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; @@ -1242,13 +1253,13 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, if (NULL == pTempBuff) goto BeceemFlashBulkWriteStatus_EXIT; - // - // check if the data to be written is overlapped across sectors - // + /* + * check if the data to be written is overlapped across sectors + */ if (uiOffset+uiNumBytes < uiSectBoundary) { uiNumSectTobeRead = 1; } else { - // Number of sectors = Last sector start address/First sector start address + /* Number of sectors = Last sector start address/First sector start address */ uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) uiNumSectTobeRead++; @@ -1331,10 +1342,10 @@ static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, uiOffsetFromSectStart += Adapter->uiSectorSize; uiNumSectTobeRead--; } -// -// Cleanup. -// -BeceemFlashBulkWriteStatus_EXIT : +/* + * Cleanup. + */ +BeceemFlashBulkWriteStatus_EXIT: if (ulStatus) BcmRestoreBlockProtectStatus(Adapter, ulStatus); @@ -1343,17 +1354,17 @@ BeceemFlashBulkWriteStatus_EXIT : return Status; } -//----------------------------------------------------------------------------- -// Procedure: PropagateCalParamsFromEEPROMToMemory -// -// Description: Dumps the calibration section of EEPROM to DDR. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: PropagateCalParamsFromEEPROMToMemory + * + * Description: Dumps the calibration section of EEPROM to DDR. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * Returns: + * OSAL_STATUS_CODE + * + */ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) { @@ -1404,32 +1415,32 @@ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) return Status; } -//----------------------------------------------------------------------------- -// Procedure: PropagateCalParamsFromFlashToMemory -// -// Description: Dumps the calibration section of EEPROM to DDR. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: PropagateCalParamsFromFlashToMemory + * + * Description: Dumps the calibration section of EEPROM to DDR. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * Returns: + * OSAL_STATUS_CODE + * + */ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff, pPtr; UINT uiEepromSize = 0; UINT uiBytesToCopy = 0; - //UINT uiIndex = 0; + /* UINT uiIndex = 0; */ UINT uiCalStartAddr = EEPROM_CALPARAM_START; UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT value; INT Status = 0; - // - // Write the signature first. This will ensure firmware does not access EEPROM. - // + /* + * Write the signature first. This will ensure firmware does not access EEPROM. + */ value = 0xbeadbead; wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); value = 0xbeadbead; @@ -1441,9 +1452,9 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) uiEepromSize = ntohl(uiEepromSize); uiEepromSize >>= 16; - // - // subtract the auto init section size - // + /* + * subtract the auto init section size + */ uiEepromSize -= EEPROM_CALPARAM_START; if (uiEepromSize > 1024 * 1024) @@ -1479,20 +1490,20 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) return Status; } -//----------------------------------------------------------------------------- -// Procedure: BeceemEEPROMReadBackandVerify -// -// Description: Read back the data written and verifies. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the flash where data needs to be written to. -// uiNumBytes - Number of bytes to be written. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemEEPROMReadBackandVerify + * + * Description: Read back the data written and verifies. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Data to be written. + * uiOffset - Offset of the flash where data needs to be written to. + * uiNumBytes - Number of bytes to be written. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -1509,11 +1520,11 @@ static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, return -1; if (uiNumBytes >= MAX_RW_SIZE) { - // for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. + /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */ BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { - // re-write + /* re-write */ BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE); mdelay(3); BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); @@ -1527,7 +1538,7 @@ static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, } else if (uiNumBytes >= 4) { BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); if (uiData != pBuffer[uiIndex]) { - // re-write + /* re-write */ BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE); mdelay(3); BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); @@ -1538,7 +1549,7 @@ static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, uiNumBytes -= 4; uiIndex++; } else { - // Handle the reads less than 4 bytes... + /* Handle the reads less than 4 bytes... */ uiData = 0; memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(UINT)), uiNumBytes); BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); @@ -1565,19 +1576,19 @@ static VOID BcmSwapWord(UINT *ptr1) ptr[3] = ptr2[0]; } -//----------------------------------------------------------------------------- -// Procedure: BeceemEEPROMWritePage -// -// Description: Performs page write (16bytes) to the EEPROM -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiData - Data to be written. -// uiOffset - Offset of the EEPROM where data needs to be written to. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemEEPROMWritePage + * + * Description: Performs page write (16bytes) to the EEPROM + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiData - Data to be written. + * uiOffset - Offset of the EEPROM where data needs to be written to. + * Returns: + * OSAL_STATUS_CODE + * + */ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset) { @@ -1595,7 +1606,8 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] /* Clear the Empty/Avail/Full bits. After this it has been confirmed * that the bit was cleared by reading back the register. See NOTE below. * We also clear the Read queues as we do a EEPROM status register read - * later. */ + * later. + */ value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); @@ -1604,7 +1616,8 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); /* We can write back to back 8bits * 16 into the queue and as we have - * checked for the queue to be empty we can write in a burst. */ + * checked for the queue to be empty we can write in a burst. + */ value = uiData[0]; BcmSwapWord(&value); @@ -1625,13 +1638,15 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG * shows that we see 7 for the EEPROM data write. Which means that * queue got full, also space is available as well as the queue is empty. - * This may happen in sequence. */ + * This may happen in sequence. + */ value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset; wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); /* Ideally we should loop here without tries and eventually succeed. * What we are checking if the previous write has completed, and this - * may take time. We should wait till the Empty bit is set. */ + * may take time. We should wait till the Empty bit is set. + */ uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) { @@ -1662,7 +1677,8 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] * proceeding. Bit 0 in the EEPROM Status register should be 0 before * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy * with the previous write. Note also that issuing this read finally - * means the previous write to the EEPROM has completed. */ + * means the previous write to the EEPROM has completed. + */ uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; uiEpromStatus = 0; while (uiRetries != 0) { @@ -1688,21 +1704,21 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] return STATUS_SUCCESS; } /* BeceemEEPROMWritePage */ -//----------------------------------------------------------------------------- -// Procedure: BeceemEEPROMBulkWrite -// -// Description: Performs write to the EEPROM -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Data to be written. -// uiOffset - Offset of the EEPROM where data needs to be written to. -// uiNumBytes - Number of bytes to be written. -// bVerify - read verify flag. -// Returns: -// OSAL_STATUS_CODE -// -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemEEPROMBulkWrite + * + * Description: Performs write to the EEPROM + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Data to be written. + * uiOffset - Offset of the EEPROM where data needs to be written to. + * uiNumBytes - Number of bytes to be written. + * bVerify - read verify flag. + * Returns: + * OSAL_STATUS_CODE + * + */ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, PUCHAR pBuffer, @@ -1711,13 +1727,14 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, BOOLEAN bVerify) { UINT uiBytesToCopy = uiNumBytes; - // UINT uiRdbk = 0; + /* UINT uiRdbk = 0; */ UINT uiData[4] = {0}; UINT uiIndex = 0; UINT uiTempOffset = 0; UINT uiExtraBytes = 0; - // PUINT puiBuffer = (PUINT)pBuffer; - // INT value; + /* PUINT puiBuffer = (PUINT)pBuffer; + * INT value; + */ if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); @@ -1758,9 +1775,9 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, uiOffset += MAX_RW_SIZE; uiBytesToCopy -= MAX_RW_SIZE; } else { - // - // To program non 16byte aligned data, read 16byte and then update. - // + /* + * To program non 16byte aligned data, read 16byte and then update. + */ BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16); memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy); @@ -1774,21 +1791,21 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, return 0; } -//----------------------------------------------------------------------------- -// Procedure: BeceemNVMRead -// -// Description: Reads n number of bytes from NVM. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Buffer to store the data read from NVM -// uiOffset - Offset of NVM from where data should be read -// uiNumBytes - Number of bytes to be read from the NVM. -// -// Returns: -// OSAL_STATUS_SUCCESS - if NVM read is successful. -// - if failed. -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemNVMRead + * + * Description: Reads n number of bytes from NVM. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Buffer to store the data read from NVM + * uiOffset - Offset of NVM from where data should be read + * uiNumBytes - Number of bytes to be read from the NVM. + * + * Returns: + * OSAL_STATUS_SUCCESS - if NVM read is successful. + * - if failed. + */ INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -1833,21 +1850,21 @@ INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, return Status; } -//----------------------------------------------------------------------------- -// Procedure: BeceemNVMWrite -// -// Description: Writes n number of bytes to NVM. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// pBuffer - Buffer contains the data to be written. -// uiOffset - Offset of NVM where data to be written to. -// uiNumBytes - Number of bytes to be written.. -// -// Returns: -// OSAL_STATUS_SUCCESS - if NVM write is successful. -// - if failed. -//----------------------------------------------------------------------------- +/* + * Procedure: BeceemNVMWrite + * + * Description: Writes n number of bytes to NVM. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * pBuffer - Buffer contains the data to be written. + * uiOffset - Offset of NVM where data to be written to. + * uiNumBytes - Number of bytes to be written.. + * + * Returns: + * OSAL_STATUS_SUCCESS - if NVM write is successful. + * - if failed. + */ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -1911,7 +1928,7 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, } else { if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) { ULONG ulBytesTobeSkipped = 0; - PUCHAR pcBuffer = (PUCHAR)pBuffer; // char pointer to take care of odd byte cases. + PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */ uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); uiOffset += (EEPROM_CALPARAM_START - uiOffset); @@ -1928,7 +1945,7 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, } } } - // restore the values. + /* restore the values. */ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); } else if (Adapter->eNVMType == NVM_EEPROM) { Status = BeceemEEPROMBulkWrite(Adapter, @@ -1944,19 +1961,19 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, return Status; } -//----------------------------------------------------------------------------- -// Procedure: BcmUpdateSectorSize -// -// Description: Updates the sector size to FLASH. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// uiSectorSize - sector size -// -// Returns: -// OSAL_STATUS_SUCCESS - if NVM write is successful. -// - if failed. -//----------------------------------------------------------------------------- +/* + * Procedure: BcmUpdateSectorSize + * + * Description: Updates the sector size to FLASH. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * uiSectorSize - sector size + * + * Returns: + * OSAL_STATUS_SUCCESS - if NVM write is successful. + * - if failed. + */ INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) { @@ -1971,9 +1988,9 @@ INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) value = 0; wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - // - // Before updating the sector size in the reserved area, check if already present. - // + /* + * Before updating the sector size in the reserved area, check if already present. + */ BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo)); uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); @@ -2000,24 +2017,24 @@ INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) } Restore: - // restore the values. + /* restore the values. */ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); return Status; } -//----------------------------------------------------------------------------- -// Procedure: BcmGetFlashSectorSize -// -// Description: Finds the sector size of the FLASH. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// UINT - sector size. -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmGetFlashSectorSize + * + * Description: Finds the sector size of the FLASH. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * UINT - sector size. + * + */ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) { @@ -2033,17 +2050,17 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { uiSectorSize = FlashSectorSize; - // - // If the sector size stored in the FLASH makes sense then use it. - // + /* + * If the sector size stored in the FLASH makes sense then use it. + */ if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) { Adapter->uiSectorSize = uiSectorSize; } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { - //No valid size in FLASH, check if Config file has it. + /* No valid size in FLASH, check if Config file has it. */ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; } else { - // Init to Default, if none of the above works. + /* Init to Default, if none of the above works. */ Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; } } else { @@ -2060,24 +2077,25 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe return Adapter->uiSectorSize; } -//----------------------------------------------------------------------------- -// Procedure: BcmInitEEPROMQueues -// -// Description: Initialization of EEPROM queues. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmInitEEPROMQueues + * + * Description: Initialization of EEPROM queues. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * + */ static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) { UINT value = 0; /* CHIP Bug : Clear the Avail bits on the Read queue. The default * value on this register is supposed to be 0x00001102. - * But we get 0x00001122. */ + * But we get 0x00001122. + */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n"); value = EEPROM_READ_DATA_AVAIL; wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); @@ -2096,17 +2114,17 @@ static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) return STATUS_SUCCESS; } /* BcmInitEEPROMQueues() */ -//----------------------------------------------------------------------------- -// Procedure: BcmInitNVM -// -// Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmInitNVM + * + * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * + */ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) { @@ -2126,15 +2144,13 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) return STATUS_SUCCESS; } -/***************************************************************************/ -/*BcmGetNvmSize : set the EEPROM or flash size in Adapter. -* -*Input Parameter: -* Adapter data structure -*Return Value : -* 0. means success; -*/ -/***************************************************************************/ +/* BcmGetNvmSize : set the EEPROM or flash size in Adapter. + * + * Input Parameter: + * Adapter data structure + * Return Value : + * 0. means success; + */ static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) { @@ -2146,61 +2162,61 @@ static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) return 0; } -//----------------------------------------------------------------------------- -// Procedure: BcmValidateNvm -// -// Description: Validates the NVM Type option selected against the device -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmValidateNvm + * + * Description: Validates the NVM Type option selected against the device + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * + */ static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) { - // - // if forcing the FLASH through CFG file, we should ensure device really has a FLASH. - // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. - // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. - // + /* + * if forcing the FLASH through CFG file, we should ensure device really has a FLASH. + * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. + * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. + */ if (Adapter->eNVMType == NVM_FLASH && Adapter->chip_id < 0xBECE3300) Adapter->eNVMType = NVM_AUTODETECT; } -//----------------------------------------------------------------------------- -// Procedure: BcmReadFlashRDID -// -// Description: Reads ID from Serial Flash -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// Flash ID -//----------------------------------------------------------------------------- +/* + * Procedure: BcmReadFlashRDID + * + * Description: Reads ID from Serial Flash + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * Flash ID + */ static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) { ULONG ulRDID = 0; UINT value; - // - // Read ID Instruction. - // + /* + * Read ID Instruction. + */ value = (FLASH_CMD_READ_ID << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - //Delay + /* Delay */ udelay(10); - // - // Read SPI READQ REG. The output will be WWXXYYZZ. - // The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. - // + /* + * Read SPI READQ REG. The output will be WWXXYYZZ. + * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. + */ rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); return (ulRDID >> 8); @@ -2314,7 +2330,7 @@ static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion); - //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); + /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */ psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion); psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage); @@ -2367,11 +2383,11 @@ static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) { - //UINT Index = 0; + /* UINT Index = 0; */ psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion); psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); - //won't convert according to old assumption + /* won't convert according to old assumption */ psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion); psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); @@ -2479,21 +2495,21 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) } } -//----------------------------------------------------------------------------- -// Procedure: BcmGetFlashCSInfo -// -// Description: Reads control structure and gets Cal section addresses. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmGetFlashCSInfo + * + * Description: Reads control structure and gets Cal section addresses. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * + */ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) { - //FLASH_CS_INFO sFlashCsInfo = {0}; + /* FLASH_CS_INFO sFlashCsInfo = {0}; */ #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) UINT value; @@ -2514,13 +2530,14 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); } - // Reading first 8 Bytes to get the Flash Layout - // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) + /* Reading first 8 Bytes to get the Flash Layout + * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) + */ BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8); Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); + /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) { @@ -2590,27 +2607,27 @@ static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart; } /* - Concerns: what if CS sector size does not match with this sector size ??? - what is the indication of AccessBitMap in CS in flash 2.x ???? - */ + * Concerns: what if CS sector size does not match with this sector size ??? + * what is the indication of AccessBitMap in CS in flash 2.x ???? + */ Adapter->ulFlashID = BcmReadFlashRDID(Adapter); Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; return STATUS_SUCCESS; } -//----------------------------------------------------------------------------- -// Procedure: BcmGetNvmType -// -// Description: Finds the type of NVM used. -// -// Arguments: -// Adapter - ptr to Adapter object instance -// -// Returns: -// NVM_TYPE -// -//----------------------------------------------------------------------------- +/* + * Procedure: BcmGetNvmType + * + * Description: Finds the type of NVM used. + * + * Arguments: + * Adapter - ptr to Adapter object instance + * + * Returns: + * NVM_TYPE + * + */ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) { @@ -2620,35 +2637,35 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) if (uiData == BECM) return NVM_EEPROM; - // - // Read control struct and get cal addresses before accessing the flash - // + /* + * Read control struct and get cal addresses before accessing the flash + */ BcmGetFlashCSInfo(Adapter); BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4); if (uiData == BECM) return NVM_FLASH; - // - // even if there is no valid signature on EEPROM/FLASH find out if they really exist. - // if exist select it. - // + /* + * even if there is no valid signature on EEPROM/FLASH find out if they really exist. + * if exist select it. + */ if (BcmGetEEPROMSize(Adapter)) return NVM_EEPROM; - //TBD for Flash. + /* TBD for Flash. */ return NVM_UNKNOWN; } -/** -* BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given -* @Adapter : Drivers Private Data structure -* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL -* -* Return value:- -* On success it return the start offset of the provided section val -* On Failure -returns STATUS_FAILURE -**/ +/* + * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given + * @Adapter : Drivers Private Data structure + * @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL + * + * Return value:- + * On success it return the start offset of the provided section val + * On Failure -returns STATUS_FAILURE + */ INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { @@ -2732,15 +2749,15 @@ INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO return SectStartOffset; } -/** -* BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given -* @Adapter : Drivers Private Data structure -* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL -* -* Return value:- -* On success it return the end offset of the provided section val -* On Failure -returns STATUS_FAILURE -**/ +/* + * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given + * @Adapter : Drivers Private Data structure + * @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL + * + * Return value:- + * On success it return the end offset of the provided section val + * On Failure -returns STATUS_FAILURE + */ INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { @@ -2791,7 +2808,7 @@ INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); break; case CONTROL_SECTION: - //Not Clear So Putting failure. confirm and fix it. + /* Not Clear So Putting failure. confirm and fix it. */ SectEndOffset = STATUS_FAILURE; case ISO_IMAGE1_PART2: if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) @@ -2817,16 +2834,16 @@ INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ } /* -* BcmFlash2xBulkRead:- Read API for Flash Map 2.x . -* @Adapter :Driver Private Data Structure -* @pBuffer : Buffer where data has to be put after reading -* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL -* @uiOffsetWithinSectionVal :- Offset with in provided section -* @uiNumBytes : Number of Bytes for Read -* -* Return value:- -* return true on success and STATUS_FAILURE on fail. -*/ + * BcmFlash2xBulkRead:- Read API for Flash Map 2.x . + * @Adapter :Driver Private Data Structure + * @pBuffer : Buffer where data has to be put after reading + * @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL + * @uiOffsetWithinSectionVal :- Offset with in provided section + * @uiNumBytes : Number of Bytes for Read + * + * Return value:- + * return true on success and STATUS_FAILURE on fail. + */ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -2848,7 +2865,7 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, return -ENODEV; } - //NO_SECTION_VAL means absolute offset is given. + /* NO_SECTION_VAL means absolute offset is given. */ if (eFlash2xSectionVal == NO_SECTION_VAL) SectionStartOffset = 0; else @@ -2862,7 +2879,7 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); - //calculating the absolute offset from FLASH; + /* calculating the absolute offset from FLASH; */ uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset; rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); value = 0; @@ -2878,17 +2895,17 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, } /* -* BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x. -* @Adapter :Driver Private Data Structure -* @pBuffer : Buffer From where data has to taken for writing -* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL -* @uiOffsetWithinSectionVal :- Offset with in provided section -* @uiNumBytes : Number of Bytes for Write -* -* Return value:- -* return true on success and STATUS_FAILURE on fail. -* -*/ + * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x. + * @Adapter :Driver Private Data Structure + * @pBuffer : Buffer From where data has to taken for writing + * @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL + * @uiOffsetWithinSectionVal :- Offset with in provided section + * @uiNumBytes : Number of Bytes for Write + * + * Return value:- + * return true on success and STATUS_FAILURE on fail. + * + */ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, @@ -2911,7 +2928,7 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, return -ENODEV; } - //NO_SECTION_VAL means absolute offset is given. + /* NO_SECTION_VAL means absolute offset is given. */ if (eFlash2xSectVal == NO_SECTION_VAL) FlashSectValStartOffset = 0; else @@ -2925,7 +2942,7 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal)) return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify); - //calculating the absolute offset from FLASH; + /* calculating the absolute offset from FLASH; */ uiOffset = uiOffset + FlashSectValStartOffset; rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); @@ -2943,14 +2960,14 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, return Status; } -/** -* BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR -* @Adapter :-Drivers private Data Structure -* -* Return Value:- -* Return STATUS_SUCESS if get success in setting the right DSD else negaive error code -* -**/ +/* + * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR + * @Adapter :-Drivers private Data Structure + * + * Return Value:- + * Return STATUS_SUCESS if get success in setting the right DSD else negaive error code + * + */ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) { @@ -2968,7 +2985,7 @@ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) if (Adapter->eActiveDSD) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); if (Adapter->eActiveDSD == 0) { - //if No DSD gets Active, Make Active the DSD with WR permission + /* if No DSD gets Active, Make Active the DSD with WR permission */ if (IsSectionWritable(Adapter, DSD2)) { Adapter->eActiveDSD = DSD2; Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; @@ -2984,15 +3001,15 @@ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) return STATUS_SUCCESS; } -/** -* BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue -* @Adapter : Driver private Data Structure -* -* Return Value:- -* Sucsess:- STATUS_SUCESS -* Failure- : negative erro code -* -**/ +/* + * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue + * @Adapter : Driver private Data Structure + * + * Return Value:- + * Sucsess:- STATUS_SUCESS + * Failure- : negative erro code + * + */ static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter) { @@ -3012,16 +3029,16 @@ static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter) return STATUS_SUCCESS; } -/** -* IsOffsetWritable :- it will tell the access permission of the sector having passed offset -* @Adapter : Drivers Private Data Structure -* @uiOffset : Offset provided in the Flash -* -* Return Value:- -* Success:-TRUE , offset is writable -* Failure:-FALSE, offset is RO -* -**/ +/* + * IsOffsetWritable :- it will tell the access permission of the sector having passed offset + * @Adapter : Drivers Private Data Structure + * @uiOffset : Offset provided in the Flash + * + * Return Value:- + * Success:-TRUE , offset is writable + * Failure:-FALSE, offset is RO + * + */ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) { @@ -3032,13 +3049,13 @@ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) uiSectorNum = uiOffset/Adapter->uiSectorSize; - // calculating the word having this Sector Access permission from SectorAccessBitMap Array + /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */ uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16]; - // calculating the bit index inside the word for this sector + /* calculating the bit index inside the word for this sector */ uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16); - // Setting Access permission + /* Setting Access permission */ permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission); permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3; if (permissionBits == SECTOR_READWRITE_PERMISSION) @@ -3066,21 +3083,21 @@ static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) return STATUS_SUCCESS; } -/** -* BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash -* 8bit has been assigned to every section. - bit[0] :Section present or not - bit[1] :section is valid or not - bit[2] : Secton is read only or has write permission too. - bit[3] : Active Section - - bit[7...4] = Reserved . - - @Adapter:-Driver private Data Structure -* -* Return value:- -* Success:- STATUS_SUCESS -* Failure:- negative error code -**/ +/* + * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash + * 8bit has been assigned to every section. + * bit[0] :Section present or not + * bit[1] :section is valid or not + * bit[2] : Secton is read only or has write permission too. + * bit[3] : Active Section - + * bit[7...4] = Reserved . + * + * @Adapter:-Driver private Data Structure + * + * Return value:- + * Success:- STATUS_SUCESS + * Failure:- negative error code + */ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap) { @@ -3090,12 +3107,13 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM BOOLEAN SetActiveDSDDone = FALSE; BOOLEAN SetActiveISODone = FALSE; - // For 1.x map all the section except DSD0 will be shown as not present - // This part will be used by calibration tool to detect the number of DSD present in Flash. + /* For 1.x map all the section except DSD0 will be shown as not present + * This part will be used by calibration tool to detect the number of DSD present in Flash. + */ if (IsFlash2x(Adapter) == FALSE) { psFlash2xBitMap->ISO_IMAGE2 = 0; psFlash2xBitMap->ISO_IMAGE1 = 0; - psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present) + psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */ psFlash2xBitMap->DSD1 = 0; psFlash2xBitMap->DSD2 = 0; psFlash2xBitMap->VSA0 = 0; @@ -3113,17 +3131,17 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM uiHighestPriDSD = getHighestPriDSD(Adapter); uiHighestPriISO = getHighestPriISO(Adapter); - /// - // IS0 IMAGE 2 - /// + /* + * IS0 IMAGE 2 + */ if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID; - // Calculation for extrating the Access permission + /* Calculation for extrating the Access permission */ if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE) psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; @@ -3133,17 +3151,17 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM } } - /// - // IS0 IMAGE 1 - /// + /* + * IS0 IMAGE 1 + */ if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID; - // Calculation for extrating the Access permission + /* Calculation for extrating the Access permission */ if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE) psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; @@ -3153,21 +3171,21 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM } } - /// - // DSD2 - /// + /* + * DSD2 + */ if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; - // Calculation for extrating the Access permission + /* Calculation for extrating the Access permission */ if (IsSectionWritable(Adapter, DSD2) == FALSE) { psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; } else { - //Means section is writable + /* Means section is writable */ if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) { psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT; SetActiveDSDDone = TRUE; @@ -3175,21 +3193,21 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM } } - /// - // DSD 1 - /// + /* + * DSD 1 + */ if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; - // Calculation for extrating the Access permission + /* Calculation for extrating the Access permission */ if (IsSectionWritable(Adapter, DSD1) == FALSE) { psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; } else { - // Means section is writable + /* Means section is writable */ if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) { psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT; SetActiveDSDDone = TRUE; @@ -3197,21 +3215,21 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM } } - /// - //For DSD 0 - // + /* + * For DSD 0 + */ if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) { - //Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER) psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; - // Setting Access permission + /* Setting Access permission */ if (IsSectionWritable(Adapter, DSD0) == FALSE) { psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; } else { - // Means section is writable + /* Means section is writable */ if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) { psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT; SetActiveDSDDone = TRUE; @@ -3219,99 +3237,99 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM } } - /// - // VSA 0 - /// + /* + * VSA 0 + */ if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; - // Setting the Access Bit. Map is not defined hece setting it always valid + /* Setting the Access Bit. Map is not defined hece setting it always valid */ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID; - // Calculation for extrating the Access permission + /* Calculation for extrating the Access permission */ if (IsSectionWritable(Adapter, VSA0) == FALSE) psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO; - // By Default section is Active + /* By Default section is Active */ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT; } - /// - // VSA 1 - /// + /* + * VSA 1 + */ if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; - // Setting the Access Bit. Map is not defined hece setting it always valid + /* Setting the Access Bit. Map is not defined hece setting it always valid */ psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID; - // Checking For Access permission + /* Checking For Access permission */ if (IsSectionWritable(Adapter, VSA1) == FALSE) psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO; - // By Default section is Active + /* By Default section is Active */ psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT; } - /// - // VSA 2 - /// + /* + * VSA 2 + */ if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; - // Setting the Access Bit. Map is not defined hece setting it always valid + /* Setting the Access Bit. Map is not defined hece setting it always valid */ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID; - // Checking For Access permission + /* Checking For Access permission */ if (IsSectionWritable(Adapter, VSA2) == FALSE) psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO; - // By Default section is Active + /* By Default section is Active */ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT; } - /// - // SCSI Section - /// + /* + * SCSI Section + */ if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; - // Setting the Access Bit. Map is not defined hece setting it always valid + /* Setting the Access Bit. Map is not defined hece setting it always valid */ psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID; - // Checking For Access permission + /* Checking For Access permission */ if (IsSectionWritable(Adapter, SCSI) == FALSE) psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO; - // By Default section is Active + /* By Default section is Active */ psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT; } - /// - // Control Section - /// + /* + * Control Section + */ if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) { - // Setting the 0th Bit representing the Section is present or not. + /* Setting the 0th Bit representing the Section is present or not. */ psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); - // Setting the Access Bit. Map is not defined hece setting it always valid + /* Setting the Access Bit. Map is not defined hece setting it always valid */ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID; - // Checking For Access permission + /* Checking For Access permission */ if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE) psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO; - // By Default section is Active + /* By Default section is Active */ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT; } - /// - // For Reserved Sections - /// + /* + * For Reserved Sections + */ psFlash2xBitMap->Reserved0 = 0; psFlash2xBitMap->Reserved0 = 0; psFlash2xBitMap->Reserved0 = 0; @@ -3320,24 +3338,25 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM return STATUS_SUCCESS; } -/** -BcmSetActiveSection :- Set Active section is used to make priority field highest over other - section of same type. - -@Adapater :- Bcm Driver Private Data Structure -@eFlash2xSectionVal :- Flash section val whose priority has to be made highest. - -Return Value:- Make the priorit highest else return erorr code - -**/ +/* + * BcmSetActiveSection :- Set Active section is used to make priority field highest over other + * section of same type. + * + * @Adapater :- Bcm Driver Private Data Structure + * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest. + * + * Return Value:- Make the priorit highest else return erorr code + * + */ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) { unsigned int SectImagePriority = 0; INT Status = STATUS_SUCCESS; - //DSD_HEADER sDSD = {0}; - //ISO_HEADER sISO = {0}; + /* DSD_HEADER sDSD = {0}; + * ISO_HEADER sISO = {0}; + */ INT HighestPriDSD = 0 ; INT HighestPriISO = 0; @@ -3363,9 +3382,10 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) { - // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. - // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO - // by user + /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. + * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO + * by user + */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); SectImagePriority = htonl(0x1); Status = BcmFlash2xBulkWrite(Adapter, @@ -3422,9 +3442,10 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; if (SectImagePriority <= 0) { - // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. - // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD - // by user + /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. + * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD + * by user + */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); SectImagePriority = htonl(0x1); @@ -3488,7 +3509,7 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF case VSA0: case VSA1: case VSA2: - // Has to be decided + /* Has to be decided */ break; default: Status = STATUS_FAILURE; @@ -3499,14 +3520,14 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF return Status; } -/** -BcmCopyISO - Used only for copying the ISO section -@Adapater :- Bcm Driver Private Data Structure -@sCopySectStrut :- Section copy structure - -Return value:- SUCCESS if copies successfully else negative error code - -**/ +/* + * BcmCopyISO - Used only for copying the ISO section + * @Adapater :- Bcm Driver Private Data Structure + * @sCopySectStrut :- Section copy structure + * + * Return value:- SUCCESS if copies successfully else negative error code + * + */ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut) { @@ -3586,7 +3607,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS CorruptISOSig(Adapter, ISO_IMAGE2); while (uiTotalDataToCopy) { if (uiTotalDataToCopy == Adapter->uiSectorSize) { - // Setting for write of first sector. First sector is assumed to be written in last + /* Setting for write of first sector. First sector is assumed to be written in last */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); eISOReadPart = ISO_IMAGE1; uiReadOffsetWithinPart = 0; @@ -3629,7 +3650,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS } if (IsThisHeaderSector == TRUE) { - // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig + /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); for (i = 0; i < MAX_RW_SIZE; i++) @@ -3656,7 +3677,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS MAX_RW_SIZE); IsThisHeaderSector = FALSE; } - //subtracting the written Data + /* subtracting the written Data */ uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; } } @@ -3699,7 +3720,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS while (uiTotalDataToCopy) { if (uiTotalDataToCopy == Adapter->uiSectorSize) { - //Setting for write of first sector. First sector is assumed to be written in last + /* Setting for write of first sector. First sector is assumed to be written in last */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); eISOReadPart = ISO_IMAGE2; uiReadOffsetWithinPart = 0; @@ -3742,7 +3763,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS } if (IsThisHeaderSector == TRUE) { - // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig + /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); for (i = 0; i < MAX_RW_SIZE; i++) @@ -3771,7 +3792,7 @@ INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS IsThisHeaderSector = FALSE; } - // subtracting the written Data + /* subtracting the written Data */ uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; } } @@ -3781,18 +3802,16 @@ out: return Status; } -/** -BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. - It will corrupt the sig, if Section is writable, by making first bytes as zero. -@Adapater :- Bcm Driver Private Data Structure -@eFlash2xSectionVal :- Flash section val which has header - -Return Value :- - Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS - Failure :-Return negative error code - - -**/ +/* + * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. + * It will corrupt the sig, if Section is writable, by making first bytes as zero. + * @Adapater :- Bcm Driver Private Data Structure + * @eFlash2xSectionVal :- Flash section val which has header + * + * Return Value :- + * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS + * Failure :-Return negative error code + */ INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { @@ -3811,24 +3830,23 @@ INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e return Status; } -/** -BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has - header and Write Permission. -@Adapater :- Bcm Driver Private Data Structure -@eFlashSectionVal :- Flash section val which has header - -Return Value :- - Success :- If Section is present and writable write the sig and return STATUS_SUCCESS - Failure :-Return negative error code - -**/ +/* + *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has + * header and Write Permission. + * @Adapater :- Bcm Driver Private Data Structure + * @eFlashSectionVal :- Flash section val which has header + * + * Return Value :- + * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS + * Failure :-Return negative error code + */ INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { UINT uiSignature = 0; UINT uiOffset = 0; - // DSD_HEADER dsdHeader = {0}; + /* DSD_HEADER dsdHeader = {0}; */ if (Adapter->bSigCorrupted == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n"); return STATUS_SUCCESS; @@ -3853,7 +3871,7 @@ INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl } } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) { uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); - // uiOffset = 0; + /* uiOffset = 0; */ uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber); if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig"); @@ -3874,16 +3892,14 @@ INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl return STATUS_SUCCESS; } -/** -validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. - if requested Bytes goes beyond the Requested section, it reports error. -@Adapater :- Bcm Driver Private Data Structure -@psFlash2xReadWrite :-Flash2x Read/write structure pointer - -Return values:-Return TRUE is request is valid else FALSE. - - -**/ +/* + * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. + * if requested Bytes goes beyond the Requested section, it reports error. + * @Adapater :- Bcm Driver Private Data Structure + * @psFlash2xReadWrite :-Flash2x Read/write structure pointer + * + * Return values:-Return TRUE is request is valid else FALSE. + */ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) { @@ -3916,8 +3932,9 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3); } - // since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset - // it should be added in startoffset. so that check done in last of this function can be valued. + /* since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset + * it should be added in startoffset. so that check done in last of this function can be valued. + */ uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset); @@ -3926,7 +3943,7 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); - // Checking the boundary condition + /* Checking the boundary condition */ if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) return TRUE; else { @@ -3935,13 +3952,13 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT } } -/** -IsFlash2x :- check for Flash 2.x -@Adapater :- Bcm Driver Private Data Structure - -Return value:- - return TRUE if flah2.x of hgher version else return false. -**/ +/* + * IsFlash2x :- check for Flash 2.x + * Adapater :- Bcm Driver Private Data Structure + * + * Return value:- + * return TRUE if flah2.x of hgher version else return false. + */ INT IsFlash2x(struct bcm_mini_adapter *Adapter) { @@ -3951,13 +3968,13 @@ INT IsFlash2x(struct bcm_mini_adapter *Adapter) return FALSE; } -/** -GetFlashBaseAddr :- Calculate the Flash Base address -@Adapater :- Bcm Driver Private Data Structure - -Return Value:- - Success :- Base Address of the Flash -**/ +/* + * GetFlashBaseAddr :- Calculate the Flash Base address + * @Adapater :- Bcm Driver Private Data Structure + * + * Return Value:- + * Success :- Base Address of the Flash + */ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) { @@ -3965,9 +3982,9 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) if (Adapter->bDDRInitDone) { /* - For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - In case of Raw Read... use the default value - */ + * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr + * In case of Raw Read... use the default value + */ if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) uiBaseAddr = Adapter->uiFlashBaseAdd; @@ -3975,9 +3992,9 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; } else { /* - For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - In case of Raw Read... use the default value - */ + * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr + * In case of Raw Read... use the default value + */ if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; @@ -3988,22 +4005,20 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) return uiBaseAddr; } -/** -BcmCopySection :- This API is used to copy the One section in another. Both section should - be contiuous and of same size. Hence this Will not be applicabe to copy ISO. - -@Adapater :- Bcm Driver Private Data Structure -@SrcSection :- Source section From where data has to be copied -@DstSection :- Destination section to which data has to be copied -@offset :- Offset from/to where data has to be copied from one section to another. -@numOfBytes :- number of byes that has to be copyed from one section to another at given offset. - in case of numofBytes equal zero complete section will be copied. - -Return Values- - Success : Return STATUS_SUCCESS - Faillure :- return negative error code - -**/ +/* + * BcmCopySection :- This API is used to copy the One section in another. Both section should + * be contiuous and of same size. Hence this Will not be applicabe to copy ISO. + * + * @Adapater :- Bcm Driver Private Data Structure + * @SrcSection :- Source section From where data has to be copied + * @DstSection :- Destination section to which data has to be copied + * @offset :- Offset from/to where data has to be copied from one section to another. + * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset. + * in case of numofBytes equal zero complete section will be copied. + * Return Values- + * Success : Return STATUS_SUCCESS + * Faillure :- return negative error code + */ INT BcmCopySection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL SrcSection, @@ -4031,7 +4046,7 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, return -EINVAL; } - // if offset zero means have to copy complete secton + /* if offset zero means have to copy complete secton */ if (numOfBytes == 0) { numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection) - BcmGetSectionValStartOffset(Adapter, SrcSection); @@ -4099,17 +4114,16 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, return Status; } -/** -SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write -@Adapater :- Bcm Driver Private Data Structure -@pBuff :- Data buffer that has to be written in sector having the header map. -@uiOffset :- Flash offset that has to be written. - -Return value :- - Success :- On success return STATUS_SUCCESS - Faillure :- Return negative error code - -**/ +/* + * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write + * @Adapater :- Bcm Driver Private Data Structure + * @pBuff :- Data buffer that has to be written in sector having the header map. + * @uiOffset :- Flash offset that has to be written. + * + * Return value :- + * Success :- On success return STATUS_SUCCESS + * Faillure :- Return negative error code + */ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset) { @@ -4119,13 +4133,13 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO UINT uiSectAlignAddr = 0; UINT sig = 0; - //making the offset sector aligned + /* making the offset sector aligned */ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) || (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) || (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) { - // offset from the sector boundary having the header map + /* offset from the sector boundary having the header map */ offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; HeaderSizeToProtect = sizeof(DSD_HEADER); bHasHeader = TRUE; @@ -4137,17 +4151,17 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO HeaderSizeToProtect = sizeof(ISO_HEADER); bHasHeader = TRUE; } - // If Header is present overwrite passed buffer with this + /* If Header is present overwrite passed buffer with this */ if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) { pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL); if (pTempBuff == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); return -ENOMEM; } - // Read header + /* Read header */ BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect); BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect); - //Replace Buffer content with Header + /* Replace Buffer content with Header */ memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect); kfree(pTempBuff); @@ -4169,13 +4183,13 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO return STATUS_SUCCESS; } -/** -BcmDoChipSelect : This will selcet the appropriate chip for writing. -@Adapater :- Bcm Driver Private Data Structure - -OutPut:- - Select the Appropriate chip and retrn status Success -**/ +/* + * BcmDoChipSelect : This will selcet the appropriate chip for writing. + * @Adapater :- Bcm Driver Private Data Structure + * + * OutPut:- + * Select the Appropriate chip and retrn status Success + */ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) { UINT FlashConfig = 0; @@ -4185,28 +4199,28 @@ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) ChipNum = offset / FLASH_PART_SIZE; - // - // Chip Select mapping to enable flash0. - // To select flash 0, we have to OR with (0<<12). - // ORing 0 will have no impact so not doing that part. - // In future if Chip select value changes from 0 to non zero, - // That needs be taken care with backward comaptibility. No worries for now. - // + /* + * Chip Select mapping to enable flash0. + * To select flash 0, we have to OR with (0<<12). + * ORing 0 will have no impact so not doing that part. + * In future if Chip select value changes from 0 to non zero, + * That needs be taken care with backward comaptibility. No worries for now. + */ /* - SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured - if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) - Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from - power down modes (Idle mode/shutdown mode), the values in the register will be different. - */ + * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured + * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) + * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from + * power down modes (Idle mode/shutdown mode), the values in the register will be different. + */ if (Adapter->SelectedChip == ChipNum) return STATUS_SUCCESS; - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); + /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */ Adapter->SelectedChip = ChipNum; - // bit[13..12] will select the appropriate chip + /* bit[13..12] will select the appropriate chip */ rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); { @@ -4229,17 +4243,17 @@ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) } } /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, - nothing to do... can return immediately. - ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. - Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. - These values are not written by host other than during CHIP_SELECT. - */ + * nothing to do... can return immediately. + * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. + * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. + * These values are not written by host other than during CHIP_SELECT. + */ if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) return STATUS_SUCCESS; - // clearing the bit[13..12] + /* clearing the bit[13..12] */ FlashConfig &= 0xFFFFCFFF; - FlashConfig = (FlashConfig | (PartNum< Date: Wed, 6 Jun 2012 22:54:30 -0400 Subject: [PATCH 1276/6849] Staging: bcm: Fix ERROR: return is not a function, parentheses are not required. This patch fixes the following error reported by checkpatch.pl in nvm.c: "ERROR: return is not a function, parentheses are not required". Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index cfc0458b6e0a..02a090461c76 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -472,7 +472,7 @@ static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) { if (IsFlash2x(Adapter)) - return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); + return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER); else return 32 * 1024; } @@ -2219,7 +2219,7 @@ static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) */ rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); - return (ulRDID >> 8); + return ulRDID >> 8; } INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) -- GitLab From 6788d7dab6a5b126604ae0f40cfb13400fdf37f6 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 6 Jun 2012 22:54:31 -0400 Subject: [PATCH 1277/6849] Staging: bcm: Use udelay instead of msleep for delays in nvm.c This patch uses udelay instead of msleep for delays because msleep can sleep up to 20ms for any value less than 20. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 02a090461c76..c8a0a9096a0e 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -102,7 +102,7 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) return uiData; } if (!(dwRetries%RETRIES_PER_DELAY)) - msleep(1); + udelay(1000); uiStatus = 0 ; } return uiData; @@ -195,7 +195,7 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, } if (!(dwRetries%RETRIES_PER_DELAY)) - msleep(1); + udelay(1000); } for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) { @@ -577,7 +577,7 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms * won't hamper performance in any case. */ - msleep(10); + udelay(10000); } while ((uiStatus & 0x1) && (iRetries < 400)); if (uiStatus & 0x1) { @@ -654,7 +654,7 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, } iRetries--; if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); + udelay(1000); } while ((uiStatus & 0x1) && (iRetries > 0)); @@ -734,7 +734,7 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, * Hence current implementation cycle will intoduce no delay in current path */ if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); + udelay(1000); } while ((uiStatus & 0x1) && (iRetries > 0)); if (uiStatus & 0x1) { @@ -811,7 +811,7 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, iRetries--; if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); + udelay(1000); } while ((uiStatus & 0x1) && (iRetries > 0)); @@ -886,7 +886,7 @@ static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, * Hence current implementation cycle will intoduce no delay in current path */ if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - msleep(1); + udelay(1000); } while ((uiStatus & 0x1) && (iRetries > 0)); @@ -1657,7 +1657,7 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] } if (!(uiRetries%RETRIES_PER_DELAY)) - msleep(1); + udelay(1000); uiStatus = 0; rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); @@ -1698,7 +1698,7 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] } uiEpromStatus = 0; if (!(uiRetries%RETRIES_PER_DELAY)) - msleep(1); + udelay(1000); } return STATUS_SUCCESS; -- GitLab From 7dd80eb925a5aac4ebe8b1abec20802e91f60c2e Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 7 Jun 2012 23:52:42 -0400 Subject: [PATCH 1278/6849] Staging: bcm: Return -ENOMEM instead of -1 when memory not acquired in nmv.c This patch changes the return statement on two conditions where memory could not be acquired. It returns -ENOMEM instead of -1. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index c8a0a9096a0e..ed2316570d30 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -1378,7 +1378,7 @@ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) INT Status = 0; if (pBuff == NULL) - return -1; + return -ENOMEM; if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { kfree(pBuff); @@ -1462,7 +1462,7 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) pBuff = kmalloc(uiEepromSize, GFP_KERNEL); if (pBuff == NULL) - return -1; + return -ENOMEM; if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) { kfree(pBuff); -- GitLab From dd13c86b0dae86efdde98119ffd7348e80719ade Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Wed, 6 Jun 2012 23:01:26 -0700 Subject: [PATCH 1279/6849] staging: gdm72xx: Fix spinlock recursion on gdm_usb_send_complete This patch fixes a spinlock recursion bug on several call sites of gdm_usb_send_complete by not calling spin_lock_irqsave on urb->context->tx_cxt->lock when the lock has already been acquired. Signed-off-by: Ben Chan Cc: Sage Ahn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_usb.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index e201b341e52f..646e0ace91ec 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -270,7 +270,7 @@ static void release_usb(struct usbwm_dev *udev) } } -static void gdm_usb_send_complete(struct urb *urb) +static void gdm_usb_send_complete_impl(struct urb *urb, bool need_lock) { struct usb_tx *t = urb->context; struct tx_cxt *tx = t->tx_cxt; @@ -282,7 +282,8 @@ static void gdm_usb_send_complete(struct urb *urb) if (urb->status == -ECONNRESET) return; - spin_lock_irqsave(&tx->lock, flags); + if (need_lock) + spin_lock_irqsave(&tx->lock, flags); if (t->callback) t->callback(t->cb_data); @@ -296,7 +297,18 @@ static void gdm_usb_send_complete(struct urb *urb) else free_tx_struct(t); - spin_unlock_irqrestore(&tx->lock, flags); + if (need_lock) + spin_unlock_irqrestore(&tx->lock, flags); +} + +static void gdm_usb_send_complete(struct urb *urb) +{ + gdm_usb_send_complete_impl(urb, true); +} + +static void gdm_usb_send_complete_no_lock(struct urb *urb) +{ + gdm_usb_send_complete_impl(urb, false); } static int gdm_usb_send(void *priv_dev, void *data, int len, @@ -411,7 +423,7 @@ out: send_fail: t->callback = NULL; - gdm_usb_send_complete(t->urb); + gdm_usb_send_complete_no_lock(t->urb); spin_unlock_irqrestore(&tx->lock, flags); return ret; } @@ -540,7 +552,7 @@ static void do_pm_control(struct work_struct *work) if (ret) { t->callback = NULL; - gdm_usb_send_complete(t->urb); + gdm_usb_send_complete_no_lock(t->urb); } } } @@ -742,7 +754,7 @@ static int k_mode_thread(void *arg) if (ret) { t->callback = NULL; - gdm_usb_send_complete(t->urb); + gdm_usb_send_complete_no_lock(t->urb); } } -- GitLab From 60ebf60b614cafd0c9f58e72cae151edf5e8bd94 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 9 Jun 2012 00:13:57 +0900 Subject: [PATCH 1280/6849] staging: Fix typo in winbond Correct spelling typo in winbond/mto.c and mds_s.h Signed-off-by: Masanari Iida Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds_s.h | 2 +- drivers/staging/winbond/mto.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h index 07d835b3b706..2972d66c9436 100644 --- a/drivers/staging/winbond/mds_s.h +++ b/drivers/staging/winbond/mds_s.h @@ -40,7 +40,7 @@ enum { /* * ================================================================ - * Configration default value + * Configuration default value * ================================================================ */ #define DEFAULT_MULTICASTLISTMAX 32 /* standard */ diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 5250217156a7..1b52ebd4b011 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -33,7 +33,7 @@ u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] = { /* * Declare data rate table: - * The following table will be changed at anytime if the opration rate + * The following table will be changed at anytime if the operation rate * supported by AP don't match the table */ static u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] = { -- GitLab From 0cf5755f00f555d7cef4a7be0ae5aac5e4bdf07d Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 9 Jun 2012 00:19:17 +0900 Subject: [PATCH 1281/6849] staging: rts5139: Fix typo in rts5139 Correct spelling typo in rts5139/rts51x_chip.h, rts51x_scsi.h Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5139/rts51x_chip.h | 2 +- drivers/staging/rts5139/rts51x_scsi.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 6d395b6533a8..64257caf2f30 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -204,7 +204,7 @@ struct trace_msg_t { /*---- error code ----*/ #define CUR_ERR 0x70 /* current error */ -/*---- sense key Infomation ----*/ +/*---- sense key Information ----*/ #define SKSV 0x80 #define CDB_ILLEGAL 0x40 diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h index 060d2c2e77ec..9042bc98a9a0 100644 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -73,7 +73,7 @@ #define GET_BATCHRSP 0x44 #ifdef SUPPORT_CPRM -/* SD Pass Through Command Extention */ +/* SD Pass Through Command Extension */ #define SD_PASS_THRU_MODE 0xD0 #define SD_EXECUTE_NO_DATA 0xD1 #define SD_EXECUTE_READ 0xD2 -- GitLab From 6fe864409b54f60ed36804752acfd148da459e53 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Jun 2012 20:05:16 +0300 Subject: [PATCH 1282/6849] Staging: rtl8187se, rtl8192e: fix '&' vs '|' bugs The original code is equivalent to: wrqu->retry.flags = 0x1000 & 0x0002; so it just sets .flags to zero. We should be ORing the values together like r8192_wx_get_retry() does in drivers/staging/rtl8192u/r8192U_wx.c. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_wx.c | 4 ++-- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 46ee6f47f525..52f63d75d248 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c @@ -615,10 +615,10 @@ static int r8180_wx_get_retry(struct net_device *dev, return -EINVAL; if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrqu->retry.value = priv->retry_rts; } else { - wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; wrqu->retry.value = priv->retry_data; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 778d7baf8e08..6202358c2984 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -919,10 +919,10 @@ static int r8192_wx_get_retry(struct net_device *dev, return -EINVAL; if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrqu->retry.value = priv->retry_rts; } else { - wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; wrqu->retry.value = priv->retry_data; } return 0; -- GitLab From e73f843a3235a19de38359c91586e9eadef12238 Mon Sep 17 00:00:00 2001 From: Suresh Jayaraman Date: Tue, 12 Jun 2012 07:15:50 +0530 Subject: [PATCH 1283/6849] cifs: fix parsing of password mount option The double delimiter check that allows a comma in the password parsing code is unconditional. We set "tmp_end" to the end of the string and we continue to check for double delimiter. In the case where the password doesn't contain a comma we end up setting tmp_end to NULL and eventually setting "options" to "end". This results in the premature termination of the options string and hence the values of UNCip and UNC are being set to NULL. This results in mount failure with "Connecting to DFS root not implemented yet" error. This error is usually not noticable as we have password as the last option in the superblock mountdata. But when we call expand_dfs_referral() from cifs_mount() and try to compose mount options for the submount, the resulting mountdata will be of the form ",ver=1,user=foo,pass=bar,ip=x.x.x.x,unc=\\server\share" and hence results in the above error. This bug has been seen with older NAS servers running Samba 3.0.24. Fix this by moving the double delimiter check inside the conditional loop. Changes since -v1 - removed the wrong strlen() micro optimization. Signed-off-by: Suresh Jayaraman Acked-by: Sachin Prabhu Cc: stable@vger.kernel.org [3.1+] Signed-off-by: Steve French --- fs/cifs/connect.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 78db68a5cf44..5b3840725d01 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1653,24 +1653,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, * If yes, we have encountered a double deliminator * reset the NULL character to the deliminator */ - if (tmp_end < end && tmp_end[1] == delim) + if (tmp_end < end && tmp_end[1] == delim) { tmp_end[0] = delim; - /* Keep iterating until we get to a single deliminator - * OR the end - */ - while ((tmp_end = strchr(tmp_end, delim)) != NULL && - (tmp_end[1] == delim)) { - tmp_end = (char *) &tmp_end[2]; - } + /* Keep iterating until we get to a single + * deliminator OR the end + */ + while ((tmp_end = strchr(tmp_end, delim)) + != NULL && (tmp_end[1] == delim)) { + tmp_end = (char *) &tmp_end[2]; + } - /* Reset var options to point to next element */ - if (tmp_end) { - tmp_end[0] = '\0'; - options = (char *) &tmp_end[1]; - } else - /* Reached the end of the mount option string */ - options = end; + /* Reset var options to point to next element */ + if (tmp_end) { + tmp_end[0] = '\0'; + options = (char *) &tmp_end[1]; + } else + /* Reached the end of the mount option + * string */ + options = end; + } /* Now build new password string */ temp_len = strlen(value); -- GitLab From 67c4e9f46b5241ff777ced09e29048363de8703f Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Sun, 10 Jun 2012 13:12:22 +0200 Subject: [PATCH 1284/6849] staging: sm7xx: code improvement This patch simplifies code. It erases redundant code under little endian compilations. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xx/smtcfb.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 746c4cd5d30e..2c172d6cd65f 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -724,16 +724,13 @@ static void smtc_unmap_mmio(struct smtcfb_info *sfb) static int smtc_map_smem(struct smtcfb_info *sfb, struct pci_dev *pdev, u_long smem_len) { - if (sfb->fb.var.bits_per_pixel == 32) { + + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); + #ifdef __BIG_ENDIAN - sfb->fb.fix.smem_start = pci_resource_start(pdev, 0) - + 0x800000; -#else - sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); + if (sfb->fb.var.bits_per_pixel == 32) + sfb->fb.fix.smem_start += 0x800000; #endif - } else { - sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); - } sfb->fb.fix.smem_len = smem_len; -- GitLab From 0beb30d365b0fb36c9cac7b7dbe980e882378f23 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Sun, 10 Jun 2012 13:12:23 +0200 Subject: [PATCH 1285/6849] staging: sm7xx: update comments and clarify supported chips This patch updates/adds comments in order to clarify devices and Lynx families supported for this driver. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xx/Kconfig | 9 +++++++-- drivers/staging/sm7xx/smtcfb.c | 10 +++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig index 315102c7fed1..323964f5b1a9 100644 --- a/drivers/staging/sm7xx/Kconfig +++ b/drivers/staging/sm7xx/Kconfig @@ -1,8 +1,13 @@ config FB_SM7XX - tristate "Silicon Motion SM7XX Frame Buffer Support" + tristate "Silicon Motion SM7XX framebuffer support" depends on FB select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help - Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. + Frame buffer driver for the Silicon Motion SM710, SM712, SM721 + and SM722 chips. + + This driver is also available as a module. The module will be + called sm7xx. If you want to compile it as a module, say M + here and read . diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 2c172d6cd65f..e7028a312ce1 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -15,6 +15,7 @@ * License. See the file COPYING in the main directory of this archive for * more details. * + * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips */ #include @@ -758,7 +759,7 @@ static void smtc_unmap_smem(struct smtcfb_info *sfb) } /* - * We need to wake up the LynxEM+, and make sure its in linear memory mode. + * We need to wake up the device and make sure its in linear memory mode. */ static inline void sm7xx_init_hw(void) { @@ -963,7 +964,11 @@ failed_free: return err; } - +/* + * 0x710 (LynxEM) + * 0x712 (LynxEM+) + * 0x720 (Lynx3DM, Lynx3DM+) + */ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { { PCI_DEVICE(0x126f, 0x710), }, { PCI_DEVICE(0x126f, 0x712), }, @@ -971,7 +976,6 @@ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { {0,} }; - static void __devexit smtcfb_pci_remove(struct pci_dev *pdev) { struct smtcfb_info *sfb; -- GitLab From 925aa6600cee015b694cb5fe2a9c667e0d9a68c6 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Sun, 10 Jun 2012 13:12:24 +0200 Subject: [PATCH 1286/6849] staging: sm7xxfb: sm7xx becomes sm7xxfb Rename sm7xx driver to sm7xxfb. Fix Kconfig and Makefile to fit the new change. Changes are coherent with the rest of stable framebuffer drivers. TODO updated. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 +- drivers/staging/Makefile | 2 +- drivers/staging/sm7xx/Makefile | 3 --- drivers/staging/{sm7xx => sm7xxfb}/Kconfig | 2 +- drivers/staging/sm7xxfb/Makefile | 1 + drivers/staging/{sm7xx => sm7xxfb}/TODO | 2 +- drivers/staging/{sm7xx/smtcfb.h => sm7xxfb/sm7xx.h} | 0 drivers/staging/{sm7xx/smtcfb.c => sm7xxfb/sm7xxfb.c} | 2 +- 8 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 drivers/staging/sm7xx/Makefile rename drivers/staging/{sm7xx => sm7xxfb}/Kconfig (85%) create mode 100644 drivers/staging/sm7xxfb/Makefile rename drivers/staging/{sm7xx => sm7xxfb}/TODO (76%) rename drivers/staging/{sm7xx/smtcfb.h => sm7xxfb/sm7xx.h} (100%) rename drivers/staging/{sm7xx/smtcfb.c => sm7xxfb/sm7xxfb.c} (99%) diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 05e33c700750..38f1fb08eaef 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -84,7 +84,7 @@ source "drivers/staging/wlags49_h2/Kconfig" source "drivers/staging/wlags49_h25/Kconfig" -source "drivers/staging/sm7xx/Kconfig" +source "drivers/staging/sm7xxfb/Kconfig" source "drivers/staging/crystalhd/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a987b3ad380b..e0c4c2444fed 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_ZSMALLOC) += zsmalloc/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ -obj-$(CONFIG_FB_SM7XX) += sm7xx/ +obj-$(CONFIG_FB_SM7XX) += sm7xxfb/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_FB_XGI) += xgifb/ diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile deleted file mode 100644 index f43cb9106305..000000000000 --- a/drivers/staging/sm7xx/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_FB_SM7XX) += sm7xx.o - -sm7xx-y := smtcfb.o diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xxfb/Kconfig similarity index 85% rename from drivers/staging/sm7xx/Kconfig rename to drivers/staging/sm7xxfb/Kconfig index 323964f5b1a9..d5013f8a865b 100644 --- a/drivers/staging/sm7xx/Kconfig +++ b/drivers/staging/sm7xxfb/Kconfig @@ -9,5 +9,5 @@ config FB_SM7XX and SM722 chips. This driver is also available as a module. The module will be - called sm7xx. If you want to compile it as a module, say M + called sm7xxfb. If you want to compile it as a module, say M here and read . diff --git a/drivers/staging/sm7xxfb/Makefile b/drivers/staging/sm7xxfb/Makefile new file mode 100644 index 000000000000..48f471cf9f36 --- /dev/null +++ b/drivers/staging/sm7xxfb/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_FB_SM7XX) += sm7xxfb.o diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xxfb/TODO similarity index 76% rename from drivers/staging/sm7xx/TODO rename to drivers/staging/sm7xxfb/TODO index 7304021368c3..1fcead591c16 100644 --- a/drivers/staging/sm7xx/TODO +++ b/drivers/staging/sm7xxfb/TODO @@ -3,7 +3,7 @@ TODO: - 2D acceleration support - use kernel coding style - refine the code and remove unused code -- move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c +- move it to drivers/video/sm7xxfb.c Please send any patches to Greg Kroah-Hartman and Teddy Wang . diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xxfb/sm7xx.h similarity index 100% rename from drivers/staging/sm7xx/smtcfb.h rename to drivers/staging/sm7xxfb/sm7xx.h diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c similarity index 99% rename from drivers/staging/sm7xx/smtcfb.c rename to drivers/staging/sm7xxfb/sm7xxfb.c index e7028a312ce1..21dab346253a 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -32,7 +32,7 @@ #include #endif -#include "smtcfb.h" +#include "sm7xx.h" struct screen_info smtc_screen_info; -- GitLab From 14e70bfdc6dd4d6b88f3477f3966df7405e78a69 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Mon, 11 Jun 2012 08:56:36 +0200 Subject: [PATCH 1287/6849] Staging: ipack: remove pr_fmt definition. As there is no pr_* function used here, pr_fmt is not needed. Signed-off-by: Samuel Iglesias Gonsalvez Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index a1448e68fd7a..c1cd97a4d9ce 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -9,8 +9,6 @@ * Software Foundation; version 2 of the License. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include -- GitLab From 4bce6b897ed6812e000c034968c8c250de40da9b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 11 Jun 2012 11:11:59 +0200 Subject: [PATCH 1288/6849] staging: usb: gadget: Configurable Composite Gadget depends on BLOCK Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ccg/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig index ff05e52392bf..1f00d701da25 100644 --- a/drivers/staging/ccg/Kconfig +++ b/drivers/staging/ccg/Kconfig @@ -2,7 +2,7 @@ if USB_GADGET config USB_G_CCG tristate "Configurable Composite Gadget (STAGING)" - depends on STAGING && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM + depends on STAGING && BLOCK && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM help The Configurable Composite Gadget supports multiple USB functions: acm, mass storage, rndis and FunctionFS. -- GitLab From 383b7fc2dca769d98ca373306e105987e8f143b3 Mon Sep 17 00:00:00 2001 From: William Blair Date: Sun, 10 Jun 2012 15:10:33 -0400 Subject: [PATCH 1289/6849] Staging: keucr: init: fixed a brace coding style issue Fixed a coding style issue. Signed-off-by: William Blair Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index 071bdc238786..231611dc0f74 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -30,9 +30,8 @@ int ENE_InitMedia(struct us_data *us) if (MiscReg03 & 0x02) { if (!us->SM_Status.Ready && !us->MS_Status.Ready) { result = ENE_SMInit(us); - if (result != USB_STOR_XFER_GOOD) { + if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - } } } -- GitLab From 7a2ea600fcda3cfa04033cf3077116cf2522aa9c Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Tue, 12 Jun 2012 11:37:46 +0200 Subject: [PATCH 1290/6849] Staging: ipack: delete sysfs from to-do list. As we have already got rid of sysfs files in the tpci200 driver, it is needed to delete that mention in the TODO file. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/TODO | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO index 3a45a53afd88..0f8bf2044843 100644 --- a/drivers/staging/ipack/TODO +++ b/drivers/staging/ipack/TODO @@ -15,10 +15,6 @@ TODO TPCI-200 -------- -* It receives the name of the mezzanine plugged in each slot by SYSFS. - No autodetection supported yet, because the mezzanine driver could not be - loaded at the time that the tpci200 driver loads. - * It has a linked list with the tpci200 devices it is managing. Get rid of it and use driver_for_each_device() instead. -- GitLab From 1b8487368bb0acedf23e226974b63aaaf2bfddbd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 12 Jun 2012 11:10:50 -0700 Subject: [PATCH 1291/6849] Revert "staging: usbip: bugfix for stack corruption on 64-bit architectures" This reverts commit 08224262adefb5e6460888b2490a96e1bc28aef5 as it's just not right. Reported-by: Ben Hutchings Cc: stable Cc: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 117a7ad9fdb1..f708cbaee16b 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -205,7 +205,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) int retval = 0; /* the enough buffer is allocated according to USB_MAXCHILDREN */ - u32 *event_bits = (unsigned long *) buf; + unsigned long *event_bits = (unsigned long *) buf; int rhport; int changed = 0; -- GitLab From 33735a94afdfb39c550b952a40f77c60afdddfa5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Jun 2012 15:09:21 +0200 Subject: [PATCH 1292/6849] staging:iio:ad7298: Fix linker error due to missing IIO kfifo buffer The ad7298 drivers buffer implementation uses the IIO kfifo buffer, so it needs to select IIO_KFIFO_BUF. Otherwise (if no other driver selects the symbol) the following linker error will occur: drivers/built-in.o: In function `ad7298_register_ring_funcs_and_init': (.text+0x245cf2): undefined reference to `iio_kfifo_allocate' drivers/built-in.o: In function `ad7298_register_ring_funcs_and_init': (.text+0x245d7d): undefined reference to `iio_kfifo_free' drivers/built-in.o: In function `ad7298_ring_cleanup': (.text+0x245dcd): undefined reference to `iio_kfifo_free' Signed-off-by: Lars-Peter Clausen Reported-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 2490dd25093b..8f1b3af02f29 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -13,6 +13,7 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI + select IIO_KFIFO_BUF if IIO_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. -- GitLab From e34995148a2a305106c4f746fb76da23488c46c7 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 11 Jun 2012 07:48:46 -0700 Subject: [PATCH 1293/6849] staging "sep" Fix typos found while reading. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_crypto.c | 18 ++++++------- drivers/staging/sep/sep_driver_api.h | 8 +++--- drivers/staging/sep/sep_driver_config.h | 4 +-- drivers/staging/sep/sep_main.c | 36 ++++++++++++------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c index 9fd9da84428e..045493b61995 100644 --- a/drivers/staging/sep/sep_crypto.c +++ b/drivers/staging/sep/sep_crypto.c @@ -807,7 +807,7 @@ end_function: * @size: size of parameter to copy (in bytes) * @max_size: size to move up offset; SEP mesg is in word sizes * @msg_offset: pointer to current offset (is updated) - * @byte_array: flag ti indicate wheter endian must be changed + * @byte_array: flag ti indicate whether endian must be changed * Copies data into the message area from caller */ static void sep_write_msg(struct this_task_ctx *ta_ctx, void *in_addr, @@ -855,7 +855,7 @@ static void sep_make_header(struct this_task_ctx *ta_ctx, u32 *msg_offset, * @size: size of parameter to copy (in bytes) * @max_size: size to move up offset; SEP mesg is in word sizes * @msg_offset: pointer to current offset (is updated) - * @byte_array: flag ti indicate wheter endian must be changed + * @byte_array: flag ti indicate whether endian must be changed * Copies data out of the message area to caller */ static void sep_read_msg(struct this_task_ctx *ta_ctx, void *in_addr, @@ -990,7 +990,7 @@ static void sep_clear_out(struct this_task_ctx *ta_ctx) /** * The following unlocks the sep and makes it available * to any other application - * First, null out crypto entries in sep before relesing it + * First, null out crypto entries in sep before releasing it */ ta_ctx->sep_used->current_hash_req = NULL; ta_ctx->sep_used->current_cypher_req = NULL; @@ -1001,7 +1001,7 @@ static void sep_clear_out(struct this_task_ctx *ta_ctx) ta_ctx->call_status.status = 0; - /* Remove anything confidentail */ + /* Remove anything confidential */ memset(ta_ctx->sep_used->shared_addr, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); @@ -1207,7 +1207,7 @@ static int sep_crypto_block_data(struct ablkcipher_request *req) req->nbytes, ta_ctx->walk.blocksize, &new_sg, 1); if (int_error < 0) { - dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page eerror\n"); + dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page error\n"); return -ENOMEM; } else if (int_error == 1) { ta_ctx->src_sg = new_sg; @@ -1870,7 +1870,7 @@ static u32 hash_update_post_op(struct sep_device *sep) sizeof(struct sep_hash_private_context)); /** - * Following is only for finup; if we just completd the + * Following is only for finup; if we just completed the * data portion of finup, we now need to kick off the * finish portion of finup. */ @@ -2011,7 +2011,7 @@ static u32 hash_digest_post_op(struct sep_device *sep) } /** - * The sep_finish function is the function that is schedule (via tasket) + * The sep_finish function is the function that is scheduled (via tasklet) * by the interrupt service routine when the SEP sends and interrupt * This is only called by the interrupt handler as a tasklet. */ @@ -2249,7 +2249,7 @@ static void sep_hash_update(void *data) head_len = (block_size - int_ctx->prev_update_bytes) % block_size; tail_len = (req->nbytes - head_len) % block_size; - /* Make sure all pages are even block */ + /* Make sure all pages are an even block */ int_error = sep_oddball_pages(ta_ctx->sep_used, req->src, req->nbytes, block_size, &new_sg, 1); @@ -2482,7 +2482,7 @@ static void sep_hash_digest(void *data) dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size); dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); - /* Make sure all pages are even block */ + /* Make sure all pages are an even block */ int_error = sep_oddball_pages(ta_ctx->sep_used, req->src, req->nbytes, block_size, &new_sg, 1); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index 8b797d5388bb..7ee1c3bf17d7 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -91,7 +91,7 @@ struct sep_dcblock { }; /* - command structure for building dcb block (currently for ext app only + command structure for building dcb block (currently for ext app only) */ struct build_dcb_struct { /* address value of the data in */ @@ -234,7 +234,7 @@ struct sep_dma_context { u32 dmatables_len; /* size of input data */ u32 input_data_len; - /* secure dma use (for imr memory restriced area in output */ + /* secure dma use (for imr memory restricted area in output) */ bool secure_dma; struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; /* Scatter gather for kernel crypto */ @@ -347,10 +347,10 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, /** * sep_free_dma_table_data_handler - free DMA table - * @sep: pointere to struct sep_device + * @sep: pointer to struct sep_device * @dma_ctx: dma context * - * Handles the request to free DMA table for synchronic actions + * Handles the request to free DMA table for synchronic actions */ int sep_free_dma_table_data_handler(struct sep_device *sep, struct sep_dma_context **dma_ctx); diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index 9d9fc7c94a6e..7d7c7ab610b7 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -43,7 +43,7 @@ #define SEP_DRIVER_POLLING_MODE 0 /* flag which defines if the shared area address should be - reconfiged (send to SEP anew) during init of the driver */ + reconfigured (send to SEP anew) during init of the driver */ #define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0 /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ @@ -166,7 +166,7 @@ held by the process (struct file) */ (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \ SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES) -/* synhronic dma tables area offset */ +/* synchronic dma tables area offset */ #define SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES \ (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \ SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index ab351289d893..270fcb811b80 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -94,7 +94,7 @@ #endif /** - * Currenlty, there is only one SEP device per platform; + * Currently, there is only one SEP device per platform; * In event platforms in the future have more than one SEP * device, this will be a linked list */ @@ -106,7 +106,7 @@ struct sep_device *sep_dev; * @sep: SEP device * @sep_queue_info: pointer to status queue * - * This function will removes information about transaction from the queue. + * This function will remove information about transaction from the queue. */ void sep_queue_status_remove(struct sep_device *sep, struct sep_queue_info **queue_elem) @@ -294,7 +294,7 @@ int sep_wait_transaction(struct sep_device *sep) end_function_setpid: /* * The pid_doing_transaction indicates that this process - * now owns the facilities to performa a transaction with + * now owns the facilities to perform a transaction with * the SEP. While this process is performing a transaction, * no other process who has the SEP device open can perform * any transactions. This method allows more than one process @@ -447,10 +447,10 @@ static int sep_open(struct inode *inode, struct file *filp) /** * sep_free_dma_table_data_handler - free DMA table - * @sep: pointere to struct sep_device + * @sep: pointer to struct sep_device * @dma_ctx: dma context * - * Handles the request to free DMA table for synchronic actions + * Handles the request to free DMA table for synchronic actions */ int sep_free_dma_table_data_handler(struct sep_device *sep, struct sep_dma_context **dma_ctx) @@ -540,7 +540,7 @@ int sep_free_dma_table_data_handler(struct sep_device *sep, * don't have a page array; the page array is generated * only in the lock_user_pages, which is not called * for kernel crypto, which is what the sg (scatter gather - * is used for exclusively + * is used for exclusively) */ if (dma->src_sg) { dma_unmap_sg(&sep->pdev->dev, dma->src_sg, @@ -1227,7 +1227,7 @@ static int sep_lock_user_pages(struct sep_device *sep, /* Map array */ struct sep_dma_map *map_array; - /* Set start and end pages and num pages */ + /* Set start and end pages and num pages */ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; start_page = app_virt_addr >> PAGE_SHIFT; num_pages = end_page - start_page + 1; @@ -1431,7 +1431,7 @@ static int sep_lli_table_secure_dma(struct sep_device *sep, /* Array of lli */ struct sep_lli_entry *lli_array; - /* Set start and end pages and num pages */ + /* Set start and end pages and num pages */ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; start_page = app_virt_addr >> PAGE_SHIFT; num_pages = end_page - start_page + 1; @@ -1602,7 +1602,7 @@ end_function: * @num_table_entries_ptr: pointer to number of tables * @table_data_size: total data size * - * Builds ant lli table from the lli_array according to + * Builds an lli table from the lli_array according to * the given size of data */ static void sep_build_lli_table(struct sep_device *sep, @@ -1701,7 +1701,7 @@ static void sep_build_lli_table(struct sep_device *sep, * @virt_address: virtual address to convert * * This functions returns the physical address inside shared area according - * to the virtual address. It can be either on the externa RAM device + * to the virtual address. It can be either on the external RAM device * (ioremapped), or on the system RAM * This implementation is for the external RAM */ @@ -1725,7 +1725,7 @@ static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, * * This functions returns the virtual address inside shared area * according to the physical address. It can be either on the - * externa RAM device (ioremapped), or on the system RAM + * external RAM device (ioremapped), or on the system RAM * This implementation is for the external RAM */ static void *sep_shared_area_bus_to_virt(struct sep_device *sep, @@ -1891,9 +1891,9 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, * @lli_table_ptr: * @num_entries_ptr: * @table_data_size_ptr: - * @is_kva: set for kernel data (kernel cryptio call) + * @is_kva: set for kernel data (kernel crypt io call) * - * This function prepares only input DMA table for synhronic symmetric + * This function prepares only input DMA table for synchronic symmetric * operations (HASH) * Note that all bus addresses that are passed to the SEP * are in 32 bit format; the SEP is a 32 bit device @@ -2174,9 +2174,9 @@ static int sep_construct_dma_tables_from_lli( u32 last_table_flag = 0; /* The data size that should be in table */ u32 table_data_size = 0; - /* Number of etnries in the input table */ + /* Number of entries in the input table */ u32 num_entries_in_table = 0; - /* Number of etnries in the output table */ + /* Number of entries in the output table */ u32 num_entries_out_table = 0; if (!dma_ctx) { @@ -2401,7 +2401,7 @@ static int sep_construct_dma_tables_from_lli( * @table_data_size_ptr: * @is_kva: set for kernel data; used only for kernel crypto module * - * This function builds input and output DMA tables for synhronic + * This function builds input and output DMA tables for synchronic * symmetric operations (AES, DES, HASH). It also checks that each table * is of the modular block size * Note that all bus addresses that are passed to the SEP @@ -2556,7 +2556,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is (hex) %x\n", current->pid, SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - /* Call the fucntion that creates table from the lli arrays */ + /* Call the function that creates table from the lli arrays */ dev_dbg(&sep->pdev->dev, "[PID%d] calling create table from lli\n", current->pid); error = sep_construct_dma_tables_from_lli( @@ -3663,7 +3663,7 @@ static ssize_t sep_read(struct file *filp, goto end_function; } - /* Checks that user has called necessarry apis */ + /* Checks that user has called necessary apis */ if (0 == test_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, &call_status->status)) { dev_warn(&sep->pdev->dev, -- GitLab From 2f0b9d082e5d0056a3aca4be038483a564849196 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 11 Jun 2012 17:45:15 -0700 Subject: [PATCH 1294/6849] staging: comedi: export alloc_subdevices as comedi_alloc_subdevices Move the inline alloc_subdevices() function from comedidev.h to drivers.c and rename it to comedi_alloc_subdevices(). The function is large enough to warrant being an exported symbol rather than being an inline in every driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 22 ++----------------- drivers/staging/comedi/drivers.c | 21 ++++++++++++++++++ drivers/staging/comedi/drivers/8255.c | 2 +- drivers/staging/comedi/drivers/acl7225b.c | 2 +- .../comedi/drivers/addi-data/addi_common.c | 2 +- .../comedi/drivers/addi-data/hwdrv_APCI1710.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 2 +- drivers/staging/comedi/drivers/adl_pci7230.c | 2 +- drivers/staging/comedi/drivers/adl_pci7296.c | 2 +- drivers/staging/comedi/drivers/adl_pci7432.c | 2 +- drivers/staging/comedi/drivers/adl_pci8164.c | 2 +- drivers/staging/comedi/drivers/adl_pci9111.c | 2 +- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- drivers/staging/comedi/drivers/adq12b.c | 2 +- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- drivers/staging/comedi/drivers/aio_aio12_8.c | 2 +- drivers/staging/comedi/drivers/aio_iiro_16.c | 2 +- drivers/staging/comedi/drivers/amplc_dio200.c | 2 +- drivers/staging/comedi/drivers/amplc_pc236.c | 2 +- drivers/staging/comedi/drivers/amplc_pc263.c | 2 +- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- drivers/staging/comedi/drivers/c6xdigio.c | 3 ++- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- drivers/staging/comedi/drivers/cb_pcidio.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdas.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdda.c | 2 +- drivers/staging/comedi/drivers/comedi_bond.c | 2 +- .../staging/comedi/drivers/comedi_parport.c | 2 +- drivers/staging/comedi/drivers/comedi_test.c | 2 +- .../staging/comedi/drivers/contec_pci_dio.c | 2 +- drivers/staging/comedi/drivers/daqboard2000.c | 2 +- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/das16.c | 2 +- drivers/staging/comedi/drivers/das16m1.c | 2 +- drivers/staging/comedi/drivers/das1800.c | 2 +- drivers/staging/comedi/drivers/das6402.c | 2 +- drivers/staging/comedi/drivers/das800.c | 2 +- drivers/staging/comedi/drivers/dmm32at.c | 2 +- drivers/staging/comedi/drivers/dt2801.c | 2 +- drivers/staging/comedi/drivers/dt2811.c | 2 +- drivers/staging/comedi/drivers/dt2814.c | 2 +- drivers/staging/comedi/drivers/dt2815.c | 2 +- drivers/staging/comedi/drivers/dt2817.c | 2 +- drivers/staging/comedi/drivers/dt282x.c | 2 +- drivers/staging/comedi/drivers/dt3000.c | 2 +- drivers/staging/comedi/drivers/dt9812.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 +- drivers/staging/comedi/drivers/fl512.c | 2 +- drivers/staging/comedi/drivers/gsc_hpdi.c | 2 +- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/ii_pci20kc.c | 2 +- drivers/staging/comedi/drivers/jr3_pci.c | 2 +- drivers/staging/comedi/drivers/ke_counter.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 2 +- drivers/staging/comedi/drivers/mpc624.c | 2 +- drivers/staging/comedi/drivers/mpc8260cpm.c | 2 +- drivers/staging/comedi/drivers/multiq3.c | 2 +- drivers/staging/comedi/drivers/ni_6527.c | 2 +- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 2 +- drivers/staging/comedi/drivers/ni_670x.c | 2 +- drivers/staging/comedi/drivers/ni_at_a2150.c | 2 +- drivers/staging/comedi/drivers/ni_at_ao.c | 2 +- drivers/staging/comedi/drivers/ni_atmio16d.c | 2 +- drivers/staging/comedi/drivers/ni_daq_700.c | 2 +- drivers/staging/comedi/drivers/ni_daq_dio24.c | 2 +- drivers/staging/comedi/drivers/ni_labpc.c | 2 +- .../staging/comedi/drivers/ni_mio_common.c | 2 +- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/pcl711.c | 2 +- drivers/staging/comedi/drivers/pcl724.c | 2 +- drivers/staging/comedi/drivers/pcl725.c | 2 +- drivers/staging/comedi/drivers/pcl726.c | 2 +- drivers/staging/comedi/drivers/pcl730.c | 2 +- drivers/staging/comedi/drivers/pcl812.c | 2 +- drivers/staging/comedi/drivers/pcl816.c | 2 +- drivers/staging/comedi/drivers/pcl818.c | 2 +- drivers/staging/comedi/drivers/pcm3724.c | 2 +- drivers/staging/comedi/drivers/pcm3730.c | 2 +- drivers/staging/comedi/drivers/pcmad.c | 2 +- drivers/staging/comedi/drivers/pcmda12.c | 2 +- drivers/staging/comedi/drivers/pcmmio.c | 2 +- drivers/staging/comedi/drivers/pcmuio.c | 2 +- drivers/staging/comedi/drivers/poc.c | 2 +- .../staging/comedi/drivers/quatech_daqp_cs.c | 2 +- drivers/staging/comedi/drivers/rtd520.c | 2 +- drivers/staging/comedi/drivers/rti800.c | 2 +- drivers/staging/comedi/drivers/rti802.c | 2 +- drivers/staging/comedi/drivers/s526.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- drivers/staging/comedi/drivers/serial2002.c | 2 +- drivers/staging/comedi/drivers/skel.c | 2 +- drivers/staging/comedi/drivers/ssv_dnp.c | 2 +- drivers/staging/comedi/drivers/unioxx5.c | 2 +- drivers/staging/comedi/drivers/usbdux.c | 2 +- drivers/staging/comedi/drivers/usbduxfast.c | 2 +- drivers/staging/comedi/drivers/usbduxsigma.c | 2 +- drivers/staging/comedi/drivers/vmk80xx.c | 2 +- 105 files changed, 127 insertions(+), 123 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 9cd2b5117106..bb98f82141a1 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -292,6 +292,8 @@ static inline struct comedi_subdevice *comedi_get_write_subdevice( return info->device->write_subdev; } +int comedi_alloc_subdevices(struct comedi_device *, unsigned int); + void comedi_device_detach(struct comedi_device *dev); int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it); @@ -413,26 +415,6 @@ struct comedi_lrange { /* some silly little inline functions */ -static inline int alloc_subdevices(struct comedi_device *dev, - unsigned int num_subdevices) -{ - unsigned i; - - dev->n_subdevices = num_subdevices; - dev->subdevices = - kcalloc(num_subdevices, sizeof(struct comedi_subdevice), - GFP_KERNEL); - if (!dev->subdevices) - return -ENOMEM; - for (i = 0; i < num_subdevices; ++i) { - dev->subdevices[i].device = dev; - dev->subdevices[i].async_dma_dir = DMA_NONE; - spin_lock_init(&dev->subdevices[i].spin_lock); - dev->subdevices[i].minor = -1; - } - return 0; -} - static inline int alloc_private(struct comedi_device *dev, int size) { dev->private = kzalloc(size, GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 49e53eaa8e41..541364782b5f 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -56,6 +56,27 @@ static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s); struct comedi_driver *comedi_drivers; +int comedi_alloc_subdevices(struct comedi_device *dev, + unsigned int num_subdevices) +{ + unsigned i; + + dev->n_subdevices = num_subdevices; + dev->subdevices = + kcalloc(num_subdevices, sizeof(struct comedi_subdevice), + GFP_KERNEL); + if (!dev->subdevices) + return -ENOMEM; + for (i = 0; i < num_subdevices; ++i) { + dev->subdevices[i].device = dev; + dev->subdevices[i].async_dma_dir = DMA_NONE; + spin_lock_init(&dev->subdevices[i].spin_lock); + dev->subdevices[i].minor = -1; + } + return 0; +} +EXPORT_SYMBOL_GPL(comedi_alloc_subdevices); + static void cleanup_device(struct comedi_device *dev) { int i; diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 27e39e4eb6b3..875b02021777 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -388,7 +388,7 @@ static int dev_8255_attach(struct comedi_device *dev, return -EINVAL; } - ret = alloc_subdevices(dev, i); + ret = comedi_alloc_subdevices(dev, i); if (ret < 0) { /* FIXME this printk call should give a proper message, the * below line just maintains previous functionality */ diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index c1963add660d..3c39148c64cb 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -82,7 +82,7 @@ static int acl7225b_attach(struct comedi_device *dev, dev->iobase = iobase; dev->irq = 0; - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 44aaf8351ba3..274990a7cd3f 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -1688,7 +1688,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } else { /* Update-0.7.57->0.7.68dev->n_subdevices = 7; */ n_subdevices = 7; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index a76ed2553fb4..9632ca182d25 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -63,7 +63,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) int n_subdevices = 9; /* Update-0.7.57->0.7.68dev->n_subdevices = 9; */ - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return; diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 2f48dc72b20e..7d26d45d0753 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -301,7 +301,7 @@ static int pci6208_attach(struct comedi_device *dev, dev->iobase = io_base; dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index 2c8349273d7f..5a6e6c11e7fe 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -116,7 +116,7 @@ static int adl_pci7230_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci7230_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; devpriv->pci_dev = adl_pci7230_find_pci(dev, it); diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index 0b8b27983122..fd9b33afd458 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -92,7 +92,7 @@ static int adl_pci7296_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci7296_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; devpriv->pci_dev = adl_pci7296_find_pci(dev, it); diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index dd818f1b75ae..4976a70fb1e4 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -125,7 +125,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci7432_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; devpriv->pci_dev = adl_pci7432_find_pci(dev, it); diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 344754877892..78169f7d06ac 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -261,7 +261,7 @@ static int adl_pci8164_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; devpriv->pci_dev = adl_pci8164_find_pci(dev, it); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 410bbf9f5a95..cc179466dce0 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1317,7 +1317,7 @@ static int pci9111_attach(struct comedi_device *dev, /* TODO: Add external multiplexer setup (according to option[2]). */ - error = alloc_subdevices(dev, 4); + error = comedi_alloc_subdevices(dev, 4); if (error < 0) return error; diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 5a5c903f5e03..ebd8b8ec8c31 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2268,7 +2268,7 @@ static int pci9118_attach(struct comedi_device *dev, pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 1da298967413..ca8892e83db1 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -271,7 +271,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index db9f0a56f79f..be3fc4dd8859 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1433,7 +1433,7 @@ static int pci1710_attach(struct comedi_device *dev, if (this_board->n_counter) n_subdevices++; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index b8768b54e943..0aa0af4741a5 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -365,7 +365,7 @@ static int pci1723_attach(struct comedi_device *dev, if (this_board->n_diochan) n_subdevices++; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) { printk(" - Allocation failed!\n"); return ret; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index df8236c952e7..0fc4f858acca 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1156,7 +1156,7 @@ static int pci_dio_attach(struct comedi_device *dev, n_subdevices++; } - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index d215ae16668b..60466c81e2a9 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -182,7 +182,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct aio12_8_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = &dev->subdevices[0]; diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 5c1548b385f4..7d161d6739ae 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -124,7 +124,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct aio_iiro_16_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 3afebb24b26b..d7d056e20c02 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1273,7 +1273,7 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, devpriv->intr_sd = -1; dev->iobase = iobase; dev->board_name = thisboard->name; - ret = alloc_subdevices(dev, layout->n_subdevs); + ret = comedi_alloc_subdevices(dev, layout->n_subdevs); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 9cf514e54a58..522e1c0c385e 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -455,7 +455,7 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase, dev->board_name = thisboard->name; dev->iobase = iobase; - ret = alloc_subdevices(dev, 2); + ret = comedi_alloc_subdevices(dev, 2); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 7020907f1af7..cfb69fa9c89d 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -227,7 +227,7 @@ static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase) dev->board_name = thisboard->name; dev->iobase = iobase; - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index a1e23bafabea..8d33aeab53b1 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1380,7 +1380,7 @@ static int pci224_attach_common(struct comedi_device *dev, dev->iobase + PCI224_DACCON); /* Allocate subdevices. There is only one! */ - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) { dev_err(dev->class_dev, "error! out of memory!\n"); return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 2a43df5d966e..e6598cafb39a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2843,7 +2843,7 @@ static int pci230_attach_common(struct comedi_device *dev, * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index fb9951a746a6..72b000fad609 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -433,7 +433,8 @@ static int c6xdigio_attach(struct comedi_device *dev, dev->iobase = iobase; dev->board_name = "c6xdigio"; - result = alloc_subdevices(dev, 2); /* 3 with encoder_init write */ + /* 3 subdevices with encoder_init write */ + result = comedi_alloc_subdevices(dev, 2); if (result < 0) return result; diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 35159235a1b6..9aa11c15497f 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -195,7 +195,7 @@ static int das16cs_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 074feeef829b..435f3aaedf88 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -617,7 +617,7 @@ found: /* * Allocate the subdevice structures. */ - if (alloc_subdevices(dev, 7) < 0) + if (comedi_alloc_subdevices(dev, 7) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 5bcadcb00c99..6b2f153980a9 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1345,7 +1345,7 @@ static int setup_subdevices(struct comedi_device *dev) void __iomem *dio_8255_iobase; int i; - if (alloc_subdevices(dev, 10) < 0) + if (comedi_alloc_subdevices(dev, 10) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index dc4cf0b030ef..4ab3584365e2 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -336,7 +336,7 @@ found: /* * Allocate the subdevice structures. */ - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 58d5a3d257bd..56c1d09188aa 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -181,7 +181,7 @@ found: * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, thisboard->n_8255) < 0) + if (comedi_alloc_subdevices(dev, thisboard->n_8255) < 0) return -ENOMEM; for (i = 0; i < thisboard->n_8255; i++) { diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index a06b67a0b36d..6acb3199e6f3 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -273,7 +273,7 @@ found: * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index bec250bf15bb..abb6008da4df 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -240,7 +240,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 29412de06c31..d56eec48e4c8 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -362,7 +362,7 @@ static int bonding_attach(struct comedi_device *dev, * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index bff5dcd76107..c9a725fc61f2 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -315,7 +315,7 @@ static int parport_attach(struct comedi_device *dev, } dev->board_name = "parport"; - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; ret = alloc_private(dev, sizeof(struct parport_private)); diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 9f3c3d5d02a4..cd43c0d7df38 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -448,7 +448,7 @@ static int waveform_attach(struct comedi_device *dev, devpriv->usec_period = period; dev->n_subdevices = 2; - if (alloc_subdevices(dev, dev->n_subdevices) < 0) + if (comedi_alloc_subdevices(dev, dev->n_subdevices) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 2cd7407adbea..a5bad1bd6dcd 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -115,7 +115,7 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct contec_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; for_each_pci_dev(pcidev) { diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index d84794ca4380..dbd0472bc7e2 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -772,7 +772,7 @@ static int daqboard2000_attach(struct comedi_device *dev, if (!devpriv->plx || !devpriv->daq) return -ENOMEM; - result = alloc_subdevices(dev, 3); + result = comedi_alloc_subdevices(dev, 3); if (result < 0) goto out; diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index f99f72b9cdf3..1dea21a33a27 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -834,7 +834,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) dev->board_name = thisboard->name; - ret = alloc_subdevices(dev, 6); + ret = comedi_alloc_subdevices(dev, 6); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 61705366dd40..6a8a7eb1ae9c 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1264,7 +1264,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) } devpriv->timer_mode = timer_mode ? 1 : 0; - ret = alloc_subdevices(dev, 5); + ret = comedi_alloc_subdevices(dev, 5); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index e468ff14aa52..eafd6b59a483 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -646,7 +646,7 @@ static int das16m1_attach(struct comedi_device *dev, return -EINVAL; } - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 079fb06de215..12d736a6e38d 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1644,7 +1644,7 @@ static int das1800_attach(struct comedi_device *dev, return -ENOMEM; } - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 881f392d1dba..2039b6c11590 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -307,7 +307,7 @@ static int das6402_attach(struct comedi_device *dev, if (ret < 0) return ret; - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 4e33b2a28d97..6263f532e5da 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -510,7 +510,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 5be99b5d22e4..40d7befec5ea 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -375,7 +375,7 @@ static int dmm32at_attach(struct comedi_device *dev, * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 625bd617a8e9..35ce076237a4 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -628,7 +628,7 @@ havetype: n_ai_chans = probe_number_of_ai_chans(dev); printk(" (ai channels = %d)", n_ai_chans); - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) goto out; diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 727da9e19206..6ff610d1b0f9 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -465,7 +465,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) } #endif - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index fa4ade61be5f..876d5cbdbe4a 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -338,7 +338,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif } - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index bbab712be4b9..33ad1fa90762 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -177,7 +177,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "dt2815"; - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; if (alloc_private(dev, sizeof(struct dt2815_private)) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 1ee10e7bf1d2..665db07aeb84 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -137,7 +137,7 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "dt2817"; - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index eefda3c064d3..f11d1fdfcae2 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1268,7 +1268,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - ret = alloc_subdevices(dev, 3); + ret = comedi_alloc_subdevices(dev, 3); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index af0202474127..10415b218b5c 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -882,7 +882,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->irq = devpriv->pci_dev->irq; - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 22cda5c76ce4..56af2f28f98d 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -1036,7 +1036,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->serial = it->options[0]; /* Allocate subdevices */ - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; /* digital input subdevice */ diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 367a7c88a0fd..6f6fb527d543 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -329,7 +329,7 @@ found: devpriv->BADR4 = pci_resource_start(pcidev, 4); devpriv->BADR5 = pci_resource_start(pcidev, 5); - if (alloc_subdevices(dev, 4) < 0) { + if (comedi_alloc_subdevices(dev, 4) < 0) { printk(KERN_ERR "comedi: dyna_pci10xx: " "failed allocating subdevices\n"); mutex_unlock(&start_stop_sem); diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index d23814450b40..7218a9b2cda9 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -131,7 +131,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_DEBUG "malloc ok\n"); #endif - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; /* diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index fe1fd2f75f0d..b103cfbf3274 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -431,7 +431,7 @@ static int setup_subdevices(struct comedi_device *dev) { struct comedi_subdevice *s; - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 1f254f480a66..06c66afc6aa1 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -903,7 +903,7 @@ static int icp_multi_attach(struct comedi_device *dev, if (this_board->n_ctrs) n_subdevices++; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 6f6947602398..9c1165791078 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -202,7 +202,7 @@ static int pci20xxx_attach(struct comedi_device *dev, struct comedi_subdevice *s; union pci20xxx_subdev_private *sdp; - ret = alloc_subdevices(dev, 1 + PCI20000_MODULES); + ret = comedi_alloc_subdevices(dev, 1 + PCI20000_MODULES); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index e8dfc367aa8d..182643bed561 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -826,7 +826,7 @@ static int jr3_pci_attach(struct comedi_device *dev, if (!devpriv->iobase) return -ENOMEM; - result = alloc_subdevices(dev, devpriv->n_channels); + result = comedi_alloc_subdevices(dev, devpriv->n_channels); if (result < 0) goto out; diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 9f92420dd826..bcb1eb49a1f7 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -190,7 +190,7 @@ found: dev->iobase = io_base; /* allocate the subdevice structures */ - error = alloc_subdevices(dev, 1); + error = comedi_alloc_subdevices(dev, 1); if (error < 0) return error; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 09890b8c586c..39100ddddef8 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -2195,7 +2195,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) * convenient macro defined in comedidev.h. It relies on * n_subdevices being set correctly. */ - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; /*========================================================================= diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index fcadb0fcd1d0..231b29413eaa 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -762,7 +762,7 @@ found: me_reset(dev); /* device driver capabilities */ - error = alloc_subdevices(dev, 3); + error = comedi_alloc_subdevices(dev, 3); if (error < 0) return error; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 4304e864a4d4..48ba6b9f9430 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -349,7 +349,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Subdevices structures */ - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c index 364470e4458f..13110510d7fe 100644 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ b/drivers/staging/comedi/drivers/mpc8260cpm.c @@ -131,7 +131,7 @@ static int mpc8260cpm_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; for (i = 0; i < 4; i++) { diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index e951e73d66f5..00d497c270ae 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -255,7 +255,7 @@ static int multiq3_attach(struct comedi_device *dev, else printk(KERN_WARNING "comedi%d: no irq\n", dev->minor); dev->board_name = "multiq3"; - result = alloc_subdevices(dev, 5); + result = comedi_alloc_subdevices(dev, 5); if (result < 0) return result; diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index b02aa0efcd86..89fee6fdcf61 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -397,7 +397,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "comedi board: %s, ID=0x%02x\n", dev->board_name, readb(devpriv->mite->daq_io_addr + ID_Register)); - ret = alloc_subdevices(dev, 3); + ret = comedi_alloc_subdevices(dev, 3); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 0d27a9323bc0..a49dceac65bc 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -678,7 +678,7 @@ static int ni_65xx_attach(struct comedi_device *dev, printk(KERN_INFO " ID=0x%02x", readb(private(dev)->mite->daq_io_addr + ID_Register)); - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 8c40730e296a..5827debd3366 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1095,7 +1095,7 @@ static int ni_660x_attach(struct comedi_device *dev, dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS; - if (alloc_subdevices(dev, dev->n_subdevices) < 0) + if (comedi_alloc_subdevices(dev, dev->n_subdevices) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index a9cf94fd0c30..45a03e64549a 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -202,7 +202,7 @@ static int ni_670x_attach(struct comedi_device *dev, dev->irq = mite_irq(devpriv->mite); printk(KERN_INFO " %s", dev->board_name); - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index ae896a094150..9d1a0f745bf8 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -826,7 +826,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_ptr = a2150_boards + a2150_probe(dev); dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index bfe7fb79880d..03a4d736b454 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -356,7 +356,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct atao_private)) < 0) return -ENOMEM; - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index a0890ee202f4..37ff6fc86157 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -709,7 +709,7 @@ static int atmio16d_attach(struct comedi_device *dev, dev->board_name = board->name; - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 75764e8d27eb..8860207e88d7 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -409,7 +409,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; /* DAQCard-700 dio */ diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 493a22788637..36c0c62382ed 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -158,7 +158,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; /* 8255 dio */ diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 1d739b26e678..a92570f5a7c5 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -622,7 +622,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 5) < 0) + if (comedi_alloc_subdevices(dev, 5) < 0) return -ENOMEM; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index fd232bc5f873..4261e929869f 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4412,7 +4412,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) return -EINVAL; } - if (alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0) + if (comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0) return -ENOMEM; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 37b700830e21..77ef312f657e 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1248,7 +1248,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) else n_subdevices = 1; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index e943b52d04a8..35b95105a749 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -518,7 +518,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->irq = irq; - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 4136a03a5125..698c9004c74e 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -156,7 +156,7 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) || (it->options[1] == 96))) n_subdevices = 4; /* PCL-724 in 96 DIO configuration */ - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 83a6fa53dddd..d7ba336ce031 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -63,7 +63,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->irq = 0; - if (alloc_subdevices(dev, 2) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index e9449bb2ba00..e756a3033767 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -292,7 +292,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("\n"); - ret = alloc_subdevices(dev, 3); + ret = comedi_alloc_subdevices(dev, 3); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index 02a4386e1031..e258bcebf198 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -85,7 +85,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->irq = 0; - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 28780ede1ee5..128f5b644878 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1382,7 +1382,7 @@ no_dma: if (board->n_dochan > 0) n_subdevices++; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) { free_resources(dev); return ret; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 845039cd6207..37cedbc47a43 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -1194,7 +1194,7 @@ no_dma: subdevs[3] = COMEDI_SUBD_DO; */ - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 6c84b29a8dad..a4c2870562fb 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1778,7 +1778,7 @@ no_rtc: no_dma: - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 9eee708e8442..d755b406a6f1 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -258,7 +258,7 @@ static int pcm3724_attach(struct comedi_device *dev, n_subdevices = board->numofports; - ret = alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index f8d1c644daf8..48a21bd679fd 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -71,7 +71,7 @@ static int pcm3730_attach(struct comedi_device *dev, dev->iobase = dev->iobase; dev->irq = 0; - if (alloc_subdevices(dev, 6) < 0) + if (comedi_alloc_subdevices(dev, 6) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 2ec0b2e63c35..00b0f2a6894c 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -117,7 +117,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_CONT "\n"); dev->iobase = iobase; - ret = alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index f49c66afe5fc..3645e9ee8807 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -197,7 +197,7 @@ static int pcmda12_attach(struct comedi_device *dev, * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the * 96-channel version of the board. */ - if (alloc_subdevices(dev, 1) < 0) { + if (comedi_alloc_subdevices(dev, 1) < 0) { printk(KERN_ERR "cannot allocate subdevice data structures\n"); return -ENOMEM; } diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index c4482ae9d08b..67fdac5b81d6 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1077,7 +1077,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) * * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) */ - if (alloc_subdevices(dev, n_subdevs) < 0) { + if (comedi_alloc_subdevices(dev, n_subdevs) < 0) { printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n", dev->minor); return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index b1a9bed38551..ce5068e3b46e 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -807,7 +807,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the * 96-channel version of the board. */ - if (alloc_subdevices(dev, n_subdevs) < 0) { + if (comedi_alloc_subdevices(dev, n_subdevs) < 0) { dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n"); return -ENOMEM; } diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 95e348fa89c8..1e954f9c4165 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -160,7 +160,7 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; if (alloc_private(dev, sizeof(unsigned int) * board->n_chan) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 2f130b3095e9..38a13ba38e18 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -871,7 +871,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = local->link->resource[0]->start; - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 84b28b6b99d6..7d248a7685b2 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -2003,7 +2003,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 4) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 04a23687ae3e..a80f6302375b 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -348,7 +348,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - ret = alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 4); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 09da5c21858c..1aacf3f6e3f5 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -103,7 +103,7 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "rti802"; - if (alloc_subdevices(dev, 1) < 0 + if (comedi_alloc_subdevices(dev, 1) < 0 || alloc_private(dev, sizeof(struct rti802_private))) { return -ENOMEM; } diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 3c8e9799824e..17d581b8ac6f 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -779,7 +779,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) * convenient macro defined in comedidev.h. */ dev->n_subdevices = 4; - if (alloc_subdevices(dev, dev->n_subdevices) < 0) + if (comedi_alloc_subdevices(dev, dev->n_subdevices) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index d6dc3381205a..f2eeca51ebfa 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -595,7 +595,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_ptr = s626_boards; dev->board_name = thisboard->name; - if (alloc_subdevices(dev, 6) < 0) + if (comedi_alloc_subdevices(dev, 6) < 0) return -ENOMEM; dev->iobase = (unsigned long)devpriv->base_addr; diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index c25808c05251..dc41c04fae4f 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -792,7 +792,7 @@ static int serial2002_attach(struct comedi_device *dev, dev_dbg(dev->hw_dev, "/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed); - if (alloc_subdevices(dev, 5) < 0) + if (comedi_alloc_subdevices(dev, 5) < 0) return -ENOMEM; /* digital input subdevice */ diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 7d13ffa7f4f9..16947c8b8803 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -237,7 +237,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 3) < 0) + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index de580958e32a..5eaef8434e09 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -200,7 +200,7 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Allocate the subdevice structures. alloc_subdevice() is a */ /* convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 1) < 0) + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index d5f1f22aa708..170bc48cfd1c 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -468,7 +468,7 @@ static int unioxx5_attach(struct comedi_device *dev, return -1; } - if (alloc_subdevices(dev, n_subd) < 0) { + if (comedi_alloc_subdevices(dev, n_subd) < 0) { printk(KERN_ERR "out of memory\n"); return -ENOMEM; } diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 13d9fd3efcfd..ca8b3e121ff0 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2645,7 +2645,7 @@ static int usbdux_attach_common(struct comedi_device *dev, } /* allocate space for the subdevices */ - ret = alloc_subdevices(dev, dev->n_subdevices); + ret = comedi_alloc_subdevices(dev, dev->n_subdevices); if (ret < 0) { dev_err(&udev->interface->dev, "comedi%d: error alloc space for subdev\n", dev->minor); diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 7b1d21a6fc53..b2f7350c429f 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1675,7 +1675,7 @@ static int usbduxfast_attach(struct comedi_device *dev, dev->n_subdevices = N_SUBDEVICES; /* allocate space for the subdevices */ - ret = alloc_subdevices(dev, N_SUBDEVICES); + ret = comedi_alloc_subdevices(dev, N_SUBDEVICES); if (ret < 0) { printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for " "subdev\n", dev->minor); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 441ccef4c110..00faf4ad6ffb 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2690,7 +2690,7 @@ static int usbduxsigma_attach(struct comedi_device *dev, } /* allocate space for the subdevices */ - ret = alloc_subdevices(dev, dev->n_subdevices); + ret = comedi_alloc_subdevices(dev, dev->n_subdevices); if (ret < 0) { dev_err(&udev->interface->dev, "comedi%d: no space for subdev\n", dev->minor); diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index baee8d767636..5a3e33d83c84 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1159,7 +1159,7 @@ static int vmk80xx_attach(struct comedi_device *cdev, else n_subd = 6; - if (alloc_subdevices(cdev, n_subd) < 0) { + if (comedi_alloc_subdevices(cdev, n_subd) < 0) { up(&dev->limit_sem); mutex_unlock(&glb_mutex); return -ENOMEM; -- GitLab From c810a399798022d545191e2daaca0368623c15d3 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 5 Jun 2012 16:40:10 +0530 Subject: [PATCH 1295/6849] staging: Android: Fix some checkpatch warnings Warnings reported by checkpatch.pl have been fixed. Cc: Brian Swetland Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 14 ++++++++------ drivers/staging/android/logger.c | 10 ++++++---- drivers/staging/android/ram_console.c | 4 +++- drivers/staging/android/timed_output.c | 4 +++- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index e84dbecd0991..69cf2db1d69c 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -16,6 +16,8 @@ ** GNU General Public License for more details. */ +#define pr_fmt(fmt) "ashmem: " fmt + #include #include #include @@ -707,7 +709,7 @@ static int __init ashmem_init(void) sizeof(struct ashmem_area), 0, 0, NULL); if (unlikely(!ashmem_area_cachep)) { - printk(KERN_ERR "ashmem: failed to create slab cache\n"); + pr_err("failed to create slab cache\n"); return -ENOMEM; } @@ -715,19 +717,19 @@ static int __init ashmem_init(void) sizeof(struct ashmem_range), 0, 0, NULL); if (unlikely(!ashmem_range_cachep)) { - printk(KERN_ERR "ashmem: failed to create slab cache\n"); + pr_err("failed to create slab cache\n"); return -ENOMEM; } ret = misc_register(&ashmem_misc); if (unlikely(ret)) { - printk(KERN_ERR "ashmem: failed to register misc device!\n"); + pr_err("failed to register misc device!\n"); return ret; } register_shrinker(&ashmem_shrinker); - printk(KERN_INFO "ashmem: initialized\n"); + pr_info("initialized\n"); return 0; } @@ -740,12 +742,12 @@ static void __exit ashmem_exit(void) ret = misc_deregister(&ashmem_misc); if (unlikely(ret)) - printk(KERN_ERR "ashmem: failed to unregister misc device!\n"); + pr_err("failed to unregister misc device!\n"); kmem_cache_destroy(ashmem_range_cachep); kmem_cache_destroy(ashmem_area_cachep); - printk(KERN_INFO "ashmem: unloaded\n"); + pr_info("unloaded\n"); } module_init(ashmem_init); diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index b2e71c6fd175..f7b8237d5be7 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -17,6 +17,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) "logger: " fmt + #include #include #include @@ -621,13 +623,13 @@ static int __init create_log(char *log_name, int size) /* finally, initialize the misc device for this log */ ret = misc_register(&log->misc); if (unlikely(ret)) { - printk(KERN_ERR "logger: failed to register misc " - "device for log '%s'!\n", log->misc.name); + pr_err("failed to register misc device for log '%s'!\n", + log->misc.name); goto out_free_log; } - printk(KERN_INFO "logger: created %luK log '%s'\n", - (unsigned long) log->size >> 10, log->misc.name); + pr_info("created %luK log '%s'\n", + (unsigned long) log->size >> 10, log->misc.name); return 0; diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c index 82323bb1d1a3..7add022b1c22 100644 --- a/drivers/staging/android/ram_console.c +++ b/drivers/staging/android/ram_console.c @@ -13,6 +13,8 @@ * */ +#define pr_fmt(fmt) "ram_console: " fmt + #include #include #include @@ -162,7 +164,7 @@ static int __init ram_console_late_init(void) entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); if (!entry) { - printk(KERN_ERR "ram_console: failed to create proc entry\n"); + pr_err("failed to create proc entry\n"); persistent_ram_free_old(prz); return 0; } diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c index 38d930cadad3..ec9e2ae2de0d 100644 --- a/drivers/staging/android/timed_output.c +++ b/drivers/staging/android/timed_output.c @@ -14,6 +14,8 @@ * */ +#define pr_fmt(fmt) "timed_output: " fmt + #include #include #include @@ -90,7 +92,7 @@ int timed_output_dev_register(struct timed_output_dev *tdev) err_create_file: device_destroy(timed_output_class, MKDEV(0, tdev->index)); - printk(KERN_ERR "timed_output: Failed to register driver %s\n", + pr_err("failed to register driver %s\n", tdev->name); return ret; -- GitLab From 592314e9e1c0057bdb75ff00cbd1c51aa06c65e7 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 5 Jun 2012 15:05:13 +0530 Subject: [PATCH 1296/6849] staging: Android: Fix NULL pointer related warning in alarm-dev.c file Fixes the following sparse warning: drivers/staging/android/alarm-dev.c:259:35: warning: Using plain integer as NULL pointer Cc: Brian Swetland Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 32614d611283..c2d87c546e99 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -255,7 +255,7 @@ static int alarm_release(struct inode *inode, struct file *file) unsigned long flags; spin_lock_irqsave(&alarm_slock, flags); - if (file->private_data != 0) { + if (file->private_data) { for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { uint32_t alarm_type_mask = 1U << i; if (alarm_enabled & alarm_type_mask) { -- GitLab From 6ddcd46463aa66855f1f8e74de454740a5f4aef4 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Mon, 11 Jun 2012 18:13:57 -0700 Subject: [PATCH 1297/6849] mwifiex: fix incorrect privacy setting in beacon and probe response Test procedure: 1. Start AP with security setting (e.g. WPA2) 2. Stop AP 3. Start AP with open security Here it's observed that privacy is enabled in beacons and probe responses. This patch fixes it by checking the privacy parameter from cfg80211_ap_settings. If privacy is not set in cfg80211_ap_settings, set open authentication and no encryption in FW. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/uap_cmd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 8173ab66066d..89f9a2a45de3 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -27,6 +27,17 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { int i; + if (!params->privacy) { + bss_config->protocol = PROTOCOL_NO_SECURITY; + bss_config->key_mgmt = KEY_MGMT_NONE; + bss_config->wpa_cfg.length = 0; + priv->sec_info.wep_enabled = 0; + priv->sec_info.wpa_enabled = 0; + priv->sec_info.wpa2_enabled = 0; + + return 0; + } + switch (params->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: bss_config->auth_mode = WLAN_AUTH_OPEN; -- GitLab From 0c16ae762990660c4dfd7515e3d46b4249f535f0 Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Tue, 12 Jun 2012 11:23:32 -0700 Subject: [PATCH 1298/6849] staging: gdm72xx: Simplify spinlock fix for gdm_usb_send_complete This patch simplifies the previous patch (commit dd13c86b0dae86efdde98119ffd7348e80719ade) for fixing the spinlock recursion issue on several call sites of gdm_usb_send_complete. Signed-off-by: Ben Chan Cc: Sage Ahn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_usb.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 646e0ace91ec..89268c785b25 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -270,21 +270,17 @@ static void release_usb(struct usbwm_dev *udev) } } -static void gdm_usb_send_complete_impl(struct urb *urb, bool need_lock) +static void __gdm_usb_send_complete(struct urb *urb) { struct usb_tx *t = urb->context; struct tx_cxt *tx = t->tx_cxt; u8 *pkt = t->buf; u16 cmd_evt; - unsigned long flags; /* Completion by usb_unlink_urb */ if (urb->status == -ECONNRESET) return; - if (need_lock) - spin_lock_irqsave(&tx->lock, flags); - if (t->callback) t->callback(t->cb_data); @@ -296,19 +292,17 @@ static void gdm_usb_send_complete_impl(struct urb *urb, bool need_lock) put_tx_struct(tx, t); else free_tx_struct(t); - - if (need_lock) - spin_unlock_irqrestore(&tx->lock, flags); } static void gdm_usb_send_complete(struct urb *urb) { - gdm_usb_send_complete_impl(urb, true); -} + struct usb_tx *t = urb->context; + struct tx_cxt *tx = t->tx_cxt; + unsigned long flags; -static void gdm_usb_send_complete_no_lock(struct urb *urb) -{ - gdm_usb_send_complete_impl(urb, false); + spin_lock_irqsave(&tx->lock, flags); + __gdm_usb_send_complete(urb); + spin_unlock_irqrestore(&tx->lock, flags); } static int gdm_usb_send(void *priv_dev, void *data, int len, @@ -423,7 +417,7 @@ out: send_fail: t->callback = NULL; - gdm_usb_send_complete_no_lock(t->urb); + __gdm_usb_send_complete(t->urb); spin_unlock_irqrestore(&tx->lock, flags); return ret; } @@ -552,7 +546,7 @@ static void do_pm_control(struct work_struct *work) if (ret) { t->callback = NULL; - gdm_usb_send_complete_no_lock(t->urb); + __gdm_usb_send_complete(t->urb); } } } @@ -754,7 +748,7 @@ static int k_mode_thread(void *arg) if (ret) { t->callback = NULL; - gdm_usb_send_complete_no_lock(t->urb); + __gdm_usb_send_complete(t->urb); } } -- GitLab From 8b9ba6e5efc3213f384cda155861a4f7ae903365 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:57:27 -0700 Subject: [PATCH 1299/6849] staging: comedi: change type of num_subdevices parameter to comedi_alloc_subdevices The n_subdevices variable of struct comedi_device is an int type. Change the type of the comedi_alloc_subdevices 'num_subdevices' from an unsigned int to an int to match it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 +- drivers/staging/comedi/drivers.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index bb98f82141a1..e0f3915b0f63 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -292,7 +292,7 @@ static inline struct comedi_subdevice *comedi_get_write_subdevice( return info->device->write_subdev; } -int comedi_alloc_subdevices(struct comedi_device *, unsigned int); +int comedi_alloc_subdevices(struct comedi_device *, int); void comedi_device_detach(struct comedi_device *dev); int comedi_device_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 541364782b5f..979aa0e88997 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -56,10 +56,9 @@ static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s); struct comedi_driver *comedi_drivers; -int comedi_alloc_subdevices(struct comedi_device *dev, - unsigned int num_subdevices) +int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) { - unsigned i; + int i; dev->n_subdevices = num_subdevices; dev->subdevices = -- GitLab From 7f801c41714729f7741a042de839918be2bb56f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:57:45 -0700 Subject: [PATCH 1300/6849] staging: comedi: sanity check num_subdevices parameter in comedi_alloc_subdevices It's possible for a couple of the comedi drivers to incorrectly call comedi_alloc_subdevices with num_subdevices = 0. Add a sanity check before doing the kcalloc. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 979aa0e88997..61161ce8e93f 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -60,6 +60,8 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) { int i; + if (num_subdevices < 1) + return -EINVAL; dev->n_subdevices = num_subdevices; dev->subdevices = kcalloc(num_subdevices, sizeof(struct comedi_subdevice), -- GitLab From fba1d0faf726b442ab8771d5e9fbaf5f5a4c624c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:58:27 -0700 Subject: [PATCH 1301/6849] staging: comedi: only set dev->n_subdevices when kcalloc succeedes It's possible for the kcalloc in comedi_alloc_subdevices to fail. Only set the dev->n_subdevices variable if the allocation is successful. Since the core sets dev->n_subdevices, remove all the places in the drivers where this variable was getting set. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 2 +- drivers/staging/comedi/drivers/comedi_test.c | 3 +-- drivers/staging/comedi/drivers/ni_660x.c | 4 +--- drivers/staging/comedi/drivers/s526.c | 3 +-- drivers/staging/comedi/drivers/usbdux.c | 7 ++++--- drivers/staging/comedi/drivers/usbduxfast.c | 10 +--------- drivers/staging/comedi/drivers/usbduxsigma.c | 7 ++++--- 7 files changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 61161ce8e93f..ecad2288c9fb 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -62,12 +62,12 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) if (num_subdevices < 1) return -EINVAL; - dev->n_subdevices = num_subdevices; dev->subdevices = kcalloc(num_subdevices, sizeof(struct comedi_subdevice), GFP_KERNEL); if (!dev->subdevices) return -ENOMEM; + dev->n_subdevices = num_subdevices; for (i = 0; i < num_subdevices; ++i) { dev->subdevices[i].device = dev; dev->subdevices[i].async_dma_dir = DMA_NONE; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index cd43c0d7df38..004da30d7d2b 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -447,8 +447,7 @@ static int waveform_attach(struct comedi_device *dev, devpriv->uvolt_amplitude = amplitude; devpriv->usec_period = period; - dev->n_subdevices = 2; - if (comedi_alloc_subdevices(dev, dev->n_subdevices) < 0) + if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5827debd3366..8c6a6ba9d4b9 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1093,9 +1093,7 @@ static int ni_660x_attach(struct comedi_device *dev, printk(KERN_INFO " %s ", dev->board_name); - dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS; - - if (comedi_alloc_subdevices(dev, dev->n_subdevices) < 0) + if (comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 17d581b8ac6f..dbbff70dc0ca 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -778,8 +778,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - dev->n_subdevices = 4; - if (comedi_alloc_subdevices(dev, dev->n_subdevices) < 0) + if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index ca8b3e121ff0..3819663b1cbe 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2624,6 +2624,7 @@ static int usbdux_attach_common(struct comedi_device *dev, { int ret; struct comedi_subdevice *s = NULL; + int n_subdevs; down(&udev->sem); /* pointer back to the corresponding comedi device */ @@ -2638,14 +2639,14 @@ static int usbdux_attach_common(struct comedi_device *dev, /* set number of subdevices */ if (udev->high_speed) { /* with pwm */ - dev->n_subdevices = 5; + n_subdevs = 5; } else { /* without pwm */ - dev->n_subdevices = 4; + n_subdevs = 4; } /* allocate space for the subdevices */ - ret = comedi_alloc_subdevices(dev, dev->n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret < 0) { dev_err(&udev->interface->dev, "comedi%d: error alloc space for subdev\n", dev->minor); diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index b2f7350c429f..262556ebc4db 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -126,11 +126,6 @@ */ #define NUMUSBDUXFAST 16 -/* - * number of subdevices - */ -#define N_SUBDEVICES 1 - /* * analogue in subdevice */ @@ -1671,11 +1666,8 @@ static int usbduxfast_attach(struct comedi_device *dev, dev->board_name = BOARDNAME; - /* set number of subdevices */ - dev->n_subdevices = N_SUBDEVICES; - /* allocate space for the subdevices */ - ret = comedi_alloc_subdevices(dev, N_SUBDEVICES); + ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) { printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for " "subdev\n", dev->minor); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 00faf4ad6ffb..87c613e88892 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2642,6 +2642,7 @@ static int usbduxsigma_attach(struct comedi_device *dev, int index; int i; struct usbduxsub *udev; + int n_subdevs; int offset; @@ -2683,14 +2684,14 @@ static int usbduxsigma_attach(struct comedi_device *dev, /* set number of subdevices */ if (udev->high_speed) { /* with pwm */ - dev->n_subdevices = 4; + n_subdevs = 4; } else { /* without pwm */ - dev->n_subdevices = 3; + n_subdevs = 3; } /* allocate space for the subdevices */ - ret = comedi_alloc_subdevices(dev, dev->n_subdevices); + ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret < 0) { dev_err(&udev->interface->dev, "comedi%d: no space for subdev\n", dev->minor); -- GitLab From 0e4039f3112326d73f66b00fd18468a3804ed29e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:58:45 -0700 Subject: [PATCH 1302/6849] staging: comedi: remove the comed_alloc_subdevices "allocation failed" messages Remove all the "allocation failed" debug messages that are displayed when the comedi_alloc_subdevices call fails. Signed-off-by: H Hartley Sweeten Cc: Ian Abbot Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 6 +----- drivers/staging/comedi/drivers/adv_pci1723.c | 4 +--- drivers/staging/comedi/drivers/amplc_dio200.c | 4 +--- drivers/staging/comedi/drivers/amplc_pc236.c | 4 +--- drivers/staging/comedi/drivers/amplc_pc263.c | 4 +--- drivers/staging/comedi/drivers/amplc_pci224.c | 4 +--- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 -- drivers/staging/comedi/drivers/pcmda12.c | 4 +--- drivers/staging/comedi/drivers/pcmmio.c | 5 +---- drivers/staging/comedi/drivers/pcmuio.c | 4 +--- drivers/staging/comedi/drivers/unioxx5.c | 4 +--- drivers/staging/comedi/drivers/usbdux.c | 2 -- drivers/staging/comedi/drivers/usbduxfast.c | 2 -- drivers/staging/comedi/drivers/usbduxsigma.c | 2 -- 14 files changed, 10 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 875b02021777..64b00547228b 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -389,12 +389,8 @@ static int dev_8255_attach(struct comedi_device *dev, } ret = comedi_alloc_subdevices(dev, i); - if (ret < 0) { - /* FIXME this printk call should give a proper message, the - * below line just maintains previous functionality */ - printk("comedi%d: 8255:", dev->minor); + if (ret < 0) return ret; - } printk(KERN_INFO "comedi%d: 8255:", dev->minor); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 0aa0af4741a5..c14ad35cb835 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -366,10 +366,8 @@ static int pci1723_attach(struct comedi_device *dev, n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) { - printk(" - Allocation failed!\n"); + if (ret < 0) return ret; - } pci1723_reset(dev); subdev = 0; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index d7d056e20c02..17d3489b7f98 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1274,10 +1274,8 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, dev->iobase = iobase; dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, layout->n_subdevs); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + if (ret < 0) return ret; - } for (n = 0; n < dev->n_subdevices; n++) { s = &dev->subdevices[n]; switch (layout->sdtype[n]) { diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 522e1c0c385e..6205985806f5 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -456,10 +456,8 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase, dev->iobase = iobase; ret = comedi_alloc_subdevices(dev, 2); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + if (ret < 0) return ret; - } s = dev->subdevices + 0; /* digital i/o subdevice (8255) */ diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index cfb69fa9c89d..f1d68dff1ab0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -228,10 +228,8 @@ static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase) dev->iobase = iobase; ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + if (ret < 0) return ret; - } s = dev->subdevices + 0; /* digital output subdevice */ diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 8d33aeab53b1..c64e32821c4d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1381,10 +1381,8 @@ static int pci224_attach_common(struct comedi_device *dev, /* Allocate subdevices. There is only one! */ ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + if (ret < 0) return ret; - } s = dev->subdevices + 0; /* Analog output subdevice. */ diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 6f6fb527d543..bab2e37967ed 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -330,8 +330,6 @@ found: devpriv->BADR5 = pci_resource_start(pcidev, 5); if (comedi_alloc_subdevices(dev, 4) < 0) { - printk(KERN_ERR "comedi: dyna_pci10xx: " - "failed allocating subdevices\n"); mutex_unlock(&start_stop_sem); return -ENOMEM; } diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 3645e9ee8807..e1b30cc5d733 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -197,10 +197,8 @@ static int pcmda12_attach(struct comedi_device *dev, * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the * 96-channel version of the board. */ - if (comedi_alloc_subdevices(dev, 1) < 0) { - printk(KERN_ERR "cannot allocate subdevice data structures\n"); + if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; - } s = dev->subdevices; s->private = NULL; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 67fdac5b81d6..abaf6c758baf 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1077,11 +1077,8 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) * * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) */ - if (comedi_alloc_subdevices(dev, n_subdevs) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n", - dev->minor); + if (comedi_alloc_subdevices(dev, n_subdevs) < 0) return -ENOMEM; - } /* First, AI */ sdev_no = 0; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index ce5068e3b46e..e4153bd27172 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -807,10 +807,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the * 96-channel version of the board. */ - if (comedi_alloc_subdevices(dev, n_subdevs) < 0) { - dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n"); + if (comedi_alloc_subdevices(dev, n_subdevs) < 0) return -ENOMEM; - } port = 0; asic = 0; diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 170bc48cfd1c..711dad77c598 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -468,10 +468,8 @@ static int unioxx5_attach(struct comedi_device *dev, return -1; } - if (comedi_alloc_subdevices(dev, n_subd) < 0) { - printk(KERN_ERR "out of memory\n"); + if (comedi_alloc_subdevices(dev, n_subd) < 0) return -ENOMEM; - } /* initializing each of for same subdevices */ for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) { diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 3819663b1cbe..79df200bb6ee 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2648,8 +2648,6 @@ static int usbdux_attach_common(struct comedi_device *dev, /* allocate space for the subdevices */ ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret < 0) { - dev_err(&udev->interface->dev, - "comedi%d: error alloc space for subdev\n", dev->minor); up(&udev->sem); return ret; } diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 262556ebc4db..660dd4ee51e0 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1669,8 +1669,6 @@ static int usbduxfast_attach(struct comedi_device *dev, /* allocate space for the subdevices */ ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) { - printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for " - "subdev\n", dev->minor); up(&(usbduxfastsub[index].sem)); up(&start_stop_sem); return ret; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 87c613e88892..f37e96c80b91 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2693,8 +2693,6 @@ static int usbduxsigma_attach(struct comedi_device *dev, /* allocate space for the subdevices */ ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret < 0) { - dev_err(&udev->interface->dev, - "comedi%d: no space for subdev\n", dev->minor); up(&udev->sem); up(&start_stop_sem); return ret; -- GitLab From eea6838b1206b0ac90110f1a6f58e101aa496e99 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:59:15 -0700 Subject: [PATCH 1303/6849] staging: comedi: remove the "Allocate the subdevice..." comments These comments are redundant. The function name 'comedi_alloc_subdevices' provides this information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 1 - drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c | 1 - drivers/staging/comedi/drivers/adq12b.c | 4 ---- drivers/staging/comedi/drivers/amplc_pci224.c | 1 - drivers/staging/comedi/drivers/amplc_pci230.c | 5 +---- drivers/staging/comedi/drivers/c6xdigio.c | 1 - drivers/staging/comedi/drivers/cb_pcidas.c | 3 --- drivers/staging/comedi/drivers/cb_pcidda.c | 3 --- drivers/staging/comedi/drivers/cb_pcidio.c | 4 ---- drivers/staging/comedi/drivers/cb_pcimdas.c | 4 ---- drivers/staging/comedi/drivers/cb_pcimdda.c | 4 ---- drivers/staging/comedi/drivers/comedi_bond.c | 4 ---- drivers/staging/comedi/drivers/dmm32at.c | 4 ---- drivers/staging/comedi/drivers/dt9812.c | 1 - drivers/staging/comedi/drivers/ke_counter.c | 1 - drivers/staging/comedi/drivers/me4000.c | 5 ----- drivers/staging/comedi/drivers/mpc624.c | 1 - drivers/staging/comedi/drivers/pcmda12.c | 7 ------- drivers/staging/comedi/drivers/pcmmio.c | 7 +------ drivers/staging/comedi/drivers/pcmuio.c | 8 +------- drivers/staging/comedi/drivers/rtd520.c | 4 ---- drivers/staging/comedi/drivers/s526.c | 4 ---- drivers/staging/comedi/drivers/skel.c | 4 ---- drivers/staging/comedi/drivers/ssv_dnp.c | 3 --- drivers/staging/comedi/drivers/usbdux.c | 1 - drivers/staging/comedi/drivers/usbduxfast.c | 1 - drivers/staging/comedi/drivers/usbduxsigma.c | 1 - 27 files changed, 3 insertions(+), 84 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 274990a7cd3f..46c590b1ad96 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -1686,7 +1686,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->s_BoardInfos.ui_Address = io_addr[2]; #endif } else { - /* Update-0.7.57->0.7.68dev->n_subdevices = 7; */ n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index 9632ca182d25..aa390b01475b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -62,7 +62,6 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) int ret = 0; int n_subdevices = 9; - /* Update-0.7.57->0.7.68dev->n_subdevices = 9; */ ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret < 0) return; diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index ca8892e83db1..afc6815bcc36 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -267,10 +267,6 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->last_channel = -1; devpriv->last_range = -1; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index c64e32821c4d..1392406d99f0 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1379,7 +1379,6 @@ static int pci224_attach_common(struct comedi_device *dev, outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); - /* Allocate subdevices. There is only one! */ ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index e6598cafb39a..52f3cb8fb2d1 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2839,10 +2839,7 @@ static int pci230_attach_common(struct comedi_device *dev, dev_dbg(dev->class_dev, "registered irq %u\n", devpriv->pci_dev->irq); } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ + if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 72b000fad609..5fa344b269fd 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -433,7 +433,6 @@ static int c6xdigio_attach(struct comedi_device *dev, dev->iobase = iobase; dev->board_name = "c6xdigio"; - /* 3 subdevices with encoder_init write */ result = comedi_alloc_subdevices(dev, 2); if (result < 0) return result; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 435f3aaedf88..e1bd99a950e4 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -614,9 +614,6 @@ found: /* Initialize dev->board_name */ dev->board_name = thisboard->name; -/* - * Allocate the subdevice structures. - */ if (comedi_alloc_subdevices(dev, 7) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 4ab3584365e2..fedaf55af03d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -333,9 +333,6 @@ found: */ dev->board_name = thisboard->name; -/* - * Allocate the subdevice structures. - */ if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 56c1d09188aa..f2fff4f2080b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -177,10 +177,6 @@ found: pci_resource_start(devpriv->pci_dev, pcidio_boards[index].dioregs_badrindex); -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, thisboard->n_8255) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 6acb3199e6f3..0ada8b91b315 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -269,10 +269,6 @@ found: /* Initialize dev->board_name */ dev->board_name = thisboard->name; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index abb6008da4df..b401aec89348 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -236,10 +236,6 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) */ dev->board_name = thisboard->name; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 2) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index d56eec48e4c8..96e5b35f4d7c 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -358,10 +358,6 @@ static int bonding_attach(struct comedi_device *dev, */ dev->board_name = devpriv->name; - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 40d7befec5ea..6b637a2a48c7 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -371,10 +371,6 @@ static int dmm32at_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct dmm32at_private)) < 0) return -ENOMEM; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 56af2f28f98d..678fa502a716 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -1035,7 +1035,6 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->serial = it->options[0]; - /* Allocate subdevices */ if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index bcb1eb49a1f7..7c256f4f32d1 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -189,7 +189,6 @@ found: io_base = pci_resource_start(pci_device, 0); dev->iobase = io_base; - /* allocate the subdevice structures */ error = comedi_alloc_subdevices(dev, 1); if (error < 0) return error; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 39100ddddef8..4adb206ebd93 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -2190,11 +2190,6 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (result) return result; - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. It relies on - * n_subdevices being set correctly. - */ if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 48ba6b9f9430..975033653f0c 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -348,7 +348,6 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; } - /* Subdevices structures */ if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index e1b30cc5d733..87faa0381976 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -190,13 +190,6 @@ static int pcmda12_attach(struct comedi_device *dev, devpriv->simultaneous_xfer_mode = it->options[1]; - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the - * 96-channel version of the board. - */ if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index abaf6c758baf..31053034b073 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1071,12 +1071,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->minor); return -ENOMEM; } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) - */ + if (comedi_alloc_subdevices(dev, n_subdevs) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index e4153bd27172..33ab4c63b3dc 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -800,13 +800,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n"); return -ENOMEM; } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the - * 96-channel version of the board. - */ + if (comedi_alloc_subdevices(dev, n_subdevs) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 7d248a7685b2..445333b2413e 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1999,10 +1999,6 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Show board configuration */ printk(KERN_INFO "%s:", dev->board_name); - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index dbbff70dc0ca..6a30537987c6 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -774,10 +774,6 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct s526_private)) < 0) return -ENOMEM; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 4) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 16947c8b8803..ca10b1a98153 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -233,10 +233,6 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct skel_private)) < 0) return -ENOMEM; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ if (comedi_alloc_subdevices(dev, 3) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 5eaef8434e09..130e4bd5c640 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -197,9 +197,6 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) return -ENOMEM; - /* Allocate the subdevice structures. alloc_subdevice() is a */ - /* convenient macro defined in comedidev.h. */ - if (comedi_alloc_subdevices(dev, 1) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 79df200bb6ee..a6cf13459c61 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2645,7 +2645,6 @@ static int usbdux_attach_common(struct comedi_device *dev, n_subdevs = 4; } - /* allocate space for the subdevices */ ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret < 0) { up(&udev->sem); diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 660dd4ee51e0..f7d4f56c1688 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1666,7 +1666,6 @@ static int usbduxfast_attach(struct comedi_device *dev, dev->board_name = BOARDNAME; - /* allocate space for the subdevices */ ret = comedi_alloc_subdevices(dev, 1); if (ret < 0) { up(&(usbduxfastsub[index].sem)); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index f37e96c80b91..f23fad957e5e 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2690,7 +2690,6 @@ static int usbduxsigma_attach(struct comedi_device *dev, n_subdevs = 3; } - /* allocate space for the subdevices */ ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret < 0) { up(&udev->sem); -- GitLab From 8b6c56949ffa83dbc2a6e8fa3f98b10a19372207 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:59:33 -0700 Subject: [PATCH 1304/6849] staging: comedi: propogate error code from comedi_alloc_subdevices comedi_alloc_subdevices can fail with -EINVAL or -ENOMEM. When it does fail make sure to pass the proper error code back. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 2 +- drivers/staging/comedi/drivers/acl7225b.c | 6 ++++-- drivers/staging/comedi/drivers/addi-data/addi_common.c | 2 +- .../staging/comedi/drivers/addi-data/hwdrv_APCI1710.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 5 +++-- drivers/staging/comedi/drivers/adl_pci7230.c | 6 ++++-- drivers/staging/comedi/drivers/adl_pci7296.c | 5 +++-- drivers/staging/comedi/drivers/adl_pci7432.c | 6 ++++-- drivers/staging/comedi/drivers/adl_pci8164.c | 6 ++++-- drivers/staging/comedi/drivers/adl_pci9111.c | 2 +- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- drivers/staging/comedi/drivers/adq12b.c | 6 ++++-- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- drivers/staging/comedi/drivers/aio_aio12_8.c | 6 ++++-- drivers/staging/comedi/drivers/aio_iiro_16.c | 6 ++++-- drivers/staging/comedi/drivers/amplc_dio200.c | 4 +++- drivers/staging/comedi/drivers/amplc_pc236.c | 2 +- drivers/staging/comedi/drivers/amplc_pc263.c | 2 +- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 6 ++++-- drivers/staging/comedi/drivers/c6xdigio.c | 2 +- drivers/staging/comedi/drivers/cb_das16_cs.c | 5 +++-- drivers/staging/comedi/drivers/cb_pcidas.c | 6 ++++-- drivers/staging/comedi/drivers/cb_pcidas64.c | 6 ++++-- drivers/staging/comedi/drivers/cb_pcidda.c | 7 ++++--- drivers/staging/comedi/drivers/cb_pcidio.c | 6 ++++-- drivers/staging/comedi/drivers/cb_pcimdas.c | 6 ++++-- drivers/staging/comedi/drivers/cb_pcimdda.c | 5 +++-- drivers/staging/comedi/drivers/comedi_bond.c | 6 ++++-- drivers/staging/comedi/drivers/comedi_parport.c | 3 ++- drivers/staging/comedi/drivers/comedi_test.c | 6 ++++-- drivers/staging/comedi/drivers/contec_pci_dio.c | 6 ++++-- drivers/staging/comedi/drivers/daqboard2000.c | 4 ++-- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/das16.c | 2 +- drivers/staging/comedi/drivers/das16m1.c | 2 +- drivers/staging/comedi/drivers/das1800.c | 5 +++-- drivers/staging/comedi/drivers/das6402.c | 2 +- drivers/staging/comedi/drivers/das800.c | 6 ++++-- drivers/staging/comedi/drivers/dmm32at.c | 5 +++-- drivers/staging/comedi/drivers/dt2801.c | 8 +++----- drivers/staging/comedi/drivers/dt2811.c | 2 +- drivers/staging/comedi/drivers/dt2814.c | 2 +- drivers/staging/comedi/drivers/dt2815.c | 7 +++++-- drivers/staging/comedi/drivers/dt2817.c | 2 +- drivers/staging/comedi/drivers/dt282x.c | 2 +- drivers/staging/comedi/drivers/dt3000.c | 2 +- drivers/staging/comedi/drivers/dt9812.c | 6 ++++-- drivers/staging/comedi/drivers/dyna_pci10xx.c | 6 ++++-- drivers/staging/comedi/drivers/fl512.c | 6 ++++-- drivers/staging/comedi/drivers/gsc_hpdi.c | 6 ++++-- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/ii_pci20kc.c | 2 +- drivers/staging/comedi/drivers/jr3_pci.c | 4 ++-- drivers/staging/comedi/drivers/ke_counter.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 5 +++-- drivers/staging/comedi/drivers/me_daq.c | 3 +-- drivers/staging/comedi/drivers/mpc624.c | 6 ++++-- drivers/staging/comedi/drivers/mpc8260cpm.c | 6 ++++-- drivers/staging/comedi/drivers/multiq3.c | 3 ++- drivers/staging/comedi/drivers/ni_6527.c | 2 +- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 5 +++-- drivers/staging/comedi/drivers/ni_670x.c | 5 +++-- drivers/staging/comedi/drivers/ni_at_a2150.c | 6 ++++-- drivers/staging/comedi/drivers/ni_at_ao.c | 6 ++++-- drivers/staging/comedi/drivers/ni_atmio16d.c | 2 +- drivers/staging/comedi/drivers/ni_daq_700.c | 6 ++++-- drivers/staging/comedi/drivers/ni_daq_dio24.c | 6 ++++-- drivers/staging/comedi/drivers/ni_labpc.c | 6 ++++-- drivers/staging/comedi/drivers/ni_mio_common.c | 6 ++++-- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/pcl711.c | 2 +- drivers/staging/comedi/drivers/pcl724.c | 2 +- drivers/staging/comedi/drivers/pcl725.c | 6 ++++-- drivers/staging/comedi/drivers/pcl726.c | 2 +- drivers/staging/comedi/drivers/pcl730.c | 6 ++++-- drivers/staging/comedi/drivers/pcl812.c | 2 +- drivers/staging/comedi/drivers/pcl816.c | 2 +- drivers/staging/comedi/drivers/pcl818.c | 2 +- drivers/staging/comedi/drivers/pcm3724.c | 2 +- drivers/staging/comedi/drivers/pcm3730.c | 6 ++++-- drivers/staging/comedi/drivers/pcmad.c | 2 +- drivers/staging/comedi/drivers/pcmda12.c | 6 ++++-- drivers/staging/comedi/drivers/pcmmio.c | 6 ++++-- drivers/staging/comedi/drivers/pcmuio.c | 6 ++++-- drivers/staging/comedi/drivers/poc.c | 7 +++++-- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 2 +- drivers/staging/comedi/drivers/rtd520.c | 6 +++--- drivers/staging/comedi/drivers/rti800.c | 2 +- drivers/staging/comedi/drivers/rti802.c | 9 ++++++--- drivers/staging/comedi/drivers/s526.c | 6 ++++-- drivers/staging/comedi/drivers/s626.c | 5 +++-- drivers/staging/comedi/drivers/serial2002.c | 6 ++++-- drivers/staging/comedi/drivers/skel.c | 6 ++++-- drivers/staging/comedi/drivers/ssv_dnp.c | 6 ++++-- drivers/staging/comedi/drivers/unioxx5.c | 6 ++++-- drivers/staging/comedi/drivers/usbdux.c | 2 +- drivers/staging/comedi/drivers/usbduxfast.c | 2 +- drivers/staging/comedi/drivers/usbduxsigma.c | 2 +- drivers/staging/comedi/drivers/vmk80xx.c | 6 ++++-- 103 files changed, 269 insertions(+), 168 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 64b00547228b..502bde8c22c1 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -389,7 +389,7 @@ static int dev_8255_attach(struct comedi_device *dev, } ret = comedi_alloc_subdevices(dev, i); - if (ret < 0) + if (ret) return ret; printk(KERN_INFO "comedi%d: 8255:", dev->minor); diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index 3c39148c64cb..0bf552581c5f 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -68,6 +68,7 @@ static int acl7225b_attach(struct comedi_device *dev, const struct boardtype *board = comedi_board(dev); struct comedi_subdevice *s; int iobase, iorange; + int ret; iobase = it->options[0]; iorange = board->io_range; @@ -82,8 +83,9 @@ static int acl7225b_attach(struct comedi_device *dev, dev->iobase = iobase; dev->irq = 0; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; /* Relays outputs */ diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 46c590b1ad96..a5aa673335ef 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -1688,7 +1688,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } else { n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; /* Allocate and Initialise AI Subdevice Structures */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index aa390b01475b..595238feaf42 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -63,7 +63,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) int n_subdevices = 9; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return; /* Allocate and Initialise Timer Subdevice Structures */ diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 7d26d45d0753..98b373063445 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -301,8 +301,9 @@ static int pci6208_attach(struct comedi_device *dev, dev->iobase = io_base; dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + retval = comedi_alloc_subdevices(dev, 2); + if (retval) + return retval; s = dev->subdevices + 0; /* analog output subdevice */ diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index 5a6e6c11e7fe..62fdf7f63703 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -108,6 +108,7 @@ static int adl_pci7230_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; + int ret; printk(KERN_INFO "comedi%d: adl_pci7230\n", dev->minor); @@ -116,8 +117,9 @@ static int adl_pci7230_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci7230_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; devpriv->pci_dev = adl_pci7230_find_pci(dev, it); if (!devpriv->pci_dev) diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index fd9b33afd458..58deb60f2b8c 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -92,8 +92,9 @@ static int adl_pci7296_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci7296_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; devpriv->pci_dev = adl_pci7296_find_pci(dev, it); if (!devpriv->pci_dev) diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index 4976a70fb1e4..aabf4183aaf5 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -117,6 +117,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; + int ret; printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); @@ -125,8 +126,9 @@ static int adl_pci7432_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci7432_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; devpriv->pci_dev = adl_pci7432_find_pci(dev, it); if (!devpriv->pci_dev) diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 78169f7d06ac..181137546133 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -252,6 +252,7 @@ static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; + int ret; printk(KERN_INFO "comedi: attempt to attach...\n"); printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); @@ -261,8 +262,9 @@ static int adl_pci8164_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; devpriv->pci_dev = adl_pci8164_find_pci(dev, it); if (!devpriv->pci_dev) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index cc179466dce0..4f2cea8e11f7 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1318,7 +1318,7 @@ static int pci9111_attach(struct comedi_device *dev, /* TODO: Add external multiplexer setup (according to option[2]). */ error = comedi_alloc_subdevices(dev, 4); - if (error < 0) + if (error) return error; subdevice = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index ebd8b8ec8c31..9a7b6a5797bb 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2269,7 +2269,7 @@ static int pci9118_attach(struct comedi_device *dev, /* Enable parity check for parity error */ ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index afc6815bcc36..f7bb14589c9b 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -224,6 +224,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase; int unipolar, differential; + int ret; iobase = it->options[0]; unipolar = it->options[1]; @@ -267,8 +268,9 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->last_channel = -1; devpriv->last_range = -1; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index be3fc4dd8859..60a50adcd715 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1434,7 +1434,7 @@ static int pci1710_attach(struct comedi_device *dev, n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; pci1710_reset(dev); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index c14ad35cb835..d37c14da5ec6 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -366,7 +366,7 @@ static int pci1723_attach(struct comedi_device *dev, n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; pci1723_reset(dev); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 0fc4f858acca..942dc777a0e6 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1157,7 +1157,7 @@ static int pci_dio_attach(struct comedi_device *dev, } ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; subdev = 0; diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 60466c81e2a9..f7d453f8fe33 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -168,6 +168,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, const struct aio12_8_boardtype *board = comedi_board(dev); int iobase; struct comedi_subdevice *s; + int ret; iobase = it->options[0]; if (!request_region(iobase, 24, "aio_aio12_8")) { @@ -182,8 +183,9 @@ static int aio_aio12_8_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct aio12_8_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 7d161d6739ae..8059cefe5b8c 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -107,6 +107,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev, const struct aio_iiro_16_board *board = comedi_board(dev); int iobase; struct comedi_subdevice *s; + int ret; printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor); @@ -124,8 +125,9 @@ static int aio_iiro_16_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct aio_iiro_16_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; s = dev->subdevices + 0; s->type = COMEDI_SUBD_DIO; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 17d3489b7f98..c67b09ff37d7 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1273,9 +1273,11 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, devpriv->intr_sd = -1; dev->iobase = iobase; dev->board_name = thisboard->name; + ret = comedi_alloc_subdevices(dev, layout->n_subdevs); - if (ret < 0) + if (ret) return ret; + for (n = 0; n < dev->n_subdevices; n++) { s = &dev->subdevices[n]; switch (layout->sdtype[n]) { diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 6205985806f5..e55321ec5ae8 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -456,7 +456,7 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase, dev->iobase = iobase; ret = comedi_alloc_subdevices(dev, 2); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index f1d68dff1ab0..4f15bfd80719 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -228,7 +228,7 @@ static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase) dev->iobase = iobase; ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 1392406d99f0..b87e10ddf239 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1380,7 +1380,7 @@ static int pci224_attach_common(struct comedi_device *dev, dev->iobase + PCI224_DACCON); ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 52f3cb8fb2d1..3d7f2cda980a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2840,8 +2840,10 @@ static int pci230_attach_common(struct comedi_device *dev, devpriv->pci_dev->irq); } - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + rc = comedi_alloc_subdevices(dev, 3); + if (rc) + return rc; + s = dev->subdevices + 0; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 5fa344b269fd..41ed8576f301 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -434,7 +434,7 @@ static int c6xdigio_attach(struct comedi_device *dev, dev->board_name = "c6xdigio"; result = comedi_alloc_subdevices(dev, 2); - if (result < 0) + if (result) return result; /* Make sure that PnP ports get activated */ diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 9aa11c15497f..031007791d29 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -195,8 +195,9 @@ static int das16cs_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = dev->subdevices + 0; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index e1bd99a950e4..2ca3fa0fc776 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -533,6 +533,7 @@ static int cb_pcidas_attach(struct comedi_device *dev, struct pci_dev *pcidev = NULL; int index; int i; + int ret; /* * Allocate the private structure area. @@ -614,8 +615,9 @@ found: /* Initialize dev->board_name */ dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 7) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 7); + if (ret) + return ret; s = dev->subdevices + 0; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 6b2f153980a9..3aab75b5217d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1344,9 +1344,11 @@ static int setup_subdevices(struct comedi_device *dev) struct comedi_subdevice *s; void __iomem *dio_8255_iobase; int i; + int ret; - if (comedi_alloc_subdevices(dev, 10) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 10); + if (ret) + return ret; s = dev->subdevices + 0; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index fedaf55af03d..0572dc6fd5ca 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -265,7 +265,7 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_subdevice *s; struct pci_dev *pcidev = NULL; int index; - + int ret; /* * Allocate the private structure area. @@ -333,8 +333,9 @@ found: */ dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; /* analog output subdevice */ diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index f2fff4f2080b..0186737c1ee1 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -116,6 +116,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pci_dev *pcidev = NULL; int index; int i; + int ret; /* * Allocate the private structure area. alloc_private() is a @@ -177,8 +178,9 @@ found: pci_resource_start(devpriv->pci_dev, pcidio_boards[index].dioregs_badrindex); - if (comedi_alloc_subdevices(dev, thisboard->n_8255) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, thisboard->n_8255); + if (ret) + return ret; for (i = 0; i < thisboard->n_8255; i++) { subdev_8255_init(dev, dev->subdevices + i, diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 0ada8b91b315..b99a451bab9e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -187,6 +187,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_subdevice *s; struct pci_dev *pcidev = NULL; int index; + int ret; /* int i; */ /* @@ -269,8 +270,9 @@ found: /* Initialize dev->board_name */ dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; /* dev->read_subdev=s; */ diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index b401aec89348..a80146133c04 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -236,8 +236,9 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) */ dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + err = comedi_alloc_subdevices(dev, 2); + if (err) + return err; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 96e5b35f4d7c..0260ddc05645 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -336,6 +336,7 @@ static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; + int ret; LOG_MSG("comedi%d\n", dev->minor); @@ -358,8 +359,9 @@ static int bonding_attach(struct comedi_device *dev, */ dev->board_name = devpriv->name; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; s = dev->subdevices + 0; s->type = COMEDI_SUBD_DIO; diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index c9a725fc61f2..589d12f68067 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -316,8 +316,9 @@ static int parport_attach(struct comedi_device *dev, dev->board_name = "parport"; ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; + ret = alloc_private(dev, sizeof(struct parport_private)); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 004da30d7d2b..523a809708b7 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -432,6 +432,7 @@ static int waveform_attach(struct comedi_device *dev, int amplitude = it->options[0]; int period = it->options[1]; int i; + int ret; dev->board_name = board->name; @@ -447,8 +448,9 @@ static int waveform_attach(struct comedi_device *dev, devpriv->uvolt_amplitude = amplitude; devpriv->usec_period = period; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; s = dev->subdevices + 0; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index a5bad1bd6dcd..79854b1ac243 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -107,6 +107,7 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev = NULL; struct comedi_subdevice *s; + int ret; printk("comedi%d: contec: ", dev->minor); @@ -115,8 +116,9 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct contec_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; for_each_pci_dev(pcidev) { if (pcidev->vendor == PCI_VENDOR_ID_CONTEC && diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index dbd0472bc7e2..9ecf1a468567 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -773,8 +773,8 @@ static int daqboard2000_attach(struct comedi_device *dev, return -ENOMEM; result = comedi_alloc_subdevices(dev, 3); - if (result < 0) - goto out; + if (result) + return result; readl(devpriv->plx + 0x6c); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 1dea21a33a27..c4627a6b62be 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -835,7 +835,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, 6); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 6a8a7eb1ae9c..0c6ad1067055 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1265,7 +1265,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->timer_mode = timer_mode ? 1 : 0; ret = comedi_alloc_subdevices(dev, 5); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index eafd6b59a483..f3fba13432bb 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -647,7 +647,7 @@ static int das16m1_attach(struct comedi_device *dev, } ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 12d736a6e38d..af60e5d5b8a3 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1644,8 +1644,9 @@ static int das1800_attach(struct comedi_device *dev, return -ENOMEM; } - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + retval = comedi_alloc_subdevices(dev, 4); + if (retval) + return retval; /* analog input subdevice */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 2039b6c11590..22a9b3448e3f 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -308,7 +308,7 @@ static int das6402_attach(struct comedi_device *dev, return ret; ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; /* ai subdevice */ diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 6263f532e5da..81698b1fd0da 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -465,6 +465,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int irq = it->options[1]; unsigned long irq_flags; int board; + int ret; dev_info(dev->hw_dev, "comedi%d: das800: io 0x%lx\n", dev->minor, iobase); @@ -510,8 +511,9 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; /* analog input subdevice */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 6b637a2a48c7..2b60cf816b6e 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -371,8 +371,9 @@ static int dmm32at_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct dmm32at_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 35ce076237a4..5afbf8a4b030 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -626,15 +626,15 @@ havetype: printk("dt2801: %s at port 0x%lx", boardtype.name, iobase); n_ai_chans = probe_number_of_ai_chans(dev); - printk(" (ai channels = %d)", n_ai_chans); + printk(" (ai channels = %d)\n", n_ai_chans); ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) goto out; ret = alloc_private(dev, sizeof(struct dt2801_private)); if (ret < 0) - goto out; + return ret; dev->board_name = boardtype.name; @@ -688,8 +688,6 @@ havetype: ret = 0; out: - printk("\n"); - return ret; } diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 6ff610d1b0f9..91fbf4a7a2af 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -466,7 +466,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct dt2811_private)); diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 876d5cbdbe4a..2e39ebe36fb5 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -339,7 +339,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) } ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct dt2814_private)); diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 33ad1fa90762..45b20bee4369 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -166,6 +166,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) int i; const struct comedi_lrange *current_range_type, *voltage_range_type; unsigned long iobase; + int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase); @@ -177,8 +178,10 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "dt2815"; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; + if (alloc_private(dev, sizeof(struct dt2815_private)) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 665db07aeb84..9282ca55f637 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -138,7 +138,7 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "dt2817"; ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index f11d1fdfcae2..9c0a0df7dff2 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1269,7 +1269,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; ret = comedi_alloc_subdevices(dev, 3); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 10415b218b5c..9828fb1e3365 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -883,7 +883,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->irq = devpriv->pci_dev->irq; ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; s = dev->subdevices; diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 678fa502a716..40821c7303ea 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -1021,6 +1021,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int i; struct comedi_subdevice *s; + int ret; dev->board_name = "dt9812"; @@ -1035,8 +1036,9 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->serial = it->options[0]; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; /* digital input subdevice */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index bab2e37967ed..9c855e25275c 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -246,6 +246,7 @@ static int dyna_pci10xx_attach(struct comedi_device *dev, struct pci_dev *pcidev; unsigned int opt_bus, opt_slot; int board_index, i; + int ret; mutex_lock(&start_stop_sem); @@ -329,9 +330,10 @@ found: devpriv->BADR4 = pci_resource_start(pcidev, 4); devpriv->BADR5 = pci_resource_start(pcidev, 5); - if (comedi_alloc_subdevices(dev, 4) < 0) { + ret = comedi_alloc_subdevices(dev, 4); + if (ret) { mutex_unlock(&start_stop_sem); - return -ENOMEM; + return ret; } /* analog input */ diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 7218a9b2cda9..d1da80976f84 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -111,6 +111,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { unsigned long iobase; + int ret; /* pointer to the subdevice: Analog in, Analog out, (not made ->and Digital IO) */ @@ -131,8 +132,9 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_DEBUG "malloc ok\n"); #endif - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; /* * this if the definitions of the supdevices, 2 have been defined diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index b103cfbf3274..79f580841dee 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -430,9 +430,11 @@ static void init_plx9080(struct comedi_device *dev) static int setup_subdevices(struct comedi_device *dev) { struct comedi_subdevice *s; + int ret; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; s = dev->subdevices + 0; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 06c66afc6aa1..544bed870470 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -904,7 +904,7 @@ static int icp_multi_attach(struct comedi_device *dev, n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; icp_multi_reset(dev); diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 9c1165791078..bea3d03bae2e 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -203,7 +203,7 @@ static int pci20xxx_attach(struct comedi_device *dev, union pci20xxx_subdev_private *sdp; ret = comedi_alloc_subdevices(dev, 1 + PCI20000_MODULES); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct pci20xxx_private)); diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 182643bed561..3c043e535506 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -827,8 +827,8 @@ static int jr3_pci_attach(struct comedi_device *dev, return -ENOMEM; result = comedi_alloc_subdevices(dev, devpriv->n_channels); - if (result < 0) - goto out; + if (result) + return result; dev->open = jr3_pci_open; for (i = 0; i < devpriv->n_channels; i++) { diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 7c256f4f32d1..019e91a9f143 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -190,7 +190,7 @@ found: dev->iobase = io_base; error = comedi_alloc_subdevices(dev, 1); - if (error < 0) + if (error) return error; subdevice = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 4adb206ebd93..aae01f10b1c3 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -2190,8 +2190,9 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (result) return result; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + result = comedi_alloc_subdevices(dev, 4); + if (result) + return result; /*========================================================================= Analog input subdevice diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 231b29413eaa..ae3b0469541e 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -761,9 +761,8 @@ found: me_reset(dev); - /* device driver capabilities */ error = comedi_alloc_subdevices(dev, 3); - if (error < 0) + if (error) return error; subdevice = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 975033653f0c..b928b6763cd5 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -285,6 +285,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase; + int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); @@ -348,8 +349,9 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; } - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; s = dev->subdevices + 0; s->type = COMEDI_SUBD_AI; diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c index 13110510d7fe..a6311b11831b 100644 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ b/drivers/staging/comedi/drivers/mpc8260cpm.c @@ -121,6 +121,7 @@ static int mpc8260cpm_attach(struct comedi_device *dev, { struct comedi_subdevice *s; int i; + int ret; printk("comedi%d: mpc8260cpm: ", dev->minor); @@ -131,8 +132,9 @@ static int mpc8260cpm_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret =comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; for (i = 0; i < 4; i++) { s = dev->subdevices + i; diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index 00d497c270ae..b1bbd0255fbc 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -255,8 +255,9 @@ static int multiq3_attach(struct comedi_device *dev, else printk(KERN_WARNING "comedi%d: no irq\n", dev->minor); dev->board_name = "multiq3"; + result = comedi_alloc_subdevices(dev, 5); - if (result < 0) + if (result) return result; result = alloc_private(dev, sizeof(struct multiq3_private)); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 89fee6fdcf61..b60ab4848b64 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -398,7 +398,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) readb(devpriv->mite->daq_io_addr + ID_Register)); ret = comedi_alloc_subdevices(dev, 3); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index a49dceac65bc..ac7c74be08a2 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -679,7 +679,7 @@ static int ni_65xx_attach(struct comedi_device *dev, readb(private(dev)->mite->daq_io_addr + ID_Register)); ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 8c6a6ba9d4b9..5391a3949da1 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1093,8 +1093,9 @@ static int ni_660x_attach(struct comedi_device *dev, printk(KERN_INFO " %s ", dev->board_name); - if (comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); + if (ret) + return ret; s = dev->subdevices + 0; /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 45a03e64549a..5dffe6ce4738 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -202,8 +202,9 @@ static int ni_670x_attach(struct comedi_device *dev, dev->irq = mite_irq(devpriv->mite); printk(KERN_INFO " %s", dev->board_name); - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; s = dev->subdevices + 0; /* analog output subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 9d1a0f745bf8..b53a4286f8cb 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -755,6 +755,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int dma = it->options[2]; static const int timeout = 2000; int i; + int ret; printk("comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name, iobase); @@ -826,8 +827,9 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_ptr = a2150_boards + a2150_probe(dev); dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; /* analog input subdevice */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 03a4d736b454..1c3f3222d496 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -337,6 +337,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase; int ao_unipolar; + int ret; iobase = it->options[0]; if (iobase == 0) @@ -356,8 +357,9 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct atao_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = dev->subdevices + 0; /* analog output subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 37ff6fc86157..95bee84b78ae 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -710,7 +710,7 @@ static int atmio16d_attach(struct comedi_device *dev, dev->board_name = board->name; ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct atmio16d_private)); diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 8860207e88d7..53b0173aa2b2 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -364,6 +364,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int irq = 0; #endif struct pcmcia_device *link; + int ret; /* allocate and initialize dev->private */ if (alloc_private(dev, sizeof(struct dio700_private)) < 0) @@ -409,8 +410,9 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; /* DAQCard-700 dio */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 36c0c62382ed..e27cae0eb8a2 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -116,6 +116,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int irq = 0; #endif struct pcmcia_device *link; + int ret; /* allocate and initialize dev->private */ if (alloc_private(dev, sizeof(struct dio24_private)) < 0) @@ -158,8 +159,9 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; /* 8255 dio */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index a92570f5a7c5..ab8b787c78bb 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -536,6 +536,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, unsigned long dma_flags; #endif short lsb, msb; + int ret; printk(KERN_ERR "comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name, @@ -622,8 +623,9 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 5) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 5); + if (ret) + return ret; /* analog input subdevice */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 4261e929869f..1f796b9361b2 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4406,14 +4406,16 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned j; enum ni_gpct_variant counter_variant; + int ret; if (boardtype.n_aochan > MAX_N_AO_CHAN) { printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n"); return -EINVAL; } - if (comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES); + if (ret) + return ret; /* analog input subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 77ef312f657e..cba045965167 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1249,7 +1249,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) n_subdevices = 1; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; if (!this_board->is_diodaq) { diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 35b95105a749..d5fa6f28eb1f 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -519,7 +519,7 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->irq = irq; ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct pcl711_private)); diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 698c9004c74e..c8fe23ca899d 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -157,7 +157,7 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) n_subdevices = 4; /* PCL-724 in 96 DIO configuration */ ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; for (i = 0; i < dev->n_subdevices; i++) { diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index d7ba336ce031..8edbefd7c43b 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -52,6 +52,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase; + int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); @@ -63,8 +64,9 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->irq = 0; - if (comedi_alloc_subdevices(dev, 2) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; s = dev->subdevices + 0; /* do */ diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index e756a3033767..b2e73cda2957 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -293,7 +293,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("\n"); ret = comedi_alloc_subdevices(dev, 3); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index e258bcebf198..3cba79a219b8 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -72,6 +72,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; + int ret; iobase = it->options[0]; iorange = board->io_range; @@ -85,8 +86,9 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->irq = 0; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = dev->subdevices + 0; /* Isolated do */ diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 128f5b644878..0a4074af8a60 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1383,7 +1383,7 @@ no_dma: n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) { + if (ret) { free_resources(dev); return ret; } diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 37cedbc47a43..c3ee6d69b9a6 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -1195,7 +1195,7 @@ no_dma: */ ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index a4c2870562fb..66b2570fb24e 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1779,7 +1779,7 @@ no_rtc: no_dma: ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index d755b406a6f1..62c22ccfb780 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -259,7 +259,7 @@ static int pcm3724_attach(struct comedi_device *dev, n_subdevices = board->numofports; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret < 0) + if (ret) return ret; for (i = 0; i < dev->n_subdevices; i++) { diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index 48a21bd679fd..b48f7aa7520b 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -59,6 +59,7 @@ static int pcm3730_attach(struct comedi_device *dev, { struct comedi_subdevice *s; unsigned long iobase; + int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase); @@ -71,8 +72,9 @@ static int pcm3730_attach(struct comedi_device *dev, dev->iobase = dev->iobase; dev->irq = 0; - if (comedi_alloc_subdevices(dev, 6) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 6); + if (ret) + return ret; s = dev->subdevices + 0; s->type = COMEDI_SUBD_DO; diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 00b0f2a6894c..54d19c943967 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -118,7 +118,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct pcmad_priv_struct)); diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 87faa0381976..291ce7c1bdb1 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -165,6 +165,7 @@ static int pcmda12_attach(struct comedi_device *dev, const struct pcmda12_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; + int ret; iobase = it->options[0]; printk(KERN_INFO @@ -190,8 +191,9 @@ static int pcmda12_attach(struct comedi_device *dev, devpriv->simultaneous_xfer_mode = it->options[1]; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; s = dev->subdevices; s->private = NULL; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 31053034b073..0e64d848a2a8 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1020,6 +1020,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) thisasic_chanct = 0; unsigned long iobase; unsigned int irq[MAX_ASICS]; + int ret; iobase = it->options[0]; irq[0] = it->options[1]; @@ -1072,8 +1073,9 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; } - if (comedi_alloc_subdevices(dev, n_subdevs) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, n_subdevs); + if (ret) + return ret; /* First, AI */ sdev_no = 0; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 33ab4c63b3dc..48565fe9efcc 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -754,6 +754,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; unsigned long iobase; unsigned int irq[MAX_ASICS]; + int ret; iobase = it->options[0]; irq[0] = it->options[1]; @@ -801,8 +802,9 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; } - if (comedi_alloc_subdevices(dev, n_subdevs) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, n_subdevs); + if (ret) + return ret; port = 0; asic = 0; diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 1e954f9c4165..a129ccace93d 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -139,6 +139,7 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase; unsigned int iosize; + int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, @@ -160,8 +161,10 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; + if (alloc_private(dev, sizeof(unsigned int) * board->n_chan) < 0) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 38a13ba38e18..a029147c9b69 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -872,7 +872,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = local->link->resource[0]->start; ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n", diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 445333b2413e..c3c8097acd02 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1999,9 +1999,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Show board configuration */ printk(KERN_INFO "%s:", dev->board_name); - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = dev->subdevices + 0; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index a80f6302375b..966ac2ccc877 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -349,7 +349,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; ret = comedi_alloc_subdevices(dev, 4); - if (ret < 0) + if (ret) return ret; ret = alloc_private(dev, sizeof(struct rti800_private)); diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 1aacf3f6e3f5..fc16508181d4 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -92,6 +92,7 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int i; unsigned long iobase; + int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase); @@ -103,10 +104,12 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "rti802"; - if (comedi_alloc_subdevices(dev, 1) < 0 - || alloc_private(dev, sizeof(struct rti802_private))) { + if (alloc_private(dev, sizeof(struct rti802_private))) return -ENOMEM; - } + + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; s = dev->subdevices; /* ao subdevice */ diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 6a30537987c6..141bc9e881c9 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -743,6 +743,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int iobase; int i, n; + int ret; /* short value; */ /* int subdev_channel = 0; */ union cmReg cmReg; @@ -774,8 +775,9 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct s526_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 4) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; s = dev->subdevices + 0; /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index f2eeca51ebfa..32e03bc247b3 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -595,8 +595,9 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_ptr = s626_boards; dev->board_name = thisboard->name; - if (comedi_alloc_subdevices(dev, 6) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 6); + if (ret) + return ret; dev->iobase = (unsigned long)devpriv->base_addr; dev->irq = devpriv->pdev->irq; diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index dc41c04fae4f..e62297380786 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -780,6 +780,7 @@ static int serial2002_attach(struct comedi_device *dev, { const struct serial2002_board *board = comedi_board(dev); struct comedi_subdevice *s; + int ret; dev_dbg(dev->hw_dev, "comedi%d: attached\n", dev->minor); dev->board_name = board->name; @@ -792,8 +793,9 @@ static int serial2002_attach(struct comedi_device *dev, dev_dbg(dev->hw_dev, "/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed); - if (comedi_alloc_subdevices(dev, 5) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 5); + if (ret) + return ret; /* digital input subdevice */ s = dev->subdevices + 0; diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index ca10b1a98153..92d44c1d2587 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -210,6 +210,7 @@ static int skel_ns_to_timer(unsigned int *ns, int round); static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; + int ret; pr_info("comedi%d: skel: ", dev->minor); @@ -233,8 +234,9 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct skel_private)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; /* dev->read_subdev=s; */ diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 130e4bd5c640..b12bafe9baf6 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -187,6 +187,7 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dnp_board *board = comedi_board(dev); struct comedi_subdevice *s; + int ret; printk(KERN_INFO "comedi%d: dnp: ", dev->minor); @@ -197,8 +198,9 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) return -ENOMEM; - if (comedi_alloc_subdevices(dev, 1) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; s = dev->subdevices + 0; /* digital i/o subdevice */ diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 711dad77c598..9f1fdec62dcb 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -443,6 +443,7 @@ static int unioxx5_attach(struct comedi_device *dev, { int iobase, i, n_subd; int id, num, ba; + int ret; iobase = it->options[0]; @@ -468,8 +469,9 @@ static int unioxx5_attach(struct comedi_device *dev, return -1; } - if (comedi_alloc_subdevices(dev, n_subd) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, n_subd); + if (ret) + return ret; /* initializing each of for same subdevices */ for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) { diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index a6cf13459c61..0386fd4a80ba 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2646,7 +2646,7 @@ static int usbdux_attach_common(struct comedi_device *dev, } ret = comedi_alloc_subdevices(dev, n_subdevs); - if (ret < 0) { + if (ret) { up(&udev->sem); return ret; } diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index f7d4f56c1688..2ee9ecd33539 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1667,7 +1667,7 @@ static int usbduxfast_attach(struct comedi_device *dev, dev->board_name = BOARDNAME; ret = comedi_alloc_subdevices(dev, 1); - if (ret < 0) { + if (ret) { up(&(usbduxfastsub[index].sem)); up(&start_stop_sem); return ret; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index f23fad957e5e..502a40948ebd 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2691,7 +2691,7 @@ static int usbduxsigma_attach(struct comedi_device *dev, } ret = comedi_alloc_subdevices(dev, n_subdevs); - if (ret < 0) { + if (ret) { up(&udev->sem); up(&start_stop_sem); return ret; diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 5a3e33d83c84..69402dade14b 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1135,6 +1135,7 @@ static int vmk80xx_attach(struct comedi_device *cdev, int n_subd; struct comedi_subdevice *s; int minor; + int ret; mutex_lock(&glb_mutex); @@ -1159,10 +1160,11 @@ static int vmk80xx_attach(struct comedi_device *cdev, else n_subd = 6; - if (comedi_alloc_subdevices(cdev, n_subd) < 0) { + ret = comedi_alloc_subdevices(cdev, n_subd); + if (ret) { up(&dev->limit_sem); mutex_unlock(&glb_mutex); - return -ENOMEM; + return ret; } /* Analog input subdevice */ -- GitLab From 03afcf472785a63d720202d28d51852d965a95d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 11:59:55 -0700 Subject: [PATCH 1305/6849] staging: comedi: cleanup comedi_alloc_subdevices Access the individual comedi_subdevices using a pointer instead of directly accessing as an array. This is how the rest of the comedi core accesses them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index ecad2288c9fb..6af4a5b302df 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -58,21 +58,24 @@ struct comedi_driver *comedi_drivers; int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) { + struct comedi_subdevice *s; int i; if (num_subdevices < 1) return -EINVAL; - dev->subdevices = - kcalloc(num_subdevices, sizeof(struct comedi_subdevice), - GFP_KERNEL); - if (!dev->subdevices) + + s = kcalloc(num_subdevices, sizeof(*s), GFP_KERNEL); + if (!s) return -ENOMEM; + dev->subdevices = s; dev->n_subdevices = num_subdevices; + for (i = 0; i < num_subdevices; ++i) { - dev->subdevices[i].device = dev; - dev->subdevices[i].async_dma_dir = DMA_NONE; - spin_lock_init(&dev->subdevices[i].spin_lock); - dev->subdevices[i].minor = -1; + s = dev->subdevices + i; + s->device = dev; + s->async_dma_dir = DMA_NONE; + spin_lock_init(&s->spin_lock); + s->minor = -1; } return 0; } -- GitLab From 17c88eb6a09bafb75644b8c37fd65c89c8f49bec Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Jun 2012 09:54:03 +0300 Subject: [PATCH 1306/6849] iio: frequency: ad9523: unlock on error in ad9523_reg_access() There was a return path which got missed accidentally. Signed-off-by: Dan Carpenter Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/iio/frequency/ad9523.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 7272924484c1..832e6ab26114 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -731,10 +731,12 @@ static int ad9523_reg_access(struct iio_dev *indio_dev, } else { ret = ad9523_read(indio_dev, reg | AD9523_R1B); if (ret < 0) - return ret; + goto out_unlock; *readval = ret; ret = 0; } + +out_unlock: mutex_unlock(&indio_dev->mlock); return ret; -- GitLab From 227d5e0040ff18b6258ef6680e3c54150bb6b8b1 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 8 Jun 2012 08:54:17 +0200 Subject: [PATCH 1307/6849] iio: remove indio_dev pointer from max517_data Signed-off-by: Peter Meerwald Acked-by: Roland Stigge Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/max517.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 92c77c82026c..352abe2004a4 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -43,7 +43,6 @@ enum max517_device_ids { }; struct max517_data { - struct iio_dev *indio_dev; struct i2c_client *client; unsigned short vref_mv[2]; }; -- GitLab From f9eb89e97dec966981494c75ef7dc41630b0cb43 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 8 Jun 2012 08:54:18 +0200 Subject: [PATCH 1308/6849] iio: max517: mark probe() and remove() with __devinit and __devexit Signed-off-by: Peter Meerwald Acked-by: Roland Stigge Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/max517.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 352abe2004a4..c3d748c25939 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -156,7 +156,7 @@ static const struct iio_chan_spec max517_channels[] = { MAX517_CHANNEL(1) }; -static int max517_probe(struct i2c_client *client, +static int __devinit max517_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max517_data *data; @@ -210,7 +210,7 @@ exit: return err; } -static int max517_remove(struct i2c_client *client) +static int __devexit max517_remove(struct i2c_client *client) { iio_device_unregister(i2c_get_clientdata(client)); iio_device_free(i2c_get_clientdata(client)); @@ -232,7 +232,7 @@ static struct i2c_driver max517_driver = { .pm = MAX517_PM_OPS, }, .probe = max517_probe, - .remove = max517_remove, + .remove = __devexit_p(max517_remove), .id_table = max517_id, }; module_i2c_driver(max517_driver); -- GitLab From e86ee142a223ec85efda7c66b3e99fe79aa8cc4f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Jun 2012 09:55:37 +0300 Subject: [PATCH 1309/6849] iio: frequency: adf4350: fix an initialization Sparse complains about this: drivers/iio/frequency/adf4350.c:58:29: warning: Initializer entry defined twice drivers/iio/frequency/adf4350.c:59:10: also defined here It looks like '|' was intended here instead of ','. Signed-off-by: Dan Carpenter Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/iio/frequency/adf4350.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 2d09f82d9752..6ce45f5c0deb 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -54,7 +54,7 @@ struct adf4350_state { static struct adf4350_platform_data default_pdata = { .clkin = 122880000, .channel_spacing = 10000, - .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS, + .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS | ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0), .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) | -- GitLab From 1a135d1ab5e3122ab2a50cbbdb9cb1504c1f421f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Jun 2012 09:54:32 +0300 Subject: [PATCH 1310/6849] iio: frequency: adf4350: using an uninitialized variable GCC complains that we use an uninitialized variable if the user passes an invalid parameter to adf4350_read(). I decided that we should return -EINVAL instead in that case. However, when I looked up at adf4350_write() it returned -ENODEV for that condition. In the end, I decided the -EINVAL was the right thing and I change adf4350_write() to match. Signed-off-by: Dan Carpenter Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/iio/frequency/adf4350.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 6ce45f5c0deb..59fbb3ae40e7 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -272,7 +272,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, adf4350_sync_config(st); break; default: - ret = -ENODEV; + ret = -EINVAL; } mutex_unlock(&indio_dev->mlock); @@ -311,7 +311,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, val = !!(st->regs[ADF4350_REG2] & ADF4350_REG2_POWER_DOWN_EN); break; default: - ret = -ENODEV; + ret = -EINVAL; } mutex_unlock(&indio_dev->mlock); -- GitLab From cf35ad61aca2c0c8983fa1e140c901f6588aba7e Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 8 Jun 2012 18:06:45 +0200 Subject: [PATCH 1311/6849] iio: add mcp4725 I2C DAC driver v5: * fix warnings (Jonathan Cameron) v4: * remove unused indio_dev pointer in mcp4725_data (Jonathan Cameron) * use u16 instead of unsigned short in mcp4725_data (Jonathan Cameron) * #include mcp4725.h from linux/iio/dac/ v3: * move from staging to drivers/iio * switch to chan_spec * dev_get_drvdata() -> dev_to_iio_dev() * annotate probe() and remove() with __devinit and __devexit v2 (based on comments from Jonathan Cameron and Lars-Peter Clausen): * did NOT switch to chan_spec yet * rebase to staging-next tree, update iio header locations * dropped dac.h #include, not needed * strict_strtol() -> kstrtol() * call iio_device_unregister() in remove() * everything in one patch Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/Kconfig | 11 ++ drivers/iio/dac/Makefile | 1 + drivers/iio/dac/mcp4725.c | 227 ++++++++++++++++++++++++++++++++ include/linux/iio/dac/mcp4725.h | 16 +++ 4 files changed, 255 insertions(+) create mode 100644 drivers/iio/dac/mcp4725.c create mode 100644 include/linux/iio/dac/mcp4725.h diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index a626f03871ec..92fb3a003510 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -118,4 +118,15 @@ config MAX517 This driver can also be built as a module. If so, the module will be called max517. +config MCP4725 + tristate "MCP4725 DAC driver" + depends on I2C + ---help--- + Say Y here if you want to build a driver for the Microchip + MCP 4725 12-bit digital-to-analog converter (DAC) with I2C + interface. + + To compile this driver as a module, choose M here: the module + will be called mcp4725. + endmenu diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 8ab1d264aab7..9ea3ceeefc07 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_AD5764) += ad5764.o obj-$(CONFIG_AD5791) += ad5791.o obj-$(CONFIG_AD5686) += ad5686.o obj-$(CONFIG_MAX517) += max517.o +obj-$(CONFIG_MCP4725) += mcp4725.o diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c new file mode 100644 index 000000000000..e0e168bd5b45 --- /dev/null +++ b/drivers/iio/dac/mcp4725.c @@ -0,0 +1,227 @@ +/* + * mcp4725.c - Support for Microchip MCP4725 + * + * Copyright (C) 2012 Peter Meerwald + * + * Based on max517 by Roland Stigge + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC) + * (7-bit I2C slave address 0x60, the three LSBs can be configured in + * hardware) + * + * writing the DAC value to EEPROM is not supported + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#define MCP4725_DRV_NAME "mcp4725" + +struct mcp4725_data { + struct i2c_client *client; + u16 vref_mv; + u16 dac_value; +}; + +#ifdef CONFIG_PM_SLEEP +static int mcp4725_suspend(struct device *dev) +{ + u8 outbuf[2]; + + outbuf[0] = 0x3 << 4; /* power-down bits, 500 kOhm resistor */ + outbuf[1] = 0; + + return i2c_master_send(to_i2c_client(dev), outbuf, 2); +} + +static int mcp4725_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct mcp4725_data *data = iio_priv(indio_dev); + u8 outbuf[2]; + + /* restore previous DAC value */ + outbuf[0] = (data->dac_value >> 8) & 0xf; + outbuf[1] = data->dac_value & 0xff; + + return i2c_master_send(to_i2c_client(dev), outbuf, 2); +} + +static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume); +#define MCP4725_PM_OPS (&mcp4725_pm_ops) +#else +#define MCP4725_PM_OPS NULL +#endif + +static const struct iio_chan_spec mcp4725_channel = { + .type = IIO_VOLTAGE, + .indexed = 1, + .output = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .scan_type = IIO_ST('u', 12, 16, 0), +}; + +static int mcp4725_set_value(struct iio_dev *indio_dev, int val) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + u8 outbuf[2]; + int ret; + + if (val >= (1 << 12) || val < 0) + return -EINVAL; + + outbuf[0] = (val >> 8) & 0xf; + outbuf[1] = val & 0xff; + + ret = i2c_master_send(data->client, outbuf, 2); + if (ret < 0) + return ret; + else if (ret != 2) + return -EIO; + else + return 0; +} + +static int mcp4725_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + unsigned long scale_uv; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + *val = data->dac_value; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + scale_uv = (data->vref_mv * 1000) >> 12; + *val = scale_uv / 1000000; + *val2 = scale_uv % 1000000; + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + +static int mcp4725_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct mcp4725_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = mcp4725_set_value(indio_dev, val); + data->dac_value = val; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static const struct iio_info mcp4725_info = { + .read_raw = mcp4725_read_raw, + .write_raw = mcp4725_write_raw, + .driver_module = THIS_MODULE, +}; + +static int __devinit mcp4725_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct mcp4725_data *data; + struct iio_dev *indio_dev; + struct mcp4725_platform_data *platform_data = client->dev.platform_data; + u8 inbuf[3]; + int err; + + if (!platform_data || !platform_data->vref_mv) { + dev_err(&client->dev, "invalid platform data"); + err = -EINVAL; + goto exit; + } + + indio_dev = iio_device_alloc(sizeof(*data)); + if (indio_dev == NULL) { + err = -ENOMEM; + goto exit; + } + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &mcp4725_info; + indio_dev->channels = &mcp4725_channel; + indio_dev->num_channels = 1; + indio_dev->modes = INDIO_DIRECT_MODE; + + data->vref_mv = platform_data->vref_mv; + + /* read current DAC value */ + err = i2c_master_recv(client, inbuf, 3); + if (err < 0) { + dev_err(&client->dev, "failed to read DAC value"); + goto exit_free_device; + } + data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4); + + err = iio_device_register(indio_dev); + if (err) + goto exit_free_device; + + dev_info(&client->dev, "MCP4725 DAC registered\n"); + + return 0; + +exit_free_device: + iio_device_free(indio_dev); +exit: + return err; +} + +static int __devexit mcp4725_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + iio_device_free(indio_dev); + + return 0; +} + +static const struct i2c_device_id mcp4725_id[] = { + { "mcp4725", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp4725_id); + +static struct i2c_driver mcp4725_driver = { + .driver = { + .name = MCP4725_DRV_NAME, + .pm = MCP4725_PM_OPS, + }, + .probe = mcp4725_probe, + .remove = __devexit_p(mcp4725_remove), + .id_table = mcp4725_id, +}; +module_i2c_driver(mcp4725_driver); + +MODULE_AUTHOR("Peter Meerwald "); +MODULE_DESCRIPTION("MCP4725 12-bit DAC"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/iio/dac/mcp4725.h b/include/linux/iio/dac/mcp4725.h new file mode 100644 index 000000000000..91530e6611e9 --- /dev/null +++ b/include/linux/iio/dac/mcp4725.h @@ -0,0 +1,16 @@ +/* + * MCP4725 DAC driver + * + * Copyright (C) 2012 Peter Meerwald + * + * Licensed under the GPL-2 or later. + */ + +#ifndef IIO_DAC_MCP4725_H_ +#define IIO_DAC_MCP4725_H_ + +struct mcp4725_platform_data { + u16 vref_mv; +}; + +#endif /* IIO_DAC_MCP4725_H_ */ -- GitLab From 011c10c351f3f081b496e2197db2948d120cc26c Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 11 Jun 2012 09:51:04 +0200 Subject: [PATCH 1312/6849] iio: ad9523: Fix argument type mismatch drivers/iio/frequency/ad9523.c:378 ad9523_vco_out_map() warn: value 2 can't fit into 1 'out' Signed-off-by: Michael Hennerich Reported-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/iio/frequency/ad9523.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 832e6ab26114..b737c64a402d 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -361,7 +361,7 @@ static int ad9523_io_update(struct iio_dev *indio_dev) } static int ad9523_vco_out_map(struct iio_dev *indio_dev, - unsigned ch, bool out) + unsigned ch, unsigned out) { struct ad9523_state *st = iio_priv(indio_dev); int ret; -- GitLab From 988bb033d703c8b2e0e71c63f3f55616a0220ced Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 12 Jun 2012 14:39:37 +0200 Subject: [PATCH 1313/6849] iio: drop comment about 'real' channels Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/types.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 1b073b1cc7c2..d086736a9033 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -11,7 +11,6 @@ #define _IIO_TYPES_H_ enum iio_chan_type { - /* real channel types */ IIO_VOLTAGE, IIO_CURRENT, IIO_POWER, -- GitLab From 8b417d78ea486280bf8e908e76214c44c533ed3d Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 12 Jun 2012 15:31:27 +0200 Subject: [PATCH 1314/6849] iio: nitpicking on sysfs-bus-iio v2: address comments by Jonathan Cameron * add more output power down modes * spelling of etc. Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-iio | 50 +++++++++++++------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 5bc8a476c15e..e0f68f6a0e2a 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -40,9 +40,9 @@ Contact: linux-iio@vger.kernel.org Description: Some devices have internal clocks. This parameter sets the resulting sampling frequency. In many devices this - parameter has an effect on input filters etc rather than + parameter has an effect on input filters etc. rather than simply controlling when the input is sampled. As this - effects datardy triggers, hardware buffers and the sysfs + effects data ready triggers, hardware buffers and the sysfs direct access interfaces, it may be found in any of the relevant directories. If it effects all of the above then it is to be found in the base device directory. @@ -74,7 +74,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Raw (unscaled no bias removal etc) voltage measurement from + Raw (unscaled no bias removal etc.) voltage measurement from channel Y. In special cases where the channel does not correspond to externally available input one of the named versions may be used. The number must always be specified and @@ -118,7 +118,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_temp_z_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Raw (unscaled no bias removal etc) temperature measurement. + Raw (unscaled no bias removal etc.) temperature measurement. If an axis is specified it generally means that the temperature sensor is associated with one part of a compound device (e.g. a gyroscope axis). Units after application of scale and offset @@ -148,10 +148,9 @@ KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: Angular velocity about axis x, y or z (may be arbitrarily - assigned) Data converted by application of offset then scale to - radians per second. Has all the equivalent parameters as - per voltageY. Units after application of scale and offset are - radians per second. + assigned). Has all the equivalent parameters as per voltageY. + Units after application of scale and offset are radians per + second. What: /sys/bus/iio/devices/iio:deviceX/in_incli_x_raw What: /sys/bus/iio/devices/iio:deviceX/in_incli_y_raw @@ -161,7 +160,7 @@ Contact: linux-iio@vger.kernel.org Description: Inclination raw reading about axis x, y or z (may be arbitrarily assigned). Data converted by application of offset - and scale to Degrees. + and scale to degrees. What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_raw What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_raw @@ -203,7 +202,7 @@ Contact: linux-iio@vger.kernel.org Description: If known for a device, offset to be added to [Y]_raw prior to scaling by [Y]_scale in order to obtain value in the - units as specified in [y]_raw documentation. + units as specified in [Y]_raw documentation. Not present if the offset is always 0 or unknown. If Y or axis is not present, then the offset applies to all in channels of . @@ -248,7 +247,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Hardware applied calibration offset. (assumed to fix production + Hardware applied calibration offset (assumed to fix production inaccuracies). What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale @@ -265,7 +264,7 @@ what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Hardware applied calibration scale factor. (assumed to fix + Hardware applied calibration scale factor (assumed to fix production inaccuracies). If shared across all channels, _calibscale is used. @@ -277,7 +276,7 @@ What: /sys/.../iio:deviceX/in_capacitance_scale_available KernelVersion: 2.635 Contact: linux-iio@vger.kernel.org Description: - If a discrete set of scale values are available, they + If a discrete set of scale values is available, they are listed in this attribute. What /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain @@ -321,9 +320,11 @@ Contact: linux-iio@vger.kernel.org Description: Specifies the output powerdown mode. DAC output stage is disconnected from the amplifier and - 1kohm_to_gnd: connected to ground via an 1kOhm resistor - 100kohm_to_gnd: connected to ground via an 100kOhm resistor - three_state: left floating + 1kohm_to_gnd: connected to ground via an 1kOhm resistor, + 6kohm_to_gnd: connected to ground via a 6kOhm resistor, + 20kohm_to_gnd: connected to ground via a 20kOhm resistor, + 100kohm_to_gnd: connected to ground via an 100kOhm resistor, + three_state: left floating. For a list of available output power down options read outX_powerdown_mode_available. If Y is not present the mode is shared across all outputs. @@ -342,9 +343,10 @@ KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: Writing 1 causes output Y to enter the power down mode specified - by the corresponding outY_powerdown_mode. Clearing returns to - normal operation. Y may be suppressed if all outputs are - controlled together. + by the corresponding outY_powerdown_mode. DAC output stage is + disconnected from the amplifier. Clearing returns to normal + operation. Y may be suppressed if all outputs are controlled + together. What: /sys/bus/iio/devices/iio:deviceX/events KernelVersion: 2.6.35 @@ -390,12 +392,12 @@ Description: different values, but the device can only enable both thresholds or neither. Note the driver will assume the last p events requested are - to be enabled where p is however many it supports (which may - vary depending on the exact set requested. So if you want to be + to be enabled where p is how many it supports (which may vary + depending on the exact set requested. So if you want to be sure you have set what you think you have, check the contents of these attributes after everything is configured. Drivers may have to buffer any parameters so that they are consistent when - a given event type is enabled a future point (and not those for + a given event type is enabled at a future point (and not those for whatever event was previously enabled). What: /sys/.../iio:deviceX/events/in_accel_x_roc_rising_en @@ -671,7 +673,7 @@ What: /sys/.../buffer/scan_elements/in_anglvel_type What: /sys/.../buffer/scan_elements/in_magn_type What: /sys/.../buffer/scan_elements/in_incli_type What: /sys/.../buffer/scan_elements/in_voltageY_type -What: /sys/.../buffer/scan_elements/in_voltage-in_type +What: /sys/.../buffer/scan_elements/in_voltage_type What: /sys/.../buffer/scan_elements/in_voltageY_supply_type What: /sys/.../buffer/scan_elements/in_timestamp_type KernelVersion: 2.6.37 @@ -692,7 +694,7 @@ Description: the buffer output value appropriately. The storagebits value also specifies the data alignment. So s48/64>>2 will be a signed 48 bit integer stored in a 64 bit location aligned to - a a64 bit boundary. To obtain the clean value, shift right 2 + a 64 bit boundary. To obtain the clean value, shift right 2 and apply a mask to zero the top 16 bits of the result. For other storage combinations this attribute will be extended appropriately. -- GitLab From cbb2d5e459f4e10b3f1d11c23c31aa5d7c21e34c Mon Sep 17 00:00:00 2001 From: Rajiv Andrade Date: Tue, 24 Apr 2012 11:19:58 -0300 Subject: [PATCH 1315/6849] MAINTAINERS: TPM maintainers' contacts update Usual contact update, Debora Velarde role resign, and the new co-maintainer inclusion, Kent Yoder. He's accepted to contribute more actively to this driver's maintainership given the current maintainer's slight career change that will affect his contribution time. [Replacing Debora Velarde by Kent Yoder] Signed-off-by: Rajiv Andrade --- MAINTAINERS | 7 ++++--- drivers/char/tpm/tpm_infineon.c | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 14bc7071f9df..58f5a7fbf67d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6835,10 +6835,11 @@ F: include/linux/shmem_fs.h F: mm/shmem.c TPM DEVICE DRIVER -M: Debora Velarde -M: Rajiv Andrade +M: Kent Yoder +M: Rajiv Andrade W: http://tpmdd.sourceforge.net -M: Marcel Selhorst +M: Marcel Selhorst +M: Sirrix AG W: http://www.sirrix.com L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 76da32e11f18..3251a44e8ceb 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -4,8 +4,8 @@ * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module * Specifications at www.trustedcomputinggroup.org * - * Copyright (C) 2005, Marcel Selhorst - * Sirrix AG - security technologies, http://www.sirrix.com and + * Copyright (C) 2005, Marcel Selhorst + * Sirrix AG - security technologies and * Applied Data Security Group, Ruhr-University Bochum, Germany * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ * @@ -671,7 +671,7 @@ static void __exit cleanup_inf(void) module_init(init_inf); module_exit(cleanup_inf); -MODULE_AUTHOR("Marcel Selhorst "); +MODULE_AUTHOR("Marcel Selhorst "); MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); MODULE_VERSION("1.9.2"); MODULE_LICENSE("GPL"); -- GitLab From 1787948873fd2ca730fb5891b6a2ade510367ace Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 12 Jun 2012 15:38:45 +0200 Subject: [PATCH 1316/6849] iio: fix typos in iio.h v2: * "used in in-kernel" (Jonathan Cameron) Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/iio.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 944c63511731..01afaa08ff21 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -131,7 +131,7 @@ struct iio_chan_spec_ext_info { /** * struct iio_enum - Enum channel info attribute - * items: A array of strings. + * items: An array of strings. * num_items: Length of the item array. * set: Set callback function, may be NULL. * get: Get callback function, may be NULL. @@ -218,7 +218,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * @extend_name: Allows labeling of channel attributes with an * informative name. Note this has no effect codes etc, * unlike modifiers. - * @datasheet_name: A name used in in kernel mapping of channels. It should + * @datasheet_name: A name used in in-kernel mapping of channels. It should * correspond to the first name that the channel is referred * to by in the datasheet (e.g. IND), or the nearest * possible compound name (e.g. IND-INC). @@ -393,7 +393,7 @@ struct iio_buffer_setup_ops { * @trig: [INTERN] current device trigger (buffer modes) * @pollfunc: [DRIVER] function run on trigger being received * @channels: [DRIVER] channel specification structure table - * @num_channels: [DRIVER] number of chanels specified in @channels. + * @num_channels: [DRIVER] number of channels specified in @channels. * @channel_attr_list: [INTERN] keep track of automatically created channel * attributes * @chan_attr_group: [INTERN] group for all attrs in base directory -- GitLab From a16561c6f713630270b905297f3eedf02db7fa98 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 12 Jun 2012 15:38:46 +0200 Subject: [PATCH 1317/6849] iio: clarify channel and indexed in struct iio_chan_spec Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/iio.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 01afaa08ff21..9a9e6d52a6de 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -196,7 +196,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, /** * struct iio_chan_spec - specification of a single channel * @type: What type of measurement is the channel making. - * @channel: What number or name do we wish to assign the channel. + * @channel: What number do we wish to assign the channel. * @channel2: If there is a second number for a differential * channel then this is it. If modified is set then the * value here specifies the modifier. @@ -227,9 +227,8 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * channel2. Examples are IIO_MOD_X for axial sensors about * the 'x' axis. * @indexed: Specify the channel has a numerical index. If not, - * the value in channel will be suppressed for attribute - * but not for event codes. Typically set it to 0 when - * the index is false. + * the channel index number will be suppressed for sysfs + * attributes but not for event codes. * @differential: Channel is differential. */ struct iio_chan_spec { -- GitLab From f4c349395e8ad4fe07f1222502568f0d9d5d1dfc Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 12 Jun 2012 15:38:47 +0200 Subject: [PATCH 1318/6849] iio: mark struct iio_enum elements with @ in comment Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/iio.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 9a9e6d52a6de..bd3e7217ceee 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -131,10 +131,10 @@ struct iio_chan_spec_ext_info { /** * struct iio_enum - Enum channel info attribute - * items: An array of strings. - * num_items: Length of the item array. - * set: Set callback function, may be NULL. - * get: Get callback function, may be NULL. + * @items: An array of strings. + * @num_items: Length of the item array. + * @set: Set callback function, may be NULL. + * @get: Get callback function, may be NULL. * * The iio_enum struct can be used to implement enum style channel attributes. * Enum style attributes are those which have a set of strings which map to -- GitLab From 7dcd7b60724cab551deba54f31752fa8959efab4 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 12 Jun 2012 15:38:48 +0200 Subject: [PATCH 1319/6849] iio: cleanup iio/iio.h indentation of parameter description, fix parameter name (@dev -> @indio_dev) in comments, IIO device info structure -> IIO device structure Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/iio.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index bd3e7217ceee..ae0cad908182 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -131,10 +131,10 @@ struct iio_chan_spec_ext_info { /** * struct iio_enum - Enum channel info attribute - * @items: An array of strings. - * @num_items: Length of the item array. - * @set: Set callback function, may be NULL. - * @get: Get callback function, may be NULL. + * @items: An array of strings. + * @num_items: Length of the item array. + * @set: Set callback function, may be NULL. + * @get: Get callback function, may be NULL. * * The iio_enum struct can be used to implement enum style channel attributes. * Enum style attributes are those which have a set of strings which map to @@ -162,9 +162,9 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, /** * IIO_ENUM() - Initialize enum extended channel attribute - * @_name: Attribute name - * @_shared: Whether the attribute is shared between all channels - * @_e: Pointer to a iio_enum struct + * @_name: Attribute name + * @_shared: Whether the attribute is shared between all channels + * @_e: Pointer to a iio_enum struct * * This should usually be used together with IIO_ENUM_AVAILABLE() */ @@ -179,8 +179,8 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, /** * IIO_ENUM_AVAILABLE() - Initialize enum available extended channel attribute - * @_name: Attribute name ("_available" will be appended to the name) - * @_e: Pointer to a iio_enum struct + * @_name: Attribute name ("_available" will be appended to the name) + * @_e: Pointer to a iio_enum struct * * Creates a read only attribute which list all the available enum items in a * space separated list. This should usually be used together with IIO_ENUM() @@ -201,7 +201,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * channel then this is it. If modified is set then the * value here specifies the modifier. * @address: Driver specific identifier. - * @scan_index: Monotonic index to give ordering in scans when read + * @scan_index: Monotonic index to give ordering in scans when read * from a buffer. * @scan_type: Sign: 's' or 'u' to specify signed or unsigned * realbits: Number of valid bits of data @@ -211,7 +211,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * endianness: little or big endian * @info_mask: What information is to be exported about this channel. * This includes calibbias, scale etc. - * @event_mask: What events can this channel produce. + * @event_mask: What events can this channel produce. * @ext_info: Array of extended info attributes for this channel. * The array is NULL terminated, the last element should * have it's name field set to NULL. @@ -482,7 +482,7 @@ extern struct bus_type iio_bus_type; /** * iio_device_put() - reference counted deallocation of struct device - * @dev: the iio_device containing the device + * @indio_dev: IIO device structure containing the device **/ static inline void iio_device_put(struct iio_dev *indio_dev) { @@ -492,7 +492,7 @@ static inline void iio_device_put(struct iio_dev *indio_dev) /** * dev_to_iio_dev() - Get IIO device struct from a device struct - * @dev: The device embedded in the IIO device + * @dev: The device embedded in the IIO device * * Note: The device must be a IIO device, otherwise the result is undefined. */ @@ -503,7 +503,7 @@ static inline struct iio_dev *dev_to_iio_dev(struct device *dev) /** * iio_device_get() - increment reference count for the device - * @indio_dev: IIO device structure + * @indio_dev: IIO device structure * * Returns: The passed IIO device **/ @@ -516,7 +516,7 @@ static inline struct iio_dev *iio_device_get(struct iio_dev *indio_dev) #define IIO_ALIGN L1_CACHE_BYTES /** * iio_device_alloc() - allocate an iio_dev from a driver - * @sizeof_priv: Space to allocate for private structure. + * @sizeof_priv: Space to allocate for private structure. **/ struct iio_dev *iio_device_alloc(int sizeof_priv); @@ -533,13 +533,13 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv) /** * iio_device_free() - free an iio_dev from a driver - * @dev: the iio_dev associated with the device + * @indio_dev: the iio_dev associated with the device **/ void iio_device_free(struct iio_dev *indio_dev); /** * iio_buffer_enabled() - helper function to test if the buffer is enabled - * @indio_dev: IIO device info structure for device + * @indio_dev: IIO device structure for device **/ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) { @@ -549,7 +549,7 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) /** * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry - * @indio_dev: IIO device info structure for device + * @indio_dev: IIO device structure for device **/ #if defined(CONFIG_DEBUG_FS) static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) -- GitLab From 24ebe6670de3d1f0dca11c9eb372134c7ab05503 Mon Sep 17 00:00:00 2001 From: Rajiv Andrade Date: Tue, 24 Apr 2012 17:38:17 -0300 Subject: [PATCH 1320/6849] TPM: chip disabled state erronously being reported as error tpm_do_selftest() attempts to read a PCR in order to decide if one can rely on the TPM being used or not. The function that's used by __tpm_pcr_read() does not expect the TPM to be disabled or deactivated, and if so, reports an error. It's fine if the TPM returns this error when trying to use it for the first time after a power cycle, but it's definitely not if it already returned success for a previous attempt to read one of its PCRs. The tpm_do_selftest() was modified so that the driver only reports this return code as an error when it really is. Reported-and-tested-by: Paul Bolle Cc: Stable Signed-off-by: Rajiv Andrade --- drivers/char/tpm/tpm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ad7c7320dd1b..08427abf5fa5 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -827,10 +827,10 @@ EXPORT_SYMBOL_GPL(tpm_pcr_extend); int tpm_do_selftest(struct tpm_chip *chip) { int rc; - u8 digest[TPM_DIGEST_SIZE]; unsigned int loops; unsigned int delay_msec = 1000; unsigned long duration; + struct tpm_cmd_t cmd; duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST); @@ -845,7 +845,15 @@ int tpm_do_selftest(struct tpm_chip *chip) return rc; do { - rc = __tpm_pcr_read(chip, 0, digest); + /* Attempt to read a PCR value */ + cmd.header.in = pcrread_header; + cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0); + rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE); + + if (rc < TPM_HEADER_SIZE) + return -EFAULT; + + rc = be32_to_cpu(cmd.header.out.return_code); if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) { dev_info(chip->dev, "TPM is disabled/deactivated (0x%X)\n", rc); -- GitLab From dad79cb89254ce646906846b0f0cf7995d626710 Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Wed, 16 May 2012 16:24:28 +0800 Subject: [PATCH 1321/6849] TPM: fix memleak when register hardware fails Adding proper kfree() before returning. Signed-off-by: Wanlong Gao Signed-off-by: Rajiv Andrade --- drivers/char/tpm/tpm.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 08427abf5fa5..dae254d53723 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1413,15 +1413,12 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, "unable to misc_register %s, minor %d\n", chip->vendor.miscdev.name, chip->vendor.miscdev.minor); - put_device(chip->dev); - return NULL; + goto put_device; } if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { misc_deregister(&chip->vendor.miscdev); - put_device(chip->dev); - - return NULL; + goto put_device; } chip->bios_dir = tpm_bios_log_setup(devname); @@ -1433,6 +1430,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, return chip; +put_device: + put_device(chip->dev); out_free: kfree(chip); kfree(devname); -- GitLab From 3072928ff2457642af0da745b88f0420b4596c48 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 28 May 2012 18:42:45 +0200 Subject: [PATCH 1322/6849] tpm: check the chip reference before using it If a driver calls tpm_dev_vendor_release for a device already released then the driver will oops. Signed-off-by: Andi Shyti Signed-off-by: Peter Huewe Signed-off-by: Rajiv Andrade --- drivers/char/tpm/tpm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index dae254d53723..d39b1f60ba23 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1330,6 +1330,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume); void tpm_dev_vendor_release(struct tpm_chip *chip) { + if (!chip) + return; + if (chip->vendor.release) chip->vendor.release(chip->dev); @@ -1347,6 +1350,9 @@ void tpm_dev_release(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); + if (!chip) + return; + tpm_dev_vendor_release(chip); chip->release(dev); -- GitLab From d0daebc3d622f95db181601cb0c4a0781f74f758 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 12 Jun 2012 00:44:01 +0000 Subject: [PATCH 1323/6849] ipv4: Add interface option to enable routing of 127.0.0.0/8 Routing of 127/8 is tradtionally forbidden, we consider packets from that address block martian when routing and do not process corresponding ARP requests. This is a sane default but renders a huge address space practically unuseable. The RFC states that no address within the 127/8 block should ever appear on any network anywhere but it does not forbid the use of such addresses outside of the loopback device in particular. For example to address a pool of virtual guests behind a load balancer. This patch adds a new interface option 'route_localnet' enabling routing of the 127/8 address block and processing of ARP requests on a specific interface. Note that for the feature to work, the default local route covering 127/8 dev lo needs to be removed. Example: $ sysctl -w net.ipv4.conf.eth0.route_localnet=1 $ ip route del 127.0.0.0/8 dev lo table local $ ip addr add 127.1.0.1/16 dev eth0 $ ip route flush cache V2: Fix invalid check to auto flush cache (thanks davem) Signed-off-by: Thomas Graf Acked-by: Neil Horman Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 5 +++++ include/linux/inetdevice.h | 2 ++ net/ipv4/arp.c | 3 ++- net/ipv4/devinet.c | 5 ++++- net/ipv4/route.c | 30 ++++++++++++++++++-------- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 6f896b94abdc..99d0e0504d6e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -862,6 +862,11 @@ accept_local - BOOLEAN local interfaces over the wire and have them accepted properly. default FALSE +route_localnet - BOOLEAN + Do not consider loopback addresses as martian source or destination + while routing. This enables the use of 127/8 for local routing purposes. + default FALSE + rp_filter - INTEGER 0 - No source validation. 1 - Strict mode as defined in RFC3704 Strict Reverse Path diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 597f4a9f3240..67f9ddacb70c 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -38,6 +38,7 @@ enum IPV4_DEVCONF_ACCEPT_LOCAL, IPV4_DEVCONF_SRC_VMARK, IPV4_DEVCONF_PROXY_ARP_PVLAN, + IPV4_DEVCONF_ROUTE_LOCALNET, __IPV4_DEVCONF_MAX }; @@ -131,6 +132,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) #define IN_DEV_PROMOTE_SECONDARIES(in_dev) \ IN_DEV_ORCONF((in_dev), \ PROMOTE_SECONDARIES) +#define IN_DEV_ROUTE_LOCALNET(in_dev) IN_DEV_ORCONF(in_dev, ROUTE_LOCALNET) #define IN_DEV_RX_REDIRECTS(in_dev) \ ((IN_DEV_FORWARD(in_dev) && \ diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index cda37be02f8d..2e560f0c757d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -790,7 +790,8 @@ static int arp_process(struct sk_buff *skb) * Check for bad requests for 127.x.x.x and requests for multicast * addresses. If this is one such, delete it. */ - if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip)) + if (ipv4_is_multicast(tip) || + (!IN_DEV_ROUTE_LOCALNET(in_dev) && ipv4_is_loopback(tip))) goto out; /* diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 10e15a144e95..44bf82e3aef7 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1500,7 +1500,8 @@ static int devinet_conf_proc(ctl_table *ctl, int write, if (cnf == net->ipv4.devconf_dflt) devinet_copy_dflt_conf(net, i); - if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1) + if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 || + i == IPV4_DEVCONF_ROUTE_LOCALNET - 1) if ((new_value == 0) && (old_value != 0)) rt_cache_flush(net, 0); } @@ -1617,6 +1618,8 @@ static struct devinet_sysctl_table { "force_igmp_version"), DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, "promote_secondaries"), + DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET, + "route_localnet"), }, }; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 842510d50453..655506af47ca 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1960,9 +1960,13 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, return -EINVAL; if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || - ipv4_is_loopback(saddr) || skb->protocol != htons(ETH_P_IP)) + skb->protocol != htons(ETH_P_IP)) goto e_inval; + if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) + if (ipv4_is_loopback(saddr)) + goto e_inval; + if (ipv4_is_zeronet(saddr)) { if (!ipv4_is_local_multicast(daddr)) goto e_inval; @@ -2203,8 +2207,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, by fib_lookup. */ - if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || - ipv4_is_loopback(saddr)) + if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr)) goto martian_source; if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0)) @@ -2216,9 +2219,17 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (ipv4_is_zeronet(saddr)) goto martian_source; - if (ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr)) + if (ipv4_is_zeronet(daddr)) goto martian_destination; + if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) { + if (ipv4_is_loopback(daddr)) + goto martian_destination; + + if (ipv4_is_loopback(saddr)) + goto martian_source; + } + /* * Now we are ready to route packet. */ @@ -2457,9 +2468,14 @@ static struct rtable *__mkroute_output(const struct fib_result *res, u16 type = res->type; struct rtable *rth; - if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK)) + in_dev = __in_dev_get_rcu(dev_out); + if (!in_dev) return ERR_PTR(-EINVAL); + if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) + if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK)) + return ERR_PTR(-EINVAL); + if (ipv4_is_lbcast(fl4->daddr)) type = RTN_BROADCAST; else if (ipv4_is_multicast(fl4->daddr)) @@ -2470,10 +2486,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - in_dev = __in_dev_get_rcu(dev_out); - if (!in_dev) - return ERR_PTR(-EINVAL); - if (type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; fi = NULL; -- GitLab From 59d4467be405316916a4087d5b02d99196eeef04 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 May 2012 11:49:24 -0700 Subject: [PATCH 1324/6849] w1: introduce a slave mutex for serializing IO w1 devices need a mutex to serial IO. Most use master->mutex. However that is used for other purposes and they can conflict. In particular master->mutex is held while w1_attach_slave_device is called. For bq27000, this registers a 'powersupply' device which tries to read the current status. The attempt to read will cause a deadlock on master->mutex. So create a new per-slave mutex and use that for serializing IO for bq27000. Signed-off-by: NeilBrown Cc: Evgeniy Polyakov Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/w1/slaves/w1_bq27000.c | 4 ++-- drivers/w1/w1.c | 1 + drivers/w1/w1.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 52ad812fa1e7..87554788fa32 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c @@ -31,10 +31,10 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg) u8 val; struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->mutex); w1_write_8(sl->master, HDQ_CMD_READ | reg); val = w1_read_8(sl->master); - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->mutex); return val; } diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 2f2e894ea0c8..69075c3dfc73 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -688,6 +688,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); atomic_set(&sl->refcnt, 0); init_completion(&sl->released); + mutex_init(&sl->mutex); spin_lock(&w1_flock); f = w1_family_registered(rn->family); diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 4d012ca3f32c..8c8be380a98a 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h @@ -75,6 +75,7 @@ struct w1_slave void *family_data; struct device dev; struct completion released; + struct mutex mutex; }; typedef void (*w1_slave_found_callback)(struct w1_master *, u64); -- GitLab From 526be41625a8b2282d5720dcb19f927edbf193b4 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 19 May 2012 07:31:54 +0400 Subject: [PATCH 1325/6849] w1: cleanup w1_uevent There were some return statements around in the w1_uevent, used goto to cleanup those return statements with the help of err variable, and also removed a semi colon at the end of the w1_uevent's closing brace. Signed-off-by: Devendra Naga Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 69075c3dfc73..79e488db5104 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -557,7 +557,7 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) struct w1_master *md = NULL; struct w1_slave *sl = NULL; char *event_owner, *name; - int err; + int err = 0; if (dev->driver == &w1_master_driver) { md = container_of(dev, struct w1_master, dev); @@ -576,19 +576,17 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) event_owner, name, dev_name(dev)); if (dev->driver != &w1_slave_driver || !sl) - return 0; + goto end; err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family); if (err) - return err; + goto end; err = add_uevent_var(env, "W1_SLAVE_ID=%024LX", (unsigned long long)sl->reg_num.id); - if (err) - return err; - - return 0; -}; +end: + return err; +} #else static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) { -- GitLab From 58bcd3322944f31c9a8b02694e221c645cf4ffd9 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jun 2012 18:51:23 -0700 Subject: [PATCH 1326/6849] serial: fix kernel-doc warnings in 8250.c Fix kernel-doc warnings in drivers/tty/serial/8250/8250.c: Warning(drivers/tty/serial/8250/8250.c:3128): No description found for parameter 'up' Warning(drivers/tty/serial/8250/8250.c:3128): Excess function parameter 'port' description in 'serial8250_register_8250_port' Signed-off-by: Randy Dunlap Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 47d061b9ad4d..6e1958a325bd 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -3113,7 +3113,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /** * serial8250_register_8250_port - register a serial port - * @port: serial port template + * @up: serial port template * * Configure the serial port specified by the request. If the * port exists and is in use, it is hung up and unregistered -- GitLab From f109293f5889dd30477564a3ce2c901f4024a53e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 5 Jun 2012 09:46:07 -0700 Subject: [PATCH 1327/6849] serial: fix serial_txx9.c build warning/typo Fix kconfig symbol test to use "defined": drivers/tty/serial/serial_txx9.c: warning: "CONFIG_CONSOLE_POLL" is not defined [-Wundef] Reported-by: Geert Uytterhoeven Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_txx9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 34bd345da775..6ae2a58d62f2 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -466,7 +466,7 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) /* * Wait for transmitter & holding register to empty */ -- GitLab From 78d80c5a720ea370defa3e3124c0f7f7179bdfe5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 23 May 2012 21:18:46 +0200 Subject: [PATCH 1328/6849] serial/amba-pl011: move custom pin control to driver We had a boot regression in Ux500 in the merge window because two orthogonal pin control schemes for the PL011 were merged at the same time: - One using the .init() and .exit() hooks into the platform for Ux500 putting the pins into default vs sleep state respectively as the port was started/stopped. commit a09806607fd20bed2f8c41fe22793386790a14aa "ARM: ux500: switch to using pinctrl for uart0" - One hogging the default setting at PL011 probe() commit 258e055111d3cde2607e0d04eb91da2f7a59b591 "serial: amba-pl011: adopt pinctrl support" To get a solution that works for both let's scrap the stuff in the platform callbacks, instead have the driver itself select default and sleep states when the port is started/stopped. Hopefully this works for all clients. Platform callbacks are bad for device tree migration anyway, so this rids us of another problem in Ux500. Cc: Shawn Guo Cc: Russell King Reported-by: Lee Jones Signed-off-by: Linus Walleij Tested-by: Shawn Guo Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-ux500/board-mop500.c | 54 +----------------------------- drivers/tty/serial/amba-pl011.c | 45 ++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 57 deletions(-) diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 9c74ac545849..1509a3cb5833 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -580,43 +580,12 @@ static void ux500_uart0_reset(void) udelay(1); } -/* This needs to be referenced by callbacks */ -struct pinctrl *u0_p; -struct pinctrl_state *u0_def; -struct pinctrl_state *u0_sleep; - -static void ux500_uart0_init(void) -{ - int ret; - - if (IS_ERR(u0_p) || IS_ERR(u0_def)) - return; - - ret = pinctrl_select_state(u0_p, u0_def); - if (ret) - pr_err("could not set UART0 defstate\n"); -} - -static void ux500_uart0_exit(void) -{ - int ret; - - if (IS_ERR(u0_p) || IS_ERR(u0_sleep)) - return; - - ret = pinctrl_select_state(u0_p, u0_sleep); - if (ret) - pr_err("could not set UART0 idlestate\n"); -} - static struct amba_pl011_data uart0_plat = { #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, .dma_rx_param = &uart0_dma_cfg_rx, .dma_tx_param = &uart0_dma_cfg_tx, #endif - .init = ux500_uart0_init, - .exit = ux500_uart0_exit, .reset = ux500_uart0_reset, }; @@ -638,28 +607,7 @@ static struct amba_pl011_data uart2_plat = { static void __init mop500_uart_init(struct device *parent) { - struct amba_device *uart0_device; - - uart0_device = db8500_add_uart0(parent, &uart0_plat); - if (uart0_device) { - u0_p = pinctrl_get(&uart0_device->dev); - if (IS_ERR(u0_p)) - dev_err(&uart0_device->dev, - "could not get UART0 pinctrl\n"); - else { - u0_def = pinctrl_lookup_state(u0_p, - PINCTRL_STATE_DEFAULT); - if (IS_ERR(u0_def)) { - dev_err(&uart0_device->dev, - "could not get UART0 defstate\n"); - } - u0_sleep = pinctrl_lookup_state(u0_p, - PINCTRL_STATE_SLEEP); - if (IS_ERR(u0_sleep)) - dev_err(&uart0_device->dev, - "could not get UART0 idlestate\n"); - } - } + db8500_add_uart0(parent, &uart0_plat); db8500_add_uart1(parent, &uart1_plat); db8500_add_uart2(parent, &uart2_plat); } diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 4ad721fb8405..c17923ec6e95 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -133,6 +133,10 @@ struct pl011_dmatx_data { struct uart_amba_port { struct uart_port port; struct clk *clk; + /* Two optional pin states - default & sleep */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; const struct vendor_data *vendor; unsigned int dmacr; /* dma control reg */ unsigned int im; /* interrupt mask */ @@ -1312,6 +1316,14 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + /* Optionaly enable pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (retval) + dev_err(port->dev, + "could not set default pins\n"); + } + retval = clk_prepare(uap->clk); if (retval) goto out; @@ -1420,6 +1432,7 @@ static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; + int retval; /* * disable all interrupts @@ -1462,6 +1475,14 @@ static void pl011_shutdown(struct uart_port *port) */ clk_disable(uap->clk); clk_unprepare(uap->clk); + /* Optionally let pins go into sleep states */ + if (!IS_ERR(uap->pins_sleep)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); + if (retval) + dev_err(port->dev, + "could not set pins to sleep state\n"); + } + if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1792,6 +1813,14 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + /* Allow pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + ret = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (ret) + dev_err(uap->port.dev, + "could not set default pins\n"); + } + ret = clk_prepare(uap->clk); if (ret) return ret; @@ -1844,7 +1873,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) { struct uart_amba_port *uap; struct vendor_data *vendor = id->data; - struct pinctrl *pinctrl; void __iomem *base; int i, ret; @@ -1869,11 +1897,20 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto free; } - pinctrl = devm_pinctrl_get_select_default(&dev->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); + uap->pinctrl = devm_pinctrl_get(&dev->dev); + if (IS_ERR(uap->pinctrl)) { + ret = PTR_ERR(uap->pinctrl); goto unmap; } + uap->pins_default = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(uap->pins_default)) + dev_err(&dev->dev, "could not get default pinstate\n"); + + uap->pins_sleep = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR(uap->pins_sleep)) + dev_dbg(&dev->dev, "could not get sleep pinstate\n"); uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { -- GitLab From 95dc690eb7cc394a7b5749ecf0118e2f2e011e69 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 15:58:29 -0700 Subject: [PATCH 1329/6849] staging: comedi: remove check for PCI_SUPPORT_VER1 This symbol is not defined in the kernel. It appears to be left over from the 2.4 kernel. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 4 ---- drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h | 4 ---- 2 files changed, 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index d70ac8bb6228..95f7dc61cd00 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -22,10 +22,6 @@ #include "../../comedidev.h" -#ifdef PCI_SUPPORT_VER1 -#error No support for 2.1.55 and older -#endif - /* written on base0 */ #define FIFO_ADVANCE_ON_BYTE_2 0x20000000 diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h index 349e93c23e91..c26c28c31b97 100644 --- a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h +++ b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h @@ -23,10 +23,6 @@ #include #include "../../comedidev.h" -#ifdef PCI_SUPPORT_VER1 -#error Sorry, no support for 2.1.55 and older! :-(((( -#endif - /***********Added by sarath for compatibility with APCI3120 *************************/ -- GitLab From 6ebb017de9d59a18c3ff9648270e8f6abaa93438 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 5 Jun 2012 08:52:34 +0200 Subject: [PATCH 1330/6849] printk: Fix alignment of buf causing crash on ARM EABI Commit 7ff9554bb578ba02166071d2d487b7fc7d860d62, printk: convert byte-buffer to variable-length record buffer, causes systems using EABI to crash very early in the boot cycle. The first entry in struct log is a u64, which for EABI must be 8 byte aligned. Make use of __alignof__() so the compiler to decide the alignment, but allow it to be overridden using CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, for systems which can perform unaligned access and want to save a few bytes of space. Tested on Orion5x and Kirkwood. Signed-off-by: Andrew Lunn Tested-by: Stephen Warren Acked-by: Stephen Warren Acked-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 32462d2b364a..f205c25c37e2 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -227,10 +227,10 @@ static u32 clear_idx; #define LOG_LINE_MAX 1024 /* record buffer */ -#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) #define LOG_ALIGN 4 #else -#define LOG_ALIGN 8 +#define LOG_ALIGN __alignof__(struct log) #endif #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); -- GitLab From ef9d884dadd4c9f2c8432a6b82309ae4a133a35d Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Mon, 11 Jun 2012 15:19:39 +0000 Subject: [PATCH 1331/6849] usbnet: remove usb_get/put_dev in .probe and .disconnect usb_device is parent device of usb_interface in the view of driver model, so its reference count is always held during .probe/.disconnect of usb_interface instance. This patch just removes the unnecessay usb_get/put_dev. Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9f58330f1312..022c1e72d004 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1307,7 +1307,6 @@ void usbnet_disconnect (struct usb_interface *intf) usb_free_urb(dev->interrupt); free_netdev(net); - usb_put_dev (xdev); } EXPORT_SYMBOL_GPL(usbnet_disconnect); @@ -1363,8 +1362,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) xdev = interface_to_usbdev (udev); interface = udev->cur_altsetting; - usb_get_dev (xdev); - status = -ENOMEM; // set up our own records @@ -1493,7 +1490,6 @@ out3: out1: free_netdev(net); out: - usb_put_dev(xdev); return status; } EXPORT_SYMBOL_GPL(usbnet_probe); -- GitLab From 5c2f05139ad9459979b3102846fa61347896d148 Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Mon, 11 Jun 2012 15:19:40 +0000 Subject: [PATCH 1332/6849] usbnet:pegasus: remove usb_get/put_dev in .probe and .disconnect usb_device is parent device of usb_interface in the view of driver model, so its reference count is always held during .probe/.disconnect of usb_interface instance. This patch just removes the unnecessay usb_get/put_dev. Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/pegasus.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 7023220456c5..a0b5807b30d4 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1329,8 +1329,6 @@ static int pegasus_probe(struct usb_interface *intf, } pegasus_count++; - usb_get_dev(dev); - net = alloc_etherdev(sizeof(struct pegasus)); if (!net) goto out; @@ -1407,7 +1405,6 @@ out2: out1: free_netdev(net); out: - usb_put_dev(dev); pegasus_dec_workqueue(); return res; } @@ -1425,7 +1422,6 @@ static void pegasus_disconnect(struct usb_interface *intf) pegasus->flags |= PEGASUS_UNPLUG; cancel_delayed_work(&pegasus->carrier_check); unregister_netdev(pegasus->net); - usb_put_dev(interface_to_usbdev(intf)); unlink_all_urbs(pegasus); free_all_urbs(pegasus); free_skb_pool(pegasus); -- GitLab From 50e7d153910b0735aa517c3d1f3723a88f66eaba Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Mon, 11 Jun 2012 15:19:41 +0000 Subject: [PATCH 1333/6849] usbnet:cdc-phonet: remove usb_get/put_dev in .probe and .disconnect usb_device is parent device of usb_interface in the view of driver model, so its reference count is always held during .probe/.disconnect of usb_interface instance. This patch just removes the unnecessay usb_get/put_dev. Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/cdc-phonet.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index d848d4dd5754..187c144c5e5b 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -394,7 +394,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) SET_NETDEV_DEV(dev, &intf->dev); pnd->dev = dev; - pnd->usb = usb_get_dev(usbdev); + pnd->usb = usbdev; pnd->intf = intf; pnd->data_intf = data_intf; spin_lock_init(&pnd->tx_lock); @@ -440,7 +440,6 @@ out: static void usbpn_disconnect(struct usb_interface *intf) { struct usbpn_dev *pnd = usb_get_intfdata(intf); - struct usb_device *usb = pnd->usb; if (pnd->disconnected) return; @@ -449,7 +448,6 @@ static void usbpn_disconnect(struct usb_interface *intf) usb_driver_release_interface(&usbpn_driver, (pnd->intf == intf) ? pnd->data_intf : pnd->intf); unregister_netdev(pnd->dev); - usb_put_dev(usb); } static struct usb_driver usbpn_driver = { -- GitLab From 4a5a14d39e8164b5c77f1bf42851a58a69a6c7b2 Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Mon, 11 Jun 2012 15:19:43 +0000 Subject: [PATCH 1334/6849] usbnet: remove flag of EVENT_DEV_WAKING The flag of EVENT_DEV_WAKING is not used any more, so just remove it. Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- include/linux/usb/usbnet.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 76f439647c4b..f87cf622317f 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -66,9 +66,8 @@ struct usbnet { # define EVENT_STS_SPLIT 3 # define EVENT_LINK_RESET 4 # define EVENT_RX_PAUSED 5 -# define EVENT_DEV_WAKING 6 -# define EVENT_DEV_ASLEEP 7 -# define EVENT_DEV_OPEN 8 +# define EVENT_DEV_ASLEEP 6 +# define EVENT_DEV_OPEN 7 }; static inline struct usb_driver *driver_of(struct usb_interface *intf) -- GitLab From 24ead29915352d4689a5972c65307a073b229fb4 Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Mon, 11 Jun 2012 15:19:44 +0000 Subject: [PATCH 1335/6849] usbnet: remove declaration for intr_complete Remove declaration for intr_complete so that ctags may be happy to decrease duplicated symbols, also decrease one line code. Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 72 +++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 022c1e72d004..205247efee62 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -180,7 +180,41 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) } EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); -static void intr_complete (struct urb *urb); +static void intr_complete (struct urb *urb) +{ + struct usbnet *dev = urb->context; + int status = urb->status; + + switch (status) { + /* success */ + case 0: + dev->driver_info->status(dev, urb); + break; + + /* software-driven interface shutdown */ + case -ENOENT: /* urb killed */ + case -ESHUTDOWN: /* hardware gone */ + netif_dbg(dev, ifdown, dev->net, + "intr shutdown, code %d\n", status); + return; + + /* NOTE: not throttling like RX/TX, since this endpoint + * already polls infrequently + */ + default: + netdev_dbg(dev->net, "intr status %d\n", status); + break; + } + + if (!netif_running (dev->net)) + return; + + memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status != 0) + netif_err(dev, timer, dev->net, + "intr resubmit --> %d\n", status); +} static int init_status (struct usbnet *dev, struct usb_interface *intf) { @@ -519,42 +553,6 @@ block: netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n"); } -static void intr_complete (struct urb *urb) -{ - struct usbnet *dev = urb->context; - int status = urb->status; - - switch (status) { - /* success */ - case 0: - dev->driver_info->status(dev, urb); - break; - - /* software-driven interface shutdown */ - case -ENOENT: /* urb killed */ - case -ESHUTDOWN: /* hardware gone */ - netif_dbg(dev, ifdown, dev->net, - "intr shutdown, code %d\n", status); - return; - - /* NOTE: not throttling like RX/TX, since this endpoint - * already polls infrequently - */ - default: - netdev_dbg(dev->net, "intr status %d\n", status); - break; - } - - if (!netif_running (dev->net)) - return; - - memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); - status = usb_submit_urb (urb, GFP_ATOMIC); - if (status != 0) - netif_err(dev, timer, dev->net, - "intr resubmit --> %d\n", status); -} - /*-------------------------------------------------------------------------*/ void usbnet_pause_rx(struct usbnet *dev) { -- GitLab From 072c0559e26bc35700b3a70dffc230f00d9262b8 Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Mon, 11 Jun 2012 15:19:45 +0000 Subject: [PATCH 1336/6849] usbnet: don't initialize transfer buffer before submit status URB The line below in intr_complete isn't needed, memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); so just remove it. Signed-off-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 205247efee62..ac2e4936b421 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -209,7 +209,6 @@ static void intr_complete (struct urb *urb) if (!netif_running (dev->net)) return; - memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); status = usb_submit_urb (urb, GFP_ATOMIC); if (status != 0) netif_err(dev, timer, dev->net, -- GitLab From de063b7040dcd9fbc9a1847fa44f0af13e19d6de Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Jun 2012 19:23:07 +0000 Subject: [PATCH 1337/6849] bonding: remove packet cloning in recv_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cloning all packets in input path have a significant cost. Use skb_header_pointer()/skb_copy_bits() instead of pskb_may_pull() so that recv_probe handlers (bond_3ad_lacpdu_recv / bond_arp_rcv / rlb_arp_recv ) dont touch input skb. bond_handle_frame() can avoid the skb_clone()/dev_kfree_skb() Signed-off-by: Eric Dumazet Cc: Jay Vosburgh Cc: Andy Gospodarek Cc: Jiri Bohac Cc: Nicolas de Pesloüan Cc: Maciej Żenczykowski Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 11 ++++++---- drivers/net/bonding/bond_3ad.h | 4 ++-- drivers/net/bonding/bond_alb.c | 20 +++++------------- drivers/net/bonding/bond_main.c | 37 ++++++++++++++++++--------------- drivers/net/bonding/bonding.h | 4 ++-- 5 files changed, 36 insertions(+), 40 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 3463b469e657..3031e0413114 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2460,18 +2460,21 @@ out: return NETDEV_TX_OK; } -int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, - struct slave *slave) +int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) { int ret = RX_HANDLER_ANOTHER; + struct lacpdu *lacpdu, _lacpdu; + if (skb->protocol != PKT_TYPE_LACPDU) return ret; - if (!pskb_may_pull(skb, sizeof(struct lacpdu))) + lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu); + if (!lacpdu) return ret; read_lock(&bond->lock); - ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); + ret = bond_3ad_rx_indication(lacpdu, slave, skb->len); read_unlock(&bond->lock); return ret; } diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 5ee7e3c45db7..0cfaa4afdece 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -274,8 +274,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave); void bond_3ad_handle_link_change(struct slave *slave, char link); int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); -int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, - struct slave *slave); +int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave); int bond_3ad_set_carrier(struct bonding *bond); void bond_3ad_update_lacp_rate(struct bonding *bond); #endif //__BOND_3AD_H__ diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 0f59c1564e53..ef3791a09ad8 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -342,27 +342,17 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) _unlock_rx_hashtbl_bh(bond); } -static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, - struct slave *slave) +static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) { - struct arp_pkt *arp; + struct arp_pkt *arp, _arp; if (skb->protocol != cpu_to_be16(ETH_P_ARP)) goto out; - arp = (struct arp_pkt *) skb->data; - if (!arp) { - pr_debug("Packet has no ARP data\n"); + arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp); + if (!arp) goto out; - } - - if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) - goto out; - - if (skb->len < sizeof(struct arp_pkt)) { - pr_debug("Packet is too small to be an ARP\n"); - goto out; - } if (arp->op_code == htons(ARPOP_REPLY)) { /* update rx hash table for this ARP */ diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2ee8cf9e8a3b..9e2301eef386 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1444,8 +1444,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) struct sk_buff *skb = *pskb; struct slave *slave; struct bonding *bond; - int (*recv_probe)(struct sk_buff *, struct bonding *, - struct slave *); + int (*recv_probe)(const struct sk_buff *, struct bonding *, + struct slave *); int ret = RX_HANDLER_ANOTHER; skb = skb_share_check(skb, GFP_ATOMIC); @@ -1462,15 +1462,10 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) recv_probe = ACCESS_ONCE(bond->recv_probe); if (recv_probe) { - struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); - - if (likely(nskb)) { - ret = recv_probe(nskb, bond, slave); - dev_kfree_skb(nskb); - if (ret == RX_HANDLER_CONSUMED) { - consume_skb(skb); - return ret; - } + ret = recv_probe(skb, bond, slave); + if (ret == RX_HANDLER_CONSUMED) { + consume_skb(skb); + return ret; } } @@ -2737,25 +2732,31 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 } } -static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, - struct slave *slave) +static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) { - struct arphdr *arp; + struct arphdr *arp = (struct arphdr *)skb->data; unsigned char *arp_ptr; __be32 sip, tip; + int alen; if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) return RX_HANDLER_ANOTHER; read_lock(&bond->lock); + alen = arp_hdr_len(bond->dev); pr_debug("bond_arp_rcv: bond %s skb->dev %s\n", bond->dev->name, skb->dev->name); - if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) - goto out_unlock; + if (alen > skb_headlen(skb)) { + arp = kmalloc(alen, GFP_ATOMIC); + if (!arp) + goto out_unlock; + if (skb_copy_bits(skb, 0, arp, alen) < 0) + goto out_unlock; + } - arp = arp_hdr(skb); if (arp->ar_hln != bond->dev->addr_len || skb->pkt_type == PACKET_OTHERHOST || skb->pkt_type == PACKET_LOOPBACK || @@ -2790,6 +2791,8 @@ static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, out_unlock: read_unlock(&bond->lock); + if (arp != (struct arphdr *)skb->data) + kfree(arp); return RX_HANDLER_ANOTHER; } diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4581aa5ccaba..f8af2fcd3d16 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -218,8 +218,8 @@ struct bonding { struct slave *primary_slave; bool force_primary; s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ - int (*recv_probe)(struct sk_buff *, struct bonding *, - struct slave *); + int (*recv_probe)(const struct sk_buff *, struct bonding *, + struct slave *); rwlock_t lock; rwlock_t curr_slave_lock; u8 send_peer_notif; -- GitLab From 95603e2293de556de7e82221649bfd7fd98b64a3 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Tue, 12 Jun 2012 10:16:35 +0000 Subject: [PATCH 1338/6849] net-next: add dev_loopback_xmit() to avoid duplicate code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add dev_loopback_xmit() in order to deduplicate functions ip_dev_loopback_xmit() (in net/ipv4/ip_output.c) and ip6_dev_loopback_xmit() (in net/ipv6/ip6_output.c). I was about to reinvent the wheel when I noticed that ip_dev_loopback_xmit() and ip6_dev_loopback_xmit() do exactly what I need and are not IP-only functions, but they were not available to reuse elsewhere. ip6_dev_loopback_xmit() does not have line "skb_dst_force(skb);", but I understand that this is harmless, and should be in dev_loopback_xmit(). Signed-off-by: Michel Machado CC: "David S. Miller" CC: Alexey Kuznetsov CC: James Morris CC: Hideaki YOSHIFUJI CC: Patrick McHardy CC: Eric Dumazet CC: Jiri Pirko CC: "Michał Mirosław" CC: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 + net/core/dev.c | 17 +++++++++++++++++ net/ipv4/ip_output.c | 17 ++--------------- net/ipv6/ip6_output.c | 15 +-------------- 4 files changed, 21 insertions(+), 29 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a0b84e3b087c..2c2ecea28a1b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1627,6 +1627,7 @@ extern int dev_alloc_name(struct net_device *dev, const char *name); extern int dev_open(struct net_device *dev); extern int dev_close(struct net_device *dev); extern void dev_disable_lro(struct net_device *dev); +extern int dev_loopback_xmit(struct sk_buff *newskb); extern int dev_queue_xmit(struct sk_buff *skb); extern int register_netdevice(struct net_device *dev); extern void unregister_netdevice_queue(struct net_device *dev, diff --git a/net/core/dev.c b/net/core/dev.c index cd0981977f5c..c6e29ea65bd9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2475,6 +2475,23 @@ static void skb_update_prio(struct sk_buff *skb) static DEFINE_PER_CPU(int, xmit_recursion); #define RECURSION_LIMIT 10 +/** + * dev_loopback_xmit - loop back @skb + * @skb: buffer to transmit + */ +int dev_loopback_xmit(struct sk_buff *skb) +{ + skb_reset_mac_header(skb); + __skb_pull(skb, skb_network_offset(skb)); + skb->pkt_type = PACKET_LOOPBACK; + skb->ip_summed = CHECKSUM_UNNECESSARY; + WARN_ON(!skb_dst(skb)); + skb_dst_force(skb); + netif_rx_ni(skb); + return 0; +} +EXPORT_SYMBOL(dev_loopback_xmit); + /** * dev_queue_xmit - transmit a buffer * @skb: buffer to transmit diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index b99ca4e154b9..0f3185a662c3 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -113,19 +113,6 @@ int ip_local_out(struct sk_buff *skb) } EXPORT_SYMBOL_GPL(ip_local_out); -/* dev_loopback_xmit for use with netfilter. */ -static int ip_dev_loopback_xmit(struct sk_buff *newskb) -{ - skb_reset_mac_header(newskb); - __skb_pull(newskb, skb_network_offset(newskb)); - newskb->pkt_type = PACKET_LOOPBACK; - newskb->ip_summed = CHECKSUM_UNNECESSARY; - WARN_ON(!skb_dst(newskb)); - skb_dst_force(newskb); - netif_rx_ni(newskb); - return 0; -} - static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) { int ttl = inet->uc_ttl; @@ -281,7 +268,7 @@ int ip_mc_output(struct sk_buff *skb) if (newskb) NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb, NULL, newskb->dev, - ip_dev_loopback_xmit); + dev_loopback_xmit); } /* Multicasts with ttl 0 must not go beyond the host */ @@ -296,7 +283,7 @@ int ip_mc_output(struct sk_buff *skb) struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); if (newskb) NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb, - NULL, newskb->dev, ip_dev_loopback_xmit); + NULL, newskb->dev, dev_loopback_xmit); } return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 62fcf3e48aca..ee1bb450bfe4 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -83,19 +83,6 @@ int ip6_local_out(struct sk_buff *skb) } EXPORT_SYMBOL_GPL(ip6_local_out); -/* dev_loopback_xmit for use with netfilter. */ -static int ip6_dev_loopback_xmit(struct sk_buff *newskb) -{ - skb_reset_mac_header(newskb); - __skb_pull(newskb, skb_network_offset(newskb)); - newskb->pkt_type = PACKET_LOOPBACK; - newskb->ip_summed = CHECKSUM_UNNECESSARY; - WARN_ON(!skb_dst(newskb)); - - netif_rx_ni(newskb); - return 0; -} - static int ip6_finish_output2(struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); @@ -121,7 +108,7 @@ static int ip6_finish_output2(struct sk_buff *skb) if (newskb) NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, newskb, NULL, newskb->dev, - ip6_dev_loopback_xmit); + dev_loopback_xmit); if (ipv6_hdr(skb)->hop_limit == 0) { IP6_INC_STATS(dev_net(dev), idev, -- GitLab From 2da45db2bdd432a9dca825099c791f5c851f92b9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 12 Jun 2012 13:05:41 +0000 Subject: [PATCH 1339/6849] ethtool: Make more commands available to unprivileged processes 'Get' commands should generally not require CAP_NET_ADMIN, with the exception of those that expose internal state. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/ethtool.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index c73d0a59212c..cbf033dcaf1f 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1443,6 +1443,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GSET: case ETHTOOL_GDRVINFO: case ETHTOOL_GMSGLVL: + case ETHTOOL_GLINK: case ETHTOOL_GCOALESCE: case ETHTOOL_GRINGPARAM: case ETHTOOL_GPAUSEPARAM: @@ -1451,6 +1452,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GSG: case ETHTOOL_GSSET_INFO: case ETHTOOL_GSTRINGS: + case ETHTOOL_GSTATS: case ETHTOOL_GTSO: case ETHTOOL_GPERMADDR: case ETHTOOL_GUFO: @@ -1463,8 +1465,11 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRULE: case ETHTOOL_GRXCLSRLALL: + case ETHTOOL_GRXFHINDIR: case ETHTOOL_GFEATURES: + case ETHTOOL_GCHANNELS: case ETHTOOL_GET_TS_INFO: + case ETHTOOL_GEEE: break; default: if (!capable(CAP_NET_ADMIN)) -- GitLab From af7985bf85840e3dc90ba108a679db044f91f00e Mon Sep 17 00:00:00 2001 From: Jefferson Delfes Date: Mon, 11 Jun 2012 09:18:51 -0400 Subject: [PATCH 1340/6849] Bluetooth: Fix flags of mgmt_device_found event Change flags field to matches userspace structure. This field needs to be converted to little endian before forward it. Signed-off-by: Jefferson Delfes Signed-off-by: Gustavo Padovan --- include/net/bluetooth/mgmt.h | 2 +- net/bluetooth/mgmt.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 23fd0546fccb..4348ee8bda69 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -444,7 +444,7 @@ struct mgmt_ev_auth_failed { struct mgmt_ev_device_found { struct mgmt_addr_info addr; __s8 rssi; - __u8 flags[4]; + __le32 flags; __le16 eir_len; __u8 eir[0]; } __packed; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c72307cc25fc..b4816632d724 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3546,9 +3546,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->addr.type = link_to_bdaddr(link_type, addr_type); ev->rssi = rssi; if (cfm_name) - ev->flags[0] |= MGMT_DEV_FOUND_CONFIRM_NAME; + ev->flags |= MGMT_DEV_FOUND_CONFIRM_NAME; if (!ssp) - ev->flags[0] |= MGMT_DEV_FOUND_LEGACY_PAIRING; + ev->flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; if (eir_len > 0) memcpy(ev->eir, eir, eir_len); @@ -3558,6 +3558,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, dev_class, 3); ev->eir_len = cpu_to_le16(eir_len); + ev->flags = cpu_to_le32(ev->flags); ev_size = sizeof(*ev) + eir_len; -- GitLab From 3701f94451ea341fb5305cb55f7afc04bf0dc56e Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 11 Jun 2012 18:41:12 -0300 Subject: [PATCH 1341/6849] Bluetooth: Remove magic value in disconnect mgmt handler This patch replaces the magic value of variable 'reason' by the proper macro. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index b4816632d724..5aa5592ad578 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1611,7 +1611,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, } dc.handle = cpu_to_le16(conn->handle); - dc.reason = 0x13; /* Remote User Terminated Connection */ + dc.reason = HCI_ERROR_REMOTE_USER_TERM; err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); if (err < 0) -- GitLab From 123df01e8e046d6065089e1bff29aa3fc48d4420 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 24 May 2012 19:24:18 +0900 Subject: [PATCH 1342/6849] sh: intc: Allocate subgroup virq backing desc directly. This switches to using irq_alloc_desc() directly for subgroup IRQs. We still need to call activate_irq() on these in order to make them requestable, at least up until these get moved in to their own irq domain.. Signed-off-by: Paul Mundt --- drivers/sh/intc/virq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index 93cec21e788b..f30ac9354ff2 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -219,12 +219,14 @@ restart: if (radix_tree_deref_retry(entry)) goto restart; - irq = create_irq(); + irq = irq_alloc_desc(numa_node_id()); if (unlikely(irq < 0)) { pr_err("no more free IRQs, bailing..\n"); break; } + activate_irq(irq); + pr_info("Setting up a chained VIRQ from %d -> %d\n", irq, entry->pirq); -- GitLab From ff1ffb850b7ac6d0f1b085208a6630f7584e1015 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Jun 2012 09:42:57 +0200 Subject: [PATCH 1343/6849] iwlwifi: fix dynamic loading Add locking to the dynamic loading code to prevent corrupting the list if multiple device ever init at the same time (which cannot happen for multiple PCI devices, but could happen when different busses init concurrently.) Also remove a device from the list when it stops so the list isn't left corrupted, including a fix from Don to not crash when it was never added. Reviewed-by: Donald H Fry Tested-by: Donald H Fry Reviewed-by: Emmanuel Grumbach Signed-off-by: Don Fry Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-drv.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index cdfdfaec395e..67c9668d2e37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -131,6 +131,8 @@ struct iwl_drv { #define DVM_OP_MODE 0 #define MVM_OP_MODE 1 +/* Protects the table contents, i.e. the ops pointer & drv list */ +static struct mutex iwlwifi_opmode_table_mtx; static struct iwlwifi_opmode_table { const char *name; /* name: iwldvm, iwlmvm, etc */ const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */ @@ -899,6 +901,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) release_firmware(ucode_raw); complete(&drv->request_firmware_complete); + mutex_lock(&iwlwifi_opmode_table_mtx); op = &iwlwifi_opmode_table[DVM_OP_MODE]; /* add this device to the list of devices using this op_mode */ @@ -910,6 +913,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) } else { request_module_nowait("%s", op->name); } + mutex_unlock(&iwlwifi_opmode_table_mtx); return; @@ -944,6 +948,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, drv->cfg = cfg; init_completion(&drv->request_firmware_complete); + INIT_LIST_HEAD(&drv->list); ret = iwl_request_firmware(drv, true); @@ -966,6 +971,16 @@ void iwl_drv_stop(struct iwl_drv *drv) iwl_dealloc_ucode(drv); + mutex_lock(&iwlwifi_opmode_table_mtx); + /* + * List is empty (this item wasn't added) + * when firmware loading failed -- in that + * case we can't remove it from any list. + */ + if (!list_empty(&drv->list)) + list_del(&drv->list); + mutex_unlock(&iwlwifi_opmode_table_mtx); + kfree(drv); } @@ -988,6 +1003,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) int i; struct iwl_drv *drv; + mutex_lock(&iwlwifi_opmode_table_mtx); for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { if (strcmp(iwlwifi_opmode_table[i].name, name)) continue; @@ -995,8 +1011,10 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); + mutex_unlock(&iwlwifi_opmode_table_mtx); return 0; } + mutex_unlock(&iwlwifi_opmode_table_mtx); return -EIO; } EXPORT_SYMBOL_GPL(iwl_opmode_register); @@ -1006,6 +1024,7 @@ void iwl_opmode_deregister(const char *name) int i; struct iwl_drv *drv; + mutex_lock(&iwlwifi_opmode_table_mtx); for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { if (strcmp(iwlwifi_opmode_table[i].name, name)) continue; @@ -1018,8 +1037,10 @@ void iwl_opmode_deregister(const char *name) drv->op_mode = NULL; } } + mutex_unlock(&iwlwifi_opmode_table_mtx); return; } + mutex_unlock(&iwlwifi_opmode_table_mtx); } EXPORT_SYMBOL_GPL(iwl_opmode_deregister); @@ -1027,6 +1048,8 @@ static int __init iwl_drv_init(void) { int i; + mutex_init(&iwlwifi_opmode_table_mtx); + for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); -- GitLab From 7eb89baa261ea8f09d7f6ad3c4db270fd7f3d0bd Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Jun 2012 08:11:33 +0300 Subject: [PATCH 1344/6849] iwlwifi: s/iwl_read_targ_mem_words/iwl_read_targ_mem_bytes This macro gets the bufsize in bytes. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/main.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-io.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 656ed317c6d3..e620af3d592d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -406,7 +406,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) base = priv->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - iwl_read_targ_mem_words(priv->trans, base, &read, sizeof(read)); + iwl_read_targ_mem_bytes(priv->trans, base, &read, sizeof(read)); capacity = read.capacity; mode = read.mode; num_wraps = read.wrap_counter; @@ -1671,7 +1671,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) } /*TODO: Update dbgfs with ISR error stats obtained below */ - iwl_read_targ_mem_words(trans, base, &table, sizeof(table)); + iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table)); if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { IWL_ERR(trans, "Start IWL Error Log Dump:\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 4a9a45f771ed..45a59c940f81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -79,7 +79,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -#define iwl_read_targ_mem_words(trans, addr, buf, bufsize) \ +#define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \ do { \ BUILD_BUG_ON((bufsize) % sizeof(u32)); \ _iwl_read_targ_mem_words(trans, addr, buf, \ -- GitLab From e4b1681eafa62e2b34710f70ab3494c89cc03130 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Jun 2012 08:18:40 +0300 Subject: [PATCH 1345/6849] iwlwifi: iwl_{read,write}_targ_mem_words takes dwords Change its name to better reflect this. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-io.c | 20 ++++++++++---------- drivers/net/wireless/iwlwifi/iwl-io.h | 12 ++++++------ drivers/net/wireless/iwlwifi/iwl-test.c | 8 ++++---- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index f60be3993e81..7f49526222a8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -473,7 +473,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) } if (priv->wowlan_sram) - _iwl_read_targ_mem_words( + _iwl_read_targ_mem_dwords( priv->trans, 0x800000, priv->wowlan_sram, img->sec[IWL_UCODE_SECTION_DATA].len / 4); diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 5f2df70b73c1..66c873399aba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -298,8 +298,8 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) } EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); -void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, - void *buf, int words) +void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + void *buf, int dwords) { unsigned long flags; int offs; @@ -308,26 +308,26 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, spin_lock_irqsave(&trans->reg_lock, flags); if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); - for (offs = 0; offs < words; offs++) + for (offs = 0; offs < dwords; offs++) vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); iwl_release_nic_access(trans); } spin_unlock_irqrestore(&trans->reg_lock, flags); } -EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_words); +EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_dwords); u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) { u32 value; - _iwl_read_targ_mem_words(trans, addr, &value, 1); + _iwl_read_targ_mem_dwords(trans, addr, &value, 1); return value; } EXPORT_SYMBOL_GPL(iwl_read_targ_mem); -int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, - void *buf, int words) +int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + void *buf, int dwords) { unsigned long flags; int offs, result = 0; @@ -336,7 +336,7 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, spin_lock_irqsave(&trans->reg_lock, flags); if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); - for (offs = 0; offs < words; offs++) + for (offs = 0; offs < dwords; offs++) iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); iwl_release_nic_access(trans); } else @@ -345,10 +345,10 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, return result; } -EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_words); +EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_dwords); int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) { - return _iwl_write_targ_mem_words(trans, addr, &val, 1); + return _iwl_write_targ_mem_dwords(trans, addr, &val, 1); } EXPORT_SYMBOL_GPL(iwl_write_targ_mem); diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 45a59c940f81..50d3819739d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -76,18 +76,18 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask); void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); -void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, - void *buf, int words); +void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + void *buf, int dwords); #define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \ do { \ BUILD_BUG_ON((bufsize) % sizeof(u32)); \ - _iwl_read_targ_mem_words(trans, addr, buf, \ - (bufsize) / sizeof(u32));\ + _iwl_read_targ_mem_dwords(trans, addr, buf, \ + (bufsize) / sizeof(u32));\ } while (0) -int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, - void *buf, int words); +int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + void *buf, int dwords); u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index 7a264aee2534..81e8c7126d72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -476,9 +476,9 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) iwl_release_nic_access(trans); spin_unlock_irqrestore(&trans->reg_lock, flags); } else { /* target memory (SRAM) */ - _iwl_read_targ_mem_words(trans, addr, - tst->mem.addr, - tst->mem.size / 4); + _iwl_read_targ_mem_dwords(trans, addr, + tst->mem.addr, + tst->mem.size / 4); } tst->mem.nchunks = @@ -522,7 +522,7 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, *(u32 *)(buf+i)); } } else if (iwl_test_valid_hw_addr(tst, addr)) { - _iwl_write_targ_mem_words(trans, addr, buf, size/4); + _iwl_write_targ_mem_dwords(trans, addr, buf, size / 4); } else { return -EINVAL; } -- GitLab From f22d33289ae61c79aa27170f7b9e4b2b2e95281d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Jun 2012 19:36:18 +0300 Subject: [PATCH 1346/6849] iwlwifi: print more info when a queue is stuck Print some more info from the SCD's SRAM and dump the TRB from the FH. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-fh.h | 2 ++ drivers/net/wireless/iwlwifi/pcie/trans.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 74bce97a8600..806046641747 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -421,6 +421,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) (FH_SRVC_LOWER_BOUND + ((_chnl) - 9) * 0x4) #define FH_TX_CHICKEN_BITS_REG (FH_MEM_LOWER_BOUND + 0xE98) +#define FH_TX_TRB_REG(_chan) (FH_MEM_LOWER_BOUND + 0x958 + (_chan) * 4) + /* Instruct FH to increment the retry count of a packet when * it is brought from the memory to TX-FIFO */ diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 1eabb834e32a..1904fdaf3177 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -298,6 +298,10 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) struct iwl_tx_queue *txq = (void *)data; struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); + u32 scd_sram_addr = trans_pcie->scd_base_addr + + SCD_TX_STTS_MEM_LOWER_BOUND + (16 * txq->q.id); + u8 buf[16]; + int i; spin_lock(&txq->lock); /* check if triggered erroneously */ @@ -307,7 +311,6 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) } spin_unlock(&txq->lock); - IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, jiffies_to_msecs(trans_pcie->wd_timeout)); IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", @@ -317,6 +320,14 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) & (TFD_QUEUE_SIZE_MAX - 1), iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq->q.id))); + iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); + + iwl_print_hex_error(trans, buf, sizeof(buf)); + + for (i = 0; i < FH_TCSR_CHNL_NUM; i++) + IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i, + iwl_read_direct32(trans, FH_TX_TRB_REG(i))); + iwl_op_mode_nic_error(trans->op_mode); } -- GitLab From 1ce8658c08f1c1baa72e3cdea43a9d715dad08a2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 4 Jun 2012 16:48:17 +0300 Subject: [PATCH 1347/6849] iwlwifi: don't configure a txq that is being disabled This is not needed, we just need to tell the SCD not to use that queue. We will reconfigure that queue when we will use it again. Clean up a bit the code on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/internal.h | 4 -- drivers/net/wireless/iwlwifi/pcie/tx.c | 74 ++++++++------------ 2 files changed, 31 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 94201c4d6227..6c7b35530dad 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -340,10 +340,6 @@ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); -void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); -void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, - struct iwl_tx_queue *txq, - int tx_fifo_id, bool active); void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 35e82161ca43..4efdeb996e48 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -380,8 +380,8 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; } -static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, - u16 txq_id) +static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, + u16 txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 tbl_dw_addr; @@ -405,7 +405,7 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, return 0; } -static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) +static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) { /* Simply stop the queue, but don't change any configuration; * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ @@ -415,33 +415,6 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); } -void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) -{ - IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d\n", txq_id, index & 0xff); - iwl_write_direct32(trans, HBUS_TARG_WRPTR, - (index & 0xff) | (txq_id << 8)); - iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); -} - -void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, - struct iwl_tx_queue *txq, - int tx_fifo_id, bool active) -{ - int txq_id = txq->q.id; - - iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), - (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | - (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | - (1 << SCD_QUEUE_STTS_REG_POS_WSL) | - SCD_QUEUE_STTS_REG_MSK); - - if (active) - IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d\n", - txq_id, tx_fifo_id); - else - IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); -} - void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, int sta_id, int tid, int frame_limit, u16 ssn) @@ -454,7 +427,7 @@ void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, WARN_ONCE(1, "queue %d already used - expect issues", txq_id); /* Stop this Tx queue before configuring it */ - iwlagn_tx_queue_stop_scheduler(trans, txq_id); + iwl_txq_set_inactive(trans, txq_id); /* Set this queue as a chain-building queue unless it is CMD queue */ if (txq_id != trans_pcie->cmd_queue) @@ -465,17 +438,27 @@ void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ra_tid = BUILD_RAxTID(sta_id, tid); /* Map receiver-address / traffic-ID to this queue */ - iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); + iwl_txq_set_ratid_map(trans, ra_tid, txq_id); /* enable aggregations for the queue */ iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); + } else { + /* + * disable aggregations for the queue, this will also make the + * ra_tid mapping configuration irrelevant since it is now a + * non-AGG queue. + */ + iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); } /* Place first TFD at index corresponding to start sequence number. * Assumes that ssn_idx is valid (!= 0xFFF) */ trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); - iwl_trans_set_wr_ptrs(trans, txq_id, ssn); + + iwl_write_direct32(trans, HBUS_TARG_WRPTR, + (ssn & 0xff) | (txq_id << 8)); + iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); /* Set up Tx window size and frame limit for this queue */ iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + @@ -488,8 +471,13 @@ void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ - iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], - fifo, true); + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), + (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | + (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | + (1 << SCD_QUEUE_STTS_REG_POS_WSL) | + SCD_QUEUE_STTS_REG_MSK); + IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", + txq_id, fifo, ssn & 0xff); } void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, @@ -509,22 +497,22 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u16 rd_ptr, wr_ptr; + int n_bd = trans_pcie->txq[txq_id].q.n_bd; if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { WARN_ONCE(1, "queue %d not used", txq_id); return; } - iwlagn_tx_queue_stop_scheduler(trans, txq_id); - - iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); + rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); + wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); - trans_pcie->txq[txq_id].q.read_ptr = 0; - trans_pcie->txq[txq_id].q.write_ptr = 0; - iwl_trans_set_wr_ptrs(trans, txq_id, 0); + WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", + txq_id, rd_ptr, wr_ptr); - iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], - 0, false); + iwl_txq_set_inactive(trans, txq_id); + IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); } /*************** HOST COMMAND QUEUE FUNCTIONS *****/ -- GitLab From 5bf9a89d9a2eaa136a23d872db4195ca8cada4c8 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 7 Jun 2012 13:44:14 +0300 Subject: [PATCH 1348/6849] iwlwifi: remove lock around txq_enable This locking isn't needed. The only locking we need is when we access prph registers but there is already a separate lock for that. Since we haven't returned from the mac80211's IEEE80211_AMPDU_TX_OPERATIONAL ampdu_action, we cannot receive any Tx frame for that sta / tid while enabling the queue. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/internal.h | 5 +---- drivers/net/wireless/iwlwifi/pcie/trans.c | 5 ++--- drivers/net/wireless/iwlwifi/pcie/tx.c | 21 ++------------------ 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 6c7b35530dad..5024fb662bf6 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -339,12 +339,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); -void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); -void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, - int fifo, int sta_id, int tid, - int frame_limit, u16 ssn); void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); +void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 1904fdaf3177..4d4cbae83a07 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1068,9 +1068,8 @@ static void iwl_tx_start(struct iwl_trans *trans) for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { int fifo = trans_pcie->setup_q_to_fifo[i]; - __iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, - IWL_TID_NON_QOS, - SCD_FRAME_LIMIT, 0); + iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, + IWL_TID_NON_QOS, SCD_FRAME_LIMIT, 0); } /* Activate all Tx DMA/FIFO channels */ diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 4efdeb996e48..6baf8deef519 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -415,14 +415,11 @@ static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); } -void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, - int fifo, int sta_id, int tid, - int frame_limit, u16 ssn) +void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, + int sta_id, int tid, int frame_limit, u16 ssn) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - lockdep_assert_held(&trans_pcie->irq_lock); - if (test_and_set_bit(txq_id, trans_pcie->queue_used)) WARN_ONCE(1, "queue %d already used - expect issues", txq_id); @@ -480,20 +477,6 @@ void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, txq_id, fifo, ssn & 0xff); } -void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, - int sta_id, int tid, int frame_limit, u16 ssn) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - unsigned long flags; - - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - - __iwl_trans_pcie_txq_enable(trans, txq_id, fifo, sta_id, - tid, frame_limit, ssn); - - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); -} - void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -- GitLab From 11741739391c2f03bbaba5349f868618fe63922f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 7 Jun 2012 14:23:06 +0300 Subject: [PATCH 1349/6849] iwlwifi: comment that setting driver_data overrides info->control Using the driver_data area in ieee80211_tx_info which resides in the CB overrides the info->control field. Add a comment to prevent mistakes. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/tx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 0dfaf649b257..1f9457fdb933 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -403,6 +403,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) info->driver_data[0] = ctx; info->driver_data[1] = dev_cmd; + /* From now on, we cannot access info->control */ spin_lock(&priv->sta_lock); -- GitLab From 65fe593a519c4d7c62289d3b0a17ca412e95b037 Mon Sep 17 00:00:00 2001 From: Brandon Misemer Date: Fri, 8 Jun 2012 14:59:27 -0700 Subject: [PATCH 1350/6849] iwlwifi: Fix Makefile build order for built-in driver When the driver is built into the kernel instead of a module when the system boots it results in a panic. The order things are built in results in their initialization order when built into the kernel. Wifi has to be initialized before mvm or dvm. Reviewed-by: Donald H Fry Tested-by: Donald H Fry Reviewed-by: Emmanuel Grumbach Signed-off-by: Brandon Misemer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index afa9758364ea..170ec330d2a9 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,7 +1,3 @@ -obj-$(CONFIG_IWLDVM) += dvm/ - -CFLAGS_iwl-devtrace.o := -I$(src) - # common obj-$(CONFIG_IWLWIFI) += iwlwifi.o iwlwifi-objs += iwl-io.o @@ -16,3 +12,8 @@ iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o ccflags-y += -D__CHECK_ENDIAN__ -I$(src) + + +obj-$(CONFIG_IWLDVM) += dvm/ + +CFLAGS_iwl-devtrace.o := -I$(src) -- GitLab From 12af0468734dcef5d123d774f98e284deedd361c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 11 Jun 2012 11:44:49 +0300 Subject: [PATCH 1351/6849] iwlwifi: print even more info when a queue is stuck Since the queue gets stuck from time to time, we are trying to get as much information as we can when this occurs. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 26 +++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 4d4cbae83a07..d6a73179ebf1 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -315,10 +315,6 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) jiffies_to_msecs(trans_pcie->wd_timeout)); IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", txq->q.read_ptr, txq->q.write_ptr); - IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", - iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq->q.id)) - & (TFD_QUEUE_SIZE_MAX - 1), - iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq->q.id))); iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); @@ -328,6 +324,28 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i, iwl_read_direct32(trans, FH_TX_TRB_REG(i))); + for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { + u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i)); + u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; + bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); + u32 tbl_dw = + iwl_read_targ_mem(trans, + trans_pcie->scd_base_addr + + SCD_TRANS_TBL_OFFSET_QUEUE(i)); + + if (i & 0x1) + tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; + else + tbl_dw = tbl_dw & 0x0000FFFF; + + IWL_ERR(trans, + "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", + i, active ? "" : "in", fifo, tbl_dw, + iwl_read_prph(trans, + SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1), + iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); + } + iwl_op_mode_nic_error(trans->op_mode); } -- GitLab From f609607c009140491dd134f0165d9a8f9f726114 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 10 Jun 2012 14:25:22 +0300 Subject: [PATCH 1352/6849] iwlwifi: turn on a lockdep assertion CMD_SYNC is zero so the if (cmd->flags & CMD_SYNC) is never true and we never check the assertion. Signed-off-by: Dan Carpenter Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index cb1ca7a25dd5..76f259283c3a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -1265,7 +1265,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) * the mutex, this ensures we don't try to send two * (or more) synchronous commands at a time. */ - if (cmd->flags & CMD_SYNC) + if (!(cmd->flags & CMD_ASYNC)) lockdep_assert_held(&priv->mutex); if (priv->ucode_owner == IWL_OWNERSHIP_TM && -- GitLab From 49a4fc20df7fced31ffe4038b32b86a0438d1c27 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Jun 2012 18:25:09 +0300 Subject: [PATCH 1353/6849] iwlwifi: don't modify the timer if we don't Tx In fragmentation we don't update the write pointer of the HW immediately. So we shouldn't modify the timer in that case. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d6a73179ebf1..b647eb4dca64 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1354,7 +1354,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, skb->data + hdr_len, secondlen); /* start timer if queue currently empty */ - if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) + if (txq->need_update && q->read_ptr == q->write_ptr && + trans_pcie->wd_timeout) mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); /* Tell device the write index *just past* this latest filled TFD */ -- GitLab From 7bc057ffb5078d3e7f391ef2357f4ab01b9694e0 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Jun 2012 18:25:09 +0300 Subject: [PATCH 1354/6849] iwlwifi: warn if TFD index and WiFi Seq don't match For AGG queues, we must match between the WiFi sequence number and the TFD number. This is a HW (SCD) requirement. This is a take two of my iwlwifi: add debug in Tx path in AGG flow This will allow us to catch bad cases in which the packets aren't in the right place on the ring. which disappeared during code move. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index b647eb4dca64..9db8c6eaa153 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1261,6 +1261,19 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, spin_lock(&txq->lock); + /* In AGG mode, the index in the ring must correspond to the WiFi + * sequence number. This is a HW requirements to help the SCD to parse + * the BA. + * Check here that the packets are in the right place on the ring. + */ +#ifdef CONFIG_IWLWIFI_DEBUG + wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); + WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && + ((wifi_seq & 0xff) != q->write_ptr), + "Q: %d WiFi Seq %d tfdNum %d", + txq_id, wifi_seq, q->write_ptr); +#endif + /* Set up driver data for this TFD */ txq->entries[q->write_ptr].skb = skb; txq->entries[q->write_ptr].cmd = dev_cmd; -- GitLab From 3c70d08795f9c81d8dc69b98a0e65175f7786aa3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 12 Jun 2012 21:43:28 +0200 Subject: [PATCH 1355/6849] iwlwifi: fix 6035 device parameters Due to commit 26a7ca9a71a ("iwlwifi: refactor EEPROM reading/parsing") adding a new parameter, while commit d2c8b15d0cb ("iwlwifi: use correct supported firmware for 6035 and 6000g2") added a new device structure we need to add the parameter to the new device structure to make 6035 device work. Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/6000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c index cb08ba03aae7..4a57624afc40 100644 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c @@ -258,6 +258,7 @@ const struct iwl_cfg iwl6030_2bg_cfg = { .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ .base_params = &iwl6000_g2_base_params, \ .bt_params = &iwl6000_bt_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true -- GitLab From d4b10483223cf1a3fd2057785b12e2790a961867 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 12 Jun 2012 19:50:43 +0200 Subject: [PATCH 1356/6849] iwlwifi: use request_module instead of _nowait Since request_module_nowait() can't be backported use request_module() instead -- we don't need the asynchronous behaviour of request_module_nowait() here since we're running in the firmware request work struct. Tested-by: Donald H Fry Reviewed-by: Donald H Fry Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-drv.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 80898bb808b5..095547b37a27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -778,6 +778,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) const unsigned int api_min = drv->cfg->ucode_api_min; u32 api_ver; int i; + bool load_module = false; fw->ucode_capa.max_probe_length = 200; fw->ucode_capa.standard_phy_calibration_size = @@ -913,7 +914,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (!drv->op_mode) goto out_unbind; } else { - request_module_nowait("%s", op->name); + load_module = true; } mutex_unlock(&iwlwifi_opmode_table_mtx); @@ -923,6 +924,14 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * are doing the start() above. */ complete(&drv->request_firmware_complete); + + /* + * Load the module last so we don't block anything + * else from proceeding if the module fails to load + * or hangs loading. + */ + if (load_module) + request_module("%s", op->name); return; try_again: -- GitLab From 67711c17fc8bcab8f9e92c49049b8356f9a557c1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 12 Jun 2012 18:31:21 +0300 Subject: [PATCH 1357/6849] iwlwifi: WARN only once when we have trouble in reclaim This flow can actually happen due to a corner case in mac80211: the station is deleted before we get a chance to reclaim all the packets in flight in AGG queue. The tid_data for this station is zeroed, and we lose the match with the Tx queue. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 1f9457fdb933..5971a23aa47d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1183,7 +1183,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, } /*we can free until ssn % q.n_bd not inclusive */ - WARN_ON(iwl_reclaim(priv, sta_id, tid, txq_id, ssn, &skbs)); + WARN_ON_ONCE(iwl_reclaim(priv, sta_id, tid, + txq_id, ssn, &skbs)); iwlagn_check_ratid_empty(priv, sta_id, tid); freed = 0; -- GitLab From 33a264ddcded2120fc0baa7afe4bcc5b4df3c416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 12 Jun 2012 19:46:43 +0200 Subject: [PATCH 1358/6849] ARM: imx: cleanup otg_mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup the code for the otg_mode command line param: * Use the bool type as it applies here. * Qualify otg_mode_host with __initdata since this variable is only used in this context. * The __setup functions are not supposed to return a status code, but a boolean indicating whether the param has been handled. See obsolete_checksetup() in init/main.c. Signed-off-by: Benoît Thébaudeau Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/mach-cpuimx27.c | 8 ++++---- arch/arm/mach-imx/mach-cpuimx35.c | 8 ++++---- arch/arm/mach-imx/mach-cpuimx51sd.c | 8 ++++---- arch/arm/mach-imx/mach-eukrea_cpuimx25.c | 8 ++++---- arch/arm/mach-imx/mach-mx27_3ds.c | 8 ++++---- arch/arm/mach-imx/mach-mx31_3ds.c | 8 ++++---- arch/arm/mach-imx/mach-mx35_3ds.c | 8 ++++---- arch/arm/mach-imx/mach-mx51_babbage.c | 8 ++++---- arch/arm/mach-imx/mach-pca100.c | 8 ++++---- arch/arm/mach-imx/mach-pcm037.c | 8 ++++---- arch/arm/mach-imx/mach-pcm043.c | 8 ++++---- 11 files changed, 44 insertions(+), 44 deletions(-) diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index d085aea08709..dbbb97074876 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c @@ -233,18 +233,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .phy_mode = FSL_USB2_PHY_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init eukrea_cpuimx27_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", eukrea_cpuimx27_otg_mode); diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index c515f8ede1a1..c754adc2bd50 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -142,18 +142,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .workaround = FLS_USB2_WORKAROUND_ENGCM09152, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init eukrea_cpuimx35_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", eukrea_cpuimx35_otg_mode); diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index ac50f1671e38..2e3243ee899d 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -218,18 +218,18 @@ static const struct mxc_usbh_platform_data usbh1_config __initconst = { .portsc = MXC_EHCI_MODE_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init eukrea_cpuimx51sd_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", eukrea_cpuimx51sd_otg_mode); diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c index d1e04e676e33..77a9edd6b843 100644 --- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c +++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c @@ -109,18 +109,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .workaround = FLS_USB2_WORKAROUND_ENGCM09152, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init eukrea_cpuimx25_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", eukrea_cpuimx25_otg_mode); diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index c6d385c52257..cc4f83c76ace 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -241,18 +241,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .phy_mode = FSL_USB2_PHY_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init mx27_3ds_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", mx27_3ds_otg_mode); diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 4eafdf275ea2..ebcadd2e6be0 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -671,18 +671,18 @@ static const struct fsl_usb2_platform_data usbotg_pdata __initconst = { .phy_mode = FSL_USB2_PHY_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init mx31_3ds_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", mx31_3ds_otg_mode); diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index 28aa19476de7..af92e5e03163 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -540,18 +540,18 @@ static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { .portsc = MXC_EHCI_MODE_SERIAL, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init mx35_3ds_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", mx35_3ds_otg_mode); diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c index dde397014d4b..3ca6902dfc34 100644 --- a/arch/arm/mach-imx/mach-mx51_babbage.c +++ b/arch/arm/mach-imx/mach-mx51_babbage.c @@ -307,18 +307,18 @@ static const struct mxc_usbh_platform_data usbh1_config __initconst = { .portsc = MXC_EHCI_MODE_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init babbage_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", babbage_otg_mode); diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index 541152e450c4..9fe7a1b32d68 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c @@ -298,18 +298,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .phy_mode = FSL_USB2_PHY_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init pca100_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", pca100_otg_mode); diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index 0a40004154f2..debc286a41d7 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c @@ -557,18 +557,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .phy_mode = FSL_USB2_PHY_ULPI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init pcm037_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", pcm037_otg_mode); diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index 73585f55cca0..a8f4a0087b8c 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c @@ -330,18 +330,18 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { .phy_mode = FSL_USB2_PHY_UTMI, }; -static int otg_mode_host; +static bool otg_mode_host __initdata; static int __init pcm043_otg_mode(char *options) { if (!strcmp(options, "host")) - otg_mode_host = 1; + otg_mode_host = true; else if (!strcmp(options, "device")) - otg_mode_host = 0; + otg_mode_host = false; else pr_info("otg_mode neither \"host\" nor \"device\". " "Defaulting to device\n"); - return 0; + return 1; } __setup("otg_mode=", pcm043_otg_mode); -- GitLab From ed88bed881c9948c4035828c5d63f60c7b015f86 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 12 Jun 2012 19:26:33 +0300 Subject: [PATCH 1359/6849] x86/apic/irq_remap: Silence a bogus pr_err() There is an extra semicolon here so the pr_err() message is printed when it is not intended. Signed-off-by: Dan Carpenter Acked-by: Yinghai Lu Cc: Alexander Gordeev Cc: Suresh Siddha Cc: Joerg Roedel Link: http://lkml.kernel.org/r/20120612162633.GA11077@elgon.mountain Signed-off-by: Ingo Molnar --- drivers/iommu/intel_irq_remapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index dafbad06390a..853902a1b7db 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -938,7 +938,7 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest); if (err) { - if (assign_irq_vector(irq, cfg, data->affinity)); + if (assign_irq_vector(irq, cfg, data->affinity)) pr_err("Failed to recover vector for irq %d\n", irq); return err; } -- GitLab From e979e33c3972044e1be5e46552a02c3b9c0bc7a7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 11 Jun 2012 17:09:41 +0200 Subject: [PATCH 1360/6849] mac80211: allow cancelling dependent ROCs In my redesign of remain-on-channel I forgot that an item could be cancelled when it's a dependent item that is part of another item. Allow cancelling such items by removing them from the dependents list. Note that when we cancel the main item, all its dependents are also cancelled. It would be possible to not do that, but would need tricks to promote an item from dependent to top-level and is tricky in the HW ROC case. Reported-by: Ilan Peer Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 93d203cf8c12..9a974579ba89 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2305,6 +2305,21 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, mutex_lock(&local->mtx); list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { + struct ieee80211_roc_work *dep, *tmp2; + + list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { + if (!mgmt_tx && (unsigned long)dep != cookie) + continue; + else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) + continue; + /* found dependent item -- just remove it */ + list_del(&dep->list); + mutex_unlock(&local->mtx); + + ieee80211_roc_notify_destroy(dep); + return 0; + } + if (!mgmt_tx && (unsigned long)roc != cookie) continue; else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) @@ -2319,6 +2334,13 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, return -ENOENT; } + /* + * We found the item to cancel, so do that. Note that it + * may have dependents, which we also cancel (and send + * the expired signal for.) Not doing so would be quite + * tricky here, but we may need to fix it later. + */ + if (local->ops->remain_on_channel) { if (found->started) { ret = drv_cancel_remain_on_channel(local); -- GitLab From fe20b39ec32e975f1054c0b7866c873a954adf05 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 12 Jun 2012 12:53:13 +0300 Subject: [PATCH 1361/6849] cfg80211: fix potential deadlock in regulatory reg_timeout_work() calls restore_regulatory_settings() which takes cfg80211_mutex. reg_set_request_processed() already holds cfg80211_mutex before calling cancel_delayed_work_sync(reg_timeout), so it might deadlock. Call the async cancel_delayed_work instead, in order to avoid the potential deadlock. This is the relevant lockdep warning: cfg80211: Calling CRDA for country: XX ====================================================== [ INFO: possible circular locking dependency detected ] 3.4.0-rc5-wl+ #26 Not tainted ------------------------------------------------------- kworker/0:2/1391 is trying to acquire lock: (cfg80211_mutex){+.+.+.}, at: [] restore_regulatory_settings+0x34/0x418 [cfg80211] but task is already holding lock: ((reg_timeout).work){+.+...}, at: [] process_one_work+0x1f0/0x480 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 ((reg_timeout).work){+.+...}: [] validate_chain+0xb94/0x10f0 [] __lock_acquire+0x8c8/0x9b0 [] lock_acquire+0xf0/0x114 [] wait_on_work+0x4c/0x154 [] __cancel_work_timer+0xd4/0x11c [] cancel_delayed_work_sync+0x1c/0x20 [] reg_set_request_processed+0x50/0x78 [cfg80211] [] set_regdom+0x550/0x600 [cfg80211] [] nl80211_set_reg+0x218/0x258 [cfg80211] [] genl_rcv_msg+0x1a8/0x1e8 [] netlink_rcv_skb+0x5c/0xc0 [] genl_rcv+0x28/0x34 [] netlink_unicast+0x15c/0x228 [] netlink_sendmsg+0x218/0x298 [] sock_sendmsg+0xa4/0xc0 [] __sys_sendmsg+0x1e4/0x268 [] sys_sendmsg+0x4c/0x70 [] ret_fast_syscall+0x0/0x3c -> #1 (reg_mutex){+.+.+.}: [] validate_chain+0xb94/0x10f0 [] __lock_acquire+0x8c8/0x9b0 [] lock_acquire+0xf0/0x114 [] mutex_lock_nested+0x48/0x320 [] reg_todo+0x30/0x538 [cfg80211] [] process_one_work+0x2a0/0x480 [] worker_thread+0x1bc/0x2bc [] kthread+0x98/0xa4 [] kernel_thread_exit+0x0/0x8 -> #0 (cfg80211_mutex){+.+.+.}: [] print_circular_bug+0x68/0x2cc [] validate_chain+0x978/0x10f0 [] __lock_acquire+0x8c8/0x9b0 [] lock_acquire+0xf0/0x114 [] mutex_lock_nested+0x48/0x320 [] restore_regulatory_settings+0x34/0x418 [cfg80211] [] reg_timeout_work+0x1c/0x20 [cfg80211] [] process_one_work+0x2a0/0x480 [] worker_thread+0x1bc/0x2bc [] kthread+0x98/0xa4 [] kernel_thread_exit+0x0/0x8 other info that might help us debug this: Chain exists of: cfg80211_mutex --> reg_mutex --> (reg_timeout).work Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock((reg_timeout).work); lock(reg_mutex); lock((reg_timeout).work); lock(cfg80211_mutex); *** DEADLOCK *** 2 locks held by kworker/0:2/1391: #0: (events){.+.+.+}, at: [] process_one_work+0x1f0/0x480 #1: ((reg_timeout).work){+.+...}, at: [] process_one_work+0x1f0/0x480 stack backtrace: [] (unwind_backtrace+0x0/0x12c) from [] (dump_stack+0x20/0x24) [] (dump_stack+0x20/0x24) from [] (print_circular_bug+0x280/0x2cc) [] (print_circular_bug+0x280/0x2cc) from [] (validate_chain+0x978/0x10f0) [] (validate_chain+0x978/0x10f0) from [] (__lock_acquire+0x8c8/0x9b0) [] (__lock_acquire+0x8c8/0x9b0) from [] (lock_acquire+0xf0/0x114) [] (lock_acquire+0xf0/0x114) from [] (mutex_lock_nested+0x48/0x320) [] (mutex_lock_nested+0x48/0x320) from [] (restore_regulatory_settings+0x34/0x418 [cfg80211]) [] (restore_regulatory_settings+0x34/0x418 [cfg80211]) from [] (reg_timeout_work+0x1c/0x20 [cfg80211]) [] (reg_timeout_work+0x1c/0x20 [cfg80211]) from [] (process_one_work+0x2a0/0x480) [] (process_one_work+0x2a0/0x480) from [] (worker_thread+0x1bc/0x2bc) [] (worker_thread+0x1bc/0x2bc) from [] (kthread+0x98/0xa4) [] (kthread+0x98/0xa4) from [] (kernel_thread_exit+0x0/0x8) cfg80211: Calling CRDA to update world regulatory domain cfg80211: World regulatory domain updated: cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp) cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm) cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm) cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm) cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm) cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm) Cc: stable@kernel.org Signed-off-by: Eliad Peller Signed-off-by: Johannes Berg --- net/wireless/reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 15f347477a99..baf5704740ee 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1389,7 +1389,7 @@ static void reg_set_request_processed(void) spin_unlock(®_requests_lock); if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) - cancel_delayed_work_sync(®_timeout); + cancel_delayed_work(®_timeout); if (need_more_processing) schedule_work(®_work); -- GitLab From 554a43d5e77e8256aa9685ffd19ad555e6f77979 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 12 Jun 2012 12:41:15 +0300 Subject: [PATCH 1362/6849] mac80211: check sdata_running on ieee80211_set_bitrate_mask Otherwise, we might call the driver callback before the interface was uploaded. Solves the following warning: WARNING: at net/mac80211/driver-ops.h:12 ieee80211_set_bitrate_mask+0xbc/0x18c [mac80211]() wlan0: Failed check-sdata-in-driver check, flags: 0x0 Modules linked in: wlcore_sdio wl12xx wl18xx wlcore mac80211 cfg80211 [last unloaded: cfg80211] [] (unwind_backtrace+0x0/0x12c) from [] (dump_stack+0x20/0x24) [] (dump_stack+0x20/0x24) from [] (warn_slowpath_common+0x5c/0x74) [] (warn_slowpath_common+0x5c/0x74) from [] (warn_slowpath_fmt+0x40/0x48) [] (warn_slowpath_fmt+0x40/0x48) from [] (ieee80211_set_bitrate_mask+0xbc/0x18c [mac80211]) [] (ieee80211_set_bitrate_mask+0xbc/0x18c [mac80211]) from [] (nl80211_set_tx_bitrate_mask+0x350/0x358 [cfg80211]) [] (nl80211_set_tx_bitrate_mask+0x350/0x358 [cfg80211]) from [] (genl_rcv_msg+0x1a8/0x1e8) [] (genl_rcv_msg+0x1a8/0x1e8) from [] (netlink_rcv_skb+0x5c/0xc0) [] (netlink_rcv_skb+0x5c/0xc0) from [] (genl_rcv+0x28/0x34) [] (genl_rcv+0x28/0x34) from [] (netlink_unicast+0x158/0x234) [] (netlink_unicast+0x158/0x234) from [] (netlink_sendmsg+0x218/0x298) [] (netlink_sendmsg+0x218/0x298) from [] (sock_sendmsg+0xa4/0xc0) [] (sock_sendmsg+0xa4/0xc0) from [] (__sys_sendmsg+0x1d8/0x254) [] (__sys_sendmsg+0x1d8/0x254) from [] (sys_sendmsg+0x4c/0x70) [] (sys_sendmsg+0x4c/0x70) from [] (ret_fast_syscall+0x0/0x3c) Note that calling the driver can also result in undefined behaviour since it doesn't have to deal with calls while down. Signed-off-by: Eliad Peller [removed timestamps, added note - Johannes] Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e9cecca5c44d..7d5108a867ad 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2093,6 +2093,9 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); int i, ret; + if (!ieee80211_sdata_running(sdata)) + return -ENETDOWN; + if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { ret = drv_set_bitrate_mask(local, sdata, mask); if (ret) -- GitLab From 79543d8eecc0957ac6fe3ec1e2486ad31d4b67a3 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Tue, 12 Jun 2012 09:59:45 +0300 Subject: [PATCH 1363/6849] mac80211: stop polling in disassociation Stop connection monitor poll during disassociation. This clears the polling flags and if a scan was deferred it will be run. Without this fix, if a scan was deferred due to connection monitoring while disassociation happens, this scan blocks further scan requests until interface down/up which causes problems connecting to another AP. Signed-off-by: David Spinadel Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 91d84cc77bbf..66e4fcdd1c6b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1352,6 +1352,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, if (WARN_ON(!ifmgd->associated)) return; + ieee80211_stop_poll(sdata); + memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); ifmgd->associated = NULL; @@ -2612,8 +2614,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; u8 frame_buf[DEAUTH_DISASSOC_LEN]; - ieee80211_stop_poll(sdata); - ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, false, frame_buf); mutex_unlock(&ifmgd->mtx); -- GitLab From ac4d82fa01c194dba10b9a7c35449ba36eb642fc Mon Sep 17 00:00:00 2001 From: Pontus Fuchs Date: Tue, 12 Jun 2012 14:13:19 +0200 Subject: [PATCH 1364/6849] mac80211: Disallow changing chan type on monitor when CHAN_MODE_FIXED If you add a monitor interface in parallel to a normal interface mac80211 will let you to change the channel type on the monitor interface even if you are connected. Add an explicit check to disallow this. Signed-off-by: Pontus Fuchs [fix typo in commit log, use sdata instead of netdev] Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9a974579ba89..cd8b1fb05d42 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -689,7 +689,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy, case CHAN_MODE_HOPPING: return -EBUSY; case CHAN_MODE_FIXED: - if (local->oper_channel != chan) + if (local->oper_channel != chan || + (!sdata && local->_oper_channel_type != channel_type)) return -EBUSY; if (!sdata && local->_oper_channel_type == channel_type) return 0; -- GitLab From 4a4ab0d7c9abe4e403bcea6ae2fc5d3f28a64a29 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 13 Jun 2012 11:17:11 +0200 Subject: [PATCH 1365/6849] nl80211: fix sched scan match attribute name It should be NL80211_SCHED_SCAN_MATCH_ATTR_SSID as documented, not NL80211_ATTR_SCHED_SCAN_MATCH_SSID. Signed-off-by: Johannes Berg --- include/linux/nl80211.h | 5 ++++- net/wireless/nl80211.c | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c61e1621822c..e7b1fc1fe26b 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1963,7 +1963,7 @@ enum nl80211_reg_rule_attr { enum nl80211_sched_scan_match_attr { __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, - NL80211_ATTR_SCHED_SCAN_MATCH_SSID, + NL80211_SCHED_SCAN_MATCH_ATTR_SSID, /* keep last */ __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, @@ -1971,6 +1971,9 @@ enum nl80211_sched_scan_match_attr { __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 }; +/* only for backward compatibility */ +#define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID + /** * enum nl80211_reg_rule_flags - regulatory rule flags * diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index dd94ee5fb40a..7db0aee8cd5b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -250,7 +250,7 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { static const struct nla_policy nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { - [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY, + [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY, .len = IEEE80211_MAX_SSID_LEN }, }; @@ -4253,7 +4253,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, nla_data(attr), nla_len(attr), nl80211_match_policy); - ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; + ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; if (ssid) { if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { err = -EINVAL; -- GitLab From 73c3df3ba3f2d7fe3ea47f944282f3cda31c5505 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 13 Jun 2012 11:17:14 +0200 Subject: [PATCH 1366/6849] cfg80211/nl80211: fix kernel-doc Add missing entries to nl80211.h and fix the kernel-doc notation in cfg80211.h. Signed-off-by: Johannes Berg --- include/linux/nl80211.h | 33 ++++++++++++++++++++++++++++----- include/net/cfg80211.h | 8 ++++---- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index e7b1fc1fe26b..e4f41bdebc07 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -277,6 +277,12 @@ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) * + * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC + * (for the BSSID) and %NL80211_ATTR_PMKID. + * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC + * (for the BSSID) and %NL80211_ATTR_PMKID. + * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. + * * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain * has been changed and provides details of the request information * that caused the change such as who initiated the regulatory request @@ -456,6 +462,10 @@ * the frame. * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for * backward compatibility. + * + * @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE + * @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE + * * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command * is used to configure connection quality monitoring notification trigger * levels. @@ -771,6 +781,13 @@ enum nl80211_commands { * section 7.3.2.25.1, e.g. 0x000FAC04) * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and * CCMP keys, each six bytes in little endian + * @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key + * @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the + * default management key + * @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or + * other commands, indicates which pairwise cipher suites are used + * @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or + * other commands, indicates which group cipher suite is used * * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing @@ -1006,6 +1023,8 @@ enum nl80211_commands { * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was * acknowledged by the recipient. * + * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. + * * @NL80211_ATTR_CQM: connection quality monitor configuration in a * nested attribute with %NL80211_ATTR_CQM_* sub-attributes. * @@ -1063,7 +1082,7 @@ enum nl80211_commands { * flag isn't set, the frame will be rejected. This is also used as an * nl80211 capability flag. * - * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16) + * @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16) * * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags * attributes, specifying what a key should be set as default as. @@ -1087,10 +1106,10 @@ enum nl80211_commands { * indicate which WoW triggers should be enabled. This is also * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN * triggers. - + * * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan * cycles, in msecs. - + * * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more * sets of attributes to match during scheduled scans. Only BSSs * that match any of the sets will be reported. These are @@ -1117,7 +1136,7 @@ enum nl80211_commands { * are managed in software: interfaces of these types aren't subject to * any restrictions in their number or combinations. * - * @%NL80211_ATTR_REKEY_DATA: nested attribute containing the information + * @NL80211_ATTR_REKEY_DATA: nested attribute containing the information * necessary for GTK rekeying in the device, see &enum nl80211_rekey_data. * * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan, @@ -1184,7 +1203,6 @@ enum nl80211_commands { * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from * &enum nl80211_feature_flags and is advertised in wiphy information. * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe - * * requests while operating in AP-mode. * This attribute holds a bitmap of the supported protocols for * offloading (see &enum nl80211_probe_resp_offload_support_attr). @@ -2507,6 +2525,11 @@ enum nl80211_band { NL80211_BAND_5GHZ, }; +/** + * enum nl80211_ps_state - powersave state + * @NL80211_PS_DISABLED: powersave is disabled + * @NL80211_PS_ENABLED: powersave is enabled + */ enum nl80211_ps_state { NL80211_PS_DISABLED, NL80211_PS_ENABLED, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 778e533a9734..76d54725ea31 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -627,10 +627,10 @@ struct sta_bss_parameters { * @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state - * @signal: the signal strength, type depends on the wiphy's signal_type - NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. - * @signal_avg: avg signal strength, type depends on the wiphy's signal_type - NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal: The signal strength, type depends on the wiphy's signal_type. + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. * @txrate: current unicast bitrate from this station * @rxrate: current unicast bitrate to this station * @rx_packets: packets received from this station -- GitLab From 85f243912b99b053ce0624c30609f5d8fd4445d2 Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Wed, 13 Jun 2012 10:09:51 +0200 Subject: [PATCH 1367/6849] ASoC: Ux500: Correct license strings GPLv2 -> GPL v2 Reported-by: Stephen Rothwell Signed-off-by: Ola Lilja Acked-by: Linus Walleij Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 2 +- sound/soc/ux500/ux500_msp_dai.c | 2 +- sound/soc/ux500/ux500_msp_i2s.c | 2 +- sound/soc/ux500/ux500_pcm.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 95dc7d5bb076..389dd660b511 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2518,4 +2518,4 @@ static struct platform_driver ab8500_codec_platform_driver = { }; module_platform_driver(ab8500_codec_platform_driver); -MODULE_LICENSE("GPLv2"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 93c6c40e724c..62ac0285bfaf 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -840,4 +840,4 @@ static struct platform_driver msp_i2s_driver = { }; module_platform_driver(msp_i2s_driver); -MODULE_LICENSE("GPLv2"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 496dec10c96e..ee14d2dac2f5 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -739,4 +739,4 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, devm_kfree(&pdev->dev, msp); } -MODULE_LICENSE("GPLv2"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 66b080e5de96..97d8e4de29c2 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -315,4 +315,4 @@ static struct platform_driver ux500_pcm_driver = { }; module_platform_driver(ux500_pcm_driver); -MODULE_LICENSE("GPLv2"); +MODULE_LICENSE("GPL v2"); -- GitLab From 8994a5e1d2443511e677d62e97d7de3718b71325 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 13 Jun 2012 14:36:07 +0800 Subject: [PATCH 1368/6849] ASoC: ml26124: Convert to devm_regmap_init_i2c This fixes a leak if snd_soc_register_codec fails. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/ml26124.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 22cb5bf59273..96aa5fa05160 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -638,7 +638,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, priv); - priv->regmap = regmap_init_i2c(i2c, &ml26124_i2c_regmap); + priv->regmap = devm_regmap_init_i2c(i2c, &ml26124_i2c_regmap); if (IS_ERR(priv->regmap)) { ret = PTR_ERR(priv->regmap); dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret); @@ -651,10 +651,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c, static __devexit int ml26124_i2c_remove(struct i2c_client *client) { - struct ml26124_priv *priv = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - regmap_exit(priv->regmap); return 0; } -- GitLab From 0ff472467a04dfecffbf44d2414c756c83212cbe Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Jun 2012 17:18:49 +0800 Subject: [PATCH 1369/6849] regulator: wm8350: Add missing min_uV and uV_step settings for DCDC4 Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index ca678eea79de..53bf3df02975 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1105,6 +1105,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_UV_DC4, .type = REGULATOR_VOLTAGE, .n_voltages = WM8350_DCDC_MAX_VSEL + 1, + .min_uV = 850000, + .uV_step = 25000, .vsel_reg = WM8350_DCDC4_CONTROL, .vsel_mask = WM8350_DC4_VSEL_MASK, .enable_reg = WM8350_DCDC_LDO_REQUESTED, -- GitLab From 3fe3a182adfeca84f39751af03c8571831a0877f Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 13 Jun 2012 17:26:15 +0900 Subject: [PATCH 1370/6849] regulator: Remove s5m8767a buck initialization As s5m8767a is revisioned, remove unnecessary buck 2,3,4 initialization routine. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 290d6fc01029..4edf344fb7c4 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -668,9 +668,6 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) s5m8767->buck4_vol[i]); } } - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff); - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff); - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff); if (s5m8767->buck2_ramp) s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08); -- GitLab From 38c20eb23fb7b5505ac80595f18f4209abc19cd3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Jun 2012 16:34:55 +0800 Subject: [PATCH 1371/6849] regulator: wm8400: Use wm8400_ldo_list_voltage instead of open code to verify selected voltage Call wm8400_ldo_list_voltage() instead of open code to verify selected voltage falls within specified range. Use wm8400_ldo_list_voltage() here is less error prone. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8400-regulator.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index f365795d51c2..9f9df8eef1a1 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -35,27 +35,19 @@ static int wm8400_ldo_map_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { u16 val; + int volt; if (min_uV < 900000 || min_uV > 3300000) return -EINVAL; - if (min_uV < 1700000) { - /* Steps of 50mV from 900mV; */ + if (min_uV < 1700000) /* Steps of 50mV from 900mV; */ val = DIV_ROUND_UP(min_uV - 900000, 50000); + else /* Steps of 100mV from 1700mV */ + val = DIV_ROUND_UP(min_uV - 1700000, 100000) + 15; - if ((val * 50000) + 900000 > max_uV) - return -EINVAL; - BUG_ON((val * 50000) + 900000 < min_uV); - } else { - /* Steps of 100mV from 1700mV */ - val = DIV_ROUND_UP(min_uV - 1700000, 100000); - - if ((val * 100000) + 1700000 > max_uV) - return -EINVAL; - BUG_ON((val * 100000) + 1700000 < min_uV); - - val += 0xf; - } + volt = wm8400_ldo_list_voltage(dev, val); + if (volt < min_uV || volt > max_uV) + return -EINVAL; return val; } -- GitLab From 7a824e214e25a49442fe868dac0af8a904b24f58 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Mon, 11 Jun 2012 18:04:38 +0800 Subject: [PATCH 1372/6849] ASoC: mmp: add audio dma support mmp-pcm handle audio dma based on soc-dmaengine Support mmp and pxa910 Signed-off-by: Zhangfei Gao Signed-off-by: Leo Yan Signed-off-by: Qiao Zhou Signed-off-by: Mark Brown --- include/linux/platform_data/mmp_audio.h | 22 ++ sound/soc/pxa/Kconfig | 9 + sound/soc/pxa/Makefile | 2 + sound/soc/pxa/mmp-pcm.c | 297 ++++++++++++++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 include/linux/platform_data/mmp_audio.h create mode 100644 sound/soc/pxa/mmp-pcm.c diff --git a/include/linux/platform_data/mmp_audio.h b/include/linux/platform_data/mmp_audio.h new file mode 100644 index 000000000000..0f25d165abd6 --- /dev/null +++ b/include/linux/platform_data/mmp_audio.h @@ -0,0 +1,22 @@ +/* + * MMP Platform AUDIO Management + * + * Copyright (c) 2011 Marvell Semiconductors Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef MMP_AUDIO_H +#define MMP_AUDIO_H + +struct mmp_audio_platdata { + u32 period_max_capture; + u32 buffer_max_capture; + u32 period_max_playback; + u32 buffer_max_playback; +}; + +#endif /* MMP_AUDIO_H */ diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index a0f7d3cfa470..5d76e2971fbe 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -8,6 +8,15 @@ config SND_PXA2XX_SOC the PXA2xx AC97, I2S or SSP interface. You will also need to select the audio interfaces to support below. +config SND_MMP_SOC + bool "Soc Audio for Marvell MMP chips" + depends on ARCH_MMP + select SND_SOC_DMAENGINE_PCM + select SND_ARM + help + Say Y if you want to add support for codecs attached to + the MMP SSPA interface. + config SND_PXA2XX_AC97 tristate select SND_AC97_CODEC diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index af357623be9d..f913e9bfce4f 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -3,11 +3,13 @@ snd-soc-pxa2xx-objs := pxa2xx-pcm.o snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o snd-soc-pxa-ssp-objs := pxa-ssp.o +snd-soc-mmp-objs := mmp-pcm.o obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o +obj-$(CONFIG_SND_MMP_SOC) += snd-soc-mmp.o # PXA Machine Support snd-soc-corgi-objs := corgi.o diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c new file mode 100644 index 000000000000..73ac5463c9e4 --- /dev/null +++ b/sound/soc/pxa/mmp-pcm.c @@ -0,0 +1,297 @@ +/* + * linux/sound/soc/pxa/mmp-pcm.c + * + * Copyright (C) 2011 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mmp_dma_data { + int ssp_id; + struct resource *dma_res; +}; + +#define MMP_PCM_INFO (SNDRV_PCM_INFO_MMAP | \ + SNDRV_PCM_INFO_MMAP_VALID | \ + SNDRV_PCM_INFO_INTERLEAVED | \ + SNDRV_PCM_INFO_PAUSE | \ + SNDRV_PCM_INFO_RESUME) + +#define MMP_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_pcm_hardware mmp_pcm_hardware[] = { + { + .info = MMP_PCM_INFO, + .formats = MMP_PCM_FORMATS, + .period_bytes_min = 1024, + .period_bytes_max = 2048, + .periods_min = 2, + .periods_max = 32, + .buffer_bytes_max = 4096, + .fifo_size = 32, + }, + { + .info = MMP_PCM_INFO, + .formats = MMP_PCM_FORMATS, + .period_bytes_min = 1024, + .period_bytes_max = 2048, + .periods_min = 2, + .periods_max = 32, + .buffer_bytes_max = 4096, + .fifo_size = 32, + }, +}; + +static int mmp_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct pxa2xx_pcm_dma_params *dma_params; + struct dma_slave_config slave_config; + int ret; + + dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + if (!dma_params) + return 0; + + ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); + if (ret) + return ret; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + slave_config.dst_addr = dma_params->dev_addr; + slave_config.dst_maxburst = 4; + } else { + slave_config.src_addr = dma_params->dev_addr; + slave_config.src_maxburst = 4; + } + + ret = dmaengine_slave_config(chan, &slave_config); + if (ret) + return ret; + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static bool filter(struct dma_chan *chan, void *param) +{ + struct mmp_dma_data *dma_data = param; + bool found = false; + char *devname; + + devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name, + dma_data->ssp_id); + if ((strcmp(dev_name(chan->device->dev), devname) == 0) && + (chan->chan_id == dma_data->dma_res->start)) { + found = true; + } + + kfree(devname); + return found; +} + +static int mmp_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct platform_device *pdev = to_platform_device(rtd->platform->dev); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct mmp_dma_data *dma_data; + struct resource *r; + int ret; + + r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); + if (!r) + return -EBUSY; + + snd_soc_set_runtime_hwparams(substream, + &mmp_pcm_hardware[substream->stream]); + dma_data = devm_kzalloc(&pdev->dev, + sizeof(struct mmp_dma_data), GFP_KERNEL); + if (dma_data == NULL) + return -ENOMEM; + + dma_data->dma_res = r; + dma_data->ssp_id = cpu_dai->id; + + ret = snd_dmaengine_pcm_open(substream, filter, dma_data); + if (ret) { + devm_kfree(&pdev->dev, dma_data); + return ret; + } + + snd_dmaengine_pcm_set_data(substream, dma_data); + return 0; +} + +static int mmp_pcm_close(struct snd_pcm_substream *substream) +{ + struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct platform_device *pdev = to_platform_device(rtd->platform->dev); + + snd_dmaengine_pcm_close(substream); + devm_kfree(&pdev->dev, dma_data); + return 0; +} + +static int mmp_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned long off = vma->vm_pgoff; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + return remap_pfn_range(vma, vma->vm_start, + __phys_to_pfn(runtime->dma_addr) + off, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +} + +struct snd_pcm_ops mmp_pcm_ops = { + .open = mmp_pcm_open, + .close = mmp_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = mmp_pcm_hw_params, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, + .mmap = mmp_pcm_mmap, +}; + +static void mmp_pcm_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + struct gen_pool *gpool; + + gpool = sram_get_gpool("asram"); + if (!gpool) + return; + + for (stream = 0; stream < 2; stream++) { + size_t size = mmp_pcm_hardware[stream].buffer_bytes_max; + + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + gen_pool_free(gpool, (unsigned long)buf->area, size); + buf->area = NULL; + } + + return; +} + +static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream, + int stream) +{ + struct snd_dma_buffer *buf = &substream->dma_buffer; + size_t size = mmp_pcm_hardware[stream].buffer_bytes_max; + struct gen_pool *gpool; + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = substream->pcm->card->dev; + buf->private_data = NULL; + + gpool = sram_get_gpool("asram"); + if (!gpool) + return -ENOMEM; + + buf->area = (unsigned char *)gen_pool_alloc(gpool, size); + if (!buf->area) + return -ENOMEM; + buf->addr = gen_pool_virt_to_phys(gpool, (unsigned long)buf->area); + buf->bytes = size; + return 0; +} + +int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm_substream *substream; + struct snd_pcm *pcm = rtd->pcm; + int ret = 0, stream; + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + + ret = mmp_pcm_preallocate_dma_buffer(substream, stream); + if (ret) + goto err; + } + + return 0; + +err: + mmp_pcm_free_dma_buffers(pcm); + return ret; +} + +struct snd_soc_platform_driver mmp_soc_platform = { + .ops = &mmp_pcm_ops, + .pcm_new = mmp_pcm_new, + .pcm_free = mmp_pcm_free_dma_buffers, +}; + +static __devinit int mmp_pcm_probe(struct platform_device *pdev) +{ + struct mmp_audio_platdata *pdata = pdev->dev.platform_data; + + if (pdata) { + mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].buffer_bytes_max = + pdata->buffer_max_playback; + mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].period_bytes_max = + pdata->period_max_playback; + mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].buffer_bytes_max = + pdata->buffer_max_capture; + mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max = + pdata->period_max_capture; + } + return snd_soc_register_platform(&pdev->dev, &mmp_soc_platform); +} + +static int __devexit mmp_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static struct platform_driver mmp_pcm_driver = { + .driver = { + .name = "mmp-pcm-audio", + .owner = THIS_MODULE, + }, + + .probe = mmp_pcm_probe, + .remove = __devexit_p(mmp_pcm_remove), +}; + +module_platform_driver(mmp_pcm_driver); + +MODULE_AUTHOR("Leo Yan "); +MODULE_DESCRIPTION("MMP Soc Audio DMA module"); +MODULE_LICENSE("GPL"); -- GitLab From fa375d42f0e531b7ca4316ea9fd5444e01d585e8 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Mon, 11 Jun 2012 18:04:39 +0800 Subject: [PATCH 1373/6849] ASoC: mmp: add sspa support The SSPA is a configurable multi-channel audio serial (TDM) interface. It's configurable at runtime to support up to 128 channels and the number of bits per sample: 8, 12, 16, 20, 24 and 32 bits. It also support stereo format: I2S, left-justified or right-justified. Signed-off-by: Zhangfei Gao Signed-off-by: Leo Yan Signed-off-by: Mark Brown --- sound/soc/pxa/Kconfig | 3 + sound/soc/pxa/Makefile | 2 + sound/soc/pxa/mmp-sspa.c | 480 +++++++++++++++++++++++++++++++++++++++ sound/soc/pxa/mmp-sspa.h | 92 ++++++++ 4 files changed, 577 insertions(+) create mode 100644 sound/soc/pxa/mmp-sspa.c create mode 100644 sound/soc/pxa/mmp-sspa.h diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 5d76e2971fbe..6c3d00b8ea0b 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -35,6 +35,9 @@ config SND_PXA_SOC_SSP tristate select PXA_SSP +config SND_MMP_SOC_SSPA + tristate + config SND_PXA2XX_SOC_CORGI tristate "SoC Audio support for Sharp Zaurus SL-C7x0" depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index f913e9bfce4f..07b841746fc3 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -4,12 +4,14 @@ snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o snd-soc-pxa-ssp-objs := pxa-ssp.o snd-soc-mmp-objs := mmp-pcm.o +snd-soc-mmp-sspa-objs := mmp-sspa.o obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o obj-$(CONFIG_SND_MMP_SOC) += snd-soc-mmp.o +obj-$(CONFIG_SND_MMP_SOC_SSPA) += snd-soc-mmp-sspa.o # PXA Machine Support snd-soc-corgi-objs := corgi.o diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c new file mode 100644 index 000000000000..4d6cb8a30fc8 --- /dev/null +++ b/sound/soc/pxa/mmp-sspa.c @@ -0,0 +1,480 @@ +/* + * linux/sound/soc/pxa/mmp-sspa.c + * Base on pxa2xx-ssp.c + * + * Copyright (C) 2011 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mmp-sspa.h" + +/* + * SSPA audio private data + */ +struct sspa_priv { + struct ssp_device *sspa; + struct pxa2xx_pcm_dma_params *dma_params; + struct clk *audio_clk; + struct clk *sysclk; + int dai_fmt; + int running_cnt; +}; + +static void mmp_sspa_write_reg(struct ssp_device *sspa, u32 reg, u32 val) +{ + __raw_writel(val, sspa->mmio_base + reg); +} + +static u32 mmp_sspa_read_reg(struct ssp_device *sspa, u32 reg) +{ + return __raw_readl(sspa->mmio_base + reg); +} + +static void mmp_sspa_tx_enable(struct ssp_device *sspa) +{ + unsigned int sspa_sp; + + sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP); + sspa_sp |= SSPA_SP_S_EN; + sspa_sp |= SSPA_SP_WEN; + mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp); +} + +static void mmp_sspa_tx_disable(struct ssp_device *sspa) +{ + unsigned int sspa_sp; + + sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP); + sspa_sp &= ~SSPA_SP_S_EN; + sspa_sp |= SSPA_SP_WEN; + mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp); +} + +static void mmp_sspa_rx_enable(struct ssp_device *sspa) +{ + unsigned int sspa_sp; + + sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP); + sspa_sp |= SSPA_SP_S_EN; + sspa_sp |= SSPA_SP_WEN; + mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp); +} + +static void mmp_sspa_rx_disable(struct ssp_device *sspa) +{ + unsigned int sspa_sp; + + sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP); + sspa_sp &= ~SSPA_SP_S_EN; + sspa_sp |= SSPA_SP_WEN; + mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp); +} + +static int mmp_sspa_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai); + + clk_enable(priv->sysclk); + clk_enable(priv->sspa->clk); + + return 0; +} + +static void mmp_sspa_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai); + + clk_disable(priv->sspa->clk); + clk_disable(priv->sysclk); + + return; +} + +/* + * Set the SSP ports SYSCLK. + */ +static int mmp_sspa_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); + int ret = 0; + + switch (clk_id) { + case MMP_SSPA_CLK_AUDIO: + ret = clk_set_rate(priv->audio_clk, freq); + if (ret) + return ret; + break; + case MMP_SSPA_CLK_PLL: + case MMP_SSPA_CLK_VCXO: + /* not support yet */ + return -EINVAL; + default: + return -EINVAL; + } + + return 0; +} + +static int mmp_sspa_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, + int source, unsigned int freq_in, + unsigned int freq_out) +{ + struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); + int ret = 0; + + switch (pll_id) { + case MMP_SYSCLK: + ret = clk_set_rate(priv->sysclk, freq_out); + if (ret) + return ret; + break; + case MMP_SSPA_CLK: + ret = clk_set_rate(priv->sspa->clk, freq_out); + if (ret) + return ret; + break; + default: + return -ENODEV; + } + + return 0; +} + +/* + * Set up the sspa dai format. The sspa port must be inactive + * before calling this function as the physical + * interface format is changed. + */ +static int mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(cpu_dai); + struct ssp_device *sspa = sspa_priv->sspa; + u32 sspa_sp, sspa_ctrl; + + /* check if we need to change anything at all */ + if (sspa_priv->dai_fmt == fmt) + return 0; + + /* we can only change the settings if the port is not in use */ + if ((mmp_sspa_read_reg(sspa, SSPA_TXSP) & SSPA_SP_S_EN) || + (mmp_sspa_read_reg(sspa, SSPA_RXSP) & SSPA_SP_S_EN)) { + dev_err(&sspa->pdev->dev, + "can't change hardware dai format: stream is in use\n"); + return -EINVAL; + } + + /* reset port settings */ + sspa_sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH; + sspa_ctrl = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + sspa_sp |= SSPA_SP_MSL; + break; + case SND_SOC_DAIFMT_CBM_CFM: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + sspa_sp |= SSPA_SP_FSP; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + sspa_sp |= SSPA_TXSP_FPER(63); + sspa_sp |= SSPA_SP_FWID(31); + sspa_ctrl |= SSPA_CTL_XDATDLY(1); + break; + default: + return -EINVAL; + } + + mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp); + mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp); + + sspa_sp &= ~(SSPA_SP_S_RST | SSPA_SP_FFLUSH); + mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp); + mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp); + + /* + * FIXME: hw issue, for the tx serial port, + * can not config the master/slave mode; + * so must clean this bit. + * The master/slave mode has been set in the + * rx port. + */ + sspa_sp &= ~SSPA_SP_MSL; + mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp); + + mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl); + mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl); + + /* Since we are configuring the timings for the format by hand + * we have to defer some things until hw_params() where we + * know parameters like the sample size. + */ + sspa_priv->dai_fmt = fmt; + return 0; +} + +/* + * Set the SSPA audio DMA parameters and sample size. + * Can be called multiple times by oss emulation. + */ +static int mmp_sspa_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai); + struct ssp_device *sspa = sspa_priv->sspa; + struct pxa2xx_pcm_dma_params *dma_params; + u32 sspa_ctrl; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_TXCTL); + else + sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_RXCTL); + + sspa_ctrl &= ~SSPA_CTL_XFRLEN1_MASK; + sspa_ctrl |= SSPA_CTL_XFRLEN1(params_channels(params) - 1); + sspa_ctrl &= ~SSPA_CTL_XWDLEN1_MASK; + sspa_ctrl |= SSPA_CTL_XWDLEN1(SSPA_CTL_32_BITS); + sspa_ctrl &= ~SSPA_CTL_XSSZ1_MASK; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_8_BITS); + break; + case SNDRV_PCM_FORMAT_S16_LE: + sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_16_BITS); + break; + case SNDRV_PCM_FORMAT_S20_3LE: + sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_20_BITS); + break; + case SNDRV_PCM_FORMAT_S24_3LE: + sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_24_BITS); + break; + case SNDRV_PCM_FORMAT_S32_LE: + sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_32_BITS); + break; + default: + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl); + mmp_sspa_write_reg(sspa, SSPA_TXFIFO_LL, 0x1); + } else { + mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl); + mmp_sspa_write_reg(sspa, SSPA_RXFIFO_UL, 0x0); + } + + dma_params = &sspa_priv->dma_params[substream->stream]; + dma_params->dev_addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + (sspa->phys_base + SSPA_TXD) : + (sspa->phys_base + SSPA_RXD); + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params); + return 0; +} + +static int mmp_sspa_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai); + struct ssp_device *sspa = sspa_priv->sspa; + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /* + * whatever playback or capture, must enable rx. + * this is a hw issue, so need check if rx has been + * enabled or not; if has been enabled by another + * stream, do not enable again. + */ + if (!sspa_priv->running_cnt) + mmp_sspa_rx_enable(sspa); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + mmp_sspa_tx_enable(sspa); + + sspa_priv->running_cnt++; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + sspa_priv->running_cnt--; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + mmp_sspa_tx_disable(sspa); + + /* have no capture stream, disable rx port */ + if (!sspa_priv->running_cnt) + mmp_sspa_rx_disable(sspa); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int mmp_sspa_probe(struct snd_soc_dai *dai) +{ + struct sspa_priv *priv = dev_get_drvdata(dai->dev); + + snd_soc_dai_set_drvdata(dai, priv); + return 0; + +} + +#define MMP_SSPA_RATES SNDRV_PCM_RATE_8000_192000 +#define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops mmp_sspa_dai_ops = { + .startup = mmp_sspa_startup, + .shutdown = mmp_sspa_shutdown, + .trigger = mmp_sspa_trigger, + .hw_params = mmp_sspa_hw_params, + .set_sysclk = mmp_sspa_set_dai_sysclk, + .set_pll = mmp_sspa_set_dai_pll, + .set_fmt = mmp_sspa_set_dai_fmt, +}; + +struct snd_soc_dai_driver mmp_sspa_dai = { + .probe = mmp_sspa_probe, + .playback = { + .channels_min = 1, + .channels_max = 128, + .rates = MMP_SSPA_RATES, + .formats = MMP_SSPA_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = MMP_SSPA_RATES, + .formats = MMP_SSPA_FORMATS, + }, + .ops = &mmp_sspa_dai_ops, +}; + +static __devinit int asoc_mmp_sspa_probe(struct platform_device *pdev) +{ + struct sspa_priv *priv; + struct resource *res; + + priv = devm_kzalloc(&pdev->dev, + sizeof(struct sspa_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->sspa = devm_kzalloc(&pdev->dev, + sizeof(struct ssp_device), GFP_KERNEL); + if (priv->sspa == NULL) + return -ENOMEM; + + priv->dma_params = devm_kzalloc(&pdev->dev, + 2 * sizeof(struct pxa2xx_pcm_dma_params), GFP_KERNEL); + if (priv->dma_params == NULL) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + return -ENOMEM; + + priv->sspa->mmio_base = devm_request_and_ioremap(&pdev->dev, res); + if (priv->sspa->mmio_base == NULL) + return -ENODEV; + + priv->sspa->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(priv->sspa->clk)) + return PTR_ERR(priv->sspa->clk); + + priv->audio_clk = clk_get(NULL, "mmp-audio"); + if (IS_ERR(priv->audio_clk)) + return PTR_ERR(priv->audio_clk); + + priv->sysclk = clk_get(NULL, "mmp-sysclk"); + if (IS_ERR(priv->sysclk)) { + clk_put(priv->audio_clk); + return PTR_ERR(priv->sysclk); + } + clk_enable(priv->audio_clk); + priv->dai_fmt = (unsigned int) -1; + platform_set_drvdata(pdev, priv); + + return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai); +} + +static int __devexit asoc_mmp_sspa_remove(struct platform_device *pdev) +{ + struct sspa_priv *priv = platform_get_drvdata(pdev); + + clk_disable(priv->audio_clk); + clk_put(priv->audio_clk); + clk_put(priv->sysclk); + snd_soc_unregister_dai(&pdev->dev); + return 0; +} + +static struct platform_driver asoc_mmp_sspa_driver = { + .driver = { + .name = "mmp-sspa-dai", + .owner = THIS_MODULE, + }, + .probe = asoc_mmp_sspa_probe, + .remove = __devexit_p(asoc_mmp_sspa_remove), +}; + +module_platform_driver(asoc_mmp_sspa_driver); + +MODULE_AUTHOR("Leo Yan "); +MODULE_DESCRIPTION("MMP SSPA SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/pxa/mmp-sspa.h b/sound/soc/pxa/mmp-sspa.h new file mode 100644 index 000000000000..ea365cb9e784 --- /dev/null +++ b/sound/soc/pxa/mmp-sspa.h @@ -0,0 +1,92 @@ +/* + * linux/sound/soc/pxa/mmp-sspa.h + * + * Copyright (C) 2011 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _MMP_SSPA_H +#define _MMP_SSPA_H + +/* + * SSPA Registers + */ +#define SSPA_RXD (0x00) +#define SSPA_RXID (0x04) +#define SSPA_RXCTL (0x08) +#define SSPA_RXSP (0x0c) +#define SSPA_RXFIFO_UL (0x10) +#define SSPA_RXINT_MASK (0x14) +#define SSPA_RXC (0x18) +#define SSPA_RXFIFO_NOFS (0x1c) +#define SSPA_RXFIFO_SIZE (0x20) + +#define SSPA_TXD (0x80) +#define SSPA_TXID (0x84) +#define SSPA_TXCTL (0x88) +#define SSPA_TXSP (0x8c) +#define SSPA_TXFIFO_LL (0x90) +#define SSPA_TXINT_MASK (0x94) +#define SSPA_TXC (0x98) +#define SSPA_TXFIFO_NOFS (0x9c) +#define SSPA_TXFIFO_SIZE (0xa0) + +/* SSPA Control Register */ +#define SSPA_CTL_XPH (1 << 31) /* Read Phase */ +#define SSPA_CTL_XFIG (1 << 15) /* Transmit Zeros when FIFO Empty */ +#define SSPA_CTL_JST (1 << 3) /* Audio Sample Justification */ +#define SSPA_CTL_XFRLEN2_MASK (7 << 24) +#define SSPA_CTL_XFRLEN2(x) ((x) << 24) /* Transmit Frame Length in Phase 2 */ +#define SSPA_CTL_XWDLEN2_MASK (7 << 21) +#define SSPA_CTL_XWDLEN2(x) ((x) << 21) /* Transmit Word Length in Phase 2 */ +#define SSPA_CTL_XDATDLY(x) ((x) << 19) /* Tansmit Data Delay */ +#define SSPA_CTL_XSSZ2_MASK (7 << 16) +#define SSPA_CTL_XSSZ2(x) ((x) << 16) /* Transmit Sample Audio Size */ +#define SSPA_CTL_XFRLEN1_MASK (7 << 8) +#define SSPA_CTL_XFRLEN1(x) ((x) << 8) /* Transmit Frame Length in Phase 1 */ +#define SSPA_CTL_XWDLEN1_MASK (7 << 5) +#define SSPA_CTL_XWDLEN1(x) ((x) << 5) /* Transmit Word Length in Phase 1 */ +#define SSPA_CTL_XSSZ1_MASK (7 << 0) +#define SSPA_CTL_XSSZ1(x) ((x) << 0) /* XSSZ1 */ + +#define SSPA_CTL_8_BITS (0x0) /* Sample Size */ +#define SSPA_CTL_12_BITS (0x1) +#define SSPA_CTL_16_BITS (0x2) +#define SSPA_CTL_20_BITS (0x3) +#define SSPA_CTL_24_BITS (0x4) +#define SSPA_CTL_32_BITS (0x5) + +/* SSPA Serial Port Register */ +#define SSPA_SP_WEN (1 << 31) /* Write Configuration Enable */ +#define SSPA_SP_MSL (1 << 18) /* Master Slave Configuration */ +#define SSPA_SP_CLKP (1 << 17) /* CLKP Polarity Clock Edge Select */ +#define SSPA_SP_FSP (1 << 16) /* FSP Polarity Clock Edge Select */ +#define SSPA_SP_FFLUSH (1 << 2) /* FIFO Flush */ +#define SSPA_SP_S_RST (1 << 1) /* Active High Reset Signal */ +#define SSPA_SP_S_EN (1 << 0) /* Serial Clock Domain Enable */ +#define SSPA_SP_FWID(x) ((x) << 20) /* Frame-Sync Width */ +#define SSPA_TXSP_FPER(x) ((x) << 4) /* Frame-Sync Active */ + +/* sspa clock sources */ +#define MMP_SSPA_CLK_PLL 0 +#define MMP_SSPA_CLK_VCXO 1 +#define MMP_SSPA_CLK_AUDIO 3 + +/* sspa pll id */ +#define MMP_SYSCLK 0 +#define MMP_SSPA_CLK 1 + +#endif /* _MMP_SSPA_H */ -- GitLab From 5ebf20ae286a7d2b02551757166247a901d705e5 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Mon, 11 Jun 2012 18:04:40 +0800 Subject: [PATCH 1374/6849] ASoC: add mmp brownstone support Adds Alsa audio platform driver for mmp brownstone machine Signed-off-by: Zhangfei Gao Signed-off-by: Leo Yan Signed-off-by: Mark Brown --- sound/soc/pxa/Kconfig | 10 +++ sound/soc/pxa/Makefile | 2 + sound/soc/pxa/brownstone.c | 174 +++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 sound/soc/pxa/brownstone.c diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 6c3d00b8ea0b..d389fd574efe 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -206,3 +206,13 @@ config SND_PXA2XX_SOC_IMOTE2 help Say Y if you want to add support for SoC audio on the IMote 2. + +config SND_MMP_SOC_BROWNSTONE + tristate "SoC Audio support for Marvell Brownstone" + depends on SND_MMP_SOC && MACH_BROWNSTONE + select SND_MMP_SOC_SSPA + select MFD_WM8994 + select SND_SOC_WM8994 + help + Say Y if you want to add support for SoC audio on the + Marvell Brownstone reference platform. diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index 07b841746fc3..c12aa2a9bf74 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -32,6 +32,7 @@ snd-soc-mioa701-objs := mioa701_wm9713.o snd-soc-z2-objs := z2.o snd-soc-imote2-objs := imote2.o snd-soc-raumfeld-objs := raumfeld.o +snd-soc-brownstone-objs := brownstone.o obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o @@ -51,3 +52,4 @@ obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o +obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c new file mode 100644 index 000000000000..5e666e03d333 --- /dev/null +++ b/sound/soc/pxa/brownstone.c @@ -0,0 +1,174 @@ +/* + * linux/sound/soc/pxa/brownstone.c + * + * Copyright (C) 2011 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include + +#include "../codecs/wm8994.h" +#include "mmp-sspa.h" + +static const struct snd_kcontrol_new brownstone_dapm_control[] = { + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Main Mic", NULL), +}; + +static const struct snd_soc_dapm_route brownstone_audio_map[] = { + {"Ext Spk", NULL, "SPKOUTLP"}, + {"Ext Spk", NULL, "SPKOUTLN"}, + {"Ext Spk", NULL, "SPKOUTRP"}, + {"Ext Spk", NULL, "SPKOUTRN"}, + + {"Headset Stereophone", NULL, "HPOUT1L"}, + {"Headset Stereophone", NULL, "HPOUT1R"}, + + {"IN1RN", NULL, "Headset Mic"}, + + {"DMIC1DAT", NULL, "MICBIAS1"}, + {"MICBIAS1", NULL, "Main Mic"}, +}; + +static int brownstone_wm8994_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Main Mic"); + + /* set endpoints to not connected */ + snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); + snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + snd_soc_dapm_nc_pin(dapm, "IN1LN"); + snd_soc_dapm_nc_pin(dapm, "IN1LP"); + snd_soc_dapm_nc_pin(dapm, "IN1RP"); + snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(dapm, "IN2RN"); + snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(dapm, "IN2LN"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int freq_out, sspa_mclk, sysclk; + int sspa_div; + + if (params_rate(params) > 11025) { + freq_out = params_rate(params) * 512; + sysclk = params_rate(params) * 256; + sspa_mclk = params_rate(params) * 64; + } else { + freq_out = params_rate(params) * 1024; + sysclk = params_rate(params) * 512; + sspa_mclk = params_rate(params) * 64; + } + sspa_div = freq_out; + do_div(sspa_div, sspa_mclk); + + snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0); + snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk); + snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk); + + /* set wm8994 sysclk */ + snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0); + + return 0; +} + +/* machine stream operations */ +static struct snd_soc_ops brownstone_ops = { + .hw_params = brownstone_wm8994_hw_params, +}; + +static struct snd_soc_dai_link brownstone_wm8994_dai[] = { +{ + .name = "WM8994", + .stream_name = "WM8994 HiFi", + .cpu_dai_name = "mmp-sspa-dai.0", + .codec_dai_name = "wm8994-aif1", + .platform_name = "mmp-pcm-audio", + .codec_name = "wm8994-codec", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ops = &brownstone_ops, + .init = brownstone_wm8994_init, +}, +}; + +/* audio machine driver */ +static struct snd_soc_card brownstone = { + .name = "brownstone", + .dai_link = brownstone_wm8994_dai, + .num_links = ARRAY_SIZE(brownstone_wm8994_dai), + + .controls = brownstone_dapm_control, + .num_controls = ARRAY_SIZE(brownstone_dapm_control), + .dapm_widgets = brownstone_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets), + .dapm_routes = brownstone_audio_map, + .num_dapm_routes = ARRAY_SIZE(brownstone_audio_map), +}; + +static int __devinit brownstone_probe(struct platform_device *pdev) +{ + int ret; + + brownstone.dev = &pdev->dev; + ret = snd_soc_register_card(&brownstone); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + return ret; +} + +static int __devexit brownstone_remove(struct platform_device *pdev) +{ + snd_soc_unregister_card(&brownstone); + return 0; +} + +static struct platform_driver mmp_driver = { + .driver = { + .name = "brownstone-audio", + .owner = THIS_MODULE, + }, + .probe = brownstone_probe, + .remove = __devexit_p(brownstone_remove), +}; + +module_platform_driver(mmp_driver); + +MODULE_AUTHOR("Leo Yan "); +MODULE_DESCRIPTION("ALSA SoC Brownstone"); +MODULE_LICENSE("GPL"); -- GitLab From b883f363495f3d2e237170f6b8814869a3dd16fe Mon Sep 17 00:00:00 2001 From: Qiao Zhou Date: Mon, 11 Jun 2012 18:04:41 +0800 Subject: [PATCH 1375/6849] ASoC: add ttc-dkb machine support add ttc-dkb machine support for pxa910. It uses 88pm8607 as codec dai, mmp-pcm as platform and pxa-ssp as cpu dai. Signed-off-by: Qiao Zhou Signed-off-by: Mark Brown --- sound/soc/pxa/Kconfig | 20 +++++ sound/soc/pxa/Makefile | 2 + sound/soc/pxa/ttc-dkb.c | 173 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 sound/soc/pxa/ttc-dkb.c diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index d389fd574efe..4d2e46fae77c 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -150,6 +150,26 @@ config SND_SOC_TAVOREVB3 Say Y if you want to add support for SoC audio on the Marvell Saarb reference platform. +config SND_PXA910_SOC + tristate "SoC Audio for Marvell PXA910 chip" + depends on ARCH_MMP && SND + select SND_PCM + help + Say Y if you want to add support for SoC audio on the + Marvell PXA910 reference platform. + +config SND_SOC_TTC_DKB + bool "SoC Audio support for TTC DKB" + depends on SND_PXA910_SOC && MACH_TTC_DKB + select PXA_SSP + select SND_PXA_SOC_SSP + select SND_MMP_SOC + select MFD_88PM860X + select SND_SOC_88PM860X + help + Say Y if you want to add support for SoC audio on TTC DKB + + config SND_SOC_ZYLONITE tristate "SoC Audio support for Marvell Zylonite" depends on SND_PXA2XX_SOC && MACH_ZYLONITE diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index c12aa2a9bf74..d8a265d2d5d7 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -33,6 +33,7 @@ snd-soc-z2-objs := z2.o snd-soc-imote2-objs := imote2.o snd-soc-raumfeld-objs := raumfeld.o snd-soc-brownstone-objs := brownstone.o +snd-soc-ttc-dkb-objs := ttc-dkb.o obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o @@ -53,3 +54,4 @@ obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o +obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c new file mode 100644 index 000000000000..935491a8a770 --- /dev/null +++ b/sound/soc/pxa/ttc-dkb.c @@ -0,0 +1,173 @@ +/* + * linux/sound/soc/pxa/ttc_dkb.c + * + * Copyright (C) 2012 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../codecs/88pm860x-codec.h" + +static struct snd_soc_jack hs_jack, mic_jack; + +static struct snd_soc_jack_pin hs_jack_pins[] = { + { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, }, +}; + +static struct snd_soc_jack_pin mic_jack_pins[] = { + { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, }, +}; + +/* ttc machine dapm widgets */ +static const struct snd_soc_dapm_widget ttc_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_LINE("Lineout Out 1", NULL), + SND_SOC_DAPM_LINE("Lineout Out 2", NULL), + SND_SOC_DAPM_SPK("Ext Speaker", NULL), + SND_SOC_DAPM_MIC("Ext Mic 1", NULL), + SND_SOC_DAPM_MIC("Headset Mic 2", NULL), + SND_SOC_DAPM_MIC("Ext Mic 3", NULL), +}; + +/* ttc machine audio map */ +static const struct snd_soc_dapm_route ttc_audio_map[] = { + {"Headset Stereophone", NULL, "HS1"}, + {"Headset Stereophone", NULL, "HS2"}, + + {"Ext Speaker", NULL, "LSP"}, + {"Ext Speaker", NULL, "LSN"}, + + {"Lineout Out 1", NULL, "LINEOUT1"}, + {"Lineout Out 2", NULL, "LINEOUT2"}, + + {"MIC1P", NULL, "Mic1 Bias"}, + {"MIC1N", NULL, "Mic1 Bias"}, + {"Mic1 Bias", NULL, "Ext Mic 1"}, + + {"MIC2P", NULL, "Mic1 Bias"}, + {"MIC2N", NULL, "Mic1 Bias"}, + {"Mic1 Bias", NULL, "Headset Mic 2"}, + + {"MIC3P", NULL, "Mic3 Bias"}, + {"MIC3N", NULL, "Mic3 Bias"}, + {"Mic3 Bias", NULL, "Ext Mic 3"}, +}; + +static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* connected pins */ + snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 1"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 3"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); + + /* Headset jack detection */ + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE + | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, + &hs_jack); + snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), + hs_jack_pins); + snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE, + &mic_jack); + snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins), + mic_jack_pins); + + /* headphone, microphone detection & headset short detection */ + pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE, + SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2); + pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE); + + return 0; +} + +/* ttc/td-dkb digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = { +{ + .name = "88pm860x i2s", + .stream_name = "audio playback", + .codec_name = "88pm860x-codec", + .platform_name = "mmp-pcm-audio", + .cpu_dai_name = "pxa-ssp-dai.1", + .codec_dai_name = "88pm860x-i2s", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, + .init = ttc_pm860x_init, +}, +}; + +/* ttc/td audio machine driver */ +static struct snd_soc_card ttc_dkb_card = { + .name = "ttc-dkb-hifi", + .dai_link = ttc_pm860x_hifi_dai, + .num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai), + + .dapm_widgets = ttc_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ttc_dapm_widgets), + .dapm_routes = ttc_audio_map, + .num_dapm_routes = ARRAY_SIZE(ttc_audio_map), +}; + +static int __devinit ttc_dkb_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &ttc_dkb_card; + int ret; + + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + + return ret; +} + +static int __devexit ttc_dkb_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver ttc_dkb_driver = { + .driver = { + .name = "ttc-dkb-audio", + .owner = THIS_MODULE, + }, + .probe = ttc_dkb_probe, + .remove = __devexit_p(ttc_dkb_remove), +}; + +module_platform_driver(ttc_dkb_driver); + +/* Module information */ +MODULE_AUTHOR("Qiao Zhou, "); +MODULE_DESCRIPTION("ALSA SoC TTC DKB"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ttc-dkb-audio"); -- GitLab From a9db7dbee0436f0c741c6dfb39ab0241d4131539 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 8 Jun 2012 12:34:20 -0600 Subject: [PATCH 1376/6849] ASoC: when initializing CPU DAI, don't duplicate any CODEC init If the CPU-side of a DAI link is a CODEC rather than a standalone DAI, the codec initialization will call try_module_get() and create the DAI widgets. Ensure that this isn't duplicated when the CPU DAI itself is probed, if the CPU DAI is part of a CODEC. Note that this is not a complete fix on its own, since there's no guarantee that the CODEC itself will be initialized - currently that only happens if the CODEC is also used as the CODEC-side of a DAI link, and that initialization may happen before or after the DAIs within the CODEC are initialized. However, such a scenario doesn't necessarily currently work, and I don't think this change alone makes it any worse. This is fixed in a couple patches time. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 3d803f3cd272..448d4a7c09dd 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -983,7 +983,9 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) } cpu_dai->probed = 0; list_del(&cpu_dai->card_list); - module_put(cpu_dai->dev->driver->owner); + + if (!cpu_dai->codec) + module_put(cpu_dai->dev->driver->owner); } } @@ -1257,11 +1259,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) /* probe the cpu_dai */ if (!cpu_dai->probed && cpu_dai->driver->probe_order == order) { - cpu_dai->dapm.card = card; - if (!try_module_get(cpu_dai->dev->driver->owner)) - return -ENODEV; + if (!cpu_dai->codec) { + cpu_dai->dapm.card = card; + if (!try_module_get(cpu_dai->dev->driver->owner)) + return -ENODEV; - snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai); + snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai); + } if (cpu_dai->driver->probe) { ret = cpu_dai->driver->probe(cpu_dai); -- GitLab From 18d756440e8ed292b772682c4440a9d33643225b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 8 Jun 2012 12:34:21 -0600 Subject: [PATCH 1377/6849] ASoC: when removing a CPU DAI, clean up its DAPM context When a standalone CPU DAI (one not part of a CODEC) is probed, widgets are created for it. Add a call to snd_soc_dapm_free() in order to clean these up when the CPU DAI is removed. In order for snd_soc_dapm_free() to work, the CPU DAI's DAPM context's list member must be initialized, since snd_soc_dapm_free() removes that from the list it's part of. Add it to the card's list of DAPM contexts. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 448d4a7c09dd..621c5bdea483 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -984,8 +984,10 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) cpu_dai->probed = 0; list_del(&cpu_dai->card_list); - if (!cpu_dai->codec) + if (!cpu_dai->codec) { + snd_soc_dapm_free(&cpu_dai->dapm); module_put(cpu_dai->dev->driver->owner); + } } } @@ -1264,6 +1266,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) if (!try_module_get(cpu_dai->dev->driver->owner)) return -ENODEV; + list_add(&cpu_dai->dapm.list, &card->dapm_list); snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai); } -- GitLab From d12cd198cba7949c70f596296297b772063175c0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 8 Jun 2012 12:34:22 -0600 Subject: [PATCH 1378/6849] ASoC: factor out soc_remove_platform() This change simply factors out part of soc_remove_dai_link() into a standalone function. This makes platform and CODEC removal much more similar at the call-sites. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 621c5bdea483..a539ade477af 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -898,6 +898,28 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) return 0; } +static int soc_remove_platform(struct snd_soc_platform *platform) +{ + int ret; + + if (platform->driver->remove) { + ret = platform->driver->remove(platform); + if (ret < 0) + pr_err("asoc: failed to remove %s: %d\n", + platform->name, ret); + } + + /* Make sure all DAPM widgets are freed */ + snd_soc_dapm_free(&platform->dapm); + + soc_cleanup_platform_debugfs(platform); + platform->probed = 0; + list_del(&platform->card_list); + module_put(platform->dev->driver->owner); + + return 0; +} + static void soc_remove_codec(struct snd_soc_codec *codec) { int err; @@ -950,22 +972,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) /* remove the platform */ if (platform && platform->probed && - platform->driver->remove_order == order) { - if (platform->driver->remove) { - err = platform->driver->remove(platform); - if (err < 0) - pr_err("asoc: failed to remove %s: %d\n", - platform->name, err); - } - - /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(&platform->dapm); - - soc_cleanup_platform_debugfs(platform); - platform->probed = 0; - list_del(&platform->card_list); - module_put(platform->dev->driver->owner); - } + platform->driver->remove_order == order) + soc_remove_platform(platform); /* remove the CODEC */ if (codec && codec->probed && -- GitLab From 62ae68fa5d6d6f93d8ca8d00e21ad7ac410f9d58 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 8 Jun 2012 12:34:23 -0600 Subject: [PATCH 1379/6849] ASoC: probe CODECs and platforms before DAIs and links soc_probe_dai_link() currently inter-mixes the probing of CODECs, platforms, and DAIs. This can lead to problems such as a CODEC's DAI being probed before the CODEC, if that DAI is used as the CPU-side of a DAI link without any other of the CODEC's DAIs having been used as the CODEC-side of any DAI link that was probed earlier. To solve this, split soc_probe_dai_link() into soc_probe_link_components() and soc_probe_link_dais(). The former is used to probe all CODECs and platforms used by a card first, and then the latter is used to probe all the DAIs and links later. A similar change is made to soc_remove_dai_links(). Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 129 +++++++++++++++++++++++++++++++------------ 1 file changed, 95 insertions(+), 34 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a539ade477af..fe16135250f8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -941,11 +941,9 @@ static void soc_remove_codec(struct snd_soc_codec *codec) module_put(codec->dev->driver->owner); } -static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) +static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; int err; @@ -970,16 +968,6 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) list_del(&codec_dai->card_list); } - /* remove the platform */ - if (platform && platform->probed && - platform->driver->remove_order == order) - soc_remove_platform(platform); - - /* remove the CODEC */ - if (codec && codec->probed && - codec->driver->remove_order == order) - soc_remove_codec(codec); - /* remove the cpu_dai */ if (cpu_dai && cpu_dai->probed && cpu_dai->driver->remove_order == order) { @@ -999,6 +987,38 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) } } +static void soc_remove_link_components(struct snd_soc_card *card, int num, + int order) +{ + struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_codec *codec; + + /* remove the platform */ + if (platform && platform->probed && + platform->driver->remove_order == order) { + soc_remove_platform(platform); + } + + /* remove the CODEC-side CODEC */ + if (codec_dai) { + codec = codec_dai->codec; + if (codec && codec->probed && + codec->driver->remove_order == order) + soc_remove_codec(codec); + } + + /* remove any CPU-side CODEC */ + if (cpu_dai) { + codec = cpu_dai->codec; + if (codec && codec->probed && + codec->driver->remove_order == order) + soc_remove_codec(codec); + } +} + static void soc_remove_dai_links(struct snd_soc_card *card) { int dai, order; @@ -1006,8 +1026,15 @@ static void soc_remove_dai_links(struct snd_soc_card *card) for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; order++) { for (dai = 0; dai < card->num_rtd; dai++) - soc_remove_dai_link(card, dai, order); + soc_remove_link_dais(card, dai, order); + } + + for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; + order++) { + for (dai = 0; dai < card->num_rtd; dai++) + soc_remove_link_components(card, dai, order); } + card->num_rtd = 0; } @@ -1244,7 +1271,44 @@ out: return 0; } -static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) +static int soc_probe_link_components(struct snd_soc_card *card, int num, + int order) +{ + struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_platform *platform = rtd->platform; + int ret; + + /* probe the CPU-side component, if it is a CODEC */ + if (cpu_dai->codec && + !cpu_dai->codec->probed && + cpu_dai->codec->driver->probe_order == order) { + ret = soc_probe_codec(card, cpu_dai->codec); + if (ret < 0) + return ret; + } + + /* probe the CODEC-side component */ + if (!codec_dai->codec->probed && + codec_dai->codec->driver->probe_order == order) { + ret = soc_probe_codec(card, codec_dai->codec); + if (ret < 0) + return ret; + } + + /* probe the platform */ + if (!platform->probed && + platform->driver->probe_order == order) { + ret = soc_probe_platform(card, platform); + if (ret < 0) + return ret; + } + + return 0; +} + +static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; @@ -1292,22 +1356,6 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) list_add(&cpu_dai->card_list, &card->dai_dev_list); } - /* probe the CODEC */ - if (!codec->probed && - codec->driver->probe_order == order) { - ret = soc_probe_codec(card, codec); - if (ret < 0) - return ret; - } - - /* probe the platform */ - if (!platform->probed && - platform->driver->probe_order == order) { - ret = soc_probe_platform(card, platform); - if (ret < 0) - return ret; - } - /* probe the CODEC DAI */ if (!codec_dai->probed && codec_dai->driver->probe_order == order) { if (codec_dai->driver->probe) { @@ -1582,14 +1630,27 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) goto card_probe_error; } - /* early DAI link probe */ + /* probe all components used by DAI links on this card */ for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; order++) { for (i = 0; i < card->num_links; i++) { - ret = soc_probe_dai_link(card, i, order); + ret = soc_probe_link_components(card, i, order); if (ret < 0) { pr_err("asoc: failed to instantiate card %s: %d\n", - card->name, ret); + card->name, ret); + goto probe_dai_err; + } + } + } + + /* probe all DAI links on this card */ + for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; + order++) { + for (i = 0; i < card->num_links; i++) { + ret = soc_probe_link_dais(card, i, order); + if (ret < 0) { + pr_err("asoc: failed to instantiate card %s: %d\n", + card->name, ret); goto probe_dai_err; } } -- GitLab From 2f74759056797054122cdc70844137f70bb3f626 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 7 Jun 2012 22:20:18 +0900 Subject: [PATCH 1380/6849] x86/alternatives: Use atomic_xchg() instead atomic_dec_and_test() for stop_machine_text_poke() stop_machine_text_poke() uses atomic_dec_and_test() to select one of the CPUs executing that function to actually modify the code. Since the variable is initialized to 1, subsequent CPUs will make the variable go negative. Since going negative is uncommon/unexpected in typical dec_and_test usage change this user to atomic_xchg(). This was found using a patch that warns on dec_and_test going negative. Signed-off-by: OGAWA Hirofumi Acked-by: Steven Rostedt [ Rewrote changelog ] Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/87zk8fgsx9.fsf@devron.myhome.or.jp Signed-off-by: Ingo Molnar --- arch/x86/kernel/alternative.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 1f84794f0759..53231a045d3d 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -664,7 +664,7 @@ static int __kprobes stop_machine_text_poke(void *data) struct text_poke_param *p; int i; - if (atomic_dec_and_test(&stop_machine_first)) { + if (atomic_xchg(&stop_machine_first, 0)) { for (i = 0; i < tpp->nparams; i++) { p = &tpp->params[i]; text_poke(p->addr, p->opcode, p->len); -- GitLab From 0d515210b6969ecfc161f71a4515831d9a6e58f4 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 13 Jun 2012 10:27:41 -0400 Subject: [PATCH 1381/6849] GFS2: Add kobject release method This patch adds a kobject release function that properly maintains the kobject use count, so that accesses to the sysfs files do not cause an access to freed kernel memory after an unmount. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_fstype.c | 36 ++++++++++++++++++++++++------------ fs/gfs2/sys.c | 21 ++++++++++++++++++--- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index b8c250fc4922..9b2389756acd 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1118,20 +1118,33 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent } error = init_names(sdp, silent); - if (error) - goto fail; + if (error) { + /* In this case, we haven't initialized sysfs, so we have to + manually free the sdp. */ + free_percpu(sdp->sd_lkstats); + kfree(sdp); + sb->s_fs_info = NULL; + return error; + } snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s", sdp->sd_table_name); - gfs2_create_debugfs_file(sdp); - error = gfs2_sys_fs_add(sdp); + /* + * If we hit an error here, gfs2_sys_fs_add will have called function + * kobject_put which causes the sysfs usage count to go to zero, which + * causes sysfs to call function gfs2_sbd_release, which frees sdp. + * Subsequent error paths here will call gfs2_sys_fs_del, which also + * kobject_put to free sdp. + */ if (error) - goto fail; + return error; + + gfs2_create_debugfs_file(sdp); error = gfs2_lm_mount(sdp, silent); if (error) - goto fail_sys; + goto fail_debug; error = init_locking(sdp, &mount_gh, DO); if (error) @@ -1215,12 +1228,12 @@ fail_locking: fail_lm: gfs2_gl_hash_clear(sdp); gfs2_lm_unmount(sdp); -fail_sys: - gfs2_sys_fs_del(sdp); -fail: +fail_debug: gfs2_delete_debugfs_file(sdp); free_percpu(sdp->sd_lkstats); - kfree(sdp); + /* gfs2_sys_fs_del must be the last thing we do, since it causes + * sysfs to call function gfs2_sbd_release, which frees sdp. */ + gfs2_sys_fs_del(sdp); sb->s_fs_info = NULL; return error; } @@ -1390,10 +1403,9 @@ static void gfs2_kill_sb(struct super_block *sb) sdp->sd_root_dir = NULL; sdp->sd_master_dir = NULL; shrink_dcache_sb(sb); - kill_block_super(sb); gfs2_delete_debugfs_file(sdp); free_percpu(sdp->sd_lkstats); - kfree(sdp); + kill_block_super(sb); } struct file_system_type gfs2_fs_type = { diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 9c2592b1d5ff..e4bee4bebbf6 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -276,7 +276,15 @@ static struct attribute *gfs2_attrs[] = { NULL, }; +static void gfs2_sbd_release(struct kobject *kobj) +{ + struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); + + kfree(sdp); +} + static struct kobj_type gfs2_ktype = { + .release = gfs2_sbd_release, .default_attrs = gfs2_attrs, .sysfs_ops = &gfs2_attr_ops, }; @@ -583,6 +591,7 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) char ro[20]; char spectator[20]; char *envp[] = { ro, spectator, NULL }; + int sysfs_frees_sdp = 0; sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0); sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); @@ -591,8 +600,10 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, "%s", sdp->sd_table_name); if (error) - goto fail; + goto fail_reg; + sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling + function gfs2_sbd_release. */ error = sysfs_create_group(&sdp->sd_kobj, &tune_group); if (error) goto fail_reg; @@ -615,9 +626,13 @@ fail_lock_module: fail_tune: sysfs_remove_group(&sdp->sd_kobj, &tune_group); fail_reg: - kobject_put(&sdp->sd_kobj); -fail: + free_percpu(sdp->sd_lkstats); fs_err(sdp, "error %d adding sysfs files", error); + if (sysfs_frees_sdp) + kobject_put(&sdp->sd_kobj); + else + kfree(sdp); + sb->s_fs_info = NULL; return error; } -- GitLab From bd3810a58ba9c16702450c643ea3c557668185db Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 13 Jun 2012 14:29:16 +0100 Subject: [PATCH 1382/6849] regmap: Remove warning on stubbed dev_get_regmap() It's perfectly sensible to ask if there's a regmap for a device which doesn't have one so the stubbed version shouldn't complain, the caller should be prepared for this. Signed-off-by: Mark Brown --- include/linux/regmap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/regmap.h b/include/linux/regmap.h index f9b624c83464..4191a4281587 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -386,7 +386,6 @@ static inline int regmap_register_patch(struct regmap *map, static inline struct regmap *dev_get_regmap(struct device *dev, const char *name) { - WARN_ONCE(1, "regmap API is disabled"); return NULL; } -- GitLab From df2643cfa4ad4f3775838ad0c0815c465f351f92 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 13 Jun 2012 17:28:18 +0900 Subject: [PATCH 1383/6849] regulator: Replace set_voltage with set_voltage_sel To apply delay time for voltage change, replace s5m8767_set_voltage with s5m8767_set_voltage_sel. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 38 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 4edf344fb7c4..a4a3c7eefd1f 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -357,32 +357,34 @@ static int s5m8767_convert_voltage_to_sel( return selector; } -static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) +static inline int s5m8767_set_high(struct s5m8767_info *s5m8767) { int temp_index = s5m8767->buck_gpioindex; gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); + + return 0; } -static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) +static inline int s5m8767_set_low(struct s5m8767_info *s5m8767) { int temp_index = s5m8767->buck_gpioindex; gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); + + return 0; } -static int s5m8767_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, unsigned *selector) +static int s5m8767_set_voltage_sel(struct regulator_dev *rdev, + unsigned selector) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); - const struct s5m_voltage_desc *desc; int reg_id = rdev_get_id(rdev); - int sel, reg, mask, ret = 0, old_index, index = 0; - u8 val; + int reg, mask, ret = 0, old_index, index = 0; u8 *buck234_vol = NULL; switch (reg_id) { @@ -407,15 +409,9 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, return -EINVAL; } - desc = reg_voltage_map[reg_id]; - - sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); - if (sel < 0) - return sel; - /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */ if (buck234_vol) { - while (*buck234_vol != sel) { + while (*buck234_vol != selector) { buck234_vol++; index++; } @@ -423,22 +419,16 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, s5m8767->buck_gpioindex = index; if (index > old_index) - s5m8767_set_high(s5m8767); + return s5m8767_set_high(s5m8767); else - s5m8767_set_low(s5m8767); + return s5m8767_set_low(s5m8767); } else { ret = s5m8767_get_voltage_register(rdev, ®); if (ret) return ret; - s5m_reg_read(s5m8767->iodev, reg, &val); - val = (val & ~mask) | sel; - - ret = s5m_reg_write(s5m8767->iodev, reg, val); + return s5m_reg_update(s5m8767->iodev, reg, selector, mask); } - - *selector = sel; - return ret; } static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, @@ -463,7 +453,7 @@ static struct regulator_ops s5m8767_ops = { .enable = s5m8767_reg_enable, .disable = s5m8767_reg_disable, .get_voltage_sel = s5m8767_get_voltage_sel, - .set_voltage = s5m8767_set_voltage, + .set_voltage_sel = s5m8767_set_voltage_sel, .set_voltage_time_sel = s5m8767_set_voltage_time_sel, }; -- GitLab From 74e20e569158063970624e360c8395ac5cffd654 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Jun 2012 16:36:20 +0800 Subject: [PATCH 1384/6849] regulator: wm8400: Adjust the equation for selector >= 15 in wm8400_ldo_list_voltage Adjust the equation for selector >= 15 for better readability. The equation "1700000 + ((selector - 15) * 100000)" can be interpreted by: Starting from selector 15: Steps of 100mV from 1700mV Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8400-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 9f9df8eef1a1..9035dd053611 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -28,7 +28,7 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev, if (selector < 15) return 900000 + (selector * 50000); else - return 1600000 + ((selector - 14) * 100000); + return 1700000 + ((selector - 15) * 100000); } static int wm8400_ldo_map_voltage(struct regulator_dev *dev, -- GitLab From b4bc9ef6253578ecc71eec79a7dd423d0a282a4b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 13 Jun 2012 11:27:11 +0800 Subject: [PATCH 1385/6849] regulator: tps65217: Convert to regulator_[is_enabled|get_voltage_sel]_regmap This patch converts .is_enabled and .get_voltage_sel to regulator_is_enabled_regmap and regulator_get_voltage_sel_regmap. For .enable, .disable, and .set_voltage_sel, the write protect level is either 1 or 2. So we cannot use regulator_[enable|disable|set_voltage_sel]_regmap. Now we store the enable reg/mask and vsel reg/mask in regulator_desc, so we can remove enable_mask, set_vout_reg, and set_vout_mask from struct tps_info. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 114 +++++++++---------------- include/linux/mfd/tps65217.h | 6 -- 2 files changed, 42 insertions(+), 78 deletions(-) diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 9d371d2cbcae..f5fa05b5bea4 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -26,7 +26,7 @@ #include #include -#define TPS65217_REGULATOR(_name, _id, _ops, _n) \ +#define TPS65217_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _em) \ { \ .name = _name, \ .id = _id, \ @@ -34,9 +34,13 @@ .n_voltages = _n, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ + .vsel_reg = _vr, \ + .vsel_mask = _vm, \ + .enable_reg = TPS65217_REG_ENABLE, \ + .enable_mask = _em, \ } \ -#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm) \ +#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n)\ { \ .name = _nm, \ .min_uV = _min, \ @@ -45,9 +49,6 @@ .uv_to_vsel = _f2, \ .table = _t, \ .table_len = _n, \ - .enable_mask = _em, \ - .set_vout_reg = _vr, \ - .set_vout_mask = _vm, \ } static const int LDO1_VSEL_table[] = { @@ -127,46 +128,21 @@ static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel) static struct tps_info tps65217_pmic_regs[] = { TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN, - TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK), + tps65217_uv_to_vsel1, NULL, 64), TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN, - TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK), + tps65217_uv_to_vsel1, NULL, 64), TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN, - TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK), + tps65217_uv_to_vsel1, NULL, 64), TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table, - 16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1, - TPS65217_DEFLDO1_LDO1_MASK), + 16), TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1, - tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN, - TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK), + tps65217_uv_to_vsel1, NULL, 64), TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2, - tps65217_uv_to_vsel2, NULL, 32, - TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, - TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK), + tps65217_uv_to_vsel2, NULL, 32), TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2, - tps65217_uv_to_vsel2, NULL, 32, - TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, - TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK), + tps65217_uv_to_vsel2, NULL, 32), }; -static int tps65217_pmic_is_enabled(struct regulator_dev *dev) -{ - int ret; - struct tps65217 *tps = rdev_get_drvdata(dev); - unsigned int data, rid = rdev_get_id(dev); - - if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) - return -EINVAL; - - ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); - if (ret) - return ret; - - return (data & tps->info[rid]->enable_mask) ? 1 : 0; -} - static int tps65217_pmic_enable(struct regulator_dev *dev) { struct tps65217 *tps = rdev_get_drvdata(dev); @@ -177,9 +153,8 @@ static int tps65217_pmic_enable(struct regulator_dev *dev) /* Enable the regulator and password protection is level 1 */ return tps65217_set_bits(tps, TPS65217_REG_ENABLE, - tps->info[rid]->enable_mask, - tps->info[rid]->enable_mask, - TPS65217_PROTECT_L1); + dev->desc->enable_mask, dev->desc->enable_mask, + TPS65217_PROTECT_L1); } static int tps65217_pmic_disable(struct regulator_dev *dev) @@ -192,25 +167,7 @@ static int tps65217_pmic_disable(struct regulator_dev *dev) /* Disable the regulator and password protection is level 1 */ return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, - tps->info[rid]->enable_mask, TPS65217_PROTECT_L1); -} - -static int tps65217_pmic_get_voltage_sel(struct regulator_dev *dev) -{ - int ret; - struct tps65217 *tps = rdev_get_drvdata(dev); - unsigned int selector, rid = rdev_get_id(dev); - - if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) - return -EINVAL; - - ret = tps65217_reg_read(tps, tps->info[rid]->set_vout_reg, &selector); - if (ret) - return ret; - - selector &= tps->info[rid]->set_vout_mask; - - return selector; + dev->desc->enable_mask, TPS65217_PROTECT_L1); } static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, @@ -221,8 +178,7 @@ static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, unsigned int rid = rdev_get_id(dev); /* Set the voltage based on vsel value and write protect level is 2 */ - ret = tps65217_set_bits(tps, tps->info[rid]->set_vout_reg, - tps->info[rid]->set_vout_mask, + ret = tps65217_set_bits(tps, dev->desc->vsel_reg, dev->desc->vsel_mask, selector, TPS65217_PROTECT_L2); /* Set GO bit for DCDCx to initiate voltage transistion */ @@ -285,10 +241,10 @@ static int tps65217_pmic_list_voltage(struct regulator_dev *dev, /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ static struct regulator_ops tps65217_pmic_ops = { - .is_enabled = tps65217_pmic_is_enabled, + .is_enabled = regulator_is_enabled_regmap, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, - .get_voltage_sel = tps65217_pmic_get_voltage_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = tps65217_pmic_list_voltage, .map_voltage = tps65217_pmic_map_voltage, @@ -296,22 +252,36 @@ static struct regulator_ops tps65217_pmic_ops = { /* Operations permitted on LDO1 */ static struct regulator_ops tps65217_pmic_ldo1_ops = { - .is_enabled = tps65217_pmic_is_enabled, + .is_enabled = regulator_is_enabled_regmap, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, - .get_voltage_sel = tps65217_pmic_get_voltage_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = tps65217_pmic_list_voltage, }; static const struct regulator_desc regulators[] = { - TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64), - TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64), - TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64), - TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16), - TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64), - TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32), - TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32), + TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64, + TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK, + TPS65217_ENABLE_DC1_EN), + TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64, + TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK, + TPS65217_ENABLE_DC2_EN), + TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64, + TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK, + TPS65217_ENABLE_DC3_EN), + TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16, + TPS65217_REG_DEFLDO1, TPS65217_DEFLDO1_LDO1_MASK, + TPS65217_ENABLE_LDO1_EN), + TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64, + TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK, + TPS65217_ENABLE_LDO2_EN), + TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32, + TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, + TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN), + TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32, + TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, + TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN), }; static int __devinit tps65217_regulator_probe(struct platform_device *pdev) diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index e030ef9a64ee..4e035a41a9b0 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h @@ -229,9 +229,6 @@ struct tps65217_board { * @uv_to_vsel: Function pointer to get selector from voltage * @table: Table for non-uniform voltage step-size * @table_len: Length of the voltage table - * @enable_mask: Regulator enable mask bits - * @set_vout_reg: Regulator output voltage set register - * @set_vout_mask: Regulator output voltage set mask * * This data is used to check the regualtor voltage limits while setting. */ @@ -243,9 +240,6 @@ struct tps_info { int (*uv_to_vsel)(int uV, unsigned int *vsel); const int *table; unsigned int table_len; - unsigned int enable_mask; - unsigned int set_vout_reg; - unsigned int set_vout_mask; }; /** -- GitLab From bcb7ad7bcbef030e6ba71ede1f9866368aca7c99 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 13 Jun 2012 21:28:09 +0530 Subject: [PATCH 1386/6849] ath9k: Fix softlockup in AR9485 steps to recreate: load latest ath9k driver with AR9485 stop the network-manager and wpa_supplicant bring the interface up Call Trace: [] ? ath_hw_check+0xe0/0xe0 [ath9k] [] __const_udelay+0x28/0x30 [] ar9003_get_pll_sqsum_dvc+0x4a/0x80 [ath9k_hw] [] ath_hw_pll_work+0x5b/0xe0 [ath9k] [] process_one_work+0x11e/0x470 [] worker_thread+0x15f/0x360 [] ? manage_workers+0x230/0x230 [] kthread+0x93/0xa0 [] kernel_thread_helper+0x4/0x10 [] ? kthread_freezable_should_stop+0x70/0x70 [] ? gs_change+0x13/0x13 ensure that the PLL-WAR for AR9485/AR9340 is executed only if the STA is associated (or) IBSS/AP mode had started beaconing. Ideally this WAR is needed to recover from some rare beacon stuck during stress testing. Before the STA is associated/IBSS had started beaconing, PLL4(0x1618c) always seem to have zero even though we had configured PLL3(0x16188) to query about PLL's locking status. When we keep on polling infinitely PLL4's 8th bit(ie check for PLL locking measurements is done), machine hangs due to softlockup. fixes https://bugzilla.redhat.com/show_bug.cgi?id=811142 Reported-by: Rolf Offermanns Cc: stable@vger.kernel.org [3.0+] Tested-by: Mohammed Shafi Shajakhan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ac41f1e3ab9f..dac1a2709e3c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -971,6 +971,15 @@ void ath_hw_pll_work(struct work_struct *work) hw_pll_work.work); u32 pll_sqsum; + /* + * ensure that the PLL WAR is executed only + * after the STA is associated (or) if the + * beaconing had started in interfaces that + * uses beacons. + */ + if (!(sc->sc_flags & SC_OP_BEACONS)) + return; + if (AR_SREV_9485(sc->sc_ah)) { ath9k_ps_wakeup(sc); -- GitLab From e8790ab4ce2a46505a8e1479645414425dbc81f0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 13 Jun 2012 22:57:24 +0800 Subject: [PATCH 1387/6849] regmap: mmio: Staticize regmap_mmio_gen_context() regmap_mmio_gen_context() is only used in regmap-mmio.c. Thus make it static. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-mmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index eec86639cac4..d64a7fc71df8 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c @@ -128,7 +128,7 @@ static struct regmap_bus regmap_mmio = { .val_format_endian_default = REGMAP_ENDIAN_NATIVE, }; -struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, +static struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, const struct regmap_config *config) { struct regmap_mmio_context *ctx; -- GitLab From e001f1c8e9c1d3b2f0c638bc712bcac10294aae3 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 7 Jun 2012 17:57:36 -0600 Subject: [PATCH 1388/6849] of: export of_platform_populate() Without this, modules can't use this API, leading to build failures. Signed-off-by: Stephen Warren Signed-off-by: Rob Herring --- drivers/of/platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 343ad29e211c..3132ea068d95 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -462,4 +462,5 @@ int of_platform_populate(struct device_node *root, of_node_put(root); return rc; } +EXPORT_SYMBOL_GPL(of_platform_populate); #endif /* CONFIG_OF_ADDRESS */ -- GitLab From ae2a7d20087f2780df7ddc829a74f4a387f26b4d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 12 Apr 2012 13:24:17 +0200 Subject: [PATCH 1389/6849] of: Add Avionic Design vendor prefix This commit adds a device tree vendor prefix for Avionic Design GmbH. Cc: Grant Likely Cc: Rob Herring Cc: devicetree-discuss@lists.ozlabs.org Cc: Linus Walleij Signed-off-by: Thierry Reding Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 6eab91747a86..db4d3af3643c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -3,6 +3,7 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. This isn't an exhaustive list, but you should add new prefixes to it before using them to avoid name-space collisions. +ad Avionic Design GmbH adi Analog Devices, Inc. amcc Applied Micro Circuits Corporation (APM, formally AMCC) apm Applied Micro Circuits Corporation (APM) -- GitLab From 37797d5f2ee47a06cc1c43b7b5f4832822436e3b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 21 Apr 2012 14:21:13 -0300 Subject: [PATCH 1390/6849] dt: fsl-imx-cspi.txt: Fix comment about GPIOs used for chip selects The gpio numbers does not match the comment. Fix the comments for GPIOs used for chip selects. Signed-off-by: Fabio Estevam Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index 9841057d112b..4256a6df9b79 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -17,6 +17,6 @@ ecspi@70010000 { reg = <0x70010000 0x4000>; interrupts = <36>; fsl,spi-num-chipselects = <2>; - cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */ - <&gpio3 25 0>; /* GPIO4_25 */ + cs-gpios = <&gpio3 24 0>, /* GPIO3_24 */ + <&gpio3 25 0>; /* GPIO3_25 */ }; -- GitLab From 06693fcd57739d2c6cb22c0f2bb494e7e65ccedd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 10 Jun 2012 14:24:07 -0300 Subject: [PATCH 1391/6849] dt: fsl-imx-esdhc.txt: Fix gpio number assignment Fix gpio number assignment, so that it can match the number stated in the comment. Cc: Signed-off-by: Fabio Estevam Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index c7e404b3ef05..fea541ee8b34 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -29,6 +29,6 @@ esdhc@70008000 { compatible = "fsl,imx51-esdhc"; reg = <0x70008000 0x4000>; interrupts = <2>; - cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */ - wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */ + cd-gpios = <&gpio1 6 0>; /* GPIO1_6 */ + wp-gpios = <&gpio1 5 0>; /* GPIO1_5 */ }; -- GitLab From d7858de94584a2edb842fa5bea1c5c7aa08608c4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 10 Jun 2012 14:24:08 -0300 Subject: [PATCH 1392/6849] dt: fsl-mma8450.txt: Add missing 'reg' description Add missing 'reg' description. Signed-off-by: Fabio Estevam ---- .../devicetree/bindings/input/fsl-mma8450.txt | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/input/fsl-mma8450.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/fsl-mma8450.txt b/Documentation/devicetree/bindings/input/fsl-mma8450.txt index a00c94ccbdee..0b96e5737d3a 100644 --- a/Documentation/devicetree/bindings/input/fsl-mma8450.txt +++ b/Documentation/devicetree/bindings/input/fsl-mma8450.txt @@ -2,6 +2,7 @@ Required properties: - compatible : "fsl,mma8450". +- reg: the I2C address of MMA8450 Example: -- GitLab From af634df194955109197f0fe098d09eab741c0ce8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 10 Jun 2012 14:24:09 -0300 Subject: [PATCH 1393/6849] dt: fsl-fec.txt: Fix gpio number assignment Fix gpio number assignment, so that it can match the number stated in the comment. Signed-off-by: Fabio Estevam Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/net/fsl-fec.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt index 7ab9e1a2d8be..4616fc28ee86 100644 --- a/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -19,6 +19,6 @@ ethernet@83fec000 { reg = <0x83fec000 0x4000>; interrupts = <87>; phy-mode = "mii"; - phy-reset-gpios = <&gpio1 14 0>; /* GPIO2_14 */ + phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */ local-mac-address = [00 04 9F 01 1B B9]; }; -- GitLab From d44115f28edba06d0844ab4b79682f48500020f6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 10 Jun 2012 14:24:10 -0300 Subject: [PATCH 1394/6849] dt: mc13xxx.txt: Fix gpio number assignment Fix gpio number assignment, so that it can match the number stated in the comment. Signed-off-by: Fabio Estevam Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/mfd/mc13xxx.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt index 19f6af47a792..baf07987ae68 100644 --- a/Documentation/devicetree/bindings/mfd/mc13xxx.txt +++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt @@ -46,8 +46,8 @@ Examples: ecspi@70010000 { /* ECSPI1 */ fsl,spi-num-chipselects = <2>; - cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */ - <&gpio3 25 0>; /* GPIO4_25 */ + cs-gpios = <&gpio4 24 0>, /* GPIO4_24 */ + <&gpio4 25 0>; /* GPIO4_25 */ status = "okay"; pmic: mc13892@0 { -- GitLab From d597ee7e28d2576ab075abdebab96d3cb65f1b54 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 9 Jun 2012 22:51:41 +0200 Subject: [PATCH 1395/6849] brcmsmac: remove brcms_set_hint() function The function brcms_set_hint() does not add any functionality so regulatory_hint() can be called directly. The error value has been removed from the message when regulatory_hint() fails. Reported-by: Seth Forshee Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 50f92a0b7c41..341e06a0d6ec 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -721,14 +721,6 @@ static const struct ieee80211_ops brcms_ops = { .flush = brcms_ops_flush, }; -/* - * is called in brcms_bcma_probe() context, therefore no locking required. - */ -static int brcms_set_hint(struct brcms_info *wl, char *abbrev) -{ - return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); -} - void brcms_dpc(unsigned long data) { struct brcms_info *wl; @@ -1068,9 +1060,9 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" "%d\n", __func__, err); - if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode)) - wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", - __func__, err); + if (wl->pub->srom_ccode[0] && + regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) + wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); n_adapters_found++; return wl; -- GitLab From 5e16e8ee3a14b59366d25f075926da3ca5d03d11 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 9 Jun 2012 22:51:42 +0200 Subject: [PATCH 1396/6849] brcmsmac: fix smatch warning found in ampdu.c This patch fixes potential NULL pointer dereference in ampdu. This was found running smatch static code checker. Smatch warning says: drivers/net/wireless/brcm80211/brcmsmac/ampdu.c:741 brcms_c_sendampdu() warn: variable dereferenced before check 'p' Reported-by: Dan Carpenter Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 95b5902bc4b3..01b190a25d94 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -735,10 +735,8 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, * a candidate for aggregation */ p = pktq_ppeek(&qi->q, prec); - /* tx_info must be checked with current p */ - tx_info = IEEE80211_SKB_CB(p); - if (p) { + tx_info = IEEE80211_SKB_CB(p); if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && ((u8) (p->priority) == tid)) { plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; @@ -759,6 +757,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, p = NULL; continue; } + /* next packet fit for aggregation so dequeue */ p = brcmu_pktq_pdeq(&qi->q, prec); } else { p = NULL; -- GitLab From d319a7cfd9d80a2e2359e978ba88991531312ee6 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 9 Jun 2012 22:51:43 +0200 Subject: [PATCH 1397/6849] brcmfmac: add debugfs helper functions This patch adds debugfs support to brcmfmac. It provide helper functions to setup the debugfs folder structure for the driver, which has following hierarchy: /brcmfmac// ie.: /sys/kernel/debug/brcmfmac/mmc0:0001:2/ The new source file provides functions to create and remove the two folders and a function to retrieve the device-specific folder so files can be created in it. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/Makefile | 2 + drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 3 + .../net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 63 +++++++++++++++++++ .../net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 23 +++++++ .../wireless/brcm80211/brcmfmac/dhd_linux.c | 7 +++ 5 files changed, 98 insertions(+) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index abb48032753b..9d5170b6df50 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -34,3 +34,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ sdio_chip.o brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ usb.o +brcmfmac-$(CONFIG_BRCMDBG) += \ + dhd_dbg.o \ No newline at end of file diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 9f637014486e..a11fe54f5950 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -613,6 +613,9 @@ struct brcmf_pub { struct work_struct multicast_work; u8 macvalue[ETH_ALEN]; atomic_t pend_8021x_cnt; +#ifdef DEBUG + struct dentry *dbgfs_dir; +#endif }; struct brcmf_if_event { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c new file mode 100644 index 000000000000..0a7a3d50df6e --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include + +#include +#include +#include +#include "dhd.h" +#include "dhd_bus.h" + +static struct dentry *root_folder; + +void brcmf_debugfs_init(void) +{ + root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); + if (IS_ERR(root_folder)) + root_folder = NULL; +} + +void brcmf_debugfs_exit(void) +{ + if (!root_folder) + return; + + debugfs_remove_recursive(root_folder); + root_folder = NULL; +} + +int brcmf_debugfs_attach(struct brcmf_pub *drvr) +{ + if (!root_folder) + return -ENODEV; + + drvr->dbgfs_dir = debugfs_create_dir(dev_name(drvr->dev), root_folder); + return PTR_RET(drvr->dbgfs_dir); +} + +void brcmf_debugfs_detach(struct brcmf_pub *drvr) +{ + if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) + debugfs_remove_recursive(drvr->dbgfs_dir); +} + +struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) +{ + return drvr->dbgfs_dir; +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index a2c4576cf9ff..0efb226030a4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -76,4 +76,27 @@ do { \ extern int brcmf_msg_level; +struct brcmf_pub; +#ifdef DEBUG +void brcmf_debugfs_init(void); +void brcmf_debugfs_exit(void); +int brcmf_debugfs_attach(struct brcmf_pub *drvr); +void brcmf_debugfs_detach(struct brcmf_pub *drvr); +struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); +#else +static inline void brcmf_debugfs_init(void) +{ +} +static inline void brcmf_debugfs_exit(void) +{ +} +static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr) +{ + return 0; +} +static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) +{ +} +#endif + #endif /* _BRCMF_DBG_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 8933f9b31a9a..01cf6c03390b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1007,6 +1007,9 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) drvr->bus_if->drvr = drvr; drvr->dev = dev; + /* create device debugfs folder */ + brcmf_debugfs_attach(drvr); + /* Attach and link in the protocol */ ret = brcmf_proto_attach(drvr); if (ret != 0) { @@ -1123,6 +1126,7 @@ void brcmf_detach(struct device *dev) brcmf_proto_detach(drvr); } + brcmf_debugfs_detach(drvr); bus_if->drvr = NULL; kfree(drvr); } @@ -1192,6 +1196,8 @@ exit: static void brcmf_driver_init(struct work_struct *work) { + brcmf_debugfs_init(); + #ifdef CONFIG_BRCMFMAC_SDIO brcmf_sdio_init(); #endif @@ -1219,6 +1225,7 @@ static void __exit brcmfmac_module_exit(void) #ifdef CONFIG_BRCMFMAC_USB brcmf_usb_exit(); #endif + brcmf_debugfs_exit(); } module_init(brcmfmac_module_init); -- GitLab From 80969836a7ddde326d3f289d234e9e2d9ed27272 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 9 Jun 2012 22:51:44 +0200 Subject: [PATCH 1398/6849] brcmfmac: expose sdio internal counters in debugfs The structure brcmf_sdio contains a number of counters that are useful for debugging. These were not available in user-space. This patch exposes them in debugfs under the filename 'counters'. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 63 +++++++ .../net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 36 ++++ .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 169 ++++++++---------- 3 files changed, 175 insertions(+), 93 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 0a7a3d50df6e..7f89540b56da 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -17,12 +17,14 @@ #include #include #include +#include #include #include #include #include "dhd.h" #include "dhd_bus.h" +#include "dhd_dbg.h" static struct dentry *root_folder; @@ -61,3 +63,64 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) { return drvr->dbgfs_dir; } + +static +ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data, + size_t count, loff_t *ppos) +{ + struct brcmf_sdio_count *sdcnt = f->private_data; + char buf[750]; + int res; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), + "intrcount: %u\nlastintrs: %u\n" + "pollcnt: %u\nregfails: %u\n" + "tx_sderrs: %u\nfcqueued: %u\n" + "rxrtx: %u\nrx_toolong: %u\n" + "rxc_errors: %u\nrx_hdrfail: %u\n" + "rx_badhdr: %u\nrx_badseq: %u\n" + "fc_rcvd: %u\nfc_xoff: %u\n" + "fc_xon: %u\nrxglomfail: %u\n" + "rxglomframes: %u\nrxglompkts: %u\n" + "f2rxhdrs: %u\nf2rxdata: %u\n" + "f2txdata: %u\nf1regdata: %u\n" + "tickcnt: %u\ntx_ctlerrs: %lu\n" + "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" + "rx_ctlpkts: %lu\nrx_readahead: %lu\n", + sdcnt->intrcount, sdcnt->lastintrs, + sdcnt->pollcnt, sdcnt->regfails, + sdcnt->tx_sderrs, sdcnt->fcqueued, + sdcnt->rxrtx, sdcnt->rx_toolong, + sdcnt->rxc_errors, sdcnt->rx_hdrfail, + sdcnt->rx_badhdr, sdcnt->rx_badseq, + sdcnt->fc_rcvd, sdcnt->fc_xoff, + sdcnt->fc_xon, sdcnt->rxglomfail, + sdcnt->rxglomframes, sdcnt->rxglompkts, + sdcnt->f2rxhdrs, sdcnt->f2rxdata, + sdcnt->f2txdata, sdcnt->f1regdata, + sdcnt->tickcnt, sdcnt->tx_ctlerrs, + sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, + sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); + + return simple_read_from_buffer(data, count, ppos, buf, res); +} + +static const struct file_operations brcmf_debugfs_sdio_counter_ops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = brcmf_debugfs_sdio_counter_read +}; + +void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, + struct brcmf_sdio_count *sdcnt) +{ + struct dentry *dentry = drvr->dbgfs_dir; + + if (!IS_ERR_OR_NULL(dentry)) + debugfs_create_file("counters", S_IRUGO, dentry, + sdcnt, &brcmf_debugfs_sdio_counter_ops); +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 0efb226030a4..b784920532d3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -76,6 +76,40 @@ do { \ extern int brcmf_msg_level; +/* + * hold counter variables used in brcmfmac sdio driver. + */ +struct brcmf_sdio_count { + uint intrcount; /* Count of device interrupt callbacks */ + uint lastintrs; /* Count as of last watchdog timer */ + uint pollcnt; /* Count of active polls */ + uint regfails; /* Count of R_REG failures */ + uint tx_sderrs; /* Count of tx attempts with sd errors */ + uint fcqueued; /* Tx packets that got queued */ + uint rxrtx; /* Count of rtx requests (NAK to dongle) */ + uint rx_toolong; /* Receive frames too long to receive */ + uint rxc_errors; /* SDIO errors when reading control frames */ + uint rx_hdrfail; /* SDIO errors on header reads */ + uint rx_badhdr; /* Bad received headers (roosync?) */ + uint rx_badseq; /* Mismatched rx sequence number */ + uint fc_rcvd; /* Number of flow-control events received */ + uint fc_xoff; /* Number which turned on flow-control */ + uint fc_xon; /* Number which turned off flow-control */ + uint rxglomfail; /* Failed deglom attempts */ + uint rxglomframes; /* Number of glom frames (superframes) */ + uint rxglompkts; /* Number of packets from glom frames */ + uint f2rxhdrs; /* Number of header reads */ + uint f2rxdata; /* Number of frame data reads */ + uint f2txdata; /* Number of f2 frame writes */ + uint f1regdata; /* Number of f1 register accesses */ + uint tickcnt; /* Number of watchdog been schedule */ + ulong tx_ctlerrs; /* Err of sending ctrl frames */ + ulong tx_ctlpkts; /* Ctrl frames sent to dongle */ + ulong rx_ctlerrs; /* Err of processing rx ctrl frames */ + ulong rx_ctlpkts; /* Ctrl frames processed from dongle */ + ulong rx_readahead_cnt; /* packets where header read-ahead was used */ +}; + struct brcmf_pub; #ifdef DEBUG void brcmf_debugfs_init(void); @@ -83,6 +117,8 @@ void brcmf_debugfs_exit(void); int brcmf_debugfs_attach(struct brcmf_pub *drvr); void brcmf_debugfs_detach(struct brcmf_pub *drvr); struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); +void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, + struct brcmf_sdio_count *sdcnt); #else static inline void brcmf_debugfs_init(void) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 1dbf2be478c8..a07fb01bc36b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -502,12 +502,9 @@ struct brcmf_sdio { bool intr; /* Use interrupts */ bool poll; /* Use polling */ bool ipend; /* Device interrupt is pending */ - uint intrcount; /* Count of device interrupt callbacks */ - uint lastintrs; /* Count as of last watchdog timer */ uint spurious; /* Count of spurious interrupts */ uint pollrate; /* Ticks between device polls */ uint polltick; /* Tick counter */ - uint pollcnt; /* Count of active polls */ #ifdef DEBUG uint console_interval; @@ -515,8 +512,6 @@ struct brcmf_sdio { uint console_addr; /* Console address from shared struct */ #endif /* DEBUG */ - uint regfails; /* Count of R_REG failures */ - uint clkstate; /* State of sd and backplane clock(s) */ bool activity; /* Activity flag for clock down */ s32 idletime; /* Control for activity timeout */ @@ -531,33 +526,6 @@ struct brcmf_sdio { /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ bool usebufpool; - /* Some additional counters */ - uint tx_sderrs; /* Count of tx attempts with sd errors */ - uint fcqueued; /* Tx packets that got queued */ - uint rxrtx; /* Count of rtx requests (NAK to dongle) */ - uint rx_toolong; /* Receive frames too long to receive */ - uint rxc_errors; /* SDIO errors when reading control frames */ - uint rx_hdrfail; /* SDIO errors on header reads */ - uint rx_badhdr; /* Bad received headers (roosync?) */ - uint rx_badseq; /* Mismatched rx sequence number */ - uint fc_rcvd; /* Number of flow-control events received */ - uint fc_xoff; /* Number which turned on flow-control */ - uint fc_xon; /* Number which turned off flow-control */ - uint rxglomfail; /* Failed deglom attempts */ - uint rxglomframes; /* Number of glom frames (superframes) */ - uint rxglompkts; /* Number of packets from glom frames */ - uint f2rxhdrs; /* Number of header reads */ - uint f2rxdata; /* Number of frame data reads */ - uint f2txdata; /* Number of f2 frame writes */ - uint f1regdata; /* Number of f1 register accesses */ - uint tickcnt; /* Number of watchdog been schedule */ - unsigned long tx_ctlerrs; /* Err of sending ctrl frames */ - unsigned long tx_ctlpkts; /* Ctrl frames sent to dongle */ - unsigned long rx_ctlerrs; /* Err of processing rx ctrl frames */ - unsigned long rx_ctlpkts; /* Ctrl frames processed from dongle */ - unsigned long rx_readahead_cnt; /* Number of packets where header - * read-ahead was used. */ - u8 *ctrl_frame_buf; u32 ctrl_frame_len; bool ctrl_frame_stat; @@ -583,6 +551,7 @@ struct brcmf_sdio { u32 fw_ptr; bool txoff; /* Transmit flow-controlled */ + struct brcmf_sdio_count sdcnt; }; /* clkstate */ @@ -945,7 +914,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) if (ret == 0) w_sdreg32(bus, SMB_INT_ACK, offsetof(struct sdpcmd_regs, tosbmailbox)); - bus->f1regdata += 2; + bus->sdcnt.f1regdata += 2; /* Dongle recomposed rx frames, accept them again */ if (hmb_data & HMB_DATA_NAKHANDLED) { @@ -984,12 +953,12 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) HMB_DATA_FCDATA_SHIFT; if (fcbits & ~bus->flowcontrol) - bus->fc_xoff++; + bus->sdcnt.fc_xoff++; if (bus->flowcontrol & ~fcbits) - bus->fc_xon++; + bus->sdcnt.fc_xon++; - bus->fc_rcvd++; + bus->sdcnt.fc_rcvd++; bus->flowcontrol = fcbits; } @@ -1021,7 +990,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); - bus->f1regdata++; + bus->sdcnt.f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { @@ -1029,7 +998,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) SBSDIO_FUNC1_RFRAMEBCHI, &err); lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO, &err); - bus->f1regdata += 2; + bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -1047,11 +1016,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries); if (rtx) { - bus->rxrtx++; + bus->sdcnt.rxrtx++; err = w_sdreg32(bus, SMB_NAK, offsetof(struct sdpcmd_regs, tosbmailbox)); - bus->f1regdata++; + bus->sdcnt.f1regdata++; if (err == 0) bus->rxskip = true; } @@ -1243,7 +1212,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) dlen); errcode = -1; } - bus->f2rxdata++; + bus->sdcnt.f2rxdata++; /* On failure, kill the superframe, allow a couple retries */ if (errcode < 0) { @@ -1256,7 +1225,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } else { bus->glomerr = 0; brcmf_sdbrcm_rxfail(bus, true, false); - bus->rxglomfail++; + bus->sdcnt.rxglomfail++; brcmf_sdbrcm_free_glom(bus); } return 0; @@ -1312,7 +1281,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (rxseq != seq) { brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n", seq, rxseq); - bus->rx_badseq++; + bus->sdcnt.rx_badseq++; rxseq = seq; } @@ -1376,7 +1345,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } else { bus->glomerr = 0; brcmf_sdbrcm_rxfail(bus, true, false); - bus->rxglomfail++; + bus->sdcnt.rxglomfail++; brcmf_sdbrcm_free_glom(bus); } bus->nextlen = 0; @@ -1402,7 +1371,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (rxseq != seq) { brcmf_dbg(GLOM, "rx_seq %d, expected %d\n", seq, rxseq); - bus->rx_badseq++; + bus->sdcnt.rx_badseq++; rxseq = seq; } rxseq++; @@ -1441,8 +1410,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) down(&bus->sdsem); } - bus->rxglomframes++; - bus->rxglompkts += bus->glom.qlen; + bus->sdcnt.rxglomframes++; + bus->sdcnt.rxglompkts += bus->glom.qlen; } return num; } @@ -1526,7 +1495,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", len, len - doff, bus->sdiodev->bus_if->maxctl); bus->sdiodev->bus_if->dstats.rx_errors++; - bus->rx_toolong++; + bus->sdcnt.rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); goto done; } @@ -1536,13 +1505,13 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); - bus->f2rxdata++; + bus->sdcnt.f2rxdata++; /* Control frame failures need retransmission */ if (sdret < 0) { brcmf_dbg(ERROR, "read %d control bytes failed: %d\n", rdlen, sdret); - bus->rxc_errors++; + bus->sdcnt.rxc_errors++; brcmf_sdbrcm_rxfail(bus, true, true); goto done; } @@ -1589,7 +1558,7 @@ brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen, /* Read the entire frame */ sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, *pkt); - bus->f2rxdata++; + bus->sdcnt.f2rxdata++; if (sdret < 0) { brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n", @@ -1630,7 +1599,7 @@ brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf, if ((u16)~(*len ^ check)) { brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n", nextlen, *len, check); - bus->rx_badhdr++; + bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); goto fail; } @@ -1746,7 +1715,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) bus->nextlen = 0; } - bus->rx_readahead_cnt++; + bus->sdcnt.rx_readahead_cnt++; /* Handle Flow Control */ fcbits = SDPCM_FCMASK_VALUE( @@ -1754,12 +1723,12 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if (bus->flowcontrol != fcbits) { if (~bus->flowcontrol & fcbits) - bus->fc_xoff++; + bus->sdcnt.fc_xoff++; if (bus->flowcontrol & ~fcbits) - bus->fc_xon++; + bus->sdcnt.fc_xon++; - bus->fc_rcvd++; + bus->sdcnt.fc_rcvd++; bus->flowcontrol = fcbits; } @@ -1767,7 +1736,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if (rxseq != seq) { brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n", seq, rxseq); - bus->rx_badseq++; + bus->sdcnt.rx_badseq++; rxseq = seq; } @@ -1814,11 +1783,11 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, bus->rxhdr, BRCMF_FIRSTREAD); - bus->f2rxhdrs++; + bus->sdcnt.f2rxhdrs++; if (sdret < 0) { brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret); - bus->rx_hdrfail++; + bus->sdcnt.rx_hdrfail++; brcmf_sdbrcm_rxfail(bus, true, true); continue; } @@ -1840,7 +1809,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if ((u16) ~(len ^ check)) { brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n", len, check); - bus->rx_badhdr++; + bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -1861,7 +1830,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if ((doff < SDPCM_HDRLEN) || (doff > len)) { brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n", doff, len, SDPCM_HDRLEN, seq); - bus->rx_badhdr++; + bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -1880,19 +1849,19 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if (bus->flowcontrol != fcbits) { if (~bus->flowcontrol & fcbits) - bus->fc_xoff++; + bus->sdcnt.fc_xoff++; if (bus->flowcontrol & ~fcbits) - bus->fc_xon++; + bus->sdcnt.fc_xon++; - bus->fc_rcvd++; + bus->sdcnt.fc_rcvd++; bus->flowcontrol = fcbits; } /* Check and update sequence number */ if (rxseq != seq) { brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq); - bus->rx_badseq++; + bus->sdcnt.rx_badseq++; rxseq = seq; } @@ -1937,7 +1906,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_dbg(ERROR, "too long: len %d rdlen %d\n", len, rdlen); bus->sdiodev->bus_if->dstats.rx_errors++; - bus->rx_toolong++; + bus->sdcnt.rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -1960,7 +1929,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) /* Read the remaining frame data */ sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); - bus->f2rxdata++; + bus->sdcnt.f2rxdata++; if (sdret < 0) { brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen, @@ -2147,18 +2116,18 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); - bus->f2txdata++; + bus->sdcnt.f2txdata++; if (ret < 0) { /* On failure, abort the command and terminate the frame */ brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", ret); - bus->tx_sderrs++; + bus->sdcnt.tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); - bus->f1regdata++; + bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; @@ -2166,7 +2135,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, SBSDIO_FUNC1_WFRAMEBCHI, NULL); lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; + bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) break; } @@ -2224,7 +2193,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) ret = r_sdreg32(bus, &intstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->f2txdata++; + bus->sdcnt.f2txdata++; if (ret != 0) break; if (intstatus & bus->hostintmask) @@ -2417,7 +2386,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) bus->ipend = false; err = r_sdreg32(bus, &newstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->f1regdata++; + bus->sdcnt.f1regdata++; if (err != 0) newstatus = 0; newstatus &= bus->hostintmask; @@ -2426,7 +2395,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) err = w_sdreg32(bus, newstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->f1regdata++; + bus->sdcnt.f1regdata++; } } @@ -2445,7 +2414,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) err = r_sdreg32(bus, &newstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->f1regdata += 2; + bus->sdcnt.f1regdata += 2; bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); intstatus |= (newstatus & bus->hostintmask); @@ -2510,13 +2479,13 @@ clkwait: terminate the frame */ brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", ret); - bus->tx_sderrs++; + bus->sdcnt.tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, &err); - bus->f1regdata++; + bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; @@ -2526,7 +2495,7 @@ clkwait: lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, &err); - bus->f1regdata += 2; + bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) break; } @@ -2657,7 +2626,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) /* Check for existing queue, current flow-control, pending event, or pending clock */ brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq)); - bus->fcqueued++; + bus->sdcnt.fcqueued++; /* Priority based enq */ spin_lock_bh(&bus->txqlock); @@ -2845,13 +2814,13 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) /* On failure, abort the command and terminate the frame */ brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", ret); - bus->tx_sderrs++; + bus->sdcnt.tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); - bus->f1regdata++; + bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; @@ -2859,7 +2828,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) SBSDIO_FUNC1_WFRAMEBCHI, NULL); lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; + bus->sdcnt.f1regdata += 2; if (hi == 0 && lo == 0) break; } @@ -2976,13 +2945,26 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) up(&bus->sdsem); if (ret) - bus->tx_ctlerrs++; + bus->sdcnt.tx_ctlerrs++; else - bus->tx_ctlpkts++; + bus->sdcnt.tx_ctlpkts++; return ret ? -EIO : 0; } +#ifdef DEBUG +static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) +{ + struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr; + + brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); +} +#else +static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) +{ +} +#endif /* DEBUG */ + static int brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) { @@ -3017,9 +2999,9 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) } if (rxlen) - bus->rx_ctlpkts++; + bus->sdcnt.rx_ctlpkts++; else - bus->rx_ctlerrs++; + bus->sdcnt.rx_ctlerrs++; return rxlen ? (int)rxlen : -ETIMEDOUT; } @@ -3419,7 +3401,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) return 0; /* Start the watchdog timer */ - bus->tickcnt = 0; + bus->sdcnt.tickcnt = 0; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); down(&bus->sdsem); @@ -3512,7 +3494,7 @@ void brcmf_sdbrcm_isr(void *arg) return; } /* Count the interrupt call */ - bus->intrcount++; + bus->sdcnt.intrcount++; bus->ipend = true; /* Shouldn't get this interrupt if we're sleeping? */ @@ -3554,7 +3536,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->polltick = 0; /* Check device if no interrupts */ - if (!bus->intr || (bus->intrcount == bus->lastintrs)) { + if (!bus->intr || + (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) { if (!bus->dpc_sched) { u8 devpend; @@ -3569,7 +3552,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) /* If there is something, make like the ISR and schedule the DPC */ if (intstatus) { - bus->pollcnt++; + bus->sdcnt.pollcnt++; bus->ipend = true; bus->dpc_sched = true; @@ -3581,7 +3564,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) } /* Update interrupt tracking */ - bus->lastintrs = bus->intrcount; + bus->sdcnt.lastintrs = bus->sdcnt.intrcount; } #ifdef DEBUG /* Poll for console output periodically */ @@ -3793,7 +3776,7 @@ brcmf_sdbrcm_watchdog_thread(void *data) if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { brcmf_sdbrcm_bus_watchdog(bus); /* Count the tick for reference */ - bus->tickcnt++; + bus->sdcnt.tickcnt++; } else break; } @@ -3834,7 +3817,6 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); - if (bus) { /* De-register interrupt handler */ brcmf_sdio_intr_unregister(bus->sdiodev); @@ -3938,6 +3920,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) goto fail; } + brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); /* if firmware path present try to download and bring up bus */ -- GitLab From 6304c20167337e21699bb3f7d25fcf099263416e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 11 Jun 2012 10:18:36 +0530 Subject: [PATCH 1399/6849] ath9k_hw: Update initvals for AR9462 Adjust quick_drop value in the baseband AGC register to improve RX in HT20 mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 4a93e1534c1d..8f406ff2c95e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -52,7 +52,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x33795d5e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, -- GitLab From cec429dd65ef1ccc693e5fa1468b0a12982b4283 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:29 +0530 Subject: [PATCH 1400/6849] ath9k: choose legacy rate as last rate of MRR series Choose legacy rate as the last rate of Multi Rate Retry series if and only if the last selected rate is MCS and having higher PER rate. The current code fills a legacy rate as last one even though the previous rates in the series are having good PER value. This could limit the aggregation that affects the uplink performance. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 92a6c0a87f89..e034add9cd5a 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -770,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_tx_rate *rates = tx_info->control.rates; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc = hdr->frame_control; - u8 try_per_rate, i = 0, rix, high_rix; + u8 try_per_rate, i = 0, rix; int is_probe = 0; if (rate_control_send_low(sta, priv_sta, txrc)) @@ -791,7 +791,6 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, rate_table = ath_rc_priv->rate_table; rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe, false); - high_rix = rix; /* * If we're in HT mode and both us and our peer supports LDPC. @@ -839,16 +838,16 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, try_per_rate = 8; /* - * Use a legacy rate as last retry to ensure that the frame - * is tried in both MCS and legacy rates. + * If the last rate in the rate series is MCS and has + * more than 80% of per thresh, then use a legacy rate + * as last retry to ensure that the frame is tried in both + * MCS and legacy rate. */ - if ((rates[2].flags & IEEE80211_TX_RC_MCS) && - (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) || - (ath_rc_priv->per[high_rix] > 45))) + ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); + if (WLAN_RC_PHY_HT(rate_table->info[rix].phy) && + (ath_rc_priv->per[rix] > 45)) rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe, true); - else - ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); /* All other rates in the series have RTS enabled */ ath_rc_rate_set_series(rate_table, &rates[i], txrc, -- GitLab From 8389fb3fd7c0bbe3289578f698917f594e0b6fc9 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:30 +0530 Subject: [PATCH 1401/6849] ath9k: restore power state on set channel failure Not doing so, could cause imbalance in powersave count. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c0f478b0a9a2..e655f2a907b5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1258,6 +1258,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ath_err(common, "Unable to set channel\n"); mutex_unlock(&sc->mutex); + ath9k_ps_restore(sc); return -EINVAL; } -- GitLab From 9dd9b0dc1de8031a31b3eaebc6a9c0ab60612026 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:31 +0530 Subject: [PATCH 1402/6849] ath9k_hw: Fix AR9462 power consumption on idle associated The HW statemachine is sometimes found stuck in the state WL_LNA_CTRL_DISABLE when BT is in sleep, which will cause TX_HOLD always asserted and resmgr stuck in PENDING_TX state Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 34 +++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_mci.h | 10 ++++-- drivers/net/wireless/ath/ath9k/hw.c | 3 ++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index b1ced2a76da3..13907f63bdc0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1404,3 +1404,37 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) /* Force another 2g5g update at next scanning */ mci->update_2g5g = true; } + +void ar9003_mci_set_power_awake(struct ath_hw *ah) +{ + u32 btcoex_ctrl2, diag_sw; + int i; + u8 lna_ctrl, bt_sleep; + + for (i = 0; i < AH_WAIT_TIMEOUT; i++) { + btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2); + if (btcoex_ctrl2 != 0xdeadbeef) + break; + udelay(AH_TIME_QUANTUM); + } + REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23))); + + for (i = 0; i < AH_WAIT_TIMEOUT; i++) { + diag_sw = REG_READ(ah, AR_DIAG_SW); + if (diag_sw != 0xdeadbeef) + break; + udelay(AH_TIME_QUANTUM); + } + REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18))); + lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3; + bt_sleep = REG_READ(ah, AR_MCI_RX_STATUS) & AR_MCI_RX_REMOTE_SLEEP; + + REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2); + REG_WRITE(ah, AR_DIAG_SW, diag_sw); + + if (bt_sleep && (lna_ctrl == 2)) { + REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1); + REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1); + udelay(50); + } +} diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 10282e2bcdc9..2a8c764281ba 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -265,8 +265,6 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); -void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); - /* * These functions are used by ath9k_hw. */ @@ -285,6 +283,8 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, bool is_full_sleep); void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); +void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); +void ar9003_mci_set_power_awake(struct ath_hw *ah); #else @@ -322,6 +322,12 @@ static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) { } +static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) +{ +} +static inline void ar9003_mci_set_power_awake(struct ath_hw *ah) +{ +} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #endif diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 45e670087e1c..6d893335f42b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2111,6 +2111,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) AR_RTC_FORCE_WAKE_EN); udelay(50); + if (ath9k_hw_mci_is_enabled(ah)) + ar9003_mci_set_power_awake(ah); + for (i = POWER_UP_TIME / 50; i > 0; i--) { val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; if (val == AR_RTC_STATUS_ON) -- GitLab From 3863495b86d8ee8e7e70a328de5b88d555d7305a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:32 +0530 Subject: [PATCH 1403/6849] ath9k_hw: check GPM HW write pointer before chip reset Both "MAC Warm Reset" and "MCI Reset Rx" will reset GPM HW write_ptr. We should check software cached write_ptr against HW write_ptr before reset. Otherwise the pending DMA data will be lost. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 18 ++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 + drivers/net/wireless/ath/ath9k/hw.c | 3 +++ 3 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 13907f63bdc0..cbeff9c4b5d8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -893,6 +893,9 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, udelay(100); } + /* Check pending GPM msg before MCI Reset Rx */ + ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL); + regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); REG_WRITE(ah, AR_MCI_COMMAND2, regval); udelay(1); @@ -1190,6 +1193,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); mci->gpm_idx = value; break; + case MCI_STATE_CHECK_GPM_OFFSET: + /* + * This should only be called before "MAC Warm Reset" or + * "MCI Reset Rx". + */ + value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + if (mci->gpm_idx == value) + break; + ath_dbg(common, MCI, + "GPM cached write pointer mismatch %d %d\n", + mci->gpm_idx, value); + mci->query_bt = true; + mci->need_flush_btinfo = true; + mci->gpm_idx = 0; + break; case MCI_STATE_NEXT_GPM_OFFSET: case MCI_STATE_LAST_GPM_OFFSET: /* diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 2a8c764281ba..45624e1d3960 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -190,6 +190,7 @@ enum mci_bt_state { enum mci_state_type { MCI_STATE_ENABLE, MCI_STATE_INIT_GPM_OFFSET, + MCI_STATE_CHECK_GPM_OFFSET, MCI_STATE_NEXT_GPM_OFFSET, MCI_STATE_LAST_GPM_OFFSET, MCI_STATE_BT, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6d893335f42b..8412128b842a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1348,6 +1348,9 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) } } + if (ath9k_hw_mci_is_enabled(ah)) + ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL); + REG_WRITE(ah, AR_RTC_RC, rst_flags); REGWRITE_BUFFER_FLUSH(ah); -- GitLab From 1bde95fa7ed84094d0606d9e79356a9dd8d0e01b Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:33 +0530 Subject: [PATCH 1404/6849] ath9k_hw: fix incorrect LNA register settings After a full reset, mci_reset will put LNA update to the setting for 2G mode. Those registers need to be forced to update when the channel is in 5G. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 24 ++++++++------------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index cbeff9c4b5d8..c11dbaa2f5b1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1013,38 +1013,32 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, } } -void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) +void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (!mci->update_2g5g) + if (!mci->update_2g5g && !force) return; if (mci->is_2g) { ar9003_mci_send_2g5g_status(ah, true); - ar9003_mci_send_lna_transfer(ah, true); - udelay(5); - REG_CLR_BIT(ah, AR_MCI_TX_CTRL, + REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) - REG_SET_BIT(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); + ar9003_mci_osla_setup(ah, true); } else { - ar9003_mci_send_lna_take(ah, true); - udelay(5); - REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); - REG_CLR_BIT(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - ar9003_mci_send_2g5g_status(ah, true); + ar9003_mci_osla_setup(ah, false); + if (!force) + ar9003_mci_send_2g5g_status(ah, true); } } @@ -1313,7 +1307,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) if (mci->unhalt_bt_gpm) ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); - ar9003_mci_2g5g_switch(ah, true); + ar9003_mci_2g5g_switch(ah, false); break; case MCI_STATE_SET_BT_CAL_START: mci->bt_state = MCI_BT_CAL_START; @@ -1394,7 +1388,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) mci->query_bt = true; mci->need_flush_btinfo = true; ar9003_mci_send_coex_wlan_channels(ah, true); - ar9003_mci_2g5g_switch(ah, true); + ar9003_mci_2g5g_switch(ah, false); break; case MCI_STATE_NEED_FTP_STOMP: value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 45624e1d3960..8cb33078f40a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -276,7 +276,7 @@ void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); void ar9003_mci_init_cal_done(struct ath_hw *ah); void ar9003_mci_set_full_sleep(struct ath_hw *ah); -void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); +void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force); void ar9003_mci_check_bt(struct ath_hw *ah); bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8412128b842a..a9d328c955e9 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1711,7 +1711,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) ath9k_hw_start_nfcal(ah, true); if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_2g5g_switch(ah, true); + ar9003_mci_2g5g_switch(ah, false); if (AR_SREV_9271(ah)) ar9002_hw_load_ani_reg(ah, chan); -- GitLab From ed6ebd8bc852845e34e8160eed43b29236b1892f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:34 +0530 Subject: [PATCH 1405/6849] ath9k_hw: program OBS register only when MCI is disabled Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a9d328c955e9..4ec496dae0eb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1915,7 +1915,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_set_dma(ah); - REG_WRITE(ah, AR_OBS, 8); + if (!ath9k_hw_mci_is_enabled(ah)) + REG_WRITE(ah, AR_OBS, 8); if (ah->config.rx_intr_mitigation) { REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); -- GitLab From 92a33298e9a329d4bed9f723811c5bedc7d92b9c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:35 +0530 Subject: [PATCH 1406/6849] ath9k_hw: process MCI interrupts only when btcoex is enabled let us process MCI interrupts only when BTCOEX is enabled to avoid processing bogus interrupts. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index d9e0824af093..78816b8b2173 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -181,11 +181,14 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) u32 mask2 = 0; struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); - u32 sync_cause = 0, async_cause; + u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; + + if (ath9k_hw_mci_is_enabled(ah)) + async_mask |= AR_INTR_ASYNC_MASK_MCI; async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); - if (async_cause & (AR_INTR_MAC_IRQ | AR_INTR_ASYNC_MASK_MCI)) { + if (async_cause & async_mask) { if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON) isr = REG_READ(ah, AR_ISR); -- GitLab From 9e2e0c84699ce7adeddb5cd5763956493ca7d331 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:36 +0530 Subject: [PATCH 1407/6849] ath9k: simplify btcoex profile management This patch simplifies profile management utility functions. * Separate find_profile from add/del functions * Return correct values when the profile list is empty or profile is ot found * flush the profiles when there are entries in the list Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mci.c | 48 ++++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 49137f477b05..2ea5e933b3ba 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -28,11 +28,14 @@ ath_mci_find_profile(struct ath_mci_profile *mci, { struct ath_mci_profile_info *entry; + if (list_empty(&mci->info)) + return NULL; + list_for_each_entry(entry, &mci->info, list) { if (entry->conn_handle == info->conn_handle) - break; + return entry; } - return entry; + return NULL; } static bool ath_mci_add_profile(struct ath_common *common, @@ -49,31 +52,21 @@ static bool ath_mci_add_profile(struct ath_common *common, (info->type != MCI_GPM_COEX_PROFILE_VOICE)) return false; - entry = ath_mci_find_profile(mci, info); - - if (entry) { - memcpy(entry, info, 10); - } else { - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return false; + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return false; - memcpy(entry, info, 10); - INC_PROF(mci, info); - list_add_tail(&info->list, &mci->info); - } + memcpy(entry, info, 10); + INC_PROF(mci, info); + list_add_tail(&entry->list, &mci->info); return true; } static void ath_mci_del_profile(struct ath_common *common, struct ath_mci_profile *mci, - struct ath_mci_profile_info *info) + struct ath_mci_profile_info *entry) { - struct ath_mci_profile_info *entry; - - entry = ath_mci_find_profile(mci, info); - if (!entry) return; @@ -86,12 +79,16 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci) { struct ath_mci_profile_info *info, *tinfo; + mci->aggr_limit = 0; + + if (list_empty(&mci->info)) + return; + list_for_each_entry_safe(info, tinfo, &mci->info, list) { list_del(&info->list); DEC_PROF(mci, info); kfree(info); } - mci->aggr_limit = 0; } static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) @@ -229,12 +226,17 @@ static void ath_mci_process_profile(struct ath_softc *sc, struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; + struct ath_mci_profile_info *entry = NULL; + + entry = ath_mci_find_profile(mci, info); + if (entry) + memcpy(entry, info, 10); if (info->start) { - if (!ath_mci_add_profile(common, mci, info)) + if (!entry && !ath_mci_add_profile(common, mci, info)) return; } else - ath_mci_del_profile(common, mci, info); + ath_mci_del_profile(common, mci, entry); btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; mci->aggr_limit = mci->num_sco ? 6 : 0; @@ -263,8 +265,6 @@ static void ath_mci_process_status(struct ath_softc *sc, if (status->is_link) return; - memset(&info, 0, sizeof(struct ath_mci_profile_info)); - info.conn_handle = status->conn_handle; if (ath_mci_find_profile(mci, &info)) return; -- GitLab From dfd0587a7d99d42cc2d608324991169494d2dbba Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Jun 2012 12:19:37 +0530 Subject: [PATCH 1408/6849] ath9k: keep btcoex period in milliseconds btcoex periord is converted into micro seconds during initialization and converted back to milli seconds while starting timer. As MCI code handles btcoex period in msec, lets keep the btcoex timer in msec and convert them into other form whenever needed. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/gpio.c | 8 ++++---- drivers/net/wireless/ath/ath9k/mci.c | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index af6d27350291..00ff5ab5a54f 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -232,7 +232,7 @@ static void ath_btcoex_period_timer(unsigned long data) } ath9k_ps_restore(sc); - timer_period = btcoex->btcoex_period / 1000; + timer_period = btcoex->btcoex_period; mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); } @@ -267,10 +267,10 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) { struct ath_btcoex *btcoex = &sc->btcoex; - btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; - btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * + btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; + btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 * btcoex->btcoex_period / 100; - btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * + btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 * btcoex->btcoex_period / 100; setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 2ea5e933b3ba..92d61cc0c8e5 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -182,8 +182,7 @@ skip_tuning: if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; - btcoex->btcoex_period *= 1000; - btcoex->btcoex_no_stomp = btcoex->btcoex_period * + btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 * (100 - btcoex->duty_cycle) / 100; ath9k_hw_btcoex_enable(sc->sc_ah); -- GitLab From 3c7992e33ab8d0c625a45ded11cc10d5b622bcd4 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 10:13:53 +0530 Subject: [PATCH 1409/6849] ath9k: defer btcoex scheme update As btcoex scheme updation might sleep, remove the function call from tasklet context and queue it up as a separate work. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 3 +++ drivers/net/wireless/ath/ath9k/mci.c | 14 +++++++++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 02fc1c1e5eeb..a8c050085648 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -698,6 +698,7 @@ struct ath_softc { #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex btcoex; struct ath_mci_coex mci_coex; + struct work_struct mci_work; #endif struct ath_descdma txsdma; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e655f2a907b5..a6f83b683db1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -150,6 +150,9 @@ static void __ath_cancel_work(struct ath_softc *sc) cancel_work_sync(&sc->hw_check_work); cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT + cancel_work_sync(&sc->mci_work); +#endif } static void ath_cancel_work(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 92d61cc0c8e5..e53df86dfce5 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -52,7 +52,7 @@ static bool ath_mci_add_profile(struct ath_common *common, (info->type != MCI_GPM_COEX_PROFILE_VOICE)) return false; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) return false; @@ -219,6 +219,13 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) } } +static void ath9k_mci_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, mci_work); + + ath_mci_update_scheme(sc); +} + static void ath_mci_process_profile(struct ath_softc *sc, struct ath_mci_profile_info *info) { @@ -249,7 +256,7 @@ static void ath_mci_process_profile(struct ath_softc *sc, btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; } - ath_mci_update_scheme(sc); + ieee80211_queue_work(sc->hw, &sc->mci_work); } static void ath_mci_process_status(struct ath_softc *sc, @@ -283,7 +290,7 @@ static void ath_mci_process_status(struct ath_softc *sc, } while (++i < ATH_MCI_MAX_PROFILE); if (old_num_mgmt != mci->num_mgmt) - ath_mci_update_scheme(sc); + ieee80211_queue_work(sc->hw, &sc->mci_work); } static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) @@ -377,6 +384,7 @@ int ath_mci_setup(struct ath_softc *sc) mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), mci->sched_buf.bf_paddr); + INIT_WORK(&sc->mci_work, ath9k_mci_work); ath_dbg(common, MCI, "MCI Initialized\n"); return 0; -- GitLab From a197b76c230725962dc8e13102b24468e8621bfb Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 10:13:54 +0530 Subject: [PATCH 1410/6849] ath9k: fix btcoex duty cycle * Reset duty cycle before updating btcoex scheme. Otherwise duty cycle reaches max limit and never be reduced again * Adjust duty cycle with proper BDR profile value Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index e53df86dfce5..f0c8fa48d79e 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -20,7 +20,7 @@ #include "ath9k.h" #include "mci.h" -static const u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; +static const u8 ath_mci_duty_cycle[] = { 55, 50, 60, 70, 80, 85, 90, 95, 98 }; static struct ath_mci_profile_info* ath_mci_find_profile(struct ath_mci_profile *mci, @@ -120,6 +120,8 @@ static void ath_mci_update_scheme(struct ath_softc *sc) if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) goto skip_tuning; + btcoex->duty_cycle = ath_mci_duty_cycle[num_profile]; + if (num_profile == 1) { info = list_first_entry(&mci->info, struct ath_mci_profile_info, @@ -178,7 +180,7 @@ skip_tuning: if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) return; - btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); + btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_BDR_DUTY_CYCLE : 0); if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; @@ -247,14 +249,12 @@ static void ath_mci_process_profile(struct ath_softc *sc, btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; mci->aggr_limit = mci->num_sco ? 6 : 0; - if (NUM_PROF(mci)) { + btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; + if (NUM_PROF(mci)) btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; - } else { + else btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : ATH_BTCOEX_STOMP_LOW; - btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; - } ieee80211_queue_work(sc->hw, &sc->mci_work); } -- GitLab From 64bc1239c790e051ff677e023435d770d2ffa174 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 12 Jun 2012 20:13:43 +0530 Subject: [PATCH 1411/6849] ath9k: Fix softlockup in AR9485 steps to recreate: load latest ath9k driver with AR9485 stop the network-manager and wpa_supplicant bring the interface up Call Trace: [] ? ath_hw_check+0xe0/0xe0 [ath9k] [] __const_udelay+0x28/0x30 [] ar9003_get_pll_sqsum_dvc+0x4a/0x80 [ath9k_hw] [] ath_hw_pll_work+0x5b/0xe0 [ath9k] [] process_one_work+0x11e/0x470 [] worker_thread+0x15f/0x360 [] ? manage_workers+0x230/0x230 [] kthread+0x93/0xa0 [] kernel_thread_helper+0x4/0x10 [] ? kthread_freezable_should_stop+0x70/0x70 [] ? gs_change+0x13/0x13 ensure that the PLL-WAR for AR9485/AR9340 is executed only if the STA is associated (or) IBSS/AP mode had started beaconing. Ideally this WAR is needed to recover from some rare beacon stuck during stress testing. Before the STA is associated/IBSS had started beaconing, PLL4(0x1618c) always seem to have zero even though we had configured PLL3(0x16188) to query about PLL's locking status. When we keep on polling infinitely PLL4's 8th bit(ie check for PLL locking measurements is done), machine hangs due to softlockup. fixes https://bugzilla.redhat.com/show_bug.cgi?id=811142 Reported-by: Rolf Offermanns Cc: stable@vger.kernel.org Tested-by: Mohammed Shafi Shajakhan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/link.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 0cc4c70f7f0c..a105c9426251 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -136,6 +136,14 @@ void ath_hw_pll_work(struct work_struct *work) u32 pll_sqsum; struct ath_softc *sc = container_of(work, struct ath_softc, hw_pll_work.work); + /* + * ensure that the PLL WAR is executed only + * after the STA is associated (or) if the + * beaconing had started in interfaces that + * uses beacons. + */ + if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) + return; ath9k_ps_wakeup(sc); pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); -- GitLab From 506847ad34c08fe4f766ffe1b955713628acf6bd Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:16 +0530 Subject: [PATCH 1412/6849] ath9k_hw: cleanup MCI gpm offset state Add utility functions to get and test GPM offset and remove MCI_STATE*_GPM_OFFSET states. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 198 ++++++++++---------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 9 +- drivers/net/wireless/ath/ath9k/hw.c | 2 +- drivers/net/wireless/ath/ath9k/mci.c | 6 +- 4 files changed, 110 insertions(+), 105 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index c11dbaa2f5b1..0433f2b12c53 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -593,8 +593,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, if (!time_out) break; - offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, - &more_data); + offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); if (offset == MCI_GPM_INVALID) continue; @@ -658,8 +657,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, time_out = 0; while (more_data == MCI_GPM_MORE) { - offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, - &more_data); + offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); if (offset == MCI_GPM_INVALID) break; @@ -894,7 +892,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, } /* Check pending GPM msg before MCI Reset Rx */ - ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL); + ar9003_mci_check_gpm_offset(ah); regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); REG_WRITE(ah, AR_MCI_COMMAND2, regval); @@ -902,7 +900,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); REG_WRITE(ah, AR_MCI_COMMAND2, regval); - ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); + ar9003_mci_get_next_gpm_offset(ah, true, NULL); REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | @@ -1170,7 +1168,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 value = 0, more_gpm = 0, gpm_ptr; + u32 value = 0; u8 query_type; switch (state_type) { @@ -1182,96 +1180,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) value = 0; } value &= AR_BTCOEX_CTRL_MCI_MODE_EN; - break; - case MCI_STATE_INIT_GPM_OFFSET: - value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - mci->gpm_idx = value; - break; - case MCI_STATE_CHECK_GPM_OFFSET: - /* - * This should only be called before "MAC Warm Reset" or - * "MCI Reset Rx". - */ - value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - if (mci->gpm_idx == value) - break; - ath_dbg(common, MCI, - "GPM cached write pointer mismatch %d %d\n", - mci->gpm_idx, value); - mci->query_bt = true; - mci->need_flush_btinfo = true; - mci->gpm_idx = 0; - break; - case MCI_STATE_NEXT_GPM_OFFSET: - case MCI_STATE_LAST_GPM_OFFSET: - /* - * This could be useful to avoid new GPM message interrupt which - * may lead to spurious interrupt after power sleep, or multiple - * entry of ath_mci_intr(). - * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can - * alleviate this effect, but clearing GPM RX interrupt bit is - * safe, because whether this is called from hw or driver code - * there must be an interrupt bit set/triggered initially - */ - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_GPM); - - gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - value = gpm_ptr; - - if (value == 0) - value = mci->gpm_len - 1; - else if (value >= mci->gpm_len) { - if (value != 0xFFFF) - value = 0; - } else { - value--; - } - - if (value == 0xFFFF) { - value = MCI_GPM_INVALID; - more_gpm = MCI_GPM_NOMORE; - } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) { - if (gpm_ptr == mci->gpm_idx) { - value = MCI_GPM_INVALID; - more_gpm = MCI_GPM_NOMORE; - } else { - for (;;) { - u32 temp_index; - - /* skip reserved GPM if any */ - - if (value != mci->gpm_idx) - more_gpm = MCI_GPM_MORE; - else - more_gpm = MCI_GPM_NOMORE; - - temp_index = mci->gpm_idx; - mci->gpm_idx++; - - if (mci->gpm_idx >= - mci->gpm_len) - mci->gpm_idx = 0; - - if (ar9003_mci_is_gpm_valid(ah, - temp_index)) { - value = temp_index; - break; - } - - if (more_gpm == MCI_GPM_NOMORE) { - value = MCI_GPM_INVALID; - break; - } - } - } - if (p_data) - *p_data = more_gpm; - } - - if (value != MCI_GPM_INVALID) - value <<= 4; - break; case MCI_STATE_LAST_SCHD_MSG_OFFSET: value = MS(REG_READ(ah, AR_MCI_RX_STATUS), @@ -1450,3 +1358,99 @@ void ar9003_mci_set_power_awake(struct ath_hw *ah) udelay(50); } } + +void ar9003_mci_check_gpm_offset(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 offset; + + /* + * This should only be called before "MAC Warm Reset" or "MCI Reset Rx". + */ + offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + if (mci->gpm_idx == offset) + return; + ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n", + mci->gpm_idx, offset); + mci->query_bt = true; + mci->need_flush_btinfo = true; + mci->gpm_idx = 0; +} + +u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) +{ + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 offset, more_gpm = 0, gpm_ptr; + + if (first) { + gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + mci->gpm_idx = gpm_ptr; + return gpm_ptr; + } + + /* + * This could be useful to avoid new GPM message interrupt which + * may lead to spurious interrupt after power sleep, or multiple + * entry of ath_mci_intr(). + * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can + * alleviate this effect, but clearing GPM RX interrupt bit is + * safe, because whether this is called from hw or driver code + * there must be an interrupt bit set/triggered initially + */ + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_GPM); + + gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + offset = gpm_ptr; + + if (!offset) + offset = mci->gpm_len - 1; + else if (offset >= mci->gpm_len) { + if (offset != 0xFFFF) + offset = 0; + } else { + offset--; + } + + if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) { + offset = MCI_GPM_INVALID; + more_gpm = MCI_GPM_NOMORE; + goto out; + } + for (;;) { + u32 temp_index; + + /* skip reserved GPM if any */ + + if (offset != mci->gpm_idx) + more_gpm = MCI_GPM_MORE; + else + more_gpm = MCI_GPM_NOMORE; + + temp_index = mci->gpm_idx; + mci->gpm_idx++; + + if (mci->gpm_idx >= mci->gpm_len) + mci->gpm_idx = 0; + + if (ar9003_mci_is_gpm_valid(ah, temp_index)) { + offset = temp_index; + break; + } + + if (more_gpm == MCI_GPM_NOMORE) { + offset = MCI_GPM_INVALID; + break; + } + } + + if (offset != MCI_GPM_INVALID) + offset <<= 4; +out: + if (more) + *more = more_gpm; + + return offset; +} +EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 8cb33078f40a..163d1562163d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -189,10 +189,6 @@ enum mci_bt_state { /* Type of state query */ enum mci_state_type { MCI_STATE_ENABLE, - MCI_STATE_INIT_GPM_OFFSET, - MCI_STATE_CHECK_GPM_OFFSET, - MCI_STATE_NEXT_GPM_OFFSET, - MCI_STATE_LAST_GPM_OFFSET, MCI_STATE_BT, MCI_STATE_SET_BT_SLEEP, MCI_STATE_SET_BT_AWAKE, @@ -266,6 +262,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); +u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); /* * These functions are used by ath9k_hw. */ @@ -286,6 +283,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); void ar9003_mci_set_power_awake(struct ath_hw *ah); +void ar9003_mci_check_gpm_offset(struct ath_hw *ah); #else @@ -329,6 +327,9 @@ static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) static inline void ar9003_mci_set_power_awake(struct ath_hw *ah) { } +static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah) +{ +} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #endif diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 4ec496dae0eb..784baee5db84 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1349,7 +1349,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) } if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL); + ar9003_mci_check_gpm_offset(ah); REG_WRITE(ah, AR_RTC_RC, rst_flags); diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index f0c8fa48d79e..9e152316fd5c 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -421,7 +421,7 @@ void ath_mci_intr(struct ath_softc *sc) ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { - ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); + ar9003_mci_get_next_gpm_offset(ah, true, NULL); return; } @@ -488,8 +488,8 @@ void ath_mci_intr(struct ath_softc *sc) while (more_data == MCI_GPM_MORE) { pgpm = mci->gpm_buf.bf_addr; - offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, - &more_data); + offset = ar9003_mci_get_next_gpm_offset(ah, false, + &more_data); if (offset == MCI_GPM_INVALID) break; -- GitLab From e1763d3f3388968d622a340fed711ae16fc1bc11 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:17 +0530 Subject: [PATCH 1413/6849] ath9k_hw: add utility function to set BT version Add a utility function to set bluetooth version and remove MCI_STATE_SET_BT_COEX_VERSION. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 25 ++++++++++----------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 2 +- drivers/net/wireless/ath/ath9k/mci.c | 11 +++------ 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 0433f2b12c53..a021e7474757 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1166,7 +1166,6 @@ EXPORT_SYMBOL(ar9003_mci_cleanup); u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 value = 0; u8 query_type; @@ -1239,18 +1238,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) case MCI_STATE_SEND_WLAN_COEX_VERSION: ar9003_mci_send_coex_version_response(ah, true); break; - case MCI_STATE_SET_BT_COEX_VERSION: - if (!p_data) - ath_dbg(common, MCI, - "MCI Set BT Coex version with NULL data!!\n"); - else { - mci->bt_ver_major = (*p_data >> 8) & 0xff; - mci->bt_ver_minor = (*p_data) & 0xff; - mci->bt_version_known = true; - ath_dbg(common, MCI, "MCI BT version set: %d.%d\n", - mci->bt_ver_major, mci->bt_ver_minor); - } - break; case MCI_STATE_SEND_WLAN_CHANNELS: if (p_data) { if (((mci->wlan_channels[1] & 0xffff0000) == @@ -1454,3 +1441,15 @@ out: return offset; } EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset); + +void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor) +{ + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + + mci->bt_ver_major = major; + mci->bt_ver_minor = minor; + mci->bt_version_known = true; + ath_dbg(ath9k_hw_common(ah), MCI, "MCI BT version set: %d.%d\n", + mci->bt_ver_major, mci->bt_ver_minor); +} +EXPORT_SYMBOL(ar9003_mci_set_bt_version); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 163d1562163d..d4e7739b89ff 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -201,7 +201,6 @@ enum mci_state_type { MCI_STATE_CONT_TXRX, MCI_STATE_RESET_REQ_WAKE, MCI_STATE_SEND_WLAN_COEX_VERSION, - MCI_STATE_SET_BT_COEX_VERSION, MCI_STATE_SEND_WLAN_CHANNELS, MCI_STATE_SEND_VERSION_QUERY, MCI_STATE_SEND_STATUS_QUERY, @@ -263,6 +262,7 @@ void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); +void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); /* * These functions are used by ath9k_hw. */ diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 9e152316fd5c..6f4188a32ff0 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -299,22 +299,17 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) struct ath_mci_profile_info profile_info; struct ath_mci_profile_status profile_status; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - u32 version; - u8 major; - u8 minor; + u8 major, minor; u32 seq_num; switch (opcode) { case MCI_GPM_COEX_VERSION_QUERY: - version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, - NULL); + ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, NULL); break; case MCI_GPM_COEX_VERSION_RESPONSE: major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); - version = (major << 8) + minor; - version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION, - &version); + ar9003_mci_set_bt_version(ah, major, minor); break; case MCI_GPM_COEX_STATUS_QUERY: ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL); -- GitLab From 2d340ac81e7474535db7a14f35c80b45b02b63a1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:18 +0530 Subject: [PATCH 1414/6849] ath9k_hw: remove MCI_STATE_SEND_WLAN_CHANNELS Add a MCI util function to send wlan channel info to BT. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 25 ++++++++------------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 2 +- drivers/net/wireless/ath/ath9k/mci.c | 2 +- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index a021e7474757..3b44ebe3f750 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1238,22 +1238,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) case MCI_STATE_SEND_WLAN_COEX_VERSION: ar9003_mci_send_coex_version_response(ah, true); break; - case MCI_STATE_SEND_WLAN_CHANNELS: - if (p_data) { - if (((mci->wlan_channels[1] & 0xffff0000) == - (*(p_data + 1) & 0xffff0000)) && - (mci->wlan_channels[2] == *(p_data + 2)) && - (mci->wlan_channels[3] == *(p_data + 3))) - break; - - mci->wlan_channels[0] = *p_data++; - mci->wlan_channels[1] = *p_data++; - mci->wlan_channels[2] = *p_data++; - mci->wlan_channels[3] = *p_data++; - } - mci->wlan_channels_update = true; - ar9003_mci_send_coex_wlan_channels(ah, true); - break; case MCI_STATE_SEND_VERSION_QUERY: ar9003_mci_send_coex_version_query(ah, true); break; @@ -1453,3 +1437,12 @@ void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor) mci->bt_ver_major, mci->bt_ver_minor); } EXPORT_SYMBOL(ar9003_mci_set_bt_version); + +void ar9003_mci_send_wlan_channels(struct ath_hw *ah) +{ + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + + mci->wlan_channels_update = true; + ar9003_mci_send_coex_wlan_channels(ah, true); +} +EXPORT_SYMBOL(ar9003_mci_send_wlan_channels); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index d4e7739b89ff..05f42a98aeac 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -201,7 +201,6 @@ enum mci_state_type { MCI_STATE_CONT_TXRX, MCI_STATE_RESET_REQ_WAKE, MCI_STATE_SEND_WLAN_COEX_VERSION, - MCI_STATE_SEND_WLAN_CHANNELS, MCI_STATE_SEND_VERSION_QUERY, MCI_STATE_SEND_STATUS_QUERY, MCI_STATE_NEED_FLUSH_BT_INFO, @@ -263,6 +262,7 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); +void ar9003_mci_send_wlan_channels(struct ath_hw *ah); /* * These functions are used by ath9k_hw. */ diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 6f4188a32ff0..dbc8e1dabad1 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -312,7 +312,7 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) ar9003_mci_set_bt_version(ah, major, minor); break; case MCI_GPM_COEX_STATUS_QUERY: - ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL); + ar9003_mci_send_wlan_channels(ah); break; case MCI_GPM_COEX_BT_PROFILE_INFO: memcpy(&profile_info, -- GitLab From d02ca07e6fdf89ed6f453fe1c9229c71a0358886 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:19 +0530 Subject: [PATCH 1415/6849] ath9k_hw: remove MCI_STATE_NEED_FLUSH_BT_INFO Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 17 ----------------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 - 2 files changed, 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 3b44ebe3f750..9a761a1fe1bf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1245,23 +1245,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY; ar9003_mci_send_coex_bt_status_query(ah, true, query_type); break; - case MCI_STATE_NEED_FLUSH_BT_INFO: - /* - * btcoex_hw.mci.unhalt_bt_gpm means whether it's - * needed to send UNHALT message. It's set whenever - * there's a request to send HALT message. - * mci_halted_bt_gpm means whether HALT message is sent - * out successfully. - * - * Checking (mci_unhalt_bt_gpm == false) instead of - * checking (ah->mci_halted_bt_gpm == false) will make - * sure currently is in UNHALT-ed mode and BT can - * respond to status query. - */ - value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0; - if (p_data) - mci->need_flush_btinfo = (*p_data != 0) ? true : false; - break; case MCI_STATE_RECOVER_RX: ar9003_mci_prep_interface(ah); mci->query_bt = true; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 05f42a98aeac..a7c17e5b90d4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -203,7 +203,6 @@ enum mci_state_type { MCI_STATE_SEND_WLAN_COEX_VERSION, MCI_STATE_SEND_VERSION_QUERY, MCI_STATE_SEND_STATUS_QUERY, - MCI_STATE_NEED_FLUSH_BT_INFO, MCI_STATE_SET_CONCUR_TX_PRI, MCI_STATE_RECOVER_RX, MCI_STATE_NEED_FTP_STOMP, -- GitLab From b98ccec0a497a9f08d705f1a7d63d5690bb48e70 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:20 +0530 Subject: [PATCH 1416/6849] ath9k_hw: remove p_data argument from ar9003_mci_state As p_data is unuse, lets remove it from ar9003_mci_state. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 6 +-- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 2 +- drivers/net/wireless/ath/ath9k/gpio.c | 2 +- drivers/net/wireless/ath/ath9k/mci.c | 49 +++++++++------------ 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 9a761a1fe1bf..d6e90f5effd0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -321,7 +321,7 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && + if (ar9003_mci_state(ah, MCI_STATE_ENABLE) && (mci->bt_state != MCI_BT_SLEEP) && !mci->halted_bt_gpm) { ar9003_mci_send_coex_halt_bt_gpm(ah, true, true); @@ -484,7 +484,7 @@ static void ar9003_mci_sync_bt_state(struct ath_hw *ah) struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 cur_bt_state; - cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); + cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP); if (mci->bt_state != cur_bt_state) mci->bt_state = cur_bt_state; @@ -1164,7 +1164,7 @@ void ar9003_mci_cleanup(struct ath_hw *ah) } EXPORT_SYMBOL(ar9003_mci_cleanup); -u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) +u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 value = 0; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index a7c17e5b90d4..697a56c3599e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -253,7 +253,7 @@ enum mci_gpm_coex_opcode { bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, u32 *payload, u8 len, bool wait_done, bool check_bt); -u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); +u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, u16 len, u32 sched_addr); void ar9003_mci_cleanup(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 00ff5ab5a54f..26032cb59b8a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -202,7 +202,7 @@ static void ath_btcoex_period_timer(unsigned long data) btcoex->bt_wait_time += btcoex->btcoex_period; if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { - if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP, NULL) && + if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && (mci->num_pan || mci->num_other_acl)) ah->btcoex_hw.mci.stomp_ftp = (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index dbc8e1dabad1..61a68e856049 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -199,16 +199,16 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) switch (opcode) { case MCI_GPM_BT_CAL_REQ: - if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { - ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); + if (ar9003_mci_state(ah, MCI_STATE_BT) == MCI_BT_AWAKE) { + ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); } else { ath_dbg(common, MCI, "MCI State mismatch: %d\n", - ar9003_mci_state(ah, MCI_STATE_BT, NULL)); + ar9003_mci_state(ah, MCI_STATE_BT)); } break; case MCI_GPM_BT_CAL_DONE: - ar9003_mci_state(ah, MCI_STATE_BT, NULL); + ar9003_mci_state(ah, MCI_STATE_BT); break; case MCI_GPM_BT_CAL_GRANT: MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); @@ -304,7 +304,7 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) switch (opcode) { case MCI_GPM_COEX_VERSION_QUERY: - ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, NULL); + ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION); break; case MCI_GPM_COEX_VERSION_RESPONSE: major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); @@ -415,7 +415,7 @@ void ath_mci_intr(struct ath_softc *sc) ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); - if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { + if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) { ar9003_mci_get_next_gpm_offset(ah, true, NULL); return; } @@ -435,46 +435,41 @@ void ath_mci_intr(struct ath_softc *sc) NULL, 0, true, false); mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE; - ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE, NULL); + ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE); /* * always do this for recovery and 2G/5G toggling and LNA_TRANS */ - ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); + ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; - if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) { - if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != - MCI_BT_SLEEP) - ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, - NULL); - } + if ((ar9003_mci_state(ah, MCI_STATE_BT) == MCI_BT_SLEEP) && + (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != + MCI_BT_SLEEP)) + ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; - if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { - if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != - MCI_BT_AWAKE) - ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, - NULL); - } + if ((ar9003_mci_state(ah, MCI_STATE_BT) == MCI_BT_AWAKE) && + (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != + MCI_BT_AWAKE)) + ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP); } if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { - ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); + ar9003_mci_state(ah, MCI_STATE_RECOVER_RX); skip_gpm = true; } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; - offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET, - NULL); + offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { @@ -526,21 +521,21 @@ void ath_mci_intr(struct ath_softc *sc) if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { int value_dbm = ar9003_mci_state(ah, - MCI_STATE_CONT_RSSI_POWER, NULL); + MCI_STATE_CONT_RSSI_POWER); mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; - if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX, NULL)) + if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX)) ath_dbg(common, MCI, "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", ar9003_mci_state(ah, - MCI_STATE_CONT_PRIORITY, NULL), + MCI_STATE_CONT_PRIORITY), value_dbm); else ath_dbg(common, MCI, "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n", ar9003_mci_state(ah, - MCI_STATE_CONT_PRIORITY, NULL), + MCI_STATE_CONT_PRIORITY), value_dbm); } -- GitLab From 6d97be48e27603f99743fc0e94e57dce2edb9cbf Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:21 +0530 Subject: [PATCH 1417/6849] ath9k_hw: remove MCI_STATE_BT remove MCI_STATE_BT and use bt_state instead. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 3 --- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 - drivers/net/wireless/ath/ath9k/mci.c | 15 ++++++--------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index d6e90f5effd0..1508500e73be 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1200,9 +1200,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) case MCI_STATE_CONT_TXRX: value = MS(mci->cont_status, AR_MCI_CONT_TXRX); break; - case MCI_STATE_BT: - value = mci->bt_state; - break; case MCI_STATE_SET_BT_SLEEP: mci->bt_state = MCI_BT_SLEEP; break; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 697a56c3599e..0c02bd86597b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -189,7 +189,6 @@ enum mci_bt_state { /* Type of state query */ enum mci_state_type { MCI_STATE_ENABLE, - MCI_STATE_BT, MCI_STATE_SET_BT_SLEEP, MCI_STATE_SET_BT_AWAKE, MCI_STATE_SET_BT_CAL_START, diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 61a68e856049..156454892588 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -195,20 +195,16 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; switch (opcode) { case MCI_GPM_BT_CAL_REQ: - if (ar9003_mci_state(ah, MCI_STATE_BT) == MCI_BT_AWAKE) { + if (mci_hw->bt_state == MCI_BT_AWAKE) { ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - } else { - ath_dbg(common, MCI, "MCI State mismatch: %d\n", - ar9003_mci_state(ah, MCI_STATE_BT)); } - break; - case MCI_GPM_BT_CAL_DONE: - ar9003_mci_state(ah, MCI_STATE_BT); + ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); break; case MCI_GPM_BT_CAL_GRANT: MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); @@ -407,6 +403,7 @@ void ath_mci_intr(struct ath_softc *sc) struct ath_mci_coex *mci = &sc->mci_coex; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; u32 mci_int, mci_int_rxmsg; u32 offset, subtype, opcode; u32 *pgpm; @@ -446,7 +443,7 @@ void ath_mci_intr(struct ath_softc *sc) if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; - if ((ar9003_mci_state(ah, MCI_STATE_BT) == MCI_BT_SLEEP) && + if ((mci_hw->bt_state == MCI_BT_SLEEP) && (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != MCI_BT_SLEEP)) ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); @@ -455,7 +452,7 @@ void ath_mci_intr(struct ath_softc *sc) if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; - if ((ar9003_mci_state(ah, MCI_STATE_BT) == MCI_BT_AWAKE) && + if ((mci_hw->bt_state == MCI_BT_AWAKE) && (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != MCI_BT_AWAKE)) ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP); -- GitLab From 26e942b790eddc757b5be179ef67907e025ff87b Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:22 +0530 Subject: [PATCH 1418/6849] ath9k_hw: remove MCI_STATE_CONT_* state Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 9 --------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 3 --- drivers/net/wireless/ath/ath9k/mci.c | 22 ++++++++------------- drivers/net/wireless/ath/ath9k/reg.h | 4 ++-- 4 files changed, 10 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 1508500e73be..25f99ef48b20 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1191,15 +1191,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE; break; - case MCI_STATE_CONT_RSSI_POWER: - value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER); - break; - case MCI_STATE_CONT_PRIORITY: - value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY); - break; - case MCI_STATE_CONT_TXRX: - value = MS(mci->cont_status, AR_MCI_CONT_TXRX); - break; case MCI_STATE_SET_BT_SLEEP: mci->bt_state = MCI_BT_SLEEP; break; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 0c02bd86597b..98bfc62d6b9b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -195,9 +195,6 @@ enum mci_state_type { MCI_STATE_SET_BT_CAL, MCI_STATE_LAST_SCHD_MSG_OFFSET, MCI_STATE_REMOTE_SLEEP, - MCI_STATE_CONT_RSSI_POWER, - MCI_STATE_CONT_PRIORITY, - MCI_STATE_CONT_TXRX, MCI_STATE_RESET_REQ_WAKE, MCI_STATE_SEND_WLAN_COEX_VERSION, MCI_STATE_SEND_VERSION_QUERY, diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 156454892588..e83d7200f762 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -517,23 +517,17 @@ void ath_mci_intr(struct ath_softc *sc) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { - int value_dbm = ar9003_mci_state(ah, - MCI_STATE_CONT_RSSI_POWER); + int value_dbm = MS(mci_hw->cont_status, + AR_MCI_CONT_RSSI_POWER); mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; - if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX)) - ath_dbg(common, MCI, - "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", - ar9003_mci_state(ah, - MCI_STATE_CONT_PRIORITY), - value_dbm); - else - ath_dbg(common, MCI, - "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n", - ar9003_mci_state(ah, - MCI_STATE_CONT_PRIORITY), - value_dbm); + ath_dbg(common, MCI, + "MCI CONT_INFO: (%s) pri = %d pwr = %d dBm\n", + MS(mci_hw->cont_status, AR_MCI_CONT_TXRX) ? + "tx" : "rx", + MS(mci_hw->cont_status, AR_MCI_CONT_PRIORITY), + value_dbm); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 560d6effac7a..75acefbd4937 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -2098,8 +2098,8 @@ enum { #define AR_MCI_CONT_STATUS 0x1848 #define AR_MCI_CONT_RSSI_POWER 0x000000FF #define AR_MCI_CONT_RSSI_POWER_S 0 -#define AR_MCI_CONT_RRIORITY 0x0000FF00 -#define AR_MCI_CONT_RRIORITY_S 8 +#define AR_MCI_CONT_PRIORITY 0x0000FF00 +#define AR_MCI_CONT_PRIORITY_S 8 #define AR_MCI_CONT_TXRX 0x00010000 #define AR_MCI_CONT_TXRX_S 16 -- GitLab From 9330969b8fd1304fdcb7c1825f1528eea38d321c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Jun 2012 20:18:23 +0530 Subject: [PATCH 1419/6849] ath9k_hw: remove MCI_STATE_SET_BT_SLEEP Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 3 --- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 - drivers/net/wireless/ath/ath9k/mci.c | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 25f99ef48b20..cc2853ade8f8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1191,9 +1191,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE; break; - case MCI_STATE_SET_BT_SLEEP: - mci->bt_state = MCI_BT_SLEEP; - break; case MCI_STATE_SET_BT_AWAKE: mci->bt_state = MCI_BT_AWAKE; ar9003_mci_send_coex_version_query(ah, true); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 98bfc62d6b9b..d33b8e128855 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -189,7 +189,6 @@ enum mci_bt_state { /* Type of state query */ enum mci_state_type { MCI_STATE_ENABLE, - MCI_STATE_SET_BT_SLEEP, MCI_STATE_SET_BT_AWAKE, MCI_STATE_SET_BT_CAL_START, MCI_STATE_SET_BT_CAL, diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index e83d7200f762..7d34a504d617 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -455,7 +455,7 @@ void ath_mci_intr(struct ath_softc *sc) if ((mci_hw->bt_state == MCI_BT_AWAKE) && (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != MCI_BT_AWAKE)) - ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP); + mci_hw->bt_state = MCI_BT_SLEEP; } if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || -- GitLab From 04414e2aa516c7af6aa316562e046c5aca025e33 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Mon, 11 Jun 2012 17:59:55 +0300 Subject: [PATCH 1420/6849] wlcore: avoid using NET_IP_ALIGN for RX alignment NET_IP_ALIGN can be overriden on different architectures and therefore cannot be used in the RX path to account for the 2 bytes added for alignment (either by the FW in the case of 18xx or by the host for 12xx). Instead use an internal define. Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/rx.c | 4 ++-- drivers/net/wireless/ti/wlcore/rx.h | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index 78200dcacfca..a1db4e032409 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -127,7 +127,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, } if (rx_align == WLCORE_RX_BUF_UNALIGNED) - reserved = NET_IP_ALIGN; + reserved = RX_BUF_ALIGN; /* the data read starts with the descriptor */ desc = (struct wl1271_rx_descriptor *) data; @@ -175,7 +175,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, */ memcpy(buf, data + sizeof(*desc), pkt_data_len); if (rx_align == WLCORE_RX_BUF_PADDED) - skb_pull(skb, NET_IP_ALIGN); + skb_pull(skb, RX_BUF_ALIGN); *hlid = desc->hlid; diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h index 9be780179456..4324a427e835 100644 --- a/drivers/net/wireless/ti/wlcore/rx.h +++ b/drivers/net/wireless/ti/wlcore/rx.h @@ -103,6 +103,12 @@ /* If set, the buffer was padded by the FW to be 4 bytes aligned */ #define RX_BUF_PADDED_PAYLOAD BIT(30) +/* + * Account for the padding inserted by the FW in case of RX_ALIGNMENT + * or for fixing alignment in case the packet wasn't aligned. + */ +#define RX_BUF_ALIGN 2 + /* Describes the alignment state of a Rx buffer */ enum wl_rx_buf_align { WLCORE_RX_BUF_ALIGNED, -- GitLab From 8f1a8684a56b3640510c0610b5635f5a4fe366fd Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 12 Jun 2012 12:39:55 +0300 Subject: [PATCH 1421/6849] wlcore: send EAPOLs with basic rate policy EAPOLs are sent at high rates as they are considered data packets. Some APs like Motorola Symbol AP7131 and AP650 don't respond well to these rates and don't respond with EAPOL 3/4 consistently. When sending EAPOL 2/4 at 54Mbps we've seen approx 30% success rate in getting EAPOL 3/4 response while using 11Mbps we got 100% success. To increase the chances of successful 4-Way handshake with such APs, send EAPOLs with basic rate policy in order to avoid high rates. Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/tx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 6983e7a829d0..8ee82b9f93f4 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -305,11 +305,15 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (is_dummy || !wlvif) rate_idx = 0; else if (wlvif->bss_type != BSS_TYPE_AP_BSS) { - /* if the packets are destined for AP (have a STA entry) - send them with AP rate policies, otherwise use default - basic rates */ + /* + * if the packets are destined for AP (have a STA entry) + * send them with AP rate policies (EAPOLs are an exception), + * otherwise use default basic rates + */ if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE) rate_idx = wlvif->sta.p2p_rate_idx; + else if (skb->protocol == cpu_to_be16(ETH_P_PAE)) + rate_idx = wlvif->sta.basic_rate_idx; else if (control->control.sta) rate_idx = wlvif->sta.ap_rate_idx; else -- GitLab From 2812eef151de189567f421c2cb1397b58334d9bd Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 12 Jun 2012 12:45:27 +0300 Subject: [PATCH 1422/6849] wlcore: update basic rates on channel switch On channel switch we have to update the basic rates, in order to reflect possible band changes (otherwise, we might start beaconing on 11a with the default rates of 11g). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 1156e3f578c1..21e05476cd35 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2454,6 +2454,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, wlvif->channel_type = conf->channel_type; if (is_ap) { + wl1271_set_band_rate(wl, wlvif); ret = wl1271_init_ap_rates(wl, wlvif); if (ret < 0) wl1271_error("AP rate policy change failed %d", -- GitLab From 05f48d45747e422dba0baaaf96ae2ea103791bce Mon Sep 17 00:00:00 2001 From: Yair Shapira Date: Wed, 13 Jun 2012 17:14:21 +0300 Subject: [PATCH 1423/6849] wlcore/wl12xx: add support for HP and SKW FEM radio manufacturers Add support for HP (High Performance TQS fem type 3) and SKW (fem type 2). This is done by increasing the number of FEM manufacturers to 4. Usually FEM parameters from ini file are read from nvs file and passed to firmware using TEST_CMD_INI_FILE_RADIO_PARAM. Still, because the nvs file has only place for 2 FEMs, we need to pass the new FEM types information in one of the available entries. This is done by mapping new fem types 2,3 to entry 0. This solution works for manual FEM selection. AutoDetect-FEM still support only fem types 0 and 1. Signed-off-by: Yair Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/cmd.c | 16 ++++++++++------ drivers/net/wireless/ti/wlcore/ini.h | 22 +++++++++++++++++----- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c index 50ba7480b790..30be784a40d8 100644 --- a/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/drivers/net/wireless/ti/wl12xx/cmd.c @@ -174,7 +174,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs; struct wl1271_radio_parms_cmd *radio_parms; struct wl1271_ini_general_params *gp = &nvs->general_params; - int ret; + int ret, fem_idx; if (!wl->nvs) return -ENODEV; @@ -185,11 +185,13 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; + fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer); + /* 2.4GHz parameters */ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, sizeof(struct wl1271_ini_band_params_2)); memcpy(&radio_parms->dyn_params_2, - &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, + &nvs->dyn_radio_params_2[fem_idx].params, sizeof(struct wl1271_ini_fem_params_2)); /* 5GHz parameters */ @@ -197,7 +199,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) &nvs->stat_radio_params_5, sizeof(struct wl1271_ini_band_params_5)); memcpy(&radio_parms->dyn_params_5, - &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, + &nvs->dyn_radio_params_5[fem_idx].params, sizeof(struct wl1271_ini_fem_params_5)); wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", @@ -216,7 +218,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs; struct wl128x_radio_parms_cmd *radio_parms; struct wl128x_ini_general_params *gp = &nvs->general_params; - int ret; + int ret, fem_idx; if (!wl->nvs) return -ENODEV; @@ -227,11 +229,13 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; + fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer); + /* 2.4GHz parameters */ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, sizeof(struct wl128x_ini_band_params_2)); memcpy(&radio_parms->dyn_params_2, - &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, + &nvs->dyn_radio_params_2[fem_idx].params, sizeof(struct wl128x_ini_fem_params_2)); /* 5GHz parameters */ @@ -239,7 +243,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) &nvs->stat_radio_params_5, sizeof(struct wl128x_ini_band_params_5)); memcpy(&radio_parms->dyn_params_5, - &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, + &nvs->dyn_radio_params_5[fem_idx].params, sizeof(struct wl128x_ini_fem_params_5)); radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options; diff --git a/drivers/net/wireless/ti/wlcore/ini.h b/drivers/net/wireless/ti/wlcore/ini.h index 4cf9ecc56212..d24fe3bbc672 100644 --- a/drivers/net/wireless/ti/wlcore/ini.h +++ b/drivers/net/wireless/ti/wlcore/ini.h @@ -172,7 +172,19 @@ struct wl128x_ini_fem_params_5 { /* NVS data structure */ #define WL1271_INI_NVS_SECTION_SIZE 468 -#define WL1271_INI_FEM_MODULE_COUNT 2 + +/* We have four FEM module types: 0-RFMD, 1-TQS, 2-SKW, 3-TQS_HP */ +#define WL1271_INI_FEM_MODULE_COUNT 4 + +/* + * In NVS we only store two FEM module entries - + * FEM modules 0,2,3 are stored in entry 0 + * FEM module 1 is stored in entry 1 + */ +#define WL12XX_NVS_FEM_MODULE_COUNT 2 + +#define WL12XX_FEM_TO_NVS_ENTRY(ini_fem_module) \ + ((ini_fem_module) == 1 ? 1 : 0) #define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 @@ -188,13 +200,13 @@ struct wl1271_nvs_file { struct { struct wl1271_ini_fem_params_2 params; u8 padding; - } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; + } dyn_radio_params_2[WL12XX_NVS_FEM_MODULE_COUNT]; struct wl1271_ini_band_params_5 stat_radio_params_5; u8 padding3; struct { struct wl1271_ini_fem_params_5 params; u8 padding; - } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; + } dyn_radio_params_5[WL12XX_NVS_FEM_MODULE_COUNT]; } __packed; struct wl128x_nvs_file { @@ -209,12 +221,12 @@ struct wl128x_nvs_file { struct { struct wl128x_ini_fem_params_2 params; u8 padding; - } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; + } dyn_radio_params_2[WL12XX_NVS_FEM_MODULE_COUNT]; struct wl128x_ini_band_params_5 stat_radio_params_5; u8 padding3; struct { struct wl128x_ini_fem_params_5 params; u8 padding; - } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; + } dyn_radio_params_5[WL12XX_NVS_FEM_MODULE_COUNT]; } __packed; #endif -- GitLab From b0b09e312ad36993a9ae51993b73448c1e38fc14 Mon Sep 17 00:00:00 2001 From: Yair Shapira Date: Wed, 13 Jun 2012 17:14:22 +0300 Subject: [PATCH 1424/6849] wlcore: add print logs of radio_status in case of BIP calibration FEM BIP calibration may fail with fw/phy radio status. In order to recognize these failures a log is added to the calibration answer (TEST_CMD_P2G_CAL) Signed-off-by: Yair Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.h | 21 +++++++++++++++++++++ drivers/net/wireless/ti/wlcore/testmode.c | 14 ++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index 85171f2bf68e..c8a6510c72cb 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h @@ -652,4 +652,25 @@ struct wl12xx_cmd_stop_channel_switch { struct wl1271_cmd_header header; } __packed; +/* Used to check radio status after calibration */ +#define MAX_TLV_LENGTH 500 +#define TEST_CMD_P2G_CAL 2 /* TX BiP */ + +struct wl1271_cmd_cal_p2g { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + __le32 ver; + __le16 len; + u8 buf[MAX_TLV_LENGTH]; + u8 type; + u8 padding; + + __le16 radio_status; + + u8 sub_band_mask; + u8 padding2; +} __packed; + #endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c index 0e59ea2cdd39..eeb339d61d1e 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.c +++ b/drivers/net/wireless/ti/wlcore/testmode.c @@ -108,6 +108,20 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) } if (answer) { + /* If we got bip calibration answer print radio status */ + struct wl1271_cmd_cal_p2g *params = + (struct wl1271_cmd_cal_p2g *) buf; + + s16 radio_status = (s16) le16_to_cpu(params->radio_status); + + if (params->test.id == TEST_CMD_P2G_CAL && + radio_status < 0) + wl1271_warning("testmode cmd: radio status=%d", + radio_status); + else + wl1271_info("testmode cmd: radio status=%d", + radio_status); + len = nla_total_size(buf_len); skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); if (!skb) { -- GitLab From bcab320ba20edf166d82d42928401a0afe61e0c5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 13 Jun 2012 20:29:16 +0300 Subject: [PATCH 1425/6849] wlcore: declare interface combinations Advertise to the stack that the wlcore driver supports multiple interfaces for a single device. This is required in order to be able to run multirole with mac80211. Signed-off-by: Eliad Peller Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 21e05476cd35..8eefcd7505e2 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4977,6 +4977,29 @@ static void wl1271_unregister_hw(struct wl1271 *wl) } +static const struct ieee80211_iface_limit wlcore_iface_limits[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT), + }, +}; + +static const struct ieee80211_iface_combination +wlcore_iface_combinations[] = { + { + .num_different_channels = 1, + .max_interfaces = 2, + .limits = wlcore_iface_limits, + .n_limits = ARRAY_SIZE(wlcore_iface_limits), + }, +}; + static int wl1271_init_ieee80211(struct wl1271 *wl) { static const u32 cipher_suites[] = { @@ -5070,6 +5093,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; + /* allowed interface combinations */ + wl->hw->wiphy->iface_combinations = wlcore_iface_combinations; + wl->hw->wiphy->n_iface_combinations = + ARRAY_SIZE(wlcore_iface_combinations); + SET_IEEE80211_DEV(wl->hw, wl->dev); wl->hw->sta_data_size = sizeof(struct wl1271_station); -- GitLab From 047fe3605235888f3ebcda0c728cb31937eadfe6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Jun 2012 15:24:40 +0200 Subject: [PATCH 1426/6849] splice: fix racy pipe->buffers uses Dave Jones reported a kernel BUG at mm/slub.c:3474! triggered by splice_shrink_spd() called from vmsplice_to_pipe() commit 35f3d14dbbc5 (pipe: add support for shrinking and growing pipes) added capability to adjust pipe->buffers. Problem is some paths don't hold pipe mutex and assume pipe->buffers doesn't change for their duration. Fix this by adding nr_pages_max field in struct splice_pipe_desc, and use it in place of pipe->buffers where appropriate. splice_shrink_spd() loses its struct pipe_inode_info argument. Reported-by: Dave Jones Signed-off-by: Eric Dumazet Cc: Jens Axboe Cc: Alexander Viro Cc: Tom Herbert Cc: stable # 2.6.35 Tested-by: Dave Jones Signed-off-by: Jens Axboe --- fs/splice.c | 35 ++++++++++++++++++++--------------- include/linux/splice.h | 8 ++++---- kernel/relay.c | 5 +++-- kernel/trace/trace.c | 6 ++++-- mm/shmem.c | 3 ++- net/core/skbuff.c | 1 + 6 files changed, 34 insertions(+), 24 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index c9f1318a3b82..7bf08fa22ec9 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -273,13 +273,16 @@ void spd_release_page(struct splice_pipe_desc *spd, unsigned int i) * Check if we need to grow the arrays holding pages and partial page * descriptions. */ -int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) +int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) { - if (pipe->buffers <= PIPE_DEF_BUFFERS) + unsigned int buffers = ACCESS_ONCE(pipe->buffers); + + spd->nr_pages_max = buffers; + if (buffers <= PIPE_DEF_BUFFERS) return 0; - spd->pages = kmalloc(pipe->buffers * sizeof(struct page *), GFP_KERNEL); - spd->partial = kmalloc(pipe->buffers * sizeof(struct partial_page), GFP_KERNEL); + spd->pages = kmalloc(buffers * sizeof(struct page *), GFP_KERNEL); + spd->partial = kmalloc(buffers * sizeof(struct partial_page), GFP_KERNEL); if (spd->pages && spd->partial) return 0; @@ -289,10 +292,9 @@ int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) return -ENOMEM; } -void splice_shrink_spd(struct pipe_inode_info *pipe, - struct splice_pipe_desc *spd) +void splice_shrink_spd(struct splice_pipe_desc *spd) { - if (pipe->buffers <= PIPE_DEF_BUFFERS) + if (spd->nr_pages_max <= PIPE_DEF_BUFFERS) return; kfree(spd->pages); @@ -315,6 +317,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, + .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &page_cache_pipe_buf_ops, .spd_release = spd_release_page, @@ -326,7 +329,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, index = *ppos >> PAGE_CACHE_SHIFT; loff = *ppos & ~PAGE_CACHE_MASK; req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - nr_pages = min(req_pages, pipe->buffers); + nr_pages = min(req_pages, spd.nr_pages_max); /* * Lookup the (hopefully) full range of pages we need. @@ -497,7 +500,7 @@ fill_it: if (spd.nr_pages) error = splice_to_pipe(pipe, &spd); - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); return error; } @@ -598,6 +601,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, + .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &default_pipe_buf_ops, .spd_release = spd_release_page, @@ -608,8 +612,8 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, res = -ENOMEM; vec = __vec; - if (pipe->buffers > PIPE_DEF_BUFFERS) { - vec = kmalloc(pipe->buffers * sizeof(struct iovec), GFP_KERNEL); + if (spd.nr_pages_max > PIPE_DEF_BUFFERS) { + vec = kmalloc(spd.nr_pages_max * sizeof(struct iovec), GFP_KERNEL); if (!vec) goto shrink_ret; } @@ -617,7 +621,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, offset = *ppos & ~PAGE_CACHE_MASK; nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - for (i = 0; i < nr_pages && i < pipe->buffers && len; i++) { + for (i = 0; i < nr_pages && i < spd.nr_pages_max && len; i++) { struct page *page; page = alloc_page(GFP_USER); @@ -665,7 +669,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, shrink_ret: if (vec != __vec) kfree(vec); - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); return res; err: @@ -1614,6 +1618,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, + .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &user_page_pipe_buf_ops, .spd_release = spd_release_page, @@ -1629,13 +1634,13 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages, spd.partial, false, - pipe->buffers); + spd.nr_pages_max); if (spd.nr_pages <= 0) ret = spd.nr_pages; else ret = splice_to_pipe(pipe, &spd); - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); return ret; } diff --git a/include/linux/splice.h b/include/linux/splice.h index 26e5b613deda..09a545a7dfa3 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -51,7 +51,8 @@ struct partial_page { struct splice_pipe_desc { struct page **pages; /* page map */ struct partial_page *partial; /* pages[] may not be contig */ - int nr_pages; /* number of pages in map */ + int nr_pages; /* number of populated pages in map */ + unsigned int nr_pages_max; /* pages[] & partial[] arrays size */ unsigned int flags; /* splice flags */ const struct pipe_buf_operations *ops;/* ops associated with output pipe */ void (*spd_release)(struct splice_pipe_desc *, unsigned int); @@ -85,9 +86,8 @@ extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, /* * for dynamic pipe sizing */ -extern int splice_grow_spd(struct pipe_inode_info *, struct splice_pipe_desc *); -extern void splice_shrink_spd(struct pipe_inode_info *, - struct splice_pipe_desc *); +extern int splice_grow_spd(const struct pipe_inode_info *, struct splice_pipe_desc *); +extern void splice_shrink_spd(struct splice_pipe_desc *); extern void spd_release_page(struct splice_pipe_desc *, unsigned int); extern const struct pipe_buf_operations page_cache_pipe_buf_ops; diff --git a/kernel/relay.c b/kernel/relay.c index ab56a1764d4d..e8cd2027abbd 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1235,6 +1235,7 @@ static ssize_t subbuf_splice_actor(struct file *in, struct splice_pipe_desc spd = { .pages = pages, .nr_pages = 0, + .nr_pages_max = PIPE_DEF_BUFFERS, .partial = partial, .flags = flags, .ops = &relay_pipe_buf_ops, @@ -1302,8 +1303,8 @@ static ssize_t subbuf_splice_actor(struct file *in, ret += padding; out: - splice_shrink_spd(pipe, &spd); - return ret; + splice_shrink_spd(&spd); + return ret; } static ssize_t relay_file_splice_read(struct file *in, diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 68032c6177db..288488082224 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3609,6 +3609,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, .pages = pages_def, .partial = partial_def, .nr_pages = 0, /* This gets updated below. */ + .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &tracing_pipe_buf_ops, .spd_release = tracing_spd_release_pipe, @@ -3680,7 +3681,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, ret = splice_to_pipe(pipe, &spd); out: - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); return ret; out_err: @@ -4231,6 +4232,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages_def, .partial = partial_def, + .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &buffer_pipe_buf_ops, .spd_release = buffer_spd_release, @@ -4318,7 +4320,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, } ret = splice_to_pipe(pipe, &spd); - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); out: return ret; } diff --git a/mm/shmem.c b/mm/shmem.c index 585bd220a21e..c244e93a70fa 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1577,6 +1577,7 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, + .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &page_cache_pipe_buf_ops, .spd_release = spd_release_page, @@ -1665,7 +1666,7 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, if (spd.nr_pages) error = splice_to_pipe(pipe, &spd); - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); if (error > 0) { *ppos += error; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 016694d62484..bac3c5756d63 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1755,6 +1755,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, + .nr_pages_max = MAX_SKB_FRAGS, .flags = flags, .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, -- GitLab From 32587371ad3db2f9d335de10dbd8cffd4fff5669 Mon Sep 17 00:00:00 2001 From: Tao Guo Date: Wed, 13 Jun 2012 21:17:21 +0200 Subject: [PATCH 1427/6849] umem: fix up unplugging Fix a regression introduced by 7eaceaccab5f40 ("block: remove per-queue plugging"). In that patch, Jens removed the whole mm_unplug_device() function, which used to be the trigger to make umem start to work. We need to implement unplugging to make umem start to work, or I/O will never be triggered. Signed-off-by: Tao Guo Cc: Neil Brown Cc: Jens Axboe Cc: Shaohua Li Cc: Acked-by: NeilBrown Signed-off-by: Jens Axboe --- drivers/block/umem.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/block/umem.c b/drivers/block/umem.c index aa2712060bfb..9a72277a31df 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -513,6 +513,44 @@ static void process_page(unsigned long data) } } +struct mm_plug_cb { + struct blk_plug_cb cb; + struct cardinfo *card; +}; + +static void mm_unplug(struct blk_plug_cb *cb) +{ + struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); + + spin_lock_irq(&mmcb->card->lock); + activate(mmcb->card); + spin_unlock_irq(&mmcb->card->lock); + kfree(mmcb); +} + +static int mm_check_plugged(struct cardinfo *card) +{ + struct blk_plug *plug = current->plug; + struct mm_plug_cb *mmcb; + + if (!plug) + return 0; + + list_for_each_entry(mmcb, &plug->cb_list, cb.list) { + if (mmcb->cb.callback == mm_unplug && mmcb->card == card) + return 1; + } + /* Not currently on the callback list */ + mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC); + if (!mmcb) + return 0; + + mmcb->card = card; + mmcb->cb.callback = mm_unplug; + list_add(&mmcb->cb.list, &plug->cb_list); + return 1; +} + static void mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; @@ -523,6 +561,8 @@ static void mm_make_request(struct request_queue *q, struct bio *bio) *card->biotail = bio; bio->bi_next = NULL; card->biotail = &bio->bi_next; + if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card)) + activate(card); spin_unlock_irq(&card->lock); return; -- GitLab From f922ffc0b52f8ee9e7503e769fa6931cb51635ab Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 13 Jun 2012 20:44:34 +0200 Subject: [PATCH 1428/6849] staging bcm: spelling of suppress in comments Signed-off-by: Peter Meerwald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/PHSModule.c | 10 +++++----- drivers/staging/bcm/cntrl_SignalingInterface.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index a6e61510d278..c0862c6c21a0 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -54,8 +54,8 @@ Function: PHSTransmit Description: This routine handle PHS(Payload Header Suppression for Tx path. It extracts a fragment of the NDIS_PACKET containing the header - to be suppressed.It then supresses the header by invoking PHS exported compress routine. - The header data after supression is copied back to the NDIS_PACKET. + to be suppressed. It then suppresses the header by invoking PHS exported compress routine. + The header data after suppression is copied back to the NDIS_PACKET. Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context @@ -101,7 +101,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, if(!bEthCSSupport) BytesToRemove=ETH_HLEN; /* - Accumulate the header upto the size we support supression + Accumulate the header upto the size we support suppression from NDIS packet */ @@ -125,7 +125,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, { - // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. + // Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. // Suppress only if IP Header and PHS Enabled For the Service Flow if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) || (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && @@ -238,7 +238,7 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, &nTotalsupressedPktHdrBytes, &nStandardPktHdrLen); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", nTotalsupressedPktHdrBytes,nStandardPktHdrLen); if(ulPhsStatus != STATUS_PHS_COMPRESSED) diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index ab131806e2c9..7619e4b819bd 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -117,7 +117,7 @@ typedef struct _stPhsRuleSI { B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; /** 8bit Total number of bytes to be suppressed for the Service Flow*/ B_UINT8 u8PHSS; - /** 8bit Indicates whether or not Packet Header contents need to be verified prior to supression */ + /** 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ B_UINT8 u8PHSV; /** Vendor Specific PHS param Length Of The Service Flow*/ B_UINT8 u8VendorSpecificPHSParamsLength; -- GitLab From b38e274fdb6dfa2dd77598b8b6e2c32d7608f494 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 13 Jun 2012 20:44:35 +0200 Subject: [PATCH 1429/6849] staging bcm: spelling of suppress in code Signed-off-by: Peter Meerwald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 8 ++++---- drivers/staging/bcm/PHSModule.c | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 11d2c5a84552..4d490a99110c 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -54,9 +54,9 @@ typedef union _U_IP_ADDRESS { }; } U_IP_ADDRESS; -struct bcm_hdr_supression_contextinfo { - UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; /* Intermediate buffer to accumulate pkt Header for PHS */ - UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; /* Intermediate buffer containing pkt Header after PHS */ +struct bcm_hdr_suppression_contextinfo { + UCHAR ucaHdrSuppressionInBuf[MAX_PHS_LENGTHS]; /* Intermediate buffer to accumulate pkt Header for PHS */ + UCHAR ucaHdrSuppressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; /* Intermediate buffer containing pkt Header after PHS */ }; struct bcm_classifier_rule { @@ -334,7 +334,7 @@ struct bcm_mini_adapter { BOOLEAN bLinkDownRequested; int downloadDDR; PHS_DEVICE_EXTENSION stBCMPhsContext; - struct bcm_hdr_supression_contextinfo stPhsTxContextInfo; + struct bcm_hdr_suppression_contextinfo stPhsTxContextInfo; uint8_t ucaPHSPktRestoreBuf[2048]; uint8_t bPHSEnabled; BOOLEAN AutoFirmDld; diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index c0862c6c21a0..479574234e4c 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -84,10 +84,10 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, UINT unPHSNewPktHeaderLen = 0; /* Pointer to PHS IN Hdr Buffer */ PUCHAR pucPHSPktHdrInBuf = - Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf; + Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf; /* Pointer to PHS OUT Hdr Buffer */ PUCHAR pucPHSPktHdrOutBuf = - Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf; + Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; UINT usPacketType; UINT BytesToRemove=0; BOOLEAN bPHSI = 0; @@ -217,7 +217,7 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, UINT bHeaderSuppressionEnabled) { u32 nStandardPktHdrLen = 0; - u32 nTotalsupressedPktHdrBytes = 0; + u32 nTotalsuppressedPktHdrBytes = 0; int ulPhsStatus = 0; PUCHAR pucInBuff = NULL ; UINT TotalBytesAdded = 0; @@ -235,11 +235,11 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, usVcid, pucInBuff, Adapter->ucaPHSPktRestoreBuf, - &nTotalsupressedPktHdrBytes, + &nTotalsuppressedPktHdrBytes, &nStandardPktHdrLen); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", - nTotalsupressedPktHdrBytes,nStandardPktHdrLen); + nTotalsuppressedPktHdrBytes,nStandardPktHdrLen); if(ulPhsStatus != STATUS_PHS_COMPRESSED) { @@ -248,7 +248,7 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, } else { - TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN; + TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN; if(TotalBytesAdded) { if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) @@ -1494,7 +1494,7 @@ static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) { unsigned char *old_addr = out_buf; - int supress = 0; + int suppress = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); if(phs_rule == NULL) { @@ -1514,10 +1514,10 @@ static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf } //To copy PHSI out_buf++; - supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF, + suppress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF, phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size); - if(supress == STATUS_PHS_COMPRESSED) + if(suppress == STATUS_PHS_COMPRESSED) { *old_addr = (unsigned char)phs_rule->u8PHSI; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI); @@ -1527,7 +1527,7 @@ static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf *old_addr = ZERO_PHSI; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed"); } - return supress; + return suppress; } -- GitLab From a2c49a9ac993fa2b4795890d5fa56f2fc002453e Mon Sep 17 00:00:00 2001 From: William Blair Date: Wed, 13 Jun 2012 01:16:49 -0400 Subject: [PATCH 1430/6849] Staging: keucr: scsiglue: fixed a do while coding style issue Added a do ... while (0) to a multi statement macro and reformatted a similar macro. Signed-off-by: William Blair Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/scsiglue.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/staging/keucr/scsiglue.c b/drivers/staging/keucr/scsiglue.c index e1f3931d41e0..083b20e6253e 100644 --- a/drivers/staging/keucr/scsiglue.c +++ b/drivers/staging/keucr/scsiglue.c @@ -230,7 +230,10 @@ void usb_stor_report_bus_reset(struct us_data *us) /* we use this macro to help us write into the buffer */ #undef SPRINTF #define SPRINTF(args...) \ - do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) + do { \ + if (pos < buffer+length) \ + pos += sprintf(pos, ## args); \ + } while (0) /* * proc_info() @@ -279,8 +282,10 @@ static int proc_info(struct Scsi_Host *host, char *buffer, char **start, pos += sprintf(pos, " Quirks:"); #define US_FLAG(name, value) \ - if (us->fflags & value)\ - pos += sprintf(pos, " " #name); + do { \ + if (us->fflags & value) \ + pos += sprintf(pos, " " #name); \ + } while (0); US_DO_ALL_FLAGS #undef US_FLAG -- GitLab From e888fabd10cdd46a4b46bcc029c5c6d2364dab7f Mon Sep 17 00:00:00 2001 From: Chris Yungmann Date: Wed, 13 Jun 2012 12:39:55 -0400 Subject: [PATCH 1431/6849] staging: speakup: fixed checkpatch and sparse warnings in selection.c Signed-off-by: Chris Yungmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/selection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index fe1f405d5d70..0612df06a4bf 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c @@ -68,7 +68,7 @@ int speakup_set_selection(struct tty_struct *tty) if (spk_sel_cons != vc_cons[fg_console].d) { speakup_clear_selection(); spk_sel_cons = vc_cons[fg_console].d; - printk(KERN_WARNING + dev_warn(tty->dev, "Selection: mark console not the same as cut\n"); return -EINVAL; } @@ -95,7 +95,7 @@ int speakup_set_selection(struct tty_struct *tty) /* Allocate a new buffer before freeing the old one ... */ bp = kmalloc((sel_end-sel_start)/2+1, GFP_ATOMIC); if (!bp) { - printk(KERN_WARNING "selection: kmalloc() failed\n"); + dev_warn(tty->dev, "selection: kmalloc() failed\n"); speakup_clear_selection(); return -ENOMEM; } @@ -141,7 +141,7 @@ int speakup_paste_selection(struct tty_struct *tty) count = sel_buffer_lth - pasted; count = min_t(int, count, tty->receive_room); tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, - 0, count); + NULL, count); pasted += count; } remove_wait_queue(&vc->paste_wait, &wait); -- GitLab From 4829a9967dbe3a3ab192df0bfdde281960cc1319 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Jun 2012 17:37:10 -0700 Subject: [PATCH 1432/6849] staging: comedi: Kconfig: cleanup depends on logic All of the config options for comedi depend on COMEDI being selected. Wrap everything in an 'if COMEDI/endif' block and remove all the individual 'depends on COMEDI' in the Kconfig. Also, remove the redundant && ISA/PCI/PCMCIA/USB for the if blocks with those driver types. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 54e32da55c7c..848cf7e3e8fd 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -6,9 +6,10 @@ config COMEDI Enable support a wide range of data acquisition devices for Linux. +if COMEDI + config COMEDI_DEBUG bool "Comedi debugging" - depends on COMEDI != n ---help--- This is an option for use by developers; most people should say N here. This enables comedi core and driver debugging. @@ -16,7 +17,6 @@ config COMEDI_DEBUG config COMEDI_DEFAULT_BUF_SIZE_KB int "Comedi default initial asynchronous buffer size in KiB" default "2048" - depends on COMEDI != n ---help--- This is the default asynchronous buffer size which is used for commands running in the background in kernel space. This @@ -26,7 +26,6 @@ config COMEDI_DEFAULT_BUF_SIZE_KB config COMEDI_DEFAULT_BUF_MAXSIZE_KB int "Comedi default maximum asynchronous buffer size in KiB" default "20480" - depends on COMEDI != n ---help--- This is the default maximum asynchronous buffer size which can be requested by a userspace program without root privileges. @@ -35,7 +34,6 @@ config COMEDI_DEFAULT_BUF_MAXSIZE_KB menuconfig COMEDI_MISC_DRIVERS tristate "Comedi misc drivers" - depends on COMEDI ---help--- Enable comedi misc drivers to be built @@ -103,7 +101,7 @@ endif # COMEDI_MISC_DRIVERS menuconfig COMEDI_ISA_DRIVERS tristate "Comedi ISA and PC/104 drivers" - depends on COMEDI && ISA + depends on ISA ---help--- Enable comedi ISA and PC/104 drivers to be built @@ -111,7 +109,7 @@ menuconfig COMEDI_ISA_DRIVERS kernel: saying N will just cause the configurator to skip all the questions about ISA and PC/104 comedi drivers. -if COMEDI_ISA_DRIVERS && ISA +if COMEDI_ISA_DRIVERS config COMEDI_ACL7225B tristate "ADlink NuDAQ ACL-7225b and compatibles support" @@ -543,7 +541,7 @@ endif # COMEDI_ISA_DRIVERS menuconfig COMEDI_PCI_DRIVERS tristate "Comedi PCI drivers" - depends on COMEDI && PCI + depends on PCI ---help--- Enable comedi PCI drivers to be built @@ -551,7 +549,7 @@ menuconfig COMEDI_PCI_DRIVERS kernel: saying N will just cause the configurator to skip all the questions about PCI comedi drivers. -if COMEDI_PCI_DRIVERS && PCI +if COMEDI_PCI_DRIVERS config COMEDI_ADDI_APCI_035 tristate "ADDI-DATA APCI_035 support" @@ -1099,7 +1097,7 @@ endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS tristate "Comedi PCMCIA drivers" - depends on COMEDI && (PCMCIA || PCCARD) + depends on (PCMCIA || PCCARD) ---help--- Enable comedi PCMCIA and PCCARD drivers to be built @@ -1107,7 +1105,7 @@ menuconfig COMEDI_PCMCIA_DRIVERS kernel: saying N will just cause the configurator to skip all the questions about PCMCIA comedi drivers. -if COMEDI_PCMCIA_DRIVERS && PCMCIA +if COMEDI_PCMCIA_DRIVERS config COMEDI_CB_DAS16_CS tristate "CB DAS16 series PCMCIA support" @@ -1182,7 +1180,7 @@ endif # COMEDI_PCMCIA_DRIVERS menuconfig COMEDI_USB_DRIVERS tristate "Comedi USB drivers" - depends on COMEDI && USB + depends on USB ---help--- Enable comedi USB drivers to be built @@ -1190,7 +1188,7 @@ menuconfig COMEDI_USB_DRIVERS kernel: saying N will just cause the configurator to skip all the questions about USB comedi drivers. -if COMEDI_USB_DRIVERS && USB +if COMEDI_USB_DRIVERS config COMEDI_DT9812 tristate "DataTranslation DT9812 USB module support" @@ -1290,7 +1288,6 @@ endif # COMEDI_NI_COMMON config COMEDI_8255 tristate "Generic 8255 support" - depends on COMEDI ---help--- Enable generic 8255 support. @@ -1306,23 +1303,20 @@ config COMEDI_8255 config COMEDI_FC tristate - depends on COMEDI config COMEDI_AMPLC_DIO200 tristate - depends on COMEDI select COMEDI_8255 config COMEDI_AMPLC_PC236 tristate - depends on COMEDI select COMEDI_8255 config COMEDI_AMPLC_PC263 tristate - depends on COMEDI config COMEDI_DAS08 tristate - depends on COMEDI select COMEDI_8255 + +endif # COMEDI -- GitLab From 4527715979a34601b783f5f12774586c679c2a89 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 28 May 2012 23:31:39 -0700 Subject: [PATCH 1433/6849] usb: renesas_usbhs: add DMAEngine ID specification note renesas_usbhs DMAEngine uses D0FIFO/D1FIFO, but the data transfer direction should be fixed for keeping consistency. This patch explain about it on renesas_usbhs.h Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/renesas_usbhs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 547e59cc00ea..c5d36c65c33b 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -132,6 +132,14 @@ struct renesas_usbhs_driver_param { * option: * * dma id for dmaengine + * The data transfer direction on D0FIFO/D1FIFO should be + * fixed for keeping consistency. + * So, the platform id settings will be.. + * .d0_tx_id = xx_TX, + * .d1_rx_id = xx_RX, + * or + * .d1_tx_id = xx_TX, + * .d0_rx_id = xx_RX, */ int d0_tx_id; int d0_rx_id; -- GitLab From c2e935a7db6e7354e9dd138b7f6f4c53affc09d9 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Wed, 13 Jun 2012 20:34:12 +0800 Subject: [PATCH 1434/6849] USB: move transceiver from ehci_hcd and ohci_hcd to hcd and rename it as phy - to decrease redundant since both ehci_hcd and ohci_hcd have the same variable - it helps access phy in usb core code - phy is more meaningful than transceiver Signed-off-by: Richard Zhao Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 21 ++++++++++----------- drivers/usb/host/ehci-hub.c | 2 +- drivers/usb/host/ehci.h | 4 ---- drivers/usb/host/ohci-omap.c | 27 ++++++++++++++------------- drivers/usb/host/ohci.h | 5 ----- include/linux/usb/hcd.h | 6 ++++++ 6 files changed, 31 insertions(+), 34 deletions(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 43362577b54a..3379945b095e 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -142,19 +142,19 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, if (pdata->operating_mode == FSL_USB2_DR_OTG) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - ehci->transceiver = usb_get_transceiver(); - dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, transceiver=0x%p\n", - hcd, ehci, ehci->transceiver); + hcd->phy = usb_get_transceiver(); + dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, phy=0x%p\n", + hcd, ehci, hcd->phy); - if (ehci->transceiver) { - retval = otg_set_host(ehci->transceiver->otg, + if (hcd->phy) { + retval = otg_set_host(hcd->phy->otg, &ehci_to_hcd(ehci)->self); if (retval) { - usb_put_transceiver(ehci->transceiver); + usb_put_transceiver(hcd->phy); goto err4; } } else { - dev_err(&pdev->dev, "can't find transceiver\n"); + dev_err(&pdev->dev, "can't find phy\n"); retval = -ENODEV; goto err4; } @@ -190,11 +190,10 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - if (ehci->transceiver) { - otg_set_host(ehci->transceiver->otg, NULL); - usb_put_transceiver(ehci->transceiver); + if (hcd->phy) { + otg_set_host(hcd->phy->otg, NULL); + usb_put_transceiver(hcd->phy); } usb_remove_hcd(hcd); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index fc9e7cc6ac9b..dd5eef6af6df 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -724,7 +724,7 @@ static int ehci_hub_control ( #ifdef CONFIG_USB_OTG if ((hcd->self.otg_port == (wIndex + 1)) && hcd->self.b_hnp_enable) { - otg_start_hnp(ehci->transceiver->otg); + otg_start_hnp(hcd->phy->otg); break; } #endif diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2694ed6558d2..85c3572155d1 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -175,10 +175,6 @@ struct ehci_hcd { /* one per controller */ #ifdef DEBUG struct dentry *debug_dir; #endif - /* - * OTG controllers and transceivers need software interaction - */ - struct usb_phy *transceiver; }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 9ce35d0d9d5d..eccddb461396 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -167,14 +167,15 @@ static int omap_1510_local_bus_init(void) static void start_hnp(struct ohci_hcd *ohci) { - const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1; + struct usb_hcd *hcd = ohci_to_hcd(ohci); + const unsigned port = hcd->self.otg_port - 1; unsigned long flags; u32 l; - otg_start_hnp(ohci->transceiver->otg); + otg_start_hnp(hcd->phy->otg); local_irq_save(flags); - ohci->transceiver->state = OTG_STATE_A_SUSPEND; + hcd->phy->state = OTG_STATE_A_SUSPEND; writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); l = omap_readl(OTG_CTRL); l &= ~OTG_A_BUSREQ; @@ -211,18 +212,18 @@ static int ohci_omap_init(struct usb_hcd *hcd) #ifdef CONFIG_USB_OTG if (need_transceiver) { - ohci->transceiver = usb_get_transceiver(); - if (ohci->transceiver) { - int status = otg_set_host(ohci->transceiver->otg, + hcd->phy = usb_get_transceiver(); + if (hcd->phy) { + int status = otg_set_host(hcd->phy->otg, &ohci_to_hcd(ohci)->self); - dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", - ohci->transceiver->label, status); + dev_dbg(hcd->self.controller, "init %s phy, status %d\n", + hcd->phy->label, status); if (status) { - usb_put_transceiver(ohci->transceiver); + usb_put_transceiver(hcd->phy); return status; } } else { - dev_err(hcd->self.controller, "can't find transceiver\n"); + dev_err(hcd->self.controller, "can't find phy\n"); return -ENODEV; } ohci->start_hnp = start_hnp; @@ -403,9 +404,9 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) struct ohci_hcd *ohci = hcd_to_ohci (hcd); usb_remove_hcd(hcd); - if (ohci->transceiver) { - (void) otg_set_host(ohci->transceiver->otg, 0); - usb_put_transceiver(ohci->transceiver); + if (hcd->phy) { + (void) otg_set_host(hcd->phy->otg, 0); + usb_put_transceiver(hcd->phy); } if (machine_is_omap_osk()) gpio_free(9); diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 1b19aea25a2b..d3299143d9e2 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -372,11 +372,6 @@ struct ohci_hcd { struct ed *ed_controltail; /* last in ctrl list */ struct ed *periodic [NUM_INTS]; /* shadow int_table */ - /* - * OTG controllers and transceivers need software interaction; - * other external transceivers should be software-transparent - */ - struct usb_phy *transceiver; void (*start_hnp)(struct ohci_hcd *ohci); /* diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7f855d50cdf5..c532cbeabfbc 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -93,6 +93,12 @@ struct usb_hcd { */ const struct hc_driver *driver; /* hw-specific hooks */ + /* + * OTG and some Host controllers need software interaction with phys; + * other external phys should be software-transparent + */ + struct usb_phy *phy; + /* Flags that need to be manipulated atomically because they can * change while the host controller is running. Always use * set_bit() or clear_bit() to change their values. -- GitLab From f6a4e494e059b7f0e361dba28f0e2d13144da1d1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:09 +0300 Subject: [PATCH 1435/6849] mei: mei.txt: minor grammar fixes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- Documentation/misc-devices/mei/mei.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/misc-devices/mei/mei.txt b/Documentation/misc-devices/mei/mei.txt index 2785697da59d..6ec702950719 100644 --- a/Documentation/misc-devices/mei/mei.txt +++ b/Documentation/misc-devices/mei/mei.txt @@ -50,25 +50,25 @@ Intel MEI Driver The driver exposes a misc device called /dev/mei. An application maintains communication with an Intel ME feature while -/dev/mei is open. The binding to a specific features is performed by calling +/dev/mei is open. The binding to a specific feature is performed by calling MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID. The number of instances of an Intel ME feature that can be opened at the same time depends on the Intel ME feature, but most of the features allow only a single instance. The Intel AMT Host Interface (Intel AMTHI) feature supports multiple -simultaneous user applications. Therefore, the Intel MEI driver handles -this internally by maintaining request queues for the applications. +simultaneous user connected applications. The Intel MEI driver +handles this internally by maintaining request queues for the applications. -The driver is oblivious to data that is passed between firmware feature +The driver is transparent to data that are passed between firmware feature and host application. Because some of the Intel ME features can change the system configuration, the driver by default allows only a privileged user to access it. -A code snippet for an application communicating with -Intel AMTHI client: +A code snippet for an application communicating with Intel AMTHI client: + struct mei_connect_client_data data; fd = open(MEI_DEVICE); @@ -185,7 +185,7 @@ The Intel AMT Watchdog is composed of two parts: 2) Intel MEI driver - connects to the watchdog feature, configures the watchdog and sends the heartbeats. -The Intel MEI driver uses the kernel watchdog to configure the Intel AMT +The Intel MEI driver uses the kernel watchdog API to configure the Intel AMT Watchdog and to send heartbeats to it. The default timeout of the watchdog is 120 seconds. -- GitLab From 1d29cfa57471a5e4b8a7c2a7433eeba170d3ad92 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 29 May 2012 18:46:06 -0700 Subject: [PATCH 1436/6849] driver core: fixup reversed deferred probe order If driver requests probe deferral, it will be added to deferred_probe_pending_list by driver_deferred_probe_add(), but, it used list_add(). Because of that, deferred probe will be run as reversed order. This patch uses list_add_tail(), and solved this issue. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1b1cbb571d38..dcb8a6e48692 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -100,7 +100,7 @@ static void driver_deferred_probe_add(struct device *dev) mutex_lock(&deferred_probe_mutex); if (list_empty(&dev->p->deferred_probe)) { dev_dbg(dev, "Added to deferred list\n"); - list_add(&dev->p->deferred_probe, &deferred_probe_pending_list); + list_add_tail(&dev->p->deferred_probe, &deferred_probe_pending_list); } mutex_unlock(&deferred_probe_mutex); } -- GitLab From aa189ecdc0c7fad2166ba6d133df8bd214550f68 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:10 +0300 Subject: [PATCH 1437/6849] misc: mei: set IRQF_ONESHOT for msi request_threaded_irq when the default irq quick handler is used then IRQF_ONESHOT must be set otherwise the request fails and following error is displayed: genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq ... Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c70333228337..88e5953eb5be 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -982,7 +982,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, err = request_threaded_irq(pdev->irq, NULL, mei_interrupt_thread_handler, - 0, mei_driver_name, dev); + IRQF_ONESHOT, mei_driver_name, dev); else err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, -- GitLab From a44cab4aff7e72e7052521121fd8ceca51351534 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:11 +0300 Subject: [PATCH 1438/6849] misc: mei: unregister misc device in pci_remove function Since the misc device is registered only in the pci probe function it has to be also unregistered in the counterpart pci remove function and not in the module exit function. In case of probe failure the driver was oopsing in module exit function. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 88e5953eb5be..a5a17e78a96c 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1101,6 +1101,8 @@ static void __devexit mei_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); + + misc_deregister(&mei_misc_device); } #ifdef CONFIG_PM static int mei_pci_suspend(struct device *device) @@ -1216,7 +1218,6 @@ module_init(mei_init_module); */ static void __exit mei_exit_module(void) { - misc_deregister(&mei_misc_device); pci_unregister_driver(&mei_driver); pr_debug("unloaded successfully.\n"); -- GitLab From 1e69d64a28cf3cabd095ada3a49f081c97f997dd Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:12 +0300 Subject: [PATCH 1439/6849] misc: mei: fix stalled read This bug caused severe connectivity issue in the LMS application (LMS is described in Documentation/misc-devices/mei/mei.txt) The bug was introduced in patch: commit 1ccb7b6249f9bc50678e2a383084ed0a34cc9239 staging/mei: propagate error codes up in the write flow The patch has reverted the return value logic of some fo function but the conditional in _mei_irq_thread_read function was not swapped making read always entering the error path Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 93936f1b75eb..23f5463d4cae 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -835,7 +835,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_io_list *cmpl_list) { - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ list_del(&cb_pos->cb_list); -- GitLab From 92f02430934ca1c1e991a1ab3541880575042697 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: [PATCH 1440/6849] PCI: add busn_res in struct pci_bus This adds a busn_res resource in struct pci_bus. This will replace the secondary/subordinate members and will be used to build a bus number resource tree to help with bus number allocation. [bhelgaas: changelog] CC: Andrew Morton Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..ba7c5cd314b7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -419,6 +419,7 @@ struct pci_bus { struct list_head slots; /* list of slots on this bus */ struct resource *resource[PCI_BRIDGE_RESOURCE_NUM]; struct list_head resources; /* address space routed to this bus */ + struct resource busn_res; /* bus numbers routed to this bus */ struct pci_ops *ops; /* configuration access functions */ void *sysdata; /* hook for sys-specific extension */ -- GitLab From b918c62e086b2130a7bae44110ca516ef10bfe5a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: [PATCH 1441/6849] PCI: replace struct pci_bus secondary/subordinate with busn_res Replace the struct pci_bus secondary/subordinate members with the struct resource busn_res. Later we'll build a resource tree of these bus numbers. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/alpha/kernel/pci.c | 2 +- arch/arm/kernel/bios32.c | 2 +- arch/ia64/pci/pci.c | 2 +- arch/microblaze/pci/pci-common.c | 4 +- arch/mips/pci/pci.c | 2 +- arch/powerpc/kernel/pci-common.c | 6 +-- arch/powerpc/kernel/pci_64.c | 2 +- arch/powerpc/kernel/pci_of_scan.c | 2 +- arch/powerpc/platforms/powernv/pci-ioda.c | 8 +-- arch/powerpc/platforms/pseries/pci_dlpar.c | 2 +- arch/sh/drivers/pci/pci.c | 2 +- arch/sparc/kernel/pci.c | 6 +-- arch/tile/kernel/pci.c | 4 +- arch/x86/pci/acpi.c | 2 +- arch/xtensa/kernel/pci.c | 2 +- drivers/iommu/intel-iommu.c | 2 +- drivers/net/ethernet/broadcom/tg3.c | 4 +- drivers/parisc/dino.c | 10 ++-- drivers/parisc/iosapic.c | 2 +- drivers/parisc/lba_pci.c | 22 ++++---- drivers/pci/hotplug/acpiphp_glue.c | 8 +-- drivers/pci/hotplug/cpci_hotplug_pci.c | 6 +-- drivers/pci/hotplug/pciehp_pci.c | 4 +- drivers/pci/hotplug/shpchp_pci.c | 6 +-- drivers/pci/hotplug/shpchp_sysfs.c | 6 +-- drivers/pci/iov.c | 4 +- drivers/pci/pci.c | 2 +- drivers/pci/probe.c | 58 +++++++++++----------- drivers/pci/setup-bus.c | 24 ++++----- drivers/pcmcia/cardbus.c | 2 +- drivers/pcmcia/yenta_socket.c | 26 +++++----- 31 files changed, 117 insertions(+), 117 deletions(-) diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 1a629636cc16..53229a496311 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -359,7 +359,7 @@ common_init_pci(void) hose, &resources); hose->bus = bus; hose->need_domain_info = need_domain_info; - next_busno = bus->subordinate + 1; + next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 25552508c3fd..f07710849b58 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -461,7 +461,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) if (!sys->bus) panic("PCI: unable to scan bus!"); - busnr = sys->bus->subordinate + 1; + busnr = sys->bus->busn_res.end + 1; list_add(&sys->node, head); } else { diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 524df4295c90..3ca9bed7dc50 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -384,7 +384,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root) return NULL; } - pbus->subordinate = pci_scan_child_bus(pbus); + pbus->busn_res.end = pci_scan_child_bus(pbus); return pbus; out3: diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index ed22bfc5db14..9b32483cd0c0 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -1506,10 +1506,10 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose) pci_free_resource_list(&resources); return; } - bus->secondary = hose->first_busno; + bus->busn_res.start = hose->first_busno; hose->bus = bus; - hose->last_busno = bus->subordinate; + hose->last_busno = bus->busn_res.end; } static int __init pcibios_init(void) diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 271e8c4a54c7..0a9bf778edb5 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -102,7 +102,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) need_domain_info = need_domain_info || hose->index; hose->need_domain_info = need_domain_info; if (bus) { - next_busno = bus->subordinate + 1; + next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 8e78e93c8185..3532b535698a 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1646,7 +1646,7 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) pci_free_resource_list(&resources); return; } - bus->secondary = hose->first_busno; + bus->busn_res.start = hose->first_busno; hose->bus = bus; /* Get probe mode and perform scan */ @@ -1655,12 +1655,12 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) mode = ppc_md.pci_probe_mode(bus); pr_debug(" probe mode: %d\n", mode); if (mode == PCI_PROBE_DEVTREE) { - bus->subordinate = hose->last_busno; + bus->busn_res.end = hose->last_busno; of_scan_bus(node, bus); } if (mode == PCI_PROBE_NORMAL) - hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); + hose->last_busno = bus->busn_res.end = pci_scan_child_bus(bus); /* Platform gets a chance to do some global fixups before * we proceed to resource allocation diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 94a54f61d341..4ff190ff24a0 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -236,7 +236,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { bus = pci_bus_b(ln); - if (in_bus >= bus->number && in_bus <= bus->subordinate) + if (in_bus >= bus->number && in_bus <= bus->busn_res.end) break; bus = NULL; } diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 89dde171a6fa..a36281aa98f3 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -240,7 +240,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) } bus->primary = dev->bus->number; - bus->subordinate = busrange[1]; + bus->busn_res.end = busrange[1]; bus->bridge_ctl = 0; /* parse ranges property */ diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index fbdd74dac3ac..9cda6a1ad0cf 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -589,7 +589,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; parent = pe->pbus->self; - count = pe->pbus->subordinate - pe->pbus->secondary + 1; + count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1; switch(count) { case 1: bcomp = OpalPciBusAll; break; case 2: bcomp = OpalPciBus7Bits; break; @@ -816,11 +816,11 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev, pe->pdev = NULL; pe->tce32_seg = -1; pe->mve_number = -1; - pe->rid = bus->secondary << 8; + pe->rid = bus->busn_res.start << 8; pe->dma_weight = 0; - pe_info(pe, "Secondary busses %d..%d associated with PE\n", - bus->secondary, bus->subordinate); + pe_info(pe, "Secondary busses %pR associated with PE\n", + &bus->busn_res); if (pnv_ioda_configure_pe(phb, pe)) { /* XXX What do we do here ? */ diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 8b7bafa489c2..3ccebc83dc02 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -121,7 +121,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus) if (!num) return; pcibios_setup_bus_devices(bus); - max = bus->secondary; + max = bus->busn_res.start; for (pass=0; pass < 2; pass++) list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 9d10a3cb8797..43068dcb451c 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -59,7 +59,7 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) need_domain_info = need_domain_info || hose->index; hose->need_domain_info = need_domain_info; if (bus) { - next_busno = bus->subordinate + 1; + next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index fdaf21811670..c85bfd788f74 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -535,7 +535,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, } bus->primary = dev->bus->number; - bus->subordinate = busrange[1]; + bus->busn_res.end = busrange[1]; bus->bridge_ctl = 0; /* parse ranges property, or cook one up by hand for Simba */ @@ -693,8 +693,8 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_free_resource_list(&resources); return NULL; } - bus->secondary = pbm->pci_first_busno; - bus->subordinate = pbm->pci_last_busno; + bus->busn_res.start = pbm->pci_first_busno; + bus->busn_res.end = pbm->pci_last_busno; pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index b56d12bf5900..54cc8d77c90c 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -329,7 +329,7 @@ int __init pcibios_init(void) */ bus = pci_scan_bus(0, controller->ops, controller); controller->root_bus = bus; - controller->last_busno = bus->subordinate; + controller->last_busno = bus->busn_res.end; } } @@ -366,7 +366,7 @@ int __init pcibios_init(void) */ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && (PCI_SLOT(dev->devfn) == 0)) { - next_bus = dev->subordinate; + next_bus = dev->busn_res.end; controllers[i].mem_resources[0] = *next_bus->resource[0]; controllers[i].mem_resources[1] = diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index fc09c2754e08..350fe63c8a42 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -440,7 +440,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); if (bus) { - bus->subordinate = pci_scan_child_bus(bus); + bus->busn_res.end = pci_scan_child_bus(bus); pci_set_host_bridge_release( to_pci_host_bridge(bus->bridge), release_pci_root_info, info); diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index eb30e356f5be..9c57c1e6870c 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -187,7 +187,7 @@ static int __init pcibios_init(void) bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno, pci_ctrl->ops, pci_ctrl, &resources); pci_ctrl->bus = bus; - pci_ctrl->last_busno = bus->subordinate; + pci_ctrl->last_busno = bus->busn_res.end; if (next_busno <= pci_ctrl->last_busno) next_busno = pci_ctrl->last_busno+1; } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index b12af2ff8c54..2fb7d1598a68 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -661,7 +661,7 @@ static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) if (drhd->devices[i] && drhd->devices[i]->subordinate && drhd->devices[i]->subordinate->number <= bus && - drhd->devices[i]->subordinate->subordinate >= bus) + drhd->devices[i]->subordinate->busn_res.end >= bus) return drhd->iommu; } diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index edeeb516807a..09fa3c687a1f 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -14168,7 +14168,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (bridge->subordinate && (bridge->subordinate->number <= tp->pdev->bus->number) && - (bridge->subordinate->subordinate >= + (bridge->subordinate->busn_res.end >= tp->pdev->bus->number)) { tg3_flag_set(tp, 5701_DMA_BUG); pci_dev_put(bridge); @@ -14196,7 +14196,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (bridge && bridge->subordinate && (bridge->subordinate->number <= tp->pdev->bus->number) && - (bridge->subordinate->subordinate >= + (bridge->subordinate->busn_res.end >= tp->pdev->bus->number)) { tg3_flag_set(tp, 40BIT_DMA_BUG); pci_dev_put(bridge); diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 432d4bbcc62a..70517b0f94e6 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -174,7 +174,7 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); void __iomem *base_addr = d->hba.base_addr; unsigned long flags; @@ -209,7 +209,7 @@ static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); void __iomem *base_addr = d->hba.base_addr; unsigned long flags; @@ -554,7 +554,7 @@ dino_fixup_bus(struct pci_bus *bus) struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", - __func__, bus, bus->secondary, + __func__, bus, bus->busn_res.start, bus->bridge->platform_data); /* Firmware doesn't set up card-mode dino, so we have to */ @@ -998,12 +998,12 @@ static int __init dino_probe(struct parisc_device *dev) return 0; } - bus->subordinate = pci_scan_child_bus(bus); + bus->busn_res.end = pci_scan_child_bus(bus); /* This code *depends* on scanning being single threaded * if it isn't, this global bus number count will fail */ - dino_current_bus = bus->subordinate + 1; + dino_current_bus = bus->busn_res.end + 1; pci_bus_assign_resources(bus); pci_bus_add_devices(bus); return 0; diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 1f9e9fefb8e7..83380c8fcb6b 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -532,7 +532,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev) intr_slot = PCI_SLOT(pcidev->devfn); } DBG_IRT("iosapic_xlate_pin: bus %d slot %d pin %d\n", - pcidev->bus->secondary, intr_slot, intr_pin); + pcidev->bus->busn_res.start, intr_slot, intr_pin); return irt_find_irqline(isi, intr_slot, intr_pin); } diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 052fa230bc77..cd8f9ce8720f 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -189,8 +189,8 @@ lba_dump_res(struct resource *r, int d) static int lba_device_present(u8 bus, u8 dfn, struct lba_device *d) { - u8 first_bus = d->hba.hba_bus->secondary; - u8 last_sub_bus = d->hba.hba_bus->subordinate; + u8 first_bus = d->hba.hba_bus->busn_res.start; + u8 last_sub_bus = d->hba.hba_bus->busn_res.end; if ((bus < first_bus) || (bus > last_sub_bus) || @@ -364,7 +364,7 @@ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size) static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; @@ -380,7 +380,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int return 0; } - if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) { + if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) { DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos); /* either don't want to look or know device isn't present. */ *data = ~0U; @@ -431,7 +431,7 @@ lba_wr_cfg(struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size) static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) @@ -444,7 +444,7 @@ static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int return 0; } - if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) { + if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->busn_res.start, devfn, d))) { DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data); return 1; /* New Workaround */ } @@ -481,7 +481,7 @@ static struct pci_ops elroy_cfg_ops = { static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; @@ -514,7 +514,7 @@ static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, i { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) @@ -636,7 +636,7 @@ lba_fixup_bus(struct pci_bus *bus) struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", - bus, bus->secondary, bus->bridge->platform_data); + bus, (int)bus->busn_res.start, bus->bridge->platform_data); /* ** Properly Setup MMIO resources for this bus. @@ -1511,7 +1511,7 @@ lba_driver_probe(struct parisc_device *dev) return 0; } - lba_bus->subordinate = pci_scan_child_bus(lba_bus); + lba_bus->busn_res.end = pci_scan_child_bus(lba_bus); /* This is in lieu of calling pci_assign_unassigned_resources() */ if (is_pdc_pat()) { @@ -1541,7 +1541,7 @@ lba_driver_probe(struct parisc_device *dev) lba_dev->flags |= LBA_FLAG_SKIP_PROBE; } - lba_next_bus = lba_bus->subordinate + 1; + lba_next_bus = lba_res->busn_res.end + 1; pci_bus_add_devices(lba_bus); /* Whew! Finally done! Tell services we got this one covered. */ diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 806c44fa645a..62d0ae4dfcad 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -100,11 +100,11 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, PCI_PRIMARY_BUS, &buses); - if (((buses >> 8) & 0xff) != bus->secondary) { + if (((buses >> 8) & 0xff) != bus->busn_res.start) { buses = (buses & 0xff000000) | ((unsigned int)(bus->primary) << 0) - | ((unsigned int)(bus->secondary) << 8) - | ((unsigned int)(bus->subordinate) << 16); + | ((unsigned int)(bus->busn_res.start) << 8) + | ((unsigned int)(bus->busn_res.end) << 16); pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); } return NOTIFY_OK; @@ -692,7 +692,7 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) * bus->subordinate value because it could have * padding in it. */ - max = bus->secondary; + max = bus->busn_res.start; list_for_each(tmp, &bus->children) { n = pci_bus_max_busnr(pci_bus_b(tmp)); diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index ae853ccd0cd5..42f3a61db87c 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -292,8 +292,8 @@ int __ref cpci_configure_slot(struct slot *slot) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { /* Find an unused bus number for the new bridge */ struct pci_bus *child; - unsigned char busnr, start = parent->secondary; - unsigned char end = parent->subordinate; + unsigned char busnr, start = parent->busn_res.start; + unsigned char end = parent->busn_res.end; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), @@ -312,7 +312,7 @@ int __ref cpci_configure_slot(struct slot *slot) pci_dev_put(dev); continue; } - child->subordinate = pci_do_scan_bus(child); + child->busn_res.end = pci_do_scan_bus(child); pci_bus_size_bridges(child); } pci_dev_put(dev); diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 47d9dc06b109..b898f06b588d 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -37,8 +37,8 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev) { struct pci_bus *parent = dev->bus; - int pass, busnr, start = parent->secondary; - int end = parent->subordinate; + int pass, busnr, start = parent->busn_res.start; + int end = parent->busn_res.end; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index df7e4bfadae3..d021eb031b3c 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -64,8 +64,8 @@ int __ref shpchp_configure_device(struct slot *p_slot) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { /* Find an unused bus number for the new bridge */ struct pci_bus *child; - unsigned char busnr, start = parent->secondary; - unsigned char end = parent->subordinate; + unsigned char busnr, start = parent->busn_res.start; + unsigned char end = parent->busn_res.end; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) @@ -84,7 +84,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) pci_dev_put(dev); continue; } - child->subordinate = pci_do_scan_bus(child); + child->busn_res.end = pci_do_scan_bus(child); pci_bus_size_bridges(child); } pci_configure_slot(dev); diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index efa30da1ae8f..eeb23ceae4a8 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -73,13 +73,13 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } } out += sprintf(out, "Free resources: bus numbers\n"); - for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) { + for (busnr = bus->busn_res.start; busnr <= bus->busn_res.end; busnr++) { if (!pci_find_bus(pci_domain_nr(bus), busnr)) break; } - if (busnr < bus->subordinate) + if (busnr < bus->busn_res.end) out += sprintf(out, "start = %8.8x, length = %8.8x\n", - busnr, (bus->subordinate - busnr)); + busnr, (int)(bus->busn_res.end - busnr)); return out - buf; } diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 6554e1a0f634..e873060fb35b 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -47,7 +47,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) if (!child) return NULL; - child->subordinate = busnr; + child->busn_res.end = busnr; child->dev.parent = bus->bridge; rc = pci_bus_add_child(child); if (rc) { @@ -327,7 +327,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) iov->offset = offset; iov->stride = stride; - if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) { + if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->busn_res.end) { dev_err(&dev->dev, "SR-IOV: bus number out of range\n"); return -ENOMEM; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..aeda6e9c245c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -110,7 +110,7 @@ unsigned char pci_bus_max_busnr(struct pci_bus* bus) struct list_head *tmp; unsigned char max, n; - max = bus->subordinate; + max = bus->busn_res.end; list_for_each(tmp, &bus->children) { n = pci_bus_max_busnr(pci_bus_b(tmp)); if(n > max) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 658ac977cb56..651b096134dc 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -381,8 +381,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ return; - dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", - child->secondary, child->subordinate, + dev_info(&dev->dev, "PCI bridge to %pR%s\n", + &child->busn_res, dev->transparent ? " (subtractive decode)" : ""); pci_bus_remove_resources(child); @@ -599,9 +599,9 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, * Set up the primary, secondary and subordinate * bus numbers. */ - child->number = child->secondary = busnr; - child->primary = parent->secondary; - child->subordinate = 0xff; + child->number = child->busn_res.start = busnr; + child->primary = parent->busn_res.start; + child->busn_res.end = 0xff; if (!bridge) return child; @@ -643,8 +643,8 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) if (!pcibios_assign_all_busses()) return; - while (parent->parent && parent->subordinate < max) { - parent->subordinate = max; + while (parent->parent && parent->busn_res.end < max) { + parent->busn_res.end = max; pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); parent = parent->parent; } @@ -718,15 +718,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, if (!child) goto out; child->primary = primary; - child->subordinate = subordinate; + child->busn_res.end = subordinate; child->bridge_ctl = bctl; } cmax = pci_scan_child_bus(child); if (cmax > max) max = cmax; - if (child->subordinate > max) - max = child->subordinate; + if (child->busn_res.end > max) + max = child->busn_res.end; } else { /* * We need to assign a number to this bus which we always @@ -759,8 +759,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, } buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) - | ((unsigned int)(child->secondary) << 8) - | ((unsigned int)(child->subordinate) << 16); + | ((unsigned int)(child->busn_res.start) << 8) + | ((unsigned int)(child->busn_res.end) << 16); /* * yenta.c forces a secondary latency timer of 176. @@ -805,8 +805,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, break; while (parent->parent) { if ((!pcibios_assign_all_busses()) && - (parent->subordinate > max) && - (parent->subordinate <= max+i)) { + (parent->busn_res.end > max) && + (parent->busn_res.end <= max+i)) { j = 1; } parent = parent->parent; @@ -827,7 +827,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, /* * Set the subordinate bus number to its real value. */ - child->subordinate = max; + child->busn_res.end = max; pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); } @@ -837,19 +837,19 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, /* Has only triggered on CardBus, fixup is in yenta_socket */ while (bus->parent) { - if ((child->subordinate > bus->subordinate) || - (child->number > bus->subordinate) || + if ((child->busn_res.end > bus->busn_res.end) || + (child->number > bus->busn_res.end) || (child->number < bus->number) || - (child->subordinate < bus->number)) { - dev_info(&child->dev, "[bus %02x-%02x] %s " - "hidden behind%s bridge %s [bus %02x-%02x]\n", - child->number, child->subordinate, - (bus->number > child->subordinate && - bus->subordinate < child->number) ? + (child->busn_res.end < bus->number)) { + dev_info(&child->dev, "%pR %s " + "hidden behind%s bridge %s %pR\n", + &child->busn_res, + (bus->number > child->busn_res.end && + bus->busn_res.end < child->number) ? "wholly" : "partially", bus->self->transparent ? " transparent" : "", dev_name(&bus->dev), - bus->number, bus->subordinate); + &bus->busn_res); } bus = bus->parent; } @@ -1548,7 +1548,7 @@ EXPORT_SYMBOL_GPL(pcie_bus_configure_settings); unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) { - unsigned int devfn, pass, max = bus->secondary; + unsigned int devfn, pass, max = bus->busn_res.start; struct pci_dev *dev; dev_dbg(&bus->dev, "scanning bus\n"); @@ -1642,7 +1642,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, /* Create legacy_io and legacy_mem files for this bus */ pci_create_legacy_files(b); - b->number = b->secondary = bus; + b->number = b->busn_res.start = bus; if (parent) dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); @@ -1693,7 +1693,7 @@ struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus, if (!b) return NULL; - b->subordinate = pci_scan_child_bus(b); + b->busn_res.end = pci_scan_child_bus(b); pci_bus_add_devices(b); return b; } @@ -1710,7 +1710,7 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, pci_add_resource(&resources, &iomem_resource); b = pci_create_root_bus(parent, bus, ops, sysdata, &resources); if (b) - b->subordinate = pci_scan_child_bus(b); + b->busn_res.end = pci_scan_child_bus(b); else pci_free_resource_list(&resources); return b; @@ -1727,7 +1727,7 @@ struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, pci_add_resource(&resources, &iomem_resource); b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources); if (b) { - b->subordinate = pci_scan_child_bus(b); + b->busn_res.end = pci_scan_child_bus(b); pci_bus_add_devices(b); } else { pci_free_resource_list(&resources); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8fa2d4be88de..192172c87b77 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -404,8 +404,8 @@ void pci_setup_cardbus(struct pci_bus *bus) struct resource *res; struct pci_bus_region region; - dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", - bus->secondary, bus->subordinate); + dev_info(&bridge->dev, "CardBus bridge to %pR\n", + &bus->busn_res); res = bus->resource[0]; pcibios_resource_to_bus(bridge, ®ion, res); @@ -553,8 +553,8 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) { struct pci_dev *bridge = bus->self; - dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", - bus->secondary, bus->subordinate); + dev_info(&bridge->dev, "PCI bridge to %pR\n", + &bus->busn_res); if (type & IORESOURCE_IO) pci_setup_bridge_io(bus); @@ -745,8 +745,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, if (!size0 && !size1) { if (b_res->start || b_res->end) dev_info(&bus->self->dev, "disabling bridge window " - "%pR to [bus %02x-%02x] (unused)\n", b_res, - bus->secondary, bus->subordinate); + "%pR to %pR (unused)\n", b_res, + &bus->busn_res); b_res->flags = 0; return; } @@ -757,8 +757,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, if (size1 > size0 && realloc_head) { add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " - "%pR to [bus %02x-%02x] add_size %lx\n", b_res, - bus->secondary, bus->subordinate, size1-size0); + "%pR to %pR add_size %lx\n", b_res, + &bus->busn_res, size1-size0); } } @@ -863,8 +863,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (!size0 && !size1) { if (b_res->start || b_res->end) dev_info(&bus->self->dev, "disabling bridge window " - "%pR to [bus %02x-%02x] (unused)\n", b_res, - bus->secondary, bus->subordinate); + "%pR to %pR (unused)\n", b_res, + &bus->busn_res); b_res->flags = 0; return 1; } @@ -874,8 +874,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (size1 > size0 && realloc_head) { add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " - "%pR to [bus %02x-%02x] add_size %llx\n", b_res, - bus->secondary, bus->subordinate, (unsigned long long)size1-size0); + "%pR to %pR add_size %llx\n", b_res, + &bus->busn_res, (unsigned long long)size1-size0); } return 1; } diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 6e75153c5b4f..24caeaf50529 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -73,7 +73,7 @@ int __ref cb_alloc(struct pcmcia_socket *s) s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); pci_fixup_cardbus(bus); - max = bus->secondary; + max = bus->busn_res.start; for (pass = 0; pass < 2; pass++) list_for_each_entry(dev, &bus->devices, bus_list) if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index d07f9ac8c41d..667678db1153 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1048,8 +1048,8 @@ static void yenta_config_init(struct yenta_socket *socket) config_writeb(socket, PCI_LATENCY_TIMER, 168); config_writel(socket, PCI_PRIMARY_BUS, (176 << 24) | /* sec. latency timer */ - (dev->subordinate->subordinate << 16) | /* subordinate bus */ - (dev->subordinate->secondary << 8) | /* secondary bus */ + ((unsigned int)dev->subordinate->busn_res.end << 16) | /* subordinate bus */ + ((unsigned int)dev->subordinate->busn_res.start << 8) | /* secondary bus */ dev->subordinate->primary); /* primary bus */ /* @@ -1086,14 +1086,14 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) struct pci_bus *bridge_to_fix = cardbus_bridge->parent; /* Check bus numbers are already set up correctly: */ - if (bridge_to_fix->subordinate >= cardbus_bridge->subordinate) + if (bridge_to_fix->busn_res.end >= cardbus_bridge->busn_res.end) return; /* The subordinate number is ok, nothing to do */ if (!bridge_to_fix->parent) return; /* Root bridges are ok */ /* stay within the limits of the bus range of the parent: */ - upper_limit = bridge_to_fix->parent->subordinate; + upper_limit = bridge_to_fix->parent->busn_res.end; /* check the bus ranges of all silbling bridges to prevent overlap */ list_for_each(tmp, &bridge_to_fix->parent->children) { @@ -1104,36 +1104,36 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) * current upper limit, set the new upper limit to * the bus number below the silbling's range: */ - if (silbling->secondary > bridge_to_fix->subordinate - && silbling->secondary <= upper_limit) - upper_limit = silbling->secondary - 1; + if (silbling->busn_res.start > bridge_to_fix->busn_res.end + && silbling->busn_res.start <= upper_limit) + upper_limit = silbling->busn_res.start - 1; } /* Show that the wanted subordinate number is not possible: */ - if (cardbus_bridge->subordinate > upper_limit) + if (cardbus_bridge->busn_res.end > upper_limit) dev_printk(KERN_WARNING, &cardbus_bridge->dev, "Upper limit for fixing this " "bridge's parent bridge: #%02x\n", upper_limit); /* If we have room to increase the bridge's subordinate number, */ - if (bridge_to_fix->subordinate < upper_limit) { + if (bridge_to_fix->busn_res.end < upper_limit) { /* use the highest number of the hidden bus, within limits */ unsigned char subordinate_to_assign = - min(cardbus_bridge->subordinate, upper_limit); + min_t(int, cardbus_bridge->busn_res.end, upper_limit); dev_printk(KERN_INFO, &bridge_to_fix->dev, "Raising subordinate bus# of parent " "bus (#%02x) from #%02x to #%02x\n", bridge_to_fix->number, - bridge_to_fix->subordinate, subordinate_to_assign); + (int)bridge_to_fix->busn_res.end, subordinate_to_assign); /* Save the new subordinate in the bus struct of the bridge */ - bridge_to_fix->subordinate = subordinate_to_assign; + bridge_to_fix->busn_res.end = subordinate_to_assign; /* and update the PCI config space with the new subordinate */ pci_write_config_byte(bridge_to_fix->self, - PCI_SUBORDINATE_BUS, bridge_to_fix->subordinate); + PCI_SUBORDINATE_BUS, bridge_to_fix->busn_res.end); } } -- GitLab From 3527ed81ca01bbaf09df952e68528377a9cd092f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: [PATCH 1442/6849] PCI: remove secondary/subordinate in struct pci_bus The pci_bus secondary/subordinate members are now unused, so remove them. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/pci.h b/include/linux/pci.h index ba7c5cd314b7..6b10966cd1b9 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -427,8 +427,6 @@ struct pci_bus { unsigned char number; /* bus number */ unsigned char primary; /* number of primary bridge */ - unsigned char secondary; /* number of secondary bridge */ - unsigned char subordinate; /* max number of subordinate buses */ unsigned char max_bus_speed; /* enum pci_bus_speed */ unsigned char cur_bus_speed; /* enum pci_bus_speed */ -- GitLab From 5cc62c202211096ec26309722ec27455d52c8726 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: [PATCH 1443/6849] PCI: build a bus number resource tree for every domain This adds get_pci_domain_busn_res(), which returns the root of the bus number resource tree for a domain, creating it if necessary. We will later populate the tree with the bus numbers used by host bridges and P2P bridges in the domain. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 651b096134dc..674a477a6486 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -20,6 +20,36 @@ LIST_HEAD(pci_root_buses); EXPORT_SYMBOL(pci_root_buses); +static LIST_HEAD(pci_domain_busn_res_list); + +struct pci_domain_busn_res { + struct list_head list; + struct resource res; + int domain_nr; +}; + +static struct resource *get_pci_domain_busn_res(int domain_nr) +{ + struct pci_domain_busn_res *r; + + list_for_each_entry(r, &pci_domain_busn_res_list, list) + if (r->domain_nr == domain_nr) + return &r->res; + + r = kzalloc(sizeof(*r), GFP_KERNEL); + if (!r) + return NULL; + + r->domain_nr = domain_nr; + r->res.start = 0; + r->res.end = 0xff; + r->res.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED; + + list_add_tail(&r->list, &pci_domain_busn_res_list); + + return &r->res; +} + static int find_anything(struct device *dev, void *data) { return 1; -- GitLab From 82ec90eac304e81b1389175b4dded7abecc678ef Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: [PATCH 1444/6849] resources: allow adjust_resource() for resources with no parent If a resource has no parent, allow its start/end to be set arbitrarily as long as any children are still contained within the new range. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- kernel/resource.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index e1d2b8ee76d5..dc8b47764443 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -722,14 +722,12 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t write_lock(&resource_lock); + if (!parent) + goto skip; + if ((start < parent->start) || (end > parent->end)) goto out; - for (tmp = res->child; tmp; tmp = tmp->sibling) { - if ((tmp->start < start) || (tmp->end > end)) - goto out; - } - if (res->sibling && (res->sibling->start <= end)) goto out; @@ -741,6 +739,11 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t goto out; } +skip: + for (tmp = res->child; tmp; tmp = tmp->sibling) + if ((tmp->start < start) || (tmp->end > end)) + goto out; + res->start = start; res->end = end; result = 0; -- GitLab From 98a3583107ed587ed3cfe2a1d8e5347421de5a80 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 18 May 2012 11:35:50 -0600 Subject: [PATCH 1445/6849] PCI: add busn_res operation functions Will use them insert/update busn res in pci_bus struct. [bhelgaas: print conflicting entry if insertion fails] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 3 ++ 2 files changed, 71 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 674a477a6486..7662ab7b2640 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1714,6 +1714,74 @@ err_out: return NULL; } +int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) +{ + struct resource *res = &b->busn_res; + struct resource *parent_res, *conflict; + + res->start = bus; + res->end = bus_max; + res->flags = IORESOURCE_BUS; + + if (!pci_is_root_bus(b)) + parent_res = &b->parent->busn_res; + else { + parent_res = get_pci_domain_busn_res(pci_domain_nr(b)); + res->flags |= IORESOURCE_PCI_FIXED; + } + + conflict = insert_resource_conflict(parent_res, res); + + if (conflict) + dev_printk(KERN_DEBUG, &b->dev, + "busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n", + res, pci_is_root_bus(b) ? "domain " : "", + parent_res, conflict->name, conflict); + else + dev_printk(KERN_DEBUG, &b->dev, + "busn_res: %pR is inserted under %s%pR\n", + res, pci_is_root_bus(b) ? "domain " : "", + parent_res); + + return conflict == NULL; +} + +int pci_bus_update_busn_res_end(struct pci_bus *b, int bus_max) +{ + struct resource *res = &b->busn_res; + struct resource old_res = *res; + resource_size_t size; + int ret; + + if (res->start > bus_max) + return -EINVAL; + + size = bus_max - res->start + 1; + ret = adjust_resource(res, res->start, size); + dev_printk(KERN_DEBUG, &b->dev, + "busn_res: %pR end %s updated to %02x\n", + &old_res, ret ? "can not be" : "is", bus_max); + + if (!ret && !res->parent) + pci_bus_insert_busn_res(b, res->start, res->end); + + return ret; +} + +void pci_bus_release_busn_res(struct pci_bus *b) +{ + struct resource *res = &b->busn_res; + int ret; + + if (!res->flags || !res->parent) + return; + + ret = release_resource(res); + dev_printk(KERN_DEBUG, &b->dev, + "busn_res: %pR %s released\n", + res, ret ? "can not be" : "is"); +} + struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 6b10966cd1b9..c4df570f3bbb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -667,6 +667,9 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); +int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); +void pci_bus_release_busn_res(struct pci_bus *b); struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); -- GitLab From f6dd68a77f9c07088eee71a1787cfc84dcf49198 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:11 -0700 Subject: [PATCH 1446/6849] PCI: release busn_res when removing bus Release bus number resource when removing a bus. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/remove.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index fd77e2bde2e8..04a4861b4749 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -68,6 +68,7 @@ void pci_remove_bus(struct pci_bus *pci_bus) down_write(&pci_bus_sem); list_del(&pci_bus->node); + pci_bus_release_busn_res(pci_bus); up_write(&pci_bus_sem); if (!pci_bus->is_added) return; -- GitLab From f848ffb1043ed0d168064176fb452cc51ec8e0b7 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1447/6849] PCI: insert busn_res in pci_create_root_bus() That busn_res is from resources list. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 7662ab7b2640..59011ce9840f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1684,7 +1684,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, list_move_tail(&window->list, &bridge->windows); res = window->res; offset = window->offset; - pci_bus_add_resource(b, res, 0); + if (res->flags & IORESOURCE_BUS) + pci_bus_insert_busn_res(b, bus, res->end); + else + pci_bus_add_resource(b, res, 0); if (offset) { if (resource_type(res) == IORESOURCE_IO) fmt = " (bus address [%#06llx-%#06llx])"; -- GitLab From 4d99f524234c2e772eea68ad019ec9c805991f23 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1448/6849] PCI: checking busn_res in pci_scan_root_bus() Some callers do not supply the bus number aperture, usually because they do not know the end. In this case, we assume the aperture extends from the root bus number to bus 255, scan the bus, and shrink the bus number resource so it ends at the largest bus number we found. This is obviously not correct because the actual end of the aperture may well be larger than the largest bus number we found. But I guess it's all we have for now. Also print out one info about that, so we could find out which path does not have busn_res in resources list. [bhelgaas: changelog, _safe iterator unnecessary, use %pR format for bus] Signed-off-by: Yinghai Lu --- drivers/pci/probe.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 59011ce9840f..6258f6f24983 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1788,13 +1788,33 @@ void pci_bus_release_busn_res(struct pci_bus *b) struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources) { + struct pci_host_bridge_window *window; + bool found = false; struct pci_bus *b; + int max; + + list_for_each_entry(window, resources, list) + if (window->res->flags & IORESOURCE_BUS) { + found = true; + break; + } b = pci_create_root_bus(parent, bus, ops, sysdata, resources); if (!b) return NULL; - b->busn_res.end = pci_scan_child_bus(b); + if (!found) { + dev_info(&b->dev, + "No busn resource found for root bus, will use [bus %02x-ff]\n", + bus); + pci_bus_insert_busn_res(b, bus, 255); + } + + max = pci_scan_child_bus(b); + + if (!found) + pci_bus_update_busn_res_end(b, max); + pci_bus_add_devices(b); return b; } -- GitLab From 67cdc827286366acb6c60c821013c1185ee00b36 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1449/6849] PCI: add default busn_resource We need to put into the resources list for legacy system. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 7 +++++++ include/linux/pci.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6258f6f24983..68e75cb0831b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -16,6 +16,13 @@ #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_RESERVE_BUSNR 3 +struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + /* Ugh. Need to stop exporting this to modules. */ LIST_HEAD(pci_root_buses); EXPORT_SYMBOL(pci_root_buses); diff --git a/include/linux/pci.h b/include/linux/pci.h index c4df570f3bbb..8c8b44d62105 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -368,6 +368,8 @@ static inline int pci_channel_offline(struct pci_dev *pdev) return (pdev->error_state != pci_channel_io_normal); } +extern struct resource busn_resource; + struct pci_host_bridge_window { struct list_head list; struct resource *res; /* host bridge aperture (CPU address) */ -- GitLab From 857c3b668ae35c48d9d7a4248b6c0bdb65797d0e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1450/6849] PCI: add default busn_res for pci_scan_bus() also do not need to shrink busn_res. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 68e75cb0831b..9f68b9d3597c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1836,9 +1836,10 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, pci_add_resource(&resources, &ioport_resource); pci_add_resource(&resources, &iomem_resource); + pci_add_resource(&resources, &busn_resource); b = pci_create_root_bus(parent, bus, ops, sysdata, &resources); if (b) - b->busn_res.end = pci_scan_child_bus(b); + pci_scan_child_bus(b); else pci_free_resource_list(&resources); return b; @@ -1853,9 +1854,10 @@ struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, pci_add_resource(&resources, &ioport_resource); pci_add_resource(&resources, &iomem_resource); + pci_add_resource(&resources, &busn_resource); b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources); if (b) { - b->busn_res.end = pci_scan_child_bus(b); + pci_scan_child_bus(b); pci_bus_add_devices(b); } else { pci_free_resource_list(&resources); -- GitLab From 5c1d81d160cc46e36fdd06702885c98c2643b4c5 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1451/6849] x86/PCI: use _CRS bus number aperture for host bridges from ACPI Add the host bridge bus number aperture from _CRS to the resource list. Like the MMIO and I/O port apertures, this will be used when assigning resources to hot-added devices or in the case of conflicts. Note that we always use the _CRS bus number aperture, even if we're ignoring _CRS otherwise. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/acpi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 350fe63c8a42..2bb885afe103 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -12,7 +12,6 @@ struct pci_root_info { char name[16]; unsigned int res_num; struct resource *res; - int busnum; struct pci_sysdata sd; }; @@ -347,7 +346,9 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, { size_t size; + sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); info->bridge = device; + info->res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, info); @@ -360,8 +361,6 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, if (!info->res) return; - sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); - acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, info); } @@ -426,6 +425,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) } else { probe_pci_root_info(info, device, busnum, domain); + /* insert busn res at first */ + pci_add_resource(&resources, &root->secondary); /* * _CRS with no apertures is normal, so only fall back to * defaults or native bridge info if we're ignoring _CRS. @@ -440,7 +441,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); if (bus) { - bus->busn_res.end = pci_scan_child_bus(bus); + pci_scan_child_bus(bus); pci_set_host_bridge_release( to_pci_host_bridge(bus->bridge), release_pci_root_info, info); -- GitLab From a10bb128b64fe03198c4930f4483dda55c5c84eb Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1452/6849] x86/PCI: put busn resource in pci_root_info for native host bridge drivers Add the host bridge bus number aperture to the resource list. Like the MMIO and I/O port apertures, this will be used when assigning resources to hot-added devices or in the case of conflicts. [bhelgaas: changelog, tidy printk] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/amd_bus.c | 7 +++---- arch/x86/pci/bus_numa.c | 22 +++++++++++++++++++--- arch/x86/pci/bus_numa.h | 3 +-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 5aed49bff058..e9e6ed5cdf94 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c @@ -121,7 +121,6 @@ static int __init early_fill_mp_bus_info(void) link = (reg >> 8) & 0x03; info = alloc_pci_root_info(min_bus, max_bus, node, link); - sprintf(info->name, "PCI Bus #%02x", min_bus); } /* get the default node and link for left over res */ @@ -300,9 +299,9 @@ static int __init early_fill_mp_bus_info(void) int busnum; struct pci_root_res *root_res; - busnum = info->bus_min; - printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", - info->bus_min, info->bus_max, info->node, info->link); + busnum = info->busn.start; + printk(KERN_DEBUG "bus: %pR on node %x link %x\n", + &info->busn, info->node, info->link); list_for_each_entry(root_res, &info->resources, list) printk(KERN_DEBUG "bus: %02x %pR\n", busnum, &root_res->res); diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index 306579f7d0fd..d37e2fec97e5 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c @@ -14,7 +14,7 @@ static struct pci_root_info *x86_find_pci_root_info(int bus) return NULL; list_for_each_entry(info, &pci_root_infos, list) - if (info->bus_min == bus) + if (info->busn.start == bus) return info; return NULL; @@ -24,6 +24,8 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) { struct pci_root_info *info = x86_find_pci_root_info(bus); struct pci_root_res *root_res; + struct pci_host_bridge_window *window; + bool found = false; if (!info) goto default_resources; @@ -31,6 +33,16 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", bus); + /* already added by acpi ? */ + list_for_each_entry(window, resources, list) + if (window->res->flags & IORESOURCE_BUS) { + found = true; + break; + } + + if (!found) + pci_add_resource(resources, &info->busn); + list_for_each_entry(root_res, &info->resources, list) { struct resource *res; struct resource *root; @@ -66,9 +78,13 @@ struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max, if (!info) return info; + sprintf(info->name, "PCI Bus #%02x", bus_min); + INIT_LIST_HEAD(&info->resources); - info->bus_min = bus_min; - info->bus_max = bus_max; + info->busn.name = info->name; + info->busn.start = bus_min; + info->busn.end = bus_max; + info->busn.flags = IORESOURCE_BUS; info->node = node; info->link = link; diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h index 226a466b2b2b..ff8f65b04574 100644 --- a/arch/x86/pci/bus_numa.h +++ b/arch/x86/pci/bus_numa.h @@ -13,8 +13,7 @@ struct pci_root_info { struct list_head list; char name[12]; struct list_head resources; - int bus_min; - int bus_max; + struct resource busn; int node; int link; }; -- GitLab From 2661b819a10d432aa6f508630ff72e31367d4f21 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1453/6849] ia64/PCI: register busn_res for root buses Add the host bridge bus number aperture from _CRS to the resource list. Like the MMIO and I/O port apertures, this is used when assigning resources to hot-added devices or in the case of conflicts. [bhelgaas: changelog] CC: Tony Luck CC: Fenghua Yu CC: linux-ia64@vger.kernel.org Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/ia64/pci/pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 3ca9bed7dc50..d173a88d744a 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -351,6 +351,8 @@ pci_acpi_scan_root(struct acpi_pci_root *root) #endif INIT_LIST_HEAD(&info.resources); + /* insert busn resource at first */ + pci_add_resource(&info.resources, &root->secondary); acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, &windows); if (windows) { @@ -384,7 +386,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root) return NULL; } - pbus->busn_res.end = pci_scan_child_bus(pbus); + pci_scan_child_bus(pbus); return pbus; out3: -- GitLab From 3f1b540d460589e20df882aa2c86808d113890a8 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1454/6849] sparc/PCI: register busn_res for root buses Add the host bridge bus number aperture to the resource list. Like the MMIO and I/O port apertures, this is used when assigning resources to hot-added devices or in the case of conflicts. [bhelgaas: changelog, fix "pci_last_busn" typo] Acked-by: "David S. Miller" CC: sparclinux@vger.kernel.org Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/sparc/kernel/pci.c | 8 +++++--- arch/sparc/kernel/pci_impl.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c85bfd788f74..4f92a9aba358 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -535,7 +535,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, } bus->primary = dev->bus->number; - bus->busn_res.end = busrange[1]; + pci_bus_insert_busn_res(bus, busrange[0], busrange[1]); bus->bridge_ctl = 0; /* parse ranges property, or cook one up by hand for Simba */ @@ -685,6 +685,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, pbm->io_space.start); pci_add_resource_offset(&resources, &pbm->mem_space, pbm->mem_space.start); + pbm->busn.start = pbm->pci_first_busno; + pbm->busn.end = pbm->pci_last_busno; + pbm->busn.flags = IORESOURCE_BUS; + pci_add_resource(&resources, &pbm->busn); bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, pbm, &resources); if (!bus) { @@ -693,8 +697,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_free_resource_list(&resources); return NULL; } - bus->busn_res.start = pbm->pci_first_busno; - bus->busn_res.end = pbm->pci_last_busno; pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 6beb60df31d0..918a2031c8bb 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -97,6 +97,7 @@ struct pci_pbm_info { /* PBM I/O and Memory space resources. */ struct resource io_space; struct resource mem_space; + struct resource busn; /* Base of PCI Config space, can be per-PBM or shared. */ unsigned long config_space; -- GitLab From be8e60d8bed118b19bd7038ac2f6ac6688d072d9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1455/6849] powerpc/PCI: register busn_res for root buses Add the host bridge bus number aperture to the resource list. Like the MMIO and I/O port apertures, this is used when assigning resources to hot-added devices or in the case of conflicts. [bhelgaas: changelog] CC: Paul Mackerras CC: linuxppc-dev@lists.ozlabs.org CC: Benjamin Herrenschmidt Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/powerpc/include/asm/pci-bridge.h | 1 + arch/powerpc/kernel/pci-common.c | 17 +++++++++++------ arch/powerpc/kernel/pci_of_scan.c | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index ac39e6a3b25a..8cccbee61519 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -30,6 +30,7 @@ struct pci_controller { int first_busno; int last_busno; int self_busno; + struct resource busn; void __iomem *io_base_virt; #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 3532b535698a..7320f3685523 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1637,6 +1637,11 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) /* Wire up PHB bus resources */ pcibios_setup_phb_resources(hose, &resources); + hose->busn.start = hose->first_busno; + hose->busn.end = hose->last_busno; + hose->busn.flags = IORESOURCE_BUS; + pci_add_resource(&resources, &hose->busn); + /* Create an empty bus for the toplevel */ bus = pci_create_root_bus(hose->parent, hose->first_busno, hose->ops, hose, &resources); @@ -1646,7 +1651,6 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) pci_free_resource_list(&resources); return; } - bus->busn_res.start = hose->first_busno; hose->bus = bus; /* Get probe mode and perform scan */ @@ -1654,13 +1658,14 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) if (node && ppc_md.pci_probe_mode) mode = ppc_md.pci_probe_mode(bus); pr_debug(" probe mode: %d\n", mode); - if (mode == PCI_PROBE_DEVTREE) { - bus->busn_res.end = hose->last_busno; + if (mode == PCI_PROBE_DEVTREE) of_scan_bus(node, bus); - } - if (mode == PCI_PROBE_NORMAL) - hose->last_busno = bus->busn_res.end = pci_scan_child_bus(bus); + if (mode == PCI_PROBE_NORMAL) { + pci_bus_update_busn_res_end(bus, 255); + hose->last_busno = pci_scan_child_bus(bus); + pci_bus_update_busn_res_end(bus, hose->last_busno); + } /* Platform gets a chance to do some global fixups before * we proceed to resource allocation diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index a36281aa98f3..ae5ea5e04d65 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -240,7 +240,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) } bus->primary = dev->bus->number; - bus->busn_res.end = busrange[1]; + pci_bus_insert_busn_res(bus, busrange[0], busrange[1]); bus->bridge_ctl = 0; /* parse ranges property */ -- GitLab From 30aa80da43a5f23728eae1516e3a1aad40e808dd Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:12 -0700 Subject: [PATCH 1456/6849] parisc/PCI: register busn_res for root buses Add the host bridge bus number aperture to the resource list. Like the MMIO and I/O port apertures, this is used when assigning resources to hot-added devices or in the case of conflicts. [bhelgaas: changelog, set flags directly, at LBA bus_num init] CC: Kyle McMartin CC: Helge Deller CC: linux-parisc@vger.kernel.org Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/parisc/dino.c | 10 ++++++++-- drivers/parisc/lba_pci.c | 8 ++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 70517b0f94e6..ffddc4f64268 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -898,6 +898,7 @@ static int __init dino_probe(struct parisc_device *dev) LIST_HEAD(resources); struct pci_bus *bus; unsigned long hpa = dev->hpa.start; + int max; name = "Dino"; if (is_card_dino(&dev->id)) { @@ -983,6 +984,10 @@ static int __init dino_probe(struct parisc_device *dev) if (dino_dev->hba.gmmio_space.flags) pci_add_resource(&resources, &dino_dev->hba.gmmio_space); + dino_dev->hba.bus_num.start = dino_current_bus; + dino_dev->hba.bus_num.end = 255; + dino_dev->hba.bus_num.flags = IORESOURCE_BUS; + pci_add_resource(&resources, &dino_dev->hba.bus_num); /* ** It's not used to avoid chicken/egg problems ** with configuration accessor functions. @@ -998,12 +1003,13 @@ static int __init dino_probe(struct parisc_device *dev) return 0; } - bus->busn_res.end = pci_scan_child_bus(bus); + max = pci_scan_child_bus(bus); + pci_bus_update_busn_res_end(bus, max); /* This code *depends* on scanning being single threaded * if it isn't, this global bus number count will fail */ - dino_current_bus = bus->busn_res.end + 1; + dino_current_bus = max + 1; pci_bus_assign_resources(bus); pci_bus_add_devices(bus); return 0; diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index cd8f9ce8720f..4f9cf2456f4e 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -989,6 +989,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) case PAT_PBNUM: lba_dev->hba.bus_num.start = p->start; lba_dev->hba.bus_num.end = p->end; + lba_dev->hba.bus_num.flags = IORESOURCE_BUS; break; case PAT_LMMIO: @@ -1366,6 +1367,7 @@ lba_driver_probe(struct parisc_device *dev) void *tmp_obj; char *version; void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096); + int max; /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS); @@ -1502,6 +1504,8 @@ lba_driver_probe(struct parisc_device *dev) if (lba_dev->hba.gmmio_space.flags) pci_add_resource(&resources, &lba_dev->hba.gmmio_space); + pci_add_resource(&resources, &lba_dev->hba.bus_num); + dev->dev.platform_data = lba_dev; lba_bus = lba_dev->hba.hba_bus = pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start, @@ -1511,7 +1515,7 @@ lba_driver_probe(struct parisc_device *dev) return 0; } - lba_bus->busn_res.end = pci_scan_child_bus(lba_bus); + max = pci_scan_child_bus(lba_bus); /* This is in lieu of calling pci_assign_unassigned_resources() */ if (is_pdc_pat()) { @@ -1541,7 +1545,7 @@ lba_driver_probe(struct parisc_device *dev) lba_dev->flags |= LBA_FLAG_SKIP_PROBE; } - lba_next_bus = lba_res->busn_res.end + 1; + lba_next_bus = max + 1; pci_bus_add_devices(lba_bus); /* Whew! Finally done! Tell services we got this one covered. */ -- GitLab From b17c0e6f665023ae729ca112516c7b6f3b71f9d3 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1457/6849] tile/PCI: use pci_scan_root_bus instead pci_scan_bus It will update busn_res accordingly, so we get that for last_busno. Acked-by: Chris Metcalf Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- arch/tile/kernel/pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 54cc8d77c90c..87422ed7b834 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -310,6 +310,7 @@ int __init pcibios_init(void) if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) { struct pci_controller *controller = &controllers[i]; struct pci_bus *bus; + LIST_HEAD(resources); if (tile_init_irqs(i, controller)) { pr_err("PCI: Could not initialize IRQs\n"); @@ -327,7 +328,9 @@ int __init pcibios_init(void) * This is inlined in linux/pci.h and calls into * pci_scan_bus_parented() in probe.c. */ - bus = pci_scan_bus(0, controller->ops, controller); + pci_add_resource(&resources, &ioport_resource); + pci_add_resource(&resources, &iomem_resource); + bus = pci_scan_root_bus(NULL, 0, controller->ops, controller, &resources); controller->root_bus = bus; controller->last_busno = bus->busn_res.end; } -- GitLab From b7eac055c0a8f6026393a83cdf9699e9052eae25 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1458/6849] PCI: register busn_res for iov bus Insert that to tree. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/iov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e873060fb35b..74bbaf82638d 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -47,7 +47,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) if (!child) return NULL; - child->busn_res.end = busnr; + pci_bus_insert_busn_res(child, busnr, busnr); child->dev.parent = bus->bridge; rc = pci_bus_add_child(child); if (rc) { -- GitLab From bc76b7310a352be1c2ed24133e89c5df24eff05e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1459/6849] PCI: insert busn_res for child bus Now we can insert busn_res now, after all root bus's get inserted. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9f68b9d3597c..08404098080b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -755,7 +755,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, if (!child) goto out; child->primary = primary; - child->busn_res.end = subordinate; + pci_bus_insert_busn_res(child, secondary, subordinate); child->bridge_ctl = bctl; } @@ -793,6 +793,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, child = pci_add_new_bus(bus, dev, ++max); if (!child) goto out; + pci_bus_insert_busn_res(child, max, 0xff); } buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) @@ -864,7 +865,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, /* * Set the subordinate bus number to its real value. */ - child->busn_res.end = max; + pci_bus_update_busn_res_end(child, max); pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); } -- GitLab From f406384628e97618955e17e8d61e59d5ecdc9ca0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1460/6849] PCI: cpci_hotplug: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpci_hotplug_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 42f3a61db87c..111b7d94c9a9 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -294,6 +294,7 @@ int __ref cpci_configure_slot(struct slot *slot) struct pci_bus *child; unsigned char busnr, start = parent->busn_res.start; unsigned char end = parent->busn_res.end; + int max; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), @@ -312,7 +313,8 @@ int __ref cpci_configure_slot(struct slot *slot) pci_dev_put(dev); continue; } - child->busn_res.end = pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); pci_bus_size_bridges(child); } pci_dev_put(dev); -- GitLab From 6cda0fcf26df18f0e5476fbff12845cc46e1f41b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1461/6849] PCI: shpchp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/shpchp_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index d021eb031b3c..13069802b8c8 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -66,6 +66,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) struct pci_bus *child; unsigned char busnr, start = parent->busn_res.start; unsigned char end = parent->busn_res.end; + int max; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) @@ -84,7 +85,8 @@ int __ref shpchp_configure_device(struct slot *p_slot) pci_dev_put(dev); continue; } - child->busn_res.end = pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); pci_bus_size_bridges(child); } pci_configure_slot(dev); -- GitLab From 450878759aa10c6d172a0cafd5922b23a3b4547a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1462/6849] PCI: cpqhp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpqphp_pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 1c8494021a42..24716725263f 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -106,9 +106,11 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) } if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + int max; pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); - pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); } pci_dev_put(func->pci_dev); -- GitLab From d0a350fe57c0a4014a8eccf8166d7dc2e599ce5c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1463/6849] PCI: ibmhp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/ibmphp_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 4fda7e6a86a7..a62f296e8b0d 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -805,9 +805,11 @@ static int ibm_configure_device(struct pci_func *func) } } if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { + int max; pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus); child = pci_add_new_bus(func->dev->bus, func->dev, bus); - pci_do_scan_bus(child); + max = pci_do_scan_bus(child); + pci_bus_update_busn_res_end(child, max); } return 0; -- GitLab From 85019faf4a88477cc72f56b6e371955ea0bb7a2a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:51:13 -0700 Subject: [PATCH 1464/6849] PCI: sgihp: register busn_res Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/sgi_hotplug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index de573113c102..b0bb3b537bb0 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -398,11 +398,13 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) sn_io_slot_fixup(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { unsigned char sec_bus; + int max; pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_bus); new_bus = pci_add_new_bus(dev->bus, dev, sec_bus); - pci_scan_child_bus(new_bus); + max = pci_scan_child_bus(new_bus); + pci_bus_update_busn_res_end(new_bus, max); new_ppb = 1; } pci_dev_put(dev); -- GitLab From a8e4b9c101ae58cc64cda0201229d3318701a7f0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 18 May 2012 13:46:34 -0600 Subject: [PATCH 1465/6849] PCI: add generic pci_hp_add_bridge() This creates a generic pci_hp_add_bridge() that can be used by several hotplug drivers. [bhelgaas: split out from pciehp patch] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug-pci.c | 23 +++++++++++++++++++++++ drivers/pci/pci.h | 1 + 2 files changed, 24 insertions(+) diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c index d3509cdeb554..44088c4fe687 100644 --- a/drivers/pci/hotplug-pci.c +++ b/drivers/pci/hotplug-pci.c @@ -4,6 +4,29 @@ #include #include "pci.h" +int __ref pci_hp_add_bridge(struct pci_dev *dev) +{ + struct pci_bus *parent = dev->bus; + int pass, busnr, start = parent->busn_res.start; + int end = parent->busn_res.end; + + for (busnr = start; busnr <= end; busnr++) { + if (!pci_find_bus(pci_domain_nr(parent), busnr)) + break; + } + if (busnr-- > end) { + printk(KERN_ERR "No bus number available for hot-added bridge %s\n", + pci_name(dev)); + return -1; + } + for (pass = 0; pass < 2; pass++) + busnr = pci_scan_bridge(parent, dev, busnr, pass); + if (!dev->subordinate) + return -1; + + return 0; +} +EXPORT_SYMBOL_GPL(pci_hp_add_bridge); unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) { diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e4943479b234..f3e14ce8eab7 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -124,6 +124,7 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } #endif /* Functions for PCI Hotplug drivers to use */ +int pci_hp_add_bridge(struct pci_dev *dev); extern unsigned int pci_do_scan_bus(struct pci_bus *bus); #ifdef HAVE_PCI_LEGACY -- GitLab From c6da81a4d3cb8d461f77c5f61843fcc9c18b6c2c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1466/6849] PCI: pciehp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: split "add generic pci_hp_add_bridge()" into a separate patch] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/pciehp_pci.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index b898f06b588d..09cecaf450c5 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -34,29 +34,6 @@ #include "../pci.h" #include "pciehp.h" -static int __ref pciehp_add_bridge(struct pci_dev *dev) -{ - struct pci_bus *parent = dev->bus; - int pass, busnr, start = parent->busn_res.start; - int end = parent->busn_res.end; - - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), busnr)) - break; - } - if (busnr-- > end) { - err("No bus number available for hot-added bridge %s\n", - pci_name(dev)); - return -1; - } - for (pass = 0; pass < 2; pass++) - busnr = pci_scan_bridge(parent, dev, busnr, pass); - if (!dev->subordinate) - return -1; - - return 0; -} - int pciehp_configure_device(struct slot *p_slot) { struct pci_dev *dev; @@ -85,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot) if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - pciehp_add_bridge(dev); - } + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + pci_hp_add_bridge(dev); pci_dev_put(dev); } -- GitLab From 073ae10c0f8284b6c6dd9708656802507349ef91 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1467/6849] PCI: cpci_hotplug: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpci_hotplug_pci.c | 37 +++++--------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 111b7d94c9a9..dcc75c785443 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -285,44 +285,19 @@ int __ref cpci_configure_slot(struct slot *slot) for (fn = 0; fn < 8; fn++) { struct pci_dev *dev; - dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); + dev = pci_get_slot(parent, + PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - /* Find an unused bus number for the new bridge */ - struct pci_bus *child; - unsigned char busnr, start = parent->busn_res.start; - unsigned char end = parent->busn_res.end; - int max; - - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), - busnr)) - break; - } - if (busnr >= end) { - err("No free bus for hot-added bridge\n"); - pci_dev_put(dev); - continue; - } - child = pci_add_new_bus(parent, dev, busnr); - if (!child) { - err("Cannot add new bus for %s\n", - pci_name(dev)); - pci_dev_put(dev); - continue; - } - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); - pci_bus_size_bridges(child); - } + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + pci_hp_add_bridge(dev); pci_dev_put(dev); } - pci_bus_assign_resources(parent); + pci_assign_unassigned_bridge_resources(parent->self); + pci_bus_add_devices(parent); - pci_enable_bridges(parent); dbg("%s - exit", __func__); return 0; -- GitLab From 7d01f70ac6f48733d595f1a54aa7c4d2ae3fef0d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1468/6849] PCI: shpchp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/shpchp_pci.c | 47 ++++++++++---------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 13069802b8c8..c627ed9957d1 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -37,9 +37,10 @@ int __ref shpchp_configure_device(struct slot *p_slot) { struct pci_dev *dev; - struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; - int num, fn; struct controller *ctrl = p_slot->ctrl; + struct pci_dev *bridge = ctrl->pci_dev; + struct pci_bus *parent = bridge->subordinate; + int num, fn; dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); if (dev) { @@ -61,41 +62,23 @@ int __ref shpchp_configure_device(struct slot *p_slot) if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - /* Find an unused bus number for the new bridge */ - struct pci_bus *child; - unsigned char busnr, start = parent->busn_res.start; - unsigned char end = parent->busn_res.end; - int max; - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), - busnr)) - break; - } - if (busnr > end) { - ctrl_err(ctrl, - "No free bus for hot-added bridge\n"); - pci_dev_put(dev); - continue; - } - child = pci_add_new_bus(parent, dev, busnr); - if (!child) { - ctrl_err(ctrl, "Cannot add new bus for %s\n", - pci_name(dev)); - pci_dev_put(dev); - continue; - } - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); - pci_bus_size_bridges(child); - } + (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) + pci_hp_add_bridge(dev); + pci_dev_put(dev); + } + + pci_assign_unassigned_bridge_resources(bridge); + + for (fn = 0; fn < 8; fn++) { + dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); + if (!dev) + continue; pci_configure_slot(dev); pci_dev_put(dev); } - pci_bus_assign_resources(parent); pci_bus_add_devices(parent); - pci_enable_bridges(parent); + return 0; } -- GitLab From 04de975e7840e6d9da3ef44ab414f3ee1b98d611 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1469/6849] PCI: cpqhp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/cpqphp_pci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 24716725263f..09801c6945ce 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -83,7 +83,6 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) { - unsigned char bus; struct pci_bus *child; int num; @@ -106,11 +105,10 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) } if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - int max; - pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); - child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); + pci_hp_add_bridge(func->pci_dev); + child = func->pci_dev->subordinate; + if (child) + pci_bus_add_devices(child); } pci_dev_put(func->pci_dev); -- GitLab From 2d7abf32925f1a8aeeb37234c8ea7590ebbe62be Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1470/6849] PCI: ibmhp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/ibmphp_core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index a62f296e8b0d..7dccad5fc891 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -775,7 +775,6 @@ static u8 bus_structure_fixup(u8 busno) static int ibm_configure_device(struct pci_func *func) { - unsigned char bus; struct pci_bus *child; int num; int flag = 0; /* this is to make sure we don't double scan the bus, @@ -805,11 +804,10 @@ static int ibm_configure_device(struct pci_func *func) } } if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { - int max; - pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus); - child = pci_add_new_bus(func->dev->bus, func->dev, bus); - max = pci_do_scan_bus(child); - pci_bus_update_busn_res_end(child, max); + pci_hp_add_bridge(func->dev); + child = func->dev->subordinate; + if (child) + pci_bus_add_devices(child); } return 0; -- GitLab From 69ba29b9f91317b0cb8a4891c0cc6270a6f77ec9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1471/6849] PCI: sgihp: use generic pci_hp_add_bridge() Use the new generic pci_hp_add_bridge() interface. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/sgi_hotplug.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index b0bb3b537bb0..f64ca92253da 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -397,15 +397,11 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) else sn_io_slot_fixup(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - unsigned char sec_bus; - int max; - pci_read_config_byte(dev, PCI_SECONDARY_BUS, - &sec_bus); - new_bus = pci_add_new_bus(dev->bus, dev, - sec_bus); - max = pci_scan_child_bus(new_bus); - pci_bus_update_busn_res_end(new_bus, max); - new_ppb = 1; + pci_hp_add_bridge(dev); + if (dev->subordinate) { + new_bus = dev->subordinate; + new_ppb = 1; + } } pci_dev_put(dev); } -- GitLab From 06aef8cec7563c40c7d7501d13ec1ed12f5e495b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 17 May 2012 18:58:41 -0700 Subject: [PATCH 1472/6849] PCI: hotplug: remove pci_do_scan_bus() All callers of pci_do_scan_bus() are gone, so remove it. Note that pci_do_scan_bus() was exported, so out-of-tree modules could depend on it. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug-pci.c | 15 --------------- drivers/pci/pci.h | 1 - 2 files changed, 16 deletions(-) diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c index 44088c4fe687..6258dc260d9f 100644 --- a/drivers/pci/hotplug-pci.c +++ b/drivers/pci/hotplug-pci.c @@ -27,18 +27,3 @@ int __ref pci_hp_add_bridge(struct pci_dev *dev) return 0; } EXPORT_SYMBOL_GPL(pci_hp_add_bridge); - -unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) -{ - unsigned int max; - - max = pci_scan_child_bus(bus); - - /* - * Make the discovered devices available. - */ - pci_bus_add_devices(bus); - - return max; -} -EXPORT_SYMBOL(pci_do_scan_bus); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index f3e14ce8eab7..1c56ea8110b1 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -125,7 +125,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } /* Functions for PCI Hotplug drivers to use */ int pci_hp_add_bridge(struct pci_dev *dev); -extern unsigned int pci_do_scan_bus(struct pci_bus *bus); #ifdef HAVE_PCI_LEGACY extern void pci_create_legacy_files(struct pci_bus *bus); -- GitLab From a276400d14bb5b98a5db1d87bbee7b1621abe4a1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 30 May 2012 12:24:59 +0200 Subject: [PATCH 1473/6849] USB: option: use usb_{get,set}_serial_data Use usb_{get,set}_serial_data to access usb-serial data. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 1aae9028cd0b..6cb40ec52532 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1347,12 +1347,15 @@ static int option_probe(struct usb_serial *serial, serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA) return -ENODEV; - data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; data->send_setup = option_send_setup; spin_lock_init(&data->susp_lock); data->private = (void *)id->driver_info; + + usb_set_serial_data(serial, data); + return 0; } @@ -1419,8 +1422,7 @@ static void option_instat_callback(struct urb *urb) static int option_send_setup(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - struct usb_wwan_intf_private *intfdata = - (struct usb_wwan_intf_private *) serial->private; + struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); struct option_port_private *portdata; int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; int val = 0; -- GitLab From 378fac2a46decbcd16b42044303ba8a1a3f8001e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 30 May 2012 12:25:00 +0200 Subject: [PATCH 1474/6849] USB: option: clean up probe coding style Clean up option probe by introducing intermediate variables and fixing up comments. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 38 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6ff37e67adfa..ccf7f3c9a7c6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1306,33 +1306,41 @@ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; + struct usb_interface_descriptor *iface_desc = + &serial->interface->cur_altsetting->desc; + struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; - /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ - if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && - serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && - serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) + /* + * D-Link DWM 652 still exposes CD-Rom emulation interface in modem + * mode. + */ + if (dev_desc->idVendor == DLINK_VENDOR_ID && + dev_desc->idProduct == DLINK_PRODUCT_DWM_652 && + iface_desc->bInterfaceClass == 0x08) return -ENODEV; /* Bandrich modem and AT command interface is 0xff */ - if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || - serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && - serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) + if ((dev_desc->idVendor == BANDRICH_VENDOR_ID || + dev_desc->idVendor == PIRELLI_VENDOR_ID) && + iface_desc->bInterfaceClass != 0xff) return -ENODEV; - - /* Don't bind reserved interfaces (like network ones) which often have + /* + * Don't bind reserved interfaces (like network ones) which often have * the same class/subclass/protocol as the serial interfaces. Look at * the Windows driver .INF files for reserved interface numbers. */ if (is_blacklisted( - serial->interface->cur_altsetting->desc.bInterfaceNumber, + iface_desc->bInterfaceNumber, OPTION_BLACKLIST_RESERVED_IF, (const struct option_blacklist_info *) id->driver_info)) return -ENODEV; - - /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ - if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID && - serial->dev->descriptor.idProduct == SAMSUNG_PRODUCT_GT_B3730 && - serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA) + /* + * Don't bind network interface on Samsung GT-B3730, it is handled by + * a separate module. + */ + if (dev_desc->idVendor == SAMSUNG_VENDOR_ID && + dev_desc->idProduct == SAMSUNG_PRODUCT_GT_B3730 && + iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) return -ENODEV; data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); -- GitLab From e463c6dda8f5ee0baa6a5400e45d300287339536 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 30 May 2012 12:25:01 +0200 Subject: [PATCH 1475/6849] USB: option: handle send_setup blacklisting at probe Determine whether to use send_setup at probe time rather than at every call to send_setup. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 40 +++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ccf7f3c9a7c6..9520c4c54743 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1276,6 +1276,10 @@ static struct usb_serial_driver * const serial_drivers[] = { static bool debug; +struct option_private { + u8 bInterfaceNumber; +}; + module_usb_serial_driver(serial_drivers, option_ids); static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, @@ -1306,6 +1310,7 @@ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; + struct option_private *priv; struct usb_interface_descriptor *iface_desc = &serial->interface->cur_altsetting->desc; struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; @@ -1346,9 +1351,22 @@ static int option_probe(struct usb_serial *serial, data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; - data->send_setup = option_send_setup; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + kfree(data); + return -ENOMEM; + } + + priv->bInterfaceNumber = iface_desc->bInterfaceNumber; + data->private = priv; + + if (!is_blacklisted(iface_desc->bInterfaceNumber, + OPTION_BLACKLIST_SENDSETUP, + (struct option_blacklist_info *)id->driver_info)) { + data->send_setup = option_send_setup; + } spin_lock_init(&data->susp_lock); - data->private = (void *)id->driver_info; usb_set_serial_data(serial, data); @@ -1357,11 +1375,13 @@ static int option_probe(struct usb_serial *serial, static void option_release(struct usb_serial *serial) { - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); + struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); + struct option_private *priv = intfdata->private; usb_wwan_release(serial); kfree(priv); + kfree(intfdata); } static void option_instat_callback(struct urb *urb) @@ -1429,16 +1449,10 @@ static int option_send_setup(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); + struct option_private *priv = intfdata->private; struct usb_wwan_port_private *portdata; - int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; int val = 0; - if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP, - (struct option_blacklist_info *) intfdata->private)) { - dbg("No send_setup on blacklisted interface #%d\n", ifNum); - return -EIO; - } - portdata = usb_get_serial_port_data(port); if (portdata->dtr_state) @@ -1446,9 +1460,9 @@ static int option_send_setup(struct usb_serial_port *port) if (portdata->rts_state) val |= 0x02; - return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); + return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + 0x22, 0x21, val, priv->bInterfaceNumber, NULL, + 0, USB_CTRL_SET_TIMEOUT); } MODULE_AUTHOR(DRIVER_AUTHOR); -- GitLab From fc8ef481df1bd6dac5d9c44b744f8050fcb6a5fe Mon Sep 17 00:00:00 2001 From: Jeffrin Jose Date: Wed, 30 May 2012 18:05:47 +0530 Subject: [PATCH 1476/6849] USB: storage: fixed space issues in coding style. Fixed space issues in coding style found by checkpatch.pl tool in drivers/usb/storage/protocol.c Signed-off-by: Jeffrin Jose Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/protocol.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 82dd834709c7..5dfb4c36a1b0 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -66,7 +66,7 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ - for (; srb->cmd_len<12; srb->cmd_len++) + for (; srb->cmd_len < 12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; /* send the command to the transport layer */ @@ -76,14 +76,14 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us) { /* fix some commands -- this is a form of mode translation - * UFI devices only accept 12 byte long commands + * UFI devices only accept 12 byte long commands * * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ /* Pad the ATAPI command with zeros */ - for (; srb->cmd_len<12; srb->cmd_len++) + for (; srb->cmd_len < 12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; /* set command length to 12 bytes (this affects the transport layer) */ -- GitLab From 169dc388685f8a1c1e09546882a114ac850a5d6b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 11 Jun 2012 12:18:30 +0300 Subject: [PATCH 1477/6849] misc: mei: Disable MSI when IRQ registration fails Since MSI is enabled right before that, we should disable it when registration fails. Signed-off-by: Samuel Ortiz Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index a5a17e78a96c..7de13891e49e 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -992,7 +992,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); - goto unmap_memory; + goto disable_msi; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { @@ -1023,8 +1023,8 @@ release_irq: mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); +disable_msi: pci_disable_msi(pdev); -unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: kfree(dev); -- GitLab From 49fbd3f1c3a67b99c053600a1cd7e5d0be48bed6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 11 Jun 2012 12:18:31 +0300 Subject: [PATCH 1478/6849] misc: mei: set WDIOF_ALARMONLY on mei watchdog mei watchdog doesn't reboot the system it only produces event therefore mark it as WDIOF_ALARMONLY. This patch depends on: commit 2bbeed016dd96045ec82c3a309afddcc3a0db1d2 Author: Alan Cox watchdog: Add a flag to indicate the watchdog doesn't reboot things Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/wd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 6be5605707b4..e2ec0505eb5c 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -341,7 +341,7 @@ static const struct watchdog_ops wd_ops = { }; static const struct watchdog_info wd_info = { .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING, + .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY, }; static struct watchdog_device amt_wd_dev = { -- GitLab From 7e97243c2080ecae7129e83635227fdebd4feef6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 25 Apr 2012 17:22:37 -0700 Subject: [PATCH 1479/6849] USB: rename the usb misc class from "usb" to "usbmisc" This class was not named properly years ago, and it turns out that tools like udev can't properly see the devices in this class after booting due to the fact that there is a bus with the same name in the system. Changing this to "usbmisc" fixes this problem, and it solves the problem for the future when we want to unify classes and busses. Reported-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index e673b26e598f..e5387a47ef6f 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -92,7 +92,7 @@ static int init_usb_class(void) } kref_init(&usb_class->kref); - usb_class->class = class_create(THIS_MODULE, "usb"); + usb_class->class = class_create(THIS_MODULE, "usbmisc"); if (IS_ERR(usb_class->class)) { result = IS_ERR(usb_class->class); printk(KERN_ERR "class_create failed for usb devices\n"); -- GitLab From 638f293307b5787b69bf0a0bc915aed491efbec9 Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Tue, 22 May 2012 21:58:40 -0600 Subject: [PATCH 1480/6849] PCI: acpiphp: fix function 0 leak when disabling a slot Previously, we acquired two references to function 0, but only released one. [bhelgaas: split this out from "remove all functions" fix] Signed-off-by: Amos Kong Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 62d0ae4dfcad..c8f999102765 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -893,6 +893,7 @@ static int disable_device(struct acpiphp_slot *slot) pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); if (!pdev) goto err_exit; + pci_dev_put(pdev); list_for_each_entry(func, &slot->funcs, sibling) { if (func->bridge) { -- GitLab From ce29ca3ea40744f24c2b5d88431e8ac566d257cc Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Wed, 23 May 2012 10:20:35 -0600 Subject: [PATCH 1481/6849] PCI: acpiphp: remove all functions in slot, even without ACPI _EJx When we add a device with acpiphp, we enumerate all functions in the slot with pci_scan_slot(), regardless of whether they have associated ACPI methods such as _EJ0. When removing the device, we previously removed only the functions with those ACPI methods. This patch makes the remove symmetric with the add: we remove all functions in the slot, whether they have associated ACPI methods or not. With qemu-kvm and SeaBIOS, we can build a multi-function device where only function 0 has _EJ0 and _ADR (see bugzilla below). Removing and re-adding that slot (including all functions of the device) works correctly with Windows guests. This patch makes it also work in Linux guests. [bhelgaas: restructure loop iteration, pull out of slot->funcs loop] Reference: https://bugzilla.kernel.org/show_bug.cgi?id=43219 Signed-off-by: Amos Kong Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 42 +++++++++++++++++++++++------- drivers/pci/search.c | 2 ++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index c8f999102765..73af3374e915 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -878,6 +878,24 @@ static void disable_bridges(struct pci_bus *bus) } } +/* return first device in slot, acquiring a reference on it */ +static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) +{ + struct pci_bus *bus = slot->bridge->pci_bus; + struct pci_dev *dev; + struct pci_dev *ret = NULL; + + down_read(&pci_bus_sem); + list_for_each_entry(dev, &bus->devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot->device) { + ret = pci_dev_get(dev); + break; + } + up_read(&pci_bus_sem); + + return ret; +} + /** * disable_device - disable a slot * @slot: ACPI PHP slot @@ -902,18 +920,22 @@ static int disable_device(struct acpiphp_slot *slot) (u32)1, NULL, NULL); func->bridge = NULL; } + } - pdev = pci_get_slot(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, func->function)); - if (pdev) { - pci_stop_bus_device(pdev); - if (pdev->subordinate) { - disable_bridges(pdev->subordinate); - pci_disable_device(pdev); - } - __pci_remove_bus_device(pdev); - pci_dev_put(pdev); + /* + * enable_device() enumerates all functions in this device via + * pci_scan_slot(), whether they have associated ACPI hotplug + * methods (_EJ0, etc.) or not. Therefore, we remove all functions + * here. + */ + while ((pdev = dev_in_slot(slot))) { + pci_stop_bus_device(pdev); + if (pdev->subordinate) { + disable_bridges(pdev->subordinate); + pci_disable_device(pdev); } + __pci_remove_bus_device(pdev); + pci_dev_put(pdev); } list_for_each_entry(func, &slot->funcs, sibling) { diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 9d75dc8ca602..993d4a0a2469 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -15,6 +15,8 @@ #include "pci.h" DECLARE_RWSEM(pci_bus_sem); +EXPORT_SYMBOL_GPL(pci_bus_sem); + /* * find the upstream PCIe-to-PCI bridge of a PCI device * if the device is PCIE, return NULL -- GitLab From 81df2d594340dcb6d1a02191976be88a1ca8120c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 18 May 2012 21:27:43 +0200 Subject: [PATCH 1482/6849] USB: allow match on bInterfaceNumber MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some composite USB devices provide multiple interfaces with different functions, all using "vendor-specific" for class/subclass/protocol. Another OS use interface numbers to match the driver and interface. It seems these devices are designed with that in mind - using static interface numbers for the different functions. This adds support for matching against the bInterfaceNumber, allowing such devices to be supported without having to resort to testing against interface number whitelists and/or blacklists in the probe. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 9 +++++++-- drivers/usb/core/message.c | 5 +++-- drivers/usb/core/sysfs.c | 5 +++-- include/linux/mod_devicetable.h | 7 +++++++ include/linux/usb.h | 16 ++++++++++++++++ scripts/mod/file2alias.c | 5 ++++- 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f536aebc958e..23d7bbd199a5 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -622,14 +622,15 @@ int usb_match_one_id(struct usb_interface *interface, if (!usb_match_device(dev, id)) return 0; - /* The interface class, subclass, and protocol should never be + /* The interface class, subclass, protocol and number should never be * checked for a match if the device class is Vendor Specific, * unless the match record specifies the Vendor ID. */ if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | - USB_DEVICE_ID_MATCH_INT_PROTOCOL))) + USB_DEVICE_ID_MATCH_INT_PROTOCOL | + USB_DEVICE_ID_MATCH_INT_NUMBER))) return 0; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && @@ -644,6 +645,10 @@ int usb_match_one_id(struct usb_interface *interface, (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) return 0; + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) && + (id->bInterfaceNumber != intf->desc.bInterfaceNumber)) + return 0; + return 1; } EXPORT_SYMBOL_GPL(usb_match_one_id); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b548cf1dbc62..ca7fc392fd9e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1559,7 +1559,7 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) if (add_uevent_var(env, "MODALIAS=usb:" - "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", + "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X", le16_to_cpu(usb_dev->descriptor.idVendor), le16_to_cpu(usb_dev->descriptor.idProduct), le16_to_cpu(usb_dev->descriptor.bcdDevice), @@ -1568,7 +1568,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) usb_dev->descriptor.bDeviceProtocol, alt->desc.bInterfaceClass, alt->desc.bInterfaceSubClass, - alt->desc.bInterfaceProtocol)) + alt->desc.bInterfaceProtocol, + alt->desc.bInterfaceNumber)) return -ENOMEM; return 0; diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 9a56e3adf476..777f03c37725 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -840,7 +840,7 @@ static ssize_t show_modalias(struct device *dev, alt = intf->cur_altsetting; return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" - "ic%02Xisc%02Xip%02X\n", + "ic%02Xisc%02Xip%02Xin%02X\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), le16_to_cpu(udev->descriptor.bcdDevice), @@ -849,7 +849,8 @@ static ssize_t show_modalias(struct device *dev, udev->descriptor.bDeviceProtocol, alt->desc.bInterfaceClass, alt->desc.bInterfaceSubClass, - alt->desc.bInterfaceProtocol); + alt->desc.bInterfaceProtocol, + alt->desc.bInterfaceNumber); } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 5db93821f9c7..7771d453e5f3 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -78,6 +78,9 @@ struct ieee1394_device_id { * of a given interface; other interfaces may support other classes. * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass. * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass. + * @bInterfaceNumber: Number of interface; composite devices may use + * fixed interface numbers to differentiate between vendor-specific + * interfaces. * @driver_info: Holds information used by the driver. Usually it holds * a pointer to a descriptor understood by the driver, or perhaps * device flags. @@ -115,6 +118,9 @@ struct usb_device_id { __u8 bInterfaceSubClass; __u8 bInterfaceProtocol; + /* Used for vendor-specific interface matches */ + __u8 bInterfaceNumber; + /* not matched against */ kernel_ulong_t driver_info; }; @@ -130,6 +136,7 @@ struct usb_device_id { #define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 +#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400 #define HID_ANY_ID (~0) #define HID_BUS_ANY 0xffff diff --git a/include/linux/usb.h b/include/linux/usb.h index dea39dc551d4..f717fbdaee8e 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -776,6 +776,22 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size) .idProduct = (prod), \ .bInterfaceProtocol = (pr) +/** + * USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * @num: bInterfaceNumber value + * + * This macro is used to create a struct usb_device_id that matches a + * specific interface number of devices. + */ +#define USB_DEVICE_INTERFACE_NUMBER(vend, prod, num) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_INT_NUMBER, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bInterfaceNumber = (num) + /** * USB_DEVICE_INFO - macro used to describe a class of usb devices * @cl: bDeviceClass value diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5759751a1f61..7ed6864ef65b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id, } /* USB is special because the bcdDevice can be matched against a numeric range */ -/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */ +/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ static void do_usb_entry(struct usb_device_id *id, unsigned int bcdDevice_initial, int bcdDevice_initial_digits, unsigned char range_lo, unsigned char range_hi, @@ -210,6 +210,9 @@ static void do_usb_entry(struct usb_device_id *id, ADD(alias, "ip", id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL, id->bInterfaceProtocol); + ADD(alias, "in", + id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, + id->bInterfaceNumber); add_wildcard(alias); buf_printf(&mod->dev_table_buf, -- GitLab From 33a03aadb52fa05d28aba6d8f0c03c7b3b905897 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:54:54 +0000 Subject: [PATCH 1483/6849] dcbnl: Prepare framework to shorten handling functions There is no need to allocate and send the reply message in each handling function separately. Instead, the reply skb can be allocated and sent in dcb_doit() directly. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 656c7c75b192..5520e431b072 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -196,6 +196,34 @@ static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { static LIST_HEAD(dcb_app_list); static DEFINE_SPINLOCK(dcb_lock); +static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, + u32 flags, struct nlmsghdr **nlhp) +{ + struct sk_buff *skb; + struct dcbmsg *dcb; + struct nlmsghdr *nlh; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return NULL; + + nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags); + if (!nlh) { + /* header should always fit, allocation must be buggy */ + BUG(); + } + + dcb = nlmsg_data(nlh); + dcb->dcb_family = AF_UNSPEC; + dcb->cmd = cmd; + dcb->dcb_pad = 0; + + if (nlhp) + *nlhp = nlh; + + return skb; +} + /* standard netlink reply call */ static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, u32 seq, u16 flags) @@ -1922,6 +1950,19 @@ static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, return err; } +struct reply_func { + /* reply netlink message type */ + int type; + + /* function to fill message contents */ + int (*cb)(struct net_device *, struct nlmsghdr *, u32, + struct nlattr **, struct sk_buff *); +}; + +static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = { + /* FIXME: add reply defs */ +}; + static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); @@ -1930,6 +1971,9 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct nlattr *tb[DCB_ATTR_MAX + 1]; u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = -EINVAL; + struct sk_buff *reply_skb; + struct nlmsghdr *reply_nlh; + const struct reply_func *fn; if (!net_eq(net, &init_net)) return -EINVAL; @@ -1939,6 +1983,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (ret < 0) return ret; + if (dcb->cmd > DCB_CMD_MAX) + return -EINVAL; + + /* check if a reply function has been defined for the command */ + fn = &reply_funcs[dcb->cmd]; + if (!fn->cb) + return -EOPNOTSUPP; + if (!tb[DCB_ATTR_IFNAME]) return -EINVAL; @@ -1949,6 +2001,25 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (!netdev->dcbnl_ops) goto errout; + reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq, + nlh->nlmsg_flags, &reply_nlh); + if (!reply_skb) { + ret = -ENOBUFS; + goto out; + } + + ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb); + if (ret < 0) { + nlmsg_free(reply_skb); + goto out; + } + + nlmsg_end(reply_skb, reply_nlh); + + ret = rtnl_unicast(reply_skb, &init_net, pid); + if (ret) + goto out; + switch (dcb->cmd) { case DCB_CMD_GSTATE: ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, -- GitLab From 7be994138b188387691322921c08e19bddf6d3c5 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:54:55 +0000 Subject: [PATCH 1484/6849] dcbnl: Shorten all command handling functions Allocating and sending the skb in dcb_doit() allows for much shorter and cleaner command handling functions. The huge switch statement is replaced with an array based definition of the handling function and reply message type. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 722 ++++++++++++------------------------------------ 1 file changed, 172 insertions(+), 550 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 5520e431b072..5e392b85d48d 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -261,27 +261,20 @@ err: return ret; } -static int dcbnl_getstate(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret = -EINVAL; - /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ if (!netdev->dcbnl_ops->getstate) - return ret; - - ret = dcbnl_reply(netdev->dcbnl_ops->getstate(netdev), RTM_GETDCB, - DCB_CMD_GSTATE, DCB_ATTR_STATE, pid, seq, flags); + return -EINVAL; - return ret; + return nla_put_u8(skb, DCB_ATTR_STATE, + netdev->dcbnl_ops->getstate(netdev)); } -static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; u8 value; int ret = -EINVAL; @@ -295,19 +288,9 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest); if (ret) - goto err_out; - - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - goto err_out; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_PFC_GCFG; + goto err; - nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PFC_CFG); + nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG); if (!nest) goto err; @@ -320,76 +303,35 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); - ret = nla_put_u8(dcbnl_skb, i, value); - + ret = nla_put_u8(skb, i, value); if (ret) { - nla_nest_cancel(dcbnl_skb, nest); + nla_nest_cancel(skb, nest); goto err; } } - nla_nest_end(dcbnl_skb, nest); - - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - goto err_out; + nla_nest_end(skb, nest); return 0; -nlmsg_failure: err: - kfree_skb(dcbnl_skb); -err_out: return -EINVAL; } -static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; u8 perm_addr[MAX_ADDR_LEN]; - int ret = -EINVAL; if (!netdev->dcbnl_ops->getpermhwaddr) - return ret; - - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - goto err_out; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_GPERM_HWADDR; + return -EINVAL; netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); - ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), - perm_addr); - - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - goto err_out; - - return 0; - -nlmsg_failure: - kfree_skb(dcbnl_skb); -err_out: - return -EINVAL; + return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr); } -static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; u8 value; int ret = -EINVAL; @@ -404,19 +346,9 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, if (ret) goto err_out; - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - goto err_out; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_GCAP; - - nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP); + nest = nla_nest_start(skb, DCB_ATTR_CAP); if (!nest) - goto err; + goto err_out; if (data[DCB_CAP_ATTR_ALL]) getall = 1; @@ -426,36 +358,23 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, continue; if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { - ret = nla_put_u8(dcbnl_skb, i, value); - + ret = nla_put_u8(skb, i, value); if (ret) { - nla_nest_cancel(dcbnl_skb, nest); - goto err; + nla_nest_cancel(skb, nest); + goto err_out; } } } - nla_nest_end(dcbnl_skb, nest); - - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - goto err_out; + nla_nest_end(skb, nest); return 0; -nlmsg_failure: -err: - kfree_skb(dcbnl_skb); err_out: return -EINVAL; } -static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; u8 value; int ret = -EINVAL; @@ -472,22 +391,10 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, goto err_out; } - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) { - ret = -EINVAL; - goto err_out; - } - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_GNUMTCS; - - nest = nla_nest_start(dcbnl_skb, DCB_ATTR_NUMTCS); + nest = nla_nest_start(skb, DCB_ATTR_NUMTCS); if (!nest) { ret = -EINVAL; - goto err; + goto err_out; } if (data[DCB_NUMTCS_ATTR_ALL]) @@ -499,37 +406,25 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); if (!ret) { - ret = nla_put_u8(dcbnl_skb, i, value); - + ret = nla_put_u8(skb, i, value); if (ret) { - nla_nest_cancel(dcbnl_skb, nest); + nla_nest_cancel(skb, nest); ret = -EINVAL; - goto err; + goto err_out; } } else { - goto err; + goto err_out; } } - nla_nest_end(dcbnl_skb, nest); - - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) { - ret = -EINVAL; - goto err_out; - } + nla_nest_end(skb, nest); return 0; -nlmsg_failure: -err: - kfree_skb(dcbnl_skb); err_out: return ret; } -static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; int ret = -EINVAL; @@ -542,10 +437,8 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], dcbnl_numtcs_nest); - if (ret) { - ret = -EINVAL; - goto err; - } + if (ret) + return -EINVAL; for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { if (data[i] == NULL) @@ -554,59 +447,41 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, value = nla_get_u8(data[i]); ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); - if (ret) - goto operr; + break; } -operr: - ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS, - DCB_ATTR_NUMTCS, pid, seq, flags); - -err: - return ret; + return nla_put_u8(skb, DCB_ATTR_NUMTCS, !!ret); } -static int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret = -EINVAL; - if (!netdev->dcbnl_ops->getpfcstate) - return ret; - - ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB, - DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE, - pid, seq, flags); + return -EINVAL; - return ret; + return nla_put_u8(skb, DCB_ATTR_PFC_STATE, + netdev->dcbnl_ops->getpfcstate(netdev)); } -static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret = -EINVAL; u8 value; if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) - return ret; + return -EINVAL; value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); netdev->dcbnl_ops->setpfcstate(netdev, value); - ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, - pid, seq, flags); - - return ret; + return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 0); } -static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *app_nest; struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; u16 id; @@ -645,51 +520,34 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, up = dcb_getapp(netdev, &app); } - /* send this back */ - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - goto out; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_GAPP; - - app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); + app_nest = nla_nest_start(skb, DCB_ATTR_APP); if (!app_nest) - goto out_cancel; + goto out; - ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); + ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype); if (ret) goto out_cancel; - ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); + ret = nla_put_u16(skb, DCB_APP_ATTR_ID, id); if (ret) goto out_cancel; - ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); + ret = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, up); if (ret) goto out_cancel; - nla_nest_end(dcbnl_skb, app_nest); - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - goto nlmsg_failure; + nla_nest_end(skb, app_nest); goto out; out_cancel: - nla_nest_cancel(dcbnl_skb, app_nest); -nlmsg_failure: - kfree_skb(dcbnl_skb); + nla_nest_cancel(skb, app_nest); out: return ret; } -static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { int err, ret = -EINVAL; u16 id; @@ -730,19 +588,15 @@ static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, err = dcb_setapp(netdev, &app); } - ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, - pid, seq, flags); + ret = nla_put_u8(skb, DCB_ATTR_APP, ret); dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); out: return ret; } -static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags, int dir) +static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, + struct nlattr **tb, struct sk_buff *skb, int dir) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *pg_nest, *param_nest, *data; struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; @@ -764,19 +618,9 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, if (ret) goto err_out; - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - goto err_out; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = (dir) ? DCB_CMD_PGRX_GCFG : DCB_CMD_PGTX_GCFG; - - pg_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PG_CFG); + pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG); if (!pg_nest) - goto err; + goto err_out; if (pg_tb[DCB_PG_ATTR_TC_ALL]) getall = 1; @@ -794,7 +638,7 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, if (ret) goto err_pg; - param_nest = nla_nest_start(dcbnl_skb, i); + param_nest = nla_nest_start(skb, i); if (!param_nest) goto err_pg; @@ -817,33 +661,33 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, if (param_tb[DCB_TC_ATTR_PARAM_PGID] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { - ret = nla_put_u8(dcbnl_skb, + ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid); if (ret) goto err_param; } if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { - ret = nla_put_u8(dcbnl_skb, + ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); if (ret) goto err_param; } if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { - ret = nla_put_u8(dcbnl_skb, + ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); if (ret) goto err_param; } if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { - ret = nla_put_u8(dcbnl_skb, DCB_TC_ATTR_PARAM_BW_PCT, + ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct); if (ret) goto err_param; } - nla_nest_end(dcbnl_skb, param_nest); + nla_nest_end(skb, param_nest); } if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) @@ -866,66 +710,53 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, netdev->dcbnl_ops->getpgbwgcfgtx(netdev, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); } - ret = nla_put_u8(dcbnl_skb, i, tc_pct); + ret = nla_put_u8(skb, i, tc_pct); if (ret) goto err_pg; } - nla_nest_end(dcbnl_skb, pg_nest); - - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - goto err_out; + nla_nest_end(skb, pg_nest); return 0; err_param: - nla_nest_cancel(dcbnl_skb, param_nest); + nla_nest_cancel(skb, param_nest); err_pg: - nla_nest_cancel(dcbnl_skb, pg_nest); -nlmsg_failure: -err: - kfree_skb(dcbnl_skb); + nla_nest_cancel(skb, pg_nest); err_out: ret = -EINVAL; return ret; } -static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 0); + return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 0); } -static int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 1); + return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 1); } -static int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret = -EINVAL; u8 value; if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) - return ret; + return -EINVAL; value = nla_get_u8(tb[DCB_ATTR_STATE]); - ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value), - RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE, - pid, seq, flags); - - return ret; + return nla_put_u8(skb, DCB_ATTR_STATE, + netdev->dcbnl_ops->setstate(netdev, value)); } -static int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; int i; @@ -949,29 +780,29 @@ static int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); } - ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SCFG, DCB_ATTR_PFC_CFG, - pid, seq, flags); + return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0); err: return ret; } -static int dcbnl_setall(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { int ret = -EINVAL; if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) return ret; - ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB, - DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags); + ret = nla_put_u8(skb, DCB_ATTR_SET_ALL, + netdev->dcbnl_ops->setall(netdev)); dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0); return ret; } -static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags, int dir) +static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb, + int dir) { struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; @@ -1054,32 +885,27 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, } } - ret = dcbnl_reply(0, RTM_SETDCB, - (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), - DCB_ATTR_PG_CFG, pid, seq, flags); + ret = nla_put_u8(skb, (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 0); err: return ret; } -static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 0); + return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 0); } -static int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 1); + return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 1); } -static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *bcn_nest; struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; u8 value_byte; @@ -1098,19 +924,9 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, if (ret) goto err_out; - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - goto err_out; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_BCN_GCFG; - - bcn_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_BCN); + bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN); if (!bcn_nest) - goto err; + goto err_out; if (bcn_tb[DCB_BCN_ATTR_ALL]) getall = true; @@ -1121,7 +937,7 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, &value_byte); - ret = nla_put_u8(dcbnl_skb, i, value_byte); + ret = nla_put_u8(skb, i, value_byte); if (ret) goto err_bcn; } @@ -1132,33 +948,24 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, netdev->dcbnl_ops->getbcncfg(netdev, i, &value_integer); - ret = nla_put_u32(dcbnl_skb, i, value_integer); + ret = nla_put_u32(skb, i, value_integer); if (ret) goto err_bcn; } - nla_nest_end(dcbnl_skb, bcn_nest); - - nlmsg_end(dcbnl_skb, nlh); - - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - goto err_out; + nla_nest_end(skb, bcn_nest); return 0; err_bcn: - nla_nest_cancel(dcbnl_skb, bcn_nest); -nlmsg_failure: -err: - kfree_skb(dcbnl_skb); + nla_nest_cancel(skb, bcn_nest); err_out: ret = -EINVAL; return ret; } -static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; int i; @@ -1192,8 +999,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, i, value_int); } - ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_BCN_SCFG, DCB_ATTR_BCN, - pid, seq, flags); + ret = nla_put_u8(skb, DCB_ATTR_BCN, 0); err: return ret; } @@ -1618,8 +1424,8 @@ EXPORT_SYMBOL(dcbnl_cee_notify); * No attempt is made to reconcile the case where only part of the * cmd can be completed. */ -static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; @@ -1677,54 +1483,24 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, } err: - dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE, - pid, seq, flags); + err = nla_put_u8(skb, DCB_ATTR_IEEE, err); dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); return err; } -static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_ieee_get(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct net *net = dev_net(netdev); - struct sk_buff *skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; - int err; if (!ops) return -EOPNOTSUPP; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!skb) - return -ENOBUFS; - - nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - if (nlh == NULL) { - nlmsg_free(skb); - return -EMSGSIZE; - } - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_IEEE_GET; - - err = dcbnl_ieee_fill(skb, netdev); - - if (err < 0) { - nlmsg_cancel(skb, nlh); - kfree_skb(skb); - } else { - nlmsg_end(skb, nlh); - err = rtnl_unicast(skb, net, pid); - } - - return err; + return dcbnl_ieee_fill(skb, netdev); } -static int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; @@ -1761,32 +1537,26 @@ static int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb, } err: - dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_DEL, DCB_ATTR_IEEE, - pid, seq, flags); + err = nla_put_u8(skb, DCB_ATTR_IEEE, err); dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); return err; } /* DCBX configuration */ -static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getdcbx(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret; - if (!netdev->dcbnl_ops->getdcbx) return -EOPNOTSUPP; - ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, - DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); - - return ret; + return nla_put_u8(skb, DCB_ATTR_DCBX, + netdev->dcbnl_ops->getdcbx(netdev)); } -static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setdcbx(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret; u8 value; if (!netdev->dcbnl_ops->setdcbx) @@ -1797,19 +1567,13 @@ static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, value = nla_get_u8(tb[DCB_ATTR_DCBX]); - ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value), - RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX, - pid, seq, flags); - - return ret; + return nla_put_u8(skb, DCB_ATTR_DCBX, + netdev->dcbnl_ops->setdcbx(netdev, value)); } -static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct sk_buff *dcbnl_skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; u8 value; int ret, i; @@ -1824,25 +1588,11 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest); if (ret) - goto err_out; - - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) { - ret = -ENOBUFS; - goto err_out; - } - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_GFEATCFG; + return ret; - nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); - if (!nest) { - ret = -EMSGSIZE; - goto nla_put_failure; - } + nest = nla_nest_start(skb, DCB_ATTR_FEATCFG); + if (!nest) + return -EMSGSIZE; if (data[DCB_FEATCFG_ATTR_ALL]) getall = 1; @@ -1853,28 +1603,21 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); if (!ret) - ret = nla_put_u8(dcbnl_skb, i, value); + ret = nla_put_u8(skb, i, value); if (ret) { - nla_nest_cancel(dcbnl_skb, nest); + nla_nest_cancel(skb, nest); goto nla_put_failure; } } - nla_nest_end(dcbnl_skb, nest); - - nlmsg_end(dcbnl_skb, nlh); + nla_nest_end(skb, nest); - return rtnl_unicast(dcbnl_skb, &init_net, pid); nla_put_failure: - nlmsg_cancel(dcbnl_skb, nlh); -nlmsg_failure: - kfree_skb(dcbnl_skb); -err_out: return ret; } -static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; int ret, i; @@ -1904,50 +1647,21 @@ static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, goto err; } err: - dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG, - pid, seq, flags); + ret = nla_put_u8(skb, DCB_ATTR_FEATCFG, ret); return ret; } /* Handle CEE DCBX GET commands. */ -static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, - u32 pid, u32 seq, u16 flags) +static int dcbnl_cee_get(struct net_device *netdev, struct nlmsghdr *nlh, + u32 seq, struct nlattr **tb, struct sk_buff *skb) { - struct net *net = dev_net(netdev); - struct sk_buff *skb; - struct nlmsghdr *nlh; - struct dcbmsg *dcb; const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; - int err; if (!ops) return -EOPNOTSUPP; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!skb) - return -ENOBUFS; - - nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); - if (nlh == NULL) { - nlmsg_free(skb); - return -EMSGSIZE; - } - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = DCB_CMD_CEE_GET; - - err = dcbnl_cee_fill(skb, netdev); - - if (err < 0) { - nlmsg_cancel(skb, nlh); - nlmsg_free(skb); - } else { - nlmsg_end(skb, nlh); - err = rtnl_unicast(skb, net, pid); - } - return err; + return dcbnl_cee_fill(skb, netdev); } struct reply_func { @@ -1960,7 +1674,33 @@ struct reply_func { }; static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = { - /* FIXME: add reply defs */ + [DCB_CMD_GSTATE] = { RTM_GETDCB, dcbnl_getstate }, + [DCB_CMD_SSTATE] = { RTM_SETDCB, dcbnl_setstate }, + [DCB_CMD_PFC_GCFG] = { RTM_GETDCB, dcbnl_getpfccfg }, + [DCB_CMD_PFC_SCFG] = { RTM_SETDCB, dcbnl_setpfccfg }, + [DCB_CMD_GPERM_HWADDR] = { RTM_GETDCB, dcbnl_getperm_hwaddr }, + [DCB_CMD_GCAP] = { RTM_GETDCB, dcbnl_getcap }, + [DCB_CMD_GNUMTCS] = { RTM_GETDCB, dcbnl_getnumtcs }, + [DCB_CMD_SNUMTCS] = { RTM_SETDCB, dcbnl_setnumtcs }, + [DCB_CMD_PFC_GSTATE] = { RTM_GETDCB, dcbnl_getpfcstate }, + [DCB_CMD_PFC_SSTATE] = { RTM_SETDCB, dcbnl_setpfcstate }, + [DCB_CMD_GAPP] = { RTM_GETDCB, dcbnl_getapp }, + [DCB_CMD_SAPP] = { RTM_SETDCB, dcbnl_setapp }, + [DCB_CMD_PGTX_GCFG] = { RTM_GETDCB, dcbnl_pgtx_getcfg }, + [DCB_CMD_PGTX_SCFG] = { RTM_SETDCB, dcbnl_pgtx_setcfg }, + [DCB_CMD_PGRX_GCFG] = { RTM_GETDCB, dcbnl_pgrx_getcfg }, + [DCB_CMD_PGRX_SCFG] = { RTM_SETDCB, dcbnl_pgrx_setcfg }, + [DCB_CMD_SET_ALL] = { RTM_SETDCB, dcbnl_setall }, + [DCB_CMD_BCN_GCFG] = { RTM_GETDCB, dcbnl_bcn_getcfg }, + [DCB_CMD_BCN_SCFG] = { RTM_SETDCB, dcbnl_bcn_setcfg }, + [DCB_CMD_IEEE_GET] = { RTM_GETDCB, dcbnl_ieee_get }, + [DCB_CMD_IEEE_SET] = { RTM_SETDCB, dcbnl_ieee_set }, + [DCB_CMD_IEEE_DEL] = { RTM_SETDCB, dcbnl_ieee_del }, + [DCB_CMD_GDCBX] = { RTM_GETDCB, dcbnl_getdcbx }, + [DCB_CMD_SDCBX] = { RTM_SETDCB, dcbnl_setdcbx }, + [DCB_CMD_GFEATCFG] = { RTM_GETDCB, dcbnl_getfeatcfg }, + [DCB_CMD_SFEATCFG] = { RTM_SETDCB, dcbnl_setfeatcfg }, + [DCB_CMD_CEE_GET] = { RTM_GETDCB, dcbnl_cee_get }, }; static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) @@ -2017,124 +1757,6 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) nlmsg_end(reply_skb, reply_nlh); ret = rtnl_unicast(reply_skb, &init_net, pid); - if (ret) - goto out; - - switch (dcb->cmd) { - case DCB_CMD_GSTATE: - ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PFC_GCFG: - ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_GPERM_HWADDR: - ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PGTX_GCFG: - ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PGRX_GCFG: - ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_BCN_GCFG: - ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_SSTATE: - ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PFC_SCFG: - ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - - case DCB_CMD_SET_ALL: - ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PGTX_SCFG: - ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PGRX_SCFG: - ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_GCAP: - ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_GNUMTCS: - ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_SNUMTCS: - ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PFC_GSTATE: - ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_PFC_SSTATE: - ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_BCN_SCFG: - ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_GAPP: - ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_SAPP: - ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_IEEE_SET: - ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_IEEE_GET: - ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_IEEE_DEL: - ret = dcbnl_ieee_del(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_GDCBX: - ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_SDCBX: - ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_GFEATCFG: - ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_SFEATCFG: - ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - case DCB_CMD_CEE_GET: - ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, - nlh->nlmsg_flags); - goto out; - default: - goto errout; - } -errout: - ret = -EINVAL; out: dev_put(netdev); return ret; -- GitLab From 77c6849d7aca31a0743be51412853079fcea03e0 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:54:56 +0000 Subject: [PATCH 1485/6849] dcbnl: Remove now unused dcbnl_reply() Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 5e392b85d48d..5ed71674a4a1 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -224,43 +224,6 @@ static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, return skb; } -/* standard netlink reply call */ -static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, - u32 seq, u16 flags) -{ - struct sk_buff *dcbnl_skb; - struct dcbmsg *dcb; - struct nlmsghdr *nlh; - int ret = -EINVAL; - - dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!dcbnl_skb) - return ret; - - nlh = NLMSG_NEW(dcbnl_skb, pid, seq, event, sizeof(*dcb), flags); - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = cmd; - dcb->dcb_pad = 0; - - ret = nla_put_u8(dcbnl_skb, attr, value); - if (ret) - goto err; - - /* end the message, assign the nlmsg_len. */ - nlmsg_end(dcbnl_skb, nlh); - ret = rtnl_unicast(dcbnl_skb, &init_net, pid); - if (ret) - return -EINVAL; - - return 0; -nlmsg_failure: -err: - kfree_skb(dcbnl_skb); - return ret; -} - static int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) { -- GitLab From ab6d470735682a6e1ba889a66f56eb1640242096 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:54:57 +0000 Subject: [PATCH 1486/6849] dcbnl: Use dcbnl_newmsg() where possible Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 5ed71674a4a1..4d9e0ef23d9f 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1328,27 +1328,16 @@ static int dcbnl_notify(struct net_device *dev, int event, int cmd, struct net *net = dev_net(dev); struct sk_buff *skb; struct nlmsghdr *nlh; - struct dcbmsg *dcb; const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; int err; if (!ops) return -EOPNOTSUPP; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + skb = dcbnl_newmsg(event, cmd, pid, seq, 0, &nlh); if (!skb) return -ENOBUFS; - nlh = nlmsg_put(skb, pid, 0, event, sizeof(*dcb), 0); - if (nlh == NULL) { - nlmsg_free(skb); - return -EMSGSIZE; - } - - dcb = NLMSG_DATA(nlh); - dcb->dcb_family = AF_UNSPEC; - dcb->cmd = cmd; - if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) err = dcbnl_ieee_fill(skb, dev); else @@ -1356,8 +1345,7 @@ static int dcbnl_notify(struct net_device *dev, int event, int cmd, if (err < 0) { /* Report error to broadcast listeners */ - nlmsg_cancel(skb, nlh); - kfree_skb(skb); + nlmsg_free(skb); rtnl_set_sk_err(net, RTNLGRP_DCB, err); } else { /* End nlmsg and notify broadcast listeners */ -- GitLab From 3d1f486952b750f1cca53cf22d4f769db5aba4f0 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:54:58 +0000 Subject: [PATCH 1487/6849] dcbnl: Return consistent error codes EMSGSIZE - ran out of space while constructing message EOPNOTSUPP - driver/hardware does not support operation ENODEV - network device not found EINVAL - invalid message Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 273 ++++++++++++++++++++++++------------------------ 1 file changed, 138 insertions(+), 135 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 4d9e0ef23d9f..5a5bc25b70d3 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -229,7 +229,7 @@ static int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh, { /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ if (!netdev->dcbnl_ops->getstate) - return -EINVAL; + return -EOPNOTSUPP; return nla_put_u8(skb, DCB_ATTR_STATE, netdev->dcbnl_ops->getstate(netdev)); @@ -240,22 +240,25 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, { struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; u8 value; - int ret = -EINVAL; + int ret; int i; int getall = 0; - if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->getpfccfg) - return ret; + if (!tb[DCB_ATTR_PFC_CFG]) + return -EINVAL; + + if (!netdev->dcbnl_ops->getpfccfg) + return -EOPNOTSUPP; ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest); if (ret) - goto err; + return ret; nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG); if (!nest) - goto err; + return -EMSGSIZE; if (data[DCB_PFC_UP_ATTR_ALL]) getall = 1; @@ -269,14 +272,12 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, ret = nla_put_u8(skb, i, value); if (ret) { nla_nest_cancel(skb, nest); - goto err; + return ret; } } nla_nest_end(skb, nest); return 0; -err: - return -EINVAL; } static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, @@ -285,7 +286,7 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, u8 perm_addr[MAX_ADDR_LEN]; if (!netdev->dcbnl_ops->getpermhwaddr) - return -EINVAL; + return -EOPNOTSUPP; netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); @@ -297,21 +298,24 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh, { struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; u8 value; - int ret = -EINVAL; + int ret; int i; int getall = 0; - if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap) - return ret; + if (!tb[DCB_ATTR_CAP]) + return -EINVAL; + + if (!netdev->dcbnl_ops->getcap) + return -EOPNOTSUPP; ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], dcbnl_cap_nest); if (ret) - goto err_out; + return ret; nest = nla_nest_start(skb, DCB_ATTR_CAP); if (!nest) - goto err_out; + return -EMSGSIZE; if (data[DCB_CAP_ATTR_ALL]) getall = 1; @@ -324,15 +328,13 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh, ret = nla_put_u8(skb, i, value); if (ret) { nla_nest_cancel(skb, nest); - goto err_out; + return ret; } } } nla_nest_end(skb, nest); return 0; -err_out: - return -EINVAL; } static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, @@ -340,25 +342,24 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, { struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; u8 value; - int ret = -EINVAL; + int ret; int i; int getall = 0; - if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->getnumtcs) - return ret; + if (!tb[DCB_ATTR_NUMTCS]) + return -EINVAL; + + if (!netdev->dcbnl_ops->getnumtcs) + return -EOPNOTSUPP; ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], dcbnl_numtcs_nest); - if (ret) { - ret = -EINVAL; - goto err_out; - } + if (ret) + return ret; nest = nla_nest_start(skb, DCB_ATTR_NUMTCS); - if (!nest) { - ret = -EINVAL; - goto err_out; - } + if (!nest) + return -EMSGSIZE; if (data[DCB_NUMTCS_ATTR_ALL]) getall = 1; @@ -372,36 +373,34 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, ret = nla_put_u8(skb, i, value); if (ret) { nla_nest_cancel(skb, nest); - ret = -EINVAL; - goto err_out; + return ret; } - } else { - goto err_out; - } + } else + return -EINVAL; } nla_nest_end(skb, nest); return 0; -err_out: - return ret; } static int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) { struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; - int ret = -EINVAL; + int ret; u8 value; int i; - if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setnumtcs) - return ret; + if (!tb[DCB_ATTR_NUMTCS]) + return -EINVAL; + + if (!netdev->dcbnl_ops->setnumtcs) + return -EOPNOTSUPP; ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], dcbnl_numtcs_nest); - if (ret) - return -EINVAL; + return ret; for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { if (data[i] == NULL) @@ -421,7 +420,7 @@ static int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) { if (!netdev->dcbnl_ops->getpfcstate) - return -EINVAL; + return -EOPNOTSUPP; return nla_put_u8(skb, DCB_ATTR_PFC_STATE, netdev->dcbnl_ops->getpfcstate(netdev)); @@ -432,9 +431,12 @@ static int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, { u8 value; - if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) + if (!tb[DCB_ATTR_PFC_STATE]) return -EINVAL; + if (!netdev->dcbnl_ops->setpfcstate) + return -EOPNOTSUPP; + value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); netdev->dcbnl_ops->setpfcstate(netdev, value); @@ -449,27 +451,26 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; u16 id; u8 up, idtype; - int ret = -EINVAL; + int ret; if (!tb[DCB_ATTR_APP]) - goto out; + return -EINVAL; ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], dcbnl_app_nest); if (ret) - goto out; + return ret; - ret = -EINVAL; /* all must be non-null */ if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || (!app_tb[DCB_APP_ATTR_ID])) - goto out; + return -EINVAL; /* either by eth type or by socket number */ idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && (idtype != DCB_APP_IDTYPE_PORTNUM)) - goto out; + return -EINVAL; id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); @@ -485,7 +486,7 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, app_nest = nla_nest_start(skb, DCB_ATTR_APP); if (!app_nest) - goto out; + return -EMSGSIZE; ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype); if (ret) @@ -501,59 +502,57 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, nla_nest_end(skb, app_nest); - goto out; + return 0; out_cancel: nla_nest_cancel(skb, app_nest); -out: return ret; } static int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int err, ret = -EINVAL; + int ret; u16 id; u8 up, idtype; struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; if (!tb[DCB_ATTR_APP]) - goto out; + return -EINVAL; ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], dcbnl_app_nest); if (ret) - goto out; + return ret; - ret = -EINVAL; /* all must be non-null */ if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || (!app_tb[DCB_APP_ATTR_ID]) || (!app_tb[DCB_APP_ATTR_PRIORITY])) - goto out; + return -EINVAL; /* either by eth type or by socket number */ idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && (idtype != DCB_APP_IDTYPE_PORTNUM)) - goto out; + return -EINVAL; id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); if (netdev->dcbnl_ops->setapp) { - err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); + ret = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); } else { struct dcb_app app; app.selector = idtype; app.protocol = id; app.priority = up; - err = dcb_setapp(netdev, &app); + ret = dcb_setapp(netdev, &app); } ret = nla_put_u8(skb, DCB_ATTR_APP, ret); dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); -out: + return ret; } @@ -564,26 +563,27 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; u8 prio, pgid, tc_pct, up_map; - int ret = -EINVAL; + int ret; int getall = 0; int i; - if (!tb[DCB_ATTR_PG_CFG] || - !netdev->dcbnl_ops->getpgtccfgtx || + if (!tb[DCB_ATTR_PG_CFG]) + return -EINVAL; + + if (!netdev->dcbnl_ops->getpgtccfgtx || !netdev->dcbnl_ops->getpgtccfgrx || !netdev->dcbnl_ops->getpgbwgcfgtx || !netdev->dcbnl_ops->getpgbwgcfgrx) - return ret; + return -EOPNOTSUPP; ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); - if (ret) - goto err_out; + return ret; pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG); if (!pg_nest) - goto err_out; + return -EMSGSIZE; if (pg_tb[DCB_PG_ATTR_TC_ALL]) getall = 1; @@ -674,7 +674,6 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); } ret = nla_put_u8(skb, i, tc_pct); - if (ret) goto err_pg; } @@ -687,9 +686,8 @@ err_param: nla_nest_cancel(skb, param_nest); err_pg: nla_nest_cancel(skb, pg_nest); -err_out: - ret = -EINVAL; - return ret; + + return -EMSGSIZE; } static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, @@ -709,9 +707,12 @@ static int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh, { u8 value; - if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) + if (!tb[DCB_ATTR_STATE]) return -EINVAL; + if (!netdev->dcbnl_ops->setstate) + return -EOPNOTSUPP; + value = nla_get_u8(tb[DCB_ATTR_STATE]); return nla_put_u8(skb, DCB_ATTR_STATE, @@ -723,17 +724,20 @@ static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, { struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; int i; - int ret = -EINVAL; + int ret; u8 value; - if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->setpfccfg) - return ret; + if (!tb[DCB_ATTR_PFC_CFG]) + return -EINVAL; + + if (!netdev->dcbnl_ops->setpfccfg) + return -EOPNOTSUPP; ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest); if (ret) - goto err; + return ret; for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { if (data[i] == NULL) @@ -744,17 +748,18 @@ static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, } return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0); -err: - return ret; } static int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) { - int ret = -EINVAL; + int ret; - if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) - return ret; + if (!tb[DCB_ATTR_SET_ALL]) + return -EINVAL; + + if (!netdev->dcbnl_ops->setall) + return -EOPNOTSUPP; ret = nla_put_u8(skb, DCB_ATTR_SET_ALL, netdev->dcbnl_ops->setall(netdev)); @@ -769,24 +774,26 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, { struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; - int ret = -EINVAL; + int ret; int i; u8 pgid; u8 up_map; u8 prio; u8 tc_pct; - if (!tb[DCB_ATTR_PG_CFG] || - !netdev->dcbnl_ops->setpgtccfgtx || + if (!tb[DCB_ATTR_PG_CFG]) + return -EINVAL; + + if (!netdev->dcbnl_ops->setpgtccfgtx || !netdev->dcbnl_ops->setpgtccfgrx || !netdev->dcbnl_ops->setpgbwgcfgtx || !netdev->dcbnl_ops->setpgbwgcfgrx) - return ret; + return -EOPNOTSUPP; ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); if (ret) - goto err; + return ret; for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { if (!pg_tb[i]) @@ -795,7 +802,7 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, pg_tb[i], dcbnl_tc_param_nest); if (ret) - goto err; + return ret; pgid = DCB_ATTR_VALUE_UNDEFINED; prio = DCB_ATTR_VALUE_UNDEFINED; @@ -848,10 +855,8 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, } } - ret = nla_put_u8(skb, (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 0); - -err: - return ret; + return nla_put_u8(skb, + (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 0); } static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, @@ -873,23 +878,25 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; u8 value_byte; u32 value_integer; - int ret = -EINVAL; + int ret; bool getall = false; int i; - if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->getbcnrp || + if (!tb[DCB_ATTR_BCN]) + return -EINVAL; + + if (!netdev->dcbnl_ops->getbcnrp || !netdev->dcbnl_ops->getbcncfg) - return ret; + return -EOPNOTSUPP; ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, tb[DCB_ATTR_BCN], dcbnl_bcn_nest); - if (ret) - goto err_out; + return ret; bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN); if (!bcn_nest) - goto err_out; + return -EMSGSIZE; if (bcn_tb[DCB_BCN_ATTR_ALL]) getall = true; @@ -922,8 +929,6 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, err_bcn: nla_nest_cancel(skb, bcn_nest); -err_out: - ret = -EINVAL; return ret; } @@ -932,19 +937,22 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, { struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; int i; - int ret = -EINVAL; + int ret; u8 value_byte; u32 value_int; - if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->setbcncfg || + if (!tb[DCB_ATTR_BCN]) + return -EINVAL; + + if (!netdev->dcbnl_ops->setbcncfg || !netdev->dcbnl_ops->setbcnrp) - return ret; + return -EOPNOTSUPP; ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest); if (ret) - goto err; + return ret; for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { if (data[i] == NULL) @@ -962,9 +970,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, i, value_int); } - ret = nla_put_u8(skb, DCB_ATTR_BCN, 0); -err: - return ret; + return nla_put_u8(skb, DCB_ATTR_BCN, 0); } static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, @@ -1030,20 +1036,21 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) struct dcb_app_type *itr; const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; int dcbx; - int err = -EMSGSIZE; + int err; if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) - goto nla_put_failure; + return -EMSGSIZE; + ieee = nla_nest_start(skb, DCB_ATTR_IEEE); if (!ieee) - goto nla_put_failure; + return -EMSGSIZE; if (ops->ieee_getets) { struct ieee_ets ets; err = ops->ieee_getets(netdev, &ets); if (!err && nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) - goto nla_put_failure; + return -EMSGSIZE; } if (ops->ieee_getmaxrate) { @@ -1053,7 +1060,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, sizeof(maxrate), &maxrate); if (err) - goto nla_put_failure; + return -EMSGSIZE; } } @@ -1062,12 +1069,12 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) err = ops->ieee_getpfc(netdev, &pfc); if (!err && nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) - goto nla_put_failure; + return -EMSGSIZE; } app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); if (!app) - goto nla_put_failure; + return -EMSGSIZE; spin_lock(&dcb_lock); list_for_each_entry(itr, &dcb_app_list, list) { @@ -1076,7 +1083,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) &itr->app); if (err) { spin_unlock(&dcb_lock); - goto nla_put_failure; + return -EMSGSIZE; } } } @@ -1095,7 +1102,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) err = ops->ieee_peer_getets(netdev, &ets); if (!err && nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) - goto nla_put_failure; + return -EMSGSIZE; } if (ops->ieee_peer_getpfc) { @@ -1103,7 +1110,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) err = ops->ieee_peer_getpfc(netdev, &pfc); if (!err && nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) - goto nla_put_failure; + return -EMSGSIZE; } if (ops->peer_getappinfo && ops->peer_getapptable) { @@ -1112,20 +1119,17 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) DCB_ATTR_IEEE_APP_UNSPEC, DCB_ATTR_IEEE_APP); if (err) - goto nla_put_failure; + return -EMSGSIZE; } nla_nest_end(skb, ieee); if (dcbx >= 0) { err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); if (err) - goto nla_put_failure; + return -EMSGSIZE; } return 0; - -nla_put_failure: - return err; } static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, @@ -1137,13 +1141,13 @@ static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, struct nlattr *pg = nla_nest_start(skb, i); if (!pg) - goto nla_put_failure; + return -EMSGSIZE; for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { struct nlattr *tc_nest = nla_nest_start(skb, i); if (!tc_nest) - goto nla_put_failure; + return -EMSGSIZE; pgid = DCB_ATTR_VALUE_UNDEFINED; prio = DCB_ATTR_VALUE_UNDEFINED; @@ -1161,7 +1165,7 @@ static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) || nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) || nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct)) - goto nla_put_failure; + return -EMSGSIZE; nla_nest_end(skb, tc_nest); } @@ -1175,13 +1179,10 @@ static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); if (nla_put_u8(skb, i, tc_pct)) - goto nla_put_failure; + return -EMSGSIZE; } nla_nest_end(skb, pg); return 0; - -nla_put_failure: - return -EMSGSIZE; } static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) @@ -1380,10 +1381,10 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, { const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; - int err = -EOPNOTSUPP; + int err; if (!ops) - return err; + return -EOPNOTSUPP; if (!tb[DCB_ATTR_IEEE]) return -EINVAL; @@ -1455,7 +1456,7 @@ static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, { const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; - int err = -EOPNOTSUPP; + int err; if (!ops) return -EOPNOTSUPP; @@ -1687,10 +1688,12 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); if (!netdev) - return -EINVAL; + return -ENODEV; - if (!netdev->dcbnl_ops) - goto errout; + if (!netdev->dcbnl_ops) { + ret = -EOPNOTSUPP; + goto out; + } reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq, nlh->nlmsg_flags, &reply_nlh); -- GitLab From 716b31abbd39baab307c0a7b38dce9a20c16c62d Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:54:59 +0000 Subject: [PATCH 1488/6849] dcbnl: Move dcb app lookup code into dcb_app_lookup() Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 81 +++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 46 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 5a5bc25b70d3..6817f1439951 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1716,6 +1716,22 @@ out: return ret; } +static struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app, + int ifindex, int prio) +{ + struct dcb_app_type *itr; + + list_for_each_entry(itr, &dcb_app_list, list) { + if (itr->app.selector == app->selector && + itr->app.protocol == app->protocol && + itr->ifindex == ifindex && + (!prio || itr->app.priority == prio)) + return itr; + } + + return NULL; +} + /** * dcb_getapp - retrieve the DCBX application user priority * @@ -1729,14 +1745,8 @@ u8 dcb_getapp(struct net_device *dev, struct dcb_app *app) u8 prio = 0; spin_lock(&dcb_lock); - list_for_each_entry(itr, &dcb_app_list, list) { - if (itr->app.selector == app->selector && - itr->app.protocol == app->protocol && - itr->ifindex == dev->ifindex) { - prio = itr->app.priority; - break; - } - } + if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) + prio = itr->app.priority; spin_unlock(&dcb_lock); return prio; @@ -1762,18 +1772,14 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new) spin_lock(&dcb_lock); /* Search for existing match and replace */ - list_for_each_entry(itr, &dcb_app_list, list) { - if (itr->app.selector == new->selector && - itr->app.protocol == new->protocol && - itr->ifindex == dev->ifindex) { - if (new->priority) - itr->app.priority = new->priority; - else { - list_del(&itr->list); - kfree(itr); - } - goto out; + if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) { + if (new->priority) + itr->app.priority = new->priority; + else { + list_del(&itr->list); + kfree(itr); } + goto out; } /* App type does not exist add new application type */ if (new->priority) { @@ -1808,13 +1814,8 @@ u8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) u8 prio = 0; spin_lock(&dcb_lock); - list_for_each_entry(itr, &dcb_app_list, list) { - if (itr->app.selector == app->selector && - itr->app.protocol == app->protocol && - itr->ifindex == dev->ifindex) { - prio |= 1 << itr->app.priority; - } - } + if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) + prio |= 1 << itr->app.priority; spin_unlock(&dcb_lock); return prio; @@ -1830,7 +1831,7 @@ EXPORT_SYMBOL(dcb_ieee_getapp_mask); */ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) { - struct dcb_app_type *itr, *entry; + struct dcb_app_type *entry; struct dcb_app_type event; int err = 0; @@ -1841,14 +1842,9 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) spin_lock(&dcb_lock); /* Search for existing match and abort if found */ - list_for_each_entry(itr, &dcb_app_list, list) { - if (itr->app.selector == new->selector && - itr->app.protocol == new->protocol && - itr->app.priority == new->priority && - itr->ifindex == dev->ifindex) { - err = -EEXIST; - goto out; - } + if (dcb_app_lookup(new, dev->ifindex, new->priority)) { + err = -EEXIST; + goto out; } /* App entry does not exist add new entry */ @@ -1887,19 +1883,12 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) spin_lock(&dcb_lock); /* Search for existing match and remove it. */ - list_for_each_entry(itr, &dcb_app_list, list) { - if (itr->app.selector == del->selector && - itr->app.protocol == del->protocol && - itr->app.priority == del->priority && - itr->ifindex == dev->ifindex) { - list_del(&itr->list); - kfree(itr); - err = 0; - goto out; - } + if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) { + list_del(&itr->list); + kfree(itr); + err = 0; } -out: spin_unlock(&dcb_lock); if (!err) call_dcbevent_notifiers(DCB_APP_EVENT, &event); -- GitLab From 4e4f2f69704be0ae218d91fb827e5a6987fe262f Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:55:00 +0000 Subject: [PATCH 1489/6849] dcbnl: Move dcb app allocation into dcb_app_add() Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 6817f1439951..6e1c32468236 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1732,6 +1732,21 @@ static struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app, return NULL; } +static int dcb_app_add(const struct dcb_app *app, int ifindex) +{ + struct dcb_app_type *entry; + + entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + if (!entry) + return -ENOMEM; + + memcpy(&entry->app, app, sizeof(*app)); + entry->ifindex = ifindex; + list_add(&entry->list, &dcb_app_list); + + return 0; +} + /** * dcb_getapp - retrieve the DCBX application user priority * @@ -1764,6 +1779,7 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new) { struct dcb_app_type *itr; struct dcb_app_type event; + int err = 0; event.ifindex = dev->ifindex; memcpy(&event.app, new, sizeof(event.app)); @@ -1782,22 +1798,13 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new) goto out; } /* App type does not exist add new application type */ - if (new->priority) { - struct dcb_app_type *entry; - entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); - if (!entry) { - spin_unlock(&dcb_lock); - return -ENOMEM; - } - - memcpy(&entry->app, new, sizeof(*new)); - entry->ifindex = dev->ifindex; - list_add(&entry->list, &dcb_app_list); - } + if (new->priority) + err = dcb_app_add(new, dev->ifindex); out: spin_unlock(&dcb_lock); - call_dcbevent_notifiers(DCB_APP_EVENT, &event); - return 0; + if (!err) + call_dcbevent_notifiers(DCB_APP_EVENT, &event); + return err; } EXPORT_SYMBOL(dcb_setapp); @@ -1831,7 +1838,6 @@ EXPORT_SYMBOL(dcb_ieee_getapp_mask); */ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) { - struct dcb_app_type *entry; struct dcb_app_type event; int err = 0; @@ -1847,16 +1853,7 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) goto out; } - /* App entry does not exist add new entry */ - entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); - if (!entry) { - err = -ENOMEM; - goto out; - } - - memcpy(&entry->app, new, sizeof(*new)); - entry->ifindex = dev->ifindex; - list_add(&entry->list, &dcb_app_list); + err = dcb_app_add(new, dev->ifindex); out: spin_unlock(&dcb_lock); if (!err) -- GitLab From 7a282bc37f8a1e7b46907d78724177d20214b137 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 02:55:01 +0000 Subject: [PATCH 1490/6849] dcbnl: Use type safe nlmsg_data() Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 6e1c32468236..70bba3eb4ae9 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1659,7 +1659,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); struct net_device *netdev; - struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); + struct dcbmsg *dcb = nlmsg_data(nlh); struct nlattr *tb[DCB_ATTR_MAX + 1]; u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = -EINVAL; -- GitLab From 0450243096de90ff51c3a6c605410c5e28d79f8d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Jun 2012 05:30:07 +0000 Subject: [PATCH 1491/6849] bonding: drop_monitor aware When packets are dropped in TX path, its better to use kfree_skb() instead of dev_kfree_skb() to give proper drop_monitor events. Also move the kfree_skb() call after read_unlock() in bond_alb_xmit() and bond_xmit_activebackup() Signed-off-by: Eric Dumazet Cc: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 2 +- drivers/net/bonding/bond_alb.c | 6 +++--- drivers/net/bonding/bond_main.c | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 3031e0413114..a030e635f001 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2454,7 +2454,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) out: if (res) { /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); + kfree_skb(skb); } return NETDEV_TX_OK; diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index ef3791a09ad8..e15cc11edbbe 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1346,12 +1346,12 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) } } + read_unlock(&bond->curr_slave_lock); + if (res) { /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); + kfree_skb(skb); } - read_unlock(&bond->curr_slave_lock); - return NETDEV_TX_OK; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index af506321500b..f5a40b925f5e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3990,7 +3990,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev out: if (res) { /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); + kfree_skb(skb); } return NETDEV_TX_OK; @@ -4012,11 +4012,11 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev); + read_unlock(&bond->curr_slave_lock); + if (res) /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); - - read_unlock(&bond->curr_slave_lock); + kfree_skb(skb); return NETDEV_TX_OK; } @@ -4055,7 +4055,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) if (res) { /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); + kfree_skb(skb); } return NETDEV_TX_OK; @@ -4093,7 +4093,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) res = bond_dev_queue_xmit(bond, skb2, tx_dev); if (res) { - dev_kfree_skb(skb2); + kfree_skb(skb2); continue; } } @@ -4107,7 +4107,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) out: if (res) /* no suitable interface, frame not sent */ - dev_kfree_skb(skb); + kfree_skb(skb); /* frame sent to all suitable interfaces */ return NETDEV_TX_OK; @@ -4213,7 +4213,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev pr_err("%s: Error: Unknown bonding mode %d\n", dev->name, bond->params.mode); WARN_ON_ONCE(1); - dev_kfree_skb(skb); + kfree_skb(skb); return NETDEV_TX_OK; } } @@ -4235,7 +4235,7 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) if (bond->slave_cnt) ret = __bond_start_xmit(skb, dev); else - dev_kfree_skb(skb); + kfree_skb(skb); read_unlock(&bond->lock); -- GitLab From 4d4847b8502ec093864936a4669318675c0ced22 Mon Sep 17 00:00:00 2001 From: Jeffrin Jose Date: Sun, 20 May 2012 00:56:58 +0530 Subject: [PATCH 1492/6849] usb: early: fixed coding style issue related to : operator Fixed a space issue relating to ":" operator found by checkpatch.pl tool in drivers/usb/early/ehci-dbgp.c Signed-off-by: Jeffrin Jose Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 1fc8f1249806..ee0ebacf8227 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -334,7 +334,7 @@ static int dbgp_control_msg(unsigned devnum, int requesttype, int ret; read = (requesttype & USB_DIR_IN) != 0; - if (size > (read ? DBGP_MAX_PACKET:0)) + if (size > (read ? DBGP_MAX_PACKET : 0)) return -1; /* Compute the control message */ -- GitLab From e714fad054e219b52eee17591d95d725888a95c4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 May 2012 11:36:59 +0200 Subject: [PATCH 1493/6849] usb-core: Set intfdata to NULL if a driver's probe method failed Ensure that intfdata always is NULL if no driver is bound: 1) drvdata is for a driver to store a pointer to driver specific data 2) If no driver is bound, there is no driver specific data associated with the device 3) Thus logically drvdata should be NULL if no driver is bound. We already set intfdata to NULL when a driver is unbound, to ensure that intfdata will be NULL even if the drivers disconnect method does not properly clear it. This ensures that intfdata will also be NULL after a failed probe, even if the driver's probe method left a (likely dangling) pointer in there. Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 23d7bbd199a5..69781016a266 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -367,6 +367,7 @@ static int usb_probe_interface(struct device *dev) return error; err: + usb_set_intfdata(intf, NULL); intf->needs_remote_wakeup = 0; intf->condition = USB_INTERFACE_UNBOUND; usb_cancel_queued_reset(intf); -- GitLab From 7e54e97812ccf59e71e002f9bd6d12bf4ab448b8 Mon Sep 17 00:00:00 2001 From: "Du, ChangbinX" Date: Wed, 23 May 2012 02:43:05 +0000 Subject: [PATCH 1494/6849] testusb: expose looping forever option "l" to user The testusb.c tool has support for looping forever implemented, which may be useful for stress test, yet it is not exposed to the user, so even though the code is there, it cannot be used. This commit adds "l" to the set of options handled by the application which enables the feature. Also, I collate help information for each command line option to make it easier to use for novice. Signed-off-by: Du Changbin Acked-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- tools/usb/testusb.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c index 82d7c590c026..b0adb2710c02 100644 --- a/tools/usb/testusb.c +++ b/tools/usb/testusb.c @@ -425,7 +425,7 @@ int main (int argc, char **argv) /* for easy use when hotplugging */ device = getenv ("DEVICE"); - while ((c = getopt (argc, argv, "D:aA:c:g:hns:t:v:")) != EOF) + while ((c = getopt (argc, argv, "D:aA:c:g:hlns:t:v:")) != EOF) switch (c) { case 'D': /* device, if only one */ device = optarg; @@ -468,10 +468,21 @@ int main (int argc, char **argv) case 'h': default: usage: - fprintf (stderr, "usage: %s [-n] [-D dev | -a | -A usbfs-dir]\n" - "\t[-c iterations] [-t testnum]\n" - "\t[-s packetsize] [-g sglen] [-v vary]\n", - argv [0]); + fprintf (stderr, + "usage: %s [options]\n" + "Options:\n" + "\t-D dev only test specific device\n" + "\t-A usbfs-dir\n" + "\t-a test all recognized devices\n" + "\t-l loop forever(for stress test)\n" + "\t-t testnum only run specified case\n" + "\t-n no test running, show devices to be tested\n" + "Case arguments:\n" + "\t-c iterations default 1000\n" + "\t-s packetsize default 512\n" + "\t-g sglen default 32\n" + "\t-v vary default 512\n", + argv[0]); return 1; } if (optind != argc) -- GitLab From 71f882fe71823c54ae095ce29ce050f814eefdbc Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 20 May 2012 00:23:26 +0530 Subject: [PATCH 1495/6849] staging: android: alarm: remove unnecessary goto statement Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index c2d87c546e99..5b7064005188 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -237,7 +237,6 @@ from_old_alarm_set: default: rv = -EINVAL; - goto err1; } err1: return rv; -- GitLab From 00763e41138267a307531397f9745835aecb8c7b Mon Sep 17 00:00:00 2001 From: Xudong Hao Date: Thu, 7 Jun 2012 18:26:07 +0800 Subject: [PATCH 1496/6849] KVM: x86: change PT_FIRST_AVAIL_BITS_SHIFT to avoid conflict with EPT Dirty bit EPT Dirty bit use bit 9 as Intel SDM definition, to avoid conflict, change PT_FIRST_AVAIL_BITS_SHIFT to 10. Signed-off-by: Xudong Hao Signed-off-by: Xiantao Zhang Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index b32a11dc884c..3b53d9e08bfc 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -90,7 +90,7 @@ module_param(dbg, bool, 0644); #define PTE_PREFETCH_NUM 8 -#define PT_FIRST_AVAIL_BITS_SHIFT 9 +#define PT_FIRST_AVAIL_BITS_SHIFT 10 #define PT64_SECOND_AVAIL_BITS_SHIFT 52 #define PT64_LEVEL_BITS 9 -- GitLab From dd0aa67cd7cf3f4a3ca52ecc1d6b82f3fad1352b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 13 Jun 2012 16:33:54 -0700 Subject: [PATCH 1497/6849] Revert "w1: introduce a slave mutex for serializing IO" This reverts commit 59d4467be405316916a4087d5b02d99196eeef04. Turns out it was the wrong version, will apply the correct version after this. Reported-by: NeilBrown Cc: Evgeniy Polyakov Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/w1/slaves/w1_bq27000.c | 4 ++-- drivers/w1/w1.c | 1 - drivers/w1/w1.h | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 87554788fa32..52ad812fa1e7 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c @@ -31,10 +31,10 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg) u8 val; struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); - mutex_lock(&sl->mutex); + mutex_lock(&sl->master->mutex); w1_write_8(sl->master, HDQ_CMD_READ | reg); val = w1_read_8(sl->master); - mutex_unlock(&sl->mutex); + mutex_unlock(&sl->master->mutex); return val; } diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 79e488db5104..bfb898641029 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -686,7 +686,6 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); atomic_set(&sl->refcnt, 0); init_completion(&sl->released); - mutex_init(&sl->mutex); spin_lock(&w1_flock); f = w1_family_registered(rn->family); diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 8c8be380a98a..4d012ca3f32c 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h @@ -75,7 +75,6 @@ struct w1_slave void *family_data; struct device dev; struct completion released; - struct mutex mutex; }; typedef void (*w1_slave_found_callback)(struct w1_master *, u64); -- GitLab From 7b5362a603a1ecc9a25b97dafd702b8098090f41 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 22 May 2012 09:43:02 +1000 Subject: [PATCH 1498/6849] w1: omap_hdq: Fix some error/debug handling. - some debug messages missed spaces - sometimes no error was returned when it should have been - sometimes a message is printed when there is no error, rather than when there is one. Acked-by: Evgeniy Polyakov Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/omap_hdq.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 5ef385bfed18..3036b6113ffd 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -180,6 +180,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); if (ret == 0) { dev_dbg(hdq_data->dev, "TX wait elapsed\n"); + ret = -ETIMEDOUT; goto out; } @@ -187,7 +188,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) /* check irqstatus */ if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { dev_dbg(hdq_data->dev, "timeout waiting for" - "TXCOMPLETE/RXCOMPLETE, %x", *status); + " TXCOMPLETE/RXCOMPLETE, %x", *status); ret = -ETIMEDOUT; goto out; } @@ -198,7 +199,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) OMAP_HDQ_FLAG_CLEAR, &tmp_status); if (ret) { dev_dbg(hdq_data->dev, "timeout waiting GO bit" - "return to zero, %x", tmp_status); + " return to zero, %x", tmp_status); } out: @@ -341,7 +342,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data) &tmp_status); if (ret) dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" - "return to zero, %x", tmp_status); + " return to zero, %x", tmp_status); out: mutex_unlock(&hdq_data->hdq_mutex); @@ -386,7 +387,7 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) /* check irqstatus */ if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { dev_dbg(hdq_data->dev, "timeout waiting for" - "RXCOMPLETE, %x", status); + " RXCOMPLETE, %x", status); ret = -ETIMEDOUT; goto out; } @@ -396,7 +397,7 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) out: mutex_unlock(&hdq_data->hdq_mutex); rtn: - return 0; + return ret; } @@ -470,7 +471,7 @@ static int omap_hdq_put(struct hdq_data *hdq_data) if (0 == hdq_data->hdq_usecount) { dev_dbg(hdq_data->dev, "attempt to decrement use count" - "when it is zero"); + " when it is zero"); ret = -EINVAL; } else { hdq_data->hdq_usecount--; @@ -540,7 +541,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) mutex_unlock(&hdq_data->hdq_mutex); ret = hdq_write_byte(hdq_data, byte, &status); - if (ret == 0) { + if (ret < 0) { dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); return; } -- GitLab From b7e938d06d0de43bdbee8844a8736c81480c1031 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 22 May 2012 09:43:02 +1000 Subject: [PATCH 1499/6849] w1: omap_hdq: use wait_event_timeout to wait for read to complete. There is no gain in having a loop - there is no risk of missing the interrupt with wait_event_timeout. Signed-off-by: NeilBrown Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/omap_hdq.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 3036b6113ffd..848399bfb9b4 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -354,7 +354,6 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) { int ret = 0; u8 status; - unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); if (ret < 0) { @@ -372,15 +371,13 @@ static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); /* - * The RX comes immediately after TX. It - * triggers another interrupt before we - * sleep. So we have to wait for RXCOMPLETE bit. + * The RX comes immediately after TX. */ - while (!(hdq_data->hdq_irqstatus - & OMAP_HDQ_INT_STATUS_RXCOMPLETE) - && time_before(jiffies, timeout)) { - schedule_timeout_uninterruptible(1); - } + wait_event_timeout(hdq_wait_queue, + (hdq_data->hdq_irqstatus + & OMAP_HDQ_INT_STATUS_RXCOMPLETE), + OMAP_HDQ_TIMEOUT); + hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, OMAP_HDQ_CTRL_STATUS_DIR); status = hdq_data->hdq_irqstatus; -- GitLab From b02f8bede217a4b145ecc16d3940c78d83941147 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 18 May 2012 15:59:52 +1000 Subject: [PATCH 1500/6849] W1: split master mutex to avoid deadlocks. The 'mutex' in struct w1_master is use for two very different purposes. Firstly it protects various data structures such as the list of all slaves. Secondly it protects the w1 buss against concurrent accesses. This can lead to deadlocks when the ->probe code called while adding a slave needs to talk on the bus, as is the case for power_supply devices. ds2780 and ds2781 drivers contain a work around to track which process hold the lock simply to avoid this deadlock. bq27000 doesn't have that work around and so deadlocks. There are other possible deadlocks involving sysfs. When removing a device the sysfs s_active lock is held, so the lock that protects the slave list must take precedence over s_active. However when access power_supply attributes via sysfs, the s_active lock must take precedence over the lock that protects accesses to the bus. So to avoid deadlocks between w1 slaves and sysfs, these must be two separate locks. Making them separate means that the work around in ds2780 and ds2781 can be removed. So this patch: - adds a new mutex: "bus_mutex" which serialises access to the bus. - takes in mutex in w1_search and ds1wm_search while they access the bus for searching. The mutex is dropped before calling the callback which adds the slave. - changes all slaves to use bus_mutex instead of mutex to protect access to the bus - removes w1_ds2790_io_nolock and w1_ds2781_io_nolock, and the related code from drivers/power/ds278[01]_battery.c which calls them. Signed-off-by: NeilBrown Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/power/ds2780_battery.c | 11 +---------- drivers/power/ds2781_battery.c | 12 +----------- drivers/w1/masters/ds1wm.c | 4 ++++ drivers/w1/slaves/w1_bq27000.c | 4 ++-- drivers/w1/slaves/w1_ds2408.c | 24 ++++++++++++------------ drivers/w1/slaves/w1_ds2423.c | 4 ++-- drivers/w1/slaves/w1_ds2431.c | 8 ++++---- drivers/w1/slaves/w1_ds2433.c | 8 ++++---- drivers/w1/slaves/w1_ds2760.c | 8 ++++---- drivers/w1/slaves/w1_ds2780.c | 22 ++++------------------ drivers/w1/slaves/w1_ds2780.h | 2 -- drivers/w1/slaves/w1_ds2781.c | 22 ++++------------------ drivers/w1/slaves/w1_ds2781.h | 2 -- drivers/w1/slaves/w1_therm.c | 10 +++++----- drivers/w1/w1.c | 9 ++++++++- drivers/w1/w1.h | 1 + drivers/w1/w1_int.c | 1 + 17 files changed, 57 insertions(+), 95 deletions(-) diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index de31cae1ba53..74fad941c56c 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c @@ -39,7 +39,6 @@ struct ds2780_device_info { struct device *dev; struct power_supply bat; struct device *w1_dev; - struct task_struct *mutex_holder; }; enum current_types { @@ -64,10 +63,7 @@ static inline struct power_supply *to_power_supply(struct device *dev) static inline int ds2780_battery_io(struct ds2780_device_info *dev_info, char *buf, int addr, size_t count, int io) { - if (dev_info->mutex_holder == current) - return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io); - else - return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); + return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); } static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val, @@ -779,7 +775,6 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) dev_info->bat.properties = ds2780_battery_props; dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); dev_info->bat.get_property = ds2780_battery_get_property; - dev_info->mutex_holder = current; ret = power_supply_register(&pdev->dev, &dev_info->bat); if (ret) { @@ -809,8 +804,6 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) goto fail_remove_bin_file; } - dev_info->mutex_holder = NULL; - return 0; fail_remove_bin_file: @@ -830,8 +823,6 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev) { struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); - dev_info->mutex_holder = current; - /* remove attributes */ sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c index 975684a40f15..5f92a4bb33f9 100644 --- a/drivers/power/ds2781_battery.c +++ b/drivers/power/ds2781_battery.c @@ -37,7 +37,6 @@ struct ds2781_device_info { struct device *dev; struct power_supply bat; struct device *w1_dev; - struct task_struct *mutex_holder; }; enum current_types { @@ -62,11 +61,7 @@ static inline struct power_supply *to_power_supply(struct device *dev) static inline int ds2781_battery_io(struct ds2781_device_info *dev_info, char *buf, int addr, size_t count, int io) { - if (dev_info->mutex_holder == current) - return w1_ds2781_io_nolock(dev_info->w1_dev, buf, addr, - count, io); - else - return w1_ds2781_io(dev_info->w1_dev, buf, addr, count, io); + return w1_ds2781_io(dev_info->w1_dev, buf, addr, count, io); } int w1_ds2781_read(struct ds2781_device_info *dev_info, char *buf, @@ -775,7 +770,6 @@ static int __devinit ds2781_battery_probe(struct platform_device *pdev) dev_info->bat.properties = ds2781_battery_props; dev_info->bat.num_properties = ARRAY_SIZE(ds2781_battery_props); dev_info->bat.get_property = ds2781_battery_get_property; - dev_info->mutex_holder = current; ret = power_supply_register(&pdev->dev, &dev_info->bat); if (ret) { @@ -805,8 +799,6 @@ static int __devinit ds2781_battery_probe(struct platform_device *pdev) goto fail_remove_bin_file; } - dev_info->mutex_holder = NULL; - return 0; fail_remove_bin_file: @@ -826,8 +818,6 @@ static int __devexit ds2781_battery_remove(struct platform_device *pdev) { struct ds2781_device_info *dev_info = platform_get_drvdata(pdev); - dev_info->mutex_holder = current; - /* remove attributes */ sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index a0c8965c1a79..530a2d309063 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c @@ -334,7 +334,9 @@ static void ds1wm_search(void *data, struct w1_master *master_dev, return; } + mutex_lock(&master_dev->bus_mutex); if (ds1wm_reset(ds1wm_data)) { + mutex_unlock(&master_dev->bus_mutex); dev_dbg(&ds1wm_data->pdev->dev, "pass: %d reset error (or no slaves)\n", pass); break; @@ -387,6 +389,7 @@ static void ds1wm_search(void *data, struct w1_master *master_dev, } if (ds1wm_data->read_error) { + mutex_unlock(&master_dev->bus_mutex); dev_err(&ds1wm_data->pdev->dev, "pass: %d read error, retrying\n", pass); break; @@ -400,6 +403,7 @@ static void ds1wm_search(void *data, struct w1_master *master_dev, dev_dbg(&ds1wm_data->pdev->dev, "pass: %d resetting bus\n", pass); ds1wm_reset(ds1wm_data); + mutex_unlock(&master_dev->bus_mutex); if ((r_prime & ((u64)1 << 63)) && (d & ((u64)1 << 63))) { dev_err(&ds1wm_data->pdev->dev, "pass: %d bus error, retrying\n", pass); diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 52ad812fa1e7..773dca5beafe 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c @@ -31,10 +31,10 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg) u8 val; struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); w1_write_8(sl->master, HDQ_CMD_READ | reg); val = w1_read_8(sl->master); - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return val; } diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 8e813eed0f0a..441ad3a3b586 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -52,11 +52,11 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) if (!buf) return -EINVAL; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "mutex locked"); if (w1_reset_select_slave(sl)) { - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return -EIO; } @@ -66,7 +66,7 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) w1_write_block(sl->master, wrbuf, 3); *buf = w1_read_8(sl->master); - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "mutex unlocked"); return 1; } @@ -165,7 +165,7 @@ static ssize_t w1_f29_write_output( return -EFAULT; dev_dbg(&sl->dev, "locking mutex for write_output"); - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "mutex locked"); if (w1_reset_select_slave(sl)) @@ -200,14 +200,14 @@ static ssize_t w1_f29_write_output( /* read the result of the READ_PIO_REGS command */ if (w1_read_8(sl->master) == *buf) { /* success! */ - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "mutex unlocked, retries:%d", retries); return 1; } } error: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); return -EIO; @@ -228,7 +228,7 @@ static ssize_t w1_f29_write_activity( if (count != 1 || off != 0) return -EFAULT; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl)) goto error; @@ -236,7 +236,7 @@ static ssize_t w1_f29_write_activity( while (retries--) { w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES); if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) { - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return 1; } if (w1_reset_resume_command(sl->master)) @@ -244,7 +244,7 @@ static ssize_t w1_f29_write_activity( } error: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return -EIO; } @@ -263,7 +263,7 @@ static ssize_t w1_f29_write_status_control( if (count != 1 || off != 0) return -EFAULT; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl)) goto error; @@ -285,12 +285,12 @@ static ssize_t w1_f29_write_status_control( w1_write_block(sl->master, w1_buf, 3); if (w1_read_8(sl->master) == *buf) { /* success! */ - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return 1; } } error: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return -EIO; } diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 7a7dbe5026f1..40a10b5ed120 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c @@ -66,7 +66,7 @@ static ssize_t w1_counter_read(struct device *device, wrbuf[0] = 0xA5; wrbuf[1] = rom_addr & 0xFF; wrbuf[2] = rom_addr >> 8; - mutex_lock(&dev->mutex); + mutex_lock(&dev->bus_mutex); if (!w1_reset_select_slave(sl)) { w1_write_block(dev, wrbuf, 3); read_byte_count = 0; @@ -124,7 +124,7 @@ static ssize_t w1_counter_read(struct device *device, } else { c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error"); } - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->bus_mutex); return PAGE_SIZE - c; } diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index 84e2410aec1d..984b30331a45 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -107,7 +107,7 @@ static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, if (count == 0) return 0; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */ while (todo > 0) { @@ -126,7 +126,7 @@ static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, off += W1_F2D_READ_MAXLEN; } - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return count; } @@ -214,7 +214,7 @@ static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, if (count == 0) return 0; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); /* Can only write data in blocks of the size of the scratchpad */ addr = off; @@ -259,7 +259,7 @@ static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, } out_up: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return count; } diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 0f7b8f9c509a..85f2cdb27fa2 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -107,7 +107,7 @@ static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) return 0; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); #ifdef CONFIG_W1_SLAVE_DS2433_CRC @@ -138,7 +138,7 @@ static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ out_up: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return count; } @@ -233,7 +233,7 @@ static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, } #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); /* Can only write data to one page at a time */ idx = 0; @@ -251,7 +251,7 @@ static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, } out_up: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return count; } diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 5754c9a4f58b..aa7bd5fa2fa8 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -31,7 +31,7 @@ static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, if (!dev) return 0; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); if (addr > DS2760_DATA_SIZE || addr < 0) { count = 0; @@ -54,7 +54,7 @@ static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, } out: - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return count; } @@ -76,14 +76,14 @@ static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd) if (!dev) return -EINVAL; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl) == 0) { w1_write_8(sl->master, cmd); w1_write_8(sl->master, addr); } - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return 0; } diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 39f78c0b143c..7b09307de0ef 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c @@ -60,30 +60,16 @@ int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, if (!dev) return -ENODEV; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); ret = w1_ds2780_do_io(dev, buf, addr, count, io); - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return ret; } EXPORT_SYMBOL(w1_ds2780_io); -int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr, size_t count, - int io) -{ - int ret; - - if (!dev) - return -ENODEV; - - ret = w1_ds2780_do_io(dev, buf, addr, count, io); - - return ret; -} -EXPORT_SYMBOL(w1_ds2780_io_nolock); - int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) { struct w1_slave *sl = container_of(dev, struct w1_slave, dev); @@ -91,14 +77,14 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) if (!dev) return -EINVAL; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl) == 0) { w1_write_8(sl->master, cmd); w1_write_8(sl->master, addr); } - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return 0; } EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); diff --git a/drivers/w1/slaves/w1_ds2780.h b/drivers/w1/slaves/w1_ds2780.h index 737379365021..a1fba79eb1b5 100644 --- a/drivers/w1/slaves/w1_ds2780.h +++ b/drivers/w1/slaves/w1_ds2780.h @@ -124,8 +124,6 @@ extern int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, int io); -extern int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr, - size_t count, int io); extern int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd); #endif /* !_W1_DS2780_H */ diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 0d0c7985293f..877daf74159c 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c @@ -58,30 +58,16 @@ int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count, if (!dev) return -ENODEV; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); ret = w1_ds2781_do_io(dev, buf, addr, count, io); - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return ret; } EXPORT_SYMBOL(w1_ds2781_io); -int w1_ds2781_io_nolock(struct device *dev, char *buf, int addr, size_t count, - int io) -{ - int ret; - - if (!dev) - return -ENODEV; - - ret = w1_ds2781_do_io(dev, buf, addr, count, io); - - return ret; -} -EXPORT_SYMBOL(w1_ds2781_io_nolock); - int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) { struct w1_slave *sl = container_of(dev, struct w1_slave, dev); @@ -89,14 +75,14 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) if (!dev) return -EINVAL; - mutex_lock(&sl->master->mutex); + mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl) == 0) { w1_write_8(sl->master, cmd); w1_write_8(sl->master, addr); } - mutex_unlock(&sl->master->mutex); + mutex_unlock(&sl->master->bus_mutex); return 0; } EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); diff --git a/drivers/w1/slaves/w1_ds2781.h b/drivers/w1/slaves/w1_ds2781.h index 82bc66497b43..557dfb0b4f64 100644 --- a/drivers/w1/slaves/w1_ds2781.h +++ b/drivers/w1/slaves/w1_ds2781.h @@ -129,8 +129,6 @@ extern int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count, int io); -extern int w1_ds2781_io_nolock(struct device *dev, char *buf, int addr, - size_t count, int io); extern int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd); #endif /* !_W1_DS2781_H */ diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index ff29ae747ee8..d90062b211f8 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -179,7 +179,7 @@ static ssize_t w1_therm_read(struct device *device, int i, max_trying = 10; ssize_t c = PAGE_SIZE; - i = mutex_lock_interruptible(&dev->mutex); + i = mutex_lock_interruptible(&dev->bus_mutex); if (i != 0) return i; @@ -207,19 +207,19 @@ static ssize_t w1_therm_read(struct device *device, w1_write_8(dev, W1_CONVERT_TEMP); if (external_power) { - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->bus_mutex); sleep_rem = msleep_interruptible(tm); if (sleep_rem != 0) return -EINTR; - i = mutex_lock_interruptible(&dev->mutex); + i = mutex_lock_interruptible(&dev->bus_mutex); if (i != 0) return i; } else if (!w1_strong_pullup) { sleep_rem = msleep_interruptible(tm); if (sleep_rem != 0) { - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->bus_mutex); return -EINTR; } } @@ -258,7 +258,7 @@ static ssize_t w1_therm_read(struct device *device, c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", w1_convert_temp(rom, sl->family->fid)); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->bus_mutex); return PAGE_SIZE - c; } diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index bfb898641029..1a574370d2cd 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -885,16 +885,21 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb * * Return 0 - device(s) present, 1 - no devices present. */ + mutex_lock(&dev->bus_mutex); if (w1_reset_bus(dev)) { + mutex_unlock(&dev->bus_mutex); dev_dbg(&dev->dev, "No devices present on the wire.\n"); break; } /* Do fast search on single slave bus */ if (dev->max_slave_count == 1) { + int rv; w1_write_8(dev, W1_READ_ROM); + rv = w1_read_block(dev, (u8 *)&rn, 8); + mutex_unlock(&dev->bus_mutex); - if (w1_read_block(dev, (u8 *)&rn, 8) == 8 && rn) + if (rv == 8 && rn) cb(dev, rn); break; @@ -927,10 +932,12 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb rn |= (tmp64 << i); if (kthread_should_stop()) { + mutex_unlock(&dev->bus_mutex); dev_dbg(&dev->dev, "Abort w1_search\n"); return; } } + mutex_unlock(&dev->bus_mutex); if ( (triplet_ret & 0x03) != 0x03 ) { if ( (desc_bit == last_zero) || (last_zero < 0)) diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 4d012ca3f32c..45908e56c2f8 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h @@ -180,6 +180,7 @@ struct w1_master struct task_struct *thread; struct mutex mutex; + struct mutex bus_mutex; struct device_driver *driver; struct device dev; diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 68288355727a..531434180afd 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -76,6 +76,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, INIT_LIST_HEAD(&dev->slist); mutex_init(&dev->mutex); + mutex_init(&dev->bus_mutex); memcpy(&dev->dev, device, sizeof(struct device)); dev_set_name(&dev->dev, "w1_bus_master%u", dev->id); -- GitLab From 0998d0631001288a5974afc0b2a5f568bcdecb4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 May 2012 00:09:34 +0200 Subject: [PATCH 1501/6849] device-core: Ensure drvdata = NULL when no driver is bound 1) drvdata is for a driver to store a pointer to driver specific data 2) If no driver is bound, there is no driver specific data associated with the device 3) Thus logically drvdata should be NULL if no driver is bound. But many drivers don't clear drvdata on device_release, or set drvdata early on in probe and leave it set on probe error. Both of which results in a dangling pointer in drvdata. This patch enforce for drvdata to be NULL after device_release or on probe failure. Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1b1cbb571d38..9a1e9704d782 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -283,6 +283,7 @@ probe_failed: devres_release_all(dev); driver_sysfs_remove(dev); dev->driver = NULL; + dev_set_drvdata(dev, NULL); if (ret == -EPROBE_DEFER) { /* Driver requested deferred probing */ @@ -487,6 +488,7 @@ static void __device_release_driver(struct device *dev) drv->remove(dev); devres_release_all(dev); dev->driver = NULL; + dev_set_drvdata(dev, NULL); klist_remove(&dev->p->knode_driver); if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, -- GitLab From a59d6293e5372d7c35212932e083e2a541151eff Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 23 May 2012 15:13:07 +0200 Subject: [PATCH 1502/6849] debugfs: change parameter check in debugfs_remove() functions The dentry parameter in debugfs_remove() and debugfs_remove_recursive() is checked being a NULL pointer. To make cleanup by callers easier this check is extended using the IS_ERR_OR_NULL macro instead because the debugfs_create_... functions can return a ERR_PTR() value. Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index b80bc846a15a..0de5e26870c3 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -498,7 +498,7 @@ void debugfs_remove(struct dentry *dentry) struct dentry *parent; int ret; - if (!dentry) + if (IS_ERR_OR_NULL(dentry)) return; parent = dentry->d_parent; @@ -530,7 +530,7 @@ void debugfs_remove_recursive(struct dentry *dentry) struct dentry *child; struct dentry *parent; - if (!dentry) + if (IS_ERR_OR_NULL(dentry)) return; parent = dentry->d_parent; -- GitLab From fbf7f7b4e2ae40f790828c86d31beff2d49e9ac8 Mon Sep 17 00:00:00 2001 From: Markus Franke Date: Sat, 26 May 2012 00:45:12 +0200 Subject: [PATCH 1503/6849] w1: Add 1-wire slave device driver for DS28E04-100 Signed-off-by: Markus Franke Signed-off-by: Greg Kroah-Hartman --- .../ABI/stable/sysfs-driver-w1_ds28e04 | 15 + Documentation/w1/slaves/w1_ds28e04 | 36 ++ drivers/w1/slaves/Kconfig | 13 + drivers/w1/slaves/Makefile | 1 + drivers/w1/slaves/w1_ds28e04.c | 469 ++++++++++++++++++ drivers/w1/w1_family.h | 1 + 6 files changed, 535 insertions(+) create mode 100644 Documentation/ABI/stable/sysfs-driver-w1_ds28e04 create mode 100644 Documentation/w1/slaves/w1_ds28e04 create mode 100644 drivers/w1/slaves/w1_ds28e04.c diff --git a/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 b/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 new file mode 100644 index 000000000000..26579ee868c9 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-w1_ds28e04 @@ -0,0 +1,15 @@ +What: /sys/bus/w1/devices/.../pio +Date: May 2012 +Contact: Markus Franke +Description: read/write the contents of the two PIO's of the DS28E04-100 + see Documentation/w1/slaves/w1_ds28e04 for detailed information +Users: any user space application which wants to communicate with DS28E04-100 + + + +What: /sys/bus/w1/devices/.../eeprom +Date: May 2012 +Contact: Markus Franke +Description: read/write the contents of the EEPROM memory of the DS28E04-100 + see Documentation/w1/slaves/w1_ds28e04 for detailed information +Users: any user space application which wants to communicate with DS28E04-100 diff --git a/Documentation/w1/slaves/w1_ds28e04 b/Documentation/w1/slaves/w1_ds28e04 new file mode 100644 index 000000000000..85bc9a7e02fe --- /dev/null +++ b/Documentation/w1/slaves/w1_ds28e04 @@ -0,0 +1,36 @@ +Kernel driver w1_ds28e04 +======================== + +Supported chips: + * Maxim DS28E04-100 4096-Bit Addressable 1-Wire EEPROM with PIO + +supported family codes: + W1_FAMILY_DS28E04 0x1C + +Author: Markus Franke, + +Description +----------- + +Support is provided through the sysfs files "eeprom" and "pio". CRC checking +during memory accesses can optionally be enabled/disabled via the device +attribute "crccheck". The strong pull-up can optionally be enabled/disabled +via the module parameter "w1_strong_pullup". + +Memory Access + + A read operation on the "eeprom" file reads the given amount of bytes + from the EEPROM of the DS28E04. + + A write operation on the "eeprom" file writes the given byte sequence + to the EEPROM of the DS28E04. If CRC checking mode is enabled only + fully alligned blocks of 32 bytes with valid CRC16 values (in bytes 30 + and 31) are allowed to be written. + +PIO Access + + The 2 PIOs of the DS28E04-100 are accessible via the "pio" sysfs file. + + The current status of the PIO's is returned as an 8 bit value. Bit 0/1 + represent the state of PIO_0/PIO_1. Bits 2..7 do not care. The PIO's are + driven low-active, i.e. the driver delivers/expects low-active values. diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index eb9e376d6244..67526690acbc 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig @@ -94,6 +94,19 @@ config W1_SLAVE_DS2781 If you are unsure, say N. +config W1_SLAVE_DS28E04 + tristate "4096-Bit Addressable 1-Wire EEPROM with PIO (DS28E04-100)" + depends on W1 + select CRC16 + help + If you enable this you will have the DS28E04-100 + chip support. + + Say Y here if you want to use a 1-wire + 4kb EEPROM with PIO family device (DS28E04). + + If you are unsure, say N. + config W1_SLAVE_BQ27000 tristate "BQ27000 slave support" depends on W1 diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index c4f1859fb520..05188f6aab5a 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o +obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c new file mode 100644 index 000000000000..98117db595bb --- /dev/null +++ b/drivers/w1/slaves/w1_ds28e04.c @@ -0,0 +1,469 @@ +/* + * w1_ds28e04.c - w1 family 1C (DS28E04) driver + * + * Copyright (c) 2012 Markus Franke + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CRC16_INIT 0 +#define CRC16_VALID 0xb001 + +#include "../w1.h" +#include "../w1_int.h" +#include "../w1_family.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Markus Franke , "); +MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO"); + +/* Allow the strong pullup to be disabled, but default to enabled. + * If it was disabled a parasite powered device might not get the required + * current to copy the data from the scratchpad to EEPROM. If it is enabled + * parasite powered devices have a better chance of getting the current + * required. + */ +static int w1_strong_pullup = 1; +module_param_named(strong_pullup, w1_strong_pullup, int, 0); + +/* enable/disable CRC checking on DS28E04-100 memory accesses */ +static char w1_enable_crccheck = 1; + +#define W1_EEPROM_SIZE 512 +#define W1_PAGE_COUNT 16 +#define W1_PAGE_SIZE 32 +#define W1_PAGE_BITS 5 +#define W1_PAGE_MASK 0x1F + +#define W1_F1C_READ_EEPROM 0xF0 +#define W1_F1C_WRITE_SCRATCH 0x0F +#define W1_F1C_READ_SCRATCH 0xAA +#define W1_F1C_COPY_SCRATCH 0x55 +#define W1_F1C_ACCESS_WRITE 0x5A + +#define W1_1C_REG_LOGIC_STATE 0x220 + +struct w1_f1C_data { + u8 memory[W1_EEPROM_SIZE]; + u32 validcrc; +}; + +/** + * Check the file size bounds and adjusts count as needed. + * This would not be needed if the file size didn't reset to 0 after a write. + */ +static inline size_t w1_f1C_fix_count(loff_t off, size_t count, size_t size) +{ + if (off > size) + return 0; + + if ((off + count) > size) + return size - off; + + return count; +} + +static int w1_f1C_refresh_block(struct w1_slave *sl, struct w1_f1C_data *data, + int block) +{ + u8 wrbuf[3]; + int off = block * W1_PAGE_SIZE; + + if (data->validcrc & (1 << block)) + return 0; + + if (w1_reset_select_slave(sl)) { + data->validcrc = 0; + return -EIO; + } + + wrbuf[0] = W1_F1C_READ_EEPROM; + wrbuf[1] = off & 0xff; + wrbuf[2] = off >> 8; + w1_write_block(sl->master, wrbuf, 3); + w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE); + + /* cache the block if the CRC is valid */ + if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID) + data->validcrc |= (1 << block); + + return 0; +} + +static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data) +{ + u8 wrbuf[3]; + + /* read directly from the EEPROM */ + if (w1_reset_select_slave(sl)) + return -EIO; + + wrbuf[0] = W1_F1C_READ_EEPROM; + wrbuf[1] = addr & 0xff; + wrbuf[2] = addr >> 8; + + w1_write_block(sl->master, wrbuf, sizeof(wrbuf)); + return w1_read_block(sl->master, data, len); +} + +static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + struct w1_f1C_data *data = sl->family_data; + int i, min_page, max_page; + + count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE); + if (count == 0) + return 0; + + mutex_lock(&sl->master->mutex); + + if (w1_enable_crccheck) { + min_page = (off >> W1_PAGE_BITS); + max_page = (off + count - 1) >> W1_PAGE_BITS; + for (i = min_page; i <= max_page; i++) { + if (w1_f1C_refresh_block(sl, data, i)) { + count = -EIO; + goto out_up; + } + } + memcpy(buf, &data->memory[off], count); + } else { + count = w1_f1C_read(sl, off, count, buf); + } + +out_up: + mutex_unlock(&sl->master->mutex); + + return count; +} + +/** + * Writes to the scratchpad and reads it back for verification. + * Then copies the scratchpad to EEPROM. + * The data must be on one page. + * The master must be locked. + * + * @param sl The slave structure + * @param addr Address for the write + * @param len length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK)) + * @param data The data to write + * @return 0=Success -1=failure + */ +static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data) +{ + u8 wrbuf[4]; + u8 rdbuf[W1_PAGE_SIZE + 3]; + u8 es = (addr + len - 1) & 0x1f; + unsigned int tm = 10; + int i; + struct w1_f1C_data *f1C = sl->family_data; + + /* Write the data to the scratchpad */ + if (w1_reset_select_slave(sl)) + return -1; + + wrbuf[0] = W1_F1C_WRITE_SCRATCH; + wrbuf[1] = addr & 0xff; + wrbuf[2] = addr >> 8; + + w1_write_block(sl->master, wrbuf, 3); + w1_write_block(sl->master, data, len); + + /* Read the scratchpad and verify */ + if (w1_reset_select_slave(sl)) + return -1; + + w1_write_8(sl->master, W1_F1C_READ_SCRATCH); + w1_read_block(sl->master, rdbuf, len + 3); + + /* Compare what was read against the data written */ + if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) || + (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) + return -1; + + /* Copy the scratchpad to EEPROM */ + if (w1_reset_select_slave(sl)) + return -1; + + wrbuf[0] = W1_F1C_COPY_SCRATCH; + wrbuf[3] = es; + + for (i = 0; i < sizeof(wrbuf); ++i) { + /* issue 10ms strong pullup (or delay) on the last byte + for writing the data from the scratchpad to EEPROM */ + if (w1_strong_pullup && i == sizeof(wrbuf)-1) + w1_next_pullup(sl->master, tm); + + w1_write_8(sl->master, wrbuf[i]); + } + + if (!w1_strong_pullup) + msleep(tm); + + if (w1_enable_crccheck) { + /* invalidate cached data */ + f1C->validcrc &= ~(1 << (addr >> W1_PAGE_BITS)); + } + + /* Reset the bus to wake up the EEPROM (this may not be needed) */ + w1_reset_bus(sl->master); + + return 0; +} + +static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) + +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + int addr, len, idx; + + count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE); + if (count == 0) + return 0; + + if (w1_enable_crccheck) { + /* can only write full blocks in cached mode */ + if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) { + dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n", + (int)off, count); + return -EINVAL; + } + + /* make sure the block CRCs are valid */ + for (idx = 0; idx < count; idx += W1_PAGE_SIZE) { + if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE) + != CRC16_VALID) { + dev_err(&sl->dev, "bad CRC at offset %d\n", + (int)off); + return -EINVAL; + } + } + } + + mutex_lock(&sl->master->mutex); + + /* Can only write data to one page at a time */ + idx = 0; + while (idx < count) { + addr = off + idx; + len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK); + if (len > (count - idx)) + len = count - idx; + + if (w1_f1C_write(sl, addr, len, &buf[idx]) < 0) { + count = -EIO; + goto out_up; + } + idx += len; + } + +out_up: + mutex_unlock(&sl->master->mutex); + + return count; +} + +static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) + +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + int ret; + + /* check arguments */ + if (off != 0 || count != 1 || buf == NULL) + return -EINVAL; + + mutex_lock(&sl->master->mutex); + ret = w1_f1C_read(sl, W1_1C_REG_LOGIC_STATE, count, buf); + mutex_unlock(&sl->master->mutex); + + return ret; +} + +static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) + +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + u8 wrbuf[3]; + u8 ack; + + /* check arguments */ + if (off != 0 || count != 1 || buf == NULL) + return -EINVAL; + + mutex_lock(&sl->master->mutex); + + /* Write the PIO data */ + if (w1_reset_select_slave(sl)) { + mutex_unlock(&sl->master->mutex); + return -1; + } + + /* set bit 7..2 to value '1' */ + *buf = *buf | 0xFC; + + wrbuf[0] = W1_F1C_ACCESS_WRITE; + wrbuf[1] = *buf; + wrbuf[2] = ~(*buf); + w1_write_block(sl->master, wrbuf, 3); + + w1_read_block(sl->master, &ack, sizeof(ack)); + + mutex_unlock(&sl->master->mutex); + + /* check for acknowledgement */ + if (ack != 0xAA) + return -EIO; + + return count; +} + +static ssize_t w1_f1C_show_crccheck(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (put_user(w1_enable_crccheck + 0x30, buf)) + return -EFAULT; + + return sizeof(w1_enable_crccheck); +} + +static ssize_t w1_f1C_store_crccheck(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char val; + + if (count != 1 || !buf) + return -EINVAL; + + if (get_user(val, buf)) + return -EFAULT; + + /* convert to decimal */ + val = val - 0x30; + if (val != 0 && val != 1) + return -EINVAL; + + /* set the new value */ + w1_enable_crccheck = val; + + return sizeof(w1_enable_crccheck); +} + +#define NB_SYSFS_BIN_FILES 2 +static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = { + { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUSR, + }, + .size = W1_EEPROM_SIZE, + .read = w1_f1C_read_bin, + .write = w1_f1C_write_bin, + }, + { + .attr = { + .name = "pio", + .mode = S_IRUGO | S_IWUSR, + }, + .size = 1, + .read = w1_f1C_read_pio, + .write = w1_f1C_write_pio, + } +}; + +static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO, + w1_f1C_show_crccheck, w1_f1C_store_crccheck); + +static int w1_f1C_add_slave(struct w1_slave *sl) +{ + int err = 0; + int i; + struct w1_f1C_data *data = NULL; + + if (w1_enable_crccheck) { + data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + sl->family_data = data; + } + + /* create binary sysfs attributes */ + for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) + err = sysfs_create_bin_file( + &sl->dev.kobj, &(w1_f1C_bin_attr[i])); + + if (!err) { + /* create device attributes */ + err = device_create_file(&sl->dev, &dev_attr_crccheck); + } + + if (err) { + /* remove binary sysfs attributes */ + for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) + sysfs_remove_bin_file( + &sl->dev.kobj, &(w1_f1C_bin_attr[i])); + + kfree(data); + } + + return err; +} + +static void w1_f1C_remove_slave(struct w1_slave *sl) +{ + int i; + + kfree(sl->family_data); + sl->family_data = NULL; + + /* remove device attributes */ + device_remove_file(&sl->dev, &dev_attr_crccheck); + + /* remove binary sysfs attributes */ + for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) + sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i])); +} + +static struct w1_family_ops w1_f1C_fops = { + .add_slave = w1_f1C_add_slave, + .remove_slave = w1_f1C_remove_slave, +}; + +static struct w1_family w1_family_1C = { + .fid = W1_FAMILY_DS28E04, + .fops = &w1_f1C_fops, +}; + +static int __init w1_f1C_init(void) +{ + return w1_register_family(&w1_family_1C); +} + +static void __exit w1_f1C_fini(void) +{ + w1_unregister_family(&w1_family_1C); +} + +module_init(w1_f1C_init); +module_exit(w1_f1C_fini); diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 874aeb05011b..b00ada44a89b 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h @@ -30,6 +30,7 @@ #define W1_FAMILY_SMEM_01 0x01 #define W1_FAMILY_SMEM_81 0x81 #define W1_THERM_DS18S20 0x10 +#define W1_FAMILY_DS28E04 0x1C #define W1_COUNTER_DS2423 0x1D #define W1_THERM_DS1822 0x22 #define W1_EEPROM_DS2433 0x23 -- GitLab From 201e4aca5aa179e6c69a4dcd36a3562e56b8d670 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:07:49 -0700 Subject: [PATCH 1504/6849] pstore/ram: Should update old dmesg buffer before reading Without the update, we'll only see the new dmesg buffer after the reboot, but previously we could see it right away. Making an oops visible in pstore filesystem before reboot is a somewhat dubious feature, but removing it wasn't an intentional change, so let's restore it. For this we have to make persistent_ram_save_old() safe for calling multiple times, and also extern it. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 2 ++ fs/pstore/ram_core.c | 15 ++++++++------- include/linux/pstore_ram.h | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 9123cce28c1e..16ff7332eae0 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -106,6 +106,8 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, time->tv_sec = 0; time->tv_nsec = 0; + /* Update old/shadowed buffer. */ + persistent_ram_save_old(prz); size = persistent_ram_old_size(prz); *buf = kmalloc(size, GFP_KERNEL); if (*buf == NULL) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 31f8d184f3a0..235513c46aaf 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -250,23 +250,24 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, persistent_ram_update_ecc(prz, start, count); } -static void __init -persistent_ram_save_old(struct persistent_ram_zone *prz) +void persistent_ram_save_old(struct persistent_ram_zone *prz) { struct persistent_ram_buffer *buffer = prz->buffer; size_t size = buffer_size(prz); size_t start = buffer_start(prz); - char *dest; - persistent_ram_ecc_old(prz); + if (!size) + return; - dest = kmalloc(size, GFP_KERNEL); - if (dest == NULL) { + if (!prz->old_log) { + persistent_ram_ecc_old(prz); + prz->old_log = kmalloc(size, GFP_KERNEL); + } + if (!prz->old_log) { pr_err("persistent_ram: failed to allocate buffer\n"); return; } - prz->old_log = dest; prz->old_log_size = size; memcpy(prz->old_log, &buffer->data[start], size - start); memcpy(prz->old_log + size - start, &buffer->data[0], start); diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 7ed7fd4dba49..4491e8ff36e6 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -75,6 +75,7 @@ struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, unsigned int count); +void persistent_ram_save_old(struct persistent_ram_zone *prz); size_t persistent_ram_old_size(struct persistent_ram_zone *prz); void *persistent_ram_old(struct persistent_ram_zone *prz); void persistent_ram_free_old(struct persistent_ram_zone *prz); -- GitLab From 25b63da64708212985c06c7f8b089d356efdd9cf Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:07:50 -0700 Subject: [PATCH 1505/6849] pstore/ram_core: Do not reset restored zone's position and size Otherwise, the files will survive just one reboot, and on a subsequent boot they will disappear. Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 235513c46aaf..f6650d12c0c1 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -406,6 +406,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool " size %zu, start %zu\n", buffer_size(prz), buffer_start(prz)); persistent_ram_save_old(prz); + return 0; } } else { pr_info("persistent_ram: no valid data in buffer" -- GitLab From fce397930475f7efc712a1345dc0dad269a10544 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:07:51 -0700 Subject: [PATCH 1506/6849] pstore/ram_core: Factor persistent_ram_zap() out of post_init() A handy function that we will use outside of ram_core soon. But so far just factor it out and start using it in post_init(). Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram_core.c | 11 ++++++++--- include/linux/pstore_ram.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f6650d12c0c1..c5fbdbbf81ac 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -320,6 +320,13 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz) prz->old_log_size = 0; } +void persistent_ram_zap(struct persistent_ram_zone *prz) +{ + atomic_set(&prz->buffer->start, 0); + atomic_set(&prz->buffer->size, 0); + persistent_ram_update_header_ecc(prz); +} + static void *persistent_ram_vmap(phys_addr_t start, size_t size) { struct page **pages; @@ -414,8 +421,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool } prz->buffer->sig = PERSISTENT_RAM_SIG; - atomic_set(&prz->buffer->start, 0); - atomic_set(&prz->buffer->size, 0); + persistent_ram_zap(prz); return 0; } @@ -450,7 +456,6 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, goto err; persistent_ram_post_init(prz, ecc); - persistent_ram_update_header_ecc(prz); return prz; err: diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 4491e8ff36e6..3b823d49a85a 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -69,6 +69,7 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, size_t size, bool ecc); void persistent_ram_free(struct persistent_ram_zone *prz); +void persistent_ram_zap(struct persistent_ram_zone *prz); struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, bool ecc); -- GitLab From 93cce049682a1aebd49766f29af363e5b8770aed Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:07:52 -0700 Subject: [PATCH 1507/6849] pstore/ram: Should zap persistent zone on unlink Otherwise, unlinked file will reappear on the next boot. Reported-by: Kees Cook Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 16ff7332eae0..453030f9c5bc 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -186,6 +186,7 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, return -EINVAL; persistent_ram_free_old(cxt->przs[id]); + persistent_ram_zap(cxt->przs[id]); return 0; } -- GitLab From 364ed2f4653d7c86ebedcc116a9cb34fd272867c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:07:53 -0700 Subject: [PATCH 1508/6849] pstore/inode: Make pstore_fill_super() static There's no reason to extern it. The patch fixes the annoying sparse warning: CHECK fs/pstore/inode.c fs/pstore/inode.c:264:5: warning: symbol 'pstore_fill_super' was not declared. Should it be static? Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index aeb19e68e086..11a2aa2a56c4 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -258,7 +258,7 @@ fail: return rc; } -int pstore_fill_super(struct super_block *sb, void *data, int silent) +static int pstore_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; -- GitLab From 61bde82caee95426bf1ad53fefc8dc691b8ba37c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 11 Jun 2012 16:06:57 +0200 Subject: [PATCH 1509/6849] KVM: s390: Set CPU in stopped state on initial cpu reset The initial cpu reset sets the cpu in the stopped state. Several places check for the cpu state (e.g. sigp set prefix) and not setting the STOPPED state triggered errors with newer guest kernels after reboot. Signed-off-by: Christian Borntraeger Signed-off-by: Cornelia Huck Signed-off-by: Marcelo Tosatti --- arch/s390/kvm/kvm-s390.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 664766d0c83c..ace93603d861 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -347,6 +347,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) vcpu->arch.guest_fpregs.fpc = 0; asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc)); vcpu->arch.sie_block->gbea = 1; + atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); } int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) -- GitLab From cd1834591fe9564720ac4b0193bf1c790fe89f0d Mon Sep 17 00:00:00 2001 From: Heinz Graalfs Date: Mon, 11 Jun 2012 16:06:59 +0200 Subject: [PATCH 1510/6849] KVM: s390: Perform early event mask processing during boot For processing under KVM it is required to detect the actual SCLP console type in order to set it as preferred console. Signed-off-by: Heinz Graalfs Acked-by: Heiko Carstens Acked-by: Peter Oberparleiter Signed-off-by: Cornelia Huck Signed-off-by: Marcelo Tosatti --- arch/s390/include/asm/sclp.h | 2 ++ arch/s390/kernel/setup.c | 12 ++++++++--- drivers/s390/char/sclp.c | 10 --------- drivers/s390/char/sclp.h | 10 +++++++++ drivers/s390/char/sclp_cmd.c | 38 +++++++++++++++++++++++++++++++++++ drivers/s390/kvm/kvm_virtio.c | 3 ++- 6 files changed, 61 insertions(+), 14 deletions(-) diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index bf238c55740b..173f07aaeb2b 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -55,5 +55,7 @@ int sclp_chp_configure(struct chp_id chpid); int sclp_chp_deconfigure(struct chp_id chpid); int sclp_chp_read_info(struct sclp_chp_info *info); void sclp_get_ipl_info(struct sclp_ipl_info *info); +bool sclp_has_linemode(void); +bool sclp_has_vt220(void); #endif /* _ASM_S390_SCLP_H */ diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 489d1d8d96b0..e86bca6f975c 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -63,6 +63,7 @@ #include #include #include +#include #include "entry.h" long psw_kernel_bits = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY | @@ -138,9 +139,14 @@ __setup("condev=", condev_setup); static void __init set_preferred_console(void) { - if (MACHINE_IS_KVM) - add_preferred_console("hvc", 0, NULL); - else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) + if (MACHINE_IS_KVM) { + if (sclp_has_vt220()) + add_preferred_console("ttyS", 1, NULL); + else if (sclp_has_linemode()) + add_preferred_console("ttyS", 0, NULL); + else + add_preferred_console("hvc", 0, NULL); + } else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) add_preferred_console("ttyS", 0, NULL); else if (CONSOLE_IS_3270) add_preferred_console("tty3270", 0, NULL); diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 30f29a0020a1..3fcc000efc53 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -654,16 +654,6 @@ sclp_remove_processed(struct sccb_header *sccb) EXPORT_SYMBOL(sclp_remove_processed); -struct init_sccb { - struct sccb_header header; - u16 _reserved; - u16 mask_length; - sccb_mask_t receive_mask; - sccb_mask_t send_mask; - sccb_mask_t sclp_receive_mask; - sccb_mask_t sclp_send_mask; -} __attribute__((packed)); - /* Prepare init mask request. Called while sclp_lock is locked. */ static inline void __sclp_make_init_req(u32 receive_mask, u32 send_mask) diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 49a1bb52bc87..d7e97ae9ef6d 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -88,6 +88,16 @@ struct sccb_header { u16 response_code; } __attribute__((packed)); +struct init_sccb { + struct sccb_header header; + u16 _reserved; + u16 mask_length; + sccb_mask_t receive_mask; + sccb_mask_t send_mask; + sccb_mask_t sclp_receive_mask; + sccb_mask_t sclp_send_mask; +} __attribute__((packed)); + extern u64 sclp_facilities; #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 766cb7b19b40..71ea923c322d 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -48,6 +48,7 @@ struct read_info_sccb { u8 _reserved5[4096 - 112]; /* 112-4095 */ } __attribute__((packed, aligned(PAGE_SIZE))); +static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE); static struct read_info_sccb __initdata early_read_info_sccb; static int __initdata early_read_info_sccb_valid; @@ -104,6 +105,19 @@ static void __init sclp_read_info_early(void) } } +static void __init sclp_event_mask_early(void) +{ + struct init_sccb *sccb = &early_event_mask_sccb; + int rc; + + do { + memset(sccb, 0, sizeof(*sccb)); + sccb->header.length = sizeof(*sccb); + sccb->mask_length = sizeof(sccb_mask_t); + rc = sclp_cmd_sync_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb); + } while (rc == -EBUSY); +} + void __init sclp_facilities_detect(void) { struct read_info_sccb *sccb; @@ -119,6 +133,30 @@ void __init sclp_facilities_detect(void) rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; rzm <<= 20; + + sclp_event_mask_early(); +} + +bool __init sclp_has_linemode(void) +{ + struct init_sccb *sccb = &early_event_mask_sccb; + + if (sccb->header.response_code != 0x20) + return 0; + if (sccb->sclp_send_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)) + return 1; + return 0; +} + +bool __init sclp_has_vt220(void) +{ + struct init_sccb *sccb = &early_event_mask_sccb; + + if (sccb->header.response_code != 0x20) + return 0; + if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK) + return 1; + return 0; } unsigned long long sclp_get_rnmax(void) diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index d74e9ae6dfb3..d3bdae49512f 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -468,7 +469,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) static int __init s390_virtio_console_init(void) { - if (!MACHINE_IS_KVM) + if (sclp_has_vt220() || sclp_has_linemode()) return -ENODEV; return virtio_cons_early_init(early_put_chars); } -- GitLab From dcce0489477f07ac1331aee71f18d6274e19a9c1 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 11 Jun 2012 18:39:50 +0200 Subject: [PATCH 1511/6849] KVM: trace events: update list of exit reasons The list of exit reasons for the kvm_userspace_exit event was missing recent additions; bring it into sync again. Reviewed-by: Christian Borntraeger Signed-off-by: Cornelia Huck Signed-off-by: Marcelo Tosatti --- include/trace/events/kvm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 46e3cd8e197a..3df5925fe641 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -13,7 +13,8 @@ ERSN(DEBUG), ERSN(HLT), ERSN(MMIO), ERSN(IRQ_WINDOW_OPEN), \ ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR), \ ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\ - ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI) + ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI), ERSN(PAPR_HCALL), \ + ERSN(S390_UCONTROL) TRACE_EVENT(kvm_userspace_exit, TP_PROTO(__u32 reason, int errno), -- GitLab From f29e5956aebafe63f81e80f972c44c4a666e5c7f Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:19 -0700 Subject: [PATCH 1512/6849] pstore: Add console log messages support Pstore doesn't support logging kernel messages in run-time, it only dumps dmesg when kernel oopses/panics. This makes pstore useless for debugging hangs caused by HW issues or improper use of HW (e.g. weird device inserted -> driver tried to write a reserved bits -> SoC hanged. In that case we don't get any messages in the pstore. Therefore, let's add a runtime logging support: PSTORE_TYPE_CONSOLE. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Acked-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- fs/pstore/Kconfig | 7 +++++++ fs/pstore/inode.c | 3 +++ fs/pstore/platform.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/pstore.h | 1 + 4 files changed, 48 insertions(+) diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig index 23ade2680a4a..d044de6ee308 100644 --- a/fs/pstore/Kconfig +++ b/fs/pstore/Kconfig @@ -12,6 +12,13 @@ config PSTORE If you don't have a platform persistent store driver, say N. +config PSTORE_CONSOLE + bool "Log kernel console messages" + depends on PSTORE + help + When the option is enabled, pstore will log all kernel + messages, even if no oops or panic happened. + config PSTORE_RAM tristate "Log panic/oops to a RAM buffer" depends on PSTORE diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 11a2aa2a56c4..45bff5441b04 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -212,6 +212,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, case PSTORE_TYPE_DMESG: sprintf(name, "dmesg-%s-%lld", psname, id); break; + case PSTORE_TYPE_CONSOLE: + sprintf(name, "console-%s", psname); + break; case PSTORE_TYPE_MCE: sprintf(name, "mce-%s-%lld", psname, id); break; diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 82c585f715e3..61461ed9b6c8 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -1,6 +1,7 @@ /* * Persistent Storage - platform driver interface parts. * + * Copyright (C) 2007-2008 Google, Inc. * Copyright (C) 2010 Intel Corporation * * This program is free software; you can redistribute it and/or modify @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -156,6 +158,40 @@ static struct kmsg_dumper pstore_dumper = { .dump = pstore_dump, }; +#ifdef CONFIG_PSTORE_CONSOLE +static void pstore_console_write(struct console *con, const char *s, unsigned c) +{ + const char *e = s + c; + + while (s < e) { + unsigned long flags; + + if (c > psinfo->bufsize) + c = psinfo->bufsize; + spin_lock_irqsave(&psinfo->buf_lock, flags); + memcpy(psinfo->buf, s, c); + psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); + spin_unlock_irqrestore(&psinfo->buf_lock, flags); + s += c; + c = e - s; + } +} + +static struct console pstore_console = { + .name = "pstore", + .write = pstore_console_write, + .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME, + .index = -1, +}; + +static void pstore_register_console(void) +{ + register_console(&pstore_console); +} +#else +static void pstore_register_console(void) {} +#endif + /* * platform specific persistent storage driver registers with * us here. If pstore is already mounted, call the platform @@ -193,6 +229,7 @@ int pstore_register(struct pstore_info *psi) pstore_get_records(0); kmsg_dump_register(&pstore_dumper); + pstore_register_console(); pstore_timer.expires = jiffies + PSTORE_INTERVAL; add_timer(&pstore_timer); diff --git a/include/linux/pstore.h b/include/linux/pstore.h index e1461e143be2..1bd014b8e432 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h @@ -29,6 +29,7 @@ enum pstore_type_id { PSTORE_TYPE_DMESG = 0, PSTORE_TYPE_MCE = 1, + PSTORE_TYPE_CONSOLE = 2, PSTORE_TYPE_UNKNOWN = 255 }; -- GitLab From cac2eb7b580c95e3871a71276c99e2bd751a1624 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:20 -0700 Subject: [PATCH 1513/6849] pstore/ram: Give proper names to dump-related variables We're about to add support for other message types, so let's rename some variables to not be confused later. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 453030f9c5bc..9b274b98bf3b 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -68,9 +68,9 @@ struct ramoops_context { size_t record_size; int dump_oops; bool ecc; - unsigned int count; - unsigned int max_count; - unsigned int read_count; + unsigned int max_dump_cnt; + unsigned int dump_write_cnt; + unsigned int dump_read_cnt; struct pstore_info pstore; }; @@ -81,7 +81,7 @@ static int ramoops_pstore_open(struct pstore_info *psi) { struct ramoops_context *cxt = psi->data; - cxt->read_count = 0; + cxt->dump_read_cnt = 0; return 0; } @@ -94,10 +94,10 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, struct ramoops_context *cxt = psi->data; struct persistent_ram_zone *prz; - if (cxt->read_count >= cxt->max_count) + if (cxt->dump_read_cnt >= cxt->max_dump_cnt) return -EINVAL; - *id = cxt->read_count++; + *id = cxt->dump_read_cnt++; prz = cxt->przs[*id]; /* Only supports dmesg output so far. */ @@ -141,7 +141,7 @@ static int ramoops_pstore_write(enum pstore_type_id type, size_t size, struct pstore_info *psi) { struct ramoops_context *cxt = psi->data; - struct persistent_ram_zone *prz = cxt->przs[cxt->count]; + struct persistent_ram_zone *prz = cxt->przs[cxt->dump_write_cnt]; size_t hlen; /* Currently ramoops is designed to only store dmesg dumps. */ @@ -172,7 +172,7 @@ static int ramoops_pstore_write(enum pstore_type_id type, size = prz->buffer_size - hlen; persistent_ram_write(prz, cxt->pstore.buf, size); - cxt->count = (cxt->count + 1) % cxt->max_count; + cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt; return 0; } @@ -182,7 +182,7 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, { struct ramoops_context *cxt = psi->data; - if (id >= cxt->max_count) + if (id >= cxt->max_dump_cnt) return -EINVAL; persistent_ram_free_old(cxt->przs[id]); @@ -213,7 +213,7 @@ static int __init ramoops_probe(struct platform_device *pdev) /* Only a single ramoops area allowed at a time, so fail extra * probes. */ - if (cxt->max_count) + if (cxt->max_dump_cnt) goto fail_out; if (!pdata->mem_size || !pdata->record_size) { @@ -239,22 +239,22 @@ static int __init ramoops_probe(struct platform_device *pdev) goto fail_out; } - cxt->max_count = pdata->mem_size / pdata->record_size; - cxt->count = 0; + cxt->max_dump_cnt = pdata->mem_size / pdata->record_size; + cxt->dump_read_cnt = 0; cxt->size = pdata->mem_size; cxt->phys_addr = pdata->mem_address; cxt->record_size = pdata->record_size; cxt->dump_oops = pdata->dump_oops; cxt->ecc = pdata->ecc; - cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_count, GFP_KERNEL); + cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt, GFP_KERNEL); if (!cxt->przs) { err = -ENOMEM; dev_err(dev, "failed to initialize a prz array\n"); goto fail_out; } - for (i = 0; i < cxt->max_count; i++) { + for (i = 0; i < cxt->max_dump_cnt; i++) { size_t sz = cxt->record_size; phys_addr_t start = cxt->phys_addr + sz * i; @@ -293,7 +293,7 @@ static int __init ramoops_probe(struct platform_device *pdev) pr_info("attached 0x%lx@0x%llx (%ux0x%zx), ecc: %s\n", cxt->size, (unsigned long long)cxt->phys_addr, - cxt->max_count, cxt->record_size, + cxt->max_dump_cnt, cxt->record_size, ramoops_ecc ? "on" : "off"); return 0; @@ -302,7 +302,7 @@ fail_buf: kfree(cxt->pstore.buf); fail_clear: cxt->pstore.bufsize = 0; - cxt->max_count = 0; + cxt->max_dump_cnt = 0; fail_przs: for (i = 0; cxt->przs[i]; i++) persistent_ram_free(cxt->przs[i]); @@ -321,7 +321,7 @@ static int __exit ramoops_remove(struct platform_device *pdev) iounmap(cxt->virt_addr); release_mem_region(cxt->phys_addr, cxt->size); - cxt->max_count = 0; + cxt->max_dump_cnt = 0; /* TODO(kees): When pstore supports unregistering, call it here. */ kfree(cxt->pstore.buf); -- GitLab From f4c5d2423c64266ba0daa9cc803d1d5ba469fe36 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:21 -0700 Subject: [PATCH 1514/6849] pstore/ram: Factor dmesg przs initialization out of probe() This will help make code clearer when we'll add support for other message types. This also makes probe() much shorter and understandable, plus makes mem/record size checking a bit easier. Implementation detail: we now use a paddr pointer, this will be used for allocating persistent ram zones for other message types. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 99 +++++++++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 37 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 9b274b98bf3b..6b7676738493 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -202,13 +202,65 @@ static struct ramoops_context oops_cxt = { }, }; +static void ramoops_free_przs(struct ramoops_context *cxt) +{ + int i; + + if (!cxt->przs) + return; + + for (i = 0; cxt->przs[i]; i++) + persistent_ram_free(cxt->przs[i]); + kfree(cxt->przs); +} + +static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, + phys_addr_t *paddr, size_t dump_mem_sz) +{ + int err = -ENOMEM; + int i; + + if (!cxt->record_size) + return 0; + + cxt->max_dump_cnt = dump_mem_sz / cxt->record_size; + if (!cxt->max_dump_cnt) + return -ENOMEM; + + cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt, + GFP_KERNEL); + if (!cxt->przs) { + dev_err(dev, "failed to initialize a prz array for dumps\n"); + return -ENOMEM; + } + + for (i = 0; i < cxt->max_dump_cnt; i++) { + size_t sz = cxt->record_size; + + cxt->przs[i] = persistent_ram_new(*paddr, sz, cxt->ecc); + if (IS_ERR(cxt->przs[i])) { + err = PTR_ERR(cxt->przs[i]); + dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", + sz, (unsigned long long)*paddr, err); + goto fail_prz; + } + *paddr += sz; + } + + return 0; +fail_prz: + ramoops_free_przs(cxt); + return err; +} + static int __init ramoops_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ramoops_platform_data *pdata = pdev->dev.platform_data; struct ramoops_context *cxt = &oops_cxt; + size_t dump_mem_sz; + phys_addr_t paddr; int err = -EINVAL; - int i; /* Only a single ramoops area allowed at a time, so fail extra * probes. @@ -225,21 +277,6 @@ static int __init ramoops_probe(struct platform_device *pdev) pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); pdata->record_size = rounddown_pow_of_two(pdata->record_size); - /* Check for the minimum memory size */ - if (pdata->mem_size < MIN_MEM_SIZE && - pdata->record_size < MIN_MEM_SIZE) { - pr_err("memory size too small, minimum is %lu\n", - MIN_MEM_SIZE); - goto fail_out; - } - - if (pdata->mem_size < pdata->record_size) { - pr_err("The memory size must be larger than the " - "records size\n"); - goto fail_out; - } - - cxt->max_dump_cnt = pdata->mem_size / pdata->record_size; cxt->dump_read_cnt = 0; cxt->size = pdata->mem_size; cxt->phys_addr = pdata->mem_address; @@ -247,24 +284,14 @@ static int __init ramoops_probe(struct platform_device *pdev) cxt->dump_oops = pdata->dump_oops; cxt->ecc = pdata->ecc; - cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt, GFP_KERNEL); - if (!cxt->przs) { - err = -ENOMEM; - dev_err(dev, "failed to initialize a prz array\n"); - goto fail_out; - } - - for (i = 0; i < cxt->max_dump_cnt; i++) { - size_t sz = cxt->record_size; - phys_addr_t start = cxt->phys_addr + sz * i; + paddr = cxt->phys_addr; - cxt->przs[i] = persistent_ram_new(start, sz, cxt->ecc); - if (IS_ERR(cxt->przs[i])) { - err = PTR_ERR(cxt->przs[i]); - dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", - sz, (unsigned long long)start, err); - goto fail_przs; - } + dump_mem_sz = cxt->size; + err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); + if (err) { + pr_err("memory size too small, minimum is %lu\n", + cxt->record_size); + goto fail_count; } cxt->pstore.data = cxt; @@ -303,10 +330,8 @@ fail_buf: fail_clear: cxt->pstore.bufsize = 0; cxt->max_dump_cnt = 0; -fail_przs: - for (i = 0; cxt->przs[i]; i++) - persistent_ram_free(cxt->przs[i]); - kfree(cxt->przs); +fail_count: + ramoops_free_przs(cxt); fail_out: return err; } -- GitLab From 755d66b48fe5a1f2a07802fcc8704e8b9e775e7d Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:22 -0700 Subject: [PATCH 1515/6849] pstore/ram: Factor ramoops_get_next_prz() out of ramoops_pstore_read() This will help make code clearer when we'll add support for other message types. The patch also changes return value from -EINVAL to 0 in case of end-of-records. The exact value doesn't matter for pstore (it should be just <= 0), but 0 feels more correct. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 6b7676738493..d770d7266e96 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -85,6 +85,33 @@ static int ramoops_pstore_open(struct pstore_info *psi) return 0; } +static struct persistent_ram_zone * +ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, + u64 *id, + enum pstore_type_id *typep, enum pstore_type_id type, + bool update) +{ + struct persistent_ram_zone *prz; + int i = (*c)++; + + if (i >= max) + return NULL; + + prz = przs[i]; + + if (update) { + /* Update old/shadowed buffer. */ + persistent_ram_save_old(prz); + if (!persistent_ram_old_size(prz)) + return NULL; + } + + *typep = type; + *id = i; + + return prz; +} + static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, struct timespec *time, char **buf, @@ -94,20 +121,16 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, struct ramoops_context *cxt = psi->data; struct persistent_ram_zone *prz; - if (cxt->dump_read_cnt >= cxt->max_dump_cnt) - return -EINVAL; - - *id = cxt->dump_read_cnt++; - prz = cxt->przs[*id]; + prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt, + cxt->max_dump_cnt, id, type, + PSTORE_TYPE_DMESG, 1); + if (!prz) + return 0; - /* Only supports dmesg output so far. */ - *type = PSTORE_TYPE_DMESG; /* TODO(kees): Bogus time for the moment. */ time->tv_sec = 0; time->tv_nsec = 0; - /* Update old/shadowed buffer. */ - persistent_ram_save_old(prz); size = persistent_ram_old_size(prz); *buf = kmalloc(size, GFP_KERNEL); if (*buf == NULL) -- GitLab From b5d38e9bf1b0c4db19e336b59b38dfb5d28bf1bf Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:23 -0700 Subject: [PATCH 1516/6849] pstore/ram: Add console messages handling The console log size is configurable via ramoops.console_size module option, and the log itself is available via /console-ramoops file. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 100 +++++++++++++++++++++++++++++++------ include/linux/pstore_ram.h | 1 + 2 files changed, 87 insertions(+), 14 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index d770d7266e96..c7acf94ff475 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -41,6 +41,10 @@ module_param(record_size, ulong, 0400); MODULE_PARM_DESC(record_size, "size of each dump done on oops/panic"); +static ulong ramoops_console_size = MIN_MEM_SIZE; +module_param_named(console_size, ramoops_console_size, ulong, 0400); +MODULE_PARM_DESC(console_size, "size of kernel console log"); + static ulong mem_address; module_param(mem_address, ulong, 0400); MODULE_PARM_DESC(mem_address, @@ -63,14 +67,17 @@ MODULE_PARM_DESC(ramoops_ecc, struct ramoops_context { struct persistent_ram_zone **przs; + struct persistent_ram_zone *cprz; phys_addr_t phys_addr; unsigned long size; size_t record_size; + size_t console_size; int dump_oops; bool ecc; unsigned int max_dump_cnt; unsigned int dump_write_cnt; unsigned int dump_read_cnt; + unsigned int console_read_cnt; struct pstore_info pstore; }; @@ -82,6 +89,7 @@ static int ramoops_pstore_open(struct pstore_info *psi) struct ramoops_context *cxt = psi->data; cxt->dump_read_cnt = 0; + cxt->console_read_cnt = 0; return 0; } @@ -124,6 +132,9 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt, cxt->max_dump_cnt, id, type, PSTORE_TYPE_DMESG, 1); + if (!prz) + prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt, + 1, id, type, PSTORE_TYPE_CONSOLE, 0); if (!prz) return 0; @@ -167,7 +178,13 @@ static int ramoops_pstore_write(enum pstore_type_id type, struct persistent_ram_zone *prz = cxt->przs[cxt->dump_write_cnt]; size_t hlen; - /* Currently ramoops is designed to only store dmesg dumps. */ + if (type == PSTORE_TYPE_CONSOLE) { + if (!cxt->cprz) + return -ENOMEM; + persistent_ram_write(cxt->cprz, cxt->pstore.buf, size); + return 0; + } + if (type != PSTORE_TYPE_DMESG) return -EINVAL; @@ -204,12 +221,23 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, struct pstore_info *psi) { struct ramoops_context *cxt = psi->data; + struct persistent_ram_zone *prz; - if (id >= cxt->max_dump_cnt) + switch (type) { + case PSTORE_TYPE_DMESG: + if (id >= cxt->max_dump_cnt) + return -EINVAL; + prz = cxt->przs[id]; + break; + case PSTORE_TYPE_CONSOLE: + prz = cxt->cprz; + break; + default: return -EINVAL; + } - persistent_ram_free_old(cxt->przs[id]); - persistent_ram_zap(cxt->przs[id]); + persistent_ram_free_old(prz); + persistent_ram_zap(prz); return 0; } @@ -276,6 +304,32 @@ fail_prz: return err; } +static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt, + struct persistent_ram_zone **prz, + phys_addr_t *paddr, size_t sz) +{ + if (!sz) + return 0; + + if (*paddr + sz > *paddr + cxt->size) + return -ENOMEM; + + *prz = persistent_ram_new(*paddr, sz, cxt->ecc); + if (IS_ERR(*prz)) { + int err = PTR_ERR(*prz); + + dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", + sz, (unsigned long long)*paddr, err); + return err; + } + + persistent_ram_zap(*prz); + + *paddr += sz; + + return 0; +} + static int __init ramoops_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -291,34 +345,50 @@ static int __init ramoops_probe(struct platform_device *pdev) if (cxt->max_dump_cnt) goto fail_out; - if (!pdata->mem_size || !pdata->record_size) { - pr_err("The memory size and the record size must be " + if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size)) { + pr_err("The memory size and the record/console size must be " "non-zero\n"); goto fail_out; } pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); pdata->record_size = rounddown_pow_of_two(pdata->record_size); + pdata->console_size = rounddown_pow_of_two(pdata->console_size); cxt->dump_read_cnt = 0; cxt->size = pdata->mem_size; cxt->phys_addr = pdata->mem_address; cxt->record_size = pdata->record_size; + cxt->console_size = pdata->console_size; cxt->dump_oops = pdata->dump_oops; cxt->ecc = pdata->ecc; paddr = cxt->phys_addr; - dump_mem_sz = cxt->size; + dump_mem_sz = cxt->size - cxt->console_size; err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); - if (err) { + if (err) + goto fail_out; + + err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr, cxt->console_size); + if (err) + goto fail_init_cprz; + + if (!cxt->przs && !cxt->cprz) { pr_err("memory size too small, minimum is %lu\n", - cxt->record_size); - goto fail_count; + cxt->console_size + cxt->record_size); + goto fail_cnt; } cxt->pstore.data = cxt; - cxt->pstore.bufsize = cxt->przs[0]->buffer_size; + /* + * Console can handle any buffer size, so prefer dumps buffer + * size since usually it is smaller. + */ + if (cxt->przs) + cxt->pstore.bufsize = cxt->przs[0]->buffer_size; + else + cxt->pstore.bufsize = cxt->cprz->buffer_size; cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL); spin_lock_init(&cxt->pstore.buf_lock); if (!cxt->pstore.buf) { @@ -341,9 +411,8 @@ static int __init ramoops_probe(struct platform_device *pdev) record_size = pdata->record_size; dump_oops = pdata->dump_oops; - pr_info("attached 0x%lx@0x%llx (%ux0x%zx), ecc: %s\n", + pr_info("attached 0x%lx@0x%llx, ecc: %s\n", cxt->size, (unsigned long long)cxt->phys_addr, - cxt->max_dump_cnt, cxt->record_size, ramoops_ecc ? "on" : "off"); return 0; @@ -353,7 +422,9 @@ fail_buf: fail_clear: cxt->pstore.bufsize = 0; cxt->max_dump_cnt = 0; -fail_count: +fail_cnt: + kfree(cxt->cprz); +fail_init_cprz: ramoops_free_przs(cxt); fail_out: return err; @@ -405,6 +476,7 @@ static int __init ramoops_init(void) dummy_data->mem_size = mem_size; dummy_data->mem_address = mem_address; dummy_data->record_size = record_size; + dummy_data->console_size = ramoops_console_size; dummy_data->dump_oops = dump_oops; dummy_data->ecc = ramoops_ecc; dummy = platform_create_bundle(&ramoops_driver, ramoops_probe, diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 3b823d49a85a..9385d41cb1c3 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -93,6 +93,7 @@ struct ramoops_platform_data { unsigned long mem_size; unsigned long mem_address; unsigned long record_size; + unsigned long console_size; int dump_oops; bool ecc; }; -- GitLab From 602b5be4f14cabd5b751c340919958549475ab62 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:24 -0700 Subject: [PATCH 1517/6849] pstore/ram_core: Silence some printks Since we use multiple regions, the messages are somewhat annoying. We do print total mapped memory already, so no need to print the information for each region in the library routines. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Acked-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index c5fbdbbf81ac..78f6d4b2addb 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -409,14 +409,14 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool " size %zu, start %zu\n", buffer_size(prz), buffer_start(prz)); else { - pr_info("persistent_ram: found existing buffer," + pr_debug("persistent_ram: found existing buffer," " size %zu, start %zu\n", buffer_size(prz), buffer_start(prz)); persistent_ram_save_old(prz); return 0; } } else { - pr_info("persistent_ram: no valid data in buffer" + pr_debug("persistent_ram: no valid data in buffer" " (sig = 0x%08x)\n", prz->buffer->sig); } -- GitLab From 958502d836cf18c6f39bdb787b76d53839e4d8aa Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:25 -0700 Subject: [PATCH 1518/6849] pstore/ram: Add some more documentation and examples Suggested-by: Shuah Khan Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Acked-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- Documentation/ramoops.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt index 4ba7db231cb2..59a74a8ee2e5 100644 --- a/Documentation/ramoops.txt +++ b/Documentation/ramoops.txt @@ -40,6 +40,12 @@ corrupt, but usually it is restorable. Setting the ramoops parameters can be done in 2 different manners: 1. Use the module parameters (which have the names of the variables described as before). + For quick debugging, you can also reserve parts of memory during boot + and then use the reserved memory for ramoops. For example, assuming a machine + with > 128 MB of memory, the following kernel command line will tell the + kernel to use only the first 128 MB of memory, and place ECC-protected ramoops + region at 128 MB boundary: + "mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1" 2. Use a platform device and set the platform data. The parameters can then be set through that platform data. An example of doing that is: @@ -70,6 +76,14 @@ if (ret) { return ret; } +You can specify either RAM memory or peripheral devices' memory. However, when +specifying RAM, be sure to reserve the memory by issuing memblock_reserve() +very early in the architecture code, e.g.: + +#include + +memblock_reserve(ramoops_data.mem_address, ramoops_data.mem_size); + 3. Dump format The data dump begins with a header, currently defined as "====" followed by a -- GitLab From b8587daa756141da776e3d4c3a5a315f5af78708 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:27 -0700 Subject: [PATCH 1519/6849] pstore/ram_core: Remove now unused code The code tried to maintain the global list of persistent ram zones, which isn't a great idea overall, plus since Android's ram_console is no longer there, we can remove some unused functions. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Acked-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram_core.c | 77 -------------------------------------- include/linux/pstore_ram.h | 19 ---------- 2 files changed, 96 deletions(-) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 78f6d4b2addb..0fd81611525c 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -35,8 +35,6 @@ struct persistent_ram_buffer { #define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */ -static __initdata LIST_HEAD(persistent_ram_list); - static inline size_t buffer_size(struct persistent_ram_zone *prz) { return atomic_read(&prz->buffer->size); @@ -462,78 +460,3 @@ err: kfree(prz); return ERR_PTR(ret); } - -#ifndef MODULE -static int __init persistent_ram_buffer_init(const char *name, - struct persistent_ram_zone *prz) -{ - int i; - struct persistent_ram *ram; - struct persistent_ram_descriptor *desc; - phys_addr_t start; - - list_for_each_entry(ram, &persistent_ram_list, node) { - start = ram->start; - for (i = 0; i < ram->num_descs; i++) { - desc = &ram->descs[i]; - if (!strcmp(desc->name, name)) - return persistent_ram_buffer_map(start, - desc->size, prz); - start += desc->size; - } - } - - return -EINVAL; -} - -static __init -struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) -{ - struct persistent_ram_zone *prz; - int ret = -ENOMEM; - - prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); - if (!prz) { - pr_err("persistent_ram: failed to allocate persistent ram zone\n"); - goto err; - } - - ret = persistent_ram_buffer_init(dev_name(dev), prz); - if (ret) { - pr_err("persistent_ram: failed to initialize buffer\n"); - goto err; - } - - persistent_ram_post_init(prz, ecc); - - return prz; -err: - kfree(prz); - return ERR_PTR(ret); -} - -struct persistent_ram_zone * __init -persistent_ram_init_ringbuffer(struct device *dev, bool ecc) -{ - return __persistent_ram_init(dev, ecc); -} - -int __init persistent_ram_early_init(struct persistent_ram *ram) -{ - int ret; - - ret = memblock_reserve(ram->start, ram->size); - if (ret) { - pr_err("Failed to reserve persistent memory from %08lx-%08lx\n", - (long)ram->start, (long)(ram->start + ram->size - 1)); - return ret; - } - - list_add_tail(&ram->node, &persistent_ram_list); - - pr_info("Initialized persistent memory from %08lx-%08lx\n", - (long)ram->start, (long)(ram->start + ram->size - 1)); - - return 0; -} -#endif diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 9385d41cb1c3..2470bb591434 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -25,21 +25,6 @@ struct persistent_ram_buffer; -struct persistent_ram_descriptor { - const char *name; - phys_addr_t size; -}; - -struct persistent_ram { - phys_addr_t start; - phys_addr_t size; - - int num_descs; - struct persistent_ram_descriptor *descs; - - struct list_head node; -}; - struct persistent_ram_zone { phys_addr_t paddr; size_t size; @@ -63,15 +48,11 @@ struct persistent_ram_zone { size_t old_log_size; }; -int persistent_ram_early_init(struct persistent_ram *ram); - struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, size_t size, bool ecc); void persistent_ram_free(struct persistent_ram_zone *prz); void persistent_ram_zap(struct persistent_ram_zone *prz); -struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, - bool ecc); int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, unsigned int count); -- GitLab From a3f5f075c2e2c52c9c656c54ea77ceff5b2e1e25 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:28 -0700 Subject: [PATCH 1520/6849] pstore/platform: Make automatic updates interval configurable There is no behavioural change, the default value is still 60 seconds. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/platform.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 61461ed9b6c8..34ca3141eb0a 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "internal.h" @@ -40,7 +41,10 @@ * whether the system is actually still running well enough * to let someone see the entry */ -#define PSTORE_INTERVAL (60 * HZ) +static int pstore_update_ms = 60000; +module_param_named(update_ms, pstore_update_ms, int, 0600); +MODULE_PARM_DESC(update_ms, "milliseconds before pstore updates its content " + "(default is 60000; -1 means runtime updates are disabled)"); static int pstore_new_entry; @@ -231,8 +235,11 @@ int pstore_register(struct pstore_info *psi) kmsg_dump_register(&pstore_dumper); pstore_register_console(); - pstore_timer.expires = jiffies + PSTORE_INTERVAL; - add_timer(&pstore_timer); + if (pstore_update_ms >= 0) { + pstore_timer.expires = jiffies + + msecs_to_jiffies(pstore_update_ms); + add_timer(&pstore_timer); + } return 0; } @@ -291,7 +298,7 @@ static void pstore_timefunc(unsigned long dummy) schedule_work(&pstore_work); } - mod_timer(&pstore_timer, jiffies + PSTORE_INTERVAL); + mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms)); } module_param(backend, charp, 0444); -- GitLab From 521f7288a8126a8ec28e3ab623aacf0590684b80 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:29 -0700 Subject: [PATCH 1521/6849] pstore/platform: Disable automatic updates by default Having automatic updates seems pointless for production system, and even dangerous and thus counter-productive: 1. If we can mount pstore, or read files, we can as well read /proc/kmsg. So, there's little point in duplicating the functionality and present the same information but via another userland ABI; 2. Expecting the kernel to behave sanely after oops/panic is naive. It might work, but you'd rather not try it. Screwed up kernel can do rather bad things, like recursive faults[1]; and pstore rather provoking bad things to happen. It uses: 1. Timers (assumes sane interrupts state); 2. Workqueues and mutexes (assumes scheduler in a sane state); 3. kzalloc (a working slab allocator); That's too much for a dead kernel, so the debugging facility itself might just make debugging harder, which is not what we want. Maybe for non-oops message types it would make sense to re-enable automatic updates, but so far I don't see any use case for this. Even for tracing, it has its own run-time/normal ABI, so we're only interested in pstore upon next boot, to retrieve what has gone wrong with HW or SW. So, let's disable the updates by default. [1] BUG: unable to handle kernel paging request at fffffffffffffff8 IP: [] kthread_data+0xb/0x20 [...] Process kworker/0:1 (pid: 14, threadinfo ffff8800072c0000, task ffff88000725b100) [... Call Trace: [] wq_worker_sleeping+0x10/0xa0 [] __schedule+0x568/0x7d0 [] ? trace_hardirqs_on+0xd/0x10 [] ? call_rcu_sched+0x12/0x20 [] ? release_task+0x156/0x2d0 [] ? release_task+0x1e/0x2d0 [] ? trace_hardirqs_on+0xd/0x10 [] schedule+0x24/0x70 [] do_exit+0x1f8/0x370 [] oops_end+0x77/0xb0 [] no_context+0x1a6/0x1b5 [] __bad_area_nosemaphore+0x1ce/0x1ed [] ? ttwu_queue+0xc6/0xe0 [] bad_area_nosemaphore+0xe/0x10 [] do_page_fault+0x2c7/0x450 [] ? __lock_release+0x6b/0xe0 [] ? mark_held_locks+0x61/0x140 [] ? __wake_up+0x4e/0x70 [] ? trace_hardirqs_off_thunk+0x3a/0x3c [] ? pstore_register+0x120/0x120 [] page_fault+0x1f/0x30 [] ? pstore_register+0x120/0x120 [] ? memcpy+0x68/0x110 [] ? pstore_get_records+0x3a/0x130 [] ? persistent_ram_copy_old+0x64/0x90 [] ramoops_pstore_read+0x84/0x130 [] pstore_get_records+0x79/0x130 [] ? process_one_work+0x116/0x450 [] ? pstore_register+0x120/0x120 [] pstore_dowork+0xe/0x10 [] process_one_work+0x174/0x450 [] ? process_one_work+0x116/0x450 [] worker_thread+0x123/0x2d0 [] ? manage_workers.isra.28+0x120/0x120 [] kthread+0x8e/0xa0 [] kernel_thread_helper+0x4/0x10 [] ? retint_restore_args+0xe/0xe [] ? __init_kthread_worker+0x70/0x70 [] ? gs_change+0xb/0xb Code: be e2 00 00 00 48 c7 c7 d1 2a 4e 81 e8 bf fb fd ff 48 8b 5d f0 4c 8b 65 f8 c9 c3 0f 1f 44 00 00 48 8b 87 08 02 00 00 55 48 89 e5 <48> 8b 40 f8 5d c3 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 RIP [] kthread_data+0xb/0x20 RSP CR2: fffffffffffffff8 ---[ end trace 996a332dc399111d ]--- Fixing recursive fault but reboot is needed! Signed-off-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman --- fs/pstore/platform.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 34ca3141eb0a..be4614f24a2f 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -41,10 +41,12 @@ * whether the system is actually still running well enough * to let someone see the entry */ -static int pstore_update_ms = 60000; +static int pstore_update_ms = -1; module_param_named(update_ms, pstore_update_ms, int, 0600); MODULE_PARM_DESC(update_ms, "milliseconds before pstore updates its content " - "(default is 60000; -1 means runtime updates are disabled)"); + "(default is -1, which means runtime updates are disabled; " + "enabling this option is not safe, it may lead to further " + "corruption on Oopses)"); static int pstore_new_entry; -- GitLab From 15d76446205710ddfcba6cc9156c7883074f84b1 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 26 May 2012 06:20:26 -0700 Subject: [PATCH 1522/6849] staging/android: Remove ram_console driver All the functionality is now supported by pstore and pstore_ram drivers. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Acked-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 5 - drivers/staging/android/Makefile | 1 - drivers/staging/android/ram_console.c | 181 -------------------------- 3 files changed, 187 deletions(-) delete mode 100644 drivers/staging/android/ram_console.c diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 0e16b594460f..0ce50d12c30f 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -25,11 +25,6 @@ config ANDROID_LOGGER tristate "Android log driver" default n -config ANDROID_RAM_CONSOLE - bool "Android RAM buffer console" - depends on !S390 && !UML && HAVE_MEMBLOCK && PSTORE_RAM=y - default n - config ANDROID_TIMED_OUTPUT bool "Timed output class driver" default y diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 98711e2b2afa..e16fcd51716e 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o -obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c deleted file mode 100644 index 7add022b1c22..000000000000 --- a/drivers/staging/android/ram_console.c +++ /dev/null @@ -1,181 +0,0 @@ -/* drivers/android/ram_console.c - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define pr_fmt(fmt) "ram_console: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ram_console.h" - -static struct persistent_ram_zone *ram_console_zone; -static const char *bootinfo; -static size_t bootinfo_size; - -static void -ram_console_write(struct console *console, const char *s, unsigned int count) -{ - struct persistent_ram_zone *prz = console->data; - persistent_ram_write(prz, s, count); -} - -static struct console ram_console = { - .name = "ram", - .write = ram_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME, - .index = -1, -}; - -void ram_console_enable_console(int enabled) -{ - if (enabled) - ram_console.flags |= CON_ENABLED; - else - ram_console.flags &= ~CON_ENABLED; -} - -static int __init ram_console_probe(struct platform_device *pdev) -{ - struct ram_console_platform_data *pdata = pdev->dev.platform_data; - struct persistent_ram_zone *prz; - - prz = persistent_ram_init_ringbuffer(&pdev->dev, true); - if (IS_ERR(prz)) - return PTR_ERR(prz); - - - if (pdata) { - bootinfo = kstrdup(pdata->bootinfo, GFP_KERNEL); - if (bootinfo) - bootinfo_size = strlen(bootinfo); - } - - ram_console_zone = prz; - ram_console.data = prz; - - register_console(&ram_console); - - return 0; -} - -static struct platform_driver ram_console_driver = { - .driver = { - .name = "ram_console", - }, -}; - -static int __init ram_console_module_init(void) -{ - return platform_driver_probe(&ram_console_driver, ram_console_probe); -} - -#ifndef CONFIG_PRINTK -#define dmesg_restrict 0 -#endif - -static ssize_t ram_console_read_old(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - loff_t pos = *offset; - ssize_t count; - struct persistent_ram_zone *prz = ram_console_zone; - size_t old_log_size = persistent_ram_old_size(prz); - const char *old_log = persistent_ram_old(prz); - char *str; - int ret; - - if (dmesg_restrict && !capable(CAP_SYSLOG)) - return -EPERM; - - /* Main last_kmsg log */ - if (pos < old_log_size) { - count = min(len, (size_t)(old_log_size - pos)); - if (copy_to_user(buf, old_log + pos, count)) - return -EFAULT; - goto out; - } - - /* ECC correction notice */ - pos -= old_log_size; - count = persistent_ram_ecc_string(prz, NULL, 0); - if (pos < count) { - str = kmalloc(count, GFP_KERNEL); - if (!str) - return -ENOMEM; - persistent_ram_ecc_string(prz, str, count + 1); - count = min(len, (size_t)(count - pos)); - ret = copy_to_user(buf, str + pos, count); - kfree(str); - if (ret) - return -EFAULT; - goto out; - } - - /* Boot info passed through pdata */ - pos -= count; - if (pos < bootinfo_size) { - count = min(len, (size_t)(bootinfo_size - pos)); - if (copy_to_user(buf, bootinfo + pos, count)) - return -EFAULT; - goto out; - } - - /* EOF */ - return 0; - -out: - *offset += count; - return count; -} - -static const struct file_operations ram_console_file_ops = { - .owner = THIS_MODULE, - .read = ram_console_read_old, -}; - -static int __init ram_console_late_init(void) -{ - struct proc_dir_entry *entry; - struct persistent_ram_zone *prz = ram_console_zone; - - if (!prz) - return 0; - - if (persistent_ram_old_size(prz) == 0) - return 0; - - entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); - if (!entry) { - pr_err("failed to create proc entry\n"); - persistent_ram_free_old(prz); - return 0; - } - - entry->proc_fops = &ram_console_file_ops; - entry->size = persistent_ram_old_size(prz) + - persistent_ram_ecc_string(prz, NULL, 0) + - bootinfo_size; - - return 0; -} - -late_initcall(ram_console_late_init); -postcore_initcall(ram_console_module_init); -- GitLab From 176f7842a8c0a19e0947f630d71bb53db312812f Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:39 +0200 Subject: [PATCH 1523/6849] staging/xgifb: Remove assignments without effect This patch removes assignments to the fb_fix_screeninfo struct which are overwritten by the memset in XGIfb_get_fix() a few lines later. Since the name/id might be useful this was moved to XGIfb_get_fix(). Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 033463d1966c..729d980f0104 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1348,6 +1348,8 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, DEBUGPRN("inside get_fix"); memset(fix, 0, sizeof(struct fb_fix_screeninfo)); + strncpy(fix->id, "XGI", sizeof(fix->id) - 1); + fix->smem_start = xgifb_info->video_base; fix->smem_len = xgifb_info->video_size; @@ -2230,11 +2232,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } - strncpy(fb_info->fix.id, "XGI", sizeof(fb_info->fix.id) - 1); - fb_info->fix.type = FB_TYPE_PACKED_PIXELS; - fb_info->fix.xpanstep = 1; - fb_info->fix.ypanstep = 1; - fb_info->flags = FBINFO_FLAG_DEFAULT; fb_info->screen_base = xgifb_info->video_vbase; fb_info->fbops = &XGIfb_ops; -- GitLab From 95649c425fa2805b76f183c27aeed93f159e47cc Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:40 +0200 Subject: [PATCH 1524/6849] staging/xgifb: Add mutext for fb_mmap locking This adds a mutex for fb_mmap around smem_start and smem_len so the mutex inside the fb_mmap() is actually used. Changing of these fields before calling the framebuffer_register() are not mutexed. We check whether framebuffer_register has been called by reading fbinfo->count. See 537a1bf0 - "fbdev: add mutex for fb_mmap locking" by Krzysztof Helt for details. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 729d980f0104..3a4328f28d07 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1350,10 +1350,17 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, strncpy(fix->id, "XGI", sizeof(fix->id) - 1); - fix->smem_start = xgifb_info->video_base; + /* if register_framebuffer has been called, we must lock */ + if (atomic_read(&info->count)) + mutex_lock(&info->mm_lock); + fix->smem_start = xgifb_info->video_base; fix->smem_len = xgifb_info->video_size; + /* if register_framebuffer has been called, we can unlock */ + if (atomic_read(&info->count)) + mutex_unlock(&info->mm_lock); + fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; if (xgifb_info->video_bpp == 8) -- GitLab From ac326fb96bdf720ceb4871a7219073c5fc257595 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:41 +0200 Subject: [PATCH 1525/6849] staging/xgifb: Add header #include guards to vb_table.h This patch adds a simple #include guard to vb_table.h Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_table.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d22e599cb305..9a17113849ec 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1,3 +1,5 @@ +#ifndef _VB_TABLE_ +#define _VB_TABLE_ /* yilin modify for xgi20 */ static struct SiS_MCLKData XGI340New_MCLKData[] = { {0x16, 0x01, 0x01, 166}, @@ -2696,3 +2698,4 @@ static struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = { } } }; +#endif -- GitLab From f3ca589baf317d61b87c409e205bfaf740169710 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:42 +0200 Subject: [PATCH 1526/6849] staging/xgifb: Remove superfluous header includes This patch removes all unnecessary, redundant and superfluous header includes from xgifb. Tested on hp t5325 (XGI Z11) Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 6 ------ drivers/staging/xgifb/XGI_main_26.c | 26 +------------------------- drivers/staging/xgifb/XGIfb.h | 3 --- drivers/staging/xgifb/vb_init.c | 9 --------- drivers/staging/xgifb/vb_setmode.c | 8 -------- drivers/staging/xgifb/vb_util.c | 9 --------- drivers/staging/xgifb/vgatypes.h | 1 - 7 files changed, 1 insertion(+), 61 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 9c62aeb9ede9..ce18f8c98b2d 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -1,13 +1,7 @@ #ifndef _XGIFB_MAIN #define _XGIFB_MAIN - - /* ------------------- Constant Definitions ------------------------- */ - - #include "XGIfb.h" -#include "vb_struct.h" -#include "../../video/sis/sis.h" #include "vb_def.h" #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 3a4328f28d07..338227226260 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -6,36 +6,12 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -/* #include */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include + #ifdef CONFIG_MTRR #include #endif -#include "XGIfb.h" -#include "vgatypes.h" #include "XGI_main.h" #include "vb_init.h" #include "vb_util.h" diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 9068c5ad76ec..741bba351cff 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -1,8 +1,5 @@ #ifndef _LINUX_XGIFB #define _LINUX_XGIFB -#include -#include - #include "vgatypes.h" #include "vb_struct.h" diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index c222d611431d..dd6a51995ea6 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1,19 +1,10 @@ -#include #include /* udelay */ -#include #include #include "XGIfb.h" -#include "vgatypes.h" - #include "vb_def.h" -#include "vb_struct.h" #include "vb_util.h" #include "vb_setmode.h" -#include "vb_init.h" - - -#include static const unsigned short XGINew_DDRDRAM_TYPE340[4][5] = { { 2, 13, 9, 64, 0x45}, diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index b2f4338b1109..ad1e23d3c938 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1,17 +1,9 @@ - -#include #include -#include #include "XGIfb.h" - #include "vb_def.h" -#include "vgatypes.h" -#include "vb_struct.h" -#include "vb_init.h" #include "vb_util.h" #include "vb_table.h" -#include "vb_setmode.h" #define IndexMask 0xff diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index b5c99891ead4..5c93a2202bd0 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -1,13 +1,4 @@ -#include -#include - -#include "vb_def.h" #include "vgatypes.h" -#include "vb_struct.h" - -#include "XGIfb.h" - -#include "vb_util.h" void xgifb_reg_set(unsigned long port, u8 index, u8 data) { diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index 30cdd1af81f1..7fc07194eea2 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -1,7 +1,6 @@ #ifndef _VGATYPES_ #define _VGATYPES_ -#include #include /* for struct fb_var_screeninfo for sis.h */ #include "../../video/sis/vgatypes.h" #include "../../video/sis/sis.h" /* for LCD_TYPE */ -- GitLab From 391f695b90ba8b3905c818f03188440a5df9cfe7 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:43 +0200 Subject: [PATCH 1527/6849] staging/xgifb: Consolidate XGINew_SetDRAMSize{,20}Reg This patch consolidates the almost identical functions XGINew_SetDRAMSizeReg and XGINew_SetDRAMSize20Reg as they are implemented identically except one division factor. The changed factor is now reflected in the input data. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 54 +++------------------------------ 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index dd6a51995ea6..726c33561bd1 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -7,10 +7,10 @@ #include "vb_setmode.h" static const unsigned short XGINew_DDRDRAM_TYPE340[4][5] = { - { 2, 13, 9, 64, 0x45}, - { 2, 12, 9, 32, 0x35}, - { 2, 12, 8, 16, 0x31}, - { 2, 11, 8, 8, 0x21} }; + { 2, 13, 9, 16, 0x45}, + { 2, 12, 9, 8, 0x35}, + { 2, 12, 8, 4, 0x31}, + { 2, 11, 8, 2, 0x21} }; static const unsigned short XGINew_DDRDRAM_TYPE20[12][5] = { { 2, 14, 11, 128, 0x5D}, @@ -591,50 +591,6 @@ static void XGINew_SetDRAMSizingType(int index, /* should delay 50 ns */ } -static unsigned short XGINew_SetDRAMSizeReg(int index, - const unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; - - RankSize = DRAMTYPE_TABLE[index][3] * pVBInfo->ram_bus / 32; - data = xgifb_reg_get(pVBInfo->P3c4, 0x13); - data &= 0x80; - - if (data == 0x80) - RankSize *= 2; - - data = 0; - - if (pVBInfo->ram_channel == 3) - ChannelNo = 4; - else - ChannelNo = pVBInfo->ram_channel; - - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; - - memsize = data >> 4; - - /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - xgifb_reg_set(pVBInfo->P3c4, - 0x14, - (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | - (data & 0xF0)); - - /* data |= pVBInfo->ram_channel << 2; */ - /* data |= (pVBInfo->ram_bus / 64) << 1; */ - /* xgifb_reg_set(pVBInfo->P3c4, 0x14, data); */ - - /* should delay */ - /* XGINew_SetDRAMModeRegister340(pVBInfo); */ - } - return memsize; -} - static unsigned short XGINew_SetDRAMSize20Reg(int index, const unsigned short DRAMTYPE_TABLE[][5], struct vb_device_info *pVBInfo) @@ -968,7 +924,7 @@ static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo); - memsize = XGINew_SetDRAMSizeReg(i, + memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE340, pVBInfo); -- GitLab From 672f5ee27e622c995bd0c19d2ba1bb5a55b6d902 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:44 +0200 Subject: [PATCH 1528/6849] staging/xgifb: Remove duplicated code from XGINew_DDRSizing340 Since XGINew_SetDRAMSize20Reg now handles both cases we can remove the code duplication in XGINew_DDRSizing340. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 64 +++++++++++++-------------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 726c33561bd1..512284c3de91 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -893,52 +893,38 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - int i; - unsigned short memsize, addr; + u8 i, size; + unsigned short memsize, start_addr; + const unsigned short (*dram_table)[5]; xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ XGINew_CheckChannel(HwDeviceExtension, pVBInfo); if (HwDeviceExtension->jChipType >= XG20) { - for (i = 0; i < 12; i++) { - XGINew_SetDRAMSizingType(i, - XGINew_DDRDRAM_TYPE20, - pVBInfo); - memsize = XGINew_SetDRAMSize20Reg(i, - XGINew_DDRDRAM_TYPE20, - pVBInfo); - if (memsize == 0) - continue; - - addr = memsize + (pVBInfo->ram_channel - 2) + 20; - if ((HwDeviceExtension->ulVideoMemorySize - 1) < - (unsigned long) (1 << addr)) - continue; - - if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1) - return 1; - } + dram_table = XGINew_DDRDRAM_TYPE20; + size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE20); + start_addr = 5; } else { - for (i = 0; i < 4; i++) { - XGINew_SetDRAMSizingType(i, - XGINew_DDRDRAM_TYPE340, - pVBInfo); - memsize = XGINew_SetDRAMSize20Reg(i, - XGINew_DDRDRAM_TYPE340, - pVBInfo); - - if (memsize == 0) - continue; - - addr = memsize + (pVBInfo->ram_channel - 2) + 20; - if ((HwDeviceExtension->ulVideoMemorySize - 1) < - (unsigned long) (1 << addr)) - continue; - - if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1) - return 1; - } + dram_table = XGINew_DDRDRAM_TYPE340; + size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE340); + start_addr = 9; + } + + for (i = 0; i < size; i++) { + XGINew_SetDRAMSizingType(i, dram_table, pVBInfo); + memsize = XGINew_SetDRAMSize20Reg(i, dram_table, pVBInfo); + + if (memsize == 0) + continue; + + memsize += (pVBInfo->ram_channel - 2) + 20; + if ((HwDeviceExtension->ulVideoMemorySize - 1) < + (unsigned long) (1 << memsize)) + continue; + + if (XGINew_ReadWriteRest(memsize, start_addr, pVBInfo) == 1) + return 1; } return 0; } -- GitLab From 4e55d0b3ee13bb21dc0f74217675e86486004b8b Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:45 +0200 Subject: [PATCH 1529/6849] staging/xgifb: Inline XGINew_SetDRAMSizingType Since the function XGINew_SetDRAMSizingType is only called from one location and consist only of 2 valuable lines we can simply inline it here. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 512284c3de91..63011af0d347 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -579,17 +579,6 @@ static void XGINew_SetDRAMDefaultRegister340( pVBInfo->SR15[3][pVBInfo->ram_type]); /* SR1B */ } -static void XGINew_SetDRAMSizingType(int index, - const unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - data = DRAMTYPE_TABLE[index][4]; - xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, data); - udelay(15); - /* should delay 50 ns */ -} static unsigned short XGINew_SetDRAMSize20Reg(int index, const unsigned short DRAMTYPE_TABLE[][5], @@ -912,7 +901,10 @@ static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, } for (i = 0; i < size; i++) { - XGINew_SetDRAMSizingType(i, dram_table, pVBInfo); + /* SetDRAMSizingType */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][4]); + udelay(15); /* should delay 50 ns */ + memsize = XGINew_SetDRAMSize20Reg(i, dram_table, pVBInfo); if (memsize == 0) -- GitLab From d6461e49c09a1a7f203437c084ec169563bcbf68 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:46 +0200 Subject: [PATCH 1530/6849] staging/xgifb: Remove unnecessary fields of XGINew_DDRDRAM_TYPE{340, 20} Since the first three entries in XGINew_DDRDRAM_TYPE{340,20} are never used, we can simply remove them; and instead of passing XGINew_DDRDRAM_TYPE with an index we can simply pass the value directly to XGINew_SetDRAMSize20Reg. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 63011af0d347..944653dcf1ea 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -6,25 +6,25 @@ #include "vb_util.h" #include "vb_setmode.h" -static const unsigned short XGINew_DDRDRAM_TYPE340[4][5] = { - { 2, 13, 9, 16, 0x45}, - { 2, 12, 9, 8, 0x35}, - { 2, 12, 8, 4, 0x31}, - { 2, 11, 8, 2, 0x21} }; - -static const unsigned short XGINew_DDRDRAM_TYPE20[12][5] = { - { 2, 14, 11, 128, 0x5D}, - { 2, 14, 10, 64, 0x59}, - { 2, 13, 11, 64, 0x4D}, - { 2, 14, 9, 32, 0x55}, - { 2, 13, 10, 32, 0x49}, - { 2, 12, 11, 32, 0x3D}, - { 2, 14, 8, 16, 0x51}, - { 2, 13, 9, 16, 0x45}, - { 2, 12, 10, 16, 0x39}, - { 2, 13, 8, 8, 0x41}, - { 2, 12, 9, 8, 0x35}, - { 2, 12, 8, 4, 0x31} }; +static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = { + { 16, 0x45}, + { 8, 0x35}, + { 4, 0x31}, + { 2, 0x21} }; + +static const unsigned short XGINew_DDRDRAM_TYPE20[12][2] = { + { 128, 0x5D}, + { 64, 0x59}, + { 64, 0x4D}, + { 32, 0x55}, + { 32, 0x49}, + { 32, 0x3D}, + { 16, 0x51}, + { 16, 0x45}, + { 16, 0x39}, + { 8, 0x41}, + { 8, 0x35}, + { 4, 0x31} }; #define XGIFB_ROM_SIZE 65536 @@ -580,15 +580,15 @@ static void XGINew_SetDRAMDefaultRegister340( } -static unsigned short XGINew_SetDRAMSize20Reg(int index, - const unsigned short DRAMTYPE_TABLE[][5], +static unsigned short XGINew_SetDRAMSize20Reg( + unsigned short dram_size, struct vb_device_info *pVBInfo) { unsigned short data = 0, memsize = 0; int RankSize; unsigned char ChannelNo; - RankSize = DRAMTYPE_TABLE[index][3] * pVBInfo->ram_bus / 8; + RankSize = dram_size * pVBInfo->ram_bus / 8; data = xgifb_reg_get(pVBInfo->P3c4, 0x13); data &= 0x80; @@ -884,7 +884,7 @@ static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, { u8 i, size; unsigned short memsize, start_addr; - const unsigned short (*dram_table)[5]; + const unsigned short (*dram_table)[2]; xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ @@ -902,10 +902,10 @@ static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, for (i = 0; i < size; i++) { /* SetDRAMSizingType */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][4]); + xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][1]); udelay(15); /* should delay 50 ns */ - memsize = XGINew_SetDRAMSize20Reg(i, dram_table, pVBInfo); + memsize = XGINew_SetDRAMSize20Reg(dram_table[i][0], pVBInfo); if (memsize == 0) continue; -- GitLab From f477d3e6bb1bef4f3e2286d762137ae7e8a53195 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:47 +0200 Subject: [PATCH 1531/6849] staging/xgifb: Replace constant arrays with constant values This patch removes the arrays in XGI_GetVCLK2Ptr which each contain only one value four times and replaces them with their constant value. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index ad1e23d3c938..47d60c8a848c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1010,24 +1010,6 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short LCDXlat1VCLK[4] = { VCLK65_315 + 2, - VCLK65_315 + 2, - VCLK65_315 + 2, - VCLK65_315 + 2 }; - unsigned short LCDXlat2VCLK[4] = { VCLK108_2_315 + 5, - VCLK108_2_315 + 5, - VCLK108_2_315 + 5, - VCLK108_2_315 + 5 }; - unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 }; - unsigned short LVDSXlat2VCLK[4] = { VCLK65_315 + 2, - VCLK65_315 + 2, - VCLK65_315 + 2, - VCLK65_315 + 2 }; - unsigned short LVDSXlat3VCLK[4] = { VCLK65_315 + 2, - VCLK65_315 + 2, - VCLK65_315 + 2, - VCLK65_315 + 2 }; - unsigned short CRT2Index, VCLKIndex; unsigned short modeflag, resinfo; @@ -1040,9 +1022,9 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, CRT2Index = CRT2Index >> 6; /* for LCD */ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/ if (pVBInfo->LCDResInfo != Panel_1024x768) - VCLKIndex = LCDXlat2VCLK[CRT2Index]; + VCLKIndex = VCLK108_2_315 + 5; /* LCDXlat2VCLK */ else - VCLKIndex = LCDXlat1VCLK[CRT2Index]; + VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */ } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->SetFlag & RPLLDIV2XO) { VCLKIndex = TVCLKBASE_315 + HiTVVCLKDIV2; @@ -1093,12 +1075,12 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex = VCLKIndex >> 6; if ((pVBInfo->LCDResInfo == Panel_800x600) || (pVBInfo->LCDResInfo == Panel_320x480)) - VCLKIndex = LVDSXlat1VCLK[VCLKIndex]; + VCLKIndex = VCLK40; /* LVDSXlat1VCLK */ else if ((pVBInfo->LCDResInfo == Panel_1024x768) || (pVBInfo->LCDResInfo == Panel_1024x768x75)) - VCLKIndex = LVDSXlat2VCLK[VCLKIndex]; + VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK */ else - VCLKIndex = LVDSXlat3VCLK[VCLKIndex]; + VCLKIndex = VCLK65_315 + 2; /* LVDSXlat3VCLK */ } return VCLKIndex; -- GitLab From 950725920af27251b4c3b253017572c664f2300a Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:48 +0200 Subject: [PATCH 1532/6849] staging/xgifb: Simplyfy XGI_GetVCLK2Ptr a bit This patch simplyfies the XGI_GetVCLK2Ptr a bit by moving the +=25 to a define and removing statements without effect. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 47d60c8a848c..3b9a0f724f26 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -7,6 +7,7 @@ #define IndexMask 0xff +#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25) static const unsigned short XGINew_VGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, @@ -1027,20 +1028,16 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */ } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->SetFlag & RPLLDIV2XO) { - VCLKIndex = TVCLKBASE_315 + HiTVVCLKDIV2; - VCLKIndex += 25; + VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2; } else { - VCLKIndex = TVCLKBASE_315 + HiTVVCLK; - VCLKIndex += 25; + VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK; } if (pVBInfo->SetFlag & TVSimuMode) { if (modeflag & Charx8Dot) { - VCLKIndex = TVCLKBASE_315 + HiTVSimuVCLK; - VCLKIndex += 25; + VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK; } else { - VCLKIndex = TVCLKBASE_315 + HiTVTextVCLK; - VCLKIndex += 25; + VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK; } } @@ -1058,11 +1055,9 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, } } else if (pVBInfo->VBInfo & SetCRT2ToTV) { if (pVBInfo->SetFlag & RPLLDIV2XO) { - VCLKIndex = TVCLKBASE_315 + TVVCLKDIV2; - VCLKIndex += 25; + VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2; } else { - VCLKIndex = TVCLKBASE_315 + TVVCLK; - VCLKIndex += 25; + VCLKIndex = TVCLKBASE_315_25 + TVVCLK; } } else { /* for CRT2 */ /* di+Ext_CRTVCLK */ @@ -1071,16 +1066,11 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex &= IndexMask; } } else { /* LVDS */ - VCLKIndex = CRT2Index; - VCLKIndex = VCLKIndex >> 6; if ((pVBInfo->LCDResInfo == Panel_800x600) || (pVBInfo->LCDResInfo == Panel_320x480)) VCLKIndex = VCLK40; /* LVDSXlat1VCLK */ - else if ((pVBInfo->LCDResInfo == Panel_1024x768) || - (pVBInfo->LCDResInfo == Panel_1024x768x75)) - VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK */ else - VCLKIndex = VCLK65_315 + 2; /* LVDSXlat3VCLK */ + VCLKIndex = VCLK65_315 + 2; /* LVDSXlat2VCLK, LVDSXlat3VCLK */ } return VCLKIndex; -- GitLab From 64e2498b6cd47eb64b1ced4ab173b6c5ecc4025e Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:49 +0200 Subject: [PATCH 1533/6849] staging/xgifb: Remove useless function XGI_CloseCRTC Since XGI_CloseCRTC does not perform anything useful we can simply remove it. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 3b9a0f724f26..2ffab4589531 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -6229,17 +6229,6 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, } } -static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - - tempbx = 0; - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) - tempbx = 0x08A0; - -} void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) @@ -6831,7 +6820,6 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo); XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/ - XGI_CloseCRTC(HwDeviceExtension, pVBInfo); XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo); } /* !XG20 */ else { -- GitLab From 03f76fc617fdcf0f9cde4d56c5d7c6d9d33acbc1 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:50 +0200 Subject: [PATCH 1534/6849] staging/xgifb: Replace delay lookup tables with constant values For TV Devices: The values taken from XGI_TVDelayList are always overwritten with the values from XGI_TVDelayList2 since the if condition for using the values from XGI_TVDelayList2 is identical with the check to enter this scope and thus always true. The delay values in XGI_TVDelayList2 is always 0x22 so we can simply replace it with this constant value. For LCD Devices: The LCD_DelayCompensation field is always set to 0x12 so we can simply replace this field with a constant value. This saves about 500 bytes in compiled size. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 25 ++----------- drivers/staging/xgifb/vb_struct.h | 3 -- drivers/staging/xgifb/vb_table.h | 60 ++++++++---------------------- 3 files changed, 19 insertions(+), 69 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2ffab4589531..c6c6843ef4de 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -105,9 +105,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) else pVBInfo->LCDCapList = XGI_LCDCapList; - pVBInfo->XGI_TVDelayList = XGI301TVDelayList; - pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2; - pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition; if (ChipType >= XG20) @@ -5712,32 +5709,19 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) { - unsigned short index; - unsigned char tempah, tempbl, tempbh; if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA | SetCRT2ToTV | SetCRT2ToRAMDAC)) { - tempbl = 0; tempbh = 0; - - index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */ - tempbl = pVBInfo->XGI_TVDelayList[index]; - - if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B - | VB_SIS301LV | VB_SIS302LV - | VB_XGI301C)) - tempbl = pVBInfo->XGI_TVDelayList2[index]; + tempbl = XGI301TVDelay; if (pVBInfo->VBInfo & SetCRT2ToDualEdge) tempbl = tempbl >> 4; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - /* Get LCD Delay */ - index = XGI_GetLCDCapPtr(pVBInfo); - tempbh = pVBInfo->LCDCapList[index]. - LCD_DelayCompensation; + tempbh = XGI301LCDDelay; if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) tempbl = tempbh; @@ -5763,10 +5747,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) tempbl = 0; tempbh = 0; if (pVBInfo->VBInfo & SetCRT2ToLCD) { - /* / Get LCD Delay */ - tempah = pVBInfo->LCDCapList[ - XGI_GetLCDCapPtr(pVBInfo)]. - LCD_DelayCompensation; + tempah = XGI301LCDDelay; tempah &= 0x0f; tempah = tempah << 4; xgifb_reg_and_or(pVBInfo->Part1Port, 0x2D, 0x0f, diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 38f47ffc69c4..b95497132b7b 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -126,7 +126,6 @@ struct XGI330_LCDCapStruct { unsigned char LCD_ID; unsigned short LCD_Capability; unsigned char LCD_SetFlag; - unsigned char LCD_DelayCompensation; unsigned char LCD_HSyncWidth; unsigned char LCD_VSyncWidth; unsigned char LCD_VCLK; @@ -262,8 +261,6 @@ struct vb_device_info { struct SiS_MCLKData *MCLKData; struct XGI_ECLKDataStruct *ECLKData; - unsigned char *XGI_TVDelayList; - unsigned char *XGI_TVDelayList2; unsigned char *NTSCTiming; unsigned char *PALTiming; unsigned char *HiTVExtTiming; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 9a17113849ec..50ef885adf62 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1993,70 +1993,70 @@ static unsigned short LCDLenList[] = { /* Dual link only */ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { /* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, + {Panel_1024x768, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ {Panel_1280x1024, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2_315, + 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ {Panel_1400x1050, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2_315, + 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ {Panel_1600x1200, XGI_LCDDualLink+DefaultLCDCap, LCDToFull, - 0x012, 0xC0, 0x03, VCLK162, + 0xC0, 0x03, VCLK162, 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1024x768x75 */ - {Panel_1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75, + {Panel_1024x768x75, DefaultLCDCap, 0, 0x60, 0, VCLK78_75, 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024x75 */ {Panel_1280x1024x75, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x012, 0x90, 0x03, VCLK135_5, + 0x90, 0x03, VCLK135_5, 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, + {0xFF, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; static struct XGI330_LCDCapStruct XGI_LCDCapList[] = { /* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, + {Panel_1024x768, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ {Panel_1280x1024, DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2_315, + 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ {Panel_1400x1050, DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2_315, + 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ {Panel_1600x1200, DefaultLCDCap, LCDToFull, - 0x012, 0xC0, 0x03, VCLK162, + 0xC0, 0x03, VCLK162, 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1024x768x75 */ - {Panel_1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75, + {Panel_1024x768x75, DefaultLCDCap, 0, 0x60, 0, VCLK78_75, 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024x75 */ {Panel_1280x1024x75, DefaultLCDCap, StLCDBToA, - 0x012, 0x90, 0x03, VCLK135_5, + 0x90, 0x03, VCLK135_5, 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, + {0xFF, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; @@ -2482,36 +2482,8 @@ static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] = { {0xFF, 0x00, 0} /* End mark */ }; -static unsigned char XGI301TVDelayList[] = { - 0x22, /* ; 0 ExtNTSCDelay */ - 0x22, /* ; 1 StNTSCDelay */ - 0x22, /* ; 2 ExtPALDelay */ - 0x22, /* ; 3 StPALDelay */ - 0x88, /* ; 4 ExtHiTVDelay(1080i) */ - 0xBB, /* ; 5 StHiTVDelay(1080i) */ - 0x22, /* ; 6 ExtYPbPrDelay(525i) */ - 0x22, /* ; 7 StYPbPrDealy(525i) */ - 0x22, /* ; 8 ExtYPbPrDelay(525p) */ - 0x22, /* ; 9 StYPbPrDealy(525p) */ - 0x22, /* ; A ExtYPbPrDelay(750p) */ - 0x22 /* B StYPbPrDealy(750p) */ -}; - -static unsigned char XGI301TVDelayList2[] = { - 0x22, /* ; 0 ExtNTSCDelay */ - 0x22, /* ; 1 StNTSCDelay */ - 0x22, /* ; 2 ExtPALDelay */ - 0x22, /* ; 3 StPALDelay */ - 0x22, /* ; 4 ExtHiTVDelay */ - 0x22, /* ; 5 StHiTVDelay */ - 0x22, /* ; 6 ExtYPbPrDelay(525i) */ - 0x22, /* ; 7 StYPbPrDealy(525i) */ - 0x22, /* ; 8 ExtYPbPrDelay(525p) */ - 0x22, /* ; 9 StYPbPrDealy(525p) */ - 0x22, /* ; A ExtYPbPrDelay(750p) */ - 0x22 /* ; B StYPbPrDealy(750p) */ -}; - +#define XGI301TVDelay 0x22 +#define XGI301LCDDelay 0x12 static unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */ 0x04, /* ; 0 Adaptive */ -- GitLab From 51f984bc068c8704221a8eddd96b580eafcd2912 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:51 +0200 Subject: [PATCH 1535/6849] staging/xgifb: Use SiS structs This patch replaces some of the XGI internal structs by their counterparts in the SiS driver. XGI330_LVDSDataStruct -> SiS_LVDSData XGI330_LCDDataStruct -> SiS_LCDData XGI330_CHTVDataStruct -> SiS_LVDSData Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 4 +- drivers/staging/xgifb/vb_struct.h | 28 --------- drivers/staging/xgifb/vb_table.h | 96 +++++++++++++++--------------- 3 files changed, 50 insertions(+), 78 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c6c6843ef4de..183afe4bc24c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1980,12 +1980,12 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short tempbx; - struct XGI330_LVDSDataStruct *LCDPtr = NULL; + struct SiS_LVDSData *LCDPtr = NULL; tempbx = 2; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, + LCDPtr = (struct SiS_LVDSData *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); pVBInfo->VGAHT = LCDPtr->VGAHT; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index b95497132b7b..b54488b621e6 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -51,13 +51,6 @@ struct XGI_LCDDataTablStruct { unsigned short DATAPTR; }; -struct XGI330_LVDSDataStruct { - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short LCDHT; - unsigned short LCDVT; -}; - struct XGI330_LCDDataDesStruct2 { unsigned short LCDHDES; unsigned short LCDHRS; @@ -67,15 +60,6 @@ struct XGI330_LCDDataDesStruct2 { unsigned short LCDVSync; }; -struct XGI330_LCDDataStruct { - unsigned short RVBHCMAX; - unsigned short RVBHCFACT; - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short LCDHT; - unsigned short LCDVT; -}; - struct XGI330_TVDataStruct { unsigned short RVBHCMAX; @@ -103,13 +87,6 @@ struct XGI330_TVDataTablStruct { }; -struct XGI330_CHTVDataStruct { - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short LCDHT; - unsigned short LCDVT; -}; - struct XGI_TimingHStruct { unsigned char data[8]; }; @@ -173,11 +150,6 @@ struct XGI_CRT1TableStruct { }; -struct XGI330_VCLKDataStruct { - unsigned char SR2B, SR2C; - unsigned short CLOCK; -}; - struct XGI301C_Tap4TimingStruct { unsigned short DE; unsigned char Reg[64]; /* C0-FF */ diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 50ef885adf62..16bb831a711f 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -420,7 +420,7 @@ static unsigned char XGI_CH7017LV1400x1050[] = { 0xAD, 0xDB, 0xF6, 0xAC, 0xE0, 0x02}; /*add for new UNIVGABIOS*/ -static struct XGI330_LCDDataStruct XGI_StLCD1024x768Data[] = { +static struct SiS_LCDData XGI_StLCD1024x768Data[] = { {62, 25, 800, 546, 1344, 806}, {32, 15, 930, 546, 1344, 806}, {62, 25, 800, 546, 1344, 806}, /*chiawenfordot9->dot8*/ @@ -430,7 +430,7 @@ static struct XGI330_LCDDataStruct XGI_StLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} }; -static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[] = { +static struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { /* { 12, 5, 896, 512,1344, 806}, // alan 09/12/2003 */ {42, 25, 1536, 419, 1344, 806}, /* { 12, 5, 896, 510,1344, 806}, // alan 09/12/2003 */ @@ -450,7 +450,7 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} }; -static struct XGI330_LCDDataStruct XGI_CetLCD1024x768Data[] = { +static struct SiS_LCDData XGI_CetLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */ @@ -461,7 +461,7 @@ static struct XGI330_LCDDataStruct XGI_CetLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} /* 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataStruct XGI_StLCD1280x1024Data[] = { +static struct SiS_LCDData XGI_StLCD1280x1024Data[] = { {22, 5, 800, 510, 1650, 1088}, {22, 5, 800, 510, 1650, 1088}, {176, 45, 900, 510, 1650, 1088}, @@ -472,7 +472,7 @@ static struct XGI330_LCDDataStruct XGI_StLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} }; -static struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[] = { +static struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { {211, 60, 1024, 501, 1688, 1066}, {211, 60, 1024, 508, 1688, 1066}, {211, 60, 1024, 501, 1688, 1066}, @@ -483,7 +483,7 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} }; -static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[] = { +static struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ @@ -496,7 +496,7 @@ static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataStruct xgifb_lcd_1400x1050[] = { +static struct SiS_LCDData xgifb_lcd_1400x1050[] = { {211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400, 640x200,640x400) */ {211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */ @@ -510,7 +510,7 @@ static struct XGI330_LCDDataStruct xgifb_lcd_1400x1050[] = { {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataStruct XGI_ExtLCD1600x1200Data[] = { +static struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { {4, 1, 1620, 420, 2160, 1250}, /* { 3,1,2160,425,2160,1250 }, // 00 (320x200,320x400, // 640x200,640x400) @@ -528,7 +528,7 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1600x1200Data[] = { {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200x60Hz) ;302lv */ }; -static struct XGI330_LCDDataStruct XGI_StLCD1600x1200Data[] = { +static struct SiS_LCDData XGI_StLCD1600x1200Data[] = { {27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400, 640x200,640x400) */ {27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */ @@ -542,7 +542,7 @@ static struct XGI330_LCDDataStruct XGI_StLCD1600x1200Data[] = { {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200) */ }; -static struct XGI330_LCDDataStruct XGI_CetLCD1400x1050Data[] = { +static struct SiS_LCDData XGI_CetLCD1400x1050Data[] = { {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ @@ -555,7 +555,7 @@ static struct XGI330_LCDDataStruct XGI_CetLCD1400x1050Data[] = { {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataStruct XGI_NoScalingData[] = { +static struct SiS_LCDData XGI_NoScalingData[] = { {1, 1, 800, 449, 800, 449}, {1, 1, 800, 449, 800, 449}, {1, 1, 900, 449, 900, 449}, @@ -566,7 +566,7 @@ static struct XGI330_LCDDataStruct XGI_NoScalingData[] = { {1, 1, 1688, 1066, 1688, 1066} }; -static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[] = { +static struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */ @@ -577,7 +577,7 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ }; -static struct XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[] = { +static struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ @@ -588,7 +588,7 @@ static struct XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ }; -static struct XGI330_LCDDataStruct xgifb_lcd_1280x1024x75[] = { +static struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { {211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */ @@ -600,7 +600,7 @@ static struct XGI330_LCDDataStruct xgifb_lcd_1280x1024x75[] = { {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */ }; -static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024x75Data[] = { +static struct SiS_LCDData XGI_CetLCD1280x1024x75Data[] = { {1, 1, 1688, 1066, 1688, 1066}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1688, 1066, 1688, 1066}, /* ; 01 (320x350,640x350) */ @@ -612,7 +612,7 @@ static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024x75Data[] = { {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */ }; -static struct XGI330_LCDDataStruct XGI_NoScalingDatax75[] = { +static struct SiS_LCDData XGI_NoScalingDatax75[] = { {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400, 640x200, 640x400) */ {1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */ @@ -1222,7 +1222,7 @@ static unsigned char XGI330_Ren750pGroup3[] = { 0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01 }; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = { { 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */ { 960, 388, 1344, 806}, /* 01 (320x350,640x350) */ {1040, 438, 1344, 806}, /* 02 (360x400,720x400) */ @@ -1233,7 +1233,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[] = { }; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = { {1344, 806, 1344, 806}, {1344, 806, 1344, 806}, {1344, 806, 1344, 806}, @@ -1245,7 +1245,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2[] = { {800, 525, 1280, 813} }; -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { {1048, 442, 1688, 1066}, {1048, 392, 1688, 1066}, {1048, 442, 1688, 1066}, @@ -1256,7 +1256,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1[] = { {1688, 1066, 1688, 1066} }; -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Data_2[] = { {1344, 806, 1344, 806}, {1344, 806, 1344, 806}, {1344, 806, 1344, 806}, @@ -1268,7 +1268,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2[] = { {800, 525, 1280, 813} }; -static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[] = { +static struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { {928, 416, 1688, 1066}, {928, 366, 1688, 1066}, {928, 416, 1688, 1066}, @@ -1280,7 +1280,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[] = { {1688, 1066, 1688, 1066} }; -static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_2[] = { +static struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = { {1688, 1066, 1688, 1066}, {1688, 1066, 1688, 1066}, {1688, 1066, 1688, 1066}, @@ -1293,7 +1293,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_2[] = { }; /* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */ -static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] = { +static struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = { {1088, 520, 2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */ {1088, 470, 2048, 1320}, /* 01 (320x350,640x350) */ {1088, 520, 2048, 1320}, /* 02 (360x400,720x400) */ @@ -1306,7 +1306,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] = { {2048, 1320, 2048, 1320} /* 09 (1600x1200) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] = { +static struct SiS_LVDSData XGI_LVDSNoScalingData[] = { { 800, 449, 800, 449}, /* 00 (320x200,320x400,640x200,640x400) */ { 800, 449, 800, 449}, /* 01 (320x350,640x350) */ { 800, 449, 800, 449}, /* 02 (360x400,720x400) */ @@ -1320,7 +1320,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] = { {1688, 806, 1688, 806} /* 0A (1280x768x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = { { 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */ { 960, 388, 1312, 800}, /* 01 (320x350,640x350) */ {1040, 438, 1312, 800}, /* 02 (360x400,720x400) */ @@ -1331,7 +1331,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] = { }; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = { {1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ {1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ @@ -1341,7 +1341,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] = { {1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = { {1048, 442, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ {1048, 392, 1688, 1066 }, /* ; 01 (320x350,640x350) */ {1128, 442, 1688, 1066 }, /* ; 02 (360x400,720x400) */ @@ -1352,7 +1352,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] = { {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = { {1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ {1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */ {1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */ @@ -1363,7 +1363,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] = { {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] = { +static struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { { 800, 449, 800, 449}, /* ; 00 (320x200,320x400,640x200,640x400) */ { 800, 449, 800, 449}, /* ; 01 (320x350,640x350) */ { 900, 449, 900, 449}, /* ; 02 (360x400,720x400) */ @@ -1378,7 +1378,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] = { {1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = { {0, 1048, 0, 771}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1048, 0, 771}, /* 01 (320x350,640x350) */ {0, 1048, 0, 771}, /* 02 (360x400,720x400) */ @@ -1388,7 +1388,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] = { {0, 1048, 805, 770} /* 06 (1024x768x60Hz) */ } ; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = { {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ @@ -1398,7 +1398,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] = { { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = { {320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ {320, 24, 597, 562}, /* 01 (320x350,640x350) */ {320, 24, 622, 587}, /* 02 (360x400,720x400) */ @@ -1406,7 +1406,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] = { {320, 24, 722, 687} /* 04 (640x480x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = { {0, 1328, 0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1328, 0, 1025}, /* 01 (320x350,640x350) */ {0, 1328, 0, 1025}, /* 02 (360x400,720x400) */ @@ -1418,7 +1418,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] = { }; /* The Display setting for DE Mode Panel */ -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* 02 (360x400,720x400) */ @@ -1429,7 +1429,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] = { {0000, 1328, 0, 1025} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] = { +static struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = { {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ @@ -1441,7 +1441,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] = { {0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] = { +static struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = { {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ @@ -1453,7 +1453,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] = { { 0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] = { +static struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { {0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1664, 0, 1201}, /* 01 (320x350,640x350) */ {0, 1664, 0, 1201}, /* 02 (360x400,720x400) */ @@ -1483,7 +1483,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { }; /* ; 1024x768 Full-screen */ -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = { {0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ {0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */ {0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */ @@ -1494,7 +1494,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] = { }; /* ; 1024x768 center-screen (Enh. Mode) */ -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = { {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ @@ -1505,7 +1505,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = { }; /* ; 1024x768 center-screen (St.Mode) */ -static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = { +static struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = { {320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {320, 24, 597, 562}, /* ; 01 (320x350,640x350) */ {320, 24, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -1513,7 +1513,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = { {320, 24, 722, 687} /* ; 04 (640x480x60Hz) */ }; -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = { {0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */ {0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -1526,7 +1526,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] = { /* The Display setting for DE Mode Panel */ /* [ycchen] 02/18/03 Set DE as default */ -static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] = { +static struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { {1368, 976, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 976, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 976, 752, 711}, /* ; 02 (360x400,720x400) */ @@ -1554,7 +1554,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { {0, 1328, 0, 771, 112, 6} /* ; 0A (1280x768x75Hz) */ }; -static struct XGI330_CHTVDataStruct XGI_CHTVUNTSCData[] = { +static struct SiS_LVDSData XGI_CHTVUNTSCData[] = { { 840, 600, 840, 600}, { 840, 600, 840, 600}, { 840, 600, 840, 600}, @@ -1563,7 +1563,7 @@ static struct XGI330_CHTVDataStruct XGI_CHTVUNTSCData[] = { {1064, 750, 1064, 750} }; -static struct XGI330_CHTVDataStruct XGI_CHTVONTSCData[] = { +static struct SiS_LVDSData XGI_CHTVONTSCData[] = { { 840, 525, 840, 525}, { 840, 525, 840, 525}, { 840, 525, 840, 525}, @@ -1572,7 +1572,7 @@ static struct XGI330_CHTVDataStruct XGI_CHTVONTSCData[] = { {1040, 700, 1040, 700} }; -static struct XGI330_CHTVDataStruct XGI_CHTVUPALData[] = { +static struct SiS_LVDSData XGI_CHTVUPALData[] = { {1008, 625, 1008, 625}, {1008, 625, 1008, 625}, {1008, 625, 1008, 625}, @@ -1581,7 +1581,7 @@ static struct XGI330_CHTVDataStruct XGI_CHTVUPALData[] = { { 936, 836, 936, 836} }; -static struct XGI330_CHTVDataStruct XGI_CHTVOPALData[] = { +static struct SiS_LVDSData XGI_CHTVOPALData[] = { {1008, 625, 1008, 625}, {1008, 625, 1008, 625}, {1008, 625, 1008, 625}, @@ -2297,7 +2297,7 @@ static unsigned char XG27_SR41 = 0x00 ; static unsigned char Z11m_CR97 = 0x80 ; -static struct XGI330_VCLKDataStruct XGI_VCLKData[] = { +static struct SiS_VCLKData XGI_VCLKData[] = { /* SR2B,SR2C,SR2D */ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ @@ -2390,7 +2390,7 @@ static struct XGI330_VCLKDataStruct XGI_VCLKData[] = { {0xFF, 0x00, 0} /* End mark */ }; -static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] = { +static struct SiS_VCLKData XGI_VBVCLKData[] = { {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ -- GitLab From 6d12dae47e8c93da24d54a402a48dab0958083ca Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 14 Jun 2012 00:21:52 +0200 Subject: [PATCH 1536/6849] staging/xgifb: Cleanup vb_device_info struct This patch cleans up the vb_device_info struct and the related functions. The cleanup decreases the size of the compiled module by about 10kB. == Remove fields in vb_device_info that are never read: == pOutputSelect pRGBSenseData pRGBSenseData2 pVideoSenseData pVideoSenseData2 pYCSenseData pYCSenseData2 CR49 pXGINew_I2CDefinition pCR2E pCR2F pCR46 pCR47 pCRD0 pCRDE pSR40 pSR41 pCR47 === Remove the corresponding 'constants' === XGI330_RGBSenseData XGI330_RGBSenseData2 XGI330_VideoSenseData XGI330_VideoSenseData2 XGI330_YCSenseData XGI330_YCSenseData2 XGI330_CR49 XG40_I2CDefinition XG21_CR2E XG21_CR2F XG21_CR46 XG21_CR47 XG27_CRD0 XG27_CRDE XGI330_OutputSelect == Remove 'constant fields' and replace constant value with #define == pSR07 = XGI330_SR07 -> 0x18 pSR1F = XGI330_SR1F -> 0 pSR23 = XGI330_SR23 -> 0xf6 pSR24 = XGI330_SR24 -> 0x0d pSR33 = XGI330_SR33 ->0 pCRT2Data_1_2 = XGI330_CRT2Data_1_2 -> 0 pCRT2Data_4_D = XGI330_CRT2Data_4_D -> 0 pCRT2Data_4_E = XGI330_CRT2Data_4_E -> 0 pCRT2Data_4_10 = XGI330_CRT2Data_4_10 -> 0x80 pSR36 = XG27_SR36 -> 0x30 pCR8F = &XG27_CR8F -> 0x0C pSR40 = XG27_SR40 -> 0x04 pSR41 = XG27_SR41 ->0x00 pSR31 = XGI330_SR31 -> 0xc0 pSR32 = XGI330_SR32 -> 0xc0 SR25 = XGI330_sr25 -> 0 (we only use XGI330_sr25[0]) == Constant fields with 'dead' code: == pSoftSetting is set to XGI330_SoftSetting = 0x30 -> if (*pVBInfo->pSoftSetting & SoftDRAMType) is never true since SoftDRAMType = 0x80 -> if (*pVBInfo->pSoftSetting & ModeSoftSetting) is never true since ModeSoftSetting = 0x04 --> remove the code, remove pSoftSetting, remove XGI330_SoftSetting pDVOSetting is set to XG21_DVOSetting = 0 -> if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) is never true --> remove the code, remove pDVOSetting, remove XG21_DVOSetting pXGINew_DRAMTypeDefinition is set to &XG40_DRAMTypeDefinition 0xFF -> if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) is always true --> remove the if and remove pXGINew_DRAMTypeDefinition remove XG40_DRAMTypeDefinition == Replace pointer to unsigned char with unsigned char variable and assign value of referenced pointer: == pSR21 -> SR21, remove XGI330_SR21 pSR22 -> SR22, remove XGI330_SR22 pXGINew_CR97 -> XGINew_CR97, remove XG20_CR97, XG27_CR97 and Z11m_CR97 Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 19 ++++++ drivers/staging/xgifb/vb_init.c | 96 ++++++++++++------------------ drivers/staging/xgifb/vb_setmode.c | 59 ++---------------- drivers/staging/xgifb/vb_struct.h | 43 ++----------- drivers/staging/xgifb/vb_table.h | 49 --------------- 5 files changed, 67 insertions(+), 199 deletions(-) diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index c7317931f671..5b987a68ee9f 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -264,4 +264,23 @@ #define RES1280x960x85 0x46 #define RES1280x960x120 0x47 + +#define XG27_CR8F 0x0C +#define XG27_SR36 0x30 +#define XG27_SR40 0x04 +#define XG27_SR41 0x00 +#define XG40_CRCF 0x13 +#define XGI330_CRT2Data_1_2 0 +#define XGI330_CRT2Data_4_D 0 +#define XGI330_CRT2Data_4_E 0 +#define XGI330_CRT2Data_4_10 0x80 +#define XGI330_SR07 0x18 +#define XGI330_SR1F 0 +#define XGI330_SR23 0xf6 +#define XGI330_SR24 0x0d +#define XGI330_SR25 0 +#define XGI330_SR31 0xc0 +#define XGI330_SR32 0x11 +#define XGI330_SR33 0 + #endif diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 944653dcf1ea..a3d54b7f23c6 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -5,7 +5,6 @@ #include "vb_def.h" #include "vb_util.h" #include "vb_setmode.h" - static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = { { 16, 0x45}, { 8, 0x35}, @@ -35,21 +34,12 @@ XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, unsigned char data, temp; if (HwDeviceExtension->jChipType < XG20) { - if (*pVBInfo->pSoftSetting & SoftDRAMType) { - data = *pVBInfo->pSoftSetting & 0x07; - return data; - } else { - data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02; - if (data == 0) - data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) & - 0x02) >> 1; - return data; - } + data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02; + if (data == 0) + data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) & + 0x02) >> 1; + return data; } else if (HwDeviceExtension->jChipType == XG27) { - if (*pVBInfo->pSoftSetting & SoftDRAMType) { - data = *pVBInfo->pSoftSetting & 0x07; - return data; - } temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) @@ -92,13 +82,11 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, xgifb_reg_set(P3c4, 0x16, 0x00); xgifb_reg_set(P3c4, 0x16, 0x80); - if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */ - mdelay(3); - xgifb_reg_set(P3c4, 0x18, 0x00); - xgifb_reg_set(P3c4, 0x19, 0x20); - xgifb_reg_set(P3c4, 0x16, 0x00); - xgifb_reg_set(P3c4, 0x16, 0x80); - } + mdelay(3); + xgifb_reg_set(P3c4, 0x18, 0x00); + xgifb_reg_set(P3c4, 0x19, 0x20); + xgifb_reg_set(P3c4, 0x16, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x80); udelay(60); xgifb_reg_set(P3c4, @@ -172,7 +160,7 @@ static void XGINew_DDRII_Bootup_XG27( /* Set Double Frequency */ /* xgifb_reg_set(P3d4, 0x97, 0x11); *//* CR97 */ - xgifb_reg_set(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */ + xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */ udelay(200); @@ -532,7 +520,7 @@ static void XGINew_SetDRAMDefaultRegister340( pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */ if (HwDeviceExtension->jChipType == XG27) - xgifb_reg_set(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */ + xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */ for (j = 0; j <= 6; j++) /* CR90 - CR96 */ xgifb_reg_set(P3d4, (0x90 + j), @@ -555,7 +543,7 @@ static void XGINew_SetDRAMDefaultRegister340( xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */ xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */ - xgifb_reg_set(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */ + xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */ if (pVBInfo->ram_type) { /* xgifb_reg_set(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */ xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */ @@ -1075,13 +1063,9 @@ static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c); if (!(CR3CData & DisplayDeviceFromCMOS)) { tempcx = 0x1FF0; - if (*pVBInfo->pSoftSetting & ModeSoftSetting) - tempbx = 0x1FF0; } } else { tempcx = 0x1FF0; - if (*pVBInfo->pSoftSetting & ModeSoftSetting) - tempbx = 0x1FF0; } tempbx &= tempcx; @@ -1425,7 +1409,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev) printk("10"); if (HwDeviceExtension->jChipType >= XG20) - xgifb_reg_set(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97); + xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97); /* 3.SetMemoryClock @@ -1435,20 +1419,20 @@ unsigned char XGIInitNew(struct pci_dev *pdev) printk("11"); /* 4.SetDefExt1Regs begin */ - xgifb_reg_set(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07); + xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07); if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_set(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40); - xgifb_reg_set(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41); + xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40); + xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41); } xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F); - xgifb_reg_set(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F); + xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F); /* xgifb_reg_set(pVBInfo->P3c4, 0x20, 0x20); */ /* alan, 2001/6/26 Frame buffer can read/write SR20 */ xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0); /* Hsuan, 2006/01/01 H/W request for slow corner chip */ xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70); if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */ - xgifb_reg_set(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36); + xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36); /* SR11 = 0x0F; */ /* xgifb_reg_set(pVBInfo->P3c4, 0x11, SR11); */ @@ -1534,9 +1518,9 @@ unsigned char XGIInitNew(struct pci_dev *pdev) } /* != XG20 */ /* Set PCI */ - xgifb_reg_set(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23); - xgifb_reg_set(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24); - xgifb_reg_set(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]); + xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23); + xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24); + xgifb_reg_set(pVBInfo->P3c4, 0x25, XGI330_SR25); printk("15"); if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ @@ -1550,8 +1534,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev) temp = (unsigned char) ((temp1 >> 4) & 0x0F); xgifb_reg_set(pVBInfo->Part1Port, - 0x02, - (*pVBInfo->pCRT2Data_1_2)); + 0x02, XGI330_CRT2Data_1_2); printk("16"); @@ -1565,15 +1548,15 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* Not DDR */ xgifb_reg_set(pVBInfo->P3c4, 0x31, - (*pVBInfo->pSR31 & 0x3F) | 0x40); + (XGI330_SR31 & 0x3F) | 0x40); xgifb_reg_set(pVBInfo->P3c4, 0x32, - (*pVBInfo->pSR32 & 0xFC) | 0x01); + (XGI330_SR32 & 0xFC) | 0x01); } else { - xgifb_reg_set(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31); - xgifb_reg_set(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32); + xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31); + xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32); } - xgifb_reg_set(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33); + xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33); printk("17"); /* @@ -1584,14 +1567,11 @@ unsigned char XGIInitNew(struct pci_dev *pdev) if (pVBInfo->IF_DEF_LVDS == 0) { xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C); xgifb_reg_set(pVBInfo->Part4Port, - 0x0D, - *pVBInfo->pCRT2Data_4_D); + 0x0D, XGI330_CRT2Data_4_D); xgifb_reg_set(pVBInfo->Part4Port, - 0x0E, - *pVBInfo->pCRT2Data_4_E); + 0x0E, XGI330_CRT2Data_4_E); xgifb_reg_set(pVBInfo->Part4Port, - 0x10, - *pVBInfo->pCRT2Data_4_10); + 0x10, XGI330_CRT2Data_4_10); xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F); } @@ -1651,12 +1631,12 @@ unsigned char XGIInitNew(struct pci_dev *pdev) AGP = 0; if (AGP == 0) - *pVBInfo->pSR21 &= 0xEF; + pVBInfo->SR21 &= 0xEF; - xgifb_reg_set(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); + xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21); if (AGP == 1) - *pVBInfo->pSR22 &= 0x20; - xgifb_reg_set(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); + pVBInfo->SR22 &= 0x20; + xgifb_reg_set(pVBInfo->P3c4, 0x22, pVBInfo->SR22); */ /* base = 0x80000000; */ /* OutPortLong(0xcf8, base); */ @@ -1664,12 +1644,12 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* if (Temp == 0x1039) { */ xgifb_reg_set(pVBInfo->P3c4, 0x22, - (unsigned char) ((*pVBInfo->pSR22) & 0xFE)); + (unsigned char) ((pVBInfo->SR22) & 0xFE)); /* } else { */ - /* xgifb_reg_set(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */ + /* xgifb_reg_set(pVBInfo->P3c4, 0x22, pVBInfo->SR22); */ /* } */ - xgifb_reg_set(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); + xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21); printk("23"); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 183afe4bc24c..b1713d389794 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -38,9 +38,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->ModeResInfo = (struct SiS_ModeResInfo_S *) XGI330_ModeResInfo; - pVBInfo->pOutputSelect = &XGI330_OutputSelect; - pVBInfo->pSoftSetting = &XGI330_SoftSetting; - pVBInfo->pSR07 = &XGI330_SR07; pVBInfo->LCDResInfo = 0; pVBInfo->LCDTypeInfo = 0; pVBInfo->LCDInfo = 0; @@ -49,36 +46,15 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR15 = XGI340_SR13; pVBInfo->CR40 = XGI340_cr41; - pVBInfo->SR25 = XGI330_sr25; - pVBInfo->pSR31 = &XGI330_sr31; - pVBInfo->pSR32 = &XGI330_sr32; pVBInfo->CR6B = XGI340_CR6B; pVBInfo->CR6E = XGI340_CR6E; pVBInfo->CR6F = XGI340_CR6F; pVBInfo->CR89 = XGI340_CR89; pVBInfo->AGPReg = XGI340_AGPReg; pVBInfo->SR16 = XGI340_SR16; - pVBInfo->pCRCF = &XG40_CRCF; - pVBInfo->pXGINew_DRAMTypeDefinition = &XG40_DRAMTypeDefinition; - - pVBInfo->CR49 = XGI330_CR49; - pVBInfo->pSR1F = &XGI330_SR1F; - pVBInfo->pSR21 = &XGI330_SR21; - pVBInfo->pSR22 = &XGI330_SR22; - pVBInfo->pSR23 = &XGI330_SR23; - pVBInfo->pSR24 = &XGI330_SR24; - pVBInfo->pSR33 = &XGI330_SR33; - - pVBInfo->pCRT2Data_1_2 = &XGI330_CRT2Data_1_2; - pVBInfo->pCRT2Data_4_D = &XGI330_CRT2Data_4_D; - pVBInfo->pCRT2Data_4_E = &XGI330_CRT2Data_4_E; - pVBInfo->pCRT2Data_4_10 = &XGI330_CRT2Data_4_10; - pVBInfo->pRGBSenseData = &XGI330_RGBSenseData; - pVBInfo->pVideoSenseData = &XGI330_VideoSenseData; - pVBInfo->pYCSenseData = &XGI330_YCSenseData; - pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2; - pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2; - pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2; + + pVBInfo->SR21 = 0xa3; + pVBInfo->SR22 = 0xfb; pVBInfo->NTSCTiming = XGI330_NTSCTiming; pVBInfo->PALTiming = XGI330_PALTiming; @@ -105,38 +81,22 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) else pVBInfo->LCDCapList = XGI_LCDCapList; - pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition; - if (ChipType >= XG20) - pVBInfo->pXGINew_CR97 = &XG20_CR97; + pVBInfo->XGINew_CR97 = 0x10; if (ChipType == XG27) { unsigned char temp; pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI27New_MCLKData; pVBInfo->CR40 = XGI27_cr41; - pVBInfo->pXGINew_CR97 = &XG27_CR97; - pVBInfo->pSR36 = &XG27_SR36; - pVBInfo->pCR8F = &XG27_CR8F; - pVBInfo->pCRD0 = XG27_CRD0; - pVBInfo->pCRDE = XG27_CRDE; - pVBInfo->pSR40 = &XG27_SR40; - pVBInfo->pSR41 = &XG27_SR41; + pVBInfo->XGINew_CR97 = 0xc1; pVBInfo->SR15 = XG27_SR13; /*Z11m DDR*/ temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - pVBInfo->pXGINew_CR97 = &Z11m_CR97; - } - - if (ChipType >= XG20) { - pVBInfo->pDVOSetting = &XG21_DVOSetting; - pVBInfo->pCR2E = &XG21_CR2E; - pVBInfo->pCR2F = &XG21_CR2F; - pVBInfo->pCR46 = &XG21_CR46; - pVBInfo->pCR47 = &XG21_CR47; + pVBInfo->XGINew_CR97 = 0x80; } } @@ -783,13 +743,6 @@ static void xgifb_set_lcd(int chip_id, } } - if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { - xgifb_reg_set(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); - xgifb_reg_set(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); - xgifb_reg_set(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); - xgifb_reg_set(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); - } - if (chip_id == XG27) { XGI_SetXG27FPBits(pVBInfo); } else { diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index b54488b621e6..aea760ad4ae2 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -191,45 +191,11 @@ struct vb_device_info { unsigned char (*SR15)[8]; unsigned char (*CR40)[8]; - unsigned char *pSoftSetting; - unsigned char *pOutputSelect; - - unsigned short *pRGBSenseData; - unsigned short *pRGBSenseData2; /*301b*/ - unsigned short *pVideoSenseData; - unsigned short *pVideoSenseData2; - unsigned short *pYCSenseData; - unsigned short *pYCSenseData2; - - unsigned char *pSR07; - unsigned char *CR49; - unsigned char *pSR1F; unsigned char *AGPReg; unsigned char *SR16; - unsigned char *pSR21; - unsigned char *pSR22; - unsigned char *pSR23; - unsigned char *pSR24; - unsigned char *SR25; - unsigned char *pSR31; - unsigned char *pSR32; - unsigned char *pSR33; - unsigned char *pSR36; /* alan 12/07/2006 */ - unsigned char *pCRCF; - unsigned char *pCRD0; /* alan 12/07/2006 */ - unsigned char *pCRDE; /* alan 12/07/2006 */ - unsigned char *pCR8F; /* alan 12/07/2006 */ - unsigned char *pSR40; /* alan 12/07/2006 */ - unsigned char *pSR41; /* alan 12/07/2006 */ - unsigned char *pDVOSetting; - unsigned char *pCR2E; - unsigned char *pCR2F; - unsigned char *pCR46; - unsigned char *pCR47; - unsigned char *pCRT2Data_1_2; - unsigned char *pCRT2Data_4_D; - unsigned char *pCRT2Data_4_E; - unsigned char *pCRT2Data_4_10; + unsigned char SR21; + unsigned char SR22; + unsigned char SR25; struct SiS_MCLKData *MCLKData; struct XGI_ECLKDataStruct *ECLKData; @@ -249,8 +215,7 @@ struct vb_device_info { unsigned char *Ren750pGroup3; unsigned char *ScreenOffset; unsigned char *pXGINew_DRAMTypeDefinition; - unsigned char *pXGINew_I2CDefinition ; - unsigned char *pXGINew_CR97 ; + unsigned char XGINew_CR97; struct XGI330_LCDCapStruct *LCDCapList; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 16bb831a711f..75da7c3e1baf 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -130,13 +130,6 @@ static unsigned char XGI340_AGPReg[12] = { static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83}; -static unsigned char XGI330_sr25[2]; -static unsigned char XGI330_sr31 = 0xc0; -static unsigned char XGI330_sr32 = 0x11; -static unsigned char XGI330_SR33; -static unsigned char XG40_CRCF = 0x13; -static unsigned char XG40_DRAMTypeDefinition = 0xFF ; - static struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, @@ -2255,48 +2248,6 @@ static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { {1152, 864, 8, 16} }; -static unsigned char XGI330_OutputSelect = 0x40; -static unsigned char XGI330_SoftSetting = 0x30; -static unsigned char XGI330_SR07 = 0x18; - -static unsigned char XGI330_CR49[] = {0xaa, 0x88}; -static unsigned char XGI330_SR1F; -static unsigned char XGI330_SR21 = 0xa3; -static unsigned char XGI330_SR22 = 0xfb; -static unsigned char XGI330_SR23 = 0xf6; -static unsigned char XGI330_SR24 = 0xd; - -static unsigned char XGI330_CRT2Data_1_2; -static unsigned char XGI330_CRT2Data_4_D; -static unsigned char XGI330_CRT2Data_4_E; -static unsigned char XGI330_CRT2Data_4_10 = 0x80; -static unsigned short XGI330_RGBSenseData = 0xd1; -static unsigned short XGI330_VideoSenseData = 0xb9; -static unsigned short XGI330_YCSenseData = 0xb3; -static unsigned short XGI330_RGBSenseData2 = 0x0190; /*301b*/ -static unsigned short XGI330_VideoSenseData2 = 0x0110; -static unsigned short XGI330_YCSenseData2 = 0x016B; -static unsigned char XG40_I2CDefinition; -static unsigned char XG20_CR97 = 0x10 ; - -static unsigned char XG21_DVOSetting; -static unsigned char XG21_CR2E; -static unsigned char XG21_CR2F; -static unsigned char XG21_CR46; -static unsigned char XG21_CR47; - -static unsigned char XG27_CR97 = 0xC1 ; -static unsigned char XG27_SR36 = 0x30 ; -static unsigned char XG27_CR8F = 0x0C ; -static unsigned char XG27_CRD0[] = { - 0, 0, 0, 0, 0, 0, 0, 0x82, 0x00, 0x66, 0x01, 0x00 -}; -static unsigned char XG27_CRDE[2]; -static unsigned char XG27_SR40 = 0x04 ; -static unsigned char XG27_SR41 = 0x00 ; - -static unsigned char Z11m_CR97 = 0x80 ; - static struct SiS_VCLKData XGI_VCLKData[] = { /* SR2B,SR2C,SR2D */ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ -- GitLab From 01bd3e3fc9f9fa62c6c86a32c9f60b4501b96b3d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:41:15 -0700 Subject: [PATCH 1537/6849] staging: comedi: 8255: replace printk calls Replace the printk calls with dev_info, dev_warn, etc. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 502bde8c22c1..b608a05bcd1b 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -383,8 +383,7 @@ static int dev_8255_attach(struct comedi_device *dev, break; } if (i == 0) { - printk(KERN_WARNING - "comedi%d: 8255: no devices specified\n", dev->minor); + dev_warn(dev->class_dev, "no devices specified\n"); return -EINVAL; } @@ -392,24 +391,21 @@ static int dev_8255_attach(struct comedi_device *dev, if (ret) return ret; - printk(KERN_INFO "comedi%d: 8255:", dev->minor); - for (i = 0; i < dev->n_subdevices; i++) { iobase = it->options[i]; - printk(" 0x%04lx", iobase); if (!request_region(iobase, _8255_SIZE, "8255")) { - printk(" (I/O port conflict)"); + dev_warn(dev->class_dev, + "0x%04lx (I/O port conflict)\n", iobase); dev->subdevices[i].type = COMEDI_SUBD_UNUSED; } else { subdev_8255_init(dev, dev->subdevices + i, NULL, iobase); + dev_info(dev->class_dev, "0x%04lx\n", iobase); } } - printk("\n"); - return 0; } -- GitLab From e40e8375c0eb546b66c5e66f5e10b68ec46f7b95 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:41:27 -0700 Subject: [PATCH 1538/6849] staging: comedi: 8255: use pointer to dev->subdevices Instead of accessing the dev->subdevices directly as an array, use a pointer. This method is more common in the comedi subsystem. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index b608a05bcd1b..23b9accc34d3 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -371,6 +371,7 @@ EXPORT_SYMBOL(subdev_8255_cleanup); static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct comedi_subdevice *s; int ret; unsigned long iobase; int i; @@ -392,16 +393,16 @@ static int dev_8255_attach(struct comedi_device *dev, return ret; for (i = 0; i < dev->n_subdevices; i++) { + s = dev->subdevices + i; iobase = it->options[i]; if (!request_region(iobase, _8255_SIZE, "8255")) { dev_warn(dev->class_dev, "0x%04lx (I/O port conflict)\n", iobase); - dev->subdevices[i].type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } else { - subdev_8255_init(dev, dev->subdevices + i, NULL, - iobase); + subdev_8255_init(dev, s, NULL, iobase); dev_info(dev->class_dev, "0x%04lx\n", iobase); } } -- GitLab From a9044d91990d4ba611f95fc5c84e2531fa54a5f9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:41:36 -0700 Subject: [PATCH 1539/6849] staging: comedi: 8255: rename the private data structure Rename the 8255's private data structure from subdev_8255_struct to subdev_8255_private. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 23b9accc34d3..446dfc5c970a 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -97,15 +97,15 @@ I/O port base address can be found in the output of 'lspci -v'. #define CR_A_MODE(a) ((a)<<5) #define CR_CW 0x80 -struct subdev_8255_struct { +struct subdev_8255_private { unsigned long cb_arg; int (*cb_func) (int, int, int, unsigned long); int have_irq; }; -#define CALLBACK_ARG (((struct subdev_8255_struct *)s->private)->cb_arg) -#define CALLBACK_FUNC (((struct subdev_8255_struct *)s->private)->cb_func) -#define subdevpriv ((struct subdev_8255_struct *)s->private) +#define CALLBACK_ARG (((struct subdev_8255_private *)s->private)->cb_arg) +#define CALLBACK_FUNC (((struct subdev_8255_private *)s->private)->cb_func) +#define subdevpriv ((struct subdev_8255_private *)s->private) void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) @@ -316,7 +316,7 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, s->range_table = &range_digital; s->maxdata = 1; - s->private = kmalloc(sizeof(struct subdev_8255_struct), GFP_KERNEL); + s->private = kmalloc(sizeof(struct subdev_8255_private), GFP_KERNEL); if (!s->private) return -ENOMEM; -- GitLab From 7c61452afcf5cf2f781f8aabc42405af0edc4b06 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:41:45 -0700 Subject: [PATCH 1540/6849] staging: comedi: 8255: remove the s->private access macros The macros CALLBACK_ARG, CALLBACK_FUNC, and subdevpriv all rely on a a local variable having a specific name. Replace the macros with local variables wherever they occur. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 59 +++++++++++++++------------ 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 446dfc5c970a..5e0e8ff89366 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -103,17 +103,14 @@ struct subdev_8255_private { int have_irq; }; -#define CALLBACK_ARG (((struct subdev_8255_private *)s->private)->cb_arg) -#define CALLBACK_FUNC (((struct subdev_8255_private *)s->private)->cb_func) -#define subdevpriv ((struct subdev_8255_private *)s->private) - void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { + struct subdev_8255_private *spriv = s->private; short d; - d = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG); - d |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8); + d = spriv->cb_func(0, _8255_DATA, 0, spriv->cb_arg); + d |= (spriv->cb_func(0, _8255_DATA + 1, 0, spriv->cb_arg) << 8); comedi_buf_put(s->async, d); s->async->events |= COMEDI_CB_EOS; @@ -138,30 +135,33 @@ static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct subdev_8255_private *spriv = s->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); if (data[0] & 0xff) - CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff, - CALLBACK_ARG); + spriv->cb_func(1, _8255_DATA, s->state & 0xff, + spriv->cb_arg); if (data[0] & 0xff00) - CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff, - CALLBACK_ARG); + spriv->cb_func(1, _8255_DATA + 1, + (s->state >> 8) & 0xff, spriv->cb_arg); if (data[0] & 0xff0000) - CALLBACK_FUNC(1, _8255_DATA + 2, - (s->state >> 16) & 0xff, CALLBACK_ARG); + spriv->cb_func(1, _8255_DATA + 2, + (s->state >> 16) & 0xff, spriv->cb_arg); } - data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG); - data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8); - data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16); + data[1] = spriv->cb_func(0, _8255_DATA, 0, spriv->cb_arg); + data[1] |= (spriv->cb_func(0, _8255_DATA + 1, 0, spriv->cb_arg) << 8); + data[1] |= (spriv->cb_func(0, _8255_DATA + 2, 0, spriv->cb_arg) << 16); return 2; } static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) { + struct subdev_8255_private *spriv = s->private; int config; config = CR_CW; @@ -174,7 +174,7 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) config |= CR_C_LO_IO; if (!(s->io_bits & 0xf00000)) config |= CR_C_HI_IO; - CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG); + spriv->cb_func(1, _8255_CR, config, spriv->cb_arg); } static int subdev_8255_insn_config(struct comedi_device *dev, @@ -310,21 +310,24 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, int, int, unsigned long), unsigned long arg) { + struct subdev_8255_private *spriv; + s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 24; s->range_table = &range_digital; s->maxdata = 1; - s->private = kmalloc(sizeof(struct subdev_8255_private), GFP_KERNEL); - if (!s->private) + spriv = kmalloc(sizeof(*spriv), GFP_KERNEL); + if (!spriv) return -ENOMEM; + s->private = spriv; - CALLBACK_ARG = arg; + spriv->cb_arg = arg; if (cb == NULL) - CALLBACK_FUNC = subdev_8255_cb; + spriv->cb_func = subdev_8255_cb; else - CALLBACK_FUNC = cb; + spriv->cb_func = cb; s->insn_bits = subdev_8255_insn; s->insn_config = subdev_8255_insn_config; @@ -340,18 +343,20 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, int, int, unsigned long), unsigned long arg) { + struct subdev_8255_private *spriv; int ret; ret = subdev_8255_init(dev, s, cb, arg); if (ret < 0) return ret; + spriv = s->private; + + spriv->have_irq = 1; s->do_cmdtest = subdev_8255_cmdtest; s->do_cmd = subdev_8255_cmd; s->cancel = subdev_8255_cancel; - subdevpriv->have_irq = 1; - return 0; } EXPORT_SYMBOL(subdev_8255_init_irq); @@ -412,15 +417,15 @@ static int dev_8255_attach(struct comedi_device *dev, static void dev_8255_detach(struct comedi_device *dev) { - int i; - unsigned long iobase; struct comedi_subdevice *s; + struct subdev_8255_private *spriv; + int i; for (i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; if (s->type != COMEDI_SUBD_UNUSED) { - iobase = CALLBACK_ARG; - release_region(iobase, _8255_SIZE); + spriv = s->private; + release_region(spriv->cb_arg, _8255_SIZE); } subdev_8255_cleanup(dev, s); } -- GitLab From 7a583163e87c8dd5b1826199d2a189f0daaf3247 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:41:54 -0700 Subject: [PATCH 1541/6849] staging: comedi: 8255: rename cb_arg and cb_func The 8255's private data variables cb_arg and cb_func are actually the iobase for the 8255 device and the pointer to the io function to access the device. Rename them as such to improve the readability of the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 5e0e8ff89366..7b7768b62484 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -98,8 +98,8 @@ I/O port base address can be found in the output of 'lspci -v'. #define CR_CW 0x80 struct subdev_8255_private { - unsigned long cb_arg; - int (*cb_func) (int, int, int, unsigned long); + unsigned long iobase; + int (*io) (int, int, int, unsigned long); int have_irq; }; @@ -109,8 +109,8 @@ void subdev_8255_interrupt(struct comedi_device *dev, struct subdev_8255_private *spriv = s->private; short d; - d = spriv->cb_func(0, _8255_DATA, 0, spriv->cb_arg); - d |= (spriv->cb_func(0, _8255_DATA + 1, 0, spriv->cb_arg) << 8); + d = spriv->io(0, _8255_DATA, 0, spriv->iobase); + d |= (spriv->io(0, _8255_DATA + 1, 0, spriv->iobase) << 8); comedi_buf_put(s->async, d); s->async->events |= COMEDI_CB_EOS; @@ -142,19 +142,19 @@ static int subdev_8255_insn(struct comedi_device *dev, s->state |= (data[0] & data[1]); if (data[0] & 0xff) - spriv->cb_func(1, _8255_DATA, s->state & 0xff, - spriv->cb_arg); + spriv->io(1, _8255_DATA, s->state & 0xff, + spriv->iobase); if (data[0] & 0xff00) - spriv->cb_func(1, _8255_DATA + 1, - (s->state >> 8) & 0xff, spriv->cb_arg); + spriv->io(1, _8255_DATA + 1, + (s->state >> 8) & 0xff, spriv->iobase); if (data[0] & 0xff0000) - spriv->cb_func(1, _8255_DATA + 2, - (s->state >> 16) & 0xff, spriv->cb_arg); + spriv->io(1, _8255_DATA + 2, + (s->state >> 16) & 0xff, spriv->iobase); } - data[1] = spriv->cb_func(0, _8255_DATA, 0, spriv->cb_arg); - data[1] |= (spriv->cb_func(0, _8255_DATA + 1, 0, spriv->cb_arg) << 8); - data[1] |= (spriv->cb_func(0, _8255_DATA + 2, 0, spriv->cb_arg) << 16); + data[1] = spriv->io(0, _8255_DATA, 0, spriv->iobase); + data[1] |= (spriv->io(0, _8255_DATA + 1, 0, spriv->iobase) << 8); + data[1] |= (spriv->io(0, _8255_DATA + 2, 0, spriv->iobase) << 16); return 2; } @@ -174,7 +174,7 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) config |= CR_C_LO_IO; if (!(s->io_bits & 0xf00000)) config |= CR_C_HI_IO; - spriv->cb_func(1, _8255_CR, config, spriv->cb_arg); + spriv->io(1, _8255_CR, config, spriv->iobase); } static int subdev_8255_insn_config(struct comedi_device *dev, @@ -323,11 +323,11 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, return -ENOMEM; s->private = spriv; - spriv->cb_arg = arg; + spriv->iobase = arg; if (cb == NULL) - spriv->cb_func = subdev_8255_cb; + spriv->io = subdev_8255_cb; else - spriv->cb_func = cb; + spriv->io = cb; s->insn_bits = subdev_8255_insn; s->insn_config = subdev_8255_insn_config; @@ -425,7 +425,7 @@ static void dev_8255_detach(struct comedi_device *dev) s = dev->subdevices + i; if (s->type != COMEDI_SUBD_UNUSED) { spriv = s->private; - release_region(spriv->cb_arg, _8255_SIZE); + release_region(spriv->iobase, _8255_SIZE); } subdev_8255_cleanup(dev, s); } -- GitLab From d29a18dcdbfbe250265abdf9c94d60df86f90316 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:02 -0700 Subject: [PATCH 1542/6849] staging: comedi: 8255: push out the 8255's private data variable rename Push out the rename of the private variables to improve the readability of the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 32 +++++++++++++-------------- drivers/staging/comedi/drivers/8255.h | 8 +++---- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 7b7768b62484..80ef0315662b 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -60,15 +60,15 @@ I/O port base address can be found in the output of 'lspci -v'. set up the subdevice in the attach function of the driver by calling: - subdev_8255_init(device, subdevice, callback_function, arg) + subdev_8255_init(device, subdevice, io_function, iobase) device and subdevice are pointers to the device and subdevice - structures. callback_function will be called to provide the + structures. io_function will be called to provide the low-level input/output to the device, i.e., actual register - access. callback_function will be called with the value of arg + access. io_function will be called with the value of iobase as the last parameter. If the 8255 device is mapped as 4 - consecutive I/O ports, you can use NULL for callback_function - and the I/O port base for arg, and an internal function will + consecutive I/O ports, you can use NULL for io_function + and the I/O port base for iobase, and an internal function will handle the register access. In addition, if the main driver handles interrupts, you can @@ -119,10 +119,8 @@ void subdev_8255_interrupt(struct comedi_device *dev, } EXPORT_SYMBOL(subdev_8255_interrupt); -static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) +static int subdev_8255_io(int dir, int port, int data, unsigned long iobase) { - unsigned long iobase = arg; - if (dir) { outb(data, iobase + port); return 0; @@ -307,8 +305,8 @@ static int subdev_8255_cancel(struct comedi_device *dev, } int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) + int (*io) (int, int, int, unsigned long), + unsigned long iobase) { struct subdev_8255_private *spriv; @@ -323,11 +321,11 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, return -ENOMEM; s->private = spriv; - spriv->iobase = arg; - if (cb == NULL) - spriv->io = subdev_8255_cb; + spriv->iobase = iobase; + if (io == NULL) + spriv->io = subdev_8255_io; else - spriv->io = cb; + spriv->io = io; s->insn_bits = subdev_8255_insn; s->insn_config = subdev_8255_insn_config; @@ -340,13 +338,13 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, EXPORT_SYMBOL(subdev_8255_init); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) + int (*io) (int, int, int, unsigned long), + unsigned long iobase) { struct subdev_8255_private *spriv; int ret; - ret = subdev_8255_init(dev, s, cb, arg); + ret = subdev_8255_init(dev, s, io, iobase); if (ret < 0) return ret; spriv = s->private; diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index b6314c9b7eae..1e589b4b8b73 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -27,11 +27,11 @@ #include "../comedidev.h" int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg); + int (*io) (int, int, int, unsigned long), + unsigned long iobase); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg); + int (*io) (int, int, int, unsigned long), + unsigned long iobase); void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s); void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s); -- GitLab From cc31b1be67bf4b878157e276056b6dbce76fdb45 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:12 -0700 Subject: [PATCH 1543/6849] staging: comedi: 8255: refactor subdev_8255_init Refactor the initialization of the 8255 so that the private data allocation is done before the subdevice is setup. This makes sure that the setup is complete. Also, add a bit of whitespace to improve the readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 31 +++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 80ef0315662b..52b98171a16e 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -310,27 +310,26 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, { struct subdev_8255_private *spriv; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 24; - s->range_table = &range_digital; - s->maxdata = 1; - spriv = kmalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) return -ENOMEM; - s->private = spriv; - spriv->iobase = iobase; - if (io == NULL) - spriv->io = subdev_8255_io; - else - spriv->io = io; - s->insn_bits = subdev_8255_insn; - s->insn_config = subdev_8255_insn_config; + spriv->iobase = iobase; + spriv->io = io ? io : subdev_8255_io; + + s->private = spriv; + + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_bits = subdev_8255_insn; + s->insn_config = subdev_8255_insn_config; + + s->state = 0; + s->io_bits = 0; - s->state = 0; - s->io_bits = 0; do_config(dev, s); return 0; -- GitLab From 34cfcf9acc6b0697e71294007c57eae91b80005c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:21 -0700 Subject: [PATCH 1544/6849] staging: comedi: 8255: remove have_irg and refactor subdev_8255_init_irq The have_irq variable in the 8255 private data is not used by the driver, remove it. This removes the need to access the private data in the subdev_8255_init_irq function. Also, add a bit of whitespace to improve the readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 52b98171a16e..da86a04b70f7 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -100,7 +100,6 @@ I/O port base address can be found in the output of 'lspci -v'. struct subdev_8255_private { unsigned long iobase; int (*io) (int, int, int, unsigned long); - int have_irq; }; void subdev_8255_interrupt(struct comedi_device *dev, @@ -340,19 +339,15 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int (*io) (int, int, int, unsigned long), unsigned long iobase) { - struct subdev_8255_private *spriv; int ret; ret = subdev_8255_init(dev, s, io, iobase); if (ret < 0) return ret; - spriv = s->private; - - spriv->have_irq = 1; - s->do_cmdtest = subdev_8255_cmdtest; - s->do_cmd = subdev_8255_cmd; - s->cancel = subdev_8255_cancel; + s->do_cmdtest = subdev_8255_cmdtest; + s->do_cmd = subdev_8255_cmd; + s->cancel = subdev_8255_cancel; return 0; } -- GitLab From 3e189f08ef81e27aeccd2c2fb55175451f9faa71 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:28 -0700 Subject: [PATCH 1545/6849] staging: comedi: 8255: check for failure of subdev_8255_init The initialization of the 8255 subdevice can fail. Make sure to check for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index da86a04b70f7..4cdd00762e86 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -342,7 +342,7 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int ret; ret = subdev_8255_init(dev, s, io, iobase); - if (ret < 0) + if (ret) return ret; s->do_cmdtest = subdev_8255_cmdtest; @@ -399,7 +399,9 @@ static int dev_8255_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } else { - subdev_8255_init(dev, s, NULL, iobase); + ret = subdev_8255_init(dev, s, NULL, iobase); + if (ret) + return ret; dev_info(dev->class_dev, "0x%04lx\n", iobase); } } -- GitLab From e64fb55b1a519a7d0fda51f40ab668830d6475ac Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:34 -0700 Subject: [PATCH 1546/6849] staging: comedi: 8255: use kzalloc to allocate the private data Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 4cdd00762e86..f6ea49335bb4 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -309,7 +309,7 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, { struct subdev_8255_private *spriv; - spriv = kmalloc(sizeof(*spriv), GFP_KERNEL); + spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) return -ENOMEM; -- GitLab From f218d9f57b472848da34beac3e8097b054dcb2fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:39 -0700 Subject: [PATCH 1547/6849] staging: comedi: 8255: use a local variable for the iobase To improve readability, use a locale variable to hold the 8255's private iobase value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index f6ea49335bb4..1f4b24c9ed85 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -106,10 +106,11 @@ void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; + unsigned long iobase = spriv->iobase; short d; - d = spriv->io(0, _8255_DATA, 0, spriv->iobase); - d |= (spriv->io(0, _8255_DATA + 1, 0, spriv->iobase) << 8); + d = spriv->io(0, _8255_DATA, 0, iobase); + d |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8); comedi_buf_put(s->async, d); s->async->events |= COMEDI_CB_EOS; @@ -133,25 +134,25 @@ static int subdev_8255_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct subdev_8255_private *spriv = s->private; + unsigned long iobase = spriv->iobase; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); if (data[0] & 0xff) - spriv->io(1, _8255_DATA, s->state & 0xff, - spriv->iobase); + spriv->io(1, _8255_DATA, s->state & 0xff, iobase); if (data[0] & 0xff00) spriv->io(1, _8255_DATA + 1, - (s->state >> 8) & 0xff, spriv->iobase); + (s->state >> 8) & 0xff, iobase); if (data[0] & 0xff0000) spriv->io(1, _8255_DATA + 2, - (s->state >> 16) & 0xff, spriv->iobase); + (s->state >> 16) & 0xff, iobase); } - data[1] = spriv->io(0, _8255_DATA, 0, spriv->iobase); - data[1] |= (spriv->io(0, _8255_DATA + 1, 0, spriv->iobase) << 8); - data[1] |= (spriv->io(0, _8255_DATA + 2, 0, spriv->iobase) << 16); + data[1] = spriv->io(0, _8255_DATA, 0, iobase); + data[1] |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8); + data[1] |= (spriv->io(0, _8255_DATA + 2, 0, iobase) << 16); return 2; } @@ -159,6 +160,7 @@ static int subdev_8255_insn(struct comedi_device *dev, static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; + unsigned long iobase = spriv->iobase; int config; config = CR_CW; @@ -171,7 +173,8 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) config |= CR_C_LO_IO; if (!(s->io_bits & 0xf00000)) config |= CR_C_HI_IO; - spriv->io(1, _8255_CR, config, spriv->iobase); + + spriv->io(1, _8255_CR, config, iobase); } static int subdev_8255_insn_config(struct comedi_device *dev, -- GitLab From 459f299e5b1759644a6cde8328919b6e542fb9eb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:45 -0700 Subject: [PATCH 1548/6849] staging: comedi: 8255: refactor subdev_8255_insn function Refactor the subdev_8255_insn function to follow what the user space library is doing. 1) This function requires 'data' to contain 2 parameters. Add a sanity check for this (insn->n != 2). 2) The 'data' parameters are actually a 'mask' of the valid bits and the actual 'bits' to modify. Create local variables of these names to help with maintainability. 3) The value returned in data[1] reflects the actual state of the 8255 io pins after the update of the masked bits. Fetch this data in a local variable and then set data[1]. 4) The user space library only checks for a < 0 return to indicate an error. It appears that the 'return 2' in this function is supposed to indicate the number of data parameters used to perform the command. Return the insn->n value for this, the open coded '2' looks wrong. Signed-off-by: H Hartley Sweeten Cc: Iam Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 44 +++++++++++++++++---------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 1f4b24c9ed85..da374dee9bc0 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -135,26 +135,38 @@ static int subdev_8255_insn(struct comedi_device *dev, { struct subdev_8255_private *spriv = s->private; unsigned long iobase = spriv->iobase; + unsigned int mask; + unsigned int bits; + unsigned int v; + + if (insn->n != 2) + return -EINVAL; - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - if (data[0] & 0xff) - spriv->io(1, _8255_DATA, s->state & 0xff, iobase); - if (data[0] & 0xff00) - spriv->io(1, _8255_DATA + 1, - (s->state >> 8) & 0xff, iobase); - if (data[0] & 0xff0000) - spriv->io(1, _8255_DATA + 2, - (s->state >> 16) & 0xff, iobase); + mask = data[0]; + bits = data[1]; + + if (mask) { + v = s->state; + v &= ~mask; + v |= (bits & mask); + + if (mask & 0xff) + spriv->io(1, _8255_DATA, v & 0xff, iobase); + if (mask & 0xff00) + spriv->io(1, _8255_DATA + 1, (v >> 8) & 0xff, iobase); + if (mask & 0xff0000) + spriv->io(1, _8255_DATA + 2, (v >> 16) & 0xff, iobase); + + s->state = v; } - data[1] = spriv->io(0, _8255_DATA, 0, iobase); - data[1] |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8); - data[1] |= (spriv->io(0, _8255_DATA + 2, 0, iobase) << 16); + v = spriv->io(0, _8255_DATA, 0, iobase); + v |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8); + v |= (spriv->io(0, _8255_DATA + 2, 0, iobase) << 16); + + data[1] = v; - return 2; + return insn->n; } static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) -- GitLab From f9af899b0c6c778083d1040349930a0f9fffb525 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:42:51 -0700 Subject: [PATCH 1549/6849] staging: comedi: 8255: move the subdev_8255_io function The subdev_8255_interrupt function indirectly calls subdev_8255_io. For aesthetic reasons, move the subdev_8255_io function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index da374dee9bc0..abbb6d4d10d1 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -102,6 +102,16 @@ struct subdev_8255_private { int (*io) (int, int, int, unsigned long); }; +static int subdev_8255_io(int dir, int port, int data, unsigned long iobase) +{ + if (dir) { + outb(data, iobase + port); + return 0; + } else { + return inb(iobase + port); + } +} + void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -119,16 +129,6 @@ void subdev_8255_interrupt(struct comedi_device *dev, } EXPORT_SYMBOL(subdev_8255_interrupt); -static int subdev_8255_io(int dir, int port, int data, unsigned long iobase) -{ - if (dir) { - outb(data, iobase + port); - return 0; - } else { - return inb(iobase + port); - } -} - static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) -- GitLab From cf8a6b3d86ec4d6ac8e2925a65335bd0d155c480 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:43:04 -0700 Subject: [PATCH 1550/6849] staging: comedi: 8255: add namespace to 'do_config' function The name 'do_config' is pretty generic, and this function is the only one in this driver without namespace. Add namespace to it just to avoid any issues. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index abbb6d4d10d1..8c97ac1e6970 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -169,7 +169,8 @@ static int subdev_8255_insn(struct comedi_device *dev, return insn->n; } -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) +static void subdev_8255_do_config(struct comedi_device *dev, + struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; unsigned long iobase = spriv->iobase; @@ -221,7 +222,7 @@ static int subdev_8255_insn_config(struct comedi_device *dev, return -EINVAL; } - do_config(dev, s); + subdev_8255_do_config(dev, s); return 1; } @@ -344,7 +345,7 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, s->state = 0; s->io_bits = 0; - do_config(dev, s); + subdev_8255_do_config(dev, s); return 0; } -- GitLab From 03ae8189ee6cab3d4af3e39136105f02d7c35883 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 15:43:11 -0700 Subject: [PATCH 1551/6849] staging: comedi: 8255: add some whitespace to the #define's Add whitespace to the _8255_* defines to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 8c97ac1e6970..e0de149c3c29 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -84,10 +84,10 @@ I/O port base address can be found in the output of 'lspci -v'. #include #include "8255.h" -#define _8255_SIZE 4 +#define _8255_SIZE 4 -#define _8255_DATA 0 -#define _8255_CR 3 +#define _8255_DATA 0 +#define _8255_CR 3 #define CR_C_LO_IO 0x01 #define CR_B_IO 0x02 -- GitLab From b4b700c5a61c6e6db976f60d4eb6ad369e838aa9 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 13 Jun 2012 16:03:42 -0500 Subject: [PATCH 1552/6849] staging: zsmalloc: fix uninit'ed variable warning This patch fixes an uninitialized variable warning in alloc_zspage(). It also fixes the secondary issue of prev_page leaving scope on each loop iteration. The only reason this ever worked was because prev_page was occupying the same space on the stack on each iteration. Signed-off-by: Seth Jennings Reported-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zsmalloc/zsmalloc-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index fb54a9b94c33..4af3dd6641c9 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -400,7 +400,7 @@ static void init_zspage(struct page *first_page, struct size_class *class) static struct page *alloc_zspage(struct size_class *class, gfp_t flags) { int i, error; - struct page *first_page = NULL; + struct page *first_page = NULL, *uninitialized_var(prev_page); /* * Allocate individual pages and link them together as: @@ -415,7 +415,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) */ error = -ENOMEM; for (i = 0; i < class->pages_per_zspage; i++) { - struct page *page, *prev_page; + struct page *page; page = alloc_page(flags); if (!page) -- GitLab From 7489301a1590c2771d27a08d41fa2778791cdf9d Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Wed, 13 Jun 2012 15:37:18 -0400 Subject: [PATCH 1553/6849] staging: usbip: cleanup and fix of vhci_hub_status Changed setting the status bits to a byte-oriented approach. Number of written status bits is now based on VHCI_NPORT, instead of casting status buffer to a long. This fixes a stack corruption bug on 64-bit based architectures, and potential byte order / endianness related issues. In addition updated function comments, and log statements. Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 39 +++++++++----------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index f708cbaee16b..12a9a5fbc797 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -178,44 +178,32 @@ void rh_port_disconnect(int rhport) | USB_PORT_STAT_C_RESET) << 16) /* - * This function is almostly the same as dummy_hcd.c:dummy_hub_status() without - * suspend/resume support. But, it is modified to provide multiple ports. + * Returns 0 if the status hasn't changed, or the number of bytes in buf. + * Ports are 0-indexed from the HCD point of view, + * and 1-indexed from the USB core pointer of view. * * @buf: a bitmap to show which port status has been changed. - * bit 0: reserved or used for another purpose? + * bit 0: reserved * bit 1: the status of port 0 has been changed. * bit 2: the status of port 1 has been changed. * ... - * bit 7: the status of port 6 has been changed. - * bit 8: the status of port 7 has been changed. - * ... - * bit 15: the status of port 14 has been changed. - * - * So, the maximum number of ports is 31 ( port 0 to port 30) ? - * - * The return value is the actual transferred length in byte. If nothing has - * been changed, return 0. In the case that the number of ports is less than or - * equal to 6 (VHCI_NPORTS==7), return 1. - * */ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) { struct vhci_hcd *vhci; unsigned long flags; - int retval = 0; - - /* the enough buffer is allocated according to USB_MAXCHILDREN */ - unsigned long *event_bits = (unsigned long *) buf; + int retval; int rhport; int changed = 0; - *event_bits = 0; + retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8); + memset(buf, 0, retval); vhci = hcd_to_vhci(hcd); spin_lock_irqsave(&vhci->lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) { - usbip_dbg_vhci_rh("hw accessible flag in on?\n"); + usbip_dbg_vhci_rh("hw accessible flag not on?\n"); goto done; } @@ -223,9 +211,9 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { if ((vhci->port_status[rhport] & PORT_C_MASK)) { /* The status of a port has been changed, */ - usbip_dbg_vhci_rh("port %d is changed\n", rhport); + usbip_dbg_vhci_rh("port %d status changed\n", rhport); - *event_bits |= 1 << (rhport + 1); + buf[(rhport + 1) / 8] |= 1 << (rhport + 1) % 8; changed = 1; } } @@ -235,14 +223,9 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) if (hcd->state == HC_STATE_SUSPENDED) usb_hcd_resume_root_hub(hcd); - if (changed) - retval = 1 + (VHCI_NPORTS / 8); - else - retval = 0; - done: spin_unlock_irqrestore(&vhci->lock, flags); - return retval; + return changed ? retval : 0; } /* See hub_configure in hub.c */ -- GitLab From d691af000274ae9658695c2a63a76b30890a8983 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 12 Jun 2012 16:50:55 +0800 Subject: [PATCH 1554/6849] crypto: s390 - clean up DES code a bit more Commit 98971f8439b1bb9a61682fe24a865ddd25167a6b ("crypto: s390 - cleanup DES code") should have also removed crypto_des.h. That file is unused and unneeded since that commit. So let's clean up that file too. Signed-off-by: Paul Bolle Acked-by: Jan Glauber Signed-off-by: Herbert Xu --- arch/s390/crypto/crypto_des.h | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 arch/s390/crypto/crypto_des.h diff --git a/arch/s390/crypto/crypto_des.h b/arch/s390/crypto/crypto_des.h deleted file mode 100644 index 6210457ceebb..000000000000 --- a/arch/s390/crypto/crypto_des.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Cryptographic API. - * - * Function for checking keys for the DES and Tripple DES Encryption - * algorithms. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ -#ifndef __CRYPTO_DES_H__ -#define __CRYPTO_DES_H__ - -extern int crypto_des_check_key(const u8*, unsigned int, u32*); - -#endif /*__CRYPTO_DES_H__*/ -- GitLab From 31b4cd2907322bd56e4090168e4ce8f8dcd17820 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 12 Jun 2012 16:52:04 +0800 Subject: [PATCH 1555/6849] crypto: testmgr - add ecb(arc4) speed tests Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 2af879786e75..58ad4fe5d208 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1342,6 +1342,11 @@ static int do_test(int m) speed_template_32_64); break; + case 208: + test_cipher_speed("ecb(arc4)", ENCRYPT, sec, NULL, 0, + speed_template_8); + break; + case 300: /* fall through */ @@ -1589,6 +1594,11 @@ static int do_test(int m) speed_template_32_48_64); break; + case 505: + test_acipher_speed("ecb(arc4)", ENCRYPT, sec, NULL, 0, + speed_template_8); + break; + case 1000: test_available(); break; -- GitLab From ce6dd368984068c8938e8d3fba8e292ef63cee97 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 9 Jun 2012 18:25:40 +0300 Subject: [PATCH 1556/6849] crypto: arc4 - improve performance by adding ecb(arc4) Currently arc4.c provides simple one-byte blocksize cipher which is wrapped by ecb() module, giving function call overhead on every encrypted byte. This patch adds ecb(arc4) directly into arc4.c for higher performance. tcrypt results (speed ratios: new/old): AMD Phenom II, x86-64 : x2.7 Intel Core 2, x86-64 : x1.9 Intel Atom N260, i386 : x1.4 Cc: Jon Oberheide Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- crypto/arc4.c | 109 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/crypto/arc4.c b/crypto/arc4.c index 0d12a96da1d8..07913fc52c4e 100644 --- a/crypto/arc4.c +++ b/crypto/arc4.c @@ -11,9 +11,11 @@ * (at your option) any later version. * */ + #include #include #include +#include #define ARC4_MIN_KEY_SIZE 1 #define ARC4_MAX_KEY_SIZE 256 @@ -48,51 +50,114 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, return 0; } -static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, + unsigned int len) { - struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); - u8 *const S = ctx->S; - u8 x = ctx->x; - u8 y = ctx->y; - u8 a, b; + u8 x, y, a, b; + u8 ty, ta, tb; + + if (len == 0) + return; + + x = ctx->x; + y = ctx->y; a = S[x]; y = (y + a) & 0xff; b = S[y]; - S[x] = b; - S[y] = a; - x = (x + 1) & 0xff; - *out++ = *in ^ S[(a + b) & 0xff]; + + do { + S[y] = a; + a = (a + b) & 0xff; + S[x] = b; + x = (x + 1) & 0xff; + ta = S[x]; + ty = (y + ta) & 0xff; + tb = S[ty]; + *out++ = *in++ ^ S[a]; + if (--len == 0) + break; + y = ty; + a = ta; + b = tb; + } while (true); ctx->x = x; ctx->y = y; } -static struct crypto_alg arc4_alg = { +static void arc4_crypt_one(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + arc4_crypt(crypto_tfm_ctx(tfm), out, in, 1); +} + +static int ecb_arc4_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + + err = blkcipher_walk_virt(desc, &walk); + + while (walk.nbytes > 0) { + u8 *wsrc = walk.src.virt.addr; + u8 *wdst = walk.dst.virt.addr; + + arc4_crypt(ctx, wdst, wsrc, walk.nbytes); + + err = blkcipher_walk_done(desc, &walk, 0); + } + + return err; +} + +static struct crypto_alg arc4_algs[2] = { { .cra_name = "arc4", .cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_blocksize = ARC4_BLOCK_SIZE, .cra_ctxsize = sizeof(struct arc4_ctx), .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list), - .cra_u = { .cipher = { - .cia_min_keysize = ARC4_MIN_KEY_SIZE, - .cia_max_keysize = ARC4_MAX_KEY_SIZE, - .cia_setkey = arc4_set_key, - .cia_encrypt = arc4_crypt, - .cia_decrypt = arc4_crypt } } -}; + .cra_u = { + .cipher = { + .cia_min_keysize = ARC4_MIN_KEY_SIZE, + .cia_max_keysize = ARC4_MAX_KEY_SIZE, + .cia_setkey = arc4_set_key, + .cia_encrypt = arc4_crypt_one, + .cia_decrypt = arc4_crypt_one, + }, + }, +}, { + .cra_name = "ecb(arc4)", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = ARC4_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct arc4_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_u = { + .blkcipher = { + .min_keysize = ARC4_MIN_KEY_SIZE, + .max_keysize = ARC4_MAX_KEY_SIZE, + .setkey = arc4_set_key, + .encrypt = ecb_arc4_crypt, + .decrypt = ecb_arc4_crypt, + }, + }, +} }; static int __init arc4_init(void) { - return crypto_register_alg(&arc4_alg); + return crypto_register_algs(arc4_algs, ARRAY_SIZE(arc4_algs)); } - static void __exit arc4_exit(void) { - crypto_unregister_alg(&arc4_alg); + crypto_unregister_algs(arc4_algs, ARRAY_SIZE(arc4_algs)); } module_init(arc4_init); -- GitLab From d366db605c8c4a9878589bc4a87e55f6063184ac Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 9 Jun 2012 18:25:46 +0300 Subject: [PATCH 1557/6849] crypto: arc4 - improve performance by using u32 for ctx and variables This patch changes u8 in struct arc4_ctx and variables to u32 (as AMD seems to have problem with u8 array). Below are tcrypt results of old 1-byte block cipher versus ecb(arc4) with u8 and ecb(arc4) with u32. tcrypt results, x86-64 (speed ratios: new-u32/old, new-u8/old): u32 u8 AMD Phenom II : x3.6 x2.7 Intel Core 2 : x2.0 x1.9 tcrypt results, i386 (speed ratios: new-u32/old, new-u8/old): u32 u8 Intel Atom N260 : x1.5 x1.4 Cc: Jon Oberheide Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- crypto/arc4.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto/arc4.c b/crypto/arc4.c index 07913fc52c4e..5a772c3657d5 100644 --- a/crypto/arc4.c +++ b/crypto/arc4.c @@ -22,8 +22,8 @@ #define ARC4_BLOCK_SIZE 1 struct arc4_ctx { - u8 S[256]; - u8 x, y; + u32 S[256]; + u32 x, y; }; static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, @@ -39,7 +39,7 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, ctx->S[i] = i; for (i = 0; i < 256; i++) { - u8 a = ctx->S[i]; + u32 a = ctx->S[i]; j = (j + in_key[k] + a) & 0xff; ctx->S[i] = ctx->S[j]; ctx->S[j] = a; @@ -53,9 +53,9 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len) { - u8 *const S = ctx->S; - u8 x, y, a, b; - u8 ty, ta, tb; + u32 *const S = ctx->S; + u32 x, y, a, b; + u32 ty, ta, tb; if (len == 0) return; -- GitLab From 3387e7d69048f5ab02729825f9611754850d9a87 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 14 Jun 2012 10:09:03 +0800 Subject: [PATCH 1558/6849] crypto: serpent-sse2/avx - allow both to be built into kernel Rename serpent-avx assembler functions so that they do not collide with serpent-sse2 assembler functions when linking both versions in to same kernel image. Reported-by: Randy Dunlap Cc: Johannes Goetzfried Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/serpent-avx-x86_64-asm_64.S | 12 +++---- arch/x86/crypto/serpent_avx_glue.c | 2 +- arch/x86/crypto/serpent_sse2_glue.c | 2 +- arch/x86/include/asm/serpent-avx.h | 32 +++++++++++++++++++ .../include/asm/{serpent.h => serpent-sse2.h} | 4 +-- 5 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 arch/x86/include/asm/serpent-avx.h rename arch/x86/include/asm/{serpent.h => serpent-sse2.h} (95%) diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S index 0ed47a124bac..504106bf04a2 100644 --- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S @@ -579,10 +579,10 @@ vmovdqu x3, (3*4*4)(out); .align 8 -.global __serpent_enc_blk_8way -.type __serpent_enc_blk_8way,@function; +.global __serpent_enc_blk_8way_avx +.type __serpent_enc_blk_8way_avx,@function; -__serpent_enc_blk_8way: +__serpent_enc_blk_8way_avx: /* input: * %rdi: ctx, CTX * %rsi: dst @@ -647,10 +647,10 @@ __enc_xor8: ret; .align 8 -.global serpent_dec_blk_8way -.type serpent_dec_blk_8way,@function; +.global serpent_dec_blk_8way_avx +.type serpent_dec_blk_8way_avx,@function; -serpent_dec_blk_8way: +serpent_dec_blk_8way_avx: /* input: * %rdi: ctx, CTX * %rsi: dst diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c index 0dc7a26535e5..dd81bab4f11a 100644 --- a/arch/x86/crypto/serpent_avx_glue.c +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 4b21be85e0a1..deecd25c1299 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/include/asm/serpent-avx.h b/arch/x86/include/asm/serpent-avx.h new file mode 100644 index 000000000000..432deedd2945 --- /dev/null +++ b/arch/x86/include/asm/serpent-avx.h @@ -0,0 +1,32 @@ +#ifndef ASM_X86_SERPENT_AVX_H +#define ASM_X86_SERPENT_AVX_H + +#include +#include + +#define SERPENT_PARALLEL_BLOCKS 8 + +asmlinkage void __serpent_enc_blk_8way_avx(struct serpent_ctx *ctx, u8 *dst, + const u8 *src, bool xor); +asmlinkage void serpent_dec_blk_8way_avx(struct serpent_ctx *ctx, u8 *dst, + const u8 *src); + +static inline void serpent_enc_blk_xway(struct serpent_ctx *ctx, u8 *dst, + const u8 *src) +{ + __serpent_enc_blk_8way_avx(ctx, dst, src, false); +} + +static inline void serpent_enc_blk_xway_xor(struct serpent_ctx *ctx, u8 *dst, + const u8 *src) +{ + __serpent_enc_blk_8way_avx(ctx, dst, src, true); +} + +static inline void serpent_dec_blk_xway(struct serpent_ctx *ctx, u8 *dst, + const u8 *src) +{ + serpent_dec_blk_8way_avx(ctx, dst, src); +} + +#endif diff --git a/arch/x86/include/asm/serpent.h b/arch/x86/include/asm/serpent-sse2.h similarity index 95% rename from arch/x86/include/asm/serpent.h rename to arch/x86/include/asm/serpent-sse2.h index d3ef63fe0c81..e6e77dffbdab 100644 --- a/arch/x86/include/asm/serpent.h +++ b/arch/x86/include/asm/serpent-sse2.h @@ -1,5 +1,5 @@ -#ifndef ASM_X86_SERPENT_H -#define ASM_X86_SERPENT_H +#ifndef ASM_X86_SERPENT_SSE2_H +#define ASM_X86_SERPENT_SSE2_H #include #include -- GitLab From fdec53d5203ee3d44be7c09d1524e3a6287d46a7 Mon Sep 17 00:00:00 2001 From: Javi Merino Date: Wed, 13 Jun 2012 15:07:00 +0100 Subject: [PATCH 1559/6849] DMA: PL330: Fix racy mutex unlock pl330_update() stores a pointer to the thrd->req that finished, which contains a pointer to the corresponding pl330_req. This is done with the pl330_lock held. Then, it iterates through the req_done list, calling the callback for each of the requests that are done. The problem is that the driver releases the lock before calling the callback for each of the callbacks. pl330_submit_req() running in another processor can then acquire the lock and insert another request in one of the thrd->req that hasn't been processed yet, replacing the pointer to pl330_req there. When the callback returns in pl330_update() and the next rqdone is popped from the list, it dereferences the pl330_req pointer to the just scheduled pl330_req, instead of the one that has finished, calling pl330 with the wrong r. This patch fixes this by storing the pointer to pl330_req directly in the list. Signed-off-by: Javi Merino Cc: Jassi Brar Acked-by: Jassi Brar Signed-off-by: Vinod Koul --- drivers/dma/pl330.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 3ce7d553a746..e4feba6b03c0 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -392,6 +392,8 @@ struct pl330_req { struct pl330_reqcfg *cfg; /* Pointer to first xfer in the request. */ struct pl330_xfer *x; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; }; /* @@ -461,8 +463,6 @@ struct _pl330_req { /* Number of bytes taken to setup MC for the req */ u32 mc_len; struct pl330_req *r; - /* Hook to attach to DMAC's list of reqs with due callback */ - struct list_head rqd; }; /* ToBeDone for tasklet */ @@ -1683,7 +1683,7 @@ static void pl330_dotask(unsigned long data) /* Returns 1 if state was updated, 0 otherwise */ static int pl330_update(const struct pl330_info *pi) { - struct _pl330_req *rqdone; + struct pl330_req *rqdone, *tmp; struct pl330_dmac *pl330; unsigned long flags; void __iomem *regs; @@ -1750,7 +1750,10 @@ static int pl330_update(const struct pl330_info *pi) if (active == -1) /* Aborted */ continue; - rqdone = &thrd->req[active]; + /* Detach the req */ + rqdone = thrd->req[active].r; + thrd->req[active].r = NULL; + mark_free(thrd, active); /* Get going again ASAP */ @@ -1762,20 +1765,11 @@ static int pl330_update(const struct pl330_info *pi) } /* Now that we are in no hurry, do the callbacks */ - while (!list_empty(&pl330->req_done)) { - struct pl330_req *r; - - rqdone = container_of(pl330->req_done.next, - struct _pl330_req, rqd); - - list_del_init(&rqdone->rqd); - - /* Detach the req */ - r = rqdone->r; - rqdone->r = NULL; + list_for_each_entry_safe(rqdone, tmp, &pl330->req_done, rqd) { + list_del(&rqdone->rqd); spin_unlock_irqrestore(&pl330->lock, flags); - _callback(r, PL330_ERR_NONE); + _callback(rqdone, PL330_ERR_NONE); spin_lock_irqsave(&pl330->lock, flags); } -- GitLab From f7ceb362c4d2f4e613982148ddb143ad6a205485 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 12 Jun 2012 20:19:24 +0200 Subject: [PATCH 1560/6849] dma: coh901318: use devm allocation Allocate memory, region, remap and irq for device state using devm_* helpers to simplify memory accounting. Signed-off-by: Linus Walleij Signed-off-by: Vinod Koul --- drivers/dma/coh901318.c | 72 ++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index e67b4e06a918..aa384e53b7ac 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -1438,34 +1438,32 @@ static int __init coh901318_probe(struct platform_device *pdev) io = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!io) - goto err_get_resource; + return -ENODEV; /* Map DMA controller registers to virtual memory */ - if (request_mem_region(io->start, - resource_size(io), - pdev->dev.driver->name) == NULL) { - err = -EBUSY; - goto err_request_mem; - } + if (devm_request_mem_region(&pdev->dev, + io->start, + resource_size(io), + pdev->dev.driver->name) == NULL) + return -ENOMEM; pdata = pdev->dev.platform_data; if (!pdata) - goto err_no_platformdata; + return -ENODEV; - base = kmalloc(ALIGN(sizeof(struct coh901318_base), 4) + - pdata->max_channels * - sizeof(struct coh901318_chan), - GFP_KERNEL); + base = devm_kzalloc(&pdev->dev, + ALIGN(sizeof(struct coh901318_base), 4) + + pdata->max_channels * + sizeof(struct coh901318_chan), + GFP_KERNEL); if (!base) - goto err_alloc_coh_dma_channels; + return -ENOMEM; base->chans = ((void *)base) + ALIGN(sizeof(struct coh901318_base), 4); - base->virtbase = ioremap(io->start, resource_size(io)); - if (!base->virtbase) { - err = -ENOMEM; - goto err_no_ioremap; - } + base->virtbase = devm_ioremap(&pdev->dev, io->start, resource_size(io)); + if (!base->virtbase) + return -ENOMEM; base->dev = &pdev->dev; base->platform = pdata; @@ -1474,25 +1472,20 @@ static int __init coh901318_probe(struct platform_device *pdev) COH901318_DEBUGFS_ASSIGN(debugfs_dma_base, base); - platform_set_drvdata(pdev, base); - irq = platform_get_irq(pdev, 0); if (irq < 0) - goto err_no_irq; - - err = request_irq(irq, dma_irq_handler, IRQF_DISABLED, - "coh901318", base); - if (err) { - dev_crit(&pdev->dev, - "Cannot allocate IRQ for DMA controller!\n"); - goto err_request_irq; - } + return irq; + + err = devm_request_irq(&pdev->dev, irq, dma_irq_handler, IRQF_DISABLED, + "coh901318", base); + if (err) + return err; err = coh901318_pool_create(&base->pool, &pdev->dev, sizeof(struct coh901318_lli), 32); if (err) - goto err_pool_create; + return err; /* init channels for device transfers */ coh901318_base_init(&base->dma_slave, base->platform->chans_slave, @@ -1538,6 +1531,7 @@ static int __init coh901318_probe(struct platform_device *pdev) if (err) goto err_register_memcpy; + platform_set_drvdata(pdev, base); dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n", (u32) base->virtbase); @@ -1547,19 +1541,6 @@ static int __init coh901318_probe(struct platform_device *pdev) dma_async_device_unregister(&base->dma_slave); err_register_slave: coh901318_pool_destroy(&base->pool); - err_pool_create: - free_irq(platform_get_irq(pdev, 0), base); - err_request_irq: - err_no_irq: - iounmap(base->virtbase); - err_no_ioremap: - kfree(base); - err_alloc_coh_dma_channels: - err_no_platformdata: - release_mem_region(pdev->resource->start, - resource_size(pdev->resource)); - err_request_mem: - err_get_resource: return err; } @@ -1570,11 +1551,6 @@ static int __exit coh901318_remove(struct platform_device *pdev) dma_async_device_unregister(&base->dma_memcpy); dma_async_device_unregister(&base->dma_slave); coh901318_pool_destroy(&base->pool); - free_irq(platform_get_irq(pdev, 0), base); - iounmap(base->virtbase); - kfree(base); - release_mem_region(pdev->resource->start, - resource_size(pdev->resource)); return 0; } -- GitLab From db218b3d55627ef515d3b32888b269ed319c4c8d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Jun 2012 14:05:24 +0900 Subject: [PATCH 1561/6849] sh64: Use generic unaligned access control/counters. This switches over from the special-casing that sh64 had and to the model that's being employed for sh32. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps_64.c | 150 ++++++++++---------------------------- 1 file changed, 37 insertions(+), 113 deletions(-) diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index ba95d63e623d..488c1cd557f1 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -264,20 +264,20 @@ static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_na die_if_no_fixup(str, regs, error_code); } -static int read_opcode(unsigned long long pc, unsigned long *result_opcode, int from_user_mode) +static int read_opcode(reg_size_t pc, insn_size_t *result_opcode, int from_user_mode) { int get_user_error; unsigned long aligned_pc; - unsigned long opcode; + insn_size_t opcode; if ((pc & 3) == 1) { /* SHmedia */ aligned_pc = pc & ~3; if (from_user_mode) { - if (!access_ok(VERIFY_READ, aligned_pc, sizeof(unsigned long))) { + if (!access_ok(VERIFY_READ, aligned_pc, sizeof(insn_size_t))) { get_user_error = -EFAULT; } else { - get_user_error = __get_user(opcode, (unsigned long *)aligned_pc); + get_user_error = __get_user(opcode, (insn_size_t *)aligned_pc); *result_opcode = opcode; } return get_user_error; @@ -285,7 +285,7 @@ static int read_opcode(unsigned long long pc, unsigned long *result_opcode, int /* If the fault was in the kernel, we can either read * this directly, or if not, we fault. */ - *result_opcode = *(unsigned long *) aligned_pc; + *result_opcode = *(insn_size_t *)aligned_pc; return 0; } } else if ((pc & 1) == 0) { @@ -311,17 +311,23 @@ static int address_is_sign_extended(__u64 a) #endif } +/* return -1 for fault, 0 for OK */ static int generate_and_check_address(struct pt_regs *regs, - __u32 opcode, + insn_size_t opcode, int displacement_not_indexed, int width_shift, __u64 *address) { - /* return -1 for fault, 0 for OK */ - __u64 base_address, addr; int basereg; + switch (1 << width_shift) { + case 1: inc_unaligned_byte_access(); break; + case 2: inc_unaligned_word_access(); break; + case 4: inc_unaligned_dword_access(); break; + case 8: inc_unaligned_multi_access(); break; + } + basereg = (opcode >> 20) & 0x3f; base_address = regs->regs[basereg]; if (displacement_not_indexed) { @@ -338,28 +344,28 @@ static int generate_and_check_address(struct pt_regs *regs, } /* Check sign extended */ - if (!address_is_sign_extended(addr)) { + if (!address_is_sign_extended(addr)) return -1; - } /* Check accessible. For misaligned access in the kernel, assume the address is always accessible (and if not, just fault when the load/store gets done.) */ if (user_mode(regs)) { - if (addr >= TASK_SIZE) { + inc_unaligned_user_access(); + + if (addr >= TASK_SIZE) return -1; - } - /* Do access_ok check later - it depends on whether it's a load or a store. */ - } + } else + inc_unaligned_kernel_access(); *address = addr; + + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, addr); + unaligned_fixups_notify(current, opcode, regs); + return 0; } -static int user_mode_unaligned_fixup_count = 10; -static int user_mode_unaligned_fixup_enable = 1; -static int kernel_mode_unaligned_fixup_count = 32; - static void misaligned_kernel_word_load(__u64 address, int do_sign_extend, __u64 *result) { unsigned short x; @@ -389,7 +395,7 @@ static void misaligned_kernel_word_store(__u64 address, __u64 value) } static int misaligned_load(struct pt_regs *regs, - __u32 opcode, + insn_size_t opcode, int displacement_not_indexed, int width_shift, int do_sign_extend) @@ -401,11 +407,8 @@ static int misaligned_load(struct pt_regs *regs, error = generate_and_check_address(regs, opcode, displacement_not_indexed, width_shift, &address); - if (error < 0) { + if (error < 0) return error; - } - - perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, address); destreg = (opcode >> 4) & 0x3f; if (user_mode(regs)) { @@ -464,11 +467,10 @@ static int misaligned_load(struct pt_regs *regs, } return 0; - } static int misaligned_store(struct pt_regs *regs, - __u32 opcode, + insn_size_t opcode, int displacement_not_indexed, int width_shift) { @@ -479,11 +481,8 @@ static int misaligned_store(struct pt_regs *regs, error = generate_and_check_address(regs, opcode, displacement_not_indexed, width_shift, &address); - if (error < 0) { + if (error < 0) return error; - } - - perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, address); srcreg = (opcode >> 4) & 0x3f; if (user_mode(regs)) { @@ -537,13 +536,12 @@ static int misaligned_store(struct pt_regs *regs, } return 0; - } /* Never need to fix up misaligned FPU accesses within the kernel since that's a real error. */ static int misaligned_fpu_load(struct pt_regs *regs, - __u32 opcode, + insn_size_t opcode, int displacement_not_indexed, int width_shift, int do_paired_load) @@ -555,11 +553,8 @@ static int misaligned_fpu_load(struct pt_regs *regs, error = generate_and_check_address(regs, opcode, displacement_not_indexed, width_shift, &address); - if (error < 0) { + if (error < 0) return error; - } - - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, address); destreg = (opcode >> 4) & 0x3f; if (user_mode(regs)) { @@ -615,12 +610,10 @@ static int misaligned_fpu_load(struct pt_regs *regs, die ("Misaligned FPU load inside kernel", regs, 0); return -1; } - - } static int misaligned_fpu_store(struct pt_regs *regs, - __u32 opcode, + insn_size_t opcode, int displacement_not_indexed, int width_shift, int do_paired_load) @@ -632,11 +625,8 @@ static int misaligned_fpu_store(struct pt_regs *regs, error = generate_and_check_address(regs, opcode, displacement_not_indexed, width_shift, &address); - if (error < 0) { + if (error < 0) return error; - } - - perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, address); srcreg = (opcode >> 4) & 0x3f; if (user_mode(regs)) { @@ -697,11 +687,13 @@ static int misaligned_fpu_store(struct pt_regs *regs, static int misaligned_fixup(struct pt_regs *regs) { - unsigned long opcode; + insn_size_t opcode; int error; int major, minor; + unsigned int user_action; - if (!user_mode_unaligned_fixup_enable) + user_action = unaligned_user_action(); + if (!(user_action & UM_FIXUP)) return -1; error = read_opcode(regs->pc, &opcode, user_mode(regs)); @@ -711,23 +703,6 @@ static int misaligned_fixup(struct pt_regs *regs) major = (opcode >> 26) & 0x3f; minor = (opcode >> 16) & 0xf; - if (user_mode(regs) && (user_mode_unaligned_fixup_count > 0)) { - --user_mode_unaligned_fixup_count; - /* Only do 'count' worth of these reports, to remove a potential DoS against syslog */ - printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n", - current->comm, task_pid_nr(current), (__u32)regs->pc, opcode); - } else if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) { - --kernel_mode_unaligned_fixup_count; - if (in_interrupt()) { - printk("Fixing up unaligned kernelspace access in interrupt pc=0x%08x ins=0x%08lx\n", - (__u32)regs->pc, opcode); - } else { - printk("Fixing up unaligned kernelspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n", - current->comm, task_pid_nr(current), (__u32)regs->pc, opcode); - } - } - - switch (major) { case (0x84>>2): /* LD.W */ error = misaligned_load(regs, opcode, 1, 1, 1); @@ -855,57 +830,6 @@ static int misaligned_fixup(struct pt_regs *regs) } -static ctl_table unaligned_table[] = { - { - .procname = "kernel_reports", - .data = &kernel_mode_unaligned_fixup_count, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec - }, - { - .procname = "user_reports", - .data = &user_mode_unaligned_fixup_count, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec - }, - { - .procname = "user_enable", - .data = &user_mode_unaligned_fixup_enable, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec}, - {} -}; - -static ctl_table unaligned_root[] = { - { - .procname = "unaligned_fixup", - .mode = 0555, - .child = unaligned_table - }, - {} -}; - -static ctl_table sh64_root[] = { - { - .procname = "sh64", - .mode = 0555, - .child = unaligned_root - }, - {} -}; -static struct ctl_table_header *sysctl_header; -static int __init init_sysctl(void) -{ - sysctl_header = register_sysctl_table(sh64_root); - return 0; -} - -__initcall(init_sysctl); - - asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs) { u64 peek_real_address_q(u64 addr); -- GitLab From 37c9ee0161332291c8d13bc40084d24c744ed842 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Jun 2012 14:12:18 +0900 Subject: [PATCH 1562/6849] sh64: Kill off old exception debugging helpers. There's not much here that we can't get at through alternate means (aside from the TLB contents, but that doesn't belong here anyways). Most of this information is already provided by the sh32 routines, which we'll consolidate on next. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps_64.c | 12 -- arch/sh/lib64/Makefile | 2 +- arch/sh/lib64/dbg.c | 248 -------------------------------------- 3 files changed, 1 insertion(+), 261 deletions(-) delete mode 100644 arch/sh/lib64/dbg.c diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index 488c1cd557f1..c902c29400a3 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -32,15 +32,6 @@ #include #include -#undef DEBUG_EXCEPTION -#ifdef DEBUG_EXCEPTION -/* implemented in ../lib/dbg.c */ -extern void show_excp_regs(char *fname, int trapnr, int signr, - struct pt_regs *regs); -#else -#define show_excp_regs(a, b, c, d) -#endif - static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_name, unsigned long error_code, struct pt_regs *regs, struct task_struct *tsk); @@ -239,7 +230,6 @@ DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current) /* Called with interrupts disabled */ asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs) { - show_excp_regs(__func__, -1, -1, regs); die_if_kernel("exception", regs, ex); } @@ -256,8 +246,6 @@ int do_unknown_trapa(unsigned long scId, struct pt_regs *regs) static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_name, unsigned long error_code, struct pt_regs *regs, struct task_struct *tsk) { - show_excp_regs(fn_name, trapnr, signr, regs); - if (user_mode(regs)) force_sig(signr, tsk); diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile index 1fee75aa1f98..69779ff741df 100644 --- a/arch/sh/lib64/Makefile +++ b/arch/sh/lib64/Makefile @@ -10,7 +10,7 @@ # # Panic should really be compiled as PIC -lib-y := udelay.o dbg.o panic.o memcpy.o memset.o \ +lib-y := udelay.o panic.o memcpy.o memset.o \ copy_user_memcpy.o copy_page.o strcpy.o strlen.o # Extracted from libgcc diff --git a/arch/sh/lib64/dbg.c b/arch/sh/lib64/dbg.c deleted file mode 100644 index 6152a6a6d9c6..000000000000 --- a/arch/sh/lib64/dbg.c +++ /dev/null @@ -1,248 +0,0 @@ -/*-------------------------------------------------------------------------- --- --- Identity : Linux50 Debug Funcions --- --- File : arch/sh/lib64/dbg.c --- --- Copyright 2000, 2001 STMicroelectronics Limited. --- Copyright 2004 Richard Curnow (evt_debug etc) --- ---------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include - -typedef u64 regType_t; - -static regType_t getConfigReg(u64 id) -{ - register u64 reg __asm__("r2"); - asm volatile ("getcfg %1, 0, %0":"=r" (reg):"r"(id)); - return (reg); -} - -/* ======================================================================= */ - -static char *szTab[] = { "4k", "64k", "1M", "512M" }; -static char *protTab[] = { "----", - "---R", - "--X-", - "--XR", - "-W--", - "-W-R", - "-WX-", - "-WXR", - "U---", - "U--R", - "U-X-", - "U-XR", - "UW--", - "UW-R", - "UWX-", - "UWXR" -}; -#define ITLB_BASE 0x00000000 -#define DTLB_BASE 0x00800000 -#define MAX_TLBs 64 -/* PTE High */ -#define GET_VALID(pte) ((pte) & 0x1) -#define GET_SHARED(pte) ((pte) & 0x2) -#define GET_ASID(pte) ((pte >> 2) & 0x0ff) -#define GET_EPN(pte) ((pte) & 0xfffff000) - -/* PTE Low */ -#define GET_CBEHAVIOR(pte) ((pte) & 0x3) -#define GET_PAGE_SIZE(pte) szTab[((pte >> 3) & 0x3)] -#define GET_PROTECTION(pte) protTab[((pte >> 6) & 0xf)] -#define GET_PPN(pte) ((pte) & 0xfffff000) - -#define PAGE_1K_MASK 0x00000000 -#define PAGE_4K_MASK 0x00000010 -#define PAGE_64K_MASK 0x00000080 -#define MMU_PAGESIZE_MASK (PAGE_64K_MASK | PAGE_4K_MASK) -#define PAGE_1MB_MASK MMU_PAGESIZE_MASK -#define PAGE_1K (1024) -#define PAGE_4K (1024 * 4) -#define PAGE_64K (1024 * 64) -#define PAGE_1MB (1024 * 1024) - -#define HOW_TO_READ_TLB_CONTENT \ - "[ ID] PPN EPN ASID Share CB P.Size PROT.\n" - -void print_single_tlb(unsigned long tlb, int single_print) -{ - regType_t pteH; - regType_t pteL; - unsigned int valid, shared, asid, epn, cb, ppn; - char *pSize; - char *pProt; - - /* - ** in case of single print is true, this implies: - ** 1) print the TLB in any case also if NOT VALID - ** 2) print out the header - */ - - pteH = getConfigReg(tlb); - valid = GET_VALID(pteH); - if (single_print) - printk(HOW_TO_READ_TLB_CONTENT); - else if (!valid) - return; - - pteL = getConfigReg(tlb + 1); - - shared = GET_SHARED(pteH); - asid = GET_ASID(pteH); - epn = GET_EPN(pteH); - cb = GET_CBEHAVIOR(pteL); - pSize = GET_PAGE_SIZE(pteL); - pProt = GET_PROTECTION(pteL); - ppn = GET_PPN(pteL); - printk("[%c%2ld] 0x%08x 0x%08x %03d %02x %02x %4s %s\n", - ((valid) ? ' ' : 'u'), ((tlb & 0x0ffff) / TLB_STEP), - ppn, epn, asid, shared, cb, pSize, pProt); -} - -void print_dtlb(void) -{ - int count; - unsigned long tlb; - - printk(" ================= SH-5 D-TLBs Status ===================\n"); - printk(HOW_TO_READ_TLB_CONTENT); - tlb = DTLB_BASE; - for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP) - print_single_tlb(tlb, 0); - printk - (" =============================================================\n"); -} - -void print_itlb(void) -{ - int count; - unsigned long tlb; - - printk(" ================= SH-5 I-TLBs Status ===================\n"); - printk(HOW_TO_READ_TLB_CONTENT); - tlb = ITLB_BASE; - for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP) - print_single_tlb(tlb, 0); - printk - (" =============================================================\n"); -} - -void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs) -{ - - unsigned long long ah, al, bh, bl, ch, cl; - - printk("\n"); - printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n", - ((from) ? from : "???"), current->pid, trapnr, signr); - - asm volatile ("getcon " __EXPEVT ", %0":"=r"(ah)); - asm volatile ("getcon " __EXPEVT ", %0":"=r"(al)); - ah = (ah) >> 32; - al = (al) & 0xffffffff; - asm volatile ("getcon " __KCR1 ", %0":"=r"(bh)); - asm volatile ("getcon " __KCR1 ", %0":"=r"(bl)); - bh = (bh) >> 32; - bl = (bl) & 0xffffffff; - asm volatile ("getcon " __INTEVT ", %0":"=r"(ch)); - asm volatile ("getcon " __INTEVT ", %0":"=r"(cl)); - ch = (ch) >> 32; - cl = (cl) & 0xffffffff; - printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - asm volatile ("getcon " __PEXPEVT ", %0":"=r"(ah)); - asm volatile ("getcon " __PEXPEVT ", %0":"=r"(al)); - ah = (ah) >> 32; - al = (al) & 0xffffffff; - asm volatile ("getcon " __PSPC ", %0":"=r"(bh)); - asm volatile ("getcon " __PSPC ", %0":"=r"(bl)); - bh = (bh) >> 32; - bl = (bl) & 0xffffffff; - asm volatile ("getcon " __PSSR ", %0":"=r"(ch)); - asm volatile ("getcon " __PSSR ", %0":"=r"(cl)); - ch = (ch) >> 32; - cl = (cl) & 0xffffffff; - printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - ah = (regs->pc) >> 32; - al = (regs->pc) & 0xffffffff; - bh = (regs->regs[18]) >> 32; - bl = (regs->regs[18]) & 0xffffffff; - ch = (regs->regs[15]) >> 32; - cl = (regs->regs[15]) & 0xffffffff; - printk("PC : %08Lx%08Lx LINK: %08Lx%08Lx SP : %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - ah = (regs->sr) >> 32; - al = (regs->sr) & 0xffffffff; - asm volatile ("getcon " __TEA ", %0":"=r"(bh)); - asm volatile ("getcon " __TEA ", %0":"=r"(bl)); - bh = (bh) >> 32; - bl = (bl) & 0xffffffff; - asm volatile ("getcon " __KCR0 ", %0":"=r"(ch)); - asm volatile ("getcon " __KCR0 ", %0":"=r"(cl)); - ch = (ch) >> 32; - cl = (cl) & 0xffffffff; - printk("SR : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - ah = (regs->regs[0]) >> 32; - al = (regs->regs[0]) & 0xffffffff; - bh = (regs->regs[1]) >> 32; - bl = (regs->regs[1]) & 0xffffffff; - ch = (regs->regs[2]) >> 32; - cl = (regs->regs[2]) & 0xffffffff; - printk("R0 : %08Lx%08Lx R1 : %08Lx%08Lx R2 : %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - ah = (regs->regs[3]) >> 32; - al = (regs->regs[3]) & 0xffffffff; - bh = (regs->regs[4]) >> 32; - bl = (regs->regs[4]) & 0xffffffff; - ch = (regs->regs[5]) >> 32; - cl = (regs->regs[5]) & 0xffffffff; - printk("R3 : %08Lx%08Lx R4 : %08Lx%08Lx R5 : %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - ah = (regs->regs[6]) >> 32; - al = (regs->regs[6]) & 0xffffffff; - bh = (regs->regs[7]) >> 32; - bl = (regs->regs[7]) & 0xffffffff; - ch = (regs->regs[8]) >> 32; - cl = (regs->regs[8]) & 0xffffffff; - printk("R6 : %08Lx%08Lx R7 : %08Lx%08Lx R8 : %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - - ah = (regs->regs[9]) >> 32; - al = (regs->regs[9]) & 0xffffffff; - bh = (regs->regs[10]) >> 32; - bl = (regs->regs[10]) & 0xffffffff; - ch = (regs->regs[11]) >> 32; - cl = (regs->regs[11]) & 0xffffffff; - printk("R9 : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - printk("....\n"); - - ah = (regs->tregs[0]) >> 32; - al = (regs->tregs[0]) & 0xffffffff; - bh = (regs->tregs[1]) >> 32; - bl = (regs->tregs[1]) & 0xffffffff; - ch = (regs->tregs[2]) >> 32; - cl = (regs->tregs[2]) & 0xffffffff; - printk("T0 : %08Lx%08Lx T1 : %08Lx%08Lx T2 : %08Lx%08Lx\n", - ah, al, bh, bl, ch, cl); - printk("....\n"); - - print_dtlb(); - print_itlb(); -} -- GitLab From 5f857bce21cfd0531dc7d4daac74d976caf6166b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Jun 2012 14:18:51 +0900 Subject: [PATCH 1563/6849] sh: Consolidate die definitions for trap handlers. This kills off the _64 versions and consolidates on the more robust _32 versions instead. Signed-off-by: Paul Mundt --- arch/sh/include/asm/bug.h | 4 +++ arch/sh/kernel/traps.c | 71 +++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/traps_32.c | 71 --------------------------------------- arch/sh/kernel/traps_64.c | 31 ----------------- 4 files changed, 75 insertions(+), 102 deletions(-) diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index 2b87d86bfc41..dcf278075429 100644 --- a/arch/sh/include/asm/bug.h +++ b/arch/sh/include/asm/bug.h @@ -110,6 +110,10 @@ do { \ #include struct pt_regs; + +/* arch/sh/kernel/traps.c */ extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn)); +extern void die_if_kernel(const char *str, struct pt_regs *regs, long err); +extern void die_if_no_fixup(const char *str, struct pt_regs *regs, long err); #endif /* __ASM_SH_BUG_H */ diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index a87e58a9e38f..72246bc06884 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -6,9 +6,80 @@ #include #include #include +#include +#include +#include #include #include +static DEFINE_SPINLOCK(die_lock); + +void die(const char *str, struct pt_regs *regs, long err) +{ + static int die_counter; + + oops_enter(); + + spin_lock_irq(&die_lock); + console_verbose(); + bust_spinlocks(1); + + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); + print_modules(); + show_regs(regs); + + printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm, + task_pid_nr(current), task_stack_page(current) + 1); + + if (!user_mode(regs) || in_interrupt()) + dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + + (unsigned long)task_stack_page(current)); + + notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV); + + bust_spinlocks(0); + add_taint(TAINT_DIE); + spin_unlock_irq(&die_lock); + oops_exit(); + + if (kexec_should_crash(current)) + crash_kexec(regs); + + if (in_interrupt()) + panic("Fatal exception in interrupt"); + + if (panic_on_oops) + panic("Fatal exception"); + + do_exit(SIGSEGV); +} + +void die_if_kernel(const char *str, struct pt_regs *regs, long err) +{ + if (!user_mode(regs)) + die(str, regs, err); +} + +/* + * try and fix up kernelspace address errors + * - userspace errors just cause EFAULT to be returned, resulting in SEGV + * - kernel/userspace interfaces cause a jump to an appropriate handler + * - other kernel errors are bad + */ +void die_if_no_fixup(const char *str, struct pt_regs *regs, long err) +{ + if (!user_mode(regs)) { + const struct exception_table_entry *fixup; + fixup = search_exception_tables(regs->pc); + if (fixup) { + regs->pc = fixup->fixup; + return; + } + + die(str, regs, err); + } +} + #ifdef CONFIG_GENERIC_BUG static void handle_BUG(struct pt_regs *regs) { diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index b8f5a51841ec..5f513a64dedf 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -16,13 +16,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -48,75 +46,6 @@ #define TRAP_ILLEGAL_SLOT_INST 13 #endif -static DEFINE_SPINLOCK(die_lock); - -void die(const char * str, struct pt_regs * regs, long err) -{ - static int die_counter; - - oops_enter(); - - spin_lock_irq(&die_lock); - console_verbose(); - bust_spinlocks(1); - - printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); - print_modules(); - show_regs(regs); - - printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm, - task_pid_nr(current), task_stack_page(current) + 1); - - if (!user_mode(regs) || in_interrupt()) - dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + - (unsigned long)task_stack_page(current)); - - notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV); - - bust_spinlocks(0); - add_taint(TAINT_DIE); - spin_unlock_irq(&die_lock); - oops_exit(); - - if (kexec_should_crash(current)) - crash_kexec(regs); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) - panic("Fatal exception"); - - do_exit(SIGSEGV); -} - -static inline void die_if_kernel(const char *str, struct pt_regs *regs, - long err) -{ - if (!user_mode(regs)) - die(str, regs, err); -} - -/* - * try and fix up kernelspace address errors - * - userspace errors just cause EFAULT to be returned, resulting in SEGV - * - kernel/userspace interfaces cause a jump to an appropriate handler - * - other kernel errors are bad - */ -static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err) -{ - if (!user_mode(regs)) { - const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs->pc); - if (fixup) { - regs->pc = fixup->fixup; - return; - } - - die(str, regs, err); - } -} - static inline void sign_extend(unsigned int count, unsigned char *dst) { #ifdef __LITTLE_ENDIAN__ diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index c902c29400a3..75bef61892d2 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -41,37 +41,6 @@ asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \ do_unhandled_exception(trapnr, signr, str, __stringify(name), error_code, regs, current); \ } -static DEFINE_SPINLOCK(die_lock); - -void die(const char * str, struct pt_regs * regs, long err) -{ - console_verbose(); - spin_lock_irq(&die_lock); - printk("%s: %lx\n", str, (err & 0xffffff)); - show_regs(regs); - spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); -} - -static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) -{ - if (!user_mode(regs)) - die(str, regs, err); -} - -static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err) -{ - if (!user_mode(regs)) { - const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs->pc); - if (fixup) { - regs->pc = fixup->fixup; - return; - } - die(str, regs, err); - } -} - DO_ERROR(13, SIGILL, "illegal slot instruction", illegal_slot_inst, current) DO_ERROR(87, SIGSEGV, "address error (exec)", address_error_exec, current) -- GitLab From 0375a73c6f1be69d5a9b439a7e95b92e54b3c09b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Jun 2012 14:46:36 +0900 Subject: [PATCH 1564/6849] sh64: Attempt to make reserved insn trap handler resemble C. This has been long overdue. No functional changes. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps_64.c | 386 +++++++++++++++++++------------------- 1 file changed, 195 insertions(+), 191 deletions(-) diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index 75bef61892d2..f87d20da1791 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -32,195 +32,6 @@ #include #include -static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_name, - unsigned long error_code, struct pt_regs *regs, struct task_struct *tsk); - -#define DO_ERROR(trapnr, signr, str, name, tsk) \ -asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \ -{ \ - do_unhandled_exception(trapnr, signr, str, __stringify(name), error_code, regs, current); \ -} - -DO_ERROR(13, SIGILL, "illegal slot instruction", illegal_slot_inst, current) -DO_ERROR(87, SIGSEGV, "address error (exec)", address_error_exec, current) - - -/* Implement misaligned load/store handling for kernel (and optionally for user - mode too). Limitation : only SHmedia mode code is handled - there is no - handling at all for misaligned accesses occurring in SHcompact code yet. */ - -static int misaligned_fixup(struct pt_regs *regs); - -asmlinkage void do_address_error_load(unsigned long error_code, struct pt_regs *regs) -{ - if (misaligned_fixup(regs) < 0) { - do_unhandled_exception(7, SIGSEGV, "address error(load)", - "do_address_error_load", - error_code, regs, current); - } - return; -} - -asmlinkage void do_address_error_store(unsigned long error_code, struct pt_regs *regs) -{ - if (misaligned_fixup(regs) < 0) { - do_unhandled_exception(8, SIGSEGV, "address error(store)", - "do_address_error_store", - error_code, regs, current); - } - return; -} - -#if defined(CONFIG_SH64_ID2815_WORKAROUND) - -#define OPCODE_INVALID 0 -#define OPCODE_USER_VALID 1 -#define OPCODE_PRIV_VALID 2 - -/* getcon/putcon - requires checking which control register is referenced. */ -#define OPCODE_CTRL_REG 3 - -/* Table of valid opcodes for SHmedia mode. - Form a 10-bit value by concatenating the major/minor opcodes i.e. - opcode[31:26,20:16]. The 6 MSBs of this value index into the following - array. The 4 LSBs select the bit-pair in the entry (bits 1:0 correspond to - LSBs==4'b0000 etc). */ -static unsigned long shmedia_opcode_table[64] = { - 0x55554044,0x54445055,0x15141514,0x14541414,0x00000000,0x10001000,0x01110055,0x04050015, - 0x00000444,0xc0000000,0x44545515,0x40405555,0x55550015,0x10005555,0x55555505,0x04050000, - 0x00000555,0x00000404,0x00040445,0x15151414,0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000055,0x40404444,0x00000404,0xc0009495,0x00000000,0x00000000,0x00000000,0x00000000, - 0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, - 0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, - 0x80005050,0x04005055,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, - 0x81055554,0x00000404,0x55555555,0x55555555,0x00000000,0x00000000,0x00000000,0x00000000 -}; - -void do_reserved_inst(unsigned long error_code, struct pt_regs *regs) -{ - /* Workaround SH5-101 cut2 silicon defect #2815 : - in some situations, inter-mode branches from SHcompact -> SHmedia - which should take ITLBMISS or EXECPROT exceptions at the target - falsely take RESINST at the target instead. */ - - unsigned long opcode = 0x6ff4fff0; /* guaranteed reserved opcode */ - unsigned long pc, aligned_pc; - int get_user_error; - int trapnr = 12; - int signr = SIGILL; - char *exception_name = "reserved_instruction"; - - pc = regs->pc; - if ((pc & 3) == 1) { - /* SHmedia : check for defect. This requires executable vmas - to be readable too. */ - aligned_pc = pc & ~3; - if (!access_ok(VERIFY_READ, aligned_pc, sizeof(unsigned long))) { - get_user_error = -EFAULT; - } else { - get_user_error = __get_user(opcode, (unsigned long *)aligned_pc); - } - if (get_user_error >= 0) { - unsigned long index, shift; - unsigned long major, minor, combined; - unsigned long reserved_field; - reserved_field = opcode & 0xf; /* These bits are currently reserved as zero in all valid opcodes */ - major = (opcode >> 26) & 0x3f; - minor = (opcode >> 16) & 0xf; - combined = (major << 4) | minor; - index = major; - shift = minor << 1; - if (reserved_field == 0) { - int opcode_state = (shmedia_opcode_table[index] >> shift) & 0x3; - switch (opcode_state) { - case OPCODE_INVALID: - /* Trap. */ - break; - case OPCODE_USER_VALID: - /* Restart the instruction : the branch to the instruction will now be from an RTE - not from SHcompact so the silicon defect won't be triggered. */ - return; - case OPCODE_PRIV_VALID: - if (!user_mode(regs)) { - /* Should only ever get here if a module has - SHcompact code inside it. If so, the same fix up is needed. */ - return; /* same reason */ - } - /* Otherwise, user mode trying to execute a privileged instruction - - fall through to trap. */ - break; - case OPCODE_CTRL_REG: - /* If in privileged mode, return as above. */ - if (!user_mode(regs)) return; - /* In user mode ... */ - if (combined == 0x9f) { /* GETCON */ - unsigned long regno = (opcode >> 20) & 0x3f; - if (regno >= 62) { - return; - } - /* Otherwise, reserved or privileged control register, => trap */ - } else if (combined == 0x1bf) { /* PUTCON */ - unsigned long regno = (opcode >> 4) & 0x3f; - if (regno >= 62) { - return; - } - /* Otherwise, reserved or privileged control register, => trap */ - } else { - /* Trap */ - } - break; - default: - /* Fall through to trap. */ - break; - } - } - /* fall through to normal resinst processing */ - } else { - /* Error trying to read opcode. This typically means a - real fault, not a RESINST any more. So change the - codes. */ - trapnr = 87; - exception_name = "address error (exec)"; - signr = SIGSEGV; - } - } - - do_unhandled_exception(trapnr, signr, exception_name, "do_reserved_inst", error_code, regs, current); -} - -#else /* CONFIG_SH64_ID2815_WORKAROUND */ - -/* If the workaround isn't needed, this is just a straightforward reserved - instruction */ -DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current) - -#endif /* CONFIG_SH64_ID2815_WORKAROUND */ - -/* Called with interrupts disabled */ -asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs) -{ - die_if_kernel("exception", regs, ex); -} - -int do_unknown_trapa(unsigned long scId, struct pt_regs *regs) -{ - /* Syscall debug */ - printk("System call ID error: [0x1#args:8 #syscall:16 0x%lx]\n", scId); - - die_if_kernel("unknown trapa", regs, scId); - - return -ENOSYS; -} - -static void do_unhandled_exception(int trapnr, int signr, char *str, char *fn_name, - unsigned long error_code, struct pt_regs *regs, struct task_struct *tsk) -{ - if (user_mode(regs)) - force_sig(signr, tsk); - - die_if_no_fixup(str, regs, error_code); -} - static int read_opcode(reg_size_t pc, insn_size_t *result_opcode, int from_user_mode) { int get_user_error; @@ -784,7 +595,201 @@ static int misaligned_fixup(struct pt_regs *regs) regs->pc += 4; /* Skip the instruction that's just been emulated */ return 0; } +} + +static void do_unhandled_exception(int signr, char *str, unsigned long error, + struct pt_regs *regs) +{ + if (user_mode(regs)) + force_sig(signr, current); + + die_if_no_fixup(str, regs, error); +} + +#define DO_ERROR(signr, str, name) \ +asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \ +{ \ + do_unhandled_exception(signr, str, error_code, regs); \ +} + +DO_ERROR(SIGILL, "illegal slot instruction", illegal_slot_inst) +DO_ERROR(SIGSEGV, "address error (exec)", address_error_exec) + +#if defined(CONFIG_SH64_ID2815_WORKAROUND) + +#define OPCODE_INVALID 0 +#define OPCODE_USER_VALID 1 +#define OPCODE_PRIV_VALID 2 + +/* getcon/putcon - requires checking which control register is referenced. */ +#define OPCODE_CTRL_REG 3 + +/* Table of valid opcodes for SHmedia mode. + Form a 10-bit value by concatenating the major/minor opcodes i.e. + opcode[31:26,20:16]. The 6 MSBs of this value index into the following + array. The 4 LSBs select the bit-pair in the entry (bits 1:0 correspond to + LSBs==4'b0000 etc). */ +static unsigned long shmedia_opcode_table[64] = { + 0x55554044,0x54445055,0x15141514,0x14541414,0x00000000,0x10001000,0x01110055,0x04050015, + 0x00000444,0xc0000000,0x44545515,0x40405555,0x55550015,0x10005555,0x55555505,0x04050000, + 0x00000555,0x00000404,0x00040445,0x15151414,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000055,0x40404444,0x00000404,0xc0009495,0x00000000,0x00000000,0x00000000,0x00000000, + 0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, + 0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, + 0x80005050,0x04005055,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555, + 0x81055554,0x00000404,0x55555555,0x55555555,0x00000000,0x00000000,0x00000000,0x00000000 +}; + +/* Workaround SH5-101 cut2 silicon defect #2815 : + in some situations, inter-mode branches from SHcompact -> SHmedia + which should take ITLBMISS or EXECPROT exceptions at the target + falsely take RESINST at the target instead. */ +void do_reserved_inst(unsigned long error_code, struct pt_regs *regs) +{ + insn_size_t opcode = 0x6ff4fff0; /* guaranteed reserved opcode */ + unsigned long pc, aligned_pc; + unsigned long index, shift; + unsigned long major, minor, combined; + unsigned long reserved_field; + int opcode_state; + int get_user_error; + int signr = SIGILL; + char *exception_name = "reserved_instruction"; + + pc = regs->pc; + + /* SHcompact is not handled */ + if (unlikely((pc & 3) == 0)) + goto out; + + /* SHmedia : check for defect. This requires executable vmas + to be readable too. */ + aligned_pc = pc & ~3; + if (!access_ok(VERIFY_READ, aligned_pc, sizeof(insn_size_t))) + get_user_error = -EFAULT; + else + get_user_error = __get_user(opcode, (insn_size_t *)aligned_pc); + + if (get_user_error < 0) { + /* + * Error trying to read opcode. This typically means a + * real fault, not a RESINST any more. So change the + * codes. + */ + exception_name = "address error (exec)"; + signr = SIGSEGV; + goto out; + } + + /* These bits are currently reserved as zero in all valid opcodes */ + reserved_field = opcode & 0xf; + if (unlikely(reserved_field)) + goto out; /* invalid opcode */ + + major = (opcode >> 26) & 0x3f; + minor = (opcode >> 16) & 0xf; + combined = (major << 4) | minor; + index = major; + shift = minor << 1; + opcode_state = (shmedia_opcode_table[index] >> shift) & 0x3; + switch (opcode_state) { + case OPCODE_INVALID: + /* Trap. */ + break; + case OPCODE_USER_VALID: + /* + * Restart the instruction: the branch to the instruction + * will now be from an RTE not from SHcompact so the + * silicon defect won't be triggered. + */ + return; + case OPCODE_PRIV_VALID: + if (!user_mode(regs)) { + /* + * Should only ever get here if a module has + * SHcompact code inside it. If so, the same fix + * up is needed. + */ + return; /* same reason */ + } + + /* + * Otherwise, user mode trying to execute a privileged + * instruction - fall through to trap. + */ + break; + case OPCODE_CTRL_REG: + /* If in privileged mode, return as above. */ + if (!user_mode(regs)) + return; + + /* In user mode ... */ + if (combined == 0x9f) { /* GETCON */ + unsigned long regno = (opcode >> 20) & 0x3f; + + if (regno >= 62) + return; + + /* reserved/privileged control register => trap */ + } else if (combined == 0x1bf) { /* PUTCON */ + unsigned long regno = (opcode >> 4) & 0x3f; + + if (regno >= 62) + return; + + /* reserved/privileged control register => trap */ + } + + break; + default: + /* Fall through to trap. */ + break; + } +out: + do_unhandled_exception(signr, exception_name, error_code, regs); +} + +#else /* CONFIG_SH64_ID2815_WORKAROUND */ + +/* If the workaround isn't needed, this is just a straightforward reserved + instruction */ +DO_ERROR(SIGILL, "reserved instruction", reserved_inst) + +#endif /* CONFIG_SH64_ID2815_WORKAROUND */ + +/* Called with interrupts disabled */ +asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs) +{ + die_if_kernel("exception", regs, ex); +} + +asmlinkage int do_unknown_trapa(unsigned long scId, struct pt_regs *regs) +{ + /* Syscall debug */ + printk("System call ID error: [0x1#args:8 #syscall:16 0x%lx]\n", scId); + + die_if_kernel("unknown trapa", regs, scId); + + return -ENOSYS; +} + +/* Implement misaligned load/store handling for kernel (and optionally for user + mode too). Limitation : only SHmedia mode code is handled - there is no + handling at all for misaligned accesses occurring in SHcompact code yet. */ + +asmlinkage void do_address_error_load(unsigned long error_code, struct pt_regs *regs) +{ + if (misaligned_fixup(regs) < 0) + do_unhandled_exception(SIGSEGV, "address error(load)", + error_code, regs); +} + +asmlinkage void do_address_error_store(unsigned long error_code, struct pt_regs *regs) +{ + if (misaligned_fixup(regs) < 0) + do_unhandled_exception(SIGSEGV, "address error(store)", + error_code, regs); } asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs) @@ -797,10 +802,9 @@ asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs) of access we make to them - just go direct to their physical addresses. */ exp_cause = peek_real_address_q(DM_EXP_CAUSE_PHY); - if (exp_cause & ~4) { + if (exp_cause & ~4) printk("DM.EXP_CAUSE had unexpected bits set (=%08lx)\n", (unsigned long)(exp_cause & 0xffffffff)); - } show_state(); /* Clear all DEBUGINT causes */ poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0); -- GitLab From 0412ddc82223ea2bb3a9db21355e5fe0862a97e5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Jun 2012 15:05:53 +0900 Subject: [PATCH 1565/6849] sh64: Fix up section mismatch warnings. WARNING: vmlinux.o(.cpuinit.text+0x280): Section mismatch in reference from the function cpu_probe() to the function .init.text:sh64_tlb_init() The function __cpuinit cpu_probe() references a function __init sh64_tlb_init(). If sh64_tlb_init is only used by cpu_probe then annotate sh64_tlb_init with a matching annotation. sh64_tlb_init() simply needs to be __cpuinit annotated, so fix that up. Signed-off-by: Paul Mundt --- arch/sh/mm/tlb-sh5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c index 3aea25dc431a..ff1c40a31cbc 100644 --- a/arch/sh/mm/tlb-sh5.c +++ b/arch/sh/mm/tlb-sh5.c @@ -17,7 +17,7 @@ /** * sh64_tlb_init - Perform initial setup for the DTLB and ITLB. */ -int __init sh64_tlb_init(void) +int __cpuinit sh64_tlb_init(void) { /* Assign some sane DTLB defaults */ cpu_data->dtlb.entries = 64; -- GitLab From ac1073a61d73b6277794d2efc872eb7e1b706b5c Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Thu, 14 Jun 2012 02:06:06 +0800 Subject: [PATCH 1566/6849] {nl,cfg,mac}80211: implement dot11MeshHWMProotInterval and dot11MeshHWMPactivePathToRootTimeout Add the mesh configuration parameters dot11MeshHWMProotInterval and dot11MeshHWMPactivePathToRootTimeout to be used by proactive PREQ mechanism. Signed-off-by: Chun-Yeow Yeoh [line-break commit log] Signed-off-by: Johannes Berg --- include/linux/nl80211.h | 9 +++++++++ include/net/cfg80211.h | 9 +++++++++ net/mac80211/cfg.c | 6 ++++++ net/mac80211/debugfs_netdev.c | 6 ++++++ net/wireless/mesh.c | 4 ++++ net/wireless/nl80211.c | 15 ++++++++++++++- 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index e4f41bdebc07..6936fabe8797 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -2185,6 +2185,13 @@ enum nl80211_mntr_flags { * * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute * + * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for + * which mesh STAs receiving a proactive PREQ shall consider the forwarding + * information to the root mesh STA to be valid. + * + * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between + * proactive PREQs are transmitted. + * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params { @@ -2211,6 +2218,8 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_RSSI_THRESHOLD, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, NL80211_MESHCONF_HT_OPMODE, + NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, + NL80211_MESHCONF_HWMP_ROOT_INTERVAL, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 76d54725ea31..e52b38d7b1b6 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -842,6 +842,13 @@ struct bss_parameters { * @rssi_threshold: the threshold for average signal strength of candidate * station to establish a peer link * @ht_opmode: mesh HT protection mode + * + * @dot11MeshHWMPactivePathToRootTimeout: The time (in TUs) for which mesh STAs + * receiving a proactive PREQ shall consider the forwarding information to + * the root mesh STA to be valid. + * + * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive + * PREQs are transmitted. */ struct mesh_config { u16 dot11MeshRetryTimeout; @@ -866,6 +873,8 @@ struct mesh_config { bool dot11MeshForwarding; s32 rssi_threshold; u16 ht_opmode; + u32 dot11MeshHWMPactivePathToRootTimeout; + u16 dot11MeshHWMProotInterval; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index cd8b1fb05d42..d93cda1c4215 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1590,6 +1590,12 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); } + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask)) + conf->dot11MeshHWMPactivePathToRootTimeout = + nconf->dot11MeshHWMPactivePathToRootTimeout; + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask)) + conf->dot11MeshHWMProotInterval = + nconf->dot11MeshHWMProotInterval; return 0; } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index c429417e1322..a8cea70902e4 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -510,6 +510,10 @@ IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); +IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout, + u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC); +IEEE80211_IF_FILE(dot11MeshHWMProotInterval, + u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC); #endif #define DEBUGFS_ADD_MODE(name, mode) \ @@ -611,6 +615,8 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); MESHPARAMS_ADD(rssi_threshold); MESHPARAMS_ADD(ht_opmode); + MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout); + MESHPARAMS_ADD(dot11MeshHWMProotInterval); #undef MESHPARAMS_ADD } #endif diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index b44c736bf9cf..2f141cfd581e 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -14,6 +14,8 @@ #define MESH_PATH_TIMEOUT 5000 #define MESH_RANN_INTERVAL 5000 +#define MESH_PATH_TO_ROOT_TIMEOUT 6000 +#define MESH_ROOT_INTERVAL 5000 /* * Minimum interval between two consecutive PREQs originated by the same @@ -62,6 +64,8 @@ const struct mesh_config default_mesh_config = { .dot11MeshForwarding = true, .rssi_threshold = MESH_RSSI_THRESHOLD, .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, + .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, + .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, }; const struct mesh_setup default_mesh_setup = { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7db0aee8cd5b..f8930db613df 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3469,7 +3469,11 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, cur_params.rssi_threshold) || nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE, - cur_params.ht_opmode)) + cur_params.ht_opmode) || + nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, + cur_params.dot11MeshHWMPactivePathToRootTimeout) || + nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, + cur_params.dot11MeshHWMProotInterval)) goto nla_put_failure; nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); @@ -3505,6 +3509,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 }, [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, + [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, + [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, }; static const struct nla_policy @@ -3612,6 +3618,13 @@ do {\ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout, + mask, + NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, + nla_get_u32); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, + mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, + nla_get_u16); if (mask_out) *mask_out = mask; -- GitLab From a69cc44fe9ebb806c5f3f8bd83fb4a50ca63647b Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Thu, 14 Jun 2012 02:06:07 +0800 Subject: [PATCH 1567/6849] mac80211: implement the proactive PREQ generation Generate the proactive PREQ element as defined in Sec. 13.10.9.3 (Case C) of IEEE Std. 802.11-2012 based on the selection of dot11MeshHWMPRootMode as follow: dot11MeshHWMPRootMode (2) is proactivePREQnoPREP dot11MeshHWMPRootMode (3) is proactivePREQwithPREP The proactive PREQ is generated based on the interval defined by dot11MeshHWMProotInterval. With this change, proactive RANN element is now generated if the dot11MeshHWMPRootMode is set to (4) instead of (1). Signed-off-by: Chun-Yeow Yeoh [line-break commit log] Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 42 +++++++++++++++++++++++++++++++++++++++ net/mac80211/mesh.c | 10 ++++++++-- net/mac80211/mesh_hwmp.c | 27 ++++++++++++++++++++++--- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 98c86ff657bb..6e0601189db9 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -567,6 +567,26 @@ struct ieee80211s_hdr { #define MESH_FLAGS_AE 0x3 #define MESH_FLAGS_PS_DEEP 0x4 +/** + * enum ieee80211_preq_flags - mesh PREQ element flags + * + * @IEEE80211_PREQ_PROACTIVE_PREP_FLAG: proactive PREP subfield + */ +enum ieee80211_preq_flags { + IEEE80211_PREQ_PROACTIVE_PREP_FLAG = 1<<2, +}; + +/** + * enum ieee80211_preq_target_flags - mesh PREQ element per target flags + * + * @IEEE80211_PREQ_TO_FLAG: target only subfield + * @IEEE80211_PREQ_USN_FLAG: unknown target HWMP sequence number subfield + */ +enum ieee80211_preq_target_flags { + IEEE80211_PREQ_TO_FLAG = 1<<0, + IEEE80211_PREQ_USN_FLAG = 1<<2, +}; + /** * struct ieee80211_quiet_ie * @@ -1474,6 +1494,28 @@ enum { IEEE80211_PATH_METRIC_VENDOR = 255, }; +/** + * enum ieee80211_root_mode_identifier - root mesh STA mode identifier + * + * These attribute are used by dot11MeshHWMPRootMode to set root mesh STA mode + * + * @IEEE80211_ROOTMODE_NO_ROOT: the mesh STA is not a root mesh STA (default) + * @IEEE80211_ROOTMODE_ROOT: the mesh STA is a root mesh STA if greater than + * this value + * @IEEE80211_PROACTIVE_PREQ_NO_PREP: the mesh STA is a root mesh STA supports + * the proactive PREQ with proactive PREP subfield set to 0 + * @IEEE80211_PROACTIVE_PREQ_WITH_PREP: the mesh STA is a root mesh STA + * supports the proactive PREQ with proactive PREP subfield set to 1 + * @IEEE80211_PROACTIVE_RANN: the mesh STA is a root mesh STA supports + * the proactive RANN + */ +enum ieee80211_root_mode_identifier { + IEEE80211_ROOTMODE_NO_ROOT = 0, + IEEE80211_ROOTMODE_ROOT = 1, + IEEE80211_PROACTIVE_PREQ_NO_PREP = 2, + IEEE80211_PROACTIVE_PREQ_WITH_PREP = 3, + IEEE80211_PROACTIVE_RANN = 4, +}; /* * IEEE 802.11-2007 7.3.2.9 Country information element diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 7cf19509fb68..6bff3c4d17dd 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + u32 interval; mesh_path_tx_root_frame(sdata); + + if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN) + interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; + else + interval = ifmsh->mshcfg.dot11MeshHWMProotInterval; + mod_timer(&ifmsh->mesh_path_root_timer, - round_jiffies(TU_TO_EXP_TIME( - ifmsh->mshcfg.dot11MeshHWMPRannInterval))); + round_jiffies(TU_TO_EXP_TIME(interval))); } #ifdef CONFIG_PM diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 9b6da2de660d..a6b08f5c4612 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1154,13 +1154,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; - u8 flags; + u8 flags, target_flags = 0; flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) ? RANN_FLAG_IS_GATE : 0; - mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, + + switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { + case IEEE80211_PROACTIVE_RANN: + mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, cpu_to_le32(++ifmsh->sn), 0, NULL, 0, broadcast_addr, - 0, sdata->u.mesh.mshcfg.element_ttl, + 0, ifmsh->mshcfg.element_ttl, cpu_to_le32(interval), 0, 0, sdata); + break; + case IEEE80211_PROACTIVE_PREQ_WITH_PREP: + flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; + case IEEE80211_PROACTIVE_PREQ_NO_PREP: + interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout; + target_flags |= IEEE80211_PREQ_TO_FLAG | + IEEE80211_PREQ_USN_FLAG; + mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, + cpu_to_le32(++ifmsh->sn), target_flags, + (u8 *) broadcast_addr, 0, broadcast_addr, + 0, ifmsh->mshcfg.element_ttl, + cpu_to_le32(interval), + 0, cpu_to_le32(ifmsh->preq_id++), sdata); + break; + default: + mhwmp_dbg("Proactive mechanism not supported"); + return; + } } -- GitLab From fbe765680d1fe9d08187ea4dad5041a7955a2c3a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 5 Jun 2012 09:59:52 +0200 Subject: [PATCH 1568/6849] s390/smp: make absolute lowcore / cpu restart parameter accesses more robust Setting the cpu restart parameters is done in three different fashions: - directly setting the four parameters individually - copying the four parameters with memcpy (using 4 * sizeof(long)) - copying the four parameters using a private structure In addition code in entry*.S relies on a certain order of the restart members of struct _lowcore. Make all of this more robust to future changes by adding a mem_absolute_assign(dest, val) define, which assigns val to dest using absolute addressing mode. Also the load multiple instructions in entry*.S have been split into separate load instruction so the order of the struct _lowcore members doesn't matter anymore. In addition move the prototypes of memcpy_real/absolute from uaccess.h to processor.h. These memcpy* variants are not related to uaccess at all. string.h doesn't seem to match as well, so lets use processor.h. Also replace the eight byte array in struct _lowcore which represents a misaliged u64 with a u64. The compiler will always create code that handles the misaligned u64 correctly. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/lowcore.h | 7 +------ arch/s390/include/asm/processor.h | 10 ++++++++++ arch/s390/include/asm/uaccess.h | 2 -- arch/s390/kernel/asm-offsets.c | 2 ++ arch/s390/kernel/entry.S | 4 +++- arch/s390/kernel/entry64.S | 4 +++- arch/s390/kernel/ipl.c | 15 ++++++--------- arch/s390/kernel/os_info.c | 2 +- arch/s390/kernel/setup.c | 13 ++++++------- arch/s390/kernel/smp.c | 16 +++++++--------- 10 files changed, 39 insertions(+), 36 deletions(-) diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 47853debb3b9..a47c6e221a95 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -302,12 +302,7 @@ struct _lowcore { */ __u64 ipib; /* 0x0e00 */ __u32 ipib_checksum; /* 0x0e08 */ - /* - * Because the vmcore_info pointer is not 8 byte aligned it never - * should not be accessed directly. For accessing the pointer, first - * copy it to a local pointer variable. - */ - __u8 vmcore_info[8]; /* 0x0e0c */ + __u64 vmcore_info; /* 0x0e0c */ __u8 pad_0x0e14[0x0e18-0x0e14]; /* 0x0e14 */ __u64 os_info; /* 0x0e18 */ __u8 pad_0x0e20[0x0f00-0x0e20]; /* 0x0e20 */ diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 20d0585cf905..f1700c5c8884 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -348,4 +348,14 @@ extern void (*s390_base_ext_handler_fn)(void); ".previous\n" #endif +extern int memcpy_real(void *, void *, size_t); +extern void memcpy_absolute(void *, void *, size_t); + +#define mem_assign_absolute(dest, val) { \ + __typeof__(dest) __tmp = (val); \ + \ + BUILD_BUG_ON(sizeof(__tmp) != sizeof(val)); \ + memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \ +} + #endif /* __ASM_S390_PROCESSOR_H */ diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 1f3a79bcd262..7e7285179aad 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -381,8 +381,6 @@ clear_user(void __user *to, unsigned long n) return n; } -extern int memcpy_real(void *, void *, size_t); -extern void memcpy_absolute(void *, void *, size_t); extern int copy_to_user_real(void __user *dest, void *src, size_t count); extern int copy_from_user_real(void *dest, void __user *src, size_t count); diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 83e6edf5cf17..0e974ddd156b 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -131,6 +131,8 @@ int main(void) DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack)); DEFINE(__LC_RESTART_STACK, offsetof(struct _lowcore, restart_stack)); DEFINE(__LC_RESTART_FN, offsetof(struct _lowcore, restart_fn)); + DEFINE(__LC_RESTART_DATA, offsetof(struct _lowcore, restart_data)); + DEFINE(__LC_RESTART_SOURCE, offsetof(struct _lowcore, restart_source)); DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce)); DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 3787f9e6907a..4ea53cd7c8c3 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -724,7 +724,9 @@ ENTRY(restart_int_handler) mvc __PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw ahi %r15,-STACK_FRAME_OVERHEAD # create stack frame on stack xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) - lm %r1,%r3,__LC_RESTART_FN # load fn, parm & source cpu + l %r1,__LC_RESTART_FN # load fn, parm & source cpu + l %r2,__LC_RESTART_DATA + l %r3,__LC_RESTART_SOURCE ltr %r3,%r3 # test source cpu address jm 1f # negative -> skip source stop 0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index d5f02e480e51..2813e831ba32 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -751,7 +751,9 @@ ENTRY(restart_int_handler) mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw aghi %r15,-STACK_FRAME_OVERHEAD # create stack frame on stack xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) - lmg %r1,%r3,__LC_RESTART_FN # load fn, parm & source cpu + lg %r1,__LC_RESTART_FN # load fn, parm & source cpu + lg %r2,__LC_RESTART_DATA + lg %r3,__LC_RESTART_SOURCE ltgr %r3,%r3 # test source cpu address jm 1f # negative -> skip source stop 0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 2f6cfd460cb6..25241cd8ddd8 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -1528,15 +1528,12 @@ static struct shutdown_action __refdata dump_action = { static void dump_reipl_run(struct shutdown_trigger *trigger) { - struct { - void *addr; - __u32 csum; - } __packed ipib; - - ipib.csum = csum_partial(reipl_block_actual, - reipl_block_actual->hdr.len, 0); - ipib.addr = reipl_block_actual; - memcpy_absolute(&S390_lowcore.ipib, &ipib, sizeof(ipib)); + unsigned long ipib = (unsigned long) &reipl_block_actual; + unsigned int csum; + + csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); + mem_assign_absolute(S390_lowcore.ipib, ipib); + mem_assign_absolute(S390_lowcore.ipib_checksum, csum); dump_run(trigger); } diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index 95fa5ac6c4ce..46480d81df00 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -60,7 +60,7 @@ void __init os_info_init(void) os_info.version_minor = OS_INFO_VERSION_MINOR; os_info.magic = OS_INFO_MAGIC; os_info.csum = os_info_csum(&os_info); - memcpy_absolute(&S390_lowcore.os_info, &ptr, sizeof(ptr)); + mem_assign_absolute(S390_lowcore.os_info, (unsigned long) ptr); } #ifdef CONFIG_CRASH_DUMP diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 489d1d8d96b0..49158cb19274 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -430,10 +430,11 @@ static void __init setup_lowcore(void) lc->restart_source = -1UL; /* Setup absolute zero lowcore */ - memcpy_absolute(&S390_lowcore.restart_stack, &lc->restart_stack, - 4 * sizeof(unsigned long)); - memcpy_absolute(&S390_lowcore.restart_psw, &lc->restart_psw, - sizeof(lc->restart_psw)); + mem_assign_absolute(S390_lowcore.restart_stack, lc->restart_stack); + mem_assign_absolute(S390_lowcore.restart_fn, lc->restart_fn); + mem_assign_absolute(S390_lowcore.restart_data, lc->restart_data); + mem_assign_absolute(S390_lowcore.restart_source, lc->restart_source); + mem_assign_absolute(S390_lowcore.restart_psw, lc->restart_psw); set_prefix((u32)(unsigned long) lc); lowcore_ptr[0] = lc; @@ -598,9 +599,7 @@ static void __init setup_memory_end(void) static void __init setup_vmcoreinfo(void) { #ifdef CONFIG_KEXEC - unsigned long ptr = paddr_vmcoreinfo_note(); - - memcpy_absolute(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); + mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); #endif } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index e01408429ad6..dc602a61233f 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -273,26 +273,24 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), void *data, unsigned long stack) { struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; - struct { - unsigned long stack; - void *func; - void *data; - unsigned long source; - } restart = { stack, func, data, stap() }; + unsigned long source_cpu = stap(); __load_psw_mask(psw_kernel_bits); - if (pcpu->address == restart.source) + if (pcpu->address == source_cpu) func(data); /* should not return */ /* Stop target cpu (if func returns this stops the current cpu). */ pcpu_sigp_retry(pcpu, SIGP_STOP, 0); /* Restart func on the target cpu and stop the current cpu. */ - memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); + mem_assign_absolute(lc->restart_stack, stack); + mem_assign_absolute(lc->restart_fn, (unsigned long) func); + mem_assign_absolute(lc->restart_data, (unsigned long) data); + mem_assign_absolute(lc->restart_source, source_cpu); asm volatile( "0: sigp 0,%0,%2 # sigp restart to target cpu\n" " brc 2,0b # busy, try again\n" "1: sigp 0,%1,%3 # sigp stop to current cpu\n" " brc 2,1b # busy, try again\n" - : : "d" (pcpu->address), "d" (restart.source), + : : "d" (pcpu->address), "d" (source_cpu), "K" (SIGP_RESTART), "K" (SIGP_STOP) : "0", "1", "cc"); for (;;) ; -- GitLab From 39912f9cf9603f0de085fb5ba916a7a88010ccd9 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 22:34:03 +0000 Subject: [PATCH 1569/6849] dcbnl: Silence harmless gcc warning about uninitialized reply_nlh Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 70bba3eb4ae9..da6ee81ce51f 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1664,7 +1664,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = -EINVAL; struct sk_buff *reply_skb; - struct nlmsghdr *reply_nlh; + struct nlmsghdr *reply_nlh = NULL; const struct reply_func *fn; if (!net_eq(net, &init_net)) -- GitLab From b3908e22ad8bb6074934496ef171fd83605d7d3e Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Jun 2012 22:40:15 +0000 Subject: [PATCH 1570/6849] dcbnl: Use BUG_ON() instead of BUG() Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index da6ee81ce51f..0a360072cfec 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -208,10 +208,7 @@ static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, return NULL; nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags); - if (!nlh) { - /* header should always fit, allocation must be buggy */ - BUG(); - } + BUG_ON(!nlh); dcb = nlmsg_data(nlh); dcb->dcb_family = AF_UNSPEC; -- GitLab From 666d1d8ad201803862514317c17695925e61316b Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 13 Jun 2012 23:03:56 -0400 Subject: [PATCH 1571/6849] GFS2: Combine functions get_local_rgrp and gfs2_inplace_reserve This function combines rgrp functions get_local_rgrp and gfs2_inplace_reserve so that the double retry loop is gone. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/rgrp.c | 82 ++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 53 deletions(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 3c6f7ed16a3b..e53d0a1c234f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1207,25 +1207,30 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip } /** - * get_local_rgrp - Choose and lock a rgrp for allocation + * gfs2_inplace_reserve - Reserve space in the filesystem * @ip: the inode to reserve space for - * @last_unlinked: the last unlinked block - * - * Try to acquire rgrp in way which avoids contending with others. + * @requested: the number of blocks to be reserved * * Returns: errno */ -static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) +int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_rgrpd *rgd, *begin = NULL; struct gfs2_blkreserv *rs = ip->i_res; - int error, rg_locked, flags = LM_FLAG_TRY; + int error = 0, rg_locked, flags = LM_FLAG_TRY; + u64 last_unlinked = NO_BLOCK; int loops = 0; if (sdp->sd_args.ar_rgrplvb) flags |= GL_SKIP; + rs = ip->i_res; + rs->rs_requested = requested; + if (gfs2_assert_warn(sdp, requested)) { + error = -EINVAL; + goto out; + } if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) rgd = begin = ip->i_rgd; @@ -1263,63 +1268,34 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) if (rgd->rd_flags & GFS2_RDF_CHECK) { if (sdp->sd_args.ar_rgrplvb) gfs2_rgrp_bh_get(rgd); - try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); + try_rgrp_unlink(rgd, &last_unlinked, + ip->i_no_addr); } if (!rg_locked) gfs2_glock_dq_uninit(&rs->rs_rgd_gh); /* fall through */ case GLR_TRYFAILED: rgd = gfs2_rgrpd_get_next(rgd); - if (rgd == begin) { - flags &= ~LM_FLAG_TRY; - loops++; - } + if (rgd != begin) /* If we didn't wrap */ + break; + + flags &= ~LM_FLAG_TRY; + loops++; + /* Check that fs hasn't grown if writing to rindex */ + if (ip == GFS2_I(sdp->sd_rindex) && + !sdp->sd_rindex_uptodate) { + error = gfs2_ri_update(ip); + if (error) + goto out; + } else if (loops == 2) + /* Flushing the log may release space */ + gfs2_log_flush(sdp, NULL); break; default: - return error; + goto out; } } - - return -ENOSPC; -} - -/** - * gfs2_inplace_reserve - Reserve space in the filesystem - * @ip: the inode to reserve space for - * @requested: the number of blocks to be reserved - * - * Returns: errno - */ - -int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) -{ - struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_blkreserv *rs; - int error = 0; - u64 last_unlinked = NO_BLOCK; - int tries = 0; - - rs = ip->i_res; - rs->rs_requested = requested; - if (gfs2_assert_warn(sdp, requested)) { - error = -EINVAL; - goto out; - } - - do { - error = get_local_rgrp(ip, &last_unlinked); - if (error != -ENOSPC) - break; - /* Check that fs hasn't grown if writing to rindex */ - if (ip == GFS2_I(sdp->sd_rindex) && !sdp->sd_rindex_uptodate) { - error = gfs2_ri_update(ip); - if (error) - break; - continue; - } - /* Flushing the log may release space */ - gfs2_log_flush(sdp, NULL); - } while (tries++ < 3); + error = -ENOSPC; out: if (error) -- GitLab From b8fd7331208e52a0a932209584bde80fd4ec09b9 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:49 -0500 Subject: [PATCH 1572/6849] ARM: OMAP: Remove unnecessary clk structure In the plat/dmtimer.h there is a structure named "clk" declared. This structure is not used and appears to be left over from previous code. Hence, remove this unused structure. Verified that both omap1 and omap2plus kernel configurations build with this change. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/dmtimer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 5da73562e486..5fdfaa481259 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -71,7 +71,6 @@ struct omap_timer_capability_dev_attr { }; struct omap_dm_timer; -struct clk; struct timer_regs { u32 tidr; -- GitLab From 26fe4e454bfee3248bc7f7bab38b4888db33528e Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:50 -0500 Subject: [PATCH 1573/6849] ARM: OMAP2+: Remove unused max number of timers definition The OMAP2+ timer code has a definition for the maximum number of timers that OMAP2+ devices have. This defintion is not used anywhere in the code and appears to be left over. Furthermore the definition is not accurate for OMAP4 devices that only have 11 timers available because the 12th timer is reserved as a secure timer and for OMAP3 devices the 12th timer is not available on secure devices. Therefore, remove this definition. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 840929bd9dae..c030dfeee76a 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -69,9 +69,6 @@ #define OMAP3_SECURE_TIMER 1 #endif -/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */ -#define MAX_GPTIMER_ID 12 - static u32 sys_timer_reserved; /* Clockevent code */ -- GitLab From b7b4ff764f7bf903e47eebdab661b1c38e791c6d Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:51 -0500 Subject: [PATCH 1574/6849] ARM: OMAP2+: Add dmtimer platform function to reserve systimers During early boot, one or two dmtimers are reserved by the kernel as system timers (for clocksource and clockevents). These timers are marked as reserved and the dmtimer driver is notified which timers have been reserved via the platform data information. For OMAP2+ devices the timers reserved may vary depending on device and compile flags. Therefore, it is not easy to assume which timers we be reserved for the system timers. In order to migrate the dmtimer driver to support device-tree we need a way to pass the timers reserved for system timers to the dmtimer driver. Using the platform data structure will not work in the same way as it is currently used because the platform data structure will be stored statically in the dmtimer itself and the platform data will be selected via the device-tree match device function (of_match_device). There are a couple ways to workaround this. One option is to store the system timers reserved for the kernel in the device-tree and query them on boot. The downside of this approach is that it adds some delay to parse the DT blob to search for the system timers. Secondly, for OMAP3 devices we have a dependency on compile time flags and the device-tree would not be aware of that kernel compile flags and so we would need to address that. The second option is to add a function to the dmtimer code to reserved the system timers during boot and so the dmtimer knows exactly which timers are being used for system timers. This also allows us to remove the "reserved" member from the timer platform data. This seemed like the simpler approach and so was implemented here. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 9 ++------- arch/arm/plat-omap/dmtimer.c | 18 +++++++++++++++++- arch/arm/plat-omap/include/plat/dmtimer.h | 3 +-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index c030dfeee76a..b0b208077c96 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -69,8 +69,6 @@ #define OMAP3_SECURE_TIMER 1 #endif -static u32 sys_timer_reserved; - /* Clockevent code */ static struct omap_dm_timer clkev; @@ -177,7 +175,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, omap_hwmod_enable(oh); - sys_timer_reserved |= (1 << (gptimer_id - 1)); + if (omap_dm_timer_reserve_systimer(gptimer_id)) + return -ENODEV; if (gptimer_id != 12) { struct clk *src; @@ -501,10 +500,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) pdata->set_timer_src = omap2_dm_timer_set_src; pdata->timer_ip_version = oh->class->rev; - /* Mark clocksource and clockevent timers as reserved */ - if ((sys_timer_reserved >> (id - 1)) & 0x1) - pdata->reserved = 1; - pwrdm = omap_hwmod_get_pwrdm(oh); pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); #ifdef CONFIG_PM diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 3b0cfeb33d05..f5b5c89ac7c2 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -45,6 +45,7 @@ #include +static u32 omap_reserved_systimers; static LIST_HEAD(omap_timer_list); static DEFINE_SPINLOCK(dm_timer_lock); @@ -152,6 +153,21 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) return ret; } +static inline u32 omap_dm_timer_reserved_systimer(int id) +{ + return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0; +} + +int omap_dm_timer_reserve_systimer(int id) +{ + if (omap_dm_timer_reserved_systimer(id)) + return -ENODEV; + + omap_reserved_systimers |= (1 << (id - 1)); + + return 0; +} + struct omap_dm_timer *omap_dm_timer_request(void) { struct omap_dm_timer *timer = NULL, *t; @@ -674,7 +690,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->id = pdev->id; timer->irq = irq->start; - timer->reserved = pdata->reserved; + timer->reserved = omap_dm_timer_reserved_systimer(timer->id); timer->pdev = pdev; timer->loses_context = pdata->loses_context; timer->get_context_loss_count = pdata->get_context_loss_count; diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 5fdfaa481259..1e5ce5d56240 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -98,13 +98,12 @@ struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); int timer_ip_version; u32 needs_manual_reset:1; - bool reserved; - bool loses_context; int (*get_context_loss_count)(struct device *dev); }; +int omap_dm_timer_reserve_systimer(int id); struct omap_dm_timer *omap_dm_timer_request(void); struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); int omap_dm_timer_free(struct omap_dm_timer *timer); -- GitLab From d1c1691be5290bf7e5b11b63b6fda0d63a9f4937 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:52 -0500 Subject: [PATCH 1575/6849] ARM: OMAP: Add DMTIMER capability variable to represent timer features Although the OMAP timers share a common hardware design, there are some differences between the timer instances in a given device. For example, a timer maybe in a power domain that can be powered-of, so can lose its logic state and need restoring where as another may be in power domain that is always be on. Another example, is a timer may support different clock sources to drive the timer. This information is passed to the dmtimer via the following platform data structure. struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); int timer_ip_version; u32 needs_manual_reset:1; bool loses_context; int (*get_context_loss_count)(struct device *dev); }; The above structure uses multiple variables to represent the timer features. HWMOD also stores the timer capabilities using a bit-mask that represents the features supported. By using the same format for representing the timer features in the platform data as used by HWMOD, we can ... 1. Use the flags defined in the plat/dmtimer.h to represent the features supported. 2. For devices using HWMOD, we can retrieve the features supported from HWMOD. 3. Eventually, simplify the platform data structure to be ... struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); u32 timer_capability; } Another benefit from doing this, is that it will simplify the migration of the dmtimer driver to device-tree. For example, in the current OMAP2+ timer code the "loses_context" variable is configured at runtime by calling an architecture specific function. For device tree this creates a problem, because we would need to call the architecture specific function from within the dmtimer driver. However, such attributes do not need to be queried at runtime and we can look up the attributes via HWMOD or device-tree. This changes a new "capability" variable to the platform data and timer structure so we can start removing and simplifying the platform data structure. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 3 +++ arch/arm/plat-omap/dmtimer.c | 1 + arch/arm/plat-omap/include/plat/dmtimer.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index b0b208077c96..d8a5dc3d695f 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -500,6 +500,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) pdata->set_timer_src = omap2_dm_timer_set_src; pdata->timer_ip_version = oh->class->rev; + if (timer_dev_attr) + pdata->timer_capability = timer_dev_attr->timer_capability; + pwrdm = omap_hwmod_get_pwrdm(oh); pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); #ifdef CONFIG_PM diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index f5b5c89ac7c2..30742d8e6819 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -694,6 +694,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->pdev = pdev; timer->loses_context = pdata->loses_context; timer->get_context_loss_count = pdata->get_context_loss_count; + timer->capability = pdata->timer_capability; /* Skip pm_runtime_enable for OMAP1 */ if (!pdata->needs_manual_reset) { diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 1e5ce5d56240..48e54caf9001 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -101,6 +101,7 @@ struct dmtimer_platform_data { bool loses_context; int (*get_context_loss_count)(struct device *dev); + u32 timer_capability; }; int omap_dm_timer_reserve_systimer(int id); @@ -273,6 +274,7 @@ struct omap_dm_timer { bool loses_context; int ctx_loss_count; int revision; + u32 capability; struct platform_device *pdev; struct list_head node; -- GitLab From 139486fa0c219914cf4a2b41df3e4c525afb1eee Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:53 -0500 Subject: [PATCH 1576/6849] ARM: OMAP2+: HWMOD: Correct timer device attributes Fix the following issues with the timer device attributes for OMAP2+ devices: 1. For OMAP24xx devices, timers 2-8 have the ALWAYS-ON attribute indicating that these timers are in an ALWAYS-ON power domain. This is not the case only timer1 is in an ALWAYS-ON power domain. 2. For OMAP3xxx devices, timers 2-7 have the ALWAYS-ON attribute indicating that these timers are in an ALWAYS-ON power domain. This is not the case only timer1 and timer12 are in an ALWAYS-ON power domain. 3. For OMAP3xxx devices, timer12 does not have the ALWAYS-ON attribute but is in an always-on power domain. Signed-off-by: Jon Hunter Acked-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 7 ------- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 8 +------- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 6 ------ 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 83eafd96ecaa..7814e83fd03f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -257,7 +257,6 @@ struct omap_hwmod omap2xxx_timer2_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; @@ -276,7 +275,6 @@ struct omap_hwmod omap2xxx_timer3_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; @@ -295,7 +293,6 @@ struct omap_hwmod omap2xxx_timer4_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; @@ -314,7 +311,6 @@ struct omap_hwmod omap2xxx_timer5_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; @@ -333,7 +329,6 @@ struct omap_hwmod omap2xxx_timer6_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; @@ -352,7 +347,6 @@ struct omap_hwmod omap2xxx_timer7_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; @@ -371,7 +365,6 @@ struct omap_hwmod omap2xxx_timer8_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index b26d3c9bca16..7b330944b3f7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -150,7 +150,7 @@ static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { /* secure timers dev attribute */ static struct omap_timer_capability_dev_attr capability_secure_dev_attr = { - .timer_capability = OMAP_TIMER_SECURE, + .timer_capability = OMAP_TIMER_ALWON | OMAP_TIMER_SECURE, }; /* always-on timers dev attribute */ @@ -195,7 +195,6 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_1ms_hwmod_class, }; @@ -213,7 +212,6 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_hwmod_class, }; @@ -231,7 +229,6 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_hwmod_class, }; @@ -249,7 +246,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_hwmod_class, }; @@ -267,7 +263,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_hwmod_class, }; @@ -285,7 +280,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_hwmod_class, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 950454a3fa31..ebf9657460dd 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2943,7 +2943,6 @@ static struct omap_hwmod omap44xx_timer2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer3 */ @@ -2965,7 +2964,6 @@ static struct omap_hwmod omap44xx_timer3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer4 */ @@ -2987,7 +2985,6 @@ static struct omap_hwmod omap44xx_timer4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer5 */ @@ -3009,7 +3006,6 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer6 */ @@ -3032,7 +3028,6 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer7 */ @@ -3054,7 +3049,6 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer8 */ -- GitLab From 67d2e760ae1909f3a3c444a063961e35a54b7bb0 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:54 -0500 Subject: [PATCH 1577/6849] ARM: OMAP2+: Fix external clock support for dmtimers Currently, the dmtimer determines whether an timer can support an external clock source (sys_altclk) for driving the timer by the IP version. Only OMAP24xx devices can support an external clock source, but the IP version between OMAP24xx and OMAP3xxx is common and so this incorrectly indicates that OMAP3 devices can use an external clock source. Rather than use the IP version, just let the clock framework handle this. If the "alt_ck" does not exist for a timer then the clock framework will fail to find the clock and hence will return an error. By doing this we can eliminate the "timer_ip_version" variable passed as part of the platform data and simplify the code. We can also remove the timer IP version from the HWMOD data because the dmtimer driver uses the TIDR register to determine the IP version. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 1 - arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 -- arch/arm/mach-omap2/timer.c | 12 ++---------- arch/arm/plat-omap/include/plat/dmtimer.h | 7 ------- 4 files changed, 2 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 7814e83fd03f..afad69c6ba6e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -68,7 +68,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { struct omap_hwmod_class omap2xxx_timer_hwmod_class = { .name = "timer", .sysc = &omap2xxx_timer_sysc, - .rev = OMAP_TIMER_IP_VERSION_1, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 7b330944b3f7..0ea53bcc7d18 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -129,7 +129,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = { static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = { .name = "timer", .sysc = &omap3xxx_timer_1ms_sysc, - .rev = OMAP_TIMER_IP_VERSION_1, }; static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { @@ -145,7 +144,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { .name = "timer", .sysc = &omap3xxx_timer_sysc, - .rev = OMAP_TIMER_IP_VERSION_1, }; /* secure timers dev attribute */ diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index d8a5dc3d695f..8c046d9d8ae8 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -397,7 +397,6 @@ OMAP_SYS_TIMER(4) static int omap2_dm_timer_set_src(struct platform_device *pdev, int source) { int ret; - struct dmtimer_platform_data *pdata = pdev->dev.platform_data; struct clk *fclk, *parent; char *parent_name = NULL; @@ -418,14 +417,8 @@ static int omap2_dm_timer_set_src(struct platform_device *pdev, int source) break; case OMAP_TIMER_SRC_EXT_CLK: - if (pdata->timer_ip_version == OMAP_TIMER_IP_VERSION_1) { - parent_name = "alt_ck"; - break; - } - dev_err(&pdev->dev, "%s: %d: invalid clk src.\n", - __func__, __LINE__); - clk_put(fclk); - return -EINVAL; + parent_name = "alt_ck"; + break; } parent = clk_get(&pdev->dev, parent_name); @@ -498,7 +491,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) sscanf(oh->name, "timer%2d", &id); pdata->set_timer_src = omap2_dm_timer_set_src; - pdata->timer_ip_version = oh->class->rev; if (timer_dev_attr) pdata->timer_capability = timer_dev_attr->timer_capability; diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 48e54caf9001..362cf97d721c 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -55,12 +55,6 @@ #define OMAP_TIMER_TRIGGER_OVERFLOW 0x01 #define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02 -/* - * IP revision identifier so that Highlander IP - * in OMAP4 can be distinguished. - */ -#define OMAP_TIMER_IP_VERSION_1 0x1 - /* timer capabilities used in hwmod database */ #define OMAP_TIMER_SECURE 0x80000000 #define OMAP_TIMER_ALWON 0x40000000 @@ -96,7 +90,6 @@ struct timer_regs { struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); - int timer_ip_version; u32 needs_manual_reset:1; bool loses_context; -- GitLab From 1c2d076b589225e51e022d85bb9f25dca26530f3 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:55 -0500 Subject: [PATCH 1578/6849] ARM: OMAP: Remove loses_context variable from timer platform data The platform data variable loses_context is used to determine if the timer may lose its logic state during power transitions and so needs to be restored. This information is also provided in the HWMOD device attributes for OMAP2+ devices via the OMAP_TIMER_ALWON flag. When this flag is set the timer will not lose context. So use the HWMOD device attributes to determine this. For OMAP1 devices, loses_context is never set and so set the OMAP_TIMER_ALWON flag for OMAP1 timers to ensure that code is equivalent. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/timer.c | 1 + arch/arm/mach-omap2/timer.c | 3 --- arch/arm/plat-omap/dmtimer.c | 8 ++++---- arch/arm/plat-omap/include/plat/dmtimer.h | 3 --- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 64c65bcb2d67..b4bf48c188fb 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -141,6 +141,7 @@ static int __init omap1_dm_timer_init(void) pdata->set_timer_src = omap1_dm_timer_set_src; pdata->needs_manual_reset = 1; + pdata->timer_capability = OMAP_TIMER_ALWON; ret = platform_device_add_data(pdev, pdata, sizeof(*pdata)); if (ret) { diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 8c046d9d8ae8..9b6880a33793 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -462,7 +462,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) struct dmtimer_platform_data *pdata; struct platform_device *pdev; struct omap_timer_capability_dev_attr *timer_dev_attr; - struct powerdomain *pwrdm; pr_debug("%s: %s\n", __func__, oh->name); @@ -495,8 +494,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) if (timer_dev_attr) pdata->timer_capability = timer_dev_attr->timer_capability; - pwrdm = omap_hwmod_get_pwrdm(oh); - pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); #ifdef CONFIG_PM pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; #endif diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 30742d8e6819..7aa12785e238 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -341,7 +341,7 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) omap_dm_timer_enable(timer); - if (timer->loses_context) { + if (!(timer->capability & OMAP_TIMER_ALWON)) { u32 ctx_loss_cnt_after = timer->get_context_loss_count(&timer->pdev->dev); if (ctx_loss_cnt_after != timer->ctx_loss_count) @@ -374,7 +374,8 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) __omap_dm_timer_stop(timer, timer->posted, rate); - if (timer->loses_context && timer->get_context_loss_count) + if (!(timer->capability & OMAP_TIMER_ALWON) && + timer->get_context_loss_count) timer->ctx_loss_count = timer->get_context_loss_count(&timer->pdev->dev); @@ -447,7 +448,7 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, omap_dm_timer_enable(timer); - if (timer->loses_context) { + if (!(timer->capability & OMAP_TIMER_ALWON)) { u32 ctx_loss_cnt_after = timer->get_context_loss_count(&timer->pdev->dev); if (ctx_loss_cnt_after != timer->ctx_loss_count) @@ -692,7 +693,6 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->reserved = omap_dm_timer_reserved_systimer(timer->id); timer->pdev = pdev; - timer->loses_context = pdata->loses_context; timer->get_context_loss_count = pdata->get_context_loss_count; timer->capability = pdata->timer_capability; diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 362cf97d721c..0a7ed31954ea 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -91,8 +91,6 @@ struct timer_regs { struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); u32 needs_manual_reset:1; - bool loses_context; - int (*get_context_loss_count)(struct device *dev); u32 timer_capability; }; @@ -264,7 +262,6 @@ struct omap_dm_timer { unsigned reserved:1; unsigned posted:1; struct timer_regs context; - bool loses_context; int ctx_loss_count; int revision; u32 capability; -- GitLab From 0b30ec1cb7f1b0134b16670f886baaf3521b083c Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:56 -0500 Subject: [PATCH 1579/6849] ARM: OMAP: Remove timer function pointer for context loss counter For OMAP2+ devices, a function pointer that returns the number of times a timer power domain has lost context is passed to the dmtimer driver. This function pointer is only populated for OMAP2+ devices and it is pointing to a platform function. Given that this is a platform function, we can simplify the code by removing the function pointer and referencing the function directly. We can use the OMAP_TIMER_ALWON flag to determine if we need to call this function for OMAP1 and OMAP2+ devices. The benefit of this change is the we can remove the function pointer from the platform data and simplifies the dmtimer migration to device-tree. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 3 --- arch/arm/plat-omap/dmtimer.c | 17 +++++++---------- arch/arm/plat-omap/include/plat/dmtimer.h | 3 --- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 9b6880a33793..0e17a0d9690b 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -494,9 +494,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) if (timer_dev_attr) pdata->timer_capability = timer_dev_attr->timer_capability; -#ifdef CONFIG_PM - pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; -#endif pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), NULL, 0, 0); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 7aa12785e238..7875eefd0474 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -42,6 +42,7 @@ #include #include +#include #include @@ -342,9 +343,8 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) omap_dm_timer_enable(timer); if (!(timer->capability & OMAP_TIMER_ALWON)) { - u32 ctx_loss_cnt_after = - timer->get_context_loss_count(&timer->pdev->dev); - if (ctx_loss_cnt_after != timer->ctx_loss_count) + if (omap_pm_get_dev_context_loss_count(&timer->pdev->dev) != + timer->ctx_loss_count) omap_timer_restore_context(timer); } @@ -374,10 +374,9 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) __omap_dm_timer_stop(timer, timer->posted, rate); - if (!(timer->capability & OMAP_TIMER_ALWON) && - timer->get_context_loss_count) + if (!(timer->capability & OMAP_TIMER_ALWON)) timer->ctx_loss_count = - timer->get_context_loss_count(&timer->pdev->dev); + omap_pm_get_dev_context_loss_count(&timer->pdev->dev); /* * Since the register values are computed and written within @@ -449,9 +448,8 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, omap_dm_timer_enable(timer); if (!(timer->capability & OMAP_TIMER_ALWON)) { - u32 ctx_loss_cnt_after = - timer->get_context_loss_count(&timer->pdev->dev); - if (ctx_loss_cnt_after != timer->ctx_loss_count) + if (omap_pm_get_dev_context_loss_count(&timer->pdev->dev) != + timer->ctx_loss_count) omap_timer_restore_context(timer); } @@ -693,7 +691,6 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->reserved = omap_dm_timer_reserved_systimer(timer->id); timer->pdev = pdev; - timer->get_context_loss_count = pdata->get_context_loss_count; timer->capability = pdata->timer_capability; /* Skip pm_runtime_enable for OMAP1 */ diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 0a7ed31954ea..e11c9ea7ec53 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -91,7 +91,6 @@ struct timer_regs { struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); u32 needs_manual_reset:1; - int (*get_context_loss_count)(struct device *dev); u32 timer_capability; }; @@ -267,8 +266,6 @@ struct omap_dm_timer { u32 capability; struct platform_device *pdev; struct list_head node; - - int (*get_context_loss_count)(struct device *dev); }; int omap_dm_timer_prepare(struct omap_dm_timer *timer); -- GitLab From 6615975bc58a1234bd401a7ff231dae85631fd58 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:57 -0500 Subject: [PATCH 1580/6849] ARM: OMAP: Add flag to indicate if a timer needs a manual reset For OMAP1 devices, it is necessary to perform a manual reset of the timer. Currently, this is indicating by setting the "needs_manual_reset" variable in the platform data. Instead of using an extra variable to indicate this add a new timer capabilities flag to indicate this and remove the "needs_manual_reset" member from the platform data. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/timer.c | 4 ++-- arch/arm/plat-omap/dmtimer.c | 9 +++------ arch/arm/plat-omap/include/plat/dmtimer.h | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index b4bf48c188fb..aa81593db1af 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -140,8 +140,8 @@ static int __init omap1_dm_timer_init(void) } pdata->set_timer_src = omap1_dm_timer_set_src; - pdata->needs_manual_reset = 1; - pdata->timer_capability = OMAP_TIMER_ALWON; + pdata->timer_capability = OMAP_TIMER_ALWON | + OMAP_TIMER_NEEDS_RESET; ret = platform_device_add_data(pdev, pdata, sizeof(*pdata)); if (ret) { diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 7875eefd0474..e3e22b3dc5c2 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -135,7 +135,6 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) int omap_dm_timer_prepare(struct omap_dm_timer *timer) { - struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; int ret; timer->fclk = clk_get(&timer->pdev->dev, "fck"); @@ -145,7 +144,7 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) return -EINVAL; } - if (pdata->needs_manual_reset) + if (timer->capability & OMAP_TIMER_NEEDS_RESET) omap_dm_timer_reset(timer); ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); @@ -363,13 +362,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start); int omap_dm_timer_stop(struct omap_dm_timer *timer) { unsigned long rate = 0; - struct dmtimer_platform_data *pdata; if (unlikely(!timer)) return -EINVAL; - pdata = timer->pdev->dev.platform_data; - if (!pdata->needs_manual_reset) + if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) rate = clk_get_rate(timer->fclk); __omap_dm_timer_stop(timer, timer->posted, rate); @@ -694,7 +691,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->capability = pdata->timer_capability; /* Skip pm_runtime_enable for OMAP1 */ - if (!pdata->needs_manual_reset) { + if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { pm_runtime_enable(&pdev->dev); pm_runtime_irq_safe(&pdev->dev); } diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index e11c9ea7ec53..c039e84bca7e 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -59,6 +59,7 @@ #define OMAP_TIMER_SECURE 0x80000000 #define OMAP_TIMER_ALWON 0x40000000 #define OMAP_TIMER_HAS_PWM 0x20000000 +#define OMAP_TIMER_NEEDS_RESET 0x10000000 struct omap_timer_capability_dev_attr { u32 timer_capability; @@ -90,7 +91,6 @@ struct timer_regs { struct dmtimer_platform_data { int (*set_timer_src)(struct platform_device *pdev, int source); - u32 needs_manual_reset:1; u32 timer_capability; }; -- GitLab From bca4580845cbffb455d77783fc7e58a94b3904e0 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:58 -0500 Subject: [PATCH 1581/6849] ARM: OMAP1: Fix dmtimer support OMAP1 dmtimer support is currently broken. When a dmtimer is requested by the omap_dm_timer_request() function fails to allocate a dmtimer because the call to clk_get() inside omap_dm_timer_prepare fails. The clk_get() fails simply because the clock data for the OMAP1 dmtimers is not present. Ideally this should be fixed by moving OMAP1 dmtimers to use the clock framework. For now simply fix this by using the "TIMER_NEEDS_RESET" flag to identify an OMAP1 device and avoid calling clk_get(). Although this is not the ideal fix and should be corrected, this flag has already been use for the same purpose in omap_dm_timer_stop(). Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dmtimer.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index e3e22b3dc5c2..6510e5e7b7e3 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -137,11 +137,17 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) { int ret; - timer->fclk = clk_get(&timer->pdev->dev, "fck"); - if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) { - timer->fclk = NULL; - dev_err(&timer->pdev->dev, ": No fclk handle.\n"); - return -EINVAL; + /* + * FIXME: OMAP1 devices do not use the clock framework for dmtimers so + * do not call clk_get() for these devices. + */ + if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { + timer->fclk = clk_get(&timer->pdev->dev, "fck"); + if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) { + timer->fclk = NULL; + dev_err(&timer->pdev->dev, ": No fclk handle.\n"); + return -EINVAL; + } } if (timer->capability & OMAP_TIMER_NEEDS_RESET) -- GitLab From 2b2d35230099613365ad6000f4d71086130b9e71 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:34:59 -0500 Subject: [PATCH 1582/6849] ARM: OMAP2+: Move dmtimer clock set function to dmtimer driver OMAP1 uses an architecture specific function for setting the dmtimer clock source, where as the OMAP2+ devices use the clock framework. Eventually OMAP1 device should also use the clock framework and hence we should not any architecture specific functions. For now move the OMAP2+ function for configuring the clock source into the dmtimer driver. Therefore, we do no longer need to specify an architecture specific function for setting the clock source for OMAP2+ devices. This will simplify device tree migration of the dmtimers for OMAP2+ devices. From now on, only OMAP1 devices should specify an architecture specific function for setting the clock source via the platform data set_dmtimer_src() function pointer. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 55 ----------------------- arch/arm/plat-omap/dmtimer.c | 46 ++++++++++++++++++- arch/arm/plat-omap/include/plat/dmtimer.h | 1 + 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 0e17a0d9690b..8fe75a81e12d 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -389,59 +389,6 @@ static void __init omap4_timer_init(void) OMAP_SYS_TIMER(4) #endif -/** - * omap2_dm_timer_set_src - change the timer input clock source - * @pdev: timer platform device pointer - * @source: array index of parent clock source - */ -static int omap2_dm_timer_set_src(struct platform_device *pdev, int source) -{ - int ret; - struct clk *fclk, *parent; - char *parent_name = NULL; - - fclk = clk_get(&pdev->dev, "fck"); - if (IS_ERR_OR_NULL(fclk)) { - dev_err(&pdev->dev, "%s: %d: clk_get() FAILED\n", - __func__, __LINE__); - return -EINVAL; - } - - switch (source) { - case OMAP_TIMER_SRC_SYS_CLK: - parent_name = "sys_ck"; - break; - - case OMAP_TIMER_SRC_32_KHZ: - parent_name = "32k_ck"; - break; - - case OMAP_TIMER_SRC_EXT_CLK: - parent_name = "alt_ck"; - break; - } - - parent = clk_get(&pdev->dev, parent_name); - if (IS_ERR_OR_NULL(parent)) { - dev_err(&pdev->dev, "%s: %d: clk_get() %s FAILED\n", - __func__, __LINE__, parent_name); - clk_put(fclk); - return -EINVAL; - } - - ret = clk_set_parent(fclk, parent); - if (IS_ERR_VALUE(ret)) { - dev_err(&pdev->dev, "%s: clk_set_parent() to %s FAILED\n", - __func__, parent_name); - ret = -EINVAL; - } - - clk_put(parent); - clk_put(fclk); - - return ret; -} - /** * omap_timer_init - build and register timer device with an * associated timer hwmod @@ -489,8 +436,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) */ sscanf(oh->name, "timer%2d", &id); - pdata->set_timer_src = omap2_dm_timer_set_src; - if (timer_dev_attr) pdata->timer_capability = timer_dev_attr->timer_capability; diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 6510e5e7b7e3..6a7088972c55 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -397,6 +397,8 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop); int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) { int ret; + char *parent_name = NULL; + struct clk *fclk, *parent; struct dmtimer_platform_data *pdata; if (unlikely(!timer)) @@ -407,7 +409,49 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) if (source < 0 || source >= 3) return -EINVAL; - ret = pdata->set_timer_src(timer->pdev, source); + /* + * FIXME: Used for OMAP1 devices only because they do not currently + * use the clock framework to set the parent clock. To be removed + * once OMAP1 migrated to using clock framework for dmtimers + */ + if (pdata->set_timer_src) + return pdata->set_timer_src(timer->pdev, source); + + fclk = clk_get(&timer->pdev->dev, "fck"); + if (IS_ERR_OR_NULL(fclk)) { + pr_err("%s: fck not found\n", __func__); + return -EINVAL; + } + + switch (source) { + case OMAP_TIMER_SRC_SYS_CLK: + parent_name = "sys_ck"; + break; + + case OMAP_TIMER_SRC_32_KHZ: + parent_name = "32k_ck"; + break; + + case OMAP_TIMER_SRC_EXT_CLK: + parent_name = "alt_ck"; + break; + } + + parent = clk_get(&timer->pdev->dev, parent_name); + if (IS_ERR_OR_NULL(parent)) { + pr_err("%s: %s not found\n", __func__, parent_name); + ret = -EINVAL; + goto out; + } + + ret = clk_set_parent(fclk, parent); + if (IS_ERR_VALUE(ret)) + pr_err("%s: failed to set %s as parent\n", __func__, + parent_name); + + clk_put(parent); +out: + clk_put(fclk); return ret; } diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index c039e84bca7e..19e7fa577bd0 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -90,6 +90,7 @@ struct timer_regs { }; struct dmtimer_platform_data { + /* set_timer_src - Only used for OMAP1 devices */ int (*set_timer_src)(struct platform_device *pdev, int source); u32 timer_capability; }; -- GitLab From c59b537d87068be8c357a0150f6172a2dc8cdf82 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 5 Jun 2012 12:35:00 -0500 Subject: [PATCH 1583/6849] ARM: OMAP2+: Simplify dmtimer clock aliases The OMAP dmtimer driver allows you to dynamically configure the functional clock that drives the timer logic. The dmtimer driver uses the device name and a "con-id" string to search for the appropriate functional clock. Currently, we define a clock alias for each functional clock source each timer supports. Some functional clock sources are common to all of the timers on a device and so for these clock sources we can use a single alias with a unique con-id string. The possible functional clock sources for an OMAP device are a 32kHz clock, a system (MHz range) clock and (for OMAP2 only) an external clock. By defining a unique con-id name for each of these (timer_32k_ck, timer_sys_ck and timer_ext_ck) we can eliminate a lot of the clock aliases for timers. This reduces code, speeds-up searches and clock initialisation time. Signed-off-by: Jon Hunter Acked-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock2420_data.c | 39 +++------------------------- arch/arm/mach-omap2/clock2430_data.c | 39 +++------------------------- arch/arm/mach-omap2/clock3xxx_data.c | 26 ++----------------- arch/arm/mach-omap2/clock44xx_data.c | 34 +++++++++--------------- arch/arm/plat-omap/dmtimer.c | 6 ++--- 5 files changed, 23 insertions(+), 121 deletions(-) diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index bace9308a4db..861767ed1a3a 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1901,42 +1901,9 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "pka_ick", &pka_ick, CK_242X), CLK(NULL, "usb_fck", &usb_fck, CK_242X), CLK("musb-hdrc", "fck", &osc_ck, CK_242X), - CLK("omap_timer.1", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.2", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.3", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.4", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.5", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.6", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.7", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.8", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.9", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.10", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.11", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.12", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.1", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.2", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.3", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.4", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.5", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.6", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.7", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.8", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.9", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.10", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.11", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.12", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.1", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.2", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.3", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.4", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.5", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.6", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.7", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.8", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.9", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.10", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.11", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.12", "alt_ck", &alt_ck, CK_243X), + CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_243X), + CLK(NULL, "timer_sys_ck", &sys_ck, CK_243X), + CLK(NULL, "timer_ext_ck", &alt_ck, CK_243X), }; /* diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 3b4d09a50399..5577810dbc26 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -2000,42 +2000,9 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X), CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X), CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X), - CLK("omap_timer.1", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.2", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.3", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.4", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.5", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.6", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.7", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.8", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.9", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.10", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.11", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.12", "32k_ck", &func_32k_ck, CK_243X), - CLK("omap_timer.1", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.2", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.3", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.4", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.5", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.6", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.7", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.8", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.9", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.10", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.11", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.12", "sys_ck", &sys_ck, CK_243X), - CLK("omap_timer.1", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.2", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.3", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.4", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.5", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.6", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.7", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.8", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.9", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.10", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.11", "alt_ck", &alt_ck, CK_243X), - CLK("omap_timer.12", "alt_ck", &alt_ck, CK_243X), + CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_243X), + CLK(NULL, "timer_sys_ck", &sys_ck, CK_243X), + CLK(NULL, "timer_ext_ck", &alt_ck, CK_243X), }; /* diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 4e1a3b0e8cc8..64b2b1fafddd 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3482,30 +3482,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK("musb-am35x", "fck", &hsotgusb_fck_am35xx, CK_AM35XX), CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX), CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX), - CLK("omap_timer.1", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.2", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.3", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.4", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.5", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.6", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.7", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.8", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.9", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.10", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.11", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.12", "32k_ck", &omap_32k_fck, CK_3XXX), - CLK("omap_timer.1", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.2", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.3", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.4", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.5", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.6", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.7", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.8", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.9", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.10", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.11", "sys_ck", &sys_ck, CK_3XXX), - CLK("omap_timer.12", "sys_ck", &sys_ck, CK_3XXX), + CLK(NULL, "timer_32k_ck", &omap_32k_fck, CK_3XXX), + CLK(NULL, "timer_sys_ck", &sys_ck, CK_3XXX), }; diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 2172f6603848..51f7424c7caa 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -3380,28 +3380,18 @@ static struct omap_clk omap44xx_clks[] = { CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X), CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X), CLK("omap_wdt", "ick", &dummy_ck, CK_443X), - CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.3", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.4", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.5", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.6", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.7", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.8", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.9", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.10", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.11", "32k_ck", &sys_32k_ck, CK_443X), - CLK("omap_timer.1", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.2", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.3", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.4", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.9", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.10", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.11", "sys_ck", &sys_clkin_ck, CK_443X), - CLK("omap_timer.5", "sys_ck", &syc_clk_div_ck, CK_443X), - CLK("omap_timer.6", "sys_ck", &syc_clk_div_ck, CK_443X), - CLK("omap_timer.7", "sys_ck", &syc_clk_div_ck, CK_443X), - CLK("omap_timer.8", "sys_ck", &syc_clk_div_ck, CK_443X), + CLK(NULL, "timer_32k_ck", &sys_32k_ck, CK_443X), + CLK("omap_timer.1", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.2", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.3", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.4", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.9", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.10", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.11", "timer_sys_ck", &sys_clkin_ck, CK_443X), + CLK("omap_timer.5", "timer_sys_ck", &syc_clk_div_ck, CK_443X), + CLK("omap_timer.6", "timer_sys_ck", &syc_clk_div_ck, CK_443X), + CLK("omap_timer.7", "timer_sys_ck", &syc_clk_div_ck, CK_443X), + CLK("omap_timer.8", "timer_sys_ck", &syc_clk_div_ck, CK_443X), }; int __init omap4xxx_clk_init(void) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 6a7088972c55..54ed4e6e429e 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -425,15 +425,15 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) switch (source) { case OMAP_TIMER_SRC_SYS_CLK: - parent_name = "sys_ck"; + parent_name = "timer_sys_ck"; break; case OMAP_TIMER_SRC_32_KHZ: - parent_name = "32k_ck"; + parent_name = "timer_32k_ck"; break; case OMAP_TIMER_SRC_EXT_CLK: - parent_name = "alt_ck"; + parent_name = "timer_ext_ck"; break; } -- GitLab From 185095fb80ce57c0f3db8738e36ad7c02dc34d33 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 7 Jun 2012 02:23:37 +0000 Subject: [PATCH 1584/6849] e1000e: use more informative logging macros when netdev not yet registered Based on a report from Ethan Zhao, before calling register_netdev() the driver should be using logging macros that do not display the potentially confusing "(unregistered net_device)" yet still display the useful driver name and PCI bus/device/function. Reported-by: Ethan Zhao Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 11 ++++-- drivers/net/ethernet/intel/e1000e/param.c | 43 ++++++++++++++-------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 31d37a2b5ba8..ba86b3f8a404 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6238,7 +6238,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) - e_info("PHY reset is blocked due to SOL/IDER session.\n"); + dev_info(&pdev->dev, + "PHY reset is blocked due to SOL/IDER session.\n"); /* Set initial default active device features */ netdev->features = (NETIF_F_SG | @@ -6288,7 +6289,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (e1000_validate_nvm_checksum(&adapter->hw) >= 0) break; if (i == 2) { - e_err("The NVM Checksum Is Not Valid\n"); + dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); err = -EIO; goto err_eeprom; } @@ -6298,13 +6299,15 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* copy the MAC address */ if (e1000e_read_mac_addr(&adapter->hw)) - e_err("NVM Read Error while reading MAC address\n"); + dev_err(&pdev->dev, + "NVM Read Error while reading MAC address\n"); memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->perm_addr)) { - e_err("Invalid MAC Address: %pM\n", netdev->perm_addr); + dev_err(&pdev->dev, "Invalid MAC Address: %pM\n", + netdev->perm_addr); err = -EIO; goto err_eeprom; } diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 55cc1565bc2f..dfbfa7fd98c3 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -199,16 +199,19 @@ static int __devinit e1000_validate_option(unsigned int *value, case enable_option: switch (*value) { case OPTION_ENABLED: - e_info("%s Enabled\n", opt->name); + dev_info(&adapter->pdev->dev, "%s Enabled\n", + opt->name); return 0; case OPTION_DISABLED: - e_info("%s Disabled\n", opt->name); + dev_info(&adapter->pdev->dev, "%s Disabled\n", + opt->name); return 0; } break; case range_option: if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - e_info("%s set to %i\n", opt->name, *value); + dev_info(&adapter->pdev->dev, "%s set to %i\n", + opt->name, *value); return 0; } break; @@ -220,7 +223,8 @@ static int __devinit e1000_validate_option(unsigned int *value, ent = &opt->arg.l.p[i]; if (*value == ent->i) { if (ent->str[0] != '\0') - e_info("%s\n", ent->str); + dev_info(&adapter->pdev->dev, "%s\n", + ent->str); return 0; } } @@ -230,8 +234,8 @@ static int __devinit e1000_validate_option(unsigned int *value, BUG(); } - e_info("Invalid %s value specified (%i) %s\n", opt->name, *value, - opt->err); + dev_info(&adapter->pdev->dev, "Invalid %s value specified (%i) %s\n", + opt->name, *value, opt->err); *value = opt->def; return -1; } @@ -251,8 +255,10 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) int bd = adapter->bd_number; if (bd >= E1000_MAX_NIC) { - e_notice("Warning: no configuration for board #%i\n", bd); - e_notice("Using defaults for all values\n"); + dev_notice(&adapter->pdev->dev, + "Warning: no configuration for board #%i\n", bd); + dev_notice(&adapter->pdev->dev, + "Using defaults for all values\n"); } { /* Transmit Interrupt Delay */ @@ -366,27 +372,32 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) * default values */ if (adapter->itr > 4) - e_info("%s set to default %d\n", opt.name, - adapter->itr); + dev_info(&adapter->pdev->dev, + "%s set to default %d\n", opt.name, + adapter->itr); } adapter->itr_setting = adapter->itr; switch (adapter->itr) { case 0: - e_info("%s turned off\n", opt.name); + dev_info(&adapter->pdev->dev, "%s turned off\n", + opt.name); break; case 1: - e_info("%s set to dynamic mode\n", opt.name); + dev_info(&adapter->pdev->dev, + "%s set to dynamic mode\n", opt.name); adapter->itr = 20000; break; case 3: - e_info("%s set to dynamic conservative mode\n", - opt.name); + dev_info(&adapter->pdev->dev, + "%s set to dynamic conservative mode\n", + opt.name); adapter->itr = 20000; break; case 4: - e_info("%s set to simplified (2000-8000 ints) mode\n", - opt.name); + dev_info(&adapter->pdev->dev, + "%s set to simplified (2000-8000 ints) mode\n", + opt.name); break; default: /* -- GitLab From 4f8a91ad9aafbc7c70097a16404fa89aa41c8deb Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 28 Mar 2012 11:42:45 +0000 Subject: [PATCH 1585/6849] ixgbe: align flow control DV macros with datasheet The flow control DV macros are used to calculate the flow control high and low thresholds. This patch annotates these macros slightly better and fixes the issues below. The macro variables are renamed LINK to _max_frame_link and TC to _max_frame_tc. This was to avoid confusion and make them more readable. It was found that people auditing the code read TC to be 'traffic class' in the 802.1Q definition instead of the max frame size of the tc. Hopefully it is clear now. This audit also found the following real deviations from the theoretical values. Fixed in this patch. * I multiplied the DV calculations by (36/25) which always evaluates to 1. This does not match the intended theoretical value of 1.44. * IXGBE_BT2KB added 1023 to account for rounding however this really should be 8 * 1023 - 1 to account for division by 8k. * x2 multiplication of max frame in DV calculations to account for updated hardware recommendations. With this patch the DV values are inline with the recommendations in the 82599 and 82598 data sheets. Its worth noting I did not see any dropped frames with flow control on in my experiments without this patch. However aligning with the hardware specs and recommendations seems like a good idea here to account for worst case scenarios. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 204848d2448c..1085c0739a3c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -2419,7 +2419,7 @@ typedef u32 ixgbe_physical_layer; */ /* BitTimes (BT) conversion */ -#define IXGBE_BT2KB(BT) ((BT + 1023) / (8 * 1024)) +#define IXGBE_BT2KB(BT) ((BT + (8 * 1024 - 1)) / (8 * 1024)) #define IXGBE_B2BT(BT) (BT * 8) /* Calculate Delay to respond to PFC */ @@ -2450,24 +2450,31 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PCI_DELAY 10000 /* Calculate X540 delay value in bit times */ -#define IXGBE_FILL_RATE (36 / 25) - -#define IXGBE_DV_X540(LINK, TC) (IXGBE_FILL_RATE * \ - (IXGBE_B2BT(LINK) + IXGBE_PFC_D + \ - (2 * IXGBE_CABLE_DC) + \ - (2 * IXGBE_ID_X540) + \ - IXGBE_HD + IXGBE_B2BT(TC))) +#define IXGBE_DV_X540(_max_frame_link, _max_frame_tc) \ + ((36 * \ + (IXGBE_B2BT(_max_frame_link) + \ + IXGBE_PFC_D + \ + (2 * IXGBE_CABLE_DC) + \ + (2 * IXGBE_ID_X540) + \ + IXGBE_HD) / 25 + 1) + \ + 2 * IXGBE_B2BT(_max_frame_tc)) /* Calculate 82599, 82598 delay value in bit times */ -#define IXGBE_DV(LINK, TC) (IXGBE_FILL_RATE * \ - (IXGBE_B2BT(LINK) + IXGBE_PFC_D + \ - (2 * IXGBE_CABLE_DC) + (2 * IXGBE_ID) + \ - IXGBE_HD + IXGBE_B2BT(TC))) +#define IXGBE_DV(_max_frame_link, _max_frame_tc) \ + ((36 * \ + (IXGBE_B2BT(_max_frame_link) + \ + IXGBE_PFC_D + \ + (2 * IXGBE_CABLE_DC) + \ + (2 * IXGBE_ID) + \ + IXGBE_HD) / 25 + 1) + \ + 2 * IXGBE_B2BT(_max_frame_tc)) /* Calculate low threshold delay values */ -#define IXGBE_LOW_DV_X540(TC) (2 * IXGBE_B2BT(TC) + \ - (IXGBE_FILL_RATE * IXGBE_PCI_DELAY)) -#define IXGBE_LOW_DV(TC) (2 * IXGBE_LOW_DV_X540(TC)) +#define IXGBE_LOW_DV_X540(_max_frame_tc) \ + (2 * IXGBE_B2BT(_max_frame_tc) + \ + (36 * IXGBE_PCI_DELAY / 25) + 1) +#define IXGBE_LOW_DV(_max_frame_tc) \ + (2 * IXGBE_LOW_DV_X540(_max_frame_tc)) /* Software ATR hash keys */ #define IXGBE_ATR_BUCKET_HASH_KEY 0x3DAD14E2 -- GitLab From 6cbc52ef10ba3c7fbd8954270c025ffbf643ab05 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 16 May 2012 07:06:38 +0000 Subject: [PATCH 1586/6849] ixgbe: do not compile ixgbe_sysfs.c when CONFIG_IXGBE_HWMON is not set ixgbe_sysfs.c is only needed when CONFIG_IXGBE_HWMON is configured in the kernel. Signed-off-by: Emil Tantilov Acked-by: Don Skidmore Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/Makefile | 4 ++-- drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile index 0bdf06bc5c49..5fd5d04c26c9 100644 --- a/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/drivers/net/ethernet/intel/ixgbe/Makefile @@ -34,11 +34,11 @@ obj-$(CONFIG_IXGBE) += ixgbe.o ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ - ixgbe_mbx.o ixgbe_x540.o ixgbe_sysfs.o ixgbe_lib.o + ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe_dcb_82599.o ixgbe_dcb_nl.o ixgbe-$(CONFIG_IXGBE_PTP) += ixgbe_ptp.o - +ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c index 1d80b1cefa6a..2334fce47018 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c @@ -37,7 +37,6 @@ #include #include -#ifdef CONFIG_IXGBE_HWMON /* hwmon callback functions */ static ssize_t ixgbe_hwmon_show_location(struct device *dev, struct device_attribute *attr, @@ -241,5 +240,4 @@ err: exit: return rc; } -#endif /* CONFIG_IXGBE_HWMON */ -- GitLab From 0ede4a606af1778b24b84b7feed3c0bed2751a34 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Tue, 22 May 2012 06:08:32 +0000 Subject: [PATCH 1587/6849] ixgbe: ptp code cleanup This patch fixes two minor nits from Richard Cochran. The first is a case of ambitious line wrapping that wasn't necessary. The second is to re-order the flag checks for PPS support. Previously, the hardware test was done first, and the interrupt flag test was done second. Now, test the interrupt flag and use the unlikely macro. Signed-off-by: Jacob Keller Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 +++----- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 13 +++++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 17ad6a3c1be1..1675b662da06 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -790,12 +790,10 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, total_packets += tx_buffer->gso_segs; #ifdef CONFIG_IXGBE_PTP - if (unlikely(tx_buffer->tx_flags & - IXGBE_TX_FLAGS_TSTAMP)) - ixgbe_ptp_tx_hwtstamp(q_vector, - tx_buffer->skb); - + if (unlikely(tx_buffer->tx_flags & IXGBE_TX_FLAGS_TSTAMP)) + ixgbe_ptp_tx_hwtstamp(q_vector, tx_buffer->skb); #endif + /* free the skb */ dev_kfree_skb_any(tx_buffer->skb); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index ddc6a4d19302..174f41fd1d2f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -307,13 +307,14 @@ void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) return; - switch (hw->mac.type) { - case ixgbe_mac_X540: - if (eicr & IXGBE_EICR_TIMESYNC) + if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) { + switch (hw->mac.type) { + case ixgbe_mac_X540: ptp_clock_event(adapter->ptp_clock, &event); - break; - default: - break; + break; + default: + break; + } } } -- GitLab From c19197a7866fee6ff9985d9dc9962bc2ccbd3d7b Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Tue, 22 May 2012 06:08:37 +0000 Subject: [PATCH 1588/6849] ixgbe: PTP Fix hwtstamp mode settings When enabling the hwtstamp mode for Rx timestamping the V2 ptp event type specific modes (Delay Request and Sync) have been rolled into the V2 all event packet modes, in order to more accurately represent what hardware is doing. Hardware always timestamps the Path delay packets when a V2 mode is selected, regardless of what type was selected (in order to always support Path delay mode). However this means the user selected modes of timestamping only Sync or Delay Request is not truly supported. This patch correctly sets the mode for the hwtstamp config and returns to the user that all V2 event packets will be timestamped. Signed-off-by: Jacob Keller Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 23 +++++++------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 174f41fd1d2f..5ed8cffee178 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -540,6 +540,11 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, * type has to be specified. Matching the kind of event packet is * not supported, with the exception of "all V2 events regardless of * level 2 or 4". + * + * Since hardware always timestamps Path delay packets when timestamping V2 + * packets, regardless of the type specified in the register, only use V2 + * Event mode. This more accurately tells the user what the hardware is going + * to do anyways. */ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, struct ifreq *ifr, int cmd) @@ -583,27 +588,15 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG; is_l4 = true; break; + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_mtrl = IXGBE_RXMTRL_V2_SYNC_MSG; - is_l2 = true; - is_l4 = true; - config.rx_filter = HWTSTAMP_FILTER_SOME; - break; case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_mtrl = IXGBE_RXMTRL_V2_DELAY_REQ_MSG; - is_l2 = true; - is_l4 = true; - config.rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_EVENT: tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; is_l2 = true; -- GitLab From 1d1a79b5b94b0aa84e1e78dd9acdcffb12274848 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Tue, 22 May 2012 06:18:08 +0000 Subject: [PATCH 1589/6849] ixgbe: Check PTP Rx timestamps via BPF filter This patch fixes a potential Rx timestamp deadlock that causes the Rx timestamping to stall indefinitely. The issue could occur when a PTP packet is timestamped by hardware but never reaches the Rx queue. In order to prevent a permanent loss of timestamping, the RXSTMP(L/H) registers have to be read to unlock them. (This used to only occur when a packet that was timestamped reached the software.) However the registers can't be read early otherwise there is no way to correlate them to the packet. This patch introduces a filter function which can be used to determine if a packet should have been timestamped. Supplied with the filter setup by the hwtstamp ioctl, check to make sure the PTP protocol and message type match the expected values. If so, then read the timestamp registers (to free them.) At this point check the descriptor bit, if the bit is set then we know this packet correlates to the timestamp stored in the RXTSTAMP registers. Otherwise, assume that packet was dropped by the hardware, and ignore this timestamp value. However, we have at least unlocked the rxtstamp registers for future timestamping. Due to the way the driver handles skb data, it cannot be directly accessed. In order to work around this, a copy of the skb data into a linear buffer is made. From this buffer it becomes possible to read the data correctly Signed-off-by: Jacob Keller Reviewed-by: Richard Cochran Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 113 ++++++++++++++++-- 3 files changed, 104 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 3ef3c5284e52..41f9f6e2a4c1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -561,6 +561,7 @@ struct ixgbe_adapter { spinlock_t tmreg_lock; struct cyclecounter cc; struct timecounter tc; + int rx_hwtstamp_filter; u32 base_incval; u32 cycle_speed; #endif /* CONFIG_IXGBE_PTP */ @@ -718,6 +719,7 @@ extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, struct sk_buff *skb); extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, + union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb); extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, struct ifreq *ifr, int cmd); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1675b662da06..b0ddfd47e473 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1397,8 +1397,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, ixgbe_rx_checksum(rx_ring, rx_desc, skb); #ifdef CONFIG_IXGBE_PTP - if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)) - ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); + ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb); #endif if ((dev->features & NETIF_F_HW_VLAN_RX) && diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 5ed8cffee178..cb7d1b2982c5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -26,6 +26,7 @@ *******************************************************************************/ #include "ixgbe.h" #include +#include /* * The 82599 and the X540 do not have true 64bit nanosecond scale @@ -100,6 +101,10 @@ #define NSECS_PER_SEC 1000000000ULL #endif +static struct sock_filter ptp_filter[] = { + PTP_FILTER +}; + /** * ixgbe_ptp_read - read raw cycle counter (to be used by time counter) * @cc - the cyclecounter structure @@ -425,6 +430,68 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) } } +/** + * ixgbe_ptp_match - determine if this skb matches a ptp packet + * @skb: pointer to the skb + * @hwtstamp: pointer to the hwtstamp_config to check + * + * Determine whether the skb should have been timestamped, assuming the + * hwtstamp was set via the hwtstamp ioctl. Returns non-zero when the packet + * should have a timestamp waiting in the registers, and 0 otherwise. + * + * V1 packets have to check the version type to determine whether they are + * correct. However, we can't directly access the data because it might be + * fragmented in the SKB, in paged memory. In order to work around this, we + * use skb_copy_bits which will properly copy the data whether it is in the + * paged memory fragments or not. We have to copy the IP header as well as the + * message type. + */ +static int ixgbe_ptp_match(struct sk_buff *skb, int rx_filter) +{ + struct iphdr iph; + u8 msgtype; + unsigned int type, offset; + + if (rx_filter == HWTSTAMP_FILTER_NONE) + return 0; + + type = sk_run_filter(skb, ptp_filter); + + if (likely(rx_filter == HWTSTAMP_FILTER_PTP_V2_EVENT)) + return type & PTP_CLASS_V2; + + /* For the remaining cases actually check message type */ + switch (type) { + case PTP_CLASS_V1_IPV4: + skb_copy_bits(skb, OFF_IHL, &iph, sizeof(iph)); + offset = ETH_HLEN + (iph.ihl << 2) + UDP_HLEN + OFF_PTP_CONTROL; + break; + case PTP_CLASS_V1_IPV6: + offset = OFF_PTP6 + OFF_PTP_CONTROL; + break; + default: + /* other cases invalid or handled above */ + return 0; + } + + /* Make sure our buffer is long enough */ + if (skb->len < offset) + return 0; + + skb_copy_bits(skb, offset, &msgtype, sizeof(msgtype)); + + switch (rx_filter) { + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + return (msgtype == IXGBE_RXMTRL_V1_SYNC_MSG); + break; + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + return (msgtype == IXGBE_RXMTRL_V1_DELAY_REQ_MSG); + break; + default: + return 0; + } +} + /** * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp * @q_vector: structure containing interrupt and ring information @@ -474,6 +541,7 @@ void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, /** * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp * @q_vector: structure containing interrupt and ring information + * @rx_desc: the rx descriptor * @skb: particular skb to send timestamp with * * if the timestamp is valid, we convert it into the timecounter ns @@ -481,6 +549,7 @@ void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, * is passed up the network stack */ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, + union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) { struct ixgbe_adapter *adapter; @@ -498,21 +567,33 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, hw = &adapter->hw; tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + + /* Check if we have a valid timestamp and make sure the skb should + * have been timestamped */ + if (likely(!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID) || + !ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter))) + return; + + /* + * Always read the registers, in order to clear a possible fault + * because of stagnant RX timestamp values for a packet that never + * reached the queue. + */ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; /* - * If this bit is set, then the RX registers contain the time stamp. No - * other packet will be time stamped until we read these registers, so - * read the registers to make them available again. Because only one - * packet can be time stamped at a time, we know that the register - * values must belong to this one here and therefore we don't need to - * compare any of the additional attributes stored for it. + * If the timestamp bit is set in the packet's descriptor, we know the + * timestamp belongs to this packet. No other packet can be + * timestamped until the registers for timestamping have been read. + * Therefor only one packet with this bit can be in the queue at a + * time, and the rx timestamp values that were in the registers belong + * to this packet. * * If nothing went wrong, then it should have a skb_shared_tx that we * can turn into a skb_shared_hwtstamps. */ - if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) + if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) return; spin_lock_irqsave(&adapter->tmreg_lock, flags); @@ -598,19 +679,20 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; is_l2 = true; is_l4 = true; + config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; break; case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_ALL: default: /* - * register RXMTRL must be set, therefore it is not - * possible to time stamp both V1 Sync and Delay_Req messages - * and hardware does not support timestamping all packets - * => return error + * register RXMTRL must be set in order to do V1 packets, + * therefore it is not possible to time stamp both V1 Sync and + * Delay_Req messages and hardware does not support + * timestamping all packets => return error */ + config.rx_filter = HWTSTAMP_FILTER_NONE; return -ERANGE; } @@ -620,6 +702,9 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, return 0; } + /* Store filter value for later use */ + adapter->rx_hwtstamp_filter = config.rx_filter; + /* define ethertype filter for timestamped packets */ if (is_l2) IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), @@ -855,6 +940,10 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) return; } + /* initialize the ptp filter */ + if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) + e_dev_warn("ptp_filter_init failed\n"); + spin_lock_init(&adapter->tmreg_lock); ixgbe_ptp_start_cyclecounter(adapter); -- GitLab From 6b03b13336ee5d8da7bda8799c9ed990e3daedcc Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Jun 2012 13:24:42 +0300 Subject: [PATCH 1590/6849] usb: otg: twl: add missing IRQF_ONESHOT this patch fixes the following warning: [ 2.825378] genirq: Threaded irq requested \ with handler=NULL and !ONESHOT for irq 363 Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl4030-usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index c4a86da858e2..02979306bf83 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -651,8 +651,8 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) */ twl->irq_enabled = true; status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "twl4030_usb", twl); + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | + IRQF_ONESHOT, "twl4030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); -- GitLab From c35f77417ebfc7c21c02aa9c8c30aa4cecf331d6 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 11 Jun 2012 12:56:45 +0300 Subject: [PATCH 1591/6849] x86: Define early read-mostly per-cpu macros Some read-mostly per-cpu data may need to be declared or defined early, so it can be initialized and accessed before per_cpu areas are allocated. Only the data that resides in the per_cpu areas should be read-mostly, as there is little benefit in optimizing cache lines on initialization. Signed-off-by: Ido Yariv [ Added the missing declarations in !SMP code. ] Signed-off-by: Vlad Zolotarov Acked-by: Shai Fultheim Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/46188571.ddB8aVQYWo@vlad Signed-off-by: Ingo Molnar --- arch/x86/include/asm/percpu.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index d9b8e3f7f42a..1104afaba52b 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -551,6 +551,12 @@ DECLARE_PER_CPU(unsigned long, this_cpu_off); { [0 ... NR_CPUS-1] = _initvalue }; \ __typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map +#define DEFINE_EARLY_PER_CPU_READ_MOSTLY(_type, _name, _initvalue) \ + DEFINE_PER_CPU_READ_MOSTLY(_type, _name) = _initvalue; \ + __typeof__(_type) _name##_early_map[NR_CPUS] __initdata = \ + { [0 ... NR_CPUS-1] = _initvalue }; \ + __typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map + #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \ EXPORT_PER_CPU_SYMBOL(_name) @@ -559,6 +565,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_off); extern __typeof__(_type) *_name##_early_ptr; \ extern __typeof__(_type) _name##_early_map[] +#define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \ + DECLARE_PER_CPU_READ_MOSTLY(_type, _name); \ + extern __typeof__(_type) *_name##_early_ptr; \ + extern __typeof__(_type) _name##_early_map[] + #define early_per_cpu_ptr(_name) (_name##_early_ptr) #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) #define early_per_cpu(_name, _cpu) \ @@ -570,12 +581,18 @@ DECLARE_PER_CPU(unsigned long, this_cpu_off); #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ DEFINE_PER_CPU(_type, _name) = _initvalue +#define DEFINE_EARLY_PER_CPU_READ_MOSTLY(_type, _name, _initvalue) \ + DEFINE_PER_CPU_READ_MOSTLY(_type, _name) = _initvalue + #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \ EXPORT_PER_CPU_SYMBOL(_name) #define DECLARE_EARLY_PER_CPU(_type, _name) \ DECLARE_PER_CPU(_type, _name) +#define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \ + DECLARE_PER_CPU_READ_MOSTLY(_type, _name) + #define early_per_cpu(_name, _cpu) per_cpu(_name, _cpu) #define early_per_cpu_ptr(_name) NULL /* no early_per_cpu_map() */ -- GitLab From 0816b0f0365539c8f6280634d2c1778d0108d8f5 Mon Sep 17 00:00:00 2001 From: Vlad Zolotarov Date: Mon, 11 Jun 2012 12:56:52 +0300 Subject: [PATCH 1592/6849] x86: Add read_mostly declaration/definition to variables from smp.h Add "read-mostly" qualifier to the following variables in smp.h: - cpu_sibling_map - cpu_core_map - cpu_llc_shared_map - cpu_llc_id - cpu_number - x86_cpu_to_apicid - x86_bios_cpu_apicid - x86_cpu_to_logical_apicid As long as all the variables above are only written during the initialization, this change is meant to prevent the false sharing. More specifically, on vSMP Foundation platform x86_cpu_to_apicid shared the same internode_cache_line with frequently written lapic_events. From the analysis of the first 33 per_cpu variables out of 219 (memories they describe, to be more specific) the 8 have read_mostly nature (tlb_vector_offset, cpu_loops_per_jiffy, xen_debug_irq, etc.) and 25 are frequently written (irq_stack_union, gdt_page, exception_stacks, idt_desc, etc.). Assuming that the spread of the rest of the per_cpu variables is similar, identifying the read mostly memories will make more sense in terms of long-term code maintenance comparing to identifying frequently written memories. Signed-off-by: Vlad Zolotarov Acked-by: Shai Fultheim Cc: Shai Fultheim (Shai@ScaleMP.com) Cc: ido@wizery.com Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1719258.EYKzE4Zbq5@vlad Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/smp.h | 16 ++++++++-------- arch/x86/kernel/apic/apic.c | 6 +++--- arch/x86/kernel/setup_percpu.c | 2 +- arch/x86/kernel/smpboot.c | 8 ++++---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index eaff4790ed96..a907d4d251a8 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -537,7 +537,7 @@ static inline const struct cpumask *default_target_cpus(void) #endif } -DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); +DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid); static inline unsigned int read_apic_id(void) diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index f48394513c37..cc1df2b5cc65 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -31,12 +31,12 @@ static inline bool cpu_has_ht_siblings(void) return has_siblings; } -DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map); -DECLARE_PER_CPU(cpumask_var_t, cpu_core_map); +DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); +DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); /* cpus sharing the last level cache: */ -DECLARE_PER_CPU(cpumask_var_t, cpu_llc_shared_map); -DECLARE_PER_CPU(u16, cpu_llc_id); -DECLARE_PER_CPU(int, cpu_number); +DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); +DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id); +DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number); static inline struct cpumask *cpu_sibling_mask(int cpu) { @@ -53,10 +53,10 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu) return per_cpu(cpu_llc_shared_map, cpu); } -DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid); -DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); +DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid); +DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid); #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) -DECLARE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid); +DECLARE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid); #endif /* Static state in head.S used to set up a CPU */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 39a222e094af..0443b6482214 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -75,8 +75,8 @@ physid_mask_t phys_cpu_present_map; /* * Map cpu index to physical APIC ID */ -DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); -DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); +DEFINE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid, BAD_APICID); +DEFINE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid, BAD_APICID); EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); @@ -88,7 +88,7 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); * used for the mapping. This is where the behaviors of x86_64 and 32 * actually diverge. Let's keep it ugly for now. */ -DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID); +DEFINE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid, BAD_APICID); /* * Knob to control our willingness to enable the local APIC. diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 5a98aa272184..5cdff0357746 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -21,7 +21,7 @@ #include #include -DEFINE_PER_CPU(int, cpu_number); +DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number); EXPORT_PER_CPU_SYMBOL(cpu_number); #ifdef CONFIG_X86_64 diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 3fab55bea29b..e61110e29a8c 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -104,17 +104,17 @@ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); /* Last level cache ID of each logical CPU */ -DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID; +DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id) = BAD_APICID; /* representing HT siblings of each logical CPU */ -DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); /* representing HT and core siblings of each logical CPU */ -DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); EXPORT_PER_CPU_SYMBOL(cpu_core_map); -DEFINE_PER_CPU(cpumask_var_t, cpu_llc_shared_map); +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); /* Per CPU bogomips and other parameters */ DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); -- GitLab From cac4afbc3da58d9e5701b34bd4c1f11ea13328d4 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 14 Jun 2012 12:39:34 +0200 Subject: [PATCH 1593/6849] x86/x2apic/cluster: Vector_allocation_domain() should return a value Since commit 8637e38 ("x86/apic: Avoid useless scanning thru a cpumask in assign_irq_vector()") vector_allocation_domain() operation indicates if a cpumask is dynamic or static. This update fixes the oversight and makes the operation to return a value. Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120614103933.GJ3383@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 23a46cf5b6fd..1885a73b7f33 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -228,10 +228,11 @@ static int x2apic_cluster_probe(void) /* * Each x2apic cluster is an allocation domain. */ -static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask) +static bool cluster_vector_allocation_domain(int cpu, struct cpumask *retmask) { cpumask_clear(retmask); cpumask_copy(retmask, per_cpu(cpus_in_cluster, cpu)); + return true; } static struct apic apic_x2apic_cluster = { -- GitLab From a5a391561bc25898ba1a702a0c4b028aa5b11ce9 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 14 Jun 2012 09:49:35 +0200 Subject: [PATCH 1594/6849] x86/apic: Eliminate cpu_mask_to_apicid() operation Since there are only two locations where cpu_mask_to_apicid() is called from, remove the operation and use only cpu_mask_to_apicid_and() instead. Signed-off-by: Alexander Gordeev Suggested-and-acked-by: Suresh Siddha Acked-by: Yinghai Lu Link: http://lkml.kernel.org/r/20120614074935.GE3383@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 33 +++++++-------------------- arch/x86/kernel/apic/apic.c | 24 +++++-------------- arch/x86/kernel/apic/apic_flat_64.c | 2 -- arch/x86/kernel/apic/apic_noop.c | 1 - arch/x86/kernel/apic/apic_numachip.c | 1 - arch/x86/kernel/apic/bigsmp_32.c | 1 - arch/x86/kernel/apic/es7000_32.c | 4 +--- arch/x86/kernel/apic/io_apic.c | 3 ++- arch/x86/kernel/apic/numaq_32.c | 8 ------- arch/x86/kernel/apic/probe_32.c | 1 - arch/x86/kernel/apic/summit_32.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 17 -------------- arch/x86/kernel/apic/x2apic_phys.c | 1 - arch/x86/kernel/apic/x2apic_uv_x.c | 29 +++++------------------ arch/x86/platform/uv/uv_irq.c | 2 +- 15 files changed, 25 insertions(+), 105 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 1ed3eead2039..eec240e12091 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -331,8 +331,6 @@ struct apic { unsigned long (*set_apic_id)(unsigned int id); unsigned long apic_id_mask; - int (*cpu_mask_to_apicid)(const struct cpumask *cpumask, - unsigned int *apicid); int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, const struct cpumask *andmask, unsigned int *apicid); @@ -594,9 +592,15 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) #endif static inline int -__flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid) +flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask, + unsigned int *apicid) { - cpu_mask = cpu_mask & APIC_ALL_CPUS & cpumask_bits(cpu_online_mask)[0]; + unsigned long cpu_mask = cpumask_bits(cpumask)[0] & + cpumask_bits(andmask)[0] & + cpumask_bits(cpu_online_mask)[0] & + APIC_ALL_CPUS; + if (likely(cpu_mask)) { *apicid = (unsigned int)cpu_mask; return 0; @@ -605,27 +609,6 @@ __flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid) } } -static inline int -flat_cpu_mask_to_apicid(const struct cpumask *cpumask, - unsigned int *apicid) -{ - return __flat_cpu_mask_to_apicid(cpumask_bits(cpumask)[0], apicid); -} - -static inline int -flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask, - unsigned int *apicid) -{ - unsigned long mask1 = cpumask_bits(cpumask)[0]; - unsigned long mask2 = cpumask_bits(andmask)[0]; - return __flat_cpu_mask_to_apicid(mask1 & mask2, apicid); -} - -extern int -default_cpu_mask_to_apicid(const struct cpumask *cpumask, - unsigned int *apicid); - extern int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 7e9bbe73bc5a..048a4f806d46 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2123,23 +2123,6 @@ void default_init_apic_ldr(void) apic_write(APIC_LDR, val); } -static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid) -{ - if (likely((unsigned int)cpu < nr_cpu_ids)) { - *apicid = per_cpu(x86_cpu_to_apicid, cpu); - return 0; - } else { - return -EINVAL; - } -} - -int default_cpu_mask_to_apicid(const struct cpumask *cpumask, - unsigned int *apicid) -{ - int cpu = cpumask_first_and(cpumask, cpu_online_mask); - return __default_cpu_to_apicid(cpu, apicid); -} - int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, unsigned int *apicid) @@ -2151,7 +2134,12 @@ int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, break; } - return __default_cpu_to_apicid(cpu, apicid); + if (likely((unsigned int)cpu < nr_cpu_ids)) { + *apicid = per_cpu(x86_cpu_to_apicid, cpu); + return 0; + } else { + return -EINVAL; + } } /* diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index bddc92566d0a..00c77cf78e9e 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -191,7 +191,6 @@ static struct apic apic_flat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = flat_send_IPI_mask, @@ -308,7 +307,6 @@ static struct apic apic_physflat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = physflat_send_IPI_mask, diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index ac9edf247b15..65c07fc630a1 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -159,7 +159,6 @@ struct apic apic_noop = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = noop_send_IPI_mask, diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index c028132ad358..bc552cff2578 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -234,7 +234,6 @@ static struct apic apic_numachip __refconst = { .set_apic_id = set_apic_id, .apic_id_mask = 0xffU << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = numachip_send_IPI_mask, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index df342fe4d6aa..d50e3640d5ae 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -188,7 +188,6 @@ static struct apic apic_bigsmp = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = bigsmp_send_IPI_mask, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index b35cfb9b6962..2c5317ea1b83 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -525,7 +525,7 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) return 1; } -static int +static inline int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) { unsigned int round = 0; @@ -643,7 +643,6 @@ static struct apic __refdata apic_es7000_cluster = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, - .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, .send_IPI_mask = es7000_send_IPI_mask, @@ -710,7 +709,6 @@ static struct apic __refdata apic_es7000 = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, - .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, .send_IPI_mask = es7000_send_IPI_mask, diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 0deb773404e5..0540f083f452 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1492,7 +1492,8 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, * We use logical delivery to get the timer IRQ * to the first CPU. */ - if (unlikely(apic->cpu_mask_to_apicid(apic->target_cpus(), &dest))) + if (unlikely(apic->cpu_mask_to_apicid_and(apic->target_cpus(), + apic->target_cpus(), &dest))) dest = BAD_APICID; entry.dest_mode = apic->irq_dest_mode; diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 2b55514c328b..d661ee95cabf 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -406,13 +406,6 @@ static inline int numaq_check_phys_apicid_present(int phys_apicid) * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ -static int -numaq_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) -{ - *apicid = 0x0F; - return 0; -} - static int numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, @@ -499,7 +492,6 @@ static struct apic __refdata apic_numaq = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid = numaq_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and, .send_IPI_mask = numaq_send_IPI_mask, diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 2c6f003b2e4b..eef6bcd1bf1e 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -108,7 +108,6 @@ static struct apic apic_default = { .set_apic_id = NULL, .apic_id_mask = 0x0F << 24, - .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = default_send_IPI_mask_logical, diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 79d360f6729e..bbad180f2890 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -263,7 +263,7 @@ static int summit_check_phys_apicid_present(int physical_apicid) return 1; } -static int +static inline int summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) { unsigned int round = 0; @@ -516,7 +516,6 @@ static struct apic apic_summit = { .set_apic_id = NULL, .apic_id_mask = 0xFF << 24, - .cpu_mask_to_apicid = summit_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and, .send_IPI_mask = summit_send_IPI_mask, diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 1885a73b7f33..943d03fc6fc4 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -96,22 +96,6 @@ static void x2apic_send_IPI_all(int vector) __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); } -static int -x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) -{ - int cpu = cpumask_first_and(cpumask, cpu_online_mask); - int i; - - if (cpu >= nr_cpu_ids) - return -EINVAL; - - *apicid = 0; - for_each_cpu_and(i, cpumask, per_cpu(cpus_in_cluster, cpu)) - *apicid |= per_cpu(x86_cpu_to_logical_apicid, i); - - return 0; -} - static int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, @@ -270,7 +254,6 @@ static struct apic apic_x2apic_cluster = { .set_apic_id = x2apic_set_apic_id, .apic_id_mask = 0xFFFFFFFFu, - .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, .send_IPI_mask = x2apic_send_IPI_mask, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index f109388a0e80..e03a1e180e81 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -123,7 +123,6 @@ static struct apic apic_x2apic_phys = { .set_apic_id = x2apic_set_apic_id, .apic_id_mask = 0xFFFFFFFFu, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, .send_IPI_mask = x2apic_send_IPI_mask, diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 307aa076bd62..026de0114d15 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -269,27 +269,6 @@ static void uv_init_apic_ldr(void) { } -static inline int __uv_cpu_to_apicid(int cpu, unsigned int *apicid) -{ - if (likely((unsigned int)cpu < nr_cpu_ids)) { - *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; - return 0; - } else { - return -EINVAL; - } -} - -static int -uv_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid) -{ - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - int cpu = cpumask_first_and(cpumask, cpu_online_mask); - return __uv_cpu_to_apicid(cpu, apicid); -} - static int uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, @@ -306,7 +285,12 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, break; } - return __uv_cpu_to_apicid(cpu, apicid); + if (likely((unsigned int)cpu < nr_cpu_ids)) { + *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; + return 0; + } else { + return -EINVAL; + } } static unsigned int x2apic_get_apic_id(unsigned long x) @@ -384,7 +368,6 @@ static struct apic __refdata apic_x2apic_uv_x = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFFFFFFFu, - .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, .cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and, .send_IPI_mask = uv_send_IPI_mask, diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c index dd1ff39a464c..a67c7a6bac7e 100644 --- a/arch/x86/platform/uv/uv_irq.c +++ b/arch/x86/platform/uv/uv_irq.c @@ -144,7 +144,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, if (err != 0) return err; - err = apic->cpu_mask_to_apicid(eligible_cpu, &dest); + err = apic->cpu_mask_to_apicid_and(eligible_cpu, eligible_cpu, &dest); if (err != 0) return err; -- GitLab From ea3807ea52a53f2cdfd60c89d8491fc9a8208d1c Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 14 Jun 2012 09:49:55 +0200 Subject: [PATCH 1595/6849] x86/apic: Fix ugly casting and branching in cpu_mask_to_apicid_and() Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120614074954.GF3383@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/apic.c | 8 ++++---- arch/x86/kernel/apic/es7000_32.c | 2 +- arch/x86/kernel/apic/summit_32.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 048a4f806d46..c421512ca5eb 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2127,19 +2127,19 @@ int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, unsigned int *apicid) { - int cpu; + unsigned int cpu; for_each_cpu_and(cpu, cpumask, andmask) { if (cpumask_test_cpu(cpu, cpu_online_mask)) break; } - if (likely((unsigned int)cpu < nr_cpu_ids)) { + if (likely(cpu < nr_cpu_ids)) { *apicid = per_cpu(x86_cpu_to_apicid, cpu); return 0; - } else { - return -EINVAL; } + + return -EINVAL; } /* diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 2c5317ea1b83..effece2ea0db 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -529,7 +529,7 @@ static inline int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) { unsigned int round = 0; - int cpu, uninitialized_var(apicid); + unsigned int cpu, uninitialized_var(apicid); /* * The cpus in the mask must all be on the apic cluster. diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index bbad180f2890..b53fd6c9993a 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -267,7 +267,7 @@ static inline int summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) { unsigned int round = 0; - int cpu, apicid = 0; + unsigned int cpu, apicid = 0; /* * The cpus in the mask must all be on the apic cluster. diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 026de0114d15..8cfade9510a4 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -274,7 +274,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, const struct cpumask *andmask, unsigned int *apicid) { - int cpu; + int unsigned cpu; /* * We're using fixed IRQ delivery, can only return one phys APIC ID. @@ -285,12 +285,12 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, break; } - if (likely((unsigned int)cpu < nr_cpu_ids)) { + if (likely(cpu < nr_cpu_ids)) { *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; return 0; - } else { - return -EINVAL; } + + return -EINVAL; } static unsigned int x2apic_get_apic_id(unsigned long x) -- GitLab From 49ad3fd4834182cce9725abb98e080b479fed464 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 14 Jun 2012 09:50:11 +0200 Subject: [PATCH 1596/6849] x86/apic/es7000+summit: Fix compile warning in cpu_mask_to_apicid() Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120614075010.GG3383@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/es7000_32.c | 2 +- arch/x86/kernel/apic/summit_32.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index effece2ea0db..0c1347df3ad0 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -554,8 +554,8 @@ es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, const struct cpumask *andmask, unsigned int *apicid) { - *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); cpumask_var_t cpumask; + *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) return 0; diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index b53fd6c9993a..e6cc1829f7c8 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -291,8 +291,8 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, const struct cpumask *andmask, unsigned int *apicid) { - *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); cpumask_var_t cpumask; + *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) return 0; -- GitLab From 214e270b5f5f6a85400a817d5305c797b2b7467a Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 14 Jun 2012 09:50:27 +0200 Subject: [PATCH 1597/6849] x86/apic/es7000+summit: Always make valid apicid from a cpumask In case of invalid parameters cpu_mask_to_apicid_and() might return apicid value of 0 (on Summit) or a uninitialized value (on ES7000), although it is supposed to return apicid of cpu-0 at least. Fix the operation to always return a valid apicid. Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120614075026.GH3383@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/es7000_32.c | 2 ++ arch/x86/kernel/apic/summit_32.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 0c1347df3ad0..9882093f26e8 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -545,6 +545,8 @@ es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) apicid = new_apicid; round++; } + if (!round) + return -EINVAL; *dest_id = apicid; return 0; } diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index e6cc1829f7c8..b6e61857c29f 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -282,6 +282,8 @@ summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) apicid |= new_apicid; round++; } + if (!round) + return -EINVAL; *dest_id = apicid; return 0; } -- GitLab From 5a0a2a308113086cc800a203d903271c9caa1611 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 14 Jun 2012 09:50:44 +0200 Subject: [PATCH 1598/6849] x86/apic/es7000: Make apicid of a cluster (not CPU) from a cpumask cpu_mask_to_apicid_and() always returns apicid of a single CPU, even in case multiple CPUs were requested. This update fixes a typo and forces apicid of a cluster to be returned. Signed-off-by: Alexander Gordeev Cc: Suresh Siddha Cc: Yinghai Lu Link: http://lkml.kernel.org/r/20120614075043.GI3383@dhcp-26-207.brq.redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/es7000_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 9882093f26e8..0874799a98c6 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -542,7 +542,7 @@ es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) return -EINVAL; } - apicid = new_apicid; + apicid |= new_apicid; round++; } if (!round) -- GitLab From c85251f8562095cd6fd63ae786354283c5318303 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Mon, 11 Jun 2012 13:36:12 -0700 Subject: [PATCH 1599/6849] ath6kl: fix fw capability parsing This patch fixes a bug where no capabilites are parsed when the number of firmware capability bits translate into fewer bytes than the host has knowledge of. Instead just process number of capability bytes as reported by the firmware. Signed-off-by: Thomas Pedersen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 62e25ccd1016..f90b5db741cf 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1004,9 +1004,6 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) ar->hw.reserved_ram_size); break; case ATH6KL_FW_IE_CAPABILITIES: - if (ie_len < DIV_ROUND_UP(ATH6KL_FW_CAPABILITY_MAX, 8)) - break; - ath6kl_dbg(ATH6KL_DBG_BOOT, "found firmware capabilities ie (%zd B)\n", ie_len); @@ -1015,6 +1012,9 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) index = i / 8; bit = i % 8; + if (index == ie_len) + break; + if (data[index] & (1 << bit)) __set_bit(i, ar->fw_capabilities); } -- GitLab From 80c8bfbe76869bfd6bdf3d260d316e7a32f318c3 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 4 Jun 2012 09:33:51 +0200 Subject: [PATCH 1600/6849] ALSA: HDA: Create phantom jacks for fixed inputs and outputs PulseAudio sometimes have difficulties knowing that there is a "Speaker" or "Internal Mic", if they have no individual volume controls or selectors. As a result, only e g "Headphone" might be created for a laptop, but no "Speaker". To help out, create phantom jacks (that are always present, at least for now) for "Speaker", "Internal Mic" etc, in case we detect them. The naming convention is e g "Speaker Phantom Jack". In order not to pollute the /dev/input namespace with even more devices, these are added to the kcontrols only, not the input devices. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_jack.c | 59 ++++++++++++++++++++++++++++------------ sound/pci/hda/hda_jack.h | 1 + 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 2dd1c113a4c1..60c976f06280 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec) static void jack_detect_update(struct hda_codec *codec, struct hda_jack_tbl *jack) { - if (jack->jack_dirty || !jack->jack_detect) { + if (!jack->jack_dirty) + return; + + if (jack->phantom_jack) + jack->pin_sense = AC_PINSENSE_PRESENCE; + else jack->pin_sense = read_pin_sense(codec, jack->nid); - jack->jack_dirty = 0; - } + + jack->jack_dirty = 0; } /** @@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack) * This assigns a jack-detection kctl to the given pin. The kcontrol * will have the given name and index. */ -int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, - const char *name, int idx) +static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, + const char *name, int idx, bool phantom_jack) { struct hda_jack_tbl *jack; struct snd_kcontrol *kctl; @@ -283,19 +288,30 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, if (err < 0) return err; jack->kctl = kctl; + jack->phantom_jack = !!phantom_jack; + state = snd_hda_jack_detect(codec, nid); snd_kctl_jack_report(codec->bus->card, kctl, state); #ifdef CONFIG_SND_HDA_INPUT_JACK - jack->type = get_input_jack_type(codec, nid); - err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); - if (err < 0) - return err; - jack->jack->private_data = jack; - jack->jack->private_free = hda_free_jack_priv; - snd_jack_report(jack->jack, state ? jack->type : 0); + if (!phantom_jack) { + jack->type = get_input_jack_type(codec, nid); + err = snd_jack_new(codec->bus->card, name, jack->type, + &jack->jack); + if (err < 0) + return err; + jack->jack->private_data = jack; + jack->jack->private_free = hda_free_jack_priv; + snd_jack_report(jack->jack, state ? jack->type : 0); + } #endif return 0; } + +int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, + const char *name, int idx) +{ + return __snd_hda_jack_add_kctl(codec, nid, name, idx, false); +} EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, @@ -305,25 +321,32 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, unsigned int def_conf, conn; char name[44]; int idx, err; + bool phantom_jack; if (!nid) return 0; - if (!is_jack_detectable(codec, nid)) - return 0; def_conf = snd_hda_codec_get_pincfg(codec, nid); conn = get_defcfg_connect(def_conf); - if (conn != AC_JACK_PORT_COMPLEX) + if (conn == AC_JACK_PORT_NONE) return 0; + phantom_jack = (conn != AC_JACK_PORT_COMPLEX) || + !is_jack_detectable(codec, nid); snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); + if (phantom_jack) + /* Example final name: "Internal Mic Phantom Jack" */ + strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); if (!strcmp(name, lastname) && idx == *lastidx) idx++; - strncpy(lastname, name, 44); + strncpy(lastname, name, sizeof(name)); *lastidx = idx; - err = snd_hda_jack_add_kctl(codec, nid, name, idx); + err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack); if (err < 0) return err; - return snd_hda_jack_detect_enable(codec, nid, 0); + + if (!phantom_jack) + return snd_hda_jack_detect_enable(codec, nid, 0); + return 0; } /** diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 8ae52465ec5d..a9803da633c0 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -23,6 +23,7 @@ struct hda_jack_tbl { unsigned int pin_sense; /* cached pin-sense value */ unsigned int jack_detect:1; /* capable of jack-detection? */ unsigned int jack_dirty:1; /* needs to update? */ + unsigned int phantom_jack:1; /* a fixed, always present port? */ struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ #ifdef CONFIG_SND_HDA_INPUT_JACK int type; -- GitLab From b9b52918abe88d9135dd570fb394b9c432eb1cfd Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 12 Jun 2012 10:49:51 +0100 Subject: [PATCH 1601/6849] ARM: 7422/1: mmc: mmci: Allocate platform memory during Device Tree boot When booting with Device Tree enabled, platform specific information is gathered by parsing the DT binary. Platform data is subsequently populated with the result. The memory required for this is not automatically allocated during Device Tree boot, so we'll do it here instead. Acked-by: Linus Walleij Signed-off-by: Lee Jones Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f0fcce40cd8d..0045ee001ec7 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1276,6 +1276,12 @@ static int __devinit mmci_probe(struct amba_device *dev, return -EINVAL; } + if (!plat) { + plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); + if (!plat) + return -ENOMEM; + } + if (np) mmci_dt_populate_generic_pdata(np, plat); -- GitLab From 2307574a50dcb0f9c13e541ca3a196f7554af977 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 12 Jun 2012 12:31:43 +0100 Subject: [PATCH 1602/6849] ARM: 7423/1: kprobes: run t32_simulate_ldr_literal() without insn slot t32_simulate_ldr_literal() can be run without an instruction slot, so it should be using DECODE_SIMULATEX instead of DECODE_EMULATEX. Acked-by: Jon Medhurst Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/kernel/kprobes-thumb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 8f96ec778e8d..6123daf397a7 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c @@ -660,7 +660,7 @@ static const union decode_item t32_table_1111_100x[] = { /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ - DECODE_EMULATEX (0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, + DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, REGS(PC, NOSPPCX, 0, 0, 0)), /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ -- GitLab From 2bea29b774ccb4bf32c7b299c677fccc5a1d8443 Mon Sep 17 00:00:00 2001 From: Mircea Gherzan Date: Mon, 11 Jun 2012 23:52:25 +0100 Subject: [PATCH 1603/6849] ARM: 7421/1: bpf_jit: BPF_S_ANC_ALU_XOR_X support JIT support for the XOR operation introduced by the commit ffe06c17afbb. Signed-off-by: Mircea Gherzan Signed-off-by: Russell King --- arch/arm/net/bpf_jit_32.c | 5 +++++ arch/arm/net/bpf_jit_32.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 62135849f48b..c641fb685017 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -762,6 +762,11 @@ b_epilogue: update_on_xread(ctx); emit(ARM_MOV_R(r_A, r_X), ctx); break; + case BPF_S_ANC_ALU_XOR_X: + /* A ^= X */ + update_on_xread(ctx); + emit(ARM_EOR_R(r_A, r_A, r_X), ctx); + break; case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol) */ ctx->seen |= SEEN_SKB; diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h index 99ae5e3f46d2..7fa2f7d3cb90 100644 --- a/arch/arm/net/bpf_jit_32.h +++ b/arch/arm/net/bpf_jit_32.h @@ -68,6 +68,8 @@ #define ARM_INST_CMP_R 0x01500000 #define ARM_INST_CMP_I 0x03500000 +#define ARM_INST_EOR_R 0x00200000 + #define ARM_INST_LDRB_I 0x05d00000 #define ARM_INST_LDRB_R 0x07d00000 #define ARM_INST_LDRH_I 0x01d000b0 @@ -132,6 +134,8 @@ #define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm) #define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) +#define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm) + #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ | (off)) #define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ -- GitLab From 15ab218318892f60e65c98bba81d725b3c19dab0 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:16 +0200 Subject: [PATCH 1604/6849] ARM: LPC32xx: Add NAND flash timing to PHY3250 board dts This patch adds necessary NAND flash timings to the board specific dts file of the PHY3250 reference board of the LPC32xx SoC. Signed-off-by: Roland Stigge Tested-by: Alexandre Pereira da Silva --- arch/arm/boot/dts/phy3250.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index c4ff6d1a018b..d7e985e47831 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -54,6 +54,17 @@ #address-cells = <1>; #size-cells = <1>; + nxp,wdr-clks = <14>; + nxp,wwidth = <40000000>; + nxp,whold = <100000000>; + nxp,wsetup = <100000000>; + nxp,rdr-clks = <14>; + nxp,rwidth = <40000000>; + nxp,rhold = <66666666>; + nxp,rsetup = <100000000>; + nand-on-flash-bbt; + gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */ + mtd0@00000000 { label = "phy3250-boot"; reg = <0x00000000 0x00064000>; -- GitLab From b27f48227c59754e1c881bd8e2b327ac02fe17b6 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:16 +0200 Subject: [PATCH 1605/6849] ARM: LPC32xx: Clock initialization for NAND controllers This patch adds clock initialization for the MLC NAND controller of the LPC32xx SoC and adjusts it for the SLC controller. Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/clock.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c index f6a3ffec1f4b..bf0c3d91af9c 100644 --- a/arch/arm/mach-lpc32xx/clock.c +++ b/arch/arm/mach-lpc32xx/clock.c @@ -691,10 +691,21 @@ static struct clk clk_nand = { .parent = &clk_hclk, .enable = local_onoff_enable, .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN, + .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN | + LPC32XX_CLKPWR_NANDCLK_SEL_SLC, .get_rate = local_return_parent_rate, }; +static struct clk clk_nand_mlc = { + .parent = &clk_hclk, + .enable = local_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN | + LPC32XX_CLKPWR_NANDCLK_DMA_INT | + LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC, + .get_rate = local_return_parent_rate, +}; + static struct clk clk_i2s0 = { .parent = &clk_hclk, .enable = local_onoff_enable, @@ -1121,7 +1132,8 @@ static struct clk_lookup lookups[] = { CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0), CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1), CLKDEV_INIT("lpc32xx_keys.0", NULL, &clk_kscan), - CLKDEV_INIT("lpc32xx-nand.0", "nand_ck", &clk_nand), + CLKDEV_INIT("20020000.flash", NULL, &clk_nand), + CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc), CLKDEV_INIT("40048000.adc", NULL, &clk_adc), CLKDEV_INIT(NULL, "i2s0_ck", &clk_i2s0), CLKDEV_INIT(NULL, "i2s1_ck", &clk_i2s1), -- GitLab From ba225a0ea225902501487a2c9f620c26dce1cee6 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:16 +0200 Subject: [PATCH 1606/6849] ARM: LPC32xx: Remove SLC controller initialization from platform init Since we now support two MTD NAND controllers (MLC and SLC) for LPC32xx via DT, we don't initialize the SLC controller statically anymore, but do it via the clock setup (see previous patch). Signed-off-by: Roland Stigge Tested-by: Alexandre Pereira da Silva --- arch/arm/mach-lpc32xx/phy3250.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 540106cdb9ec..42a078eb1665 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -241,10 +241,6 @@ static void __init lpc3250_machine_init(void) { u32 tmp; - /* Setup SLC NAND controller muxing */ - __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, - LPC32XX_CLKPWR_NAND_CLK_CTRL); - /* Setup LCD muxing to RGB565 */ tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) & ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK | -- GitLab From d807af4793a464f7331f92461a619e5e7ddf9089 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1607/6849] ARM: LPC32xx: Add DMA configuration to platform data This patch adds DMA channel configuration to the LPC32xx platform file. The configured DMA signalling is generic for LPC32xx SoC and is not board specific. Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/phy3250.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 42a078eb1665..eade77fbebdd 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -226,7 +226,38 @@ static int __init phy3250_spi_board_register(void) } arch_initcall(phy3250_spi_board_register); +static struct pl08x_channel_data pl08x_slave_channels[] = { + { + .bus_id = "nand-slc", + .min_signal = 1, /* SLC NAND Flash */ + .max_signal = 1, + .periph_buses = PL08X_AHB1, + }, + { + .bus_id = "nand-mlc", + .min_signal = 12, /* MLC NAND Flash */ + .max_signal = 12, + .periph_buses = PL08X_AHB1, + }, +}; + +/* NOTE: These will change, according to RMK */ +static int pl08x_get_signal(struct pl08x_dma_chan *ch) +{ + return ch->cd->min_signal; +} + +static void pl08x_put_signal(struct pl08x_dma_chan *ch) +{ +} + static struct pl08x_platform_data pl08x_pd = { + .slave_channels = &pl08x_slave_channels[0], + .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels), + .get_signal = pl08x_get_signal, + .put_signal = pl08x_put_signal, + .lli_buses = PL08X_AHB1, + .mem_buses = PL08X_AHB1, }; static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { -- GitLab From 6d1c3e93e37f35dac67fd88822e4a3100b1bd2c3 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1608/6849] ARM: LPC32xx: Adjust dtsi file for MLC controller configuration This patch takes into account that the MTD NAND MLC controller needs more registers, located actually before the previously allocated memory range, already starting at 200a8000 instead of 200b0000. Further, the interrupt for the controller is configured. Signed-off-by: Roland Stigge Tested-by: Alexandre Pereira da Silva --- arch/arm/boot/dts/lpc32xx.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index 3f5dad801a98..254d586d4b1a 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -38,9 +38,10 @@ status = "disable"; }; - mlc: flash@200B0000 { + mlc: flash@200a8000 { compatible = "nxp,lpc3220-mlc"; - reg = <0x200B0000 0x1000>; + reg = <0x200a8000 0x11000>; + interrupts = <11 0>; status = "disable"; }; -- GitLab From d0408713e764c20796a8f79f3179ae41148edf19 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1609/6849] ARM: LPC32xx: Add dts for EA3250 reference board There is another reference/development board for the LPC32xx SoC (besides the Phytec 3250): The Embedded Artists LPC3250 board. This patch adds a default dts file for it. Signed-off-by: Roland Stigge Acked-by: Alexandre Pereira da Silva --- arch/arm/boot/dts/ea3250.dts | 157 +++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 arch/arm/boot/dts/ea3250.dts diff --git a/arch/arm/boot/dts/ea3250.dts b/arch/arm/boot/dts/ea3250.dts new file mode 100644 index 000000000000..c07ba8c2cc0d --- /dev/null +++ b/arch/arm/boot/dts/ea3250.dts @@ -0,0 +1,157 @@ +/* + * Embedded Artists LPC3250 board + * + * Copyright 2012 Roland Stigge + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "lpc32xx.dtsi" + +/ { + model = "Embedded Artists LPC3250 board based on NXP LPC3250"; + compatible = "ea,ea3250", "nxp,lpc3250"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + device_type = "memory"; + reg = <0 0x4000000>; + }; + + ahb { + mac: ethernet@31060000 { + phy-mode = "rmii"; + use-iram; + }; + + /* Here, choose exactly one from: ohci, usbd */ + ohci@31020000 { + transceiver = <&isp1301>; + status = "okay"; + }; + +/* + usbd@31020000 { + transceiver = <&isp1301>; + status = "okay"; + }; +*/ + + /* 128MB Flash via SLC NAND controller */ + slc: flash@20020000 { + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + nxp,wdr-clks = <14>; + nxp,wwidth = <260000000>; + nxp,whold = <104000000>; + nxp,wsetup = <200000000>; + nxp,rdr-clks = <14>; + nxp,rwidth = <34666666>; + nxp,rhold = <104000000>; + nxp,rsetup = <200000000>; + nand-on-flash-bbt; + gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */ + + mtd0@00000000 { + label = "ea3250-boot"; + reg = <0x00000000 0x00080000>; + read-only; + }; + + mtd1@00080000 { + label = "ea3250-uboot"; + reg = <0x00080000 0x000c0000>; + read-only; + }; + + mtd2@00140000 { + label = "ea3250-kernel"; + reg = <0x00140000 0x00400000>; + }; + + mtd3@00540000 { + label = "ea3250-rootfs"; + reg = <0x00540000 0x07ac0000>; + }; + }; + + apb { + uart5: serial@40090000 { + status = "okay"; + }; + + uart3: serial@40080000 { + status = "okay"; + }; + + uart6: serial@40098000 { + status = "okay"; + }; + + i2c1: i2c@400A0000 { + clock-frequency = <100000>; + + eeprom@50 { + compatible = "at,24c256"; + reg = <0x50>; + }; + + eeprom@57 { + compatible = "at,24c64"; + reg = <0x57>; + }; + + uda1380: uda1380@18 { + compatible = "nxp,uda1380"; + reg = <0x18>; + power-gpio = <&gpio 0x59 0>; + reset-gpio = <&gpio 0x51 0>; + dac-clk = "wspll"; + }; + + pca9532: pca9532@60 { + compatible = "nxp,pca9532"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x60>; + }; + }; + + i2c2: i2c@400A8000 { + clock-frequency = <100000>; + }; + + i2cusb: i2c@31020300 { + clock-frequency = <100000>; + + isp1301: usb-transceiver@2d { + compatible = "nxp,isp1301"; + reg = <0x2d>; + }; + }; + + sd@20098000 { + wp-gpios = <&pca9532 5 0>; + cd-gpios = <&pca9532 4 0>; + cd-inverted; + bus-width = <4>; + status = "okay"; + }; + }; + + fab { + uart1: serial@40014000 { + status = "okay"; + }; + }; + }; +}; -- GitLab From a6d1be0e5825246da6df42cdaa21f3ce66698ff2 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1610/6849] ARM: LPC32xx: DTS adjustment for key matrix controller This patch connects the lpc32xx-key driver to the LPC32xx platform (via lpc32xx.dtsi), and more specifically to the reference board via its dts file. Signed-off-by: Roland Stigge Acked-by: Rob Herring Acked-by: Alexandre Pereira da Silva --- arch/arm/boot/dts/lpc32xx.dtsi | 2 ++ arch/arm/boot/dts/phy3250.dts | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index 254d586d4b1a..e2b50b220a38 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -249,6 +249,8 @@ key@40050000 { compatible = "nxp,lpc3220-key"; reg = <0x40050000 0x1000>; + interrupts = <54 0>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index d7e985e47831..1dbfea8b7bdf 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -135,6 +135,15 @@ tsc@40048000 { status = "okay"; }; + + key@40050000 { + status = "okay"; + keypad,num-rows = <1>; + keypad,num-columns = <1>; + nxp,debounce-delay-ms = <3>; + nxp,scan-delay-ms = <34>; + linux,keymap = <0x00000002>; + }; }; }; -- GitLab From 821e7edd5130a1efd8754bcd7e4c30ccb1fc9c71 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1611/6849] ARM: LPC32xx: Clock adjustment for key matrix controller The clock.c file needs to be changed to match the automatic device name to its clock. Signed-off-by: Roland Stigge Acked-by: Rob Herring --- arch/arm/mach-lpc32xx/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c index bf0c3d91af9c..963d12a9fc3d 100644 --- a/arch/arm/mach-lpc32xx/clock.c +++ b/arch/arm/mach-lpc32xx/clock.c @@ -1131,7 +1131,7 @@ static struct clk_lookup lookups[] = { CLKDEV_INIT("31020300.i2c", NULL, &clk_i2c2), CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0), CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1), - CLKDEV_INIT("lpc32xx_keys.0", NULL, &clk_kscan), + CLKDEV_INIT("40050000.key", NULL, &clk_kscan), CLKDEV_INIT("20020000.flash", NULL, &clk_nand), CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc), CLKDEV_INIT("40048000.adc", NULL, &clk_adc), -- GitLab From 360c9627cc3b0334514d6cb8260833e768c71b63 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1612/6849] ARM: LPC32xx: Defconfig update This defconfig update for the LPC32xx SoC platform adds the new drivers in v3.5 and drivers typically used in systems with the LPC32xx chip. Signed-off-by: Roland Stigge Acked-by: Alexandre Pereira da Silva --- arch/arm/configs/lpc32xx_defconfig | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig index 4fa60547494a..eceed186a3c1 100644 --- a/arch/arm/configs/lpc32xx_defconfig +++ b/arch/arm/configs/lpc32xx_defconfig @@ -1,5 +1,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 @@ -16,8 +18,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_LPC32XX=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -52,13 +52,17 @@ CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y +CONFIG_MTD_M25P80=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_MUSEUM_IDS=y +CONFIG_MTD_NAND_SLC_LPC32XX=y +CONFIG_MTD_NAND_MLC_LPC32XX=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=1 CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -79,16 +83,22 @@ CONFIG_LPC_ENET=y # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_SMSC_PHY=y # CONFIG_WLAN is not set +CONFIG_INPUT_MATRIXKMAP=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_LPC32XX=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_LPC32XX=y +CONFIG_SERIO_LIBPS2=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_HS_LPC32XX=y +CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=y @@ -96,7 +106,8 @@ CONFIG_I2C_PNX=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set +CONFIG_SENSORS_DS620=y +CONFIG_SENSORS_MAX6639=y CONFIG_WATCHDOG=y CONFIG_PNX4008_WATCHDOG=y CONFIG_FB=y @@ -133,6 +144,8 @@ CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_PCA9532=y +CONFIG_LEDS_PCA9532_GPIO=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y @@ -146,10 +159,10 @@ CONFIG_RTC_DRV_DS1374=y CONFIG_RTC_DRV_PCF8563=y CONFIG_RTC_DRV_LPC32XX=y CONFIG_DMADEVICES=y -CONFIG_AMBA_PL08X=y CONFIG_STAGING=y -CONFIG_IIO=y CONFIG_LPC32XX_ADC=y +CONFIG_MAX517=y +CONFIG_IIO=y CONFIG_EXT2_FS=y CONFIG_AUTOFS4_FS=y CONFIG_MSDOS_FS=y @@ -159,7 +172,6 @@ CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_WBUF_VERIFY=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y -- GitLab From 291dd71fe48c0b696a9391ed1ba476c8878d6fca Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:17 +0200 Subject: [PATCH 1613/6849] ARM: LPC32xx: Add MMC controller support This patch adds support for the MMC controller of the LPC32xx SoC to the platform initialization via the pl08x primecell driver. Lacking more complete DT support, done via DT auxdata. Signed-off-by: Roland Stigge Acked-by: Alexandre Pereira da Silva --- arch/arm/mach-lpc32xx/phy3250.c | 43 ++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index eade77fbebdd..03ee3491b7cf 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -30,12 +30,13 @@ #include #include #include +#include +#include #include #include #include #include #include -#include #include #include @@ -50,9 +51,12 @@ /* * Mapped GPIOLIB GPIOs */ -#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) -#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) -#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) +#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) +#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) +#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) +#define MMC_PWR_ENABLE_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 5) +#define MMC_CD_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 1) +#define MMC_WP_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 0) /* * AMBA LCD controller @@ -260,11 +264,32 @@ static struct pl08x_platform_data pl08x_pd = { .mem_buses = PL08X_AHB1, }; +static int mmc_handle_ios(struct device *dev, struct mmc_ios *ios) +{ + /* Only on and off are supported */ + if (ios->power_mode == MMC_POWER_OFF) + gpio_set_value(MMC_PWR_ENABLE_GPIO, 0); + else + gpio_set_value(MMC_PWR_ENABLE_GPIO, 1); + return 0; +} + +static struct mmci_platform_data lpc32xx_mmci_data = { + .ocr_mask = MMC_VDD_30_31 | MMC_VDD_31_32 | + MMC_VDD_32_33 | MMC_VDD_33_34, + .ios_handler = mmc_handle_ios, + .dma_filter = NULL, + /* No DMA for now since AMBA PL080 dmaengine driver only does scatter + * gather, and the MMCI driver doesn't do it this way */ +}; + static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data), OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data), OF_DEV_AUXDATA("arm,pl110", 0x31040000, "dev:clcd", &lpc32xx_clcd_data), OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd), + OF_DEV_AUXDATA("arm,pl18x", 0x20098000, "20098000.sd", + &lpc32xx_mmci_data), { } }; @@ -308,6 +333,11 @@ static void __init lpc3250_machine_init(void) * detection or a data fault will occur, so enable the clocks * here. */ + tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); + tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | + LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; + __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); + tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), LPC32XX_CLKPWR_LCDCLK_CTRL); @@ -335,6 +365,11 @@ static void __init lpc3250_machine_init(void) else if (gpio_direction_output(SPI0_CS_GPIO, 1)) printk(KERN_ERR "Error setting gpio %u to output", SPI0_CS_GPIO); + + if (gpio_request(MMC_PWR_ENABLE_GPIO, "mmc_power_en")) + pr_err("Error requesting gpio %u", MMC_PWR_ENABLE_GPIO); + else if (gpio_direction_output(MMC_PWR_ENABLE_GPIO, 1)) + pr_err("Error setting gpio %u to output", MMC_PWR_ENABLE_GPIO); } static char const *lpc32xx_dt_compat[] __initdata = { -- GitLab From 2c7fa28622d8c00ca41f0362d11c52d9f404f543 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:18 +0200 Subject: [PATCH 1614/6849] ARM: LPC32xx: DTS adjustment for using pl18x primecell This patch adjusts the dts files to reference the pl18x primecell driver correctly. Signed-off-by: Roland Stigge --- arch/arm/boot/dts/lpc32xx.dtsi | 3 ++- arch/arm/boot/dts/phy3250.dts | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index e2b50b220a38..a9b2a6a22024 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -115,9 +115,10 @@ }; sd@20098000 { - compatible = "arm,pl180", "arm,primecell"; + compatible = "arm,pl18x", "arm,primecell"; reg = <0x20098000 0x1000>; interrupts = <0x0f 0>, <0x0d 0>; + status = "disabled"; }; i2s1: i2s@2009C000 { diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index 1dbfea8b7bdf..d5432378f234 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -129,6 +129,14 @@ compatible = "atmel,at25"; }; }; + + sd@20098000 { + wp-gpios = <&gpio 3 0 0>; + cd-gpios = <&gpio 3 1 0>; + cd-inverted; + bus-width = <4>; + status = "okay"; + }; }; fab { -- GitLab From c70426f1534a7d8e52e478ce67fd4634cc588741 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:18 +0200 Subject: [PATCH 1615/6849] ARM: LPC32xx: DT conversion of Standard UARTs This patch switches from static serial driver initialization to devicetree configuration. This way, the Standard UARTs of the LPC32xx SoC can be enabled individually via DT. E.g., instead of Kconfig configuration, the phy3250.dts activates UARTs 3 and 5. Signed-off-by: Roland Stigge Tested-by: Alexandre Pereira da Silva --- arch/arm/Kconfig | 2 - arch/arm/boot/dts/lpc32xx.dtsi | 34 ++++++++++---- arch/arm/boot/dts/phy3250.dts | 8 ++++ arch/arm/mach-lpc32xx/Kconfig | 32 ------------- arch/arm/mach-lpc32xx/serial.c | 85 +--------------------------------- 5 files changed, 35 insertions(+), 126 deletions(-) delete mode 100644 arch/arm/mach-lpc32xx/Kconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 84449dd8f031..973d5380a431 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1019,8 +1019,6 @@ source "arch/arm/mach-kirkwood/Kconfig" source "arch/arm/mach-ks8695/Kconfig" -source "arch/arm/mach-lpc32xx/Kconfig" - source "arch/arm/mach-msm/Kconfig" source "arch/arm/mach-mv78xx0/Kconfig" diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index a9b2a6a22024..acb68171d04d 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -126,24 +126,42 @@ reg = <0x2009C000 0x1000>; }; + /* UART5 first since it is the default console, ttyS0 */ + uart5: serial@40090000 { + /* actually, ns16550a w/ 64 byte fifos! */ + compatible = "nxp,lpc3220-uart"; + reg = <0x40090000 0x1000>; + interrupts = <9 0>; + clock-frequency = <13000000>; + reg-shift = <2>; + status = "disabled"; + }; + uart3: serial@40080000 { - compatible = "nxp,serial"; + compatible = "nxp,lpc3220-uart"; reg = <0x40080000 0x1000>; + interrupts = <7 0>; + clock-frequency = <13000000>; + reg-shift = <2>; + status = "disabled"; }; uart4: serial@40088000 { - compatible = "nxp,serial"; + compatible = "nxp,lpc3220-uart"; reg = <0x40088000 0x1000>; - }; - - uart5: serial@40090000 { - compatible = "nxp,serial"; - reg = <0x40090000 0x1000>; + interrupts = <8 0>; + clock-frequency = <13000000>; + reg-shift = <2>; + status = "disabled"; }; uart6: serial@40098000 { - compatible = "nxp,serial"; + compatible = "nxp,lpc3220-uart"; reg = <0x40098000 0x1000>; + interrupts = <10 0>; + clock-frequency = <13000000>; + reg-shift = <2>; + status = "disabled"; }; i2c1: i2c@400A0000 { diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index d5432378f234..57d4961372d4 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -94,6 +94,14 @@ }; apb { + uart5: serial@40090000 { + status = "okay"; + }; + + uart3: serial@40080000 { + status = "okay"; + }; + i2c1: i2c@400A0000 { clock-frequency = <100000>; diff --git a/arch/arm/mach-lpc32xx/Kconfig b/arch/arm/mach-lpc32xx/Kconfig deleted file mode 100644 index e0b3eee83834..000000000000 --- a/arch/arm/mach-lpc32xx/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -if ARCH_LPC32XX - -menu "Individual UART enable selections" - -config ARCH_LPC32XX_UART3_SELECT - bool "Add support for standard UART3" - help - Adds support for standard UART 3 when the 8250 serial support - is enabled. - -config ARCH_LPC32XX_UART4_SELECT - bool "Add support for standard UART4" - help - Adds support for standard UART 4 when the 8250 serial support - is enabled. - -config ARCH_LPC32XX_UART5_SELECT - bool "Add support for standard UART5" - default y - help - Adds support for standard UART 5 when the 8250 serial support - is enabled. - -config ARCH_LPC32XX_UART6_SELECT - bool "Add support for standard UART6" - help - Adds support for standard UART 6 when the 8250 serial support - is enabled. - -endmenu - -endif diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c index f2735281616a..b5a3f3423f63 100644 --- a/arch/arm/mach-lpc32xx/serial.c +++ b/arch/arm/mach-lpc32xx/serial.c @@ -31,59 +31,6 @@ #define LPC32XX_SUART_FIFO_SIZE 64 -/* Standard 8250/16550 compatible serial ports */ -static struct plat_serial8250_port serial_std_platform_data[] = { -#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT - { - .membase = io_p2v(LPC32XX_UART5_BASE), - .mapbase = LPC32XX_UART5_BASE, - .irq = IRQ_LPC32XX_UART_IIR5, - .uartclk = LPC32XX_MAIN_OSC_FREQ, - .regshift = 2, - .iotype = UPIO_MEM32, - .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | - UPF_SKIP_TEST, - }, -#endif -#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT - { - .membase = io_p2v(LPC32XX_UART3_BASE), - .mapbase = LPC32XX_UART3_BASE, - .irq = IRQ_LPC32XX_UART_IIR3, - .uartclk = LPC32XX_MAIN_OSC_FREQ, - .regshift = 2, - .iotype = UPIO_MEM32, - .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | - UPF_SKIP_TEST, - }, -#endif -#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT - { - .membase = io_p2v(LPC32XX_UART4_BASE), - .mapbase = LPC32XX_UART4_BASE, - .irq = IRQ_LPC32XX_UART_IIR4, - .uartclk = LPC32XX_MAIN_OSC_FREQ, - .regshift = 2, - .iotype = UPIO_MEM32, - .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | - UPF_SKIP_TEST, - }, -#endif -#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT - { - .membase = io_p2v(LPC32XX_UART6_BASE), - .mapbase = LPC32XX_UART6_BASE, - .irq = IRQ_LPC32XX_UART_IIR6, - .uartclk = LPC32XX_MAIN_OSC_FREQ, - .regshift = 2, - .iotype = UPIO_MEM32, - .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | - UPF_SKIP_TEST, - }, -#endif - { }, -}; - struct uartinit { char *uart_ck_name; u32 ck_mode_mask; @@ -92,7 +39,6 @@ struct uartinit { }; static struct uartinit uartinit_data[] __initdata = { -#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT { .uart_ck_name = "uart5_ck", .ck_mode_mask = @@ -100,8 +46,6 @@ static struct uartinit uartinit_data[] __initdata = { .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL, .mapbase = LPC32XX_UART5_BASE, }, -#endif -#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT { .uart_ck_name = "uart3_ck", .ck_mode_mask = @@ -109,8 +53,6 @@ static struct uartinit uartinit_data[] __initdata = { .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL, .mapbase = LPC32XX_UART3_BASE, }, -#endif -#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT { .uart_ck_name = "uart4_ck", .ck_mode_mask = @@ -118,8 +60,6 @@ static struct uartinit uartinit_data[] __initdata = { .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL, .mapbase = LPC32XX_UART4_BASE, }, -#endif -#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT { .uart_ck_name = "uart6_ck", .ck_mode_mask = @@ -127,19 +67,6 @@ static struct uartinit uartinit_data[] __initdata = { .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL, .mapbase = LPC32XX_UART6_BASE, }, -#endif -}; - -static struct platform_device serial_std_platform_device = { - .name = "serial8250", - .id = 0, - .dev = { - .platform_data = serial_std_platform_data, - }, -}; - -static struct platform_device *lpc32xx_serial_devs[] __initdata = { - &serial_std_platform_device, }; void __init lpc32xx_serial_init(void) @@ -156,15 +83,8 @@ void __init lpc32xx_serial_init(void) clk = clk_get(NULL, uartinit_data[i].uart_ck_name); if (!IS_ERR(clk)) { clk_enable(clk); - serial_std_platform_data[i].uartclk = - clk_get_rate(clk); } - /* Fall back on main osc rate if clock rate return fails */ - if (serial_std_platform_data[i].uartclk == 0) - serial_std_platform_data[i].uartclk = - LPC32XX_MAIN_OSC_FREQ; - /* Setup UART clock modes for all UARTs, disable autoclock */ clkmodes |= uartinit_data[i].ck_mode_mask; @@ -189,7 +109,7 @@ void __init lpc32xx_serial_init(void) __raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE); for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) { /* Force a flush of the RX FIFOs to work around a HW bug */ - puart = serial_std_platform_data[i].mapbase; + puart = uartinit_data[i].mapbase; __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart)); __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart)); j = LPC32XX_SUART_FIFO_SIZE; @@ -202,7 +122,4 @@ void __init lpc32xx_serial_init(void) tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB; __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); - - platform_add_devices(lpc32xx_serial_devs, - ARRAY_SIZE(lpc32xx_serial_devs)); } -- GitLab From ac5ced91aa6b5013027d3313824c9c5afb071f23 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:18 +0200 Subject: [PATCH 1616/6849] ARM: LPC32xx: High Speed UART configuration via DT This patch fixes the DTS files for the High Speed UARTs 1, 2 and 7 of the LPC32xx SoC, adjusting the compatible strings, adding interrupts and status configuration. On the PHY3250 reference board, UART2 is enabled. Signed-off-by: Roland Stigge Acked-by: Alexandre Pereira da Silva --- arch/arm/boot/dts/lpc32xx.dtsi | 16 +++++++++++----- arch/arm/boot/dts/phy3250.dts | 4 ++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index acb68171d04d..34a73f34621c 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -212,18 +212,24 @@ }; uart1: serial@40014000 { - compatible = "nxp,serial"; + compatible = "nxp,lpc3220-hsuart"; reg = <0x40014000 0x1000>; + interrupts = <26 0>; + status = "disabled"; }; uart2: serial@40018000 { - compatible = "nxp,serial"; + compatible = "nxp,lpc3220-hsuart"; reg = <0x40018000 0x1000>; + interrupts = <25 0>; + status = "disabled"; }; - uart7: serial@4001C000 { - compatible = "nxp,serial"; - reg = <0x4001C000 0x1000>; + uart7: serial@4001c000 { + compatible = "nxp,lpc3220-hsuart"; + reg = <0x4001c000 0x1000>; + interrupts = <24 0>; + status = "disabled"; }; rtc@40024000 { diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index 57d4961372d4..f3bf1493afb0 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -148,6 +148,10 @@ }; fab { + uart2: serial@40018000 { + status = "okay"; + }; + tsc@40048000 { status = "okay"; }; -- GitLab From 1a6e29c913d25eae0e232926fd9f7ceaf5306dc2 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:18 +0200 Subject: [PATCH 1617/6849] ARM: LPC32xx: Remove mach specific ARCH_NR_GPIOS, use default ARCH_NR_GPIOS was defined statically to include exactly all SoC specific GPIOs. Now if additional GPIOs need to be added dynamically, e.g. via DT, none are available. Removing the mach specific setting, leaving ARCH_NR_GPIOS to the default of 256 (currently in include/asm-generic/gpio.h). Signed-off-by: Roland Stigge Acked-by: Alexandre Pereira da Silva --- arch/arm/mach-lpc32xx/include/mach/gpio.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-lpc32xx/include/mach/gpio.h b/arch/arm/mach-lpc32xx/include/mach/gpio.h index 2ba6ca412bef..0052e7a76179 100644 --- a/arch/arm/mach-lpc32xx/include/mach/gpio.h +++ b/arch/arm/mach-lpc32xx/include/mach/gpio.h @@ -3,6 +3,4 @@ #include "gpio-lpc32xx.h" -#define ARCH_NR_GPIOS (LPC32XX_GPO_P3_GRP + LPC32XX_GPO_P3_MAX) - #endif /* __MACH_GPIO_H */ -- GitLab From cb85a9e50817aec997d3cb7488614dac1f27465d Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 14 Jun 2012 16:16:18 +0200 Subject: [PATCH 1618/6849] ARM: LPC32xx: Fix lpc32xx.dtsi status property: "disable" -> "disabled" This patches fixes some status = "disable" strings to "disabled", the correct way of disabling nodes in the devicetree. Signed-off-by: Roland Stigge --- arch/arm/boot/dts/lpc32xx.dtsi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index 34a73f34621c..c5f37fbd33e6 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -35,14 +35,14 @@ slc: flash@20020000 { compatible = "nxp,lpc3220-slc"; reg = <0x20020000 0x1000>; - status = "disable"; + status = "disabled"; }; mlc: flash@200a8000 { compatible = "nxp,lpc3220-mlc"; reg = <0x200a8000 0x11000>; interrupts = <11 0>; - status = "disable"; + status = "disabled"; }; dma@31000000 { @@ -58,21 +58,21 @@ compatible = "nxp,ohci-nxp", "usb-ohci"; reg = <0x31020000 0x300>; interrupts = <0x3b 0>; - status = "disable"; + status = "disabled"; }; usbd@31020000 { compatible = "nxp,lpc3220-udc"; reg = <0x31020000 0x300>; interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>; - status = "disable"; + status = "disabled"; }; clcd@31040000 { compatible = "arm,pl110", "arm,primecell"; reg = <0x31040000 0x1000>; interrupts = <0x0e 0>; - status = "disable"; + status = "disabled"; }; mac: ethernet@31060000 { @@ -261,14 +261,14 @@ compatible = "nxp,lpc3220-adc"; reg = <0x40048000 0x1000>; interrupts = <0x27 0>; - status = "disable"; + status = "disabled"; }; tsc@40048000 { compatible = "nxp,lpc3220-tsc"; reg = <0x40048000 0x1000>; interrupts = <0x27 0>; - status = "disable"; + status = "disabled"; }; key@40050000 { -- GitLab From 1440837440a31672973eedaf632f54c9dfc08c4d Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Tue, 12 Jun 2012 10:23:27 -0300 Subject: [PATCH 1619/6849] ARM: LPC32xx: Build arch dtbs Add ea3250.dtb and phy3250.dtb to the list of dtbs to be built Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/Makefile.boot | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-lpc32xx/Makefile.boot b/arch/arm/mach-lpc32xx/Makefile.boot index 2cfe0ee635c5..697323b5f92d 100644 --- a/arch/arm/mach-lpc32xx/Makefile.boot +++ b/arch/arm/mach-lpc32xx/Makefile.boot @@ -2,3 +2,4 @@ params_phys-y := 0x80000100 initrd_phys-y := 0x82000000 +dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb -- GitLab From 2e0b5a375288d624feb16b58a3af662338a63641 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Tue, 12 Jun 2012 10:34:12 -0300 Subject: [PATCH 1620/6849] ARM: LPC32xx: Add dt settings to the at25 node Add the reg, cs-gpios and max-frequencies that are needed for spi device registry in phy3250. Adds also the pl022 internal transfers details via dt Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/boot/dts/phy3250.dts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index f3bf1493afb0..802ec5b2fd00 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -133,8 +133,29 @@ }; ssp0: ssp@20084000 { + #address-cells = <1>; + #size-cells = <0>; + pl022,num-chipselects = <1>; + cs-gpios = <&gpio 3 5 0>; + eeprom: at25@0 { + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable = <0>; + pl022,com-mode = <0>; + pl022,rx-level-trig = <1>; + pl022,tx-level-trig = <1>; + pl022,ctrl-len = <11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + + at25,byte-len = <0x8000>; + at25,addr-mode = <2>; + at25,page-size = <64>; + compatible = "atmel,at25"; + reg = <0>; + spi-max-frequency = <5000000>; }; }; -- GitLab From c05a8b145cb84e8101a57b6876f14cdb79fa12b8 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Tue, 12 Jun 2012 11:34:28 -0300 Subject: [PATCH 1621/6849] ARM: LPC32xx: Remove spi chipselect request from board init The lpc32xx spi0 chipselect will be requested directly from the pl022 driver Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/phy3250.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 03ee3491b7cf..4ba238395be9 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -359,13 +359,6 @@ static void __init lpc3250_machine_init(void) lpc32xx_auxdata_lookup, NULL); /* Register GPIOs used on this board */ - if (gpio_request(SPI0_CS_GPIO, "spi0 cs")) - printk(KERN_ERR "Error requesting gpio %u", - SPI0_CS_GPIO); - else if (gpio_direction_output(SPI0_CS_GPIO, 1)) - printk(KERN_ERR "Error setting gpio %u to output", - SPI0_CS_GPIO); - if (gpio_request(MMC_PWR_ENABLE_GPIO, "mmc_power_en")) pr_err("Error requesting gpio %u", MMC_PWR_ENABLE_GPIO); else if (gpio_direction_output(MMC_PWR_ENABLE_GPIO, 1)) -- GitLab From 72b78cf713176f376f369df8ccca865c5d51c42b Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Mon, 11 Jun 2012 00:25:15 -0300 Subject: [PATCH 1622/6849] ARM: LPC32xx: Remove spi chip definitions Leave chipselect and spi devices binding to the devicetree Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/phy3250.c | 56 --------------------------------- 1 file changed, 56 deletions(-) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 4ba238395be9..93408883eaca 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -162,24 +162,6 @@ static struct clcd_board lpc32xx_clcd_data = { /* * AMBA SSP (SPI) */ -static void phy3250_spi_cs_set(u32 control) -{ - gpio_set_value(SPI0_CS_GPIO, (int) control); -} - -static struct pl022_config_chip spi0_chip_info = { - .com_mode = INTERRUPT_TRANSFER, - .iface = SSP_INTERFACE_MOTOROLA_SPI, - .hierarchy = SSP_MASTER, - .slave_tx_disable = 0, - .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, - .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, - .ctrl_len = SSP_BITS_8, - .wait_state = SSP_MWIRE_WAIT_ZERO, - .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, - .cs_control = phy3250_spi_cs_set, -}; - static struct pl022_ssp_controller lpc32xx_ssp0_data = { .bus_id = 0, .num_chipselect = 1, @@ -192,44 +174,6 @@ static struct pl022_ssp_controller lpc32xx_ssp1_data = { .enable_dma = 0, }; -/* AT25 driver registration */ -static int __init phy3250_spi_board_register(void) -{ -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) - static struct spi_board_info info[] = { - { - .modalias = "spidev", - .max_speed_hz = 5000000, - .bus_num = 0, - .chip_select = 0, - .controller_data = &spi0_chip_info, - }, - }; - -#else - static struct spi_eeprom eeprom = { - .name = "at25256a", - .byte_len = 0x8000, - .page_size = 64, - .flags = EE_ADDR2, - }; - - static struct spi_board_info info[] = { - { - .modalias = "at25", - .max_speed_hz = 5000000, - .bus_num = 0, - .chip_select = 0, - .mode = SPI_MODE_0, - .platform_data = &eeprom, - .controller_data = &spi0_chip_info, - }, - }; -#endif - return spi_register_board_info(info, ARRAY_SIZE(info)); -} -arch_initcall(phy3250_spi_board_register); - static struct pl08x_channel_data pl08x_slave_channels[] = { { .bus_id = "nand-slc", -- GitLab From 112e9adda4ddcd56895f20c4c886d2493d7907f3 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 13 Jun 2012 19:28:23 -0300 Subject: [PATCH 1623/6849] ARM: LPC32xx: Cleanup board init, remove duplicate clock init Remove SSP0, CLCD and DMA clocks that are already migrated to the clock framework. Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/phy3250.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 93408883eaca..d7389598c21a 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -272,28 +272,11 @@ static void __init lpc3250_machine_init(void) lpc32xx_serial_init(); - /* - * AMBA peripheral clocks need to be enabled prior to AMBA device - * detection or a data fault will occur, so enable the clocks - * here. - */ tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); - tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); - __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), - LPC32XX_CLKPWR_LCDCLK_CTRL); - - tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); - __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), - LPC32XX_CLKPWR_SSP_CLK_CTRL); - - tmp = __raw_readl(LPC32XX_CLKPWR_DMA_CLK_CTRL); - __raw_writel((tmp | LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN), - LPC32XX_CLKPWR_DMA_CLK_CTRL); - /* Test clock needed for UDA1380 initial init */ __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, -- GitLab From 5fe8f11ccb63298bcaab34994c3ca04fd6d30887 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 13 Jun 2012 19:34:25 -0300 Subject: [PATCH 1624/6849] ARM: LPC32xx: Move uart6 irda disable to serial.c Move the irda configuration to serial.c where other special cases are handled Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/phy3250.c | 5 ----- arch/arm/mach-lpc32xx/serial.c | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index d7389598c21a..eb22fbf029ea 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -260,11 +260,6 @@ static void __init lpc3250_machine_init(void) LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE; __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); - /* Disable IrDA pulsing support on UART6 */ - tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); - tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS; - __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); - /* Enable DMA for I2S1 channel */ tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL); tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA; diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c index b5a3f3423f63..05621a29fba2 100644 --- a/arch/arm/mach-lpc32xx/serial.c +++ b/arch/arm/mach-lpc32xx/serial.c @@ -118,6 +118,11 @@ void __init lpc32xx_serial_init(void) __raw_writel(0, LPC32XX_UART_IIR_FCR(puart)); } + /* Disable IrDA pulsing support on UART6 */ + tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); + tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS; + __raw_writel(tmp, LPC32XX_UARTCTL_CTRL); + /* Disable UART5->USB transparent mode or USB won't work */ tmp = __raw_readl(LPC32XX_UARTCTL_CTRL); tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB; -- GitLab From df072717eb0050326f0f63eed98200412c395831 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 13 Jun 2012 19:38:48 -0300 Subject: [PATCH 1625/6849] ARM: LPC32xx: Move i2s1 dma enabling to clock.c Move i2s1 dma init to be done when it's clock is enabled. Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Roland Stigge --- arch/arm/mach-lpc32xx/clock.c | 3 ++- arch/arm/mach-lpc32xx/phy3250.c | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c index 963d12a9fc3d..e8d315e6db09 100644 --- a/arch/arm/mach-lpc32xx/clock.c +++ b/arch/arm/mach-lpc32xx/clock.c @@ -718,7 +718,8 @@ static struct clk clk_i2s1 = { .parent = &clk_hclk, .enable = local_onoff_enable, .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN, + .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN | + LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA, .get_rate = local_return_parent_rate, }; diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index eb22fbf029ea..c1aabfcbde49 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -260,11 +260,6 @@ static void __init lpc3250_machine_init(void) LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE; __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); - /* Enable DMA for I2S1 channel */ - tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL); - tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA; - __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL); - lpc32xx_serial_init(); tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); -- GitLab From f960727e6c98a36018029c0512aa03f1c5faa914 Mon Sep 17 00:00:00 2001 From: Vishal Agarwal Date: Wed, 13 Jun 2012 05:32:43 +0530 Subject: [PATCH 1626/6849] Bluetooth: Fix sending HCI_Disconnect only when connected HCI_Disconnect should only be sent after connection is established. If connection is not yet established and HCI_Disconnect is called then disconnection complete will be received with a handle which does not exist and hence this event will be ignored. But as mgmt.c will not receive this event, its variable for pending command is not cleared.This will result in future Disconnect commands for that BD Address to be blocked with error busy. Signed-off-by: Vishal Agarwal Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 991d5b667674..3e5e3362ea00 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1598,7 +1598,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, else conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); - if (!conn) { + if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, MGMT_STATUS_NOT_CONNECTED); goto failed; -- GitLab From daf67ce8cffd148308ae15c25fb06c1fc20c88f1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Jun 2012 21:35:26 +0300 Subject: [PATCH 1627/6849] iwlwifi: unlock on error path We introduced a lock here in ff1ffb850b ("iwlwifi: fix dynamic loading"). But we missed an error path which needs an unlock. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 095547b37a27..a175997e7829 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -911,8 +911,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) const struct iwl_op_mode_ops *ops = op->ops; drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); - if (!drv->op_mode) + if (!drv->op_mode) { + mutex_unlock(&iwlwifi_opmode_table_mtx); goto out_unbind; + } } else { load_module = true; } -- GitLab From 8d240dd88cca33b704adf3fe281aa64b5aac2dd8 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 29 Mar 2012 19:11:40 +0200 Subject: [PATCH 1628/6849] ftrace: Remove a superfluous check register_ftrace_function() checks ftrace_disabled and calls __register_ftrace_function which does it again. Drop the first check and add the unlikely hint to the second one. Also, drop the label as John correctly notices. No functional change. Link: http://lkml.kernel.org/r/20120329171140.GE6409@aftab Cc: Borislav Petkov Cc: John Kacur Signed-off-by: Borislav Petkov Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index a008663d86c8..b4f20fba09fc 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -312,7 +312,7 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list, static int __register_ftrace_function(struct ftrace_ops *ops) { - if (ftrace_disabled) + if (unlikely(ftrace_disabled)) return -ENODEV; if (FTRACE_WARN_ON(ops == &global_ops)) @@ -4299,16 +4299,12 @@ int register_ftrace_function(struct ftrace_ops *ops) mutex_lock(&ftrace_lock); - if (unlikely(ftrace_disabled)) - goto out_unlock; - ret = __register_ftrace_function(ops); if (!ret) ret = ftrace_startup(ops, 0); - - out_unlock: mutex_unlock(&ftrace_lock); + return ret; } EXPORT_SYMBOL_GPL(register_ftrace_function); -- GitLab From 5da43bed800770906fca24deef7ae3d456823b86 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 31 May 2012 21:28:58 -0400 Subject: [PATCH 1629/6849] tracing: Add comments for the other bits of ftrace_event_call.flags TRACE_EVENT_FL_ENABLED_BIT, TRACE_EVENT_FL_FILTERED_BIT, TRACE_EVENT_FL_RECORDED_CMD_BIT, Have comments about what they are, but: TRACE_EVENT_FL_CAP_ANY_BIT, TRACE_EVENT_FL_NO_SET_FILTER_BIT, TRACE_EVENT_FL_IGNORE_ENABLE_BIT, do not, making them second class citizens. To prevent another class warfare, these bits have protested for their right to be commented. And By Golly! I'll give them what they want! Signed-off-by: Steven Rostedt --- include/linux/ftrace_event.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 176a939d1547..1aff18346c71 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -207,6 +207,9 @@ struct ftrace_event_call { * bit 1: enabled * bit 2: filter_active * bit 3: enabled cmd record + * bit 4: allow trace by non root (cap any) + * bit 5: failed to apply filter + * bit 6: ftrace internal event (do not enable) * * Changes to flags must hold the event_mutex. * -- GitLab From 7374e82771c6d5a9af2080be46f64a5826c7efb1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 31 May 2012 21:40:05 -0400 Subject: [PATCH 1630/6849] tracing: Register the ftrace internal events during early boot All trace events including ftrace internel events (like trace_printk and function tracing), register functions that describe how to print their output. The events may be recorded as soon as the ring buffer is allocated, but they are just raw binary in the buffer. The mapping of event ids to how to print them are held within a structure that is registered on system boot. If a crash happens in boot up before these functions are registered then their output (via ftrace_dump_on_oops) will be useless: Dumping ftrace buffer: --------------------------------- <...>-1 0.... 319705us : Unknown type 6 --------------------------------- This can be quite frustrating for a kernel developer trying to see what is going wrong. There's no reason to register them so late in the boot up process. They can be registered by early_initcall(). Reported-by: Peter Zijlstra Signed-off-by: Steven Rostedt --- kernel/trace/trace_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index df611a0e76c5..123b189c732c 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -1325,4 +1325,4 @@ __init static int init_events(void) return 0; } -device_initcall(init_events); +early_initcall(init_events); -- GitLab From f28fa729149c8b39699f7995ce5fff34c5145a9d Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Thu, 14 Jun 2012 13:11:37 -0700 Subject: [PATCH 1631/6849] [IA64] Port OOM changes to ia64_do_page_fault Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable) The above commits introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable. These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation. Port these changes to ia64. Signed-off-by: Kautuk Consul Signed-off-by: Tony Luck --- arch/ia64/mm/fault.c | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 02d29c2a132a..8443daf4f515 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -72,6 +72,10 @@ mapped_kernel_page_is_present (unsigned long address) return pte_present(pte); } +# define VM_READ_BIT 0 +# define VM_WRITE_BIT 1 +# define VM_EXEC_BIT 2 + void __kprobes ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs) { @@ -81,6 +85,12 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re struct siginfo si; unsigned long mask; int fault; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; + + mask = ((((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT) + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); + + flags |= ((mask & VM_WRITE) ? FAULT_FLAG_WRITE : 0); /* mmap_sem is performance critical.... */ prefetchw(&mm->mmap_sem); @@ -109,6 +119,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re if (notify_page_fault(regs, TRAP_BRKPT)) return; +retry: down_read(&mm->mmap_sem); vma = find_vma_prev(mm, address, &prev_vma); @@ -130,10 +141,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re /* OK, we've got a good vm_area for this memory area. Check the access permissions: */ -# define VM_READ_BIT 0 -# define VM_WRITE_BIT 1 -# define VM_EXEC_BIT 2 - # if (((1 << VM_READ_BIT) != VM_READ || (1 << VM_WRITE_BIT) != VM_WRITE) \ || (1 << VM_EXEC_BIT) != VM_EXEC) # error File is out of sync with . Please update. @@ -142,9 +149,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE)))) goto bad_area; - mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT) - | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); - if ((vma->vm_flags & mask) != mask) goto bad_area; @@ -153,7 +157,11 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re * sure we exit gracefully rather than endlessly redo the * fault. */ - fault = handle_mm_fault(mm, vma, address, (mask & VM_WRITE) ? FAULT_FLAG_WRITE : 0); + fault = handle_mm_fault(mm, vma, address, flags); + + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return; + if (unlikely(fault & VM_FAULT_ERROR)) { /* * We ran out of memory, or some other thing happened @@ -168,10 +176,24 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re } BUG(); } - if (fault & VM_FAULT_MAJOR) - current->maj_flt++; - else - current->min_flt++; + + if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (fault & VM_FAULT_MAJOR) + current->maj_flt++; + else + current->min_flt++; + if (fault & VM_FAULT_RETRY) { + flags &= ~FAULT_FLAG_ALLOW_RETRY; + + /* No need to up_read(&mm->mmap_sem) as we would + * have already released it in __lock_page_or_retry + * in mm/filemap.c. + */ + + goto retry; + } + } + up_read(&mm->mmap_sem); return; -- GitLab From 7b33dc2b050b71de0e202885a26caffbc864d072 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Jun 2012 21:36:09 +0300 Subject: [PATCH 1632/6849] RDMA/ocrdma: Fix off by one in ocrdma_query_gid() The dev->sgid_tbl[] array is allocated in ocrdma_alloc_resources(). It has OCRDMA_MAX_SGID elements so the test here is off by one. Signed-off-by: Dan Carpenter Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index d55d459b7fc8..2e2e7aecc990 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port, dev = get_ocrdma_dev(ibdev); memset(sgid, 0, sizeof(*sgid)); - if (index > OCRDMA_MAX_SGID) + if (index >= OCRDMA_MAX_SGID) return -EINVAL; memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); -- GitLab From 2584f5212d97b664be250ad5700a2d0fee31a10d Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 5 Jun 2012 11:15:50 -0400 Subject: [PATCH 1633/6849] stable: update references to older 2.6 versions for 3.x Also add information on where the respective trees are. Signed-off-by: Paul Gortmaker Acked-by: Rob Landley Signed-off-by: Greg Kroah-Hartman --- Documentation/stable_kernel_rules.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index f0ab5cf28fca..2edf833e8cb5 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -1,4 +1,4 @@ -Everything you ever wanted to know about Linux 2.6 -stable releases. +Everything you ever wanted to know about Linux -stable releases. Rules on what kind of patches are accepted, and which ones are not, into the "-stable" tree: @@ -36,10 +36,10 @@ Procedure for submitting patches to the -stable tree: cherry-picked than this can be specified in the following format in the sign-off area: - Cc: # .32.x: a1f84a3: sched: Check for idle - Cc: # .32.x: 1b9508f: sched: Rate-limit newidle - Cc: # .32.x: fd21073: sched: Fix affinity logic - Cc: # .32.x + Cc: # 3.3.x: a1f84a3: sched: Check for idle + Cc: # 3.3.x: 1b9508f: sched: Rate-limit newidle + Cc: # 3.3.x: fd21073: sched: Fix affinity logic + Cc: # 3.3.x Signed-off-by: Ingo Molnar The tag sequence has the meaning of: @@ -73,6 +73,15 @@ Review cycle: security kernel team, and not go through the normal review cycle. Contact the kernel security team for more details on this procedure. +Trees: + + - The queues of patches, for both completed versions and in progress + versions can be found at: + http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git + - The finalized and tagged releases of all stable kernels can be found + in separate branches per version at: + http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git + Review committee: -- GitLab From be3a07f71ca3ae300d652a653279321e85b9f3d0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 16:14:38 +0100 Subject: [PATCH 1634/6849] Extcon: Staticise extcon_class It's not referenced outside the core file. Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index f598a700ec15..99f7227834e3 100644 --- a/drivers/extcon/extcon_class.c +++ b/drivers/extcon/extcon_class.c @@ -65,7 +65,7 @@ const char *extcon_cable_name[] = { NULL, }; -struct class *extcon_class; +static struct class *extcon_class; #if defined(CONFIG_ANDROID) static struct class_compat *switch_class; #endif /* CONFIG_ANDROID */ -- GitLab From 6e7b4a59b3d7bb2dcd11c019354bf0c91037dadd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 9 Jun 2012 15:02:59 -0700 Subject: [PATCH 1635/6849] driver core: fix some kernel-doc warnings in dma*.c Fix kernel-doc warnings in drivers/base/dma*.c: Warning(drivers/base/dma-buf.c:498): No description found for parameter 'vaddr' Warning(drivers/base/dma-coherent.c:199): No description found for parameter 'ret' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/base/dma-buf.c | 1 + drivers/base/dma-coherent.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 24e88fe29ec1..c30f3e1d0efc 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -493,6 +493,7 @@ EXPORT_SYMBOL_GPL(dma_buf_vmap); /** * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap. * @dmabuf: [in] buffer to vunmap + * @vaddr: [in] vmap to vunmap */ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) { diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 1b85949e3d2f..560a7173f810 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -186,6 +186,7 @@ EXPORT_SYMBOL(dma_release_from_coherent); * @vma: vm_area for the userspace memory * @vaddr: cpu address returned by dma_alloc_from_coherent * @size: size of the memory buffer allocated by dma_alloc_from_coherent + * @ret: result from remap_pfn_range() * * This checks whether the memory was allocated from the per-device * coherent memory pool and if so, maps that memory to the provided vma. -- GitLab From c3b15452e253ab0629cd9e400d3fb6d76c76cb73 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 16:43:53 +0100 Subject: [PATCH 1636/6849] Extcon: Don't try to create duplicate link names We can't create a link from the device to the compatibility switch class since we already create a link from the device to to the extcon class object and we try to use the same name for both links. This causes a loud complaint from sysfs on boot. Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index f598a700ec15..159aeb07b3ba 100644 --- a/drivers/extcon/extcon_class.c +++ b/drivers/extcon/extcon_class.c @@ -762,7 +762,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev) #if defined(CONFIG_ANDROID) if (switch_class) ret = class_compat_create_link(switch_class, edev->dev, - dev); + NULL); #endif /* CONFIG_ANDROID */ spin_lock_init(&edev->lock); -- GitLab From 1bd289d1e8e29c09be0e783a53f16a1dc80684be Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Thu, 14 Jun 2012 15:57:01 +0200 Subject: [PATCH 1637/6849] vme: change maintainer e-mail address This changes my e-mail address from my work address to my personal one as I finish my contract with CERN at the end of June 2012. I will continue helping with maintaining the VME driver regardless. Signed-off-by: Manohar Vanga Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 14bc7071f9df..bc610ae361f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7413,7 +7413,7 @@ F: include/linux/vlynq.h VME SUBSYSTEM M: Martyn Welch -M: Manohar Vanga +M: Manohar Vanga M: Greg Kroah-Hartman L: devel@driverdev.osuosl.org S: Maintained -- GitLab From 98dcd59dd063dd8099d8dbccd84a40e927dc7138 Mon Sep 17 00:00:00 2001 From: "Camuso, Tony" Date: Sun, 10 Jun 2012 14:39:20 +0100 Subject: [PATCH 1638/6849] misc: hpilo: increase number of max supported channels Increase number of supported channels from 8 to 24. Make the number of channels configurable via module parameter max_ccb. Signed-off-by: Mark Rusk Signed-off-by: Tony Camuso Signed-off-by: Greg Kroah-Hartman --- drivers/misc/hpilo.c | 33 +++++++++++++++++++++------------ drivers/misc/hpilo.h | 4 +++- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index fffc227181b0..6df0da4085e3 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -30,6 +30,7 @@ static struct class *ilo_class; static unsigned int ilo_major; +static unsigned int max_ccb = MIN_CCB; static char ilo_hwdev[MAX_ILO_DEV]; static inline int get_entry_id(int entry) @@ -424,7 +425,7 @@ static void ilo_set_reset(struct ilo_hwinfo *hw) * Mapped memory is zeroed on ilo reset, so set a per ccb flag * to indicate that this ccb needs to be closed and reopened. */ - for (slot = 0; slot < MAX_CCB; slot++) { + for (slot = 0; slot < max_ccb; slot++) { if (!hw->ccb_alloc[slot]) continue; set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb); @@ -535,7 +536,7 @@ static int ilo_close(struct inode *ip, struct file *fp) struct ilo_hwinfo *hw; unsigned long flags; - slot = iminor(ip) % MAX_CCB; + slot = iminor(ip) % max_ccb; hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); spin_lock(&hw->open_lock); @@ -566,7 +567,7 @@ static int ilo_open(struct inode *ip, struct file *fp) struct ilo_hwinfo *hw; unsigned long flags; - slot = iminor(ip) % MAX_CCB; + slot = iminor(ip) % max_ccb; hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); /* new ccb allocation */ @@ -663,7 +664,7 @@ static irqreturn_t ilo_isr(int irq, void *data) ilo_set_reset(hw); } - for (i = 0; i < MAX_CCB; i++) { + for (i = 0; i < max_ccb; i++) { if (!hw->ccb_alloc[i]) continue; if (pending & (1 << i)) @@ -697,14 +698,14 @@ static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) } /* map the adapter shared memory region */ - hw->ram_vaddr = pci_iomap(pdev, 2, MAX_CCB * ILOHW_CCB_SZ); + hw->ram_vaddr = pci_iomap(pdev, 2, max_ccb * ILOHW_CCB_SZ); if (hw->ram_vaddr == NULL) { dev_err(&pdev->dev, "Error mapping shared mem\n"); goto mmio_free; } /* map the doorbell aperture */ - hw->db_vaddr = pci_iomap(pdev, 3, MAX_CCB * ONE_DB_SIZE); + hw->db_vaddr = pci_iomap(pdev, 3, max_ccb * ONE_DB_SIZE); if (hw->db_vaddr == NULL) { dev_err(&pdev->dev, "Error mapping doorbell\n"); goto ram_free; @@ -727,7 +728,7 @@ static void ilo_remove(struct pci_dev *pdev) clear_device(ilo_hw); minor = MINOR(ilo_hw->cdev.dev); - for (i = minor; i < minor + MAX_CCB; i++) + for (i = minor; i < minor + max_ccb; i++) device_destroy(ilo_class, MKDEV(ilo_major, i)); cdev_del(&ilo_hw->cdev); @@ -737,7 +738,7 @@ static void ilo_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); kfree(ilo_hw); - ilo_hwdev[(minor / MAX_CCB)] = 0; + ilo_hwdev[(minor / max_ccb)] = 0; } static int __devinit ilo_probe(struct pci_dev *pdev, @@ -746,6 +747,11 @@ static int __devinit ilo_probe(struct pci_dev *pdev, int devnum, minor, start, error; struct ilo_hwinfo *ilo_hw; + if (max_ccb > MAX_CCB) + max_ccb = MAX_CCB; + else if (max_ccb < MIN_CCB) + max_ccb = MIN_CCB; + /* find a free range for device files */ for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) { if (ilo_hwdev[devnum] == 0) { @@ -795,14 +801,14 @@ static int __devinit ilo_probe(struct pci_dev *pdev, cdev_init(&ilo_hw->cdev, &ilo_fops); ilo_hw->cdev.owner = THIS_MODULE; - start = devnum * MAX_CCB; - error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB); + start = devnum * max_ccb; + error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), max_ccb); if (error) { dev_err(&pdev->dev, "Could not add cdev\n"); goto remove_isr; } - for (minor = 0 ; minor < MAX_CCB; minor++) { + for (minor = 0 ; minor < max_ccb; minor++) { struct device *dev; dev = device_create(ilo_class, &pdev->dev, MKDEV(ilo_major, minor), NULL, @@ -879,11 +885,14 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("1.2"); +MODULE_VERSION("1.3"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli "); MODULE_LICENSE("GPL v2"); +module_param(max_ccb, uint, 0444); +MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8)"); + module_init(ilo_init); module_exit(ilo_exit); diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index 54e43adbdea1..b97672e0cf90 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h @@ -14,7 +14,9 @@ #define ILO_NAME "hpilo" /* max number of open channel control blocks per device, hw limited to 32 */ -#define MAX_CCB 8 +#define MAX_CCB 24 +/* min number of open channel control blocks per device, hw limited to 32 */ +#define MIN_CCB 8 /* max number of supported devices */ #define MAX_ILO_DEV 1 /* max number of files */ -- GitLab From 002176db8113c92d0bda02a47e3d2a4b8f9f55ea Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Thu, 14 Jun 2012 09:59:23 -0300 Subject: [PATCH 1639/6849] misc: at25: Parse dt settings This adds dt support to the at25 eeprom driver. Signed-off-by: Alexandre Pereira da Silva Tested-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/misc/at25.txt | 21 +++++++ drivers/misc/eeprom/at25.c | 61 ++++++++++++++----- 2 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 Documentation/devicetree/bindings/misc/at25.txt diff --git a/Documentation/devicetree/bindings/misc/at25.txt b/Documentation/devicetree/bindings/misc/at25.txt new file mode 100644 index 000000000000..ab3c327929dd --- /dev/null +++ b/Documentation/devicetree/bindings/misc/at25.txt @@ -0,0 +1,21 @@ +Atmel AT25 eeprom + +Required properties: +- compatible : "atmel,at25". +- reg : chip select number +- spi-max-frequency : max spi frequency to use + +- at25,byte-len : total eeprom size in bytes +- at25,addr-mode : addr-mode flags, as defined in include/linux/spi/eeprom.h +- at25,page-size : size of the eeprom page + +Examples: +at25@0 { + compatible = "atmel,at25"; + reg = <0> + spi-max-frequency = <5000000>; + + at25,byte-len = <0x8000>; + at25,addr-mode = <2>; + at25,page-size = <64>; +}; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 0842c2994ee2..25003d6ceb56 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -19,7 +19,7 @@ #include #include - +#include /* * NOTE: this is an *EEPROM* driver. The vagaries of product naming @@ -305,25 +305,54 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf, static int at25_probe(struct spi_device *spi) { struct at25_data *at25 = NULL; - const struct spi_eeprom *chip; + struct spi_eeprom chip; + struct device_node *np = spi->dev.of_node; int err; int sr; int addrlen; /* Chip description */ - chip = spi->dev.platform_data; - if (!chip) { - dev_dbg(&spi->dev, "no chip description\n"); - err = -ENODEV; - goto fail; - } + if (!spi->dev.platform_data) { + if (np) { + u32 val; + + memset(&chip, 0, sizeof(chip)); + strncpy(chip.name, np->name, 10); + + err = of_property_read_u32(np, "at25,byte-len", &val); + if (err) { + dev_dbg(&spi->dev, "invalid chip dt description\n"); + goto fail; + } + chip.byte_len = val; + + err = of_property_read_u32(np, "at25,addr-mode", &val); + if (err) { + dev_dbg(&spi->dev, "invalid chip dt description\n"); + goto fail; + } + chip.flags = (u16)val; + + err = of_property_read_u32(np, "at25,page-size", &val); + if (err) { + dev_dbg(&spi->dev, "invalid chip dt description\n"); + goto fail; + } + chip.page_size = (u16)val; + } else { + dev_dbg(&spi->dev, "no chip description\n"); + err = -ENODEV; + goto fail; + } + } else + chip = *(struct spi_eeprom *)spi->dev.platform_data; /* For now we only support 8/16/24 bit addressing */ - if (chip->flags & EE_ADDR1) + if (chip.flags & EE_ADDR1) addrlen = 1; - else if (chip->flags & EE_ADDR2) + else if (chip.flags & EE_ADDR2) addrlen = 2; - else if (chip->flags & EE_ADDR3) + else if (chip.flags & EE_ADDR3) addrlen = 3; else { dev_dbg(&spi->dev, "unsupported address type\n"); @@ -348,7 +377,7 @@ static int at25_probe(struct spi_device *spi) } mutex_init(&at25->lock); - at25->chip = *chip; + at25->chip = chip; at25->spi = spi_dev_get(spi); dev_set_drvdata(&spi->dev, at25); at25->addrlen = addrlen; @@ -369,7 +398,7 @@ static int at25_probe(struct spi_device *spi) at25->mem.read = at25_mem_read; at25->bin.size = at25->chip.byte_len; - if (!(chip->flags & EE_READONLY)) { + if (!(chip.flags & EE_READONLY)) { at25->bin.write = at25_bin_write; at25->bin.attr.mode |= S_IWUSR; at25->mem.write = at25_mem_write; @@ -379,8 +408,8 @@ static int at25_probe(struct spi_device *spi) if (err) goto fail; - if (chip->setup) - chip->setup(&at25->mem, chip->context); + if (chip.setup) + chip.setup(&at25->mem, chip.context); dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n", (at25->bin.size < 1024) @@ -388,7 +417,7 @@ static int at25_probe(struct spi_device *spi) : (at25->bin.size / 1024), (at25->bin.size < 1024) ? "Byte" : "KByte", at25->chip.name, - (chip->flags & EE_READONLY) ? " (readonly)" : "", + (chip.flags & EE_READONLY) ? " (readonly)" : "", at25->chip.page_size); return 0; fail: -- GitLab From d7be394f7c2869e22d2258a1bba257661ca3fc52 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 6 Jun 2012 21:05:48 +0200 Subject: [PATCH 1640/6849] staging: zcache: don't limit number of pools per client Currently the amount of pools each client can use is limited to 16, this is and arbitrary limit which isn't really required by current implementation. This places and arbitrary limit on the number of mounted filesystems that can use cleancache. This patch removes that limit and uses IDR to do sparse mapping of pools in each client. Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 38 +++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index d0141fbc649e..174861f93b42 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "tmem.h" #include "../zsmalloc/zsmalloc.h" @@ -53,15 +54,13 @@ (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) #endif -#define MAX_POOLS_PER_CLIENT 16 - #define MAX_CLIENTS 16 #define LOCAL_CLIENT ((uint16_t)-1) MODULE_LICENSE("GPL"); struct zcache_client { - struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; + struct idr tmem_pools; struct zs_pool *zspool; bool allocated; atomic_t refcount; @@ -949,11 +948,9 @@ static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid) goto out; atomic_inc(&cli->refcount); } - if (poolid < MAX_POOLS_PER_CLIENT) { - pool = cli->tmem_pools[poolid]; - if (pool != NULL) - atomic_inc(&pool->refcount); - } + pool = idr_find(&cli->tmem_pools, poolid); + if (pool != NULL) + atomic_inc(&pool->refcount); out: return pool; } @@ -987,6 +984,7 @@ int zcache_new_client(uint16_t cli_id) cli->zspool = zs_create_pool("zcache", ZCACHE_GFP_MASK); if (cli->zspool == NULL) goto out; + idr_init(&cli->tmem_pools); #endif ret = 0; out: @@ -1673,10 +1671,10 @@ static int zcache_destroy_pool(int cli_id, int pool_id) if (cli == NULL) goto out; atomic_inc(&cli->refcount); - pool = cli->tmem_pools[pool_id]; + pool = idr_find(&cli->tmem_pools, pool_id); if (pool == NULL) goto out; - cli->tmem_pools[pool_id] = NULL; + idr_remove(&cli->tmem_pools, pool_id); /* wait for pool activity on other cpus to quiesce */ while (atomic_read(&pool->refcount) != 0) ; @@ -1696,6 +1694,7 @@ static int zcache_new_pool(uint16_t cli_id, uint32_t flags) int poolid = -1; struct tmem_pool *pool; struct zcache_client *cli = NULL; + int r; if (cli_id == LOCAL_CLIENT) cli = &zcache_host; @@ -1710,20 +1709,25 @@ static int zcache_new_pool(uint16_t cli_id, uint32_t flags) goto out; } - for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) - if (cli->tmem_pools[poolid] == NULL) - break; - if (poolid >= MAX_POOLS_PER_CLIENT) { - pr_info("zcache: pool creation failed: max exceeded\n"); + do { + r = idr_pre_get(&cli->tmem_pools, GFP_ATOMIC); + if (r != 1) { + kfree(pool); + pr_info("zcache: pool creation failed: out of memory\n"); + goto out; + } + r = idr_get_new(&cli->tmem_pools, pool, &poolid); + } while (r == -EAGAIN); + if (r) { + pr_info("zcache: pool creation failed: error %d\n", r); kfree(pool); - poolid = -1; goto out; } + atomic_set(&pool->refcount, 0); pool->client = cli; pool->pool_id = poolid; tmem_new_pool(pool, flags); - cli->tmem_pools[poolid] = pool; pr_info("zcache: created %s tmem pool, id=%d, client=%d\n", flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", poolid, cli_id); -- GitLab From 985eb50d553f4e2609778f999ecc5ec9837152f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 18:09:51 -0700 Subject: [PATCH 1641/6849] staging: comedi: ni_atmio16d: remove the function tracing debug These printk's are #ifdef'ed out with an undefined symbol anyway. Just remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio16d.c | 24 ++------------------ 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 95bee84b78ae..87992c99d413 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -236,10 +236,6 @@ static irqreturn_t atmio16d_interrupt(int irq, void *d) struct comedi_device *dev = d; struct comedi_subdevice *s = dev->subdevices + 0; -#ifdef DEBUG1 - printk(KERN_DEBUG "atmio16d_interrupt!\n"); -#endif - comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG)); comedi_event(dev, s); @@ -251,9 +247,7 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0, tmp; -#ifdef DEBUG1 - printk(KERN_DEBUG "atmio16d_ai_cmdtest\n"); -#endif + /* make sure triggers are valid */ tmp = cmd->start_src; cmd->start_src &= TRIG_NOW; @@ -355,9 +349,7 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, unsigned int timer, base_clock; unsigned int sample_count, tmp, chan, gain; int i; -#ifdef DEBUG1 - printk(KERN_DEBUG "atmio16d_ai_cmd\n"); -#endif + /* This is slowly becoming a working command interface. * * It is still uber-experimental */ @@ -517,9 +509,6 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev, int gain; int status; -#ifdef DEBUG1 - printk(KERN_DEBUG "atmio16d_ai_insn_read\n"); -#endif chan = CR_CHAN(insn->chanspec); gain = CR_RANGE(insn->chanspec); @@ -538,9 +527,6 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev, for (t = 0; t < ATMIO16D_TIMEOUT; t++) { /* check conversion status */ status = inw(dev->iobase + STAT_REG); -#ifdef DEBUG1 - printk(KERN_DEBUG "status=%x\n", status); -#endif if (status & STAT_AD_CONVAVAIL) { /* read the data now */ data[i] = inw(dev->iobase + AD_FIFO_REG); @@ -572,9 +558,6 @@ static int atmio16d_ao_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { int i; -#ifdef DEBUG1 - printk(KERN_DEBUG "atmio16d_ao_insn_read\n"); -#endif for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; @@ -588,9 +571,6 @@ static int atmio16d_ao_insn_write(struct comedi_device *dev, int i; int chan; int d; -#ifdef DEBUG1 - printk(KERN_DEBUG "atmio16d_ao_insn_write\n"); -#endif chan = CR_CHAN(insn->chanspec); -- GitLab From 2b8557a734ab17d2cbb96a79bc267b30055e0ef3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 17:50:53 -0700 Subject: [PATCH 1642/6849] staging: comedi: pcl816: remove unneeded tests in pcl816_ai_cmdtest The step 2 tests of the start_src, scan_begin_src, and scan_end_src triggers to make sure they are unique are not needed. These triggers all only have one source and it was trivially validated in step 1. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index c3ee6d69b9a6..ba6911f063cb 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -493,26 +493,11 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, * are unique and mutually compatible */ - if (cmd->start_src != TRIG_NOW) { - cmd->start_src = TRIG_NOW; - err++; - } - - if (cmd->scan_begin_src != TRIG_FOLLOW) { - cmd->scan_begin_src = TRIG_FOLLOW; - err++; - } - if (cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_TIMER) { cmd->convert_src = TRIG_TIMER; err++; } - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; -- GitLab From f7f111c214f218483a23d40a1f8e2d798b6e130a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 17:41:35 -0700 Subject: [PATCH 1643/6849] staging: comedi: pcl818: remove unneeded tests in ai_cmdtest The step 2 tests of the start_src, scan_begin_src, and scan_end_src triggers to make sure they are unique are not needed. These triggers all only have one source and it was trivially validated in step 1. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 66b2570fb24e..786c3b6442a6 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1299,22 +1299,9 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* step 2: make sure trigger sources are unique and mutually compatible */ - if (cmd->start_src != TRIG_NOW) { - cmd->start_src = TRIG_NOW; - err++; - } - if (cmd->scan_begin_src != TRIG_FOLLOW) { - cmd->scan_begin_src = TRIG_FOLLOW; - err++; - } if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) err++; - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; -- GitLab From 31a4590ee31f2b46d28a4b85f84b04e90fa7ae00 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 17:58:07 -0700 Subject: [PATCH 1644/6849] staging: comedi: pcl812: remove unneeded tests in pcl812_ai_cmdtest The step 2 tests to make sure that the triggers are unique is not needed for single source triggers. These were already trivially validated in step 1. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 27 ------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 0a4074af8a60..511c90136439 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -612,33 +612,6 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, * unique and mutually compatible */ - if (cmd->start_src != TRIG_NOW) { - cmd->start_src = TRIG_NOW; - err++; - } - - if (cmd->scan_begin_src != TRIG_FOLLOW) { - cmd->scan_begin_src = TRIG_FOLLOW; - err++; - } - - if (devpriv->use_ext_trg) { - if (cmd->convert_src != TRIG_EXT) { - cmd->convert_src = TRIG_EXT; - err++; - } - } else { - if (cmd->convert_src != TRIG_TIMER) { - cmd->convert_src = TRIG_TIMER; - err++; - } - } - - if (cmd->scan_end_src != TRIG_COUNT) { - cmd->scan_end_src = TRIG_COUNT; - err++; - } - if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; -- GitLab From 23bcbb6495d04df086450e0751fc9b9fd5e98936 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 18:22:07 -0700 Subject: [PATCH 1645/6849] staging: comedi: pcl812: remove PCL812_EXTDEBUG define and related code The PCL812_EXTDEBUG define enables a bunch of function tracing debug messages as well as a dump of the comedi_cmd info during the cmdtest. There are better ways to do the function tracing and the cmdtest dump shouldn't be in the driver. Just remove all of it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 100 +----------------------- 1 file changed, 4 insertions(+), 96 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 511c90136439..b0eb2ab89fd8 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -119,9 +119,6 @@ #include "8253.h" -/* if this is defined then a lot of messages is printed */ -#undef PCL812_EXTDEBUG - /* hardware types of the cards */ #define boardPCL812PG 0 /* and ACL-8112PG */ #define boardPCL813B 1 @@ -534,24 +531,6 @@ static int pcl812_do_insn_bits(struct comedi_device *dev, return 2; } -#ifdef PCL812_EXTDEBUG -/* -============================================================================== -*/ -static void pcl812_cmdtest_out(int e, struct comedi_cmd *cmd) -{ - printk(KERN_INFO "pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e, - cmd->start_src, cmd->scan_begin_src, cmd->convert_src); - printk(KERN_INFO "pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e, - cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg); - printk(KERN_INFO "pcl812 e=%d stopsrc=%x scanend=%x\n", e, - cmd->stop_src, cmd->scan_end_src); - printk(KERN_INFO "pcl812 e=%d stoparg=%d scanendarg=%d " - "chanlistlen=%d\n", e, cmd->stop_arg, cmd->scan_end_arg, - cmd->chanlist_len); -} -#endif - /* ============================================================================== */ @@ -562,10 +541,6 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp, divisor1, divisor2; -#ifdef PCL812_EXTDEBUG - printk("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...)\n"); - pcl812_cmdtest_out(-1, cmd); -#endif /* step 1: make sure trigger sources are trivially valid */ tmp = cmd->start_src; @@ -597,15 +572,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, if (!cmd->stop_src || tmp != cmd->stop_src) err++; - if (err) { -#ifdef PCL812_EXTDEBUG - pcl812_cmdtest_out(1, cmd); - printk - ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=1\n", - err); -#endif + if (err) return 1; - } /* * step 2: make sure trigger sources are @@ -615,15 +583,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) err++; - if (err) { -#ifdef PCL812_EXTDEBUG - pcl812_cmdtest_out(2, cmd); - printk - ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=2\n", - err); -#endif + if (err) return 2; - } /* step 3: make sure arguments are trivially compatible */ @@ -673,15 +634,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, } } - if (err) { -#ifdef PCL812_EXTDEBUG - pcl812_cmdtest_out(3, cmd); - printk - ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=3\n", - err); -#endif + if (err) return 3; - } /* step 4: fix up any arguments */ @@ -696,14 +650,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, err++; } - if (err) { -#ifdef PCL812_EXTDEBUG - printk - ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=4\n", - err); -#endif + if (err) return 4; - } return 0; } @@ -717,10 +665,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes; struct comedi_cmd *cmd = &s->async->cmd; -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n"); -#endif - if (cmd->start_src != TRIG_NOW) return -EINVAL; if (cmd->scan_begin_src != TRIG_FOLLOW) @@ -844,13 +788,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]); release_dma_lock(dma_flags); enable_dma(devpriv->dma); -#ifdef PCL812_EXTDEBUG - printk - ("pcl812 EDBG: DMA %d PTR 0x%0x/0x%0x LEN %u/%u EOS %d\n", - devpriv->dma, devpriv->hwdmaptr[0], - devpriv->hwdmaptr[1], devpriv->dmabytestomove[0], - devpriv->dmabytestomove[1], devpriv->ai_eos); -#endif } switch (cmd->convert_src) { @@ -864,10 +801,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) else /* let's go! */ outb(devpriv->mode_reg_int | 6, dev->iobase + PCL812_MODE); -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: END: pcl812_ai_cmd(...)\n"); -#endif - return 0; } @@ -987,9 +920,6 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) int len, bufptr; short *ptr; -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n"); -#endif ptr = (short *)devpriv->dmabuf[devpriv->next_dma_buf]; len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) - devpriv->ai_poll_ptr; @@ -1022,9 +952,6 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) transfer_from_dma_buf(dev, s, ptr, bufptr, len); -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: END: interrupt_pcl812_ai_dma(...)\n"); -#endif return IRQ_HANDLED; } @@ -1141,10 +1068,6 @@ static void setup_range_channel(struct comedi_device *dev, static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, unsigned int divisor2) { -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, - divisor1, divisor2); -#endif outb(0xb4, dev->iobase + PCL812_CTRCTL); outb(0x74, dev->iobase + PCL812_CTRCTL); udelay(1); @@ -1155,9 +1078,6 @@ static void start_pacer(struct comedi_device *dev, int mode, outb(divisor1 & 0xff, dev->iobase + PCL812_CTR1); outb((divisor1 >> 8) & 0xff, dev->iobase + PCL812_CTR1); } -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: END: start_pacer(...)\n"); -#endif } /* @@ -1187,9 +1107,6 @@ static void free_resources(struct comedi_device *dev) static int pcl812_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n"); -#endif if (devpriv->ai_dma) disable_dma(devpriv->dma); outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */ @@ -1197,9 +1114,6 @@ static int pcl812_ai_cancel(struct comedi_device *dev, outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE); start_pacer(dev, -1, 0, 0); /* stop 8254 */ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */ -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: END: pcl812_ai_cancel(...)\n"); -#endif return 0; } @@ -1210,9 +1124,6 @@ static void pcl812_reset(struct comedi_device *dev) { const struct pcl812_board *board = comedi_board(dev); -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: BGN: pcl812_reset(...)\n"); -#endif outb(0, dev->iobase + PCL812_MUX); outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN); devpriv->old_chan_reg = -1; /* invalidate chain/gain memory */ @@ -1242,9 +1153,6 @@ static void pcl812_reset(struct comedi_device *dev) break; } udelay(5); -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "pcl812 EDBG: END: pcl812_reset(...)\n"); -#endif } static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) -- GitLab From 1d489bab6651cfda44ddcb2ae0543ccf3cbd5400 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 19:12:18 -0700 Subject: [PATCH 1646/6849] staging: comedi: me4000: remove CALL_PDEBUG macro The CALL_PDEBUG macro is used to do function tracing in the driver. There are better ways to do this. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 61 ------------------------- drivers/staging/comedi/drivers/me4000.h | 8 ---- 2 files changed, 69 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index aae01f10b1c3..f5a0bcf65cf5 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -163,8 +163,6 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) int result, i; struct me4000_board *board; - CALL_PDEBUG("In me4000_probe()\n"); - /* Allocate private memory */ if (alloc_private(dev, sizeof(struct me4000_info)) < 0) return -ENOMEM; @@ -308,9 +306,6 @@ found: static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p) { - - CALL_PDEBUG("In get_registers()\n"); - /*--------------------------- plx regbase -------------------------------*/ info->plx_regbase = pci_resource_start(pci_dev_p, 1); @@ -362,8 +357,6 @@ static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p) { int result; - CALL_PDEBUG("In init_board_info()\n"); - /* Init spin locks */ /* spin_lock_init(&info->preload_lock); */ /* spin_lock_init(&info->ai_ctrl_lock); */ @@ -394,8 +387,6 @@ static int init_ao_context(struct comedi_device *dev) { int i; - CALL_PDEBUG("In init_ao_context()\n"); - for (i = 0; i < thisboard->ao.count; i++) { /* spin_lock_init(&info->ao_context[i].use_lock); */ info->ao_context[i].irq = info->irq; @@ -475,9 +466,6 @@ static int init_ao_context(struct comedi_device *dev) static int init_ai_context(struct comedi_device *dev) { - - CALL_PDEBUG("In init_ai_context()\n"); - info->ai_context.irq = info->irq; info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG; @@ -509,9 +497,6 @@ static int init_ai_context(struct comedi_device *dev) static int init_dio_context(struct comedi_device *dev) { - - CALL_PDEBUG("In init_dio_context()\n"); - info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG; info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG; info->dio_context.port_0_reg = @@ -528,9 +513,6 @@ static int init_dio_context(struct comedi_device *dev) static int init_cnt_context(struct comedi_device *dev) { - - CALL_PDEBUG("In init_cnt_context()\n"); - info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG; info->cnt_context.counter_0_reg = info->timer_regbase + ME4000_CNT_COUNTER_0_REG; @@ -554,8 +536,6 @@ static int xilinx_download(struct comedi_device *dev) int idx = 0; int size = 0; - CALL_PDEBUG("In xilinx_download()\n"); - init_waitqueue_head(&queue); /* @@ -634,8 +614,6 @@ static int reset_board(struct comedi_device *dev) { unsigned long icr; - CALL_PDEBUG("In reset_board()\n"); - /* Make a hardware reset */ icr = me4000_inl(dev, info->plx_regbase + PLX_ICR); icr |= 0x40000000; @@ -708,8 +686,6 @@ static int me4000_ai_insn_read(struct comedi_device *dev, unsigned long tmp; long lval; - CALL_PDEBUG("In me4000_ai_insn_read()\n"); - if (insn->n == 0) { return 0; } else if (insn->n > 1) { @@ -827,8 +803,6 @@ static int me4000_ai_cancel(struct comedi_device *dev, { unsigned long tmp; - CALL_PDEBUG("In me4000_ai_cancel()\n"); - /* Stop any running conversion */ tmp = me4000_inl(dev, info->ai_context.ctrl_reg); tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); @@ -846,8 +820,6 @@ static int ai_check_chanlist(struct comedi_device *dev, int aref; int i; - CALL_PDEBUG("In ai_check_chanlist()\n"); - /* Check whether a channel list is available */ if (!cmd->chanlist_len) { printk(KERN_ERR @@ -933,8 +905,6 @@ static int ai_round_cmd_args(struct comedi_device *dev, int rest; - CALL_PDEBUG("In ai_round_cmd_args()\n"); - *init_ticks = 0; *scan_ticks = 0; *chan_ticks = 0; @@ -994,9 +964,6 @@ static void ai_write_timer(struct comedi_device *dev, unsigned int init_ticks, unsigned int scan_ticks, unsigned int chan_ticks) { - - CALL_PDEBUG("In ai_write_timer()\n"); - me4000_outl(dev, init_ticks - 1, info->ai_context.scan_pre_timer_low_reg); me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg); @@ -1020,8 +987,6 @@ static int ai_prepare(struct comedi_device *dev, unsigned long tmp = 0; - CALL_PDEBUG("In ai_prepare()\n"); - /* Write timer arguments */ ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks); @@ -1089,8 +1054,6 @@ static int ai_write_chanlist(struct comedi_device *dev, unsigned int aref; int i; - CALL_PDEBUG("In ai_write_chanlist()\n"); - for (i = 0; i < cmd->chanlist_len; i++) { chan = CR_CHAN(cmd->chanlist[i]); rang = CR_RANGE(cmd->chanlist[i]); @@ -1127,8 +1090,6 @@ static int me4000_ai_do_cmd(struct comedi_device *dev, unsigned int chan_ticks = 0; struct comedi_cmd *cmd = &s->async->cmd; - CALL_PDEBUG("In me4000_ai_do_cmd()\n"); - /* Reset the analog input */ err = me4000_ai_cancel(dev, s); if (err) @@ -1173,8 +1134,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, unsigned int scan_ticks; int err = 0; - CALL_PDEBUG("In me4000_ai_do_cmd_test()\n"); - PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev); PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags); PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n", @@ -1717,8 +1676,6 @@ static int me4000_ao_insn_write(struct comedi_device *dev, int aref = CR_AREF(insn->chanspec); unsigned long tmp; - CALL_PDEBUG("In me4000_ao_insn_write()\n"); - if (insn->n == 0) { return 0; } else if (insn->n > 1) { @@ -1794,9 +1751,6 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - - CALL_PDEBUG("In me4000_dio_insn_bits()\n"); - /* Length of data must be 2 (mask and new data, see below) */ if (insn->n == 0) return 0; @@ -1851,8 +1805,6 @@ static int me4000_dio_insn_config(struct comedi_device *dev, unsigned long tmp; int chan = CR_CHAN(insn->chanspec); - CALL_PDEBUG("In me4000_dio_insn_config()\n"); - switch (data[0]) { default: return -EINVAL; @@ -1948,9 +1900,6 @@ static int me4000_dio_insn_config(struct comedi_device *dev, static int cnt_reset(struct comedi_device *dev, unsigned int channel) { - - CALL_PDEBUG("In cnt_reset()\n"); - switch (channel) { case 0: me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg); @@ -1982,8 +1931,6 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel, { int tmp = 0; - CALL_PDEBUG("In cnt_config()\n"); - switch (channel) { case 0: tmp |= ME4000_CNT_COUNTER_0; @@ -2041,8 +1988,6 @@ static int me4000_cnt_insn_config(struct comedi_device *dev, int err; - CALL_PDEBUG("In me4000_cnt_insn_config()\n"); - switch (data[0]) { case GPCT_RESET: if (insn->n != 1) { @@ -2087,8 +2032,6 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, unsigned short tmp; - CALL_PDEBUG("In me4000_cnt_insn_read()\n"); - if (insn->n == 0) return 0; @@ -2137,8 +2080,6 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, unsigned short tmp; - CALL_PDEBUG("In me4000_cnt_insn_write()\n"); - if (insn->n == 0) { return 0; } else if (insn->n > 1) { @@ -2184,8 +2125,6 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int result; - CALL_PDEBUG("In me4000_attach()\n"); - result = me4000_probe(dev, it); if (result) return result; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 733b19243c75..7087da27b716 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -28,18 +28,10 @@ Debug section ===========================================================================*/ -#undef ME4000_CALL_DEBUG /* Debug function entry and exit */ #undef ME4000_PORT_DEBUG /* Debug port access */ #undef ME4000_ISR_DEBUG /* Debug the interrupt service routine */ #undef ME4000_DEBUG /* General purpose debug masseges */ -#ifdef ME4000_CALL_DEBUG -#undef CALL_PDEBUG -#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -#else -# define CALL_PDEBUG(fmt, args...) /* no debugging, do nothing */ -#endif - #ifdef ME4000_PORT_DEBUG #undef PORT_PDEBUG #define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -- GitLab From 3934954b4c76b049c79b28ed245425dee71c2472 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 19:12:35 -0700 Subject: [PATCH 1647/6849] staging: comedi: me4000: remove PORT_PDEBUG macro The PORT_PDEBUG macro is used to output the result of every port io operation. This shouldn't be in a mainline driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 4 ---- drivers/staging/comedi/drivers/me4000.h | 8 -------- 2 files changed, 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index f5a0bcf65cf5..ddb93844bb56 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -111,14 +111,12 @@ static int ai_write_chanlist(struct comedi_device *dev, static inline void me4000_outb(struct comedi_device *dev, unsigned char value, unsigned long port) { - PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port); outb(value, port); } static inline void me4000_outl(struct comedi_device *dev, unsigned long value, unsigned long port) { - PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port); outl(value, port); } @@ -127,7 +125,6 @@ static inline unsigned long me4000_inl(struct comedi_device *dev, { unsigned long value; value = inl(port); - PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port); return value; } @@ -136,7 +133,6 @@ static inline unsigned char me4000_inb(struct comedi_device *dev, { unsigned char value; value = inb(port); - PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port); return value; } diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index 7087da27b716..d9ee3fbb1212 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -28,17 +28,9 @@ Debug section ===========================================================================*/ -#undef ME4000_PORT_DEBUG /* Debug port access */ #undef ME4000_ISR_DEBUG /* Debug the interrupt service routine */ #undef ME4000_DEBUG /* General purpose debug masseges */ -#ifdef ME4000_PORT_DEBUG -#undef PORT_PDEBUG -#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -#else -#define PORT_PDEBUG(fmt, args...) /* no debugging, do nothing */ -#endif - #ifdef ME4000_ISR_DEBUG #undef ISR_PDEBUG #define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -- GitLab From d6cbe537c6f0cb99bc76a48d138ac21f7ec59548 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 19:12:55 -0700 Subject: [PATCH 1648/6849] staging: comedi: me4000: remove inline port io wrappers With the PORT_PDEBUG macro remove we can now remove the inline port io wrappers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 247 ++++++++++-------------- 1 file changed, 98 insertions(+), 149 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index ddb93844bb56..5b4514621d00 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -104,38 +104,6 @@ static int ai_write_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); -/*----------------------------------------------------------------------------- - Meilhaus inline functions - ---------------------------------------------------------------------------*/ - -static inline void me4000_outb(struct comedi_device *dev, unsigned char value, - unsigned long port) -{ - outb(value, port); -} - -static inline void me4000_outl(struct comedi_device *dev, unsigned long value, - unsigned long port) -{ - outl(value, port); -} - -static inline unsigned long me4000_inl(struct comedi_device *dev, - unsigned long port) -{ - unsigned long value; - value = inl(port); - return value; -} - -static inline unsigned char me4000_inb(struct comedi_device *dev, - unsigned long port) -{ - unsigned char value; - value = inb(port); - return value; -} - static const struct comedi_lrange me4000_ai_range = { 4, { @@ -611,56 +579,45 @@ static int reset_board(struct comedi_device *dev) unsigned long icr; /* Make a hardware reset */ - icr = me4000_inl(dev, info->plx_regbase + PLX_ICR); + icr = inl(info->plx_regbase + PLX_ICR); icr |= 0x40000000; - me4000_outl(dev, icr, info->plx_regbase + PLX_ICR); + outl(icr, info->plx_regbase + PLX_ICR); icr &= ~0x40000000; - me4000_outl(dev, icr, info->plx_regbase + PLX_ICR); + outl(icr, info->plx_regbase + PLX_ICR); /* 0x8000 to the DACs means an output voltage of 0V */ - me4000_outl(dev, 0x8000, - info->me4000_regbase + ME4000_AO_00_SINGLE_REG); - me4000_outl(dev, 0x8000, - info->me4000_regbase + ME4000_AO_01_SINGLE_REG); - me4000_outl(dev, 0x8000, - info->me4000_regbase + ME4000_AO_02_SINGLE_REG); - me4000_outl(dev, 0x8000, - info->me4000_regbase + ME4000_AO_03_SINGLE_REG); + outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG); + outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG); + outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG); + outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG); /* Set both stop bits in the analog input control register */ - me4000_outl(dev, - ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AI_CTRL_REG); + outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, + info->me4000_regbase + ME4000_AI_CTRL_REG); /* Set both stop bits in the analog output control register */ - me4000_outl(dev, - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_00_CTRL_REG); - me4000_outl(dev, - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_01_CTRL_REG); - me4000_outl(dev, - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_02_CTRL_REG); - me4000_outl(dev, - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_03_CTRL_REG); + outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, + info->me4000_regbase + ME4000_AO_00_CTRL_REG); + outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, + info->me4000_regbase + ME4000_AO_01_CTRL_REG); + outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, + info->me4000_regbase + ME4000_AO_02_CTRL_REG); + outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, + info->me4000_regbase + ME4000_AO_03_CTRL_REG); /* Enable interrupts on the PLX */ - me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR); + outl(0x43, info->plx_regbase + PLX_INTCSR); /* Set the adustment register for AO demux */ - me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE, + outl(ME4000_AO_DEMUX_ADJUST_VALUE, info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG); /* * Set digital I/O direction for port 0 * to output on isolated versions */ - if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) { - me4000_outl(dev, 0x1, - info->me4000_regbase + ME4000_DIO_CTRL_REG); - } + if (!(inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) + outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG); return 0; } @@ -750,36 +707,34 @@ static int me4000_ai_insn_read(struct comedi_device *dev, entry |= ME4000_AI_LIST_LAST_ENTRY; /* Clear channel list, data fifo and both stop bits */ - tmp = me4000_inl(dev, info->ai_context.ctrl_reg); + tmp = inl(info->ai_context.ctrl_reg); tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO | ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); - me4000_outl(dev, tmp, info->ai_context.ctrl_reg); + outl(tmp, info->ai_context.ctrl_reg); /* Set the acquisition mode to single */ tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 | ME4000_AI_CTRL_BIT_MODE_2); - me4000_outl(dev, tmp, info->ai_context.ctrl_reg); + outl(tmp, info->ai_context.ctrl_reg); /* Enable channel list and data fifo */ tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO; - me4000_outl(dev, tmp, info->ai_context.ctrl_reg); + outl(tmp, info->ai_context.ctrl_reg); /* Generate channel list entry */ - me4000_outl(dev, entry, info->ai_context.channel_list_reg); + outl(entry, info->ai_context.channel_list_reg); /* Set the timer to maximum sample rate */ - me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg); - me4000_outl(dev, ME4000_AI_MIN_TICKS, - info->ai_context.chan_pre_timer_reg); + outl(ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg); + outl(ME4000_AI_MIN_TICKS, info->ai_context.chan_pre_timer_reg); /* Start conversion by dummy read */ - me4000_inl(dev, info->ai_context.start_reg); + inl(info->ai_context.start_reg); /* Wait until ready */ udelay(10); - if (! - (me4000_inl(dev, info->ai_context.status_reg) & + if (!(inl(info->ai_context.status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)) { printk(KERN_ERR "comedi%d: me4000: me4000_ai_insn_read(): " @@ -788,7 +743,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, } /* Read value from data fifo */ - lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF; + lval = inl(info->ai_context.data_reg) & 0xFFFF; data[0] = lval ^ 0x8000; return 1; @@ -800,12 +755,12 @@ static int me4000_ai_cancel(struct comedi_device *dev, unsigned long tmp; /* Stop any running conversion */ - tmp = me4000_inl(dev, info->ai_context.ctrl_reg); + tmp = inl(info->ai_context.ctrl_reg); tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); - me4000_outl(dev, tmp, info->ai_context.ctrl_reg); + outl(tmp, info->ai_context.ctrl_reg); /* Clear the control register */ - me4000_outl(dev, 0x0, info->ai_context.ctrl_reg); + outl(0x0, info->ai_context.ctrl_reg); return 0; } @@ -960,18 +915,16 @@ static void ai_write_timer(struct comedi_device *dev, unsigned int init_ticks, unsigned int scan_ticks, unsigned int chan_ticks) { - me4000_outl(dev, init_ticks - 1, - info->ai_context.scan_pre_timer_low_reg); - me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg); + outl(init_ticks - 1, info->ai_context.scan_pre_timer_low_reg); + outl(0x0, info->ai_context.scan_pre_timer_high_reg); if (scan_ticks) { - me4000_outl(dev, scan_ticks - 1, - info->ai_context.scan_timer_low_reg); - me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg); + outl(scan_ticks - 1, info->ai_context.scan_timer_low_reg); + outl(0x0, info->ai_context.scan_timer_high_reg); } - me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg); - me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg); + outl(chan_ticks - 1, info->ai_context.chan_pre_timer_reg); + outl(chan_ticks - 1, info->ai_context.chan_timer_reg); } static int ai_prepare(struct comedi_device *dev, @@ -987,7 +940,7 @@ static int ai_prepare(struct comedi_device *dev, ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks); /* Reset control register */ - me4000_outl(dev, tmp, info->ai_context.ctrl_reg); + outl(tmp, info->ai_context.ctrl_reg); /* Start sources */ if ((cmd->start_src == TRIG_EXT && @@ -1020,12 +973,12 @@ static int ai_prepare(struct comedi_device *dev, /* Stop triggers */ if (cmd->stop_src == TRIG_COUNT) { - me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg, + outl(cmd->chanlist_len * cmd->stop_arg, info->ai_context.sample_counter_reg); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; } else if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_COUNT) { - me4000_outl(dev, cmd->scan_end_arg, + outl(cmd->scan_end_arg, info->ai_context.sample_counter_reg); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; } else { @@ -1033,7 +986,7 @@ static int ai_prepare(struct comedi_device *dev, } /* Write the setup to the control register */ - me4000_outl(dev, tmp, info->ai_context.ctrl_reg); + outl(tmp, info->ai_context.ctrl_reg); /* Write the channel list */ ai_write_chanlist(dev, s, cmd); @@ -1071,7 +1024,7 @@ static int ai_write_chanlist(struct comedi_device *dev, else entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED; - me4000_outl(dev, entry, info->ai_context.channel_list_reg); + outl(entry, info->ai_context.channel_list_reg); } return 0; @@ -1103,7 +1056,7 @@ static int me4000_ai_do_cmd(struct comedi_device *dev, return err; /* Start acquistion by dummy read */ - me4000_inl(dev, info->ai_context.start_reg); + inl(info->ai_context.start_reg); return 0; } @@ -1516,14 +1469,13 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) return IRQ_HANDLED; } - if (me4000_inl(dev, - ai_context->irq_status_reg) & + if (inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) { ISR_PDEBUG ("me4000_ai_isr(): Fifo half full interrupt occurred\n"); /* Read status register to find out what happened */ - tmp = me4000_inl(dev, ai_context->ctrl_reg); + tmp = inl(ai_context->ctrl_reg); if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && @@ -1538,7 +1490,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; @@ -1566,7 +1518,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; @@ -1590,7 +1542,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); s->async->events |= COMEDI_CB_OVERFLOW; @@ -1605,13 +1557,12 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) /* Work is done, so reset the interrupt */ ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n"); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET; - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET; - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); } - if (me4000_inl(dev, - ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { + if (inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { ISR_PDEBUG ("me4000_ai_isr(): Sample counter interrupt occurred\n"); @@ -1621,10 +1572,10 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) * Acquisition is complete, so stop * conversion and disable all interrupts */ - tmp = me4000_inl(dev, ai_context->ctrl_reg); + tmp = inl(ai_context->ctrl_reg); tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); /* Poll data until fifo empty */ while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) { @@ -1645,9 +1596,9 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) ISR_PDEBUG ("me4000_ai_isr(): Reset interrupt from sample counter\n"); tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET; - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET; - me4000_outl(dev, tmp, ai_context->ctrl_reg); + outl(tmp, ai_context->ctrl_reg); } ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events); @@ -1703,15 +1654,15 @@ static int me4000_ao_insn_write(struct comedi_device *dev, } /* Stop any running conversion */ - tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg); + tmp = inl(info->ao_context[chan].ctrl_reg); tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP; - me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg); + outl(tmp, info->ao_context[chan].ctrl_reg); /* Clear control register and set to single mode */ - me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg); + outl(0x0, info->ao_context[chan].ctrl_reg); /* Write data value */ - me4000_outl(dev, data[0], info->ao_context[chan].single_reg); + outl(data[0], info->ao_context[chan].single_reg); /* Store in the mirror */ info->ao_context[chan].mirror = data[0]; @@ -1773,23 +1724,22 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, s->state |= data[0] & data[1]; /* Write out the new digital output lines */ - me4000_outl(dev, (s->state >> 0) & 0xFF, + outl((s->state >> 0) & 0xFF, info->dio_context.port_0_reg); - me4000_outl(dev, (s->state >> 8) & 0xFF, + outl((s->state >> 8) & 0xFF, info->dio_context.port_1_reg); - me4000_outl(dev, (s->state >> 16) & 0xFF, + outl((s->state >> 16) & 0xFF, info->dio_context.port_2_reg); - me4000_outl(dev, (s->state >> 24) & 0xFF, + outl((s->state >> 24) & 0xFF, info->dio_context.port_3_reg); } /* On return, data[1] contains the value of the digital input and output lines. */ - data[1] = - ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) | - ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) | - ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) | - ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24); + data[1] = ((inl(info->dio_context.port_0_reg) & 0xFF) << 0) | + ((inl(info->dio_context.port_1_reg) & 0xFF) << 8) | + ((inl(info->dio_context.port_2_reg) & 0xFF) << 16) | + ((inl(info->dio_context.port_3_reg) & 0xFF) << 24); return 2; } @@ -1821,7 +1771,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, * On the ME-4000 it is only possible to switch port wise (8 bit) */ - tmp = me4000_inl(dev, info->dio_context.ctrl_reg); + tmp = inl(info->dio_context.ctrl_reg); if (data[0] == INSN_CONFIG_DIO_OUTPUT) { if (chan < 8) { @@ -1835,7 +1785,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, * If one the first port is a fixed output * port and the second is a fixed input port. */ - if (!me4000_inl(dev, info->dio_context.dir_reg)) + if (!inl(info->dio_context.dir_reg)) return -ENODEV; s->io_bits |= 0xFF00; @@ -1862,7 +1812,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, * If one the first port is a fixed output * port and the second is a fixed input port. */ - if (!me4000_inl(dev, info->dio_context.dir_reg)) + if (!inl(info->dio_context.dir_reg)) return -ENODEV; s->io_bits &= ~0xFF; @@ -1885,7 +1835,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev, } } - me4000_outl(dev, tmp, info->dio_context.ctrl_reg); + outl(tmp, info->dio_context.ctrl_reg); return 1; } @@ -1898,19 +1848,19 @@ static int cnt_reset(struct comedi_device *dev, unsigned int channel) { switch (channel) { case 0: - me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg); - me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg); - me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg); + outb(0x30, info->cnt_context.ctrl_reg); + outb(0x00, info->cnt_context.counter_0_reg); + outb(0x00, info->cnt_context.counter_0_reg); break; case 1: - me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg); - me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg); - me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg); + outb(0x70, info->cnt_context.ctrl_reg); + outb(0x00, info->cnt_context.counter_1_reg); + outb(0x00, info->cnt_context.counter_1_reg); break; case 2: - me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg); - me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg); - me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg); + outb(0xB0, info->cnt_context.ctrl_reg); + outb(0x00, info->cnt_context.counter_2_reg); + outb(0x00, info->cnt_context.counter_2_reg); break; default: printk(KERN_ERR @@ -1972,7 +1922,7 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel, /* Write the control word */ tmp |= 0x30; - me4000_outb(dev, tmp, info->cnt_context.ctrl_reg); + outb(tmp, info->cnt_context.ctrl_reg); return 0; } @@ -2041,21 +1991,21 @@ static int me4000_cnt_insn_read(struct comedi_device *dev, switch (insn->chanspec) { case 0: - tmp = me4000_inb(dev, info->cnt_context.counter_0_reg); + tmp = inb(info->cnt_context.counter_0_reg); data[0] = tmp; - tmp = me4000_inb(dev, info->cnt_context.counter_0_reg); + tmp = inb(info->cnt_context.counter_0_reg); data[0] |= tmp << 8; break; case 1: - tmp = me4000_inb(dev, info->cnt_context.counter_1_reg); + tmp = inb(info->cnt_context.counter_1_reg); data[0] = tmp; - tmp = me4000_inb(dev, info->cnt_context.counter_1_reg); + tmp = inb(info->cnt_context.counter_1_reg); data[0] |= tmp << 8; break; case 2: - tmp = me4000_inb(dev, info->cnt_context.counter_2_reg); + tmp = inb(info->cnt_context.counter_2_reg); data[0] = tmp; - tmp = me4000_inb(dev, info->cnt_context.counter_2_reg); + tmp = inb(info->cnt_context.counter_2_reg); data[0] |= tmp << 8; break; default: @@ -2089,21 +2039,21 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, switch (insn->chanspec) { case 0: tmp = data[0] & 0xFF; - me4000_outb(dev, tmp, info->cnt_context.counter_0_reg); + outb(tmp, info->cnt_context.counter_0_reg); tmp = (data[0] >> 8) & 0xFF; - me4000_outb(dev, tmp, info->cnt_context.counter_0_reg); + outb(tmp, info->cnt_context.counter_0_reg); break; case 1: tmp = data[0] & 0xFF; - me4000_outb(dev, tmp, info->cnt_context.counter_1_reg); + outb(tmp, info->cnt_context.counter_1_reg); tmp = (data[0] >> 8) & 0xFF; - me4000_outb(dev, tmp, info->cnt_context.counter_1_reg); + outb(tmp, info->cnt_context.counter_1_reg); break; case 2: tmp = data[0] & 0xFF; - me4000_outb(dev, tmp, info->cnt_context.counter_2_reg); + outb(tmp, info->cnt_context.counter_2_reg); tmp = (data[0] >> 8) & 0xFF; - me4000_outb(dev, tmp, info->cnt_context.counter_2_reg); + outb(tmp, info->cnt_context.counter_2_reg); break; default: printk(KERN_ERR @@ -2207,10 +2157,9 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Check for optoisolated ME-4000 version. If one the first * port is a fixed output port and the second is a fixed input port. */ - if (!me4000_inl(dev, info->dio_context.dir_reg)) { + if (!inl(info->dio_context.dir_reg)) { s->io_bits |= 0xFF; - me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, - info->dio_context.dir_reg); + outl(ME4000_DIO_CTRL_BIT_MODE_0, info->dio_context.dir_reg); } /*========================================================================= -- GitLab From ef5bbfcb29db95c944bbfd4487454cd237d38b29 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 19:13:15 -0700 Subject: [PATCH 1649/6849] staging: comedi: me4000: remove ISR_PDEBUG macro The ISR_PDEBUG macro is used to output trace messages in the isr routine. This shouldn't be in a mainline driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 22 +--------------------- drivers/staging/comedi/drivers/me4000.h | 8 -------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 5b4514621d00..657d2fa8bd89 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1451,12 +1451,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) int c = 0; long lval; - ISR_PDEBUG("me4000_ai_isr() is executed\n"); - - if (!dev->attached) { - ISR_PDEBUG("me4000_ai_isr() premature interrupt\n"); + if (!dev->attached) return IRQ_NONE; - } /* Reset all events */ s->async->events = 0; @@ -1471,16 +1467,12 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) if (inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) { - ISR_PDEBUG - ("me4000_ai_isr(): Fifo half full interrupt occurred\n"); - /* Read status register to find out what happened */ tmp = inl(ai_context->ctrl_reg); if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG("me4000_ai_isr(): Fifo full\n"); c = ME4000_AI_FIFO_COUNT; /* @@ -1500,8 +1492,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n"); - s->async->events |= COMEDI_CB_BLOCK; c = ME4000_AI_FIFO_COUNT / 2; @@ -1527,8 +1517,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) "Undefined FIFO state\n", dev->minor); } - ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c); - for (i = 0; i < c; i++) { /* Read value from data fifo */ lval = inl(ai_context->data_reg) & 0xFFFF; @@ -1555,7 +1543,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) } /* Work is done, so reset the interrupt */ - ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n"); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET; outl(tmp, ai_context->ctrl_reg); tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET; @@ -1563,9 +1550,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) } if (inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { - ISR_PDEBUG - ("me4000_ai_isr(): Sample counter interrupt occurred\n"); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA; /* @@ -1593,16 +1577,12 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) } /* Work is done, so reset the interrupt */ - ISR_PDEBUG - ("me4000_ai_isr(): Reset interrupt from sample counter\n"); tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET; outl(tmp, ai_context->ctrl_reg); tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET; outl(tmp, ai_context->ctrl_reg); } - ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events); - if (s->async->events) comedi_event(dev, s); diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index d9ee3fbb1212..f87dd197a96a 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -28,16 +28,8 @@ Debug section ===========================================================================*/ -#undef ME4000_ISR_DEBUG /* Debug the interrupt service routine */ #undef ME4000_DEBUG /* General purpose debug masseges */ -#ifdef ME4000_ISR_DEBUG -#undef ISR_PDEBUG -#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -#else -#define ISR_PDEBUG(fmt, args...) /* no debugging, do nothing */ -#endif - #ifdef ME4000_DEBUG #undef PDEBUG #define PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -- GitLab From 871784a5f86323ce654ba56e1f5e85f717a53a5e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Jun 2012 19:13:42 -0700 Subject: [PATCH 1650/6849] staging: comedi: me4000: remove PDEBUG macro The PDEBUG macro is used to output a bunch of debug messages in the driver. These messages might be useful when first creating the driver but they shouldn't be in mainline. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 35 ------------------------- drivers/staging/comedi/drivers/me4000.h | 13 --------- 2 files changed, 48 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 657d2fa8bd89..72466bfa3b1d 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -860,11 +860,6 @@ static int ai_round_cmd_args(struct comedi_device *dev, *scan_ticks = 0; *chan_ticks = 0; - PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg); - PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n", - cmd->scan_begin_arg); - PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg); - if (cmd->start_arg) { *init_ticks = (cmd->start_arg * 33) / 1000; rest = (cmd->start_arg * 33) % 1000; @@ -904,10 +899,6 @@ static int ai_round_cmd_args(struct comedi_device *dev, } } - PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks); - PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks); - PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks); - return 0; } @@ -1083,32 +1074,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, unsigned int scan_ticks; int err = 0; - PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev); - PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags); - PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n", - cmd->start_src); - PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n", - cmd->start_arg); - PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n", - cmd->scan_begin_src); - PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n", - cmd->scan_begin_arg); - PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n", - cmd->convert_src); - PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n", - cmd->convert_arg); - PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n", - cmd->scan_end_src); - PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n", - cmd->scan_end_arg); - PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n", - cmd->stop_src); - PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg); - PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n", - (unsigned int)cmd->chanlist); - PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n", - cmd->chanlist_len); - /* Only rounding flags are implemented */ cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN; diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h index f87dd197a96a..5a4df4e4b236 100644 --- a/drivers/staging/comedi/drivers/me4000.h +++ b/drivers/staging/comedi/drivers/me4000.h @@ -24,19 +24,6 @@ #ifndef _ME4000_H_ #define _ME4000_H_ -/*============================================================================= - Debug section - ===========================================================================*/ - -#undef ME4000_DEBUG /* General purpose debug masseges */ - -#ifdef ME4000_DEBUG -#undef PDEBUG -#define PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args) -#else -#define PDEBUG(fmt, args...) /* no debugging, do nothing */ -#endif - /*============================================================================= PCI vendor and device IDs ===========================================================================*/ -- GitLab From a529ae4ba3acfd97210769e3445e8d8b07ca1112 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 14 Jun 2012 15:45:09 +0200 Subject: [PATCH 1651/6849] iio: drop wrong reference from Kconfig The documentation lives in drivers/staging/iio/Documentation, but according to Jonathan it's obsolete and needs fixing. Signed-off-by: Jiri Kosina Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 56eecefcec75..2ec93da41e2c 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -8,8 +8,7 @@ menuconfig IIO help The industrial I/O subsystem provides a unified framework for drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). See - Documentation/iio for more information. + number of different physical interfaces (i2c, spi, etc). if IIO -- GitLab From 9f77186dd13125bef301f9136b6075f5530f3d85 Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Thu, 14 Jun 2012 13:18:56 -0700 Subject: [PATCH 1652/6849] staging: gdm72xx: Release netlink socket properly This patch modifies the gdm72xx driver to properly release a netlink socket using netlink_kernel_release. It fixes the following kernel crash, which occurs after repeatedly suspending and resuming a system. kernel BUG at /home/benchan/trunk/src/third_party/kernel/files/mm/slub.c:3471! invalid opcode: 0000 [#1] SMP CPU 2 Modules linked in: asix usbnet snd_hda_codec_hdmi snd_hda_codec_cirrus i2c_dev uinput snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_timer bluetooth snd_page_alloc fuse aesni_intel cryptd isl29018(C) aes_x86_64 industrialio(C) memconsole nm10_gpio rtc_cmos nf_conntrack_ipv6 nf_defrag_ipv6 r8169 ath9k mac80211 ip6table_filter ath9k_common ath9k_hw ath cfg80211 xt_mark ip6_tables uvcvideo videobuf2_core videodev videobuf2_vmalloc videobuf2_memops gdmwm(C) joydev Pid: 3125, comm: kworker/u:30 Tainted: G WC 3.4.0 #1 RIP: 0010:[] [] kfree+0x67/0xca RSP: 0018:ffff880134977d60 EFLAGS: 00010246 RAX: 4000000000000400 RBX: ffffffff818832a0 RCX: 0000000000000000 RDX: 4000000000000000 RSI: 0000000000000000 RDI: ffffffff818832a0 RBP: ffff880134977d80 R08: 00000000ffffffff R09: ffffea00000620c0 R10: ffffffff8111b729 R11: ffff880149fb3840 R12: ffffffff81a08840 R13: ffffffff813f5bc3 R14: ffffffff8138ed84 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88014fb00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007f7cad963110 CR3: 000000000180b000 CR4: 00000000000407e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/u:30 (pid: 3125, threadinfo ffff880134976000, task ffff8801330647e0) Stack: 0000000000000002 ffffffff818832a0 ffffffff81a08840 ffff880134977df0 ffff880134977da0 ffffffff813f5bc3 ffff880134977df0 ffffffff81883250 ffff880134977dd0 ffffffff8138e64c 0000000180150010 ffffffff81883250 Call Trace: [] ipv4_sysctl_exit_net+0x23/0x27 [] ops_exit_list+0x27/0x50 [] cleanup_net+0xee/0x17c [] process_one_work+0x199/0x2b8 [] worker_thread+0x13c/0x222 [] ? manage_workers.isra.26+0x171/0x171 [] kthread+0x8b/0x93 [] kernel_thread_helper+0x4/0x10 [] ? __init_kthread_worker+0x39/0x39 [] ? gs_change+0xb/0xb Code: 83 c4 10 49 83 3c 24 00 eb e4 48 83 fb 10 76 76 48 89 df e8 17 e1 ff ff 49 89 c1 48 8b 00 a8 80 75 15 49 f7 01 00 c0 00 00 75 02 <0f> 0b 4c 89 cf e8 b8 b4 fd ff eb 4f 4c 8b 55 08 49 8b 79 30 48 RIP [] kfree+0x67/0xca RSP Signed-off-by: Ben Chan Cc: Sage Ahn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/netlink_k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 292af0f7f451..51665132c61b 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -104,7 +104,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void netlink_exit(struct sock *sock) { - sock_release(sock->sk_socket); + netlink_kernel_release(sock); } int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) -- GitLab From 4d9505af7743828464d066795c6e1311c7884db4 Mon Sep 17 00:00:00 2001 From: Leed Aguilar Date: Thu, 14 Jun 2012 11:05:31 -0400 Subject: [PATCH 1653/6849] staging:iio:gyro:adis16080: remove sparse warnings Removed the following sparse warning: In function 'adis16080_read_raw': warning: 'ut' may be used uninitialized in this function Signed-off-by: Leed Aguilar Acked-by: Lars-Peter Clausen Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16080_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 11f1dccd7a0d..345e4fa778ba 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -82,7 +82,7 @@ static int adis16080_read_raw(struct iio_dev *indio_dev, long mask) { int ret = -EINVAL; - u16 ut; + u16 ut = 0; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); -- GitLab From 0b91f45b23cb73ce11acdc3cf4c6efd4441e3b3e Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 14 Jun 2012 18:07:15 -0700 Subject: [PATCH 1654/6849] x86, compat: Use test_thread_flag(TIF_IA32) in compat signal delivery Signal delivery compat path may not have the 'TS_COMPAT' flag (that flag indicates how we entered the kernel). So use test_thread_flag(TIF_IA32) instead of is_ia32_task(): one of the functions of TIF_IA32 is just what kind of signal frame we want. Signed-off-by: Suresh Siddha Link: http://lkml.kernel.org/r/1339722435.3475.57.camel@sbsiddha-desk.sc.intel.com Cc: stable@kernel.org # v3.4 Signed-off-by: H. Peter Anvin --- arch/x86/ia32/ia32_signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index daeca56211e3..673ac9b63d6b 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -38,7 +38,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) { int err = 0; - bool ia32 = is_ia32_task(); + bool ia32 = test_thread_flag(TIF_IA32); if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) return -EFAULT; -- GitLab From 107a84e61cdd3406c842a0e4be7efffd3a05dba6 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 14 Jun 2012 09:12:35 +0200 Subject: [PATCH 1655/6849] of: match by compatible property first When matching devices against an OF device ID table, the first string of the compatible property that is listed in the table should match, regardless of its position in the table. Cc: Grant Likely Cc: Rob Herring Cc: devicetree-discuss@lists.ozlabs.org Signed-off-by: Thierry Reding Signed-off-by: Rob Herring --- drivers/of/base.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index d9bfd49b1935..eada3f4ef801 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -511,6 +511,22 @@ out: } EXPORT_SYMBOL(of_find_node_with_property); +static const struct of_device_id *of_match_compat(const struct of_device_id *matches, + const char *compat) +{ + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { + const char *cp = matches->compatible; + int len = strlen(cp); + + if (len > 0 && of_compat_cmp(compat, cp, len) == 0) + return matches; + + matches++; + } + + return NULL; +} + /** * of_match_node - Tell if an device_node has a matching of_match structure * @matches: array of of device match structures to search in @@ -521,9 +537,18 @@ EXPORT_SYMBOL(of_find_node_with_property); const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node) { + struct property *prop; + const char *cp; + if (!matches) return NULL; + of_property_for_each_string(node, "compatible", prop, cp) { + const struct of_device_id *match = of_match_compat(matches, cp); + if (match) + return match; + } + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; if (matches->name[0]) @@ -532,10 +557,7 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, if (matches->type[0]) match &= node->type && !strcmp(matches->type, node->type); - if (matches->compatible[0]) - match &= of_device_is_compatible(node, - matches->compatible); - if (match) + if (match && !matches->compatible[0]) return matches; matches++; } -- GitLab From 36393395536064e483b73d173f6afc103eadfbc4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 14 Jun 2012 22:21:46 -0700 Subject: [PATCH 1656/6849] ipv4: Handle PMTU in all ICMP error handlers. With ip_rt_frag_needed() removed, we have to explicitly update PMTU information in every ICMP error handler. Create two helper functions to facilitate this. 1) ipv4_sk_update_pmtu() This updates the PMTU when we have a socket context to work with. 2) ipv4_update_pmtu() Raw version, used when no socket context is available. For this interface, we essentially just pass in explicit arguments for the flow identity information we would have extracted from the socket. And you'll notice that ipv4_sk_update_pmtu() is simply implemented in terms of ipv4_update_pmtu() Note that __ip_route_output_key() is used, rather than something like ip_route_output_flow() or ip_route_output_key(). This is because we absolutely do not want to end up with a route that does IPSEC encapsulation and the like. Instead, we only want the route that would get us to the node described by the outermost IP header. Reported-by: Steffen Klassert Signed-off-by: David S. Miller --- include/net/route.h | 5 ++++- net/ipv4/ah4.c | 1 + net/ipv4/esp4.c | 1 + net/ipv4/ip_gre.c | 14 ++++++++++---- net/ipv4/ipcomp.c | 1 + net/ipv4/ipip.c | 15 +++++++++++---- net/ipv4/ping.c | 1 + net/ipv4/raw.c | 3 +++ net/ipv4/route.c | 28 ++++++++++++++++++++++++++++ net/ipv4/udp.c | 1 + net/ipv6/sit.c | 15 +++++++++++---- 11 files changed, 72 insertions(+), 13 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index a36ae429ed5d..47eb25ac1f7f 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -215,7 +215,10 @@ static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 s return ip_route_input_common(skb, dst, src, tos, devin, true); } -extern void ip_rt_send_redirect(struct sk_buff *skb); +extern void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, + int oif, u32 mark, u8 protocol, int flow_flags); +extern void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu); +extern void ip_rt_send_redirect(struct sk_buff *skb); extern unsigned int inet_addr_type(struct net *net, __be32 addr); extern unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr); diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index e8f2617ecd47..916d5ecaf6c6 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -408,6 +408,7 @@ static void ah4_err(struct sk_buff *skb, u32 info) return; pr_debug("pmtu discovery on SA AH/%08x/%08x\n", ntohl(ah->spi), ntohl(iph->daddr)); + ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0); xfrm_state_put(x); } diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index cb982a61536f..7b95b49a36ce 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -494,6 +494,7 @@ static void esp4_err(struct sk_buff *skb, u32 info) return; NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n", ntohl(esph->spi), ntohl(iph->daddr)); + ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0); xfrm_state_put(x); } diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f49047b79609..594cec35ac4d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -516,9 +516,6 @@ static void ipgre_err(struct sk_buff *skb, u32 info) case ICMP_PORT_UNREACH: /* Impossible event. */ return; - case ICMP_FRAG_NEEDED: - /* Soft state for pmtu is maintained by IP core. */ - return; default: /* All others are translated to HOST_UNREACH. rfc2003 contains "deep thoughts" about NET_UNREACH, @@ -538,7 +535,16 @@ static void ipgre_err(struct sk_buff *skb, u32 info) flags & GRE_KEY ? *(((__be32 *)p) + (grehlen / 4) - 1) : 0, p[1]); - if (t == NULL || t->parms.iph.daddr == 0 || + if (t == NULL) + goto out; + + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + ipv4_update_pmtu(skb, dev_net(skb->dev), info, + t->parms.link, 0, IPPROTO_GRE, 0); + goto out; + } + + if (t->parms.iph.daddr == 0 || ipv4_is_multicast(t->parms.iph.daddr)) goto out; diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 63b64c45a826..b91375482d84 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -42,6 +42,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) return; NETDEBUG(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%pI4\n", spi, &iph->daddr); + ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0); xfrm_state_put(x); } diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 2d0f99bf61b3..715338a1b205 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -348,9 +348,6 @@ static int ipip_err(struct sk_buff *skb, u32 info) case ICMP_PORT_UNREACH: /* Impossible event. */ return 0; - case ICMP_FRAG_NEEDED: - /* Soft state for pmtu is maintained by IP core. */ - return 0; default: /* All others are translated to HOST_UNREACH. rfc2003 contains "deep thoughts" about NET_UNREACH, @@ -369,7 +366,17 @@ static int ipip_err(struct sk_buff *skb, u32 info) rcu_read_lock(); t = ipip_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr); - if (t == NULL || t->parms.iph.daddr == 0) + if (t == NULL) + goto out; + + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + ipv4_update_pmtu(skb, dev_net(skb->dev), info, + t->dev->ifindex, 0, IPPROTO_IPIP, 0); + err = 0; + goto out; + } + + if (t->parms.iph.daddr == 0) goto out; err = 0; diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 2c00e8bf684d..340fcf29a966 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -371,6 +371,7 @@ void ping_err(struct sk_buff *skb, u32 info) break; case ICMP_DEST_UNREACH: if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */ + ipv4_sk_update_pmtu(skb, sk, info); if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) { err = EMSGSIZE; harderr = 1; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 4032b818f3e4..659ddfb10947 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -216,6 +216,9 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info) int err = 0; int harderr = 0; + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) + ipv4_sk_update_pmtu(skb, sk, info); + /* Report error on raw socket, if: 1. User requested ip_recverr. 2. Socket is connected (otherwise the error indication diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 655506af47ca..41df5297a412 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1711,6 +1711,34 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } } +void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, + int oif, u32 mark, u8 protocol, int flow_flags) +{ + const struct iphdr *iph = (const struct iphdr *)skb->data; + struct flowi4 fl4; + struct rtable *rt; + + flowi4_init_output(&fl4, oif, mark, RT_TOS(iph->tos), RT_SCOPE_UNIVERSE, + protocol, flow_flags | FLOWI_FLAG_PRECOW_METRICS, + iph->daddr, iph->saddr, 0, 0); + rt = __ip_route_output_key(net, &fl4); + if (!IS_ERR(rt)) { + ip_rt_update_pmtu(&rt->dst, mtu); + ip_rt_put(rt); + } +} +EXPORT_SYMBOL_GPL(ipv4_update_pmtu); + +void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) +{ + const struct inet_sock *inet = inet_sk(sk); + + return ipv4_update_pmtu(skb, sock_net(sk), mtu, + sk->sk_bound_dev_if, sk->sk_mark, + inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, + inet_sk_flowi_flags(sk)); +} +EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); static void ipv4_validate_peer(struct rtable *rt) { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index eaca73644e79..db017efb76ea 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -615,6 +615,7 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) break; case ICMP_DEST_UNREACH: if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */ + ipv4_sk_update_pmtu(skb, sk, info); if (inet->pmtudisc != IP_PMTUDISC_DONT) { err = EMSGSIZE; harderr = 1; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 60415711563f..49aea94c9be3 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -527,9 +527,6 @@ static int ipip6_err(struct sk_buff *skb, u32 info) case ICMP_PORT_UNREACH: /* Impossible event. */ return 0; - case ICMP_FRAG_NEEDED: - /* Soft state for pmtu is maintained by IP core. */ - return 0; default: /* All others are translated to HOST_UNREACH. rfc2003 contains "deep thoughts" about NET_UNREACH, @@ -551,7 +548,17 @@ static int ipip6_err(struct sk_buff *skb, u32 info) skb->dev, iph->daddr, iph->saddr); - if (t == NULL || t->parms.iph.daddr == 0) + if (t == NULL) + goto out; + + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + ipv4_update_pmtu(skb, dev_net(skb->dev), info, + t->dev->ifindex, 0, IPPROTO_IPV6, 0); + err = 0; + goto out; + } + + if (t->parms.iph.daddr == 0) goto out; err = 0; -- GitLab From 458f27a9823a0841acb4ca59e0e7f33e181f85e2 Mon Sep 17 00:00:00 2001 From: Asias He Date: Fri, 15 Jun 2012 08:45:25 +0200 Subject: [PATCH 1657/6849] block: Avoid missed wakeup in request waitqueue After hot-unplug a stressed disk, I found that rl->wait[] is not empty while rl->count[] is empty and there are theads still sleeping on get_request after the queue cleanup. With simple debug code, I found there are exactly nr_sleep - nr_wakeup of theads in D state. So there are missed wakeup. $ dmesg | grep nr_sleep [ 52.917115] ---> nr_sleep=1046, nr_wakeup=873, delta=173 $ vmstat 1 1 173 0 712640 24292 96172 0 0 0 0 419 757 0 0 0 100 0 To quote Tejun: Ah, okay, freed_request() wakes up single waiter with the assumption that after the wakeup there will at least be one successful allocation which in turn will continue the wakeup chain until the wait list is empty - ie. waiter wakeup is dependent on successful request allocation happening after each wakeup. With queue marked dead, any woken up waiter fails the allocation path, so the wakeup chaining is lost and we're left with hung waiters. What we need is wake_up_all() after drain completion. This patch fixes the missed wakeup by waking up all the theads which are sleeping on wait queue after queue drain. Changes in v2: Drop waitqueue_active() optimization Acked-by: Tejun Heo Signed-off-by: Asias He Fixed a bug by me, where stacked devices would oops on calling blk_drain_queue() since ->rq.wait[] do not get initialized unless it's a full queue setup. Signed-off-by: Jens Axboe --- block/blk-core.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index 3c923a7aeb56..ce7fbf8d85a6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -361,9 +361,10 @@ EXPORT_SYMBOL(blk_put_queue); */ void blk_drain_queue(struct request_queue *q, bool drain_all) { + int i; + while (true) { bool drain = false; - int i; spin_lock_irq(q->queue_lock); @@ -408,6 +409,18 @@ void blk_drain_queue(struct request_queue *q, bool drain_all) break; msleep(10); } + + /* + * With queue marked dead, any woken up waiter will fail the + * allocation path, so the wakeup chaining is lost and we're + * left with hung waiters. We need to wake up those waiters. + */ + if (q->request_fn) { + spin_lock_irq(q->queue_lock); + for (i = 0; i < ARRAY_SIZE(q->rq.wait); i++) + wake_up_all(&q->rq.wait[i]); + spin_unlock_irq(q->queue_lock); + } } /** -- GitLab From 5e5cfac0c622d42eff4fa308e91b3c9c1884b4f0 Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 24 May 2012 23:28:52 +0800 Subject: [PATCH 1658/6849] block: Mitigate lock unbalance caused by lock switching Commit 777eb1bf15b8532c396821774bf6451e563438f5 disconnects externally supplied queue_lock before blk_drain_queue(). Switching the lock would introduce lock unbalance because theads which have taken the external lock might unlock the internal lock in the during the queue drain. This patch mitigate this by disconnecting the lock after the queue draining since queue draining makes a lot of request_queue users go away. However, please note, this patch only makes the problem less likely to happen. Anyone who still holds a ref might try to issue a new request on a dead queue after the blk_cleanup_queue() finishes draining, the lock unbalance might still happen in this case. ===================================== [ BUG: bad unlock balance detected! ] 3.4.0+ #288 Not tainted ------------------------------------- fio/17706 is trying to release lock (&(&q->__queue_lock)->rlock) at: [] blk_queue_bio+0x2a2/0x380 but there are no more locks to release! other info that might help us debug this: 1 lock held by fio/17706: #0: (&(&vblk->lock)->rlock){......}, at: [] get_request_wait+0x19a/0x250 stack backtrace: Pid: 17706, comm: fio Not tainted 3.4.0+ #288 Call Trace: [] ? blk_queue_bio+0x2a2/0x380 [] print_unlock_inbalance_bug+0xf9/0x100 [] lock_release_non_nested+0x1df/0x330 [] ? dio_bio_end_aio+0x34/0xc0 [] ? bio_check_pages_dirty+0x85/0xe0 [] ? dio_bio_end_aio+0xb1/0xc0 [] ? blk_queue_bio+0x2a2/0x380 [] ? blk_queue_bio+0x2a2/0x380 [] lock_release+0xd9/0x250 [] _raw_spin_unlock_irq+0x23/0x40 [] blk_queue_bio+0x2a2/0x380 [] generic_make_request+0xca/0x100 [] submit_bio+0x76/0xf0 [] ? set_page_dirty_lock+0x3c/0x60 [] ? bio_set_pages_dirty+0x51/0x70 [] do_blockdev_direct_IO+0xbf8/0xee0 [] ? blkdev_get_block+0x80/0x80 [] __blockdev_direct_IO+0x55/0x60 [] ? blkdev_get_block+0x80/0x80 [] blkdev_direct_IO+0x57/0x60 [] ? blkdev_get_block+0x80/0x80 [] generic_file_aio_read+0x70e/0x760 [] ? __lock_acquire+0x215/0x5a0 [] ? aio_run_iocb+0x54/0x1a0 [] ? grab_cache_page_nowait+0xc0/0xc0 [] aio_rw_vect_retry+0x7c/0x1e0 [] ? aio_fsync+0x30/0x30 [] aio_run_iocb+0x66/0x1a0 [] do_io_submit+0x6f0/0xb80 [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] sys_io_submit+0x10/0x20 [] system_call_fastpath+0x16/0x1b Changes since v2: Update commit log to explain how the code is still broken even if we delay the lock switching after the drain. Changes since v1: Update commit log as Tejun suggested. Acked-by: Tejun Heo Signed-off-by: Asias He Signed-off-by: Jens Axboe --- block/blk-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index ce7fbf8d85a6..93eb3e4f88ce 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -480,7 +480,6 @@ void blk_cleanup_queue(struct request_queue *q) /* mark @q DEAD, no new request or merges will be allowed afterwards */ mutex_lock(&q->sysfs_lock); queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q); - spin_lock_irq(lock); /* @@ -498,10 +497,6 @@ void blk_cleanup_queue(struct request_queue *q) queue_flag_set(QUEUE_FLAG_NOMERGES, q); queue_flag_set(QUEUE_FLAG_NOXMERGES, q); queue_flag_set(QUEUE_FLAG_DEAD, q); - - if (q->queue_lock != &q->__queue_lock) - q->queue_lock = &q->__queue_lock; - spin_unlock_irq(lock); mutex_unlock(&q->sysfs_lock); @@ -512,6 +507,11 @@ void blk_cleanup_queue(struct request_queue *q) del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer); blk_sync_queue(q); + spin_lock_irq(lock); + if (q->queue_lock != &q->__queue_lock) + q->queue_lock = &q->__queue_lock; + spin_unlock_irq(lock); + /* @q is and will stay empty, shutdown and put */ blk_put_queue(q); } -- GitLab From 76aaa5101fffaef12b45b4c01ed0d0528f23dedf Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 14 Jun 2012 09:04:07 +0200 Subject: [PATCH 1659/6849] block: Drop dead function blk_abort_queue() This function was only used by btrfs code in btrfs_abort_devices() (seems in a wrong way). It was removed in commit d07eb9117050c9ed3f78296ebcc06128b52693be, So, Let's remove the dead code to avoid any confusion. Changes in v2: update commit log, btrfs_abort_devices() was removed already. Cc: Jens Axboe Cc: linux-kernel@vger.kernel.org Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org Cc: David Sterba Signed-off-by: Asias He Signed-off-by: Jens Axboe --- block/blk-timeout.c | 41 ----------------------------------------- include/linux/blkdev.h | 1 - 2 files changed, 42 deletions(-) diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 780354888958..6e4744cbfb56 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c @@ -197,44 +197,3 @@ void blk_add_timer(struct request *req) mod_timer(&q->timeout, expiry); } -/** - * blk_abort_queue -- Abort all request on given queue - * @queue: pointer to queue - * - */ -void blk_abort_queue(struct request_queue *q) -{ - unsigned long flags; - struct request *rq, *tmp; - LIST_HEAD(list); - - /* - * Not a request based block device, nothing to abort - */ - if (!q->request_fn) - return; - - spin_lock_irqsave(q->queue_lock, flags); - - elv_abort_queue(q); - - /* - * Splice entries to local list, to avoid deadlocking if entries - * get readded to the timeout list by error handling - */ - list_splice_init(&q->timeout_list, &list); - - list_for_each_entry_safe(rq, tmp, &list, timeout_list) - blk_abort_request(rq); - - /* - * Occasionally, blk_abort_request() will return without - * deleting the element from the list. Make sure we add those back - * instead of leaving them on the local stack list. - */ - list_splice(&list, &q->timeout_list); - - spin_unlock_irqrestore(q->queue_lock, flags); - -} -EXPORT_SYMBOL_GPL(blk_abort_queue); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ba43f408baa3..07954b05b86c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -827,7 +827,6 @@ extern bool __blk_end_request_err(struct request *rq, int error); extern void blk_complete_request(struct request *); extern void __blk_complete_request(struct request *); extern void blk_abort_request(struct request *); -extern void blk_abort_queue(struct request_queue *); extern void blk_unprep_request(struct request *); /* -- GitLab From 3e386565e14175c57dee50281613c4bd1865f5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 8 Jun 2012 12:04:50 +0200 Subject: [PATCH 1660/6849] ARM: imx27/dt: make dt_compat entry const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/imx27-dt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c index eee0cc8d92a4..52efe4d5149b 100644 --- a/arch/arm/mach-imx/imx27-dt.c +++ b/arch/arm/mach-imx/imx27-dt.c @@ -75,7 +75,7 @@ static struct sys_timer imx27_timer = { .init = imx27_timer_init, }; -static const char *imx27_dt_board_compat[] __initdata = { +static const char * const imx27_dt_board_compat[] __initconst = { "fsl,imx27", NULL }; -- GitLab From c20c5a841cbe47f5b7812b57bd25397497e5fbc0 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Thu, 14 Jun 2012 14:23:53 -0700 Subject: [PATCH 1661/6849] ALSA: hda_intel: activate COMBO mode for Intel client chipsets This patch activates the COMBO position_fix for recent Intel client chipsets. COMBO mode is the recommended setting for Intel chipsets and eliminates HD audio warnings in dmesg. This patch has been tested on Lynx Point, Panther Point, and Cougar Pont. Signed-off-by: Seth Heasley Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d49926e4d19f..1a07d2188dd7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -535,6 +535,7 @@ enum { #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ +#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */ /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -2728,6 +2729,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix) snd_printd(SFX "Using LPIB position fix\n"); return POS_FIX_LPIB; } + if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) { + snd_printd(SFX "Using COMBO position fix\n"); + return POS_FIX_COMBO; + } return POS_FIX_AUTO; } @@ -3240,7 +3245,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE }, + AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, /* PBG */ { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | @@ -3248,11 +3253,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE}, + AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, /* Lynx Point */ { PCI_DEVICE(0x8086, 0x8c20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE}, + AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | -- GitLab From 4b6ace9e7176d93f819cec9df47faadaaceead4b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jun 2012 11:53:32 +0200 Subject: [PATCH 1662/6849] ALSA: hda - Add the support for VIA HDMI pin detection This patch adds the hotplug unsol event handling to simple_hdmi*(). It works on VIA VX900. If AMD or Nvidia chips support the pin-detection similarly, it can be added easily, too. Reported-by: Annie Liu Tested-by: Annie Liu Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 696681826b01..8e7333b07b58 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1377,6 +1377,19 @@ static int simple_playback_build_pcms(struct hda_codec *codec) return 0; } +/* unsolicited event for jack sensing */ +static void simple_hdmi_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + snd_hda_jack_get_action(codec, res >> AC_UNSOL_RES_TAG_SHIFT); + snd_hda_jack_report_sync(codec); +} + +/* generic_hdmi_build_jack can be used for simple_hdmi, too, + * as long as spec->pins[] is set correctly + */ +#define simple_hdmi_build_jack generic_hdmi_build_jack + static int simple_playback_build_controls(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; @@ -1389,6 +1402,11 @@ static int simple_playback_build_controls(struct hda_codec *codec) spec->cvts[i].cvt_nid); if (err < 0) return err; + if (codec->patch_ops.unsol_event) { + err = simple_hdmi_build_jack(codec, i); + if (err < 0) + return err; + } } return 0; @@ -1876,6 +1894,7 @@ static struct hda_verb viahdmi_basic_init[] = { static int via_hdmi_init(struct hda_codec *codec) { snd_hda_sequence_write(codec, viahdmi_basic_init); + snd_hda_jack_report_sync(codec); return 0; } @@ -1884,6 +1903,7 @@ static const struct hda_codec_ops via_hdmi_patch_ops = { .build_pcms = simple_playback_build_pcms, .init = via_hdmi_init, .free = simple_playback_free, + .unsol_event = simple_hdmi_unsol_event, }; static struct hda_pcm_stream via_hdmi_digital_playback = { -- GitLab From 6d9359280753d2955f86d6411047516a9431eb51 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 15 Jun 2012 12:52:46 +0200 Subject: [PATCH 1663/6849] scsi: Silence unnecessary warnings about ioctl to partition Sometimes, warnings about ioctls to partition happen often enough that they form majority of the warnings in the kernel log and users complain. In some cases warnings are about ioctls such as SG_IO so it's not good to get rid of the warnings completely as they can ease debugging of userspace problems when ioctl is refused. Since I have seen warnings from lots of commands, including some proprietary userspace applications, I don't think disallowing the ioctls for processes with CAP_SYS_RAWIO will happen in the near future if ever. So lets just stop warning for processes with CAP_SYS_RAWIO for which ioctl is allowed. CC: Paolo Bonzini CC: James Bottomley CC: linux-scsi@vger.kernel.org Acked-by: Paolo Bonzini Signed-off-by: Jan Kara Signed-off-by: Jens Axboe --- block/scsi_ioctl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 260fa80ef575..9a87daa6f4fb 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -721,11 +721,14 @@ int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) break; } + if (capable(CAP_SYS_RAWIO)) + return 0; + /* In particular, rule out all resets and host-specific ioctls. */ printk_ratelimited(KERN_WARNING "%s: sending ioctl %x to a partition!\n", current->comm, cmd); - return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD; + return -ENOIOCTLCMD; } EXPORT_SYMBOL(scsi_verify_blk_ioctl); -- GitLab From 4f0110ced1b5d61e6df4871f6f800a9d3678bf26 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jun 2012 12:45:43 +0200 Subject: [PATCH 1664/6849] ALSA: hda - Merge ATI/VIA HDMI simple init functions Just a minor code cleanup to use the same function for both AMD and VIA simple_hdmi*(). Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 56 +++++++++++++++----------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8e7333b07b58..c9d0c98bbe86 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1412,6 +1412,24 @@ static int simple_playback_build_controls(struct hda_codec *codec) return 0; } +static int simple_playback_init(struct hda_codec *codec) +{ + struct hdmi_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_pins; i++) { + snd_hda_codec_write(codec, spec->pins[i].pin_nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + /* some codecs require to unmute the pin */ + if (get_wcaps(codec, spec->pins[i].pin_nid) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, spec->pins[i].pin_nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); + } + snd_hda_jack_report_sync(codec); + return 0; +} + static void simple_playback_free(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; @@ -1831,29 +1849,10 @@ static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { }, }; -static const struct hda_verb atihdmi_basic_init[] = { - /* enable digital output on pin widget */ - { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {} /* terminator */ -}; - -static int atihdmi_init(struct hda_codec *codec) -{ - struct hdmi_spec *spec = codec->spec; - - snd_hda_sequence_write(codec, atihdmi_basic_init); - /* SI codec requires to unmute the pin */ - if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP) - snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_UNMUTE); - return 0; -} - static const struct hda_codec_ops atihdmi_patch_ops = { .build_controls = simple_playback_build_controls, .build_pcms = simple_playback_build_pcms, - .init = atihdmi_init, + .init = simple_playback_init, .free = simple_playback_free, }; @@ -1872,6 +1871,7 @@ static int patch_atihdmi(struct hda_codec *codec) spec->multiout.max_channels = 2; spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; spec->num_cvts = 1; + spec->num_pins = 1; spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID; spec->pins[0].pin_nid = ATIHDMI_PIN_NID; spec->pcm_playback = &atihdmi_pcm_digital_playback; @@ -1885,23 +1885,10 @@ static int patch_atihdmi(struct hda_codec *codec) #define VIAHDMI_CVT_NID 0x02 /* audio converter1 */ #define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */ -static struct hda_verb viahdmi_basic_init[] = { - /* enable digital output on pin widget */ - { VIAHDMI_PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {} /* terminator */ -}; - -static int via_hdmi_init(struct hda_codec *codec) -{ - snd_hda_sequence_write(codec, viahdmi_basic_init); - snd_hda_jack_report_sync(codec); - return 0; -} - static const struct hda_codec_ops via_hdmi_patch_ops = { .build_controls = simple_playback_build_controls, .build_pcms = simple_playback_build_pcms, - .init = via_hdmi_init, + .init = simple_playback_init, .free = simple_playback_free, .unsol_event = simple_hdmi_unsol_event, }; @@ -1930,6 +1917,7 @@ static int patch_via_hdmi(struct hda_codec *codec) spec->multiout.max_channels = 2; spec->multiout.dig_out_nid = VIAHDMI_CVT_NID; /* pure-digital case */ spec->num_cvts = 1; + spec->num_pins = 1; spec->cvts[0].cvt_nid = VIAHDMI_CVT_NID; spec->pins[0].pin_nid = VIAHDMI_PIN_NID; spec->pcm_playback = &via_hdmi_digital_playback; -- GitLab From 1a12af1a751311e129ff8e8ca18f83613b78a83c Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 12 Jun 2012 12:42:17 +0200 Subject: [PATCH 1665/6849] usb: gadget: mass_storage: remove unused options This commit removes thread_name and lun_name_format fields from the fsg_config structure. Those fields are not used by any in-tree code and their usefulness is rather theoretical. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_mass_storage.c | 50 ++++++----------------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 72116fa49ffb..9b29e8eab18f 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -75,25 +75,6 @@ * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12) * commands for this LUN shall be ignored. * - * lun_name_format A printf-like format for names of the LUN - * devices. This determines how the - * directory in sysfs will be named. - * Unless you are using several MSFs in - * a single gadget (as opposed to single - * MSF in many configurations) you may - * leave it as NULL (in which case - * "lun%d" will be used). In the format - * you can use "%d" to index LUNs for - * MSF's with more than one LUN. (Beware - * that there is only one integer given - * as an argument for the format and - * specifying invalid format may cause - * unspecified behaviour.) - * thread_name Name of the kernel thread process used by the - * MSF. You can safely set it to NULL - * (in which case default "file-storage" - * will be used). - * * vendor_name * product_name * release Information used as a reply to INQUIRY @@ -155,15 +136,14 @@ * a buffer from being used by more than one endpoint. * * - * The pathnames of the backing files and the ro settings are - * available in the attribute files "file" and "ro" in the lun (or - * to be more precise in a directory which name comes from - * "lun_name_format" option!) subdirectory of the gadget's sysfs - * directory. If the "removable" option is set, writing to these - * files will simulate ejecting/loading the medium (writing an empty - * line means eject) and adjusting a write-enable tab. Changes to the - * ro setting are not allowed when the medium is loaded or if CD-ROM - * emulation is being used. + * The pathnames of the backing files, the ro settings and nofua + * settings are available in the attribute files "file", "ro" and + * "nofua" in the lun subdirectory of the gadget's sysfs directory. + * If the "removable" option is set, writing to these files will + * simulate ejecting/loading the medium (writing an empty line means + * eject) and adjusting a write-enable tab. Changes to the ro setting + * are not allowed when the medium is loaded or if CD-ROM emulation is + * being used. * * When a LUN receive an "eject" SCSI request (Start/Stop Unit), * if the LUN is removable, the backing file is released to simulate @@ -417,9 +397,6 @@ struct fsg_config { char nofua; } luns[FSG_MAX_LUNS]; - const char *lun_name_format; - const char *thread_name; - /* Callback functions. */ const struct fsg_operations *ops; /* Gadget's private data. */ @@ -2792,11 +2769,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, curlun->dev.parent = &gadget->dev; /* curlun->dev.driver = &fsg_driver.driver; XXX */ dev_set_drvdata(&curlun->dev, &common->filesem); - dev_set_name(&curlun->dev, - cfg->lun_name_format - ? cfg->lun_name_format - : "lun%d", - i); + dev_set_name(&curlun->dev, "lun%d", i); rc = device_register(&curlun->dev); if (rc) { @@ -2878,8 +2851,7 @@ buffhds_first_it: /* Tell the thread to start working */ common->thread_task = - kthread_create(fsg_main_thread, common, - cfg->thread_name ?: "file-storage"); + kthread_create(fsg_main_thread, common, "file-storage"); if (IS_ERR(common->thread_task)) { rc = PTR_ERR(common->thread_task); goto error_release; @@ -3175,8 +3147,6 @@ fsg_config_from_params(struct fsg_config *cfg, } /* Let MSF use defaults */ - cfg->lun_name_format = 0; - cfg->thread_name = 0; cfg->vendor_name = 0; cfg->product_name = 0; cfg->release = 0xffff; -- GitLab From a8287a4ed543494c121050dc453972902637e6de Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 12 Jun 2012 12:42:18 +0200 Subject: [PATCH 1666/6849] usb: gadget: mass_storage: add documentation This commit adds Documentation/usb/mass-storage.txt file. It contains description of how to use the mass storage gadget from user space. It elaborates on madule parameters and sysfs interface more then it was written in the comments in the source code. Signed-off-by: Michal Nazarewicz Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- Documentation/usb/mass-storage.txt | 226 ++++++++++++++++++++++++++++ drivers/usb/gadget/f_mass_storage.c | 69 +-------- 2 files changed, 233 insertions(+), 62 deletions(-) create mode 100644 Documentation/usb/mass-storage.txt diff --git a/Documentation/usb/mass-storage.txt b/Documentation/usb/mass-storage.txt new file mode 100644 index 000000000000..e9b9334627bf --- /dev/null +++ b/Documentation/usb/mass-storage.txt @@ -0,0 +1,226 @@ +* Overview + + Mass Storage Gadget (or MSG) acts as a USB Mass Storage device, + appearing to the host as a disk or a CD-ROM drive. It supports + multiple logical units (LUNs). Backing storage for each LUN is + provided by a regular file or a block device, access can be limited + to read-only, and gadget can indicate that it is removable and/or + CD-ROM (the latter implies read-only access). + + Its requirements are modest; only a bulk-in and a bulk-out endpoint + are needed. The memory requirement amounts to two 16K buffers. + Support is included for full-speed, high-speed and SuperSpeed + operation. + + Note that the driver is slightly non-portable in that it assumes + a single memory/DMA buffer will be useable for bulk-in and bulk-out + endpoints. With most device controllers this is not an issue, but + there may be some with hardware restrictions that prevent a buffer + from being used by more than one endpoint. + + This document describes how to use the gadget from user space, its + relation to mass storage function (or MSF) and different gadgets + using it, and how it differs from File Storage Gadget (or FSG). It + will talk only briefly about how to use MSF within composite + gadgets. + +* Module parameters + + The mass storage gadget accepts the following mass storage specific + module parameters: + + - file=filename[,filename...] + + This parameter lists paths to files or block devices used for + backing storage for each logical unit. There may be at most + FSG_MAX_LUNS (8) LUNs set. If more files are specified, they will + be silently ignored. See also “luns” parameter. + + *BEWARE* that if a file is used as a backing storage, it may not + be modified by any other process. This is because the host + assumes the data does not change without its knowledge. It may be + read, but (if the logical unit is writable) due to buffering on + the host side, the contents are not well defined. + + The size of the logical unit will be rounded down to a full + logical block. The logical block size is 2048 bytes for LUNs + simulating CD-ROM, block size of the device if the backing file is + a block device, or 512 bytes otherwise. + + - removable=b[,b...] + + This parameter specifies whether each logical unit should be + removable. “b” here is either “y”, “Y” or “1” for true or “n”, + “N” or “0” for false. + + If this option is set for a logical unit, gadget will accept an + “eject” SCSI request (Start/Stop Unit). When it is sent, the + backing file will be closed to simulate ejection and the logical + unit will not be mountable by the host until a new backing file is + specified by userspace on the device (see “sysfs entries” + section). + + If a logical unit is not removable (the default), a backing file + must be specified for it with the “file” parameter as the module + is loaded. The same applies if the module is built in, no + exceptions. + + The default value of the flag is false, *HOWEVER* it used to be + true. This has been changed to better match File Storage Gadget + and because it seems like a saner default after all. Thus to + maintain compatibility with older kernels, it's best to specify + the default values. Also, if one relied on old default, explicit + “n” needs to be specified now. + + Note that “removable” means the logical unit's media can be + ejected or removed (as is true for a CD-ROM drive or a card + reader). It does *not* mean that the entire gadget can be + unplugged from the host; the proper term for that is + “hot-unpluggable”. + + - cdrom=b[,b...] + + This parameter specifies whether each logical unit should simulate + CD-ROM. The default is false. + + - ro=b[,b...] + + This parameter specifies whether each logical unit should be + reported as read only. This will prevent host from modifying the + backing files. + + Note that if this flag for given logical unit is false but the + backing file could not be opened in read/write mode, the gadget + will fall back to read only mode anyway. + + The default value for non-CD-ROM logical units is false; for + logical units simulating CD-ROM it is forced to true. + + - nofua=b[,b...] + + This parameter specifies whether FUA flag should be ignored in SCSI + Write10 and Write12 commands sent to given logical units. + + MS Windows mounts removable storage in “Removal optimised mode” by + default. All the writes to the media are synchronous, which is + achieved by setting the FUA (Force Unit Access) bit in SCSI + Write(10,12) commands. This forces each write to wait until the + data has actually been written out and prevents I/O requests + aggregation in block layer dramatically decreasing performance. + + Note that this may mean that if the device is powered from USB and + the user unplugs the device without unmounting it first (which at + least some Windows users do), the data may be lost. + + The default value is false. + + - luns=N + + This parameter specifies number of logical units the gadget will + have. It is limited by FSG_MAX_LUNS (8) and higher value will be + capped. + + If this parameter is provided, and the number of files specified + in “file” argument is greater then the value of “luns”, all excess + files will be ignored. + + If this parameter is not present, the number of logical units will + be deduced from the number of files specified in the “file” + parameter. If the file parameter is missing as well, one is + assumed. + + - stall=b + + Specifies whether the gadget is allowed to halt bulk endpoints. + The default is determined according to the type of USB device + controller, but usually true. + + In addition to the above, the gadget also accepts the following + parameters defined by the composite framework (they are common to + all composite gadgets so just a quick listing): + + - idVendor -- USB Vendor ID (16 bit integer) + - idProduct -- USB Product ID (16 bit integer) + - bcdDevice -- USB Device version (BCD) (16 bit integer) + - iManufacturer -- USB Manufacturer string (string) + - iProduct -- USB Product string (string) + - iSerialNumber -- SerialNumber string (sting) + +* sysfs entries + + For each logical unit, the gadget creates a directory in the sysfs + hierarchy. Inside of it the following three files are created: + + - file + + When read it returns the path to the backing file for the given + logical unit. If there is no backing file (possible only if the + logical unit is removable), the content is empty. + + When written into, it changes the backing file for given logical + unit. This change can be performed even if given logical unit is + not specified as removable (but that may look strange to the + host). It may fail, however, if host disallowed medium removal + with the Prevent-Allow Medium Removal SCSI command. + + - ro + + Reflects the state of ro flag for the given logical unit. It can + be read any time, and written to when there is no backing file + open for given logical unit. + + - nofua + + Reflects the state of nofua flag for given logical unit. It can + be read and written. + + Other then those, as usual, the values of module parameters can be + read from /sys/module/g_mass_storage/parameters/* files. + +* Other gadgets using mass storage function + + The Mass Storage Gadget uses the Mass Storage Function to handle + mass storage protocol. As a composite function, MSF may be used by + other gadgets as well (eg. g_multi and acm_ms). + + All of the information in previous sections are valid for other + gadgets using MSF, except that support for mass storage related + module parameters may be missing, or the parameters may have + a prefix. To figure out whether any of this is true one needs to + consult the gadget's documentation or its source code. + + For examples of how to include mass storage function in gadgets, one + may take a look at mass_storage.c, acm_ms.c and multi.c (sorted by + complexity). + +* Relation to file storage gadget + + The Mass Storage Function and thus the Mass Storage Gadget has been + based on the File Storage Gadget. The difference between the two is + that MSG is a composite gadget (ie. uses the composite framework) + while file storage gadget is a traditional gadget. From userspace + point of view this distinction does not really matter, but from + kernel hacker's point of view, this means that (i) MSG does not + duplicate code needed for handling basic USB protocol commands and + (ii) MSF can be used in any other composite gadget. + + Because of that, File Storage Gadget has been deprecated and + scheduled to be removed in Linux 3.8. All users need to transition + to the Mass Storage Gadget by that time. The two gadgets behave + mostly the same from the outside except: + + 1. In FSG the “removable” and “cdrom” module parameters set the flag + for all logical units whereas in MSG they accept a list of y/n + values for each logical unit. If one uses only a single logical + unit this does not matter, but if there are more, the y/n value + needs to be repeated for each logical unit. + + 2. FSG's “serial”, “vendor”, “product” and “release” module + parameters are handled in MSG by the composite layer's parameters + named respectively: “iSerialnumber”, “idVendor”, “idProduct” and + “bcdDevice”. + + 3. MSG does not support FSG's test mode, thus “transport”, + “protocol” and “buflen” FSG's module parameters are not + supported. MSG always uses SCSI protocol with bulk only + transport mode and 16 KiB buffers. diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 9b29e8eab18f..7ad4f819752d 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -44,12 +44,12 @@ * function for a USB device, it also illustrates a technique of * double-buffering for increased throughput. * - * Function supports multiple logical units (LUNs). Backing storage - * for each LUN is provided by a regular file or a block device. - * Access for each LUN can be limited to read-only. Moreover, the - * function can indicate that LUN is removable and/or CD-ROM. (The - * later implies read-only access.) - * + * For more information about MSF and in particular its module + * parameters and sysfs interface read the + * file. + */ + +/* * MSF is configured by specifying a fsg_config structure. It has the * following fields: * @@ -95,61 +95,6 @@ * data track and no audio tracks; hence there need be only one * backing file per LUN. * - * - * MSF includes support for module parameters. If gadget using it - * decides to use it, the following module parameters will be - * available: - * - * file=filename[,filename...] - * Names of the files or block devices used for - * backing storage. - * ro=b[,b...] Default false, boolean for read-only access. - * removable=b[,b...] - * Default false, boolean for removable media. - * cdrom=b[,b...] Default false, boolean for whether to emulate - * a CD-ROM drive. - * nofua=b[,b...] Default false, booleans for ignore FUA flag - * in SCSI WRITE(10,12) commands - * luns=N Default N = number of filenames, number of - * LUNs to support. - * stall Default determined according to the type of - * USB device controller (usually true), - * boolean to permit the driver to halt - * bulk endpoints. - * - * The module parameters may be prefixed with some string. You need - * to consult gadget's documentation or source to verify whether it is - * using those module parameters and if it does what are the prefixes - * (look for FSG_MODULE_PARAMETERS() macro usage, what's inside it is - * the prefix). - * - * - * Requirements are modest; only a bulk-in and a bulk-out endpoint are - * needed. The memory requirement amounts to two 16K buffers, size - * configurable by a parameter. Support is included for both - * full-speed and high-speed operation. - * - * Note that the driver is slightly non-portable in that it assumes a - * single memory/DMA buffer will be useable for bulk-in, bulk-out, and - * interrupt-in endpoints. With most device controllers this isn't an - * issue, but there may be some with hardware restrictions that prevent - * a buffer from being used by more than one endpoint. - * - * - * The pathnames of the backing files, the ro settings and nofua - * settings are available in the attribute files "file", "ro" and - * "nofua" in the lun subdirectory of the gadget's sysfs directory. - * If the "removable" option is set, writing to these files will - * simulate ejecting/loading the medium (writing an empty line means - * eject) and adjusting a write-enable tab. Changes to the ro setting - * are not allowed when the medium is loaded or if CD-ROM emulation is - * being used. - * - * When a LUN receive an "eject" SCSI request (Start/Stop Unit), - * if the LUN is removable, the backing file is released to simulate - * ejection. - * - * * This function is heavily based on "File-backed Storage Gadget" by * Alan Stern which in turn is heavily based on "Gadget Zero" by David * Brownell. The driver's SCSI command interface was based on the @@ -191,7 +136,7 @@ * In normal operation the main thread is started during the gadget's * fsg_bind() callback and stopped during fsg_unbind(). But it can * also exit when it receives a signal, and there's no point leaving - * the gadget running when the thread is dead. At of this moment, MSF + * the gadget running when the thread is dead. As of this moment, MSF * provides no way to deregister the gadget when thread dies -- maybe * a callback functions is needed. * -- GitLab From 99c515005857ff7d6cd5c2ba272ccab5dc0ea648 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 13 Jun 2012 12:54:45 +0200 Subject: [PATCH 1667/6849] usb: gadget: hidg: register OUT INT endpoint for SET_REPORT The hidg function driver currently handles its SET_REPORT calls via EP0. This is the implicit behaviour when no OUT interrupt endpoint is configured and generally works fine. The problem is that due to EP0's role in the gadget framework, we cannot hold back packets and control traffic flow to sync it to the char device, and hence there's a high risk of loosing packets with this implementation. This patch adds an OUT interrupt endpoint to the interface and queues a fix number of request to catch SET_REPORT events. According to the specs, host drivers should always use the dedicated OUT endpoint when present. The char device's read implementation was rewritten to retrieve data from the list of completed output requests. Signed-off-by: Daniel Mack Cc: Felipe Balbi Cc: Greg Kroah-Hartman Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_hid.c | 208 +++++++++++++++++++++++++++++-------- 1 file changed, 165 insertions(+), 43 deletions(-) diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c index 3b3932c55361..16a8b1c15c62 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/f_hid.c @@ -26,6 +26,12 @@ static struct class *hidg_class; /*-------------------------------------------------------------------------*/ /* HID gadget struct */ +struct f_hidg_req_list { + struct usb_request *req; + unsigned int pos; + struct list_head list; +}; + struct f_hidg { /* configuration */ unsigned char bInterfaceSubClass; @@ -35,10 +41,10 @@ struct f_hidg { unsigned short report_length; /* recv report */ - char *set_report_buff; - unsigned short set_report_length; + struct list_head completed_out_req; spinlock_t spinlock; wait_queue_head_t read_queue; + unsigned int qlen; /* send report */ struct mutex lock; @@ -49,7 +55,9 @@ struct f_hidg { int minor; struct cdev cdev; struct usb_function func; + struct usb_ep *in_ep; + struct usb_ep *out_ep; }; static inline struct f_hidg *func_to_hidg(struct usb_function *f) @@ -65,7 +73,7 @@ static struct usb_interface_descriptor hidg_interface_desc = { .bDescriptorType = USB_DT_INTERFACE, /* .bInterfaceNumber = DYNAMIC */ .bAlternateSetting = 0, - .bNumEndpoints = 1, + .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_HID, /* .bInterfaceSubClass = DYNAMIC */ /* .bInterfaceProtocol = DYNAMIC */ @@ -96,10 +104,23 @@ static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = { */ }; +static struct usb_endpoint_descriptor hidg_hs_out_ep_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_INT, + /*.wMaxPacketSize = DYNAMIC */ + .bInterval = 4, /* FIXME: Add this field in the + * HID gadget configuration? + * (struct hidg_func_descriptor) + */ +}; + static struct usb_descriptor_header *hidg_hs_descriptors[] = { (struct usb_descriptor_header *)&hidg_interface_desc, (struct usb_descriptor_header *)&hidg_desc, (struct usb_descriptor_header *)&hidg_hs_in_ep_desc, + (struct usb_descriptor_header *)&hidg_hs_out_ep_desc, NULL, }; @@ -117,10 +138,23 @@ static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = { */ }; +static struct usb_endpoint_descriptor hidg_fs_out_ep_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_INT, + /*.wMaxPacketSize = DYNAMIC */ + .bInterval = 10, /* FIXME: Add this field in the + * HID gadget configuration? + * (struct hidg_func_descriptor) + */ +}; + static struct usb_descriptor_header *hidg_fs_descriptors[] = { (struct usb_descriptor_header *)&hidg_interface_desc, (struct usb_descriptor_header *)&hidg_desc, (struct usb_descriptor_header *)&hidg_fs_in_ep_desc, + (struct usb_descriptor_header *)&hidg_fs_out_ep_desc, NULL, }; @@ -130,9 +164,11 @@ static struct usb_descriptor_header *hidg_fs_descriptors[] = { static ssize_t f_hidg_read(struct file *file, char __user *buffer, size_t count, loff_t *ptr) { - struct f_hidg *hidg = file->private_data; - char *tmp_buff = NULL; - unsigned long flags; + struct f_hidg *hidg = file->private_data; + struct f_hidg_req_list *list; + struct usb_request *req; + unsigned long flags; + int ret; if (!count) return 0; @@ -142,8 +178,9 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, spin_lock_irqsave(&hidg->spinlock, flags); -#define READ_COND (hidg->set_report_buff != NULL) +#define READ_COND (!list_empty(&hidg->completed_out_req)) + /* wait for at least one buffer to complete */ while (!READ_COND) { spin_unlock_irqrestore(&hidg->spinlock, flags); if (file->f_flags & O_NONBLOCK) @@ -155,19 +192,34 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, spin_lock_irqsave(&hidg->spinlock, flags); } - - count = min_t(unsigned, count, hidg->set_report_length); - tmp_buff = hidg->set_report_buff; - hidg->set_report_buff = NULL; - + /* pick the first one */ + list = list_first_entry(&hidg->completed_out_req, + struct f_hidg_req_list, list); + req = list->req; + count = min_t(unsigned int, count, req->actual - list->pos); spin_unlock_irqrestore(&hidg->spinlock, flags); - if (tmp_buff != NULL) { - /* copy to user outside spinlock */ - count -= copy_to_user(buffer, tmp_buff, count); - kfree(tmp_buff); - } else - count = -ENOMEM; + /* copy to user outside spinlock */ + count -= copy_to_user(buffer, req->buf + list->pos, count); + list->pos += count; + + /* + * if this request is completely handled and transfered to + * userspace, remove its entry from the list and requeue it + * again. Otherwise, we will revisit it again upon the next + * call, taking into account its current read position. + */ + if (list->pos == req->actual) { + spin_lock_irqsave(&hidg->spinlock, flags); + list_del(&list->list); + kfree(list); + spin_unlock_irqrestore(&hidg->spinlock, flags); + + req->length = hidg->report_length; + ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL); + if (ret < 0) + return ret; + } return count; } @@ -282,28 +334,37 @@ static int f_hidg_open(struct inode *inode, struct file *fd) /*-------------------------------------------------------------------------*/ /* usb_function */ -static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) +static struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, unsigned length) { - struct f_hidg *hidg = (struct f_hidg *)req->context; - - if (req->status != 0 || req->buf == NULL || req->actual == 0) { - ERROR(hidg->func.config->cdev, "%s FAILED\n", __func__); - return; + struct usb_request *req; + + req = usb_ep_alloc_request(ep, GFP_ATOMIC); + if (req) { + req->length = length; + req->buf = kmalloc(length, GFP_ATOMIC); + if (!req->buf) { + usb_ep_free_request(ep, req); + req = NULL; + } } + return req; +} - spin_lock(&hidg->spinlock); - - hidg->set_report_buff = krealloc(hidg->set_report_buff, - req->actual, GFP_ATOMIC); +static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct f_hidg *hidg = (struct f_hidg *) req->context; + struct f_hidg_req_list *req_list; + unsigned long flags; - if (hidg->set_report_buff == NULL) { - spin_unlock(&hidg->spinlock); + req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC); + if (!req_list) return; - } - hidg->set_report_length = req->actual; - memcpy(hidg->set_report_buff, req->buf, req->actual); - spin_unlock(&hidg->spinlock); + req_list->req = req; + + spin_lock_irqsave(&hidg->spinlock, flags); + list_add_tail(&req_list->list, &hidg->completed_out_req); + spin_unlock_irqrestore(&hidg->spinlock, flags); wake_up(&hidg->read_queue); } @@ -344,9 +405,7 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_SET_REPORT): VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength); - req->context = hidg; - req->complete = hidg_set_report_complete; - goto respond; + goto stall; break; case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 @@ -403,16 +462,25 @@ respond: static void hidg_disable(struct usb_function *f) { struct f_hidg *hidg = func_to_hidg(f); + struct f_hidg_req_list *list, *next; usb_ep_disable(hidg->in_ep); hidg->in_ep->driver_data = NULL; + + usb_ep_disable(hidg->out_ep); + hidg->out_ep->driver_data = NULL; + + list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { + list_del(&list->list); + kfree(list); + } } static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct usb_composite_dev *cdev = f->config->cdev; struct f_hidg *hidg = func_to_hidg(f); - int status = 0; + int i, status = 0; VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); @@ -429,11 +497,55 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } status = usb_ep_enable(hidg->in_ep); if (status < 0) { - ERROR(cdev, "Enable endpoint FAILED!\n"); + ERROR(cdev, "Enable IN endpoint FAILED!\n"); goto fail; } hidg->in_ep->driver_data = hidg; } + + + if (hidg->out_ep != NULL) { + /* restart endpoint */ + if (hidg->out_ep->driver_data != NULL) + usb_ep_disable(hidg->out_ep); + + status = config_ep_by_speed(f->config->cdev->gadget, f, + hidg->out_ep); + if (status) { + ERROR(cdev, "config_ep_by_speed FAILED!\n"); + goto fail; + } + status = usb_ep_enable(hidg->out_ep); + if (status < 0) { + ERROR(cdev, "Enable IN endpoint FAILED!\n"); + goto fail; + } + hidg->out_ep->driver_data = hidg; + + /* + * allocate a bunch of read buffers and queue them all at once. + */ + for (i = 0; i < hidg->qlen && status == 0; i++) { + struct usb_request *req = + hidg_alloc_ep_req(hidg->out_ep, + hidg->report_length); + if (req) { + req->complete = hidg_set_report_complete; + req->context = hidg; + status = usb_ep_queue(hidg->out_ep, req, + GFP_ATOMIC); + if (status) + ERROR(cdev, "%s queue req --> %d\n", + hidg->out_ep->name, status); + } else { + usb_ep_disable(hidg->out_ep); + hidg->out_ep->driver_data = NULL; + status = -ENOMEM; + goto fail; + } + } + } + fail: return status; } @@ -470,13 +582,18 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) ep->driver_data = c->cdev; /* claim */ hidg->in_ep = ep; + ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); + if (!ep) + goto fail; + ep->driver_data = c->cdev; /* claim */ + hidg->out_ep = ep; + /* preallocate request and buffer */ status = -ENOMEM; hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); if (!hidg->req) goto fail; - hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); if (!hidg->req->buf) goto fail; @@ -486,12 +603,12 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); + hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); + hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; hidg_desc.desc[0].wDescriptorLength = cpu_to_le16(hidg->report_desc_length); - hidg->set_report_buff = NULL; - /* copy descriptors */ f->descriptors = usb_copy_descriptors(hidg_fs_descriptors); if (!f->descriptors) @@ -500,6 +617,8 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) if (gadget_is_dualspeed(c->cdev->gadget)) { hidg_hs_in_ep_desc.bEndpointAddress = hidg_fs_in_ep_desc.bEndpointAddress; + hidg_hs_out_ep_desc.bEndpointAddress = + hidg_fs_out_ep_desc.bEndpointAddress; f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors); if (!f->hs_descriptors) goto fail; @@ -509,6 +628,7 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) spin_lock_init(&hidg->spinlock); init_waitqueue_head(&hidg->write_queue); init_waitqueue_head(&hidg->read_queue); + INIT_LIST_HEAD(&hidg->completed_out_req); /* create char device */ cdev_init(&hidg->cdev, &f_hidg_fops); @@ -553,7 +673,6 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) usb_free_descriptors(f->descriptors); kfree(hidg->report_desc); - kfree(hidg->set_report_buff); kfree(hidg); } @@ -624,6 +743,9 @@ int __init hidg_bind_config(struct usb_configuration *c, hidg->func.disable = hidg_disable; hidg->func.setup = hidg_setup; + /* this could me made configurable at some point */ + hidg->qlen = 4; + status = usb_add_function(c, &hidg->func); if (status) kfree(hidg); -- GitLab From 22258f4906aa87e0c0debcad22cb292453e2ebfb Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 14 Jun 2012 10:02:24 +0200 Subject: [PATCH 1668/6849] usb: hsotg: samsung: Replace endpoint specific locks with a global lock The endpoint specific locks are replaced with a global lock. This is crucial for running s3c-hsotg driver on a SMP SoC. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 54 ++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index d37585105bb4..b10791282f15 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -112,7 +112,6 @@ struct s3c_hsotg_ep { struct s3c_hsotg_req *req; struct dentry *debugfs; - spinlock_t lock; unsigned long total_data; unsigned int size_loaded; @@ -156,6 +155,8 @@ struct s3c_hsotg { struct usb_gadget_driver *driver; struct s3c_hsotg_plat *plat; + spinlock_t lock; + void __iomem *regs; int irq; struct clk *clk; @@ -901,6 +902,8 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, ep->name, req, req->length, req->buf, req->no_interrupt, req->zero, req->short_not_ok); + spin_lock_irqsave(&hs->lock, irqflags); + /* initialise status of the request */ INIT_LIST_HEAD(&hs_req->queue); req->actual = 0; @@ -913,15 +916,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, return ret; } - spin_lock_irqsave(&hs_ep->lock, irqflags); - first = list_empty(&hs_ep->queue); list_add_tail(&hs_req->queue, &hs_ep->queue); if (first) s3c_hsotg_start_req(hs, hs_ep, hs_req, false); - spin_unlock_irqrestore(&hs_ep->lock, irqflags); + spin_unlock_irqrestore(&hs->lock, irqflags); return 0; } @@ -1381,9 +1382,9 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, */ if (hs_req->req.complete) { - spin_unlock(&hs_ep->lock); + spin_unlock(&hsotg->lock); hs_req->req.complete(&hs_ep->ep, &hs_req->req); - spin_lock(&hs_ep->lock); + spin_lock(&hsotg->lock); } /* @@ -1418,9 +1419,9 @@ static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, { unsigned long flags; - spin_lock_irqsave(&hs_ep->lock, flags); + spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); - spin_unlock_irqrestore(&hs_ep->lock, flags); + spin_unlock_irqrestore(&hsotg->lock, flags); } /** @@ -1442,6 +1443,8 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) int max_req; int read_ptr; + spin_lock(&hsotg->lock); + if (!hs_req) { u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); int ptr; @@ -1454,11 +1457,10 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) for (ptr = 0; ptr < size; ptr += 4) (void)readl(fifo); + spin_unlock(&hsotg->lock); return; } - spin_lock(&hs_ep->lock); - to_read = size; read_ptr = hs_req->req.actual; max_req = hs_req->req.length - read_ptr; @@ -1486,7 +1488,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) */ readsl(fifo, hs_req->req.buf + read_ptr, to_read); - spin_unlock(&hs_ep->lock); + spin_unlock(&hsotg->lock); } /** @@ -2123,7 +2125,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, struct s3c_hsotg_req *req, *treq; unsigned long flags; - spin_lock_irqsave(&ep->lock, flags); + spin_lock_irqsave(&hsotg->lock, flags); list_for_each_entry_safe(req, treq, &ep->queue, queue) { /* @@ -2138,7 +2140,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, result); } - spin_unlock_irqrestore(&ep->lock, flags); + spin_unlock_irqrestore(&hsotg->lock, flags); } #define call_gadget(_hs, _entry) \ @@ -2602,7 +2604,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", __func__, epctrl, epctrl_reg); - spin_lock_irqsave(&hs_ep->lock, flags); + spin_lock_irqsave(&hsotg->lock, flags); epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); epctrl |= DxEPCTL_MPS(mps); @@ -2681,7 +2683,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); out: - spin_unlock_irqrestore(&hs_ep->lock, flags); + spin_unlock_irqrestore(&hsotg->lock, flags); return ret; } @@ -2711,7 +2713,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) /* terminate all requests with shutdown */ kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); - spin_lock_irqsave(&hs_ep->lock, flags); + spin_lock_irqsave(&hsotg->lock, flags); ctrl = readl(hsotg->regs + epctrl_reg); ctrl &= ~DxEPCTL_EPEna; @@ -2724,7 +2726,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) /* disable endpoint interrupts */ s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); - spin_unlock_irqrestore(&hs_ep->lock, flags); + spin_unlock_irqrestore(&hsotg->lock, flags); return 0; } @@ -2759,15 +2761,15 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); - spin_lock_irqsave(&hs_ep->lock, flags); + spin_lock_irqsave(&hs->lock, flags); if (!on_list(hs_ep, hs_req)) { - spin_unlock_irqrestore(&hs_ep->lock, flags); + spin_unlock_irqrestore(&hs->lock, flags); return -EINVAL; } s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); - spin_unlock_irqrestore(&hs_ep->lock, flags); + spin_unlock_irqrestore(&hs->lock, flags); return 0; } @@ -2789,7 +2791,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); - spin_lock_irqsave(&hs_ep->lock, irqflags); + spin_lock_irqsave(&hs->lock, irqflags); /* write both IN and OUT control registers */ @@ -2825,7 +2827,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) writel(epctl, hs->regs + epreg); - spin_unlock_irqrestore(&hs_ep->lock, irqflags); + spin_unlock_irqrestore(&hs->lock, irqflags); return 0; } @@ -3061,8 +3063,6 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, INIT_LIST_HEAD(&hs_ep->queue); INIT_LIST_HEAD(&hs_ep->ep.ep_list); - spin_lock_init(&hs_ep->lock); - /* add to the list of endpoints known by the gadget driver */ if (epnum) list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); @@ -3340,7 +3340,7 @@ static int ep_show(struct seq_file *seq, void *v) seq_printf(seq, "request list (%p,%p):\n", ep->queue.next, ep->queue.prev); - spin_lock_irqsave(&ep->lock, flags); + spin_lock_irqsave(&hsotg->lock, flags); list_for_each_entry(req, &ep->queue, queue) { if (--show_limit < 0) { @@ -3355,7 +3355,7 @@ static int ep_show(struct seq_file *seq, void *v) req->req.actual, req->req.status); } - spin_unlock_irqrestore(&ep->lock, flags); + spin_unlock_irqrestore(&hsotg->lock, flags); return 0; } @@ -3507,6 +3507,8 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) goto err_clk; } + spin_lock_init(&hsotg->lock); + hsotg->irq = ret; ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, -- GitLab From 2b19a52cc8a31ede990323d46a7faeeeba76bb8f Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 14 Jun 2012 10:02:25 +0200 Subject: [PATCH 1669/6849] usb: hsotg: samsung: Protect the udc_stop routine with spinlock Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b10791282f15..ee1fe2b8b07f 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2988,6 +2988,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct s3c_hsotg *hsotg = to_hsotg(gadget); + unsigned long flags = 0; int ep; if (!hsotg) @@ -3000,6 +3001,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, for (ep = 0; ep < hsotg->num_of_eps; ep++) s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); + spin_lock_irqsave(&hsotg->lock, flags); + s3c_hsotg_phy_disable(hsotg); regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -3007,6 +3010,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, hsotg->gadget.speed = USB_SPEED_UNKNOWN; hsotg->gadget.dev.driver = NULL; + spin_unlock_irqrestore(&hsotg->lock, flags); + dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", driver->driver.name); -- GitLab From 5ad1d3160973c588db806072968d7a2a93cb2a80 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 14 Jun 2012 10:02:26 +0200 Subject: [PATCH 1670/6849] usb: hsotg: samsung: smp Provide *_lock functions abstraction layer for SMP SoCs For SMP processors the spin_lock_irqsave is _only_ able to disable interrupt on a core on which it is executed. Therefore there may be a situation when other cores raise s3c-hsotg IRQ. Then there are several places where critical sections can be overwritten. To protect the above thread, a spin_lock in the interrupt handler has been added. Due to coherent memory view (especially L1 cache) the spin lock variable control access to IRQ handler only for one CPU core. In this way serialization to access this driver is provided and hence several spin_lock_* routines could be removed from IRQ handler's related functions. The complete_request_lock function has been removed since all its calls are performed from interrupt (spin lock protected) context. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 97 +++++++++++++++++----------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index ee1fe2b8b07f..d208c46341d7 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -895,15 +895,12 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, struct s3c_hsotg_req *hs_req = our_req(req); struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct s3c_hsotg *hs = hs_ep->parent; - unsigned long irqflags; bool first; dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", ep->name, req, req->length, req->buf, req->no_interrupt, req->zero, req->short_not_ok); - spin_lock_irqsave(&hs->lock, irqflags); - /* initialise status of the request */ INIT_LIST_HEAD(&hs_req->queue); req->actual = 0; @@ -922,11 +919,24 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, if (first) s3c_hsotg_start_req(hs, hs_ep, hs_req, false); - spin_unlock_irqrestore(&hs->lock, irqflags); - return 0; } +static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, + gfp_t gfp_flags) +{ + struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct s3c_hsotg *hs = hs_ep->parent; + unsigned long flags = 0; + int ret = 0; + + spin_lock_irqsave(&hs->lock, flags); + ret = s3c_hsotg_ep_queue(ep, req, gfp_flags); + spin_unlock_irqrestore(&hs->lock, flags); + + return ret; +} + static void s3c_hsotg_ep_free_request(struct usb_ep *ep, struct usb_request *req) { @@ -1402,28 +1412,6 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, } } -/** - * s3c_hsotg_complete_request_lock - complete a request given to us (locked) - * @hsotg: The device state. - * @hs_ep: The endpoint the request was on. - * @hs_req: The request to complete. - * @result: The result code (0 => Ok, otherwise errno) - * - * See s3c_hsotg_complete_request(), but called with the endpoint's - * lock held. - */ -static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, - struct s3c_hsotg_req *hs_req, - int result) -{ - unsigned long flags; - - spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); - spin_unlock_irqrestore(&hsotg->lock, flags); -} - /** * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint * @hsotg: The device state. @@ -1443,7 +1431,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) int max_req; int read_ptr; - spin_lock(&hsotg->lock); if (!hs_req) { u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); @@ -1457,7 +1444,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) for (ptr = 0; ptr < size; ptr += 4) (void)readl(fifo); - spin_unlock(&hsotg->lock); return; } @@ -1487,8 +1473,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) * alignment of the data. */ readsl(fifo, hs_req->req.buf + read_ptr, to_read); - - spin_unlock(&hsotg->lock); } /** @@ -1609,7 +1593,7 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, s3c_hsotg_send_zlp(hsotg, hs_req); } - s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, result); + s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); } /** @@ -1864,7 +1848,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, /* Finish ZLP handling for IN EP0 transactions */ if (hsotg->eps[0].sent_zlp) { dev_dbg(hsotg->dev, "zlp packet received\n"); - s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); + s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); return; } @@ -1915,7 +1899,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); } else - s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); + s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); } /** @@ -2123,9 +2107,6 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, int result, bool force) { struct s3c_hsotg_req *req, *treq; - unsigned long flags; - - spin_lock_irqsave(&hsotg->lock, flags); list_for_each_entry_safe(req, treq, &ep->queue, queue) { /* @@ -2139,14 +2120,15 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, s3c_hsotg_complete_request(hsotg, ep, req, result); } - - spin_unlock_irqrestore(&hsotg->lock, flags); } #define call_gadget(_hs, _entry) \ if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ - (_hs)->driver && (_hs)->driver->_entry) \ - (_hs)->driver->_entry(&(_hs)->gadget); + (_hs)->driver && (_hs)->driver->_entry) { \ + spin_unlock(&_hs->lock); \ + (_hs)->driver->_entry(&(_hs)->gadget); \ + spin_lock(&_hs->lock); \ + } /** * s3c_hsotg_disconnect - disconnect service @@ -2388,6 +2370,7 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) u32 gintsts; u32 gintmsk; + spin_lock(&hsotg->lock); irq_retry: gintsts = readl(hsotg->regs + GINTSTS); gintmsk = readl(hsotg->regs + GINTMSK); @@ -2557,6 +2540,8 @@ irq_retry: if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) goto irq_retry; + spin_unlock(&hsotg->lock); + return IRQ_HANDLED; } @@ -2710,10 +2695,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); + spin_lock_irqsave(&hsotg->lock, flags); /* terminate all requests with shutdown */ kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); - spin_lock_irqsave(&hsotg->lock, flags); ctrl = readl(hsotg->regs + epctrl_reg); ctrl &= ~DxEPCTL_EPEna; @@ -2784,15 +2769,12 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct s3c_hsotg *hs = hs_ep->parent; int index = hs_ep->index; - unsigned long irqflags; u32 epreg; u32 epctl; u32 xfertype; dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); - spin_lock_irqsave(&hs->lock, irqflags); - /* write both IN and OUT control registers */ epreg = DIEPCTL(index); @@ -2827,19 +2809,36 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) writel(epctl, hs->regs + epreg); - spin_unlock_irqrestore(&hs->lock, irqflags); - return 0; } +/** + * s3c_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held + * @ep: The endpoint to set halt. + * @value: Set or unset the halt. + */ +static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) +{ + struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct s3c_hsotg *hs = hs_ep->parent; + unsigned long flags = 0; + int ret = 0; + + spin_lock_irqsave(&hs->lock, flags); + ret = s3c_hsotg_ep_sethalt(ep, value); + spin_unlock_irqrestore(&hs->lock, flags); + + return ret; +} + static struct usb_ep_ops s3c_hsotg_ep_ops = { .enable = s3c_hsotg_ep_enable, .disable = s3c_hsotg_ep_disable, .alloc_request = s3c_hsotg_ep_alloc_request, .free_request = s3c_hsotg_ep_free_request, - .queue = s3c_hsotg_ep_queue, + .queue = s3c_hsotg_ep_queue_lock, .dequeue = s3c_hsotg_ep_dequeue, - .set_halt = s3c_hsotg_ep_sethalt, + .set_halt = s3c_hsotg_ep_sethalt_lock, /* note, don't believe we have any call for the fifo routines */ }; -- GitLab From e8d4e8be860d935099ffcf695dcd29b55ae50b36 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Fri, 15 Jun 2012 11:54:00 +0530 Subject: [PATCH 1671/6849] usb: dwc3: fix giveback of queued request in ep_dequeue In case of ep_dequeue , if dequeued request was submitted for dma transfer, then endpoint is stopped. Once endpoint is stooped, callback for the dequeued request must be called. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3df1a1973b05..ec70df7aba17 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1091,7 +1091,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { /* wait until it is processed */ dwc3_stop_active_transfer(dwc, dep->number); - goto out0; + goto out1; } dev_err(dwc->dev, "request %p was not queued to %s\n", request, ep->name); @@ -1099,6 +1099,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; } +out1: /* giveback the request */ dwc3_gadget_giveback(dep, req, -ECONNRESET); -- GitLab From 1591633ed6c4c3994944f31ddb59bc072a2ed0ca Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Fri, 15 Jun 2012 11:54:36 +0530 Subject: [PATCH 1672/6849] usb: dwc3: giveback all queued request when ep disabled or reset received In case of ep_disable and reset interrupt is received and, still there was at least one request queued for dma transfer, then endpoint is stopped first. Once endpoint is stopped, callback for all queued request must be called. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 38cd13ffae9d..f6fb42da2e64 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -579,8 +579,11 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) */ udelay(100); - req = next_request(&dep->req_queued); - dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + while (!list_empty(&dep->req_queued)) { + req = next_request(&dep->req_queued); + + dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + } } while (!list_empty(&dep->request_list)) { -- GitLab From d48daf37a3d2e2b28a61e615c0fc538301edb0dd Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 14 Jun 2012 18:43:08 +0300 Subject: [PATCH 1673/6849] x86/vsmp: Fix linker error when CONFIG_PROC_FS is not set set_vsmp_pv_ops() references no_irq_affinity which is undeclared if CONFIG_PROC_FS isn't set. Fix this by adding an #ifdef around this variable's access. Reported-by: Fengguang Wu Signed-off-by: Ido Yariv Acked-by: Shai Fultheim Link: http://lkml.kernel.org/r/1339688588-12674-1-git-send-email-ido@wizery.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/vsmp_64.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 6b96a7374f94..3f0285ac00fa 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -101,7 +101,10 @@ static void __init set_vsmp_pv_ops(void) #ifdef CONFIG_SMP if (cap & ctl & BIT(8)) { ctl &= ~BIT(8); +#ifdef CONFIG_PROC_FS + /* Don't let users change irq affinity via procfs */ no_irq_affinity = 1; +#endif } #endif -- GitLab From 7eb9ae0799b1e9f0b77733b432bc5f6f055b020b Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 14 Jun 2012 18:28:49 -0700 Subject: [PATCH 1674/6849] irq/apic: Use config_enabled(CONFIG_SMP) checks to clean up irq_set_affinity() for UP Move the ->irq_set_affinity() routines out of the #ifdef CONFIG_SMP sections and use config_enabled(CONFIG_SMP) checks inside those routines. Thus making those routines simple null stubs for !CONFIG_SMP and retaining those routines with no additional runtime overhead for CONFIG_SMP kernels. Cleans up the ifdef CONFIG_SMP in and around routines related to irq_set_affinity in io_apic and irq_remapping subsystems. Signed-off-by: Suresh Siddha Cc: torvalds@linux-foundation.org Cc: joerg.roedel@amd.com Cc: Sam Ravnborg Cc: Paul Gortmaker Link: http://lkml.kernel.org/r/1339723729.3475.63.camel@sbsiddha-desk.sc.intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/io_apic.c | 180 +++++++++++++--------------- drivers/iommu/intel_irq_remapping.c | 7 +- drivers/iommu/irq_remapping.c | 5 +- drivers/iommu/irq_remapping.h | 2 - include/linux/irq.h | 2 - 5 files changed, 86 insertions(+), 110 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 7cbd397884f5..a951ef7decb1 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2224,81 +2224,6 @@ void send_cleanup_vector(struct irq_cfg *cfg) cfg->move_in_progress = 0; } -static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) -{ - int apic, pin; - struct irq_pin_list *entry; - u8 vector = cfg->vector; - - for_each_irq_pin(entry, cfg->irq_2_pin) { - unsigned int reg; - - apic = entry->apic; - pin = entry->pin; - /* - * With interrupt-remapping, destination information comes - * from interrupt-remapping table entry. - */ - if (!irq_remapped(cfg)) - io_apic_write(apic, 0x11 + pin*2, dest); - reg = io_apic_read(apic, 0x10 + pin*2); - reg &= ~IO_APIC_REDIR_VECTOR_MASK; - reg |= vector; - io_apic_modify(apic, 0x10 + pin*2, reg); - } -} - -/* - * Either sets data->affinity to a valid value, and returns - * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and - * leaves data->affinity untouched. - */ -int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, - unsigned int *dest_id) -{ - struct irq_cfg *cfg = data->chip_data; - unsigned int irq = data->irq; - int err; - - if (!cpumask_intersects(mask, cpu_online_mask)) - return -EINVAL; - - err = assign_irq_vector(irq, cfg, mask); - if (err) - return err; - - err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id); - if (err) { - if (assign_irq_vector(irq, cfg, data->affinity)) - pr_err("Failed to recover vector for irq %d\n", irq); - return err; - } - - cpumask_copy(data->affinity, mask); - - return 0; -} - -static int -ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, - bool force) -{ - unsigned int dest, irq = data->irq; - unsigned long flags; - int ret; - - raw_spin_lock_irqsave(&ioapic_lock, flags); - ret = __ioapic_set_affinity(data, mask, &dest); - if (!ret) { - /* Only the high 8 bits are valid. */ - dest = SET_APIC_LOGICAL_ID(dest); - __target_IO_APIC_irq(irq, dest, data->chip_data); - ret = IRQ_SET_MASK_OK_NOCOPY; - } - raw_spin_unlock_irqrestore(&ioapic_lock, flags); - return ret; -} - asmlinkage void smp_irq_move_cleanup_interrupt(void) { unsigned vector, me; @@ -2386,6 +2311,87 @@ void irq_force_complete_move(int irq) static inline void irq_complete_move(struct irq_cfg *cfg) { } #endif +static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) +{ + int apic, pin; + struct irq_pin_list *entry; + u8 vector = cfg->vector; + + for_each_irq_pin(entry, cfg->irq_2_pin) { + unsigned int reg; + + apic = entry->apic; + pin = entry->pin; + /* + * With interrupt-remapping, destination information comes + * from interrupt-remapping table entry. + */ + if (!irq_remapped(cfg)) + io_apic_write(apic, 0x11 + pin*2, dest); + reg = io_apic_read(apic, 0x10 + pin*2); + reg &= ~IO_APIC_REDIR_VECTOR_MASK; + reg |= vector; + io_apic_modify(apic, 0x10 + pin*2, reg); + } +} + +/* + * Either sets data->affinity to a valid value, and returns + * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and + * leaves data->affinity untouched. + */ +int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, + unsigned int *dest_id) +{ + struct irq_cfg *cfg = data->chip_data; + unsigned int irq = data->irq; + int err; + + if (!config_enabled(CONFIG_SMP)) + return -1; + + if (!cpumask_intersects(mask, cpu_online_mask)) + return -EINVAL; + + err = assign_irq_vector(irq, cfg, mask); + if (err) + return err; + + err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id); + if (err) { + if (assign_irq_vector(irq, cfg, data->affinity)) + pr_err("Failed to recover vector for irq %d\n", irq); + return err; + } + + cpumask_copy(data->affinity, mask); + + return 0; +} + +static int +ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, + bool force) +{ + unsigned int dest, irq = data->irq; + unsigned long flags; + int ret; + + if (!config_enabled(CONFIG_SMP)) + return -1; + + raw_spin_lock_irqsave(&ioapic_lock, flags); + ret = __ioapic_set_affinity(data, mask, &dest); + if (!ret) { + /* Only the high 8 bits are valid. */ + dest = SET_APIC_LOGICAL_ID(dest); + __target_IO_APIC_irq(irq, dest, data->chip_data); + ret = IRQ_SET_MASK_OK_NOCOPY; + } + raw_spin_unlock_irqrestore(&ioapic_lock, flags); + return ret; +} + static void ack_apic_edge(struct irq_data *data) { irq_complete_move(data->chip_data); @@ -2565,9 +2571,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip) chip->irq_ack = ir_ack_apic_edge; chip->irq_eoi = ir_ack_apic_level; -#ifdef CONFIG_SMP chip->irq_set_affinity = set_remapped_irq_affinity; -#endif } #endif /* CONFIG_IRQ_REMAP */ @@ -2578,9 +2582,7 @@ static struct irq_chip ioapic_chip __read_mostly = { .irq_unmask = unmask_ioapic_irq, .irq_ack = ack_apic_edge, .irq_eoi = ack_apic_level, -#ifdef CONFIG_SMP .irq_set_affinity = ioapic_set_affinity, -#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3099,7 +3101,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, return err; } -#ifdef CONFIG_SMP static int msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -3121,7 +3122,6 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) return IRQ_SET_MASK_OK_NOCOPY; } -#endif /* CONFIG_SMP */ /* * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, @@ -3132,9 +3132,7 @@ static struct irq_chip msi_chip = { .irq_unmask = unmask_msi_irq, .irq_mask = mask_msi_irq, .irq_ack = ack_apic_edge, -#ifdef CONFIG_SMP .irq_set_affinity = msi_set_affinity, -#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3219,7 +3217,6 @@ void native_teardown_msi_irq(unsigned int irq) } #ifdef CONFIG_DMAR_TABLE -#ifdef CONFIG_SMP static int dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) @@ -3244,16 +3241,12 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, return IRQ_SET_MASK_OK_NOCOPY; } -#endif /* CONFIG_SMP */ - static struct irq_chip dmar_msi_type = { .name = "DMAR_MSI", .irq_unmask = dmar_msi_unmask, .irq_mask = dmar_msi_mask, .irq_ack = ack_apic_edge, -#ifdef CONFIG_SMP .irq_set_affinity = dmar_msi_set_affinity, -#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3274,7 +3267,6 @@ int arch_setup_dmar_msi(unsigned int irq) #ifdef CONFIG_HPET_TIMER -#ifdef CONFIG_SMP static int hpet_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -3297,16 +3289,12 @@ static int hpet_msi_set_affinity(struct irq_data *data, return IRQ_SET_MASK_OK_NOCOPY; } -#endif /* CONFIG_SMP */ - static struct irq_chip hpet_msi_type = { .name = "HPET_MSI", .irq_unmask = hpet_msi_unmask, .irq_mask = hpet_msi_mask, .irq_ack = ack_apic_edge, -#ifdef CONFIG_SMP .irq_set_affinity = hpet_msi_set_affinity, -#endif .irq_retrigger = ioapic_retrigger_irq, }; @@ -3341,8 +3329,6 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) */ #ifdef CONFIG_HT_IRQ -#ifdef CONFIG_SMP - static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) { struct ht_irq_msg msg; @@ -3370,16 +3356,12 @@ ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) return IRQ_SET_MASK_OK_NOCOPY; } -#endif - static struct irq_chip ht_irq_chip = { .name = "PCI-HT", .irq_mask = mask_ht_irq, .irq_unmask = unmask_ht_irq, .irq_ack = ack_apic_edge, -#ifdef CONFIG_SMP .irq_set_affinity = ht_set_affinity, -#endif .irq_retrigger = ioapic_retrigger_irq, }; diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 853902a1b7db..e0b18f3ae9a8 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -902,7 +902,6 @@ static int intel_setup_ioapic_entry(int irq, return 0; } -#ifdef CONFIG_SMP /* * Migrate the IO-APIC irq in the presence of intr-remapping. * @@ -926,6 +925,9 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irte irte; int err; + if (!config_enabled(CONFIG_SMP)) + return -EINVAL; + if (!cpumask_intersects(mask, cpu_online_mask)) return -EINVAL; @@ -963,7 +965,6 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, cpumask_copy(data->affinity, mask); return 0; } -#endif static void intel_compose_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, @@ -1065,9 +1066,7 @@ struct irq_remap_ops intel_irq_remap_ops = { .reenable = reenable_irq_remapping, .enable_faulting = enable_drhd_fault_handling, .setup_ioapic_entry = intel_setup_ioapic_entry, -#ifdef CONFIG_SMP .set_affinity = intel_ioapic_set_affinity, -#endif .free_irq = free_irte, .compose_msi_msg = intel_compose_msi_msg, .msi_alloc_irq = intel_msi_alloc_irq, diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c index 40cda8e98d87..1d29b1c66e72 100644 --- a/drivers/iommu/irq_remapping.c +++ b/drivers/iommu/irq_remapping.c @@ -111,16 +111,15 @@ int setup_ioapic_remapped_entry(int irq, vector, attr); } -#ifdef CONFIG_SMP int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - if (!remap_ops || !remap_ops->set_affinity) + if (!config_enabled(CONFIG_SMP) || !remap_ops || + !remap_ops->set_affinity) return 0; return remap_ops->set_affinity(data, mask, force); } -#endif void free_remapped_irq(int irq) { diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h index be9d72950c51..b12974cc1dfe 100644 --- a/drivers/iommu/irq_remapping.h +++ b/drivers/iommu/irq_remapping.h @@ -59,11 +59,9 @@ struct irq_remap_ops { unsigned int, int, struct io_apic_irq_attr *); -#ifdef CONFIG_SMP /* Set the CPU affinity of a remapped interrupt */ int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, bool force); -#endif /* Free an IRQ */ int (*free_irq)(int); diff --git a/include/linux/irq.h b/include/linux/irq.h index 61f5cec031e0..47a937cd84af 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -150,9 +150,7 @@ struct irq_data { void *handler_data; void *chip_data; struct msi_desc *msi_desc; -#ifdef CONFIG_SMP cpumask_var_t affinity; -#endif }; /* -- GitLab From d0b1252dd11549103a97a13aca25737b084c5618 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jun 2012 14:34:42 +0200 Subject: [PATCH 1675/6849] ALSA: hda - Use common codes for ATI, Nvidia and VIA simple codecs The code refactoring using the same helper functions for sharing the codes among ATI, Nvidia and VIA simple_hdmi* stuff. Except for that spec->pcm_playback is no longer pointer, the functionality doesn't change. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 191 +++++++++++++------------------------ 1 file changed, 65 insertions(+), 126 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index c9d0c98bbe86..6bf784fc8d6d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -85,7 +85,7 @@ struct hdmi_spec { * Non-generic ATI/NVIDIA specific */ struct hda_multi_out multiout; - const struct hda_pcm_stream *pcm_playback; + struct hda_pcm_stream pcm_playback; }; @@ -1367,8 +1367,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) info->name = get_hdmi_pcm_name(i); info->pcm_type = HDA_PCM_TYPE_HDMI; pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; - snd_BUG_ON(!spec->pcm_playback); - *pstr = *spec->pcm_playback; + *pstr = spec->pcm_playback; pstr->nid = spec->cvts[i].cvt_nid; if (pstr->channels_max <= 2 && chans && chans <= 16) pstr->channels_max = chans; @@ -1560,6 +1559,49 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo, stream_tag, format, substream); } +static const struct hda_pcm_stream simple_pcm_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .ops = { + .open = simple_playback_pcm_open, + .close = simple_playback_pcm_close, + .prepare = simple_playback_pcm_prepare + }, +}; + +static const struct hda_codec_ops simple_hdmi_patch_ops = { + .build_controls = simple_playback_build_controls, + .build_pcms = simple_playback_build_pcms, + .init = simple_playback_init, + .free = simple_playback_free, +}; + +static int patch_simple_hdmi(struct hda_codec *codec, + hda_nid_t cvt_nid, hda_nid_t pin_nid) +{ + struct hdmi_spec *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + + codec->spec = spec; + + spec->multiout.num_dacs = 0; /* no analog */ + spec->multiout.max_channels = 2; + spec->multiout.dig_out_nid = cvt_nid; + spec->num_cvts = 1; + spec->num_pins = 1; + spec->cvts[0].cvt_nid = cvt_nid; + spec->cvts[0].cvt_nid = pin_nid; + spec->pcm_playback = simple_pcm_playback; + + codec->patch_ops = simple_hdmi_patch_ops; + + return 0; +} + static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, int channels) { @@ -1732,54 +1774,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { }, }; -static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = nvhdmi_master_con_nid_7x, - .rates = SUPPORTED_RATES, - .maxbps = SUPPORTED_MAXBPS, - .formats = SUPPORTED_FORMATS, - .ops = { - .open = simple_playback_pcm_open, - .close = simple_playback_pcm_close, - .prepare = simple_playback_pcm_prepare - }, -}; - -static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { - .build_controls = simple_playback_build_controls, - .build_pcms = simple_playback_build_pcms, - .init = nvhdmi_7x_init, - .free = simple_playback_free, -}; - -static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { - .build_controls = simple_playback_build_controls, - .build_pcms = simple_playback_build_pcms, - .init = nvhdmi_7x_init, - .free = simple_playback_free, -}; - static int patch_nvhdmi_2ch(struct hda_codec *codec) { struct hdmi_spec *spec; + int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x, + nvhdmi_master_pin_nid_7x); + if (err < 0) + return err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - spec->multiout.num_dacs = 0; /* no analog */ - spec->multiout.max_channels = 2; - spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; - spec->num_cvts = 1; - spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x; - spec->pcm_playback = &nvhdmi_pcm_playback_2ch; - - codec->patch_ops = nvhdmi_patch_ops_2ch; - + codec->patch_ops.init = nvhdmi_7x_init; + /* override the PCM rates, etc, as the codec doesn't give full list */ + spec = codec->spec; + spec->pcm_playback.rates = SUPPORTED_RATES; + spec->pcm_playback.maxbps = SUPPORTED_MAXBPS; + spec->pcm_playback.formats = SUPPORTED_FORMATS; return 0; } @@ -1787,13 +1795,11 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) { struct hdmi_spec *spec; int err = patch_nvhdmi_2ch(codec); - if (err < 0) return err; spec = codec->spec; spec->multiout.max_channels = 8; - spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; - codec->patch_ops = nvhdmi_patch_ops_8ch_7x; + spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x; /* Initialize the audio infoframe channel mask and checksum to something * valid */ @@ -1837,47 +1843,14 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, return 0; } -static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = ATIHDMI_CVT_NID, - .ops = { - .open = simple_playback_pcm_open, - .close = simple_playback_pcm_close, - .prepare = atihdmi_playback_pcm_prepare - }, -}; - -static const struct hda_codec_ops atihdmi_patch_ops = { - .build_controls = simple_playback_build_controls, - .build_pcms = simple_playback_build_pcms, - .init = simple_playback_init, - .free = simple_playback_free, -}; - - static int patch_atihdmi(struct hda_codec *codec) { struct hdmi_spec *spec; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - spec->multiout.num_dacs = 0; /* no analog */ - spec->multiout.max_channels = 2; - spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; - spec->num_cvts = 1; - spec->num_pins = 1; - spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID; - spec->pins[0].pin_nid = ATIHDMI_PIN_NID; - spec->pcm_playback = &atihdmi_pcm_digital_playback; - - codec->patch_ops = atihdmi_patch_ops; - + int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID); + if (err < 0) + return err; + spec = codec->spec; + spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare; return 0; } @@ -1885,46 +1858,12 @@ static int patch_atihdmi(struct hda_codec *codec) #define VIAHDMI_CVT_NID 0x02 /* audio converter1 */ #define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */ -static const struct hda_codec_ops via_hdmi_patch_ops = { - .build_controls = simple_playback_build_controls, - .build_pcms = simple_playback_build_pcms, - .init = simple_playback_init, - .free = simple_playback_free, - .unsol_event = simple_hdmi_unsol_event, -}; - -static struct hda_pcm_stream via_hdmi_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = VIAHDMI_CVT_NID, /* NID to query formats and rates*/ - .ops = { - .open = simple_playback_pcm_open, - .close = simple_playback_pcm_close, - .prepare = simple_playback_pcm_prepare - }, -}; - static int patch_via_hdmi(struct hda_codec *codec) { - struct hdmi_spec *spec; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - spec->multiout.num_dacs = 0; /* no analog */ - spec->multiout.max_channels = 2; - spec->multiout.dig_out_nid = VIAHDMI_CVT_NID; /* pure-digital case */ - spec->num_cvts = 1; - spec->num_pins = 1; - spec->cvts[0].cvt_nid = VIAHDMI_CVT_NID; - spec->pins[0].pin_nid = VIAHDMI_PIN_NID; - spec->pcm_playback = &via_hdmi_digital_playback; - - codec->spec = spec; - codec->patch_ops = via_hdmi_patch_ops; - + int err = patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID); + if (err < 0) + return err; + codec->patch_ops.unsol_event = simple_hdmi_unsol_event; return 0; } -- GitLab From ceaa86ba2ed90780617be76526de975521374595 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jun 2012 14:38:31 +0200 Subject: [PATCH 1676/6849] ALSA: hda - Remove invalid init verbs for Nvidia 2ch codecs Nvidia 2ch codecs have no NIDs greather than 0x05. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 6bf784fc8d6d..f51a0b5bfcb2 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1453,7 +1453,15 @@ static const hda_nid_t nvhdmi_con_nids_7x[4] = { 0x6, 0x8, 0xa, 0xc, }; -static const struct hda_verb nvhdmi_basic_init_7x[] = { +static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = { + /* set audio protect on */ + { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, + /* enable digital output on pin widget */ + { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, + {} /* terminator */ +}; + +static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = { /* set audio protect on */ { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, /* enable digital output on pin widget */ @@ -1481,9 +1489,15 @@ static const struct hda_verb nvhdmi_basic_init_7x[] = { (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) #endif -static int nvhdmi_7x_init(struct hda_codec *codec) +static int nvhdmi_7x_init_2ch(struct hda_codec *codec) +{ + snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch); + return 0; +} + +static int nvhdmi_7x_init_8ch(struct hda_codec *codec) { - snd_hda_sequence_write(codec, nvhdmi_basic_init_7x); + snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch); return 0; } @@ -1782,7 +1796,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) if (err < 0) return err; - codec->patch_ops.init = nvhdmi_7x_init; + codec->patch_ops.init = nvhdmi_7x_init_2ch; /* override the PCM rates, etc, as the codec doesn't give full list */ spec = codec->spec; spec->pcm_playback.rates = SUPPORTED_RATES; @@ -1800,6 +1814,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) spec = codec->spec; spec->multiout.max_channels = 8; spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x; + codec->patch_ops.init = nvhdmi_7x_init_8ch; /* Initialize the audio infoframe channel mask and checksum to something * valid */ -- GitLab From 250e41ac9f31216db1b592bfd77c6a097f10503d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jun 2012 14:40:21 +0200 Subject: [PATCH 1677/6849] ALSA: hda - Enable unsol event for ATI and Nvidia HDMI codecs too ATI and Nvidia HDMI codecs have also the pin-detection capability, so let's enable the jack-detecion for them, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index f51a0b5bfcb2..8891fa658382 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1401,11 +1401,9 @@ static int simple_playback_build_controls(struct hda_codec *codec) spec->cvts[i].cvt_nid); if (err < 0) return err; - if (codec->patch_ops.unsol_event) { - err = simple_hdmi_build_jack(codec, i); - if (err < 0) - return err; - } + err = simple_hdmi_build_jack(codec, i); + if (err < 0) + return err; } return 0; @@ -1589,6 +1587,7 @@ static const struct hda_codec_ops simple_hdmi_patch_ops = { .build_pcms = simple_playback_build_pcms, .init = simple_playback_init, .free = simple_playback_free, + .unsol_event = simple_hdmi_unsol_event, }; static int patch_simple_hdmi(struct hda_codec *codec, @@ -1875,11 +1874,7 @@ static int patch_atihdmi(struct hda_codec *codec) static int patch_via_hdmi(struct hda_codec *codec) { - int err = patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID); - if (err < 0) - return err; - codec->patch_ops.unsol_event = simple_hdmi_unsol_event; - return 0; + return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID); } /* -- GitLab From d03fcfe626b89832b36dbfa5fb32a805478b097a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 15 Jun 2012 16:40:21 +0800 Subject: [PATCH 1678/6849] iio: dac: Convert ad5380 to devm_regmap_* APIs Signed-off-by: Axel Lin Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/ad5380.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index 5dfb4451728f..14991ac55f26 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -373,7 +373,7 @@ static int __devinit ad5380_probe(struct device *dev, struct regmap *regmap, if (indio_dev == NULL) { dev_err(dev, "Failed to allocate iio device\n"); ret = -ENOMEM; - goto error_regmap_exit; + goto error_out; } st = iio_priv(indio_dev); @@ -436,8 +436,7 @@ error_free_reg: kfree(indio_dev->channels); error_free: iio_device_free(indio_dev); -error_regmap_exit: - regmap_exit(regmap); +error_out: return ret; } @@ -456,7 +455,6 @@ static int __devexit ad5380_remove(struct device *dev) regulator_put(st->vref_reg); } - regmap_exit(st->regmap); iio_device_free(indio_dev); return 0; @@ -485,7 +483,7 @@ static int __devinit ad5380_spi_probe(struct spi_device *spi) const struct spi_device_id *id = spi_get_device_id(spi); struct regmap *regmap; - regmap = regmap_init_spi(spi, &ad5380_regmap_config); + regmap = devm_regmap_init_spi(spi, &ad5380_regmap_config); if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -559,7 +557,7 @@ static int __devinit ad5380_i2c_probe(struct i2c_client *i2c, { struct regmap *regmap; - regmap = regmap_init_i2c(i2c, &ad5380_regmap_config); + regmap = devm_regmap_init_i2c(i2c, &ad5380_regmap_config); if (IS_ERR(regmap)) return PTR_ERR(regmap); -- GitLab From 791de6771ee96e208ee30bfed48e8f6b25422843 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Jun 2012 18:11:49 +0200 Subject: [PATCH 1679/6849] staging:iio:adis16400: Fix ADIS16300 ROLL_OUT register address In the current driver ROLL_OUT register address is the same as the PITCH_OUT register address. This patch fixes it to use the correct address. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16400.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 83d133efaac6..1f4e98783ef5 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -42,7 +42,7 @@ #define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */ #define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */ -#define ADIS16300_ROLL_OUT 0x12 /* Y axis inclinometer output measurement */ +#define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */ /* Calibration parameters */ #define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */ -- GitLab From 6f30592e8cf0c9eb2e403fe2a44c1d7c1d58b4f1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Jun 2012 18:11:50 +0200 Subject: [PATCH 1680/6849] staging:iio:adis16400: Fix ADIS16300 temperature address The ADIS16300 uses the same address for the temperature register as the ADIS16350 and not the same as the ADIS16400. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16400_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f6bd854e950..1c9931ed4057 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -946,7 +946,7 @@ static struct iio_chan_spec adis16300_channels[] = { .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = temp, + .address = temp0, .scan_index = ADIS16400_SCAN_TEMP, .scan_type = IIO_ST('s', 12, 16, 0), }, { -- GitLab From bb7cf8bc52ff388c89f5984e428e966e326315ad Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Jun 2012 18:11:51 +0200 Subject: [PATCH 1681/6849] staging:iio:adis16400: Fix ADIS16334 temperature address The channel spec for ADUS16334's temperature channel uses the address and scan index for the Z-axis acceleration channel. This patch fixes it to use the temperature channel address and scan index instead. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16400_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1c9931ed4057..7aa3a9aa55e4 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1054,8 +1054,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = accel_z, - .scan_index = ADIS16400_SCAN_ACC_Z, + .address = temp0, + .scan_index = ADIS16400_SCAN_TEMP, .scan_type = IIO_ST('s', 14, 16, 0), }, IIO_CHAN_SOFT_TIMESTAMP(12) -- GitLab From 07a8329c48b699a85086756eaa1a658540d02ac4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Jun 2012 18:11:52 +0200 Subject: [PATCH 1682/6849] staging:iio:adis16400: Fix ADIS163xx AUX_ADC address The ADIS163xx variants use a different register address for the auxiliary ADC channel than the ADIS16400. This patch fixes them to use the correct address. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16400.h | 1 + drivers/staging/iio/imu/adis16400_core.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 1f4e98783ef5..9dd9f1459a4d 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -43,6 +43,7 @@ #define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */ #define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */ +#define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */ /* Calibration parameters */ #define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */ diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 7aa3a9aa55e4..387301437cf5 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -472,11 +472,12 @@ enum adis16400_chan { temp, temp0, temp1, temp2, in1, + in2, incli_x, incli_y, }; -static u8 adis16400_addresses[17][2] = { +static u8 adis16400_addresses[18][2] = { [in_supply] = { ADIS16400_SUPPLY_OUT }, [gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF }, [gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF }, @@ -491,7 +492,8 @@ static u8 adis16400_addresses[17][2] = { [temp0] = { ADIS16350_XTEMP_OUT }, [temp1] = { ADIS16350_YTEMP_OUT }, [temp2] = { ADIS16350_ZTEMP_OUT }, - [in1] = { ADIS16400_AUX_ADC }, + [in1] = { ADIS16300_AUX_ADC }, + [in2] = { ADIS16400_AUX_ADC }, [incli_x] = { ADIS16300_PITCH_OUT }, [incli_y] = { ADIS16300_ROLL_OUT } }; @@ -752,7 +754,7 @@ static struct iio_chan_spec adis16400_channels[] = { .channel = 1, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in1, + .address = in2, .scan_index = ADIS16400_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), }, -- GitLab From 25c38aa3d17d6ccfca225fafce68401908a1ccb4 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:27:10 +0200 Subject: [PATCH 1683/6849] staging: iio: fix typos in simple dummy driver Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio_simple_dummy.c | 10 +++++----- drivers/staging/iio/iio_simple_dummy_buffer.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index 310411911ed7..155a49a9da7e 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -27,7 +27,7 @@ /* * A few elements needed to fake a bus for this driver - * Note instances parmeter controls how many of these + * Note instances parameter controls how many of these * dummy devices are registered. */ static unsigned instances = 1; @@ -178,7 +178,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { .scan_index = accelx, .scan_type = { /* Description of storage in buffer */ .sign = 's', /* signed */ - .realbits = 16, /* 12 bits */ + .realbits = 16, /* 16 bits */ .storagebits = 16, /* 16 bits used for storage */ .shift = 0, /* zero shift */ }, @@ -285,9 +285,9 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, * iio_dummy_write_raw() - data write function. * @indio_dev: the struct iio_dev associated with this device instance * @chan: the channel whose data is to be read - * @val: first element of returned value (typically INT) - * @val2: second element of returned value (typically MICRO) - * @mask: what we actually want to read. 0 is the channel, everything else + * @val: first element of value to set (typically INT) + * @val2: second element of value to set (typically MICRO) + * @mask: what we actually want to write. 0 is the channel, everything else * is as per the info_mask in iio_chan_spec. * * Note that all raw writes are assumed IIO_VAL_INT and info mask elements diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index fdfc8739095a..3e43025f887d 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -67,8 +67,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) * software culled hardware scans: * occasionally a driver may process the nearest hardware * scan to avoid storing elements that are not desired. This - * is the fidliest option by far. - * Here lets pretend we have random access. And the values are + * is the fiddliest option by far. + * Here let's pretend we have random access. And the values are * in the constant table fakedata. */ int i, j; -- GitLab From eaedfa54db0584ddf7308bb99c473cc6cf28fb65 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Jun 2012 18:14:36 +0200 Subject: [PATCH 1684/6849] staging: iio: Remove superfluous flush_scheduled_work None of these drivers ever schedule any work, so there is no need to flush any scheduled work when the driver is removed. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16209_core.c | 2 -- drivers/staging/iio/accel/adis16220_core.c | 2 -- drivers/staging/iio/accel/adis16240_core.c | 2 -- drivers/staging/iio/gyro/adis16260_core.c | 2 -- 4 files changed, 8 deletions(-) diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index f6fd0d31d4f0..6fc426e27e4e 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -606,8 +606,6 @@ static int adis16209_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); - flush_scheduled_work(); - iio_device_unregister(indio_dev); adis16209_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 6a9ac898cb01..af5c57637166 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -694,8 +694,6 @@ static int adis16220_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); - flush_scheduled_work(); - sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 8b15eaea3381..2f59f83d002d 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -641,8 +641,6 @@ static int adis16240_remove(struct spi_device *spi) struct iio_dev *indio_dev = spi_get_drvdata(spi); - flush_scheduled_work(); - iio_device_unregister(indio_dev); adis16240_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index ec765f955f8d..fdb84cc3d7c9 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -728,8 +728,6 @@ static int adis16260_remove(struct spi_device *spi) if (ret) goto err_ret; - flush_scheduled_work(); - adis16260_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16260_unconfigure_ring(indio_dev); -- GitLab From cf655d2d6fb38de1a292e87075b39b1741f406c0 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:25:23 +0200 Subject: [PATCH 1685/6849] iio: sysfs-bus-iio typo Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-iio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 05449c68952c..a3774a71ec26 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -122,7 +122,7 @@ Description: If an axis is specified it generally means that the temperature sensor is associated with one part of a compound device (e.g. a gyroscope axis). Units after application of scale and offset - are milli degrees Celsuis. + are milli degrees Celsius. What: /sys/bus/iio/devices/iio:deviceX/in_tempX_input KernelVersion: 2.6.38 -- GitLab From 79e9b4e6f2d3fb904233f62cea1b6a42a58416a4 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:25:24 +0200 Subject: [PATCH 1686/6849] iio: cleanup sysfs-bus-iio-light-lm3533-als Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als b/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als index 694a52c8cf82..22c5ea670971 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als +++ b/Documentation/ABI/testing/sysfs-bus-iio-light-lm3533-als @@ -14,7 +14,6 @@ KernelVersion: 3.5 Contact: Johan Hovold Description: Get the hysteresis for thresholds Y, that is, - threshY_hysteresis = threshY_raising - threshY_falling What: /sys/.../events/illuminance_threshY_falling_value @@ -31,7 +30,7 @@ Description: threshY_raising. These thresholds correspond to the eight zone-boundary - registers (boundaryY_{low,high}) and defines the five light + registers (boundaryY_{low,high}) and define the five light zones. What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_zone -- GitLab From 33e0c249801c6913b2bd102683ab65ab61e12952 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:25:25 +0200 Subject: [PATCH 1687/6849] iio: iio/machine.h typo Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h index 0b1f19bfdc44..400a453ff67b 100644 --- a/include/linux/iio/machine.h +++ b/include/linux/iio/machine.h @@ -14,7 +14,7 @@ * This is matched against the datasheet_name element * of struct iio_chan_spec. * @consumer_dev_name: Name to uniquely identify the consumer device. - * @consumer_channel: Unique name used to idenitify the channel on the + * @consumer_channel: Unique name used to identify the channel on the * consumer side. */ struct iio_map { -- GitLab From a21601463d0e542d20635b835b6c97294571b0a5 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:25:26 +0200 Subject: [PATCH 1688/6849] staging: iio: add IIO_ALTVOLTAGE to iio_event_monitor example IIO_ALTVOLTAGE is used by frequency/adf4350 and frequency/ad9523 Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_event_monitor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 22275845fb12..4326e9e764c9 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -45,6 +45,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_ANGL] = "angl", [IIO_TIMESTAMP] = "timestamp", [IIO_CAPACITANCE] = "capacitance", + [IIO_ALTVOLTAGE] = "altvoltage", }; static const char * const iio_ev_type_text[] = { @@ -92,6 +93,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_ANGL: case IIO_TIMESTAMP: case IIO_CAPACITANCE: + case IIO_ALTVOLTAGE: break; default: return false; -- GitLab From 60ba16e35b887008eececcb935c835026504cef5 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:25:27 +0200 Subject: [PATCH 1689/6849] staging: iio:: fix some typos typos in comments, fix ring_sw module description Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/device.txt | 10 +++++----- drivers/staging/iio/Documentation/overview.txt | 2 +- drivers/staging/iio/Documentation/ring.txt | 4 ++-- drivers/staging/iio/ring_sw.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index f03fbd3bb454..ea08d6213373 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -12,7 +12,7 @@ struct iio_dev *indio_dev = iio_device_alloc(sizeof(struct chip_state)); where chip_state is a structure of local state data for this instance of the chip. -That data can be accessed using iio_priv(struct iio_dev *) +That data can be accessed using iio_priv(struct iio_dev *). Then fill in the following: @@ -39,7 +39,7 @@ Then fill in the following: and for associate parameters such as offsets and scales. * info->write_raw: Raw value writing function. Used for writable device values such - as DAC values and caliboffset. + as DAC values and calibbias. * info->read_event_config: Typically only set if there are some interrupt lines. This is used to read if an on sensor event detector is enabled. @@ -62,8 +62,8 @@ Then fill in the following: Poll function related elements. This controls what occurs when a trigger to which this device is attached sends an event. - indio_dev->channels: - Specification of device channels. Most attributes etc are built - form this spec. + Specification of device channels. Most attributes etc. are built + from this spec. - indio_dev->num_channels: How many channels are there? @@ -76,4 +76,4 @@ be registered afterwards (otherwise the whole parentage of devices gets confused) On remove, iio_device_unregister(indio_dev) will remove the device from -the core, and iio_device_free will clean up. +the core, and iio_device_free(indio_dev) will clean up. diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt index afc39ecde9ca..43f92b06bc3e 100644 --- a/drivers/staging/iio/Documentation/overview.txt +++ b/drivers/staging/iio/Documentation/overview.txt @@ -8,7 +8,7 @@ actual devices combine some ADCs with digital to analog converters The aim is to fill the gap between the somewhat similar hwmon and input subsystems. Hwmon is very much directed at low sample rate sensors used in applications such as fan speed control and temperature -measurement. Input is, as it's name suggests focused on input +measurement. Input is, as its name suggests focused on input devices. In some cases there is considerable overlap between these and IIO. diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt index e33807761cd7..e1da43381d0e 100644 --- a/drivers/staging/iio/Documentation/ring.txt +++ b/drivers/staging/iio/Documentation/ring.txt @@ -15,8 +15,8 @@ struct iio_ring_buffer contains a struct iio_ring_setup_ops *setup_ops which in turn contains the 4 function pointers (preenable, postenable, predisable and postdisable). These are used to perform device specific steps on either side -of the core changing it's current mode to indicate that the buffer -is enabled or disabled (along with enabling triggering etc as appropriate). +of the core changing its current mode to indicate that the buffer +is enabled or disabled (along with enabling triggering etc. as appropriate). Also in struct iio_ring_buffer is a struct iio_ring_access_funcs. The function pointers within here are used to allow the core to handle diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 9358c6cb1c72..f61c8fdaab06 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -24,7 +24,7 @@ * @read_p: read pointer (oldest available) * @write_p: write pointer * @half_p: half buffer length behind write_p (event generation) - * @update_needed: flag to indicated change in size requested + * @update_needed: flag to indicate change in size requested * * Note that the first element of all ring buffers must be a * struct iio_buffer. @@ -363,5 +363,5 @@ void iio_sw_rb_free(struct iio_buffer *r) } EXPORT_SYMBOL(iio_sw_rb_free); -MODULE_DESCRIPTION("Industrialio I/O software ring buffer"); +MODULE_DESCRIPTION("Industrial I/O software ring buffer"); MODULE_LICENSE("GPL"); -- GitLab From fb1c4bcd721fcc30d6e43f60a244483dc0d07056 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 15 Jun 2012 19:25:28 +0200 Subject: [PATCH 1690/6849] iio: iio/events.h typos Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/events.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/iio/events.h b/include/linux/iio/events.h index b5acbf93c5da..13ce220c7003 100644 --- a/include/linux/iio/events.h +++ b/include/linux/iio/events.h @@ -46,7 +46,7 @@ enum iio_event_direction { * @diff: Whether the event is for an differential channel or not. * @modifier: Modifier for the channel. Should be one of enum iio_modifier. * @direction: Direction of the event. One of enum iio_event_direction. - * @type: Type of the event. Should be one enum iio_event_type. + * @type: Type of the event. Should be one of enum iio_event_type. * @chan: Channel number for non-differential channels. * @chan1: First channel number for differential channels. * @chan2: Second channel number for differential channels. @@ -69,7 +69,7 @@ enum iio_event_direction { * @chan_type: Type of the channel. Should be one of enum iio_chan_type. * @number: Channel number. * @modifier: Modifier for the channel. Should be one of enum iio_modifier. - * @type: Type of the event. Should be one enum iio_event_type. + * @type: Type of the event. Should be one of enum iio_event_type. * @direction: Direction of the event. One of enum iio_event_direction. */ @@ -81,7 +81,7 @@ enum iio_event_direction { * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified channels * @chan_type: Type of the channel. Should be one of enum iio_chan_type. * @number: Channel number. - * @type: Type of the event. Should be one enum iio_event_type. + * @type: Type of the event. Should be one of enum iio_event_type. * @direction: Direction of the event. One of enum iio_event_direction. */ -- GitLab From aff1eb4e3dd13ee419c6cd76baf1bcc2edeaaa86 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Jun 2012 18:08:59 +0200 Subject: [PATCH 1691/6849] iio: buffer: Fix NULL pointer deref caused by empty scan mask iio_scan_mask_match() returns NULL if the passed in scan mask is empty. This will happen if no channel has been selected and buffer is enabled. iio_sw_buffer_preenable() will assign NULL to indio_dev->active_scan_mask in this case. As a result iio_update_demux() will cause a NULL pointer deref, because it expects active_scan_mask to be non-NULL. Since it does not make much sense to start data capture if there is no data to capture this patch updates the code to fail gracefully in iio_scan_mask_match() instead of crashing the kernel. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-buffer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index ac185b8694bd..2f35db93cdb6 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -553,6 +553,10 @@ int iio_sw_buffer_preenable(struct iio_dev *indio_dev) buffer->scan_mask); else indio_dev->active_scan_mask = buffer->scan_mask; + + if (indio_dev->active_scan_mask == NULL) + return -EINVAL; + iio_update_demux(indio_dev); if (indio_dev->info->update_scan_mode) -- GitLab From dc348147a9e1ba84395d1e585d26af44f0ca4e29 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 15 Jun 2012 09:18:55 -0700 Subject: [PATCH 1692/6849] staging: comedi: fix Kconfig for COMEDI_PCMCIA_DRIVERS The depends on PCCARD is redundant. All of the comedi PCMCIA drivers depend on PCMCIA which can only be enabled if PCCARD is enabled. Remove the extra depends check. Signed-off-by: H Hartley Sweeten Cc: Frank Mori Hess Tested-by: Ian Abbott Reported-by: Randy Dunlap Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 848cf7e3e8fd..2ca7f08bc5b9 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1097,7 +1097,7 @@ endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS tristate "Comedi PCMCIA drivers" - depends on (PCMCIA || PCCARD) + depends on PCMCIA ---help--- Enable comedi PCMCIA and PCCARD drivers to be built -- GitLab From 3026b0e942c65c65c8fc80d391d004228b52b916 Mon Sep 17 00:00:00 2001 From: Lubomir Schmidt Date: Fri, 15 Jun 2012 15:12:17 -0500 Subject: [PATCH 1693/6849] staging: r8712u: Add new USB IDs There are two new devices for this driver. Signed-off-by: Larry Finger Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/usb_intf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 9bd18e2d0513..69f616c6964e 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -102,6 +102,8 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { /* - */ {USB_DEVICE(0x20F4, 0x646B)}, {USB_DEVICE(0x083A, 0xC512)}, + {USB_DEVICE(0x25D4, 0x4CA1)}, + {USB_DEVICE(0x25D4, 0x4CAB)}, /* RTL8191SU */ /* Realtek */ -- GitLab From e2ae715d66bf4becfb85eb84b7150e23cf27df30 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 15 Jun 2012 14:07:51 +0200 Subject: [PATCH 1694/6849] kmsg - kmsg_dump() use iterator to receive log buffer content Provide an iterator to receive the log buffer content, and convert all kmsg_dump() users to it. The structured data in the kmsg buffer now contains binary data, which should no longer be copied verbatim to the kmsg_dump() users. The iterator should provide reliable access to the buffer data, and also supports proper log line-aware chunking of data while iterating. Signed-off-by: Kay Sievers Tested-by: Tony Luck Reported-by: Anton Vorontsov Tested-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/pseries/nvram.c | 61 +----- arch/x86/platform/mrst/early_printk_mrst.c | 13 +- drivers/mtd/mtdoops.c | 22 +-- fs/pstore/platform.c | 34 ++-- include/linux/kmsg_dump.h | 45 ++++- kernel/printk.c | 220 ++++++++++++++++++--- 6 files changed, 258 insertions(+), 137 deletions(-) diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 36f957f31842..8733a86ad52e 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -68,9 +68,7 @@ static const char *pseries_nvram_os_partitions[] = { }; static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *old_msgs, unsigned long old_len, - const char *new_msgs, unsigned long new_len); + enum kmsg_dump_reason reason); static struct kmsg_dumper nvram_kmsg_dumper = { .dump = oops_to_nvram @@ -503,28 +501,6 @@ int __init pSeries_nvram_init(void) return 0; } -/* - * Try to capture the last capture_len bytes of the printk buffer. Return - * the amount actually captured. - */ -static size_t capture_last_msgs(const char *old_msgs, size_t old_len, - const char *new_msgs, size_t new_len, - char *captured, size_t capture_len) -{ - if (new_len >= capture_len) { - memcpy(captured, new_msgs + (new_len - capture_len), - capture_len); - return capture_len; - } else { - /* Grab the end of old_msgs. */ - size_t old_tail_len = min(old_len, capture_len - new_len); - memcpy(captured, old_msgs + (old_len - old_tail_len), - old_tail_len); - memcpy(captured + old_tail_len, new_msgs, new_len); - return old_tail_len + new_len; - } -} - /* * Are we using the ibm,rtas-log for oops/panic reports? And if so, * would logging this oops/panic overwrite an RTAS event that rtas_errd @@ -541,27 +517,6 @@ static int clobbering_unread_rtas_event(void) NVRAM_RTAS_READ_TIMEOUT); } -/* Squeeze out each line's severity prefix. */ -static size_t elide_severities(char *buf, size_t len) -{ - char *in, *out, *buf_end = buf + len; - /* Assume a at the very beginning marks the start of a line. */ - int newline = 1; - - in = out = buf; - while (in < buf_end) { - if (newline && in+3 <= buf_end && - *in == '<' && isdigit(in[1]) && in[2] == '>') { - in += 3; - newline = 0; - } else { - newline = (*in == '\n'); - *out++ = *in++; - } - } - return out - buf; -} - /* Derived from logfs_compress() */ static int nvram_compress(const void *in, void *out, size_t inlen, size_t outlen) @@ -619,9 +574,7 @@ static int zip_oops(size_t text_len) * partition. If that's too much, go back and capture uncompressed text. */ static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *old_msgs, unsigned long old_len, - const char *new_msgs, unsigned long new_len) + enum kmsg_dump_reason reason) { static unsigned int oops_count = 0; static bool panicking = false; @@ -660,14 +613,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, return; if (big_oops_buf) { - text_len = capture_last_msgs(old_msgs, old_len, - new_msgs, new_len, big_oops_buf, big_oops_buf_sz); - text_len = elide_severities(big_oops_buf, text_len); + kmsg_dump_get_buffer(dumper, false, + big_oops_buf, big_oops_buf_sz, &text_len); rc = zip_oops(text_len); } if (rc != 0) { - text_len = capture_last_msgs(old_msgs, old_len, - new_msgs, new_len, oops_data, oops_data_sz); + kmsg_dump_rewind(dumper); + kmsg_dump_get_buffer(dumper, true, + oops_data, oops_data_sz, &text_len); err_type = ERR_TYPE_KERNEL_PANIC; *oops_len = (u16) text_len; } diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/mrst/early_printk_mrst.c index 3c6e328483c7..028454f0c3a5 100644 --- a/arch/x86/platform/mrst/early_printk_mrst.c +++ b/arch/x86/platform/mrst/early_printk_mrst.c @@ -110,19 +110,16 @@ static struct kmsg_dumper dw_dumper; static int dumper_registered; static void dw_kmsg_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { - int i; + static char line[1024]; + size_t len; /* When run to this, we'd better re-init the HW */ mrst_early_console_init(); - for (i = 0; i < l1; i++) - early_mrst_console.write(&early_mrst_console, s1 + i, 1); - for (i = 0; i < l2; i++) - early_mrst_console.write(&early_mrst_console, s2 + i, 1); + while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) + early_mrst_console.write(&early_mrst_console, line, len); } /* Set the ratio rate to 115200, 8n1, IRQ disabled */ diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index ae36d7e1e913..551e316e4454 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -304,32 +304,17 @@ static void find_next_position(struct mtdoops_context *cxt) } static void mtdoops_do_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { struct mtdoops_context *cxt = container_of(dumper, struct mtdoops_context, dump); - unsigned long s1_start, s2_start; - unsigned long l1_cpy, l2_cpy; - char *dst; - - if (reason != KMSG_DUMP_OOPS && - reason != KMSG_DUMP_PANIC) - return; /* Only dump oopses if dump_oops is set */ if (reason == KMSG_DUMP_OOPS && !dump_oops) return; - dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ - l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); - l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); - - s2_start = l2 - l2_cpy; - s1_start = l1 - l1_cpy; - - memcpy(dst, s1 + s1_start, l1_cpy); - memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); + kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, + record_size - MTDOOPS_HEADER_SIZE, NULL); /* Panics must be written immediately */ if (reason != KMSG_DUMP_OOPS) @@ -375,6 +360,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } + cxt->dump.max_reason = KMSG_DUMP_OOPS; cxt->dump.dump = mtdoops_do_dump; err = kmsg_dump_register(&cxt->dump); if (err) { diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 82c585f715e3..03ce7a9b81cc 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -94,20 +94,15 @@ static const char *get_reason_str(enum kmsg_dump_reason reason) * as we can from the end of the buffer. */ static void pstore_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, - const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { - unsigned long s1_start, s2_start; - unsigned long l1_cpy, l2_cpy; - unsigned long size, total = 0; - char *dst; + unsigned long total = 0; const char *why; u64 id; - int hsize, ret; unsigned int part = 1; unsigned long flags = 0; int is_locked = 0; + int ret; why = get_reason_str(reason); @@ -119,30 +114,25 @@ static void pstore_dump(struct kmsg_dumper *dumper, spin_lock_irqsave(&psinfo->buf_lock, flags); oopscount++; while (total < kmsg_bytes) { + char *dst; + unsigned long size; + int hsize; + size_t len; + dst = psinfo->buf; hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part); size = psinfo->bufsize - hsize; dst += hsize; - l2_cpy = min(l2, size); - l1_cpy = min(l1, size - l2_cpy); - - if (l1_cpy + l2_cpy == 0) + if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len)) break; - s2_start = l2 - l2_cpy; - s1_start = l1 - l1_cpy; - - memcpy(dst, s1 + s1_start, l1_cpy); - memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); - ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, - hsize + l1_cpy + l2_cpy, psinfo); + hsize + len, psinfo); if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) pstore_new_entry = 1; - l1 -= l1_cpy; - l2 -= l2_cpy; - total += l1_cpy + l2_cpy; + + total += hsize + len; part++; } if (in_nmi()) { diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index 35f7237ec972..af4eb5a39d9a 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -21,6 +21,7 @@ * is passed to the kernel. */ enum kmsg_dump_reason { + KMSG_DUMP_UNDEF, KMSG_DUMP_PANIC, KMSG_DUMP_OOPS, KMSG_DUMP_EMERG, @@ -31,23 +32,37 @@ enum kmsg_dump_reason { /** * struct kmsg_dumper - kernel crash message dumper structure - * @dump: The callback which gets called on crashes. The buffer is passed - * as two sections, where s1 (length l1) contains the older - * messages and s2 (length l2) contains the newer. * @list: Entry in the dumper list (private) + * @dump: Call into dumping code which will retrieve the data with + * through the record iterator + * @max_reason: filter for highest reason number that should be dumped * @registered: Flag that specifies if this is already registered */ struct kmsg_dumper { - void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason, - const char *s1, unsigned long l1, - const char *s2, unsigned long l2); struct list_head list; - int registered; + void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason); + enum kmsg_dump_reason max_reason; + bool active; + bool registered; + + /* private state of the kmsg iterator */ + u32 cur_idx; + u32 next_idx; + u64 cur_seq; + u64 next_seq; }; #ifdef CONFIG_PRINTK void kmsg_dump(enum kmsg_dump_reason reason); +bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + char *line, size_t size, size_t *len); + +bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len); + +void kmsg_dump_rewind(struct kmsg_dumper *dumper); + int kmsg_dump_register(struct kmsg_dumper *dumper); int kmsg_dump_unregister(struct kmsg_dumper *dumper); @@ -56,6 +71,22 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason) { } +bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + const char *line, size_t size, size_t *len) +{ + return false; +} + +bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len) +{ + return false; +} + +void kmsg_dump_rewind(struct kmsg_dumper *dumper) +{ +} + static inline int kmsg_dump_register(struct kmsg_dumper *dumper) { return -EINVAL; diff --git a/kernel/printk.c b/kernel/printk.c index f205c25c37e2..ceb4a2f775a1 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -909,7 +909,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) /* * Find first record that fits, including all following records, * into the user-provided buffer for this dump. - */ + */ seq = clear_seq; idx = clear_idx; while (seq < log_next_seq) { @@ -919,6 +919,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear) idx = log_next(idx); seq++; } + + /* move first record forward until length fits into the buffer */ seq = clear_seq; idx = clear_idx; while (len > size && seq < log_next_seq) { @@ -929,7 +931,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) seq++; } - /* last message in this dump */ + /* last message fitting into this dump */ next_seq = log_next_seq; len = 0; @@ -2300,48 +2302,210 @@ module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); * kmsg_dump - dump kernel log to kernel message dumpers. * @reason: the reason (oops, panic etc) for dumping * - * Iterate through each of the dump devices and call the oops/panic - * callbacks with the log buffer. + * Call each of the registered dumper's dump() callback, which can + * retrieve the kmsg records with kmsg_dump_get_line() or + * kmsg_dump_get_buffer(). */ void kmsg_dump(enum kmsg_dump_reason reason) { - u64 idx; struct kmsg_dumper *dumper; - const char *s1, *s2; - unsigned long l1, l2; unsigned long flags; if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump) return; - /* Theoretically, the log could move on after we do this, but - there's not a lot we can do about that. The new messages - will overwrite the start of what we dump. */ + rcu_read_lock(); + list_for_each_entry_rcu(dumper, &dump_list, list) { + if (dumper->max_reason && reason > dumper->max_reason) + continue; + + /* initialize iterator with data about the stored records */ + dumper->active = true; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + dumper->cur_seq = clear_seq; + dumper->cur_idx = clear_idx; + dumper->next_seq = log_next_seq; + dumper->next_idx = log_next_idx; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + + /* invoke dumper which will iterate over records */ + dumper->dump(dumper, reason); + + /* reset iterator */ + dumper->active = false; + } + rcu_read_unlock(); +} + +/** + * kmsg_dump_get_line - retrieve one kmsg log line + * @dumper: registered kmsg dumper + * @syslog: include the "<4>" prefixes + * @line: buffer to copy the line to + * @size: maximum size of the buffer + * @len: length of line placed into buffer + * + * Start at the beginning of the kmsg buffer, with the oldest kmsg + * record, and copy one record into the provided buffer. + * + * Consecutive calls will return the next available record moving + * towards the end of the buffer with the youngest messages. + * + * A return value of FALSE indicates that there are no more records to + * read. + */ +bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + char *line, size_t size, size_t *len) +{ + unsigned long flags; + struct log *msg; + size_t l = 0; + bool ret = false; + + if (!dumper->active) + goto out; raw_spin_lock_irqsave(&logbuf_lock, flags); - if (syslog_seq < log_first_seq) - idx = syslog_idx; - else - idx = log_first_idx; + if (dumper->cur_seq < log_first_seq) { + /* messages are gone, move to first available one */ + dumper->cur_seq = log_first_seq; + dumper->cur_idx = log_first_idx; + } - if (idx > log_next_idx) { - s1 = log_buf; - l1 = log_next_idx; + /* last entry */ + if (dumper->cur_seq >= log_next_seq) { + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + goto out; + } - s2 = log_buf + idx; - l2 = log_buf_len - idx; - } else { - s1 = ""; - l1 = 0; + msg = log_from_idx(dumper->cur_idx); + l = msg_print_text(msg, syslog, + line, size); + + dumper->cur_idx = log_next(dumper->cur_idx); + dumper->cur_seq++; + ret = true; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); +out: + if (len) + *len = l; + return ret; +} +EXPORT_SYMBOL_GPL(kmsg_dump_get_line); + +/** + * kmsg_dump_get_buffer - copy kmsg log lines + * @dumper: registered kmsg dumper + * @syslog: include the "<4>" prefixes + * @line: buffer to copy the line to + * @size: maximum size of the buffer + * @len: length of line placed into buffer + * + * Start at the end of the kmsg buffer and fill the provided buffer + * with as many of the the *youngest* kmsg records that fit into it. + * If the buffer is large enough, all available kmsg records will be + * copied with a single call. + * + * Consecutive calls will fill the buffer with the next block of + * available older records, not including the earlier retrieved ones. + * + * A return value of FALSE indicates that there are no more records to + * read. + */ +bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len) +{ + unsigned long flags; + u64 seq; + u32 idx; + u64 next_seq; + u32 next_idx; + size_t l = 0; + bool ret = false; + + if (!dumper->active) + goto out; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + if (dumper->cur_seq < log_first_seq) { + /* messages are gone, move to first available one */ + dumper->cur_seq = log_first_seq; + dumper->cur_idx = log_first_idx; + } + + /* last entry */ + if (dumper->cur_seq >= dumper->next_seq) { + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + goto out; + } + + /* calculate length of entire buffer */ + seq = dumper->cur_seq; + idx = dumper->cur_idx; + while (seq < dumper->next_seq) { + struct log *msg = log_from_idx(idx); + + l += msg_print_text(msg, true, NULL, 0); + idx = log_next(idx); + seq++; + } + + /* move first record forward until length fits into the buffer */ + seq = dumper->cur_seq; + idx = dumper->cur_idx; + while (l > size && seq < dumper->next_seq) { + struct log *msg = log_from_idx(idx); - s2 = log_buf + idx; - l2 = log_next_idx - idx; + l -= msg_print_text(msg, true, NULL, 0); + idx = log_next(idx); + seq++; } + + /* last message in next interation */ + next_seq = seq; + next_idx = idx; + + l = 0; + while (seq < dumper->next_seq) { + struct log *msg = log_from_idx(idx); + + l += msg_print_text(msg, syslog, + buf + l, size - l); + + idx = log_next(idx); + seq++; + } + + dumper->next_seq = next_seq; + dumper->next_idx = next_idx; + ret = true; raw_spin_unlock_irqrestore(&logbuf_lock, flags); +out: + if (len) + *len = l; + return ret; +} +EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer); - rcu_read_lock(); - list_for_each_entry_rcu(dumper, &dump_list, list) - dumper->dump(dumper, reason, s1, l1, s2, l2); - rcu_read_unlock(); +/** + * kmsg_dump_rewind - reset the interator + * @dumper: registered kmsg dumper + * + * Reset the dumper's iterator so that kmsg_dump_get_line() and + * kmsg_dump_get_buffer() can be called again and used multiple + * times within the same dumper.dump() callback. + */ +void kmsg_dump_rewind(struct kmsg_dumper *dumper) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&logbuf_lock, flags); + dumper->cur_seq = clear_seq; + dumper->cur_idx = clear_idx; + dumper->next_seq = log_next_seq; + dumper->next_idx = log_next_idx; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); } +EXPORT_SYMBOL_GPL(kmsg_dump_rewind); #endif -- GitLab From 81aded24675ebda5de8a68843250ad15584ac38a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 15 Jun 2012 14:54:11 -0700 Subject: [PATCH 1695/6849] ipv6: Handle PMTU in ICMP error handlers. One tricky issue on the ipv6 side vs. ipv4 is that the ICMP callouts to handle the error pass the 32-bit info cookie in network byte order whereas ipv4 passes it around in host byte order. Like the ipv4 side, we have two helper functions. One for when we have a socket context and one for when we do not. ip6ip6 tunnels are not handled here, because they handle PMTU events by essentially relaying another ICMP packet-too-big message back to the original sender. This patch allows us to get rid of rt6_do_pmtu_disc(). It handles all kinds of situations that simply cannot happen when we do the PMTU update directly using a fully resolved route. In fact, the "plen == 128" check in ip6_rt_update_pmtu() can very likely be removed or changed into a BUG_ON() check. We should never have a prefixed ipv6 route when we get there. Another piece of strange history here is that TCP and DCCP, unlike in ipv4, never invoke the update_pmtu() method from their ICMP error handlers. This is incredibly astonishing since this is the context where we have the most accurate context in which to make a PMTU update, namely we have a fully connected socket and associated cached socket route. Signed-off-by: David S. Miller --- include/net/ip6_route.h | 8 +-- net/dccp/ipv6.c | 2 + net/ipv6/ah6.c | 3 +- net/ipv6/esp6.c | 2 + net/ipv6/icmp.c | 6 +- net/ipv6/ipcomp6.c | 2 + net/ipv6/raw.c | 5 +- net/ipv6/route.c | 143 ++++++++++------------------------------ net/ipv6/tcp_ipv6.c | 2 + net/ipv6/udp.c | 3 + 10 files changed, 54 insertions(+), 122 deletions(-) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index a2cda240ca95..58cb3fc34879 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -140,10 +140,10 @@ extern void rt6_redirect(const struct in6_addr *dest, u8 *lladdr, int on_link); -extern void rt6_pmtu_discovery(const struct in6_addr *daddr, - const struct in6_addr *saddr, - struct net_device *dev, - u32 pmtu); +extern void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, + int oif, u32 mark); +extern void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, + __be32 mtu); struct netlink_callback; diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index fa9512d86f3b..9991be083ad0 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -165,6 +165,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, } else dst_hold(dst); + dst->ops->update_pmtu(dst, ntohl(info)); + if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { dccp_sync_mss(sk, dst_mtu(dst)); } /* else let the usual retransmit timer handle it */ diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index f1a4a2c28ed3..49d4d26bda88 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -621,7 +622,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/%pI6\n", ntohl(ah->spi), &iph->daddr); - + ip6_update_pmtu(skb, net, info, 0, 0); xfrm_state_put(x); } diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index db1521fcda5b..89a615ba84f8 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -442,6 +443,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, return; pr_debug("pmtu discovery on SA ESP/%08x/%pI6\n", ntohl(esph->spi), &iph->daddr); + ip6_update_pmtu(skb, net, info, 0, 0); xfrm_state_put(x); } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index ed89bba745a1..5247d5c211f9 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -649,7 +649,6 @@ static int icmpv6_rcv(struct sk_buff *skb) struct net_device *dev = skb->dev; struct inet6_dev *idev = __in6_dev_get(dev); const struct in6_addr *saddr, *daddr; - const struct ipv6hdr *orig_hdr; struct icmp6hdr *hdr; u8 type; @@ -661,7 +660,7 @@ static int icmpv6_rcv(struct sk_buff *skb) XFRM_STATE_ICMP)) goto drop_no_count; - if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(*orig_hdr))) + if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(struct ipv6hdr))) goto drop_no_count; nh = skb_network_offset(skb); @@ -722,9 +721,6 @@ static int icmpv6_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto discard_it; hdr = icmp6_hdr(skb); - orig_hdr = (struct ipv6hdr *) (hdr + 1); - rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev, - ntohl(hdr->icmp6_mtu)); /* * Drop through to notify diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 5cb75bfe45b1..92832385a8ef 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, pr_debug("pmtu discovery on SA IPCOMP/%08x/%pI6\n", spi, &iph->daddr); + ip6_update_pmtu(skb, net, info, 0, 0); xfrm_state_put(x); } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 93d69836fded..43b0042f15f4 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -328,9 +328,10 @@ static void rawv6_err(struct sock *sk, struct sk_buff *skb, return; harderr = icmpv6_err_convert(type, code, &err); - if (type == ICMPV6_PKT_TOOBIG) + if (type == ICMPV6_PKT_TOOBIG) { + ip6_sk_update_pmtu(skb, sk, info); harderr = (np->pmtudisc == IPV6_PMTUDISC_DO); - + } if (np->recverr) { u8 *payload = skb->data; if (!inet->hdrincl) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 58a3ec23da2f..0d41f68daff2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1049,7 +1049,10 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) { struct rt6_info *rt6 = (struct rt6_info*)dst; + dst_confirm(dst); if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) { + struct net *net = dev_net(dst->dev); + rt6->rt6i_flags |= RTF_MODIFIED; if (mtu < IPV6_MIN_MTU) { u32 features = dst_metric(dst, RTAX_FEATURES); @@ -1058,9 +1061,39 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) dst_metric_set(dst, RTAX_FEATURES, features); } dst_metric_set(dst, RTAX_MTU, mtu); + rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); } } +void ip6_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, + int oif, __be32 mark) +{ + const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; + struct dst_entry *dst; + struct flowi6 fl6; + + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_oif = oif; + fl6.flowi6_mark = mark; + fl6.flowi6_flags = FLOWI_FLAG_PRECOW_METRICS; + fl6.daddr = iph->daddr; + fl6.saddr = iph->saddr; + fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK; + + dst = ip6_route_output(net, NULL, &fl6); + if (!dst->error) + ip6_rt_update_pmtu(dst, ntohl(mtu)); + dst_release(dst); +} +EXPORT_SYMBOL_GPL(ip6_update_pmtu); + +void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) +{ + ip6_update_pmtu(skb, sock_net(sk), mtu, + sk->sk_bound_dev_if, sk->sk_mark); +} +EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); + static unsigned int ip6_default_advmss(const struct dst_entry *dst) { struct net_device *dev = dst->dev; @@ -1703,116 +1736,6 @@ out: dst_release(&rt->dst); } -/* - * Handle ICMP "packet too big" messages - * i.e. Path MTU discovery - */ - -static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr *saddr, - struct net *net, u32 pmtu, int ifindex) -{ - struct rt6_info *rt, *nrt; - int allfrag = 0; -again: - rt = rt6_lookup(net, daddr, saddr, ifindex, 0); - if (!rt) - return; - - if (rt6_check_expired(rt)) { - ip6_del_rt(rt); - goto again; - } - - if (pmtu >= dst_mtu(&rt->dst)) - goto out; - - if (pmtu < IPV6_MIN_MTU) { - /* - * According to RFC2460, PMTU is set to the IPv6 Minimum Link - * MTU (1280) and a fragment header should always be included - * after a node receiving Too Big message reporting PMTU is - * less than the IPv6 Minimum Link MTU. - */ - pmtu = IPV6_MIN_MTU; - allfrag = 1; - } - - /* New mtu received -> path was valid. - They are sent only in response to data packets, - so that this nexthop apparently is reachable. --ANK - */ - dst_confirm(&rt->dst); - - /* Host route. If it is static, it would be better - not to override it, but add new one, so that - when cache entry will expire old pmtu - would return automatically. - */ - if (rt->rt6i_flags & RTF_CACHE) { - dst_metric_set(&rt->dst, RTAX_MTU, pmtu); - if (allfrag) { - u32 features = dst_metric(&rt->dst, RTAX_FEATURES); - features |= RTAX_FEATURE_ALLFRAG; - dst_metric_set(&rt->dst, RTAX_FEATURES, features); - } - rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); - rt->rt6i_flags |= RTF_MODIFIED; - goto out; - } - - /* Network route. - Two cases are possible: - 1. It is connected route. Action: COW - 2. It is gatewayed route or NONEXTHOP route. Action: clone it. - */ - if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) - nrt = rt6_alloc_cow(rt, daddr, saddr); - else - nrt = rt6_alloc_clone(rt, daddr); - - if (nrt) { - dst_metric_set(&nrt->dst, RTAX_MTU, pmtu); - if (allfrag) { - u32 features = dst_metric(&nrt->dst, RTAX_FEATURES); - features |= RTAX_FEATURE_ALLFRAG; - dst_metric_set(&nrt->dst, RTAX_FEATURES, features); - } - - /* According to RFC 1981, detecting PMTU increase shouldn't be - * happened within 5 mins, the recommended timer is 10 mins. - * Here this route expiration time is set to ip6_rt_mtu_expires - * which is 10 mins. After 10 mins the decreased pmtu is expired - * and detecting PMTU increase will be automatically happened. - */ - rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires); - nrt->rt6i_flags |= RTF_DYNAMIC; - ip6_ins_rt(nrt); - } -out: - dst_release(&rt->dst); -} - -void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *saddr, - struct net_device *dev, u32 pmtu) -{ - struct net *net = dev_net(dev); - - /* - * RFC 1981 states that a node "MUST reduce the size of the packets it - * is sending along the path" that caused the Packet Too Big message. - * Since it's not possible in the general case to determine which - * interface was used to send the original packet, we update the MTU - * on the interface that will be used to send future packets. We also - * update the MTU on the interface that received the Packet Too Big in - * case the original packet was forced out that interface with - * SO_BINDTODEVICE or similar. This is the next best thing to the - * correct behaviour, which would be to update the MTU on all - * interfaces. - */ - rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0); - rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex); -} - /* * Misc support functions */ diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index f91b0bfd12d5..26a88623940b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -415,6 +415,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, } else dst_hold(dst); + dst->ops->update_pmtu(dst, ntohl(info)); + if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { tcp_sync_mss(sk, dst_mtu(dst)); tcp_simple_retransmit(sk); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index f05099fc5901..051ad481973f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -479,6 +479,9 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (sk == NULL) return; + if (type == ICMPV6_PKT_TOOBIG) + ip6_sk_update_pmtu(skb, sk, info); + np = inet6_sk(sk); if (!icmpv6_err_convert(type, code, &err) && !np->recverr) -- GitLab From 71c421dbd9d87ffe6229816a04b759ec5613014d Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Fri, 15 Jun 2012 12:01:33 +0200 Subject: [PATCH 1696/6849] usb: correct trivial typo in drivers/usb/host/Kconfig Correct "Enbale" -> "Enable", in the desc for USB_HCD_BCMA and USB_HCD_SSB. Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 83e58df29fe3..18ba33da34ec 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -652,7 +652,7 @@ config USB_HCD_BCMA select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD help - Enbale support for the EHCI and OCHI host controller on an bcma bus. + Enable support for the EHCI and OCHI host controller on an bcma bus. It converts the bcma driver into two platform device drivers for ehci and ohci. @@ -664,7 +664,7 @@ config USB_HCD_SSB select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD help - Enbale support for the EHCI and OCHI host controller on an bcma bus. + Enable support for the EHCI and OCHI host controller on an bcma bus. It converts the bcma driver into two platform device drivers for ehci and ohci. -- GitLab From d9cb9bd63eb27ac19f26a8547128c053f43a5da8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Jun 2012 00:20:44 +0000 Subject: [PATCH 1697/6849] can: c_can: precedence error in c_can_chip_config() (CAN_CTRLMODE_LISTENONLY & CAN_CTRLMODE_LOOPBACK) is (0x02 & 0x01) which is zero so the condition is never true. The intent here was to test that both flags were set. Cc: # 2.6.39+ Signed-off-by: Dan Carpenter Acked-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/c_can/c_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 8dc84d66eea1..86cd532c78f9 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -590,8 +590,8 @@ static void c_can_chip_config(struct net_device *dev) priv->write_reg(priv, &priv->regs->control, CONTROL_ENABLE_AR); - if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & - CAN_CTRLMODE_LOOPBACK)) { + if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && + (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); -- GitLab From bc14786a100cc6a81cd060e8031ec481241b418c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Jun 2012 09:45:16 +0000 Subject: [PATCH 1698/6849] bnx2x: fix panic when TX ring is full There is a off by one error in the minimal number of BD in bnx2x_start_xmit() and bnx2x_tx_int() before stopping/resuming tx queue. A full size GSO packet, with data included in skb->head really needs (MAX_SKB_FRAGS + 4) BDs, because of bnx2x_tx_split() This error triggers if BQL is disabled and heavy TCP transmit traffic occurs. bnx2x_tx_split() definitely can be called, remove a wrong comment. Reported-by: Tomas Hruby Signed-off-by: Eric Dumazet Cc: Eilon Greenstein Cc: Yaniv Rosner Cc: Merav Sicron Cc: Tom Herbert Cc: Robert Evans Cc: Willem de Bruijn Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index cbc56f274e0c..8098eea9704d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -190,7 +190,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) if ((netif_tx_queue_stopped(txq)) && (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) netif_tx_wake_queue(txq); __netif_tx_unlock(txq); @@ -2516,8 +2516,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs - * So far this has only been observed to happen - * in Other Operating Systems(TM) */ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, @@ -3171,7 +3169,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) txdata->tx_bd_prod += nbd; - if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { netif_tx_stop_queue(txq); /* paired memory barrier is in bnx2x_tx_int(), we have to keep @@ -3180,7 +3178,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_mb(); fp->eth_q_stats.driver_xoff++; - if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) netif_tx_wake_queue(txq); } txdata->tx_pkt++; -- GitLab From 62b1a8ab9b3660bb820d8dfe23148ed6cda38574 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Jun 2012 06:42:44 +0000 Subject: [PATCH 1699/6849] net: remove skb_orphan_try() Orphaning skb in dev_hard_start_xmit() makes bonding behavior unfriendly for applications sending big UDP bursts : Once packets pass the bonding device and come to real device, they might hit a full qdisc and be dropped. Without orphaning, the sender is automatically throttled because sk->sk_wmemalloc reaches sk->sk_sndbuf (assuming sk_sndbuf is not too big) We could try to defer the orphaning adding another test in dev_hard_start_xmit(), but all this seems of little gain, now that BQL tends to make packets more likely to be parked in Qdisc queues instead of NIC TX ring, in cases where performance matters. Reverts commits : fc6055a5ba31 net: Introduce skb_orphan_try() 87fd308cfc6b net: skb_tx_hash() fix relative to skb_orphan_try() and removes SKBTX_DRV_NEEDS_SK_REF flag Reported-and-bisected-by: Jean-Michel Hautbois Signed-off-by: Eric Dumazet Tested-by: Oliver Hartkopp Acked-by: Oliver Hartkopp Signed-off-by: David S. Miller --- include/linux/skbuff.h | 7 ++----- net/can/raw.c | 3 --- net/core/dev.c | 23 +---------------------- net/iucv/af_iucv.c | 1 - 4 files changed, 3 insertions(+), 31 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b534a1be540a..642cb7355df3 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -225,14 +225,11 @@ enum { /* device driver is going to provide hardware time stamp */ SKBTX_IN_PROGRESS = 1 << 2, - /* ensure the originating sk reference is available on driver level */ - SKBTX_DRV_NEEDS_SK_REF = 1 << 3, - /* device driver supports TX zero-copy buffers */ - SKBTX_DEV_ZEROCOPY = 1 << 4, + SKBTX_DEV_ZEROCOPY = 1 << 3, /* generate wifi status information (where possible) */ - SKBTX_WIFI_STATUS = 1 << 5, + SKBTX_WIFI_STATUS = 1 << 4, }; /* diff --git a/net/can/raw.c b/net/can/raw.c index cde1b4a20f75..46cca3a91d19 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -681,9 +681,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, if (err < 0) goto free_skb; - /* to be able to check the received tx sock reference in raw_rcv() */ - skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; - skb->dev = dev; skb->sk = sk; diff --git a/net/core/dev.c b/net/core/dev.c index cd0981977f5c..6df214041a5e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2089,25 +2089,6 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) return 0; } -/* - * Try to orphan skb early, right before transmission by the device. - * We cannot orphan skb if tx timestamp is requested or the sk-reference - * is needed on driver level for other reasons, e.g. see net/can/raw.c - */ -static inline void skb_orphan_try(struct sk_buff *skb) -{ - struct sock *sk = skb->sk; - - if (sk && !skb_shinfo(skb)->tx_flags) { - /* skb_tx_hash() wont be able to get sk. - * We copy sk_hash into skb->rxhash - */ - if (!skb->rxhash) - skb->rxhash = sk->sk_hash; - skb_orphan(skb); - } -} - static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) { return ((features & NETIF_F_GEN_CSUM) || @@ -2193,8 +2174,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, if (!list_empty(&ptype_all)) dev_queue_xmit_nit(skb, dev); - skb_orphan_try(skb); - features = netif_skb_features(skb); if (vlan_tx_tag_present(skb) && @@ -2304,7 +2283,7 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, if (skb->sk && skb->sk->sk_hash) hash = skb->sk->sk_hash; else - hash = (__force u16) skb->protocol ^ skb->rxhash; + hash = (__force u16) skb->protocol; hash = jhash_1word(hash, hashrnd); return (u16) (((u64) hash * qcount) >> 32) + qoffset; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 07d7d55a1b93..cd6f7a991d80 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -372,7 +372,6 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, skb_trim(skb, skb->dev->mtu); } skb->protocol = ETH_P_AF_IUCV; - skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; nskb = skb_clone(skb, GFP_ATOMIC); if (!nskb) return -ENOMEM; -- GitLab From 0f6efff92524c65fc3ef41c8b936c526580f1db0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Jun 2012 08:34:24 +0000 Subject: [PATCH 1700/6849] qlcnic: off by one in qlcnic_init_pci_info() The adapter->npars[] array has QLCNIC_MAX_PCI_FUNC elements. We allocate it that way a few lines earlier in the function. So this test is off by one. Signed-off-by: Dan Carpenter Acked-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2c5121..ad98f4d7919d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -479,7 +479,7 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { pfn = pci_info[i].id; - if (pfn > QLCNIC_MAX_PCI_FUNC) { + if (pfn >= QLCNIC_MAX_PCI_FUNC) { ret = QL_STATUS_INVALID_PARAM; goto err_eswitch; } -- GitLab From 2a0c451ade8e1783c5d453948289e4a978d417c9 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 14 Jun 2012 23:00:17 +0000 Subject: [PATCH 1701/6849] ipv6: Prevent access to uninitialized fib_table_hash via /proc/net/ipv6_route /proc/net/ipv6_route reflects the contents of fib_table_hash. The proc handler is installed in ip6_route_net_init() whereas fib_table_hash is allocated in fib6_net_init() _after_ the proc handler has been installed. This opens up a short time frame to access fib_table_hash with its pants down. fib6_init() as a whole can't be moved to an earlier position as it also registers the rtnetlink message handlers which should be registered at the end. Therefore split it into fib6_init() which is run early and fib6_init_late() to register the rtnetlink message handlers. Signed-off-by: Thomas Graf Reviewed-by: Neil Horman Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 2 ++ net/ipv6/ip6_fib.c | 18 +++++++++++------- net/ipv6/route.c | 16 +++++++++++----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 0ae759a6c76e..209af13b0336 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -271,6 +271,8 @@ extern void fib6_run_gc(unsigned long expires, extern void fib6_gc_cleanup(void); extern int fib6_init(void); +extern int fib6_init_late(void); +extern void fib6_cleanup_late(void); #ifdef CONFIG_IPV6_MULTIPLE_TABLES extern int fib6_rules_init(void); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 74c21b924a79..fbd4afff05fa 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1692,21 +1692,25 @@ int __init fib6_init(void) ret = register_pernet_subsys(&fib6_net_ops); if (ret) goto out_kmem_cache_create; - - ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib, - NULL); - if (ret) - goto out_unregister_subsys; out: return ret; -out_unregister_subsys: - unregister_pernet_subsys(&fib6_net_ops); out_kmem_cache_create: kmem_cache_destroy(fib6_node_kmem); goto out; } +int __init fib6_init_late(void) +{ + return __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib, + NULL); +} + +void fib6_cleanup_late(void) +{ + rtnl_unregister(PF_INET6, RTM_GETROUTE); +} + void fib6_gc_cleanup(void) { unregister_pernet_subsys(&fib6_net_ops); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 999a982ad3fd..dc60bf585966 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -3018,10 +3018,14 @@ int __init ip6_route_init(void) if (ret) goto out_kmem_cache; - ret = register_pernet_subsys(&ip6_route_net_ops); + ret = fib6_init(); if (ret) goto out_dst_entries; + ret = register_pernet_subsys(&ip6_route_net_ops); + if (ret) + goto out_fib6_init; + ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; /* Registering of the loopback is done before this portion of code, @@ -3035,13 +3039,13 @@ int __init ip6_route_init(void) init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); #endif - ret = fib6_init(); + ret = fib6_init_late(); if (ret) goto out_register_subsys; ret = xfrm6_init(); if (ret) - goto out_fib6_init; + goto out_fib6_init_late; ret = fib6_rules_init(); if (ret) @@ -3064,10 +3068,12 @@ fib6_rules_init: fib6_rules_cleanup(); xfrm6_init: xfrm6_fini(); -out_fib6_init: - fib6_gc_cleanup(); +out_fib6_init_late: + fib6_cleanup_late(); out_register_subsys: unregister_pernet_subsys(&ip6_route_net_ops); +out_fib6_init: + fib6_gc_cleanup(); out_dst_entries: dst_entries_destroy(&ip6_dst_blackhole_ops); out_kmem_cache: -- GitLab From 60cd4dba9b75da175c79d0dc6d7beb8701307ff8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 15 Jun 2012 16:38:23 -0600 Subject: [PATCH 1702/6849] sparc/PCI: remove unused pcibios_assign_resource() definition pcibios_assign_resource() isn't used anywhere; remove it. Signed-off-by: Bjorn Helgaas --- arch/sparc/kernel/pcic.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index ded3f6090c3f..46ba84998f16 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -884,11 +884,6 @@ void __init sun4m_pci_init_IRQ(void) sparc_config.load_profile_irq = pcic_load_profile_irq; } -int pcibios_assign_resource(struct pci_dev *pdev, int resource) -{ - return -ENXIO; -} - /* * This probably belongs here rather than ioport.c because * we do not want this crud linked into SBus kernels. -- GitLab From f961f72836eb6c0fd76201f6f6b2fafff93c4cea Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 15 Jun 2012 07:56:20 -0600 Subject: [PATCH 1703/6849] KVM: Fix PCI header check on device assignment The masking was wrong (must have been 0x7f), and there is no need to re-read the value as pci_setup_device already does this for us. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43339 Signed-off-by: Jan Kiszka Acked-by: Alex Williamson Signed-off-by: Marcelo Tosatti --- virt/kvm/assigned-dev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 01f572c10c71..b1e091ae2f37 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -635,7 +635,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, int r = 0, idx; struct kvm_assigned_dev_kernel *match; struct pci_dev *dev; - u8 header_type; if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)) return -EINVAL; @@ -668,8 +667,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, } /* Don't allow bridges to be assigned */ - pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); - if ((header_type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) { + if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) { r = -EPERM; goto out_put; } -- GitLab From 42ae66c80d94645e8f74080c7f344596d6f19cd5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 15 Jun 2012 20:01:57 -0700 Subject: [PATCH 1704/6849] ipv6: Fix types of ip6_update_pmtu(). The mtu should be a __be32, not the mark. Reported-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv6/route.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c7ccc36ba63e..1c279fe2c9b4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1065,8 +1065,8 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } } -void ip6_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, - int oif, __be32 mark) +void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, + int oif, u32 mark) { const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data; struct dst_entry *dst; -- GitLab From ea131377148cdfe90641b42ae9aa5a6b3a4fa327 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:22 +0200 Subject: [PATCH 1705/6849] uprobes: Valid_vma() should reject VM_HUGETLB __replace_page() obviously can't work with the hugetlbfs mappings, uprobe_register() will likely crash the kernel. Change valid_vma() to check VM_HUGETLB as well. As for PageTransHuge() no need to worry, vma->vm_file != NULL. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154322.GA9561@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index b52376d02332..f0d04530af63 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -99,7 +99,8 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register) if (!is_register) return true; - if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC)) + if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) + == (VM_READ|VM_EXEC)) return true; return false; -- GitLab From cc359d180fa9c25a4c1819f17e07a422d788353d Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:25 +0200 Subject: [PATCH 1706/6849] uprobes: __copy_insn() should ensure a_ops->readpage != NULL __copy_insn() blindly calls read_mapping_page(), this will crash the kernel if ->readpage == NULL, add the necessary check. For example, hugetlbfs_aops->readpage is NULL. Perhaps we should change read_mapping_page() instead. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154325.GA9568@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index f0d04530af63..604930bf9c92 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -610,6 +610,9 @@ __copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *ins if (!filp) return -EINVAL; + if (!mapping->a_ops->readpage) + return -EIO; + idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT); off1 = offset &= ~PAGE_MASK; -- GitLab From 5323ce71e4b4e1f188ebbc0cc7776885ea6c75fb Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:28 +0200 Subject: [PATCH 1707/6849] uprobes: Write_opcode()->__replace_page() can race with try_to_unmap() write_opcode() gets old_page via get_user_pages() and then calls __replace_page() which assumes that this old_page is still mapped after pte_offset_map_lock(). This is not true if this old_page was already try_to_unmap()'ed, and in this case everything __replace_page() does with old_page is wrong. Just for example, put_page() is not balanced. I think it is possible to teach __replace_page() to handle this unlikely case correctly, but this patch simply changes it to use page_check_address() and return -EAGAIN if it fails. The caller should notice this error code and retry. Note: write_opcode() asks for the cleanups, I'll try to do this in a separate patch. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154328.GA9571@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 604930bf9c92..3ccdb29ee8d6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -129,33 +129,17 @@ static loff_t vma_address(struct vm_area_struct *vma, loff_t offset) static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage) { struct mm_struct *mm = vma->vm_mm; - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *ptep; - spinlock_t *ptl; unsigned long addr; - int err = -EFAULT; + spinlock_t *ptl; + pte_t *ptep; addr = page_address_in_vma(page, vma); if (addr == -EFAULT) - goto out; - - pgd = pgd_offset(mm, addr); - if (!pgd_present(*pgd)) - goto out; - - pud = pud_offset(pgd, addr); - if (!pud_present(*pud)) - goto out; + return -EFAULT; - pmd = pmd_offset(pud, addr); - if (!pmd_present(*pmd)) - goto out; - - ptep = pte_offset_map_lock(mm, pmd, addr, &ptl); + ptep = page_check_address(page, mm, addr, &ptl, 0); if (!ptep) - goto out; + return -EAGAIN; get_page(kpage); page_add_new_anon_rmap(kpage, vma, addr); @@ -174,10 +158,8 @@ static int __replace_page(struct vm_area_struct *vma, struct page *page, struct try_to_free_swap(page); put_page(page); pte_unmap_unlock(ptep, ptl); - err = 0; -out: - return err; + return 0; } /** @@ -222,9 +204,10 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, void *vaddr_old, *vaddr_new; struct vm_area_struct *vma; struct uprobe *uprobe; + unsigned long pgoff; loff_t addr; int ret; - +retry: /* Read the page with vaddr into memory */ ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); if (ret <= 0) @@ -269,9 +252,9 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, memcpy(vaddr_new, vaddr_old, PAGE_SIZE); /* poke the new insn in, ASSUMES we don't cross page boundary */ - vaddr &= ~PAGE_MASK; - BUG_ON(vaddr + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); - memcpy(vaddr_new + vaddr, &opcode, UPROBE_SWBP_INSN_SIZE); + pgoff = (vaddr & ~PAGE_MASK); + BUG_ON(pgoff + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); + memcpy(vaddr_new + pgoff, &opcode, UPROBE_SWBP_INSN_SIZE); kunmap_atomic(vaddr_new); kunmap_atomic(vaddr_old); @@ -291,6 +274,8 @@ unlock_out: put_out: put_page(old_page); + if (unlikely(ret == -EAGAIN)) + goto retry; return ret; } -- GitLab From c1914a0936f79ed0236f670122e06e36e4d332ee Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:31 +0200 Subject: [PATCH 1708/6849] uprobes: Install_breakpoint() should fail if is_swbp_insn() == T install_breakpoint() returns -EEXIST if is_swbp_insn(orig_insn) == T, the caller treats this code as success. This is doubly wrong. The successful return should set UPROBE_COPY_INSN, but the real problem is that it shouldn't succeed. If the probed insn is int3 the application should get SIGTRAP, this won't happen with uprobe. Probably we can fix this, we can add the UPROBE_SHARED_BP flag and teach handle_swbp/set_orig_insn to handle this case correctly. But this needs some complications and we have other insns which can't be probed, lets make a simple fix for now. I think this needs a cleanup. UPROBE_COPY_INSN should die, copy_insn() should be called by alloc_uprobe(). arch_uprobe_analyze_insn() depends on ->mm (ia32_compat) but it is called only once. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154331.GA9578@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 3ccdb29ee8d6..ec78152e32e9 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -693,7 +693,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, return ret; if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) - return -EEXIST; + return -ENOTSUPP; ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, addr); if (ret) -- GitLab From 268720903f87e0b84b161626c4447b81671b5d18 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:33 +0200 Subject: [PATCH 1709/6849] uprobes: Rework register_for_each_vma() to make it O(n) Currently register_for_each_vma() is O(n ** 2) + O(n ** 3), every time find_next_vma_info() "restarts" the vma_prio_tree_foreach() loop and each iteration rechecks the whole try_list. This also means that try_list can grow "indefinitely" if register/unregister races with munmap/mmap activity even if the number of mapping is bounded at any time. With this patch register_for_each_vma() builds the list of mm/vaddr structures only once and does install_breakpoint() for each entry. We do not care about the new mappings which can be created after build_map_info() drops mapping->i_mmap_mutex, uprobe_mmap() should do its work. Note that we do not allocate map_info under i_mmap_mutex, this can deadlock with page reclaim (but see the next patch). So we use 2 lists, "curr" which we are going to return, and "prev" which holds the already allocated memory. The main loop deques the entry from "prev" (initially it is empty), and if "prev" becomes empty again it counts the number of entries we need to pre-allocate outside of i_mmap_mutex. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Peter Zijlstra Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Link: http://lkml.kernel.org/r/20120615154333.GA9581@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 199 +++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 113 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index ec78152e32e9..4e0db3496d70 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -60,17 +60,6 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; */ static atomic_t uprobe_events = ATOMIC_INIT(0); -/* - * Maintain a temporary per vma info that can be used to search if a vma - * has already been handled. This structure is introduced since extending - * vm_area_struct wasnt recommended. - */ -struct vma_info { - struct list_head probe_list; - struct mm_struct *mm; - loff_t vaddr; -}; - struct uprobe { struct rb_node rb_node; /* node in the rb tree */ atomic_t ref; @@ -742,139 +731,123 @@ static void delete_uprobe(struct uprobe *uprobe) atomic_dec(&uprobe_events); } -static struct vma_info * -__find_next_vma_info(struct address_space *mapping, struct list_head *head, - struct vma_info *vi, loff_t offset, bool is_register) +struct map_info { + struct map_info *next; + struct mm_struct *mm; + loff_t vaddr; +}; + +static inline struct map_info *free_map_info(struct map_info *info) { + struct map_info *next = info->next; + kfree(info); + return next; +} + +static struct map_info * +build_map_info(struct address_space *mapping, loff_t offset, bool is_register) +{ + unsigned long pgoff = offset >> PAGE_SHIFT; struct prio_tree_iter iter; struct vm_area_struct *vma; - struct vma_info *tmpvi; - unsigned long pgoff; - int existing_vma; - loff_t vaddr; - - pgoff = offset >> PAGE_SHIFT; + struct map_info *curr = NULL; + struct map_info *prev = NULL; + struct map_info *info; + int more = 0; + again: + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { if (!valid_vma(vma, is_register)) continue; - existing_vma = 0; - vaddr = vma_address(vma, offset); - - list_for_each_entry(tmpvi, head, probe_list) { - if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) { - existing_vma = 1; - break; - } - } - - /* - * Another vma needs a probe to be installed. However skip - * installing the probe if the vma is about to be unlinked. - */ - if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) { - vi->mm = vma->vm_mm; - vi->vaddr = vaddr; - list_add(&vi->probe_list, head); - - return vi; + if (!prev) { + more++; + continue; } - } - - return NULL; -} -/* - * Iterate in the rmap prio tree and find a vma where a probe has not - * yet been inserted. - */ -static struct vma_info * -find_next_vma_info(struct address_space *mapping, struct list_head *head, - loff_t offset, bool is_register) -{ - struct vma_info *vi, *retvi; + if (!atomic_inc_not_zero(&vma->vm_mm->mm_users)) + continue; - vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL); - if (!vi) - return ERR_PTR(-ENOMEM); + info = prev; + prev = prev->next; + info->next = curr; + curr = info; - mutex_lock(&mapping->i_mmap_mutex); - retvi = __find_next_vma_info(mapping, head, vi, offset, is_register); + info->mm = vma->vm_mm; + info->vaddr = vma_address(vma, offset); + } mutex_unlock(&mapping->i_mmap_mutex); - if (!retvi) - kfree(vi); + if (!more) + goto out; + + prev = curr; + while (curr) { + mmput(curr->mm); + curr = curr->next; + } - return retvi; + do { + info = kmalloc(sizeof(struct map_info), GFP_KERNEL); + if (!info) { + curr = ERR_PTR(-ENOMEM); + goto out; + } + info->next = prev; + prev = info; + } while (--more); + + goto again; + out: + while (prev) + prev = free_map_info(prev); + return curr; } static int register_for_each_vma(struct uprobe *uprobe, bool is_register) { - struct list_head try_list; - struct vm_area_struct *vma; - struct address_space *mapping; - struct vma_info *vi, *tmpvi; - struct mm_struct *mm; - loff_t vaddr; - int ret; + struct map_info *info; + int err = 0; - mapping = uprobe->inode->i_mapping; - INIT_LIST_HEAD(&try_list); - - ret = 0; + info = build_map_info(uprobe->inode->i_mapping, + uprobe->offset, is_register); + if (IS_ERR(info)) + return PTR_ERR(info); - for (;;) { - vi = find_next_vma_info(mapping, &try_list, uprobe->offset, is_register); - if (!vi) - break; + while (info) { + struct mm_struct *mm = info->mm; + struct vm_area_struct *vma; + loff_t vaddr; - if (IS_ERR(vi)) { - ret = PTR_ERR(vi); - break; - } + if (err) + goto free; - mm = vi->mm; down_write(&mm->mmap_sem); - vma = find_vma(mm, (unsigned long)vi->vaddr); - if (!vma || !valid_vma(vma, is_register)) { - list_del(&vi->probe_list); - kfree(vi); - up_write(&mm->mmap_sem); - mmput(mm); - continue; - } + vma = find_vma(mm, (unsigned long)info->vaddr); + if (!vma || !valid_vma(vma, is_register)) + goto unlock; + vaddr = vma_address(vma, uprobe->offset); if (vma->vm_file->f_mapping->host != uprobe->inode || - vaddr != vi->vaddr) { - list_del(&vi->probe_list); - kfree(vi); - up_write(&mm->mmap_sem); - mmput(mm); - continue; - } + vaddr != info->vaddr) + goto unlock; - if (is_register) - ret = install_breakpoint(uprobe, mm, vma, vi->vaddr); - else - remove_breakpoint(uprobe, mm, vi->vaddr); - - up_write(&mm->mmap_sem); - mmput(mm); if (is_register) { - if (ret && ret == -EEXIST) - ret = 0; - if (ret) - break; + err = install_breakpoint(uprobe, mm, vma, info->vaddr); + if (err == -EEXIST) + err = 0; + } else { + remove_breakpoint(uprobe, mm, info->vaddr); } + unlock: + up_write(&mm->mmap_sem); + free: + mmput(mm); + info = free_map_info(info); } - list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) { - list_del(&vi->probe_list); - kfree(vi); - } - - return ret; + return err; } static int __uprobe_register(struct uprobe *uprobe) -- GitLab From 7a5bfb66b07f22d2429db776da7bb8b57bfb5cff Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:36 +0200 Subject: [PATCH 1710/6849] uprobes: Change build_map_info() to try kmalloc(GFP_NOWAIT) first build_map_info() doesn't allocate the memory under i_mmap_mutex to avoid the deadlock with page reclaim. But it can try GFP_NOWAIT first, it should work in the likely case and thus we almost never need the pre-alloc-and-retry path. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Peter Zijlstra Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Link: http://lkml.kernel.org/r/20120615154336.GA9588@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 4e0db3496d70..897417dbca8e 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -761,6 +761,16 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register) if (!valid_vma(vma, is_register)) continue; + if (!prev && !more) { + /* + * Needs GFP_NOWAIT to avoid i_mmap_mutex recursion through + * reclaim. This is optimistic, no harm done if it fails. + */ + prev = kmalloc(sizeof(struct map_info), + GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN); + if (prev) + prev->next = NULL; + } if (!prev) { more++; continue; -- GitLab From c5784de2b351fe871bb57487878f7fc7ec5b075c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 15 Jun 2012 17:43:39 +0200 Subject: [PATCH 1711/6849] uprobes: Document uprobe_register() vs uprobe_mmap() race Because the mind is treacherous and makes us forget we need to write stuff down. Signed-off-by: Peter Zijlstra Signed-off-by: Oleg Nesterov Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Cc: Srikar Dronamraju Link: http://lkml.kernel.org/r/20120615154339.GA9591@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 897417dbca8e..2671d9ad49be 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -44,6 +44,23 @@ static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */ #define UPROBES_HASH_SZ 13 +/* + * We need separate register/unregister and mmap/munmap lock hashes because + * of mmap_sem nesting. + * + * uprobe_register() needs to install probes on (potentially) all processes + * and thus needs to acquire multiple mmap_sems (consequtively, not + * concurrently), whereas uprobe_mmap() is called while holding mmap_sem + * for the particular process doing the mmap. + * + * uprobe_register()->register_for_each_vma() needs to drop/acquire mmap_sem + * because of lock order against i_mmap_mutex. This means there's a hole in + * the register vma iteration where a mmap() can happen. + * + * Thus uprobe_register() can race with uprobe_mmap() and we can try and + * install a probe where one is already installed. + */ + /* serialize (un)register */ static struct mutex uprobes_mutex[UPROBES_HASH_SZ]; @@ -339,7 +356,9 @@ out: int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) { int result; - + /* + * See the comment near uprobes_hash(). + */ result = is_swbp_at_addr(mm, vaddr); if (result == 1) return -EEXIST; @@ -845,6 +864,10 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) if (is_register) { err = install_breakpoint(uprobe, mm, vma, info->vaddr); + /* + * We can race against uprobe_mmap(), see the + * comment near uprobe_hash(). + */ if (err == -EEXIST) err = 0; } else { @@ -1054,8 +1077,10 @@ int uprobe_mmap(struct vm_area_struct *vma) } ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); - - /* Ignore double add: */ + /* + * We can race against uprobe_register(), see the + * comment near uprobe_hash(). + */ if (ret == -EEXIST) { ret = 0; -- GitLab From d436615e60c386095dac4a9bf72b08868d2a7564 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:42 +0200 Subject: [PATCH 1712/6849] uprobes: Copy_insn() shouldn't depend on mm/vma/vaddr 1. copy_insn() doesn't need "addr", it can use uprobe->offset. Remove this argument. 2. Change copy_insn/__copy_insn to accept "struct file*" instead of vma. copy_insn() is called only once and mm/vma/vaddr are random, it shouldn't depend on them. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154342.GA9598@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 2671d9ad49be..08ef566da763 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -591,10 +591,9 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc) } static int -__copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *insn, +__copy_insn(struct address_space *mapping, struct file *filp, char *insn, unsigned long nbytes, unsigned long offset) { - struct file *filp = vma->vm_file; struct page *page; void *vaddr; unsigned long off1; @@ -625,15 +624,13 @@ __copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *ins return 0; } -static int -copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr) +static int copy_insn(struct uprobe *uprobe, struct file *filp) { struct address_space *mapping; unsigned long nbytes; int bytes; - addr &= ~PAGE_MASK; - nbytes = PAGE_SIZE - addr; + nbytes = PAGE_SIZE - (uprobe->offset & ~PAGE_MASK); mapping = uprobe->inode->i_mapping; /* Instruction at end of binary; copy only available bytes */ @@ -644,13 +641,13 @@ copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr) /* Instruction at the page-boundary; copy bytes in second page */ if (nbytes < bytes) { - if (__copy_insn(mapping, vma, uprobe->arch.insn + nbytes, + if (__copy_insn(mapping, filp, uprobe->arch.insn + nbytes, bytes - nbytes, uprobe->offset + nbytes)) return -ENOMEM; bytes = nbytes; } - return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset); + return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset); } /* @@ -696,7 +693,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, addr = (unsigned long)vaddr; if (!(uprobe->flags & UPROBE_COPY_INSN)) { - ret = copy_insn(uprobe, vma, addr); + ret = copy_insn(uprobe, vma->vm_file); if (ret) return ret; -- GitLab From fc36f59565861af2e897225bc3782479a26c5d5a Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:44 +0200 Subject: [PATCH 1713/6849] uprobes: Copy_insn() should not return -ENOMEM if __copy_insn() fails copy_insn() returns -ENOMEM if the first __copy_insn() fails, it should return the correct error code. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154344.GA9601@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 08ef566da763..2db1d94d7dfc 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -641,10 +641,10 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp) /* Instruction at the page-boundary; copy bytes in second page */ if (nbytes < bytes) { - if (__copy_insn(mapping, filp, uprobe->arch.insn + nbytes, - bytes - nbytes, uprobe->offset + nbytes)) - return -ENOMEM; - + int err = __copy_insn(mapping, filp, uprobe->arch.insn + nbytes, + bytes - nbytes, uprobe->offset + nbytes); + if (err) + return err; bytes = nbytes; } return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset); -- GitLab From eb2bf57bee42c7565032f93adaa211e2c9fcc52c Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:47 +0200 Subject: [PATCH 1714/6849] uprobes: No need to re-check vma_address() in write_opcode() write_opcode() is called by register_for_each_vma() and uprobe_mmap() paths. In both cases the caller has already verified this vaddr under mmap_sem, no need to re-check. Note also that this check is wrong anyway, we should not truncate loff_t returned by vma_address() if we do not trust this mapping. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154347.GA9604@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 2db1d94d7dfc..14c71a2aadad 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -211,7 +211,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, struct vm_area_struct *vma; struct uprobe *uprobe; unsigned long pgoff; - loff_t addr; int ret; retry: /* Read the page with vaddr into memory */ @@ -235,10 +234,6 @@ retry: if (mapping != vma->vm_file->f_mapping) goto put_out; - addr = vma_address(vma, uprobe->offset); - if (vaddr != (unsigned long)addr) - goto put_out; - ret = -ENOMEM; new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); if (!new_page) -- GitLab From d9c4a30e82614d43b55893a73f31e7284007ce82 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:50 +0200 Subject: [PATCH 1715/6849] uprobes: Move BUG_ON(UPROBE_SWBP_INSN_SIZE) from write_opcode() to install_breakpoint() write_opcode() ensures that UPROBE_SWBP_INSN doesn't cross the page boundary. This looks a bit confusing, the check does not depend on vaddr and it is enough to do it only once right after install_breakpoint()->arch_uprobe_analyze_insn(). Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154350.GA9611@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 14c71a2aadad..b9c61bda9029 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -210,7 +210,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, void *vaddr_old, *vaddr_new; struct vm_area_struct *vma; struct uprobe *uprobe; - unsigned long pgoff; int ret; retry: /* Read the page with vaddr into memory */ @@ -251,11 +250,7 @@ retry: vaddr_new = kmap_atomic(new_page); memcpy(vaddr_new, vaddr_old, PAGE_SIZE); - - /* poke the new insn in, ASSUMES we don't cross page boundary */ - pgoff = (vaddr & ~PAGE_MASK); - BUG_ON(pgoff + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); - memcpy(vaddr_new + pgoff, &opcode, UPROBE_SWBP_INSN_SIZE); + memcpy(vaddr_new + (vaddr & ~PAGE_MASK), &opcode, UPROBE_SWBP_INSN_SIZE); kunmap_atomic(vaddr_new); kunmap_atomic(vaddr_old); @@ -699,6 +694,10 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, if (ret) return ret; + /* write_opcode() assumes we don't cross page boundary */ + BUG_ON((uprobe->offset & ~PAGE_MASK) + + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); + uprobe->flags |= UPROBE_COPY_INSN; } -- GitLab From 449d0d7c9fb87277175db34c009c70cb348004a8 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:53 +0200 Subject: [PATCH 1716/6849] uprobes: Simplify the usage of uprobe->pending_list uprobe->pending_list is only used to create the temporary list, it has no meaning after we drop uprobes_mmap_hash(inode). No need to initialize this node or remove it from tmp_list, and we can use list_for_each_entry(). Signed-off-by: Oleg Nesterov Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Cc: Srikar Dronamraju Link: http://lkml.kernel.org/r/20120615154353.GA9614@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index b9c61bda9029..7d5c78f063ae 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -513,7 +513,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) uprobe->inode = igrab(inode); uprobe->offset = offset; init_rwsem(&uprobe->consumer_rwsem); - INIT_LIST_HEAD(&uprobe->pending_list); /* add to uprobes_tree, sorted on inode:offset */ cur_uprobe = insert_uprobe(uprobe); @@ -1037,7 +1036,7 @@ static void build_probe_list(struct inode *inode, struct list_head *head) int uprobe_mmap(struct vm_area_struct *vma) { struct list_head tmp_list; - struct uprobe *uprobe, *u; + struct uprobe *uprobe; struct inode *inode; int ret, count; @@ -1055,10 +1054,9 @@ int uprobe_mmap(struct vm_area_struct *vma) ret = 0; count = 0; - list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { + list_for_each_entry(uprobe, &tmp_list, pending_list) { loff_t vaddr; - list_del(&uprobe->pending_list); if (!ret) { vaddr = vma_address(vma, uprobe->offset); @@ -1106,7 +1104,7 @@ int uprobe_mmap(struct vm_area_struct *vma) void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) { struct list_head tmp_list; - struct uprobe *uprobe, *u; + struct uprobe *uprobe; struct inode *inode; if (!atomic_read(&uprobe_events) || !valid_vma(vma, false)) @@ -1123,12 +1121,10 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon mutex_lock(uprobes_mmap_hash(inode)); build_probe_list(inode, &tmp_list); - list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { + list_for_each_entry(uprobe, &tmp_list, pending_list) { loff_t vaddr; - list_del(&uprobe->pending_list); vaddr = vma_address(vma, uprobe->offset); - if (vaddr >= start && vaddr < end) { /* * An unregister could have removed the probe before -- GitLab From 816c03fbabe64fa09f66fbb64e932081af381415 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:55 +0200 Subject: [PATCH 1717/6849] uprobes: Don't use loff_t for the valid virtual address loff_t looks confusing when it is used for the virtual address. Change map_info and install_breakpoint/remove_breakpoint paths to use "unsigned long". The patch doesn't change vma_address(), it can't return "long" because it is used to verify the mapping. But probably this needs some cleanups too. Signed-off-by: Oleg Nesterov Signed-off-by: Anton Arapov Acked-by: Srikar Dronamraju Acked-by: Ananth N Mavinakayanahalli Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154355.GA9622@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 7d5c78f063ae..4df84b76dd48 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -664,9 +664,8 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp) */ static int install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, - struct vm_area_struct *vma, loff_t vaddr) + struct vm_area_struct *vma, unsigned long vaddr) { - unsigned long addr; int ret; /* @@ -679,8 +678,6 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, if (!uprobe->consumers) return -EEXIST; - addr = (unsigned long)vaddr; - if (!(uprobe->flags & UPROBE_COPY_INSN)) { ret = copy_insn(uprobe, vma->vm_file); if (ret) @@ -689,7 +686,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) return -ENOTSUPP; - ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, addr); + ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); if (ret) return ret; @@ -709,7 +706,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, * Hence increment before and decrement on failure. */ atomic_inc(&mm->uprobes_state.count); - ret = set_swbp(&uprobe->arch, mm, addr); + ret = set_swbp(&uprobe->arch, mm, vaddr); if (ret) atomic_dec(&mm->uprobes_state.count); @@ -717,9 +714,9 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, } static void -remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr) +remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr) { - if (!set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true)) + if (!set_orig_insn(&uprobe->arch, mm, vaddr, true)) atomic_dec(&mm->uprobes_state.count); } @@ -743,7 +740,7 @@ static void delete_uprobe(struct uprobe *uprobe) struct map_info { struct map_info *next; struct mm_struct *mm; - loff_t vaddr; + unsigned long vaddr; }; static inline struct map_info *free_map_info(struct map_info *info) @@ -837,7 +834,6 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) while (info) { struct mm_struct *mm = info->mm; struct vm_area_struct *vma; - loff_t vaddr; if (err) goto free; @@ -847,9 +843,8 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) if (!vma || !valid_vma(vma, is_register)) goto unlock; - vaddr = vma_address(vma, uprobe->offset); if (vma->vm_file->f_mapping->host != uprobe->inode || - vaddr != info->vaddr) + vma_address(vma, uprobe->offset) != info->vaddr) goto unlock; if (is_register) { @@ -1055,10 +1050,8 @@ int uprobe_mmap(struct vm_area_struct *vma) count = 0; list_for_each_entry(uprobe, &tmp_list, pending_list) { - loff_t vaddr; - if (!ret) { - vaddr = vma_address(vma, uprobe->offset); + loff_t vaddr = vma_address(vma, uprobe->offset); if (vaddr < vma->vm_start || vaddr >= vma->vm_end) { put_uprobe(uprobe); @@ -1122,9 +1115,8 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon build_probe_list(inode, &tmp_list); list_for_each_entry(uprobe, &tmp_list, pending_list) { - loff_t vaddr; + loff_t vaddr = vma_address(vma, uprobe->offset); - vaddr = vma_address(vma, uprobe->offset); if (vaddr >= start && vaddr < end) { /* * An unregister could have removed the probe before -- GitLab From 593609a59600c8377f311b300f14deacb155b9a4 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:43:59 +0200 Subject: [PATCH 1718/6849] uprobes: __copy_insn() needs "loff_t offset" 1. __copy_insn() needs "loff_t offset", not "unsigned long", to read the file. 2. use pgoff_t for "idx" and remove the unnecessary typecast. 3. fix the typo, "&=" is not what we want 4. can't resist, rename off1 to off. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120615154359.GA9625@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 4df84b76dd48..d1b2eeb80837 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -581,12 +581,12 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc) static int __copy_insn(struct address_space *mapping, struct file *filp, char *insn, - unsigned long nbytes, unsigned long offset) + unsigned long nbytes, loff_t offset) { struct page *page; void *vaddr; - unsigned long off1; - unsigned long idx; + unsigned long off; + pgoff_t idx; if (!filp) return -EINVAL; @@ -594,8 +594,8 @@ __copy_insn(struct address_space *mapping, struct file *filp, char *insn, if (!mapping->a_ops->readpage) return -EIO; - idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT); - off1 = offset &= ~PAGE_MASK; + idx = offset >> PAGE_CACHE_SHIFT; + off = offset & ~PAGE_MASK; /* * Ensure that the page that has the original instruction is @@ -606,7 +606,7 @@ __copy_insn(struct address_space *mapping, struct file *filp, char *insn, return PTR_ERR(page); vaddr = kmap_atomic(page); - memcpy(insn, vaddr + off1, nbytes); + memcpy(insn, vaddr + off, nbytes); kunmap_atomic(vaddr); page_cache_release(page); -- GitLab From e227051b13956b8f71c0abecc41ad351e64671c8 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 15 Jun 2012 17:44:01 +0200 Subject: [PATCH 1719/6849] uprobes: Remove the unnecessary initialization in add_utask() Trivial cleanup. No need to nullify ->active_uprobe after kzalloc(). Signed-off-by: Oleg Nesterov Cc: Ananth N Mavinakayanahalli Cc: Anton Arapov Cc: Peter Zijlstra Cc: Srikar Dronamraju Link: http://lkml.kernel.org/r/20120615154401.GA9633@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index d1b2eeb80837..f93532748bca 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1392,7 +1392,6 @@ static struct uprobe_task *add_utask(void) if (unlikely(!utask)) return NULL; - utask->active_uprobe = NULL; current->utask = utask; return utask; } -- GitLab From e8803b6c387129059e04d9e14d49efda250a7361 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 16 Jun 2012 01:12:19 -0700 Subject: [PATCH 1720/6849] Revert "ipv6: Prevent access to uninitialized fib_table_hash via /proc/net/ipv6_route" This reverts commit 2a0c451ade8e1783c5d453948289e4a978d417c9. It causes crashes, because now ip6_null_entry is used before it is initialized. Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 2 -- net/ipv6/ip6_fib.c | 18 +++++++----------- net/ipv6/route.c | 16 +++++----------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 209af13b0336..0ae759a6c76e 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -271,8 +271,6 @@ extern void fib6_run_gc(unsigned long expires, extern void fib6_gc_cleanup(void); extern int fib6_init(void); -extern int fib6_init_late(void); -extern void fib6_cleanup_late(void); #ifdef CONFIG_IPV6_MULTIPLE_TABLES extern int fib6_rules_init(void); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index fbd4afff05fa..74c21b924a79 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1692,25 +1692,21 @@ int __init fib6_init(void) ret = register_pernet_subsys(&fib6_net_ops); if (ret) goto out_kmem_cache_create; + + ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib, + NULL); + if (ret) + goto out_unregister_subsys; out: return ret; +out_unregister_subsys: + unregister_pernet_subsys(&fib6_net_ops); out_kmem_cache_create: kmem_cache_destroy(fib6_node_kmem); goto out; } -int __init fib6_init_late(void) -{ - return __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib, - NULL); -} - -void fib6_cleanup_late(void) -{ - rtnl_unregister(PF_INET6, RTM_GETROUTE); -} - void fib6_gc_cleanup(void) { unregister_pernet_subsys(&fib6_net_ops); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index dc60bf585966..999a982ad3fd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -3018,13 +3018,9 @@ int __init ip6_route_init(void) if (ret) goto out_kmem_cache; - ret = fib6_init(); - if (ret) - goto out_dst_entries; - ret = register_pernet_subsys(&ip6_route_net_ops); if (ret) - goto out_fib6_init; + goto out_dst_entries; ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; @@ -3039,13 +3035,13 @@ int __init ip6_route_init(void) init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); #endif - ret = fib6_init_late(); + ret = fib6_init(); if (ret) goto out_register_subsys; ret = xfrm6_init(); if (ret) - goto out_fib6_init_late; + goto out_fib6_init; ret = fib6_rules_init(); if (ret) @@ -3068,12 +3064,10 @@ fib6_rules_init: fib6_rules_cleanup(); xfrm6_init: xfrm6_fini(); -out_fib6_init_late: - fib6_cleanup_late(); -out_register_subsys: - unregister_pernet_subsys(&ip6_route_net_ops); out_fib6_init: fib6_gc_cleanup(); +out_register_subsys: + unregister_pernet_subsys(&ip6_route_net_ops); out_dst_entries: dst_entries_destroy(&ip6_dst_blackhole_ops); out_kmem_cache: -- GitLab From e5a867a51d9b009f90d5dca6a320608e4e8a37ec Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 16 Jun 2012 07:41:28 +0100 Subject: [PATCH 1721/6849] drm/udl: only bind to the video devices on the hub. This is ported from udlfb. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=832188 Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_drv.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 4d02c46a9420..6e52069894b3 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -13,8 +13,21 @@ static struct drm_driver driver; +/* + * There are many DisplayLink-based graphics products, all with unique PIDs. + * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) + * We also require a match on SubClass (0x00) and Protocol (0x00), + * which is compatible with all known USB 2.0 era graphics chips and firmware, + * but allows DisplayLink to increment those for any future incompatible chips + */ static struct usb_device_id id_table[] = { - {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, + {.idVendor = 0x17e9, .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS | + USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, {}, }; MODULE_DEVICE_TABLE(usb, id_table); -- GitLab From f8fee8f5acb5c3f82e02f2ae139a6f1e7b4eb583 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 15 Jun 2012 12:46:17 -0700 Subject: [PATCH 1722/6849] vga_switcheroo.h: fix pci_dev warning Fix warnings on some architectures/configs (not on x86): include/linux/vga_switcheroo.h:28:30: warning: 'struct pci_dev' declared inside parameter list [enabled by default] include/linux/vga_switcheroo.h:28:30: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] Signed-off-by: Randy Dunlap Cc: Takashi Iwai Reported-by: Geert Uytterhoeven Signed-off-by: Dave Airlie --- include/linux/vga_switcheroo.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index 60da41fe9dc2..d844b7790ea6 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -9,6 +9,8 @@ #include +struct pci_dev; + enum vga_switcheroo_state { VGA_SWITCHEROO_OFF, VGA_SWITCHEROO_ON, -- GitLab From 0ec0612a80f957000999c3f7b31a84e3558c719d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 15:54:57 -0400 Subject: [PATCH 1723/6849] drm/radeon: fix regression in dynpm due to multi-ring rework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not all asics have all rings, so make sure the ring is ready before attempting to check it in the dynpm work handler. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=43367 Signed-off-by: Alex Deucher Reviewed-by: Jerome Glisse Reviewed-by: Christian König Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_pm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 08825548ee69..5b37e283ec38 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -801,9 +801,13 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) int i; for (i = 0; i < RADEON_NUM_RINGS; ++i) { - not_processed += radeon_fence_count_emitted(rdev, i); - if (not_processed >= 3) - break; + struct radeon_ring *ring = &rdev->ring[i]; + + if (ring->ready) { + not_processed += radeon_fence_count_emitted(rdev, i); + if (not_processed >= 3) + break; + } } if (not_processed >= 3) { /* should upclock */ -- GitLab From 489797d510dfbce15120492d7ef6f956928b99f2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 12 Jun 2012 16:10:39 +0100 Subject: [PATCH 1724/6849] drm/radeon/prime: reserve/unreserve around pin I finally got to test this code a bit more and hit the ttm no reserved assert, so add the reservations around the pinning. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_prime.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index 8ddab4c76710..6bef46ace831 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -169,11 +169,17 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct radeon_bo *bo = gem_to_radeon_bo(obj); int ret = 0; + ret = radeon_bo_reserve(bo, false); + if (unlikely(ret != 0)) + return ERR_PTR(ret); + /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (ret) + if (ret) { + radeon_bo_unreserve(bo); return ERR_PTR(ret); - + } + radeon_bo_unreserve(bo); return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags); } -- GitLab From ce020ea53264f1460ae619cfc12f968dbd0b8974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jun 2012 23:39:55 +0200 Subject: [PATCH 1725/6849] drm via: initialize object_idr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The field obejct_idr of struct drm_via_private was introduced with the commit http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=77ee8f3825054f23b17e9c8f728f061defd86cdc . In that patch idr_init(&dev->object_name_idr) was called instead of idr_init(&dev_priv->object_idr) by mistake, leaving the dev_priv->object_idr uninitialized. To be more exact, the object_idr buffer is filled with zeros because of kzalloc(), but the dev_priv->object_idr.lock spinlock can cause system freeze at lib/idr.c:move_to_free_list() when spin_lock_irqsave() is called on this spinlock. The patch was tested on Clevo D4J, model D410J laptop, on the following hardware, without AGP kernel module loaded: # lspci -s 01:00.0 -n 01:00.0 0300: 1106:3108 (rev 01) # lspci -s 01:00.0 -v 01:00.0 VGA compatible controller: VIA Technologies, Inc. K8M800/K8N800/K8N800A [S3 UniChrome Pro] (rev 01) (prog-if 00 [VGA controller]) Subsystem: CLEVO/KAPOK Computer Device 4702 Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 16 Memory at f0000000 (32-bit, prefetchable) [size=64M] Memory at d1000000 (32-bit, non-prefetchable) [size=16M] Expansion ROM at [disabled] Capabilities: [60] Power Management version 2 Capabilities: [70] AGP version 3.0 Signed-off-by: Márton Németh Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/via/via_map.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 1f182254e81e..c126182ac07e 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c @@ -100,12 +100,11 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; + idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; - idr_init(&dev->object_name_idr); - pci_set_master(dev->pdev); ret = drm_vblank_init(dev, 1); -- GitLab From 648ccc7d35e3416fdc739d2e520e85de3125361b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Mon, 11 Jun 2012 19:09:25 +0200 Subject: [PATCH 1726/6849] drm sis: initialize object_idr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filed object_idr of struct drm_sis_private was introduced with commit http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=6de8a748881f1cd9d795454da2b6db616d5ca3d7 . The idr_init(&dev->object_name_idr) is called instead of idr_init(&dev_priv->object_idr) by mistake, leaving object_idr uninitialized. Correct this. This patch was not tested because of lack of hardware. Signed-off-by: Márton Németh Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/sis/sis_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 30d98d14b5c5..dd14cd1a0033 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -47,9 +47,9 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; + idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; - idr_init(&dev->object_name_idr); return 0; } -- GitLab From 6b53a0507b6e728c53f2fc60912a8511f151e5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 11 Jun 2012 12:34:01 +0200 Subject: [PATCH 1727/6849] drm/radeon: enable HDMI on DCE5 (AKA NI excluding Aruba) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After recent changes HDMI code is ready to be enabled on DCE5. This patch just changes conditions to execute already present code on DCE5. Signed-off-by: Rafał Miłecki Reviewed-by: Alex Deucher Tested-by: Christian König Tested-by: Andre Heider Tested-by: Zoltán Böszörményi Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_encoders.c | 4 +++- drivers/gpu/drm/radeon/evergreen_hdmi.c | 3 --- drivers/gpu/drm/radeon/ni.c | 5 +++++ drivers/gpu/drm/radeon/r600_audio.c | 2 +- drivers/gpu/drm/radeon/r600_hdmi.c | 7 ++----- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index e7b1ec5ae8c6..486ccdf4aacd 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1926,7 +1926,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { r600_hdmi_enable(encoder); - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE6(rdev)) + ; /* TODO (use pointers instead of if-s?) */ + else if (ASIC_IS_DCE4(rdev)) evergreen_hdmi_setmode(encoder, adjusted_mode); else r600_hdmi_setmode(encoder, adjusted_mode); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index a51f880985f8..65c54160028b 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -156,9 +156,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3186522a4458..b7bf18e40215 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1303,6 +1303,10 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) + return r; + return 0; } @@ -1329,6 +1333,7 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 7479a5c503e4..79b55916cf90 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -57,7 +57,7 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder) */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) + return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev)) || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 969c27529dfe..82a0a4c919c0 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -322,9 +322,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; @@ -483,7 +480,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) uint32_t offset; u32 hdmi; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Silent, r600_hdmi_enable will raise WARN for us */ @@ -543,7 +540,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Called for ATOM_ENCODER_MODE_HDMI only */ -- GitLab From 3a8fc53a45c444400259e2e285ba414a87061e3d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 15 Jan 2012 16:34:08 +0100 Subject: [PATCH 1728/6849] netfilter: nf_ct_helper: allocate 16 bytes for the helper and policy names This patch modifies the struct nf_conntrack_helper to allocate the room for the helper name. The maximum length is 16 bytes (this was already introduced in 2.6.24). For the maximum length for expectation policy names, I have also selected 16 bytes. This patch is required by the follow-up patch to support user-space connection tracking helpers. Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_expect.h | 4 +++- include/net/netfilter/nf_conntrack_helper.h | 2 +- net/netfilter/nf_conntrack_ftp.c | 8 ++------ net/netfilter/nf_conntrack_irc.c | 8 ++------ net/netfilter/nf_conntrack_sane.c | 8 ++------ net/netfilter/nf_conntrack_sip.c | 7 ++----- net/netfilter/nf_conntrack_tftp.c | 8 ++------ 7 files changed, 14 insertions(+), 31 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 4619caadd9d1..983f00263243 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -59,10 +59,12 @@ static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp) return nf_ct_net(exp->master); } +#define NF_CT_EXP_POLICY_NAME_LEN 16 + struct nf_conntrack_expect_policy { unsigned int max_expected; unsigned int timeout; - const char *name; + char name[NF_CT_EXP_POLICY_NAME_LEN]; }; #define NF_CT_EXPECT_CLASS_DEFAULT 0 diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 1d1889409b9e..5f5a4d9d4df5 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -19,7 +19,7 @@ struct module; struct nf_conntrack_helper { struct hlist_node hnode; /* Internal use. */ - const char *name; /* name of the module */ + char name[NF_CT_HELPER_NAME_LEN]; /* name of the module */ struct module *me; /* pointer to self */ const struct nf_conntrack_expect_policy *expect_policy; diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 8c5c95c6d34f..44e47c9e14fb 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -512,7 +512,6 @@ out_update_nl: } static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly; -static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly; static const struct nf_conntrack_expect_policy ftp_exp_policy = { .max_expected = 1, @@ -541,7 +540,6 @@ static void nf_conntrack_ftp_fini(void) static int __init nf_conntrack_ftp_init(void) { int i, j = -1, ret = 0; - char *tmpname; ftp_buffer = kmalloc(65536, GFP_KERNEL); if (!ftp_buffer) @@ -561,12 +559,10 @@ static int __init nf_conntrack_ftp_init(void) ftp[i][j].expect_policy = &ftp_exp_policy; ftp[i][j].me = THIS_MODULE; ftp[i][j].help = help; - tmpname = &ftp_names[i][j][0]; if (ports[i] == FTP_PORT) - sprintf(tmpname, "ftp"); + sprintf(ftp[i][j].name, "ftp"); else - sprintf(tmpname, "ftp-%d", ports[i]); - ftp[i][j].name = tmpname; + sprintf(ftp[i][j].name, "ftp-%d", ports[i]); pr_debug("nf_ct_ftp: registering helper for pf: %d " "port: %d\n", diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 81366c118271..009c52cfd1ec 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c @@ -221,7 +221,6 @@ static int help(struct sk_buff *skb, unsigned int protoff, } static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly; -static char irc_names[MAX_PORTS][sizeof("irc-65535")] __read_mostly; static struct nf_conntrack_expect_policy irc_exp_policy; static void nf_conntrack_irc_fini(void); @@ -229,7 +228,6 @@ static void nf_conntrack_irc_fini(void); static int __init nf_conntrack_irc_init(void) { int i, ret; - char *tmpname; if (max_dcc_channels < 1) { printk(KERN_ERR "nf_ct_irc: max_dcc_channels must not be zero\n"); @@ -255,12 +253,10 @@ static int __init nf_conntrack_irc_init(void) irc[i].me = THIS_MODULE; irc[i].help = help; - tmpname = &irc_names[i][0]; if (ports[i] == IRC_PORT) - sprintf(tmpname, "irc"); + sprintf(irc[i].name, "irc"); else - sprintf(tmpname, "irc-%u", i); - irc[i].name = tmpname; + sprintf(irc[i].name, "irc-%u", i); ret = nf_conntrack_helper_register(&irc[i]); if (ret) { diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index 8501823b3f9b..ec3fc18c4ef6 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c @@ -163,7 +163,6 @@ out: } static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly; -static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly; static const struct nf_conntrack_expect_policy sane_exp_policy = { .max_expected = 1, @@ -190,7 +189,6 @@ static void nf_conntrack_sane_fini(void) static int __init nf_conntrack_sane_init(void) { int i, j = -1, ret = 0; - char *tmpname; sane_buffer = kmalloc(65536, GFP_KERNEL); if (!sane_buffer) @@ -210,12 +208,10 @@ static int __init nf_conntrack_sane_init(void) sane[i][j].expect_policy = &sane_exp_policy; sane[i][j].me = THIS_MODULE; sane[i][j].help = help; - tmpname = &sane_names[i][j][0]; if (ports[i] == SANE_PORT) - sprintf(tmpname, "sane"); + sprintf(sane[i][j].name, "sane"); else - sprintf(tmpname, "sane-%d", ports[i]); - sane[i][j].name = tmpname; + sprintf(sane[i][j].name, "sane-%d", ports[i]); pr_debug("nf_ct_sane: registering helper for pf: %d " "port: %d\n", diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 93faf6a3a637..dfd3ff382243 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -1556,7 +1556,6 @@ static void nf_conntrack_sip_fini(void) static int __init nf_conntrack_sip_init(void) { int i, j, ret; - char *tmpname; if (ports_c == 0) ports[ports_c++] = SIP_PORT; @@ -1584,12 +1583,10 @@ static int __init nf_conntrack_sip_init(void) sip[i][j].expect_class_max = SIP_EXPECT_MAX; sip[i][j].me = THIS_MODULE; - tmpname = &sip_names[i][j][0]; if (ports[i] == SIP_PORT) - sprintf(tmpname, "sip"); + sprintf(sip_names[i][j], "sip"); else - sprintf(tmpname, "sip-%u", i); - sip[i][j].name = tmpname; + sprintf(sip_names[i][j], "sip-%u", i); pr_debug("port #%u: %u\n", i, ports[i]); diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c index 75466fd72f4f..81fc61c05263 100644 --- a/net/netfilter/nf_conntrack_tftp.c +++ b/net/netfilter/nf_conntrack_tftp.c @@ -92,7 +92,6 @@ static int tftp_help(struct sk_buff *skb, } static struct nf_conntrack_helper tftp[MAX_PORTS][2] __read_mostly; -static char tftp_names[MAX_PORTS][2][sizeof("tftp-65535")] __read_mostly; static const struct nf_conntrack_expect_policy tftp_exp_policy = { .max_expected = 1, @@ -112,7 +111,6 @@ static void nf_conntrack_tftp_fini(void) static int __init nf_conntrack_tftp_init(void) { int i, j, ret; - char *tmpname; if (ports_c == 0) ports[ports_c++] = TFTP_PORT; @@ -129,12 +127,10 @@ static int __init nf_conntrack_tftp_init(void) tftp[i][j].me = THIS_MODULE; tftp[i][j].help = tftp_help; - tmpname = &tftp_names[i][j][0]; if (ports[i] == TFTP_PORT) - sprintf(tmpname, "tftp"); + sprintf(tftp[i][j].name, "tftp"); else - sprintf(tmpname, "tftp-%u", i); - tftp[i][j].name = tmpname; + sprintf(tftp[i][j].name, "tftp-%u", i); ret = nf_conntrack_helper_register(&tftp[i][j]); if (ret) { -- GitLab From 3cf4c7e381d9a98a44fd86207b950bd8fef55d20 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 1 Feb 2012 16:18:31 +0100 Subject: [PATCH 1729/6849] netfilter: nf_ct_ext: support variable length extensions We can now define conntrack extensions of variable size. This patch is useful to get rid of these unions: union nf_conntrack_help union nf_conntrack_proto union nf_conntrack_nat_help Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_extend.h | 9 ++++++--- net/netfilter/nf_conntrack_extend.c | 16 +++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 96755c3798a5..8b4d1fc29096 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -80,10 +80,13 @@ static inline void nf_ct_ext_free(struct nf_conn *ct) } /* Add this type, returns pointer to data or NULL. */ -void * -__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp); +void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, + size_t var_alloc_len, gfp_t gfp); + #define nf_ct_ext_add(ct, id, gfp) \ - ((id##_TYPE *)__nf_ct_ext_add((ct), (id), (gfp))) + ((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), 0, (gfp))) +#define nf_ct_ext_add_length(ct, id, len, gfp) \ + ((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), (len), (gfp))) #define NF_CT_EXT_F_PREALLOC 0x0001 diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 641ff5f96718..1a9545965c0d 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -44,7 +44,8 @@ void __nf_ct_ext_destroy(struct nf_conn *ct) EXPORT_SYMBOL(__nf_ct_ext_destroy); static void * -nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) +nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, + size_t var_alloc_len, gfp_t gfp) { unsigned int off, len; struct nf_ct_ext_type *t; @@ -54,8 +55,8 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) t = rcu_dereference(nf_ct_ext_types[id]); BUG_ON(t == NULL); off = ALIGN(sizeof(struct nf_ct_ext), t->align); - len = off + t->len; - alloc_size = t->alloc_size; + len = off + t->len + var_alloc_len; + alloc_size = t->alloc_size + var_alloc_len; rcu_read_unlock(); *ext = kzalloc(alloc_size, gfp); @@ -68,7 +69,8 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) return (void *)(*ext) + off; } -void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) +void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, + size_t var_alloc_len, gfp_t gfp) { struct nf_ct_ext *old, *new; int i, newlen, newoff; @@ -79,7 +81,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) old = ct->ext; if (!old) - return nf_ct_ext_create(&ct->ext, id, gfp); + return nf_ct_ext_create(&ct->ext, id, var_alloc_len, gfp); if (__nf_ct_ext_exist(old, id)) return NULL; @@ -89,7 +91,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) BUG_ON(t == NULL); newoff = ALIGN(old->len, t->align); - newlen = newoff + t->len; + newlen = newoff + t->len + var_alloc_len; rcu_read_unlock(); new = __krealloc(old, newlen, gfp); @@ -117,7 +119,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) memset((void *)new + newoff, 0, newlen - newoff); return (void *)new + newoff; } -EXPORT_SYMBOL(__nf_ct_ext_add); +EXPORT_SYMBOL(__nf_ct_ext_add_length); static void update_alloc_size(struct nf_ct_ext_type *type) { -- GitLab From 1afc56794e03229fa53cfa3c5012704d226e1dec Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 7 Jun 2012 12:11:50 +0200 Subject: [PATCH 1730/6849] netfilter: nf_ct_helper: implement variable length helper private data This patch uses the new variable length conntrack extensions. Instead of using union nf_conntrack_help that contain all the helper private data information, we allocate variable length area to store the private helper data. This patch includes the modification of all existing helpers. It also includes a couple of include header to avoid compilation warnings. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/nf_conntrack_sip.h | 2 + include/net/netfilter/nf_conntrack.h | 35 ++-------------- include/net/netfilter/nf_conntrack_helper.h | 15 ++++++- net/ipv4/netfilter/nf_nat_amanda.c | 4 +- net/ipv4/netfilter/nf_nat_h323.c | 8 ++-- net/ipv4/netfilter/nf_nat_pptp.c | 6 +-- net/ipv4/netfilter/nf_nat_tftp.c | 4 +- net/netfilter/nf_conntrack_core.c | 3 +- net/netfilter/nf_conntrack_ftp.c | 3 +- net/netfilter/nf_conntrack_h323_main.c | 16 +++++--- net/netfilter/nf_conntrack_helper.c | 11 ++++-- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_pptp.c | 17 ++++---- net/netfilter/nf_conntrack_proto_gre.c | 16 ++++---- net/netfilter/nf_conntrack_sane.c | 4 +- net/netfilter/nf_conntrack_sip.c | 25 ++++++------ net/netfilter/xt_CT.c | 44 ++++++++++++--------- 17 files changed, 111 insertions(+), 106 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index 0ce91d56a5f2..0dfc8b7210a3 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h @@ -2,6 +2,8 @@ #define __NF_CONNTRACK_SIP_H__ #ifdef __KERNEL__ +#include + #define SIP_PORT 5060 #define SIP_TIMEOUT 3600 diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index cce7f6a798bf..f1494feba79f 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -39,36 +39,6 @@ union nf_conntrack_expect_proto { /* insert expect proto private data here */ }; -/* Add protocol helper include file here */ -#include -#include -#include -#include -#include - -/* per conntrack: application helper private data */ -union nf_conntrack_help { - /* insert conntrack helper private data (master) here */ -#if defined(CONFIG_NF_CONNTRACK_FTP) || defined(CONFIG_NF_CONNTRACK_FTP_MODULE) - struct nf_ct_ftp_master ct_ftp_info; -#endif -#if defined(CONFIG_NF_CONNTRACK_PPTP) || \ - defined(CONFIG_NF_CONNTRACK_PPTP_MODULE) - struct nf_ct_pptp_master ct_pptp_info; -#endif -#if defined(CONFIG_NF_CONNTRACK_H323) || \ - defined(CONFIG_NF_CONNTRACK_H323_MODULE) - struct nf_ct_h323_master ct_h323_info; -#endif -#if defined(CONFIG_NF_CONNTRACK_SANE) || \ - defined(CONFIG_NF_CONNTRACK_SANE_MODULE) - struct nf_ct_sane_master ct_sane_info; -#endif -#if defined(CONFIG_NF_CONNTRACK_SIP) || defined(CONFIG_NF_CONNTRACK_SIP_MODULE) - struct nf_ct_sip_master ct_sip_info; -#endif -}; - #include #include #include @@ -89,12 +59,13 @@ struct nf_conn_help { /* Helper. if any */ struct nf_conntrack_helper __rcu *helper; - union nf_conntrack_help help; - struct hlist_head expectations; /* Current number of expected connections */ u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; + + /* private helper information. */ + char data[]; }; #include diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 5f5a4d9d4df5..061352f71a84 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -11,6 +11,7 @@ #define _NF_CONNTRACK_HELPER_H #include #include +#include struct module; @@ -23,6 +24,9 @@ struct nf_conntrack_helper { struct module *me; /* pointer to self */ const struct nf_conntrack_expect_policy *expect_policy; + /* length of internal data, ie. sizeof(struct nf_ct_*_master) */ + size_t data_len; + /* Tuple of things we will help (compared against server response) */ struct nf_conntrack_tuple tuple; @@ -48,7 +52,7 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum); extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); -extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp); +extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, struct nf_conntrack_helper *helper, gfp_t gfp); extern int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, gfp_t flags); @@ -60,6 +64,15 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) return nf_ct_ext_find(ct, NF_CT_EXT_HELPER); } +static inline void *nfct_help_data(const struct nf_conn *ct) +{ + struct nf_conn_help *help; + + help = nf_ct_ext_find(ct, NF_CT_EXT_HELPER); + + return (void *)help->data; +} + extern int nf_conntrack_helper_init(struct net *net); extern void nf_conntrack_helper_fini(struct net *net); diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c index 7b22382ff0e9..3c04d24e2976 100644 --- a/net/ipv4/netfilter/nf_nat_amanda.c +++ b/net/ipv4/netfilter/nf_nat_amanda.c @@ -13,10 +13,10 @@ #include #include -#include -#include #include #include +#include +#include #include MODULE_AUTHOR("Brian J. Murrell "); diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index cad29c121318..c6784a18c1c4 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -95,7 +95,7 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct, unsigned char **data, TransportAddress *taddr, int count) { - const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + const struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); int i; __be16 port; @@ -178,7 +178,7 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, struct nf_conntrack_expect *rtp_exp, struct nf_conntrack_expect *rtcp_exp) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); int i; u_int16_t nated_port; @@ -330,7 +330,7 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, TransportAddress *taddr, __be16 port, struct nf_conntrack_expect *exp) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); u_int16_t nated_port = ntohs(port); @@ -419,7 +419,7 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, unsigned char **data, TransportAddress *taddr, int idx, __be16 port, struct nf_conntrack_expect *exp) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); u_int16_t nated_port = ntohs(port); union nf_inet_addr addr; diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index c273d58980ae..388140881ebe 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c @@ -49,7 +49,7 @@ static void pptp_nat_expected(struct nf_conn *ct, const struct nf_nat_pptp *nat_pptp_info; struct nf_nat_ipv4_range range; - ct_pptp_info = &nfct_help(master)->help.ct_pptp_info; + ct_pptp_info = nfct_help_data(master); nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info; /* And here goes the grand finale of corrosion... */ @@ -123,7 +123,7 @@ pptp_outbound_pkt(struct sk_buff *skb, __be16 new_callid; unsigned int cid_off; - ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info; + ct_pptp_info = nfct_help_data(ct); nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; new_callid = ct_pptp_info->pns_call_id; @@ -192,7 +192,7 @@ pptp_exp_gre(struct nf_conntrack_expect *expect_orig, struct nf_ct_pptp_master *ct_pptp_info; struct nf_nat_pptp *nat_pptp_info; - ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info; + ct_pptp_info = nfct_help_data(ct); nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; /* save original PAC call ID in nat_info */ diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c index a2901bf829c0..9dbb8d284f99 100644 --- a/net/ipv4/netfilter/nf_nat_tftp.c +++ b/net/ipv4/netfilter/nf_nat_tftp.c @@ -8,10 +8,10 @@ #include #include -#include -#include #include #include +#include +#include #include MODULE_AUTHOR("Magnus Boden "); diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 1ee2082b81b5..cf4875565d67 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -819,7 +819,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, __set_bit(IPS_EXPECTED_BIT, &ct->status); ct->master = exp->master; if (exp->helper) { - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); + help = nf_ct_helper_ext_add(ct, exp->helper, + GFP_ATOMIC); if (help) rcu_assign_pointer(help->helper, exp->helper); } diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 44e47c9e14fb..4bb771d1f57a 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -358,7 +358,7 @@ static int help(struct sk_buff *skb, u32 seq; int dir = CTINFO2DIR(ctinfo); unsigned int uninitialized_var(matchlen), uninitialized_var(matchoff); - struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info; + struct nf_ct_ftp_master *ct_ftp_info = nfct_help_data(ct); struct nf_conntrack_expect *exp; union nf_inet_addr *daddr; struct nf_conntrack_man cmd = {}; @@ -554,6 +554,7 @@ static int __init nf_conntrack_ftp_init(void) ftp[i][0].tuple.src.l3num = PF_INET; ftp[i][1].tuple.src.l3num = PF_INET6; for (j = 0; j < 2; j++) { + ftp[i][j].data_len = sizeof(struct nf_ct_ftp_master); ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; ftp[i][j].expect_policy = &ftp_exp_policy; diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 46d69d7f1bb4..ed2199280527 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -114,7 +114,7 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int *datalen, int *dataoff) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); const struct tcphdr *th; struct tcphdr _tcph; @@ -618,6 +618,7 @@ static const struct nf_conntrack_expect_policy h245_exp_policy = { static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { .name = "H.245", .me = THIS_MODULE, + .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_UNSPEC, .tuple.dst.protonum = IPPROTO_UDP, .help = h245_help, @@ -1170,6 +1171,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { { .name = "Q.931", .me = THIS_MODULE, + .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET, .tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT), .tuple.dst.protonum = IPPROTO_TCP, @@ -1245,7 +1247,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct, unsigned char **data, TransportAddress *taddr, int count) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); int ret = 0; int i; @@ -1360,7 +1362,7 @@ static int process_rrq(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, RegistrationRequest *rrq) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int ret; typeof(set_ras_addr_hook) set_ras_addr; @@ -1395,7 +1397,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, RegistrationConfirm *rcf) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); int ret; struct nf_conntrack_expect *exp; @@ -1444,7 +1446,7 @@ static int process_urq(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, UnregistrationRequest *urq) { - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); int ret; typeof(set_sig_addr_hook) set_sig_addr; @@ -1476,7 +1478,7 @@ static int process_arq(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, AdmissionRequest *arq) { - const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; + const struct nf_ct_h323_master *info = nfct_help_data(ct); int dir = CTINFO2DIR(ctinfo); __be16 port; union nf_inet_addr addr; @@ -1743,6 +1745,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { { .name = "RAS", .me = THIS_MODULE, + .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET, .tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), .tuple.dst.protonum = IPPROTO_UDP, @@ -1752,6 +1755,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { { .name = "RAS", .me = THIS_MODULE, + .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET6, .tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), .tuple.dst.protonum = IPPROTO_UDP, diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 4fa2ff961f5a..9c18ecb0ab81 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -161,11 +161,14 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum) } EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get); -struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) +struct nf_conn_help * +nf_ct_helper_ext_add(struct nf_conn *ct, + struct nf_conntrack_helper *helper, gfp_t gfp) { struct nf_conn_help *help; - help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp); + help = nf_ct_ext_add_length(ct, NF_CT_EXT_HELPER, + helper->data_len, gfp); if (help) INIT_HLIST_HEAD(&help->expectations); else @@ -218,13 +221,13 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, } if (help == NULL) { - help = nf_ct_helper_ext_add(ct, flags); + help = nf_ct_helper_ext_add(ct, helper, flags); if (help == NULL) { ret = -ENOMEM; goto out; } } else { - memset(&help->help, 0, sizeof(help->help)); + memset(help->data, 0, helper->data_len); } rcu_assign_pointer(help->helper, helper); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6f4b00a8fc73..a08892048b46 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1218,7 +1218,7 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) if (help->helper) return -EBUSY; /* need to zero data of old helper */ - memset(&help->help, 0, sizeof(help->help)); + memset(help->data, 0, help->helper->data_len); } else { /* we cannot set a helper for an existing conntrack */ return -EOPNOTSUPP; @@ -1440,7 +1440,7 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, } else { struct nf_conn_help *help; - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); + help = nf_ct_helper_ext_add(ct, helper, GFP_ATOMIC); if (help == NULL) { err = -ENOMEM; goto err2; diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 31d56b23b9e9..6fed9ec35248 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -174,7 +174,7 @@ static int destroy_sibling_or_exp(struct net *net, struct nf_conn *ct, static void pptp_destroy_siblings(struct nf_conn *ct) { struct net *net = nf_ct_net(ct); - const struct nf_conn_help *help = nfct_help(ct); + const struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); struct nf_conntrack_tuple t; nf_ct_gre_keymap_destroy(ct); @@ -182,16 +182,16 @@ static void pptp_destroy_siblings(struct nf_conn *ct) /* try original (pns->pac) tuple */ memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t)); t.dst.protonum = IPPROTO_GRE; - t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id; - t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id; + t.src.u.gre.key = ct_pptp_info->pns_call_id; + t.dst.u.gre.key = ct_pptp_info->pac_call_id; if (!destroy_sibling_or_exp(net, ct, &t)) pr_debug("failed to timeout original pns->pac ct/exp\n"); /* try reply (pac->pns) tuple */ memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t)); t.dst.protonum = IPPROTO_GRE; - t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id; - t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id; + t.src.u.gre.key = ct_pptp_info->pac_call_id; + t.dst.u.gre.key = ct_pptp_info->pns_call_id; if (!destroy_sibling_or_exp(net, ct, &t)) pr_debug("failed to timeout reply pac->pns ct/exp\n"); } @@ -269,7 +269,7 @@ pptp_inbound_pkt(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo) { - struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info; + struct nf_ct_pptp_master *info = nfct_help_data(ct); u_int16_t msg; __be16 cid = 0, pcid = 0; typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound; @@ -396,7 +396,7 @@ pptp_outbound_pkt(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo) { - struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info; + struct nf_ct_pptp_master *info = nfct_help_data(ct); u_int16_t msg; __be16 cid = 0, pcid = 0; typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound; @@ -506,7 +506,7 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff, { int dir = CTINFO2DIR(ctinfo); - const struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info; + const struct nf_ct_pptp_master *info = nfct_help_data(ct); const struct tcphdr *tcph; struct tcphdr _tcph; const struct pptp_pkt_hdr *pptph; @@ -592,6 +592,7 @@ static const struct nf_conntrack_expect_policy pptp_exp_policy = { static struct nf_conntrack_helper pptp __read_mostly = { .name = "pptp", .me = THIS_MODULE, + .data_len = sizeof(struct nf_ct_pptp_master), .tuple.src.l3num = AF_INET, .tuple.src.u.tcp.port = cpu_to_be16(PPTP_CONTROL_PORT), .tuple.dst.protonum = IPPROTO_TCP, diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 25ba5a2f5edc..5cac41c2fa09 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -117,10 +117,10 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, { struct net *net = nf_ct_net(ct); struct netns_proto_gre *net_gre = gre_pernet(net); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); struct nf_ct_gre_keymap **kmp, *km; - kmp = &help->help.ct_pptp_info.keymap[dir]; + kmp = &ct_pptp_info->keymap[dir]; if (*kmp) { /* check whether it's a retransmission */ read_lock_bh(&net_gre->keymap_lock); @@ -158,19 +158,19 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct) { struct net *net = nf_ct_net(ct); struct netns_proto_gre *net_gre = gre_pernet(net); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); enum ip_conntrack_dir dir; pr_debug("entering for ct %p\n", ct); write_lock_bh(&net_gre->keymap_lock); for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { - if (help->help.ct_pptp_info.keymap[dir]) { + if (ct_pptp_info->keymap[dir]) { pr_debug("removing %p from list\n", - help->help.ct_pptp_info.keymap[dir]); - list_del(&help->help.ct_pptp_info.keymap[dir]->list); - kfree(help->help.ct_pptp_info.keymap[dir]); - help->help.ct_pptp_info.keymap[dir] = NULL; + ct_pptp_info->keymap[dir]); + list_del(&ct_pptp_info->keymap[dir]->list); + kfree(ct_pptp_info->keymap[dir]); + ct_pptp_info->keymap[dir] = NULL; } } write_unlock_bh(&net_gre->keymap_lock); diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index ec3fc18c4ef6..295429f39088 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c @@ -69,13 +69,12 @@ static int help(struct sk_buff *skb, void *sb_ptr; int ret = NF_ACCEPT; int dir = CTINFO2DIR(ctinfo); - struct nf_ct_sane_master *ct_sane_info; + struct nf_ct_sane_master *ct_sane_info = nfct_help_data(ct); struct nf_conntrack_expect *exp; struct nf_conntrack_tuple *tuple; struct sane_request *req; struct sane_reply_net_start *reply; - ct_sane_info = &nfct_help(ct)->help.ct_sane_info; /* Until there's been traffic both ways, don't look in packets. */ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) @@ -203,6 +202,7 @@ static int __init nf_conntrack_sane_init(void) sane[i][0].tuple.src.l3num = PF_INET; sane[i][1].tuple.src.l3num = PF_INET6; for (j = 0; j < 2; j++) { + sane[i][j].data_len = sizeof(struct nf_ct_sane_master); sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); sane[i][j].tuple.dst.protonum = IPPROTO_TCP; sane[i][j].expect_policy = &sane_exp_policy; diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index dfd3ff382243..758a1bacc126 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -1075,12 +1075,12 @@ static int process_invite_response(struct sk_buff *skb, unsigned int dataoff, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dataoff, dptr, datalen, cseq); - else if (help->help.ct_sip_info.invite_cseq == cseq) + else if (ct_sip_info->invite_cseq == cseq) flush_expectations(ct, true); return NF_ACCEPT; } @@ -1091,12 +1091,12 @@ static int process_update_response(struct sk_buff *skb, unsigned int dataoff, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dataoff, dptr, datalen, cseq); - else if (help->help.ct_sip_info.invite_cseq == cseq) + else if (ct_sip_info->invite_cseq == cseq) flush_expectations(ct, true); return NF_ACCEPT; } @@ -1107,12 +1107,12 @@ static int process_prack_response(struct sk_buff *skb, unsigned int dataoff, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dataoff, dptr, datalen, cseq); - else if (help->help.ct_sip_info.invite_cseq == cseq) + else if (ct_sip_info->invite_cseq == cseq) flush_expectations(ct, true); return NF_ACCEPT; } @@ -1123,13 +1123,13 @@ static int process_invite_request(struct sk_buff *skb, unsigned int dataoff, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); unsigned int ret; flush_expectations(ct, true); ret = process_sdp(skb, dataoff, dptr, datalen, cseq); if (ret == NF_ACCEPT) - help->help.ct_sip_info.invite_cseq = cseq; + ct_sip_info->invite_cseq = cseq; return ret; } @@ -1154,7 +1154,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int dataoff, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); unsigned int matchoff, matchlen; struct nf_conntrack_expect *exp; @@ -1235,7 +1235,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int dataoff, store_cseq: if (ret == NF_ACCEPT) - help->help.ct_sip_info.register_cseq = cseq; + ct_sip_info->register_cseq = cseq; return ret; } @@ -1245,7 +1245,7 @@ static int process_register_response(struct sk_buff *skb, unsigned int dataoff, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conn_help *help = nfct_help(ct); + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); union nf_inet_addr addr; __be16 port; @@ -1262,7 +1262,7 @@ static int process_register_response(struct sk_buff *skb, unsigned int dataoff, * responses, so we store the sequence number of the last valid * request and compare it here. */ - if (help->help.ct_sip_info.register_cseq != cseq) + if (ct_sip_info->register_cseq != cseq) return NF_ACCEPT; if (code >= 100 && code <= 199) @@ -1578,6 +1578,7 @@ static int __init nf_conntrack_sip_init(void) sip[i][3].help = sip_help_tcp; for (j = 0; j < ARRAY_SIZE(sip[i]); j++) { + sip[i][j].data_len = sizeof(struct nf_ct_sip_master); sip[i][j].tuple.src.u.udp.port = htons(ports[i]); sip[i][j].expect_policy = sip_exp_policy; sip[i][j].expect_class_max = SIP_EXPECT_MAX; diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index a51de9b052be..116018560c60 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -112,6 +112,8 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) goto err3; if (info->helper[0]) { + struct nf_conntrack_helper *helper; + ret = -ENOENT; proto = xt_ct_find_proto(par); if (!proto) { @@ -120,19 +122,21 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) goto err3; } - ret = -ENOMEM; - help = nf_ct_helper_ext_add(ct, GFP_KERNEL); - if (help == NULL) - goto err3; - ret = -ENOENT; - help->helper = nf_conntrack_helper_try_module_get(info->helper, - par->family, - proto); - if (help->helper == NULL) { + helper = nf_conntrack_helper_try_module_get(info->helper, + par->family, + proto); + if (helper == NULL) { pr_info("No such helper \"%s\"\n", info->helper); goto err3; } + + ret = -ENOMEM; + help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL); + if (help == NULL) + goto err3; + + help->helper = helper; } __set_bit(IPS_TEMPLATE_BIT, &ct->status); @@ -202,6 +206,8 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) goto err3; if (info->helper[0]) { + struct nf_conntrack_helper *helper; + ret = -ENOENT; proto = xt_ct_find_proto(par); if (!proto) { @@ -210,19 +216,21 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) goto err3; } - ret = -ENOMEM; - help = nf_ct_helper_ext_add(ct, GFP_KERNEL); - if (help == NULL) - goto err3; - ret = -ENOENT; - help->helper = nf_conntrack_helper_try_module_get(info->helper, - par->family, - proto); - if (help->helper == NULL) { + helper = nf_conntrack_helper_try_module_get(info->helper, + par->family, + proto); + if (helper == NULL) { pr_info("No such helper \"%s\"\n", info->helper); goto err3; } + + ret = -ENOMEM; + help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL); + if (help == NULL) + goto err3; + + help->helper = helper; } #ifdef CONFIG_NF_CONNTRACK_TIMEOUT -- GitLab From 9cb0176654a7dc33a32af8a0bc9e0b2f9f9ebb0f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 7 Jun 2012 12:13:39 +0200 Subject: [PATCH 1731/6849] netfilter: add glue code to integrate nfnetlink_queue and ctnetlink This patch allows you to include the conntrack information together with the packet that is sent to user-space via NFQUEUE. Previously, there was no integration between ctnetlink and nfnetlink_queue. If you wanted to access conntrack information from your libnetfilter_queue program, you required to query ctnetlink from user-space to obtain it. Thus, delaying the packet processing even more. Including the conntrack information is optional, you can set it via NFQA_CFG_F_CONNTRACK flag with the new NFQA_CFG_FLAGS attribute. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter.h | 10 ++ include/linux/netfilter/nfnetlink_queue.h | 3 + net/netfilter/core.c | 4 + net/netfilter/nf_conntrack_netlink.c | 144 +++++++++++++++++++++- net/netfilter/nfnetlink_queue.c | 48 ++++++++ 5 files changed, 208 insertions(+), 1 deletion(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 4541f33dbfc3..ba65bfbd7f74 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -393,6 +393,16 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *) __rcu; extern void nf_ct_attach(struct sk_buff *, struct sk_buff *); extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu; + +struct nf_conn; +struct nlattr; + +struct nfq_ct_hook { + size_t (*build_size)(const struct nf_conn *ct); + int (*build)(struct sk_buff *skb, struct nf_conn *ct); + int (*parse)(const struct nlattr *attr, struct nf_conn *ct); +}; +extern struct nfq_ct_hook *nfq_ct_hook; #else static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} #endif diff --git a/include/linux/netfilter/nfnetlink_queue.h b/include/linux/netfilter/nfnetlink_queue.h index a6c1ddac05cc..e0d8fd8d4d24 100644 --- a/include/linux/netfilter/nfnetlink_queue.h +++ b/include/linux/netfilter/nfnetlink_queue.h @@ -42,6 +42,8 @@ enum nfqnl_attr_type { NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */ NFQA_HWADDR, /* nfqnl_msg_packet_hw */ NFQA_PAYLOAD, /* opaque data payload */ + NFQA_CT, /* nf_conntrack_netlink.h */ + NFQA_CT_INFO, /* enum ip_conntrack_info */ __NFQA_MAX }; @@ -92,5 +94,6 @@ enum nfqnl_attr_config { /* Flags for NFQA_CFG_FLAGS */ #define NFQA_CFG_F_FAIL_OPEN (1 << 0) +#define NFQA_CFG_F_CONNTRACK (1 << 1) #endif /* _NFNETLINK_QUEUE_H */ diff --git a/net/netfilter/core.c b/net/netfilter/core.c index e19f3653db23..7eef8453b909 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -264,6 +264,10 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct) rcu_read_unlock(); } EXPORT_SYMBOL(nf_conntrack_destroy); + +struct nfq_ct_hook *nfq_ct_hook; +EXPORT_SYMBOL_GPL(nfq_ct_hook); + #endif /* CONFIG_NF_CONNTRACK */ #ifdef CONFIG_PROC_FS diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index a08892048b46..d304d5917950 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1620,6 +1620,140 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; } +#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \ + defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE) +static size_t +ctnetlink_nfqueue_build_size(const struct nf_conn *ct) +{ + return 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */ + + 3 * nla_total_size(0) /* CTA_TUPLE_IP */ + + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */ + + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */ + + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */ + + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */ + + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */ + + nla_total_size(0) /* CTA_PROTOINFO */ + + nla_total_size(0) /* CTA_HELP */ + + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */ + + ctnetlink_secctx_size(ct) +#ifdef CONFIG_NF_NAT_NEEDED + + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */ + + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */ +#endif +#ifdef CONFIG_NF_CONNTRACK_MARK + + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */ +#endif + + ctnetlink_proto_size(ct) + ; +} + +static int +ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct) +{ + struct nlattr *nest_parms; + + rcu_read_lock(); + nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; + if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) + goto nla_put_failure; + nla_nest_end(skb, nest_parms); + + nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; + if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0) + goto nla_put_failure; + nla_nest_end(skb, nest_parms); + + if (nf_ct_zone(ct)) { + if (nla_put_be16(skb, CTA_ZONE, htons(nf_ct_zone(ct)))) + goto nla_put_failure; + } + + if (ctnetlink_dump_id(skb, ct) < 0) + goto nla_put_failure; + + if (ctnetlink_dump_status(skb, ct) < 0) + goto nla_put_failure; + + if (ctnetlink_dump_timeout(skb, ct) < 0) + goto nla_put_failure; + + if (ctnetlink_dump_protoinfo(skb, ct) < 0) + goto nla_put_failure; + + if (ctnetlink_dump_helpinfo(skb, ct) < 0) + goto nla_put_failure; + +#ifdef CONFIG_NF_CONNTRACK_SECMARK + if (ct->secmark && ctnetlink_dump_secctx(skb, ct) < 0) + goto nla_put_failure; +#endif + if (ct->master && ctnetlink_dump_master(skb, ct) < 0) + goto nla_put_failure; + + if ((ct->status & IPS_SEQ_ADJUST) && + ctnetlink_dump_nat_seq_adj(skb, ct) < 0) + goto nla_put_failure; + +#ifdef CONFIG_NF_CONNTRACK_MARK + if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0) + goto nla_put_failure; +#endif + rcu_read_unlock(); + return 0; + +nla_put_failure: + rcu_read_unlock(); + return -ENOSPC; +} + +static int +ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) +{ + int err; + + if (cda[CTA_TIMEOUT]) { + err = ctnetlink_change_timeout(ct, cda); + if (err < 0) + return err; + } + if (cda[CTA_STATUS]) { + err = ctnetlink_change_status(ct, cda); + if (err < 0) + return err; + } + if (cda[CTA_HELP]) { + err = ctnetlink_change_helper(ct, cda); + if (err < 0) + return err; + } +#if defined(CONFIG_NF_CONNTRACK_MARK) + if (cda[CTA_MARK]) + ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); +#endif + return 0; +} + +static int +ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct) +{ + struct nlattr *cda[CTA_MAX+1]; + + nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy); + + return ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct); +} + +static struct nfq_ct_hook ctnetlink_nfqueue_hook = { + .build_size = ctnetlink_nfqueue_build_size, + .build = ctnetlink_nfqueue_build, + .parse = ctnetlink_nfqueue_parse, +}; +#endif /* CONFIG_NETFILTER_NETLINK_QUEUE */ + /*********************************************************************** * EXPECT ***********************************************************************/ @@ -2424,7 +2558,11 @@ static int __init ctnetlink_init(void) pr_err("ctnetlink_init: cannot register pernet operations\n"); goto err_unreg_exp_subsys; } - +#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \ + defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE) + /* setup interaction between nf_queue and nf_conntrack_netlink. */ + RCU_INIT_POINTER(nfq_ct_hook, &ctnetlink_nfqueue_hook); +#endif return 0; err_unreg_exp_subsys: @@ -2442,6 +2580,10 @@ static void __exit ctnetlink_exit(void) unregister_pernet_subsys(&ctnetlink_net_ops); nfnetlink_subsys_unregister(&ctnl_exp_subsys); nfnetlink_subsys_unregister(&ctnl_subsys); +#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \ + defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE) + RCU_INIT_POINTER(nfq_ct_hook, NULL); +#endif } module_init(ctnetlink_init); diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 630da3d2c62a..647923ae9230 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -233,6 +234,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, struct sk_buff *entskb = entry->skb; struct net_device *indev; struct net_device *outdev; + struct nfq_ct_hook *nfq_ct; + struct nf_conn *ct = NULL; + enum ip_conntrack_info uninitialized_var(ctinfo); size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) @@ -266,6 +270,17 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, break; } + /* rcu_read_lock()ed by __nf_queue already. */ + nfq_ct = rcu_dereference(nfq_ct_hook); + if (nfq_ct != NULL && (queue->flags & NFQA_CFG_F_CONNTRACK)) { + ct = nf_ct_get(entskb, &ctinfo); + if (ct) { + if (!nf_ct_is_untracked(ct)) + size += nfq_ct->build_size(ct); + else + ct = NULL; + } + } skb = alloc_skb(size, GFP_ATOMIC); if (!skb) @@ -389,6 +404,24 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, BUG(); } + if (ct) { + struct nlattr *nest_parms; + u_int32_t tmp; + + nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; + + if (nfq_ct->build(skb, ct) < 0) + goto nla_put_failure; + + nla_nest_end(skb, nest_parms); + + tmp = ctinfo; + if (nla_put_u32(skb, NFQA_CT_INFO, htonl(ctinfo))) + goto nla_put_failure; + } + nlh->nlmsg_len = skb->tail - old_tail; return skb; @@ -632,6 +665,7 @@ static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = { [NFQA_VERDICT_HDR] = { .len = sizeof(struct nfqnl_msg_verdict_hdr) }, [NFQA_MARK] = { .type = NLA_U32 }, [NFQA_PAYLOAD] = { .type = NLA_UNSPEC }, + [NFQA_CT] = { .type = NLA_UNSPEC }, }; static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = { @@ -732,6 +766,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, struct nfqnl_instance *queue; unsigned int verdict; struct nf_queue_entry *entry; + struct nfq_ct_hook *nfq_ct; queue = instance_lookup(queue_num); if (!queue) @@ -750,6 +785,19 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, if (entry == NULL) return -ENOENT; + rcu_read_lock(); + nfq_ct = rcu_dereference(nfq_ct_hook); + if (nfq_ct != NULL && + (queue->flags & NFQA_CFG_F_CONNTRACK) && nfqa[NFQA_CT]) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct; + + ct = nf_ct_get(entry->skb, &ctinfo); + if (ct && !nf_ct_is_untracked(ct)) + nfq_ct->parse(nfqa[NFQA_CT], ct); + } + rcu_read_unlock(); + if (nfqa[NFQA_PAYLOAD]) { if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]), nla_len(nfqa[NFQA_PAYLOAD]), entry) < 0) -- GitLab From 8c88f87cb27ad09086940bdd3e6955e5325ec89a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 7 Jun 2012 13:31:25 +0200 Subject: [PATCH 1732/6849] netfilter: nfnetlink_queue: add NAT TCP sequence adjustment if packet mangled User-space programs that receive traffic via NFQUEUE may mangle packets. If NAT is enabled, this usually puzzles sequence tracking, leading to traffic disruptions. With this patch, nfnl_queue will make the corresponding NAT TCP sequence adjustment if: 1) The packet has been mangled, 2) the NFQA_CFG_F_CONNTRACK flag has been set, and 3) NAT is detected. There are some records on the Internet complaning about this issue: http://stackoverflow.com/questions/260757/packet-mangling-utilities-besides-iptables By now, we only support TCP since we have no helpers for DCCP or SCTP. Better to add this if we ever have some helper over those layer 4 protocols. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter.h | 2 ++ include/net/netfilter/nf_nat_helper.h | 4 ++++ net/ipv4/netfilter/nf_nat_helper.c | 13 +++++++++++++ net/netfilter/nf_conntrack_netlink.c | 4 ++++ net/netfilter/nfnetlink_queue.c | 19 +++++++++++-------- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index ba65bfbd7f74..dca19e61b30a 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -401,6 +401,8 @@ struct nfq_ct_hook { size_t (*build_size)(const struct nf_conn *ct); int (*build)(struct sk_buff *skb, struct nf_conn *ct); int (*parse)(const struct nlattr *attr, struct nf_conn *ct); + void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, + u32 ctinfo, int off); }; extern struct nfq_ct_hook *nfq_ct_hook; #else diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h index 02bb6c29dc3d..7d8fb7b46c44 100644 --- a/include/net/netfilter/nf_nat_helper.h +++ b/include/net/netfilter/nf_nat_helper.h @@ -54,4 +54,8 @@ extern void nf_nat_follow_master(struct nf_conn *ct, extern s16 nf_nat_get_offset(const struct nf_conn *ct, enum ip_conntrack_dir dir, u32 seq); + +extern void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, + u32 dir, int off); + #endif diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index af65958f6308..2e59ad0b90ca 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c @@ -153,6 +153,19 @@ void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo, } EXPORT_SYMBOL_GPL(nf_nat_set_seq_adjust); +void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, + u32 ctinfo, int off) +{ + const struct tcphdr *th; + + if (nf_ct_protonum(ct) != IPPROTO_TCP) + return; + + th = (struct tcphdr *)(skb_network_header(skb)+ ip_hdrlen(skb)); + nf_nat_set_seq_adjust(ct, ctinfo, th->seq, off); +} +EXPORT_SYMBOL_GPL(nf_nat_tcp_seq_adjust); + static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data, int datalen, __sum16 *check, int oldlen) { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index d304d5917950..8be0ab9b4758 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -46,6 +46,7 @@ #ifdef CONFIG_NF_NAT_NEEDED #include #include +#include #endif #include @@ -1751,6 +1752,9 @@ static struct nfq_ct_hook ctnetlink_nfqueue_hook = { .build_size = ctnetlink_nfqueue_build_size, .build = ctnetlink_nfqueue_build, .parse = ctnetlink_nfqueue_parse, +#ifdef CONFIG_NF_NAT_NEEDED + .seq_adjust = nf_nat_tcp_seq_adjust, +#endif }; #endif /* CONFIG_NETFILTER_NETLINK_QUEUE */ diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 647923ae9230..ff82c7933dfd 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -502,12 +502,10 @@ err_out: } static int -nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) +nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e, int diff) { struct sk_buff *nskb; - int diff; - diff = data_len - e->skb->len; if (diff < 0) { if (pskb_trim(e->skb, data_len)) return -ENOMEM; @@ -767,6 +765,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, unsigned int verdict; struct nf_queue_entry *entry; struct nfq_ct_hook *nfq_ct; + enum ip_conntrack_info uninitialized_var(ctinfo); + struct nf_conn *ct = NULL; queue = instance_lookup(queue_num); if (!queue) @@ -789,20 +789,23 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, nfq_ct = rcu_dereference(nfq_ct_hook); if (nfq_ct != NULL && (queue->flags & NFQA_CFG_F_CONNTRACK) && nfqa[NFQA_CT]) { - enum ip_conntrack_info ctinfo; - struct nf_conn *ct; - ct = nf_ct_get(entry->skb, &ctinfo); if (ct && !nf_ct_is_untracked(ct)) nfq_ct->parse(nfqa[NFQA_CT], ct); } - rcu_read_unlock(); if (nfqa[NFQA_PAYLOAD]) { + u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]); + int diff = payload_len - entry->skb->len; + if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]), - nla_len(nfqa[NFQA_PAYLOAD]), entry) < 0) + payload_len, entry, diff) < 0) verdict = NF_DROP; + + if (ct && (ct->status & IPS_NAT_MASK) && diff) + nfq_ct->seq_adjust(skb, ct, ctinfo, diff); } + rcu_read_unlock(); if (nfqa[NFQA_MARK]) entry->skb->mark = ntohl(nla_get_be32(nfqa[NFQA_MARK])); -- GitLab From ae243bee397102c51fbf9db440eca3b077e0e702 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 7 Jun 2012 14:19:42 +0200 Subject: [PATCH 1733/6849] netfilter: ctnetlink: add CTA_HELP_INFO attribute This attribute can be used to modify and to dump the internal protocol information. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/nfnetlink_conntrack.h | 1 + include/net/netfilter/nf_conntrack_helper.h | 1 + net/netfilter/nf_conntrack_netlink.c | 23 +++++++++++++++---- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index e58e4b93c108..768883370080 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h @@ -191,6 +191,7 @@ enum ctattr_expect_nat { enum ctattr_help { CTA_HELP_UNSPEC, CTA_HELP_NAME, + CTA_HELP_INFO, __CTA_HELP_MAX }; #define CTA_HELP_MAX (__CTA_HELP_MAX - 1) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 061352f71a84..84b24c3a3834 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -39,6 +39,7 @@ struct nf_conntrack_helper { void (*destroy)(struct nf_conn *ct); + int (*from_nlattr)(struct nlattr *attr, struct nf_conn *ct); int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct); unsigned int expect_class_max; }; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 8be0ab9b4758..ae156dff4887 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -902,7 +902,8 @@ static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = { }; static inline int -ctnetlink_parse_help(const struct nlattr *attr, char **helper_name) +ctnetlink_parse_help(const struct nlattr *attr, char **helper_name, + struct nlattr **helpinfo) { struct nlattr *tb[CTA_HELP_MAX+1]; @@ -913,6 +914,9 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name) *helper_name = nla_data(tb[CTA_HELP_NAME]); + if (tb[CTA_HELP_INFO]) + *helpinfo = tb[CTA_HELP_INFO]; + return 0; } @@ -1173,13 +1177,14 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) struct nf_conntrack_helper *helper; struct nf_conn_help *help = nfct_help(ct); char *helpname = NULL; + struct nlattr *helpinfo = NULL; int err; /* don't change helper of sibling connections */ if (ct->master) return -EBUSY; - err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); + err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo); if (err < 0) return err; @@ -1214,8 +1219,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) } if (help) { - if (help->helper == helper) + if (help->helper == helper) { + /* update private helper data if allowed. */ + if (helper->from_nlattr && helpinfo) + helper->from_nlattr(helpinfo, ct); return 0; + } if (help->helper) return -EBUSY; /* need to zero data of old helper */ @@ -1411,8 +1420,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, rcu_read_lock(); if (cda[CTA_HELP]) { char *helpname = NULL; - - err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); + struct nlattr *helpinfo = NULL; + + err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo); if (err < 0) goto err2; @@ -1446,6 +1456,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, err = -ENOMEM; goto err2; } + /* set private helper data if allowed. */ + if (helper->from_nlattr && helpinfo) + helper->from_nlattr(helpinfo, ct); /* not in hash table yet so not strictly necessary */ RCU_INIT_POINTER(help->helper, helper); -- GitLab From b866d1334ba2d544bc575d75357dea6bdcdc7f46 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 22:06:36 +0200 Subject: [PATCH 1734/6849] drm/radeon: add some additional 6xx/7xx/EG register init - SMX_SAR_CTL0 needs to be programmed correctly to prevent problems with memory exports in certain cases. - VC_ENHANCE needs to be initialized on 6xx/7xx. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 +++ drivers/gpu/drm/radeon/evergreend.h | 1 + drivers/gpu/drm/radeon/r600.c | 1 + drivers/gpu/drm/radeon/r600d.h | 1 + drivers/gpu/drm/radeon/rv770.c | 5 ++++- drivers/gpu/drm/radeon/rv770d.h | 3 +++ 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 01550d05e273..7fb3d2e0434c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1932,6 +1932,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); WREG32(SMX_DC_CTL0, smx_dc_ctl0); + if (rdev->family <= CHIP_SUMO2) + WREG32(SMX_SAR_CTL0, 0x00010000); + WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 2773039b4902..b50b15c70498 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -503,6 +503,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define NUMBER_OF_SETS(x) ((x) << 1) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f30dc95f83b1..bff627293812 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1839,6 +1839,7 @@ void r600_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); + WREG32(VC_ENHANCE, 0); } diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a0dbf1fe6a40..c6857e8d76f2 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -485,6 +485,7 @@ #define TC_L2_SIZE(x) ((x)<<5) #define L2_DISABLE_LATE_HIT (1<<9) +#define VC_ENHANCE 0x9714 #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4ad0281fdc37..b4f51c569c36 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -616,6 +616,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) ACK_FLUSH_CTL(3) | SYNC_FLUSH_CTL)); + if (rdev->family != CHIP_RV770) + WREG32(SMX_SAR_CTL0, 0x00003f3f); + db_debug3 = RREG32(DB_DEBUG3); db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); switch (rdev->family) { @@ -792,7 +795,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); - + WREG32(VC_ENHANCE, 0); } void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index fdc089896011..b0adfc595d75 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -211,6 +211,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define CACHE_DEPTH(x) ((x) << 1) @@ -310,6 +311,8 @@ #define TCP_CNTL 0x9610 #define TCP_CHAN_STEER 0x9614 +#define VC_ENHANCE 0x9714 + #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) #define VC_ONLY 0 -- GitLab From 7c77bf2a1a8bf67d580a3b189b37fded0a13ab78 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 22:06:37 +0200 Subject: [PATCH 1735/6849] drm/radeon: add support for STRMOUT_BASE_UPDATE on 7xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Required for streamout. Bump drm minor. Marek v2: fix pkt->count check Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 42 +++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/r600d.h | 1 + drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0133f5f09bd6..ca87f7afaf23 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -2079,6 +2079,48 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } break; + case PACKET3_STRMOUT_BASE_UPDATE: + if (p->family < CHIP_RV770) { + DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); + return -EINVAL; + } + if (pkt->count != 1) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n"); + return -EINVAL; + } + if (idx_value > 3) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n"); + return -EINVAL; + } + { + u64 offset; + + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); + return -EINVAL; + } + + if (reloc->robj != track->vgt_strmout_bo[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n"); + return -EINVAL; + } + + offset = radeon_get_ib_value(p, idx+1) << 8; + if (offset != track->vgt_strmout_bo_offset[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n", + offset, track->vgt_strmout_bo_offset[idx_value]); + return -EINVAL; + } + + if ((offset + 4) > radeon_bo_size(reloc->robj)) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%llx, 0x%lx\n", + offset + 4, radeon_bo_size(reloc->robj)); + return -EINVAL; + } + ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + } + break; case PACKET3_SURFACE_BASE_UPDATE: if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index c6857e8d76f2..025fd5b6c08c 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1164,6 +1164,7 @@ #define PACKET3_SET_CTL_CONST 0x6F #define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 #define PACKET3_SET_CTL_CONST_END 0x0003e200 +#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ #define PACKET3_SURFACE_BASE_UPDATE 0x73 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 03e5f5df40f1..2c4d53fd20c5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -58,9 +58,10 @@ * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query * 2.16.0 - fix evergreen 2D tiled surface calculation + * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 16 +#define KMS_DRIVER_MINOR 17 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- GitLab From b708a1d5ea7880b399dbd45cacafff6ae8d73171 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 11 Jun 2012 14:39:56 -0400 Subject: [PATCH 1736/6849] drm/i915: don't enumerate HDMID if an eDP panel is already active on the port This prevents the HDMI detect functions from poking at an eDP connected panel, which can lead to trouble. [danvet: Note that we have some other reports of DP vs. HDMI fighting, but the general case is a much bigger fish to fry.] References: https://bugs.freedesktop.org/show_bug.cgi?id=42278 Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e0aa064def31..a7c727d0c105 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6558,7 +6558,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(HDMIC) & PORT_DETECTED) intel_hdmi_init(dev, HDMIC); - if (I915_READ(HDMID) & PORT_DETECTED) + if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) -- GitLab From 351cfc34db8decb0c5cc1aac7cf1780a0e45c8b1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 12 Jun 2012 13:20:47 +0200 Subject: [PATCH 1737/6849] drm/i915: eDP aux needs vdd The new oui probe has been missing these. This issue has been introduce in commit 0d198328538276c4459ef5de081e68ae60e6c4c2 Author: Adam Jackson Date: Mon May 14 16:05:47 2012 -0400 drm/i915/dp: Probe branch/sink OUIs v2: Do the eDP vdd dance of simply not probing the OUI on eDP panels as suggested by Chris Wilson. v3: Fix up the error path fail - I suck. Cc: Adam Jackson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50808 Reported-by: Linus Torvalds Bugreport: http://permalink.gmane.org/gmane.comp.video.dri.devel/69695 Tested-by: Yang Guang Reviewed-by: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 296cfc201a81..c574ff0189de 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1973,6 +1973,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; + ironlake_edp_panel_vdd_on(intel_dp); + if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3)) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); @@ -1980,6 +1982,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3)) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); + + ironlake_edp_panel_vdd_off(intel_dp, false); } static bool -- GitLab From 6b4e0a93ff6e45714c72bdce193f719ed94810e3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 14 Jun 2012 22:15:00 +0200 Subject: [PATCH 1738/6849] Revert "drm/i915/dp: Use auxch precharge value of 5 everywhere" This reverts commit 092945e11c5b84f66dd08f0b87fb729715d377bc. This commit prevents a DP screen from properly training the link. Oddly enough it works, once the machine has been warm-booted with an older kernel. According to DP docs this _should_ have been the right precharge time. Also, the commit that originally introduces this was just general snb DP enabling and didn't mention any specific reason for this special value. Whatever, trust the reporter that this makes things worse and let's just revert it. v2: Less spelling fail. Cc: Adam Jackson Cc: Jesse Barnes Reported-by: "Wouter M. Koolen" Buglink: https://lkml.org/lkml/2012/6/14/301 Cc: stable@vger.kernel.org (only for 3.4) Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c574ff0189de..a4b3887575a1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -371,7 +371,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, int recv_bytes; uint32_t status; uint32_t aux_clock_divider; - int try, precharge = 5; + int try, precharge; intel_dp_check_edp(intel_dp); /* The clock divider is based off the hrawclk, @@ -391,6 +391,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = intel_hrawclk(dev) / 2; + if (IS_GEN6(dev)) + precharge = 3; + else + precharge = 5; + /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ(ch_ctl); -- GitLab From d6f24d0fa6cdf3431a2fe3330a74bc6c5871f496 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 14 Jun 2012 15:28:33 -0400 Subject: [PATCH 1739/6849] drm/i915: cache the EDID for eDP panels They aren't going anywhere, and probing on DDC can cause the panel to blank briefly, so read them up front and cache them for later queries. v2: fix potential NULL derefs in intel_dp_get_edid_modes and intel_dp_get_edid (Jani) copy full EDID length, including extension blocks (Takashi) free EDID on teardown (Takashi) v3: malloc a new EDID buffer that's big enough for the memcpy (Chris) v4: change handling of NULL EDIDs, just preserve the NULL behavior across detects and mode list fetches rather than trying to re-fetch the EDID (Chris) v5: be glad that Chris is around to remind me to hit C-x C-s before committing. References: https://bugs.freedesktop.org/show_bug.cgi?id=46856 Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 49 +++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a4b3887575a1..c0449324143c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -32,6 +32,7 @@ #include "drm.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" +#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -67,6 +68,8 @@ struct intel_dp { struct drm_display_mode *panel_fixed_mode; /* for eDP */ struct delayed_work panel_vdd_work; bool want_panel_vdd; + struct edid *edid; /* cached EDID for eDP */ + int edid_mode_count; }; /** @@ -2125,10 +2128,22 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { struct intel_dp *intel_dp = intel_attached_dp(connector); struct edid *edid; + int size; + + if (is_edp(intel_dp)) { + if (!intel_dp->edid) + return NULL; + + size = (intel_dp->edid->extensions + 1) * EDID_LENGTH; + edid = kmalloc(size, GFP_KERNEL); + if (!edid) + return NULL; + + memcpy(edid, intel_dp->edid, size); + return edid; + } - ironlake_edp_panel_vdd_on(intel_dp); edid = drm_get_edid(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); return edid; } @@ -2138,9 +2153,17 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada struct intel_dp *intel_dp = intel_attached_dp(connector); int ret; - ironlake_edp_panel_vdd_on(intel_dp); + if (is_edp(intel_dp)) { + drm_mode_connector_update_edid_property(connector, + intel_dp->edid); + ret = drm_add_edid_modes(connector, intel_dp->edid); + drm_edid_to_eld(connector, + intel_dp->edid); + connector->display_info.raw_edid = NULL; + return intel_dp->edid_mode_count; + } + ret = intel_ddc_get_modes(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); return ret; } @@ -2330,6 +2353,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { + kfree(intel_dp->edid); cancel_delayed_work_sync(&intel_dp->panel_vdd_work); ironlake_panel_vdd_off_sync(intel_dp); } @@ -2513,11 +2537,14 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; } + intel_dp_i2c_init(intel_dp, intel_connector, name); + /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { bool ret; struct edp_power_seq cur, vbt; u32 pp_on, pp_off, pp_div; + struct edid *edid; pp_on = I915_READ(PCH_PP_ON_DELAYS); pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2585,9 +2612,19 @@ intel_dp_init(struct drm_device *dev, int output_reg) intel_dp_destroy(&intel_connector->base); return; } - } - intel_dp_i2c_init(intel_dp, intel_connector, name); + ironlake_edp_panel_vdd_on(intel_dp); + edid = drm_get_edid(connector, &intel_dp->adapter); + if (edid) { + drm_mode_connector_update_edid_property(connector, + edid); + intel_dp->edid_mode_count = + drm_add_edid_modes(connector, edid); + drm_edid_to_eld(connector, edid); + intel_dp->edid = edid; + } + ironlake_edp_panel_vdd_off(intel_dp, false); + } intel_encoder->hot_plug = intel_dp_hot_plug; -- GitLab From 12f7a505331e6b2754684b509f2ac8f0011ce644 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 13 May 2012 21:44:54 +0200 Subject: [PATCH 1740/6849] netfilter: add user-space connection tracking helper infrastructure There are good reasons to supports helpers in user-space instead: * Rapid connection tracking helper development, as developing code in user-space is usually faster. * Reliability: A buggy helper does not crash the kernel. Moreover, we can monitor the helper process and restart it in case of problems. * Security: Avoid complex string matching and mangling in kernel-space running in privileged mode. Going further, we can even think about running user-space helpers as a non-root process. * Extensibility: It allows the development of very specific helpers (most likely non-standard proprietary protocols) that are very likely not to be accepted for mainline inclusion in the form of kernel-space connection tracking helpers. This patch adds the infrastructure to allow the implementation of user-space conntrack helpers by means of the new nfnetlink subsystem `nfnetlink_cthelper' and the existing queueing infrastructure (nfnetlink_queue). I had to add the new hook NF_IP6_PRI_CONNTRACK_HELPER to register ipv[4|6]_helper which results from splitting ipv[4|6]_confirm into two pieces. This change is required not to break NAT sequence adjustment and conntrack confirmation for traffic that is enqueued to our user-space conntrack helpers. Basic operation, in a few steps: 1) Register user-space helper by means of `nfct': nfct helper add ftp inet tcp [ It must be a valid existing helper supported by conntrack-tools ] 2) Add rules to enable the FTP user-space helper which is used to track traffic going to TCP port 21. For locally generated packets: iptables -I OUTPUT -t raw -p tcp --dport 21 -j CT --helper ftp For non-locally generated packets: iptables -I PREROUTING -t raw -p tcp --dport 21 -j CT --helper ftp 3) Run the test conntrackd in helper mode (see example files under doc/helper/conntrackd.conf conntrackd 4) Generate FTP traffic going, if everything is OK, then conntrackd should create expectations (you can check that with `conntrack': conntrack -E expect [NEW] 301 proto=6 src=192.168.1.136 dst=130.89.148.12 sport=0 dport=54037 mask-src=255.255.255.255 mask-dst=255.255.255.255 sport=0 dport=65535 master-src=192.168.1.136 master-dst=130.89.148.12 sport=57127 dport=21 class=0 helper=ftp [DESTROY] 301 proto=6 src=192.168.1.136 dst=130.89.148.12 sport=0 dport=54037 mask-src=255.255.255.255 mask-dst=255.255.255.255 sport=0 dport=65535 master-src=192.168.1.136 master-dst=130.89.148.12 sport=57127 dport=21 class=0 helper=ftp This confirms that our test helper is receiving packets including the conntrack information, and adding expectations in kernel-space. The user-space helper can also store its private tracking information in the conntrack structure in the kernel via the CTA_HELP_INFO. The kernel will consider this a binary blob whose layout is unknown. This information will be included in the information that is transfered to user-space via glue code that integrates nfnetlink_queue and ctnetlink. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/Kbuild | 1 + include/linux/netfilter/nfnetlink.h | 3 +- include/linux/netfilter/nfnetlink_cthelper.h | 55 ++ include/linux/netfilter_ipv4.h | 1 + include/linux/netfilter_ipv6.h | 1 + include/net/netfilter/nf_conntrack_helper.h | 11 + .../netfilter/nf_conntrack_l3proto_ipv4.c | 48 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 43 +- net/netfilter/Kconfig | 8 + net/netfilter/Makefile | 1 + net/netfilter/nf_conntrack_helper.c | 21 +- net/netfilter/nfnetlink_cthelper.c | 672 ++++++++++++++++++ 12 files changed, 839 insertions(+), 26 deletions(-) create mode 100644 include/linux/netfilter/nfnetlink_cthelper.h create mode 100644 net/netfilter/nfnetlink_cthelper.c diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild index 1697036336b6..874ae8f2706b 100644 --- a/include/linux/netfilter/Kbuild +++ b/include/linux/netfilter/Kbuild @@ -10,6 +10,7 @@ header-y += nfnetlink.h header-y += nfnetlink_acct.h header-y += nfnetlink_compat.h header-y += nfnetlink_conntrack.h +header-y += nfnetlink_cthelper.h header-y += nfnetlink_cttimeout.h header-y += nfnetlink_log.h header-y += nfnetlink_queue.h diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index a1048c1587d1..18341cdb2443 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -50,7 +50,8 @@ struct nfgenmsg { #define NFNL_SUBSYS_IPSET 6 #define NFNL_SUBSYS_ACCT 7 #define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8 -#define NFNL_SUBSYS_COUNT 9 +#define NFNL_SUBSYS_CTHELPER 9 +#define NFNL_SUBSYS_COUNT 10 #ifdef __KERNEL__ diff --git a/include/linux/netfilter/nfnetlink_cthelper.h b/include/linux/netfilter/nfnetlink_cthelper.h new file mode 100644 index 000000000000..33659f6fad3e --- /dev/null +++ b/include/linux/netfilter/nfnetlink_cthelper.h @@ -0,0 +1,55 @@ +#ifndef _NFNL_CTHELPER_H_ +#define _NFNL_CTHELPER_H_ + +#define NFCT_HELPER_STATUS_DISABLED 0 +#define NFCT_HELPER_STATUS_ENABLED 1 + +enum nfnl_acct_msg_types { + NFNL_MSG_CTHELPER_NEW, + NFNL_MSG_CTHELPER_GET, + NFNL_MSG_CTHELPER_DEL, + NFNL_MSG_CTHELPER_MAX +}; + +enum nfnl_cthelper_type { + NFCTH_UNSPEC, + NFCTH_NAME, + NFCTH_TUPLE, + NFCTH_QUEUE_NUM, + NFCTH_POLICY, + NFCTH_PRIV_DATA_LEN, + NFCTH_STATUS, + __NFCTH_MAX +}; +#define NFCTH_MAX (__NFCTH_MAX - 1) + +enum nfnl_cthelper_policy_type { + NFCTH_POLICY_SET_UNSPEC, + NFCTH_POLICY_SET_NUM, + NFCTH_POLICY_SET, + NFCTH_POLICY_SET1 = NFCTH_POLICY_SET, + NFCTH_POLICY_SET2, + NFCTH_POLICY_SET3, + NFCTH_POLICY_SET4, + __NFCTH_POLICY_SET_MAX +}; +#define NFCTH_POLICY_SET_MAX (__NFCTH_POLICY_SET_MAX - 1) + +enum nfnl_cthelper_pol_type { + NFCTH_POLICY_UNSPEC, + NFCTH_POLICY_NAME, + NFCTH_POLICY_EXPECT_MAX, + NFCTH_POLICY_EXPECT_TIMEOUT, + __NFCTH_POLICY_MAX +}; +#define NFCTH_POLICY_MAX (__NFCTH_POLICY_MAX - 1) + +enum nfnl_cthelper_tuple_type { + NFCTH_TUPLE_UNSPEC, + NFCTH_TUPLE_L3PROTONUM, + NFCTH_TUPLE_L4PROTONUM, + __NFCTH_TUPLE_MAX, +}; +#define NFCTH_TUPLE_MAX (__NFCTH_TUPLE_MAX - 1) + +#endif /* _NFNL_CTHELPER_H */ diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index fa0946c549d3..e2b12801378d 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h @@ -66,6 +66,7 @@ enum nf_ip_hook_priorities { NF_IP_PRI_SECURITY = 50, NF_IP_PRI_NAT_SRC = 100, NF_IP_PRI_SELINUX_LAST = 225, + NF_IP_PRI_CONNTRACK_HELPER = 300, NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, NF_IP_PRI_LAST = INT_MAX, }; diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 57c025127f1d..7c8a513ce7a3 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -71,6 +71,7 @@ enum nf_ip6_hook_priorities { NF_IP6_PRI_SECURITY = 50, NF_IP6_PRI_NAT_SRC = 100, NF_IP6_PRI_SELINUX_LAST = 225, + NF_IP6_PRI_CONNTRACK_HELPER = 300, NF_IP6_PRI_LAST = INT_MAX, }; diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 84b24c3a3834..9aad956d1008 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -15,6 +15,11 @@ struct module; +enum nf_ct_helper_flags { + NF_CT_HELPER_F_USERSPACE = (1 << 0), + NF_CT_HELPER_F_CONFIGURED = (1 << 1), +}; + #define NF_CT_HELPER_NAME_LEN 16 struct nf_conntrack_helper { @@ -42,6 +47,9 @@ struct nf_conntrack_helper { int (*from_nlattr)(struct nlattr *attr, struct nf_conn *ct); int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct); unsigned int expect_class_max; + + unsigned int flags; + unsigned int queue_num; /* For user-space helpers. */ }; extern struct nf_conntrack_helper * @@ -96,4 +104,7 @@ nf_ct_helper_expectfn_find_by_name(const char *name); struct nf_ct_helper_expectfn * nf_ct_helper_expectfn_find_by_symbol(const void *symbol); +extern struct hlist_head *nf_ct_helper_hash; +extern unsigned int nf_ct_helper_hsize; + #endif /*_NF_CONNTRACK_HELPER_H*/ diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index d79b961a8009..e7ff2dcab6ce 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -95,11 +95,11 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, return NF_ACCEPT; } -static unsigned int ipv4_confirm(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) +static unsigned int ipv4_helper(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) { struct nf_conn *ct; enum ip_conntrack_info ctinfo; @@ -110,24 +110,38 @@ static unsigned int ipv4_confirm(unsigned int hooknum, /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(skb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED_REPLY) - goto out; + return NF_ACCEPT; help = nfct_help(ct); if (!help) - goto out; + return NF_ACCEPT; /* rcu_read_lock()ed by nf_hook_slow */ helper = rcu_dereference(help->helper); if (!helper) - goto out; + return NF_ACCEPT; ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), ct, ctinfo); - if (ret != NF_ACCEPT) { + if (ret != NF_ACCEPT && (ret & NF_VERDICT_MASK) != NF_QUEUE) { nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL, "nf_ct_%s: dropping packet", helper->name); - return ret; } + return ret; +} + +static unsigned int ipv4_confirm(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct nf_conn *ct; + enum ip_conntrack_info ctinfo; + + ct = nf_ct_get(skb, &ctinfo); + if (!ct || ctinfo == IP_CT_RELATED_REPLY) + goto out; /* adjust seqs for loopback traffic only in outgoing direction */ if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && @@ -184,6 +198,13 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_CONNTRACK, }, + { + .hook = ipv4_helper, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_HELPER, + }, { .hook = ipv4_confirm, .owner = THIS_MODULE, @@ -191,6 +212,13 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { .hooknum = NF_INET_POST_ROUTING, .priority = NF_IP_PRI_CONNTRACK_CONFIRM, }, + { + .hook = ipv4_helper, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_LOCAL_IN, + .priority = NF_IP_PRI_CONNTRACK_HELPER, + }, { .hook = ipv4_confirm, .owner = THIS_MODULE, diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index fca10da80ea7..4794f96cf2e0 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -143,11 +143,11 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, return NF_ACCEPT; } -static unsigned int ipv6_confirm(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) +static unsigned int ipv6_helper(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) { struct nf_conn *ct; const struct nf_conn_help *help; @@ -161,15 +161,15 @@ static unsigned int ipv6_confirm(unsigned int hooknum, /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(skb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED_REPLY) - goto out; + return NF_ACCEPT; help = nfct_help(ct); if (!help) - goto out; + return NF_ACCEPT; /* rcu_read_lock()ed by nf_hook_slow */ helper = rcu_dereference(help->helper); if (!helper) - goto out; + return NF_ACCEPT; protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff); @@ -179,12 +179,19 @@ static unsigned int ipv6_confirm(unsigned int hooknum, } ret = helper->help(skb, protoff, ct, ctinfo); - if (ret != NF_ACCEPT) { + if (ret != NF_ACCEPT && (ret & NF_VERDICT_MASK) != NF_QUEUE) { nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL, "nf_ct_%s: dropping packet", helper->name); - return ret; } -out: + return ret; +} + +static unsigned int ipv6_confirm(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ /* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm(skb); } @@ -253,6 +260,13 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_CONNTRACK, }, + { + .hook = ipv6_helper, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP6_PRI_CONNTRACK_HELPER, + }, { .hook = ipv6_confirm, .owner = THIS_MODULE, @@ -260,6 +274,13 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { .hooknum = NF_INET_POST_ROUTING, .priority = NF_IP6_PRI_LAST, }, + { + .hook = ipv6_helper, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_LOCAL_IN, + .priority = NF_IP6_PRI_CONNTRACK_HELPER, + }, { .hook = ipv6_confirm, .owner = THIS_MODULE, diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 209c1ed43368..aae6c628991d 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -12,6 +12,14 @@ tristate "Netfilter NFACCT over NFNETLINK interface" If this option is enabled, the kernel will include support for extended accounting via NFNETLINK. +config NETFILTER_NETLINK_CTHELPER +tristate "Netfilter CTHELPER over NFNETLINK interface" + depends on NETFILTER_ADVANCED + select NETFILTER_NETLINK + help + If this option is enabled, the kernel will include support + for user-space connection tracking helpers via NFNETLINK. + config NETFILTER_NETLINK_QUEUE tristate "Netfilter NFQUEUE over NFNETLINK interface" depends on NETFILTER_ADVANCED diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 4e7960cc7b97..2f3bc0f647ba 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_NETFILTER) = netfilter.o obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o +obj-$(CONFIG_NETFILTER_NETLINK_CTHELPER) += nfnetlink_cthelper.o obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 9c18ecb0ab81..2918ec2e4509 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -30,8 +30,10 @@ #include static DEFINE_MUTEX(nf_ct_helper_mutex); -static struct hlist_head *nf_ct_helper_hash __read_mostly; -static unsigned int nf_ct_helper_hsize __read_mostly; +struct hlist_head *nf_ct_helper_hash __read_mostly; +EXPORT_SYMBOL_GPL(nf_ct_helper_hash); +unsigned int nf_ct_helper_hsize __read_mostly; +EXPORT_SYMBOL_GPL(nf_ct_helper_hsize); static unsigned int nf_ct_helper_count __read_mostly; static bool nf_ct_auto_assign_helper __read_mostly = true; @@ -322,6 +324,9 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol); int nf_conntrack_helper_register(struct nf_conntrack_helper *me) { + int ret = 0; + struct nf_conntrack_helper *cur; + struct hlist_node *n; unsigned int h = helper_hash(&me->tuple); BUG_ON(me->expect_policy == NULL); @@ -329,11 +334,19 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1); mutex_lock(&nf_ct_helper_mutex); + hlist_for_each_entry(cur, n, &nf_ct_helper_hash[h], hnode) { + if (strncmp(cur->name, me->name, NF_CT_HELPER_NAME_LEN) == 0 && + cur->tuple.src.l3num == me->tuple.src.l3num && + cur->tuple.dst.protonum == me->tuple.dst.protonum) { + ret = -EEXIST; + goto out; + } + } hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]); nf_ct_helper_count++; +out: mutex_unlock(&nf_ct_helper_mutex); - - return 0; + return ret; } EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c new file mode 100644 index 000000000000..d6836193d479 --- /dev/null +++ b/net/netfilter/nfnetlink_cthelper.c @@ -0,0 +1,672 @@ +/* + * (C) 2012 Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation (or any later at your option). + * + * This software has been sponsored by Vyatta Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Pablo Neira Ayuso "); +MODULE_DESCRIPTION("nfnl_cthelper: User-space connection tracking helpers"); + +static int +nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff, + struct nf_conn *ct, enum ip_conntrack_info ctinfo) +{ + const struct nf_conn_help *help; + struct nf_conntrack_helper *helper; + + help = nfct_help(ct); + if (help == NULL) + return NF_DROP; + + /* rcu_read_lock()ed by nf_hook_slow */ + helper = rcu_dereference(help->helper); + if (helper == NULL) + return NF_DROP; + + /* This is an user-space helper not yet configured, skip. */ + if ((helper->flags & + (NF_CT_HELPER_F_USERSPACE | NF_CT_HELPER_F_CONFIGURED)) == + NF_CT_HELPER_F_USERSPACE) + return NF_ACCEPT; + + /* If the user-space helper is not available, don't block traffic. */ + return NF_QUEUE_NR(helper->queue_num) | NF_VERDICT_FLAG_QUEUE_BYPASS; +} + +static const struct nla_policy nfnl_cthelper_tuple_pol[NFCTH_TUPLE_MAX+1] = { + [NFCTH_TUPLE_L3PROTONUM] = { .type = NLA_U16, }, + [NFCTH_TUPLE_L4PROTONUM] = { .type = NLA_U8, }, +}; + +static int +nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, + const struct nlattr *attr) +{ + struct nlattr *tb[NFCTH_TUPLE_MAX+1]; + + nla_parse_nested(tb, NFCTH_TUPLE_MAX, attr, nfnl_cthelper_tuple_pol); + + if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) + return -EINVAL; + + tuple->src.l3num = ntohs(nla_get_u16(tb[NFCTH_TUPLE_L3PROTONUM])); + tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); + + return 0; +} + +static int +nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) +{ + const struct nf_conn_help *help = nfct_help(ct); + + if (help->helper->data_len == 0) + return -EINVAL; + + memcpy(&help->data, nla_data(attr), help->helper->data_len); + return 0; +} + +static int +nfnl_cthelper_to_nlattr(struct sk_buff *skb, const struct nf_conn *ct) +{ + const struct nf_conn_help *help = nfct_help(ct); + + if (help->helper->data_len && + nla_put(skb, CTA_HELP_INFO, help->helper->data_len, &help->data)) + goto nla_put_failure; + + return 0; + +nla_put_failure: + return -ENOSPC; +} + +static const struct nla_policy nfnl_cthelper_expect_pol[NFCTH_POLICY_MAX+1] = { + [NFCTH_POLICY_NAME] = { .type = NLA_NUL_STRING, + .len = NF_CT_HELPER_NAME_LEN-1 }, + [NFCTH_POLICY_EXPECT_MAX] = { .type = NLA_U32, }, + [NFCTH_POLICY_EXPECT_TIMEOUT] = { .type = NLA_U32, }, +}; + +static int +nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy, + const struct nlattr *attr) +{ + struct nlattr *tb[NFCTH_POLICY_MAX+1]; + + nla_parse_nested(tb, NFCTH_POLICY_MAX, attr, nfnl_cthelper_expect_pol); + + if (!tb[NFCTH_POLICY_NAME] || + !tb[NFCTH_POLICY_EXPECT_MAX] || + !tb[NFCTH_POLICY_EXPECT_TIMEOUT]) + return -EINVAL; + + strncpy(expect_policy->name, + nla_data(tb[NFCTH_POLICY_NAME]), NF_CT_HELPER_NAME_LEN); + expect_policy->max_expected = + ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); + expect_policy->timeout = + ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])); + + return 0; +} + +static const struct nla_policy +nfnl_cthelper_expect_policy_set[NFCTH_POLICY_SET_MAX+1] = { + [NFCTH_POLICY_SET_NUM] = { .type = NLA_U32, }, +}; + +static int +nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper, + const struct nlattr *attr) +{ + int i, ret; + struct nf_conntrack_expect_policy *expect_policy; + struct nlattr *tb[NFCTH_POLICY_SET_MAX+1]; + + nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr, + nfnl_cthelper_expect_policy_set); + + if (!tb[NFCTH_POLICY_SET_NUM]) + return -EINVAL; + + helper->expect_class_max = + ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM])); + + if (helper->expect_class_max != 0 && + helper->expect_class_max > NF_CT_MAX_EXPECT_CLASSES) + return -EOVERFLOW; + + expect_policy = kzalloc(sizeof(struct nf_conntrack_expect_policy) * + helper->expect_class_max, GFP_KERNEL); + if (expect_policy == NULL) + return -ENOMEM; + + for (i=0; iexpect_class_max; i++) { + if (!tb[NFCTH_POLICY_SET+i]) + goto err; + + ret = nfnl_cthelper_expect_policy(&expect_policy[i], + tb[NFCTH_POLICY_SET+i]); + if (ret < 0) + goto err; + } + helper->expect_policy = expect_policy; + return 0; +err: + kfree(expect_policy); + return -EINVAL; +} + +static int +nfnl_cthelper_create(const struct nlattr * const tb[], + struct nf_conntrack_tuple *tuple) +{ + struct nf_conntrack_helper *helper; + int ret; + + if (!tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_PRIV_DATA_LEN]) + return -EINVAL; + + helper = kzalloc(sizeof(struct nf_conntrack_helper), GFP_KERNEL); + if (helper == NULL) + return -ENOMEM; + + ret = nfnl_cthelper_parse_expect_policy(helper, tb[NFCTH_POLICY]); + if (ret < 0) + goto err; + + strncpy(helper->name, nla_data(tb[NFCTH_NAME]), NF_CT_HELPER_NAME_LEN); + helper->data_len = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); + helper->flags |= NF_CT_HELPER_F_USERSPACE; + memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple)); + + helper->me = THIS_MODULE; + helper->help = nfnl_userspace_cthelper; + helper->from_nlattr = nfnl_cthelper_from_nlattr; + helper->to_nlattr = nfnl_cthelper_to_nlattr; + + /* Default to queue number zero, this can be updated at any time. */ + if (tb[NFCTH_QUEUE_NUM]) + helper->queue_num = ntohl(nla_get_be32(tb[NFCTH_QUEUE_NUM])); + + if (tb[NFCTH_STATUS]) { + int status = ntohl(nla_get_be32(tb[NFCTH_STATUS])); + + switch(status) { + case NFCT_HELPER_STATUS_ENABLED: + helper->flags |= NF_CT_HELPER_F_CONFIGURED; + break; + case NFCT_HELPER_STATUS_DISABLED: + helper->flags &= ~NF_CT_HELPER_F_CONFIGURED; + break; + } + } + + ret = nf_conntrack_helper_register(helper); + if (ret < 0) + goto err; + + return 0; +err: + kfree(helper); + return ret; +} + +static int +nfnl_cthelper_update(const struct nlattr * const tb[], + struct nf_conntrack_helper *helper) +{ + int ret; + + if (tb[NFCTH_PRIV_DATA_LEN]) + return -EBUSY; + + if (tb[NFCTH_POLICY]) { + ret = nfnl_cthelper_parse_expect_policy(helper, + tb[NFCTH_POLICY]); + if (ret < 0) + return ret; + } + if (tb[NFCTH_QUEUE_NUM]) + helper->queue_num = ntohl(nla_get_be32(tb[NFCTH_QUEUE_NUM])); + + if (tb[NFCTH_STATUS]) { + int status = ntohl(nla_get_be32(tb[NFCTH_STATUS])); + + switch(status) { + case NFCT_HELPER_STATUS_ENABLED: + helper->flags |= NF_CT_HELPER_F_CONFIGURED; + break; + case NFCT_HELPER_STATUS_DISABLED: + helper->flags &= ~NF_CT_HELPER_F_CONFIGURED; + break; + } + } + return 0; +} + +static int +nfnl_cthelper_new(struct sock *nfnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, const struct nlattr * const tb[]) +{ + const char *helper_name; + struct nf_conntrack_helper *cur, *helper = NULL; + struct nf_conntrack_tuple tuple; + struct hlist_node *n; + int ret = 0, i; + + if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE]) + return -EINVAL; + + helper_name = nla_data(tb[NFCTH_NAME]); + + ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]); + if (ret < 0) + return ret; + + rcu_read_lock(); + for (i = 0; i < nf_ct_helper_hsize && !helper; i++) { + hlist_for_each_entry_rcu(cur, n, &nf_ct_helper_hash[i], hnode) { + + /* skip non-userspace conntrack helpers. */ + if (!(cur->flags & NF_CT_HELPER_F_USERSPACE)) + continue; + + if (strncmp(cur->name, helper_name, + NF_CT_HELPER_NAME_LEN) != 0) + continue; + + if ((tuple.src.l3num != cur->tuple.src.l3num || + tuple.dst.protonum != cur->tuple.dst.protonum)) + continue; + + if (nlh->nlmsg_flags & NLM_F_EXCL) { + ret = -EEXIST; + goto err; + } + helper = cur; + break; + } + } + rcu_read_unlock(); + + if (helper == NULL) + ret = nfnl_cthelper_create(tb, &tuple); + else + ret = nfnl_cthelper_update(tb, helper); + + return ret; +err: + rcu_read_unlock(); + return ret; +} + +static int +nfnl_cthelper_dump_tuple(struct sk_buff *skb, + struct nf_conntrack_helper *helper) +{ + struct nlattr *nest_parms; + + nest_parms = nla_nest_start(skb, NFCTH_TUPLE | NLA_F_NESTED); + if (nest_parms == NULL) + goto nla_put_failure; + + if (nla_put_be16(skb, NFCTH_TUPLE_L3PROTONUM, + htons(helper->tuple.src.l3num))) + goto nla_put_failure; + + if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->tuple.dst.protonum)) + goto nla_put_failure; + + nla_nest_end(skb, nest_parms); + return 0; + +nla_put_failure: + return -1; +} + +static int +nfnl_cthelper_dump_policy(struct sk_buff *skb, + struct nf_conntrack_helper *helper) +{ + int i; + struct nlattr *nest_parms1, *nest_parms2; + + nest_parms1 = nla_nest_start(skb, NFCTH_POLICY | NLA_F_NESTED); + if (nest_parms1 == NULL) + goto nla_put_failure; + + if (nla_put_be32(skb, NFCTH_POLICY_SET_NUM, + htonl(helper->expect_class_max))) + goto nla_put_failure; + + for (i=0; iexpect_class_max; i++) { + nest_parms2 = nla_nest_start(skb, + (NFCTH_POLICY_SET+i) | NLA_F_NESTED); + if (nest_parms2 == NULL) + goto nla_put_failure; + + if (nla_put_string(skb, NFCTH_POLICY_NAME, + helper->expect_policy[i].name)) + goto nla_put_failure; + + if (nla_put_be32(skb, NFCTH_POLICY_EXPECT_MAX, + htonl(helper->expect_policy[i].max_expected))) + goto nla_put_failure; + + if (nla_put_be32(skb, NFCTH_POLICY_EXPECT_TIMEOUT, + htonl(helper->expect_policy[i].timeout))) + goto nla_put_failure; + + nla_nest_end(skb, nest_parms2); + } + nla_nest_end(skb, nest_parms1); + return 0; + +nla_put_failure: + return -1; +} + +static int +nfnl_cthelper_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type, + int event, struct nf_conntrack_helper *helper) +{ + struct nlmsghdr *nlh; + struct nfgenmsg *nfmsg; + unsigned int flags = pid ? NLM_F_MULTI : 0; + int status; + + event |= NFNL_SUBSYS_CTHELPER << 8; + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); + if (nlh == NULL) + goto nlmsg_failure; + + nfmsg = nlmsg_data(nlh); + nfmsg->nfgen_family = AF_UNSPEC; + nfmsg->version = NFNETLINK_V0; + nfmsg->res_id = 0; + + if (nla_put_string(skb, NFCTH_NAME, helper->name)) + goto nla_put_failure; + + if (nla_put_be32(skb, NFCTH_QUEUE_NUM, htonl(helper->queue_num))) + goto nla_put_failure; + + if (nfnl_cthelper_dump_tuple(skb, helper) < 0) + goto nla_put_failure; + + if (nfnl_cthelper_dump_policy(skb, helper) < 0) + goto nla_put_failure; + + if (nla_put_be32(skb, NFCTH_PRIV_DATA_LEN, htonl(helper->data_len))) + goto nla_put_failure; + + if (helper->flags & NF_CT_HELPER_F_CONFIGURED) + status = NFCT_HELPER_STATUS_ENABLED; + else + status = NFCT_HELPER_STATUS_DISABLED; + + if (nla_put_be32(skb, NFCTH_STATUS, htonl(status))) + goto nla_put_failure; + + nlmsg_end(skb, nlh); + return skb->len; + +nlmsg_failure: +nla_put_failure: + nlmsg_cancel(skb, nlh); + return -1; +} + +static int +nfnl_cthelper_dump_table(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct nf_conntrack_helper *cur, *last; + struct hlist_node *n; + + rcu_read_lock(); + last = (struct nf_conntrack_helper *)cb->args[1]; + for (; cb->args[0] < nf_ct_helper_hsize; cb->args[0]++) { +restart: + hlist_for_each_entry_rcu(cur, n, + &nf_ct_helper_hash[cb->args[0]], hnode) { + + /* skip non-userspace conntrack helpers. */ + if (!(cur->flags & NF_CT_HELPER_F_USERSPACE)) + continue; + + if (cb->args[1]) { + if (cur != last) + continue; + cb->args[1] = 0; + } + if (nfnl_cthelper_fill_info(skb, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, + NFNL_MSG_TYPE(cb->nlh->nlmsg_type), + NFNL_MSG_CTHELPER_NEW, cur) < 0) { + cb->args[1] = (unsigned long)cur; + goto out; + } + } + } + if (cb->args[1]) { + cb->args[1] = 0; + goto restart; + } +out: + rcu_read_unlock(); + return skb->len; +} + +static int +nfnl_cthelper_get(struct sock *nfnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, const struct nlattr * const tb[]) +{ + int ret = -ENOENT, i; + struct nf_conntrack_helper *cur; + struct hlist_node *n; + struct sk_buff *skb2; + char *helper_name = NULL; + struct nf_conntrack_tuple tuple; + bool tuple_set = false; + + if (nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { + .dump = nfnl_cthelper_dump_table, + }; + return netlink_dump_start(nfnl, skb, nlh, &c); + } + + if (tb[NFCTH_NAME]) + helper_name = nla_data(tb[NFCTH_NAME]); + + if (tb[NFCTH_TUPLE]) { + ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]); + if (ret < 0) + return ret; + + tuple_set = true; + } + + for (i = 0; i < nf_ct_helper_hsize; i++) { + hlist_for_each_entry_rcu(cur, n, &nf_ct_helper_hash[i], hnode) { + + /* skip non-userspace conntrack helpers. */ + if (!(cur->flags & NF_CT_HELPER_F_USERSPACE)) + continue; + + if (helper_name && strncmp(cur->name, helper_name, + NF_CT_HELPER_NAME_LEN) != 0) { + continue; + } + if (tuple_set && + (tuple.src.l3num != cur->tuple.src.l3num || + tuple.dst.protonum != cur->tuple.dst.protonum)) + continue; + + skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (skb2 == NULL) { + ret = -ENOMEM; + break; + } + + ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).pid, + nlh->nlmsg_seq, + NFNL_MSG_TYPE(nlh->nlmsg_type), + NFNL_MSG_CTHELPER_NEW, cur); + if (ret <= 0) { + kfree_skb(skb2); + break; + } + + ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).pid, + MSG_DONTWAIT); + if (ret > 0) + ret = 0; + + /* this avoids a loop in nfnetlink. */ + return ret == -EAGAIN ? -ENOBUFS : ret; + } + } + return ret; +} + +static int +nfnl_cthelper_del(struct sock *nfnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, const struct nlattr * const tb[]) +{ + char *helper_name = NULL; + struct nf_conntrack_helper *cur; + struct hlist_node *n, *tmp; + struct nf_conntrack_tuple tuple; + bool tuple_set = false, found = false; + int i, j = 0, ret; + + if (tb[NFCTH_NAME]) + helper_name = nla_data(tb[NFCTH_NAME]); + + if (tb[NFCTH_TUPLE]) { + ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]); + if (ret < 0) + return ret; + + tuple_set = true; + } + + for (i = 0; i < nf_ct_helper_hsize; i++) { + hlist_for_each_entry_safe(cur, n, tmp, &nf_ct_helper_hash[i], + hnode) { + /* skip non-userspace conntrack helpers. */ + if (!(cur->flags & NF_CT_HELPER_F_USERSPACE)) + continue; + + j++; + + if (helper_name && strncmp(cur->name, helper_name, + NF_CT_HELPER_NAME_LEN) != 0) { + continue; + } + if (tuple_set && + (tuple.src.l3num != cur->tuple.src.l3num || + tuple.dst.protonum != cur->tuple.dst.protonum)) + continue; + + found = true; + nf_conntrack_helper_unregister(cur); + } + } + /* Make sure we return success if we flush and there is no helpers */ + return (found || j == 0) ? 0 : -ENOENT; +} + +static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = { + [NFCTH_NAME] = { .type = NLA_NUL_STRING, + .len = NF_CT_HELPER_NAME_LEN-1 }, + [NFCTH_QUEUE_NUM] = { .type = NLA_U32, }, +}; + +static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = { + [NFNL_MSG_CTHELPER_NEW] = { .call = nfnl_cthelper_new, + .attr_count = NFCTH_MAX, + .policy = nfnl_cthelper_policy }, + [NFNL_MSG_CTHELPER_GET] = { .call = nfnl_cthelper_get, + .attr_count = NFCTH_MAX, + .policy = nfnl_cthelper_policy }, + [NFNL_MSG_CTHELPER_DEL] = { .call = nfnl_cthelper_del, + .attr_count = NFCTH_MAX, + .policy = nfnl_cthelper_policy }, +}; + +static const struct nfnetlink_subsystem nfnl_cthelper_subsys = { + .name = "cthelper", + .subsys_id = NFNL_SUBSYS_CTHELPER, + .cb_count = NFNL_MSG_CTHELPER_MAX, + .cb = nfnl_cthelper_cb, +}; + +MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTHELPER); + +static int __init nfnl_cthelper_init(void) +{ + int ret; + + ret = nfnetlink_subsys_register(&nfnl_cthelper_subsys); + if (ret < 0) { + pr_err("nfnl_cthelper: cannot register with nfnetlink.\n"); + goto err_out; + } + return 0; +err_out: + return ret; +} + +static void __exit nfnl_cthelper_exit(void) +{ + struct nf_conntrack_helper *cur; + struct hlist_node *n, *tmp; + int i; + + nfnetlink_subsys_unregister(&nfnl_cthelper_subsys); + + for (i=0; iflags & NF_CT_HELPER_F_USERSPACE)) + continue; + + nf_conntrack_helper_unregister(cur); + } + } +} + +module_init(nfnl_cthelper_init); +module_exit(nfnl_cthelper_exit); -- GitLab From 667d1b48bcb66b89776ebefbaf05b358bc5907ce Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 15 Jun 2012 16:49:58 +0100 Subject: [PATCH 1741/6849] ARM: 7425/1: extable: ensure fixup entries are 4-byte aligned Fixup entries in the kernel exception tables should be 4-byte aligned since we return directly to them when handling a faulting instruction in the kernel. This patch adds the missing align directives to the fixup entries. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/futex.h | 1 + arch/arm/kernel/entry-armv.S | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 7be54690aeec..e42cf597f6e6 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -19,6 +19,7 @@ " .long 1b, 4f, 2b, 4f\n" \ " .popsection\n" \ " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ "4: mov %0, " err_reg "\n" \ " b 3b\n" \ " .popsection" diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 437f0c426517..0d1851ca6eb9 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -495,6 +495,7 @@ ENDPROC(__und_usr) * The out of line fixup for the ldrt above. */ .pushsection .fixup, "ax" + .align 2 4: mov pc, r9 .popsection .pushsection __ex_table,"a" -- GitLab From 4a77a5a06ec66ed05199b301e7c25f42f979afdc Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Sat, 16 Jun 2012 21:21:51 +0800 Subject: [PATCH 1742/6849] printk: use mutex lock to stop syslog_seq from going wild Although syslog_seq and log_next_seq stuff are protected by logbuf_lock spin log, it's not enough. Say we have two processes A and B, and let syslog_seq = N, while log_next_seq = N + 1, and the two processes both come to syslog_print at almost the same time. And No matter which process get the spin lock first, it will increase syslog_seq by one, then release spin lock; thus later, another process increase syslog_seq by one again. In this case, syslog_seq is bigger than syslog_next_seq. And latter, it would make: wait_event_interruptiable(log_wait, syslog != log_next_seq) don't wait any more even there is no new write comes. Thus it introduce a infinite loop reading. I can easily see this kind of issue by the following steps: # cat /proc/kmsg # at meantime, I don't kill rsyslog # So they are the two processes. # xinit # I added drm.debug=6 in the kernel parameter line, # so that it will produce lots of message and let that # issue happen It's 100% reproducable on my side. And my disk will be filled up by /var/log/messages in a quite short time. So, introduce a mutex_lock to stop syslog_seq from going wild just like what devkmsg_read() does. It does fix this issue as expected. v2: use mutex_lock_interruptiable() instead (comments from Kay) Signed-off-by: Yuanhan Liu Reviewed-by: Fengguang Wu Acked-By: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index ceb4a2f775a1..572730bd8a5c 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -414,7 +414,9 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, if (!user) return -EBADF; - mutex_lock(&user->lock); + ret = mutex_lock_interruptible(&user->lock); + if (ret) + return ret; raw_spin_lock(&logbuf_lock); while (user->seq == log_next_seq) { if (file->f_flags & O_NONBLOCK) { @@ -976,6 +978,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) { bool clear = false; static int saved_console_loglevel = -1; + static DEFINE_MUTEX(syslog_mutex); int error; error = check_syslog_permissions(type, from_file); @@ -1002,11 +1005,17 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) error = -EFAULT; goto out; } + error = mutex_lock_interruptible(&syslog_mutex); + if (error) + goto out; error = wait_event_interruptible(log_wait, syslog_seq != log_next_seq); - if (error) + if (error) { + mutex_unlock(&syslog_mutex); goto out; + } error = syslog_print(buf, len); + mutex_unlock(&syslog_mutex); break; /* Read/clear last kernel messages */ case SYSLOG_ACTION_READ_CLEAR: -- GitLab From b56a39ac263e5b8cafedd551a49c2105e68b98c2 Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Sat, 16 Jun 2012 12:40:55 +0800 Subject: [PATCH 1743/6849] printk: return -EINVAL if the message len is bigger than the buf size Just like what devkmsg_read() does, return -EINVAL if the message len is bigger than the buf size, or it will trigger a segfault error. Acked-by: Kay Sievers Acked-by: Fengguang Wu Signed-off-by: Yuanhan Liu Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index 572730bd8a5c..a2276b916769 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -880,7 +880,9 @@ static int syslog_print(char __user *buf, int size) syslog_seq++; raw_spin_unlock_irq(&logbuf_lock); - if (len > 0 && copy_to_user(buf, text, len)) + if (len > size) + len = -EINVAL; + else if (len > 0 && copy_to_user(buf, text, len)) len = -EFAULT; kfree(text); -- GitLab From 492bf4f25a1c8e87a6abb0e2edaa532b7fd43b29 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:24 +0200 Subject: [PATCH 1744/6849] powerpc/PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Cc: Kumar Gala Cc: Paul Mackerras Acked-by: Benjamin Herrenschmidt Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- arch/powerpc/platforms/85xx/tqm85xx.c | 2 +- arch/powerpc/platforms/86xx/gef_ppc9a.c | 2 +- arch/powerpc/platforms/86xx/gef_sbc310.c | 2 +- arch/powerpc/platforms/86xx/gef_sbc610.c | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- arch/powerpc/sysdev/mv64x60_pci.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 4d786c25d3e5..3e70a2035e53 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c @@ -102,7 +102,7 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); } -static void __init tqm85xx_ti1520_fixup(struct pci_dev *pdev) +static void __devinit tqm85xx_ti1520_fixup(struct pci_dev *pdev) { unsigned int val; diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index 1fca663f1b25..563aafa8629c 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c @@ -164,7 +164,7 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m) gef_ppc9a_get_vme_is_syscon() ? "yes" : "no"); } -static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev) +static void __devinit gef_ppc9a_nec_fixup(struct pci_dev *pdev) { unsigned int val; diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 14e0e576bcbd..cc6a91ae0889 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -152,7 +152,7 @@ static void gef_sbc310_show_cpuinfo(struct seq_file *m) } -static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev) +static void __devinit gef_sbc310_nec_fixup(struct pci_dev *pdev) { unsigned int val; diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 1638f43599f0..aead6b337f4a 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -141,7 +141,7 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m) seq_printf(m, "SVR\t\t: 0x%x\n", svid); } -static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev) +static void __devinit gef_sbc610_nec_fixup(struct pci_dev *pdev) { unsigned int val; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 6073288fed29..edbf79465d50 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -36,7 +36,7 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci; -static void __init quirk_fsl_pcie_header(struct pci_dev *dev) +static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev) { u8 progif; diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index b0037cefaada..364b14d4754b 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -104,7 +104,7 @@ subsys_initcall(mv64x60_sysfs_init); #endif /* CONFIG_SYSFS */ -static void __init mv64x60_pci_fixup_early(struct pci_dev *dev) +static void __devinit mv64x60_pci_fixup_early(struct pci_dev *dev) { /* * Set the host bridge hdr_type to an invalid value so that -- GitLab From 1359bac229637cd9e317f6069e5fb3544d64b7ca Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:25 +0200 Subject: [PATCH 1745/6849] sh/PCI: move fixup hooks from __init to __devinit The fixups are executed once the pci-device is found which is during boot process so __init seems fine as long as the platform does not support hotplug. However it is possible to remove the PCI bus at run time and have it rediscovered again via "echo 1 > /sys/bus/pci/rescan" and this will call the fixups again. Cc: Paul Mundt Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- arch/sh/drivers/pci/fixups-dreamcast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index edeea8960c30..a5fe1b54c952 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -28,7 +28,7 @@ #include #include -static void __init gapspci_fixup_resources(struct pci_dev *dev) +static void __devinit gapspci_fixup_resources(struct pci_dev *dev) { struct pci_channel *p = dev->sysdata; -- GitLab From bb15d8db7cce766b62cab624120916d25e94ac7a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 3 Jun 2012 20:48:17 +0200 Subject: [PATCH 1746/6849] scripts/modpost: check for bad references in .pci.fixups area Functions used for PCI fixups (like DECLARE_PCI_FIXUP_HEADER) are often marked __init. This is okay as long as nobody is using PCI hotplug. However if one does execute | echo 1 > /sys/bus/pci/rescan and we hit a module which is marked __init istead of __devinit then we go boom because the code is removed after the kernel booted. This patch help to see those section mismatches. Cc: Michal Marek Cc: linux-kbuild@vger.kernel.org Cc: Rusty Russell Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Bjorn Helgaas --- scripts/mod/modpost.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0f84bb38eb0d..68e9f5ed0a6f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -865,6 +865,11 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_EXIT_TEXT_SECTIONS \ ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" +#define ALL_PCI_INIT_SECTIONS \ + ".pci_fixup_early$", ".pci_fixup_header$", ".pci_fixup_final$", \ + ".pci_fixup_enable$", ".pci_fixup_resume$", \ + ".pci_fixup_resume_early$", ".pci_fixup_suspend$" + #define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \ MEM_INIT_SECTIONS #define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \ @@ -1027,6 +1032,12 @@ const struct sectioncheck sectioncheck[] = { .mismatch = ANY_EXIT_TO_ANY_INIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, +{ + .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, + .tosec = { INIT_SECTIONS, NULL }, + .mismatch = ANY_INIT_TO_ANY_EXIT, + .symbol_white_list = { NULL }, +}, /* Do not export init/exit functions or data */ { .fromsec = { "__ksymtab*", NULL }, -- GitLab From fbebb9fd22581b6422d60669c4ff86ce99d6cdba Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Sat, 16 Jun 2012 14:40:22 -0600 Subject: [PATCH 1747/6849] PCI: add infrastructure for devices with broken INTx masking pci_intx_mask_supported() assumes INTx masking is supported if the PCI_COMMAND_INTX_DISABLE bit is writable. But when that bit is set, some devices don't actually mask INTx or update PCI_STATUS_INTERRUPT as we expect. This patch adds a way for quirks to identify these broken devices. [bhelgaas: split out from Chelsio quirk addition] Signed-off-by: Jan Kiszka Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 3 +++ drivers/pci/quirks.c | 10 ++++++++++ include/linux/pci.h | 1 + 3 files changed, 14 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..9ae517a68360 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2876,6 +2876,9 @@ bool pci_intx_mask_supported(struct pci_dev *dev) bool mask_supported = false; u16 orig, new; + if (dev->broken_intx_masking) + return false; + pci_cfg_access_lock(dev); pci_read_config_word(dev, PCI_COMMAND, &orig); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2a7521677541..cc13415416d7 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2929,6 +2929,16 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); +/* + * Some devices may pass our check in pci_intx_mask_supported if + * PCI_COMMAND_INTX_DISABLE works though they actually do not properly + * support this feature. + */ +static void __devinit quirk_broken_intx_masking(struct pci_dev *dev) +{ + dev->broken_intx_masking = 1; +} + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..40a039f1dffb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -324,6 +324,7 @@ struct pci_dev { unsigned int is_hotplug_bridge:1; unsigned int __aer_firmware_first_valid:1; unsigned int __aer_firmware_first:1; + unsigned int broken_intx_masking:1; pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ -- GitLab From 7f95e1880e70bb351b992b01ef70ff083fc00d30 Mon Sep 17 00:00:00 2001 From: Eldad Zack Date: Sat, 16 Jun 2012 15:14:49 +0200 Subject: [PATCH 1748/6849] include/net/dst.h: neaten asterisk placement Fix code style - place the asterisk where it belongs. Signed-off-by: Eldad Zack Signed-off-by: David S. Miller --- include/net/dst.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 8197eadca819..f0bf3b8d5911 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -48,8 +48,8 @@ struct dst_entry { #else void *__pad1; #endif - int (*input)(struct sk_buff*); - int (*output)(struct sk_buff*); + int (*input)(struct sk_buff *); + int (*output)(struct sk_buff *); int flags; #define DST_HOST 0x0001 @@ -241,7 +241,7 @@ dst_metric_locked(const struct dst_entry *dst, int metric) return dst_metric(dst, RTAX_LOCK) & (1<lastuse = time; } -static inline -struct dst_entry * dst_clone(struct dst_entry * dst) +static inline struct dst_entry *dst_clone(struct dst_entry *dst) { if (dst) atomic_inc(&dst->__refcnt); @@ -371,12 +370,12 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) } extern int dst_discard(struct sk_buff *skb); -extern void *dst_alloc(struct dst_ops * ops, struct net_device *dev, +extern void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, int initial_obsolete, int flags); -extern void __dst_free(struct dst_entry * dst); -extern struct dst_entry *dst_destroy(struct dst_entry * dst); +extern void __dst_free(struct dst_entry *dst); +extern struct dst_entry *dst_destroy(struct dst_entry *dst); -static inline void dst_free(struct dst_entry * dst) +static inline void dst_free(struct dst_entry *dst) { if (dst->obsolete > 1) return; -- GitLab From 9b0f7e399238c61f28539daeb65d72a8d7f91966 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 11 Jun 2012 09:03:58 -0500 Subject: [PATCH 1749/6849] arm: versatile: fix and enable PCI I/O space With commit 4d5fc58dbe34b (ARM: remove bunch of now unused mach/io.h files), the I/O space setup was completely broken on versatile. This patch fixes that and prepares for further I/O space clean-up. I/O space handling on the versatile platform is currently broken in multiple ways. Most importantly, the ports do not get mapped into the virtual address space at all. Also, there is some amount of confusion between PCI I/O space and other statically mapped MMIO registers in the platform code: * The __io_address() macro that is used to access the platform register maps to the same __io macro that gets used for I/O space. * The IO_SPACE_LIMIT is set to a value that is much larger than the total available space. * The I/O resource of the PCI bus is set to the physical address of the mapping, which is way outside of the actual I/O space limit as well as the address range that gets decoded by traditional PCI cards. * No attempt is made to stay outside of the ISA port range that some device drivers try access. * No resource gets requested as a child of ioport_resource, but an IORESOURCE_IO type mapping gets requested as a child of iomem_resource. This patch attempts to correct all of the above. This makes it possible to use virtio-pci based virtual devices as well as actual PCI cards including those with legacy ISA port ranges like VGA. Some of the issues seem to be duplicated on other platforms. Signed-off-by: Arnd Bergmann [rob: update to 3.5-rc2 and io.h cleanup related changes] Signed-off-by: Rob Herring Tested-by: Robert Schwebel Signed-off-by: Olof Johansson --- arch/arm/Kconfig | 1 + arch/arm/mach-versatile/core.c | 19 +++---------- .../mach-versatile/include/mach/hardware.h | 3 ++- arch/arm/mach-versatile/include/mach/io.h | 27 +++++++++++++++++++ arch/arm/mach-versatile/pci.c | 18 +++++++++++-- 5 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 arch/arm/mach-versatile/include/mach/io.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b649c5904a4f..567b4323c9e6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -294,6 +294,7 @@ config ARCH_VERSATILE select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select NEED_MACH_IO_H if PCI select PLAT_VERSATILE select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_FPGA_IRQ diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index cf4687ee2a7b..cd8ea3588f93 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -169,26 +169,13 @@ static struct map_desc versatile_io_desc[] __initdata = { .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), .length = VERSATILE_PCI_CFG_BASE_SIZE, .type = MT_DEVICE - }, -#if 0 - { - .virtual = VERSATILE_PCI_VIRT_MEM_BASE0, - .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), - .length = SZ_16M, - .type = MT_DEVICE }, { - .virtual = VERSATILE_PCI_VIRT_MEM_BASE1, - .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), - .length = SZ_16M, - .type = MT_DEVICE - }, { - .virtual = VERSATILE_PCI_VIRT_MEM_BASE2, - .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2), - .length = SZ_16M, + .virtual = (unsigned long)VERSATILE_PCI_VIRT_MEM_BASE0, + .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), + .length = IO_SPACE_LIMIT, .type = MT_DEVICE }, #endif -#endif }; void __init versatile_map_io(void) diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h index 4d4973dd8fba..408e58da46c6 100644 --- a/arch/arm/mach-versatile/include/mach/hardware.h +++ b/arch/arm/mach-versatile/include/mach/hardware.h @@ -29,8 +29,9 @@ */ #define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul #define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul +#define VERSATILE_PCI_VIRT_MEM_BASE0 (void __iomem *)PCIO_BASE -/* macro to get at IO space when running virtually */ +/* macro to get at MMIO space when running virtually */ #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) #define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n)) diff --git a/arch/arm/mach-versatile/include/mach/io.h b/arch/arm/mach-versatile/include/mach/io.h new file mode 100644 index 000000000000..0406513be7d8 --- /dev/null +++ b/arch/arm/mach-versatile/include/mach/io.h @@ -0,0 +1,27 @@ +/* + * arch/arm/mach-versatile/include/mach/io.h + * + * Copyright (C) 2003 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define PCIO_BASE 0xeb000000ul + +#define __io(a) ((a) + PCIO_BASE) + +#endif diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 15c6a00000ec..bec933b04ef0 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -169,11 +169,18 @@ static struct pci_ops pci_versatile_ops = { .write = versatile_write_config, }; +static struct resource io_port = { + .name = "PCI", + .start = 0, + .end = IO_SPACE_LIMIT, + .flags = IORESOURCE_IO, +}; + static struct resource io_mem = { .name = "PCI I/O space", .start = VERSATILE_PCI_MEM_BASE0, .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_MEM, }; static struct resource non_mem = { @@ -200,6 +207,12 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) "memory region (%d)\n", ret); goto out; } + ret = request_resource(&ioport_resource, &io_port); + if (ret) { + printk(KERN_ERR "PCI: unable to allocate I/O " + "port region (%d)\n", ret); + goto out; + } ret = request_resource(&iomem_resource, &non_mem); if (ret) { printk(KERN_ERR "PCI: unable to allocate non-prefetchable " @@ -218,7 +231,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); + pci_add_resource_offset(&sys->resources, &io_port, sys->io_offset); pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); @@ -249,6 +262,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) if (nr == 0) { sys->mem_offset = 0; + sys->io_offset = 0; ret = pci_versatile_setup_resources(sys); if (ret < 0) { printk("pci_versatile_setup: resources... oops?\n"); -- GitLab From 128789a8293653a4f889f2b1601eea07c00ff65e Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 13 Jun 2012 14:52:45 +0200 Subject: [PATCH 1750/6849] ARM: Kirkwood: Fix clk problems modular ethernet driver When the ethernet driver was built as a module, it would lock the machine when loaded. At boot the ethernet clks are unused, so get turned off. Later, when the module is loaded, the probe function would access the hardware before the clock was restarted, and the machine would lock. It has also been determined that when the clk is turned off, the interface forgets its MAC address, which for most systems, is set by the boot loader. When the machine setup file creates a platform device for the interface, prepare and enable the clock for the interface. This will ensure it is not turned off. However, if the setup file only instantiates one platform device, the other will have its clk disabled, thus maybe saving a little power. Report-by: Simon Baatz Signed-off-by: Andrew Lunn Tested-by: Simon Baatz Signed-off-by: Olof Johansson --- arch/arm/mach-kirkwood/common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 25fb3fd418ef..e1d2c6def5e6 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -193,9 +193,11 @@ static struct clk __init *kirkwood_register_gate_fn(const char *name, bit_idx, 0, &gating_lock, fn); } +static struct clk *ge0, *ge1; + void __init kirkwood_clk_init(void) { - struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; + struct clk *runit, *sata0, *sata1, *usb0, *sdio; struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, @@ -257,6 +259,9 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) orion_ge00_init(eth_data, GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, IRQ_KIRKWOOD_GE00_ERR); + /* The interface forgets the MAC address assigned by u-boot if + the clock is turned off, so claim the clk now. */ + clk_prepare_enable(ge0); } @@ -268,6 +273,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) orion_ge01_init(eth_data, GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, IRQ_KIRKWOOD_GE01_ERR); + clk_prepare_enable(ge1); } -- GitLab From 555069dad01c955f41593711ce2a688c668f8234 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 16 Jun 2012 15:45:41 +0000 Subject: [PATCH 1751/6849] bnx2: Dump all FTQ_CTL registers during tx_timeout to help debug tx timeouts reported in the field. Reviewed-by Benjamin Li Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 71 ++++++++++++++++++++++++++++ drivers/net/ethernet/broadcom/bnx2.h | 41 ++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index ff5d3c1f1217..8eaab0ce220a 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -6405,6 +6406,75 @@ bnx2_reset_task(struct work_struct *work) rtnl_unlock(); } +#define BNX2_FTQ_ENTRY(ftq) { __stringify(ftq##FTQ_CTL), BNX2_##ftq##FTQ_CTL } + +static void +bnx2_dump_ftq(struct bnx2 *bp) +{ + int i; + u32 reg, bdidx, cid, valid; + struct net_device *dev = bp->dev; + static const struct ftq_reg { + char *name; + u32 off; + } ftq_arr[] = { + BNX2_FTQ_ENTRY(RV2P_P), + BNX2_FTQ_ENTRY(RV2P_T), + BNX2_FTQ_ENTRY(RV2P_M), + BNX2_FTQ_ENTRY(TBDR_), + BNX2_FTQ_ENTRY(TDMA_), + BNX2_FTQ_ENTRY(TXP_), + BNX2_FTQ_ENTRY(TXP_), + BNX2_FTQ_ENTRY(TPAT_), + BNX2_FTQ_ENTRY(RXP_C), + BNX2_FTQ_ENTRY(RXP_), + BNX2_FTQ_ENTRY(COM_COMXQ_), + BNX2_FTQ_ENTRY(COM_COMTQ_), + BNX2_FTQ_ENTRY(COM_COMQ_), + BNX2_FTQ_ENTRY(CP_CPQ_), + }; + + netdev_err(dev, "<--- start FTQ dump --->\n"); + for (i = 0; i < ARRAY_SIZE(ftq_arr); i++) + netdev_err(dev, "%s %08x\n", ftq_arr[i].name, + bnx2_reg_rd_ind(bp, ftq_arr[i].off)); + + netdev_err(dev, "CPU states:\n"); + for (reg = BNX2_TXP_CPU_MODE; reg <= BNX2_CP_CPU_MODE; reg += 0x40000) + netdev_err(dev, "%06x mode %x state %x evt_mask %x pc %x pc %x instr %x\n", + reg, bnx2_reg_rd_ind(bp, reg), + bnx2_reg_rd_ind(bp, reg + 4), + bnx2_reg_rd_ind(bp, reg + 8), + bnx2_reg_rd_ind(bp, reg + 0x1c), + bnx2_reg_rd_ind(bp, reg + 0x1c), + bnx2_reg_rd_ind(bp, reg + 0x20)); + + netdev_err(dev, "<--- end FTQ dump --->\n"); + netdev_err(dev, "<--- start TBDC dump --->\n"); + netdev_err(dev, "TBDC free cnt: %ld\n", + REG_RD(bp, BNX2_TBDC_STATUS) & BNX2_TBDC_STATUS_FREE_CNT); + netdev_err(dev, "LINE CID BIDX CMD VALIDS\n"); + for (i = 0; i < 0x20; i++) { + int j = 0; + + REG_WR(bp, BNX2_TBDC_BD_ADDR, i); + REG_WR(bp, BNX2_TBDC_CAM_OPCODE, + BNX2_TBDC_CAM_OPCODE_OPCODE_CAM_READ); + REG_WR(bp, BNX2_TBDC_COMMAND, BNX2_TBDC_COMMAND_CMD_REG_ARB); + while ((REG_RD(bp, BNX2_TBDC_COMMAND) & + BNX2_TBDC_COMMAND_CMD_REG_ARB) && j < 100) + j++; + + cid = REG_RD(bp, BNX2_TBDC_CID); + bdidx = REG_RD(bp, BNX2_TBDC_BIDX); + valid = REG_RD(bp, BNX2_TBDC_CAM_OPCODE); + netdev_err(dev, "%02x %06x %04lx %02x [%x]\n", + i, cid, bdidx & BNX2_TBDC_BDIDX_BDIDX, + bdidx >> 24, (valid >> 8) & 0x0ff); + } + netdev_err(dev, "<--- end TBDC dump --->\n"); +} + static void bnx2_dump_state(struct bnx2 *bp) { @@ -6434,6 +6504,7 @@ bnx2_tx_timeout(struct net_device *dev) { struct bnx2 *bp = netdev_priv(dev); + bnx2_dump_ftq(bp); bnx2_dump_state(bp); bnx2_dump_mcp_state(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index dc06bda73be7..29975857842e 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h @@ -4642,6 +4642,47 @@ struct l2_fhdr { #define BNX2_TBDR_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) +/* + * tbdc definition + * offset: 0x5400 + */ +#define BNX2_TBDC_COMMAND 0x5400 +#define BNX2_TBDC_COMMAND_CMD_ENABLED (1UL<<0) +#define BNX2_TBDC_COMMAND_CMD_FLUSH (1UL<<1) +#define BNX2_TBDC_COMMAND_CMD_SOFT_RST (1UL<<2) +#define BNX2_TBDC_COMMAND_CMD_REG_ARB (1UL<<3) +#define BNX2_TBDC_COMMAND_WRCHK_RANGE_ERROR (1UL<<4) +#define BNX2_TBDC_COMMAND_WRCHK_ALL_ONES_ERROR (1UL<<5) +#define BNX2_TBDC_COMMAND_WRCHK_ALL_ZEROS_ERROR (1UL<<6) +#define BNX2_TBDC_COMMAND_WRCHK_ANY_ONES_ERROR (1UL<<7) +#define BNX2_TBDC_COMMAND_WRCHK_ANY_ZEROS_ERROR (1UL<<8) + +#define BNX2_TBDC_STATUS 0x5404 +#define BNX2_TBDC_STATUS_FREE_CNT (0x3fUL<<0) + +#define BNX2_TBDC_BD_ADDR 0x5424 + +#define BNX2_TBDC_BIDX 0x542c +#define BNX2_TBDC_BDIDX_BDIDX (0xffffUL<<0) +#define BNX2_TBDC_BDIDX_CMD (0xffUL<<24) + +#define BNX2_TBDC_CID 0x5430 + +#define BNX2_TBDC_CAM_OPCODE 0x5434 +#define BNX2_TBDC_CAM_OPCODE_OPCODE (0x7UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_SEARCH (0UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_CACHE_WRITE (1UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_INVALIDATE (2UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_CAM_WRITE (4UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_CAM_READ (5UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_RAM_WRITE (6UL<<0) +#define BNX2_TBDC_CAM_OPCODE_OPCODE_RAM_READ (7UL<<0) +#define BNX2_TBDC_CAM_OPCODE_SMASK_BDIDX (1UL<<4) +#define BNX2_TBDC_CAM_OPCODE_SMASK_CID (1UL<<5) +#define BNX2_TBDC_CAM_OPCODE_SMASK_CMD (1UL<<6) +#define BNX2_TBDC_CAM_OPCODE_WMT_FAILED (1UL<<7) +#define BNX2_TBDC_CAM_OPCODE_CAM_VALIDS (0xffUL<<8) + /* * tdma_reg definition -- GitLab From 13e63517f4bc425a17888e6497c59a9663c2b520 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 16 Jun 2012 15:45:42 +0000 Subject: [PATCH 1752/6849] bnx2: Dump additional BC_STATE during firmware sync timeout. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 1 + drivers/net/ethernet/broadcom/bnx2.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 8eaab0ce220a..da88de73e899 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -2473,6 +2473,7 @@ bnx2_dump_mcp_state(struct bnx2 *bp) bnx2_shmem_rd(bp, BNX2_BC_STATE_RESET_TYPE)); pr_cont(" condition[%08x]\n", bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION)); + DP_SHMEM_LINE(bp, BNX2_BC_RESET_TYPE); DP_SHMEM_LINE(bp, 0x3cc); DP_SHMEM_LINE(bp, 0x3dc); DP_SHMEM_LINE(bp, 0x3ec); diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index 29975857842e..f9cb639a4787 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h @@ -7355,6 +7355,8 @@ struct bnx2_rv2p_fw_file { #define BNX2_BC_STATE_RESET_TYPE_VALUE(msg) (BNX2_BC_STATE_RESET_TYPE_SIG | \ (msg)) +#define BNX2_BC_RESET_TYPE 0x000001c0 + #define BNX2_BC_STATE 0x000001c4 #define BNX2_BC_STATE_ERR_MASK 0x0000ff00 #define BNX2_BC_STATE_SIGN 0x42530000 -- GitLab From aefd90e41476223c95e3c84c7dd22a65a21b1e40 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 16 Jun 2012 15:45:43 +0000 Subject: [PATCH 1753/6849] bnx2: Read PCI function number from internal register so that it will work on any hypervisor. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 7 +++++-- drivers/net/ethernet/broadcom/bnx2.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index da88de73e899..c6d39438cbe3 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -7903,7 +7903,7 @@ bnx2_get_5709_media(struct bnx2 *bp) else strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8; - if (PCI_FUNC(bp->pdev->devfn) == 0) { + if (bp->func == 0) { switch (strap) { case 0x4: case 0x5: @@ -8202,9 +8202,12 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) reg = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_SIGNATURE); + if (bnx2_reg_rd_ind(bp, BNX2_MCP_TOE_ID) & BNX2_MCP_TOE_ID_FUNCTION_ID) + bp->func = 1; + if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == BNX2_SHM_HDR_SIGNATURE_SIG) { - u32 off = PCI_FUNC(pdev->devfn) << 2; + u32 off = bp->func << 2; bp->shmem_base = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_ADDR_0 + off); } else diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index f9cb639a4787..af6451dec295 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h @@ -6971,6 +6971,8 @@ struct bnx2 { struct bnx2_irq irq_tbl[BNX2_MAX_MSIX_VEC]; int irq_nvecs; + u8 func; + u8 num_tx_rings; u8 num_rx_rings; -- GitLab From 260762c7d8030055a157b6f4ea7d1805a09e59e8 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 16 Jun 2012 15:45:44 +0000 Subject: [PATCH 1754/6849] bnx2: Update version 2.2.2 Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index c6d39438cbe3..9b69a628641c 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -58,8 +58,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.2.1" -#define DRV_MODULE_RELDATE "Dec 18, 2011" +#define DRV_MODULE_VERSION "2.2.2" +#define DRV_MODULE_RELDATE "June 16, 2012" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw" -- GitLab From 50a2984543aa2581d08580f8468533ce0ade8a62 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Sat, 16 Jun 2012 20:27:14 +0000 Subject: [PATCH 1755/6849] bnx2x: fix I2C non-respondent issue When I2C is not responding it's usually due to a previous unexpected reset during I2C operation. We release it by powering down and up the SFP+ module. Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index a3fb7215cd89..51d7ab6a0276 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -40,6 +40,7 @@ #define I2C_BSC0 0 #define I2C_BSC1 1 #define I2C_WA_RETRY_CNT 3 +#define I2C_WA_PWR_ITER (I2C_WA_RETRY_CNT - 1) #define MCPR_IMC_COMMAND_READ_OP 1 #define MCPR_IMC_COMMAND_WRITE_OP 2 @@ -7659,6 +7660,28 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } +static void bnx2x_warpcore_power_module(struct link_params *params, + struct bnx2x_phy *phy, + u8 power) +{ + u32 pin_cfg; + struct bnx2x *bp = params->bp; + + pin_cfg = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_PWR_DIS_MASK) >> + PORT_HW_CFG_E3_PWR_DIS_SHIFT; + + if (pin_cfg == PIN_CFG_NA) + return; + DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", + power, pin_cfg); + /* Low ==> corresponding SFP+ module is powered + * high ==> the SFP+ module is powered down + */ + bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); +} static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, @@ -7678,6 +7701,12 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { + if (cnt == I2C_WA_PWR_ITER) { + bnx2x_warpcore_power_module(params, phy, 0); + /* Note that 100us are not enough here */ + usleep_range(1000,1000); + bnx2x_warpcore_power_module(params, phy, 1); + } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, data_array); } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); @@ -8200,29 +8229,6 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, bnx2x_set_e1e2_module_fault_led(params, gpio_mode); } -static void bnx2x_warpcore_power_module(struct link_params *params, - struct bnx2x_phy *phy, - u8 power) -{ - u32 pin_cfg; - struct bnx2x *bp = params->bp; - - pin_cfg = (REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & - PORT_HW_CFG_E3_PWR_DIS_MASK) >> - PORT_HW_CFG_E3_PWR_DIS_SHIFT; - - if (pin_cfg == PIN_CFG_NA) - return; - DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", - power, pin_cfg); - /* Low ==> corresponding SFP+ module is powered - * high ==> the SFP+ module is powered down - */ - bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); -} - static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { -- GitLab From 5481388bc705de27ca37241a42c6612c86f2cc3b Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Sat, 16 Jun 2012 20:27:15 +0000 Subject: [PATCH 1756/6849] bnx2x: fix link for BCM57711 with 84823 phy Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 51d7ab6a0276..6e7d5c0843b4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -9754,7 +9754,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, msleep(1); - if (!(CHIP_IS_E1(bp))) + if (!(CHIP_IS_E1x(bp))) port = BP_PATH(bp); else port = params->port; -- GitLab From 6b03976288538a94e072bbfcd12d69a20daea8aa Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Mon, 21 May 2012 16:31:12 +0300 Subject: [PATCH 1757/6849] remoteproc/omap: fix dev_err typo For some reason one of the dev_err invocations is using a wrong device so fix that. Signed-off-by: Ohad Ben-Cohen Cc: stable@vger.kernel.org --- drivers/remoteproc/omap_remoteproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 69425c4e86f3..de138e30d3e6 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -182,7 +182,7 @@ static int __devinit omap_rproc_probe(struct platform_device *pdev) ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); + dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret); return ret; } -- GitLab From fcc14ac1a86931f38da047cf8fb634c6db7b58bc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 17 Jun 2012 18:05:05 +0200 Subject: [PATCH 1758/6849] hwmon: (coretemp) Improve support of recent Atom CPU models Document the new Atom series (Tunnel Creek and Medfield) as being supported, and list TjMax for the Atom E600 series. Also enable the Atom tjmax heuristic for these Atom CPU models. Signed-off-by: Jean Delvare Reviewed-by: Guenter Roeck Cc: Alexander Stein Cc: Fenghua Yu Cc: "R, Durgadoss" --- Documentation/hwmon/coretemp | 8 +++++++- drivers/hwmon/coretemp.c | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 84d46c0c71a3..f6aed440c3d7 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp @@ -6,7 +6,8 @@ Supported chips: Prefix: 'coretemp' CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), - 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield) + 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield), + 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom) Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide http://softwarecommunity.intel.com/Wiki/Mobility/720.htm @@ -65,6 +66,9 @@ Process Processor TjMax(C) U3400 105 P4505/P4500 90 +32nm Atom Processors + Z2460 90 + 45nm Xeon Processors 5400 Quad-Core X5492, X5482, X5472, X5470, X5460, X5450 85 E5472, E5462, E5450/40/30/20/10/05 85 @@ -85,6 +89,8 @@ Process Processor TjMax(C) N475/470/455/450 100 N280/270 90 330/230 125 + E680/660/640/620 90 + E680T/660T/640T/620T 110 45nm Core2 Processors Solo ULV SU3500/3300 100 diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index b9d512331ed4..495add52c802 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -210,7 +210,8 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, /* Atom CPUs */ - if (c->x86_model == 0x1c) { + if (c->x86_model == 0x1c || c->x86_model == 0x26 + || c->x86_model == 0x27) { usemsr_ee = 0; host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); -- GitLab From 5592906f8b01282ea3c2acaf641fd067ad4bb3dc Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 17 Jun 2012 18:05:05 +0200 Subject: [PATCH 1759/6849] hwmon: (coretemp) Add support for Atom D2000 and N2000 series CPU models Document the Atom series D2000 and N2000 (Cedar Trail) as being supported. List and set TjMax for those series. Cc: Fenghua Yu Cc: "R, Durgadoss" Signed-off-by: Guenter Roeck Signed-off-by: Jean Delvare --- Documentation/hwmon/coretemp | 5 ++++- drivers/hwmon/coretemp.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index f6aed440c3d7..71d83d2f984d 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp @@ -7,7 +7,8 @@ Supported chips: CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield), - 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom) + 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom), + 0x36 (Cedar Trail Atom) Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide http://softwarecommunity.intel.com/Wiki/Mobility/720.htm @@ -68,6 +69,8 @@ Process Processor TjMax(C) 32nm Atom Processors Z2460 90 + D2700/2550/2500 100 + N2850/2800/2650/2600 100 45nm Xeon Processors 5400 Quad-Core X5492, X5482, X5472, X5470, X5460, X5450 85 diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 495add52c802..42c2f431ea51 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -224,6 +224,9 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, tjmax = 90000; pci_dev_put(host_bridge); + } else if (c->x86_model == 0x36) { + usemsr_ee = 0; + tjmax = 100000; } if (c->x86_model > 0xe && usemsr_ee) { -- GitLab From 41e58a1f2b90c88d94b4bd84beb9927a4c2704e9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 17 Jun 2012 18:05:05 +0200 Subject: [PATCH 1760/6849] hwmon: (coretemp) Improve support for TjMax detection on Atom CPUs Atom CPUs don't have a register to retrieve TjMax. Detection so far was incomplete. Use the X86 model ID to improve it. Signed-off-by: Guenter Roeck Signed-off-by: Jean Delvare --- drivers/hwmon/coretemp.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 42c2f431ea51..22716833739a 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -191,6 +191,24 @@ static ssize_t show_temp(struct device *dev, return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; } +struct tjmax { + char const *id; + int tjmax; +}; + +static struct tjmax __cpuinitconst tjmax_table[] = { + { "CPU D410", 100000 }, + { "CPU D425", 100000 }, + { "CPU D510", 100000 }, + { "CPU D525", 100000 }, + { "CPU N450", 100000 }, + { "CPU N455", 100000 }, + { "CPU N470", 100000 }, + { "CPU N475", 100000 }, + { "CPU 230", 100000 }, + { "CPU 330", 125000 }, +}; + static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) { @@ -202,6 +220,13 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, int err; u32 eax, edx; struct pci_dev *host_bridge; + int i; + + /* explicit tjmax table entries override heuristics */ + for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { + if (strstr(c->x86_model_id, tjmax_table[i].id)) + return tjmax_table[i].tjmax; + } /* Early chips have no MSR for TjMax */ -- GitLab From 813441f16e5248e7fd6a4044e8adabf4ac3aaec9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 17 Jun 2012 18:05:06 +0200 Subject: [PATCH 1761/6849] hwmon: (coretemp) Document TjMax for 3rd generation i5/i7 processors Tjmax values from Intel datasheets. Signed-off-by: Guenter Roeck Signed-off-by: Jean Delvare --- Documentation/hwmon/coretemp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 71d83d2f984d..c86b50c03ea8 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp @@ -54,6 +54,17 @@ Some information comes from ark.intel.com Process Processor TjMax(C) +22nm Core i5/i7 Processors + i7 3920XM, 3820QM, 3720QM, 3667U, 3520M 105 + i5 3427U, 3360M/3320M 105 + i7 3770/3770K 105 + i5 3570/3570K, 3550, 3470/3450 105 + i7 3770S 103 + i5 3570S/3550S, 3475S/3470S/3450S 103 + i7 3770T 94 + i5 3570T 94 + i5 3470T 91 + 32nm Core i3/i5/i7 Processors i7 660UM/640/620, 640LM/620, 620M, 610E 105 i5 540UM/520/430, 540M/520/450/430 105 -- GitLab From 1268a172cdb00353f107e6cc964dccff29047077 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 17 Jun 2012 18:05:06 +0200 Subject: [PATCH 1762/6849] hwmon: (coretemp) Drop needless initialization The value is overridden a few lines later. Signed-off-by: Jean Delvare Acked-by: Guenter Roeck --- drivers/hwmon/coretemp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 22716833739a..7f1feb2f467a 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -801,7 +801,7 @@ MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); static int __init coretemp_init(void) { - int i, err = -ENODEV; + int i, err; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal -- GitLab From 9d88fc0b3503e80ab1a5c9fb3b3f074302f44b33 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 13 Jun 2012 17:27:16 +0900 Subject: [PATCH 1763/6849] regulator: Fix the s5m8767a problem of the division by null If ramp_delay is 0, delay value can be divided by zero. This patch can fix the problem. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 290d6fc01029..9caadb482178 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -451,7 +451,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - if (old_sel < new_sel) + if ((old_sel < new_sel) && s5m8767->ramp_delay) return DIV_ROUND_UP(desc->step * (new_sel - old_sel), s5m8767->ramp_delay * 1000); return 0; -- GitLab From f7f3f1ad9ee13c962122e36752ef6908aff920a2 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 30 May 2012 12:47:26 +0800 Subject: [PATCH 1764/6849] regulator: Change ab8500 match names to reflect Device Tree The 'name' field in 'struct of_regulator_match' expects to match with its corresponding regulator device node in the Device Tree. This patch renames each of the regulators in the ab8500 regulator driver so this is true. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e1b8c54ace5a..a739f5ca936a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -794,17 +794,17 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, + { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, + { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; static __devinit int -- GitLab From ea851f4f08eb366e829abb8f1b2f1741a19ed696 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 30 May 2012 12:47:27 +0800 Subject: [PATCH 1765/6849] regulator: Change db8500-prcmu match names to reflect Device Tree The 'name' field in 'struct of_regulator_match' expects to match with its corresponding regulator device node in the Device Tree. This patch renames each of the regulators in the db8500-prcum regulator driver so this is true. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/db8500-prcmu.c | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 968f97f3cb3d..9dbb491b6efa 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -452,26 +452,26 @@ static __devinit int db8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, + { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, + { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, + { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, + { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, + { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, + { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, + { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, + { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, + { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, + { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, + { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, + { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, + { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, + { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, + { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, + { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, + { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, + { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, + { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, + { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; static __devinit int -- GitLab From 14e1e9f5cadb7cff3a2846c27cc1b9c8f207ee18 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 13 Jun 2012 14:06:07 -0300 Subject: [PATCH 1766/6849] pinctrl: mxs: Use kfree to fix build error commit 0bf7481 (pinctrl: pinctrl-mxs: Take care of frees if the kzalloc fails) introduced the following build error: drivers/pinctrl/pinctrl-mxs.c:140:3: error: implicit declaration of function 'free' Use kfree function instead. Signed-off-by: Fabio Estevam Acked-by: Devendra Naga Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index afb50ee64598..4ba4636b6a4a 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -137,7 +137,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, free_group: if (!purecfg) - free(group); + kfree(group); free: kfree(new_map); return ret; -- GitLab From daf731748f978efb4f741d19b499236e03bf667f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 May 2012 11:46:45 +0200 Subject: [PATCH 1767/6849] pinctrl/nomadik: document Alt-C glitch This documentation comment existed in an earlier patch set for GPIO consolidation, so I'm saving it for maintainability of the code. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index e8937e7e4999..3e7e47d6b385 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1438,7 +1438,27 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins); - /* Handle this special glitch on altfunction C */ + /* + * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, + * we may pass through an undesired state. In this case we take + * some extra care. + * + * Safe sequence used to switch IOs between GPIO and Alternate-C mode: + * - Save SLPM registers (since we have a shadow register in the + * nmk_chip we're using that as backup) + * - Set SLPM=0 for the IOs you want to switch and others to 1 + * - Configure the GPIO registers for the IOs that are being switched + * - Set IOFORCE=1 + * - Modify the AFLSA/B registers for the IOs that are being switched + * - Set IOFORCE=0 + * - Restore SLPM registers + * - Any spurious wake up event during switch sequence to be ignored + * and cleared + * + * We REALLY need to save ALL slpm registers, because the external + * IOFORCE will switch *all* ports to their sleepmode setting to as + * to avoid glitches. (Not just one port!) + */ glitch = (g->altsetting == NMK_GPIO_ALT_C); if (glitch) { -- GitLab From d8493d210b69b2965236a8a02f5f6e2835ad5e30 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 15 Jun 2012 19:09:09 +0100 Subject: [PATCH 1768/6849] regulator: core: Actually use the data in _notifier_call_chain() Reported-by: Pankaj Jangra Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 3cbe3129ed3b..52a9bae10393 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2657,7 +2657,7 @@ static void _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) { /* call rdev chain first */ - blocking_notifier_call_chain(&rdev->notifier, event, NULL); + blocking_notifier_call_chain(&rdev->notifier, event, data); } /** -- GitLab From 650513979a437c32d7a0a84f0ed952a55bbb5583 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 16 Jun 2012 21:47:37 -0700 Subject: [PATCH 1769/6849] x86-64, reboot: Allow reboot=bios and reboot-cpu override on x86-64 With the revamped realmode trampoline code, it is trivial to extend support for reboot=bios to x86-64. Furthermore, while we are at it, remove the restriction that only we can only override the reboot CPU on 32 bits. Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/n/tip-jopx7y6g6dbcx4tpal8q0jlr@git.kernel.org --- arch/x86/include/asm/emergency-restart.h | 2 - arch/x86/include/asm/realmode.h | 3 +- arch/x86/include/asm/reboot.h | 4 +- arch/x86/kernel/reboot.c | 52 +++++++++---------- arch/x86/realmode/rm/Makefile | 2 +- arch/x86/realmode/rm/header.S | 4 +- .../x86/realmode/rm/{reboot_32.S => reboot.S} | 26 ++++++++-- 7 files changed, 55 insertions(+), 38 deletions(-) rename arch/x86/realmode/rm/{reboot_32.S => reboot.S} (88%) diff --git a/arch/x86/include/asm/emergency-restart.h b/arch/x86/include/asm/emergency-restart.h index cc70c1c78ca4..75ce3f47d204 100644 --- a/arch/x86/include/asm/emergency-restart.h +++ b/arch/x86/include/asm/emergency-restart.h @@ -4,9 +4,7 @@ enum reboot_type { BOOT_TRIPLE = 't', BOOT_KBD = 'k', -#ifdef CONFIG_X86_32 BOOT_BIOS = 'b', -#endif BOOT_ACPI = 'a', BOOT_EFI = 'e', BOOT_CF9 = 'p', diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index fce3f4ae5bd6..fe1ec5bcd846 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h @@ -21,8 +21,9 @@ struct real_mode_header { u32 wakeup_header; #endif /* APM/BIOS reboot */ -#ifdef CONFIG_X86_32 u32 machine_real_restart_asm; +#ifdef CONFIG_X86_64 + u32 machine_real_restart_seg; #endif }; diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index 92f297069e87..a82c4f1b4d83 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -18,8 +18,8 @@ extern struct machine_ops machine_ops; void native_machine_crash_shutdown(struct pt_regs *regs); void native_machine_shutdown(void); -void machine_real_restart(unsigned int type); -/* These must match dispatch_table in reboot_32.S */ +void __noreturn machine_real_restart(unsigned int type); +/* These must match dispatch in arch/x86/realmore/rm/reboot.S */ #define MRR_BIOS 0 #define MRR_APM 1 diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 25b48edb847c..6ddb9cd0ced0 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -20,14 +20,12 @@ #include #include #include +#include -#ifdef CONFIG_X86_32 -# include -# include -# include -#else -# include -#endif +#include +#include +#include +#include /* * Power off function, if any @@ -49,7 +47,7 @@ int reboot_force; */ static int reboot_default = 1; -#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) +#ifdef CONFIG_SMP static int reboot_cpu = -1; #endif @@ -67,8 +65,8 @@ bool port_cf9_safe = false; * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] * warm Don't set the cold reboot flag * cold Set the cold reboot flag - * bios Reboot by jumping through the BIOS (only for X86_32) - * smp Reboot by executing reset on BSP or other CPU (only for X86_32) + * bios Reboot by jumping through the BIOS + * smp Reboot by executing reset on BSP or other CPU * triple Force a triple fault (init) * kbd Use the keyboard controller. cold reset (default) * acpi Use the RESET_REG in the FADT @@ -95,7 +93,6 @@ static int __init reboot_setup(char *str) reboot_mode = 0; break; -#ifdef CONFIG_X86_32 #ifdef CONFIG_SMP case 's': if (isdigit(*(str+1))) { @@ -112,7 +109,6 @@ static int __init reboot_setup(char *str) #endif /* CONFIG_SMP */ case 'b': -#endif case 'a': case 'k': case 't': @@ -138,7 +134,6 @@ static int __init reboot_setup(char *str) __setup("reboot=", reboot_setup); -#ifdef CONFIG_X86_32 /* * Reboot options and system auto-detection code provided by * Dell Inc. so their systems "just work". :-) @@ -157,11 +152,8 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) return 0; } -void machine_real_restart(unsigned int type) +void __noreturn machine_real_restart(unsigned int type) { - void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) - real_mode_header->machine_real_restart_asm; - local_irq_disable(); /* @@ -181,7 +173,11 @@ void machine_real_restart(unsigned int type) /* * Switch back to the initial page table. */ +#ifdef CONFIG_X86_32 load_cr3(initial_page_table); +#else + write_cr3(real_mode_header->trampoline_pgd); +#endif /* * Write 0x1234 to absolute memory location 0x472. The BIOS reads @@ -192,14 +188,21 @@ void machine_real_restart(unsigned int type) *((unsigned short *)0x472) = reboot_mode; /* Jump to the identity-mapped low memory code */ - restart_lowmem(type); +#ifdef CONFIG_X86_32 + asm volatile("jmpl *%0" : : + "rm" (real_mode_header->machine_real_restart_asm), + "a" (type)); +#else + asm volatile("ljmpl *%0" : : + "m" (real_mode_header->machine_real_restart_asm), + "D" (type)); +#endif + unreachable(); } #ifdef CONFIG_APM_MODULE EXPORT_SYMBOL(machine_real_restart); #endif -#endif /* CONFIG_X86_32 */ - /* * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot */ @@ -223,11 +226,9 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) } /* - * This is a single dmi_table handling all reboot quirks. Note that - * REBOOT_BIOS is only available for 32bit + * This is a single dmi_table handling all reboot quirks. */ static struct dmi_system_id __initdata reboot_dmi_table[] = { -#ifdef CONFIG_X86_32 { /* Handle problems with rebooting on Dell E520's */ .callback = set_bios_reboot, .ident = "Dell E520", @@ -377,7 +378,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "P4S800"), }, }, -#endif /* CONFIG_X86_32 */ { /* Handle reboot issue on Acer Aspire one */ .callback = set_kbd_reboot, @@ -576,13 +576,11 @@ static void native_machine_emergency_restart(void) reboot_type = BOOT_KBD; break; -#ifdef CONFIG_X86_32 case BOOT_BIOS: machine_real_restart(MRR_BIOS); reboot_type = BOOT_KBD; break; -#endif case BOOT_ACPI: acpi_reboot(); @@ -624,12 +622,10 @@ void native_machine_shutdown(void) /* The boot cpu is always logical cpu 0 */ int reboot_cpu_id = 0; -#ifdef CONFIG_X86_32 /* See if there has been given a command line override */ if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && cpu_online(reboot_cpu)) reboot_cpu_id = reboot_cpu; -#endif /* Make certain the cpu I'm about to reboot on is online */ if (!cpu_online(reboot_cpu_id)) diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 5b84a2d30888..b2d534cab25f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile @@ -22,7 +22,7 @@ wakeup-objs += video-bios.o realmode-y += header.o realmode-y += trampoline_$(BITS).o realmode-y += stack.o -realmode-$(CONFIG_X86_32) += reboot_32.o +realmode-y += reboot.o realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) targets += $(realmode-y) diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index fadf48378ada..a28221d94e69 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S @@ -6,6 +6,7 @@ #include #include +#include #include "realmode.h" @@ -28,8 +29,9 @@ GLOBAL(real_mode_header) .long pa_wakeup_header #endif /* APM/BIOS reboot */ -#ifdef CONFIG_X86_32 .long pa_machine_real_restart_asm +#ifdef CONFIG_X86_64 + .long __KERNEL32_CS #endif END(real_mode_header) diff --git a/arch/x86/realmode/rm/reboot_32.S b/arch/x86/realmode/rm/reboot.S similarity index 88% rename from arch/x86/realmode/rm/reboot_32.S rename to arch/x86/realmode/rm/reboot.S index 114044876b3d..6bf8feac5557 100644 --- a/arch/x86/realmode/rm/reboot_32.S +++ b/arch/x86/realmode/rm/reboot.S @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "realmode.h" /* @@ -12,13 +14,31 @@ * doesn't work with at least one type of 486 motherboard. It is easy * to stop this code working; hence the copious comments. * - * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. + * This code is called with the restart type (0 = BIOS, 1 = APM) in + * the primary argument register (%eax for 32 bit, %edi for 64 bit). */ .section ".text32", "ax" .code32 - - .balign 16 ENTRY(machine_real_restart_asm) + +#ifdef CONFIG_X86_64 + + /* Disable paging to drop us out of long mode */ + movl %cr0, %eax + andl $~X86_CR0_PG, %eax + movl %eax, %cr0 + jmp 1f /* "A branch" may be needed here, assume near is OK */ + +1: + xorl %eax, %eax + xorl %edx, %edx + movl $MSR_EFER, %ecx + wrmsr + + movl %edi, %eax + +#endif /* CONFIG_X86_64 */ + /* Set up the IDT for real mode. */ lidtl pa_machine_real_restart_idt -- GitLab From 22cec7ca02f81b57a06d238a4043bc6c9ba6ea03 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 8 Jun 2012 11:36:45 +0200 Subject: [PATCH 1770/6849] ARM: iconnect: Remove include of removed linux/spi/orion_spi.h v3.5-rc1 fails to build when DT and iconnect is enabled because of this now none existant include file. Also remove the other two SPI include files, which are not needed with the move to DT. Signed-off-by: Andrew Lunn Acked-by: Arnaud Patard Signed-off-by: Olof Johansson --- arch/arm/mach-kirkwood/board-iconnect.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c index 2222c5739519..b0d3cc49269d 100644 --- a/arch/arm/mach-kirkwood/board-iconnect.c +++ b/arch/arm/mach-kirkwood/board-iconnect.c @@ -20,9 +20,6 @@ #include #include #include -#include -#include -#include #include #include #include -- GitLab From 6bc07d6afa1679a2f5b272bc36618314686e143a Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Sun, 17 Jun 2012 11:57:50 -0600 Subject: [PATCH 1771/6849] ARM: OMAP: PM: Lock clocks list while generating summary Commit a53025724052b2b1edbc982a4a248784638f563d (OMAP: Add debugfs node to show the summary of all clocks) introduced clock summary, however, we are interested in seeing snapshot of the clock state, not in dynamically changing clock configurations as the data provided by clock summary will then be useless for debugging configuration issues. So, hold the common lock when dumping the clock summary. Cc: Paul Walmsley Cc: Tony Lindgren Signed-off-by: Todd Poynor [nm@ti.com: added commit message] Signed-off-by: Nishanth Menon [paul@pwsan.com: minor edits to commit message] Signed-off-by: Paul Walmsley --- arch/arm/plat-omap/clock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 62ec5c452792..706b7e29397f 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -461,6 +461,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused) struct clk *c; struct clk *pa; + mutex_lock(&clocks_mutex); seq_printf(s, "%-30s %-30s %-10s %s\n", "clock-name", "parent-name", "rate", "use-count"); @@ -469,6 +470,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused) seq_printf(s, "%-30s %-30s %-10lu %d\n", c->name, pa ? pa->name : "none", c->rate, c->usecount); } + mutex_unlock(&clocks_mutex); return 0; } -- GitLab From 2f7baf89d3e4ed787989168cf31f2fdc04067586 Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Fri, 15 Jun 2012 11:27:36 -0700 Subject: [PATCH 1772/6849] regulator: core.c Pass voltage to notifier when setting voltage The voltage being set should be passed to the call in handler requesting the callback. Currently this is not done. The calling handler cannot call regulator_get_voltage() to get the information since the mutex is held by the regulator and deadlock occurs. Without this change the receiver of the call in cannot know what action to take. This is used, for example, to set PAD voltages when doing SD vccq voltage changes. [Review and spelling fix in the commit log from Pankaj Jangra] Signed-off-by: Philip Rakity Signed-off-by: Mark Brown --- drivers/regulator/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 52a9bae10393..ebdd9e0e14d4 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2142,7 +2142,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, if (rdev->desc->ops->list_voltage) best_val = rdev->desc->ops->list_voltage(rdev, selector); else - best_val = -1; + best_val = _regulator_get_voltage(rdev); /* Call set_voltage_time_sel if successfully obtained old_selector */ if (_regulator_is_enabled(rdev) && ret == 0 && old_selector >= 0 && @@ -2165,9 +2165,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, udelay(delay); } - if (ret == 0) + if (ret == 0 && best_val >= 0) _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, - NULL); + (void *)best_val); trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val); -- GitLab From e0690385a86cac5403a62d91dc146f2508416ded Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Tue, 12 Jun 2012 08:50:08 +0200 Subject: [PATCH 1773/6849] ASoC: Ux500: Add machine-driver Add machine-driver for ST-Ericsson U8500 platform, including support for the AB8500-codec. Signed-off-by: Ola Lilja Acked-by: Linus Walleij Signed-off-by: Mark Brown --- sound/soc/ux500/Kconfig | 11 + sound/soc/ux500/Makefile | 3 + sound/soc/ux500/mop500.c | 113 +++++++++ sound/soc/ux500/mop500_ab8500.c | 431 ++++++++++++++++++++++++++++++++ sound/soc/ux500/mop500_ab8500.h | 22 ++ 5 files changed, 580 insertions(+) create mode 100644 sound/soc/ux500/mop500.c create mode 100644 sound/soc/ux500/mop500_ab8500.c create mode 100644 sound/soc/ux500/mop500_ab8500.h diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig index 1d385150064f..069330d82be5 100644 --- a/sound/soc/ux500/Kconfig +++ b/sound/soc/ux500/Kconfig @@ -19,3 +19,14 @@ config SND_SOC_UX500_PLAT_DMA select SND_SOC_DMAENGINE_PCM help Say Y if you want to enable the Ux500 platform-driver. + ++config SND_SOC_UX500_MACH_MOP500 ++ tristate "Machine - MOP500 (Ux500 + AB8500)" + depends on AB8500_CORE && AB8500_GPADC && SND_SOC_UX500 + select SND_SOC_AB8500_CODEC + select SND_SOC_UX500_PLAT_MSP_I2S + select SND_SOC_UX500_PLAT_DMA + help + Select this to enable the MOP500 machine-driver. + This will enable platform-drivers for: Ux500 + This will enable codec-drivers for: AB8500 diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile index 4634bf015f62..cce0c11a4d86 100644 --- a/sound/soc/ux500/Makefile +++ b/sound/soc/ux500/Makefile @@ -5,3 +5,6 @@ obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o snd-soc-ux500-plat-dma-objs := ux500_pcm.o obj-$(CONFIG_SND_SOC_UX500_PLAT_DMA) += snd-soc-ux500-plat-dma.o + +snd-soc-ux500-mach-mop500-objs := mop500.o mop500_ab8500.o +obj-$(CONFIG_SND_SOC_UX500_MACH_MOP500) += snd-soc-ux500-mach-mop500.o diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c new file mode 100644 index 000000000000..31c4d26d0359 --- /dev/null +++ b/sound/soc/ux500/mop500.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja (ola.o.lilja@stericsson.com) + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include + +#include +#include +#include + +#include +#include + +#include "ux500_pcm.h" +#include "ux500_msp_dai.h" + +#include + +/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */ +struct snd_soc_dai_link mop500_dai_links[] = { + { + .name = "ab8500_0", + .stream_name = "ab8500_0", + .cpu_dai_name = "ux500-msp-i2s.1", + .codec_dai_name = "ab8500-codec-dai.0", + .platform_name = "ux500-pcm.0", + .codec_name = "ab8500-codec.0", + .init = mop500_ab8500_machine_init, + .ops = mop500_ab8500_ops, + }, + { + .name = "ab8500_1", + .stream_name = "ab8500_1", + .cpu_dai_name = "ux500-msp-i2s.3", + .codec_dai_name = "ab8500-codec-dai.1", + .platform_name = "ux500-pcm.0", + .codec_name = "ab8500-codec.0", + .init = NULL, + .ops = mop500_ab8500_ops, + }, +}; + +static struct snd_soc_card mop500_card = { + .name = "MOP500-card", + .probe = NULL, + .dai_link = mop500_dai_links, + .num_links = ARRAY_SIZE(mop500_dai_links), +}; + +static int __devinit mop500_probe(struct platform_device *pdev) +{ + int ret; + + pr_debug("%s: Enter.\n", __func__); + + dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); + + mop500_card.dev = &pdev->dev; + + dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n", + __func__, mop500_card.name); + platform_set_drvdata(pdev, &mop500_card); + + snd_soc_card_set_drvdata(&mop500_card, NULL); + + dev_dbg(&pdev->dev, "%s: Card %s: num_links = %d\n", + __func__, mop500_card.name, mop500_card.num_links); + dev_dbg(&pdev->dev, "%s: Card %s: DAI-link 0: name = %s\n", + __func__, mop500_card.name, mop500_card.dai_link[0].name); + dev_dbg(&pdev->dev, "%s: Card %s: DAI-link 0: stream_name = %s\n", + __func__, mop500_card.name, + mop500_card.dai_link[0].stream_name); + + ret = snd_soc_register_card(&mop500_card); + if (ret) + dev_err(&pdev->dev, + "Error: snd_soc_register_card failed (%d)!\n", + ret); + + return ret; +} + +static int __devexit mop500_remove(struct platform_device *pdev) +{ + struct snd_soc_card *mop500_card = platform_get_drvdata(pdev); + + pr_debug("%s: Enter.\n", __func__); + + snd_soc_unregister_card(mop500_card); + mop500_ab8500_remove(mop500_card); + + return 0; +} + +static struct platform_driver snd_soc_mop500_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "snd-soc-mop500", + }, + .probe = mop500_probe, + .remove = __devexit_p(mop500_remove), +}; + +module_platform_driver(snd_soc_mop500_driver); diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c new file mode 100644 index 000000000000..78cce236693e --- /dev/null +++ b/sound/soc/ux500/mop500_ab8500.c @@ -0,0 +1,431 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja , + * Kristoffer Karlsson + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "ux500_pcm.h" +#include "ux500_msp_dai.h" +#include "../codecs/ab8500-codec.h" + +#define TX_SLOT_MONO 0x0008 +#define TX_SLOT_STEREO 0x000a +#define RX_SLOT_MONO 0x0001 +#define RX_SLOT_STEREO 0x0003 +#define TX_SLOT_8CH 0x00FF +#define RX_SLOT_8CH 0x00FF + +#define DEF_TX_SLOTS TX_SLOT_STEREO +#define DEF_RX_SLOTS RX_SLOT_MONO + +#define DRIVERMODE_NORMAL 0 +#define DRIVERMODE_CODEC_ONLY 1 + +/* Slot configuration */ +static unsigned int tx_slots = DEF_TX_SLOTS; +static unsigned int rx_slots = DEF_RX_SLOTS; + +/* Clocks */ +static const char * const enum_mclk[] = { + "SYSCLK", + "ULPCLK" +}; +enum mclk { + MCLK_SYSCLK, + MCLK_ULPCLK, +}; + +static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk); + +/* Private data for machine-part MOP500<->AB8500 */ +struct mop500_ab8500_drvdata { + /* Clocks */ + enum mclk mclk_sel; + struct clk *clk_ptr_intclk; + struct clk *clk_ptr_sysclk; + struct clk *clk_ptr_ulpclk; +}; + +static inline const char *get_mclk_str(enum mclk mclk_sel) +{ + switch (mclk_sel) { + case MCLK_SYSCLK: + return "SYSCLK"; + case MCLK_ULPCLK: + return "ULPCLK"; + default: + return "Unknown"; + } +} + +static int mop500_ab8500_set_mclk(struct device *dev, + struct mop500_ab8500_drvdata *drvdata) +{ + int status; + struct clk *clk_ptr; + + if (IS_ERR(drvdata->clk_ptr_intclk)) { + dev_err(dev, + "%s: ERROR: intclk not initialized!\n", __func__); + return -EIO; + } + + switch (drvdata->mclk_sel) { + case MCLK_SYSCLK: + clk_ptr = drvdata->clk_ptr_sysclk; + break; + case MCLK_ULPCLK: + clk_ptr = drvdata->clk_ptr_ulpclk; + break; + default: + return -EINVAL; + } + + if (IS_ERR(clk_ptr)) { + dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__, + get_mclk_str(drvdata->mclk_sel)); + return -EIO; + } + + status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr); + if (status) + dev_err(dev, + "%s: ERROR: Setting intclk parent to %s failed (ret = %d)!", + __func__, get_mclk_str(drvdata->mclk_sel), status); + else + dev_dbg(dev, + "%s: intclk parent changed to %s.\n", + __func__, get_mclk_str(drvdata->mclk_sel)); + + return status; +} + +/* + * Control-events + */ + +static int mclk_input_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct mop500_ab8500_drvdata *drvdata = + snd_soc_card_get_drvdata(codec->card); + + ucontrol->value.enumerated.item[0] = drvdata->mclk_sel; + + return 0; +} + +static int mclk_input_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct mop500_ab8500_drvdata *drvdata = + snd_soc_card_get_drvdata(codec->card); + unsigned int val = ucontrol->value.enumerated.item[0]; + + if (val > (unsigned int)MCLK_ULPCLK) + return -EINVAL; + if (drvdata->mclk_sel == val) + return 0; + + drvdata->mclk_sel = val; + + return 1; +} + +/* + * Controls + */ + +static struct snd_kcontrol_new mop500_ab8500_ctrls[] = { + SOC_ENUM_EXT("Master Clock Select", + soc_enum_mclk, + mclk_input_control_get, mclk_input_control_put), + /* Digital interface - Clocks */ + SOC_SINGLE("Digital Interface Master Generator Switch", + AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN, + 1, 0), + SOC_SINGLE("Digital Interface 0 Bit-clock Switch", + AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0, + 1, 0), + SOC_SINGLE("Digital Interface 1 Bit-clock Switch", + AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1, + 1, 0), + SOC_DAPM_PIN_SWITCH("Headset Left"), + SOC_DAPM_PIN_SWITCH("Headset Right"), + SOC_DAPM_PIN_SWITCH("Earpiece"), + SOC_DAPM_PIN_SWITCH("Speaker Left"), + SOC_DAPM_PIN_SWITCH("Speaker Right"), + SOC_DAPM_PIN_SWITCH("LineOut Left"), + SOC_DAPM_PIN_SWITCH("LineOut Right"), + SOC_DAPM_PIN_SWITCH("Vibra 1"), + SOC_DAPM_PIN_SWITCH("Vibra 2"), + SOC_DAPM_PIN_SWITCH("Mic 1"), + SOC_DAPM_PIN_SWITCH("Mic 2"), + SOC_DAPM_PIN_SWITCH("LineIn Left"), + SOC_DAPM_PIN_SWITCH("LineIn Right"), + SOC_DAPM_PIN_SWITCH("DMic 1"), + SOC_DAPM_PIN_SWITCH("DMic 2"), + SOC_DAPM_PIN_SWITCH("DMic 3"), + SOC_DAPM_PIN_SWITCH("DMic 4"), + SOC_DAPM_PIN_SWITCH("DMic 5"), + SOC_DAPM_PIN_SWITCH("DMic 6"), +}; + +/* ASoC */ + +int mop500_ab8500_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + /* Set audio-clock source */ + return mop500_ab8500_set_mclk(rtd->card->dev, + snd_soc_card_get_drvdata(rtd->card)); +} + +void mop500_ab8500_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct device *dev = rtd->card->dev; + + dev_dbg(dev, "%s: Enter\n", __func__); + + /* Reset slots configuration to default(s) */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + tx_slots = DEF_TX_SLOTS; + else + rx_slots = DEF_RX_SLOTS; +} + +int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct device *dev = rtd->card->dev; + unsigned int fmt; + int channels, ret = 0, driver_mode, slots; + unsigned int sw_codec, sw_cpu; + bool is_playback; + + dev_dbg(dev, "%s: Enter\n", __func__); + + dev_dbg(dev, "%s: substream->pcm->name = %s\n" + "substream->pcm->id = %s.\n" + "substream->name = %s.\n" + "substream->number = %d.\n", + __func__, + substream->pcm->name, + substream->pcm->id, + substream->name, + substream->number); + + channels = params_channels(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + sw_cpu = 32; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + sw_cpu = 16; + break; + + default: + return -EINVAL; + } + + /* Setup codec depending on driver-mode */ + if (channels == 8) + driver_mode = DRIVERMODE_CODEC_ONLY; + else + driver_mode = DRIVERMODE_NORMAL; + dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__, + (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY"); + + /* Setup format */ + + if (driver_mode == DRIVERMODE_NORMAL) { + fmt = SND_SOC_DAIFMT_DSP_A | + SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CONT; + } else { + fmt = SND_SOC_DAIFMT_DSP_A | + SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_GATED; + } + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); + if (ret < 0) { + dev_err(dev, + "%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n", + __func__, ret); + return ret; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + dev_err(dev, + "%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n", + __func__, ret); + return ret; + } + + /* Setup TDM-slots */ + + is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + switch (channels) { + case 1: + slots = 16; + tx_slots = (is_playback) ? TX_SLOT_MONO : 0; + rx_slots = (is_playback) ? 0 : RX_SLOT_MONO; + break; + case 2: + slots = 16; + tx_slots = (is_playback) ? TX_SLOT_STEREO : 0; + rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO; + break; + case 8: + slots = 16; + tx_slots = (is_playback) ? TX_SLOT_8CH : 0; + rx_slots = (is_playback) ? 0 : RX_SLOT_8CH; + break; + default: + return -EINVAL; + } + + if (driver_mode == DRIVERMODE_NORMAL) + sw_codec = sw_cpu; + else + sw_codec = 20; + + dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__, + tx_slots, rx_slots); + ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots, + sw_cpu); + if (ret) + return ret; + + dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__, + tx_slots, rx_slots); + ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots, + sw_codec); + if (ret) + return ret; + + return 0; +} + +struct snd_soc_ops mop500_ab8500_ops[] = { + { + .hw_params = mop500_ab8500_hw_params, + .startup = mop500_ab8500_startup, + .shutdown = mop500_ab8500_shutdown, + } +}; + +int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct device *dev = rtd->card->dev; + struct mop500_ab8500_drvdata *drvdata; + int ret; + + dev_dbg(dev, "%s Enter.\n", __func__); + + /* Create driver private-data struct */ + drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata), + GFP_KERNEL); + snd_soc_card_set_drvdata(rtd->card, drvdata); + + /* Setup clocks */ + + drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk"); + if (IS_ERR(drvdata->clk_ptr_sysclk)) + dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n", + __func__); + drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk"); + if (IS_ERR(drvdata->clk_ptr_ulpclk)) + dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n", + __func__); + drvdata->clk_ptr_intclk = clk_get(dev, "intclk"); + if (IS_ERR(drvdata->clk_ptr_intclk)) + dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n", + __func__); + + /* Set intclk default parent to ulpclk */ + drvdata->mclk_sel = MCLK_ULPCLK; + ret = mop500_ab8500_set_mclk(dev, drvdata); + if (ret < 0) + dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n", + __func__); + + drvdata->mclk_sel = MCLK_ULPCLK; + + /* Add controls */ + ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls, + ARRAY_SIZE(mop500_ab8500_ctrls)); + if (ret < 0) { + pr_err("%s: Failed to add machine-controls (%d)!\n", + __func__, ret); + return ret; + } + + ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5"); + ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6"); + + return ret; +} + +void mop500_ab8500_remove(struct snd_soc_card *card) +{ + struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card); + + if (drvdata->clk_ptr_sysclk != NULL) + clk_put(drvdata->clk_ptr_sysclk); + if (drvdata->clk_ptr_ulpclk != NULL) + clk_put(drvdata->clk_ptr_ulpclk); + if (drvdata->clk_ptr_intclk != NULL) + clk_put(drvdata->clk_ptr_intclk); + + snd_soc_card_set_drvdata(card, drvdata); +} diff --git a/sound/soc/ux500/mop500_ab8500.h b/sound/soc/ux500/mop500_ab8500.h new file mode 100644 index 000000000000..cca5b33964b6 --- /dev/null +++ b/sound/soc/ux500/mop500_ab8500.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) ST-Ericsson SA 2012 + * + * Author: Ola Lilja + * for ST-Ericsson. + * + * License terms: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef MOP500_AB8500_H +#define MOP500_AB8500_H + +extern struct snd_soc_ops mop500_ab8500_ops[]; + +int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *runtime); +void mop500_ab8500_remove(struct snd_soc_card *card); + +#endif -- GitLab From 9f0ed7a7c547efbce2c15b5017744809e9bba23a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 16 Jun 2012 16:19:27 +0300 Subject: [PATCH 1774/6849] ASoC: Ux500: unlock on an error path There is a missing mutex_unlock() here. The cleanup path also has more debug output. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 389dd660b511..3c795921c5f6 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -1235,7 +1235,8 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, req != ANC_APPLY_IIR) { dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n", __func__, enum_anc_state[req]); - return -EINVAL; + status = -EINVAL; + goto cleanup; } apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR; apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR; -- GitLab From 8b96de31b0cf190fb6b21c4ab1ce310c430b72ae Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Thu, 14 Jun 2012 15:07:56 -0700 Subject: [PATCH 1775/6849] regulator: core.c Only delay when setting voltage requires this minor optimization: move delay code to where delay is set and thus where it is used vs in the main line path. Signed-off-by: Philip Rakity Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ebdd9e0e14d4..663ebd534ef9 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2155,14 +2155,14 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, delay); delay = 0; } - } - /* Insert any necessary delays */ - if (delay >= 1000) { - mdelay(delay / 1000); - udelay(delay % 1000); - } else if (delay) { - udelay(delay); + /* Insert any necessary delays */ + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); + } } if (ret == 0 && best_val >= 0) -- GitLab From a967fbfaca0a979fc34c1097b37d824039a709b1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Jun 2012 20:08:30 +0800 Subject: [PATCH 1776/6849] regulator: wm8350: Use wm8350_ldo_list_voltage instead of open code to verify selected voltage Call wm8350_ldo_list_voltage() instead of open code to verify selected voltage falls within specified range. Use wm8350_ldo_list_voltage() here is less error prone. wm8350_ldo_val_to_mvolts() is only used in wm8350_ldo_list_voltage now, so remove it and move the implementation to wm8350_ldo_list_voltage(). This patch also include below small changes in wm8350_ldo_map_voltage: 1. wm8350_ldo_map_voltage() returns selector, thus rename variable mV to sel. 2. Use DIV_ROUND_UP macro to calculate selector. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 52 +++++++++++----------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 53bf3df02975..c4913be3e1b4 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -108,15 +108,6 @@ static int get_isink_val(int min_uA, int max_uA, u16 *setting) return -EINVAL; } -static inline int wm8350_ldo_val_to_mvolts(unsigned int val) -{ - if (val < 16) - return (val * 50) + 900; - else - return ((val - 16) * 100) + 1800; - -} - static inline unsigned int wm8350_ldo_mvolts_to_val(int mV) { if (mV < 1800) @@ -671,10 +662,22 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) return 0; } +static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector > WM8350_LDO1_VSEL_MASK) + return -EINVAL; + + if (selector < 16) + return (selector * 50000) + 900000; + else + return ((selector - 16) * 100000) + 1800000; +} + static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { - int mV; + int volt, sel; int min_mV = min_uV / 1000; int max_mV = max_uV / 1000; @@ -683,29 +686,16 @@ static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV, if (max_mV < 900 || max_mV > 3300) return -EINVAL; - if (min_mV < 1800) { - /* step size is 50mV < 1800mV */ - mV = (min_mV - 851) / 50; - if (wm8350_ldo_val_to_mvolts(mV) > max_mV) - return -EINVAL; - BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); - } else { - /* step size is 100mV > 1800mV */ - mV = ((min_mV - 1701) / 100) + 16; - if (wm8350_ldo_val_to_mvolts(mV) > max_mV) - return -EINVAL; - BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); - } - - return mV; -} + if (min_mV < 1800) /* step size is 50mV < 1800mV */ + sel = DIV_ROUND_UP(min_uV - 900, 50); + else /* step size is 100mV > 1800mV */ + sel = DIV_ROUND_UP(min_uV - 1800, 100) + 16; -static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector > WM8350_LDO1_VSEL_MASK) + volt = wm8350_ldo_list_voltage(rdev, sel); + if (volt < min_uV || volt > max_uV) return -EINVAL; - return wm8350_ldo_val_to_mvolts(selector) * 1000; + + return sel; } int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start, -- GitLab From c705742201260afd08b05ff84674507735e2b16b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Jun 2012 20:10:26 +0800 Subject: [PATCH 1777/6849] regulator: wm8350: Reuse map_voltage() to get selector of a given uV Reuse map_voltage() to get the selector of a given uV. Then we can remove wm8350_ldo_mvolts_to_val() and wm8350_dcdc_mvolts_to_val(). Also remove unused wm8350_dcdc_val_to_mvolts() function. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 127 +++++++++++---------------- 1 file changed, 50 insertions(+), 77 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index c4913be3e1b4..7f0fa22ef2aa 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -108,24 +108,6 @@ static int get_isink_val(int min_uA, int max_uA, u16 *setting) return -EINVAL; } -static inline unsigned int wm8350_ldo_mvolts_to_val(int mV) -{ - if (mV < 1800) - return (mV - 900) / 50; - else - return ((mV - 1800) / 100) + 16; -} - -static inline int wm8350_dcdc_val_to_mvolts(unsigned int val) -{ - return (val * 25) + 850; -} - -static inline unsigned int wm8350_dcdc_mvolts_to_val(int mV) -{ - return (mV - 850) / 25; -} - static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA, int max_uA) { @@ -353,19 +335,10 @@ EXPORT_SYMBOL_GPL(wm8350_isink_set_flash); static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, mV = uV / 1000, dcdc = rdev_get_id(rdev); + int sel, volt_reg, dcdc = rdev_get_id(rdev); u16 val; - dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, mV); - - if (mV && (mV < 850 || mV > 4025)) { - dev_err(wm8350->dev, - "DCDC%d suspend voltage %d mV out of range\n", - dcdc, mV); - return -EINVAL; - } - if (mV == 0) - mV = 850; + dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000); switch (dcdc) { case WM8350_DCDC_1: @@ -386,10 +359,13 @@ static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) return -EINVAL; } + sel = regulator_map_voltage_linear(rdev, uV, uV); + if (sel < 0) + return -EINVAL; + /* all DCDCs have same mV bits */ val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, - val | wm8350_dcdc_mvolts_to_val(mV)); + wm8350_reg_write(wm8350, volt_reg, val | sel); return 0; } @@ -566,19 +542,49 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev, return 0; } +static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector > WM8350_LDO1_VSEL_MASK) + return -EINVAL; + + if (selector < 16) + return (selector * 50000) + 900000; + else + return ((selector - 16) * 100000) + 1800000; +} + +static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV) +{ + int volt, sel; + int min_mV = min_uV / 1000; + int max_mV = max_uV / 1000; + + if (min_mV < 900 || min_mV > 3300) + return -EINVAL; + if (max_mV < 900 || max_mV > 3300) + return -EINVAL; + + if (min_mV < 1800) /* step size is 50mV < 1800mV */ + sel = DIV_ROUND_UP(min_uV - 900, 50); + else /* step size is 100mV > 1800mV */ + sel = DIV_ROUND_UP(min_uV - 1800, 100) + 16; + + volt = wm8350_ldo_list_voltage(rdev, sel); + if (volt < min_uV || volt > max_uV) + return -EINVAL; + + return sel; +} + static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, mV = uV / 1000, ldo = rdev_get_id(rdev); + int sel, volt_reg, ldo = rdev_get_id(rdev); u16 val; - dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, mV); - - if (mV < 900 || mV > 3300) { - dev_err(wm8350->dev, "LDO%d voltage %d mV out of range\n", - ldo, mV); - return -EINVAL; - } + dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000); switch (ldo) { case WM8350_LDO_1: @@ -597,10 +603,13 @@ static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) return -EINVAL; } + sel = wm8350_ldo_map_voltage(rdev, uV, uV); + if (sel < 0) + return -EINVAL; + /* all LDOs have same mV bits */ val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, - val | wm8350_ldo_mvolts_to_val(mV)); + wm8350_reg_write(wm8350, volt_reg, val | sel); return 0; } @@ -662,42 +671,6 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) return 0; } -static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector > WM8350_LDO1_VSEL_MASK) - return -EINVAL; - - if (selector < 16) - return (selector * 50000) + 900000; - else - return ((selector - 16) * 100000) + 1800000; -} - -static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV) -{ - int volt, sel; - int min_mV = min_uV / 1000; - int max_mV = max_uV / 1000; - - if (min_mV < 900 || min_mV > 3300) - return -EINVAL; - if (max_mV < 900 || max_mV > 3300) - return -EINVAL; - - if (min_mV < 1800) /* step size is 50mV < 1800mV */ - sel = DIV_ROUND_UP(min_uV - 900, 50); - else /* step size is 100mV > 1800mV */ - sel = DIV_ROUND_UP(min_uV - 1800, 100) + 16; - - volt = wm8350_ldo_list_voltage(rdev, sel); - if (volt < min_uV || volt > max_uV) - return -EINVAL; - - return sel; -} - int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start, u16 stop, u16 fault) { -- GitLab From ec0ab07587f0d2af208366158f5fd487311f1c56 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Jun 2012 10:22:59 +0800 Subject: [PATCH 1778/6849] regulator: tps65023: Set n_voltages to 1 for fixed voltage For fixed voltage, the n_voltages should be 1 rather than 0. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index f841bd0db6aa..df8b70d76f9e 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -324,7 +324,10 @@ static int __devinit tps_65023_probe(struct i2c_client *client, tps->desc[i].name = info->name; tps->desc[i].id = i; - tps->desc[i].n_voltages = info->table_len; + if (info->fixed) + tps->desc[i].n_voltages = 1; + else + tps->desc[i].n_voltages = info->table_len; tps->desc[i].ops = (i > TPS65023_DCDC_3 ? &tps65023_ldo_ops : &tps65023_dcdc_ops); tps->desc[i].type = REGULATOR_VOLTAGE; -- GitLab From 6b57c0155cb78d15b0d93b2c7f66ad9536862476 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Jun 2012 13:55:25 +0800 Subject: [PATCH 1779/6849] regulator: tps65023: Fix mask for LDOs output voltage select control According to the datasheet: The LDO_CTRL registers are used to set the output voltage of LDO1 and LDO2. LDO_CTRL[7] and LDO_CTRL[3] are reserved and should always be written to 0. Thus the mask for TPS65023_LDO_1 and TPS65023_LDO_2 should be 0x07 and 0x70 respectively. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index f841bd0db6aa..8f1be8586c72 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -71,7 +71,7 @@ /* LDO_CTRL bitfields */ #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) -#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4)) +#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x07 << ((ldo_id)*4)) /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 -- GitLab From c70ad9dcf08c839b018d8c440bd8c19aabbb08a8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 13 Jun 2012 20:27:14 +0800 Subject: [PATCH 1780/6849] regulator: wm831x-dcdc: Convert wm831x_buckp_ops to regulator_list_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 099da11e989f..fbcff56e0114 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -599,15 +599,6 @@ static struct platform_driver wm831x_buckv_driver = { * BUCKP specifics */ -static int wm831x_buckp_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector <= WM831X_BUCKP_MAX_SELECTOR) - return 850000 + (selector * 25000); - else - return -EINVAL; -} - static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, int min_uV, int max_uV, int *selector) { @@ -620,7 +611,7 @@ static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, else return -EINVAL; - if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV) + if (regulator_list_voltage_linear(rdev, vsel) > max_uV) return -EINVAL; *selector = vsel; @@ -652,7 +643,7 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, static struct regulator_ops wm831x_buckp_ops = { .set_voltage = wm831x_buckp_set_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .list_voltage = wm831x_buckp_list_voltage, + .list_voltage = regulator_list_voltage_linear, .set_suspend_voltage = wm831x_buckp_set_suspend_voltage, .is_enabled = regulator_is_enabled_regmap, @@ -715,6 +706,8 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) dcdc->desc.vsel_mask = WM831X_DC3_ON_VSEL_MASK; dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; dcdc->desc.enable_mask = 1 << id; + dcdc->desc.min_uV = 850000; + dcdc->desc.uV_step = 25000; config.dev = pdev->dev.parent; if (pdata) -- GitLab From e08ef739feec5341fe9382a9f5173ddd56c95f93 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 14:35:32 +0800 Subject: [PATCH 1781/6849] regulator: tps62360: Simplify tps62360_set_voltage_time_sel implementation For linear mappings, we can use below equation to get the voltage difference between new_selector and old_selector: abs(new_selector - old_selector) * rdev->desc->uV_step Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps62360-regulator.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index e534269ed44a..d044a58640e7 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -179,17 +179,10 @@ static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { struct tps62360_chip *tps = rdev_get_drvdata(rdev); - int old_uV, new_uV; - old_uV = regulator_list_voltage_linear(rdev, old_selector); - if (old_uV < 0) - return old_uV; - - new_uV = regulator_list_voltage_linear(rdev, new_selector); - if (new_uV < 0) - return new_uV; - - return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); + return DIV_ROUND_UP(abs(new_selector - old_selector) * + rdev->desc->uV_step, + tps->change_uv_per_us); } static int tps62360_set_mode(struct regulator_dev *rdev, unsigned int mode) -- GitLab From ee5e6253ac22210da892435711890fa2272daa41 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 15:39:34 +0800 Subject: [PATCH 1782/6849] regulator: mc13xxx: Fix voltage checking for mc13xxx_fixed_regulator_set_voltage The voltage range checking should be to ensure mc13xxx_regulators[id].voltages[0] falls with min_uV and max_uV. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/mc13xxx-regulator-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 4fa9704739bc..3e191715fb25 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -158,8 +158,8 @@ int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", __func__, id, min_uV, max_uV); - if (min_uV >= mc13xxx_regulators[id].voltages[0] && - max_uV <= mc13xxx_regulators[id].voltages[0]) + if (min_uV <= mc13xxx_regulators[id].voltages[0] && + mc13xxx_regulators[id].voltages[0] <= max_uV) return 0; else return -EINVAL; -- GitLab From 34e74f39fa9a2c1489444266cc9e973dc1b3a419 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 15:41:48 +0800 Subject: [PATCH 1783/6849] regulator: mc13xxx: Convert to regulator_list_voltage_table Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/mc13783-regulator.c | 38 ++++++++++---------- drivers/regulator/mc13892-regulator.c | 42 +++++++++++----------- drivers/regulator/mc13xxx-regulator-core.c | 30 ++++------------ drivers/regulator/mc13xxx.h | 9 ++--- 4 files changed, 49 insertions(+), 70 deletions(-) diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 7dcdfa283e93..4932e3449fe1 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -93,78 +93,78 @@ /* Voltage Values */ -static const int mc13783_sw3_val[] = { +static const unsigned int mc13783_sw3_val[] = { 5000000, 5000000, 5000000, 5500000, }; -static const int mc13783_vaudio_val[] = { +static const unsigned int mc13783_vaudio_val[] = { 2775000, }; -static const int mc13783_viohi_val[] = { +static const unsigned int mc13783_viohi_val[] = { 2775000, }; -static const int mc13783_violo_val[] = { +static const unsigned int mc13783_violo_val[] = { 1200000, 1300000, 1500000, 1800000, }; -static const int mc13783_vdig_val[] = { +static const unsigned int mc13783_vdig_val[] = { 1200000, 1300000, 1500000, 1800000, }; -static const int mc13783_vgen_val[] = { +static const unsigned int mc13783_vgen_val[] = { 1200000, 1300000, 1500000, 1800000, 1100000, 2000000, 2775000, 2400000, }; -static const int mc13783_vrfdig_val[] = { +static const unsigned int mc13783_vrfdig_val[] = { 1200000, 1500000, 1800000, 1875000, }; -static const int mc13783_vrfref_val[] = { +static const unsigned int mc13783_vrfref_val[] = { 2475000, 2600000, 2700000, 2775000, }; -static const int mc13783_vrfcp_val[] = { +static const unsigned int mc13783_vrfcp_val[] = { 2700000, 2775000, }; -static const int mc13783_vsim_val[] = { +static const unsigned int mc13783_vsim_val[] = { 1800000, 2900000, 3000000, }; -static const int mc13783_vesim_val[] = { +static const unsigned int mc13783_vesim_val[] = { 1800000, 2900000, }; -static const int mc13783_vcam_val[] = { +static const unsigned int mc13783_vcam_val[] = { 1500000, 1800000, 2500000, 2550000, 2600000, 2750000, 2800000, 3000000, }; -static const int mc13783_vrfbg_val[] = { +static const unsigned int mc13783_vrfbg_val[] = { 1250000, }; -static const int mc13783_vvib_val[] = { +static const unsigned int mc13783_vvib_val[] = { 1300000, 1800000, 2000000, 3000000, }; -static const int mc13783_vmmc_val[] = { +static const unsigned int mc13783_vmmc_val[] = { 1600000, 1800000, 2000000, 2600000, 2700000, 2800000, 2900000, 3000000, }; -static const int mc13783_vrf_val[] = { +static const unsigned int mc13783_vrf_val[] = { 1500000, 1875000, 2700000, 2775000, }; -static const int mc13783_gpo_val[] = { +static const unsigned int mc13783_gpo_val[] = { 3100000, }; -static const int mc13783_pwgtdrv_val[] = { +static const unsigned int mc13783_pwgtdrv_val[] = { 5500000, }; @@ -328,7 +328,7 @@ static struct regulator_ops mc13783_gpo_regulator_ops = { .enable = mc13783_gpo_regulator_enable, .disable = mc13783_gpo_regulator_disable, .is_enabled = mc13783_gpo_regulator_is_enabled, - .list_voltage = mc13xxx_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, .set_voltage = mc13xxx_fixed_regulator_set_voltage, .get_voltage = mc13xxx_fixed_regulator_get_voltage, }; diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 970a233dbe46..6329723b5372 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -150,12 +150,12 @@ #define MC13892_USB1 50 #define MC13892_USB1_VUSBEN (1<<3) -static const int mc13892_vcoincell[] = { +static const unsigned int mc13892_vcoincell[] = { 2500000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, }; -static const int mc13892_sw1[] = { +static const unsigned int mc13892_sw1[] = { 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, @@ -164,7 +164,7 @@ static const int mc13892_sw1[] = { 1350000, 1375000 }; -static const int mc13892_sw[] = { +static const unsigned int mc13892_sw[] = { 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, 1000000, 1025000, @@ -176,65 +176,65 @@ static const int mc13892_sw[] = { 1800000, 1825000, 1850000, 1875000 }; -static const int mc13892_swbst[] = { +static const unsigned int mc13892_swbst[] = { 5000000, }; -static const int mc13892_viohi[] = { +static const unsigned int mc13892_viohi[] = { 2775000, }; -static const int mc13892_vpll[] = { +static const unsigned int mc13892_vpll[] = { 1050000, 1250000, 1650000, 1800000, }; -static const int mc13892_vdig[] = { +static const unsigned int mc13892_vdig[] = { 1050000, 1250000, 1650000, 1800000, }; -static const int mc13892_vsd[] = { +static const unsigned int mc13892_vsd[] = { 1800000, 2000000, 2600000, 2700000, 2800000, 2900000, 3000000, 3150000, }; -static const int mc13892_vusb2[] = { +static const unsigned int mc13892_vusb2[] = { 2400000, 2600000, 2700000, 2775000, }; -static const int mc13892_vvideo[] = { +static const unsigned int mc13892_vvideo[] = { 2700000, 2775000, 2500000, 2600000, }; -static const int mc13892_vaudio[] = { +static const unsigned int mc13892_vaudio[] = { 2300000, 2500000, 2775000, 3000000, }; -static const int mc13892_vcam[] = { +static const unsigned int mc13892_vcam[] = { 2500000, 2600000, 2750000, 3000000, }; -static const int mc13892_vgen1[] = { +static const unsigned int mc13892_vgen1[] = { 1200000, 1500000, 2775000, 3150000, }; -static const int mc13892_vgen2[] = { +static const unsigned int mc13892_vgen2[] = { 1200000, 1500000, 1600000, 1800000, 2700000, 2800000, 3000000, 3150000, }; -static const int mc13892_vgen3[] = { +static const unsigned int mc13892_vgen3[] = { 1800000, 2900000, }; -static const int mc13892_vusb[] = { +static const unsigned int mc13892_vusb[] = { 3300000, }; -static const int mc13892_gpo[] = { +static const unsigned int mc13892_gpo[] = { 2750000, }; -static const int mc13892_pwgtdrv[] = { +static const unsigned int mc13892_pwgtdrv[] = { 5000000, }; @@ -394,7 +394,7 @@ static struct regulator_ops mc13892_gpo_regulator_ops = { .enable = mc13892_gpo_regulator_enable, .disable = mc13892_gpo_regulator_disable, .is_enabled = mc13892_gpo_regulator_is_enabled, - .list_voltage = mc13xxx_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, .set_voltage = mc13xxx_fixed_regulator_set_voltage, .get_voltage = mc13xxx_fixed_regulator_get_voltage, }; @@ -436,7 +436,7 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, u32 valread; int ret; - value = mc13892_regulators[id].voltages[selector]; + value = rdev->desc->volt_table[selector]; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, @@ -470,7 +470,7 @@ err: static struct regulator_ops mc13892_sw_regulator_ops = { .is_enabled = mc13xxx_sw_regulator_is_enabled, - .list_voltage = mc13xxx_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, .get_voltage = mc13892_sw_regulator_get_voltage, }; diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 3e191715fb25..8a6b050ff5aa 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -80,20 +80,6 @@ static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) return (val & mc13xxx_regulators[id].enable_bit) != 0; } -int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - int id = rdev_get_id(rdev); - struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); - struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; - - if (selector >= mc13xxx_regulators[id].desc.n_voltages) - return -EINVAL; - - return mc13xxx_regulators[id].voltages[selector]; -} -EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage); - static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { @@ -135,14 +121,14 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages); - return mc13xxx_regulators[id].voltages[val]; + return rdev->desc->volt_table[val]; } struct regulator_ops mc13xxx_regulator_ops = { .enable = mc13xxx_regulator_enable, .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, - .list_voltage = mc13xxx_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, .set_voltage_sel = mc13xxx_regulator_set_voltage_sel, .get_voltage = mc13xxx_regulator_get_voltage, }; @@ -151,15 +137,13 @@ EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops); int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { - struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); - struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", __func__, id, min_uV, max_uV); - if (min_uV <= mc13xxx_regulators[id].voltages[0] && - mc13xxx_regulators[id].voltages[0] <= max_uV) + if (min_uV <= rdev->desc->volt_table[0] && + rdev->desc->volt_table[0] <= max_uV) return 0; else return -EINVAL; @@ -168,13 +152,11 @@ EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev) { - struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); - struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - return mc13xxx_regulators[id].voltages[0]; + return rdev->desc->volt_table[0]; } EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage); @@ -182,7 +164,7 @@ struct regulator_ops mc13xxx_fixed_regulator_ops = { .enable = mc13xxx_regulator_enable, .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, - .list_voltage = mc13xxx_regulator_list_voltage, + .list_voltage = regulator_list_voltage_table, .set_voltage = mc13xxx_fixed_regulator_set_voltage, .get_voltage = mc13xxx_fixed_regulator_get_voltage, }; diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h index 044aba4d28ec..9a8f72ce718e 100644 --- a/drivers/regulator/mc13xxx.h +++ b/drivers/regulator/mc13xxx.h @@ -22,7 +22,6 @@ struct mc13xxx_regulator { int vsel_shift; int vsel_mask; int hi_bit; - int const *voltages; }; struct mc13xxx_regulator_priv { @@ -35,8 +34,6 @@ struct mc13xxx_regulator_priv { extern int mc13xxx_sw_regulator(struct regulator_dev *rdev); extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev); -extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, - unsigned selector); extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector); extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev); @@ -68,6 +65,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .desc = { \ .name = #_name, \ .n_voltages = ARRAY_SIZE(_voltages), \ + .volt_table = _voltages, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .id = prefix ## _name, \ @@ -78,7 +76,6 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .vsel_reg = prefix ## _vsel_reg, \ .vsel_shift = prefix ## _vsel_reg ## _ ## _name ## VSEL,\ .vsel_mask = prefix ## _vsel_reg ## _ ## _name ## VSEL_M,\ - .voltages = _voltages, \ } #define MC13xxx_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops) \ @@ -86,6 +83,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .desc = { \ .name = #_name, \ .n_voltages = ARRAY_SIZE(_voltages), \ + .volt_table = _voltages, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .id = prefix ## _name, \ @@ -93,7 +91,6 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; }, \ .reg = prefix ## _reg, \ .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ - .voltages = _voltages, \ } #define MC13xxx_GPO_DEFINE(prefix, _name, _reg, _voltages, _ops) \ @@ -101,6 +98,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .desc = { \ .name = #_name, \ .n_voltages = ARRAY_SIZE(_voltages), \ + .volt_table = _voltages, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .id = prefix ## _name, \ @@ -108,7 +106,6 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; }, \ .reg = prefix ## _reg, \ .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ - .voltages = _voltages, \ } #define MC13xxx_DEFINE_SW(_name, _reg, _vsel_reg, _voltages, ops) \ -- GitLab From 7142e2138b088da429d94859df0ed05b1b82607c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 10:27:49 +0800 Subject: [PATCH 1784/6849] regulator: ab8500: Use regulator_list_voltage_linear for ab8500_regulator_fixed_ops Also removes set_voltage_time_sel callback from ab8500_regulator_fixed_ops because the voltage won't change. ( And ab8500_regulator_fixed_ops does not implement get_voltage_sel so set_voltage_time_sel won't be called ) Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 41 +++++++++----------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 290c289a653d..c931c7c0ad1b 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -32,7 +32,6 @@ * @regulator_dev: regulator device * @max_uV: maximum voltage (for variable voltage supplies) * @min_uV: minimum voltage (for variable voltage supplies) - * @fixed_uV: typical voltage (for fixed voltage supplies) * @update_bank: bank to control on/off * @update_reg: register to control on/off * @update_mask: mask to enable/disable regulator @@ -48,7 +47,6 @@ struct ab8500_regulator_info { struct regulator_dev *regulator; int max_uV; int min_uV; - int fixed_uV; u8 update_bank; u8 update_reg; u8 update_mask; @@ -271,29 +269,9 @@ static struct regulator_ops ab8500_regulator_ops = { .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; -static int ab8500_fixed_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - - if (info == NULL) { - dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); - return -EINVAL; - } - - return info->fixed_uV; -} - static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) { - struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - - if (info == NULL) { - dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); - return -EINVAL; - } - - return info->fixed_uV; + return rdev->desc->min_uV; } static struct regulator_ops ab8500_regulator_fixed_ops = { @@ -301,9 +279,8 @@ static struct regulator_ops ab8500_regulator_fixed_ops = { .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .get_voltage = ab8500_fixed_get_voltage, - .list_voltage = ab8500_fixed_list_voltage, + .list_voltage = regulator_list_voltage_linear, .enable_time = ab8500_regulator_enable_time, - .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, }; static struct ab8500_regulator_info @@ -408,9 +385,9 @@ static struct ab8500_regulator_info .id = AB8500_LDO_TVOUT, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 2000000, }, .delay = 10000, - .fixed_uV = 2000000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x82, @@ -424,8 +401,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_USB, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 3300000, }, - .fixed_uV = 3300000, .update_bank = 0x03, .update_reg = 0x82, .update_mask = 0x03, @@ -439,8 +416,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_AUDIO, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 2000000, }, - .fixed_uV = 2000000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x02, @@ -454,8 +431,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_ANAMIC1, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 2050000, }, - .fixed_uV = 2050000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x08, @@ -469,8 +446,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_ANAMIC2, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 2050000, }, - .fixed_uV = 2050000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x10, @@ -484,8 +461,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_DMIC, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 1800000, }, - .fixed_uV = 1800000, .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x04, @@ -499,8 +476,8 @@ static struct ab8500_regulator_info .id = AB8500_LDO_ANA, .owner = THIS_MODULE, .n_voltages = 1, + .min_uV = 1200000, }, - .fixed_uV = 1200000, .update_bank = 0x04, .update_reg = 0x06, .update_mask = 0x0c, -- GitLab From 07b9e329f99397d01e4789d64aa2f581a7c94b03 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 8 Jun 2012 10:29:21 +0800 Subject: [PATCH 1785/6849] regulator: ab8500: Remove min_uV and max_uV from struct ab8500_regulator_info The min_uV and max_uV are not really used in the code and misleading because the min_uV and max_uV settings does not match the value in the voltage table. For example, we have static const unsigned int ldo_vaux3_voltages[] = { 1200000, 1500000, 1800000, 2100000, 2500000, 2750000, 2790000, 2910000, }; With below min_uV/max_uV settings for AB8500_LDO_AUX3. .min_uV = 1100000, .max_uV = 3300000, The min_uV/max_uV for AB8500_LDO_AUX3 seems copy-paste from AB8500_LDO_AUX2 and is wrong. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index c931c7c0ad1b..13d424fc1c14 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -30,8 +30,6 @@ * @dev: device pointer * @desc: regulator description * @regulator_dev: regulator device - * @max_uV: maximum voltage (for variable voltage supplies) - * @min_uV: minimum voltage (for variable voltage supplies) * @update_bank: bank to control on/off * @update_reg: register to control on/off * @update_mask: mask to enable/disable regulator @@ -45,8 +43,6 @@ struct ab8500_regulator_info { struct device *dev; struct regulator_desc desc; struct regulator_dev *regulator; - int max_uV; - int min_uV; u8 update_bank; u8 update_reg; u8 update_mask; @@ -301,8 +297,6 @@ static struct ab8500_regulator_info .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), .volt_table = ldo_vauxn_voltages, }, - .min_uV = 1100000, - .max_uV = 3300000, .update_bank = 0x04, .update_reg = 0x09, .update_mask = 0x03, @@ -321,8 +315,6 @@ static struct ab8500_regulator_info .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), .volt_table = ldo_vauxn_voltages, }, - .min_uV = 1100000, - .max_uV = 3300000, .update_bank = 0x04, .update_reg = 0x09, .update_mask = 0x0c, @@ -341,8 +333,6 @@ static struct ab8500_regulator_info .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), .volt_table = ldo_vaux3_voltages, }, - .min_uV = 1100000, - .max_uV = 3300000, .update_bank = 0x04, .update_reg = 0x0a, .update_mask = 0x03, @@ -361,8 +351,6 @@ static struct ab8500_regulator_info .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), .volt_table = ldo_vintcore_voltages, }, - .min_uV = 1100000, - .max_uV = 3300000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x44, -- GitLab From 368a7887698c3e7ec30678853fa7dd1f0720863f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 11 Jun 2012 14:43:57 +0800 Subject: [PATCH 1786/6849] regulator: pcf50633: Convert to regulator_set_voltage_sel_regmap and map_voltage Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/pcf50633-regulator.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 3c9d14c0017b..092e5cb848a1 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -100,13 +100,12 @@ static unsigned int ldo_voltage_value(u8 bits) return 900 + (bits * 100); } -static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, - unsigned *selector) +static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) { struct pcf50633 *pcf; int regulator_id, millivolts; - u8 volt_bits, regnr; + u8 volt_bits; pcf = rdev_get_drvdata(rdev); @@ -116,15 +115,11 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, millivolts = min_uV / 1000; - regnr = rdev->desc->vsel_reg; - switch (regulator_id) { case PCF50633_REGULATOR_AUTO: volt_bits = auto_voltage_bits(millivolts); break; case PCF50633_REGULATOR_DOWN1: - volt_bits = down_voltage_bits(millivolts); - break; case PCF50633_REGULATOR_DOWN2: volt_bits = down_voltage_bits(millivolts); break; @@ -142,9 +137,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, return -EINVAL; } - *selector = volt_bits; - - return pcf50633_reg_write(pcf, regnr, volt_bits); + return volt_bits; } static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, @@ -159,8 +152,6 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, millivolts = auto_voltage_value(index); break; case PCF50633_REGULATOR_DOWN1: - millivolts = down_voltage_value(index); - break; case PCF50633_REGULATOR_DOWN2: millivolts = down_voltage_value(index); break; @@ -182,9 +173,10 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, } static struct regulator_ops pcf50633_regulator_ops = { - .set_voltage = pcf50633_regulator_set_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = pcf50633_regulator_list_voltage, + .map_voltage = pcf50633_regulator_map_voltage, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, -- GitLab From 1bd1955a1f90ca29a3b8ac657028267c8d9de671 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 11 Jun 2012 10:14:28 +0800 Subject: [PATCH 1787/6849] regulator: ab3100: Convert fixed voltage to use regulator_list_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/ab3100.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index b088b6c228c8..16d420b2f7a8 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -43,15 +43,12 @@ * @dev: handle to the device * @plfdata: AB3100 platform data passed in at probe time * @regreg: regulator register number in the AB3100 - * @fixed_voltage: a fixed voltage for this regulator, if this - * 0 the voltages array is used instead. */ struct ab3100_regulator { struct regulator_dev *rdev; struct device *dev; struct ab3100_platform_data *plfdata; u8 regreg; - int fixed_voltage; }; /* The order in which registers are initialized */ @@ -121,15 +118,12 @@ static struct ab3100_regulator ab3100_regulators[AB3100_NUM_REGULATORS] = { { .regreg = AB3100_LDO_A, - .fixed_voltage = LDO_A_VOLTAGE, }, { .regreg = AB3100_LDO_C, - .fixed_voltage = LDO_C_VOLTAGE, }, { .regreg = AB3100_LDO_D, - .fixed_voltage = LDO_D_VOLTAGE, }, { .regreg = AB3100_LDO_E, @@ -246,10 +240,6 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg) u8 regval; int err; - /* Return the voltage for fixed regulators immediately */ - if (abreg->fixed_voltage) - return abreg->fixed_voltage; - /* * For variable types, read out setting and index into * supplied voltage list. @@ -382,11 +372,17 @@ static int ab3100_enable_time_regulator(struct regulator_dev *reg) return 0; } +static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg) +{ + return reg->desc->min_uV; +} + static struct regulator_ops regulator_ops_fixed = { + .list_voltage = regulator_list_voltage_linear, .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, - .get_voltage = ab3100_get_voltage_regulator, + .get_voltage = ab3100_get_fixed_voltage_regulator, .enable_time = ab3100_enable_time_regulator, }; @@ -430,22 +426,28 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .name = "LDO_A", .id = AB3100_LDO_A, .ops = ®ulator_ops_fixed, + .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = LDO_A_VOLTAGE, }, { .name = "LDO_C", .id = AB3100_LDO_C, .ops = ®ulator_ops_fixed, + .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = LDO_C_VOLTAGE, }, { .name = "LDO_D", .id = AB3100_LDO_D, .ops = ®ulator_ops_fixed, + .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, + .min_uV = LDO_D_VOLTAGE, }, { .name = "LDO_E", -- GitLab From 0a4796896bda399a63090dad267896ea93d44fa7 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Jun 2012 10:46:43 +0800 Subject: [PATCH 1788/6849] regulator: wm831x-ldo: Convert to regulator_set_voltage_sel_regmap and map_voltage Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-ldo.c | 129 ++++++++++----------------------- 1 file changed, 38 insertions(+), 91 deletions(-) diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index f23d020e9503..04d8a413c260 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -78,13 +78,10 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, - int min_uV, int max_uV, - unsigned *selector) +static int wm831x_gp_ldo_map_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) { - struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - struct wm831x *wm831x = ldo->wm831x; - int vsel, ret; + int volt, vsel; if (min_uV < 900000) vsel = 0; @@ -94,36 +91,25 @@ static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, vsel = ((min_uV - 1700000) / 100000) + WM831X_GP_LDO_SELECTOR_LOW + 1; - ret = wm831x_gp_ldo_list_voltage(rdev, vsel); - if (ret < 0) - return ret; - if (ret < min_uV || ret > max_uV) + volt = wm831x_gp_ldo_list_voltage(rdev, vsel); + if (volt < min_uV || volt > max_uV) return -EINVAL; - *selector = vsel; - - return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, vsel); -} - -static int wm831x_gp_ldo_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, - unsigned *selector) -{ - struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - int reg = ldo->base + WM831X_LDO_ON_CONTROL; - - return wm831x_gp_ldo_set_voltage_int(rdev, reg, min_uV, max_uV, - selector); + return vsel; } static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; - unsigned int selector; + struct wm831x *wm831x = ldo->wm831x; + int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; - return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); + sel = wm831x_gp_ldo_map_voltage(rdev, uV, uV); + if (sel < 0) + return sel; + + return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, sel); } static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev) @@ -243,8 +229,9 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev, static struct regulator_ops wm831x_gp_ldo_ops = { .list_voltage = wm831x_gp_ldo_list_voltage, + .map_voltage = wm831x_gp_ldo_map_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage = wm831x_gp_ldo_set_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage, .get_mode = wm831x_gp_ldo_get_mode, .set_mode = wm831x_gp_ldo_set_mode, @@ -384,13 +371,10 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg, - int min_uV, int max_uV, - unsigned *selector) +static int wm831x_aldo_map_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) { - struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - struct wm831x *wm831x = ldo->wm831x; - int vsel, ret; + int volt, vsel; if (min_uV < 1000000) vsel = 0; @@ -400,35 +384,26 @@ static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg, vsel = ((min_uV - 1700000) / 100000) + WM831X_ALDO_SELECTOR_LOW + 1; - ret = wm831x_aldo_list_voltage(rdev, vsel); - if (ret < 0) - return ret; - if (ret < min_uV || ret > max_uV) + volt = wm831x_aldo_list_voltage(rdev, vsel); + if (volt < min_uV || volt > max_uV) return -EINVAL; - *selector = vsel; - - return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, vsel); -} - -static int wm831x_aldo_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, unsigned *selector) -{ - struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - int reg = ldo->base + WM831X_LDO_ON_CONTROL; + return vsel; - return wm831x_aldo_set_voltage_int(rdev, reg, min_uV, max_uV, - selector); } static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; - unsigned int selector; + struct wm831x *wm831x = ldo->wm831x; + int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; + + sel = wm831x_aldo_map_voltage(rdev, uV, uV); + if (sel < 0) + return sel; - return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector); + return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, sel); } static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) @@ -506,8 +481,9 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev) static struct regulator_ops wm831x_aldo_ops = { .list_voltage = wm831x_aldo_list_voltage, + .map_voltage = wm831x_aldo_map_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage = wm831x_aldo_set_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .set_suspend_voltage = wm831x_aldo_set_suspend_voltage, .get_mode = wm831x_aldo_get_mode, .set_mode = wm831x_aldo_set_mode, @@ -628,47 +604,18 @@ static struct platform_driver wm831x_aldo_driver = { #define WM831X_ALIVE_LDO_MAX_SELECTOR 0xf -static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, - int reg, - int min_uV, int max_uV, - unsigned *selector) -{ - struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - struct wm831x *wm831x = ldo->wm831x; - int vsel, ret; - - vsel = (min_uV - 800000) / 50000; - - ret = regulator_list_voltage_linear(rdev, vsel); - if (ret < 0) - return ret; - if (ret < min_uV || ret > max_uV) - return -EINVAL; - - *selector = vsel; - - return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, vsel); -} - -static int wm831x_alive_ldo_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, - unsigned *selector) -{ - struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL; - - return wm831x_alive_ldo_set_voltage_int(rdev, reg, min_uV, max_uV, - selector); -} - static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); - int reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL; - unsigned selector; + struct wm831x *wm831x = ldo->wm831x; + int sel, reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL; + + sel = regulator_map_voltage_linear(rdev, uV, uV); + if (sel < 0) + return sel; - return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); + return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, sel); } static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) @@ -692,7 +639,7 @@ static struct regulator_ops wm831x_alive_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage = wm831x_alive_ldo_set_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage, .get_status = wm831x_alive_ldo_get_status, -- GitLab From d580cb5e78763eb3d8149e0d60a0a73d355d27c5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 13 Jun 2012 20:27:58 +0800 Subject: [PATCH 1789/6849] regulator: wm831x-dcdc: Convert wm831x_buckp_ops to regulator_set_voltage_sel_regmap Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 44 +++++++-------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index fbcff56e0114..91b5b0a727ef 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -599,51 +599,25 @@ static struct platform_driver wm831x_buckv_driver = { * BUCKP specifics */ -static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg, - int min_uV, int max_uV, int *selector) +static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); struct wm831x *wm831x = dcdc->wm831x; - u16 vsel; - - if (min_uV <= 34000000) - vsel = (min_uV - 850000) / 25000; - else - return -EINVAL; - - if (regulator_list_voltage_linear(rdev, vsel) > max_uV) - return -EINVAL; - - *selector = vsel; - - return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel); -} - -static int wm831x_buckp_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, - unsigned *selector) -{ - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; - - return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV, - selector); -} - -static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, - int uV) -{ - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; - unsigned selector; + int sel; + + sel = regulator_map_voltage_linear(rdev, uV, uV); + if (sel < 0) + return sel; - return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector); + return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, sel); } static struct regulator_ops wm831x_buckp_ops = { - .set_voltage = wm831x_buckp_set_voltage, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .set_suspend_voltage = wm831x_buckp_set_suspend_voltage, .is_enabled = regulator_is_enabled_regmap, -- GitLab From b5fb77e0188dc85630b395eb0faddc4987be6ddb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 13 Jun 2012 20:29:17 +0800 Subject: [PATCH 1790/6849] regulator: wm831x-dcdc: Convert wm831x_buckv_ops to set_voltage_sel and map_voltage Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 91b5b0a727ef..7413885be01b 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -215,8 +215,8 @@ static int wm831x_buckv_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int wm831x_buckv_map_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) { u16 vsel; @@ -251,20 +251,14 @@ static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) return 0; } -static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV, unsigned *selector) +static int wm831x_buckv_set_voltage_sel(struct regulator_dev *rdev, + unsigned vsel) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); struct wm831x *wm831x = dcdc->wm831x; int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG; int dvs_reg = dcdc->base + WM831X_DCDC_DVS_CONTROL; - int vsel, ret; - - vsel = wm831x_buckv_select_min_voltage(rdev, min_uV, max_uV); - if (vsel < 0) - return vsel; - - *selector = vsel; + int ret; /* If this value is already set then do a GPIO update if we can */ if (dcdc->dvs_gpio && dcdc->on_vsel == vsel) @@ -315,7 +309,7 @@ static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; int vsel; - vsel = wm831x_buckv_select_min_voltage(rdev, uV, uV); + vsel = wm831x_buckv_map_voltage(rdev, uV, uV); if (vsel < 0) return vsel; @@ -373,9 +367,10 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) } static struct regulator_ops wm831x_buckv_ops = { - .set_voltage = wm831x_buckv_set_voltage, + .set_voltage_sel = wm831x_buckv_set_voltage_sel, .get_voltage_sel = wm831x_buckv_get_voltage_sel, .list_voltage = wm831x_buckv_list_voltage, + .map_voltage = wm831x_buckv_map_voltage, .set_suspend_voltage = wm831x_buckv_set_suspend_voltage, .set_current_limit = wm831x_buckv_set_current_limit, .get_current_limit = wm831x_buckv_get_current_limit, -- GitLab From 6f0b2c696ca340cc2da381fe693fda3f8fdb2149 Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Mon, 11 Jun 2012 17:41:08 +0530 Subject: [PATCH 1791/6849] regulator: Add ramp_delay configuration to constraints For some hardwares ramp_delay for BUCKs is a configurable parameter which can be configured through DT or board file.This patch adds ramp_delay to regulator constraints and allow user to configure it for regulators which supports this feature, through DT or board file. It will provide two ways of setting the ramp_delay for a regulator: First, by setting it as constraints in board file(for configurable regulators) and set_machine_constraints() will take care of setting it on hardware by calling(the provided) .set_ramp_delay() operation(callback). Second, by setting it as data in regulator_desc(as fixed/default ramp_delay rate) for a regulator in driver. regulator_set_voltage_time_sel() will give preference to constraints->ramp_delay while reading ramp_delay rate for regulator. Similarly users should also take care accordingly while refering ramp_delay rate(in case of implementing their private .set_voltage_time_sel() callbacks for different regulators). [Rewrote subject for 80 columns -- broonie] Signed-off-by: Yadwinder Singh Brar Signed-off-by: Mark Brown --- .../bindings/regulator/regulator.txt | 1 + drivers/regulator/core.c | 23 +++++++++++++++---- drivers/regulator/of_regulator.c | 6 ++++- include/linux/regulator/driver.h | 3 +++ include/linux/regulator/machine.h | 3 +++ 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 5b7a408acdaa..d0a7b1296a36 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -10,6 +10,7 @@ Optional properties: - regulator-always-on: boolean, regulator should never be disabled - regulator-boot-on: bootloader/firmware enabled regulator - -supply: phandle to the parent supply/regulator node +- regulator-ramp-delay: ramp delay for regulator(in mV/uS) Example: diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6ffca9b32388..b615ae6606db 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -967,6 +967,14 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } + if (rdev->constraints->ramp_delay && ops->set_ramp_delay) { + ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay); + if (ret < 0) { + rdev_err(rdev, "failed to set ramp_delay\n"); + goto out; + } + } + print_constraints(rdev); return 0; out: @@ -2296,10 +2304,17 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { - if (rdev->desc->ramp_delay && rdev->desc->uV_step) - return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), - rdev->desc->ramp_delay * 1000); + if (rdev->desc->uV_step) { + if (rdev->constraints->ramp_delay) + return DIV_ROUND_UP(rdev->desc->uV_step * + abs(new_selector - old_selector), + rdev->constraints->ramp_delay * 1000); + if (rdev->desc->ramp_delay) + return DIV_ROUND_UP(rdev->desc->uV_step * + abs(new_selector - old_selector), + rdev->desc->ramp_delay * 1000); + rdev_warn(rdev, "ramp_delay not set\n"); + } return 0; } diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 56593b75168a..e2a731079066 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -20,7 +20,7 @@ static void of_get_regulation_constraints(struct device_node *np, struct regulator_init_data **init_data) { const __be32 *min_uV, *max_uV, *uV_offset; - const __be32 *min_uA, *max_uA; + const __be32 *min_uA, *max_uA, *ramp_delay; struct regulation_constraints *constraints = &(*init_data)->constraints; constraints->name = of_get_property(np, "regulator-name", NULL); @@ -60,6 +60,10 @@ static void of_get_regulation_constraints(struct device_node *np, constraints->always_on = true; else /* status change should be possible if not always on. */ constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; + + ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL); + if (ramp_delay) + constraints->min_uV = be32_to_cpu(*ramp_delay); } /** diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index ae5c25379237..ddc155d262da 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -67,6 +67,8 @@ enum regulator_status { * * @enable_time: Time taken for the regulator voltage output voltage to * stabilise after being enabled, in microseconds. + * @set_ramp_delay: Set the ramp delay for the regulator. The driver should + * select ramp delay equal to or less than(closest) ramp_delay. * @set_voltage_time_sel: Time taken for the regulator voltage output voltage * to stabilise after being set to a new value, in microseconds. * The function provides the from and to voltage selector, the @@ -113,6 +115,7 @@ struct regulator_ops { /* Time taken to enable or set voltage on the regulator */ int (*enable_time) (struct regulator_dev *); + int (*set_ramp_delay) (struct regulator_dev *, int ramp_delay); int (*set_voltage_time_sel) (struct regulator_dev *, unsigned int old_selector, unsigned int new_selector); diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index b02108446be7..5f37ad3cc172 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -92,6 +92,7 @@ struct regulator_state { * mode. * @initial_state: Suspend state to set by default. * @initial_mode: Mode to set at startup. + * @ramp_delay: Time to settle down after voltage change (unit: mV/us) */ struct regulation_constraints { @@ -125,6 +126,8 @@ struct regulation_constraints { /* mode to set on startup */ unsigned int initial_mode; + unsigned int ramp_delay; + /* constraint flags */ unsigned always_on:1; /* regulator never off when system is on */ unsigned boot_on:1; /* bootloader/firmware enabled regulator */ -- GitLab From fc3ebd788e894b4dd6c9524cb3874eeeb1e862d6 Mon Sep 17 00:00:00 2001 From: Krystian Garbaciak Date: Fri, 15 Jun 2012 11:23:56 +0100 Subject: [PATCH 1792/6849] regmap: Move lock out from internal function _regmap_update_bits(). Locks are moved to regmap_update_bits(), which allows to reenter internal function _regmap_update_bits() from inside of regmap read/write routines. Signed-off-by: Krystian Garbaciak Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index c89aa01fb1de..652017991da6 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -982,11 +982,9 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, int ret; unsigned int tmp, orig; - map->lock(map); - ret = _regmap_read(map, reg, &orig); if (ret != 0) - goto out; + return ret; tmp = orig & ~mask; tmp |= val & mask; @@ -998,9 +996,6 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, *change = false; } -out: - map->unlock(map); - return ret; } @@ -1018,7 +1013,13 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val) { bool change; - return _regmap_update_bits(map, reg, mask, val, &change); + int ret; + + map->lock(map); + ret = _regmap_update_bits(map, reg, mask, val, &change); + map->unlock(map); + + return ret; } EXPORT_SYMBOL_GPL(regmap_update_bits); @@ -1038,7 +1039,12 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change) { - return _regmap_update_bits(map, reg, mask, val, change); + int ret; + + map->lock(map); + ret = _regmap_update_bits(map, reg, mask, val, change); + map->unlock(map); + return ret; } EXPORT_SYMBOL_GPL(regmap_update_bits_check); -- GitLab From 6863ca6227598d15c372f1e03449bbb4cfbcca7f Mon Sep 17 00:00:00 2001 From: Krystian Garbaciak Date: Fri, 15 Jun 2012 11:23:56 +0100 Subject: [PATCH 1793/6849] regmap: Add support for register indirect addressing. Devices with register paging or indirectly accessed registers can configure register mapping to map those on virtual address range. During access to virtually mapped register range, indirect addressing is processed automatically, in following steps: 1. selector for page or indirect register is updated (when needed); 2. register in data window is accessed. Configuration should provide minimum and maximum register for virtual range, details of selector field for page selection, minimum and maximum register of data window for indirect access. Virtual range registers are managed by cache as well as direct access registers. In order to make indirect access more efficient, selector register should be declared as non-volatile, if possible. struct regmap_config is extended with the following: struct regmap_range_cfg *ranges; unsigned int n_ranges; [Also reordered debugfs init to later on since the cleanup code was conflicting with the new cleanup code for ranges anyway -- broonie] Signed-off-by: Krystian Garbaciak Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 17 +++ drivers/base/regmap/regmap.c | 201 ++++++++++++++++++++++++++++++++- include/linux/regmap.h | 39 +++++++ 3 files changed, 252 insertions(+), 5 deletions(-) diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index b986b8660b0c..80f9ab9c3aa4 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -95,6 +95,9 @@ struct regmap { /* if set, converts bulk rw to single rw */ bool use_single_rw; + + struct rb_root range_tree; + void *selector_work_buf; /* Scratch buffer used for selector */ }; struct regcache_ops { @@ -115,6 +118,20 @@ bool regmap_precious(struct regmap *map, unsigned int reg); int _regmap_write(struct regmap *map, unsigned int reg, unsigned int val); +struct regmap_range_node { + struct rb_node node; + + unsigned int range_min; + unsigned int range_max; + + unsigned int selector_reg; + unsigned int selector_mask; + int selector_shift; + + unsigned int window_start; + unsigned int window_len; +}; + #ifdef CONFIG_DEBUG_FS extern void regmap_debugfs_initcall(void); extern void regmap_debugfs_init(struct regmap *map, const char *name); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 652017991da6..83a0166420a4 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -15,12 +15,17 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include #include "internal.h" +static int _regmap_update_bits(struct regmap *map, unsigned int reg, + unsigned int mask, unsigned int val, + bool *change); + bool regmap_writeable(struct regmap *map, unsigned int reg) { if (map->max_register && reg > map->max_register) @@ -208,6 +213,67 @@ static void dev_get_regmap_release(struct device *dev, void *res) */ } +static bool _regmap_range_add(struct regmap *map, + struct regmap_range_node *data) +{ + struct rb_root *root = &map->range_tree; + struct rb_node **new = &(root->rb_node), *parent = NULL; + + while (*new) { + struct regmap_range_node *this = + container_of(*new, struct regmap_range_node, node); + + parent = *new; + if (data->range_max < this->range_min) + new = &((*new)->rb_left); + else if (data->range_min > this->range_max) + new = &((*new)->rb_right); + else + return false; + } + + rb_link_node(&data->node, parent, new); + rb_insert_color(&data->node, root); + + return true; +} + +static struct regmap_range_node *_regmap_range_lookup(struct regmap *map, + unsigned int reg) +{ + struct rb_node *node = map->range_tree.rb_node; + + while (node) { + struct regmap_range_node *this = + container_of(node, struct regmap_range_node, node); + + if (reg < this->range_min) + node = node->rb_left; + else if (reg > this->range_max) + node = node->rb_right; + else + return this; + } + + return NULL; +} + +static void regmap_range_exit(struct regmap *map) +{ + struct rb_node *next; + struct regmap_range_node *range_node; + + next = rb_first(&map->range_tree); + while (next) { + range_node = rb_entry(next, struct regmap_range_node, node); + next = rb_next(&range_node->node); + rb_erase(&range_node->node, &map->range_tree); + kfree(range_node); + } + + kfree(map->selector_work_buf); +} + /** * regmap_init(): Initialise register map * @@ -227,6 +293,7 @@ struct regmap *regmap_init(struct device *dev, { struct regmap *map, **m; int ret = -EINVAL; + int i, j; if (!bus || !config) goto err; @@ -364,27 +431,88 @@ struct regmap *regmap_init(struct device *dev, goto err_map; } - regmap_debugfs_init(map, config->name); + map->range_tree = RB_ROOT; + for (i = 0; i < config->n_ranges; i++) { + const struct regmap_range_cfg *range_cfg = &config->ranges[i]; + struct regmap_range_node *new; + + /* Sanity check */ + if (range_cfg->range_max < range_cfg->range_min || + range_cfg->range_max > map->max_register || + range_cfg->selector_reg > map->max_register || + range_cfg->window_len == 0) + goto err_range; + + /* Make sure, that this register range has no selector + or data window within its boundary */ + for (j = 0; j < config->n_ranges; j++) { + unsigned sel_reg = config->ranges[j].selector_reg; + unsigned win_min = config->ranges[j].window_start; + unsigned win_max = win_min + + config->ranges[j].window_len - 1; + + if (range_cfg->range_min <= sel_reg && + sel_reg <= range_cfg->range_max) { + goto err_range; + } + + if (!(win_max < range_cfg->range_min || + win_min > range_cfg->range_max)) { + goto err_range; + } + } + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (new == NULL) { + ret = -ENOMEM; + goto err_range; + } + + new->range_min = range_cfg->range_min; + new->range_max = range_cfg->range_max; + new->selector_reg = range_cfg->selector_reg; + new->selector_mask = range_cfg->selector_mask; + new->selector_shift = range_cfg->selector_shift; + new->window_start = range_cfg->window_start; + new->window_len = range_cfg->window_len; + + if (_regmap_range_add(map, new) == false) { + kfree(new); + goto err_range; + } + + if (map->selector_work_buf == NULL) { + map->selector_work_buf = + kzalloc(map->format.buf_size, GFP_KERNEL); + if (map->selector_work_buf == NULL) { + ret = -ENOMEM; + goto err_range; + } + } + } ret = regcache_init(map, config); if (ret < 0) - goto err_debugfs; + goto err_range; + + regmap_debugfs_init(map, config->name); /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); if (!m) { ret = -ENOMEM; - goto err_cache; + goto err_debugfs; } *m = map; devres_add(dev, m); return map; -err_cache: - regcache_exit(map); err_debugfs: regmap_debugfs_exit(map); + regcache_exit(map); +err_range: + regmap_range_exit(map); kfree(map->work_buf); err_map: kfree(map); @@ -481,6 +609,7 @@ void regmap_exit(struct regmap *map) { regcache_exit(map); regmap_debugfs_exit(map); + regmap_range_exit(map); if (map->bus->free_context) map->bus->free_context(map->bus_context); kfree(map->work_buf); @@ -526,6 +655,56 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name) } EXPORT_SYMBOL_GPL(dev_get_regmap); +static int _regmap_select_page(struct regmap *map, unsigned int *reg, + unsigned int val_num) +{ + struct regmap_range_node *range; + void *orig_work_buf; + unsigned int win_offset; + unsigned int win_page; + bool page_chg; + int ret; + + range = _regmap_range_lookup(map, *reg); + if (range) { + win_offset = (*reg - range->range_min) % range->window_len; + win_page = (*reg - range->range_min) / range->window_len; + + if (val_num > 1) { + /* Bulk write shouldn't cross range boundary */ + if (*reg + val_num - 1 > range->range_max) + return -EINVAL; + + /* ... or single page boundary */ + if (val_num > range->window_len - win_offset) + return -EINVAL; + } + + /* It is possible to have selector register inside data window. + In that case, selector register is located on every page and + it needs no page switching, when accessed alone. */ + if (val_num > 1 || + range->window_start + win_offset != range->selector_reg) { + /* Use separate work_buf during page switching */ + orig_work_buf = map->work_buf; + map->work_buf = map->selector_work_buf; + + ret = _regmap_update_bits(map, range->selector_reg, + range->selector_mask, + win_page << range->selector_shift, + &page_chg); + if (ret < 0) + return ret; + + map->work_buf = orig_work_buf; + } + + *reg = range->window_start + win_offset; + } + + return 0; +} + static int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { @@ -563,6 +742,10 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, } } + ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); + if (ret < 0) + return ret; + map->format.format_reg(map->work_buf, reg, map->reg_shift); u8[0] |= map->write_flag_mask; @@ -626,6 +809,10 @@ int _regmap_write(struct regmap *map, unsigned int reg, trace_regmap_reg_write(map->dev, reg, val); if (map->format.format_write) { + ret = _regmap_select_page(map, ®, 1); + if (ret < 0) + return ret; + map->format.format_write(map, reg, val); trace_regmap_hw_write_start(map->dev, reg, 1); @@ -783,6 +970,10 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, u8 *u8 = map->work_buf; int ret; + ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); + if (ret < 0) + return ret; + map->format.format_reg(map->work_buf, reg, map->reg_shift); /* diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 56af22ec9aba..5f69d4ad3eb1 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -14,12 +14,14 @@ */ #include +#include struct module; struct device; struct i2c_client; struct spi_device; struct regmap; +struct regmap_range_cfg; /* An enum of all the supported cache types */ enum regcache_type { @@ -84,6 +86,9 @@ struct reg_default { * @reg_defaults_raw: Power on reset values for registers (for use with * register cache support). * @num_reg_defaults_raw: Number of elements in reg_defaults_raw. + * + * @ranges: Array of configuration entries for virtual address ranges. + * @num_ranges: Number of range configuration entries. */ struct regmap_config { const char *name; @@ -109,6 +114,40 @@ struct regmap_config { u8 write_flag_mask; bool use_single_rw; + + const struct regmap_range_cfg *ranges; + unsigned int n_ranges; +}; + +/** + * Configuration for indirectly accessed or paged registers. + * Registers, mapped to this virtual range, are accessed in two steps: + * 1. page selector register update; + * 2. access through data window registers. + * + * @range_min: Address of the lowest register address in virtual range. + * @range_max: Address of the highest register in virtual range. + * + * @page_sel_reg: Register with selector field. + * @page_sel_mask: Bit shift for selector value. + * @page_sel_shift: Bit mask for selector value. + * + * @window_start: Address of first (lowest) register in data window. + * @window_len: Number of registers in data window. + */ +struct regmap_range_cfg { + /* Registers of virtual address range */ + unsigned int range_min; + unsigned int range_max; + + /* Page selector for indirect addressing */ + unsigned int selector_reg; + unsigned int selector_mask; + int selector_shift; + + /* Data window (per each page) */ + unsigned int window_start; + unsigned int window_len; }; typedef int (*regmap_hw_write)(void *context, const void *data, -- GitLab From f43380981716c9b48bf2809e4cd1cb0c6b71429d Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sun, 17 Jun 2012 21:13:34 +0100 Subject: [PATCH 1794/6849] ARM: 7426/1: mmc: mmci: Remove wrong error handling of gpio 0 Zero is a valid GPIO and shouldn't be handled as an error return code from of_get_named_gpio(). It was a leftover from old code before getting pdata->gpio_*() was modified. Signed-off-by: Roland Stigge Acked-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0045ee001ec7..78d3e4845997 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1216,12 +1216,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np, int bus_width = 0; pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); - if (!pdata->gpio_wp) - pdata->gpio_wp = -1; - pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0); - if (!pdata->gpio_cd) - pdata->gpio_cd = -1; if (of_get_property(np, "cd-inverted", NULL)) pdata->cd_invert = true; -- GitLab From 2805b9ab7c836cfbe01e86129983e36205078cb2 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sun, 17 Jun 2012 21:14:27 +0100 Subject: [PATCH 1795/6849] ARM: 7427/1: mmc: mmci: Defer probe() in case of yet uninitialized GPIOs If the GPIOs used by the MMCI driver are not registered yet when the driver is probe()d, they can't be used. This happens if the mmci driver is probed before the respective GPIO controller (e.g. on the LPC32xx EA3250 board, the PCA9532 GPIO controller would be initialized via DT after mmci). Therefore, we defer mmci in this case. Signed-off-by: Roland Stigge Acked-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 78d3e4845997..50ff19a62368 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1425,6 +1425,10 @@ static int __devinit mmci_probe(struct amba_device *dev, writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); + if (plat->gpio_cd == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_cd; + } if (gpio_is_valid(plat->gpio_cd)) { ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); if (ret == 0) @@ -1448,6 +1452,10 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret >= 0) host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); } + if (plat->gpio_wp == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_wp; + } if (gpio_is_valid(plat->gpio_wp)) { ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); if (ret == 0) -- GitLab From a6dc8c04218eb752ff79cdc24a995cf51866caed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20Kalliom=C3=A4ki?= Date: Sun, 17 Jun 2012 17:05:24 -0400 Subject: [PATCH 1796/6849] hfsplus: fix overflow in sector calculations in hfsplus_submit_bio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variable io_size was unsigned int, which caused the wrong sector number to be calculated after aligning it. This then caused mount to fail with big volumes, as backup volume header information was searched from a wrong sector. Signed-off-by: Janne Kalliomäki Signed-off-by: Christoph Hellwig Signed-off-by: Linus Torvalds --- fs/hfsplus/wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 7daf4b852d1c..90effcccca9a 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -56,7 +56,7 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, DECLARE_COMPLETION_ONSTACK(wait); struct bio *bio; int ret = 0; - unsigned int io_size; + u64 io_size; loff_t start; int offset; -- GitLab From 7dea9665fee828fb56db3bae5b9685d9fa006d33 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Sun, 17 Jun 2012 17:05:25 -0400 Subject: [PATCH 1797/6849] hfsplus: fix bless ioctl when used with hardlinks HFS+ doesn't really implement hard links - instead, hardlinks are indicated by a magic file type which refers to an indirect node in a hidden directory. The spec indicates that stat() should return the inode number of the indirect node, but it turns out that this doesn't satisfy the firmware when it's looking for a bootloader - it wants the catalog ID of the hardlink file instead. Fix up this case. Signed-off-by: Matthew Garrett Signed-off-by: Christoph Hellwig Signed-off-by: Linus Torvalds --- fs/hfsplus/ioctl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index c640ba57074b..09addc8615fa 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -31,6 +31,7 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); struct hfsplus_vh *vh = sbi->s_vhdr; struct hfsplus_vh *bvh = sbi->s_backup_vhdr; + u32 cnid = (unsigned long)dentry->d_fsdata; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -41,8 +42,12 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) vh->finder_info[0] = bvh->finder_info[0] = cpu_to_be32(parent_ino(dentry)); - /* Bootloader */ - vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(inode->i_ino); + /* + * Bootloader. Just using the inode here breaks in the case of + * hard links - the firmware wants the ID of the hard link file, + * but the inode points at the indirect inode + */ + vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(cnid); /* Per spec, the OS X system folder - same as finder_info[0] here */ vh->finder_info[5] = bvh->finder_info[5] = -- GitLab From b6138ed60457ef1e9150692f6790eb4a2a696308 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Sat, 16 Jun 2012 23:29:00 +0000 Subject: [PATCH 1798/6849] ixgbe: Fix PHC loophole allowing misconfiguration of increment register This patch fixes a potential hole when configuring the cycle counter used to generate the nanosecond time clock. This clock is based off of the SYSTIME registers along with the TIMINCA registers. The TIMINCA register determines the increment to be added to the SYSTIME registers every DMA clock tick. This register needs to be reconfigured whenever the link-speed changes. However, the value calculated stays the same when link is down and when link is up. Misconfiguration can occur if the link status changes due to a reset, which causes the TIMINCA register to be reset. This reset puts the device in an unstable state where the SYSTIME registers stop incrementing and the PTP protocol does not function. The solution is to double check the TIMINCA value and always reset the value if the register is zero. This prevents a misconfiguration bug that halts the PHC. Signed-off-by: Jacob Keller Acked-by: Don Skidmore Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index ddc6a4d19302..dcebd128becf 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -708,6 +708,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 incval = 0; + u32 timinca = 0; u32 shift = 0; u32 cycle_speed; unsigned long flags; @@ -730,8 +731,16 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) break; } - /* Bail if the cycle speed didn't change */ - if (adapter->cycle_speed == cycle_speed) + /* + * grab the current TIMINCA value from the register so that it can be + * double checked. If the register value has been cleared, it must be + * reset to the correct value for generating a cyclecounter. If + * TIMINCA is zero, the SYSTIME registers do not increment at all. + */ + timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA); + + /* Bail if the cycle speed didn't change and TIMINCA is non-zero */ + if (adapter->cycle_speed == cycle_speed && timinca) return; /* disable the SDP clock out */ -- GitLab From 79504d708d8be4131fbb115912521739c11db750 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Sun, 17 Jun 2012 02:04:50 +0000 Subject: [PATCH 1799/6849] bnx2x: correct LPI pass-through configuration Commit c8c60d88c59cbb48737732ba948663a3efe882aa contained an incorrect logic which enabled a buffer overflow when accessing an array during LPI pass-through configuration. This patch fixes this issue by removing that logic altogether. Signed-off-by: Yuval Mintz Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index c7c814db027d..91aa565d4374 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -4057,18 +4057,12 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); /* Enable LPI pass through */ - if ((params->eee_mode & EEE_MODE_ADV_LPI) && - (phy->flags & FLAGS_EEE_10GBT) && - (!(params->eee_mode & EEE_MODE_ENABLE_LPI) || - bnx2x_eee_calc_timer(params)) && - (params->req_duplex[bnx2x_phy_selection(params)] == DUPLEX_FULL)) { - DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n"); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_EEE_COMBO_CONTROL0, - 0x7c); - bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL4_MISC5, 0xc000); - } + DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n"); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_EEE_COMBO_CONTROL0, + 0x7c); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC5, 0xc000); /* 10G XFI Full Duplex */ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, -- GitLab From b7e5887e0e414bde0a2f311ae3fbea5611562e29 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 13 Jun 2012 19:51:43 +0000 Subject: [PATCH 1800/6849] be2net: reduce gso_max_size setting to account for ethernet header. The maximum size of packet that can be handled by controller including ethernet header is 65535. Reducing gso_max_size accordingly. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fdb50cec6b51..501dfa9c88ec 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3237,7 +3237,7 @@ static void be_netdev_init(struct net_device *netdev) netdev->flags |= IFF_MULTICAST; - netif_set_gso_max_size(netdev, 65535); + netif_set_gso_max_size(netdev, 65535 - ETH_HLEN); netdev->netdev_ops = &be_netdev_ops; -- GitLab From 97f1d8cd8d61642d01af1fc181f3103314128c3b Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 13 Jun 2012 19:51:44 +0000 Subject: [PATCH 1801/6849] be2net: Modify error message to incorporate subsystem Modify IOCTL error message to print subsystem also. Signed-off-by: Vasundhara Volam Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 8d06ea381741..921c2082af4c 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -122,15 +122,15 @@ static int be_mcc_compl_process(struct be_adapter *adapter, goto done; if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { - dev_warn(&adapter->pdev->dev, "This domain(VM) is not " - "permitted to execute this cmd (opcode %d)\n", - opcode); + dev_warn(&adapter->pdev->dev, + "opcode %d-%d is not permitted\n", + opcode, subsystem); } else { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & CQE_STATUS_EXTD_MASK; - dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:" - "status %d, extd-status %d\n", - opcode, compl_status, extd_status); + dev_err(&adapter->pdev->dev, + "opcode %d-%d failed:status %d-%d\n", + opcode, subsystem, compl_status, extd_status); } } done: -- GitLab From 0b3f0e7ae0765c81c7d659811595ea5058ae05a7 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 13 Jun 2012 19:51:45 +0000 Subject: [PATCH 1802/6849] be2net: Increase statistics structure size for skyhawk. Increasing the hardware statistics structure to accomodate statistics for skyhawk. Signed-off-by: Vasundhara Volam Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 9625bf420c16..b3f3fc3d1323 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1566,7 +1566,7 @@ struct be_hw_stats_v1 { u32 rsvd0[BE_TXP_SW_SZ]; struct be_erx_stats_v1 erx; struct be_pmem_stats pmem; - u32 rsvd1[3]; + u32 rsvd1[18]; }; struct be_cmd_req_get_stats_v1 { -- GitLab From 86a2f415e6cdc5dbb2163b31abf4d36f26f7e3da Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 14 Jun 2012 01:18:42 +0000 Subject: [PATCH 1803/6849] usbnet: sanitise overlong driver information strings As seen on smsc75xx, driver_info->description being longer than 32 characters messes up 'ethtool -i' output. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9f58330f1312..d4f7256a607d 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -876,9 +876,9 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { struct usbnet *dev = netdev_priv(net); - strncpy (info->driver, dev->driver_name, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - strncpy (info->fw_version, dev->driver_info->description, + strlcpy (info->driver, dev->driver_name, sizeof info->driver); + strlcpy (info->version, DRIVER_VERSION, sizeof info->version); + strlcpy (info->fw_version, dev->driver_info->description, sizeof info->fw_version); usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); } -- GitLab From df2bcc4af2616b18efeaa3d044fe15ce891c5d21 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 14 Jun 2012 22:39:27 +0000 Subject: [PATCH 1804/6849] bonding: show all the link status of slaves There are four link statuses of a bonding slave, the procfs code shows a wrong status when using downdelay/updelay: (slave->link == BOND_LINK_UP) ? "up" : "down" It doesn't respect the rest two statuses. This patch fixes it. Cc: Jay Vosburgh Cc: Andy Gospodarek Cc: "David S. Miller" Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- drivers/net/bonding/bond_procfs.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index ad284baafe87..3cea38d37344 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -150,14 +150,25 @@ static void bond_info_show_master(struct seq_file *seq) } } +static const char *bond_slave_link_status(s8 link) +{ + static const char * const status[] = { + [BOND_LINK_UP] = "up", + [BOND_LINK_FAIL] = "going down", + [BOND_LINK_DOWN] = "down", + [BOND_LINK_BACK] = "going back", + }; + + return status[link]; +} + static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave) { struct bonding *bond = seq->private; seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); - seq_printf(seq, "MII Status: %s\n", - (slave->link == BOND_LINK_UP) ? "up" : "down"); + seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link)); if (slave->speed == SPEED_UNKNOWN) seq_printf(seq, "Speed: %s\n", "Unknown"); else -- GitLab From a7e2eaadd0edf6d71637c0d99aca404b0da8c1be Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Jun 2012 23:58:16 +0000 Subject: [PATCH 1805/6849] net: lpc_eth: free skbs in start_xmit Transmitted skbs can be freed immediately in lpc_eth_hard_start_xmit() instead of at TX completion, since driver copies the frames in DMA area. Signed-off-by: Eric Dumazet Tested-by: Roland Stigge Signed-off-by: David S. Miller --- drivers/net/ethernet/nxp/lpc_eth.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 083d6715335c..028dde4d4979 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -440,7 +440,7 @@ struct netdata_local { spinlock_t lock; void __iomem *net_base; u32 msg_enable; - struct sk_buff *skb[ENET_TX_DESC]; + unsigned int skblen[ENET_TX_DESC]; unsigned int last_tx_idx; unsigned int num_used_tx_buffs; struct mii_bus *mii_bus; @@ -903,12 +903,11 @@ err_out: static void __lpc_handle_xmit(struct net_device *ndev) { struct netdata_local *pldat = netdev_priv(ndev); - struct sk_buff *skb; u32 txcidx, *ptxstat, txstat; txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); while (pldat->last_tx_idx != txcidx) { - skb = pldat->skb[pldat->last_tx_idx]; + unsigned int skblen = pldat->skblen[pldat->last_tx_idx]; /* A buffer is available, get buffer status */ ptxstat = &pldat->tx_stat_v[pldat->last_tx_idx]; @@ -945,9 +944,8 @@ static void __lpc_handle_xmit(struct net_device *ndev) } else { /* Update stats */ ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += skblen; } - dev_kfree_skb_irq(skb); txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); } @@ -1132,7 +1130,7 @@ static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len); /* Save the buffer and increment the buffer counter */ - pldat->skb[txidx] = skb; + pldat->skblen[txidx] = len; pldat->num_used_tx_buffs++; /* Start transmit */ @@ -1147,6 +1145,7 @@ static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) spin_unlock_irq(&pldat->lock); + dev_kfree_skb(skb); return NETDEV_TX_OK; } -- GitLab From 31fdc5553b42abd7e29bb7b89f6ba07514eb4763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Wed, 13 Jun 2012 22:29:03 +0000 Subject: [PATCH 1806/6849] net: remove my future former mail address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Cc: Sakari Ailus Signed-off-by: David S. Miller --- include/net/phonet/gprs.h | 2 +- net/caif/caif_dev.c | 3 +-- net/phonet/af_phonet.c | 4 ++-- net/phonet/datagram.c | 4 ++-- net/phonet/pep-gprs.c | 2 +- net/phonet/pep.c | 2 +- net/phonet/pn_dev.c | 4 ++-- net/phonet/pn_netlink.c | 4 ++-- net/phonet/socket.c | 4 ++-- net/phonet/sysctl.c | 2 +- 10 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/net/phonet/gprs.h b/include/net/phonet/gprs.h index 928daf595beb..bcd525e39a0b 100644 --- a/include/net/phonet/gprs.h +++ b/include/net/phonet/gprs.h @@ -5,7 +5,7 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Author: Rémi Denis-Courmont + * Author: Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index aa6f716524fd..554b31289607 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -4,8 +4,7 @@ * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 * - * Borrowed heavily from file: pn_dev.c. Thanks to - * Remi Denis-Courmont + * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont * and Sakari Ailus */ diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 779ce4ff92ec..5a940dbd74a3 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -5,8 +5,8 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Contact: Remi Denis-Courmont - * Original author: Sakari Ailus + * Authors: Sakari Ailus + * Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index bf35b4e1a14c..12c30f3e643e 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c @@ -5,8 +5,8 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Contact: Remi Denis-Courmont - * Original author: Sakari Ailus + * Authors: Sakari Ailus + * Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c index d01208968c83..a2fba7edfd1f 100644 --- a/net/phonet/pep-gprs.c +++ b/net/phonet/pep-gprs.c @@ -5,7 +5,7 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Author: Rémi Denis-Courmont + * Author: Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 9dd4f926f7d1..576f22c9c76e 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -5,7 +5,7 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Author: Rémi Denis-Courmont + * Author: Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 36f75a9e2c3d..5bf6341e2dd4 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -5,8 +5,8 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Contact: Remi Denis-Courmont - * Original author: Sakari Ailus + * Authors: Sakari Ailus + * Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index cfdf135fcd69..7dd762a464e5 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c @@ -5,8 +5,8 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Contact: Remi Denis-Courmont - * Original author: Sakari Ailus + * Authors: Sakari Ailus + * Remi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 89cfa9ce4939..0acc943f713a 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -5,8 +5,8 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Contact: Remi Denis-Courmont - * Original author: Sakari Ailus + * Authors: Sakari Ailus + * Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c index 696348fd31a1..d6bbbbd0af18 100644 --- a/net/phonet/sysctl.c +++ b/net/phonet/sysctl.c @@ -5,7 +5,7 @@ * * Copyright (C) 2008 Nokia Corporation. * - * Contact: Remi Denis-Courmont + * Author: Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License -- GitLab From 6fac262526ee91ee66210b8919a4297dcf7d544e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Jun 2012 19:47:34 -0700 Subject: [PATCH 1807/6849] ipv4: Cap ADVMSS metric in the FIB rather than the routing cache. It makes no sense to execute this limit test every time we create a routing cache entry. We can't simply error out on these things since we've silently accepted and truncated them forever. Signed-off-by: David S. Miller --- net/ipv4/fib_semantics.c | 7 ++++++- net/ipv4/route.c | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index e5b7182fa099..415f8230fc88 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -779,9 +779,14 @@ struct fib_info *fib_create_info(struct fib_config *cfg) int type = nla_type(nla); if (type) { + u32 val; + if (type > RTAX_MAX) goto err_inval; - fi->fib_metrics[type - 1] = nla_get_u32(nla); + val = nla_get_u32(nla); + if (type == RTAX_ADVMSS && val > 65535 - 40) + val = 65535 - 40; + fi->fib_metrics[type - 1] = val; } } } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 41df5297a412..a91f6d33804c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1951,8 +1951,6 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *fl4, if (dst_mtu(dst) > IP_MAX_MTU) dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU); - if (dst_metric_raw(dst, RTAX_ADVMSS) > 65535 - 40) - dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); #ifdef CONFIG_IP_ROUTE_CLASSID #ifdef CONFIG_IP_MULTIPLE_TABLES -- GitLab From 7fb75db139965c1955bf6bbde62a357f9843286d Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 17 Jun 2012 13:44:27 +0200 Subject: [PATCH 1808/6849] ALSA: snd-usb: fix sync pipe check Fix a bogus sanity check for sync pipe in pcm.c. This flaw was introduced during the streaming logic refactorization. While at it, improve the error messages that are generated in such cases. Signed-off-by: Daniel Mack Reported-and-tested-by: Signed-off-by: Takashi Iwai --- sound/usb/pcm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index cdf8b7601973..fc7ce7c1b4fa 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -354,17 +354,21 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && get_endpoint(alts, 1)->bSynchAddress != 0 && !implicit_fb)) { - snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", - dev->devnum, fmt->iface, fmt->altsetting); + snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", + dev->devnum, fmt->iface, fmt->altsetting, + get_endpoint(alts, 1)->bmAttributes, + get_endpoint(alts, 1)->bLength, + get_endpoint(alts, 1)->bSynchAddress); return -EINVAL; } ep = get_endpoint(alts, 1)->bEndpointAddress; - if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && + if (!implicit_fb && + get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || - (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)) || - ( is_playback && !implicit_fb))) { - snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", - dev->devnum, fmt->iface, fmt->altsetting); + (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { + snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", + dev->devnum, fmt->iface, fmt->altsetting, + is_playback, ep, get_endpoint(alts, 0)->bSynchAddress); return -EINVAL; } -- GitLab From 2e113c648dc29c3d8418fe277917b04397375939 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 18 Jun 2012 00:47:25 -0600 Subject: [PATCH 1809/6849] ARM: OMAP2+: control: Add AM33XX control reg & sec clkctrl offset Define AM33XX control register, in order to allow access to control register address space, also add CONTROL_SEC_CLK_CTRL register offset; both are required in clock tree data, for wdt0 and timer0 clock source select configuration. CONTROL.SEC_CLK_CTRL register is provided to select/configure clock input for WDT0 and TIMER0. Signed-off-by: Vaibhav Hiremath Cc: Paul Walmsley Cc: Tony Lindgren [paul@pwsan.com: added include of plat/am33xx.h to fix build break; added AM33XX_CONTROL_STATUS bitfields that will be needed for the clock tree; fixed some control.h whitespace problems while here] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/control.h | 39 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a406fd045ce1..c43f03cbefc5 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -21,6 +21,8 @@ #include #include +#include + #ifndef __ASSEMBLY__ #define OMAP242X_CTRL_REGADDR(reg) \ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) @@ -28,6 +30,8 @@ OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) #define OMAP343X_CTRL_REGADDR(reg) \ OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) +#define AM33XX_CTRL_REGADDR(reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_BASE + (reg)) #else #define OMAP242X_CTRL_REGADDR(reg) \ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) @@ -35,6 +39,8 @@ OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) #define OMAP343X_CTRL_REGADDR(reg) \ OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) +#define AM33XX_CTRL_REGADDR(reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_BASE + (reg)) #endif /* __ASSEMBLY__ */ /* @@ -312,15 +318,15 @@ OMAP343X_SCRATCHPAD + reg) /* AM35XX_CONTROL_IPSS_CLK_CTRL bits */ -#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0 -#define AM35XX_CPGMAC_VBUSP_CLK_SHIFT 1 -#define AM35XX_VPFE_VBUSP_CLK_SHIFT 2 -#define AM35XX_HECC_VBUSP_CLK_SHIFT 3 -#define AM35XX_USBOTG_FCLK_SHIFT 8 -#define AM35XX_CPGMAC_FCLK_SHIFT 9 -#define AM35XX_VPFE_FCLK_SHIFT 10 - -/*AM35XX CONTROL_LVL_INTR_CLEAR bits*/ +#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0 +#define AM35XX_CPGMAC_VBUSP_CLK_SHIFT 1 +#define AM35XX_VPFE_VBUSP_CLK_SHIFT 2 +#define AM35XX_HECC_VBUSP_CLK_SHIFT 3 +#define AM35XX_USBOTG_FCLK_SHIFT 8 +#define AM35XX_CPGMAC_FCLK_SHIFT 9 +#define AM35XX_VPFE_FCLK_SHIFT 10 + +/* AM35XX CONTROL_LVL_INTR_CLEAR bits */ #define AM35XX_CPGMAC_C0_MISC_PULSE_CLR BIT(0) #define AM35XX_CPGMAC_C0_RX_PULSE_CLR BIT(1) #define AM35XX_CPGMAC_C0_RX_THRESH_CLR BIT(2) @@ -330,21 +336,22 @@ #define AM35XX_VPFE_CCDC_VD1_INT_CLR BIT(6) #define AM35XX_VPFE_CCDC_VD2_INT_CLR BIT(7) -/*AM35XX CONTROL_IP_SW_RESET bits*/ +/* AM35XX CONTROL_IP_SW_RESET bits */ #define AM35XX_USBOTGSS_SW_RST BIT(0) #define AM35XX_CPGMACSS_SW_RST BIT(1) #define AM35XX_VPFE_VBUSP_SW_RST BIT(2) #define AM35XX_HECC_SW_RST BIT(3) #define AM35XX_VPFE_PCLK_SW_RST BIT(4) -/* - * CONTROL AM33XX STATUS register - */ +/* AM33XX CONTROL_STATUS register */ #define AM33XX_CONTROL_STATUS 0x040 +#define AM33XX_CONTROL_SEC_CLK_CTRL 0x1bc -/* - * CONTROL OMAP STATUS register to identify OMAP3 features - */ +/* AM33XX CONTROL_STATUS bitfields (partial) */ +#define AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT 22 +#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK (0x3 << 22) + +/* CONTROL OMAP STATUS register to identify OMAP3 features */ #define OMAP3_CONTROL_OMAP_STATUS 0x044c #define OMAP3_SGX_SHIFT 13 -- GitLab From ce3fc89a4e120c1fb012efd71f403116b6bcc1ee Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 18 Jun 2012 00:47:26 -0600 Subject: [PATCH 1810/6849] ARM: OMAP AM33xx: voltagedomain: Add voltage domain data Currently dummy voltage domain data is being created in order to succeed boot process, nothing has been done w.r.t actual hardware (voltage control). Also, hook up the AM33XX voltage domain to OMAP framework. Signed-off-by: Vaibhav Hiremath Signed-off-by: Afzal Mohammed Cc: Benoit Cousson Cc: Tony Lindgren Cc: Kevin Hilman Cc: Paul Walmsley Cc: Rajendra Nayak Acked-by: Kevin Hilman [paul@pwsan.com: updated for 3.5] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/io.c | 1 + arch/arm/mach-omap2/voltage.h | 1 + arch/arm/mach-omap2/voltagedomains33xx_data.c | 43 +++++++++++++++++++ 5 files changed, 47 insertions(+) create mode 100644 arch/arm/mach-omap2/voltagedomains33xx_data.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fa742f3c2629..6a3aef66f03e 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -99,6 +99,7 @@ obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o # OMAP powerdomain framework powerdomain-common += powerdomain.o powerdomain-common.o diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 56f687bebd0a..5d99c1b2cb48 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -129,6 +129,7 @@ void omap3430_init_early(void); void omap35xx_init_early(void); void omap3630_init_early(void); void omap3_init_early(void); /* Do not use this one */ +void am33xx_init_early(void); void am35xx_init_early(void); void ti81xx_init_early(void); void am33xx_init_early(void); diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 5d6b2346bf75..d15ecb3782b7 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -484,6 +484,7 @@ void __init am33xx_init_early(void) omap3xxx_check_revision(); ti81xx_check_features(); omap_common_init_early(); + am33xx_voltagedomains_init(); } #endif diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index 16a1b092cf36..a7c43c1042be 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h @@ -156,6 +156,7 @@ int omap_voltage_late_init(void); extern void omap2xxx_voltagedomains_init(void); extern void omap3xxx_voltagedomains_init(void); +extern void am33xx_voltagedomains_init(void); extern void omap44xx_voltagedomains_init(void); struct voltagedomain *voltdm_lookup(const char *name); diff --git a/arch/arm/mach-omap2/voltagedomains33xx_data.c b/arch/arm/mach-omap2/voltagedomains33xx_data.c new file mode 100644 index 000000000000..965458dc0cb9 --- /dev/null +++ b/arch/arm/mach-omap2/voltagedomains33xx_data.c @@ -0,0 +1,43 @@ +/* + * AM33XX voltage domain data + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "voltage.h" + +static struct voltagedomain am33xx_voltdm_mpu = { + .name = "mpu", +}; + +static struct voltagedomain am33xx_voltdm_core = { + .name = "core", +}; + +static struct voltagedomain am33xx_voltdm_rtc = { + .name = "rtc", +}; + +static struct voltagedomain *voltagedomains_am33xx[] __initdata = { + &am33xx_voltdm_mpu, + &am33xx_voltdm_core, + &am33xx_voltdm_rtc, + NULL, +}; + +void __init am33xx_voltagedomains_init(void) +{ + voltdm_init(voltagedomains_am33xx); +} -- GitLab From afe25967ecf66b38d94d374f0fcb5f4add458a4c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 16 Jun 2012 16:58:04 +0200 Subject: [PATCH 1811/6849] ALSA: snd-usb: make snd_usb_substream_capture_trigger static Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai --- sound/usb/pcm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index fc7ce7c1b4fa..54607f8c4f66 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1151,7 +1151,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea return -EINVAL; } -int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd) +static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, + int cmd) { int err; struct snd_usb_substream *subs = substream->runtime->private_data; -- GitLab From b4a91cf05c33d4ab5b2b3738a257a3fe49b462bd Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Fri, 15 Jun 2012 19:36:23 -0700 Subject: [PATCH 1812/6849] ALSA: hda - Handle open while transitioning to D3. This addresses an issue encountered when a pcm is opened while transitioning to low power state (codec->power_on == 1 && codec->power_transition == -1). Add snd_pcm_power_up_d3wait to hda_codec. This function is used to power up from azx_open as opposed to snd_hda_power_up used from codec_exec_verb. When powering up from azx_open, wait for pending power downs to complete, avoiding the power up continuing in parallel with the power down on the work queue. The specific issue seen was with the CS4210 codec, it powers off the ADC and DAC nid in its suspend handler. If it is re-opened before the ~100ms power down process completes, the ADC and DAC nid are initialized while powered down and audio is lost until another suspend/resume cycle. Signed-off-by: Dylan Reid Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 46 +++++++++++++++++++++++++++++++-------- sound/pci/hda/hda_codec.h | 2 ++ sound/pci/hda/hda_intel.c | 2 +- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 41ca803a1fff..7504e62188d6 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4393,20 +4393,19 @@ void snd_hda_update_power_acct(struct hda_codec *codec) codec->power_jiffies += delta; } -/** - * snd_hda_power_up - Power-up the codec - * @codec: HD-audio codec - * - * Increment the power-up counter and power up the hardware really when - * not turned on yet. - */ -void snd_hda_power_up(struct hda_codec *codec) +/* Transition to powered up, if wait_power_down then wait for a pending + * transition to D3 to complete. A pending D3 transition is indicated + * with power_transition == -1. */ +static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) { struct hda_bus *bus = codec->bus; spin_lock(&codec->power_lock); codec->power_count++; - if (codec->power_on || codec->power_transition > 0) { + /* Return if power_on or transitioning to power_on, unless currently + * powering down. */ + if ((codec->power_on || codec->power_transition > 0) && + !(wait_power_down && codec->power_transition < 0)) { spin_unlock(&codec->power_lock); return; } @@ -4430,8 +4429,37 @@ void snd_hda_power_up(struct hda_codec *codec) codec->power_transition = 0; spin_unlock(&codec->power_lock); } + +/** + * snd_hda_power_up - Power-up the codec + * @codec: HD-audio codec + * + * Increment the power-up counter and power up the hardware really when + * not turned on yet. + */ +void snd_hda_power_up(struct hda_codec *codec) +{ + __snd_hda_power_up(codec, false); +} EXPORT_SYMBOL_HDA(snd_hda_power_up); +/** + * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending + * D3 transition to complete. This differs from snd_hda_power_up() when + * power_transition == -1. snd_hda_power_up sees this case as a nop, + * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers + * back up. + * @codec: HD-audio codec + * + * Cancel any power down operation hapenning on the work queue, then power up. + */ +void snd_hda_power_up_d3wait(struct hda_codec *codec) +{ + /* This will cancel and wait for pending power_work to complete. */ + __snd_hda_power_up(codec, true); +} +EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait); + #define power_save(codec) \ ((codec)->bus->power_save ? *(codec)->bus->power_save : 0) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 4fc3960c8591..2fdaadbb4326 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -1056,10 +1056,12 @@ const char *snd_hda_get_jack_location(u32 cfg); */ #ifdef CONFIG_SND_HDA_POWER_SAVE void snd_hda_power_up(struct hda_codec *codec); +void snd_hda_power_up_d3wait(struct hda_codec *codec); void snd_hda_power_down(struct hda_codec *codec); void snd_hda_update_power_acct(struct hda_codec *codec); #else static inline void snd_hda_power_up(struct hda_codec *codec) {} +static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {} static inline void snd_hda_power_down(struct hda_codec *codec) {} #endif diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 02763827dde0..7757536b9d5f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1766,7 +1766,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) buff_step); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, buff_step); - snd_hda_power_up(apcm->codec); + snd_hda_power_up_d3wait(apcm->codec); err = hinfo->ops.open(hinfo, apcm->codec, substream); if (err < 0) { azx_release_device(azx_dev); -- GitLab From 0b1d8e09089b69ac2e8be203fb28cd07cfe035b2 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 16 Jun 2012 16:58:36 +0200 Subject: [PATCH 1813/6849] ALSA: 6fire: use NULL instead of 0 for pointer assignment Signed-off-by: Daniel Mack Cc: Torsten Schenk Signed-off-by: Takashi Iwai --- sound/usb/6fire/firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 6f9715ab32fe..56ad923bf6b5 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -209,7 +209,7 @@ static int usb6fire_fw_ezusb_upload( int ret; u8 data; struct usb_device *device = interface_to_usbdev(intf); - const struct firmware *fw = 0; + const struct firmware *fw = NULL; struct ihex_record *rec = kmalloc(sizeof(struct ihex_record), GFP_KERNEL); -- GitLab From 4be77a530be1ea62574f31c20dd9848e7e2ab0f6 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 15 Jun 2012 16:35:28 +0100 Subject: [PATCH 1814/6849] ALSA: pcm: Add snd_pcm_rate_bit_to_rate() This is essentially the reverse of snd_pcm_rate_to_rate_bit(). This is generally useful as the Compress API uses the rate bit directly and it helps to be able to map back to the actual sample rate. Signed-off-by: Dimitris Papastamos Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 1 + sound/core/pcm_misc.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 0d1112815be3..68372bc1e11b 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -893,6 +893,7 @@ extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates; int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime); unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); +unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, struct snd_dma_buffer *bufp) diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 9c9eff9afbac..d4fc1bfbe457 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -488,3 +488,21 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) return SNDRV_PCM_RATE_KNOT; } EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); + +/** + * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate + * @rate_bit: the rate bit to convert + * + * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag + * or 0 for an unknown rate bit + */ +unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) +{ + unsigned int i; + + for (i = 0; i < snd_pcm_known_rates.count; i++) + if ((1u << i) == rate_bit) + return snd_pcm_known_rates.list[i]; + return 0; +} +EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); -- GitLab From 10a3061accd897c9e4e3821cbd501660ac482497 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Fri, 15 Jun 2012 20:55:54 +0200 Subject: [PATCH 1815/6849] ALSA: snd-opti9xx: fixes for MED3931 card (opti931) MED3931 card did not work (failed with "OPTI chip not found") because snd-opti9xx gets mc_indir_index from pnp by adding 2 to the pnp-reported port. It probably works for some cards but not for this one. Datasheet says that the port is always at 0xe?e so just force the lowest nibble to be 0xe. Also this card powers up with (ugly) 3D sound enabled. As there's no mixer control for this, just disable it. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai --- sound/isa/opti9xx/opti92x-ad1848.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index d7ccf28bd66a..ecc68dfe7b54 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -135,7 +135,6 @@ struct snd_opti9xx { unsigned long mc_base_size; #ifdef OPTi93X unsigned long mc_indir_index; - unsigned long mc_indir_size; struct resource *res_mc_indir; struct snd_wss *codec; #endif /* OPTi93X */ @@ -245,10 +244,8 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, case OPTi9XX_HW_82C931: case OPTi9XX_HW_82C933: chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; - if (!chip->mc_indir_index) { + if (!chip->mc_indir_index) chip->mc_indir_index = 0xe0e; - chip->mc_indir_size = 2; - } chip->password = 0xe4; chip->pwd_reg = 0; break; @@ -403,7 +400,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, #else /* OPTi93X */ case OPTi9XX_HW_82C931: - case OPTi9XX_HW_82C933: + /* disable 3D sound (set GPIO1 as output, low) */ + snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c); + case OPTi9XX_HW_82C933: /* FALL THROUGH */ /* * The BTC 1817DW has QS1000 wavetable which is connected * to the serial digital input of the OPTI931. @@ -696,8 +695,7 @@ static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip) if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) return 0; #else /* OPTi93X */ - chip->res_mc_indir = request_region(chip->mc_indir_index, - chip->mc_indir_size, + chip->res_mc_indir = request_region(chip->mc_indir_index, 2, "OPTi93x MC"); if (chip->res_mc_indir == NULL) return -EBUSY; @@ -770,8 +768,9 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, #ifdef OPTi93X port = pnp_port_start(pdev, 0) - 4; fm_port = pnp_port_start(pdev, 1) + 8; - chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; - chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; + /* adjust mc_indir_index - some cards report it at 0xe?d, + other at 0xe?c but it really is always at 0xe?e */ + chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe; #else devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); if (devmc == NULL) -- GitLab From 303e56f2d2868f1bcdd3b72c3296d02a7af28962 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 13 Jun 2012 19:37:06 +0300 Subject: [PATCH 1816/6849] iwlwifi: check that we have enough bits to track the TX queues Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index e620af3d592d..bba3edfb3488 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -1352,6 +1352,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; trans_cfg.command_names = iwl_dvm_cmd_strings; + WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE < + priv->cfg->base_params->num_of_queues); + ucode_flags = fw->ucode_capa.flags; #ifndef CONFIG_IWLWIFI_P2P -- GitLab From e9d364de1aed8f7e81b3e67fdf3015533bfc76b1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 13 Jun 2012 14:16:40 +0300 Subject: [PATCH 1817/6849] iwlwifi: print the scratch of all the buffers stuck in a queue Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index cc935168ae52..c6f53af639c6 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -296,6 +296,7 @@ static void iwlagn_free_dma_ptr(struct iwl_trans *trans, static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) { struct iwl_tx_queue *txq = (void *)data; + struct iwl_queue *q = &txq->q; struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); u32 scd_sram_addr = trans_pcie->scd_base_addr + @@ -346,6 +347,14 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); } + for (i = q->read_ptr; i != q->write_ptr; + i = iwl_queue_inc_wrap(i, q->n_bd)) { + struct iwl_tx_cmd *tx_cmd = + (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; + IWL_ERR(trans, "scratch %d = 0x%08x\n", i, + get_unaligned_le32(&tx_cmd->scratch)); + } + iwl_op_mode_nic_error(trans->op_mode); } -- GitLab From 901787c1674ee5d35c7c3713efbc009c72f43971 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 17 Jun 2012 16:00:22 +0300 Subject: [PATCH 1818/6849] iwlwifi: comment context requirements of the op_mode A few op_mode of the op_mode API functions have requirements on the running context of the caller. Document that. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index cd9ef114d3a3..64886f95664f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -111,22 +111,25 @@ struct iwl_cfg; * May sleep * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the * HCMD the this Rx responds to. - * Must be atomic. + * Must be atomic and called with BH disabled. * @queue_full: notifies that a HW queue is full. - * Must be atomic + * Must be atomic and called with BH disabled. * @queue_not_full: notifies that a HW queue is not full any more. - * Must be atomic + * Must be atomic and called with BH disabled. * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that * the radio is killed. Must be atomic. * @free_skb: allows the transport layer to free skbs that haven't been * reclaimed by the op_mode. This can happen when the driver is freed and * there are Tx packets pending in the transport layer. * Must be atomic - * @nic_error: error notification. Must be atomic - * @cmd_queue_full: Called when the command queue gets full. Must be atomic. + * @nic_error: error notification. Must be atomic and must be called with BH + * disabled. + * @cmd_queue_full: Called when the command queue gets full. Must be atomic and + * called with BH disabled. * @nic_config: configure NIC, called before firmware is started. * May sleep - * @wimax_active: invoked when WiMax becomes active. Must be atomic. + * @wimax_active: invoked when WiMax becomes active. Must be atomic and called + * with BH disabled. */ struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans, @@ -165,7 +168,6 @@ struct iwl_op_mode { static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode) { might_sleep(); - op_mode->ops->stop(op_mode); } -- GitLab From 24172f39b02e5fcd35a4f721bde5bc9b61534736 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 17 Jun 2012 16:04:25 +0300 Subject: [PATCH 1819/6849] iwlwifi: disable BH before the call to iwl_op_mode_nic_error This is required by the op_mode API. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index c6f53af639c6..e20880acdd34 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -2026,7 +2026,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, if (!trans->op_mode) return -EAGAIN; + local_bh_disable(); iwl_op_mode_nic_error(trans->op_mode); + local_bh_enable(); return count; } -- GitLab From 3595c003f962bcf089f83e8ea44fd3169ad60ca3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 17 Jun 2012 16:12:42 +0300 Subject: [PATCH 1820/6849] iwlwifi: don't disable interrupt in iwl_abort_notification_waits This is not needed since notif_wait_lock is never accessed from IRQ. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index 5cfed29b1b18..c61f2070f15a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -121,13 +121,12 @@ EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) { - unsigned long flags; struct iwl_notification_wait *wait_entry; - spin_lock_irqsave(¬if_wait->notif_wait_lock, flags); + spin_lock(¬if_wait->notif_wait_lock); list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list) wait_entry->aborted = true; - spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags); + spin_unlock(¬if_wait->notif_wait_lock); wake_up_all(¬if_wait->notif_waitq); } -- GitLab From ae8baec22878be1f8d14b5bb00ac83f7954a9832 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 14 Jun 2012 12:27:56 +0300 Subject: [PATCH 1821/6849] iwlwifi: don't disable interrupt while starting tx This is really not needed, we already have a lock inside the accesses to the prph. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index e20880acdd34..42f369d15f48 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1046,15 +1046,12 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, /* * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask - * must be called under the irq lock and with MAC access */ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) { struct iwl_trans_pcie __maybe_unused *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - lockdep_assert_held(&trans_pcie->irq_lock); - iwl_write_prph(trans, SCD_TXFACT, mask); } @@ -1062,12 +1059,9 @@ static void iwl_tx_start(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 a; - unsigned long flags; int i, chan; u32 reg_val; - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - /* make sure all queue are not stopped/used */ memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); @@ -1118,8 +1112,6 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - /* Enable L1-Active */ iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); -- GitLab From c15acff337ca5c2f101fee99f36c89d47839d387 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Tue, 12 Jun 2012 12:53:21 +0800 Subject: [PATCH 1822/6849] x86: Fix kernel-doc warnings Signed-off-by: Wanpeng Li Cc: Peter Zijlstra Cc: Jason Wessel Cc: Jan Kiszka Cc: Gavin Shan Cc: Wanpeng Li Signed-off-by: Ingo Molnar --- arch/x86/kernel/kgdb.c | 8 ++++---- arch/x86/lib/csum-wrappers_64.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 8bfb6146f753..3f61904365cf 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -444,12 +444,12 @@ void kgdb_roundup_cpus(unsigned long flags) /** * kgdb_arch_handle_exception - Handle architecture specific GDB packets. - * @vector: The error vector of the exception that happened. + * @e_vector: The error vector of the exception that happened. * @signo: The signal number of the exception that happened. * @err_code: The error code of the exception that happened. - * @remcom_in_buffer: The buffer of the packet we have read. - * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. - * @regs: The &struct pt_regs of the current process. + * @remcomInBuffer: The buffer of the packet we have read. + * @remcomOutBuffer: The buffer of %BUFMAX bytes to write a packet into. + * @linux_regs: The &struct pt_regs of the current process. * * This function MUST handle the 'c' and 's' command packets, * as well packets to set / remove a hardware breakpoint, if used. diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index 459b58a8a15c..25b7ae8d058a 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c @@ -115,7 +115,7 @@ EXPORT_SYMBOL(csum_partial_copy_to_user); * @src: source address * @dst: destination address * @len: number of bytes to be copied. - * @isum: initial sum that is added into the result (32bit unfolded) + * @sum: initial sum that is added into the result (32bit unfolded) * * Returns an 32bit unfolded checksum of the buffer. */ -- GitLab From abf71f3066740f3b59c3f731b4b68ed335f7b24d Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Fri, 15 Jun 2012 18:10:55 +0300 Subject: [PATCH 1823/6849] x86/vsmp: Fix vector_allocation_domain's return value Commit 8637e38a ("x86/apic: Avoid useless scanning thru a cpumask in assign_irq_vector()") modified vector_allocation_domain() to return a boolean indicating if cpumask is dynamic or static. Adjust vSMP's callback implementation accordingly. Signed-off-by: Ido Yariv Acked-by: Shai Fultheim Cc: Alexander Gordeev Link: http://lkml.kernel.org/r/1339773055-27397-1-git-send-email-ido@wizery.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/vsmp_64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 3f0285ac00fa..fa5adb7c228c 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -208,9 +208,10 @@ static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) * In vSMP, all cpus should be capable of handling interrupts, regardless of * the APIC used. */ -static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask) +static bool fill_vector_allocation_domain(int cpu, struct cpumask *retmask) { cpumask_setall(retmask); + return false; } static void vsmp_apic_post_init(void) -- GitLab From 76958a61e42fb6277a8431eb17e4bdb24176f1b7 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 15 Jun 2012 19:06:44 +0200 Subject: [PATCH 1824/6849] perf/x86/amd: Fix RDPMC index calculation for AMD family 15h The RDPMC index calculation is wrong for AMD family 15h (X86_FEATURE_ PERFCTR_CORE set). This leads to a #GP when accessing the counter: Pid: 2237, comm: syslog-ng Not tainted 3.5.0-rc1-perf-x86_64-standard-g130ff90 #135 AMD Pike/Pike RIP: 0010:[] [] x86_perf_event_update+0x27/0x66 While the msr address offset is (index << 1) we must use index to select the correct rdpmc. Signed-off-by: Robert Richter Acked-by: Peter Zijlstra Cc: Vince Weaver Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 766c76d5ec4c..d1f38c9509d0 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -823,7 +823,7 @@ static inline void x86_assign_hw_event(struct perf_event *event, } else { hwc->config_base = x86_pmu_config_addr(hwc->idx); hwc->event_base = x86_pmu_event_addr(hwc->idx); - hwc->event_base_rdpmc = x86_pmu_addr_offset(hwc->idx); + hwc->event_base_rdpmc = hwc->idx; } } -- GitLab From 9c5da09d266ca9b32eb16cf940f8161d949c2fe5 Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Thu, 14 Jun 2012 15:31:09 -0700 Subject: [PATCH 1825/6849] perf: Use css_tryget() to avoid propping up css refcount An rmdir pushes css's ref count to zero. However, if the associated directory is open at the time, the dentry ref count is non-zero. If the fd for this directory is then passed into perf_event_open, it does a css_get(). This bounces the ref count back up from zero. This is a problem by itself. But what makes it turn into a crash is the fact that we end up doing an extra dput, since we perform a dput when css_put sees the ref count go down to zero. css_tryget() does not fall into that trap. So, we use that instead. Reproduction test-case for the bug: #include #include #include #include #include #include #include #include #include #define PERF_FLAG_PID_CGROUP (1U << 2) int perf_event_open(struct perf_event_attr *hw_event_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) { return syscall(__NR_perf_event_open,hw_event_uptr, pid, cpu, group_fd, flags); } /* * Directly poke at the perf_event bug, since it's proving hard to repro * depending on where in the kernel tree. what moved? */ int main(int argc, char **argv) { int fd; struct perf_event_attr attr; memset(&attr, 0, sizeof(attr)); attr.exclude_kernel = 1; attr.size = sizeof(attr); mkdir("/dev/cgroup/perf_event/blah", 0777); fd = open("/dev/cgroup/perf_event/blah", O_RDONLY); perror("open"); rmdir("/dev/cgroup/perf_event/blah"); sleep(2); perf_event_open(&attr, fd, 0, -1, PERF_FLAG_PID_CGROUP); perror("perf_event_open"); close(fd); return 0; } Signed-off-by: Salman Qazi Signed-off-by: Peter Zijlstra Acked-by: Tejun Heo Link: http://lkml.kernel.org/r/20120614223108.1025.2503.stgit@dungbeetle.mtv.corp.google.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index f85c0154b333..d7d71d6ec972 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -253,9 +253,9 @@ perf_cgroup_match(struct perf_event *event) return !event->cgrp || event->cgrp == cpuctx->cgrp; } -static inline void perf_get_cgroup(struct perf_event *event) +static inline bool perf_tryget_cgroup(struct perf_event *event) { - css_get(&event->cgrp->css); + return css_tryget(&event->cgrp->css); } static inline void perf_put_cgroup(struct perf_event *event) @@ -484,7 +484,11 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, event->cgrp = cgrp; /* must be done before we fput() the file */ - perf_get_cgroup(event); + if (!perf_tryget_cgroup(event)) { + event->cgrp = NULL; + ret = -ENOENT; + goto out; + } /* * all events in a group must monitor -- GitLab From 086ccd4379ad6c9c7c7713ef5f61b9d12e995147 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 18 Jun 2012 13:59:02 +0800 Subject: [PATCH 1826/6849] regulator: Fix setting constraints->ramp_delay in of_get_regulation_constraints Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/of_regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index e2a731079066..68dc3d43dd37 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -63,7 +63,7 @@ static void of_get_regulation_constraints(struct device_node *np, ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL); if (ramp_delay) - constraints->min_uV = be32_to_cpu(*ramp_delay); + constraints->ramp_delay = be32_to_cpu(*ramp_delay); } /** -- GitLab From 398715ab9414b3b7741c8239c254111f5016821c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 18 Jun 2012 10:11:28 +0800 Subject: [PATCH 1827/6849] regulator: core: Support table based mapping in regulator_set_voltage_time_sel For table based mapping, we can calculate voltage difference by below equation: abs(rdev->desc->volt_table[new_selector] - rdev->desc->volt_table[old_selector]) Thus we can make regulator_set_voltage_time_sel work for table based mapping. regulator_set_voltage_time_sel() only supports linear or table based mapping. In case it is misused, also warn if neither linear nor table based mapping is used with regulator_set_voltage_time_sel(). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b615ae6606db..73a3d874ca6e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2296,25 +2296,38 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time); * Provided with the starting and target voltage selectors, this function * returns time in microseconds required to rise or fall to this new voltage * - * Drivers providing uV_step in their regulator_desc and ramp_delay in - * regulation_constraints can use this as their set_voltage_time_sel() - * operation. + * Drivers providing uV_step or volt_table in their regulator_desc and + * ramp_delay in regulation_constraints can use this as their + * set_voltage_time_sel() operation. */ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { - if (rdev->desc->uV_step) { - if (rdev->constraints->ramp_delay) - return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), - rdev->constraints->ramp_delay * 1000); - if (rdev->desc->ramp_delay) - return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), - rdev->desc->ramp_delay * 1000); + unsigned int ramp_delay = 0; + + if (rdev->constraints->ramp_delay) + ramp_delay = rdev->constraints->ramp_delay; + else if (rdev->desc->ramp_delay) + ramp_delay = rdev->desc->ramp_delay; + + if (ramp_delay == 0) { rdev_warn(rdev, "ramp_delay not set\n"); + return 0; } + + if (rdev->desc->uV_step) { + return DIV_ROUND_UP(rdev->desc->uV_step * + abs(new_selector - old_selector), + ramp_delay * 1000); + } else if (rdev->desc->volt_table) { + return DIV_ROUND_UP(abs(rdev->desc->volt_table[new_selector] - + rdev->desc->volt_table[old_selector]), + ramp_delay * 1000); + } else { + rdev_warn(rdev, "Unsupported voltage mapping settings\n"); + } + return 0; } -- GitLab From ea38d13fd1666bc030cb1c0feec5b0da2f89f9b2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 18 Jun 2012 14:03:16 +0800 Subject: [PATCH 1828/6849] regulator: core: Change the unit of ramp_delay from mV/uS to uV/uS This change makes it possible to set ramp_delay with 0.xxx mV/uS without truncation issue. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/regulator.txt | 2 +- drivers/regulator/core.c | 4 ++-- include/linux/regulator/driver.h | 2 +- include/linux/regulator/machine.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index d0a7b1296a36..bec5d5747411 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -10,7 +10,7 @@ Optional properties: - regulator-always-on: boolean, regulator should never be disabled - regulator-boot-on: bootloader/firmware enabled regulator - -supply: phandle to the parent supply/regulator node -- regulator-ramp-delay: ramp delay for regulator(in mV/uS) +- regulator-ramp-delay: ramp delay for regulator(in uV/uS) Example: diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 73a3d874ca6e..ce0a3462e0de 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2319,11 +2319,11 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, if (rdev->desc->uV_step) { return DIV_ROUND_UP(rdev->desc->uV_step * abs(new_selector - old_selector), - ramp_delay * 1000); + ramp_delay); } else if (rdev->desc->volt_table) { return DIV_ROUND_UP(abs(rdev->desc->volt_table[new_selector] - rdev->desc->volt_table[old_selector]), - ramp_delay * 1000); + ramp_delay); } else { rdev_warn(rdev, "Unsupported voltage mapping settings\n"); } diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index ddc155d262da..84f999ed394b 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -173,7 +173,7 @@ enum regulator_type { * * @min_uV: Voltage given by the lowest selector (if linear mapping) * @uV_step: Voltage increase with each selector (if linear mapping) - * @ramp_delay: Time to settle down after voltage change (unit: mV/us) + * @ramp_delay: Time to settle down after voltage change (unit: uV/us) * @volt_table: Voltage mapping table (if table based mapping) * * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_ diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 5f37ad3cc172..40dd0a394cfa 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -92,7 +92,7 @@ struct regulator_state { * mode. * @initial_state: Suspend state to set by default. * @initial_mode: Mode to set at startup. - * @ramp_delay: Time to settle down after voltage change (unit: mV/us) + * @ramp_delay: Time to settle down after voltage change (unit: uV/us) */ struct regulation_constraints { -- GitLab From 74ea0e599215330e8964401508a5d7ec41ef15b0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 15 Jun 2012 19:04:33 +0100 Subject: [PATCH 1829/6849] regulator: tps65910: Don't use 0 as NULL Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 6bf864b4bdf6..e1b01ec82301 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1136,7 +1136,7 @@ static inline struct tps65910_board *tps65910_parse_dt_reg_data( struct of_regulator_match **tps65910_reg_matches) { *tps65910_reg_matches = NULL; - return 0; + return NULL; } #endif -- GitLab From 4b4969b14490a4f65b572b8f180164181104b5e1 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:30 +0800 Subject: [PATCH 1830/6849] perf: Export perf_assign_events() Export perf_assign_events() so the uncore code can use it to schedule events. Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-2-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 6 +++--- arch/x86/kernel/cpu/perf_event.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index d1f38c9509d0..6d32aefc9dbd 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -626,7 +626,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) c = sched->constraints[sched->state.event]; /* Prefer fixed purpose counters */ - if (x86_pmu.num_counters_fixed) { + if (c->idxmsk64 & (~0ULL << X86_PMC_IDX_FIXED)) { idx = X86_PMC_IDX_FIXED; for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { if (!__test_and_set_bit(idx, sched->state.used)) @@ -693,8 +693,8 @@ static bool perf_sched_next_event(struct perf_sched *sched) /* * Assign a counter for each event. */ -static int perf_assign_events(struct event_constraint **constraints, int n, - int wmin, int wmax, int *assign) +int perf_assign_events(struct event_constraint **constraints, int n, + int wmin, int wmax, int *assign) { struct perf_sched sched; diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 3df3de9452a9..83238f2a12b2 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -481,6 +481,8 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, void x86_pmu_enable_all(int added); +int perf_assign_events(struct event_constraint **constraints, int n, + int wmin, int wmax, int *assign); int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); void x86_pmu_stop(struct perf_event *event, int flags); -- GitLab From fbfc623f8231c8d8c78aab5841e9c6e5811ab638 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:31 +0800 Subject: [PATCH 1831/6849] perf: Avoid race between cpu hotplug and installing event perf_event_open() requires the cpu on which to install event is online, but the cpu can go offline after perf_event_open checks that. Add a get_online_cpus()/put_online_cpus() pair to avoid the race. Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-3-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index d7d71d6ec972..31d182e01549 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6252,6 +6252,8 @@ SYSCALL_DEFINE5(perf_event_open, } } + get_online_cpus(); + event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, NULL, NULL); if (IS_ERR(event)) { @@ -6391,6 +6393,8 @@ SYSCALL_DEFINE5(perf_event_open, perf_unpin_context(ctx); mutex_unlock(&ctx->mutex); + put_online_cpus(); + event->owner = current; mutex_lock(¤t->perf_event_mutex); @@ -6419,6 +6423,7 @@ err_context: err_alloc: free_event(event); err_task: + put_online_cpus(); if (task) put_task_struct(task); err_group_fd: -- GitLab From e2d37cd213dcc0aeb3db4b37b9bd1710fe36fbf7 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:32 +0800 Subject: [PATCH 1832/6849] perf: Allow the PMU driver to choose the CPU on which to install events Allow the pmu->event_init callback to change event->cpu, so the PMU driver can choose the CPU on which to install events. Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-4-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 31d182e01549..fa36a39e8bb7 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6306,7 +6306,7 @@ SYSCALL_DEFINE5(perf_event_open, /* * Get the target context (task or percpu): */ - ctx = find_get_context(pmu, task, cpu); + ctx = find_get_context(pmu, task, event->cpu); if (IS_ERR(ctx)) { err = PTR_ERR(ctx); goto err_alloc; @@ -6379,16 +6379,16 @@ SYSCALL_DEFINE5(perf_event_open, mutex_lock(&ctx->mutex); if (move_group) { - perf_install_in_context(ctx, group_leader, cpu); + perf_install_in_context(ctx, group_leader, event->cpu); get_ctx(ctx); list_for_each_entry(sibling, &group_leader->sibling_list, group_entry) { - perf_install_in_context(ctx, sibling, cpu); + perf_install_in_context(ctx, sibling, event->cpu); get_ctx(ctx); } } - perf_install_in_context(ctx, event, cpu); + perf_install_in_context(ctx, event, event->cpu); ++ctx->generation; perf_unpin_context(ctx); mutex_unlock(&ctx->mutex); -- GitLab From 0cda4c023132aa93f2dd94811061f812e88daf4c Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:33 +0800 Subject: [PATCH 1833/6849] perf: Introduce perf_pmu_migrate_context() Originally from Peter Zijlstra. The helper migrates perf events from one cpu to another cpu. Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-5-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 2 ++ kernel/events/core.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 1ce887abcc5c..76c5c8b724a7 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1107,6 +1107,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, struct task_struct *task, perf_overflow_handler_t callback, void *context); +extern void perf_pmu_migrate_context(struct pmu *pmu, + int src_cpu, int dst_cpu); extern u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running); diff --git a/kernel/events/core.c b/kernel/events/core.c index fa36a39e8bb7..f1cf0edeb39a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1645,6 +1645,8 @@ perf_install_in_context(struct perf_event_context *ctx, lockdep_assert_held(&ctx->mutex); event->ctx = ctx; + if (event->cpu != -1) + event->cpu = cpu; if (!task) { /* @@ -6379,6 +6381,7 @@ SYSCALL_DEFINE5(perf_event_open, mutex_lock(&ctx->mutex); if (move_group) { + synchronize_rcu(); perf_install_in_context(ctx, group_leader, event->cpu); get_ctx(ctx); list_for_each_entry(sibling, &group_leader->sibling_list, @@ -6484,6 +6487,39 @@ err: } EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); +void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) +{ + struct perf_event_context *src_ctx; + struct perf_event_context *dst_ctx; + struct perf_event *event, *tmp; + LIST_HEAD(events); + + src_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, src_cpu)->ctx; + dst_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, dst_cpu)->ctx; + + mutex_lock(&src_ctx->mutex); + list_for_each_entry_safe(event, tmp, &src_ctx->event_list, + event_entry) { + perf_remove_from_context(event); + put_ctx(src_ctx); + list_add(&event->event_entry, &events); + } + mutex_unlock(&src_ctx->mutex); + + synchronize_rcu(); + + mutex_lock(&dst_ctx->mutex); + list_for_each_entry_safe(event, tmp, &events, event_entry) { + list_del(&event->event_entry); + if (event->state >= PERF_EVENT_STATE_OFF) + event->state = PERF_EVENT_STATE_INACTIVE; + perf_install_in_context(dst_ctx, event, dst_cpu); + get_ctx(dst_ctx); + } + mutex_unlock(&dst_ctx->mutex); +} +EXPORT_SYMBOL_GPL(perf_pmu_migrate_context); + static void sync_child_event(struct perf_event *child_event, struct task_struct *child) { -- GitLab From 087bfbb032691262f2f7d52b910652450c5554b8 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:34 +0800 Subject: [PATCH 1834/6849] perf/x86: Add generic Intel uncore PMU support This patch adds the generic Intel uncore PMU support, including helper functions that add/delete uncore events, a hrtimer that periodically polls the counters to avoid overflow and code that places all events for a particular socket onto a single cpu. The code design is based on the structure of Sandy Bridge-EP's uncore subsystem, which consists of a variety of components, each component contains one or more "boxes". (Tooling support follows in the next patches.) Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1339741902-8449-6-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/Makefile | 4 +- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 878 ++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_uncore.h | 204 ++++ 3 files changed, 1085 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/cpu/perf_event_intel_uncore.c create mode 100644 arch/x86/kernel/cpu/perf_event_intel_uncore.h diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 6ab6aa2fdfdd..bac4c3804cc7 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -32,7 +32,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o ifdef CONFIG_PERF_EVENTS obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o endif obj-$(CONFIG_X86_MCE) += mcheck/ diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c new file mode 100644 index 000000000000..fe76a07dfdbc --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -0,0 +1,878 @@ +#include "perf_event_intel_uncore.h" + +static struct intel_uncore_type *empty_uncore[] = { NULL, }; +static struct intel_uncore_type **msr_uncores = empty_uncore; + +/* mask of cpus that collect uncore events */ +static cpumask_t uncore_cpu_mask; + +/* constraint for the fixed counter */ +static struct event_constraint constraint_fixed = + EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL); + +static void uncore_assign_hw_event(struct intel_uncore_box *box, + struct perf_event *event, int idx) +{ + struct hw_perf_event *hwc = &event->hw; + + hwc->idx = idx; + hwc->last_tag = ++box->tags[idx]; + + if (hwc->idx == UNCORE_PMC_IDX_FIXED) { + hwc->event_base = uncore_msr_fixed_ctr(box); + hwc->config_base = uncore_msr_fixed_ctl(box); + return; + } + + hwc->config_base = uncore_msr_event_ctl(box, hwc->idx); + hwc->event_base = uncore_msr_perf_ctr(box, hwc->idx); +} + +static void uncore_perf_event_update(struct intel_uncore_box *box, + struct perf_event *event) +{ + u64 prev_count, new_count, delta; + int shift; + + if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) + shift = 64 - uncore_fixed_ctr_bits(box); + else + shift = 64 - uncore_perf_ctr_bits(box); + + /* the hrtimer might modify the previous event value */ +again: + prev_count = local64_read(&event->hw.prev_count); + new_count = uncore_read_counter(box, event); + if (local64_xchg(&event->hw.prev_count, new_count) != prev_count) + goto again; + + delta = (new_count << shift) - (prev_count << shift); + delta >>= shift; + + local64_add(delta, &event->count); +} + +/* + * The overflow interrupt is unavailable for SandyBridge-EP, is broken + * for SandyBridge. So we use hrtimer to periodically poll the counter + * to avoid overflow. + */ +static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) +{ + struct intel_uncore_box *box; + unsigned long flags; + int bit; + + box = container_of(hrtimer, struct intel_uncore_box, hrtimer); + if (!box->n_active || box->cpu != smp_processor_id()) + return HRTIMER_NORESTART; + /* + * disable local interrupt to prevent uncore_pmu_event_start/stop + * to interrupt the update process + */ + local_irq_save(flags); + + for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX) + uncore_perf_event_update(box, box->events[bit]); + + local_irq_restore(flags); + + hrtimer_forward_now(hrtimer, ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL)); + return HRTIMER_RESTART; +} + +static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) +{ + __hrtimer_start_range_ns(&box->hrtimer, + ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL), 0, + HRTIMER_MODE_REL_PINNED, 0); +} + +static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box) +{ + hrtimer_cancel(&box->hrtimer); +} + +static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box) +{ + hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + box->hrtimer.function = uncore_pmu_hrtimer; +} + +struct intel_uncore_box *uncore_alloc_box(int cpu) +{ + struct intel_uncore_box *box; + + box = kmalloc_node(sizeof(*box), GFP_KERNEL | __GFP_ZERO, + cpu_to_node(cpu)); + if (!box) + return NULL; + + uncore_pmu_init_hrtimer(box); + atomic_set(&box->refcnt, 1); + box->cpu = -1; + box->phys_id = -1; + + return box; +} + +static struct intel_uncore_box * +uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) +{ + return *per_cpu_ptr(pmu->box, cpu); +} + +static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) +{ + return container_of(event->pmu, struct intel_uncore_pmu, pmu); +} + +static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) +{ + /* + * perf core schedules event on the basis of cpu, uncore events are + * collected by one of the cpus inside a physical package. + */ + return uncore_pmu_to_box(uncore_event_to_pmu(event), + smp_processor_id()); +} + +static int uncore_collect_events(struct intel_uncore_box *box, + struct perf_event *leader, bool dogrp) +{ + struct perf_event *event; + int n, max_count; + + max_count = box->pmu->type->num_counters; + if (box->pmu->type->fixed_ctl) + max_count++; + + if (box->n_events >= max_count) + return -EINVAL; + + n = box->n_events; + box->event_list[n] = leader; + n++; + if (!dogrp) + return n; + + list_for_each_entry(event, &leader->sibling_list, group_entry) { + if (event->state <= PERF_EVENT_STATE_OFF) + continue; + + if (n >= max_count) + return -EINVAL; + + box->event_list[n] = event; + n++; + } + return n; +} + +static struct event_constraint * +uncore_event_constraint(struct intel_uncore_type *type, + struct perf_event *event) +{ + struct event_constraint *c; + + if (event->hw.config == ~0ULL) + return &constraint_fixed; + + if (type->constraints) { + for_each_event_constraint(c, type->constraints) { + if ((event->hw.config & c->cmask) == c->code) + return c; + } + } + + return &type->unconstrainted; +} + +static int uncore_assign_events(struct intel_uncore_box *box, + int assign[], int n) +{ + unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; + struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; + int i, ret, wmin, wmax; + struct hw_perf_event *hwc; + + bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); + + for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { + c = uncore_event_constraint(box->pmu->type, + box->event_list[i]); + constraints[i] = c; + wmin = min(wmin, c->weight); + wmax = max(wmax, c->weight); + } + + /* fastpath, try to reuse previous register */ + for (i = 0; i < n; i++) { + hwc = &box->event_list[i]->hw; + c = constraints[i]; + + /* never assigned */ + if (hwc->idx == -1) + break; + + /* constraint still honored */ + if (!test_bit(hwc->idx, c->idxmsk)) + break; + + /* not already used */ + if (test_bit(hwc->idx, used_mask)) + break; + + __set_bit(hwc->idx, used_mask); + assign[i] = hwc->idx; + } + if (i == n) + return 0; + + /* slow path */ + ret = perf_assign_events(constraints, n, wmin, wmax, assign); + return ret ? -EINVAL : 0; +} + +static void uncore_pmu_event_start(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + int idx = event->hw.idx; + + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + return; + + if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX)) + return; + + event->hw.state = 0; + box->events[idx] = event; + box->n_active++; + __set_bit(idx, box->active_mask); + + local64_set(&event->hw.prev_count, uncore_read_counter(box, event)); + uncore_enable_event(box, event); + + if (box->n_active == 1) { + uncore_enable_box(box); + uncore_pmu_start_hrtimer(box); + } +} + +static void uncore_pmu_event_stop(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + struct hw_perf_event *hwc = &event->hw; + + if (__test_and_clear_bit(hwc->idx, box->active_mask)) { + uncore_disable_event(box, event); + box->n_active--; + box->events[hwc->idx] = NULL; + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); + hwc->state |= PERF_HES_STOPPED; + + if (box->n_active == 0) { + uncore_disable_box(box); + uncore_pmu_cancel_hrtimer(box); + } + } + + if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { + /* + * Drain the remaining delta count out of a event + * that we are disabling: + */ + uncore_perf_event_update(box, event); + hwc->state |= PERF_HES_UPTODATE; + } +} + +static int uncore_pmu_event_add(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + struct hw_perf_event *hwc = &event->hw; + int assign[UNCORE_PMC_IDX_MAX]; + int i, n, ret; + + if (!box) + return -ENODEV; + + ret = n = uncore_collect_events(box, event, false); + if (ret < 0) + return ret; + + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; + if (!(flags & PERF_EF_START)) + hwc->state |= PERF_HES_ARCH; + + ret = uncore_assign_events(box, assign, n); + if (ret) + return ret; + + /* save events moving to new counters */ + for (i = 0; i < box->n_events; i++) { + event = box->event_list[i]; + hwc = &event->hw; + + if (hwc->idx == assign[i] && + hwc->last_tag == box->tags[assign[i]]) + continue; + /* + * Ensure we don't accidentally enable a stopped + * counter simply because we rescheduled. + */ + if (hwc->state & PERF_HES_STOPPED) + hwc->state |= PERF_HES_ARCH; + + uncore_pmu_event_stop(event, PERF_EF_UPDATE); + } + + /* reprogram moved events into new counters */ + for (i = 0; i < n; i++) { + event = box->event_list[i]; + hwc = &event->hw; + + if (hwc->idx != assign[i] || + hwc->last_tag != box->tags[assign[i]]) + uncore_assign_hw_event(box, event, assign[i]); + else if (i < box->n_events) + continue; + + if (hwc->state & PERF_HES_ARCH) + continue; + + uncore_pmu_event_start(event, 0); + } + box->n_events = n; + + return 0; +} + +static void uncore_pmu_event_del(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + int i; + + uncore_pmu_event_stop(event, PERF_EF_UPDATE); + + for (i = 0; i < box->n_events; i++) { + if (event == box->event_list[i]) { + while (++i < box->n_events) + box->event_list[i - 1] = box->event_list[i]; + + --box->n_events; + break; + } + } + + event->hw.idx = -1; + event->hw.last_tag = ~0ULL; +} + +static void uncore_pmu_event_read(struct perf_event *event) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + uncore_perf_event_update(box, event); +} + +/* + * validation ensures the group can be loaded onto the + * PMU if it was the only group available. + */ +static int uncore_validate_group(struct intel_uncore_pmu *pmu, + struct perf_event *event) +{ + struct perf_event *leader = event->group_leader; + struct intel_uncore_box *fake_box; + int assign[UNCORE_PMC_IDX_MAX]; + int ret = -EINVAL, n; + + fake_box = uncore_alloc_box(smp_processor_id()); + if (!fake_box) + return -ENOMEM; + + fake_box->pmu = pmu; + /* + * the event is not yet connected with its + * siblings therefore we must first collect + * existing siblings, then add the new event + * before we can simulate the scheduling + */ + n = uncore_collect_events(fake_box, leader, true); + if (n < 0) + goto out; + + fake_box->n_events = n; + n = uncore_collect_events(fake_box, event, false); + if (n < 0) + goto out; + + fake_box->n_events = n; + + ret = uncore_assign_events(fake_box, assign, n); +out: + kfree(fake_box); + return ret; +} + +int uncore_pmu_event_init(struct perf_event *event) +{ + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + struct hw_perf_event *hwc = &event->hw; + int ret; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + pmu = uncore_event_to_pmu(event); + /* no device found for this pmu */ + if (pmu->func_id < 0) + return -ENOENT; + + /* + * Uncore PMU does measure at all privilege level all the time. + * So it doesn't make sense to specify any exclude bits. + */ + if (event->attr.exclude_user || event->attr.exclude_kernel || + event->attr.exclude_hv || event->attr.exclude_idle) + return -EINVAL; + + /* Sampling not supported yet */ + if (hwc->sample_period) + return -EINVAL; + + /* + * Place all uncore events for a particular physical package + * onto a single cpu + */ + if (event->cpu < 0) + return -EINVAL; + box = uncore_pmu_to_box(pmu, event->cpu); + if (!box || box->cpu < 0) + return -EINVAL; + event->cpu = box->cpu; + + if (event->attr.config == UNCORE_FIXED_EVENT) { + /* no fixed counter */ + if (!pmu->type->fixed_ctl) + return -EINVAL; + /* + * if there is only one fixed counter, only the first pmu + * can access the fixed counter + */ + if (pmu->type->single_fixed && pmu->pmu_idx > 0) + return -EINVAL; + hwc->config = ~0ULL; + } else { + hwc->config = event->attr.config & pmu->type->event_mask; + } + + event->hw.idx = -1; + event->hw.last_tag = ~0ULL; + + if (event->group_leader != event) + ret = uncore_validate_group(pmu, event); + else + ret = 0; + + return ret; +} + +static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) +{ + int ret; + + pmu->pmu = (struct pmu) { + .attr_groups = pmu->type->attr_groups, + .task_ctx_nr = perf_invalid_context, + .event_init = uncore_pmu_event_init, + .add = uncore_pmu_event_add, + .del = uncore_pmu_event_del, + .start = uncore_pmu_event_start, + .stop = uncore_pmu_event_stop, + .read = uncore_pmu_event_read, + }; + + if (pmu->type->num_boxes == 1) { + if (strlen(pmu->type->name) > 0) + sprintf(pmu->name, "uncore_%s", pmu->type->name); + else + sprintf(pmu->name, "uncore"); + } else { + sprintf(pmu->name, "uncore_%s_%d", pmu->type->name, + pmu->pmu_idx); + } + + ret = perf_pmu_register(&pmu->pmu, pmu->name, -1); + return ret; +} + +static void __init uncore_type_exit(struct intel_uncore_type *type) +{ + int i; + + for (i = 0; i < type->num_boxes; i++) + free_percpu(type->pmus[i].box); + kfree(type->pmus); + type->pmus = NULL; + kfree(type->attr_groups[1]); + type->attr_groups[1] = NULL; +} + +static int __init uncore_type_init(struct intel_uncore_type *type) +{ + struct intel_uncore_pmu *pmus; + struct attribute_group *events_group; + struct attribute **attrs; + int i, j; + + pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL); + if (!pmus) + return -ENOMEM; + + type->unconstrainted = (struct event_constraint) + __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, + 0, type->num_counters, 0); + + for (i = 0; i < type->num_boxes; i++) { + pmus[i].func_id = -1; + pmus[i].pmu_idx = i; + pmus[i].type = type; + pmus[i].box = alloc_percpu(struct intel_uncore_box *); + if (!pmus[i].box) + goto fail; + } + + if (type->event_descs) { + i = 0; + while (type->event_descs[i].attr.attr.name) + i++; + + events_group = kzalloc(sizeof(struct attribute *) * (i + 1) + + sizeof(*events_group), GFP_KERNEL); + if (!events_group) + goto fail; + + attrs = (struct attribute **)(events_group + 1); + events_group->name = "events"; + events_group->attrs = attrs; + + for (j = 0; j < i; j++) + attrs[j] = &type->event_descs[j].attr.attr; + + type->attr_groups[1] = events_group; + } + + type->pmus = pmus; + return 0; +fail: + uncore_type_exit(type); + return -ENOMEM; +} + +static int __init uncore_types_init(struct intel_uncore_type **types) +{ + int i, ret; + + for (i = 0; types[i]; i++) { + ret = uncore_type_init(types[i]); + if (ret) + goto fail; + } + return 0; +fail: + while (--i >= 0) + uncore_type_exit(types[i]); + return ret; +} + +static void __cpuinit uncore_cpu_dying(int cpu) +{ + struct intel_uncore_type *type; + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + int i, j; + + for (i = 0; msr_uncores[i]; i++) { + type = msr_uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + box = *per_cpu_ptr(pmu->box, cpu); + *per_cpu_ptr(pmu->box, cpu) = NULL; + if (box && atomic_dec_and_test(&box->refcnt)) + kfree(box); + } + } +} + +static int __cpuinit uncore_cpu_starting(int cpu) +{ + struct intel_uncore_type *type; + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box, *exist; + int i, j, k, phys_id; + + phys_id = topology_physical_package_id(cpu); + + for (i = 0; msr_uncores[i]; i++) { + type = msr_uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + box = *per_cpu_ptr(pmu->box, cpu); + /* called by uncore_cpu_init? */ + if (box && box->phys_id >= 0) { + uncore_box_init(box); + continue; + } + + for_each_online_cpu(k) { + exist = *per_cpu_ptr(pmu->box, k); + if (exist && exist->phys_id == phys_id) { + atomic_inc(&exist->refcnt); + *per_cpu_ptr(pmu->box, cpu) = exist; + kfree(box); + box = NULL; + break; + } + } + + if (box) { + box->phys_id = phys_id; + uncore_box_init(box); + } + } + } + return 0; +} + +static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id) +{ + struct intel_uncore_type *type; + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + int i, j; + + for (i = 0; msr_uncores[i]; i++) { + type = msr_uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + if (pmu->func_id < 0) + pmu->func_id = j; + + box = uncore_alloc_box(cpu); + if (!box) + return -ENOMEM; + + box->pmu = pmu; + box->phys_id = phys_id; + *per_cpu_ptr(pmu->box, cpu) = box; + } + } + return 0; +} + +static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores, + int old_cpu, int new_cpu) +{ + struct intel_uncore_type *type; + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + int i, j; + + for (i = 0; uncores[i]; i++) { + type = uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + if (old_cpu < 0) + box = uncore_pmu_to_box(pmu, new_cpu); + else + box = uncore_pmu_to_box(pmu, old_cpu); + if (!box) + continue; + + if (old_cpu < 0) { + WARN_ON_ONCE(box->cpu != -1); + box->cpu = new_cpu; + continue; + } + + WARN_ON_ONCE(box->cpu != old_cpu); + if (new_cpu >= 0) { + uncore_pmu_cancel_hrtimer(box); + perf_pmu_migrate_context(&pmu->pmu, + old_cpu, new_cpu); + box->cpu = new_cpu; + } else { + box->cpu = -1; + } + } + } +} + +static void __cpuinit uncore_event_exit_cpu(int cpu) +{ + int i, phys_id, target; + + /* if exiting cpu is used for collecting uncore events */ + if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask)) + return; + + /* find a new cpu to collect uncore events */ + phys_id = topology_physical_package_id(cpu); + target = -1; + for_each_online_cpu(i) { + if (i == cpu) + continue; + if (phys_id == topology_physical_package_id(i)) { + target = i; + break; + } + } + + /* migrate uncore events to the new cpu */ + if (target >= 0) + cpumask_set_cpu(target, &uncore_cpu_mask); + + uncore_change_context(msr_uncores, cpu, target); +} + +static void __cpuinit uncore_event_init_cpu(int cpu) +{ + int i, phys_id; + + phys_id = topology_physical_package_id(cpu); + for_each_cpu(i, &uncore_cpu_mask) { + if (phys_id == topology_physical_package_id(i)) + return; + } + + cpumask_set_cpu(cpu, &uncore_cpu_mask); + + uncore_change_context(msr_uncores, -1, cpu); +} + +static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + /* allocate/free data structure for uncore box */ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_UP_PREPARE: + uncore_cpu_prepare(cpu, -1); + break; + case CPU_STARTING: + uncore_cpu_starting(cpu); + break; + case CPU_UP_CANCELED: + case CPU_DYING: + uncore_cpu_dying(cpu); + break; + default: + break; + } + + /* select the cpu that collects uncore events */ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_DOWN_FAILED: + case CPU_STARTING: + uncore_event_init_cpu(cpu); + break; + case CPU_DOWN_PREPARE: + uncore_event_exit_cpu(cpu); + break; + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block uncore_cpu_nb __cpuinitdata = { + .notifier_call = uncore_cpu_notifier, + /* + * to migrate uncore events, our notifier should be executed + * before perf core's notifier. + */ + .priority = CPU_PRI_PERF + 1, +}; + +static void __init uncore_cpu_setup(void *dummy) +{ + uncore_cpu_starting(smp_processor_id()); +} + +static int __init uncore_cpu_init(void) +{ + int ret, cpu; + + switch (boot_cpu_data.x86_model) { + default: + return 0; + } + + ret = uncore_types_init(msr_uncores); + if (ret) + return ret; + + get_online_cpus(); + + for_each_online_cpu(cpu) { + int i, phys_id = topology_physical_package_id(cpu); + + for_each_cpu(i, &uncore_cpu_mask) { + if (phys_id == topology_physical_package_id(i)) { + phys_id = -1; + break; + } + } + if (phys_id < 0) + continue; + + uncore_cpu_prepare(cpu, phys_id); + uncore_event_init_cpu(cpu); + } + on_each_cpu(uncore_cpu_setup, NULL, 1); + + register_cpu_notifier(&uncore_cpu_nb); + + put_online_cpus(); + + return 0; +} + +static int __init uncore_pmus_register(void) +{ + struct intel_uncore_pmu *pmu; + struct intel_uncore_type *type; + int i, j; + + for (i = 0; msr_uncores[i]; i++) { + type = msr_uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + uncore_pmu_register(pmu); + } + } + + return 0; +} + +static int __init intel_uncore_init(void) +{ + int ret; + + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return -ENODEV; + + ret = uncore_cpu_init(); + if (ret) + goto fail; + + uncore_pmus_register(); + return 0; +fail: + return ret; +} +device_initcall(intel_uncore_init); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h new file mode 100644 index 000000000000..49a6bfbba0de --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -0,0 +1,204 @@ +#include +#include +#include +#include "perf_event.h" + +#define UNCORE_PMU_NAME_LEN 32 +#define UNCORE_BOX_HASH_SIZE 8 + +#define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) + +#define UNCORE_FIXED_EVENT 0xffff +#define UNCORE_PMC_IDX_MAX_GENERIC 8 +#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC +#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) + +#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) + +struct intel_uncore_ops; +struct intel_uncore_pmu; +struct intel_uncore_box; +struct uncore_event_desc; + +struct intel_uncore_type { + const char *name; + int num_counters; + int num_boxes; + int perf_ctr_bits; + int fixed_ctr_bits; + int single_fixed; + unsigned perf_ctr; + unsigned event_ctl; + unsigned event_mask; + unsigned fixed_ctr; + unsigned fixed_ctl; + unsigned box_ctl; + unsigned msr_offset; + struct event_constraint unconstrainted; + struct event_constraint *constraints; + struct intel_uncore_pmu *pmus; + struct intel_uncore_ops *ops; + struct uncore_event_desc *event_descs; + const struct attribute_group *attr_groups[3]; +}; + +#define format_group attr_groups[0] + +struct intel_uncore_ops { + void (*init_box)(struct intel_uncore_box *); + void (*disable_box)(struct intel_uncore_box *); + void (*enable_box)(struct intel_uncore_box *); + void (*disable_event)(struct intel_uncore_box *, struct perf_event *); + void (*enable_event)(struct intel_uncore_box *, struct perf_event *); + u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *); +}; + +struct intel_uncore_pmu { + struct pmu pmu; + char name[UNCORE_PMU_NAME_LEN]; + int pmu_idx; + int func_id; + struct intel_uncore_type *type; + struct intel_uncore_box ** __percpu box; +}; + +struct intel_uncore_box { + int phys_id; + int n_active; /* number of active events */ + int n_events; + int cpu; /* cpu to collect events */ + unsigned long flags; + atomic_t refcnt; + struct perf_event *events[UNCORE_PMC_IDX_MAX]; + struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; + unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; + u64 tags[UNCORE_PMC_IDX_MAX]; + struct intel_uncore_pmu *pmu; + struct hrtimer hrtimer; + struct list_head list; +}; + +#define UNCORE_BOX_FLAG_INITIATED 0 + +struct uncore_event_desc { + struct kobj_attribute attr; + const char *config; +}; + +#define INTEL_UNCORE_EVENT_DESC(_name, _config) \ +{ \ + .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \ + .config = _config, \ +} + +#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ +static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *page) \ +{ \ + BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ + return sprintf(page, _format "\n"); \ +} \ +static struct kobj_attribute format_attr_##_var = \ + __ATTR(_name, 0444, __uncore_##_var##_show, NULL) + + +static ssize_t uncore_event_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct uncore_event_desc *event = + container_of(attr, struct uncore_event_desc, attr); + return sprintf(buf, "%s", event->config); +} + +static inline +unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) +{ + if (!box->pmu->type->box_ctl) + return 0; + return box->pmu->type->box_ctl + + box->pmu->type->msr_offset * box->pmu->pmu_idx; +} + +static inline +unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) +{ + if (!box->pmu->type->fixed_ctl) + return 0; + return box->pmu->type->fixed_ctl + + box->pmu->type->msr_offset * box->pmu->pmu_idx; +} + +static inline +unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) +{ + return box->pmu->type->fixed_ctr + + box->pmu->type->msr_offset * box->pmu->pmu_idx; +} + +static inline +unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) +{ + return idx + box->pmu->type->event_ctl + + box->pmu->type->msr_offset * box->pmu->pmu_idx; +} + +static inline +unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) +{ + return idx + box->pmu->type->perf_ctr + + box->pmu->type->msr_offset * box->pmu->pmu_idx; +} + +static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box) +{ + return box->pmu->type->perf_ctr_bits; +} + +static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box) +{ + return box->pmu->type->fixed_ctr_bits; +} + +static inline int uncore_num_counters(struct intel_uncore_box *box) +{ + return box->pmu->type->num_counters; +} + +static inline void uncore_disable_box(struct intel_uncore_box *box) +{ + if (box->pmu->type->ops->disable_box) + box->pmu->type->ops->disable_box(box); +} + +static inline void uncore_enable_box(struct intel_uncore_box *box) +{ + if (box->pmu->type->ops->enable_box) + box->pmu->type->ops->enable_box(box); +} + +static inline void uncore_disable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + box->pmu->type->ops->disable_event(box, event); +} + +static inline void uncore_enable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + box->pmu->type->ops->enable_event(box, event); +} + +static inline u64 uncore_read_counter(struct intel_uncore_box *box, + struct perf_event *event) +{ + return box->pmu->type->ops->read_counter(box, event); +} + +static inline void uncore_box_init(struct intel_uncore_box *box) +{ + if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { + if (box->pmu->type->ops->init_box) + box->pmu->type->ops->init_box(box); + } +} -- GitLab From fcde10e916326545e8fec1807357c68ef08dc443 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:35 +0800 Subject: [PATCH 1835/6849] perf/x86: Add Intel Nehalem and Sandy Bridge uncore PMU support Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1339741902-8449-7-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 195 ++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_uncore.h | 50 +++++ 2 files changed, 245 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index fe76a07dfdbc..3ed941ac3745 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -10,6 +10,192 @@ static cpumask_t uncore_cpu_mask; static struct event_constraint constraint_fixed = EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL); +DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); +DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); +DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); +DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); +DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); +DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); + +/* Sandy Bridge uncore support */ +static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (hwc->idx < UNCORE_PMC_IDX_FIXED) + wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); + else + wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); +} + +static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + wrmsrl(event->hw.config_base, 0); +} + +static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box, + struct perf_event *event) +{ + u64 count; + rdmsrl(event->hw.event_base, count); + return count; +} + +static void snb_uncore_msr_init_box(struct intel_uncore_box *box) +{ + if (box->pmu->pmu_idx == 0) { + wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, + SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL); + } +} + +static struct attribute *snb_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_cmask5.attr, + NULL, +}; + +static struct attribute_group snb_uncore_format_group = { + .name = "format", + .attrs = snb_uncore_formats_attr, +}; + +static struct intel_uncore_ops snb_uncore_msr_ops = { + .init_box = snb_uncore_msr_init_box, + .disable_event = snb_uncore_msr_disable_event, + .enable_event = snb_uncore_msr_enable_event, + .read_counter = snb_uncore_msr_read_counter, +}; + +static struct event_constraint snb_uncore_cbox_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x80, 0x1), + UNCORE_EVENT_CONSTRAINT(0x83, 0x1), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type snb_uncore_cbox = { + .name = "cbox", + .num_counters = 2, + .num_boxes = 4, + .perf_ctr_bits = 44, + .fixed_ctr_bits = 48, + .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, + .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, + .fixed_ctr = SNB_UNC_FIXED_CTR, + .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL, + .single_fixed = 1, + .event_mask = SNB_UNC_RAW_EVENT_MASK, + .msr_offset = SNB_UNC_CBO_MSR_OFFSET, + .constraints = snb_uncore_cbox_constraints, + .ops = &snb_uncore_msr_ops, + .format_group = &snb_uncore_format_group, +}; + +static struct intel_uncore_type *snb_msr_uncores[] = { + &snb_uncore_cbox, + NULL, +}; +/* end of Sandy Bridge uncore support */ + +/* Nehalem uncore support */ +static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) +{ + wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0); +} + +static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) +{ + wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, + NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); +} + +static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (hwc->idx < UNCORE_PMC_IDX_FIXED) + wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); + else + wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN); +} + +static struct attribute *nhm_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_cmask8.attr, + NULL, +}; + +static struct attribute_group nhm_uncore_format_group = { + .name = "format", + .attrs = nhm_uncore_formats_attr, +}; + +static struct uncore_event_desc nhm_uncore_events[] = { + INTEL_UNCORE_EVENT_DESC(CLOCKTICKS, "config=0xffff"), + /* full cache line writes to DRAM */ + INTEL_UNCORE_EVENT_DESC(QMC_WRITES_FULL_ANY, "event=0x2f,umask=0xf"), + /* Quickpath Memory Controller normal priority read requests */ + INTEL_UNCORE_EVENT_DESC(QMC_NORMAL_READS_ANY, "event=0x2c,umask=0xf"), + /* Quickpath Home Logic read requests from the IOH */ + INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_IOH_READS, + "event=0x20,umask=0x1"), + /* Quickpath Home Logic write requests from the IOH */ + INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_IOH_WRITES, + "event=0x20,umask=0x2"), + /* Quickpath Home Logic read requests from a remote socket */ + INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_REMOTE_READS, + "event=0x20,umask=0x4"), + /* Quickpath Home Logic write requests from a remote socket */ + INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_REMOTE_WRITES, + "event=0x20,umask=0x8"), + /* Quickpath Home Logic read requests from the local socket */ + INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_LOCAL_READS, + "event=0x20,umask=0x10"), + /* Quickpath Home Logic write requests from the local socket */ + INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_LOCAL_WRITES, + "event=0x20,umask=0x20"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_ops nhm_uncore_msr_ops = { + .disable_box = nhm_uncore_msr_disable_box, + .enable_box = nhm_uncore_msr_enable_box, + .disable_event = snb_uncore_msr_disable_event, + .enable_event = nhm_uncore_msr_enable_event, + .read_counter = snb_uncore_msr_read_counter, +}; + +static struct intel_uncore_type nhm_uncore = { + .name = "", + .num_counters = 8, + .num_boxes = 1, + .perf_ctr_bits = 48, + .fixed_ctr_bits = 48, + .event_ctl = NHM_UNC_PERFEVTSEL0, + .perf_ctr = NHM_UNC_UNCORE_PMC0, + .fixed_ctr = NHM_UNC_FIXED_CTR, + .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL, + .event_mask = NHM_UNC_RAW_EVENT_MASK, + .event_descs = nhm_uncore_events, + .ops = &nhm_uncore_msr_ops, + .format_group = &nhm_uncore_format_group, +}; + +static struct intel_uncore_type *nhm_msr_uncores[] = { + &nhm_uncore, + NULL, +}; +/* end of Nehalem uncore support */ + static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx) { @@ -808,6 +994,15 @@ static int __init uncore_cpu_init(void) int ret, cpu; switch (boot_cpu_data.x86_model) { + case 26: /* Nehalem */ + case 30: + case 37: /* Westmere */ + case 44: + msr_uncores = nhm_msr_uncores; + break; + case 42: /* Sandy Bridge */ + msr_uncores = snb_msr_uncores; + break; default: return 0; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 49a6bfbba0de..eeb5ca5815a8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -15,6 +15,56 @@ #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) +/* SNB event control */ +#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff +#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 +#define SNB_UNC_CTL_EDGE_DET (1 << 18) +#define SNB_UNC_CTL_EN (1 << 22) +#define SNB_UNC_CTL_INVERT (1 << 23) +#define SNB_UNC_CTL_CMASK_MASK 0x1f000000 +#define NHM_UNC_CTL_CMASK_MASK 0xff000000 +#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0) + +#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ + SNB_UNC_CTL_UMASK_MASK | \ + SNB_UNC_CTL_EDGE_DET | \ + SNB_UNC_CTL_INVERT | \ + SNB_UNC_CTL_CMASK_MASK) + +#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ + SNB_UNC_CTL_UMASK_MASK | \ + SNB_UNC_CTL_EDGE_DET | \ + SNB_UNC_CTL_INVERT | \ + NHM_UNC_CTL_CMASK_MASK) + +/* SNB global control register */ +#define SNB_UNC_PERF_GLOBAL_CTL 0x391 +#define SNB_UNC_FIXED_CTR_CTRL 0x394 +#define SNB_UNC_FIXED_CTR 0x395 + +/* SNB uncore global control */ +#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1) +#define SNB_UNC_GLOBAL_CTL_EN (1 << 29) + +/* SNB Cbo register */ +#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700 +#define SNB_UNC_CBO_0_PER_CTR0 0x706 +#define SNB_UNC_CBO_MSR_OFFSET 0x10 + +/* NHM global control register */ +#define NHM_UNC_PERF_GLOBAL_CTL 0x391 +#define NHM_UNC_FIXED_CTR 0x394 +#define NHM_UNC_FIXED_CTR_CTRL 0x395 + +/* NHM uncore global control */ +#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1) +#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32) + +/* NHM uncore register */ +#define NHM_UNC_PERFEVTSEL0 0x3c0 +#define NHM_UNC_UNCORE_PMC0 0x3b0 + + struct intel_uncore_ops; struct intel_uncore_pmu; struct intel_uncore_box; -- GitLab From 14371cce03c2fc393997e17f979e76674b7f392a Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:36 +0800 Subject: [PATCH 1836/6849] perf: Add generic PCI uncore PMU device support This patch adds generic support for uncore PMUs presented as PCI devices. (These come in addition to the CPU/MSR based uncores.) Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-8-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 175 +++++++++++++++++- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 66 +++++++ 2 files changed, 236 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 3ed941ac3745..e20c65a0e108 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -2,6 +2,11 @@ static struct intel_uncore_type *empty_uncore[] = { NULL, }; static struct intel_uncore_type **msr_uncores = empty_uncore; +static struct intel_uncore_type **pci_uncores = empty_uncore; +/* pci bus to socket mapping */ +static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; + +static DEFINE_RAW_SPINLOCK(uncore_box_lock); /* mask of cpus that collect uncore events */ static cpumask_t uncore_cpu_mask; @@ -205,13 +210,13 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box, hwc->last_tag = ++box->tags[idx]; if (hwc->idx == UNCORE_PMC_IDX_FIXED) { - hwc->event_base = uncore_msr_fixed_ctr(box); - hwc->config_base = uncore_msr_fixed_ctl(box); + hwc->event_base = uncore_fixed_ctr(box); + hwc->config_base = uncore_fixed_ctl(box); return; } - hwc->config_base = uncore_msr_event_ctl(box, hwc->idx); - hwc->event_base = uncore_msr_perf_ctr(box, hwc->idx); + hwc->config_base = uncore_event_ctl(box, hwc->idx); + hwc->event_base = uncore_perf_ctr(box, hwc->idx); } static void uncore_perf_event_update(struct intel_uncore_box *box, @@ -305,6 +310,22 @@ struct intel_uncore_box *uncore_alloc_box(int cpu) static struct intel_uncore_box * uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) { + static struct intel_uncore_box *box; + + box = *per_cpu_ptr(pmu->box, cpu); + if (box) + return box; + + raw_spin_lock(&uncore_box_lock); + list_for_each_entry(box, &pmu->box_list, list) { + if (box->phys_id == topology_physical_package_id(cpu)) { + atomic_inc(&box->refcnt); + *per_cpu_ptr(pmu->box, cpu) = box; + break; + } + } + raw_spin_unlock(&uncore_box_lock); + return *per_cpu_ptr(pmu->box, cpu); } @@ -706,6 +727,13 @@ static void __init uncore_type_exit(struct intel_uncore_type *type) type->attr_groups[1] = NULL; } +static void uncore_types_exit(struct intel_uncore_type **types) +{ + int i; + for (i = 0; types[i]; i++) + uncore_type_exit(types[i]); +} + static int __init uncore_type_init(struct intel_uncore_type *type) { struct intel_uncore_pmu *pmus; @@ -725,6 +753,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type) pmus[i].func_id = -1; pmus[i].pmu_idx = i; pmus[i].type = type; + INIT_LIST_HEAD(&pmus[i].box_list); pmus[i].box = alloc_percpu(struct intel_uncore_box *); if (!pmus[i].box) goto fail; @@ -773,6 +802,127 @@ fail: return ret; } +static struct pci_driver *uncore_pci_driver; +static bool pcidrv_registered; + +/* + * add a pci uncore device + */ +static int __devinit uncore_pci_add(struct intel_uncore_type *type, + struct pci_dev *pdev) +{ + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + int i, phys_id; + + phys_id = pcibus_to_physid[pdev->bus->number]; + if (phys_id < 0) + return -ENODEV; + + box = uncore_alloc_box(0); + if (!box) + return -ENOMEM; + + /* + * for performance monitoring unit with multiple boxes, + * each box has a different function id. + */ + for (i = 0; i < type->num_boxes; i++) { + pmu = &type->pmus[i]; + if (pmu->func_id == pdev->devfn) + break; + if (pmu->func_id < 0) { + pmu->func_id = pdev->devfn; + break; + } + pmu = NULL; + } + + if (!pmu) { + kfree(box); + return -EINVAL; + } + + box->phys_id = phys_id; + box->pci_dev = pdev; + box->pmu = pmu; + uncore_box_init(box); + pci_set_drvdata(pdev, box); + + raw_spin_lock(&uncore_box_lock); + list_add_tail(&box->list, &pmu->box_list); + raw_spin_unlock(&uncore_box_lock); + + return 0; +} + +static void __devexit uncore_pci_remove(struct pci_dev *pdev) +{ + struct intel_uncore_box *box = pci_get_drvdata(pdev); + struct intel_uncore_pmu *pmu = box->pmu; + int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; + + if (WARN_ON_ONCE(phys_id != box->phys_id)) + return; + + raw_spin_lock(&uncore_box_lock); + list_del(&box->list); + raw_spin_unlock(&uncore_box_lock); + + for_each_possible_cpu(cpu) { + if (*per_cpu_ptr(pmu->box, cpu) == box) { + *per_cpu_ptr(pmu->box, cpu) = NULL; + atomic_dec(&box->refcnt); + } + } + + WARN_ON_ONCE(atomic_read(&box->refcnt) != 1); + kfree(box); +} + +static int __devinit uncore_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct intel_uncore_type *type; + + type = (struct intel_uncore_type *)id->driver_data; + return uncore_pci_add(type, pdev); +} + +static int __init uncore_pci_init(void) +{ + int ret; + + switch (boot_cpu_data.x86_model) { + default: + return 0; + } + + ret = uncore_types_init(pci_uncores); + if (ret) + return ret; + + uncore_pci_driver->probe = uncore_pci_probe; + uncore_pci_driver->remove = uncore_pci_remove; + + ret = pci_register_driver(uncore_pci_driver); + if (ret == 0) + pcidrv_registered = true; + else + uncore_types_exit(pci_uncores); + + return ret; +} + +static void __init uncore_pci_exit(void) +{ + if (pcidrv_registered) { + pcidrv_registered = false; + pci_unregister_driver(uncore_pci_driver); + uncore_types_exit(pci_uncores); + } +} + static void __cpuinit uncore_cpu_dying(int cpu) { struct intel_uncore_type *type; @@ -921,6 +1071,7 @@ static void __cpuinit uncore_event_exit_cpu(int cpu) cpumask_set_cpu(target, &uncore_cpu_mask); uncore_change_context(msr_uncores, cpu, target); + uncore_change_context(pci_uncores, cpu, target); } static void __cpuinit uncore_event_init_cpu(int cpu) @@ -936,6 +1087,7 @@ static void __cpuinit uncore_event_init_cpu(int cpu) cpumask_set_cpu(cpu, &uncore_cpu_mask); uncore_change_context(msr_uncores, -1, cpu); + uncore_change_context(pci_uncores, -1, cpu); } static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, @@ -1051,6 +1203,14 @@ static int __init uncore_pmus_register(void) } } + for (i = 0; pci_uncores[i]; i++) { + type = pci_uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + uncore_pmu_register(pmu); + } + } + return 0; } @@ -1061,9 +1221,14 @@ static int __init intel_uncore_init(void) if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) return -ENODEV; - ret = uncore_cpu_init(); + ret = uncore_pci_init(); if (ret) goto fail; + ret = uncore_cpu_init(); + if (ret) { + uncore_pci_exit(); + goto fail; + } uncore_pmus_register(); return 0; diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index eeb5ca5815a8..aa01df87b8de 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -1,5 +1,6 @@ #include #include +#include #include #include "perf_event.h" @@ -110,6 +111,7 @@ struct intel_uncore_pmu { int func_id; struct intel_uncore_type *type; struct intel_uncore_box ** __percpu box; + struct list_head box_list; }; struct intel_uncore_box { @@ -123,6 +125,7 @@ struct intel_uncore_box { struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; u64 tags[UNCORE_PMC_IDX_MAX]; + struct pci_dev *pci_dev; struct intel_uncore_pmu *pmu; struct hrtimer hrtimer; struct list_head list; @@ -161,6 +164,33 @@ static ssize_t uncore_event_show(struct kobject *kobj, return sprintf(buf, "%s", event->config); } +static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box) +{ + return box->pmu->type->box_ctl; +} + +static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box) +{ + return box->pmu->type->fixed_ctl; +} + +static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box) +{ + return box->pmu->type->fixed_ctr; +} + +static inline +unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx) +{ + return idx * 4 + box->pmu->type->event_ctl; +} + +static inline +unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx) +{ + return idx * 8 + box->pmu->type->perf_ctr; +} + static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) { @@ -200,6 +230,42 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) box->pmu->type->msr_offset * box->pmu->pmu_idx; } +static inline +unsigned uncore_fixed_ctl(struct intel_uncore_box *box) +{ + if (box->pci_dev) + return uncore_pci_fixed_ctl(box); + else + return uncore_msr_fixed_ctl(box); +} + +static inline +unsigned uncore_fixed_ctr(struct intel_uncore_box *box) +{ + if (box->pci_dev) + return uncore_pci_fixed_ctr(box); + else + return uncore_msr_fixed_ctr(box); +} + +static inline +unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx) +{ + if (box->pci_dev) + return uncore_pci_event_ctl(box, idx); + else + return uncore_msr_event_ctl(box, idx); +} + +static inline +unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx) +{ + if (box->pci_dev) + return uncore_pci_perf_ctr(box, idx); + else + return uncore_msr_perf_ctr(box, idx); +} + static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box) { return box->pmu->type->perf_ctr_bits; -- GitLab From 7c94ee2e0917b2ea56498bff939c8aa55da27207 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:37 +0800 Subject: [PATCH 1837/6849] perf/x86: Add Intel Nehalem and Sandy Bridge-EP uncore support The uncore subsystem in Sandy Bridge-EP consists of 8 components: Ubox, Cacheing Agent, Home Agent, Memory controller, Power Control, QPI Link Layer, R2PCIe, R3QPI. Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1339741902-8449-9-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 484 ++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_uncore.h | 86 ++++ include/linux/pci_ids.h | 11 + 3 files changed, 581 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index e20c65a0e108..d34f68bf990b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -21,6 +21,482 @@ DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); +DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); +DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); +DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); +DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); +DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); + +/* Sandy Bridge-EP uncore support */ +static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + int box_ctl = uncore_pci_box_ctl(box); + u32 config; + + pci_read_config_dword(pdev, box_ctl, &config); + config |= SNBEP_PMON_BOX_CTL_FRZ; + pci_write_config_dword(pdev, box_ctl, config); +} + +static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + int box_ctl = uncore_pci_box_ctl(box); + u32 config; + + pci_read_config_dword(pdev, box_ctl, &config); + config &= ~SNBEP_PMON_BOX_CTL_FRZ; + pci_write_config_dword(pdev, box_ctl, config); +} + +static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, hwc->config_base, hwc->config | + SNBEP_PMON_CTL_EN); +} + +static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, hwc->config_base, hwc->config); +} + +static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + u64 count; + + pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); + pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); + return count; +} + +static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, + SNBEP_PMON_BOX_CTL_INT); +} + +static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) +{ + u64 config; + unsigned msr; + + msr = uncore_msr_box_ctl(box); + if (msr) { + rdmsrl(msr, config); + config |= SNBEP_PMON_BOX_CTL_FRZ; + wrmsrl(msr, config); + return; + } +} + +static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) +{ + u64 config; + unsigned msr; + + msr = uncore_msr_box_ctl(box); + if (msr) { + rdmsrl(msr, config); + config &= ~SNBEP_PMON_BOX_CTL_FRZ; + wrmsrl(msr, config); + return; + } +} + +static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); +} + +static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + wrmsrl(hwc->config_base, hwc->config); +} + +static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + u64 count; + + rdmsrl(hwc->event_base, count); + return count; +} + +static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) +{ + unsigned msr = uncore_msr_box_ctl(box); + if (msr) + wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); +} + +static struct attribute *snbep_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + NULL, +}; + +static struct attribute *snbep_uncore_ubox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh5.attr, + NULL, +}; + +static struct attribute *snbep_uncore_pcu_formats_attr[] = { + &format_attr_event.attr, + &format_attr_occ_sel.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh5.attr, + &format_attr_occ_invert.attr, + &format_attr_occ_edge.attr, + NULL, +}; + +static struct uncore_event_desc snbep_uncore_imc_events[] = { + INTEL_UNCORE_EVENT_DESC(CLOCKTICKS, "config=0xffff"), + /* read */ + INTEL_UNCORE_EVENT_DESC(CAS_COUNT_RD, "event=0x4,umask=0x3"), + /* write */ + INTEL_UNCORE_EVENT_DESC(CAS_COUNT_WR, "event=0x4,umask=0xc"), + { /* end: all zeroes */ }, +}; + +static struct uncore_event_desc snbep_uncore_qpi_events[] = { + INTEL_UNCORE_EVENT_DESC(CLOCKTICKS, "event=0x14"), + /* outgoing data+nondata flits */ + INTEL_UNCORE_EVENT_DESC(TxL_FLITS_ACTIVE, "event=0x0,umask=0x6"), + /* DRS data received */ + INTEL_UNCORE_EVENT_DESC(DRS_DATA, "event=0x2,umask=0x8"), + /* NCB data received */ + INTEL_UNCORE_EVENT_DESC(NCB_DATA, "event=0x3,umask=0x4"), + { /* end: all zeroes */ }, +}; + +static struct attribute_group snbep_uncore_format_group = { + .name = "format", + .attrs = snbep_uncore_formats_attr, +}; + +static struct attribute_group snbep_uncore_ubox_format_group = { + .name = "format", + .attrs = snbep_uncore_ubox_formats_attr, +}; + +static struct attribute_group snbep_uncore_pcu_format_group = { + .name = "format", + .attrs = snbep_uncore_pcu_formats_attr, +}; + +static struct intel_uncore_ops snbep_uncore_msr_ops = { + .init_box = snbep_uncore_msr_init_box, + .disable_box = snbep_uncore_msr_disable_box, + .enable_box = snbep_uncore_msr_enable_box, + .disable_event = snbep_uncore_msr_disable_event, + .enable_event = snbep_uncore_msr_enable_event, + .read_counter = snbep_uncore_msr_read_counter, +}; + +static struct intel_uncore_ops snbep_uncore_pci_ops = { + .init_box = snbep_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = snbep_uncore_pci_disable_event, + .enable_event = snbep_uncore_pci_enable_event, + .read_counter = snbep_uncore_pci_read_counter, +}; + +static struct event_constraint snbep_uncore_cbox_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x01, 0x1), + UNCORE_EVENT_CONSTRAINT(0x02, 0x3), + UNCORE_EVENT_CONSTRAINT(0x04, 0x3), + UNCORE_EVENT_CONSTRAINT(0x05, 0x3), + UNCORE_EVENT_CONSTRAINT(0x07, 0x3), + UNCORE_EVENT_CONSTRAINT(0x11, 0x1), + UNCORE_EVENT_CONSTRAINT(0x12, 0x3), + UNCORE_EVENT_CONSTRAINT(0x13, 0x3), + UNCORE_EVENT_CONSTRAINT(0x1b, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1c, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1d, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1e, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1f, 0xe), + UNCORE_EVENT_CONSTRAINT(0x21, 0x3), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x31, 0x3), + UNCORE_EVENT_CONSTRAINT(0x32, 0x3), + UNCORE_EVENT_CONSTRAINT(0x33, 0x3), + UNCORE_EVENT_CONSTRAINT(0x34, 0x3), + UNCORE_EVENT_CONSTRAINT(0x35, 0x3), + UNCORE_EVENT_CONSTRAINT(0x36, 0x1), + UNCORE_EVENT_CONSTRAINT(0x37, 0x3), + UNCORE_EVENT_CONSTRAINT(0x38, 0x3), + UNCORE_EVENT_CONSTRAINT(0x39, 0x3), + UNCORE_EVENT_CONSTRAINT(0x3b, 0x1), + EVENT_CONSTRAINT_END +}; + +static struct event_constraint snbep_uncore_r2pcie_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x10, 0x3), + UNCORE_EVENT_CONSTRAINT(0x11, 0x3), + UNCORE_EVENT_CONSTRAINT(0x12, 0x1), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x24, 0x3), + UNCORE_EVENT_CONSTRAINT(0x25, 0x3), + UNCORE_EVENT_CONSTRAINT(0x26, 0x3), + UNCORE_EVENT_CONSTRAINT(0x32, 0x3), + UNCORE_EVENT_CONSTRAINT(0x33, 0x3), + UNCORE_EVENT_CONSTRAINT(0x34, 0x3), + EVENT_CONSTRAINT_END +}; + +static struct event_constraint snbep_uncore_r3qpi_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x10, 0x3), + UNCORE_EVENT_CONSTRAINT(0x11, 0x3), + UNCORE_EVENT_CONSTRAINT(0x12, 0x3), + UNCORE_EVENT_CONSTRAINT(0x13, 0x1), + UNCORE_EVENT_CONSTRAINT(0x20, 0x3), + UNCORE_EVENT_CONSTRAINT(0x21, 0x3), + UNCORE_EVENT_CONSTRAINT(0x22, 0x3), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x24, 0x3), + UNCORE_EVENT_CONSTRAINT(0x25, 0x3), + UNCORE_EVENT_CONSTRAINT(0x26, 0x3), + UNCORE_EVENT_CONSTRAINT(0x30, 0x3), + UNCORE_EVENT_CONSTRAINT(0x31, 0x3), + UNCORE_EVENT_CONSTRAINT(0x32, 0x3), + UNCORE_EVENT_CONSTRAINT(0x33, 0x3), + UNCORE_EVENT_CONSTRAINT(0x34, 0x3), + UNCORE_EVENT_CONSTRAINT(0x36, 0x3), + UNCORE_EVENT_CONSTRAINT(0x37, 0x3), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type snbep_uncore_ubox = { + .name = "ubox", + .num_counters = 2, + .num_boxes = 1, + .perf_ctr_bits = 44, + .fixed_ctr_bits = 48, + .perf_ctr = SNBEP_U_MSR_PMON_CTR0, + .event_ctl = SNBEP_U_MSR_PMON_CTL0, + .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, + .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, + .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, + .ops = &snbep_uncore_msr_ops, + .format_group = &snbep_uncore_ubox_format_group, +}; + +static struct intel_uncore_type snbep_uncore_cbox = { + .name = "cbox", + .num_counters = 4, + .num_boxes = 8, + .perf_ctr_bits = 44, + .event_ctl = SNBEP_C0_MSR_PMON_CTL0, + .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, + .msr_offset = SNBEP_CBO_MSR_OFFSET, + .constraints = snbep_uncore_cbox_constraints, + .ops = &snbep_uncore_msr_ops, + .format_group = &snbep_uncore_format_group, +}; + +static struct intel_uncore_type snbep_uncore_pcu = { + .name = "pcu", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, + .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, + .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, + .ops = &snbep_uncore_msr_ops, + .format_group = &snbep_uncore_pcu_format_group, +}; + +static struct intel_uncore_type *snbep_msr_uncores[] = { + &snbep_uncore_ubox, + &snbep_uncore_cbox, + &snbep_uncore_pcu, + NULL, +}; + +#define SNBEP_UNCORE_PCI_COMMON_INIT() \ + .perf_ctr = SNBEP_PCI_PMON_CTR0, \ + .event_ctl = SNBEP_PCI_PMON_CTL0, \ + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \ + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ + .ops = &snbep_uncore_pci_ops, \ + .format_group = &snbep_uncore_format_group + +static struct intel_uncore_type snbep_uncore_ha = { + .name = "ha", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type snbep_uncore_imc = { + .name = "imc", + .num_counters = 4, + .num_boxes = 4, + .perf_ctr_bits = 48, + .fixed_ctr_bits = 48, + .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, + .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, + .event_descs = snbep_uncore_imc_events, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type snbep_uncore_qpi = { + .name = "qpi", + .num_counters = 4, + .num_boxes = 2, + .perf_ctr_bits = 48, + .event_descs = snbep_uncore_qpi_events, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + + +static struct intel_uncore_type snbep_uncore_r2pcie = { + .name = "r2pcie", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 44, + .constraints = snbep_uncore_r2pcie_constraints, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type snbep_uncore_r3qpi = { + .name = "r3qpi", + .num_counters = 3, + .num_boxes = 2, + .perf_ctr_bits = 44, + .constraints = snbep_uncore_r3qpi_constraints, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type *snbep_pci_uncores[] = { + &snbep_uncore_ha, + &snbep_uncore_imc, + &snbep_uncore_qpi, + &snbep_uncore_r2pcie, + &snbep_uncore_r3qpi, + NULL, +}; + +static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { + { /* Home Agent */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), + .driver_data = (unsigned long)&snbep_uncore_ha, + }, + { /* MC Channel 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), + .driver_data = (unsigned long)&snbep_uncore_imc, + }, + { /* MC Channel 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), + .driver_data = (unsigned long)&snbep_uncore_imc, + }, + { /* MC Channel 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), + .driver_data = (unsigned long)&snbep_uncore_imc, + }, + { /* MC Channel 3 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), + .driver_data = (unsigned long)&snbep_uncore_imc, + }, + { /* QPI Port 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), + .driver_data = (unsigned long)&snbep_uncore_qpi, + }, + { /* QPI Port 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), + .driver_data = (unsigned long)&snbep_uncore_qpi, + }, + { /* P2PCIe */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), + .driver_data = (unsigned long)&snbep_uncore_r2pcie, + }, + { /* R3QPI Link 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), + .driver_data = (unsigned long)&snbep_uncore_r3qpi, + }, + { /* R3QPI Link 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), + .driver_data = (unsigned long)&snbep_uncore_r3qpi, + }, + { /* end: all zeroes */ } +}; + +static struct pci_driver snbep_uncore_pci_driver = { + .name = "snbep_uncore", + .id_table = snbep_uncore_pci_ids, +}; + +/* + * build pci bus to socket mapping + */ +static void snbep_pci2phy_map_init(void) +{ + struct pci_dev *ubox_dev = NULL; + int i, bus, nodeid; + u32 config; + + while (1) { + /* find the UBOX device */ + ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX, + ubox_dev); + if (!ubox_dev) + break; + bus = ubox_dev->bus->number; + /* get the Node ID of the local register */ + pci_read_config_dword(ubox_dev, 0x40, &config); + nodeid = config; + /* get the Node ID mapping */ + pci_read_config_dword(ubox_dev, 0x54, &config); + /* + * every three bits in the Node ID mapping register maps + * to a particular node. + */ + for (i = 0; i < 8; i++) { + if (nodeid == ((config >> (3 * i)) & 0x7)) { + pcibus_to_physid[bus] = i; + break; + } + } + }; + return; +} +/* end of Sandy Bridge-EP uncore support */ + /* Sandy Bridge uncore support */ static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, @@ -894,6 +1370,11 @@ static int __init uncore_pci_init(void) int ret; switch (boot_cpu_data.x86_model) { + case 45: /* Sandy Bridge-EP */ + pci_uncores = snbep_pci_uncores; + uncore_pci_driver = &snbep_uncore_pci_driver; + snbep_pci2phy_map_init(); + break; default: return 0; } @@ -1155,6 +1636,9 @@ static int __init uncore_cpu_init(void) case 42: /* Sandy Bridge */ msr_uncores = snb_msr_uncores; break; + case 45: /* Sandy Birdge-EP */ + msr_uncores = snbep_msr_uncores; + break; default: return 0; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index aa01df87b8de..4d52db0d1dfe 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -65,6 +65,92 @@ #define NHM_UNC_PERFEVTSEL0 0x3c0 #define NHM_UNC_UNCORE_PMC0 0x3b0 +/* SNB-EP Box level control */ +#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) +#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) +#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8) +#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16) +#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ + SNBEP_PMON_BOX_CTL_RST_CTRS | \ + SNBEP_PMON_BOX_CTL_FRZ_EN) +/* SNB-EP event control */ +#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff +#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 +#define SNBEP_PMON_CTL_RST (1 << 17) +#define SNBEP_PMON_CTL_EDGE_DET (1 << 18) +#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) /* only for QPI */ +#define SNBEP_PMON_CTL_EN (1 << 22) +#define SNBEP_PMON_CTL_INVERT (1 << 23) +#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 +#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_UMASK_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_INVERT | \ + SNBEP_PMON_CTL_TRESH_MASK) + +/* SNB-EP Ubox event control */ +#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000 +#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_UMASK_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_INVERT | \ + SNBEP_U_MSR_PMON_CTL_TRESH_MASK) + +/* SNB-EP PCU event control */ +#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000 +#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000 +#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30) +#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31) +#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_INVERT | \ + SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) + +/* SNB-EP pci control register */ +#define SNBEP_PCI_PMON_BOX_CTL 0xf4 +#define SNBEP_PCI_PMON_CTL0 0xd8 +/* SNB-EP pci counter register */ +#define SNBEP_PCI_PMON_CTR0 0xa0 + +/* SNB-EP home agent register */ +#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40 +#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44 +#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48 +/* SNB-EP memory controller register */ +#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0 +#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0 +/* SNB-EP QPI register */ +#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228 +#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c +#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238 +#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c + +/* SNB-EP Ubox register */ +#define SNBEP_U_MSR_PMON_CTR0 0xc16 +#define SNBEP_U_MSR_PMON_CTL0 0xc10 + +#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08 +#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09 + +/* SNB-EP Cbo register */ +#define SNBEP_C0_MSR_PMON_CTR0 0xd16 +#define SNBEP_C0_MSR_PMON_CTL0 0xd10 +#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 +#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 +#define SNBEP_CBO_MSR_OFFSET 0x20 + +/* SNB-EP PCU register */ +#define SNBEP_PCU_MSR_PMON_CTR0 0xc36 +#define SNBEP_PCU_MSR_PMON_CTL0 0xc30 +#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34 +#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24 +#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc +#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd struct intel_uncore_ops; struct intel_uncore_pmu; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab741b0d0074..5f187026b812 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2755,6 +2755,17 @@ #define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27 #define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e #define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f +#define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46 +#define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0 +#define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1 +#define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4 +#define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5 +#define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c41 +#define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c42 +#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c43 +#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c44 +#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45 +#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 -- GitLab From 46010ab2607aed9484816a8f1679c2ec3c8e7dcf Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 15 Jun 2012 14:31:38 +0800 Subject: [PATCH 1838/6849] perf/tool: Use data struct for arg passing in event parse function Moving all the bison arguments into the structure. In upcomming patches we are going to: - add more arguments - reuse the grammer for term parsing so it's more clear to pack/separate related arguments. Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-10-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events.c | 16 ++++++----- tools/perf/util/parse-events.h | 8 ++++-- tools/perf/util/parse-events.y | 52 +++++++++++++++++++++++----------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 05dbc8b3c767..c71b29ad26ec 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -26,7 +26,7 @@ struct event_symbol { #ifdef PARSER_DEBUG extern int parse_events_debug; #endif -int parse_events_parse(struct list_head *list, int *idx); +int parse_events_parse(void *data); #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x @@ -789,25 +789,27 @@ int parse_events_modifier(struct list_head *list, char *str) int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) { - LIST_HEAD(list); - LIST_HEAD(list_tmp); + struct parse_events_data__events data = { + .list = LIST_HEAD_INIT(data.list), + .idx = evlist->nr_entries, + }; YY_BUFFER_STATE buffer; - int ret, idx = evlist->nr_entries; + int ret; buffer = parse_events__scan_string(str); #ifdef PARSER_DEBUG parse_events_debug = 1; #endif - ret = parse_events_parse(&list, &idx); + ret = parse_events_parse(&data); parse_events__flush_buffer(buffer); parse_events__delete_buffer(buffer); parse_events_lex_destroy(); if (!ret) { - int entries = idx - evlist->nr_entries; - perf_evlist__splice_list_tail(evlist, &list, entries); + int entries = data.idx - evlist->nr_entries; + perf_evlist__splice_list_tail(evlist, &data.list, entries); return 0; } diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 8cac57ab4ee6..dc3c83a0ab8a 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -63,6 +63,11 @@ struct parse_events__term { struct list_head list; }; +struct parse_events_data__events { + struct list_head list; + int idx; +}; + int parse_events__is_hardcoded_term(struct parse_events__term *term); int parse_events__term_num(struct parse_events__term **_term, int type_term, char *config, long num); @@ -83,8 +88,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx, char *pmu , struct list_head *head_config); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); -void parse_events_error(struct list_head *list_all, - int *idx, char const *msg); +void parse_events_error(void *data, char const *msg); int parse_events__test(void); void print_events(const char *event_glob); diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 362cc59332ae..e533bf72ba9c 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -1,7 +1,6 @@ %name-prefix "parse_events_" -%parse-param {struct list_head *list_all} -%parse-param {int *idx} +%parse-param {void *_data} %{ @@ -64,18 +63,22 @@ events ',' event | event event: event_def PE_MODIFIER_EVENT { + struct parse_events_data__events *data = _data; + /* * Apply modifier on all events added by single event definition * (there could be more events added for multiple tracepoint * definitions via '*?'. */ ABORT_ON(parse_events_modifier($1, $2)); - parse_events_update_lists($1, list_all); + parse_events_update_lists($1, &data->list); } | event_def { - parse_events_update_lists($1, list_all); + struct parse_events_data__events *data = _data; + + parse_events_update_lists($1, &data->list); } event_def: event_pmu | @@ -89,9 +92,10 @@ event_def: event_pmu | event_pmu: PE_NAME '/' event_config '/' { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_pmu(&list, idx, $1, $3)); + ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3)); parse_events__free_terms($3); $$ = list; } @@ -99,91 +103,106 @@ PE_NAME '/' event_config '/' event_legacy_symbol: PE_VALUE_SYM '/' event_config '/' { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; int type = $1 >> 16; int config = $1 & 255; - ABORT_ON(parse_events_add_numeric(&list, idx, type, config, $3)); + ABORT_ON(parse_events_add_numeric(&list, &data->idx, + type, config, $3)); parse_events__free_terms($3); $$ = list; } | PE_VALUE_SYM sep_slash_dc { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; int type = $1 >> 16; int config = $1 & 255; - ABORT_ON(parse_events_add_numeric(&list, idx, type, config, NULL)); + ABORT_ON(parse_events_add_numeric(&list, &data->idx, + type, config, NULL)); $$ = list; } event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, $5)); + ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5)); $$ = list; } | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, NULL)); + ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL)); $$ = list; } | PE_NAME_CACHE_TYPE { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_cache(&list, idx, $1, NULL, NULL)); + ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL)); $$ = list; } event_legacy_mem: PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, $4)); + ABORT_ON(parse_events_add_breakpoint(&list, &data->idx, + (void *) $2, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE sep_dc { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, NULL)); + ABORT_ON(parse_events_add_breakpoint(&list, &data->idx, + (void *) $2, NULL)); $$ = list; } event_legacy_tracepoint: PE_NAME ':' PE_NAME { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_tracepoint(&list, idx, $1, $3)); + ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3)); $$ = list; } event_legacy_numeric: PE_VALUE ':' PE_VALUE { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_numeric(&list, idx, $1, $3, NULL)); + ABORT_ON(parse_events_add_numeric(&list, &data->idx, $1, $3, NULL)); $$ = list; } event_legacy_raw: PE_RAW { + struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_numeric(&list, idx, PERF_TYPE_RAW, $1, NULL)); + ABORT_ON(parse_events_add_numeric(&list, &data->idx, + PERF_TYPE_RAW, $1, NULL)); $$ = list; } @@ -267,8 +286,7 @@ sep_slash_dc: '/' | ':' | %% -void parse_events_error(struct list_head *list_all __used, - int *idx __used, +void parse_events_error(void *data __used, char const *msg __used) { } -- GitLab From ac20de6fff445d6deb0c44c25946d198f79f2f00 Mon Sep 17 00:00:00 2001 From: Zheng Yan Date: Fri, 15 Jun 2012 14:31:39 +0800 Subject: [PATCH 1839/6849] perf/tool: Make the event parser re-entrant Make the event parser reentrant by creating separate scanner for each parsing. The scanner is passed to the bison as and argument to the lexer. Signed-off-by: Zheng Yan [ Cleaned up the patch. ] Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-11-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events.c | 35 ++++++---- tools/perf/util/parse-events.h | 2 +- tools/perf/util/parse-events.l | 116 +++++++++++++++++++-------------- tools/perf/util/parse-events.y | 9 ++- 4 files changed, 98 insertions(+), 64 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index c71b29ad26ec..ca8665e19c0d 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -11,6 +11,7 @@ #include "cache.h" #include "header.h" #include "debugfs.h" +#include "parse-events-bison.h" #include "parse-events-flex.h" #include "pmu.h" @@ -26,7 +27,7 @@ struct event_symbol { #ifdef PARSER_DEBUG extern int parse_events_debug; #endif -int parse_events_parse(void *data); +int parse_events_parse(void *data, void *scanner); #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x @@ -787,26 +788,38 @@ int parse_events_modifier(struct list_head *list, char *str) return 0; } -int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) +static int parse_events__scanner(const char *str, void *data) { - struct parse_events_data__events data = { - .list = LIST_HEAD_INIT(data.list), - .idx = evlist->nr_entries, - }; YY_BUFFER_STATE buffer; + void *scanner; int ret; - buffer = parse_events__scan_string(str); + ret = parse_events_lex_init(&scanner); + if (ret) + return ret; + + buffer = parse_events__scan_string(str, scanner); #ifdef PARSER_DEBUG parse_events_debug = 1; #endif - ret = parse_events_parse(&data); + ret = parse_events_parse(data, scanner); + + parse_events__flush_buffer(buffer, scanner); + parse_events__delete_buffer(buffer, scanner); + parse_events_lex_destroy(scanner); + return ret; +} - parse_events__flush_buffer(buffer); - parse_events__delete_buffer(buffer); - parse_events_lex_destroy(); +int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) +{ + struct parse_events_data__events data = { + .list = LIST_HEAD_INIT(data.list), + .idx = evlist->nr_entries, + }; + int ret; + ret = parse_events__scanner(str, &data); if (!ret) { int entries = data.idx - evlist->nr_entries; perf_evlist__splice_list_tail(evlist, &data.list, entries); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index dc3c83a0ab8a..fa2b19b862e2 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -88,7 +88,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx, char *pmu , struct list_head *head_config); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); -void parse_events_error(void *data, char const *msg); +void parse_events_error(void *data, void *scanner, char const *msg); int parse_events__test(void); void print_events(const char *event_glob); diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 618a8e788399..329794eea711 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -1,4 +1,6 @@ +%option reentrant +%option bison-bridge %option prefix="parse_events_" %option stack @@ -8,7 +10,10 @@ #include "parse-events-bison.h" #include "parse-events.h" -static int __value(char *str, int base, int token) +char *parse_events_get_text(yyscan_t yyscanner); +YYSTYPE *parse_events_get_lval(yyscan_t yyscanner); + +static int __value(YYSTYPE *yylval, char *str, int base, int token) { long num; @@ -17,35 +22,48 @@ static int __value(char *str, int base, int token) if (errno) return PE_ERROR; - parse_events_lval.num = num; + yylval->num = num; return token; } -static int value(int base) +static int value(yyscan_t scanner, int base) { - return __value(parse_events_text, base, PE_VALUE); + YYSTYPE *yylval = parse_events_get_lval(scanner); + char *text = parse_events_get_text(scanner); + + return __value(yylval, text, base, PE_VALUE); } -static int raw(void) +static int raw(yyscan_t scanner) { - return __value(parse_events_text + 1, 16, PE_RAW); + YYSTYPE *yylval = parse_events_get_lval(scanner); + char *text = parse_events_get_text(scanner); + + return __value(yylval, text + 1, 16, PE_RAW); } -static int str(int token) +static int str(yyscan_t scanner, int token) { - parse_events_lval.str = strdup(parse_events_text); + YYSTYPE *yylval = parse_events_get_lval(scanner); + char *text = parse_events_get_text(scanner); + + yylval->str = strdup(text); return token; } -static int sym(int type, int config) +static int sym(yyscan_t scanner, int type, int config) { - parse_events_lval.num = (type << 16) + config; + YYSTYPE *yylval = parse_events_get_lval(scanner); + + yylval->num = (type << 16) + config; return PE_VALUE_SYM; } -static int term(int type) +static int term(yyscan_t scanner, int type) { - parse_events_lval.num = type; + YYSTYPE *yylval = parse_events_get_lval(scanner); + + yylval->num = type; return PE_TERM; } @@ -61,25 +79,25 @@ modifier_event [ukhpGH]{1,8} modifier_bp [rwx] %% -cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } -stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } -stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } -instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } -cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } -cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } -branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } -branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } -bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } -ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } -cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } -task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } -page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } -minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } -major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } -context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } -cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } -alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } -emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } +cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } +stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } +stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } +instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } +cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } +cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } +branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } +branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } +bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } +ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } +cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } +task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } +page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } +minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } +major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } +context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } +cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } +alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } +emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } L1-dcache|l1-d|l1d|L1-data | L1-icache|l1-i|l1i|L1-instruction | @@ -87,14 +105,14 @@ LLC|L2 | dTLB|d-tlb|Data-TLB | iTLB|i-tlb|Instruction-TLB | branch|branches|bpu|btb|bpc | -node { return str(PE_NAME_CACHE_TYPE); } +node { return str(yyscanner, PE_NAME_CACHE_TYPE); } load|loads|read | store|stores|write | prefetch|prefetches | speculative-read|speculative-load | refs|Reference|ops|access | -misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } +misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); } /* * These are event config hardcoded term names to be specified @@ -102,20 +120,20 @@ misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } * so we can put them here directly. In case the we have a conflict * in future, this needs to go into '//' condition block. */ -config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } -config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } -config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } -name { return term(PARSE_EVENTS__TERM_TYPE_NAME); } -period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } -branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } +config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); } +config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); } +config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); } +name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); } +period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } +branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } mem: { BEGIN(mem); return PE_PREFIX_MEM; } -r{num_raw_hex} { return raw(); } -{num_dec} { return value(10); } -{num_hex} { return value(16); } +r{num_raw_hex} { return raw(yyscanner); } +{num_dec} { return value(yyscanner, 10); } +{num_hex} { return value(yyscanner, 16); } -{modifier_event} { return str(PE_MODIFIER_EVENT); } -{name} { return str(PE_NAME); } +{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } +{name} { return str(yyscanner, PE_NAME); } "/" { return '/'; } - { return '-'; } , { return ','; } @@ -123,17 +141,17 @@ r{num_raw_hex} { return raw(); } = { return '='; } { -{modifier_bp} { return str(PE_MODIFIER_BP); } +{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } : { return ':'; } -{num_dec} { return value(10); } -{num_hex} { return value(16); } +{num_dec} { return value(yyscanner, 10); } +{num_hex} { return value(yyscanner, 16); } /* * We need to separate 'mem:' scanner part, in order to get specific * modifier bits parsed out. Otherwise we would need to handle PE_NAME * and we'd need to parse it manually. During the escape from * state we need to put the escaping char back, so we dont miss it. */ -. { unput(*parse_events_text); BEGIN(INITIAL); } +. { unput(*yytext); BEGIN(INITIAL); } /* * We destroy the scanner after reaching EOF, * but anyway just to be sure get back to INIT state. @@ -143,7 +161,7 @@ r{num_raw_hex} { return raw(); } %% -int parse_events_wrap(void) +int parse_events_wrap(void *scanner __used) { return 1; } diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index e533bf72ba9c..2a93d5c8ccda 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -1,6 +1,8 @@ - +%pure-parser %name-prefix "parse_events_" %parse-param {void *_data} +%parse-param {void *scanner} +%lex-param {void* scanner} %{ @@ -11,8 +13,9 @@ #include "types.h" #include "util.h" #include "parse-events.h" +#include "parse-events-bison.h" -extern int parse_events_lex (void); +extern int parse_events_lex (YYSTYPE* lvalp, void* scanner); #define ABORT_ON(val) \ do { \ @@ -286,7 +289,7 @@ sep_slash_dc: '/' | ':' | %% -void parse_events_error(void *data __used, +void parse_events_error(void *data __used, void *scanner __used, char const *msg __used) { } -- GitLab From 90e2b22dee908c13df256140a0d6527e3e8ea3f4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 15 Jun 2012 14:31:40 +0800 Subject: [PATCH 1840/6849] perf/tool: Add support to reuse event grammar to parse out terms We want to reuse the event grammar for parsing aliased terms. The obvious reason is we dont need to add new code when there's already support for this in event grammar. Doing this by adding terms and event start entries into event parse grammar. The grammar forks on the begining based on the starting token, which is supplied via bison interface into the lexer. The lexer then returns the starting token as the first token, thus making the grammar switch accordingly. Currently 2 starting tokens/grammars are supported: PE_START_TERMS, PE_START_EVENTS The PE_START_TERMS related grammar uses 'event_config' part of the grammar for term parsing. Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-12-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events.c | 28 +++++++++++++++++++++++++--- tools/perf/util/parse-events.h | 5 +++++ tools/perf/util/parse-events.l | 13 +++++++++++++ tools/perf/util/parse-events.y | 12 ++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index ca8665e19c0d..d002170adb3f 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -12,6 +12,7 @@ #include "header.h" #include "debugfs.h" #include "parse-events-bison.h" +#define YY_EXTRA_TYPE int #include "parse-events-flex.h" #include "pmu.h" @@ -788,13 +789,13 @@ int parse_events_modifier(struct list_head *list, char *str) return 0; } -static int parse_events__scanner(const char *str, void *data) +static int parse_events__scanner(const char *str, void *data, int start_token) { YY_BUFFER_STATE buffer; void *scanner; int ret; - ret = parse_events_lex_init(&scanner); + ret = parse_events_lex_init_extra(start_token, &scanner); if (ret) return ret; @@ -811,6 +812,27 @@ static int parse_events__scanner(const char *str, void *data) return ret; } +/* + * parse event config string, return a list of event terms. + */ +int parse_events_terms(struct list_head *terms, const char *str) +{ + struct parse_events_data__terms data = { + .terms = NULL, + }; + int ret; + + ret = parse_events__scanner(str, &data, PE_START_TERMS); + if (!ret) { + list_splice(data.terms, terms); + free(data.terms); + return 0; + } + + parse_events__free_terms(data.terms); + return ret; +} + int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) { struct parse_events_data__events data = { @@ -819,7 +841,7 @@ int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) }; int ret; - ret = parse_events__scanner(str, &data); + ret = parse_events__scanner(str, &data, PE_START_EVENTS); if (!ret) { int entries = data.idx - evlist->nr_entries; perf_evlist__splice_list_tail(evlist, &data.list, entries); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index fa2b19b862e2..9896edadbe62 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -33,6 +33,7 @@ extern int parse_events_option(const struct option *opt, const char *str, int unset); extern int parse_events(struct perf_evlist *evlist, const char *str, int unset); +extern int parse_events_terms(struct list_head *terms, const char *str); extern int parse_filter(const struct option *opt, const char *str, int unset); #define EVENTS_HELP_MAX (128*1024) @@ -68,6 +69,10 @@ struct parse_events_data__events { int idx; }; +struct parse_events_data__terms { + struct list_head *terms; +}; + int parse_events__is_hardcoded_term(struct parse_events__term *term); int parse_events__term_num(struct parse_events__term **_term, int type_term, char *config, long num); diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 329794eea711..488362e14133 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -79,6 +79,19 @@ modifier_event [ukhpGH]{1,8} modifier_bp [rwx] %% + +%{ + { + int start_token; + + start_token = (int) parse_events_get_extra(yyscanner); + if (start_token) { + parse_events_set_extra(NULL, yyscanner); + return start_token; + } + } +%} + cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 2a93d5c8ccda..9525c455d27f 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -25,6 +25,7 @@ do { \ %} +%token PE_START_EVENTS PE_START_TERMS %token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM %token PE_NAME %token PE_MODIFIER_EVENT PE_MODIFIER_BP @@ -60,6 +61,11 @@ do { \ } %% +start: +PE_START_EVENTS events +| +PE_START_TERMS terms + events: events ',' event | event @@ -209,6 +215,12 @@ PE_RAW $$ = list; } +terms: event_config +{ + struct parse_events_data__terms *data = _data; + data->terms = $1; +} + event_config: event_config ',' event_term { -- GitLab From a6146d5040cce560f700221158d77dd335eed332 Mon Sep 17 00:00:00 2001 From: Zheng Yan Date: Fri, 15 Jun 2012 14:31:41 +0800 Subject: [PATCH 1841/6849] perf/tool: Add PMU event alias support Add support to specify alias term within the event description. The definition of pmu event alias is located at: ${sysfs_mount}/bus/event_source/devices/${pmu}/events/ Each file in the 'events' directory defines a event alias. Its contents are like: config=1,config1=2 Using pmu event alias, an event can be now specified like: uncore/CLOCKTICKS/ or uncore/event=CLOCKTICKS/ Signed-off-by: Zheng Yan [ Cleaned it up. ] Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1339741902-8449-13-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events.c | 10 ++ tools/perf/util/parse-events.h | 2 + tools/perf/util/pmu.c | 166 +++++++++++++++++++++++++++++++++ tools/perf/util/pmu.h | 11 ++- 4 files changed, 188 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d002170adb3f..3339424cc421 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -701,6 +701,9 @@ int parse_events_add_pmu(struct list_head **list, int *idx, memset(&attr, 0, sizeof(attr)); + if (perf_pmu__check_alias(pmu, head_config)) + return -EINVAL; + /* * Configure hardcoded terms first, no need to check * return value when called with fail == 0 ;) @@ -1143,6 +1146,13 @@ int parse_events__term_str(struct parse_events__term **term, config, str, 0); } +int parse_events__term_clone(struct parse_events__term **new, + struct parse_events__term *term) +{ + return new_term(new, term->type_val, term->type_term, term->config, + term->val.str, term->val.num); +} + void parse_events__free_terms(struct list_head *terms) { struct parse_events__term *term, *h; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 9896edadbe62..a2c71684f6a4 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -78,6 +78,8 @@ int parse_events__term_num(struct parse_events__term **_term, int type_term, char *config, long num); int parse_events__term_str(struct parse_events__term **_term, int type_term, char *config, char *str); +int parse_events__term_clone(struct parse_events__term **new, + struct parse_events__term *term); void parse_events__free_terms(struct list_head *terms); int parse_events_modifier(struct list_head *list, char *str); int parse_events_add_tracepoint(struct list_head **list, int *idx, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index a119a5371699..74d0948ec368 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -80,6 +80,114 @@ static int pmu_format(char *name, struct list_head *format) return 0; } +static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file) +{ + struct perf_pmu__alias *alias; + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + alias = malloc(sizeof(*alias)); + if (!alias) + return -ENOMEM; + + INIT_LIST_HEAD(&alias->terms); + ret = parse_events_terms(&alias->terms, buf); + if (ret) { + free(alias); + return ret; + } + + alias->name = strdup(name); + list_add_tail(&alias->list, list); + return 0; +} + +/* + * Process all the sysfs attributes located under the directory + * specified in 'dir' parameter. + */ +static int pmu_aliases_parse(char *dir, struct list_head *head) +{ + struct dirent *evt_ent; + DIR *event_dir; + int ret = 0; + + event_dir = opendir(dir); + if (!event_dir) + return -EINVAL; + + while (!ret && (evt_ent = readdir(event_dir))) { + char path[PATH_MAX]; + char *name = evt_ent->d_name; + FILE *file; + + if (!strcmp(name, ".") || !strcmp(name, "..")) + continue; + + snprintf(path, PATH_MAX, "%s/%s", dir, name); + + ret = -EINVAL; + file = fopen(path, "r"); + if (!file) + break; + ret = perf_pmu__new_alias(head, name, file); + fclose(file); + } + + closedir(event_dir); + return ret; +} + +/* + * Reading the pmu event aliases definition, which should be located at: + * /sys/bus/event_source/devices//events as sysfs group attributes. + */ +static int pmu_aliases(char *name, struct list_head *head) +{ + struct stat st; + char path[PATH_MAX]; + const char *sysfs; + + sysfs = sysfs_find_mountpoint(); + if (!sysfs) + return -1; + + snprintf(path, PATH_MAX, + "%s/bus/event_source/devices/%s/events", sysfs, name); + + if (stat(path, &st) < 0) + return -1; + + if (pmu_aliases_parse(path, head)) + return -1; + + return 0; +} + +static int pmu_alias_terms(struct perf_pmu__alias *alias, + struct list_head *terms) +{ + struct parse_events__term *term, *clone; + LIST_HEAD(list); + int ret; + + list_for_each_entry(term, &alias->terms, list) { + ret = parse_events__term_clone(&clone, term); + if (ret) { + parse_events__free_terms(&list); + return ret; + } + list_add_tail(&clone->list, &list); + } + list_splice(&list, terms); + return 0; +} + /* * Reading/parsing the default pmu type value, which should be * located at: @@ -118,6 +226,7 @@ static struct perf_pmu *pmu_lookup(char *name) { struct perf_pmu *pmu; LIST_HEAD(format); + LIST_HEAD(aliases); __u32 type; /* @@ -135,8 +244,12 @@ static struct perf_pmu *pmu_lookup(char *name) if (!pmu) return NULL; + pmu_aliases(name, &aliases); + INIT_LIST_HEAD(&pmu->format); + INIT_LIST_HEAD(&pmu->aliases); list_splice(&format, &pmu->format); + list_splice(&aliases, &pmu->aliases); pmu->name = strdup(name); pmu->type = type; return pmu; @@ -279,6 +392,59 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, return pmu_config(&pmu->format, attr, head_terms); } +static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu, + struct parse_events__term *term) +{ + struct perf_pmu__alias *alias; + char *name; + + if (parse_events__is_hardcoded_term(term)) + return NULL; + + if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { + if (term->val.num != 1) + return NULL; + if (pmu_find_format(&pmu->format, term->config)) + return NULL; + name = term->config; + } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { + if (strcasecmp(term->config, "event")) + return NULL; + name = term->val.str; + } else { + return NULL; + } + + list_for_each_entry(alias, &pmu->aliases, list) { + if (!strcasecmp(alias->name, name)) + return alias; + } + return NULL; +} + +/* + * Find alias in the terms list and replace it with the terms + * defined for the alias + */ +int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms) +{ + struct parse_events__term *term, *h; + struct perf_pmu__alias *alias; + int ret; + + list_for_each_entry_safe(term, h, head_terms, list) { + alias = pmu_find_alias(pmu, term); + if (!alias) + continue; + ret = pmu_alias_terms(alias, &term->list); + if (ret) + return ret; + list_del(&term->list); + free(term); + } + return 0; +} + int perf_pmu__new_format(struct list_head *list, char *name, int config, unsigned long *bits) { diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 68c0db965e1f..535f2c5258ab 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -19,17 +19,26 @@ struct perf_pmu__format { struct list_head list; }; +struct perf_pmu__alias { + char *name; + struct list_head terms; + struct list_head list; +}; + struct perf_pmu { char *name; __u32 type; struct list_head format; + struct list_head aliases; struct list_head list; }; struct perf_pmu *perf_pmu__find(char *name); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms); - +int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms); +struct list_head *perf_pmu__alias(struct perf_pmu *pmu, + struct list_head *head_terms); int perf_pmu_wrap(void); void perf_pmu_error(struct list_head *list, char *name, char const *msg); -- GitLab From 4429392e1484319df4209d41a98244c76d0caf56 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 15 Jun 2012 14:31:42 +0800 Subject: [PATCH 1842/6849] perf/tool: Add automated test for pure terms parsing Adding automated test for parsing terms out of the event grammar. Also slightly changing current event parsing test functions to follow up more generic namespace. Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-14-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events-test.c | 122 ++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 76b98e2a587d..af1039cdb853 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -430,6 +430,49 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) return 0; } +static int test__checkterms_simple(struct list_head *terms) +{ + struct parse_events__term *term; + + /* config=10 */ + term = list_entry(terms->next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 10); + TEST_ASSERT_VAL("wrong config", !term->config); + + /* config1 */ + term = list_entry(term->list.next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 1); + TEST_ASSERT_VAL("wrong config", !term->config); + + /* config2=3 */ + term = list_entry(term->list.next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 3); + TEST_ASSERT_VAL("wrong config", !term->config); + + /* umask=1*/ + term = list_entry(term->list.next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_USER); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 1); + TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); + + return 0; +} + struct test__event_st { const char *name; __u32 type; @@ -559,7 +602,23 @@ static struct test__event_st test__events_pmu[] = { #define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \ sizeof(struct test__event_st)) -static int test(struct test__event_st *e) +struct test__term { + const char *str; + __u32 type; + int (*check)(struct list_head *terms); +}; + +static struct test__term test__terms[] = { + [0] = { + .str = "config=10,config1,config2=3,umask=1", + .check = test__checkterms_simple, + }, +}; + +#define TEST__TERMS_CNT (sizeof(test__terms) / \ + sizeof(struct test__term)) + +static int test_event(struct test__event_st *e) { struct perf_evlist *evlist; int ret; @@ -590,7 +649,48 @@ static int test_events(struct test__event_st *events, unsigned cnt) struct test__event_st *e = &events[i]; pr_debug("running test %d '%s'\n", i, e->name); - ret = test(e); + ret = test_event(e); + if (ret) + break; + } + + return ret; +} + +static int test_term(struct test__term *t) +{ + struct list_head *terms; + int ret; + + terms = malloc(sizeof(*terms)); + if (!terms) + return -ENOMEM; + + INIT_LIST_HEAD(terms); + + ret = parse_events_terms(terms, t->str); + if (ret) { + pr_debug("failed to parse terms '%s', err %d\n", + t->str , ret); + return ret; + } + + ret = t->check(terms); + parse_events__free_terms(terms); + + return ret; +} + +static int test_terms(struct test__term *terms, unsigned cnt) +{ + int ret = 0; + unsigned i; + + for (i = 0; i < cnt; i++) { + struct test__term *t = &terms[i]; + + pr_debug("running test %d '%s'\n", i, t->str); + ret = test_term(t); if (ret) break; } @@ -617,9 +717,21 @@ int parse_events__test(void) { int ret; - ret = test_events(test__events, TEST__EVENTS_CNT); - if (!ret && test_pmu()) - ret = test_events(test__events_pmu, TEST__EVENTS_PMU_CNT); + do { + ret = test_events(test__events, TEST__EVENTS_CNT); + if (ret) + break; + + if (test_pmu()) { + ret = test_events(test__events_pmu, + TEST__EVENTS_PMU_CNT); + if (ret) + break; + } + + ret = test_terms(test__terms, TEST__TERMS_CNT); + + } while (0); return ret; } -- GitLab From 10aa5a35e34fb00a2dd814447199f08756eb307b Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 18 Jun 2012 11:27:04 +0100 Subject: [PATCH 1843/6849] SPI: fix over-eager devm_xxx() conversion 1a77b127ae (OMAP : SPI : use devm_* functions) converted the SPI device controller state to use devm_kzalloc(). Unfortunately, this is used against an unbound struct device, which results in the following when the device is bound to its driver: ------------[ cut here ]------------ WARNING: at /home/rmk/git/linux-rmk/drivers/base/dd.c:257 driver_probe_device+0x78/0x21c() Modules linked in: Backtrace: [] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c) r7:00000000 r6:c01ff28c r5:c040050c r4:00000101 [] (dump_stack+0x0/0x1c) from [] (warn_slowpath_common+0x58/0x70) [] (warn_slowpath_common+0x0/0x70) from [] (warn_slowpath_null+0x24/0x2c) [] (warn_slowpath_null+0x0/0x2c) from [] (driver_probe_device+0x78/0x21c) [] (driver_probe_device+0x0/0x21c) from [] (__driver_attach+0x6c/0x90) [] (__driver_attach+0x0/0x90) from [] (bus_for_each_dev+0x58/0x98) [] (bus_for_each_dev+0x0/0x98) from [] (driver_attach+0x20/0x28) [] (driver_attach+0x0/0x28) from [] (bus_add_driver+0xb4/0x230) [] (bus_add_driver+0x0/0x230) from [] (driver_register+0xac/0x138) [] (driver_register+0x0/0x138) from [] (spi_register_driver+0x4c/0x60) [] (spi_register_driver+0x0/0x60) from [] (ks8851_init+0x14/0x1c) [] (ks8851_init+0x0/0x1c) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x128/0x210) [] (kernel_init+0x0/0x210) from [] (do_exit+0x0/0x72c) ---[ end trace 4dcda79f5e89dd84 ]--- ks8851 spi1.0: message enable is 0 ks8851 spi1.0: eth0: revision 0, MAC 08:00:28:01:4d:c6, IRQ 194, has EEPROM Fix this by partially reverting the original commit. Signed-off-by: Russell King --- drivers/spi/spi-omap2-mcspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 46ef5fe51db5..0c73dd4f43a0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -801,7 +801,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) mcspi_dma = &mcspi->dma_channels[spi->chip_select]; if (!cs) { - cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); + cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; @@ -842,6 +842,7 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) cs = spi->controller_state; list_del(&cs->node); + kfree(cs); } if (spi->chip_select < spi->master->num_chipselect) { -- GitLab From 1cfb7271076a265b7c2cbbf9cf5c2ae060a24385 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Jun 2012 12:08:23 +0300 Subject: [PATCH 1844/6849] UBIFS: fix assertion The asserts here never check anything because it uses '|' instead of '&'. Now if the flags are not set it prints a warning a a stack trace. Signed-off-by: Dan Carpenter Signed-off-by: Artem Bityutskiy --- fs/ubifs/find.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 2559d174e004..28ec13af28d9 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c @@ -939,8 +939,8 @@ static int find_dirtiest_idx_leb(struct ubifs_info *c) } dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty, lp->free, lp->flags); - ubifs_assert(lp->flags | LPROPS_TAKEN); - ubifs_assert(lp->flags | LPROPS_INDEX); + ubifs_assert(lp->flags & LPROPS_TAKEN); + ubifs_assert(lp->flags & LPROPS_INDEX); return lnum; } -- GitLab From 70c276a6abdb1a466a9026da631c396fee2984bd Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 25 May 2012 18:06:33 -0300 Subject: [PATCH 1845/6849] [media] Revert "[media] media: mx2_camera: Fix mbus format handling" This reverts commit d509835e32bd761a2b7b446034a273da568e5573. That commit breaks support for the generic pass-through mode in the driver for formats, not natively supported by it. Besides due to a merge conflict it also breaks driver compilation: drivers/media/video/mx2_camera.c: In function 'mx2_camera_set_bus_param': drivers/media/video/mx2_camera.c:937: error: 'pixfmt' undeclared (first use in this function) drivers/media/video/mx2_camera.c:937: error: (Each undeclared identifier is reported only once drivers/media/video/mx2_camera.c:937: error: for each function it appears in.) Signed-off-by: Guennadi Liakhovetski Cc: Javier Martin Signed-off-by: Mauro Carvalho Chehab --- arch/arm/plat-mxc/include/mach/mx2_cam.h | 2 + drivers/media/video/mx2_camera.c | 52 +++--------------------- 2 files changed, 7 insertions(+), 47 deletions(-) diff --git a/arch/arm/plat-mxc/include/mach/mx2_cam.h b/arch/arm/plat-mxc/include/mach/mx2_cam.h index 7ded6f1f74bc..3c080a32dbf5 100644 --- a/arch/arm/plat-mxc/include/mach/mx2_cam.h +++ b/arch/arm/plat-mxc/include/mach/mx2_cam.h @@ -23,6 +23,7 @@ #ifndef __MACH_MX2_CAM_H_ #define __MACH_MX2_CAM_H_ +#define MX2_CAMERA_SWAP16 (1 << 0) #define MX2_CAMERA_EXT_VSYNC (1 << 1) #define MX2_CAMERA_CCIR (1 << 2) #define MX2_CAMERA_CCIR_INTERLACE (1 << 3) @@ -30,6 +31,7 @@ #define MX2_CAMERA_GATED_CLOCK (1 << 5) #define MX2_CAMERA_INV_DATA (1 << 6) #define MX2_CAMERA_PCLK_SAMPLE_RISING (1 << 7) +#define MX2_CAMERA_PACK_DIR_MSB (1 << 8) /** * struct mx2_camera_platform_data - optional platform data for mx2_camera diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index ded26b7286fa..41f9a254b245 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -345,19 +345,6 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { PRP_INTR_CH2OVF, } }, - { - .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, - .out_fmt = V4L2_PIX_FMT_YUV420, - .cfg = { - .channel = 2, - .in_fmt = PRP_CNTL_DATA_IN_YUV422, - .out_fmt = PRP_CNTL_CH2_OUT_YUV420, - .src_pixel = 0x22000888, /* YUV422 (YUYV) */ - .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR | - PRP_INTR_CH2FC | PRP_INTR_LBOVF | - PRP_INTR_CH2OVF, - } - }, }; static struct mx2_fmt_cfg *mx27_emma_prp_get_format( @@ -984,7 +971,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; - const struct soc_camera_format_xlate *xlate; unsigned long common_flags; int ret; int bytesperline; @@ -1029,31 +1015,14 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) return ret; } - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(icd->parent, "Format %x not found\n", pixfmt); - return -EINVAL; - } - - if (xlate->code == V4L2_MBUS_FMT_YUYV8_2X8) { - csicr1 |= CSICR1_PACK_DIR; - csicr1 &= ~CSICR1_SWAP16_EN; - dev_dbg(icd->parent, "already yuyv format, don't convert\n"); - } else if (xlate->code == V4L2_MBUS_FMT_UYVY8_2X8) { - csicr1 &= ~CSICR1_PACK_DIR; - csicr1 |= CSICR1_SWAP16_EN; - dev_dbg(icd->parent, "convert uyvy mbus format into yuyv\n"); - } else { - dev_warn(icd->parent, "mbus format not supported\n"); - return -EINVAL; - } - if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_SOF_POL; if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_HSYNC_POL; + if (pcdev->platform_flags & MX2_CAMERA_SWAP16) + csicr1 |= CSICR1_SWAP16_EN; if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC) csicr1 |= CSICR1_EXT_VSYNC; if (pcdev->platform_flags & MX2_CAMERA_CCIR) @@ -1064,6 +1033,8 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) csicr1 |= CSICR1_GCLK_MODE; if (pcdev->platform_flags & MX2_CAMERA_INV_DATA) csicr1 |= CSICR1_INV_DATA; + if (pcdev->platform_flags & MX2_CAMERA_PACK_DIR_MSB) + csicr1 |= CSICR1_PACK_DIR; pcdev->csicr1 = csicr1; @@ -1138,8 +1109,7 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, return 0; } - if (code == V4L2_MBUS_FMT_YUYV8_2X8 || - code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == V4L2_MBUS_FMT_YUYV8_2X8) { formats++; if (xlate) { /* @@ -1155,18 +1125,6 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, } } - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { - formats++; - if (xlate) { - xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8); - xlate->code = code; - dev_dbg(dev, "Providing host format %s for sensor code %d\n", - xlate->host_fmt->name, code); - xlate++; - } - } - /* Generic pass-trough */ formats++; if (xlate) { -- GitLab From 1ccd7a2a33f2b47e46c51f4501e9623a51d28090 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:13 +0200 Subject: [PATCH 1846/6849] HID: uhid: introduce user-space I/O driver support for HID This adds a dummy driver that will support user-space I/O drivers for the HID subsystem. This allows to write transport-level drivers like USB-HID and Bluetooth-HID in user-space. Low-Energy Bluetooth needs this to feed HID data that is parsed in user-space back into the kernel. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 21 +++++++++++ drivers/hid/Makefile | 1 + drivers/hid/uhid.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 drivers/hid/uhid.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e9c68fedfcff..8cca0af2dbd1 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -59,6 +59,27 @@ config HIDRAW If unsure, say Y. +config UHID + tristate "User-space I/O driver support for HID subsystem" + depends on HID + default n + ---help--- + Say Y here if you want to provide HID I/O Drivers from user-space. + This allows to write I/O drivers in user-space and feed the data from + the device into the kernel. The kernel parses the HID reports, loads the + corresponding HID Device Driver or provides input devices on top of your + user-space device. + + This driver cannot be used to parse HID-reports in user-space and write + special HID-drivers. You should use hidraw for that. + Instead, this driver allows to write the transport-layer driver in + user-space like USB-HID and Bluetooth-HID do in kernel-space. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called uhid. + source "drivers/hid/usbhid/Kconfig" menu "Special HID drivers" diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index ca6cc9f0485c..d7061928325e 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -8,6 +8,7 @@ ifdef CONFIG_DEBUG_FS endif obj-$(CONFIG_HID) += hid.o +obj-$(CONFIG_UHID) += uhid.o obj-$(CONFIG_HID_GENERIC) += hid-generic.o diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c new file mode 100644 index 000000000000..5b02d6cb0e60 --- /dev/null +++ b/drivers/hid/uhid.c @@ -0,0 +1,88 @@ +/* + * User-space I/O driver support for HID subsystem + * Copyright (c) 2012 David Herrmann + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UHID_NAME "uhid" + +static struct miscdevice uhid_misc; + +static int uhid_char_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int uhid_char_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static ssize_t uhid_char_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + return 0; +} + +static ssize_t uhid_char_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + return 0; +} + +static unsigned int uhid_char_poll(struct file *file, poll_table *wait) +{ + return 0; +} + +static const struct file_operations uhid_fops = { + .owner = THIS_MODULE, + .open = uhid_char_open, + .release = uhid_char_release, + .read = uhid_char_read, + .write = uhid_char_write, + .poll = uhid_char_poll, + .llseek = no_llseek, +}; + +static struct miscdevice uhid_misc = { + .fops = &uhid_fops, + .minor = MISC_DYNAMIC_MINOR, + .name = UHID_NAME, +}; + +static int __init uhid_init(void) +{ + return misc_register(&uhid_misc); +} + +static void __exit uhid_exit(void) +{ + misc_deregister(&uhid_misc); +} + +module_init(uhid_init); +module_exit(uhid_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David Herrmann "); +MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); -- GitLab From ace3d8614ab0e6544f5f85921085b55b915fe9aa Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:14 +0200 Subject: [PATCH 1847/6849] HID: uhid: add internal message buffer When receiving messages from the HID subsystem, we need to process them and store them in an internal buffer so user-space can read() on the char device to retrieve the messages. This adds a static buffer for 32 messages to each uhid device. Each message is dynamically allocated so the uhid_device structure does not get too big. uhid_queue() adds a message to the buffer. If the buffer is full, the message is discarded. uhid_queue_event() is an helper for messages without payload. This also adds a public header: uhid.h. It contains the declarations for the user-space API. It is built around "struct uhid_event" which contains a type field which specifies the event type and each event can then add a variable-length payload. For now, there is only a dummy event but later patches will add new event types and payloads. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/Kbuild | 1 + include/linux/uhid.h | 33 ++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 include/linux/uhid.h diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 5b02d6cb0e60..05ef4b05a63e 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -25,16 +25,81 @@ #include #define UHID_NAME "uhid" +#define UHID_BUFSIZE 32 + +struct uhid_device { + struct hid_device *hid; + + wait_queue_head_t waitq; + spinlock_t qlock; + __u8 head; + __u8 tail; + struct uhid_event *outq[UHID_BUFSIZE]; +}; static struct miscdevice uhid_misc; +static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev) +{ + __u8 newhead; + + newhead = (uhid->head + 1) % UHID_BUFSIZE; + + if (newhead != uhid->tail) { + uhid->outq[uhid->head] = ev; + uhid->head = newhead; + wake_up_interruptible(&uhid->waitq); + } else { + hid_warn(uhid->hid, "Output queue is full\n"); + kfree(ev); + } +} + +static int uhid_queue_event(struct uhid_device *uhid, __u32 event) +{ + unsigned long flags; + struct uhid_event *ev; + + ev = kzalloc(sizeof(*ev), GFP_KERNEL); + if (!ev) + return -ENOMEM; + + ev->type = event; + + spin_lock_irqsave(&uhid->qlock, flags); + uhid_queue(uhid, ev); + spin_unlock_irqrestore(&uhid->qlock, flags); + + return 0; +} + static int uhid_char_open(struct inode *inode, struct file *file) { + struct uhid_device *uhid; + + uhid = kzalloc(sizeof(*uhid), GFP_KERNEL); + if (!uhid) + return -ENOMEM; + + spin_lock_init(&uhid->qlock); + init_waitqueue_head(&uhid->waitq); + + file->private_data = uhid; + nonseekable_open(inode, file); + return 0; } static int uhid_char_release(struct inode *inode, struct file *file) { + struct uhid_device *uhid = file->private_data; + unsigned int i; + + for (i = 0; i < UHID_BUFSIZE; ++i) + kfree(uhid->outq[i]); + + kfree(uhid); + return 0; } diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 39737839ce29..8cdabecfbe27 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -373,6 +373,7 @@ header-y += tty.h header-y += types.h header-y += udf_fs_i.h header-y += udp.h +header-y += uhid.h header-y += uinput.h header-y += uio.h header-y += ultrasound.h diff --git a/include/linux/uhid.h b/include/linux/uhid.h new file mode 100644 index 000000000000..16b786a2b18f --- /dev/null +++ b/include/linux/uhid.h @@ -0,0 +1,33 @@ +#ifndef __UHID_H_ +#define __UHID_H_ + +/* + * User-space I/O driver support for HID subsystem + * Copyright (c) 2012 David Herrmann + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +/* + * Public header for user-space communication. We try to keep every structure + * aligned but to be safe we also use __attribute__((__packed__)). Therefore, + * the communication should be ABI compatible even between architectures. + */ + +#include +#include + +enum uhid_event_type { + UHID_DUMMY, +}; + +struct uhid_event { + __u32 type; +} __attribute__((__packed__)); + +#endif /* __UHID_H_ */ -- GitLab From 1f9dec1e0164b48da9b268a02197f38caa69b118 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:15 +0200 Subject: [PATCH 1848/6849] HID: uhid: allow poll()'ing on uhid devices As long as the internal buffer is not empty, we return POLLIN to user-space. uhid->head and uhid->tail are no atomics so the comparison may return inexact results. However, this doesn't matter here as user-space would need to poll() in two threads simultaneously to trigger this. And in this case it doesn't matter if a cached result is returned or the exact new result as user-space does not know which thread returns first from poll() and the following read(). So it is safe to compare the values without locking. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 05ef4b05a63e..b1a477f8260c 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -117,6 +117,13 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, static unsigned int uhid_char_poll(struct file *file, poll_table *wait) { + struct uhid_device *uhid = file->private_data; + + poll_wait(file, &uhid->waitq, wait); + + if (uhid->head != uhid->tail) + return POLLIN | POLLRDNORM; + return 0; } -- GitLab From d937ae5fae17e63aaa97f029be221a6516b25475 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:16 +0200 Subject: [PATCH 1849/6849] HID: uhid: implement read() on uhid devices User-space can use read() to get a single event from uhid devices. read() does never return multiple events. This allows us to extend the event structure and still keep backwards compatibility. If user-space wants to get multiple events in one syscall, they should use the readv()/writev() syscalls which are supported by uhid. This introduces a new lock which helps us synchronizing simultaneous reads from user-space. We also correctly return -EINVAL/-EFAULT only on errors and retry the read() when some other thread captured the event faster than we did. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index b1a477f8260c..93860826d629 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -28,6 +28,7 @@ #define UHID_BUFSIZE 32 struct uhid_device { + struct mutex devlock; struct hid_device *hid; wait_queue_head_t waitq; @@ -81,6 +82,7 @@ static int uhid_char_open(struct inode *inode, struct file *file) if (!uhid) return -ENOMEM; + mutex_init(&uhid->devlock); spin_lock_init(&uhid->qlock); init_waitqueue_head(&uhid->waitq); @@ -106,7 +108,49 @@ static int uhid_char_release(struct inode *inode, struct file *file) static ssize_t uhid_char_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - return 0; + struct uhid_device *uhid = file->private_data; + int ret; + unsigned long flags; + size_t len; + + /* they need at least the "type" member of uhid_event */ + if (count < sizeof(__u32)) + return -EINVAL; + +try_again: + if (file->f_flags & O_NONBLOCK) { + if (uhid->head == uhid->tail) + return -EAGAIN; + } else { + ret = wait_event_interruptible(uhid->waitq, + uhid->head != uhid->tail); + if (ret) + return ret; + } + + ret = mutex_lock_interruptible(&uhid->devlock); + if (ret) + return ret; + + if (uhid->head == uhid->tail) { + mutex_unlock(&uhid->devlock); + goto try_again; + } else { + len = min(count, sizeof(**uhid->outq)); + if (copy_to_user(buffer, &uhid->outq[uhid->tail], len)) { + ret = -EFAULT; + } else { + kfree(uhid->outq[uhid->tail]); + uhid->outq[uhid->tail] = NULL; + + spin_lock_irqsave(&uhid->qlock, flags); + uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE; + spin_unlock_irqrestore(&uhid->qlock, flags); + } + } + + mutex_unlock(&uhid->devlock); + return ret ? ret : len; } static ssize_t uhid_char_write(struct file *file, const char __user *buffer, -- GitLab From 6664ef72a47459f883d3409ca9b2fa200015704b Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:17 +0200 Subject: [PATCH 1850/6849] HID: uhid: implement write() on uhid devices Similar to read() you can only write() a single event with one call to an uhid device. To write multiple events use writev() which is supported by uhid. We currently always return -EOPNOTSUPP but other events will be added in later patches. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 93860826d629..31e8379cfd15 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -30,6 +30,7 @@ struct uhid_device { struct mutex devlock; struct hid_device *hid; + struct uhid_event input_buf; wait_queue_head_t waitq; spinlock_t qlock; @@ -156,7 +157,35 @@ try_again: static ssize_t uhid_char_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - return 0; + struct uhid_device *uhid = file->private_data; + int ret; + size_t len; + + /* we need at least the "type" member of uhid_event */ + if (count < sizeof(__u32)) + return -EINVAL; + + ret = mutex_lock_interruptible(&uhid->devlock); + if (ret) + return ret; + + memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); + len = min(count, sizeof(uhid->input_buf)); + if (copy_from_user(&uhid->input_buf, buffer, len)) { + ret = -EFAULT; + goto unlock; + } + + switch (uhid->input_buf.type) { + default: + ret = -EOPNOTSUPP; + } + +unlock: + mutex_unlock(&uhid->devlock); + + /* return "count" not "len" to not confuse the caller */ + return ret ? ret : count; } static unsigned int uhid_char_poll(struct file *file, poll_table *wait) -- GitLab From d365c6cfd337a2bccdc65eacce271a311ea1072c Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:18 +0200 Subject: [PATCH 1851/6849] HID: uhid: add UHID_CREATE and UHID_DESTROY events UHID_CREATE and UHID_DESTROY are used to create and destroy a device on an open uhid char-device. Internally, we allocate and register an HID device with the HID core and immediately start the device. From now on events may be received or sent to the device. The UHID_CREATE event has a payload similar to the data used by Bluetooth-HIDP when creating a new connection. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 144 +++++++++++++++++++++++++++++++++++++++++++ include/linux/uhid.h | 21 ++++++- 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 31e8379cfd15..61ee7cc32ccf 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -29,6 +29,11 @@ struct uhid_device { struct mutex devlock; + bool running; + + __u8 *rd_data; + uint rd_size; + struct hid_device *hid; struct uhid_event input_buf; @@ -75,6 +80,136 @@ static int uhid_queue_event(struct uhid_device *uhid, __u32 event) return 0; } +static int uhid_hid_start(struct hid_device *hid) +{ + return 0; +} + +static void uhid_hid_stop(struct hid_device *hid) +{ +} + +static int uhid_hid_open(struct hid_device *hid) +{ + return 0; +} + +static void uhid_hid_close(struct hid_device *hid) +{ +} + +static int uhid_hid_input(struct input_dev *input, unsigned int type, + unsigned int code, int value) +{ + return 0; +} + +static int uhid_hid_parse(struct hid_device *hid) +{ + return 0; +} + +static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, + __u8 *buf, size_t count, unsigned char rtype) +{ + return 0; +} + +static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, + unsigned char report_type) +{ + return 0; +} + +static struct hid_ll_driver uhid_hid_driver = { + .start = uhid_hid_start, + .stop = uhid_hid_stop, + .open = uhid_hid_open, + .close = uhid_hid_close, + .hidinput_input_event = uhid_hid_input, + .parse = uhid_hid_parse, +}; + +static int uhid_dev_create(struct uhid_device *uhid, + const struct uhid_event *ev) +{ + struct hid_device *hid; + int ret; + + if (uhid->running) + return -EALREADY; + + uhid->rd_size = ev->u.create.rd_size; + if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE) + return -EINVAL; + + uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL); + if (!uhid->rd_data) + return -ENOMEM; + + if (copy_from_user(uhid->rd_data, ev->u.create.rd_data, + uhid->rd_size)) { + ret = -EFAULT; + goto err_free; + } + + hid = hid_allocate_device(); + if (IS_ERR(hid)) { + ret = PTR_ERR(hid); + goto err_free; + } + + strncpy(hid->name, ev->u.create.name, 127); + hid->name[127] = 0; + strncpy(hid->phys, ev->u.create.phys, 63); + hid->phys[63] = 0; + strncpy(hid->uniq, ev->u.create.uniq, 63); + hid->uniq[63] = 0; + + hid->ll_driver = &uhid_hid_driver; + hid->hid_get_raw_report = uhid_hid_get_raw; + hid->hid_output_raw_report = uhid_hid_output_raw; + hid->bus = ev->u.create.bus; + hid->vendor = ev->u.create.vendor; + hid->product = ev->u.create.product; + hid->version = ev->u.create.version; + hid->country = ev->u.create.country; + hid->driver_data = uhid; + hid->dev.parent = uhid_misc.this_device; + + uhid->hid = hid; + uhid->running = true; + + ret = hid_add_device(hid); + if (ret) { + hid_err(hid, "Cannot register HID device\n"); + goto err_hid; + } + + return 0; + +err_hid: + hid_destroy_device(hid); + uhid->hid = NULL; + uhid->running = false; +err_free: + kfree(uhid->rd_data); + return ret; +} + +static int uhid_dev_destroy(struct uhid_device *uhid) +{ + if (!uhid->running) + return -EINVAL; + + uhid->running = false; + + hid_destroy_device(uhid->hid); + kfree(uhid->rd_data); + + return 0; +} + static int uhid_char_open(struct inode *inode, struct file *file) { struct uhid_device *uhid; @@ -86,6 +221,7 @@ static int uhid_char_open(struct inode *inode, struct file *file) mutex_init(&uhid->devlock); spin_lock_init(&uhid->qlock); init_waitqueue_head(&uhid->waitq); + uhid->running = false; file->private_data = uhid; nonseekable_open(inode, file); @@ -98,6 +234,8 @@ static int uhid_char_release(struct inode *inode, struct file *file) struct uhid_device *uhid = file->private_data; unsigned int i; + uhid_dev_destroy(uhid); + for (i = 0; i < UHID_BUFSIZE; ++i) kfree(uhid->outq[i]); @@ -177,6 +315,12 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, } switch (uhid->input_buf.type) { + case UHID_CREATE: + ret = uhid_dev_create(uhid, &uhid->input_buf); + break; + case UHID_DESTROY: + ret = uhid_dev_destroy(uhid); + break; default: ret = -EOPNOTSUPP; } diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 16b786a2b18f..8a493e604a77 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -23,11 +23,30 @@ #include enum uhid_event_type { - UHID_DUMMY, + UHID_CREATE, + UHID_DESTROY, }; +struct uhid_create_req { + __u8 name[128]; + __u8 phys[64]; + __u8 uniq[64]; + __u8 __user *rd_data; + __u16 rd_size; + + __u16 bus; + __u32 vendor; + __u32 product; + __u32 version; + __u32 country; +} __attribute__((__packed__)); + struct uhid_event { __u32 type; + + union { + struct uhid_create_req create; + } u; } __attribute__((__packed__)); #endif /* __UHID_H_ */ -- GitLab From 5e87a36ae375297b71cc21ac7e32846832bcfb34 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:19 +0200 Subject: [PATCH 1852/6849] HID: uhid: allow feeding input data into uhid devices This adds a new event type UHID_INPUT which allows user-space to feed raw HID reports into the HID subsystem. We copy the data into kernel memory and directly feed it into the HID core. There is no error handling of the events couldn't be parsed so user-space should consider all events successfull unless read() returns an error. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 14 ++++++++++++++ include/linux/uhid.h | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 61ee7cc32ccf..3d1ebda122e5 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -210,6 +210,17 @@ static int uhid_dev_destroy(struct uhid_device *uhid) return 0; } +static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev) +{ + if (!uhid->running) + return -EINVAL; + + hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, + min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0); + + return 0; +} + static int uhid_char_open(struct inode *inode, struct file *file) { struct uhid_device *uhid; @@ -321,6 +332,9 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, case UHID_DESTROY: ret = uhid_dev_destroy(uhid); break; + case UHID_INPUT: + ret = uhid_dev_input(uhid, &uhid->input_buf); + break; default: ret = -EOPNOTSUPP; } diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 8a493e604a77..6eb42bea86a2 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -25,6 +25,7 @@ enum uhid_event_type { UHID_CREATE, UHID_DESTROY, + UHID_INPUT, }; struct uhid_create_req { @@ -41,11 +42,19 @@ struct uhid_create_req { __u32 country; } __attribute__((__packed__)); +#define UHID_DATA_MAX 4096 + +struct uhid_input_req { + __u8 data[UHID_DATA_MAX]; + __u16 size; +} __attribute__((__packed__)); + struct uhid_event { __u32 type; union { struct uhid_create_req create; + struct uhid_input_req input; } u; } __attribute__((__packed__)); -- GitLab From 037c061bca06cbfe9998476fb593090300fbbe87 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:20 +0200 Subject: [PATCH 1853/6849] HID: uhid: forward hid report-descriptor to hid core When the uhid_hid_parse callback is called we simply forward it to hid_parse_report() with the data that we got in the UHID_CREATE event. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 3d1ebda122e5..0d011db30a46 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -106,7 +106,9 @@ static int uhid_hid_input(struct input_dev *input, unsigned int type, static int uhid_hid_parse(struct hid_device *hid) { - return 0; + struct uhid_device *uhid = hid->driver_data; + + return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); } static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, -- GitLab From ec4b7dea453e0f9fd0fbf1761b2d01eff64f264b Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:21 +0200 Subject: [PATCH 1854/6849] HID: uhid: add UHID_START and UHID_STOP events We send UHID_START and UHID_STOP events to user-space when the HID core starts/stops the device. This notifies user-space about driver readiness and data-I/O can start now. This directly forwards the callbacks from hid-core to user-space. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 8 +++++++- include/linux/uhid.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 0d011db30a46..2e7f3a023975 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -82,11 +82,17 @@ static int uhid_queue_event(struct uhid_device *uhid, __u32 event) static int uhid_hid_start(struct hid_device *hid) { - return 0; + struct uhid_device *uhid = hid->driver_data; + + return uhid_queue_event(uhid, UHID_START); } static void uhid_hid_stop(struct hid_device *hid) { + struct uhid_device *uhid = hid->driver_data; + + hid->claimed = 0; + uhid_queue_event(uhid, UHID_STOP); } static int uhid_hid_open(struct hid_device *hid) diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 6eb42bea86a2..f8ce6f7571d8 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -25,6 +25,8 @@ enum uhid_event_type { UHID_CREATE, UHID_DESTROY, + UHID_START, + UHID_STOP, UHID_INPUT, }; -- GitLab From e7191474a5459e6ba7039fadca6a32f3a5731909 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:22 +0200 Subject: [PATCH 1855/6849] HID: uhid: forward open/close events to user-space HID core notifies us with *_open/*_close callbacks when there is an actual user of our device. We forward these to user-space so they can react on this. This allows user-space to skip I/O unless they receive an OPEN event. When they receive a CLOSE event they can stop I/O again to save energy. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 7 ++++++- include/linux/uhid.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 2e7f3a023975..0226ba3f5307 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -97,11 +97,16 @@ static void uhid_hid_stop(struct hid_device *hid) static int uhid_hid_open(struct hid_device *hid) { - return 0; + struct uhid_device *uhid = hid->driver_data; + + return uhid_queue_event(uhid, UHID_OPEN); } static void uhid_hid_close(struct hid_device *hid) { + struct uhid_device *uhid = hid->driver_data; + + uhid_queue_event(uhid, UHID_CLOSE); } static int uhid_hid_input(struct input_dev *input, unsigned int type, diff --git a/include/linux/uhid.h b/include/linux/uhid.h index f8ce6f7571d8..351650b7a0f6 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -27,6 +27,8 @@ enum uhid_event_type { UHID_DESTROY, UHID_START, UHID_STOP, + UHID_OPEN, + UHID_CLOSE, UHID_INPUT, }; -- GitLab From f80e13601c51a836b2aac583b8a3b4327c0c27ce Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:23 +0200 Subject: [PATCH 1856/6849] HID: uhid: forward output request to user-space If the hid-driver wants to send standardized data to the device it uses a linux input_event. We forward this to the user-space transport-level driver so they can perform the requested action on the device. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 18 ++++++++++++++++++ include/linux/uhid.h | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 0226ba3f5307..4dd693e1c8b8 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -112,6 +112,24 @@ static void uhid_hid_close(struct hid_device *hid) static int uhid_hid_input(struct input_dev *input, unsigned int type, unsigned int code, int value) { + struct hid_device *hid = input_get_drvdata(input); + struct uhid_device *uhid = hid->driver_data; + unsigned long flags; + struct uhid_event *ev; + + ev = kzalloc(sizeof(*ev), GFP_ATOMIC); + if (!ev) + return -ENOMEM; + + ev->type = UHID_OUTPUT_EV; + ev->u.output_ev.type = type; + ev->u.output_ev.code = code; + ev->u.output_ev.value = value; + + spin_lock_irqsave(&uhid->qlock, flags); + uhid_queue(uhid, ev); + spin_unlock_irqrestore(&uhid->qlock, flags); + return 0; } diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 351650b7a0f6..3fa484921010 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -29,6 +29,7 @@ enum uhid_event_type { UHID_STOP, UHID_OPEN, UHID_CLOSE, + UHID_OUTPUT_EV, UHID_INPUT, }; @@ -53,12 +54,19 @@ struct uhid_input_req { __u16 size; } __attribute__((__packed__)); +struct uhid_output_ev_req { + __u16 type; + __u16 code; + __s32 value; +} __attribute__((__packed__)); + struct uhid_event { __u32 type; union { struct uhid_create_req create; struct uhid_input_req input; + struct uhid_output_ev_req output_ev; } u; } __attribute__((__packed__)); -- GitLab From 3b3baa82e4306b5160692643fab2fa322ceb94f9 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:24 +0200 Subject: [PATCH 1857/6849] HID: uhid: forward raw output reports to user-space Some drivers that use non-standard HID features require raw output reports sent to the device. We now forward these requests directly to user-space so the transport-level driver can correctly send it to the device or handle it correspondingly. There is no way to signal back whether the transmission was successful, moreover, there might be lots of messages coming out from the driver flushing the output-queue. However, there is currently no driver that causes this so we are safe. If some drivers need to transmit lots of data this way, we need a method to synchronize this and can implement another UHID_OUTPUT_SYNC event. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 34 +++++++++++++++++++++++++++++++++- include/linux/uhid.h | 14 ++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 4dd693e1c8b8..421c492dc824 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -149,7 +149,39 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, unsigned char report_type) { - return 0; + struct uhid_device *uhid = hid->driver_data; + __u8 rtype; + unsigned long flags; + struct uhid_event *ev; + + switch (report_type) { + case HID_FEATURE_REPORT: + rtype = UHID_FEATURE_REPORT; + break; + case HID_OUTPUT_REPORT: + rtype = UHID_OUTPUT_REPORT; + break; + default: + return -EINVAL; + } + + if (count < 1 || count > UHID_DATA_MAX) + return -EINVAL; + + ev = kzalloc(sizeof(*ev), GFP_KERNEL); + if (!ev) + return -ENOMEM; + + ev->type = UHID_OUTPUT; + ev->u.output.size = count; + ev->u.output.rtype = rtype; + memcpy(ev->u.output.data, buf, count); + + spin_lock_irqsave(&uhid->qlock, flags); + uhid_queue(uhid, ev); + spin_unlock_irqrestore(&uhid->qlock, flags); + + return count; } static struct hid_ll_driver uhid_hid_driver = { diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 3fa484921010..2c972550a624 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -29,6 +29,7 @@ enum uhid_event_type { UHID_STOP, UHID_OPEN, UHID_CLOSE, + UHID_OUTPUT, UHID_OUTPUT_EV, UHID_INPUT, }; @@ -49,11 +50,23 @@ struct uhid_create_req { #define UHID_DATA_MAX 4096 +enum uhid_report_type { + UHID_FEATURE_REPORT, + UHID_OUTPUT_REPORT, + UHID_INPUT_REPORT, +}; + struct uhid_input_req { __u8 data[UHID_DATA_MAX]; __u16 size; } __attribute__((__packed__)); +struct uhid_output_req { + __u8 data[UHID_DATA_MAX]; + __u16 size; + __u8 rtype; +} __attribute__((__packed__)); + struct uhid_output_ev_req { __u16 type; __u16 code; @@ -66,6 +79,7 @@ struct uhid_event { union { struct uhid_create_req create; struct uhid_input_req input; + struct uhid_output_req output; struct uhid_output_ev_req output_ev; } u; } __attribute__((__packed__)); -- GitLab From fcfcf0deb89ece6eb9ae23768fec1bc1718f9b7f Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:25 +0200 Subject: [PATCH 1858/6849] HID: uhid: implement feature requests HID standard allows sending a feature request to the device which is answered by an HID report. uhid implements this by sending a UHID_FEATURE event to user-space which then must answer with UHID_FEATURE_ANSWER. If it doesn't do this in a timely manner, the request is discarded silently. We serialize the feature requests, that is, there is always only a single active feature-request sent to user-space, other requests have to wait. HIDP and USB-HID do it the same way. Because we discard feature-requests silently, we must make sure to match a response to the corresponding request. We use sequence-IDs for this so user-space must copy the ID from the request into the answer. Feature-answers are ignored if they do not contain the same ID as the currently pending feature request. Internally, we must make sure that feature-requests are synchronized with UHID_DESTROY and close() events. We must not dead-lock when closing the HID device, either, so we have to use separate locks. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 120 ++++++++++++++++++++++++++++++++++++++++++- include/linux/uhid.h | 17 ++++++ 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 421c492dc824..ea560bfa033d 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -42,6 +42,12 @@ struct uhid_device { __u8 head; __u8 tail; struct uhid_event *outq[UHID_BUFSIZE]; + + struct mutex report_lock; + wait_queue_head_t report_wait; + atomic_t report_done; + atomic_t report_id; + struct uhid_event report_buf; }; static struct miscdevice uhid_misc; @@ -143,7 +149,84 @@ static int uhid_hid_parse(struct hid_device *hid) static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, __u8 *buf, size_t count, unsigned char rtype) { - return 0; + struct uhid_device *uhid = hid->driver_data; + __u8 report_type; + struct uhid_event *ev; + unsigned long flags; + int ret; + size_t len; + struct uhid_feature_answer_req *req; + + if (!uhid->running) + return -EIO; + + switch (rtype) { + case HID_FEATURE_REPORT: + report_type = UHID_FEATURE_REPORT; + break; + case HID_OUTPUT_REPORT: + report_type = UHID_OUTPUT_REPORT; + break; + case HID_INPUT_REPORT: + report_type = UHID_INPUT_REPORT; + break; + default: + return -EINVAL; + } + + ret = mutex_lock_interruptible(&uhid->report_lock); + if (ret) + return ret; + + ev = kzalloc(sizeof(*ev), GFP_KERNEL); + if (!ev) { + ret = -ENOMEM; + goto unlock; + } + + spin_lock_irqsave(&uhid->qlock, flags); + ev->type = UHID_FEATURE; + ev->u.feature.id = atomic_inc_return(&uhid->report_id); + ev->u.feature.rnum = rnum; + ev->u.feature.rtype = report_type; + + atomic_set(&uhid->report_done, 0); + uhid_queue(uhid, ev); + spin_unlock_irqrestore(&uhid->qlock, flags); + + ret = wait_event_interruptible_timeout(uhid->report_wait, + atomic_read(&uhid->report_done), 5 * HZ); + + /* + * Make sure "uhid->running" is cleared on shutdown before + * "uhid->report_done" is set. + */ + smp_rmb(); + if (!ret || !uhid->running) { + ret = -EIO; + } else if (ret < 0) { + ret = -ERESTARTSYS; + } else { + spin_lock_irqsave(&uhid->qlock, flags); + req = &uhid->report_buf.u.feature_answer; + + if (req->err) { + ret = -EIO; + } else { + ret = 0; + len = min(count, + min_t(size_t, req->size, UHID_DATA_MAX)); + memcpy(buf, req->data, len); + } + + spin_unlock_irqrestore(&uhid->qlock, flags); + } + + atomic_set(&uhid->report_done, 1); + +unlock: + mutex_unlock(&uhid->report_lock); + return ret ? ret : len; } static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, @@ -265,7 +348,11 @@ static int uhid_dev_destroy(struct uhid_device *uhid) if (!uhid->running) return -EINVAL; + /* clear "running" before setting "report_done" */ uhid->running = false; + smp_wmb(); + atomic_set(&uhid->report_done, 1); + wake_up_interruptible(&uhid->report_wait); hid_destroy_device(uhid->hid); kfree(uhid->rd_data); @@ -284,6 +371,31 @@ static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev) return 0; } +static int uhid_dev_feature_answer(struct uhid_device *uhid, + struct uhid_event *ev) +{ + unsigned long flags; + + if (!uhid->running) + return -EINVAL; + + spin_lock_irqsave(&uhid->qlock, flags); + + /* id for old report; drop it silently */ + if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id) + goto unlock; + if (atomic_read(&uhid->report_done)) + goto unlock; + + memcpy(&uhid->report_buf, ev, sizeof(*ev)); + atomic_set(&uhid->report_done, 1); + wake_up_interruptible(&uhid->report_wait); + +unlock: + spin_unlock_irqrestore(&uhid->qlock, flags); + return 0; +} + static int uhid_char_open(struct inode *inode, struct file *file) { struct uhid_device *uhid; @@ -293,9 +405,12 @@ static int uhid_char_open(struct inode *inode, struct file *file) return -ENOMEM; mutex_init(&uhid->devlock); + mutex_init(&uhid->report_lock); spin_lock_init(&uhid->qlock); init_waitqueue_head(&uhid->waitq); + init_waitqueue_head(&uhid->report_wait); uhid->running = false; + atomic_set(&uhid->report_done, 1); file->private_data = uhid; nonseekable_open(inode, file); @@ -398,6 +513,9 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, case UHID_INPUT: ret = uhid_dev_input(uhid, &uhid->input_buf); break; + case UHID_FEATURE_ANSWER: + ret = uhid_dev_feature_answer(uhid, &uhid->input_buf); + break; default: ret = -EOPNOTSUPP; } diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 2c972550a624..9c6974f16966 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h @@ -32,6 +32,8 @@ enum uhid_event_type { UHID_OUTPUT, UHID_OUTPUT_EV, UHID_INPUT, + UHID_FEATURE, + UHID_FEATURE_ANSWER, }; struct uhid_create_req { @@ -73,6 +75,19 @@ struct uhid_output_ev_req { __s32 value; } __attribute__((__packed__)); +struct uhid_feature_req { + __u32 id; + __u8 rnum; + __u8 rtype; +} __attribute__((__packed__)); + +struct uhid_feature_answer_req { + __u32 id; + __u16 err; + __u16 size; + __u8 data[UHID_DATA_MAX]; +}; + struct uhid_event { __u32 type; @@ -81,6 +96,8 @@ struct uhid_event { struct uhid_input_req input; struct uhid_output_req output; struct uhid_output_ev_req output_ev; + struct uhid_feature_req feature; + struct uhid_feature_answer_req feature_answer; } u; } __attribute__((__packed__)); -- GitLab From d99b8bad7663c8b920b366877a27b4176dece062 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:26 +0200 Subject: [PATCH 1859/6849] HID: uhid: add documentation This describes the protocol used by uhid for user-space applications. It describes the details like non-blocking I/O and readv/writev for multiple events per syscall. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- Documentation/hid/uhid.txt | 169 +++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Documentation/hid/uhid.txt diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt new file mode 100644 index 000000000000..4627c4241ece --- /dev/null +++ b/Documentation/hid/uhid.txt @@ -0,0 +1,169 @@ + UHID - User-space I/O driver support for HID subsystem + ======================================================== + +The HID subsystem needs two kinds of drivers. In this document we call them: + + 1. The "HID I/O Driver" is the driver that performs raw data I/O to the + low-level device. Internally, they register an hid_ll_driver structure with + the HID core. They perform device setup, read raw data from the device and + push it into the HID subsystem and they provide a callback so the HID + subsystem can send data to the device. + + 2. The "HID Device Driver" is the driver that parses HID reports and reacts on + them. There are generic drivers like "generic-usb" and "generic-bluetooth" + which adhere to the HID specification and provide the standardizes features. + But there may be special drivers and quirks for each non-standard device out + there. Internally, they use the hid_driver structure. + +Historically, the USB stack was the first subsystem to provide an HID I/O +Driver. However, other standards like Bluetooth have adopted the HID specs and +may provide HID I/O Drivers, too. The UHID driver allows to implement HID I/O +Drivers in user-space and feed the data into the kernel HID-subsystem. + +This allows user-space to operate on the same level as USB-HID, Bluetooth-HID +and similar. It does not provide a way to write HID Device Drivers, though. Use +hidraw for this purpose. + +There is an example user-space application in ./samples/uhid/uhid-example.c + +The UHID API +------------ + +UHID is accessed through a character misc-device. The minor-number is allocated +dynamically so you need to rely on udev (or similar) to create the device node. +This is /dev/uhid by default. + +If a new device is detected by your HID I/O Driver and you want to register this +device with the HID subsystem, then you need to open /dev/uhid once for each +device you want to register. All further communication is done by read()'ing or +write()'ing "struct uhid_event" objects. Non-blocking operations are supported +by setting O_NONBLOCK. + +struct uhid_event { + __u32 type; + union { + struct uhid_create_req create; + struct uhid_data_req data; + ... + } u; +}; + +The "type" field contains the ID of the event. Depending on the ID different +payloads are sent. You must not split a single event across multiple read()'s or +multiple write()'s. A single event must always be sent as a whole. Furthermore, +only a single event can be sent per read() or write(). Pending data is ignored. +If you want to handle multiple events in a single syscall, then use vectored +I/O with readv()/writev(). + +The first thing you should do is sending an UHID_CREATE event. This will +register the device. UHID will respond with an UHID_START event. You can now +start sending data to and reading data from UHID. However, unless UHID sends the +UHID_OPEN event, the internally attached HID Device Driver has no user attached. +That is, you might put your device asleep unless you receive the UHID_OPEN +event. If you receive the UHID_OPEN event, you should start I/O. If the last +user closes the HID device, you will receive an UHID_CLOSE event. This may be +followed by an UHID_OPEN event again and so on. There is no need to perform +reference-counting in user-space. That is, you will never receive multiple +UHID_OPEN events without an UHID_CLOSE event. The HID subsystem performs +ref-counting for you. +You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even +though the device may have no users. + +If you want to send data to the HID subsystem, you send an HID_INPUT event with +your raw data payload. If the kernel wants to send data to the device, you will +read an UHID_OUTPUT or UHID_OUTPUT_EV event. + +If your device disconnects, you should send an UHID_DESTROY event. This will +unregister the device. You can now send UHID_CREATE again to register a new +device. +If you close() the fd, the device is automatically unregistered and destroyed +internally. + +write() +------- +write() allows you to modify the state of the device and feed input data into +the kernel. The following types are supported: UHID_CREATE, UHID_DESTROY and +UHID_INPUT. The kernel will parse the event immediately and if the event ID is +not supported, it will return -EOPNOTSUPP. If the payload is invalid, then +-EINVAL is returned, otherwise, the amount of data that was read is returned and +the request was handled successfully. + + UHID_CREATE: + This creates the internal HID device. No I/O is possible until you send this + event to the kernel. The payload is of type struct uhid_create_req and + contains information about your device. You can start I/O now. + + UHID_DESTROY: + This destroys the internal HID device. No further I/O will be accepted. There + may still be pending messages that you can receive with read() but no further + UHID_INPUT events can be sent to the kernel. + You can create a new device by sending UHID_CREATE again. There is no need to + reopen the character device. + + UHID_INPUT: + You must send UHID_CREATE before sending input to the kernel! This event + contains a data-payload. This is the raw data that you read from your device. + The kernel will parse the HID reports and react on it. + + UHID_FEATURE_ANSWER: + If you receive a UHID_FEATURE request you must answer with this request. You + must copy the "id" field from the request into the answer. Set the "err" field + to 0 if no error occured or to EIO if an I/O error occurred. + If "err" is 0 then you should fill the buffer of the answer with the results + of the feature request and set "size" correspondingly. + +read() +------ +read() will return a queued ouput report. These output reports can be of type +UHID_START, UHID_STOP, UHID_OPEN, UHID_CLOSE, UHID_OUTPUT or UHID_OUTPUT_EV. No +reaction is required to any of them but you should handle them according to your +needs. Only UHID_OUTPUT and UHID_OUTPUT_EV have payloads. + + UHID_START: + This is sent when the HID device is started. Consider this as an answer to + UHID_CREATE. This is always the first event that is sent. + + UHID_STOP: + This is sent when the HID device is stopped. Consider this as an answer to + UHID_DESTROY. + If the kernel HID device driver closes the device manually (that is, you + didn't send UHID_DESTROY) then you should consider this device closed and send + an UHID_DESTROY event. You may want to reregister your device, though. This is + always the last message that is sent to you unless you reopen the device with + UHID_CREATE. + + UHID_OPEN: + This is sent when the HID device is opened. That is, the data that the HID + device provides is read by some other process. You may ignore this event but + it is useful for power-management. As long as you haven't received this event + there is actually no other process that reads your data so there is no need to + send UHID_INPUT events to the kernel. + + UHID_CLOSE: + This is sent when there are no more processes which read the HID data. It is + the counterpart of UHID_OPEN and you may as well ignore this event. + + UHID_OUTPUT: + This is sent if the HID device driver wants to send raw data to the I/O + device. You should read the payload and forward it to the device. The payload + is of type "struct uhid_data_req". + This may be received even though you haven't received UHID_OPEN, yet. + + UHID_OUTPUT_EV: + Same as UHID_OUTPUT but this contains a "struct input_event" as payload. This + is called for force-feedback, LED or similar events which are received through + an input device by the HID subsystem. You should convert this into raw reports + and send them to your device similar to events of type UHID_OUTPUT. + + UHID_FEATURE: + This event is sent if the kernel driver wants to perform a feature request as + described in the HID specs. The report-type and report-number are available in + the payload. + The kernel serializes feature requests so there will never be two in parallel. + However, if you fail to respond with a UHID_FEATURE_ANSWER in a time-span of 5 + seconds, then the requests will be dropped and a new one might be sent. + Therefore, the payload also contains an "id" field that identifies every + request. + +Document by: + David Herrmann -- GitLab From 5148fa52a12fa1b97c730b2fe321f2aad7ea041c Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:27 +0200 Subject: [PATCH 1860/6849] HID: uhid: add example program This adds an example user-space program that emulates a 3 button mouse with wheel. It detects keyboard presses and moves the mouse accordingly. It register a fake HID device to feed the raw HID reports into the kernel. In this example, you could use uinput to get the same result, but this shows how to get the same behavior with uhid so you don't need HID parsers in user-space. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- samples/uhid/Makefile | 10 + samples/uhid/uhid-example.c | 381 ++++++++++++++++++++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 samples/uhid/Makefile create mode 100644 samples/uhid/uhid-example.c diff --git a/samples/uhid/Makefile b/samples/uhid/Makefile new file mode 100644 index 000000000000..c95a696560a7 --- /dev/null +++ b/samples/uhid/Makefile @@ -0,0 +1,10 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := uhid-example + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_uhid-example.o += -I$(objtree)/usr/include diff --git a/samples/uhid/uhid-example.c b/samples/uhid/uhid-example.c new file mode 100644 index 000000000000..03ce3c059a5e --- /dev/null +++ b/samples/uhid/uhid-example.c @@ -0,0 +1,381 @@ +/* + * UHID Example + * + * Copyright (c) 2012 David Herrmann + * + * The code may be used by anyone for any purpose, + * and can serve as a starting point for developing + * applications using uhid. + */ + +/* UHID Example + * This example emulates a basic 3 buttons mouse with wheel over UHID. Run this + * program as root and then use the following keys to control the mouse: + * q: Quit the application + * 1: Toggle left button (down, up, ...) + * 2: Toggle right button + * 3: Toggle middle button + * a: Move mouse left + * d: Move mouse right + * w: Move mouse up + * s: Move mouse down + * r: Move wheel up + * f: Move wheel down + * + * If uhid is not available as /dev/uhid, then you can pass a different path as + * first argument. + * If is not installed in /usr, then compile this with: + * gcc -o ./uhid_test -Wall -I./include ./samples/uhid/uhid-example.c + * And ignore the warning about kernel headers. However, it is recommended to + * use the installed uhid.h if available. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* HID Report Desciptor + * We emulate a basic 3 button mouse with wheel. This is the report-descriptor + * as the kernel will parse it: + * + * INPUT[INPUT] + * Field(0) + * Physical(GenericDesktop.Pointer) + * Application(GenericDesktop.Mouse) + * Usage(3) + * Button.0001 + * Button.0002 + * Button.0003 + * Logical Minimum(0) + * Logical Maximum(1) + * Report Size(1) + * Report Count(3) + * Report Offset(0) + * Flags( Variable Absolute ) + * Field(1) + * Physical(GenericDesktop.Pointer) + * Application(GenericDesktop.Mouse) + * Usage(3) + * GenericDesktop.X + * GenericDesktop.Y + * GenericDesktop.Wheel + * Logical Minimum(-128) + * Logical Maximum(127) + * Report Size(8) + * Report Count(3) + * Report Offset(8) + * Flags( Variable Relative ) + * + * This is the mapping that we expect: + * Button.0001 ---> Key.LeftBtn + * Button.0002 ---> Key.RightBtn + * Button.0003 ---> Key.MiddleBtn + * GenericDesktop.X ---> Relative.X + * GenericDesktop.Y ---> Relative.Y + * GenericDesktop.Wheel ---> Relative.Wheel + * + * This information can be verified by reading /sys/kernel/debug/hid//rdesc + * This file should print the same information as showed above. + */ + +static unsigned char rdesc[] = { + 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, + 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, + 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, + 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01, + 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, + 0x15, 0x80, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, + 0x81, 0x06, 0xc0, 0xc0, +}; + +static int uhid_write(int fd, const struct uhid_event *ev) +{ + ssize_t ret; + + ret = write(fd, ev, sizeof(*ev)); + if (ret < 0) { + fprintf(stderr, "Cannot write to uhid: %m\n"); + return -errno; + } else if (ret != sizeof(*ev)) { + fprintf(stderr, "Wrong size written to uhid: %ld != %lu\n", + ret, sizeof(ev)); + return -EFAULT; + } else { + return 0; + } +} + +static int create(int fd) +{ + struct uhid_event ev; + + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_CREATE; + strcpy((char*)ev.u.create.name, "test-uhid-device"); + ev.u.create.rd_data = rdesc; + ev.u.create.rd_size = sizeof(rdesc); + ev.u.create.bus = BUS_USB; + ev.u.create.vendor = 0x15d9; + ev.u.create.product = 0x0a37; + ev.u.create.version = 0; + ev.u.create.country = 0; + + return uhid_write(fd, &ev); +} + +static void destroy(int fd) +{ + struct uhid_event ev; + + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_DESTROY; + + uhid_write(fd, &ev); +} + +static int event(int fd) +{ + struct uhid_event ev; + ssize_t ret; + + memset(&ev, 0, sizeof(ev)); + ret = read(fd, &ev, sizeof(ev)); + if (ret == 0) { + fprintf(stderr, "Read HUP on uhid-cdev\n"); + return -EFAULT; + } else if (ret < 0) { + fprintf(stderr, "Cannot read uhid-cdev: %m\n"); + return -errno; + } else if (ret != sizeof(ev)) { + fprintf(stderr, "Invalid size read from uhid-dev: %ld != %lu\n", + ret, sizeof(ev)); + return -EFAULT; + } + + switch (ev.type) { + case UHID_START: + fprintf(stderr, "UHID_START from uhid-dev\n"); + break; + case UHID_STOP: + fprintf(stderr, "UHID_STOP from uhid-dev\n"); + break; + case UHID_OPEN: + fprintf(stderr, "UHID_OPEN from uhid-dev\n"); + break; + case UHID_CLOSE: + fprintf(stderr, "UHID_CLOSE from uhid-dev\n"); + break; + case UHID_OUTPUT: + fprintf(stderr, "UHID_OUTPUT from uhid-dev\n"); + break; + case UHID_OUTPUT_EV: + fprintf(stderr, "UHID_OUTPUT_EV from uhid-dev\n"); + break; + default: + fprintf(stderr, "Invalid event from uhid-dev: %u\n", ev.type); + } + + return 0; +} + +static bool btn1_down; +static bool btn2_down; +static bool btn3_down; +static signed char abs_hor; +static signed char abs_ver; +static signed char wheel; + +static int send_event(int fd) +{ + struct uhid_event ev; + + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_INPUT; + ev.u.input.size = 4; + + if (btn1_down) + ev.u.input.data[0] |= 0x1; + if (btn2_down) + ev.u.input.data[0] |= 0x2; + if (btn3_down) + ev.u.input.data[0] |= 0x4; + + ev.u.input.data[1] = abs_hor; + ev.u.input.data[2] = abs_ver; + ev.u.input.data[3] = wheel; + + return uhid_write(fd, &ev); +} + +static int keyboard(int fd) +{ + char buf[128]; + ssize_t ret, i; + + ret = read(STDIN_FILENO, buf, sizeof(buf)); + if (ret == 0) { + fprintf(stderr, "Read HUP on stdin\n"); + return -EFAULT; + } else if (ret < 0) { + fprintf(stderr, "Cannot read stdin: %m\n"); + return -errno; + } + + for (i = 0; i < ret; ++i) { + switch (buf[i]) { + case '1': + btn1_down = !btn1_down; + ret = send_event(fd); + if (ret) + return ret; + break; + case '2': + btn2_down = !btn2_down; + ret = send_event(fd); + if (ret) + return ret; + break; + case '3': + btn3_down = !btn3_down; + ret = send_event(fd); + if (ret) + return ret; + break; + case 'a': + abs_hor = -20; + ret = send_event(fd); + abs_hor = 0; + if (ret) + return ret; + break; + case 'd': + abs_hor = 20; + ret = send_event(fd); + abs_hor = 0; + if (ret) + return ret; + break; + case 'w': + abs_ver = -20; + ret = send_event(fd); + abs_ver = 0; + if (ret) + return ret; + break; + case 's': + abs_ver = 20; + ret = send_event(fd); + abs_ver = 0; + if (ret) + return ret; + break; + case 'r': + wheel = 1; + ret = send_event(fd); + wheel = 0; + if (ret) + return ret; + break; + case 'f': + wheel = -1; + ret = send_event(fd); + wheel = 0; + if (ret) + return ret; + break; + case 'q': + return -ECANCELED; + default: + fprintf(stderr, "Invalid input: %c\n", buf[i]); + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + int fd; + const char *path = "/dev/uhid"; + struct pollfd pfds[2]; + int ret; + struct termios state; + + ret = tcgetattr(STDIN_FILENO, &state); + if (ret) { + fprintf(stderr, "Cannot get tty state\n"); + } else { + state.c_lflag &= ~ICANON; + state.c_cc[VMIN] = 1; + ret = tcsetattr(STDIN_FILENO, TCSANOW, &state); + if (ret) + fprintf(stderr, "Cannot set tty state\n"); + } + + if (argc >= 2) { + if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + fprintf(stderr, "Usage: %s [%s]\n", argv[0], path); + return EXIT_SUCCESS; + } else { + path = argv[1]; + } + } + + fprintf(stderr, "Open uhid-cdev %s\n", path); + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) { + fprintf(stderr, "Cannot open uhid-cdev %s: %m\n", path); + return EXIT_FAILURE; + } + + fprintf(stderr, "Create uhid device\n"); + ret = create(fd); + if (ret) { + close(fd); + return EXIT_FAILURE; + } + + pfds[0].fd = STDIN_FILENO; + pfds[0].events = POLLIN; + pfds[1].fd = fd; + pfds[1].events = POLLIN; + + fprintf(stderr, "Press 'q' to quit...\n"); + while (1) { + ret = poll(pfds, 2, -1); + if (ret < 0) { + fprintf(stderr, "Cannot poll for fds: %m\n"); + break; + } + if (pfds[0].revents & POLLHUP) { + fprintf(stderr, "Received HUP on stdin\n"); + break; + } + if (pfds[1].revents & POLLHUP) { + fprintf(stderr, "Received HUP on uhid-cdev\n"); + break; + } + + if (pfds[0].revents & POLLIN) { + ret = keyboard(fd); + if (ret) + break; + } + if (pfds[1].revents & POLLIN) { + ret = event(fd); + if (ret) + break; + } + } + + fprintf(stderr, "Destroy uhid device\n"); + destroy(fd); + return EXIT_SUCCESS; +} -- GitLab From 0a09d3ab3780aad9e64f1e45e56acf5b20bb82bf Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:28 +0200 Subject: [PATCH 1861/6849] MAINTAINERS: add UHID entry Add an UHID entry to the MAINTAINERS file. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index aa067a95ce11..4997519ea0ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6886,6 +6886,13 @@ S: Maintained F: Documentation/filesystems/ufs.txt F: fs/ufs/ +UHID USERSPACE HID IO DRIVER: +M: David Herrmann +L: linux-input@vger.kernel.org +S: Maintained +F: drivers/hid/uhid.c +F: include/linux/uhid.h + ULTRA-WIDEBAND (UWB) SUBSYSTEM: L: linux-usb@vger.kernel.org S: Orphan -- GitLab From eb6476441bc2fecf6232a87d0313a85f8e3da7f4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 14 Jun 2012 14:23:02 +0300 Subject: [PATCH 1862/6849] iwlwifi: protect use_ict with irq_lock This variable was accessed without taking the lock. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/rx.c | 30 ++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index d6860c070c16..be143eb4aa4f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -867,24 +867,23 @@ void iwl_disable_ict(struct iwl_trans *trans) spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } +/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ static irqreturn_t iwl_isr(int irq, void *data) { struct iwl_trans *trans = data; - struct iwl_trans_pcie *trans_pcie; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 inta, inta_mask; - unsigned long flags; #ifdef CONFIG_IWLWIFI_DEBUG u32 inta_fh; #endif + + lockdep_assert_held(&trans_pcie->irq_lock); + if (!trans) return IRQ_NONE; trace_iwlwifi_dev_irq(trans->dev); - trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - /* Disable (but don't clear!) interrupts here to avoid * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. @@ -907,7 +906,7 @@ static irqreturn_t iwl_isr(int irq, void *data) /* Hardware disappeared. It might have already raised * an interrupt */ IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta); - goto unplugged; + return IRQ_HANDLED; } #ifdef CONFIG_IWLWIFI_DEBUG @@ -926,18 +925,13 @@ static irqreturn_t iwl_isr(int irq, void *data) !trans_pcie->inta) iwl_enable_interrupts(trans); - unplugged: - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - return IRQ_HANDLED; - - none: +none: /* re-enable interrupts here since we don't have anything to service. */ /* only Re-enable if disabled by irq and no schedules tasklet. */ if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return IRQ_NONE; } @@ -963,15 +957,19 @@ irqreturn_t iwl_isr_ict(int irq, void *data) trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + /* dram interrupt table not set yet, * use legacy interrupt. */ - if (!trans_pcie->use_ict) - return iwl_isr(irq, data); + if (unlikely(!trans_pcie->use_ict)) { + irqreturn_t ret = iwl_isr(irq, data); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); + return ret; + } trace_iwlwifi_dev_irq(trans->dev); - spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Disable (but don't clear!) interrupts here to avoid * back-to-back ISRs and sporadic interrupts from our NIC. -- GitLab From dada03ca73b699337781ae36e1ce4c8fec2da40a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 17 Jun 2012 15:42:37 +0300 Subject: [PATCH 1863/6849] iwlwifi: disable early power Off reset for all NICs This feature needs to be disabled for all NICs. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/devices.c | 13 ------------- drivers/net/wireless/iwlwifi/dvm/main.c | 13 ++++++++++++- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 0521a6be09d2..349c205d5f62 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -250,17 +250,6 @@ struct iwl_lib_ops iwl2030_lib = { */ /* NIC configuration for 5000 series */ -static void iwl5000_nic_config(struct iwl_priv *priv) -{ - /* W/A : NIC is stuck in a reset state after Early PCIe power off - * (PCIe power is lost before PERST# is asserted), - * causing ME FW to lose ownership and not being able to obtain it back. - */ - iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG, - APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, - ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); -} - static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { .min_nrg_cck = 100, .auto_corr_min_ofdm = 90, @@ -433,14 +422,12 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, struct iwl_lib_ops iwl5000_lib = { .set_hw_params = iwl5000_hw_set_hw_params, .set_channel_switch = iwl5000_hw_channel_switch, - .nic_config = iwl5000_nic_config, .temperature = iwlagn_temperature, }; struct iwl_lib_ops iwl5150_lib = { .set_hw_params = iwl5150_hw_set_hw_params, .set_channel_switch = iwl5000_hw_channel_switch, - .nic_config = iwl5000_nic_config, .temperature = iwl5150_temperature, }; diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index bba3edfb3488..c642c217e29f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -51,11 +51,13 @@ #include "iwl-op-mode.h" #include "iwl-drv.h" #include "iwl-modparams.h" +#include "iwl-prph.h" #include "dev.h" #include "calib.h" #include "agn.h" + /****************************************************************************** * * module boiler plate @@ -2076,7 +2078,16 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode) CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); - priv->lib->nic_config(priv); + /* W/A : NIC is stuck in a reset state after Early PCIe power off + * (PCIe power is lost before PERST# is asserted), + * causing ME FW to lose ownership and not being able to obtain it back. + */ + iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG, + APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, + ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); + + if (priv->lib->nic_config) + priv->lib->nic_config(priv); } static void iwl_wimax_active(struct iwl_op_mode *op_mode) -- GitLab From 601968b3bb1176b4cee47faba2d7a104422de8e6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 14 Jun 2012 21:22:17 +0200 Subject: [PATCH 1864/6849] iwlwifi: delay ROC if doing internal reset scan When the device is doing an internal radio reset scan, ROC can be rejected to the supplicant with busy status which confuses it. One option would be to queue the ROC and handle it later, but since the radio reset scan is very quick we can just wait for it to finish instead. Also add a warning since we shouldn't run into the case of having a scan active when requesting a ROC in any other case since mac80211 will not scan while ROC or ROC while scanning. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 9d2374862314..c57726348ffe 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1036,8 +1036,18 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (test_bit(STATUS_SCAN_HW, &priv->status)) { - err = -EBUSY; - goto out; + /* mac80211 should not scan while ROC or ROC while scanning */ + if (WARN_ON_ONCE(priv->scan_type != IWL_SCAN_RADIO_RESET)) { + err = -EBUSY; + goto out; + } + + iwl_scan_cancel_timeout(priv, 100); + + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + err = -EBUSY; + goto out; + } } priv->hw_roc_channel = channel; -- GitLab From 3fbf4b71be81e6dd3d6bfbcdef9618628ee1bafe Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Sun, 17 Jun 2012 02:27:40 +0800 Subject: [PATCH 1865/6849] mac80211: implement the proactive PREP generation Generate the proactive PREP element in Proactive PREQ mode as defined in Sec. 13.10.10.3 (Case D) of IEEE Std. 802.11-2012. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Johannes Berg --- net/mac80211/mesh_hwmp.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index a6b08f5c4612..35e3acbe2262 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -516,10 +516,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, struct mesh_path *mpath = NULL; u8 *target_addr, *orig_addr; const u8 *da; - u8 target_flags, ttl; - u32 orig_sn, target_sn, lifetime; + u8 target_flags, ttl, flags; + u32 orig_sn, target_sn, lifetime, orig_metric; bool reply = false; bool forward = true; + bool root_is_gate; /* Update target SN, if present */ target_addr = PREQ_IE_TARGET_ADDR(preq_elem); @@ -527,6 +528,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = PREQ_IE_TARGET_SN(preq_elem); orig_sn = PREQ_IE_ORIG_SN(preq_elem); target_flags = PREQ_IE_TARGET_F(preq_elem); + orig_metric = metric; + /* Proactive PREQ gate announcements */ + flags = PREQ_IE_FLAGS(preq_elem); + root_is_gate = !!(flags & RANN_FLAG_IS_GATE); mhwmp_dbg("received PREQ from %pM", orig_addr); @@ -541,6 +546,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = ++ifmsh->sn; ifmsh->last_sn_update = jiffies; } + } else if (is_broadcast_ether_addr(target_addr) && + (target_flags & IEEE80211_PREQ_TO_FLAG)) { + rcu_read_lock(); + mpath = mesh_path_lookup(orig_addr, sdata); + if (mpath) { + if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { + reply = true; + target_addr = sdata->vif.addr; + target_sn = ++ifmsh->sn; + metric = 0; + ifmsh->last_sn_update = jiffies; + } + if (root_is_gate) + mesh_path_add_gate(mpath); + } + rcu_read_unlock(); } else { rcu_read_lock(); mpath = mesh_path_lookup(target_addr, sdata); @@ -573,13 +594,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, cpu_to_le32(target_sn), mgmt->sa, 0, ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 0, sdata); - } else + } else { ifmsh->mshstats.dropped_frames_ttl++; + } } if (forward && ifmsh->mshcfg.dot11MeshForwarding) { u32 preq_id; - u8 hopcount, flags; + u8 hopcount; ttl = PREQ_IE_TTL(preq_elem); lifetime = PREQ_IE_LIFETIME(preq_elem); @@ -589,11 +611,17 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, } mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); --ttl; - flags = PREQ_IE_FLAGS(preq_elem); preq_id = PREQ_IE_PREQ_ID(preq_elem); hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; da = (mpath && mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; + + if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { + target_addr = PREQ_IE_TARGET_ADDR(preq_elem); + target_sn = PREQ_IE_TARGET_SN(preq_elem); + metric = orig_metric; + } + mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, cpu_to_le32(orig_sn), target_flags, target_addr, cpu_to_le32(target_sn), da, -- GitLab From dbb912cd4ce64e763c5610b49a85529d2634e9d8 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Thu, 14 Jun 2012 02:06:09 +0800 Subject: [PATCH 1866/6849] mac80211: invoke the timer only with correct dot11MeshHWMPRootMode value mesh_path_root_timer is invoked once the dot11MeshHWMPRootMode is larger than 1. This patch also adds the backward compatible to the previous setting on dot11MeshHWMPRootMode. If the user configures as follow, it will still trigger the proactive RANN with Gate Announcement. iw mesh0 set mesh_param mesh_hwmp_rootmode 1 iw mesh0 set mesh_param mesh_gate_announcements 1 similar to the following setting: iw mesh0 set mesh_param mesh_hwmp_rootmode 4 iw mesh0 set mesh_param mesh_gate_announcements 1 Signed-off-by: Chun-Yeow Yeoh [line-break commit log] Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 4 ++-- net/mac80211/mesh.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d93cda1c4215..5bd316c0a63d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1565,8 +1565,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, * announcements, so require this ifmsh to also be a root node * */ if (nconf->dot11MeshGateAnnouncementProtocol && - !conf->dot11MeshHWMPRootMode) { - conf->dot11MeshHWMPRootMode = 1; + !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) { + conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN; ieee80211_mesh_root_setup(ifmsh); } conf->dot11MeshGateAnnouncementProtocol = diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 6bff3c4d17dd..ae40a83675e9 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data) void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) { - if (ifmsh->mshcfg.dot11MeshHWMPRootMode) + if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT) set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); else { clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); -- GitLab From 728b19e5fb9bbebbd580784a092b786fe379ed8e Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Thu, 14 Jun 2012 02:06:10 +0800 Subject: [PATCH 1867/6849] {nl,cfg,mac}80211: implement dot11MeshHWMPconfirmationInterval As defined in section 13.10.9.3 Case D (802.11-2012), this control variable is used to limit the mesh STA to send only one PREQ to a root mesh STA within this interval of time (in TUs). The default value for this variable is set to 2000 TUs. However, for current implementation, the maximum configurable of dot11MeshHWMPconfirmationInterval is restricted by dot11MeshHWMPactivePathTimeout. Signed-off-by: Chun-Yeow Yeoh [line-break commit log] Signed-off-by: Johannes Berg --- include/linux/nl80211.h | 5 +++++ include/net/cfg80211.h | 4 ++++ net/mac80211/cfg.c | 3 +++ net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/mesh.h | 2 ++ net/mac80211/mesh_hwmp.c | 7 ++++++- net/wireless/mesh.c | 2 ++ net/wireless/nl80211.c | 9 ++++++++- 8 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 6936fabe8797..b7c3b737ddde 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -2192,6 +2192,10 @@ enum nl80211_mntr_flags { * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between * proactive PREQs are transmitted. * + * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time + * (in TUs) during which a mesh STA can send only one Action frame + * containing a PREQ element for root path confirmation. + * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params { @@ -2220,6 +2224,7 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_HT_OPMODE, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, + NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e52b38d7b1b6..f0163a10b8ce 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -849,6 +849,9 @@ struct bss_parameters { * * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive * PREQs are transmitted. + * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs) + * during which a mesh STA can send only one Action frame containing + * a PREQ element for root path confirmation. */ struct mesh_config { u16 dot11MeshRetryTimeout; @@ -875,6 +878,7 @@ struct mesh_config { u16 ht_opmode; u32 dot11MeshHWMPactivePathToRootTimeout; u16 dot11MeshHWMProotInterval; + u16 dot11MeshHWMPconfirmationInterval; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5bd316c0a63d..6e25ac4873c7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1596,6 +1596,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask)) conf->dot11MeshHWMProotInterval = nconf->dot11MeshHWMProotInterval; + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask)) + conf->dot11MeshHWMPconfirmationInterval = + nconf->dot11MeshHWMPconfirmationInterval; return 0; } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index a8cea70902e4..512c894893d6 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -514,6 +514,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout, u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC); IEEE80211_IF_FILE(dot11MeshHWMProotInterval, u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC); +IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval, + u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC); #endif #define DEBUGFS_ADD_MODE(name, mode) \ @@ -617,6 +619,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(ht_opmode); MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout); MESHPARAMS_ADD(dot11MeshHWMProotInterval); + MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval); #undef MESHPARAMS_ADD } #endif diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index c7400a23b64b..faaa39bcfd10 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -104,6 +104,7 @@ enum mesh_deferred_task_flags { * an mpath to a hash bucket on a path table. * @rann_snd_addr: the RANN sender address * @rann_metric: the aggregated path metric towards the root node + * @last_preq_to_root: Timestamp of last PREQ sent to root * @is_root: the destination station of this path is a root node * @is_gate: the destination station of this path is a mesh gate * @@ -131,6 +132,7 @@ struct mesh_path { spinlock_t state_lock; u8 rann_snd_addr[ETH_ALEN]; u32 rann_metric; + unsigned long last_preq_to_root; bool is_root; bool is_gate; }; diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 35e3acbe2262..bea52479e3aa 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -98,6 +98,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae) #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries) #define disc_timeout_jiff(s) \ msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout) +#define root_path_confirmation_jiffies(s) \ + msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval) enum mpath_frame_type { MPATH_PREQ = 0, @@ -811,11 +813,14 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, } if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || - time_after(jiffies, mpath->exp_time - 1*HZ)) && + (time_after(jiffies, mpath->last_preq_to_root + + root_path_confirmation_jiffies(sdata)) || + time_before(jiffies, mpath->last_preq_to_root))) && !(mpath->flags & MESH_PATH_FIXED)) { mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, orig_addr); mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); + mpath->last_preq_to_root = jiffies; } if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn && diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 2f141cfd581e..3b73b07486cf 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -16,6 +16,7 @@ #define MESH_RANN_INTERVAL 5000 #define MESH_PATH_TO_ROOT_TIMEOUT 6000 #define MESH_ROOT_INTERVAL 5000 +#define MESH_ROOT_CONFIRMATION_INTERVAL 2000 /* * Minimum interval between two consecutive PREQs originated by the same @@ -66,6 +67,7 @@ const struct mesh_config default_mesh_config = { .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, + .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, }; const struct mesh_setup default_mesh_setup = { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f8930db613df..a363ca17bfc5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3473,7 +3473,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, cur_params.dot11MeshHWMPactivePathToRootTimeout) || nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, - cur_params.dot11MeshHWMProotInterval)) + cur_params.dot11MeshHWMProotInterval) || + nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, + cur_params.dot11MeshHWMPconfirmationInterval)) goto nla_put_failure; nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); @@ -3511,6 +3513,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, + [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, }; static const struct nla_policy @@ -3625,6 +3628,10 @@ do {\ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, + dot11MeshHWMPconfirmationInterval, mask, + NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, + nla_get_u16); if (mask_out) *mask_out = mask; -- GitLab From 58886a9011f8eae705b9f585ec6c80b34f3c4e6c Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Fri, 15 Jun 2012 00:23:53 +0800 Subject: [PATCH 1868/6849] mac80211: fix the assignment of mesh element TTL This patch fixes the wrong assignment of mesh element TTL. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6e25ac4873c7..17162fcc24bc 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1530,7 +1530,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) conf->dot11MeshTTL = nconf->dot11MeshTTL; if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) - conf->dot11MeshTTL = nconf->element_ttl; + conf->element_ttl = nconf->element_ttl; if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) conf->auto_open_plinks = nconf->auto_open_plinks; if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) -- GitLab From 230a5a1c41464f7fe5b676c21280ae4effa222c8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 15 Jun 2012 18:25:08 +0100 Subject: [PATCH 1869/6849] regulator: Fix double free in devm_regulator_put() Signed-off-by: Mark Brown --- drivers/regulator/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 663ebd534ef9..729b20d1c1de 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1461,9 +1461,7 @@ void devm_regulator_put(struct regulator *regulator) rc = devres_release(regulator->dev, devm_regulator_release, devm_regulator_match, regulator); - if (rc == 0) - regulator_put(regulator); - else + if (rc != 0) WARN_ON(rc); } EXPORT_SYMBOL_GPL(devm_regulator_put); -- GitLab From 08aed2f6fb09c9f8efc9258c152072ed614db226 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 20:14:24 +0800 Subject: [PATCH 1870/6849] regulator: stubs: Make stub regulator_get_voltage() return an error Returning 0 isn't useful, it's not even meaningful if there is a real regulator there. Reported-by: Guennadi Liakhovetski Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 4ed1b30ac5fc..9ff29ef317c2 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -291,7 +291,7 @@ static inline int regulator_set_voltage(struct regulator *regulator, static inline int regulator_get_voltage(struct regulator *regulator) { - return 0; + return -EINVAL; } static inline int regulator_set_current_limit(struct regulator *regulator, -- GitLab From 0e8e5c34cf1a8beaaf0a6a05c053592693bf8cb4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Jun 2012 17:23:13 +0100 Subject: [PATCH 1871/6849] regulator: twl: Remove references to 32kHz clock from DT bindings Due to the lack of a generic clock API we'd had the 32kHz clock in the regulator driver but this is definitely a Linux-specific thing and now we have a clock API hopefully the code can be moved elsewhere. Try to avoid getting DTs deployed relying on the 32kHz clock by removing it from the bindings, grep seems to tell me it's not currently used anyway. Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/twl-regulator.txt | 1 - drivers/regulator/twl-regulator.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/twl-regulator.txt b/Documentation/devicetree/bindings/regulator/twl-regulator.txt index 0c3395d55ac1..658749b90b97 100644 --- a/Documentation/devicetree/bindings/regulator/twl-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/twl-regulator.txt @@ -15,7 +15,6 @@ For twl6030 regulators/LDOs - "ti,twl6030-vusb" for VUSB LDO - "ti,twl6030-v1v8" for V1V8 LDO - "ti,twl6030-v2v1" for V2V1 LDO - - "ti,twl6030-clk32kg" for CLK32KG RESOURCE - "ti,twl6030-vdd1" for VDD1 SMPS - "ti,twl6030-vdd2" for VDD2 SMPS - "ti,twl6030-vdd3" for VDD3 SMPS diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index a1d07e517db3..ca308cb8e676 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1106,7 +1106,6 @@ static u8 twl_get_smps_mult(void) #define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label) #define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label) #define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label) -#define TWLRES_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLRES, label) #define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label) static const struct of_device_id twl_of_match[] __devinitconst = { @@ -1154,7 +1153,6 @@ static const struct of_device_id twl_of_match[] __devinitconst = { TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB), TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8), TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1), - TWLRES_OF_MATCH("ti,twl6030-clk32kg", CLK32KG), TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3), TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4), TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO), -- GitLab From 2a4c8994eeef50796015f8a2005e4a75c1929166 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 14 Jun 2012 13:08:38 -0400 Subject: [PATCH 1872/6849] NFSv4.1: Fix umount when filelayout DS is also the MDS Currently there is a 'chicken and egg' issue when the DS is also the mounted MDS. The nfs_match_client() reference from nfs4_set_ds_client bumps the cl_count, the nfs_client is not freed at umount, and nfs4_deviceid_purge_client is not called to dereference the MDS usage of a deviceid which holds a reference to the DS nfs_client. The result is the umount program returns, but the nfs_client is not freed, and the cl_session hearbeat continues. The MDS (and all other nfs mounts) lose their last nfs_client reference in nfs_free_server when the last nfs_server (fsid) is umounted. The file layout DS lose their last nfs_client reference in destroy_ds when the last deviceid referencing the data server is put and destroy_ds is called. This is triggered by a call to nfs4_deviceid_purge_client which removes references to a pNFS deviceid used by an MDS mount. The fix is to track how many pnfs enabled filesystems are mounted from this server, and then to purge the device id cache once that count reaches zero. Reported-by: Jorge Mora Reported-by: Andy Adamson Signed-off-by: Trond Myklebust --- fs/nfs/client.c | 1 - fs/nfs/pnfs.c | 5 +++++ include/linux/nfs_fs_sb.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 17ba6b995659..f005b5bebdc7 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -207,7 +207,6 @@ error_0: static void nfs4_shutdown_session(struct nfs_client *clp) { if (nfs4_has_session(clp)) { - nfs4_deviceid_purge_client(clp); nfs4_destroy_session(clp->cl_session); nfs4_destroy_clientid(clp); } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b8323aa7b543..bdf7e52943c8 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -80,6 +80,9 @@ unset_pnfs_layoutdriver(struct nfs_server *nfss) if (nfss->pnfs_curr_ld) { if (nfss->pnfs_curr_ld->clear_layoutdriver) nfss->pnfs_curr_ld->clear_layoutdriver(nfss); + /* Decrement the MDS count. Purge the deviceid cache if zero */ + if (atomic_dec_and_test(&nfss->nfs_client->cl_mds_count)) + nfs4_deviceid_purge_client(nfss->nfs_client); module_put(nfss->pnfs_curr_ld->owner); } nfss->pnfs_curr_ld = NULL; @@ -127,6 +130,8 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, module_put(ld_type->owner); goto out_no_driver; } + /* Bump the MDS count */ + atomic_inc(&server->nfs_client->cl_mds_count); dprintk("%s: pNFS module for %u set\n", __func__, id); return; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index fbb78fb09bd2..f58325a1d8fb 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -25,6 +25,7 @@ struct nfs41_impl_id; */ struct nfs_client { atomic_t cl_count; + atomic_t cl_mds_count; int cl_cons_state; /* current construction state (-ve: init error) */ #define NFS_CS_READY 0 /* ready to be used */ #define NFS_CS_INITING 1 /* busy initialising */ -- GitLab From 9900b4b48b095895cf962054e45aafa49ef70f74 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 15 Jun 2012 15:07:02 -0400 Subject: [PATCH 1873/6849] KVM: use KVM_CAP_IRQ_ROUTING to protect the routing related code The KVM code sometimes uses CONFIG_HAVE_KVM_IRQCHIP to protect code that is related to IRQ routing, which not all in-kernel irqchips may support. Use KVM_CAP_IRQ_ROUTING instead. Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 27ac8a4767fa..c7f77876c9b3 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -802,7 +802,7 @@ static inline int mmu_notifier_retry(struct kvm_vcpu *vcpu, unsigned long mmu_se } #endif -#ifdef CONFIG_HAVE_KVM_IRQCHIP +#ifdef KVM_CAP_IRQ_ROUTING #define KVM_MAX_IRQ_ROUTES 1024 diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 02cb440f802d..636bd08bb399 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2225,7 +2225,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) case KVM_CAP_SIGNAL_MSI: #endif return 1; -#ifdef CONFIG_HAVE_KVM_IRQCHIP +#ifdef KVM_CAP_IRQ_ROUTING case KVM_CAP_IRQ_ROUTING: return KVM_MAX_IRQ_ROUTES; #endif -- GitLab From a1e4ccb990447df0fe83d164d9a7bc2e6c4b7db7 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Fri, 15 Jun 2012 15:07:13 -0400 Subject: [PATCH 1874/6849] KVM: Introduce __KVM_HAVE_IRQ_LINE This is a preparatory patch for the KVM/ARM implementation. KVM/ARM will use the KVM_IRQ_LINE ioctl, which is currently conditional on __KVM_HAVE_IOAPIC, but ARM obviously doesn't have any IOAPIC support and we need a separate define. Signed-off-by: Christoffer Dall Signed-off-by: Avi Kivity --- arch/ia64/include/asm/kvm.h | 1 + arch/x86/include/asm/kvm.h | 1 + include/trace/events/kvm.h | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h index b9f82c84f093..ec6c6b301238 100644 --- a/arch/ia64/include/asm/kvm.h +++ b/arch/ia64/include/asm/kvm.h @@ -26,6 +26,7 @@ /* Select x86 specific features in */ #define __KVM_HAVE_IOAPIC +#define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_DEVICE_ASSIGNMENT /* Architectural interrupt line count. */ diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index e7d1c194d272..246617efd67f 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h @@ -12,6 +12,7 @@ /* Select x86 specific features in */ #define __KVM_HAVE_PIT #define __KVM_HAVE_IOAPIC +#define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_DEVICE_ASSIGNMENT #define __KVM_HAVE_MSI #define __KVM_HAVE_USER_NMI diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 3df5925fe641..7ef9e759f499 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -37,7 +37,7 @@ TRACE_EVENT(kvm_userspace_exit, __entry->errno < 0 ? -__entry->errno : __entry->reason) ); -#if defined(__KVM_HAVE_IOAPIC) +#if defined(__KVM_HAVE_IRQ_LINE) TRACE_EVENT(kvm_set_irq, TP_PROTO(unsigned int gsi, int level, int irq_source_id), TP_ARGS(gsi, level, irq_source_id), @@ -57,7 +57,9 @@ TRACE_EVENT(kvm_set_irq, TP_printk("gsi %u level %d source %d", __entry->gsi, __entry->level, __entry->irq_source_id) ); +#endif +#if defined(__KVM_HAVE_IOAPIC) #define kvm_deliver_mode \ {0x0, "Fixed"}, \ {0x1, "LowPrio"}, \ -- GitLab From 25976a796cca22d6b0b2e9f821fa00fc4d98daa0 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Sun, 17 Jun 2012 18:52:34 +0800 Subject: [PATCH 1875/6849] HID: select NEW_LEDS for driver of Lenovo ThinkPad USB Keyboard with TrackPoint commit 'HID: Driver for Lenovo Keyboard with Trackpoint' (c1dcad2d32d0252e8a3023d20311b52a187ecda3) introduced a compiling error due to unmetting dependency of CONFIG_LEDS_CLASS. on i386: ERROR: "led_brightness_set" [drivers/leds/led-class.ko] undefined! ERROR: "leds_list" [drivers/leds/led-class.ko] undefined! ERROR: "leds_list_lock" [drivers/leds/led-class.ko] undefined! Reported-by: Randy Dunlap Signed-off-by: Bryan Wu Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index ca7e76cab83d..cbf0e0344e3e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -271,6 +271,7 @@ config HID_LCPOWER config HID_LENOVO_TPKBD tristate "Lenovo ThinkPad USB Keyboard with TrackPoint" depends on USB_HID + select NEW_LEDS select LEDS_CLASS ---help--- Support for the Lenovo ThinkPad USB Keyboard with TrackPoint. -- GitLab From 93b3cca1ccd30b1ad290951a3fc7c10c73db7313 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Jun 2012 10:54:28 -0400 Subject: [PATCH 1876/6849] ftrace: Make all inline tags also include notrace Commit 5963e317b1e9d2a ("ftrace/x86: Do not change stacks in DEBUG when calling lockdep") prevented lockdep calls from the int3 breakpoint handler from reseting the stack if a function that was called was in the process of being converted for tracing and had a breakpoint on it. The idea is, before calling the lockdep code, do a load_idt() to the special IDT that kept the breakpoint stack from reseting. This worked well as a quick fix for this kernel release, until a certain config caused a lockup in the function tracer start up tests. Investigating it, I found that the load_idt that was used to prevent the int3 from changing stacks was itself being traced! Even though the config had CONFIG_OPTIMIZE_INLINING disabled, and all 'inline' tags were set to always inline, there were still cases that it did not inline! This was caused by CONFIG_PARAVIRT_GUEST, where it would add a pointer to the native_load_idt() which made that function to be traced. Commit 45959ee7aa645815a ("ftrace: Do not function trace inlined functions") only touched the 'inline' tags when CONFIG_OPMITIZE_INLINING was enabled. PARAVIRT_GUEST shows that this was not enough and we need to also mark always_inline with notrace as well. Reported-by: Fengguang Wu Tested-by: Fengguang Wu Signed-off-by: Steven Rostedt --- include/linux/compiler-gcc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index e5834aa24b9e..6a6d7aefe12d 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -47,9 +47,9 @@ */ #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -# define inline inline __attribute__((always_inline)) -# define __inline__ __inline__ __attribute__((always_inline)) -# define __inline __inline __attribute__((always_inline)) +# define inline inline __attribute__((always_inline)) notrace +# define __inline__ __inline__ __attribute__((always_inline)) notrace +# define __inline __inline __attribute__((always_inline)) notrace #else /* A lot of inline functions can cause havoc with function tracing */ # define inline inline notrace -- GitLab From 2992c542fcd40777ed253f57362c65711fb8acaf Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 16 Jun 2012 14:45:49 +0200 Subject: [PATCH 1877/6849] perf/x86: Lowercase uncore PMU event names Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-ucnds8gkve4x3s4biuukyph3@git.kernel.org [ Trivial build fix ] Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 51 ++++++------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index d34f68bf990b..28a8413ca199 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -179,22 +179,17 @@ static struct attribute *snbep_uncore_pcu_formats_attr[] = { }; static struct uncore_event_desc snbep_uncore_imc_events[] = { - INTEL_UNCORE_EVENT_DESC(CLOCKTICKS, "config=0xffff"), - /* read */ - INTEL_UNCORE_EVENT_DESC(CAS_COUNT_RD, "event=0x4,umask=0x3"), - /* write */ - INTEL_UNCORE_EVENT_DESC(CAS_COUNT_WR, "event=0x4,umask=0xc"), + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0xff"), + INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"), + INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"), { /* end: all zeroes */ }, }; static struct uncore_event_desc snbep_uncore_qpi_events[] = { - INTEL_UNCORE_EVENT_DESC(CLOCKTICKS, "event=0x14"), - /* outgoing data+nondata flits */ - INTEL_UNCORE_EVENT_DESC(TxL_FLITS_ACTIVE, "event=0x0,umask=0x6"), - /* DRS data received */ - INTEL_UNCORE_EVENT_DESC(DRS_DATA, "event=0x2,umask=0x8"), - /* NCB data received */ - INTEL_UNCORE_EVENT_DESC(NCB_DATA, "event=0x3,umask=0x4"), + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), + INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), + INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"), + INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"), { /* end: all zeroes */ }, }; @@ -621,29 +616,15 @@ static struct attribute_group nhm_uncore_format_group = { }; static struct uncore_event_desc nhm_uncore_events[] = { - INTEL_UNCORE_EVENT_DESC(CLOCKTICKS, "config=0xffff"), - /* full cache line writes to DRAM */ - INTEL_UNCORE_EVENT_DESC(QMC_WRITES_FULL_ANY, "event=0x2f,umask=0xf"), - /* Quickpath Memory Controller normal priority read requests */ - INTEL_UNCORE_EVENT_DESC(QMC_NORMAL_READS_ANY, "event=0x2c,umask=0xf"), - /* Quickpath Home Logic read requests from the IOH */ - INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_IOH_READS, - "event=0x20,umask=0x1"), - /* Quickpath Home Logic write requests from the IOH */ - INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_IOH_WRITES, - "event=0x20,umask=0x2"), - /* Quickpath Home Logic read requests from a remote socket */ - INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_REMOTE_READS, - "event=0x20,umask=0x4"), - /* Quickpath Home Logic write requests from a remote socket */ - INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_REMOTE_WRITES, - "event=0x20,umask=0x8"), - /* Quickpath Home Logic read requests from the local socket */ - INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_LOCAL_READS, - "event=0x20,umask=0x10"), - /* Quickpath Home Logic write requests from the local socket */ - INTEL_UNCORE_EVENT_DESC(QHL_REQUEST_LOCAL_WRITES, - "event=0x20,umask=0x20"), + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0xff"), + INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"), + INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"), + INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"), + INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"), + INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"), + INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"), + INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"), + INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"), { /* end: all zeroes */ }, }; -- GitLab From e0815f35ccd276a903298ad4c3d8d10b65933b86 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Jun 2012 16:58:49 -0300 Subject: [PATCH 1878/6849] ALSA: maestro3: Remove unused AC97 register definitions Signed-off-by: Ezequiel Garcia Signed-off-by: Takashi Iwai --- sound/pci/maestro3.c | 68 -------------------------------------------- 1 file changed, 68 deletions(-) diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index deef21399586..adb3b4c7917e 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -361,74 +361,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)"); #define DSP2HOST_REQ_I2SRATE 0x02 #define DSP2HOST_REQ_TIMER 0x04 -/* AC97 registers */ -/* XXX fix this crap up */ -/*#define AC97_RESET 0x00*/ - -#define AC97_VOL_MUTE_B 0x8000 -#define AC97_VOL_M 0x1F -#define AC97_LEFT_VOL_S 8 - -#define AC97_MASTER_VOL 0x02 -#define AC97_LINE_LEVEL_VOL 0x04 -#define AC97_MASTER_MONO_VOL 0x06 -#define AC97_PC_BEEP_VOL 0x0A -#define AC97_PC_BEEP_VOL_M 0x0F -#define AC97_SROUND_MASTER_VOL 0x38 -#define AC97_PC_BEEP_VOL_S 1 - -/*#define AC97_PHONE_VOL 0x0C -#define AC97_MIC_VOL 0x0E*/ -#define AC97_MIC_20DB_ENABLE 0x40 - -/*#define AC97_LINEIN_VOL 0x10 -#define AC97_CD_VOL 0x12 -#define AC97_VIDEO_VOL 0x14 -#define AC97_AUX_VOL 0x16*/ -#define AC97_PCM_OUT_VOL 0x18 -/*#define AC97_RECORD_SELECT 0x1A*/ -#define AC97_RECORD_MIC 0x00 -#define AC97_RECORD_CD 0x01 -#define AC97_RECORD_VIDEO 0x02 -#define AC97_RECORD_AUX 0x03 -#define AC97_RECORD_MONO_MUX 0x02 -#define AC97_RECORD_DIGITAL 0x03 -#define AC97_RECORD_LINE 0x04 -#define AC97_RECORD_STEREO 0x05 -#define AC97_RECORD_MONO 0x06 -#define AC97_RECORD_PHONE 0x07 - -/*#define AC97_RECORD_GAIN 0x1C*/ -#define AC97_RECORD_VOL_M 0x0F - -/*#define AC97_GENERAL_PURPOSE 0x20*/ -#define AC97_POWER_DOWN_CTRL 0x26 -#define AC97_ADC_READY 0x0001 -#define AC97_DAC_READY 0x0002 -#define AC97_ANALOG_READY 0x0004 -#define AC97_VREF_ON 0x0008 -#define AC97_PR0 0x0100 -#define AC97_PR1 0x0200 -#define AC97_PR2 0x0400 -#define AC97_PR3 0x0800 -#define AC97_PR4 0x1000 - -#define AC97_RESERVED1 0x28 - -#define AC97_VENDOR_TEST 0x5A - -#define AC97_CLOCK_DELAY 0x5C -#define AC97_LINEOUT_MUX_SEL 0x0001 -#define AC97_MONO_MUX_SEL 0x0002 -#define AC97_CLOCK_DELAY_SEL 0x1F -#define AC97_DAC_CDS_SHIFT 6 -#define AC97_ADC_CDS_SHIFT 11 - -#define AC97_MULTI_CHANNEL_SEL 0x74 - -/*#define AC97_VENDOR_ID1 0x7C -#define AC97_VENDOR_ID2 0x7E*/ - /* * ASSP control regs */ -- GitLab From ac6e4c1560f8d3d18e6ba265d84ff03810496f4f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 26 May 2012 15:25:26 -0300 Subject: [PATCH 1879/6849] [media] USB: Staging: media: lirc: initialize spinlocks before usage Initialize the spinlock for each hardware time. Signed-off-by: Sasha Levin Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_serial.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 3295ea63f3eb..97ef67036e3f 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -129,6 +129,7 @@ static void send_space_homebrew(long length); static struct lirc_serial hardware[] = { [LIRC_HOMEBREW] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_HOMEBREW].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -145,6 +146,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = UART_MCR_OUT2, @@ -156,6 +158,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO_REMOTE] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO_REMOTE].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), @@ -167,6 +170,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_ANIMAX] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_ANIMAX].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = 0, @@ -177,6 +181,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IGOR] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IGOR].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -201,6 +206,7 @@ static struct lirc_serial hardware[] = { * See also http://www.nslu2-linux.org for this device */ [LIRC_NSLU2] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_NSLU2].lock), .signal_pin = UART_MSR_CTS, .signal_pin_change = UART_MSR_DCTS, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), -- GitLab From bdca5036332311bea183dc628c69e3cb50a9369e Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Tue, 29 May 2012 17:19:27 -0300 Subject: [PATCH 1880/6849] [media] em28xx: Add remote control support for Terratec's Cinergy HTC Stick HD The Cinergy HTC Stick HD uses the same remote control as the TerraTec Cinergy XS products. Thus the same keymap could be re-used. Signed-off-by: Martin Blumenstingl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 20a7e24de6fb..92da7c28b6f0 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -974,6 +974,7 @@ struct em28xx_board em28xx_boards[] = { [EM2884_BOARD_CINERGY_HTC_STICK] = { .name = "Terratec Cinergy HTC Stick", .has_dvb = 1, + .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, #if 0 .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x41, -- GitLab From b83f671566f8a3b9796bed7416d25e07866ff408 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 30 May 2012 15:47:40 -0300 Subject: [PATCH 1881/6849] [media] em28xx: Show a warning if the board does not support remote controls This simply shows a little warning if the board does not have remote control support. This should make it easier for users to see if they have misconfigured their system or if the driver simply does not have rc-support for their card (yet). Signed-off-by: Martin Blumenstingl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-input.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index fce5f7680c99..5e30c4f3f248 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -527,6 +527,8 @@ static int em28xx_ir_init(struct em28xx *dev) if (dev->board.ir_codes == NULL) { /* No remote control support */ + em28xx_warn("Remote control support is not available for " + "this card.\n"); return 0; } -- GitLab From 1a8b294ce6b0cdab438175eed45ebb088bdd659a Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 18 Jun 2012 17:08:08 +0200 Subject: [PATCH 1882/6849] HID: uhid: silence gcc warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc is giving me: drivers/hid/uhid.c: In function ‘uhid_hid_get_raw’: drivers/hid/uhid.c:157: warning: ‘len’ may be used uninitialized in this function which is clearly bogus, as - when used as memcpy() argument, it's initialized properly - the code is structured in a way that either 'ret' or 'len' is always initialized, so the return statement always has an initialized value. Signed-off-by: Jiri Kosina --- drivers/hid/uhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index ea560bfa033d..119b7e6405be 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -154,7 +154,7 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, struct uhid_event *ev; unsigned long flags; int ret; - size_t len; + size_t uninitialized_var(len); struct uhid_feature_answer_req *req; if (!uhid->running) -- GitLab From ac852edb47b15900886ba2564eeeb13b3b526e3e Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 7 Jun 2012 04:54:29 -0400 Subject: [PATCH 1883/6849] hwmon: (applesmc) Limit key length in warning messages Key lookups may call read_smc() with a fixed-length key string, and if the lookup fails, trailing stack content may appear in the kernel log. Fixed with this patch. Signed-off-by: Henrik Rydberg Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f082e48ab113..70d62f5bc909 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) int i; if (send_command(cmd) || send_argument(key)) { - pr_warn("%s: read arg fail\n", key); + pr_warn("%.4s: read arg fail\n", key); return -EIO; } @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) for (i = 0; i < len; i++) { if (__wait_status(0x05)) { - pr_warn("%s: read data fail\n", key); + pr_warn("%.4s: read data fail\n", key); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); -- GitLab From 2355375efdf10f43680d420023baa97796bfcdff Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 10:16:32 -0700 Subject: [PATCH 1884/6849] hwmon: (emc2103) Fix use of an uninitilized variable in error case Fix: emc2103.c: In function set_pwm_enable: emc2103.c:463:12: warning: conf_reg may be used uninitialized in this function by checking the return value from read_u8_from_i2c(). This fixes a real problem, as conf_reg is really uninitialized if read_u8_from_i2c returns an error. Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson Acked-by: Jean Delvare --- drivers/hwmon/emc2103.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index 9691f664c76e..e7d234b59312 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -451,11 +451,15 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, data->fan_rpm_control = true; break; default: - mutex_unlock(&data->update_lock); - return -EINVAL; + count = -EINVAL; + goto err; } - read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + if (result) { + count = result; + goto err; + } if (data->fan_rpm_control) conf_reg |= 0x80; @@ -463,7 +467,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, conf_reg &= ~0x80; i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); - +err: mutex_unlock(&data->update_lock); return count; } -- GitLab From 284fefd59ae0357695b17b59cb44d7cc12445bb5 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 17 Jun 2012 13:26:37 +0200 Subject: [PATCH 1885/6849] batman-adv: update internal version number Signed-off-by: Sven Eckelmann --- net/batman-adv/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index f4a3ec003479..630bbe8968ca 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -28,7 +28,7 @@ #define DRIVER_DEVICE "batman-adv" #ifndef SOURCE_VERSION -#define SOURCE_VERSION "2012.2.0" +#define SOURCE_VERSION "2012.3.0" #endif /* B.A.T.M.A.N. parameters */ -- GitLab From d2b6cc8e460494251442a877fcbc150faa175b4f Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 14 Jun 2012 22:21:28 +0200 Subject: [PATCH 1886/6849] batman-adv: fix skb->data assignment skb_linearize(skb) possibly rearranges the skb internal data and then changes the skb->data pointer value. For this reason any other pointer in the code that was assigned skb->data before invoking skb_linearise(skb) must be re-assigned. In the current tt_query message handling code this is not done and therefore, in case of skb linearization, the pointer used to handle the packet header ends up in pointing to poisoned memory. The packet is then dropped but the translation-table mechanism is corrupted. Signed-off-by: Antonio Quartulli Cc: Signed-off-by: Sven Eckelmann --- net/batman-adv/routing.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 840e2c64a301..015471d801b4 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -617,6 +617,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) * changes */ if (skb_linearize(skb) < 0) goto out; + /* skb_linearize() possibly changed skb->data */ + tt_query = (struct tt_query_packet *)skb->data; tt_len = tt_query->tt_data * sizeof(struct tt_change); -- GitLab From 5d52dad27a08d2c8851acb12b041088ec07881dd Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 29 Mar 2012 12:38:20 +0200 Subject: [PATCH 1887/6849] batman-adv: Initialize lockdep class keys for hashes The hash for claim and backbone hash in the bridge loop avoidance code receive the same key because they are getting initialized by hash_new with the same key. Lockdep will create a backtrace when they are used recursively. This can be avoided by reinitializing the key directly after the hash_new. Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 13 +++++++++++++ net/batman-adv/hash.c | 9 +++++++++ net/batman-adv/hash.h | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 8bf97515a77d..5c1ac559edbb 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1127,6 +1127,14 @@ out: bla_start_timer(bat_priv); } +/* The hash for claim and backbone hash receive the same key because they + * are getting initialized by hash_new with the same key. Reinitializing + * them with to different keys to allow nested locking without generating + * lockdep warnings + */ +static struct lock_class_key claim_hash_lock_class_key; +static struct lock_class_key backbone_hash_lock_class_key; + /* initialize all bla structures */ int bla_init(struct bat_priv *bat_priv) { @@ -1164,6 +1172,11 @@ int bla_init(struct bat_priv *bat_priv) if (!bat_priv->claim_hash || !bat_priv->backbone_hash) return -1; + batadv_hash_set_lock_class(bat_priv->claim_hash, + &claim_hash_lock_class_key); + batadv_hash_set_lock_class(bat_priv->backbone_hash, + &backbone_hash_lock_class_key); + bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); bla_start_timer(bat_priv); diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index 117687bedf25..5b2eabe7c4e0 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c @@ -69,3 +69,12 @@ free_hash: kfree(hash); return NULL; } + +void batadv_hash_set_lock_class(struct hashtable_t *hash, + struct lock_class_key *key) +{ + uint32_t i; + + for (i = 0; i < hash->size; i++) + lockdep_set_class(&hash->list_locks[i], key); +} diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index d4bd7862719b..93b3c71aeaf8 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h @@ -45,6 +45,10 @@ struct hashtable_t { /* allocates and clears the hash */ struct hashtable_t *hash_new(uint32_t size); +/* set class key for all locks */ +void batadv_hash_set_lock_class(struct hashtable_t *hash, + struct lock_class_key *key); + /* free only the hashtable and the hash itself. */ void hash_destroy(struct hashtable_t *hash); -- GitLab From 66a1b2bcb34b0c74a3422968b15a7ea853ea5a2d Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Sat, 14 Apr 2012 13:15:26 +0200 Subject: [PATCH 1888/6849] batman-adv: convert bat_priv->tt_crc from atomic_t to uint16_t In the code we neever need to atomically check and set the bat_priv->tt_crc field value. It is simply set and read once in different pieces of the code. Therefore this field can be safely be converted from atomic_t to uint16_t. Reported-by: Al Viro Signed-off-by: Antonio Quartulli Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 3 +-- net/batman-adv/send.c | 2 +- net/batman-adv/types.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index dc53798ebb47..ec351199c652 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -575,8 +575,7 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface, htonl((uint32_t)atomic_read(&hard_iface->seqno)); batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); - batman_ogm_packet->tt_crc = htons((uint16_t) - atomic_read(&bat_priv->tt_crc)); + batman_ogm_packet->tt_crc = htons(bat_priv->tt_crc); if (tt_num_changes >= 0) batman_ogm_packet->tt_num_changes = tt_num_changes; diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index f47299f22c68..f5ff36492b2f 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -111,7 +111,7 @@ static int prepare_packet_buffer(struct bat_priv *bat_priv, realloc_packet_buffer(hard_iface, new_len); - atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv)); + bat_priv->tt_crc = tt_local_crc(bat_priv); /* reset the sending counter */ atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 61308e8016ff..547dc339f33d 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -210,7 +210,7 @@ struct bat_priv { spinlock_t vis_list_lock; /* protects vis_info::recv_list */ atomic_t num_local_tt; /* Checksum of the local table, recomputed before sending a new OGM */ - atomic_t tt_crc; + uint16_t tt_crc; unsigned char *tt_buff; int16_t tt_buff_len; spinlock_t tt_buff_lock; /* protects tt_buff */ -- GitLab From f8214865a55f805e65c33350bc0f1eb46dd8433d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Hundeb=C3=B8ll?= Date: Fri, 20 Apr 2012 17:02:45 +0200 Subject: [PATCH 1889/6849] batman-adv: Add get_ethtool_stats() support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added additional counters in a bat_stats structure, which are exported through the ethtool api. The counters are specific to batman-adv and includes: forwarded packets and bytes management packets and bytes (aggregated OGMs at this point) translation table packets New counters are added by extending "enum bat_counters" in types.h and adding corresponding descriptive string(s) to bat_counters_strings in soft-iface.c. Counters are increased by calling batadv_add_counter() and incremented by one by calling batadv_inc_counter(). Signed-off-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- Documentation/networking/batman-adv.txt | 5 ++ net/batman-adv/bat_iv_ogm.c | 10 +++- net/batman-adv/main.c | 2 + net/batman-adv/main.h | 27 ++++++++++ net/batman-adv/routing.c | 11 +++++ net/batman-adv/soft-interface.c | 66 ++++++++++++++++++++++++- net/batman-adv/translation-table.c | 8 +++ net/batman-adv/types.h | 17 +++++++ 8 files changed, 143 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index 75a592365af9..8f3ae4a6147e 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt @@ -211,6 +211,11 @@ The debug output can be changed at runtime using the file will enable debug messages for when routes change. +Counters for different types of packets entering and leaving the +batman-adv module are available through ethtool: + +# ethtool --statistics bat0 + BATCTL ------ diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index ec351199c652..99ec218df7f2 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -196,8 +196,12 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, /* create clone because function is called more than once */ skb = skb_clone(forw_packet->skb, GFP_ATOMIC); - if (skb) + if (skb) { + batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX); + batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES, + skb->len + ETH_HLEN); send_skb_packet(skb, hard_iface, broadcast_addr); + } } /* send a batman ogm packet */ @@ -1203,6 +1207,10 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) return NET_RX_DROP; + batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX); + batadv_add_counter(bat_priv, BAT_CNT_MGMT_RX_BYTES, + skb->len + ETH_HLEN); + packet_len = skb_headlen(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb); packet_buff = skb->data; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 083a2993efe4..bd83aa4e7c87 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -153,6 +153,8 @@ void mesh_free(struct net_device *soft_iface) bla_free(bat_priv); + free_percpu(bat_priv->bat_counters); + atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); } diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 630bbe8968ca..6e0cbdc48321 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -138,6 +138,7 @@ enum dbg_level { #include /* kernel threads */ #include /* schedule types */ #include /* workqueue */ +#include #include #include /* struct sock */ #include @@ -242,4 +243,30 @@ static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout) _dummy > smallest_signed_int(_dummy); }) #define seq_after(x, y) seq_before(y, x) +/* Stop preemption on local cpu while incrementing the counter */ +static inline void batadv_add_counter(struct bat_priv *bat_priv, size_t idx, + size_t count) +{ + int cpu = get_cpu(); + per_cpu_ptr(bat_priv->bat_counters, cpu)[idx] += count; + put_cpu(); +} + +#define batadv_inc_counter(b, i) batadv_add_counter(b, i, 1) + +/* Sum and return the cpu-local counters for index 'idx' */ +static inline uint64_t batadv_sum_counter(struct bat_priv *bat_priv, size_t idx) +{ + uint64_t *counters; + int cpu; + int sum = 0; + + for_each_possible_cpu(cpu) { + counters = per_cpu_ptr(bat_priv->bat_counters, cpu); + sum += counters[idx]; + } + + return sum; +} + #endif /* _NET_BATMAN_ADV_MAIN_H_ */ diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 015471d801b4..369604c99a46 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -600,6 +600,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) switch (tt_query->flags & TT_QUERY_TYPE_MASK) { case TT_REQUEST: + batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX); + /* If we cannot provide an answer the tt_request is * forwarded */ if (!send_tt_response(bat_priv, tt_query)) { @@ -612,6 +614,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) } break; case TT_RESPONSE: + batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_RX); + if (is_my_mac(tt_query->dst)) { /* packet needs to be linearized to access the TT * changes */ @@ -665,6 +669,8 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) if (is_broadcast_ether_addr(ethhdr->h_source)) goto out; + batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_RX); + roam_adv_packet = (struct roam_adv_packet *)skb->data; if (!is_my_mac(roam_adv_packet->dst)) @@ -872,6 +878,11 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* decrement ttl */ unicast_packet->header.ttl--; + /* Update stats counter */ + batadv_inc_counter(bat_priv, BAT_CNT_FORWARD); + batadv_add_counter(bat_priv, BAT_CNT_FORWARD_BYTES, + skb->len + ETH_HLEN); + /* route it */ send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = NET_RX_SUCCESS; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 6e2530b02043..304a7ba09e03 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -45,6 +45,10 @@ static void bat_get_drvinfo(struct net_device *dev, static u32 bat_get_msglevel(struct net_device *dev); static void bat_set_msglevel(struct net_device *dev, u32 value); static u32 bat_get_link(struct net_device *dev); +static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data); +static void batadv_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data); +static int batadv_get_sset_count(struct net_device *dev, int stringset); static const struct ethtool_ops bat_ethtool_ops = { .get_settings = bat_get_settings, @@ -52,6 +56,9 @@ static const struct ethtool_ops bat_ethtool_ops = { .get_msglevel = bat_get_msglevel, .set_msglevel = bat_set_msglevel, .get_link = bat_get_link, + .get_strings = batadv_get_strings, + .get_ethtool_stats = batadv_get_ethtool_stats, + .get_sset_count = batadv_get_sset_count, }; int my_skb_head_push(struct sk_buff *skb, unsigned int len) @@ -399,13 +406,18 @@ struct net_device *softif_create(const char *name) bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; + bat_priv->bat_counters = __alloc_percpu(sizeof(uint64_t) * BAT_CNT_NUM, + __alignof__(uint64_t)); + if (!bat_priv->bat_counters) + goto unreg_soft_iface; + ret = bat_algo_select(bat_priv, bat_routing_algo); if (ret < 0) - goto unreg_soft_iface; + goto free_bat_counters; ret = sysfs_add_meshif(soft_iface); if (ret < 0) - goto unreg_soft_iface; + goto free_bat_counters; ret = debugfs_add_meshif(soft_iface); if (ret < 0) @@ -421,6 +433,8 @@ unreg_debugfs: debugfs_del_meshif(soft_iface); unreg_sysfs: sysfs_del_meshif(soft_iface); +free_bat_counters: + free_percpu(bat_priv->bat_counters); unreg_soft_iface: unregister_netdevice(soft_iface); return NULL; @@ -486,3 +500,51 @@ static u32 bat_get_link(struct net_device *dev) { return 1; } + +/* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 + * Declare each description string in struct.name[] to get fixed sized buffer + * and compile time checking for strings longer than ETH_GSTRING_LEN. + */ +static const struct { + const char name[ETH_GSTRING_LEN]; +} bat_counters_strings[] = { + { "forward" }, + { "forward_bytes" }, + { "mgmt_tx" }, + { "mgmt_tx_bytes" }, + { "mgmt_rx" }, + { "mgmt_rx_bytes" }, + { "tt_request_tx" }, + { "tt_request_rx" }, + { "tt_response_tx" }, + { "tt_response_rx" }, + { "tt_roam_adv_tx" }, + { "tt_roam_adv_rx" }, +}; + +static void batadv_get_strings(struct net_device *dev, uint32_t stringset, + uint8_t *data) +{ + if (stringset == ETH_SS_STATS) + memcpy(data, bat_counters_strings, + sizeof(bat_counters_strings)); +} + +static void batadv_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, + uint64_t *data) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + int i; + + for (i = 0; i < BAT_CNT_NUM; i++) + data[i] = batadv_sum_counter(bat_priv, i); +} + +static int batadv_get_sset_count(struct net_device *dev, int stringset) +{ + if (stringset == ETH_SS_STATS) + return BAT_CNT_NUM; + + return -EOPNOTSUPP; +} diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a66c2dcd1088..ca53542e1e8e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1356,6 +1356,8 @@ static int send_tt_request(struct bat_priv *bat_priv, dst_orig_node->orig, neigh_node->addr, (full_table ? 'F' : '.')); + batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_TX); + send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; @@ -1480,6 +1482,8 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, res_dst_orig_node->orig, neigh_node->addr, req_dst_orig_node->orig, req_ttvn); + batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); + send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = true; goto out; @@ -1596,6 +1600,8 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, orig_node->orig, neigh_node->addr, (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); + batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); + send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = true; goto out; @@ -1895,6 +1901,8 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", orig_node->orig, client, neigh_node->addr); + batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_TX); + send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 547dc339f33d..6b569debc1a6 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -148,9 +148,26 @@ struct bcast_duplist_entry { }; #endif +enum bat_counters { + BAT_CNT_FORWARD, + BAT_CNT_FORWARD_BYTES, + BAT_CNT_MGMT_TX, + BAT_CNT_MGMT_TX_BYTES, + BAT_CNT_MGMT_RX, + BAT_CNT_MGMT_RX_BYTES, + BAT_CNT_TT_REQUEST_TX, + BAT_CNT_TT_REQUEST_RX, + BAT_CNT_TT_RESPONSE_TX, + BAT_CNT_TT_RESPONSE_RX, + BAT_CNT_TT_ROAM_ADV_TX, + BAT_CNT_TT_ROAM_ADV_RX, + BAT_CNT_NUM, +}; + struct bat_priv { atomic_t mesh_state; struct net_device_stats stats; + uint64_t __percpu *bat_counters; /* Per cpu counters */ atomic_t aggregated_ogms; /* boolean */ atomic_t bonding; /* boolean */ atomic_t fragmentation; /* boolean */ -- GitLab From 519d3497c667ed2f26f0b7ea56f1451e387264d7 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Wed, 18 Apr 2012 17:15:57 +0800 Subject: [PATCH 1890/6849] batman-adv: avoid characters requiring shell escapes in protocol names Reported-by: Andrew Lunn Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 2 +- net/batman-adv/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 99ec218df7f2..e94ac0b99c65 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1241,7 +1241,7 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, } static struct bat_algo_ops batman_iv __read_mostly = { - .name = "BATMAN IV", + .name = "BATMAN_IV", .bat_iface_enable = bat_iv_ogm_iface_enable, .bat_iface_disable = bat_iv_ogm_iface_disable, .bat_iface_update_mac = bat_iv_ogm_iface_update_mac, diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index bd83aa4e7c87..65b4f0824e4f 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -40,7 +40,7 @@ * list traversals just rcu-locked */ struct list_head hardif_list; static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); -char bat_routing_algo[20] = "BATMAN IV"; +char bat_routing_algo[20] = "BATMAN_IV"; static struct hlist_head bat_algo_list; unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -- GitLab From d8cb548616524e10d36b4241b03893a11655ec5d Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Wed, 18 Apr 2012 17:16:39 +0800 Subject: [PATCH 1891/6849] batman-adv: ignore trailing CR when comparing protocol names Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 65b4f0824e4f..8610b5caa178 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -381,14 +381,19 @@ int bat_algo_seq_print_text(struct seq_file *seq, void *offset) static int param_set_ra(const char *val, const struct kernel_param *kp) { struct bat_algo_ops *bat_algo_ops; + char *algo_name = (char *)val; + size_t name_len = strlen(algo_name); - bat_algo_ops = bat_algo_get((char *)val); + if (algo_name[name_len - 1] == '\n') + algo_name[name_len - 1] = '\0'; + + bat_algo_ops = bat_algo_get(algo_name); if (!bat_algo_ops) { - pr_err("Routing algorithm '%s' is not supported\n", val); + pr_err("Routing algorithm '%s' is not supported\n", algo_name); return -EINVAL; } - return param_set_copystring(val, kp); + return param_set_copystring(algo_name, kp); } static const struct kernel_param_ops param_ops_ra = { -- GitLab From 08ad76ecc9f7f02cbe6ccbaa4abc9e9f193ed0e4 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 23 Apr 2012 16:32:55 +0800 Subject: [PATCH 1892/6849] batman-adv: return added entries instead of number of possibly added entries Signed-off-by: Marek Lindner Acked-by: Antonio Quartulli Signed-off-by: Sven Eckelmann --- net/batman-adv/translation-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index ca53542e1e8e..f9675b7f5f99 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -319,7 +319,7 @@ int tt_changes_fill_buffer(struct bat_priv *bat_priv, } spin_unlock_bh(&bat_priv->tt_buff_lock); - return tot_changes; + return count; } int tt_local_seq_print_text(struct seq_file *seq, void *offset) -- GitLab From 1a5852d81a664e5a6456f82dff6f31b06dc2bede Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Apr 2012 07:50:29 +0100 Subject: [PATCH 1893/6849] batman-adv: get rid of pointless cast in memcpy() memcpy() arguments are void *, precisely to avoid that kind of pointless casts. Signed-off-by: Al Viro Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 5c1ac559edbb..89e2b1cda182 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -510,7 +510,7 @@ static void bla_send_announce(struct bat_priv *bat_priv, memcpy(mac, announce_mac, 4); crc = htons(backbone_gw->crc); - memcpy(&mac[4], (uint8_t *)&crc, 2); + memcpy(&mac[4], &crc, 2); bla_send_claim(bat_priv, mac, backbone_gw->vid, CLAIM_TYPE_ANNOUNCE); -- GitLab From 3e2f1a1bb528df14065a9287f37378ca453c52f9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Apr 2012 07:47:50 +0100 Subject: [PATCH 1894/6849] batman-adv: trivial endianness annotations Signed-off-by: Al Viro Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 6 +++--- net/batman-adv/packet.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 89e2b1cda182..0355c48db282 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -258,7 +258,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, struct net_device *soft_iface; uint8_t *hw_src; struct bla_claim_dst local_claim_dest; - uint32_t zeroip = 0; + __be32 zeroip = 0; primary_if = primary_if_get_selected(bat_priv); if (!primary_if) @@ -506,7 +506,7 @@ static void bla_send_announce(struct bat_priv *bat_priv, struct backbone_gw *backbone_gw) { uint8_t mac[ETH_ALEN]; - uint16_t crc; + __be16 crc; memcpy(mac, announce_mac, 4); crc = htons(backbone_gw->crc); @@ -627,7 +627,7 @@ static int handle_announce(struct bat_priv *bat_priv, /* handle as ANNOUNCE frame */ backbone_gw->lasttime = jiffies; - crc = ntohs(*((uint16_t *)(&an_addr[4]))); + crc = ntohs(*((__be16 *)(&an_addr[4]))); bat_dbg(DBG_BLA, bat_priv, "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n", diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 0ee1af770798..eaa602863fd2 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -105,7 +105,7 @@ enum bla_claimframe { struct bla_claim_dst { uint8_t magic[3]; /* FF:43:05 */ uint8_t type; /* bla_claimframe */ - uint16_t group; /* group id */ + __be16 group; /* group id */ } __packed; struct batman_header { @@ -134,7 +134,7 @@ struct icmp_packet { uint8_t msg_type; /* see ICMP message types above */ uint8_t dst[ETH_ALEN]; uint8_t orig[ETH_ALEN]; - uint16_t seqno; + __be16 seqno; uint8_t uid; uint8_t reserved; } __packed; @@ -148,7 +148,7 @@ struct icmp_packet_rr { uint8_t msg_type; /* see ICMP message types above */ uint8_t dst[ETH_ALEN]; uint8_t orig[ETH_ALEN]; - uint16_t seqno; + __be16 seqno; uint8_t uid; uint8_t rr_cur; uint8_t rr[BAT_RR_LEN][ETH_ALEN]; @@ -167,20 +167,20 @@ struct unicast_frag_packet { uint8_t flags; uint8_t align; uint8_t orig[ETH_ALEN]; - uint16_t seqno; + __be16 seqno; } __packed; struct bcast_packet { struct batman_header header; uint8_t reserved; - uint32_t seqno; + __be32 seqno; uint8_t orig[ETH_ALEN]; } __packed; struct vis_packet { struct batman_header header; uint8_t vis_type; /* which type of vis-participant sent this? */ - uint32_t seqno; /* sequence number */ + __be32 seqno; /* sequence number */ uint8_t entries; /* number of entries behind this struct */ uint8_t reserved; uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */ -- GitLab From e0f5211f9bbfaa66d27cda6b0dc86466c7dcb206 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Apr 2012 07:46:29 +0100 Subject: [PATCH 1895/6849] batman-adv: keep batman_ogm_packet ->seqno net-endian all along Signed-off-by: Al Viro Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 22 +++++++++++----------- net/batman-adv/packet.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index e94ac0b99c65..56b6d78bfbfd 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -34,11 +34,12 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, const uint8_t *neigh_addr, struct orig_node *orig_node, struct orig_node *orig_neigh, - uint32_t seqno) + __be32 seqno) { struct neigh_node *neigh_node; - neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, seqno); + neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, + ntohl(seqno)); if (!neigh_node) goto out; @@ -546,7 +547,6 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, "Forwarding packet: tq: %i, ttl: %i\n", batman_ogm_packet->tq, batman_ogm_packet->header.ttl); - batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); /* switch of primaries first hop flag when forwarding */ @@ -871,13 +871,14 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, int32_t seq_diff; int need_update = 0; int set_mark, ret = -1; + uint32_t seqno = ntohl(batman_ogm_packet->seqno); orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) return 0; spin_lock_bh(&orig_node->ogm_cnt_lock); - seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno; + seq_diff = seqno - orig_node->last_real_seqno; /* signalize caller that the packet is to be dropped. */ if (!hlist_empty(&orig_node->neigh_list) && @@ -891,7 +892,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, is_duplicate |= bat_test_bit(tmp_neigh_node->real_bits, orig_node->last_real_seqno, - batman_ogm_packet->seqno); + seqno); if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) @@ -913,8 +914,8 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, if (need_update) { bat_dbg(DBG_BATMAN, bat_priv, "updating last_seqno: old %u, new %u\n", - orig_node->last_real_seqno, batman_ogm_packet->seqno); - orig_node->last_real_seqno = batman_ogm_packet->seqno; + orig_node->last_real_seqno, seqno); + orig_node->last_real_seqno = seqno; } ret = is_duplicate; @@ -970,7 +971,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", ethhdr->h_source, if_incoming->net_dev->name, if_incoming->net_dev->dev_addr, batman_ogm_packet->orig, - batman_ogm_packet->prev_sender, batman_ogm_packet->seqno, + batman_ogm_packet->prev_sender, ntohl(batman_ogm_packet->seqno), batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc, batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq, batman_ogm_packet->header.ttl, @@ -1042,7 +1043,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, word = &(orig_neigh_node->bcast_own[offset]); bat_set_bit(word, if_incoming_seqno - - batman_ogm_packet->seqno - 2); + ntohl(batman_ogm_packet->seqno) - 2); orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE); spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); @@ -1135,7 +1136,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, * seqno and similar ttl as the non-duplicate */ if (is_bidirectional && (!is_duplicate || - ((orig_node->last_real_seqno == batman_ogm_packet->seqno) && + ((orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno)) && (orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl)))) bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, batman_ogm_packet, if_incoming, @@ -1220,7 +1221,6 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, do { /* network to host order for our 32bit seqno and the orig_interval */ - batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno); batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc); tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN; diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index eaa602863fd2..5bf567b52534 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -117,7 +117,7 @@ struct batman_header { struct batman_ogm_packet { struct batman_header header; uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ - uint32_t seqno; + __be32 seqno; uint8_t orig[ETH_ALEN]; uint8_t prev_sender[ETH_ALEN]; uint8_t gw_flags; /* flags related to gateway class */ -- GitLab From 5346c35ebfbdb1727e60079456dd8071cb888059 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 5 May 2012 13:27:28 +0200 Subject: [PATCH 1896/6849] batman-adv: Return error codes instead of -1 on failures Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 11 +++++++---- net/batman-adv/bat_iv_ogm.c | 2 +- net/batman-adv/bat_sysfs.c | 2 +- net/batman-adv/bridge_loop_avoidance.c | 6 +++--- net/batman-adv/hard-interface.c | 4 +--- net/batman-adv/icmp_socket.c | 4 ++-- net/batman-adv/main.c | 27 +++++++++++++++----------- net/batman-adv/originator.c | 18 ++++++++--------- net/batman-adv/translation-table.c | 24 +++++++++++++---------- net/batman-adv/vis.c | 8 ++++---- 10 files changed, 58 insertions(+), 48 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 3b588f86d770..db8273c26989 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -195,13 +195,13 @@ static int debug_log_setup(struct bat_priv *bat_priv) d = debugfs_create_file("log", S_IFREG | S_IRUSR, bat_priv->debug_dir, bat_priv, &log_fops); - if (d) + if (!d) goto err; return 0; err: - return 1; + return -ENOMEM; } static void debug_log_cleanup(struct bat_priv *bat_priv) @@ -348,8 +348,11 @@ int debugfs_add_meshif(struct net_device *dev) if (!bat_priv->debug_dir) goto out; - bat_socket_setup(bat_priv); - debug_log_setup(bat_priv); + if (bat_socket_setup(bat_priv) < 0) + goto rem_attr; + + if (debug_log_setup(bat_priv) < 0) + goto rem_attr; for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) { file = debugfs_create_file(((*bat_debug)->attr).name, diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 56b6d78bfbfd..896287e62df9 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -60,7 +60,7 @@ static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; uint32_t random_seqno; - int res = -1; + int res = -ENOMEM; /* randomize initial seqno to avoid collision */ get_random_bytes(&random_seqno, sizeof(random_seqno)); diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 5bc7b66d32dc..62f4f6cb888a 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -680,7 +680,7 @@ void sysfs_del_hardif(struct kobject **hardif_obj) int throw_uevent(struct bat_priv *bat_priv, enum uev_type type, enum uev_action action, const char *data) { - int ret = -1; + int ret = -ENOMEM; struct hard_iface *primary_if = NULL; struct kobject *bat_kobj; char *uevent_env[4] = { NULL, NULL, NULL, NULL }; diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 0355c48db282..314e37b272a7 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1164,13 +1164,13 @@ int bla_init(struct bat_priv *bat_priv) bat_priv->bcast_duplist_curr = 0; if (bat_priv->claim_hash) - return 1; + return 0; bat_priv->claim_hash = hash_new(128); bat_priv->backbone_hash = hash_new(32); if (!bat_priv->claim_hash || !bat_priv->backbone_hash) - return -1; + return -ENOMEM; batadv_hash_set_lock_class(bat_priv->claim_hash, &claim_hash_lock_class_key); @@ -1180,7 +1180,7 @@ int bla_init(struct bat_priv *bat_priv) bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); bla_start_timer(bat_priv); - return 1; + return 0; } /** diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index dc334fa89847..ce78c6d645c6 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -306,10 +306,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface, bat_priv = netdev_priv(hard_iface->soft_iface); ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface); - if (ret < 0) { - ret = -ENOMEM; + if (ret < 0) goto err_dev; - } hard_iface->if_num = bat_priv->num_ifaces; bat_priv->num_ifaces++; diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 2e98a57f3407..d27db8192e93 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -285,13 +285,13 @@ int bat_socket_setup(struct bat_priv *bat_priv) d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, bat_priv->debug_dir, bat_priv, &fops); - if (d) + if (!d) goto err; return 0; err: - return 1; + return -ENOMEM; } static void bat_socket_add_packet(struct socket_client *socket_client, diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 8610b5caa178..46ba302d2d01 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -92,6 +92,7 @@ static void __exit batman_exit(void) int mesh_init(struct net_device *soft_iface) { struct bat_priv *bat_priv = netdev_priv(soft_iface); + int ret; spin_lock_init(&bat_priv->forw_bat_list_lock); spin_lock_init(&bat_priv->forw_bcast_list_lock); @@ -110,30 +111,32 @@ int mesh_init(struct net_device *soft_iface) INIT_LIST_HEAD(&bat_priv->tt_req_list); INIT_LIST_HEAD(&bat_priv->tt_roam_list); - if (originator_init(bat_priv) < 1) + ret = originator_init(bat_priv); + if (ret < 0) goto err; - if (tt_init(bat_priv) < 1) + ret = tt_init(bat_priv); + if (ret < 0) goto err; tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); - if (vis_init(bat_priv) < 1) + ret = vis_init(bat_priv); + if (ret < 0) goto err; - if (bla_init(bat_priv) < 1) + ret = bla_init(bat_priv); + if (ret < 0) goto err; atomic_set(&bat_priv->gw_reselect, 0); atomic_set(&bat_priv->mesh_state, MESH_ACTIVE); - goto end; + + return 0; err: mesh_free(soft_iface); - return -1; - -end: - return 0; + return ret; } void mesh_free(struct net_device *soft_iface) @@ -319,12 +322,13 @@ static struct bat_algo_ops *bat_algo_get(char *name) int bat_algo_register(struct bat_algo_ops *bat_algo_ops) { struct bat_algo_ops *bat_algo_ops_tmp; - int ret = -1; + int ret; bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name); if (bat_algo_ops_tmp) { pr_info("Trying to register already registered routing algorithm: %s\n", bat_algo_ops->name); + ret = -EEXIST; goto out; } @@ -337,6 +341,7 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) !bat_algo_ops->bat_ogm_emit) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); + ret = -EINVAL; goto out; } @@ -351,7 +356,7 @@ out: int bat_algo_select(struct bat_priv *bat_priv, char *name) { struct bat_algo_ops *bat_algo_ops; - int ret = -1; + int ret = -EINVAL; bat_algo_ops = bat_algo_get(name); if (!bat_algo_ops) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 41147942ba53..cf83c5422e9a 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -50,7 +50,7 @@ static int compare_orig(const struct hlist_node *node, const void *data2) int originator_init(struct bat_priv *bat_priv) { if (bat_priv->orig_hash) - return 1; + return 0; bat_priv->orig_hash = hash_new(1024); @@ -58,10 +58,10 @@ int originator_init(struct bat_priv *bat_priv) goto err; start_purge_timer(bat_priv); - return 1; + return 0; err: - return 0; + return -ENOMEM; } void neigh_node_free_ref(struct neigh_node *neigh_node) @@ -488,7 +488,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS, GFP_ATOMIC); if (!data_ptr) - return -1; + return -ENOMEM; memcpy(data_ptr, orig_node->bcast_own, (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS); @@ -497,7 +497,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) - return -1; + return -ENOMEM; memcpy(data_ptr, orig_node->bcast_own_sum, (max_if_num - 1) * sizeof(uint8_t)); @@ -528,7 +528,7 @@ int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) ret = orig_node_add_if(orig_node, max_if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); - if (ret == -1) + if (ret == -ENOMEM) goto err; } rcu_read_unlock(); @@ -554,7 +554,7 @@ static int orig_node_del_if(struct orig_node *orig_node, chunk_size = sizeof(unsigned long) * NUM_WORDS; data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); if (!data_ptr) - return -1; + return -ENOMEM; /* copy first part */ memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); @@ -573,7 +573,7 @@ free_bcast_own: data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) - return -1; + return -ENOMEM; memcpy(data_ptr, orig_node->bcast_own_sum, del_if_num * sizeof(uint8_t)); @@ -612,7 +612,7 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) hard_iface->if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); - if (ret == -1) + if (ret == -ENOMEM) goto err; } rcu_read_unlock(); diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index f9675b7f5f99..24e691d7275c 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -181,14 +181,14 @@ int tt_len(int changes_num) static int tt_local_init(struct bat_priv *bat_priv) { if (bat_priv->tt_local_hash) - return 1; + return 0; bat_priv->tt_local_hash = hash_new(1024); if (!bat_priv->tt_local_hash) - return 0; + return -ENOMEM; - return 1; + return 0; } void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, @@ -491,14 +491,14 @@ static void tt_local_table_free(struct bat_priv *bat_priv) static int tt_global_init(struct bat_priv *bat_priv) { if (bat_priv->tt_global_hash) - return 1; + return 0; bat_priv->tt_global_hash = hash_new(1024); if (!bat_priv->tt_global_hash) - return 0; + return -ENOMEM; - return 1; + return 0; } static void tt_changes_list_free(struct bat_priv *bat_priv) @@ -1773,11 +1773,15 @@ out: int tt_init(struct bat_priv *bat_priv) { - if (!tt_local_init(bat_priv)) - return 0; + int ret; - if (!tt_global_init(bat_priv)) - return 0; + ret = tt_local_init(bat_priv); + if (ret < 0) + return ret; + + ret = tt_global_init(bat_priv); + if (ret < 0) + return ret; tt_start_timer(bat_priv); diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index cec216fb77c7..411c0e16f911 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -626,7 +626,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) best_tq = find_best_vis_server(bat_priv, info); if (best_tq < 0) - return -1; + return best_tq; } for (i = 0; i < hash->size; i++) { @@ -878,7 +878,7 @@ int vis_init(struct bat_priv *bat_priv) int hash_added; if (bat_priv->vis_hash) - return 1; + return 0; spin_lock_bh(&bat_priv->vis_hash_lock); @@ -929,7 +929,7 @@ int vis_init(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->vis_hash_lock); start_vis_timer(bat_priv); - return 1; + return 0; free_info: kfree(bat_priv->my_vis_info); @@ -937,7 +937,7 @@ free_info: err: spin_unlock_bh(&bat_priv->vis_hash_lock); vis_quit(bat_priv); - return 0; + return -ENOMEM; } /* Decrease the reference count on a hash item info */ -- GitLab From f25bd58a9d95481e81a09a3a88c4a3f3ab38609f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Apr 2012 07:44:27 +0100 Subject: [PATCH 1897/6849] batman-adv: don't bother flipping ->tt_data just keep it net-endian all along Signed-off-by: Al Viro [lindner_marek@yahoo.de: fix checkpatch warnings] Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/packet.h | 2 +- net/batman-adv/routing.c | 10 +++------- net/batman-adv/translation-table.c | 10 ++++++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 5bf567b52534..372fc889832a 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -206,7 +206,7 @@ struct tt_query_packet { * if TT_REQUEST: crc associated with the * ttvn * if TT_RESPONSE: table_size */ - uint16_t tt_data; + __be16 tt_data; } __packed; struct roam_adv_packet { diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 369604c99a46..9cfd23c6d64a 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -573,7 +573,7 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct tt_query_packet *tt_query; - uint16_t tt_len; + uint16_t tt_size; struct ethhdr *ethhdr; /* drop packet if it has not necessary minimum size */ @@ -596,8 +596,6 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) tt_query = (struct tt_query_packet *)skb->data; - tt_query->tt_data = ntohs(tt_query->tt_data); - switch (tt_query->flags & TT_QUERY_TYPE_MASK) { case TT_REQUEST: batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX); @@ -609,7 +607,6 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) "Routing TT_REQUEST to %pM [%c]\n", tt_query->dst, (tt_query->flags & TT_FULL_TABLE ? 'F' : '.')); - tt_query->tt_data = htons(tt_query->tt_data); return route_unicast_packet(skb, recv_if); } break; @@ -624,11 +621,11 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) /* skb_linearize() possibly changed skb->data */ tt_query = (struct tt_query_packet *)skb->data; - tt_len = tt_query->tt_data * sizeof(struct tt_change); + tt_size = tt_len(ntohs(tt_query->tt_data)); /* Ensure we have all the claimed data */ if (unlikely(skb_headlen(skb) < - sizeof(struct tt_query_packet) + tt_len)) + sizeof(struct tt_query_packet) + tt_size)) goto out; handle_tt_response(bat_priv, tt_query); @@ -637,7 +634,6 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) "Routing TT_RESPONSE to %pM [%c]\n", tt_query->dst, (tt_query->flags & TT_FULL_TABLE ? 'F' : '.')); - tt_query->tt_data = htons(tt_query->tt_data); return route_unicast_packet(skb, recv_if); } break; diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 24e691d7275c..88cfe2a8ea4f 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1418,7 +1418,7 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, /* I don't have the requested data */ if (orig_ttvn != req_ttvn || - tt_request->tt_data != req_dst_orig_node->tt_crc) + tt_request->tt_data != htons(req_dst_orig_node->tt_crc)) goto out; /* If the full table has been explicitly requested */ @@ -1678,7 +1678,7 @@ static void tt_fill_gtable(struct bat_priv *bat_priv, _tt_update_changes(bat_priv, orig_node, (struct tt_change *)(tt_response + 1), - tt_response->tt_data, tt_response->ttvn); + ntohs(tt_response->tt_data), tt_response->ttvn); spin_lock_bh(&orig_node->tt_buff_lock); kfree(orig_node->tt_buff); @@ -1733,7 +1733,8 @@ void handle_tt_response(struct bat_priv *bat_priv, bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", - tt_response->src, tt_response->ttvn, tt_response->tt_data, + tt_response->src, tt_response->ttvn, + ntohs(tt_response->tt_data), (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); /* we should have never asked a backbone gw */ @@ -1747,7 +1748,8 @@ void handle_tt_response(struct bat_priv *bat_priv, if (tt_response->flags & TT_FULL_TABLE) tt_fill_gtable(bat_priv, tt_response); else - tt_update_changes(bat_priv, orig_node, tt_response->tt_data, + tt_update_changes(bat_priv, orig_node, + ntohs(tt_response->tt_data), tt_response->ttvn, (struct tt_change *)(tt_response + 1)); -- GitLab From 16a703459bb58aa873c5b36f42093f0f681628af Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Apr 2012 07:45:29 +0100 Subject: [PATCH 1898/6849] batman-adv: don't bother flipping ->tt_crc Keep it net-endian Signed-off-by: Al Viro Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 10 ++-------- net/batman-adv/packet.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 896287e62df9..ec3542c3bf0c 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -547,8 +547,6 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, "Forwarding packet: tq: %i, ttl: %i\n", batman_ogm_packet->tq, batman_ogm_packet->header.ttl); - batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); - /* switch of primaries first hop flag when forwarding */ batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; if (is_single_hop_neigh) @@ -724,7 +722,7 @@ update_tt: tt_update_orig(bat_priv, orig_node, tt_buff, batman_ogm_packet->tt_num_changes, batman_ogm_packet->ttvn, - batman_ogm_packet->tt_crc); + ntohs(batman_ogm_packet->tt_crc)); if (orig_node->gw_flags != batman_ogm_packet->gw_flags) gw_node_update(bat_priv, orig_node, @@ -972,7 +970,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, ethhdr->h_source, if_incoming->net_dev->name, if_incoming->net_dev->dev_addr, batman_ogm_packet->orig, batman_ogm_packet->prev_sender, ntohl(batman_ogm_packet->seqno), - batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc, + batman_ogm_packet->ttvn, ntohs(batman_ogm_packet->tt_crc), batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq, batman_ogm_packet->header.ttl, batman_ogm_packet->header.version, has_directlink_flag); @@ -1219,10 +1217,6 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, /* unpack the aggregated packets and process them one by one */ do { - /* network to host order for our 32bit seqno and the - orig_interval */ - batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc); - tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN; bat_iv_ogm_process(ethhdr, batman_ogm_packet, diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 372fc889832a..033d99490e82 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -124,7 +124,7 @@ struct batman_ogm_packet { uint8_t tq; uint8_t tt_num_changes; uint8_t ttvn; /* translation table version number */ - uint16_t tt_crc; + __be16 tt_crc; } __packed; #define BATMAN_OGM_HLEN sizeof(struct batman_ogm_packet) -- GitLab From beeb96a4142180c34ddf592aef5a278c2d676bf0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 May 2012 17:51:53 +0200 Subject: [PATCH 1899/6849] batman-adv: fix visualization output without neighbors on the primary interface The primary entry and the corresponding secondary entries are missing when there are no neighbors on the primary interface. This also causes the TT entries to miss and makes nodes with multiply secondary interface fall apart since there is no way to see they are related without a primary entry. Fix this by always emitting a primary entry. Signed-off-by: Matthias Schiffer Signed-off-by: Sven Eckelmann --- net/batman-adv/vis.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 411c0e16f911..01d5da54143e 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -207,7 +207,6 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) int vis_server = atomic_read(&bat_priv->vis_mode); size_t buff_pos, buf_size; char *buff; - int compare; primary_if = primary_if_get_selected(bat_priv); if (!primary_if) @@ -228,14 +227,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) entries = (struct vis_info_entry *) ((char *)packet + sizeof(*packet)); + vis_data_insert_interface(packet->vis_orig, + &vis_if_list, true); + for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) continue; - compare = - compare_eth(entries[j].src, packet->vis_orig); + if (compare_eth(entries[j].src, + packet->vis_orig)) + continue; vis_data_insert_interface(entries[j].src, &vis_if_list, - compare); + false); } hlist_for_each_entry(entry, pos, &vis_if_list, list) { @@ -276,14 +279,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) entries = (struct vis_info_entry *) ((char *)packet + sizeof(*packet)); + vis_data_insert_interface(packet->vis_orig, + &vis_if_list, true); + for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) continue; - compare = - compare_eth(entries[j].src, packet->vis_orig); + if (compare_eth(entries[j].src, + packet->vis_orig)) + continue; vis_data_insert_interface(entries[j].src, &vis_if_list, - compare); + false); } hlist_for_each_entry(entry, pos, &vis_if_list, list) { -- GitLab From be9aa4c1e0d7124cf976831db098f1e852fdbd14 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 7 May 2012 04:22:05 +0800 Subject: [PATCH 1900/6849] batman-adv: turn tt commit code into routing protocol agnostic API Prior to this patch the translation table code made assumptions about how the routing protocol works and where its buffers are stored (to directly modify them). Each protocol now calls the tt code with the relevant pointers, thereby abstracting the code. Signed-off-by: Marek Lindner Acked-by: Antonio Quartulli Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 14 ++-- net/batman-adv/send.c | 74 +---------------- net/batman-adv/translation-table.c | 124 ++++++++++++++++++++++++----- net/batman-adv/translation-table.h | 7 +- net/batman-adv/types.h | 3 +- 5 files changed, 118 insertions(+), 104 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index ec3542c3bf0c..6e0859f4a6a9 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -559,22 +559,28 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, if_incoming, 0, bat_iv_ogm_fwd_send_time()); } -static void bat_iv_ogm_schedule(struct hard_iface *hard_iface, - int tt_num_changes) +static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batman_ogm_packet *batman_ogm_packet; struct hard_iface *primary_if; - int vis_server; + int vis_server, tt_num_changes = 0; vis_server = atomic_read(&bat_priv->vis_mode); primary_if = primary_if_get_selected(bat_priv); + if (hard_iface == primary_if) + tt_num_changes = batadv_tt_append_diff(bat_priv, + &hard_iface->packet_buff, + &hard_iface->packet_len, + BATMAN_OGM_HLEN); + batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; /* change sequence number to network order */ batman_ogm_packet->seqno = htonl((uint32_t)atomic_read(&hard_iface->seqno)); + atomic_inc(&hard_iface->seqno); batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); batman_ogm_packet->tt_crc = htons(bat_priv->tt_crc); @@ -593,8 +599,6 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface, else batman_ogm_packet->gw_flags = NO_FLAGS; - atomic_inc(&hard_iface->seqno); - slide_own_bcast_window(hard_iface); bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, hard_iface->packet_len, hard_iface, 1, diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index f5ff36492b2f..79f8973810c0 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -77,62 +77,9 @@ send_skb_err: return NET_XMIT_DROP; } -static void realloc_packet_buffer(struct hard_iface *hard_iface, - int new_len) -{ - unsigned char *new_buff; - - new_buff = kmalloc(new_len, GFP_ATOMIC); - - /* keep old buffer if kmalloc should fail */ - if (new_buff) { - memcpy(new_buff, hard_iface->packet_buff, - BATMAN_OGM_HLEN); - - kfree(hard_iface->packet_buff); - hard_iface->packet_buff = new_buff; - hard_iface->packet_len = new_len; - } -} - -/* when calling this function (hard_iface == primary_if) has to be true */ -static int prepare_packet_buffer(struct bat_priv *bat_priv, - struct hard_iface *hard_iface) -{ - int new_len; - - new_len = BATMAN_OGM_HLEN + - tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes)); - - /* if we have too many changes for one packet don't send any - * and wait for the tt table request which will be fragmented */ - if (new_len > hard_iface->soft_iface->mtu) - new_len = BATMAN_OGM_HLEN; - - realloc_packet_buffer(hard_iface, new_len); - - bat_priv->tt_crc = tt_local_crc(bat_priv); - - /* reset the sending counter */ - atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); - - return tt_changes_fill_buffer(bat_priv, - hard_iface->packet_buff + BATMAN_OGM_HLEN, - hard_iface->packet_len - BATMAN_OGM_HLEN); -} - -static int reset_packet_buffer(struct bat_priv *bat_priv, - struct hard_iface *hard_iface) -{ - realloc_packet_buffer(hard_iface, BATMAN_OGM_HLEN); - return 0; -} - void schedule_bat_ogm(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); - struct hard_iface *primary_if; - int tt_num_changes = -1; if ((hard_iface->if_status == IF_NOT_IN_USE) || (hard_iface->if_status == IF_TO_BE_REMOVED)) @@ -148,26 +95,7 @@ void schedule_bat_ogm(struct hard_iface *hard_iface) if (hard_iface->if_status == IF_TO_BE_ACTIVATED) hard_iface->if_status = IF_ACTIVE; - primary_if = primary_if_get_selected(bat_priv); - - if (hard_iface == primary_if) { - /* if at least one change happened */ - if (atomic_read(&bat_priv->tt_local_changes) > 0) { - tt_commit_changes(bat_priv); - tt_num_changes = prepare_packet_buffer(bat_priv, - hard_iface); - } - - /* if the changes have been sent often enough */ - if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt)) - tt_num_changes = reset_packet_buffer(bat_priv, - hard_iface); - } - - if (primary_if) - hardif_free_ref(primary_if); - - bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface, tt_num_changes); + bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface); } static void forw_packet_free(struct forw_packet *forw_packet) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 88cfe2a8ea4f..a1a51cc9d88e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -275,14 +275,64 @@ out: tt_global_entry_free_ref(tt_global_entry); } -int tt_changes_fill_buffer(struct bat_priv *bat_priv, - unsigned char *buff, int buff_len) +static void tt_realloc_packet_buff(unsigned char **packet_buff, + int *packet_buff_len, int min_packet_len, + int new_packet_len) +{ + unsigned char *new_buff; + + new_buff = kmalloc(new_packet_len, GFP_ATOMIC); + + /* keep old buffer if kmalloc should fail */ + if (new_buff) { + memcpy(new_buff, *packet_buff, min_packet_len); + kfree(*packet_buff); + *packet_buff = new_buff; + *packet_buff_len = new_packet_len; + } +} + +static void tt_prepare_packet_buff(struct bat_priv *bat_priv, + unsigned char **packet_buff, + int *packet_buff_len, int min_packet_len) +{ + struct hard_iface *primary_if; + int req_len; + + primary_if = primary_if_get_selected(bat_priv); + + req_len = min_packet_len; + req_len += tt_len(atomic_read(&bat_priv->tt_local_changes)); + + /* if we have too many changes for one packet don't send any + * and wait for the tt table request which will be fragmented + */ + if ((!primary_if) || (req_len > primary_if->soft_iface->mtu)) + req_len = min_packet_len; + + tt_realloc_packet_buff(packet_buff, packet_buff_len, + min_packet_len, req_len); + + if (primary_if) + hardif_free_ref(primary_if); +} + +static int tt_changes_fill_buff(struct bat_priv *bat_priv, + unsigned char **packet_buff, + int *packet_buff_len, int min_packet_len) { - int count = 0, tot_changes = 0; struct tt_change_node *entry, *safe; + int count = 0, tot_changes = 0, new_len; + unsigned char *tt_buff; + + tt_prepare_packet_buff(bat_priv, packet_buff, + packet_buff_len, min_packet_len); - if (buff_len > 0) - tot_changes = buff_len / tt_len(1); + new_len = *packet_buff_len - min_packet_len; + tt_buff = *packet_buff + min_packet_len; + + if (new_len > 0) + tot_changes = new_len / tt_len(1); spin_lock_bh(&bat_priv->tt_changes_list_lock); atomic_set(&bat_priv->tt_local_changes, 0); @@ -290,7 +340,7 @@ int tt_changes_fill_buffer(struct bat_priv *bat_priv, list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, list) { if (count < tot_changes) { - memcpy(buff + tt_len(count), + memcpy(tt_buff + tt_len(count), &entry->change, sizeof(struct tt_change)); count++; } @@ -304,17 +354,15 @@ int tt_changes_fill_buffer(struct bat_priv *bat_priv, kfree(bat_priv->tt_buff); bat_priv->tt_buff_len = 0; bat_priv->tt_buff = NULL; - /* We check whether this new OGM has no changes due to size - * problems */ - if (buff_len > 0) { - /** - * if kmalloc() fails we will reply with the full table + /* check whether this new OGM has no changes due to size problems */ + if (new_len > 0) { + /* if kmalloc() fails we will reply with the full table * instead of providing the diff */ - bat_priv->tt_buff = kmalloc(buff_len, GFP_ATOMIC); + bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC); if (bat_priv->tt_buff) { - memcpy(bat_priv->tt_buff, buff, buff_len); - bat_priv->tt_buff_len = buff_len; + memcpy(bat_priv->tt_buff, tt_buff, new_len); + bat_priv->tt_buff_len = new_len; } } spin_unlock_bh(&bat_priv->tt_buff_lock); @@ -1105,7 +1153,7 @@ static uint16_t tt_global_crc(struct bat_priv *bat_priv, } /* Calculates the checksum of the local table */ -uint16_t tt_local_crc(struct bat_priv *bat_priv) +static uint16_t batadv_tt_local_crc(struct bat_priv *bat_priv) { uint16_t total = 0, total_one; struct hashtable_t *hash = bat_priv->tt_local_hash; @@ -2025,20 +2073,56 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) } -void tt_commit_changes(struct bat_priv *bat_priv) +static int tt_commit_changes(struct bat_priv *bat_priv, + unsigned char **packet_buff, int *packet_buff_len, + int packet_min_len) { - uint16_t changed_num = tt_set_flags(bat_priv->tt_local_hash, - TT_CLIENT_NEW, false); - /* all the reset entries have now to be effectively counted as local - * entries */ + uint16_t changed_num = 0; + + if (atomic_read(&bat_priv->tt_local_changes) < 1) + return -ENOENT; + + changed_num = tt_set_flags(bat_priv->tt_local_hash, + TT_CLIENT_NEW, false); + + /* all reset entries have to be counted as local entries */ atomic_add(changed_num, &bat_priv->num_local_tt); tt_local_purge_pending_clients(bat_priv); + bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); /* Increment the TTVN only once per OGM interval */ atomic_inc(&bat_priv->ttvn); bat_dbg(DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", (uint8_t)atomic_read(&bat_priv->ttvn)); bat_priv->tt_poss_change = false; + + /* reset the sending counter */ + atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); + + return tt_changes_fill_buff(bat_priv, packet_buff, + packet_buff_len, packet_min_len); +} + +/* when calling this function (hard_iface == primary_if) has to be true */ +int batadv_tt_append_diff(struct bat_priv *bat_priv, + unsigned char **packet_buff, int *packet_buff_len, + int packet_min_len) +{ + int tt_num_changes; + + /* if at least one change happened */ + tt_num_changes = tt_commit_changes(bat_priv, packet_buff, + packet_buff_len, packet_min_len); + + /* if the changes have been sent often enough */ + if ((tt_num_changes < 0) && + (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { + tt_realloc_packet_buff(packet_buff, packet_buff_len, + packet_min_len, packet_min_len); + tt_num_changes = 0; + } + + return tt_num_changes; } bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index c43374dc364d..d6ea30f9b026 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -23,8 +23,6 @@ #define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ int tt_len(int changes_num); -int tt_changes_fill_buffer(struct bat_priv *bat_priv, - unsigned char *buff, int buff_len); int tt_init(struct bat_priv *bat_priv); void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, int ifindex); @@ -41,18 +39,19 @@ void tt_global_del_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const char *message); struct orig_node *transtable_search(struct bat_priv *bat_priv, const uint8_t *src, const uint8_t *addr); -uint16_t tt_local_crc(struct bat_priv *bat_priv); void tt_free(struct bat_priv *bat_priv); bool send_tt_response(struct bat_priv *bat_priv, struct tt_query_packet *tt_request); bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); void handle_tt_response(struct bat_priv *bat_priv, struct tt_query_packet *tt_response); -void tt_commit_changes(struct bat_priv *bat_priv); bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const unsigned char *tt_buff, uint8_t tt_num_changes, uint8_t ttvn, uint16_t tt_crc); +int batadv_tt_append_diff(struct bat_priv *bat_priv, + unsigned char **packet_buff, int *packet_buff_len, + int packet_min_len); bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 6b569debc1a6..bf71d525445a 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -405,8 +405,7 @@ struct bat_algo_ops { /* called when primary interface is selected / changed */ void (*bat_primary_iface_set)(struct hard_iface *hard_iface); /* prepare a new outgoing OGM for the send queue */ - void (*bat_ogm_schedule)(struct hard_iface *hard_iface, - int tt_num_changes); + void (*bat_ogm_schedule)(struct hard_iface *hard_iface); /* send scheduled OGM */ void (*bat_ogm_emit)(struct forw_packet *forw_packet); }; -- GitLab From ef3a409391f55ad0bddbf017d4d4987b783a3059 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 9 May 2012 09:50:45 +0200 Subject: [PATCH 1901/6849] batman-adv: use DBG_ALL in log_level sysfs definition Each time a new log level is added the developer must change either the DBG_ALL enum definition and the hard coded value in the bat_sysfs.c for the log_level attribute max value. This is extremely error prone. With this patch the code directly uses DBG_ALL in the sysfs definition Signed-off-by: Antonio Quartulli Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 62f4f6cb888a..dc1edbee63df 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -445,7 +445,7 @@ BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG -BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); +BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, DBG_ALL, NULL); #endif static struct bat_attribute *mesh_attrs[] = { -- GitLab From 75c5a2e788ab02f67931442e8dcbc854ae7252d1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 8 May 2012 22:31:57 +0200 Subject: [PATCH 1902/6849] batman-adv: fix locking in hash_add() To ensure an entry isn't added twice all comparisons have to be protected by the hash line write spinlock. This doesn't really hurt as the case that it is tried to add an element already present to the hash shouldn't occur very often, so in most cases the lock would have have to be taken anyways. Signed-off-by: Matthias Schiffer Acked-by: Sven Eckelmann Signed-off-by: Sven Eckelmann --- net/batman-adv/hash.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index 93b3c71aeaf8..3d67ce49fc31 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h @@ -110,26 +110,23 @@ static inline int hash_add(struct hashtable_t *hash, head = &hash->table[index]; list_lock = &hash->list_locks[index]; - rcu_read_lock(); - __hlist_for_each_rcu(node, head) { + spin_lock_bh(list_lock); + + hlist_for_each(node, head) { if (!compare(node, data)) continue; ret = 1; - goto err_unlock; + goto unlock; } - rcu_read_unlock(); /* no duplicate found in list, add new element */ - spin_lock_bh(list_lock); hlist_add_head_rcu(data_node, head); - spin_unlock_bh(list_lock); ret = 0; - goto out; -err_unlock: - rcu_read_unlock(); +unlock: + spin_unlock_bh(list_lock); out: return ret; } -- GitLab From dafe94b278e052c3901b137fe6f666f8f92d839a Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 11 May 2012 16:10:50 +0800 Subject: [PATCH 1903/6849] batman-adv: only store changed gw_bandwidth values Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index ca57ac7d73b2..6e3b052b935d 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -162,6 +162,9 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) **/ gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up); + if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) + return count; + gw_deselect(bat_priv); bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", -- GitLab From 13429ced25fdca14b28dbd116333262b0d51d10f Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 13 Jun 2012 22:14:50 +0200 Subject: [PATCH 1904/6849] ARM: davinci: remove dummy header files These dummy headers are unused. Commit 6ea96e111e6a7f06ef62227bf64e8cd65bd705b3 ("ARM: davinci: add back dummy header files") only added them as a temporary measure. They can be removed now. Signed-off-by: Paul Bolle Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/include/mach/dm365.h | 1 - arch/arm/mach-davinci/include/mach/dm646x.h | 1 - 2 files changed, 2 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/dm365.h delete mode 100644 arch/arm/mach-davinci/include/mach/dm646x.h diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h deleted file mode 100644 index b9bf3d6a4423..000000000000 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ /dev/null @@ -1 +0,0 @@ -/* empty, remove once unused */ diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h deleted file mode 100644 index b9bf3d6a4423..000000000000 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ /dev/null @@ -1 +0,0 @@ -/* empty, remove once unused */ -- GitLab From 9e0304e388ef0e7495b279ce737c24ad56d20b5d Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 18 Jun 2012 13:11:21 -0400 Subject: [PATCH 1905/6849] arch/tile: big-endian: properly bswap instruction bundles when backtracing Instruction bundles are always little-endian, even when running in big-endian mode. I missed this internal bug fix when cherry-picking the big-endian code to return to the community. Signed-off-by: Chris Metcalf --- arch/tile/kernel/backtrace.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c index 9092ce8aa6b4..f8b74ca83b92 100644 --- a/arch/tile/kernel/backtrace.c +++ b/arch/tile/kernel/backtrace.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -336,8 +337,12 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location, bytes_to_prefetch / sizeof(tile_bundle_bits); } - /* Decode the next bundle. */ - bundle.bits = prefetched_bundles[next_bundle++]; + /* + * Decode the next bundle. + * TILE always stores instruction bundles in little-endian + * mode, even when the chip is running in big-endian mode. + */ + bundle.bits = le64_to_cpu(prefetched_bundles[next_bundle++]); bundle.num_insns = parse_insn_tile(bundle.bits, pc, bundle.insns); num_info_ops = bt_get_info_ops(&bundle, info_operands); -- GitLab From 04800ada2acc3a9ffc754c1d73576cef326f3311 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 6 Jun 2012 11:25:02 +0300 Subject: [PATCH 1906/6849] mac80211: stop Rx during HW reconfig While HW reconfig is in progress, drop all incoming Rx. This prevents incoming packets from changing the internal state of the driver or calling callbacks of the low level driver while it is in inconsistent state. Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/main.c | 7 +++++++ net/mac80211/rx.c | 4 ++++ net/mac80211/util.c | 3 +++ 4 files changed, 17 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e6cbf5b68c89..ddf768f6350e 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -881,6 +881,9 @@ struct ieee80211_local { /* device is started */ bool started; + /* device is during a HW reconfig */ + bool in_reconfig; + /* wowlan is enabled -- don't reconfig on resume */ bool wowlan; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d81c178c7712..976e41365c25 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -345,6 +345,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); + /* + * Stop all Rx during the reconfig. We don't want state changes + * or driver callbacks while this is in progress. + */ + local->in_reconfig = true; + barrier(); + schedule_work(&local->restart_work); } EXPORT_SYMBOL(ieee80211_restart_hw); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6fd2cb0838c4..072e8f3afa2b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3027,6 +3027,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) if (unlikely(local->quiescing || local->suspended)) goto drop; + /* We might be during a HW reconfig, prevent Rx for the same reason */ + if (unlikely(local->in_reconfig)) + goto drop; + /* * The same happens when we're not even started, * but that's worth a warning. diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1df4019f294b..242ecde381f6 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1411,6 +1411,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) if (ieee80211_sdata_running(sdata)) ieee80211_enable_keys(sdata); + local->in_reconfig = false; + barrier(); + wake_up: /* * Clear the WLAN_STA_BLOCK_BA flag so new aggregation -- GitLab From d6a4ed6fe0a0d4790941e7f13e56630b8b9b053d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 18 Jun 2012 10:43:50 +0300 Subject: [PATCH 1907/6849] mac80211: set only VO as a U-APSD enabled AC Some APs experience problems when working with U-APSD. Decrease the probability of that happening by using legacy mode for all ACs but VO. The AP that caused us troubles was a Cisco 4410N. It ignores our setting, and always treats non-VO ACs as legacy. Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ddf768f6350e..34af2e5263c2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -55,11 +55,14 @@ struct ieee80211_local; #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) +/* + * Some APs experience problems when working with U-APSD. Decrease the + * probability of that happening by using legacy mode for all ACs but VO. + * The AP that caused us trouble was a Cisco 4410N. It ignores our + * setting, and always treats non-VO ACs as legacy. + */ #define IEEE80211_DEFAULT_UAPSD_QUEUES \ - (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \ - IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \ - IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \ - IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) + IEEE80211_WMM_IE_STA_QOSINFO_AC_VO #define IEEE80211_DEFAULT_MAX_SP_LEN \ IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL -- GitLab From 7ebfa46973aa239f79fbd4651ddeed5c92df45b2 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Fri, 15 Jun 2012 10:20:02 +0800 Subject: [PATCH 1908/6849] mac80211: fix and improve mesh RANN processing This patch fixes the problem of dropping RANN element if the TTL is 1. If the received RANN element TTL is 1 or greater than 1, the RANN is processed. However, forwarding of received RANN element with TTL 1 or less is prohibited according to the standard. This is previously reported by Monthadar Al Jaberi. Besides, this patch also avoid the processing of unicast PREQ generation if the RANN element does not meet the acceptance criteria mentioned in Sec. 13.10.12.4.2 of IEEE Std. 802.11-2012. Reported-by: Monthadar Al Jaberi Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Johannes Berg --- net/mac80211/mesh_hwmp.c | 43 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index bea52479e3aa..aed1821bd6f1 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -771,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, bool root_is_gate; ttl = rann->rann_ttl; - if (ttl <= 1) { - ifmsh->mshstats.dropped_frames_ttl++; - return; - } - ttl--; flags = rann->rann_flags; root_is_gate = !!(flags & RANN_FLAG_IS_GATE); orig_addr = rann->rann_addr; @@ -812,37 +807,49 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, } } + if (!(SN_LT(mpath->sn, orig_sn)) && + !(mpath->sn == orig_sn && metric < mpath->rann_metric)) { + rcu_read_unlock(); + return; + } + if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || (time_after(jiffies, mpath->last_preq_to_root + root_path_confirmation_jiffies(sdata)) || time_before(jiffies, mpath->last_preq_to_root))) && - !(mpath->flags & MESH_PATH_FIXED)) { + !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) { mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, orig_addr); mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); mpath->last_preq_to_root = jiffies; } - if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn && - metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) { + mpath->sn = orig_sn; + mpath->rann_metric = metric + metric_txsta; + mpath->is_root = true; + /* Recording RANNs sender address to send individually + * addressed PREQs destined for root mesh STA */ + memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); + + if (root_is_gate) + mesh_path_add_gate(mpath); + + if (ttl <= 1) { + ifmsh->mshstats.dropped_frames_ttl++; + rcu_read_unlock(); + return; + } + ttl--; + + if (ifmsh->mshcfg.dot11MeshForwarding) { mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, cpu_to_le32(orig_sn), 0, NULL, 0, broadcast_addr, hopcount, ttl, cpu_to_le32(interval), cpu_to_le32(metric + metric_txsta), 0, sdata); - mpath->sn = orig_sn; - mpath->rann_metric = metric + metric_txsta; - /* Recording RANNs sender address to send individually - * addressed PREQs destined for root mesh STA */ - memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); } - mpath->is_root = true; - - if (root_is_gate) - mesh_path_add_gate(mpath); - rcu_read_unlock(); } -- GitLab From de509f9f08726077ffd2f2d5e4b63e17cb516938 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 7 Jun 2012 10:30:59 +0200 Subject: [PATCH 1909/6849] PCI: add Chelsio T310 10GbE NIC broken INTx masking quirk According to http://thread.gmane.org/gmane.comp.emulators.kvm.devel/91388 the T310 does not properly support INTx masking as it fails to keep the PCI_STATUS_INTERRUPT bit updated once the interrupt is masked. Mark this adapter as broken so that pci_intx_mask_supported won't report it as compatible. [bhelgaas: use HEADER, not FINAL, which is currently broken for hotplug] Tested-by: Alexey Kardashevskiy Signed-off-by: Jan Kiszka Signed-off-by: Bjorn Helgaas --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index cc13415416d7..b2b66d21105f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2938,6 +2938,8 @@ static void __devinit quirk_broken_intx_masking(struct pci_dev *dev) { dev->broken_intx_masking = 1; } +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, 0x0030, + quirk_broken_intx_masking); static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) -- GitLab From 0bdb3b213ac64f9a16e59d57660174543eaa01f0 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 7 Jun 2012 11:01:59 -0600 Subject: [PATCH 1910/6849] PCI: add Ralink RT2800 broken INTx masking quirk Passes pci_intx_mask_supported test but continues to send interrupts as discovered through VFIO-based device assignment. http://www.spinics.net/lists/kvm/msg73738.html [bhelgaas: use HEADER, not FINAL, which is currently broken for hotplug] Tested-by: Andreas Hartmann Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b2b66d21105f..2bbea6428d2e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2940,6 +2940,8 @@ static void __devinit quirk_broken_intx_masking(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, 0x0030, quirk_broken_intx_masking); +DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */ + quirk_broken_intx_masking); static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) -- GitLab From ddd04b989f50157a599de036b670262aa3ec9405 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 18 Jun 2012 00:47:26 -0600 Subject: [PATCH 1911/6849] ARM: OMAP AM33xx: PRM: add PRM support As far as PRM/CM/PRCM modules are concerned, AM33XX device is different than OMAP3 and OMAP4 architectures; so we need to handle it separately. This patch adds support for the PRM APIs required for AM33XX device. Signed-off-by: Vaibhav Hiremath Signed-off-by: Afzal Mohammed Cc: Benoit Cousson Cc: Tony Lindgren Cc: Kevin Hilman Cc: Paul Walmsley Cc: Rajendra Nayak [paul@pwsan.com: separated the PRM parts of "ARM: OMAP3+: am33xx: Add powerdomain & PRM support" into this patch; fixed Makefile prm33xx.o location; cleaned up some checkpatch violations; updated for 3.5] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 1 + arch/arm/mach-omap2/prm-regbits-33xx.h | 357 +++++++++++++++++++++++++ arch/arm/mach-omap2/prm33xx.c | 135 ++++++++++ arch/arm/mach-omap2/prm33xx.h | 129 +++++++++ 4 files changed, 622 insertions(+) create mode 100644 arch/arm/mach-omap2/prm-regbits-33xx.h create mode 100644 arch/arm/mach-omap2/prm33xx.c create mode 100644 arch/arm/mach-omap2/prm33xx.h diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 6a3aef66f03e..76921ebc63d9 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += prcm.o cminst44xx.o cm44xx.o obj-$(CONFIG_ARCH_OMAP4) += prcm_mpu44xx.o prminst44xx.o obj-$(CONFIG_ARCH_OMAP4) += vc44xx_data.o vp44xx_data.o prm44xx.o +obj-$(CONFIG_SOC_AM33XX) += prcm.o prm33xx.o # OMAP voltage domains voltagedomain-common := voltage.o vc.o vp.o diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h new file mode 100644 index 000000000000..0221b5c20e87 --- /dev/null +++ b/arch/arm/mach-omap2/prm-regbits-33xx.h @@ -0,0 +1,357 @@ +/* + * AM33XX PRM_XXX register bits + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_33XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_33XX_H + +#include "prm.h" + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ABBOFF_ACT_EXPORT_SHIFT 1 +#define AM33XX_ABBOFF_ACT_EXPORT_MASK (1 << 1) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ABBOFF_SLEEP_EXPORT_SHIFT 2 +#define AM33XX_ABBOFF_SLEEP_EXPORT_MASK (1 << 2) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_AIPOFF_SHIFT 8 +#define AM33XX_AIPOFF_MASK (1 << 8) + +/* Used by PM_WKUP_PWRSTST */ +#define AM33XX_DEBUGSS_MEM_STATEST_SHIFT 17 +#define AM33XX_DEBUGSS_MEM_STATEST_MASK (0x3 << 17) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_DISABLE_RTA_EXPORT_SHIFT 0 +#define AM33XX_DISABLE_RTA_EXPORT_MASK (1 << 0) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_CORE_RECAL_EN_SHIFT 12 +#define AM33XX_DPLL_CORE_RECAL_EN_MASK (1 << 12) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_CORE_RECAL_ST_SHIFT 12 +#define AM33XX_DPLL_CORE_RECAL_ST_MASK (1 << 12) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_DDR_RECAL_EN_SHIFT 14 +#define AM33XX_DPLL_DDR_RECAL_EN_MASK (1 << 14) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_DDR_RECAL_ST_SHIFT 14 +#define AM33XX_DPLL_DDR_RECAL_ST_MASK (1 << 14) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_DISP_RECAL_EN_SHIFT 15 +#define AM33XX_DPLL_DISP_RECAL_EN_MASK (1 << 15) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_DISP_RECAL_ST_SHIFT 13 +#define AM33XX_DPLL_DISP_RECAL_ST_MASK (1 << 13) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_MPU_RECAL_EN_SHIFT 11 +#define AM33XX_DPLL_MPU_RECAL_EN_MASK (1 << 11) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_MPU_RECAL_ST_SHIFT 11 +#define AM33XX_DPLL_MPU_RECAL_ST_MASK (1 << 11) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_PER_RECAL_EN_SHIFT 13 +#define AM33XX_DPLL_PER_RECAL_EN_MASK (1 << 13) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_PER_RECAL_ST_SHIFT 15 +#define AM33XX_DPLL_PER_RECAL_ST_MASK (1 << 15) + +/* Used by RM_WKUP_RSTST */ +#define AM33XX_EMULATION_M3_RST_SHIFT 6 +#define AM33XX_EMULATION_M3_RST_MASK (1 << 6) + +/* Used by RM_MPU_RSTST */ +#define AM33XX_EMULATION_MPU_RST_SHIFT 5 +#define AM33XX_EMULATION_MPU_RST_MASK (1 << 5) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC1_EXPORT_SHIFT 3 +#define AM33XX_ENFUNC1_EXPORT_MASK (1 << 3) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC3_EXPORT_SHIFT 5 +#define AM33XX_ENFUNC3_EXPORT_MASK (1 << 5) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC4_SHIFT 6 +#define AM33XX_ENFUNC4_MASK (1 << 6) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC5_SHIFT 7 +#define AM33XX_ENFUNC5_MASK (1 << 7) + +/* Used by PRM_RSTST */ +#define AM33XX_EXTERNAL_WARM_RST_SHIFT 5 +#define AM33XX_EXTERNAL_WARM_RST_MASK (1 << 5) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_FORCEWKUP_EN_SHIFT 10 +#define AM33XX_FORCEWKUP_EN_MASK (1 << 10) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_FORCEWKUP_ST_SHIFT 10 +#define AM33XX_FORCEWKUP_ST_MASK (1 << 10) + +/* Used by PM_GFX_PWRSTCTRL */ +#define AM33XX_GFX_MEM_ONSTATE_SHIFT 17 +#define AM33XX_GFX_MEM_ONSTATE_MASK (0x3 << 17) + +/* Used by PM_GFX_PWRSTCTRL */ +#define AM33XX_GFX_MEM_RETSTATE_SHIFT 6 +#define AM33XX_GFX_MEM_RETSTATE_MASK (1 << 6) + +/* Used by PM_GFX_PWRSTST */ +#define AM33XX_GFX_MEM_STATEST_SHIFT 4 +#define AM33XX_GFX_MEM_STATEST_MASK (0x3 << 4) + +/* Used by RM_GFX_RSTCTRL, RM_GFX_RSTST */ +#define AM33XX_GFX_RST_SHIFT 0 +#define AM33XX_GFX_RST_MASK (1 << 0) + +/* Used by PRM_RSTST */ +#define AM33XX_GLOBAL_COLD_RST_SHIFT 0 +#define AM33XX_GLOBAL_COLD_RST_MASK (1 << 0) + +/* Used by PRM_RSTST */ +#define AM33XX_GLOBAL_WARM_SW_RST_SHIFT 1 +#define AM33XX_GLOBAL_WARM_SW_RST_MASK (1 << 1) + +/* Used by RM_WKUP_RSTST */ +#define AM33XX_ICECRUSHER_M3_RST_SHIFT 7 +#define AM33XX_ICECRUSHER_M3_RST_MASK (1 << 7) + +/* Used by RM_MPU_RSTST */ +#define AM33XX_ICECRUSHER_MPU_RST_SHIFT 6 +#define AM33XX_ICECRUSHER_MPU_RST_MASK (1 << 6) + +/* Used by PRM_RSTST */ +#define AM33XX_ICEPICK_RST_SHIFT 9 +#define AM33XX_ICEPICK_RST_MASK (1 << 9) + +/* Used by RM_PER_RSTCTRL */ +#define AM33XX_PRUSS_LRST_SHIFT 1 +#define AM33XX_PRUSS_LRST_MASK (1 << 1) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PRUSS_MEM_ONSTATE_SHIFT 5 +#define AM33XX_PRUSS_MEM_ONSTATE_MASK (0x3 << 5) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PRUSS_MEM_RETSTATE_SHIFT 7 +#define AM33XX_PRUSS_MEM_RETSTATE_MASK (1 << 7) + +/* Used by PM_PER_PWRSTST */ +#define AM33XX_PRUSS_MEM_STATEST_SHIFT 23 +#define AM33XX_PRUSS_MEM_STATEST_MASK (0x3 << 23) + +/* + * Used by PM_GFX_PWRSTST, PM_CEFUSE_PWRSTST, PM_PER_PWRSTST, PM_MPU_PWRSTST, + * PM_WKUP_PWRSTST, PM_RTC_PWRSTST + */ +#define AM33XX_INTRANSITION_SHIFT 20 +#define AM33XX_INTRANSITION_MASK (1 << 20) + +/* Used by PM_CEFUSE_PWRSTST */ +#define AM33XX_LASTPOWERSTATEENTERED_SHIFT 24 +#define AM33XX_LASTPOWERSTATEENTERED_MASK (0x3 << 24) + +/* Used by PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_RTC_PWRSTCTRL */ +#define AM33XX_LOGICRETSTATE_SHIFT 2 +#define AM33XX_LOGICRETSTATE_MASK (1 << 2) + +/* Renamed from LOGICRETSTATE Used by PM_PER_PWRSTCTRL, PM_WKUP_PWRSTCTRL */ +#define AM33XX_LOGICRETSTATE_3_3_SHIFT 3 +#define AM33XX_LOGICRETSTATE_3_3_MASK (1 << 3) + +/* + * Used by PM_GFX_PWRSTST, PM_CEFUSE_PWRSTST, PM_PER_PWRSTST, PM_MPU_PWRSTST, + * PM_WKUP_PWRSTST, PM_RTC_PWRSTST + */ +#define AM33XX_LOGICSTATEST_SHIFT 2 +#define AM33XX_LOGICSTATEST_MASK (1 << 2) + +/* + * Used by PM_GFX_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL, PM_PER_PWRSTCTRL, + * PM_MPU_PWRSTCTRL, PM_WKUP_PWRSTCTRL, PM_RTC_PWRSTCTRL + */ +#define AM33XX_LOWPOWERSTATECHANGE_SHIFT 4 +#define AM33XX_LOWPOWERSTATECHANGE_MASK (1 << 4) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L1_ONSTATE_SHIFT 18 +#define AM33XX_MPU_L1_ONSTATE_MASK (0x3 << 18) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L1_RETSTATE_SHIFT 22 +#define AM33XX_MPU_L1_RETSTATE_MASK (1 << 22) + +/* Used by PM_MPU_PWRSTST */ +#define AM33XX_MPU_L1_STATEST_SHIFT 6 +#define AM33XX_MPU_L1_STATEST_MASK (0x3 << 6) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L2_ONSTATE_SHIFT 20 +#define AM33XX_MPU_L2_ONSTATE_MASK (0x3 << 20) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L2_RETSTATE_SHIFT 23 +#define AM33XX_MPU_L2_RETSTATE_MASK (1 << 23) + +/* Used by PM_MPU_PWRSTST */ +#define AM33XX_MPU_L2_STATEST_SHIFT 8 +#define AM33XX_MPU_L2_STATEST_MASK (0x3 << 8) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_RAM_ONSTATE_SHIFT 16 +#define AM33XX_MPU_RAM_ONSTATE_MASK (0x3 << 16) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_RAM_RETSTATE_SHIFT 24 +#define AM33XX_MPU_RAM_RETSTATE_MASK (1 << 24) + +/* Used by PM_MPU_PWRSTST */ +#define AM33XX_MPU_RAM_STATEST_SHIFT 4 +#define AM33XX_MPU_RAM_STATEST_MASK (0x3 << 4) + +/* Used by PRM_RSTST */ +#define AM33XX_MPU_SECURITY_VIOL_RST_SHIFT 2 +#define AM33XX_MPU_SECURITY_VIOL_RST_MASK (1 << 2) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_PCHARGECNT_VALUE_SHIFT 0 +#define AM33XX_PCHARGECNT_VALUE_MASK (0x3f << 0) + +/* Used by RM_PER_RSTCTRL */ +#define AM33XX_PCI_LRST_SHIFT 0 +#define AM33XX_PCI_LRST_MASK (1 << 0) + +/* Renamed from PCI_LRST Used by RM_PER_RSTST */ +#define AM33XX_PCI_LRST_5_5_SHIFT 5 +#define AM33XX_PCI_LRST_5_5_MASK (1 << 5) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PER_MEM_ONSTATE_SHIFT 25 +#define AM33XX_PER_MEM_ONSTATE_MASK (0x3 << 25) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PER_MEM_RETSTATE_SHIFT 29 +#define AM33XX_PER_MEM_RETSTATE_MASK (1 << 29) + +/* Used by PM_PER_PWRSTST */ +#define AM33XX_PER_MEM_STATEST_SHIFT 17 +#define AM33XX_PER_MEM_STATEST_MASK (0x3 << 17) + +/* + * Used by PM_GFX_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL, PM_PER_PWRSTCTRL, + * PM_MPU_PWRSTCTRL + */ +#define AM33XX_POWERSTATE_SHIFT 0 +#define AM33XX_POWERSTATE_MASK (0x3 << 0) + +/* Used by PM_GFX_PWRSTST, PM_CEFUSE_PWRSTST, PM_PER_PWRSTST, PM_MPU_PWRSTST */ +#define AM33XX_POWERSTATEST_SHIFT 0 +#define AM33XX_POWERSTATEST_MASK (0x3 << 0) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_RAM_MEM_ONSTATE_SHIFT 30 +#define AM33XX_RAM_MEM_ONSTATE_MASK (0x3 << 30) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_RAM_MEM_RETSTATE_SHIFT 27 +#define AM33XX_RAM_MEM_RETSTATE_MASK (1 << 27) + +/* Used by PM_PER_PWRSTST */ +#define AM33XX_RAM_MEM_STATEST_SHIFT 21 +#define AM33XX_RAM_MEM_STATEST_MASK (0x3 << 21) + +/* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_MPU_CTRL */ +#define AM33XX_RETMODE_ENABLE_SHIFT 0 +#define AM33XX_RETMODE_ENABLE_MASK (1 << 0) + +/* Used by REVISION_PRM */ +#define AM33XX_REV_SHIFT 0 +#define AM33XX_REV_MASK (0xff << 0) + +/* Used by PRM_RSTTIME */ +#define AM33XX_RSTTIME1_SHIFT 0 +#define AM33XX_RSTTIME1_MASK (0xff << 0) + +/* Used by PRM_RSTTIME */ +#define AM33XX_RSTTIME2_SHIFT 8 +#define AM33XX_RSTTIME2_MASK (0x1f << 8) + +/* Used by PRM_RSTCTRL */ +#define AM33XX_RST_GLOBAL_COLD_SW_SHIFT 1 +#define AM33XX_RST_GLOBAL_COLD_SW_MASK (1 << 1) + +/* Used by PRM_RSTCTRL */ +#define AM33XX_RST_GLOBAL_WARM_SW_SHIFT 0 +#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_SLPCNT_VALUE_SHIFT 16 +#define AM33XX_SLPCNT_VALUE_MASK (0xff << 16) + +/* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_MPU_CTRL */ +#define AM33XX_SRAMLDO_STATUS_SHIFT 8 +#define AM33XX_SRAMLDO_STATUS_MASK (1 << 8) + +/* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_MPU_CTRL */ +#define AM33XX_SRAM_IN_TRANSITION_SHIFT 9 +#define AM33XX_SRAM_IN_TRANSITION_MASK (1 << 9) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_STARTUP_COUNT_SHIFT 24 +#define AM33XX_STARTUP_COUNT_MASK (0xff << 24) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_TRANSITION_EN_SHIFT 8 +#define AM33XX_TRANSITION_EN_MASK (1 << 8) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_TRANSITION_ST_SHIFT 8 +#define AM33XX_TRANSITION_ST_MASK (1 << 8) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_VSETUPCNT_VALUE_SHIFT 8 +#define AM33XX_VSETUPCNT_VALUE_MASK (0xff << 8) + +/* Used by PRM_RSTST */ +#define AM33XX_WDT0_RST_SHIFT 3 +#define AM33XX_WDT0_RST_MASK (1 << 3) + +/* Used by PRM_RSTST */ +#define AM33XX_WDT1_RST_SHIFT 4 +#define AM33XX_WDT1_RST_MASK (1 << 4) + +/* Used by RM_WKUP_RSTCTRL */ +#define AM33XX_WKUP_M3_LRST_SHIFT 3 +#define AM33XX_WKUP_M3_LRST_MASK (1 << 3) + +/* Renamed from WKUP_M3_LRST Used by RM_WKUP_RSTST */ +#define AM33XX_WKUP_M3_LRST_5_5_SHIFT 5 +#define AM33XX_WKUP_M3_LRST_5_5_MASK (1 << 5) + +#endif diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c new file mode 100644 index 000000000000..e7dbb6cf1255 --- /dev/null +++ b/arch/arm/mach-omap2/prm33xx.c @@ -0,0 +1,135 @@ +/* + * AM33XX PRM functions + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "prm33xx.h" +#include "prm-regbits-33xx.h" + +/* Read a register in a PRM instance */ +u32 am33xx_prm_read_reg(s16 inst, u16 idx) +{ + return __raw_readl(prm_base + inst + idx); +} + +/* Write into a register in a PRM instance */ +void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) +{ + __raw_writel(val, prm_base + inst + idx); +} + +/* Read-modify-write a register in PRM. Caller must lock */ +u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) +{ + u32 v; + + v = am33xx_prm_read_reg(inst, idx); + v &= ~mask; + v |= bits; + am33xx_prm_write_reg(v, inst, idx); + + return v; +} + +/** + * am33xx_prm_is_hardreset_asserted - read the HW reset line state of + * submodules contained in the hwmod module + * @shift: register bit shift corresponding to the reset line to check + * @inst: CM instance register offset (*_INST macro) + * @rstctrl_offs: RM_RSTCTRL register address offset for this module + * + * Returns 1 if the (sub)module hardreset line is currently asserted, + * 0 if the (sub)module hardreset line is not currently asserted, or + * -EINVAL upon parameter error. + */ +int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) +{ + u32 v; + + v = am33xx_prm_read_reg(inst, rstctrl_offs); + v &= 1 << shift; + v >>= shift; + + return v; +} + +/** + * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule + * @shift: register bit shift corresponding to the reset line to assert + * @inst: CM instance register offset (*_INST macro) + * @rstctrl_reg: RM_RSTCTRL register address for this module + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * place the submodule into reset. Returns 0 upon success or -EINVAL + * upon an argument error. + */ +int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) +{ + u32 mask = 1 << shift; + + am33xx_prm_rmw_reg_bits(mask, mask, inst, rstctrl_offs); + + return 0; +} + +/** + * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and + * wait + * @shift: register bit shift corresponding to the reset line to deassert + * @inst: CM instance register offset (*_INST macro) + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @rstst_reg: RM_RSTST register address for this module + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * take the submodule out of reset and wait until the PRCM indicates + * that the reset has completed before returning. Returns 0 upon success or + * -EINVAL upon an argument error, -EEXIST if the submodule was already out + * of reset, or -EBUSY if the submodule did not exit reset promptly. + */ +int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, + u16 rstctrl_offs, u16 rstst_offs) +{ + int c; + u32 mask = 1 << shift; + + /* Check the current status to avoid de-asserting the line twice */ + if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) + return -EEXIST; + + /* Clear the reset status by writing 1 to the status bit */ + am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs); + /* de-assert the reset control line */ + am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); + /* wait the status to be set */ + + omap_test_timeout(am33xx_prm_is_hardreset_asserted(shift, inst, + rstst_offs), + MAX_MODULE_HARDRESET_WAIT, c); + + return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; +} diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h new file mode 100644 index 000000000000..3f25c563a821 --- /dev/null +++ b/arch/arm/mach-omap2/prm33xx.h @@ -0,0 +1,129 @@ +/* + * AM33XX PRM instance offset macros + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM33XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM33XX_H + +#include "prcm-common.h" +#include "prm.h" + +#define AM33XX_PRM_BASE 0x44E00000 + +#define AM33XX_PRM_REGADDR(inst, reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRM_BASE + (inst) + (reg)) + + +/* PRM instances */ +#define AM33XX_PRM_OCP_SOCKET_MOD 0x0B00 +#define AM33XX_PRM_PER_MOD 0x0C00 +#define AM33XX_PRM_WKUP_MOD 0x0D00 +#define AM33XX_PRM_MPU_MOD 0x0E00 +#define AM33XX_PRM_DEVICE_MOD 0x0F00 +#define AM33XX_PRM_RTC_MOD 0x1000 +#define AM33XX_PRM_GFX_MOD 0x1100 +#define AM33XX_PRM_CEFUSE_MOD 0x1200 + +/* PRM */ + +/* PRM.OCP_SOCKET_PRM register offsets */ +#define AM33XX_REVISION_PRM_OFFSET 0x0000 +#define AM33XX_REVISION_PRM AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0000) +#define AM33XX_PRM_IRQSTATUS_MPU_OFFSET 0x0004 +#define AM33XX_PRM_IRQSTATUS_MPU AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0004) +#define AM33XX_PRM_IRQENABLE_MPU_OFFSET 0x0008 +#define AM33XX_PRM_IRQENABLE_MPU AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0008) +#define AM33XX_PRM_IRQSTATUS_M3_OFFSET 0x000c +#define AM33XX_PRM_IRQSTATUS_M3 AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x000c) +#define AM33XX_PRM_IRQENABLE_M3_OFFSET 0x0010 +#define AM33XX_PRM_IRQENABLE_M3 AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0010) + +/* PRM.PER_PRM register offsets */ +#define AM33XX_RM_PER_RSTCTRL_OFFSET 0x0000 +#define AM33XX_RM_PER_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0000) +#define AM33XX_RM_PER_RSTST_OFFSET 0x0004 +#define AM33XX_RM_PER_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0004) +#define AM33XX_PM_PER_PWRSTST_OFFSET 0x0008 +#define AM33XX_PM_PER_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0008) +#define AM33XX_PM_PER_PWRSTCTRL_OFFSET 0x000c +#define AM33XX_PM_PER_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x000c) + +/* PRM.WKUP_PRM register offsets */ +#define AM33XX_RM_WKUP_RSTCTRL_OFFSET 0x0000 +#define AM33XX_RM_WKUP_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0000) +#define AM33XX_PM_WKUP_PWRSTCTRL_OFFSET 0x0004 +#define AM33XX_PM_WKUP_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0004) +#define AM33XX_PM_WKUP_PWRSTST_OFFSET 0x0008 +#define AM33XX_PM_WKUP_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0008) +#define AM33XX_RM_WKUP_RSTST_OFFSET 0x000c +#define AM33XX_RM_WKUP_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x000c) + +/* PRM.MPU_PRM register offsets */ +#define AM33XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_MPU_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0000) +#define AM33XX_PM_MPU_PWRSTST_OFFSET 0x0004 +#define AM33XX_PM_MPU_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0004) +#define AM33XX_RM_MPU_RSTST_OFFSET 0x0008 +#define AM33XX_RM_MPU_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0008) + +/* PRM.DEVICE_PRM register offsets */ +#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000 +#define AM33XX_PRM_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0000) +#define AM33XX_PRM_RSTTIME_OFFSET 0x0004 +#define AM33XX_PRM_RSTTIME AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0004) +#define AM33XX_PRM_RSTST_OFFSET 0x0008 +#define AM33XX_PRM_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0008) +#define AM33XX_PRM_SRAM_COUNT_OFFSET 0x000c +#define AM33XX_PRM_SRAM_COUNT AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x000c) +#define AM33XX_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x0010 +#define AM33XX_PRM_LDO_SRAM_CORE_SETUP AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0010) +#define AM33XX_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x0014 +#define AM33XX_PRM_LDO_SRAM_CORE_CTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0014) +#define AM33XX_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x0018 +#define AM33XX_PRM_LDO_SRAM_MPU_SETUP AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0018) +#define AM33XX_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x001c +#define AM33XX_PRM_LDO_SRAM_MPU_CTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x001c) + +/* PRM.RTC_PRM register offsets */ +#define AM33XX_PM_RTC_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_RTC_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_RTC_MOD, 0x0000) +#define AM33XX_PM_RTC_PWRSTST_OFFSET 0x0004 +#define AM33XX_PM_RTC_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_RTC_MOD, 0x0004) + +/* PRM.GFX_PRM register offsets */ +#define AM33XX_PM_GFX_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_GFX_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0000) +#define AM33XX_RM_GFX_RSTCTRL_OFFSET 0x0004 +#define AM33XX_RM_GFX_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0004) +#define AM33XX_PM_GFX_PWRSTST_OFFSET 0x0010 +#define AM33XX_PM_GFX_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0010) +#define AM33XX_RM_GFX_RSTST_OFFSET 0x0014 +#define AM33XX_RM_GFX_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0014) + +/* PRM.CEFUSE_PRM register offsets */ +#define AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_CEFUSE_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0000) +#define AM33XX_PM_CEFUSE_PWRSTST_OFFSET 0x0004 +#define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) + +extern u32 am33xx_prm_read_reg(s16 inst, u16 idx); +extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx); +extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); +extern void am33xx_prm_global_warm_sw_reset(void); +extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, + u16 rstctrl_offs); +extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs); +extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, + u16 rstctrl_offs, u16 rstst_offs); +#endif -- GitLab From f969a6dcec75fe997a156b904d4fbbb5b313e54f Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 18 Jun 2012 00:47:26 -0600 Subject: [PATCH 1912/6849] ARM: OMAP AM33xx: CM: Introduce AM33xx CM APIs and register level details As far as PRM/CM/PRCM modules are concerned, AM33XX device is different than OMAP3 and OMAP4 architectures; so similar to PRM implementation, handle AM33XX CM separately. This patch introduces AM33XX CM module low-level api's, used and required by omap clockdomain and hwmod framework. Please note that cm-regbits-33xx.h (register bit field offset) and cm33xx.h (register addr offset) files are mostly auto generated. Signed-off-by: Vaibhav Hiremath Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Bedia Cc: Kevin Hilman Cc: Rajendra Nayak CC: Tony Lindgren Cc: Paul Walmsley Cc: Benoit Cousson [paul@pwsan.com: split the hwmod code changes in this patch into a separate patch; updated for 3.5] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/cm-regbits-33xx.h | 687 ++++++++++++++++++++++++++ arch/arm/mach-omap2/cm33xx.c | 313 ++++++++++++ arch/arm/mach-omap2/cm33xx.h | 420 ++++++++++++++++ 4 files changed, 1421 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/cm-regbits-33xx.h create mode 100644 arch/arm/mach-omap2/cm33xx.c create mode 100644 arch/arm/mach-omap2/cm33xx.h diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 76921ebc63d9..cc080946ec61 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -90,7 +90,7 @@ obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += prcm.o cminst44xx.o cm44xx.o obj-$(CONFIG_ARCH_OMAP4) += prcm_mpu44xx.o prminst44xx.o obj-$(CONFIG_ARCH_OMAP4) += vc44xx_data.o vp44xx_data.o prm44xx.o -obj-$(CONFIG_SOC_AM33XX) += prcm.o prm33xx.o +obj-$(CONFIG_SOC_AM33XX) += prcm.o prm33xx.o cm33xx.o # OMAP voltage domains voltagedomain-common := voltage.o vc.o vp.o diff --git a/arch/arm/mach-omap2/cm-regbits-33xx.h b/arch/arm/mach-omap2/cm-regbits-33xx.h new file mode 100644 index 000000000000..532027ee3d8d --- /dev/null +++ b/arch/arm/mach-omap2/cm-regbits-33xx.h @@ -0,0 +1,687 @@ +/* + * AM33XX Power Management register bits + * + * This file is automatically generated from the AM33XX hardware databases. + * Vaibhav Hiremath + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_33XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_33XX_H + +/* + * Used by CM_AUTOIDLE_DPLL_CORE, CM_AUTOIDLE_DPLL_DDR, CM_AUTOIDLE_DPLL_DISP, + * CM_AUTOIDLE_DPLL_MPU, CM_AUTOIDLE_DPLL_PER + */ +#define AM33XX_AUTO_DPLL_MODE_SHIFT 0 +#define AM33XX_AUTO_DPLL_MODE_MASK (0x7 << 0) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_ADC_FCLK_SHIFT 14 +#define AM33XX_CLKACTIVITY_ADC_FCLK_MASK (1 << 16) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CAN_CLK_SHIFT 11 +#define AM33XX_CLKACTIVITY_CAN_CLK_MASK (1 << 11) + +/* Used by CM_PER_CLK_24MHZ_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_MASK (1 << 4) + +/* Used by CM_PER_CPSW_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_MASK (1 << 4) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_MASK (1 << 4) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_SHIFT 5 +#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_MASK (1 << 5) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_SHIFT 6 +#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_MASK (1 << 6) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_SHIFT 6 +#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_MASK (1 << 6) + +/* Used by CM_CEFUSE_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9 +#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9) + +/* Used by CM_L3_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_DBGSYSCLK_SHIFT 2 +#define AM33XX_CLKACTIVITY_DBGSYSCLK_MASK (1 << 2) + +/* Used by CM_L3_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_DEBUG_CLKA_SHIFT 4 +#define AM33XX_CLKACTIVITY_DEBUG_CLKA_MASK (1 << 4) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_EMIF_GCLK_SHIFT 2 +#define AM33XX_CLKACTIVITY_EMIF_GCLK_MASK (1 << 2) + +/* Used by CM_GFX_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GFX_FCLK_SHIFT 9 +#define AM33XX_CLKACTIVITY_GFX_FCLK_MASK (1 << 9) + +/* Used by CM_GFX_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_MASK (1 << 8) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_MASK (1 << 8) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_SHIFT 19 +#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_MASK (1 << 19) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_SHIFT 20 +#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_MASK (1 << 20) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_SHIFT 21 +#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_MASK (1 << 21) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_SHIFT 22 +#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_MASK (1 << 22) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_SHIFT 26 +#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_MASK (1 << 26) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_SHIFT 18 +#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_MASK (1 << 18) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_I2C0_GFCLK_SHIFT 11 +#define AM33XX_CLKACTIVITY_I2C0_GFCLK_MASK (1 << 11) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_I2C_FCLK_SHIFT 24 +#define AM33XX_CLKACTIVITY_I2C_FCLK_MASK (1 << 24) + +/* Used by CM_PER_PRUSS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_SHIFT 5 +#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_MASK (1 << 5) + +/* Used by CM_PER_PRUSS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_MASK (1 << 4) + +/* Used by CM_PER_PRUSS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_SHIFT 6 +#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_MASK (1 << 6) + +/* Used by CM_PER_L3S_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L3S_GCLK_SHIFT 3 +#define AM33XX_CLKACTIVITY_L3S_GCLK_MASK (1 << 3) + +/* Used by CM_L3_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L3_AON_GCLK_SHIFT 3 +#define AM33XX_CLKACTIVITY_L3_AON_GCLK_MASK (1 << 3) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L3_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_L3_GCLK_MASK (1 << 4) + +/* Used by CM_PER_L4FW_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4FW_GCLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_L4FW_GCLK_MASK (1 << 8) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4HS_GCLK_SHIFT 3 +#define AM33XX_CLKACTIVITY_L4HS_GCLK_MASK (1 << 3) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4LS_GCLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_L4LS_GCLK_MASK (1 << 8) + +/* Used by CM_GFX_L4LS_GFX_CLKSTCTRL__1 */ +#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_MASK (1 << 8) + +/* Used by CM_CEFUSE_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_MASK (1 << 8) + +/* Used by CM_RTC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_SHIFT 8 +#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_MASK (1 << 8) + +/* Used by CM_L4_WKUP_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_SHIFT 2 +#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_MASK (1 << 2) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_SHIFT 2 +#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_MASK (1 << 2) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_LCDC_GCLK_SHIFT 17 +#define AM33XX_CLKACTIVITY_LCDC_GCLK_MASK (1 << 17) + +/* Used by CM_PER_LCDC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_MASK (1 << 4) + +/* Used by CM_PER_LCDC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_SHIFT 5 +#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_MASK (1 << 5) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_MCASP_GCLK_SHIFT 7 +#define AM33XX_CLKACTIVITY_MCASP_GCLK_MASK (1 << 7) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_MMC_FCLK_SHIFT 3 +#define AM33XX_CLKACTIVITY_MMC_FCLK_MASK (1 << 3) + +/* Used by CM_MPU_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_MPU_CLK_SHIFT 2 +#define AM33XX_CLKACTIVITY_MPU_CLK_MASK (1 << 2) + +/* Used by CM_PER_OCPWP_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_MASK (1 << 4) + +/* Used by CM_PER_OCPWP_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_SHIFT 5 +#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_MASK (1 << 5) + +/* Used by CM_RTC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_RTC_32KCLK_SHIFT 9 +#define AM33XX_CLKACTIVITY_RTC_32KCLK_MASK (1 << 9) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_SPI_GCLK_SHIFT 25 +#define AM33XX_CLKACTIVITY_SPI_GCLK_MASK (1 << 25) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_SR_SYSCLK_SHIFT 3 +#define AM33XX_CLKACTIVITY_SR_SYSCLK_MASK (1 << 3) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER0_GCLK_SHIFT 10 +#define AM33XX_CLKACTIVITY_TIMER0_GCLK_MASK (1 << 10) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER1_GCLK_SHIFT 13 +#define AM33XX_CLKACTIVITY_TIMER1_GCLK_MASK (1 << 13) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER2_GCLK_SHIFT 14 +#define AM33XX_CLKACTIVITY_TIMER2_GCLK_MASK (1 << 14) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER3_GCLK_SHIFT 15 +#define AM33XX_CLKACTIVITY_TIMER3_GCLK_MASK (1 << 15) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER4_GCLK_SHIFT 16 +#define AM33XX_CLKACTIVITY_TIMER4_GCLK_MASK (1 << 16) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER5_GCLK_SHIFT 27 +#define AM33XX_CLKACTIVITY_TIMER5_GCLK_MASK (1 << 27) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER6_GCLK_SHIFT 28 +#define AM33XX_CLKACTIVITY_TIMER6_GCLK_MASK (1 << 28) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER7_GCLK_SHIFT 13 +#define AM33XX_CLKACTIVITY_TIMER7_GCLK_MASK (1 << 13) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_UART0_GFCLK_SHIFT 12 +#define AM33XX_CLKACTIVITY_UART0_GFCLK_MASK (1 << 12) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_UART_GFCLK_SHIFT 10 +#define AM33XX_CLKACTIVITY_UART_GFCLK_MASK (1 << 10) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_WDT0_GCLK_SHIFT 9 +#define AM33XX_CLKACTIVITY_WDT0_GCLK_MASK (1 << 9) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_WDT1_GCLK_SHIFT 4 +#define AM33XX_CLKACTIVITY_WDT1_GCLK_MASK (1 << 4) + +/* Used by CLKSEL_GFX_FCLK */ +#define AM33XX_CLKDIV_SEL_GFX_FCLK_SHIFT 0 +#define AM33XX_CLKDIV_SEL_GFX_FCLK_MASK (1 << 0) + +/* Used by CM_CLKOUT_CTRL */ +#define AM33XX_CLKOUT2DIV_SHIFT 3 +#define AM33XX_CLKOUT2DIV_MASK (0x05 << 3) + +/* Used by CM_CLKOUT_CTRL */ +#define AM33XX_CLKOUT2EN_SHIFT 7 +#define AM33XX_CLKOUT2EN_MASK (1 << 7) + +/* Used by CM_CLKOUT_CTRL */ +#define AM33XX_CLKOUT2SOURCE_SHIFT 0 +#define AM33XX_CLKOUT2SOURCE_MASK (0x02 << 0) + +/* + * Used by CLKSEL_GPIO0_DBCLK, CLKSEL_LCDC_PIXEL_CLK, CLKSEL_TIMER2_CLK, + * CLKSEL_TIMER3_CLK, CLKSEL_TIMER4_CLK, CLKSEL_TIMER5_CLK, CLKSEL_TIMER6_CLK, + * CLKSEL_TIMER7_CLK + */ +#define AM33XX_CLKSEL_SHIFT 0 +#define AM33XX_CLKSEL_MASK (0x01 << 0) + +/* + * Renamed from CLKSEL Used by CLKSEL_PRUSS_OCP_CLK, CLKSEL_WDT1_CLK, + * CM_CPTS_RFT_CLKSEL + */ +#define AM33XX_CLKSEL_0_0_SHIFT 0 +#define AM33XX_CLKSEL_0_0_MASK (1 << 0) + +#define AM33XX_CLKSEL_0_1_SHIFT 0 +#define AM33XX_CLKSEL_0_1_MASK (3 << 0) + +/* Renamed from CLKSEL Used by CLKSEL_TIMER1MS_CLK */ +#define AM33XX_CLKSEL_0_2_SHIFT 0 +#define AM33XX_CLKSEL_0_2_MASK (7 << 0) + +/* Used by CLKSEL_GFX_FCLK */ +#define AM33XX_CLKSEL_GFX_FCLK_SHIFT 1 +#define AM33XX_CLKSEL_GFX_FCLK_MASK (1 << 1) + +/* + * Used by CM_MPU_CLKSTCTRL, CM_RTC_CLKSTCTRL, CM_PER_CLK_24MHZ_CLKSTCTRL, + * CM_PER_CPSW_CLKSTCTRL, CM_PER_PRUSS_CLKSTCTRL, CM_PER_L3S_CLKSTCTRL, + * CM_PER_L3_CLKSTCTRL, CM_PER_L4FW_CLKSTCTRL, CM_PER_L4HS_CLKSTCTRL, + * CM_PER_L4LS_CLKSTCTRL, CM_PER_LCDC_CLKSTCTRL, CM_PER_OCPWP_L3_CLKSTCTRL, + * CM_L3_AON_CLKSTCTRL, CM_L4_WKUP_AON_CLKSTCTRL, CM_WKUP_CLKSTCTRL, + * CM_GFX_L3_CLKSTCTRL, CM_GFX_L4LS_GFX_CLKSTCTRL__1, CM_CEFUSE_CLKSTCTRL + */ +#define AM33XX_CLKTRCTRL_SHIFT 0 +#define AM33XX_CLKTRCTRL_MASK (0x3 << 0) + +/* + * Used by CM_SSC_DELTAMSTEP_DPLL_CORE, CM_SSC_DELTAMSTEP_DPLL_DDR, + * CM_SSC_DELTAMSTEP_DPLL_DISP, CM_SSC_DELTAMSTEP_DPLL_MPU, + * CM_SSC_DELTAMSTEP_DPLL_PER + */ +#define AM33XX_DELTAMSTEP_SHIFT 0 +#define AM33XX_DELTAMSTEP_MASK (0x19 << 0) + +/* Used by CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, CM_CLKSEL_DPLL_MPU */ +#define AM33XX_DPLL_BYP_CLKSEL_SHIFT 23 +#define AM33XX_DPLL_BYP_CLKSEL_MASK (1 << 23) + +/* Used by CM_CLKDCOLDO_DPLL_PER */ +#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT 8 +#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_MASK (1 << 8) + +/* Used by CM_CLKDCOLDO_DPLL_PER */ +#define AM33XX_DPLL_CLKDCOLDO_PWDN_SHIFT 12 +#define AM33XX_DPLL_CLKDCOLDO_PWDN_MASK (1 << 12) + +/* Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU */ +#define AM33XX_DPLL_CLKOUT_DIV_SHIFT 0 +#define AM33XX_DPLL_CLKOUT_DIV_MASK (0x1f << 0) + +/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_PER */ +#define AM33XX_DPLL_CLKOUT_DIV_0_6_SHIFT 0 +#define AM33XX_DPLL_CLKOUT_DIV_0_6_MASK (0x06 << 0) + +/* Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU */ +#define AM33XX_DPLL_CLKOUT_DIVCHACK_SHIFT 5 +#define AM33XX_DPLL_CLKOUT_DIVCHACK_MASK (1 << 5) + +/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_PER */ +#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_SHIFT 7 +#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_MASK (1 << 7) + +/* + * Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU, + * CM_DIV_M2_DPLL_PER + */ +#define AM33XX_DPLL_CLKOUT_GATE_CTRL_SHIFT 8 +#define AM33XX_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8) + +/* + * Used by CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, + * CM_CLKSEL_DPLL_MPU + */ +#define AM33XX_DPLL_DIV_SHIFT 0 +#define AM33XX_DPLL_DIV_MASK (0x7f << 0) + +#define AM33XX_DPLL_PER_DIV_MASK (0xff << 0) + +/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_PERIPH */ +#define AM33XX_DPLL_DIV_0_7_SHIFT 0 +#define AM33XX_DPLL_DIV_0_7_MASK (0x07 << 0) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU + */ +#define AM33XX_DPLL_DRIFTGUARD_EN_SHIFT 8 +#define AM33XX_DPLL_DRIFTGUARD_EN_MASK (1 << 8) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_EN_SHIFT 0 +#define AM33XX_DPLL_EN_MASK (0x7 << 0) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU + */ +#define AM33XX_DPLL_LPMODE_EN_SHIFT 10 +#define AM33XX_DPLL_LPMODE_EN_MASK (1 << 10) + +/* + * Used by CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, + * CM_CLKSEL_DPLL_MPU + */ +#define AM33XX_DPLL_MULT_SHIFT 8 +#define AM33XX_DPLL_MULT_MASK (0x7ff << 8) + +/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_PERIPH */ +#define AM33XX_DPLL_MULT_PERIPH_SHIFT 8 +#define AM33XX_DPLL_MULT_PERIPH_MASK (0xfff << 8) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU + */ +#define AM33XX_DPLL_REGM4XEN_SHIFT 11 +#define AM33XX_DPLL_REGM4XEN_MASK (1 << 11) + +/* Used by CM_CLKSEL_DPLL_PERIPH */ +#define AM33XX_DPLL_SD_DIV_SHIFT 24 +#define AM33XX_DPLL_SD_DIV_MASK (24, 31) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_SSC_ACK_SHIFT 13 +#define AM33XX_DPLL_SSC_ACK_MASK (1 << 13) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_SSC_DOWNSPREAD_SHIFT 14 +#define AM33XX_DPLL_SSC_DOWNSPREAD_MASK (1 << 14) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_SSC_EN_SHIFT 12 +#define AM33XX_DPLL_SSC_EN_MASK (1 << 12) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT 0 +#define AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT 5 +#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_MASK (1 << 5) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT 8 +#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK (1 << 8) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_SHIFT 12 +#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_MASK (1 << 12) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT 0 +#define AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT 5 +#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_MASK (1 << 5) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT 8 +#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK (1 << 8) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_SHIFT 12 +#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_MASK (1 << 12) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT 0 +#define AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK (0x04 << 0) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT 5 +#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_MASK (1 << 5) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT 8 +#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK (1 << 8) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_SHIFT 12 +#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_MASK (1 << 12) + +/* + * Used by CM_MPU_MPU_CLKCTRL, CM_RTC_RTC_CLKCTRL, CM_PER_AES0_CLKCTRL, + * CM_PER_AES1_CLKCTRL, CM_PER_CLKDIV32K_CLKCTRL, CM_PER_CPGMAC0_CLKCTRL, + * CM_PER_DCAN0_CLKCTRL, CM_PER_DCAN1_CLKCTRL, CM_PER_DES_CLKCTRL, + * CM_PER_ELM_CLKCTRL, CM_PER_EMIF_CLKCTRL, CM_PER_EMIF_FW_CLKCTRL, + * CM_PER_EPWMSS0_CLKCTRL, CM_PER_EPWMSS1_CLKCTRL, CM_PER_EPWMSS2_CLKCTRL, + * CM_PER_GPIO1_CLKCTRL, CM_PER_GPIO2_CLKCTRL, CM_PER_GPIO3_CLKCTRL, + * CM_PER_GPIO4_CLKCTRL, CM_PER_GPIO5_CLKCTRL, CM_PER_GPIO6_CLKCTRL, + * CM_PER_GPMC_CLKCTRL, CM_PER_I2C1_CLKCTRL, CM_PER_I2C2_CLKCTRL, + * CM_PER_PRUSS_CLKCTRL, CM_PER_IEEE5000_CLKCTRL, CM_PER_L3_CLKCTRL, + * CM_PER_L3_INSTR_CLKCTRL, CM_PER_L4FW_CLKCTRL, CM_PER_L4HS_CLKCTRL, + * CM_PER_L4LS_CLKCTRL, CM_PER_LCDC_CLKCTRL, CM_PER_MAILBOX0_CLKCTRL, + * CM_PER_MAILBOX1_CLKCTRL, CM_PER_MCASP0_CLKCTRL, CM_PER_MCASP1_CLKCTRL, + * CM_PER_MCASP2_CLKCTRL, CM_PER_MLB_CLKCTRL, CM_PER_MMC0_CLKCTRL, + * CM_PER_MMC1_CLKCTRL, CM_PER_MMC2_CLKCTRL, CM_PER_MSTR_EXPS_CLKCTRL, + * CM_PER_OCMCRAM_CLKCTRL, CM_PER_OCPWP_CLKCTRL, CM_PER_PCIE_CLKCTRL, + * CM_PER_PKA_CLKCTRL, CM_PER_RNG_CLKCTRL, CM_PER_SHA0_CLKCTRL, + * CM_PER_SLV_EXPS_CLKCTRL, CM_PER_SPARE0_CLKCTRL, CM_PER_SPARE1_CLKCTRL, + * CM_PER_SPARE_CLKCTRL, CM_PER_SPI0_CLKCTRL, CM_PER_SPI1_CLKCTRL, + * CM_PER_SPI2_CLKCTRL, CM_PER_SPI3_CLKCTRL, CM_PER_SPINLOCK_CLKCTRL, + * CM_PER_TIMER2_CLKCTRL, CM_PER_TIMER3_CLKCTRL, CM_PER_TIMER4_CLKCTRL, + * CM_PER_TIMER5_CLKCTRL, CM_PER_TIMER6_CLKCTRL, CM_PER_TIMER7_CLKCTRL, + * CM_PER_TPCC_CLKCTRL, CM_PER_TPTC0_CLKCTRL, CM_PER_TPTC1_CLKCTRL, + * CM_PER_TPTC2_CLKCTRL, CM_PER_UART1_CLKCTRL, CM_PER_UART2_CLKCTRL, + * CM_PER_UART3_CLKCTRL, CM_PER_UART4_CLKCTRL, CM_PER_UART5_CLKCTRL, + * CM_PER_USB0_CLKCTRL, CM_WKUP_ADC_TSC_CLKCTRL, CM_WKUP_CONTROL_CLKCTRL, + * CM_WKUP_DEBUGSS_CLKCTRL, CM_WKUP_GPIO0_CLKCTRL, CM_WKUP_I2C0_CLKCTRL, + * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_SMARTREFLEX0_CLKCTRL, + * CM_WKUP_SMARTREFLEX1_CLKCTRL, CM_WKUP_TIMER0_CLKCTRL, + * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_UART0_CLKCTRL, CM_WKUP_WDT0_CLKCTRL, + * CM_WKUP_WDT1_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, CM_GFX_GFX_CLKCTRL, + * CM_GFX_MMUCFG_CLKCTRL, CM_GFX_MMUDATA_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL + */ +#define AM33XX_IDLEST_SHIFT 16 +#define AM33XX_IDLEST_MASK (0x3 << 16) +#define AM33XX_IDLEST_VAL 0x3 + +/* Used by CM_MAC_CLKSEL */ +#define AM33XX_MII_CLK_SEL_SHIFT 2 +#define AM33XX_MII_CLK_SEL_MASK (1 << 2) + +/* + * Used by CM_SSC_MODFREQDIV_DPLL_CORE, CM_SSC_MODFREQDIV_DPLL_DDR, + * CM_SSC_MODFREQDIV_DPLL_DISP, CM_SSC_MODFREQDIV_DPLL_MPU, + * CM_SSC_MODFREQDIV_DPLL_PER + */ +#define AM33XX_MODFREQDIV_EXPONENT_SHIFT 8 +#define AM33XX_MODFREQDIV_EXPONENT_MASK (0x10 << 8) + +/* + * Used by CM_SSC_MODFREQDIV_DPLL_CORE, CM_SSC_MODFREQDIV_DPLL_DDR, + * CM_SSC_MODFREQDIV_DPLL_DISP, CM_SSC_MODFREQDIV_DPLL_MPU, + * CM_SSC_MODFREQDIV_DPLL_PER + */ +#define AM33XX_MODFREQDIV_MANTISSA_SHIFT 0 +#define AM33XX_MODFREQDIV_MANTISSA_MASK (0x06 << 0) + +/* + * Used by CM_MPU_MPU_CLKCTRL, CM_RTC_RTC_CLKCTRL, CM_PER_AES0_CLKCTRL, + * CM_PER_AES1_CLKCTRL, CM_PER_CLKDIV32K_CLKCTRL, CM_PER_CPGMAC0_CLKCTRL, + * CM_PER_DCAN0_CLKCTRL, CM_PER_DCAN1_CLKCTRL, CM_PER_DES_CLKCTRL, + * CM_PER_ELM_CLKCTRL, CM_PER_EMIF_CLKCTRL, CM_PER_EMIF_FW_CLKCTRL, + * CM_PER_EPWMSS0_CLKCTRL, CM_PER_EPWMSS1_CLKCTRL, CM_PER_EPWMSS2_CLKCTRL, + * CM_PER_GPIO1_CLKCTRL, CM_PER_GPIO2_CLKCTRL, CM_PER_GPIO3_CLKCTRL, + * CM_PER_GPIO4_CLKCTRL, CM_PER_GPIO5_CLKCTRL, CM_PER_GPIO6_CLKCTRL, + * CM_PER_GPMC_CLKCTRL, CM_PER_I2C1_CLKCTRL, CM_PER_I2C2_CLKCTRL, + * CM_PER_PRUSS_CLKCTRL, CM_PER_IEEE5000_CLKCTRL, CM_PER_L3_CLKCTRL, + * CM_PER_L3_INSTR_CLKCTRL, CM_PER_L4FW_CLKCTRL, CM_PER_L4HS_CLKCTRL, + * CM_PER_L4LS_CLKCTRL, CM_PER_LCDC_CLKCTRL, CM_PER_MAILBOX0_CLKCTRL, + * CM_PER_MAILBOX1_CLKCTRL, CM_PER_MCASP0_CLKCTRL, CM_PER_MCASP1_CLKCTRL, + * CM_PER_MCASP2_CLKCTRL, CM_PER_MLB_CLKCTRL, CM_PER_MMC0_CLKCTRL, + * CM_PER_MMC1_CLKCTRL, CM_PER_MMC2_CLKCTRL, CM_PER_MSTR_EXPS_CLKCTRL, + * CM_PER_OCMCRAM_CLKCTRL, CM_PER_OCPWP_CLKCTRL, CM_PER_PCIE_CLKCTRL, + * CM_PER_PKA_CLKCTRL, CM_PER_RNG_CLKCTRL, CM_PER_SHA0_CLKCTRL, + * CM_PER_SLV_EXPS_CLKCTRL, CM_PER_SPARE0_CLKCTRL, CM_PER_SPARE1_CLKCTRL, + * CM_PER_SPARE_CLKCTRL, CM_PER_SPI0_CLKCTRL, CM_PER_SPI1_CLKCTRL, + * CM_PER_SPI2_CLKCTRL, CM_PER_SPI3_CLKCTRL, CM_PER_SPINLOCK_CLKCTRL, + * CM_PER_TIMER2_CLKCTRL, CM_PER_TIMER3_CLKCTRL, CM_PER_TIMER4_CLKCTRL, + * CM_PER_TIMER5_CLKCTRL, CM_PER_TIMER6_CLKCTRL, CM_PER_TIMER7_CLKCTRL, + * CM_PER_TPCC_CLKCTRL, CM_PER_TPTC0_CLKCTRL, CM_PER_TPTC1_CLKCTRL, + * CM_PER_TPTC2_CLKCTRL, CM_PER_UART1_CLKCTRL, CM_PER_UART2_CLKCTRL, + * CM_PER_UART3_CLKCTRL, CM_PER_UART4_CLKCTRL, CM_PER_UART5_CLKCTRL, + * CM_PER_USB0_CLKCTRL, CM_WKUP_ADC_TSC_CLKCTRL, CM_WKUP_CONTROL_CLKCTRL, + * CM_WKUP_DEBUGSS_CLKCTRL, CM_WKUP_GPIO0_CLKCTRL, CM_WKUP_I2C0_CLKCTRL, + * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_SMARTREFLEX0_CLKCTRL, + * CM_WKUP_SMARTREFLEX1_CLKCTRL, CM_WKUP_TIMER0_CLKCTRL, + * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_UART0_CLKCTRL, CM_WKUP_WDT0_CLKCTRL, + * CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WKUP_M3_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, + * CM_GFX_GFX_CLKCTRL, CM_GFX_MMUCFG_CLKCTRL, CM_GFX_MMUDATA_CLKCTRL, + * CM_CEFUSE_CEFUSE_CLKCTRL + */ +#define AM33XX_MODULEMODE_SHIFT 0 +#define AM33XX_MODULEMODE_MASK (0x3 << 0) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_OPTCLK_DEBUG_CLKA_SHIFT 30 +#define AM33XX_OPTCLK_DEBUG_CLKA_MASK (1 << 30) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT 19 +#define AM33XX_OPTFCLKEN_DBGSYSCLK_MASK (1 << 19) + +/* Used by CM_WKUP_GPIO0_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_MASK (1 << 18) + +/* Used by CM_PER_GPIO1_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_MASK (1 << 18) + +/* Used by CM_PER_GPIO2_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_MASK (1 << 18) + +/* Used by CM_PER_GPIO3_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_MASK (1 << 18) + +/* Used by CM_PER_GPIO4_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_MASK (1 << 18) + +/* Used by CM_PER_GPIO5_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_MASK (1 << 18) + +/* Used by CM_PER_GPIO6_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_MASK (1 << 18) + +/* + * Used by CM_MPU_MPU_CLKCTRL, CM_PER_CPGMAC0_CLKCTRL, CM_PER_PRUSS_CLKCTRL, + * CM_PER_IEEE5000_CLKCTRL, CM_PER_LCDC_CLKCTRL, CM_PER_MLB_CLKCTRL, + * CM_PER_MSTR_EXPS_CLKCTRL, CM_PER_OCPWP_CLKCTRL, CM_PER_PCIE_CLKCTRL, + * CM_PER_SPARE_CLKCTRL, CM_PER_TPTC0_CLKCTRL, CM_PER_TPTC1_CLKCTRL, + * CM_PER_TPTC2_CLKCTRL, CM_PER_USB0_CLKCTRL, CM_WKUP_DEBUGSS_CLKCTRL, + * CM_WKUP_WKUP_M3_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, CM_GFX_GFX_CLKCTRL + */ +#define AM33XX_STBYST_SHIFT 18 +#define AM33XX_STBYST_MASK (1 << 18) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_STM_PMD_CLKDIVSEL_SHIFT 27 +#define AM33XX_STM_PMD_CLKDIVSEL_MASK (0x29 << 27) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_STM_PMD_CLKSEL_SHIFT 22 +#define AM33XX_STM_PMD_CLKSEL_MASK (0x23 << 22) + +/* + * Used by CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDR, CM_IDLEST_DPLL_DISP, + * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER + */ +#define AM33XX_ST_DPLL_CLK_SHIFT 0 +#define AM33XX_ST_DPLL_CLK_MASK (1 << 0) + +/* Used by CM_CLKDCOLDO_DPLL_PER */ +#define AM33XX_ST_DPLL_CLKDCOLDO_SHIFT 8 +#define AM33XX_ST_DPLL_CLKDCOLDO_MASK (1 << 8) + +/* + * Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU, + * CM_DIV_M2_DPLL_PER + */ +#define AM33XX_ST_DPLL_CLKOUT_SHIFT 9 +#define AM33XX_ST_DPLL_CLKOUT_MASK (1 << 9) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_ST_HSDIVIDER_CLKOUT1_SHIFT 9 +#define AM33XX_ST_HSDIVIDER_CLKOUT1_MASK (1 << 9) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_ST_HSDIVIDER_CLKOUT2_SHIFT 9 +#define AM33XX_ST_HSDIVIDER_CLKOUT2_MASK (1 << 9) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_ST_HSDIVIDER_CLKOUT3_SHIFT 9 +#define AM33XX_ST_HSDIVIDER_CLKOUT3_MASK (1 << 9) + +/* + * Used by CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDR, CM_IDLEST_DPLL_DISP, + * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER + */ +#define AM33XX_ST_MN_BYPASS_SHIFT 8 +#define AM33XX_ST_MN_BYPASS_MASK (1 << 8) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_TRC_PMD_CLKDIVSEL_SHIFT 24 +#define AM33XX_TRC_PMD_CLKDIVSEL_MASK (0x26 << 24) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_TRC_PMD_CLKSEL_SHIFT 20 +#define AM33XX_TRC_PMD_CLKSEL_MASK (0x21 << 20) + +/* Used by CONTROL_SEC_CLK_CTRL */ +#define AM33XX_TIMER0_CLKSEL_MASK (0x3 << 4) +#endif diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c new file mode 100644 index 000000000000..13f56eafef03 --- /dev/null +++ b/arch/arm/mach-omap2/cm33xx.c @@ -0,0 +1,313 @@ +/* + * AM33XX CM functions + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath + * + * Reference taken from from OMAP4 cminst44xx.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include + +#include "cm.h" +#include "cm33xx.h" +#include "cm-regbits-34xx.h" +#include "cm-regbits-33xx.h" +#include "prm33xx.h" + +/* + * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: + * + * 0x0 func: Module is fully functional, including OCP + * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep + * abortion + * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if + * using separate functional clock + * 0x3 disabled: Module is disabled and cannot be accessed + * + */ +#define CLKCTRL_IDLEST_FUNCTIONAL 0x0 +#define CLKCTRL_IDLEST_INTRANSITION 0x1 +#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 +#define CLKCTRL_IDLEST_DISABLED 0x3 + +/* Private functions */ + +/* Read a register in a CM instance */ +static inline u32 am33xx_cm_read_reg(s16 inst, u16 idx) +{ + return __raw_readl(cm_base + inst + idx); +} + +/* Write into a register in a CM */ +static inline void am33xx_cm_write_reg(u32 val, s16 inst, u16 idx) +{ + __raw_writel(val, cm_base + inst + idx); +} + +/* Read-modify-write a register in CM */ +static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, idx); + v &= ~mask; + v |= bits; + am33xx_cm_write_reg(v, inst, idx); + + return v; +} + +static inline u32 am33xx_cm_set_reg_bits(u32 bits, s16 inst, s16 idx) +{ + return am33xx_cm_rmw_reg_bits(bits, bits, inst, idx); +} + +static inline u32 am33xx_cm_clear_reg_bits(u32 bits, s16 inst, s16 idx) +{ + return am33xx_cm_rmw_reg_bits(bits, 0x0, inst, idx); +} + +static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, idx); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +/** + * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to + * bit 0. + */ +static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); + v &= AM33XX_IDLEST_MASK; + v >>= AM33XX_IDLEST_SHIFT; + return v; +} + +/** + * _is_module_ready - can module registers be accessed without causing an abort? + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either + * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. + */ +static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = _clkctrl_idlest(inst, cdoffs, clkctrl_offs); + + return (v == CLKCTRL_IDLEST_FUNCTIONAL || + v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; +} + +/** + * _clktrctrl_write - write @c to a CM_CLKSTCTRL.CLKTRCTRL register bitfield + * @c: CLKTRCTRL register bitfield (LSB = bit 0, i.e., unshifted) + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * @c must be the unshifted value for CLKTRCTRL - i.e., this function + * will handle the shift itself. + */ +static void _clktrctrl_write(u8 c, s16 inst, u16 cdoffs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, cdoffs); + v &= ~AM33XX_CLKTRCTRL_MASK; + v |= c << AM33XX_CLKTRCTRL_SHIFT; + am33xx_cm_write_reg(v, inst, cdoffs); +} + +/* Public functions */ + +/** + * am33xx_cm_is_clkdm_in_hwsup - is a clockdomain in hwsup idle mode? + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Returns true if the clockdomain referred to by (@inst, @cdoffs) + * is in hardware-supervised idle mode, or 0 otherwise. + */ +bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, cdoffs); + v &= AM33XX_CLKTRCTRL_MASK; + v >>= AM33XX_CLKTRCTRL_SHIFT; + + return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? true : false; +} + +/** + * am33xx_cm_clkdm_enable_hwsup - put a clockdomain in hwsup-idle mode + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@inst, @cdoffs) into + * hardware-supervised idle mode. No return value. + */ +void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); +} + +/** + * am33xx_cm_clkdm_disable_hwsup - put a clockdomain in swsup-idle mode + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@inst, @cdoffs) into + * software-supervised idle mode, i.e., controlled manually by the + * Linux OMAP clockdomain code. No return value. + */ +void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); +} + +/** + * am33xx_cm_clkdm_force_sleep - try to put a clockdomain into idle + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@inst, @cdoffs) into idle + * No return value. + */ +void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); +} + +/** + * am33xx_cm_clkdm_force_wakeup - try to take a clockdomain out of idle + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, + * waking it up. No return value. + */ +void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); +} + +/* + * + */ + +/** + * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Wait for the module IDLEST to be functional. If the idle state is in any + * the non functional state (trans, idle or disabled), module and thus the + * sysconfig cannot be accessed and will probably lead to an "imprecise + * external abort" + */ +int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + int i = 0; + + if (!clkctrl_offs) + return 0; + + omap_test_timeout(_is_module_ready(inst, cdoffs, clkctrl_offs), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' + * state + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Wait for the module IDLEST to be disabled. Some PRCM transition, + * like reset assertion or parent clock de-activation must wait the + * module to be fully disabled. + */ +int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + int i = 0; + + if (!clkctrl_offs) + return 0; + + omap_test_timeout((_clkctrl_idlest(inst, cdoffs, clkctrl_offs) == + CLKCTRL_IDLEST_DISABLED), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL + * @mode: Module mode (SW or HW) + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, clkctrl_offs); + v &= ~AM33XX_MODULEMODE_MASK; + v |= mode << AM33XX_MODULEMODE_SHIFT; + am33xx_cm_write_reg(v, inst, clkctrl_offs); +} + +/** + * am33xx_cm_module_disable - Disable the module inside CLKCTRL + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, clkctrl_offs); + v &= ~AM33XX_MODULEMODE_MASK; + am33xx_cm_write_reg(v, inst, clkctrl_offs); +} diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h new file mode 100644 index 000000000000..5fa0b62e1a79 --- /dev/null +++ b/arch/arm/mach-omap2/cm33xx.h @@ -0,0 +1,420 @@ +/* + * AM33XX CM offset macros + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_33XX_H + +#include +#include +#include +#include + +#include "common.h" + +#include "cm.h" +#include "cm-regbits-33xx.h" +#include "cm33xx.h" + +/* CM base address */ +#define AM33XX_CM_BASE 0x44e00000 + +#define AM33XX_CM_REGADDR(inst, reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_CM_BASE + (inst) + (reg)) + +/* CM instances */ +#define AM33XX_CM_PER_MOD 0x0000 +#define AM33XX_CM_WKUP_MOD 0x0400 +#define AM33XX_CM_DPLL_MOD 0x0500 +#define AM33XX_CM_MPU_MOD 0x0600 +#define AM33XX_CM_DEVICE_MOD 0x0700 +#define AM33XX_CM_RTC_MOD 0x0800 +#define AM33XX_CM_GFX_MOD 0x0900 +#define AM33XX_CM_CEFUSE_MOD 0x0A00 + +/* CM */ + +/* CM.PER_CM register offsets */ +#define AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_PER_L4LS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0000) +#define AM33XX_CM_PER_L3S_CLKSTCTRL_OFFSET 0x0004 +#define AM33XX_CM_PER_L3S_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0004) +#define AM33XX_CM_PER_L4FW_CLKSTCTRL_OFFSET 0x0008 +#define AM33XX_CM_PER_L4FW_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0008) +#define AM33XX_CM_PER_L3_CLKSTCTRL_OFFSET 0x000c +#define AM33XX_CM_PER_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x000c) +#define AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0014 +#define AM33XX_CM_PER_CPGMAC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0014) +#define AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET 0x0018 +#define AM33XX_CM_PER_LCDC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0018) +#define AM33XX_CM_PER_USB0_CLKCTRL_OFFSET 0x001c +#define AM33XX_CM_PER_USB0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x001c) +#define AM33XX_CM_PER_MLB_CLKCTRL_OFFSET 0x0020 +#define AM33XX_CM_PER_MLB_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0020) +#define AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0024 +#define AM33XX_CM_PER_TPTC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0024) +#define AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET 0x0028 +#define AM33XX_CM_PER_EMIF_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0028) +#define AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x002c +#define AM33XX_CM_PER_OCMCRAM_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x002c) +#define AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0030 +#define AM33XX_CM_PER_GPMC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0030) +#define AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0034 +#define AM33XX_CM_PER_MCASP0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0034) +#define AM33XX_CM_PER_UART5_CLKCTRL_OFFSET 0x0038 +#define AM33XX_CM_PER_UART5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0038) +#define AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x003c +#define AM33XX_CM_PER_MMC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x003c) +#define AM33XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0040 +#define AM33XX_CM_PER_ELM_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0040) +#define AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x0044 +#define AM33XX_CM_PER_I2C2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0044) +#define AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x0048 +#define AM33XX_CM_PER_I2C1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0048) +#define AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x004c +#define AM33XX_CM_PER_SPI0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x004c) +#define AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0050 +#define AM33XX_CM_PER_SPI1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0050) +#define AM33XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0054 +#define AM33XX_CM_PER_SPI2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0054) +#define AM33XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0058 +#define AM33XX_CM_PER_SPI3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0058) +#define AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0060 +#define AM33XX_CM_PER_L4LS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0060) +#define AM33XX_CM_PER_L4FW_CLKCTRL_OFFSET 0x0064 +#define AM33XX_CM_PER_L4FW_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0064) +#define AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0068 +#define AM33XX_CM_PER_MCASP1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0068) +#define AM33XX_CM_PER_UART1_CLKCTRL_OFFSET 0x006c +#define AM33XX_CM_PER_UART1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x006c) +#define AM33XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0070 +#define AM33XX_CM_PER_UART2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0070) +#define AM33XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0074 +#define AM33XX_CM_PER_UART3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0074) +#define AM33XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0078 +#define AM33XX_CM_PER_UART4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0078) +#define AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x007c +#define AM33XX_CM_PER_TIMER7_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x007c) +#define AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0080 +#define AM33XX_CM_PER_TIMER2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0080) +#define AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0084 +#define AM33XX_CM_PER_TIMER3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0084) +#define AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0088 +#define AM33XX_CM_PER_TIMER4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0088) +#define AM33XX_CM_PER_MCASP2_CLKCTRL_OFFSET 0x008c +#define AM33XX_CM_PER_MCASP2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x008c) +#define AM33XX_CM_PER_RNG_CLKCTRL_OFFSET 0x0090 +#define AM33XX_CM_PER_RNG_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0090) +#define AM33XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0094 +#define AM33XX_CM_PER_AES0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0094) +#define AM33XX_CM_PER_AES1_CLKCTRL_OFFSET 0x0098 +#define AM33XX_CM_PER_AES1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0098) +#define AM33XX_CM_PER_DES_CLKCTRL_OFFSET 0x009c +#define AM33XX_CM_PER_DES_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x009c) +#define AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x00a0 +#define AM33XX_CM_PER_SHA0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a0) +#define AM33XX_CM_PER_PKA_CLKCTRL_OFFSET 0x00a4 +#define AM33XX_CM_PER_PKA_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a4) +#define AM33XX_CM_PER_GPIO6_CLKCTRL_OFFSET 0x00a8 +#define AM33XX_CM_PER_GPIO6_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a8) +#define AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x00ac +#define AM33XX_CM_PER_GPIO1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00ac) +#define AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x00b0 +#define AM33XX_CM_PER_GPIO2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b0) +#define AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x00b4 +#define AM33XX_CM_PER_GPIO3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b4) +#define AM33XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x00b8 +#define AM33XX_CM_PER_GPIO4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b8) +#define AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x00bc +#define AM33XX_CM_PER_TPCC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00bc) +#define AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x00c0 +#define AM33XX_CM_PER_DCAN0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00c0) +#define AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x00c4 +#define AM33XX_CM_PER_DCAN1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00c4) +#define AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x00cc +#define AM33XX_CM_PER_EPWMSS1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00cc) +#define AM33XX_CM_PER_EMIF_FW_CLKCTRL_OFFSET 0x00d0 +#define AM33XX_CM_PER_EMIF_FW_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d0) +#define AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x00d4 +#define AM33XX_CM_PER_EPWMSS0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d4) +#define AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x00d8 +#define AM33XX_CM_PER_EPWMSS2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d8) +#define AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x00dc +#define AM33XX_CM_PER_L3_INSTR_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00dc) +#define AM33XX_CM_PER_L3_CLKCTRL_OFFSET 0x00e0 +#define AM33XX_CM_PER_L3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e0) +#define AM33XX_CM_PER_IEEE5000_CLKCTRL_OFFSET 0x00e4 +#define AM33XX_CM_PER_IEEE5000_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e4) +#define AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x00e8 +#define AM33XX_CM_PER_PRUSS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e8) +#define AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x00ec +#define AM33XX_CM_PER_TIMER5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00ec) +#define AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x00f0 +#define AM33XX_CM_PER_TIMER6_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f0) +#define AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x00f4 +#define AM33XX_CM_PER_MMC1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f4) +#define AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x00f8 +#define AM33XX_CM_PER_MMC2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f8) +#define AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x00fc +#define AM33XX_CM_PER_TPTC1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00fc) +#define AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0100 +#define AM33XX_CM_PER_TPTC2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0100) +#define AM33XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0104 +#define AM33XX_CM_PER_GPIO5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0104) +#define AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x010c +#define AM33XX_CM_PER_SPINLOCK_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x010c) +#define AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x0110 +#define AM33XX_CM_PER_MAILBOX0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0110) +#define AM33XX_CM_PER_L4HS_CLKSTCTRL_OFFSET 0x011c +#define AM33XX_CM_PER_L4HS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x011c) +#define AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x0120 +#define AM33XX_CM_PER_L4HS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0120) +#define AM33XX_CM_PER_MSTR_EXPS_CLKCTRL_OFFSET 0x0124 +#define AM33XX_CM_PER_MSTR_EXPS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0124) +#define AM33XX_CM_PER_SLV_EXPS_CLKCTRL_OFFSET 0x0128 +#define AM33XX_CM_PER_SLV_EXPS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0128) +#define AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET 0x012c +#define AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x012c) +#define AM33XX_CM_PER_OCPWP_CLKCTRL_OFFSET 0x0130 +#define AM33XX_CM_PER_OCPWP_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0130) +#define AM33XX_CM_PER_MAILBOX1_CLKCTRL_OFFSET 0x0134 +#define AM33XX_CM_PER_MAILBOX1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0134) +#define AM33XX_CM_PER_PRUSS_CLKSTCTRL_OFFSET 0x0140 +#define AM33XX_CM_PER_PRUSS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0140) +#define AM33XX_CM_PER_CPSW_CLKSTCTRL_OFFSET 0x0144 +#define AM33XX_CM_PER_CPSW_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0144) +#define AM33XX_CM_PER_LCDC_CLKSTCTRL_OFFSET 0x0148 +#define AM33XX_CM_PER_LCDC_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0148) +#define AM33XX_CM_PER_CLKDIV32K_CLKCTRL_OFFSET 0x014c +#define AM33XX_CM_PER_CLKDIV32K_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x014c) +#define AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET 0x0150 +#define AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0150) + +/* CM.WKUP_CM register offsets */ +#define AM33XX_CM_WKUP_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_WKUP_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0000) +#define AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0004 +#define AM33XX_CM_WKUP_CONTROL_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0004) +#define AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0008 +#define AM33XX_CM_WKUP_GPIO0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0008) +#define AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x000c +#define AM33XX_CM_WKUP_L4WKUP_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x000c) +#define AM33XX_CM_WKUP_TIMER0_CLKCTRL_OFFSET 0x0010 +#define AM33XX_CM_WKUP_TIMER0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0010) +#define AM33XX_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET 0x0014 +#define AM33XX_CM_WKUP_DEBUGSS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0014) +#define AM33XX_CM_L3_AON_CLKSTCTRL_OFFSET 0x0018 +#define AM33XX_CM_L3_AON_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0018) +#define AM33XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x001c +#define AM33XX_CM_AUTOIDLE_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x001c) +#define AM33XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0020 +#define AM33XX_CM_IDLEST_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0020) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0024 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0024) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x0028 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0028) +#define AM33XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x002c +#define AM33XX_CM_CLKSEL_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x002c) +#define AM33XX_CM_AUTOIDLE_DPLL_DDR_OFFSET 0x0030 +#define AM33XX_CM_AUTOIDLE_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0030) +#define AM33XX_CM_IDLEST_DPLL_DDR_OFFSET 0x0034 +#define AM33XX_CM_IDLEST_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0034) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DDR_OFFSET 0x0038 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0038) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DDR_OFFSET 0x003c +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x003c) +#define AM33XX_CM_CLKSEL_DPLL_DDR_OFFSET 0x0040 +#define AM33XX_CM_CLKSEL_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0040) +#define AM33XX_CM_AUTOIDLE_DPLL_DISP_OFFSET 0x0044 +#define AM33XX_CM_AUTOIDLE_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0044) +#define AM33XX_CM_IDLEST_DPLL_DISP_OFFSET 0x0048 +#define AM33XX_CM_IDLEST_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0048) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DISP_OFFSET 0x004c +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x004c) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DISP_OFFSET 0x0050 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0050) +#define AM33XX_CM_CLKSEL_DPLL_DISP_OFFSET 0x0054 +#define AM33XX_CM_CLKSEL_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0054) +#define AM33XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0058 +#define AM33XX_CM_AUTOIDLE_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0058) +#define AM33XX_CM_IDLEST_DPLL_CORE_OFFSET 0x005c +#define AM33XX_CM_IDLEST_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x005c) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0060 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0060) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x0064 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0064) +#define AM33XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x0068 +#define AM33XX_CM_CLKSEL_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0068) +#define AM33XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x006c +#define AM33XX_CM_AUTOIDLE_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x006c) +#define AM33XX_CM_IDLEST_DPLL_PER_OFFSET 0x0070 +#define AM33XX_CM_IDLEST_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0070) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0074 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0074) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x0078 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0078) +#define AM33XX_CM_CLKDCOLDO_DPLL_PER_OFFSET 0x007c +#define AM33XX_CM_CLKDCOLDO_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x007c) +#define AM33XX_CM_DIV_M4_DPLL_CORE_OFFSET 0x0080 +#define AM33XX_CM_DIV_M4_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0080) +#define AM33XX_CM_DIV_M5_DPLL_CORE_OFFSET 0x0084 +#define AM33XX_CM_DIV_M5_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0084) +#define AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0088 +#define AM33XX_CM_CLKMODE_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0088) +#define AM33XX_CM_CLKMODE_DPLL_PER_OFFSET 0x008c +#define AM33XX_CM_CLKMODE_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x008c) +#define AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0090 +#define AM33XX_CM_CLKMODE_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0090) +#define AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET 0x0094 +#define AM33XX_CM_CLKMODE_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0094) +#define AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET 0x0098 +#define AM33XX_CM_CLKMODE_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0098) +#define AM33XX_CM_CLKSEL_DPLL_PERIPH_OFFSET 0x009c +#define AM33XX_CM_CLKSEL_DPLL_PERIPH AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x009c) +#define AM33XX_CM_DIV_M2_DPLL_DDR_OFFSET 0x00a0 +#define AM33XX_CM_DIV_M2_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a0) +#define AM33XX_CM_DIV_M2_DPLL_DISP_OFFSET 0x00a4 +#define AM33XX_CM_DIV_M2_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a4) +#define AM33XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x00a8 +#define AM33XX_CM_DIV_M2_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a8) +#define AM33XX_CM_DIV_M2_DPLL_PER_OFFSET 0x00ac +#define AM33XX_CM_DIV_M2_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00ac) +#define AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x00b0 +#define AM33XX_CM_WKUP_WKUP_M3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b0) +#define AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x00b4 +#define AM33XX_CM_WKUP_UART0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b4) +#define AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x00b8 +#define AM33XX_CM_WKUP_I2C0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b8) +#define AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x00bc +#define AM33XX_CM_WKUP_ADC_TSC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00bc) +#define AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x00c0 +#define AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c0) +#define AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x00c4 +#define AM33XX_CM_WKUP_TIMER1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c4) +#define AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x00c8 +#define AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c8) +#define AM33XX_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET 0x00cc +#define AM33XX_CM_L4_WKUP_AON_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00cc) +#define AM33XX_CM_WKUP_WDT0_CLKCTRL_OFFSET 0x00d0 +#define AM33XX_CM_WKUP_WDT0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d0) +#define AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x00d4 +#define AM33XX_CM_WKUP_WDT1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d4) +#define AM33XX_CM_DIV_M6_DPLL_CORE_OFFSET 0x00d8 +#define AM33XX_CM_DIV_M6_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d8) + +/* CM.DPLL_CM register offsets */ +#define AM33XX_CLKSEL_TIMER7_CLK_OFFSET 0x0004 +#define AM33XX_CLKSEL_TIMER7_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0004) +#define AM33XX_CLKSEL_TIMER2_CLK_OFFSET 0x0008 +#define AM33XX_CLKSEL_TIMER2_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0008) +#define AM33XX_CLKSEL_TIMER3_CLK_OFFSET 0x000c +#define AM33XX_CLKSEL_TIMER3_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x000c) +#define AM33XX_CLKSEL_TIMER4_CLK_OFFSET 0x0010 +#define AM33XX_CLKSEL_TIMER4_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0010) +#define AM33XX_CM_MAC_CLKSEL_OFFSET 0x0014 +#define AM33XX_CM_MAC_CLKSEL AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0014) +#define AM33XX_CLKSEL_TIMER5_CLK_OFFSET 0x0018 +#define AM33XX_CLKSEL_TIMER5_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0018) +#define AM33XX_CLKSEL_TIMER6_CLK_OFFSET 0x001c +#define AM33XX_CLKSEL_TIMER6_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x001c) +#define AM33XX_CM_CPTS_RFT_CLKSEL_OFFSET 0x0020 +#define AM33XX_CM_CPTS_RFT_CLKSEL AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0020) +#define AM33XX_CLKSEL_TIMER1MS_CLK_OFFSET 0x0028 +#define AM33XX_CLKSEL_TIMER1MS_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0028) +#define AM33XX_CLKSEL_GFX_FCLK_OFFSET 0x002c +#define AM33XX_CLKSEL_GFX_FCLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x002c) +#define AM33XX_CLKSEL_PRUSS_OCP_CLK_OFFSET 0x0030 +#define AM33XX_CLKSEL_PRUSS_OCP_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0030) +#define AM33XX_CLKSEL_LCDC_PIXEL_CLK_OFFSET 0x0034 +#define AM33XX_CLKSEL_LCDC_PIXEL_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0034) +#define AM33XX_CLKSEL_WDT1_CLK_OFFSET 0x0038 +#define AM33XX_CLKSEL_WDT1_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0038) +#define AM33XX_CLKSEL_GPIO0_DBCLK_OFFSET 0x003c +#define AM33XX_CLKSEL_GPIO0_DBCLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x003c) + +/* CM.MPU_CM register offsets */ +#define AM33XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_MPU_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_MPU_MOD, 0x0000) +#define AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0004 +#define AM33XX_CM_MPU_MPU_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_MPU_MOD, 0x0004) + +/* CM.DEVICE_CM register offsets */ +#define AM33XX_CM_CLKOUT_CTRL_OFFSET 0x0000 +#define AM33XX_CM_CLKOUT_CTRL AM33XX_CM_REGADDR(AM33XX_CM_DEVICE_MOD, 0x0000) + +/* CM.RTC_CM register offsets */ +#define AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0000 +#define AM33XX_CM_RTC_RTC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_RTC_MOD, 0x0000) +#define AM33XX_CM_RTC_CLKSTCTRL_OFFSET 0x0004 +#define AM33XX_CM_RTC_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_RTC_MOD, 0x0004) + +/* CM.GFX_CM register offsets */ +#define AM33XX_CM_GFX_L3_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_GFX_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0000) +#define AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0004 +#define AM33XX_CM_GFX_GFX_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0004) +#define AM33XX_CM_GFX_BITBLT_CLKCTRL_OFFSET 0x0008 +#define AM33XX_CM_GFX_BITBLT_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0008) +#define AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET 0x000c +#define AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1 AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x000c) +#define AM33XX_CM_GFX_MMUCFG_CLKCTRL_OFFSET 0x0010 +#define AM33XX_CM_GFX_MMUCFG_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0010) +#define AM33XX_CM_GFX_MMUDATA_CLKCTRL_OFFSET 0x0014 +#define AM33XX_CM_GFX_MMUDATA_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0014) + +/* CM.CEFUSE_CM register offsets */ +#define AM33XX_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_CEFUSE_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0000) +#define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020 +#define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020) + + +extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs); + +#ifdef CONFIG_SOC_AM33XX +extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, + u16 clkctrl_offs); +#else +static inline int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + return 0; +} +static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ +} +static inline void am33xx_cm_module_disable(u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ +} +static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + return 0; +} +#endif + +#endif -- GitLab From 3f0ea7645ae6d7111ebc3e83f47fbc0f2c8a8964 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 18 Jun 2012 00:47:27 -0600 Subject: [PATCH 1913/6849] ARM: OMAP AM33xx: powerdomains: add AM335x support Add offset & mask fields to struct powerdomain In case of AM33xx family of devices, there is no consistency between PWRSTCTRL & PWRSTST register offsers in PRM space, for example - PRM_XXX PWRSTCTRL PWRSTST ======================================= PRM_PER_MOD: 0x0C, 0x08 PRM_WKUP_MOD: 0x04, 0x08 PRM_MPU_MOD: 0x00, 0x04 PRM_DEVICE_MOD: NA, NA And also, there is no consistency between bit-offsets inside PWRSTCTRL & PWRSTST register, for example - PRM_XXX LOGICRET MEMON MEMRET ======================================= GFX_PWRCTRL: 2, 17, 6 PER_PWRCTRL: 3, 25, 29 MPU_PWRCTRL: 2, 18, 22 WKUP_PWRCTRL: 3, NA, NA This means, we need to maintain and pass on all this information in powerdomain handle; so adding fields for, - PWRSTCTRL/ST register offset - Logic retention state mask - mem_on/ret/pwrst/retst mask Currently, this fields is only applicable and used for AM33XX devices. Signed-off-by: Vaibhav Hiremath Cc: Benoit Cousson Cc: Tony Lindgren Cc: Kevin Hilman Cc: Paul Walmsley Cc: Rajendra Nayak [paul@pwsan.com: this patch is a combination of "Add offset & mask fields to struct powerdomain" and the powerdomain portions of "ARM: OMAP3+: am33xx: Add powerdomain & PRM support"; updated for 3.5] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 2 + arch/arm/mach-omap2/io.c | 1 + arch/arm/mach-omap2/powerdomain.h | 23 +- arch/arm/mach-omap2/powerdomain33xx.c | 229 ++++++++++++++++++++ arch/arm/mach-omap2/powerdomains33xx_data.c | 185 ++++++++++++++++ 5 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-omap2/powerdomain33xx.c create mode 100644 arch/arm/mach-omap2/powerdomains33xx_data.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index cc080946ec61..b664dc8722aa 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -115,6 +115,8 @@ obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX) += powerdomain33xx.o +obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o # PRCM clockdomain control clockdomain-common += clockdomain.o diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index d15ecb3782b7..3c885248b984 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -485,6 +485,7 @@ void __init am33xx_init_early(void) ti81xx_check_features(); omap_common_init_early(); am33xx_voltagedomains_init(); + am33xx_powerdomains_init(); } #endif diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 8f88d65c46ea..a8a95184243d 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -67,9 +67,9 @@ /* * Maximum number of clockdomains that can be associated with a powerdomain. - * CORE powerdomain on OMAP4 is the worst case + * PER powerdomain on AM33XX is the worst case */ -#define PWRDM_MAX_CLKDMS 9 +#define PWRDM_MAX_CLKDMS 11 /* XXX A completely arbitrary number. What is reasonable here? */ #define PWRDM_TRANSITION_BAILOUT 100000 @@ -92,6 +92,15 @@ struct powerdomain; * @pwrdm_clkdms: Clockdomains in this powerdomain * @node: list_head linking all powerdomains * @voltdm_node: list_head linking all powerdomains in a voltagedomain + * @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs + * @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs + * @logicretstate_mask: (AM33XX only) mask for logic retention bitfield + * in @pwrstctrl_offs + * @mem_on_mask: (AM33XX only) mask for mem on bitfield in @pwrstctrl_offs + * @mem_ret_mask: (AM33XX only) mask for mem ret bitfield in @pwrstctrl_offs + * @mem_pwrst_mask: (AM33XX only) mask for mem state bitfield in @pwrstst_offs + * @mem_retst_mask: (AM33XX only) mask for mem retention state bitfield + * in @pwrstctrl_offs * @state: * @state_counter: * @timer: @@ -121,6 +130,14 @@ struct powerdomain { unsigned ret_logic_off_counter; unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; + const u8 pwrstctrl_offs; + const u8 pwrstst_offs; + const u32 logicretstate_mask; + const u32 mem_on_mask[PWRDM_MAX_MEM_BANKS]; + const u32 mem_ret_mask[PWRDM_MAX_MEM_BANKS]; + const u32 mem_pwrst_mask[PWRDM_MAX_MEM_BANKS]; + const u32 mem_retst_mask[PWRDM_MAX_MEM_BANKS]; + #ifdef CONFIG_PM_DEBUG s64 timer; s64 state_timer[PWRDM_MAX_PWRSTS]; @@ -222,10 +239,12 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); extern void omap242x_powerdomains_init(void); extern void omap243x_powerdomains_init(void); extern void omap3xxx_powerdomains_init(void); +extern void am33xx_powerdomains_init(void); extern void omap44xx_powerdomains_init(void); extern struct pwrdm_ops omap2_pwrdm_operations; extern struct pwrdm_ops omap3_pwrdm_operations; +extern struct pwrdm_ops am33xx_pwrdm_operations; extern struct pwrdm_ops omap4_pwrdm_operations; /* Common Internal functions used across OMAP rev's */ diff --git a/arch/arm/mach-omap2/powerdomain33xx.c b/arch/arm/mach-omap2/powerdomain33xx.c new file mode 100644 index 000000000000..67c5663899b6 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomain33xx.c @@ -0,0 +1,229 @@ +/* + * AM33XX Powerdomain control + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * Derived from mach-omap2/powerdomain44xx.c written by Rajendra Nayak + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include + +#include "powerdomain.h" +#include "prm33xx.h" +#include "prm-regbits-33xx.h" + + +static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK, + (pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + return 0; +} + +static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + v &= OMAP_POWERSTATE_MASK; + v >>= OMAP_POWERSTATE_SHIFT; + + return v; +} + +static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= OMAP_POWERSTATEST_MASK; + v >>= OMAP_POWERSTATEST_SHIFT; + + return v; +} + +static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= AM33XX_LASTPOWERSTATEENTERED_MASK; + v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT; + + return v; +} + +static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) +{ + am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK, + (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + return 0; +} + +static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) +{ + am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK, + AM33XX_LASTPOWERSTATEENTERED_MASK, + pwrdm->prcm_offs, pwrdm->pwrstst_offs); + return 0; +} + +static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) +{ + u32 m; + + m = pwrdm->logicretstate_mask; + if (!m) + return -EINVAL; + + am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + + return 0; +} + +static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= AM33XX_LOGICSTATEST_MASK; + v >>= AM33XX_LOGICSTATEST_SHIFT; + + return v; +} + +static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm) +{ + u32 v, m; + + m = pwrdm->logicretstate_mask; + if (!m) + return -EINVAL; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = pwrdm->mem_on_mask[bank]; + if (!m) + return -EINVAL; + + am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + + return 0; +} + +static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = pwrdm->mem_ret_mask[bank]; + if (!m) + return -EINVAL; + + am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + + return 0; +} + +static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m, v; + + m = pwrdm->mem_pwrst_mask[bank]; + if (!m) + return -EINVAL; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m, v; + + m = pwrdm->mem_retst_mask[bank]; + if (!m) + return -EINVAL; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm) +{ + u32 c = 0; + + /* + * REVISIT: pwrdm_wait_transition() may be better implemented + * via a callback and a periodic timer check -- how long do we expect + * powerdomain transitions to take? + */ + + /* XXX Is this udelay() value meaningful? */ + while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs) + & OMAP_INTRANSITION_MASK) && + (c++ < PWRDM_TRANSITION_BAILOUT)) + udelay(1); + + if (c > PWRDM_TRANSITION_BAILOUT) { + pr_err("powerdomain: %s: waited too long to complete transition\n", + pwrdm->name); + return -EAGAIN; + } + + pr_debug("powerdomain: completed transition in %d loops\n", c); + + return 0; +} + +struct pwrdm_ops am33xx_pwrdm_operations = { + .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst, + .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst, + .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst, + .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst, + .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst, + .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst, + .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange, + .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst, + .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst, + .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst, + .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst, + .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, +}; diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c new file mode 100644 index 000000000000..869adb82569e --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains33xx_data.c @@ -0,0 +1,185 @@ +/* + * AM33XX Power domain data + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "powerdomain.h" +#include "prcm-common.h" +#include "prm-regbits-33xx.h" +#include "prm33xx.h" + +static struct powerdomain gfx_33xx_pwrdm = { + .name = "gfx_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_GFX_MOD, + .pwrstctrl_offs = AM33XX_PM_GFX_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_GFX_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .banks = 1, + .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK, + .mem_on_mask = { + [0] = AM33XX_GFX_MEM_ONSTATE_MASK, /* gfx_mem */ + }, + .mem_ret_mask = { + [0] = AM33XX_GFX_MEM_RETSTATE_MASK, /* gfx_mem */ + }, + .mem_pwrst_mask = { + [0] = AM33XX_GFX_MEM_STATEST_MASK, /* gfx_mem */ + }, + .mem_retst_mask = { + [0] = AM33XX_GFX_MEM_RETSTATE_MASK, /* gfx_mem */ + }, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* gfx_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* gfx_mem */ + }, +}; + +static struct powerdomain rtc_33xx_pwrdm = { + .name = "rtc_pwrdm", + .voltdm = { .name = "rtc" }, + .prcm_offs = AM33XX_PRM_RTC_MOD, + .pwrstctrl_offs = AM33XX_PM_RTC_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_RTC_PWRSTST_OFFSET, + .pwrsts = PWRSTS_ON, + .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK, +}; + +static struct powerdomain wkup_33xx_pwrdm = { + .name = "wkup_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_WKUP_MOD, + .pwrstctrl_offs = AM33XX_PM_WKUP_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_WKUP_PWRSTST_OFFSET, + .pwrsts = PWRSTS_ON, + .logicretstate_mask = AM33XX_LOGICRETSTATE_3_3_MASK, +}; + +static struct powerdomain per_33xx_pwrdm = { + .name = "per_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_PER_MOD, + .pwrstctrl_offs = AM33XX_PM_PER_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_PER_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .banks = 3, + .logicretstate_mask = AM33XX_LOGICRETSTATE_3_3_MASK, + .mem_on_mask = { + [0] = AM33XX_PRUSS_MEM_ONSTATE_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_ONSTATE_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_ONSTATE_MASK, /* ram_mem */ + }, + .mem_ret_mask = { + [0] = AM33XX_PRUSS_MEM_RETSTATE_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_RETSTATE_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_RETSTATE_MASK, /* ram_mem */ + }, + .mem_pwrst_mask = { + [0] = AM33XX_PRUSS_MEM_STATEST_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_STATEST_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_STATEST_MASK, /* ram_mem */ + }, + .mem_retst_mask = { + [0] = AM33XX_PRUSS_MEM_RETSTATE_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_RETSTATE_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_RETSTATE_MASK, /* ram_mem */ + }, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* pruss_mem */ + [1] = PWRSTS_OFF_RET, /* per_mem */ + [2] = PWRSTS_OFF_RET, /* ram_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* pruss_mem */ + [1] = PWRSTS_ON, /* per_mem */ + [2] = PWRSTS_ON, /* ram_mem */ + }, +}; + +static struct powerdomain mpu_33xx_pwrdm = { + .name = "mpu_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = AM33XX_PRM_MPU_MOD, + .pwrstctrl_offs = AM33XX_PM_MPU_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .banks = 3, + .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK, + .mem_on_mask = { + [0] = AM33XX_MPU_L1_ONSTATE_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_ONSTATE_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_ONSTATE_MASK, /* mpu_ram */ + }, + .mem_ret_mask = { + [0] = AM33XX_MPU_L1_RETSTATE_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_RETSTATE_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_RETSTATE_MASK, /* mpu_ram */ + }, + .mem_pwrst_mask = { + [0] = AM33XX_MPU_L1_STATEST_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_STATEST_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_STATEST_MASK, /* mpu_ram */ + }, + .mem_retst_mask = { + [0] = AM33XX_MPU_L1_RETSTATE_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_RETSTATE_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_RETSTATE_MASK, /* mpu_ram */ + }, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l1 */ + [1] = PWRSTS_OFF_RET, /* mpu_l2 */ + [2] = PWRSTS_OFF_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* mpu_l1 */ + [1] = PWRSTS_ON, /* mpu_l2 */ + [2] = PWRSTS_ON, /* mpu_ram */ + }, +}; + +static struct powerdomain cefuse_33xx_pwrdm = { + .name = "cefuse_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_CEFUSE_MOD, + .pwrstctrl_offs = AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_CEFUSE_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct powerdomain *powerdomains_am33xx[] __initdata = { + &gfx_33xx_pwrdm, + &rtc_33xx_pwrdm, + &wkup_33xx_pwrdm, + &per_33xx_pwrdm, + &mpu_33xx_pwrdm, + &cefuse_33xx_pwrdm, + NULL, +}; + +void __init am33xx_powerdomains_init(void) +{ + pwrdm_register_platform_funcs(&am33xx_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_am33xx); + pwrdm_complete_init(); +} -- GitLab From 9c80f3aa8b7828c89c5bae5c769955d1ac58630b Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 18 Jun 2012 00:47:27 -0600 Subject: [PATCH 1914/6849] ARM: OMAP AM33xx: clockdomains: Add clockdomain data and respective operations AM33XX PRCM module consists of various clockdomains, in all total we have 18 clockdomains available, with following controlling options, - SW Sleep: sw forced sleep transition - SW Wakeup: sw forced wakeup transition This patch adds all available clockdomain data, respective clockdomain operations for AM33XX family of device, and also integrates it into existing OMAP framework. Signed-off-by: Vaibhav Hiremath Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Bedia Cc: Kevin Hilman Cc: Rajendra Nayak CC: Tony Lindgren Cc: Paul Walmsley Cc: Benoit Cousson [paul@pwsan.com: removed CLKDM_NO_AUTODEPS from clockdomain flags, removed unnecessary .clktrctrl_offs field; updated for 3.5] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 2 + arch/arm/mach-omap2/clockdomain.h | 2 + arch/arm/mach-omap2/clockdomain33xx.c | 74 ++++++++ arch/arm/mach-omap2/clockdomains33xx_data.c | 196 ++++++++++++++++++++ arch/arm/mach-omap2/io.c | 1 + 5 files changed, 275 insertions(+) create mode 100644 arch/arm/mach-omap2/clockdomain33xx.c create mode 100644 arch/arm/mach-omap2/clockdomains33xx_data.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index b664dc8722aa..a4cf93242b0b 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -133,6 +133,8 @@ obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX) += clockdomain33xx.o +obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o # Clock framework obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index f7b58609bad8..72cb12bbb9c3 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -195,6 +195,7 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); extern void __init omap242x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void); extern void __init omap3xxx_clockdomains_init(void); +extern void __init am33xx_clockdomains_init(void); extern void __init omap44xx_clockdomains_init(void); extern void _clkdm_add_autodeps(struct clockdomain *clkdm); extern void _clkdm_del_autodeps(struct clockdomain *clkdm); @@ -202,6 +203,7 @@ extern void _clkdm_del_autodeps(struct clockdomain *clkdm); extern struct clkdm_ops omap2_clkdm_operations; extern struct clkdm_ops omap3_clkdm_operations; extern struct clkdm_ops omap4_clkdm_operations; +extern struct clkdm_ops am33xx_clkdm_operations; extern struct clkdm_dep gfx_24xx_wkdeps[]; extern struct clkdm_dep dsp_24xx_wkdeps[]; diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c new file mode 100644 index 000000000000..aca6388fad76 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomain33xx.c @@ -0,0 +1,74 @@ +/* + * AM33XX clockdomain control + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath + * + * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include "clockdomain.h" +#include "cm33xx.h" + + +static int am33xx_clkdm_sleep(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static int am33xx_clkdm_wakeup(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); +} + +static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); +} + +static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm) +{ + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + return am33xx_clkdm_wakeup(clkdm); + + return 0; +} + +static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); + + if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) + am33xx_clkdm_sleep(clkdm); + + return 0; +} + +struct clkdm_ops am33xx_clkdm_operations = { + .clkdm_sleep = am33xx_clkdm_sleep, + .clkdm_wakeup = am33xx_clkdm_wakeup, + .clkdm_allow_idle = am33xx_clkdm_allow_idle, + .clkdm_deny_idle = am33xx_clkdm_deny_idle, + .clkdm_clk_enable = am33xx_clkdm_clk_enable, + .clkdm_clk_disable = am33xx_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/clockdomains33xx_data.c b/arch/arm/mach-omap2/clockdomains33xx_data.c new file mode 100644 index 000000000000..32c90fd9eba2 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains33xx_data.c @@ -0,0 +1,196 @@ +/* + * AM33XX Clock Domain data. + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "clockdomain.h" +#include "cm.h" +#include "cm33xx.h" +#include "cm-regbits-33xx.h" + +static struct clockdomain l4ls_am33xx_clkdm = { + .name = "l4ls_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3s_am33xx_clkdm = { + .name = "l3s_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L3S_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4fw_am33xx_clkdm = { + .name = "l4fw_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L4FW_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_am33xx_clkdm = { + .name = "l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L3_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4hs_am33xx_clkdm = { + .name = "l4hs_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L4HS_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain ocpwp_l3_am33xx_clkdm = { + .name = "ocpwp_l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain pruss_ocp_am33xx_clkdm = { + .name = "pruss_ocp_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_PRUSS_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain cpsw_125mhz_am33xx_clkdm = { + .name = "cpsw_125mhz_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_CPSW_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain lcdc_am33xx_clkdm = { + .name = "lcdc_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_LCDC_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain clk_24mhz_am33xx_clkdm = { + .name = "clk_24mhz_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_am33xx_clkdm = { + .name = "l4_wkup_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .cm_inst = AM33XX_CM_WKUP_MOD, + .clkdm_offs = AM33XX_CM_WKUP_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_aon_am33xx_clkdm = { + .name = "l3_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .cm_inst = AM33XX_CM_WKUP_MOD, + .clkdm_offs = AM33XX_CM_L3_AON_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_aon_am33xx_clkdm = { + .name = "l4_wkup_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .cm_inst = AM33XX_CM_WKUP_MOD, + .clkdm_offs = AM33XX_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain mpu_am33xx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .cm_inst = AM33XX_CM_MPU_MOD, + .clkdm_offs = AM33XX_CM_MPU_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_rtc_am33xx_clkdm = { + .name = "l4_rtc_clkdm", + .pwrdm = { .name = "rtc_pwrdm" }, + .cm_inst = AM33XX_CM_RTC_MOD, + .clkdm_offs = AM33XX_CM_RTC_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain gfx_l3_am33xx_clkdm = { + .name = "gfx_l3_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .cm_inst = AM33XX_CM_GFX_MOD, + .clkdm_offs = AM33XX_CM_GFX_L3_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain gfx_l4ls_gfx_am33xx_clkdm = { + .name = "gfx_l4ls_gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .cm_inst = AM33XX_CM_GFX_MOD, + .clkdm_offs = AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_cefuse_am33xx_clkdm = { + .name = "l4_cefuse_clkdm", + .pwrdm = { .name = "cefuse_pwrdm" }, + .cm_inst = AM33XX_CM_CEFUSE_MOD, + .clkdm_offs = AM33XX_CM_CEFUSE_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain *clockdomains_am33xx[] __initdata = { + &l4ls_am33xx_clkdm, + &l3s_am33xx_clkdm, + &l4fw_am33xx_clkdm, + &l3_am33xx_clkdm, + &l4hs_am33xx_clkdm, + &ocpwp_l3_am33xx_clkdm, + &pruss_ocp_am33xx_clkdm, + &cpsw_125mhz_am33xx_clkdm, + &lcdc_am33xx_clkdm, + &clk_24mhz_am33xx_clkdm, + &l4_wkup_am33xx_clkdm, + &l3_aon_am33xx_clkdm, + &l4_wkup_aon_am33xx_clkdm, + &mpu_am33xx_clkdm, + &l4_rtc_am33xx_clkdm, + &gfx_l3_am33xx_clkdm, + &gfx_l4ls_gfx_am33xx_clkdm, + &l4_cefuse_am33xx_clkdm, + NULL, +}; + +void __init am33xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&am33xx_clkdm_operations); + clkdm_register_clkdms(clockdomains_am33xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3c885248b984..cb6c11cd8df9 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -486,6 +486,7 @@ void __init am33xx_init_early(void) omap_common_init_early(); am33xx_voltagedomains_init(); am33xx_powerdomains_init(); + am33xx_clockdomains_init(); } #endif -- GitLab From a1f42beb8e287482d1a802731d4fb7e2bdc2c703 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jun 2012 13:48:08 +0900 Subject: [PATCH 1915/6849] Makefile: fix up CROSS_COMPILE and READABLE_ASM interaction. When the READABLE_ASM cc-option tests were added they were done so prior to the arch Makefile include, resulting in cc-option being run on the host cc instead of the factoring in the cross prefix set up by the architecture. This bumps the include back up so that cc-option actually runs on the compiler that we're building with. Cc: Andi Kleen Signed-off-by: Paul Mundt Signed-off-by: Linus Torvalds --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b771af583389..462a0b4794b6 100644 --- a/Makefile +++ b/Makefile @@ -561,6 +561,8 @@ else KBUILD_CFLAGS += -O2 endif +include $(srctree)/arch/$(SRCARCH)/Makefile + ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -571,8 +573,6 @@ KBUILD_CFLAGS += $(call cc-option,-fno-reorder-blocks,) \ $(call cc-option,-fno-partial-inlining) endif -include $(srctree)/arch/$(SRCARCH)/Makefile - ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif -- GitLab From 2603efa31a0377eeaa06723bded8a1d644dd4901 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jun 2012 13:54:17 +0900 Subject: [PATCH 1916/6849] bug.h: Fix up powerpc build regression. The asm-generic/bug.h __ASSEMBLY__ guarding is completely bogus, which tripped up the powerpc build when the kernel.h include was added: In file included from include/asm-generic/bug.h:5:0, from arch/powerpc/include/asm/bug.h:127, from arch/powerpc/kernel/head_64.S:31: include/linux/kernel.h:44:0: warning: "ALIGN" redefined [enabled by default] include/linux/linkage.h:57:0: note: this is the location of the previous definition include/linux/sysinfo.h: Assembler messages: include/linux/sysinfo.h:7: Error: Unrecognized opcode: `struct' include/linux/sysinfo.h:8: Error: Unrecognized opcode: `__kernel_long_t' Moving the __ASSEMBLY__ guard up and stashing the kernel.h include under it fixes this up, as well as covering the case the original fix was attempting to handle. Tested-by: Stephen Rothwell Acked-by: Arnd Bergmann Signed-off-by: Paul Mundt Signed-off-by: Linus Torvalds --- include/asm-generic/bug.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 9f02005f217a..506ec19a3736 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -2,7 +2,6 @@ #define _ASM_GENERIC_BUG_H #include -#include #ifdef CONFIG_BUG @@ -32,6 +31,9 @@ struct bug_entry { #endif /* CONFIG_GENERIC_BUG */ +#ifndef __ASSEMBLY__ +#include + /* * Don't use BUG() or BUG_ON() unless there's really no way out; one * example might be detecting data structure corruption in the middle @@ -61,7 +63,6 @@ struct bug_entry { * to provide better diagnostics. */ #ifndef __WARN_TAINT -#ifndef __ASSEMBLY__ extern __printf(3, 4) void warn_slowpath_fmt(const char *file, const int line, const char *fmt, ...); @@ -70,7 +71,6 @@ void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint, const char *fmt, ...); extern void warn_slowpath_null(const char *file, const int line); #define WANT_WARN_ON_SLOWPATH -#endif #define __WARN() warn_slowpath_null(__FILE__, __LINE__) #define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg) #define __WARN_printf_taint(taint, arg...) \ @@ -203,4 +203,6 @@ extern void warn_slowpath_null(const char *file, const int line); # define WARN_ON_SMP(x) ({0;}) #endif +#endif /* __ASSEMBLY__ */ + #endif -- GitLab From 3d9f032724e72851c6de38d026b2417501a2f240 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 12:12:23 -0600 Subject: [PATCH 1917/6849] ARM: OMAP4: hwmod: rename _enable_module to _omap4_enable_module() _enable_module is specific to SoCs with PRCM interfaces similar to that of the OMAP4, so rename it to be consistent with the corresponding _omap4_disable_module. Signed-off-by: Kevin Hilman [paul@pwsan.com: tweaked commit message] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index bf86f7e8f91f..939032a427fd 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -771,13 +771,13 @@ static void _disable_optional_clocks(struct omap_hwmod *oh) } /** - * _enable_module - enable CLKCTRL modulemode on OMAP4 + * _omap4_enable_module - enable CLKCTRL modulemode on OMAP4 * @oh: struct omap_hwmod * * * Enables the PRCM module mode related to the hwmod @oh. * No return value. */ -static void _enable_module(struct omap_hwmod *oh) +static void _omap4_enable_module(struct omap_hwmod *oh) { /* The module mode does not exist prior OMAP4 */ if (cpu_is_omap24xx() || cpu_is_omap34xx()) @@ -786,8 +786,8 @@ static void _enable_module(struct omap_hwmod *oh) if (!oh->clkdm || !oh->prcm.omap4.modulemode) return; - pr_debug("omap_hwmod: %s: _enable_module: %d\n", - oh->name, oh->prcm.omap4.modulemode); + pr_debug("omap_hwmod: %s: %s: %d\n", + oh->name, __func__, oh->prcm.omap4.modulemode); omap4_cminst_module_enable(oh->prcm.omap4.modulemode, oh->clkdm->prcm_partition, @@ -1814,7 +1814,7 @@ static int _enable(struct omap_hwmod *oh) } _enable_clocks(oh); - _enable_module(oh); + _omap4_enable_module(oh); r = _wait_target_ready(oh); if (!r) { -- GitLab From 9ebfd285371835b1c0243d15aaacd72d5def76f8 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 12:12:23 -0600 Subject: [PATCH 1918/6849] ARM: OMAP2+: hwmod: use init-time function ptrs for enable/disable module The enable/disable module functions are specific to SoCs with OMAP4-class PRCM. Rather than use cpu_is* checks at runtime inside the enable/disable module functions, use cpu_is at init time to initialize function pointers only for SoCs that need them. NOTE: the cpu_is* check for _enable_module was different than the one for _disable_module, and this patch uses cpu_is_omap44xx() for both. Signed-off-by: Kevin Hilman [paul@pwsan.com: moved soc_ops function pointers to be per-kernel rather than per-hwmod since they do not vary by hwmod; added kerneldoc] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 62 ++++++++++++++++---- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_2430_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 + 6 files changed, 57 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 939032a427fd..634a79836c64 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -166,6 +166,23 @@ */ #define LINKS_PER_OCP_IF 2 +/** + * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations + * @enable_module: function to enable a module (via MODULEMODE) + * @disable_module: function to disable a module (via MODULEMODE) + * + * XXX Eventually this functionality will be hidden inside the PRM/CM + * device drivers. Until then, this should avoid huge blocks of cpu_is_*() + * conditionals in this code. + */ +struct omap_hwmod_soc_ops { + void (*enable_module)(struct omap_hwmod *oh); + int (*disable_module)(struct omap_hwmod *oh); +}; + +/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ +static struct omap_hwmod_soc_ops soc_ops; + /* omap_hwmod_list contains all registered struct omap_hwmods */ static LIST_HEAD(omap_hwmod_list); @@ -186,6 +203,9 @@ static struct omap_hwmod_link *linkspace; */ static unsigned short free_ls, max_ls, ls_supp; +/* inited: set to true once the hwmod code is initialized */ +static bool inited; + /* Private functions */ /** @@ -779,10 +799,6 @@ static void _disable_optional_clocks(struct omap_hwmod *oh) */ static void _omap4_enable_module(struct omap_hwmod *oh) { - /* The module mode does not exist prior OMAP4 */ - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - return; - if (!oh->clkdm || !oh->prcm.omap4.modulemode) return; @@ -1571,10 +1587,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh) { int v; - /* The module mode does not exist prior OMAP4 */ - if (!cpu_is_omap44xx()) - return -EINVAL; - if (!oh->clkdm || !oh->prcm.omap4.modulemode) return -EINVAL; @@ -1814,7 +1826,8 @@ static int _enable(struct omap_hwmod *oh) } _enable_clocks(oh); - _omap4_enable_module(oh); + if (soc_ops.enable_module) + soc_ops.enable_module(oh); r = _wait_target_ready(oh); if (!r) { @@ -1870,7 +1883,8 @@ static int _idle(struct omap_hwmod *oh) _idle_sysc(oh); _del_initiator_dep(oh, mpu_oh); - _omap4_disable_module(oh); + if (soc_ops.disable_module) + soc_ops.disable_module(oh); /* * The module must be in idle mode before disabling any parents @@ -1975,7 +1989,8 @@ static int _shutdown(struct omap_hwmod *oh) if (oh->_state == _HWMOD_STATE_ENABLED) { _del_initiator_dep(oh, mpu_oh); /* XXX what about the other system initiators here? dma, dsp */ - _omap4_disable_module(oh); + if (soc_ops.disable_module) + soc_ops.disable_module(oh); _disable_clocks(oh); if (oh->clkdm) clkdm_hwmod_disable(oh->clkdm, oh); @@ -2563,12 +2578,18 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), * * Intended to be called early in boot before the clock framework is * initialized. If @ois is not null, will register all omap_hwmods - * listed in @ois that are valid for this chip. Returns 0. + * listed in @ois that are valid for this chip. Returns -EINVAL if + * omap_hwmod_init() hasn't been called before calling this function, + * -ENOMEM if the link memory area can't be allocated, or 0 upon + * success. */ int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) { int r, i; + if (!inited) + return -EINVAL; + if (!ois) return 0; @@ -3401,3 +3422,20 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) return 0; } + +/** + * omap_hwmod_init - initialize the hwmod code + * + * Sets up some function pointers needed by the hwmod code to operate on the + * currently-booted SoC. Intended to be called once during kernel init + * before any hwmods are registered. No return value. + */ +void __init omap_hwmod_init(void) +{ + if (cpu_is_omap44xx()) { + soc_ops.enable_module = _omap4_enable_module; + soc_ops.disable_module = _omap4_disable_module; + } + + inited = true; +} diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a7640d1b215e..5b1938b52d09 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -585,5 +585,6 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { int __init omap2420_hwmod_init(void) { + omap_hwmod_init(); return omap_hwmod_register_links(omap2420_hwmod_ocp_ifs); } diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 4d7264981230..71f199783c63 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -938,5 +938,6 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = { int __init omap2430_hwmod_init(void) { + omap_hwmod_init(); return omap_hwmod_register_links(omap2430_hwmod_ocp_ifs); } diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index b26d3c9bca16..abb1f6b56ee5 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3283,6 +3283,8 @@ int __init omap3xxx_hwmod_init(void) struct omap_hwmod_ocp_if **h = NULL; unsigned int rev; + omap_hwmod_init(); + /* Register hwmod links common to all OMAP3 */ r = omap_hwmod_register_links(omap3xxx_hwmod_ocp_ifs); if (r < 0) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 950454a3fa31..d3c48dc26af1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -6144,6 +6144,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { int __init omap44xx_hwmod_init(void) { + omap_hwmod_init(); return omap_hwmod_register_links(omap44xx_hwmod_ocp_ifs); } diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index c835b7194ff5..a8ecc53b3670 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -629,6 +629,8 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx); +extern void __init omap_hwmod_init(void); + /* * Chip variant-specific hwmod init routines - XXX should be converted * to use initcalls once the initial boot ordering is straightened out -- GitLab From baa2607f56f1589eb21c01fe16aa5f5c3f9dad31 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 12:12:24 -0600 Subject: [PATCH 1919/6849] ARM: OMAP4: hwmod: drop extra cpu_is check from _wait_target_disable() _omap4_wait_target_disable() is called only from inside _omap4_disable_module() which is already protected by SoC specific checks. Remove the cpu_is check here. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap_hwmod.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 634a79836c64..2b845836f7dc 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -823,9 +823,6 @@ static void _omap4_enable_module(struct omap_hwmod *oh) */ static int _omap4_wait_target_disable(struct omap_hwmod *oh) { - if (!cpu_is_omap44xx()) - return 0; - if (!oh) return -EINVAL; -- GitLab From 8f6aa8ee114fb52a425e247e27e271ee35d7d3b3 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 12:12:24 -0600 Subject: [PATCH 1920/6849] ARM: OMAP2+: hwmod: use init-time function pointer for wait_target_ready Rather than using cpu_is* checking at runtime, initialize an SoC specific function pointer for wait_target_ready(). While here, downgrade the BUG() to a WARN_ON() so it gives a noisy warning instead of causing a kernel panic. Signed-off-by: Kevin Hilman [paul@pwsan.com: convert to use soc_ops function pointers; add kerneldoc; move soc_ops functions to their own section in the code; integrated the _wait_target_ready() function with the OMAP2/OMAP4 variants; renamed the wait_module_ready field to wait_target_ready] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 115 ++++++++++++++++++------------- 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 2b845836f7dc..d1f784cd5f0f 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -178,6 +178,7 @@ struct omap_hwmod_soc_ops { void (*enable_module)(struct omap_hwmod *oh); int (*disable_module)(struct omap_hwmod *oh); + int (*wait_target_ready)(struct omap_hwmod *oh); }; /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -1361,53 +1362,6 @@ static int _init_clocks(struct omap_hwmod *oh, void *data) return ret; } -/** - * _wait_target_ready - wait for a module to leave slave idle - * @oh: struct omap_hwmod * - * - * Wait for a module @oh to leave slave idle. Returns 0 if the module - * does not have an IDLEST bit or if the module successfully leaves - * slave idle; otherwise, pass along the return value of the - * appropriate *_cm*_wait_module_ready() function. - */ -static int _wait_target_ready(struct omap_hwmod *oh) -{ - struct omap_hwmod_ocp_if *os; - int ret; - - if (!oh) - return -EINVAL; - - if (oh->flags & HWMOD_NO_IDLEST) - return 0; - - os = _find_mpu_rt_port(oh); - if (!os) - return 0; - - /* XXX check module SIDLEMODE */ - - /* XXX check clock enable states */ - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, - oh->prcm.omap2.idlest_reg_id, - oh->prcm.omap2.idlest_idle_bit); - } else if (cpu_is_omap44xx()) { - if (!oh->clkdm) - return -EINVAL; - - ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, - oh->clkdm->cm_inst, - oh->clkdm->clkdm_offs, - oh->prcm.omap4.clkctrl_offs); - } else { - BUG(); - }; - - return ret; -} - /** * _lookup_hardreset - fill register bit info for this hwmod/reset line * @oh: struct omap_hwmod * @@ -1826,7 +1780,8 @@ static int _enable(struct omap_hwmod *oh) if (soc_ops.enable_module) soc_ops.enable_module(oh); - r = _wait_target_ready(oh); + r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) : + -EINVAL; if (!r) { /* * Set the clockdomain to HW_AUTO only if the target is ready, @@ -2443,6 +2398,63 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois) return 0; } +/* Static functions intended only for use in soc_ops field function pointers */ + +/** + * _omap2_wait_target_ready - wait for a module to leave slave idle + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to leave slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully leaves + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_ready() function. + */ +static int _omap2_wait_target_ready(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + if (!_find_mpu_rt_port(oh)) + return 0; + + /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ + + return omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, + oh->prcm.omap2.idlest_reg_id, + oh->prcm.omap2.idlest_idle_bit); +} + +/** + * _omap4_wait_target_ready - wait for a module to leave slave idle + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to leave slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully leaves + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_ready() function. + */ +static int _omap4_wait_target_ready(struct omap_hwmod *oh) +{ + if (!oh || !oh->clkdm) + return -EINVAL; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + if (!_find_mpu_rt_port(oh)) + return 0; + + /* XXX check module SIDLEMODE, hardreset status */ + + return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + /* Public functions */ u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) @@ -3429,9 +3441,14 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) */ void __init omap_hwmod_init(void) { - if (cpu_is_omap44xx()) { + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { + soc_ops.wait_target_ready = _omap2_wait_target_ready; + } else if (cpu_is_omap44xx()) { soc_ops.enable_module = _omap4_enable_module; soc_ops.disable_module = _omap4_disable_module; + soc_ops.wait_target_ready = _omap4_wait_target_ready; + } else { + WARN(1, "omap_hwmod: unknown SoC type\n"); } inited = true; -- GitLab From b8249cf2d2b16de9582d3cbaa98c16c32c624d8a Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 12:12:24 -0600 Subject: [PATCH 1921/6849] ARM: OMAP2+: hwmod: use init-time function pointer for hardreset Rather than using cpu_is* checking at runtime, initialize SoC specific function pointers for the various hard reset functions at init time. Signed-off-by: Kevin Hilman [paul@pwsan.com: convert to use soc_ops function pointers; add kerneldoc] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 216 ++++++++++++++++++++++++------- 1 file changed, 169 insertions(+), 47 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d1f784cd5f0f..93cb96dbb543 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -179,6 +179,12 @@ struct omap_hwmod_soc_ops { void (*enable_module)(struct omap_hwmod *oh); int (*disable_module)(struct omap_hwmod *oh); int (*wait_target_ready)(struct omap_hwmod *oh); + int (*assert_hardreset)(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri); + int (*deassert_hardreset)(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri); + int (*is_hardreset_asserted)(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri); }; /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -1398,32 +1404,31 @@ static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name, * @oh: struct omap_hwmod * * @name: name of the reset line to lookup and assert * - * Some IP like dsp, ipu or iva contain processor that require - * an HW reset line to be assert / deassert in order to enable fully - * the IP. + * Some IP like dsp, ipu or iva contain processor that require an HW + * reset line to be assert / deassert in order to enable fully the IP. + * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of + * asserting the hardreset line on the currently-booted SoC, or passes + * along the return value from _lookup_hardreset() or the SoC's + * assert_hardreset code. */ static int _assert_hardreset(struct omap_hwmod *oh, const char *name) { struct omap_hwmod_rst_info ohri; - u8 ret; + u8 ret = -EINVAL; if (!oh) return -EINVAL; + if (!soc_ops.assert_hardreset) + return -ENOSYS; + ret = _lookup_hardreset(oh, name, &ohri); if (IS_ERR_VALUE(ret)) return ret; - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, - ohri.rst_shift); - else if (cpu_is_omap44xx()) - return omap4_prminst_assert_hardreset(ohri.rst_shift, - oh->clkdm->pwrdm.ptr->prcm_partition, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); - else - return -EINVAL; + ret = soc_ops.assert_hardreset(oh, &ohri); + + return ret; } /** @@ -1432,38 +1437,29 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name) * @oh: struct omap_hwmod * * @name: name of the reset line to look up and deassert * - * Some IP like dsp, ipu or iva contain processor that require - * an HW reset line to be assert / deassert in order to enable fully - * the IP. + * Some IP like dsp, ipu or iva contain processor that require an HW + * reset line to be assert / deassert in order to enable fully the IP. + * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of + * deasserting the hardreset line on the currently-booted SoC, or passes + * along the return value from _lookup_hardreset() or the SoC's + * deassert_hardreset code. */ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) { struct omap_hwmod_rst_info ohri; - int ret; + int ret = -EINVAL; if (!oh) return -EINVAL; + if (!soc_ops.deassert_hardreset) + return -ENOSYS; + ret = _lookup_hardreset(oh, name, &ohri); if (IS_ERR_VALUE(ret)) return ret; - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, - ohri.rst_shift, - ohri.st_shift); - } else if (cpu_is_omap44xx()) { - if (ohri.st_shift) - pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", - oh->name, name); - ret = omap4_prminst_deassert_hardreset(ohri.rst_shift, - oh->clkdm->pwrdm.ptr->prcm_partition, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); - } else { - return -EINVAL; - } - + ret = soc_ops.deassert_hardreset(oh, &ohri); if (ret == -EBUSY) pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name); @@ -1476,31 +1472,28 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) * @oh: struct omap_hwmod * * @name: name of the reset line to look up and read * - * Return the state of the reset line. + * Return the state of the reset line. Returns -EINVAL if @oh is + * null, -ENOSYS if we have no way of reading the hardreset line + * status on the currently-booted SoC, or passes along the return + * value from _lookup_hardreset() or the SoC's is_hardreset_asserted + * code. */ static int _read_hardreset(struct omap_hwmod *oh, const char *name) { struct omap_hwmod_rst_info ohri; - u8 ret; + u8 ret = -EINVAL; if (!oh) return -EINVAL; + if (!soc_ops.is_hardreset_asserted) + return -ENOSYS; + ret = _lookup_hardreset(oh, name, &ohri); if (IS_ERR_VALUE(ret)) return ret; - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, - ohri.st_shift); - } else if (cpu_is_omap44xx()) { - return omap4_prminst_is_hardreset_asserted(ohri.rst_shift, - oh->clkdm->pwrdm.ptr->prcm_partition, - oh->clkdm->pwrdm.ptr->prcm_offs, - oh->prcm.omap4.rstctrl_offs); - } else { - return -EINVAL; - } + return soc_ops.is_hardreset_asserted(oh, &ohri); } /** @@ -2455,6 +2448,129 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh) oh->prcm.omap4.clkctrl_offs); } +/** + * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to assert hardreset + * @ohri: hardreset line data + * + * Call omap2_prm_assert_hardreset() with parameters extracted from + * the hwmod @oh and the hardreset line data @ohri. Only intended for + * use as an soc_ops function pointer. Passes along the return value + * from omap2_prm_assert_hardreset(). XXX This function is scheduled + * for removal when the PRM code is moved into drivers/. + */ +static int _omap2_assert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, + ohri->rst_shift); +} + +/** + * _omap2_deassert_hardreset - call OMAP2 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to deassert hardreset + * @ohri: hardreset line data + * + * Call omap2_prm_deassert_hardreset() with parameters extracted from + * the hwmod @oh and the hardreset line data @ohri. Only intended for + * use as an soc_ops function pointer. Passes along the return value + * from omap2_prm_deassert_hardreset(). XXX This function is + * scheduled for removal when the PRM code is moved into drivers/. + */ +static int _omap2_deassert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, + ohri->rst_shift, + ohri->st_shift); +} + +/** + * _omap2_is_hardreset_asserted - call OMAP2 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to test hardreset + * @ohri: hardreset line data + * + * Call omap2_prm_is_hardreset_asserted() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from omap2_prm_is_hardreset_asserted(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, + ohri->st_shift); +} + +/** + * _omap4_assert_hardreset - call OMAP4 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to assert hardreset + * @ohri: hardreset line data + * + * Call omap4_prminst_assert_hardreset() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from omap4_prminst_assert_hardreset(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _omap4_assert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) + +{ + return omap4_prminst_assert_hardreset(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/** + * _omap4_deassert_hardreset - call OMAP4 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to deassert hardreset + * @ohri: hardreset line data + * + * Call omap4_prminst_deassert_hardreset() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from omap4_prminst_deassert_hardreset(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _omap4_deassert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + if (ohri->st_shift) + pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", + oh->name, ohri->name); + return omap4_prminst_deassert_hardreset(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/** + * _omap4_is_hardreset_asserted - call OMAP4 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to test hardreset + * @ohri: hardreset line data + * + * Call omap4_prminst_is_hardreset_asserted() with parameters + * extracted from the hwmod @oh and the hardreset line data @ohri. + * Only intended for use as an soc_ops function pointer. Passes along + * the return value from omap4_prminst_is_hardreset_asserted(). XXX + * This function is scheduled for removal when the PRM code is moved + * into drivers/. + */ +static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap4_prminst_is_hardreset_asserted(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + /* Public functions */ u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) @@ -3443,10 +3559,16 @@ void __init omap_hwmod_init(void) { if (cpu_is_omap24xx() || cpu_is_omap34xx()) { soc_ops.wait_target_ready = _omap2_wait_target_ready; + soc_ops.assert_hardreset = _omap2_assert_hardreset; + soc_ops.deassert_hardreset = _omap2_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; } else if (cpu_is_omap44xx()) { soc_ops.enable_module = _omap4_enable_module; soc_ops.disable_module = _omap4_disable_module; soc_ops.wait_target_ready = _omap4_wait_target_ready; + soc_ops.assert_hardreset = _omap4_assert_hardreset; + soc_ops.deassert_hardreset = _omap4_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; } else { WARN(1, "omap_hwmod: unknown SoC type\n"); } -- GitLab From 0a179eaa436e58ed9fd00e09cdf01f1b3604d9a1 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 12:12:25 -0600 Subject: [PATCH 1922/6849] ARM: OMAP2+: hwmod: use init-time function pointer for _init_clkdm Rather than use runtime cpu_is* checking inside _init_clkdm, initialize SoC specific function pointer at init time. Signed-off-by: Kevin Hilman [paul@pwsan.com: convert to use soc_ops function pointers; remove second para from commit message since soc_ops function pointers are now set during hwmod layer init] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 93cb96dbb543..acc616c02e14 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -185,6 +185,7 @@ struct omap_hwmod_soc_ops { struct omap_hwmod_rst_info *ohri); int (*is_hardreset_asserted)(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri); + int (*init_clkdm)(struct omap_hwmod *oh); }; /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -1315,9 +1316,6 @@ static struct omap_hwmod *_lookup(const char *name) */ static int _init_clkdm(struct omap_hwmod *oh) { - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - return 0; - if (!oh->clkdm_name) { pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name); return -EINVAL; @@ -1358,7 +1356,8 @@ static int _init_clocks(struct omap_hwmod *oh, void *data) ret |= _init_main_clk(oh); ret |= _init_interface_clks(oh); ret |= _init_opt_clks(oh); - ret |= _init_clkdm(oh); + if (soc_ops.init_clkdm) + ret |= soc_ops.init_clkdm(oh); if (!ret) oh->_state = _HWMOD_STATE_CLKS_INITED; @@ -3569,6 +3568,7 @@ void __init omap_hwmod_init(void) soc_ops.assert_hardreset = _omap4_assert_hardreset; soc_ops.deassert_hardreset = _omap4_deassert_hardreset; soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; } else { WARN(1, "omap_hwmod: unknown SoC type\n"); } -- GitLab From cba5d0b20e7c75dc06e3a609059f17f11c843d94 Mon Sep 17 00:00:00 2001 From: Janne Huttunen Date: Wed, 30 May 2012 05:28:46 -0300 Subject: [PATCH 1923/6849] [media] cxd2820r: Fix an incorrect modulation type bitmask Fix an incorrect modulation type bitmask. This allows QAM256 also to be correctly reported. Signed-off-by: Janne Huttunen Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cxd2820r_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index 945404991529..ed3b0ba624de 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c @@ -121,7 +121,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe) if (ret) goto error; - switch ((buf[0] >> 0) & 0x03) { + switch ((buf[0] >> 0) & 0x07) { case 0: c->modulation = QAM_16; break; -- GitLab From d44f42e6af483cbdc239d7f28666e711d2e8ab92 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 18 Jun 2012 16:17:44 -0600 Subject: [PATCH 1924/6849] ARM: OMAP2+: CLEANUP: Remove ARCH_OMAPx ifdef from struct dpll_data There are certain fields inside 'struct dpll_data' which are included under ARCH_OMAP3 and ARCH_OMAP4 option, which makes it difficult to use it for new devices like, am33xx, ti81xx, etc... So remove the ifdef completely, this will add few fields to the struct unused, but it improves readability and maintainability of the code. Signed-off-by: Kevin Hilman [hvaibhav@ti.com: wrote detailed changelog] Signed-off-by: Vaibhav Hiremath Cc: Tony Lindgren Cc: Paul Walmsley Cc: Santosh Shilimkar Cc: R Sricharan Acked-by: Santosh Shilimkar Signed-off-by: Paul Walmsley --- arch/arm/plat-omap/include/plat/clock.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index d0ef57c1d71b..656b9862279e 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -156,7 +156,6 @@ struct dpll_data { u8 min_divider; u16 max_divider; u8 modes; -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) void __iomem *autoidle_reg; void __iomem *idlest_reg; u32 autoidle_mask; @@ -167,7 +166,6 @@ struct dpll_data { u8 auto_recal_bit; u8 recal_en_bit; u8 recal_st_bit; -# endif u8 flags; }; -- GitLab From 90f1380ef6436a3f5425f942ea0b3f78e1cca142 Mon Sep 17 00:00:00 2001 From: Omar Ramirez Luna Date: Mon, 18 Jun 2012 16:18:09 -0600 Subject: [PATCH 1925/6849] ARM: OMAP2+: control: new APIs to configure boot address and mode SCM contains boot addr and boot mode registers to control other processors on different OMAP versions. It controls the boot address and mode for DSP based subsystems like: IVA 2.1 (OMAP2430), IVA 2.2 (OMAP3) and DSP (OMAP4). If contained within SCM registers, when a processor is booting it uses BOOTADDR to start running the code at that location. BOOTMOD register specifies a different set of modes for the processor to execute when booting (from direct, idle, self-loop, user and default). Since there was no offset associated with OMAP4, this patch defines it. Signed-off-by: Omar Ramirez Luna Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/control.c | 43 +++++++++++++++++++ arch/arm/mach-omap2/control.h | 2 + .../include/mach/ctrl_module_core_44xx.h | 1 + 3 files changed, 46 insertions(+) diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 08e674bb0417..3223b81e7532 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -241,6 +241,49 @@ void omap3_ctrl_write_boot_mode(u8 bootmode) #endif +/** + * omap_ctrl_write_dsp_boot_addr - set boot address for a remote processor + * @bootaddr: physical address of the boot loader + * + * Set boot address for the boot loader of a supported processor + * when a power ON sequence occurs. + */ +void omap_ctrl_write_dsp_boot_addr(u32 bootaddr) +{ + u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTADDR : + cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTADDR : + cpu_is_omap44xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR : + 0; + + if (!offset) { + pr_err("%s: unsupported omap type\n", __func__); + return; + } + + omap_ctrl_writel(bootaddr, offset); +} + +/** + * omap_ctrl_write_dsp_boot_mode - set boot mode for a remote processor + * @bootmode: 8-bit value to pass to some boot code + * + * Sets boot mode for the boot loader of a supported processor + * when a power ON sequence occurs. + */ +void omap_ctrl_write_dsp_boot_mode(u8 bootmode) +{ + u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTMOD : + cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTMOD : + 0; + + if (!offset) { + pr_err("%s: unsupported omap type\n", __func__); + return; + } + + omap_ctrl_writel(bootmode, offset); +} + #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) /* * Clears the scratchpad contents in case of cold boot- diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a406fd045ce1..fcc98f822d9d 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -397,6 +397,8 @@ extern u32 omap3_arm_context[128]; extern void omap3_control_save_context(void); extern void omap3_control_restore_context(void); extern void omap3_ctrl_write_boot_mode(u8 bootmode); +extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr); +extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode); extern void omap3630_ctrl_disable_rta(void); extern int omap3_ctrl_save_padconf(void); #else diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h index 2f7ac70a20d8..01970824e0e5 100644 --- a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h @@ -42,6 +42,7 @@ #define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1 0x0268 #define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4 #define OMAP4_CTRL_MODULE_CORE_DEV_CONF 0x0300 +#define OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR 0x0304 #define OMAP4_CTRL_MODULE_CORE_LDOVBB_IVA_VOLTAGE_CTRL 0x0314 #define OMAP4_CTRL_MODULE_CORE_LDOVBB_MPU_VOLTAGE_CTRL 0x0318 #define OMAP4_CTRL_MODULE_CORE_LDOSRAM_IVA_VOLTAGE_CTRL 0x0320 -- GitLab From 3d3635c4d77a97c61a539dff86f9a4b67134b4cb Mon Sep 17 00:00:00 2001 From: Omar Ramirez Luna Date: Mon, 18 Jun 2012 16:18:10 -0600 Subject: [PATCH 1926/6849] ARM: OMAP: dsp: interface to control module functions Provide an interface for a driver to call SCM functions to set a boot address and boot mode. Signed-off-by: Omar Ramirez Luna Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/dsp.c | 4 ++++ arch/arm/plat-omap/include/plat/dsp.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c index 845309f146fe..8b251a995abf 100644 --- a/arch/arm/mach-omap2/dsp.c +++ b/arch/arm/mach-omap2/dsp.c @@ -20,6 +20,7 @@ #include #include +#include "control.h" #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #ifdef CONFIG_BRIDGE_DVFS @@ -43,6 +44,9 @@ static struct omap_dsp_platform_data omap_dsp_pdata __initdata = { .dsp_cm_read = omap2_cm_read_mod_reg, .dsp_cm_write = omap2_cm_write_mod_reg, .dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits, + + .set_bootaddr = omap_ctrl_write_dsp_boot_addr, + .set_bootmode = omap_ctrl_write_dsp_boot_mode, }; static phys_addr_t omap_dsp_phys_mempool_base; diff --git a/arch/arm/plat-omap/include/plat/dsp.h b/arch/arm/plat-omap/include/plat/dsp.h index 9c604b390f9f..5927709b1908 100644 --- a/arch/arm/plat-omap/include/plat/dsp.h +++ b/arch/arm/plat-omap/include/plat/dsp.h @@ -18,6 +18,9 @@ struct omap_dsp_platform_data { u32 (*dsp_cm_read)(s16 , u16); u32 (*dsp_cm_rmw_bits)(u32, u32, s16, s16); + void (*set_bootaddr)(u32); + void (*set_bootmode)(u8); + phys_addr_t phys_mempool_base; phys_addr_t phys_mempool_size; }; -- GitLab From fd7462de461949e36d70f5b0bc17b98c5a00729c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 18 Jun 2012 17:29:53 +0200 Subject: [PATCH 1927/6849] netfilter: ctnetlink: fix NULL dereference while trying to change helper The patch 1afc56794e03: "netfilter: nf_ct_helper: implement variable length helper private data" from Jun 7, 2012, leads to the following Smatch complaint: net/netfilter/nf_conntrack_netlink.c:1231 ctnetlink_change_helper() error: we previously assumed 'help->helper' could be null (see line 1228) This NULL dereference can be triggered with the following sequence: 1) attach the helper for first time when the conntrack is created. 2) remove the helper module or detach the helper from the conntrack via ctnetlink. 3) attach helper again (the same or different one, no matter) to the that existing conntrack again via ctnetlink. This patch fixes the problem by removing the use case that allows you to re-assign again a helper for one conntrack entry via ctnetlink since I cannot find any practical use for it. Reported-by: Dan Carpenter Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_netlink.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index ae156dff4887..76271a1301a5 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1224,19 +1224,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) if (helper->from_nlattr && helpinfo) helper->from_nlattr(helpinfo, ct); return 0; - } - if (help->helper) + } else return -EBUSY; - /* need to zero data of old helper */ - memset(help->data, 0, help->helper->data_len); - } else { - /* we cannot set a helper for an existing conntrack */ - return -EOPNOTSUPP; } - rcu_assign_pointer(help->helper, helper); - - return 0; + /* we cannot set a helper for an existing conntrack */ + return -EOPNOTSUPP; } static inline int -- GitLab From b3153100a0b1624dd82d67e956f9229a6a2dbc1b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 18 Jun 2012 16:18:42 -0600 Subject: [PATCH 1928/6849] ARM: OMAP2: Move McBSP fck clock alias to hwmod data for OMAP2420 Remove the existing alias for pad_fck, prcm_fck from the clock data and add them as opt_clks to the hwmod data. Signed-off-by: Peter Ujfalusi Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clock2420_data.c | 4 ---- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 9 +++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index bace9308a4db..7e39015357b1 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1774,8 +1774,6 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "osc_ck", &osc_ck, CK_242X), CLK(NULL, "sys_ck", &sys_ck, CK_242X), CLK(NULL, "alt_ck", &alt_ck, CK_242X), - CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_242X), - CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_242X), CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_242X), /* internal analog sources */ CLK(NULL, "dpll_ck", &dpll_ck, CK_242X), @@ -1784,8 +1782,6 @@ static struct omap_clk omap2420_clks[] = { /* internal prcm root sources */ CLK(NULL, "func_54m_ck", &func_54m_ck, CK_242X), CLK(NULL, "core_ck", &core_ck, CK_242X), - CLK("omap-mcbsp.1", "prcm_fck", &func_96m_ck, CK_242X), - CLK("omap-mcbsp.2", "prcm_fck", &func_96m_ck, CK_242X), CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X), CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X), CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X), diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a7640d1b215e..910d256f3abe 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -192,6 +192,11 @@ static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = { .name = "mcbsp", }; +static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "func_96m_ck" }, +}; + /* mcbsp1 */ static struct omap_hwmod_irq_info omap2420_mcbsp1_irqs[] = { { .name = "tx", .irq = 59 }, @@ -214,6 +219,8 @@ static struct omap_hwmod omap2420_mcbsp1_hwmod = { .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; /* mcbsp2 */ @@ -238,6 +245,8 @@ static struct omap_hwmod omap2420_mcbsp2_hwmod = { .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; static struct omap_hwmod_class_sysconfig omap2420_msdi_sysc = { -- GitLab From db382a869dfbc6f6ea298c9d8607404016cacbc0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 18 Jun 2012 16:18:43 -0600 Subject: [PATCH 1929/6849] ARM: OMAP2: Move McBSP fck clock alias to hwmod data for OMAP2430 Remove the existing alias for pad_fck, prcm_fck from the clock data and add them as opt_clks to the hwmod data. Signed-off-by: Peter Ujfalusi Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clock2430_data.c | 10 ---------- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 3b4d09a50399..90a08c3b12ac 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1858,11 +1858,6 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "osc_ck", &osc_ck, CK_243X), CLK(NULL, "sys_ck", &sys_ck, CK_243X), CLK(NULL, "alt_ck", &alt_ck, CK_243X), - CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_243X), - CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_243X), - CLK("omap-mcbsp.3", "pad_fck", &mcbsp_clks, CK_243X), - CLK("omap-mcbsp.4", "pad_fck", &mcbsp_clks, CK_243X), - CLK("omap-mcbsp.5", "pad_fck", &mcbsp_clks, CK_243X), CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_243X), /* internal analog sources */ CLK(NULL, "dpll_ck", &dpll_ck, CK_243X), @@ -1871,11 +1866,6 @@ static struct omap_clk omap2430_clks[] = { /* internal prcm root sources */ CLK(NULL, "func_54m_ck", &func_54m_ck, CK_243X), CLK(NULL, "core_ck", &core_ck, CK_243X), - CLK("omap-mcbsp.1", "prcm_fck", &func_96m_ck, CK_243X), - CLK("omap-mcbsp.2", "prcm_fck", &func_96m_ck, CK_243X), - CLK("omap-mcbsp.3", "prcm_fck", &func_96m_ck, CK_243X), - CLK("omap-mcbsp.4", "prcm_fck", &func_96m_ck, CK_243X), - CLK("omap-mcbsp.5", "prcm_fck", &func_96m_ck, CK_243X), CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X), CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X), CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X), diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 4d7264981230..f105314bdb63 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -296,6 +296,11 @@ static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = { .rev = MCBSP_CONFIG_TYPE2, }; +static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "func_96m_ck" }, +}; + /* mcbsp1 */ static struct omap_hwmod_irq_info omap2430_mcbsp1_irqs[] = { { .name = "tx", .irq = 59 }, @@ -320,6 +325,8 @@ static struct omap_hwmod omap2430_mcbsp1_hwmod = { .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; /* mcbsp2 */ @@ -345,6 +352,8 @@ static struct omap_hwmod omap2430_mcbsp2_hwmod = { .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; /* mcbsp3 */ @@ -370,6 +379,8 @@ static struct omap_hwmod omap2430_mcbsp3_hwmod = { .idlest_idle_bit = OMAP2430_ST_MCBSP3_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; /* mcbsp4 */ @@ -401,6 +412,8 @@ static struct omap_hwmod omap2430_mcbsp4_hwmod = { .idlest_idle_bit = OMAP2430_ST_MCBSP4_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; /* mcbsp5 */ @@ -432,6 +445,8 @@ static struct omap_hwmod omap2430_mcbsp5_hwmod = { .idlest_idle_bit = OMAP2430_ST_MCBSP5_SHIFT, }, }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), }; /* MMC/SD/SDIO common */ -- GitLab From 7039154bb218e06cc876a008cdf57f3fbc00c25e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 18 Jun 2012 16:18:43 -0600 Subject: [PATCH 1930/6849] ARM: OMAP3: Move McBSP fck clock alias to hwmod data Remove the existing alias for pad_fck, prcm_fck from the clock data and add them as opt_clks to the hwmod data. Signed-off-by: Peter Ujfalusi Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clock3xxx_data.c | 10 ---------- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 4e1a3b0e8cc8..d6889b58dd05 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3236,11 +3236,6 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_3XXX), CLK(NULL, "sys_ck", &sys_ck, CK_3XXX), CLK(NULL, "sys_altclk", &sys_altclk, CK_3XXX), - CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_3XXX), - CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_3XXX), - CLK("omap-mcbsp.3", "pad_fck", &mcbsp_clks, CK_3XXX), - CLK("omap-mcbsp.4", "pad_fck", &mcbsp_clks, CK_3XXX), - CLK("omap-mcbsp.5", "pad_fck", &mcbsp_clks, CK_3XXX), CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_3XXX), CLK(NULL, "sys_clkout1", &sys_clkout1, CK_3XXX), CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX), @@ -3307,8 +3302,6 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), - CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), CLK(NULL, "mmchs3_fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_3XXX), @@ -3413,9 +3406,6 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX), CLK(NULL, "gpt12_ick", &gpt12_ick, CK_3XXX), CLK(NULL, "gpt1_ick", &gpt1_ick, CK_3XXX), - CLK("omap-mcbsp.2", "prcm_fck", &per_96m_fck, CK_3XXX), - CLK("omap-mcbsp.3", "prcm_fck", &per_96m_fck, CK_3XXX), - CLK("omap-mcbsp.4", "prcm_fck", &per_96m_fck, CK_3XXX), CLK(NULL, "per_96m_fck", &per_96m_fck, CK_3XXX), CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX), CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX), diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index b26d3c9bca16..7ac051145219 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1074,6 +1074,17 @@ static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = { .rev = MCBSP_CONFIG_TYPE3, }; +/* McBSP functional clock mapping */ +static struct omap_hwmod_opt_clk mcbsp15_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "core_96m_fck" }, +}; + +static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "per_96m_fck" }, +}; + /* mcbsp1 */ static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = { { .name = "common", .irq = 16 }, @@ -1097,6 +1108,8 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = { .idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT, }, }, + .opt_clks = mcbsp15_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks), }; /* mcbsp2 */ @@ -1126,6 +1139,8 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = { .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, }, }, + .opt_clks = mcbsp234_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), .dev_attr = &omap34xx_mcbsp2_dev_attr, }; @@ -1156,6 +1171,8 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = { .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, }, }, + .opt_clks = mcbsp234_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), .dev_attr = &omap34xx_mcbsp3_dev_attr, }; @@ -1188,6 +1205,8 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = { .idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT, }, }, + .opt_clks = mcbsp234_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), }; /* mcbsp5 */ @@ -1219,6 +1238,8 @@ static struct omap_hwmod omap3xxx_mcbsp5_hwmod = { .idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT, }, }, + .opt_clks = mcbsp15_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks), }; /* 'mcbsp sidetone' class */ -- GitLab From 8e3bbf42c6d73881956863cc3305456afe2bc4ea Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Thu, 14 Jun 2012 14:55:30 -0700 Subject: [PATCH 1931/6849] cgroups: Account for CSS_DEACT_BIAS in __css_put When we fixed the race between atomic_dec and css_refcnt, we missed the fact that css_refcnt internally subtracts CSS_DEACT_BIAS to get the actual reference count. This can potentially cause a refcount leak if __css_put races with cgroup_clear_css_refs. Signed-off-by: Salman Qazi Acked-by: Li Zefan Signed-off-by: Tejun Heo --- kernel/cgroup.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ceeafe874b3f..2097684cf194 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -255,12 +255,17 @@ int cgroup_lock_is_held(void) EXPORT_SYMBOL_GPL(cgroup_lock_is_held); +static int css_unbias_refcnt(int refcnt) +{ + return refcnt >= 0 ? refcnt : refcnt - CSS_DEACT_BIAS; +} + /* the current nr of refs, always >= 0 whether @css is deactivated or not */ static int css_refcnt(struct cgroup_subsys_state *css) { int v = atomic_read(&css->refcnt); - return v >= 0 ? v : v - CSS_DEACT_BIAS; + return css_unbias_refcnt(v); } /* convenient tests for these bits */ @@ -4982,9 +4987,12 @@ EXPORT_SYMBOL_GPL(__css_tryget); void __css_put(struct cgroup_subsys_state *css) { struct cgroup *cgrp = css->cgroup; + int v; rcu_read_lock(); - switch (atomic_dec_return(&css->refcnt)) { + v = css_unbias_refcnt(atomic_dec_return(&css->refcnt)); + + switch (v) { case 1: if (notify_on_release(cgrp)) { set_bit(CGRP_RELEASABLE, &cgrp->flags); -- GitLab From fec1868e23099023bc545e199b78d99840b1abc9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Jun 2012 15:38:22 -0700 Subject: [PATCH 1932/6849] USB: properly pad out usb_device_id.driver_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some systems, struct usb_device_id doesn't align properly due to the recent changes in it. So pad out the driver_info field to align on a boundry that systems can handle it. Reported-by: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Cc: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- include/linux/mod_devicetable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 7771d453e5f3..6955045199b0 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -122,7 +122,8 @@ struct usb_device_id { __u8 bInterfaceNumber; /* not matched against */ - kernel_ulong_t driver_info; + kernel_ulong_t driver_info + __attribute__((aligned(sizeof(kernel_ulong_t)))); }; /* Some useful macros to use to create struct usb_device_id */ -- GitLab From 4e6bb2a5fb9265a222e3a86b215f4c5e6bcd61de Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Fri, 8 Jun 2012 04:46:38 -0300 Subject: [PATCH 1933/6849] [media] s5p-mfc: Bug fix of timestamp/timecode copy mechanism Fixed the code copying timecode/timestamp to corresponding frames between OUTPUT and CAPTURE. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/regs-mfc.h | 5 +++++ drivers/media/video/s5p-mfc/s5p_mfc_opr.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-mfc/regs-mfc.h b/drivers/media/video/s5p-mfc/regs-mfc.h index 053a8a872fd7..a19bece41ba9 100644 --- a/drivers/media/video/s5p-mfc/regs-mfc.h +++ b/drivers/media/video/s5p-mfc/regs-mfc.h @@ -164,10 +164,15 @@ decoded pic */ #define S5P_FIMV_SI_DISPLAY_Y_ADR 0x2010 /* luma addr of displayed pic */ #define S5P_FIMV_SI_DISPLAY_C_ADR 0x2014 /* chroma addrof displayed pic */ + #define S5P_FIMV_SI_CONSUMED_BYTES 0x2018 /* Consumed number of bytes to decode a frame */ #define S5P_FIMV_SI_DISPLAY_STATUS 0x201c /* status of decoded picture */ +#define S5P_FIMV_SI_DECODE_Y_ADR 0x2024 /* luma addr of decoded pic */ +#define S5P_FIMV_SI_DECODE_C_ADR 0x2028 /* chroma addrof decoded pic */ +#define S5P_FIMV_SI_DECODE_STATUS 0x202c /* status of decoded picture */ + #define S5P_FIMV_SI_CH0_SB_ST_ADR 0x2044 /* start addr of stream buf */ #define S5P_FIMV_SI_CH0_SB_FRM_SIZE 0x2048 /* size of stream buf */ #define S5P_FIMV_SI_CH0_DESC_ADR 0x204c /* addr of descriptor buf */ diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h index db83836e6a9f..5932d1c782c5 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h @@ -57,10 +57,12 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq); S5P_FIMV_SI_DISPLAY_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \ - S5P_FIMV_SI_DISPLAY_Y_ADR) << \ + S5P_FIMV_SI_DECODE_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dspl_status() readl(dev->regs_base + \ S5P_FIMV_SI_DISPLAY_STATUS) +#define s5p_mfc_get_dec_status() readl(dev->regs_base + \ + S5P_FIMV_SI_DECODE_STATUS) #define s5p_mfc_get_frame_type() (readl(dev->regs_base + \ S5P_FIMV_DECODE_FRAME_TYPE) \ & S5P_FIMV_DECODE_FRAME_MASK) -- GitLab From 9f4161a6b8796dc41dc3924d7869622f7975706a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 8 Jun 2012 04:47:34 -0300 Subject: [PATCH 1934/6849] [media] v4l: mem2mem_testdev: Fix race conditions in driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mem2mem_testdev allows multiple instances to be opened in parallel. Source and destination queue data are being shared between all instances, which can lead to kernel oops due to race conditions (most likely to happen inside device_run()). Attached patch fixes mentioned problem by storing queue data per device context. Signed-off-by: Tomasz Moń Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 50 ++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index d2dec585e61b..3945556f5733 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -110,22 +110,6 @@ enum { V4L2_M2M_DST = 1, }; -/* Source and destination queue data */ -static struct m2mtest_q_data q_data[2]; - -static struct m2mtest_q_data *get_q_data(enum v4l2_buf_type type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - return &q_data[V4L2_M2M_SRC]; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &q_data[V4L2_M2M_DST]; - default: - BUG(); - } - return NULL; -} - #define V4L2_CID_TRANS_TIME_MSEC V4L2_CID_PRIVATE_BASE #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE + 1) @@ -198,8 +182,26 @@ struct m2mtest_ctx { int aborting; struct v4l2_m2m_ctx *m2m_ctx; + + /* Source and destination queue data */ + struct m2mtest_q_data q_data[2]; }; +static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, + enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &ctx->q_data[V4L2_M2M_SRC]; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &ctx->q_data[V4L2_M2M_DST]; + default: + BUG(); + } + return NULL; +} + + static struct v4l2_queryctrl *get_ctrl(int id) { int i; @@ -223,7 +225,7 @@ static int device_process(struct m2mtest_ctx *ctx, int tile_w, bytes_left; int width, height, bytesperline; - q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT); + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); width = q_data->width; height = q_data->height; @@ -436,7 +438,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(f->type); + q_data = get_q_data(ctx, f->type); f->fmt.pix.width = q_data->width; f->fmt.pix.height = q_data->height; @@ -535,7 +537,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(f->type); + q_data = get_q_data(ctx, f->type); if (!q_data) return -EINVAL; @@ -747,7 +749,7 @@ static int m2mtest_queue_setup(struct vb2_queue *vq, struct m2mtest_q_data *q_data; unsigned int size, count = *nbuffers; - q_data = get_q_data(vq->type); + q_data = get_q_data(ctx, vq->type); size = q_data->width * q_data->height * q_data->fmt->depth >> 3; @@ -775,7 +777,7 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb) dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); - q_data = get_q_data(vb->vb2_queue->type); + q_data = get_q_data(ctx, vb->vb2_queue->type); if (vb2_plane_size(vb, 0) < q_data->sizeimage) { dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n", @@ -860,6 +862,9 @@ static int m2mtest_open(struct file *file) ctx->transtime = MEM2MEM_DEF_TRANSTIME; ctx->num_processed = 0; + ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; + ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; + ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); if (IS_ERR(ctx->m2m_ctx)) { @@ -986,9 +991,6 @@ static int m2mtest_probe(struct platform_device *pdev) goto err_m2m; } - q_data[V4L2_M2M_SRC].fmt = &formats[0]; - q_data[V4L2_M2M_DST].fmt = &formats[0]; - return 0; v4l2_m2m_release(dev->m2m_dev); -- GitLab From afd14f48a732758d6fbbc3a5fc5b211742102c4b Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 12 Jun 2012 07:12:58 -0300 Subject: [PATCH 1935/6849] [media] v4l/s5p-mfc: corrected encoder v4l control definitions Patch corrects definition of H264 level control and changes bare numbers to enums in two other cases. Signed-off-by: Andrzej Hajda Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index acedb2004be3..9c19aa8038dd 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -243,12 +243,6 @@ static struct mfc_control controls[] = { .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0, .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_1) - ), }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, @@ -494,7 +488,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED, - .default_value = 0, + .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .menu_skip_mask = 0, }, { @@ -534,7 +528,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, - .default_value = 0, + .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .menu_skip_mask = 0, }, { -- GitLab From 0749ae350133204c2562c69f4265842141cacf12 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 12 Jun 2012 09:46:26 -0300 Subject: [PATCH 1936/6849] [media] v4l/s5p-mfc: added image size align in VIDIOC_TRY_FMT Image size for MFC encoder should have size between 8x4 and 1920x1080 with even width and height. Signed-off-by: Andrzej Hajda Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 9c19aa8038dd..03d83340e7fb 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -901,6 +901,8 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_err("failed to try output format\n"); return -EINVAL; } + v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, + &pix_fmt_mp->height, 4, 1080, 1, 0); } else { mfc_err("invalid buf type\n"); return -EINVAL; -- GitLab From f60935c17f0c99d4d70fa7e90cfdba3e7008282d Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Thu, 14 Jun 2012 05:58:07 -0300 Subject: [PATCH 1937/6849] [media] s5p-mfc: Fix setting controls Fixed s_ctrl function when setting the following controls: - V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER - V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index c25ec022d267..4dd32fc8fd82 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -627,13 +627,13 @@ static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY: - ctx->loop_filter_mpeg4 = ctrl->val; + ctx->display_delay = ctrl->val; break; case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE: ctx->display_delay_enable = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: - ctx->display_delay = ctrl->val; + ctx->loop_filter_mpeg4 = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: ctx->slice_interface = ctrl->val; -- GitLab From 618a2a3a72e2e41a523d25c17b85521858a41e28 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 11 Jun 2012 06:58:42 -0300 Subject: [PATCH 1938/6849] [media] s5p-mfc: Fix checkpatch error in s5p_mfc_shm.h file Fixes the following error: ERROR: open brace '{' following enum go on the same line +enum MFC_SHM_OFS +{ Signed-off-by: Sachin Kamat Acked-by: Kamil Debski Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_shm.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h index 764eac6bcc4c..cf962a466276 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h +++ b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h @@ -13,8 +13,7 @@ #ifndef S5P_MFC_SHM_H_ #define S5P_MFC_SHM_H_ -enum MFC_SHM_OFS -{ +enum MFC_SHM_OFS { EXTENEDED_DECODE_STATUS = 0x00, /* D */ SET_FRAME_TAG = 0x04, /* D */ GET_FRAME_TAG_TOP = 0x08, /* D */ -- GitLab From 4c4ed22632bfafd5367a5a864a8039f5b6efbbab Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Fri, 15 Jun 2012 13:40:32 -0300 Subject: [PATCH 1939/6849] [media] s5p-fimc: Fix control creation function Fixed the size of the V4L2_CID_COLORFX control cluster. Prior to this fix V4L2_CID_ROTATE was also icluded in the cluster preventing application from enabling rotation. Reported-by: Marek Szyprowski Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index fedcd561ba27..92fc5a20fb76 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -615,7 +615,7 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS; if (!handler->error) { - v4l2_ctrl_cluster(3, &ctrls->colorfx); + v4l2_ctrl_cluster(2, &ctrls->colorfx); ctrls->ready = true; } -- GitLab From 2bece307c96270fc3fdb2cc0ad8b918c26897b95 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Jun 2012 06:59:45 -0300 Subject: [PATCH 1940/6849] [media] Fix VIDIOC_DQEVENT docbook entry Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/vidioc-dqevent.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml index e8714aa16433..98a856f9ec30 100644 --- a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml +++ b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml @@ -89,7 +89,7 @@ &v4l2-event-frame-sync; - frame + frame_sync Event data for event V4L2_EVENT_FRAME_SYNC. -- GitLab From 099987f0aaf28771261b91a41240b9228f2e32b2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 14 Jun 2012 09:54:07 -0300 Subject: [PATCH 1941/6849] [media] smia: Fix compile failures Fix compile of smia code. Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=43337 Signed-off-by: Alan Cox Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/smiapp/Kconfig | 2 +- drivers/media/video/smiapp/smiapp-core.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/smiapp/Kconfig b/drivers/media/video/smiapp/Kconfig index f7b35ff443bf..fb99ff18be07 100644 --- a/drivers/media/video/smiapp/Kconfig +++ b/drivers/media/video/smiapp/Kconfig @@ -1,6 +1,6 @@ config VIDEO_SMIAPP tristate "SMIA++/SMIA sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK select VIDEO_SMIAPP_PLL ---help--- This is a generic driver for SMIA++/SMIA camera modules. diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c index f518026cb67b..e8c93c89265a 100644 --- a/drivers/media/video/smiapp/smiapp-core.c +++ b/drivers/media/video/smiapp/smiapp-core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include -- GitLab From 246f6f2ff2c5cf46ded6d06f11f63e38bad880d1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 19 Jun 2012 00:32:57 +0200 Subject: [PATCH 1942/6849] kmsg - kmsg_dump() fix CONFIG_PRINTK=n compilation Signed-off-by: Kay Sievers Cc: Stephen Rothwell Reported-by: Randy Dunlap Reported-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman --- include/linux/kmsg_dump.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index af4eb5a39d9a..d6bd50110ec2 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -71,19 +71,19 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason) { } -bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, - const char *line, size_t size, size_t *len) +static inline bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, + const char *line, size_t size, size_t *len) { return false; } -bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, - char *buf, size_t size, size_t *len) +static inline bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len) { return false; } -void kmsg_dump_rewind(struct kmsg_dumper *dumper) +static inline void kmsg_dump_rewind(struct kmsg_dumper *dumper) { } -- GitLab From 4d146ad7388a9cca2a890d7449aeb767565068d7 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Sat, 9 Jun 2012 20:00:19 -0300 Subject: [PATCH 1943/6849] [media] pms: fix build error in pms_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a compiler breakage introduced by commit 8173090acb33: drivers/media/video/pms.c: In function ‘pms_probe’: drivers/media/video/pms.c:1047:2: error: implicit declaration of function ‘kzalloc’ [-Werror=implicit-function-declaration] drivers/media/video/pms.c:1116:2: error: implicit declaration of function ‘kfree’ [-Werror=implicit-function-declaration] Signed-off-by: Fengguang Wu Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index af2d9086d7e8..77f9c92186f4 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include -- GitLab From 32f5376003920a8bc1bd97c6cddcf42df0b6a833 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 18 Jun 2012 17:29:53 +0200 Subject: [PATCH 1944/6849] netfilter: nf_ct_helper: disable automatic helper re-assignment of different type This patch modifies __nf_ct_try_assign_helper in a way that invalidates support for the following scenario: 1) attach the helper A for first time when the conntrack is created 2) attach new (different) helper B due to changes the reply tuple caused by NAT eg. port redirection from TCP/21 to TCP/5060 with both FTP and SIP helpers loaded, which seems to be a quite unorthodox scenario. I can provide a more elaborated patch to support this scenario but explicit helper attachment provides a better solution for this since now the use can attach the helpers consistently, without relying on the automatic helper lookup magic. This patch fixes a possible out of bound zeroing of the conntrack helper extension if the helper B uses more memory for its private data than helper A. Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_helper.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 2918ec2e4509..c4bc637feb76 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -229,7 +229,13 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, goto out; } } else { - memset(help->data, 0, helper->data_len); + /* We only allow helper re-assignment of the same sort since + * we cannot reallocate the helper extension area. + */ + if (help->helper != helper) { + RCU_INIT_POINTER(help->helper, NULL); + goto out; + } } rcu_assign_pointer(help->helper, helper); -- GitLab From 6e9c2db3aa8c8219568db31e29dce7db46aa0dad Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 18 Jun 2012 21:14:30 +0200 Subject: [PATCH 1945/6849] netfilter: fix compilation of the nfnl_cthelper if NF_CONNTRACK is unset This patch fixes the compilation of net/netfilter/nfnetlink_cthelper.c if CONFIG_NF_CONNTRACK is not set. This patch also moves the definition of the cthelper infrastructure to the scope of NF_CONNTRACK things. I have also renamed NETFILTER_NETLINK_CTHELPER by NF_CT_NETLINK_HELPER, to use similar names to other nf_conntrack_netlink extensions. Better now that this has been only for two days in David's tree. Two new dependencies have been added: * NF_CT_NETLINK * NETFILTER_NETLINK_QUEUE Since these infrastructure requires both ctnetlink and nfqueue. Reported-by: Randy Dunlap Signed-off-by: Pablo Neira Ayuso --- net/netfilter/Kconfig | 20 ++++++++++++-------- net/netfilter/Makefile | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index aae6c628991d..f1a52ba3e4c5 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -12,14 +12,6 @@ tristate "Netfilter NFACCT over NFNETLINK interface" If this option is enabled, the kernel will include support for extended accounting via NFNETLINK. -config NETFILTER_NETLINK_CTHELPER -tristate "Netfilter CTHELPER over NFNETLINK interface" - depends on NETFILTER_ADVANCED - select NETFILTER_NETLINK - help - If this option is enabled, the kernel will include support - for user-space connection tracking helpers via NFNETLINK. - config NETFILTER_NETLINK_QUEUE tristate "Netfilter NFQUEUE over NFNETLINK interface" depends on NETFILTER_ADVANCED @@ -343,6 +335,18 @@ config NF_CT_NETLINK_TIMEOUT If unsure, say `N'. +config NF_CT_NETLINK_HELPER + tristate 'Connection tracking helpers in user-space via Netlink' + select NETFILTER_NETLINK + depends on NF_CT_NETLINK + depends on NETFILTER_NETLINK_QUEUE + depends on NETFILTER_ADVANCED + help + This option enables the user-space connection tracking helpers + infrastructure. + + If unsure, say `N'. + endif # NF_CONNTRACK # transparent proxy support diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 2f3bc0f647ba..7cc20199fe8c 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_NETFILTER) = netfilter.o obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o -obj-$(CONFIG_NETFILTER_NETLINK_CTHELPER) += nfnetlink_cthelper.o obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o @@ -25,6 +24,7 @@ obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o # netlink interface for nf_conntrack obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o obj-$(CONFIG_NF_CT_NETLINK_TIMEOUT) += nfnetlink_cttimeout.o +obj-$(CONFIG_NF_CT_NETLINK_HELPER) += nfnetlink_cthelper.o # connection tracking helpers nf_conntrack_h323-objs := nf_conntrack_h323_main.o nf_conntrack_h323_asn1.o -- GitLab From 155cb06c89f13af3e3e6bd520b9c62762f532d7b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 11:36:08 +0800 Subject: [PATCH 1946/6849] extcon: Fix wrong index in max8997_extcon_cable[] Currently, the index of "Dock-desk" and "Dock-card" are the same. Thus the latter one overrides the first one. Then we have problem when calling extcon_find_cable_index() because edev->supported_cable[7] only matches "Dock-card". Signed-off-by: Axel Lin Acked-by: Kyungmin Park Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon-max8997.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 23416e443765..5ecf1763b5d4 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -116,8 +116,8 @@ const char *max8997_extcon_cable[] = { [5] = "Charge-downstream", [6] = "MHL", [7] = "Dock-desk", - [7] = "Dock-card", - [8] = "JIG", + [8] = "Dock-card", + [9] = "JIG", NULL, }; -- GitLab From 3f1dc550b069e9fbfe375844f3c76f2cdd12f05c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 11:55:18 +0800 Subject: [PATCH 1947/6849] extcon: Set platform drvdata in gpio_extcon_probe() and fix irq leak Add missing platform_set_drvdata() in gpio_extcon_probe(), otherwise calling platform_get_drvdata in gpio_extcon_remove() returns NULL. Also add missing free_irq call in gpio_extcon_remove(). Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe7a07b47336..8a0dcc11c7c7 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c @@ -125,6 +125,7 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) goto err_request_irq; + platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ gpio_extcon_work(&extcon_data->work.work); @@ -146,6 +147,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); + free_irq(extcon_data->irq, extcon_data); gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); devm_kfree(&pdev->dev, extcon_data); -- GitLab From 96c9f05b39a5a3239cf0588cc86a1b95cac652c4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 21:25:11 +0800 Subject: [PATCH 1948/6849] extcon: max8997: Add missing kfree for info->edev in max8997_muic_remove() extcon_dev_unregister(info->edev) doest not free info->edev, we need to call kfree(info->edev) here. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon-max8997.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 5ecf1763b5d4..a4ed30bd9a41 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -514,6 +514,7 @@ static int __devexit max8997_muic_remove(struct platform_device *pdev) extcon_dev_unregister(info->edev); + kfree(info->edev); kfree(info); return 0; -- GitLab From b945f3fa829a7315488f4d39a866dfbb29e8a49a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 11:55:18 +0800 Subject: [PATCH 1949/6849] extcon: Set platform drvdata in gpio_extcon_probe() and fix irq leak Add missing platform_set_drvdata() in gpio_extcon_probe(), otherwise calling platform_get_drvdata in gpio_extcon_remove() returns NULL. Also add missing free_irq call in gpio_extcon_remove(). Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe7a07b47336..8a0dcc11c7c7 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c @@ -125,6 +125,7 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) goto err_request_irq; + platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ gpio_extcon_work(&extcon_data->work.work); @@ -146,6 +147,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); + free_irq(extcon_data->irq, extcon_data); gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); devm_kfree(&pdev->dev, extcon_data); -- GitLab From 01eaf2458773b276e219a48df69351d230c63d0b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 11:56:24 +0800 Subject: [PATCH 1950/6849] extcon: Convert extcon_gpio to devm_gpio_request_one Also remove unneeded devm_kfree calls. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_gpio.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index 8a0dcc11c7c7..fe3db45fa83c 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c @@ -105,25 +105,25 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) ret = extcon_dev_register(&extcon_data->edev, &pdev->dev); if (ret < 0) - goto err_extcon_dev_register; + return ret; ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); if (ret < 0) - goto err_request_gpio; + goto err; INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); extcon_data->irq = gpio_to_irq(extcon_data->gpio); if (extcon_data->irq < 0) { ret = extcon_data->irq; - goto err_detect_irq_num_failed; + goto err; } ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler, pdata->irq_flags, pdev->name, extcon_data); if (ret < 0) - goto err_request_irq; + goto err; platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ @@ -131,13 +131,8 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) return 0; -err_request_irq: -err_detect_irq_num_failed: - gpio_free(extcon_data->gpio); -err_request_gpio: +err: extcon_dev_unregister(&extcon_data->edev); -err_extcon_dev_register: - devm_kfree(&pdev->dev, extcon_data); return ret; } @@ -148,9 +143,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) cancel_delayed_work_sync(&extcon_data->work); free_irq(extcon_data->irq, extcon_data); - gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); - devm_kfree(&pdev->dev, extcon_data); return 0; } -- GitLab From 679012655acecfa807038ccf9237bba246f9fad8 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Sun, 17 Jun 2012 12:17:31 -0300 Subject: [PATCH 1951/6849] w1: Fix a typo in 'hardware' word Signed-off-by: Otavio Salvador Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1_int.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 531434180afd..5a98649f6abc 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -118,7 +118,7 @@ int w1_add_master_device(struct w1_bus_master *master) return(-EINVAL); } /* While it would be electrically possible to make a device that - * generated a strong pullup in bit bang mode, only hardare that + * generated a strong pullup in bit bang mode, only hardware that * controls 1-wire time frames are even expected to support a strong * pullup. w1_io.c would need to support calling set_pullup before * the last write_bit operation of a w1_write_8 which it currently -- GitLab From 6355f25ed965421725d92cf719fc63008690ca1c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 18 Jun 2012 15:01:50 -0600 Subject: [PATCH 1952/6849] ARM: tegra: make tegra_cpu_reset_handler_enable() __init This solves a section mismatch warning. I hadn't noticed this before, because my compiler was inlining tegra_cpu_reset_handler_enable() inside tegra_cpu_reset_handler_init(), which is already __init, but I switched compilers and it stopped doing that. Cc: # v3.4 Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- arch/arm/mach-tegra/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index 4d6a2ee99c3b..5beb7ebe2948 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c @@ -33,7 +33,7 @@ static bool is_enabled; -static void tegra_cpu_reset_handler_enable(void) +static void __init tegra_cpu_reset_handler_enable(void) { void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE); void __iomem *evp_cpu_reset = -- GitLab From 4ea418b8b2fa8a70d0fcc8231b65e67b3a72984b Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Sat, 16 Jun 2012 16:55:20 -0500 Subject: [PATCH 1953/6849] Staging: speakup: fix an improperly-declared variable. A local static variable was declared as a pointer to a string constant. We're assigning to the underlying memory, so it needs to be an array instead. Signed-off-by: Christopher Brannon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 92b34e29ad06..40e2488b9679 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1854,7 +1854,7 @@ static void speakup_bits(struct vc_data *vc) static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) { - static u_char *goto_buf = "\0\0\0\0\0\0"; + static u_char goto_buf[8]; static int num; int maxlen, go_pos; char *cp; -- GitLab From f41ad6675f2d5705a0fc1e210af8eb4a27dbacb4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 18 Jun 2012 14:05:34 +0100 Subject: [PATCH 1954/6849] staging: comedi: change device used in dev_...() calls A previous set of patches by Ravishankar Karkala Mallikarjunayya replaced a load of printk() calls with dev_info(), dev_err(), etc. Unfortunately, these used the 'struct device *hw_dev' member of 'struct comedi_device') as the first parameter of these dev_...() calls, but that pointer is usually NULL, so the kernel log messages come out a bit wrong (they contain the phrase "(NULL device *)"). Use the 'struct device *class_dev' member of 'struct comedi_device' instead for these dev_...() calls. It will be non-NULL and somewhat meaningful to users. It's also consistent with those comedi drivers that already use the class_dev member in their dev_...() calls. Some of the messages included the format "comedi%d" with the minor device number used for the "%d". This is now redundant as it will be the same as the dev_name() part of the kernel log message produced by the dev_...() calls. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 17 ++++---- drivers/staging/comedi/drivers/adv_pci_dio.c | 8 ++-- drivers/staging/comedi/drivers/cb_das16_cs.c | 14 +++---- drivers/staging/comedi/drivers/cb_pcidas.c | 26 +++++++------ drivers/staging/comedi/drivers/cb_pcidas64.c | 20 +++++----- drivers/staging/comedi/drivers/cb_pcidda.c | 12 +++--- drivers/staging/comedi/drivers/cb_pcidio.c | 9 +++-- drivers/staging/comedi/drivers/cb_pcimdas.c | 21 +++++----- .../staging/comedi/drivers/contec_pci_dio.c | 10 ++--- drivers/staging/comedi/drivers/daqboard2000.c | 29 +++++++------- drivers/staging/comedi/drivers/das08_cs.c | 7 ++-- drivers/staging/comedi/drivers/das1800.c | 36 +++++++++-------- drivers/staging/comedi/drivers/das6402.c | 10 ++--- drivers/staging/comedi/drivers/das800.c | 39 ++++++++++--------- drivers/staging/comedi/drivers/dt3000.c | 28 ++++++------- drivers/staging/comedi/drivers/jr3_pci.c | 18 +++++---- drivers/staging/comedi/drivers/ni_pcimio.c | 4 +- drivers/staging/comedi/drivers/pcl818.c | 12 +++--- drivers/staging/comedi/drivers/pcmuio.c | 23 ++++++----- drivers/staging/comedi/drivers/serial2002.c | 4 +- 20 files changed, 187 insertions(+), 160 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 60a50adcd715..94d69e421c29 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1347,7 +1347,7 @@ static int pci1710_attach(struct comedi_device *dev, int i; int board_index; - dev_info(dev->hw_dev, "comedi%d: adv_pci1710:\n", dev->minor); + dev_info(dev->class_dev, DRV_NAME ": attach\n"); opt_bus = it->options[0]; opt_slot = it->options[1]; @@ -1399,10 +1399,10 @@ static int pci1710_attach(struct comedi_device *dev, if (!pcidev) { if (opt_bus || opt_slot) { - dev_err(dev->hw_dev, "- Card at b:s %d:%d %s\n", + dev_err(dev->class_dev, "- Card at b:s %d:%d %s\n", opt_bus, opt_slot, errstr); } else { - dev_err(dev->hw_dev, "- Card %s\n", errstr); + dev_err(dev->class_dev, "- Card %s\n", errstr); } return -EIO; } @@ -1413,8 +1413,8 @@ static int pci1710_attach(struct comedi_device *dev, irq = pcidev->irq; iobase = pci_resource_start(pcidev, 2); - dev_dbg(dev->hw_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n", pci_bus, pci_slot, - pci_func, iobase); + dev_dbg(dev->class_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n", + pci_bus, pci_slot, pci_func, iobase); dev->iobase = iobase; @@ -1444,14 +1444,15 @@ static int pci1710_attach(struct comedi_device *dev, if (request_irq(irq, interrupt_service_pci1710, IRQF_SHARED, "Advantech PCI-1710", dev)) { - dev_dbg(dev->hw_dev, "unable to allocate IRQ %d, DISABLING IT", + dev_dbg(dev->class_dev, + "unable to allocate IRQ %d, DISABLING IT", irq); irq = 0; /* Can't use IRQ */ } else { - dev_dbg(dev->hw_dev, "irq=%u", irq); + dev_dbg(dev->class_dev, "irq=%u", irq); } } else { - dev_dbg(dev->hw_dev, "IRQ disabled"); + dev_dbg(dev->class_dev, "IRQ disabled"); } } else { irq = 0; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 942dc777a0e6..176a8016432d 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1121,16 +1121,18 @@ static int pci_dio_attach(struct comedi_device *dev, } if (!dev->board_ptr) { - dev_err(dev->hw_dev, "Error: Requested type of the card was not found!\n"); + dev_err(dev->class_dev, + "Error: Requested type of the card was not found!\n"); return -EIO; } if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_err(dev->hw_dev, "Error: Can't enable PCI device and request regions!\n"); + dev_err(dev->class_dev, + "Error: Can't enable PCI device and request regions!\n"); return -EIO; } iobase = pci_resource_start(pcidev, this_board->main_pci_region); - dev_dbg(dev->hw_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n", + dev_dbg(dev->class_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n", pcidev->bus->number, PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn), iobase); diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 031007791d29..77dc880ca786 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -150,7 +150,7 @@ static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, return das16cs_boards + i; } - dev_dbg(dev->hw_dev, "unknown board!\n"); + dev_dbg(dev->class_dev, "unknown board!\n"); return NULL; } @@ -163,18 +163,18 @@ static int das16cs_attach(struct comedi_device *dev, int ret; int i; - dev_dbg(dev->hw_dev, "comedi%d: cb_das16_cs: attached\n", dev->minor); + dev_dbg(dev->class_dev, "cb_das16_cs: attach\n"); link = cur_dev; /* XXX hack */ if (!link) return -EIO; dev->iobase = link->resource[0]->start; - dev_dbg(dev->hw_dev, "I/O base=0x%04lx\n", dev->iobase); + dev_dbg(dev->class_dev, "I/O base=0x%04lx\n", dev->iobase); - dev_dbg(dev->hw_dev, "fingerprint:\n"); + dev_dbg(dev->class_dev, "fingerprint:\n"); for (i = 0; i < 48; i += 2) - dev_dbg(dev->hw_dev, "%04x\n", inw(dev->iobase + i)); + dev_dbg(dev->class_dev, "%04x\n", inw(dev->iobase + i)); ret = request_irq(link->irq, das16cs_interrupt, @@ -184,7 +184,7 @@ static int das16cs_attach(struct comedi_device *dev, dev->irq = link->irq; - dev_dbg(dev->hw_dev, "irq=%u\n", dev->irq); + dev_dbg(dev->class_dev, "irq=%u\n", dev->irq); dev->board_ptr = das16cs_probe(dev, link); if (!dev->board_ptr) @@ -306,7 +306,7 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, break; } if (to == TIMEOUT) { - dev_dbg(dev->hw_dev, "cb_das16_cs: ai timeout\n"); + dev_dbg(dev->class_dev, "cb_das16_cs: ai timeout\n"); return -ETIME; } data[i] = (unsigned short)inw(dev->iobase + 0); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 2ca3fa0fc776..e2bf22270561 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -567,12 +567,13 @@ static int cb_pcidas_attach(struct comedi_device *dev, } } - dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); + dev_err(dev->class_dev, + "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); return -EIO; found: - dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", + dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name, pcidev->bus->number, PCI_SLOT(pcidev->devfn)); @@ -580,7 +581,8 @@ found: * Enable PCI device and reserve I/O ports. */ if (comedi_pci_enable(pcidev, "cb_pcidas")) { - dev_err(dev->hw_dev, "Failed to enable PCI device and request regions\n"); + dev_err(dev->class_dev, + "Failed to enable PCI device and request regions\n"); return -EIO; } /* @@ -606,7 +608,7 @@ found: /* get irq */ if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, IRQF_SHARED, "cb_pcidas", dev)) { - dev_dbg(dev->hw_dev, "unable to allocate irq %d\n", + dev_dbg(dev->class_dev, "unable to allocate irq %d\n", devpriv->pci_dev->irq); return -EINVAL; } @@ -807,7 +809,7 @@ static int ai_config_calibration_source(struct comedi_device *dev, unsigned int source = data[1]; if (source >= num_calibration_sources) { - dev_err(dev->hw_dev, "invalid calibration source: %i\n", + dev_err(dev->class_dev, "invalid calibration source: %i\n", source); return -EINVAL; } @@ -1229,7 +1231,7 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, outw(bits, devpriv->control_status + ADCMUX_CONT); #ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "comedi: sent 0x%x to adcmux control\n", bits); + dev_dbg(dev->class_dev, "sent 0x%x to adcmux control\n", bits); #endif /* load counters */ @@ -1256,7 +1258,7 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, devpriv->adc_fifo_bits |= INT_FHF; /* interrupt fifo half full */ } #ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "comedi: adc_fifo_bits are 0x%x\n", + dev_dbg(dev->class_dev, "adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits); #endif /* enable (and clear) interrupts */ @@ -1283,7 +1285,7 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, bits |= BURSTE; outw(bits, devpriv->control_status + TRIG_CONTSTAT); #ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "comedi: sent 0x%x to trig control\n", bits); + dev_dbg(dev->class_dev, "sent 0x%x to trig control\n", bits); #endif return 0; @@ -1500,7 +1502,7 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev, spin_lock_irqsave(&dev->spinlock, flags); devpriv->adc_fifo_bits |= DAEMIE | DAHFIE; #ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "comedi: adc_fifo_bits are 0x%x\n", + dev_dbg(dev->class_dev, "adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits); #endif /* enable and clear interrupts */ @@ -1511,7 +1513,7 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev, devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY; outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); #ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "comedi: sent 0x%x to dac control\n", + dev_dbg(dev->class_dev, "sent 0x%x to dac control\n", devpriv->ao_control_bits); #endif spin_unlock_irqrestore(&dev->spinlock, flags); @@ -1540,8 +1542,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR); #ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "intcsr 0x%x\n", s5933_status); - dev_dbg(dev->hw_dev, "mbef 0x%x\n", + dev_dbg(dev->class_dev, "intcsr 0x%x\n", s5933_status); + dev_dbg(dev->class_dev, "mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF)); #endif diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 3aab75b5217d..7aacff3292c2 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1701,11 +1701,12 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", board(dev)->name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn)); + dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n", + board(dev)->name, pcidev->bus->number, PCI_SLOT(pcidev->devfn)); if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_warn(dev->hw_dev, "failed to enable PCI device and request regions\n"); + dev_warn(dev->class_dev, + "failed to enable PCI device and request regions\n"); return -EIO; } pci_set_master(pcidev); @@ -1733,7 +1734,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase || !priv(dev)->dio_counter_iobase) { - dev_warn(dev->hw_dev, "failed to remap io memory\n"); + dev_warn(dev->class_dev, "failed to remap io memory\n"); return -ENOMEM; } @@ -1769,19 +1770,19 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) priv(dev)->hw_revision = hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG)); - dev_dbg(dev->hw_dev, "stc hardware revision %i\n", + dev_dbg(dev->class_dev, "stc hardware revision %i\n", priv(dev)->hw_revision); init_plx9080(dev); init_stc_registers(dev); /* get irq */ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, "cb_pcidas64", dev)) { - dev_dbg(dev->hw_dev, "unable to allocate irq %u\n", + dev_dbg(dev->class_dev, "unable to allocate irq %u\n", pcidev->irq); return -EINVAL; } dev->irq = pcidev->irq; - dev_dbg(dev->hw_dev, "irq %u\n", dev->irq); + dev_dbg(dev->class_dev, "irq %u\n", dev->irq); retval = setup_subdevices(dev); if (retval < 0) @@ -2002,7 +2003,7 @@ static int ai_config_calibration_source(struct comedi_device *dev, else num_calibration_sources = 8; if (source >= num_calibration_sources) { - dev_dbg(dev->hw_dev, "invalid calibration source: %i\n", + dev_dbg(dev->class_dev, "invalid calibration source: %i\n", source); return -EINVAL; } @@ -2834,7 +2835,8 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) } if (num_samples < 0) { - dev_err(dev->hw_dev, "cb_pcidas64: bug! num_samples < 0\n"); + dev_err(dev->class_dev, + "cb_pcidas64: bug! num_samples < 0\n"); break; } diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 0572dc6fd5ca..f5a7957639df 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -294,21 +294,23 @@ static int cb_pcidda_attach(struct comedi_device *dev, } } if (!pcidev) { - dev_err(dev->hw_dev, "Not a ComputerBoards/MeasurementComputing card on requested position\n"); + dev_err(dev->class_dev, + "Not a ComputerBoards/MeasurementComputing card on requested position\n"); return -EIO; } found: devpriv->pci_dev = pcidev; dev->board_ptr = cb_pcidda_boards + index; /* "thisboard" macro can be used from here. */ - dev_dbg(dev->hw_dev, "Found %s at requested position\n", + dev_dbg(dev->class_dev, "Found %s at requested position\n", thisboard->name); /* * Enable PCI device and request regions. */ if (comedi_pci_enable(pcidev, thisboard->name)) { - dev_err(dev->hw_dev, "cb_pcidda: failed to enable PCI device and request regions\n"); + dev_err(dev->class_dev, + "cb_pcidda: failed to enable PCI device and request regions\n"); return -EIO; } @@ -356,10 +358,10 @@ found: s = dev->subdevices + 2; subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); - dev_dbg(dev->hw_dev, "eeprom:\n"); + dev_dbg(dev->class_dev, "eeprom:\n"); for (index = 0; index < EEPROM_SIZE; index++) { devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); - dev_dbg(dev->hw_dev, "%i:0x%x\n", index, + dev_dbg(dev->class_dev, "%i:0x%x\n", index, devpriv->eeprom_data[index]); } diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 0186737c1ee1..9160859deee3 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -155,7 +155,8 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); + dev_err(dev->class_dev, + "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); return -EIO; found: @@ -167,8 +168,8 @@ found: dev->board_name = thisboard->name; devpriv->pci_dev = pcidev; - dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", thisboard->name, - devpriv->pci_dev->bus->number, + dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n", + thisboard->name, devpriv->pci_dev->bus->number, PCI_SLOT(devpriv->pci_dev->devfn)); if (comedi_pci_enable(pcidev, thisboard->name)) return -EIO; @@ -185,7 +186,7 @@ found: for (i = 0; i < thisboard->n_8255; i++) { subdev_8255_init(dev, dev->subdevices + i, NULL, devpriv->dio_reg_base + i * 4); - dev_dbg(dev->hw_dev, "subdev %d: base = 0x%lx\n", i, + dev_dbg(dev->class_dev, "subdev %d: base = 0x%lx\n", i, devpriv->dio_reg_base + i * 4); } diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index b99a451bab9e..2977f2d309cb 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -223,12 +223,13 @@ static int cb_pcimdas_attach(struct comedi_device *dev, } } - dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); + dev_err(dev->class_dev, + "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); return -EIO; found: - dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", + dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name, pcidev->bus->number, PCI_SLOT(pcidev->devfn)); @@ -237,12 +238,14 @@ found: case 0x56: break; default: - dev_dbg(dev->hw_dev, "THIS CARD IS UNSUPPORTED.\n" + dev_dbg(dev->class_dev, "THIS CARD IS UNSUPPORTED.\n"); + dev_dbg(dev->class_dev, "PLEASE REPORT USAGE TO \n"); } if (comedi_pci_enable(pcidev, "cb_pcimdas")) { - dev_err(dev->hw_dev, "Failed to enable PCI device and request regions\n"); + dev_err(dev->class_dev, + "Failed to enable PCI device and request regions\n"); return -EIO; } @@ -252,11 +255,11 @@ found: devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3); devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4); - dev_dbg(dev->hw_dev, "devpriv->BADR0 = 0x%lx\n", devpriv->BADR0); - dev_dbg(dev->hw_dev, "devpriv->BADR1 = 0x%lx\n", devpriv->BADR1); - dev_dbg(dev->hw_dev, "devpriv->BADR2 = 0x%lx\n", devpriv->BADR2); - dev_dbg(dev->hw_dev, "devpriv->BADR3 = 0x%lx\n", devpriv->BADR3); - dev_dbg(dev->hw_dev, "devpriv->BADR4 = 0x%lx\n", devpriv->BADR4); + dev_dbg(dev->class_dev, "devpriv->BADR0 = 0x%lx\n", devpriv->BADR0); + dev_dbg(dev->class_dev, "devpriv->BADR1 = 0x%lx\n", devpriv->BADR1); + dev_dbg(dev->class_dev, "devpriv->BADR2 = 0x%lx\n", devpriv->BADR2); + dev_dbg(dev->class_dev, "devpriv->BADR3 = 0x%lx\n", devpriv->BADR3); + dev_dbg(dev->class_dev, "devpriv->BADR4 = 0x%lx\n", devpriv->BADR4); /* Dont support IRQ yet */ /* get irq */ diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 79854b1ac243..d49561ff35ba 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -71,8 +71,8 @@ static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - dev_dbg(dev->hw_dev, "contec_do_insn_bits called\n"); - dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]); + dev_dbg(dev->class_dev, "contec_do_insn_bits called\n"); + dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); if (insn->n != 2) return -EINVAL; @@ -80,7 +80,7 @@ static int contec_do_insn_bits(struct comedi_device *dev, if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; - dev_dbg(dev->hw_dev, "out: %d on %lx\n", s->state, + dev_dbg(dev->class_dev, "out: %d on %lx\n", s->state, dev->iobase + thisboard->out_offs); outw(s->state, dev->iobase + thisboard->out_offs); } @@ -92,8 +92,8 @@ static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - dev_dbg(dev->hw_dev, "contec_di_insn_bits called\n"); - dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]); + dev_dbg(dev->class_dev, "contec_di_insn_bits called\n"); + dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); if (insn->n != 2) return -EINVAL; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 9ecf1a468567..8455cb9f8d1c 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -485,7 +485,7 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev, static void daqboard2000_resetLocalBus(struct comedi_device *dev) { - dev_dbg(dev->hw_dev, "daqboard2000_resetLocalBus\n"); + dev_dbg(dev->class_dev, "daqboard2000_resetLocalBus\n"); writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c); udelay(10000); writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c); @@ -494,7 +494,7 @@ static void daqboard2000_resetLocalBus(struct comedi_device *dev) static void daqboard2000_reloadPLX(struct comedi_device *dev) { - dev_dbg(dev->hw_dev, "daqboard2000_reloadPLX\n"); + dev_dbg(dev->class_dev, "daqboard2000_reloadPLX\n"); writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c); udelay(10000); writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c); @@ -505,7 +505,7 @@ static void daqboard2000_reloadPLX(struct comedi_device *dev) static void daqboard2000_pulseProgPin(struct comedi_device *dev) { - dev_dbg(dev->hw_dev, "daqboard2000_pulseProgPin 1\n"); + dev_dbg(dev->class_dev, "daqboard2000_pulseProgPin 1\n"); writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c); udelay(10000); writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c); @@ -557,14 +557,14 @@ static int initialize_daqboard2000(struct comedi_device *dev, secr = readl(devpriv->plx + 0x6c); if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) { #ifdef DEBUG_EEPROM - dev_dbg(dev->hw_dev, "no serial eeprom\n"); + dev_dbg(dev->class_dev, "no serial eeprom\n"); #endif return -EIO; } for (retry = 0; retry < 3; retry++) { #ifdef DEBUG_EEPROM - dev_dbg(dev->hw_dev, "Programming EEPROM try %x\n", retry); + dev_dbg(dev->class_dev, "Programming EEPROM try %x\n", retry); #endif daqboard2000_resetLocalBus(dev); @@ -575,8 +575,8 @@ static int initialize_daqboard2000(struct comedi_device *dev, if (cpld_array[i] == 0xff && cpld_array[i + 1] == 0x20) { #ifdef DEBUG_EEPROM - dev_dbg(dev->hw_dev, "Preamble found at %d\n", - i); + dev_dbg(dev->class_dev, + "Preamble found at %d\n", i); #endif break; } @@ -589,7 +589,7 @@ static int initialize_daqboard2000(struct comedi_device *dev, } if (i >= len) { #ifdef DEBUG_EEPROM - dev_dbg(dev->hw_dev, "Programmed\n"); + dev_dbg(dev->class_dev, "Programmed\n"); #endif daqboard2000_resetLocalBus(dev); daqboard2000_reloadPLX(dev); @@ -733,10 +733,11 @@ static int daqboard2000_attach(struct comedi_device *dev, } if (!card) { if (bus || slot) - dev_err(dev->hw_dev, "no daqboard2000 found at bus/slot: %d/%d\n", + dev_err(dev->class_dev, + "no daqboard2000 found at bus/slot: %d/%d\n", bus, slot); else - dev_err(dev->hw_dev, "no daqboard2000 found\n"); + dev_err(dev->class_dev, "no daqboard2000 found\n"); return -EIO; } else { u32 id; @@ -746,7 +747,7 @@ static int daqboard2000_attach(struct comedi_device *dev, subsystem_device << 16) | card->subsystem_vendor; for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { if (boardtypes[i].id == id) { - dev_dbg(dev->hw_dev, "%s\n", + dev_dbg(dev->class_dev, "%s\n", boardtypes[i].name); dev->board_ptr = boardtypes + i; } @@ -761,7 +762,8 @@ static int daqboard2000_attach(struct comedi_device *dev, result = comedi_pci_enable(card, "daqboard2000"); if (result < 0) { - dev_err(dev->hw_dev, "failed to enable PCI device and request regions\n"); + dev_err(dev->class_dev, + "failed to enable PCI device and request regions\n"); return -EIO; } devpriv->got_regions = 1; @@ -791,7 +793,8 @@ static int daqboard2000_attach(struct comedi_device *dev, if (aux_data && aux_len) { result = initialize_daqboard2000(dev, aux_data, aux_len); } else { - dev_dbg(dev->hw_dev, "no FPGA initialization code, aborting\n"); + dev_dbg(dev->class_dev, + "no FPGA initialization code, aborting\n"); result = -EIO; } if (result < 0) diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 4ad398aad72c..8bf6ec2dddba 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -79,17 +79,18 @@ static int das08_cs_attach(struct comedi_device *dev, if (ret < 0) return ret; - dev_info(dev->hw_dev, "comedi%d: das08_cs:\n", dev->minor); + dev_info(dev->class_dev, "das08_cs: attach\n"); /* deal with a pci board */ if (thisboard->bustype == pcmcia) { if (link == NULL) { - dev_err(dev->hw_dev, "no pcmcia cards found\n"); + dev_err(dev->class_dev, "no pcmcia cards found\n"); return -EIO; } iobase = link->resource[0]->start; } else { - dev_err(dev->hw_dev, "bug! board does not have PCMCIA bustype\n"); + dev_err(dev->class_dev, + "bug! board does not have PCMCIA bustype\n"); return -EINVAL; } diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index af60e5d5b8a3..365028772b00 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1405,22 +1405,26 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, devpriv->dma_bits |= DMA_CH7_CH5; break; default: - dev_err(dev->hw_dev, " only supports dma channels 5 through 7\n" - " Dual dma only allows the following combinations:\n" - " dma 5,6 / 6,7 / or 7,5\n"); + dev_err(dev->class_dev, + "only supports dma channels 5 through 7\n"); + dev_err(dev->class_dev, + "Dual dma only allows the following combinations:\n"); + dev_err(dev->class_dev, + "dma 5,6 / 6,7 / or 7,5\n"); return -EINVAL; break; } if (request_dma(dma0, dev->driver->driver_name)) { - dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", - dma0); + dev_err(dev->class_dev, + "failed to allocate dma channel %i\n", dma0); return -EINVAL; } devpriv->dma0 = dma0; devpriv->dma_current = dma0; if (dma1) { if (request_dma(dma1, dev->driver->driver_name)) { - dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", + dev_err(dev->class_dev, + "failed to allocate dma channel %i\n", dma1); return -EINVAL; } @@ -1460,7 +1464,7 @@ static int das1800_probe(struct comedi_device *dev) case 0x3: if (board == das1801st_da || board == das1802st_da || board == das1701st_da || board == das1702st_da) { - dev_dbg(dev->hw_dev, "Board model: %s\n", + dev_dbg(dev->class_dev, "Board model: %s\n", das1800_boards[board].name); return board; } @@ -1470,7 +1474,7 @@ static int das1800_probe(struct comedi_device *dev) break; case 0x4: if (board == das1802hr_da || board == das1702hr_da) { - dev_dbg(dev->hw_dev, "Board model: %s\n", + dev_dbg(dev->class_dev, "Board model: %s\n", das1800_boards[board].name); return board; } @@ -1481,7 +1485,7 @@ static int das1800_probe(struct comedi_device *dev) case 0x5: if (board == das1801ao || board == das1802ao || board == das1701ao || board == das1702ao) { - dev_dbg(dev->hw_dev, "Board model: %s\n", + dev_dbg(dev->class_dev, "Board model: %s\n", das1800_boards[board].name); return board; } @@ -1491,7 +1495,7 @@ static int das1800_probe(struct comedi_device *dev) break; case 0x6: if (board == das1802hr || board == das1702hr) { - dev_dbg(dev->hw_dev, "Board model: %s\n", + dev_dbg(dev->class_dev, "Board model: %s\n", das1800_boards[board].name); return board; } @@ -1502,7 +1506,7 @@ static int das1800_probe(struct comedi_device *dev) case 0x7: if (board == das1801st || board == das1802st || board == das1701st || board == das1702st) { - dev_dbg(dev->hw_dev, "Board model: %s\n", + dev_dbg(dev->class_dev, "Board model: %s\n", das1800_boards[board].name); return board; } @@ -1512,7 +1516,7 @@ static int das1800_probe(struct comedi_device *dev) break; case 0x8: if (board == das1801hc || board == das1802hc) { - dev_dbg(dev->hw_dev, "Board model: %s\n", + dev_dbg(dev->class_dev, "Board model: %s\n", das1800_boards[board].name); return board; } @@ -1559,7 +1563,7 @@ static int das1800_attach(struct comedi_device *dev, printk(KERN_CONT "\n"); if (iobase == 0) { - dev_err(dev->hw_dev, "io base address required\n"); + dev_err(dev->class_dev, "io base address required\n"); return -EINVAL; } @@ -1574,7 +1578,7 @@ static int das1800_attach(struct comedi_device *dev, board = das1800_probe(dev); if (board < 0) { - dev_err(dev->hw_dev, "unable to determine board type\n"); + dev_err(dev->class_dev, "unable to determine board type\n"); return -ENODEV; } @@ -1598,7 +1602,7 @@ static int das1800_attach(struct comedi_device *dev, if (irq) { if (request_irq(irq, das1800_interrupt, 0, dev->driver->driver_name, dev)) { - dev_dbg(dev->hw_dev, "unable to allocate irq %u\n", + dev_dbg(dev->class_dev, "unable to allocate irq %u\n", irq); return -EINVAL; } @@ -1628,7 +1632,7 @@ static int das1800_attach(struct comedi_device *dev, devpriv->irq_dma_bits |= 0x38; break; default: - dev_err(dev->hw_dev, "irq out of range\n"); + dev_err(dev->class_dev, "irq out of range\n"); return -EINVAL; break; } diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 22a9b3448e3f..e3afcfa9efc8 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -155,7 +155,7 @@ static irqreturn_t intr_handler(int irq, void *d) struct comedi_subdevice *s = dev->subdevices; if (!dev->attached || devpriv->das6402_ignoreirq) { - dev_warn(dev->hw_dev, "BUG: spurious interrupt\n"); + dev_warn(dev->class_dev, "BUG: spurious interrupt\n"); return IRQ_HANDLED; } #ifdef DEBUG @@ -202,7 +202,7 @@ static int das6402_ai_cancel(struct comedi_device *dev, */ devpriv->das6402_ignoreirq = 1; - dev_dbg(dev->hw_dev, "Stopping acquisition\n"); + dev_dbg(dev->class_dev, "Stopping acquisition\n"); devpriv->das6402_ignoreirq = 1; outb_p(0x02, dev->iobase + 10); /* disable external trigging */ outw_p(SCANL, dev->iobase + 2); /* resets the card fifo */ @@ -218,7 +218,7 @@ static int das6402_ai_mode2(struct comedi_device *dev, struct comedi_subdevice *s, comedi_trig * it) { devpriv->das6402_ignoreirq = 1; - dev_dbg(dev->hw_dev, "Starting acquisition\n"); + dev_dbg(dev->class_dev, "Starting acquisition\n"); outb_p(0x03, dev->iobase + 10); /* enable external trigging */ outw_p(SCANL, dev->iobase + 2); /* resets the card fifo */ outb_p(IRQ | CONVSRC | BURSTEN | INTE, dev->iobase + 9); @@ -289,7 +289,7 @@ static int das6402_attach(struct comedi_device *dev, iobase = 0x300; if (!request_region(iobase, DAS6402_SIZE, "das6402")) { - dev_err(dev->hw_dev, "I/O port conflict\n"); + dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; @@ -297,7 +297,7 @@ static int das6402_attach(struct comedi_device *dev, /* should do a probe here */ irq = it->options[0]; - dev_dbg(dev->hw_dev, "( irq = %u )\n", irq); + dev_dbg(dev->class_dev, "( irq = %u )\n", irq); ret = request_irq(irq, intr_handler, 0, "das6402", dev); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 81698b1fd0da..917b31812b6c 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -296,46 +296,47 @@ static int das800_probe(struct comedi_device *dev) switch (id_bits) { case 0x0: if (board == das800) { - dev_dbg(dev->hw_dev, "Board model: DAS-800\n"); + dev_dbg(dev->class_dev, "Board model: DAS-800\n"); return board; } if (board == ciodas800) { - dev_dbg(dev->hw_dev, "Board model: CIO-DAS800\n"); + dev_dbg(dev->class_dev, "Board model: CIO-DAS800\n"); return board; } - dev_dbg(dev->hw_dev, "Board model (probed): DAS-800\n"); + dev_dbg(dev->class_dev, "Board model (probed): DAS-800\n"); return das800; break; case 0x2: if (board == das801) { - dev_dbg(dev->hw_dev, "Board model: DAS-801\n"); + dev_dbg(dev->class_dev, "Board model: DAS-801\n"); return board; } if (board == ciodas801) { - dev_dbg(dev->hw_dev, "Board model: CIO-DAS801\n"); + dev_dbg(dev->class_dev, "Board model: CIO-DAS801\n"); return board; } - dev_dbg(dev->hw_dev, "Board model (probed): DAS-801\n"); + dev_dbg(dev->class_dev, "Board model (probed): DAS-801\n"); return das801; break; case 0x3: if (board == das802) { - dev_dbg(dev->hw_dev, "Board model: DAS-802\n"); + dev_dbg(dev->class_dev, "Board model: DAS-802\n"); return board; } if (board == ciodas802) { - dev_dbg(dev->hw_dev, "Board model: CIO-DAS802\n"); + dev_dbg(dev->class_dev, "Board model: CIO-DAS802\n"); return board; } if (board == ciodas80216) { - dev_dbg(dev->hw_dev, "Board model: CIO-DAS802/16\n"); + dev_dbg(dev->class_dev, "Board model: CIO-DAS802/16\n"); return board; } - dev_dbg(dev->hw_dev, "Board model (probed): DAS-802\n"); + dev_dbg(dev->class_dev, "Board model (probed): DAS-802\n"); return das802; break; default: - dev_dbg(dev->hw_dev, "Board model: probe returned 0x%x (unknown)\n", + dev_dbg(dev->class_dev, + "Board model: probe returned 0x%x (unknown)\n", id_bits); return board; break; @@ -467,42 +468,42 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) int board; int ret; - dev_info(dev->hw_dev, "comedi%d: das800: io 0x%lx\n", dev->minor, - iobase); + dev_info(dev->class_dev, "das800: io 0x%lx\n", iobase); if (irq) - dev_dbg(dev->hw_dev, "irq %u\n", irq); + dev_dbg(dev->class_dev, "irq %u\n", irq); /* allocate and initialize dev->private */ if (alloc_private(dev, sizeof(struct das800_private)) < 0) return -ENOMEM; if (iobase == 0) { - dev_err(dev->hw_dev, "io base address required for das800\n"); + dev_err(dev->class_dev, + "io base address required for das800\n"); return -EINVAL; } /* check if io addresses are available */ if (!request_region(iobase, DAS800_SIZE, "das800")) { - dev_err(dev->hw_dev, "I/O port conflict\n"); + dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; board = das800_probe(dev); if (board < 0) { - dev_dbg(dev->hw_dev, "unable to determine board type\n"); + dev_dbg(dev->class_dev, "unable to determine board type\n"); return -ENODEV; } dev->board_ptr = das800_boards + board; /* grab our IRQ */ if (irq == 1 || irq > 7) { - dev_err(dev->hw_dev, "irq out of range\n"); + dev_err(dev->class_dev, "irq out of range\n"); return -EINVAL; } if (irq) { if (request_irq(irq, das800_interrupt, 0, "das800", dev)) { - dev_err(dev->hw_dev, "unable to allocate irq %u\n", + dev_err(dev->class_dev, "unable to allocate irq %u\n", irq); return -EINVAL; } diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 9828fb1e3365..31a16edc0a27 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -289,7 +289,7 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) return 0; - dev_dbg(dev->hw_dev, "dt3k_send_cmd() timeout/error status=0x%04x\n", + dev_dbg(dev->class_dev, "dt3k_send_cmd() timeout/error status=0x%04x\n", status); return -ETIME; @@ -390,7 +390,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, if (count < 0) count += AI_FIFO_DEPTH; - dev_dbg(dev->hw_dev, "reading %d samples\n", count); + dev_dbg(dev->class_dev, "reading %d samples\n", count); rear = devpriv->ai_rear; @@ -578,7 +578,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) int ret; unsigned int mode; - dev_dbg(dev->hw_dev, "dt3k_ai_cmd:\n"); + dev_dbg(dev->class_dev, "dt3k_ai_cmd:\n"); for (i = 0; i < cmd->chanlist_len; i++) { chan = CR_CHAN(cmd->chanlist[i]); range = CR_RANGE(cmd->chanlist[i]); @@ -589,15 +589,15 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) aref = CR_AREF(cmd->chanlist[0]); writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0)); - dev_dbg(dev->hw_dev, "param[0]=0x%04x\n", cmd->scan_end_arg); + dev_dbg(dev->class_dev, "param[0]=0x%04x\n", cmd->scan_end_arg); if (cmd->convert_src == TRIG_TIMER) { divider = dt3k_ns_to_timer(50, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); writew((divider >> 16), devpriv->io_addr + DPR_Params(1)); - dev_dbg(dev->hw_dev, "param[1]=0x%04x\n", divider >> 16); + dev_dbg(dev->class_dev, "param[1]=0x%04x\n", divider >> 16); writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2)); - dev_dbg(dev->hw_dev, "param[2]=0x%04x\n", divider & 0xffff); + dev_dbg(dev->class_dev, "param[2]=0x%04x\n", divider & 0xffff); } else { /* not supported */ } @@ -606,21 +606,21 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3)); - dev_dbg(dev->hw_dev, "param[3]=0x%04x\n", tscandiv >> 16); + dev_dbg(dev->class_dev, "param[3]=0x%04x\n", tscandiv >> 16); writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4)); - dev_dbg(dev->hw_dev, "param[4]=0x%04x\n", tscandiv & 0xffff); + dev_dbg(dev->class_dev, "param[4]=0x%04x\n", tscandiv & 0xffff); } else { /* not supported */ } mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0; writew(mode, devpriv->io_addr + DPR_Params(5)); - dev_dbg(dev->hw_dev, "param[5]=0x%04x\n", mode); + dev_dbg(dev->class_dev, "param[5]=0x%04x\n", mode); writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6)); - dev_dbg(dev->hw_dev, "param[6]=0x%04x\n", aref == AREF_DIFF); + dev_dbg(dev->class_dev, "param[6]=0x%04x\n", aref == AREF_DIFF); writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7)); - dev_dbg(dev->hw_dev, "param[7]=0x%04x\n", AI_FIFO_DEPTH / 2); + dev_dbg(dev->class_dev, "param[7]=0x%04x\n", AI_FIFO_DEPTH / 2); writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); ret = dt3k_send_cmd(dev, CMD_CONFIG); @@ -856,7 +856,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) int bus, slot; int ret = 0; - dev_dbg(dev->hw_dev, "dt3000:\n"); + dev_dbg(dev->class_dev, "dt3000:\n"); bus = it->options[0]; slot = it->options[1]; @@ -868,7 +868,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; if (ret == 0) { - dev_warn(dev->hw_dev, "no DT board found\n"); + dev_warn(dev->class_dev, "no DT board found\n"); return -ENODEV; } @@ -876,7 +876,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (request_irq(devpriv->pci_dev->irq, dt3k_interrupt, IRQF_SHARED, "dt3000", dev)) { - dev_err(dev->hw_dev, "unable to allocate IRQ %u\n", + dev_err(dev->class_dev, "unable to allocate IRQ %u\n", devpriv->pci_dev->irq); return -EINVAL; } diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 3c043e535506..93f94cd7bae2 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -349,13 +349,13 @@ static int jr3_pci_open(struct comedi_device *dev) int i; struct jr3_pci_dev_private *devpriv = dev->private; - dev_dbg(dev->hw_dev, "jr3_pci_open\n"); + dev_dbg(dev->class_dev, "jr3_pci_open\n"); for (i = 0; i < devpriv->n_channels; i++) { struct jr3_pci_subdev_private *p; p = dev->subdevices[i].private; if (p) { - dev_dbg(dev->hw_dev, "serial: %p %d (%d)\n", p, + dev_dbg(dev->class_dev, "serial: %p %d (%d)\n", p, p->serial_no, p->channel_no); } } @@ -434,7 +434,8 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, break; more = more && read_idm_word(data, size, &pos, &addr); - dev_dbg(dev->hw_dev, "Loading#%d %4.4x bytes at %4.4x\n", + dev_dbg(dev->class_dev, + "Loading#%d %4.4x bytes at %4.4x\n", i, count, addr); while (more && count > 0) { if (addr & 0x4000) { @@ -754,7 +755,8 @@ static int jr3_pci_attach(struct comedi_device *dev, opt_slot = it->options[1]; if (sizeof(struct jr3_channel) != 0xc00) { - dev_err(dev->hw_dev, "sizeof(struct jr3_channel) = %x [expected %x]\n", + dev_err(dev->class_dev, + "sizeof(struct jr3_channel) = %x [expected %x]\n", (unsigned)sizeof(struct jr3_channel), 0xc00); return -EINVAL; } @@ -809,7 +811,7 @@ static int jr3_pci_attach(struct comedi_device *dev, } } if (!card) { - dev_err(dev->hw_dev, "no jr3_pci found\n"); + dev_err(dev->class_dev, "no jr3_pci found\n"); return -EIO; } else { devpriv->pci_dev = card; @@ -844,7 +846,7 @@ static int jr3_pci_attach(struct comedi_device *dev, p = dev->subdevices[i].private; p->channel = &devpriv->iobase->channel[i].data; - dev_dbg(dev->hw_dev, "p->channel %p %p (%tx)\n", + dev_dbg(dev->class_dev, "p->channel %p %p (%tx)\n", p->channel, devpriv->iobase, ((char *)(p->channel) - (char *)(devpriv->iobase))); @@ -885,7 +887,7 @@ static int jr3_pci_attach(struct comedi_device *dev, devpriv->iobase->channel[0].reset = 0; result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware); - dev_dbg(dev->hw_dev, "Firmare load %d\n", result); + dev_dbg(dev->class_dev, "Firmare load %d\n", result); if (result < 0) goto out; @@ -903,7 +905,7 @@ static int jr3_pci_attach(struct comedi_device *dev, */ msleep_interruptible(25); for (i = 0; i < 0x18; i++) { - dev_dbg(dev->hw_dev, "%c\n", + dev_dbg(dev->class_dev, "%c\n", get_u16(&devpriv->iobase->channel[0]. data.copyright[i]) >> 8); } diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 3974c0d98d2a..89f4d43c6d08 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1593,7 +1593,7 @@ static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; - dev_info(dev->hw_dev, "comedi%d: ni_pcimio:\n", dev->minor); + dev_info(dev->class_dev, "ni_pcimio: attach\n"); ret = ni_alloc_private(dev); if (ret < 0) @@ -1603,7 +1603,7 @@ static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - dev_dbg(dev->hw_dev, "%s\n", boardtype.name); + dev_dbg(dev->class_dev, "%s\n", boardtype.name); dev->board_name = boardtype.name; if (boardtype.reg_type & ni_reg_m_series_mask) { diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 786c3b6442a6..23b61d8aa404 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -952,7 +952,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, int divisor1 = 0, divisor2 = 0; unsigned int seglen; - dev_dbg(dev->hw_dev, "pcl818_ai_cmd_mode()\n"); + dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode()\n"); if ((!dev->irq) && (!devpriv->dma_rtc)) { comedi_error(dev, "IRQ not defined!"); return -EINVAL; @@ -1055,7 +1055,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, break; } #endif - dev_dbg(dev->hw_dev, "pcl818_ai_cmd_mode() end\n"); + dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode() end\n"); return 0; } @@ -1386,7 +1386,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_cmd *cmd = &s->async->cmd; int retval; - dev_dbg(dev->hw_dev, "pcl818_ai_cmd()\n"); + dev_dbg(dev->class_dev, "pcl818_ai_cmd()\n"); devpriv->ai_n_chan = cmd->chanlist_len; devpriv->ai_chanlist = cmd->chanlist; devpriv->ai_flags = cmd->flags; @@ -1404,7 +1404,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->convert_src == TRIG_TIMER) { /* mode 1 */ devpriv->ai_timer1 = cmd->convert_arg; retval = pcl818_ai_cmd_mode(1, dev, s); - dev_dbg(dev->hw_dev, "pcl818_ai_cmd() end\n"); + dev_dbg(dev->class_dev, "pcl818_ai_cmd() end\n"); return retval; } if (cmd->convert_src == TRIG_EXT) { /* mode 3 */ @@ -1423,7 +1423,7 @@ static int pcl818_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { if (devpriv->irq_blocked > 0) { - dev_dbg(dev->hw_dev, "pcl818_ai_cancel()\n"); + dev_dbg(dev->class_dev, "pcl818_ai_cancel()\n"); devpriv->irq_was_now_closed = 1; switch (devpriv->ai_mode) { @@ -1473,7 +1473,7 @@ static int pcl818_ai_cancel(struct comedi_device *dev, } end: - dev_dbg(dev->hw_dev, "pcl818_ai_cancel() end\n"); + dev_dbg(dev->class_dev, "pcl818_ai_cancel() end\n"); return 0; } diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 48565fe9efcc..4426e1798ed5 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -227,7 +227,7 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, #ifdef DAMMIT_ITS_BROKEN /* DEBUG */ - dev_dbg(dev->hw_dev, "write mask: %08x data: %08x\n", data[0], + dev_dbg(dev->class_dev, "write mask: %08x data: %08x\n", data[0], data[1]); #endif @@ -264,7 +264,7 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, } #ifdef DAMMIT_ITS_BROKEN /* DEBUG */ - dev_dbg(dev->hw_dev, "data_out_byte %02x\n", (unsigned)byte); + dev_dbg(dev->class_dev, "data_out_byte %02x\n", (unsigned)byte); #endif /* save the digital input lines for this byte.. */ s->state |= ((unsigned int)byte) << offset; @@ -275,7 +275,7 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, #ifdef DAMMIT_ITS_BROKEN /* DEBUG */ - dev_dbg(dev->hw_dev, "s->state %08x data_out %08x\n", s->state, + dev_dbg(dev->class_dev, "s->state %08x data_out %08x\n", s->state, data[1]); #endif @@ -760,7 +760,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq[0] = it->options[1]; irq[1] = it->options[2]; - dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor, + dev_dbg(dev->class_dev, "%s: io: %lx attach\n", dev->driver->driver_name, iobase); dev->iobase = iobase; @@ -768,7 +768,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!iobase || !request_region(iobase, board->num_asics * ASIC_IOSIZE, dev->driver->driver_name)) { - dev_err(dev->hw_dev, "I/O port conflict\n"); + dev_err(dev->class_dev, "I/O port conflict\n"); return -EIO; } @@ -779,7 +779,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) * convenient macro defined in comedidev.h. */ if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { - dev_warn(dev->hw_dev, "cannot allocate private data structure\n"); + dev_warn(dev->class_dev, + "cannot allocate private data structure\n"); return -ENOMEM; } @@ -798,7 +799,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), GFP_KERNEL); if (!devpriv->sprivs) { - dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n"); + dev_warn(dev->class_dev, + "cannot allocate subdevice private data structures\n"); return -ENOMEM; } @@ -890,11 +892,12 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) irqs.. */ if (irq[0]) { - dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]); + dev_dbg(dev->class_dev, "irq: %u\n", irq[0]); if (irq[1] && board->num_asics == 2) - dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]); + dev_dbg(dev->class_dev, "second ASIC irq: %u\n", + irq[1]); } else { - dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n"); + dev_dbg(dev->class_dev, "(IRQ mode disabled)\n"); } diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index e62297380786..c18314be8c82 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -782,7 +782,7 @@ static int serial2002_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - dev_dbg(dev->hw_dev, "comedi%d: attached\n", dev->minor); + dev_dbg(dev->class_dev, "serial2002: attach\n"); dev->board_name = board->name; if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) return -ENOMEM; @@ -790,7 +790,7 @@ static int serial2002_attach(struct comedi_device *dev, dev->close = serial_2002_close; devpriv->port = it->options[0]; devpriv->speed = it->options[1]; - dev_dbg(dev->hw_dev, "/dev/ttyS%d @ %d\n", devpriv->port, + dev_dbg(dev->class_dev, "/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed); ret = comedi_alloc_subdevices(dev, 5); -- GitLab From 185f9aa7df9b75609f6828ecc0d0120fbe94da08 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 18 Jun 2012 15:16:44 +0100 Subject: [PATCH 1955/6849] staging: comedi: usbduxfast: use attach_usb() hook Change the usbduxfast driver to use the new attach_usb() hook in struct comedi_driver to auto-configure probed USB devices after the firmware is loaded. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 133 ++++++++++++-------- 1 file changed, 79 insertions(+), 54 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 2ee9ecd33539..c71362086cdf 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1619,64 +1619,28 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) #endif } -/* - * is called when comedi-config is called - */ -static int usbduxfast_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +/* common part of attach and attach_usb */ +static int usbduxfast_attach_common(struct comedi_device *dev, + struct usbduxfastsub_s *udfs, + void *aux_data, int aux_len) { int ret; - int index; - int i; - struct comedi_subdevice *s = NULL; - dev->private = NULL; - - down(&start_stop_sem); - /* - * find a valid device which has been detected by the - * probe function of the usb - */ - index = -1; - for (i = 0; i < NUMUSBDUXFAST; i++) { - if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) { - index = i; - break; - } - } - - if (index < 0) { - printk(KERN_ERR "comedi%d: usbduxfast: error: attach failed, " - "no usbduxfast devs connected to the usb bus.\n", - dev->minor); - up(&start_stop_sem); - return -ENODEV; - } + struct comedi_subdevice *s; - down(&(usbduxfastsub[index].sem)); + down(&udfs->sem); /* pointer back to the corresponding comedi device */ - usbduxfastsub[index].comedidev = dev; - + udfs->comedidev = dev; /* trying to upload the firmware into the chip */ - if (comedi_aux_data(it->options, 0) && - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { - firmwareUpload(&usbduxfastsub[index], - comedi_aux_data(it->options, 0), - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); - } - + if (aux_data) + firmwareUpload(udfs, aux_data, aux_len); dev->board_name = BOARDNAME; - ret = comedi_alloc_subdevices(dev, 1); if (ret) { - up(&(usbduxfastsub[index].sem)); - up(&start_stop_sem); + up(&udfs->sem); return ret; } - - printk(KERN_INFO "comedi%d: usbduxfast: usb-device %d is attached to " - "comedi.\n", dev->minor, index); /* private structure is also simply the usb-structure */ - dev->private = usbduxfastsub + index; + dev->private = udfs; /* the first subdevice is the A/D converter */ s = dev->subdevices + SUBDEV_AD; /* @@ -1703,16 +1667,76 @@ static int usbduxfast_attach(struct comedi_device *dev, s->maxdata = 0x1000; /* range table to convert to physical units */ s->range_table = &range_usbduxfast_ai_range; - /* finally decide that it's attached */ - usbduxfastsub[index].attached = 1; + udfs->attached = 1; + up(&udfs->sem); + dev_info(dev->class_dev, "successfully attached to usbduxfast.\n"); + return 0; +} + +/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ +static int usbduxfast_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int ret; + int index; + int i; + void *aux_data; + int aux_len; - up(&(usbduxfastsub[index].sem)); + dev->private = NULL; + + aux_data = comedi_aux_data(it->options, 0); + aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; + if (aux_data == NULL) + aux_len = 0; + else if (aux_len == 0) + aux_data = NULL; + down(&start_stop_sem); + /* + * find a valid device which has been detected by the + * probe function of the usb + */ + index = -1; + for (i = 0; i < NUMUSBDUXFAST; i++) { + if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) { + index = i; + break; + } + } + if (index < 0) { + dev_err(dev->class_dev, + "usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n"); + ret = -ENODEV; + } else + ret = usbduxfast_attach_common(dev, &usbduxfastsub[index], + aux_data, aux_len); up(&start_stop_sem); - printk(KERN_INFO "comedi%d: successfully attached to usbduxfast.\n", - dev->minor); + return ret; +} - return 0; +/* is called from comedi_usb_auto_config() */ +static int usbduxfast_attach_usb(struct comedi_device *dev, + struct usb_interface *uinterf) +{ + int ret; + struct usbduxfastsub_s *udfs; + + dev->private = NULL; + down(&start_stop_sem); + udfs = usb_get_intfdata(uinterf); + if (!udfs || !udfs->probed) { + dev_err(dev->class_dev, + "usbduxfast: error: attach_usb failed, not connected\n"); + ret = -ENODEV; + } else if (udfs->attached) { + dev_err(dev->class_dev, + "usbduxfast: error: attach_usb failed, already attached\n"); + ret = -ENODEV; + } else + ret = usbduxfast_attach_common(dev, udfs, NULL, 0); + up(&start_stop_sem); + return ret; } static void usbduxfast_detach(struct comedi_device *dev) @@ -1737,7 +1761,8 @@ static struct comedi_driver driver_usbduxfast = { .driver_name = "usbduxfast", .module = THIS_MODULE, .attach = usbduxfast_attach, - .detach = usbduxfast_detach + .detach = usbduxfast_detach, + .attach_usb = usbduxfast_attach_usb, }; /* -- GitLab From f7d4d3bc0c5e30ac58e9e41c695852bfdcb8cb95 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 18 Jun 2012 17:36:58 +0100 Subject: [PATCH 1956/6849] staging: comedi: vmk80xx: use attach_usb() hook Change the vmv80xx driver to use the new attach_usb() hook in struct comedi_driver to auto-configure probed USB devices after the firmware is loaded. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 84 +++++++++++++----------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 69402dade14b..7d3cb3a035e6 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1127,46 +1127,25 @@ static int vmk80xx_pwm_winsn(struct comedi_device *cdev, return n; } -static int vmk80xx_attach(struct comedi_device *cdev, - struct comedi_devconfig *it) +static int vmk80xx_attach_common(struct comedi_device *cdev, + struct vmk80xx_usb *dev) { - int i; - struct vmk80xx_usb *dev; int n_subd; struct comedi_subdevice *s; - int minor; int ret; - mutex_lock(&glb_mutex); - - for (i = 0; i < VMK80XX_MAX_BOARDS; i++) - if (vmb[i].probed && !vmb[i].attached) - break; - - if (i == VMK80XX_MAX_BOARDS) { - mutex_unlock(&glb_mutex); - return -ENODEV; - } - - dev = &vmb[i]; - down(&dev->limit_sem); - cdev->board_name = dev->board.name; cdev->private = dev; - if (dev->board.model == VMK8055_MODEL) n_subd = 5; else n_subd = 6; - ret = comedi_alloc_subdevices(cdev, n_subd); if (ret) { up(&dev->limit_sem); - mutex_unlock(&glb_mutex); return ret; } - /* Analog input subdevice */ s = cdev->subdevices + VMK80XX_SUBD_AI; s->type = COMEDI_SUBD_AI; @@ -1175,7 +1154,6 @@ static int vmk80xx_attach(struct comedi_device *cdev, s->maxdata = (1 << dev->board.ai_bits) - 1; s->range_table = dev->board.range; s->insn_read = vmk80xx_ai_rinsn; - /* Analog output subdevice */ s = cdev->subdevices + VMK80XX_SUBD_AO; s->type = COMEDI_SUBD_AO; @@ -1184,12 +1162,10 @@ static int vmk80xx_attach(struct comedi_device *cdev, s->maxdata = (1 << dev->board.ao_bits) - 1; s->range_table = dev->board.range; s->insn_write = vmk80xx_ao_winsn; - if (dev->board.model == VMK8061_MODEL) { s->subdev_flags |= SDF_READABLE; s->insn_read = vmk80xx_ao_rinsn; } - /* Digital input subdevice */ s = cdev->subdevices + VMK80XX_SUBD_DI; s->type = COMEDI_SUBD_DI; @@ -1198,7 +1174,6 @@ static int vmk80xx_attach(struct comedi_device *cdev, s->maxdata = 1; s->insn_read = vmk80xx_di_rinsn; s->insn_bits = vmk80xx_di_bits; - /* Digital output subdevice */ s = cdev->subdevices + VMK80XX_SUBD_DO; s->type = COMEDI_SUBD_DO; @@ -1207,12 +1182,10 @@ static int vmk80xx_attach(struct comedi_device *cdev, s->maxdata = 1; s->insn_write = vmk80xx_do_winsn; s->insn_bits = vmk80xx_do_bits; - if (dev->board.model == VMK8061_MODEL) { s->subdev_flags |= SDF_READABLE; s->insn_read = vmk80xx_do_rinsn; } - /* Counter subdevice */ s = cdev->subdevices + VMK80XX_SUBD_CNT; s->type = COMEDI_SUBD_COUNTER; @@ -1220,13 +1193,11 @@ static int vmk80xx_attach(struct comedi_device *cdev, s->n_chan = dev->board.cnt_chans; s->insn_read = vmk80xx_cnt_rinsn; s->insn_config = vmk80xx_cnt_cinsn; - if (dev->board.model == VMK8055_MODEL) { s->subdev_flags |= SDF_WRITEABLE; s->maxdata = (1 << dev->board.cnt_bits) - 1; s->insn_write = vmk80xx_cnt_winsn; } - /* PWM subdevice */ if (dev->board.model == VMK8061_MODEL) { s = cdev->subdevices + VMK80XX_SUBD_PWM; @@ -1237,19 +1208,51 @@ static int vmk80xx_attach(struct comedi_device *cdev, s->insn_read = vmk80xx_pwm_rinsn; s->insn_write = vmk80xx_pwm_winsn; } - dev->attached = 1; + dev_info(cdev->class_dev, "vmk80xx: board #%d [%s] attached\n", + dev->count, dev->board.name); + up(&dev->limit_sem); + return 0; +} - minor = cdev->minor; - - printk(KERN_INFO - "comedi%d: vmk80xx: board #%d [%s] attached to comedi\n", - minor, dev->count, dev->board.name); +/* called for COMEDI_DEVCONFIG ioctl for board_name "vmk80xx" */ +static int vmk80xx_attach(struct comedi_device *cdev, + struct comedi_devconfig *it) +{ + int i; + int ret; - up(&dev->limit_sem); + mutex_lock(&glb_mutex); + for (i = 0; i < VMK80XX_MAX_BOARDS; i++) + if (vmb[i].probed && !vmb[i].attached) + break; + if (i == VMK80XX_MAX_BOARDS) + ret = -ENODEV; + else + ret = vmk80xx_attach_common(cdev, &vmb[i]); mutex_unlock(&glb_mutex); + return ret; +} - return 0; +/* called via comedi_usb_auto_config() */ +static int vmk80xx_attach_usb(struct comedi_device *cdev, + struct usb_interface *intf) +{ + int i; + int ret; + + mutex_lock(&glb_mutex); + for (i = 0; i < VMK80XX_MAX_BOARDS; i++) + if (vmb[i].probed && vmb[i].intf == intf) + break; + if (i == VMK80XX_MAX_BOARDS) + ret = -ENODEV; + else if (vmb[i].attached) + ret = -EBUSY; + else + ret = vmk80xx_attach_common(cdev, &vmb[i]); + mutex_unlock(&glb_mutex); + return ret; } static void vmk80xx_detach(struct comedi_device *dev) @@ -1457,7 +1460,8 @@ static struct comedi_driver driver_vmk80xx = { .module = THIS_MODULE, .driver_name = "vmk80xx", .attach = vmk80xx_attach, - .detach = vmk80xx_detach + .detach = vmk80xx_detach, + .attach_usb = vmk80xx_attach_usb, }; static int __init vmk80xx_init(void) -- GitLab From 60ff46106744220506841c45f82576b9b56cf22e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 18 Jun 2012 16:35:54 +0100 Subject: [PATCH 1957/6849] staging: comedi: usbduxsigma: use attach_usb() hook Change the usbduxsigma driver to use the new attach_usb() hook in struct comedi_driver to auto-configure probed USB devices after the firmware is loaded. Move the release of the driver's static 'start_stop_sem' semaphore in usbduxsigma_attach() to occur a bit later for convenience, otherwise the new usbduxsigma_attach_common() would need to be split in two. I don't think the slight delay in releasing the semaphore matters too much; it's only used in the USB probe and disconnect functions and when attaching and detaching comedi devices. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 161 +++++++++++-------- 1 file changed, 90 insertions(+), 71 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 502a40948ebd..699deb16fa38 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2634,72 +2634,35 @@ static void usbduxsigma_disconnect(struct usb_interface *intf) dev_info(&intf->dev, "comedi_: disconnected from the usb\n"); } -/* is called when comedi-config is called */ -static int usbduxsigma_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +/* common part of attach and attach_usb */ +static int usbduxsigma_attach_common(struct comedi_device *dev, + struct usbduxsub *uds, + void *aux_data, int aux_len) { int ret; - int index; - int i; - struct usbduxsub *udev; + struct comedi_subdevice *s; int n_subdevs; - int offset; - struct comedi_subdevice *s = NULL; - dev->private = NULL; - - down(&start_stop_sem); - /* find a valid device which has been detected by the probe function of - * the usb */ - index = -1; - for (i = 0; i < NUMUSBDUX; i++) { - if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { - index = i; - break; - } - } - - if (index < 0) { - printk(KERN_ERR "comedi%d: usbduxsigma: error: attach failed," - "dev not connected to the usb bus.\n", dev->minor); - up(&start_stop_sem); - return -ENODEV; - } - - udev = &usbduxsub[index]; - down(&udev->sem); + down(&uds->sem); /* pointer back to the corresponding comedi device */ - udev->comedidev = dev; - + uds->comedidev = dev; /* trying to upload the firmware into the FX2 */ - if (comedi_aux_data(it->options, 0) && - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { - firmwareUpload(udev, comedi_aux_data(it->options, 0), - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); - } - + if (aux_data) + firmwareUpload(uds, aux_data, aux_len); dev->board_name = BOARDNAME; - /* set number of subdevices */ - if (udev->high_speed) { - /* with pwm */ - n_subdevs = 4; - } else { - /* without pwm */ - n_subdevs = 3; - } - + if (uds->high_speed) + n_subdevs = 4; /* with pwm */ + else + n_subdevs = 3; /* without pwm */ ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret) { - up(&udev->sem); - up(&start_stop_sem); + up(&uds->sem); return ret; } - /* private structure is also simply the usb-structure */ - dev->private = udev; - + dev->private = uds; /* the first subdevice is the A/D converter */ s = dev->subdevices + SUBDEV_AD; /* the URBs get the comedi subdevice */ @@ -2727,8 +2690,7 @@ static int usbduxsigma_attach(struct comedi_device *dev, s->maxdata = 0x00FFFFFF; /* range table to convert to physical units */ s->range_table = (&range_usbdux_ai_range); - - /* analog out */ + /* analog output subdevice */ s = dev->subdevices + SUBDEV_DA; /* analog out */ s->type = COMEDI_SUBD_AO; @@ -2753,8 +2715,7 @@ static int usbduxsigma_attach(struct comedi_device *dev, s->cancel = usbdux_ao_cancel; s->insn_read = usbdux_ao_insn_read; s->insn_write = usbdux_ao_insn_write; - - /* digital I/O */ + /* digital I/O subdevice */ s = dev->subdevices + SUBDEV_DIO; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -2766,37 +2727,94 @@ static int usbduxsigma_attach(struct comedi_device *dev, s->insn_config = usbdux_dio_insn_config; /* we don't use it */ s->private = NULL; - - if (udev->high_speed) { - /* timer / pwm */ + if (uds->high_speed) { + /* timer / pwm subdevice */ s = dev->subdevices + SUBDEV_PWM; s->type = COMEDI_SUBD_PWM; s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; s->n_chan = 8; /* this defines the max duty cycle resolution */ - s->maxdata = udev->sizePwmBuf; + s->maxdata = uds->sizePwmBuf; s->insn_write = usbdux_pwm_write; s->insn_read = usbdux_pwm_read; s->insn_config = usbdux_pwm_config; usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); } /* finally decide that it's attached */ - udev->attached = 1; + uds->attached = 1; + up(&uds->sem); + offset = usbdux_getstatusinfo(dev, 0); + if (offset < 0) + dev_err(&uds->interface->dev, + "Communication to USBDUXSIGMA failed! Check firmware and cabling."); + dev_info(&uds->interface->dev, + "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset); + return 0; +} - up(&udev->sem); +/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ +static int usbduxsigma_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int ret; + int index; + int i; + void *aux_data; + int aux_len; - up(&start_stop_sem); + dev->private = NULL; - offset = usbdux_getstatusinfo(dev, 0); - if (offset < 0) - dev_err(&udev->interface->dev, - "Communication to USBDUXSIGMA failed!" - "Check firmware and cabling."); + aux_data = comedi_aux_data(it->options, 0); + aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; + if (aux_data == NULL) + aux_len = 0; + else if (aux_len == 0) + aux_data = NULL; - dev_info(&udev->interface->dev, - "comedi%d: attached, ADC_zero = %x", dev->minor, offset); + down(&start_stop_sem); + /* find a valid device which has been detected by the probe function of + * the usb */ + index = -1; + for (i = 0; i < NUMUSBDUX; i++) { + if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { + index = i; + break; + } + } + if (index < 0) { + dev_err(dev->class_dev, + "usbduxsigma: error: attach failed, dev not connected to the usb bus.\n"); + up(&start_stop_sem); + ret = -ENODEV; + } else + ret = usbduxsigma_attach_common(dev, &usbduxsub[index], + aux_data, aux_len); + up(&start_stop_sem); + return ret; +} - return 0; +/* is called from comedi_usb_auto_config() */ +static int usbduxsigma_attach_usb(struct comedi_device *dev, + struct usb_interface *uinterf) +{ + int ret; + struct usbduxsub *uds; + + dev->private = NULL; + down(&start_stop_sem); + uds = usb_get_intfdata(uinterf); + if (!uds || !uds->probed) { + dev_err(dev->class_dev, + "usbduxsigma: error: attach_usb failed, not connected\n"); + ret = -ENODEV; + } else if (uds->attached) { + dev_err(dev->class_dev, + "usbduxsigma: error: attach_usb failed, already attached\n"); + ret = -ENODEV; + } else + ret = usbduxsigma_attach_common(dev, uds, NULL, 0); + up(&start_stop_sem); + return ret; } static void usbduxsigma_detach(struct comedi_device *dev) @@ -2818,6 +2836,7 @@ static struct comedi_driver driver_usbduxsigma = { .module = THIS_MODULE, .attach = usbduxsigma_attach, .detach = usbduxsigma_detach, + .attach_usb = usbduxsigma_attach_usb, }; /* Table with the USB-devices */ -- GitLab From 520706607befd1f5c20ec14db35d6be45791bc41 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 18 Jun 2012 11:18:25 -0700 Subject: [PATCH 1958/6849] staging: comedi: remove unneeded sanity check in insn_bits functions The comedi core does the sanity check to make sure that the data length the INSN_BITS instruction is 2. There is no need for the drivers to do this check. Remove all the sanity checks in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 3 --- drivers/staging/comedi/drivers/acl7225b.c | 6 ------ drivers/staging/comedi/drivers/adl_pci6208.c | 2 -- drivers/staging/comedi/drivers/adl_pci7230.c | 6 ------ drivers/staging/comedi/drivers/adl_pci7432.c | 6 ------ drivers/staging/comedi/drivers/aio_iiro_16.c | 6 ------ drivers/staging/comedi/drivers/amplc_pc263.c | 3 --- drivers/staging/comedi/drivers/cb_das16_cs.c | 3 --- drivers/staging/comedi/drivers/comedi_bond.c | 2 -- drivers/staging/comedi/drivers/comedi_parport.c | 3 --- drivers/staging/comedi/drivers/contec_pci_dio.c | 6 ------ drivers/staging/comedi/drivers/dmm32at.c | 3 --- drivers/staging/comedi/drivers/dt2801.c | 2 -- drivers/staging/comedi/drivers/dt2811.c | 6 ------ drivers/staging/comedi/drivers/dt3000.c | 3 --- drivers/staging/comedi/drivers/dyna_pci10xx.c | 6 ------ drivers/staging/comedi/drivers/me4000.c | 11 ----------- drivers/staging/comedi/drivers/multiq3.c | 6 ------ drivers/staging/comedi/drivers/ni_6527.c | 8 -------- drivers/staging/comedi/drivers/ni_65xx.c | 6 +----- drivers/staging/comedi/drivers/ni_670x.c | 3 --- drivers/staging/comedi/drivers/ni_at_ao.c | 3 --- drivers/staging/comedi/drivers/ni_atmio16d.c | 3 --- drivers/staging/comedi/drivers/ni_mio_common.c | 9 ++------- drivers/staging/comedi/drivers/ni_pcidio.c | 2 -- drivers/staging/comedi/drivers/pcl711.c | 6 ------ drivers/staging/comedi/drivers/pcl725.c | 6 ------ drivers/staging/comedi/drivers/pcl726.c | 6 ------ drivers/staging/comedi/drivers/pcl730.c | 6 ------ drivers/staging/comedi/drivers/pcl812.c | 6 ------ drivers/staging/comedi/drivers/pcl818.c | 6 ------ drivers/staging/comedi/drivers/pcm3730.c | 4 ---- drivers/staging/comedi/drivers/pcmmio.c | 2 -- drivers/staging/comedi/drivers/pcmuio.c | 2 -- drivers/staging/comedi/drivers/poc.c | 5 ----- drivers/staging/comedi/drivers/rtd520.c | 3 --- drivers/staging/comedi/drivers/rti800.c | 5 ----- drivers/staging/comedi/drivers/s526.c | 3 --- drivers/staging/comedi/drivers/s626.c | 12 ------------ drivers/staging/comedi/drivers/skel.c | 3 --- drivers/staging/comedi/drivers/ssv_dnp.c | 4 ---- drivers/staging/comedi/drivers/usbdux.c | 3 --- drivers/staging/comedi/drivers/usbduxsigma.c | 3 --- 43 files changed, 3 insertions(+), 199 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index e0de149c3c29..4c9977b8a5ae 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -139,9 +139,6 @@ static int subdev_8255_insn(struct comedi_device *dev, unsigned int bits; unsigned int v; - if (insn->n != 2) - return -EINVAL; - mask = data[0]; bits = data[1]; diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index 0bf552581c5f..ab765d3233e2 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -31,9 +31,6 @@ static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -53,9 +50,6 @@ static int acl7225b_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + (unsigned long)s->private) | (inb(dev->iobase + (unsigned long)s->private + 1) << 8); diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 98b373063445..f0a5958d77b6 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -141,8 +141,6 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data) */ /* { */ -/* if(insn->n!=2)return -EINVAL; */ - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ /* if(data[0]){ */ diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index 62fdf7f63703..d75734a03fb4 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -54,9 +54,6 @@ static int adl_pci7230_do_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -72,9 +69,6 @@ static int adl_pci7230_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; return 2; diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index aabf4183aaf5..b071a08b6159 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -57,9 +57,6 @@ static int adl_pci7432_do_insn_bits(struct comedi_device *dev, printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -79,9 +76,6 @@ static int adl_pci7432_di_insn_bits(struct comedi_device *dev, printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - if (insn->n != 2) - return -EINVAL; - data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 8059cefe5b8c..34341078f654 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -70,9 +70,6 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; @@ -91,9 +88,6 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = 0; data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 4f15bfd80719..a018d8176aef 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -185,9 +185,6 @@ static int pc263_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ if (data[0]) { diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 77dc880ca786..515dda033e9a 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -549,9 +549,6 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 0260ddc05645..5ed324c4f620 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -133,8 +133,6 @@ static int bonding_dio_insn_bits(struct comedi_device *dev, { #define LSAMPL_BITS (sizeof(unsigned int)*8) unsigned nchans = LSAMPL_BITS, num_done = 0, i; - if (insn->n != 2) - return -EINVAL; if (devpriv->nchans < nchans) nchans = devpriv->nchans; diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 589d12f68067..10c3c353f967 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -162,9 +162,6 @@ static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n < 1) - return -EINVAL; - data[1] = 0; return 2; } diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index d49561ff35ba..6aec9a6451b6 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -74,9 +74,6 @@ static int contec_do_insn_bits(struct comedi_device *dev, dev_dbg(dev->class_dev, "contec_do_insn_bits called\n"); dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; @@ -95,9 +92,6 @@ static int contec_di_insn_bits(struct comedi_device *dev, dev_dbg(dev->class_dev, "contec_di_insn_bits called\n"); dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); - if (insn->n != 2) - return -EINVAL; - data[1] = inw(dev->iobase + thisboard->in_offs); return 2; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 2b60cf816b6e..7cc9d20f3482 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -914,9 +914,6 @@ static int dmm32at_dio_insn_bits(struct comedi_device *dev, { unsigned char diobits; - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ if (data[0]) { diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 5afbf8a4b030..d0bbbbb8816a 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -535,8 +535,6 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, if (s == dev->subdevices + 4) which = 1; - if (insn->n != 2) - return -EINVAL; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 91fbf4a7a2af..b239f381ad50 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -352,9 +352,6 @@ static int dt2811_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + DT2811_DIO); return 2; @@ -364,9 +361,6 @@ static int dt2811_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - s->state &= ~data[0]; s->state |= data[0] & data[1]; outb(s->state, dev->iobase + DT2811_DIO); diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 31a16edc0a27..6acfe05ac569 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -745,9 +745,6 @@ static int dt3k_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[1] & data[0]; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 9c855e25275c..78f3c8b4a0dc 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -189,9 +189,6 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, { u16 d = 0; - if (insn->n != 2) - return -EINVAL; - mutex_lock(&devpriv->mutex); smp_mb(); d = inw_p(devpriv->BADR3); @@ -209,9 +206,6 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. * s->state contains the previous write data diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 72466bfa3b1d..631b4229201a 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1643,17 +1643,6 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - /* Length of data must be 2 (mask and new data, see below) */ - if (insn->n == 0) - return 0; - - if (insn->n != 2) { - printk - ("comedi%d: me4000: me4000_dio_insn_bits(): " - "Invalid instruction length\n", dev->minor); - return -EINVAL; - } - /* * The insn data consists of a mask in data[0] and the new data * in data[1]. The mask defines which bits we are concerning about. diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index b1bbd0255fbc..d1a8e9129b0f 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -161,9 +161,6 @@ static int multiq3_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inw(dev->iobase + MULTIQ3_DIGIN_PORT); return 2; @@ -173,9 +170,6 @@ static int multiq3_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - s->state &= ~data[0]; s->state |= (data[0] & data[1]); outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index b60ab4848b64..eec44a05af65 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -174,9 +174,6 @@ static int ni6527_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0)); data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8; data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16; @@ -188,8 +185,6 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -339,9 +334,6 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n < 1) - return -EINVAL; - data[1] = 0; return 2; } diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index ac7c74be08a2..f92f8ab30687 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -415,8 +415,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, const unsigned max_ports_per_bitfield = 5; unsigned read_bits = 0; unsigned j; - if (insn->n != 2) - return -EINVAL; + base_bitfield_channel = CR_CHAN(insn->chanspec); for (j = 0; j < max_ports_per_bitfield; ++j) { const unsigned port_offset = @@ -602,9 +601,6 @@ static int ni_65xx_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n < 1) - return -EINVAL; - data[1] = 0; return 2; } diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 5dffe6ce4738..b62b4271191e 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -306,9 +306,6 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ if (data[0]) { diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 1c3f3222d496..28848bcc9375 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -239,9 +239,6 @@ static int atao_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 87992c99d413..54c039437b04 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -599,9 +599,6 @@ static int atmio16d_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] | data[1]); diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 1f796b9361b2..42df64ec921a 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -3567,8 +3567,7 @@ static int ni_dio_insn_bits(struct comedi_device *dev, #ifdef DEBUG_DIO printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]); #endif - if (insn->n != 2) - return -EINVAL; + if (data[0]) { /* Perform check to make sure we're not using the serial part of the dio */ @@ -3629,8 +3628,7 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev, printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]); #endif - if (insn->n != 2) - return -EINVAL; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -5485,9 +5483,6 @@ static int ni_rtsi_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = 0; return 2; diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index cba045965167..133ab2fd0377 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -745,8 +745,6 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index d5fa6f28eb1f..0df086a1a18d 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -449,9 +449,6 @@ static int pcl711_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + PCL711_DI_LO) | (inb(dev->iobase + PCL711_DI_HI) << 8); @@ -463,9 +460,6 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 8edbefd7c43b..433ea05c3e91 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -23,9 +23,6 @@ Devices: [Advantech] PCL-725 (pcl725) static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -40,9 +37,6 @@ static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + PCL725_DI); return 2; diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index b2e73cda2957..dfff9af1951b 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -197,9 +197,6 @@ static int pcl726_di_insn_bits(struct comedi_device *dev, { const struct pcl726_board *board = comedi_board(dev); - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + board->di_lo) | (inb(dev->iobase + board->di_hi) << 8); @@ -212,9 +209,6 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, { const struct pcl726_board *board = comedi_board(dev); - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index 3cba79a219b8..d40caca42862 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -35,9 +35,6 @@ struct pcl730_board { static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -57,9 +54,6 @@ static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcl730_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + ((unsigned long)s->private)) | (inb(dev->iobase + ((unsigned long)s->private) + 1) << 8); diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index b0eb2ab89fd8..1c146c879be9 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -501,9 +501,6 @@ static int pcl812_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + PCL812_DI_LO); data[1] |= inb(dev->iobase + PCL812_DI_HI) << 8; @@ -517,9 +514,6 @@ static int pcl812_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 23b61d8aa404..13eaadfbaaab 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -442,9 +442,6 @@ static int pcl818_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + PCL818_DI_LO) | (inb(dev->iobase + PCL818_DI_HI) << 8); @@ -461,9 +458,6 @@ static int pcl818_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - s->state &= ~data[0]; s->state |= (data[0] & data[1]); diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index b48f7aa7520b..311fe2dc5386 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -32,8 +32,6 @@ static int pcm3730_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -48,8 +46,6 @@ static int pcm3730_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; data[1] = inb(dev->iobase + (unsigned long)(s->private)); return 2; } diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 0e64d848a2a8..a918cc087708 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -275,8 +275,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { int byte_no; - if (insn->n != 2) - return -EINVAL; /* NOTE: reading a 0 means this channel was high diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 4426e1798ed5..33f740ee3524 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -211,8 +211,6 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { int byte_no; - if (insn->n != 2) - return -EINVAL; /* NOTE: reading a 0 means this channel was high diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index a129ccace93d..a655b906164a 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -99,9 +99,6 @@ static int pcl733_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - data[1] = inb(dev->iobase + 0); data[1] |= (inb(dev->iobase + 1) << 8); data[1] |= (inb(dev->iobase + 2) << 16); @@ -114,8 +111,6 @@ static int pcl734_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index c3c8097acd02..6ff1fa0fd5de 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1811,9 +1811,6 @@ static int rtd_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ if (data[0]) { diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 966ac2ccc877..b6f219922a01 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -263,8 +263,6 @@ static int rti800_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; data[1] = inb(dev->iobase + RTI800_DI); return 2; } @@ -273,9 +271,6 @@ static int rti800_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - if (data[0]) { s->state &= ~data[0]; s->state |= data[0] & data[1]; diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 141bc9e881c9..b1dd22423704 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -678,9 +678,6 @@ static int s526_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ if (data[0]) { diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 32e03bc247b3..182074c5f78b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2140,18 +2140,6 @@ static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - - /* Length of data must be 2 (mask and new data, see below) */ - if (insn->n == 0) - return 0; - - if (insn->n != 2) { - printk - ("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n", - dev->minor); - return -EINVAL; - } - /* * The insn data consists of a mask in data[0] and the new data in * data[1]. The mask defines which bits we are concerning about. diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 92d44c1d2587..67207de33906 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -561,9 +561,6 @@ static int skel_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - if (insn->n != 2) - return -EINVAL; - /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ if (data[0]) { diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index b12bafe9baf6..f7bf3a2b9f31 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -77,10 +77,6 @@ static int dnp_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - - if (insn->n != 2) - return -EINVAL; /* insn uses data[0] and data[1] */ - /* The insn data is a mask in data[0] and the new data in data[1], */ /* each channel cooresponding to a bit. */ diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 0386fd4a80ba..3185e1cdfb29 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1780,9 +1780,6 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, if (!this_usbduxsub) return -EFAULT; - if (insn->n != 2) - return -EINVAL; - down(&this_usbduxsub->sem); if (!(this_usbduxsub->probed)) { diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 699deb16fa38..a93cc5df2093 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1845,9 +1845,6 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, if (!this_usbduxsub) return -EFAULT; - if (insn->n != 2) - return -EINVAL; - down(&this_usbduxsub->sem); if (!(this_usbduxsub->probed)) { -- GitLab From a2714e3e42e746d6c8525c35fdcc58fb60c2830d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 18 Jun 2012 13:16:35 -0700 Subject: [PATCH 1959/6849] staging: comedi: fix return value for insn_bits functions The comedi_subdevice 'insn_bits' functions return the number of data elements used to perform the command. Most of the insn_bits functions return an open coded '2' to indicate this. The same value is available as 'insn->n'. Return that instead to better indicate what the return means. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/acl7225b.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci6208.c | 2 +- drivers/staging/comedi/drivers/adl_pci7230.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci7432.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci9111.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci9118.c | 4 ++-- drivers/staging/comedi/drivers/adq12b.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci1710.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 12 ++++++------ drivers/staging/comedi/drivers/aio_iiro_16.c | 4 ++-- drivers/staging/comedi/drivers/amplc_dio200.c | 2 +- drivers/staging/comedi/drivers/amplc_pc236.c | 2 +- drivers/staging/comedi/drivers/amplc_pc263.c | 2 +- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 6 +++--- drivers/staging/comedi/drivers/comedi_parport.c | 8 ++++---- drivers/staging/comedi/drivers/contec_pci_dio.c | 4 ++-- drivers/staging/comedi/drivers/das08.c | 8 ++++---- drivers/staging/comedi/drivers/das16.c | 4 ++-- drivers/staging/comedi/drivers/das16m1.c | 4 ++-- drivers/staging/comedi/drivers/das1800.c | 4 ++-- drivers/staging/comedi/drivers/das800.c | 4 ++-- drivers/staging/comedi/drivers/dmm32at.c | 2 +- drivers/staging/comedi/drivers/dt2801.c | 2 +- drivers/staging/comedi/drivers/dt2811.c | 4 ++-- drivers/staging/comedi/drivers/dt2817.c | 2 +- drivers/staging/comedi/drivers/dt282x.c | 2 +- drivers/staging/comedi/drivers/dt3000.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 4 ++-- drivers/staging/comedi/drivers/icp_multi.c | 4 ++-- drivers/staging/comedi/drivers/ii_pci20kc.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 2 +- drivers/staging/comedi/drivers/mpc8260cpm.c | 2 +- drivers/staging/comedi/drivers/multiq3.c | 4 ++-- drivers/staging/comedi/drivers/ni_6527.c | 6 +++--- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 2 +- drivers/staging/comedi/drivers/ni_670x.c | 2 +- drivers/staging/comedi/drivers/ni_at_ao.c | 2 +- drivers/staging/comedi/drivers/ni_atmio16d.c | 2 +- drivers/staging/comedi/drivers/ni_daq_700.c | 2 +- drivers/staging/comedi/drivers/ni_mio_common.c | 8 ++++---- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/pcl711.c | 4 ++-- drivers/staging/comedi/drivers/pcl725.c | 4 ++-- drivers/staging/comedi/drivers/pcl726.c | 4 ++-- drivers/staging/comedi/drivers/pcl730.c | 4 ++-- drivers/staging/comedi/drivers/pcl812.c | 4 ++-- drivers/staging/comedi/drivers/pcl818.c | 4 ++-- drivers/staging/comedi/drivers/pcm3730.c | 4 ++-- drivers/staging/comedi/drivers/pcmmio.c | 2 +- drivers/staging/comedi/drivers/pcmuio.c | 2 +- drivers/staging/comedi/drivers/poc.c | 4 ++-- drivers/staging/comedi/drivers/rtd520.c | 2 +- drivers/staging/comedi/drivers/rti800.c | 4 ++-- drivers/staging/comedi/drivers/s526.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- drivers/staging/comedi/drivers/skel.c | 2 +- drivers/staging/comedi/drivers/ssv_dnp.c | 2 +- drivers/staging/comedi/drivers/usbdux.c | 2 +- drivers/staging/comedi/drivers/usbduxsigma.c | 2 +- 63 files changed, 107 insertions(+), 107 deletions(-) diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index ab765d3233e2..ddba5db1e2e1 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -43,7 +43,7 @@ static int acl7225b_do_insn(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } static int acl7225b_di_insn(struct comedi_device *dev, @@ -53,7 +53,7 @@ static int acl7225b_di_insn(struct comedi_device *dev, data[1] = inb(dev->iobase + (unsigned long)s->private) | (inb(dev->iobase + (unsigned long)s->private + 1) << 8); - return 2; + return insn->n; } static int acl7225b_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index f0a5958d77b6..79f6765c46c1 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -157,7 +157,7 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, * it was a purely digital output subdevice */ /* data[1]=s->state; */ -/* return 2; */ +/* return insn->n; */ /* } */ /* static int pci6208_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index d75734a03fb4..cfb8bb055a02 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -61,7 +61,7 @@ static int adl_pci7230_do_insn_bits(struct comedi_device *dev, outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); } - return 2; + return insn->n; } static int adl_pci7230_di_insn_bits(struct comedi_device *dev, @@ -71,7 +71,7 @@ static int adl_pci7230_di_insn_bits(struct comedi_device *dev, { data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; - return 2; + return insn->n; } static struct pci_dev *adl_pci7230_find_pci(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index b071a08b6159..10683c29276c 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -65,7 +65,7 @@ static int adl_pci7432_do_insn_bits(struct comedi_device *dev, dev->iobase + PCI7432_DO); outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); } - return 2; + return insn->n; } static int adl_pci7432_di_insn_bits(struct comedi_device *dev, @@ -79,7 +79,7 @@ static int adl_pci7432_di_insn_bits(struct comedi_device *dev, data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); - return 2; + return insn->n; } static struct pci_dev *adl_pci7432_find_pci(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 4f2cea8e11f7..c41cfc5c97ff 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1153,7 +1153,7 @@ static int pci9111_di_insn_bits(struct comedi_device *dev, bits = pci9111_di_get_bits(); data[1] = bits; - return 2; + return insn->n; } /* Digital outputs */ @@ -1179,7 +1179,7 @@ static int pci9111_do_insn_bits(struct comedi_device *dev, data[1] = bits; - return 2; + return insn->n; } /* ------------------------------------------------------------------ */ diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 9a7b6a5797bb..4482aabb3dcc 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -492,7 +492,7 @@ static int pci9118_insn_bits_di(struct comedi_device *dev, { data[1] = inl(dev->iobase + PCI9118_DI) & 0xf; - return 2; + return insn->n; } /* @@ -509,7 +509,7 @@ static int pci9118_insn_bits_do(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index f7bb14589c9b..6df51c8a602a 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -193,7 +193,7 @@ static int adq12b_di_insn_bits(struct comedi_device *dev, /* only bits 0-4 have information about digital inputs */ data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f)); - return 2; + return insn->n; } static int adq12b_do_insn_bits(struct comedi_device *dev, @@ -215,7 +215,7 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, data[1] = devpriv->digital_state; - return 2; + return insn->n; } static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 94d69e421c29..0ed1ff9217d5 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -435,7 +435,7 @@ static int pci171x_insn_bits_di(struct comedi_device *dev, { data[1] = inw(dev->iobase + PCI171x_DI); - return 2; + return insn->n; } /* @@ -452,7 +452,7 @@ static int pci171x_insn_bits_do(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index d37c14da5ec6..5c99c746d228 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -284,7 +284,7 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD); } data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); - return 2; + return insn->n; } static int pci1723_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 176a8016432d..ad653a5b8e2c 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -424,7 +424,7 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, data[1] |= inb(dev->iobase + d->addr + i) << (8 * i); - return 2; + return insn->n; } /* @@ -441,7 +441,7 @@ static int pci_dio_insn_bits_di_w(struct comedi_device *dev, for (i = 0; i < d->regs; i++) data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i); - return 2; + return insn->n; } /* @@ -463,7 +463,7 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } /* @@ -485,7 +485,7 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } /* @@ -634,7 +634,7 @@ static int pci1760_insn_bits_di(struct comedi_device *dev, { data[1] = inb(dev->iobase + IMB3); - return 2; + return insn->n; } /* @@ -663,7 +663,7 @@ static int pci1760_insn_bits_do(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 34341078f654..16f28f65d292 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -80,7 +80,7 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, @@ -92,7 +92,7 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; - return 2; + return insn->n; } static int aio_iiro_16_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index c67b09ff37d7..55f30507e9e8 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -551,7 +551,7 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, data[0] = 0; } - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index e55321ec5ae8..77dae8e956ca 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -293,7 +293,7 @@ static int pc236_intr_insn(struct comedi_device *dev, unsigned int *data) { data[1] = 0; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index a018d8176aef..e90178d29611 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -194,7 +194,7 @@ static int pc263_do_insn_bits(struct comedi_device *dev, outb(s->state & 0xFF, dev->iobase); outb(s->state >> 8, dev->iobase + 1); } - return 2; + return insn->n; } static void pc263_report_attach(struct comedi_device *dev) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 515dda033e9a..6866e25543d1 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -560,7 +560,7 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, * input and output lines. */ data[1] = inw(dev->iobase + 16); - return 2; + return insn->n; } static int das16cs_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 7aacff3292c2..11ce3fdff195 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3617,7 +3617,7 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = bits; data[0] = 0; - return 2; + return insn->n; } static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -3633,7 +3633,7 @@ static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = s->state; - return 2; + return insn->n; } static int dio_60xx_config_insn(struct comedi_device *dev, @@ -3676,7 +3676,7 @@ static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG); - return 2; + return insn->n; } static void caldac_write(struct comedi_device *dev, unsigned int channel, diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 10c3c353f967..9a63cac2434a 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -110,7 +110,7 @@ static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = inb(dev->iobase + PARPORT_A); - return 2; + return insn->n; } static int parport_insn_config_a(struct comedi_device *dev, @@ -139,7 +139,7 @@ static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = (inb(dev->iobase + PARPORT_B) >> 3); - return 2; + return insn->n; } static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s, @@ -155,7 +155,7 @@ static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = devpriv->c_data & 0xf; - return 2; + return insn->n; } static int parport_intr_insn(struct comedi_device *dev, @@ -163,7 +163,7 @@ static int parport_intr_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { data[1] = 0; - return 2; + return insn->n; } static int parport_intr_cmdtest(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 6aec9a6451b6..ee769e00dc20 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -81,7 +81,7 @@ static int contec_do_insn_bits(struct comedi_device *dev, dev->iobase + thisboard->out_offs); outw(s->state, dev->iobase + thisboard->out_offs); } - return 2; + return insn->n; } static int contec_di_insn_bits(struct comedi_device *dev, @@ -94,7 +94,7 @@ static int contec_di_insn_bits(struct comedi_device *dev, data[1] = inw(dev->iobase + thisboard->in_offs); - return 2; + return insn->n; } static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index c4627a6b62be..d0128e0e15cc 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -313,7 +313,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, data[0] = 0; data[1] = DAS08_IP(inb(dev->iobase + DAS08_STATUS)); - return 2; + return insn->n; } static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -338,7 +338,7 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = wbits; - return 2; + return insn->n; } static int __maybe_unused @@ -348,7 +348,7 @@ das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, data[0] = 0; data[1] = inb(dev->iobase + DAS08JR_DIO); - return 2; + return insn->n; } static int __maybe_unused @@ -365,7 +365,7 @@ das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = devpriv->do_bits; - return 2; + return insn->n; } static int __maybe_unused diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 0c6ad1067055..895cc7783c9c 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -812,7 +812,7 @@ static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = bits; data[0] = 0; - return 2; + return insn->n; } static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -832,7 +832,7 @@ static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, outb(s->state, dev->iobase + DAS16_DIO); - return 2; + return insn->n; } static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index f3fba13432bb..200926347861 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -428,7 +428,7 @@ static int das16m1_di_rbits(struct comedi_device *dev, data[1] = bits; data[0] = 0; - return 2; + return insn->n; } static int das16m1_do_wbits(struct comedi_device *dev, @@ -449,7 +449,7 @@ static int das16m1_do_wbits(struct comedi_device *dev, outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO); - return 2; + return insn->n; } static void das16m1_handler(struct comedi_device *dev, unsigned int status) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 365028772b00..25e7e56a376f 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1353,7 +1353,7 @@ static int das1800_di_rbits(struct comedi_device *dev, data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; data[0] = 0; - return 2; + return insn->n; } /* writes to digital output channels */ @@ -1374,7 +1374,7 @@ static int das1800_do_wbits(struct comedi_device *dev, data[1] = devpriv->do_bits; - return 2; + return insn->n; } static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 917b31812b6c..a0959a5e8747 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -875,7 +875,7 @@ static int das800_di_rbits(struct comedi_device *dev, data[1] = bits; data[0] = 0; - return 2; + return insn->n; } static int das800_do_wbits(struct comedi_device *dev, @@ -899,7 +899,7 @@ static int das800_do_wbits(struct comedi_device *dev, data[1] = wbits; - return 2; + return insn->n; } /* loads counters with divisor1, divisor2 from private structure */ diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 7cc9d20f3482..af3531676e81 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -956,7 +956,7 @@ static int dmm32at_dio_insn_bits(struct comedi_device *dev, * it was a purely digital output subdevice */ /* data[1]=s->state; */ - return 2; + return insn->n; } static int dmm32at_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index d0bbbbb8816a..d332269375ab 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -546,7 +546,7 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, dt2801_writedata(dev, which); dt2801_readdata(dev, data + 1); - return 2; + return insn->n; } static int dt2801_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index b239f381ad50..290b933c5f96 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -354,7 +354,7 @@ static int dt2811_di_insn_bits(struct comedi_device *dev, { data[1] = inb(dev->iobase + DT2811_DIO); - return 2; + return insn->n; } static int dt2811_do_insn_bits(struct comedi_device *dev, @@ -367,7 +367,7 @@ static int dt2811_do_insn_bits(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 9282ca55f637..beba0447b3ee 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -119,7 +119,7 @@ static int dt2817_dio_insn_bits(struct comedi_device *dev, data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16); data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24); - return 2; + return insn->n; } static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 9c0a0df7dff2..4af33431c380 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1038,7 +1038,7 @@ static int dt282x_dio_insn_bits(struct comedi_device *dev, } data[1] = inw(dev->iobase + DT2821_DIODAT); - return 2; + return insn->n; } static int dt282x_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 6acfe05ac569..d1d99a3e7491 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -752,7 +752,7 @@ static int dt3k_dio_insn_bits(struct comedi_device *dev, } data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0); - return 2; + return insn->n; } static int dt3k_mem_insn_read(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 78f3c8b4a0dc..d0e3679ba2ad 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -198,7 +198,7 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, data[1] = d; data[0] = s->state; mutex_unlock(&devpriv->mutex); - return 2; + return insn->n; } /* digital output bit interface */ @@ -226,7 +226,7 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, */ data[1] = s->state; mutex_unlock(&devpriv->mutex); - return 2; + return insn->n; } /******************************************************************************/ diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 544bed870470..b10ebdbc1f7e 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -542,7 +542,7 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev, { data[1] = readw(devpriv->io_addr + ICP_MULTI_DI); - return 2; + return insn->n; } /* @@ -585,7 +585,7 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, #ifdef ICP_MULTI_EXTDEBUG printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_insn_bits_do(...)\n"); #endif - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index bea3d03bae2e..0f9cfe662b9a 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -565,7 +565,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16; data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24; - return 2; + return insn->n; } static void pci20xxx_dio_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 631b4229201a..9a8258e6fa45 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1675,7 +1675,7 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, ((inl(info->dio_context.port_2_reg) & 0xFF) << 16) | ((inl(info->dio_context.port_3_reg) & 0xFF) << 24); - return 2; + return insn->n; } static int me4000_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index ae3b0469541e..1803d66cbf7d 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -331,7 +331,7 @@ static int me_dio_insn_bits(struct comedi_device *dev, data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16; } - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c index a6311b11831b..a7fda8f01e8c 100644 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ b/drivers/staging/comedi/drivers/mpc8260cpm.c @@ -113,7 +113,7 @@ static int mpc8260cpm_dio_bits(struct comedi_device *dev, p = cpm_pdat((int)s->private); - return 2; + return insn->n; } static int mpc8260cpm_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index d1a8e9129b0f..eccbe1fb4f2c 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -163,7 +163,7 @@ static int multiq3_di_insn_bits(struct comedi_device *dev, { data[1] = inw(dev->iobase + MULTIQ3_DIGIN_PORT); - return 2; + return insn->n; } static int multiq3_do_insn_bits(struct comedi_device *dev, @@ -176,7 +176,7 @@ static int multiq3_do_insn_bits(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } static int multiq3_encoder_insn_read(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index eec44a05af65..a80c52fb2731 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -178,7 +178,7 @@ static int ni6527_di_insn_bits(struct comedi_device *dev, data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8; data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16; - return 2; + return insn->n; } static int ni6527_do_insn_bits(struct comedi_device *dev, @@ -206,7 +206,7 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } static irqreturn_t ni6527_interrupt(int irq, void *d) @@ -335,7 +335,7 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { data[1] = 0; - return 2; + return insn->n; } static int ni6527_intr_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index f92f8ab30687..bce39f1ea36d 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -602,7 +602,7 @@ static int ni_65xx_intr_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { data[1] = 0; - return 2; + return insn->n; } static int ni_65xx_intr_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5391a3949da1..5e863ff343dd 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1285,7 +1285,7 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev, data[1] = (ni_660x_read_register(dev, 0, DIO32Input) >> base_bitfield_channel); - return 2; + return insn->n; } static void ni_660x_select_pfi_output(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index b62b4271191e..9032baccf3aa 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -319,7 +319,7 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, * input lines. */ data[1] = readl(devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET); - return 2; + return insn->n; } static int ni_670x_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 28848bcc9375..62c8c44a8d28 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -247,7 +247,7 @@ static int atao_dio_insn_bits(struct comedi_device *dev, data[1] = inw(dev->iobase + ATAO_DIN); - return 2; + return insn->n; } static int atao_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 54c039437b04..2c78d3dd242a 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -606,7 +606,7 @@ static int atmio16d_dio_insn_bits(struct comedi_device *dev, } data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG); - return 2; + return insn->n; } static int atmio16d_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 53b0173aa2b2..4b42809d87a7 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -174,7 +174,7 @@ static int subdev_700_insn(struct comedi_device *dev, data[1] = s->state & 0xff; data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8; - return 2; + return insn->n; } static int subdev_700_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 42df64ec921a..cf0e0d147f8c 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -3584,7 +3584,7 @@ static int ni_dio_insn_bits(struct comedi_device *dev, } data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register); - return 2; + return insn->n; } static int ni_m_series_dio_insn_config(struct comedi_device *dev, @@ -3636,7 +3636,7 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev, } data[1] = ni_readl(M_Offset_Static_Digital_Input); - return 2; + return insn->n; } static int ni_cdio_cmdtest(struct comedi_device *dev, @@ -5394,7 +5394,7 @@ static int ni_pfi_insn_bits(struct comedi_device *dev, ni_writew(s->state, M_Offset_PFI_DO); } data[1] = ni_readw(M_Offset_PFI_DI); - return 2; + return insn->n; } static int ni_pfi_insn_config(struct comedi_device *dev, @@ -5485,7 +5485,7 @@ static int ni_rtsi_insn_bits(struct comedi_device *dev, { data[1] = 0; - return 2; + return insn->n; } /* Find best multiplier/divider to try and get the PLL running at 80 MHz diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 133ab2fd0377..0a55de968039 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -752,7 +752,7 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev, } data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0)); - return 2; + return insn->n; } static int ni_pcidio_cmdtest(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 0df086a1a18d..bb72d0bc2975 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -452,7 +452,7 @@ static int pcl711_di_insn_bits(struct comedi_device *dev, data[1] = inb(dev->iobase + PCL711_DI_LO) | (inb(dev->iobase + PCL711_DI_HI) << 8); - return 2; + return insn->n; } /* Digital port write - Untested on 8112 */ @@ -471,7 +471,7 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 433ea05c3e91..d5b60cf7c93f 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -31,7 +31,7 @@ static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = s->state; - return 2; + return insn->n; } static int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -39,7 +39,7 @@ static int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, { data[1] = inb(dev->iobase + PCL725_DI); - return 2; + return insn->n; } static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index dfff9af1951b..2b10f1d83085 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -200,7 +200,7 @@ static int pcl726_di_insn_bits(struct comedi_device *dev, data[1] = inb(dev->iobase + board->di_lo) | (inb(dev->iobase + board->di_hi) << 8); - return 2; + return insn->n; } static int pcl726_do_insn_bits(struct comedi_device *dev, @@ -220,7 +220,7 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index d40caca42862..4675ec57082e 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -48,7 +48,7 @@ static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = s->state; - return 2; + return insn->n; } static int pcl730_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -57,7 +57,7 @@ static int pcl730_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = inb(dev->iobase + ((unsigned long)s->private)) | (inb(dev->iobase + ((unsigned long)s->private) + 1) << 8); - return 2; + return insn->n; } static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 1c146c879be9..578fd8920be1 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -504,7 +504,7 @@ static int pcl812_di_insn_bits(struct comedi_device *dev, data[1] = inb(dev->iobase + PCL812_DI_LO); data[1] |= inb(dev->iobase + PCL812_DI_HI) << 8; - return 2; + return insn->n; } /* @@ -522,7 +522,7 @@ static int pcl812_do_insn_bits(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 13eaadfbaaab..34169c16fb92 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -445,7 +445,7 @@ static int pcl818_di_insn_bits(struct comedi_device *dev, data[1] = inb(dev->iobase + PCL818_DI_LO) | (inb(dev->iobase + PCL818_DI_HI) << 8); - return 2; + return insn->n; } /* @@ -466,7 +466,7 @@ static int pcl818_do_insn_bits(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index 311fe2dc5386..d65e0bda2c44 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -39,7 +39,7 @@ static int pcm3730_do_insn_bits(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } static int pcm3730_di_insn_bits(struct comedi_device *dev, @@ -47,7 +47,7 @@ static int pcm3730_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { data[1] = inb(dev->iobase + (unsigned long)(s->private)); - return 2; + return insn->n; } static int pcm3730_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index a918cc087708..82a60d681eb4 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -344,7 +344,7 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, printk(KERN_DEBUG "s->state %08x data_out %08x\n", s->state, data[1]); #endif - return 2; + return insn->n; } /* The input or output configuration of each digital line is diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 33f740ee3524..feef3d02f35a 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -277,7 +277,7 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, data[1]); #endif - return 2; + return insn->n; } /* The input or output configuration of each digital line is diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index a655b906164a..c253bb9ef335 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -104,7 +104,7 @@ static int pcl733_insn_bits(struct comedi_device *dev, data[1] |= (inb(dev->iobase + 2) << 16); data[1] |= (inb(dev->iobase + 3) << 24); - return 2; + return insn->n; } static int pcl734_insn_bits(struct comedi_device *dev, @@ -125,7 +125,7 @@ static int pcl734_insn_bits(struct comedi_device *dev, } data[1] = s->state; - return 2; + return insn->n; } static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 6ff1fa0fd5de..cc1371daacd2 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1826,7 +1826,7 @@ static int rtd_dio_insn_bits(struct comedi_device *dev, /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */ - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index b6f219922a01..f7fa940d9783 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -264,7 +264,7 @@ static int rti800_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { data[1] = inb(dev->iobase + RTI800_DI); - return 2; + return insn->n; } static int rti800_do_insn_bits(struct comedi_device *dev, @@ -280,7 +280,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev, data[1] = s->state; - return 2; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index b1dd22423704..358380f3eac5 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -694,7 +694,7 @@ static int s526_dio_insn_bits(struct comedi_device *dev, * it was a purely digital output subdevice */ /* data[1]=s->state & 0xFF; */ - return 2; + return insn->n; } static int s526_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 182074c5f78b..d5edd9c091e6 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2160,7 +2160,7 @@ static int s626_dio_insn_bits(struct comedi_device *dev, } data[1] = DEBIread(dev, diopriv->RDDIn); - return 2; + return insn->n; } static int s626_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 67207de33906..6baac525f434 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -577,7 +577,7 @@ static int skel_dio_insn_bits(struct comedi_device *dev, * it was a purely digital output subdevice */ /* data[1]=s->state; */ - return 2; + return insn->n; } static int skel_dio_insn_config(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index f7bf3a2b9f31..72dbccc4427e 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -110,7 +110,7 @@ static int dnp_dio_insn_bits(struct comedi_device *dev, outb(PCDR, CSCIR); data[0] += ((inb(CSCDR) & 0xF0) << 12); - return 2; + return insn->n; } diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 3185e1cdfb29..83ee66965427 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1809,7 +1809,7 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]); up(&this_usbduxsub->sem); - return 2; + return insn->n; } /* reads the 4 counters, only two are used just now */ diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index a93cc5df2093..28f41e9cf682 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1884,7 +1884,7 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, s->state = data[1]; up(&this_usbduxsub->sem); - return 2; + return insn->n; } /***********************************/ -- GitLab From d4a7dc85289306d019378bac18fd88f35dc81b51 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 18 Jun 2012 14:45:42 -0700 Subject: [PATCH 1960/6849] staging: comedi: comedi_subdevice 'io_bits' should be an unsigned int The 'io_bits' variable in the comedi_subdevice struct is a bitmask of the input/output configuration of the the subdevice. It should be an unsigned int to correctly represent this. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess: Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index e0f3915b0f63..7363fd81cc7f 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -78,7 +78,7 @@ struct comedi_subdevice { unsigned runflags; spinlock_t spin_lock; - int io_bits; + unsigned int io_bits; unsigned int maxdata; /* if maxdata==0, use list */ const unsigned int *maxdata_list; /* list is channel specific */ -- GitLab From 560e8788eb659d9d301137eac1704ae1520d2fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:11:59 +0200 Subject: [PATCH 1961/6849] Staging: xgifb: reformat module parameter descriptions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 338227226260..8e0786d0ccf0 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2297,23 +2297,23 @@ static struct pci_driver xgifb_driver = { module_param(mode, charp, 0); MODULE_PARM_DESC(mode, - "\nSelects the desired default display mode in the format XxYxDepth,\n" - "eg. 1024x768x16.\n"); + "Selects the desired default display mode in the format XxYxDepth " + "(eg. 1024x768x16)."); module_param(forcecrt2type, charp, 0); MODULE_PARM_DESC(forcecrt2type, - "\nForce the second display output type. Possible values are NONE,\n" - "LCD, TV, VGA, SVIDEO or COMPOSITE.\n"); + "Force the second display output type. Possible values are NONE, " + "LCD, TV, VGA, SVIDEO or COMPOSITE."); module_param(vesa, int, 0); MODULE_PARM_DESC(vesa, - "\nSelects the desired default display mode by VESA mode number, eg.\n" - "0x117.\n"); + "Selects the desired default display mode by VESA mode number " + "(eg. 0x117)."); module_param(filter, int, 0); MODULE_PARM_DESC(filter, - "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n" - "(Possible values 0-7, default: [no filter])\n"); + "Selects TV flicker filter type (only for systems with a SiS301 video bridge). " + "Possible values 0-7. Default: [no filter])."); static int __init xgifb_init(void) { -- GitLab From 67c0bf7ac72ebe7453ce822ca0d40e54fbbee52d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:00 +0200 Subject: [PATCH 1962/6849] Staging: xgifb: remove DEBUGPRN() macro and its uses. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove DEBUGPRN() macro which is defined as empty. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 8e0786d0ccf0..143dd31298ba 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -117,12 +117,6 @@ static inline void dumpVGAReg(void) } #endif -#if 1 -#define DEBUGPRN(x) -#else -#define DEBUGPRN(x) pr_info(x "\n"); -#endif - /* --------------- Hardware Access Routines -------------------------- */ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, @@ -1054,7 +1048,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, int old_mode; /* unsigned char reg, reg1; */ - DEBUGPRN("Inside do_set_var"); /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */ info->var.xres_virtual = var->xres_virtual; @@ -1199,7 +1192,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, } } XGIfb_bpp_to_var(xgifb_info, var); /*update ARGB info*/ - DEBUGPRN("End of do_set_var"); dumpVGAReg(); return 0; @@ -1321,7 +1313,6 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, { struct xgifb_video_info *xgifb_info = info->par; - DEBUGPRN("inside get_fix"); memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strncpy(fix->id, "XGI", sizeof(fix->id) - 1); @@ -1352,7 +1343,6 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, fix->mmio_len = xgifb_info->mmio_size; fix->accel = FB_ACCEL_SIS_XABRE; - DEBUGPRN("end of get_fix"); return 0; } @@ -1379,8 +1369,6 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) int found_mode = 0; int refresh_rate, search_idx; - DEBUGPRN("Inside check_var"); - if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { vtotal = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; @@ -1511,7 +1499,6 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->blue.msb_right = var->transp.offset = var->transp.length = var->transp.msb_right = 0; - DEBUGPRN("end of check_var"); return 0; } -- GitLab From d56b4c3dff9d1761bbd87746a0d92424960d2df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:01 +0200 Subject: [PATCH 1963/6849] Staging: xgifb: remove DPRINTK() macro and replace it with pr_debug. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 42 +++++++++++++---------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 143dd31298ba..9ffc85377c60 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -32,12 +32,6 @@ static unsigned int refresh_rate; #undef XGIFBDEBUG -#ifdef XGIFBDEBUG -#define DPRINTK(fmt, args...) pr_debug("%s: " fmt, __func__ , ## args) -#else -#define DPRINTK(fmt, args...) -#endif - #ifdef XGIFBDEBUG static void dumpVGAReg(void) { @@ -662,8 +656,8 @@ static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, break; } else if (XGIfb_vrate[i].refresh > rate) { if ((XGIfb_vrate[i].refresh - rate) <= 3) { - DPRINTK("XGIfb: Adjusting rate from %d up to %d\n", - rate, XGIfb_vrate[i].refresh); + pr_debug("XGIfb: Adjusting rate from %d up to %d\n", + rate, XGIfb_vrate[i].refresh); xgifb_info->rate_idx = XGIfb_vrate[i].idx; xgifb_info->refresh_rate = @@ -671,8 +665,8 @@ static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, } else if (((rate - XGIfb_vrate[i - 1].refresh) <= 2) && (XGIfb_vrate[i].idx != 1)) { - DPRINTK("XGIfb: Adjusting rate from %d down to %d\n", - rate, XGIfb_vrate[i-1].refresh); + pr_debug("XGIfb: Adjusting rate from %d down to %d\n", + rate, XGIfb_vrate[i-1].refresh); xgifb_info->rate_idx = XGIfb_vrate[i - 1].idx; xgifb_info->refresh_rate = @@ -680,8 +674,8 @@ static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, } break; } else if ((rate - XGIfb_vrate[i].refresh) <= 2) { - DPRINTK("XGIfb: Adjusting rate from %d down to %d\n", - rate, XGIfb_vrate[i].refresh); + pr_debug("XGIfb: Adjusting rate from %d down to %d\n", + rate, XGIfb_vrate[i].refresh); xgifb_info->rate_idx = XGIfb_vrate[i].idx; break; } @@ -995,15 +989,15 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) } if ((filter >= 0) && (filter <= 7)) { - DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", - filter_tb, filter, - XGI_TV_filter[filter_tb]. + pr_debug("FilterTable[%d]-%d: %02x %02x %02x %02x\n", + filter_tb, filter, + XGI_TV_filter[filter_tb]. filter[filter][0], - XGI_TV_filter[filter_tb]. + XGI_TV_filter[filter_tb]. filter[filter][1], - XGI_TV_filter[filter_tb]. + XGI_TV_filter[filter_tb]. filter[filter][2], - XGI_TV_filter[filter_tb]. + XGI_TV_filter[filter_tb]. filter[filter][3] ); xgifb_reg_set( @@ -1064,7 +1058,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, } if (!htotal || !vtotal) { - DPRINTK("XGIfb: Invalid 'var' information\n"); + pr_debug("XGIfb: Invalid 'var' information\n"); return -EINVAL; } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n", var->pixclock, htotal, vtotal); @@ -1140,11 +1134,11 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, XGIfb_post_setmode(xgifb_info); - DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n", - XGIbios_mode[xgifb_info->mode_idx].xres, - XGIbios_mode[xgifb_info->mode_idx].yres, - XGIbios_mode[xgifb_info->mode_idx].bpp, - xgifb_info->refresh_rate); + pr_debug("XGIfb: Set new mode: %dx%dx%d-%d\n", + XGIbios_mode[xgifb_info->mode_idx].xres, + XGIbios_mode[xgifb_info->mode_idx].yres, + XGIbios_mode[xgifb_info->mode_idx].bpp, + xgifb_info->refresh_rate); xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp; xgifb_info->video_vwidth = info->var.xres_virtual; -- GitLab From 96cd1f8b41c36c2520cc8b524734784a9e995ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:02 +0200 Subject: [PATCH 1964/6849] Staging: xgifb: define real dumpVGAReg() content only in DEBUG mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define real content of dumpVGAReg() only in debug mode. Remove old condition. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 9ffc85377c60..a45a497115ed 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -30,9 +30,7 @@ static unsigned int refresh_rate; /* -------------------- Macro definitions ---------------------------- */ -#undef XGIFBDEBUG - -#ifdef XGIFBDEBUG +#ifdef DEBUG static void dumpVGAReg(void) { u8 i, reg; -- GitLab From 47cee13d1dfe9867758c82a5ef93fd96629ceefd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:03 +0200 Subject: [PATCH 1965/6849] Staging: xgifb: Remove XGIFAIL() macro and its calls. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XGIFAIL() prints a message and returns a value, but it's used only in one place. Better remove it and replace the call with the macro content. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 2 -- drivers/staging/xgifb/XGI_main_26.c | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index ce18f8c98b2d..be6bb7d0971e 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -4,8 +4,6 @@ #include "XGIfb.h" #include "vb_def.h" -#define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) - #ifndef PCI_DEVICE_ID_XGI_42 #define PCI_DEVICE_ID_XGI_42 0x042 #endif diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index a45a497115ed..58cddb40f314 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1376,8 +1376,10 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) vtotal = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; - if (!(htotal) || !(vtotal)) - XGIFAIL("XGIfb: no valid timing data"); + if (!(htotal) || !(vtotal)) { + pr_debug("XGIfb: no valid timing data\n"); + return -EINVAL; + } if (var->pixclock && htotal && vtotal) { drate = 1000000000 / var->pixclock; -- GitLab From 448810662ac3ba1c93c23a352a46d1f523f0b0f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:04 +0200 Subject: [PATCH 1966/6849] Staging: xgifb: Remove printk usage. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace meaninful printks with pr_debug and remove useless ones. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 36 ++++++++-------------- drivers/staging/xgifb/vb_init.c | 47 ++--------------------------- 2 files changed, 15 insertions(+), 68 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 58cddb40f314..df6ef4686bbe 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -69,37 +69,37 @@ static void dumpVGAReg(void) for (i = 0; i < 0x4f; i++) { reg = xgifb_reg_get(XGISR, i); - printk("\no 3c4 %x", i); - printk("\ni 3c5 => %x", reg); + pr_debug("\no 3c4 %x", i); + pr_debug("\ni 3c5 => %x", reg); } for (i = 0; i < 0xF0; i++) { reg = xgifb_reg_get(XGICR, i); - printk("\no 3d4 %x", i); - printk("\ni 3d5 => %x", reg); + pr_debug("\no 3d4 %x", i); + pr_debug("\ni 3d5 => %x", reg); } /* xgifb_reg_set(XGIPART1,0x2F,1); for (i=1; i < 0x50; i++) { reg = xgifb_reg_get(XGIPART1, i); - printk("\no d004 %x", i); - printk("\ni d005 => %x", reg); + pr_debug("\no d004 %x", i); + pr_debug("\ni d005 => %x", reg); } for (i=0; i < 0x50; i++) { reg = xgifb_reg_get(XGIPART2, i); - printk("\no d010 %x", i); - printk("\ni d011 => %x", reg); + pr_debug("\no d010 %x", i); + pr_debug("\ni d011 => %x", reg); } for (i=0; i < 0x50; i++) { reg = xgifb_reg_get(XGIPART3, i); - printk("\no d012 %x",i); - printk("\ni d013 => %x",reg); + pr_debug("\no d012 %x",i); + pr_debug("\ni d013 => %x",reg); } for (i=0; i < 0x50; i++) { reg = xgifb_reg_get(XGIPART4, i); - printk("\no d014 %x",i); - printk("\ni d015 => %x",reg); + pr_debug("\no d014 %x",i); + pr_debug("\ni d015 => %x",reg); } */ } @@ -1040,8 +1040,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, int old_mode; /* unsigned char reg, reg1; */ - /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */ - info->var.xres_virtual = var->xres_virtual; info->var.yres_virtual = var->yres_virtual; info->var.bits_per_pixel = var->bits_per_pixel; @@ -1194,8 +1192,6 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) struct xgifb_video_info *xgifb_info = info->par; unsigned int base; - /* printk("Inside pan_var"); */ - base = var->yoffset * info->var.xres_virtual + var->xoffset; /* calculate base bpp dep. */ @@ -1229,7 +1225,6 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) 0x7F, ((base >> 24) & 0x01) << 7); } - /* printk("End of pan_var"); */ return 0; } @@ -1342,12 +1337,10 @@ static int XGIfb_set_par(struct fb_info *info) { int err; - /* printk("XGIfb: inside set_par\n"); */ err = XGIfb_do_set_var(&info->var, 1, info); if (err) return err; XGIfb_get_fix(&info->fix, -1, info); - /* printk("XGIfb: end of set_par\n"); */ return 0; } @@ -1501,8 +1494,6 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var, { int err; - /* printk("\nInside pan_display:\n"); */ - if (var->xoffset > (info->var.xres_virtual - info->var.xres)) return -EINVAL; if (var->yoffset > (info->var.yres_virtual - info->var.yres)) @@ -1529,7 +1520,6 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var, else info->var.vmode &= ~FB_VMODE_YWRAP; - /* printk("End of pan_display\n"); */ return 0; } @@ -1986,7 +1976,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, /* else if (reg >= 0xB0) { hw_info->ujVBChipID = VB_CHIP_301B; reg1 = xgifb_reg_get(XGIPART4, 0x23); - printk("XGIfb: XGI301B bridge detected\n"); + pr_debug("XGIfb: XGI301B bridge detected\n"); } */ else { hw_info->ujVBChipID = VB_CHIP_301; diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index a3d54b7f23c6..64d13117485a 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1318,22 +1318,17 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* Newdebugcode(0x99); */ if (pVBInfo->FBAddr == NULL) { - printk("\n pVBInfo->FBAddr == 0 "); + pr_debug("pVBInfo->FBAddr == 0\n"); return 0; } - printk("1"); if (pVBInfo->BaseAddr == 0) { - printk("\npVBInfo->BaseAddr == 0 "); + pr_debug("pVBInfo->BaseAddr == 0\n"); return 0; } - printk("2"); outb(0x67, (pVBInfo->BaseAddr + 0x12)); /* 3c2 <- 67 ,ynlai */ pVBInfo->ISXPDOS = 0; - printk("3"); - - printk("4"); /* VBIOSVersion[4] = 0x0; */ @@ -1356,7 +1351,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12; pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14; pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2; - printk("5"); if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ /* Run XGI_GetVBType before InitTo330Pointer */ @@ -1368,7 +1362,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* 1.Openkey */ xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); - printk("6"); /* GetXG21Sense (GPIO) */ if (HwDeviceExtension->jChipType == XG21) @@ -1377,8 +1370,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) if (HwDeviceExtension->jChipType == XG27) XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo); - printk("7"); - /* 2.Reset Extended register */ for (i = 0x06; i < 0x20; i++) @@ -1390,11 +1381,8 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* for(i = 0x06; i <= 0x27; i++) */ /* xgifb_reg_set(pVBInfo->P3c4, i, 0); */ - printk("8"); - for (i = 0x31; i <= 0x3B; i++) xgifb_reg_set(pVBInfo->P3c4, i, 0); - printk("9"); /* [Hsuan] 2004/08/20 Auto over driver for XG42 */ if (HwDeviceExtension->jChipType == XG42) @@ -1406,8 +1394,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) for (i = 0x79; i <= 0x7C; i++) xgifb_reg_set(pVBInfo->P3d4, i, 0); /* shampoo 0208 */ - printk("10"); - if (HwDeviceExtension->jChipType >= XG20) xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97); @@ -1416,8 +1402,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); */ - printk("11"); - /* 4.SetDefExt1Regs begin */ xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07); if (HwDeviceExtension->jChipType == XG27) { @@ -1437,8 +1421,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* SR11 = 0x0F; */ /* xgifb_reg_set(pVBInfo->P3c4, 0x11, SR11); */ - printk("12"); - if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ u32 Temp; @@ -1484,8 +1466,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) } */ - printk("13"); - /* Set AGP customize registers (in SetDefAGPRegs) Start */ for (i = 0x47; i <= 0x4C; i++) xgifb_reg_set(pVBInfo->P3d4, @@ -1514,14 +1494,12 @@ unsigned char XGIInitNew(struct pci_dev *pdev) if (Temp == 1) xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ - printk("14"); } /* != XG20 */ /* Set PCI */ xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23); xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24); xgifb_reg_set(pVBInfo->P3c4, 0x25, XGI330_SR25); - printk("15"); if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ /* Set VB */ @@ -1536,8 +1514,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) xgifb_reg_set(pVBInfo->Part1Port, 0x02, XGI330_CRT2Data_1_2); - printk("16"); - xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ } /* != XG20 */ @@ -1557,7 +1533,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32); } xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33); - printk("17"); /* SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4); */ @@ -1578,18 +1553,11 @@ unsigned char XGIInitNew(struct pci_dev *pdev) XGI_LockCRT2(HwDeviceExtension, pVBInfo); } } /* != XG20 */ - printk("18"); - - printk("181"); - - printk("182"); XGI_SenseCRT1(pVBInfo); - printk("183"); /* XGINew_DetectMonitor(HwDeviceExtension); */ if (HwDeviceExtension->jChipType == XG21) { - printk("186"); xgifb_reg_and_or(pVBInfo->P3d4, 0x32, @@ -1597,7 +1565,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) Monitor1Sense); /* Z9 default has CRT */ temp = GetXG21FPBits(pVBInfo); xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp); - printk("187"); } if (HwDeviceExtension->jChipType == XG27) { @@ -1608,7 +1575,6 @@ unsigned char XGIInitNew(struct pci_dev *pdev) temp = GetXG27FPBits(pVBInfo); xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp); } - printk("19"); pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); @@ -1616,11 +1582,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev) pVBInfo->P3d4, pVBInfo); - printk("20"); XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo); - printk("21"); - - printk("22"); /* SetDefExt2Regs begin */ /* @@ -1651,16 +1613,11 @@ unsigned char XGIInitNew(struct pci_dev *pdev) xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21); - printk("23"); - XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo); XGINew_SetModeScratch(HwDeviceExtension, pVBInfo); - printk("24"); - xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87); xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x31); - printk("25"); return 1; } /* end of init */ -- GitLab From e054102b9fee7ef8cd1a10a8a6474f566e1c5631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:05 +0200 Subject: [PATCH 1967/6849] Staging: xgifb: Fix sparse warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add include files with function definitions to avoid sparse warnings. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 1 + drivers/staging/xgifb/vb_setmode.c | 2 +- drivers/staging/xgifb/vb_util.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 64d13117485a..143957f82d6a 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -5,6 +5,7 @@ #include "vb_def.h" #include "vb_util.h" #include "vb_setmode.h" +#include "vb_init.h" static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = { { 16, 0x45}, { 8, 0x35}, diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index b1713d389794..479362eacb4f 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -4,7 +4,7 @@ #include "vb_def.h" #include "vb_util.h" #include "vb_table.h" - +#include "vb_setmode.h" #define IndexMask 0xff #define TVCLKBASE_315_25 (TVCLKBASE_315 + 25) diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 5c93a2202bd0..1b452f8b6274 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -1,4 +1,5 @@ #include "vgatypes.h" +#include "vb_util.h" void xgifb_reg_set(unsigned long port, u8 index, u8 data) { -- GitLab From 1918570388066fb15d591d9b9bf915dfc793aff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20G=C3=B3mez?= Date: Mon, 18 Jun 2012 13:12:06 +0200 Subject: [PATCH 1968/6849] Staging: xgifb: Replace pr_* with dev_* when possible. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace pr_* calls with dev_* ones when the device structure is available. Signed-off-by: Miguel Gómez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 72 +++++++++++++++++------------ drivers/staging/xgifb/vb_init.c | 4 +- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index df6ef4686bbe..fe9061d37ce8 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1838,9 +1838,9 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_base = pci_resource_start(pdev, 1); xgifb_info->mmio_size = pci_resource_len(pdev, 1); xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; - pr_info("Relocate IO address: %Lx [%08lx]\n", - (u64) pci_resource_start(pdev, 2), - xgifb_info->vga_base); + dev_info(&pdev->dev, "Relocate IO address: %Lx [%08lx]\n", + (u64) pci_resource_start(pdev, 2), + xgifb_info->vga_base); if (pci_enable_device(pdev)) { ret = -EIO; @@ -1858,7 +1858,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD); if (reg1 != 0xa1) { /*I/O error */ - pr_err("I/O error!!!"); + dev_err(&pdev->dev, "I/O error!!!"); ret = -EIO; goto error_disable; } @@ -1886,11 +1886,12 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, goto error_disable; } - pr_info("chipid = %x\n", xgifb_info->chip); + dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip); hw_info->jChipType = xgifb_info->chip; if (XGIfb_get_dram_size(xgifb_info)) { - pr_err("Fatal error: Unable to determine RAM size.\n"); + dev_err(&pdev->dev, + "Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; goto error_disable; } @@ -1907,10 +1908,11 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!request_mem_region(xgifb_info->video_base, xgifb_info->video_size, "XGIfb FB")) { - pr_err("unable request memory size %x\n", + dev_err(&pdev->dev, "unable request memory size %x\n", xgifb_info->video_size); - pr_err("Fatal error: Unable to reserve frame buffer memory\n"); - pr_err("Is there another framebuffer driver active?\n"); + dev_err(&pdev->dev, + "Fatal error: Unable to reserve frame buffer memory. " + "Is there another framebuffer driver active?\n"); ret = -ENODEV; goto error_disable; } @@ -1918,7 +1920,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!request_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size, "XGIfb MMIO")) { - pr_err("Fatal error: Unable to reserve MMIO region\n"); + dev_err(&pdev->dev, + "Fatal error: Unable to reserve MMIO region\n"); ret = -ENODEV; goto error_0; } @@ -1928,18 +1931,20 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, xgifb_info->mmio_size); - pr_info("Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n", - (u64) xgifb_info->video_base, - xgifb_info->video_vbase, - xgifb_info->video_size / 1024); + dev_info(&pdev->dev, + "Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n", + (u64) xgifb_info->video_base, + xgifb_info->video_vbase, + xgifb_info->video_size / 1024); - pr_info("MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n", - (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase, - xgifb_info->mmio_size / 1024); + dev_info(&pdev->dev, + "MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n", + (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase, + xgifb_info->mmio_size / 1024); pci_set_drvdata(pdev, xgifb_info); if (!XGIInitNew(pdev)) - pr_err("XGIInitNew() failed!\n"); + dev_err(&pdev->dev, "XGIInitNew() failed!\n"); xgifb_info->mtrr = (unsigned int) 0; @@ -1968,10 +1973,14 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, reg = xgifb_reg_get(XGIPART4, 0x01); if (reg >= 0xE0) { hw_info->ujVBChipID = VB_CHIP_302LV; - pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg); + dev_info(&pdev->dev, + "XGI302LV bridge detected (revision 0x%02x)\n", + reg); } else if (reg >= 0xD0) { hw_info->ujVBChipID = VB_CHIP_301LV; - pr_info("XGI301LV bridge detected (revision 0x%02x)\n", reg); + dev_info(&pdev->dev, + "XGI301LV bridge detected (revision 0x%02x)\n", + reg); } /* else if (reg >= 0xB0) { hw_info->ujVBChipID = VB_CHIP_301B; @@ -1980,17 +1989,21 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } */ else { hw_info->ujVBChipID = VB_CHIP_301; - pr_info("XGI301 bridge detected\n"); + dev_info(&pdev->dev, "XGI301 bridge detected\n"); } break; case HASVB_302: reg = xgifb_reg_get(XGIPART4, 0x01); if (reg >= 0xE0) { hw_info->ujVBChipID = VB_CHIP_302LV; - pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg); + dev_info(&pdev->dev, + "XGI302LV bridge detected (revision 0x%02x)\n", + reg); } else if (reg >= 0xD0) { hw_info->ujVBChipID = VB_CHIP_301LV; - pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg); + dev_info(&pdev->dev, + "XGI302LV bridge detected (revision 0x%02x)\n", + reg); } else if (reg >= 0xB0) { reg1 = xgifb_reg_get(XGIPART4, 0x23); @@ -1998,27 +2011,28 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } else { hw_info->ujVBChipID = VB_CHIP_302; - pr_info("XGI302 bridge detected\n"); + dev_info(&pdev->dev, "XGI302 bridge detected\n"); } break; case HASVB_LVDS: hw_info->ulExternalChip = 0x1; - pr_info("LVDS transmitter detected\n"); + dev_info(&pdev->dev, "LVDS transmitter detected\n"); break; case HASVB_TRUMPION: hw_info->ulExternalChip = 0x2; - pr_info("Trumpion Zurac LVDS scaler detected\n"); + dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n"); break; case HASVB_CHRONTEL: hw_info->ulExternalChip = 0x4; - pr_info("Chrontel TV encoder detected\n"); + dev_info(&pdev->dev, "Chrontel TV encoder detected\n"); break; case HASVB_LVDS_CHRONTEL: hw_info->ulExternalChip = 0x5; - pr_info("LVDS transmitter and Chrontel TV encoder detected\n"); + dev_info(&pdev->dev, + "LVDS transmitter and Chrontel TV encoder detected\n"); break; default: - pr_info("No or unknown bridge type detected\n"); + dev_info(&pdev->dev, "No or unknown bridge type detected\n"); break; } diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 143957f82d6a..7c555a7725fe 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1319,11 +1319,11 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* Newdebugcode(0x99); */ if (pVBInfo->FBAddr == NULL) { - pr_debug("pVBInfo->FBAddr == 0\n"); + dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n"); return 0; } if (pVBInfo->BaseAddr == 0) { - pr_debug("pVBInfo->BaseAddr == 0\n"); + dev_dbg(&pdev->dev, "pVBInfo->BaseAddr == 0\n"); return 0; } -- GitLab From 1351acce4fd25c6b7f007a92cc706e3fbd56479c Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 18 Jun 2012 07:42:23 -0700 Subject: [PATCH 1969/6849] staging: serqt_usb2: Fix some typos. Fixes some typos that was found while reading through staging/serqt_usb2 Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 43045db982d4..8a362f7af379 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -609,7 +609,7 @@ static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number, /* * qt_setuart - * issuse a SET_UART vendor-spcific request on the default control pipe + * issues a SET_UART vendor-specific request on the default control pipe * If successful sets baud rate divisor and LCR value */ static int qt_setuart(struct usb_serial *serial, unsigned short Uart_Number, @@ -1388,7 +1388,7 @@ static inline int qt_real_tiocmset(struct tty_struct *tty, return -ESPIPE; /* - * Turn off the RTS and DTR and loopbcck and then only turn on what was + * Turn off the RTS and DTR and loopback and then only turn on what was * asked for */ mcr &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP); -- GitLab From 493b67b73c7f575058acec61903a2cb128207106 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 18 Jun 2012 07:42:24 -0700 Subject: [PATCH 1970/6849] staging: slicoss: Fix a typo. The below patch fixes a typo found while reading through staging/slicoss Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 77a0751a31ad..d2b82a78d2af 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -47,7 +47,7 @@ * Oasis cards (single and dual port PCI-x Gigabit) copper and fiber * Kalahari cards (dual and quad port PCI-e Gigabit) copper and fiber * - * The driver was acutally tested on Oasis and Kalahari cards. + * The driver was actually tested on Oasis and Kalahari cards. * * * NOTE: This is the standard, non-accelerated version of Alacritech's -- GitLab From f5b81ddd12da71bd00b2963203c23ff929e0c182 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:47 +0200 Subject: [PATCH 1971/6849] iio: iio_buffer_register: Skip channels with negative scan index It is not always the case that all channels can be used in buffered mode. This patch allows channels, which can not be used in buffered mode, to set their scan index to a negative number, which will cause iio_buffer_register to ignore the channel. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-buffer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 2f35db93cdb6..3d8d187eef2a 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -285,6 +285,9 @@ int iio_buffer_register(struct iio_dev *indio_dev, if (channels) { /* new magic */ for (i = 0; i < num_channels; i++) { + if (channels[i].scan_index < 0) + continue; + /* Establish necessary mask length */ if (channels[i].scan_index > (int)indio_dev->masklength - 1) -- GitLab From 23f2d735a932c7833d2d00da5e3ecdf4a6836210 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:48 +0200 Subject: [PATCH 1972/6849] iio: Add helper function for initializing triggered buffers Add a helper function for executing the common tasks which are usually involved in setting up a simple software ringbuffer. It will allocate the buffer, allocate the pollfunc and register the buffer. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/Kconfig | 7 ++ drivers/iio/Makefile | 1 + drivers/iio/industrialio-triggered-buffer.c | 110 ++++++++++++++++++++ include/linux/iio/triggered_buffer.h | 15 +++ 4 files changed, 133 insertions(+) create mode 100644 drivers/iio/industrialio-triggered-buffer.c create mode 100644 include/linux/iio/triggered_buffer.h diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 103349f2b3b5..612073f6c540 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -30,6 +30,13 @@ config IIO_KFIFO_BUF no buffer events so it is up to userspace to work out how often to read from the buffer. +config IIO_TRIGGERED_BUFFER + tristate + select IIO_TRIGGER + select IIO_KFIFO_BUF + help + Provides helper functions for setting up triggered buffers. + endif # IIO_BUFFER config IIO_TRIGGER diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index c38fa2a40af2..34309abb7979 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -7,6 +7,7 @@ industrialio-y := industrialio-core.o industrialio-event.o inkern.o industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o +obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-y += adc/ diff --git a/drivers/iio/industrialio-triggered-buffer.c b/drivers/iio/industrialio-triggered-buffer.c new file mode 100644 index 000000000000..46c619b0d8c5 --- /dev/null +++ b/drivers/iio/industrialio-triggered-buffer.c @@ -0,0 +1,110 @@ + /* + * Copyright (c) 2012 Analog Devices, Inc. + * Author: Lars-Peter Clausen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { + .preenable = &iio_sw_buffer_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, +}; + +/** + * iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc + * @indio_dev: IIO device structure + * @pollfunc_bh: Function which will be used as pollfunc bottom half + * @pollfunc_th: Function which will be used as pollfunc top half + * @setup_ops: Buffer setup functions to use for this device. + * If NULL the default setup functions for triggered + * buffers will be used. + * + * This function combines some common tasks which will normally be performed + * when setting up a triggered buffer. It will allocate the buffer and the + * pollfunc, as well as register the buffer with the IIO core. + * + * Before calling this function the indio_dev structure should already be + * completely initialized, but not yet registered. In practice this means that + * this function should be called right before iio_device_register(). + * + * To free the resources allocated by this function call + * iio_triggered_buffer_cleanup(). + */ +int iio_triggered_buffer_setup(struct iio_dev *indio_dev, + irqreturn_t (*pollfunc_bh)(int irq, void *p), + irqreturn_t (*pollfunc_th)(int irq, void *p), + const struct iio_buffer_setup_ops *setup_ops) +{ + int ret; + + indio_dev->buffer = iio_kfifo_allocate(indio_dev); + if (!indio_dev->buffer) { + ret = -ENOMEM; + goto error_ret; + } + + indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh, + pollfunc_th, + IRQF_ONESHOT, + indio_dev, + "%s_consumer%d", + indio_dev->name, + indio_dev->id); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_kfifo_free; + } + + /* Ring buffer functions - here trigger setup related */ + if (setup_ops) + indio_dev->setup_ops = setup_ops; + else + indio_dev->setup_ops = &iio_triggered_buffer_setup_ops; + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_BUFFER_TRIGGERED; + + ret = iio_buffer_register(indio_dev, + indio_dev->channels, + indio_dev->num_channels); + if (ret) + goto error_dealloc_pollfunc; + + return 0; + +error_dealloc_pollfunc: + iio_dealloc_pollfunc(indio_dev->pollfunc); +error_kfifo_free: + iio_kfifo_free(indio_dev->buffer); +error_ret: + return ret; +} +EXPORT_SYMBOL(iio_triggered_buffer_setup); + +/** + * iio_triggered_buffer_cleanup() - Free resources allocated by iio_triggered_buffer_setup() + * @indio_dev: IIO device structure + */ +void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev) +{ + iio_buffer_unregister(indio_dev); + iio_dealloc_pollfunc(indio_dev->pollfunc); + iio_kfifo_free(indio_dev->buffer); +} +EXPORT_SYMBOL(iio_triggered_buffer_cleanup); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/iio/triggered_buffer.h b/include/linux/iio/triggered_buffer.h new file mode 100644 index 000000000000..c378ebec605e --- /dev/null +++ b/include/linux/iio/triggered_buffer.h @@ -0,0 +1,15 @@ +#ifndef _LINUX_IIO_TRIGGERED_BUFFER_H_ +#define _LINUX_IIO_TRIGGERED_BUFFER_H_ + +#include + +struct iio_dev; +struct iio_buffer_setup_ops; + +int iio_triggered_buffer_setup(struct iio_dev *indio_dev, + irqreturn_t (*pollfunc_bh)(int irq, void *p), + irqreturn_t (*pollfunc_th)(int irq, void *p), + const struct iio_buffer_setup_ops *setup_ops); +void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev); + +#endif -- GitLab From 90032e4e9cc40e2933259190b670d70ddd149e68 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:49 +0200 Subject: [PATCH 1973/6849] iio:adc:at91: Use new triggered buffer setup helper Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Acked-by: Maxime Ripard Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/Kconfig | 3 +-- drivers/iio/adc/at91_adc.c | 51 +++----------------------------------- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 9a0df8123cc4..4f7f584cfd61 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -7,8 +7,7 @@ config AT91_ADC tristate "Atmel AT91 ADC" depends on ARCH_AT91 select IIO_BUFFER - select IIO_KFIFO_BUF - select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER select SYSFS help Say yes here to build support for Atmel AT91 ADC. diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f18a95d80255..6a084695b77e 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -26,9 +26,9 @@ #include #include -#include #include #include +#include #include @@ -318,58 +318,15 @@ static void at91_adc_trigger_remove(struct iio_dev *idev) } } -static const struct iio_buffer_setup_ops at91_adc_buffer_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - static int at91_adc_buffer_init(struct iio_dev *idev) { - int ret; - - idev->buffer = iio_kfifo_allocate(idev); - if (!idev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - - idev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &at91_adc_trigger_handler, - IRQF_ONESHOT, - idev, - "%s-consumer%d", - idev->name, - idev->id); - if (idev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_pollfunc; - } - - idev->setup_ops = &at91_adc_buffer_ops; - idev->modes |= INDIO_BUFFER_TRIGGERED; - - ret = iio_buffer_register(idev, - idev->channels, - idev->num_channels); - if (ret) - goto error_register; - - return 0; - -error_register: - iio_dealloc_pollfunc(idev->pollfunc); -error_pollfunc: - iio_kfifo_free(idev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(idev, &iio_pollfunc_store_time, + &at91_adc_trigger_handler, NULL); } static void at91_adc_buffer_remove(struct iio_dev *idev) { - iio_buffer_unregister(idev); - iio_dealloc_pollfunc(idev->pollfunc); - iio_kfifo_free(idev->buffer); + iio_triggered_buffer_cleanup(idev); } static int at91_adc_read_raw(struct iio_dev *idev, -- GitLab From a648232dc5ed840c6dab0a949450ee4cdf5830bd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:50 +0200 Subject: [PATCH 1974/6849] staging:iio:adc:ad7192: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 3 +- drivers/staging/iio/adc/ad7192.c | 49 ++++---------------------------- 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 8f1b3af02f29..7cdf421e76ee 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -136,8 +136,7 @@ config AD7192 tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver" depends on SPI select IIO_BUFFER - select IIO_KFIFO_BUF - select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD7190, AD7192 or AD7195 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 5eaeaf1f0ae8..839f17c4e33d 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -20,9 +20,9 @@ #include #include #include -#include #include #include +#include #include "ad7192.h" @@ -542,41 +542,13 @@ static const struct iio_buffer_setup_ops ad7192_ring_setup_ops = { static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - int ret; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &ad7192_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "ad7192_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &ad7192_ring_setup_ops; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad7192_trigger_handler, &ad7192_ring_setup_ops); } static void ad7192_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } /** @@ -1077,23 +1049,15 @@ static int __devinit ad7192_probe(struct spi_device *spi) if (ret) goto error_ring_cleanup; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - indio_dev->num_channels); - if (ret) - goto error_remove_trigger; - ret = ad7192_setup(st); if (ret) - goto error_unreg_ring; + goto error_remove_trigger; ret = iio_device_register(indio_dev); if (ret < 0) - goto error_unreg_ring; + goto error_remove_trigger; return 0; -error_unreg_ring: - iio_buffer_unregister(indio_dev); error_remove_trigger: ad7192_remove_trigger(indio_dev); error_ring_cleanup: @@ -1116,7 +1080,6 @@ static int ad7192_remove(struct spi_device *spi) struct ad7192_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - iio_buffer_unregister(indio_dev); ad7192_remove_trigger(indio_dev); ad7192_ring_cleanup(indio_dev); -- GitLab From d045b9d21b9591a4605590e7fe433f92d4b54762 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:51 +0200 Subject: [PATCH 1975/6849] staging:iio:adc:ad7298: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. The previous code was not passing the temperature channel to iio_buffer_register since the temperature channel can not be used in buffered mode. With the new helper functions it is not possible to do this, instead the scan index for the temperature channel is set to -1 which will cause iio_buffer_register to ignore the channel. (Also While we are at it also assign the symbolic constant instead of the raw value to the channel address for the temperature channel). Also as part of the conversion drop scan_timestamp being enabled by default, since it is a left over of an earlier cleanup. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 2 +- drivers/staging/iio/adc/ad7298.h | 5 +++ drivers/staging/iio/adc/ad7298_core.c | 15 ++----- drivers/staging/iio/adc/ad7298_ring.c | 64 +++++---------------------- 4 files changed, 20 insertions(+), 66 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 7cdf421e76ee..bb6fffd0d373 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -13,7 +13,7 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI - select IIO_KFIFO_BUF if IIO_BUFFER + select IIO_TRIGGERED_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h index 5051a7e4d4fd..18f278723002 100644 --- a/drivers/staging/iio/adc/ad7298.h +++ b/drivers/staging/iio/adc/ad7298.h @@ -55,6 +55,8 @@ struct ad7298_state { #ifdef CONFIG_IIO_BUFFER int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev); void ad7298_ring_cleanup(struct iio_dev *indio_dev); +int ad7298_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask); #else /* CONFIG_IIO_BUFFER */ static inline int @@ -66,5 +68,8 @@ ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) static inline void ad7298_ring_cleanup(struct iio_dev *indio_dev) { } + +#define ad7298_update_scan_mode NULL + #endif /* CONFIG_IIO_BUFFER */ #endif /* IIO_ADC_AD7298_H_ */ diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index c90f2b3e661f..6141f4a70cfa 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -45,8 +45,8 @@ static struct iio_chan_spec ad7298_channels[] = { .channel = 0, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = 9, - .scan_index = AD7298_CH_TEMP, + .address = AD7298_CH_TEMP, + .scan_index = -1, .scan_type = { .sign = 's', .realbits = 32, @@ -171,6 +171,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad7298_info = { .read_raw = &ad7298_read_raw, + .update_scan_mode = ad7298_update_scan_mode, .driver_module = THIS_MODULE, }; @@ -231,19 +232,12 @@ static int __devinit ad7298_probe(struct spi_device *spi) if (ret) goto error_disable_reg; - ret = iio_buffer_register(indio_dev, - &ad7298_channels[1], /* skip temp0 */ - ARRAY_SIZE(ad7298_channels) - 1); - if (ret) - goto error_cleanup_ring; ret = iio_device_register(indio_dev); if (ret) - goto error_unregister_ring; + goto error_cleanup_ring; return 0; -error_unregister_ring: - iio_buffer_unregister(indio_dev); error_cleanup_ring: ad7298_ring_cleanup(indio_dev); error_disable_reg: @@ -263,7 +257,6 @@ static int __devexit ad7298_remove(struct spi_device *spi) struct ad7298_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - iio_buffer_unregister(indio_dev); ad7298_ring_cleanup(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 908a3e5609df..cd3e9cb47a64 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -13,37 +13,29 @@ #include #include -#include #include +#include #include "ad7298.h" /** - * ad7298_ring_preenable() setup the parameters of the ring before enabling - * - * The complex nature of the setting of the number of bytes per datum is due - * to this driver currently ensuring that the timestamp is stored at an 8 - * byte boundary. + * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask **/ -static int ad7298_ring_preenable(struct iio_dev *indio_dev) +int ad7298_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) { struct ad7298_state *st = iio_priv(indio_dev); int i, m; unsigned short command; - int scan_count, ret; - - ret = iio_sw_buffer_preenable(indio_dev); - if (ret < 0) - return ret; + int scan_count; /* Now compute overall size */ - scan_count = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); + scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength); command = AD7298_WRITE | st->ext_ref; for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) - if (test_bit(i, indio_dev->active_scan_mask)) + if (test_bit(i, active_scan_mask)) command |= m; st->tx_buf[0] = cpu_to_be16(command); @@ -108,49 +100,13 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) return IRQ_HANDLED; } -static const struct iio_buffer_setup_ops ad7298_ring_setup_ops = { - .preenable = &ad7298_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - int ret; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(NULL, - &ad7298_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "ad7298_consumer%d", - indio_dev->id); - - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &ad7298_ring_setup_ops; - indio_dev->buffer->scan_timestamp = true; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, NULL, + &ad7298_trigger_handler, NULL); } void ad7298_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } -- GitLab From 397b85dd860db633e73fd5c1daf995431d5f6f7e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:52 +0200 Subject: [PATCH 1976/6849] staging:iio:adc:ad7476: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Also as part of the conversion drop scan_timestamp being enabled by default, since it is a left over of an earlier cleanup. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 3 +- drivers/staging/iio/adc/ad7476_core.c | 9 ------ drivers/staging/iio/adc/ad7476_ring.c | 46 +++------------------------ 3 files changed, 5 insertions(+), 53 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index bb6fffd0d373..c5f56511743c 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -73,8 +73,7 @@ config AD7476 tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" depends on SPI select IIO_BUFFER - select IIO_KFIFO_BUF - select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495 diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index be1c260cf165..4d30a798ba0d 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -177,20 +177,12 @@ static int __devinit ad7476_probe(struct spi_device *spi) if (ret) goto error_disable_reg; - ret = iio_buffer_register(indio_dev, - st->chip_info->channel, - ARRAY_SIZE(st->chip_info->channel)); - if (ret) - goto error_cleanup_ring; - ret = iio_device_register(indio_dev); if (ret) goto error_ring_unregister; return 0; error_ring_unregister: - iio_buffer_unregister(indio_dev); -error_cleanup_ring: ad7476_ring_cleanup(indio_dev); error_disable_reg: if (!IS_ERR(st->reg)) @@ -210,7 +202,6 @@ static int ad7476_remove(struct spi_device *spi) struct ad7476_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - iio_buffer_unregister(indio_dev); ad7476_ring_cleanup(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 383611b05764..10f8b8dd1fa4 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -15,8 +15,8 @@ #include #include -#include #include +#include #include "ad7476.h" @@ -52,51 +52,13 @@ done: return IRQ_HANDLED; } -static const struct iio_buffer_setup_ops ad7476_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - struct ad7476_state *st = iio_priv(indio_dev); - int ret = 0; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc - = iio_alloc_pollfunc(NULL, - &ad7476_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - spi_get_device_id(st->spi)->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &ad7476_ring_setup_ops; - indio_dev->buffer->scan_timestamp = true; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, NULL, + &ad7476_trigger_handler, NULL); } void ad7476_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } -- GitLab From 74ed964931b1be634bce199ac854dc4ed76679b5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:53 +0200 Subject: [PATCH 1977/6849] staging:iio:adc:ad7606: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Also as part of the conversion drop scan_timestamp being enabled by default, since it is a left over of an earlier cleanup. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 3 +- drivers/staging/iio/adc/ad7606_core.c | 9 ------ drivers/staging/iio/adc/ad7606_ring.c | 46 +++------------------------ 3 files changed, 6 insertions(+), 52 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index c5f56511743c..ca4662750249 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -25,8 +25,7 @@ config AD7606 tristate "Analog Devices AD7606 ADC driver" depends on GPIOLIB select IIO_BUFFER - select IIO_TRIGGER - select IIO_KFIFO_BUF + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices: ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index a13afff2dfe6..ccb97fecdea7 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -533,20 +533,12 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq, if (ret) goto error_free_irq; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - indio_dev->num_channels); - if (ret) - goto error_cleanup_ring; ret = iio_device_register(indio_dev); if (ret) goto error_unregister_ring; return indio_dev; error_unregister_ring: - iio_buffer_unregister(indio_dev); - -error_cleanup_ring: ad7606_ring_cleanup(indio_dev); error_free_irq: @@ -571,7 +563,6 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq) struct ad7606_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - iio_buffer_unregister(indio_dev); ad7606_ring_cleanup(indio_dev); free_irq(irq, indio_dev); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 24ce8fc71646..f15afe47c20d 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -13,8 +13,8 @@ #include #include -#include #include +#include #include "ad7606.h" @@ -91,54 +91,18 @@ done: kfree(buf); } -static const struct iio_buffer_setup_ops ad7606_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) { struct ad7606_state *st = iio_priv(indio_dev); - int ret; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - - indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh, - &ad7606_trigger_handler_th_bh, - 0, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - - /* Ring buffer functions - here trigger setup related */ - - indio_dev->setup_ops = &ad7606_ring_setup_ops; - indio_dev->buffer->scan_timestamp = true; INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, + &ad7606_trigger_handler_th_bh, &ad7606_trigger_handler_th_bh, + NULL); } void ad7606_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } -- GitLab From 82796edca9ba014aa09cc158240c23b5b3f9326d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:54 +0200 Subject: [PATCH 1978/6849] staging:iio:adc:ad7793: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 3 +- drivers/staging/iio/adc/ad7793.c | 49 ++++---------------------------- 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index ca4662750249..4fcc4be044ea 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -112,8 +112,7 @@ config AD7793 tristate "Analog Devices AD7792 AD7793 ADC driver" depends on SPI select IIO_BUFFER - select IIO_KFIFO_BUF - select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD7792 and AD7793 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index b36556fa2957..2bb9f68d66a4 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -21,9 +21,9 @@ #include #include #include -#include #include #include +#include #include "ad7793.h" @@ -407,41 +407,13 @@ static const struct iio_buffer_setup_ops ad7793_ring_setup_ops = { static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - int ret; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &ad7793_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "ad7793_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &ad7793_ring_setup_ops; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad7793_trigger_handler, &ad7793_ring_setup_ops); } static void ad7793_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } /** @@ -959,24 +931,16 @@ static int __devinit ad7793_probe(struct spi_device *spi) if (ret) goto error_unreg_ring; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - indio_dev->num_channels); - if (ret) - goto error_remove_trigger; - ret = ad7793_setup(st); if (ret) - goto error_uninitialize_ring; + goto error_remove_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_uninitialize_ring; + goto error_remove_trigger; return 0; -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); error_remove_trigger: ad7793_remove_trigger(indio_dev); error_unreg_ring: @@ -999,7 +963,6 @@ static int ad7793_remove(struct spi_device *spi) struct ad7793_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - iio_buffer_unregister(indio_dev); ad7793_remove_trigger(indio_dev); ad7793_ring_cleanup(indio_dev); -- GitLab From cc4dd03a6a9535cb2f731c5069e6a02781e3267a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:55 +0200 Subject: [PATCH 1979/6849] staging:iio:adc:ad7887: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 3 +-- drivers/staging/iio/adc/ad7887_core.c | 9 ------- drivers/staging/iio/adc/ad7887_ring.c | 35 +++------------------------ 3 files changed, 5 insertions(+), 42 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 4fcc4be044ea..e3fdb847de2c 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -86,8 +86,7 @@ config AD7887 tristate "Analog Devices AD7887 ADC driver" depends on SPI select IIO_BUFFER - select IIO_KFIFO_BUF - select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD7887 SPI analog to digital converter (ADC). diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 7186074deeb3..397b84947155 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -201,20 +201,12 @@ static int __devinit ad7887_probe(struct spi_device *spi) if (ret) goto error_disable_reg; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - indio_dev->num_channels); - if (ret) - goto error_cleanup_ring; - ret = iio_device_register(indio_dev); if (ret) goto error_unregister_ring; return 0; error_unregister_ring: - iio_buffer_unregister(indio_dev); -error_cleanup_ring: ad7887_ring_cleanup(indio_dev); error_disable_reg: if (!IS_ERR(st->reg)) @@ -233,7 +225,6 @@ static int ad7887_remove(struct spi_device *spi) struct ad7887_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - iio_buffer_unregister(indio_dev); ad7887_ring_cleanup(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index fd91384db894..1c406dad0e67 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -14,8 +14,8 @@ #include #include -#include #include +#include #include "ad7887.h" @@ -112,38 +112,11 @@ static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = { int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - int ret; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &ad7887_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "ad7887_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &ad7887_ring_setup_ops; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad7887_trigger_handler, &ad7887_ring_setup_ops); } void ad7887_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } -- GitLab From ae3805c3aece38ee40ebc902a598b44a393902e1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Jun 2012 18:33:56 +0200 Subject: [PATCH 1980/6849] staging:iio:adc:ad799x: Use new triggered buffer setup helper function Use the new triggered buffer setup helper function to allocate and register buffer and pollfunc. Also as part of the conversion drop scan_timestamp being enabled by default, since it is a left over of an earlier cleanup. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 2 +- drivers/staging/iio/adc/ad799x.h | 2 - drivers/staging/iio/adc/ad799x_core.c | 25 ++++++----- drivers/staging/iio/adc/ad799x_ring.c | 65 ++------------------------- 4 files changed, 20 insertions(+), 74 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index e3fdb847de2c..67711b7d718a 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -63,7 +63,7 @@ config AD799X_RING_BUFFER bool "Analog Devices AD799x: use ring buffer" depends on AD799X select IIO_BUFFER - select IIO_KFIFO_BUF + select IIO_TRIGGERED_BUFFER help Say yes here to include ring buffer support in the AD799X ADC driver. diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h index 99f8abe9731b..3e363c4ba211 100644 --- a/drivers/staging/iio/adc/ad799x.h +++ b/drivers/staging/iio/adc/ad799x.h @@ -120,8 +120,6 @@ struct ad799x_platform_data { u16 vref_mv; }; -int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask); - #ifdef CONFIG_AD799X_RING_BUFFER int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev); void ad799x_ring_cleanup(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 80e0c6e25a9b..2d4bda99eff7 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -99,10 +99,21 @@ static int ad799x_i2c_write8(struct ad799x_state *st, u8 reg, u8 data) return ret; } -int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask) +static int ad7997_8_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) { - return ad799x_i2c_write16(st, AD7998_CONF_REG, - st->config | (mask << AD799X_CHANNEL_SHIFT)); + struct ad799x_state *st = iio_priv(indio_dev); + + switch (st->id) { + case ad7997: + case ad7998: + return ad799x_i2c_write16(st, AD7998_CONF_REG, + st->config | (*scan_mask << AD799X_CHANNEL_SHIFT)); + default: + break; + } + + return 0; } static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch) @@ -442,6 +453,7 @@ static const struct iio_info ad7993_4_7_8_info = { .read_event_value = &ad799x_read_event_value, .write_event_value = &ad799x_write_event_value, .driver_module = THIS_MODULE, + .update_scan_mode = ad7997_8_update_scan_mode, }; #define AD799X_EV_MASK (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ @@ -887,12 +899,6 @@ static int __devinit ad799x_probe(struct i2c_client *client, if (ret) goto error_disable_reg; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - indio_dev->num_channels); - if (ret) - goto error_cleanup_ring; - if (client->irq > 0) { ret = request_threaded_irq(client->irq, NULL, @@ -934,7 +940,6 @@ static __devexit int ad799x_remove(struct i2c_client *client) if (client->irq > 0) free_irq(client->irq, indio_dev); - iio_buffer_unregister(indio_dev); ad799x_ring_cleanup(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 1c7ff4423db4..0882c9ef6572 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -18,32 +18,11 @@ #include #include -#include #include +#include #include "ad799x.h" -/** - * ad799x_ring_preenable() setup the parameters of the ring before enabling - * - * The complex nature of the setting of the number of bytes per datum is due - * to this driver currently ensuring that the timestamp is stored at an 8 - * byte boundary. - **/ -static int ad799x_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad799x_state *st = iio_priv(indio_dev); - /* - * Need to figure out the current mode based upon the requested - * scan mask in iio_dev - */ - - if (st->id == ad7997 || st->id == ad7998) - ad7997_8_set_scan_mode(st, *indio_dev->active_scan_mask); - - return iio_sw_buffer_preenable(indio_dev); -} - /** * ad799x_trigger_handler() bh of trigger launched polling to ring buffer * @@ -110,49 +89,13 @@ out: return IRQ_HANDLED; } -static const struct iio_buffer_setup_ops ad799x_buf_setup_ops = { - .preenable = &ad799x_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - int ret = 0; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(NULL, - &ad799x_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_kfifo; - } - - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &ad799x_buf_setup_ops; - indio_dev->buffer->scan_timestamp = true; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_deallocate_kfifo: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; + return iio_triggered_buffer_setup(indio_dev, NULL, + &ad799x_trigger_handler, NULL); } void ad799x_ring_cleanup(struct iio_dev *indio_dev) { - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); + iio_triggered_buffer_cleanup(indio_dev); } -- GitLab From 0941b9307e461570afe0378a410fb339936fad31 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:06 +0200 Subject: [PATCH 1981/6849] iio staging: fix typos in tsl*: register Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2583.c | 2 +- drivers/staging/iio/light/tsl2x7x_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 5e23ad5a30d5..6d2f4c659e56 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -410,7 +410,7 @@ static int taos_chip_on(struct iio_dev *indio_dev) return -EINVAL; } - /* determine als integration regster */ + /* determine als integration register */ als_count = (chip->taos_settings.als_time * 100 + 135) / 270; if (als_count == 0) als_count = 1; /* ensure at least one cycle */ diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 040da4acc66e..fdf75e45428c 100755 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -736,7 +736,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) return -EINVAL; } - /* determine als integration regster */ + /* determine als integration register */ als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270; if (als_count == 0) als_count = 1; /* ensure at least one cycle */ -- GitLab From 7695afdeb4dc6ae1ac7118c6ef9df7246f575923 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:05 +0200 Subject: [PATCH 1982/6849] iio staging: fix tsl2x7x file mode just drop execute permission Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 | 0 .../staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x | 0 drivers/staging/iio/light/tsl2x7x.h | 0 drivers/staging/iio/light/tsl2x7x_core.c | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 mode change 100755 => 100644 drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x mode change 100755 => 100644 drivers/staging/iio/light/tsl2x7x.h mode change 100755 => 100644 drivers/staging/iio/light/tsl2x7x_core.c diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 old mode 100755 new mode 100644 diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x old mode 100755 new mode 100644 diff --git a/drivers/staging/iio/light/tsl2x7x.h b/drivers/staging/iio/light/tsl2x7x.h old mode 100755 new mode 100644 diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c old mode 100755 new mode 100644 -- GitLab From 2a1d45ecc8cac79afe7f769f4241e4ad919c45bf Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:07 +0200 Subject: [PATCH 1983/6849] iio staging: fix spelling of suppression in isl29018 beware, does change the ABI as proximity_on_chip_ambient_infrared_supression is changed to proximity_on_chip_ambient_infrared_suppression Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Acked-by: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman --- .../iio/Documentation/sysfs-bus-iio-light | 2 +- drivers/staging/iio/light/isl29018.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light index 715c74dcb53a..d52be0385dc4 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light @@ -34,7 +34,7 @@ Description: it comes back in SI units, it should also include _input else it should include _raw to signify it is not in SI units. -What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_supression +What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_suppression KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 0abbf18d6103..31d22f5591ca 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -292,18 +292,18 @@ static ssize_t store_resolution(struct device *dev, } /* proximity scheme */ -static ssize_t show_prox_infrared_supression(struct device *dev, +static ssize_t show_prox_infrared_suppression(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); /* return the "proximity scheme" i.e. if the chip does on chip - infrared supression (1 means perform on chip supression) */ + infrared suppression (1 means perform on chip suppression) */ return sprintf(buf, "%d\n", chip->prox_scheme); } -static ssize_t store_prox_infrared_supression(struct device *dev, +static ssize_t store_prox_infrared_suppression(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -318,7 +318,7 @@ static ssize_t store_prox_infrared_supression(struct device *dev, } /* get the "proximity scheme" i.e. if the chip does on chip - infrared supression (1 means perform on chip supression) */ + infrared suppression (1 means perform on chip suppression) */ mutex_lock(&chip->lock); chip->prox_scheme = (int)lval; mutex_unlock(&chip->lock); @@ -413,10 +413,10 @@ static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000"); static IIO_CONST_ATTR(adc_resolution_available, "4 8 12 16"); static IIO_DEVICE_ATTR(adc_resolution, S_IRUGO | S_IWUSR, show_resolution, store_resolution, 0); -static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_supression, +static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_suppression, S_IRUGO | S_IWUSR, - show_prox_infrared_supression, - store_prox_infrared_supression, 0); + show_prox_infrared_suppression, + store_prox_infrared_suppression, 0); #define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) #define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) @@ -425,7 +425,7 @@ static struct attribute *isl29018_attributes[] = { ISL29018_CONST_ATTR(range_available), ISL29018_DEV_ATTR(adc_resolution), ISL29018_CONST_ATTR(adc_resolution_available), - ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_supression), + ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_suppression), NULL }; -- GitLab From 9cc113bc84e683435c110268712d25aea05b8198 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:01 +0200 Subject: [PATCH 1984/6849] iio: typo in iio_chan_spec.ext_info comment Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/iio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index ae0cad908182..2afbb6f01afc 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -214,7 +214,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * @event_mask: What events can this channel produce. * @ext_info: Array of extended info attributes for this channel. * The array is NULL terminated, the last element should - * have it's name field set to NULL. + * have its name field set to NULL. * @extend_name: Allows labeling of channel attributes with an * informative name. Note this has no effect codes etc, * unlike modifiers. -- GitLab From b90406f1e5f4cb673e331ce6d435f4bdbf2136a2 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:02 +0200 Subject: [PATCH 1985/6849] iio: correct documentation for IIO_CONST_ATTR_SAMP_FREQ_AVAIL, match name of #define Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/sysfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/iio/sysfs.h b/include/linux/iio/sysfs.h index bfedb73b850e..b7a934b9431b 100644 --- a/include/linux/iio/sysfs.h +++ b/include/linux/iio/sysfs.h @@ -97,7 +97,7 @@ struct iio_const_attr { #define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \ IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0) /** - * IIO_CONST_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies + * IIO_CONST_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies * @_string: frequency string for the attribute * * Constant version -- GitLab From 19ea4752fc1f45c778ae66443c1023aced14ba05 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:03 +0200 Subject: [PATCH 1986/6849] iio: remove extra ; after function definition Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index fb0fe46fd659..ad4fb1af0f7d 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -184,7 +184,7 @@ static inline int iio_buffer_register(struct iio_dev *indio_dev, } static inline void iio_buffer_unregister(struct iio_dev *indio_dev) -{}; +{} #endif /* CONFIG_IIO_BUFFER */ -- GitLab From d163a19d915e9bb3dfa01abc251bc4d5395dc118 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 18 Jun 2012 20:33:04 +0200 Subject: [PATCH 1987/6849] iio staging: another typo in iio_simple_dummy_buffer Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio_simple_dummy_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 3e43025f887d..fa4939caee6a 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -78,7 +78,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) i++) { j = find_next_bit(buffer->scan_mask, indio_dev->masklength, j + 1); - /* random access read form the 'device' */ + /* random access read from the 'device' */ data[i] = fakedata[j]; len += 2; } -- GitLab From 76728a93a70f23c6376c728e337fb26473737e7f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 18 Jun 2012 17:03:17 -0700 Subject: [PATCH 1988/6849] staging: comedi: pcmmio: quiet NULL pointer sparse noise The comedi_async 'inttrig' member is a pointer to a callback function. NULL should be used to clear it not 0. This quiets a number of sparse warnings about: Warning: Using plain integer as NULL pointer Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmmio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 82a60d681eb4..3d2e6f01c4b7 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -512,7 +512,7 @@ static void pcmmio_stop_intr(struct comedi_device *dev, subpriv->dio.intr.enabled_mask = 0; subpriv->dio.intr.active = 0; - s->async->inttrig = 0; + s->async->inttrig = NULL; nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; switch_page(dev, asic, PAGE_ENAB); @@ -778,7 +778,7 @@ pcmmio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, return -EINVAL; spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); - s->async->inttrig = 0; + s->async->inttrig = NULL; if (subpriv->dio.intr.active) event = pcmmio_start_intr(dev, s); spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); -- GitLab From 55232eca66c540cbef9b950e71b358137651955b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 18 Jun 2012 16:53:17 -0700 Subject: [PATCH 1989/6849] staging: comedi: comedi_compat_ioctl should be NULL not 0 When CONFIG_COMPAT is not defined, comedi_compat_ioctl should be NULL not 0 in order to set the file_operations compat_ioctl variable correctly. This quiets a sparse warning about: warning: Using plain integer as NULL pointer Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_compat32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h index 0340a8949c6b..c99573be046a 100644 --- a/drivers/staging/comedi/comedi_compat32.h +++ b/drivers/staging/comedi/comedi_compat32.h @@ -37,7 +37,7 @@ extern long comedi_compat_ioctl(struct file *file, unsigned int cmd, #else /* CONFIG_COMPAT */ -#define comedi_compat_ioctl 0 /* NULL */ +#define comedi_compat_ioctl NULL #endif /* CONFIG_COMPAT */ -- GitLab From d189634ecab947c10f6f832258b103d0bbfe73cc Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Mon, 18 Jun 2012 12:08:33 +0000 Subject: [PATCH 1990/6849] ipv6: Move ipv6 proc file registration to end of init order /proc/net/ipv6_route reflects the contents of fib_table_hash. The proc handler is installed in ip6_route_net_init() whereas fib_table_hash is allocated in fib6_net_init() _after_ the proc handler has been installed. This opens up a short time frame to access fib_table_hash with its pants down. Move the registration of the proc files to a later point in the init order to avoid the race. Tested :-) Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv6/route.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 999a982ad3fd..becb048d18d4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2957,10 +2957,6 @@ static int __net_init ip6_route_net_init(struct net *net) net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; -#ifdef CONFIG_PROC_FS - proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); - proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); -#endif net->ipv6.ip6_rt_gc_expire = 30*HZ; ret = 0; @@ -2981,10 +2977,6 @@ out_ip6_dst_ops: static void __net_exit ip6_route_net_exit(struct net *net) { -#ifdef CONFIG_PROC_FS - proc_net_remove(net, "ipv6_route"); - proc_net_remove(net, "rt6_stats"); -#endif kfree(net->ipv6.ip6_null_entry); #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.ip6_prohibit_entry); @@ -2993,11 +2985,33 @@ static void __net_exit ip6_route_net_exit(struct net *net) dst_entries_destroy(&net->ipv6.ip6_dst_ops); } +static int __net_init ip6_route_net_init_late(struct net *net) +{ +#ifdef CONFIG_PROC_FS + proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); + proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); +#endif + return 0; +} + +static void __net_exit ip6_route_net_exit_late(struct net *net) +{ +#ifdef CONFIG_PROC_FS + proc_net_remove(net, "ipv6_route"); + proc_net_remove(net, "rt6_stats"); +#endif +} + static struct pernet_operations ip6_route_net_ops = { .init = ip6_route_net_init, .exit = ip6_route_net_exit, }; +static struct pernet_operations ip6_route_net_late_ops = { + .init = ip6_route_net_init_late, + .exit = ip6_route_net_exit_late, +}; + static struct notifier_block ip6_route_dev_notifier = { .notifier_call = ip6_route_dev_notify, .priority = 0, @@ -3047,19 +3061,25 @@ int __init ip6_route_init(void) if (ret) goto xfrm6_init; + ret = register_pernet_subsys(&ip6_route_net_late_ops); + if (ret) + goto fib6_rules_init; + ret = -ENOBUFS; if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) - goto fib6_rules_init; + goto out_register_late_subsys; ret = register_netdevice_notifier(&ip6_route_dev_notifier); if (ret) - goto fib6_rules_init; + goto out_register_late_subsys; out: return ret; +out_register_late_subsys: + unregister_pernet_subsys(&ip6_route_net_late_ops); fib6_rules_init: fib6_rules_cleanup(); xfrm6_init: @@ -3078,6 +3098,7 @@ out_kmem_cache: void ip6_route_cleanup(void) { unregister_netdevice_notifier(&ip6_route_dev_notifier); + unregister_pernet_subsys(&ip6_route_net_late_ops); fib6_rules_cleanup(); xfrm6_fini(); fib6_gc_cleanup(); -- GitLab From 7c62234547255ce4c385a218915965bc2f14fe45 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 19 Jun 2012 02:10:57 +0200 Subject: [PATCH 1991/6849] netfilter: nfnetlink_queue: fix compilation with NF_CONNTRACK disabled In "9cb0176 netfilter: add glue code to integrate nfnetlink_queue and ctnetlink" the compilation with NF_CONNTRACK disabled is broken. This patch fixes this issue. I have moved the conntrack part into nfnetlink_queue_ct.c to avoid peppering the entire nfnetlink_queue.c code with ifdefs. I also needed to rename nfnetlink_queue.c to nfnetlink_queue_pkt.c to update the net/netfilter/Makefile to support conditional compilation of the conntrack integration. This patch also adds CONFIG_NETFILTER_QUEUE_CT in case you want to explicitly disable the integration between nf_conntrack and nfnetlink_queue. Reported-by: Andrew Morton Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nfnetlink_queue.h | 43 ++++++++ net/netfilter/Kconfig | 9 ++ net/netfilter/Makefile | 2 + net/netfilter/nf_conntrack_netlink.c | 11 +-- ...netlink_queue.c => nfnetlink_queue_core.c} | 49 ++-------- net/netfilter/nfnetlink_queue_ct.c | 97 +++++++++++++++++++ 6 files changed, 164 insertions(+), 47 deletions(-) create mode 100644 include/net/netfilter/nfnetlink_queue.h rename net/netfilter/{nfnetlink_queue.c => nfnetlink_queue_core.c} (95%) create mode 100644 net/netfilter/nfnetlink_queue_ct.c diff --git a/include/net/netfilter/nfnetlink_queue.h b/include/net/netfilter/nfnetlink_queue.h new file mode 100644 index 000000000000..9f8095c108e4 --- /dev/null +++ b/include/net/netfilter/nfnetlink_queue.h @@ -0,0 +1,43 @@ +#ifndef _NET_NFNL_QUEUE_H_ +#define _NET_NFNL_QUEUE_H_ + +#include + +struct nf_conn; + +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) +struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size, + enum ip_conntrack_info *ctinfo); +struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb, + const struct nlattr *attr, + enum ip_conntrack_info *ctinfo); +int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo); +void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo, int diff); +#else +inline struct nf_conn * +nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo) +{ + return NULL; +} + +inline struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb, + const struct nlattr *attr, + enum ip_conntrack_info *ctinfo) +{ + return NULL; +} + +inline int +nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo) +{ + return 0; +} + +inline void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo, int diff) +{ +} +#endif /* NF_CONNTRACK */ +#endif diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index f1a52ba3e4c5..c19b214ffd57 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -340,6 +340,7 @@ config NF_CT_NETLINK_HELPER select NETFILTER_NETLINK depends on NF_CT_NETLINK depends on NETFILTER_NETLINK_QUEUE + depends on NETFILTER_NETLINK_QUEUE_CT depends on NETFILTER_ADVANCED help This option enables the user-space connection tracking helpers @@ -347,6 +348,14 @@ config NF_CT_NETLINK_HELPER If unsure, say `N'. +config NETFILTER_NETLINK_QUEUE_CT + bool "NFQUEUE integration with Connection Tracking" + default n + depends on NETFILTER_NETLINK_QUEUE + help + If this option is enabled, NFQUEUE can include Connection Tracking + information together with the packet is the enqueued via NFNETLINK. + endif # NF_CONNTRACK # transparent proxy support diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 7cc20199fe8c..1c5160f2278e 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -9,6 +9,8 @@ obj-$(CONFIG_NETFILTER) = netfilter.o obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o +nfnetlink_queue-y := nfnetlink_queue_core.o +nfnetlink_queue-$(CONFIG_NETFILTER_NETLINK_QUEUE_CT) += nfnetlink_queue_ct.o obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 76271a1301a5..31d1d8f3a6ce 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1627,8 +1627,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; } -#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \ - defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE) +#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT static size_t ctnetlink_nfqueue_build_size(const struct nf_conn *ct) { @@ -1762,7 +1761,7 @@ static struct nfq_ct_hook ctnetlink_nfqueue_hook = { .seq_adjust = nf_nat_tcp_seq_adjust, #endif }; -#endif /* CONFIG_NETFILTER_NETLINK_QUEUE */ +#endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */ /*********************************************************************** * EXPECT @@ -2568,8 +2567,7 @@ static int __init ctnetlink_init(void) pr_err("ctnetlink_init: cannot register pernet operations\n"); goto err_unreg_exp_subsys; } -#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \ - defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE) +#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT /* setup interaction between nf_queue and nf_conntrack_netlink. */ RCU_INIT_POINTER(nfq_ct_hook, &ctnetlink_nfqueue_hook); #endif @@ -2590,8 +2588,7 @@ static void __exit ctnetlink_exit(void) unregister_pernet_subsys(&ctnetlink_net_ops); nfnetlink_subsys_unregister(&ctnl_exp_subsys); nfnetlink_subsys_unregister(&ctnl_subsys); -#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \ - defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE) +#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT RCU_INIT_POINTER(nfq_ct_hook, NULL); #endif } diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue_core.c similarity index 95% rename from net/netfilter/nfnetlink_queue.c rename to net/netfilter/nfnetlink_queue_core.c index ff82c7933dfd..d36b95ea8ca3 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue_core.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include @@ -234,7 +234,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, struct sk_buff *entskb = entry->skb; struct net_device *indev; struct net_device *outdev; - struct nfq_ct_hook *nfq_ct; struct nf_conn *ct = NULL; enum ip_conntrack_info uninitialized_var(ctinfo); @@ -270,17 +269,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, break; } - /* rcu_read_lock()ed by __nf_queue already. */ - nfq_ct = rcu_dereference(nfq_ct_hook); - if (nfq_ct != NULL && (queue->flags & NFQA_CFG_F_CONNTRACK)) { - ct = nf_ct_get(entskb, &ctinfo); - if (ct) { - if (!nf_ct_is_untracked(ct)) - size += nfq_ct->build_size(ct); - else - ct = NULL; - } - } + if (queue->flags & NFQA_CFG_F_CONNTRACK) + ct = nfqnl_ct_get(entskb, &size, &ctinfo); skb = alloc_skb(size, GFP_ATOMIC); if (!skb) @@ -404,23 +394,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, BUG(); } - if (ct) { - struct nlattr *nest_parms; - u_int32_t tmp; - - nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED); - if (!nest_parms) - goto nla_put_failure; - - if (nfq_ct->build(skb, ct) < 0) - goto nla_put_failure; - - nla_nest_end(skb, nest_parms); - - tmp = ctinfo; - if (nla_put_u32(skb, NFQA_CT_INFO, htonl(ctinfo))) - goto nla_put_failure; - } + if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0) + goto nla_put_failure; nlh->nlmsg_len = skb->tail - old_tail; return skb; @@ -764,7 +739,6 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, struct nfqnl_instance *queue; unsigned int verdict; struct nf_queue_entry *entry; - struct nfq_ct_hook *nfq_ct; enum ip_conntrack_info uninitialized_var(ctinfo); struct nf_conn *ct = NULL; @@ -786,13 +760,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, return -ENOENT; rcu_read_lock(); - nfq_ct = rcu_dereference(nfq_ct_hook); - if (nfq_ct != NULL && - (queue->flags & NFQA_CFG_F_CONNTRACK) && nfqa[NFQA_CT]) { - ct = nf_ct_get(entry->skb, &ctinfo); - if (ct && !nf_ct_is_untracked(ct)) - nfq_ct->parse(nfqa[NFQA_CT], ct); - } + if (nfqa[NFQA_CT] && (queue->flags & NFQA_CFG_F_CONNTRACK)) + ct = nfqnl_ct_parse(entry->skb, nfqa[NFQA_CT], &ctinfo); if (nfqa[NFQA_PAYLOAD]) { u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]); @@ -802,8 +771,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, payload_len, entry, diff) < 0) verdict = NF_DROP; - if (ct && (ct->status & IPS_NAT_MASK) && diff) - nfq_ct->seq_adjust(skb, ct, ctinfo, diff); + if (ct) + nfqnl_ct_seq_adjust(skb, ct, ctinfo, diff); } rcu_read_unlock(); diff --git a/net/netfilter/nfnetlink_queue_ct.c b/net/netfilter/nfnetlink_queue_ct.c new file mode 100644 index 000000000000..68ef550066f5 --- /dev/null +++ b/net/netfilter/nfnetlink_queue_ct.c @@ -0,0 +1,97 @@ +/* + * (C) 2012 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size, + enum ip_conntrack_info *ctinfo) +{ + struct nfq_ct_hook *nfq_ct; + struct nf_conn *ct; + + /* rcu_read_lock()ed by __nf_queue already. */ + nfq_ct = rcu_dereference(nfq_ct_hook); + if (nfq_ct == NULL) + return NULL; + + ct = nf_ct_get(entskb, ctinfo); + if (ct) { + if (!nf_ct_is_untracked(ct)) + *size += nfq_ct->build_size(ct); + else + ct = NULL; + } + return ct; +} + +struct nf_conn * +nfqnl_ct_parse(const struct sk_buff *skb, const struct nlattr *attr, + enum ip_conntrack_info *ctinfo) +{ + struct nfq_ct_hook *nfq_ct; + struct nf_conn *ct; + + /* rcu_read_lock()ed by __nf_queue already. */ + nfq_ct = rcu_dereference(nfq_ct_hook); + if (nfq_ct == NULL) + return NULL; + + ct = nf_ct_get(skb, ctinfo); + if (ct && !nf_ct_is_untracked(ct)) + nfq_ct->parse(attr, ct); + + return ct; +} + +int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo) +{ + struct nfq_ct_hook *nfq_ct; + struct nlattr *nest_parms; + u_int32_t tmp; + + nfq_ct = rcu_dereference(nfq_ct_hook); + if (nfq_ct == NULL) + return 0; + + nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; + + if (nfq_ct->build(skb, ct) < 0) + goto nla_put_failure; + + nla_nest_end(skb, nest_parms); + + tmp = ctinfo; + if (nla_put_be32(skb, NFQA_CT_INFO, htonl(tmp))) + goto nla_put_failure; + + return 0; + +nla_put_failure: + return -1; +} + +void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo, int diff) +{ + struct nfq_ct_hook *nfq_ct; + + nfq_ct = rcu_dereference(nfq_ct_hook); + if (nfq_ct == NULL) + return; + + if ((ct->status & IPS_NAT_MASK) && diff) + nfq_ct->seq_adjust(skb, ct, ctinfo, diff); +} -- GitLab From 33cef264cd945d64ae8cbbfc5f246661f9655483 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 18 Jun 2012 13:03:46 +0300 Subject: [PATCH 1992/6849] Bluetooth: Fix compile warnings in mgmt Commit af7985bf85840e3dc90ba108a679db044f91f00e introduced regression resulting in complie warnings: ... net/bluetooth/mgmt.c:3568:27: warning: invalid assignment: |= net/bluetooth/mgmt.c:3568:27: left side has type restricted __le32 net/bluetooth/mgmt.c:3568:27: right side has type int net/bluetooth/mgmt.c:3570:27: warning: invalid assignment: |= net/bluetooth/mgmt.c:3570:27: left side has type restricted __le32 net/bluetooth/mgmt.c:3570:27: right side has type int net/bluetooth/mgmt.c:3580:21: warning: cast from restricted __le32 ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 5aa5592ad578..eff610d5081a 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3546,9 +3546,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->addr.type = link_to_bdaddr(link_type, addr_type); ev->rssi = rssi; if (cfm_name) - ev->flags |= MGMT_DEV_FOUND_CONFIRM_NAME; + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); if (!ssp) - ev->flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); if (eir_len > 0) memcpy(ev->eir, eir, eir_len); @@ -3558,8 +3558,6 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, dev_class, 3); ev->eir_len = cpu_to_le16(eir_len); - ev->flags = cpu_to_le32(ev->flags); - ev_size = sizeof(*ev) + eir_len; return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); -- GitLab From 9345d40c580d0f3dfc040add0e6371b1a629c1cc Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 15 Jun 2012 10:36:42 +0300 Subject: [PATCH 1993/6849] Bluetooth: Use AUTO_OFF constant in jiffies Move AUTO_OFF_TIMEOUT to other constants changing name to HCI_AUTO_OFF_TIMEOUT and convert to jiffies. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 3 ++- net/bluetooth/hci_core.c | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 7dcd3495edde..ccd723e0f783 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -142,8 +142,9 @@ enum { #define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ #define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */ #define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */ -#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 seconds */ +#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ +#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ /* HCI data types */ #define HCI_COMMAND_PKT 0x01 diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a2bdf936ed46..32dcb09cdb5d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -33,8 +33,6 @@ #include #include -#define AUTO_OFF_TIMEOUT 2000 - static void hci_rx_work(struct work_struct *work); static void hci_cmd_work(struct work_struct *work); static void hci_tx_work(struct work_struct *work); @@ -1083,8 +1081,7 @@ static void hci_power_on(struct work_struct *work) return; if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) - schedule_delayed_work(&hdev->power_off, - msecs_to_jiffies(AUTO_OFF_TIMEOUT)); + schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT); if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) mgmt_index_added(hdev); -- GitLab From ea1e76a3f92f8565d395c549b9ca836c7eaa44b9 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 13 Jun 2012 13:35:44 +0300 Subject: [PATCH 1994/6849] Bluetooth: btmrvl: Do not send vendor events to bluetooth stack Vendor-specific events shall be processed in driver and not sent to bluetooth stack where they screw up HCI command countings. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_drv.h | 2 +- drivers/bluetooth/btmrvl_main.c | 14 ++++++++++++-- drivers/bluetooth/btmrvl_sdio.c | 8 +++++--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 94f2d65131c4..27068d149380 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv); void btmrvl_interrupt(struct btmrvl_private *priv); -void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); +bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 681ca9d18e12..dc304def8400 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -44,23 +44,33 @@ void btmrvl_interrupt(struct btmrvl_private *priv) } EXPORT_SYMBOL_GPL(btmrvl_interrupt); -void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) +bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; struct hci_ev_cmd_complete *ec; - u16 opcode, ocf; + u16 opcode, ocf, ogf; if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); + ogf = hci_opcode_ogf(opcode); + if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } + + if (ogf == OGF) { + BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf); + kfree_skb(skb); + return false; + } } + + return true; } EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index a853244e7fd7..0cd61d9f07cd 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -562,10 +562,12 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); - if (type == HCI_EVENT_PKT) - btmrvl_check_evtpkt(priv, skb); + if (type == HCI_EVENT_PKT) { + if (btmrvl_check_evtpkt(priv, skb)) + hci_recv_frame(skb); + } else + hci_recv_frame(skb); - hci_recv_frame(skb); hdev->stat.byte_rx += buf_len; break; -- GitLab From 92c4c2049762dc0ef2b152df8c787051db1cdf60 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 7 Jun 2012 19:05:44 -0300 Subject: [PATCH 1995/6849] Bluetooth: Use GFP_KERNEL in mgmt_handlers add_uuid and get_connections mgmt_handlers are executed by user threads running in kernel-mode. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index eff610d5081a..86590c653232 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1268,7 +1268,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) goto failed; } - uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); + uuid = kmalloc(sizeof(*uuid), GFP_KERNEL); if (!uuid) { err = -ENOMEM; goto failed; @@ -1667,7 +1667,7 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data, } rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); - rp = kmalloc(rp_len, GFP_ATOMIC); + rp = kmalloc(rp_len, GFP_KERNEL); if (!rp) { err = -ENOMEM; goto unlock; -- GitLab From 12b9456502d421a8272615fb641349eb2013b6d8 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 7 Jun 2012 19:05:45 -0300 Subject: [PATCH 1996/6849] Bluetooth: Use GFP_KERNEL in mgmt_pending_add We are allowed to sleep in mgmt_pending_add, so we should use GFP_KERNEL for memory allocations instead of GFP_ATOMIC. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 86590c653232..41b5192bc041 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -687,14 +687,14 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, { struct pending_cmd *cmd; - cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return NULL; cmd->opcode = opcode; cmd->index = hdev->id; - cmd->param = kmalloc(len, GFP_ATOMIC); + cmd->param = kmalloc(len, GFP_KERNEL); if (!cmd->param) { kfree(cmd); return NULL; -- GitLab From 790eff4429e45b850859f1bb8117846dafd5f86a Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 7 Jun 2012 19:05:46 -0300 Subject: [PATCH 1997/6849] Bluetooth: Use GFP_KERNEL in mgmt events functions cmd_status, cmd_complete and mgmt_event functions are executed in process context and they are not called inside atomic sections. Thus, they should use GFP_KERNEL for memory allocation instead of GFP_ATOMIC. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 41b5192bc041..2f9f52f19b48 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -210,7 +210,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); - skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); if (!skb) return -ENOMEM; @@ -241,7 +241,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, BT_DBG("sock %p", sk); - skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC); + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); if (!skb) return -ENOMEM; @@ -812,7 +812,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, struct sk_buff *skb; struct mgmt_hdr *hdr; - skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); + skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL); if (!skb) return -ENOMEM; -- GitLab From 674147e21195a496164e1c7ff70d0f0b45235f25 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 19 Jun 2012 05:25:46 +0200 Subject: [PATCH 1998/6849] netfilter: fix missing symbols if CONFIG_NETFILTER_NETLINK_QUEUE_CT unset ERROR: "nfqnl_ct_parse" [net/netfilter/nfnetlink_queue.ko] undefined! ERROR: "nfqnl_ct_seq_adjust" [net/netfilter/nfnetlink_queue.ko] undefined! ERROR: "nfqnl_ct_put" [net/netfilter/nfnetlink_queue.ko] undefined! ERROR: "nfqnl_ct_get" [net/netfilter/nfnetlink_queue.ko] undefined! We have to use CONFIG_NETFILTER_NETLINK_QUEUE_CT in include/net/netfilter/nfnetlink_queue.h, not CONFIG_NF_CONNTRACK. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- include/net/netfilter/nfnetlink_queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/netfilter/nfnetlink_queue.h b/include/net/netfilter/nfnetlink_queue.h index 9f8095c108e4..86267a529514 100644 --- a/include/net/netfilter/nfnetlink_queue.h +++ b/include/net/netfilter/nfnetlink_queue.h @@ -5,7 +5,7 @@ struct nf_conn; -#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) +#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo); struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb, -- GitLab From 39d84a58ad6290a43e6503acc8b54ebb7e4ecc54 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Mon, 18 Jun 2012 11:04:55 +0000 Subject: [PATCH 1999/6849] sctp: fix warning when compiling without IPv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/sctp/protocol.c: In function ‘sctp_addr_wq_timeout_handler’: net/sctp/protocol.c:676: warning: label ‘free_next’ defined but not used Signed-off-by: Daniel Halperin Signed-off-by: David S. Miller --- net/sctp/protocol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5942d27b1444..9c90811d1134 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -673,7 +673,9 @@ void sctp_addr_wq_timeout_handler(unsigned long arg) SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: sctp_asconf_mgmt failed\n"); sctp_bh_unlock_sock(sk); } +#if IS_ENABLED(CONFIG_IPV6) free_next: +#endif list_del(&addrw->list); kfree(addrw); } -- GitLab From b31525d16b50fe0eb33545afbc0be1a03f2896e3 Mon Sep 17 00:00:00 2001 From: "stigge@antcom.de" Date: Mon, 18 Jun 2012 10:14:42 +0000 Subject: [PATCH 2000/6849] net: lpc_eth: Driver cleanup This patch removes some nowadays superfluous definitions (one unused define and an obsolete function forward declaration) and corrects a netdev_err() to netdev_dbg(). Signed-off-by: Roland Stigge Signed-off-by: Alexandre Pereira da Silva Signed-off-by: David S. Miller --- drivers/net/ethernet/nxp/lpc_eth.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 028dde4d4979..e7d2496a4738 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -52,7 +52,6 @@ #define MODNAME "lpc-eth" #define DRV_VERSION "1.00" -#define PHYDEF_ADDR 0x00 #define ENET_MAXF_SIZE 1536 #define ENET_RX_DESC 48 @@ -416,9 +415,6 @@ static bool use_iram_for_net(struct device *dev) #define TXDESC_CONTROL_LAST (1 << 30) #define TXDESC_CONTROL_INT (1 << 31) -static int lpc_eth_hard_start_xmit(struct sk_buff *skb, - struct net_device *ndev); - /* * Structure of a TX/RX descriptors and RX status */ @@ -1441,7 +1437,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) res->start); netdev_dbg(ndev, "IO address size :%d\n", res->end - res->start + 1); - netdev_err(ndev, "IO address (mapped) :0x%p\n", + netdev_dbg(ndev, "IO address (mapped) :0x%p\n", pldat->net_base); netdev_dbg(ndev, "IRQ number :%d\n", ndev->irq); netdev_dbg(ndev, "DMA buffer size :%d\n", pldat->dma_buff_size); -- GitLab From 48d7d0ad9022b36be9fd8a236fb58ad4c0f3b80c Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Sun, 17 Jun 2012 22:52:09 +0000 Subject: [PATCH 2001/6849] phy/micrel: change phy_id_mask for KSZ9021 and KS8001 On a freescale imx6q platform, a hardware phy chip KSZ9021 is recognized as a KS8001 chip by the current driver like this: eth0: Freescale FEC PHY driver [Micrel KS8001 or KS8721] KSZ9021 has phy_id 0x00221610, while KSZ8001 has phy_id 0x0022161a, the current phy_id_mask (0x00fffff0/0x00ffff10) can't distinguish them. So change phy_id_mask to resolve this problem. Although the micrel datasheet says that the 4 LSB of phyid2 register contains the chip revision number and the current driver is designed to follow this rule, in reality the chip implementation doesn't follow it. Cc: David J. Choi Cc: David S. Miller Cc: Nobuhiro Iwamatsu Signed-off-by: Hui Wang Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 590f902deb6b..9d6c80c8a0cf 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -161,7 +161,7 @@ static struct phy_driver ks8051_driver = { static struct phy_driver ks8001_driver = { .phy_id = PHY_ID_KS8001, .name = "Micrel KS8001 or KS8721", - .phy_id_mask = 0x00fffff0, + .phy_id_mask = 0x00ffffff, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, @@ -174,7 +174,7 @@ static struct phy_driver ks8001_driver = { static struct phy_driver ksz9021_driver = { .phy_id = PHY_ID_KSZ9021, - .phy_id_mask = 0x000fff10, + .phy_id_mask = 0x000ffffe, .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), @@ -240,8 +240,8 @@ MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); static struct mdio_device_id __maybe_unused micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000fff10 }, - { PHY_ID_KS8001, 0x00fffff0 }, + { PHY_ID_KSZ9021, 0x000ffffe }, + { PHY_ID_KS8001, 0x00ffffff }, { PHY_ID_KS8737, 0x00fffff0 }, { PHY_ID_KS8041, 0x00fffff0 }, { PHY_ID_KS8051, 0x00fffff0 }, -- GitLab From 632a5b01db8cd4068a06f8a67720ea4f9b00d9b3 Mon Sep 17 00:00:00 2001 From: Krystian Garbaciak Date: Mon, 18 Jun 2012 13:04:29 +0100 Subject: [PATCH 2002/6849] regmap: Fix work_buf switching for page update during virtual range access. After page update, orginal work_buf has to be restored regardless of the result. Signed-off-by: Krystian Garbaciak Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 83a0166420a4..d912eb2d19ce 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -693,10 +693,11 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg, range->selector_mask, win_page << range->selector_shift, &page_chg); - if (ret < 0) - return ret; map->work_buf = orig_work_buf; + + if (ret < 0) + return ret; } *reg = range->window_start + win_offset; -- GitLab From 2c19ad43d1a4b0e376a0c764e3c2350afd018fac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 19 Jun 2012 14:19:57 +0800 Subject: [PATCH 2003/6849] regulator: mc13xxx: Remove mc13xxx_sw_regulator_is_enabled function If .is_enabled callback is not implemented, regulator core assumes that the regulator is always on. Thus we don't need mc13xxx_sw_regulator_is_enabled function. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/mc13892-regulator.c | 1 - drivers/regulator/mc13xxx-regulator-core.c | 6 ------ drivers/regulator/mc13xxx.h | 1 - 3 files changed, 8 deletions(-) diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 6329723b5372..b388b746452e 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -469,7 +469,6 @@ err: } static struct regulator_ops mc13892_sw_regulator_ops = { - .is_enabled = mc13xxx_sw_regulator_is_enabled, .list_voltage = regulator_list_voltage_table, .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, .get_voltage = mc13892_sw_regulator_get_voltage, diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 8a6b050ff5aa..d6eda28ca5d0 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -170,12 +170,6 @@ struct regulator_ops mc13xxx_fixed_regulator_ops = { }; EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); -int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev) -{ - return 1; -} -EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled); - #ifdef CONFIG_OF int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) { diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h index 9a8f72ce718e..8343a25888d2 100644 --- a/drivers/regulator/mc13xxx.h +++ b/drivers/regulator/mc13xxx.h @@ -33,7 +33,6 @@ struct mc13xxx_regulator_priv { }; extern int mc13xxx_sw_regulator(struct regulator_dev *rdev); -extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev); extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector); extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev); -- GitLab From ba3bd8a301c76838faded10dbe2ecdfdc2eb5d7e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 19 Jun 2012 17:12:18 +0800 Subject: [PATCH 2004/6849] regulator: tps65023: Convert to regulator_list_voltage_table In current mapping table settings, min_uV/max_uV are always equal to volt_table[0] and volt_table[table_len -1]. Thus remove min_uV and max_uV from struct tps_info. The table based mapping with table_len == 1 means fixed voltage. So we don't need fixed flag to differentiate if it is fixed or not. This patch adds DCDC_FIXED_3300000_VSEL_table and DCDC_FIXED_1800000_VSEL_table for fixed voltage cases. So we can convert tps65023_dcdc_ops to regulator_list_voltage_table. This makes the code simpler. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 153 ++++++++----------------- 1 file changed, 49 insertions(+), 104 deletions(-) diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index df8b70d76f9e..45f4eeb221f7 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -91,48 +91,53 @@ #define TPS65023_MAX_REG_ID TPS65023_LDO_2 /* Supported voltage values for regulators */ -static const u16 VCORE_VSEL_table[] = { - 800, 825, 850, 875, - 900, 925, 950, 975, - 1000, 1025, 1050, 1075, - 1100, 1125, 1150, 1175, - 1200, 1225, 1250, 1275, - 1300, 1325, 1350, 1375, - 1400, 1425, 1450, 1475, - 1500, 1525, 1550, 1600, +static const unsigned int VCORE_VSEL_table[] = { + 800000, 825000, 850000, 875000, + 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, + 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, + 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, + 1500000, 1525000, 1550000, 1600000, +}; + +static const unsigned int DCDC_FIXED_3300000_VSEL_table[] = { + 3300000, +}; + +static const unsigned int DCDC_FIXED_1800000_VSEL_table[] = { + 1800000, }; /* Supported voltage values for LDO regulators for tps65020 */ -static const u16 TPS65020_LDO1_VSEL_table[] = { - 1000, 1050, 1100, 1300, - 1800, 2500, 3000, 3300, +static const unsigned int TPS65020_LDO1_VSEL_table[] = { + 1000000, 1050000, 1100000, 1300000, + 1800000, 2500000, 3000000, 3300000, }; -static const u16 TPS65020_LDO2_VSEL_table[] = { - 1000, 1050, 1100, 1300, - 1800, 2500, 3000, 3300, +static const unsigned int TPS65020_LDO2_VSEL_table[] = { + 1000000, 1050000, 1100000, 1300000, + 1800000, 2500000, 3000000, 3300000, }; /* Supported voltage values for LDO regulators * for tps65021 and tps65023 */ -static const u16 TPS65023_LDO1_VSEL_table[] = { - 1000, 1100, 1300, 1800, - 2200, 2600, 2800, 3150, +static const unsigned int TPS65023_LDO1_VSEL_table[] = { + 1000000, 1100000, 1300000, 1800000, + 2200000, 2600000, 2800000, 3150000, }; -static const u16 TPS65023_LDO2_VSEL_table[] = { - 1050, 1200, 1300, 1800, - 2500, 2800, 3000, 3300, +static const unsigned int TPS65023_LDO2_VSEL_table[] = { + 1050000, 1200000, 1300000, 1800000, + 2500000, 2800000, 3000000, 3300000, }; /* Regulator specific details */ struct tps_info { const char *name; - unsigned min_uV; - unsigned max_uV; - bool fixed; u8 table_len; - const u16 *table; + const unsigned int *table; }; /* PMIC details */ @@ -164,9 +169,9 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) if (ret != 0) return ret; data &= (tps->info[dcdc]->table_len - 1); - return tps->info[dcdc]->table[data] * 1000; + return tps->info[dcdc]->table[data]; } else - return tps->info[dcdc]->min_uV; + return tps->info[dcdc]->table[0]; } static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, @@ -208,7 +213,7 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev) data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)); data &= (tps->info[ldo]->table_len - 1); - return tps->info[ldo]->table[data] * 1000; + return tps->info[ldo]->table[data]; } static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, @@ -222,39 +227,6 @@ static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index)); } -static int tps65023_dcdc_list_voltage(struct regulator_dev *dev, - unsigned selector) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int dcdc = rdev_get_id(dev); - - if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) - return -EINVAL; - - if (dcdc == tps->core_regulator) { - if (selector >= tps->info[dcdc]->table_len) - return -EINVAL; - else - return tps->info[dcdc]->table[selector] * 1000; - } else - return tps->info[dcdc]->min_uV; -} - -static int tps65023_ldo_list_voltage(struct regulator_dev *dev, - unsigned selector) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int ldo = rdev_get_id(dev); - - if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) - return -EINVAL; - - if (selector >= tps->info[ldo]->table_len) - return -EINVAL; - else - return tps->info[ldo]->table[selector] * 1000; -} - /* Operations permitted on VDCDCx */ static struct regulator_ops tps65023_dcdc_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -262,7 +234,7 @@ static struct regulator_ops tps65023_dcdc_ops = { .disable = regulator_disable_regmap, .get_voltage = tps65023_dcdc_get_voltage, .set_voltage_sel = tps65023_dcdc_set_voltage_sel, - .list_voltage = tps65023_dcdc_list_voltage, + .list_voltage = regulator_list_voltage_table, }; /* Operations permitted on LDOx */ @@ -272,7 +244,7 @@ static struct regulator_ops tps65023_ldo_ops = { .disable = regulator_disable_regmap, .get_voltage = tps65023_ldo_get_voltage, .set_voltage_sel = tps65023_ldo_set_voltage_sel, - .list_voltage = tps65023_ldo_list_voltage, + .list_voltage = regulator_list_voltage_table, }; static struct regmap_config tps65023_regmap_config = { @@ -324,10 +296,8 @@ static int __devinit tps_65023_probe(struct i2c_client *client, tps->desc[i].name = info->name; tps->desc[i].id = i; - if (info->fixed) - tps->desc[i].n_voltages = 1; - else - tps->desc[i].n_voltages = info->table_len; + tps->desc[i].n_voltages = info->table_len; + tps->desc[i].volt_table = info->table; tps->desc[i].ops = (i > TPS65023_DCDC_3 ? &tps65023_ldo_ops : &tps65023_dcdc_ops); tps->desc[i].type = REGULATOR_VOLTAGE; @@ -387,35 +357,26 @@ static int __devexit tps_65023_remove(struct i2c_client *client) static const struct tps_info tps65020_regs[] = { { .name = "VDCDC1", - .min_uV = 3300000, - .max_uV = 3300000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), + .table = DCDC_FIXED_3300000_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 1800000, - .max_uV = 1800000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), + .table = DCDC_FIXED_1800000_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 800000, - .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, - { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table), .table = TPS65020_LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 1050000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table), .table = TPS65020_LDO2_VSEL_table, }, @@ -424,34 +385,26 @@ static const struct tps_info tps65020_regs[] = { static const struct tps_info tps65021_regs[] = { { .name = "VDCDC1", - .min_uV = 3300000, - .max_uV = 3300000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), + .table = DCDC_FIXED_3300000_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 1800000, - .max_uV = 1800000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), + .table = DCDC_FIXED_1800000_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 800000, - .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), .table = TPS65023_LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 1050000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), .table = TPS65023_LDO2_VSEL_table, }, @@ -460,34 +413,26 @@ static const struct tps_info tps65021_regs[] = { static const struct tps_info tps65023_regs[] = { { .name = "VDCDC1", - .min_uV = 800000, - .max_uV = 1600000, .table_len = ARRAY_SIZE(VCORE_VSEL_table), .table = VCORE_VSEL_table, }, { .name = "VDCDC2", - .min_uV = 3300000, - .max_uV = 3300000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), + .table = DCDC_FIXED_3300000_VSEL_table, }, { .name = "VDCDC3", - .min_uV = 1800000, - .max_uV = 1800000, - .fixed = 1, + .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), + .table = DCDC_FIXED_1800000_VSEL_table, }, { .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3150000, .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), .table = TPS65023_LDO1_VSEL_table, }, { .name = "LDO2", - .min_uV = 1050000, - .max_uV = 3300000, .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), .table = TPS65023_LDO2_VSEL_table, }, -- GitLab From a133829e66d25e1ce293a30bcc3fb8eb653a1519 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 19 Jun 2012 17:13:13 +0800 Subject: [PATCH 2005/6849] regulator: tps65023: Convert to get_voltage_sel Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 45f4eeb221f7..4b6f1b2b9481 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -155,7 +155,7 @@ struct tps_driver_data { u8 core_regulator; }; -static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) +static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev) { struct tps_pmic *tps = rdev_get_drvdata(dev); int ret; @@ -169,9 +169,9 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) if (ret != 0) return ret; data &= (tps->info[dcdc]->table_len - 1); - return tps->info[dcdc]->table[data]; + return data; } else - return tps->info[dcdc]->table[0]; + return 0; } static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, @@ -198,7 +198,7 @@ out: return ret; } -static int tps65023_ldo_get_voltage(struct regulator_dev *dev) +static int tps65023_ldo_get_voltage_sel(struct regulator_dev *dev) { struct tps_pmic *tps = rdev_get_drvdata(dev); int data, ldo = rdev_get_id(dev); @@ -213,7 +213,7 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev) data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)); data &= (tps->info[ldo]->table_len - 1); - return tps->info[ldo]->table[data]; + return data; } static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, @@ -232,7 +232,7 @@ static struct regulator_ops tps65023_dcdc_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage = tps65023_dcdc_get_voltage, + .get_voltage_sel = tps65023_dcdc_get_voltage_sel, .set_voltage_sel = tps65023_dcdc_set_voltage_sel, .list_voltage = regulator_list_voltage_table, }; @@ -242,7 +242,7 @@ static struct regulator_ops tps65023_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage = tps65023_ldo_get_voltage, + .get_voltage_sel = tps65023_ldo_get_voltage_sel, .set_voltage_sel = tps65023_ldo_set_voltage_sel, .list_voltage = regulator_list_voltage_table, }; -- GitLab From 852abad238da723efac29f3e78dd768c18d6a062 Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Tue, 19 Jun 2012 13:23:42 +0530 Subject: [PATCH 2006/6849] regulator: max77686: Convert driver to use regulator_set_voltage_time_sel. This patch converts the driver to use regulator_set_voltage_time_sel() as .set_voltage_time_sel() callback. It also sets ramp_delay as 100000 uV/us for LDOs & normal BUCKs and 27500 uV/us(default/reset value) for BUCKs[2/3/4] in regulator_desc[]. Signed-off-by: Yadwinder Singh Brar Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 42 ++++++++---------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 2dd4ac91d283..a29eee33dd7b 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -40,6 +40,8 @@ #define MAX77686_LDO_LOW_UVSTEP 25000 #define MAX77686_BUCK_MINUV 750000 #define MAX77686_BUCK_UVSTEP 50000 +#define MAX77686_RAMP_DELAY 100000 /* uV/us */ +#define MAX77686_DVS_RAMP_DELAY 27500 /* uV/us */ #define MAX77686_DVS_MINUV 600000 #define MAX77686_DVS_UVSTEP 12500 @@ -66,28 +68,8 @@ struct max77686_data { struct device *dev; struct max77686_dev *iodev; struct regulator_dev **rdev; - int ramp_delay; /* in mV/us */ }; -static int max77686_set_dvs_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, unsigned int new_selector) -{ - struct max77686_data *max77686 = rdev_get_drvdata(rdev); - int ramp_rate[] = {13, 27, 55, 100}; - - return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), - ramp_rate[max77686->ramp_delay] * 1000); -} - -static int max77686_set_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, unsigned int new_selector) -{ - /* Unconditionally 100 mV/us */ - return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), 100 * 1000); -} - static struct regulator_ops max77686_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, @@ -96,7 +78,7 @@ static struct regulator_ops max77686_ops = { .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_voltage_time_sel = max77686_set_voltage_time_sel, + .set_voltage_time_sel = regulator_set_voltage_time_sel, }; static struct regulator_ops max77686_buck_dvs_ops = { @@ -107,7 +89,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_voltage_time_sel = max77686_set_dvs_voltage_time_sel, + .set_voltage_time_sel = regulator_set_voltage_time_sel, }; #define regulator_desc_ldo(num) { \ @@ -118,6 +100,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .owner = THIS_MODULE, \ .min_uV = MAX77686_LDO_MINUV, \ .uV_step = MAX77686_LDO_UVSTEP, \ + .ramp_delay = MAX77686_RAMP_DELAY, \ .n_voltages = MAX77686_VSEL_MASK + 1, \ .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ .vsel_mask = MAX77686_VSEL_MASK, \ @@ -133,6 +116,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .owner = THIS_MODULE, \ .min_uV = MAX77686_LDO_LOW_MINUV, \ .uV_step = MAX77686_LDO_LOW_UVSTEP, \ + .ramp_delay = MAX77686_RAMP_DELAY, \ .n_voltages = MAX77686_VSEL_MASK + 1, \ .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ .vsel_mask = MAX77686_VSEL_MASK, \ @@ -148,6 +132,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .owner = THIS_MODULE, \ .min_uV = MAX77686_BUCK_MINUV, \ .uV_step = MAX77686_BUCK_UVSTEP, \ + .ramp_delay = MAX77686_RAMP_DELAY, \ .n_voltages = MAX77686_VSEL_MASK + 1, \ .vsel_reg = MAX77686_REG_BUCK5OUT + (num - 5) * 2, \ .vsel_mask = MAX77686_VSEL_MASK, \ @@ -162,6 +147,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .owner = THIS_MODULE, \ .min_uV = MAX77686_BUCK_MINUV, \ .uV_step = MAX77686_BUCK_UVSTEP, \ + .ramp_delay = MAX77686_RAMP_DELAY, \ .n_voltages = MAX77686_VSEL_MASK + 1, \ .vsel_reg = MAX77686_REG_BUCK1OUT, \ .vsel_mask = MAX77686_VSEL_MASK, \ @@ -176,6 +162,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .owner = THIS_MODULE, \ .min_uV = MAX77686_DVS_MINUV, \ .uV_step = MAX77686_DVS_UVSTEP, \ + .ramp_delay = MAX77686_DVS_RAMP_DELAY, \ .n_voltages = MAX77686_DVS_VSEL_MASK + 1, \ .vsel_reg = MAX77686_REG_BUCK2DVS1 + (num - 2) * 10, \ .vsel_mask = MAX77686_DVS_VSEL_MASK, \ @@ -255,17 +242,6 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) max77686->iodev = iodev; platform_set_drvdata(pdev, max77686); - max77686->ramp_delay = RAMP_RATE_NO_CTRL; /* Set 0x3 for RAMP */ - regmap_update_bits(max77686->iodev->regmap, - MAX77686_REG_BUCK2CTRL1, MAX77686_RAMP_RATE_MASK, - max77686->ramp_delay << 6); - regmap_update_bits(max77686->iodev->regmap, - MAX77686_REG_BUCK3CTRL1, MAX77686_RAMP_RATE_MASK, - max77686->ramp_delay << 6); - regmap_update_bits(max77686->iodev->regmap, - MAX77686_REG_BUCK4CTRL1, MAX77686_RAMP_RATE_MASK, - max77686->ramp_delay << 6); - for (i = 0; i < MAX77686_REGULATORS; i++) { config.dev = max77686->dev; config.regmap = iodev->regmap; -- GitLab From c848bc8538cd29e92223d5e72e8fb60e6f2e176e Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Mon, 18 Jun 2012 09:49:20 +0900 Subject: [PATCH 2007/6849] regulator: s5m8767a: Support AP watchdog reset operation The S5M8767A can't know status of ap reset. So, After AP watchdog reset, AP can't boot normally. Problem can be happened like below condition. - AP Bootable lowest voltage(vdd_arm): 0.9v - AP DVFS voltage table: 0.8v, 0.9v, 1.0v - During AP works on lowest voltage(0.8V), watchdog reset is asserted - AP can't boot, because vdd arm is still 0.8v Solution - Basic concept: After ap watchdog reset, GPIO configuration is changed by default value - S5M8767A has function of voltage control with gpio (8 levels with 3 gpios) - Set bootable voltage on level 0 -> can work with default gpio configuration - In the probing, Change voltage control level from level 0 to level 1 - Execute normal dvfs operation on level 1 - After watchdog reset, ap gpio is set by default value - PMIC operation mode is changed by ap reset (level1 -> level0) - Regardless of previous vdd_arm voltage, AP always can be booted. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 137 ++++++++++++++++++--------- include/linux/mfd/s5m87xx/s5m-core.h | 5 + 2 files changed, 98 insertions(+), 44 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index a4a3c7eefd1f..fd89574c405c 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -41,6 +41,7 @@ struct s5m8767_info { u8 buck3_vol[8]; u8 buck4_vol[8]; int buck_gpios[3]; + int buck_ds[3]; int buck_gpioindex; }; @@ -283,17 +284,17 @@ static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) reg = S5M8767_REG_BUCK1CTRL2; break; case S5M8767_BUCK2: - reg = S5M8767_REG_BUCK2DVS1; + reg = S5M8767_REG_BUCK2DVS2; if (s5m8767->buck2_gpiodvs) reg += s5m8767->buck_gpioindex; break; case S5M8767_BUCK3: - reg = S5M8767_REG_BUCK3DVS1; + reg = S5M8767_REG_BUCK3DVS2; if (s5m8767->buck3_gpiodvs) reg += s5m8767->buck_gpioindex; break; case S5M8767_BUCK4: - reg = S5M8767_REG_BUCK4DVS1; + reg = S5M8767_REG_BUCK4DVS2; if (s5m8767->buck4_gpiodvs) reg += s5m8767->buck_gpioindex; break; @@ -512,7 +513,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) struct regulator_config config = { }; struct regulator_dev **rdev; struct s5m8767_info *s5m8767; - int i, ret, size; + int i, ret, size, buck_init; if (!pdata) { dev_err(pdev->dev.parent, "Platform data not supplied\n"); @@ -563,12 +564,37 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) s5m8767->buck_gpios[0] = pdata->buck_gpios[0]; s5m8767->buck_gpios[1] = pdata->buck_gpios[1]; s5m8767->buck_gpios[2] = pdata->buck_gpios[2]; + s5m8767->buck_ds[0] = pdata->buck_ds[0]; + s5m8767->buck_ds[1] = pdata->buck_ds[1]; + s5m8767->buck_ds[2] = pdata->buck_ds[2]; + s5m8767->ramp_delay = pdata->buck_ramp_delay; s5m8767->buck2_ramp = pdata->buck2_ramp_enable; s5m8767->buck3_ramp = pdata->buck3_ramp_enable; s5m8767->buck4_ramp = pdata->buck4_ramp_enable; s5m8767->opmode = pdata->opmode; + buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, + pdata->buck2_init, + pdata->buck2_init + + buck_voltage_val2.step); + + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS2, buck_init); + + buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, + pdata->buck3_init, + pdata->buck3_init + + buck_voltage_val2.step); + + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS2, buck_init); + + buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, + pdata->buck4_init, + pdata->buck4_init + + buck_voltage_val2.step); + + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS2, buck_init); + for (i = 0; i < 8; i++) { if (s5m8767->buck2_gpiodvs) { s5m8767->buck2_vol[i] = @@ -598,48 +624,71 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) } } - if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || - pdata->buck4_gpiodvs) { - if (gpio_is_valid(pdata->buck_gpios[0]) && - gpio_is_valid(pdata->buck_gpios[1]) && - gpio_is_valid(pdata->buck_gpios[2])) { - ret = gpio_request(pdata->buck_gpios[0], - "S5M8767 SET1"); - if (ret == -EBUSY) - dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n"); - - ret = gpio_request(pdata->buck_gpios[1], - "S5M8767 SET2"); - if (ret == -EBUSY) - dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n"); - - ret = gpio_request(pdata->buck_gpios[2], - "S5M8767 SET3"); - if (ret == -EBUSY) - dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n"); - /* SET1 GPIO */ - gpio_direction_output(pdata->buck_gpios[0], - (s5m8767->buck_gpioindex >> 2) & 0x1); - /* SET2 GPIO */ - gpio_direction_output(pdata->buck_gpios[1], - (s5m8767->buck_gpioindex >> 1) & 0x1); - /* SET3 GPIO */ - gpio_direction_output(pdata->buck_gpios[2], - (s5m8767->buck_gpioindex >> 0) & 0x1); - ret = 0; - } else { - dev_err(&pdev->dev, "GPIO NOT VALID\n"); - ret = -EINVAL; - return ret; - } + if (gpio_is_valid(pdata->buck_gpios[0]) && + gpio_is_valid(pdata->buck_gpios[1]) && + gpio_is_valid(pdata->buck_gpios[2])) { + ret = gpio_request(pdata->buck_gpios[0], "S5M8767 SET1"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request" + " for SET1\n"); + + ret = gpio_request(pdata->buck_gpios[1], "S5M8767 SET2"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request" + " for SET2\n"); + + ret = gpio_request(pdata->buck_gpios[2], "S5M8767 SET3"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request" + " for SET3\n"); + /* SET1 GPIO */ + gpio_direction_output(pdata->buck_gpios[0], + (s5m8767->buck_gpioindex >> 2) & 0x1); + /* SET2 GPIO */ + gpio_direction_output(pdata->buck_gpios[1], + (s5m8767->buck_gpioindex >> 1) & 0x1); + /* SET3 GPIO */ + gpio_direction_output(pdata->buck_gpios[2], + (s5m8767->buck_gpioindex >> 0) & 0x1); + ret = 0; + + } else { + dev_err(&pdev->dev, "GPIO NOT VALID\n"); + ret = -EINVAL; + return ret; } - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, - (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, - (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); - s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, - (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + ret = gpio_request(pdata->buck_ds[0], "S5M8767 DS2"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for DS2\n"); + + ret = gpio_request(pdata->buck_ds[1], "S5M8767 DS3"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for DS3\n"); + + ret = gpio_request(pdata->buck_ds[2], "S5M8767 DS4"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for DS4\n"); + + /* DS2 GPIO */ + gpio_direction_output(pdata->buck_ds[0], 0x0); + /* DS3 GPIO */ + gpio_direction_output(pdata->buck_ds[1], 0x0); + /* DS4 GPIO */ + gpio_direction_output(pdata->buck_ds[2], 0x0); + + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || + pdata->buck4_gpiodvs) { + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), + 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), + 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), + 1 << 1); + } /* Initialize GPIO DVS registers */ for (i = 0; i < 8; i++) { diff --git a/include/linux/mfd/s5m87xx/s5m-core.h b/include/linux/mfd/s5m87xx/s5m-core.h index 21603b42f22f..0b2e0ed309f5 100644 --- a/include/linux/mfd/s5m87xx/s5m-core.h +++ b/include/linux/mfd/s5m87xx/s5m-core.h @@ -347,6 +347,7 @@ struct s5m_platform_data { bool buck_voltage_lock; int buck_gpios[3]; + int buck_ds[3]; int buck2_voltage[8]; bool buck2_gpiodvs; int buck3_voltage[8]; @@ -369,6 +370,10 @@ struct s5m_platform_data { bool buck2_ramp_enable; bool buck3_ramp_enable; bool buck4_ramp_enable; + + int buck2_init; + int buck3_init; + int buck4_init; }; #endif /* __LINUX_MFD_S5M_CORE_H */ -- GitLab From e90a84473ee941c0056c773923e9cc90a550c266 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 19 Jun 2012 17:14:31 +0800 Subject: [PATCH 2008/6849] regulator: tps65023: Convert tps65023_ldo_ops to regulator_[get|set]_voltage_sel_regmap Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 51 +++++++------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 4b6f1b2b9481..6998d579d07b 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -69,10 +69,6 @@ #define TPS65023_REG_CTRL2_DCDC1 BIT(1) #define TPS65023_REG_CTRL2_DCDC3 BIT(0) -/* LDO_CTRL bitfields */ -#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) -#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4)) - /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 /* Number of LDO voltage regulators available */ @@ -198,35 +194,6 @@ out: return ret; } -static int tps65023_ldo_get_voltage_sel(struct regulator_dev *dev) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int data, ldo = rdev_get_id(dev); - int ret; - - if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) - return -EINVAL; - - ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data); - if (ret != 0) - return ret; - - data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)); - data &= (tps->info[ldo]->table_len - 1); - return data; -} - -static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) -{ - struct tps_pmic *tps = rdev_get_drvdata(dev); - int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1; - - return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL, - TPS65023_LDO_CTRL_LDOx_MASK(ldo_index), - selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index)); -} - /* Operations permitted on VDCDCx */ static struct regulator_ops tps65023_dcdc_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -242,8 +209,8 @@ static struct regulator_ops tps65023_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .get_voltage_sel = tps65023_ldo_get_voltage_sel, - .set_voltage_sel = tps65023_ldo_set_voltage_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_table, }; @@ -304,13 +271,21 @@ static int __devinit tps_65023_probe(struct i2c_client *client, tps->desc[i].owner = THIS_MODULE; tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL; - if (i == TPS65023_LDO_1) + switch (i) { + case TPS65023_LDO_1: + tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; + tps->desc[i].vsel_mask = 0x07; tps->desc[i].enable_mask = 1 << 1; - else if (i == TPS65023_LDO_2) + break; + case TPS65023_LDO_2: + tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; + tps->desc[i].vsel_mask = 0x70; tps->desc[i].enable_mask = 1 << 2; - else /* DCDCx */ + break; + default: /* DCDCx */ tps->desc[i].enable_mask = 1 << (TPS65023_NUM_REGULATOR - i); + } config.dev = &client->dev; config.init_data = init_data; -- GitLab From 629b15b95d5b12a47791147b7559eacbad04d507 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 18 Jun 2012 21:09:04 +0100 Subject: [PATCH 2009/6849] ASoC: wm5100: Remove stubs of ASoC-level register map code Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 3823af362912..f4817292ef45 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2378,13 +2378,6 @@ static int wm5100_remove(struct snd_soc_codec *codec) return 0; } -static int wm5100_soc_volatile(struct snd_soc_codec *codec, - unsigned int reg) -{ - return true; -} - - static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { .probe = wm5100_probe, .remove = wm5100_remove, @@ -2392,8 +2385,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { .set_sysclk = wm5100_set_sysclk, .set_pll = wm5100_set_fll, .idle_bias_off = 1, - .reg_cache_size = WM5100_MAX_REGISTER, - .volatile_register = wm5100_soc_volatile, .seq_notifier = wm5100_seq_notifier, .controls = wm5100_snd_controls, -- GitLab From 081f323bd3cc3a4d5ee6276e53cc52eddfc20a63 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 1 Jun 2012 20:20:24 +1000 Subject: [PATCH 2010/6849] KVM: PPC: Book3S HV: Drop locks around call to kvmppc_pin_guest_page At the moment we call kvmppc_pin_guest_page() in kvmppc_update_vpa() with two spinlocks held: the vcore lock and the vcpu->vpa_update_lock. This is not good, since kvmppc_pin_guest_page() calls down_read() and get_user_pages_fast(), both of which can sleep. This bug was introduced in 2e25aa5f ("KVM: PPC: Book3S HV: Make virtual processor area registration more robust"). This arranges to drop those spinlocks before calling kvmppc_pin_guest_page() and re-take them afterwards. Dropping the vcore lock in kvmppc_run_core() means we have to set the vcore_state field to VCORE_RUNNING before we drop the lock, so that other vcpus won't try to run this vcore. Signed-off-by: Paul Mackerras Acked-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_hv.c | 96 +++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index c6af1d623839..3abe1b86e583 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -268,24 +268,45 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, return err; } -static void kvmppc_update_vpa(struct kvm *kvm, struct kvmppc_vpa *vpap) +static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap) { + struct kvm *kvm = vcpu->kvm; void *va; unsigned long nb; + unsigned long gpa; - vpap->update_pending = 0; - va = NULL; - if (vpap->next_gpa) { - va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb); - if (nb < vpap->len) { - /* - * If it's now too short, it must be that userspace - * has changed the mappings underlying guest memory, - * so unregister the region. - */ + /* + * We need to pin the page pointed to by vpap->next_gpa, + * but we can't call kvmppc_pin_guest_page under the lock + * as it does get_user_pages() and down_read(). So we + * have to drop the lock, pin the page, then get the lock + * again and check that a new area didn't get registered + * in the meantime. + */ + for (;;) { + gpa = vpap->next_gpa; + spin_unlock(&vcpu->arch.vpa_update_lock); + va = NULL; + nb = 0; + if (gpa) + va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb); + spin_lock(&vcpu->arch.vpa_update_lock); + if (gpa == vpap->next_gpa) + break; + /* sigh... unpin that one and try again */ + if (va) kvmppc_unpin_guest_page(kvm, va); - va = NULL; - } + } + + vpap->update_pending = 0; + if (va && nb < vpap->len) { + /* + * If it's now too short, it must be that userspace + * has changed the mappings underlying guest memory, + * so unregister the region. + */ + kvmppc_unpin_guest_page(kvm, va); + va = NULL; } if (vpap->pinned_addr) kvmppc_unpin_guest_page(kvm, vpap->pinned_addr); @@ -296,20 +317,18 @@ static void kvmppc_update_vpa(struct kvm *kvm, struct kvmppc_vpa *vpap) static void kvmppc_update_vpas(struct kvm_vcpu *vcpu) { - struct kvm *kvm = vcpu->kvm; - spin_lock(&vcpu->arch.vpa_update_lock); if (vcpu->arch.vpa.update_pending) { - kvmppc_update_vpa(kvm, &vcpu->arch.vpa); + kvmppc_update_vpa(vcpu, &vcpu->arch.vpa); init_vpa(vcpu, vcpu->arch.vpa.pinned_addr); } if (vcpu->arch.dtl.update_pending) { - kvmppc_update_vpa(kvm, &vcpu->arch.dtl); + kvmppc_update_vpa(vcpu, &vcpu->arch.dtl); vcpu->arch.dtl_ptr = vcpu->arch.dtl.pinned_addr; vcpu->arch.dtl_index = 0; } if (vcpu->arch.slb_shadow.update_pending) - kvmppc_update_vpa(kvm, &vcpu->arch.slb_shadow); + kvmppc_update_vpa(vcpu, &vcpu->arch.slb_shadow); spin_unlock(&vcpu->arch.vpa_update_lock); } @@ -800,12 +819,39 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc) struct kvm_vcpu *vcpu, *vcpu0, *vnext; long ret; u64 now; - int ptid, i; + int ptid, i, need_vpa_update; /* don't start if any threads have a signal pending */ - list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) + need_vpa_update = 0; + list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { if (signal_pending(vcpu->arch.run_task)) return 0; + need_vpa_update |= vcpu->arch.vpa.update_pending | + vcpu->arch.slb_shadow.update_pending | + vcpu->arch.dtl.update_pending; + } + + /* + * Initialize *vc, in particular vc->vcore_state, so we can + * drop the vcore lock if necessary. + */ + vc->n_woken = 0; + vc->nap_count = 0; + vc->entry_exit_count = 0; + vc->vcore_state = VCORE_RUNNING; + vc->in_guest = 0; + vc->napping_threads = 0; + + /* + * Updating any of the vpas requires calling kvmppc_pin_guest_page, + * which can't be called with any spinlocks held. + */ + if (need_vpa_update) { + spin_unlock(&vc->lock); + list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) + kvmppc_update_vpas(vcpu); + spin_lock(&vc->lock); + } /* * Make sure we are running on thread 0, and that @@ -838,20 +884,10 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc) if (vcpu->arch.ceded) vcpu->arch.ptid = ptid++; - vc->n_woken = 0; - vc->nap_count = 0; - vc->entry_exit_count = 0; - vc->vcore_state = VCORE_RUNNING; vc->stolen_tb += mftb() - vc->preempt_tb; - vc->in_guest = 0; vc->pcpu = smp_processor_id(); - vc->napping_threads = 0; list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { kvmppc_start_thread(vcpu); - if (vcpu->arch.vpa.update_pending || - vcpu->arch.slb_shadow.update_pending || - vcpu->arch.dtl.update_pending) - kvmppc_update_vpas(vcpu); kvmppc_create_dtl_entry(vcpu, vc); } /* Grab any remaining hw threads so they can't go into the kernel */ -- GitLab From 9e40b67bf2bfaa40b28354c501a72fd001a1397a Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Tue, 19 Jun 2012 22:04:56 +0900 Subject: [PATCH 2011/6849] KVM: Use kvm_kvfree() to free memory allocated by kvm_kvzalloc() The following commit did not care about the error handling path: commit c1a7b32a14138f908df52d7c53b5ce3415ec6b50 KVM: Avoid wasting pages for small lpage_info arrays If memory allocation fails, vfree() will be called with the address returned by kzalloc(). This patch fixes this issue. Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a01a4241bc6b..6ed5983f78ff 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6350,7 +6350,7 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) out_free: for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { - vfree(slot->arch.lpage_info[i]); + kvm_kvfree(slot->arch.lpage_info[i]); slot->arch.lpage_info[i] = NULL; } return -ENOMEM; -- GitLab From 409a8be61560c5875816da6dcb0c575d78145a5c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 30 May 2012 10:33:24 -0300 Subject: [PATCH 2012/6849] perf tools: Add sort by src line/number Using addr2line for now, requires debuginfo, needs more work to support detached debuginfo, aka foo-debuginfo packages. Example: [root@sandy ~]# perf record -a sleep 3 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.555 MB perf.data (~24236 samples) ] [root@sandy ~]# perf report -s dso,srcline 2>&1 | grep -v ^# | head -5 22.41% [kernel.kallsyms] /home/git/linux/drivers/idle/intel_idle.c:280 4.79% [kernel.kallsyms] /home/git/linux/drivers/cpuidle/cpuidle.c:148 4.78% [kernel.kallsyms] /home/git/linux/arch/x86/include/asm/atomic64_64.h:121 4.49% [kernel.kallsyms] /home/git/linux/kernel/sched/core.c:1690 4.30% [kernel.kallsyms] /home/git/linux/include/linux/seqlock.h:90 [root@sandy ~]# [root@sandy ~]# perf top -U -s dso,symbol,srcline Samples: 1K of event 'cycles', Event count (approx.): 589617389 18.66% [kernel] [k] copy_user_generic_unrolled /home/git/linux/arch/x86/lib/copy_user_64.S:143 7.83% [kernel] [k] clear_page /home/git/linux/arch/x86/lib/clear_page_64.S:39 6.59% [kernel] [k] clear_page /home/git/linux/arch/x86/lib/clear_page_64.S:38 3.66% [kernel] [k] page_fault /home/git/linux/arch/x86/kernel/entry_64.S:1379 3.25% [kernel] [k] clear_page /home/git/linux/arch/x86/lib/clear_page_64.S:40 3.12% [kernel] [k] clear_page /home/git/linux/arch/x86/lib/clear_page_64.S:37 2.74% [kernel] [k] clear_page /home/git/linux/arch/x86/lib/clear_page_64.S:36 2.39% [kernel] [k] clear_page /home/git/linux/arch/x86/lib/clear_page_64.S:43 2.12% [kernel] [k] ioread32 /home/git/linux/lib/iomap.c:90 1.51% [kernel] [k] copy_user_generic_unrolled /home/git/linux/arch/x86/lib/copy_user_64.S:144 1.19% [kernel] [k] copy_user_generic_unrolled /home/git/linux/arch/x86/lib/copy_user_64.S:154 Suggested-by: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-pdmqbng9twz06jzkbgtuwbp8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/Documentation/perf-top.txt | 2 +- tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 49 ++++++++++++++++++++++++ tools/perf/util/sort.h | 2 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 2d89f02719b5..495210a612c4 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -57,7 +57,7 @@ OPTIONS -s:: --sort=:: - Sort by key(s): pid, comm, dso, symbol, parent. + Sort by key(s): pid, comm, dso, symbol, parent, srcline. -p:: --parent=:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 4a5680cb242e..5b80d84d6b4a 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -112,7 +112,7 @@ Default is to monitor all CPUS. -s:: --sort:: - Sort by key(s): pid, comm, dso, symbol, parent + Sort by key(s): pid, comm, dso, symbol, parent, srcline. -n:: --show-nr-samples:: diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 34bb556d6219..0b096c27a419 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -47,6 +47,7 @@ enum hist_column { HISTC_SYMBOL_TO, HISTC_DSO_FROM, HISTC_DSO_TO, + HISTC_SRCLINE, HISTC_NR_COLS, /* Last entry */ }; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index a27237430c5f..0f5a0a496bc4 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -241,6 +241,54 @@ struct sort_entry sort_sym = { .se_width_idx = HISTC_SYMBOL, }; +/* --sort srcline */ + +static int64_t +sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) +{ + return (int64_t)(right->ip - left->ip); +} + +static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, + size_t size, unsigned int width __used) +{ + FILE *fp; + char cmd[PATH_MAX + 2], *path = self->srcline, *nl; + size_t line_len; + + if (path != NULL) + goto out_path; + + snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64, + self->ms.map->dso->long_name, self->ip); + fp = popen(cmd, "r"); + if (!fp) + goto out_ip; + + if (getline(&path, &line_len, fp) < 0 || !line_len) + goto out_ip; + fclose(fp); + self->srcline = strdup(path); + if (self->srcline == NULL) + goto out_ip; + + nl = strchr(self->srcline, '\n'); + if (nl != NULL) + *nl = '\0'; + path = self->srcline; +out_path: + return repsep_snprintf(bf, size, "%s", path); +out_ip: + return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip); +} + +struct sort_entry sort_srcline = { + .se_header = "Source:Line", + .se_cmp = sort__srcline_cmp, + .se_snprintf = hist_entry__srcline_snprintf, + .se_width_idx = HISTC_SRCLINE, +}; + /* --sort parent */ static int64_t @@ -439,6 +487,7 @@ static struct sort_dimension sort_dimensions[] = { DIM(SORT_PARENT, "parent", sort_parent), DIM(SORT_CPU, "cpu", sort_cpu), DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), + DIM(SORT_SRCLINE, "srcline", sort_srcline), }; int sort_dimension__add(const char *tok) diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 472aa5a63a58..e724b26acd51 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -71,6 +71,7 @@ struct hist_entry { char level; bool used; u8 filtered; + char *srcline; struct symbol *parent; union { unsigned long position; @@ -93,6 +94,7 @@ enum sort_type { SORT_SYM_FROM, SORT_SYM_TO, SORT_MISPREDICT, + SORT_SRCLINE, }; /* -- GitLab From ba47a142d9f9b84e0464a11b7a067e5ad95c5d4b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 29 May 2012 13:22:58 +0900 Subject: [PATCH 2013/6849] perf ui: Introduce struct perf_error_ops The struct perf_error_ops is for flexible error logging. We can register appropriate functions based on front-end. Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1338265382-6872-4-git-send-email-namhyung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 3 + tools/perf/ui/gtk/util.c | 20 +++ tools/perf/ui/tui/setup.c | 6 + tools/perf/ui/tui/util.c | 243 +++++++++++++++++++++++++++++++++ tools/perf/ui/util.c | 277 ++++++++------------------------------ tools/perf/ui/util.h | 9 +- tools/perf/util/debug.c | 2 +- tools/perf/util/debug.h | 23 +++- 8 files changed, 357 insertions(+), 226 deletions(-) create mode 100644 tools/perf/ui/gtk/util.c create mode 100644 tools/perf/ui/tui/util.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 0eee64cfe9a0..c0ee917ae8ab 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -503,6 +503,7 @@ else LIB_OBJS += $(OUTPUT)ui/progress.o LIB_OBJS += $(OUTPUT)ui/util.o LIB_OBJS += $(OUTPUT)ui/tui/setup.o + LIB_OBJS += $(OUTPUT)ui/tui/util.o LIB_H += ui/browser.h LIB_H += ui/browsers/map.h LIB_H += ui/helpline.h @@ -526,9 +527,11 @@ else EXTLIBS += $(shell pkg-config --libs gtk+-2.0) LIB_OBJS += $(OUTPUT)ui/gtk/browser.o LIB_OBJS += $(OUTPUT)ui/gtk/setup.o + LIB_OBJS += $(OUTPUT)ui/gtk/util.o # Make sure that it'd be included only once. ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),) LIB_OBJS += $(OUTPUT)ui/setup.o + LIB_OBJS += $(OUTPUT)ui/util.o endif endif endif diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c new file mode 100644 index 000000000000..a727fe394e91 --- /dev/null +++ b/tools/perf/ui/gtk/util.c @@ -0,0 +1,20 @@ +#include "../util.h" +#include "../../util/debug.h" +#include "gtk.h" + + +/* + * FIXME: Functions below should be implemented properly. + * For now, just add stubs for NO_NEWT=1 build. + */ +#ifdef NO_NEWT_SUPPORT +int ui_helpline__show_help(const char *format __used, va_list ap __used) +{ + return 0; +} + +void ui_progress__update(u64 curr __used, u64 total __used, + const char *title __used) +{ +} +#endif diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index d33e943ac434..e813c1d17346 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -15,6 +15,8 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; static volatile int ui__need_resize; +extern struct perf_error_ops perf_tui_eops; + void ui__refresh_dimensions(bool force) { if (force || ui__need_resize) { @@ -122,6 +124,8 @@ int ui__init(void) signal(SIGINT, ui__signal); signal(SIGQUIT, ui__signal); signal(SIGTERM, ui__signal); + + perf_error__register(&perf_tui_eops); out: return err; } @@ -137,4 +141,6 @@ void ui__exit(bool wait_for_ok) SLsmg_refresh(); SLsmg_reset_smg(); SLang_reset_tty(); + + perf_error__unregister(&perf_tui_eops); } diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c new file mode 100644 index 000000000000..092902e30cee --- /dev/null +++ b/tools/perf/ui/tui/util.c @@ -0,0 +1,243 @@ +#include "../../util/util.h" +#include +#include +#include +#include + +#include "../../util/cache.h" +#include "../../util/debug.h" +#include "../browser.h" +#include "../keysyms.h" +#include "../helpline.h" +#include "../ui.h" +#include "../util.h" +#include "../libslang.h" + +static void ui_browser__argv_write(struct ui_browser *browser, + void *entry, int row) +{ + char **arg = entry; + bool current_entry = ui_browser__is_current_entry(browser, row); + + ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : + HE_COLORSET_NORMAL); + slsmg_write_nstring(*arg, browser->width); +} + +static int popup_menu__run(struct ui_browser *menu) +{ + int key; + + if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) + return -1; + + while (1) { + key = ui_browser__run(menu, 0); + + switch (key) { + case K_RIGHT: + case K_ENTER: + key = menu->index; + break; + case K_LEFT: + case K_ESC: + case 'q': + case CTRL('c'): + key = -1; + break; + default: + continue; + } + + break; + } + + ui_browser__hide(menu); + return key; +} + +int ui__popup_menu(int argc, char * const argv[]) +{ + struct ui_browser menu = { + .entries = (void *)argv, + .refresh = ui_browser__argv_refresh, + .seek = ui_browser__argv_seek, + .write = ui_browser__argv_write, + .nr_entries = argc, + }; + + return popup_menu__run(&menu); +} + +int ui_browser__input_window(const char *title, const char *text, char *input, + const char *exit_msg, int delay_secs) +{ + int x, y, len, key; + int max_len = 60, nr_lines = 0; + static char buf[50]; + const char *t; + + t = text; + while (1) { + const char *sep = strchr(t, '\n'); + + if (sep == NULL) + sep = strchr(t, '\0'); + len = sep - t; + if (max_len < len) + max_len = len; + ++nr_lines; + if (*sep == '\0') + break; + t = sep + 1; + } + + max_len += 2; + nr_lines += 8; + y = SLtt_Screen_Rows / 2 - nr_lines / 2; + x = SLtt_Screen_Cols / 2 - max_len / 2; + + SLsmg_set_color(0); + SLsmg_draw_box(y, x++, nr_lines, max_len); + if (title) { + SLsmg_gotorc(y, x + 1); + SLsmg_write_string((char *)title); + } + SLsmg_gotorc(++y, x); + nr_lines -= 7; + max_len -= 2; + SLsmg_write_wrapped_string((unsigned char *)text, y, x, + nr_lines, max_len, 1); + y += nr_lines; + len = 5; + while (len--) { + SLsmg_gotorc(y + len - 1, x); + SLsmg_write_nstring((char *)" ", max_len); + } + SLsmg_draw_box(y++, x + 1, 3, max_len - 2); + + SLsmg_gotorc(y + 3, x); + SLsmg_write_nstring((char *)exit_msg, max_len); + SLsmg_refresh(); + + x += 2; + len = 0; + key = ui__getch(delay_secs); + while (key != K_TIMER && key != K_ENTER && key != K_ESC) { + if (key == K_BKSPC) { + if (len == 0) + goto next_key; + SLsmg_gotorc(y, x + --len); + SLsmg_write_char(' '); + } else { + buf[len] = key; + SLsmg_gotorc(y, x + len++); + SLsmg_write_char(key); + } + SLsmg_refresh(); + + /* XXX more graceful overflow handling needed */ + if (len == sizeof(buf) - 1) { + ui_helpline__push("maximum size of symbol name reached!"); + key = K_ENTER; + break; + } +next_key: + key = ui__getch(delay_secs); + } + + buf[len] = '\0'; + strncpy(input, buf, len+1); + return key; +} + +int ui__question_window(const char *title, const char *text, + const char *exit_msg, int delay_secs) +{ + int x, y; + int max_len = 0, nr_lines = 0; + const char *t; + + t = text; + while (1) { + const char *sep = strchr(t, '\n'); + int len; + + if (sep == NULL) + sep = strchr(t, '\0'); + len = sep - t; + if (max_len < len) + max_len = len; + ++nr_lines; + if (*sep == '\0') + break; + t = sep + 1; + } + + max_len += 2; + nr_lines += 4; + y = SLtt_Screen_Rows / 2 - nr_lines / 2, + x = SLtt_Screen_Cols / 2 - max_len / 2; + + SLsmg_set_color(0); + SLsmg_draw_box(y, x++, nr_lines, max_len); + if (title) { + SLsmg_gotorc(y, x + 1); + SLsmg_write_string((char *)title); + } + SLsmg_gotorc(++y, x); + nr_lines -= 2; + max_len -= 2; + SLsmg_write_wrapped_string((unsigned char *)text, y, x, + nr_lines, max_len, 1); + SLsmg_gotorc(y + nr_lines - 2, x); + SLsmg_write_nstring((char *)" ", max_len); + SLsmg_gotorc(y + nr_lines - 1, x); + SLsmg_write_nstring((char *)exit_msg, max_len); + SLsmg_refresh(); + return ui__getch(delay_secs); +} + +int ui__help_window(const char *text) +{ + return ui__question_window("Help", text, "Press any key...", 0); +} + +int ui__dialog_yesno(const char *msg) +{ + return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); +} + +static int __ui__warning(const char *title, const char *format, va_list args) +{ + char *s; + + if (vasprintf(&s, format, args) > 0) { + int key; + + pthread_mutex_lock(&ui__lock); + key = ui__question_window(title, s, "Press any key...", 0); + pthread_mutex_unlock(&ui__lock); + free(s); + return key; + } + + fprintf(stderr, "%s\n", title); + vfprintf(stderr, format, args); + return K_ESC; +} + +static int perf_tui__error(const char *format, va_list args) +{ + return __ui__warning("Error:", format, args); +} + +static int perf_tui__warning(const char *format, va_list args) +{ + return __ui__warning("Warning:", format, args); +} + +struct perf_error_ops perf_tui_eops = { + .error = perf_tui__error, + .warning = perf_tui__warning, +}; diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c index ad4374a16bb0..4f989774c8c6 100644 --- a/tools/perf/ui/util.c +++ b/tools/perf/ui/util.c @@ -1,250 +1,85 @@ -#include "../util.h" -#include -#include -#include -#include - -#include "../cache.h" -#include "../debug.h" -#include "browser.h" -#include "keysyms.h" -#include "helpline.h" -#include "ui.h" #include "util.h" -#include "libslang.h" - -static void ui_browser__argv_write(struct ui_browser *browser, - void *entry, int row) -{ - char **arg = entry; - bool current_entry = ui_browser__is_current_entry(browser, row); - - ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : - HE_COLORSET_NORMAL); - slsmg_write_nstring(*arg, browser->width); -} - -static int popup_menu__run(struct ui_browser *menu) -{ - int key; - - if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) - return -1; +#include "../debug.h" - while (1) { - key = ui_browser__run(menu, 0); - - switch (key) { - case K_RIGHT: - case K_ENTER: - key = menu->index; - break; - case K_LEFT: - case K_ESC: - case 'q': - case CTRL('c'): - key = -1; - break; - default: - continue; - } - - break; - } - - ui_browser__hide(menu); - return key; -} -int ui__popup_menu(int argc, char * const argv[]) +/* + * Default error logging functions + */ +static int perf_stdio__error(const char *format, va_list args) { - struct ui_browser menu = { - .entries = (void *)argv, - .refresh = ui_browser__argv_refresh, - .seek = ui_browser__argv_seek, - .write = ui_browser__argv_write, - .nr_entries = argc, - }; - - return popup_menu__run(&menu); + fprintf(stderr, "Error:\n"); + vfprintf(stderr, format, args); + return 0; } -int ui_browser__input_window(const char *title, const char *text, char *input, - const char *exit_msg, int delay_secs) +static int perf_stdio__warning(const char *format, va_list args) { - int x, y, len, key; - int max_len = 60, nr_lines = 0; - static char buf[50]; - const char *t; - - t = text; - while (1) { - const char *sep = strchr(t, '\n'); - - if (sep == NULL) - sep = strchr(t, '\0'); - len = sep - t; - if (max_len < len) - max_len = len; - ++nr_lines; - if (*sep == '\0') - break; - t = sep + 1; - } - - max_len += 2; - nr_lines += 8; - y = SLtt_Screen_Rows / 2 - nr_lines / 2; - x = SLtt_Screen_Cols / 2 - max_len / 2; - - SLsmg_set_color(0); - SLsmg_draw_box(y, x++, nr_lines, max_len); - if (title) { - SLsmg_gotorc(y, x + 1); - SLsmg_write_string((char *)title); - } - SLsmg_gotorc(++y, x); - nr_lines -= 7; - max_len -= 2; - SLsmg_write_wrapped_string((unsigned char *)text, y, x, - nr_lines, max_len, 1); - y += nr_lines; - len = 5; - while (len--) { - SLsmg_gotorc(y + len - 1, x); - SLsmg_write_nstring((char *)" ", max_len); - } - SLsmg_draw_box(y++, x + 1, 3, max_len - 2); - - SLsmg_gotorc(y + 3, x); - SLsmg_write_nstring((char *)exit_msg, max_len); - SLsmg_refresh(); - - x += 2; - len = 0; - key = ui__getch(delay_secs); - while (key != K_TIMER && key != K_ENTER && key != K_ESC) { - if (key == K_BKSPC) { - if (len == 0) - goto next_key; - SLsmg_gotorc(y, x + --len); - SLsmg_write_char(' '); - } else { - buf[len] = key; - SLsmg_gotorc(y, x + len++); - SLsmg_write_char(key); - } - SLsmg_refresh(); - - /* XXX more graceful overflow handling needed */ - if (len == sizeof(buf) - 1) { - ui_helpline__push("maximum size of symbol name reached!"); - key = K_ENTER; - break; - } -next_key: - key = ui__getch(delay_secs); - } - - buf[len] = '\0'; - strncpy(input, buf, len+1); - return key; + fprintf(stderr, "Warning:\n"); + vfprintf(stderr, format, args); + return 0; } -int ui__question_window(const char *title, const char *text, - const char *exit_msg, int delay_secs) +static struct perf_error_ops default_eops = { - int x, y; - int max_len = 0, nr_lines = 0; - const char *t; - - t = text; - while (1) { - const char *sep = strchr(t, '\n'); - int len; - - if (sep == NULL) - sep = strchr(t, '\0'); - len = sep - t; - if (max_len < len) - max_len = len; - ++nr_lines; - if (*sep == '\0') - break; - t = sep + 1; - } - - max_len += 2; - nr_lines += 4; - y = SLtt_Screen_Rows / 2 - nr_lines / 2, - x = SLtt_Screen_Cols / 2 - max_len / 2; - - SLsmg_set_color(0); - SLsmg_draw_box(y, x++, nr_lines, max_len); - if (title) { - SLsmg_gotorc(y, x + 1); - SLsmg_write_string((char *)title); - } - SLsmg_gotorc(++y, x); - nr_lines -= 2; - max_len -= 2; - SLsmg_write_wrapped_string((unsigned char *)text, y, x, - nr_lines, max_len, 1); - SLsmg_gotorc(y + nr_lines - 2, x); - SLsmg_write_nstring((char *)" ", max_len); - SLsmg_gotorc(y + nr_lines - 1, x); - SLsmg_write_nstring((char *)exit_msg, max_len); - SLsmg_refresh(); - return ui__getch(delay_secs); -} + .error = perf_stdio__error, + .warning = perf_stdio__warning, +}; -int ui__help_window(const char *text) -{ - return ui__question_window("Help", text, "Press any key...", 0); -} +static struct perf_error_ops *perf_eops = &default_eops; -int ui__dialog_yesno(const char *msg) -{ - return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); -} -int __ui__warning(const char *title, const char *format, va_list args) +int ui__error(const char *format, ...) { - char *s; - - if (use_browser > 0 && vasprintf(&s, format, args) > 0) { - int key; + int ret; + va_list args; - pthread_mutex_lock(&ui__lock); - key = ui__question_window(title, s, "Press any key...", 0); - pthread_mutex_unlock(&ui__lock); - free(s); - return key; - } + va_start(args, format); + ret = perf_eops->error(format, args); + va_end(args); - fprintf(stderr, "%s:\n", title); - vfprintf(stderr, format, args); - return K_ESC; + return ret; } int ui__warning(const char *format, ...) { - int key; + int ret; va_list args; va_start(args, format); - key = __ui__warning("Warning", format, args); + ret = perf_eops->warning(format, args); va_end(args); - return key; + + return ret; } -int ui__error(const char *format, ...) + +/** + * perf_error__register - Register error logging functions + * @eops: The pointer to error logging function struct + * + * Register UI-specific error logging functions. Before calling this, + * other logging functions should be unregistered, if any. + */ +int perf_error__register(struct perf_error_ops *eops) { - int key; - va_list args; + if (perf_eops != &default_eops) + return -1; - va_start(args, format); - key = __ui__warning("Error", format, args); - va_end(args); - return key; + perf_eops = eops; + return 0; +} + +/** + * perf_error__unregister - Unregister error logging functions + * @eops: The pointer to error logging function struct + * + * Unregister already registered error logging functions. + */ +int perf_error__unregister(struct perf_error_ops *eops) +{ + if (perf_eops != eops) + return -1; + + perf_eops = &default_eops; + return 0; } diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h index 2d1738bd71c8..361f08c52d37 100644 --- a/tools/perf/ui/util.h +++ b/tools/perf/ui/util.h @@ -9,6 +9,13 @@ int ui__help_window(const char *text); int ui__dialog_yesno(const char *msg); int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs); -int __ui__warning(const char *title, const char *format, va_list args); + +struct perf_error_ops { + int (*error)(const char *format, va_list args); + int (*warning)(const char *format, va_list args); +}; + +int perf_error__register(struct perf_error_ops *eops); +int perf_error__unregister(struct perf_error_ops *eops); #endif /* _PERF_UI_UTIL_H_ */ diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index efb1fce259a4..4dfe0bb3c322 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -47,7 +47,7 @@ int dump_printf(const char *fmt, ...) return ret; } -#ifdef NO_NEWT_SUPPORT +#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) int ui__warning(const char *format, ...) { va_list args; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 6bebe7f0a20c..015c91dbc096 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -12,8 +12,9 @@ int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void trace_event(union perf_event *event); struct ui_progress; +struct perf_error_ops; -#ifdef NO_NEWT_SUPPORT +#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) static inline int ui_helpline__show_help(const char *format __used, va_list ap __used) { return 0; @@ -23,12 +24,28 @@ static inline void ui_progress__update(u64 curr __used, u64 total __used, const char *title __used) {} #define ui__error(format, arg...) ui__warning(format, ##arg) -#else + +static inline int +perf_error__register(struct perf_error_ops *eops __used) +{ + return 0; +} + +static inline int +perf_error__unregister(struct perf_error_ops *eops __used) +{ + return 0; +} + +#else /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ + extern char ui_helpline__last_msg[]; int ui_helpline__show_help(const char *format, va_list ap); #include "../ui/progress.h" int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); -#endif +#include "../ui/util.h" + +#endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); int ui__error_paranoid(void); -- GitLab From 42ab68a35ffee04700648ec42c9507145a66837d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 29 May 2012 13:22:59 +0900 Subject: [PATCH 2014/6849] perf ui/gtk: Introduce struct perf_gtk_context The struct perf_gtk_context is for tracking current state of GTK window and/or other things. This is a preparation of next changes. Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1338265382-6872-5-git-send-email-namhyung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/gtk/browser.c | 8 +++++++- tools/perf/ui/gtk/gtk.h | 17 +++++++++++++++++ tools/perf/ui/gtk/util.c | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 0656c381a89c..33ab1aee3472 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -11,8 +11,8 @@ static void perf_gtk__signal(int sig) { + perf_gtk__exit(false); psignal(sig, "perf"); - gtk_main_quit(); } static void perf_gtk__resize_window(GtkWidget *window) @@ -143,6 +143,10 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, g_signal_connect(window, "delete_event", gtk_main_quit, NULL); + pgctx = perf_gtk__activate_context(window); + if (!pgctx) + return -1; + notebook = gtk_notebook_new(); list_for_each_entry(pos, &evlist->entries, node) { @@ -174,5 +178,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_main(); + perf_gtk__deactivate_context(&pgctx); + return 0; } diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 75177ee04032..34fbca6d48a2 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -1,8 +1,25 @@ #ifndef _PERF_GTK_H_ #define _PERF_GTK_H_ 1 +#include + #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include #pragma GCC diagnostic error "-Wstrict-prototypes" + +struct perf_gtk_context { + GtkWidget *main_window; +}; + +extern struct perf_gtk_context *pgctx; + +static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx) +{ + return ctx && ctx->main_window; +} + +struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window); +int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); + #endif /* _PERF_GTK_H_ */ diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index a727fe394e91..6fe13fdc513e 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -3,6 +3,29 @@ #include "gtk.h" +struct perf_gtk_context *pgctx; + +struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window) +{ + struct perf_gtk_context *ctx; + + ctx = malloc(sizeof(*pgctx)); + if (ctx) + ctx->main_window = window; + + return ctx; +} + +int perf_gtk__deactivate_context(struct perf_gtk_context **ctx) +{ + if (!perf_gtk__is_active_context(*ctx)) + return -1; + + free(*ctx); + *ctx = NULL; + return 0; +} + /* * FIXME: Functions below should be implemented properly. * For now, just add stubs for NO_NEWT=1 build. -- GitLab From b4418c6848dcd56cc90625dcfaef7cb019492233 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 29 May 2012 13:23:00 +0900 Subject: [PATCH 2015/6849] perf ui/gtk: Add GTK statusbar widget to browser window Add statusbar widget to display non-critical messages at the bottom of the window. This can be used for showing a status change, warning or help message. Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1338265382-6872-6-git-send-email-namhyung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/gtk/browser.c | 26 +++++++++++++++++++++++++- tools/perf/ui/gtk/gtk.h | 2 ++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 33ab1aee3472..ece360db8658 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -122,13 +122,30 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) gtk_container_add(GTK_CONTAINER(window), view); } +static GtkWidget *perf_gtk__setup_statusbar(void) +{ + GtkWidget *stbar; + unsigned ctxid; + + stbar = gtk_statusbar_new(); + + ctxid = gtk_statusbar_get_context_id(GTK_STATUSBAR(stbar), + "perf report"); + pgctx->statbar = stbar; + pgctx->statbar_ctx_id = ctxid; + + return stbar; +} + int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help __used, void (*timer) (void *arg)__used, void *arg __used, int delay_secs __used) { struct perf_evsel *pos; + GtkWidget *vbox; GtkWidget *notebook; + GtkWidget *statbar; GtkWidget *window; signal(SIGSEGV, perf_gtk__signal); @@ -147,6 +164,8 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, if (!pgctx) return -1; + vbox = gtk_vbox_new(FALSE, 0); + notebook = gtk_notebook_new(); list_for_each_entry(pos, &evlist->entries, node) { @@ -168,7 +187,12 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); } - gtk_container_add(GTK_CONTAINER(window), notebook); + gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); + + statbar = perf_gtk__setup_statusbar(); + gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), vbox); gtk_widget_show_all(window); diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 34fbca6d48a2..206167868c5f 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -10,6 +10,8 @@ struct perf_gtk_context { GtkWidget *main_window; + GtkWidget *statbar; + guint statbar_ctx_id; }; extern struct perf_gtk_context *pgctx; -- GitLab From a6b702c117f839023814c1e03453c701d26de522 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 29 May 2012 13:23:01 +0900 Subject: [PATCH 2016/6849] perf ui/gtk: Add GTK info_bar widget to browser window The GtkInfoBar is a modern UI component to display messages without bothering the main window. It'll be used for showing a warning message. As the GtkInfoBar requires 2.18 (or newer) version of GTK+ library, add availability check to Makefile too. Suggested-by: Sunjin Yang Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1338265382-6872-7-git-send-email-namhyung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 3 +++ tools/perf/config/feature-tests.mak | 13 ++++++++++++ tools/perf/ui/gtk/browser.c | 33 +++++++++++++++++++++++++++++ tools/perf/ui/gtk/gtk.h | 12 +++++++++++ 4 files changed, 61 insertions(+) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index c0ee917ae8ab..d698c118a602 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -523,6 +523,9 @@ else msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); BASIC_CFLAGS += -DNO_GTK2_SUPPORT else + ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y) + BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR + endif BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) EXTLIBS += $(shell pkg-config --libs gtk+-2.0) LIB_OBJS += $(OUTPUT)ui/gtk/browser.o diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index d9084e03ce56..6c18785a6417 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -78,6 +78,19 @@ int main(int argc, char *argv[]) return 0; } endef + +define SOURCE_GTK2_INFOBAR +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#include +#pragma GCC diagnostic error \"-Wstrict-prototypes\" + +int main(void) +{ + gtk_info_bar_new(); + + return 0; +} +endef endif ifndef NO_LIBPERL diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index ece360db8658..fd41e8d10337 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -122,6 +122,34 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) gtk_container_add(GTK_CONTAINER(window), view); } +#ifdef HAVE_GTK_INFO_BAR +static GtkWidget *perf_gtk__setup_info_bar(void) +{ + GtkWidget *info_bar; + GtkWidget *label; + GtkWidget *content_area; + + info_bar = gtk_info_bar_new(); + gtk_widget_set_no_show_all(info_bar, TRUE); + + label = gtk_label_new(""); + gtk_widget_show(label); + + content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar)); + gtk_container_add(GTK_CONTAINER(content_area), label); + + gtk_info_bar_add_button(GTK_INFO_BAR(info_bar), GTK_STOCK_OK, + GTK_RESPONSE_OK); + g_signal_connect(info_bar, "response", + G_CALLBACK(gtk_widget_hide), NULL); + + pgctx->info_bar = info_bar; + pgctx->message_label = label; + + return info_bar; +} +#endif + static GtkWidget *perf_gtk__setup_statusbar(void) { GtkWidget *stbar; @@ -145,6 +173,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, struct perf_evsel *pos; GtkWidget *vbox; GtkWidget *notebook; + GtkWidget *info_bar; GtkWidget *statbar; GtkWidget *window; @@ -189,6 +218,10 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); + info_bar = perf_gtk__setup_info_bar(); + if (info_bar) + gtk_box_pack_start(GTK_BOX(vbox), info_bar, FALSE, FALSE, 0); + statbar = perf_gtk__setup_statusbar(); gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0); diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 206167868c5f..a4d0f2b4a2dc 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -10,6 +10,11 @@ struct perf_gtk_context { GtkWidget *main_window; + +#ifdef HAVE_GTK_INFO_BAR + GtkWidget *info_bar; + GtkWidget *message_label; +#endif GtkWidget *statbar; guint statbar_ctx_id; }; @@ -24,4 +29,11 @@ static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx) struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window); int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); +#ifndef HAVE_GTK_INFO_BAR +static inline GtkWidget *perf_gtk__setup_info_bar(void) +{ + return NULL; +} +#endif + #endif /* _PERF_GTK_H_ */ -- GitLab From e078ba14dff5c315ce19a978574883f417d2cfa0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 29 May 2012 13:23:02 +0900 Subject: [PATCH 2017/6849] perf ui/gtk: Use struct perf_error_ops Define and use perf_gtk_eops to provide a GTK2 message dialog for error reporting and a info_bar for warning. As GtkInfoBar requires recent GTK+ libraries, provides a fallback implementation using statusbar widget too. Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1338265382-6872-8-git-send-email-namhyung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/gtk/setup.c | 5 +++ tools/perf/ui/gtk/util.c | 86 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c index 829529957766..92879ce61e2f 100644 --- a/tools/perf/ui/gtk/setup.c +++ b/tools/perf/ui/gtk/setup.c @@ -1,12 +1,17 @@ #include "gtk.h" #include "../../util/cache.h" +#include "../../util/debug.h" + +extern struct perf_error_ops perf_gtk_eops; int perf_gtk__init(void) { + perf_error__register(&perf_gtk_eops); return gtk_init_check(NULL, NULL) ? 0 : -1; } void perf_gtk__exit(bool wait_for_ok __used) { + perf_error__unregister(&perf_gtk_eops); gtk_main_quit(); } diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index 6fe13fdc513e..0ead373c0dfb 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -2,6 +2,8 @@ #include "../../util/debug.h" #include "gtk.h" +#include + struct perf_gtk_context *pgctx; @@ -26,6 +28,90 @@ int perf_gtk__deactivate_context(struct perf_gtk_context **ctx) return 0; } +static int perf_gtk__error(const char *format, va_list args) +{ + char *msg; + GtkWidget *dialog; + + if (!perf_gtk__is_active_context(pgctx) || + vasprintf(&msg, format, args) < 0) { + fprintf(stderr, "Error:\n"); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + return -1; + } + + dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(pgctx->main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Error\n\n%s", msg); + gtk_dialog_run(GTK_DIALOG(dialog)); + + gtk_widget_destroy(dialog); + free(msg); + return 0; +} + +#ifdef HAVE_GTK_INFO_BAR +static int perf_gtk__warning_info_bar(const char *format, va_list args) +{ + char *msg; + + if (!perf_gtk__is_active_context(pgctx) || + vasprintf(&msg, format, args) < 0) { + fprintf(stderr, "Warning:\n"); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + return -1; + } + + gtk_label_set_text(GTK_LABEL(pgctx->message_label), msg); + gtk_info_bar_set_message_type(GTK_INFO_BAR(pgctx->info_bar), + GTK_MESSAGE_WARNING); + gtk_widget_show(pgctx->info_bar); + + free(msg); + return 0; +} +#else +static int perf_gtk__warning_statusbar(const char *format, va_list args) +{ + char *msg, *p; + + if (!perf_gtk__is_active_context(pgctx) || + vasprintf(&msg, format, args) < 0) { + fprintf(stderr, "Warning:\n"); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + return -1; + } + + gtk_statusbar_pop(GTK_STATUSBAR(pgctx->statbar), + pgctx->statbar_ctx_id); + + /* Only first line can be displayed */ + p = strchr(msg, '\n'); + if (p) + *p = '\0'; + + gtk_statusbar_push(GTK_STATUSBAR(pgctx->statbar), + pgctx->statbar_ctx_id, msg); + + free(msg); + return 0; +} +#endif + +struct perf_error_ops perf_gtk_eops = { + .error = perf_gtk__error, +#ifdef HAVE_GTK_INFO_BAR + .warning = perf_gtk__warning_info_bar, +#else + .warning = perf_gtk__warning_statusbar, +#endif +}; + /* * FIXME: Functions below should be implemented properly. * For now, just add stubs for NO_NEWT=1 build. -- GitLab From cb1a28a0cbf9dac5a7a0ca02ebebc12db260d2f8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 7 Jun 2012 18:23:31 -0300 Subject: [PATCH 2018/6849] perf lib: Introduce rtrim Remove the trailing whitespaces. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-8bxozh5lyixgjmziqaxo9675@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/string.c | 22 ++++++++++++++++++++++ tools/perf/util/util.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index d5836382ff2c..199bc4d8905d 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -313,3 +313,25 @@ int strtailcmp(const char *s1, const char *s2) return 0; } +/** + * rtrim - Removes trailing whitespace from @s. + * @s: The string to be stripped. + * + * Note that the first trailing whitespace is replaced with a %NUL-terminator + * in the given string @s. Returns @s. + */ +char *rtrim(char *s) +{ + size_t size = strlen(s); + char *end; + + if (!size) + return s; + + end = s + size - 1; + while (end >= s && isspace(*end)) + end--; + *(end + 1) = '\0'; + + return s; +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 2daaedb83d84..b13c7331eaf8 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -264,4 +264,6 @@ bool is_power_of_2(unsigned long n) size_t hex_width(u64 v); +char *rtrim(char *s); + #endif -- GitLab From aff3f3f68ae6002a30543726b2ae48cafce109e6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 7 Jun 2012 19:31:28 -0300 Subject: [PATCH 2019/6849] perf hists browser: Implement printing snapshots to files To avoid having to resort to --stdio, that expands everything, instead allow the user to go on expanding the relevant callchains and then press 'P' to print that view. As the hists browser is used for both static (report) and dynamic (top) views, it prints to a 'perf.hists.N' sequence, i.e. multiple snapshots can be taken in report and top. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-wr9xx4ba0utrynu5j6wotd79@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 195 +++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 53f6697d014e..f556e5f6388b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -23,6 +23,7 @@ struct hist_browser { struct hists *hists; struct hist_entry *he_selection; struct map_symbol *selection; + int print_seq; bool has_symbols; }; @@ -800,6 +801,196 @@ do_offset: } } +static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *browser, + struct callchain_node *chain_node, + u64 total, int level, + FILE *fp) +{ + struct rb_node *node; + int offset = level * LEVEL_OFFSET_STEP; + u64 new_total, remaining; + int printed = 0; + + if (callchain_param.mode == CHAIN_GRAPH_REL) + new_total = chain_node->children_hit; + else + new_total = total; + + remaining = new_total; + node = rb_first(&chain_node->rb_root); + while (node) { + struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); + struct rb_node *next = rb_next(node); + u64 cumul = callchain_cumul_hits(child); + struct callchain_list *chain; + char folded_sign = ' '; + int first = true; + int extra_offset = 0; + + remaining -= cumul; + + list_for_each_entry(chain, &child->val, list) { + char ipstr[BITS_PER_LONG / 4 + 1], *alloc_str; + const char *str; + bool was_first = first; + + if (first) + first = false; + else + extra_offset = LEVEL_OFFSET_STEP; + + folded_sign = callchain_list__folded(chain); + + alloc_str = NULL; + str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); + if (was_first) { + double percent = cumul * 100.0 / new_total; + + if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) + str = "Not enough memory!"; + else + str = alloc_str; + } + + printed += fprintf(fp, "%*s%c %s\n", offset + extra_offset, " ", folded_sign, str); + free(alloc_str); + if (folded_sign == '+') + break; + } + + if (folded_sign == '-') { + const int new_level = level + (extra_offset ? 2 : 1); + printed += hist_browser__fprintf_callchain_node_rb_tree(browser, child, new_total, + new_level, fp); + } + + node = next; + } + + return printed; +} + +static int hist_browser__fprintf_callchain_node(struct hist_browser *browser, + struct callchain_node *node, + int level, FILE *fp) +{ + struct callchain_list *chain; + int offset = level * LEVEL_OFFSET_STEP; + char folded_sign = ' '; + int printed = 0; + + list_for_each_entry(chain, &node->val, list) { + char ipstr[BITS_PER_LONG / 4 + 1], *s; + + folded_sign = callchain_list__folded(chain); + s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); + printed += fprintf(fp, "%*s%c %s\n", offset, " ", folded_sign, s); + } + + if (folded_sign == '-') + printed += hist_browser__fprintf_callchain_node_rb_tree(browser, node, + browser->hists->stats.total_period, + level + 1, fp); + return printed; +} + +static int hist_browser__fprintf_callchain(struct hist_browser *browser, + struct rb_root *chain, int level, FILE *fp) +{ + struct rb_node *nd; + int printed = 0; + + for (nd = rb_first(chain); nd; nd = rb_next(nd)) { + struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); + + printed += hist_browser__fprintf_callchain_node(browser, node, level, fp); + } + + return printed; +} + +static int hist_browser__fprintf_entry(struct hist_browser *browser, + struct hist_entry *he, FILE *fp) +{ + char s[8192]; + double percent; + int printed = 0; + char folded_sign = ' '; + + if (symbol_conf.use_callchain) + folded_sign = hist_entry__folded(he); + + hist_entry__snprintf(he, s, sizeof(s), browser->hists); + percent = (he->period * 100.0) / browser->hists->stats.total_period; + + if (symbol_conf.use_callchain) + printed += fprintf(fp, "%c ", folded_sign); + + printed += fprintf(fp, " %5.2f%%", percent); + + if (symbol_conf.show_nr_samples) + printed += fprintf(fp, " %11u", he->nr_events); + + if (symbol_conf.show_total_period) + printed += fprintf(fp, " %12" PRIu64, he->period); + + printed += fprintf(fp, "%s\n", rtrim(s)); + + if (folded_sign == '-') + printed += hist_browser__fprintf_callchain(browser, &he->sorted_chain, 1, fp); + + return printed; +} + +static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) +{ + struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries)); + int printed = 0; + + while (nd) { + struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); + + printed += hist_browser__fprintf_entry(browser, h, fp); + nd = hists__filter_entries(rb_next(nd)); + } + + return printed; +} + +static int hist_browser__dump(struct hist_browser *browser) +{ + char filename[64]; + FILE *fp; + + while (1) { + scnprintf(filename, sizeof(filename), "perf.hist.%d", browser->print_seq); + if (access(filename, F_OK)) + break; + /* + * XXX: Just an arbitrary lazy upper limit + */ + if (++browser->print_seq == 8192) { + ui_helpline__fpush("Too many perf.hist.N files, nothing written!"); + return -1; + } + } + + fp = fopen(filename, "w"); + if (fp == NULL) { + char bf[64]; + strerror_r(errno, bf, sizeof(bf)); + ui_helpline__fpush("Couldn't write to %s: %s", filename, bf); + return -1; + } + + ++browser->print_seq; + hist_browser__fprintf(browser, fp); + fclose(fp); + ui_helpline__fpush("%s written!", filename); + + return 0; +} + static struct hist_browser *hist_browser__new(struct hists *hists) { struct hist_browser *browser = zalloc(sizeof(*browser)); @@ -937,6 +1128,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, browser->selection->map->dso->annotate_warned) continue; goto do_annotate; + case 'P': + hist_browser__dump(browser); + continue; case 'd': goto zoom_dso; case 't': @@ -969,6 +1163,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "E Expand all callchains\n" "d Zoom into current DSO\n" "t Zoom into current Thread\n" + "P Print histograms to perf.hist.N\n" "/ Filter symbol by name"); continue; case K_ENTER: -- GitLab From 27f18617b01dbbc928e9bd3731d1766222fb7e0d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 11 Jun 2012 13:33:09 -0300 Subject: [PATCH 2020/6849] perf evsel: Carve out event modifier formatting From perf_evsel__hw_name, so that we can use it for the other kinds of events (tracepoints, software, hw cache, etc). Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-9gmd5wewsrvtny8tzxjfp471@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9f6cebd798ee..dab893804a14 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -86,16 +86,15 @@ const char *__perf_evsel__hw_name(u64 config) return "unknown-hardware"; } -static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t size) { - int colon = 0; + int colon = 0, r = 0; struct perf_event_attr *attr = &evsel->attr; - int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config)); bool exclude_guest_default = false; #define MOD_PRINT(context, mod) do { \ if (!attr->exclude_##context) { \ - if (!colon) colon = r++; \ + if (!colon) colon = ++r; \ r += scnprintf(bf + r, size - r, "%c", mod); \ } } while(0) @@ -108,7 +107,7 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) if (attr->precise_ip) { if (!colon) - colon = r++; + colon = ++r; r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); exclude_guest_default = true; } @@ -119,10 +118,16 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) } #undef MOD_PRINT if (colon) - bf[colon] = ':'; + bf[colon - 1] = ':'; return r; } +static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->attr.config)); + return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); +} + int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) { int ret; -- GitLab From 0b668bc9a74ce1bd3b8c5fd93e8d85ed955e11fe Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 11 Jun 2012 14:08:07 -0300 Subject: [PATCH 2021/6849] perf tools: Reconstruct hw cache event with modifiers from perf_event_attr [root@sandy ~]# perf record -a -e dTLB-load-misses:u usleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.486 MB perf.data (~21216 samples) ] Before: [root@sandy ~]# perf evlist dTLB-load-misses [root@sandy ~]# After: [root@sandy ~]# perf evlist dTLB-load-misses:u [root@sandy ~]# Ditto for other tools. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-7x1b0e6jthkr93lfjzsuakk5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 104 +++++++++++++++++++++++++++++ tools/perf/util/evsel.h | 16 ++++- tools/perf/util/parse-events.c | 115 +++++---------------------------- 3 files changed, 134 insertions(+), 101 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index dab893804a14..47f1fe2feab8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -128,6 +128,105 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); } +const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] + [PERF_EVSEL__MAX_ALIASES] = { + { "L1-dcache", "l1-d", "l1d", "L1-data", }, + { "L1-icache", "l1-i", "l1i", "L1-instruction", }, + { "LLC", "L2", }, + { "dTLB", "d-tlb", "Data-TLB", }, + { "iTLB", "i-tlb", "Instruction-TLB", }, + { "branch", "branches", "bpu", "btb", "bpc", }, + { "node", }, +}; + +const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_EVSEL__MAX_ALIASES] = { + { "load", "loads", "read", }, + { "store", "stores", "write", }, + { "prefetch", "prefetches", "speculative-read", "speculative-load", }, +}; + +const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] + [PERF_EVSEL__MAX_ALIASES] = { + { "refs", "Reference", "ops", "access", }, + { "misses", "miss", }, +}; + +#define C(x) PERF_COUNT_HW_CACHE_##x +#define CACHE_READ (1 << C(OP_READ)) +#define CACHE_WRITE (1 << C(OP_WRITE)) +#define CACHE_PREFETCH (1 << C(OP_PREFETCH)) +#define COP(x) (1 << x) + +/* + * cache operartion stat + * L1I : Read and prefetch only + * ITLB and BPU : Read-only + */ +static unsigned long perf_evsel__hw_cache_stat[C(MAX)] = { + [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), + [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), + [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), + [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), + [C(ITLB)] = (CACHE_READ), + [C(BPU)] = (CACHE_READ), + [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), +}; + +bool perf_evsel__is_cache_op_valid(u8 type, u8 op) +{ + if (perf_evsel__hw_cache_stat[type] & COP(op)) + return true; /* valid */ + else + return false; /* invalid */ +} + +int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, + char *bf, size_t size) +{ + if (result) { + return scnprintf(bf, size, "%s-%s-%s", perf_evsel__hw_cache[type][0], + perf_evsel__hw_cache_op[op][0], + perf_evsel__hw_cache_result[result][0]); + } + + return scnprintf(bf, size, "%s-%s", perf_evsel__hw_cache[type][0], + perf_evsel__hw_cache_op[op][1]); +} + +int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) +{ + u8 op, result, type = (config >> 0) & 0xff; + const char *err = "unknown-ext-hardware-cache-type"; + + if (type > PERF_COUNT_HW_CACHE_MAX) + goto out_err; + + op = (config >> 8) & 0xff; + err = "unknown-ext-hardware-cache-op"; + if (op > PERF_COUNT_HW_CACHE_OP_MAX) + goto out_err; + + result = (config >> 16) & 0xff; + err = "unknown-ext-hardware-cache-result"; + if (result > PERF_COUNT_HW_CACHE_RESULT_MAX) + goto out_err; + + err = "invalid-cache"; + if (!perf_evsel__is_cache_op_valid(type, op)) + goto out_err; + + return __perf_evsel__hw_cache_type_op_res_name(type, op, result, bf, size); +out_err: + return scnprintf(bf, size, "%s", err); +} + +static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size); + return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); +} + int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) { int ret; @@ -140,6 +239,11 @@ int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) case PERF_TYPE_HARDWARE: ret = perf_evsel__hw_name(evsel, bf, size); break; + + case PERF_TYPE_HW_CACHE: + ret = perf_evsel__hw_cache_name(evsel, bf, size); + break; + default: /* * FIXME diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 4ba8b564e6f4..5bf946a05a6b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -83,7 +83,21 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, struct perf_evsel *first); -const char* __perf_evsel__hw_name(u64 config); +bool perf_evsel__is_cache_op_valid(u8 type, u8 op); + +#define PERF_EVSEL__MAX_ALIASES 8 + +extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] + [PERF_EVSEL__MAX_ALIASES]; +extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_EVSEL__MAX_ALIASES]; +const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] + [PERF_EVSEL__MAX_ALIASES]; +int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, + char *bf, size_t size); +int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size); + +const char *__perf_evsel__hw_name(u64 config); int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 05dbc8b3c767..c8f8cf4a6920 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -74,51 +74,6 @@ static const char *sw_event_names[PERF_COUNT_SW_MAX] = { "emulation-faults", }; -#define MAX_ALIASES 8 - -static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = { - { "L1-dcache", "l1-d", "l1d", "L1-data", }, - { "L1-icache", "l1-i", "l1i", "L1-instruction", }, - { "LLC", "L2", }, - { "dTLB", "d-tlb", "Data-TLB", }, - { "iTLB", "i-tlb", "Instruction-TLB", }, - { "branch", "branches", "bpu", "btb", "bpc", }, - { "node", }, -}; - -static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = { - { "load", "loads", "read", }, - { "store", "stores", "write", }, - { "prefetch", "prefetches", "speculative-read", "speculative-load", }, -}; - -static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] - [MAX_ALIASES] = { - { "refs", "Reference", "ops", "access", }, - { "misses", "miss", }, -}; - -#define C(x) PERF_COUNT_HW_CACHE_##x -#define CACHE_READ (1 << C(OP_READ)) -#define CACHE_WRITE (1 << C(OP_WRITE)) -#define CACHE_PREFETCH (1 << C(OP_PREFETCH)) -#define COP(x) (1 << x) - -/* - * cache operartion stat - * L1I : Read and prefetch only - * ITLB and BPU : Read-only - */ -static unsigned long hw_cache_stat[C(MAX)] = { - [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), - [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), - [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), - [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), - [C(ITLB)] = (CACHE_READ), - [C(BPU)] = (CACHE_READ), - [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), -}; - #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ if (sys_dirent.d_type == DT_DIR && \ @@ -236,30 +191,6 @@ static const char *tracepoint_id_to_name(u64 config) return buf; } -static int is_cache_op_valid(u8 cache_type, u8 cache_op) -{ - if (hw_cache_stat[cache_type] & COP(cache_op)) - return 1; /* valid */ - else - return 0; /* invalid */ -} - -static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) -{ - static char name[50]; - - if (cache_result) { - sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], - hw_cache_op[cache_op][0], - hw_cache_result[cache_result][0]); - } else { - sprintf(name, "%s-%s", hw_cache[cache_type][0], - hw_cache_op[cache_op][1]); - } - - return name; -} - const char *event_type(int type) { switch (type) { @@ -287,7 +218,7 @@ const char *event_name(struct perf_evsel *evsel) u64 config = evsel->attr.config; int type = evsel->attr.type; - if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) { + if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE) { /* * XXX minimal fix, see comment on perf_evsen__name, this static buffer * will go away together with event_name in the next devel cycle. @@ -316,26 +247,9 @@ const char *__event_name(int type, u64 config) case PERF_TYPE_HARDWARE: return __perf_evsel__hw_name(config); - case PERF_TYPE_HW_CACHE: { - u8 cache_type, cache_op, cache_result; - - cache_type = (config >> 0) & 0xff; - if (cache_type > PERF_COUNT_HW_CACHE_MAX) - return "unknown-ext-hardware-cache-type"; - - cache_op = (config >> 8) & 0xff; - if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) - return "unknown-ext-hardware-cache-op"; - - cache_result = (config >> 16) & 0xff; - if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) - return "unknown-ext-hardware-cache-result"; - - if (!is_cache_op_valid(cache_type, cache_op)) - return "invalid-cache"; - - return event_cache_name(cache_type, cache_op, cache_result); - } + case PERF_TYPE_HW_CACHE: + __perf_evsel__hw_cache_name(config, buf, sizeof(buf)); + return buf; case PERF_TYPE_SOFTWARE: if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) @@ -379,13 +293,13 @@ static int add_event(struct list_head **_list, int *idx, return 0; } -static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) +static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) { int i, j; int n, longest = -1; for (i = 0; i < size; i++) { - for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { + for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { n = strlen(names[i][j]); if (n > longest && !strncasecmp(str, names[i][j], n)) longest = n; @@ -410,7 +324,7 @@ int parse_events_add_cache(struct list_head **list, int *idx, * No fallback - if we cannot get a clear cache type * then bail out: */ - cache_type = parse_aliases(type, hw_cache, + cache_type = parse_aliases(type, perf_evsel__hw_cache, PERF_COUNT_HW_CACHE_MAX); if (cache_type == -1) return -EINVAL; @@ -423,18 +337,18 @@ int parse_events_add_cache(struct list_head **list, int *idx, snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); if (cache_op == -1) { - cache_op = parse_aliases(str, hw_cache_op, + cache_op = parse_aliases(str, perf_evsel__hw_cache_op, PERF_COUNT_HW_CACHE_OP_MAX); if (cache_op >= 0) { - if (!is_cache_op_valid(cache_type, cache_op)) + if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) return -EINVAL; continue; } } if (cache_result == -1) { - cache_result = parse_aliases(str, hw_cache_result, - PERF_COUNT_HW_CACHE_RESULT_MAX); + cache_result = parse_aliases(str, perf_evsel__hw_cache_result, + PERF_COUNT_HW_CACHE_RESULT_MAX); if (cache_result >= 0) continue; } @@ -970,16 +884,17 @@ void print_events_type(u8 type) int print_hwcache_events(const char *event_glob) { unsigned int type, op, i, printed = 0; + char name[64]; for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { /* skip invalid cache type */ - if (!is_cache_op_valid(type, op)) + if (!perf_evsel__is_cache_op_valid(type, op)) continue; for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - char *name = event_cache_name(type, op, i); - + __perf_evsel__hw_cache_type_op_res_name(type, op, i, + name, sizeof(name)); if (event_glob != NULL && !strglobmatch(name, event_glob)) continue; -- GitLab From 335c2f5d25319b208fb8b444e6f3099a806a33bf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 11 Jun 2012 14:36:20 -0300 Subject: [PATCH 2022/6849] perf tools: Reconstruct sw event with modifiers from perf_event_attr [root@sandy ~]# perf record -e task-clock:u -a usleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.482 MB perf.data (~21073 samples) ] [root@sandy ~]# Before: [root@sandy ~]# perf evlist task-clock [root@sandy ~]# After: [root@sandy ~]# perf evlist task-clock:u [root@sandy ~]# Ditto for other tools. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-97ltkmj7v23kyhflltf6iz5n@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/evsel.h | 2 ++ tools/perf/util/parse-events.c | 19 +++---------------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 47f1fe2feab8..2da047331173 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -128,6 +128,31 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); } +static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { + "cpu-clock", + "task-clock", + "page-faults", + "context-switches", + "CPU-migrations", + "minor-faults", + "major-faults", + "alignment-faults", + "emulation-faults", +}; + +const char *__perf_evsel__sw_name(u64 config) +{ + if (config < PERF_COUNT_SW_MAX && perf_evsel__sw_names[config]) + return perf_evsel__sw_names[config]; + return "unknown-software"; +} + +static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->attr.config)); + return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); +} + const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] [PERF_EVSEL__MAX_ALIASES] = { { "L1-dcache", "l1-d", "l1d", "L1-data", }, @@ -244,6 +269,10 @@ int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) ret = perf_evsel__hw_cache_name(evsel, bf, size); break; + case PERF_TYPE_SOFTWARE: + ret = perf_evsel__sw_name(evsel, bf, size); + break; + default: /* * FIXME diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 5bf946a05a6b..9ae64d9622bc 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -98,6 +98,8 @@ int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size); const char *__perf_evsel__hw_name(u64 config); +const char *__perf_evsel__sw_name(u64 config); + int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index c8f8cf4a6920..641c4ac8a838 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -62,18 +62,6 @@ static struct event_symbol event_symbols[] = { #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) -static const char *sw_event_names[PERF_COUNT_SW_MAX] = { - "cpu-clock", - "task-clock", - "page-faults", - "context-switches", - "CPU-migrations", - "minor-faults", - "major-faults", - "alignment-faults", - "emulation-faults", -}; - #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ if (sys_dirent.d_type == DT_DIR && \ @@ -218,7 +206,8 @@ const char *event_name(struct perf_evsel *evsel) u64 config = evsel->attr.config; int type = evsel->attr.type; - if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE) { + if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE || + type == PERF_TYPE_SOFTWARE || type == PERF_TYPE_HW_CACHE) { /* * XXX minimal fix, see comment on perf_evsen__name, this static buffer * will go away together with event_name in the next devel cycle. @@ -252,9 +241,7 @@ const char *__event_name(int type, u64 config) return buf; case PERF_TYPE_SOFTWARE: - if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) - return sw_event_names[config]; - return "unknown-software"; + return __perf_evsel__sw_name(config); case PERF_TYPE_TRACEPOINT: return tracepoint_id_to_name(config); -- GitLab From a446083604fe2bafe0f46b1e95b22f7b06e3a63f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jun 2012 10:29:12 -0300 Subject: [PATCH 2023/6849] perf evsel: Handle all event types in perf_evsel__name Now to convert all event_name users to perf_evsel__name. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-buuz0j0gynseglxa76r01rdn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 24 +++++++++++------------- tools/perf/util/parse-events.c | 21 +++------------------ 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 2da047331173..2ddc81271855 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -252,6 +252,11 @@ static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } +static int perf_evsel__tracepoint_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + return scnprintf(bf, size, "%s", evsel->name ?: "unknown tracepoint"); +} + int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) { int ret; @@ -273,20 +278,13 @@ int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) ret = perf_evsel__sw_name(evsel, bf, size); break; + case PERF_TYPE_TRACEPOINT: + ret = perf_evsel__tracepoint_name(evsel, bf, size); + break; + default: - /* - * FIXME - * - * This is the minimal perf_evsel__name so that we can - * reconstruct event names taking into account event modifiers. - * - * The old event_name uses it now for raw anr hw events, so that - * we don't drag all the parsing stuff into the python binding. - * - * On the next devel cycle the rest of the event naming will be - * brought here. - */ - return 0; + ret = scnprintf(bf, size, "%s", "unknown attr type"); + break; } return ret; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 641c4ac8a838..d73690b11242 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -203,24 +203,9 @@ const char *event_type(int type) const char *event_name(struct perf_evsel *evsel) { - u64 config = evsel->attr.config; - int type = evsel->attr.type; - - if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE || - type == PERF_TYPE_SOFTWARE || type == PERF_TYPE_HW_CACHE) { - /* - * XXX minimal fix, see comment on perf_evsen__name, this static buffer - * will go away together with event_name in the next devel cycle. - */ - static char bf[128]; - perf_evsel__name(evsel, bf, sizeof(bf)); - return bf; - } - - if (evsel->name) - return evsel->name; - - return __event_name(type, config); + static char bf[128]; + perf_evsel__name(evsel, bf, sizeof(bf)); + return bf; } const char *__event_name(int type, u64 config) -- GitLab From 7289f83cceb437ca56c77eb45b8b1cda15e2e476 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jun 2012 12:34:58 -0300 Subject: [PATCH 2024/6849] perf tools: Move all users of event_name to perf_evsel__name So that we don't use global variables that could make us misreport event names when having a multi window top, for instance. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-mccancovi1u0wdkg8ncth509@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-evlist.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-report.c | 6 +++--- tools/perf/builtin-stat.c | 12 ++++++------ tools/perf/builtin-test.c | 2 +- tools/perf/builtin-top.c | 10 +++++----- tools/perf/ui/browsers/hists.c | 15 ++++----------- tools/perf/ui/gtk/browser.c | 2 +- tools/perf/util/evsel.c | 26 +++++++++++++------------- tools/perf/util/evsel.h | 2 +- tools/perf/util/header.c | 2 +- tools/perf/util/parse-events.c | 7 ------- tools/perf/util/parse-events.h | 1 - tools/perf/util/session.c | 2 +- tools/perf/util/top.c | 2 +- 15 files changed, 40 insertions(+), 55 deletions(-) diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index acd78dc28341..0dd5a058f766 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -60,7 +60,7 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail list_for_each_entry(pos, &session->evlist->entries, node) { bool first = true; - printf("%s", event_name(pos)); + printf("%s", perf_evsel__name(pos)); if (details->verbose || details->freq) { comma_printf(&first, " sample_freq=%" PRIu64, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f95840d04e4c..f5a6452931e6 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -265,7 +265,7 @@ try_again: if (err == ENOENT) { ui__error("The %s event is not supported.\n", - event_name(pos)); + perf_evsel__name(pos)); exit(EXIT_FAILURE); } @@ -916,7 +916,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) usage_with_options(record_usage, record_options); list_for_each_entry(pos, &evsel_list->entries, node) { - if (perf_header__push_event(pos->attr.config, event_name(pos))) + if (perf_header__push_event(pos->attr.config, perf_evsel__name(pos))) goto out_free_fd; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 25249f76329d..ea8ce8e1c0d8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -230,7 +230,7 @@ static int process_read_event(struct perf_tool *tool, struct perf_report *rep = container_of(tool, struct perf_report, tool); if (rep->show_threads) { - const char *name = evsel ? event_name(evsel) : "unknown"; + const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; perf_read_values_add_value(&rep->show_threads_values, event->read.pid, event->read.tid, event->read.id, @@ -239,7 +239,7 @@ static int process_read_event(struct perf_tool *tool, } dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, - evsel ? event_name(evsel) : "FAIL", + evsel ? perf_evsel__name(evsel) : "FAIL", event->read.value); return 0; @@ -314,7 +314,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, list_for_each_entry(pos, &evlist->entries, node) { struct hists *hists = &pos->hists; - const char *evname = event_name(pos); + const char *evname = perf_evsel__name(pos); hists__fprintf_nr_sample_events(hists, evname, stdout); hists__fprintf(hists, NULL, false, true, 0, 0, stdout); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 262589991ea4..875bf2675326 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -391,7 +391,7 @@ static int read_counter_aggr(struct perf_evsel *counter) if (verbose) { fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", - event_name(counter), count[0], count[1], count[2]); + perf_evsel__name(counter), count[0], count[1], count[2]); } /* @@ -496,7 +496,7 @@ static int run_perf_stat(int argc __used, const char **argv) errno == ENXIO) { if (verbose) ui__warning("%s event is not supported by the kernel.\n", - event_name(counter)); + perf_evsel__name(counter)); counter->supported = false; continue; } @@ -594,7 +594,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) csv_output ? 0 : -4, evsel_list->cpus->map[cpu], csv_sep); - fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel)); + fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel)); if (evsel->cgrp) fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); @@ -792,7 +792,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) else cpu = 0; - fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel)); + fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel)); if (evsel->cgrp) fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); @@ -908,7 +908,7 @@ static void print_counter_aggr(struct perf_evsel *counter) counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, csv_sep, csv_output ? 0 : -24, - event_name(counter)); + perf_evsel__name(counter)); if (counter->cgrp) fprintf(output, "%s%s", csv_sep, counter->cgrp->name); @@ -961,7 +961,7 @@ static void print_counter(struct perf_evsel *counter) counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, csv_sep, csv_output ? 0 : -24, - event_name(counter)); + perf_evsel__name(counter)); if (counter->cgrp) fprintf(output, "%s%s", diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 5a8727c08757..5ce30305462b 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -583,7 +583,7 @@ static int test__basic_mmap(void) if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { pr_debug("expected %d %s events, got %d\n", expected_nr_events[evsel->idx], - event_name(evsel), nr_events[evsel->idx]); + perf_evsel__name(evsel), nr_events[evsel->idx]); goto out_munmap; } } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6bb0277b7dfe..8090a280578c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -245,7 +245,7 @@ static void perf_top__show_details(struct perf_top *top) if (notes->src == NULL) goto out_unlock; - printf("Showing %s for %s\n", event_name(top->sym_evsel), symbol->name); + printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name); printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter); more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx, @@ -408,7 +408,7 @@ static void perf_top__print_mapped_keys(struct perf_top *top) fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); if (top->evlist->nr_entries > 1) - fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(top->sym_evsel)); + fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel)); fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); @@ -503,13 +503,13 @@ static void perf_top__handle_keypress(struct perf_top *top, int c) fprintf(stderr, "\nAvailable events:"); list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) - fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, event_name(top->sym_evsel)); + fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel)); prompt_integer(&counter, "Enter details event counter"); if (counter >= top->evlist->nr_entries) { top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node); - fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top->sym_evsel)); + fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel)); sleep(1); break; } @@ -960,7 +960,7 @@ try_again: if (err == ENOENT) { ui__error("The %s event is not supported.\n", - event_name(counter)); + perf_evsel__name(counter)); goto out_err; } else if (err == EMFILE) { ui__error("Too many events are opened.\n" diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index f556e5f6388b..482f0517b61e 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1367,7 +1367,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); bool current_entry = ui_browser__is_current_entry(browser, row); unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; - const char *ev_name = event_name(evsel); + const char *ev_name = perf_evsel__name(evsel); char bf[256], unit; const char *warn = " "; size_t printed; @@ -1435,7 +1435,7 @@ browse_hists: */ if (timer) timer(arg); - ev_name = event_name(pos); + ev_name = perf_evsel__name(pos); key = perf_evsel__hists_browse(pos, nr_events, help, ev_name, true, timer, arg, delay_secs); @@ -1504,17 +1504,11 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, ui_helpline__push("Press ESC to exit"); list_for_each_entry(pos, &evlist->entries, node) { - const char *ev_name = event_name(pos); + const char *ev_name = perf_evsel__name(pos); size_t line_len = strlen(ev_name) + 7; if (menu.b.width < line_len) menu.b.width = line_len; - /* - * Cache the evsel name, tracepoints have a _high_ cost per - * event_name() call. - */ - if (pos->name == NULL) - pos->name = strdup(ev_name); } return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer, @@ -1525,11 +1519,10 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, void(*timer)(void *arg), void *arg, int delay_secs) { - if (evlist->nr_entries == 1) { struct perf_evsel *first = list_entry(evlist->entries.next, struct perf_evsel, node); - const char *ev_name = event_name(first); + const char *ev_name = perf_evsel__name(first); return perf_evsel__hists_browse(first, evlist->nr_entries, help, ev_name, false, timer, arg, delay_secs); diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index fd41e8d10337..ec12e0b4ded6 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -199,7 +199,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, list_for_each_entry(pos, &evlist->entries, node) { struct hists *hists = &pos->hists; - const char *evname = event_name(pos); + const char *evname = perf_evsel__name(pos); GtkWidget *scrolled_window; GtkWidget *tab_label; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 2ddc81271855..236bdf25db6d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -252,42 +252,42 @@ static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } -static int perf_evsel__tracepoint_name(struct perf_evsel *evsel, char *bf, size_t size) +const char *perf_evsel__name(struct perf_evsel *evsel) { - return scnprintf(bf, size, "%s", evsel->name ?: "unknown tracepoint"); -} + char bf[128]; -int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) -{ - int ret; + if (evsel->name) + return evsel->name; switch (evsel->attr.type) { case PERF_TYPE_RAW: - ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); + scnprintf(bf, sizeof(bf), "raw 0x%" PRIx64, evsel->attr.config); break; case PERF_TYPE_HARDWARE: - ret = perf_evsel__hw_name(evsel, bf, size); + perf_evsel__hw_name(evsel, bf, sizeof(bf)); break; case PERF_TYPE_HW_CACHE: - ret = perf_evsel__hw_cache_name(evsel, bf, size); + perf_evsel__hw_cache_name(evsel, bf, sizeof(bf)); break; case PERF_TYPE_SOFTWARE: - ret = perf_evsel__sw_name(evsel, bf, size); + perf_evsel__sw_name(evsel, bf, sizeof(bf)); break; case PERF_TYPE_TRACEPOINT: - ret = perf_evsel__tracepoint_name(evsel, bf, size); + scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint"); break; default: - ret = scnprintf(bf, size, "%s", "unknown attr type"); + scnprintf(bf, sizeof(bf), "%s", "unknown attr type"); break; } - return ret; + evsel->name = strdup(bf); + + return evsel->name ?: "unknown"; } void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 9ae64d9622bc..c936feb4e0a6 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -100,7 +100,7 @@ int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size); const char *__perf_evsel__hw_name(u64 config); const char *__perf_evsel__sw_name(u64 config); -int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); +const char *perf_evsel__name(struct perf_evsel *evsel); int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 2dd5edf161b7..07c8f3792954 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -641,7 +641,7 @@ static int write_event_desc(int fd, struct perf_header *h __used, /* * write event string as passed on cmdline */ - ret = do_write_string(fd, event_name(attr)); + ret = do_write_string(fd, perf_evsel__name(attr)); if (ret < 0) return ret; /* diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d73690b11242..517e6473982c 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -201,13 +201,6 @@ const char *event_type(int type) return "unknown"; } -const char *event_name(struct perf_evsel *evsel) -{ - static char bf[128]; - perf_evsel__name(evsel, bf, sizeof(bf)); - return bf; -} - const char *__event_name(int type, u64 config) { static char buf[32]; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 8cac57ab4ee6..d7eb070937c4 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -26,7 +26,6 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config); extern bool have_tracepoints(struct list_head *evlist); const char *event_type(int type); -const char *event_name(struct perf_evsel *event); extern const char *__event_name(int type, u64 config); extern int parse_events_option(const struct option *opt, const char *str, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2600916efa83..582ee38ed216 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1439,7 +1439,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) ret += hists__fprintf_nr_events(&session->hists, fp); list_for_each_entry(pos, &session->evlist->entries, node) { - ret += fprintf(fp, "%s stats:\n", event_name(pos)); + ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); ret += hists__fprintf_nr_events(&pos->hists, fp); } diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index abe0e8e95068..7eeebcee291c 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -65,7 +65,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) top->freq ? "Hz" : ""); } - ret += SNPRINTF(bf + ret, size - ret, "%s", event_name(top->sym_evsel)); + ret += SNPRINTF(bf + ret, size - ret, "%s", perf_evsel__name(top->sym_evsel)); ret += SNPRINTF(bf + ret, size - ret, "], "); -- GitLab From 5bff01f66db1753abcae03a06b21e56e7e9d9fa9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jun 2012 13:35:44 -0300 Subject: [PATCH 2025/6849] perf script: Replace __event_name uses with perf_evsel__name No logic change, just remove one more user of __event_name(). Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-e4f0vuy3283hmzfjjvkgm7fo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 38 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8e395a538eb9..8f9f9b6140db 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -137,10 +137,11 @@ static const char *output_field2str(enum perf_output_field field) #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) -static int perf_event_attr__check_stype(struct perf_event_attr *attr, - u64 sample_type, const char *sample_msg, - enum perf_output_field field) +static int perf_evsel__check_stype(struct perf_evsel *evsel, + u64 sample_type, const char *sample_msg, + enum perf_output_field field) { + struct perf_event_attr *attr = &evsel->attr; int type = attr->type; const char *evname; @@ -148,7 +149,7 @@ static int perf_event_attr__check_stype(struct perf_event_attr *attr, return 0; if (output[type].user_set) { - evname = __event_name(attr->type, attr->config); + evname = perf_evsel__name(evsel); pr_err("Samples for '%s' event do not have %s attribute set. " "Cannot print '%s' field.\n", evname, sample_msg, output_field2str(field)); @@ -157,7 +158,7 @@ static int perf_event_attr__check_stype(struct perf_event_attr *attr, /* user did not ask for it explicitly so remove from the default list */ output[type].fields &= ~field; - evname = __event_name(attr->type, attr->config); + evname = perf_evsel__name(evsel); pr_debug("Samples for '%s' event do not have %s attribute set. " "Skipping '%s' field.\n", evname, sample_msg, output_field2str(field)); @@ -175,8 +176,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, return -EINVAL; if (PRINT_FIELD(IP)) { - if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", - PERF_OUTPUT_IP)) + if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", + PERF_OUTPUT_IP)) return -EINVAL; if (!no_callchain && @@ -185,8 +186,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, } if (PRINT_FIELD(ADDR) && - perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR", - PERF_OUTPUT_ADDR)) + perf_evsel__check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", + PERF_OUTPUT_ADDR)) return -EINVAL; if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { @@ -208,18 +209,18 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, } if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && - perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", - PERF_OUTPUT_TID|PERF_OUTPUT_PID)) + perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", + PERF_OUTPUT_TID|PERF_OUTPUT_PID)) return -EINVAL; if (PRINT_FIELD(TIME) && - perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME", - PERF_OUTPUT_TIME)) + perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", + PERF_OUTPUT_TIME)) return -EINVAL; if (PRINT_FIELD(CPU) && - perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU", - PERF_OUTPUT_CPU)) + perf_evsel__check_stype(evsel, PERF_SAMPLE_CPU, "CPU", + PERF_OUTPUT_CPU)) return -EINVAL; return 0; @@ -258,9 +259,10 @@ static int perf_session__check_output_opt(struct perf_session *session) static void print_sample_start(struct perf_sample *sample, struct thread *thread, - struct perf_event_attr *attr) + struct perf_evsel *evsel) { int type; + struct perf_event_attr *attr = &evsel->attr; struct event_format *event; const char *evname = NULL; unsigned long secs; @@ -305,7 +307,7 @@ static void print_sample_start(struct perf_sample *sample, if (event) evname = event->name; } else - evname = __event_name(attr->type, attr->config); + evname = perf_evsel__name(evsel); printf("%s: ", evname ? evname : "[unknown]"); } @@ -412,7 +414,7 @@ static void process_event(union perf_event *event __unused, if (output[attr->type].fields == 0) return; - print_sample_start(sample, thread, attr); + print_sample_start(sample, thread, evsel); if (is_bts_event(attr)) { print_sample_bts(event, sample, evsel, machine, thread); -- GitLab From 22c8b84320ecf9ecbb6587d46a259b828e9ece5e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jun 2012 13:55:13 -0300 Subject: [PATCH 2026/6849] perf tools: Don't access evsel->name directly One needs to use perf_evsel__name() so that if needed the name gets synthesized and stored in evsel->name, from where perf_evsel__name() will serve from them on. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ml7zbenjmri9bghmrea0jm0d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 2 +- tools/perf/util/parse-events-test.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index b125e07eb399..9fe77b185338 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1601,7 +1601,7 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, if (thread == NULL) { pr_debug("problem processing %s event, skipping it.\n", - evsel->name); + perf_evsel__name(evsel)); return -1; } diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 76b98e2a587d..d0cf7c1ed068 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -418,14 +418,14 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "krava")); + TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); /* cpu/config=2/" */ evsel = list_entry(evsel->node.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "raw 0x2")); + TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "raw 0x2")); return 0; } -- GitLab From 9db1763c72b1548626ae9d634015de4f07ef624f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 12 Jun 2012 13:45:00 -0300 Subject: [PATCH 2027/6849] perf tools: Remove __event_name Not needed anymore, the parsing code can just leave evsel->name as NULL and the first call to perf_evsel__name() will do exactly what was being pre-cached using __event_name(). Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-cn2eiijcinnc97buod8cs34m@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.c | 61 ++++------------------------------ tools/perf/util/parse-events.h | 1 - 2 files changed, 6 insertions(+), 56 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 517e6473982c..eacf932a36a0 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -161,24 +161,6 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) return NULL; } -#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) -static const char *tracepoint_id_to_name(u64 config) -{ - static char buf[TP_PATH_LEN]; - struct tracepoint_path *path; - - path = tracepoint_id_to_path(config); - if (path) { - snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); - free(path->name); - free(path->system); - free(path); - } else - snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); - - return buf; -} - const char *event_type(int type) { switch (type) { @@ -201,36 +183,6 @@ const char *event_type(int type) return "unknown"; } -const char *__event_name(int type, u64 config) -{ - static char buf[32]; - - if (type == PERF_TYPE_RAW) { - sprintf(buf, "raw 0x%" PRIx64, config); - return buf; - } - - switch (type) { - case PERF_TYPE_HARDWARE: - return __perf_evsel__hw_name(config); - - case PERF_TYPE_HW_CACHE: - __perf_evsel__hw_cache_name(config, buf, sizeof(buf)); - return buf; - - case PERF_TYPE_SOFTWARE: - return __perf_evsel__sw_name(config); - - case PERF_TYPE_TRACEPOINT: - return tracepoint_id_to_name(config); - - default: - break; - } - - return "unknown"; -} - static int add_event(struct list_head **_list, int *idx, struct perf_event_attr *attr, char *name) { @@ -252,7 +204,8 @@ static int add_event(struct list_head **_list, int *idx, return -ENOMEM; } - evsel->name = strdup(name); + if (name) + evsel->name = strdup(name); list_add_tail(&evsel->node, list); *_list = list; return 0; @@ -545,8 +498,7 @@ int parse_events_add_numeric(struct list_head **list, int *idx, config_attr(&attr, head_config, 1)) return -EINVAL; - return add_event(list, idx, &attr, - (char *) __event_name(type, config)); + return add_event(list, idx, &attr, NULL); } static int parse_events__is_name_term(struct parse_events__term *term) @@ -554,8 +506,7 @@ static int parse_events__is_name_term(struct parse_events__term *term) return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; } -static char *pmu_event_name(struct perf_event_attr *attr, - struct list_head *head_terms) +static char *pmu_event_name(struct list_head *head_terms) { struct parse_events__term *term; @@ -563,7 +514,7 @@ static char *pmu_event_name(struct perf_event_attr *attr, if (parse_events__is_name_term(term)) return term->val.str; - return (char *) __event_name(PERF_TYPE_RAW, attr->config); + return NULL; } int parse_events_add_pmu(struct list_head **list, int *idx, @@ -588,7 +539,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx, return -EINVAL; return add_event(list, idx, &attr, - pmu_event_name(&attr, head_config)); + pmu_event_name(head_config)); } void parse_events_update_lists(struct list_head *list_event, diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index d7eb070937c4..1784f06e3a6a 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -26,7 +26,6 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config); extern bool have_tracepoints(struct list_head *evlist); const char *event_type(int type); -extern const char *__event_name(int type, u64 config); extern int parse_events_option(const struct option *opt, const char *str, int unset); -- GitLab From 6eef3d9c2bcf52b7a3c18e609f5838c007b989a4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 13 Jun 2012 11:53:37 -0300 Subject: [PATCH 2028/6849] perf evsel: Reconstruct raw event with modifiers from perf_event_attr I forgot to add the modifiers to raw events too, fix it. Reported-by: Jiri Olsa Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-pi267j1aqqjti9rqh9qy4g58@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 236bdf25db6d..8f0e9dd03775 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -252,6 +252,12 @@ static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } +static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); + return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); +} + const char *perf_evsel__name(struct perf_evsel *evsel) { char bf[128]; @@ -261,7 +267,7 @@ const char *perf_evsel__name(struct perf_evsel *evsel) switch (evsel->attr.type) { case PERF_TYPE_RAW: - scnprintf(bf, sizeof(bf), "raw 0x%" PRIx64, evsel->attr.config); + perf_evsel__raw_name(evsel, bf, sizeof(bf)); break; case PERF_TYPE_HARDWARE: -- GitLab From a9c34a9f9c677fcbe06bd3eda8d6caa3487b4a65 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Jun 2012 15:20:03 +0200 Subject: [PATCH 2029/6849] perf tools: Remove unused evsel parameter from machine__resolve_callchain Removing unused evsel parameter from machine__resolve_callchain function. Plus related header file and callers changes. The evsel parameter is unused since following commit: perf callchain: Make callchain cursors TLS commit 472606458f3e1ced5fe3cc5f04e90a6b5a4732cf Author: Namhyung Kim Date: Thu May 31 14:43:26 2012 +0900 Signed-off-by: Jiri Olsa Cc: Arun Sharma Cc: Benjamin Redelings Cc: Corey Ashford Cc: Cyrill Gorcunov Cc: Frank Ch. Eigler Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter Cc: Stephane Eranian Cc: Tom Zanussi Cc: Ulrich Drepper Link: http://lkml.kernel.org/r/1339420814-7379-9-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 4 ++-- tools/perf/builtin-script.c | 4 ++-- tools/perf/builtin-top.c | 2 +- tools/perf/util/map.h | 2 +- tools/perf/util/session.c | 7 +++---- tools/perf/util/session.h | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ea8ce8e1c0d8..40b0ffc3ad3b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -69,7 +69,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { - err = machine__resolve_callchain(machine, evsel, al->thread, + err = machine__resolve_callchain(machine, al->thread, sample->callchain, &parent); if (err) return err; @@ -140,7 +140,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, struct hist_entry *he; if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { - err = machine__resolve_callchain(machine, evsel, al->thread, + err = machine__resolve_callchain(machine, al->thread, sample->callchain, &parent); if (err) return err; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8f9f9b6140db..8fecd3b8130a 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -389,7 +389,7 @@ static void print_sample_bts(union perf_event *event, printf(" "); else printf("\n"); - perf_event__print_ip(event, sample, machine, evsel, + perf_event__print_ip(event, sample, machine, PRINT_FIELD(SYM), PRINT_FIELD(DSO), PRINT_FIELD(SYMOFFSET)); } @@ -433,7 +433,7 @@ static void process_event(union perf_event *event __unused, printf(" "); else printf("\n"); - perf_event__print_ip(event, sample, machine, evsel, + perf_event__print_ip(event, sample, machine, PRINT_FIELD(SYM), PRINT_FIELD(DSO), PRINT_FIELD(SYMOFFSET)); } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 8090a280578c..e3cab5f088f8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -774,7 +774,7 @@ static void perf_event__process_sample(struct perf_tool *tool, if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { - err = machine__resolve_callchain(machine, evsel, al.thread, + err = machine__resolve_callchain(machine, al.thread, sample->callchain, &parent); if (err) return; diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 81371bad4ef0..c14c665d9a25 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -157,7 +157,7 @@ void machine__exit(struct machine *self); void machine__delete(struct machine *self); int machine__resolve_callchain(struct machine *machine, - struct perf_evsel *evsel, struct thread *thread, + struct thread *thread, struct ip_callchain *chain, struct symbol **parent); int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 582ee38ed216..febc0aeb3c66 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -289,7 +289,6 @@ struct branch_info *machine__resolve_bstack(struct machine *self, } int machine__resolve_callchain(struct machine *self, - struct perf_evsel *evsel __used, struct thread *thread, struct ip_callchain *chain, struct symbol **parent) @@ -1480,8 +1479,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, } void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, - struct machine *machine, struct perf_evsel *evsel, - int print_sym, int print_dso, int print_symoffset) + struct machine *machine, int print_sym, + int print_dso, int print_symoffset) { struct addr_location al; struct callchain_cursor_node *node; @@ -1495,7 +1494,7 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, if (symbol_conf.use_callchain && sample->callchain) { - if (machine__resolve_callchain(machine, evsel, al.thread, + if (machine__resolve_callchain(machine, al.thread, sample->callchain, NULL) != 0) { if (verbose) error("Failed to resolve callchain. Skipping\n"); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7a5434c00565..877d78186f2c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -150,8 +150,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, - struct machine *machine, struct perf_evsel *evsel, - int print_sym, int print_dso, int print_symoffset); + struct machine *machine, int print_sym, + int print_dso, int print_symoffset); int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); -- GitLab From dd4f52232c60bcb41205a67d2df2ac0ecdfe3683 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 13 Jun 2012 15:52:42 -0300 Subject: [PATCH 2030/6849] perf evsel: Make some methods private Now that __event_name is gone, no need to export __perf_evsel__[hs]w_name(). Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-rpjnarbt83nu9uowrfatmy12@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8f0e9dd03775..876f639d69ed 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -78,7 +78,7 @@ static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { "ref-cycles", }; -const char *__perf_evsel__hw_name(u64 config) +static const char *__perf_evsel__hw_name(u64 config) { if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) return perf_evsel__hw_names[config]; @@ -140,7 +140,7 @@ static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { "emulation-faults", }; -const char *__perf_evsel__sw_name(u64 config) +static const char *__perf_evsel__sw_name(u64 config) { if (config < PERF_COUNT_SW_MAX && perf_evsel__sw_names[config]) return perf_evsel__sw_names[config]; @@ -219,7 +219,7 @@ int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, perf_evsel__hw_cache_op[op][1]); } -int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) +static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) { u8 op, result, type = (config >> 0) & 0xff; const char *err = "unknown-ext-hardware-cache-type"; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index c936feb4e0a6..67cc5033d192 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -95,11 +95,6 @@ const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] [PERF_EVSEL__MAX_ALIASES]; int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size); -int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size); - -const char *__perf_evsel__hw_name(u64 config); -const char *__perf_evsel__sw_name(u64 config); - const char *perf_evsel__name(struct perf_evsel *evsel); int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); -- GitLab From c0a58fb2bdf033df433cad9009c7dac4c6b872b0 Mon Sep 17 00:00:00 2001 From: Samuel Liao Date: Tue, 5 Jun 2012 13:14:59 +0800 Subject: [PATCH 2031/6849] perf annotate: Check null of sym pointer before using it Sym may be NULL, and that will cause perf to crash. Signed-off-by: Shan Wei Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/4FCD95D3.90209@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/annotate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 34b1c46eaf42..67a2703e666a 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -814,7 +814,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, { struct disasm_line *pos, *n; struct annotation *notes; - const size_t size = symbol__size(sym); + size_t size; struct map_symbol ms = { .map = map, .sym = sym, @@ -834,6 +834,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, if (sym == NULL) return -1; + size = symbol__size(sym); + if (map->dso->annotate_warned) return -1; -- GitLab From 0a9c63fae7df086ff5e107273c3cce8642430974 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 15 Jun 2012 13:02:58 -0400 Subject: [PATCH 2032/6849] NFSv4.1: Fix a race in set_pnfs_layoutdriver The call to try_module_get() dereferences ld_type outside the spin locks, which means that it may be pointing to garbage if a module unload was in progress. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index bdf7e52943c8..bbc49caa7a82 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -70,6 +70,10 @@ find_pnfs_driver(u32 id) spin_lock(&pnfs_spinlock); local = find_pnfs_driver_locked(id); + if (local != NULL && !try_module_get(local->owner)) { + dprintk("%s: Could not grab reference on module\n", __func__); + local = NULL; + } spin_unlock(&pnfs_spinlock); return local; } @@ -118,10 +122,6 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, goto out_no_driver; } } - if (!try_module_get(ld_type->owner)) { - dprintk("%s: Could not grab reference on module\n", __func__); - goto out_no_driver; - } server->pnfs_curr_ld = ld_type; if (ld_type->set_layoutdriver && ld_type->set_layoutdriver(server, mntfh)) { -- GitLab From 76591bea9714a58d8924154068c78d702eb2cb17 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 03:04:52 +0200 Subject: [PATCH 2033/6849] ath9k: fix a tx rate duration calculation bug The rate pointer variable for a rate series is used in a loop before it is initialized. This went unnoticed because it was used earlier for the RTS/CTS rate. This bug can lead to the wrong PHY type being passed to the duration calculation function. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d59dd01d6cde..efb7f00f3561 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1001,13 +1001,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, } /* legacy rates */ + rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; if ((tx_info->band == IEEE80211_BAND_2GHZ) && !(rate->flags & IEEE80211_RATE_ERP_G)) phy = WLAN_RC_PHY_CCK; else phy = WLAN_RC_PHY_OFDM; - rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; info->rates[i].Rate = rate->hw_value; if (rate->hw_value_short) { if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) -- GitLab From 80b08a8d8829a58b5db14b1417151094cc28face Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 03:04:53 +0200 Subject: [PATCH 2034/6849] ath9k: fix invalid pointer access in the tx path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After setup_frame_info has been called, only info->control.rates is still valid, other control fields have been overwritten by the ath_frame_info data. Move the access to info->control.vif for checking short preamble to setup_frame_info before it gets overwritten. This regression was introduced in commit d47a61aa "ath9k: Fix multi-VIF BSS handling" Signed-off-by: Felix Fietkau Reported-by: Thomas Hühn Acked-by: Sujith Manoharan Cc: stable@vger.kernel.org [3.4] Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/xmit.c | 29 +++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a277cf6f339d..4866550ddd96 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -214,6 +214,7 @@ struct ath_frame_info { enum ath9k_key_type keytype; u8 keyix; u8 retries; + u8 rtscts_rate; }; struct ath_buf_state { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index efb7f00f3561..4d571394c7a8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, struct ieee80211_tx_rate *rates; const struct ieee80211_rate *rate; struct ieee80211_hdr *hdr; + struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); int i; u8 rix = 0; @@ -948,18 +949,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, /* set dur_update_en for l-sig computation except for PS-Poll frames */ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); - - /* - * We check if Short Preamble is needed for the CTS rate by - * checking the BSS's global flag. - * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. - */ - rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); - info->rtscts_rate = rate->hw_value; - - if (tx_info->control.vif && - tx_info->control.vif->bss_conf.use_short_preamble) - info->rtscts_rate |= rate->hw_value_short; + info->rtscts_rate = fi->rtscts_rate; for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; @@ -1776,10 +1766,22 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const struct ieee80211_rate *rate; struct ath_frame_info *fi = get_frame_info(skb); struct ath_node *an = NULL; enum ath9k_key_type keytype; + bool short_preamble = false; + + /* + * We check if Short Preamble is needed for the CTS rate by + * checking the BSS's global flag. + * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. + */ + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) + short_preamble = true; + rate = ieee80211_get_rts_cts_rate(hw, tx_info); keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (sta) @@ -1794,6 +1796,9 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; + fi->rtscts_rate = rate->hw_value; + if (short_preamble) + fi->rtscts_rate |= rate->hw_value_short; } u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) -- GitLab From 6617942e15a16e97a1e2e93cee26f45e26243f43 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 15 Jun 2012 16:03:29 -0400 Subject: [PATCH 2035/6849] ath5k: remove _bh from inner locks spin_unlock_bh(&txq->lock) already disables softirqs so we don't want to do it here. Fixes smatch warnings: drivers/net/wireless/ath/ath5k/base.c:1048 ath5k_drain_tx_buffs() error: double lock 'bottom_half:' drivers/net/wireless/ath/ath5k/base.c:1056 ath5k_drain_tx_buffs() error: double unlock 'bottom_half:' Reported-by: Johannes Berg Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fbaa30930076..44ad6fe0278f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1045,11 +1045,11 @@ ath5k_drain_tx_buffs(struct ath5k_hw *ah) ath5k_txbuf_free_skb(ah, bf); - spin_lock_bh(&ah->txbuflock); + spin_lock(&ah->txbuflock); list_move_tail(&bf->list, &ah->txbuf); ah->txbuf_len++; txq->txq_len--; - spin_unlock_bh(&ah->txbuflock); + spin_unlock(&ah->txbuflock); } txq->link = NULL; txq->txq_poll_mark = false; -- GitLab From 73dc3b90232780462f3771901024a160559b4532 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 16:21:53 -0700 Subject: [PATCH 2036/6849] mwifiex: fix uAP TX packet timeout issue When running heavy traffic we stop the tx queue if the pending packet count reaches certain threshold. Later, the tx queue should be woken up as soon as the packet count falls below the threshold. Current code wakes TX queue up on STA interface only. Removing the check for STA interface will allow both STA and AP interfaces to resume transmit when tx_pending count becomes low. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/txrx.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index e2faec4db108..cecb27283196 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -161,15 +161,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, goto done; for (i = 0; i < adapter->priv_num; i++) { - tpriv = adapter->priv[i]; - if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && - (tpriv->media_connected)) { - if (netif_queue_stopped(tpriv->netdev)) - mwifiex_wake_up_net_dev_queue(tpriv->netdev, - adapter); - } + if (tpriv->media_connected && + netif_queue_stopped(tpriv->netdev)) + mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); } done: dev_kfree_skb_any(skb); -- GitLab From 7f59ebb5f34380696d16094fa1090485ec077fb1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 18 Jun 2012 10:48:14 +0300 Subject: [PATCH 2037/6849] airo: copying wrong data in airo_get_aplist() "qual" used to be declared on the stack, but then in 998a5a7d6a ("airo: reduce stack memory footprint") we made it dynamically allocated. Unfortunately the memcpy() here was missed and it's still copying stack memory instead of the data that we want. In other words, "&qual" should be "qual". Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 520a4b2eb9cc..a747c632597a 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -7233,8 +7233,8 @@ static int airo_get_aplist(struct net_device *dev, } } else { dwrq->flags = 1; /* Should be define'd */ - memcpy(extra + sizeof(struct sockaddr)*i, - &qual, sizeof(struct iw_quality)*i); + memcpy(extra + sizeof(struct sockaddr) * i, qual, + sizeof(struct iw_quality) * i); } dwrq->length = i; -- GitLab From 858faa57dd9e2b91f3f870fbb1185982e42f5a2b Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Fri, 15 Jun 2012 15:49:54 -0700 Subject: [PATCH 2038/6849] mwifiex: fix wrong return values in add_virtual_intf() error cases add_virtual_intf() needs to return an ERR_PTR(), instead of NULL, on errors, otherwise cfg80211 will crash. Reported-by: Johannes Berg Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 015fec3371a0..ce61b6fae1c9 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1484,7 +1484,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev; if (!adapter) - return NULL; + return ERR_PTR(-EFAULT); switch (type) { case NL80211_IFTYPE_UNSPECIFIED: @@ -1494,12 +1494,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple sta/adhoc ifaces\n"); - return NULL; + return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return NULL; + return ERR_PTR(-ENOMEM); wdev->wiphy = wiphy; priv->wdev = wdev; @@ -1522,12 +1522,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "Can't create multiple AP interfaces"); - return NULL; + return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return NULL; + return ERR_PTR(-ENOMEM); priv->wdev = wdev; wdev->wiphy = wiphy; @@ -1544,14 +1544,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, break; default: wiphy_err(wiphy, "type not supported\n"); - return NULL; + return ERR_PTR(-EINVAL); } dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); - goto error; + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(-ENOMEM); } mwifiex_init_priv_params(priv, dev); @@ -1582,7 +1583,9 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); - goto error; + free_netdev(dev); + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(-EFAULT); } sema_init(&priv->async_sem, 1); @@ -1594,12 +1597,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, mwifiex_dev_debugfs_init(priv); #endif return dev; -error: - if (dev && (dev->reg_state == NETREG_UNREGISTERED)) - free_netdev(dev); - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - - return NULL; } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); -- GitLab From 5b92da0443c2585e31b64e86c2e1b8e22845d4bb Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Thu, 14 Jun 2012 13:43:42 +0200 Subject: [PATCH 2039/6849] c_can_pci: generic module for C_CAN/D_CAN on PCI Signed-off-by: Federico Vaga Acked-by: Giancarlo Asnaghi Cc: Alan Cox Acked-by: Wolfgang Grandegger Acked-by: Bhupesh Sharma [mkl: fix call to pci_iounmap] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/Kconfig | 7 + drivers/net/can/c_can/Makefile | 1 + drivers/net/can/c_can/c_can_pci.c | 236 ++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 drivers/net/can/c_can/c_can_pci.c diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig index 25d371cf98dd..3b83bafcd947 100644 --- a/drivers/net/can/c_can/Kconfig +++ b/drivers/net/can/c_can/Kconfig @@ -13,4 +13,11 @@ config CAN_C_CAN_PLATFORM boards from ST Microelectronics (http://www.st.com) like the SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com) boards like am335x, dm814x, dm813x and dm811x. + +config CAN_C_CAN_PCI + tristate "Generic PCI Bus based C_CAN/D_CAN driver" + depends on PCI + ---help--- + This driver adds support for the C_CAN/D_CAN chips connected + to the PCI bus. endif diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile index 9273f6d5c4b7..ad1cc842170a 100644 --- a/drivers/net/can/c_can/Makefile +++ b/drivers/net/can/c_can/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_CAN_C_CAN) += c_can.o obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o +obj-$(CONFIG_CAN_C_CAN_PCI) += c_can_pci.o ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c new file mode 100644 index 000000000000..914aecfa09a9 --- /dev/null +++ b/drivers/net/can/c_can/c_can_pci.c @@ -0,0 +1,236 @@ +/* + * PCI bus driver for Bosch C_CAN/D_CAN controller + * + * Copyright (C) 2012 Federico Vaga + * + * Borrowed from c_can_platform.c + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include + +#include "c_can.h" + +enum c_can_pci_reg_align { + C_CAN_REG_ALIGN_16, + C_CAN_REG_ALIGN_32, +}; + +struct c_can_pci_data { + /* Specify if is C_CAN or D_CAN */ + enum c_can_dev_id type; + /* Set the register alignment in the memory */ + enum c_can_pci_reg_align reg_align; + /* Set the frequency if clk is not usable */ + unsigned int freq; +}; + +/* + * 16-bit c_can registers can be arranged differently in the memory + * architecture of different implementations. For example: 16-bit + * registers can be aligned to a 16-bit boundary or 32-bit boundary etc. + * Handle the same by providing a common read/write interface. + */ +static u16 c_can_pci_read_reg_aligned_to_16bit(struct c_can_priv *priv, + enum reg index) +{ + return readw(priv->base + priv->regs[index]); +} + +static void c_can_pci_write_reg_aligned_to_16bit(struct c_can_priv *priv, + enum reg index, u16 val) +{ + writew(val, priv->base + priv->regs[index]); +} + +static u16 c_can_pci_read_reg_aligned_to_32bit(struct c_can_priv *priv, + enum reg index) +{ + return readw(priv->base + 2 * priv->regs[index]); +} + +static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, + enum reg index, u16 val) +{ + writew(val, priv->base + 2 * priv->regs[index]); +} + +static int __devinit c_can_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct c_can_pci_data *c_can_pci_data = (void *)ent->driver_data; + struct c_can_priv *priv; + struct net_device *dev; + void __iomem *addr; + struct clk *clk; + int ret; + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "pci_enable_device FAILED\n"); + goto out; + } + + ret = pci_request_regions(pdev, KBUILD_MODNAME); + if (ret) { + dev_err(&pdev->dev, "pci_request_regions FAILED\n"); + goto out_disable_device; + } + + pci_set_master(pdev); + pci_enable_msi(pdev); + + addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); + if (!addr) { + dev_err(&pdev->dev, + "device has no PCI memory resources, " + "failing adapter\n"); + ret = -ENOMEM; + goto out_release_regions; + } + + /* allocate the c_can device */ + dev = alloc_c_can_dev(); + if (!dev) { + ret = -ENOMEM; + goto out_iounmap; + } + + priv = netdev_priv(dev); + pci_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + + dev->irq = pdev->irq; + priv->base = addr; + + if (!c_can_pci_data->freq) { + /* get the appropriate clk */ + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "no clock defined\n"); + ret = -ENODEV; + goto out_free_c_can; + } + priv->can.clock.freq = clk_get_rate(clk); + priv->priv = clk; + } else { + priv->can.clock.freq = c_can_pci_data->freq; + priv->priv = NULL; + } + + /* Configure CAN type */ + switch (c_can_pci_data->type) { + case C_CAN_DEVTYPE: + priv->regs = reg_map_c_can; + break; + case D_CAN_DEVTYPE: + priv->regs = reg_map_d_can; + priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; + break; + default: + ret = -EINVAL; + goto out_free_clock; + } + + /* Configure access to registers */ + switch (c_can_pci_data->reg_align) { + case C_CAN_REG_ALIGN_32: + priv->read_reg = c_can_pci_read_reg_aligned_to_32bit; + priv->write_reg = c_can_pci_write_reg_aligned_to_32bit; + break; + case C_CAN_REG_ALIGN_16: + priv->read_reg = c_can_pci_read_reg_aligned_to_16bit; + priv->write_reg = c_can_pci_write_reg_aligned_to_16bit; + break; + default: + ret = -EINVAL; + goto out_free_clock; + } + + ret = register_c_can_dev(dev); + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", + KBUILD_MODNAME, ret); + goto out_free_clock; + } + + dev_dbg(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", + KBUILD_MODNAME, priv->regs, dev->irq); + + return 0; + +out_free_clock: + if (priv->priv) + clk_put(priv->priv); +out_free_c_can: + pci_set_drvdata(pdev, NULL); + free_c_can_dev(dev); +out_iounmap: + pci_iounmap(pdev, addr); +out_release_regions: + pci_disable_msi(pdev); + pci_clear_master(pdev); + pci_release_regions(pdev); +out_disable_device: + pci_disable_device(pdev); +out: + return ret; +} + +static void __devexit c_can_pci_remove(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct c_can_priv *priv = netdev_priv(dev); + + unregister_c_can_dev(dev); + + if (priv->priv) + clk_put(priv->priv); + + pci_set_drvdata(pdev, NULL); + free_c_can_dev(dev); + + pci_iounmap(pdev, priv->base); + pci_disable_msi(pdev); + pci_clear_master(pdev); + pci_release_regions(pdev); + pci_disable_device(pdev); +} + +static struct c_can_pci_data c_can_sta2x11= { + .type = C_CAN_DEVTYPE, + .reg_align = C_CAN_REG_ALIGN_32, + .freq = 52000000, /* 52 Mhz */ +}; + +#define C_CAN_ID(_vend, _dev, _driverdata) { \ + PCI_DEVICE(_vend, _dev), \ + .driver_data = (unsigned long)&_driverdata, \ +} +static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = { + C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN, + c_can_sta2x11), + {}, +}; +static struct pci_driver c_can_pci_driver = { + .name = KBUILD_MODNAME, + .id_table = c_can_pci_tbl, + .probe = c_can_pci_probe, + .remove = __devexit_p(c_can_pci_remove), +}; + +module_pci_driver(c_can_pci_driver); + +MODULE_AUTHOR("Federico Vaga "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("PCI CAN bus driver for Bosch C_CAN/D_CAN controller"); +MODULE_DEVICE_TABLE(pci, c_can_pci_tbl); -- GitLab From 7c9416365c60f150ef8961a2855fafbc7394ad6b Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 13 Jun 2012 20:04:33 +0200 Subject: [PATCH 2040/6849] canfd: add new data structures and constants - add new struct canfd_frame - check identical element offsets in struct can_frame and struct canfd_frame - new ETH_P_CANFD definition to tag CAN FD skbs correctly - add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection - add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values - update existing struct can_frame with helper constants and comments Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can.h | 59 ++++++++++++++++++++++++++++++++++++---- include/linux/if_ether.h | 3 +- net/can/af_can.c | 7 +++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/include/linux/can.h b/include/linux/can.h index 17334c09bd93..1a66cf6112ae 100644 --- a/include/linux/can.h +++ b/include/linux/can.h @@ -46,18 +46,67 @@ typedef __u32 canid_t; */ typedef __u32 can_err_mask_t; +/* CAN payload length and DLC definitions according to ISO 11898-1 */ +#define CAN_MAX_DLC 8 +#define CAN_MAX_DLEN 8 + +/* CAN FD payload length and DLC definitions according to ISO 11898-7 */ +#define CANFD_MAX_DLC 15 +#define CANFD_MAX_DLEN 64 + /** * struct can_frame - basic CAN frame structure - * @can_id: the CAN ID of the frame and CAN_*_FLAG flags, see above. - * @can_dlc: the data length field of the CAN frame - * @data: the CAN frame payload. + * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition + * @can_dlc: frame payload length in byte (0 .. 8) aka data length code + * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 + * mapping of the 'data length code' to the real payload length + * @data: CAN frame payload (up to 8 byte) */ struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ - __u8 can_dlc; /* data length code: 0 .. 8 */ - __u8 data[8] __attribute__((aligned(8))); + __u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ + __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); }; +/* + * defined bits for canfd_frame.flags + * + * As the default for CAN FD should be to support the high data rate in the + * payload section of the frame (HDR) and to support up to 64 byte in the + * data section (EDL) the bits are only set in the non-default case. + * Btw. as long as there's no real implementation for CAN FD network driver + * these bits are only preliminary. + * + * RX: NOHDR/NOEDL - info about received CAN FD frame + * ESI - bit from originating CAN controller + * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller + * ESI - bit is set by local CAN controller + */ +#define CANFD_NOHDR 0x01 /* frame without high data rate */ +#define CANFD_NOEDL 0x02 /* frame without extended data length */ +#define CANFD_ESI 0x04 /* error state indicator */ + +/** + * struct canfd_frame - CAN flexible data rate frame structure + * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition + * @len: frame payload length in byte (0 .. CANFD_MAX_DLEN) + * @flags: additional flags for CAN FD + * @__res0: reserved / padding + * @__res1: reserved / padding + * @data: CAN FD frame payload (up to CANFD_MAX_DLEN byte) + */ +struct canfd_frame { + canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ + __u8 len; /* frame payload length in byte */ + __u8 flags; /* additional flags for CAN FD */ + __u8 __res0; /* reserved / padding */ + __u8 __res1; /* reserved / padding */ + __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); +}; + +#define CAN_MTU (sizeof(struct can_frame)) +#define CANFD_MTU (sizeof(struct canfd_frame)) + /* particular protocols of the protocol family PF_CAN */ #define CAN_RAW 1 /* RAW sockets */ #define CAN_BCM 2 /* Broadcast Manager */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 56d907a2c804..167ce5b363d2 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -105,7 +105,8 @@ #define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ #define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ #define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ -#define ETH_P_CAN 0x000C /* Controller Area Network */ +#define ETH_P_CAN 0x000C /* CAN: Controller Area Network */ +#define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/ #define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ #define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ #define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ diff --git a/net/can/af_can.c b/net/can/af_can.c index 6efcd37b4bd0..c96140a1458e 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -41,6 +41,7 @@ */ #include +#include #include #include #include @@ -824,6 +825,12 @@ static struct notifier_block can_netdev_notifier __read_mostly = { static __init int can_init(void) { + /* check for correct padding to be able to use the structs similarly */ + BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) != + offsetof(struct canfd_frame, len) || + offsetof(struct can_frame, data) != + offsetof(struct canfd_frame, data)); + printk(banner); memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list)); -- GitLab From 8b01939f358d680cea971151375268cfdb6b9635 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 13 Jun 2012 20:33:02 +0200 Subject: [PATCH 2041/6849] canfd: add support for CAN FD in PF_CAN core - handle ETH_P_CAN and ETH_P_CANFD skbuffs - update sanity checks for CAN and CAN FD - make sure the CAN frame can pass the selected CAN netdevice on send - bump core version and abi version to indicate the new CAN FD support Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can/core.h | 4 +- net/can/af_can.c | 109 +++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/include/linux/can/core.h b/include/linux/can/core.h index 0ccc1cd28b95..78c6c52073ad 100644 --- a/include/linux/can/core.h +++ b/include/linux/can/core.h @@ -17,10 +17,10 @@ #include #include -#define CAN_VERSION "20090105" +#define CAN_VERSION "20120528" /* increment this number each time you change some user-space interface */ -#define CAN_ABI_VERSION "8" +#define CAN_ABI_VERSION "9" #define CAN_VERSION_STRING "rev " CAN_VERSION " abi " CAN_ABI_VERSION diff --git a/net/can/af_can.c b/net/can/af_can.c index c96140a1458e..821022a7214f 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -221,30 +221,46 @@ static int can_create(struct net *net, struct socket *sock, int protocol, * -ENOBUFS on full driver queue (see net_xmit_errno()) * -ENOMEM when local loopback failed at calling skb_clone() * -EPERM when trying to send on a non-CAN interface + * -EMSGSIZE CAN frame size is bigger than CAN interface MTU * -EINVAL when the skb->data does not contain a valid CAN frame */ int can_send(struct sk_buff *skb, int loop) { struct sk_buff *newskb = NULL; - struct can_frame *cf = (struct can_frame *)skb->data; - int err; + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + int err = -EINVAL; + + if (skb->len == CAN_MTU) { + skb->protocol = htons(ETH_P_CAN); + if (unlikely(cfd->len > CAN_MAX_DLEN)) + goto inval_skb; + } else if (skb->len == CANFD_MTU) { + skb->protocol = htons(ETH_P_CANFD); + if (unlikely(cfd->len > CANFD_MAX_DLEN)) + goto inval_skb; + } else + goto inval_skb; - if (skb->len != sizeof(struct can_frame) || cf->can_dlc > 8) { - kfree_skb(skb); - return -EINVAL; + /* + * Make sure the CAN frame can pass the selected CAN netdevice. + * As structs can_frame and canfd_frame are similar, we can provide + * CAN FD frames to legacy CAN drivers as long as the length is <= 8 + */ + if (unlikely(skb->len > skb->dev->mtu && cfd->len > CAN_MAX_DLEN)) { + err = -EMSGSIZE; + goto inval_skb; } - if (skb->dev->type != ARPHRD_CAN) { - kfree_skb(skb); - return -EPERM; + if (unlikely(skb->dev->type != ARPHRD_CAN)) { + err = -EPERM; + goto inval_skb; } - if (!(skb->dev->flags & IFF_UP)) { - kfree_skb(skb); - return -ENETDOWN; + if (unlikely(!(skb->dev->flags & IFF_UP))) { + err = -ENETDOWN; + goto inval_skb; } - skb->protocol = htons(ETH_P_CAN); skb_reset_network_header(skb); skb_reset_transport_header(skb); @@ -301,6 +317,10 @@ int can_send(struct sk_buff *skb, int loop) can_stats.tx_frames_delta++; return 0; + +inval_skb: + kfree_skb(skb); + return err; } EXPORT_SYMBOL(can_send); @@ -633,24 +653,11 @@ static int can_rcv_filter(struct dev_rcv_lists *d, struct sk_buff *skb) return matches; } -static int can_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) +static void can_receive(struct sk_buff *skb, struct net_device *dev) { struct dev_rcv_lists *d; - struct can_frame *cf = (struct can_frame *)skb->data; int matches; - if (!net_eq(dev_net(dev), &init_net)) - goto drop; - - if (WARN_ONCE(dev->type != ARPHRD_CAN || - skb->len != sizeof(struct can_frame) || - cf->can_dlc > 8, - "PF_CAN: dropped non conform skbuf: " - "dev type %d, len %d, can_dlc %d\n", - dev->type, skb->len, cf->can_dlc)) - goto drop; - /* update statistics */ can_stats.rx_frames++; can_stats.rx_frames_delta++; @@ -674,7 +681,49 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev, can_stats.matches++; can_stats.matches_delta++; } +} + +static int can_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + if (unlikely(!net_eq(dev_net(dev), &init_net))) + goto drop; + + if (WARN_ONCE(dev->type != ARPHRD_CAN || + skb->len != CAN_MTU || + cfd->len > CAN_MAX_DLEN, + "PF_CAN: dropped non conform CAN skbuf: " + "dev type %d, len %d, datalen %d\n", + dev->type, skb->len, cfd->len)) + goto drop; + + can_receive(skb, dev); + return NET_RX_SUCCESS; + +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static int canfd_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + + if (unlikely(!net_eq(dev_net(dev), &init_net))) + goto drop; + + if (WARN_ONCE(dev->type != ARPHRD_CAN || + skb->len != CANFD_MTU || + cfd->len > CANFD_MAX_DLEN, + "PF_CAN: dropped non conform CAN FD skbuf: " + "dev type %d, len %d, datalen %d\n", + dev->type, skb->len, cfd->len)) + goto drop; + + can_receive(skb, dev); return NET_RX_SUCCESS; drop: @@ -808,10 +857,14 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, static struct packet_type can_packet __read_mostly = { .type = cpu_to_be16(ETH_P_CAN), - .dev = NULL, .func = can_rcv, }; +static struct packet_type canfd_packet __read_mostly = { + .type = cpu_to_be16(ETH_P_CANFD), + .func = canfd_rcv, +}; + static const struct net_proto_family can_family_ops = { .family = PF_CAN, .create = can_create, @@ -853,6 +906,7 @@ static __init int can_init(void) sock_register(&can_family_ops); register_netdevice_notifier(&can_netdev_notifier); dev_add_pack(&can_packet); + dev_add_pack(&canfd_packet); return 0; } @@ -867,6 +921,7 @@ static __exit void can_exit(void) can_remove_proc(); /* protocol unregister */ + dev_remove_pack(&canfd_packet); dev_remove_pack(&can_packet); unregister_netdevice_notifier(&can_netdev_notifier); sock_unregister(PF_CAN); -- GitLab From e2d265d3b587f5f6f8febc0222aace93302ff0be Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 13 Jun 2012 20:41:31 +0200 Subject: [PATCH 2042/6849] canfd: add support for CAN FD in CAN_RAW sockets - introduce a new sockopt CAN_RAW_FD_FRAMES to allow CAN FD frames - handle CAN frames and CAN FD frames simultaneously when enabled Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can/raw.h | 3 ++- net/can/raw.c | 50 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/linux/can/raw.h b/include/linux/can/raw.h index 781f3a3701be..a814062b0719 100644 --- a/include/linux/can/raw.h +++ b/include/linux/can/raw.h @@ -23,7 +23,8 @@ enum { CAN_RAW_FILTER = 1, /* set 0 .. n can_filter(s) */ CAN_RAW_ERR_FILTER, /* set filter for error frames */ CAN_RAW_LOOPBACK, /* local loopback (default:on) */ - CAN_RAW_RECV_OWN_MSGS /* receive my own msgs (default:off) */ + CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */ + CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */ }; #endif diff --git a/net/can/raw.c b/net/can/raw.c index 46cca3a91d19..3e9c89356a93 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -82,6 +82,7 @@ struct raw_sock { struct notifier_block notifier; int loopback; int recv_own_msgs; + int fd_frames; int count; /* number of active filters */ struct can_filter dfilter; /* default/single filter */ struct can_filter *filter; /* pointer to filter(s) */ @@ -119,6 +120,14 @@ static void raw_rcv(struct sk_buff *oskb, void *data) if (!ro->recv_own_msgs && oskb->sk == sk) return; + /* do not pass frames with DLC > 8 to a legacy socket */ + if (!ro->fd_frames) { + struct canfd_frame *cfd = (struct canfd_frame *)oskb->data; + + if (unlikely(cfd->len > CAN_MAX_DLEN)) + return; + } + /* clone the given skb to be able to enqueue it into the rcv queue */ skb = skb_clone(oskb, GFP_ATOMIC); if (!skb) @@ -291,6 +300,7 @@ static int raw_init(struct sock *sk) /* set default loopback behaviour */ ro->loopback = 1; ro->recv_own_msgs = 0; + ro->fd_frames = 0; /* set notifier */ ro->notifier.notifier_call = raw_notifier; @@ -569,6 +579,15 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, break; + case CAN_RAW_FD_FRAMES: + if (optlen != sizeof(ro->fd_frames)) + return -EINVAL; + + if (copy_from_user(&ro->fd_frames, optval, optlen)) + return -EFAULT; + + break; + default: return -ENOPROTOOPT; } @@ -627,6 +646,12 @@ static int raw_getsockopt(struct socket *sock, int level, int optname, val = &ro->recv_own_msgs; break; + case CAN_RAW_FD_FRAMES: + if (len > sizeof(int)) + len = sizeof(int); + val = &ro->fd_frames; + break; + default: return -ENOPROTOOPT; } @@ -662,8 +687,13 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, } else ifindex = ro->ifindex; - if (size != sizeof(struct can_frame)) - return -EINVAL; + if (ro->fd_frames) { + if (unlikely(size != CANFD_MTU && size != CAN_MTU)) + return -EINVAL; + } else { + if (unlikely(size != CAN_MTU)) + return -EINVAL; + } dev = dev_get_by_index(&init_net, ifindex); if (!dev) @@ -705,7 +735,9 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags) { struct sock *sk = sock->sk; + struct raw_sock *ro = raw_sk(sk); struct sk_buff *skb; + int rxmtu; int err = 0; int noblock; @@ -716,10 +748,20 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, if (!skb) return err; - if (size < skb->len) + /* + * when serving a legacy socket the DLC <= 8 is already checked inside + * raw_rcv(). Now check if we need to pass a canfd_frame to a legacy + * socket and cut the possible CANFD_MTU/CAN_MTU length to CAN_MTU + */ + if (!ro->fd_frames) + rxmtu = CAN_MTU; + else + rxmtu = skb->len; + + if (size < rxmtu) msg->msg_flags |= MSG_TRUNC; else - size = skb->len; + size = rxmtu; err = memcpy_toiovec(msg->msg_iov, skb->data, size); if (err < 0) { -- GitLab From 1e0625facab2e871472472b7df87d8fbe6caf75a Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 13 Jun 2012 20:48:21 +0200 Subject: [PATCH 2043/6849] candev: add/update helpers for CAN FD - update sanity checks - add DLC to length conversion helpers - can_dlc2len() - get data length from can_dlc with sanitized can_dlc - can_len2dlc() - map the sanitized data length to an appropriate DLC Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 35 ++++++++++++++++++++++++++++++++++- include/linux/can/dev.h | 33 +++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index f03d7a481a80..239e4dd92ca1 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -33,6 +33,39 @@ MODULE_DESCRIPTION(MOD_DESC); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Wolfgang Grandegger "); +/* CAN DLC to real data length conversion helpers */ + +static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7, + 8, 12, 16, 20, 24, 32, 48, 64}; + +/* get data length from can_dlc with sanitized can_dlc */ +u8 can_dlc2len(u8 can_dlc) +{ + return dlc2len[can_dlc & 0x0F]; +} +EXPORT_SYMBOL_GPL(can_dlc2len); + +static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */ + 9, 9, 9, 9, /* 9 - 12 */ + 10, 10, 10, 10, /* 13 - 16 */ + 11, 11, 11, 11, /* 17 - 20 */ + 12, 12, 12, 12, /* 21 - 24 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 25 - 32 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* 33 - 40 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* 41 - 48 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 49 - 56 */ + 15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */ + +/* map the sanitized data length to an appropriate data length code */ +u8 can_len2dlc(u8 len) +{ + if (unlikely(len > 64)) + return 0xF; + + return len2dlc[len]; +} +EXPORT_SYMBOL_GPL(can_len2dlc); + #ifdef CONFIG_CAN_CALC_BITTIMING #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ @@ -454,7 +487,7 @@ EXPORT_SYMBOL_GPL(can_bus_off); static void can_setup(struct net_device *dev) { dev->type = ARPHRD_CAN; - dev->mtu = sizeof(struct can_frame); + dev->mtu = CAN_MTU; dev->hard_header_len = 0; dev->addr_len = 0; dev->tx_queue_len = 10; diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 5d2efe7e3f1b..ee5a771fb20d 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -61,23 +61,40 @@ struct can_priv { * To be used in the CAN netdriver receive path to ensure conformance with * ISO 11898-1 Chapter 8.4.2.3 (DLC field) */ -#define get_can_dlc(i) (min_t(__u8, (i), 8)) +#define get_can_dlc(i) (min_t(__u8, (i), CAN_MAX_DLC)) +#define get_canfd_dlc(i) (min_t(__u8, (i), CANFD_MAX_DLC)) /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ static inline int can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) { - const struct can_frame *cf = (struct can_frame *)skb->data; - - if (unlikely(skb->len != sizeof(*cf) || cf->can_dlc > 8)) { - kfree_skb(skb); - dev->stats.tx_dropped++; - return 1; - } + const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + + if (skb->protocol == htons(ETH_P_CAN)) { + if (unlikely(skb->len != CAN_MTU || + cfd->len > CAN_MAX_DLEN)) + goto inval_skb; + } else if (skb->protocol == htons(ETH_P_CANFD)) { + if (unlikely(skb->len != CANFD_MTU || + cfd->len > CANFD_MAX_DLEN)) + goto inval_skb; + } else + goto inval_skb; return 0; + +inval_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return 1; } +/* get data length from can_dlc with sanitized can_dlc */ +u8 can_dlc2len(u8 can_dlc); + +/* map the sanitized data length to an appropriate data length code */ +u8 can_len2dlc(u8 len); + struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max); void free_candev(struct net_device *dev); -- GitLab From 41052ef6dfe90e7639103a010f49d13dadc55a28 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 13 Jun 2012 20:56:59 +0200 Subject: [PATCH 2044/6849] vcan: add CAN FD support - move the length calculation from dlc to real length (using canfd_frame) - allow to switch the driver between CAN and CAN FD (change of MTU) Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/vcan.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index ea2d94285936..4f93c0be0053 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c @@ -70,13 +70,12 @@ MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)"); static void vcan_rx(struct sk_buff *skb, struct net_device *dev) { - struct can_frame *cf = (struct can_frame *)skb->data; + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; struct net_device_stats *stats = &dev->stats; stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; + stats->rx_bytes += cfd->len; - skb->protocol = htons(ETH_P_CAN); skb->pkt_type = PACKET_BROADCAST; skb->dev = dev; skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -86,7 +85,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev) static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) { - struct can_frame *cf = (struct can_frame *)skb->data; + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; struct net_device_stats *stats = &dev->stats; int loop; @@ -94,7 +93,7 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; stats->tx_packets++; - stats->tx_bytes += cf->can_dlc; + stats->tx_bytes += cfd->len; /* set flag whether this packet has to be looped back */ loop = skb->pkt_type == PACKET_LOOPBACK; @@ -108,7 +107,7 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) * CAN core already did the echo for us */ stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; + stats->rx_bytes += cfd->len; } kfree_skb(skb); return NETDEV_TX_OK; @@ -133,14 +132,28 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +static int vcan_change_mtu(struct net_device *dev, int new_mtu) +{ + /* Do not allow changing the MTU while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU) + return -EINVAL; + + dev->mtu = new_mtu; + return 0; +} + static const struct net_device_ops vcan_netdev_ops = { .ndo_start_xmit = vcan_tx, + .ndo_change_mtu = vcan_change_mtu, }; static void vcan_setup(struct net_device *dev) { dev->type = ARPHRD_CAN; - dev->mtu = sizeof(struct can_frame); + dev->mtu = CAN_MTU; dev->hard_header_len = 0; dev->addr_len = 0; dev->tx_queue_len = 0; -- GitLab From ea53fe0c667ad3cae61d4d71d2be41908ac5c0a4 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Sat, 16 Jun 2012 12:01:58 +0200 Subject: [PATCH 2045/6849] canfd: update documentation according to CAN FD extensions Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- Documentation/networking/can.txt | 154 +++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 8 deletions(-) diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index a06741898f29..820f55344edc 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -22,7 +22,8 @@ This file contains 4.1.2 RAW socket option CAN_RAW_ERR_FILTER 4.1.3 RAW socket option CAN_RAW_LOOPBACK 4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS - 4.1.5 RAW socket returned message flags + 4.1.5 RAW socket option CAN_RAW_FD_FRAMES + 4.1.6 RAW socket returned message flags 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) @@ -41,7 +42,8 @@ This file contains 6.5.1 Netlink interface to set/get devices properties 6.5.2 Setting the CAN bit-timing 6.5.3 Starting and stopping the CAN network device - 6.6 supported CAN hardware + 6.6 CAN FD (flexible data rate) driver support + 6.7 supported CAN hardware 7 Socket CAN resources @@ -273,7 +275,7 @@ solution for a couple of reasons: struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ - __u8 can_dlc; /* data length code: 0 .. 8 */ + __u8 can_dlc; /* frame payload length in byte (0 .. 8) */ __u8 data[8] __attribute__((aligned(8))); }; @@ -375,6 +377,51 @@ solution for a couple of reasons: nbytes = sendto(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr)); + Remark about CAN FD (flexible data rate) support: + + Generally the handling of CAN FD is very similar to the formerly described + examples. The new CAN FD capable CAN controllers support two different + bitrates for the arbitration phase and the payload phase of the CAN FD frame + and up to 64 bytes of payload. This extended payload length breaks all the + kernel interfaces (ABI) which heavily rely on the CAN frame with fixed eight + bytes of payload (struct can_frame) like the CAN_RAW socket. Therefore e.g. + the CAN_RAW socket supports a new socket option CAN_RAW_FD_FRAMES that + switches the socket into a mode that allows the handling of CAN FD frames + and (legacy) CAN frames simultaneously (see section 4.1.5). + + The struct canfd_frame is defined in include/linux/can.h: + + struct canfd_frame { + canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ + __u8 len; /* frame payload length in byte (0 .. 64) */ + __u8 flags; /* additional flags for CAN FD */ + __u8 __res0; /* reserved / padding */ + __u8 __res1; /* reserved / padding */ + __u8 data[64] __attribute__((aligned(8))); + }; + + The struct canfd_frame and the existing struct can_frame have the can_id, + the payload length and the payload data at the same offset inside their + structures. This allows to handle the different structures very similar. + When the content of a struct can_frame is copied into a struct canfd_frame + all structure elements can be used as-is - only the data[] becomes extended. + + When introducing the struct canfd_frame it turned out that the data length + code (DLC) of the struct can_frame was used as a length information as the + length and the DLC has a 1:1 mapping in the range of 0 .. 8. To preserve + the easy handling of the length information the canfd_frame.len element + contains a plain length value from 0 .. 64. So both canfd_frame.len and + can_frame.can_dlc are equal and contain a length information and no DLC. + For details about the distinction of CAN and CAN FD capable devices and + the mapping to the bus-relevant data length code (DLC), see chapter 6.6. + + The length of the two CAN(FD) frame structures define the maximum transfer + unit (MTU) of the CAN(FD) network interface and skbuff data length. Two + definitions are specified for CAN specific MTUs in include/linux/can.h : + + #define CAN_MTU (sizeof(struct can_frame)) == 16 => 'legacy' CAN frame + #define CANFD_MTU (sizeof(struct canfd_frame)) == 72 => CAN FD frame + 4.1 RAW protocol sockets with can_filters (SOCK_RAW) Using CAN_RAW sockets is extensively comparable to the commonly @@ -472,7 +519,69 @@ solution for a couple of reasons: setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs, sizeof(recv_own_msgs)); - 4.1.5 RAW socket returned message flags + 4.1.5 RAW socket option CAN_RAW_FD_FRAMES + + CAN FD support in CAN_RAW sockets can be enabled with a new socket option + CAN_RAW_FD_FRAMES which is off by default. When the new socket option is + not supported by the CAN_RAW socket (e.g. on older kernels), switching the + CAN_RAW_FD_FRAMES option returns the error -ENOPROTOOPT. + + Once CAN_RAW_FD_FRAMES is enabled the application can send both CAN frames + and CAN FD frames. OTOH the application has to handle CAN and CAN FD frames + when reading from the socket. + + CAN_RAW_FD_FRAMES enabled: CAN_MTU and CANFD_MTU are allowed + CAN_RAW_FD_FRAMES disabled: only CAN_MTU is allowed (default) + + Example: + [ remember: CANFD_MTU == sizeof(struct canfd_frame) ] + + struct canfd_frame cfd; + + nbytes = read(s, &cfd, CANFD_MTU); + + if (nbytes == CANFD_MTU) { + printf("got CAN FD frame with length %d\n", cfd.len); + /* cfd.flags contains valid data */ + } else if (nbytes == CAN_MTU) { + printf("got legacy CAN frame with length %d\n", cfd.len); + /* cfd.flags is undefined */ + } else { + fprintf(stderr, "read: invalid CAN(FD) frame\n"); + return 1; + } + + /* the content can be handled independently from the received MTU size */ + + printf("can_id: %X data length: %d data: ", cfd.can_id, cfd.len); + for (i = 0; i < cfd.len; i++) + printf("%02X ", cfd.data[i]); + + When reading with size CANFD_MTU only returns CAN_MTU bytes that have + been received from the socket a legacy CAN frame has been read into the + provided CAN FD structure. Note that the canfd_frame.flags data field is + not specified in the struct can_frame and therefore it is only valid in + CANFD_MTU sized CAN FD frames. + + As long as the payload length is <=8 the received CAN frames from CAN FD + capable CAN devices can be received and read by legacy sockets too. When + user-generated CAN FD frames have a payload length <=8 these can be send + by legacy CAN network interfaces too. Sending CAN FD frames with payload + length > 8 to a legacy CAN network interface returns an -EMSGSIZE error. + + Implementation hint for new CAN applications: + + To build a CAN FD aware application use struct canfd_frame as basic CAN + data structure for CAN_RAW based applications. When the application is + executed on an older Linux kernel and switching the CAN_RAW_FD_FRAMES + socket option returns an error: No problem. You'll get legacy CAN frames + or CAN FD frames and can process them the same way. + + When sending to CAN devices make sure that the device is capable to handle + CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU. + The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall. + + 4.1.6 RAW socket returned message flags When using recvmsg() call, the msg->msg_flags may contain following flags: @@ -573,10 +682,13 @@ solution for a couple of reasons: dev->type = ARPHRD_CAN; /* the netdevice hardware type */ dev->flags = IFF_NOARP; /* CAN has no arp */ - dev->mtu = sizeof(struct can_frame); + dev->mtu = CAN_MTU; /* sizeof(struct can_frame) -> legacy CAN interface */ - The struct can_frame is the payload of each socket buffer in the - protocol family PF_CAN. + or alternative, when the controller supports CAN with flexible data rate: + dev->mtu = CANFD_MTU; /* sizeof(struct canfd_frame) -> CAN FD interface */ + + The struct can_frame or struct canfd_frame is the payload of each socket + buffer (skbuff) in the protocol family PF_CAN. 6.2 local loopback of sent frames @@ -792,7 +904,33 @@ solution for a couple of reasons: Note that a restart will also create a CAN error message frame (see also chapter 3.4). - 6.6 Supported CAN hardware + 6.6 CAN FD (flexible data rate) driver support + + CAN FD capable CAN controllers support two different bitrates for the + arbitration phase and the payload phase of the CAN FD frame. Therefore a + second bittiming has to be specified in order to enable the CAN FD bitrate. + + Additionally CAN FD capable CAN controllers support up to 64 bytes of + payload. The representation of this length in can_frame.can_dlc and + canfd_frame.len for userspace applications and inside the Linux network + layer is a plain value from 0 .. 64 instead of the CAN 'data length code'. + The data length code was a 1:1 mapping to the payload length in the legacy + CAN frames anyway. The payload length to the bus-relevant DLC mapping is + only performed inside the CAN drivers, preferably with the helper + functions can_dlc2len() and can_len2dlc(). + + The CAN netdevice driver capabilities can be distinguished by the network + devices maximum transfer unit (MTU): + + MTU = 16 (CAN_MTU) => sizeof(struct can_frame) => 'legacy' CAN device + MTU = 72 (CANFD_MTU) => sizeof(struct canfd_frame) => CAN FD capable device + + The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall. + N.B. CAN FD capable devices can also handle and send legacy CAN frames. + + FIXME: Add details about the CAN FD controller configuration when available. + + 6.7 Supported CAN hardware Please check the "Kconfig" file in "drivers/net/can" to get an actual list of the support CAN hardware. On the Socket CAN project website -- GitLab From 868c157df9721675c19729eed2c96bac6c3f1d01 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 19 Jun 2012 15:01:02 -0600 Subject: [PATCH 2046/6849] ARM: OMAP2+: hwmod: remove prm_clkdm, cm_clkdm; allow hwmods to have no clockdomain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove prm_clkdm and cm_clkdm and allow hwmods to have no clockdomain. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/clockdomain.h | 2 -- arch/arm/mach-omap2/clockdomains2420_data.c | 2 -- arch/arm/mach-omap2/clockdomains2430_data.c | 2 -- arch/arm/mach-omap2/clockdomains3xxx_data.c | 2 -- arch/arm/mach-omap2/clockdomains44xx_data.c | 2 -- .../arm/mach-omap2/clockdomains_common_data.c | 24 ---------------- arch/arm/mach-omap2/omap_hwmod.c | 28 +++++++++++++------ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 -- 9 files changed, 19 insertions(+), 47 deletions(-) delete mode 100644 arch/arm/mach-omap2/clockdomains_common_data.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fa742f3c2629..bc7d2393161f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -116,7 +116,6 @@ obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o # PRCM clockdomain control clockdomain-common += clockdomain.o -clockdomain-common += clockdomains_common_data.o obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index f7b58609bad8..349dcbb6fecb 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -206,7 +206,5 @@ extern struct clkdm_ops omap4_clkdm_operations; extern struct clkdm_dep gfx_24xx_wkdeps[]; extern struct clkdm_dep dsp_24xx_wkdeps[]; extern struct clockdomain wkup_common_clkdm; -extern struct clockdomain prm_common_clkdm; -extern struct clockdomain cm_common_clkdm; #endif diff --git a/arch/arm/mach-omap2/clockdomains2420_data.c b/arch/arm/mach-omap2/clockdomains2420_data.c index 0ab8e46d5b2b..5c741852fac0 100644 --- a/arch/arm/mach-omap2/clockdomains2420_data.c +++ b/arch/arm/mach-omap2/clockdomains2420_data.c @@ -131,8 +131,6 @@ static struct clockdomain dss_2420_clkdm = { static struct clockdomain *clockdomains_omap242x[] __initdata = { &wkup_common_clkdm, - &cm_common_clkdm, - &prm_common_clkdm, &mpu_2420_clkdm, &iva1_2420_clkdm, &dsp_2420_clkdm, diff --git a/arch/arm/mach-omap2/clockdomains2430_data.c b/arch/arm/mach-omap2/clockdomains2430_data.c index 3645ed044890..f09617555e15 100644 --- a/arch/arm/mach-omap2/clockdomains2430_data.c +++ b/arch/arm/mach-omap2/clockdomains2430_data.c @@ -157,8 +157,6 @@ static struct clockdomain dss_2430_clkdm = { static struct clockdomain *clockdomains_omap243x[] __initdata = { &wkup_common_clkdm, - &cm_common_clkdm, - &prm_common_clkdm, &mpu_2430_clkdm, &mdm_clkdm, &dsp_2430_clkdm, diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c index 6038adb97710..2cdc17c9d2fa 100644 --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -347,8 +347,6 @@ static struct clkdm_autodep clkdm_autodeps[] = { static struct clockdomain *clockdomains_omap3430_common[] __initdata = { &wkup_common_clkdm, - &cm_common_clkdm, - &prm_common_clkdm, &mpu_3xxx_clkdm, &neon_clkdm, &iva2_clkdm, diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index c53425847493..bd7ed13515cc 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -430,8 +430,6 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = { &l4_wkup_44xx_clkdm, &emu_sys_44xx_clkdm, &l3_dma_44xx_clkdm, - &prm_common_clkdm, - &cm_common_clkdm, NULL }; diff --git a/arch/arm/mach-omap2/clockdomains_common_data.c b/arch/arm/mach-omap2/clockdomains_common_data.c deleted file mode 100644 index 615b1f04967d..000000000000 --- a/arch/arm/mach-omap2/clockdomains_common_data.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * OMAP2+-common clockdomain data - * - * Copyright (C) 2008-2012 Texas Instruments, Inc. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Paul Walmsley, Jouni Högander - */ - -#include -#include - -#include "clockdomain.h" - -/* These are implicit clockdomains - they are never defined as such in TRM */ -struct clockdomain prm_common_clkdm = { - .name = "prm_clkdm", - .pwrdm = { .name = "wkup_pwrdm" }, -}; - -struct clockdomain cm_common_clkdm = { - .name = "cm_clkdm", - .pwrdm = { .name = "core_pwrdm" }, -}; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index bf86f7e8f91f..32a5e08ffb9b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -810,7 +810,7 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh) if (!cpu_is_omap44xx()) return 0; - if (!oh) + if (!oh || !oh->clkdm) return -EINVAL; if (oh->_int_flags & _HWMOD_NO_MPU_PORT) @@ -1285,23 +1285,22 @@ static struct omap_hwmod *_lookup(const char *name) return oh; } + /** * _init_clkdm - look up a clockdomain name, store pointer in omap_hwmod * @oh: struct omap_hwmod * * * Convert a clockdomain name stored in a struct omap_hwmod into a * clockdomain pointer, and save it into the struct omap_hwmod. - * return -EINVAL if clkdm_name does not exist or if the lookup failed. + * Return -EINVAL if the clkdm_name lookup failed. */ static int _init_clkdm(struct omap_hwmod *oh) { if (cpu_is_omap24xx() || cpu_is_omap34xx()) return 0; - if (!oh->clkdm_name) { - pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name); - return -EINVAL; - } + if (!oh->clkdm_name) + return 0; oh->clkdm = clkdm_lookup(oh->clkdm_name); if (!oh->clkdm) { @@ -1447,16 +1446,20 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name) if (IS_ERR_VALUE(ret)) return ret; - if (cpu_is_omap24xx() || cpu_is_omap34xx()) + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, ohri.rst_shift); - else if (cpu_is_omap44xx()) + } else if (cpu_is_omap44xx()) { + if (!oh->clkdm) + return -EINVAL; + return omap4_prminst_assert_hardreset(ohri.rst_shift, oh->clkdm->pwrdm.ptr->prcm_partition, oh->clkdm->pwrdm.ptr->prcm_offs, oh->prcm.omap4.rstctrl_offs); - else + } else { return -EINVAL; + } } /** @@ -1489,6 +1492,10 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) if (ohri.st_shift) pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", oh->name, name); + + if (!oh->clkdm) + return -EINVAL; + ret = omap4_prminst_deassert_hardreset(ohri.rst_shift, oh->clkdm->pwrdm.ptr->prcm_partition, oh->clkdm->pwrdm.ptr->prcm_offs, @@ -1527,6 +1534,9 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name) return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, ohri.st_shift); } else if (cpu_is_omap44xx()) { + if (!oh->clkdm) + return -EINVAL; + return omap4_prminst_is_hardreset_asserted(ohri.rst_shift, oh->clkdm->pwrdm.ptr->prcm_partition, oh->clkdm->pwrdm.ptr->prcm_offs, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 950454a3fa31..e9e9ec0df64a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2540,14 +2540,12 @@ static struct omap_hwmod omap44xx_prcm_mpu_hwmod = { static struct omap_hwmod omap44xx_cm_core_aon_hwmod = { .name = "cm_core_aon", .class = &omap44xx_prcm_hwmod_class, - .clkdm_name = "cm_clkdm", }; /* cm_core */ static struct omap_hwmod omap44xx_cm_core_hwmod = { .name = "cm_core", .class = &omap44xx_prcm_hwmod_class, - .clkdm_name = "cm_clkdm", }; /* prm */ @@ -2564,7 +2562,6 @@ static struct omap_hwmod_rst_info omap44xx_prm_resets[] = { static struct omap_hwmod omap44xx_prm_hwmod = { .name = "prm", .class = &omap44xx_prcm_hwmod_class, - .clkdm_name = "prm_clkdm", .mpu_irqs = omap44xx_prm_irqs, .rst_lines = omap44xx_prm_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_prm_resets), -- GitLab From 8970b2e4393a34ddf5832f9c1568a88087b0d948 Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:22 +0000 Subject: [PATCH 2047/6849] bnx2x: Add support for external LB This change enables to do self-test with external loopback via ethtool. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 5 +- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 76 +++++++++++++++++-- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 ++ 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 7de824184979..4335f9f51e6f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1817,6 +1817,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define LOAD_NORMAL 0 #define LOAD_OPEN 1 #define LOAD_DIAG 2 +#define LOAD_LOOPBACK_EXT 3 #define UNLOAD_NORMAL 0 #define UNLOAD_CLOSE 1 #define UNLOAD_RECOVERY 2 @@ -1900,12 +1901,14 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PCICFG_LINK_SPEED_SHIFT 16 -#define BNX2X_NUM_TESTS 7 +#define BNX2X_NUM_TESTS 8 #define BNX2X_PHY_LOOPBACK 0 #define BNX2X_MAC_LOOPBACK 1 +#define BNX2X_EXT_LOOPBACK 2 #define BNX2X_PHY_LOOPBACK_FAILED 1 #define BNX2X_MAC_LOOPBACK_FAILED 2 +#define BNX2X_EXT_LOOPBACK_FAILED 3 #define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \ BNX2X_PHY_LOOPBACK_FAILED) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 8098eea9704d..9370f5ffaf4a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2176,6 +2176,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) break; case LOAD_DIAG: + case LOAD_LOOPBACK_EXT: bp->state = BNX2X_STATE_DIAG; break; @@ -2215,7 +2216,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) return -EBUSY; } - bnx2x_dcbx_init(bp); + if (bp->state != BNX2X_STATE_DIAG) + bnx2x_dcbx_init(bp); return 0; #ifndef BNX2X_STOP_ON_ERROR diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index bf30e2829285..68fa902511dc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1538,7 +1538,8 @@ static const struct { } bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { { "register_test (offline)" }, { "memory_test (offline)" }, - { "loopback_test (offline)" }, + { "int_loopback_test (offline)" }, + { "ext_loopback_test (offline)" }, { "nvram_test (online)" }, { "interrupt_test (online)" }, { "link_test (online)" }, @@ -1943,6 +1944,14 @@ static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) if (cnt <= 0 && bnx2x_link_test(bp, is_serdes)) DP(BNX2X_MSG_ETHTOOL, "Timeout waiting for link up\n"); + + cnt = 1400; + while (!bp->link_vars.link_up && cnt--) + msleep(20); + + if (cnt <= 0 && !bp->link_vars.link_up) + DP(BNX2X_MSG_ETHTOOL, + "Timeout waiting for link init\n"); } } @@ -1968,13 +1977,16 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) u16 len; int rc = -ENODEV; u8 *data; - struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txdata->txq_index); + struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, + txdata->txq_index); /* check the loopback mode */ switch (loopback_mode) { case BNX2X_PHY_LOOPBACK: - if (bp->link_params.loopback_mode != LOOPBACK_XGXS) + if (bp->link_params.loopback_mode != LOOPBACK_XGXS) { + DP(BNX2X_MSG_ETHTOOL, "PHY loopback not supported\n"); return -EINVAL; + } break; case BNX2X_MAC_LOOPBACK: if (CHIP_IS_E3(bp)) { @@ -1991,6 +2003,13 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) bnx2x_phy_init(&bp->link_params, &bp->link_vars); break; + case BNX2X_EXT_LOOPBACK: + if (bp->link_params.loopback_mode != LOOPBACK_EXT) { + DP(BNX2X_MSG_ETHTOOL, + "Can't configure external loopback\n"); + return -EINVAL; + } + break; default: DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n"); return -EINVAL; @@ -2162,6 +2181,38 @@ static int bnx2x_test_loopback(struct bnx2x *bp) return rc; } +static int bnx2x_test_ext_loopback(struct bnx2x *bp) +{ + int rc; + u8 is_serdes = + (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; + + if (BP_NOMCP(bp)) + return -ENODEV; + + if (!netif_running(bp->dev)) + return BNX2X_EXT_LOOPBACK_FAILED; + + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_LOOPBACK_EXT); + if (rc) { + DP(BNX2X_MSG_ETHTOOL, + "Can't perform self-test, nic_load (for external lb) failed\n"); + return -ENODEV; + } + bnx2x_wait_for_link(bp, 1, is_serdes); + + bnx2x_netif_stop(bp, 1); + + rc = bnx2x_run_loopback(bp, BNX2X_EXT_LOOPBACK); + if (rc) + DP(BNX2X_MSG_ETHTOOL, "EXT loopback failed (res %d)\n", rc); + + bnx2x_netif_start(bp); + + return rc; +} + #define CRC32_RESIDUAL 0xdebb20e3 static int bnx2x_test_nvram(struct bnx2x *bp) @@ -2263,6 +2314,10 @@ static void bnx2x_self_test(struct net_device *dev, etest->flags |= ETH_TEST_FL_FAILED; return; } + DP(BNX2X_MSG_ETHTOOL, + "Self-test command parameters: offline = %d, external_lb = %d\n", + (etest->flags & ETH_TEST_FL_OFFLINE), + (etest->flags & ETH_TEST_FL_EXTERNAL_LB)>>2); memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS); @@ -2300,10 +2355,17 @@ static void bnx2x_self_test(struct net_device *dev, etest->flags |= ETH_TEST_FL_FAILED; } - buf[2] = bnx2x_test_loopback(bp); + buf[2] = bnx2x_test_loopback(bp); /* internal LB */ if (buf[2] != 0) etest->flags |= ETH_TEST_FL_FAILED; + if (etest->flags & ETH_TEST_FL_EXTERNAL_LB) { + buf[3] = bnx2x_test_ext_loopback(bp); /* external LB */ + if (buf[3] != 0) + etest->flags |= ETH_TEST_FL_FAILED; + etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE; + } + bnx2x_nic_unload(bp, UNLOAD_NORMAL); /* restore input for TX port IF */ @@ -2314,16 +2376,16 @@ static void bnx2x_self_test(struct net_device *dev, bnx2x_wait_for_link(bp, link_up, is_serdes); } if (bnx2x_test_nvram(bp) != 0) { - buf[3] = 1; + buf[4] = 1; etest->flags |= ETH_TEST_FL_FAILED; } if (bnx2x_test_intr(bp) != 0) { - buf[4] = 1; + buf[5] = 1; etest->flags |= ETH_TEST_FL_FAILED; } if (bnx2x_link_test(bp, is_serdes) != 0) { - buf[5] = 1; + buf[6] = 1; etest->flags |= ETH_TEST_FL_FAILED; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index a622bb7bf21d..cebc557f0b37 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -2124,6 +2124,11 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) } } + if (load_mode == LOAD_LOOPBACK_EXT) { + struct link_params *lp = &bp->link_params; + lp->loopback_mode = LOOPBACK_EXT; + } + rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); bnx2x_release_phy_lock(bp); -- GitLab From cf2c1df62e065bfc15e38daf2d3479a56b320f29 Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:23 +0000 Subject: [PATCH 2048/6849] bnx2x: Return only online tests for MF 1. In multi-function device, show only the online tests in self-test results as only these test are performed (offline tests cannot be performed as they may corrupt the traffic of other functions on the same physical port). Note that multi-function mode cannot change while the driver is up. 2. Check result code in NIC load and act accordingly. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 6 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 85 +++++++++++++------ 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 4335f9f51e6f..8ee4bfc1b0bb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1900,8 +1900,10 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PCICFG_LINK_SPEED 0xf0000 #define PCICFG_LINK_SPEED_SHIFT 16 - -#define BNX2X_NUM_TESTS 8 +#define BNX2X_NUM_TESTS_SF 7 +#define BNX2X_NUM_TESTS_MF 3 +#define BNX2X_NUM_TESTS(bp) (IS_MF(bp) ? BNX2X_NUM_TESTS_MF : \ + BNX2X_NUM_TESTS_SF) #define BNX2X_PHY_LOOPBACK 0 #define BNX2X_MAC_LOOPBACK 1 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 68fa902511dc..ed2b49a0c5a5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -826,7 +826,7 @@ static void bnx2x_get_drvinfo(struct net_device *dev, ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver); strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); info->n_stats = BNX2X_NUM_STATS; - info->testinfo_len = BNX2X_NUM_TESTS; + info->testinfo_len = BNX2X_NUM_TESTS(bp); info->eedump_len = bp->common.flash_size; info->regdump_len = bnx2x_get_regs_len(dev); } @@ -1533,17 +1533,14 @@ static int bnx2x_set_pauseparam(struct net_device *dev, return 0; } -static const struct { - char string[ETH_GSTRING_LEN]; -} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { - { "register_test (offline)" }, - { "memory_test (offline)" }, - { "int_loopback_test (offline)" }, - { "ext_loopback_test (offline)" }, - { "nvram_test (online)" }, - { "interrupt_test (online)" }, - { "link_test (online)" }, - { "idle check (online)" } +char *bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF] = { + "register_test (offline) ", + "memory_test (offline) ", + "int_loopback_test (offline)", + "ext_loopback_test (offline)", + "nvram_test (online) ", + "interrupt_test (online) ", + "link_test (online) " }; static u32 bnx2x_eee_to_adv(u32 eee_adv) @@ -2308,6 +2305,8 @@ static void bnx2x_self_test(struct net_device *dev, { struct bnx2x *bp = netdev_priv(dev); u8 is_serdes; + int rc; + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { netdev_err(bp->dev, "Handling parity error recovery. Try again later\n"); @@ -2319,17 +2318,18 @@ static void bnx2x_self_test(struct net_device *dev, (etest->flags & ETH_TEST_FL_OFFLINE), (etest->flags & ETH_TEST_FL_EXTERNAL_LB)>>2); - memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS); + memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp)); - if (!netif_running(dev)) + if (!netif_running(dev)) { + DP(BNX2X_MSG_ETHTOOL, + "Can't perform self-test when interface is down\n"); return; + } - /* offline tests are not supported in MF mode */ - if (IS_MF(bp)) - etest->flags &= ~ETH_TEST_FL_OFFLINE; is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; - if (etest->flags & ETH_TEST_FL_OFFLINE) { + /* offline tests are not supported in MF mode */ + if ((etest->flags & ETH_TEST_FL_OFFLINE) && !IS_MF(bp)) { int port = BP_PORT(bp); u32 val; u8 link_up; @@ -2342,7 +2342,14 @@ static void bnx2x_self_test(struct net_device *dev, link_up = bp->link_vars.link_up; bnx2x_nic_unload(bp, UNLOAD_NORMAL); - bnx2x_nic_load(bp, LOAD_DIAG); + rc = bnx2x_nic_load(bp, LOAD_DIAG); + if (rc) { + etest->flags |= ETH_TEST_FL_FAILED; + DP(BNX2X_MSG_ETHTOOL, + "Can't perform self-test, nic_load (for offline) failed\n"); + return; + } + /* wait until link state is restored */ bnx2x_wait_for_link(bp, 1, is_serdes); @@ -2370,22 +2377,36 @@ static void bnx2x_self_test(struct net_device *dev, /* restore input for TX port IF */ REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val); - - bnx2x_nic_load(bp, LOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_NORMAL); + if (rc) { + etest->flags |= ETH_TEST_FL_FAILED; + DP(BNX2X_MSG_ETHTOOL, + "Can't perform self-test, nic_load (for online) failed\n"); + return; + } /* wait until link state is restored */ bnx2x_wait_for_link(bp, link_up, is_serdes); } if (bnx2x_test_nvram(bp) != 0) { - buf[4] = 1; + if (!IS_MF(bp)) + buf[4] = 1; + else + buf[0] = 1; etest->flags |= ETH_TEST_FL_FAILED; } if (bnx2x_test_intr(bp) != 0) { - buf[5] = 1; + if (!IS_MF(bp)) + buf[5] = 1; + else + buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } if (bnx2x_link_test(bp, is_serdes) != 0) { - buf[6] = 1; + if (!IS_MF(bp)) + buf[6] = 1; + else + buf[2] = 1; etest->flags |= ETH_TEST_FL_FAILED; } @@ -2430,7 +2451,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) return num_stats; case ETH_SS_TEST: - return BNX2X_NUM_TESTS; + return BNX2X_NUM_TESTS(bp); default: return -EINVAL; @@ -2440,7 +2461,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) { struct bnx2x *bp = netdev_priv(dev); - int i, j, k; + int i, j, k, offset, start; char queue_name[MAX_QUEUE_NAME_LEN+1]; switch (stringset) { @@ -2471,7 +2492,17 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) break; case ETH_SS_TEST: - memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr)); + /* First 4 tests cannot be done in MF mode */ + if (!IS_MF(bp)) + start = 0; + else + start = 4; + for (i = 0, j = start; j < (start + BNX2X_NUM_TESTS(bp)); + i++, j++) { + offset = sprintf(buf+32*i, "%s", + bnx2x_tests_str_arr[j]); + *(buf+offset) = '\0'; + } break; } } -- GitLab From 5d317c6a9597267643b6ce6593c4d1785eb1b8df Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:24 +0000 Subject: [PATCH 2049/6849] bnx2x: Add support for 4-tupple UDP RSS This change enables to control via ethtool whether to do UDP RSS on 2-tupple (IP source / destination only) or on 4-tupple (include UDP source / destination port). It also enables to read back the RSS configuration. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 16 ++- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 8 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 136 +++++++++++++++++- .../net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 8 ++ .../net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 6 + 5 files changed, 159 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 9370f5ffaf4a..f4366f79c117 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1666,14 +1666,13 @@ static void bnx2x_set_rx_buf_size(struct bnx2x *bp) static int bnx2x_init_rss_pf(struct bnx2x *bp) { int i; - u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0}; u8 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp); /* Prepare the initial contents fo the indirection table if RSS is * enabled */ - for (i = 0; i < sizeof(ind_table); i++) - ind_table[i] = + for (i = 0; i < sizeof(bp->rss_conf_obj.ind_table); i++) + bp->rss_conf_obj.ind_table[i] = bp->fp->cl_id + ethtool_rxfh_indir_default(i, num_eth_queues); @@ -1685,12 +1684,11 @@ static int bnx2x_init_rss_pf(struct bnx2x *bp) * For 57712 and newer on the other hand it's a per-function * configuration. */ - return bnx2x_config_rss_eth(bp, ind_table, - bp->port.pmf || !CHIP_IS_E1x(bp)); + return bnx2x_config_rss_eth(bp, bp->port.pmf || !CHIP_IS_E1x(bp)); } int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj, - u8 *ind_table, bool config_hash) + bool config_hash) { struct bnx2x_config_rss_params params = {NULL}; int i; @@ -1713,11 +1711,15 @@ int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj, __set_bit(BNX2X_RSS_IPV4_TCP, ¶ms.rss_flags); __set_bit(BNX2X_RSS_IPV6, ¶ms.rss_flags); __set_bit(BNX2X_RSS_IPV6_TCP, ¶ms.rss_flags); + if (rss_obj->udp_rss_v4) + __set_bit(BNX2X_RSS_IPV4_UDP, ¶ms.rss_flags); + if (rss_obj->udp_rss_v6) + __set_bit(BNX2X_RSS_IPV6_UDP, ¶ms.rss_flags); /* Hash bits */ params.rss_result_mask = MULTI_MASK; - memcpy(params.ind_table, ind_table, sizeof(params.ind_table)); + memcpy(params.ind_table, rss_obj->ind_table, sizeof(params.ind_table)); if (config_hash) { /* RSS keys */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 7cd99b75347a..bb479843d59c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -94,7 +94,7 @@ void bnx2x_send_unload_done(struct bnx2x *bp); * @config_hash: re-configure RSS hash keys configuration */ int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj, - u8 *ind_table, bool config_hash); + bool config_hash); /** * bnx2x__init_func_obj - init function object @@ -865,11 +865,9 @@ static inline int func_by_vn(struct bnx2x *bp, int vn) return 2 * vn + BP_PORT(bp); } -static inline int bnx2x_config_rss_eth(struct bnx2x *bp, u8 *ind_table, - bool config_hash) +static inline int bnx2x_config_rss_eth(struct bnx2x *bp, bool config_hash) { - return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, ind_table, - config_hash); + return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, config_hash); } /** diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index ed2b49a0c5a5..d096813994b2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2600,6 +2600,41 @@ static int bnx2x_set_phys_id(struct net_device *dev, return 0; } +static int bnx2x_get_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info) +{ + + switch (info->flow_type) { + case TCP_V4_FLOW: + case TCP_V6_FLOW: + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + break; + case UDP_V4_FLOW: + if (bp->rss_conf_obj.udp_rss_v4) + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + else + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case UDP_V6_FLOW: + if (bp->rss_conf_obj.udp_rss_v6) + info->data = RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + else + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + case IPV4_FLOW: + case IPV6_FLOW: + info->data = RXH_IP_SRC | RXH_IP_DST; + break; + default: + info->data = 0; + break; + } + + return 0; +} + static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, u32 *rules __always_unused) { @@ -2609,7 +2644,102 @@ static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, case ETHTOOL_GRXRINGS: info->data = BNX2X_NUM_ETH_QUEUES(bp); return 0; + case ETHTOOL_GRXFH: + return bnx2x_get_rss_flags(bp, info); + default: + DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n"); + return -EOPNOTSUPP; + } +} + +static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info) +{ + int udp_rss_requested; + + DP(BNX2X_MSG_ETHTOOL, + "Set rss flags command parameters: flow type = %d, data = %llu\n", + info->flow_type, info->data); + + switch (info->flow_type) { + case TCP_V4_FLOW: + case TCP_V6_FLOW: + /* For TCP only 4-tupple hash is supported */ + if (info->data ^ (RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + DP(BNX2X_MSG_ETHTOOL, + "Command parameters not supported\n"); + return -EINVAL; + } else { + return 0; + } + + case UDP_V4_FLOW: + case UDP_V6_FLOW: + /* For UDP either 2-tupple hash or 4-tupple hash is supported */ + if (info->data == (RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3)) + udp_rss_requested = 1; + else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) + udp_rss_requested = 0; + else + return -EINVAL; + if ((info->flow_type == UDP_V4_FLOW) && + (bp->rss_conf_obj.udp_rss_v4 != udp_rss_requested)) { + bp->rss_conf_obj.udp_rss_v4 = udp_rss_requested; + DP(BNX2X_MSG_ETHTOOL, + "rss re-configured, UDP 4-tupple %s\n", + udp_rss_requested ? "enabled" : "disabled"); + return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, 0); + } else if ((info->flow_type == UDP_V6_FLOW) && + (bp->rss_conf_obj.udp_rss_v6 != udp_rss_requested)) { + bp->rss_conf_obj.udp_rss_v6 = udp_rss_requested; + return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, 0); + DP(BNX2X_MSG_ETHTOOL, + "rss re-configured, UDP 4-tupple %s\n", + udp_rss_requested ? "enabled" : "disabled"); + } else { + return 0; + } + case IPV4_FLOW: + case IPV6_FLOW: + /* For IP only 2-tupple hash is supported */ + if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) { + DP(BNX2X_MSG_ETHTOOL, + "Command parameters not supported\n"); + return -EINVAL; + } else { + return 0; + } + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IP_USER_FLOW: + case ETHER_FLOW: + /* RSS is not supported for these protocols */ + if (info->data) { + DP(BNX2X_MSG_ETHTOOL, + "Command parameters not supported\n"); + return -EINVAL; + } else { + return 0; + } + default: + return -EINVAL; + } +} + +static int bnx2x_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info) +{ + struct bnx2x *bp = netdev_priv(dev); + switch (info->cmd) { + case ETHTOOL_SRXFH: + return bnx2x_set_rss_flags(bp, info); default: DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n"); return -EOPNOTSUPP; @@ -2649,7 +2779,6 @@ static int bnx2x_set_rxfh_indir(struct net_device *dev, const u32 *indir) { struct bnx2x *bp = netdev_priv(dev); size_t i; - u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0}; for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) { /* @@ -2661,10 +2790,10 @@ static int bnx2x_set_rxfh_indir(struct net_device *dev, const u32 *indir) * align the received table to the Client ID of the leading RSS * queue */ - ind_table[i] = indir[i] + bp->fp->cl_id; + bp->rss_conf_obj.ind_table[i] = indir[i] + bp->fp->cl_id; } - return bnx2x_config_rss_eth(bp, ind_table, false); + return bnx2x_config_rss_eth(bp, false); } static const struct ethtool_ops bnx2x_ethtool_ops = { @@ -2694,6 +2823,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .set_phys_id = bnx2x_set_phys_id, .get_ethtool_stats = bnx2x_get_ethtool_stats, .get_rxnfc = bnx2x_get_rxnfc, + .set_rxnfc = bnx2x_set_rxnfc, .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, .get_rxfh_indir = bnx2x_get_rxfh_indir, .set_rxfh_indir = bnx2x_set_rxfh_indir, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 6c14b4a4e82c..734fd87cd990 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -4107,6 +4107,10 @@ static int bnx2x_setup_rss(struct bnx2x *bp, data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_IPV4_TCP_CAPABILITY; + if (test_bit(BNX2X_RSS_IPV4_UDP, &p->rss_flags)) + data->capabilities |= + ETH_RSS_UPDATE_RAMROD_DATA_IPV4_UDP_CAPABILITY; + if (test_bit(BNX2X_RSS_IPV6, &p->rss_flags)) data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_IPV6_CAPABILITY; @@ -4115,6 +4119,10 @@ static int bnx2x_setup_rss(struct bnx2x *bp, data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY; + if (test_bit(BNX2X_RSS_IPV6_UDP, &p->rss_flags)) + data->capabilities |= + ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY; + /* Hashing mask */ data->rss_result_mask = p->rss_result_mask; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index efd80bdd0dfe..76818ef08f9b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -694,8 +694,10 @@ enum { BNX2X_RSS_IPV4, BNX2X_RSS_IPV4_TCP, + BNX2X_RSS_IPV4_UDP, BNX2X_RSS_IPV6, BNX2X_RSS_IPV6_TCP, + BNX2X_RSS_IPV6_UDP, }; struct bnx2x_config_rss_params { @@ -729,6 +731,10 @@ struct bnx2x_rss_config_obj { /* Last configured indirection table */ u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE]; + /* flags for enabling 4-tupple hash on UDP */ + u8 udp_rss_v4; + u8 udp_rss_v6; + int (*config_rss)(struct bnx2x *bp, struct bnx2x_config_rss_params *p); }; -- GitLab From a052997ea32164b2466daff8db5f783131184dae Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:25 +0000 Subject: [PATCH 2050/6849] bnx2x: Allow more than 64 L2 CIDs With increased number of RSS queues, each multiplied by the number of traffic- classes, we may have up to 64*3=192 CIDs. The current driver scheme with regard to context allocation supports only 64 CIDs. The new scheme enables scatter- gatehr list of pages for the context. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 10 ++- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 67 ++++++++++++++----- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 8ee4bfc1b0bb..c0c539fd2490 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -978,8 +978,8 @@ union cdu_context { }; /* CDU host DB constants */ -#define CDU_ILT_PAGE_SZ_HW 3 -#define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 64K */ +#define CDU_ILT_PAGE_SZ_HW 2 +#define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */ #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) #ifdef BCM_CNIC @@ -1420,7 +1420,11 @@ struct bnx2x { dma_addr_t fw_stats_data_mapping; int fw_stats_data_sz; - struct hw_context context; + /* For max 196 cids (64*3 + non-eth), 32KB ILT page size and 1KB + * context size we need 8 ILT entries. + */ +#define ILT_MAX_L2_LINES 8 + struct hw_context context[ILT_MAX_L2_LINES]; struct bnx2x_ilt *ilt; #define BP_ILT(bp) ((bp)->ilt) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index cebc557f0b37..9b216e64c4fc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -7068,12 +7068,10 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; for (i = 0; i < L2_ILT_LINES(bp); i++) { - ilt->lines[cdu_ilt_start + i].page = - bp->context.vcxt + (ILT_PAGE_CIDS * i); + ilt->lines[cdu_ilt_start + i].page = bp->context[i].vcxt; ilt->lines[cdu_ilt_start + i].page_mapping = - bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i); - /* cdu ilt pages are allocated manually so there's no need to - set the size */ + bp->context[i].cxt_mapping; + ilt->lines[cdu_ilt_start + i].size = bp->context[i].size; } bnx2x_ilt_init_op(bp, INITOP_SET); @@ -7340,6 +7338,8 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) void bnx2x_free_mem(struct bnx2x *bp) { + int i; + /* fastpath */ bnx2x_free_fp_mem(bp); /* end of fastpath */ @@ -7353,9 +7353,9 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); - BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping, - bp->context.size); - + for (i = 0; i < L2_ILT_LINES(bp); i++) + BNX2X_PCI_FREE(bp->context[i].vcxt, bp->context[i].cxt_mapping, + bp->context[i].size); bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); BNX2X_FREE(bp->ilt->lines); @@ -7441,6 +7441,8 @@ alloc_mem_err: int bnx2x_alloc_mem(struct bnx2x *bp) { + int i, allocated, context_size; + #ifdef BCM_CNIC if (!CHIP_IS_E1x(bp)) /* size = the status block + ramrod buffers */ @@ -7470,11 +7472,29 @@ int bnx2x_alloc_mem(struct bnx2x *bp) if (bnx2x_alloc_fw_stats_mem(bp)) goto alloc_mem_err; - bp->context.size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp); - - BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, - bp->context.size); + /* Allocate memory for CDU context: + * This memory is allocated separately and not in the generic ILT + * functions because CDU differs in few aspects: + * 1. There are multiple entities allocating memory for context - + * 'regular' driver, CNIC and SRIOV driver. Each separately controls + * its own ILT lines. + * 2. Since CDU page-size is not a single 4KB page (which is the case + * for the other ILT clients), to be efficient we want to support + * allocation of sub-page-size in the last entry. + * 3. Context pointers are used by the driver to pass to FW / update + * the context (for the other ILT clients the pointers are used just to + * free the memory during unload). + */ + context_size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp); + for (i = 0, allocated = 0; allocated < context_size; i++) { + bp->context[i].size = min(CDU_ILT_PAGE_SZ, + (context_size - allocated)); + BNX2X_PCI_ALLOC(bp->context[i].vcxt, + &bp->context[i].cxt_mapping, + bp->context[i].size); + allocated += bp->context[i].size; + } BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) @@ -7748,6 +7768,8 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp, { u8 cos; + int cxt_index, cxt_offset; + /* FCoE Queue uses Default SB, thus has no HC capabilities */ if (!IS_FCOE_FP(fp)) { __set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags); @@ -7784,9 +7806,13 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp, fp->index, init_params->max_cos); /* set the context pointers queue object */ - for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) + for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) { + cxt_index = fp->txdata[cos].cid / ILT_PAGE_CIDS; + cxt_offset = fp->txdata[cos].cid - (cxt_index * + ILT_PAGE_CIDS); init_params->cxts[cos] = - &bp->context.vcxt[fp->txdata[cos].cid].eth; + &bp->context[cxt_index].vcxt[cxt_offset].eth; + } } int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp, @@ -12202,6 +12228,7 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp) static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) { struct eth_spe *spe; + int cxt_index, cxt_offset; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -12224,10 +12251,16 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) * ramrod */ if (type == ETH_CONNECTION_TYPE) { - if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) - bnx2x_set_ctx_validation(bp, &bp->context. - vcxt[BNX2X_ISCSI_ETH_CID].eth, + if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) { + cxt_index = BNX2X_ISCSI_ETH_CID / + ILT_PAGE_CIDS; + cxt_offset = BNX2X_ISCSI_ETH_CID - + (cxt_index * ILT_PAGE_CIDS); + bnx2x_set_ctx_validation(bp, + &bp->context[cxt_index]. + vcxt[cxt_offset].eth, BNX2X_ISCSI_ETH_CID); + } } /* -- GitLab From 65565884fba67d9254f32d239b0fb6c38fae88aa Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:26 +0000 Subject: [PATCH 2051/6849] bnx2x: Make the transmission queues adjacent In the current scheme the transmission queues of traffic-class 0 were 0-15, the transmission queues of traffic-class 1 were 16-31 and so on. If the number of RSS queues was smaller than 16, there were gaps in transmission queues numbering, as well as in CIDs numbering. This is both a waste (especially when 16 is increased to 64), and may causes problems with flushing queues when reducing the number of RSS queues (using ethtool -L). The new scheme eliminates the gaps. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 66 ++++++----- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 105 +++++++++++------- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 14 ++- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 42 +++---- .../net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 4 +- 6 files changed, 139 insertions(+), 94 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index c0c539fd2490..d06064b0d063 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -276,29 +276,32 @@ enum { #define FIRST_TX_ONLY_COS_INDEX 1 #define FIRST_TX_COS_INDEX 0 -/* defines for decodeing the fastpath index and the cos index out of the - * transmission queue index - */ #define MAX_TXQS_PER_COS FP_SB_MAX_E1x -#define TXQ_TO_FP(txq_index) ((txq_index) % MAX_TXQS_PER_COS) -#define TXQ_TO_COS(txq_index) ((txq_index) / MAX_TXQS_PER_COS) - /* rules for calculating the cids of tx-only connections */ -#define CID_TO_FP(cid) ((cid) % MAX_TXQS_PER_COS) -#define CID_COS_TO_TX_ONLY_CID(cid, cos) (cid + cos * MAX_TXQS_PER_COS) +#define CID_TO_FP(cid, bp) ((cid) % BNX2X_NUM_NON_CNIC_QUEUES(bp)) +#define CID_COS_TO_TX_ONLY_CID(cid, cos, bp) \ + (cid + cos * BNX2X_NUM_NON_CNIC_QUEUES(bp)) /* fp index inside class of service range */ -#define FP_COS_TO_TXQ(fp, cos) ((fp)->index + cos * MAX_TXQS_PER_COS) - -/* - * 0..15 eth cos0 - * 16..31 eth cos1 if applicable - * 32..47 eth cos2 If applicable - * fcoe queue follows eth queues (16, 32, 48 depending on cos) +#define FP_COS_TO_TXQ(fp, cos, bp) \ + ((fp)->index + cos * BNX2X_NUM_NON_CNIC_QUEUES(bp)) + +/* Indexes for transmission queues array: + * txdata for RSS i CoS j is at location i + (j * num of RSS) + * txdata for FCoE (if exist) is at location max cos * num of RSS + * txdata for FWD (if exist) is one location after FCoE + * txdata for OOO (if exist) is one location after FWD */ -#define MAX_ETH_TXQ_IDX(bp) (MAX_TXQS_PER_COS * (bp)->max_cos) -#define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp)) +enum { + FCOE_TXQ_IDX_OFFSET, + FWD_TXQ_IDX_OFFSET, + OOO_TXQ_IDX_OFFSET, +}; +#define MAX_ETH_TXQ_IDX(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) * (bp)->max_cos) +#ifdef BCM_CNIC +#define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp) + FCOE_TXQ_IDX_OFFSET) +#endif /* fast path */ /* @@ -481,6 +484,8 @@ struct bnx2x_fp_txdata { __le16 *tx_cons_sb; int txq_index; + struct bnx2x_fastpath *parent_fp; + int tx_ring_size; }; enum bnx2x_tpa_mode_t { @@ -507,7 +512,7 @@ struct bnx2x_fastpath { enum bnx2x_tpa_mode_t mode; u8 max_cos; /* actual number of active tx coses */ - struct bnx2x_fp_txdata txdata[BNX2X_MULTI_TX_COS]; + struct bnx2x_fp_txdata *txdata_ptr[BNX2X_MULTI_TX_COS]; struct sw_rx_bd *rx_buf_ring; /* BDs mappings ring */ struct sw_rx_page *rx_page_ring; /* SGE pages mappings ring */ @@ -579,19 +584,22 @@ struct bnx2x_fastpath { /* Use 2500 as a mini-jumbo MTU for FCoE */ #define BNX2X_FCOE_MINI_JUMBO_MTU 2500 -/* FCoE L2 `fastpath' entry is right after the eth entries */ -#define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp) -#define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX]) -#define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) -#define bnx2x_fcoe_tx(bp, var) (bnx2x_fcoe_fp(bp)-> \ - txdata[FIRST_TX_COS_INDEX].var) +#define FCOE_IDX_OFFSET 0 + +#define FCOE_IDX(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) + \ + FCOE_IDX_OFFSET) +#define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX(bp)]) +#define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) +#define bnx2x_fcoe_tx(bp, var) (bnx2x_fcoe_fp(bp)-> \ + txdata_ptr[FIRST_TX_COS_INDEX] \ + ->var) #define IS_ETH_FP(fp) (fp->index < \ BNX2X_NUM_ETH_QUEUES(fp->bp)) #ifdef BCM_CNIC -#define IS_FCOE_FP(fp) (fp->index == FCOE_IDX) -#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX) +#define IS_FCOE_FP(fp) (fp->index == FCOE_IDX(fp->bp)) +#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX(bp)) #else #define IS_FCOE_FP(fp) false #define IS_FCOE_IDX(idx) false @@ -1187,6 +1195,8 @@ struct bnx2x { * are grouped together in the beginning of the structure */ struct bnx2x_fastpath *fp; + struct bnx2x_fp_txdata *bnx2x_txq; + int bnx2x_txq_size; void __iomem *regview; void __iomem *doorbells; u16 db_size; @@ -1389,6 +1399,7 @@ struct bnx2x { u8 igu_dsb_id; u8 igu_base_sb; u8 igu_sb_cnt; + dma_addr_t def_status_blk_mapping; struct bnx2x_slowpath *slowpath; @@ -1443,7 +1454,6 @@ struct bnx2x { NON_ETH_CONTEXT_USE + CNIC_PRESENT) #define L2_ILT_LINES(bp) (DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\ ILT_PAGE_CIDS)) -#define BNX2X_DB_SIZE(bp) (BNX2X_L2_CID_COUNT(bp) * (1 << BNX2X_DB_SHIFT)) int qm_cid_count; @@ -1602,6 +1612,8 @@ struct bnx2x { extern int num_queues; #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NON_ETH_CONTEXT_USE) +#define BNX2X_NUM_NON_CNIC_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - \ + NON_ETH_CONTEXT_USE) #define BNX2X_NUM_RX_QUEUES(bp) BNX2X_NUM_QUEUES(bp) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index f4366f79c117..d99f20ace9df 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -40,12 +40,15 @@ * Makes sure the contents of the bp->fp[to].napi is kept * intact. This is done by first copying the napi struct from * the target to the source, and then mem copying the entire - * source onto the target + * source onto the target. Update txdata pointers and related + * content. */ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) { struct bnx2x_fastpath *from_fp = &bp->fp[from]; struct bnx2x_fastpath *to_fp = &bp->fp[to]; + int old_max_eth_txqs, new_max_eth_txqs; + int old_txdata_index = 0, new_txdata_index = 0; /* Copy the NAPI object as it has been already initialized */ from_fp->napi = to_fp->napi; @@ -53,6 +56,24 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) /* Move bnx2x_fastpath contents */ memcpy(to_fp, from_fp, sizeof(*to_fp)); to_fp->index = to; + + /* Update txdata pointers in fp and move txdata content accordingly: + * Each fp consumes 'max_cos' txdata structures, so the index should be + * decremented by max_cos x delta. + */ + + old_max_eth_txqs = BNX2X_NUM_ETH_QUEUES(bp) * (bp)->max_cos; + new_max_eth_txqs = (BNX2X_NUM_ETH_QUEUES(bp) - from + to) * + (bp)->max_cos; + if (from == FCOE_IDX(bp)) { + old_txdata_index = old_max_eth_txqs + FCOE_TXQ_IDX_OFFSET; + new_txdata_index = new_max_eth_txqs + FCOE_TXQ_IDX_OFFSET; + } + + memcpy(&bp->bnx2x_txq[old_txdata_index], + &bp->bnx2x_txq[new_txdata_index], + sizeof(struct bnx2x_fp_txdata)); + to_fp->txdata_ptr[0] = &bp->bnx2x_txq[new_txdata_index]; } int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ @@ -888,7 +909,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) prefetch(fp->rx_cons_sb); for_each_cos_in_tx_queue(fp, cos) - prefetch(fp->txdata[cos].tx_cons_sb); + prefetch(fp->txdata_ptr[cos]->tx_cons_sb); prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); @@ -1205,7 +1226,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp) for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; for_each_cos_in_tx_queue(fp, cos) { - struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; unsigned pkts_compl = 0, bytes_compl = 0; u16 sw_prod = txdata->tx_pkt_prod; @@ -1217,7 +1238,8 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp) sw_cons++; } netdev_tx_reset_queue( - netdev_get_tx_queue(bp->dev, txdata->txq_index)); + netdev_get_tx_queue(bp->dev, + txdata->txq_index)); } } } @@ -1579,6 +1601,8 @@ void bnx2x_set_num_queues(struct bnx2x *bp) #endif /* Add special queues */ bp->num_queues += NON_ETH_CONTEXT_USE; + + BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues); } /** @@ -1607,8 +1631,8 @@ static int bnx2x_set_real_num_queues(struct bnx2x *bp) { int rc, tx, rx; - tx = MAX_TXQS_PER_COS * bp->max_cos; - rx = BNX2X_NUM_ETH_QUEUES(bp); + tx = BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos; + rx = BNX2X_NUM_QUEUES(bp) - NON_ETH_CONTEXT_USE; /* account for fcoe queue */ #ifdef BCM_CNIC @@ -1853,6 +1877,7 @@ bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err) static void bnx2x_bz_fp(struct bnx2x *bp, int index) { struct bnx2x_fastpath *fp = &bp->fp[index]; + int cos; struct napi_struct orig_napi = fp->napi; /* bzero bnx2x_fastpath contents */ if (bp->stats_init) @@ -1902,6 +1927,16 @@ static void bnx2x_bz_fp(struct bnx2x *bp, int index) /* Special queues support only one CoS */ fp->max_cos = 1; + /* Init txdata pointers */ +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp)) + fp->txdata_ptr[0] = &bp->bnx2x_txq[FCOE_TXQ_IDX(bp)]; +#endif + if (IS_ETH_FP(fp)) + for_each_cos_in_tx_queue(fp, cos) + fp->txdata_ptr[cos] = &bp->bnx2x_txq[cos * + BNX2X_NUM_ETH_QUEUES(bp) + index]; + /* * set the tpa flag for each queue. The tpa flag determines the queue * minimal size so it must be set prior to queue memory allocation @@ -1951,11 +1986,13 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* * Zero fastpath structures preserving invariants like napi, which are * allocated only once, fp index, max_cos, bp pointer. - * Also set fp->disable_tpa. + * Also set fp->disable_tpa and txdata_ptr. */ DP(NETIF_MSG_IFUP, "num queues: %d", bp->num_queues); for_each_queue(bp, i) bnx2x_bz_fp(bp, i); + memset(bp->bnx2x_txq, 0, bp->bnx2x_txq_size * + sizeof(struct bnx2x_fp_txdata)); /* Set the receive queues buffer size */ @@ -2302,6 +2339,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Stop Tx */ bnx2x_tx_disable(bp); + netdev_reset_tc(bp->dev); #ifdef BCM_CNIC bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); @@ -2460,8 +2498,8 @@ int bnx2x_poll(struct napi_struct *napi, int budget) #endif for_each_cos_in_tx_queue(fp, cos) - if (bnx2x_tx_queue_has_work(&fp->txdata[cos])) - bnx2x_tx_int(bp, &fp->txdata[cos]); + if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) + bnx2x_tx_int(bp, fp->txdata_ptr[cos]); if (bnx2x_has_rx_work(fp)) { @@ -2838,7 +2876,6 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); - struct bnx2x_fastpath *fp; struct netdev_queue *txq; struct bnx2x_fp_txdata *txdata; struct sw_tx_bd *tx_buf; @@ -2848,7 +2885,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; u32 pbd_e2_parsing_data = 0; u16 pkt_prod, bd_prod; - int nbd, txq_index, fp_index, txdata_index; + int nbd, txq_index; dma_addr_t mapping; u32 xmit_type = bnx2x_xmit_type(bp, skb); int i; @@ -2867,31 +2904,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) BUG_ON(txq_index >= MAX_ETH_TXQ_IDX(bp) + FCOE_PRESENT); - /* decode the fastpath index and the cos index from the txq */ - fp_index = TXQ_TO_FP(txq_index); - txdata_index = TXQ_TO_COS(txq_index); - -#ifdef BCM_CNIC - /* - * Override the above for the FCoE queue: - * - FCoE fp entry is right after the ETH entries. - * - FCoE L2 queue uses bp->txdata[0] only. - */ - if (unlikely(!NO_FCOE(bp) && (txq_index == - bnx2x_fcoe_tx(bp, txq_index)))) { - fp_index = FCOE_IDX; - txdata_index = 0; - } -#endif + txdata = &bp->bnx2x_txq[txq_index]; /* enable this debug print to view the transmission queue being used DP(NETIF_MSG_TX_QUEUED, "indices: txq %d, fp %d, txdata %d\n", txq_index, fp_index, txdata_index); */ - /* locate the fastpath and the txdata */ - fp = &bp->fp[fp_index]; - txdata = &fp->txdata[txdata_index]; - /* enable this debug print to view the tranmission details DP(NETIF_MSG_TX_QUEUED, "transmitting packet cid %d fp index %d txdata_index %d tx_data ptr %p fp pointer %p\n", @@ -2899,7 +2917,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(bnx2x_tx_avail(bp, txdata) < (skb_shinfo(skb)->nr_frags + 3))) { - fp->eth_q_stats.driver_xoff++; + txdata->parent_fp->eth_q_stats.driver_xoff++; netif_tx_stop_queue(txq); BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); return NETDEV_TX_BUSY; @@ -3181,7 +3199,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) * fp->bd_tx_cons */ smp_mb(); - fp->eth_q_stats.driver_xoff++; + txdata->parent_fp->eth_q_stats.driver_xoff++; if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) netif_tx_wake_queue(txq); } @@ -3247,7 +3265,7 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc) /* configure traffic class to transmission queue mapping */ for (cos = 0; cos < bp->max_cos; cos++) { count = BNX2X_NUM_ETH_QUEUES(bp); - offset = cos * MAX_TXQS_PER_COS; + offset = cos * BNX2X_NUM_NON_CNIC_QUEUES(bp); netdev_set_tc_queue(dev, cos, count, offset); DP(BNX2X_MSG_SP | NETIF_MSG_IFUP, "mapping tc %d to offset %d count %d\n", @@ -3346,7 +3364,7 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) if (!skip_tx_queue(bp, fp_index)) { /* fastpath tx rings: tx_buf tx_desc */ for_each_cos_in_tx_queue(fp, cos) { - struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; DP(NETIF_MSG_IFDOWN, "freeing tx memory of fp %d cos %d cid %d\n", @@ -3503,7 +3521,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) if (!skip_tx_queue(bp, index)) { /* fastpath tx rings: tx_buf tx_desc */ for_each_cos_in_tx_queue(fp, cos) { - struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; DP(NETIF_MSG_IFUP, "allocating tx memory of fp %d cos %d\n", @@ -3586,7 +3604,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) #ifdef BCM_CNIC if (!NO_FCOE(bp)) /* FCoE */ - if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX)) + if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX(bp))) /* we will fail load process instead of mark * NO_FCOE_FLAG */ @@ -3611,7 +3629,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) */ /* move FCoE fp even NO_FCOE_FLAG is on */ - bnx2x_move_fp(bp, FCOE_IDX, FCOE_IDX - delta); + bnx2x_move_fp(bp, FCOE_IDX(bp), FCOE_IDX(bp) - delta); #endif bp->num_queues -= delta; BNX2X_ERR("Adjusted num of queues from %d to %d\n", @@ -3624,6 +3642,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) void bnx2x_free_mem_bp(struct bnx2x *bp) { kfree(bp->fp); + kfree(bp->bnx2x_txq); kfree(bp->msix_table); kfree(bp->ilt); } @@ -3648,6 +3667,16 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) goto alloc_err; bp->fp = fp; + /* Allocate memory for the transmission queues array */ + bp->bnx2x_txq_size = BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS; +#ifdef BCM_CNIC + bp->bnx2x_txq_size++; +#endif + bp->bnx2x_txq = kcalloc(bp->bnx2x_txq_size, + sizeof(struct bnx2x_fp_txdata), GFP_KERNEL); + if (!bp->bnx2x_txq) + goto alloc_err; + /* msix table */ tbl = kcalloc(msix_table_size, sizeof(*tbl), GFP_KERNEL); if (!tbl) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bb479843d59c..112ffccb3121 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -728,7 +728,7 @@ static inline bool bnx2x_has_tx_work(struct bnx2x_fastpath *fp) { u8 cos; for_each_cos_in_tx_queue(fp, cos) - if (bnx2x_tx_queue_has_work(&fp->txdata[cos])) + if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) return true; return false; } @@ -1066,12 +1066,14 @@ static inline u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp) } static inline void bnx2x_init_txdata(struct bnx2x *bp, - struct bnx2x_fp_txdata *txdata, u32 cid, int txq_index, - __le16 *tx_cons_sb) + struct bnx2x_fp_txdata *txdata, u32 cid, + int txq_index, __le16 *tx_cons_sb, + struct bnx2x_fastpath *fp) { txdata->cid = cid; txdata->txq_index = txq_index; txdata->tx_cons_sb = tx_cons_sb; + txdata->parent_fp = fp; DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", txdata->cid, txdata->txq_index); @@ -1114,9 +1116,9 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; - - bnx2x_init_txdata(bp, &bnx2x_fcoe(bp, txdata[0]), - fp->cid, FCOE_TXQ_IDX(bp), BNX2X_FCOE_L2_TX_INDEX); + bnx2x_init_txdata(bp, bnx2x_fcoe(bp, txdata_ptr[0]), + fp->cid, FCOE_TXQ_IDX(bp), BNX2X_FCOE_L2_TX_INDEX, + fp); DP(NETIF_MSG_IFUP, "created fcoe tx data (fp index %d)\n", fp->index); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index d096813994b2..b46822356a1c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1959,7 +1959,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) unsigned char *packet; struct bnx2x_fastpath *fp_rx = &bp->fp[0]; struct bnx2x_fastpath *fp_tx = &bp->fp[0]; - struct bnx2x_fp_txdata *txdata = &fp_tx->txdata[0]; + struct bnx2x_fp_txdata *txdata = fp_tx->txdata_ptr[0]; u16 tx_start_idx, tx_idx; u16 rx_start_idx, rx_idx; u16 pkt_prod, bd_prod; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9b216e64c4fc..e1c011e188aa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -758,7 +758,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* Tx */ for_each_cos_in_tx_queue(fp, cos) { - txdata = fp->txdata[cos]; + txdata = *fp->txdata_ptr[cos]; BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x) tx_bd_prod(0x%x) tx_bd_cons(0x%x) *tx_cons_sb(0x%x)\n", i, txdata.tx_pkt_prod, txdata.tx_pkt_cons, txdata.tx_bd_prod, @@ -876,7 +876,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; for_each_cos_in_tx_queue(fp, cos) { - struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; start = TX_BD(le16_to_cpu(*txdata->tx_cons_sb) - 10); end = TX_BD(le16_to_cpu(*txdata->tx_cons_sb) + 245); @@ -1710,7 +1710,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) /* Handle Rx or Tx according to SB id */ prefetch(fp->rx_cons_sb); for_each_cos_in_tx_queue(fp, cos) - prefetch(fp->txdata[cos].tx_cons_sb); + prefetch(fp->txdata_ptr[cos]->tx_cons_sb); prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); status &= ~mask; @@ -2921,7 +2921,7 @@ static void bnx2x_pf_tx_q_prep(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct bnx2x_txq_setup_params *txq_init, u8 cos) { - txq_init->dscr_map = fp->txdata[cos].tx_desc_mapping; + txq_init->dscr_map = fp->txdata_ptr[cos]->tx_desc_mapping; txq_init->sb_cq_index = HC_INDEX_ETH_FIRST_TX_CQ_CONS + cos; txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; txq_init->fw_sb_id = fp->fw_sb_id; @@ -3068,11 +3068,11 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp) /* insert FCoE stats from ramrod response */ if (!NO_FCOE(bp)) { struct tstorm_per_queue_stats *fcoe_q_tstorm_stats = - &bp->fw_stats_data->queue_stats[FCOE_IDX]. + &bp->fw_stats_data->queue_stats[FCOE_IDX(bp)]. tstorm_queue_statistics; struct xstorm_per_queue_stats *fcoe_q_xstorm_stats = - &bp->fw_stats_data->queue_stats[FCOE_IDX]. + &bp->fw_stats_data->queue_stats[FCOE_IDX(bp)]. xstorm_queue_statistics; struct fcoe_statistics_params *fw_fcoe_stat = @@ -4741,7 +4741,7 @@ static void bnx2x_after_function_update(struct bnx2x *bp) #ifdef BCM_CNIC if (!NO_FCOE(bp)) { - fp = &bp->fp[FCOE_IDX]; + fp = &bp->fp[FCOE_IDX(bp)]; queue_params.q_obj = &fp->q_obj; /* clear pending completion bit */ @@ -4778,7 +4778,7 @@ static struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( return &bnx2x_fcoe(bp, q_obj); else #endif - return &bnx2x_fp(bp, CID_TO_FP(cid), q_obj); + return &bnx2x_fp(bp, CID_TO_FP(cid, bp), q_obj); } static void bnx2x_eq_int(struct bnx2x *bp) @@ -5660,11 +5660,11 @@ static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx) /* init tx data */ for_each_cos_in_tx_queue(fp, cos) { - bnx2x_init_txdata(bp, &fp->txdata[cos], - CID_COS_TO_TX_ONLY_CID(fp->cid, cos), - FP_COS_TO_TXQ(fp, cos), - BNX2X_TX_SB_INDEX_BASE + cos); - cids[cos] = fp->txdata[cos].cid; + bnx2x_init_txdata(bp, fp->txdata_ptr[cos], + CID_COS_TO_TX_ONLY_CID(fp->cid, cos, bp), + FP_COS_TO_TXQ(fp, cos, bp), + BNX2X_TX_SB_INDEX_BASE + cos, fp); + cids[cos] = fp->txdata_ptr[cos]->cid; } bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, cids, fp->max_cos, @@ -5719,7 +5719,7 @@ static void bnx2x_init_tx_rings(struct bnx2x *bp) for_each_tx_queue(bp, i) for_each_cos_in_tx_queue(&bp->fp[i], cos) - bnx2x_init_tx_ring_one(&bp->fp[i].txdata[cos]); + bnx2x_init_tx_ring_one(bp->fp[i].txdata_ptr[cos]); } void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) @@ -7807,8 +7807,8 @@ static void bnx2x_pf_q_prep_init(struct bnx2x *bp, /* set the context pointers queue object */ for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) { - cxt_index = fp->txdata[cos].cid / ILT_PAGE_CIDS; - cxt_offset = fp->txdata[cos].cid - (cxt_index * + cxt_index = fp->txdata_ptr[cos]->cid / ILT_PAGE_CIDS; + cxt_offset = fp->txdata_ptr[cos]->cid - (cxt_index * ILT_PAGE_CIDS); init_params->cxts[cos] = &bp->context[cxt_index].vcxt[cxt_offset].eth; @@ -7961,7 +7961,7 @@ static int bnx2x_stop_queue(struct bnx2x *bp, int index) tx_index++){ /* ascertain this is a normal queue*/ - txdata = &fp->txdata[tx_index]; + txdata = fp->txdata_ptr[tx_index]; DP(NETIF_MSG_IFDOWN, "stopping tx-only queue %d\n", txdata->txq_index); @@ -8328,7 +8328,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) struct bnx2x_fastpath *fp = &bp->fp[i]; for_each_cos_in_tx_queue(fp, cos) - rc = bnx2x_clean_tx_queue(bp, &fp->txdata[cos]); + rc = bnx2x_clean_tx_queue(bp, fp->txdata_ptr[cos]); #ifdef BNX2X_STOP_ON_ERROR if (rc) return; @@ -11769,7 +11769,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, struct bnx2x *bp; int pcie_width, pcie_speed; int rc, max_non_def_sbs; - int rx_count, tx_count, rss_count; + int rx_count, tx_count, rss_count, doorbell_size; /* * An estimated maximum supported CoS number according to the chip * version. @@ -11863,8 +11863,10 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, * Map doorbels here as we need the real value of bp->max_cos which * is initialized in bnx2x_init_bp(). */ + doorbell_size = (rss_count * max_cos_est + NON_ETH_CONTEXT_USE + + CNIC_PRESENT) * (1 << BNX2X_DB_SHIFT); bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), - min_t(u64, BNX2X_DB_SIZE(bp), + min_t(u64, doorbell_size, pci_resource_len(pdev, 2))); if (!bp->doorbells) { dev_err(&bp->pdev->dev, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 0e8bdcb9c748..776b52163b11 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1432,7 +1432,7 @@ static void bnx2x_prep_fw_stats_req(struct bnx2x *bp) query[first_queue_query_index + i]; cur_query_entry->kind = STATS_TYPE_QUEUE; - cur_query_entry->index = bnx2x_stats_id(&bp->fp[FCOE_IDX]); + cur_query_entry->index = bnx2x_stats_id(&bp->fp[FCOE_IDX(bp)]); cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp)); cur_query_entry->address.hi = cpu_to_le32(U64_HI(cur_data_offset)); @@ -1573,7 +1573,7 @@ void bnx2x_afex_collect_stats(struct bnx2x *bp, void *void_afex_stats, struct afex_stats *afex_stats = (struct afex_stats *)void_afex_stats; struct bnx2x_eth_stats *estats = &bp->eth_stats; struct per_queue_stats *fcoe_q_stats = - &bp->fw_stats_data->queue_stats[FCOE_IDX]; + &bp->fw_stats_data->queue_stats[FCOE_IDX(bp)]; struct tstorm_per_queue_stats *fcoe_q_tstorm_stats = &fcoe_q_stats->tstorm_queue_statistics; -- GitLab From 37ae41a965fbb810b6a98df7df8ab46fefcc15eb Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:27 +0000 Subject: [PATCH 2052/6849] bnx2x: Move the CNIC L2 CIDs to be right after the RSS CIDs Currently the CNIC-related L2 CIDs (for sending control FCoE / iSCSI packets) were at fixed position, according to the maximal number of RSS queues multiplied by the number of traffic-classes. This change makes the CIDs dynamic, as they are defined to be right after the highest RSS CID. This decreases the memory allocated for the context. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 19 ++++---- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 + .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 15 +++--- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 47 +++++++++++++------ 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index d06064b0d063..234517f132a8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -248,13 +248,12 @@ enum { BNX2X_MAX_CNIC_ETH_CL_ID_IDX, }; -#define BNX2X_CNIC_START_ETH_CID 48 -enum { +#define BNX2X_CNIC_START_ETH_CID(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) *\ + (bp)->max_cos) /* iSCSI L2 */ - BNX2X_ISCSI_ETH_CID = BNX2X_CNIC_START_ETH_CID, +#define BNX2X_ISCSI_ETH_CID(bp) (BNX2X_CNIC_START_ETH_CID(bp)) /* FCoE L2 */ - BNX2X_FCOE_ETH_CID, -}; +#define BNX2X_FCOE_ETH_CID(bp) (BNX2X_CNIC_START_ETH_CID(bp) + 1) /** Additional rings budgeting */ #ifdef BCM_CNIC @@ -276,8 +275,6 @@ enum { #define FIRST_TX_ONLY_COS_INDEX 1 #define FIRST_TX_COS_INDEX 0 -#define MAX_TXQS_PER_COS FP_SB_MAX_E1x - /* rules for calculating the cids of tx-only connections */ #define CID_TO_FP(cid, bp) ((cid) % BNX2X_NUM_NON_CNIC_QUEUES(bp)) #define CID_COS_TO_TX_ONLY_CID(cid, cos, bp) \ @@ -1448,10 +1445,12 @@ struct bnx2x { /* * Maximum CID count that might be required by the bnx2x: - * Max Tss * Max_Tx_Multi_Cos + CNIC L2 Clients (FCoE and iSCSI related) + * Max RSS * Max_Tx_Multi_Cos + FCoE + iSCSI */ -#define BNX2X_L2_CID_COUNT(bp) (MAX_TXQS_PER_COS * BNX2X_MULTI_TX_COS +\ - NON_ETH_CONTEXT_USE + CNIC_PRESENT) +#define BNX2X_L2_CID_COUNT(bp) (BNX2X_NUM_ETH_QUEUES(bp) * BNX2X_MULTI_TX_COS \ + + NON_ETH_CONTEXT_USE + CNIC_PRESENT) +#define BNX2X_L2_MAX_CID(bp) (BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS \ + + NON_ETH_CONTEXT_USE + CNIC_PRESENT) #define L2_ILT_LINES(bp) (DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\ ILT_PAGE_CIDS)) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index d99f20ace9df..cdd9ca42556e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2235,6 +2235,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* re-read iscsi info */ bnx2x_get_iscsi_info(bp); bnx2x_setup_cnic_irq_info(bp); + bnx2x_setup_cnic_info(bp); if (bp->state == BNX2X_STATE_OPEN) bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); #endif diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 112ffccb3121..de79cdf1299b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -244,6 +244,14 @@ int bnx2x_cnic_notify(struct bnx2x *bp, int cmd); * @bp: driver handle */ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); + +/** + * bnx2x_setup_cnic_info - provides cnic with updated info + * + * @bp: driver handle + */ +void bnx2x_setup_cnic_info(struct bnx2x *bp); + #endif /** @@ -1107,12 +1115,7 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) bnx2x_fcoe(bp, rx_queue) = BNX2X_NUM_ETH_QUEUES(bp); bnx2x_fcoe(bp, cl_id) = bnx2x_cnic_eth_cl_id(bp, BNX2X_FCOE_ETH_CL_ID_IDX); - /** Current BNX2X_FCOE_ETH_CID deffinition implies not more than - * 16 ETH clients per function when CNIC is enabled! - * - * Fix it ASAP!!! - */ - bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID; + bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID(bp); bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e1c011e188aa..c9302d9a796c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4628,7 +4628,7 @@ static void bnx2x_handle_classification_eqe(struct bnx2x *bp, case BNX2X_FILTER_MAC_PENDING: DP(BNX2X_MSG_SP, "Got SETUP_MAC completions\n"); #ifdef BCM_CNIC - if (cid == BNX2X_ISCSI_ETH_CID) + if (cid == BNX2X_ISCSI_ETH_CID(bp)) vlan_mac_obj = &bp->iscsi_l2_mac_obj; else #endif @@ -4774,7 +4774,7 @@ static struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( { DP(BNX2X_MSG_SP, "retrieving fp from cid %d\n", cid); #ifdef BCM_CNIC - if (cid == BNX2X_FCOE_ETH_CID) + if (cid == BNX2X_FCOE_ETH_CID(bp)) return &bnx2x_fcoe(bp, q_obj); else #endif @@ -11724,7 +11724,7 @@ void bnx2x__init_func_obj(struct bnx2x *bp) /* must be called after sriov-enable */ static int bnx2x_set_qm_cid_count(struct bnx2x *bp) { - int cid_count = BNX2X_L2_CID_COUNT(bp); + int cid_count = BNX2X_L2_MAX_CID(bp); #ifdef BCM_CNIC cid_count += CNIC_CID_MAX; @@ -11829,9 +11829,9 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* * Maximum number of netdev Tx queues: - * Maximum TSS queues * Maximum supported number of CoS + FCoE L2 + * Maximum TSS queues * Maximum supported number of CoS + FCoE L2 */ - tx_count = MAX_TXQS_PER_COS * max_cos_est + FCOE_PRESENT; + tx_count = rss_count * max_cos_est + FCOE_PRESENT; /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count); @@ -11863,11 +11863,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, * Map doorbels here as we need the real value of bp->max_cos which * is initialized in bnx2x_init_bp(). */ - doorbell_size = (rss_count * max_cos_est + NON_ETH_CONTEXT_USE + - CNIC_PRESENT) * (1 << BNX2X_DB_SHIFT); + doorbell_size = BNX2X_L2_MAX_CID(bp) * (1 << BNX2X_DB_SHIFT); + if (doorbell_size > pci_resource_len(pdev, 2)) { + dev_err(&bp->pdev->dev, + "Cannot map doorbells, bar size too small, aborting\n"); + rc = -ENOMEM; + goto init_one_exit; + } bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), - min_t(u64, doorbell_size, - pci_resource_len(pdev, 2))); + doorbell_size); if (!bp->doorbells) { dev_err(&bp->pdev->dev, "Cannot map doorbell space, aborting\n"); @@ -12254,14 +12258,14 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) */ if (type == ETH_CONNECTION_TYPE) { if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) { - cxt_index = BNX2X_ISCSI_ETH_CID / + cxt_index = BNX2X_ISCSI_ETH_CID(bp) / ILT_PAGE_CIDS; - cxt_offset = BNX2X_ISCSI_ETH_CID - + cxt_offset = BNX2X_ISCSI_ETH_CID(bp) - (cxt_index * ILT_PAGE_CIDS); bnx2x_set_ctx_validation(bp, &bp->context[cxt_index]. vcxt[cxt_offset].eth, - BNX2X_ISCSI_ETH_CID); + BNX2X_ISCSI_ETH_CID(bp)); } } @@ -12615,6 +12619,21 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->num_irq = 2; } +void bnx2x_setup_cnic_info(struct bnx2x *bp) +{ + struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + + + cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + + bnx2x_cid_ilt_lines(bp); + cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS; + cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID(bp); + cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID(bp); + + if (NO_ISCSI_OOO(bp)) + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO; +} + static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, void *data) { @@ -12693,10 +12712,10 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->drv_ctl = bnx2x_drv_ctl; cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; - cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID; + cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID(bp); cp->iscsi_l2_client_id = bnx2x_cnic_eth_cl_id(bp, BNX2X_ISCSI_ETH_CL_ID_IDX); - cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; + cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID(bp); if (NO_ISCSI_OOO(bp)) cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO; -- GitLab From 15192a8cf8a8d16e0ff38a144c8a4630c94f9fd6 Mon Sep 17 00:00:00 2001 From: Barak Witkowski Date: Tue, 19 Jun 2012 07:48:28 +0000 Subject: [PATCH 2053/6849] bnx2x: Split the FP structure This patch moves some fields out of the FP structure to different structures, in order to minimize size of contigiuous memory allocated. Signed-off-by: Barak Witkowski Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 41 +++++--- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 97 ++++++++++++++----- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 8 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 4 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 37 +++---- .../net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 55 +++++++---- 6 files changed, 155 insertions(+), 87 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 234517f132a8..25d46c10dbd4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -549,34 +549,23 @@ struct bnx2x_fastpath { rx_calls; /* TPA related */ - struct bnx2x_agg_info tpa_info[ETH_MAX_AGGREGATION_QUEUES_E1H_E2]; + struct bnx2x_agg_info *tpa_info; u8 disable_tpa; #ifdef BNX2X_STOP_ON_ERROR u64 tpa_queue_used; #endif - - struct tstorm_per_queue_stats old_tclient; - struct ustorm_per_queue_stats old_uclient; - struct xstorm_per_queue_stats old_xclient; - struct bnx2x_eth_q_stats eth_q_stats; - struct bnx2x_eth_q_stats_old eth_q_stats_old; - /* The size is calculated using the following: sizeof name field from netdev structure + 4 ('-Xx-' string) + 4 (for the digits and to make it DWORD aligned) */ #define FP_NAME_SIZE (sizeof(((struct net_device *)0)->name) + 8) char name[FP_NAME_SIZE]; - - /* MACs object */ - struct bnx2x_vlan_mac_obj mac_obj; - - /* Queue State object */ - struct bnx2x_queue_sp_obj q_obj; - }; -#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) +#define bnx2x_fp(bp, nr, var) ((bp)->fp[(nr)].var) +#define bnx2x_sp_obj(bp, fp) ((bp)->sp_objs[(fp)->index]) +#define bnx2x_fp_stats(bp, fp) (&((bp)->fp_stats[(fp)->index])) +#define bnx2x_fp_qstats(bp, fp) (&((bp)->fp_stats[(fp)->index].eth_q_stats)) /* Use 2500 as a mini-jumbo MTU for FCoE */ #define BNX2X_FCOE_MINI_JUMBO_MTU 2500 @@ -587,6 +576,8 @@ struct bnx2x_fastpath { FCOE_IDX_OFFSET) #define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX(bp)]) #define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) +#define bnx2x_fcoe_inner_sp_obj(bp) (&bp->sp_objs[FCOE_IDX(bp)]) +#define bnx2x_fcoe_sp_obj(bp, var) (bnx2x_fcoe_inner_sp_obj(bp)->var) #define bnx2x_fcoe_tx(bp, var) (bnx2x_fcoe_fp(bp)-> \ txdata_ptr[FIRST_TX_COS_INDEX] \ ->var) @@ -1187,11 +1178,29 @@ struct bnx2x_prev_path_list { struct list_head list; }; +struct bnx2x_sp_objs { + /* MACs object */ + struct bnx2x_vlan_mac_obj mac_obj; + + /* Queue State object */ + struct bnx2x_queue_sp_obj q_obj; +}; + +struct bnx2x_fp_stats { + struct tstorm_per_queue_stats old_tclient; + struct ustorm_per_queue_stats old_uclient; + struct xstorm_per_queue_stats old_xclient; + struct bnx2x_eth_q_stats eth_q_stats; + struct bnx2x_eth_q_stats_old eth_q_stats_old; +}; + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure */ struct bnx2x_fastpath *fp; + struct bnx2x_sp_objs *sp_objs; + struct bnx2x_fp_stats *fp_stats; struct bnx2x_fp_txdata *bnx2x_txq; int bnx2x_txq_size; void __iomem *regview; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index cdd9ca42556e..413b665646b7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -47,6 +47,10 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) { struct bnx2x_fastpath *from_fp = &bp->fp[from]; struct bnx2x_fastpath *to_fp = &bp->fp[to]; + struct bnx2x_sp_objs *from_sp_objs = &bp->sp_objs[from]; + struct bnx2x_sp_objs *to_sp_objs = &bp->sp_objs[to]; + struct bnx2x_fp_stats *from_fp_stats = &bp->fp_stats[from]; + struct bnx2x_fp_stats *to_fp_stats = &bp->fp_stats[to]; int old_max_eth_txqs, new_max_eth_txqs; int old_txdata_index = 0, new_txdata_index = 0; @@ -57,6 +61,12 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) memcpy(to_fp, from_fp, sizeof(*to_fp)); to_fp->index = to; + /* move sp_objs contents as well, as their indices match fp ones */ + memcpy(to_sp_objs, from_sp_objs, sizeof(*to_sp_objs)); + + /* move fp_stats contents as well, as their indices match fp ones */ + memcpy(to_fp_stats, from_fp_stats, sizeof(*to_fp_stats)); + /* Update txdata pointers in fp and move txdata content accordingly: * Each fp consumes 'max_cos' txdata structures, so the index should be * decremented by max_cos x delta. @@ -500,7 +510,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, where we are and drop the whole packet */ err = bnx2x_alloc_rx_sge(bp, fp, sge_idx); if (unlikely(err)) { - fp->eth_q_stats.rx_skb_alloc_failed++; + bnx2x_fp_qstats(bp, fp)->rx_skb_alloc_failed++; return err; } @@ -605,7 +615,7 @@ drop: /* drop the packet and keep the buffer in the bin */ DP(NETIF_MSG_RX_STATUS, "Failed to allocate or map a new skb - dropping packet!\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; + bnx2x_fp_stats(bp, fp)->eth_q_stats.rx_skb_alloc_failed++; } static int bnx2x_alloc_rx_data(struct bnx2x *bp, @@ -638,8 +648,10 @@ static int bnx2x_alloc_rx_data(struct bnx2x *bp, return 0; } -static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, - struct bnx2x_fastpath *fp) +static +void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, + struct bnx2x_fastpath *fp, + struct bnx2x_eth_q_stats *qstats) { /* Do nothing if no IP/L4 csum validation was done */ @@ -653,7 +665,7 @@ static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, if (cqe->fast_path_cqe.type_error_flags & (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) - fp->eth_q_stats.hw_csum_err++; + qstats->hw_csum_err++; else skb->ip_summed = CHECKSUM_UNNECESSARY; } @@ -797,7 +809,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) DP(NETIF_MSG_RX_ERR | NETIF_MSG_RX_STATUS, "ERROR flags %x rx packet %u\n", cqe_fp_flags, sw_comp_cons); - fp->eth_q_stats.rx_err_discard_pkt++; + bnx2x_fp_qstats(bp, fp)->rx_err_discard_pkt++; goto reuse_rx; } @@ -810,7 +822,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) if (skb == NULL) { DP(NETIF_MSG_RX_ERR | NETIF_MSG_RX_STATUS, "ERROR packet dropped because of alloc failure\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; + bnx2x_fp_qstats(bp, fp)->rx_skb_alloc_failed++; goto reuse_rx; } memcpy(skb->data, data + pad, len); @@ -824,14 +836,15 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb = build_skb(data, 0); if (unlikely(!skb)) { kfree(data); - fp->eth_q_stats.rx_skb_alloc_failed++; + bnx2x_fp_qstats(bp, fp)-> + rx_skb_alloc_failed++; goto next_rx; } skb_reserve(skb, pad); } else { DP(NETIF_MSG_RX_ERR | NETIF_MSG_RX_STATUS, "ERROR packet dropped because of alloc failure\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; + bnx2x_fp_qstats(bp, fp)->rx_skb_alloc_failed++; reuse_rx: bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); goto next_rx; @@ -847,8 +860,8 @@ reuse_rx: skb_checksum_none_assert(skb); if (bp->dev->features & NETIF_F_RXCSUM) - bnx2x_csum_validate(skb, cqe, fp); - + bnx2x_csum_validate(skb, cqe, fp, + bnx2x_fp_qstats(bp, fp)); skb_record_rx_queue(skb, fp->rx_queue); @@ -1780,7 +1793,7 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp) int rc; unsigned long ramrod_flags = 0, vlan_mac_flags = 0; struct bnx2x_mcast_ramrod_params rparam = {NULL}; - struct bnx2x_vlan_mac_obj *mac_obj = &bp->fp->mac_obj; + struct bnx2x_vlan_mac_obj *mac_obj = &bp->sp_objs->mac_obj; /***************** Cleanup MACs' object first *************************/ @@ -1791,7 +1804,7 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp) /* Clean ETH primary MAC */ __set_bit(BNX2X_ETH_MAC, &vlan_mac_flags); - rc = mac_obj->delete_all(bp, &bp->fp->mac_obj, &vlan_mac_flags, + rc = mac_obj->delete_all(bp, &bp->sp_objs->mac_obj, &vlan_mac_flags, &ramrod_flags); if (rc != 0) BNX2X_ERR("Failed to clean ETH MACs: %d\n", rc); @@ -1877,12 +1890,16 @@ bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err) static void bnx2x_bz_fp(struct bnx2x *bp, int index) { struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x_fp_stats *fp_stats = &bp->fp_stats[index]; + int cos; struct napi_struct orig_napi = fp->napi; + struct bnx2x_agg_info *orig_tpa_info = fp->tpa_info; /* bzero bnx2x_fastpath contents */ - if (bp->stats_init) + if (bp->stats_init) { + memset(fp->tpa_info, 0, sizeof(*fp->tpa_info)); memset(fp, 0, sizeof(*fp)); - else { + } else { /* Keep Queue statistics */ struct bnx2x_eth_q_stats *tmp_eth_q_stats; struct bnx2x_eth_q_stats_old *tmp_eth_q_stats_old; @@ -1890,26 +1907,27 @@ static void bnx2x_bz_fp(struct bnx2x *bp, int index) tmp_eth_q_stats = kzalloc(sizeof(struct bnx2x_eth_q_stats), GFP_KERNEL); if (tmp_eth_q_stats) - memcpy(tmp_eth_q_stats, &fp->eth_q_stats, + memcpy(tmp_eth_q_stats, &fp_stats->eth_q_stats, sizeof(struct bnx2x_eth_q_stats)); tmp_eth_q_stats_old = kzalloc(sizeof(struct bnx2x_eth_q_stats_old), GFP_KERNEL); if (tmp_eth_q_stats_old) - memcpy(tmp_eth_q_stats_old, &fp->eth_q_stats_old, + memcpy(tmp_eth_q_stats_old, &fp_stats->eth_q_stats_old, sizeof(struct bnx2x_eth_q_stats_old)); + memset(fp->tpa_info, 0, sizeof(*fp->tpa_info)); memset(fp, 0, sizeof(*fp)); if (tmp_eth_q_stats) { - memcpy(&fp->eth_q_stats, tmp_eth_q_stats, - sizeof(struct bnx2x_eth_q_stats)); + memcpy(&fp_stats->eth_q_stats, tmp_eth_q_stats, + sizeof(struct bnx2x_eth_q_stats)); kfree(tmp_eth_q_stats); } if (tmp_eth_q_stats_old) { - memcpy(&fp->eth_q_stats_old, tmp_eth_q_stats_old, + memcpy(&fp_stats->eth_q_stats_old, tmp_eth_q_stats_old, sizeof(struct bnx2x_eth_q_stats_old)); kfree(tmp_eth_q_stats_old); } @@ -1918,7 +1936,7 @@ static void bnx2x_bz_fp(struct bnx2x *bp, int index) /* Restore the NAPI object as it has been already initialized */ fp->napi = orig_napi; - + fp->tpa_info = orig_tpa_info; fp->bp = bp; fp->index = index; if (IS_ETH_FP(fp)) @@ -2918,7 +2936,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(bnx2x_tx_avail(bp, txdata) < (skb_shinfo(skb)->nr_frags + 3))) { - txdata->parent_fp->eth_q_stats.driver_xoff++; + bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++; netif_tx_stop_queue(txq); BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); return NETDEV_TX_BUSY; @@ -3200,7 +3218,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) * fp->bd_tx_cons */ smp_mb(); - txdata->parent_fp->eth_q_stats.driver_xoff++; + bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++; if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) netif_tx_wake_queue(txq); } @@ -3437,7 +3455,7 @@ static int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, cqe_ring_prod); fp->rx_pkt = fp->rx_calls = 0; - fp->eth_q_stats.rx_skb_alloc_failed += failure_cnt; + bnx2x_fp_stats(bp, fp)->eth_q_stats.rx_skb_alloc_failed += failure_cnt; return i - failure_cnt; } @@ -3642,7 +3660,10 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) void bnx2x_free_mem_bp(struct bnx2x *bp) { + kfree(bp->fp->tpa_info); kfree(bp->fp); + kfree(bp->sp_objs); + kfree(bp->fp_stats); kfree(bp->bnx2x_txq); kfree(bp->msix_table); kfree(bp->ilt); @@ -3654,6 +3675,8 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) struct msix_entry *tbl; struct bnx2x_ilt *ilt; int msix_table_size = 0; + int fp_array_size; + int i; /* * The biggest MSI-X table we might need is as a maximum number of fast @@ -3662,12 +3685,34 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) msix_table_size = bp->igu_sb_cnt + 1; /* fp array: RSS plus CNIC related L2 queues */ - fp = kcalloc(BNX2X_MAX_RSS_COUNT(bp) + NON_ETH_CONTEXT_USE, - sizeof(*fp), GFP_KERNEL); + fp_array_size = BNX2X_MAX_RSS_COUNT(bp) + NON_ETH_CONTEXT_USE; + BNX2X_DEV_INFO("fp_array_size %d", fp_array_size); + + fp = kcalloc(fp_array_size, sizeof(*fp), GFP_KERNEL); if (!fp) goto alloc_err; + for (i = 0; i < fp_array_size; i++) { + fp[i].tpa_info = + kcalloc(ETH_MAX_AGGREGATION_QUEUES_E1H_E2, + sizeof(struct bnx2x_agg_info), GFP_KERNEL); + if (!(fp[i].tpa_info)) + goto alloc_err; + } + bp->fp = fp; + /* allocate sp objs */ + bp->sp_objs = kcalloc(fp_array_size, sizeof(struct bnx2x_sp_objs), + GFP_KERNEL); + if (!bp->sp_objs) + goto alloc_err; + + /* allocate fp_stats */ + bp->fp_stats = kcalloc(fp_array_size, sizeof(struct bnx2x_fp_stats), + GFP_KERNEL); + if (!bp->fp_stats) + goto alloc_err; + /* Allocate memory for the transmission queues array */ bp->bnx2x_txq_size = BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS; #ifdef BCM_CNIC diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index de79cdf1299b..11afe5d8819b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -981,8 +981,8 @@ static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, struct bnx2x *bp = fp->bp; /* Configure classification DBs */ - bnx2x_init_mac_obj(bp, &fp->mac_obj, fp->cl_id, fp->cid, - BP_FUNC(bp), bnx2x_sp(bp, mac_rdata), + bnx2x_init_mac_obj(bp, &bnx2x_sp_obj(bp, fp).mac_obj, fp->cl_id, + fp->cid, BP_FUNC(bp), bnx2x_sp(bp, mac_rdata), bnx2x_sp_mapping(bp, mac_rdata), BNX2X_FILTER_MAC_PENDING, &bp->sp_state, obj_type, @@ -1138,8 +1138,8 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) /* No multi-CoS for FCoE L2 client */ BUG_ON(fp->max_cos != 1); - bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, &fp->cid, 1, - BP_FUNC(bp), bnx2x_sp(bp, q_rdata), + bnx2x_init_queue_obj(bp, &bnx2x_sp_obj(bp, fp).q_obj, fp->cl_id, + &fp->cid, 1, BP_FUNC(bp), bnx2x_sp(bp, q_rdata), bnx2x_sp_mapping(bp, q_rdata), q_type); DP(NETIF_MSG_IFUP, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index b46822356a1c..af84ebdeed7a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2292,7 +2292,7 @@ static int bnx2x_test_intr(struct bnx2x *bp) return -ENODEV; } - params.q_obj = &bp->fp->q_obj; + params.q_obj = &bp->sp_objs->q_obj; params.cmd = BNX2X_Q_CMD_EMPTY; __set_bit(RAMROD_COMP_WAIT, ¶ms.ramrod_flags); @@ -2516,7 +2516,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, if (is_multi(bp)) { for_each_eth_queue(bp, i) { - hw_stats = (u32 *)&bp->fp[i].eth_q_stats; + hw_stats = (u32 *)&bp->fp_stats[i].eth_q_stats; for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { if (bnx2x_q_stats_arr[j].size == 0) { /* skip this counter */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c9302d9a796c..dce705636bc6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1583,7 +1583,7 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data); int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data); enum bnx2x_queue_cmd drv_cmd = BNX2X_Q_CMD_MAX; - struct bnx2x_queue_sp_obj *q_obj = &fp->q_obj; + struct bnx2x_queue_sp_obj *q_obj = &bnx2x_sp_obj(bp, fp).q_obj; DP(BNX2X_MSG_SP, "fp %d cid %d got ramrod #%d state is %x type is %d\n", @@ -3035,9 +3035,9 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp) memcpy(ether_stat->version, DRV_MODULE_VERSION, ETH_STAT_INFO_VERSION_LEN - 1); - bp->fp[0].mac_obj.get_n_elements(bp, &bp->fp[0].mac_obj, - DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED, - ether_stat->mac_local); + bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj, + DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED, + ether_stat->mac_local); ether_stat->mtu_size = bp->dev->mtu; @@ -4632,7 +4632,7 @@ static void bnx2x_handle_classification_eqe(struct bnx2x *bp, vlan_mac_obj = &bp->iscsi_l2_mac_obj; else #endif - vlan_mac_obj = &bp->fp[cid].mac_obj; + vlan_mac_obj = &bp->sp_objs[cid].mac_obj; break; case BNX2X_FILTER_MCAST_PENDING: @@ -4730,7 +4730,7 @@ static void bnx2x_after_function_update(struct bnx2x *bp) for_each_eth_queue(bp, q) { /* Set the appropriate Queue object */ fp = &bp->fp[q]; - queue_params.q_obj = &fp->q_obj; + queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; /* send the ramrod */ rc = bnx2x_queue_state_change(bp, &queue_params); @@ -4742,7 +4742,7 @@ static void bnx2x_after_function_update(struct bnx2x *bp) #ifdef BCM_CNIC if (!NO_FCOE(bp)) { fp = &bp->fp[FCOE_IDX(bp)]; - queue_params.q_obj = &fp->q_obj; + queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; /* clear pending completion bit */ __clear_bit(RAMROD_COMP_WAIT, &queue_params.ramrod_flags); @@ -4775,10 +4775,10 @@ static struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( DP(BNX2X_MSG_SP, "retrieving fp from cid %d\n", cid); #ifdef BCM_CNIC if (cid == BNX2X_FCOE_ETH_CID(bp)) - return &bnx2x_fcoe(bp, q_obj); + return &bnx2x_fcoe_sp_obj(bp, q_obj); else #endif - return &bnx2x_fp(bp, CID_TO_FP(cid, bp), q_obj); + return &bp->sp_objs[CID_TO_FP(cid, bp)].q_obj; } static void bnx2x_eq_int(struct bnx2x *bp) @@ -5667,8 +5667,8 @@ static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx) cids[cos] = fp->txdata_ptr[cos]->cid; } - bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, cids, fp->max_cos, - BP_FUNC(bp), bnx2x_sp(bp, q_rdata), + bnx2x_init_queue_obj(bp, &bnx2x_sp_obj(bp, fp).q_obj, fp->cl_id, cids, + fp->max_cos, BP_FUNC(bp), bnx2x_sp(bp, q_rdata), bnx2x_sp_mapping(bp, q_rdata), q_type); /** @@ -7596,8 +7596,8 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set) __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); /* Eth MAC is set on RSS leading client (fp[0]) */ - return bnx2x_set_mac_one(bp, bp->dev->dev_addr, &bp->fp->mac_obj, set, - BNX2X_ETH_MAC, &ramrod_flags); + return bnx2x_set_mac_one(bp, bp->dev->dev_addr, &bp->sp_objs->mac_obj, + set, BNX2X_ETH_MAC, &ramrod_flags); } int bnx2x_setup_leading(struct bnx2x *bp) @@ -7877,7 +7877,7 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); - q_params.q_obj = &fp->q_obj; + q_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; /* We want to wait for completion in this context */ __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); @@ -7950,7 +7950,7 @@ static int bnx2x_stop_queue(struct bnx2x *bp, int index) DP(NETIF_MSG_IFDOWN, "stopping queue %d cid %d\n", index, fp->cid); - q_params.q_obj = &fp->q_obj; + q_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; /* We want to wait for completion in this context */ __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); @@ -8339,12 +8339,13 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) usleep_range(1000, 1000); /* Clean all ETH MACs */ - rc = bnx2x_del_all_macs(bp, &bp->fp[0].mac_obj, BNX2X_ETH_MAC, false); + rc = bnx2x_del_all_macs(bp, &bp->sp_objs[0].mac_obj, BNX2X_ETH_MAC, + false); if (rc < 0) BNX2X_ERR("Failed to delete all ETH macs: %d\n", rc); /* Clean up UC list */ - rc = bnx2x_del_all_macs(bp, &bp->fp[0].mac_obj, BNX2X_UC_LIST_MAC, + rc = bnx2x_del_all_macs(bp, &bp->sp_objs[0].mac_obj, BNX2X_UC_LIST_MAC, true); if (rc < 0) BNX2X_ERR("Failed to schedule DEL commands for UC MACs list: %d\n", @@ -11049,7 +11050,7 @@ static int bnx2x_set_uc_list(struct bnx2x *bp) int rc; struct net_device *dev = bp->dev; struct netdev_hw_addr *ha; - struct bnx2x_vlan_mac_obj *mac_obj = &bp->fp->mac_obj; + struct bnx2x_vlan_mac_obj *mac_obj = &bp->sp_objs->mac_obj; unsigned long ramrod_flags = 0; /* First schedule a cleanup up of old configuration */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 776b52163b11..514a528f6ddf 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -859,17 +859,22 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) struct tstorm_per_queue_stats *tclient = &bp->fw_stats_data->queue_stats[i]. tstorm_queue_statistics; - struct tstorm_per_queue_stats *old_tclient = &fp->old_tclient; + struct tstorm_per_queue_stats *old_tclient = + &bnx2x_fp_stats(bp, fp)->old_tclient; struct ustorm_per_queue_stats *uclient = &bp->fw_stats_data->queue_stats[i]. ustorm_queue_statistics; - struct ustorm_per_queue_stats *old_uclient = &fp->old_uclient; + struct ustorm_per_queue_stats *old_uclient = + &bnx2x_fp_stats(bp, fp)->old_uclient; struct xstorm_per_queue_stats *xclient = &bp->fw_stats_data->queue_stats[i]. xstorm_queue_statistics; - struct xstorm_per_queue_stats *old_xclient = &fp->old_xclient; - struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; - struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old; + struct xstorm_per_queue_stats *old_xclient = + &bnx2x_fp_stats(bp, fp)->old_xclient; + struct bnx2x_eth_q_stats *qstats = + &bnx2x_fp_stats(bp, fp)->eth_q_stats; + struct bnx2x_eth_q_stats_old *qstats_old = + &bnx2x_fp_stats(bp, fp)->eth_q_stats_old; u32 diff; @@ -1052,8 +1057,11 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); tmp = estats->mac_discard; - for_each_rx_queue(bp, i) - tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); + for_each_rx_queue(bp, i) { + struct tstorm_per_queue_stats *old_tclient = + &bp->fp_stats[i].old_tclient; + tmp += le32_to_cpu(old_tclient->checksum_discard); + } nstats->rx_dropped = tmp + bp->net_stats_old.rx_dropped; nstats->tx_dropped = 0; @@ -1103,9 +1111,9 @@ static void bnx2x_drv_stats_update(struct bnx2x *bp) int i; for_each_queue(bp, i) { - struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats; + struct bnx2x_eth_q_stats *qstats = &bp->fp_stats[i].eth_q_stats; struct bnx2x_eth_q_stats_old *qstats_old = - &bp->fp[i].eth_q_stats_old; + &bp->fp_stats[i].eth_q_stats_old; UPDATE_ESTAT_QSTAT(driver_xoff); UPDATE_ESTAT_QSTAT(rx_err_discard_pkt); @@ -1483,15 +1491,19 @@ void bnx2x_stats_init(struct bnx2x *bp) /* function stats */ for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - memset(&fp->old_tclient, 0, sizeof(fp->old_tclient)); - memset(&fp->old_uclient, 0, sizeof(fp->old_uclient)); - memset(&fp->old_xclient, 0, sizeof(fp->old_xclient)); + struct bnx2x_fp_stats *fp_stats = &bp->fp_stats[i]; + + memset(&fp_stats->old_tclient, 0, + sizeof(fp_stats->old_tclient)); + memset(&fp_stats->old_uclient, 0, + sizeof(fp_stats->old_uclient)); + memset(&fp_stats->old_xclient, 0, + sizeof(fp_stats->old_xclient)); if (bp->stats_init) { - memset(&fp->eth_q_stats, 0, sizeof(fp->eth_q_stats)); - memset(&fp->eth_q_stats_old, 0, - sizeof(fp->eth_q_stats_old)); + memset(&fp_stats->eth_q_stats, 0, + sizeof(fp_stats->eth_q_stats)); + memset(&fp_stats->eth_q_stats_old, 0, + sizeof(fp_stats->eth_q_stats_old)); } } @@ -1533,8 +1545,10 @@ void bnx2x_save_statistics(struct bnx2x *bp) /* save queue statistics */ for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; - struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old; + struct bnx2x_eth_q_stats *qstats = + &bnx2x_fp_stats(bp, fp)->eth_q_stats; + struct bnx2x_eth_q_stats_old *qstats_old = + &bnx2x_fp_stats(bp, fp)->eth_q_stats_old; UPDATE_QSTAT_OLD(total_unicast_bytes_received_hi); UPDATE_QSTAT_OLD(total_unicast_bytes_received_lo); @@ -1590,8 +1604,7 @@ void bnx2x_afex_collect_stats(struct bnx2x *bp, void *void_afex_stats, memset(afex_stats, 0, sizeof(struct afex_stats)); for_each_eth_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; + struct bnx2x_eth_q_stats *qstats = &bp->fp_stats[i].eth_q_stats; ADD_64(afex_stats->rx_unicast_bytes_hi, qstats->total_unicast_bytes_received_hi, -- GitLab From 60aa0509056616afe9d66cf0fcd290589395032c Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:29 +0000 Subject: [PATCH 2054/6849] bnx2x: Allow up to 63 RSS queues This patch removed the limitation in the code for 16 RSS queues. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index dce705636bc6..1ebcaa1183df 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11813,13 +11813,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, max_non_def_sbs = bnx2x_get_num_non_def_sbs(pdev); - /* !!! FIXME !!! - * Do not allow the maximum SB count to grow above 16 - * since Special CIDs starts from 16*BNX2X_MULTI_TX_COS=48. - * We will use the FP_SB_MAX_E1x macro for this matter. - */ - max_non_def_sbs = min_t(int, FP_SB_MAX_E1x, max_non_def_sbs); - WARN_ON(!max_non_def_sbs); /* Maximum number of RSS queues: one IGU SB goes to CNIC */ @@ -11841,9 +11834,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, bp = netdev_priv(dev); - BNX2X_DEV_INFO("Allocated netdev with %d tx and %d rx queues\n", - tx_count, rx_count); - bp->igu_sb_cnt = max_non_def_sbs; bp->msg_enable = debug; pci_set_drvdata(pdev, dev); @@ -11856,6 +11846,9 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, BNX2X_DEV_INFO("max_non_def_sbs %d\n", max_non_def_sbs); + BNX2X_DEV_INFO("Allocated netdev with %d tx and %d rx queues\n", + tx_count, rx_count); + rc = bnx2x_init_bp(bp); if (rc) goto init_one_exit; -- GitLab From 0e8d2ec5c6ccf74dbe40216bb62d82c2f73fe836 Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:30 +0000 Subject: [PATCH 2055/6849] bnx2x: Add support for ethtool -L Add support for ethtool -L/-l for setting and getting the number of RSS queues. The 'combined' field is used as we don't support separate IRQ for Rx and Tx. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 4 + .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 11 ++- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 80 +++++++++++++++++++ .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 15 ++-- 5 files changed, 100 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 25d46c10dbd4..fcc3b26c1c60 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1393,6 +1393,7 @@ struct bnx2x { #define BNX2X_MAX_COS 3 #define BNX2X_MAX_TX_COS 2 int num_queues; + int num_napi_queues; int disable_tpa; u32 rx_mode; @@ -1680,6 +1681,9 @@ struct bnx2x_func_init_params { continue; \ else +#define for_each_napi_rx_queue(bp, var) \ + for ((var) = 0; (var) < bp->num_napi_queues; (var)++) + /* Skip OOO FP */ #define for_each_tx_queue(bp, var) \ for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 413b665646b7..829befbc20a5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1360,7 +1360,7 @@ void bnx2x_free_irq(struct bnx2x *bp) free_irq(bp->dev->irq, bp->dev); } -int __devinit bnx2x_enable_msix(struct bnx2x *bp) +int bnx2x_enable_msix(struct bnx2x *bp) { int msix_vec = 0, i, rc, req_cnt; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 11afe5d8819b..12dbbc4ff9bc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -29,6 +29,7 @@ extern int load_count[2][3]; /* per-path: 0-common, 1-port0, 2-port1 */ extern int num_queues; +extern int int_mode; /************************ Macros ********************************/ #define BNX2X_PCI_FREE(x, y, size) \ @@ -495,7 +496,7 @@ void bnx2x_netif_start(struct bnx2x *bp); * fills msix_table, requests vectors, updates num_queues * according to number of available vectors. */ -int __devinit bnx2x_enable_msix(struct bnx2x *bp); +int bnx2x_enable_msix(struct bnx2x *bp); /** * bnx2x_enable_msi - request msi mode from OS, updated internals accordingly @@ -788,8 +789,10 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) { int i; + bp->num_napi_queues = bp->num_queues; + /* Add NAPI objects */ - for_each_rx_queue(bp, i) + for_each_napi_rx_queue(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), bnx2x_poll, BNX2X_NAPI_WEIGHT); } @@ -798,10 +801,12 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) { int i; - for_each_rx_queue(bp, i) + for_each_napi_rx_queue(bp, i) netif_napi_del(&bnx2x_fp(bp, i, napi)); } +void bnx2x_set_int_mode(struct bnx2x *bp); + static inline void bnx2x_disable_msi(struct bnx2x *bp) { if (bp->flags & USING_MSIX_FLAG) { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index af84ebdeed7a..70c0881ce5a0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2796,6 +2796,84 @@ static int bnx2x_set_rxfh_indir(struct net_device *dev, const u32 *indir) return bnx2x_config_rss_eth(bp, false); } +/** + * bnx2x_get_channels - gets the number of RSS queues. + * + * @dev: net device + * @channels: returns the number of max / current queues + */ +static void bnx2x_get_channels(struct net_device *dev, + struct ethtool_channels *channels) +{ + struct bnx2x *bp = netdev_priv(dev); + + channels->max_combined = BNX2X_MAX_RSS_COUNT(bp); + channels->combined_count = BNX2X_NUM_ETH_QUEUES(bp); +} + +/** + * bnx2x_change_num_queues - change the number of RSS queues. + * + * @bp: bnx2x private structure + * + * Re-configure interrupt mode to get the new number of MSI-X + * vectors and re-add NAPI objects. + */ +static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) +{ + bnx2x_del_all_napi(bp); + bnx2x_disable_msi(bp); + BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; + bnx2x_set_int_mode(bp); + bnx2x_add_all_napi(bp); +} + +/** + * bnx2x_set_channels - sets the number of RSS queues. + * + * @dev: net device + * @channels: includes the number of queues requested + */ +static int bnx2x_set_channels(struct net_device *dev, + struct ethtool_channels *channels) +{ + struct bnx2x *bp = netdev_priv(dev); + + + DP(BNX2X_MSG_ETHTOOL, + "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n", + channels->rx_count, channels->tx_count, channels->other_count, + channels->combined_count); + + /* We don't support separate rx / tx channels. + * We don't allow setting 'other' channels. + */ + if (channels->rx_count || channels->tx_count || channels->other_count + || (channels->combined_count == 0) || + (channels->combined_count > BNX2X_MAX_RSS_COUNT(bp))) { + DP(BNX2X_MSG_ETHTOOL, "command parameters not supported\n"); + return -EINVAL; + } + + /* Check if there was a change in the active parameters */ + if (channels->combined_count == BNX2X_NUM_ETH_QUEUES(bp)) { + DP(BNX2X_MSG_ETHTOOL, "No change in active parameters\n"); + return 0; + } + + /* Set the requested number of queues in bp context. + * Note that the actual number of queues created during load may be + * less than requested if memory is low. + */ + if (unlikely(!netif_running(dev))) { + bnx2x_change_num_queues(bp, channels->combined_count); + return 0; + } + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + bnx2x_change_num_queues(bp, channels->combined_count); + return bnx2x_nic_load(bp, LOAD_NORMAL); +} + static const struct ethtool_ops bnx2x_ethtool_ops = { .get_settings = bnx2x_get_settings, .set_settings = bnx2x_set_settings, @@ -2827,6 +2905,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, .get_rxfh_indir = bnx2x_get_rxfh_indir, .set_rxfh_indir = bnx2x_set_rxfh_indir, + .get_channels = bnx2x_get_channels, + .set_channels = bnx2x_set_channels, .get_eee = bnx2x_get_eee, .set_eee = bnx2x_set_eee, }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1ebcaa1183df..08c8d7d5e893 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -104,7 +104,7 @@ MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); #define INT_MODE_INTx 1 #define INT_MODE_MSI 2 -static int int_mode; +int int_mode; module_param(int_mode, int, 0); MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " "(1 INT#x; 2 MSI)"); @@ -7612,7 +7612,7 @@ int bnx2x_setup_leading(struct bnx2x *bp) * * In case of MSI-X it will also try to enable MSI-X. */ -static void __devinit bnx2x_set_int_mode(struct bnx2x *bp) +void bnx2x_set_int_mode(struct bnx2x *bp) { switch (int_mode) { case INT_MODE_MSI: @@ -7623,11 +7623,6 @@ static void __devinit bnx2x_set_int_mode(struct bnx2x *bp) BNX2X_DEV_INFO("set number of queues to 1\n"); break; default: - /* Set number of queues for MSI-X mode */ - bnx2x_set_num_queues(bp); - - BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues); - /* if we can't use MSI-X we only need one fp, * so try to enable MSI-X with the requested number of fp's * and fallback to MSI or legacy INTx with one fp @@ -11883,8 +11878,12 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, #endif + + /* Set bp->num_queues for MSI-X mode*/ + bnx2x_set_num_queues(bp); + /* Configure interrupt mode: try to enable MSI-X/MSI if - * needed, set bp->num_queues appropriately. + * needed. */ bnx2x_set_int_mode(bp); -- GitLab From 9876879fce3081cd9f3f2b9e995954d423bcd863 Mon Sep 17 00:00:00 2001 From: Barak Witkowski Date: Tue, 19 Jun 2012 07:48:31 +0000 Subject: [PATCH 2056/6849] bnx2x: Support DCBX for all functions In multi-function device, allow configuring dcbx admin params from all drivers on a single physical port. Signed-off-by: Barak Witkowski Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 + .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 6 ++-- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | 30 +++++++++++++------ .../net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 1 + .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 ++ .../net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 1 + 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index fcc3b26c1c60..fa061cf60fee 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1318,6 +1318,7 @@ struct bnx2x { #define NO_FCOE_FLAG (1 << 15) #define BC_SUPPORTS_PFC_STATS (1 << 17) #define USING_SINGLE_MSIX_FLAG (1 << 20) +#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21) #define NO_ISCSI(bp) ((bp)->flags & NO_ISCSI_FLAG) #define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 829befbc20a5..00951b3aa62b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2274,8 +2274,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) return -EBUSY; } - if (bp->state != BNX2X_STATE_DIAG) - bnx2x_dcbx_init(bp); + /* If PMF - send ADMIN DCBX msg to MFW to initiate DCBX FSM */ + if (bp->port.pmf && (bp->state != BNX2X_STATE_DIAG)) + bnx2x_dcbx_init(bp, false); + return 0; #ifndef BNX2X_STOP_ON_ERROR diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 12dbbc4ff9bc..daa894bd772a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -418,7 +418,7 @@ void bnx2x_ilt_set_info(struct bnx2x *bp); * * @bp: driver handle */ -void bnx2x_dcbx_init(struct bnx2x *bp); +void bnx2x_dcbx_init(struct bnx2x *bp, bool update_shmem); /** * bnx2x_set_power_state - set power state to the requested value. diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 4f9244bd7530..8a73374e52a7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c @@ -972,23 +972,26 @@ void bnx2x_dcbx_init_params(struct bnx2x *bp) bp->dcbx_config_params.admin_default_priority = 0; } -void bnx2x_dcbx_init(struct bnx2x *bp) +void bnx2x_dcbx_init(struct bnx2x *bp, bool update_shmem) { u32 dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; + /* only PMF can send ADMIN msg to MFW in old MFW versions */ + if ((!bp->port.pmf) && (!(bp->flags & BC_SUPPORTS_DCBX_MSG_NON_PMF))) + return; + if (bp->dcbx_enabled <= 0) return; /* validate: * chip of good for dcbx version, * dcb is wanted - * the function is pmf * shmem2 contains DCBX support fields */ DP(BNX2X_MSG_DCB, "dcb_state %d bp->port.pmf %d\n", bp->dcb_state, bp->port.pmf); - if (bp->dcb_state == BNX2X_DCB_STATE_ON && bp->port.pmf && + if (bp->dcb_state == BNX2X_DCB_STATE_ON && SHMEM2_HAS(bp, dcbx_lldp_params_offset)) { dcbx_lldp_params_offset = SHMEM2_RD(bp, dcbx_lldp_params_offset); @@ -999,12 +1002,23 @@ void bnx2x_dcbx_init(struct bnx2x *bp) bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0); if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { - bnx2x_dcbx_admin_mib_updated_params(bp, - dcbx_lldp_params_offset); + /* need HW lock to avoid scenario of two drivers + * writing in parallel to shmem + */ + bnx2x_acquire_hw_lock(bp, + HW_LOCK_RESOURCE_DCBX_ADMIN_MIB); + if (update_shmem) + bnx2x_dcbx_admin_mib_updated_params(bp, + dcbx_lldp_params_offset); /* Let HW start negotiation */ bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 0); + /* release HW lock only after MFW acks that it finished + * reading values from shmem + */ + bnx2x_release_hw_lock(bp, + HW_LOCK_RESOURCE_DCBX_ADMIN_MIB); } } } @@ -2063,10 +2077,8 @@ static u8 bnx2x_dcbnl_set_all(struct net_device *netdev) "Handling parity error recovery. Try again later\n"); return 1; } - if (netif_running(bp->dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); - } + if (netif_running(bp->dev)) + bnx2x_dcbx_init(bp, true); DP(BNX2X_MSG_DCB, "set_dcbx_params done (%d)\n", rc); if (rc) return 1; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index c61aa37298a3..6b776309e0a1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -1253,6 +1253,7 @@ struct drv_func_mb { #define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 #define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 + #define REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF 0x00070401 #define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 08c8d7d5e893..8ddc78e0d945 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9732,6 +9732,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ? BC_SUPPORTS_PFC_STATS : 0; + bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ? + BC_SUPPORTS_DCBX_MSG_NON_PMF : 0; boot_mode = SHMEM_RD(bp, dev_info.port_feature_config[BP_PORT(bp)].mba_config) & PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index bfef98f666c9..a78e35683b03 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -5913,6 +5913,7 @@ #define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 #define MISC_REGISTERS_SPIO_SET_POS 8 #define HW_LOCK_MAX_RESOURCE_VALUE 31 +#define HW_LOCK_RESOURCE_DCBX_ADMIN_MIB 13 #define HW_LOCK_RESOURCE_DRV_FLAGS 10 #define HW_LOCK_RESOURCE_GPIO 1 #define HW_LOCK_RESOURCE_MDIO 0 -- GitLab From 364f5b3a151942ad24521155355cc7d1d252fd55 Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 19 Jun 2012 07:48:32 +0000 Subject: [PATCH 2057/6849] bnx2x: Change date and version to 1.72.51-0 This change updates the date and version of the bnx2x driver. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index fa061cf60fee..7211cb07426e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -23,8 +23,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.72.50-0" -#define DRV_MODULE_RELDATE "2012/04/23" +#define DRV_MODULE_VERSION "1.72.51-0" +#define DRV_MODULE_RELDATE "2012/06/18" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_DCB) -- GitLab From 2c995ff892313009e336ecc8ec3411022f5b1c39 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Tue, 19 Jun 2012 09:26:39 +0000 Subject: [PATCH 2058/6849] batman-adv: fix skb->data assignment skb_linearize(skb) possibly rearranges the skb internal data and then changes the skb->data pointer value. For this reason any other pointer in the code that was assigned skb->data before invoking skb_linearise(skb) must be re-assigned. In the current tt_query message handling code this is not done and therefore, in case of skb linearization, the pointer used to handle the packet header ends up in pointing to free'd memory. This bug was introduced by a73105b8d4c765d9ebfb664d0a66802127d8e4c7 (batman-adv: improved client announcement mechanism) Signed-off-by: Antonio Quartulli Cc: Signed-off-by: David S. Miller --- net/batman-adv/routing.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 840e2c64a301..015471d801b4 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -617,6 +617,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) * changes */ if (skb_linearize(skb) < 0) goto out; + /* skb_linearize() possibly changed skb->data */ + tt_query = (struct tt_query_packet *)skb->data; tt_len = tt_query->tt_data * sizeof(struct tt_change); -- GitLab From 0402788a6cda4e204a805e83eaaff64fef9e4418 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:03 +0000 Subject: [PATCH 2059/6849] team: make team_mode struct const Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 55 ++++++++++++++++------- drivers/net/team/team_mode_activebackup.c | 2 +- drivers/net/team/team_mode_loadbalance.c | 2 +- drivers/net/team/team_mode_roundrobin.c | 2 +- include/linux/if_team.h | 5 +-- 5 files changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index c61ae35a53ce..bdf87a971382 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -371,13 +371,18 @@ static int team_option_set(struct team *team, static LIST_HEAD(mode_list); static DEFINE_SPINLOCK(mode_list_lock); -static struct team_mode *__find_mode(const char *kind) +struct team_mode_item { + struct list_head list; + const struct team_mode *mode; +}; + +static struct team_mode_item *__find_mode(const char *kind) { - struct team_mode *mode; + struct team_mode_item *mitem; - list_for_each_entry(mode, &mode_list, list) { - if (strcmp(mode->kind, kind) == 0) - return mode; + list_for_each_entry(mitem, &mode_list, list) { + if (strcmp(mitem->mode->kind, kind) == 0) + return mitem; } return NULL; } @@ -392,49 +397,65 @@ static bool is_good_mode_name(const char *name) return true; } -int team_mode_register(struct team_mode *mode) +int team_mode_register(const struct team_mode *mode) { int err = 0; + struct team_mode_item *mitem; if (!is_good_mode_name(mode->kind) || mode->priv_size > TEAM_MODE_PRIV_SIZE) return -EINVAL; + + mitem = kmalloc(sizeof(*mitem), GFP_KERNEL); + if (!mitem) + return -ENOMEM; + spin_lock(&mode_list_lock); if (__find_mode(mode->kind)) { err = -EEXIST; + kfree(mitem); goto unlock; } - list_add_tail(&mode->list, &mode_list); + mitem->mode = mode; + list_add_tail(&mitem->list, &mode_list); unlock: spin_unlock(&mode_list_lock); return err; } EXPORT_SYMBOL(team_mode_register); -int team_mode_unregister(struct team_mode *mode) +void team_mode_unregister(const struct team_mode *mode) { + struct team_mode_item *mitem; + spin_lock(&mode_list_lock); - list_del_init(&mode->list); + mitem = __find_mode(mode->kind); + if (mitem) { + list_del_init(&mitem->list); + kfree(mitem); + } spin_unlock(&mode_list_lock); - return 0; } EXPORT_SYMBOL(team_mode_unregister); -static struct team_mode *team_mode_get(const char *kind) +static const struct team_mode *team_mode_get(const char *kind) { - struct team_mode *mode; + struct team_mode_item *mitem; + const struct team_mode *mode = NULL; spin_lock(&mode_list_lock); - mode = __find_mode(kind); - if (!mode) { + mitem = __find_mode(kind); + if (!mitem) { spin_unlock(&mode_list_lock); request_module("team-mode-%s", kind); spin_lock(&mode_list_lock); - mode = __find_mode(kind); + mitem = __find_mode(kind); } - if (mode) + if (mitem) { + mode = mitem->mode; if (!try_module_get(mode->owner)) mode = NULL; + } spin_unlock(&mode_list_lock); return mode; @@ -523,7 +544,7 @@ static int __team_change_mode(struct team *team, static int team_change_mode(struct team *team, const char *kind) { - struct team_mode *new_mode; + const struct team_mode *new_mode; struct net_device *dev = team->dev; int err; diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c index fd6bd03aaa89..acd925f070b5 100644 --- a/drivers/net/team/team_mode_activebackup.c +++ b/drivers/net/team/team_mode_activebackup.c @@ -108,7 +108,7 @@ static const struct team_mode_ops ab_mode_ops = { .port_leave = ab_port_leave, }; -static struct team_mode ab_mode = { +static const struct team_mode ab_mode = { .kind = "activebackup", .owner = THIS_MODULE, .priv_size = sizeof(struct ab_priv), diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index 86e8183c8e3d..6452428a1d6c 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -148,7 +148,7 @@ static const struct team_mode_ops lb_mode_ops = { .transmit = lb_transmit, }; -static struct team_mode lb_mode = { +static const struct team_mode lb_mode = { .kind = "loadbalance", .owner = THIS_MODULE, .priv_size = sizeof(struct lb_priv), diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c index 6abfbdc96be5..daafca2b2da4 100644 --- a/drivers/net/team/team_mode_roundrobin.c +++ b/drivers/net/team/team_mode_roundrobin.c @@ -81,7 +81,7 @@ static const struct team_mode_ops rr_mode_ops = { .port_change_mac = rr_port_change_mac, }; -static struct team_mode rr_mode = { +static const struct team_mode rr_mode = { .kind = "roundrobin", .owner = THIS_MODULE, .priv_size = sizeof(struct rr_priv), diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 8185f57a9c7f..d45fcd5a188d 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -105,7 +105,6 @@ struct team_option { }; struct team_mode { - struct list_head list; const char *kind; struct module *owner; size_t priv_size; @@ -178,8 +177,8 @@ extern int team_options_register(struct team *team, extern void team_options_unregister(struct team *team, const struct team_option *option, size_t option_count); -extern int team_mode_register(struct team_mode *mode); -extern int team_mode_unregister(struct team_mode *mode); +extern int team_mode_register(const struct team_mode *mode); +extern void team_mode_unregister(const struct team_mode *mode); #endif /* __KERNEL__ */ -- GitLab From d299cd51166c156c77250f4cdd6363b74fd2f77e Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:04 +0000 Subject: [PATCH 2060/6849] team: for nomode use dummy struct team_mode That leaves team->mode and all its values valid so no checks would be needed (for example in team_mode_option_get()). Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index bdf87a971382..343f4ffaf8f0 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -479,6 +479,20 @@ rx_handler_result_t team_dummy_receive(struct team *team, return RX_HANDLER_ANOTHER; } +static const struct team_mode __team_no_mode = { + .kind = "*NOMODE*", +}; + +static bool team_is_mode_set(struct team *team) +{ + return team->mode != &__team_no_mode; +} + +static void team_set_no_mode(struct team *team) +{ + team->mode = &__team_no_mode; +} + static void team_adjust_ops(struct team *team) { /* @@ -487,13 +501,13 @@ static void team_adjust_ops(struct team *team) */ if (list_empty(&team->port_list) || - !team->mode || !team->mode->ops->transmit) + !team_is_mode_set(team) || !team->mode->ops->transmit) team->ops.transmit = team_dummy_transmit; else team->ops.transmit = team->mode->ops->transmit; if (list_empty(&team->port_list) || - !team->mode || !team->mode->ops->receive) + !team_is_mode_set(team) || !team->mode->ops->receive) team->ops.receive = team_dummy_receive; else team->ops.receive = team->mode->ops->receive; @@ -508,7 +522,7 @@ static int __team_change_mode(struct team *team, const struct team_mode *new_mode) { /* Check if mode was previously set and do cleanup if so */ - if (team->mode) { + if (team_is_mode_set(team)) { void (*exit_op)(struct team *team) = team->ops.exit; /* Clear ops area so no callback is called any longer */ @@ -518,7 +532,7 @@ static int __team_change_mode(struct team *team, if (exit_op) exit_op(team); team_mode_put(team->mode); - team->mode = NULL; + team_set_no_mode(team); /* zero private data area */ memset(&team->mode_priv, 0, sizeof(struct team) - offsetof(struct team, mode_priv)); @@ -553,7 +567,7 @@ static int team_change_mode(struct team *team, const char *kind) return -EBUSY; } - if (team->mode && strcmp(team->mode->kind, kind) == 0) { + if (team_is_mode_set(team) && strcmp(team->mode->kind, kind) == 0) { netdev_err(dev, "Unable to change to the same mode the team is in\n"); return -EINVAL; } @@ -912,11 +926,9 @@ static int team_port_del(struct team *team, struct net_device *port_dev) * Net device ops *****************/ -static const char team_no_mode_kind[] = "*NOMODE*"; - static int team_mode_option_get(struct team *team, struct team_gsetter_ctx *ctx) { - ctx->data.str_val = team->mode ? team->mode->kind : team_no_mode_kind; + ctx->data.str_val = team->mode->kind; return 0; } @@ -1014,6 +1026,7 @@ static int team_init(struct net_device *dev) team->dev = dev; mutex_init(&team->lock); + team_set_no_mode(team); team->pcpu_stats = alloc_percpu(struct team_pcpu_stats); if (!team->pcpu_stats) -- GitLab From 5149ee58385bdfef260fb07a89a8ff0913be6b25 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:05 +0000 Subject: [PATCH 2061/6849] team: add mode priv to port Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 3 ++- include/linux/if_team.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 343f4ffaf8f0..dea2d8afa2f4 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -793,7 +793,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev) return -EBUSY; } - port = kzalloc(sizeof(struct team_port), GFP_KERNEL); + port = kzalloc(sizeof(struct team_port) + team->mode->port_priv_size, + GFP_KERNEL); if (!port) return -ENOMEM; diff --git a/include/linux/if_team.h b/include/linux/if_team.h index d45fcd5a188d..54af95f5d58b 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -61,6 +61,7 @@ struct team_port { } orig; struct rcu_head rcu; + long mode_priv[0]; }; struct team_mode_ops { @@ -108,6 +109,7 @@ struct team_mode { const char *kind; struct module *owner; size_t priv_size; + size_t port_priv_size; const struct team_mode_ops *ops; }; -- GitLab From 596e2024c42159fedf71b3d17fba78eed9b5bf10 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:06 +0000 Subject: [PATCH 2062/6849] team: lb: push hash counting into separate function Also squash hash into one byte Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_loadbalance.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index 6452428a1d6c..a475b1304f9a 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -27,18 +27,27 @@ static struct lb_priv *lb_priv(struct team *team) return (struct lb_priv *) &team->mode_priv; } -static bool lb_transmit(struct team *team, struct sk_buff *skb) +static unsigned char lb_get_skb_hash(struct lb_priv *lb_priv, + struct sk_buff *skb) { struct sk_filter *fp; + uint32_t lhash; + unsigned char *c; + + fp = rcu_dereference(lb_priv->fp); + if (unlikely(!fp)) + return 0; + lhash = SK_RUN_FILTER(fp, skb); + c = (char *) &lhash; + return c[0] ^ c[1] ^ c[2] ^ c[3]; +} + +static bool lb_transmit(struct team *team, struct sk_buff *skb) +{ struct team_port *port; - unsigned int hash; int port_index; - fp = rcu_dereference(lb_priv(team)->fp); - if (unlikely(!fp)) - goto drop; - hash = SK_RUN_FILTER(fp, skb); - port_index = hash % team->en_port_count; + port_index = lb_get_skb_hash(lb_priv(team), skb) % team->en_port_count; port = team_get_port_by_index_rcu(team, port_index); if (unlikely(!port)) goto drop; -- GitLab From f82b959d26557fe4ce283d3b27050d4b8268ef1e Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:07 +0000 Subject: [PATCH 2063/6849] team: allow read/write-only options Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index dea2d8afa2f4..f50b8ca8dc94 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -346,6 +346,8 @@ static int team_option_get(struct team *team, struct team_option_inst *opt_inst, struct team_gsetter_ctx *ctx) { + if (!opt_inst->option->getter) + return -EOPNOTSUPP; return opt_inst->option->getter(team, ctx); } @@ -355,6 +357,8 @@ static int team_option_set(struct team *team, { int err; + if (!opt_inst->option->setter) + return -EOPNOTSUPP; err = opt_inst->option->setter(team, ctx); if (err) return err; -- GitLab From b13033262d2496e271444d5a09226a2be5ceb989 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:08 +0000 Subject: [PATCH 2064/6849] team: introduce array options Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 75 ++++++++++++++++++++++++++++------------- include/linux/if_team.h | 3 ++ 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index f50b8ca8dc94..32cb290fb800 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -90,6 +90,7 @@ struct team_option_inst { /* One for each option instance */ struct list_head list; struct team_option *option; struct team_port *port; /* != NULL if per-port */ + u32 array_index; bool changed; bool removed; }; @@ -106,22 +107,6 @@ static struct team_option *__team_find_option(struct team *team, return NULL; } -static int __team_option_inst_add(struct team *team, struct team_option *option, - struct team_port *port) -{ - struct team_option_inst *opt_inst; - - opt_inst = kmalloc(sizeof(*opt_inst), GFP_KERNEL); - if (!opt_inst) - return -ENOMEM; - opt_inst->option = option; - opt_inst->port = port; - opt_inst->changed = true; - opt_inst->removed = false; - list_add_tail(&opt_inst->list, &team->option_inst_list); - return 0; -} - static void __team_option_inst_del(struct team_option_inst *opt_inst) { list_del(&opt_inst->list); @@ -139,14 +124,42 @@ static void __team_option_inst_del_option(struct team *team, } } +static int __team_option_inst_add(struct team *team, struct team_option *option, + struct team_port *port) +{ + struct team_option_inst *opt_inst; + unsigned int array_size; + unsigned int i; + + array_size = option->array_size; + if (!array_size) + array_size = 1; /* No array but still need one instance */ + + for (i = 0; i < array_size; i++) { + opt_inst = kmalloc(sizeof(*opt_inst), GFP_KERNEL); + if (!opt_inst) + return -ENOMEM; + opt_inst->option = option; + opt_inst->port = port; + opt_inst->array_index = i; + opt_inst->changed = true; + opt_inst->removed = false; + list_add_tail(&opt_inst->list, &team->option_inst_list); + } + return 0; +} + static int __team_option_inst_add_option(struct team *team, struct team_option *option) { struct team_port *port; int err; - if (!option->per_port) - return __team_option_inst_add(team, option, 0); + if (!option->per_port) { + err = __team_option_inst_add(team, option, 0); + if (err) + goto inst_del_option; + } list_for_each_entry(port, &team->port_list, list) { err = __team_option_inst_add(team, option, port); @@ -1567,6 +1580,11 @@ static int team_nl_fill_options_get(struct sk_buff *skb, opt_inst->port->dev->ifindex)) goto nla_put_failure; ctx.port = opt_inst->port; + if (opt_inst->option->array_size && + nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, + opt_inst->array_index)) + goto nla_put_failure; + ctx.array_index = opt_inst->array_index; switch (option->type) { case TEAM_OPTION_TYPE_U32: if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) @@ -1668,10 +1686,12 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) nla_for_each_nested(nl_option, info->attrs[TEAM_ATTR_LIST_OPTION], i) { struct nlattr *opt_attrs[TEAM_ATTR_OPTION_MAX + 1]; - struct nlattr *attr_port_ifindex; + struct nlattr *attr; struct nlattr *attr_data; enum team_option_type opt_type; int opt_port_ifindex = 0; /* != 0 for per-port options */ + u32 opt_array_index = 0; + bool opt_is_array = false; struct team_option_inst *opt_inst; char *opt_name; bool opt_found = false; @@ -1713,9 +1733,15 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) } opt_name = nla_data(opt_attrs[TEAM_ATTR_OPTION_NAME]); - attr_port_ifindex = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX]; - if (attr_port_ifindex) - opt_port_ifindex = nla_get_u32(attr_port_ifindex); + attr = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX]; + if (attr) + opt_port_ifindex = nla_get_u32(attr); + + attr = opt_attrs[TEAM_ATTR_OPTION_ARRAY_INDEX]; + if (attr) { + opt_is_array = true; + opt_array_index = nla_get_u32(attr); + } list_for_each_entry(opt_inst, &team->option_inst_list, list) { struct team_option *option = opt_inst->option; @@ -1726,10 +1752,13 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) opt_inst->port->dev->ifindex : 0; if (option->type != opt_type || strcmp(option->name, opt_name) || - tmp_ifindex != opt_port_ifindex) + tmp_ifindex != opt_port_ifindex || + (option->array_size && !opt_is_array) || + opt_inst->array_index != opt_array_index) continue; opt_found = true; ctx.port = opt_inst->port; + ctx.array_index = opt_inst->array_index; switch (opt_type) { case TEAM_OPTION_TYPE_U32: ctx.data.u32_val = nla_get_u32(attr_data); diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 54af95f5d58b..b1719e239a0b 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -93,6 +93,7 @@ struct team_gsetter_ctx { } bin_val; bool bool_val; } data; + u32 array_index; struct team_port *port; }; @@ -100,6 +101,7 @@ struct team_option { struct list_head list; const char *name; bool per_port; + unsigned int array_size; /* != 0 means the option is array */ enum team_option_type type; int (*getter)(struct team *team, struct team_gsetter_ctx *ctx); int (*setter)(struct team *team, struct team_gsetter_ctx *ctx); @@ -242,6 +244,7 @@ enum { TEAM_ATTR_OPTION_DATA, /* dynamic */ TEAM_ATTR_OPTION_REMOVED, /* flag */ TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */ + TEAM_ATTR_OPTION_ARRAY_INDEX, /* u32 */ /* for array options */ __TEAM_ATTR_OPTION_MAX, TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1, -- GitLab From 0d572e45f7f8ae3a27c82c5f0e352abf1dcb67f4 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:09 +0000 Subject: [PATCH 2065/6849] team: comments: s/net\/drivers\/team/drivers\/net\/team/ Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 2 +- drivers/net/team/team_mode_activebackup.c | 2 +- drivers/net/team/team_mode_roundrobin.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 32cb290fb800..7ec53f81c1c4 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1,5 +1,5 @@ /* - * net/drivers/team/team.c - Network team device driver + * drivers/net/team/team.c - Network team device driver * Copyright (c) 2011 Jiri Pirko * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c index acd925f070b5..bcc7d6d2579a 100644 --- a/drivers/net/team/team_mode_activebackup.c +++ b/drivers/net/team/team_mode_activebackup.c @@ -1,5 +1,5 @@ /* - * net/drivers/team/team_mode_activebackup.c - Active-backup mode for team + * drivers/net/team/team_mode_activebackup.c - Active-backup mode for team * Copyright (c) 2011 Jiri Pirko * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c index daafca2b2da4..52dd0ec9cd1f 100644 --- a/drivers/net/team/team_mode_roundrobin.c +++ b/drivers/net/team/team_mode_roundrobin.c @@ -1,5 +1,5 @@ /* - * net/drivers/team/team_mode_roundrobin.c - Round-robin mode for team + * drivers/net/team/team_mode_roundrobin.c - Round-robin mode for team * Copyright (c) 2011 Jiri Pirko * * This program is free software; you can redistribute it and/or modify -- GitLab From 85d59a87248de90e3266e10dce99477b60f524c0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:10 +0000 Subject: [PATCH 2066/6849] team: push array_index and port into separate structure Introduce struct team_option_inst_info and push option instance info there. It can be then easily passed to gsetter context and used for feature async option changes. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 68 ++++++++++++++++++++++++++--------------- include/linux/if_team.h | 9 ++++-- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 7ec53f81c1c4..cff8e253df72 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -89,8 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port) struct team_option_inst { /* One for each option instance */ struct list_head list; struct team_option *option; - struct team_port *port; /* != NULL if per-port */ - u32 array_index; + struct team_option_inst_info info; bool changed; bool removed; }; @@ -130,6 +129,7 @@ static int __team_option_inst_add(struct team *team, struct team_option *option, struct team_option_inst *opt_inst; unsigned int array_size; unsigned int i; + int err; array_size = option->array_size; if (!array_size) @@ -140,11 +140,17 @@ static int __team_option_inst_add(struct team *team, struct team_option *option, if (!opt_inst) return -ENOMEM; opt_inst->option = option; - opt_inst->port = port; - opt_inst->array_index = i; + opt_inst->info.port = port; + opt_inst->info.array_index = i; opt_inst->changed = true; opt_inst->removed = false; list_add_tail(&opt_inst->list, &team->option_inst_list); + if (option->init) { + err = option->init(team, &opt_inst->info); + if (err) + return err; + } + } return 0; } @@ -193,7 +199,7 @@ static void __team_option_inst_del_port(struct team *team, list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) { if (opt_inst->option->per_port && - opt_inst->port == port) + opt_inst->info.port == port) __team_option_inst_del(opt_inst); } } @@ -224,7 +230,7 @@ static void __team_option_inst_mark_removed_port(struct team *team, struct team_option_inst *opt_inst; list_for_each_entry(opt_inst, &team->option_inst_list, list) { - if (opt_inst->port == port) { + if (opt_inst->info.port == port) { opt_inst->changed = true; opt_inst->removed = true; } @@ -958,39 +964,47 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx) static int team_port_en_option_get(struct team *team, struct team_gsetter_ctx *ctx) { - ctx->data.bool_val = team_port_enabled(ctx->port); + struct team_port *port = ctx->info->port; + + ctx->data.bool_val = team_port_enabled(port); return 0; } static int team_port_en_option_set(struct team *team, struct team_gsetter_ctx *ctx) { + struct team_port *port = ctx->info->port; + if (ctx->data.bool_val) - team_port_enable(team, ctx->port); + team_port_enable(team, port); else - team_port_disable(team, ctx->port); + team_port_disable(team, port); return 0; } static int team_user_linkup_option_get(struct team *team, struct team_gsetter_ctx *ctx) { - ctx->data.bool_val = ctx->port->user.linkup; + struct team_port *port = ctx->info->port; + + ctx->data.bool_val = port->user.linkup; return 0; } static int team_user_linkup_option_set(struct team *team, struct team_gsetter_ctx *ctx) { - ctx->port->user.linkup = ctx->data.bool_val; - team_refresh_port_linkup(ctx->port); + struct team_port *port = ctx->info->port; + + port->user.linkup = ctx->data.bool_val; + team_refresh_port_linkup(port); return 0; } static int team_user_linkup_en_option_get(struct team *team, struct team_gsetter_ctx *ctx) { - struct team_port *port = ctx->port; + struct team_port *port = ctx->info->port; ctx->data.bool_val = port->user.linkup_enabled; return 0; @@ -999,10 +1013,10 @@ static int team_user_linkup_en_option_get(struct team *team, static int team_user_linkup_en_option_set(struct team *team, struct team_gsetter_ctx *ctx) { - struct team_port *port = ctx->port; + struct team_port *port = ctx->info->port; port->user.linkup_enabled = ctx->data.bool_val; - team_refresh_port_linkup(ctx->port); + team_refresh_port_linkup(port); return 0; } @@ -1557,6 +1571,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb, list_for_each_entry(opt_inst, &team->option_inst_list, list) { struct nlattr *option_item; struct team_option *option = opt_inst->option; + struct team_option_inst_info *opt_inst_info; struct team_gsetter_ctx ctx; /* Include only changed options if fill all mode is not on */ @@ -1575,16 +1590,18 @@ static int team_nl_fill_options_get(struct sk_buff *skb, if (opt_inst->removed && nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) goto nla_put_failure; - if (opt_inst->port && + + opt_inst_info = &opt_inst->info; + if (opt_inst_info->port && nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX, - opt_inst->port->dev->ifindex)) + opt_inst_info->port->dev->ifindex)) goto nla_put_failure; - ctx.port = opt_inst->port; if (opt_inst->option->array_size && nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, - opt_inst->array_index)) + opt_inst_info->array_index)) goto nla_put_failure; - ctx.array_index = opt_inst->array_index; + ctx.info = opt_inst_info; + switch (option->type) { case TEAM_OPTION_TYPE_U32: if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) @@ -1746,19 +1763,20 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) list_for_each_entry(opt_inst, &team->option_inst_list, list) { struct team_option *option = opt_inst->option; struct team_gsetter_ctx ctx; + struct team_option_inst_info *opt_inst_info; int tmp_ifindex; - tmp_ifindex = opt_inst->port ? - opt_inst->port->dev->ifindex : 0; + opt_inst_info = &opt_inst->info; + tmp_ifindex = opt_inst_info->port ? + opt_inst_info->port->dev->ifindex : 0; if (option->type != opt_type || strcmp(option->name, opt_name) || tmp_ifindex != opt_port_ifindex || (option->array_size && !opt_is_array) || - opt_inst->array_index != opt_array_index) + opt_inst_info->array_index != opt_array_index) continue; opt_found = true; - ctx.port = opt_inst->port; - ctx.array_index = opt_inst->array_index; + ctx.info = opt_inst_info; switch (opt_type) { case TEAM_OPTION_TYPE_U32: ctx.data.u32_val = nla_get_u32(attr_data); diff --git a/include/linux/if_team.h b/include/linux/if_team.h index b1719e239a0b..30854cb0c855 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -83,6 +83,11 @@ enum team_option_type { TEAM_OPTION_TYPE_BOOL, }; +struct team_option_inst_info { + u32 array_index; + struct team_port *port; /* != NULL if per-port */ +}; + struct team_gsetter_ctx { union { u32 u32_val; @@ -93,8 +98,7 @@ struct team_gsetter_ctx { } bin_val; bool bool_val; } data; - u32 array_index; - struct team_port *port; + struct team_option_inst_info *info; }; struct team_option { @@ -103,6 +107,7 @@ struct team_option { bool per_port; unsigned int array_size; /* != 0 means the option is array */ enum team_option_type type; + int (*init)(struct team *team, struct team_option_inst_info *info); int (*getter)(struct team *team, struct team_gsetter_ctx *ctx); int (*setter)(struct team *team, struct team_gsetter_ctx *ctx); }; -- GitLab From 0f1aad2b7f01d88782fbf4ab08b13a7d92b9b6b2 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:11 +0000 Subject: [PATCH 2067/6849] team: allow async option changes This patch adds two exported functions. One allows to mark option instance as changed and the second processes change check and does transfer of changed options to userspace. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 18 ++++++++++++++++++ include/linux/if_team.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index cff8e253df72..7988ba099b94 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -82,6 +82,7 @@ static void team_refresh_port_linkup(struct team_port *port) port->state.linkup; } + /******************* * Options handling *******************/ @@ -387,6 +388,22 @@ static int team_option_set(struct team *team, return err; } +void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info) +{ + struct team_option_inst *opt_inst; + + opt_inst = container_of(opt_inst_info, struct team_option_inst, info); + opt_inst->changed = true; +} +EXPORT_SYMBOL(team_option_inst_set_change); + +void team_options_change_check(struct team *team) +{ + __team_options_change_check(team); +} +EXPORT_SYMBOL(team_options_change_check); + + /**************** * Mode handling ****************/ @@ -2051,6 +2068,7 @@ static void team_port_change_check(struct team_port *port, bool linkup) mutex_unlock(&team->lock); } + /************************************ * Net device notifier event handler ************************************/ diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 30854cb0c855..2f2972535cc0 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -112,6 +112,9 @@ struct team_option { int (*setter)(struct team *team, struct team_gsetter_ctx *ctx); }; +extern void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info); +extern void team_options_change_check(struct team *team); + struct team_mode { const char *kind; struct module *owner; -- GitLab From 75db986a6b93dd93e543387720b88f350ce38d30 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:12 +0000 Subject: [PATCH 2068/6849] team: fix error path in team_nl_fill_options_get() genlmsg_cancel() needs to be called in case nest fails Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 7988ba099b94..82ded1820caf 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1583,7 +1583,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb, goto nla_put_failure; option_list = nla_nest_start(skb, TEAM_ATTR_LIST_OPTION); if (!option_list) - return -EMSGSIZE; + goto nla_put_failure; list_for_each_entry(opt_inst, &team->option_inst_list, list) { struct nlattr *option_item; -- GitLab From 3221c64603d9843d8a28dfd8e678e46625d5d807 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:13 +0000 Subject: [PATCH 2069/6849] team: fix error path in team_nl_fill_port_list_get() genlmsg_cancel() needs to be called in case nest fails Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 82ded1820caf..e977f440c378 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1849,7 +1849,7 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb, goto nla_put_failure; port_list = nla_nest_start(skb, TEAM_ATTR_LIST_PORT); if (!port_list) - return -EMSGSIZE; + goto nla_put_failure; list_for_each_entry(port, &team->port_list, list) { struct nlattr *port_item; -- GitLab From 01048d9a293cbe9aac00fd014b9754bbc7eb136f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:14 +0000 Subject: [PATCH 2070/6849] team: allow to specify one option instance to be send to userspace No need to walk through option instance list and look for ->changed == true when called knows exactly what one option instance changed. Also use lists to pass option instances needed to be present in netlink message. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 210 ++++++++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 86 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index e977f440c378..da72f41d3914 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -89,6 +89,7 @@ static void team_refresh_port_linkup(struct team_port *port) struct team_option_inst { /* One for each option instance */ struct list_head list; + struct list_head tmp_list; struct team_option *option; struct team_option_inst_info info; bool changed; @@ -319,6 +320,8 @@ static void __team_options_unregister(struct team *team, } static void __team_options_change_check(struct team *team); +static void __team_option_inst_change(struct team *team, + struct team_option_inst *opt_inst); int team_options_register(struct team *team, const struct team_option *option, @@ -383,8 +386,7 @@ static int team_option_set(struct team *team, if (err) return err; - opt_inst->changed = true; - __team_options_change_check(team); + __team_option_inst_change(team, opt_inst); return err; } @@ -1565,9 +1567,95 @@ err_fill: return err; } +static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team, + struct team_option_inst *opt_inst) +{ + struct nlattr *option_item; + struct team_option *option = opt_inst->option; + struct team_option_inst_info *opt_inst_info; + struct team_gsetter_ctx ctx; + int err; + + option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION); + if (!option_item) + goto nla_put_failure; + if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name)) + goto nla_put_failure; + if (opt_inst->changed) { + if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED)) + goto nla_put_failure; + opt_inst->changed = false; + } + if (opt_inst->removed && nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) + goto nla_put_failure; + + opt_inst_info = &opt_inst->info; + if (opt_inst_info->port && + nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX, + opt_inst_info->port->dev->ifindex)) + goto nla_put_failure; + if (opt_inst->option->array_size && + nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, + opt_inst_info->array_index)) + goto nla_put_failure; + ctx.info = opt_inst_info; + + switch (option->type) { + case TEAM_OPTION_TYPE_U32: + if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) + goto nla_put_failure; + err = team_option_get(team, opt_inst, &ctx); + if (err) + goto errout; + if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.u32_val)) + goto nla_put_failure; + break; + case TEAM_OPTION_TYPE_STRING: + if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING)) + goto nla_put_failure; + err = team_option_get(team, opt_inst, &ctx); + if (err) + goto errout; + if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA, + ctx.data.str_val)) + goto nla_put_failure; + break; + case TEAM_OPTION_TYPE_BINARY: + if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY)) + goto nla_put_failure; + err = team_option_get(team, opt_inst, &ctx); + if (err) + goto errout; + if (nla_put(skb, TEAM_ATTR_OPTION_DATA, ctx.data.bin_val.len, + ctx.data.bin_val.ptr)) + goto nla_put_failure; + break; + case TEAM_OPTION_TYPE_BOOL: + if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_FLAG)) + goto nla_put_failure; + err = team_option_get(team, opt_inst, &ctx); + if (err) + goto errout; + if (ctx.data.bool_val && + nla_put_flag(skb, TEAM_ATTR_OPTION_DATA)) + goto nla_put_failure; + break; + default: + BUG(); + } + nla_nest_end(skb, option_item); + return 0; + +nla_put_failure: + err = -EMSGSIZE; +errout: + return err; +} + static int team_nl_fill_options_get(struct sk_buff *skb, u32 pid, u32 seq, int flags, - struct team *team, bool fillall) + struct team *team, + struct list_head *sel_opt_inst_list) { struct nlattr *option_list; void *hdr; @@ -1585,85 +1673,10 @@ static int team_nl_fill_options_get(struct sk_buff *skb, if (!option_list) goto nla_put_failure; - list_for_each_entry(opt_inst, &team->option_inst_list, list) { - struct nlattr *option_item; - struct team_option *option = opt_inst->option; - struct team_option_inst_info *opt_inst_info; - struct team_gsetter_ctx ctx; - - /* Include only changed options if fill all mode is not on */ - if (!fillall && !opt_inst->changed) - continue; - option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION); - if (!option_item) - goto nla_put_failure; - if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name)) - goto nla_put_failure; - if (opt_inst->changed) { - if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED)) - goto nla_put_failure; - opt_inst->changed = false; - } - if (opt_inst->removed && - nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) - goto nla_put_failure; - - opt_inst_info = &opt_inst->info; - if (opt_inst_info->port && - nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX, - opt_inst_info->port->dev->ifindex)) - goto nla_put_failure; - if (opt_inst->option->array_size && - nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, - opt_inst_info->array_index)) - goto nla_put_failure; - ctx.info = opt_inst_info; - - switch (option->type) { - case TEAM_OPTION_TYPE_U32: - if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; - if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA, - ctx.data.u32_val)) - goto nla_put_failure; - break; - case TEAM_OPTION_TYPE_STRING: - if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; - if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA, - ctx.data.str_val)) - goto nla_put_failure; - break; - case TEAM_OPTION_TYPE_BINARY: - if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; - if (nla_put(skb, TEAM_ATTR_OPTION_DATA, - ctx.data.bin_val.len, ctx.data.bin_val.ptr)) - goto nla_put_failure; - break; - case TEAM_OPTION_TYPE_BOOL: - if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_FLAG)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; - if (ctx.data.bool_val && - nla_put_flag(skb, TEAM_ATTR_OPTION_DATA)) - goto nla_put_failure; - break; - default: - BUG(); - } - nla_nest_end(skb, option_item); + list_for_each_entry(opt_inst, sel_opt_inst_list, tmp_list) { + err = team_nl_fill_one_option_get(skb, team, opt_inst); + if (err) + goto errout; } nla_nest_end(skb, option_list); @@ -1680,9 +1693,14 @@ static int team_nl_fill_options_get_all(struct sk_buff *skb, struct genl_info *info, int flags, struct team *team) { + struct team_option_inst *opt_inst; + LIST_HEAD(sel_opt_inst_list); + + list_for_each_entry(opt_inst, &team->option_inst_list, list) + list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list); return team_nl_fill_options_get(skb, info->snd_pid, info->snd_seq, NLM_F_ACK, - team, true); + team, &sel_opt_inst_list); } static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) @@ -1941,7 +1959,8 @@ static struct genl_multicast_group team_change_event_mcgrp = { .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, }; -static int team_nl_send_event_options_get(struct team *team) +static int team_nl_send_event_options_get(struct team *team, + struct list_head *sel_opt_inst_list) { struct sk_buff *skb; int err; @@ -1951,7 +1970,7 @@ static int team_nl_send_event_options_get(struct team *team) if (!skb) return -ENOMEM; - err = team_nl_fill_options_get(skb, 0, 0, 0, team, false); + err = team_nl_fill_options_get(skb, 0, 0, 0, team, sel_opt_inst_list); if (err < 0) goto err_fill; @@ -2021,12 +2040,31 @@ static void team_nl_fini(void) static void __team_options_change_check(struct team *team) { int err; + struct team_option_inst *opt_inst; + LIST_HEAD(sel_opt_inst_list); - err = team_nl_send_event_options_get(team); + list_for_each_entry(opt_inst, &team->option_inst_list, list) { + if (opt_inst->changed) + list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list); + } + err = team_nl_send_event_options_get(team, &sel_opt_inst_list); if (err) netdev_warn(team->dev, "Failed to send options change via netlink\n"); } +static void __team_option_inst_change(struct team *team, + struct team_option_inst *sel_opt_inst) +{ + int err; + LIST_HEAD(sel_opt_inst_list); + + sel_opt_inst->changed = true; + list_add(&sel_opt_inst->tmp_list, &sel_opt_inst_list); + err = team_nl_send_event_options_get(team, &sel_opt_inst_list); + if (err) + netdev_warn(team->dev, "Failed to send option change via netlink\n"); +} + /* rtnl lock is held */ static void __team_port_change_check(struct team_port *port, bool linkup) { -- GitLab From f88725ffb069fef0ea3d47381d33c928f4c48cba Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:15 +0000 Subject: [PATCH 2071/6849] team: pass NULL to __team_option_inst_add() instead of 0 Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index da72f41d3914..eb18ac93095a 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -164,7 +164,7 @@ static int __team_option_inst_add_option(struct team *team, int err; if (!option->per_port) { - err = __team_option_inst_add(team, option, 0); + err = __team_option_inst_add(team, option, NULL); if (err) goto inst_del_option; } -- GitLab From 4bccfd17e1f77593e99d5321c48c704a0a43ab68 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:16 +0000 Subject: [PATCH 2072/6849] team: add port_[enabled/disabled] mode callbacks Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 4 ++++ include/linux/if_team.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index eb18ac93095a..bc76f946e071 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -714,6 +714,8 @@ static void team_port_enable(struct team *team, port->index = team->en_port_count++; hlist_add_head_rcu(&port->hlist, team_port_index_hash(team, port->index)); + if (team->ops.port_enabled) + team->ops.port_enabled(team, port); } static void __reconstruct_port_hlist(struct team *team, int rm_index) @@ -737,6 +739,8 @@ static void team_port_disable(struct team *team, if (!team_port_enabled(port)) return; + if (team->ops.port_disabled) + team->ops.port_disabled(team, port); hlist_del_rcu(&port->hlist); __reconstruct_port_hlist(team, rm_index); team->en_port_count--; diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 2f2972535cc0..c1938869191f 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -74,6 +74,8 @@ struct team_mode_ops { int (*port_enter)(struct team *team, struct team_port *port); void (*port_leave)(struct team *team, struct team_port *port); void (*port_change_mac)(struct team *team, struct team_port *port); + void (*port_enabled)(struct team *team, struct team_port *port); + void (*port_disabled)(struct team *team, struct team_port *port); }; enum team_option_type { -- GitLab From ab8250d70063f77929fc404c02390a1f64d66416 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:17 +0000 Subject: [PATCH 2073/6849] team: lb: introduce infrastructure for userspace driven tx loadbalancing Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_loadbalance.c | 517 ++++++++++++++++++++++- 1 file changed, 500 insertions(+), 17 deletions(-) diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index a475b1304f9a..33e30edeb202 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -17,18 +17,163 @@ #include #include +struct lb_priv; + +typedef struct team_port *lb_select_tx_port_func_t(struct team *, + struct lb_priv *, + struct sk_buff *, + unsigned char); + +#define LB_TX_HASHTABLE_SIZE 256 /* hash is a char */ + +struct lb_stats { + u64 tx_bytes; +}; + +struct lb_pcpu_stats { + struct lb_stats hash_stats[LB_TX_HASHTABLE_SIZE]; + struct u64_stats_sync syncp; +}; + +struct lb_stats_info { + struct lb_stats stats; + struct lb_stats last_stats; + struct team_option_inst_info *opt_inst_info; +}; + +struct lb_port_mapping { + struct team_port __rcu *port; + struct team_option_inst_info *opt_inst_info; +}; + +struct lb_priv_ex { + struct team *team; + struct lb_port_mapping tx_hash_to_port_mapping[LB_TX_HASHTABLE_SIZE]; + struct sock_fprog *orig_fprog; + struct { + unsigned int refresh_interval; /* in tenths of second */ + struct delayed_work refresh_dw; + struct lb_stats_info info[LB_TX_HASHTABLE_SIZE]; + } stats; +}; + struct lb_priv { struct sk_filter __rcu *fp; - struct sock_fprog *orig_fprog; + lb_select_tx_port_func_t __rcu *select_tx_port_func; + struct lb_pcpu_stats __percpu *pcpu_stats; + struct lb_priv_ex *ex; /* priv extension */ }; -static struct lb_priv *lb_priv(struct team *team) +static struct lb_priv *get_lb_priv(struct team *team) { return (struct lb_priv *) &team->mode_priv; } -static unsigned char lb_get_skb_hash(struct lb_priv *lb_priv, - struct sk_buff *skb) +struct lb_port_priv { + struct lb_stats __percpu *pcpu_stats; + struct lb_stats_info stats_info; +}; + +static struct lb_port_priv *get_lb_port_priv(struct team_port *port) +{ + return (struct lb_port_priv *) &port->mode_priv; +} + +#define LB_HTPM_PORT_BY_HASH(lp_priv, hash) \ + (lb_priv)->ex->tx_hash_to_port_mapping[hash].port + +#define LB_HTPM_OPT_INST_INFO_BY_HASH(lp_priv, hash) \ + (lb_priv)->ex->tx_hash_to_port_mapping[hash].opt_inst_info + +static void lb_tx_hash_to_port_mapping_null_port(struct team *team, + struct team_port *port) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + bool changed = false; + int i; + + for (i = 0; i < LB_TX_HASHTABLE_SIZE; i++) { + struct lb_port_mapping *pm; + + pm = &lb_priv->ex->tx_hash_to_port_mapping[i]; + if (pm->port == port) { + rcu_assign_pointer(pm->port, NULL); + team_option_inst_set_change(pm->opt_inst_info); + changed = true; + } + } + if (changed) + team_options_change_check(team); +} + +/* Basic tx selection based solely by hash */ +static struct team_port *lb_hash_select_tx_port(struct team *team, + struct lb_priv *lb_priv, + struct sk_buff *skb, + unsigned char hash) +{ + int port_index; + + port_index = hash % team->en_port_count; + return team_get_port_by_index_rcu(team, port_index); +} + +/* Hash to port mapping select tx port */ +static struct team_port *lb_htpm_select_tx_port(struct team *team, + struct lb_priv *lb_priv, + struct sk_buff *skb, + unsigned char hash) +{ + return rcu_dereference(LB_HTPM_PORT_BY_HASH(lb_priv, hash)); +} + +struct lb_select_tx_port { + char *name; + lb_select_tx_port_func_t *func; +}; + +static const struct lb_select_tx_port lb_select_tx_port_list[] = { + { + .name = "hash", + .func = lb_hash_select_tx_port, + }, + { + .name = "hash_to_port_mapping", + .func = lb_htpm_select_tx_port, + }, +}; +#define LB_SELECT_TX_PORT_LIST_COUNT ARRAY_SIZE(lb_select_tx_port_list) + +static char *lb_select_tx_port_get_name(lb_select_tx_port_func_t *func) +{ + int i; + + for (i = 0; i < LB_SELECT_TX_PORT_LIST_COUNT; i++) { + const struct lb_select_tx_port *item; + + item = &lb_select_tx_port_list[i]; + if (item->func == func) + return item->name; + } + return NULL; +} + +static lb_select_tx_port_func_t *lb_select_tx_port_get_func(const char *name) +{ + int i; + + for (i = 0; i < LB_SELECT_TX_PORT_LIST_COUNT; i++) { + const struct lb_select_tx_port *item; + + item = &lb_select_tx_port_list[i]; + if (!strcmp(item->name, name)) + return item->func; + } + return NULL; +} + +static unsigned int lb_get_skb_hash(struct lb_priv *lb_priv, + struct sk_buff *skb) { struct sk_filter *fp; uint32_t lhash; @@ -42,18 +187,40 @@ static unsigned char lb_get_skb_hash(struct lb_priv *lb_priv, return c[0] ^ c[1] ^ c[2] ^ c[3]; } +static void lb_update_tx_stats(unsigned int tx_bytes, struct lb_priv *lb_priv, + struct lb_port_priv *lb_port_priv, + unsigned char hash) +{ + struct lb_pcpu_stats *pcpu_stats; + struct lb_stats *port_stats; + struct lb_stats *hash_stats; + + pcpu_stats = this_cpu_ptr(lb_priv->pcpu_stats); + port_stats = this_cpu_ptr(lb_port_priv->pcpu_stats); + hash_stats = &pcpu_stats->hash_stats[hash]; + u64_stats_update_begin(&pcpu_stats->syncp); + port_stats->tx_bytes += tx_bytes; + hash_stats->tx_bytes += tx_bytes; + u64_stats_update_end(&pcpu_stats->syncp); +} + static bool lb_transmit(struct team *team, struct sk_buff *skb) { + struct lb_priv *lb_priv = get_lb_priv(team); + lb_select_tx_port_func_t *select_tx_port_func; struct team_port *port; - int port_index; + unsigned char hash; + unsigned int tx_bytes = skb->len; - port_index = lb_get_skb_hash(lb_priv(team), skb) % team->en_port_count; - port = team_get_port_by_index_rcu(team, port_index); + hash = lb_get_skb_hash(lb_priv, skb); + select_tx_port_func = rcu_dereference(lb_priv->select_tx_port_func); + port = select_tx_port_func(team, lb_priv, skb, hash); if (unlikely(!port)) goto drop; skb->dev = port->dev; if (dev_queue_xmit(skb)) return false; + lb_update_tx_stats(tx_bytes, lb_priv, get_lb_port_priv(port), hash); return true; drop: @@ -63,14 +230,16 @@ drop: static int lb_bpf_func_get(struct team *team, struct team_gsetter_ctx *ctx) { - if (!lb_priv(team)->orig_fprog) { + struct lb_priv *lb_priv = get_lb_priv(team); + + if (!lb_priv->ex->orig_fprog) { ctx->data.bin_val.len = 0; ctx->data.bin_val.ptr = NULL; return 0; } - ctx->data.bin_val.len = lb_priv(team)->orig_fprog->len * + ctx->data.bin_val.len = lb_priv->ex->orig_fprog->len * sizeof(struct sock_filter); - ctx->data.bin_val.ptr = lb_priv(team)->orig_fprog->filter; + ctx->data.bin_val.ptr = lb_priv->ex->orig_fprog->filter; return 0; } @@ -103,6 +272,7 @@ static void __fprog_destroy(struct sock_fprog *fprog) static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) { + struct lb_priv *lb_priv = get_lb_priv(team); struct sk_filter *fp = NULL; struct sock_fprog *fprog = NULL; int err; @@ -119,14 +289,232 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) } } - if (lb_priv(team)->orig_fprog) { + if (lb_priv->ex->orig_fprog) { /* Clear old filter data */ - __fprog_destroy(lb_priv(team)->orig_fprog); - sk_unattached_filter_destroy(lb_priv(team)->fp); + __fprog_destroy(lb_priv->ex->orig_fprog); + sk_unattached_filter_destroy(lb_priv->fp); } - rcu_assign_pointer(lb_priv(team)->fp, fp); - lb_priv(team)->orig_fprog = fprog; + rcu_assign_pointer(lb_priv->fp, fp); + lb_priv->ex->orig_fprog = fprog; + return 0; +} + +static int lb_tx_method_get(struct team *team, struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + char *name; + + name = lb_select_tx_port_get_name(lb_priv->select_tx_port_func); + BUG_ON(!name); + ctx->data.str_val = name; + return 0; +} + +static int lb_tx_method_set(struct team *team, struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + lb_select_tx_port_func_t *func; + + func = lb_select_tx_port_get_func(ctx->data.str_val); + if (!func) + return -EINVAL; + rcu_assign_pointer(lb_priv->select_tx_port_func, func); + return 0; +} + +static int lb_tx_hash_to_port_mapping_init(struct team *team, + struct team_option_inst_info *info) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + unsigned char hash = info->array_index; + + LB_HTPM_OPT_INST_INFO_BY_HASH(lb_priv, hash) = info; + return 0; +} + +static int lb_tx_hash_to_port_mapping_get(struct team *team, + struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + struct team_port *port; + unsigned char hash = ctx->info->array_index; + + port = LB_HTPM_PORT_BY_HASH(lb_priv, hash); + ctx->data.u32_val = port ? port->dev->ifindex : 0; + return 0; +} + +static int lb_tx_hash_to_port_mapping_set(struct team *team, + struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + struct team_port *port; + unsigned char hash = ctx->info->array_index; + + list_for_each_entry(port, &team->port_list, list) { + if (ctx->data.u32_val == port->dev->ifindex) { + rcu_assign_pointer(LB_HTPM_PORT_BY_HASH(lb_priv, hash), + port); + return 0; + } + } + return -ENODEV; +} + +static int lb_hash_stats_init(struct team *team, + struct team_option_inst_info *info) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + unsigned char hash = info->array_index; + + lb_priv->ex->stats.info[hash].opt_inst_info = info; + return 0; +} + +static int lb_hash_stats_get(struct team *team, struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + unsigned char hash = ctx->info->array_index; + + ctx->data.bin_val.ptr = &lb_priv->ex->stats.info[hash].stats; + ctx->data.bin_val.len = sizeof(struct lb_stats); + return 0; +} + +static int lb_port_stats_init(struct team *team, + struct team_option_inst_info *info) +{ + struct team_port *port = info->port; + struct lb_port_priv *lb_port_priv = get_lb_port_priv(port); + + lb_port_priv->stats_info.opt_inst_info = info; + return 0; +} + +static int lb_port_stats_get(struct team *team, struct team_gsetter_ctx *ctx) +{ + struct team_port *port = ctx->info->port; + struct lb_port_priv *lb_port_priv = get_lb_port_priv(port); + + ctx->data.bin_val.ptr = &lb_port_priv->stats_info.stats; + ctx->data.bin_val.len = sizeof(struct lb_stats); + return 0; +} + +static void __lb_stats_info_refresh_prepare(struct lb_stats_info *s_info) +{ + memcpy(&s_info->last_stats, &s_info->stats, sizeof(struct lb_stats)); + memset(&s_info->stats, 0, sizeof(struct lb_stats)); +} + +static bool __lb_stats_info_refresh_check(struct lb_stats_info *s_info, + struct team *team) +{ + if (memcmp(&s_info->last_stats, &s_info->stats, + sizeof(struct lb_stats))) { + team_option_inst_set_change(s_info->opt_inst_info); + return true; + } + return false; +} + +static void __lb_one_cpu_stats_add(struct lb_stats *acc_stats, + struct lb_stats *cpu_stats, + struct u64_stats_sync *syncp) +{ + unsigned int start; + struct lb_stats tmp; + + do { + start = u64_stats_fetch_begin_bh(syncp); + tmp.tx_bytes = cpu_stats->tx_bytes; + } while (u64_stats_fetch_retry_bh(syncp, start)); + acc_stats->tx_bytes += tmp.tx_bytes; +} + +static void lb_stats_refresh(struct work_struct *work) +{ + struct team *team; + struct lb_priv *lb_priv; + struct lb_priv_ex *lb_priv_ex; + struct lb_pcpu_stats *pcpu_stats; + struct lb_stats *stats; + struct lb_stats_info *s_info; + struct team_port *port; + bool changed = false; + int i; + int j; + + lb_priv_ex = container_of(work, struct lb_priv_ex, + stats.refresh_dw.work); + + team = lb_priv_ex->team; + lb_priv = get_lb_priv(team); + + if (!mutex_trylock(&team->lock)) { + schedule_delayed_work(&lb_priv_ex->stats.refresh_dw, 0); + return; + } + + for (j = 0; j < LB_TX_HASHTABLE_SIZE; j++) { + s_info = &lb_priv->ex->stats.info[j]; + __lb_stats_info_refresh_prepare(s_info); + for_each_possible_cpu(i) { + pcpu_stats = per_cpu_ptr(lb_priv->pcpu_stats, i); + stats = &pcpu_stats->hash_stats[j]; + __lb_one_cpu_stats_add(&s_info->stats, stats, + &pcpu_stats->syncp); + } + changed |= __lb_stats_info_refresh_check(s_info, team); + } + + list_for_each_entry(port, &team->port_list, list) { + struct lb_port_priv *lb_port_priv = get_lb_port_priv(port); + + s_info = &lb_port_priv->stats_info; + __lb_stats_info_refresh_prepare(s_info); + for_each_possible_cpu(i) { + pcpu_stats = per_cpu_ptr(lb_priv->pcpu_stats, i); + stats = per_cpu_ptr(lb_port_priv->pcpu_stats, i); + __lb_one_cpu_stats_add(&s_info->stats, stats, + &pcpu_stats->syncp); + } + changed |= __lb_stats_info_refresh_check(s_info, team); + } + + if (changed) + team_options_change_check(team); + + schedule_delayed_work(&lb_priv_ex->stats.refresh_dw, + (lb_priv_ex->stats.refresh_interval * HZ) / 10); + + mutex_unlock(&team->lock); +} + +static int lb_stats_refresh_interval_get(struct team *team, + struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + + ctx->data.u32_val = lb_priv->ex->stats.refresh_interval; + return 0; +} + +static int lb_stats_refresh_interval_set(struct team *team, + struct team_gsetter_ctx *ctx) +{ + struct lb_priv *lb_priv = get_lb_priv(team); + unsigned int interval; + + interval = ctx->data.u32_val; + if (lb_priv->ex->stats.refresh_interval == interval) + return 0; + lb_priv->ex->stats.refresh_interval = interval; + if (interval) + schedule_delayed_work(&lb_priv->ex->stats.refresh_dw, 0); + else + cancel_delayed_work(&lb_priv->ex->stats.refresh_dw); return 0; } @@ -137,23 +525,117 @@ static const struct team_option lb_options[] = { .getter = lb_bpf_func_get, .setter = lb_bpf_func_set, }, + { + .name = "lb_tx_method", + .type = TEAM_OPTION_TYPE_STRING, + .getter = lb_tx_method_get, + .setter = lb_tx_method_set, + }, + { + .name = "lb_tx_hash_to_port_mapping", + .array_size = LB_TX_HASHTABLE_SIZE, + .type = TEAM_OPTION_TYPE_U32, + .init = lb_tx_hash_to_port_mapping_init, + .getter = lb_tx_hash_to_port_mapping_get, + .setter = lb_tx_hash_to_port_mapping_set, + }, + { + .name = "lb_hash_stats", + .array_size = LB_TX_HASHTABLE_SIZE, + .type = TEAM_OPTION_TYPE_BINARY, + .init = lb_hash_stats_init, + .getter = lb_hash_stats_get, + }, + { + .name = "lb_port_stats", + .per_port = true, + .type = TEAM_OPTION_TYPE_BINARY, + .init = lb_port_stats_init, + .getter = lb_port_stats_get, + }, + { + .name = "lb_stats_refresh_interval", + .type = TEAM_OPTION_TYPE_U32, + .getter = lb_stats_refresh_interval_get, + .setter = lb_stats_refresh_interval_set, + }, }; static int lb_init(struct team *team) { - return team_options_register(team, lb_options, - ARRAY_SIZE(lb_options)); + struct lb_priv *lb_priv = get_lb_priv(team); + lb_select_tx_port_func_t *func; + int err; + + /* set default tx port selector */ + func = lb_select_tx_port_get_func("hash"); + BUG_ON(!func); + rcu_assign_pointer(lb_priv->select_tx_port_func, func); + + lb_priv->ex = kzalloc(sizeof(*lb_priv->ex), GFP_KERNEL); + if (!lb_priv->ex) + return -ENOMEM; + lb_priv->ex->team = team; + + lb_priv->pcpu_stats = alloc_percpu(struct lb_pcpu_stats); + if (!lb_priv->pcpu_stats) { + err = -ENOMEM; + goto err_alloc_pcpu_stats; + } + + INIT_DELAYED_WORK(&lb_priv->ex->stats.refresh_dw, lb_stats_refresh); + + err = team_options_register(team, lb_options, ARRAY_SIZE(lb_options)); + if (err) + goto err_options_register; + return 0; + +err_options_register: + free_percpu(lb_priv->pcpu_stats); +err_alloc_pcpu_stats: + kfree(lb_priv->ex); + return err; } static void lb_exit(struct team *team) { + struct lb_priv *lb_priv = get_lb_priv(team); + team_options_unregister(team, lb_options, ARRAY_SIZE(lb_options)); + cancel_delayed_work_sync(&lb_priv->ex->stats.refresh_dw); + free_percpu(lb_priv->pcpu_stats); + kfree(lb_priv->ex); +} + +static int lb_port_enter(struct team *team, struct team_port *port) +{ + struct lb_port_priv *lb_port_priv = get_lb_port_priv(port); + + lb_port_priv->pcpu_stats = alloc_percpu(struct lb_stats); + if (!lb_port_priv->pcpu_stats) + return -ENOMEM; + return 0; +} + +static void lb_port_leave(struct team *team, struct team_port *port) +{ + struct lb_port_priv *lb_port_priv = get_lb_port_priv(port); + + free_percpu(lb_port_priv->pcpu_stats); +} + +static void lb_port_disabled(struct team *team, struct team_port *port) +{ + lb_tx_hash_to_port_mapping_null_port(team, port); } static const struct team_mode_ops lb_mode_ops = { .init = lb_init, .exit = lb_exit, + .port_enter = lb_port_enter, + .port_leave = lb_port_leave, + .port_disabled = lb_port_disabled, .transmit = lb_transmit, }; @@ -161,6 +643,7 @@ static const struct team_mode lb_mode = { .kind = "loadbalance", .owner = THIS_MODULE, .priv_size = sizeof(struct lb_priv), + .port_priv_size = sizeof(struct lb_port_priv), .ops = &lb_mode_ops, }; -- GitLab From 9b00cf2d1024d683cb2e206109e356dcac968568 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:18 +0000 Subject: [PATCH 2074/6849] team: implement multipart netlink messages for options transfers Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 198 +++++++++++++++++++++++----------------- 1 file changed, 116 insertions(+), 82 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index bc76f946e071..9e9d3e57a2f6 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1571,102 +1571,128 @@ err_fill: return err; } +typedef int team_nl_send_func_t(struct sk_buff *skb, + struct team *team, u32 pid); + +static int team_nl_send_unicast(struct sk_buff *skb, struct team *team, u32 pid) +{ + return genlmsg_unicast(dev_net(team->dev), skb, pid); +} + static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team, struct team_option_inst *opt_inst) { struct nlattr *option_item; struct team_option *option = opt_inst->option; - struct team_option_inst_info *opt_inst_info; + struct team_option_inst_info *opt_inst_info = &opt_inst->info; struct team_gsetter_ctx ctx; int err; + ctx.info = opt_inst_info; + err = team_option_get(team, opt_inst, &ctx); + if (err) + return err; + option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION); if (!option_item) - goto nla_put_failure; - if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name)) - goto nla_put_failure; - if (opt_inst->changed) { - if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED)) - goto nla_put_failure; - opt_inst->changed = false; - } - if (opt_inst->removed && nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) - goto nla_put_failure; + return -EMSGSIZE; - opt_inst_info = &opt_inst->info; + if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name)) + goto nest_cancel; if (opt_inst_info->port && nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX, opt_inst_info->port->dev->ifindex)) - goto nla_put_failure; + goto nest_cancel; if (opt_inst->option->array_size && nla_put_u32(skb, TEAM_ATTR_OPTION_ARRAY_INDEX, opt_inst_info->array_index)) - goto nla_put_failure; - ctx.info = opt_inst_info; + goto nest_cancel; switch (option->type) { case TEAM_OPTION_TYPE_U32: if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; + goto nest_cancel; if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.u32_val)) - goto nla_put_failure; + goto nest_cancel; break; case TEAM_OPTION_TYPE_STRING: if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; + goto nest_cancel; if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA, ctx.data.str_val)) - goto nla_put_failure; + goto nest_cancel; break; case TEAM_OPTION_TYPE_BINARY: if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; + goto nest_cancel; if (nla_put(skb, TEAM_ATTR_OPTION_DATA, ctx.data.bin_val.len, ctx.data.bin_val.ptr)) - goto nla_put_failure; + goto nest_cancel; break; case TEAM_OPTION_TYPE_BOOL: if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_FLAG)) - goto nla_put_failure; - err = team_option_get(team, opt_inst, &ctx); - if (err) - goto errout; + goto nest_cancel; if (ctx.data.bool_val && nla_put_flag(skb, TEAM_ATTR_OPTION_DATA)) - goto nla_put_failure; + goto nest_cancel; break; default: BUG(); } + if (opt_inst->removed && nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED)) + goto nest_cancel; + if (opt_inst->changed) { + if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED)) + goto nest_cancel; + opt_inst->changed = false; + } nla_nest_end(skb, option_item); return 0; -nla_put_failure: - err = -EMSGSIZE; -errout: - return err; +nest_cancel: + nla_nest_cancel(skb, option_item); + return -EMSGSIZE; +} + +static int __send_and_alloc_skb(struct sk_buff **pskb, + struct team *team, u32 pid, + team_nl_send_func_t *send_func) +{ + int err; + + if (*pskb) { + err = send_func(*pskb, team, pid); + if (err) + return err; + } + *pskb = genlmsg_new(NLMSG_DEFAULT_SIZE - GENL_HDRLEN, GFP_KERNEL); + if (!*pskb) + return -ENOMEM; + return 0; } -static int team_nl_fill_options_get(struct sk_buff *skb, - u32 pid, u32 seq, int flags, - struct team *team, +static int team_nl_send_options_get(struct team *team, u32 pid, u32 seq, + int flags, team_nl_send_func_t *send_func, struct list_head *sel_opt_inst_list) { struct nlattr *option_list; + struct nlmsghdr *nlh; void *hdr; struct team_option_inst *opt_inst; int err; + struct sk_buff *skb = NULL; + bool incomplete; + int i; - hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags, + opt_inst = list_first_entry(sel_opt_inst_list, + struct team_option_inst, tmp_list); + +start_again: + err = __send_and_alloc_skb(&skb, team, pid, send_func); + if (err) + return err; + + hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags | NLM_F_MULTI, TEAM_CMD_OPTIONS_GET); if (IS_ERR(hdr)) return PTR_ERR(hdr); @@ -1677,46 +1703,62 @@ static int team_nl_fill_options_get(struct sk_buff *skb, if (!option_list) goto nla_put_failure; - list_for_each_entry(opt_inst, sel_opt_inst_list, tmp_list) { + i = 0; + incomplete = false; + list_for_each_entry_from(opt_inst, sel_opt_inst_list, tmp_list) { err = team_nl_fill_one_option_get(skb, team, opt_inst); - if (err) + if (err) { + if (err == -EMSGSIZE) { + if (!i) + goto errout; + incomplete = true; + break; + } goto errout; + } + i++; } nla_nest_end(skb, option_list); - return genlmsg_end(skb, hdr); + genlmsg_end(skb, hdr); + if (incomplete) + goto start_again; + +send_done: + nlh = nlmsg_put(skb, pid, seq, NLMSG_DONE, 0, flags | NLM_F_MULTI); + if (!nlh) { + err = __send_and_alloc_skb(&skb, team, pid, send_func); + if (err) + goto errout; + goto send_done; + } + + return send_func(skb, team, pid); nla_put_failure: err = -EMSGSIZE; errout: genlmsg_cancel(skb, hdr); + nlmsg_free(skb); return err; } -static int team_nl_fill_options_get_all(struct sk_buff *skb, - struct genl_info *info, int flags, - struct team *team) -{ - struct team_option_inst *opt_inst; - LIST_HEAD(sel_opt_inst_list); - - list_for_each_entry(opt_inst, &team->option_inst_list, list) - list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list); - return team_nl_fill_options_get(skb, info->snd_pid, - info->snd_seq, NLM_F_ACK, - team, &sel_opt_inst_list); -} - static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) { struct team *team; + struct team_option_inst *opt_inst; int err; + LIST_HEAD(sel_opt_inst_list); team = team_nl_team_get(info); if (!team) return -EINVAL; - err = team_nl_send_generic(info, team, team_nl_fill_options_get_all); + list_for_each_entry(opt_inst, &team->option_inst_list, list) + list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list); + err = team_nl_send_options_get(team, info->snd_pid, info->snd_seq, + NLM_F_ACK, team_nl_send_unicast, + &sel_opt_inst_list); team_nl_team_put(team); @@ -1963,28 +2005,18 @@ static struct genl_multicast_group team_change_event_mcgrp = { .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, }; +static int team_nl_send_multicast(struct sk_buff *skb, + struct team *team, u32 pid) +{ + return genlmsg_multicast_netns(dev_net(team->dev), skb, 0, + team_change_event_mcgrp.id, GFP_KERNEL); +} + static int team_nl_send_event_options_get(struct team *team, struct list_head *sel_opt_inst_list) { - struct sk_buff *skb; - int err; - struct net *net = dev_net(team->dev); - - skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb) - return -ENOMEM; - - err = team_nl_fill_options_get(skb, 0, 0, 0, team, sel_opt_inst_list); - if (err < 0) - goto err_fill; - - err = genlmsg_multicast_netns(net, skb, 0, team_change_event_mcgrp.id, - GFP_KERNEL); - return err; - -err_fill: - nlmsg_free(skb); - return err; + return team_nl_send_options_get(team, 0, 0, 0, team_nl_send_multicast, + sel_opt_inst_list); } static int team_nl_send_event_port_list_get(struct team *team) @@ -2053,7 +2085,8 @@ static void __team_options_change_check(struct team *team) } err = team_nl_send_event_options_get(team, &sel_opt_inst_list); if (err) - netdev_warn(team->dev, "Failed to send options change via netlink\n"); + netdev_warn(team->dev, "Failed to send options change via netlink (err %d)\n", + err); } static void __team_option_inst_change(struct team *team, @@ -2066,7 +2099,8 @@ static void __team_option_inst_change(struct team *team, list_add(&sel_opt_inst->tmp_list, &sel_opt_inst_list); err = team_nl_send_event_options_get(team, &sel_opt_inst_list); if (err) - netdev_warn(team->dev, "Failed to send option change via netlink\n"); + netdev_warn(team->dev, "Failed to send option change via netlink (err %d)\n", + err); } /* rtnl lock is held */ -- GitLab From 35b384bd14f91c74e358e02969ee7bb2542e6d78 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:19 +0000 Subject: [PATCH 2075/6849] team: ensure correct order of netlink messages delivery currently, when port is created and per-port options are present, there options are sent to userspace with ifindex of port which userspace does not know about. Port add message goes right after. This patch corrects message ordering so userspace would not be confused. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 9e9d3e57a2f6..a7b391dfb3b0 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -347,24 +347,6 @@ void team_options_unregister(struct team *team, } EXPORT_SYMBOL(team_options_unregister); -static int team_option_port_add(struct team *team, struct team_port *port) -{ - int err; - - err = __team_option_inst_add_port(team, port); - if (err) - return err; - __team_options_change_check(team); - return 0; -} - -static void team_option_port_del(struct team *team, struct team_port *port) -{ - __team_option_inst_mark_removed_port(team, port); - __team_options_change_check(team); - __team_option_inst_del_port(team, port); -} - static int team_option_get(struct team *team, struct team_option_inst *opt_inst, struct team_gsetter_ctx *ctx) @@ -891,7 +873,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_handler_register; } - err = team_option_port_add(team, port); + err = __team_option_inst_add_port(team, port); if (err) { netdev_err(dev, "Device %s failed to add per-port options\n", portname); @@ -904,6 +886,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) team_adjust_ops(team); __team_compute_features(team); __team_port_change_check(port, !!netif_carrier_ok(port_dev)); + __team_options_change_check(team); netdev_info(dev, "Port device %s added\n", portname); @@ -947,12 +930,14 @@ static int team_port_del(struct team *team, struct net_device *port_dev) return -ENOENT; } + __team_option_inst_mark_removed_port(team, port); + __team_options_change_check(team); + __team_option_inst_del_port(team, port); port->removed = true; __team_port_change_check(port, false); team_port_disable(team, port); list_del_rcu(&port->list); team_adjust_ops(team); - team_option_port_del(team, port); netdev_rx_handler_unregister(port_dev); netdev_set_master(port_dev, NULL); vlan_vids_del_by_dev(port_dev, dev); -- GitLab From 2fcdb2c9e6598e6ced232eca7aa4a61342691f3b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:20 +0000 Subject: [PATCH 2076/6849] team: allow to send multiple set events in one message When multiple sets are done, event message is generated for each. This patch accumulates these messages into one. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index a7b391dfb3b0..3a4a74be52d9 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -320,8 +320,6 @@ static void __team_options_unregister(struct team *team, } static void __team_options_change_check(struct team *team); -static void __team_option_inst_change(struct team *team, - struct team_option_inst *opt_inst); int team_options_register(struct team *team, const struct team_option *option, @@ -360,16 +358,9 @@ static int team_option_set(struct team *team, struct team_option_inst *opt_inst, struct team_gsetter_ctx *ctx) { - int err; - if (!opt_inst->option->setter) return -EOPNOTSUPP; - err = opt_inst->option->setter(team, ctx); - if (err) - return err; - - __team_option_inst_change(team, opt_inst); - return err; + return opt_inst->option->setter(team, ctx); } void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info) @@ -1750,12 +1741,16 @@ static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) return err; } +static int team_nl_send_event_options_get(struct team *team, + struct list_head *sel_opt_inst_list); + static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) { struct team *team; int err = 0; int i; struct nlattr *nl_option; + LIST_HEAD(opt_inst_list); team = team_nl_team_get(info); if (!team) @@ -1867,6 +1862,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) err = team_option_set(team, opt_inst, &ctx); if (err) goto team_put; + opt_inst->changed = true; + list_add(&opt_inst->tmp_list, &opt_inst_list); } if (!opt_found) { err = -ENOENT; @@ -1874,6 +1871,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) } } + err = team_nl_send_event_options_get(team, &opt_inst_list); + team_put: team_nl_team_put(team); @@ -2074,20 +2073,6 @@ static void __team_options_change_check(struct team *team) err); } -static void __team_option_inst_change(struct team *team, - struct team_option_inst *sel_opt_inst) -{ - int err; - LIST_HEAD(sel_opt_inst_list); - - sel_opt_inst->changed = true; - list_add(&sel_opt_inst->tmp_list, &sel_opt_inst_list); - err = team_nl_send_event_options_get(team, &sel_opt_inst_list); - if (err) - netdev_warn(team->dev, "Failed to send option change via netlink (err %d)\n", - err); -} - /* rtnl lock is held */ static void __team_port_change_check(struct team_port *port, bool linkup) { -- GitLab From d1904fbd881e43cde2ec024117efaba83f8d9996 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 19 Jun 2012 05:54:21 +0000 Subject: [PATCH 2077/6849] team: use rcu_dereference_bh() in tx path Should be used instead of rcu_dereference, since rcu_read_lock_bh is held. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_activebackup.c | 2 +- drivers/net/team/team_mode_loadbalance.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c index bcc7d6d2579a..2fe02a8713ea 100644 --- a/drivers/net/team/team_mode_activebackup.c +++ b/drivers/net/team/team_mode_activebackup.c @@ -40,7 +40,7 @@ static bool ab_transmit(struct team *team, struct sk_buff *skb) { struct team_port *active_port; - active_port = rcu_dereference(ab_priv(team)->active_port); + active_port = rcu_dereference_bh(ab_priv(team)->active_port); if (unlikely(!active_port)) goto drop; skb->dev = active_port->dev; diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index 33e30edeb202..45cc0951aa48 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -124,7 +124,7 @@ static struct team_port *lb_htpm_select_tx_port(struct team *team, struct sk_buff *skb, unsigned char hash) { - return rcu_dereference(LB_HTPM_PORT_BY_HASH(lb_priv, hash)); + return rcu_dereference_bh(LB_HTPM_PORT_BY_HASH(lb_priv, hash)); } struct lb_select_tx_port { @@ -179,7 +179,7 @@ static unsigned int lb_get_skb_hash(struct lb_priv *lb_priv, uint32_t lhash; unsigned char *c; - fp = rcu_dereference(lb_priv->fp); + fp = rcu_dereference_bh(lb_priv->fp); if (unlikely(!fp)) return 0; lhash = SK_RUN_FILTER(fp, skb); @@ -213,7 +213,7 @@ static bool lb_transmit(struct team *team, struct sk_buff *skb) unsigned int tx_bytes = skb->len; hash = lb_get_skb_hash(lb_priv, skb); - select_tx_port_func = rcu_dereference(lb_priv->select_tx_port_func); + select_tx_port_func = rcu_dereference_bh(lb_priv->select_tx_port_func); port = select_tx_port_func(team, lb_priv, skb, hash); if (unlikely(!port)) goto drop; -- GitLab From 853c24f79dd6f4a3d6d7b52f235fe121aee08b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 19 Jun 2012 00:41:59 +0000 Subject: [PATCH 2078/6849] net: qmi_wwan: define a structure for driver specific state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usbnet allocates a fixed size array for minidriver specific state. Naming the fields and taking advantage of type checking is a bit more failsafe than casting array elements each time they are referenced. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 49 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..c7b9be81ad08 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -54,6 +54,13 @@ * corresponding management interface */ +/* driver specific data */ +struct qmi_wwan_state { + struct usb_driver *subdriver; + atomic_t pmcount; + unsigned long unused[3]; +}; + static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) { int status = -1; @@ -65,9 +72,11 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) struct usb_cdc_ether_desc *cdc_ether = NULL; u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; u32 found = 0; - atomic_t *pmcount = (void *)&dev->data[1]; + struct qmi_wwan_state *info = (void *)&dev->data; + + BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); - atomic_set(pmcount, 0); + atomic_set(&info->pmcount, 0); /* * assume a data interface has no additional descriptors and @@ -177,12 +186,12 @@ err: /* using a counter to merge subdriver requests with our own into a combined state */ static int qmi_wwan_manage_power(struct usbnet *dev, int on) { - atomic_t *pmcount = (void *)&dev->data[1]; + struct qmi_wwan_state *info = (void *)&dev->data; int rv = 0; - dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(pmcount), on); + dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); - if ((on && atomic_add_return(1, pmcount) == 1) || (!on && atomic_dec_and_test(pmcount))) { + if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { /* need autopm_get/put here to ensure the usbcore sees the new value */ rv = usb_autopm_get_interface(dev->intf); if (rv < 0) @@ -212,7 +221,7 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) { int rv; struct usb_driver *subdriver = NULL; - atomic_t *pmcount = (void *)&dev->data[1]; + struct qmi_wwan_state *info = (void *)&dev->data; /* ZTE makes devices where the interface descriptors and endpoint * configurations of two or more interfaces are identical, even @@ -228,7 +237,7 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) goto err; } - atomic_set(pmcount, 0); + atomic_set(&info->pmcount, 0); /* collect all three endpoints */ rv = usbnet_get_endpoints(dev, intf); @@ -251,7 +260,7 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) dev->status = NULL; /* save subdriver struct for suspend/resume wrappers */ - dev->data[0] = (unsigned long)subdriver; + info->subdriver = subdriver; err: return rv; @@ -282,12 +291,12 @@ err: static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) { - struct usb_driver *subdriver = (void *)dev->data[0]; + struct qmi_wwan_state *info = (void *)&dev->data; - if (subdriver && subdriver->disconnect) - subdriver->disconnect(intf); + if (info->subdriver && info->subdriver->disconnect) + info->subdriver->disconnect(intf); - dev->data[0] = (unsigned long)NULL; + info->subdriver = NULL; } /* suspend/resume wrappers calling both usbnet and the cdc-wdm @@ -299,15 +308,15 @@ static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *int static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) { struct usbnet *dev = usb_get_intfdata(intf); - struct usb_driver *subdriver = (void *)dev->data[0]; + struct qmi_wwan_state *info = (void *)&dev->data; int ret; ret = usbnet_suspend(intf, message); if (ret < 0) goto err; - if (subdriver && subdriver->suspend) - ret = subdriver->suspend(intf, message); + if (info->subdriver && info->subdriver->suspend) + ret = info->subdriver->suspend(intf, message); if (ret < 0) usbnet_resume(intf); err: @@ -317,16 +326,16 @@ err: static int qmi_wwan_resume(struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); - struct usb_driver *subdriver = (void *)dev->data[0]; + struct qmi_wwan_state *info = (void *)&dev->data; int ret = 0; - if (subdriver && subdriver->resume) - ret = subdriver->resume(intf); + if (info->subdriver && info->subdriver->resume) + ret = info->subdriver->resume(intf); if (ret < 0) goto err; ret = usbnet_resume(intf); - if (ret < 0 && subdriver && subdriver->resume && subdriver->suspend) - subdriver->suspend(intf, PMSG_SUSPEND); + if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) + info->subdriver->suspend(intf, PMSG_SUSPEND); err: return ret; } -- GitLab From f47cd1360f36e599815650522986673b9aa83393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 19 Jun 2012 00:42:00 +0000 Subject: [PATCH 2079/6849] net: qmi_wwan: rearranging to prepare for code sharing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of the subdriver registration code can be reused for devices with separate control and data interfaces. Move the code a bit around to prepare for such reuse. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 128 ++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 52 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c7b9be81ad08..6fcf54d43eab 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -58,9 +58,80 @@ struct qmi_wwan_state { struct usb_driver *subdriver; atomic_t pmcount; - unsigned long unused[3]; + unsigned long unused; + struct usb_interface *control; + struct usb_interface *data; }; +/* using a counter to merge subdriver requests with our own into a combined state */ +static int qmi_wwan_manage_power(struct usbnet *dev, int on) +{ + struct qmi_wwan_state *info = (void *)&dev->data; + int rv = 0; + + dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); + + if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { + /* need autopm_get/put here to ensure the usbcore sees the new value */ + rv = usb_autopm_get_interface(dev->intf); + if (rv < 0) + goto err; + dev->intf->needs_remote_wakeup = on; + usb_autopm_put_interface(dev->intf); + } +err: + return rv; +} + +static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) +{ + struct usbnet *dev = usb_get_intfdata(intf); + return qmi_wwan_manage_power(dev, on); +} + +/* collect all three endpoints and register subdriver */ +static int qmi_wwan_register_subdriver(struct usbnet *dev) +{ + int rv; + struct usb_driver *subdriver = NULL; + struct qmi_wwan_state *info = (void *)&dev->data; + + /* collect bulk endpoints */ + rv = usbnet_get_endpoints(dev, info->data); + if (rv < 0) + goto err; + + /* update status endpoint if separate control interface */ + if (info->control != info->data) + dev->status = &info->control->cur_altsetting->endpoint[0]; + + /* require interrupt endpoint for subdriver */ + if (!dev->status) { + rv = -EINVAL; + goto err; + } + + /* for subdriver power management */ + atomic_set(&info->pmcount, 0); + + /* register subdriver */ + subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, 512, &qmi_wwan_cdc_wdm_manage_power); + if (IS_ERR(subdriver)) { + dev_err(&info->control->dev, "subdriver registration failed\n"); + rv = PTR_ERR(subdriver); + goto err; + } + + /* prevent usbnet from using status endpoint */ + dev->status = NULL; + + /* save subdriver struct for suspend/resume wrappers */ + info->subdriver = subdriver; + +err: + return rv; +} + static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) { int status = -1; @@ -183,32 +254,6 @@ err: return status; } -/* using a counter to merge subdriver requests with our own into a combined state */ -static int qmi_wwan_manage_power(struct usbnet *dev, int on) -{ - struct qmi_wwan_state *info = (void *)&dev->data; - int rv = 0; - - dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); - - if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { - /* need autopm_get/put here to ensure the usbcore sees the new value */ - rv = usb_autopm_get_interface(dev->intf); - if (rv < 0) - goto err; - dev->intf->needs_remote_wakeup = on; - usb_autopm_put_interface(dev->intf); - } -err: - return rv; -} - -static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) -{ - struct usbnet *dev = usb_get_intfdata(intf); - return qmi_wwan_manage_power(dev, on); -} - /* Some devices combine the "control" and "data" functions into a * single interface with all three endpoints: interrupt + bulk in and * out @@ -220,7 +265,6 @@ static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) { int rv; - struct usb_driver *subdriver = NULL; struct qmi_wwan_state *info = (void *)&dev->data; /* ZTE makes devices where the interface descriptors and endpoint @@ -237,30 +281,10 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) goto err; } - atomic_set(&info->pmcount, 0); - - /* collect all three endpoints */ - rv = usbnet_get_endpoints(dev, intf); - if (rv < 0) - goto err; - - /* require interrupt endpoint for subdriver */ - if (!dev->status) { - rv = -EINVAL; - goto err; - } - - subdriver = usb_cdc_wdm_register(intf, &dev->status->desc, 512, &qmi_wwan_cdc_wdm_manage_power); - if (IS_ERR(subdriver)) { - rv = PTR_ERR(subdriver); - goto err; - } - - /* can't let usbnet use the interrupt endpoint */ - dev->status = NULL; - - /* save subdriver struct for suspend/resume wrappers */ - info->subdriver = subdriver; + /* control and data is shared */ + info->control = intf; + info->data = intf; + rv = qmi_wwan_register_subdriver(dev); err: return rv; -- GitLab From 230718bda1be24119d9e25623d90fa5da3079aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 19 Jun 2012 00:42:01 +0000 Subject: [PATCH 2080/6849] net: qmi_wwan: bind to both control and data interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always bind to control interface regardless of whether it is a shared interface or not. A QMI/wwan function is required to provide both a control interface (QMI) and a data interface (wwan). All devices supported by this driver do so. But the vendors may choose to use different USB descriptor layouts, and some vendors even allow the same device to present different layouts. Most of these devices use a USB descriptor layout with a single USB interface for both control and data. But some split control and data into two interfaces, bound together by a CDC Union descriptor on the control interface. Before the cdc-wdm subdriver support was added, this split was used to let cdc-wdm drive the QMI control interface and qmi_wwan drive the wwna data interface. This split driver model has a number of issues: - qmi_wwan must match on the data interface descriptor, which often are indistiguishable from data interfaces belonging to other CDC (like) functions like ACM - supporting a single QMI/wwan function requires adding the device to two drivers - syncronizing the probes among a number of drivers, to ensure selecting the correct driver, is difficult unless all drivers match on the same interface This patch resolves these problems by using the same probing mechanism as cdc-ether for devices with a two- interface USB descriptor layout. This makes the driver behave consistently, supporting both the control and data part of the QMI/wwan function, regardless of the USB descriptors. Cc: Thomas Schäfer Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 131 ++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 68 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 6fcf54d43eab..05571fcbd70a 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1,6 +1,10 @@ /* * Copyright (c) 2012 Bjørn Mork * + * The probing code is heavily inspired by cdc_ether, which is: + * Copyright (C) 2003-2005 by David Brownell + * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -15,11 +19,7 @@ #include #include -/* The name of the CDC Device Management driver */ -#define DM_DRIVER "cdc_wdm" - -/* - * This driver supports wwan (3G/LTE/?) devices using a vendor +/* This driver supports wwan (3G/LTE/?) devices using a vendor * specific management protocol called Qualcomm MSM Interface (QMI) - * in addition to the more common AT commands over serial interface * management @@ -31,27 +31,16 @@ * management protocol is used in place of the standard CDC * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE * + * Alternatively, control and data functions can be combined in a + * single USB interface. + * * Handling a protocol like QMI is out of the scope for any driver. - * It can be exported as a character device using the cdc-wdm driver, - * which will enable userspace applications ("modem managers") to - * handle it. This may be required to use the network interface - * provided by the driver. + * It is exported as a character device using the cdc-wdm driver as + * a subdriver, enabling userspace applications ("modem managers") to + * handle it. * * These devices may alternatively/additionally be configured using AT - * commands on any of the serial interfaces driven by the option driver - * - * This driver binds only to the data ("slave") interface to enable - * the cdc-wdm driver to bind to the control interface. It still - * parses the CDC functional descriptors on the control interface to - * a) verify that this is indeed a handled interface (CDC Union - * header lists it as slave) - * b) get MAC address and other ethernet config from the CDC Ethernet - * header - * c) enable user bind requests against the control interface, which - * is the common way to bind to CDC Ethernet Control Model type - * interfaces - * d) provide a hint to the user about which interface is the - * corresponding management interface + * commands on a serial interface */ /* driver specific data */ @@ -135,7 +124,6 @@ err: static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) { int status = -1; - struct usb_interface *control = NULL; u8 *buf = intf->cur_altsetting->extra; int len = intf->cur_altsetting->extralen; struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; @@ -143,27 +131,14 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) struct usb_cdc_ether_desc *cdc_ether = NULL; u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; u32 found = 0; + struct usb_driver *driver = driver_of(intf); struct qmi_wwan_state *info = (void *)&dev->data; BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); - atomic_set(&info->pmcount, 0); - - /* - * assume a data interface has no additional descriptors and - * that the control and data interface are numbered - * consecutively - this holds for the Huawei device at least - */ - if (len == 0 && desc->bInterfaceNumber > 0) { - control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1); - if (!control) - goto err; - - buf = control->cur_altsetting->extra; - len = control->cur_altsetting->extralen; - dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n", - dev_name(&control->dev)); - } + /* require a single interrupt status endpoint for subdriver */ + if (intf->cur_altsetting->desc.bNumEndpoints != 1) + goto err; while (len > 3) { struct usb_descriptor_header *h = (void *)buf; @@ -227,10 +202,17 @@ next_desc: goto err; } - /* give the user a helpful hint if trying to bind to the wrong interface */ - if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) { - dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n", - dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev)); + /* verify CDC Union */ + if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) { + dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0); + goto err; + } + + /* need to save these for unbind */ + info->control = intf; + info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); + if (!info->data) { + dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0); goto err; } @@ -240,15 +222,16 @@ next_desc: usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress); } - /* success! point the user to the management interface */ - if (control) - dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n", - dev_name(&control->dev)); - - /* XXX: add a sysfs symlink somewhere to help management applications find it? */ + /* claim data interface and set it up */ + status = usb_driver_claim_interface(driver, info->data, dev); + if (status < 0) + goto err; - /* collect bulk endpoints now that we know intf == "data" interface */ - status = usbnet_get_endpoints(dev, intf); + status = qmi_wwan_register_subdriver(dev); + if (status < 0) { + usb_set_intfdata(info->data, NULL); + usb_driver_release_interface(driver, info->data); + } err: return status; @@ -257,11 +240,7 @@ err: /* Some devices combine the "control" and "data" functions into a * single interface with all three endpoints: interrupt + bulk in and * out - * - * Setting up cdc-wdm as a subdriver owning the interrupt endpoint - * will let it provide userspace access to the encapsulated QMI - * protocol without interfering with the usbnet operations. - */ + */ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) { int rv; @@ -313,14 +292,30 @@ err: return rv; } -static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) +static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) { struct qmi_wwan_state *info = (void *)&dev->data; + struct usb_driver *driver = driver_of(intf); + struct usb_interface *other; if (info->subdriver && info->subdriver->disconnect) - info->subdriver->disconnect(intf); + info->subdriver->disconnect(info->control); + + /* allow user to unbind using either control or data */ + if (intf == info->control) + other = info->data; + else + other = info->control; + + /* only if not shared */ + if (other && intf != other) { + usb_set_intfdata(other, NULL); + usb_driver_release_interface(driver, other); + } info->subdriver = NULL; + info->data = NULL; + info->control = NULL; } /* suspend/resume wrappers calling both usbnet and the cdc-wdm @@ -364,11 +359,11 @@ err: return ret; } - static const struct driver_info qmi_wwan_info = { .description = "QMI speaking wwan device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind, + .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, }; @@ -376,7 +371,7 @@ static const struct driver_info qmi_wwan_shared = { .description = "QMI speaking wwan device with combined interface", .flags = FLAG_WWAN, .bind = qmi_wwan_bind_shared, - .unbind = qmi_wwan_unbind_shared, + .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, }; @@ -384,7 +379,7 @@ static const struct driver_info qmi_wwan_gobi = { .description = "Qualcomm Gobi wwan/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind_gobi, - .unbind = qmi_wwan_unbind_shared, + .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, }; @@ -393,7 +388,7 @@ static const struct driver_info qmi_wwan_force_int1 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind_shared, - .unbind = qmi_wwan_unbind_shared, + .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, .data = BIT(1), /* interface whitelist bitmap */ }; @@ -402,7 +397,7 @@ static const struct driver_info qmi_wwan_force_int4 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind_shared, - .unbind = qmi_wwan_unbind_shared, + .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, .data = BIT(4), /* interface whitelist bitmap */ }; @@ -424,7 +419,7 @@ static const struct driver_info qmi_wwan_sierra = { .description = "Sierra Wireless wwan/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind_gobi, - .unbind = qmi_wwan_unbind_shared, + .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ }; @@ -440,7 +435,7 @@ static const struct usb_device_id products[] = { .idVendor = HUAWEI_VENDOR_ID, .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, - .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ + .bInterfaceProtocol = 9, /* CDC Ethernet *control* interface */ .driver_info = (unsigned long)&qmi_wwan_info, }, { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ @@ -448,7 +443,7 @@ static const struct usb_device_id products[] = { .idVendor = HUAWEI_VENDOR_ID, .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, - .bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */ + .bInterfaceProtocol = 57, /* CDC Ethernet *control* interface */ .driver_info = (unsigned long)&qmi_wwan_info, }, { /* Huawei E392, E398 and possibly others in "Windows mode" -- GitLab From a40345b5b4a09ff8539aaafeb2c612db6d0b4d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 19 Jun 2012 00:42:02 +0000 Subject: [PATCH 2081/6849] net: qmi_wwan: shorten driver description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The description is used in ethtool fixed length fields. Make it shorter to avoid truncation. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 05571fcbd70a..f12ba3c2134c 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -360,7 +360,7 @@ err: } static const struct driver_info qmi_wwan_info = { - .description = "QMI speaking wwan device", + .description = "WWAN/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, @@ -368,7 +368,7 @@ static const struct driver_info qmi_wwan_info = { }; static const struct driver_info qmi_wwan_shared = { - .description = "QMI speaking wwan device with combined interface", + .description = "WWAN/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind, -- GitLab From 677a3d60fb3153f786a0d28fcf0287670e7bd3c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 19 Jun 2012 00:42:03 +0000 Subject: [PATCH 2082/6849] net: qmi_wwan: use module_usb_driver macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index f12ba3c2134c..f1e779135899 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -593,17 +593,7 @@ static struct usb_driver qmi_wwan_driver = { .disable_hub_initiated_lpm = 1, }; -static int __init qmi_wwan_init(void) -{ - return usb_register(&qmi_wwan_driver); -} -module_init(qmi_wwan_init); - -static void __exit qmi_wwan_exit(void) -{ - usb_deregister(&qmi_wwan_driver); -} -module_exit(qmi_wwan_exit); +module_usb_driver(qmi_wwan_driver); MODULE_AUTHOR("Bjørn Mork "); MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver"); -- GitLab From af8b5fc31099abd7f3b297332c9e280ec0b30a71 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Tue, 19 Jun 2012 07:08:22 +0000 Subject: [PATCH 2083/6849] regulator: add new regulator driver for lp872x This driver supports TI/National LP8720, LP8725 PMIC. Signed-off-by: Milo(Woogyom) Kim Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 7 + drivers/regulator/Makefile | 1 + drivers/regulator/lp872x.c | 957 +++++++++++++++++++++++++++++++ include/linux/regulator/lp872x.h | 90 +++ 4 files changed, 1055 insertions(+) create mode 100644 drivers/regulator/lp872x.c create mode 100644 include/linux/regulator/lp872x.h diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 00ffe05d8026..870f7300b156 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -224,6 +224,13 @@ config REGULATOR_LP3972 Say Y here to support the voltage regulators and convertors on National Semiconductors LP3972 PMIC +config REGULATOR_LP872X + tristate "TI/National Semiconductor LP8720/LP8725 voltage regulators" + depends on I2C + select REGMAP_I2C + help + This driver supports LP8720/LP8725 PMIC + config REGULATOR_PCF50633 tristate "NXP PCF50633 regulator driver" depends on MFD_PCF50633 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index d8544539efec..e6f700748a3b 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o +obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c new file mode 100644 index 000000000000..d51d09852041 --- /dev/null +++ b/drivers/regulator/lp872x.c @@ -0,0 +1,957 @@ +/* + * Copyright 2012 Texas Instruments + * + * Author: Milo(Woogyom) Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers : LP8720/8725 shared */ +#define LP872X_GENERAL_CFG 0x00 +#define LP872X_LDO1_VOUT 0x01 +#define LP872X_LDO2_VOUT 0x02 +#define LP872X_LDO3_VOUT 0x03 +#define LP872X_LDO4_VOUT 0x04 +#define LP872X_LDO5_VOUT 0x05 + +/* Registers : LP8720 */ +#define LP8720_BUCK_VOUT1 0x06 +#define LP8720_BUCK_VOUT2 0x07 +#define LP8720_ENABLE 0x08 + +/* Registers : LP8725 */ +#define LP8725_LILO1_VOUT 0x06 +#define LP8725_LILO2_VOUT 0x07 +#define LP8725_BUCK1_VOUT1 0x08 +#define LP8725_BUCK1_VOUT2 0x09 +#define LP8725_BUCK2_VOUT1 0x0A +#define LP8725_BUCK2_VOUT2 0x0B +#define LP8725_BUCK_CTRL 0x0C +#define LP8725_LDO_CTRL 0x0D + +/* Mask/shift : LP8720/LP8725 shared */ +#define LP872X_VOUT_M 0x1F +#define LP872X_START_DELAY_M 0xE0 +#define LP872X_START_DELAY_S 5 +#define LP872X_EN_LDO1_M BIT(0) +#define LP872X_EN_LDO2_M BIT(1) +#define LP872X_EN_LDO3_M BIT(2) +#define LP872X_EN_LDO4_M BIT(3) +#define LP872X_EN_LDO5_M BIT(4) + +/* Mask/shift : LP8720 */ +#define LP8720_TIMESTEP_S 0 /* Addr 00h */ +#define LP8720_TIMESTEP_M BIT(0) +#define LP8720_EXT_DVS_M BIT(2) +#define LP8720_BUCK_FPWM_S 5 /* Addr 07h */ +#define LP8720_BUCK_FPWM_M BIT(5) +#define LP8720_EN_BUCK_M BIT(5) /* Addr 08h */ +#define LP8720_DVS_SEL_M BIT(7) + +/* Mask/shift : LP8725 */ +#define LP8725_TIMESTEP_M 0xC0 /* Addr 00h */ +#define LP8725_TIMESTEP_S 6 +#define LP8725_BUCK1_EN_M BIT(0) +#define LP8725_DVS1_M BIT(2) +#define LP8725_DVS2_M BIT(3) +#define LP8725_BUCK2_EN_M BIT(4) +#define LP8725_BUCK_CL_M 0xC0 /* Addr 09h, 0Bh */ +#define LP8725_BUCK_CL_S 6 +#define LP8725_BUCK1_FPWM_S 1 /* Addr 0Ch */ +#define LP8725_BUCK1_FPWM_M BIT(1) +#define LP8725_BUCK2_FPWM_S 5 +#define LP8725_BUCK2_FPWM_M BIT(5) +#define LP8725_EN_LILO1_M BIT(5) /* Addr 0Dh */ +#define LP8725_EN_LILO2_M BIT(6) + +/* PWM mode */ +#define LP872X_FORCE_PWM 1 +#define LP872X_AUTO_PWM 0 + +#define LP8720_NUM_REGULATORS 6 +#define LP8725_NUM_REGULATORS 9 +#define EXTERN_DVS_USED 0 +#define MAX_DELAY 6 + +/* dump registers in regmap-debugfs */ +#define MAX_REGISTERS 0x0F + +enum lp872x_id { + LP8720, + LP8725, +}; + +struct lp872x { + struct regmap *regmap; + struct device *dev; + enum lp872x_id chipid; + struct lp872x_platform_data *pdata; + struct regulator_dev **regulators; + int num_regulators; + enum lp872x_dvs_state dvs_pin; + int dvs_gpio; +}; + +/* LP8720/LP8725 shared voltage table for LDOs */ +static const unsigned int lp872x_ldo_vtbl[] = { + 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 2000000, + 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2650000, 2700000, + 2750000, 2800000, 2850000, 2900000, 2950000, 3000000, 3100000, 3300000, +}; + +/* LP8720 LDO4 voltage table */ +static const unsigned int lp8720_ldo4_vtbl[] = { + 800000, 850000, 900000, 1000000, 1100000, 1200000, 1250000, 1300000, + 1350000, 1400000, 1450000, 1500000, 1550000, 1600000, 1650000, 1700000, + 1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000, + 2400000, 2500000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, +}; + +/* LP8725 LILO(Low Input Low Output) voltage table */ +static const unsigned int lp8725_lilo_vtbl[] = { + 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, + 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000, + 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, + 2600000, 2700000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000, +}; + +/* LP8720 BUCK voltage table */ +#define EXT_R 0 /* external resistor divider */ +static const unsigned int lp8720_buck_vtbl[] = { + EXT_R, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, + 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, + 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, + 1950000, 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, +}; + +/* LP8725 BUCK voltage table */ +static const unsigned int lp8725_buck_vtbl[] = { + 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, + 1200000, 1250000, 1300000, 1350000, 1400000, 1500000, 1600000, 1700000, + 1750000, 1800000, 1850000, 1900000, 2000000, 2100000, 2200000, 2300000, + 2400000, 2500000, 2600000, 2700000, 2800000, 2850000, 2900000, 3000000, +}; + +/* LP8725 BUCK current limit */ +static const unsigned int lp8725_buck_uA[] = { + 460000, 780000, 1050000, 1370000, +}; + +static int lp872x_read_byte(struct lp872x *lp, u8 addr, u8 *data) +{ + int ret; + unsigned int val; + + ret = regmap_read(lp->regmap, addr, &val); + if (ret < 0) { + dev_err(lp->dev, "failed to read 0x%.2x\n", addr); + return ret; + } + + *data = (u8)val; + return 0; +} + +static inline int lp872x_write_byte(struct lp872x *lp, u8 addr, u8 data) +{ + return regmap_write(lp->regmap, addr, data); +} + +static inline int lp872x_update_bits(struct lp872x *lp, u8 addr, + unsigned int mask, u8 data) +{ + return regmap_update_bits(lp->regmap, addr, mask, data); +} + +static int _rdev_to_offset(struct regulator_dev *rdev) +{ + enum lp872x_regulator_id id = rdev_get_id(rdev); + + switch (id) { + case LP8720_ID_LDO1 ... LP8720_ID_BUCK: + return id; + case LP8725_ID_LDO1 ... LP8725_ID_BUCK2: + return id - LP8725_ID_BASE; + default: + return -EINVAL; + } +} + +static int lp872x_get_timestep_usec(struct lp872x *lp) +{ + enum lp872x_id chip = lp->chipid; + u8 val, mask, shift; + int *time_usec, size, ret; + int lp8720_time_usec[] = { 25, 50 }; + int lp8725_time_usec[] = { 32, 64, 128, 256 }; + + switch (chip) { + case LP8720: + mask = LP8720_TIMESTEP_M; + shift = LP8720_TIMESTEP_S; + time_usec = &lp8720_time_usec[0]; + size = ARRAY_SIZE(lp8720_time_usec); + break; + case LP8725: + mask = LP8725_TIMESTEP_M; + shift = LP8725_TIMESTEP_S; + time_usec = &lp8725_time_usec[0]; + size = ARRAY_SIZE(lp8725_time_usec); + break; + default: + return -EINVAL; + } + + ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); + if (ret) + return -EINVAL; + + val = (val & mask) >> shift; + if (val >= size) + return -EINVAL; + + return *(time_usec + val); +} + +static int lp872x_regulator_enable_time(struct regulator_dev *rdev) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id regulator = rdev_get_id(rdev); + int time_step_us = lp872x_get_timestep_usec(lp); + int ret, offset; + u8 addr, val; + + if (time_step_us < 0) + return -EINVAL; + + switch (regulator) { + case LP8720_ID_LDO1 ... LP8720_ID_LDO5: + case LP8725_ID_LDO1 ... LP8725_ID_LILO2: + offset = _rdev_to_offset(rdev); + if (offset < 0) + return -EINVAL; + + addr = LP872X_LDO1_VOUT + offset; + break; + case LP8720_ID_BUCK: + addr = LP8720_BUCK_VOUT1; + break; + case LP8725_ID_BUCK1: + addr = LP8725_BUCK1_VOUT1; + break; + case LP8725_ID_BUCK2: + addr = LP8725_BUCK2_VOUT1; + break; + default: + return -EINVAL; + } + + ret = lp872x_read_byte(lp, addr, &val); + if (ret) + return ret; + + val = (val & LP872X_START_DELAY_M) >> LP872X_START_DELAY_S; + + return val > MAX_DELAY ? 0 : val * time_step_us; +} + +static void lp872x_set_dvs(struct lp872x *lp, int gpio) +{ + enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel; + enum lp872x_dvs_state state; + + state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW; + gpio_set_value(gpio, state); + lp->dvs_pin = state; +} + +static u8 lp872x_select_buck_vout_addr(struct lp872x *lp, + enum lp872x_regulator_id buck) +{ + u8 val, addr; + + if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val)) + return 0; + + switch (buck) { + case LP8720_ID_BUCK: + if (val & LP8720_EXT_DVS_M) { + addr = (lp->dvs_pin == DVS_HIGH) ? + LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; + } else { + if (lp872x_read_byte(lp, LP8720_ENABLE, &val)) + return 0; + + addr = val & LP8720_DVS_SEL_M ? + LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; + } + break; + case LP8725_ID_BUCK1: + if (val & LP8725_DVS1_M) + addr = LP8725_BUCK1_VOUT1; + else + addr = (lp->dvs_pin == DVS_HIGH) ? + LP8725_BUCK1_VOUT1 : LP8725_BUCK1_VOUT2; + break; + case LP8725_ID_BUCK2: + addr = val & LP8725_DVS2_M ? + LP8725_BUCK2_VOUT1 : LP8725_BUCK2_VOUT2; + break; + default: + return 0; + } + + return addr; +} + +static bool lp872x_is_valid_buck_addr(u8 addr) +{ + switch (addr) { + case LP8720_BUCK_VOUT1: + case LP8720_BUCK_VOUT2: + case LP8725_BUCK1_VOUT1: + case LP8725_BUCK1_VOUT2: + case LP8725_BUCK2_VOUT1: + case LP8725_BUCK2_VOUT2: + return true; + default: + return false; + } +} + +static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev, + unsigned selector) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id buck = rdev_get_id(rdev); + u8 addr, mask = LP872X_VOUT_M; + struct lp872x_dvs *dvs = lp->pdata->dvs; + + if (dvs && gpio_is_valid(dvs->gpio)) + lp872x_set_dvs(lp, dvs->gpio); + + addr = lp872x_select_buck_vout_addr(lp, buck); + if (!lp872x_is_valid_buck_addr(addr)) + return -EINVAL; + + return lp872x_update_bits(lp, addr, mask, selector); +} + +static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id buck = rdev_get_id(rdev); + u8 addr, val; + int ret; + + addr = lp872x_select_buck_vout_addr(lp, buck); + if (!lp872x_is_valid_buck_addr(addr)) + return -EINVAL; + + ret = lp872x_read_byte(lp, addr, &val); + if (ret) + return ret; + + return val & LP872X_VOUT_M; +} + +static int lp8725_buck_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id buck = rdev_get_id(rdev); + int i, max = ARRAY_SIZE(lp8725_buck_uA); + u8 addr, val; + + switch (buck) { + case LP8725_ID_BUCK1: + addr = LP8725_BUCK1_VOUT2; + break; + case LP8725_ID_BUCK2: + addr = LP8725_BUCK2_VOUT2; + break; + default: + return -EINVAL; + } + + for (i = 0 ; i < max ; i++) + if (lp8725_buck_uA[i] >= min_uA && + lp8725_buck_uA[i] <= max_uA) + break; + + if (i == max) + return -EINVAL; + + val = i << LP8725_BUCK_CL_S; + + return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val); +} + +static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id buck = rdev_get_id(rdev); + u8 addr, val; + int ret; + + switch (buck) { + case LP8725_ID_BUCK1: + addr = LP8725_BUCK1_VOUT2; + break; + case LP8725_ID_BUCK2: + addr = LP8725_BUCK2_VOUT2; + break; + default: + return -EINVAL; + } + + ret = lp872x_read_byte(lp, addr, &val); + if (ret) + return ret; + + val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S; + + return (val < ARRAY_SIZE(lp8725_buck_uA)) ? + lp8725_buck_uA[val] : -EINVAL; +} + +static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id buck = rdev_get_id(rdev); + u8 addr, mask, shift, val; + + switch (buck) { + case LP8720_ID_BUCK: + addr = LP8720_BUCK_VOUT2; + mask = LP8720_BUCK_FPWM_M; + shift = LP8720_BUCK_FPWM_S; + break; + case LP8725_ID_BUCK1: + addr = LP8725_BUCK_CTRL; + mask = LP8725_BUCK1_FPWM_M; + shift = LP8725_BUCK1_FPWM_S; + break; + case LP8725_ID_BUCK2: + addr = LP8725_BUCK_CTRL; + mask = LP8725_BUCK2_FPWM_M; + shift = LP8725_BUCK2_FPWM_S; + break; + default: + return -EINVAL; + } + + if (mode == REGULATOR_MODE_FAST) + val = LP872X_FORCE_PWM << shift; + else if (mode == REGULATOR_MODE_NORMAL) + val = LP872X_AUTO_PWM << shift; + else + return -EINVAL; + + return lp872x_update_bits(lp, addr, mask, val); +} + +static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) +{ + struct lp872x *lp = rdev_get_drvdata(rdev); + enum lp872x_regulator_id buck = rdev_get_id(rdev); + u8 addr, mask, val; + int ret; + + switch (buck) { + case LP8720_ID_BUCK: + addr = LP8720_BUCK_VOUT2; + mask = LP8720_BUCK_FPWM_M; + break; + case LP8725_ID_BUCK1: + addr = LP8725_BUCK_CTRL; + mask = LP8725_BUCK1_FPWM_M; + break; + case LP8725_ID_BUCK2: + addr = LP8725_BUCK_CTRL; + mask = LP8725_BUCK2_FPWM_M; + break; + default: + return -EINVAL; + } + + ret = lp872x_read_byte(lp, addr, &val); + if (ret) + return ret; + + return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; +} + +static struct regulator_ops lp872x_ldo_ops = { + .list_voltage = regulator_list_voltage_table, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .enable_time = lp872x_regulator_enable_time, +}; + +static struct regulator_ops lp8720_buck_ops = { + .list_voltage = regulator_list_voltage_table, + .set_voltage_sel = lp872x_buck_set_voltage_sel, + .get_voltage_sel = lp872x_buck_get_voltage_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .enable_time = lp872x_regulator_enable_time, + .set_mode = lp872x_buck_set_mode, + .get_mode = lp872x_buck_get_mode, +}; + +static struct regulator_ops lp8725_buck_ops = { + .list_voltage = regulator_list_voltage_table, + .set_voltage_sel = lp872x_buck_set_voltage_sel, + .get_voltage_sel = lp872x_buck_get_voltage_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .enable_time = lp872x_regulator_enable_time, + .set_mode = lp872x_buck_set_mode, + .get_mode = lp872x_buck_get_mode, + .set_current_limit = lp8725_buck_set_current_limit, + .get_current_limit = lp8725_buck_get_current_limit, +}; + +static struct regulator_desc lp8720_regulator_desc[] = { + { + .name = "ldo1", + .id = LP8720_ID_LDO1, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO1_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8720_ENABLE, + .enable_mask = LP872X_EN_LDO1_M, + }, + { + .name = "ldo2", + .id = LP8720_ID_LDO2, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO2_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8720_ENABLE, + .enable_mask = LP872X_EN_LDO2_M, + }, + { + .name = "ldo3", + .id = LP8720_ID_LDO3, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO3_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8720_ENABLE, + .enable_mask = LP872X_EN_LDO3_M, + }, + { + .name = "ldo4", + .id = LP8720_ID_LDO4, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), + .volt_table = lp8720_ldo4_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO4_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8720_ENABLE, + .enable_mask = LP872X_EN_LDO4_M, + }, + { + .name = "ldo5", + .id = LP8720_ID_LDO5, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO5_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8720_ENABLE, + .enable_mask = LP872X_EN_LDO5_M, + }, + { + .name = "buck", + .id = LP8720_ID_BUCK, + .ops = &lp8720_buck_ops, + .n_voltages = ARRAY_SIZE(lp8720_buck_vtbl), + .volt_table = lp8720_buck_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .enable_reg = LP8720_ENABLE, + .enable_mask = LP8720_EN_BUCK_M, + }, +}; + +static struct regulator_desc lp8725_regulator_desc[] = { + { + .name = "ldo1", + .id = LP8725_ID_LDO1, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO1_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP872X_EN_LDO1_M, + }, + { + .name = "ldo2", + .id = LP8725_ID_LDO2, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO2_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP872X_EN_LDO2_M, + }, + { + .name = "ldo3", + .id = LP8725_ID_LDO3, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO3_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP872X_EN_LDO3_M, + }, + { + .name = "ldo4", + .id = LP8725_ID_LDO4, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO4_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP872X_EN_LDO4_M, + }, + { + .name = "ldo5", + .id = LP8725_ID_LDO5, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), + .volt_table = lp872x_ldo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP872X_LDO5_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP872X_EN_LDO5_M, + }, + { + .name = "lilo1", + .id = LP8725_ID_LILO1, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), + .volt_table = lp8725_lilo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP8725_LILO1_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP8725_EN_LILO1_M, + }, + { + .name = "lilo2", + .id = LP8725_ID_LILO2, + .ops = &lp872x_ldo_ops, + .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), + .volt_table = lp8725_lilo_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LP8725_LILO2_VOUT, + .vsel_mask = LP872X_VOUT_M, + .enable_reg = LP8725_LDO_CTRL, + .enable_mask = LP8725_EN_LILO2_M, + }, + { + .name = "buck1", + .id = LP8725_ID_BUCK1, + .ops = &lp8725_buck_ops, + .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), + .volt_table = lp8725_buck_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .enable_reg = LP872X_GENERAL_CFG, + .enable_mask = LP8725_BUCK1_EN_M, + }, + { + .name = "buck2", + .id = LP8725_ID_BUCK2, + .ops = &lp8725_buck_ops, + .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), + .volt_table = lp8725_buck_vtbl, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .enable_reg = LP872X_GENERAL_CFG, + .enable_mask = LP8725_BUCK2_EN_M, + }, +}; + +static int lp872x_check_dvs_validity(struct lp872x *lp) +{ + struct lp872x_dvs *dvs = lp->pdata->dvs; + u8 val = 0; + int ret; + + ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); + if (ret) + return ret; + + ret = 0; + if (lp->chipid == LP8720) { + if (val & LP8720_EXT_DVS_M) + ret = dvs ? 0 : -EINVAL; + } else { + if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED) + ret = dvs ? 0 : -EINVAL; + } + + return ret; +} + +static int lp872x_init_dvs(struct lp872x *lp) +{ + int ret, gpio; + struct lp872x_dvs *dvs = lp->pdata->dvs; + enum lp872x_dvs_state pinstate; + + ret = lp872x_check_dvs_validity(lp); + if (ret) { + dev_warn(lp->dev, "invalid dvs data: %d\n", ret); + return ret; + } + + gpio = dvs->gpio; + if (!gpio_is_valid(gpio)) { + dev_err(lp->dev, "invalid gpio: %d\n", gpio); + return -EINVAL; + } + + pinstate = dvs->init_state; + ret = devm_gpio_request_one(lp->dev, gpio, pinstate, "LP872X DVS"); + if (ret) { + dev_err(lp->dev, "gpio request err: %d\n", ret); + return ret; + } + + lp->dvs_pin = pinstate; + lp->dvs_gpio = gpio; + + return 0; +} + +static int lp872x_config(struct lp872x *lp) +{ + struct lp872x_platform_data *pdata = lp->pdata; + int ret; + + if (!pdata) { + dev_warn(lp->dev, "no platform data\n"); + return 0; + } + + if (!pdata->update_config) + return 0; + + ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config); + if (ret) + return ret; + + return lp872x_init_dvs(lp); +} + +static struct regulator_init_data +*lp872x_find_regulator_init_data(int idx, struct lp872x *lp) +{ + int i, base, id, max_regulators; + + switch (lp->chipid) { + case LP8720: + base = LP8720_ID_BASE; + max_regulators = LP8720_NUM_REGULATORS; + break; + case LP8725: + base = LP8725_ID_BASE; + max_regulators = LP8725_NUM_REGULATORS; + break; + default: + return NULL; + } + + id = base + idx; + for (i = 0 ; i < max_regulators ; i++) + if (lp->pdata->regulator_data[i].id == id) + break; + + return (i == max_regulators) ? NULL : + lp->pdata->regulator_data[i].init_data; +} + +static int lp872x_regulator_register(struct lp872x *lp) +{ + struct regulator_desc *desc; + struct regulator_config cfg = { }; + struct regulator_dev *rdev; + int i, ret; + + for (i = 0 ; i < lp->num_regulators ; i++) { + desc = (lp->chipid == LP8720) ? &lp8720_regulator_desc[i] : + &lp8725_regulator_desc[i]; + + cfg.dev = lp->dev; + cfg.init_data = lp872x_find_regulator_init_data(i, lp); + cfg.driver_data = lp; + cfg.regmap = lp->regmap; + + rdev = regulator_register(desc, &cfg); + if (IS_ERR(rdev)) { + dev_err(lp->dev, "regulator register err"); + ret = PTR_ERR(rdev); + goto err; + } + + *(lp->regulators + i) = rdev; + } + + return 0; +err: + while (--i >= 0) { + rdev = *(lp->regulators + i); + regulator_unregister(rdev); + } + return ret; +} + +static void lp872x_regulator_unregister(struct lp872x *lp) +{ + struct regulator_dev *rdev; + int i; + + for (i = 0 ; i < lp->num_regulators ; i++) { + rdev = *(lp->regulators + i); + regulator_unregister(rdev); + } +} + +static const struct regmap_config lp872x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX_REGISTERS, +}; + +static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) +{ + struct lp872x *lp; + struct lp872x_platform_data *pdata = cl->dev.platform_data; + int ret, size, num_regulators; + const int lp872x_num_regulators[] = { + [LP8720] = LP8720_NUM_REGULATORS, + [LP8725] = LP8725_NUM_REGULATORS, + }; + + lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); + if (!lp) + goto err_mem; + + num_regulators = lp872x_num_regulators[id->driver_data]; + size = sizeof(struct regulator_dev *) * num_regulators; + + lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL); + if (!lp->regulators) + goto err_mem; + + lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); + if (IS_ERR(lp->regmap)) { + ret = PTR_ERR(lp->regmap); + dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); + goto err_dev; + } + + lp->dev = &cl->dev; + lp->pdata = pdata; + lp->chipid = id->driver_data; + lp->num_regulators = num_regulators; + i2c_set_clientdata(cl, lp); + + ret = lp872x_config(lp); + if (ret) + goto err_dev; + + return lp872x_regulator_register(lp); + +err_mem: + return -ENOMEM; +err_dev: + return ret; +} + +static int __devexit lp872x_remove(struct i2c_client *cl) +{ + struct lp872x *lp = i2c_get_clientdata(cl); + + lp872x_regulator_unregister(lp); + return 0; +} + +static const struct i2c_device_id lp872x_ids[] = { + {"lp8720", LP8720}, + {"lp8725", LP8725}, + { } +}; +MODULE_DEVICE_TABLE(i2c, lp872x_ids); + +static struct i2c_driver lp872x_driver = { + .driver = { + .name = "lp872x", + .owner = THIS_MODULE, + }, + .probe = lp872x_probe, + .remove = __devexit_p(lp872x_remove), + .id_table = lp872x_ids, +}; + +module_i2c_driver(lp872x_driver); + +MODULE_DESCRIPTION("TI/National Semiconductor LP872x PMU Regulator Driver"); +MODULE_AUTHOR("Milo Kim"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/regulator/lp872x.h b/include/linux/regulator/lp872x.h new file mode 100644 index 000000000000..132e05c46661 --- /dev/null +++ b/include/linux/regulator/lp872x.h @@ -0,0 +1,90 @@ +/* + * Copyright 2012 Texas Instruments + * + * Author: Milo(Woogyom) Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __LP872X_REGULATOR_H__ +#define __LP872X_REGULATOR_H__ + +#include +#include +#include + +#define LP872X_MAX_REGULATORS 9 + +enum lp872x_regulator_id { + LP8720_ID_BASE, + LP8720_ID_LDO1 = LP8720_ID_BASE, + LP8720_ID_LDO2, + LP8720_ID_LDO3, + LP8720_ID_LDO4, + LP8720_ID_LDO5, + LP8720_ID_BUCK, + + LP8725_ID_BASE, + LP8725_ID_LDO1 = LP8725_ID_BASE, + LP8725_ID_LDO2, + LP8725_ID_LDO3, + LP8725_ID_LDO4, + LP8725_ID_LDO5, + LP8725_ID_LILO1, + LP8725_ID_LILO2, + LP8725_ID_BUCK1, + LP8725_ID_BUCK2, + + LP872X_ID_MAX, +}; + +enum lp872x_dvs_state { + DVS_LOW = GPIOF_OUT_INIT_LOW, + DVS_HIGH = GPIOF_OUT_INIT_HIGH, +}; + +enum lp872x_dvs_sel { + SEL_V1, + SEL_V2, +}; + +/** + * lp872x_dvs + * @gpio : gpio pin number for dvs control + * @vsel : dvs selector for buck v1 or buck v2 register + * @init_state : initial dvs pin state + */ +struct lp872x_dvs { + int gpio; + enum lp872x_dvs_sel vsel; + enum lp872x_dvs_state init_state; +}; + +/** + * lp872x_regdata + * @id : regulator id + * @init_data : init data for each regulator + */ +struct lp872x_regulator_data { + enum lp872x_regulator_id id; + struct regulator_init_data *init_data; +}; + +/** + * lp872x_platform_data + * @general_config : the value of LP872X_GENERAL_CFG register + * @update_config : if LP872X_GENERAL_CFG register is updated, set true + * @regulator_data : platform regulator id and init data + * @dvs : dvs data for buck voltage control + */ +struct lp872x_platform_data { + u8 general_config; + bool update_config; + struct lp872x_regulator_data regulator_data[LP872X_MAX_REGULATORS]; + struct lp872x_dvs *dvs; +}; + +#endif -- GitLab From dfad84aeab5f71b33a12e6803a809f698bdef5a2 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 19 Jun 2012 17:43:56 +0200 Subject: [PATCH 2084/6849] regulator: support multiple dummy fixed regulators Currently regulator_register_fixed() uses a constant name to register a fixed dummy regulator. This is sufficient in principle, since there is no reason to register multiple such regulators. The user can simply supply all consumers in one array and use it to initialise such a regulator. However, in some cases it can be convenient to register multiple such regulators. This is also a prerequisite for the upcoming patch, that will add a voltage parameter to this function. The original function is provided as a wrapper macro. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mark Brown --- drivers/regulator/fixed-helper.c | 14 +++++++++++--- include/linux/regulator/fixed.h | 7 +++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index cacd33c9d042..3aa268dfdb1d 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -13,16 +14,18 @@ static void regulator_fixed_release(struct device *dev) { struct fixed_regulator_data *data = container_of(dev, struct fixed_regulator_data, pdev.dev); + kfree(data->cfg.supply_name); kfree(data); } /** - * regulator_register_fixed - register a no-op fixed regulator + * regulator_register_fixed_name - register a no-op fixed regulator * @id: platform device id + * @name: name to be used for the regulator * @supplies: consumers for this regulator * @num_supplies: number of consumers */ -struct platform_device *regulator_register_fixed(int id, +struct platform_device *regulator_register_always_on(int id, const char *name, struct regulator_consumer_supply *supplies, int num_supplies) { struct fixed_regulator_data *data; @@ -31,7 +34,12 @@ struct platform_device *regulator_register_fixed(int id, if (!data) return NULL; - data->cfg.supply_name = "fixed-dummy"; + data->cfg.supply_name = kstrdup(name, GFP_KERNEL); + if (!data->cfg.supply_name) { + kfree(data); + return NULL; + } + data->cfg.microvolts = 0; data->cfg.gpio = -EINVAL; data->cfg.enabled_at_boot = 1; diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h index f83f7440b488..6b9325b5e371 100644 --- a/include/linux/regulator/fixed.h +++ b/include/linux/regulator/fixed.h @@ -58,14 +58,17 @@ struct fixed_voltage_config { struct regulator_consumer_supply; #if IS_ENABLED(CONFIG_REGULATOR) -struct platform_device *regulator_register_fixed(int id, +struct platform_device *regulator_register_always_on(int id, const char *name, struct regulator_consumer_supply *supplies, int num_supplies); #else -static inline struct platform_device *regulator_register_fixed(int id, +static inline struct platform_device *regulator_register_always_on(int id, const char *name, struct regulator_consumer_supply *supplies, int num_supplies) { return NULL; } #endif +#define regulator_register_fixed(id, s, ns) regulator_register_always_on(id, \ + "fixed-dummy", s, ns) + #endif -- GitLab From 15719ccc274981b19ad8fe9ac20c94249de8a257 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 19 Jun 2012 17:44:39 +0200 Subject: [PATCH 2085/6849] regulator: extend the fixed dummy voltage regulator to accept voltage Trivially extend the regulator_register_always_on() helper function to be even more useful by adding a voltage parameter to it. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mark Brown --- drivers/regulator/fixed-helper.c | 5 +++-- include/linux/regulator/fixed.h | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index 3aa268dfdb1d..f9d027992aae 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -24,9 +24,10 @@ static void regulator_fixed_release(struct device *dev) * @name: name to be used for the regulator * @supplies: consumers for this regulator * @num_supplies: number of consumers + * @uv: voltage in microvolts */ struct platform_device *regulator_register_always_on(int id, const char *name, - struct regulator_consumer_supply *supplies, int num_supplies) + struct regulator_consumer_supply *supplies, int num_supplies, int uv) { struct fixed_regulator_data *data; @@ -40,7 +41,7 @@ struct platform_device *regulator_register_always_on(int id, const char *name, return NULL; } - data->cfg.microvolts = 0; + data->cfg.microvolts = uv; data->cfg.gpio = -EINVAL; data->cfg.enabled_at_boot = 1; data->cfg.init_data = &data->init_data; diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h index 6b9325b5e371..680f24e08af2 100644 --- a/include/linux/regulator/fixed.h +++ b/include/linux/regulator/fixed.h @@ -59,16 +59,16 @@ struct regulator_consumer_supply; #if IS_ENABLED(CONFIG_REGULATOR) struct platform_device *regulator_register_always_on(int id, const char *name, - struct regulator_consumer_supply *supplies, int num_supplies); + struct regulator_consumer_supply *supplies, int num_supplies, int uv); #else static inline struct platform_device *regulator_register_always_on(int id, const char *name, - struct regulator_consumer_supply *supplies, int num_supplies) + struct regulator_consumer_supply *supplies, int num_supplies, int uv) { return NULL; } #endif #define regulator_register_fixed(id, s, ns) regulator_register_always_on(id, \ - "fixed-dummy", s, ns) + "fixed-dummy", s, ns, 0) #endif -- GitLab From a819c4f16d5a2708c11e708fd59a96565c5384a8 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Thu, 19 Apr 2012 11:17:45 -0700 Subject: [PATCH 2086/6849] ARM: OMAP3: PM: Only access IVA if one exists prcm_setup_regs() blindly accesses IVA bits in the PRM and calls omap3_iva_idle() which does more IVA related register accesses. Only do this if the IVA hardware actually exists. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a34023d0ca7c..7eb8c5e4183e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -581,10 +581,13 @@ static void __init prcm_setup_regs(void) OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); /* Don't attach IVA interrupts */ - omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); - omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); - omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); - omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL); + if (omap3_has_iva()) { + omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); + omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); + omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); + omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, + OMAP3430_PM_IVAGRPSEL); + } /* Clear any pending 'reset' flags */ omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST); @@ -598,7 +601,9 @@ static void __init prcm_setup_regs(void) /* Clear any pending PRCM interrupts */ omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); - omap3_iva_idle(); + if (omap3_has_iva()) + omap3_iva_idle(); + omap3_d2d_idle(); } -- GitLab From 164e0cbf608214bddc4d28e2777f49e7b3a0f65c Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 10 May 2012 12:02:57 +0200 Subject: [PATCH 2087/6849] ARM: OMAP3/4: consolidate cpuidle Makefile The current Makefile compiles the cpuidle34xx.c and cpuidle44xx.c files even if the cpuidle option is not set in the kernel. This patch fixes this by creating a section in the Makefile where these files are compiled only if the CONFIG_CPU_IDLE option is set. This modification breaks an implicit dependency between CPU_IDLE and PM as they belong to the same block in the Makefile. This is fixed in the Kconfig by selecting explicitely PM is CPU_IDLE is set. The linux coding style recommend to use no-op functions in the headers when the subsystem is disabled instead of adding big section in C files. This patch fix this also. Signed-off-by: Daniel Lezcano Reviewed-by: Jean Pihet Reviewed-by: Rajendra Nayak Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/Kconfig | 2 ++ arch/arm/mach-omap2/Makefile | 7 +++++-- arch/arm/mach-omap2/cpuidle34xx.c | 8 -------- arch/arm/mach-omap2/cpuidle44xx.c | 8 -------- arch/arm/mach-omap2/pm.h | 17 +++++++++++++++-- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 4cf5142f22cc..cf84588cd110 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -35,6 +35,7 @@ config ARCH_OMAP3 select CPU_V7 select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARCH_HAS_OPP + select PM if CPU_IDLE select PM_OPP if PM select ARM_CPU_SUSPEND if PM select MULTI_IRQ_HANDLER @@ -52,6 +53,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP + select PM if CPU_IDLE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fa742f3c2629..6be43ac5c35c 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -66,9 +66,7 @@ ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o -obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o -obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o @@ -82,6 +80,11 @@ endif endif +ifeq ($(CONFIG_CPU_IDLE),y) +obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o +obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o +endif + # PRCM obj-y += prm_common.o obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 207bc1c7759f..31344528eb54 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -36,8 +36,6 @@ #include "control.h" #include "common.h" -#ifdef CONFIG_CPU_IDLE - /* Mach specific information to be recorded in the C-state driver_data */ struct omap3_idle_statedata { u32 mpu_state; @@ -379,9 +377,3 @@ int __init omap3_idle_init(void) return 0; } -#else -int __init omap3_idle_init(void) -{ - return 0; -} -#endif /* CONFIG_CPU_IDLE */ diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index be1617ca84bd..02d15bbd4e35 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -22,8 +22,6 @@ #include "pm.h" #include "prm.h" -#ifdef CONFIG_CPU_IDLE - /* Machine specific information */ struct omap4_idle_statedata { u32 cpu_state; @@ -199,9 +197,3 @@ int __init omap4_idle_init(void) return 0; } -#else -int __init omap4_idle_init(void) -{ - return 0; -} -#endif /* CONFIG_CPU_IDLE */ diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 78564895e914..ab04d3bba2e7 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -15,12 +15,25 @@ #include "powerdomain.h" +#ifdef CONFIG_CPU_IDLE +extern int __init omap3_idle_init(void); +extern int __init omap4_idle_init(void); +#else +static inline int omap3_idle_init(void) +{ + return 0; +} + +static inline int omap4_idle_init(void) +{ + return 0; +} +#endif + extern void *omap3_secure_ram_storage; extern void omap3_pm_off_mode_enable(int); extern void omap_sram_idle(void); extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); -extern int omap3_idle_init(void); -extern int omap4_idle_init(void); extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); extern int (*omap_pm_suspend)(void); -- GitLab From b110547e586eb5825bc1d04aa9147bff83b57672 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 18 May 2012 12:26:19 -0500 Subject: [PATCH 2088/6849] ARM: OMAP2+: OPP: Fix to ensure check of right oppdef after bad one Commit 9fa2df6b90786301b175e264f5fa9846aba81a65 (ARM: OMAP2+: OPP: allow OPP enumeration to continue if device is not present) makes the logic: for (i = 0; i < opp_def_size; i++) { if (!oh || !oh->od) { continue; } opp_def++; } In short, the moment we hit a "Bad OPP", we end up looping the list comparing against the bad opp definition pointer for the rest of the iteration count. Instead, increment opp_def in the for loop itself and allow continue to be used in code without much thought so that we check the next set of OPP definition pointers :) Cc: Steve Sakoman Cc: Tony Lindgren Cc: stable@vger.kernel.org Signed-off-by: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/opp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index de6d46451746..d8f6dbf45d16 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -53,7 +53,7 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, omap_table_init = 1; /* Lets now register with OPP library */ - for (i = 0; i < opp_def_size; i++) { + for (i = 0; i < opp_def_size; i++, opp_def++) { struct omap_hwmod *oh; struct device *dev; @@ -86,7 +86,6 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, __func__, opp_def->freq, opp_def->hwmod_name, i, r); } - opp_def++; } return 0; -- GitLab From a844a197f136ea4cffe050890dd25a35a4d26a42 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 14 Mar 2012 13:56:01 -0700 Subject: [PATCH 2089/6849] ARM: OMAP2+: TWL: remove usage of pdata->irq_base/_end The TWL driver has been converted to use SPARSE_IRQ and no longer needs to be passed IRQ base/end. Since driver no longer uses these fields, so remove them from the reamaining users. Cc: Benoit Cousson Cc: Samuel Ortiz Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-2430sdp.c | 3 --- arch/arm/mach-omap2/board-omap3logic.c | 3 --- arch/arm/mach-omap2/twl-common.c | 9 --------- 3 files changed, 15 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 99ca6bad5c30..0dac4db01139 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -218,9 +218,6 @@ static struct twl4030_gpio_platform_data sdp2430_gpio_data = { }; static struct twl4030_platform_data sdp2430_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, - /* platform_data for children goes here */ .gpio = &sdp2430_gpio_data, .vmmc1 = &sdp2430_vmmc1, diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c index 932e1778aff9..fca93d1afd43 100644 --- a/arch/arm/mach-omap2/board-omap3logic.c +++ b/arch/arm/mach-omap2/board-omap3logic.c @@ -93,9 +93,6 @@ static struct twl4030_usb_data omap3logic_usb_data = { static struct twl4030_platform_data omap3logic_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, - /* platform_data for children goes here */ .gpio = &omap3logic_gpio_data, .vmmc1 = &omap3logic_vmmc1, diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 119d5a910f3a..ce7cccf5a772 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -211,10 +211,6 @@ static struct twl_regulator_driver_data omap3_vdd2_drvdata = { void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags) { - if (!pmic_data->irq_base) - pmic_data->irq_base = TWL4030_IRQ_BASE; - if (!pmic_data->irq_end) - pmic_data->irq_end = TWL4030_IRQ_END; if (!pmic_data->vdd1) { omap3_vdd1.driver_data = &omap3_vdd1_drvdata; omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva"); @@ -479,11 +475,6 @@ static struct regulator_init_data omap4_v2v1_idata = { void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags) { - if (!pmic_data->irq_base) - pmic_data->irq_base = TWL6030_IRQ_BASE; - if (!pmic_data->irq_end) - pmic_data->irq_end = TWL6030_IRQ_END; - if (!pmic_data->vdd1) { omap4_vdd1.driver_data = &omap4_vdd1_drvdata; omap4_vdd1_drvdata.data = voltdm_lookup("mpu"); -- GitLab From 3e7b706ca5151849e4ca91f7f3d8d6d8d8f7b667 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 14 Mar 2012 15:34:17 -0700 Subject: [PATCH 2090/6849] mfd: twl: remove pdata->irq_base/_end, no more users After converstion to SPARSE_IRQ, the driver doesn't use the pdata->irq_base/irq_end fields anymore. The last users have been cleanup up, and now these fields can be removed. Cc: Benoit Cousson Acked-by: Samuel Ortiz Signed-off-by: Kevin Hilman --- include/linux/i2c/twl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 3993477103a5..555382660bc4 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -683,7 +683,6 @@ struct twl4030_audio_data { }; struct twl4030_platform_data { - unsigned irq_base, irq_end; struct twl4030_clock_init_data *clock; struct twl4030_bci_platform_data *bci; struct twl4030_gpio_platform_data *gpio; -- GitLab From 5a695da26367f53a368c90435e0b883c12f02791 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 19 Jun 2012 13:39:14 -0400 Subject: [PATCH 2091/6849] NFS: Fix a refcounting issue in O_DIRECT In nfs_direct_write_reschedule(), the requests from nfs_scan_commit_list have a refcount of 2, whereas the operations in nfs_direct_write_completion_ops expect them to have a refcount of 1. This patch adds a call to release the extra references. Signed-off-by: Trond Myklebust Cc: Fred Isaman --- fs/nfs/direct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 3168f6e3d4d4..9a4cbfc85d81 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -490,6 +490,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) dreq->error = -EIO; spin_unlock(cinfo.lock); } + nfs_release_request(req); } nfs_pageio_complete(&desc); -- GitLab From 1a0de48ae56b5cdb9a46b3d3a0b578dd7f787f22 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 19 Jun 2012 18:38:56 -0400 Subject: [PATCH 2092/6849] NFS: Initialise commit_info.rpc_out when !defined(CONFIG_NFS_V4) Signed-off-by: Trond Myklebust Cc: Fred Isaman --- fs/nfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index e605d695dbcb..f7296983eba6 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1530,7 +1530,6 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) nfsi->delegation_state = 0; init_rwsem(&nfsi->rwsem); nfsi->layout = NULL; - atomic_set(&nfsi->commit_info.rpcs_out, 0); #endif } @@ -1545,6 +1544,7 @@ static void init_once(void *foo) INIT_LIST_HEAD(&nfsi->commit_info.list); nfsi->npages = 0; nfsi->commit_info.ncommit = 0; + atomic_set(&nfsi->commit_info.rpcs_out, 0); atomic_set(&nfsi->silly_count, 1); INIT_HLIST_HEAD(&nfsi->silly_list); init_waitqueue_head(&nfsi->waitqueue); -- GitLab From fbb20e81bd26e41667d8d0929fd08ed60b24d9ec Mon Sep 17 00:00:00 2001 From: Boojin Kim Date: Tue, 19 Jun 2012 13:26:53 +0900 Subject: [PATCH 2093/6849] ARM: SAMSUNG: Add config() function in DMA common operations This patch adds config() that configures DMA transmit option. This function was originally included in request(). But, Some DMA client driver requires to change the configuration after request(). So, This patch picks up it from request(). Signed-off-by: Boojin Kim Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/dma-ops.c | 77 +++++++++++--------- arch/arm/plat-samsung/include/plat/dma-ops.h | 20 +++-- arch/arm/plat-samsung/s3c-dma-ops.c | 39 +++++----- 3 files changed, 77 insertions(+), 59 deletions(-) diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index eb9f4f534006..f9eb353d768c 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -19,72 +19,80 @@ #include static unsigned samsung_dmadev_request(enum dma_ch dma_ch, - struct samsung_dma_info *info) + struct samsung_dma_req *param) { - struct dma_chan *chan; dma_cap_mask_t mask; - struct dma_slave_config slave_config; void *filter_param; dma_cap_zero(mask); - dma_cap_set(info->cap, mask); + dma_cap_set(param->cap, mask); /* * If a dma channel property of a device node from device tree is * specified, use that as the fliter parameter. */ - filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop : - (void *)dma_ch; - chan = dma_request_channel(mask, pl330_filter, filter_param); + filter_param = (dma_ch == DMACH_DT_PROP) ? + (void *)param->dt_dmach_prop : (void *)dma_ch; + return (unsigned)dma_request_channel(mask, pl330_filter, filter_param); +} - if (info->direction == DMA_DEV_TO_MEM) { +static int samsung_dmadev_release(unsigned ch, + struct s3c2410_dma_client *client) +{ + dma_release_channel((struct dma_chan *)ch); + + return 0; +} + +static int samsung_dmadev_config(unsigned ch, + struct samsung_dma_config *param) +{ + struct dma_chan *chan = (struct dma_chan *)ch; + struct dma_slave_config slave_config; + + if (param->direction == DMA_DEV_TO_MEM) { memset(&slave_config, 0, sizeof(struct dma_slave_config)); - slave_config.direction = info->direction; - slave_config.src_addr = info->fifo; - slave_config.src_addr_width = info->width; + slave_config.direction = param->direction; + slave_config.src_addr = param->fifo; + slave_config.src_addr_width = param->width; slave_config.src_maxburst = 1; dmaengine_slave_config(chan, &slave_config); - } else if (info->direction == DMA_MEM_TO_DEV) { + } else if (param->direction == DMA_MEM_TO_DEV) { memset(&slave_config, 0, sizeof(struct dma_slave_config)); - slave_config.direction = info->direction; - slave_config.dst_addr = info->fifo; - slave_config.dst_addr_width = info->width; + slave_config.direction = param->direction; + slave_config.dst_addr = param->fifo; + slave_config.dst_addr_width = param->width; slave_config.dst_maxburst = 1; dmaengine_slave_config(chan, &slave_config); + } else { + pr_warn("unsupported direction\n"); + return -EINVAL; } - return (unsigned)chan; -} - -static int samsung_dmadev_release(unsigned ch, - struct s3c2410_dma_client *client) -{ - dma_release_channel((struct dma_chan *)ch); - return 0; } static int samsung_dmadev_prepare(unsigned ch, - struct samsung_dma_prep_info *info) + struct samsung_dma_prep *param) { struct scatterlist sg; struct dma_chan *chan = (struct dma_chan *)ch; struct dma_async_tx_descriptor *desc; - switch (info->cap) { + switch (param->cap) { case DMA_SLAVE: sg_init_table(&sg, 1); - sg_dma_len(&sg) = info->len; - sg_set_page(&sg, pfn_to_page(PFN_DOWN(info->buf)), - info->len, offset_in_page(info->buf)); - sg_dma_address(&sg) = info->buf; + sg_dma_len(&sg) = param->len; + sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)), + param->len, offset_in_page(param->buf)); + sg_dma_address(&sg) = param->buf; desc = dmaengine_prep_slave_sg(chan, - &sg, 1, info->direction, DMA_PREP_INTERRUPT); + &sg, 1, param->direction, DMA_PREP_INTERRUPT); break; case DMA_CYCLIC: - desc = dmaengine_prep_dma_cyclic(chan, - info->buf, info->len, info->period, info->direction); + desc = dmaengine_prep_dma_cyclic(chan, param->buf, + param->len, param->period, param->direction); break; default: dev_err(&chan->dev->device, "unsupported format\n"); @@ -96,8 +104,8 @@ static int samsung_dmadev_prepare(unsigned ch, return -EFAULT; } - desc->callback = info->fp; - desc->callback_param = info->fp_param; + desc->callback = param->fp; + desc->callback_param = param->fp_param; dmaengine_submit((struct dma_async_tx_descriptor *)desc); @@ -119,6 +127,7 @@ static inline int samsung_dmadev_flush(unsigned ch) static struct samsung_dma_ops dmadev_ops = { .request = samsung_dmadev_request, .release = samsung_dmadev_release, + .config = samsung_dmadev_config, .prepare = samsung_dmadev_prepare, .trigger = samsung_dmadev_trigger, .started = NULL, diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h index 71a6827c7706..f5144cdd3001 100644 --- a/arch/arm/plat-samsung/include/plat/dma-ops.h +++ b/arch/arm/plat-samsung/include/plat/dma-ops.h @@ -16,7 +16,13 @@ #include #include -struct samsung_dma_prep_info { +struct samsung_dma_req { + enum dma_transaction_type cap; + struct property *dt_dmach_prop; + struct s3c2410_dma_client *client; +}; + +struct samsung_dma_prep { enum dma_transaction_type cap; enum dma_transfer_direction direction; dma_addr_t buf; @@ -26,19 +32,17 @@ struct samsung_dma_prep_info { void *fp_param; }; -struct samsung_dma_info { - enum dma_transaction_type cap; +struct samsung_dma_config { enum dma_transfer_direction direction; enum dma_slave_buswidth width; dma_addr_t fifo; - struct s3c2410_dma_client *client; - struct property *dt_dmach_prop; }; struct samsung_dma_ops { - unsigned (*request)(enum dma_ch ch, struct samsung_dma_info *info); - int (*release)(unsigned ch, struct s3c2410_dma_client *client); - int (*prepare)(unsigned ch, struct samsung_dma_prep_info *info); + unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param); + int (*release)(unsigned ch, void *param); + int (*config)(unsigned ch, struct samsung_dma_config *param); + int (*prepare)(unsigned ch, struct samsung_dma_prep *param); int (*trigger)(unsigned ch); int (*started)(unsigned ch); int (*flush)(unsigned ch); diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c index 781494912827..f99448c48d30 100644 --- a/arch/arm/plat-samsung/s3c-dma-ops.c +++ b/arch/arm/plat-samsung/s3c-dma-ops.c @@ -36,30 +36,26 @@ static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param, } static unsigned s3c_dma_request(enum dma_ch dma_ch, - struct samsung_dma_info *info) + struct samsung_dma_req *param) { struct cb_data *data; - if (s3c2410_dma_request(dma_ch, info->client, NULL) < 0) { - s3c2410_dma_free(dma_ch, info->client); + if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) { + s3c2410_dma_free(dma_ch, param->client); return 0; } + if (param->cap == DMA_CYCLIC) + s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR); + data = kzalloc(sizeof(struct cb_data), GFP_KERNEL); data->ch = dma_ch; list_add_tail(&data->node, &dma_list); - s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo); - - if (info->cap == DMA_CYCLIC) - s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR); - - s3c2410_dma_config(dma_ch, info->width); - return (unsigned)dma_ch; } -static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client) +static int s3c_dma_release(unsigned ch, void *param) { struct cb_data *data; @@ -68,16 +64,24 @@ static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client) break; list_del(&data->node); - s3c2410_dma_free(ch, client); + s3c2410_dma_free(ch, param); kfree(data); return 0; } -static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info) +static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param) +{ + s3c2410_dma_devconfig(ch, param->direction, param->fifo); + s3c2410_dma_config(ch, param->width); + + return 0; +} + +static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) { struct cb_data *data; - int len = (info->cap == DMA_CYCLIC) ? info->period : info->len; + int len = (param->cap == DMA_CYCLIC) ? param->period : param->len; list_for_each_entry(data, &dma_list, node) if (data->ch == ch) @@ -85,11 +89,11 @@ static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info) if (!data->fp) { s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb); - data->fp = info->fp; - data->fp_param = info->fp_param; + data->fp = param->fp; + data->fp_param = param->fp_param; } - s3c2410_dma_enqueue(ch, (void *)data, info->buf, len); + s3c2410_dma_enqueue(ch, (void *)data, param->buf, len); return 0; } @@ -117,6 +121,7 @@ static inline int s3c_dma_stop(unsigned ch) static struct samsung_dma_ops s3c_dma_ops = { .request = s3c_dma_request, .release = s3c_dma_release, + .config = s3c_dma_config, .prepare = s3c_dma_prepare, .trigger = s3c_dma_trigger, .started = s3c_dma_started, -- GitLab From 4969c32bab70d71e07b0a76e1699782857d5aa22 Mon Sep 17 00:00:00 2001 From: Boojin Kim Date: Tue, 19 Jun 2012 13:27:03 +0900 Subject: [PATCH 2094/6849] spi/s3c64xx: Add the use of DMA config operation Config operation is separated from request operation in DMA common operation. Because spi driver can change the DMA config for every transfer. So this patch is using the separated DMA config operation. Signed-off-by: Boojin Kim Signed-off-by: Kyoungil Kim Signed-off-by: Kukjin Kim --- drivers/spi/spi-s3c64xx.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 972a94c58be3..3c36cfaa1b93 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -262,14 +262,24 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, unsigned len, dma_addr_t buf) { struct s3c64xx_spi_driver_data *sdd; - struct samsung_dma_prep_info info; + struct samsung_dma_prep info; + struct samsung_dma_config config; - if (dma->direction == DMA_DEV_TO_MEM) + if (dma->direction == DMA_DEV_TO_MEM) { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, rx_dma); - else + config.direction = sdd->rx_dma.direction; + config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; + config.width = sdd->cur_bpw / 8; + sdd->ops->config(sdd->rx_dma.ch, &config); + } else { sdd = container_of((void *)dma, struct s3c64xx_spi_driver_data, tx_dma); + config.direction = sdd->tx_dma.direction; + config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; + config.width = sdd->cur_bpw / 8; + sdd->ops->config(sdd->tx_dma.ch, &config); + } info.cap = DMA_SLAVE; info.len = len; @@ -284,20 +294,15 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) { - struct samsung_dma_info info; + struct samsung_dma_req req; sdd->ops = samsung_dma_get_ops(); - info.cap = DMA_SLAVE; - info.client = &s3c64xx_spi_dma_client; - info.width = sdd->cur_bpw / 8; - - info.direction = sdd->rx_dma.direction; - info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; - sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info); - info.direction = sdd->tx_dma.direction; - info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; - sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info); + req.cap = DMA_SLAVE; + req.client = &s3c64xx_spi_dma_client; + + sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req); + sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req); return 1; } -- GitLab From 21c4afed6acc35deed6db3989f992c17712cd00e Mon Sep 17 00:00:00 2001 From: Boojin Kim Date: Tue, 19 Jun 2012 13:27:07 +0900 Subject: [PATCH 2095/6849] ASoC: follow the updated samsung DMA common operations This patch uses config() function to configure DMA transmit options. Signed-off-by: Boojin Kim Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- sound/soc/samsung/dma.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index ddc6cde14e2a..f3ebc38c10fe 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -74,7 +74,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream) struct runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned int limit; - struct samsung_dma_prep_info dma_info; + struct samsung_dma_prep dma_info; pr_debug("Entered %s\n", __func__); @@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream, unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - struct samsung_dma_info dma_info; + struct samsung_dma_req req; + struct samsung_dma_config config; pr_debug("Entered %s\n", __func__); @@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream, prtd->params->ops = samsung_dma_get_ops(); - dma_info.cap = (samsung_dma_has_circular() ? + req.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); - dma_info.client = prtd->params->client; - dma_info.direction = + req.client = prtd->params->client; + config.direction = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); - dma_info.width = prtd->params->dma_size; - dma_info.fifo = prtd->params->dma_addr; + config.width = prtd->params->dma_size; + config.fifo = prtd->params->dma_addr; prtd->params->ch = prtd->params->ops->request( - prtd->params->channel, &dma_info); + prtd->params->channel, &req); + prtd->params->ops->config(prtd->params->ch, &config); } snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); -- GitLab From 15a4bc17b7f4e85cb019e683f14e834078ec2208 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 24 May 2012 09:47:38 -0700 Subject: [PATCH 2096/6849] Staging: add CSR Wifi "os helper" module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This module is used by the CSR wifi driver to "abstract" away the OS-specific parts of core functions. It will be eventually deleted, but for now is needed as the CSR driver relies on it. Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/csr/Kconfig | 7 + drivers/staging/csr/Makefile | 1 + drivers/staging/csr/oska/Makefile | 12 ++ drivers/staging/csr/oska/all.h | 61 +++++++ drivers/staging/csr/oska/alloc.h | 41 +++++ drivers/staging/csr/oska/compat.c | 54 ++++++ drivers/staging/csr/oska/event.c | 82 ++++++++++ drivers/staging/csr/oska/event.h | 33 ++++ drivers/staging/csr/oska/io.h | 63 +++++++ drivers/staging/csr/oska/kernel-compat.h | 199 +++++++++++++++++++++++ drivers/staging/csr/oska/list.c | 103 ++++++++++++ drivers/staging/csr/oska/list.h | 115 +++++++++++++ drivers/staging/csr/oska/mutex.h | 42 +++++ drivers/staging/csr/oska/oska_module.c | 21 +++ drivers/staging/csr/oska/print.c | 44 +++++ drivers/staging/csr/oska/print.h | 32 ++++ drivers/staging/csr/oska/refcount.c | 47 ++++++ drivers/staging/csr/oska/refcount.h | 86 ++++++++++ drivers/staging/csr/oska/semaphore.h | 70 ++++++++ drivers/staging/csr/oska/spinlock.h | 43 +++++ drivers/staging/csr/oska/thread.c | 66 ++++++++ drivers/staging/csr/oska/thread.h | 39 +++++ drivers/staging/csr/oska/time.h | 34 ++++ drivers/staging/csr/oska/timer.c | 28 ++++ drivers/staging/csr/oska/timer.h | 40 +++++ drivers/staging/csr/oska/trace.h | 23 +++ drivers/staging/csr/oska/types.h | 14 ++ drivers/staging/csr/oska/util.h | 48 ++++++ 30 files changed, 1451 insertions(+) create mode 100644 drivers/staging/csr/Kconfig create mode 100644 drivers/staging/csr/Makefile create mode 100644 drivers/staging/csr/oska/Makefile create mode 100644 drivers/staging/csr/oska/all.h create mode 100644 drivers/staging/csr/oska/alloc.h create mode 100644 drivers/staging/csr/oska/compat.c create mode 100644 drivers/staging/csr/oska/event.c create mode 100644 drivers/staging/csr/oska/event.h create mode 100644 drivers/staging/csr/oska/io.h create mode 100644 drivers/staging/csr/oska/kernel-compat.h create mode 100644 drivers/staging/csr/oska/list.c create mode 100644 drivers/staging/csr/oska/list.h create mode 100644 drivers/staging/csr/oska/mutex.h create mode 100644 drivers/staging/csr/oska/oska_module.c create mode 100644 drivers/staging/csr/oska/print.c create mode 100644 drivers/staging/csr/oska/print.h create mode 100644 drivers/staging/csr/oska/refcount.c create mode 100644 drivers/staging/csr/oska/refcount.h create mode 100644 drivers/staging/csr/oska/semaphore.h create mode 100644 drivers/staging/csr/oska/spinlock.h create mode 100644 drivers/staging/csr/oska/thread.c create mode 100644 drivers/staging/csr/oska/thread.h create mode 100644 drivers/staging/csr/oska/time.h create mode 100644 drivers/staging/csr/oska/timer.c create mode 100644 drivers/staging/csr/oska/timer.h create mode 100644 drivers/staging/csr/oska/trace.h create mode 100644 drivers/staging/csr/oska/types.h create mode 100644 drivers/staging/csr/oska/util.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 38f1fb08eaef..d3934d79524a 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -132,4 +132,6 @@ source "drivers/staging/ipack/Kconfig" source "drivers/staging/gdm72xx/Kconfig" +source "drivers/staging/csr/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e0c4c2444fed..5b2219ac5207 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_RAMSTER) += ramster/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_USB_G_CCG) += ccg/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ +obj-$(CONFIG_CSR_WIFI) += csr/ diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig new file mode 100644 index 000000000000..5d7b800058a3 --- /dev/null +++ b/drivers/staging/csr/Kconfig @@ -0,0 +1,7 @@ +config CSR_WIFI + tristate "CSR wireless driver" + depends on PCI + help + Driver for the CSR wireless SDIO device. + + If unsure, select N. diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile new file mode 100644 index 000000000000..b9ba3b378e65 --- /dev/null +++ b/drivers/staging/csr/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CSR_WIFI) += oska/ diff --git a/drivers/staging/csr/oska/Makefile b/drivers/staging/csr/oska/Makefile new file mode 100644 index 000000000000..3a0b648ddebc --- /dev/null +++ b/drivers/staging/csr/oska/Makefile @@ -0,0 +1,12 @@ +obj-$(CONFIG_CSR_WIFI) := csr_oska.o + +csr_oska-y := \ + list.o \ + refcount.o \ + compat.o \ + event.o \ + oska_module.o \ + print.o \ + thread.o \ + timer.o + diff --git a/drivers/staging/csr/oska/all.h b/drivers/staging/csr/oska/all.h new file mode 100644 index 000000000000..5fe85834894b --- /dev/null +++ b/drivers/staging/csr/oska/all.h @@ -0,0 +1,61 @@ +/* + * Operating system kernel abstraction -- all functions + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_ALL_H +#define __OSKA_ALL_H + +/** + * @mainpage Operating System Kernel Abstraction + * + * @section intro Introduction + * + * The Operating System Kernel Abstraction (oska) is a software + * package providing an abstraction for various operating system + * kernel facilities for use by device drivers and other OS kernel + * software (e.g., SDIO stacks). Oska is modularized and intended to + * be a lightweight wrapper around an OSes interfaces. + * + * @section modules Modules + * + * Oska is organized into the modules, each of which has it's own + * header file providing the interface. + * + * - \ref alloc "Memory allocation" + * - \ref event "Events" + * - \ref mutex "Mutexes" + * - \ref print "Console output" + * - \ref spinlock "Spinlocks" + * - \ref thread "Threading" + * - \ref time "Timing and delays" + * - \ref timer "Timers" + * - \ref types "Standard Types" + * - \ref util "Miscellaneous utilities" + * + * An header is provided which includes all the above + * modules. + * + * There are additional modules that are not included in . + * + * - \ref io "Memory mapped I/O" + * - \ref refcount "Reference Counting" + * - \ref list "Linked lists" + * - \ref trace "Tracing messages" + */ + +#include "alloc.h" +#include "event.h" +#include "mutex.h" +#include "print.h" +#include "spinlock.h" +#include "thread.h" +#include "time.h" +#include "timer.h" +#include "types.h" +#include "util.h" + +#endif /* __OSKA_ALL_H */ diff --git a/drivers/staging/csr/oska/alloc.h b/drivers/staging/csr/oska/alloc.h new file mode 100644 index 000000000000..0f106016e1f7 --- /dev/null +++ b/drivers/staging/csr/oska/alloc.h @@ -0,0 +1,41 @@ +/* + * OSKA Linux implementation -- memory allocation + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_ALLOC_H +#define __OSKA_LINUX_ALLOC_H + +#include +#include +#include + +static inline void *os_alloc(size_t size) +{ + return kzalloc(size, GFP_ATOMIC); +} + +static inline void *os_alloc_nonzeroed(size_t size) +{ + return kmalloc(size, GFP_KERNEL); +} + +static inline void os_free(void *ptr) +{ + kfree(ptr); +} + +static inline void *os_alloc_big(size_t size) +{ + return vmalloc(size); +} + +static inline void os_free_big(void *ptr) +{ + vfree(ptr); +} + +#endif /* #ifndef __OSKA_LINUX_ALLOC_H */ diff --git a/drivers/staging/csr/oska/compat.c b/drivers/staging/csr/oska/compat.c new file mode 100644 index 000000000000..790b97a7d5f9 --- /dev/null +++ b/drivers/staging/csr/oska/compat.c @@ -0,0 +1,54 @@ +/* + * Linux version compatibility functions. + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include "kernel-compat.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + +int dev_set_name(struct device *dev, const char *fmt, ...) +{ + va_list vargs; + + va_start(vargs, fmt); + vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs); + va_end(vargs); + return 0; +} +EXPORT_SYMBOL_GPL(dev_set_name); + +#endif /* Linux kernel < 2.6.26 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + +struct device *class_find_device(struct class *class, struct device *start, + void *data, int (*match)(struct device *, void *)) +{ + struct device *dev; + + list_for_each_entry(dev, &class->devices, node) { + if (match(dev, data)) { + get_device(dev); + return dev; + } + } + return NULL; +} +EXPORT_SYMBOL_GPL(class_find_device); + +#endif /* Linux kernel < 2.6.25 */ diff --git a/drivers/staging/csr/oska/event.c b/drivers/staging/csr/oska/event.c new file mode 100644 index 000000000000..4aedaaa0d9e4 --- /dev/null +++ b/drivers/staging/csr/oska/event.c @@ -0,0 +1,82 @@ +/* + * Linux event functions. + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include +#include + +#include "event.h" + +void os_event_init(os_event_t *evt) +{ + init_waitqueue_head(&evt->wq); + spin_lock_init(&evt->lock); + evt->events = 0; +} +EXPORT_SYMBOL(os_event_init); + +uint16_t os_event_wait(os_event_t *evt) +{ + uint16_t e; + unsigned long flags; + + wait_event(evt->wq, evt->events != 0); + + spin_lock_irqsave(&evt->lock, flags); + e = evt->events; + evt->events &= ~e; + spin_unlock_irqrestore(&evt->lock, flags); + + return e; +} +EXPORT_SYMBOL(os_event_wait); + +uint16_t os_event_wait_interruptible(os_event_t *evt) +{ + uint16_t e; + unsigned long flags; + + wait_event_interruptible(evt->wq, evt->events != 0); + + spin_lock_irqsave(&evt->lock, flags); + e = evt->events; + evt->events &= ~e; + spin_unlock_irqrestore(&evt->lock, flags); + + return e; +} +EXPORT_SYMBOL(os_event_wait_interruptible); + +uint16_t os_event_wait_timed(os_event_t *evt, unsigned timeout_ms) +{ + uint16_t e; + unsigned long flags; + + wait_event_interruptible_timeout(evt->wq, + evt->events != 0, + msecs_to_jiffies(timeout_ms)); + + spin_lock_irqsave(&evt->lock, flags); + e = evt->events; + evt->events &= ~e; + spin_unlock_irqrestore(&evt->lock, flags); + + return e; +} +EXPORT_SYMBOL(os_event_wait_timed); + +void os_event_raise(os_event_t *evt, uint16_t events) +{ + unsigned long flags; + + spin_lock_irqsave(&evt->lock, flags); + evt->events |= events; + spin_unlock_irqrestore(&evt->lock, flags); + + wake_up(&evt->wq); +} +EXPORT_SYMBOL(os_event_raise); diff --git a/drivers/staging/csr/oska/event.h b/drivers/staging/csr/oska/event.h new file mode 100644 index 000000000000..be52e42c37dc --- /dev/null +++ b/drivers/staging/csr/oska/event.h @@ -0,0 +1,33 @@ +/* + * OSKA Linux implementation -- events + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_EVENT_H +#define __OSKA_LINUX_EVENT_H + +#include +#include +#include + +typedef struct { + wait_queue_head_t wq; + spinlock_t lock; + uint16_t events; +} os_event_t; + +void os_event_init(os_event_t *evt); + +static inline void os_event_destroy(os_event_t *evt) +{ +} + +uint16_t os_event_wait(os_event_t *evt); +uint16_t os_event_wait_interruptible(os_event_t *evt); +uint16_t os_event_wait_timed(os_event_t *evt, unsigned timeout_ms); +void os_event_raise(os_event_t *evt, uint16_t events); + +#endif /* #ifndef __OSKA_LINUX_EVENT_H */ diff --git a/drivers/staging/csr/oska/io.h b/drivers/staging/csr/oska/io.h new file mode 100644 index 000000000000..c6c406c364b9 --- /dev/null +++ b/drivers/staging/csr/oska/io.h @@ -0,0 +1,63 @@ +/* + * OSKA Linux implementation -- memory mapped I/O. + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_IO_H +#define __OSKA_LINUX_IO_H + +#include +#include +#include + +typedef void __iomem *os_io_mem_t; + +static inline uint8_t os_io_read8(os_io_mem_t base, unsigned offset) +{ + return readb(base + offset); +} + +static inline uint16_t os_io_read16(os_io_mem_t base, unsigned offset) +{ + return readw(base + offset); +} + +static inline uint32_t os_io_read32(os_io_mem_t base, unsigned offset) +{ + return readl(base + offset); +} + +static inline uint64_t os_io_read64(os_io_mem_t base, unsigned offset) +{ + return readq(base + offset); +} + +static inline void os_io_write8(os_io_mem_t base, unsigned offset, uint8_t val) +{ + writeb(val, base + offset); +} + +static inline void os_io_write16(os_io_mem_t base, unsigned offset, uint16_t val) +{ + writew(val, base + offset); +} + +static inline void os_io_write32(os_io_mem_t base, unsigned offset, uint32_t val) +{ + writel(val, base + offset); +} + +static inline void os_io_write64(os_io_mem_t base, unsigned offset, uint64_t val) +{ + writeq(val, base + offset); +} + +static inline void os_io_memory_barrier(void) +{ + mb(); +} + +#endif /* #ifndef __OSKA_LINUX_IO_H */ diff --git a/drivers/staging/csr/oska/kernel-compat.h b/drivers/staging/csr/oska/kernel-compat.h new file mode 100644 index 000000000000..b6d27d39c33b --- /dev/null +++ b/drivers/staging/csr/oska/kernel-compat.h @@ -0,0 +1,199 @@ +/* + * Kernel version compatibility. + * + * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * Wherever possible compatible implementations of newer APIs are + * provided for older kernel versions. + */ +#ifndef __LINUX_KERNEL_COMPAT_H +#define __LINUX_KERNEL_COMPAT_H + +#include +#include +#include + +#include + +/* + * linux/semaphore.h replaces asm/semaphore.h in 2.6.27. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +# include +#else +# include +#endif + +/* + * Workqueue API changes in 2.6.20 + * + * See http://lwn.net/Articles/211279/ for details. + * + * We deliberately don't provide the non-automatic release (NAR) + * variants as a simple compatible implementation is not possible. + * This shouldn't be a problem as all usage so far is to embed the + * struct work_struct into another struct and the NAR variants aren't + * useful in this case (see http://lwn.net/Articles/213149/). + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + +#include + +#undef INIT_WORK +#define INIT_WORK(_work, _func) \ + do { \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->pending = 0; \ + PREPARE_WORK((_work), (_func), (_work)); \ + init_timer(&(_work)->timer); \ + } while(0) + +#undef DECLARE_WORK +#define DECLARE_WORK(n, f) \ + struct work_struct n = __WORK_INITIALIZER((n), (f), &(n)) + +struct delayed_work { + struct work_struct work; +}; + +#define INIT_DELAYED_WORK(dw, fn) \ + INIT_WORK(&(dw)->work, (fn)) + +#define queue_delayed_work(wq, dw, delay) \ + queue_delayed_work((wq), &(dw)->work, (delay)) + +#define schedule_delayed_work(dw, delay) \ + schedule_delayed_work(&(dw)->work, (delay)) + +#define cancel_delayed_work(dw) \ + cancel_delayed_work(&(dw)->work) + +#endif /* Linux kernel < 2.6.20 */ + +/* + * device_create()/class_device_create() + * + * device_create() gains a drvdata parameter in 2.6.27. Since all + * users of device_create() in CSR code don't use drvdata just ignore + * it. + * + * device_create() replaces class_device_create() in 2.6.21. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) + +#define device_create(class, parent, devt, drvdata, fmt, args...) \ + class_device_create((class), (parent), (devt), NULL, (fmt), ## args) +#define device_destroy(class, devt) \ + class_device_destroy(class, devt) + +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + +#define device_create(class, parent, devt, drvdata, fmt, args...) \ + device_create((class), (parent), (devt), (fmt), ## args) + +#endif /* Linux kernel < 2.6.26 */ + +/* + * dev_name() and dev_set_name() added in 2.6.26. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + +static inline char *dev_name(struct device *dev) +{ + return dev->bus_id; +} + +int dev_set_name(struct device *dev, const char *fmt, ...); + +#endif /* Linux kernel < 2.6.26 */ + +/* + * class_find_device() in 2.6.25 + */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + +struct device *class_find_device(struct class *class, struct device *start, + void *data, int (*match)(struct device *, void *)); + +#endif /* Linux kernel < 2.6.25 */ + +/* + * list_first_entry in 2.6.22. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +#endif /* Linux kernel < 2.6.22 */ + +/* + * 2.6.19 adds a bool type. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + +typedef _Bool bool; +enum { + false = 0, + true = 1 +}; + +#endif /* Linux kernel < 2.6.19 */ + +/* + * Provide readq() and writeq() if unavailable. + */ +#ifndef readq +static inline __u64 readq(const volatile void __iomem *addr) +{ + const volatile u32 __iomem *p = addr; + u32 low, high; + + low = readl(p); + high = readl(p + 1); + + return low + ((u64)high << 32); +} +#endif + +#ifndef writeq +static inline void writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val >> 32, addr+4); +} +#endif + +/* + * get_unaligned_le16() and friends added in 2.6.26. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#include + +static inline __u16 get_unaligned_le16(const void *p) +{ + return le16_to_cpu(get_unaligned((__le16 *)p)); +} + +static inline void put_unaligned_le16(__u16 val, const void *p) +{ + put_unaligned(cpu_to_le16(val), (__le16 *)p); +} +#endif /* Linux kernel < 2.6.26 */ + +/* + * Various device or vendor IDs may not exist. + */ +#ifndef PCI_VENDOR_ID_CSR +# define PCI_VENDOR_ID_CSR 0x18e5 +#endif + +#ifndef PCI_DEVICE_ID_JMICRON_JMB38X_SD +# define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 +#endif + +#endif /* #ifndef __LINUX_KERNEL_COMPAT_H */ diff --git a/drivers/staging/csr/oska/list.c b/drivers/staging/csr/oska/list.c new file mode 100644 index 000000000000..b5e884e1f201 --- /dev/null +++ b/drivers/staging/csr/oska/list.c @@ -0,0 +1,103 @@ +/* + * Operating system kernel abstraction -- linked lists. + * + * Copyright (C) 2009-2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ + +#include + +#include "list.h" +#include "util.h" + +/** + * Initialize an empty list. + * + * @ingroup list + */ +void os_list_init(struct os_list *list) +{ + list->head.next = list->head.prev = &list->head; +} + +/** + * Is the list empty? + * + * @return true iff the list contains no nodes. + * + * @ingroup list + */ +int os_list_empty(struct os_list *list) +{ + return list->head.next == &list->head; +} + +static void os_list_add(struct os_list_node *prev, struct os_list_node *new, + struct os_list_node *next) +{ + OS_ASSERT(new->next == NULL && new->prev == NULL); + + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * Add a node to the tail of the list. + * + * @param list the list. + * @param node the list node to add. + * + * @ingroup list + */ +void os_list_add_tail(struct os_list *list, struct os_list_node *node) +{ + os_list_add(list->head.prev, node, &list->head); +} + +/** + * Remove a node from a list. + * + * @param node the node to remove. + * + * @ingroup list + */ +void os_list_del(struct os_list_node *node) +{ + node->prev->next = node->next; + node->next->prev = node->prev; + + node->prev = node->next = NULL; +} + +/** + * The node at the head of the list. + * + * @param list the list. + * + * @return the node at the head of the list; or os_list_end() if the + * list is empty. + * + * @ingroup list + */ +struct os_list_node *os_list_head(struct os_list *list) +{ + return list->head.next; +} + +/** + * The node marking the end of a list. + * + * @param list the list. + * + * @return the node that marks the end of the list. + * + * @ingroup list + */ +struct os_list_node *os_list_end(struct os_list *list) +{ + return &list->head; +} diff --git a/drivers/staging/csr/oska/list.h b/drivers/staging/csr/oska/list.h new file mode 100644 index 000000000000..a69b3b7d96b4 --- /dev/null +++ b/drivers/staging/csr/oska/list.h @@ -0,0 +1,115 @@ +/* + * Operating system kernel abstraction -- linked lists. + * + * Copyright (C) 2009-2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LIST_H +#define __OSKA_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup list Linked Lists + * + * Generic linked list implementations suitable for all platforms. + * + * - Circular, doubly-linked list (struct os_list). + */ + +/** + * A list node. + * + * This list node structure should be the first field within any + * structure that is to be stored in a list. + * + * @see struct os_list + * @ingroup list + */ +struct os_list_node { + /** + * The pointer to the previous node in the list, or os_list_end() + * if the end of the list has been reached. + */ + struct os_list_node *prev; + /** + * The pointer to the next node in the list, or os_list_end() if + * the end of the list has been reached. + */ + struct os_list_node *next; +}; + +/** + * A circular, doubly-linked list of nodes. + * + * Structures to be stored in a list should contains a struct + * os_list_node as the \e first field. + * \code + * struct foo { + * struct os_list_node node; + * int bar; + * ... + * }; + * \endcode + * Going to/from a struct foo to a list node is then simple. + * \code + * struct os_list_node *node; + * struct foo *foo; + * [...] + * node = &foo->node; + * foo = (struct foo *)node + * \endcode + * Lists must be initialized with os_list_init() before adding nodes + * with os_list_add_tail(). The node at the head of the list is + * obtained with os_list_head(). Nodes are removed from the list with + * os_list_del(). + * + * A list can be interated from the head to the tail using: + * \code + * struct os_list_node *node; + * for (node = os_list_head(list); node != os_list_end(list); node = node->next) { + * struct foo *foo = (struct foo *)node; + * ... + * } + * \endcode + * + * In the above loop, the current list node cannot be removed (with + * os_list_del()). If this is required use this form of loop: + * \code + * struct os_list_node *node, *next; + * for (node = os_list_head(list), next = node->next; + * node != os_list_end(list); + * node = next, next = node->next) { + * struct foo *foo = (struct foo *)node; + * ... + * os_list_del(node); + * ... + * } + * \endcode + * + * @ingroup list + */ +struct os_list { + /** + * @internal + * The dummy node marking the end of the list. + */ + struct os_list_node head; +}; + +void os_list_init(struct os_list *list); +int os_list_empty(struct os_list *list); +void os_list_add_tail(struct os_list *list, struct os_list_node *node); +void os_list_del(struct os_list_node *node); +struct os_list_node *os_list_head(struct os_list *list); +struct os_list_node *os_list_end(struct os_list *list); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* #ifndef __OSKA_LIST_H */ diff --git a/drivers/staging/csr/oska/mutex.h b/drivers/staging/csr/oska/mutex.h new file mode 100644 index 000000000000..9138b2881832 --- /dev/null +++ b/drivers/staging/csr/oska/mutex.h @@ -0,0 +1,42 @@ +/* + * OSKA Linux implementation -- mutexes + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_MUTEX_H +#define __OSKA_LINUX_MUTEX_H + +#include +#include + +#include "kernel-compat.h" + +/* Real mutexes were only added to 2.6.16 so use semaphores + instead. */ +typedef struct semaphore os_mutex_t; + +static inline void os_mutex_init(os_mutex_t *mutex) +{ + //init_MUTEX(mutex); + sema_init(mutex, 1); +} + +static inline void os_mutex_destroy(os_mutex_t *mutex) +{ + /* no op */ +} + +static inline void os_mutex_lock(os_mutex_t *mutex) +{ + down(mutex); +} + +static inline void os_mutex_unlock(os_mutex_t *mutex) +{ + up(mutex); +} + +#endif /* __OSKA_LINUX_MUTEX_H */ diff --git a/drivers/staging/csr/oska/oska_module.c b/drivers/staging/csr/oska/oska_module.c new file mode 100644 index 000000000000..da125643d2d6 --- /dev/null +++ b/drivers/staging/csr/oska/oska_module.c @@ -0,0 +1,21 @@ +/* + * Linux kernel module support. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include + +#include "all.h" +#include "refcount.h" + +EXPORT_SYMBOL(os_refcount_init); +EXPORT_SYMBOL(os_refcount_destroy); +EXPORT_SYMBOL(os_refcount_get); +EXPORT_SYMBOL(os_refcount_put); + +MODULE_DESCRIPTION("Operating System Kernel Abstraction"); +MODULE_AUTHOR("Cambridge Silicon Radio Ltd."); +MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/staging/csr/oska/print.c b/drivers/staging/csr/oska/print.c new file mode 100644 index 000000000000..5f5b26310663 --- /dev/null +++ b/drivers/staging/csr/oska/print.c @@ -0,0 +1,44 @@ +/* + * Linux console printing functions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include + +#include "print.h" + +void os_print(enum os_print_level level, const char *prefix, const char *name, + const char *format, ...) +{ + va_list va_args; + + va_start(va_args, format); + os_vprint(level, prefix, name, format, va_args); + va_end(va_args); +} +EXPORT_SYMBOL(os_print); + +void os_vprint(enum os_print_level level, const char *prefix, const char *name, + const char *format, va_list args) +{ + const char *level_str[] = { + [OS_PRINT_ERROR] = KERN_ERR, + [OS_PRINT_WARNING] = KERN_WARNING, + [OS_PRINT_INFO] = KERN_INFO, + [OS_PRINT_DEBUG] = KERN_DEBUG, + }; + char buf[80]; + int w = 0; + + if (name) { + w += snprintf(buf + w, sizeof(buf) - w, "%s%s%s: ", level_str[level], prefix, name); + } else { + w += snprintf(buf + w, sizeof(buf) - w, "%s%s", level_str[level], prefix); + } + w += vsnprintf(buf + w, sizeof(buf) - w, format, args); + printk("%s\n", buf); +} +EXPORT_SYMBOL(os_vprint); diff --git a/drivers/staging/csr/oska/print.h b/drivers/staging/csr/oska/print.h new file mode 100644 index 000000000000..f48bb836a587 --- /dev/null +++ b/drivers/staging/csr/oska/print.h @@ -0,0 +1,32 @@ +/* + * OSKA Linux implementation -- console printing + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_PRINT_H +#define __OSKA_LINUX_PRINT_H + +#include + +/** + * Severity of a console or log message. + * + * @ingroup print + */ +enum os_print_level { + OS_PRINT_ERROR, + OS_PRINT_WARNING, + OS_PRINT_INFO, + OS_PRINT_DEBUG, +}; + +void os_print(enum os_print_level level, const char *prefix, const char *name, + const char *format, ...); +void os_vprint(enum os_print_level level, const char *prefix, const char *name, + const char *format, va_list args); + + +#endif /* #ifndef __OSKA_LINUX_PRINT_H */ diff --git a/drivers/staging/csr/oska/refcount.c b/drivers/staging/csr/oska/refcount.c new file mode 100644 index 000000000000..28abb64a9d20 --- /dev/null +++ b/drivers/staging/csr/oska/refcount.c @@ -0,0 +1,47 @@ +/* + * OSKA generic implementation -- reference counting. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include "refcount.h" +#include "types.h" + +void os_refcount_init(os_refcount_t *refcount, os_refcount_callback_f func, void *arg) +{ + os_spinlock_init(&refcount->lock); + refcount->count = 1; + refcount->func = func; + refcount->arg = arg; +} + +void os_refcount_destroy(os_refcount_t *refcount) +{ + os_spinlock_destroy(&refcount->lock); +} + +void os_refcount_get(os_refcount_t *refcount) +{ + os_int_status_t istate; + + os_spinlock_lock_intsave(&refcount->lock, &istate); + refcount->count++; + os_spinlock_unlock_intrestore(&refcount->lock, &istate); +} + +void os_refcount_put(os_refcount_t *refcount) +{ + bool is_zero; + os_int_status_t istate; + + os_spinlock_lock_intsave(&refcount->lock, &istate); + refcount->count--; + is_zero = refcount->count == 0; + os_spinlock_unlock_intrestore(&refcount->lock, &istate); + + if (is_zero) { + refcount->func(refcount->arg); + } +} diff --git a/drivers/staging/csr/oska/refcount.h b/drivers/staging/csr/oska/refcount.h new file mode 100644 index 000000000000..741b00afcdf0 --- /dev/null +++ b/drivers/staging/csr/oska/refcount.h @@ -0,0 +1,86 @@ +/* + * Operating system kernel abstraction -- reference counting. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_REFCOUNT_H +#define __OSKA_REFCOUNT_H + +#include "spinlock.h" + +/** + * @defgroup refcount Reference Counting + * + * A reference count is an atomic counter. A callback function is + * called whenever the count reaches zero. + * + * A generic implementation is provided that is suitable for all + * platforms that support the spinlock API in (see + * \ref spinlock). + */ + +typedef void (*os_refcount_callback_f)(void *arg); + +struct __os_refcount_impl { + unsigned count; + os_spinlock_t lock; + os_refcount_callback_f func; + void *arg; +}; + +/** + * A reference count object. + * + * @ingroup refcount + */ +typedef struct __os_refcount_impl os_refcount_t; + +/** + * Initialize a reference count to 1. + * + * Initialized reference counts must be destroyed by calling + * os_refcount_destroy(). + * + * @param refcount the reference count. + * @param func the function which will be called when the + * reference count reaches 0. + * @param arg an argument to pass to func. + * + * @ingroup refcount + */ +void os_refcount_init(os_refcount_t *refcount, os_refcount_callback_f func, void *arg); + +/** + * Destroy a reference count object. + * + * @param refcount the reference count. + * + * @ingroup refcount + */ +void os_refcount_destroy(os_refcount_t *refcount); + +/** + * Atomically increase the reference count by 1. + * + * @param refcount the reference count. + * + * @ingroup refcount + */ +void os_refcount_get(os_refcount_t *refcount); + +/** + * Atomically decrease the reference count by 1. + * + * The callback function passed to the call to os_refcount_init() is + * called if the count was decreased to zero. + * + * @param refcount the reference count. + * + * @ingroup refcount + */ +void os_refcount_put(os_refcount_t *refcount); + +#endif /* #ifndef __OSKA_REFCOUNT_H */ diff --git a/drivers/staging/csr/oska/semaphore.h b/drivers/staging/csr/oska/semaphore.h new file mode 100644 index 000000000000..965bfe8f52cf --- /dev/null +++ b/drivers/staging/csr/oska/semaphore.h @@ -0,0 +1,70 @@ +/* + * OSKA Linux implementation -- semaphores + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_SEMAPHORE_H +#define __OSKA_LINUX_SEMAPHORE_H + +#include + +#include + +typedef struct semaphore os_semaphore_t; + +static inline void os_semaphore_init(os_semaphore_t *sem) +{ + sema_init(sem, 0); +} + +static inline void os_semaphore_destroy(os_semaphore_t *sem) +{ +} + +static inline void os_semaphore_wait(os_semaphore_t *sem) +{ + down(sem); +} + +/* + * down_timeout() was added in 2.6.26 with the generic semaphore + * implementation. For now, only support it on recent kernels as + * semaphores may be replaced by an event API that would be + * implemented with wait_event(), and wait_event_timeout(). + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + +static inline int os_semaphore_wait_timed(os_semaphore_t *sem, + int time_ms) +{ + if (down_timeout(sem, msecs_to_jiffies(time_ms)) < 0) { + return -ETIMEDOUT; + } + return 0; +} + +#else + +static inline int os_semaphore_wait_timed(os_semaphore_t *sem, int time_ms) +{ + unsigned long now = jiffies; + do{ + if(!down_trylock(sem)) + return 0; + msleep(1); + } while(time_before(jiffies, now + msecs_to_jiffies(time_ms))); + + return -ETIMEDOUT; +} + +#endif + +static inline void os_semaphore_post(os_semaphore_t *sem) +{ + up(sem); +} + +#endif /* __OSKA_LINUX_SEMAPHORE_H */ diff --git a/drivers/staging/csr/oska/spinlock.h b/drivers/staging/csr/oska/spinlock.h new file mode 100644 index 000000000000..157b350107ae --- /dev/null +++ b/drivers/staging/csr/oska/spinlock.h @@ -0,0 +1,43 @@ +/* + * OSKA Linux implementation -- spinlocks + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_SPINLOCK_H +#define __OSKA_LINUX_SPINLOCK_H + +#include +#include + +typedef spinlock_t os_spinlock_t; +typedef unsigned long os_int_status_t; + +static inline void os_spinlock_init(os_spinlock_t *lock) +{ + spinlock_t *l = (spinlock_t *)lock; + spin_lock_init(l); +} + +static inline void os_spinlock_destroy(os_spinlock_t *lock) +{ + /* no op */ +} + +static inline void os_spinlock_lock_intsave(os_spinlock_t *lock, + os_int_status_t *int_state) +{ + spinlock_t *l = (spinlock_t *)lock; + spin_lock_irqsave(l, *int_state); +} + +static inline void os_spinlock_unlock_intrestore(os_spinlock_t *lock, + os_int_status_t *int_state) +{ + spinlock_t *l = (spinlock_t *)lock; + spin_unlock_irqrestore(l, *int_state); +} + +#endif /* #ifndef __OSKA_LINUX_SPINLOCK_H */ diff --git a/drivers/staging/csr/oska/thread.c b/drivers/staging/csr/oska/thread.c new file mode 100644 index 000000000000..f680cef709e7 --- /dev/null +++ b/drivers/staging/csr/oska/thread.c @@ -0,0 +1,66 @@ +/* + * Linux thread functions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include + +#include "thread.h" + +static int thread_func(void *data) +{ + os_thread_t *thread = data; + + thread->func(thread->arg); + + /* + * kthread_stop() cannot handle the thread exiting while + * kthread_should_stop() is false, so sleep until kthread_stop() + * wakes us up. + */ + set_current_state(TASK_INTERRUPTIBLE); + if (!kthread_should_stop()) + schedule(); + + return 0; +} + +int os_thread_create(os_thread_t *thread, const char *name, void (*func)(void *), void *arg) +{ + thread->func = func; + thread->arg = arg; + + thread->stop = 0; + + thread->task = kthread_run(thread_func, thread, name); + if (IS_ERR(thread->task)) { + return PTR_ERR(thread->task); + } + return 0; +} +EXPORT_SYMBOL(os_thread_create); + +void os_thread_stop(os_thread_t *thread, os_event_t *evt) +{ + /* + * Stop flag must be set before the event is raised so + * kthread_should_stop() cannot be used. + */ + thread->stop = 1; + + if (evt) { + os_event_raise(evt, ~0); + } + + kthread_stop(thread->task); +} +EXPORT_SYMBOL(os_thread_stop); + +int os_thread_should_stop(os_thread_t *thread) +{ + return thread->stop; +} +EXPORT_SYMBOL(os_thread_should_stop); diff --git a/drivers/staging/csr/oska/thread.h b/drivers/staging/csr/oska/thread.h new file mode 100644 index 000000000000..8816dc853e26 --- /dev/null +++ b/drivers/staging/csr/oska/thread.h @@ -0,0 +1,39 @@ +/* + * OSKA Linux implementation -- threading + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_THREAD_H +#define __OSKA_LINUX_THREAD_H + +#include +#include +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19) +#include +#endif +#include "event.h" + +struct os_thread_lx { + void (*func)(void *); + void *arg; + struct task_struct *task; + int stop; +}; + +typedef struct os_thread_lx os_thread_t; + +int os_thread_create(os_thread_t *thread, const char *name, + void (*func)(void *), void *arg); +void os_thread_stop(os_thread_t *thread, os_event_t *evt); +int os_thread_should_stop(os_thread_t *thread); + +static inline void os_try_suspend_thread(os_thread_t *thread) +{ + try_to_freeze(); +} + +#endif /* __OSKA_LINUX_THREAD_H */ diff --git a/drivers/staging/csr/oska/time.h b/drivers/staging/csr/oska/time.h new file mode 100644 index 000000000000..d246ce937309 --- /dev/null +++ b/drivers/staging/csr/oska/time.h @@ -0,0 +1,34 @@ +/* + * OSKA Linux implementation -- timing + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_TIME_H +#define __OSKA_LINUX_TIME_H + +#include +#include +#include +#include + +static inline unsigned long os_current_time_ms(void) +{ + return jiffies_to_msecs(jiffies); +} + +static inline void os_sleep_ms(unsigned ms) +{ + msleep_interruptible(ms); +} + +static inline void os_delay_us(unsigned us) +{ + udelay(us); +} + +#define os_time_after(a, b) time_after((a), (b)) + +#endif /* __OSKA_LINUX_TIME_H */ diff --git a/drivers/staging/csr/oska/timer.c b/drivers/staging/csr/oska/timer.c new file mode 100644 index 000000000000..67d3423315f5 --- /dev/null +++ b/drivers/staging/csr/oska/timer.c @@ -0,0 +1,28 @@ +/* + * OSKA Linux implementation -- timers. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#include + +#include "timer.h" + +static void timer_func(unsigned long data) +{ + os_timer_t *timer = (os_timer_t *)data; + + timer->func(timer->arg); +} + +void os_timer_init(os_timer_t *timer, os_timer_func_t func, void *arg) +{ + timer->func = func; + timer->arg = arg; + timer->timer.function = timer_func; + timer->timer.data = (unsigned long)timer; + init_timer(&timer->timer); +} +EXPORT_SYMBOL(os_timer_init); diff --git a/drivers/staging/csr/oska/timer.h b/drivers/staging/csr/oska/timer.h new file mode 100644 index 000000000000..3045fc3b98b7 --- /dev/null +++ b/drivers/staging/csr/oska/timer.h @@ -0,0 +1,40 @@ +/* + * OSKA Linux implementation -- timers. + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_TIMER_H +#define __OSKA_LINUX_TIMER_H + +#include +#include + +typedef void (*os_timer_func_t)(void *arg); + +typedef struct { + os_timer_func_t func; + void *arg; + struct timer_list timer; +} os_timer_t; + +void os_timer_init(os_timer_t *timer, os_timer_func_t func, void *arg); + +static inline void os_timer_destroy(os_timer_t *timer) +{ + del_timer_sync(&timer->timer); +} + +static inline void os_timer_set(os_timer_t *timer, unsigned long expires_ms) +{ + mod_timer(&timer->timer, jiffies + msecs_to_jiffies(expires_ms)); +} + +static inline void os_timer_cancel(os_timer_t *timer) +{ + del_timer(&timer->timer); +} + +#endif /* #ifndef __OSKA_LINUX_TIMER_H */ diff --git a/drivers/staging/csr/oska/trace.h b/drivers/staging/csr/oska/trace.h new file mode 100644 index 000000000000..b28f37da4fbb --- /dev/null +++ b/drivers/staging/csr/oska/trace.h @@ -0,0 +1,23 @@ +/* + * OSKA Linux implementation -- tracing messages. + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_TRACE_H +#define __OSKA_LINUX_TRACE_H + +#include + +#ifndef OS_TRACE_PREFIX +# define OS_TRACE_PREFIX "" +#endif + +#define os_trace_err(format, ...) printk(KERN_ERR OS_TRACE_PREFIX format "\n", ## __VA_ARGS__) +#define os_trace_warn(format, ...) printk(KERN_WARNING OS_TRACE_PREFIX format "\n", ## __VA_ARGS__) +#define os_trace_info(format, ...) printk(KERN_INFO OS_TRACE_PREFIX format "\n", ## __VA_ARGS__) +#define os_trace_dbg(format, ...) printk(KERN_DEBUG OS_TRACE_PREFIX format "\n", ## __VA_ARGS__) + +#endif /* #ifndef __OSKA_LINUX_TRACE_H */ diff --git a/drivers/staging/csr/oska/types.h b/drivers/staging/csr/oska/types.h new file mode 100644 index 000000000000..18d7c111e74a --- /dev/null +++ b/drivers/staging/csr/oska/types.h @@ -0,0 +1,14 @@ +/* + * OSKA Linux implementation -- types + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_TYPES_H +#define __OSKA_LINUX_TYPES_H + +#include + +#endif /* #ifndef __OSKA_LINUX_TYPES_H */ diff --git a/drivers/staging/csr/oska/util.h b/drivers/staging/csr/oska/util.h new file mode 100644 index 000000000000..bf29e2d906ed --- /dev/null +++ b/drivers/staging/csr/oska/util.h @@ -0,0 +1,48 @@ +/* + * OSKA Linux implementation -- misc. utility functions + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef __OSKA_LINUX_UTILS_H +#define __OSKA_LINUX_UTILS_H + +#include +#include +#include + +#define OS_ASSERT(expr) BUG_ON(!(expr)) + +static inline uint16_t os_le16_to_cpu(uint16_t x) +{ + return le16_to_cpu(x); +} + +static inline uint16_t os_cpu_to_le16(uint16_t x) +{ + return cpu_to_le16(x); +} + +static inline uint32_t os_le32_to_cpu(uint32_t x) +{ + return le32_to_cpu(x); +} + +static inline uint32_t os_cpu_to_le32(uint32_t x) +{ + return cpu_to_le32(x); +} + +static inline uint64_t os_le64_to_cpu(uint64_t x) +{ + return le64_to_cpu(x); +} + +static inline uint64_t os_cpu_to_le64(uint64_t x) +{ + return cpu_to_le64(x); +} + +#endif /* __OSKA_LINUX_UTILS_H */ -- GitLab From 635d2b00e5070378e7bf812acf47fb135c6ab928 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 19 Jun 2012 16:15:42 -0700 Subject: [PATCH 2097/6849] Staging: add CSR wifi module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This consists of two modules, the driver, and a "helper" module that is just a wrapper around common kernel functions. The wrapper module will be removed soon, but for now it's needed. These files were based on the csr-linux-wifi-5.0.3-oss.tar.gz package provided by CSR and Blue Giga, and is covered under the license specified in the LICENSE.txt file (basically dual BSD and GPLv2). The files were flattened out of the deep directory mess they were originally in, and a few EXPORT_SYMBOL_GPL() were added in order for everything to link properly with the helper module setup. Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/Kconfig | 2 +- drivers/staging/csr/LICENSE.txt | 39 + drivers/staging/csr/Makefile | 70 + drivers/staging/csr/bh.c | 391 + drivers/staging/csr/csr_formatted_io.c | 29 + drivers/staging/csr/csr_formatted_io.h | 25 + drivers/staging/csr/csr_framework_ext.c | 213 + drivers/staging/csr/csr_framework_ext.h | 354 + drivers/staging/csr/csr_framework_ext_types.h | 65 + drivers/staging/csr/csr_lib.h | 189 + drivers/staging/csr/csr_log.h | 250 + drivers/staging/csr/csr_log_configure.h | 135 + drivers/staging/csr/csr_log_text.h | 133 + drivers/staging/csr/csr_macro.h | 111 + drivers/staging/csr/csr_msg_transport.h | 25 + drivers/staging/csr/csr_msgconv.c | 324 + drivers/staging/csr/csr_msgconv.h | 145 + drivers/staging/csr/csr_panic.c | 22 + drivers/staging/csr/csr_panic.h | 55 + drivers/staging/csr/csr_pmem.c | 51 + drivers/staging/csr/csr_pmem.h | 143 + drivers/staging/csr/csr_prim_defs.h | 64 + drivers/staging/csr/csr_result.h | 27 + drivers/staging/csr/csr_sched.h | 292 + drivers/staging/csr/csr_sdio.h | 732 ++ .../csr/csr_serialize_primitive_types.c | 472 ++ drivers/staging/csr/csr_time.c | 71 + drivers/staging/csr/csr_time.h | 205 + drivers/staging/csr/csr_types.h | 93 + drivers/staging/csr/csr_unicode.h | 190 + drivers/staging/csr/csr_utf16.c | 1136 +++ drivers/staging/csr/csr_util.c | 435 ++ drivers/staging/csr/csr_util.h | 75 + drivers/staging/csr/csr_wifi_common.h | 109 + drivers/staging/csr/csr_wifi_fsm.h | 250 + drivers/staging/csr/csr_wifi_fsm_event.h | 51 + drivers/staging/csr/csr_wifi_fsm_types.h | 441 ++ drivers/staging/csr/csr_wifi_hip_card.h | 114 + drivers/staging/csr/csr_wifi_hip_card_sdio.c | 4128 +++++++++++ drivers/staging/csr/csr_wifi_hip_card_sdio.h | 702 ++ .../staging/csr/csr_wifi_hip_card_sdio_intr.c | 2561 +++++++ .../staging/csr/csr_wifi_hip_card_sdio_mem.c | 1713 +++++ drivers/staging/csr/csr_wifi_hip_chiphelper.c | 793 ++ drivers/staging/csr/csr_wifi_hip_chiphelper.h | 471 ++ .../csr/csr_wifi_hip_chiphelper_private.h | 208 + .../staging/csr/csr_wifi_hip_conversions.h | 81 + drivers/staging/csr/csr_wifi_hip_download.c | 834 +++ drivers/staging/csr/csr_wifi_hip_dump.c | 872 +++ drivers/staging/csr/csr_wifi_hip_packing.c | 4804 ++++++++++++ drivers/staging/csr/csr_wifi_hip_send.c | 422 ++ drivers/staging/csr/csr_wifi_hip_signals.c | 1313 ++++ drivers/staging/csr/csr_wifi_hip_signals.h | 137 + drivers/staging/csr/csr_wifi_hip_sigs.h | 1425 ++++ .../staging/csr/csr_wifi_hip_ta_sampling.c | 535 ++ .../staging/csr/csr_wifi_hip_ta_sampling.h | 75 + drivers/staging/csr/csr_wifi_hip_udi.c | 268 + drivers/staging/csr/csr_wifi_hip_unifi.h | 852 +++ .../csr/csr_wifi_hip_unifi_signal_names.c | 46 + drivers/staging/csr/csr_wifi_hip_unifi_udi.h | 76 + drivers/staging/csr/csr_wifi_hip_unifihw.h | 67 + .../staging/csr/csr_wifi_hip_unifiversion.h | 38 + drivers/staging/csr/csr_wifi_hip_xbv.c | 1075 +++ drivers/staging/csr/csr_wifi_hip_xbv.h | 127 + drivers/staging/csr/csr_wifi_hostio_prim.h | 27 + drivers/staging/csr/csr_wifi_lib.h | 113 + drivers/staging/csr/csr_wifi_msgconv.h | 60 + .../csr/csr_wifi_nme_ap_converter_init.h | 49 + drivers/staging/csr/csr_wifi_nme_ap_lib.h | 526 ++ drivers/staging/csr/csr_wifi_nme_ap_prim.h | 504 ++ drivers/staging/csr/csr_wifi_nme_ap_sef.c | 30 + drivers/staging/csr/csr_wifi_nme_ap_sef.h | 31 + .../staging/csr/csr_wifi_nme_ap_serialize.h | 105 + .../staging/csr/csr_wifi_nme_converter_init.h | 46 + drivers/staging/csr/csr_wifi_nme_lib.h | 1056 +++ drivers/staging/csr/csr_wifi_nme_prim.h | 1666 +++++ drivers/staging/csr/csr_wifi_nme_serialize.h | 177 + drivers/staging/csr/csr_wifi_nme_task.h | 38 + drivers/staging/csr/csr_wifi_private_common.h | 91 + drivers/staging/csr/csr_wifi_result.h | 36 + .../csr/csr_wifi_router_converter_init.c | 83 + .../csr/csr_wifi_router_converter_init.h | 42 + .../csr/csr_wifi_router_ctrl_converter_init.c | 132 + .../csr/csr_wifi_router_ctrl_converter_init.h | 42 + ...ifi_router_ctrl_free_downstream_contents.c | 95 + ..._wifi_router_ctrl_free_upstream_contents.c | 81 + .../staging/csr/csr_wifi_router_ctrl_lib.h | 1958 +++++ .../staging/csr/csr_wifi_router_ctrl_prim.h | 2018 +++++ .../staging/csr/csr_wifi_router_ctrl_sef.c | 43 + .../staging/csr/csr_wifi_router_ctrl_sef.h | 56 + .../csr/csr_wifi_router_ctrl_serialize.c | 2369 ++++++ .../csr/csr_wifi_router_ctrl_serialize.h | 323 + ...csr_wifi_router_free_downstream_contents.c | 54 + .../csr_wifi_router_free_upstream_contents.c | 54 + drivers/staging/csr/csr_wifi_router_lib.h | 429 ++ drivers/staging/csr/csr_wifi_router_prim.h | 430 ++ drivers/staging/csr/csr_wifi_router_sef.c | 19 + drivers/staging/csr/csr_wifi_router_sef.h | 33 + .../staging/csr/csr_wifi_router_serialize.c | 422 ++ .../staging/csr/csr_wifi_router_serialize.h | 78 + drivers/staging/csr/csr_wifi_router_task.h | 34 + .../staging/csr/csr_wifi_router_transport.c | 210 + .../csr/csr_wifi_serialize_primitive_types.c | 257 + drivers/staging/csr/csr_wifi_sme_ap_lib.h | 656 ++ drivers/staging/csr/csr_wifi_sme_ap_prim.h | 904 +++ .../staging/csr/csr_wifi_sme_converter_init.c | 201 + .../staging/csr/csr_wifi_sme_converter_init.h | 42 + .../csr_wifi_sme_free_downstream_contents.c | 181 + .../csr/csr_wifi_sme_free_upstream_contents.c | 276 + drivers/staging/csr/csr_wifi_sme_lib.h | 4282 +++++++++++ drivers/staging/csr/csr_wifi_sme_prim.h | 6494 +++++++++++++++++ drivers/staging/csr/csr_wifi_sme_sef.c | 85 + drivers/staging/csr/csr_wifi_sme_sef.h | 101 + drivers/staging/csr/csr_wifi_sme_serialize.c | 5756 +++++++++++++++ drivers/staging/csr/csr_wifi_sme_serialize.h | 668 ++ drivers/staging/csr/csr_wifi_sme_task.h | 34 + drivers/staging/csr/csr_wifi_vif_utils.h | 108 + drivers/staging/csr/data_tx.c | 57 + drivers/staging/csr/drv.c | 2150 ++++++ drivers/staging/csr/firmware.c | 398 + drivers/staging/csr/indications.c | 18 + drivers/staging/csr/inet.c | 106 + drivers/staging/csr/init_hw.c | 108 + drivers/staging/csr/io.c | 1146 +++ drivers/staging/csr/mlme.c | 441 ++ drivers/staging/csr/monitor.c | 458 ++ drivers/staging/csr/netdev.c | 3902 ++++++++++ drivers/staging/csr/os.c | 479 ++ drivers/staging/csr/putest.c | 664 ++ drivers/staging/csr/sdio_emb.c | 732 ++ drivers/staging/csr/sdio_events.c | 87 + drivers/staging/csr/sdio_mmc.c | 1165 +++ drivers/staging/csr/sdio_stubs.c | 82 + drivers/staging/csr/sdioemb/cspi.h | 62 + drivers/staging/csr/sdioemb/csr_result.h | 16 + drivers/staging/csr/sdioemb/csr_sdio.h | 711 ++ drivers/staging/csr/sdioemb/csr_sdio_lib.h | 30 + drivers/staging/csr/sdioemb/csr_sdio_wdf.h | 22 + drivers/staging/csr/sdioemb/csr_types.h | 53 + drivers/staging/csr/sdioemb/libsdio.h | 404 + drivers/staging/csr/sdioemb/linux.h | 16 + drivers/staging/csr/sdioemb/sdio.h | 117 + drivers/staging/csr/sdioemb/sdio_api.h | 408 ++ drivers/staging/csr/sdioemb/sdio_bt_a.h | 143 + drivers/staging/csr/sdioemb/sdio_cis.h | 27 + drivers/staging/csr/sdioemb/sdio_csr.h | 134 + drivers/staging/csr/sdioemb/slot_api.h | 313 + drivers/staging/csr/sdioemb/slot_imx27.h | 86 + drivers/staging/csr/sdioemb/slot_imx31.h | 86 + drivers/staging/csr/sdioemb/slot_pxa27x.h | 70 + drivers/staging/csr/sdioemb/slot_shc.h | 223 + drivers/staging/csr/sdioemb/slot_ushc.h | 133 + drivers/staging/csr/sdioemb/trace.h | 19 + drivers/staging/csr/sdioemb/uif.h | 41 + drivers/staging/csr/sdioemb/version.h | 11 + drivers/staging/csr/sme_blocking.c | 1468 ++++ drivers/staging/csr/sme_mgt.c | 1018 +++ drivers/staging/csr/sme_native.c | 591 ++ drivers/staging/csr/sme_sys.c | 2950 ++++++++ drivers/staging/csr/sme_userspace.c | 316 + drivers/staging/csr/sme_userspace.h | 38 + drivers/staging/csr/sme_wext.c | 3394 +++++++++ drivers/staging/csr/ul_int.c | 552 ++ drivers/staging/csr/unifi_clients.h | 129 + drivers/staging/csr/unifi_config.h | 34 + drivers/staging/csr/unifi_dbg.c | 110 + drivers/staging/csr/unifi_event.c | 794 ++ drivers/staging/csr/unifi_native.h | 276 + drivers/staging/csr/unifi_os.h | 137 + drivers/staging/csr/unifi_pdu_processing.c | 3728 ++++++++++ drivers/staging/csr/unifi_priv.h | 1148 +++ drivers/staging/csr/unifi_sme.c | 1164 +++ drivers/staging/csr/unifi_sme.h | 236 + drivers/staging/csr/unifi_wext.h | 124 + drivers/staging/csr/unifiio.h | 400 + drivers/staging/csr/wext_events.c | 285 + 175 files changed, 98765 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/csr/LICENSE.txt create mode 100644 drivers/staging/csr/bh.c create mode 100644 drivers/staging/csr/csr_formatted_io.c create mode 100644 drivers/staging/csr/csr_formatted_io.h create mode 100644 drivers/staging/csr/csr_framework_ext.c create mode 100644 drivers/staging/csr/csr_framework_ext.h create mode 100644 drivers/staging/csr/csr_framework_ext_types.h create mode 100644 drivers/staging/csr/csr_lib.h create mode 100644 drivers/staging/csr/csr_log.h create mode 100644 drivers/staging/csr/csr_log_configure.h create mode 100644 drivers/staging/csr/csr_log_text.h create mode 100644 drivers/staging/csr/csr_macro.h create mode 100644 drivers/staging/csr/csr_msg_transport.h create mode 100644 drivers/staging/csr/csr_msgconv.c create mode 100644 drivers/staging/csr/csr_msgconv.h create mode 100644 drivers/staging/csr/csr_panic.c create mode 100644 drivers/staging/csr/csr_panic.h create mode 100644 drivers/staging/csr/csr_pmem.c create mode 100644 drivers/staging/csr/csr_pmem.h create mode 100644 drivers/staging/csr/csr_prim_defs.h create mode 100644 drivers/staging/csr/csr_result.h create mode 100644 drivers/staging/csr/csr_sched.h create mode 100644 drivers/staging/csr/csr_sdio.h create mode 100644 drivers/staging/csr/csr_serialize_primitive_types.c create mode 100644 drivers/staging/csr/csr_time.c create mode 100644 drivers/staging/csr/csr_time.h create mode 100644 drivers/staging/csr/csr_types.h create mode 100644 drivers/staging/csr/csr_unicode.h create mode 100644 drivers/staging/csr/csr_utf16.c create mode 100644 drivers/staging/csr/csr_util.c create mode 100644 drivers/staging/csr/csr_util.h create mode 100644 drivers/staging/csr/csr_wifi_common.h create mode 100644 drivers/staging/csr/csr_wifi_fsm.h create mode 100644 drivers/staging/csr/csr_wifi_fsm_event.h create mode 100644 drivers/staging/csr/csr_wifi_fsm_types.h create mode 100644 drivers/staging/csr/csr_wifi_hip_card.h create mode 100644 drivers/staging/csr/csr_wifi_hip_card_sdio.c create mode 100644 drivers/staging/csr/csr_wifi_hip_card_sdio.h create mode 100644 drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c create mode 100644 drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c create mode 100644 drivers/staging/csr/csr_wifi_hip_chiphelper.c create mode 100644 drivers/staging/csr/csr_wifi_hip_chiphelper.h create mode 100644 drivers/staging/csr/csr_wifi_hip_chiphelper_private.h create mode 100644 drivers/staging/csr/csr_wifi_hip_conversions.h create mode 100644 drivers/staging/csr/csr_wifi_hip_download.c create mode 100644 drivers/staging/csr/csr_wifi_hip_dump.c create mode 100644 drivers/staging/csr/csr_wifi_hip_packing.c create mode 100644 drivers/staging/csr/csr_wifi_hip_send.c create mode 100644 drivers/staging/csr/csr_wifi_hip_signals.c create mode 100644 drivers/staging/csr/csr_wifi_hip_signals.h create mode 100644 drivers/staging/csr/csr_wifi_hip_sigs.h create mode 100644 drivers/staging/csr/csr_wifi_hip_ta_sampling.c create mode 100644 drivers/staging/csr/csr_wifi_hip_ta_sampling.h create mode 100644 drivers/staging/csr/csr_wifi_hip_udi.c create mode 100644 drivers/staging/csr/csr_wifi_hip_unifi.h create mode 100644 drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c create mode 100644 drivers/staging/csr/csr_wifi_hip_unifi_udi.h create mode 100644 drivers/staging/csr/csr_wifi_hip_unifihw.h create mode 100644 drivers/staging/csr/csr_wifi_hip_unifiversion.h create mode 100644 drivers/staging/csr/csr_wifi_hip_xbv.c create mode 100644 drivers/staging/csr/csr_wifi_hip_xbv.h create mode 100644 drivers/staging/csr/csr_wifi_hostio_prim.h create mode 100644 drivers/staging/csr/csr_wifi_lib.h create mode 100644 drivers/staging/csr/csr_wifi_msgconv.h create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_converter_init.h create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_lib.h create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_prim.h create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_sef.c create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_sef.h create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_serialize.h create mode 100644 drivers/staging/csr/csr_wifi_nme_converter_init.h create mode 100644 drivers/staging/csr/csr_wifi_nme_lib.h create mode 100644 drivers/staging/csr/csr_wifi_nme_prim.h create mode 100644 drivers/staging/csr/csr_wifi_nme_serialize.h create mode 100644 drivers/staging/csr/csr_wifi_nme_task.h create mode 100644 drivers/staging/csr/csr_wifi_private_common.h create mode 100644 drivers/staging/csr/csr_wifi_result.h create mode 100644 drivers/staging/csr/csr_wifi_router_converter_init.c create mode 100644 drivers/staging/csr/csr_wifi_router_converter_init.h create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_lib.h create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_prim.h create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_sef.c create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_sef.h create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_serialize.c create mode 100644 drivers/staging/csr/csr_wifi_router_ctrl_serialize.h create mode 100644 drivers/staging/csr/csr_wifi_router_free_downstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_router_free_upstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_router_lib.h create mode 100644 drivers/staging/csr/csr_wifi_router_prim.h create mode 100644 drivers/staging/csr/csr_wifi_router_sef.c create mode 100644 drivers/staging/csr/csr_wifi_router_sef.h create mode 100644 drivers/staging/csr/csr_wifi_router_serialize.c create mode 100644 drivers/staging/csr/csr_wifi_router_serialize.h create mode 100644 drivers/staging/csr/csr_wifi_router_task.h create mode 100644 drivers/staging/csr/csr_wifi_router_transport.c create mode 100644 drivers/staging/csr/csr_wifi_serialize_primitive_types.c create mode 100644 drivers/staging/csr/csr_wifi_sme_ap_lib.h create mode 100644 drivers/staging/csr/csr_wifi_sme_ap_prim.h create mode 100644 drivers/staging/csr/csr_wifi_sme_converter_init.c create mode 100644 drivers/staging/csr/csr_wifi_sme_converter_init.h create mode 100644 drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_sme_lib.h create mode 100644 drivers/staging/csr/csr_wifi_sme_prim.h create mode 100644 drivers/staging/csr/csr_wifi_sme_sef.c create mode 100644 drivers/staging/csr/csr_wifi_sme_sef.h create mode 100644 drivers/staging/csr/csr_wifi_sme_serialize.c create mode 100644 drivers/staging/csr/csr_wifi_sme_serialize.h create mode 100644 drivers/staging/csr/csr_wifi_sme_task.h create mode 100644 drivers/staging/csr/csr_wifi_vif_utils.h create mode 100644 drivers/staging/csr/data_tx.c create mode 100644 drivers/staging/csr/drv.c create mode 100644 drivers/staging/csr/firmware.c create mode 100644 drivers/staging/csr/indications.c create mode 100644 drivers/staging/csr/inet.c create mode 100644 drivers/staging/csr/init_hw.c create mode 100644 drivers/staging/csr/io.c create mode 100644 drivers/staging/csr/mlme.c create mode 100644 drivers/staging/csr/monitor.c create mode 100644 drivers/staging/csr/netdev.c create mode 100644 drivers/staging/csr/os.c create mode 100644 drivers/staging/csr/putest.c create mode 100644 drivers/staging/csr/sdio_emb.c create mode 100644 drivers/staging/csr/sdio_events.c create mode 100644 drivers/staging/csr/sdio_mmc.c create mode 100644 drivers/staging/csr/sdio_stubs.c create mode 100644 drivers/staging/csr/sdioemb/cspi.h create mode 100644 drivers/staging/csr/sdioemb/csr_result.h create mode 100644 drivers/staging/csr/sdioemb/csr_sdio.h create mode 100644 drivers/staging/csr/sdioemb/csr_sdio_lib.h create mode 100644 drivers/staging/csr/sdioemb/csr_sdio_wdf.h create mode 100644 drivers/staging/csr/sdioemb/csr_types.h create mode 100644 drivers/staging/csr/sdioemb/libsdio.h create mode 100644 drivers/staging/csr/sdioemb/linux.h create mode 100644 drivers/staging/csr/sdioemb/sdio.h create mode 100644 drivers/staging/csr/sdioemb/sdio_api.h create mode 100644 drivers/staging/csr/sdioemb/sdio_bt_a.h create mode 100644 drivers/staging/csr/sdioemb/sdio_cis.h create mode 100644 drivers/staging/csr/sdioemb/sdio_csr.h create mode 100644 drivers/staging/csr/sdioemb/slot_api.h create mode 100644 drivers/staging/csr/sdioemb/slot_imx27.h create mode 100644 drivers/staging/csr/sdioemb/slot_imx31.h create mode 100644 drivers/staging/csr/sdioemb/slot_pxa27x.h create mode 100644 drivers/staging/csr/sdioemb/slot_shc.h create mode 100644 drivers/staging/csr/sdioemb/slot_ushc.h create mode 100644 drivers/staging/csr/sdioemb/trace.h create mode 100644 drivers/staging/csr/sdioemb/uif.h create mode 100644 drivers/staging/csr/sdioemb/version.h create mode 100644 drivers/staging/csr/sme_blocking.c create mode 100644 drivers/staging/csr/sme_mgt.c create mode 100644 drivers/staging/csr/sme_native.c create mode 100644 drivers/staging/csr/sme_sys.c create mode 100644 drivers/staging/csr/sme_userspace.c create mode 100644 drivers/staging/csr/sme_userspace.h create mode 100644 drivers/staging/csr/sme_wext.c create mode 100644 drivers/staging/csr/ul_int.c create mode 100644 drivers/staging/csr/unifi_clients.h create mode 100644 drivers/staging/csr/unifi_config.h create mode 100644 drivers/staging/csr/unifi_dbg.c create mode 100644 drivers/staging/csr/unifi_event.c create mode 100644 drivers/staging/csr/unifi_native.h create mode 100644 drivers/staging/csr/unifi_os.h create mode 100644 drivers/staging/csr/unifi_pdu_processing.c create mode 100644 drivers/staging/csr/unifi_priv.h create mode 100644 drivers/staging/csr/unifi_sme.c create mode 100644 drivers/staging/csr/unifi_sme.h create mode 100644 drivers/staging/csr/unifi_wext.h create mode 100644 drivers/staging/csr/unifiio.h create mode 100644 drivers/staging/csr/wext_events.c diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig index 5d7b800058a3..e3a923ac6e75 100644 --- a/drivers/staging/csr/Kconfig +++ b/drivers/staging/csr/Kconfig @@ -1,6 +1,6 @@ config CSR_WIFI tristate "CSR wireless driver" - depends on PCI + depends on PCI && MMC help Driver for the CSR wireless SDIO device. diff --git a/drivers/staging/csr/LICENSE.txt b/drivers/staging/csr/LICENSE.txt new file mode 100644 index 000000000000..364853e5fedc --- /dev/null +++ b/drivers/staging/csr/LICENSE.txt @@ -0,0 +1,39 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +Except as contained in this notice, the names of above-listed +copyright holders and the names of any contributors shall not be used +in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Alternatively, this software may be distributed under the terms of the +GNU General Public License ("GPL") version 2 as published +by the Free Software Foundation. + +As a special exception, if other files instantiate templates or use +macros or inline functions from this file, or you compile this file +and link it with other works to produce a work based on this file, +this file does not by itself cause the resulting work to be covered by +the GNU General Public License. However the source code for this file +must still be made available in accordance with section (3) of the GNU +General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile index b9ba3b378e65..27eb4a77bc7f 100644 --- a/drivers/staging/csr/Makefile +++ b/drivers/staging/csr/Makefile @@ -1 +1,71 @@ obj-$(CONFIG_CSR_WIFI) += oska/ + +ccflags-y := -DCSR_SME_USERSPACE -DCSR_SUPPORT_SME -DREMOTE_SYS_SAP -DCSR_WIFI_SECURITY_WAPI_ENABLE -DENABLE_SHUTDOWN + +obj-$(CONFIG_CSR_WIFI) += csr_wifi.o +obj-$(CONFIG_CSR_WIFI) += csr_helper.o + +csr_wifi-y := bh.o \ + data_tx.o \ + drv.o \ + firmware.o \ + indications.o \ + inet.o \ + init_hw.o \ + io.o \ + monitor.o \ + netdev.o \ + os.o \ + putest.o \ + sdio_events.o \ + sdio_mmc.o \ + sdio_stubs.o \ + sme_blocking.o \ + ul_int.o \ + unifi_dbg.o \ + unifi_event.o \ + unifi_pdu_processing.o \ + unifi_sme.o \ + csr_formatted_io.o \ + csr_wifi_hip_card_sdio.o \ + csr_wifi_hip_card_sdio_intr.o \ + csr_wifi_hip_card_sdio_mem.o \ + csr_wifi_hip_chiphelper.o \ + csr_wifi_hip_download.o \ + csr_wifi_hip_dump.o \ + csr_wifi_hip_packing.o \ + csr_wifi_hip_send.o \ + csr_wifi_hip_signals.o \ + csr_wifi_hip_ta_sampling.o \ + csr_wifi_hip_udi.o \ + csr_wifi_hip_unifi_signal_names.o \ + csr_wifi_hip_xbv.o \ + csr_wifi_router_ctrl_sef.o \ + csr_wifi_router_sef.o \ + csr_wifi_router_transport.o \ + csr_wifi_sme_sef.o \ + csr_wifi_sme_converter_init.o \ + csr_wifi_sme_free_downstream_contents.o \ + csr_wifi_sme_free_upstream_contents.o \ + csr_wifi_sme_serialize.o \ + csr_wifi_router_ctrl_converter_init.o \ + csr_wifi_router_ctrl_free_downstream_contents.o \ + csr_wifi_router_ctrl_free_upstream_contents.o \ + csr_wifi_router_ctrl_serialize.o \ + csr_wifi_router_converter_init.o \ + csr_wifi_router_free_downstream_contents.o \ + csr_wifi_router_free_upstream_contents.o \ + csr_wifi_router_serialize.o \ + sme_mgt.o \ + sme_sys.o \ + sme_userspace.o + +csr_helper-y := csr_time.o \ + csr_util.o \ + csr_framework_ext.o \ + csr_pmem.o \ + csr_wifi_serialize_primitive_types.o \ + csr_serialize_primitive_types.o \ + csr_utf16.o \ + csr_msgconv.o \ + csr_panic.o diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c new file mode 100644 index 000000000000..6af9d2953eae --- /dev/null +++ b/drivers/staging/csr/bh.c @@ -0,0 +1,391 @@ +/* + * --------------------------------------------------------------------------- + * FILE: bh.c + * + * PURPOSE: + * Provides an implementation for the driver bottom-half. + * It is part of the porting exercise in Linux. + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" + + +/* + * --------------------------------------------------------------------------- + * uf_start_thread + * + * Helper function to start a new thread. + * + * Arguments: + * priv Pointer to OS driver structure for the device. + * thread Pointer to the thread object + * func The thread function + * + * Returns: + * 0 on success or else a Linux error code. + * --------------------------------------------------------------------------- + */ +int +uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void *)) +{ + if (thread->thread_task != NULL) { + unifi_error(priv, "%s thread already started\n", thread->name); + return 0; + } + + /* Start the kernel thread that handles all h/w accesses. */ + thread->thread_task = kthread_run(func, priv, "%s", thread->name); + if (IS_ERR(thread->thread_task)) { + return PTR_ERR(thread->thread_task); + } + + /* Module parameter overides the thread priority */ + if (bh_priority != -1) { + if (bh_priority >= 0 && bh_priority <= MAX_RT_PRIO) { + struct sched_param param; + priv->bh_thread.prio = bh_priority; + unifi_trace(priv, UDBG1, "%s thread (RT) priority = %d\n", + thread->name, bh_priority); + param.sched_priority = bh_priority; + sched_setscheduler(thread->thread_task, SCHED_FIFO, ¶m); + } else if (bh_priority > MAX_RT_PRIO && bh_priority <= MAX_PRIO) { + priv->bh_thread.prio = bh_priority; + unifi_trace(priv, UDBG1, "%s thread priority = %d\n", + thread->name, PRIO_TO_NICE(bh_priority)); + set_user_nice(thread->thread_task, PRIO_TO_NICE(bh_priority)); + } else { + priv->bh_thread.prio = DEFAULT_PRIO; + unifi_warning(priv, "%s thread unsupported (%d) priority\n", + thread->name, bh_priority); + } + } else { + priv->bh_thread.prio = DEFAULT_PRIO; + } + unifi_trace(priv, UDBG2, "Started %s thread\n", thread->name); + + return 0; +} /* uf_start_thread() */ + + +/* + * --------------------------------------------------------------------------- + * uf_stop_thread + * + * Helper function to stop a thread. + * + * Arguments: + * priv Pointer to OS driver structure for the device. + * thread Pointer to the thread object + * + * Returns: + * + * --------------------------------------------------------------------------- + */ + void +uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread) +{ + if (!thread->thread_task) { + unifi_notice(priv, "%s thread is already stopped\n", thread->name); + return; + } + + unifi_trace(priv, UDBG2, "Stopping %s thread\n", thread->name); + + kthread_stop(thread->thread_task); + thread->thread_task = NULL; + +} /* uf_stop_thread() */ + + + +/* + * --------------------------------------------------------------------------- + * uf_wait_for_thread_to_stop + * + * Helper function to wait until a thread is stopped. + * + * Arguments: + * priv Pointer to OS driver structure for the device. + * + * Returns: + * + * --------------------------------------------------------------------------- + */ + void +uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread) +{ + /* + * kthread_stop() cannot handle the thread exiting while + * kthread_should_stop() is false, so sleep until kthread_stop() + * wakes us up. + */ + unifi_trace(priv, UDBG2, "%s waiting for the stop signal.\n", thread->name); + set_current_state(TASK_INTERRUPTIBLE); + if (!kthread_should_stop()) { + unifi_trace(priv, UDBG2, "%s schedule....\n", thread->name); + schedule(); + } + + thread->thread_task = NULL; + unifi_trace(priv, UDBG2, "%s exiting....\n", thread->name); +} /* uf_wait_for_thread_to_stop() */ + + +/* + * --------------------------------------------------------------------------- + * handle_bh_error + * + * This function reports an error returned from the HIP core bottom-half. + * Normally, implemented during the porting exercise, passing the error + * to the SME using unifi_sys_wifi_off_ind(). + * The SME will try to reset the device and go through + * the initialisation of the UniFi. + * + * Arguments: + * priv Pointer to OS driver structure for the device. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ + static void +handle_bh_error(unifi_priv_t *priv) +{ + u8 conf_param = CONFIG_IND_ERROR; + CsrUint8 interfaceTag = 0; /* used as a loop counter */ + + + /* Block unifi_run_bh() until the error has been handled. */ + priv->bh_thread.block_thread = 1; + + /* Consider UniFi to be uninitialised */ + priv->init_progress = UNIFI_INIT_NONE; + + /* Stop the network traffic */ + for( interfaceTag =0; interfaceTag interfacePriv[interfaceTag]; + if (interfacePriv->netdev_registered == 1) { + netif_carrier_off(priv->netdev[interfaceTag]); + } + } + +#ifdef CSR_NATIVE_LINUX + /* Force any client waiting on an mlme_wait_for_reply() to abort. */ + uf_abort_mlme(priv); + + /* Cancel any pending workqueue tasks */ + flush_workqueue(priv->unifi_workqueue); + +#endif /* CSR_NATIVE_LINUX */ + + unifi_error(priv, "handle_bh_error: fatal error is reported to the SME.\n"); + /* Notify the clients (SME or unifi_manager) for the error. */ + ul_log_config_ind(priv, &conf_param, sizeof(u8)); + +} /* handle_bh_error() */ + + + +/* + * --------------------------------------------------------------------------- + * bh_thread_function + * + * All hardware access happens in this thread. + * This means there is no need for locks on the hardware and we don't need + * to worry about reentrancy with the SDIO library. + * Provides and example implementation on how to call unifi_bh(), which + * is part of the HIP core API. + * + * It processes the events generated by unifi_run_bh() to serialise calls + * to unifi_bh(). It also demonstrates how the timeout parameter passed in + * and returned from unifi_bh() needs to be handled. + * + * Arguments: + * arg Pointer to OS driver structure for the device. + * + * Returns: + * None. + * + * Notes: + * When the bottom half of the driver needs to process signals, events, + * or simply the host status (i.e sleep mode), it invokes unifi_run_bh(). + * Since we need all SDIO transaction to be in a single thread, the + * unifi_run_bh() will wake up this thread to process it. + * + * --------------------------------------------------------------------------- + */ +static int +bh_thread_function(void *arg) +{ + unifi_priv_t *priv = (unifi_priv_t*)arg; + CsrResult csrResult; + long ret; + CsrUint32 timeout, t; + struct uf_thread *this_thread; + + unifi_trace(priv, UDBG2, "bh_thread_function starting\n"); + + this_thread = &priv->bh_thread; + + t = timeout = 0; + while (!kthread_should_stop()) { + /* wait until an error occurs, or we need to process something. */ + unifi_trace(priv, UDBG3, "bh_thread goes to sleep.\n"); + + if (timeout > 0) { + /* Convert t in ms to jiffies */ + t = msecs_to_jiffies(timeout); + ret = wait_event_interruptible_timeout(this_thread->wakeup_q, + (this_thread->wakeup_flag && !this_thread->block_thread) || + kthread_should_stop(), + t); + timeout = (ret > 0) ? jiffies_to_msecs(ret) : 0; + } else { + ret = wait_event_interruptible(this_thread->wakeup_q, + (this_thread->wakeup_flag && !this_thread->block_thread) || + kthread_should_stop()); + } + + if (kthread_should_stop()) { + unifi_trace(priv, UDBG2, "bh_thread: signalled to exit\n"); + break; + } + + if (ret < 0) { + unifi_notice(priv, + "bh_thread: wait_event returned %d, thread will exit\n", + ret); + uf_wait_for_thread_to_stop(priv, this_thread); + break; + } + + this_thread->wakeup_flag = 0; + + unifi_trace(priv, UDBG3, "bh_thread calls unifi_bh().\n"); + + CsrSdioClaim(priv->sdio); + csrResult = unifi_bh(priv->card, &timeout); + if(csrResult != CSR_RESULT_SUCCESS) { + if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) { + CsrSdioRelease(priv->sdio); + uf_wait_for_thread_to_stop(priv, this_thread); + break; + } + /* Errors must be delivered to the error task */ + handle_bh_error(priv); + } + CsrSdioRelease(priv->sdio); + } + + /* + * I would normally try to call csr_sdio_remove_irq() here to make sure + * that we do not get any interrupts while this thread is not running. + * However, the MMC/SDIO driver tries to kill its' interrupt thread. + * The kernel threads implementation does not allow to kill threads + * from a signalled to stop thread. + * So, instead call csr_sdio_linux_remove_irq() always after calling + * uf_stop_thread() to kill this thread. + */ + + unifi_trace(priv, UDBG2, "bh_thread exiting....\n"); + return 0; +} /* bh_thread_function() */ + + +/* + * --------------------------------------------------------------------------- + * uf_init_bh + * + * Helper function to start the bottom half of the driver. + * All we need to do here is start the I/O bh thread. + * + * Arguments: + * priv Pointer to OS driver structure for the device. + * + * Returns: + * 0 on success or else a Linux error code. + * --------------------------------------------------------------------------- + */ + int +uf_init_bh(unifi_priv_t *priv) +{ + int r; + + /* Enable mlme interface. */ + priv->io_aborted = 0; + + + /* Start the BH thread */ + r = uf_start_thread(priv, &priv->bh_thread, bh_thread_function); + if (r) { + unifi_error(priv, + "uf_init_bh: failed to start the BH thread.\n"); + return r; + } + + /* Allow interrupts */ + r = csr_sdio_linux_install_irq(priv->sdio); + if (r) { + unifi_error(priv, + "uf_init_bh: failed to install the IRQ.\n"); + + uf_stop_thread(priv, &priv->bh_thread); + } + + return r; +} /* uf_init_bh() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_run_bh + * + * Part of the HIP core lib API, implemented in the porting exercise. + * The bottom half of the driver calls this function when + * it wants to process anything that requires access to unifi. + * We need to call unifi_bh() which in this implementation is done + * by waking up the I/O thread. + * + * Arguments: + * ospriv Pointer to OS driver structure for the device. + * + * Returns: + * 0 on success or else a Linux error code. + * + * Notes: + * --------------------------------------------------------------------------- + */ +CsrResult unifi_run_bh(void *ospriv) +{ + unifi_priv_t *priv = ospriv; + + /* + * If an error has occured, we discard silently all messages from the bh + * until the error has been processed and the unifi has been reinitialised. + */ + if (priv->bh_thread.block_thread == 1) { + unifi_trace(priv, UDBG3, "unifi_run_bh: discard message.\n"); + /* + * Do not try to acknowledge a pending interrupt here. + * This function is called by unifi_send_signal() which in turn can be + * running in an atomic or 'disabled irq' level if a signal is sent + * from a workqueue task (i.e multicass addresses set). + * We can not hold the SDIO lock because it might sleep. + */ + return CSR_RESULT_FAILURE; + } + + priv->bh_thread.wakeup_flag = 1; + /* wake up I/O thread */ + wake_up_interruptible(&priv->bh_thread.wakeup_q); + + return CSR_RESULT_SUCCESS; +} /* unifi_run_bh() */ + diff --git a/drivers/staging/csr/csr_formatted_io.c b/drivers/staging/csr/csr_formatted_io.c new file mode 100644 index 000000000000..bd6456bcf866 --- /dev/null +++ b/drivers/staging/csr/csr_formatted_io.c @@ -0,0 +1,29 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_formatted_io.h" +#include "csr_util.h" + +CsrInt32 CsrSnprintf(CsrCharString *dest, CsrSize n, const CsrCharString *fmt, ...) +{ + CsrInt32 r; + va_list args; + va_start(args, fmt); + r = CsrVsnprintf(dest, n, fmt, args); + va_end(args); + + if (dest && (n > 0)) + { + dest[n - 1] = '\0'; + } + + return r; +} diff --git a/drivers/staging/csr/csr_formatted_io.h b/drivers/staging/csr/csr_formatted_io.h new file mode 100644 index 000000000000..b458eb5ce9cd --- /dev/null +++ b/drivers/staging/csr/csr_formatted_io.h @@ -0,0 +1,25 @@ +#ifndef CSR_FORMATTED_IO_H__ +#define CSR_FORMATTED_IO_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_types.h" + +CsrInt32 CsrSnprintf(CsrCharString *dest, CsrSize n, const CsrCharString *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c new file mode 100644 index 000000000000..0406a4b0f786 --- /dev/null +++ b/drivers/staging/csr/csr_framework_ext.c @@ -0,0 +1,213 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) +#include +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 19) +#include +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) +#include +#else +#include +#endif + +#include + +#include "csr_types.h" +#include "csr_framework_ext.h" +#include "csr_panic.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexCreate + * + * DESCRIPTION + * Create a mutex and return a handle to the created mutex. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_NO_MORE_MUTEXES in case of out of mutex resources + * CSR_FE_RESULT_INVALID_POINTER in case the mutexHandle pointer is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle) +{ + if (mutexHandle == NULL) + { + return CSR_FE_RESULT_INVALID_POINTER; + } + + sema_init(mutexHandle, 1); + + return CSR_RESULT_SUCCESS; +} + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexDestroy + * + * DESCRIPTION + * Destroy the previously created mutex. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrMutexDestroy(CsrMutexHandle *mutexHandle) +{ +} + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexLock + * + * DESCRIPTION + * Lock the mutex refered to by the provided handle. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle) +{ + if (mutexHandle == NULL) + { + return CSR_FE_RESULT_INVALID_POINTER; + } + + if (down_interruptible(mutexHandle)) + { + CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_UNEXPECTED_VALUE, "CsrMutexLock Failed"); + return CSR_FE_RESULT_INVALID_POINTER; + } + + return CSR_RESULT_SUCCESS; +} + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexUnlock + * + * DESCRIPTION + * Unlock the mutex refered to by the provided handle. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle) +{ + if (mutexHandle == NULL) + { + return CSR_FE_RESULT_INVALID_POINTER; + } + + up(mutexHandle); + + return CSR_RESULT_SUCCESS; +} + +/*----------------------------------------------------------------------------* + * NAME + * CsrThreadSleep + * + * DESCRIPTION + * Sleep for a given period. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrThreadSleep(CsrUint16 sleepTimeInMs) +{ + unsigned long t; + + /* Convert t in ms to jiffies and round up */ + t = ((sleepTimeInMs * HZ) + 999) / 1000; + schedule_timeout_uninterruptible(t); +} +EXPORT_SYMBOL_GPL(CsrThreadSleep); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemCalloc + * + * DESCRIPTION + * Allocate dynamic memory of a given size calculated as the + * numberOfElements times the elementSize. + * + * RETURNS + * Pointer to allocated memory, or NULL in case of failure. + * Allocated memory is zero initialised. + * + *----------------------------------------------------------------------------*/ +void *CsrMemCalloc(CsrSize numberOfElements, CsrSize elementSize) +{ + void *buf; + size_t size; + + size = numberOfElements * elementSize; + + buf = kmalloc(size, GFP_KERNEL); + if (buf != NULL) + { + memset(buf, 0, size); + } + + return buf; +} + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemAlloc + * + * DESCRIPTION + * Allocate dynamic memory of a given size. + * + * RETURNS + * Pointer to allocated memory, or NULL in case of failure. + * Allocated memory is not initialised. + * + *----------------------------------------------------------------------------*/ +void *CsrMemAlloc(CsrSize size) +{ + return kmalloc(size, GFP_KERNEL); +} +EXPORT_SYMBOL_GPL(CsrMemAlloc); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemFree + * + * DESCRIPTION + * Free dynamic allocated memory. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrMemFree(void *pointer) +{ + kfree(pointer); +} +EXPORT_SYMBOL_GPL(CsrMemFree); diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h new file mode 100644 index 000000000000..401bf2d547a3 --- /dev/null +++ b/drivers/staging/csr/csr_framework_ext.h @@ -0,0 +1,354 @@ +#ifndef CSR_FRAMEWORK_EXT_H__ +#define CSR_FRAMEWORK_EXT_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_result.h" +#include "csr_framework_ext_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Result codes */ +#define CSR_FE_RESULT_NO_MORE_EVENTS ((CsrResult) 0x0001) +#define CSR_FE_RESULT_INVALID_POINTER ((CsrResult) 0x0002) +#define CSR_FE_RESULT_INVALID_HANDLE ((CsrResult) 0x0003) +#define CSR_FE_RESULT_NO_MORE_MUTEXES ((CsrResult) 0x0004) +#define CSR_FE_RESULT_TIMEOUT ((CsrResult) 0x0005) +#define CSR_FE_RESULT_NO_MORE_THREADS ((CsrResult) 0x0006) + +/* Thread priorities */ +#define CSR_THREAD_PRIORITY_HIGHEST ((CsrUint16) 0) +#define CSR_THREAD_PRIORITY_HIGH ((CsrUint16) 1) +#define CSR_THREAD_PRIORITY_NORMAL ((CsrUint16) 2) +#define CSR_THREAD_PRIORITY_LOW ((CsrUint16) 3) +#define CSR_THREAD_PRIORITY_LOWEST ((CsrUint16) 4) + +#define CSR_EVENT_WAIT_INFINITE ((CsrUint16) 0xFFFF) + +/*----------------------------------------------------------------------------* + * NAME + * CsrEventCreate + * + * DESCRIPTION + * Creates an event and returns a handle to the created event. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_NO_MORE_EVENTS in case of out of event resources + * CSR_FE_RESULT_INVALID_POINTER in case the eventHandle pointer is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrEventCreate(CsrEventHandle *eventHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrEventWait + * + * DESCRIPTION + * Wait fore one or more of the event bits to be set. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_TIMEOUT in case of timeout + * CSR_FE_RESULT_INVALID_HANDLE in case the eventHandle is invalid + * CSR_FE_RESULT_INVALID_POINTER in case the eventBits pointer is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrEventWait(CsrEventHandle *eventHandle, CsrUint16 timeoutInMs, CsrUint32 *eventBits); + +/*----------------------------------------------------------------------------* + * NAME + * CsrEventSet + * + * DESCRIPTION + * Set an event. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_INVALID_HANDLE in case the eventHandle is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrEventSet(CsrEventHandle *eventHandle, CsrUint32 eventBits); + +/*----------------------------------------------------------------------------* + * NAME + * CsrEventDestroy + * + * DESCRIPTION + * Destroy the event associated. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrEventDestroy(CsrEventHandle *eventHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexCreate + * + * DESCRIPTION + * Create a mutex and return a handle to the created mutex. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_NO_MORE_MUTEXES in case of out of mutex resources + * CSR_FE_RESULT_INVALID_POINTER in case the mutexHandle pointer is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexLock + * + * DESCRIPTION + * Lock the mutex refered to by the provided handle. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexUnlock + * + * DESCRIPTION + * Unlock the mutex refered to by the provided handle. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMutexDestroy + * + * DESCRIPTION + * Destroy the previously created mutex. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrMutexDestroy(CsrMutexHandle *mutexHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrGlobalMutexLock + * + * DESCRIPTION + * Lock the global mutex. The global mutex is a single pre-initialised + * shared mutex, spinlock or similar that does not need to be created prior + * to use. The limitation is that there is only one single lock shared + * between all code. Consequently, it must only be used very briefly to + * either protect simple one-time initialisation or to protect the creation + * of a dedicated mutex by calling CsrMutexCreate. + * + *----------------------------------------------------------------------------*/ +void CsrGlobalMutexLock(void); + +/*----------------------------------------------------------------------------* + * NAME + * CsrGlobalMutexUnlock + * + * DESCRIPTION + * Unlock the global mutex. + * + *----------------------------------------------------------------------------*/ +void CsrGlobalMutexUnlock(void); + +/*----------------------------------------------------------------------------* + * NAME + * CsrThreadCreate + * + * DESCRIPTION + * Create thread function and return a handle to the created thread. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_NO_MORE_THREADS in case of out of thread resources + * CSR_FE_RESULT_INVALID_POINTER in case one of the supplied pointers is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrThreadCreate(void (*threadFunction)(void *pointer), void *pointer, + CsrUint32 stackSize, CsrUint16 priority, + const CsrCharString *threadName, CsrThreadHandle *threadHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrThreadGetHandle + * + * DESCRIPTION + * Return thread handle of calling thread. + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case of success + * CSR_FE_RESULT_INVALID_POINTER in case the threadHandle pointer is invalid + * + *----------------------------------------------------------------------------*/ +CsrResult CsrThreadGetHandle(CsrThreadHandle *threadHandle); + +/*----------------------------------------------------------------------------* + * NAME + * CsrThreadEqual + * + * DESCRIPTION + * Compare thread handles + * + * RETURNS + * Possible values: + * CSR_RESULT_SUCCESS in case thread handles are identical + * CSR_FE_RESULT_INVALID_POINTER in case either threadHandle pointer is invalid + * CSR_RESULT_FAILURE otherwise + * + *----------------------------------------------------------------------------*/ +CsrResult CsrThreadEqual(CsrThreadHandle *threadHandle1, CsrThreadHandle *threadHandle2); + +/*----------------------------------------------------------------------------* + * NAME + * CsrThreadSleep + * + * DESCRIPTION + * Sleep for a given period. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrThreadSleep(CsrUint16 sleepTimeInMs); + +#ifndef CSR_PMEM_DEBUG_ENABLE +/*----------------------------------------------------------------------------* + * NAME + * CsrMemAlloc + * + * DESCRIPTION + * Allocate dynamic memory of a given size. + * + * RETURNS + * Pointer to allocated memory, or NULL in case of failure. + * Allocated memory is not initialised. + * + *----------------------------------------------------------------------------*/ +#ifdef CSR_MEM_DEBUG +void *CsrMemAllocDebug(CsrSize size, + const CsrCharString *file, CsrUint32 line); +#define CsrMemAlloc(sz) CsrMemAllocDebug((sz), __FILE__, __LINE__) +#else +void *CsrMemAlloc(CsrSize size); +#endif + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemCalloc + * + * DESCRIPTION + * Allocate dynamic memory of a given size calculated as the + * numberOfElements times the elementSize. + * + * RETURNS + * Pointer to allocated memory, or NULL in case of failure. + * Allocated memory is zero initialised. + * + *----------------------------------------------------------------------------*/ +#ifdef CSR_MEM_DEBUG +void *CsrMemCallocDebug(CsrSize numberOfElements, CsrSize elementSize, + const CsrCharString *file, CsrUint32 line); +#define CsrMemCalloc(cnt, sz) CsrMemAllocDebug((cnt), (sz), __FILE__, __LINE__) +#else +void *CsrMemCalloc(CsrSize numberOfElements, CsrSize elementSize); +#endif + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemFree + * + * DESCRIPTION + * Free dynamic allocated memory. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrMemFree(void *pointer); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemAllocDma + * + * DESCRIPTION + * Allocate dynamic memory suitable for DMA transfers. + * + * RETURNS + * Pointer to allocated memory, or NULL in case of failure. + * Allocated memory is not initialised. + * + *----------------------------------------------------------------------------*/ +#ifdef CSR_MEM_DEBUG +void *CsrMemAllocDmaDebug(CsrSize size, + const CsrCharString *file, CsrUint32 line); +#define CsrMemAllocDma(sz) CsrMemAllocDmaDebug((sz), __FILE__, __LINE__) +#else +void *CsrMemAllocDma(CsrSize size); +#endif + + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemFreeDma + * + * DESCRIPTION + * Free dynamic memory allocated by CsrMemAllocDma. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrMemFreeDma(void *pointer); +#else + +#include "csr_pmem.h" + +#define CsrMemAlloc(size) CsrPmemDebugAlloc(size, CSR_PMEM_DEBUG_TYPE_MEM_ALLOC, __FILE__, __LINE__) + +#define CsrMemCalloc(numberOfElements, elementSize) CsrPmemDebugAlloc((numberOfElements * elementSize), CSR_PMEM_DEBUG_TYPE_MEM_CALLOC, __FILE__, __LINE__) + +#define CsrMemFree(ptr) CsrPmemDebugFree(ptr,CSR_PMEM_DEBUG_TYPE_MEM_ALLOC, __FILE__, __LINE__) + +#define CsrMemAllocDma(size) CsrPmemDebugAlloc(size, CSR_PMEM_DEBUG_TYPE_MEM_ALLOC_DMA, __FILE__, __LINE__) + +#define CsrMemFreeDma(ptr) CsrPmemDebugFree(ptr, CSR_PMEM_DEBUG_TYPE_MEM_ALLOC_DMA, __FILE__, __LINE__) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h new file mode 100644 index 000000000000..d155a2b8eee6 --- /dev/null +++ b/drivers/staging/csr/csr_framework_ext_types.h @@ -0,0 +1,65 @@ +#ifndef CSR_FRAMEWORK_EXT_TYPES_H__ +#define CSR_FRAMEWORK_EXT_TYPES_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" + +#ifdef __KERNEL__ +#include +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __KERNEL__ + +struct CsrThread +{ + struct task_struct *thread_task; + char name[16]; +}; + +struct CsrEvent +{ + /* wait_queue for waking the kernel thread */ + wait_queue_head_t wakeup_q; + unsigned int wakeup_flag; +}; + +typedef struct CsrEvent CsrEventHandle; +typedef struct semaphore CsrMutexHandle; +typedef struct CsrThread CsrThreadHandle; + +#else /* __KERNEL __ */ + +struct CsrEvent +{ + pthread_cond_t event; + pthread_mutex_t mutex; + CsrUint32 eventBits; +}; + +typedef struct CsrEvent CsrEventHandle; +typedef pthread_mutex_t CsrMutexHandle; +typedef pthread_t CsrThreadHandle; + +#endif /* __KERNEL__ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_lib.h b/drivers/staging/csr/csr_lib.h new file mode 100644 index 000000000000..171f5feeea94 --- /dev/null +++ b/drivers/staging/csr/csr_lib.h @@ -0,0 +1,189 @@ +#ifndef CSR_LIB_H__ +#define CSR_LIB_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_prim_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + CsrPrim type; +} CsrEvent; + +/*----------------------------------------------------------------------------* + * CsrEvent_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEvent + * + *----------------------------------------------------------------------------*/ +CsrEvent *CsrEvent_struct(CsrUint16 primtype, CsrUint16 msgtype); + +typedef struct +{ + CsrPrim type; + CsrUint8 value; +} CsrEventCsrUint8; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint8_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint8 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint8 *CsrEventCsrUint8_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint8 value); + +typedef struct +{ + CsrPrim type; + CsrUint16 value; +} CsrEventCsrUint16; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint16_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint16 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint16 *CsrEventCsrUint16_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint16 value); + +typedef struct +{ + CsrPrim type; + CsrUint16 value1; + CsrUint8 value2; +} CsrEventCsrUint16CsrUint8; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint16CsrUint8_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint16CsrUint8 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint16CsrUint8 *CsrEventCsrUint16CsrUint8_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint16 value1, CsrUint8 value2); + +typedef struct +{ + CsrPrim type; + CsrUint16 value1; + CsrUint16 value2; +} CsrEventCsrUint16CsrUint16; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint16CsrUint16_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint16CsrUint16 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint16CsrUint16 *CsrEventCsrUint16CsrUint16_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint16 value1, CsrUint16 value2); + +typedef struct +{ + CsrPrim type; + CsrUint16 value1; + CsrUint32 value2; +} CsrEventCsrUint16CsrUint32; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint16_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint16 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint16CsrUint32 *CsrEventCsrUint16CsrUint32_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint16 value1, CsrUint32 value2); + +typedef struct +{ + CsrPrim type; + CsrUint16 value1; + CsrCharString *value2; +} CsrEventCsrUint16CsrCharString; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint16CsrCharString_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint16CsrCharString + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint16CsrCharString *CsrEventCsrUint16CsrCharString_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint16 value1, CsrCharString *value2); + +typedef struct +{ + CsrPrim type; + CsrUint32 value; +} CsrEventCsrUint32; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint32_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint32 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint32 *CsrEventCsrUint32_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint32 value); + +typedef struct +{ + CsrPrim type; + CsrUint32 value1; + CsrUint16 value2; +} CsrEventCsrUint32CsrUint16; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint32CsrUint16_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint32CsrUint16 + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint32CsrUint16 *CsrEventCsrUint32CsrUint16_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint32 value1, CsrUint32 value2); + +typedef struct +{ + CsrPrim type; + CsrUint32 value1; + CsrCharString *value2; +} CsrEventCsrUint32CsrCharString; + +/*----------------------------------------------------------------------------* + * CsrEventCsrUint32CsrCharString_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrEventCsrUint32CsrCharString + * + *----------------------------------------------------------------------------*/ +CsrEventCsrUint32CsrCharString *CsrEventCsrUint32CsrCharString_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrUint32 value1, CsrCharString *value2); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_LIB_H__ */ diff --git a/drivers/staging/csr/csr_log.h b/drivers/staging/csr/csr_log.h new file mode 100644 index 000000000000..db2653c30ea6 --- /dev/null +++ b/drivers/staging/csr/csr_log.h @@ -0,0 +1,250 @@ +#ifndef CSR_LOG_H__ +#define CSR_LOG_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_sched.h" +#include "csr_panic.h" +#include "csr_prim_defs.h" +#include "csr_msgconv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Log filtering + */ + +/*----------------------------------------------------*/ +/* Filtering on environment specific log levels */ +/*----------------------------------------------------*/ +typedef CsrUint32 CsrLogLevelEnvironment; +#define CSR_LOG_LEVEL_ENVIRONMENT_OFF ((CsrLogLevelEnvironment) 0x00000000) /* No environment data/events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_ACL ((CsrLogLevelEnvironment) 0x00000001) /* BlueCore Channel Interface HCI Acl data are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_HCI ((CsrLogLevelEnvironment) 0x00000002) /* BlueCore Channel Interface HCI Cmd/Evt data are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_SCO ((CsrLogLevelEnvironment) 0x00000004) /* BlueCore Channel Interface HCI Sco data are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_VENDOR ((CsrLogLevelEnvironment) 0x00000008) /* BlueCore Channel Interface HCI Vendor specific data are logged (This includes BCCMD, HQ, VM etc) */ +#define CSR_LOG_LEVEL_ENVIRONMENT_TRANSPORTS ((CsrLogLevelEnvironment) 0x00000010) /* Transport protocol data is logged (This includes transport protocols like BCSP, H4 etc.) */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_REG ((CsrLogLevelEnvironment) 0x00000020) /* Background Interrupt registration events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_UNREG ((CsrLogLevelEnvironment) 0x00000040) /* Background Interrupt unregistration events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_SET ((CsrLogLevelEnvironment) 0x00000080) /* Background Interrupt set events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_START ((CsrLogLevelEnvironment) 0x00000100) /* Background Interrupt start events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_DONE ((CsrLogLevelEnvironment) 0x00000200) /* Background Interrupt done events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_PROTO ((CsrLogLevelEnvironment) 0x00000400) /* Transport protocol events are logged */ +#define CSR_LOG_LEVEL_ENVIRONMENT_PROTO_LOC ((CsrLogLevelEnvironment) 0x00000800) /* The Location where the transport protocol event occured are logged NB: This is a supplement to CSR_LOG_LEVEL_ENVIRONMENT_PROTO, it has no effect without it */ +/* The bit masks between here are reserved for future usage */ +#define CSR_LOG_LEVEL_ENVIRONMENT_ALL ((CsrLogLevelEnvironment) 0xFFFFFFFF) /* All possible environment data/events are logged WARNING: By using this define the application also accepts future possible environment data/events in the logs */ + +/*----------------------------------------------------*/ +/* Filtering on task specific log levels */ +/*----------------------------------------------------*/ +typedef CsrUint32 CsrLogLevelTask; +#define CSR_LOG_LEVEL_TASK_OFF ((CsrLogLevelTask) 0x00000000) /* No events are logged for this task */ +#define CSR_LOG_LEVEL_TASK_TEXT ((CsrLogLevelTask) 0x00000001) /* Text strings printed by a task are logged NB: This bit does not affect the CSR_LOG_TEXT_LEVEL interface. This has to be configured separately */ +#define CSR_LOG_LEVEL_TASK_TEXT_LOC ((CsrLogLevelTask) 0x00000002) /* The locaction where the text string call occured are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_TEXT, it has no effect without it */ +#define CSR_LOG_LEVEL_TASK_STATE ((CsrLogLevelTask) 0x00000004) /* FSM state transitions in a task are logged */ +#define CSR_LOG_LEVEL_TASK_STATE_NAME ((CsrLogLevelTask) 0x00000008) /* The name of each state in a FSM state transition are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_STATE, it has no effect without it */ +#define CSR_LOG_LEVEL_TASK_STATE_LOC ((CsrLogLevelTask) 0x00000010) /* The location where the FSM state transition occured are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_STATE, it has no effect without it */ +#define CSR_LOG_LEVEL_TASK_TASK_SWITCH ((CsrLogLevelTask) 0x00000020) /* Activation and deactiation of a task are logged */ +#define CSR_LOG_LEVEL_TASK_MESSAGE_PUT ((CsrLogLevelTask) 0x00000080) /* Message put operations are logged */ +#define CSR_LOG_LEVEL_TASK_MESSAGE_PUT_LOC ((CsrLogLevelTask) 0x00000100) /* The location where a message was sent are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_MESSAGE_PUT, it has no effect without it */ +#define CSR_LOG_LEVEL_TASK_MESSAGE_GET ((CsrLogLevelTask) 0x00000200) /* Message get operations are logged */ +#define CSR_LOG_LEVEL_TASK_MESSAGE_QUEUE_PUSH ((CsrLogLevelTask) 0x00000400) /* Message push operations are logged */ +#define CSR_LOG_LEVEL_TASK_MESSAGE_QUEUE_POP ((CsrLogLevelTask) 0x00000800) /* Message pop operations are logged */ +#define CSR_LOG_LEVEL_TASK_PRIM_ONLY_TYPE ((CsrLogLevelTask) 0x00001000) /* Only the type of primitives in messages are logged. By default the entire primitive is serialized and logged */ +#define CSR_LOG_LEVEL_TASK_PRIM_APPLY_LIMIT ((CsrLogLevelTask) 0x00002000) /* An upper limit (defined by CSR_LOG_PRIM_SIZE_UPPER_LIMIT) is applied to how much of a primitive in a message are logged. NB: This limit is only applied if CSR_LOG_LEVEL_TASK_PRIM_ONLY_TYPE is _not_ defined */ +#define CSR_LOG_LEVEL_TASK_TIMER_IN ((CsrLogLevelTask) 0x00004000) /* TimedEventIn events are logged */ +#define CSR_LOG_LEVEL_TASK_TIMER_IN_LOC ((CsrLogLevelTask) 0x00008000) /* The location where a timer was started are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_TIMER_IN, it has no effect without it */ +#define CSR_LOG_LEVEL_TASK_TIMER_CANCEL ((CsrLogLevelTask) 0x00010000) /* TimedEventCancel events are logged */ +#define CSR_LOG_LEVEL_TASK_TIMER_CANCEL_LOC ((CsrLogLevelTask) 0x00020000) /* The location where a timer was cancelled are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_TIMER_CANCEL, it has no effect without it */ +#define CSR_LOG_LEVEL_TASK_TIMER_FIRE ((CsrLogLevelTask) 0x00040000) /* TimedEventFire events are logged */ +#define CSR_LOG_LEVEL_TASK_TIMER_DONE ((CsrLogLevelTask) 0x00080000) /* TimedEventDone events are logged */ +/* The bit masks between here are reserved for future usage */ +#define CSR_LOG_LEVEL_TASK_ALL ((CsrLogLevelTask) 0xFFFFFFFF & ~(CSR_LOG_LEVEL_TASK_PRIM_ONLY_TYPE | CSR_LOG_LEVEL_TASK_PRIM_APPLY_LIMIT)) /* All info possible to log for a task are logged. WARNING: By using this define the application also accepts future possible task data/events in the logs */ + +CsrBool CsrLogEnvironmentIsFiltered(CsrLogLevelEnvironment level); +CsrLogLevelTask CsrLogTaskFilterGet(CsrSchedQid taskId); +CsrBool CsrLogTaskIsFiltered(CsrSchedQid taskId, CsrLogLevelTask level); + +/* + * Logging stuff + */ +#define CSR_LOG_STRINGIFY_REAL(a) #a +#define CSR_LOG_STRINGIFY(a) CSR_LOG_STRINGIFY_REAL(a) + +#ifdef CSR_LOG_ASSERT_ENABLE +#define CSR_LOG_ASSERT(cond) \ + do { \ + if (!(cond)) \ + { \ + CsrCharString *panic_arg = "[" __FILE__ ":" CSR_LOG_STRINGIFY(__LINE__) "] - " CSR_LOG_STRINGIFY(cond); \ + CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_ASSERTION_FAIL, panic_arg); \ + } \ + } while (0) +#else +#define CSR_LOG_ASSERT(cond) +#endif + +typedef struct +{ + CsrUint16 primitiveType; + const CsrCharString *primitiveName; + CsrMsgConvMsgEntry *messageConv; /* Private - do not use */ +} CsrLogPrimitiveInformation; + +typedef struct +{ + const CsrCharString *techVer; + CsrUint32 primitiveInfoCount; + CsrLogPrimitiveInformation *primitiveInfo; +} CsrLogTechInformation; + +/*---------------------------------*/ +/* Tech logging */ +/*---------------------------------*/ +typedef CsrUint8 bitmask8_t; +typedef CsrUint16 bitmask16_t; +typedef CsrUint32 bitmask32_t; + +#ifdef CSR_LOG_ENABLE +#ifdef CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER +/* DEPRECATED - replaced by csr_log_text.h */ +#define CSR_LOG_TEXT(text) \ + do { \ + if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) \ + { \ + CsrLogTaskText(text, __LINE__, __FILE__); \ + } \ + } while (0) +#else +/* DEPRECATED - replaced by csr_log_text.h */ +#define CSR_LOG_TEXT(text) \ + do { \ + if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) \ + { \ + CsrLogTaskText(text, 0, NULL); \ + } \ + } while (0) +#endif +#else +#define CSR_LOG_TEXT(text) +#endif + +/* DEPRECATED - replaced by csr_log_text.h */ +void CsrLogTaskText(const CsrCharString *text, + CsrUint32 line, + const CsrCharString *file); + +#define CSR_LOG_STATE_TRANSITION_MASK_FSM_NAME (0x001) +#define CSR_LOG_STATE_TRANSITION_MASK_NEXT_STATE (0x002) +#define CSR_LOG_STATE_TRANSITION_MASK_NEXT_STATE_STR (0x004) +#define CSR_LOG_STATE_TRANSITION_MASK_PREV_STATE (0x008) +#define CSR_LOG_STATE_TRANSITION_MASK_PREV_STATE_STR (0x010) +#define CSR_LOG_STATE_TRANSITION_MASK_EVENT (0x020) +#define CSR_LOG_STATE_TRANSITION_MASK_EVENT_STR (0x040) + +/* DEPRECATED - replaced by csr_log_text.h */ +void CsrLogStateTransition(bitmask16_t mask, + CsrUint32 identifier, + const CsrCharString *fsm_name, + CsrUint32 prev_state, + const CsrCharString *prev_state_str, + CsrUint32 in_event, + const CsrCharString *in_event_str, + CsrUint32 next_state, + const CsrCharString *next_state_str, + CsrUint32 line, + const CsrCharString *file); + +/*---------------------------------*/ +/* BSP logging */ +/*---------------------------------*/ +void CsrLogSchedInit(CsrUint8 thread_id); +void CsrLogSchedDeinit(CsrUint8 thread_id); + +void CsrLogSchedStart(CsrUint8 thread_id); +void CsrLogSchedStop(CsrUint8 thread_id); + +void CsrLogInitTask(CsrUint8 thread_id, CsrSchedQid tskid, const CsrCharString *tskName); +void CsrLogDeinitTask(CsrUint16 task_id); + +void CsrLogActivate(CsrSchedQid tskid); +void CsrLogDeactivate(CsrSchedQid tskid); + +#define SYNERGY_SERIALIZER_TYPE_DUMP (0x000) +#define SYNERGY_SERIALIZER_TYPE_SER (0x001) + +void CsrLogMessagePut(CsrUint32 line, + const CsrCharString *file, + CsrSchedQid src_task_id, + CsrSchedQid dst_taskid, + CsrSchedMsgId msg_id, + CsrUint16 prim_type, + const void *msg); + +void CsrLogMessageGet(CsrSchedQid src_task_id, + CsrSchedQid dst_taskid, + CsrBool get_res, + CsrSchedMsgId msg_id, + CsrUint16 prim_type, + const void *msg); + +void CsrLogTimedEventIn(CsrUint32 line, + const CsrCharString *file, + CsrSchedQid task_id, + CsrSchedTid tid, + CsrTime requested_delay, + CsrUint16 fniarg, + const void *fnvarg); + +void CsrLogTimedEventFire(CsrSchedQid task_id, + CsrSchedTid tid); + +void CsrLogTimedEventDone(CsrSchedQid task_id, + CsrSchedTid tid); + +void CsrLogTimedEventCancel(CsrUint32 line, + const CsrCharString *file, + CsrSchedQid task_id, + CsrSchedTid tid, + CsrBool cancel_res); + +void CsrLogBgintRegister(CsrUint8 thread_id, + CsrSchedBgint irq, + const CsrCharString *callback, + const void *ptr); +void CsrLogBgintUnregister(CsrSchedBgint irq); +void CsrLogBgintSet(CsrSchedBgint irq); +void CsrLogBgintServiceStart(CsrSchedBgint irq); +void CsrLogBgintServiceDone(CsrSchedBgint irq); + +void CsrLogExceptionStateEvent(CsrUint16 prim_type, + CsrPrim msg_type, + CsrUint16 state, + CsrUint32 line, + const CsrCharString *file); +void CsrLogExceptionGeneral(CsrUint16 prim_type, + CsrUint16 state, + const CsrCharString *text, + CsrUint32 line, + const CsrCharString *file); +void CsrLogExceptionWarning(CsrUint16 prim_type, + CsrUint16 state, + const CsrCharString *text, + CsrUint32 line, + const CsrCharString *file); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_log_configure.h b/drivers/staging/csr/csr_log_configure.h new file mode 100644 index 000000000000..3d48bf9762ea --- /dev/null +++ b/drivers/staging/csr/csr_log_configure.h @@ -0,0 +1,135 @@ +#ifndef CSR_LOG_CONFIGURE_H__ +#define CSR_LOG_CONFIGURE_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------*/ +/* Log init/deinit */ +/*---------------------------------*/ +void CsrLogInit(CsrUint8 size); +void CsrLogDeinit(void); + +/*---------------------------------*/ +/* Log Framework Tech info */ +/*---------------------------------*/ +void CsrLogTechInfoRegister(void); + +/* Set the logging level for the environment outside the scheduler context */ +void CsrLogLevelEnvironmentSet(CsrLogLevelEnvironment environmentLogLevel); + + +/* Set the logging level for all scheduler tasks */ +/* This function call takes precedence over all previous calls to CsrLogLevelTaskSetSpecific() */ +void CsrLogLevelTaskSetAll(CsrLogLevelTask tasksLogLevelMask); + +/* Set the logging level for a given Task */ +/* This function can be used as a complement to CsrLogLevelTaskSetAll() to add more _or_ less log from a given task than what is set +generally with CsrLogLevelTaskSetAll(). */ +void CsrLogLevelTaskSetSpecific(CsrSchedQid taskId, CsrLogLevelTask taskLogLevelMask); + + +/*--------------------------------------------*/ +/* Filtering on log text warning levels */ +/*--------------------------------------------*/ +typedef CsrUint32 CsrLogLevelText; +#define CSR_LOG_LEVEL_TEXT_OFF ((CsrLogLevelText) 0x0000) + +#define CSR_LOG_LEVEL_TEXT_CRITICAL ((CsrLogLevelText) 0x0001) +#define CSR_LOG_LEVEL_TEXT_ERROR ((CsrLogLevelText) 0x0002) +#define CSR_LOG_LEVEL_TEXT_WARNING ((CsrLogLevelText) 0x0004) +#define CSR_LOG_LEVEL_TEXT_INFO ((CsrLogLevelText) 0x0008) +#define CSR_LOG_LEVEL_TEXT_DEBUG ((CsrLogLevelText) 0x0010) + +#define CSR_LOG_LEVEL_TEXT_ALL ((CsrLogLevelText) 0xFFFF) + +/* The log text interface is used by both scheduler tasks and components outside the scheduler context. + * Therefore a CsrLogTextTaskId is introduced. It is effectively considered as two CsrUint16's. The lower + * 16 bits corresponds one2one with the scheduler queueId's (CsrSchedQid) and as such these bits can not be used + * by components outside scheduler tasks. The upper 16 bits are allocated for use of components outside the + * scheduler like drivers etc. Components in this range is defined independently by each technology. To avoid + * clashes the technologies are only allowed to assign values within the same restrictive range as allies to + * primitive identifiers. eg. for the framework components outside the scheduler is only allowed to assign + * taskId's in the range 0x0600xxxx to 0x06FFxxxx. And so on for other technologies. */ +typedef CsrUint32 CsrLogTextTaskId; + +/* Set the text logging level for all Tasks */ +/* This function call takes precedence over all previous calls to CsrLogLevelTextSetTask() and CsrLogLevelTextSetTaskSubOrigin() */ +void CsrLogLevelTextSetAll(CsrLogLevelText warningLevelMask); + +/* Set the text logging level for a given Task */ +/* This function call takes precedence over all previous calls to CsrLogLevelTextSetTaskSubOrigin(), but it can be used as a complement to + * CsrLogLevelTextSetAll() to add more _or_ less log from a given task than what is set generally with CsrLogLevelTextSetAll(). */ +void CsrLogLevelTextSetTask(CsrLogTextTaskId taskId, CsrLogLevelText warningLevelMask); + +/* Set the text logging level for a given tasks subOrigin */ +/* This function can be used as a complement to CsrLogLevelTextSetAll() and CsrLogLevelTextSetTask() to add more _or_ less log from a given + * subOrigin within a task than what is set generally with CsrLogLevelTextSetAll() _or_ CsrLogLevelTextSetTask(). */ +void CsrLogLevelTextSetTaskSubOrigin(CsrLogTextTaskId taskId, CsrUint16 subOrigin, CsrLogLevelText warningLevelMask); + +/******************************************************************************* + + NAME + CsrLogLevelTextSet + + DESCRIPTION + Set the text logging level for a given origin and optionally sub origin + by name. If either string is NULL or zero length, it is interpreted as + all origins and/or all sub origins respectively. If originName is NULL + or zero length, subOriginName is ignored. + + Passing NULL or zero length strings in both originName and subOriginName + is equivalent to calling CsrLogLevelTextSetAll, and overrides all + previous filter configurations for all origins and sub origins. + + Passing NULL or a zero length string in subOriginName overrides all + previous filter configurations for all sub origins of the specified + origin. + + Note: the supplied strings may be accessed after the function returns + and must remain valid and constant until CsrLogDeinit is called. + + Note: when specifying an origin (originName is not NULL and not zero + length), this function can only be used for origins that use the + csr_log_text_2.h interface for registration and logging. Filtering for + origins that use the legacy csr_log_text.h interface must be be + configured using the legacy filter configuration functions that accept + a CsrLogTextTaskId as origin specifier. However, when not specifying an + origin this function also affects origins that have been registered with + the legacy csr_log_text.h interface. Furthermore, using this function + and the legacy filter configuration functions on the same origin is not + allowed. + + PARAMETERS + originName - a string containing the name of the origin. Can be NULL or + zero length to set the log level for all origins. In this case, the + subOriginName parameter will be ignored. + subOriginName - a string containing the name of the sub origin. Can be + NULL or zero length to set the log level for all sub origins of the + specified origin. + warningLevelMask - The desired log level for the specified origin(s) and + sub origin(s). + +*******************************************************************************/ +void CsrLogLevelTextSet(const CsrCharString *originName, + const CsrCharString *subOriginName, + CsrLogLevelText warningLevelMask); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_log_text.h b/drivers/staging/csr/csr_log_text.h new file mode 100644 index 000000000000..6e0df43c008e --- /dev/null +++ b/drivers/staging/csr/csr_log_text.h @@ -0,0 +1,133 @@ +#ifndef CSR_LOG_TEXT_H__ +#define CSR_LOG_TEXT_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_log_configure.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CsrLogSubOrigin +{ + CsrUint16 subOriginNumber; /* Id of the given SubOrigin */ + const CsrCharString *subOriginName; /* Prefix Text for this SubOrigin */ +} CsrLogSubOrigin; + +/* Register a task which is going to use the CSR_LOG_TEXT_XXX interface */ +#ifdef CSR_LOG_ENABLE +void CsrLogTextRegister(CsrLogTextTaskId taskId, const CsrCharString *taskName, CsrUint16 subOriginsLength, const CsrLogSubOrigin *subOrigins); +#else +#define CsrLogTextRegister(taskId, taskName, subOriginsLength, subOrigins) +#endif + +/* CRITICAL: Conditions that are threatening to the integrity/stability of the + system as a whole. */ +#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_CRITICAL_DISABLE) +void CsrLogTextCritical(CsrLogTextTaskId taskId, CsrUint16 subOrigin, const CsrCharString *formatString, ...); +void CsrLogTextBufferCritical(CsrLogTextTaskId taskId, CsrUint16 subOrigin, CsrSize bufferLength, const void *buffer, const CsrCharString *formatString, ...); +#define CSR_LOG_TEXT_CRITICAL(taskId_subOrigin_formatString_varargs) CsrLogTextCritical taskId_subOrigin_formatString_varargs +#define CSR_LOG_TEXT_CONDITIONAL_CRITICAL(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_CRITICAL(logtextargs);}} +#define CSR_LOG_TEXT_BUFFER_CRITICAL(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferCritical taskId_subOrigin_length_buffer_formatString_varargs +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_CRITICAL(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_CRITICAL(logtextbufferargs);}} +#else +#define CSR_LOG_TEXT_CRITICAL(taskId_subOrigin_formatString_varargs) +#define CSR_LOG_TEXT_CONDITIONAL_CRITICAL(condition, logtextargs) +#define CSR_LOG_TEXT_BUFFER_CRITICAL(taskId_subOrigin_length_buffer_formatString_varargs) +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_CRITICAL(condition, logtextbufferargs) +#endif + +/* ERROR: Malfunction of a component rendering it unable to operate correctly, + causing lack of functionality but not loss of system integrity/stability. */ +#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_ERROR_DISABLE) +void CsrLogTextError(CsrLogTextTaskId taskId, CsrUint16 subOrigin, const CsrCharString *formatString, ...); +void CsrLogTextBufferError(CsrLogTextTaskId taskId, CsrUint16 subOrigin, CsrSize bufferLength, const void *buffer, const CsrCharString *formatString, ...); +#define CSR_LOG_TEXT_ERROR(taskId_subOrigin_formatString_varargs) CsrLogTextError taskId_subOrigin_formatString_varargs +#define CSR_LOG_TEXT_CONDITIONAL_ERROR(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_ERROR(logtextargs);}} +#define CSR_LOG_TEXT_BUFFER_ERROR(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferError taskId_subOrigin_length_buffer_formatString_varargs +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_ERROR(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_ERROR(logtextbufferargs);}} +#else +#define CSR_LOG_TEXT_ERROR(taskId_subOrigin_formatString_varargs) +#define CSR_LOG_TEXT_CONDITIONAL_ERROR(condition, logtextargs) +#define CSR_LOG_TEXT_BUFFER_ERROR(taskId_subOrigin_length_buffer_formatString_varargs) +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_ERROR(condition, logtextbufferargs) +#endif + +/* WARNING: Conditions that are unexpected and indicative of possible problems + or violations of specifications, where the result of such deviations does not + lead to malfunction of the component. */ +#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_WARNING_DISABLE) +void CsrLogTextWarning(CsrLogTextTaskId taskId, CsrUint16 subOrigin, const CsrCharString *formatString, ...); +void CsrLogTextBufferWarning(CsrLogTextTaskId taskId, CsrUint16 subOrigin, CsrSize bufferLength, const void *buffer, const CsrCharString *formatString, ...); +#define CSR_LOG_TEXT_WARNING(taskId_subOrigin_formatString_varargs) CsrLogTextWarning taskId_subOrigin_formatString_varargs +#define CSR_LOG_TEXT_CONDITIONAL_WARNING(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_WARNING(logtextargs);}} +#define CSR_LOG_TEXT_BUFFER_WARNING(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferWarning taskId_subOrigin_length_buffer_formatString_varargs +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_WARNING(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_WARNING(logtextbufferargs);}} +#else +#define CSR_LOG_TEXT_WARNING(taskId_subOrigin_formatString_varargs) +#define CSR_LOG_TEXT_CONDITIONAL_WARNING(condition, logtextargs) +#define CSR_LOG_TEXT_BUFFER_WARNING(taskId_subOrigin_length_buffer_formatString_varargs) +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_WARNING(condition, logtextbufferargs) +#endif + +/* INFO: Important events that may aid in determining the conditions under which + the more severe conditions are encountered. */ +#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_INFO_DISABLE) +void CsrLogTextInfo(CsrLogTextTaskId taskId, CsrUint16 subOrigin, const CsrCharString *formatString, ...); +void CsrLogTextBufferInfo(CsrLogTextTaskId taskId, CsrUint16 subOrigin, CsrSize bufferLength, const void *buffer, const CsrCharString *formatString, ...); +#define CSR_LOG_TEXT_INFO(taskId_subOrigin_formatString_varargs) CsrLogTextInfo taskId_subOrigin_formatString_varargs +#define CSR_LOG_TEXT_CONDITIONAL_INFO(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_INFO(logtextargs);}} +#define CSR_LOG_TEXT_BUFFER_INFO(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferInfo taskId_subOrigin_length_buffer_formatString_varargs +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_INFO(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_INFO(logtextbufferargs);}} +#else +#define CSR_LOG_TEXT_INFO(taskId_subOrigin_formatString_varargs) +#define CSR_LOG_TEXT_CONDITIONAL_INFO(condition, logtextargs) +#define CSR_LOG_TEXT_BUFFER_INFO(taskId_subOrigin_length_buffer_formatString_varargs) +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_INFO(condition, logtextbufferargs) +#endif + +/* DEBUG: Similar to INFO, but dedicated to events that occur more frequently. */ +#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_DEBUG_DISABLE) +void CsrLogTextDebug(CsrLogTextTaskId taskId, CsrUint16 subOrigin, const CsrCharString *formatString, ...); +void CsrLogTextBufferDebug(CsrLogTextTaskId taskId, CsrUint16 subOrigin, CsrSize bufferLength, const void *buffer, const CsrCharString *formatString, ...); +#define CSR_LOG_TEXT_DEBUG(taskId_subOrigin_formatString_varargs) CsrLogTextDebug taskId_subOrigin_formatString_varargs +#define CSR_LOG_TEXT_CONDITIONAL_DEBUG(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_DEBUG(logtextargs);}} +#define CSR_LOG_TEXT_BUFFER_DEBUG(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferDebug taskId_subOrigin_length_buffer_formatString_varargs +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_DEBUG(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_DEBUG(logtextbufferargs);}} +#else +#define CSR_LOG_TEXT_DEBUG(taskId_subOrigin_formatString_varargs) +#define CSR_LOG_TEXT_CONDITIONAL_DEBUG(condition, logtextargs) +#define CSR_LOG_TEXT_BUFFER_DEBUG(taskId_subOrigin_length_buffer_formatString_varargs) +#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_DEBUG(condition, logtextbufferargs) +#endif + +/* CSR_LOG_TEXT_ASSERT (CRITICAL) */ +#ifdef CSR_LOG_ENABLE +#define CSR_LOG_TEXT_ASSERT(origin, suborigin, condition) \ + {if (!(condition)) {CSR_LOG_TEXT_CRITICAL((origin, suborigin, "Assertion \"%s\" failed at %s:%u", #condition, __FILE__, __LINE__));}} +#else +#define CSR_LOG_TEXT_ASSERT(origin, suborigin, condition) +#endif + +/* CSR_LOG_TEXT_UNHANDLED_PRIM (CRITICAL) */ +#ifdef CSR_LOG_ENABLE +#define CSR_LOG_TEXT_UNHANDLED_PRIMITIVE(origin, suborigin, primClass, primType) \ + CSR_LOG_TEXT_CRITICAL((origin, suborigin, "Unhandled primitive 0x%04X:0x%04X at %s:%u", primClass, primType, __FILE__, __LINE__)) +#else +#define CSR_LOG_TEXT_UNHANDLED_PRIMITIVE(origin, suborigin, primClass, primType) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_macro.h b/drivers/staging/csr/csr_macro.h new file mode 100644 index 000000000000..2e3dcac4f331 --- /dev/null +++ b/drivers/staging/csr/csr_macro.h @@ -0,0 +1,111 @@ +#ifndef CSR_MACRO_H__ +#define CSR_MACRO_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------*/ +/* Bits - intended to operate on CsrUint32 values */ +/*------------------------------------------------------------------*/ +#define CSR_MASK_IS_SET(val, mask) (((val) & (mask)) == (mask)) +#define CSR_MASK_IS_UNSET(val, mask) ((((val) & (mask)) ^ mask) == (mask)) +#define CSR_MASK_SET(val, mask) ((val) |= (mask)) +#define CSR_MASK_UNSET(val, mask) ((val) = ((val) ^ (mask)) & (val)) /* Unsets the bits in val that are set in mask */ +#define CSR_BIT_IS_SET(val, bit) ((CsrBool) ((((val) & (1UL << (bit))) != 0))) +#define CSR_BIT_SET(val, bit) ((val) |= (1UL << (bit))) +#define CSR_BIT_UNSET(val, bit) ((val) &= ~(1UL << (bit))) +#define CSR_BIT_TOGGLE(val, bit) ((val) ^= (1UL << (bit))) + +/*------------------------------------------------------------------*/ +/* Endian conversion */ +/*------------------------------------------------------------------*/ +#define CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr) (((CsrUint16) ((CsrUint8 *) (ptr))[0]) | ((CsrUint16) ((CsrUint8 *) (ptr))[1]) << 8) +#define CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr) (((CsrUint32) ((CsrUint8 *) (ptr))[0]) | ((CsrUint32) ((CsrUint8 *) (ptr))[1]) << 8 | \ + ((CsrUint32) ((CsrUint8 *) (ptr))[2]) << 16 | ((CsrUint32) ((CsrUint8 *) (ptr))[3]) << 24) +#define CSR_COPY_UINT16_TO_LITTLE_ENDIAN(uint, ptr) ((CsrUint8 *) (ptr))[0] = ((CsrUint8) ((uint) & 0x00FF)); \ + ((CsrUint8 *) (ptr))[1] = ((CsrUint8) ((uint) >> 8)) +#define CSR_COPY_UINT32_TO_LITTLE_ENDIAN(uint, ptr) ((CsrUint8 *) (ptr))[0] = ((CsrUint8) ((uint) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[1] = ((CsrUint8) (((uint) >> 8) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[2] = ((CsrUint8) (((uint) >> 16) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[3] = ((CsrUint8) (((uint) >> 24) & 0x000000FF)) +#define CSR_GET_UINT16_FROM_BIG_ENDIAN(ptr) (((CsrUint16) ((CsrUint8 *) (ptr))[1]) | ((CsrUint16) ((CsrUint8 *) (ptr))[0]) << 8) +#define CSR_GET_UINT24_FROM_BIG_ENDIAN(ptr) (((CsrUint24) ((CsrUint8 *) (ptr))[2]) | \ + ((CsrUint24) ((CsrUint8 *) (ptr))[1]) << 8 | ((CsrUint24) ((CsrUint8 *) (ptr))[0]) << 16) +#define CSR_GET_UINT32_FROM_BIG_ENDIAN(ptr) (((CsrUint32) ((CsrUint8 *) (ptr))[3]) | ((CsrUint32) ((CsrUint8 *) (ptr))[2]) << 8 | \ + ((CsrUint32) ((CsrUint8 *) (ptr))[1]) << 16 | ((CsrUint32) ((CsrUint8 *) (ptr))[0]) << 24) +#define CSR_COPY_UINT16_TO_BIG_ENDIAN(uint, ptr) ((CsrUint8 *) (ptr))[1] = ((CsrUint8) ((uint) & 0x00FF)); \ + ((CsrUint8 *) (ptr))[0] = ((CsrUint8) ((uint) >> 8)) +#define CSR_COPY_UINT24_TO_BIG_ENDIAN(uint, ptr) ((CsrUint8 *) (ptr))[2] = ((CsrUint8) ((uint) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[1] = ((CsrUint8) (((uint) >> 8) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[0] = ((CsrUint8) (((uint) >> 16) & 0x000000FF)) +#define CSR_COPY_UINT32_TO_BIG_ENDIAN(uint, ptr) ((CsrUint8 *) (ptr))[3] = ((CsrUint8) ((uint) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[2] = ((CsrUint8) (((uint) >> 8) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[1] = ((CsrUint8) (((uint) >> 16) & 0x000000FF)); \ + ((CsrUint8 *) (ptr))[0] = ((CsrUint8) (((uint) >> 24) & 0x000000FF)) + +/*------------------------------------------------------------------*/ +/* XAP conversion macros */ +/*------------------------------------------------------------------*/ + +#define CSR_LSB16(a) ((CsrUint8) ((a) & 0x00ff)) +#define CSR_MSB16(b) ((CsrUint8) ((b) >> 8)) + +#define CSR_CONVERT_8_FROM_XAP(output, input) \ + (output) = ((CsrUint8) (input));(input) += 2 + +#define CSR_CONVERT_16_FROM_XAP(output, input) \ + (output) = (CsrUint16) ((((CsrUint16) (input)[1]) << 8) | \ + ((CsrUint16) (input)[0]));(input) += 2 + +#define CSR_CONVERT_32_FROM_XAP(output, input) \ + (output) = (((CsrUint32) (input)[1]) << 24) | \ + (((CsrUint32) (input)[0]) << 16) | \ + (((CsrUint32) (input)[3]) << 8) | \ + ((CsrUint32) (input)[2]);input += 4 + +#define CSR_ADD_UINT8_TO_XAP(output, input) \ + (output)[0] = (input); \ + (output)[1] = 0;(output) += 2 + +#define CSR_ADD_UINT16_TO_XAP(output, input) \ + (output)[0] = ((CsrUint8) ((input) & 0x00FF)); \ + (output)[1] = ((CsrUint8) ((input) >> 8));(output) += 2 + +#define CSR_ADD_UINT32_TO_XAP(output, input) \ + (output)[0] = ((CsrUint8) (((input) >> 16) & 0x00FF)); \ + (output)[1] = ((CsrUint8) ((input) >> 24)); \ + (output)[2] = ((CsrUint8) ((input) & 0x00FF)); \ + (output)[3] = ((CsrUint8) (((input) >> 8) & 0x00FF));(output) += 4 + +/*------------------------------------------------------------------*/ +/* Misc */ +/*------------------------------------------------------------------*/ +#define CSRMAX(a, b) (((a) > (b)) ? (a) : (b)) +#define CSRMIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* Use this macro on unused local variables that cannot be removed (such as + unused function parameters). This will quell warnings from certain compilers + and static code analysis tools like Lint and Valgrind. */ +#define CSR_UNUSED(x) ((void) (x)) + +#define CSR_TOUPPER(character) (((character) >= 'a') && ((character) <= 'z') ? ((character) - 0x20) : (character)) +#define CSR_TOLOWER(character) (((character) >= 'A') && ((character) <= 'Z') ? ((character) + 0x20) : (character)) +#define CSR_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_msg_transport.h b/drivers/staging/csr/csr_msg_transport.h new file mode 100644 index 000000000000..b0095b023817 --- /dev/null +++ b/drivers/staging/csr/csr_msg_transport.h @@ -0,0 +1,25 @@ +#ifndef CSR_MSG_TRANSPORT_H__ +#define CSR_MSG_TRANSPORT_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CsrMsgTransport +#define CsrMsgTransport CsrSchedMessagePut +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_MSG_TRANSPORT */ diff --git a/drivers/staging/csr/csr_msgconv.c b/drivers/staging/csr/csr_msgconv.c new file mode 100644 index 000000000000..9f1c946c66f9 --- /dev/null +++ b/drivers/staging/csr/csr_msgconv.c @@ -0,0 +1,324 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_panic.h" +#include "csr_sched.h" +#include "csr_msgconv.h" +#include "csr_util.h" + +static CsrMsgConvEntry *converter; + +CsrMsgConvPrimEntry *CsrMsgConvFind(CsrUint16 primType) +{ + CsrMsgConvPrimEntry *ptr = NULL; + + if (converter) + { + ptr = converter->profile_converters; + while (ptr) + { + if (ptr->primType == primType) + { + break; + } + else + { + ptr = ptr->next; + } + } + } + + return ptr; +} + +static const CsrMsgConvMsgEntry *find_msg_converter(CsrMsgConvPrimEntry *ptr, CsrUint16 msgType) +{ + const CsrMsgConvMsgEntry *cv = ptr->conv; + if (ptr->lookupFunc) + { + return (const CsrMsgConvMsgEntry *) ptr->lookupFunc((CsrMsgConvMsgEntry *) cv, msgType); + } + + while (cv) + { + if (cv->serFunc == NULL) + { + /* We've reached the end of the chain */ + cv = NULL; + break; + } + + if (cv->msgType == msgType) + { + break; + } + else + { + cv++; + } + } + + return cv; +} + +static void *deserialize_data(CsrUint16 primType, + CsrSize length, + CsrUint8 *data) +{ + CsrMsgConvPrimEntry *ptr; + CsrUint8 *ret; + + ptr = CsrMsgConvFind(primType); + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + CsrUint16 msgId = 0; + CsrSize offset = 0; + CsrUint16Des(&msgId, data, &offset); + + cv = find_msg_converter(ptr, msgId); + if (cv) + { + ret = cv->deserFunc(data, length); + } + else + { + ret = NULL; + } + } + else + { + ret = NULL; + } + + return ret; +} + +static CsrSize sizeof_message(CsrUint16 primType, void *msg) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + CsrSize ret; + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + CsrUint16 msgId = *(CsrUint16 *) msg; + + cv = find_msg_converter(ptr, msgId); + if (cv) + { + ret = cv->sizeofFunc(msg); + } + else + { + ret = 0; + } + } + else + { + ret = 0; + } + + return ret; +} + +static CsrBool free_message(CsrUint16 primType, CsrUint8 *data) +{ + CsrMsgConvPrimEntry *ptr; + CsrBool ret; + + ptr = CsrMsgConvFind(primType); + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + CsrUint16 msgId = *(CsrUint16 *) data; + + cv = find_msg_converter(ptr, msgId); + if (cv) + { + cv->freeFunc(data); + ret = TRUE; + } + else + { + ret = FALSE; + } + } + else + { + ret = FALSE; + } + + return ret; +} + +static CsrUint8 *serialize_message(CsrUint16 primType, + void *msg, + CsrSize *length, + CsrUint8 *buffer) +{ + CsrMsgConvPrimEntry *ptr; + CsrUint8 *ret; + + ptr = CsrMsgConvFind(primType); + + *length = 0; + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + + cv = find_msg_converter(ptr, *(CsrUint16 *) msg); + if (cv) + { + ret = cv->serFunc(buffer, length, msg); + } + else + { + ret = NULL; + } + } + else + { + ret = NULL; + } + + return ret; +} + +CsrSize CsrMsgConvSizeof(CsrUint16 primType, void *msg) +{ + return sizeof_message(primType, msg); +} + +CsrUint8 *CsrMsgConvSerialize(CsrUint8 *buffer, CsrSize maxBufferOffset, CsrSize *offset, CsrUint16 primType, void *msg) +{ + if (converter) + { + CsrSize serializedLength; + CsrUint8 *bufSerialized; + CsrUint8 *bufOffset = &buffer[*offset]; + bufSerialized = converter->serialize_message(primType, msg, &serializedLength, bufOffset); + *offset += serializedLength; + return bufSerialized; + } + else + { + return NULL; + } +} + +/* Insert profile converter at head of converter list. */ +void CsrMsgConvInsert(CsrUint16 primType, const CsrMsgConvMsgEntry *ce) +{ + CsrMsgConvPrimEntry *pc; + pc = CsrMsgConvFind(primType); + + if (pc) + { + /* Already registered. Do nothing */ + } + else + { + pc = CsrPmemAlloc(sizeof(*pc)); + pc->primType = primType; + pc->conv = ce; + pc->lookupFunc = NULL; + pc->next = converter->profile_converters; + converter->profile_converters = pc; + } +} +EXPORT_SYMBOL_GPL(CsrMsgConvInsert); + +CsrMsgConvMsgEntry *CsrMsgConvFindEntry(CsrUint16 primType, CsrUint16 msgType) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + if (ptr) + { + return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType); + } + return NULL; +} +EXPORT_SYMBOL_GPL(CsrMsgConvFindEntry); + +CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(CsrUint16 primType, const void *msg) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + if (ptr && msg) + { + CsrUint16 msgType = *((CsrUint16 *) msg); + return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType); + } + return NULL; +} + +void CsrMsgConvCustomLookupRegister(CsrUint16 primType, CsrMsgCustomLookupFunc *lookupFunc) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + if (ptr) + { + ptr->lookupFunc = lookupFunc; + } +} +EXPORT_SYMBOL_GPL(CsrMsgConvCustomLookupRegister); + +CsrMsgConvEntry *CsrMsgConvInit(void) +{ + if (!converter) + { + converter = (CsrMsgConvEntry *) CsrPmemAlloc(sizeof(CsrMsgConvEntry)); + + converter->profile_converters = NULL; + converter->free_message = free_message; + converter->sizeof_message = sizeof_message; + converter->serialize_message = serialize_message; + converter->deserialize_data = deserialize_data; + } + + return converter; +} +EXPORT_SYMBOL_GPL(CsrMsgConvInit); + +CsrMsgConvEntry *CsrMsgConvGet(void) +{ + return converter; +} + +#ifdef ENABLE_SHUTDOWN +void CsrMsgConvDeinit(void) +{ + CsrMsgConvPrimEntry *s; + + if (converter == NULL) + { + return; + } + + /* Walk converter list and free elements. */ + s = converter->profile_converters; + while (s) + { + CsrMsgConvPrimEntry *s_next; + s_next = s->next; + CsrPmemFree(s); + s = s_next; + } + + CsrPmemFree(converter); + converter = NULL; +} +EXPORT_SYMBOL_GPL(CsrMsgConvDeinit); + +#endif /* ENABLE_SHUTDOWN */ diff --git a/drivers/staging/csr/csr_msgconv.h b/drivers/staging/csr/csr_msgconv.h new file mode 100644 index 000000000000..2875c8c69418 --- /dev/null +++ b/drivers/staging/csr/csr_msgconv.h @@ -0,0 +1,145 @@ +#ifndef CSR_MSGCONV_H__ +#define CSR_MSGCONV_H__ + +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_unicode.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef CsrSize (CsrMsgSizeofFunc)(void *msg); +typedef CsrUint8 *(CsrMsgSerializeFunc)(CsrUint8 *buffer, CsrSize *length, void *msg); +typedef void (CsrMsgFreeFunc)(void *msg); +typedef void *(CsrMsgDeserializeFunc)(CsrUint8 *buffer, CsrSize length); + +/* Converter entry for one message type */ +typedef struct CsrMsgConvMsgEntry +{ + CsrUint16 msgType; + CsrMsgSizeofFunc *sizeofFunc; + CsrMsgSerializeFunc *serFunc; + CsrMsgDeserializeFunc *deserFunc; + CsrMsgFreeFunc *freeFunc; +} CsrMsgConvMsgEntry; + +/* Optional lookup function */ +typedef CsrMsgConvMsgEntry *(CsrMsgCustomLookupFunc)(CsrMsgConvMsgEntry *ce, CsrUint16 msgType); + +/* All converter entries for one specific primitive */ +typedef struct CsrMsgConvPrimEntry +{ + CsrUint16 primType; + const CsrMsgConvMsgEntry *conv; + CsrMsgCustomLookupFunc *lookupFunc; + struct CsrMsgConvPrimEntry *next; +} CsrMsgConvPrimEntry; + +typedef struct +{ + CsrMsgConvPrimEntry *profile_converters; + void *(*deserialize_data)(CsrUint16 primType, CsrSize length, CsrUint8 * data); + CsrBool (*free_message)(CsrUint16 primType, CsrUint8 *data); + CsrSize (*sizeof_message)(CsrUint16 primType, void *msg); + CsrUint8 *(*serialize_message)(CsrUint16 primType, void *msg, + CsrSize * length, + CsrUint8 * buffer); +} CsrMsgConvEntry; + +CsrSize CsrMsgConvSizeof(CsrUint16 primType, void *msg); +CsrUint8 *CsrMsgConvSerialize(CsrUint8 *buffer, CsrSize maxBufferOffset, CsrSize *offset, CsrUint16 primType, void *msg); +void CsrMsgConvCustomLookupRegister(CsrUint16 primType, CsrMsgCustomLookupFunc *lookupFunc); +void CsrMsgConvInsert(CsrUint16 primType, const CsrMsgConvMsgEntry *ce); +CsrMsgConvPrimEntry *CsrMsgConvFind(CsrUint16 primType); +CsrMsgConvMsgEntry *CsrMsgConvFindEntry(CsrUint16 primType, CsrUint16 msgType); +CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(CsrUint16 primType, const void *msg); +CsrMsgConvEntry *CsrMsgConvGet(void); +CsrMsgConvEntry *CsrMsgConvInit(void); +#ifdef ENABLE_SHUTDOWN +void CsrMsgConvDeinit(void); +#endif /* ENABLE_SHUTDOWN */ + +/* SHOULD BE INTERNAL TO FRAMEWORK AKA DEPRECATED */ + +CsrUint32 CsrCharStringSerLen(const CsrCharString *str); +CsrUint32 CsrUtf8StringSerLen(const CsrUtf8String *str); +CsrUint32 CsrUtf16StringSerLen(const CsrUtf16String *str); + +/* Prototypes for primitive type serializers */ +void CsrUint8Ser(CsrUint8 *buffer, CsrSize *offset, CsrUint8 value); +void CsrUint16Ser(CsrUint8 *buffer, CsrSize *offset, CsrUint16 value); +void CsrUint32Ser(CsrUint8 *buffer, CsrSize *offset, CsrUint32 value); +void CsrMemCpySer(CsrUint8 *buffer, CsrSize *offset, const void *value, CsrSize length); +void CsrCharStringSer(CsrUint8 *buffer, CsrSize *offset, const CsrCharString *value); +void CsrUtf8StringSer(CsrUint8 *buffer, CsrSize *offset, const CsrUtf8String *value); +void CsrUtf16StringSer(CsrUint8 *buffer, CsrSize *offset, const CsrUtf16String *value); +void CsrVoidPtrSer(CsrUint8 *buffer, CsrSize *offset, void *ptr); +void CsrSizeSer(CsrUint8 *buffer, CsrSize *offset, CsrSize value); + +void CsrUint8Des(CsrUint8 *value, CsrUint8 *buffer, CsrSize *offset); +void CsrUint16Des(CsrUint16 *value, CsrUint8 *buffer, CsrSize *offset); +void CsrUint32Des(CsrUint32 *value, CsrUint8 *buffer, CsrSize *offset); +void CsrMemCpyDes(void *value, CsrUint8 *buffer, CsrSize *offset, CsrSize length); +void CsrCharStringDes(CsrCharString **value, CsrUint8 *buffer, CsrSize *offset); +void CsrUtf8StringDes(CsrUtf8String **value, CsrUint8 *buffer, CsrSize *offset); +void CsrUtf16StringDes(CsrUtf16String **value, CsrUint8 *buffer, CsrSize *offset); +void CsrVoidPtrDes(void **value, CsrUint8 *buffer, CsrSize *offset); +void CsrSizeDes(CsrSize *value, CsrUint8 *buffer, CsrSize *offset); + +CsrSize CsrEventSizeof(void *msg); +CsrUint8 *CsrEventSer(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventDes(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint8Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint8Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint16Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint16Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint32Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint32Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint32Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint16CsrUint8Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint16CsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint16CsrUint8Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint16CsrUint16Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint16CsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint16CsrUint16Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint16CsrUint32Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint16CsrUint32Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint16CsrUint32Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint16CsrCharStringSizeof(void *msg); +CsrUint8 *CsrEventCsrUint16CsrCharStringSer(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint16CsrCharStringDes(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint32CsrUint16Sizeof(void *msg); +CsrUint8 *CsrEventCsrUint32CsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint32CsrUint16Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrEventCsrUint32CsrCharStringSizeof(void *msg); +CsrUint8 *CsrEventCsrUint32CsrCharStringSer(CsrUint8 *ptr, CsrSize *len, void *msg); +void *CsrEventCsrUint32CsrCharStringDes(CsrUint8 *buffer, CsrSize length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_panic.c b/drivers/staging/csr/csr_panic.c new file mode 100644 index 000000000000..2564e80297e2 --- /dev/null +++ b/drivers/staging/csr/csr_panic.c @@ -0,0 +1,22 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include +#include + +#include "csr_types.h" +#include "csr_panic.h" + +void CsrPanic(CsrUint8 tech, CsrUint16 reason, const char *p) +{ + BUG_ON(1); +} +EXPORT_SYMBOL_GPL(CsrPanic); diff --git a/drivers/staging/csr/csr_panic.h b/drivers/staging/csr/csr_panic.h new file mode 100644 index 000000000000..6e33f9337b21 --- /dev/null +++ b/drivers/staging/csr/csr_panic.h @@ -0,0 +1,55 @@ +#ifndef CSR_PANIC_H__ +#define CSR_PANIC_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Synergy techonology ID definitions */ +#define CSR_TECH_FW 0 +#define CSR_TECH_BT 1 +#define CSR_TECH_WIFI 2 +#define CSR_TECH_GPS 3 +#define CSR_TECH_NFC 4 + +/* Panic type ID definitions for technology type CSR_TECH_FW */ +#define CSR_PANIC_FW_UNEXPECTED_VALUE 0 +#define CSR_PANIC_FW_HEAP_EXHAUSTION 1 +#define CSR_PANIC_FW_INVALID_PFREE_POINTER 2 +#define CSR_PANIC_FW_EXCEPTION 3 +#define CSR_PANIC_FW_ASSERTION_FAIL 4 +#define CSR_PANIC_FW_NULL_TASK_HANDLER 5 +#define CSR_PANIC_FW_UNKNOWN_TASK 6 +#define CSR_PANIC_FW_QUEUE_ACCESS_VIOLATION 7 +#define CSR_PANIC_FW_TOO_MANY_MESSAGES 8 +#define CSR_PANIC_FW_TOO_MANY_TIMED_EVENTS 9 +#define CSR_PANIC_FW_ABCSP_SYNC_LOST 10 +#define CSR_PANIC_FW_OVERSIZE_ABCSP_PRIM 11 +#define CSR_PANIC_FW_H4_CORRUPTION 12 +#define CSR_PANIC_FW_H4_SYNC_LOST 13 +#define CSR_PANIC_FW_H4_RX_OVERRUN 14 +#define CSR_PANIC_FW_H4_TX_OVERRUN 15 +#define CSR_PANIC_FW_TM_BC_RESTART_FAIL 16 +#define CSR_PANIC_FW_TM_BC_START_FAIL 17 +#define CSR_PANIC_FW_TM_BC_BAD_STATE 18 +#define CSR_PANIC_FW_TM_BC_TRANSPORT_LOST 19 + +/* Panic interface used by technologies */ +/* DEPRECATED - replaced by csr_log_text.h */ +void CsrPanic(CsrUint8 tech, CsrUint16 reason, const char *p); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_PANIC_H__ */ diff --git a/drivers/staging/csr/csr_pmem.c b/drivers/staging/csr/csr_pmem.c new file mode 100644 index 000000000000..a07c44999168 --- /dev/null +++ b/drivers/staging/csr/csr_pmem.c @@ -0,0 +1,51 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include +#include + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) +#include +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) +#include +#endif + +#include + +#include "csr_panic.h" +#include "csr_pmem.h" + +void *CsrPmemAlloc(CsrSize size) +{ + void *ret; + + ret = kmalloc(size, GFP_KERNEL); + if (!ret) + { + CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_HEAP_EXHAUSTION, + "out of memory"); + } + + return ret; +} +EXPORT_SYMBOL_GPL(CsrPmemAlloc); + +void CsrPmemFree(void *ptr) +{ + if (ptr == NULL) + { + return; + } + + kfree(ptr); +} +EXPORT_SYMBOL_GPL(CsrPmemFree); diff --git a/drivers/staging/csr/csr_pmem.h b/drivers/staging/csr/csr_pmem.h new file mode 100644 index 000000000000..f1e59ef83c65 --- /dev/null +++ b/drivers/staging/csr/csr_pmem.h @@ -0,0 +1,143 @@ +#ifndef CSR_PMEM_H__ +#define CSR_PMEM_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_PMEM_DEBUG_ENABLE +/***************************************************************************** + + NAME + CsrPmemAlloc + + DESCRIPTION + This function will allocate a contiguous block of memory of at least + the specified size in bytes and return a pointer to the allocated + memory. This function is not allowed to return NULL. A size of 0 is a + valid request, and a unique and valid (not NULL) pointer must be + returned in this case. + + PARAMETERS + size - Size of memory requested. Note that a size of 0 is valid. + + RETURNS + Pointer to allocated memory. + +*****************************************************************************/ +#ifdef CSR_PMEM_DEBUG +void *CsrPmemAllocDebug(CsrSize size, + const CsrCharString *file, CsrUint32 line); +#define CsrPmemAlloc(sz) CsrPmemAllocDebug((sz), __FILE__, __LINE__) +#else +void *CsrPmemAlloc(CsrSize size); +#endif + + +/***************************************************************************** + + NAME + CsrPmemFree + + DESCRIPTION + This function will deallocate a previously allocated block of memory. + + PARAMETERS + ptr - Pointer to allocated memory. + +*****************************************************************************/ +void CsrPmemFree(void *ptr); +#endif + +/***************************************************************************** + + NAME + CsrPmemZalloc + + DESCRIPTION + This function is equivalent to CsrPmemAlloc, but the allocated memory + is initialised to zero. + + PARAMETERS + size - Size of memory requested. Note that a size of 0 is valid. + + RETURNS + Pointer to allocated memory. + +*****************************************************************************/ +#define CsrPmemZalloc(s) (CsrMemSet(CsrPmemAlloc(s), 0x00, (s))) + + +/***************************************************************************** + + NAME + pnew and zpnew + + DESCRIPTIOM + Type-safe wrappers for CsrPmemAlloc and CsrPmemZalloc, for allocating + single instances of a specified and named type. + + PARAMETERS + t - type to allocate. + +*****************************************************************************/ +#define pnew(t) ((t *) (CsrPmemAlloc(sizeof(t)))) +#define zpnew(t) ((t *) (CsrPmemZalloc(sizeof(t)))) + + +/*----------------------------------------------------------------------------* + * Csr Pmem Debug code. Allows custom callbacks on CsrPmemAlloc and CsrPmemFree + *----------------------------------------------------------------------------*/ +#ifdef CSR_PMEM_DEBUG_ENABLE + +typedef CsrUint8 CsrPmemDebugAllocType; +#define CSR_PMEM_DEBUG_TYPE_PMEM_ALLOC 1 +#define CSR_PMEM_DEBUG_TYPE_MEM_ALLOC 2 +#define CSR_PMEM_DEBUG_TYPE_MEM_CALLOC 3 +#define CSR_PMEM_DEBUG_TYPE_MEM_ALLOC_DMA 4 + +typedef void (CsrPmemDebugOnAlloc)(void *ptr, void *userptr, CsrSize size, CsrPmemDebugAllocType type, const CsrCharString* file, CsrUint32 line); +typedef void (CsrPmemDebugOnFree)(void *ptr, void *userptr, CsrPmemDebugAllocType type, const CsrCharString* file, CsrUint32 line); + +/*----------------------------------------------------------------------------* + * NAME + * CsrPmemInstallHooks + * + * DESCRIPTION + * Install debug hooks for memory allocation + * Use NULL values to uninstall the hooks + * headSize = The number of extra bytes to allocate in the head of the Allocated buffer + * footSize = The number of extra bytes to allocate in the end of the Allocated buffer + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrPmemDebugInstallHooks(CsrUint8 headSize, CsrUint8 endSize, CsrPmemDebugOnAlloc *onAllocCallback, CsrPmemDebugOnFree *onFreeCallback); + +void *CsrPmemDebugAlloc(CsrSize size, CsrPmemDebugAllocType type, const CsrCharString* file, CsrUint32 line); +#define CsrPmemAlloc(size) CsrPmemDebugAlloc(size, CSR_PMEM_DEBUG_TYPE_PMEM_ALLOC, __FILE__, __LINE__) + +void CsrPmemDebugFree(void *ptr, CsrPmemDebugAllocType type, const CsrCharString* file, CsrUint32 line); +#define CsrPmemFree(ptr) CsrPmemDebugFree(ptr, CSR_PMEM_DEBUG_TYPE_PMEM_ALLOC, __FILE__, __LINE__) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_prim_defs.h b/drivers/staging/csr/csr_prim_defs.h new file mode 100644 index 000000000000..02ab91391949 --- /dev/null +++ b/drivers/staging/csr/csr_prim_defs.h @@ -0,0 +1,64 @@ +#ifndef CSR_PRIM_DEFS_H__ +#define CSR_PRIM_DEFS_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************ + * Segmentation of primitives in upstream and downstream segment + ************************************************************************************/ +typedef CsrUint16 CsrPrim; +#define CSR_PRIM_UPSTREAM ((CsrPrim) (0x8000)) + +/************************************************************************************ + * Primitive definitions for Synergy framework + ************************************************************************************/ +#define CSR_SYNERGY_EVENT_CLASS_BASE ((CsrUint16) (0x0600)) + +#define CSR_HCI_PRIM ((CsrUint16) (0x0000 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_BCCMD_PRIM ((CsrUint16) (0x0001 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_HQ_PRIM ((CsrUint16) (0x0002 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_VM_PRIM ((CsrUint16) (0x0003 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_TM_BLUECORE_PRIM ((CsrUint16) (0x0004 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_FP_PRIM ((CsrUint16) (0x0005 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_IP_SOCKET_PRIM ((CsrUint16) (0x0006 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_IP_ETHER_PRIM ((CsrUint16) (0x0007 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_IP_IFCONFIG_PRIM ((CsrUint16) (0x0008 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_IP_INTERNAL_PRIM ((CsrUint16) (0x0009 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_FSAL_PRIM ((CsrUint16) (0x000A | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_DATA_STORE_PRIM ((CsrUint16) (0x000B | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_AM_PRIM ((CsrUint16) (0x000C | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_TLS_PRIM ((CsrUint16) (0x000D | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_DHCP_SERVER_PRIM ((CsrUint16) (0x000E | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_TFTP_PRIM ((CsrUint16) (0x000F | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_DSPM_PRIM ((CsrUint16) (0x0010 | CSR_SYNERGY_EVENT_CLASS_BASE)) +#define CSR_TLS_INTERNAL_PRIM ((CsrUint16) (0x0011 | CSR_SYNERGY_EVENT_CLASS_BASE)) + +#define NUMBER_OF_CSR_FW_EVENTS (CSR_DSPM_PRIM - CSR_SYNERGY_EVENT_CLASS_BASE + 1) + +#define CSR_SYNERGY_EVENT_CLASS_MISC_BASE ((CsrUint16) (0x06A0)) + +#define CSR_UI_PRIM ((CsrUint16) (0x0000 | CSR_SYNERGY_EVENT_CLASS_MISC_BASE)) +#define CSR_APP_PRIM ((CsrUint16) (0x0001 | CSR_SYNERGY_EVENT_CLASS_MISC_BASE)) +#define CSR_SDIO_PROBE_PRIM ((CsrUint16) (0x0002 | CSR_SYNERGY_EVENT_CLASS_MISC_BASE)) + +#define NUMBER_OF_CSR_FW_MISC_EVENTS (CSR_SDIO_PROBE_PRIM - CSR_SYNERGY_EVENT_CLASS_MISC_BASE + 1) + +#define CSR_ENV_PRIM ((CsrUint16) (0x00FF | CSR_SYNERGY_EVENT_CLASS_MISC_BASE)) + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_PRIM_DEFS_H__ */ diff --git a/drivers/staging/csr/csr_result.h b/drivers/staging/csr/csr_result.h new file mode 100644 index 000000000000..249b4990c478 --- /dev/null +++ b/drivers/staging/csr/csr_result.h @@ -0,0 +1,27 @@ +#ifndef CSR_RESULT_H__ +#define CSR_RESULT_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef CsrUint16 CsrResult; +#define CSR_RESULT_SUCCESS ((CsrResult) 0x0000) +#define CSR_RESULT_FAILURE ((CsrResult) 0xFFFF) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_sched.h b/drivers/staging/csr/csr_sched.h new file mode 100644 index 000000000000..2f982bbfb723 --- /dev/null +++ b/drivers/staging/csr/csr_sched.h @@ -0,0 +1,292 @@ +#ifndef CSR_SCHED_H__ +#define CSR_SCHED_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#include "csr_types.h" +#include "csr_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* An identifier issued by the scheduler. */ +typedef CsrUint32 CsrSchedIdentifier; + +/* A task identifier */ +typedef CsrUint16 CsrSchedTaskId; + +/* A queue identifier */ +typedef CsrUint16 CsrSchedQid; +#define CSR_SCHED_QID_INVALID ((CsrSchedQid) 0xFFFF) + +/* A message identifier */ +typedef CsrSchedIdentifier CsrSchedMsgId; + +/* A timer event identifier */ +typedef CsrSchedIdentifier CsrSchedTid; +#define CSR_SCHED_TID_INVALID ((CsrSchedTid) 0) + +/* Scheduler entry functions share this structure */ +typedef void (*schedEntryFunction_t)(void **inst); + +/* Time constants. */ +#define CSR_SCHED_TIME_MAX ((CsrTime) 0xFFFFFFFF) +#define CSR_SCHED_MILLISECOND ((CsrTime) (1000)) +#define CSR_SCHED_SECOND ((CsrTime) (1000 * CSR_SCHED_MILLISECOND)) +#define CSR_SCHED_MINUTE ((CsrTime) (60 * CSR_SCHED_SECOND)) + +/* Queue and primitive that identifies the environment */ +#define CSR_SCHED_TASK_ID 0xFFFF +#define CSR_SCHED_PRIM (CSR_SCHED_TASK_ID) +#define CSR_SCHED_EXCLUDED_MODULE_QUEUE 0xFFFF + +/* + * Background interrupt definitions + */ +typedef CsrUint16 CsrSchedBgint; +#define CSR_SCHED_BGINT_INVALID ((CsrSchedBgint) 0xFFFF) + +typedef void (*CsrSchedBgintHandler)(void *); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedBgintReg + * + * DESCRIPTION + * Register a background interrupt handler function with the scheduler. + * When CsrSchedBgint() is called from the foreground (e.g. an interrupt + * routine) the registered function is called. + * + * If "cb" is null then the interrupt is effectively disabled. If a + * no bgints are available, CSR_SCHED_BGINT_INVALID is returned, otherwise + * a CsrSchedBgint value is returned to be used in subsequent calls to + * CsrSchedBgint(). id is a possibly NULL identifier used for logging + * purposes only. + * + * RETURNS + * CsrSchedBgint -- CSR_SCHED_BGINT_INVALID denotes failure to obtain a CsrSchedBgintSet. + * + *----------------------------------------------------------------------------*/ +CsrSchedBgint CsrSchedBgintReg(CsrSchedBgintHandler cb, + void *context, + const CsrCharString *id); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedBgintUnreg + * + * DESCRIPTION + * Unregister a background interrupt handler function. + * + * ``irq'' is a background interrupt handle previously obtained + * from a call to CsrSchedBgintReg(). + * + * RETURNS + * void. + * + *----------------------------------------------------------------------------*/ +void CsrSchedBgintUnreg(CsrSchedBgint bgint); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedBgintSet + * + * DESCRIPTION + * Set background interrupt. + * + * RETURNS + * void. + * + *----------------------------------------------------------------------------*/ +void CsrSchedBgintSet(CsrSchedBgint bgint); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedMessagePut + * + * DESCRIPTION + * Sends a message consisting of the integer "mi" and the void * pointer + * "mv" to the message queue "q". + * + * "mi" and "mv" are neither inspected nor changed by the scheduler - the + * task that owns "q" is expected to make sense of the values. "mv" may + * be null. + * + * NOTE + * If "mv" is not null then it will typically be a chunk of CsrPmemAlloc()ed + * memory, though there is no need for it to be so. Tasks should normally + * obey the convention that when a message built with CsrPmemAlloc()ed memory + * is given to CsrSchedMessagePut() then ownership of the memory is ceded to the + * scheduler - and eventually to the recipient task. I.e., the receiver of + * the message will be expected to CsrPmemFree() the message storage. + * + * RETURNS + * void. + * + *----------------------------------------------------------------------------*/ +#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) +void CsrSchedMessagePutStringLog(CsrSchedQid q, + CsrUint16 mi, + void *mv, + CsrUint32 line, + const CsrCharString *file); +#define CsrSchedMessagePut(q, mi, mv) CsrSchedMessagePutStringLog((q), (mi), (mv), __LINE__, __FILE__) +#else +void CsrSchedMessagePut(CsrSchedQid q, + CsrUint16 mi, + void *mv); +#endif + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedMessageBroadcast + * + * DESCRIPTION + * Sends a message to all tasks. + * + * The user must supply a "factory function" that is called once + * for every task that exists. The "factory function", msg_build_func, + * must allocate and initialise the message and set the msg_build_ptr + * to point to the message when done. + * + * NOTE + * N/A + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) +void CsrSchedMessageBroadcastStringLog(CsrUint16 mi, + void *(*msg_build_func)(void *), + void *msg_build_ptr, + CsrUint32 line, + const CsrCharString *file); +#define CsrSchedMessageBroadcast(mi, fn, ptr) CsrSchedMessageBroadcastStringLog((mi), (fn), (ptr), __LINE__, __FILE__) +#else +void CsrSchedMessageBroadcast(CsrUint16 mi, + void *(*msg_build_func)(void *), + void *msg_build_ptr); +#endif + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedMessageGet + * + * DESCRIPTION + * Obtains a message from the message queue belonging to the calling task. + * The message consists of one or both of a CsrUint16 and a void *. + * + * RETURNS + * CsrBool - TRUE if a message has been obtained from the queue, else FALSE. + * If a message is taken from the queue, then "*pmi" and "*pmv" are set to + * the "mi" and "mv" passed to CsrSchedMessagePut() respectively. + * + * "pmi" and "pmv" can be null, in which case the corresponding value from + * them message is discarded. + * + *----------------------------------------------------------------------------*/ +CsrBool CsrSchedMessageGet(CsrUint16 *pmi, void **pmv); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedTimerSet + * + * DESCRIPTION + * Causes the void function "fn" to be called with the arguments + * "fniarg" and "fnvarg" after "delay" has elapsed. + * + * "delay" must be less than half the range of a CsrTime. + * + * CsrSchedTimerSet() does nothing with "fniarg" and "fnvarg" except + * deliver them via a call to "fn()". (Unless CsrSchedTimerCancel() + * is used to prevent delivery.) + * + * NOTE + * The function will be called at or after "delay"; the actual delay will + * depend on the timing behaviour of the scheduler's tasks. + * + * RETURNS + * CsrSchedTid - A timed event identifier, can be used in CsrSchedTimerCancel(). + * + *----------------------------------------------------------------------------*/ +#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) +CsrSchedTid CsrSchedTimerSetStringLog(CsrTime delay, + void (*fn)(CsrUint16 mi, void *mv), + CsrUint16 fniarg, + void *fnvarg, + CsrUint32 line, + const CsrCharString *file); +#define CsrSchedTimerSet(d, fn, fni, fnv) CsrSchedTimerSetStringLog((d), (fn), (fni), (fnv), __LINE__, __FILE__) +#else +CsrSchedTid CsrSchedTimerSet(CsrTime delay, + void (*fn)(CsrUint16 mi, void *mv), + CsrUint16 fniarg, + void *fnvarg); +#endif + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedTimerCancel + * + * DESCRIPTION + * Attempts to prevent the timed event with identifier "eventid" from + * occurring. + * + * RETURNS + * CsrBool - TRUE if cancelled, FALSE if the event has already occurred. + * + *----------------------------------------------------------------------------*/ +#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) +CsrBool CsrSchedTimerCancelStringLog(CsrSchedTid eventid, + CsrUint16 *pmi, + void **pmv, + CsrUint32 line, + const CsrCharString *file); +#define CsrSchedTimerCancel(e, pmi, pmv) CsrSchedTimerCancelStringLog((e), (pmi), (pmv), __LINE__, __FILE__) +#else +CsrBool CsrSchedTimerCancel(CsrSchedTid eventid, + CsrUint16 *pmi, + void **pmv); +#endif + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedTaskQueueGet + * + * DESCRIPTION + * Return the queue identifier for the currently running queue + * + * RETURNS + * CsrSchedQid - The current task queue identifier, or 0xFFFF if not available. + * + *----------------------------------------------------------------------------*/ +CsrSchedQid CsrSchedTaskQueueGet(void); + + +/*----------------------------------------------------------------------------* + * NAME + * CsrSchedTaskQueueGet + * + * DESCRIPTION + * Return the queue identifier for the currently running queue + * + * RETURNS + * CsrCharString - The current task queue identifier, or 0xFFFF if not available. + * + *----------------------------------------------------------------------------*/ +CsrCharString* CsrSchedTaskNameGet(CsrSchedQid ); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_sdio.h b/drivers/staging/csr/csr_sdio.h new file mode 100644 index 000000000000..d60ef45a9ab0 --- /dev/null +++ b/drivers/staging/csr/csr_sdio.h @@ -0,0 +1,732 @@ +#ifndef CSR_SDIO_H__ +#define CSR_SDIO_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" +#include "csr_result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Result Codes */ +#define CSR_SDIO_RESULT_INVALID_VALUE ((CsrResult) 1) /* Invalid argument value */ +#define CSR_SDIO_RESULT_NO_DEVICE ((CsrResult) 2) /* The specified device is no longer present */ +#define CSR_SDIO_RESULT_CRC_ERROR ((CsrResult) 3) /* The transmitted/received data or command response contained a CRC error */ +#define CSR_SDIO_RESULT_TIMEOUT ((CsrResult) 4) /* No command response or data received from device, or function enable/disable did not succeed within timeout period */ +#define CSR_SDIO_RESULT_NOT_RESET ((CsrResult) 5) /* The device was not reset */ + +/* Features (for use in features member of CsrSdioFunction) */ +#define CSR_SDIO_FEATURE_BYTE_MODE 0x00000001 /* Transfer sizes do not have to be a multiple of block size */ +#define CSR_SDIO_FEATURE_DMA_CAPABLE_MEM_REQUIRED 0x00000002 /* Bulk operations require DMA friendly memory */ + +/* CsrSdioFunctionId wildcards (for use in CsrSdioFunctionId members) */ +#define CSR_SDIO_ANY_MANF_ID 0xFFFF +#define CSR_SDIO_ANY_CARD_ID 0xFFFF +#define CSR_SDIO_ANY_SDIO_FUNCTION 0xFF +#define CSR_SDIO_ANY_SDIO_INTERFACE 0xFF + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionId + * + * DESCRIPTION + * This structure describes one or more functions of a device, based on + * four qualitative measures. The CsrSdioFunctionId wildcard defines can be + * used for making the CsrSdioFunctionId match more than one function. + * + * MEMBERS + * manfId - Vendor ID (or CSR_SDIO_ANY_MANF_ID). + * cardId - Device ID (or CSR_SDIO_ANY_CARD_ID). + * sdioFunction - SDIO Function number (or CSR_SDIO_ANY_SDIO_FUNCTION). + * sdioInterface - SDIO Standard Interface Code (or CSR_SDIO_ANY_SDIO_INTERFACE) + * + *----------------------------------------------------------------------------*/ +typedef struct +{ + CsrUint16 manfId; /* Vendor ID to match or CSR_SDIO_ANY_MANF_ID */ + CsrUint16 cardId; /* Device ID to match or CSR_SDIO_ANY_CARD_ID */ + CsrUint8 sdioFunction; /* SDIO Function number to match or CSR_SDIO_ANY_SDIO_FUNCTION */ + CsrUint8 sdioInterface; /* SDIO Standard Interface Code to match or CSR_SDIO_ANY_SDIO_INTERFACE */ +} CsrSdioFunctionId; + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunction + * + * DESCRIPTION + * This structure represents a single function on a device. + * + * MEMBERS + * sdioId - A CsrSdioFunctionId describing this particular function. The + * subfield shall not contain any CsrSdioFunctionId wildcards. The + * subfields shall describe the specific single function + * represented by this structure. + * blockSize - Actual configured block size, or 0 if unconfigured. + * features - Bit mask with any of CSR_SDIO_FEATURE_* set. + * device - Handle of device containing the function. If two functions have + * the same device handle, they reside on the same device. + * driverData - For use by the Function Driver. The SDIO Driver shall not + * attempt to dereference the pointer. + * priv - For use by the SDIO Driver. The Function Driver shall not attempt + * to dereference the pointer. + * + * + *----------------------------------------------------------------------------*/ +typedef struct +{ + CsrSdioFunctionId sdioId; + CsrUint16 blockSize; /* Actual configured block size, or 0 if unconfigured */ + CsrUint32 features; /* Bit mask with any of CSR_SDIO_FEATURE_* set */ + void *device; /* Handle of device containing the function */ + void *driverData; /* For use by the Function Driver */ + void *priv; /* For use by the SDIO Driver */ +} CsrSdioFunction; + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInsertedCallback, CsrSdioRemovedCallback + * + * DESCRIPTION + * CsrSdioInsertedCallback is called when a function becomes available to + * a registered Function Driver that supports the function. + * CsrSdioRemovedCallback is called when a function is no longer available + * to a Function Driver, either because the device has been removed, or the + * Function Driver has been unregistered. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the CsrSdioFunctionDriver struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioInsertedCallback)(CsrSdioFunction *function); +typedef void (*CsrSdioRemovedCallback)(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInterruptDsrCallback, CsrSdioInterruptCallback + * + * DESCRIPTION + * CsrSdioInterruptCallback is called when an interrupt occurs on the + * the device associated with the specified function. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the CsrSdioFunctionDriver struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + * RETURNS (only CsrSdioInterruptCallback) + * A pointer to a CsrSdioInterruptDsrCallback function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioInterruptDsrCallback)(CsrSdioFunction *function); +typedef CsrSdioInterruptDsrCallback (*CsrSdioInterruptCallback)(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioSuspendCallback, CsrSdioResumeCallback + * + * DESCRIPTION + * CsrSdioSuspendCallback is called when the system is preparing to go + * into a suspended state. CsrSdioResumeCallback is called when the system + * has entered an active state again. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the CsrSdioFunctionDriver struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioSuspendCallback)(CsrSdioFunction *function); +typedef void (*CsrSdioResumeCallback)(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioAsyncCallback, CsrSdioAsyncDsrCallback + * + * DESCRIPTION + * CsrSdioAsyncCallback is called when an asynchronous operation completes. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the function calls that initiate + * the operation. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * result - The result of the operation that completed. See the description + * of the initiating function for possible result values. + * + * RETURNS (only CsrSdioAsyncCallback) + * A pointer to a CsrSdioAsyncDsrCallback function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioAsyncDsrCallback)(CsrSdioFunction *function, CsrResult result); +typedef CsrSdioAsyncDsrCallback (*CsrSdioAsyncCallback)(CsrSdioFunction *function, CsrResult result); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionDriver + * + * DESCRIPTION + * Structure representing a Function Driver. + * + * MEMBERS + * inserted - Callback, see description of CsrSdioInsertedCallback. + * removed - Callback, see description of CsrSdioRemovedCallback. + * intr - Callback, see description of CsrSdioInterruptCallback. + * suspend - Callback, see description of CsrSdioSuspendCallback. + * resume - Callback, see description of CsrSdioResumeCallback. + * ids - Array of CsrSdioFunctionId describing one or more functions that + * are supported by the Function Driver. + * idsCount - Length of the ids array. + * priv - For use by the SDIO Driver. The Function Driver may initialise + * it to NULL, but shall otherwise not access the pointer or attempt + * to dereference it. + * + *----------------------------------------------------------------------------*/ +typedef struct +{ + CsrSdioInsertedCallback inserted; + CsrSdioRemovedCallback removed; + CsrSdioInterruptCallback intr; + CsrSdioSuspendCallback suspend; + CsrSdioResumeCallback resume; + CsrSdioFunctionId *ids; + CsrUint8 idsCount; + void *priv; /* For use by the SDIO Driver */ +} CsrSdioFunctionDriver; + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionDriverRegister + * + * DESCRIPTION + * Register a Function Driver. + * + * PARAMETERS + * functionDriver - Pointer to struct describing the Function Driver. + * + * RETURNS + * CSR_RESULT_SUCCESS - The Function Driver was successfully + * registered. + * CSR_RESULT_FAILURE - Unable to register the function driver, + * because of an unspecified/unknown error. The + * Function Driver has not been registered. + * CSR_SDIO_RESULT_INVALID_VALUE - The specified Function Driver pointer + * does not point at a valid Function + * Driver structure, or some of the members + * contain invalid entries. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *functionDriver); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionDriverUnregister + * + * DESCRIPTION + * Unregister a previously registered Function Driver. + * + * PARAMETERS + * functionDriver - pointer to struct describing the Function Driver. + * + *----------------------------------------------------------------------------*/ +void CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *functionDriver); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionEnable, CsrSdioFunctionDisable + * + * DESCRIPTION + * Enable/disable the specified function by setting/clearing the + * corresponding bit in the I/O Enable register in function 0, and then + * periodically reading the related bit in the I/O Ready register until it + * is set/clear, limited by an implementation defined timeout. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + * RETURNS + * CSR_RESULT_SUCCESS - The specified function was enabled/disabled. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The state of the + * related bit in the I/O Enable register is + * undefined. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device, or the related + * bit in the I/O ready register was not + * set/cleared within the timeout period. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioFunctionEnable(CsrSdioFunction *function); +CsrResult CsrSdioFunctionDisable(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInterruptEnable, CsrSdioInterruptDisable + * + * DESCRIPTION + * Enable/disable the interrupt for the specified function by + * setting/clearing the corresponding bit in the INT Enable register in + * function 0. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + * RETURNS + * CSR_RESULT_SUCCESS - The specified function was enabled/disabled. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The state of the + * related bit in the INT Enable register is + * unchanged. + * CSR_SDIO_RESULT_INVALID_VALUE - The specified function cannot be + * enabled/disabled, because it either + * does not exist or it is not possible to + * individually enable/disable functions. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioInterruptEnable(CsrSdioFunction *function); +CsrResult CsrSdioInterruptDisable(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInterruptAcknowledge + * + * DESCRIPTION + * Acknowledge that a signalled interrupt has been handled. Shall only + * be called once, and exactly once for each signalled interrupt to the + * corresponding function. + * + * PARAMETERS + * function - Pointer to struct representing the function to which the + * event was signalled. + * + *----------------------------------------------------------------------------*/ +void CsrSdioInterruptAcknowledge(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInsertedAcknowledge, CsrSdioRemovedAcknowledge + * + * DESCRIPTION + * Acknowledge that a signalled inserted/removed event has been handled. + * Shall only be called once, and exactly once for each signalled event to + * the corresponding function. + * + * PARAMETERS + * function - Pointer to struct representing the function to which the + * inserted was signalled. + * result (CsrSdioInsertedAcknowledge only) + * CSR_RESULT_SUCCESS - The Function Driver has accepted the + * function, and the function is attached to + * the Function Driver until the + * CsrSdioRemovedCallback is called and + * acknowledged. + * CSR_RESULT_FAILURE - Unable to accept the function. The + * function is not attached to the Function + * Driver, and it may be passed to another + * Function Driver which supports the + * function. + * + *----------------------------------------------------------------------------*/ +void CsrSdioInsertedAcknowledge(CsrSdioFunction *function, CsrResult result); +void CsrSdioRemovedAcknowledge(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioSuspendAcknowledge, CsrSdioResumeAcknowledge + * + * DESCRIPTION + * Acknowledge that a signalled suspend event has been handled. Shall only + * be called once, and exactly once for each signalled event to the + * corresponding function. + * + * PARAMETERS + * function - Pointer to struct representing the function to which the + * event was signalled. + * result + * CSR_RESULT_SUCCESS - Successfully suspended/resumed. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * + *----------------------------------------------------------------------------*/ +void CsrSdioSuspendAcknowledge(CsrSdioFunction *function, CsrResult result); +void CsrSdioResumeAcknowledge(CsrSdioFunction *function, CsrResult result); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioBlockSizeSet + * + * DESCRIPTION + * Set the block size to use for the function. The actual configured block + * size shall be the minimum of: + * 1) Maximum block size supported by the function. + * 2) Maximum block size supported by the host controller. + * 3) The block size specified by the blockSize argument. + * + * When this function returns, the actual configured block size is + * available in the blockSize member of the function struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * blockSize - Block size to use for the function. Valid range is 1 to + * 2048. + * + * RETURNS + * CSR_RESULT_SUCCESS - The block size register on the chip + * was updated. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The configured block + * size is undefined. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER + * bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned. + * If the ERROR bit is set (but not FUNCTION_NUMBER), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: Setting the block size requires two individual operations. The + * implementation shall ignore the OUT_OF_RANGE bit of the SDIO R5 + * response for the first operation, as the partially configured + * block size may be out of range, even if the final block size + * (after the second operation) is in the valid range. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioMaxBusClockFrequencySet + * + * DESCRIPTION + * Set the maximum clock frequency to use for the device associated with + * the specified function. The actual configured clock frequency for the + * device shall be the minimum of: + * 1) Maximum clock frequency supported by the device. + * 2) Maximum clock frequency supported by the host controller. + * 3) Maximum clock frequency specified for any function on the same + * device. + * + * If the clock frequency exceeds 25MHz, it is the responsibility of the + * SDIO driver to enable high speed mode on the device, using the standard + * defined procedure, before increasing the frequency beyond the limit. + * + * Note that the clock frequency configured affects all functions on the + * same device. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * maxFrequency - The maximum clock frequency for the function in Hertz. + * + * RETURNS + * CSR_RESULT_SUCCESS - The maximum clock frequency was succesfully + * set for the function. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * + * NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER + * bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned. + * If the ERROR bit is set (but not FUNCTION_NUMBER), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioRead8, CsrSdioWrite8, CsrSdioRead8Async, CsrSdioWrite8Async + * + * DESCRIPTION + * Read/write an 8bit value from/to the specified register address. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. No data read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioRead8Async and CsrSdioWrite8Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data); +CsrResult CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data); +void CsrSdioRead8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data, CsrSdioAsyncCallback callback); +void CsrSdioWrite8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioRead16, CsrSdioWrite16, CsrSdioRead16Async, CsrSdioWrite16Async + * + * DESCRIPTION + * Read/write a 16bit value from/to the specified register address. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. Data may have been + * partially read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioRead16Async and CsrSdioWrite16Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data); +CsrResult CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data); +void CsrSdioRead16Async(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data, CsrSdioAsyncCallback callback); +void CsrSdioWrite16Async(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioF0Read8, CsrSdioF0Write8, CsrSdioF0Read8Async, + * CsrSdioF0Write8Async + * + * DESCRIPTION + * Read/write an 8bit value from/to the specified register address in + * function 0. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. No data read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data); +CsrResult CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data); +void CsrSdioF0Read8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data, CsrSdioAsyncCallback callback); +void CsrSdioF0Write8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioRead, CsrSdioWrite, CsrSdioReadAsync, CsrSdioWriteAsync + * + * DESCRIPTION + * Read/write a specified number of bytes from/to the specified register + * address. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * length - Number of byte to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. Data may have been + * partially read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length); +CsrResult CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length); +void CsrSdioReadAsync(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length, CsrSdioAsyncCallback callback); +void CsrSdioWriteAsync(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioPowerOn, CsrSdioPowerOff + * + * DESCRIPTION + * Power on/off the device. + * + * PARAMETERS + * function - Pointer to struct representing the function that resides on + * the device to power on/off. + * + * RETURNS (only CsrSdioPowerOn) + * CSR_RESULT_SUCCESS - Power was succesfully reapplied and the device + * has been reinitialised. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured during reinitialisation. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device during + * reinitialisation. + * CSR_SDIO_RESULT_NOT_RESET - The power was not removed by the + * CsrSdioPowerOff call. The state of the + * device is unchanged. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioPowerOn(CsrSdioFunction *function); +void CsrSdioPowerOff(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioHardReset + * + * DESCRIPTION + * Perform a hardware reset of the device. + * + * PARAMETERS + * function - Pointer to struct representing the function that resides on + * the device to hard reset. + * + * RETURNS + * CSR_RESULT_SUCCESS - Reset was succesfully performed and the device + * has been reinitialised. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured during reinitialisation. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device during + * reinitialisation. + * CSR_SDIO_RESULT_NOT_RESET - The reset was not applied because it is not + * supported. The state of the device is + * unchanged. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioHardReset(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionActive, CsrSdioFunctionIdle + * + * DESCRIPTION + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + *----------------------------------------------------------------------------*/ +void CsrSdioFunctionActive(CsrSdioFunction *function); +void CsrSdioFunctionIdle(CsrSdioFunction *function); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_serialize_primitive_types.c b/drivers/staging/csr/csr_serialize_primitive_types.c new file mode 100644 index 000000000000..5ea06fc964d1 --- /dev/null +++ b/drivers/staging/csr/csr_serialize_primitive_types.c @@ -0,0 +1,472 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_msgconv.h" +#include "csr_util.h" +#include "csr_pmem.h" +#include "csr_lib.h" + +void CsrUint8Des(CsrUint8 *value, CsrUint8 *buffer, CsrSize *offset) +{ + *value = buffer[*offset]; + *offset += sizeof(*value); +} +EXPORT_SYMBOL_GPL(CsrUint8Des); + +void CsrUint16Des(CsrUint16 *value, CsrUint8 *buffer, CsrSize *offset) +{ + *value = (buffer[*offset + 0] << 0) | + (buffer[*offset + 1] << 8); + *offset += sizeof(*value); +} +EXPORT_SYMBOL_GPL(CsrUint16Des); + +void CsrUint32Des(CsrUint32 *value, CsrUint8 *buffer, CsrSize *offset) +{ + *value = (buffer[*offset + 0] << 0) | + (buffer[*offset + 1] << 8) | + (buffer[*offset + 2] << 16) | + (buffer[*offset + 3] << 24); + *offset += sizeof(*value); +} +EXPORT_SYMBOL_GPL(CsrUint32Des); + +void CsrMemCpyDes(void *value, CsrUint8 *buffer, CsrSize *offset, CsrSize length) +{ + CsrMemCpy(value, &buffer[*offset], length); + *offset += length; +} +EXPORT_SYMBOL_GPL(CsrMemCpyDes); + +void CsrCharStringDes(CsrCharString **value, CsrUint8 *buffer, CsrSize *offset) +{ + *value = CsrStrDup((CsrCharString *) &buffer[*offset]); + *offset += CsrStrLen(*value) + 1; +} +EXPORT_SYMBOL_GPL(CsrCharStringDes); + +void CsrUtf8StringDes(CsrUtf8String **value, CsrUint8 *buffer, CsrSize *offset) +{ + *value = (CsrUtf8String *) CsrStrDup((CsrCharString *) &buffer[*offset]); + *offset += CsrStrLen((CsrCharString *) *value) + 1; +} + +void CsrUtf16StringDes(CsrUtf16String **value, CsrUint8 *buffer, CsrSize *offset) +{ + CsrUint32 length, i; + + CsrUint32Des(&length, buffer, offset); + + *value = CsrPmemAlloc(length * sizeof(**value)); + for (i = 0; i < length; i++) + { + CsrUint16Des(&(*value)[i], buffer, offset); + } +} + +void CsrSizeDes(CsrSize *value, CsrUint8 *buffer, CsrSize *offset) +{ + *value = (buffer[*offset + 0] << 0) | + (buffer[*offset + 1] << 8) | + (buffer[*offset + 2] << 16) | + (buffer[*offset + 3] << 24); + *offset += sizeof(*value); +} + +void CsrVoidPtrDes(void **value, CsrUint8 *buffer, CsrSize *offset) +{ + CsrSizeDes((CsrSize *) value, buffer, offset); +} + +void CsrUint8Ser(CsrUint8 *buffer, CsrSize *offset, CsrUint8 value) +{ + buffer[*offset] = value; + *offset += sizeof(value); +} +EXPORT_SYMBOL_GPL(CsrUint8Ser); + +void CsrUint16Ser(CsrUint8 *buffer, CsrSize *offset, CsrUint16 value) +{ + buffer[*offset + 0] = (CsrUint8) ((value >> 0) & 0xFF); + buffer[*offset + 1] = (CsrUint8) ((value >> 8) & 0xFF); + *offset += sizeof(value); +} +EXPORT_SYMBOL_GPL(CsrUint16Ser); + +void CsrUint32Ser(CsrUint8 *buffer, CsrSize *offset, CsrUint32 value) +{ + buffer[*offset + 0] = (CsrUint8) ((value >> 0) & 0xFF); + buffer[*offset + 1] = (CsrUint8) ((value >> 8) & 0xFF); + buffer[*offset + 2] = (CsrUint8) ((value >> 16) & 0xFF); + buffer[*offset + 3] = (CsrUint8) ((value >> 24) & 0xFF); + *offset += sizeof(value); +} +EXPORT_SYMBOL_GPL(CsrUint32Ser); + +void CsrMemCpySer(CsrUint8 *buffer, CsrSize *offset, const void *value, CsrSize length) +{ + CsrMemCpy(&buffer[*offset], value, length); + *offset += length; +} +EXPORT_SYMBOL_GPL(CsrMemCpySer); + +void CsrCharStringSer(CsrUint8 *buffer, CsrSize *offset, const CsrCharString *value) +{ + if (value) + { + CsrStrCpy(((CsrCharString *) &buffer[*offset]), value); + *offset += CsrStrLen(value) + 1; + } + else + { + CsrUint8Ser(buffer, offset, 0); + } +} +EXPORT_SYMBOL_GPL(CsrCharStringSer); + +void CsrUtf8StringSer(CsrUint8 *buffer, CsrSize *offset, const CsrUtf8String *value) +{ + CsrCharStringSer(buffer, offset, (CsrCharString *) value); +} + +void CsrUtf16StringSer(CsrUint8 *buffer, CsrSize *offset, const CsrUtf16String *value) +{ + if (value) + { + CsrUint32 length = CsrUtf16StrLen(value) + 1; + CsrUint32 i; + + CsrUint32Ser(buffer, offset, length); + + for (i = 0; i < length; i++) + { + CsrUint16Ser(buffer, offset, (CsrUint16) value[i]); + } + } + else + { + CsrUint32Ser(buffer, offset, 0); + } +} + +void CsrSizeSer(CsrUint8 *buffer, CsrSize *offset, CsrSize value) +{ + buffer[*offset + 0] = (CsrUint8) ((value >> 0) & 0xFF); + buffer[*offset + 1] = (CsrUint8) ((value >> 8) & 0xFF); + buffer[*offset + 2] = (CsrUint8) ((value >> 16) & 0xFF); + buffer[*offset + 3] = (CsrUint8) ((value >> 24) & 0xFF); + *offset += sizeof(value); +} + +void CsrVoidPtrSer(CsrUint8 *buffer, CsrSize *offset, void *ptr) +{ + CsrSizeSer(buffer, offset, (CsrSize) ptr); +} + +CsrUint32 CsrCharStringSerLen(const CsrCharString *str) +{ + if (str) + { + return (CsrUint32) (CsrStrLen(str) + sizeof(*str)); + } + else + { + return sizeof(*str); + } +} + +CsrUint32 CsrUtf8StringSerLen(const CsrUtf8String *str) +{ + if (str) + { + return (CsrUint32) (CsrStrLen((CsrCharString *) str) + sizeof(*str)); + } + else + { + return sizeof(*str); + } +} + +CsrUint32 CsrUtf16StringSerLen(const CsrUtf16String *str) +{ + if (str) + { + /* We always write down the length of the string */ + return sizeof(CsrUint32) + (CsrUtf16StrLen(str) + 1) * sizeof(*str); + } + else + { + return sizeof(CsrUint32); + } +} + +CsrSize CsrEventSizeof(void *msg) +{ + return 2; +} + +CsrUint8 *CsrEventSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEvent *primitive = (CsrEvent *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + return ptr; +} + +void *CsrEventDes(CsrUint8 *buffer, CsrSize length) +{ + CsrEvent *primitive = (CsrEvent *) CsrPmemAlloc(sizeof(CsrEvent)); + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint8Sizeof(void *msg) +{ + return 3; +} + +CsrUint8 *CsrEventCsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint8 *primitive = (CsrEventCsrUint8 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint8Ser(ptr, len, primitive->value); + return ptr; +} + +void *CsrEventCsrUint8Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint8 *primitive = (CsrEventCsrUint8 *) CsrPmemAlloc(sizeof(CsrEventCsrUint8)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint8Des(&primitive->value, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint16Sizeof(void *msg) +{ + return 4; +} + +CsrUint8 *CsrEventCsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint16 *primitive = (CsrEventCsrUint16 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint16Ser(ptr, len, primitive->value); + return ptr; +} + +void *CsrEventCsrUint16Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint16 *primitive = (CsrEventCsrUint16 *) CsrPmemAlloc(sizeof(CsrEventCsrUint16)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint16Des(&primitive->value, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint32Sizeof(void *msg) +{ + return 6; +} + +CsrUint8 *CsrEventCsrUint32Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint32 *primitive = (CsrEventCsrUint32 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint32Ser(ptr, len, primitive->value); + return ptr; +} + +void *CsrEventCsrUint32Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint32 *primitive = (CsrEventCsrUint32 *) CsrPmemAlloc(sizeof(CsrEventCsrUint32)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint32Des(&primitive->value, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint16CsrUint8Sizeof(void *msg) +{ + return 5; +} + +CsrUint8 *CsrEventCsrUint16CsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint16CsrUint8 *primitive = (CsrEventCsrUint16CsrUint8 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint16Ser(ptr, len, primitive->value1); + CsrUint8Ser(ptr, len, primitive->value2); + return ptr; +} + +void *CsrEventCsrUint16CsrUint8Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint16CsrUint8 *primitive = (CsrEventCsrUint16CsrUint8 *) CsrPmemAlloc(sizeof(CsrEventCsrUint16CsrUint8)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint16Des(&primitive->value1, buffer, &offset); + CsrUint8Des(&primitive->value2, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint16CsrUint16Sizeof(void *msg) +{ + return 6; +} + +CsrUint8 *CsrEventCsrUint16CsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint16CsrUint16 *primitive = (CsrEventCsrUint16CsrUint16 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint16Ser(ptr, len, primitive->value1); + CsrUint16Ser(ptr, len, primitive->value2); + return ptr; +} + +void *CsrEventCsrUint16CsrUint16Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint16CsrUint16 *primitive = (CsrEventCsrUint16CsrUint16 *) CsrPmemAlloc(sizeof(CsrEventCsrUint16CsrUint16)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint16Des(&primitive->value1, buffer, &offset); + CsrUint16Des(&primitive->value2, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint16CsrUint32Sizeof(void *msg) +{ + return 8; +} + +CsrUint8 *CsrEventCsrUint16CsrUint32Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint16CsrUint32 *primitive = (CsrEventCsrUint16CsrUint32 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint16Ser(ptr, len, primitive->value1); + CsrUint32Ser(ptr, len, primitive->value2); + return ptr; +} + +void *CsrEventCsrUint16CsrUint32Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint16CsrUint32 *primitive = (CsrEventCsrUint16CsrUint32 *) CsrPmemAlloc(sizeof(CsrEventCsrUint16CsrUint32)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint16Des(&primitive->value1, buffer, &offset); + CsrUint32Des(&primitive->value2, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint16CsrCharStringSizeof(void *msg) +{ + CsrEventCsrUint16CsrCharString *primitive = (CsrEventCsrUint16CsrCharString *) msg; + return 4 + CsrStrLen(primitive->value2) + 1; +} + +CsrUint8 *CsrEventCsrUint16CsrCharStringSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint16CsrCharString *primitive = (CsrEventCsrUint16CsrCharString *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint16Ser(ptr, len, primitive->value1); + CsrCharStringSer(ptr, len, primitive->value2); + return ptr; +} + +void *CsrEventCsrUint16CsrCharStringDes(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint16CsrCharString *primitive = (CsrEventCsrUint16CsrCharString *) CsrPmemAlloc(sizeof(CsrEventCsrUint16CsrCharString)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint16Des(&primitive->value1, buffer, &offset); + CsrCharStringDes(&primitive->value2, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint32CsrUint16Sizeof(void *msg) +{ + return 8; +} + +CsrUint8 *CsrEventCsrUint32CsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint32CsrUint16 *primitive = (CsrEventCsrUint32CsrUint16 *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint32Ser(ptr, len, primitive->value1); + CsrUint16Ser(ptr, len, primitive->value2); + return ptr; +} + +void *CsrEventCsrUint32CsrUint16Des(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint32CsrUint16 *primitive = (CsrEventCsrUint32CsrUint16 *) CsrPmemAlloc(sizeof(CsrEventCsrUint32CsrUint16)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint32Des(&primitive->value1, buffer, &offset); + CsrUint16Des(&primitive->value2, buffer, &offset); + + return primitive; +} + +CsrSize CsrEventCsrUint32CsrCharStringSizeof(void *msg) +{ + CsrEventCsrUint32CsrCharString *primitive = (CsrEventCsrUint32CsrCharString *) msg; + return 6 + CsrStrLen(primitive->value2) + 1; +} + +CsrUint8 *CsrEventCsrUint32CsrCharStringSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrEventCsrUint32CsrCharString *primitive = (CsrEventCsrUint32CsrCharString *) msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + CsrUint32Ser(ptr, len, primitive->value1); + CsrCharStringSer(ptr, len, primitive->value2); + return ptr; +} + +void *CsrEventCsrUint32CsrCharStringDes(CsrUint8 *buffer, CsrSize length) +{ + CsrEventCsrUint32CsrCharString *primitive = (CsrEventCsrUint32CsrCharString *) CsrPmemAlloc(sizeof(CsrEventCsrUint32CsrCharString)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + CsrUint32Des(&primitive->value1, buffer, &offset); + CsrCharStringDes(&primitive->value2, buffer, &offset); + + return primitive; +} diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c new file mode 100644 index 000000000000..1ef61e3efac6 --- /dev/null +++ b/drivers/staging/csr/csr_time.c @@ -0,0 +1,71 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) +#include +#include +#endif + +#include +#include + +#include "csr_types.h" +#include "csr_time.h" + +CsrTime CsrTimeGet(CsrTime *high) +{ + struct timespec ts; + CsrUint64 time; + CsrTime low; + + ts = current_kernel_time(); + time = (CsrUint64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + + if (high != NULL) + { + *high = (CsrTime) ((time >> 32) & 0xFFFFFFFF); + } + + low = (CsrTime) (time & 0xFFFFFFFF); + + return low; +} +EXPORT_SYMBOL_GPL(CsrTimeGet); + +void CsrTimeUtcGet(CsrTimeUtc *tod, CsrTime *low, CsrTime *high) +{ + struct timespec ts; + CsrUint64 time; + + ts = current_kernel_time(); + time = (CsrUint64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + + if (high != NULL) + { + *high = (CsrTime) ((time >> 32) & 0xFFFFFFFF); + } + + if (low != NULL) + { + *low = (CsrTime) (time & 0xFFFFFFFF); + } + + if (tod != NULL) + { + struct timeval tv; + do_gettimeofday(&tv); + tod->sec = tv.tv_sec; + tod->msec = tv.tv_usec / 1000; + } +} diff --git a/drivers/staging/csr/csr_time.h b/drivers/staging/csr/csr_time.h new file mode 100644 index 000000000000..0ede47e911f1 --- /dev/null +++ b/drivers/staging/csr/csr_time.h @@ -0,0 +1,205 @@ +#ifndef CSR_TIME_H__ +#define CSR_TIME_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + + NAME + CsrTime + + DESCRIPTION + Type to hold a value describing the current system time, which is a + measure of time elapsed since some arbitrarily defined fixed time + reference, usually associated with system startup. + +*******************************************************************************/ +typedef CsrUint32 CsrTime; + + +/******************************************************************************* + + NAME + CsrTimeUtc + + DESCRIPTION + Type to hold a value describing a UTC wallclock time expressed in + seconds and milliseconds elapsed since midnight January 1st 1970. + +*******************************************************************************/ +typedef struct +{ + CsrUint32 sec; + CsrUint16 msec; +} CsrTimeUtc; + + +/******************************************************************************* + + NAME + CsrTimeGet + + DESCRIPTION + Returns the current system time in a low and a high part. The low part + is expressed in microseconds. The high part is incremented when the low + part wraps to provide an extended range. + + The caller may provide a NULL pointer as the high parameter. In this case + the function just returns the low part and ignores the high parameter. + + Although the time is expressed in microseconds the actual resolution is + platform dependent and can be less. It is recommended that the + resolution is at least 10 milliseconds. + + PARAMETERS + high - Pointer to variable that will receive the high part of the + current system time. Passing NULL is valid. + + RETURNS + Low part of current system time in microseconds. + +*******************************************************************************/ +CsrTime CsrTimeGet(CsrTime *high); + + +/******************************************************************************* + + NAME + CsrTimeUtcGet + + DESCRIPTION + Get the current system wallclock time, and optionally the current system + time in a low and a high part as would have been returned by + CsrTimeGet. + + Although CsrTimeUtc is expressed in seconds and milliseconds, the actual + resolution is platform dependent, and can be less. It is recommended + that the resolution is at least 1 second. + + PARAMETERS + tod - Pointer to variable that will receive the current system + wallclock time. + low - The low part of the current system time in microseconds. Passing + NULL is valid. + high - The high part of the current system time in microseconds. Passing + NULL is valid. + +*******************************************************************************/ +void CsrTimeUtcGet(CsrTimeUtc *tod, CsrTime *low, CsrTime *high); + + +/*------------------------------------------------------------------*/ +/* CsrTime Macros */ +/*------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeAdd + * + * DESCRIPTION + * Add two time values. Adding the numbers can overflow the range of a + * CsrTime, so the user must be cautious. + * + * RETURNS + * CsrTime - the sum of "t1" and "t2". + * + *----------------------------------------------------------------------------*/ +#define CsrTimeAdd(t1, t2) ((t1) + (t2)) + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeSub + * + * DESCRIPTION + * Subtract two time values. Subtracting the numbers can provoke an + * underflow, so the user must be cautious. + * + * RETURNS + * CsrTime - "t1" - "t2". + * + *----------------------------------------------------------------------------*/ +#define CsrTimeSub(t1, t2) ((CsrInt32) (t1) - (CsrInt32) (t2)) + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeEq + * + * DESCRIPTION + * Compare two time values. + * + * RETURNS + * !0 if "t1" equal "t2", else 0. + * + *----------------------------------------------------------------------------*/ +#define CsrTimeEq(t1, t2) ((t1) == (t2)) + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeGt + * + * DESCRIPTION + * Compare two time values. + * + * RETURNS + * !0 if "t1" is greater than "t2", else 0. + * + *----------------------------------------------------------------------------*/ +#define CsrTimeGt(t1, t2) (CsrTimeSub((t1), (t2)) > 0) + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeGe + * + * DESCRIPTION + * Compare two time values. + * + * RETURNS + * !0 if "t1" is greater than, or equal to "t2", else 0. + * + *----------------------------------------------------------------------------*/ +#define CsrTimeGe(t1, t2) (CsrTimeSub((t1), (t2)) >= 0) + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeLt + * + * DESCRIPTION + * Compare two time values. + * + * RETURNS + * !0 if "t1" is less than "t2", else 0. + * + *----------------------------------------------------------------------------*/ +#define CsrTimeLt(t1, t2) (CsrTimeSub((t1), (t2)) < 0) + +/*----------------------------------------------------------------------------* + * NAME + * CsrTimeLe + * + * DESCRIPTION + * Compare two time values. + * + * RETURNS + * !0 if "t1" is less than, or equal to "t2", else 0. + * + *----------------------------------------------------------------------------*/ +#define CsrTimeLe(t1, t2) (CsrTimeSub((t1), (t2)) <= 0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_types.h b/drivers/staging/csr/csr_types.h new file mode 100644 index 000000000000..d7d2c5d061fe --- /dev/null +++ b/drivers/staging/csr/csr_types.h @@ -0,0 +1,93 @@ +#ifndef CSR_TYPES_H__ +#define CSR_TYPES_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#undef FALSE +#define FALSE (0) + +#undef TRUE +#define TRUE (1) + +/* Basic types */ +typedef size_t CsrSize; /* Return type of sizeof (ISO/IEC 9899:1990 7.1.6) */ +typedef ptrdiff_t CsrPtrdiff; /* Type of the result of subtracting two pointers (ISO/IEC 9899:1990 7.1.6) */ +typedef uintptr_t CsrUintptr; /* Unsigned integer large enough to hold any pointer (ISO/IEC 9899:1999 7.18.1.4) */ +#ifdef __KERNEL__ +typedef ptrdiff_t CsrIntptr; /* intptr_t is not defined in kernel. Use the equivalent ptrdiff_t. */ +#else +typedef intptr_t CsrIntptr; /* Signed integer large enough to hold any pointer (ISO/IEC 9899:1999 7.18.1.4) */ +#endif + +/* Unsigned fixed width types */ +typedef uint8_t CsrUint8; +typedef uint16_t CsrUint16; +typedef uint32_t CsrUint32; + +/* Signed fixed width types */ +typedef int8_t CsrInt8; +typedef int16_t CsrInt16; +typedef int32_t CsrInt32; + +/* Boolean */ +typedef CsrUint8 CsrBool; + +/* String types */ +typedef char CsrCharString; +typedef CsrUint8 CsrUtf8String; +typedef CsrUint16 CsrUtf16String; /* 16-bit UTF16 strings */ +typedef CsrUint32 CsrUint24; + +/* + * 64-bit integers + * + * Note: If a given compiler does not support 64-bit types, it is + * OK to omit these definitions; 32-bit versions of the code using + * these types may be available. Consult the relevant documentation + * or the customer support group for information on this. + */ +#define CSR_HAVE_64_BIT_INTEGERS +typedef uint64_t CsrUint64; +typedef int64_t CsrInt64; + +/* + * Floating point + * + * Note: If a given compiler does not support floating point, it is + * OK to omit these definitions; alternative versions of the code using + * these types may be available. Consult the relevant documentation + * or the customer support group for information on this. + */ +#define CSR_HAVE_FLOATING_POINT +typedef float CsrFloat; +typedef double CsrDouble; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_unicode.h b/drivers/staging/csr/csr_unicode.h new file mode 100644 index 000000000000..9faf8567a5a1 --- /dev/null +++ b/drivers/staging/csr/csr_unicode.h @@ -0,0 +1,190 @@ +#ifndef CSR_UNICODE_H__ +#define CSR_UNICODE_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CsrUtf16String *CsrUint32ToUtf16String(CsrUint32 number); + +CsrUint32 CsrUtf16StringToUint32(const CsrUtf16String *unicodeString); +CsrUint32 CsrUtf16StrLen(const CsrUtf16String *unicodeString); + +CsrUtf8String *CsrUtf16String2Utf8(const CsrUtf16String *source); + +CsrUtf16String *CsrUtf82Utf16String(const CsrUtf8String *utf8String); + +CsrUtf16String *CsrUtf16StrCpy(CsrUtf16String *target, const CsrUtf16String *source); +CsrUtf16String *CsrUtf16StringDuplicate(const CsrUtf16String *source); + +CsrUint16 CsrUtf16StrICmp(const CsrUtf16String *string1, const CsrUtf16String *string2); +CsrUint16 CsrUtf16StrNICmp(const CsrUtf16String *string1, const CsrUtf16String *string2, CsrUint32 count); + +CsrUtf16String *CsrUtf16MemCpy(CsrUtf16String *dest, const CsrUtf16String *src, CsrUint32 count); +CsrUtf16String *CsrUtf16ConcatenateTexts(const CsrUtf16String *inputText1, const CsrUtf16String *inputText2, + const CsrUtf16String *inputText3, const CsrUtf16String *inputText4); + +CsrUtf16String *CsrUtf16String2XML(CsrUtf16String *str); +CsrUtf16String *CsrXML2Utf16String(CsrUtf16String *str); + +CsrInt32 CsrUtf8StrCmp(const CsrUtf8String *string1, const CsrUtf8String *string2); +CsrInt32 CsrUtf8StrNCmp(const CsrUtf8String *string1, const CsrUtf8String *string2, CsrSize count); +CsrUint32 CsrUtf8StringLengthInBytes(const CsrUtf8String *string); + +/******************************************************************************* + + NAME + CsrUtf8StrTruncate + + DESCRIPTION + In-place truncate a string on a UTF-8 character boundary by writing a + null character somewhere in the range target[count - 3]:target[count]. + + Please note that memory passed must be at least of length count + 1, to + ensure space for a full length string that is terminated at + target[count], in the event that target[count - 1] is the final byte of + a UTF-8 character. + + PARAMETERS + target - Target string to truncate. + count - The desired length, in bytes, of the resulting string. Depending + on the contents, the resulting string length will be between + count - 3 and count. + + RETURNS + Returns target + +*******************************************************************************/ +CsrUtf8String *CsrUtf8StrTruncate(CsrUtf8String *target, CsrSize count); + +/******************************************************************************* + + NAME + CsrUtf8StrCpy + + DESCRIPTION + Copies the null terminated UTF-8 string pointed at by source into the + memory pointed at by target, including the terminating null character. + + To avoid overflows, the size of the memory pointed at by target shall be + long enough to contain the same UTF-8 string as source (including the + terminating null character), and should not overlap in memory with + source. + + PARAMETERS + target - Pointer to the target memory where the content is to be copied. + source - UTF-8 string to be copied. + + RETURNS + Returns target + +*******************************************************************************/ +CsrUtf8String *CsrUtf8StrCpy(CsrUtf8String *target, const CsrUtf8String *source); + +/******************************************************************************* + + NAME + CsrUtf8StrNCpy + + DESCRIPTION + Copies the first count bytes of source to target. If the end of the + source UTF-8 string (which is signaled by a null-character) is found + before count bytes have been copied, target is padded with null + characters until a total of count bytes have been written to it. + + No null-character is implicitly appended to the end of target, so target + will only be null-terminated if the length of the UTF-8 string in source + is less than count. + + PARAMETERS + target - Pointer to the target memory where the content is to be copied. + source - UTF-8 string to be copied. + count - Maximum number of bytes to be written to target. + + RETURNS + Returns target + +*******************************************************************************/ +CsrUtf8String *CsrUtf8StrNCpy(CsrUtf8String *target, const CsrUtf8String *source, CsrSize count); + +/******************************************************************************* + + NAME + CsrUtf8StrNCpyZero + + DESCRIPTION + Equivalent to CsrUtf8StrNCpy, but if the length of source is equal to or + greater than count the target string is truncated on a UTF-8 character + boundary by writing a null character somewhere in the range + target[count - 4]:target[count - 1], leaving the target string + unconditionally null terminated in all cases. + + Please note that if the length of source is shorter than count, no + truncation will be applied, and the target string will be a one to one + copy of source. + + PARAMETERS + target - Pointer to the target memory where the content is to be copied. + source - UTF-8 string to be copied. + count - Maximum number of bytes to be written to target. + + RETURNS + Returns target + +*******************************************************************************/ +CsrUtf8String *CsrUtf8StrNCpyZero(CsrUtf8String *target, const CsrUtf8String *source, CsrSize count); + +/******************************************************************************* + + NAME + CsrUtf8StrDup + + DESCRIPTION + This function will allocate memory and copy the source string into the + allocated memory, which is then returned as a duplicate of the original + string. The memory returned must be freed by calling CsrPmemFree when + the duplicate is no longer needed. + + PARAMETERS + source - UTF-8 string to be duplicated. + + RETURNS + Returns a duplicate of source. + +*******************************************************************************/ +CsrUtf8String *CsrUtf8StrDup(const CsrUtf8String *source); + +CsrUtf8String *CsrUtf8StringConcatenateTexts(const CsrUtf8String *inputText1, const CsrUtf8String *inputText2, const CsrUtf8String *inputText3, const CsrUtf8String *inputText4); + +/* + * UCS2 + * + * D-13157 + */ +typedef CsrUint8 CsrUcs2String; + +CsrSize CsrUcs2ByteStrLen(const CsrUcs2String *ucs2String); +CsrSize CsrConverterUcs2ByteStrLen(const CsrUcs2String *str); + +CsrUint8 *CsrUcs2ByteString2Utf8(const CsrUcs2String *ucs2String); +CsrUcs2String *CsrUtf82Ucs2ByteString(const CsrUint8 *utf8String); + +CsrUint8 *CsrUtf16String2Ucs2ByteString(const CsrUtf16String *source); +CsrUtf16String *CsrUcs2ByteString2Utf16String(const CsrUint8 *source); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_utf16.c b/drivers/staging/csr/csr_utf16.c new file mode 100644 index 000000000000..9259635851f7 --- /dev/null +++ b/drivers/staging/csr/csr_utf16.c @@ -0,0 +1,1136 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#include +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_unicode.h" +#include "csr_util.h" + +#define UNI_SUR_HIGH_START ((CsrUint32) 0xD800) +#define UNI_SUR_HIGH_END ((CsrUint32) 0xDBFF) +#define UNI_SUR_LOW_START ((CsrUint32) 0xDC00) +#define UNI_SUR_LOW_END ((CsrUint32) 0xDFFF) +#define UNI_REPLACEMENT_CHAR ((CsrUint32) 0xFFFD) +#define UNI_HALF_SHIFT ((CsrUint8) 10) /* used for shifting by 10 bits */ +#define UNI_HALF_BASE ((CsrUint32) 0x00010000) +#define UNI_BYTEMASK ((CsrUint32) 0xBF) +#define UNI_BYTEMARK ((CsrUint32) 0x80) + +#define CAPITAL(x) ((x >= 'a') && (x <= 'z') ? ((x) & 0x00DF) : (x)) + +/* +* Index into the table with the first byte to get the number of trailing bytes in a utf-8 character. +* -1 if the byte has an invalid value. +* +* Legal sequences are: +* +* byte 1st 2nd 3rd 4th +* +* 00-7F +* C2-DF 80-BF +* E0 A0-BF 80-BF +* E1-EC 80-BF 80-BF +* ED 80-9F 80-BF +* EE-EF 80-BF 80-BF +* F0 90-BF 80-BF 80-BF +* F1-F3 80-BF 80-BF 80-BF +* F4 80-8F 80-BF 80-BF +*/ +static const CsrInt8 trailingBytesForUtf8[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x1F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x3F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x5F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x7F */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 - 0x9F */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 - 0xBF */ + -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xC0 - 0xDF */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 - 0xFF */ +}; + +/* Values to be substracted from a CsrUint32 when converting from UTF8 to UTF16 */ +static const CsrUint32 offsetsFromUtf8[4] = +{ + 0x00000000, 0x00003080, 0x000E2080, 0x03C82080 +}; + +/******************************************************************************** +* +* Name: CsrUint32ToUtf16String +* +* Description: The function converts an 32 bit number to an UTF-16 string +* that is allocated and 0-terminated. +* +* Input: 32 bit number. +* +* Output: A string of UTF-16 characters. +* +*********************************************************************************/ +CsrUtf16String *CsrUint32ToUtf16String(CsrUint32 number) +{ + CsrUint16 count, noOfDigits; + CsrUtf16String *output; + CsrUint32 tempNumber; + + /* calculate the number of digits in the output */ + tempNumber = number; + noOfDigits = 1; + while (tempNumber >= 10) + { + tempNumber = tempNumber / 10; + noOfDigits++; + } + + output = (CsrUtf16String *) CsrPmemAlloc(sizeof(CsrUtf16String) * (noOfDigits + 1)); /*add space for 0-termination*/ + + tempNumber = number; + for (count = noOfDigits; count > 0; count--) + { + output[count - 1] = (CsrUtf16String) ((tempNumber % 10) + '0'); + tempNumber = tempNumber / 10; + } + output[noOfDigits] = '\0'; + + return output; +} + +/******************************************************************************** +* +* Name: CsrUtf16StringToUint32 +* +* Description: The function converts an UTF-16 string that is +* 0-terminated into a 32 bit number. +* +* Input: A string of UTF-16 characters containig a number. +* +* Output: 32 bit number. +* +*********************************************************************************/ +CsrUint32 CsrUtf16StringToUint32(const CsrUtf16String *unicodeString) +{ + CsrUint16 numLen, count; + CsrUint32 newNumber = 0; + + numLen = (CsrUint16) CsrUtf16StrLen(unicodeString); + + if ((numLen > 10) || (numLen == 0) || (unicodeString == NULL)) /*CSRMAX number is 4.294.967.295 */ + { + return 0; + } + + for (count = 0; count < numLen; count++) + { + CsrUtf16String input = unicodeString[count]; + if ((input < 0x30) || (input > 0x39) || ((newNumber == 0x19999999) && (input > 0x35)) || (newNumber > 0x19999999)) /* chars are present or number is too large now causing number to get to large when *10 */ + { + return 0; + } + + newNumber = (newNumber * 10) + (input - 0x30); + } + return newNumber; +} + +/******************************************************************************** +* +* Name: CsrUtf16MemCpy +* +* Description: The function copies count number of 16 bit data elements +* from srv to dest. +* +* Input: A pointer to an unicoded string. +* +* Output: A pointer to an unicoded string. +* +*********************************************************************************/ +CsrUtf16String *CsrUtf16MemCpy(CsrUtf16String *dest, const CsrUtf16String *src, CsrUint32 count) +{ + return CsrMemCpy((CsrUint8 *) dest, (CsrUint8 *) src, count * sizeof(CsrUtf16String)); +} + +/******************************************************************************** +* +* Name: CsrUtf16ConcatenateTexts +* +* Description: The function merge the contents of 4 unicoded input pointers +* into a new string. +* +* Input: 4 unicoded input strings (UTF-16). +* +* Output: A new unicoded string (UTF-16) containing the combined strings. +* +*********************************************************************************/ +CsrUtf16String *CsrUtf16ConcatenateTexts(const CsrUtf16String *inputText1, const CsrUtf16String *inputText2, + const CsrUtf16String *inputText3, const CsrUtf16String *inputText4) +{ + CsrUtf16String *outputText; + CsrUint32 textLen, textLen1, textLen2, textLen3, textLen4; + + textLen1 = CsrUtf16StrLen(inputText1); + textLen2 = CsrUtf16StrLen(inputText2); + textLen3 = CsrUtf16StrLen(inputText3); + textLen4 = CsrUtf16StrLen(inputText4); + + textLen = textLen1 + textLen2 + textLen3 + textLen4; + + if (textLen == 0) /*stop here is all lengths are 0*/ + { + return NULL; + } + + outputText = (CsrUtf16String *) CsrPmemAlloc((textLen + 1) * sizeof(CsrUtf16String)); /* add space for 0-termination*/ + + + if (inputText1 != NULL) + { + CsrUtf16MemCpy(outputText, inputText1, textLen1); + } + + if (inputText2 != NULL) + { + CsrUtf16MemCpy(&(outputText[textLen1]), inputText2, textLen2); + } + + if (inputText3 != NULL) + { + CsrUtf16MemCpy(&(outputText[textLen1 + textLen2]), inputText3, textLen3); + } + + if (inputText4 != NULL) + { + CsrUtf16MemCpy(&(outputText[textLen1 + textLen2 + textLen3]), inputText4, textLen4); + } + + outputText[textLen] = '\0'; + + return outputText; +} + +/******************************************************************************** +* +* Name: CsrUtf16StrLen +* +* Description: The function returns the number of 16 bit elements present +* in the 0-terminated string. +* +* Input: 0-terminated string of 16 bit unicoded characters. +* +* Output: The number of 16 bit elements in the string. +* +*********************************************************************************/ +CsrUint32 CsrUtf16StrLen(const CsrUtf16String *unicodeString) +{ + CsrUint32 length; + + length = 0; + if (unicodeString != NULL) + { + while (*unicodeString) + { + length++; + unicodeString++; + } + } + return length; +} + +/******************************************************************************** +* +* Name: CsrUtf16String2Utf8 +* +* Description: The function decodes an UTF-16 string into an UTF8 byte +* oriented string. +* +* Input: 0-terminated UTF-16 string characters. +* +* Output: 0-terminated string of byte oriented UTF8 coded characters. +* +*********************************************************************************/ +CsrUtf8String *CsrUtf16String2Utf8(const CsrUtf16String *source) +{ + CsrUtf8String *dest, *destStart = NULL; + CsrUint32 i; + CsrUint32 ch; + CsrUint32 length; + CsrUint32 sourceLength; + CsrUint8 bytes; + CsrBool appendNull = FALSE; + + CsrUint8 firstByteMark[5] = {0x00, 0x00, 0xC0, 0xE0, 0xF0}; + + if (!source) + { + return NULL; + } + + length = 0; + sourceLength = CsrUtf16StrLen(source) + 1; + + for (i = 0; i < sourceLength; i++) + { + ch = source[i]; + if ((ch >= UNI_SUR_HIGH_START) && (ch <= UNI_SUR_HIGH_END)) /* This is a high surrogate */ + { + if (i + 1 < sourceLength) /* The low surrogate is in the source */ + { + CsrUint32 ch2 = source[++i]; + if ((ch2 >= UNI_SUR_LOW_START) && (ch2 <= UNI_SUR_LOW_END)) /* And it is a legal low surrogate */ + { + length += 4; + } + else /* It is not a low surrogate, instead put a Unicode + 'REPLACEMENT CHARACTER' (U+FFFD) */ + { + length += 3; + i--; /* Substract 1 again as the conversion must continue after the ill-formed code unit */ + } + } + else /* The low surrogate does not exist, instead put a Unicode + 'REPLACEMENT CHARACTER' (U+FFFD), and the null terminated character */ + { + length += 4; + } + } + else if ((ch >= UNI_SUR_LOW_START) && (ch <= UNI_SUR_LOW_END)) /* The value of UTF-16 is not allowed to be in this range, instead put + a Unicode 'REPLACEMENT CHARACTER' (U+FFFD) */ + { + length += 3; + } + else /* Figure out how many bytes that are required */ + { + if (ch < 0x0080) + { + length++; + } + else if (ch < 0x0800) + { + length += 2; + } + else + { + length += 3; + } + } + } + + dest = CsrPmemAlloc(length); + destStart = dest; + + for (i = 0; i < sourceLength; i++) + { + ch = source[i]; + if ((ch >= UNI_SUR_HIGH_START) && (ch <= UNI_SUR_HIGH_END)) /* This is a high surrogate */ + { + if (i + 1 < sourceLength) /* The low surrogate is in the source */ + { + CsrUint32 ch2 = source[++i]; + if ((ch2 >= UNI_SUR_LOW_START) && (ch2 <= UNI_SUR_LOW_END)) /* And it is a legal low surrogate, convert to UTF-32 */ + { + ch = ((ch - UNI_SUR_HIGH_START) << UNI_HALF_SHIFT) + (ch2 - UNI_SUR_LOW_START) + UNI_HALF_BASE; + } + else /* It is not a low surrogate, instead put a Unicode + 'REPLACEMENT CHARACTER' (U+FFFD) */ + { + ch = UNI_REPLACEMENT_CHAR; + i--; /* Substract 1 again as the conversion must continue after the ill-formed code unit */ + } + } + else /* The low surrogate does not exist, instead put a Unicode + 'REPLACEMENT CHARACTER' (U+FFFD), and the null terminated character */ + { + ch = UNI_REPLACEMENT_CHAR; + appendNull = TRUE; + } + } + else if ((ch >= UNI_SUR_LOW_START) && (ch <= UNI_SUR_LOW_END)) /* The value of UTF-16 is not allowed to be in this range, instead put + a Unicode 'REPLACEMENT CHARACTER' (U+FFFD) */ + { + ch = UNI_REPLACEMENT_CHAR; + } + + /* Figure out how many bytes that are required */ + if (ch < (CsrUint32) 0x80) + { + bytes = 1; + } + else if (ch < (CsrUint32) 0x800) + { + bytes = 2; + } + else if (ch < (CsrUint32) 0x10000) + { + bytes = 3; + } + else if (ch < (CsrUint32) 0x110000) + { + bytes = 4; + } + else + { + bytes = 3; + ch = UNI_REPLACEMENT_CHAR; + } + + dest += bytes; + + switch (bytes) /* Convert character to UTF-8. Note: everything falls through. */ + { + case 4: + { + *--dest = (CsrUint8) ((ch | UNI_BYTEMARK) & UNI_BYTEMASK); + ch >>= 6; + } + /* FALLTHROUGH */ + case 3: + { + *--dest = (CsrUint8) ((ch | UNI_BYTEMARK) & UNI_BYTEMASK); + ch >>= 6; + } + /* FALLTHROUGH */ + case 2: + { + *--dest = (CsrUint8) ((ch | UNI_BYTEMARK) & UNI_BYTEMASK); + ch >>= 6; + } + /* FALLTHROUGH */ + case 1: + { + *--dest = (CsrUint8) (ch | firstByteMark[bytes]); + } + /* FALLTHROUGH */ + default: + { + break; + } + } + + dest += bytes; + } + + if (appendNull) /* Append the \0 character */ + { + *dest = '\0'; + } + + return destStart; +} + +/***************************************************************************** + + NAME + isLegalUtf8 + + DESCRIPTION + Returns TRUE if the given UFT-8 code unit is legal as defined by the + Unicode standard (see Chapter 3: Conformance, Section 3.9: Unicode + Encoding Forms, UTF-8). + + This function assumes that the length parameter is unconditionally + correct and that the first byte is already validated by looking it up + in the trailingBytesForUtf8 array, which also reveals the number of + trailing bytes. + + Legal code units are composed of one of the following byte sequences: + + 1st 2nd 3rd 4th + -------------------------------- + 00-7F + C2-DF 80-BF + E0 A0-BF 80-BF + E1-EC 80-BF 80-BF + ED 80-9F 80-BF + EE-EF 80-BF 80-BF + F0 90-BF 80-BF 80-BF + F1-F3 80-BF 80-BF 80-BF + F4 80-8F 80-BF 80-BF + + Please note that this function only checks whether the 2nd, 3rd and + 4th bytes fall into the valid ranges. + + PARAMETERS + codeUnit - pointer to the first byte of the byte sequence composing + the code unit to test. + length - the number of bytes in the code unit. Valid range is 1 to 4. + + RETURNS + TRUE if the given code unit is legal. + +*****************************************************************************/ +static CsrBool isLegalUtf8(const CsrUtf8String *codeUnit, CsrUint32 length) +{ + const CsrUtf8String *srcPtr = codeUnit + length; + CsrUint8 byte; + + switch (length) /* Everything falls through except case 1 */ + { + case 4: + { + byte = *--srcPtr; + if ((byte < 0x80) || (byte > 0xBF)) + { + return FALSE; + } + } + /* Fallthrough */ + case 3: + { + byte = *--srcPtr; + if ((byte < 0x80) || (byte > 0xBF)) + { + return FALSE; + } + } + /* Fallthrough */ + case 2: + { + byte = *--srcPtr; + if (byte > 0xBF) + { + return FALSE; + } + + switch (*codeUnit) /* No fallthrough */ + { + case 0xE0: + { + if (byte < 0xA0) + { + return FALSE; + } + break; + } + case 0xED: + { + if ((byte < 0x80) || (byte > 0x9F)) + { + return FALSE; + } + break; + } + case 0xF0: + { + if (byte < 0x90) + { + return FALSE; + } + break; + } + case 0xF4: + { + if ((byte < 0x80) || (byte > 0x8F)) + { + return FALSE; + } + break; + } + default: + { + if (byte < 0x80) + { + return FALSE; + } + break; + } + } + } + /* Fallthrough */ + case 1: + default: + /* The 1st byte and length are assumed correct */ + break; + } + + return TRUE; +} + +/******************************************************************************** +* +* Name: CsrUtf82Utf16String +* +* Description: The function decodes an UTF8 byte oriented string into a +* UTF-16string. +* +* Input: 0-terminated string of byte oriented UTF8 coded characters. +* +* Output: 0-terminated string of UTF-16 characters. +* +*********************************************************************************/ +CsrUtf16String *CsrUtf82Utf16String(const CsrUtf8String *utf8String) +{ + CsrSize i, length = 0; + CsrSize sourceLength; + CsrUtf16String *dest = NULL; + CsrUtf16String *destStart = NULL; + CsrInt8 extraBytes2Read; + + if (!utf8String) + { + return NULL; + } + sourceLength = CsrStrLen((CsrCharString *) utf8String); + + for (i = 0; i < sourceLength; i++) + { + extraBytes2Read = trailingBytesForUtf8[utf8String[i]]; + + if (extraBytes2Read == -1) /* Illegal byte value, instead put a Unicode 'REPLACEMENT CHARACTER' (U+FFFD) */ + { + length += 1; + } + else if (i + extraBytes2Read > sourceLength) /* The extra bytes does not exist, instead put a Unicode 'REPLACEMENT + CHARACTER' (U+FFFD), and the null terminated character */ + { + length += 2; + break; + } + else if (isLegalUtf8(&utf8String[i], extraBytes2Read + 1) == FALSE) /* It is not a legal utf-8 character, instead put a Unicode 'REPLACEMENT + CHARACTER' (U+FFFD) */ + { + length += 1; + } + else + { + if (utf8String[i] > 0xEF) /* Needs a high and a low surrogate */ + { + length += 2; + } + else + { + length += 1; + } + i += extraBytes2Read; + } + } + + /* Create space for the null terminated character */ + dest = (CsrUtf16String *) CsrPmemAlloc((1 + length) * sizeof(CsrUtf16String)); + destStart = dest; + + for (i = 0; i < sourceLength; i++) + { + extraBytes2Read = trailingBytesForUtf8[utf8String[i]]; + + if (extraBytes2Read == -1) /* Illegal byte value, instead put a Unicode 'REPLACEMENT CHARACTER' (U+FFFD) */ + { + *dest++ = UNI_REPLACEMENT_CHAR; + } + else if (i + extraBytes2Read > sourceLength) /* The extra bytes does not exist, instead put a Unicode 'REPLACEMENT + CHARACTER' (U+FFFD), and the null terminated character */ + { + *dest++ = UNI_REPLACEMENT_CHAR; + *dest++ = '\0'; + break; + } + else if (isLegalUtf8(&utf8String[i], extraBytes2Read + 1) == FALSE) /* It is not a legal utf-8 character, instead put a Unicode 'REPLACEMENT + CHARACTER' (U+FFFD) */ + { + *dest++ = UNI_REPLACEMENT_CHAR; + } + else /* It is legal, convert the character to an CsrUint32 */ + { + CsrUint32 ch = 0; + + switch (extraBytes2Read) /* Everything falls through */ + { + case 3: + { + ch += utf8String[i]; + ch <<= 6; + i++; + } + /* FALLTHROUGH */ + case 2: + { + ch += utf8String[i]; + ch <<= 6; + i++; + } + /* FALLTHROUGH */ + case 1: + { + ch += utf8String[i]; + ch <<= 6; + i++; + } + /* FALLTHROUGH */ + case 0: + { + ch += utf8String[i]; + } + /* FALLTHROUGH */ + default: + { + break; + } + } + + ch -= offsetsFromUtf8[extraBytes2Read]; + + if (ch <= 0xFFFF) /* Character can be encoded in one CsrUint16 */ + { + *dest++ = (CsrUint16) ch; + } + else /* The character needs two CsrUint16 */ + { + ch -= UNI_HALF_BASE; + *dest++ = (CsrUint16) ((ch >> UNI_HALF_SHIFT) | UNI_SUR_HIGH_START); + *dest++ = (CsrUint16) ((ch & 0x03FF) | UNI_SUR_LOW_START); + } + } + } + + destStart[length] = 0x00; + + return destStart; +} + +/******************************************************************************** +* +* Name: CsrUtf16StrCpy +* +* Description: The function copies the contents from one UTF-16 string +* to another UTF-16 string. +* +* Input: 0-terminated UTF-16 string. +* +* Output: 0-terminated UTF-16 string. +* +*********************************************************************************/ +CsrUtf16String *CsrUtf16StrCpy(CsrUtf16String *target, const CsrUtf16String *source) +{ + if (source) /* if source is not NULL*/ + { + CsrMemCpy(target, source, (CsrUtf16StrLen(source) + 1) * sizeof(CsrUtf16String)); + return target; + } + else + { + return NULL; + } +} + +/******************************************************************************** +* +* Name: CsrUtf16StringDuplicate +* +* Description: The function allocates a new pointer and copies the input to +* the new pointer. +* +* Input: 0-terminated UTF-16 string. +* +* Output: Allocated variable0-terminated UTF-16 string. +* +*********************************************************************************/ +CsrUtf16String *CsrUtf16StringDuplicate(const CsrUtf16String *source) +{ + CsrUtf16String *target = NULL; + CsrUint32 length; + + if (source) /* if source is not NULL*/ + { + length = (CsrUtf16StrLen(source) + 1) * sizeof(CsrUtf16String); + target = (CsrUtf16String *) CsrPmemAlloc(length); + CsrMemCpy(target, source, length); + } + return target; +} + +/******************************************************************************** +* +* Name: CsrUtf16StrICmp +* +* Description: The function compares two UTF-16 strings. +* +* Input: Two 0-terminated UTF-16 string. +* +* Output: 0: if the strings are identical. +* +*********************************************************************************/ +CsrUint16 CsrUtf16StrICmp(const CsrUtf16String *string1, const CsrUtf16String *string2) +{ + while (*string1 || *string2) + { + if (CAPITAL(*string1) != CAPITAL(*string2)) + { + return *string1 - *string2; + } + string1++; + string2++; + } + + return 0; +} + +/******************************************************************************** +* +* Name: CsrUtf16StrNICmp +* +* Description: The function compares upto count number of elements in the +* two UTF-16 string. +* +* Input: Two 0-terminated UTF-16 string and a maximum +* number of elements to check. +* +* Output: 0: if the strings are identical. +* +*********************************************************************************/ +CsrUint16 CsrUtf16StrNICmp(const CsrUtf16String *string1, const CsrUtf16String *string2, CsrUint32 count) +{ + while ((*string1 || *string2) && count--) + { + if (CAPITAL(*string1) != CAPITAL(*string2)) + { + return *string1 - *string2; + } + string1++; + string2++; + } + + return 0; +} + +/******************************************************************************** +* +* Name: CsrUtf16String2XML +* +* Description: The function converts an unicoded string (UTF-16) into an unicoded XML +* string where some special characters are encoded according to +* the XML spec. +* +* Input: A unicoded string (UTF-16) which is freed. +* +* Output: A new unicoded string (UTF-16) containing the converted output. +* +*********************************************************************************/ +CsrUtf16String *CsrUtf16String2XML(CsrUtf16String *str) +{ + CsrUtf16String *scanString; + CsrUtf16String *outputString = NULL; + CsrUtf16String *resultString = str; + CsrUint32 stringLength = 0; + CsrBool encodeChars = FALSE; + + scanString = str; + if (scanString) + { + while (*scanString) + { + if (*scanString == L'&') + { + stringLength += 5; + encodeChars = TRUE; + } + else if ((*scanString == L'<') || (*scanString == L'>')) + { + stringLength += 4; + encodeChars = TRUE; + } + else + { + stringLength++; + } + + scanString++; + } + + stringLength++; + + if (encodeChars) + { + resultString = outputString = CsrPmemAlloc(stringLength * sizeof(CsrUtf16String)); + + scanString = str; + + while (*scanString) + { + if (*scanString == L'&') + { + *outputString++ = '&'; + *outputString++ = 'a'; + *outputString++ = 'm'; + *outputString++ = 'p'; + *outputString++ = ';'; + } + else if (*scanString == L'<') + { + *outputString++ = '&'; + *outputString++ = 'l'; + *outputString++ = 't'; + *outputString++ = ';'; + } + else if (*scanString == L'>') + { + *outputString++ = '&'; + *outputString++ = 'g'; + *outputString++ = 't'; + *outputString++ = ';'; + } + else + { + *outputString++ = *scanString; + } + + scanString++; + } + + *outputString++ = 0; + + CsrPmemFree(str); + } + } + + return resultString; +} + +/******************************************************************************** +* +* Name: CsrXML2Utf16String +* +* Description: The function converts an unicoded XML string into an unicoded +* string (UTF-16) where some special XML characters are decoded according to +* the XML spec. +* +* Input: A unicoded XML string which is freed. +* +* Output: A new unicoded pointer containing the decoded output. +* +*********************************************************************************/ +CsrUtf16String *CsrXML2Utf16String(CsrUtf16String *str) +{ + CsrUtf16String *scanString; + CsrUtf16String *outputString = NULL; + CsrUtf16String *resultString = str; + CsrUint32 stringLength = 0; + CsrBool encodeChars = FALSE; + + scanString = str; + if (scanString) + { + while (*scanString) + { + if (*scanString == (CsrUtf16String) L'&') + { + scanString++; + + if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"AMP;", 4)) + { + scanString += 3; + encodeChars = TRUE; + } + else if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"LT;", 3)) + { + scanString += 2; + encodeChars = TRUE; + } + else if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"GT;", 3)) + { + scanString += 2; + encodeChars = TRUE; + } + if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"APOS;", 5)) + { + scanString += 4; + encodeChars = TRUE; + } + if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"QUOT;", 5)) + { + scanString += 4; + encodeChars = TRUE; + } + else + { + scanString--; + } + } + + stringLength++; + scanString++; + } + + stringLength++; + + if (encodeChars) + { + resultString = outputString = CsrPmemAlloc(stringLength * sizeof(CsrUtf16String)); + + scanString = str; + + while (*scanString) + { + if (*scanString == L'&') + { + scanString++; + + if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"AMP;", 4)) + { + *outputString++ = L'&'; + scanString += 3; + } + else if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"LT;", 3)) + { + *outputString++ = L'<'; + scanString += 2; + } + else if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"GT;", 3)) + { + *outputString++ = L'>'; + scanString += 2; + } + else if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"APOS;", 5)) + { + *outputString++ = L'\''; + scanString += 4; + } + else if (!CsrUtf16StrNICmp(scanString, (CsrUtf16String *) L"QUOT;", 5)) + { + *outputString++ = L'\"'; + scanString += 4; + } + else + { + *outputString++ = L'&'; + scanString--; + } + } + else + { + *outputString++ = *scanString; + } + + scanString++; + } + + *outputString++ = 0; + + CsrPmemFree(str); + } + } + + return resultString; +} + +CsrInt32 CsrUtf8StrCmp(const CsrUtf8String *string1, const CsrUtf8String *string2) +{ + return CsrStrCmp((const CsrCharString *) string1, (const CsrCharString *) string2); +} + +CsrInt32 CsrUtf8StrNCmp(const CsrUtf8String *string1, const CsrUtf8String *string2, CsrSize count) +{ + return CsrStrNCmp((const CsrCharString *) string1, (const CsrCharString *) string2, count); +} + +CsrUint32 CsrUtf8StringLengthInBytes(const CsrUtf8String *string) +{ + CsrSize length = 0; + if (string) + { + length = CsrStrLen((const CsrCharString *) string); + } + return (CsrUint32) length; +} + +CsrUtf8String *CsrUtf8StrCpy(CsrUtf8String *target, const CsrUtf8String *source) +{ + return (CsrUtf8String *) CsrStrCpy((CsrCharString *) target, (const CsrCharString *) source); +} + +CsrUtf8String *CsrUtf8StrTruncate(CsrUtf8String *target, CsrSize count) +{ + CsrSize lastByte = count - 1; + + target[count] = '\0'; + + if (count && (target[lastByte] & 0x80)) + { + /* the last byte contains non-ascii char */ + if (target[lastByte] & 0x40) + { + /* multi-byte char starting just before truncation */ + target[lastByte] = '\0'; + } + else if ((target[lastByte - 1] & 0xE0) == 0xE0) + { + /* 3-byte char starting 2 bytes before truncation */ + target[lastByte - 1] = '\0'; + } + else if ((target[lastByte - 2] & 0xF0) == 0xF0) + { + /* 4-byte char starting 3 bytes before truncation */ + target[lastByte - 2] = '\0'; + } + } + + return target; +} + +CsrUtf8String *CsrUtf8StrNCpy(CsrUtf8String *target, const CsrUtf8String *source, CsrSize count) +{ + return (CsrUtf8String *) CsrStrNCpy((CsrCharString *) target, (const CsrCharString *) source, count); +} + +CsrUtf8String *CsrUtf8StrNCpyZero(CsrUtf8String *target, const CsrUtf8String *source, CsrSize count) +{ + CsrStrNCpy((CsrCharString *) target, (const CsrCharString *) source, count); + if (target[count - 1] != '\0') + { + CsrUtf8StrTruncate(target, count - 1); + } + return target; +} + +CsrUtf8String *CsrUtf8StrDup(const CsrUtf8String *source) +{ + return (CsrUtf8String *) CsrStrDup((const CsrCharString *) source); +} + +CsrUtf8String *CsrUtf8StringConcatenateTexts(const CsrUtf8String *inputText1, const CsrUtf8String *inputText2, const CsrUtf8String *inputText3, const CsrUtf8String *inputText4) +{ + CsrUtf8String *outputText; + CsrUint32 textLen, textLen1, textLen2, textLen3, textLen4; + + textLen1 = CsrUtf8StringLengthInBytes(inputText1); + textLen2 = CsrUtf8StringLengthInBytes(inputText2); + textLen3 = CsrUtf8StringLengthInBytes(inputText3); + textLen4 = CsrUtf8StringLengthInBytes(inputText4); + + textLen = textLen1 + textLen2 + textLen3 + textLen4; + + if (textLen == 0) /*stop here is all lengths are 0*/ + { + return NULL; + } + + outputText = (CsrUtf8String *) CsrPmemAlloc((textLen + 1) * sizeof(CsrUtf8String)); /* add space for 0-termination*/ + + + if (inputText1 != NULL) + { + CsrUtf8StrNCpy(outputText, inputText1, textLen1); + } + + if (inputText2 != NULL) + { + CsrUtf8StrNCpy(&(outputText[textLen1]), inputText2, textLen2); + } + + if (inputText3 != NULL) + { + CsrUtf8StrNCpy(&(outputText[textLen1 + textLen2]), inputText3, textLen3); + } + + if (inputText4 != NULL) + { + CsrUtf8StrNCpy(&(outputText[textLen1 + textLen2 + textLen3]), inputText4, textLen4); + } + + outputText[textLen] = '\0'; + + return outputText; +} diff --git a/drivers/staging/csr/csr_util.c b/drivers/staging/csr/csr_util.c new file mode 100644 index 000000000000..0ae11531e26d --- /dev/null +++ b/drivers/staging/csr/csr_util.c @@ -0,0 +1,435 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include +#include + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_util.h" + +/*------------------------------------------------------------------*/ +/* Bits */ +/*------------------------------------------------------------------*/ + +/* Time proportional with the number of 1's */ +CsrUint8 CsrBitCountSparse(CsrUint32 n) +{ + CsrUint8 count = 0; + + while (n) + { + count++; + n &= (n - 1); + } + + return count; +} + +/* Time proportional with the number of 0's */ +CsrUint8 CsrBitCountDense(CsrUint32 n) +{ + CsrUint8 count = 8 * sizeof(CsrUint32); + + n ^= (CsrUint32) (-1); + + while (n) + { + count--; + n &= (n - 1); + } + + return count; +} + +/*------------------------------------------------------------------*/ +/* Base conversion */ +/*------------------------------------------------------------------*/ +CsrBool CsrHexStrToUint8(const CsrCharString *string, CsrUint8 *returnValue) +{ + CsrUint16 currentIndex = 0; + *returnValue = 0; + if ((string[currentIndex] == '0') && (CSR_TOUPPER(string[currentIndex + 1]) == 'X')) + { + string += 2; + } + if (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F'))) + { + while (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F'))) + { + *returnValue = (CsrUint8) (*returnValue * 16 + (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) ? string[currentIndex] - '0' : CSR_TOUPPER(string[currentIndex]) - 'A' + 10)); + currentIndex++; + if (currentIndex >= 2) + { + break; + } + } + return TRUE; + } + return FALSE; +} + +CsrBool CsrHexStrToUint16(const CsrCharString *string, CsrUint16 *returnValue) +{ + CsrUint16 currentIndex = 0; + *returnValue = 0; + if ((string[currentIndex] == '0') && (CSR_TOUPPER(string[currentIndex + 1]) == 'X')) + { + string += 2; + } + if (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F'))) + { + while (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F'))) + { + *returnValue = (CsrUint16) (*returnValue * 16 + (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) ? string[currentIndex] - '0' : CSR_TOUPPER(string[currentIndex]) - 'A' + 10)); + currentIndex++; + if (currentIndex >= 4) + { + break; + } + } + return TRUE; + } + return FALSE; +} + +CsrBool CsrHexStrToUint32(const CsrCharString *string, CsrUint32 *returnValue) +{ + CsrUint16 currentIndex = 0; + *returnValue = 0; + if ((string[currentIndex] == '0') && (CSR_TOUPPER(string[currentIndex + 1]) == 'X')) + { + string += 2; + } + if (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F'))) + { + while (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F'))) + { + *returnValue = *returnValue * 16 + (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) ? string[currentIndex] - '0' : CSR_TOUPPER(string[currentIndex]) - 'A' + 10); + currentIndex++; + if (currentIndex >= 8) + { + break; + } + } + return TRUE; + } + return FALSE; +} + +CsrUint32 CsrPow(CsrUint32 base, CsrUint32 exponent) +{ + if (exponent == 0) + { + return 1; + } + else + { + CsrUint32 i, t = base; + + for (i = 1; i < exponent; i++) + { + t = t * base; + } + return t; + } +} + +/* Convert signed 32 bit (or less) integer to string */ +#define I2B10_MAX 12 +void CsrIntToBase10(CsrInt32 number, CsrCharString *str) +{ + CsrInt32 digit; + CsrUint8 index; + CsrCharString res[I2B10_MAX]; + CsrBool foundDigit = FALSE; + + for (digit = 0; digit < I2B10_MAX; digit++) + { + res[digit] = '\0'; + } + + /* Catch sign - and deal with positive numbers only afterwards */ + index = 0; + if (number < 0) + { + res[index++] = '-'; + number = -1 * number; + } + + digit = 1000000000; + if (number > 0) + { + while ((index < I2B10_MAX - 1) && (digit > 0)) + { + /* If the foundDigit flag is TRUE, this routine should be proceeded. + Otherwise the number which has '0' digit cannot be converted correctly */ + if (((number / digit) > 0) || foundDigit) + { + foundDigit = TRUE; /* set foundDigit flag to TRUE*/ + res[index++] = (char) ('0' + (number / digit)); + number = number % digit; + } + + digit = digit / 10; + } + } + else + { + res[index] = (char) '0'; + } + + CsrStrCpy(str, res); +} + +void CsrUInt16ToHex(CsrUint16 number, CsrCharString *str) +{ + CsrUint16 index; + CsrUint16 currentValue; + + for (index = 0; index < 4; index++) + { + currentValue = (CsrUint16) (number & 0x000F); + number >>= 4; + str[3 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0'); + } + str[4] = '\0'; +} + +void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str) +{ + CsrUint16 index; + CsrUint32 currentValue; + + for (index = 0; index < 8; index++) + { + currentValue = (CsrUint32) (number & 0x0000000F); + number >>= 4; + str[7 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0'); + } + str[8] = '\0'; +} + +/*------------------------------------------------------------------*/ +/* String */ +/*------------------------------------------------------------------*/ +void *CsrMemCpy(void *dest, const void *src, CsrSize count) +{ + return memcpy(dest, src, count); +} +EXPORT_SYMBOL_GPL(CsrMemCpy); + +void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count) +{ + return memset(dest, c, count); +} +EXPORT_SYMBOL_GPL(CsrMemSet); + +void *CsrMemMove(void *dest, const void *src, CsrSize count) +{ + return memmove(dest, src, count); +} +EXPORT_SYMBOL_GPL(CsrMemMove); + +CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count) +{ + return memcmp(buf1, buf2, count); +} +EXPORT_SYMBOL_GPL(CsrMemCmp); + +void *CsrMemDup(const void *buf1, CsrSize count) +{ + void *buf2 = NULL; + + if (buf1) + { + buf2 = CsrPmemAlloc(count); + CsrMemCpy(buf2, buf1, count); + } + + return buf2; +} + +CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src) +{ + return strcpy(dest, src); +} + +CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count) +{ + return strncpy(dest, src, count); +} + +CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src) +{ + return strcat(dest, src); +} + +CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count) +{ + return strncat(dest, src, count); +} + +CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2) +{ + return strstr(string1, string2); +} + +CsrSize CsrStrLen(const CsrCharString *string) +{ + return strlen(string); +} +EXPORT_SYMBOL_GPL(CsrStrLen); + +CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2) +{ + return strcmp(string1, string2); +} + +CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count) +{ + return strncmp(string1, string2, count); +} + +CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c) +{ + return strchr(string, c); +} + +CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args) +{ + return vsnprintf(string, count, format, args); +} +EXPORT_SYMBOL_GPL(CsrVsnprintf); + +CsrCharString *CsrStrNCpyZero(CsrCharString *dest, + const CsrCharString *src, + CsrSize count) +{ + CsrStrNCpy(dest, src, count - 1); + dest[count - 1] = '\0'; + return dest; +} + +/* Convert string with base 10 to integer */ +CsrUint32 CsrStrToInt(const CsrCharString *str) +{ + CsrInt16 i; + CsrUint32 res; + CsrUint32 digit; + + res = 0; + digit = 1; + + /* Start from the string end */ + for (i = (CsrUint16) (CsrStrLen(str) - 1); i >= 0; i--) + { + /* Only convert numbers */ + if ((str[i] >= '0') && (str[i] <= '9')) + { + res += digit * (str[i] - '0'); + digit = digit * 10; + } + } + + return res; +} + +CsrCharString *CsrStrDup(const CsrCharString *string) +{ + CsrCharString *copy; + CsrUint32 len; + + copy = NULL; + if (string != NULL) + { + len = CsrStrLen(string) + 1; + copy = CsrPmemAlloc(len); + CsrMemCpy(copy, string, len); + } + return copy; +} + +int CsrStrNICmp(const CsrCharString *string1, + const CsrCharString *string2, + CsrSize count) +{ + CsrUint32 index; + int returnValue = 0; + + for (index = 0; index < count; index++) + { + if (CSR_TOUPPER(string1[index]) != CSR_TOUPPER(string2[index])) + { + if (CSR_TOUPPER(string1[index]) > CSR_TOUPPER(string2[index])) + { + returnValue = 1; + } + else + { + returnValue = -1; + } + break; + } + if (string1[index] == '\0') + { + break; + } + } + return returnValue; +} + +const CsrCharString *CsrGetBaseName(const CsrCharString *file) +{ + const CsrCharString *pch; + static const CsrCharString dotDir[] = "."; + + if (!file) + { + return NULL; + } + + if (file[0] == '\0') + { + return dotDir; + } + + pch = file + CsrStrLen(file) - 1; + + while (*pch != '\\' && *pch != '/' && *pch != ':') + { + if (pch == file) + { + return pch; + } + --pch; + } + + return ++pch; +} + +/*------------------------------------------------------------------*/ +/* Misc */ +/*------------------------------------------------------------------*/ +CsrBool CsrIsSpace(CsrUint8 c) +{ + switch (c) + { + case '\t': + case '\n': + case '\f': + case '\r': + case ' ': + return TRUE; + default: + return FALSE; + } +} diff --git a/drivers/staging/csr/csr_util.h b/drivers/staging/csr/csr_util.h new file mode 100644 index 000000000000..a19baddc0213 --- /dev/null +++ b/drivers/staging/csr/csr_util.h @@ -0,0 +1,75 @@ +#ifndef CSR_UTIL_H__ +#define CSR_UTIL_H__ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_types.h" +#include "csr_macro.h" + +/*------------------------------------------------------------------*/ +/* Bits - intended to operate on CsrUint32 values */ +/*------------------------------------------------------------------*/ +CsrUint8 CsrBitCountSparse(CsrUint32 n); +CsrUint8 CsrBitCountDense(CsrUint32 n); + +/*------------------------------------------------------------------*/ +/* Base conversion */ +/*------------------------------------------------------------------*/ +CsrBool CsrHexStrToUint8(const CsrCharString *string, CsrUint8 *returnValue); +CsrBool CsrHexStrToUint16(const CsrCharString *string, CsrUint16 *returnValue); +CsrBool CsrHexStrToUint32(const CsrCharString *string, CsrUint32 *returnValue); +CsrUint32 CsrPow(CsrUint32 base, CsrUint32 exponent); +void CsrIntToBase10(CsrInt32 number, CsrCharString *str); +void CsrUInt16ToHex(CsrUint16 number, CsrCharString *str); +void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str); + +/*------------------------------------------------------------------*/ +/* String */ +/*------------------------------------------------------------------*/ +void *CsrMemCpy(void *dest, const void *src, CsrSize count); +void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count); +void *CsrMemMove(void *dest, const void *src, CsrSize count); +CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count); +void *CsrMemDup(const void *buf1, CsrSize count); +CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src); +CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count); +int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count); +CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src); +CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count); +CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2); +CsrSize CsrStrLen(const CsrCharString *string); +CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2); +CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count); +CsrCharString *CsrStrDup(const CsrCharString *string); +CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c); +CsrUint32 CsrStrToInt(const CsrCharString *string); +CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args); +CsrCharString *CsrStrNCpyZero(CsrCharString *dest, const CsrCharString *src, CsrSize count); + +/*------------------------------------------------------------------*/ +/* Filename */ +/*------------------------------------------------------------------*/ +const CsrCharString *CsrGetBaseName(const CsrCharString *file); + +/*------------------------------------------------------------------*/ +/* Misc */ +/*------------------------------------------------------------------*/ +CsrBool CsrIsSpace(CsrUint8 c); +#define CsrOffsetOf(st, m) ((CsrSize) & ((st *) 0)->m) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_wifi_common.h b/drivers/staging/csr/csr_wifi_common.h new file mode 100644 index 000000000000..1cdde5c7bd8d --- /dev/null +++ b/drivers/staging/csr/csr_wifi_common.h @@ -0,0 +1,109 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_COMMON_H__ +#define CSR_WIFI_COMMON_H__ + +#include "csr_types.h" +#include "csr_result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* MAC address */ +typedef struct +{ + CsrUint8 a[6]; +} CsrWifiMacAddress; + +/* IPv4 address */ +typedef struct +{ + CsrUint8 a[4]; +} CsrWifiIp4Address; + +/* IPv6 address */ +typedef struct +{ + CsrUint8 a[16]; +} CsrWifiIp6Address; + +typedef struct +{ + CsrUint8 ssid[32]; + CsrUint8 length; +} CsrWifiSsid; + +/******************************************************************************* + + DESCRIPTION + Result values used on the Wifi Interfaces + + VALUES + CSR_RESULT_SUCCESS + - The request/procedure succeeded + CSR_RESULT_FAILURE + - The request/procedure did not succeed because of an error + CSR_WIFI_RESULT_NOT_FOUND + - The request did not succeed because some resource was not + found. + CSR_WIFI_RESULT_TIMED_OUT + - The request/procedure did not succeed because of a time out + CSR_WIFI_RESULT_CANCELLED + - The request was canceled due to another conflicting + request that was issued before this one was completed + CSR_WIFI_RESULT_INVALID_PARAMETER + - The request/procedure did not succeed because it had an + invalid parameter + CSR_WIFI_RESULT_NO_ROOM + - The request did not succeed due to a lack of resources, + e.g. out of memory problem. + CSR_WIFI_RESULT_UNSUPPORTED + - The request/procedure did not succeed because the feature + is not supported yet + CSR_WIFI_RESULT_UNAVAILABLE + - The request cannot be processed at this time + CSR_WIFI_RESULT_WIFI_OFF + - The requested action is not available because Wi-Fi is + currently off + CSR_WIFI_RESULT_SECURITY_ERROR + - The request/procedure did not succeed because of a security + error + CSR_WIFI_RESULT_MIB_SET_FAILURE + - MIB Set Failure: either the MIB OID to be written to does + not exist or the MIB Value is invalid. + CSR_WIFI_RESULT_INVALID_INTERFACE_TAG + - The supplied Interface Tag is not valid. + CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT + - The new NOA configuration conflicts with the existing NOA configuration + hence not accepted" +*******************************************************************************/ +#define CSR_WIFI_RESULT_NOT_FOUND ((CsrResult) 0x0001) +#define CSR_WIFI_RESULT_TIMED_OUT ((CsrResult) 0x0002) +#define CSR_WIFI_RESULT_CANCELLED ((CsrResult) 0x0003) +#define CSR_WIFI_RESULT_INVALID_PARAMETER ((CsrResult) 0x0004) +#define CSR_WIFI_RESULT_NO_ROOM ((CsrResult) 0x0005) +#define CSR_WIFI_RESULT_UNSUPPORTED ((CsrResult) 0x0006) +#define CSR_WIFI_RESULT_UNAVAILABLE ((CsrResult) 0x0007) +#define CSR_WIFI_RESULT_WIFI_OFF ((CsrResult) 0x0008) +#define CSR_WIFI_RESULT_SECURITY_ERROR ((CsrResult) 0x0009) +#define CSR_WIFI_RESULT_MIB_SET_FAILURE ((CsrResult) 0x000A) +#define CSR_WIFI_RESULT_INVALID_INTERFACE_TAG ((CsrResult) 0x000B) +#define CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT ((CsrResult) 0x000C) + +#define CSR_WIFI_VERSION "5.0.3.0" + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/drivers/staging/csr/csr_wifi_fsm.h b/drivers/staging/csr/csr_wifi_fsm.h new file mode 100644 index 000000000000..cfdf082349ee --- /dev/null +++ b/drivers/staging/csr/csr_wifi_fsm.h @@ -0,0 +1,250 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_FSM_H +#define CSR_WIFI_FSM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_prim_defs.h" +#include "csr_log_text.h" +#include "csr_wifi_fsm_event.h" + +/* including this file for CsrWifiInterfaceMode*/ +#include "csr_wifi_common.h" + +#define CSR_WIFI_FSM_ENV (0xFFFF) + +/** + * @brief + * Toplevel FSM context data + * + * @par Description + * Holds ALL FSM static and dynamic data for a FSM + */ +typedef struct CsrWifiFsmContext CsrWifiFsmContext; + +/** + * @brief + * FSM External Wakeup CallbackFunction Pointer + * + * @par Description + * Defines the external wakeup function for the FSM + * to call when an external event is injected into the systen + * + * @param[in] context : External context + * + * @return + * void + */ +typedef void (*CsrWifiFsmExternalWakupCallbackPtr)(void *context); + +/** + * @brief + * Initialises a top level FSM context + * + * @par Description + * Initialises the FSM Context to an initial state and allocates + * space for "maxProcesses" number of instances + * + * @param[in] osaContext : OSA context + * @param[in] applicationContext : Internal fsm application context + * @param[in] externalContext : External context + * @param[in] maxProcesses : Max processes to allocate room for + * + * @return + * CsrWifiFsmContext* fsm context + */ +extern CsrWifiFsmContext* CsrWifiFsmInit(void *applicationContext, void *externalContext, CsrUint16 maxProcesses, CsrLogTextTaskId loggingTaskId); + +/** + * @brief + * Resets the FSM's back to first conditions + * + * @par Description + * This function is used to free any dynamic resources allocated for the + * given context by CsrWifiFsmInit(). + * The FSM's reset function is called to cleanup any fsm specific memory + * The reset funtion does NOT need to free the fsm data pointer as + * CsrWifiFsmShutdown() will do it. + * the FSM's init function is call again to reinitialise the FSM context. + * CsrWifiFsmReset() should NEVER be called when CsrWifiFsmExecute() is running. + * + * @param[in] context : FSM context + * + * @return + * void + */ +extern void CsrWifiFsmReset(CsrWifiFsmContext *context); + +/** + * @brief + * Frees resources allocated by CsrWifiFsmInit + * + * @par Description + * This function is used to free any dynamic resources allocated for the + * given context by CsrWifiFsmInit(), prior to complete termination of + * the program. + * The FSM's reset function is called to cleanup any fsm specific memory. + * The reset funtion does NOT need to free the fsm data pointer as + * CsrWifiFsmShutdown() will do it. + * CsrWifiFsmShutdown() should NEVER be called when CsrWifiFsmExecute() is running. + * + * @param[in] context : FSM context + * + * @return + * void + */ +extern void CsrWifiFsmShutdown(CsrWifiFsmContext *context); + +/** + * @brief + * Executes the fsm context + * + * @par Description + * Executes the FSM context and runs until ALL events in the context are processed. + * When no more events are left to process then CsrWifiFsmExecute() returns to a time + * specifying when to next call the CsrWifiFsmExecute() + * Scheduling, threading, blocking and external event notification are outside + * the scope of the FSM and CsrWifiFsmExecute(). + * + * @param[in] context : FSM context + * + * @return + * CsrUint32 Time in ms until next timeout or 0xFFFFFFFF for no timer set + */ +extern CsrUint32 CsrWifiFsmExecute(CsrWifiFsmContext *context); + +/** + * @brief + * Adds an event to the FSM context's external event queue for processing + * + * @par Description + * Adds an event to the contexts external queue + * This is thread safe and adds an event to the fsm's external event queue. + * + * @param[in] context : FSM context + * @param[in] event : event to add to the event queue + * @param[in] source : source of the event (this can be a synergy task queue or an fsm instance id) + * @param[in] destination : destination of the event (This can be a fsm instance id or CSR_WIFI_FSM_ENV) + * @param[in] id : event id + * + * @return + * void + */ +extern void CsrWifiFsmSendEventExternal(CsrWifiFsmContext *context, CsrWifiFsmEvent *event, CsrUint16 source, CsrUint16 destination, CsrPrim primtype, CsrUint16 id); + +/** + * @brief + * Adds an Alien event to the FSM context's external event queue for processing + * + * @par Description + * Adds an event to the contexts external queue + * This is thread safe and adds an event to the fsm's external event queue. + * + * @param[in] context : FSM context + * @param[in] event : event to add to the event queue + * @param[in] source : source of the event (this can be a synergy task queue or an fsm instance id) + * @param[in] destination : destination of the event (This can be a fsm instance id or CSR_WIFI_FSM_ENV) + * @param[in] id : event id + */ +#define CsrWifiFsmSendAlienEventExternal(_context, _alienEvent, _source, _destination, _primtype, _id) \ + { \ + CsrWifiFsmAlienEvent *_evt = (CsrWifiFsmAlienEvent *)CsrPmemAlloc(sizeof(CsrWifiFsmAlienEvent)); \ + _evt->alienEvent = _alienEvent; \ + CsrWifiFsmSendEventExternal(_context, (CsrWifiFsmEvent *)_evt, _source, _destination, _primtype, _id); \ + } + + +/** + * @brief + * Current time of day in ms + * + * @param[in] context : FSM context + * + * @return + * CsrUint32 32 bit ms tick + */ +extern CsrUint32 CsrWifiFsmGetTimeOfDayMs(CsrWifiFsmContext *context); + +/** + * @brief + * Gets the time until the next FSM timer expiry + * + * @par Description + * Returns the next timeout time or 0 if no timers are set. + * + * @param[in] context : FSM context + * + * @return + * CsrUint32 Time in ms until next timeout or 0xFFFFFFFF for no timer set + */ +extern CsrUint32 CsrWifiFsmGetNextTimeout(CsrWifiFsmContext *context); + +/** + * @brief + * Fast forwards the fsm timers by ms Milliseconds + * + * @param[in] context : FSM context + * @param[in] ms : Milliseconds to fast forward by + * + * @return + * void + */ +extern void CsrWifiFsmFastForward(CsrWifiFsmContext *context, CsrUint16 ms); + +/** + * @brief + * shift the current time of day by ms amount + * + * @par Description + * usefull to speed up tests where time needs to pass + * + * @param[in] context : FSM context + * @param[in] ms : ms to adjust time by + * + * @return + * void + */ +extern void CsrWifiFsmTestAdvanceTime(CsrWifiFsmContext *context, CsrUint32 ms); + +/** + * @brief + * Check if the fsm has events to process + * + * @param[in] context : FSM context + * + * @return + * CsrBool returns TRUE if there are events for the FSM to process + */ +extern CsrBool CsrWifiFsmHasEvents(CsrWifiFsmContext *context); + +/** + * @brief + * function that installs the contexts wakeup function + * + * @param[in] context : FSM context + * @param[in] callback : Callback function pointer + * + * @return + * void + */ +extern void CsrWifiFsmInstallWakeupCallback(CsrWifiFsmContext *context, CsrWifiFsmExternalWakupCallbackPtr callback); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_FSM_H */ + diff --git a/drivers/staging/csr/csr_wifi_fsm_event.h b/drivers/staging/csr/csr_wifi_fsm_event.h new file mode 100644 index 000000000000..ef07d8a5cfb2 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_fsm_event.h @@ -0,0 +1,51 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_FSM_EVENT_H +#define CSR_WIFI_FSM_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" + +/** + * @brief + * FSM event header. + * + * @par Description + * All events MUST have this struct as the FIRST member. + * The next member is used internally for linked lists + */ +typedef struct CsrWifiFsmEvent +{ + CsrPrim type; + CsrUint16 primtype; + CsrSchedQid destination; + CsrSchedQid source; + + /* Private pointer to allow an optimal Event list */ + /* NOTE: Ignore this pointer. + * Do not waste code initializing OR freeing it. + * The pointer is used internally in the CsrWifiFsm code + * to avoid a second malloc when queuing events. + */ + struct CsrWifiFsmEvent *next; +} CsrWifiFsmEvent; + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_FSM_EVENT_H */ + diff --git a/drivers/staging/csr/csr_wifi_fsm_types.h b/drivers/staging/csr/csr_wifi_fsm_types.h new file mode 100644 index 000000000000..7c611e342938 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_fsm_types.h @@ -0,0 +1,441 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_FSM_TYPES_H +#define CSR_WIFI_FSM_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_types.h" +#include "csr_util.h" +#include "csr_pmem.h" +#include "csr_panic.h" +#include "csr_sched.h" + +#ifdef CSR_WIFI_FSM_MUTEX_ENABLE +#include "csr_framework_ext.h" +#endif + +#include "csr_wifi_fsm.h" + +#define CSR_WIFI_FSM_MAX_TRANSITION_HISTORY 10 + +/** + * @brief + * FSM event list header. + * + * @par Description + * Singly linked list of events. + */ +typedef struct CsrWifiFsmEventList +{ + CsrWifiFsmEvent *first; + CsrWifiFsmEvent *last; +} CsrWifiFsmEventList; + + +/** + * @brief + * FSM timer id. + * + * @par Description + * Composite Id made up of the type, dest and a unique id so + * CsrWifiFsmRemoveTimer knows where to look when removing the timer + */ +typedef struct CsrWifiFsmTimerId +{ + CsrPrim type; + CsrUint16 primtype; + CsrSchedQid destination; + CsrUint16 uniqueid; +} CsrWifiFsmTimerId; + +/** + * @brief + * FSM timer header. + * + * @par Description + * All timer MUST have this struct as the FIRST member. + * The first members of the structure MUST remain compatable + * with the CsrWifiFsmEvent so that timers are just specialised events + */ +typedef struct CsrWifiFsmTimer +{ + CsrPrim type; + CsrUint16 primtype; + CsrSchedQid destination; + CsrSchedQid source; + + /* Private pointer to allow an optimal Event list */ + struct CsrWifiFsmTimer *next; + + CsrWifiFsmTimerId timerid; + CsrUint32 timeoutTimeMs; +} CsrWifiFsmTimer; + + +/** + * @brief + * Fsm Alien Event + * + * @par Description + * Allows the wrapping of alien events that do not use CsrWifiFsmEvent + * as the first member of the Event struct + */ +typedef struct +{ + CsrWifiFsmEvent event; + void *alienEvent; +} CsrWifiFsmAlienEvent; + + +/** + * @brief + * FSM timer list header. + * + * @par Description + * Singly linked list of timers. + */ +typedef struct CsrWifiFsmTimerList +{ + CsrWifiFsmTimer *first; + CsrWifiFsmTimer *last; + CsrUint16 nexttimerid; +} CsrWifiFsmTimerList; + +/** + * @brief + * Process Entry Function Pointer + * + * @par Description + * Defines the entry function for a processes. + * Called at process initialisation. + * + * @param[in] context : FSM context + * + * @return + * void + */ +typedef void (*CsrWifiFsmProcEntryFnPtr)(CsrWifiFsmContext *context); + +/** + * @brief + * Process Transition Function Pointer + * + * @par Description + * Defines a transition function for a processes. + * Called when an event causes a transition on a process + * + * @param[in] CsrWifiFsmContext* : FSM context + * @param[in] void* : FSM data (can be NULL) + * @param[in] const CsrWifiFsmEvent* : event to process + * + * @return + * void + */ +typedef void (*CsrWifiFsmTransitionFnPtr)(CsrWifiFsmContext *context, void *fsmData, const CsrWifiFsmEvent *event); + +/** + * @brief + * Process reset/shutdown Function Pointer + * + * @par Description + * Defines the reset/shutdown function for a processes. + * Called to reset or shutdown an fsm. + * + * @param[in] context : FSM context + * + * @return + * void + */ +typedef void (*CsrWifiFsmProcResetFnPtr)(CsrWifiFsmContext *context); + +/** + * @brief + * FSM Default Destination CallbackFunction Pointer + * + * @par Description + * Defines the default destination function for the FSM + * to call when an event does not have a valid destination. + * This + * + * @param[in] context : External context + * + * @return + * CsrUint16 a valid destination OR CSR_WIFI_FSM_ENV + */ +typedef CsrUint16 (*CsrWifiFsmDestLookupCallbackPtr)(void *context, const CsrWifiFsmEvent *event); + + +#ifdef CSR_WIFI_FSM_DUMP_ENABLE +/** + * @brief + * Trace Dump Function Pointer + * + * @par Description + * Called when we want to trace the FSM + * + * @param[in] context : FSM context + * @param[in] id : fsm id + * + * @return + * void + */ +typedef void (*CsrWifiFsmDumpFnPtr)(CsrWifiFsmContext *context, void *fsmData); +#endif + +/** + * @brief + * Event ID to transition function entry + * + * @par Description + * Event ID to Transition Entry in a state table. + */ +typedef struct +{ + CsrUint32 eventid; + CsrWifiFsmTransitionFnPtr transition; +#ifdef CSR_LOG_ENABLE + const CsrCharString *transitionName; +#endif +} CsrWifiFsmEventEntry; + +/** + * @brief + * Single State's Transition Table + * + * @par Description + * Stores Data for a single State's event to + * transition functions mapping + */ +typedef struct +{ + const CsrUint8 numEntries; + const CsrBool saveAll; + const CsrWifiFsmEventEntry *eventEntryArray; /* array of transition function pointers for state */ +#ifdef CSR_LOG_ENABLE + CsrUint16 stateNumber; + const CsrCharString *stateName; +#endif +} CsrWifiFsmTableEntry; + +/** + * @brief + * Process State Transtion table + * + * @par Description + * Stores Data for a processes State to transition table + */ +typedef struct +{ + CsrUint16 numStates; /* number of states */ + const CsrWifiFsmTableEntry *aStateEventMatrix; /* state event matrix */ +} CsrWifiFsmTransitionFunctionTable; + +/** + * @brief + * Const Process definition + * + * @par Description + * Constant process specification. + * This is ALL the non dynamic data that defines + * a process. + */ +typedef struct +{ + const CsrCharString *processName; + const CsrUint32 processId; + const CsrWifiFsmTransitionFunctionTable transitionTable; + const CsrWifiFsmTableEntry unhandledTransitions; + const CsrWifiFsmTableEntry ignoreFunctions; + const CsrWifiFsmProcEntryFnPtr entryFn; + const CsrWifiFsmProcResetFnPtr resetFn; +#ifdef CSR_WIFI_FSM_DUMP_ENABLE + const CsrWifiFsmDumpFnPtr dumpFn; /* Called to dump fsm specific trace if not NULL */ +#endif +} CsrWifiFsmProcessStateMachine; + +#ifdef CSR_WIFI_FSM_DUMP_ENABLE +/** + * @brief + * Storage for state transition info + */ +typedef struct +{ + CsrUint16 transitionNumber; + CsrWifiFsmEvent event; + CsrUint16 fromState; + CsrUint16 toState; + CsrWifiFsmTransitionFnPtr transitionFn; + CsrUint16 transitionCount; /* number consecutive of times this transition was seen */ +#ifdef CSR_LOG_ENABLE + const CsrCharString *transitionName; +#endif +} CsrWifiFsmTransitionRecord; + +/** + * @brief + * Storage for the last state X transitions + */ +typedef struct +{ + CsrUint16 numTransitions; + CsrWifiFsmTransitionRecord records[CSR_WIFI_FSM_MAX_TRANSITION_HISTORY]; +} CsrWifiFsmTransitionRecords; +#endif + +/** + * @brief + * Dynamic Process data + * + * @par Description + * Dynamic process data that is used to keep track of the + * state and data for a process instance + */ +typedef struct +{ + const CsrWifiFsmProcessStateMachine *fsmInfo; /* state machine info that is constant regardless of context */ + CsrUint16 instanceId; /* Runtime process id */ + CsrUint16 state; /* Current state */ + void *params; /* Instance user data */ + CsrWifiFsmEventList savedEventQueue; /* The saved event queue */ + struct CsrWifiFsmInstanceEntry *subFsm; /* Sub Fsm instance data */ + struct CsrWifiFsmInstanceEntry *subFsmCaller; /* The Fsm instance that created the SubFsm and should be used for callbacks*/ +#ifdef CSR_WIFI_FSM_DUMP_ENABLE + CsrWifiFsmTransitionRecords transitionRecords; /* Last X transitions in the FSM */ +#endif +} CsrWifiFsmInstanceEntry; + +/** + * @brief + * OnCreate Callback Function Pointer + * + * @par Description + * Called when an fsm is created. + * + * @param[in] extContext : External context + * @param[in] instance : FSM instance + * + * @return + * void + */ +typedef void (*CsrWifiFsmOnCreateFnPtr)(void *extContext, const CsrWifiFsmInstanceEntry *instance); + +/** + * @brief + * OnTransition Callback Function Pointer + * + * @par Description + * Called when an event is processed by a fsm + * + * @param[in] extContext : External context + * @param[in] eventEntryArray : Entry data + * @param[in] event : Event + * + * @return + * void + */ +typedef void (*CsrWifiFsmOnTransitionFnPtr)(void *extContext, const CsrWifiFsmEventEntry *eventEntryArray, const CsrWifiFsmEvent *event); + +/** + * @brief + * OnStateChange Callback Function Pointer + * + * @par Description + * Called when CsrWifiFsmNextState is called + * + * @param[in] extContext : External context + * + * @return + * void + */ +typedef void (*CsrWifiFsmOnStateChangeFnPtr)(void *extContext, CsrUint16 nextstate); + +/** + * @brief + * OnIgnore,OnError or OnInvalid Callback Function Pointer + * + * @par Description + * Called when an event is processed by a fsm + * + * @param[in] extContext : External context + * @param[in] event : Event + * + * @return + * void + */ +typedef void (*CsrWifiFsmOnEventFnPtr)(void *extContext, const CsrWifiFsmEvent *event); + +/** + * @brief + * Toplevel FSM context data + * + * @par Description + * Holds ALL FSM static and dynamic data for a FSM + */ +struct CsrWifiFsmContext +{ + CsrWifiFsmEventList eventQueue; /* The internal event queue */ + CsrWifiFsmEventList externalEventQueue; /* The external event queue */ +#ifdef CSR_WIFI_FSM_MUTEX_ENABLE + CsrMutexHandle externalEventQueueLock; /* The external event queue mutex */ +#endif + CsrUint32 timeOffset; /* Amount to adjust the TimeOfDayMs by */ + CsrWifiFsmTimerList timerQueue; /* The internal timer queue */ + CsrBool useTempSaveList; /* Should the temp save list be used */ + CsrWifiFsmEventList tempSaveList; /* The temp save event queue */ + CsrWifiFsmEvent *eventForwardedOrSaved; /* The event that was forwarded or Saved */ + CsrUint16 maxProcesses; /* Size of instanceArray */ + CsrUint16 numProcesses; /* Current number allocated in instanceArray */ + CsrWifiFsmInstanceEntry *instanceArray; /* Array of processes for this component */ + CsrWifiFsmInstanceEntry *ownerInstance; /* The Process that owns currentInstance (SubFsm support) */ + CsrWifiFsmInstanceEntry *currentInstance; /* Current Process that is executing */ + CsrWifiFsmExternalWakupCallbackPtr externalEventFn; /* External event Callback */ + CsrWifiFsmOnEventFnPtr appIgnoreCallback; /* Application Ignore event Callback */ + CsrWifiFsmDestLookupCallbackPtr appEvtDstCallback; /* Application Lookup event Destination Function*/ + + void *applicationContext; /* Internal fsm application context */ + void *externalContext; /* External context (set by the user of the fsm)*/ + CsrLogTextTaskId loggingTaskId; /* Task Id to use in any logging output */ + +#ifndef CSR_WIFI_FSM_SCHEDULER_DISABLED + CsrSchedTid schedTimerId; /* Scheduler TimerId for use in Scheduler Tasks */ + CsrUint32 schedTimerNexttimeoutMs; /* Next timeout time for the current timer */ +#endif + +#ifdef CSR_WIFI_FSM_MUTEX_ENABLE +#ifdef CSR_WIFI_FSM_TRANSITION_LOCK + CsrMutexHandle transitionLock; /* Lock when calling transition functions */ +#endif +#endif + +#ifdef CSR_LOG_ENABLE + CsrWifiFsmOnCreateFnPtr onCreate; /* Debug Transition Callback */ + CsrWifiFsmOnTransitionFnPtr onTransition; /* Debug Transition Callback */ + CsrWifiFsmOnTransitionFnPtr onUnhandedCallback; /* Unhanded event Callback */ + CsrWifiFsmOnStateChangeFnPtr onStateChange; /* Debug State Change Callback */ + CsrWifiFsmOnEventFnPtr onIgnoreCallback; /* Ignore event Callback */ + CsrWifiFsmOnEventFnPtr onSaveCallback; /* Save event Callback */ + CsrWifiFsmOnEventFnPtr onErrorCallback; /* Error event Callback */ + CsrWifiFsmOnEventFnPtr onInvalidCallback; /* Invalid event Callback */ +#endif +#ifdef CSR_WIFI_FSM_DUMP_ENABLE + CsrUint16 masterTransitionNumber; /* Increments on every transition */ +#endif +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_FSM_TYPES_H */ diff --git a/drivers/staging/csr/csr_wifi_hip_card.h b/drivers/staging/csr/csr_wifi_hip_card.h new file mode 100644 index 000000000000..8904211d3317 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_card.h @@ -0,0 +1,114 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + ****************************************************************************** + * FILE : csr_wifi_hip_card.h + * + * PURPOSE : Defines abstract interface for hardware specific functions. + * Note, this is a different file from one of the same name in the + * Windows driver. + * + ***************************************************************************** + */ +#ifndef __CARD_H__ +#define __CARD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_wifi_hip_card_sdio.h" +#include "csr_wifi_hip_signals.h" +#include "csr_wifi_hip_unifi_udi.h" + + +/***************************************************************************** + * CardEnableInt - + */ +CsrResult CardEnableInt(card_t *card); + +/***************************************************************************** + * CardGenInt - + */ +CsrResult CardGenInt(card_t *card); + +/***************************************************************************** + * CardPendingInt - + */ +CsrResult CardPendingInt(card_t *card, CsrBool *pintr); + +/***************************************************************************** + * CardDisableInt - + */ +CsrResult CardDisableInt(card_t *card); + +/***************************************************************************** + * CardClearInt - + */ +CsrResult CardClearInt(card_t *card); + +/***************************************************************************** + * CardDisable - + */ +void CardDisable(card_t *card); + +/***************************************************************************** + * CardIntEnabled - + */ +CsrResult CardIntEnabled(card_t *card, CsrBool *enabled); + +/***************************************************************************** + * CardGetDataSlotSize + */ +CsrUint16 CardGetDataSlotSize(card_t *card); + +/***************************************************************************** + * CardWriteBulkData - + */ +CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQueue queue); + + +/***************************************************************************** + * CardClearFromHostDataSlot - + */ +void CardClearFromHostDataSlot(card_t *card, const CsrInt16 aSlotNum); + +/***************************************************************************** + * CardGetFreeFromHostDataSlots - + */ +CsrUint16 CardGetFreeFromHostDataSlots(card_t *card); + +CsrUint16 CardAreAllFromHostDataSlotsEmpty(card_t *card); + +CsrResult card_start_processor(card_t *card, enum unifi_dbg_processors_select which); + +CsrResult card_wait_for_firmware_to_start(card_t *card, CsrUint32 *paddr); + +CsrResult unifi_dl_firmware(card_t *card, void *arg); +CsrResult unifi_dl_patch(card_t *card, void *arg, CsrUint32 boot_ctrl); +CsrResult unifi_do_loader_op(card_t *card, CsrUint32 op_addr, CsrUint8 opcode); +void* unifi_dl_fw_read_start(card_t *card, CsrInt8 is_fw); + +CsrResult unifi_coredump_handle_request(card_t *card); + +CsrResult ConvertCsrSdioToCsrHipResult(card_t *card, CsrResult csrResult); +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +void unifi_debug_log_to_buf(const CsrCharString *fmt, ...); +void unifi_debug_string_to_buf(const CsrCharString *str); +void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* __CARD_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c new file mode 100644 index 000000000000..719c608d18b4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c @@ -0,0 +1,4128 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_card_sdio.c + * + * PURPOSE: Implementation of the Card API for SDIO. + * + * NOTES: + * CardInit() is called from the SDIO probe callback when a card is + * inserted. This performs the basic SDIO initialisation, enabling i/o + * etc. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "csr_wifi_hip_unifiversion.h" +#include "csr_wifi_hip_card.h" +#include "csr_wifi_hip_card_sdio.h" +#include "csr_wifi_hip_chiphelper.h" + + +/* Time to wait between attempts to read MAILBOX0 */ +#define MAILBOX1_TIMEOUT 10 /* in millisecs */ +#define MAILBOX1_ATTEMPTS 200 /* 2 seconds */ + +#define MAILBOX2_TIMEOUT 5 /* in millisecs */ +#define MAILBOX2_ATTEMPTS 10 /* 50ms */ + +#define MAILBOX2_RESET_ATTEMPTS 10 +#define MAILBOX2_RESET_TIMEOUT 5 /* in millisecs */ + +#define RESET_SETTLE_DELAY 25 /* in millisecs */ + +static CsrResult card_init_slots(card_t *card); +static CsrResult card_hw_init(card_t *card); +static CsrResult firmware_present_in_flash(card_t *card); +static void bootstrap_chip_hw(card_t *card); +static CsrResult unifi_reset_hardware(card_t *card); +static CsrResult unifi_hip_init(card_t *card); +static CsrResult card_access_panic(card_t *card); +static CsrResult unifi_read_chip_version(card_t *card); + +/* + * --------------------------------------------------------------------------- + * unifi_alloc_card + * + * Allocate and initialise the card context structure. + * + * Arguments: + * sdio Pointer to SDIO context pointer to pass to low + * level i/o functions. + * ospriv Pointer to O/S private struct to pass when calling + * callbacks to the higher level system. + * + * Returns: + * Pointer to card struct, which represents the driver context or + * NULL if the allocation failed. + * --------------------------------------------------------------------------- + */ +card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv) +{ + card_t *card; + CsrUint32 i; + + func_enter(); + + + card = (card_t *)CsrMemAlloc(sizeof(card_t)); + if (card == NULL) + { + return NULL; + } + CsrMemSet(card, 0, sizeof(card_t)); + + + card->sdio_if = sdio; + card->ospriv = ospriv; + + card->unifi_interrupt_seq = 1; + + /* Make these invalid. */ + card->proc_select = (CsrUint32)(-1); + card->dmem_page = (CsrUint32)(-1); + card->pmem_page = (CsrUint32)(-1); + + card->bh_reason_host = 0; + card->bh_reason_unifi = 0; + + for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++) + { + card->tx_q_paused_flag[i] = 0; + } + card->memory_resources_allocated = 0; + + card->low_power_mode = UNIFI_LOW_POWER_DISABLED; + card->periodic_wake_mode = UNIFI_PERIODIC_WAKE_HOST_DISABLED; + + card->host_state = UNIFI_HOST_STATE_AWAKE; + card->intmode = CSR_WIFI_INTMODE_DEFAULT; + + /* + * Memory resources for buffers are allocated when the chip is initialised + * because we need configuration information from the firmware. + */ + + /* + * Initialise wait queues and lists + */ + card->fh_command_queue.q_body = card->fh_command_q_body; + card->fh_command_queue.q_length = UNIFI_SOFT_COMMAND_Q_LENGTH; + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + card->fh_traffic_queue[i].q_body = card->fh_traffic_q_body[i]; + card->fh_traffic_queue[i].q_length = UNIFI_SOFT_TRAFFIC_Q_LENGTH; + } + + + /* Initialise mini-coredump pointers in case no coredump buffers + * are requested by the OS layer. + */ + card->request_coredump_on_reset = 0; + card->dump_next_write = NULL; + card->dump_cur_read = NULL; + card->dump_buf = NULL; + +#ifdef UNIFI_DEBUG + /* Determine offset of LSB in pointer for later alignment sanity check. + * Synergy integer types have specific widths, which cause compiler + * warnings when casting pointer types, e.g. on 64-bit systems. + */ + { + CsrUint32 val = 0x01234567; + + if (*((CsrUint8 *)&val) == 0x01) + { + card->lsb = sizeof(void *) - 1; /* BE */ + } + else + { + card->lsb = 0; /* LE */ + } + } +#endif + func_exit(); + return card; +} /* unifi_alloc_card() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_init_card + * + * Reset the hardware and perform HIP initialization + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CsrResult code + * CSR_RESULT_SUCCESS if successful + * --------------------------------------------------------------------------- + */ +CsrResult unifi_init_card(card_t *card, CsrInt32 led_mask) +{ + CsrResult r; + + func_enter(); + + if (card == NULL) + { + func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + r = unifi_init(card); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + + r = unifi_hip_init(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + func_exit_r(r); + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to start host protocol.\n"); + func_exit_r(r); + return r; + } + + func_exit(); + return CSR_RESULT_SUCCESS; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_init + * + * Init the hardware. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CsrResult code + * CSR_RESULT_SUCCESS if successful + * --------------------------------------------------------------------------- + */ +CsrResult unifi_init(card_t *card) +{ + CsrResult r; + CsrResult csrResult; + + func_enter(); + + if (card == NULL) + { + func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* + * Disable the SDIO interrupts while initialising UniFi. + * Re-enable them when f/w is running. + */ + csrResult = CsrSdioInterruptDisable(card->sdio_if); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + + /* + * UniFi's PLL may start with a slow clock (~ 1 MHz) so initially + * set the SDIO bus clock to a similar value or SDIO accesses may + * fail. + */ + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ); + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + func_exit_r(r); + return r; + } + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ; + + /* + * Reset UniFi. Note, this only resets the WLAN function part of the chip, + * the SDIO interface is not reset. + */ + unifi_trace(card->ospriv, UDBG1, "Resetting UniFi\n"); + r = unifi_reset_hardware(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to reset UniFi\n"); + func_exit_r(r); + return r; + } + + /* Reset the power save mode, to be active until the MLME-reset is complete */ + r = unifi_configure_low_power_mode(card, + UNIFI_LOW_POWER_DISABLED, UNIFI_PERIODIC_WAKE_HOST_DISABLED); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to set power save mode\n"); + func_exit_r(r); + return r; + } + + /* + * Set initial value of page registers. + * The page registers will be maintained by unifi_read...() and + * unifi_write...(). + */ + card->proc_select = (CsrUint32)(-1); + card->dmem_page = (CsrUint32)(-1); + card->pmem_page = (CsrUint32)(-1); + r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, 0); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n"); + func_exit_r(r); + return r; + } + r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, 0); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write PROG_MEM2_PAGE\n"); + func_exit_r(r); + return r; + } + + /* + * If the driver has reset UniFi due to previous SDIO failure, this may + * have been due to a chip watchdog reset. In this case, the driver may + * have requested a mini-coredump which needs to be captured now the + * SDIO interface is alive. + */ + unifi_coredump_handle_request(card); + + /* + * Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do. + */ + r = firmware_present_in_flash(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r == CSR_WIFI_HIP_RESULT_NOT_FOUND) + { + unifi_error(card->ospriv, "No firmware found\n"); + } + else if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Probe for Flash failed\n"); + } + + func_exit_r(r); + return r; +} /* unifi_init() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_download + * + * Load the firmware. + * + * Arguments: + * card Pointer to card struct + * led_mask Loader LED mask + * + * Returns: + * CSR_RESULT_SUCCESS on success + * CsrResult error code on failure. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_download(card_t *card, CsrInt32 led_mask) +{ + CsrResult r; + void *dlpriv; + + func_enter(); + + if (card == NULL) + { + func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* Set the loader led mask */ + card->loader_led_mask = led_mask; + + /* Get the firmware file information */ + unifi_trace(card->ospriv, UDBG1, "downloading firmware...\n"); + + dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA); + if (dlpriv == NULL) + { + func_exit_r(CSR_WIFI_HIP_RESULT_NOT_FOUND); + return CSR_WIFI_HIP_RESULT_NOT_FOUND; + } + + /* Download the firmware. */ + r = unifi_dl_firmware(card, dlpriv); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to download firmware\n"); + func_exit_r(r); + return r; + } + + /* Free the firmware file information. */ + unifi_fw_read_stop(card->ospriv, dlpriv); + + func_exit(); + + return CSR_RESULT_SUCCESS; +} /* unifi_download() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_hip_init + * + * This function performs the f/w initialisation sequence as described + * in the Unifi Host Interface Protocol Specification. + * It allocates memory for host-side slot data and signal queues. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS on success or else a CSR error code + * + * Notes: + * The firmware must have been downloaded. + * --------------------------------------------------------------------------- + */ +static CsrResult unifi_hip_init(card_t *card) +{ + CsrResult r; + CsrResult csrResult; + + func_enter(); + + r = card_hw_init(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to establish communication with UniFi\n"); + func_exit_r(r); + return r; + } +#ifdef CSR_PRE_ALLOC_NET_DATA + /* if there is any preallocated netdata left from the prev session free it now */ + prealloc_netdata_free(card); +#endif + /* + * Allocate memory for host-side slot data and signal queues. + * We need the config info read from the firmware to know how much + * memory to allocate. + */ + r = card_init_slots(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Init slots failed: %d\n", r); + func_exit_r(r); + return r; + } + + unifi_trace(card->ospriv, UDBG2, "Sending first UniFi interrupt\n"); + + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + + /* Enable the SDIO interrupts now that the f/w is running. */ + csrResult = CsrSdioInterruptEnable(card->sdio_if); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + + /* Signal the UniFi to start handling messages */ + r = CardGenInt(card); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + + func_exit(); + + return CSR_RESULT_SUCCESS; +} /* unifi_hip_init() */ + + +/* + * --------------------------------------------------------------------------- + * _build_sdio_config_data + * + * Unpack the SDIO configuration information from a buffer read from + * UniFi into a host structure. + * The data is byte-swapped for a big-endian host if necessary by the + * UNPACK... macros. + * + * Arguments: + * card Pointer to card struct + * cfg_data Destination structure to unpack into. + * cfg_data_buf Source buffer to read from. This should be the raw + * data read from UniFi. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void _build_sdio_config_data(sdio_config_data_t *cfg_data, + const CsrUint8 *cfg_data_buf) +{ + CsrInt16 offset = 0; + + cfg_data->version = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->sdio_ctrl_offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->fromhost_sigbuf_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->tohost_sigbuf_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->num_fromhost_sig_frags = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->num_tohost_sig_frags = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->num_fromhost_data_slots = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->num_tohost_data_slots = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->data_slot_size = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->initialised = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->overlay_size = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT32; + + cfg_data->data_slot_round = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->sig_frag_size = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); + offset += SIZEOF_UINT16; + + cfg_data->tohost_signal_padding = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset); +} /* _build_sdio_config_data() */ + + +/* + * - Function ---------------------------------------------------------------- + * card_hw_init() + * + * Perform the initialisation procedure described in the UniFi Host + * Interface Protocol document (section 3.3.8) and read the run-time + * configuration information from the UniFi. This is stuff like number + * of bulk data slots etc. + * + * The card enumeration and SD initialisation has already been done by + * the SDIO library, see card_sdio_init(). + * + * The initialisation is done when firmware is ready, i.e. this may need + * to be called after a f/w download operation. + * + * The initialisation procedure goes like this: + * - Wait for UniFi to start-up by polling SHARED_MAILBOX1 + * - Find the symbol table and look up SLT_SDIO_SLOT_CONFIG + * - Read the config structure + * - Check the "SDIO initialised" flag, if not zero do a h/w reset and + * start again + * - Decide the number of bulk data slots to allocate, allocate them and + * set "SDIO initialised" flag (and generate an interrupt) to say so. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCEESS on success, + * a CSR error code on failure + * + * Notes: + * All data in the f/w is stored in a little endian format, without any + * padding bytes. Every read from this memory has to be transformed in + * host (cpu specific) format, before it is stored in driver's parameters + * or/and structures. Athough unifi_card_read16() and unifi_read32() do perform + * the convertion internally, unifi_readn() does not. + * --------------------------------------------------------------------------- + */ +static CsrResult card_hw_init(card_t *card) +{ + CsrUint32 slut_address; + CsrUint16 initialised; + CsrUint16 finger_print; + symbol_t slut; + sdio_config_data_t *cfg_data; + CsrUint8 cfg_data_buf[SDIO_CONFIG_DATA_SIZE]; + CsrResult r; + void *dlpriv; + CsrInt16 major, minor; + CsrInt16 search_4slut_again; + CsrResult csrResult; + + func_enter(); + + /* + * The device revision from the TPLMID_MANF and TPLMID_CARD fields + * of the CIS are available as + * card->sdio_if->pDevice->ManfID + * card->sdio_if->pDevice->AppID + */ + + /* + * Run in a loop so we can patch. + */ + do + { + /* Reset these each time around the loop. */ + search_4slut_again = 0; + cfg_data = NULL; + + r = card_wait_for_firmware_to_start(card, &slut_address); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Firmware hasn't started\n"); + func_exit_r(r); + return r; + } + unifi_trace(card->ospriv, UDBG4, "SLUT addr 0x%lX\n", slut_address); + + /* + * Firmware has started, but doesn't know full clock configuration yet + * as some of the information may be in the MIB. Therefore we set an + * initial SDIO clock speed, faster than UNIFI_SDIO_CLOCK_SAFE_HZ, for + * the patch download and subsequent firmware initialisation, and + * full speed UNIFI_SDIO_CLOCK_MAX_HZ will be set once the f/w tells us + * that it is ready. + */ + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ); + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + func_exit_r(r); + return r; + } + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ; + + /* + * Check the SLUT fingerprint. + * The slut_address is a generic pointer so we must use unifi_card_read16(). + */ + unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n"); + finger_print = 0; + r = unifi_card_read16(card, slut_address, &finger_print); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read SLUT finger print\n"); + func_exit_r(r); + return r; + } + + if (finger_print != SLUT_FINGERPRINT) + { + unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n"); + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + /* Symbol table starts imedately after the fingerprint */ + slut_address += 2; + + /* Search the table until either the end marker is found, or the + * loading of patch firmware invalidates the current table. + */ + while (!search_4slut_again) + { + CsrUint16 s; + CsrUint32 l; + + r = unifi_card_read16(card, slut_address, &s); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + slut_address += 2; + + if (s == CSR_SLT_END) + { + unifi_trace(card->ospriv, UDBG3, " found CSR_SLT_END\n"); + break; + } + + r = unifi_read32(card, slut_address, &l); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + slut_address += 4; + + slut.id = s; + slut.obj = l; + + unifi_trace(card->ospriv, UDBG3, " found SLUT id %02d.%08lx\n", slut.id, slut.obj); + switch (slut.id) + { + case CSR_SLT_SDIO_SLOT_CONFIG: + cfg_data = &card->config_data; + /* + * unifi_card_readn reads n bytes from the card, where data is stored + * in a little endian format, without any padding bytes. So, we + * can not just pass the cfg_data pointer or use the + * sizeof(sdio_config_data_t) since the structure in the host can + * be big endian formatted or have padding bytes for alignment. + * We use a char buffer to read the data from the card. + */ + r = unifi_card_readn(card, slut.obj, cfg_data_buf, SDIO_CONFIG_DATA_SIZE); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read config data\n"); + func_exit_r(r); + return r; + } + /* .. and then we copy the data to the host structure */ + _build_sdio_config_data(cfg_data, cfg_data_buf); + + /* Make sure the from host data slots are what we expect + we reserve 2 for commands and there should be at least + 1 left for each access category */ + if ((cfg_data->num_fromhost_data_slots < UNIFI_RESERVED_COMMAND_SLOTS) + || (cfg_data->num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS) / UNIFI_NO_OF_TX_QS == 0) + { + unifi_error(card->ospriv, "From host data slots %d\n", cfg_data->num_fromhost_data_slots); + unifi_error(card->ospriv, "need to be (queues * x + 2) (UNIFI_RESERVED_COMMAND_SLOTS for commands)\n"); + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + /* Configure SDIO to-block-size padding */ + if (card->sdio_io_block_pad) + { + /* + * Firmware limits the maximum padding size via data_slot_round. + * Therefore when padding to whole block sizes, the block size + * must be configured correctly by adjusting CSR_WIFI_HIP_SDIO_BLOCK_SIZE. + */ + if (cfg_data->data_slot_round < card->sdio_io_block_size) + { + unifi_error(card->ospriv, + "Configuration error: Block size of %d exceeds f/w data_slot_round of %d\n", + card->sdio_io_block_size, cfg_data->data_slot_round); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* + * To force the To-Host signals to be rounded up to the SDIO block + * size, we need to write the To-Host Signal Padding Fragments + * field of the SDIO configuration in UniFi. + */ + if ((card->sdio_io_block_size % cfg_data->sig_frag_size) != 0) + { + unifi_error(card->ospriv, "Configuration error: Can not pad to-host signals.\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + cfg_data->tohost_signal_padding = (CsrUint16) (card->sdio_io_block_size / cfg_data->sig_frag_size); + unifi_info(card->ospriv, "SDIO block size %d requires %d padding chunks\n", + card->sdio_io_block_size, cfg_data->tohost_signal_padding); + r = unifi_card_write16(card, slut.obj + SDIO_TO_HOST_SIG_PADDING_OFFSET, cfg_data->tohost_signal_padding); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write To-Host Signal Padding Fragments\n"); + func_exit_r(r); + return r; + } + } + + /* Reconstruct the Generic Pointer address of the + * SDIO Control Data Struct. + */ + card->sdio_ctrl_addr = cfg_data->sdio_ctrl_offset | (UNIFI_SH_DMEM << 24); + card->init_flag_addr = slut.obj + SDIO_INIT_FLAG_OFFSET; + break; + + case CSR_SLT_BUILD_ID_NUMBER: + { + CsrUint32 n; + r = unifi_read32(card, slut.obj, &n); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read build id\n"); + func_exit_r(r); + return r; + } + card->build_id = n; + } + break; + + case CSR_SLT_BUILD_ID_STRING: + r = unifi_readnz(card, slut.obj, card->build_id_string, + sizeof(card->build_id_string)); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read build string\n"); + func_exit_r(r); + return r; + } + break; + + case CSR_SLT_PERSISTENT_STORE_DB: + break; + + case CSR_SLT_BOOT_LOADER_CONTROL: + + /* This command copies most of the station firmware + * image from ROM into program RAM. It also clears + * out the zerod data and sets up the initialised + * data. */ + r = unifi_do_loader_op(card, slut.obj + 6, UNIFI_BOOT_LOADER_LOAD_STA); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write loader load image command\n"); + func_exit_r(r); + return r; + } + + dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA); + + /* dlpriv might be NULL, we still need to do the do_loader_op step. */ + if (dlpriv != NULL) + { + /* Download the firmware. */ + r = unifi_dl_patch(card, dlpriv, slut.obj); + + /* Free the firmware file information. */ + unifi_fw_read_stop(card->ospriv, dlpriv); + + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to patch firmware\n"); + func_exit_r(r); + return r; + } + } + + /* This command starts the firmware image that we want (the + * station by default) with any patches required applied. */ + r = unifi_do_loader_op(card, slut.obj + 6, UNIFI_BOOT_LOADER_RESTART); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write loader restart command\n"); + func_exit_r(r); + return r; + } + + /* The now running patch f/w defines a new SLUT data structure - + * the current one is no longer valid. We must drop out of the + * processing loop and enumerate the new SLUT (which may appear + * at a different offset). + */ + search_4slut_again = 1; + break; + + case CSR_SLT_PANIC_DATA_PHY: + card->panic_data_phy_addr = slut.obj; + break; + + case CSR_SLT_PANIC_DATA_MAC: + card->panic_data_mac_addr = slut.obj; + break; + + default: + /* do nothing */ + break; + } + } /* while */ + } while (search_4slut_again); + + /* Did we find the Config Data ? */ + if (cfg_data == NULL) + { + unifi_error(card->ospriv, "Failed to find SDIO_SLOT_CONFIG Symbol\n"); + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + /* + * Has ths card already been initialised? + * If so, return an error so we do a h/w reset and start again. + */ + r = unifi_card_read16(card, card->init_flag_addr, &initialised); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read init flag at %08lx\n", + card->init_flag_addr); + func_exit_r(r); + return r; + } + if (initialised != 0) + { + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + + /* + * Now check the UniFi firmware version + */ + major = (cfg_data->version >> 8) & 0xFF; + minor = cfg_data->version & 0xFF; + unifi_info(card->ospriv, "UniFi f/w protocol version %d.%d (driver %d.%d)\n", + major, minor, + UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION); + + unifi_info(card->ospriv, "Firmware build %u: %s\n", + card->build_id, card->build_id_string); + + if (major != UNIFI_HIP_MAJOR_VERSION) + { + unifi_error(card->ospriv, "UniFi f/w protocol major version (%d) is different from driver (v%d.%d)\n", + major, UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION); +#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; +#endif + } + if (minor < UNIFI_HIP_MINOR_VERSION) + { + unifi_error(card->ospriv, "UniFi f/w protocol version (v%d.%d) is older than minimum required by driver (v%d.%d).\n", + major, minor, + UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION); +#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; +#endif + } + + /* Read panic codes from a previous firmware panic. If the firmware has + * not panicked since power was applied (e.g. power-off hard reset) + * the stored panic codes will not be updated. + */ + unifi_read_panic(card); + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* card_hw_init() */ + + +/* + * --------------------------------------------------------------------------- + * card_wait_for_unifi_to_reset + * + * Waits for a reset to complete by polling the WLAN function enable + * bit (which is cleared on reset). + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on failure. + * --------------------------------------------------------------------------- + */ +static CsrResult card_wait_for_unifi_to_reset(card_t *card) +{ + CsrInt16 i; + CsrResult r; + CsrUint8 io_enable; + CsrResult csrResult; + + func_enter(); + + r = CSR_RESULT_SUCCESS; + for (i = 0; i < MAILBOX2_ATTEMPTS; i++) + { + unifi_trace(card->ospriv, UDBG1, "waiting for reset to complete, attempt %d\n", i); + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + /* It's quite likely that this read will timeout for the + * first few tries - especially if we have reset via + * DBG_RESET. + */ +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("m0@%02X=", SDIO_IO_READY); +#endif + csrResult = CsrSdioF0Read8(card->sdio_if, SDIO_IO_READY, &io_enable); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf("error=%X\n", csrResult); + } + else + { + unifi_debug_log_to_buf("%X\n", io_enable); + } +#endif + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + r = CSR_RESULT_SUCCESS; + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + } + } + else + { + r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_enable); + } + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r == CSR_RESULT_SUCCESS) + { + CsrUint16 mbox2; + CsrInt16 enabled = io_enable & (1 << card->function); + + if (!enabled) + { + unifi_trace(card->ospriv, UDBG1, + "Reset complete (function %d is disabled) in ~ %u msecs\n", + card->function, i * MAILBOX2_TIMEOUT); + + /* Enable WLAN function and verify MAILBOX2 is zero'd */ + csrResult = CsrSdioFunctionEnable(card->sdio_if); + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + unifi_error(card->ospriv, "CsrSdioFunctionEnable failed %d\n", r); + break; + } + } + + r = unifi_read_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, &mbox2); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "read HIP_HANDSHAKE failed %d\n", r); + break; + } + if (mbox2 != 0) + { + unifi_error(card->ospriv, "MAILBOX2 non-zero after reset (mbox2 = %04x)\n", mbox2); + r = CSR_RESULT_FAILURE; + } + break; + } + else + { + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + /* We ignore read failures for the first few reads, + * they are probably benign. */ + if (i > MAILBOX2_ATTEMPTS / 4) + { + unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Ready register while polling for reset\n"); + } + } + else + { + unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Enable register while polling for reset\n"); + } + } + CsrThreadSleep(MAILBOX2_TIMEOUT); + } + + if (r == CSR_RESULT_SUCCESS && i == MAILBOX2_ATTEMPTS) + { + unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete reset\n"); + r = CSR_RESULT_FAILURE; + } + + func_exit(); + return r; +} /* card_wait_for_unifi_to_reset() */ + + +/* + * --------------------------------------------------------------------------- + * card_wait_for_unifi_to_disable + * + * Waits for the function to become disabled by polling the + * IO_READY bit. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on failure. + * + * Notes: This function can only be used with + * card->chip_id > SDIO_CARD_ID_UNIFI_2 + * --------------------------------------------------------------------------- + */ +static CsrResult card_wait_for_unifi_to_disable(card_t *card) +{ + CsrInt16 i; + CsrResult r; + CsrUint8 io_enable; + CsrResult csrResult; + + func_enter(); + + if (card->chip_id <= SDIO_CARD_ID_UNIFI_2) + { + unifi_error(card->ospriv, + "Function reset method not supported for chip_id=%d\n", + card->chip_id); + func_exit(); + return CSR_RESULT_FAILURE; + } + + r = CSR_RESULT_SUCCESS; + for (i = 0; i < MAILBOX2_ATTEMPTS; i++) + { + unifi_trace(card->ospriv, UDBG1, "waiting for disable to complete, attempt %d\n", i); + + /* + * It's quite likely that this read will timeout for the + * first few tries - especially if we have reset via + * DBG_RESET. + */ +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("r0@%02X=", SDIO_IO_READY); +#endif + csrResult = CsrSdioF0Read8(card->sdio_if, SDIO_IO_READY, &io_enable); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf("error=%X\n", csrResult); + } + else + { + unifi_debug_log_to_buf("%X\n", io_enable); + } +#endif + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + if (csrResult == CSR_RESULT_SUCCESS) + { + CsrInt16 enabled = io_enable & (1 << card->function); + r = CSR_RESULT_SUCCESS; + if (!enabled) + { + unifi_trace(card->ospriv, UDBG1, + "Disable complete (function %d is disabled) in ~ %u msecs\n", + card->function, i * MAILBOX2_TIMEOUT); + + break; + } + } + else + { + /* + * We ignore read failures for the first few reads, + * they are probably benign. + */ + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + if (i > (MAILBOX2_ATTEMPTS / 4)) + { + unifi_trace(card->ospriv, UDBG1, + "Failed to read CCCR IO Ready register while polling for disable\n"); + } + } + CsrThreadSleep(MAILBOX2_TIMEOUT); + } + + if ((r == CSR_RESULT_SUCCESS) && (i == MAILBOX2_ATTEMPTS)) + { + unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete disable\n"); + r = CSR_RESULT_FAILURE; + } + + func_exit(); + return r; +} /* card_wait_for_unifi_to_reset() */ + + +/* + * --------------------------------------------------------------------------- + * card_wait_for_firmware_to_start + * + * Polls the MAILBOX1 register for a non-zero value. + * Then reads MAILBOX0 and forms the two values into a 32-bit address + * which is returned to the caller. + * + * Arguments: + * card Pointer to card struct + * paddr Pointer to receive the UniFi address formed + * by concatenating MAILBOX1 and MAILBOX0. + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on failure. + * --------------------------------------------------------------------------- + */ +CsrResult card_wait_for_firmware_to_start(card_t *card, CsrUint32 *paddr) +{ + CsrInt32 i; + CsrUint16 mbox0, mbox1; + CsrResult r; + + func_enter(); + + /* + * Wait for UniFi to initialise its data structures by polling + * the SHARED_MAILBOX1 register. + * Experience shows this is typically 120ms. + */ + CsrThreadSleep(MAILBOX1_TIMEOUT); + + mbox1 = 0; + unifi_trace(card->ospriv, UDBG1, "waiting for MAILBOX1 to be non-zero...\n"); + for (i = 0; i < MAILBOX1_ATTEMPTS; i++) + { + r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + /* These reads can fail if UniFi isn't up yet, so try again */ + unifi_warning(card->ospriv, "Failed to read UniFi Mailbox1 register\n"); + } + + if ((r == CSR_RESULT_SUCCESS) && (mbox1 != 0)) + { + unifi_trace(card->ospriv, UDBG1, "MAILBOX1 ready (0x%04X) in %u millisecs\n", + mbox1, i * MAILBOX1_TIMEOUT); + + /* Read the MAILBOX1 again in case we caught the value as it + * changed. */ + r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read UniFi Mailbox1 register for second time\n"); + func_exit_r(r); + return r; + } + unifi_trace(card->ospriv, UDBG1, "MAILBOX1 value=0x%04X\n", mbox1); + + break; + } + + CsrThreadSleep(MAILBOX1_TIMEOUT); + if ((i % 100) == 99) + { + unifi_trace(card->ospriv, UDBG2, "MAILBOX1 not ready (0x%X), still trying...\n", mbox1); + } + } + + if ((r == CSR_RESULT_SUCCESS) && (mbox1 == 0)) + { + unifi_trace(card->ospriv, UDBG1, "Timeout waiting for firmware to start, Mailbox1 still 0 after %d ms\n", + MAILBOX1_ATTEMPTS * MAILBOX1_TIMEOUT); + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + + /* + * Complete the reset handshake by setting MAILBOX2 to 0xFFFF + */ + r = unifi_write_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, 0xFFFF); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write f/w startup handshake to MAILBOX2\n"); + func_exit_r(r); + return r; + } + + + /* + * Read the Symbol Look Up Table (SLUT) offset. + * Top 16 bits are in mbox1, read the lower 16 bits from mbox0. + */ + mbox0 = 0; + r = unifi_read_direct16(card, ChipHelper_MAILBOX0(card->helper) * 2, &mbox0); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read UniFi Mailbox0 register\n"); + func_exit_r(r); + return r; + } + + *paddr = (((CsrUint32)mbox1 << 16) | mbox0); + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* card_wait_for_firmware_to_start() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_capture_panic + * + * Attempt to capture panic codes from the firmware. This may involve + * warm reset of the chip to regain access following a watchdog reset. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS if panic codes were captured, or none available + * CSR_RESULT_FAILURE if the driver could not access function 1 + * --------------------------------------------------------------------------- + */ +CsrResult unifi_capture_panic(card_t *card) +{ + func_enter(); + + /* The firmware must have previously initialised to read the panic addresses + * from the SLUT + */ + if (!card->panic_data_phy_addr || !card->panic_data_mac_addr) + { + func_exit(); + return CSR_RESULT_SUCCESS; + } + + /* Ensure we can access function 1 following a panic/watchdog reset */ + if (card_access_panic(card) == CSR_RESULT_SUCCESS) + { + /* Read the panic codes */ + unifi_read_panic(card); + } + else + { + unifi_info(card->ospriv, "Unable to read panic codes"); + } + + func_exit(); + return CSR_RESULT_SUCCESS; +} + + +/* + * --------------------------------------------------------------------------- + * card_access_panic + * Attempt to read the WLAN SDIO function in order to read panic codes + * and perform various reset steps to regain access if the read fails. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS if panic codes can be read + * CSR error code if panic codes can not be read + * --------------------------------------------------------------------------- + */ +static CsrResult card_access_panic(card_t *card) +{ + CsrUint16 data_u16 = 0; + CsrInt32 i; + CsrResult r, sr; + + func_enter(); + + /* A chip version of zero means that the version never got succesfully read + * during reset. In this case give up because it will not be possible to + * verify the chip version. + */ + if (!card->chip_version) + { + unifi_info(card->ospriv, "Unknown chip version\n"); + return CSR_RESULT_FAILURE; + } + + /* Ensure chip is awake or access to function 1 will fail */ + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "unifi_set_host_state() failed %d\n", r); + return CSR_RESULT_FAILURE; /* Card is probably unpowered */ + } + CsrThreadSleep(20); + + for (i = 0; i < 3; i++) + { + sr = CsrSdioRead16(card->sdio_if, CHIP_HELPER_UNIFI_GBL_CHIP_VERSION * 2, &data_u16); + if (sr != CSR_RESULT_SUCCESS || data_u16 != card->chip_version) + { + unifi_info(card->ospriv, "Failed to read valid chip version sr=%d (0x%04x want 0x%04x) try %d\n", + sr, data_u16, card->chip_version, i); + + /* Set clock speed low */ + sr = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ); + if (sr != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "CsrSdioMaxBusClockFrequencySet() failed1 %d\n", sr); + r = ConvertCsrSdioToCsrHipResult(card, sr); + } + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ; + + /* First try re-enabling function in case a f/w watchdog reset disabled it */ + if (i == 0) + { + unifi_info(card->ospriv, "Try function enable\n"); + sr = CsrSdioFunctionEnable(card->sdio_if); + if (sr != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, sr); + unifi_error(card->ospriv, "CsrSdioFunctionEnable failed %d (HIP %d)\n", sr, r); + } + continue; + } + + /* Second try, set awake */ + unifi_info(card->ospriv, "Try set awake\n"); + + /* Ensure chip is awake */ + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "unifi_set_host_state() failed2 %d\n", r); + } + + /* Set clock speed low in case setting the host state raised it, which + * would only happen if host state was previously TORPID + */ + sr = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ); + if (sr != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "CsrSdioMaxBusClockFrequencySet() failed2 %d\n", sr); + } + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ; + + if (i == 1) + { + continue; + } + + /* Perform a s/w reset to preserve as much as the card state as possible, + * (mainly the preserve RAM). The context will be lost for coredump - but as we + * were unable to access the WLAN function for panic, the coredump would have + * also failed without a reset. + */ + unifi_info(card->ospriv, "Try s/w reset\n"); + + r = unifi_card_hard_reset(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "unifi_card_hard_reset() failed %d\n", r); + } + } + else + { + if (i > 0) + { + unifi_info(card->ospriv, "Read chip version 0x%x after %d retries\n", data_u16, i); + } + break; + } + } + + r = ConvertCsrSdioToCsrHipResult(card, sr); + func_exit_r(r); + return r; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_read_panic + * Reads, saves and prints panic codes stored by the firmware in UniFi's + * preserve RAM by the last panic that occurred since chip was powered. + * Nothing is saved if the panic codes are read as zero. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * --------------------------------------------------------------------------- + */ +void unifi_read_panic(card_t *card) +{ + CsrResult r; + CsrUint16 p_code, p_arg; + + func_enter(); + + /* The firmware must have previously initialised to read the panic addresses + * from the SLUT + */ + if (!card->panic_data_phy_addr || !card->panic_data_mac_addr) + { + return; + } + + /* Get the panic data from PHY */ + r = unifi_card_read16(card, card->panic_data_phy_addr, &p_code); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_phy_addr, r); + p_code = 0; + } + if (p_code) + { + r = unifi_card_read16(card, card->panic_data_phy_addr + 2, &p_arg); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_phy_addr + 2, r); + } + unifi_error(card->ospriv, "Last UniFi PHY PANIC %04x arg %04x\n", p_code, p_arg); + card->last_phy_panic_code = p_code; + card->last_phy_panic_arg = p_arg; + } + + /* Get the panic data from MAC */ + r = unifi_card_read16(card, card->panic_data_mac_addr, &p_code); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_mac_addr, r); + p_code = 0; + } + if (p_code) + { + r = unifi_card_read16(card, card->panic_data_mac_addr + 2, &p_arg); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_mac_addr + 2, r); + } + unifi_error(card->ospriv, "Last UniFi MAC PANIC %04x arg %04x\n", p_code, p_arg); + card->last_mac_panic_code = p_code; + card->last_mac_panic_arg = p_arg; + } + + func_exit(); +} + + +/* + * --------------------------------------------------------------------------- + * card_allocate_memory_resources + * + * Allocates memory for the from-host, to-host bulk data slots, + * soft queue buffers and bulk data buffers. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on failure. + * --------------------------------------------------------------------------- + */ +static CsrResult card_allocate_memory_resources(card_t *card) +{ + CsrInt16 n, i, k, r; + sdio_config_data_t *cfg_data; + + func_enter(); + + /* Reset any state carried forward from a previous life */ + card->fh_command_queue.q_rd_ptr = 0; + card->fh_command_queue.q_wr_ptr = 0; + CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, + "fh_cmd_q"); + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + card->fh_traffic_queue[i].q_rd_ptr = 0; + card->fh_traffic_queue[i].q_wr_ptr = 0; + CsrSnprintf(card->fh_traffic_queue[i].name, + UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); + } +#ifndef CSR_WIFI_HIP_TA_DISABLE + unifi_ta_sampling_init(card); +#endif + /* Convenience short-cut */ + cfg_data = &card->config_data; + + /* + * Allocate memory for the from-host and to-host signal buffers. + */ + card->fh_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE); + if (card->fh_buffer.buf == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + card->fh_buffer.bufsize = UNIFI_FH_BUF_SIZE; + card->fh_buffer.ptr = card->fh_buffer.buf; + card->fh_buffer.count = 0; + + card->th_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE); + if (card->th_buffer.buf == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + card->th_buffer.bufsize = UNIFI_FH_BUF_SIZE; + card->th_buffer.ptr = card->th_buffer.buf; + card->th_buffer.count = 0; + + + /* + * Allocate memory for the from-host and to-host bulk data slots. + * This is done as separate CsrPmemAllocs because lots of smaller + * allocations are more likely to succeed than one huge one. + */ + + /* Allocate memory for the array of pointers */ + n = cfg_data->num_fromhost_data_slots; + + unifi_trace(card->ospriv, UDBG3, "Alloc from-host resources, %d slots.\n", n); + card->from_host_data = + (slot_desc_t *)CsrMemAlloc(n * sizeof(slot_desc_t)); + if (card->from_host_data == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for F-H bulk data array\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + /* Initialise from-host bulk data slots */ + for (i = 0; i < n; i++) + { + UNIFI_INIT_BULK_DATA(&card->from_host_data[i].bd); + } + + /* Allocate memory for the array used for slot host tag mapping */ + card->fh_slot_host_tag_record = + (CsrUint32 *)CsrMemAlloc(n * sizeof(CsrUint32)); + + if (card->fh_slot_host_tag_record == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for F-H slot host tag mapping array\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + + /* Allocate memory for the array of pointers */ + n = cfg_data->num_tohost_data_slots; + + unifi_trace(card->ospriv, UDBG3, "Alloc to-host resources, %d slots.\n", n); + card->to_host_data = + (bulk_data_desc_t *)CsrMemAlloc(n * sizeof(bulk_data_desc_t)); + if (card->to_host_data == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for T-H bulk data array\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + /* Initialise to-host bulk data slots */ + for (i = 0; i < n; i++) + { + UNIFI_INIT_BULK_DATA(&card->to_host_data[i]); + } + + /* + * Initialise buffers for soft Q + */ + for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++) + { + for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) + { + UNIFI_INIT_BULK_DATA(&card->fh_command_q_body[i].bulkdata[r]); + } + } + + for (k = 0; k < UNIFI_NO_OF_TX_QS; k++) + { + for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++) + { + for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) + { + UNIFI_INIT_BULK_DATA(&card->fh_traffic_q_body[k][i].bulkdata[r]); + } + } + } + + card->memory_resources_allocated = 1; + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* card_allocate_memory_resources() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_free_bulk_data + * + * Free the data associated to a bulk data structure. + * + * Arguments: + * card Pointer to card struct + * bulk_data_slot Pointer to bulk data structure + * + * Returns: + * None. + * + * --------------------------------------------------------------------------- + */ +static void unifi_free_bulk_data(card_t *card, bulk_data_desc_t *bulk_data_slot) +{ + if (bulk_data_slot->data_length != 0) + { + unifi_net_data_free(card->ospriv, bulk_data_slot); + } +} /* unifi_free_bulk_data() */ + + +/* + * --------------------------------------------------------------------------- + * card_free_memory_resources + * + * Frees memory allocated for the from-host, to-host bulk data slots, + * soft queue buffers and bulk data buffers. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void card_free_memory_resources(card_t *card) +{ + func_enter(); + + unifi_trace(card->ospriv, UDBG1, "Freeing card memory resources.\n"); + + /* Clear our internal queues */ + unifi_cancel_pending_signals(card); + + + if (card->to_host_data) + { + CsrMemFree(card->to_host_data); + card->to_host_data = NULL; + } + + if (card->from_host_data) + { + CsrMemFree(card->from_host_data); + card->from_host_data = NULL; + } + + /* free the memory for slot host tag mapping array */ + if (card->fh_slot_host_tag_record) + { + CsrMemFree(card->fh_slot_host_tag_record); + card->fh_slot_host_tag_record = NULL; + } + + if (card->fh_buffer.buf) + { + CsrMemFree(card->fh_buffer.buf); + } + card->fh_buffer.ptr = card->fh_buffer.buf = NULL; + card->fh_buffer.bufsize = 0; + card->fh_buffer.count = 0; + + if (card->th_buffer.buf) + { + CsrMemFree(card->th_buffer.buf); + } + card->th_buffer.ptr = card->th_buffer.buf = NULL; + card->th_buffer.bufsize = 0; + card->th_buffer.count = 0; + + + card->memory_resources_allocated = 0; + + func_exit(); +} /* card_free_memory_resources() */ + + +static void card_init_soft_queues(card_t *card) +{ + CsrInt16 i; + + func_enter(); + + unifi_trace(card->ospriv, UDBG1, "Initialising internal signal queues.\n"); + /* Reset any state carried forward from a previous life */ + card->fh_command_queue.q_rd_ptr = 0; + card->fh_command_queue.q_wr_ptr = 0; + CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, + "fh_cmd_q"); + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + card->fh_traffic_queue[i].q_rd_ptr = 0; + card->fh_traffic_queue[i].q_wr_ptr = 0; + CsrSnprintf(card->fh_traffic_queue[i].name, + UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); + } +#ifndef CSR_WIFI_HIP_TA_DISABLE + unifi_ta_sampling_init(card); +#endif + func_exit(); +} + + +/* + * --------------------------------------------------------------------------- + * unifi_cancel_pending_signals + * + * Free the signals and associated bulk data, pending in the core. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void unifi_cancel_pending_signals(card_t *card) +{ + CsrInt16 i, n, r; + func_enter(); + + unifi_trace(card->ospriv, UDBG1, "Canceling pending signals.\n"); + + if (card->to_host_data) + { + /* + * Free any bulk data buffers allocated for the t-h slots + * This will clear all buffers that did not make it to + * unifi_receive_event() before cancel was request. + */ + n = card->config_data.num_tohost_data_slots; + unifi_trace(card->ospriv, UDBG3, "Freeing to-host resources, %d slots.\n", n); + for (i = 0; i < n; i++) + { + unifi_free_bulk_data(card, &card->to_host_data[i]); + } + } + + /* + * If any of the from-host bulk data has reached the card->from_host_data + * but not UniFi, we need to free the buffers here. + */ + if (card->from_host_data) + { + /* Free any bulk data buffers allocated for the f-h slots */ + n = card->config_data.num_fromhost_data_slots; + unifi_trace(card->ospriv, UDBG3, "Freeing from-host resources, %d slots.\n", n); + for (i = 0; i < n; i++) + { + unifi_free_bulk_data(card, &card->from_host_data[i].bd); + } + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + card->dynamic_slot_data.from_host_used_slots[i] = 0; + card->dynamic_slot_data.from_host_max_slots[i] = 0; + card->dynamic_slot_data.from_host_reserved_slots[i] = 0; + } + } + + /* + * Free any bulk data buffers allocated in the soft queues. + * This covers the case where a bulk data pointer has reached the soft queue + * but not the card->from_host_data. + */ + unifi_trace(card->ospriv, UDBG3, "Freeing cmd q resources.\n"); + for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++) + { + for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) + { + unifi_free_bulk_data(card, &card->fh_command_q_body[i].bulkdata[r]); + } + } + + unifi_trace(card->ospriv, UDBG3, "Freeing traffic q resources.\n"); + for (n = 0; n < UNIFI_NO_OF_TX_QS; n++) + { + for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++) + { + for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) + { + unifi_free_bulk_data(card, &card->fh_traffic_q_body[n][i].bulkdata[r]); + } + } + } + + card_init_soft_queues(card); + + func_exit(); +} /* unifi_cancel_pending_signals() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_free_card + * + * Free the memory allocated for the card structure and buffers. + * + * Notes: + * The porting layer is responsible for freeing any mini-coredump buffers + * allocated when it called unifi_coredump_init(), by calling + * unifi_coredump_free() before calling this function. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void unifi_free_card(card_t *card) +{ + func_enter(); +#ifdef CSR_PRE_ALLOC_NET_DATA + prealloc_netdata_free(card); +#endif + /* Free any memory allocated. */ + card_free_memory_resources(card); + + /* Warn if caller didn't free coredump buffers */ + if (card->dump_buf) + { + unifi_error(card->ospriv, "Caller should call unifi_coredump_free()\n"); + unifi_coredump_free(card); /* free anyway to prevent memory leak */ + } + + CsrMemFree(card); + + func_exit(); +} /* unifi_free_card() */ + + +/* + * --------------------------------------------------------------------------- + * card_init_slots + * + * Allocate memory for host-side slot data and signal queues. + * + * Arguments: + * card Pointer to card object + * + * Returns: + * CSR error code. + * --------------------------------------------------------------------------- + */ +static CsrResult card_init_slots(card_t *card) +{ + CsrResult r; + CsrUint8 i; + + func_enter(); + + /* Allocate the buffers we need, only once. */ + if (card->memory_resources_allocated == 1) + { + card_free_memory_resources(card); + } + else + { + /* Initialise our internal command and traffic queues */ + card_init_soft_queues(card); + } + + r = card_allocate_memory_resources(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to allocate card memory resources.\n"); + card_free_memory_resources(card); + func_exit_r(r); + return r; + } + + if (card->sdio_ctrl_addr == 0) + { + unifi_error(card->ospriv, "Failed to find config struct!\n"); + func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* + * Set initial counts. + */ + + card->from_host_data_head = 0; + + /* Get initial signal counts from UniFi, in case it has not been reset. */ + { + CsrUint16 s; + + /* Get the from-host-signals-written count */ + r = unifi_card_read16(card, card->sdio_ctrl_addr + 0, &s); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read from-host sig written count\n"); + func_exit_r(r); + return r; + } + card->from_host_signals_w = (CsrInt16)s; + + /* Get the to-host-signals-written count */ + r = unifi_card_read16(card, card->sdio_ctrl_addr + 6, &s); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read to-host sig read count\n"); + func_exit_r(r); + return r; + } + card->to_host_signals_r = (CsrInt16)s; + } + + /* Set Initialised flag. */ + r = unifi_card_write16(card, card->init_flag_addr, 0x0001); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write initialised flag\n"); + func_exit_r(r); + return r; + } + + /* Dynamic queue reservation */ + CsrMemSet(&card->dynamic_slot_data, 0, sizeof(card_dynamic_slot_t)); + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + card->dynamic_slot_data.from_host_max_slots[i] = card->config_data.num_fromhost_data_slots - + UNIFI_RESERVED_COMMAND_SLOTS; + card->dynamic_slot_data.queue_stable[i] = FALSE; + } + + card->dynamic_slot_data.packets_interval = UNIFI_PACKETS_INTERVAL; + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* card_init_slots() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_set_udi_hook + * + * Registers the udi hook that reports the sent signals to the core. + * + * Arguments: + * card Pointer to the card context struct + * udi_fn Pointer to the callback function. + * + * Returns: + * CSR_WIFI_HIP_RESULT_INVALID_VALUE if the card pointer is invalid, + * CSR_RESULT_SUCCESS on success. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_set_udi_hook(card_t *card, udi_func_t udi_fn) +{ + if (card == NULL) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + if (card->udi_hook == NULL) + { + card->udi_hook = udi_fn; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_set_udi_hook() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_remove_udi_hook + * + * Removes the udi hook that reports the sent signals from the core. + * + * Arguments: + * card Pointer to the card context struct + * udi_fn Pointer to the callback function. + * + * Returns: + * CSR_WIFI_HIP_RESULT_INVALID_VALUE if the card pointer is invalid, + * CSR_RESULT_SUCCESS on success. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn) +{ + if (card == NULL) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + if (card->udi_hook == udi_fn) + { + card->udi_hook = NULL; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_remove_udi_hook() */ + + +static void CardReassignDynamicReservation(card_t *card) +{ + CsrUint8 i; + + func_enter(); + + unifi_trace(card->ospriv, UDBG5, "Packets Txed %d %d %d %d\n", + card->dynamic_slot_data.packets_txed[0], + card->dynamic_slot_data.packets_txed[1], + card->dynamic_slot_data.packets_txed[2], + card->dynamic_slot_data.packets_txed[3]); + + /* Clear reservation and recalculate max slots */ + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + card->dynamic_slot_data.queue_stable[i] = FALSE; + card->dynamic_slot_data.from_host_reserved_slots[i] = 0; + card->dynamic_slot_data.from_host_max_slots[i] = card->config_data.num_fromhost_data_slots - + UNIFI_RESERVED_COMMAND_SLOTS; + card->dynamic_slot_data.packets_txed[i] = 0; + + unifi_trace(card->ospriv, UDBG5, "CardReassignDynamicReservation: queue %d reserved %d Max %d\n", i, + card->dynamic_slot_data.from_host_reserved_slots[i], + card->dynamic_slot_data.from_host_max_slots[i]); + } + + card->dynamic_slot_data.total_packets_txed = 0; + func_exit(); +} + + +/* Algorithm to dynamically reserve slots. The logic is based mainly on the outstanding queue + * length. Slots are reserved for particular queues during an interval and cleared after the interval. + * Each queue has three associated variables.. a) used slots - the number of slots currently occupied + * by the queue b) reserved slots - number of slots reserved specifically for the queue c) max slots - total + * slots that this queue can actually use (may be higher than reserved slots and is dependent on reserved slots + * for other queues). + * This function is called when there are no slots available for a queue. It checks to see if there are enough + * unreserved slots sufficient for this request. If available these slots are reserved for the queue. + * If there are not enough unreserved slots, a fair share for each queue is calculated based on the total slots + * and the number of active queues (any queue with existing reservation is considered active). Queues needing + * less than their fair share are allowed to have the previously reserved slots. The remaining slots are + * distributed evenly among queues that need more than the fair share + * + * A better scheme would take current bandwidth per AC into consideration when reserving slots. An + * implementation scheme could consider the relative time/service period for slots in an AC. If the firmware + * services other ACs faster than a particular AC (packets wait in the slots longer) then it is fair to reserve + * less slots for the AC + */ +static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue) +{ + CsrUint16 q_len, active_queues = 0, excess_queue_slots, div_extra_slots, + queue_fair_share, reserved_slots = 0, q, excess_need_queues = 0, unmovable_slots = 0; + CsrInt32 i; + q_t *sigq; + CsrUint16 num_data_slots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS; + + func_enter(); + + /* Calculate the pending queue length */ + sigq = &card->fh_traffic_queue[queue]; + q_len = CSR_WIFI_HIP_Q_SLOTS_USED(sigq); + + if (q_len <= card->dynamic_slot_data.from_host_reserved_slots[queue]) + { + unifi_trace(card->ospriv, UDBG5, "queue %d q_len %d already has that many reserved slots, exiting\n", queue, q_len); + func_exit(); + return; + } + + /* Upper limit */ + if (q_len > num_data_slots) + { + q_len = num_data_slots; + } + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + if (i != (CsrInt32)queue) + { + reserved_slots += card->dynamic_slot_data.from_host_reserved_slots[i]; + } + if ((i == (CsrInt32)queue) || (card->dynamic_slot_data.from_host_reserved_slots[i] > 0)) + { + active_queues++; + } + } + + unifi_trace(card->ospriv, UDBG5, "CardCheckDynamicReservation: queue %d q_len %d\n", queue, q_len); + unifi_trace(card->ospriv, UDBG5, "Active queues %d reserved slots on other queues %d\n", + active_queues, reserved_slots); + + if (reserved_slots + q_len <= num_data_slots) + { + card->dynamic_slot_data.from_host_reserved_slots[queue] = q_len; + if (q_len == num_data_slots) + { + /* This is the common case when just 1 stream is going */ + card->dynamic_slot_data.queue_stable[queue] = TRUE; + } + } + else + { + queue_fair_share = num_data_slots / active_queues; + unifi_trace(card->ospriv, UDBG5, "queue fair share %d\n", queue_fair_share); + + /* Evenly distribute slots among active queues */ + /* Find out the queues that need excess of fair share. Also find slots allocated + * to queues less than their fair share, these slots cannot be reallocated (unmovable slots) */ + + card->dynamic_slot_data.from_host_reserved_slots[queue] = q_len; + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + if (card->dynamic_slot_data.from_host_reserved_slots[i] > queue_fair_share) + { + excess_need_queues++; + } + else + { + unmovable_slots += card->dynamic_slot_data.from_host_reserved_slots[i]; + } + } + + unifi_trace(card->ospriv, UDBG5, "Excess need queues %d\n", excess_need_queues); + + /* Now find the slots per excess demand queue */ + excess_queue_slots = (num_data_slots - unmovable_slots) / excess_need_queues; + div_extra_slots = (num_data_slots - unmovable_slots) - excess_queue_slots * excess_need_queues; + for (i = UNIFI_NO_OF_TX_QS - 1; i >= 0; i--) + { + if (card->dynamic_slot_data.from_host_reserved_slots[i] > excess_queue_slots) + { + card->dynamic_slot_data.from_host_reserved_slots[i] = excess_queue_slots; + if (div_extra_slots > 0) + { + card->dynamic_slot_data.from_host_reserved_slots[i]++; + div_extra_slots--; + } + /* No more slots will be allocated to this queue during the current interval */ + card->dynamic_slot_data.queue_stable[i] = TRUE; + unifi_trace(card->ospriv, UDBG5, "queue stable %d\n", i); + } + } + } + + /* Redistribute max slots */ + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + reserved_slots = 0; + for (q = 0; q < UNIFI_NO_OF_TX_QS; q++) + { + if (i != q) + { + reserved_slots += card->dynamic_slot_data.from_host_reserved_slots[q]; + } + } + + card->dynamic_slot_data.from_host_max_slots[i] = num_data_slots - reserved_slots; + unifi_trace(card->ospriv, UDBG5, "queue %d reserved %d Max %d\n", i, + card->dynamic_slot_data.from_host_reserved_slots[i], + card->dynamic_slot_data.from_host_max_slots[i]); + } + + func_exit(); +} + + +/* + * --------------------------------------------------------------------------- + * CardClearFromHostDataSlot + * + * Clear a the given data slot, making it available again. + * + * Arguments: + * card Pointer to Card object + * slot Index of the signal slot to clear. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void CardClearFromHostDataSlot(card_t *card, const CsrInt16 slot) +{ + CsrUint8 queue = card->from_host_data[slot].queue; + const void *os_data_ptr = card->from_host_data[slot].bd.os_data_ptr; + + func_enter(); + + if (card->from_host_data[slot].bd.data_length == 0) + { + unifi_warning(card->ospriv, + "Surprise: request to clear an already free FH data slot: %d\n", + slot); + func_exit(); + return; + } + + if (os_data_ptr == NULL) + { + unifi_warning(card->ospriv, + "Clearing FH data slot %d: has null payload, len=%d\n", + slot, card->from_host_data[slot].bd.data_length); + } + + /* Free card->from_host_data[slot].bd.os_net_ptr here. */ + /* Mark slot as free by setting length to 0. */ + unifi_free_bulk_data(card, &card->from_host_data[slot].bd); + if (queue < UNIFI_NO_OF_TX_QS) + { + if (card->dynamic_slot_data.from_host_used_slots[queue] == 0) + { + unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n", + queue, + card->dynamic_slot_data.from_host_used_slots[queue]); + } + else + { + card->dynamic_slot_data.from_host_used_slots[queue]--; + } + card->dynamic_slot_data.packets_txed[queue]++; + card->dynamic_slot_data.total_packets_txed++; + if (card->dynamic_slot_data.total_packets_txed >= card->dynamic_slot_data.packets_interval) + { + CardReassignDynamicReservation(card); + } + } + + unifi_trace(card->ospriv, UDBG4, "CardClearFromHostDataSlot: slot %d recycled %p\n", slot, os_data_ptr); + + func_exit(); +} /* CardClearFromHostDataSlot() */ + + +CsrUint16 CardGetDataSlotSize(card_t *card) +{ + return card->config_data.data_slot_size; +} /* CardGetDataSlotSize() */ + + +/* + * --------------------------------------------------------------------------- + * CardGetFreeFromHostDataSlots + * + * Retrieve the number of from-host bulk data slots available. + * + * Arguments: + * card Pointer to the card context struct + * + * Returns: + * Number of free from-host bulk data slots. + * --------------------------------------------------------------------------- + */ +CsrUint16 CardGetFreeFromHostDataSlots(card_t *card) +{ + CsrUint16 i, n = 0; + + func_enter(); + + /* First two slots reserved for MLME */ + for (i = 0; i < card->config_data.num_fromhost_data_slots; i++) + { + if (card->from_host_data[i].bd.data_length == 0) + { + /* Free slot */ + n++; + } + } + + func_exit(); + return n; +} /* CardGetFreeFromHostDataSlots() */ + + +/* + * --------------------------------------------------------------------------- + * CardAreAllFromHostDataSlotsEmpty + * + * Returns the state of from-host bulk data slots. + * + * Arguments: + * card Pointer to the card context struct + * + * Returns: + * 1 The from-host bulk data slots are all empty (available). + * 0 Some or all the from-host bulk data slots are in use. + * --------------------------------------------------------------------------- + */ +CsrUint16 CardAreAllFromHostDataSlotsEmpty(card_t *card) +{ + CsrUint16 i; + + for (i = 0; i < card->config_data.num_fromhost_data_slots; i++) + { + if (card->from_host_data[i].bd.data_length != 0) + { + return 0; + } + } + + return 1; +} /* CardGetFreeFromHostDataSlots() */ + + +static CsrResult unifi_identify_hw(card_t *card) +{ + func_enter(); + + card->chip_id = card->sdio_if->sdioId.cardId; + card->function = card->sdio_if->sdioId.sdioFunction; + card->sdio_io_block_size = card->sdio_if->blockSize; + + /* If SDIO controller doesn't support byte mode CMD53, pad transfers to block sizes */ + card->sdio_io_block_pad = (card->sdio_if->features & CSR_SDIO_FEATURE_BYTE_MODE)?FALSE : TRUE; + + /* + * Setup the chip helper so that we can access the registers (and + * also tell what sub-type of HIP we should use). + */ + card->helper = ChipHelper_GetVersionSdio((CsrUint8)card->chip_id); + if (!card->helper) + { + unifi_error(card->ospriv, "Null ChipHelper\n"); + } + + unifi_info(card->ospriv, "Chip ID 0x%02X Function %u Block Size %u Name %s(%s)\n", + card->chip_id, card->function, card->sdio_io_block_size, + ChipHelper_MarketingName(card->helper), + ChipHelper_FriendlyName(card->helper)); + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* unifi_identify_hw() */ + + +static CsrResult unifi_prepare_hw(card_t *card) +{ + CsrResult r; + CsrResult csrResult; + enum unifi_host_state old_state = card->host_state; + + func_enter(); + + r = unifi_identify_hw(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to identify hw\n"); + func_exit_r(r); + return r; + } + + unifi_trace(card->ospriv, UDBG1, + "%s mode SDIO\n", card->sdio_io_block_pad?"Block" : "Byte"); + /* + * Chip must be a awake or blocks that are asleep may not get + * reset. We can only do this after we have read the chip_id. + */ + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + + if (old_state == UNIFI_HOST_STATE_TORPID) + { + /* Ensure the initial clock rate is set; if a reset occured when the chip was + * TORPID, unifi_set_host_state() may have raised it to MAX. + */ + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ); + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + func_exit_r(r); + return r; + } + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ; + } + + /* + * The WLAN function must be enabled to access MAILBOX2 and DEBUG_RST + * registers. + */ + csrResult = CsrSdioFunctionEnable(card->sdio_if); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + /* Can't enable WLAN function. Try resetting the SDIO block. */ + unifi_error(card->ospriv, "Failed to re-enable function %d.\n", card->function); + func_exit_r(r); + return r; + } + + /* + * Poke some registers to make sure the PLL has started, + * otherwise memory accesses are likely to fail. + */ + bootstrap_chip_hw(card); + + /* Try to read the chip version from register. */ + r = unifi_read_chip_version(card); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* unifi_prepare_hw() */ + + +static CsrResult unifi_read_chip_version(card_t *card) +{ + CsrUint32 gbl_chip_version; + CsrResult r; + CsrUint16 ver; + + func_enter(); + + gbl_chip_version = ChipHelper_GBL_CHIP_VERSION(card->helper); + + /* Try to read the chip version from register. */ + if (gbl_chip_version != 0) + { + r = unifi_read_direct16(card, gbl_chip_version * 2, &ver); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read GBL_CHIP_VERSION\n"); + func_exit_r(r); + return r; + } + card->chip_version = ver; + } + else + { + unifi_info(card->ospriv, "Unknown Chip ID, cannot locate GBL_CHIP_VERSION\n"); + r = CSR_RESULT_FAILURE; + } + + unifi_info(card->ospriv, "Chip Version 0x%04X\n", card->chip_version); + + func_exit_r(r); + return r; +} /* unifi_read_chip_version() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_reset_hardware + * + * Execute the UniFi reset sequence. + * + * Note: This may fail if the chip is going TORPID so retry at + * least once. + * + * Arguments: + * card - pointer to card context structure + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error otherwise. + * + * Notes: + * Some platforms (e.g. Windows Vista) do not allow access to registers + * that are necessary for a software soft reset. + * --------------------------------------------------------------------------- + */ +static CsrResult unifi_reset_hardware(card_t *card) +{ + CsrResult r; + CsrUint16 new_block_size = UNIFI_IO_BLOCK_SIZE; + CsrResult csrResult; + + func_enter(); + + /* Errors returned by unifi_prepare_hw() are not critical at this point */ + r = unifi_prepare_hw(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + + /* First try SDIO controller reset, which may power cycle the UniFi, assert + * its reset line, or not be implemented depending on the platform. + */ + unifi_info(card->ospriv, "Calling CsrSdioHardReset\n"); + csrResult = CsrSdioHardReset(card->sdio_if); + if (csrResult == CSR_RESULT_SUCCESS) + { + unifi_info(card->ospriv, "CsrSdioHardReset succeeded on reseting UniFi\n"); + r = unifi_prepare_hw(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "unifi_prepare_hw failed after hard reset\n"); + func_exit_r(r); + return r; + } + } + else if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + else + { + /* Falling back to software hard reset methods */ + unifi_info(card->ospriv, "Falling back to software hard reset\n"); + r = unifi_card_hard_reset(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "software hard reset failed\n"); + func_exit_r(r); + return r; + } + + /* If we fell back to unifi_card_hard_reset() methods, chip version may + * not have been read. (Note in the unlikely event that it is zero, + * it will be harmlessly read again) + */ + if (card->chip_version == 0) + { + r = unifi_read_chip_version(card); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + } + } + +#ifdef CSR_WIFI_HIP_SDIO_BLOCK_SIZE + new_block_size = CSR_WIFI_HIP_SDIO_BLOCK_SIZE; +#endif + + /* After hard reset, we need to restore the SDIO block size */ + csrResult = CsrSdioBlockSizeSet(card->sdio_if, new_block_size); + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + + /* Warn if a different block size was achieved by the transport */ + if (card->sdio_if->blockSize != new_block_size) + { + unifi_info(card->ospriv, + "Actually got block size %d\n", card->sdio_if->blockSize); + } + + /* sdio_io_block_size always needs be updated from the achieved block size, + * as it is used by the OS layer to allocate memory in unifi_net_malloc(). + * Controllers which don't support block mode (e.g. CSPI) will report a + * block size of zero. + */ + if (card->sdio_if->blockSize == 0) + { + unifi_info(card->ospriv, "Block size 0, block mode not available\n"); + + /* Set sdio_io_block_size to 1 so that unifi_net_data_malloc() has a + * sensible rounding value. Elsewhere padding will already be + * disabled because the controller supports byte mode. + */ + card->sdio_io_block_size = 1; + + /* Controller features must declare support for byte mode */ + if (!(card->sdio_if->features & CSR_SDIO_FEATURE_BYTE_MODE)) + { + unifi_error(card->ospriv, "Requires byte mode\n"); + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + } + else + { + /* Padding will be enabled if CSR_SDIO_FEATURE_BYTE_MODE isn't set */ + card->sdio_io_block_size = card->sdio_if->blockSize; + } + + + func_exit_r(r); + return r; +} /* unifi_reset_hardware() */ + + +/* + * --------------------------------------------------------------------------- + * card_reset_method_io_enable + * + * Issue a hard reset to the hw writing the IO_ENABLE. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * 0 on success, + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred or if a response + * was not seen in the expected time + * --------------------------------------------------------------------------- + */ +static CsrResult card_reset_method_io_enable(card_t *card) +{ + CsrResult r; + CsrResult csrResult; + + func_enter(); + + /* + * This resets only function 1, so should be used in + * preference to the method below (CSR_FUNC_EN) + */ + unifi_trace(card->ospriv, UDBG1, "Hard reset (IO_ENABLE)\n"); + + csrResult = CsrSdioFunctionDisable(card->sdio_if); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + unifi_warning(card->ospriv, "SDIO error writing IO_ENABLE: %d\n", r); + } + else + { + /* Delay here to let the reset take affect. */ + CsrThreadSleep(RESET_SETTLE_DELAY); + + r = card_wait_for_unifi_to_disable(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + + if (r == CSR_RESULT_SUCCESS) + { + r = card_wait_for_unifi_to_reset(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + } + } + + if (r != CSR_RESULT_SUCCESS) + { + unifi_trace(card->ospriv, UDBG1, "Hard reset (CSR_FUNC_EN)\n"); + + r = sdio_write_f0(card, SDIO_CSR_FUNC_EN, 0); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_warning(card->ospriv, "SDIO error writing SDIO_CSR_FUNC_EN: %d\n", r); + func_exit_r(r); + return r; + } + else + { + /* Delay here to let the reset take affect. */ + CsrThreadSleep(RESET_SETTLE_DELAY); + + r = card_wait_for_unifi_to_reset(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + } + } + + if (r != CSR_RESULT_SUCCESS) + { + unifi_warning(card->ospriv, "card_reset_method_io_enable failed to reset UniFi\n"); + } + + func_exit(); + return r; +} /* card_reset_method_io_enable() */ + + +/* + * --------------------------------------------------------------------------- + * card_reset_method_dbg_reset + * + * Issue a hard reset to the hw writing the DBG_RESET. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred or if a response + * was not seen in the expected time + * --------------------------------------------------------------------------- + */ +static CsrResult card_reset_method_dbg_reset(card_t *card) +{ + CsrResult r; + + func_enter(); + + /* + * Prepare UniFi for h/w reset + */ + if (card->host_state == UNIFI_HOST_STATE_TORPID) + { + r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to set UNIFI_HOST_STATE_DROWSY\n"); + func_exit_r(r); + return r; + } + CsrThreadSleep(5); + } + + r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Can't stop processors\n"); + func_exit(); + return r; + } + + unifi_trace(card->ospriv, UDBG1, "Hard reset (DBG_RESET)\n"); + + /* + * This register write may fail. The debug reset resets + * parts of the Function 0 sections of the chip, and + * therefore the response cannot be sent back to the host. + */ + r = unifi_write_direct_8_or_16(card, ChipHelper_DBG_RESET(card->helper) * 2, 1); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r); + func_exit_r(r); + return r; + } + + /* Delay here to let the reset take affect. */ + CsrThreadSleep(RESET_SETTLE_DELAY); + + r = card_wait_for_unifi_to_reset(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_warning(card->ospriv, "card_reset_method_dbg_reset failed to reset UniFi\n"); + } + + func_exit(); + return r; +} /* card_reset_method_dbg_reset() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_card_hard_reset + * + * Issue reset to hardware, by writing to registers on the card. + * Power to the card is preserved. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred or if a response + * was not seen in the expected time + * --------------------------------------------------------------------------- + */ +CsrResult unifi_card_hard_reset(card_t *card) +{ + CsrResult r; + const struct chip_helper_reset_values *init_data; + CsrUint32 chunks; + + func_enter(); + + /* Clear cache of page registers */ + card->proc_select = (CsrUint32)(-1); + card->dmem_page = (CsrUint32)(-1); + card->pmem_page = (CsrUint32)(-1); + + /* + * We need to have a valid card->helper before we use software hard reset. + * If unifi_identify_hw() fails to get the card ID, it probably means + * that there is no way to talk to the h/w. + */ + r = unifi_identify_hw(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "unifi_card_hard_reset failed to identify h/w\n"); + func_exit(); + return r; + } + + /* Search for some reset code. */ + chunks = ChipHelper_HostResetSequence(card->helper, &init_data); + if (chunks != 0) + { + unifi_error(card->ospriv, + "Hard reset (Code download) is unsupported\n"); + + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + /* The HIP spec considers this a bus-specific reset. + * This resets only function 1, so should be used in + * preference to the method below (CSR_FUNC_EN) + * If this method fails, it means that the f/w is probably + * not running. In this case, try the DBG_RESET method. + */ + r = card_reset_method_io_enable(card); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r == CSR_RESULT_SUCCESS) + { + func_exit(); + return r; + } + } + + /* Software hard reset */ + r = card_reset_method_dbg_reset(card); + + func_exit_r(r); + return r; +} /* unifi_card_hard_reset() */ + + +/* + * --------------------------------------------------------------------------- + * + * CardGenInt + * + * Prod the card. + * This function causes an internal interrupt to be raised in the + * UniFi chip. It is used to signal the firmware that some action has + * been completed. + * The UniFi Host Interface asks that the value used increments for + * debugging purposes. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred or if a response + * was not seen in the expected time + * --------------------------------------------------------------------------- + */ +CsrResult CardGenInt(card_t *card) +{ + CsrResult r; + + func_enter(); + + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + r = sdio_write_f0(card, SDIO_CSR_FROM_HOST_SCRATCH0, + (CsrUint8)card->unifi_interrupt_seq); + } + else + { + r = unifi_write_direct_8_or_16(card, + ChipHelper_SHARED_IO_INTERRUPT(card->helper) * 2, + (CsrUint8)card->unifi_interrupt_seq); + } + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error writing UNIFI_SHARED_IO_INTERRUPT: %d\n", r); + func_exit_r(r); + return r; + } + + card->unifi_interrupt_seq++; + + func_exit(); + return CSR_RESULT_SUCCESS; +} /* CardGenInt() */ + + +/* + * --------------------------------------------------------------------------- + * CardEnableInt + * + * Enable the outgoing SDIO interrupt from UniFi to the host. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred, + * --------------------------------------------------------------------------- + */ +CsrResult CardEnableInt(card_t *card) +{ + CsrResult r; + CsrUint8 int_enable; + + r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n"); + return r; + } + + int_enable |= (1 << card->function) | UNIFI_SD_INT_ENABLE_IENM; + + r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n"); + return r; + } + + return CSR_RESULT_SUCCESS; +} /* CardEnableInt() */ + + +/* + * --------------------------------------------------------------------------- + * CardDisableInt + * + * Disable the outgoing SDIO interrupt from UniFi to the host. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred, + * --------------------------------------------------------------------------- + */ +CsrResult CardDisableInt(card_t *card) +{ + CsrResult r; + CsrUint8 int_enable; + + r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n"); + return r; + } + + int_enable &= ~(1 << card->function); + + r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n"); + return r; + } + + return CSR_RESULT_SUCCESS; +} /* CardDisableInt() */ + + +/* + * --------------------------------------------------------------------------- + * CardPendingInt + * + * Determine whether UniFi is currently asserting the SDIO interrupt + * request. + * + * Arguments: + * card Pointer to Card object + * pintr Pointer to location to write interrupt status, + * TRUE if interrupt pending, + * FALSE if no interrupt pending. + * Returns: + * CSR_RESULT_SUCCESS interrupt status read successfully + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred, + * --------------------------------------------------------------------------- + */ +CsrResult CardPendingInt(card_t *card, CsrBool *pintr) +{ + CsrResult r; + CsrUint8 pending; + + *pintr = FALSE; + + r = sdio_read_f0(card, SDIO_INT_PENDING, &pending); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error reading SDIO_INT_PENDING\n"); + return r; + } + + *pintr = (pending & (1 << card->function))?TRUE : FALSE; + + return CSR_RESULT_SUCCESS; +} /* CardPendingInt() */ + + +/* + * --------------------------------------------------------------------------- + * CardClearInt + * + * Clear the UniFi SDIO interrupt request. + * + * Arguments: + * card Pointer to Card object + * + * Returns: + * CSR_RESULT_SUCCESS if pending interrupt was cleared, or no pending interrupt. + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred, + * --------------------------------------------------------------------------- + */ +CsrResult CardClearInt(card_t *card) +{ + CsrResult r; + CsrBool intr; + + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + /* CardPendingInt() sets intr, if there is a pending interrupt */ + r = CardPendingInt(card, &intr); + if (intr == FALSE) + { + return r; + } + + r = sdio_write_f0(card, SDIO_CSR_HOST_INT_CLEAR, 1); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error writing SDIO_CSR_HOST_INT_CLEAR\n"); + } + } + else + { + r = unifi_write_direct_8_or_16(card, + ChipHelper_SDIO_HOST_INT(card->helper) * 2, + 0); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error writing UNIFI_SDIO_HOST_INT\n"); + } + } + + return r; +} /* CardClearInt() */ + + +/* + * --------------------------------------------------------------------------- + * CardIntEnabled + * + * Determine whether UniFi is currently asserting the SDIO interrupt + * request. + * + * Arguments: + * card Pointer to Card object + * enabled Pointer to location to write interrupt enable status, + * TRUE if interrupts enabled, + * FALSE if interupts disabled. + * + * Returns: + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred, + * --------------------------------------------------------------------------- + */ +CsrResult CardIntEnabled(card_t *card, CsrBool *enabled) +{ + CsrResult r; + CsrUint8 int_enable; + + r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n"); + return r; + } + + *enabled = (int_enable & (1 << card->function))?TRUE : FALSE; + + return CSR_RESULT_SUCCESS; +} /* CardIntEnabled() */ + + +/* + * --------------------------------------------------------------------------- + * CardWriteBulkData + * Allocate slot in the pending bulkdata arrays and assign it to a signal's + * bulkdata reference. The slot is then ready for UniFi's bulkdata commands + * to transfer the data to/from the host. + * + * Arguments: + * card Pointer to Card object + * csptr Pending signal pointer, including bulkdata ref + * queue Traffic queue that this signal is using + * + * Returns: + * CSR_RESULT_SUCCESS if a free slot was assigned + * CSR_RESULT_FAILURE if no slot was available + * --------------------------------------------------------------------------- + */ +CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQueue queue) +{ + CsrUint16 i, slots[UNIFI_MAX_DATA_REFERENCES], j = 0; + CsrUint8 *packed_sigptr, num_slots_required = 0; + bulk_data_desc_t *bulkdata = csptr->bulkdata; + CsrInt16 h, nslots; + + func_enter(); + + /* Count the number of slots required */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) + { + if (bulkdata[i].data_length != 0) + { + num_slots_required++; + } + } + + /* Get the slot numbers */ + if (num_slots_required != 0) + { + /* Last 2 slots for MLME */ + if (queue == UNIFI_TRAFFIC_Q_MLME) + { + h = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS; + for (i = 0; i < card->config_data.num_fromhost_data_slots; i++) + { + if (card->from_host_data[h].bd.data_length == 0) + { + /* Free data slot, claim it */ + slots[j++] = h; + if (j == num_slots_required) + { + break; + } + } + + if (++h >= card->config_data.num_fromhost_data_slots) + { + h = 0; + } + } + } + else + { + if (card->dynamic_slot_data.from_host_used_slots[queue] + < card->dynamic_slot_data.from_host_max_slots[queue]) + { + /* Data commands get a free slot only after a few checks */ + nslots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS; + + h = card->from_host_data_head; + + for (i = 0; i < nslots; i++) + { + if (card->from_host_data[h].bd.data_length == 0) + { + /* Free data slot, claim it */ + slots[j++] = h; + if (j == num_slots_required) + { + break; + } + } + + if (++h >= nslots) + { + h = 0; + } + } + card->from_host_data_head = h; + } + } + + /* Required number of slots are not available, bail out */ + if (j != num_slots_required) + { + unifi_trace(card->ospriv, UDBG5, "CardWriteBulkData: didn't find free slot/s\n"); + + /* If we haven't already reached the stable state we can ask for reservation */ + if ((queue != UNIFI_TRAFFIC_Q_MLME) && (card->dynamic_slot_data.queue_stable[queue] == FALSE)) + { + CardCheckDynamicReservation(card, queue); + } + + for (i = 0; i < card->config_data.num_fromhost_data_slots; i++) + { + unifi_trace(card->ospriv, UDBG5, "fh data slot %d: %d\n", i, card->from_host_data[i].bd.data_length); + } + func_exit(); + return CSR_RESULT_FAILURE; + } + } + + packed_sigptr = csptr->sigbuf; + + /* Fill in the slots with data */ + j = 0; + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) + { + if (bulkdata[i].data_length == 0) + { + /* Zero-out the DATAREF in the signal */ + SET_PACKED_DATAREF_SLOT(packed_sigptr, i, 0); + SET_PACKED_DATAREF_LEN(packed_sigptr, i, 0); + } + else + { + /* + * Fill in the slot number in the SIGNAL structure but + * preserve the offset already in there + */ + SET_PACKED_DATAREF_SLOT(packed_sigptr, i, slots[j] | (((CsrUint16)packed_sigptr[SIZEOF_SIGNAL_HEADER + (i * SIZEOF_DATAREF) + 1]) << 8)); + SET_PACKED_DATAREF_LEN(packed_sigptr, i, bulkdata[i].data_length); + + /* Do not copy the data, just store the information to them */ + card->from_host_data[slots[j]].bd.os_data_ptr = bulkdata[i].os_data_ptr; + card->from_host_data[slots[j]].bd.os_net_buf_ptr = bulkdata[i].os_net_buf_ptr; + card->from_host_data[slots[j]].bd.data_length = bulkdata[i].data_length; + card->from_host_data[slots[j]].bd.net_buf_length = bulkdata[i].net_buf_length; + card->from_host_data[slots[j]].queue = queue; + + unifi_trace(card->ospriv, UDBG4, "CardWriteBulkData sig=0x%x, fh slot %d = %p\n", + GET_SIGNAL_ID(packed_sigptr), i, bulkdata[i].os_data_ptr); + + /* Sanity-check that the bulk data desc being assigned to the slot + * actually has a payload. + */ + if (!bulkdata[i].os_data_ptr) + { + unifi_error(card->ospriv, "Assign null os_data_ptr (len=%d) fh slot %d, i=%d, q=%d, sig=0x%x", + bulkdata[i].data_length, slots[j], i, queue, GET_SIGNAL_ID(packed_sigptr)); + } + + j++; + if (queue < UNIFI_NO_OF_TX_QS) + { + card->dynamic_slot_data.from_host_used_slots[queue]++; + } + } + } + + func_exit(); + + return CSR_RESULT_SUCCESS; +} /* CardWriteBulkData() */ + + +/* + * --------------------------------------------------------------------------- + * card_find_data_slot + * + * Dereference references to bulk data slots into pointers to real data. + * + * Arguments: + * card Pointer to the card struct. + * slot Slot number from a signal structure + * + * Returns: + * Pointer to entry in bulk_data_slot array. + * --------------------------------------------------------------------------- + */ +bulk_data_desc_t* card_find_data_slot(card_t *card, CsrInt16 slot) +{ + CsrInt16 sn; + bulk_data_desc_t *bd; + + sn = slot & 0x7FFF; + + /* ?? check sanity of slot number ?? */ + + if (slot & SLOT_DIR_TO_HOST) + { + bd = &card->to_host_data[sn]; + } + else + { + bd = &card->from_host_data[sn].bd; + } + + return bd; +} /* card_find_data_slot() */ + + +/* + * --------------------------------------------------------------------------- + * firmware_present_in_flash + * + * Probe for external Flash that looks like it might contain firmware. + * + * If Flash is not present, reads always return 0x0008. + * If Flash is present, but empty, reads return 0xFFFF. + * Anything else is considered to be firmware. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS firmware is present in ROM or flash + * CSR_WIFI_HIP_RESULT_NOT_FOUND firmware is not present in ROM or flash + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred + * --------------------------------------------------------------------------- + */ +static CsrResult firmware_present_in_flash(card_t *card) +{ + CsrResult r; + CsrUint16 m1, m5; + + if (ChipHelper_HasRom(card->helper)) + { + return CSR_RESULT_SUCCESS; + } + if (!ChipHelper_HasFlash(card->helper)) + { + return CSR_WIFI_HIP_RESULT_NOT_FOUND; + } + + /* + * Examine the Flash locations that are the power-on default reset + * vectors of the XAP processors. + * These are words 1 and 5 in Flash. + */ + r = unifi_card_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 2), &m1); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + r = unifi_card_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 10), &m5); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + /* Check for uninitialised/missing flash */ + if ((m1 == 0x0008) || (m1 == 0xFFFF) || + (m1 == 0x0004) || (m5 == 0x0004) || + (m5 == 0x0008) || (m5 == 0xFFFF)) + { + return CSR_WIFI_HIP_RESULT_NOT_FOUND; + } + + return CSR_RESULT_SUCCESS; +} /* firmware_present_in_flash() */ + + +/* + * --------------------------------------------------------------------------- + * bootstrap_chip_hw + * + * Perform chip specific magic to "Get It Working" TM. This will + * increase speed of PLLs in analogue and maybe enable some + * on-chip regulators. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void bootstrap_chip_hw(card_t *card) +{ + const struct chip_helper_init_values *vals; + CsrUint32 i, len; + void *sdio = card->sdio_if; + CsrResult csrResult; + + len = ChipHelper_ClockStartupSequence(card->helper, &vals); + if (len != 0) + { + for (i = 0; i < len; i++) + { + csrResult = CsrSdioWrite16(sdio, vals[i].addr * 2, vals[i].value); + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_warning(card->ospriv, "Failed to write bootstrap value %d\n", i); + /* Might not be fatal */ + } + + CsrThreadSleep(1); + } + } +} /* bootstrap_chip_hw() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_card_stop_processor + * + * Stop the UniFi XAP processors. + * + * Arguments: + * card Pointer to card struct + * which One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH + * + * Returns: + * CSR_RESULT_SUCCESS if successful, or CSR error code + * --------------------------------------------------------------------------- + */ +CsrResult unifi_card_stop_processor(card_t *card, enum unifi_dbg_processors_select which) +{ + CsrResult r = CSR_RESULT_SUCCESS; + CsrUint8 status; + CsrInt16 retry = 100; + + while (retry--) + { + /* Select both XAPs */ + r = unifi_set_proc_select(card, which); + if (r != CSR_RESULT_SUCCESS) + { + break; + } + + /* Stop processors */ + r = unifi_write_direct16(card, ChipHelper_DBG_EMU_CMD(card->helper) * 2, 2); + if (r != CSR_RESULT_SUCCESS) + { + break; + } + + /* Read status */ + r = unifi_read_direct_8_or_16(card, + ChipHelper_DBG_HOST_STOP_STATUS(card->helper) * 2, + &status); + if (r != CSR_RESULT_SUCCESS) + { + break; + } + + if ((status & 1) == 1) + { + /* Success! */ + return CSR_RESULT_SUCCESS; + } + + /* Processors didn't stop, try again */ + } + + if (r != CSR_RESULT_SUCCESS) + { + /* An SDIO error occurred */ + unifi_error(card->ospriv, "Failed to stop processors: SDIO error\n"); + } + else + { + /* If we reach here, we didn't the status in time. */ + unifi_error(card->ospriv, "Failed to stop processors: timeout waiting for stopped status\n"); + r = CSR_RESULT_FAILURE; + } + + return r; +} /* unifi_card_stop_processor() */ + + +/* + * --------------------------------------------------------------------------- + * card_start_processor + * + * Start the UniFi XAP processors. + * + * Arguments: + * card Pointer to card struct + * which One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH + * + * Returns: + * CSR_RESULT_SUCCESS or CSR error code + * --------------------------------------------------------------------------- + */ +CsrResult card_start_processor(card_t *card, enum unifi_dbg_processors_select which) +{ + CsrResult r; + + /* Select both XAPs */ + r = unifi_set_proc_select(card, which); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "unifi_set_proc_select failed: %d.\n", r); + return r; + } + + + r = unifi_write_direct_8_or_16(card, + ChipHelper_DBG_EMU_CMD(card->helper) * 2, 8); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + r = unifi_write_direct_8_or_16(card, + ChipHelper_DBG_EMU_CMD(card->helper) * 2, 0); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + return CSR_RESULT_SUCCESS; +} /* card_start_processor() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_set_interrupt_mode + * + * Configure the interrupt processing mode used by the HIP + * + * Arguments: + * card Pointer to card struct + * mode Interrupt mode to apply + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +void unifi_set_interrupt_mode(card_t *card, CsrUint32 mode) +{ + if (mode == CSR_WIFI_INTMODE_RUN_BH_ONCE) + { + unifi_info(card->ospriv, "Scheduled interrupt mode"); + } + card->intmode = mode; +} /* unifi_set_interrupt_mode() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_start_processors + * + * Start all UniFi XAP processors. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on error + * --------------------------------------------------------------------------- + */ +CsrResult unifi_start_processors(card_t *card) +{ + return card_start_processor(card, UNIFI_PROC_BOTH); +} /* unifi_start_processors() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_request_max_sdio_clock + * + * Requests that the maximum SDIO clock rate is set at the next suitable + * opportunity (e.g. when the BH next runs, so as not to interfere with + * any current operation). + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +void unifi_request_max_sdio_clock(card_t *card) +{ + card->request_max_clock = 1; +} /* unifi_request_max_sdio_clock() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_set_host_state + * + * Set the host deep-sleep state. + * + * If transitioning to TORPID, the SDIO driver will be notified + * that the SD bus will be unused (idle) and conversely, when + * transitioning from TORPID that the bus will be used (active). + * + * Arguments: + * card Pointer to card struct + * state New deep-sleep state. + * + * Returns: + * CSR_RESULT_SUCCESS on success + * CSR_WIFI_HIP_RESULT_NO_DEVICE if the card was ejected + * CSR_RESULT_FAILURE if an SDIO error occurred + * + * Notes: + * We need to reduce the SDIO clock speed before trying to wake up the + * chip. Actually, in the implementation below we reduce the clock speed + * not just before we try to wake up the chip, but when we put the chip to + * deep sleep. This means that if the f/w wakes up on its' own, we waste + * a reduce/increace cycle. However, trying to eliminate this overhead is + * proved difficult, as the current state machine in the HIP lib does at + * least a CMD52 to disable the interrupts before we configure the host + * state. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_set_host_state(card_t *card, enum unifi_host_state state) +{ + CsrResult r = CSR_RESULT_SUCCESS; + CsrResult csrResult; + static const CsrCharString *const states[] = { + "AWAKE", "DROWSY", "TORPID" + }; + static const CsrUint8 state_csr_host_wakeup[] = { + 1, 3, 0 + }; + static const CsrUint8 state_io_abort[] = { + 0, 2, 3 + }; + + unifi_trace(card->ospriv, UDBG4, "State %s to %s\n", + states[card->host_state], states[state]); + + if (card->host_state == UNIFI_HOST_STATE_TORPID) + { + CsrSdioFunctionActive(card->sdio_if); + } + + /* Write the new state to UniFi. */ + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + r = sdio_write_f0(card, SDIO_CSR_HOST_WAKEUP, + (CsrUint8)((card->function << 4) | state_csr_host_wakeup[state])); + } + else + { + r = sdio_write_f0(card, SDIO_IO_ABORT, state_io_abort[state]); + } + + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write UniFi deep sleep state\n"); + } + else + { + /* + * If the chip was in state TORPID then we can now increase + * the maximum bus clock speed. + */ + if (card->host_state == UNIFI_HOST_STATE_TORPID) + { + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, + UNIFI_SDIO_CLOCK_MAX_HZ); + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + /* Non-fatal error */ + if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + unifi_warning(card->ospriv, + "Failed to increase the SDIO clock speed\n"); + } + else + { + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ; + } + } + + /* + * Cache the current state in the card structure to avoid + * unnecessary SDIO reads. + */ + card->host_state = state; + + if (state == UNIFI_HOST_STATE_TORPID) + { + /* + * If the chip is now in state TORPID then we must now decrease + * the maximum bus clock speed. + */ + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, + UNIFI_SDIO_CLOCK_SAFE_HZ); + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + unifi_warning(card->ospriv, + "Failed to decrease the SDIO clock speed\n"); + } + else + { + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ; + } + CsrSdioFunctionIdle(card->sdio_if); + } + } + + return r; +} /* unifi_set_host_state() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_card_info + * + * Update the card information data structure + * + * Arguments: + * card Pointer to card struct + * card_info Pointer to info structure to update + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +void unifi_card_info(card_t *card, card_info_t *card_info) +{ + card_info->chip_id = card->chip_id; + card_info->chip_version = card->chip_version; + card_info->fw_build = card->build_id; + card_info->fw_hip_version = card->config_data.version; + card_info->sdio_block_size = card->sdio_io_block_size; +} /* unifi_card_info() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_check_io_status + * + * Check UniFi for spontaneous reset and pending interrupt. + * + * Arguments: + * card Pointer to card struct + * status Pointer to location to write chip status: + * 0 if UniFi is running, and no interrupt pending + * 1 if UniFi has spontaneously reset + * 2 if there is a pending interrupt + * Returns: + * CSR_RESULT_SUCCESS if OK, or CSR error + * --------------------------------------------------------------------------- + */ +CsrResult unifi_check_io_status(card_t *card, CsrInt32 *status) +{ + CsrUint8 io_en; + CsrResult r; + CsrBool pending; + + *status = 0; + + r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_en); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read SDIO_IO_ENABLE to check for spontaneous reset\n"); + return r; + } + + if ((io_en & (1 << card->function)) == 0) + { + CsrInt32 fw_count; + *status = 1; + unifi_error(card->ospriv, "UniFi has spontaneously reset.\n"); + + /* + * These reads are very likely to fail. We want to know if the function is really + * disabled or the SDIO driver just returns rubbish. + */ + fw_count = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); + if (fw_count < 0) + { + unifi_error(card->ospriv, "Failed to read to-host sig written count\n"); + } + else + { + unifi_error(card->ospriv, "thsw: %u (driver thinks is %u)\n", + fw_count, card->to_host_signals_w); + } + fw_count = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2); + if (fw_count < 0) + { + unifi_error(card->ospriv, "Failed to read from-host sig read count\n"); + } + else + { + unifi_error(card->ospriv, "fhsr: %u (driver thinks is %u)\n", + fw_count, card->from_host_signals_r); + } + + return r; + } + + unifi_info(card->ospriv, "UniFi function %d is enabled.\n", card->function); + + /* See if we missed an SDIO interrupt */ + r = CardPendingInt(card, &pending); + if (pending) + { + unifi_error(card->ospriv, "There is an unhandled pending interrupt.\n"); + *status = 2; + return r; + } + + return r; +} /* unifi_check_io_status() */ + + +void unifi_get_hip_qos_info(card_t *card, unifi_HipQosInfo *hipqosinfo) +{ + CsrInt32 count_fhr; + CsrInt16 t; + CsrUint32 occupied_fh; + + q_t *sigq; + CsrUint16 nslots, i; + + CsrMemSet(hipqosinfo, 0, sizeof(unifi_HipQosInfo)); + + nslots = card->config_data.num_fromhost_data_slots; + + for (i = 0; i < nslots; i++) + { + if (card->from_host_data[i].bd.data_length == 0) + { + hipqosinfo->free_fh_bulkdata_slots++; + } + } + + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + sigq = &card->fh_traffic_queue[i]; + t = sigq->q_wr_ptr - sigq->q_rd_ptr; + if (t < 0) + { + t += sigq->q_length; + } + hipqosinfo->free_fh_sig_queue_slots[i] = (sigq->q_length - t) - 1; + } + + count_fhr = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2); + if (count_fhr < 0) + { + unifi_error(card->ospriv, "Failed to read from-host sig read count - %d\n", count_fhr); + hipqosinfo->free_fh_fw_slots = 0xfa; + return; + } + + occupied_fh = (card->from_host_signals_w - count_fhr) % 128; + + hipqosinfo->free_fh_fw_slots = (CsrUint16)(card->config_data.num_fromhost_sig_frags - occupied_fh); +} + + + +CsrResult ConvertCsrSdioToCsrHipResult(card_t *card, CsrResult csrResult) +{ + CsrResult r = CSR_RESULT_FAILURE; + + switch (csrResult) + { + case CSR_RESULT_SUCCESS: + r = CSR_RESULT_SUCCESS; + break; + /* Timeout errors */ + case CSR_SDIO_RESULT_TIMEOUT: + /* Integrity errors */ + case CSR_SDIO_RESULT_CRC_ERROR: + r = CSR_RESULT_FAILURE; + break; + case CSR_SDIO_RESULT_NO_DEVICE: + r = CSR_WIFI_HIP_RESULT_NO_DEVICE; + break; + case CSR_SDIO_RESULT_INVALID_VALUE: + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + break; + case CSR_RESULT_FAILURE: + r = CSR_RESULT_FAILURE; + break; + default: + unifi_warning(card->ospriv, "Unrecognised csrResult error code: %d\n", csrResult); + break; + } + + return r; +} /* ConvertCsrSdioToCsrHipResult() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.h b/drivers/staging/csr/csr_wifi_hip_card_sdio.h new file mode 100644 index 000000000000..4481d81eee48 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.h @@ -0,0 +1,702 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * + * FILE: csr_wifi_hip_card_sdio.h + * + * PURPOSE: + * Internal header for Card API for SDIO. + * --------------------------------------------------------------------------- + */ +#ifndef __CARD_SDIO_H__ +#define __CARD_SDIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_unifi_udi.h" +#include "csr_wifi_hip_unifihw.h" +#include "csr_wifi_hip_unifiversion.h" +#ifndef CSR_WIFI_HIP_TA_DISABLE +#include "csr_wifi_hip_ta_sampling.h" +#endif +#include "csr_wifi_hip_xbv.h" +#include "csr_wifi_hip_chiphelper.h" + + +/* + * + * Configuration items. + * Which of these should go in a platform unifi_config.h file? + * + */ + +/* + * When the traffic queues contain more signals than there is space for on + * UniFi, a limiting algorithm comes into play. + * If a traffic queue has enough slots free to buffer more traffic from the + * network stack, then the following check is applied. The number of free + * slots is RESUME_XMIT_THRESHOLD. + */ +#define RESUME_XMIT_THRESHOLD 4 + + +/* + * When reading signals from UniFi, the host processes pending all signals + * and then acknowledges them together in a single write to update the + * to-host-chunks-read location. + * When there is more than one bulk data transfer (e.g. one received data + * packet and a request for the payload data of a transmitted packet), the + * update can be delayed significantly. This ties up resources on chip. + * + * To remedy this problem, to-host-chunks-read is updated after processing + * a signal if TO_HOST_FLUSH_THRESHOLD bytes of bulk data have been + * transferred since the last update. + */ +#define TO_HOST_FLUSH_THRESHOLD (500 * 5) + + +/* SDIO Card Common Control Registers */ +#define SDIO_CCCR_SDIO_REVISION (0x00) +#define SDIO_SD_SPEC_REVISION (0x01) +#define SDIO_IO_ENABLE (0x02) +#define SDIO_IO_READY (0x03) +#define SDIO_INT_ENABLE (0x04) +#define SDIO_INT_PENDING (0x05) +#define SDIO_IO_ABORT (0x06) +#define SDIO_BUS_IFACE_CONTROL (0x07) +#define SDIO_CARD_CAPABILOTY (0x08) +#define SDIO_COMMON_CIS_POINTER (0x09) +#define SDIO_BUS_SUSPEND (0x0C) +#define SDIO_FUNCTION_SELECT (0x0D) +#define SDIO_EXEC_FLAGS (0x0E) +#define SDIO_READY_FLAGS (0x0F) +#define SDIO_FN0_BLOCK_SIZE (0x10) +#define SDIO_POWER_CONTROL (0x12) +#define SDIO_VENDOR_START (0xF0) + +#define SDIO_CSR_HOST_WAKEUP (0xf0) +#define SDIO_CSR_HOST_INT_CLEAR (0xf1) +#define SDIO_CSR_FROM_HOST_SCRATCH0 (0xf2) +#define SDIO_CSR_FROM_HOST_SCRATCH1 (0xf3) +#define SDIO_CSR_TO_HOST_SCRATCH0 (0xf4) +#define SDIO_CSR_TO_HOST_SCRATCH1 (0xf5) +#define SDIO_CSR_FUNC_EN (0xf6) +#define SDIO_CSR_CSPI_MODE (0xf7) +#define SDIO_CSR_CSPI_STATUS (0xf8) +#define SDIO_CSR_CSPI_PADDING (0xf9) + + +#define UNIFI_SD_INT_ENABLE_IENM 0x0001 /* Master INT Enable */ + +#ifdef CSR_PRE_ALLOC_NET_DATA +#define BULK_DATA_PRE_ALLOC_NUM 16 +#endif + +/* + * Structure to hold configuration information read from UniFi. + */ +typedef struct +{ + /* + * The version of the SDIO signal queues and bulk data pools + * configuration structure. The MSB is the major version number, used to + * indicate incompatible changes. The LSB gives the minor revision number, + * used to indicate changes that maintain backwards compatibility. + */ + CsrUint16 version; + + /* + * offset from the start of the shared data memory to the SD IO + * control structure. + */ + CsrUint16 sdio_ctrl_offset; + + /* Buffer handle of the from-host signal queue */ + CsrUint16 fromhost_sigbuf_handle; + + /* Buffer handle of the to-host signal queue */ + CsrUint16 tohost_sigbuf_handle; + + /* + * Maximum number of signal primitive or bulk data command fragments that may be + * pending in the to-hw signal queue. + */ + CsrUint16 num_fromhost_sig_frags; + + /* + * Number of signal primitive or bulk data command fragments that must be pending + * in the to-host signal queue before the host will generate an interrupt + * to indicate that it has read a signal. This will usually be the total + * capacity of the to-host signal buffer less the size of the largest signal + * primitive divided by the signal primitive fragment size, but may be set + * to 1 to request interrupts every time that the host read a signal. + * Note that the hw may place more signals in the to-host signal queue + * than indicated by this field. + */ + CsrUint16 num_tohost_sig_frags; + + /* + * Number of to-hw bulk data slots. Slots are numbered from 0 (zero) to + * one less than the value in this field + */ + CsrUint16 num_fromhost_data_slots; + + /* + * Number of frm-hw bulk data slots. Slots are numbered from 0 (zero) to + * one less than the value in this field + */ + CsrUint16 num_tohost_data_slots; + + /* + * Size of the bulk data slots (2 octets) + * The size of the bulk data slots in octets. This will usually be + * the size of the largest MSDU. The value should always be even. + */ + CsrUint16 data_slot_size; + + /* + * Indicates that the host has finished the initialisation sequence. + * Initialised to 0x0000 by the firmware, and set to 0x0001 by us. + */ + CsrUint16 initialised; + + /* Added by protocol version 0x0001 */ + CsrUint32 overlay_size; + + /* Added by protocol version 0x0300 */ + CsrUint16 data_slot_round; + CsrUint16 sig_frag_size; + + /* Added by protocol version 0x0500 */ + CsrUint16 tohost_signal_padding; +} sdio_config_data_t; + +/* + * These values may change with versions of the Host Interface Protocol. + */ +/* + * Size of config info block pointed to by the CSR_SLT_SDIO_SLOT_CONFIG + * entry in the f/w symbol table + */ +#define SDIO_CONFIG_DATA_SIZE 30 + +/* Offset of the INIT flag in the config info block. */ +#define SDIO_INIT_FLAG_OFFSET 0x12 +#define SDIO_TO_HOST_SIG_PADDING_OFFSET 0x1C + + +/* Structure for a bulk data transfer command */ +typedef struct +{ + CsrUint16 cmd_and_len; /* bits 12-15 cmd, bits 0-11 len */ + CsrUint16 data_slot; /* slot number, perhaps OR'd with SLOT_DIR_TO_HOST */ + CsrUint16 offset; + CsrUint16 buffer_handle; +} bulk_data_cmd_t; + + +/* Bulk Data signal command values */ +#define SDIO_CMD_SIGNAL 0x00 +#define SDIO_CMD_TO_HOST_TRANSFER 0x01 +#define SDIO_CMD_TO_HOST_TRANSFER_ACK 0x02 /*deprecated*/ +#define SDIO_CMD_FROM_HOST_TRANSFER 0x03 +#define SDIO_CMD_FROM_HOST_TRANSFER_ACK 0x04 /*deprecated*/ +#define SDIO_CMD_CLEAR_SLOT 0x05 +#define SDIO_CMD_OVERLAY_TRANSFER 0x06 +#define SDIO_CMD_OVERLAY_TRANSFER_ACK 0x07 /*deprecated*/ +#define SDIO_CMD_FROM_HOST_AND_CLEAR 0x08 +#define SDIO_CMD_PADDING 0x0f + +#define SLOT_DIR_TO_HOST 0x8000 + + +/* Initialise bulkdata slot + * params: + * bulk_data_desc_t *bulk_data_slot + */ +#define UNIFI_INIT_BULK_DATA(bulk_data_slot) \ + { \ + (bulk_data_slot)->os_data_ptr = NULL; \ + (bulk_data_slot)->data_length = 0; \ + (bulk_data_slot)->os_net_buf_ptr = NULL; \ + (bulk_data_slot)->net_buf_length = 0; \ + } + +/* + * Structure to contain a SIGNAL datagram. + * This is used to build signal queues between the main driver and the + * i/o thread. + * The fields are: + * sigbuf Contains the HIP signal is wire-format (i.e. packed, + * little-endian) + * bulkdata Contains a copy of any associated bulk data + * signal_length The size of the signal in the sigbuf + */ +typedef struct card_signal +{ + CsrUint8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE]; + + /* Length of the SIGNAL inside sigbuf */ + CsrUint16 signal_length; + + bulk_data_desc_t bulkdata[UNIFI_MAX_DATA_REFERENCES]; +} card_signal_t; + + +/* + * Control structure for a generic ring buffer. + */ +#define UNIFI_QUEUE_NAME_MAX_LENGTH 16 +typedef struct +{ + card_signal_t *q_body; + + /* Num elements in queue (capacity is one less than this!) */ + CsrUint16 q_length; + + CsrUint16 q_wr_ptr; + CsrUint16 q_rd_ptr; + + CsrCharString name[UNIFI_QUEUE_NAME_MAX_LENGTH]; +} q_t; + + +#define UNIFI_RESERVED_COMMAND_SLOTS 2 + +/* Considering approx 500 us per packet giving 0.5 secs */ +#define UNIFI_PACKETS_INTERVAL 1000 + +/* + * Dynamic slot reservation for QoS + */ +typedef struct +{ + CsrUint16 from_host_used_slots[UNIFI_NO_OF_TX_QS]; + CsrUint16 from_host_max_slots[UNIFI_NO_OF_TX_QS]; + CsrUint16 from_host_reserved_slots[UNIFI_NO_OF_TX_QS]; + + /* Parameters to determine if a queue was active. + If number of packets sent is greater than the threshold + for the queue, the queue is considered active and no + re reservation is done, it is important not to keep this + value too low */ + /* Packets sent during this interval */ + CsrUint16 packets_txed[UNIFI_NO_OF_TX_QS]; + CsrUint16 total_packets_txed; + + /* Number of packets to see if slots need to be reassigned */ + CsrUint16 packets_interval; + + /* Once a queue reaches a stable state, avoid processing */ + CsrBool queue_stable[UNIFI_NO_OF_TX_QS]; +} card_dynamic_slot_t; + + +/* These are type-safe and don't write incorrect values to the + * structure. */ + +/* Return queue slots used count + * params: + * const q_t *q + * returns: + * CsrUint16 + */ +#define CSR_WIFI_HIP_Q_SLOTS_USED(q) \ + (((q)->q_wr_ptr - (q)->q_rd_ptr < 0)? \ + ((q)->q_wr_ptr - (q)->q_rd_ptr + (q)->q_length) : ((q)->q_wr_ptr - (q)->q_rd_ptr)) + +/* Return queue slots free count + * params: + * const q_t *q + * returns: + * CsrUint16 + */ +#define CSR_WIFI_HIP_Q_SLOTS_FREE(q) \ + ((q)->q_length - CSR_WIFI_HIP_Q_SLOTS_USED((q)) - 1) + +/* Return slot signal data pointer + * params: + * const q_t *q + * CsrUint16 slot + * returns: + * card_signal_t * + */ +#define CSR_WIFI_HIP_Q_SLOT_DATA(q, slot) \ + ((q)->q_body + slot) + +/* Return queue next read slot + * params: + * const q_t *q + * returns: + * CsrUint16 slot offset + */ +#define CSR_WIFI_HIP_Q_NEXT_R_SLOT(q) \ + ((q)->q_rd_ptr) + +/* Return queue next write slot + * params: + * const q_t *q + * returns: + * CsrUint16 slot offset + */ +#define CSR_WIFI_HIP_Q_NEXT_W_SLOT(q) \ + ((q)->q_wr_ptr) + +/* Return updated queue pointer wrapped around its length + * params: + * const q_t *q + * CsrUint16 x amount to add to queue pointer + * returns: + * CsrUint16 wrapped queue pointer + */ +#define CSR_WIFI_HIP_Q_WRAP(q, x) \ + ((((x) >= (q)->q_length)?((x) % (q)->q_length) : (x))) + +/* Advance queue read pointer + * params: + * const q_t *q + */ +#define CSR_WIFI_HIP_Q_INC_R(q) \ + ((q)->q_rd_ptr = CSR_WIFI_HIP_Q_WRAP((q), (q)->q_rd_ptr + 1)) + +/* Advance queue write pointer + * params: + * const q_t *q + */ +#define CSR_WIFI_HIP_Q_INC_W(q) \ + ((q)->q_wr_ptr = CSR_WIFI_HIP_Q_WRAP((q), (q)->q_wr_ptr + 1)) + +enum unifi_host_state +{ + UNIFI_HOST_STATE_AWAKE = 0, + UNIFI_HOST_STATE_DROWSY = 1, + UNIFI_HOST_STATE_TORPID = 2 +}; + +typedef struct +{ + bulk_data_desc_t bd; + unifi_TrafficQueue queue; /* Used for dynamic slot reservation */ +} slot_desc_t; + +/* + * Structure describing a UniFi SDIO card. + */ +struct card +{ + /* + * Back pointer for the higher level OS code. This is passed as + * an argument to callbacks (e.g. for received data and indications). + */ + void *ospriv; + + /* + * mapping of HIP slot to MA-PACKET.req host tag, the + * array is indexed by slot numbers and each index stores + * information of the last host tag it was used for + */ + CsrUint32 *fh_slot_host_tag_record; + + + /* Info read from Symbol Table during probe */ + CsrUint32 build_id; + CsrCharString build_id_string[128]; + + /* Retrieve from SDIO driver. */ + CsrUint16 chip_id; + + /* Read from GBL_CHIP_VERSION. */ + CsrUint16 chip_version; + + /* From the SDIO driver (probably 1) */ + CsrUint8 function; + + /* This is sused to get the register addresses and things. */ + ChipDescript *helper; + + /* + * Bit mask of PIOs for the loader to waggle during download. + * We assume these are connected to LEDs. The main firmware gets + * the mask from a MIB entry. + */ + CsrInt32 loader_led_mask; + + /* + * Support for flow control. When the from-host queue of signals + * is full, we ask the host upper layer to stop sending packets. When + * the queue drains we tell it that it can send packets again. + * We use this flag to remember the current state. + */ +#define card_is_tx_q_paused(card, q) (card->tx_q_paused_flag[q]) +#define card_tx_q_unpause(card, q) (card->tx_q_paused_flag[q] = 0) +#define card_tx_q_pause(card, q) (card->tx_q_paused_flag[q] = 1) + + CsrUint16 tx_q_paused_flag[UNIFI_TRAFFIC_Q_MAX + 1 + UNIFI_NO_OF_TX_QS]; /* defensive more than big enough */ + + /* UDI callback for logging UniFi interactions */ + udi_func_t udi_hook; + + CsrUint8 bh_reason_host; + CsrUint8 bh_reason_unifi; + + /* SDIO clock speed request from OS layer */ + CsrUint8 request_max_clock; + + /* Last SDIO clock frequency set */ + CsrUint32 sdio_clock_speed; + + /* + * Current host state (copy of value in IOABORT register and + * spinlock to protect it. + */ + enum unifi_host_state host_state; + + enum unifi_low_power_mode low_power_mode; + enum unifi_periodic_wake_mode periodic_wake_mode; + + /* + * Ring buffer of signal structs for a queue of data packets from + * the host. + * The queue is empty when fh_data_q_num_rd == fh_data_q_num_wr. + * To add a packet to the queue, copy it to index given by + * (fh_data_q_num_wr%UNIFI_SOFT_Q_LENGTH) and advance fh_data_q_num_wr. + * To take a packet from the queue, copy data from index given by + * (fh_data_q_num_rd%UNIFI_SOFT_Q_LENGTH) and advance fh_data_q_num_rd. + * fh_data_q_num_rd and fh_data_q_num_rd are both modulo 256. + */ + card_signal_t fh_command_q_body[UNIFI_SOFT_COMMAND_Q_LENGTH]; + q_t fh_command_queue; + + card_signal_t fh_traffic_q_body[UNIFI_NO_OF_TX_QS][UNIFI_SOFT_TRAFFIC_Q_LENGTH]; + q_t fh_traffic_queue[UNIFI_NO_OF_TX_QS]; + + /* + * Signal counts from UniFi SDIO Control Data Structure. + * These are cached and synchronised with the UniFi before and after + * a batch of operations. + * + * These are the modulo-256 count of signals written to or read from UniFi + * The value is incremented for every signal. + */ + CsrInt32 from_host_signals_w; + CsrInt32 from_host_signals_r; + CsrInt32 to_host_signals_r; + CsrInt32 to_host_signals_w; + + + /* Should specify buffer size as a number of signals */ + /* + * Enough for 10 th and 10 fh data slots: + * 1 * 10 * 8 = 80 + * 2 * 10 * 8 = 160 + */ +#define UNIFI_FH_BUF_SIZE 1024 + struct sigbuf + { + CsrUint8 *buf; /* buffer area */ + CsrUint8 *ptr; /* current pos */ + CsrUint16 count; /* signal count */ + CsrUint16 bufsize; + } fh_buffer; + struct sigbuf th_buffer; + + + /* + * Field to use for the incrementing value to write to the UniFi + * SHARED_IO_INTERRUPT register. + * Flag to say we need to generate an interrupt at end of processing. + */ + CsrUint32 unifi_interrupt_seq; + CsrUint8 generate_interrupt; + + + /* Pointers to the bulk data slots */ + slot_desc_t *from_host_data; + bulk_data_desc_t *to_host_data; + + + /* + * Index of the next (hopefully) free data slot. + * This is an optimisation that starts searching at a more likely point + * than the beginning. + */ + CsrInt16 from_host_data_head; + + /* Dynamic slot allocation for queues */ + card_dynamic_slot_t dynamic_slot_data; + + /* + * SDIO specific fields + */ + + /* Interface pointer for the SDIO library */ + CsrSdioFunction *sdio_if; + + /* Copy of config_data struct from the card */ + sdio_config_data_t config_data; + + /* SDIO address of the Initialised flag and Control Data struct */ + CsrUint32 init_flag_addr; + CsrUint32 sdio_ctrl_addr; + + /* The last value written to the Shared Data Memory Page register */ + CsrUint32 proc_select; + CsrUint32 dmem_page; + CsrUint32 pmem_page; + + /* SDIO traffic counters limited to 32 bits for Synergy compatibility */ + CsrUint32 sdio_bytes_read; + CsrUint32 sdio_bytes_written; + + CsrUint8 memory_resources_allocated; + + /* UniFi SDIO I/O Block size. */ + CsrUint16 sdio_io_block_size; + + /* Pad transfer sizes to SDIO block boundaries */ + CsrBool sdio_io_block_pad; + + /* Read from the XBV */ + struct FWOV fwov; + +#ifndef CSR_WIFI_HIP_TA_DISABLE + /* TA sampling */ + ta_data_t ta_sampling; +#endif + + /* Auto-coredump */ + CsrInt16 request_coredump_on_reset; /* request coredump on next reset */ + struct coredump_buf *dump_buf; /* root node */ + struct coredump_buf *dump_next_write; /* node to fill at next dump */ + struct coredump_buf *dump_cur_read; /* valid node to read, or NULL */ + +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + struct cmd_profile + { + CsrUint32 cmd52_count; + CsrUint32 cmd53_count; + CsrUint32 tx_count; + CsrUint32 tx_cfm_count; + CsrUint32 rx_count; + CsrUint32 bh_count; + CsrUint32 process_count; + CsrUint32 protocol_count; + + CsrUint32 cmd52_f0_r_count; + CsrUint32 cmd52_f0_w_count; + CsrUint32 cmd52_r8or16_count; + CsrUint32 cmd52_w8or16_count; + CsrUint32 cmd52_r16_count; + CsrUint32 cmd52_w16_count; + CsrUint32 cmd52_r32_count; + + CsrUint32 sdio_cmd_signal; + CsrUint32 sdio_cmd_clear_slot; + CsrUint32 sdio_cmd_to_host; + CsrUint32 sdio_cmd_from_host; + CsrUint32 sdio_cmd_from_host_and_clear; + } hip_prof; + struct cmd_profile cmd_prof; +#endif + + /* Interrupt processing mode flags */ + CsrUint32 intmode; + +#ifdef UNIFI_DEBUG + CsrUint8 lsb; +#endif + + /* Historic firmware panic codes */ + CsrUint32 panic_data_phy_addr; + CsrUint32 panic_data_mac_addr; + CsrUint16 last_phy_panic_code; + CsrUint16 last_phy_panic_arg; + CsrUint16 last_mac_panic_code; + CsrUint16 last_mac_panic_arg; +#ifdef CSR_PRE_ALLOC_NET_DATA + bulk_data_desc_t bulk_data_desc_list[BULK_DATA_PRE_ALLOC_NUM]; + CsrUint16 prealloc_netdata_r; + CsrUint16 prealloc_netdata_w; +#endif +}; /* struct card */ + + +/* Reset types */ +enum unifi_reset_type +{ + UNIFI_COLD_RESET = 1, + UNIFI_WARM_RESET = 2 +}; + +/* + * unifi_set_host_state() implements signalling for waking UniFi from + * deep sleep. The host indicates to UniFi that it is in one of three states: + * Torpid - host has nothing to send, UniFi can go to sleep. + * Drowsy - host has data to send to UniFi. UniFi will respond with an + * SDIO interrupt. When hosts responds it moves to Awake. + * Awake - host has data to transfer, UniFi must stay awake. + * When host has finished, it moves to Torpid. + */ +CsrResult unifi_set_host_state(card_t *card, enum unifi_host_state state); + + +CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select); +CsrInt32 card_read_signal_counts(card_t *card); +bulk_data_desc_t* card_find_data_slot(card_t *card, CsrInt16 slot); + + +CsrResult unifi_read32(card_t *card, CsrUint32 unifi_addr, CsrUint32 *pdata); +CsrResult unifi_readnz(card_t *card, CsrUint32 unifi_addr, + void *pdata, CsrUint16 len); +CsrInt32 unifi_read_shared_count(card_t *card, CsrUint32 addr); + +CsrResult unifi_writen(card_t *card, CsrUint32 unifi_addr, void *pdata, CsrUint16 len); + +CsrResult unifi_bulk_rw(card_t *card, CsrUint32 handle, + void *pdata, CsrUint32 len, CsrInt16 direction); +CsrResult unifi_bulk_rw_noretry(card_t *card, CsrUint32 handle, + void *pdata, CsrUint32 len, CsrInt16 direction); +#define UNIFI_SDIO_READ 0 +#define UNIFI_SDIO_WRITE 1 + +CsrResult unifi_read_8_or_16(card_t *card, CsrUint32 unifi_addr, CsrUint8 *pdata); +CsrResult unifi_write_8_or_16(card_t *card, CsrUint32 unifi_addr, CsrUint8 data); +CsrResult unifi_read_direct_8_or_16(card_t *card, CsrUint32 addr, CsrUint8 *pdata); +CsrResult unifi_write_direct_8_or_16(card_t *card, CsrUint32 addr, CsrUint8 data); + +CsrResult unifi_read_direct16(card_t *card, CsrUint32 addr, CsrUint16 *pdata); +CsrResult unifi_read_direct32(card_t *card, CsrUint32 addr, CsrUint32 *pdata); +CsrResult unifi_read_directn(card_t *card, CsrUint32 addr, void *pdata, CsrUint16 len); + +CsrResult unifi_write_direct16(card_t *card, CsrUint32 addr, CsrUint16 data); +CsrResult unifi_write_directn(card_t *card, CsrUint32 addr, void *pdata, CsrUint16 len); + +CsrResult sdio_read_f0(card_t *card, CsrUint32 addr, CsrUint8 *pdata); +CsrResult sdio_write_f0(card_t *card, CsrUint32 addr, CsrUint8 data); + +void unifi_read_panic(card_t *card); +#ifdef CSR_PRE_ALLOC_NET_DATA +void prealloc_netdata_free(card_t *card); +CsrResult prealloc_netdata_alloc(card_t *card); +#endif +/* For diagnostic use */ +void dump(void *mem, CsrUint16 len); +void dump16(void *mem, CsrUint16 len); + +#ifdef __cplusplus +} +#endif + +#endif /* __CARD_SDIO_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c new file mode 100644 index 000000000000..3d563c13ff5a --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c @@ -0,0 +1,2561 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_card_sdio_intr.c + * + * PURPOSE: + * Interrupt processing for the UniFi SDIO driver. + * + * We may need another signal queue of responses to UniFi to hold + * bulk data commands generated by read_to_host_signals(). + * + * --------------------------------------------------------------------------- + */ +#undef CSR_WIFI_HIP_NOISY + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "csr_wifi_hip_card.h" +#include "csr_wifi_hip_xbv.h" + + +/* + * If the SDIO link is idle for this time (in milliseconds), + * signal UniFi to go into Deep Sleep. + * Valid return value of unifi_bh(). + */ +#define UNIFI_DEFAULT_HOST_IDLE_TIMEOUT 5 +/* + * If the UniFi has not woken up for this time (in milliseconds), + * signal the bottom half to take action. + * Valid return value of unifi_bh(). + */ +#define UNIFI_DEFAULT_WAKE_TIMEOUT 1000 + + +static CsrResult process_bh(card_t *card); +static CsrResult handle_host_protocol(card_t *card, CsrBool *processed_something); + +static CsrResult flush_fh_buffer(card_t *card); + +static CsrResult check_fh_sig_slots(card_t *card, CsrUint16 needed, CsrInt32 *space); + +static CsrResult read_to_host_signals(card_t *card, CsrInt32 *processed); +static CsrResult process_to_host_signals(card_t *card, CsrInt32 *processed); + +static CsrResult process_bulk_data_command(card_t *card, + const CsrUint8 *cmdptr, + CsrInt16 cmd, CsrUint16 len); +static CsrResult process_clear_slot_command(card_t *card, + const CsrUint8 *cmdptr); +static CsrResult process_fh_cmd_queue(card_t *card, CsrInt32 *processed); +static CsrResult process_fh_traffic_queue(card_t *card, CsrInt32 *processed); +static void restart_packet_flow(card_t *card); +static CsrResult process_clock_request(card_t *card); + +#ifdef CSR_WIFI_HIP_NOISY +CsrInt16 dump_fh_buf = 0; +#endif /* CSR_WIFI_HIP_NOISY */ + +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE + +/* + * The unifi_debug_output buffer can be used to debug the HIP behaviour offline + * i.e. without using the tracing functions that change the timing. + * + * Call unifi_debug_log_to_buf() with printf arguments to store a string into + * unifi_debug_output. When unifi_debug_buf_dump() is called, the contents of the + * buffer are dumped with dump_str() which has to be implemented in the + * OS layer, during the porting exercise. The offset printed, holds the + * offset where the last character is (always a zero). + * + */ + +#define UNIFI_DEBUG_GBUFFER_SIZE 8192 +static CsrCharString unifi_debug_output[UNIFI_DEBUG_GBUFFER_SIZE]; +static CsrCharString *unifi_dbgbuf_ptr = unifi_debug_output; +static CsrCharString *unifi_dbgbuf_start = unifi_debug_output; + +static void append_char(CsrCharString c) +{ + /* write char and advance pointer */ + *unifi_dbgbuf_ptr++ = c; + /* wrap pointer at end of buffer */ + if ((unifi_dbgbuf_ptr - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE) + { + unifi_dbgbuf_ptr = unifi_debug_output; + } +} /* append_char() */ + + +void unifi_debug_string_to_buf(const CsrCharString *str) +{ + const CsrCharString *p = str; + while (*p) + { + append_char(*p); + p++; + } + /* Update start-of-buffer pointer */ + unifi_dbgbuf_start = unifi_dbgbuf_ptr + 1; + if ((unifi_dbgbuf_start - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE) + { + unifi_dbgbuf_start = unifi_debug_output; + } +} + + +void unifi_debug_log_to_buf(const CsrCharString *fmt, ...) +{ +#define DEBUG_BUFFER_SIZE 80 + static CsrCharString s[DEBUG_BUFFER_SIZE]; + va_list args; + + va_start(args, fmt); + CsrVsnprintf(s, DEBUG_BUFFER_SIZE, fmt, args); + va_end(args); + + unifi_debug_string_to_buf(s); +} /* unifi_debug_log_to_buf() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_debug_hex_to_buf + * + * puts the contents of the passed buffer into the debug buffer as a hex string + * + * Arguments: + * buff buffer to print as hex + * length number of chars to print + * + * Returns: + * None. + * + * --------------------------------------------------------------------------- + */ +void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length) +{ + CsrCharString s[5]; + CsrUint16 i; + + for (i = 0; i < length; i++) + { + CsrUInt16ToHex(0xff & buff[i], s); + unifi_debug_string_to_buf(s); + } +} + + +void unifi_debug_buf_dump(void) +{ + CsrInt32 offset = unifi_dbgbuf_ptr - unifi_debug_output; + + unifi_error(NULL, "HIP debug buffer offset=%d\n", offset); + dump_str(unifi_debug_output + offset, UNIFI_DEBUG_GBUFFER_SIZE - offset); + dump_str(unifi_debug_output, offset); +} /* unifi_debug_buf_dump() */ + + +#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ + +#ifdef CSR_PRE_ALLOC_NET_DATA +#define NETDATA_PRE_ALLOC_BUF_SIZE 8000 + +void prealloc_netdata_free(card_t *card) +{ + unifi_warning(card->ospriv, "prealloc_netdata_free: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r); + + while (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length != 0) + { + unifi_warning(card->ospriv, "prealloc_netdata_free: r=%d\n", card->prealloc_netdata_r); + + unifi_net_data_free(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_r]); + card->prealloc_netdata_r++; + card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM; + } + card->prealloc_netdata_r = card->prealloc_netdata_w = 0; + + unifi_warning(card->ospriv, "prealloc_netdata_free: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r); +} + + +CsrResult prealloc_netdata_alloc(card_t *card) +{ + CsrResult r; + + unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r); + + while (card->bulk_data_desc_list[card->prealloc_netdata_w].data_length == 0) + { + r = unifi_net_data_malloc(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_w], NETDATA_PRE_ALLOC_BUF_SIZE); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "prealloc_netdata_alloc: Failed to allocate t-h bulk data\n"); + return CSR_RESULT_FAILURE; + } + card->prealloc_netdata_w++; + card->prealloc_netdata_w %= BULK_DATA_PRE_ALLOC_NUM; + } + unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r); + + return CSR_RESULT_SUCCESS; +} + + +static CsrResult prealloc_netdata_get(card_t *card, bulk_data_desc_t *bulk_data_slot, CsrUint32 size) +{ + CsrResult r; + + unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r); + + if (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0) + { + unifi_error(card->ospriv, "prealloc_netdata_get: data_length = 0\n"); + } + + if ((size > NETDATA_PRE_ALLOC_BUF_SIZE) || (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0)) + { + unifi_warning(card->ospriv, "prealloc_netdata_get: Calling net_data_malloc\n"); + + r = unifi_net_data_malloc(card->ospriv, bulk_data_slot, size); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "prealloc_netdata_get: Failed to allocate t-h bulk data\n"); + return CSR_RESULT_FAILURE; + } + return CSR_RESULT_SUCCESS; + } + + *bulk_data_slot = card->bulk_data_desc_list[card->prealloc_netdata_r]; + card->bulk_data_desc_list[card->prealloc_netdata_r].os_data_ptr = NULL; + card->bulk_data_desc_list[card->prealloc_netdata_r].os_net_buf_ptr = NULL; + card->bulk_data_desc_list[card->prealloc_netdata_r].net_buf_length = 0; + card->bulk_data_desc_list[card->prealloc_netdata_r].data_length = 0; + + card->prealloc_netdata_r++; + card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM; + + unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r); + + return CSR_RESULT_SUCCESS; +} + + +#endif + +/* + * --------------------------------------------------------------------------- + * unifi_sdio_interrupt_handler + * + * This function should be called by the OS-dependent code to handle + * an SDIO interrupt from the UniFi. + * + * Arguments: + * card Pointer to card context structure. + * + * Returns: + * None. + * + * Notes: This function may be called in DRS context. In this case, + * tracing with the unifi_trace(), etc, is not allowed. + * --------------------------------------------------------------------------- + */ +void unifi_sdio_interrupt_handler(card_t *card) +{ + /* + * Set the flag to say reason for waking was SDIO interrupt. + * Then ask the OS layer to run the unifi_bh to give attention to the UniFi. + */ + card->bh_reason_unifi = 1; + unifi_run_bh(card->ospriv); +} /* sdio_interrupt_handler() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_configure_low_power_mode + * + * This function should be called by the OS-dependent when + * the deep sleep signaling needs to be enabled or disabled. + * + * Arguments: + * card Pointer to card context structure. + * low_power_mode Disable/Enable the deep sleep signaling + * periodic_wake_mode UniFi wakes host periodically. + * + * Returns: + * CSR_RESULT_SUCCESS on success or a CSR error code. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_configure_low_power_mode(card_t *card, + enum unifi_low_power_mode low_power_mode, + enum unifi_periodic_wake_mode periodic_wake_mode) +{ + card->low_power_mode = low_power_mode; + card->periodic_wake_mode = periodic_wake_mode; + + unifi_trace(card->ospriv, UDBG1, + "unifi_configure_low_power_mode: new mode = %s, wake_host = %s\n", + (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled", + (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE"); + + unifi_run_bh(card->ospriv); + return CSR_RESULT_SUCCESS; +} /* unifi_configure_low_power_mode() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_force_low_power_mode + * + * This function should be called by the OS-dependent when + * UniFi needs to be set to the low power mode (e.g. on suspend) + * + * Arguments: + * card Pointer to card context structure. + * + * Returns: + * CSR_RESULT_SUCCESS on success or a CSR error code. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_force_low_power_mode(card_t *card) +{ + if (card->low_power_mode == UNIFI_LOW_POWER_DISABLED) + { + unifi_error(card->ospriv, "Attempt to set mode to TORPID when lower power mode is disabled\n"); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + return unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID); +} /* unifi_force_low_power_mode() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_bh + * + * This function should be called by the OS-dependent code when + * host and/or UniFi has requested an exchange of messages. + * + * Arguments: + * card Pointer to card context structure. + * + * Returns: + * CSR_RESULT_SUCCESS on success or a CSR error code. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_bh(card_t *card, CsrUint32 *remaining) +{ + CsrResult r; + CsrResult csrResult; + CsrBool pending; + CsrInt32 iostate, j; + const enum unifi_low_power_mode low_power_mode = card->low_power_mode; + CsrUint16 data_slots_used = 0; + + + /* Process request to raise the maximum SDIO clock */ + r = process_clock_request(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Error setting maximum SDIO clock\n"); + goto exit; + } + + /* + * Why was the BH thread woken? + * If it was an SDIO interrupt, UniFi is awake and we need to process it. + * If it was a host process queueing data, then we need to awaken UniFi. + * + * Priority of flags is top down. + * + * ----------------------------------------------------------+ + * \state| AWAKE | DROWSY | TORPID | + * flag\ | | | | + * ---------+--------------+----------------+----------------| + * | do the host | go to AWAKE and| go to AWAKE and| + * unifi | protocol | do the host | do the host | + * | | protocol | protocol | + * ---------+--------------+----------------+----------------| + * | do the host | | | + * host | protocol | do nothing | go to DROWSY | + * | | | | + * ---------+--------------+----------------+----------------| + * | | | should not | + * timeout | go to TORPID | error, unifi | occur | + * | | didn't wake up | do nothing | + * ----------------------------------------------------------+ + * + * Note that if we end up in the AWAKE state we always do the host protocol. + */ + + do + { + /* + * When the host state is set to DROWSY, then we can not disable the + * interrupts as UniFi can generate an interrupt even when the INT_ENABLE + * register has the interrupts disabled. This interrupt will be lost. + */ + if (card->host_state == UNIFI_HOST_STATE_DROWSY || card->host_state == UNIFI_HOST_STATE_TORPID) + { + CsrUint8 reason_unifi; + + /* + * An interrupt may occur while or after we cache the reason. + * This interrupt will cause the unifi_bh() to be scheduled again. + * Any interrupt that has happened before the register is read + * and is considered spurious has to acknowledged. + */ + reason_unifi = card->bh_reason_unifi; + + /* + * If an interrupt is received, check if it was a real one, + * set the host state to AWAKE and run the BH. + */ + r = CardPendingInt(card, &pending); + if (r != CSR_RESULT_SUCCESS) + { + goto exit; + } + + if (pending) + { + unifi_trace(card->ospriv, UDBG5, + "UNIFI_HOST_STATE_%s: Set state to AWAKE.\n", + (card->host_state == UNIFI_HOST_STATE_TORPID)?"TORPID" : "DROWSY"); + + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r == CSR_RESULT_SUCCESS) + { + (*remaining) = 0; + break; + } + } + else if (reason_unifi) + { + CsrSdioInterruptAcknowledge(card->sdio_if); + } + + /* + * If an chip is in TORPID, and the host wants to wake it up, + * set the host state to DROWSY and wait for the wake-up interrupt. + */ + if ((card->host_state == UNIFI_HOST_STATE_TORPID) && card->bh_reason_host) + { + r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY); + if (r == CSR_RESULT_SUCCESS) + { + /* + * set the timeout value to UNIFI_DEFAULT_WAKE_TIMEOUT + * to capture a wake error. + */ + card->bh_reason_host = 0; + (*remaining) = UNIFI_DEFAULT_WAKE_TIMEOUT; + return CSR_RESULT_SUCCESS; + } + + goto exit; + } + + /* + * If the chip is in DROWSY, and the timeout expires, + * we need to reset the chip. This should never occur. + * (If it does, check that the calling thread set "remaining" + * according to the time remaining when unifi_bh() was called). + */ + if ((card->host_state == UNIFI_HOST_STATE_DROWSY) && ((*remaining) == 0)) + { + unifi_error(card->ospriv, "UniFi did not wake up on time...\n"); + + /* + * Check if Function1 has gone away or + * if we missed an SDIO interrupt. + */ + r = unifi_check_io_status(card, &iostate); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + goto exit; + } + /* Need to reset and reboot */ + return CSR_RESULT_FAILURE; + } + } + else + { + if (card->bh_reason_unifi || card->bh_reason_host) + { + break; + } + + if (((*remaining) == 0) && (low_power_mode == UNIFI_LOW_POWER_ENABLED)) + { + r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID); + if (r == CSR_RESULT_SUCCESS) + { + (*remaining) = 0; + return CSR_RESULT_SUCCESS; + } + + goto exit; + } + } + + /* No need to run the host protocol */ + return CSR_RESULT_SUCCESS; + } while (0); + + + /* Disable the SDIO interrupts while doing SDIO ops */ + csrResult = CsrSdioInterruptDisable(card->sdio_if); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + r = CSR_WIFI_HIP_RESULT_NO_DEVICE; + goto exit; + } + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + unifi_error(card->ospriv, "Failed to disable SDIO interrupts. unifi_bh queues error.\n"); + goto exit; + } + + /* Now that the interrupts are disabled, ack the interrupt */ + CsrSdioInterruptAcknowledge(card->sdio_if); + + /* Run the HIP */ + r = process_bh(card); + if (r != CSR_RESULT_SUCCESS) + { + goto exit; + } + + /* + * If host is now idle, schedule a timer for the delay before we + * let UniFi go into deep sleep. + * If the timer goes off, we will move to TORPID state. + * If UniFi raises an interrupt in the meantime, we will cancel + * the timer and start a new one when we become idle. + */ + for (j = 0; j < UNIFI_NO_OF_TX_QS; j++) + { + data_slots_used += CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[j]); + } + + if ((low_power_mode == UNIFI_LOW_POWER_ENABLED) && (data_slots_used == 0)) + { +#ifndef CSR_WIFI_HIP_TA_DISABLE + if (card->ta_sampling.traffic_type != CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC) + { +#endif + /* return the UNIFI_DEFAULT_HOST_IDLE_TIMEOUT, so we can go to sleep. */ + unifi_trace(card->ospriv, UDBG5, + "Traffic is not periodic, set timer for TORPID.\n"); + (*remaining) = UNIFI_DEFAULT_HOST_IDLE_TIMEOUT; +#ifndef CSR_WIFI_HIP_TA_DISABLE + } + else + { + unifi_trace(card->ospriv, UDBG5, + "Traffic is periodic, set unifi to TORPID immediately.\n"); + if (CardAreAllFromHostDataSlotsEmpty(card) == 1) + { + r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID); + if (r != CSR_RESULT_SUCCESS) + { + goto exit; + } + } + } +#endif + } + + csrResult = CsrSdioInterruptEnable(card->sdio_if); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + r = CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + unifi_error(card->ospriv, "Failed to enable SDIO interrupt\n"); + } + +exit: + + unifi_trace(card->ospriv, UDBG4, "New state=%d\n", card->host_state); + + if (r != CSR_RESULT_SUCCESS) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_buf_dump(); +#endif + /* If an interrupt has been raised, ack it here */ + if (card->bh_reason_unifi) + { + CsrSdioInterruptAcknowledge(card->sdio_if); + } + + unifi_error(card->ospriv, + "unifi_bh: state=%d %c, clock=%dkHz, interrupt=%d host=%d, power_save=%s\n", + card->host_state, + (card->host_state == UNIFI_HOST_STATE_AWAKE)?'A' : (card->host_state == UNIFI_HOST_STATE_DROWSY)?'D' : 'T', + card->sdio_clock_speed / 1000, + card->bh_reason_unifi, card->bh_reason_host, + (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled"); + + /* Try to capture firmware panic codes */ + unifi_capture_panic(card); + + /* Ask for a mini-coredump when the driver has reset UniFi */ + unifi_coredump_request_at_next_reset(card, 1); + } + + return r; +} /* unifi_bh() */ + + +/* + * --------------------------------------------------------------------------- + * process_clock_request + * + * Handle request from the OS layer to increase the SDIO clock speed. + * The fast clock is limited until the firmware has indicated that it has + * completed initialisation to the OS layer. + * + * Arguments: + * card Pointer to card context structure. + * + * Returns: + * CSR_RESULT_SUCCESS on success or CSR error code. + * --------------------------------------------------------------------------- + */ +static CsrResult process_clock_request(card_t *card) +{ + CsrResult r = CSR_RESULT_SUCCESS; + CsrResult csrResult; + + if (!card->request_max_clock) + { + return CSR_RESULT_SUCCESS; /* No pending request */ + } + + /* + * The SDIO clock speed request from the OS layer is only acted upon if + * the UniFi is awake. If it was in any other state, the clock speed will + * transition through SAFE to MAX while the host wakes it up, and the + * final speed reached will be UNIFI_SDIO_CLOCK_MAX_HZ. + * This assumes that the SME never requests low power mode while the f/w + * initialisation takes place. + */ + if (card->host_state == UNIFI_HOST_STATE_AWAKE) + { + unifi_trace(card->ospriv, UDBG1, "Set SDIO max clock\n"); + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_MAX_HZ); + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + } + else + { + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ; /* log the new freq */ + } + } + else + { + unifi_trace(card->ospriv, UDBG1, "Will set SDIO max clock after wakeup\n"); + } + + /* Cancel the request now that it has been acted upon, or is about to be + * by the wakeup mechanism + */ + card->request_max_clock = 0; + + return r; +} + + +/* + * --------------------------------------------------------------------------- + * process_bh + * + * Exchange messages with UniFi + * + * Arguments: + * card Pointer to card context structure. + * + * Returns: + * CSR_RESULT_SUCCESS on success or CSR error code. + * --------------------------------------------------------------------------- + */ +static CsrResult process_bh(card_t *card) +{ + CsrResult r; + CsrBool more; + more = FALSE; + + /* Process the reasons (interrupt, signals) */ + do + { + /* + * Run in a while loop, to save clearing the interrupts + * every time around the outside loop. + */ + do + { + /* If configured to run the HIP just once, skip first loop */ + if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE) + { + break; + } + + r = handle_host_protocol(card, &more); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n", + card->cmd_prof.cmd52_count, + card->cmd_prof.cmd53_count, + card->cmd_prof.tx_count, + card->cmd_prof.tx_cfm_count, + card->cmd_prof.rx_count, + card->cmd_prof.sdio_cmd_signal, + card->cmd_prof.sdio_cmd_to_host, + card->cmd_prof.sdio_cmd_from_host_and_clear + ); + + card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0; + card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0; + + card->cmd_prof.cmd52_f0_r_count = 0; + card->cmd_prof.cmd52_f0_w_count = 0; + card->cmd_prof.cmd52_r8or16_count = 0; + card->cmd_prof.cmd52_w8or16_count = 0; + card->cmd_prof.cmd52_r16_count = 0; + card->cmd_prof.cmd52_w16_count = 0; + card->cmd_prof.cmd52_r32_count = 0; + + card->cmd_prof.sdio_cmd_signal = 0; + card->cmd_prof.sdio_cmd_clear_slot = 0; + card->cmd_prof.sdio_cmd_to_host = 0; + card->cmd_prof.sdio_cmd_from_host = 0; + card->cmd_prof.sdio_cmd_from_host_and_clear = 0; +#endif + + + } while (more || card->bh_reason_unifi || card->bh_reason_host); + + /* Acknowledge the h/w interrupt */ + r = CardClearInt(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to acknowledge interrupt.\n"); + return r; + } + + /* + * UniFi may have tried to generate an interrupt during the + * CardClearInt() was running. So, we need to run the host + * protocol again, to check if there are any pending requests. + */ + r = handle_host_protocol(card, &more); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n", + card->cmd_prof.cmd52_count, + card->cmd_prof.cmd53_count, + card->cmd_prof.tx_count, + card->cmd_prof.tx_cfm_count, + card->cmd_prof.rx_count, + card->cmd_prof.sdio_cmd_signal, + card->cmd_prof.sdio_cmd_to_host, + card->cmd_prof.sdio_cmd_from_host_and_clear + ); + + card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0; + card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0; + + card->cmd_prof.cmd52_f0_r_count = 0; + card->cmd_prof.cmd52_f0_w_count = 0; + card->cmd_prof.cmd52_r8or16_count = 0; + card->cmd_prof.cmd52_w8or16_count = 0; + card->cmd_prof.cmd52_r16_count = 0; + card->cmd_prof.cmd52_w16_count = 0; + card->cmd_prof.cmd52_r32_count = 0; + + card->cmd_prof.sdio_cmd_signal = 0; + card->cmd_prof.sdio_cmd_clear_slot = 0; + card->cmd_prof.sdio_cmd_to_host = 0; + card->cmd_prof.sdio_cmd_from_host = 0; + card->cmd_prof.sdio_cmd_from_host_and_clear = 0; +#endif + /* If configured to run the HIP just once, work is now done */ + if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE) + { + break; + } + + } while (more || card->bh_reason_unifi || card->bh_reason_host); + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + if ((card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE) == 0) + { + unifi_debug_log_to_buf("proc=%d\n", + card->cmd_prof.process_count); + } +#endif + + return CSR_RESULT_SUCCESS; +} /* process_bh() */ + + +/* + * --------------------------------------------------------------------------- + * handle_host_protocol + * + * This function implements the Host Interface Protocol (HIP) as + * described in the Host Interface Protocol Specification. + * + * Arguments: + * card Pointer to card context structure. + * processed_something Pointer to location to update processing status: + * TRUE when data was transferred + * FALSE when no data was transferred (queues empty) + * + * Returns: + * CSR_RESULT_SUCCESS on success or CSR error code. + * --------------------------------------------------------------------------- + */ +static CsrResult handle_host_protocol(card_t *card, CsrBool *processed_something) +{ + CsrResult r; + CsrInt32 done; + + *processed_something = FALSE; + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, " ======================== \n"); +#endif /* CSR_WIFI_HIP_NOISY */ + +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + card->cmd_prof.process_count++; +#endif + + card->bh_reason_unifi = card->bh_reason_host = 0; + card->generate_interrupt = 0; + + + /* + * (Re)fill the T-H signal buffer + */ + r = read_to_host_signals(card, &done); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Error occured reading to-host signals\n"); + return r; + } + if (done > 0) + { + *processed_something = TRUE; + } + + /* + * Process any to-host signals. + * Perform any requested CMD53 transfers here, but just queue any + * bulk data command responses. + */ + r = process_to_host_signals(card, &done); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Error occured processing to-host signals\n"); + return r; + } + + /* Now send any signals in the F-H queues */ + /* Give precedence to the command queue */ + r = process_fh_cmd_queue(card, &done); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Error occured processing from-host signals\n"); + return r; + } + if (done > 0) + { + *processed_something = TRUE; + } + + r = process_fh_traffic_queue(card, &done); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Error occured processing from-host data signals\n"); + return r; + } + if (done > 0) + { + *processed_something = TRUE; + } + + /* Flush out the batch of signals to the UniFi. */ + r = flush_fh_buffer(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to copy from-host signals to UniFi\n"); + return r; + } + + + /* + * Send the host interrupt to say the queues have been modified. + */ + if (card->generate_interrupt) + { + r = CardGenInt(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to notify UniFi that queues have been modified.\n"); + return r; + } + } +#ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ + unifi_rx_queue_flush(card->ospriv); +#endif + /* See if we can re-enable transmission now */ + restart_packet_flow(card); + +#ifdef CSR_PRE_ALLOC_NET_DATA + r = prealloc_netdata_alloc(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "prealloc_netdata failed\n"); + return r; + } +#endif + + /* + * Don't put the thread sleep if we just interacted with the chip, + * there might be more to do if we look again. + */ + return r; +} /* handle_host_protocol() */ + + +/* + * Rounds the given signal length in bytes to a whole number + * of sig_frag_size. + */ +#define GET_CHUNKS_FOR(SIG_FRAG_SIZE, LENGTH) (((LENGTH) + ((SIG_FRAG_SIZE)-1)) / (SIG_FRAG_SIZE)) + + +/* + * --------------------------------------------------------------------------- + * read_to_host_signals + * + * Read everything pending in the UniFi TH signal buffer. + * Only do it if the local buffer is empty. + * + * Arguments: + * card Pointer to card context struct + * processed Number of signals read: + * 0 if there were no signals pending, + * 1 if we read at least one signal + * Returns: + * CSR error code if an error occurred. + * --------------------------------------------------------------------------- + */ +static CsrResult read_to_host_signals(card_t *card, CsrInt32 *processed) +{ + CsrInt32 count_thw, count_thr; + CsrInt32 unread_chunks, unread_bytes; + CsrResult r; + + *processed = 0; + + /* Read any pending signals or bulk data commands */ + count_thw = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); + if (count_thw < 0) + { + unifi_error(card->ospriv, "Failed to read to-host sig written count\n"); + return CSR_RESULT_FAILURE; + } + card->to_host_signals_w = count_thw; /* diag */ + + count_thr = card->to_host_signals_r; + + if (count_thw == count_thr) + { + return CSR_RESULT_SUCCESS; + } + + unread_chunks = + (((count_thw - count_thr) + 128) % 128) - card->th_buffer.count; + + if (unread_chunks == 0) + { + return CSR_RESULT_SUCCESS; + } + + unread_bytes = card->config_data.sig_frag_size * unread_chunks; + + + r = unifi_bulk_rw(card, + card->config_data.tohost_sigbuf_handle, + card->th_buffer.ptr, + unread_bytes, + UNIFI_SDIO_READ); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read ToHost signal\n"); + return r; + } + + card->th_buffer.ptr += unread_bytes; + card->th_buffer.count += (CsrUint16)unread_chunks; + + *processed = 1; + + return CSR_RESULT_SUCCESS; +} /* read_to_host_signals() */ + + +/* + * --------------------------------------------------------------------------- + * update_to_host_signals_r + * + * Advance the shared-memory count of chunks read from the to-host + * signal buffer. + * Raise a UniFi internal interrupt to tell the firmware that the + * count has changed. + * + * Arguments: + * card Pointer to card context struct + * pending Number of chunks remaining + * + * Returns: + * CSR_RESULT_SUCCESS on success or CSR error code + * --------------------------------------------------------------------------- + */ +static CsrResult update_to_host_signals_r(card_t *card, CsrInt16 pending) +{ + CsrResult r; + + card->to_host_signals_r = + (card->to_host_signals_r + (card->th_buffer.count - pending)) % 128; + card->th_buffer.count = pending; + + /* Update the count of signals read */ + r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 6, + (CsrUint8)card->to_host_signals_r); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to update to-host signals read\n"); + return r; + } + + r = CardGenInt(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to notify UniFi that we processed to-host signals.\n"); + return r; + } + + card->generate_interrupt = 0; + + return CSR_RESULT_SUCCESS; +} /* update_to_host_signals_r() */ + + +/* + * --------------------------------------------------------------------------- + * read_unpack_cmd + * + * Converts a wire-formatted command to the host bulk_data_cmd_t structure. + * + * Arguments: + * ptr Pointer to the command + * bulk_data_cmd Pointer to the host structure + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void read_unpack_cmd(const CsrUint8 *ptr, bulk_data_cmd_t *bulk_data_cmd) +{ + CsrInt16 index = 0; + bulk_data_cmd->cmd_and_len = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + bulk_data_cmd->data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + bulk_data_cmd->offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + bulk_data_cmd->buffer_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; +} /* read_unpack_cmd */ + + +/* + * --------------------------------------------------------------------------- + * process_to_host_signals + * + * Read and dispatch signals from the UniFi + * + * Arguments: + * card Pointer to card context struct + * processed Pointer to location to write processing result: + * 0 if there were no signals pending, + * 1 if we read at least one signal + * + * Returns: + * CSR error code if there was an error + * + * Notes: + * Since bulk data transfers can take a long time, if we wait until + * all are done before we acknowledge the signals, the UniFi runs out + * of buffer space. Therefore we keep a count of the bytes transferred + * in bulk data commands, and update the to-host-signals-read count + * if we've done a large transfer. + * + * All data in the f/w is stored in a little endian format, without any + * padding bytes. Every read from the memory has to be transformed in + * host (cpu specific) format, before we can process it. Therefore we + * use read_unpack_cmd() and read_unpack_signal() to convert the raw data + * contained in the card->th_buffer.buf to host structures. + * Important: UDI clients use wire-formatted structures, so we need to + * indicate all data, as we have read it from the device. + * --------------------------------------------------------------------------- + */ +static CsrResult process_to_host_signals(card_t *card, CsrInt32 *processed) +{ + CsrInt16 pending; + CsrInt16 remaining; + CsrUint8 *bufptr; + bulk_data_param_t data_ptrs; + CsrInt16 cmd; + CsrUint16 sig_len; + CsrInt16 i; + CsrUint16 chunks_in_buf; + CsrUint16 bytes_transferred = 0; + CsrResult r = CSR_RESULT_SUCCESS; + + *processed = 0; + + pending = card->th_buffer.count; + + /* Are there new to-host signals? */ + unifi_trace(card->ospriv, UDBG4, "handling %d to-host chunks\n", pending); + + if (!pending) + { + return CSR_RESULT_SUCCESS; + } + + /* + * This is a pointer to the raw data we have read from the f/w. + * Can be a signal or a command. Note that we need to convert + * it to a host structure before we process it. + */ + bufptr = card->th_buffer.buf; + + while (pending > 0) + { + CsrInt16 f_flush_count = 0; + + /* + * Command and length are common to signal and bulk data msgs. + * If command == 0 (i.e. a signal), len is number of bytes + * *following* the 2-byte header. + */ + cmd = bufptr[1] >> 4; + sig_len = bufptr[0] + ((bufptr[1] & 0x0F) << 8); + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "Received UniFi msg cmd=%d, len=%d\n", + cmd, sig_len); +#endif /* CSR_WIFI_HIP_NOISY */ + + if ((sig_len == 0) && + ((cmd != SDIO_CMD_CLEAR_SLOT) && (cmd != SDIO_CMD_PADDING))) + { + unifi_error(card->ospriv, "incomplete signal or command: has size zero\n"); + return CSR_RESULT_FAILURE; + } + /* + * Make sure the buffer contains a complete message. + * Signals may occupy multiple chunks, bulk-data commands occupy + * one chunk. + */ + if (cmd == SDIO_CMD_SIGNAL) + { + chunks_in_buf = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (CsrUint16)(sig_len + 2)); + } + else + { + chunks_in_buf = 1; + } + + if (chunks_in_buf > (CsrUint16)pending) + { + unifi_error(card->ospriv, "incomplete signal (0x%x?): need %d chunks, got %d\n", + GET_SIGNAL_ID(bufptr + 2), + chunks_in_buf, pending); + unifi_error(card->ospriv, " thsw=%d, thsr=%d\n", + card->to_host_signals_w, + card->to_host_signals_r); + return CSR_RESULT_FAILURE; + } + + + switch (cmd) + { + case SDIO_CMD_SIGNAL: + /* This is a signal. Read the rest of it and then handle it. */ +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.sdio_cmd_signal++; +#endif + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) + { + /* Retrieve dataRefs[i].DataLength */ + CsrUint16 data_len = GET_PACKED_DATAREF_LEN(bufptr + 2, i); + + /* + * The bulk data length in the signal can not be greater than + * the maximun length allowed by the SDIO config structure. + */ + if (data_len > card->config_data.data_slot_size) + { + unifi_error(card->ospriv, + "Bulk Data length (%d) exceeds Maximum Bulk Data length (%d)\n", + data_len, card->config_data.data_slot_size); + return CSR_RESULT_FAILURE; + } + + /* + * Len here might not be the same as the length in the + * bulk data slot. The slot length will always be even, + * but len could be odd. + */ + if (data_len != 0) + { + /* Retrieve dataRefs[i].SlotNumber */ + CsrInt16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i); + + if (slot >= card->config_data.num_tohost_data_slots) + { + unifi_error(card->ospriv, "!!!bad slot number in to-host signal: %d, sig 0x%X\n", + slot, cmd); + return CSR_RESULT_FAILURE; + } + + data_ptrs.d[i].os_data_ptr = card->to_host_data[slot].os_data_ptr; + data_ptrs.d[i].os_net_buf_ptr = card->to_host_data[slot].os_net_buf_ptr; + data_ptrs.d[i].net_buf_length = card->to_host_data[slot].net_buf_length; + data_ptrs.d[i].data_length = data_len; + } + else + { + UNIFI_INIT_BULK_DATA(&data_ptrs.d[i]); + } + } + + /* + * Log the signal to the UDI, before call unifi_receive_event() as + * it can modify the bulk data. + */ + if (card->udi_hook) + { + (*card->udi_hook)(card->ospriv, bufptr + 2, sig_len, + &data_ptrs, UDI_LOG_TO_HOST); + } + +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID) + { + card->cmd_prof.tx_cfm_count++; + } + else if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_INDICATION_ID) + { + if (data_ptrs.d[0].os_data_ptr) + { + if ((*data_ptrs.d[0].os_data_ptr) & 0x08) + { + card->cmd_prof.rx_count++; + } + } + } +#endif + /* + * Check if the signal is MA-PACKET.cfm and if so check the status. + * If the status is failure, search through the slot records to find + * if any slots are occupied for this host tag. This can happen if + * f/w has not downloaded the bulkdata and before that itself it has + * signalled the confirm with failure. If it finds a slot with that + * host tag then, it clears the corresponding slot + */ + + if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID) + { + /* Get host tag and transmission status */ + CsrUint32 host_tag = GET_PACKED_MA_PACKET_CONFIRM_HOST_TAG(bufptr + 2); + CsrUint16 status = GET_PACKED_MA_PACKET_CONFIRM_TRANSMISSION_STATUS(bufptr + 2); + + unifi_trace(card->ospriv, UDBG4, "process_to_host_signals signal ID=%x host Tag=%x status=%x\n", + GET_SIGNAL_ID(bufptr + 2), host_tag, status); + + /* If transmission status is failure then search through the slot records + * and if for any slot records the clear slot is not done then do it now + */ + + if (status && (card->fh_slot_host_tag_record)) + { + CsrUint16 num_fh_slots = card->config_data.num_fromhost_data_slots; + CsrUint16 i = 0; + + /* search through the list of slot records and match with host tag + * If a slot is not yet cleared then clear the slot from here + */ + for (i = 0; i < num_fh_slots; i++) + { + if (card->fh_slot_host_tag_record[i] == host_tag) + { + unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag); + card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG; + + /* Set length field in from_host_data array to 0 */ + CardClearFromHostDataSlot(card, i); + + break; + } + } + } + } + + /* Pass event to OS layer */ + unifi_receive_event(card->ospriv, bufptr + 2, sig_len, &data_ptrs); + + /* Initialise the to_host data, so it can be re-used. */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) + { + /* The slot is only valid if the length is non-zero. */ + if (GET_PACKED_DATAREF_LEN(bufptr + 2, i) != 0) + { + CsrInt16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i); + if (slot < card->config_data.num_tohost_data_slots) + { + UNIFI_INIT_BULK_DATA(&card->to_host_data[slot]); + } + } + } + +#ifndef CSR_WIFI_DEFER_TH_FLUSH + /* + * If we have previously transferred a lot of data, ack + * the signals read so far, so f/w can reclaim the buffer + * memory sooner. + */ + if (bytes_transferred >= TO_HOST_FLUSH_THRESHOLD) + { + f_flush_count = 1; + } +#endif + break; + + + case SDIO_CMD_CLEAR_SLOT: +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.sdio_cmd_clear_slot++; +#endif + /* This is a clear slot command. */ + if (sig_len != 0) + { + unifi_error(card->ospriv, "process_to_host_signals: clear slot, bad data len: 0x%X at offset %d\n", + sig_len, bufptr - card->th_buffer.buf); + return CSR_RESULT_FAILURE; + } + + r = process_clear_slot_command(card, bufptr); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to process clear slot\n"); + return r; + } + break; + + case SDIO_CMD_TO_HOST_TRANSFER: + case SDIO_CMD_FROM_HOST_TRANSFER: + case SDIO_CMD_FROM_HOST_AND_CLEAR: + case SDIO_CMD_OVERLAY_TRANSFER: + /* This is a bulk data command. */ + if (sig_len & 1) + { + unifi_error(card->ospriv, "process_to_host_signals: bulk data, bad data len: 0x%X at offset %d\n", + sig_len, bufptr - card->th_buffer.buf); + return CSR_RESULT_FAILURE; + } + + r = process_bulk_data_command(card, bufptr, cmd, sig_len); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to process bulk cmd\n"); + return r; + } + /* Count the bytes transferred */ + bytes_transferred += sig_len; + + if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.sdio_cmd_from_host_and_clear++; +#endif +#ifndef CSR_WIFI_DEFER_TH_FLUSH + f_flush_count = 1; +#endif + } +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + else if (cmd == SDIO_CMD_FROM_HOST_TRANSFER) + { + card->cmd_prof.sdio_cmd_from_host++; + } + else if (cmd == SDIO_CMD_TO_HOST_TRANSFER) + { + card->cmd_prof.sdio_cmd_to_host++; + } +#endif + break; + + case SDIO_CMD_PADDING: + break; + + default: + unifi_error(card->ospriv, "Unrecognised to-host command: %d\n", cmd); + break; + } + + bufptr += chunks_in_buf * card->config_data.sig_frag_size; + pending -= chunks_in_buf; + + /* + * Write out the host signal count when a significant + * number of bytes of bulk data have been transferred or + * when we have performed a CopyFromHostAndClear. + */ + if (f_flush_count) + { + r = update_to_host_signals_r(card, pending); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + bytes_transferred = 0; + } + } + + if (pending) + { + unifi_warning(card->ospriv, "proc_th_sigs: %d unprocessed\n", pending); + } + + /* If we processed any signals, write the updated count to UniFi */ + if (card->th_buffer.count != pending) + { + r = update_to_host_signals_r(card, pending); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + } + + /* + * Reset the buffer pointer, copying down any un-processed signals. + * This can happen if we enable the optimisation in read_to_host_signals() + * that limits the length to whole blocks. + */ + remaining = card->th_buffer.ptr - bufptr; + if (remaining < 0) + { + unifi_error(card->ospriv, "Processing TH signals overran the buffer\n"); + return CSR_RESULT_FAILURE; + } + if (remaining > 0) + { + /* Use a safe copy because source and destination may overlap */ + CsrUint8 *d = card->th_buffer.buf; + CsrUint8 *s = bufptr; + CsrInt32 n = remaining; + while (n--) + { + *d++ = *s++; + } + } + card->th_buffer.ptr = card->th_buffer.buf + remaining; + + + /* If we reach here then we processed something */ + *processed = 1; + return CSR_RESULT_SUCCESS; +} /* process_to_host_signals() */ + + +/* + * --------------------------------------------------------------------------- + * process_clear_slot_command + * + * Process a clear slot command fom the UniFi. + * + * Arguments: + * card Pointer to card context struct + * bdcmd Pointer to bulk-data command msg from UniFi + * + * Returns: + * 0 on success, CSR error code on error + * --------------------------------------------------------------------------- + */ +static CsrResult process_clear_slot_command(card_t *card, const CsrUint8 *cmdptr) +{ + CsrUint16 data_slot; + CsrInt16 slot; + + data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cmdptr + SIZEOF_UINT16); + + unifi_trace(card->ospriv, UDBG4, "Processing clear slot cmd, slot=0x%X\n", + data_slot); + + slot = data_slot & 0x7FFF; + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "CMD clear data slot 0x%04x\n", data_slot); +#endif /* CSR_WIFI_HIP_NOISY */ + + if (data_slot & SLOT_DIR_TO_HOST) + { + if (slot >= card->config_data.num_tohost_data_slots) + { + unifi_error(card->ospriv, + "Invalid to-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n", + slot); + return CSR_RESULT_FAILURE; + } + /* clear to-host data slot */ + unifi_warning(card->ospriv, "Unexpected clear to-host data slot cmd: 0x%04x\n", + data_slot); + } + else + { + if (slot >= card->config_data.num_fromhost_data_slots) + { + unifi_error(card->ospriv, + "Invalid from-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n", + slot); + return CSR_RESULT_FAILURE; + } + + /* + * The driver is the owner to clear all slots now + * Ref - comment in process_fh_traffic_queue + * so it will just ignore the clear slot command from firmware + * and return success + */ + return CSR_RESULT_SUCCESS; + + /* Set length field in from_host_data array to 0 */ + /* CardClearFromHostDataSlot(card, slot); */ + } + + return CSR_RESULT_SUCCESS; +} /* process_clear_slot_command() */ + + +/* + * --------------------------------------------------------------------------- + * process_bulk_data_command + * + * Process a bulk data request from the UniFi. + * + * Arguments: + * card Pointer to card context struct + * bdcmd Pointer to bulk-data command msg from UniFi + * cmd, len Decoded values of command and length from the msg header + * Cmd will only be one of: + * SDIO_CMD_TO_HOST_TRANSFER + * SDIO_CMD_FROM_HOST_TRANSFER + * SDIO_CMD_FROM_HOST_AND_CLEAR + * SDIO_CMD_OVERLAY_TRANSFER + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on error + * --------------------------------------------------------------------------- + */ +static CsrResult process_bulk_data_command(card_t *card, const CsrUint8 *cmdptr, + CsrInt16 cmd, CsrUint16 len) +{ + bulk_data_desc_t *bdslot; +#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND + CsrUint8 *host_bulk_data_slot; +#endif + bulk_data_cmd_t bdcmd; + CsrInt16 offset; + CsrInt16 slot; + CsrInt16 dir; + CsrResult r; + + read_unpack_cmd(cmdptr, &bdcmd); + + unifi_trace(card->ospriv, UDBG4, "Processing bulk data cmd %d %s, len=%d, slot=0x%X\n", + cmd, lookup_bulkcmd_name(cmd), len, bdcmd.data_slot); + + /* + * Round up the transfer length if required. + * This is useful to force all transfers to be a multiple of the SDIO block + * size, so the SDIO driver won't try to use a byte-mode CMD53. These are + * broken on some hardware platforms. + */ + if (card->sdio_io_block_pad) + { + len = (len + card->sdio_io_block_size - 1) & ~(card->sdio_io_block_size - 1); + unifi_trace(card->ospriv, UDBG4, "Rounded bulk data length up to %d\n", len); + } + + slot = bdcmd.data_slot & 0x7FFF; + + if (cmd == SDIO_CMD_OVERLAY_TRANSFER) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; /* Not used on CSR6xxx */ + } + else + { + if (bdcmd.data_slot & SLOT_DIR_TO_HOST) + { + /* Request is for to-host bulk data */ + + /* Check sanity of slot number */ + if (slot >= card->config_data.num_tohost_data_slots) + { + unifi_error(card->ospriv, + "Invalid to-host data slot in SDIO bulk xfr req: %d\n", + slot); + return CSR_RESULT_FAILURE; + } + + /* Allocate memory for card->to_host_data[slot] bulk data here. */ +#ifdef CSR_PRE_ALLOC_NET_DATA + r = prealloc_netdata_get(card, &card->to_host_data[slot], len); +#else + r = unifi_net_data_malloc(card->ospriv, &card->to_host_data[slot], len); +#endif + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to allocate t-h bulk data\n"); + return CSR_RESULT_FAILURE; + } + + bdslot = &card->to_host_data[slot]; + + /* Make sure that the buffer is 4-bytes aligned */ + r = unifi_net_dma_align(card->ospriv, bdslot); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to align t-h bulk data buffer for DMA\n"); + return CSR_RESULT_FAILURE; + } + } + else + { + /* Request is for from-host bulk data */ + + if (slot >= card->config_data.num_fromhost_data_slots) + { + unifi_error(card->ospriv, + "Invalid from-host data slot in SDIO bulk xfr req: %d\n", + slot); + return CSR_RESULT_FAILURE; + } + bdslot = &card->from_host_data[slot].bd; + } + offset = bdcmd.offset; + } + /* Do the transfer */ + dir = (cmd == SDIO_CMD_TO_HOST_TRANSFER)? + UNIFI_SDIO_READ : UNIFI_SDIO_WRITE; + + unifi_trace(card->ospriv, UDBG4, + "Bulk %c %s len=%d, handle %d - slot=%d %p+(%d)\n", + (dir == UNIFI_SDIO_READ)?'R' : 'W', + lookup_bulkcmd_name(cmd), + len, + bdcmd.buffer_handle, + slot, bdslot->os_data_ptr, offset); +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "Bulk %s len=%d, handle %d - slot=%d %p+(%d)\n", + lookup_bulkcmd_name(cmd), + len, + bdcmd.buffer_handle, + slot, bdslot->os_data_ptr, offset); +#endif /* CSR_WIFI_HIP_NOISY */ + + + if (bdslot->os_data_ptr == NULL) + { + unifi_error(card->ospriv, "Null os_data_ptr - Bulk %s handle %d - slot=%d o=(%d)\n", + lookup_bulkcmd_name(cmd), + bdcmd.buffer_handle, + slot, + offset); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + +#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND + /* if os_data_ptr is not 4-byte aligned, then allocate a new buffer and copy data + to new buffer to ensure the address passed to unifi_bulk_rw is 4-byte aligned */ + + if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3)) + { + host_bulk_data_slot = CsrMemAlloc(len); + + if (!host_bulk_data_slot) + { + unifi_error(card->ospriv, " failed to allocate request_data before unifi_bulk_rw\n"); + return -1; + } + + CsrMemCpy((void *)host_bulk_data_slot, + (void *)(bdslot->os_data_ptr + offset), len); + + r = unifi_bulk_rw(card, + bdcmd.buffer_handle, + (void *)host_bulk_data_slot, + len, + dir); + } + else +#endif + { + r = unifi_bulk_rw(card, + bdcmd.buffer_handle, + (void *)(bdslot->os_data_ptr + offset), + len, + dir); + } + + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, + "Failed: %s hlen=%d, slen=%d, handle %d - slot=%d %p+0x%X\n", + lookup_bulkcmd_name(cmd), + len, /* Header length */ + bdslot->data_length, /* Length stored in slot */ + bdcmd.buffer_handle, + slot, bdslot->os_data_ptr, offset); + return r; + } + + bdslot->data_length = len; + + if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR) + { + if (slot >= card->config_data.num_fromhost_data_slots) + { + unifi_error(card->ospriv, + "Invalid from-host data slot in SDIO_CMD_FROM_HOST_AND_CLEAR: %d\n", + slot); + return CSR_RESULT_FAILURE; + } + +#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND + /* moving this check before we clear host data slot */ + if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3)) + { + CsrMemFree(host_bulk_data_slot); + } +#endif + + if (card->fh_slot_host_tag_record) + { + unifi_trace(card->ospriv, UDBG5, "CopyFromHostAndClearSlot Reset entry for slot=%d\n", slot); + + /* reset the host tag entry for the corresponding slot */ + card->fh_slot_host_tag_record[slot] = CSR_WIFI_HIP_RESERVED_HOST_TAG; + } + + + /* Set length field in from_host_data array to 0 */ + CardClearFromHostDataSlot(card, slot); + } + + return CSR_RESULT_SUCCESS; +} /* process_bulk_data_command() */ + + +/* + * --------------------------------------------------------------------------- + * check_fh_sig_slots + * + * Check whether there are free signal slots available on UniFi. + * This takes into account the signals already batched since the + * from_host_signal counts were last read. + * If the from_host_signal counts indicate not enough space, we read + * the latest count from UniFi to see if some more have been freed. + * + * Arguments: + * None. + * + * Returns: + * CSR_RESULT_SUCCESS, otherwise CSR error code on error. + * --------------------------------------------------------------------------- + */ +static CsrResult check_fh_sig_slots(card_t *card, CsrUint16 needed, CsrInt32 *space_fh) +{ + CsrUint32 count_fhw; + CsrUint32 occupied_fh, slots_fh; + CsrInt32 count_fhr; + + count_fhw = card->from_host_signals_w; + count_fhr = card->from_host_signals_r; + slots_fh = card->config_data.num_fromhost_sig_frags; + + /* Only read the space in from-host queue if necessary */ + occupied_fh = (count_fhw - count_fhr) % 128; + + if (slots_fh < occupied_fh) + { + *space_fh = 0; + } + else + { + *space_fh = slots_fh - occupied_fh; + } + + if ((occupied_fh != 0) && (*space_fh < needed)) + { + count_fhr = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2); + if (count_fhr < 0) + { + unifi_error(card->ospriv, "Failed to read from-host sig read count\n"); + return CSR_RESULT_FAILURE; + } + card->from_host_signals_r = count_fhr; /* diag */ + + occupied_fh = (count_fhw - count_fhr) % 128; + *space_fh = slots_fh - occupied_fh; + } + + return CSR_RESULT_SUCCESS; +} /* check_fh_sig_slots() */ + + +/* +* If we are padding the From-Host signals to the SDIO block size, +* we need to round up the needed_chunks to the SDIO block size. +*/ +#define ROUND_UP_NEEDED_CHUNKS(_card, _needed_chunks) \ + { \ + CsrUint16 _chunks_per_block; \ + CsrUint16 _chunks_in_last_block; \ + \ + if (_card->sdio_io_block_pad) \ + { \ + _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \ + _chunks_in_last_block = _needed_chunks % _chunks_per_block; \ + if (_chunks_in_last_block != 0) \ + { \ + _needed_chunks = _needed_chunks + (_chunks_per_block - _chunks_in_last_block); \ + } \ + } \ + } + + +#define ROUND_UP_SPACE_CHUNKS(_card, _space_chunks) \ + { \ + CsrUint16 _chunks_per_block; \ + \ + if (_card->sdio_io_block_pad) \ + { \ + _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \ + _space_chunks = ((_space_chunks / _chunks_per_block) * _chunks_per_block); \ + } \ + } + + + + + +/* + * --------------------------------------------------------------------------- + * process_fh_cmd_queue + * + * Take one signal off the from-host queue and copy it to the UniFi. + * Does nothing if the UniFi has no slots free. + * + * Arguments: + * card Pointer to card context struct + * processed Location to write: + * 0 if there is nothing on the queue to process + * 1 if a signal was successfully processed + * + * Returns: + * CSR error code if an error occurred. + * + * Notes: + * The from-host queue contains signal requests from the network driver + * and any UDI clients interspersed. UDI clients' requests have been stored + * in the from-host queue using the wire-format structures, as they arrive. + * All other requests are stored in the from-host queue using the host + * (cpu specific) structures. We use the is_packed member of the card_signal_t + * structure that describes the queue to make the distiction. + * --------------------------------------------------------------------------- + */ +static CsrResult process_fh_cmd_queue(card_t *card, CsrInt32 *processed) +{ + q_t *sigq = &card->fh_command_queue; + + CsrResult r; + CsrUint16 pending_sigs; + CsrUint16 pending_chunks; + CsrUint16 needed_chunks; + CsrInt32 space_chunks; + CsrUint16 q_index; + + *processed = 0; + + /* Get the number of pending signals. */ + pending_sigs = CSR_WIFI_HIP_Q_SLOTS_USED(sigq); + unifi_trace(card->ospriv, UDBG5, "proc_fh: %d pending\n", pending_sigs); + if (pending_sigs == 0) + { + /* Nothing to do */ + return CSR_RESULT_SUCCESS; + } + + /* Work out how many chunks we have waiting to send */ + for (pending_chunks = 0, q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq); + q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(sigq); + q_index = CSR_WIFI_HIP_Q_WRAP(sigq, q_index + 1)) + { + card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index); + + /* + * Note that GET_CHUNKS_FOR() needs the size of the packed + * (wire-formatted) structure + */ + pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (CsrUint16)(csptr->signal_length + 2)); + } + + /* + * Check whether UniFi has space for all the buffered bulk-data + * commands and signals as well. + */ + needed_chunks = pending_chunks + card->fh_buffer.count; + + /* Round up to the block size if necessary */ + ROUND_UP_NEEDED_CHUNKS(card, needed_chunks); + + r = check_fh_sig_slots(card, needed_chunks, &space_chunks); + if (r != CSR_RESULT_SUCCESS) + { + /* Error */ + unifi_error(card->ospriv, "Failed to read fh sig count\n"); + return r; + } + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "proc_fh: %d chunks free, need %d\n", + space_chunks, needed_chunks); +#endif /* CSR_WIFI_HIP_NOISY */ + + + /* + * Coalesce as many from-host signals as possible + * into a single block and write using a single CMD53 + */ + if (needed_chunks > (CsrUint16)space_chunks) + { + /* Round up to the block size if necessary */ + ROUND_UP_SPACE_CHUNKS(card, space_chunks); + + /* + * If the f/w has less free chunks than those already pending + * return immediately. + */ + if ((CsrUint16)space_chunks <= card->fh_buffer.count) + { + /* + * No room in UniFi for any signals after the buffered bulk + * data commands have been sent. + */ + unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n", + card->fh_buffer.count, space_chunks); + card->generate_interrupt = 1; + return CSR_RESULT_SUCCESS; + } + pending_chunks = (CsrUint16)(space_chunks - card->fh_buffer.count); + } + + while (pending_sigs-- && pending_chunks > 0) + { + card_signal_t *csptr; + CsrInt16 i; + CsrUint16 sig_chunks, total_length, free_chunks_in_fh_buffer; + bulk_data_param_t bulkdata; + CsrUint8 *packed_sigptr; + CsrUint16 signal_length = 0; + + /* Retrieve the entry at the head of the queue */ + q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq); + + /* Get a pointer to the containing card_signal_t struct */ + csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index); + + /* Get the new length of the packed signal */ + signal_length = csptr->signal_length; + + if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE)) + { + unifi_error(card->ospriv, "process_fh_queue: Bad len: %d\n", signal_length); + return CSR_RESULT_FAILURE; + } + + /* Need space for 2-byte SDIO protocol header + signal */ + sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (CsrUint16)(signal_length + 2)); + + free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size, + (CsrUint16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr)); + if (free_chunks_in_fh_buffer < sig_chunks) + { + /* No more room */ + unifi_notice(card->ospriv, "proc_fh_cmd_q: no room in fh buffer for 0x%.4X, deferring\n", + (CsrUint16)(GET_SIGNAL_ID(csptr->sigbuf))); + break; + } + + packed_sigptr = csptr->sigbuf; + + /* Claim and set up a from-host data slot */ + if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, UNIFI_TRAFFIC_Q_MLME)) + { + unifi_notice(card->ospriv, "proc_fh_cmd_q: no fh data slots for 0x%.4X, deferring\n", + (CsrUint16)(GET_SIGNAL_ID(csptr->sigbuf))); + break; + } + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) + { + if (csptr->bulkdata[i].data_length == 0) + { + UNIFI_INIT_BULK_DATA(&bulkdata.d[i]); + } + else + { + bulkdata.d[i].os_data_ptr = csptr->bulkdata[i].os_data_ptr; + bulkdata.d[i].data_length = csptr->bulkdata[i].data_length; + } + + /* Pass the free responsibility to the lower layer. */ + UNIFI_INIT_BULK_DATA(&csptr->bulkdata[i]); + } + + unifi_trace(card->ospriv, UDBG2, "Sending signal 0x%.4X\n", + GET_SIGNAL_ID(packed_sigptr)); +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "Sending signal 0x%.4X\n", + GET_SIGNAL_ID(packed_sigptr)); +#endif /* CSR_WIFI_HIP_NOISY */ + + + /* Append packed signal to F-H buffer */ + total_length = sig_chunks * card->config_data.sig_frag_size; + + card->fh_buffer.ptr[0] = (CsrUint8)(signal_length & 0xff); + card->fh_buffer.ptr[1] = + (CsrUint8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4)); + + CsrMemCpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length); + CsrMemSet(card->fh_buffer.ptr + 2 + signal_length, 0, + total_length - (2 + signal_length)); + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n", + signal_length + 2); + dump(card->fh_buffer.ptr, signal_length + 2); + unifi_trace(card->ospriv, UDBG1, " \n"); +#endif /* CSR_WIFI_HIP_NOISY */ + + card->fh_buffer.ptr += total_length; + card->fh_buffer.count += sig_chunks; + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n", + signal_length, + card->fh_buffer.ptr - card->fh_buffer.buf, + card->fh_buffer.count); +#endif /* CSR_WIFI_HIP_NOISY */ + + (*processed)++; + pending_chunks -= sig_chunks; + + /* Log the signal to the UDI. */ + /* UDI will get the packed structure */ + /* Can not log the unpacked signal, unless we reconstruct it! */ + if (card->udi_hook) + { + (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length, + &bulkdata, UDI_LOG_FROM_HOST); + } + + /* Remove entry from q */ + csptr->signal_length = 0; + CSR_WIFI_HIP_Q_INC_R(sigq); + } + + return CSR_RESULT_SUCCESS; +} /* process_fh_cmd_queue() */ + + +/* + * --------------------------------------------------------------------------- + * process_fh_traffic_queue + * + * Take signals off the from-host queue and copy them to the UniFi. + * Does nothing if the UniFi has no slots free. + * + * Arguments: + * card Pointer to card context struct + * sigq Pointer to the traffic queue + * processed Pointer to location to write: + * 0 if there is nothing on the queue to process + * 1 if a signal was successfully processed + * + * Returns: + * CSR error code if an error occurred. + * + * Notes: + * The from-host queue contains signal requests from the network driver + * and any UDI clients interspersed. + * --------------------------------------------------------------------------- + */ +static CsrResult process_fh_traffic_queue(card_t *card, CsrInt32 *processed) +{ + q_t *sigq = card->fh_traffic_queue; + + CsrResult r; + CsrInt16 n = 0; + CsrInt32 q_no; + CsrUint16 pending_sigs = 0; + CsrUint16 pending_chunks = 0; + CsrUint16 needed_chunks; + CsrInt32 space_chunks; + CsrUint16 q_index; + CsrUint32 host_tag = 0; + CsrUint16 slot_num = 0; + + *processed = 0; + + /* calculate how many signals are in queues and how many chunks are needed. */ + for (n = UNIFI_NO_OF_TX_QS - 1; n >= 0; n--) + { + /* Get the number of pending signals. */ + pending_sigs += CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[n]); + unifi_trace(card->ospriv, UDBG5, "proc_fh%d: %d pending\n", n, pending_sigs); + + /* Work out how many chunks we have waiting to send */ + for (q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[n]); + q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(&sigq[n]); + q_index = CSR_WIFI_HIP_Q_WRAP(&sigq[n], q_index + 1)) + { + card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[n], q_index); + + /* + * Note that GET_CHUNKS_FOR() needs the size of the packed + * (wire-formatted) structure + */ + pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (CsrUint16)(csptr->signal_length + 2)); + } + } + + /* If there are no pending signals, just return */ + if (pending_sigs == 0) + { + /* Nothing to do */ + return CSR_RESULT_SUCCESS; + } + + /* + * Check whether UniFi has space for all the buffered bulk-data + * commands and signals as well. + */ + needed_chunks = pending_chunks + card->fh_buffer.count; + + /* Round up to the block size if necessary */ + ROUND_UP_NEEDED_CHUNKS(card, needed_chunks); + + r = check_fh_sig_slots(card, needed_chunks, &space_chunks); + if (r != CSR_RESULT_SUCCESS) + { + /* Error */ + unifi_error(card->ospriv, "Failed to read fh sig count\n"); + return r; + } + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, + "process_fh_traffic_queue: %d chunks free, need %d\n", + space_chunks, needed_chunks); + read_fhsr(card); /* debugging only */ +#endif /* CSR_WIFI_HIP_NOISY */ + + /* Coalesce as many from-host signals as possible + into a single block and write using a single CMD53 */ + if (needed_chunks > (CsrUint16)space_chunks) + { + /* Round up to the block size if necessary */ + ROUND_UP_SPACE_CHUNKS(card, space_chunks); + + if ((CsrUint16)space_chunks <= card->fh_buffer.count) + { + /* + * No room in UniFi for any signals after the buffered bulk + * data commands have been sent. + */ + unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n", + card->fh_buffer.count, space_chunks); + card->generate_interrupt = 1; + return 0; + } + + pending_chunks = (CsrUint16)space_chunks - card->fh_buffer.count; + } + + q_no = UNIFI_NO_OF_TX_QS - 1; + + /* + * pending_sigs will be exhausted if there are is no restriction to the pending + * signals per queue. pending_chunks may be exhausted if there is a restriction. + * q_no check will be exhausted if there is a restriction and our round-robin + * algorith fails to fill all chunks. + */ + do + { + card_signal_t *csptr; + CsrUint16 sig_chunks, total_length, free_chunks_in_fh_buffer; + bulk_data_param_t bulkdata; + CsrUint8 *packed_sigptr; + CsrUint16 signal_length = 0; + + /* if this queue is empty go to next one. */ + if (CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[q_no]) == 0) + { + q_no--; + continue; + } + + /* Retrieve the entry at the head of the queue */ + q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[q_no]); + + /* Get a pointer to the containing card_signal_t struct */ + csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[q_no], q_index); + + /* Get the new length of the packed signal */ + signal_length = csptr->signal_length; + + if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE)) + { + unifi_error(card->ospriv, "process_fh_traffic_queue: Bad len: %d\n", signal_length); + return CSR_RESULT_FAILURE; + } + + /* Need space for 2-byte SDIO protocol header + signal */ + sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (CsrUint16)(signal_length + 2)); + free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size, + (CsrUint16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr)); + if (free_chunks_in_fh_buffer < sig_chunks) + { + /* No more room */ + unifi_notice(card->ospriv, "process_fh_traffic_queue: no more chunks.\n"); + break; + } + + packed_sigptr = csptr->sigbuf; + /* Claim and set up a from-host data slot */ + if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, (unifi_TrafficQueue)q_no)) + { + q_no--; + continue; + } + + /* Sanity check: MA-PACKET.req must have a valid bulk data */ + if ((csptr->bulkdata[0].data_length == 0) || (csptr->bulkdata[0].os_data_ptr == NULL)) + { + unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n", + csptr->bulkdata[0].data_length, csptr->bulkdata[0].os_data_ptr); + dump(packed_sigptr, signal_length); + return CSR_RESULT_FAILURE; + } + + bulkdata.d[0].os_data_ptr = csptr->bulkdata[0].os_data_ptr; + bulkdata.d[0].data_length = csptr->bulkdata[0].data_length; + bulkdata.d[0].os_net_buf_ptr = csptr->bulkdata[0].os_net_buf_ptr; + bulkdata.d[0].net_buf_length = csptr->bulkdata[0].net_buf_length; + + /* The driver owns clearing of HIP slots for following scenario + * - driver has requested a MA-PACKET.req signal + * - The f/w after receiving the signal decides it can't send it out due to various reasons + * - So the f/w without downloading the bulk data decides to just send a confirmation with fail + * - and then sends a clear slot signal to HIP + * + * But in some cases the clear slot signal never comes and the slot remains --NOT-- freed for ever + * + * To handle this, HIP will keep the record of host tag for each occupied slot + * and then based on status of that Host tag and slot the driver will decide if the slot is + * cleared by f/w signal or the slot has to be freed by driver + */ + + if (card->fh_slot_host_tag_record) + { + /* Update the f-h slot record for the corresponding host tag */ + host_tag = GET_PACKED_MA_PACKET_REQUEST_HOST_TAG(packed_sigptr); + slot_num = GET_PACKED_DATAREF_SLOT(packed_sigptr, 0) & 0x00FF; + + unifi_trace(card->ospriv, UDBG5, + "process_fh_traffic_queue signal ID =%x fh slot=%x Host tag =%x\n", + GET_SIGNAL_ID(packed_sigptr), slot_num, host_tag); + card->fh_slot_host_tag_record[slot_num] = host_tag; + } + UNIFI_INIT_BULK_DATA(&bulkdata.d[1]); + UNIFI_INIT_BULK_DATA(&csptr->bulkdata[0]); + UNIFI_INIT_BULK_DATA(&csptr->bulkdata[1]); + +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + if (bulkdata.d[0].os_data_ptr) + { + if ((*bulkdata.d[0].os_data_ptr) & 0x08) + { + card->cmd_prof.tx_count++; + } + } +#endif + unifi_trace(card->ospriv, UDBG3, "Sending signal 0x%.4X\n", + GET_SIGNAL_ID(packed_sigptr)); +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "Sending signal 0x%.4X\n", + GET_SIGNAL_ID(packed_sigptr)); +#endif /* CSR_WIFI_HIP_NOISY */ + + /* Append packed signal to F-H buffer */ + total_length = sig_chunks * card->config_data.sig_frag_size; + + card->fh_buffer.ptr[0] = (CsrUint8)(signal_length & 0xff); + card->fh_buffer.ptr[1] = + (CsrUint8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4)); + + CsrMemCpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length); + CsrMemSet(card->fh_buffer.ptr + 2 + signal_length, 0, + total_length - (2 + signal_length)); + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n", + signal_length + 2); + dump(card->fh_buffer.ptr, signal_length + 2); + unifi_trace(card->ospriv, UDBG1, " \n"); +#endif /* CSR_WIFI_HIP_NOISY */ + + card->fh_buffer.ptr += total_length; + card->fh_buffer.count += sig_chunks; + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n", + signal_length, + card->fh_buffer.ptr - card->fh_buffer.buf, + card->fh_buffer.count); +#endif /* CSR_WIFI_HIP_NOISY */ + + (*processed)++; + pending_sigs--; + pending_chunks -= sig_chunks; + + /* Log the signal to the UDI. */ + /* UDI will get the packed structure */ + /* Can not log the unpacked signal, unless we reconstruct it! */ + if (card->udi_hook) + { + (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length, + &bulkdata, UDI_LOG_FROM_HOST); + } + + /* Remove entry from q */ + csptr->signal_length = 0; + /* Note that the traffic queue has only one valid bulk data buffer. */ + csptr->bulkdata[0].data_length = 0; + + CSR_WIFI_HIP_Q_INC_R(&sigq[q_no]); + } while ((pending_sigs > 0) && (pending_chunks > 0) && (q_no >= 0)); + + return CSR_RESULT_SUCCESS; +} /* process_fh_traffic_queue() */ + + +/* + * --------------------------------------------------------------------------- + * flush_fh_buffer + * + * Write out the cache from-hosts signals to the UniFi. + * + * Arguments: + * card Pointer to card context struct + * + * Returns: + * CSR error code if an SDIO error occurred. + * --------------------------------------------------------------------------- + */ +static CsrResult flush_fh_buffer(card_t *card) +{ + CsrResult r; + CsrUint16 len; + CsrUint16 sig_units; + CsrUint16 data_round; + CsrUint16 chunks_in_last_block; + CsrUint16 padding_chunks; + CsrUint16 i; + + len = card->fh_buffer.ptr - card->fh_buffer.buf; + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "fh_buffer is at %p, ptr= %p\n", + card->fh_buffer.buf, card->fh_buffer.ptr); +#endif /* CSR_WIFI_HIP_NOISY */ + + if (len == 0) + { + return CSR_RESULT_SUCCESS; + } + +#ifdef CSR_WIFI_HIP_NOISY + if (dump_fh_buf) + { + dump(card->fh_buffer.buf, len); + dump_fh_buf = 0; + } +#endif /* CSR_WIFI_HIP_NOISY */ + + if (card->sdio_io_block_pad) + { + /* Both of these are powers of 2 */ + sig_units = card->config_data.sig_frag_size; + data_round = card->sdio_io_block_size; + + if (data_round > sig_units) + { + chunks_in_last_block = (len % data_round) / sig_units; + + if (chunks_in_last_block != 0) + { + padding_chunks = (data_round / sig_units) - chunks_in_last_block; + + CsrMemSet(card->fh_buffer.ptr, 0, padding_chunks * sig_units); + for (i = 0; i < padding_chunks; i++) + { + card->fh_buffer.ptr[1] = SDIO_CMD_PADDING << 4; + card->fh_buffer.ptr += sig_units; + } + + card->fh_buffer.count += padding_chunks; + len += padding_chunks * sig_units; + } + } + } + + r = unifi_bulk_rw(card, + card->config_data.fromhost_sigbuf_handle, + card->fh_buffer.buf, + len, UNIFI_SDIO_WRITE); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write fh signals: %u bytes, error %d\n", len, r); + return r; + } + + /* Update from-host-signals-written signal count */ + card->from_host_signals_w = + (card->from_host_signals_w + card->fh_buffer.count) % 128u; + r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 0, + (CsrUint8)card->from_host_signals_w); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write fh signal count %u with error %d\n", + card->from_host_signals_w, r); + return r; + } + card->generate_interrupt = 1; + + /* Reset the fh buffer pointer */ + card->fh_buffer.ptr = card->fh_buffer.buf; + card->fh_buffer.count = 0; + +#ifdef CSR_WIFI_HIP_NOISY + unifi_error(card->ospriv, "END flush: fh len %d, count %d\n", + card->fh_buffer.ptr - card->fh_buffer.buf, + card->fh_buffer.count); +#endif /* CSR_WIFI_HIP_NOISY */ + + return CSR_RESULT_SUCCESS; +} /* flush_fh_buffer() */ + + +/* + * --------------------------------------------------------------------------- + * restart_packet_flow + * + * This function is called before the bottom-half thread sleeps. + * It checks whether both data and signal resources are available and + * then calls the OS-layer function to re-enable packet transmission. + * + * Arguments: + * card Pointer to card context struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void restart_packet_flow(card_t *card) +{ + CsrUint8 q; + + /* + * We only look at the fh_traffic_queue, because that is where packets from + * the network stack are placed. + */ + for (q = 0; q <= UNIFI_TRAFFIC_Q_VO; q++) + { + if (card_is_tx_q_paused(card, q) && + CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[q]) >= RESUME_XMIT_THRESHOLD) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("U"); +#endif + card_tx_q_unpause(card, q); + unifi_restart_xmit(card->ospriv, (unifi_TrafficQueue)q); + } + } +} /* restart_packet_flow() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c new file mode 100644 index 000000000000..403641d4df02 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c @@ -0,0 +1,1713 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_card_sdio_mem.c + * + * PURPOSE: Implementation of the Card API for SDIO. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_card.h" + +#define SDIO_RETRIES 3 +#define CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH 16 + + +#define retryable_sdio_error(_csrResult) (((_csrResult) == CSR_SDIO_RESULT_CRC_ERROR) || ((_csrResult) == CSR_SDIO_RESULT_TIMEOUT)) + + +/* + * --------------------------------------------------------------------------- + * retrying_read8 + * retrying_write8 + * + * These functions provide the first level of retry for SDIO operations. + * If an SDIO command fails for reason of a response timeout or CRC + * error, it is retried immediately. If three attempts fail we report a + * failure. + * If the command failed for any other reason, the failure is reported + * immediately. + * + * Arguments: + * card Pointer to card structure. + * funcnum The SDIO function to access. + * Function 0 is the Card Configuration Register space, + * function 1/2 is the UniFi register space. + * addr Address to access + * pdata Pointer in which to return the value read. + * data Value to write. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * --------------------------------------------------------------------------- + */ +static CsrResult retrying_read8(card_t *card, CsrInt16 funcnum, CsrUint32 addr, CsrUint8 *pdata) +{ + CsrSdioFunction *sdio = card->sdio_if; + CsrResult r = CSR_RESULT_SUCCESS; + CsrInt16 retries; + CsrResult csrResult = CSR_RESULT_SUCCESS; + + retries = 0; + while (retries++ < SDIO_RETRIES) + { + if (funcnum == 0) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("r0@%02X", addr); +#endif + csrResult = CsrSdioF0Read8(sdio, addr, pdata); + } + else + { +#ifdef CSR_WIFI_TRANSPORT_CSPI + unifi_error(card->ospriv, + "retrying_read_f0_8: F1 8-bit reads are not allowed.\n"); + return CSR_RESULT_FAILURE; +#else +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("r@%02X", addr); +#endif + csrResult = CsrSdioRead8(sdio, addr, pdata); +#endif + } +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf("error=%X\n", csrResult); + } + else + { + unifi_debug_log_to_buf("=%X\n", *pdata); + } +#endif + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + /* + * Try again for retryable (CRC or TIMEOUT) errors, + * break on success or fatal error + */ + if (!retryable_sdio_error(csrResult)) + { +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + card->cmd_prof.cmd52_count++; +#endif + break; + } + unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr); + } + + if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1)) + { + unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries); + } + + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n", + addr, retries - 1); + /* Report any SDIO error as a general i/o error */ + r = CSR_RESULT_FAILURE; + } + + return r; +} /* retrying_read8() */ + + +static CsrResult retrying_write8(card_t *card, CsrInt16 funcnum, CsrUint32 addr, CsrUint8 data) +{ + CsrSdioFunction *sdio = card->sdio_if; + CsrResult r = CSR_RESULT_SUCCESS; + CsrInt16 retries; + CsrResult csrResult = CSR_RESULT_SUCCESS; + + retries = 0; + while (retries++ < SDIO_RETRIES) + { + if (funcnum == 0) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("w0@%02X=%X", addr, data); +#endif + csrResult = CsrSdioF0Write8(sdio, addr, data); + } + else + { +#ifdef CSR_WIFI_TRANSPORT_CSPI + unifi_error(card->ospriv, + "retrying_write_f0_8: F1 8-bit writes are not allowed.\n"); + return CSR_RESULT_FAILURE; +#else +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("w@%02X=%X", addr, data); +#endif + csrResult = CsrSdioWrite8(sdio, addr, data); +#endif + } +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf(",error=%X", csrResult); + } + unifi_debug_string_to_buf("\n"); +#endif + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + /* + * Try again for retryable (CRC or TIMEOUT) errors, + * break on success or fatal error + */ + if (!retryable_sdio_error(csrResult)) + { +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + card->cmd_prof.cmd52_count++; +#endif + break; + } + unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n", + data, funcnum, addr); + } + + if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1)) + { + unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries); + } + + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n", + addr, retries - 1); + /* Report any SDIO error as a general i/o error */ + r = CSR_RESULT_FAILURE; + } + + return r; +} /* retrying_write8() */ + + +static CsrResult retrying_read16(card_t *card, CsrInt16 funcnum, + CsrUint32 addr, CsrUint16 *pdata) +{ + CsrSdioFunction *sdio = card->sdio_if; + CsrResult r = CSR_RESULT_SUCCESS; + CsrInt16 retries; + CsrResult csrResult = CSR_RESULT_SUCCESS; + + retries = 0; + while (retries++ < SDIO_RETRIES) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("r@%02X", addr); +#endif + csrResult = CsrSdioRead16(sdio, addr, pdata); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf("error=%X\n", csrResult); + } + else + { + unifi_debug_log_to_buf("=%X\n", *pdata); + } +#endif + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + + /* + * Try again for retryable (CRC or TIMEOUT) errors, + * break on success or fatal error + */ + if (!retryable_sdio_error(csrResult)) + { +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + card->cmd_prof.cmd52_count++; +#endif + break; + } + unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr); + } + + if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1)) + { + unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries); + } + + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n", + addr, retries - 1); + /* Report any SDIO error as a general i/o error */ + r = CSR_RESULT_FAILURE; + } + + return r; +} /* retrying_read16() */ + + +static CsrResult retrying_write16(card_t *card, CsrInt16 funcnum, + CsrUint32 addr, CsrUint16 data) +{ + CsrSdioFunction *sdio = card->sdio_if; + CsrResult r = CSR_RESULT_SUCCESS; + CsrInt16 retries; + CsrResult csrResult = CSR_RESULT_SUCCESS; + + retries = 0; + while (retries++ < SDIO_RETRIES) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("w@%02X=%X", addr, data); +#endif + csrResult = CsrSdioWrite16(sdio, addr, data); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf(",error=%X", csrResult); + } + unifi_debug_string_to_buf("\n"); +#endif + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } + + /* + * Try again for retryable (CRC or TIMEOUT) errors, + * break on success or fatal error + */ + if (!retryable_sdio_error(csrResult)) + { +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + card->cmd_prof.cmd52_count++; +#endif + break; + } + unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n", + data, funcnum, addr); + } + + if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1)) + { + unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries); + } + + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n", + addr, retries - 1); + /* Report any SDIO error as a general i/o error */ + r = CSR_RESULT_FAILURE; + } + + return r; +} /* retrying_write16() */ + + +/* + * --------------------------------------------------------------------------- + * sdio_read_f0 + * + * Reads a byte value from the CCCR (func 0) area of UniFi. + * + * Arguments: + * card Pointer to card structure. + * addr Address to read from + * pdata Pointer in which to store the read value. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * --------------------------------------------------------------------------- + */ +CsrResult sdio_read_f0(card_t *card, CsrUint32 addr, CsrUint8 *pdata) +{ +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_f0_r_count++; +#endif + return retrying_read8(card, 0, addr, pdata); +} /* sdio_read_f0() */ + + +/* + * --------------------------------------------------------------------------- + * sdio_write_f0 + * + * Writes a byte value to the CCCR (func 0) area of UniFi. + * + * Arguments: + * card Pointer to card structure. + * addr Address to read from + * data Data value to write. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * --------------------------------------------------------------------------- + */ +CsrResult sdio_write_f0(card_t *card, CsrUint32 addr, CsrUint8 data) +{ +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_f0_w_count++; +#endif + return retrying_write8(card, 0, addr, data); +} /* sdio_write_f0() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_read_direct_8_or_16 + * + * Read a 8-bit value from the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Address to read from + * pdata Pointer in which to return data. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * --------------------------------------------------------------------------- + */ +CsrResult unifi_read_direct_8_or_16(card_t *card, CsrUint32 addr, CsrUint8 *pdata) +{ +#ifdef CSR_WIFI_TRANSPORT_CSPI + CsrUint16 w; + CsrResult r; + + r = retrying_read16(card, card->function, addr, &w); + *pdata = (CsrUint8)(w & 0xFF); + return r; +#else + return retrying_read8(card, card->function, addr, pdata); +#endif +} /* unifi_read_direct_8_or_16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_write_direct_8_or_16 + * + * Write a byte value to the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Address to write to + * data Value to write. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error + * + * Notes: + * If 8-bit write is used, the even address *must* be written second. + * This is because writes to odd bytes are cached and not committed + * to memory until the preceding even address is written. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_write_direct_8_or_16(card_t *card, CsrUint32 addr, CsrUint8 data) +{ + if (addr & 1) + { + unifi_warning(card->ospriv, + "Warning: Byte write to an odd address (0x%lX) is dangerous\n", + addr); + } + +#ifdef CSR_WIFI_TRANSPORT_CSPI + return retrying_write16(card, card->function, addr, (CsrUint16)data); +#else + return retrying_write8(card, card->function, addr, data); +#endif +} /* unifi_write_direct_8_or_16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_read_direct16 + * + * Read a 16-bit value from the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Address to read from + * pdata Pointer in which to return data. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * The even address *must* be read first. This is because reads from + * odd bytes are cached and read from memory when the preceding + * even address is read. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_read_direct16(card_t *card, CsrUint32 addr, CsrUint16 *pdata) +{ + return retrying_read16(card, card->function, addr, pdata); +} /* unifi_read_direct16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_write_direct16 + * + * Write a 16-bit value to the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Address to write to + * data Value to write. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * The even address *must* be written second. This is because writes to + * odd bytes are cached and not committed to memory until the preceding + * even address is written. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_write_direct16(card_t *card, CsrUint32 addr, CsrUint16 data) +{ + return retrying_write16(card, card->function, addr, data); +} /* unifi_write_direct16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_read_direct32 + * + * Read a 32-bit value from the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Address to read from + * pdata Pointer in which to return data. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * --------------------------------------------------------------------------- + */ +CsrResult unifi_read_direct32(card_t *card, CsrUint32 addr, CsrUint32 *pdata) +{ + CsrResult r; + CsrUint16 w0, w1; + + r = retrying_read16(card, card->function, addr, &w0); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + r = retrying_read16(card, card->function, addr + 2, &w1); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + *pdata = ((CsrUint32)w1 << 16) | (CsrUint32)w0; + + return CSR_RESULT_SUCCESS; +} /* unifi_read_direct32() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_read_directn_match + * + * Read multiple 8-bit values from the UniFi SDIO interface, + * stopping when either we have read 'len' bytes or we have read + * a octet equal to 'match'. If 'match' is not a valid octet + * then this function is the same as 'unifi_read_directn'. + * + * Arguments: + * card Pointer to card structure. + * addr Start address to read from. + * pdata Pointer to which to write data. + * len Maximum umber of bytes to read + * match The value to stop reading at. + * num Pointer to buffer to write number of bytes read + * + * Returns: + * number of octets read on success, negative error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * The even address *must* be read first. This is because reads from + * odd bytes are cached and read from memory when the preceding + * even address is read. + * --------------------------------------------------------------------------- + */ +static CsrResult unifi_read_directn_match(card_t *card, CsrUint32 addr, void *pdata, CsrUint16 len, CsrInt8 m, CsrUint32 *num) +{ + CsrResult r; + CsrUint32 i; + CsrUint8 *cptr; + CsrUint16 w; + + *num = 0; + + cptr = (CsrUint8 *)pdata; + for (i = 0; i < len; i += 2) + { + r = retrying_read16(card, card->function, addr, &w); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + *cptr++ = ((CsrUint8)w & 0xFF); + if ((m >= 0) && (((CsrInt8)w & 0xFF) == m)) + { + break; + } + + if (i + 1 == len) + { + /* The len is odd. Ignore the last high byte */ + break; + } + + *cptr++ = ((CsrUint8)(w >> 8) & 0xFF); + if ((m >= 0) && (((CsrInt8)(w >> 8) & 0xFF) == m)) + { + break; + } + + addr += 2; + } + + *num = (CsrInt32)(cptr - (CsrUint8 *)pdata); + return CSR_RESULT_SUCCESS; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_read_directn + * + * Read multiple 8-bit values from the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Start address to read from. + * pdata Pointer to which to write data. + * len Number of bytes to read + * + * Returns: + * 0 on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * The even address *must* be read first. This is because reads from + * odd bytes are cached and read from memory when the preceding + * even address is read. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_read_directn(card_t *card, CsrUint32 addr, void *pdata, CsrUint16 len) +{ + CsrUint32 num; + + return unifi_read_directn_match(card, addr, pdata, len, -1, &num); +} /* unifi_read_directn() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_write_directn + * + * Write multiple 8-bit values to the UniFi SDIO interface. + * + * Arguments: + * card Pointer to card structure. + * addr Start address to write to. + * pdata Source data pointer. + * len Number of bytes to write, must be even. + * + * Returns: + * 0 on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * The UniFi has a peculiar 16-bit bus architecture. Writes are only + * committed to memory when an even address is accessed. Writes to + * odd addresses are cached and only committed if the next write is + * to the preceding address. + * This means we must write data as pairs of bytes in reverse order. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_write_directn(card_t *card, CsrUint32 addr, void *pdata, CsrUint16 len) +{ + CsrResult r; + CsrUint8 *cptr; + CsrInt16 signed_len; + + cptr = (CsrUint8 *)pdata; + signed_len = (CsrInt16)len; + while (signed_len > 0) + { + /* This is UniFi-1 specific code. CSPI not supported so 8-bit write allowed */ + r = retrying_write16(card, card->function, addr, *cptr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + cptr += 2; + addr += 2; + signed_len -= 2; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_write_directn() */ + + +/* + * --------------------------------------------------------------------------- + * set_dmem_page + * set_pmem_page + * + * Set up the page register for the shared data memory window or program + * memory window. + * + * Arguments: + * card Pointer to card structure. + * dmem_addr UniFi shared-data-memory address to access. + * pmem_addr UniFi program memory address to access. This includes + * External FLASH memory at 0x000000 + * Processor program memory at 0x200000 + * External SRAM at memory 0x400000 + * paddr Location to write an SDIO address (24-bit) for + * use in a unifi_read_direct or unifi_write_direct call. + * + * Returns: + * CSR_RESULT_SUCCESS on success + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * --------------------------------------------------------------------------- + */ +static CsrResult set_dmem_page(card_t *card, CsrUint32 dmem_addr, CsrUint32 *paddr) +{ + CsrUint16 page, addr; + CsrUint32 len; + CsrResult r; + + *paddr = 0; + + if (!ChipHelper_DecodeWindow(card->helper, + CHIP_HELPER_WINDOW_3, + CHIP_HELPER_WT_SHARED, + dmem_addr / 2, + &page, &addr, &len)) + { + unifi_error(card->ospriv, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + if (page != card->dmem_page) + { + unifi_trace(card->ospriv, UDBG6, "setting dmem page=0x%X, addr=0x%lX\n", page, addr); + + /* change page register */ + r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, page); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n"); + return r; + } + + card->dmem_page = page; + } + + *paddr = ((CsrInt32)addr * 2) + (dmem_addr & 1); + + return CSR_RESULT_SUCCESS; +} /* set_dmem_page() */ + + +static CsrResult set_pmem_page(card_t *card, CsrUint32 pmem_addr, + enum chip_helper_window_type mem_type, CsrUint32 *paddr) +{ + CsrUint16 page, addr; + CsrUint32 len; + CsrResult r; + + *paddr = 0; + + if (!ChipHelper_DecodeWindow(card->helper, + CHIP_HELPER_WINDOW_2, + mem_type, + pmem_addr / 2, + &page, &addr, &len)) + { + unifi_error(card->ospriv, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr, mem_type); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + if (page != card->pmem_page) + { + unifi_trace(card->ospriv, UDBG6, "setting pmem page=0x%X, addr=0x%lX\n", page, addr); + + /* change page register */ + r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, page); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write PROG MEM PAGE\n"); + return r; + } + + card->pmem_page = page; + } + + *paddr = ((CsrInt32)addr * 2) + (pmem_addr & 1); + + return CSR_RESULT_SUCCESS; +} /* set_pmem_page() */ + + +/* + * --------------------------------------------------------------------------- + * set_page + * + * Sets up the appropriate page register to access the given address. + * Returns the sdio address at which the unifi address can be accessed. + * + * Arguments: + * card Pointer to card structure. + * generic_addr UniFi internal address to access, in Generic Pointer + * format, i.e. top byte is space indicator. + * paddr Location to write page address + * SDIO address (24-bit) for use in a unifi_read_direct or + * unifi_write_direct call + * + * Returns: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE the address is invalid + * --------------------------------------------------------------------------- + */ +static CsrResult set_page(card_t *card, CsrUint32 generic_addr, CsrUint32 *paddr) +{ + CsrInt32 space; + CsrUint32 addr; + CsrResult r = CSR_RESULT_SUCCESS; + + if (!paddr) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + *paddr = 0; + space = UNIFI_GP_SPACE(generic_addr); + addr = UNIFI_GP_OFFSET(generic_addr); + switch (space) + { + case UNIFI_SH_DMEM: + /* Shared Data Memory is accessed via the Shared Data Memory window */ + r = set_dmem_page(card, addr, paddr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + break; + + case UNIFI_EXT_FLASH: + if (!ChipHelper_HasFlash(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + /* External FLASH is accessed via the Program Memory window */ + r = set_pmem_page(card, addr, CHIP_HELPER_WT_FLASH, paddr); + break; + + case UNIFI_EXT_SRAM: + if (!ChipHelper_HasExtSram(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08l (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + /* External SRAM is accessed via the Program Memory window */ + r = set_pmem_page(card, addr, CHIP_HELPER_WT_EXT_SRAM, paddr); + break; + + case UNIFI_REGISTERS: + /* Registers are accessed directly */ + *paddr = addr; + break; + + case UNIFI_PHY_DMEM: + r = unifi_set_proc_select(card, UNIFI_PROC_PHY); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr; + break; + + case UNIFI_MAC_DMEM: + r = unifi_set_proc_select(card, UNIFI_PROC_MAC); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr; + break; + + case UNIFI_BT_DMEM: + if (!ChipHelper_HasBt(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + r = unifi_set_proc_select(card, UNIFI_PROC_BT); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr; + break; + + case UNIFI_PHY_PMEM: + r = unifi_set_proc_select(card, UNIFI_PROC_PHY); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr); + break; + + case UNIFI_MAC_PMEM: + r = unifi_set_proc_select(card, UNIFI_PROC_MAC); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr); + break; + + case UNIFI_BT_PMEM: + if (!ChipHelper_HasBt(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + r = unifi_set_proc_select(card, UNIFI_PROC_BT); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr); + break; + + case UNIFI_PHY_ROM: + if (!ChipHelper_HasRom(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + r = unifi_set_proc_select(card, UNIFI_PROC_PHY); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr); + break; + + case UNIFI_MAC_ROM: + if (!ChipHelper_HasRom(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + r = unifi_set_proc_select(card, UNIFI_PROC_MAC); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr); + break; + + case UNIFI_BT_ROM: + if (!ChipHelper_HasRom(card->helper) || !ChipHelper_HasBt(card->helper)) + { + unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n", + generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + r = unifi_set_proc_select(card, UNIFI_PROC_BT); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr); + break; + + default: + unifi_error(card->ospriv, "Bad address space %d in generic pointer 0x%08lX (helper=0x%x)\n", + space, generic_addr, card->helper); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + return r; +} /* set_page() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_set_proc_select + * + * + * Arguments: + * card Pointer to card structure. + * select Which XAP core to select + * + * Returns: + * 0 on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * --------------------------------------------------------------------------- + */ +CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select) +{ + CsrResult r; + + /* Verify the the select value is allowed. */ + switch (select) + { + case UNIFI_PROC_MAC: + case UNIFI_PROC_PHY: + case UNIFI_PROC_BOTH: + break; + + + default: + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + if (card->proc_select != (CsrUint32)select) + { + r = unifi_write_direct16(card, + ChipHelper_DBG_HOST_PROC_SELECT(card->helper) * 2, + (CsrUint8)select); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write to Proc Select register\n"); + return r; + } + + card->proc_select = (CsrUint32)select; + } + + return CSR_RESULT_SUCCESS; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_read_8_or_16 + * + * Performs a byte read of the given address in shared data memory. + * Set up the shared data memory page register as required. + * + * Arguments: + * card Pointer to card structure. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to a byte variable for the value read. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified + * --------------------------------------------------------------------------- + */ +CsrResult unifi_read_8_or_16(card_t *card, CsrUint32 unifi_addr, CsrUint8 *pdata) +{ + CsrUint32 sdio_addr; + CsrResult r; +#ifdef CSR_WIFI_TRANSPORT_CSPI + CsrUint16 w; +#endif + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_r8or16_count++; +#endif +#ifdef CSR_WIFI_TRANSPORT_CSPI + r = retrying_read16(card, card->function, sdio_addr, &w); + *pdata = (CsrUint8)(w & 0xFF); + return r; +#else + return retrying_read8(card, card->function, sdio_addr, pdata); +#endif +} /* unifi_read_8_or_16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_write_8_or_16 + * + * Performs a byte write of the given address in shared data memory. + * Set up the shared data memory page register as required. + * + * Arguments: + * card Pointer to card context struct. + * unifi_addr UniFi shared-data-memory address to access. + * data Value to write. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified + * + * Notes: + * Beware using unifi_write8() because byte writes are not safe on UniFi. + * Writes to odd bytes are cached, writes to even bytes perform a 16-bit + * write with the previously cached odd byte. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_write_8_or_16(card_t *card, CsrUint32 unifi_addr, CsrUint8 data) +{ + CsrUint32 sdio_addr; + CsrResult r; +#ifdef CSR_WIFI_TRANSPORT_CSPI + CsrUint16 w; +#endif + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + if (sdio_addr & 1) + { + unifi_warning(card->ospriv, + "Warning: Byte write to an odd address (0x%lX) is dangerous\n", + sdio_addr); + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_w8or16_count++; +#endif +#ifdef CSR_WIFI_TRANSPORT_CSPI + w = data; + return retrying_write16(card, card->function, sdio_addr, w); +#else + return retrying_write8(card, card->function, sdio_addr, data); +#endif +} /* unifi_write_8_or_16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_card_read16 + * + * Performs a 16-bit read of the given address in shared data memory. + * Set up the shared data memory page register as required. + * + * Arguments: + * card Pointer to card structure. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to a 16-bit int variable for the value read. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified + * --------------------------------------------------------------------------- + */ +CsrResult unifi_card_read16(card_t *card, CsrUint32 unifi_addr, CsrUint16 *pdata) +{ + CsrUint32 sdio_addr; + CsrResult r; + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_r16_count++; +#endif + return unifi_read_direct16(card, sdio_addr, pdata); +} /* unifi_card_read16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_card_write16 + * + * Performs a 16-bit write of the given address in shared data memory. + * Set up the shared data memory page register as required. + * + * Arguments: + * card Pointer to card structure. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to a byte variable for the value write. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified + * --------------------------------------------------------------------------- + */ +CsrResult unifi_card_write16(card_t *card, CsrUint32 unifi_addr, CsrUint16 data) +{ + CsrUint32 sdio_addr; + CsrResult r; + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_w16_count++; +#endif + return unifi_write_direct16(card, sdio_addr, data); +} /* unifi_card_write16() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_read32 + * + * Performs a 32-bit read of the given address in shared data memory. + * Set up the shared data memory page register as required. + * + * Arguments: + * card Pointer to card structure. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to a int variable for the value read. + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified + * --------------------------------------------------------------------------- + */ +CsrResult unifi_read32(card_t *card, CsrUint32 unifi_addr, CsrUint32 *pdata) +{ + CsrUint32 sdio_addr; + CsrResult r; + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + card->cmd_prof.cmd52_r32_count++; +#endif + return unifi_read_direct32(card, sdio_addr, pdata); +} /* unifi_read32() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_card_readn + * unifi_readnz + * + * Read multiple 8-bit values from the UniFi SDIO interface. + * This function interprets the address as a GenericPointer as + * defined in the UniFi Host Interface Protocol Specification. + * The readnz version of this function will stop when it reads a + * zero octet. + * + * Arguments: + * card Pointer to card structure. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to which to write data. + * len Number of bytes to read + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified + * --------------------------------------------------------------------------- + */ +CsrResult unifi_readn_match(card_t *card, CsrUint32 unifi_addr, void *pdata, CsrUint16 len, CsrInt8 match) +{ + CsrUint32 sdio_addr; + CsrResult r; + CsrUint32 num; + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + r = unifi_read_directn_match(card, sdio_addr, pdata, len, match, &num); + return r; +} /* unifi_readn_match() */ + + +CsrResult unifi_card_readn(card_t *card, CsrUint32 unifi_addr, void *pdata, CsrUint16 len) +{ + return unifi_readn_match(card, unifi_addr, pdata, len, -1); +} /* unifi_card_readn() */ + + +CsrResult unifi_readnz(card_t *card, CsrUint32 unifi_addr, void *pdata, CsrUint16 len) +{ + return unifi_readn_match(card, unifi_addr, pdata, len, 0); +} /* unifi_readnz() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_read_shared_count + * + * Read signal count locations, checking for an SDIO error. The + * signal count locations only contain a valid number if the + * highest bit isn't set. + * + * Arguments: + * card Pointer to card context structure. + * addr Shared-memory address to read. + * + * Returns: + * Value read from memory (0-127) or -1 on error + * --------------------------------------------------------------------------- + */ +CsrInt32 unifi_read_shared_count(card_t *card, CsrUint32 addr) +{ + CsrUint8 b; + /* I've increased this count, because I have seen cases where + * there were three reads in a row with the top bit set. I'm not + * sure why this might have happened, but I can't see a problem + * with increasing this limit. It's better to take a while to + * recover than to fail. */ +#define SHARED_READ_RETRY_LIMIT 10 + CsrInt32 i; + + /* + * Get the to-host-signals-written count. + * The top-bit will be set if the firmware was in the process of + * changing the value, in which case we read again. + */ + /* Limit the number of repeats so we don't freeze */ + for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) + { + CsrResult r; + r = unifi_read_8_or_16(card, addr, &b); + if (r != CSR_RESULT_SUCCESS) + { + return -1; + } + if (!(b & 0x80)) + { + /* There is a chance that the MSB may have contained invalid data + * (overflow) at the time it was read. Therefore mask off the MSB. + * This avoids a race between driver read and firmware write of the + * word, the value we need is in the lower 8 bits anway. + */ + return (CsrInt32)(b & 0xff); + } + } + + return -1; /* this function has changed in WMM mods */ +} /* unifi_read_shared_count() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_writen + * + * Write multiple 8-bit values to the UniFi SDIO interface using CMD52 + * This function interprets the address as a GenericPointer as + * defined in the UniFi Host Interface Protocol Specification. + * + * Arguments: + * card Pointer to card structure. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to which to write data. + * len Number of bytes to write + * + * Returns: + * 0 on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * CSR_WIFI_HIP_RESULT_INVALID_VALUE an odd length or length too big. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_writen(card_t *card, CsrUint32 unifi_addr, void *pdata, CsrUint16 len) +{ + CsrUint32 sdio_addr; + CsrResult r; + + r = set_page(card, unifi_addr, &sdio_addr); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + return unifi_write_directn(card, sdio_addr, pdata, len); +} /* unifi_writen() */ + + +static CsrResult csr_sdio_block_rw(card_t *card, CsrInt16 funcnum, + CsrUint32 addr, CsrUint8 *pdata, + CsrUint16 count, CsrInt16 dir_is_write) +{ + CsrResult csrResult; + + if (dir_is_write == UNIFI_SDIO_READ) + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("r@%02X#%X=", addr, count); +#endif +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("R"); +#endif + csrResult = CsrSdioRead(card->sdio_if, addr, pdata, count); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("<"); +#endif + } + else + { +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + unifi_debug_log_to_buf("w@%02X#%X=", addr, count); + unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count); +#endif +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("W"); +#endif + csrResult = CsrSdioWrite(card->sdio_if, addr, pdata, count); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf(">"); +#endif + } +#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE + card->cmd_prof.cmd53_count++; +#endif +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE) + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_debug_log_to_buf("error=%X", csrResult); + } + else if (dir_is_write == UNIFI_SDIO_READ) + { + unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count); + } + unifi_debug_string_to_buf("\n"); +#endif + return csrResult; /* CSR SDIO (not HIP) error code */ +} + + +/* + * --------------------------------------------------------------------------- + * unifi_bulk_rw + * + * Transfer bulk data to or from the UniFi SDIO interface. + * This function is used to read or write signals and bulk data. + * + * Arguments: + * card Pointer to card structure. + * handle Value to put in the Register Address field of the CMD53 req. + * data Pointer to data to write. + * direction One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE + * + * Returns: + * CSR_RESULT_SUCCESS on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * This function uses SDIO CMD53, which is the block transfer mode. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_bulk_rw(card_t *card, CsrUint32 handle, void *pdata, + CsrUint32 len, CsrInt16 direction) +{ +#define CMD53_RETRIES 3 + /* + * Ideally instead of sleeping, we want to busy wait. + * Currently there is no framework API to do this. When it becomes available, + * we can use it to busy wait using usecs + */ +#define REWIND_RETRIES 15 /* when REWIND_DELAY==1msec, or 250 when REWIND_DELAY==50usecs */ +#define REWIND_POLLING_RETRIES 5 +#define REWIND_DELAY 1 /* msec or 50usecs */ + CsrResult csrResult; /* SDIO error code */ + CsrResult r = CSR_RESULT_SUCCESS; /* HIP error code */ + CsrInt16 retries = CMD53_RETRIES; + CsrInt16 stat_retries; + CsrUint8 stat; + CsrInt16 dump_read; +#ifdef UNIFI_DEBUG + CsrUint8 *pdata_lsb = ((CsrUint8 *)&pdata) + card->lsb; +#endif +#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS + static CsrInt16 fake_error; +#endif + + dump_read = 0; +#ifdef UNIFI_DEBUG + if (*pdata_lsb & 1) + { + unifi_notice(card->ospriv, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n", + pdata, (direction == UNIFI_SDIO_READ)?"To" : "From"); + if (direction == UNIFI_SDIO_WRITE) + { + dump(pdata, (CsrUint16)len); + } + else + { + dump_read = 1; + } + } +#endif + + /* Defensive checks */ + if (!pdata) + { + unifi_error(card->ospriv, "Null pdata for unifi_bulk_rw() len: %d\n", len); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + if ((len & 1) || (len > 0xffff)) + { + unifi_error(card->ospriv, "Impossible CMD53 length requested: %d\n", len); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + while (1) + { + csrResult = csr_sdio_block_rw(card, card->function, handle, + (CsrUint8 *)pdata, (CsrUint16)len, + direction); + if (csrResult == CSR_SDIO_RESULT_NO_DEVICE) + { + return CSR_WIFI_HIP_RESULT_NO_DEVICE; + } +#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS + if (++fake_error > 100) + { + fake_error = 90; + unifi_warning(card->ospriv, "Faking a CMD53 error,\n"); + if (csrResult == CSR_RESULT_SUCCESS) + { + csrResult = CSR_RESULT_FAILURE; + } + } +#endif + if (csrResult == CSR_RESULT_SUCCESS) + { + if (dump_read) + { + dump(pdata, (CsrUint16)len); + } + break; + } + + /* + * At this point the SDIO driver should have written the I/O Abort + * register to notify UniFi that the command has failed. + * UniFi-1 and UniFi-2 (not UF6xxx) use the same register to store the + * Deep Sleep State. This means we have to restore the Deep Sleep + * State (AWAKE in any case since we can not perform a CD53 in any other + * state) by rewriting the I/O Abort register to its previous value. + */ + if (card->chip_id <= SDIO_CARD_ID_UNIFI_2) + { + unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + } + + /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted + * then stop retrying + */ + if (!retryable_sdio_error(csrResult)) + { + unifi_error(card->ospriv, "Fatal error in a CMD53 transfer\n"); + break; + } + + /* + * These happen from time to time, try again + */ + if (--retries == 0) + { + break; + } + + unifi_trace(card->ospriv, UDBG4, + "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n", + (CsrInt16)handle & 0xff, len); + + /* The transfer failed, rewind and try again */ + r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 8, + (CsrUint8)(handle & 0xff)); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + /* + * If we can't even do CMD52 (register read/write) then + * stop here. + */ + unifi_error(card->ospriv, "Failed to write REWIND cmd\n"); + return r; + } + + /* Signal the UniFi to look for the rewind request. */ + r = CardGenInt(card); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + /* Wait for UniFi to acknowledge the rewind */ + stat_retries = REWIND_RETRIES; + while (1) + { + r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 8, &stat); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read REWIND status\n"); + return CSR_RESULT_FAILURE; + } + + if (stat == 0) + { + break; + } + if (--stat_retries == 0) + { + unifi_error(card->ospriv, "Timeout waiting for REWIND ready\n"); + return CSR_RESULT_FAILURE; + } + + /* Poll for the ack a few times */ + if (stat_retries < REWIND_RETRIES - REWIND_POLLING_RETRIES) + { + CsrThreadSleep(REWIND_DELAY); + } + } + } + + /* The call to csr_sdio_block_rw() still failed after retrying */ + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Block %s failed after %d retries\n", + (direction == UNIFI_SDIO_READ)?"read" : "write", + CMD53_RETRIES - retries); + /* Report any SDIO error as a general i/o error */ + return CSR_RESULT_FAILURE; + } + + /* Collect some stats */ + if (direction == UNIFI_SDIO_READ) + { + card->sdio_bytes_read += len; + } + else + { + card->sdio_bytes_written += len; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_bulk_rw() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_bulk_rw_noretry + * + * Transfer bulk data to or from the UniFi SDIO interface. + * This function is used to read or write signals and bulk data. + * + * Arguments: + * card Pointer to card structure. + * handle Value to put in the Register Address field of + * the CMD53 req. + * data Pointer to data to write. + * direction One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE + * + * Returns: + * 0 on success, non-zero error code on error: + * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected + * CSR_RESULT_FAILURE an SDIO error occurred + * + * Notes: + * This function uses SDIO CMD53, which is the block transfer mode. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_bulk_rw_noretry(card_t *card, CsrUint32 handle, void *pdata, + CsrUint32 len, CsrInt16 direction) +{ + CsrResult csrResult; + + csrResult = csr_sdio_block_rw(card, card->function, handle, + (CsrUint8 *)pdata, (CsrUint16)len, direction); + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Block %s failed\n", + (direction == UNIFI_SDIO_READ)?"read" : "write"); + return csrResult; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_bulk_rw_noretry() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper.c b/drivers/staging/csr/csr_wifi_hip_chiphelper.c new file mode 100644 index 000000000000..0e2477ff4dd0 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_chiphelper.c @@ -0,0 +1,793 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + + +#include "csr_wifi_hip_chiphelper_private.h" + +#ifndef nelem +#define nelem(a) (sizeof(a) / sizeof(a[0])) +#endif + +#define counted(foo) { nelem(foo), foo } +#define null_counted() { 0, NULL } + +/* The init values are a set of register writes that we must + perform when we first connect to the chip to get it working. + They swicth on the correct clocks and possibly set the host + interface as a wkaeup source. They should not be used if + proper HIP opperation is required, but are useful before we + do a code download. */ +static const struct chip_helper_init_values init_vals_v1[] = { + { 0xFDBB, 0xFFFF }, + { 0xFDB6, 0x03FF }, + { 0xFDB1, 0x01E3 }, + { 0xFDB3, 0x0FFF }, + { 0xFEE3, 0x08F0 }, + { 0xFEE7, 0x3C3F }, + { 0xFEE6, 0x0050 }, + { 0xFDBA, 0x0000 } +}; + +static const struct chip_helper_init_values init_vals_v2[] = { + { 0xFDB6, 0x0FFF }, + { 0xF023, 0x3F3F }, + { 0xFDB1, 0x01E3 }, + { 0xFDB3, 0x0FFF }, + { 0xF003, 0x08F0 }, + { 0xF007, 0x3C3F }, + { 0xF006, 0x0050 } +}; + + +static const struct chip_helper_init_values init_vals_v22_v23[] = { + { 0xF81C, 0x00FF }, + /*{ 0x????, 0x???? }, */ + { 0xF80C, 0x1FFF }, + { 0xFA25, 0x001F }, + { 0xF804, 0x00FF }, + { 0xF802, 0x0FFF }, + /*{ 0x????, 0x???? }, + { 0x????, 0x???? }, + { 0x????, 0x???? }*/ +}; + +static const CsrUint16 reset_program_a_v1_or_v2[] = { + 0x0000 +}; +static const CsrUint16 reset_program_b_v1_or_v2[] = { + 0x0010, 0xFE00, 0xA021, 0xFF00, 0x8111, 0x0009, 0x0CA4, 0x0114, + 0x0280, 0x04F8, 0xFE00, 0x6F25, 0x06E0, 0x0010, 0xFC00, 0x0121, + 0xFC00, 0x0225, 0xFE00, 0x7125, 0xFE00, 0x6D11, 0x03F0, 0xFE00, + 0x6E25, 0x0008, 0x00E0 +}; + +static const struct chip_helper_reset_values reset_program_v1_or_v2[] = +{ + { + MAKE_GP(REGISTERS, 0x000C), + nelem(reset_program_a_v1_or_v2), + reset_program_a_v1_or_v2 + }, + { + MAKE_GP(MAC_PMEM, 0x000000), + nelem(reset_program_b_v1_or_v2), + reset_program_b_v1_or_v2 + } +}; + +static const struct chip_map_address_t unifi_map_address_v1_v2[] = +{ + { 0xFE9F, 0xFE7B }, /* PM1_BANK_SELECT */ + { 0xFE9E, 0xFE78 }, /* PM2_BANK_SELECT */ + { 0xFE9D, 0xFE7E }, /* SHARED_DMEM_PAGE */ + { 0xFE91, 0xFE90 }, /* PROC_SELECT */ + { 0xFE8D, 0xFE8C }, /* STOP_STATUS */ +}; + +static const struct chip_map_address_t unifi_map_address_v22_v23[] = +{ + { 0xF8F9, 0xF8AC }, /* GW1_CONFIG */ + { 0xF8FA, 0xF8AD }, /* GW2_CONFIG */ + { 0xF8FB, 0xF8AE }, /* GW3_CONFIG */ + { 0xF830, 0xF81E }, /* PROC_SELECT */ + { 0xF831, 0xF81F }, /* STOP_STATUS */ + { 0xF8FC, 0xF8AF }, /* IO_LOG_ADDRESS */ +}; + +static const struct chip_device_regs_t unifi_device_regs_null = +{ + 0xFE81, /* GBL_CHIP_VERSION */ + 0x0000, /* GBL_MISC_ENABLES */ + 0x0000, /* DBG_EMU_CMD */ + { + 0x0000, /* HOST.DBG_PROC_SELECT */ + 0x0000, /* HOST.DBG_STOP_STATUS */ + 0x0000, /* HOST.WINDOW1_PAGE */ + 0x0000, /* HOST.WINDOW2_PAGE */ + 0x0000, /* HOST.WINDOW3_PAGE */ + 0x0000 /* HOST.IO_LOG_ADDR */ + }, + { + 0x0000, /* SPI.DBG_PROC_SELECT */ + 0x0000, /* SPI.DBG_STOP_STATUS */ + 0x0000, /* SPI.WINDOW1_PAGE */ + 0x0000, /* SPI.WINDOW2_PAGE */ + 0x0000, /* SPI.WINDOW3_PAGE */ + 0x0000 /* SPI.IO_LOG_ADDR */ + }, + 0x0000, /* DBG_RESET */ + 0x0000, /* > DBG_RESET_VALUE */ + 0x0000, /* DBG_RESET_WARN */ + 0x0000, /* DBG_RESET_WARN_VALUE */ + 0x0000, /* DBG_RESET_RESULT */ + 0xFFE9, /* XAP_PCH */ + 0xFFEA, /* XAP_PCL */ + 0x0000, /* PROC_PC_SNOOP */ + 0x0000, /* WATCHDOG_DISABLE */ + 0x0000, /* MAILBOX0 */ + 0x0000, /* MAILBOX1 */ + 0x0000, /* MAILBOX2 */ + 0x0000, /* MAILBOX3 */ + 0x0000, /* SDIO_HOST_INT */ + 0x0000, /* SHARED_IO_INTERRUPT */ + 0x0000, /* SDIO HIP HANDSHAKE */ + 0x0000 /* COEX_STATUS */ +}; + +/* UF105x */ +static const struct chip_device_regs_t unifi_device_regs_v1 = +{ + 0xFE81, /* GBL_CHIP_VERSION */ + 0xFE87, /* GBL_MISC_ENABLES */ + 0xFE9C, /* DBG_EMU_CMD */ + { + 0xFE90, /* HOST.DBG_PROC_SELECT */ + 0xFE8C, /* HOST.DBG_STOP_STATUS */ + 0xFE7B, /* HOST.WINDOW1_PAGE */ + 0xFE78, /* HOST.WINDOW2_PAGE */ + 0xFE7E, /* HOST.WINDOW3_PAGE */ + 0x0000 /* HOST.IO_LOG_ADDR */ + }, + { + 0xFE91, /* SPI.DBG_PROC_SELECT */ + 0xFE8D, /* SPI.DBG_STOP_STATUS */ + 0xFE9F, /* SPI.WINDOW1_PAGE */ + 0xFE9E, /* SPI.WINDOW2_PAGE */ + 0xFE9D, /* SPI.WINDOW3_PAGE */ + 0x0000 /* SPI.IO_LOG_ADDR */ + }, + 0xFE92, /* DBG_RESET */ + 0x0001, /* > DBG_RESET_VALUE */ + 0xFDA0, /* DBG_RESET_WARN (HOST_SELECT) */ + 0x0000, /* DBG_RESET_WARN_VALUE */ + 0xFE92, /* DBG_RESET_RESULT */ + 0xFFE9, /* XAP_PCH */ + 0xFFEA, /* XAP_PCL */ + 0x0051, /* PROC_PC_SNOOP */ + 0xFE70, /* WATCHDOG_DISABLE */ + 0xFE6B, /* MAILBOX0 */ + 0xFE6A, /* MAILBOX1 */ + 0xFE69, /* MAILBOX2 */ + 0xFE68, /* MAILBOX3 */ + 0xFE67, /* SDIO_HOST_INT */ + 0xFE65, /* SHARED_IO_INTERRUPT */ + 0xFDE9, /* SDIO HIP HANDSHAKE */ + 0x0000 /* COEX_STATUS */ +}; + +/* UF2... */ +static const struct chip_device_regs_t unifi_device_regs_v2 = +{ + 0xFE81, /* GBL_CHIP_VERSION */ + 0xFE87, /* GBL_MISC_ENABLES */ + 0xFE9C, /* DBG_EMU_CMD */ + { + 0xFE90, /* HOST.DBG_PROC_SELECT */ + 0xFE8C, /* HOST.DBG_STOP_STATUS */ + 0xFE7B, /* HOST.WINDOW1_PAGE */ + 0xFE78, /* HOST.WINDOW2_PAGE */ + 0xFE7E, /* HOST.WINDOW3_PAGE */ + 0x0000 /* HOST.IO_LOG_ADDR */ + }, + { + 0xFE91, /* SPI.DBG_PROC_SELECT */ + 0xFE8D, /* SPI.DBG_STOP_STATUS */ + 0xFE9F, /* SPI.WINDOW1_PAGE */ + 0xFE9E, /* SPI.WINDOW2_PAGE */ + 0xFE9D, /* SPI.WINDOW3_PAGE */ + 0x0000 /* SPI.IO_LOG_ADDR */ + }, + 0xFE92, /* DBG_RESET */ + 0x0000, /* > DBG_RESET_VALUE */ + 0xFDE9, /* DBG_RESET_WARN (TEST_FLASH_DATA - SHARED_MAILBOX2B) */ + 0xFFFF, /* DBG_RESET_WARN_VALUE */ + 0xFDE9, /* DBG_RESET_RESULT (TEST_FLASH_DATA) */ + 0xFFE9, /* XAP_PCH */ + 0xFFEA, /* XAP_PCL */ + 0x0051, /* PROC_PC_SNOOP */ + 0xFE70, /* WATCHDOG_DISABLE */ + 0xFE6B, /* MAILBOX0 */ + 0xFE6A, /* MAILBOX1 */ + 0xFE69, /* MAILBOX2 */ + 0xFE68, /* MAILBOX3 */ + 0xFE67, /* SDIO_HOST_INT */ + 0xFE65, /* SHARED_IO_INTERRUPT */ + 0xFE69, /* SDIO HIP HANDSHAKE */ + 0x0000 /* COEX_STATUS */ +}; + +/* UF60xx */ +static const struct chip_device_regs_t unifi_device_regs_v22_v23 = +{ + 0xFE81, /* GBL_CHIP_VERSION */ + 0xF84F, /* GBL_MISC_ENABLES */ + 0xF81D, /* DBG_EMU_CMD */ + { + 0xF81E, /* HOST.DBG_PROC_SELECT */ + 0xF81F, /* HOST.DBG_STOP_STATUS */ + 0xF8AC, /* HOST.WINDOW1_PAGE */ + 0xF8AD, /* HOST.WINDOW2_PAGE */ + 0xF8AE, /* HOST.WINDOW3_PAGE */ + 0xF8AF /* HOST.IO_LOG_ADDR */ + }, + { + 0xF830, /* SPI.DBG_PROC_SELECT */ + 0xF831, /* SPI.DBG_STOP_STATUS */ + 0xF8F9, /* SPI.WINDOW1_PAGE */ + 0xF8FA, /* SPI.WINDOW2_PAGE */ + 0xF8FB, /* SPI.WINDOW3_PAGE */ + 0xF8FC /* SPI.IO_LOG_ADDR */ + }, + 0xF82F, /* DBG_RESET */ + 0x0001, /* > DBG_RESET_VALUE */ + 0x0000, /* DBG_RESET_WARN */ + 0x0000, /* DBG_RESET_WARN_VALUE */ + 0xF82F, /* DBG_RESET_RESULT */ + 0xFFE9, /* XAP_PCH */ + 0xFFEA, /* XAP_PCL */ + 0x001B, /* PROC_PC_SNOOP */ + 0x0055, /* WATCHDOG_DISABLE */ + 0xF84B, /* MAILBOX0 */ + 0xF84C, /* MAILBOX1 */ + 0xF84D, /* MAILBOX2 */ + 0xF84E, /* MAILBOX3 */ + 0xF92F, /* SDIO_HOST_INT */ + 0xF92B, /* SDIO_FROMHOST_SCRTACH0 / SHARED_IO_INTERRUPT */ + 0xF84D, /* SDIO HIP HANDSHAKE (MAILBOX2) */ + 0xF9FB /* COEX_STATUS */ +}; + +/* Program memory window on UF105x. */ +static const struct window_shift_info_t prog_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] = +{ + { TRUE, 11, 0x0200 }, /* CODE RAM */ + { TRUE, 11, 0x0000 }, /* FLASH */ + { TRUE, 11, 0x0400 }, /* External SRAM */ + { FALSE, 0, 0 }, /* ROM */ + { FALSE, 0, 0 } /* SHARED */ +}; + +/* Shared memory window on UF105x. */ +static const struct window_shift_info_t shared_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] = +{ + { FALSE, 0, 0 }, /* CODE RAM */ + { FALSE, 0, 0 }, /* FLASH */ + { FALSE, 0, 0 }, /* External SRAM */ + { FALSE, 0, 0 }, /* ROM */ + { TRUE, 11, 0x0000 } /* SHARED */ +}; + +/* One of the Generic Windows on UF60xx and later. */ +static const struct window_shift_info_t generic_window_array_unifi_v22_v23[CHIP_HELPER_WT_COUNT] = +{ + { TRUE, 11, 0x3800 }, /* CODE RAM */ + { FALSE, 0, 0 }, /* FLASH */ + { FALSE, 0, 0 }, /* External SRAM */ + { TRUE, 11, 0x2000 }, /* ROM */ + { TRUE, 11, 0x0000 } /* SHARED */ +}; + +/* The three windows on UF105x. */ +static const struct window_info_t prog1_window_unifi_v1_v2 = { 0x0000, 0x2000, 0x0080, prog_window_array_unifi_v1_v2 }; +static const struct window_info_t prog2_window_unifi_v1_v2 = { 0x2000, 0x2000, 0x0000, prog_window_array_unifi_v1_v2 }; +static const struct window_info_t shared_window_unifi_v1_v2 = { 0x4000, 0x2000, 0x0000, shared_window_array_unifi_v1_v2 }; + +/* The three windows on UF60xx and later. */ +static const struct window_info_t generic1_window_unifi_v22_v23 = { 0x0000, 0x2000, 0x0080, generic_window_array_unifi_v22_v23 }; +static const struct window_info_t generic2_window_unifi_v22_v23 = { 0x2000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 }; +static const struct window_info_t generic3_window_unifi_v22_v23 = { 0x4000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 }; + +static const struct chip_device_desc_t chip_device_desc_null = +{ + { FALSE, 0x0000, 0x0000, 0x00 }, + "", + "", + null_counted(), /* init */ + null_counted(), /* reset_prog */ + &unifi_device_regs_null, /* regs */ + { + FALSE, /* has_flash */ + FALSE, /* has_ext_sram */ + FALSE, /* has_rom */ + FALSE, /* has_bt */ + FALSE, /* has_wlan */ + }, + null_counted(), + /* prog_offset */ + { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }, + /* data_offset */ + { + 0x0000 /* ram */ + }, + /* windows */ + { + NULL, + NULL, + NULL + } +}; + +static const struct chip_device_desc_t unifi_device_desc_v1 = +{ + { FALSE, 0xf0ff, 0x1001, 0x01 }, /* UF105x R01 */ + "UF105x", + "UniFi-1", + counted(init_vals_v1), /* init */ + counted(reset_program_v1_or_v2), /* reset_prog */ + &unifi_device_regs_v1, /* regs */ + { + TRUE, /* has_flash */ + TRUE, /* has_ext_sram */ + FALSE, /* has_rom */ + FALSE, /* has_bt */ + TRUE, /* has_wlan */ + }, + counted(unifi_map_address_v1_v2), /* map */ + /* prog_offset */ + { + 0x00100000, /* ram */ + 0x00000000, /* rom (invalid) */ + 0x00000000, /* flash */ + 0x00200000, /* ext_ram */ + }, + /* data_offset */ + { + 0x8000 /* ram */ + }, + /* windows */ + { + &prog1_window_unifi_v1_v2, + &prog2_window_unifi_v1_v2, + &shared_window_unifi_v1_v2 + } +}; + +static const struct chip_device_desc_t unifi_device_desc_v2 = +{ + { FALSE, 0xf0ff, 0x2001, 0x02 }, /* UF2... R02 */ + "UF2...", + "UniFi-2", + counted(init_vals_v2), /* init */ + counted(reset_program_v1_or_v2), /* reset_prog */ + &unifi_device_regs_v2, /* regs */ + { + TRUE, /* has_flash */ + TRUE, /* has_ext_sram */ + FALSE, /* has_rom */ + FALSE, /* has_bt */ + TRUE, /* has_wlan */ + }, + counted(unifi_map_address_v1_v2), /* map */ + /* prog_offset */ + { + 0x00100000, /* ram */ + 0x00000000, /* rom (invalid) */ + 0x00000000, /* flash */ + 0x00200000, /* ext_ram */ + }, + /* data_offset */ + { + 0x8000 /* ram */ + }, + /* windows */ + { + &prog1_window_unifi_v1_v2, + &prog2_window_unifi_v1_v2, + &shared_window_unifi_v1_v2 + } +}; + +static const struct chip_device_desc_t unifi_device_desc_v3 = +{ + { FALSE, 0xf0ff, 0x3001, 0x02 }, /* UF2... R03 */ + "UF2...", + "UniFi-3", + counted(init_vals_v2), /* init */ + counted(reset_program_v1_or_v2), /* reset_prog */ + &unifi_device_regs_v2, /* regs */ + { + TRUE, /* has_flash */ + TRUE, /* has_ext_sram */ + FALSE, /* has_rom */ + FALSE, /* has_bt */ + TRUE, /* has_wlan */ + }, + counted(unifi_map_address_v1_v2), /* map */ + /* prog_offset */ + { + 0x00100000, /* ram */ + 0x00000000, /* rom (invalid) */ + 0x00000000, /* flash */ + 0x00200000, /* ext_ram */ + }, + /* data_offset */ + { + 0x8000 /* ram */ + }, + /* windows */ + { + &prog1_window_unifi_v1_v2, + &prog2_window_unifi_v1_v2, + &shared_window_unifi_v1_v2 + } +}; + +static const struct chip_device_desc_t unifi_device_desc_v22 = +{ + { FALSE, 0x00ff, 0x0022, 0x07 }, /* UF60xx */ + "UF60xx", + "UniFi-4", + counted(init_vals_v22_v23), /* init */ + null_counted(), /* reset_prog */ + &unifi_device_regs_v22_v23, /* regs */ + { + FALSE, /* has_flash */ + FALSE, /* has_ext_sram */ + TRUE, /* has_rom */ + FALSE, /* has_bt */ + TRUE, /* has_wlan */ + }, + counted(unifi_map_address_v22_v23), /* map */ + /* prog_offset */ + { + 0x00C00000, /* ram */ + 0x00000000, /* rom */ + 0x00000000, /* flash (invalid) */ + 0x00000000, /* ext_ram (invalid) */ + }, + /* data_offset */ + { + 0x8000 /* ram */ + }, + /* windows */ + { + &generic1_window_unifi_v22_v23, + &generic2_window_unifi_v22_v23, + &generic3_window_unifi_v22_v23 + } +}; + +static const struct chip_device_desc_t unifi_device_desc_v23 = +{ + { FALSE, 0x00ff, 0x0023, 0x08 }, /* UF.... */ + "UF....", + "UF.... (5)", + counted(init_vals_v22_v23), /* init */ + null_counted(), /* reset_prog */ + &unifi_device_regs_v22_v23, /* regs */ + { + FALSE, /* has_flash */ + FALSE, /* has_ext_sram */ + TRUE, /* has_rom */ + TRUE, /* has_bt */ + TRUE, /* has_wlan */ + }, + counted(unifi_map_address_v22_v23), + /* prog_offset */ + { + 0x00C00000, /* ram */ + 0x00000000, /* rom */ + 0x00000000, /* flash (invalid) */ + 0x00000000, /* ext_sram (invalid) */ + }, + /* data_offset */ + { + 0x8000 /* ram */ + }, + /* windows */ + { + &generic1_window_unifi_v22_v23, + &generic2_window_unifi_v22_v23, + &generic3_window_unifi_v22_v23 + } +}; + +static const struct chip_device_desc_t hyd_wlan_subsys_desc_v1 = +{ + { FALSE, 0x00ff, 0x0044, 0x00 }, /* UF.... */ + "HYD...", + "HYD... ", + counted(init_vals_v22_v23), /* init */ + null_counted(), /* reset_prog */ + &unifi_device_regs_v22_v23, /* regs */ + { + FALSE, /* has_flash */ + FALSE, /* has_ext_sram */ + TRUE, /* has_rom */ + FALSE, /* has_bt */ + TRUE, /* has_wlan */ + }, + counted(unifi_map_address_v22_v23), + /* prog_offset */ + { + 0x00C00000, /* ram */ + 0x00000000, /* rom */ + 0x00000000, /* flash (invalid) */ + 0x00000000, /* ext_sram (invalid) */ + }, + /* data_offset */ + { + 0x8000 /* ram */ + }, + /* windows */ + { + &generic1_window_unifi_v22_v23, + &generic2_window_unifi_v22_v23, + &generic3_window_unifi_v22_v23 + } +}; + + +/* This is the list of all chips that we know about. I'm + assuming that the order here will be important - we + might have multiple entries witrh the same SDIO id for + instance. The first one in this list will be the one + that is returned if a search is done on only that id. + The client will then have to call GetVersionXXX again + but with more detailed info. + + I don't know if we need to signal this up to the client + in some way? + + (We get the SDIO id before we know anything else about + the chip. We might not be able to read any of the other + registers at first, but we still need to know about the + chip). */ +static const struct chip_device_desc_t *chip_ver_to_desc[] = +{ + &unifi_device_desc_v1, /* UF105x R01 */ + &unifi_device_desc_v2, /* UF2... R02 */ + &unifi_device_desc_v3, /* UF2... R03 */ + &unifi_device_desc_v22, /* UF60xx */ + &unifi_device_desc_v23, /* UF.... */ + &hyd_wlan_subsys_desc_v1 +}; + +ChipDescript* ChipHelper_GetVersionSdio(CsrUint8 sdio_ver) +{ + CsrUint32 i; + + for (i = 0; i < nelem(chip_ver_to_desc); i++) + { + if (chip_ver_to_desc[i]->chip_version.sdio == sdio_ver) + { + return chip_ver_to_desc[i]; + } + } + + return &chip_device_desc_null; +} + + +ChipDescript* ChipHelper_GetVersionAny(CsrUint16 from_FF9A, CsrUint16 from_FE81) +{ + CsrUint32 i; + + if ((from_FF9A & 0xFF00) != 0) + { + for (i = 0; i < nelem(chip_ver_to_desc); i++) + { + if (chip_ver_to_desc[i]->chip_version.pre_bc7 && + ((from_FF9A & chip_ver_to_desc[i]->chip_version.mask) == + chip_ver_to_desc[i]->chip_version.result)) + { + return chip_ver_to_desc[i]; + } + } + } + else + { + for (i = 0; i < nelem(chip_ver_to_desc); i++) + { + if (!chip_ver_to_desc[i]->chip_version.pre_bc7 && + ((from_FE81 & chip_ver_to_desc[i]->chip_version.mask) == + chip_ver_to_desc[i]->chip_version.result)) + { + return chip_ver_to_desc[i]; + } + } + } + + return &chip_device_desc_null; +} + + +ChipDescript* ChipHelper_GetVersionUniFi(CsrUint16 ver) +{ + return ChipHelper_GetVersionAny(0x0000, ver); +} + + +ChipDescript* ChipHelper_Null() +{ + return &chip_device_desc_null; +} + + +ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age bc_age, CsrUint16 version) +{ + if (bc_age == chip_helper_bluecore_pre_bc7) + { + return ChipHelper_GetVersionAny(version, 0x0000); + } + else + { + return ChipHelper_GetVersionAny(0x0000, version); + } +} + + +/* Expand the DEF0 functions into simple code to return the + correct thing. The DEF1 functions expand to nothing in + this X macro expansion. */ +#define CHIP_HELPER_DEF0_C_DEF(ret_type, name, info) \ + ret_type ChipHelper_ ## name(ChipDescript * chip_help) \ + { \ + return chip_help->info; \ + } +#define CHIP_HELPER_DEF1_C_DEF(ret_type, name, type1, name1) + +CHIP_HELPER_LIST(C_DEF) + +/* + * Map register addresses between HOST and SPI access. + */ +CsrUint16 ChipHelper_MapAddress_SPI2HOST(ChipDescript *chip_help, CsrUint16 addr) +{ + CsrUint32 i; + for (i = 0; i < chip_help->map.len; i++) + { + if (chip_help->map.vals[i].spi == addr) + { + return chip_help->map.vals[i].host; + } + } + return addr; +} + + +CsrUint16 ChipHelper_MapAddress_HOST2SPI(ChipDescript *chip_help, CsrUint16 addr) +{ + CsrUint32 i; + for (i = 0; i < chip_help->map.len; i++) + { + if (chip_help->map.vals[i].host == addr) + { + return chip_help->map.vals[i].spi; + } + } + return addr; +} + + +/* The address returned by this function is the start of the + window in the address space, that is where we can start + accessing data from. If a section of the window at the + start is unusable because something else is cluttering up + the address map then that is taken into account and this + function returns that address justt past that. */ +CsrUint16 ChipHelper_WINDOW_ADDRESS(ChipDescript *chip_help, + enum chip_helper_window_index window) +{ + if (window < CHIP_HELPER_WINDOW_COUNT && + chip_help->windows[window] != NULL) + { + return chip_help->windows[window]->address + chip_help->windows[window]->blocked; + } + return 0; +} + + +/* This returns the size of the window minus any blocked section */ +CsrUint16 ChipHelper_WINDOW_SIZE(ChipDescript *chip_help, + enum chip_helper_window_index window) +{ + if (window < CHIP_HELPER_WINDOW_COUNT && + chip_help->windows[window] != NULL) + { + return chip_help->windows[window]->size - chip_help->windows[window]->blocked; + } + return 0; +} + + +/* Get the register writes we should do to make sure that + the chip is running with most clocks on. */ +CsrUint32 ChipHelper_ClockStartupSequence(ChipDescript *chip_help, + const struct chip_helper_init_values **val) +{ + *val = chip_help->init.vals; + return chip_help->init.len; +} + + +/* Get the set of values tat we should write to the chip to perform a reset. */ +CsrUint32 ChipHelper_HostResetSequence(ChipDescript *chip_help, + const struct chip_helper_reset_values **val) +{ + *val = chip_help->reset_prog.vals; + return chip_help->reset_prog.len; +} + + +/* Decode a windowed access to the chip. */ +CsrInt32 ChipHelper_DecodeWindow(ChipDescript *chip_help, + enum chip_helper_window_index window, + enum chip_helper_window_type type, + CsrUint32 offset, + CsrUint16 *page, CsrUint16 *addr, CsrUint32 *len) +{ + const struct window_info_t *win; + const struct window_shift_info_t *mode; + CsrUint16 of, pg; + + if (window >= CHIP_HELPER_WINDOW_COUNT) + { + return FALSE; + } + if ((win = chip_help->windows[window]) == NULL) + { + return FALSE; + } + if (type >= CHIP_HELPER_WT_COUNT) + { + return FALSE; + } + if ((mode = &win->mode[type]) == NULL) + { + return FALSE; + } + if (!mode->allowed) + { + return FALSE; + } + + pg = (CsrUint16)(offset >> mode->page_shift) + mode->page_offset; + of = (CsrUint16)(offset & ((1 << mode->page_shift) - 1)); + /* If 'blocked' is zero this does nothing, else decrease + the page register and increase the offset until we aren't + in the blocked region of the window. */ + while (of < win->blocked) + { + of += 1 << mode->page_shift; + pg--; + } + *page = pg; + *addr = win->address + of; + *len = win->size - of; + return TRUE; +} + + diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper.h b/drivers/staging/csr/csr_wifi_hip_chiphelper.h new file mode 100644 index 000000000000..6166d5587571 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_chiphelper.h @@ -0,0 +1,471 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_HIP_CHIPHELPER_H__ +#define CSR_WIFI_HIP_CHIPHELPER_H__ + + +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The age of the BlueCore chip. This is probably not useful, if + you know the age then you can probably work out the version directly. */ +enum chip_helper_bluecore_age +{ + chip_helper_bluecore_pre_bc7, + chip_helper_bluecore_bc7_or_later +}; + +/* We support up to three windowed regions at the moment. + Don't reorder these - they're used to index into an array. */ +enum chip_helper_window_index +{ + CHIP_HELPER_WINDOW_1 = 0, + CHIP_HELPER_WINDOW_2 = 1, + CHIP_HELPER_WINDOW_3 = 2, + CHIP_HELPER_WINDOW_COUNT = 3 +}; + +/* These are the things that we can access through a window. + Don't reorder these - they're used to index into an array. */ +enum chip_helper_window_type +{ + CHIP_HELPER_WT_CODE_RAM = 0, + CHIP_HELPER_WT_FLASH = 1, + CHIP_HELPER_WT_EXT_SRAM = 2, + CHIP_HELPER_WT_ROM = 3, + CHIP_HELPER_WT_SHARED = 4, + CHIP_HELPER_WT_COUNT = 5 +}; + +/* Commands to stop and start the XAP */ +enum chip_helper_dbg_emu_cmd_enum +{ + CHIP_HELPER_DBG_EMU_CMD_XAP_STEP_MASK = 0x0001, + CHIP_HELPER_DBG_EMU_CMD_XAP_RUN_B_MASK = 0x0002, + CHIP_HELPER_DBG_EMU_CMD_XAP_BRK_MASK = 0x0004, + CHIP_HELPER_DBG_EMU_CMD_XAP_WAKEUP_MASK = 0x0008 +}; + +/* Bitmasks for Stop and sleep status: DBG_SPI_STOP_STATUS & DBG_HOST_STOP_STATUS */ +enum chip_helper_dbg_stop_status_enum +{ + CHIP_HELPER_DBG_STOP_STATUS_NONE_MASK = 0x0000, + CHIP_HELPER_DBG_STOP_STATUS_P0_MASK = 0x0001, + CHIP_HELPER_DBG_STOP_STATUS_P1_MASK = 0x0002, + CHIP_HELPER_DBG_STOP_STATUS_P2_MASK = 0x0004, + CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P0_MASK = 0x0008, + CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P1_MASK = 0x0010, + CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P2_MASK = 0x0020, + /* Legacy names/alias */ + CHIP_HELPER_DBG_STOP_STATUS_MAC_MASK = 0x0001, + CHIP_HELPER_DBG_STOP_STATUS_PHY_MASK = 0x0002, + CHIP_HELPER_DBG_STOP_STATUS_BT_MASK = 0x0004, + CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_MAC_MASK = 0x0008, + CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_PHY_MASK = 0x0010, + CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_BT_MASK = 0x0020 +}; + +/* Codes to disable the watchdog */ +enum chip_helper_watchdog_disable_enum +{ + CHIP_HELPER_WATCHDOG_DISABLE_CODE1 = 0x6734, + CHIP_HELPER_WATCHDOG_DISABLE_CODE2 = 0xD6BF, + CHIP_HELPER_WATCHDOG_DISABLE_CODE3 = 0xC31E +}; + +/* Other bits have changed between versions */ +enum chip_helper_gbl_misc_enum +{ + CHIP_HELPER_GBL_MISC_SPI_STOP_OUT_EN_MASK = 0x0001, + CHIP_HELPER_GBL_MISC_MMU_INIT_DONE_MASK = 0x0004 +}; + +/* Coex status register, contains interrupt status and reset pullup status. + * CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK can be used to check + * for WAPI on R03 chips and later. */ +enum chip_helper_coex_status_mask_enum +{ + CHIP_HELPER_COEX_STATUS_RST_PULLS_LSB_MASK = 0x0001, + CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK = 0x0008, + CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_LSB_MASK = 0x0010, + CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_MSB_MASK = 0x0080, + CHIP_HELPER_COEX_STATUS_INT_UART_MASK = 0x0100, + CHIP_HELPER_COEX_STATUS_INT_BT_LEG_MASK = 0x0200 +}; + +/* How to select the different CPUs */ +enum chip_helper_dbg_proc_sel_enum +{ + CHIP_HELPER_DBG_PROC_SEL_MAC = 0, + CHIP_HELPER_DBG_PROC_SEL_PHY = 1, + CHIP_HELPER_DBG_PROC_SEL_BT = 2, + CHIP_HELPER_DBG_PROC_SEL_NONE = 2, + CHIP_HELPER_DBG_PROC_SEL_BOTH = 3 +}; + +/* These are the only registers that we have to know the + address of before we know the chip version. */ +enum chip_helper_fixed_registers +{ + /* This is the address of GBL_CHIP_VERISON on BC7, + UF105x, UF60xx and + anything later than that. */ + CHIP_HELPER_UNIFI_GBL_CHIP_VERSION = 0xFE81, + + CHIP_HELPER_OLD_BLUECORE_GBL_CHIP_VERSION = 0xFF9A + + /* This isn't used at the moment (but might be needed + to distinguish the BlueCore sub version?) */ + /* CHIP_HELPER_OLD_BLUECORE_ANA_VERSION_ID = 0xFF7D */ +}; + +/* Address-value pairs for defining initialisation values */ +struct chip_helper_init_values +{ + CsrUint16 addr; + CsrUint16 value; +}; + +/* A block of data that should be written to the device */ +struct chip_helper_reset_values +{ + CsrUint32 gp_address; + CsrUint32 len; + const CsrUint16 *data; +}; + +/* + * This is the C API. + */ + +/* opaque type */ +typedef const struct chip_device_desc_t ChipDescript; + +/* Return a NULL descriptor */ +ChipDescript* ChipHelper_Null(void); + +/* This should get the correct version for any CSR chip. + The two parameters are what is read from addresses + 0xFF9A and 0xFE81 (OLD_BLUECORE_GBL_CHIP_VERSION and + UNIFI_GBL_CHIP_VERSION). These should give a unique identity + for most (all?) chips. + + FF9A is the old GBL_CHIP_VERSION register. If the high + eight bits are zero then the chip is a new (BC7 +) one + and FE81 is the _new_ GBL_CHIP_VERSION register. */ +ChipDescript* ChipHelper_GetVersionAny(CsrUint16 from_FF9A, CsrUint16 from_FE81); + +/* The chip is a UniFi, but we don't know which type + The parameter is the value of UNIFI_GBL_CHIP_VERSION (0xFE81) */ +ChipDescript* ChipHelper_GetVersionUniFi(CsrUint16 version); + +/* This gets the version from the SDIO device id. This only + gives quite a coarse grained version, so we should update once + we hav access to the function N registers. */ +ChipDescript* ChipHelper_GetVersionSdio(CsrUint8 sdio_version); + +/* The chip is some sort of BlueCore. If "age" is "pre_bc7" then + "version" is what was read from FF9A. If "age" is bc7_or_later + then "version" is read from FE81. If we don't know if we're pre + or post BC7 then we should use "GetVersionAny". */ +ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age age, + CsrUint16 version); + +/* The main functions of this class are built with an X macro. This + means we can generate the C and C++ versions from the same source + without the two diverging. + + The DEF0 functions are simple and take no parameters. The first + parameter to the macro is the return type. The second parameter + is the function name and the third parameter is where to get the + info from (this is hidden from the user). + + The DEF1 functions take one parameter. This time the third macro + parameter is the type of this parameter, and the fourth macro + parameter is the name of the parameter. The bodies of these + functions are hand written. */ +#define CHIP_HELPER_LIST(m) \ + CHIP_HELPER_DEF0(m, (const CsrCharString *, FriendlyName, friendly_name)) \ + CHIP_HELPER_DEF0(m, (const CsrCharString *, MarketingName, marketing_name)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_EMU_CMD, regs->dbg_emu_cmd)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_HOST_PROC_SELECT, regs->host.dbg_proc_select)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_HOST_STOP_STATUS, regs->host.dbg_stop_status)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, HOST_WINDOW1_PAGE, regs->host.window1_page)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, HOST_WINDOW2_PAGE, regs->host.window2_page)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, HOST_WINDOW3_PAGE, regs->host.window3_page)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, HOST_IO_LOG_ADDR, regs->host.io_log_addr)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_SPI_PROC_SELECT, regs->spi.dbg_proc_select)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_SPI_STOP_STATUS, regs->spi.dbg_stop_status)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SPI_WINDOW1_PAGE, regs->spi.window1_page)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SPI_WINDOW2_PAGE, regs->spi.window2_page)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SPI_WINDOW3_PAGE, regs->spi.window3_page)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SPI_IO_LOG_ADDR, regs->spi.io_log_addr)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_RESET, regs->dbg_reset)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_RESET_VALUE, regs->dbg_reset_value)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_RESET_WARN, regs->dbg_reset_warn)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_RESET_WARN_VALUE, regs->dbg_reset_warn_value)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DBG_RESET_RESULT, regs->dbg_reset_result)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, WATCHDOG_DISABLE, regs->watchdog_disable)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, PROC_PC_SNOOP, regs->proc_pc_snoop)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, GBL_CHIP_VERSION, regs->gbl_chip_version)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, GBL_MISC_ENABLES, regs->gbl_misc_enables)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, XAP_PCH, regs->xap_pch)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, XAP_PCL, regs->xap_pcl)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, MAILBOX0, regs->mailbox0)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, MAILBOX1, regs->mailbox1)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, MAILBOX2, regs->mailbox2)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, MAILBOX3, regs->mailbox3)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SDIO_HIP_HANDSHAKE, regs->sdio_hip_handshake)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SDIO_HOST_INT, regs->sdio_host_int)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, COEX_STATUS, regs->coex_status)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, SHARED_IO_INTERRUPT, regs->shared_io_interrupt)) \ + CHIP_HELPER_DEF0(m, (CsrUint32, PROGRAM_MEMORY_RAM_OFFSET, prog_offset.ram)) \ + CHIP_HELPER_DEF0(m, (CsrUint32, PROGRAM_MEMORY_ROM_OFFSET, prog_offset.rom)) \ + CHIP_HELPER_DEF0(m, (CsrUint32, PROGRAM_MEMORY_FLASH_OFFSET, prog_offset.flash)) \ + CHIP_HELPER_DEF0(m, (CsrUint32, PROGRAM_MEMORY_EXT_SRAM_OFFSET, prog_offset.ext_sram)) \ + CHIP_HELPER_DEF0(m, (CsrUint16, DATA_MEMORY_RAM_OFFSET, data_offset.ram)) \ + CHIP_HELPER_DEF0(m, (CsrInt32, HasFlash, bools.has_flash)) \ + CHIP_HELPER_DEF0(m, (CsrInt32, HasExtSram, bools.has_ext_sram)) \ + CHIP_HELPER_DEF0(m, (CsrInt32, HasRom, bools.has_rom)) \ + CHIP_HELPER_DEF0(m, (CsrInt32, HasBt, bools.has_bt)) \ + CHIP_HELPER_DEF0(m, (CsrInt32, HasWLan, bools.has_wlan)) \ + CHIP_HELPER_DEF1(m, (CsrUint16, WINDOW_ADDRESS, enum chip_helper_window_index, window)) \ + CHIP_HELPER_DEF1(m, (CsrUint16, WINDOW_SIZE, enum chip_helper_window_index, window)) \ + CHIP_HELPER_DEF1(m, (CsrUint16, MapAddress_SPI2HOST, CsrUint16, addr)) \ + CHIP_HELPER_DEF1(m, (CsrUint16, MapAddress_HOST2SPI, CsrUint16, addr)) \ + CHIP_HELPER_DEF1(m, (CsrUint32, ClockStartupSequence, const struct chip_helper_init_values **, val)) \ + CHIP_HELPER_DEF1(m, (CsrUint32, HostResetSequence, const struct chip_helper_reset_values **, val)) + +/* Some magic to help the expansion */ +#define CHIP_HELPER_DEF0(a, b) \ + CHIP_HELPER_DEF0_ ## a b +#define CHIP_HELPER_DEF1(a, b) \ + CHIP_HELPER_DEF1_ ## a b + +/* Macros so that when we expand the list we get "C" function prototypes. */ +#define CHIP_HELPER_DEF0_C_DEC(ret_type, name, info) \ + ret_type ChipHelper_ ## name(ChipDescript * chip_help); +#define CHIP_HELPER_DEF1_C_DEC(ret_type, name, type1, name1) \ + ret_type ChipHelper_ ## name(ChipDescript * chip_help, type1 name1); + +CHIP_HELPER_LIST(C_DEC) + +/* FriendlyName + MarketingName + + These two functions return human readable strings that describe + the chip. FriendlyName returns something that a software engineer + at CSR might understand. MarketingName returns something more like + an external name for a CSR chip. +*/ +/* DBG_EMU_CMD + WATCHDOG_DISABLE + PROC_PC_SNOOP + GBL_CHIP_VERSION + XAP_PCH + XAP_PCL + + These registers are used to control the XAPs. +*/ +/* DBG_HOST_PROC_SELECT DBG_HOST_STOP_STATUS + HOST_WINDOW1_PAGE HOST_WINDOW2_PAGE HOST_WINDOW3_PAGE + HOST_IO_LOG_ADDR + DBG_SPI_PROC_SELECT DBG_SPI_STOP_STATUS + SPI_WINDOW1_PAGE SPI_WINDOW2_PAGE SPI_WINDOW3_PAGE + SPI_IO_LOG_ADDR + + These register are used to control the XAPs and the memory + windows, normally while debugging the code on chip. There + are two versons of these registers, one for access via SPI + and another for access via the host interface. +*/ +/* DBG_RESET + DBG_RESET_VALUE + DBG_RESET_WARN + DBG_RESET_WARN_VALUE + DBG_RESET_RESULT + + These registers are used to reset the XAP. This can be + quite complex for some chips. If DBG_RESET_WARN is non + zero the DBG_RESET_WARN_VALUE should be written to address + DBG_RESET_WARN before the reset is perfeormed. DBG_RESET_VALUE + should then be written to DBG_RESET to make the reset happen. + The DBG_RESET_RESULT register should contain 0 if the reset + was successful. +*/ +/* GBL_MISC_ENABLES + + This register controls some special chip features. It + should be used with care is it changes quite a lot between + chip versions. +*/ +/* MAILBOX0 + MAILBOX1 + MAILBOX2 + MAILBOX3 + + The mailbox registers are for communication between the host + and the firmware. There use is described in part by the host + interface protcol specifcation. +*/ +/* SDIO_HIP_HANDSHAKE + + This is one of the more important SDIO HIP registers. On some + chips it has the same value as one of the mailbox registers + and on other chips it is different. +*/ +/* SDIO_HOST_INT + SHARED_IO_INTERRUPT + + These registers are used by some versions of the host interface + protocol specification. Their names should probably be changed + to hide the registers and to expose the functions more. +*/ +/* COEX_STATUS + + Coex status register, contains interrupt status and reset + pullup status. The latter is used to detect WAPI. +*/ +/* PROGRAM_MEMORY_RAM_OFFSET + PROGRAM_MEMORY_ROM_OFFSET + PROGRAM_MEMORY_FLASH_OFFSET + PROGRAM_MEMORY_EXT_SRAM_OFFSET + DATA_MEMORY_RAM_OFFSET + + These are constants that describe the offset of the different + memory types in the two different address spaces. +*/ +/* HasFlash HasExtSram HasRom + HasBt HasWLan + + These are a set of bools describing the chip. +*/ +/* WINDOW_ADDRESS WINDOW_SIZE + + These two functions return the size and address of the windows. + The address is the address of the lowest value in the address + map that is part of the window and the size is the number of + visible words. + + Some of the windows have thier lowest portion covered by + registers. For these windows address is the first address + after the registers and size is the siave excluding the part + covered by registers. +*/ +/* MapAddress_SPI2HOST + MapAddress_HOST2SPI + + The debugging interface is duplicated on UniFi and later chips + so that there are two versions - one over the SPI interaface and + the other over the SDIO interface. These functions map the + registers between these two interfaces. +*/ +/* ClockStartupSequence + + This function returns the list of register value pairs that + should be forced into UniFi to enable SPI communication. This + set of registers is not needed if the firmware is running, but + will be needed if the device is being booted from cold. These + register writes enable the clocks and setup the PLL to a basic + working state. SPI access might be unreliable until these writes + have occured (And they may take mulitple goes). +*/ +/* HostResetSequence + + This returns a number of chunks of data and generic pointers. + All of the XAPs should be stopped. The data should be written + to the generic pointers. The instruction pointer for the MAC + should then be set to the start of program memory and then the + MAC should be "go"d. This will reset the chip in a reliable + and orderly manner without resetting the SDIO interface. It + is therefore not needed if the chip is being accessed by the + SPI interface (the DBG_RESET_ mechanism can be used instead). +*/ + +/* The Decode Window function is more complex. For the window + 'window' it tries to return the address and page register + value needed to see offset 'offset' of memory type 'type'. + + It return 1 on success and 0 on failure. 'page' is what + should be written to the page register. 'addr' is the + address in the XAPs 16 address map to read from. 'len' + is the length that we can read without having to change + the page registers. */ +CsrInt32 ChipHelper_DecodeWindow(ChipDescript *chip_help, + enum chip_helper_window_index window, + enum chip_helper_window_type type, + CsrUint32 offset, + CsrUint16 *page, CsrUint16 *addr, CsrUint32 *len); + +#ifdef __cplusplus +/* Close the extern "C" */ +} + +/* + * This is the C++ API. + */ + +class ChipHelper +{ +public: + /* If this constructor is used then a GetVersionXXX function + should be called next. */ + ChipHelper(); + + /* copy constructor */ + ChipHelper(ChipDescript * desc); + + /* The default constructor assume a BC7 / UF105x series chip + and that the number given is the value of UNIFI_GBL_CHIP_VERSION + (0xFE81) */ + ChipHelper(CsrUint16 version); + + /* This returns the C interface magic token from a C++ instance. */ + ChipDescript* GetDescript() const + { + return m_desc; + } + + + /* Clear out theis class (set it to the null token). */ + void ClearVersion(); + + /* Load this class with data for a specific chip. */ + void GetVersionAny(CsrUint16 from_FF9A, CsrUint16 from_FE81); + void GetVersionUniFi(CsrUint16 version); + void GetVersionBlueCore(chip_helper_bluecore_age age, CsrUint16 version); + void GetVersionSdio(CsrUint8 sdio_version); + + /* Helpers to build the definitions of the member functions. */ +#define CHIP_HELPER_DEF0_CPP_DEC(ret_type, name, info) \ + ret_type name() const; +#define CHIP_HELPER_DEF1_CPP_DEC(ret_type, name, type1, name1) \ + ret_type name(type1 name1) const; + + CHIP_HELPER_LIST(CPP_DEC) + + + /* The DecodeWindow function, see the description of the C version. */ + CsrInt32 DecodeWindow(chip_helper_window_index window, + chip_helper_window_type type, + CsrUint32 offset, + CsrUint16 &page, CsrUint16 &addr, CsrUint32 &len) const; + +private: + ChipDescript *m_desc; +}; + +#endif /* __cplusplus */ + +#endif diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h b/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h new file mode 100644 index 000000000000..7ab8173328c4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h @@ -0,0 +1,208 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__ +#define CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__ + + +#include "csr_wifi_hip_chiphelper.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* This GP stuff should be somewhere else? */ + +/* Memory spaces encoded in top byte of Generic Pointer type */ +#define UNIFI_SH_DMEM 0x01 /* Shared Data Memory */ +#define UNIFI_EXT_FLASH 0x02 /* External FLASH */ +#define UNIFI_EXT_SRAM 0x03 /* External SRAM */ +#define UNIFI_REGISTERS 0x04 /* Registers */ +#define UNIFI_PHY_DMEM 0x10 /* PHY Data Memory */ +#define UNIFI_PHY_PMEM 0x11 /* PHY Program Memory */ +#define UNIFI_PHY_ROM 0x12 /* PHY ROM */ +#define UNIFI_MAC_DMEM 0x20 /* MAC Data Memory */ +#define UNIFI_MAC_PMEM 0x21 /* MAC Program Memory */ +#define UNIFI_MAC_ROM 0x22 /* MAC ROM */ +#define UNIFI_BT_DMEM 0x30 /* BT Data Memory */ +#define UNIFI_BT_PMEM 0x31 /* BT Program Memory */ +#define UNIFI_BT_ROM 0x32 /* BT ROM */ + +#define MAKE_GP(R, O) (((UNIFI_ ## R) << 24) | (O)) +#define GP_OFFSET(GP) ((GP) & 0xFFFFFF) +#define GP_SPACE(GP) (((GP) >> 24) & 0xFF) + + +/* Address value pairs */ +struct val_array_t +{ + CsrUint32 len; + const struct chip_helper_init_values *vals; +}; + +/* Just a (counted) CsrUint16 array */ +struct data_array_t +{ + CsrUint32 len; + const CsrUint16 *vals; +}; + +struct reset_prog_t +{ + CsrUint32 len; + const struct chip_helper_reset_values *vals; +}; + +/* The addresses of registers that are equivalent but on + different host transports. */ +struct chip_map_address_t +{ + CsrUint16 spi, host; +}; + +struct map_array_t +{ + CsrUint32 len; + const struct chip_map_address_t *vals; +}; + +struct chip_device_regs_per_transport_t +{ + CsrUint16 dbg_proc_select; + CsrUint16 dbg_stop_status; + CsrUint16 window1_page; /* PROG_PMEM1 or GW1 */ + CsrUint16 window2_page; /* PROG_PMEM2 or GW2 */ + CsrUint16 window3_page; /* SHARED or GW3 */ + CsrUint16 io_log_addr; +}; + +struct chip_device_regs_t +{ + CsrUint16 gbl_chip_version; + CsrUint16 gbl_misc_enables; + CsrUint16 dbg_emu_cmd; + struct chip_device_regs_per_transport_t host; + struct chip_device_regs_per_transport_t spi; + CsrUint16 dbg_reset; + CsrUint16 dbg_reset_value; + CsrUint16 dbg_reset_warn; + CsrUint16 dbg_reset_warn_value; + CsrUint16 dbg_reset_result; + CsrUint16 xap_pch; + CsrUint16 xap_pcl; + CsrUint16 proc_pc_snoop; + CsrUint16 watchdog_disable; + CsrUint16 mailbox0; + CsrUint16 mailbox1; + CsrUint16 mailbox2; + CsrUint16 mailbox3; + CsrUint16 sdio_host_int; + CsrUint16 shared_io_interrupt; + CsrUint16 sdio_hip_handshake; + CsrUint16 coex_status; /* Allows WAPI detection */ +}; + +/* If allowed is false then this window does not provide this + type of access. + This describes how addresses should be shifted to make the + "page" address. The address is shifted left by 'page_shift' + and then has 'page_offset' added. This value should then be + written to the page register. */ +struct window_shift_info_t +{ + CsrInt32 allowed; + CsrUint32 page_shift; + CsrUint16 page_offset; +}; + +/* Each window has an address and size. These are obvious. It then + has a description for each type of memory that might be accessed + through it. There might also be a start to the offset of the window. + This means that that number of addresses at the start of the window + are unusable. */ +struct window_info_t +{ + CsrUint16 address; + CsrUint16 size; + CsrUint16 blocked; + const struct window_shift_info_t *mode; +}; + +/* If GBL_CHIP_VERSION and'ed with 'mask' and is equal to 'result' + then this is the correct set of info. If pre_bc7 is true then the + address of GBL_CHIP_VERSION is FF9A, else its FE81. */ +struct chip_version_t +{ + CsrInt32 pre_bc7; + CsrUint16 mask; + CsrUint16 result; + CsrUint8 sdio; +}; + +struct chip_device_desc_t +{ + struct chip_version_t chip_version; + + /* This is a text string that a human might find useful (BC02, UF105x) */ + const CsrCharString *friendly_name; + /* This is what we show to customers */ + const CsrCharString *marketing_name; + + /* Initialisation values to write following a reset */ + struct val_array_t init; + + /* Binary sequence for hard reset */ + struct reset_prog_t reset_prog; + + /* The register map */ + const struct chip_device_regs_t *regs; + + /* Some misc. info on the chip */ + struct + { + CsrUint32 has_flash : 1; + CsrUint32 has_ext_sram : 1; + CsrUint32 has_rom : 1; + CsrUint32 has_bt : 1; + CsrUint32 has_wlan : 1; + } bools; + + /* This table is used to remap register addresses depending on what + host interface is used. On the BC7 and later chips there are + multiple sets of memory window registers, on for each host + interafce (SDIO / SPI). The correct one is needed. */ + struct map_array_t map; + + /* The offsets into the program address space of the different types of memory. + The RAM offset is probably the most useful. */ + struct + { + CsrUint32 ram; + CsrUint32 rom; + CsrUint32 flash; + CsrUint32 ext_sram; + } prog_offset; + + /* The offsets into the data address space of interesting things. */ + struct + { + CsrUint16 ram; + /* maybe add shared / page tables? */ + } data_offset; + + /* Information on the different windows */ + const struct window_info_t *windows[CHIP_HELPER_WINDOW_COUNT]; +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_conversions.h b/drivers/staging/csr/csr_wifi_hip_conversions.h new file mode 100644 index 000000000000..6a4647d5f910 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_conversions.h @@ -0,0 +1,81 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * + * FILE: csr_wifi_hip_conversions.h + * + * PURPOSE: + * This header file provides the macros for converting to and from + * wire format. + * These macros *MUST* work for little-endian AND big-endian hosts. + * + * --------------------------------------------------------------------------- + */ +#ifndef __CSR_WIFI_HIP_CONVERSIONS_H__ +#define __CSR_WIFI_HIP_CONVERSIONS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SIZEOF_UINT16 2 +#define SIZEOF_UINT32 4 +#define SIZEOF_UINT64 8 + +#define SIZEOF_SIGNAL_HEADER 6 +#define SIZEOF_DATAREF 4 + + +/* + * Macro to retrieve the signal ID from a wire-format signal. + */ +#define GET_SIGNAL_ID(_buf) CSR_GET_UINT16_FROM_LITTLE_ENDIAN((_buf)) + +/* + * Macros to retrieve and set the DATAREF fields in a packed (i.e. wire-format) + * HIP signal. + */ +#define GET_PACKED_DATAREF_SLOT(_buf, _ref) \ + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 0)) + +#define GET_PACKED_DATAREF_LEN(_buf, _ref) \ + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 2)) + +#define SET_PACKED_DATAREF_SLOT(_buf, _ref, _slot) \ + CSR_COPY_UINT16_TO_LITTLE_ENDIAN((_slot), ((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 0)) + +#define SET_PACKED_DATAREF_LEN(_buf, _ref, _len) \ + CSR_COPY_UINT16_TO_LITTLE_ENDIAN((_len), ((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 2)) + +#define GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(_buf) \ + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 8)) + +#define GET_PACKED_MA_PACKET_REQUEST_HOST_TAG(_buf) \ + CSR_GET_UINT32_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 4)) + +#define GET_PACKED_MA_PACKET_CONFIRM_HOST_TAG(_buf) \ + CSR_GET_UINT32_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 8)) + +#define GET_PACKED_MA_PACKET_CONFIRM_TRANSMISSION_STATUS(_buf) \ + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 2)) + + +CsrInt32 get_packed_struct_size(const CsrUint8 *buf); +CsrResult read_unpack_signal(const CsrUint8 *ptr, CSR_SIGNAL *sig); +CsrResult write_pack(const CSR_SIGNAL *sig, CsrUint8 *ptr, CsrUint16 *sig_len); + +#ifdef __cplusplus +} +#endif + +#endif /* __CSR_WIFI_HIP_CONVERSIONS_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c new file mode 100644 index 000000000000..fb6f04e1bbf4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_download.c @@ -0,0 +1,834 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_download.c + * + * PURPOSE: + * Routines for downloading firmware to UniFi. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_unifiversion.h" +#include "csr_wifi_hip_card.h" +#include "csr_wifi_hip_xbv.h" + +#undef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH + +static CsrResult do_patch_download(card_t *card, void *dlpriv, + xbv1_t *pfwinfo, CsrUint32 boot_ctrl_addr); + +static CsrResult do_patch_convert_download(card_t *card, + void *dlpriv, xbv1_t *pfwinfo); + +/* + * --------------------------------------------------------------------------- + * _find_in_slut + * + * Find the offset of the appropriate object in the SLUT of a card + * + * Arguments: + * card Pointer to card struct + * psym Pointer to symbol object. + * id set up by caller + * obj will be set up by this function + * pslut Pointer to SLUT address, if 0xffffffff then it must be + * read from the chip. + * Returns: + * CSR_RESULT_SUCCESS on success + * Non-zero on error, + * CSR_WIFI_HIP_RESULT_NOT_FOUND if not found + * --------------------------------------------------------------------------- + */ +static CsrResult _find_in_slut(card_t *card, symbol_t *psym, CsrUint32 *pslut) +{ + CsrUint32 slut_address; + CsrUint16 finger_print; + CsrResult r; + CsrResult csrResult; + + /* Get SLUT address */ + if (*pslut == 0xffffffff) + { + r = card_wait_for_firmware_to_start(card, &slut_address); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Firmware hasn't started\n"); + func_exit_r(r); + return r; + } + *pslut = slut_address; + + /* + * Firmware has started so set the SDIO bus clock to the initial speed, + * faster than UNIFI_SDIO_CLOCK_SAFE_HZ, to speed up the f/w download. + */ + csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ); + if (csrResult != CSR_RESULT_SUCCESS) + { + r = ConvertCsrSdioToCsrHipResult(card, csrResult); + func_exit_r(r); + return r; + } + card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ; + } + else + { + slut_address = *pslut; /* Use previously discovered address */ + } + unifi_trace(card->ospriv, UDBG4, "SLUT addr: 0x%lX\n", slut_address); + + /* + * Check the SLUT fingerprint. + * The slut_address is a generic pointer so we must use unifi_card_read16(). + */ + unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n"); + finger_print = 0; + r = unifi_card_read16(card, slut_address, &finger_print); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read SLUT finger print\n"); + func_exit_r(r); + return r; + } + + if (finger_print != SLUT_FINGERPRINT) + { + unifi_error(card->ospriv, "Failed to find SLUT fingerprint\n"); + func_exit_r(CSR_RESULT_FAILURE); + return CSR_RESULT_FAILURE; + } + + /* Symbol table starts imedately after the fingerprint */ + slut_address += 2; + + while (1) + { + CsrUint16 id; + CsrUint32 obj; + + r = unifi_card_read16(card, slut_address, &id); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + slut_address += 2; + + if (id == CSR_SLT_END) + { + /* End of table reached: not found */ + r = CSR_WIFI_HIP_RESULT_RANGE; + break; + } + + r = unifi_read32(card, slut_address, &obj); + if (r != CSR_RESULT_SUCCESS) + { + func_exit_r(r); + return r; + } + slut_address += 4; + + unifi_trace(card->ospriv, UDBG3, " found SLUT id %02d.%08lx\n", id, obj); + + r = CSR_WIFI_HIP_RESULT_NOT_FOUND; + /* Found search term? */ + if (id == psym->id) + { + unifi_trace(card->ospriv, UDBG1, " matched SLUT id %02d.%08lx\n", id, obj); + psym->obj = obj; + r = CSR_RESULT_SUCCESS; + break; + } + } + + func_exit_r(r); + return r; +} + + +/* + * --------------------------------------------------------------------------- + * do_patch_convert_download + * + * Download the given firmware image to the UniFi, converting from FWDL + * to PTDL XBV format. + * + * Arguments: + * card Pointer to card struct + * dlpriv Pointer to source firmware image + * fwinfo Pointer to source firmware info struct + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on error + * + * Notes: + * --------------------------------------------------------------------------- + */ +static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo) +{ + CsrResult r; + CsrUint32 slut_base = 0xffffffff; + void *pfw; + CsrUint32 psize; + symbol_t sym; + + /* Reset the chip to guarantee that the ROM loader is running */ + r = unifi_init(card); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, + "do_patch_convert_download: failed to re-init UniFi\n"); + return r; + } + + /* If no unifi_helper is running, the firmware version must be read */ + if (card->build_id == 0) + { + CsrUint32 ver = 0; + sym.id = CSR_SLT_BUILD_ID_NUMBER; + sym.obj = 0; /* To be updated by _find_in_slut() */ + + unifi_trace(card->ospriv, UDBG1, "Need f/w version\n"); + + /* Find chip build id entry in SLUT */ + r = _find_in_slut(card, &sym, &slut_base); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to find CSR_SLT_BUILD_ID_NUMBER\n"); + return CSR_RESULT_FAILURE; + } + + /* Read running f/w version */ + r = unifi_read32(card, sym.obj, &ver); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read f/w id\n"); + return CSR_RESULT_FAILURE; + } + card->build_id = ver; + } + + /* Convert the ptest firmware to a patch against the running firmware */ + pfw = xbv_to_patch(card, unifi_fw_read, dlpriv, pfwinfo, &psize); + if (!pfw) + { + unifi_error(card->ospriv, "Failed to convert f/w to patch"); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + else + { + void *desc; + sym.id = CSR_SLT_BOOT_LOADER_CONTROL; + sym.obj = 0; /* To be updated by _find_in_slut() */ + + /* Find boot loader control entry in SLUT */ + r = _find_in_slut(card, &sym, &slut_base); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to find BOOT_LOADER_CONTROL\n"); + return CSR_RESULT_FAILURE; + } + + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to wake UniFi\n"); + } + + /* Get a dlpriv for the patch buffer so that unifi_fw_read() can + * access it. + */ + desc = unifi_fw_open_buffer(card->ospriv, pfw, psize); + if (!desc) + { + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + /* Download the patch */ + unifi_info(card->ospriv, "Downloading converted f/w as patch\n"); + r = unifi_dl_patch(card, desc, sym.obj); + CsrMemFree(pfw); + unifi_fw_close_buffer(card->ospriv, desc); + + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Converted patch download failed\n"); + func_exit_r(r); + return r; + } + else + { + unifi_trace(card->ospriv, UDBG1, "Converted patch downloaded\n"); + } + + /* This command starts the firmware */ + r = unifi_do_loader_op(card, sym.obj + 6, UNIFI_BOOT_LOADER_RESTART); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write loader restart cmd\n"); + } + + func_exit_r(r); + return r; + } +} + + +/* + * --------------------------------------------------------------------------- + * unifi_dl_firmware + * + * Download the given firmware image to the UniFi. + * + * Arguments: + * card Pointer to card struct + * dlpriv A context pointer from the calling function to be + * passed when calling unifi_fw_read(). + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_MEMORY memory allocation failed + * CSR_WIFI_HIP_RESULT_INVALID_VALUE error in XBV file + * CSR_RESULT_FAILURE SDIO error + * + * Notes: + * Stops and resets the chip, does the download and runs the new + * firmware. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_dl_firmware(card_t *card, void *dlpriv) +{ + xbv1_t *fwinfo; + CsrResult r; + + func_enter(); + + fwinfo = CsrMemAlloc(sizeof(xbv1_t)); + if (fwinfo == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for firmware\n"); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + /* + * Scan the firmware file to find the TLVs we are interested in. + * These are: + * - check we support the file format version in VERF + * - SLTP Symbol Lookup Table Pointer + * - FWDL firmware download segments + * - FWOV firmware overlay segment + * - VMEQ Register probe tests to verify matching h/w + */ + r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo); + if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_firmware) + { + unifi_error(card->ospriv, "File type is %s, expected firmware.\n", + fwinfo->mode == xbv_patch?"patch" : "unknown"); + CsrMemFree(fwinfo); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* UF6xxx doesn't accept firmware, only patches. Therefore we convert + * the file to patch format with version numbers matching the current + * running firmware, and then download via the patch mechanism. + * The sole purpose of this is to support production test firmware across + * different ROM releases, the test firmware being provided in non-patch + * format. + */ + if (card->chip_id > SDIO_CARD_ID_UNIFI_2) + { + unifi_info(card->ospriv, "Must convert f/w to patch format\n"); + r = do_patch_convert_download(card, dlpriv, fwinfo); + } + else + { + /* Older UniFi chips allowed firmware to be directly loaded onto the + * chip, which is no longer supported. + */ + unifi_error(card->ospriv, "Only patch downloading supported\n"); + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + CsrMemFree(fwinfo); + func_exit_r(r); + return r; +} /* unifi_dl_firmware() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_dl_patch + * + * Load the given patch set into UniFi. + * + * Arguments: + * card Pointer to card struct + * dlpriv The os specific handle to the firmware file. + * boot_ctrl The address of the boot loader control structure. + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_NO_MEMORY memory allocation failed + * CSR_WIFI_HIP_RESULT_INVALID_VALUE error in XBV file + * CSR_RESULT_FAILURE SDIO error + * + * Notes: + * This ends up telling UniFi to restart. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_dl_patch(card_t *card, void *dlpriv, CsrUint32 boot_ctrl) +{ + xbv1_t *fwinfo; + CsrResult r; + + func_enter(); + + unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl); + + fwinfo = CsrMemAlloc(sizeof(xbv1_t)); + if (fwinfo == NULL) + { + unifi_error(card->ospriv, "Failed to allocate memory for patches\n"); + func_exit(); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + /* + * Scan the firmware file to find the TLVs we are interested in. + * These are: + * - check we support the file format version in VERF + * - FWID The build ID of the ROM that we can patch + * - PTDL patch download segments + */ + r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo); + if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_patch) + { + CsrMemFree(fwinfo); + unifi_error(card->ospriv, "Failed to read in patch file\n"); + func_exit(); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* + * We have to check the build id read from the SLUT against that + * for the patch file. They have to match exactly. + * "card->build_id" == XBV1.PTCH.FWID + */ + if (card->build_id != fwinfo->build_id) + { + unifi_error(card->ospriv, "Wrong patch file for chip (chip = %lu, file = %lu)\n", + card->build_id, fwinfo->build_id); + CsrMemFree(fwinfo); +#ifndef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH + func_exit(); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; +#else + fwinfo = NULL; + dlpriv = NULL; + return CSR_RESULT_SUCCESS; +#endif + } + + r = do_patch_download(card, dlpriv, fwinfo, boot_ctrl); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to patch image\n"); + } + + CsrMemFree(fwinfo); + + func_exit_r(r); + return r; +} /* unifi_dl_patch() */ + + +void* unifi_dl_fw_read_start(card_t *card, CsrInt8 is_fw) +{ + card_info_t card_info; + + unifi_card_info(card, &card_info); + unifi_trace(card->ospriv, UDBG5, + "id=%d, ver=0x%x, fw_build=%u, fw_hip=0x%x, block_size=%d\n", + card_info.chip_id, card_info.chip_version, + card_info.fw_build, card_info.fw_hip_version, + card_info.sdio_block_size); + + return unifi_fw_read_start(card->ospriv, is_fw, &card_info); +} + + +/* + * --------------------------------------------------------------------------- + * safe_read_shared_location + * + * Read a shared memory location repeatedly until we get two readings + * the same. + * + * Arguments: + * card Pointer to card context struct. + * unifi_addr UniFi shared-data-memory address to access. + * pdata Pointer to a byte variable for the value read. + * + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on failure + * --------------------------------------------------------------------------- + */ +static CsrResult safe_read_shared_location(card_t *card, CsrUint32 address, CsrUint8 *pdata) +{ + CsrResult r; + CsrUint16 limit = 1000; + CsrUint8 b, b2; + + *pdata = 0; + + r = unifi_read_8_or_16(card, address, &b); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + while (limit--) + { + r = unifi_read_8_or_16(card, address, &b2); + if (r != CSR_RESULT_SUCCESS) + { + return r; + } + + /* When we have a stable value, return it */ + if (b == b2) + { + *pdata = b; + return CSR_RESULT_SUCCESS; + } + + b = b2; + } + + return CSR_RESULT_FAILURE; +} /* safe_read_shared_location() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_do_loader_op + * + * Send a loader / boot_loader command to the UniFi and wait for + * it to complete. + * + * Arguments: + * card Pointer to card context struct. + * op_addr The address of the loader operation control word. + * opcode The operation to perform. + * + * Returns: + * CSR_RESULT_SUCCESS on success + * CSR_RESULT_FAILURE SDIO error or SDIO/XAP timeout + * --------------------------------------------------------------------------- + */ + +/* + * Ideally instead of sleeping, we want to busy wait. + * Currently there is no framework API to do this. When it becomes available, + * we can use it to busy wait using usecs + */ +#define OPERATION_TIMEOUT_LOOPS (100) /* when OPERATION_TIMEOUT_DELAY==1, (500) otherwise */ +#define OPERATION_TIMEOUT_DELAY 1 /* msec, or 200usecs */ + +CsrResult unifi_do_loader_op(card_t *card, CsrUint32 op_addr, CsrUint8 opcode) +{ + CsrResult r; + CsrInt16 op_retries; + + unifi_trace(card->ospriv, UDBG4, "Loader cmd 0x%0x -> 0x%08x\n", opcode, op_addr); + + /* Set the Operation command byte to the opcode */ + r = unifi_write_8_or_16(card, op_addr, opcode); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to write loader copy command\n"); + return r; + } + + /* Wait for Operation command byte to be Idle */ + /* Typically takes ~100us */ + op_retries = 0; + r = CSR_RESULT_SUCCESS; + while (1) + { + CsrUint8 op; + + /* + * Read the memory location until two successive reads give + * the same value. + * Then handle it. + */ + r = safe_read_shared_location(card, op_addr, &op); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to read loader status\n"); + break; + } + + if (op == UNIFI_LOADER_IDLE) + { + /* Success */ + break; + } + + if (op != opcode) + { + unifi_error(card->ospriv, "Error reported by loader: 0x%X\n", op); + r = CSR_RESULT_FAILURE; + break; + } + + /* Allow 500us timeout */ + if (++op_retries >= OPERATION_TIMEOUT_LOOPS) + { + unifi_error(card->ospriv, "Timeout waiting for loader to ack transfer\n"); + /* Stop XAPs to aid post-mortem */ + r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to stop UniFi processors\n"); + } + else + { + r = CSR_RESULT_FAILURE; + } + break; + } + CsrThreadSleep(OPERATION_TIMEOUT_DELAY); + } /* Loop exits with r != CSR_RESULT_SUCCESS on error */ + + return r; +} /* unifi_do_loader_op() */ + + +/* + * --------------------------------------------------------------------------- + * send_ptdl_to_unifi + * + * Copy a patch block from userland to the UniFi. + * This function reads data, 2K at a time, from userland and writes + * it to the UniFi. + * + * Arguments: + * card A pointer to the card structure + * dlpriv The os specific handle for the firmware file + * ptdl A pointer ot the PTDL block + * handle The buffer handle to use for the xfer + * op_addr The address of the loader operation control word + * + * Returns: + * Number of bytes sent (Positive) or negative value indicating + * error code: + * CSR_WIFI_HIP_RESULT_NO_MEMORY memory allocation failed + * CSR_WIFI_HIP_RESULT_INVALID_VALUE error in XBV file + * CSR_RESULT_FAILURE SDIO error + * --------------------------------------------------------------------------- + */ +static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv, + const struct PTDL *ptdl, CsrUint32 handle, + CsrUint32 op_addr) +{ + CsrUint32 offset; + CsrUint8 *buf; + CsrInt32 data_len; + CsrUint32 write_len; + CsrResult r; + const CsrUint16 buf_size = 2 * 1024; + + offset = ptdl->dl_offset; + data_len = ptdl->dl_size; + + if (data_len > buf_size) + { + unifi_error(card->ospriv, "PTDL block is too large (%u)\n", + ptdl->dl_size); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + buf = CsrMemAlloc(buf_size); + if (buf == NULL) + { + unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n"); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; + } + + r = CSR_RESULT_SUCCESS; + + if (unifi_fw_read(card->ospriv, dlpriv, offset, buf, data_len) != data_len) + { + unifi_error(card->ospriv, "Failed to read from file\n"); + } + else + { + /* We can always round these if the host wants to */ + if (card->sdio_io_block_pad) + { + write_len = (data_len + (card->sdio_io_block_size - 1)) & + ~(card->sdio_io_block_size - 1); + + /* Zero out the rest of the buffer (This isn't needed, but it + * makes debugging things later much easier). */ + CsrMemSet(buf + data_len, 0, write_len - data_len); + } + else + { + write_len = data_len; + } + + r = unifi_bulk_rw_noretry(card, handle, buf, write_len, UNIFI_SDIO_WRITE); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "CMD53 failed writing %d bytes to handle %ld\n", + data_len, handle); + } + else + { + /* + * Can change the order of things to overlap read from file + * with copy to unifi + */ + r = unifi_do_loader_op(card, op_addr, UNIFI_BOOT_LOADER_PATCH); + } + } + + CsrMemFree(buf); + + if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + unifi_error(card->ospriv, "Failed to copy block of %u bytes to UniFi\n", + ptdl->dl_size); + } + + return r; +} /* send_ptdl_to_unifi() */ + + +/* + * --------------------------------------------------------------------------- + * do_patch_download + * + * This function downloads a set of patches to UniFi and then + * causes it to restart. + * + * Arguments: + * card Pointer to card struct. + * dlpriv A context pointer from the calling function to be + * used when reading the XBV file. This can be NULL + * in which case not patches are applied. + * pfwinfo Pointer to a fwinfo struct describing the f/w + * XBV file. + * boot_ctrl_addr The address of the boot loader control structure. + * + * Returns: + * 0 on success, or an error code + * CSR_WIFI_HIP_RESULT_INVALID_VALUE for a bad laoader version number + * --------------------------------------------------------------------------- + */ +static CsrResult do_patch_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo, CsrUint32 boot_ctrl_addr) +{ + CsrResult r; + CsrInt32 i; + CsrUint16 loader_version; + CsrUint16 handle; + CsrUint32 total_bytes; + + /* + * Read info from the SDIO Loader Control Data Structure + */ + /* Check the loader version */ + r = unifi_card_read16(card, boot_ctrl_addr, &loader_version); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Patch download: Failed to read loader version\n"); + return r; + } + unifi_trace(card->ospriv, UDBG2, "Patch download: boot loader version 0x%04X\n", loader_version); + switch (loader_version) + { + case 0x0000: + break; + + default: + unifi_error(card->ospriv, "Patch loader version (0x%04X) is not supported by this driver\n", + loader_version); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* Retrieve the handle to use with CMD53 */ + r = unifi_card_read16(card, boot_ctrl_addr + 4, &handle); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Patch download: Failed to read loader handle\n"); + return r; + } + + /* Set the mask of LEDs to flash */ + if (card->loader_led_mask) + { + r = unifi_card_write16(card, boot_ctrl_addr + 2, + (CsrUint16)card->loader_led_mask); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Patch download: Failed to write LED mask\n"); + return r; + } + } + + total_bytes = 0; + + /* Copy download data to UniFi memory */ + for (i = 0; i < pfwinfo->num_ptdl; i++) + { + unifi_trace(card->ospriv, UDBG3, "Patch download: %d Downloading for %d from offset %d\n", + i, + pfwinfo->ptdl[i].dl_size, + pfwinfo->ptdl[i].dl_offset); + + r = send_ptdl_to_unifi(card, dlpriv, &pfwinfo->ptdl[i], + handle, boot_ctrl_addr + 6); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + return r; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Patch failed after %u bytes\n", + total_bytes); + return r; + } + total_bytes += pfwinfo->ptdl[i].dl_size; + } + + return CSR_RESULT_SUCCESS; +} /* do_patch_download() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c new file mode 100644 index 000000000000..c191ea135040 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_dump.c @@ -0,0 +1,872 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_dump.c + * + * PURPOSE: + * Routines for retrieving and buffering core status from the UniFi + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_unifiversion.h" +#include "csr_wifi_hip_card.h" + +/* Locations to capture in dump (XAP words) */ +#define HIP_CDUMP_FIRST_CPUREG (0xFFE0) /* First CPU register */ +#define HIP_CDUMP_FIRST_LO (0) /* Start of low address range */ +#define HIP_CDUMP_FIRST_HI_MAC (0x3C00) /* Start of MAC high area */ +#define HIP_CDUMP_FIRST_HI_PHY (0x1C00) /* Start of PHY high area */ +#define HIP_CDUMP_FIRST_SH (0) /* Start of shared memory area */ + +#define HIP_CDUMP_NCPUREGS (10) /* No. of 16-bit XAP registers */ +#define HIP_CDUMP_NWORDS_LO (0x0100) /* Low area size in 16-bit words */ +#define HIP_CDUMP_NWORDS_HI (0x0400) /* High area size in 16-bit words */ +#define HIP_CDUMP_NWORDS_SH (0x0500) /* Shared memory area size, 16-bit words */ + +#define HIP_CDUMP_NUM_ZONES 7 /* Number of UniFi memory areas to capture */ + +/* Mini-coredump state */ +typedef struct coredump_buf +{ + CsrUint16 count; /* serial number of dump */ + CsrTime timestamp; /* host's system time at capture */ + CsrInt16 requestor; /* request: 0=auto dump, 1=manual */ + CsrUint16 chip_ver; + CsrUint32 fw_ver; + CsrUint16 *zone[HIP_CDUMP_NUM_ZONES]; + + struct coredump_buf *next; /* circular list */ + struct coredump_buf *prev; /* circular list */ +} coredump_buffer; + +/* Structure used to describe a zone of chip memory captured by mini-coredump */ +struct coredump_zone +{ + unifi_coredump_space_t space; /* XAP memory space this zone covers */ + enum unifi_dbg_processors_select cpu; /* XAP CPU core selector */ + CsrUint32 gp; /* Generic Pointer to memory zone on XAP */ + CsrUint16 offset; /* 16-bit XAP word offset of zone in memory space */ + CsrUint16 length; /* Length of zone in XAP words */ +}; + +static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_buf); +static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_buf); +static CsrResult unifi_coredump_read_zone(card_t *card, CsrUint16 *zone, + const struct coredump_zone *def); +static CsrInt32 get_value_from_coredump(const coredump_buffer *dump, + const unifi_coredump_space_t space, const CsrUint16 offset); + +/* Table of chip memory zones we capture on mini-coredump */ +static const struct coredump_zone zonedef_table[HIP_CDUMP_NUM_ZONES] = { + { UNIFI_COREDUMP_MAC_REG, UNIFI_PROC_MAC, UNIFI_MAKE_GP(REGISTERS, HIP_CDUMP_FIRST_CPUREG * 2), HIP_CDUMP_FIRST_CPUREG, HIP_CDUMP_NCPUREGS }, + { UNIFI_COREDUMP_PHY_REG, UNIFI_PROC_PHY, UNIFI_MAKE_GP(REGISTERS, HIP_CDUMP_FIRST_CPUREG * 2), HIP_CDUMP_FIRST_CPUREG, HIP_CDUMP_NCPUREGS }, + { UNIFI_COREDUMP_SH_DMEM, UNIFI_PROC_INVALID, UNIFI_MAKE_GP(SH_DMEM, HIP_CDUMP_FIRST_SH * 2), HIP_CDUMP_FIRST_SH, HIP_CDUMP_NWORDS_SH }, + { UNIFI_COREDUMP_MAC_DMEM, UNIFI_PROC_MAC, UNIFI_MAKE_GP(MAC_DMEM, HIP_CDUMP_FIRST_LO * 2), HIP_CDUMP_FIRST_LO, HIP_CDUMP_NWORDS_LO }, + { UNIFI_COREDUMP_MAC_DMEM, UNIFI_PROC_MAC, UNIFI_MAKE_GP(MAC_DMEM, HIP_CDUMP_FIRST_HI_MAC * 2), HIP_CDUMP_FIRST_HI_MAC, HIP_CDUMP_NWORDS_HI }, + { UNIFI_COREDUMP_PHY_DMEM, UNIFI_PROC_PHY, UNIFI_MAKE_GP(PHY_DMEM, HIP_CDUMP_FIRST_LO * 2), HIP_CDUMP_FIRST_LO, HIP_CDUMP_NWORDS_LO }, + { UNIFI_COREDUMP_PHY_DMEM, UNIFI_PROC_PHY, UNIFI_MAKE_GP(PHY_DMEM, HIP_CDUMP_FIRST_HI_PHY * 2), HIP_CDUMP_FIRST_HI_PHY, HIP_CDUMP_NWORDS_HI }, +}; + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_request_at_next_reset + * + * Request that a mini-coredump is performed when the driver has + * completed resetting the UniFi device. + * + * Arguments: + * card Pointer to card struct + * enable If non-zero, sets the request. + * If zero, cancels any pending request. + * + * Returns: + * CSR_RESULT_SUCCESS or CSR HIP error code + * + * Notes: + * This function is typically called once the driver has detected that + * the UniFi device has become unresponsive due to crash, or internal + * watchdog reset. The driver must reset it to regain communication and, + * immediately after that, the mini-coredump can be captured. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_coredump_request_at_next_reset(card_t *card, CsrInt8 enable) +{ + CsrResult r; + + func_enter(); + + if (enable) + { + unifi_trace(card->ospriv, UDBG2, "Mini-coredump requested after reset\n"); + } + + if (card == NULL) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + else + { + card->request_coredump_on_reset = enable?1 : 0; + r = CSR_RESULT_SUCCESS; + } + + func_exit_r(r); + return r; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_handle_request + * + * Performs a coredump now, if one was requested, and clears the request. + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * CSR_RESULT_SUCCESS or CSR HIP error code + * + * Notes: + * --------------------------------------------------------------------------- + */ +CsrResult unifi_coredump_handle_request(card_t *card) +{ + CsrResult r = CSR_RESULT_SUCCESS; + + func_enter(); + + if (card == NULL) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + else + { + if (card->request_coredump_on_reset == 1) + { + card->request_coredump_on_reset = 0; + r = unifi_coredump_capture(card, NULL); + } + } + + func_exit_r(r); + return r; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_capture + * + * Capture the current status of the UniFi device. + * Various registers are buffered for future offline inspection. + * + * Arguments: + * card Pointer to card struct + * req Pointer to request struct, or NULL: + * A coredump requested manually by the user app + * will have a request struct pointer, an automatic + * coredump will have a NULL pointer. + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_RESULT_FAILURE SDIO error + * CSR_WIFI_HIP_RESULT_INVALID_VALUE Initialisation not complete + * + * Notes: + * The result is a filled entry in the circular buffer of core dumps, + * values from which can be extracted to userland via an ioctl. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req) +{ + CsrResult r = CSR_RESULT_SUCCESS; + static CsrUint16 dump_seq_no = 1; + CsrTime time_of_capture; + + func_enter(); + + if (card->dump_next_write == NULL) + { + r = CSR_RESULT_SUCCESS; + goto done; + } + + /* Reject forced capture before initialisation has happened */ + if (card->helper == NULL) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + goto done; + } + + + /* + * Force a mini-coredump capture right now + */ + time_of_capture = CsrTimeGet(NULL); + unifi_info(card->ospriv, "Mini-coredump capture at t=%u\n", time_of_capture); + + /* Wake up the processors so we can talk to them */ + r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to wake UniFi\n"); + goto done; + } + CsrThreadSleep(20); + + /* Stop both XAPs */ + unifi_trace(card->ospriv, UDBG4, "Stopping XAPs for coredump capture\n"); + r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to stop UniFi XAPs\n"); + goto done; + } + + /* Dump core into the next available slot in the circular list */ + r = unifi_coredump_from_sdio(card, card->dump_next_write); + if (r == CSR_RESULT_SUCCESS) + { + /* Record whether the dump was manual or automatic */ + card->dump_next_write->requestor = (req?1 : 0); + card->dump_next_write->timestamp = time_of_capture; + /* Advance to the next buffer */ + card->dump_next_write->count = dump_seq_no++; + card->dump_cur_read = card->dump_next_write; + card->dump_next_write = card->dump_next_write->next; + + /* Sequence no. of zero indicates slot not in use, so handle wrap */ + if (dump_seq_no == 0) + { + dump_seq_no = 1; + } + + unifi_trace(card->ospriv, UDBG3, + "Coredump (%p), SeqNo=%d, cur_read=%p, next_write=%p\n", + req, + card->dump_cur_read->count, + card->dump_cur_read, card->dump_next_write); + } + + /* Start both XAPs */ + unifi_trace(card->ospriv, UDBG4, "Restart XAPs after coredump\n"); + r = card_start_processor(card, UNIFI_PROC_BOTH); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Failed to start UniFi XAPs\n"); + goto done; + } + +done: + func_exit_r(r); + return r; +} /* unifi_coredump_capture() */ + + +/* + * --------------------------------------------------------------------------- + * get_value_from_coredump + * + * + * + * Arguments: + * dump Pointer to buffered coredump data + * offset_in_space XAP memory space to retrieve from the buffer (there + * may be more than one zone covering the same memory + * space, but starting from different offsets). + * offset Offset within the XAP memory space to be retrieved + * + * Returns: + * >=0 Register value on success + * <0 Register out of range of any captured zones + * + * Notes: + * --------------------------------------------------------------------------- + */ +static CsrInt32 get_value_from_coredump(const coredump_buffer *dump, + const unifi_coredump_space_t space, + const CsrUint16 offset_in_space) +{ + CsrInt32 r = -1; + CsrUint16 offset_in_zone; + CsrUint32 zone_end_offset; + CsrInt32 i; + const struct coredump_zone *def = &zonedef_table[0]; + + /* Search zone def table for a match with the requested memory space */ + for (i = 0; i < HIP_CDUMP_NUM_ZONES; i++, def++) + { + if (space == def->space) + { + zone_end_offset = def->offset + def->length; + + /* Is the space offset contained in this zone? */ + if (offset_in_space < zone_end_offset && + offset_in_space >= def->offset) + { + /* Calculate the offset of data within the zone buffer */ + offset_in_zone = offset_in_space - def->offset; + r = (CsrInt32) * (dump->zone[i] + offset_in_zone); + + unifi_trace(NULL, UDBG6, + "sp %d, offs 0x%04x = 0x%04x (in z%d 0x%04x->0x%04x)\n", + space, offset_in_space, r, + i, def->offset, zone_end_offset - 1); + break; + } + } + } + return r; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_get_value + * + * Retrieve the value of a register buffered from a previous core dump, + * so that it may be reported back to application code. + * + * Arguments: + * card Pointer to card struct + * req_reg Pointer to request parameter partially filled. This + * function puts in the values retrieved from the dump. + * + * Returns: + * CSR_RESULT_SUCCESS on success, or: + * CSR_WIFI_HIP_RESULT_INVALID_VALUE Null parameter error + * CSR_WIFI_HIP_RESULT_RANGE Register out of range + * CSR_WIFI_HIP_RESULT_NOT_FOUND Dump index not (yet) captured + * + * Notes: + * --------------------------------------------------------------------------- + */ +CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req) +{ + CsrResult r; + CsrInt32 i = 0; + coredump_buffer *find_dump = NULL; + + func_enter(); + + if (req == NULL || card == NULL) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + goto done; + } + req->value = -1; + if (card->dump_buf == NULL) + { + unifi_trace(card->ospriv, UDBG2, "No coredump buffers\n"); + r = CSR_WIFI_HIP_RESULT_NOT_FOUND; /* Coredumping disabled */ + goto done; + } + if (card->dump_cur_read == NULL) + { + unifi_trace(card->ospriv, UDBG4, "No coredumps captured\n"); + r = CSR_WIFI_HIP_RESULT_NOT_FOUND; /* No coredump yet captured */ + goto done; + } + + /* Find the requested dump buffer */ + switch (req->index) + { + case 0: /* Newest */ + find_dump = card->dump_cur_read; + break; + case -1: /* Oldest: The next used slot forward */ + for (find_dump = card->dump_cur_read->next; + (find_dump->count == 0) && (find_dump != card->dump_cur_read); + find_dump = card->dump_cur_read->next) + { + } + break; + default: /* Number of steps back from current read position */ + for (i = 0, find_dump = card->dump_cur_read; + i < req->index; + i++, find_dump = find_dump->prev) + { + /* Walk the list for the index'th entry, but + * stop when about to wrap. */ + unifi_trace(card->ospriv, UDBG6, + "%d: %d, @%p, p=%p, n=%p, cr=%p, h=%p\n", + i, find_dump->count, find_dump, find_dump->prev, + find_dump->next, card->dump_cur_read, card->dump_buf); + if (find_dump->prev == card->dump_cur_read) + { + /* Wrapped but still not found, index out of range */ + if (i != req->index) + { + unifi_trace(card->ospriv, UDBG6, + "Dump index %d not found %d\n", req->index, i); + r = CSR_WIFI_HIP_RESULT_NOT_FOUND; + goto done; + } + break; + } + } + break; + } + + /* Check if the slot is actually filled with a core dump */ + if (find_dump->count == 0) + { + unifi_trace(card->ospriv, UDBG4, "Not captured %d\n", req->index); + r = CSR_WIFI_HIP_RESULT_NOT_FOUND; + goto done; + } + + unifi_trace(card->ospriv, UDBG6, "Req index %d, found seq %d at step %d\n", + req->index, find_dump->count, i); + + /* Find the appropriate entry in the buffer */ + req->value = get_value_from_coredump(find_dump, req->space, (CsrUint16)req->offset); + if (req->value < 0) + { + r = CSR_WIFI_HIP_RESULT_RANGE; /* Un-captured register */ + unifi_trace(card->ospriv, UDBG4, + "Can't read space %d, reg 0x%x from coredump buffer %d\n", + req->space, req->offset, req->index); + } + else + { + r = CSR_RESULT_SUCCESS; + } + + /* Update the private request structure with the found values */ + req->chip_ver = find_dump->chip_ver; + req->fw_ver = find_dump->fw_ver; + req->timestamp = find_dump->timestamp; + req->requestor = find_dump->requestor; + req->serial = find_dump->count; + +done: + func_exit_r(r); + return r; +} /* unifi_coredump_get_value() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_read_zone + * + * Captures a UniFi memory zone into a buffer on the host + * + * Arguments: + * card Pointer to card struct + * zonebuf Pointer to on-host buffer to dump the memory zone into + * def Pointer to description of the memory zone to read from UniFi. + * + * Returns: + * CSR_RESULT_SUCCESS on success, or: + * CSR_RESULT_FAILURE SDIO error + * CSR_WIFI_HIP_RESULT_INVALID_VALUE Parameter error + * + * Notes: + * It is assumed that the caller has already stopped the XAPs + * --------------------------------------------------------------------------- + */ +static CsrResult unifi_coredump_read_zone(card_t *card, CsrUint16 *zonebuf, const struct coredump_zone *def) +{ + CsrResult r; + + func_enter(); + + if (zonebuf == NULL || def == NULL) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + goto done; + } + + /* Select XAP CPU if necessary */ + if (def->cpu != UNIFI_PROC_INVALID) + { + if (def->cpu != UNIFI_PROC_MAC && def->cpu != UNIFI_PROC_PHY) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + goto done; + } + r = unifi_set_proc_select(card, def->cpu); + if (r != CSR_RESULT_SUCCESS) + { + goto done; + } + } + + unifi_trace(card->ospriv, UDBG4, + "Dump sp %d, offs 0x%04x, 0x%04x words @GP=%08x CPU %d\n", + def->space, def->offset, def->length, def->gp, def->cpu); + + /* Read on-chip RAM (byte-wise) */ + r = unifi_card_readn(card, def->gp, zonebuf, (CsrUint16)(def->length * 2)); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + goto done; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Can't read UniFi shared data area\n"); + goto done; + } + +done: + func_exit_r(r); + return r; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_read_zones + * + * Walks through the table of on-chip memory zones defined in zonedef_table, + * and reads each of them from the UniFi chip + * + * Arguments: + * card Pointer to card struct + * dump_buf Buffer into which register values will be dumped + * + * Returns: + * CSR_RESULT_SUCCESS on success, or: + * CSR_RESULT_FAILURE SDIO error + * CSR_WIFI_HIP_RESULT_INVALID_VALUE Parameter error + * + * Notes: + * It is assumed that the caller has already stopped the XAPs + * --------------------------------------------------------------------------- + */ +static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_buf) +{ + CsrResult r = CSR_RESULT_SUCCESS; + CsrInt32 i; + + func_enter(); + + /* Walk the table of coredump zone definitions and read them from the chip */ + for (i = 0; + (i < HIP_CDUMP_NUM_ZONES) && (r == 0); + i++) + { + r = unifi_coredump_read_zone(card, dump_buf->zone[i], &zonedef_table[i]); + } + + func_exit_r(r); + return r; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_from_sdio + * + * Capture the status of the UniFi processors, over SDIO + * + * Arguments: + * card Pointer to card struct + * reg_buffer Buffer into which register values will be dumped + * + * Returns: + * CSR_RESULT_SUCCESS on success, or: + * CSR_RESULT_FAILURE SDIO error + * CSR_WIFI_HIP_RESULT_INVALID_VALUE Parameter error + * + * Notes: + * --------------------------------------------------------------------------- + */ +static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_buf) +{ + CsrUint16 val; + CsrResult r; + CsrUint32 sdio_addr; + + func_enter(); + + if (dump_buf == NULL) + { + r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; + goto done; + } + + + /* Chip and firmware version */ + unifi_trace(card->ospriv, UDBG4, "Get chip version\n"); + sdio_addr = 2 * ChipHelper_GBL_CHIP_VERSION(card->helper); + if (sdio_addr != 0) + { + r = unifi_read_direct16(card, sdio_addr, &val); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + goto done; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Can't read GBL_CHIP_VERSION\n"); + goto done; + } + } + dump_buf->chip_ver = val; + dump_buf->fw_ver = card->build_id; + + unifi_trace(card->ospriv, UDBG4, "chip_ver 0x%04x, fw_ver %u\n", + dump_buf->chip_ver, dump_buf->fw_ver); + + /* Capture the memory zones required from UniFi */ + r = unifi_coredump_read_zones(card, dump_buf); + if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) + { + goto done; + } + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "Can't read UniFi memory areas\n"); + goto done; + } + +done: + func_exit_r(r); + return r; +} /* unifi_coredump_from_sdio() */ + + +#ifndef UNIFI_DISABLE_COREDUMP +/* + * --------------------------------------------------------------------------- + * new_coredump_node + * + * Allocates a coredump linked-list node, and links it to the previous. + * + * Arguments: + * ospriv OS context + * prevnode Previous node to link into + * + * Returns: + * Pointer to valid coredump_buffer on success + * NULL on memory allocation failure + * + * Notes: + * Allocates "all or nothing" + * --------------------------------------------------------------------------- + */ +static +coredump_buffer* new_coredump_node(void *ospriv, coredump_buffer *prevnode) +{ + coredump_buffer *newnode = NULL; + CsrUint16 *newzone = NULL; + CsrInt32 i; + CsrUint32 zone_size; + + /* Allocate node header */ + newnode = (coredump_buffer *)CsrMemAlloc(sizeof(coredump_buffer)); + if (newnode == NULL) + { + return NULL; + } + CsrMemSet(newnode, 0, sizeof(coredump_buffer)); + + /* Allocate chip memory zone capture buffers */ + for (i = 0; i < HIP_CDUMP_NUM_ZONES; i++) + { + zone_size = sizeof(CsrUint16) * zonedef_table[i].length; + newzone = (CsrUint16 *)CsrMemAlloc(zone_size); + newnode->zone[i] = newzone; + if (newzone != NULL) + { + CsrMemSet(newzone, 0, zone_size); + } + else + { + unifi_error(ospriv, "Out of memory on coredump zone %d (%d words)\n", + i, zonedef_table[i].length); + break; + } + } + + /* Clean up if any zone alloc failed */ + if (newzone == NULL) + { + for (i = 0; newnode->zone[i] != NULL; i++) + { + CsrMemFree(newnode->zone[i]); + newnode->zone[i] = NULL; + } + } + + /* Link to previous node */ + newnode->prev = prevnode; + if (prevnode) + { + prevnode->next = newnode; + } + newnode->next = NULL; + + return newnode; +} + + +#endif /* UNIFI_DISABLE_COREDUMP */ + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_init + * + * Allocates buffers for the automatic SDIO core dump + * + * Arguments: + * card Pointer to card struct + * num_dump_buffers Number of buffers to reserve for coredumps + * + * Returns: + * CSR_RESULT_SUCCESS on success, or: + * CSR_WIFI_HIP_RESULT_NO_MEMORY memory allocation failed + * + * Notes: + * Allocates space in advance, to be used for the last n coredump buffers + * the intention being that the size is sufficient for at least one dump, + * probably several. + * It's probably advisable to have at least 2 coredump buffers to allow + * one to be enquired with the unifi_coredump tool, while leaving another + * free for capturing. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_coredump_init(card_t *card, CsrUint16 num_dump_buffers) +{ +#ifndef UNIFI_DISABLE_COREDUMP + void *ospriv = card->ospriv; + coredump_buffer *prev = NULL; + coredump_buffer *newnode = NULL; + CsrUint32 i = 0; +#endif + + func_enter(); + + card->request_coredump_on_reset = 0; + card->dump_next_write = NULL; + card->dump_cur_read = NULL; + card->dump_buf = NULL; + +#ifndef UNIFI_DISABLE_COREDUMP + unifi_trace(ospriv, UDBG1, + "Allocate buffers for %d core dumps\n", num_dump_buffers); + if (num_dump_buffers == 0) + { + goto done; + } + + /* Root node */ + card->dump_buf = new_coredump_node(ospriv, NULL); + if (card->dump_buf == NULL) + { + goto fail; + } + prev = card->dump_buf; + newnode = card->dump_buf; + + /* Add each subsequent node at tail */ + for (i = 1; i < num_dump_buffers; i++) + { + newnode = new_coredump_node(ospriv, prev); + if (newnode == NULL) + { + goto fail; + } + prev = newnode; + } + + /* Link the first and last nodes to make the list circular */ + card->dump_buf->prev = newnode; + newnode->next = card->dump_buf; + + /* Set initial r/w access pointers */ + card->dump_next_write = card->dump_buf; + card->dump_cur_read = NULL; + + unifi_trace(ospriv, UDBG2, "Core dump configured (%d dumps max)\n", i); + +done: +#endif + func_exit(); + return CSR_RESULT_SUCCESS; + +#ifndef UNIFI_DISABLE_COREDUMP +fail: + /* Unwind what we allocated so far */ + unifi_error(ospriv, "Out of memory allocating core dump node %d\n", i); + unifi_coredump_free(card); + func_exit(); + return CSR_WIFI_HIP_RESULT_NO_MEMORY; +#endif +} /* unifi_coreump_init() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_coredump_free + * + * Free all memory dynamically allocated for core dump + * + * Arguments: + * card Pointer to card struct + * + * Returns: + * None + * + * Notes: + * --------------------------------------------------------------------------- + */ +void unifi_coredump_free(card_t *card) +{ + void *ospriv = card->ospriv; + coredump_buffer *node, *del_node; + CsrInt16 i = 0; + CsrInt16 j; + + func_enter(); + unifi_trace(ospriv, UDBG2, "Core dump de-configured\n"); + + if (card->dump_buf == NULL) + { + return; + } + + node = card->dump_buf; + do + { + /* Free payload zones */ + for (j = 0; j < HIP_CDUMP_NUM_ZONES; j++) + { + if (node->zone[j] != NULL) + { + CsrMemFree(node->zone[j]); + node->zone[j] = NULL; + } + } + + /* Detach */ + del_node = node; + node = node->next; + + /* Free header */ + CsrMemFree(del_node); + i++; + } while ((node != NULL) && (node != card->dump_buf)); + + unifi_trace(ospriv, UDBG3, "Freed %d coredump buffers\n", i); + + card->dump_buf = NULL; + card->dump_next_write = NULL; + card->dump_cur_read = NULL; + + func_exit(); +} /* unifi_coredump_free() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_packing.c b/drivers/staging/csr/csr_wifi_hip_packing.c new file mode 100644 index 000000000000..4e98da976668 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_packing.c @@ -0,0 +1,4804 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_wifi_hip_signals.h" +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" + + +/* + * --------------------------------------------------------------------------- + * get_packed_struct_size + * + * Examine a buffer containing a UniFi signal in wire-format. + * The first two bytes contain the signal ID, decode the signal ID and + * return the size, in bytes, of the signal, not including any bulk + * data. + * + * WARNING: This function is auto-generated, DO NOT EDIT! + * + * Arguments: + * buf Pointer to buffer to decode. + * + * Returns: + * 0 if the signal ID is not recognised (i.e. zero length), + * otherwise the number of bytes occupied by the signal in the buffer. + * This is useful for stepping past the signal to the object in the buffer. + * --------------------------------------------------------------------------- + */ +CsrInt32 get_packed_struct_size(const CsrUint8 *buf) +{ + CsrInt32 size = 0; + CsrUint16 sig_id; + + sig_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(buf); + + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + switch (sig_id) + { +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_WORD16_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; + case CSR_DEBUG_GENERIC_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; + case CSR_MA_PACKET_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT64; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; + case CSR_MLME_SET_TIM_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECTED_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_TRIGGERED_GET_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif + case CSR_DEBUG_GENERIC_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CANCEL_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_MLME_SET_TIM_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_GENERIC_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; + case CSR_MA_PACKET_CANCEL_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_MA_VIF_AVAILABILITY_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif + case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + size += SIZEOF_UINT32; + size += SIZEOF_UINT32; + size += 48 / 8; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 32 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_ERROR_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + size += SIZEOF_UINT32; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += 48 / 8; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT32; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_REQUEST_ID: + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + size += SIZEOF_UINT16; + break; +#endif + default: + size = 0; + } + return size; +} /* get_packed_struct_size() */ + + +/* + * --------------------------------------------------------------------------- + * read_unpack_signal + * + * Unpack a wire-format signal into a host-native structure. + * This function handles any necessary conversions for endianness and + * places no restrictions on packing or alignment for the structure + * definition. + * + * WARNING: This function is auto-generated, DO NOT EDIT! + * + * Arguments: + * ptr Signal buffer to unpack. + * sig Pointer to destination structure to populate. + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_INVALID_VALUE if the ID of signal was not recognised. + * --------------------------------------------------------------------------- + */ +CsrResult read_unpack_signal(const CsrUint8 *ptr, CSR_SIGNAL *sig) +{ + CsrInt32 index = 0; + + sig->SignalPrimitiveHeader.SignalId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + + sig->SignalPrimitiveHeader.ReceiverProcessId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + + sig->SignalPrimitiveHeader.SenderProcessId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + + switch (sig->SignalPrimitiveHeader.SignalId) + { +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_CONFIRM_ID: + sig->u.MlmeSetkeysConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + sig->u.MlmeConfigQueueConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanConfirm.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + sig->u.MlmeAddBlackoutConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutConfirm.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_REQUEST_ID: + sig->u.MlmeDelBlackoutRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutRequest.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_CONFIRM_ID: + sig->u.MlmeSmStartConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + sig->u.MlmeStopAggregationConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeStopAggregationConfirm.PeerQstaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeStopAggregationConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationConfirm.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_REQUEST_ID: + sig->u.MlmeDelTspecRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_WORD16_INDICATION_ID: + sig->u.DebugWord16Indication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[8] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[9] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[10] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[11] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[12] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[13] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[14] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugWord16Indication.DebugWords[15] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_DEBUG_GENERIC_CONFIRM_ID: + sig->u.DebugGenericConfirm.DebugVariable.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugVariable.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericConfirm.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_MA_PACKET_INDICATION_ID: + sig->u.MaPacketIndication.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MaPacketIndication.LocalTime.x, &ptr[index], 64 / 8); + index += 64 / 8; + sig->u.MaPacketIndication.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.Channel = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.ReceptionStatus = (CSR_RECEPTION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.Rssi = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.Snr = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketIndication.ReceivedRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_MLME_SET_TIM_REQUEST_ID: + sig->u.MlmeSetTimRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimRequest.AssociationId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimRequest.TimValue = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECTED_INDICATION_ID: + sig->u.MlmeConnectedIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectedIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectedIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectedIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectedIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectedIndication.ConnectionStatus = (CSR_CONNECTION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeConnectedIndication.PeerMacAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID: + sig->u.MlmeDelRxTriggerRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerRequest.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_TRIGGERED_GET_INDICATION_ID: + sig->u.MlmeTriggeredGetIndication.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeTriggeredGetIndication.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_REQUEST_ID: + sig->u.MlmeScanRequest.ChannelList.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.ChannelList.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.ScanType = (CSR_SCAN_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.ProbeDelay = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeScanRequest.MinChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanRequest.MaxChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + sig->u.MlmeDeletekeysConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_REQUEST_ID: + sig->u.MlmeGetNextRequest.MibAttribute.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextRequest.MibAttribute.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + sig->u.MlmeSetChannelConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_REQUEST_ID: + sig->u.MlmeStartAggregationRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeStartAggregationRequest.PeerQstaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeStartAggregationRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.StartingSequenceNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.BufferSize = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationRequest.BlockAckTimeout = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_REQUEST_ID: + sig->u.MlmeHlSyncRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeHlSyncRequest.GroupAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif + case CSR_DEBUG_GENERIC_REQUEST_ID: + sig->u.DebugGenericRequest.DebugVariable.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugVariable.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericRequest.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_CONFIRM_ID: + sig->u.MlmeLeaveConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID: + sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetRequest.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID: + sig->u.MlmeAddMulticastAddressRequest.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressRequest.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressRequest.NumberOfMulticastGroupAddresses = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_REQUEST_ID: + sig->u.MlmeResetRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeResetRequest.StaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeResetRequest.SetDefaultMib = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CANCEL_REQUEST_ID: + sig->u.MlmeScanCancelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanCancelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanCancelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanCancelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanCancelRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetConfirm.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID: + sig->u.MlmeSetPacketFilterRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterRequest.PacketFilterMode = (CSR_PACKET_FILTER_MODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetPacketFilterRequest.ArpFilterAddress = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerConfirm.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelRxTriggerConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_REQUEST_ID: + sig->u.MlmeConnectStatusRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusRequest.ConnectionStatus = (CSR_CONNECTION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeConnectStatusRequest.StaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeConnectStatusRequest.AssociationId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusRequest.AssociationCapabilityInformation = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_REQUEST_ID: + sig->u.MlmeLeaveRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeLeaveRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_REQUEST_ID: + sig->u.MlmeConfigQueueRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.QueueIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.Aifs = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.Cwmin = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.Cwmax = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConfigQueueRequest.TxopLimit = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + sig->u.MlmeDelTspecConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTspecConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MLME_SET_TIM_CONFIRM_ID: + sig->u.MlmeSetTimConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetTimConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_INDICATION_ID: + sig->u.MlmeMeasureIndication.MeasurementReportSet.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureIndication.MeasurementReportSet.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureIndication.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + sig->u.MlmeDelBlackoutConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutConfirm.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelBlackoutConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelTriggeredGetConfirm.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_GENERIC_INDICATION_ID: + sig->u.DebugGenericIndication.DebugVariable.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugVariable.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugGenericIndication.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_MA_PACKET_CANCEL_REQUEST_ID: + sig->u.MaPacketCancelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketCancelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketCancelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketCancelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketCancelRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketCancelRequest.HostTag = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanConfirm.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_REQUEST_ID: + sig->u.MaPacketRequest.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketRequest.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketRequest.TransmitRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketRequest.HostTag = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MaPacketRequest.Priority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MaPacketRequest.Ra.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MaPacketRequest.TransmissionControl = (CSR_TRANSMISSION_CONTROL) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID: + sig->u.MlmeModifyBssParameterRequest.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.BeaconPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.DtimPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeModifyBssParameterRequest.CapabilityInformation = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeModifyBssParameterRequest.Bssid.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeModifyBssParameterRequest.RtsThreshold = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID: + sig->u.MlmeAddRxTriggerRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerRequest.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerRequest.Priority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_VIF_AVAILABILITY_INDICATION_ID: + sig->u.MaVifAvailabilityIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityIndication.Multicast = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID: + sig->u.MlmeHlSyncCancelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeHlSyncCancelRequest.GroupAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID: + sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanRequest.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID: + sig->u.MlmeBlackoutEndedIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlackoutEndedIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlackoutEndedIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlackoutEndedIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlackoutEndedIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlackoutEndedIndication.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID: + sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanDoneIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanDoneIndication.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanDoneIndication.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID: + sig->u.MlmeGetKeySequenceRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceRequest.KeyId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetKeySequenceRequest.KeyType = (CSR_KEY_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeGetKeySequenceRequest.Address.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_REQUEST_ID: + sig->u.MlmeSetChannelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.Channel = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeSetChannelRequest.Address.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeSetChannelRequest.AvailabilityDuration = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetChannelRequest.AvailabilityInterval = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_CONFIRM_ID: + sig->u.MlmeMeasureConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureConfirm.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID: + sig->u.MlmeAddTriggeredGetRequest.MibAttribute.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetRequest.MibAttribute.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTriggeredGetRequest.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID: + sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAutonomousScanLossIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeAutonomousScanLossIndication.Bssid.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif + case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID: + sig->u.MaVifAvailabilityResponse.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityResponse.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityResponse.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityResponse.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityResponse.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaVifAvailabilityResponse.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_REQUEST_ID: + sig->u.MlmeAddTemplateRequest.Data1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateRequest.Data1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateRequest.Data2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateRequest.Data2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateRequest.FrameType = (CSR_FRAME_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateRequest.MinTransmitRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_CONFIRM_ID: + sig->u.MlmePowermgtConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + sig->u.MlmeAddPeriodicConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicConfirm.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_CONFIRM_ID: + sig->u.MlmeGetConfirm.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetConfirm.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetConfirm.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetConfirm.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_CONFIRM_ID: + sig->u.MlmeGetNextConfirm.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextConfirm.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextConfirm.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetNextConfirm.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_REQUEST_ID: + sig->u.MlmeStopAggregationRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeStopAggregationRequest.PeerQstaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeStopAggregationRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopAggregationRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerConfirm.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddRxTriggerConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_REQUEST_ID: + sig->u.MlmeAddBlackoutRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.BlackoutType = (CSR_BLACKOUT_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.BlackoutSource = (CSR_BLACKOUT_SOURCE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddBlackoutRequest.BlackoutStartReference = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeAddBlackoutRequest.BlackoutPeriod = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeAddBlackoutRequest.BlackoutDuration = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + CsrMemCpy(sig->u.MlmeAddBlackoutRequest.PeerStaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeAddBlackoutRequest.BlackoutCount = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_REQUEST_ID: + sig->u.MlmeDeletekeysRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysRequest.KeyId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDeletekeysRequest.KeyType = (CSR_KEY_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeDeletekeysRequest.Address.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_CONFIRM_ID: + sig->u.MlmeResetConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeResetConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CONFIRM_ID: + sig->u.MlmeHlSyncConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeHlSyncConfirm.GroupAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeHlSyncConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID: + sig->u.MlmeAddAutonomousScanRequest.ChannelList.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.ChannelList.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.ChannelStartingFactor = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.ScanType = (CSR_SCAN_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.ProbeDelay = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeAddAutonomousScanRequest.MinChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddAutonomousScanRequest.MaxChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_REQUEST_ID: + sig->u.MlmeSetRequest.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetRequest.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_REQUEST_ID: + sig->u.MlmeSmStartRequest.Beacon.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.Beacon.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.BssParameters.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.BssParameters.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.Channel = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeSmStartRequest.InterfaceAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + CsrMemCpy(sig->u.MlmeSmStartRequest.Bssid.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeSmStartRequest.BeaconPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.DtimPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSmStartRequest.CapabilityInformation = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + sig->u.MlmeConnectStatusConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeConnectStatusConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelAutonomousScanConfirm.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_REQUEST_ID: + sig->u.MlmeDelPeriodicRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicRequest.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_REQUEST_ID: + sig->u.MlmeSetkeysRequest.Key.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.Key.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.Length = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.KeyId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.KeyType = (CSR_KEY_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeSetkeysRequest.Address.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeSetkeysRequest.SequenceNumber[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetkeysRequest.SequenceNumber[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(&sig->u.MlmeSetkeysRequest.CipherSuiteSelector, &ptr[index], 32 / 8); + index += 32 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID: + sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanRequest.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePauseAutonomousScanRequest.Pause = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_REQUEST_ID: + sig->u.MlmeGetRequest.MibAttribute.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetRequest.MibAttribute.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeGetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_REQUEST_ID: + sig->u.MlmePowermgtRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.PowerManagementMode = (CSR_POWER_MANAGEMENT_MODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.ReceiveDtims = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.ListenInterval = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmePowermgtRequest.TrafficWindow = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_ERROR_INDICATION_ID: + sig->u.MaPacketErrorIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketErrorIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketErrorIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketErrorIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketErrorIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MaPacketErrorIndication.PeerQstaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MaPacketErrorIndication.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketErrorIndication.SequenceNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_REQUEST_ID: + sig->u.MlmeAddPeriodicRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.MaximumLatency = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeAddPeriodicRequest.PeriodicSchedulingMode = (CSR_PERIODIC_SCHEDULING_MODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.WakeHost = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddPeriodicRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_REQUEST_ID: + sig->u.MlmeAddTspecRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.PsScheme = (CSR_PS_SCHEME) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.MediumTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecRequest.ServiceStartTime = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeAddTspecRequest.ServiceInterval = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + sig->u.MlmeAddTspecRequest.MinimumDataRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddMulticastAddressConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + sig->u.MlmeAddTspecConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTspecConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeHlSyncCancelConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CONFIRM_ID: + sig->u.MlmeScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + sig->u.DebugStringIndication.DebugMessage.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugStringIndication.DebugMessage.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugStringIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.DebugStringIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + sig->u.MlmeAddTemplateConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateConfirm.FrameType = (CSR_FRAME_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeAddTemplateConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID: + sig->u.MlmeBlockackErrorIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlockackErrorIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlockackErrorIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlockackErrorIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlockackErrorIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeBlockackErrorIndication.ResultCode = (CSR_REASON_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeBlockackErrorIndication.PeerQstaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CONFIRM_ID: + sig->u.MlmeSetConfirm.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetConfirm.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetConfirm.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeSetConfirm.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_REQUEST_ID: + sig->u.MlmeMeasureRequest.MeasurementRequestSet.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureRequest.MeasurementRequestSet.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeMeasureRequest.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + sig->u.MlmeStartAggregationConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(sig->u.MlmeStartAggregationConfirm.PeerQstaAddress.x, &ptr[index], 48 / 8); + index += 48 / 8; + sig->u.MlmeStartAggregationConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStartAggregationConfirm.SequenceNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + sig->u.MlmeStopMeasureConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureConfirm.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_CONFIRM_ID: + sig->u.MaPacketConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.TransmissionStatus = (CSR_TRANSMISSION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.RetryCount = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.Rate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MaPacketConfirm.HostTag = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT32; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + sig->u.MlmeDelPeriodicConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicConfirm.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeDelPeriodicConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_REQUEST_ID: + sig->u.MlmeStopMeasureRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + sig->u.MlmeStopMeasureRequest.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index); + index += SIZEOF_UINT16; + break; +#endif + + default: + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + return CSR_RESULT_SUCCESS; +} /* read_unpack_signal() */ + + +/* + * --------------------------------------------------------------------------- + * write_pack + * + * Convert a signal structure, in host-native format, to the + * little-endian wire format specified in the UniFi Host Interface + * Protocol Specification. + * + * WARNING: This function is auto-generated, DO NOT EDIT! + * + * Arguments: + * sig Pointer to signal structure to pack. + * ptr Destination buffer to pack into. + * sig_len Returns the length of the packed signal, i.e. the + * number of bytes written to ptr. + * + * Returns: + * CSR_RESULT_SUCCESS on success, + * CSR_WIFI_HIP_RESULT_INVALID_VALUE if the ID of signal was not recognised. + * --------------------------------------------------------------------------- + */ +CsrResult write_pack(const CSR_SIGNAL *sig, CsrUint8 *ptr, CsrUint16 *sig_len) +{ + CsrInt16 index = 0; + + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->SignalPrimitiveHeader.SignalId, ptr + index); + index += SIZEOF_UINT16; + + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->SignalPrimitiveHeader.ReceiverProcessId, ptr + index); + index += SIZEOF_UINT16; + + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->SignalPrimitiveHeader.SenderProcessId, ptr + index); + index += SIZEOF_UINT16; + + switch (sig->SignalPrimitiveHeader.SignalId) + { +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.BlackoutId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.BlackoutId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[0], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[1], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[2], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[3], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[4], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[5], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[6], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[7], ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeStopAggregationConfirm.PeerQstaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Direction, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Direction, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_WORD16_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[0], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[1], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[2], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[3], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[4], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[5], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[6], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[7], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[8], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[9], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[10], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[11], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[12], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[13], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[14], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[15], ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_DEBUG_GENERIC_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugVariable.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugVariable.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[0], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[1], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[2], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[3], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[4], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[5], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[6], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[7], ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_MA_PACKET_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Data.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Data.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MaPacketIndication.LocalTime.x, 64 / 8); + index += 64 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Ifindex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Channel, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.ReceptionStatus, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Rssi, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Snr, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.ReceivedRate, ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_MLME_SET_TIM_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.AssociationId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.TimValue, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECTED_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.ConnectionStatus, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeConnectedIndication.PeerMacAddress.x, 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.TriggerId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_TRIGGERED_GET_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.MibAttributeValue.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.MibAttributeValue.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.Status, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.ErrorIndex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.TriggeredId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ChannelList.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ChannelList.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.InformationElements.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.InformationElements.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.Ifindex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ScanType, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ProbeDelay, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.MinChannelTime, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.MaxChannelTime, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.MibAttribute.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.MibAttribute.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeStartAggregationRequest.PeerQstaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Direction, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.StartingSequenceNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.BufferSize, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.BlockAckTimeout, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeHlSyncRequest.GroupAddress.x, 48 / 8); + index += 48 / 8; + break; +#endif + case CSR_DEBUG_GENERIC_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugVariable.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugVariable.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[0], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[1], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[2], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[3], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[4], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[5], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[6], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[7], ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.TriggeredId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Data.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Data.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.NumberOfMulticastGroupAddresses, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeResetRequest.StaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.SetDefaultMib, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CANCEL_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.TriggeredId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.InformationElements.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.InformationElements.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.PacketFilterMode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.ArpFilterAddress, ptr + index); + index += SIZEOF_UINT32; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.TriggerId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.InformationElements.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.InformationElements.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.ConnectionStatus, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeConnectStatusRequest.StaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.AssociationId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.AssociationCapabilityInformation, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.QueueIndex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Aifs, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Cwmin, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Cwmax, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.TxopLimit, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MLME_SET_TIM_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.MeasurementReportSet.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.MeasurementReportSet.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.DialogToken, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.BlackoutId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.TriggeredId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_GENERIC_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugVariable.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugVariable.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[0], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[1], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[2], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[3], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[4], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[5], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[6], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[7], ptr + index); + index += SIZEOF_UINT16; + break; + case CSR_MA_PACKET_CANCEL_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.HostTag, ptr + index); + index += SIZEOF_UINT32; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Data.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Data.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.TransmitRate, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.HostTag, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Priority, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MaPacketRequest.Ra.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.TransmissionControl, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Data.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Data.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.BeaconPeriod, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.DtimPeriod, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.CapabilityInformation, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeModifyBssParameterRequest.Bssid.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.RtsThreshold, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.InformationElements.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.InformationElements.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.TriggerId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.Priority, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_VIF_AVAILABILITY_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Multicast, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeHlSyncCancelRequest.GroupAddress.x, 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.BlackoutId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.KeyId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.KeyType, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeGetKeySequenceRequest.Address.x, 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Ifindex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Channel, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeSetChannelRequest.Address.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.AvailabilityDuration, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.AvailabilityInterval, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.DialogToken, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.MibAttribute.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.MibAttribute.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.TriggeredId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeAutonomousScanLossIndication.Bssid.x, 48 / 8); + index += 48 / 8; + break; +#endif + case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.FrameType, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.MinTransmitRate, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.PeriodicId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.MibAttributeValue.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.MibAttributeValue.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.Status, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.ErrorIndex, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.MibAttributeValue.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.MibAttributeValue.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.Status, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.ErrorIndex, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeStopAggregationRequest.PeerQstaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Direction, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.TriggerId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutType, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutSource, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutStartReference, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutPeriod, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutDuration, ptr + index); + index += SIZEOF_UINT32; + CsrMemCpy(ptr + index, sig->u.MlmeAddBlackoutRequest.PeerStaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutCount, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.KeyId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.KeyType, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeDeletekeysRequest.Address.x, 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeHlSyncConfirm.GroupAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ChannelList.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ChannelList.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.InformationElements.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.InformationElements.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.Ifindex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ChannelStartingFactor, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ScanType, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ProbeDelay, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.MinChannelTime, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.MaxChannelTime, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.MibAttributeValue.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.MibAttributeValue.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Beacon.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Beacon.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.BssParameters.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.BssParameters.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Ifindex, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Channel, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeSmStartRequest.InterfaceAddress.x, 48 / 8); + index += 48 / 8; + CsrMemCpy(ptr + index, sig->u.MlmeSmStartRequest.Bssid.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.BeaconPeriod, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.DtimPeriod, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.CapabilityInformation, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.PeriodicId, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Key.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Key.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Length, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.KeyId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.KeyType, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeSetkeysRequest.Address.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[0], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[1], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[2], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[3], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[4], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[5], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[6], ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[7], ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, &sig->u.MlmeSetkeysRequest.CipherSuiteSelector, 32 / 8); + index += 32 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.AutonomousScanId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Pause, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.MibAttribute.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.MibAttribute.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.PowerManagementMode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.ReceiveDtims, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.ListenInterval, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.TrafficWindow, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_ERROR_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MaPacketErrorIndication.PeerQstaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.SequenceNumber, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.PeriodicId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.MaximumLatency, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.PeriodicSchedulingMode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.WakeHost, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.UserPriority, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Direction, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.PsScheme, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.MediumTime, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.ServiceStartTime, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.ServiceInterval, ptr + index); + index += SIZEOF_UINT32; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.MinimumDataRate, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.DebugMessage.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.DebugMessage.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.FrameType, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeBlockackErrorIndication.PeerQstaAddress.x, 48 / 8); + index += 48 / 8; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.MibAttributeValue.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.MibAttributeValue.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.Status, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.ErrorIndex, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.MeasurementRequestSet.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.MeasurementRequestSet.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.DialogToken, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CsrMemCpy(ptr + index, sig->u.MlmeStartAggregationConfirm.PeerQstaAddress.x, 48 / 8); + index += 48 / 8; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.UserPriority, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Direction, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.SequenceNumber, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.DialogToken, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + case CSR_MA_PACKET_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.TransmissionStatus, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.RetryCount, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Rate, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.HostTag, ptr + index); + index += SIZEOF_UINT32; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.VirtualInterfaceIdentifier, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.PeriodicId, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.ResultCode, ptr + index); + index += SIZEOF_UINT16; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_REQUEST_ID: + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref1.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref1.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref2.SlotNumber, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref2.DataLength, ptr + index); + index += SIZEOF_UINT16; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.DialogToken, ptr + index); + index += SIZEOF_UINT16; + break; +#endif + + default: + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + *sig_len = index; + + return CSR_RESULT_SUCCESS; +} /* write_pack() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_send.c b/drivers/staging/csr/csr_wifi_hip_send.c new file mode 100644 index 000000000000..624f3bb37129 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_send.c @@ -0,0 +1,422 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * *************************************************************************** + * + * FILE: csr_wifi_hip_send.c + * + * PURPOSE: + * Code for adding a signal request to the from-host queue. + * When the driver bottom-half is run, it will take requests from the + * queue and pass them to the UniFi. + * + * *************************************************************************** + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "csr_wifi_hip_sigs.h" +#include "csr_wifi_hip_card.h" + +unifi_TrafficQueue unifi_frame_priority_to_queue(CSR_PRIORITY priority) +{ + switch (priority) + { + case CSR_QOS_UP0: + case CSR_QOS_UP3: + return UNIFI_TRAFFIC_Q_BE; + case CSR_QOS_UP1: + case CSR_QOS_UP2: + return UNIFI_TRAFFIC_Q_BK; + case CSR_QOS_UP4: + case CSR_QOS_UP5: + return UNIFI_TRAFFIC_Q_VI; + case CSR_QOS_UP6: + case CSR_QOS_UP7: + case CSR_MANAGEMENT: + return UNIFI_TRAFFIC_Q_VO; + default: + return UNIFI_TRAFFIC_Q_BE; + } +} + + +CSR_PRIORITY unifi_get_default_downgrade_priority(unifi_TrafficQueue queue) +{ + switch (queue) + { + case UNIFI_TRAFFIC_Q_BE: + return CSR_QOS_UP0; + case UNIFI_TRAFFIC_Q_BK: + return CSR_QOS_UP1; + case UNIFI_TRAFFIC_Q_VI: + return CSR_QOS_UP5; + case UNIFI_TRAFFIC_Q_VO: + return CSR_QOS_UP6; + default: + return CSR_QOS_UP0; + } +} + + +/* + * --------------------------------------------------------------------------- + * send_signal + * + * This function queues a signal for sending to UniFi. It first checks + * that there is space on the fh_signal_queue for another entry, then + * claims any bulk data slots required and copies data into them. Then + * increments the fh_signal_queue write count. + * + * The fh_signal_queue is later processed by the driver bottom half + * (in unifi_bh()). + * + * This function call unifi_pause_xmit() to pause the flow of data plane + * packets when: + * - the fh_signal_queue ring buffer is full + * - there are less than UNIFI_MAX_DATA_REFERENCES (2) bulk data + * slots available. + * + * Arguments: + * card Pointer to card context structure + * sigptr Pointer to the signal to write to UniFi. + * siglen Number of bytes pointer to by sigptr. + * bulkdata Array of pointers to an associated bulk data. + * sigq To which from-host queue to add the signal. + * + * Returns: + * CSR_RESULT_SUCCESS on success + * CSR_WIFI_HIP_RESULT_NO_SPACE if there were insufficient data slots or + * no free signal queue entry + * + * Notes: + * Calls unifi_pause_xmit() when the last slots are used. + * --------------------------------------------------------------------------- + */ +static CsrResult send_signal(card_t *card, const CsrUint8 *sigptr, CsrUint32 siglen, + const bulk_data_param_t *bulkdata, + q_t *sigq, CsrUint32 priority_q, CsrUint32 run_bh) +{ + CsrUint16 i, data_slot_size; + card_signal_t *csptr; + CsrInt16 qe; + CsrResult r; + CsrInt16 debug_print = 0; + + data_slot_size = CardGetDataSlotSize(card); + + /* Check that the fh_data_queue has a free slot */ + if (!CSR_WIFI_HIP_Q_SLOTS_FREE(sigq)) + { + unifi_trace(card->ospriv, UDBG3, "send_signal: %s full\n", sigq->name); + + return CSR_WIFI_HIP_RESULT_NO_SPACE; + } + + /* + * Now add the signal to the From Host signal queue + */ + /* Get next slot on queue */ + qe = CSR_WIFI_HIP_Q_NEXT_W_SLOT(sigq); + csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, qe); + + /* Make up the card_signal struct */ + csptr->signal_length = (CsrUint16)siglen; + CsrMemCpy((void *)csptr->sigbuf, (void *)sigptr, siglen); + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) + { + if ((bulkdata != NULL) && (bulkdata->d[i].data_length != 0)) + { + CsrUint32 datalen = bulkdata->d[i].data_length; + + /* Make sure data will fit in a bulk data slot */ + if (bulkdata->d[i].os_data_ptr == NULL) + { + unifi_error(card->ospriv, "send_signal - NULL bulkdata[%d]\n", i); + debug_print++; + csptr->bulkdata[i].data_length = 0; + } + else + { + if (datalen > data_slot_size) + { + unifi_error(card->ospriv, + "send_signal - Invalid data length %u (@%p), " + "truncating\n", + datalen, bulkdata->d[i].os_data_ptr); + datalen = data_slot_size; + debug_print++; + } + /* Store the bulk data info in the soft queue. */ + csptr->bulkdata[i].os_data_ptr = (CsrUint8 *)bulkdata->d[i].os_data_ptr; + csptr->bulkdata[i].os_net_buf_ptr = (CsrUint8 *)bulkdata->d[i].os_net_buf_ptr; + csptr->bulkdata[i].net_buf_length = bulkdata->d[i].net_buf_length; + csptr->bulkdata[i].data_length = datalen; + } + } + else + { + UNIFI_INIT_BULK_DATA(&csptr->bulkdata[i]); + } + } + + if (debug_print) + { + const CsrUint8 *sig = sigptr; + + unifi_error(card->ospriv, "Signal(%d): %02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + siglen, + sig[0], sig[1], sig[2], sig[3], + sig[4], sig[5], sig[6], sig[7], + sig[8], sig[9], sig[10], sig[11], + sig[12], sig[13], sig[14], sig[15]); + unifi_error(card->ospriv, "Bulkdata pointer %p(%d), %p(%d)\n", + bulkdata != NULL?bulkdata->d[0].os_data_ptr : NULL, + bulkdata != NULL?bulkdata->d[0].data_length : 0, + bulkdata != NULL?bulkdata->d[1].os_data_ptr : NULL, + bulkdata != NULL?bulkdata->d[1].data_length : 0); + } + + /* Advance the written count to say there is a new entry */ + CSR_WIFI_HIP_Q_INC_W(sigq); + + /* + * Set the flag to say reason for waking was a host request. + * Then ask the OS layer to run the unifi_bh. + */ + if (run_bh == 1) + { + card->bh_reason_host = 1; + r = unifi_run_bh(card->ospriv); + if (r != CSR_RESULT_SUCCESS) + { + unifi_error(card->ospriv, "failed to run bh.\n"); + card->bh_reason_host = 0; + + /* + * The bulk data buffer will be freed by the caller. + * We need to invalidate the description of the bulk data in our + * soft queue, to prevent the core freeing the bulk data again later. + */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) + { + if (csptr->bulkdata[i].data_length != 0) + { + csptr->bulkdata[i].os_data_ptr = csptr->bulkdata[i].os_net_buf_ptr = NULL; + csptr->bulkdata[i].net_buf_length = csptr->bulkdata[i].data_length = 0; + } + } + return r; + } + } + else + { + unifi_error(card->ospriv, "run_bh=%d, bh not called.\n", run_bh); + } + + /* + * Have we used up all the fh signal list entries? + */ + if (CSR_WIFI_HIP_Q_SLOTS_FREE(sigq) == 0) + { + /* We have filled the queue, so stop the upper layer. The command queue + * is an exception, as suspending due to that being full could delay + * resume/retry until new commands or data are received. + */ + if (sigq != &card->fh_command_queue) + { + /* + * Must call unifi_pause_xmit() *before* setting the paused flag. + * (the unifi_pause_xmit call should not be after setting the flag because of the possibility of being interrupted + * by the bh thread between our setting the flag and the call to unifi_pause_xmit() + * If bh thread then cleared the flag, we would end up paused, but without the flag set) + * Instead, setting it afterwards means that if this thread is interrupted by the bh thread + * the pause flag is still guaranteed to end up set + * However the potential deadlock now is that if bh thread emptied the queue and cleared the flag before this thread's + * call to unifi_pause_xmit(), then bh thread may not run again because it will be waiting for + * a packet to appear in the queue but nothing ever will because xmit is paused. + * So we will end up with the queue paused, and the flag set to say it is paused, but bh never runs to unpause it. + * (Note even this bad situation would not persist long in practice, because something else (eg rx, or tx in different queue) + * is likely to wake bh thread quite soon) + * But to avoid this deadlock completely, after setting the flag we check that there is something left in the queue. + * If there is, we know that bh thread has not emptied the queue yet. + * Since bh thread checks to unpause the queue *after* taking packets from the queue, we know that it is still going to make at + * least one more check to see whether it needs to unpause the queue. So all is well. + * If there are no packets in the queue, then the deadlock described above might happen. To make sure it does not, we + * unpause the queue here. A possible side effect is that unifi_restart_xmit() may (rarely) be called for second time + * unnecessarily, which is harmless + */ + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("P"); +#endif + unifi_pause_xmit(card->ospriv, (unifi_TrafficQueue)priority_q); + card_tx_q_pause(card, priority_q); + if (CSR_WIFI_HIP_Q_SLOTS_USED(sigq) == 0) + { + card_tx_q_unpause(card, priority_q); + unifi_restart_xmit(card->ospriv, (unifi_TrafficQueue) priority_q); + } + } + else + { + unifi_warning(card->ospriv, + "send_signal: fh_cmd_q full, not pausing (run_bh=%d)\n", + run_bh); + } + } + + func_exit(); + + return CSR_RESULT_SUCCESS; +} /* send_signal() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_send_signal + * + * Invokes send_signal() to queue a signal in the command or traffic queue + * If sigptr pointer is NULL, it pokes the bh to check if UniFi is responsive. + * + * Arguments: + * card Pointer to card context struct + * sigptr Pointer to signal from card. + * siglen Size of the signal + * bulkdata Pointer to the bulk data of the signal + * + * Returns: + * CSR_RESULT_SUCCESS on success + * CSR_WIFI_HIP_RESULT_NO_SPACE if there were insufficient data slots or no free signal queue entry + * + * Notes: + * unifi_send_signal() is used to queue signals, created by the driver, + * to the device. Signals are constructed using the UniFi packed structures. + * --------------------------------------------------------------------------- + */ +CsrResult unifi_send_signal(card_t *card, const CsrUint8 *sigptr, CsrUint32 siglen, + const bulk_data_param_t *bulkdata) +{ + q_t *sig_soft_q; + CsrUint16 signal_id; + CsrResult r; + CsrUint32 run_bh; + CsrUint32 priority_q; + + /* A NULL signal pointer is a request to check if UniFi is responsive */ + if (sigptr == NULL) + { + card->bh_reason_host = 1; + return unifi_run_bh(card->ospriv); + } + + priority_q = 0; + run_bh = 1; + signal_id = GET_SIGNAL_ID(sigptr); + /* + * If the signal is a CSR_MA_PACKET_REQUEST , + * we send it using the traffic soft queue. Else we use the command soft queue. + */ + if (signal_id == CSR_MA_PACKET_REQUEST_ID) + { + CsrUint16 frame_priority; + + if (card->periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_ENABLED) + { + run_bh = 0; + } + +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) + unifi_debug_log_to_buf("D"); +#endif + /* Sanity check: MA-PACKET.req must have a valid bulk data */ + if ((bulkdata->d[0].data_length == 0) || (bulkdata->d[0].os_data_ptr == NULL)) + { + unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n", + bulkdata->d[0].data_length, bulkdata->d[0].os_data_ptr); + dump((void *)sigptr, siglen); + return CSR_RESULT_FAILURE; + } + + /* Map the frame priority to a traffic queue index. */ + frame_priority = GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(sigptr); + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY)frame_priority); + + sig_soft_q = &card->fh_traffic_queue[priority_q]; + } + else + { + sig_soft_q = &card->fh_command_queue; + } + + r = send_signal(card, sigptr, siglen, bulkdata, sig_soft_q, priority_q, run_bh); + /* On error, the caller must free or requeue bulkdata buffers */ + + return r; +} /* unifi_send_signal() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_send_resources_available + * + * Examines whether there is available space to queue + * a signal in the command or traffic queue + * + * Arguments: + * card Pointer to card context struct + * sigptr Pointer to signal. + * + * Returns: + * CSR_RESULT_SUCCESS if resources available + * CSR_WIFI_HIP_RESULT_NO_SPACE if there was no free signal queue entry + * + * Notes: + * --------------------------------------------------------------------------- + */ +CsrResult unifi_send_resources_available(card_t *card, const CsrUint8 *sigptr) +{ + q_t *sig_soft_q; + CsrUint16 signal_id = GET_SIGNAL_ID(sigptr); + + /* + * If the signal is a CSR_MA_PACKET_REQUEST , + * we send it using the traffic soft queue. Else we use the command soft queue. + */ + if (signal_id == CSR_MA_PACKET_REQUEST_ID) + { + CsrUint16 frame_priority; + CsrUint32 priority_q; + + /* Map the frame priority to a traffic queue index. */ + frame_priority = GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(sigptr); + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY)frame_priority); + + sig_soft_q = &card->fh_traffic_queue[priority_q]; + } + else + { + sig_soft_q = &card->fh_command_queue; + } + + /* Check that the fh_data_queue has a free slot */ + if (!CSR_WIFI_HIP_Q_SLOTS_FREE(sig_soft_q)) + { + unifi_notice(card->ospriv, "unifi_send_resources_available: %s full\n", + sig_soft_q->name); + return CSR_WIFI_HIP_RESULT_NO_SPACE; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_send_resources_available() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_signals.c b/drivers/staging/csr/csr_wifi_hip_signals.c new file mode 100644 index 000000000000..5d0be5397a4f --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_signals.c @@ -0,0 +1,1313 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + + +/* Generated by hip_dd_l_c_gen.pl */ + +#include "csr_wifi_hip_signals.h" + +#include "csr_wifi_hip_unifi.h" + +CsrInt32 SigGetSize(const CSR_SIGNAL *aSignal) +{ + switch (aSignal->SignalPrimitiveHeader.SignalId) + { + case CSR_MA_PACKET_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_REQUEST); + case CSR_MA_PACKET_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_CONFIRM); + case CSR_MA_PACKET_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_INDICATION); + case CSR_MA_PACKET_CANCEL_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_CANCEL_REQUEST); + case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_VIF_AVAILABILITY_RESPONSE); + case CSR_MA_VIF_AVAILABILITY_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_VIF_AVAILABILITY_INDICATION); + case CSR_MA_PACKET_ERROR_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_ERROR_INDICATION); +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_NEXT_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_NEXT_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_POWERMGT_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_POWERMGT_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETKEYS_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETKEYS_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELETEKEYS_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELETEKEYS_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECTED_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECTED_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CANCEL_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_CANCEL_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CANCEL_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CANCEL_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_PERIODIC_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_PERIODIC_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_PERIODIC_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_PERIODIC_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_PACKET_FILTER_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_PACKET_FILTER_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_MEASURE_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_MEASURE_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TRIGGERED_GET_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TRIGGERED_GET_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TRIGGERED_GET_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TRIGGERED_GET_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_TRIGGERED_GET_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_TRIGGERED_GET_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_BLACKOUT_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_BLACKOUT_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_BLACKOUT_ENDED_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_BLACKOUT_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_BLACKOUT_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_RX_TRIGGER_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_RX_TRIGGER_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_RX_TRIGGER_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_RX_TRIGGER_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECT_STATUS_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECT_STATUS_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TEMPLATE_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TEMPLATE_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONFIG_QUEUE_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONFIG_QUEUE_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TSPEC_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TSPEC_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TSPEC_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TSPEC_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_START_AGGREGATION_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_START_AGGREGATION_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_BLOCKACK_ERROR_INDICATION); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_AGGREGATION_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_AGGREGATION_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SM_START_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SM_START_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_LEAVE_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_LEAVE_CONFIRM); +#endif + case CSR_MLME_SET_TIM_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_TIM_REQUEST); + case CSR_MLME_SET_TIM_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_TIM_CONFIRM); +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_KEY_SEQUENCE_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_KEY_SEQUENCE_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CHANNEL_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CHANNEL_CONFIRM); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST); +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM); +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_STRING_INDICATION); + case CSR_DEBUG_WORD16_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_WORD16_INDICATION); + case CSR_DEBUG_GENERIC_REQUEST_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_REQUEST); + case CSR_DEBUG_GENERIC_CONFIRM_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_CONFIRM); + case CSR_DEBUG_GENERIC_INDICATION_ID: + return CsrOffsetOf(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_INDICATION); + default: + return 0; + } +} + + +CsrInt32 SigGetDataRefs(CSR_SIGNAL *aSignal, CSR_DATAREF **aDataRef) +{ + CsrInt32 numRefs = 0; + + switch (aSignal->SignalPrimitiveHeader.SignalId) + { + case CSR_MA_PACKET_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MaPacketRequest.Data; + aDataRef[numRefs++] = &aSignal->u.MaPacketRequest.Dummydataref2; + break; + case CSR_MA_PACKET_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MaPacketConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MaPacketConfirm.Dummydataref2; + break; + case CSR_MA_PACKET_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MaPacketIndication.Data; + aDataRef[numRefs++] = &aSignal->u.MaPacketIndication.Dummydataref2; + break; + case CSR_MA_PACKET_CANCEL_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MaPacketCancelRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MaPacketCancelRequest.Dummydataref2; + break; + case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID: + aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityResponse.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityResponse.Dummydataref2; + break; + case CSR_MA_VIF_AVAILABILITY_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityIndication.Dummydataref2; + break; + case CSR_MA_PACKET_ERROR_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MaPacketErrorIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MaPacketErrorIndication.Dummydataref2; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeResetRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeResetRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeResetConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeResetConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeGetRequest.MibAttribute; + aDataRef[numRefs++] = &aSignal->u.MlmeGetRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeGetConfirm.MibAttributeValue; + aDataRef[numRefs++] = &aSignal->u.MlmeGetConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetRequest.MibAttributeValue; + aDataRef[numRefs++] = &aSignal->u.MlmeSetRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetConfirm.MibAttributeValue; + aDataRef[numRefs++] = &aSignal->u.MlmeSetConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeGetNextRequest.MibAttribute; + aDataRef[numRefs++] = &aSignal->u.MlmeGetNextRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeGetNextConfirm.MibAttributeValue; + aDataRef[numRefs++] = &aSignal->u.MlmeGetNextConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmePowermgtRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmePowermgtRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmePowermgtConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmePowermgtConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeScanRequest.ChannelList; + aDataRef[numRefs++] = &aSignal->u.MlmeScanRequest.InformationElements; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeScanConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeScanConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeMeasureRequest.MeasurementRequestSet; + aDataRef[numRefs++] = &aSignal->u.MlmeMeasureRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeMeasureConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeMeasureConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeMeasureIndication.MeasurementReportSet; + aDataRef[numRefs++] = &aSignal->u.MlmeMeasureIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysRequest.Key; + aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanLossIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanLossIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECTED_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeConnectedIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeConnectedIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CANCEL_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeScanCancelRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeScanCancelRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanRequest.ChannelList; + aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanRequest.InformationElements; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterRequest.InformationElements; + aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanDoneIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanDoneIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetRequest.MibAttribute; + aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_TRIGGERED_GET_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeTriggeredGetIndication.MibAttributeValue; + aDataRef[numRefs++] = &aSignal->u.MlmeTriggeredGetIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeBlackoutEndedIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeBlackoutEndedIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerRequest.InformationElements; + aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusRequest.InformationElements; + aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterRequest.Data; + aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateRequest.Data1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateRequest.Data2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeBlockackErrorIndication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeBlockackErrorIndication.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSmStartRequest.Beacon; + aDataRef[numRefs++] = &aSignal->u.MlmeSmStartRequest.BssParameters; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSmStartConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSmStartConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeLeaveRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeLeaveRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeLeaveConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeLeaveConfirm.Dummydataref2; + break; +#endif + case CSR_MLME_SET_TIM_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetTimRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSetTimRequest.Dummydataref2; + break; + case CSR_MLME_SET_TIM_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetTimConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSetTimConfirm.Dummydataref2; + break; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelRequest.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelConfirm.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressRequest.Data; + aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressRequest.Dummydataref2; + break; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressConfirm.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressConfirm.Dummydataref2; + break; +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.DebugStringIndication.DebugMessage; + aDataRef[numRefs++] = &aSignal->u.DebugStringIndication.Dummydataref2; + break; + case CSR_DEBUG_WORD16_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.DebugWord16Indication.Dummydataref1; + aDataRef[numRefs++] = &aSignal->u.DebugWord16Indication.Dummydataref2; + break; + case CSR_DEBUG_GENERIC_REQUEST_ID: + aDataRef[numRefs++] = &aSignal->u.DebugGenericRequest.DebugVariable; + aDataRef[numRefs++] = &aSignal->u.DebugGenericRequest.Dummydataref2; + break; + case CSR_DEBUG_GENERIC_CONFIRM_ID: + aDataRef[numRefs++] = &aSignal->u.DebugGenericConfirm.DebugVariable; + aDataRef[numRefs++] = &aSignal->u.DebugGenericConfirm.Dummydataref2; + break; + case CSR_DEBUG_GENERIC_INDICATION_ID: + aDataRef[numRefs++] = &aSignal->u.DebugGenericIndication.DebugVariable; + aDataRef[numRefs++] = &aSignal->u.DebugGenericIndication.Dummydataref2; + break; + default: + return 0; + } + return numRefs; +} + + +CsrUint32 SigGetFilterPos(CsrUint16 aSigID) +{ + switch (aSigID) + { + case CSR_MA_PACKET_REQUEST_ID: + return 0x00000001; + case CSR_MA_PACKET_CONFIRM_ID: + return 0x00000002; + case CSR_MA_PACKET_INDICATION_ID: + return 0x00000004; + case CSR_MA_PACKET_CANCEL_REQUEST_ID: + return 0x00000008; + case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID: + return 0x00000010; + case CSR_MA_VIF_AVAILABILITY_INDICATION_ID: + return 0x00000020; + case CSR_MA_PACKET_ERROR_INDICATION_ID: + return 0x00000040; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_REQUEST_ID: + return 0x00000080; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_RESET_CONFIRM_ID: + return 0x00000100; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_REQUEST_ID: + return 0x00000200; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_CONFIRM_ID: + return 0x00000400; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_REQUEST_ID: + return 0x00000800; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CONFIRM_ID: + return 0x00001000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_REQUEST_ID: + return 0x00002000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_NEXT_CONFIRM_ID: + return 0x00004000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_REQUEST_ID: + return 0x00008000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_POWERMGT_CONFIRM_ID: + return 0x00010001; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_REQUEST_ID: + return 0x00010002; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CONFIRM_ID: + return 0x00010004; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_REQUEST_ID: + return 0x00010008; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CONFIRM_ID: + return 0x00010010; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_REQUEST_ID: + return 0x00010020; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_CONFIRM_ID: + return 0x00010040; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MEASURE_INDICATION_ID: + return 0x00010080; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_REQUEST_ID: + return 0x00010100; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SETKEYS_CONFIRM_ID: + return 0x00010200; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_REQUEST_ID: + return 0x00010400; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + return 0x00010800; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID: + return 0x00011000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECTED_INDICATION_ID: + return 0x00012000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SCAN_CANCEL_REQUEST_ID: + return 0x00014000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID: + return 0x00018000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + return 0x00020001; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_REQUEST_ID: + return 0x00020002; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + return 0x00020004; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_REQUEST_ID: + return 0x00020008; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + return 0x00020010; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID: + return 0x00020020; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + return 0x00020040; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID: + return 0x00020080; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + return 0x00020100; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID: + return 0x00020200; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + return 0x00020400; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_REQUEST_ID: + return 0x00020800; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + return 0x00021000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID: + return 0x00022000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + return 0x00024000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID: + return 0x00028000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID: + return 0x00030001; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + return 0x00030002; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID: + return 0x00030004; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + return 0x00030008; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_TRIGGERED_GET_INDICATION_ID: + return 0x00030010; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_REQUEST_ID: + return 0x00030020; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + return 0x00030040; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID: + return 0x00030080; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_REQUEST_ID: + return 0x00030100; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + return 0x00030200; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID: + return 0x00030400; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + return 0x00030800; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID: + return 0x00031000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + return 0x00032000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_REQUEST_ID: + return 0x00034000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + return 0x00038000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID: + return 0x00040001; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + return 0x00040002; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_REQUEST_ID: + return 0x00040004; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + return 0x00040008; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_REQUEST_ID: + return 0x00040010; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + return 0x00040020; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_REQUEST_ID: + return 0x00040040; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + return 0x00040080; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_REQUEST_ID: + return 0x00040100; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + return 0x00040200; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_REQUEST_ID: + return 0x00040400; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + return 0x00040800; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID: + return 0x00041000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_REQUEST_ID: + return 0x00042000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + return 0x00044000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_REQUEST_ID: + return 0x00048000; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SM_START_CONFIRM_ID: + return 0x00050001; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_REQUEST_ID: + return 0x00050002; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_LEAVE_CONFIRM_ID: + return 0x00050004; +#endif + case CSR_MLME_SET_TIM_REQUEST_ID: + return 0x00050008; + case CSR_MLME_SET_TIM_CONFIRM_ID: + return 0x00050010; +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID: + return 0x00050020; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + return 0x00050040; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_REQUEST_ID: + return 0x00050080; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + return 0x00050100; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID: + return 0x00050200; +#endif +#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + return 0x00050400; +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + return 0x00050800; + case CSR_DEBUG_WORD16_INDICATION_ID: + return 0x00051000; + case CSR_DEBUG_GENERIC_REQUEST_ID: + return 0x00052000; + case CSR_DEBUG_GENERIC_CONFIRM_ID: + return 0x00054000; + case CSR_DEBUG_GENERIC_INDICATION_ID: + return 0x00058000; + default: + break; + } + return 0xffffffff; +} + + diff --git a/drivers/staging/csr/csr_wifi_hip_signals.h b/drivers/staging/csr/csr_wifi_hip_signals.h new file mode 100644 index 000000000000..c48fddd5fa34 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_signals.h @@ -0,0 +1,137 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + ***************************************************************************** + * + * FILE: csr_wifi_hip_signals.h + * + * PURPOSE: + * Header file wrapping the auto-generated code in csr_wifi_hip_sigs.h + * and csr_wifi_hip_signals.c - + * csr_wifi_hip_sigs.h provides structures defining UniFi signals and + * csr_wifi_hip_signals.c provides SigGetSize() and SigGetDataRefs(). + * + ***************************************************************************** + */ +#ifndef __CSR_WIFI_HIP_SIGNALS_H__ +#define __CSR_WIFI_HIP_SIGNALS_H__ + +#include "csr_types.h" +#include "csr_wifi_hip_sigs.h" + + +/****************************************************************************/ +/* INFORMATION ELEMENTS */ +/****************************************************************************/ + +/* Information Element ID's - shouldn't be in here, but nowhere better yet */ +#define IE_SSID_ID 0 +#define IE_SUPPORTED_RATES_ID 1 +#define IE_FH_PARAM_SET_ID 2 +#define IE_DS_PARAM_SET_ID 3 +#define IE_CF_PARAM_SET_ID 4 +#define IE_TIM_ID 5 +#define IE_IBSS_PARAM_SET_ID 6 +#define IE_COUNTRY_ID 7 +#define IE_HOPPING_PATTERN_PARAMS_ID 8 +#define IE_HOPPING_PATTERN_TABLE_ID 9 +#define IE_REQUEST_ID 10 +#define IE_QBSS_LOAD_ID 11 +#define IE_EDCA_PARAM_SET_ID 12 +#define IE_TRAFFIC_SPEC_ID 13 +#define IE_TRAFFIC_CLASS_ID 14 +#define IE_SCHEDULE_ID 15 +#define IE_CHALLENGE_TEXT_ID 16 +#define IE_POWER_CONSTRAINT_ID 32 +#define IE_POWER_CAPABILITY_ID 33 +#define IE_TPC_REQUEST_ID 34 +#define IE_TPC_REPORT_ID 35 +#define IE_SUPPORTED_CHANNELS_ID 36 +#define IE_CHANNEL_SWITCH_ANNOUNCE_ID 37 +#define IE_MEASUREMENT_REQUEST_ID 38 +#define IE_MEASUREMENT_REPORT_ID 39 +#define IE_QUIET_ID 40 +#define IE_IBSS_DFS_ID 41 +#define IE_ERP_INFO_ID 42 +#define IE_TS_DELAY_ID 43 +#define IE_TCLAS_PROCESSING_ID 44 +#define IE_QOS_CAPABILITY_ID 46 +#define IE_RSN_ID 48 +#define IE_EXTENDED_SUPPORTED_RATES_ID 50 +#define IE_AP_CHANNEL_REPORT_ID 52 +#define IE_RCPI_ID 53 +#define IE_WPA_ID 221 + + +/* The maximum number of data references in a signal structure */ +#define UNIFI_MAX_DATA_REFERENCES 2 + +/* The space to allow for a wire-format signal structure */ +#define UNIFI_PACKED_SIGBUF_SIZE 64 + + +/******************************************************************************/ +/* SIGNAL PARAMETER VALUES */ +/******************************************************************************/ + +/* ifIndex */ +#define UNIFI_IF_2G4 1 +#define UNIFI_IF_5G 2 + +/* SendProcessId */ +#define HOST_PROC_ID 0xc000 + +#define SIG_CAP_ESS 0x0001 +#define SIG_CAP_IBSS 0x0002 +#define SIG_CAP_CF_POLLABLE 0x0004 +#define SIG_CAP_CF_POLL_REQUEST 0x0008 +#define SIG_CAP_PRIVACY 0x0010 +#define SIG_CAP_SHORT_PREAMBLE 0x0020 +#define SIG_CAP_DSSSOFDM 0x2000 + +/******************************************************************************/ +/* FUNCTION DECLARATIONS */ +/******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/****************************************************************************** + * SigGetNumDataRefs - Retrieve pointers to data-refs from a signal. + * + * PARAMETERS: + * aSignal - Pointer to signal to retrieve the data refs of. + * aDataRef - Address of a pointer to the structure that the data refs + * pointers will be stored. + * + * RETURNS: + * The number of data-refs in the signal. + */ +CsrInt32 SigGetDataRefs(CSR_SIGNAL *aSignal, CSR_DATAREF **aDataRef); + +/****************************************************************************** + * SigGetSize - Retrieve the size (in bytes) of a given signal. + * + * PARAMETERS: + * aSignal - Pointer to signal to retrieve size of. + * + * RETURNS: + * The size (in bytes) of the given signal. + */ +CsrInt32 SigGetSize(const CSR_SIGNAL *aSignal); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __CSR_WIFI_HIP_SIGNALS_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_sigs.h b/drivers/staging/csr/csr_wifi_hip_sigs.h new file mode 100644 index 000000000000..c94e2a483975 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_sigs.h @@ -0,0 +1,1425 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + + +/* Generated by hip_dd_l_h_gen.pl */ + +#ifndef CSR_WIFI_HIP_SIGS_H +#define CSR_WIFI_HIP_SIGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef CsrInt16 csr_place_holding_type; + +typedef CsrUint16 CSR_ASSOCIATION_ID; + +typedef CsrUint16 CSR_AUTONOMOUS_SCAN_ID; + +typedef CsrUint16 CSR_BEACON_PERIODS; + +typedef CsrUint16 CSR_BLACKOUT_ID; + +typedef enum CSR_BLACKOUT_SOURCE +{ + CSR_DOT11_LOCAL = 0x0000, + CSR_DOT11_REMOTE = 0x0001, + CSR_OTHER_RADIO = 0x0002, + CSR_NOT_LINKED = 0x0004 +} CSR_BLACKOUT_SOURCE; + +typedef enum CSR_BLACKOUT_TYPE +{ + CSR_LOCAL_DEVICE_ONLY = 0x0001, + CSR_SPECIFIED_PEER = 0x0002, + CSR_CURRENT_CHANNEL = 0x0004, + CSR_P2P = 0x0008 +} CSR_BLACKOUT_TYPE; + +typedef enum CSR_BOOT_LOADER_OPERATION +{ + CSR_BOOT_LOADER_IDLE = 0x00, + CSR_BOOT_LOADER_RESTART = 0x01, + CSR_BOOT_LOADER_PATCH = 0x02, + CSR_BOOT_LOADER_IMAGE_0 = 0x10, + CSR_BOOT_LOADER_IMAGE_1 = 0x11, + CSR_BOOT_LOADER_IMAGE_2 = 0x12, + CSR_BOOT_LOADER_IMAGE_3 = 0x13 +} CSR_BOOT_LOADER_OPERATION; + +typedef CsrUint16 CSR_CAPABILITY_INFORMATION; + +typedef CsrUint16 CSR_CHANNEL_STARTING_FACTOR; + +typedef CsrUint32 CSR_CIPHER_SUITE_SELECTOR; + +typedef CsrUint32 CSR_CLIENT_TAG; + +typedef enum CSR_CONNECTION_STATUS +{ + CSR_DISCONNECTED = 0x0000, + CSR_CONNECTED_AWAKE = 0x0001 +} CSR_CONNECTION_STATUS; + +typedef CsrInt16 CSR_DECIBELS; + +typedef enum CSR_DIRECTION +{ + CSR_TRANSMIT = 0x0000, + CSR_RECEIVE = 0x0001, + CSR_BIDIRECTIONAL = 0x0003 +} CSR_DIRECTION; + +typedef enum CSR_FRAME_TYPE +{ + CSR_RESERVED = 0x0000, + CSR_BEACON = 0x0001, + CSR_PROBE_RESPONSE = 0x0002, + CSR_BEACON_AND_PROBE_RESPONSE = 0x0003, + CSR_PROBE_REQUEST = 0x0004 +} CSR_FRAME_TYPE; + +typedef CsrUint32 CSR_IPV4_ADDRESS; + +typedef enum CSR_IFINTERFACE +{ + CSR_INDEX_2G4 = 0x0001, + CSR_INDEX_5G = 0x0002 +} CSR_IFINTERFACE; + +typedef enum CSR_KEY_TYPE +{ + CSR_GROUP = 0x0000, + CSR_PAIRWISE = 0x0001, + CSR_PEER_KEY = 0x0002, + CSR_IGTK = 0x0003 +} CSR_KEY_TYPE; + +typedef enum CSR_LOADER_OPERATION +{ + CSR_LOADER_IDLE = 0x0000, + CSR_LOADER_COPY = 0x0001 +} CSR_LOADER_OPERATION; + +typedef struct CSR_MAC_ADDRESS +{ + CsrUint8 x[6]; +} CSR_MACADDRESS; + +typedef enum CSR_MIB_STATUS +{ + CSR_MIB_SUCCESSFUL = 0x0000, + CSR_MIB_INVALID_PARAMETERS = 0x0001, + CSR_MIB_WRITE_ONLY = 0x0002, + CSR_MIB_READ_ONLY = 0x0003 +} CSR_MIB_STATUS; + +typedef enum CSR_MEMORY_SPACE +{ + CSR_NONE = 0x00, + CSR_SHARED_DATA_MEMORY = 0x01, + CSR_EXTERNAL_FLASH_MEMORY = 0x02, + CSR_EXTERNAL_SRAM = 0x03, + CSR_REGISTERS = 0x04, + CSR_PHY_PROCESSOR_DATA_MEMORY = 0x10, + CSR_PHY_PROCESSOR_PROGRAM_MEMORY = 0x11, + CSR_PHY_PROCESSOR_ROM = 0x12, + CSR_MAC_PROCESSOR_DATA_MEMORY = 0x20, + CSR_MAC_PROCESSOR_PROGRAM_MEMORY = 0x21, + CSR_MAC_PROCESSOR_ROM = 0x22, + CSR_BT_PROCESSOR_DATA_MEMORY = 0x30, + CSR_BT_PROCESSOR_PROGRAM_MEMORY = 0x31, + CSR_BT_PROCESSOR_ROM = 0x32 +} CSR_MEMORY_SPACE; + +typedef CsrUint16 CSR_MICROSECONDS16; + +typedef CsrUint32 CSR_MICROSECONDS32; + +typedef CsrUint16 CSR_NATURAL16; + +typedef enum CSR_PS_SCHEME +{ + CSR_LEGACY_PS = 0x0001, + CSR_U_APSD = 0x0002, + CSR_S_APSD = 0x0004 +} CSR_PS_SCHEME; + +typedef enum CSR_PACKET_FILTER_MODE +{ + CSR_PFM_OPT_OUT = 0x0000, + CSR_PFM_OPT_IN = 0x0003 +} CSR_PACKET_FILTER_MODE; + +typedef CsrUint16 CSR_PERIODIC_ID; + +typedef enum CSR_PERIODIC_SCHEDULING_MODE +{ + CSR_PSM_PERIODIC_SCHEDULE_PS_POLL = 0x0001, + CSR_PSM_PERIODIC_SCHEDULE_PM_BIT = 0x0002, + CSR_PSM_PERIODIC_SCHEDULE_UAPSD = 0x0004, + CSR_PSM_PERIODIC_SCHEDULE_SAPSD = 0x0008 +} CSR_PERIODIC_SCHEDULING_MODE; + +typedef enum CSR_POWER_MANAGEMENT_MODE +{ + CSR_PMM_ACTIVE_MODE = 0x0000, + CSR_PMM_POWER_SAVE = 0x0001, + CSR_PMM_FAST_POWER_SAVE = 0x0002 +} CSR_POWER_MANAGEMENT_MODE; + +typedef enum CSR_PRIORITY +{ + CSR_QOS_UP0 = 0x0000, + CSR_QOS_UP1 = 0x0001, + CSR_QOS_UP2 = 0x0002, + CSR_QOS_UP3 = 0x0003, + CSR_QOS_UP4 = 0x0004, + CSR_QOS_UP5 = 0x0005, + CSR_QOS_UP6 = 0x0006, + CSR_QOS_UP7 = 0x0007, + CSR_CONTENTION = 0x8000, + CSR_MANAGEMENT = 0x8010 +} CSR_PRIORITY; + +typedef enum CSR_REASON_CODE +{ + CSR_UNSPECIFIED_REASON = 0x0001, + CSR_INVALID_INFORMATION_ELEMENT = 0x000d, + CSR_QOS_UNSPECIFIED_REASON = 0x0020, + CSR_QOS_EXCESSIVE_NOT_ACK = 0x0022, + CSR_QOS_TXOP_LIMIT_EXCEEDED = 0x0023, + CSR_QSTA_LEAVING = 0x0024, + CSR_UNKNOWN_BA = 0x0026, + CSR_UNKNOWN_TS = 0x0026, + CSR_TIMEOUT = 0x0027 +} CSR_REASON_CODE; + +typedef enum CSR_RECEPTION_STATUS +{ + CSR_RX_SUCCESS = 0x0000, + CSR_RX_FAILURE_UNSPECIFIED = 0x0001, + CSR_MICHAEL_MIC_ERROR = 0x0002, + CSR_DECRYPTION_ERROR = 0x0003, + CSR_NO_TEMPORAL_KEY_AVAILABLE = 0x0004, + CSR_UNSUPPORTED_MODULATION = 0x0011, + CSR_BAD_FCS = 0x0012, + CSR_BAD_SIGNAL = 0x0013 +} CSR_RECEPTION_STATUS; + +typedef enum CSR_RESULT_CODE +{ + CSR_RC_SUCCESS = 0x0000, + CSR_RC_UNSPECIFIED_FAILURE = 0x0001, + CSR_RC_REFUSED = 0x0003, + CSR_RC_INVALID_PARAMETERS = 0x0026, + CSR_RC_REJECTED_INVALID_IE = 0x0028, + CSR_RC_REJECTED_INVALID_GROUP_CIPHER = 0x0029, + CSR_RC_REJECTED_INVALID_PAIRWISE_CIPHER = 0x002a, + CSR_RC_TIMEOUT = 0x8000, + CSR_RC_TOO_MANY_SIMULTANEOUS_REQUESTS = 0x8001, + CSR_RC_BSS_ALREADY_STARTED_OR_JOINED = 0x8002, + CSR_RC_NOT_SUPPORTED = 0x8003, + CSR_RC_TRANSMISSION_FAILURE = 0x8004, + CSR_RC_RESET_REQUIRED_BEFORE_START = 0x8006, + CSR_RC_INSUFFICIENT_RESOURCE = 0x8007, + CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES = 0x8008, + CSR_RC_INVALID_UNICAST_CIPHER = 0xf02f, + CSR_RC_INVALID_MULTICAST_CIPHER = 0xf030 +} CSR_RESULT_CODE; + +typedef enum CSR_SCAN_TYPE +{ + CSR_SC_ACTIVE_SCAN = 0x0000, + CSR_SC_PASSIVE_SCAN = 0x0001 +} CSR_SCAN_TYPE; + +typedef enum CSR_SIGNAL_ID +{ + CSR_MA_PACKET_REQUEST_ID = 0x0110, + CSR_MA_PACKET_CONFIRM_ID = 0x0111, + CSR_MA_PACKET_INDICATION_ID = 0x0113, + CSR_MA_PACKET_CANCEL_REQUEST_ID = 0x0114, + CSR_MA_VIF_AVAILABILITY_RESPONSE_ID = 0x0116, + CSR_MA_VIF_AVAILABILITY_INDICATION_ID = 0x0117, + CSR_MA_PACKET_ERROR_INDICATION_ID = 0x011b, + CSR_MLME_RESET_REQUEST_ID = 0x0200, + CSR_MLME_RESET_CONFIRM_ID = 0x0201, + CSR_MLME_GET_REQUEST_ID = 0x0204, + CSR_MLME_GET_CONFIRM_ID = 0x0205, + CSR_MLME_SET_REQUEST_ID = 0x0208, + CSR_MLME_SET_CONFIRM_ID = 0x0209, + CSR_MLME_GET_NEXT_REQUEST_ID = 0x020c, + CSR_MLME_GET_NEXT_CONFIRM_ID = 0x020d, + CSR_MLME_POWERMGT_REQUEST_ID = 0x0210, + CSR_MLME_POWERMGT_CONFIRM_ID = 0x0211, + CSR_MLME_SCAN_REQUEST_ID = 0x0214, + CSR_MLME_SCAN_CONFIRM_ID = 0x0215, + CSR_MLME_HL_SYNC_REQUEST_ID = 0x0244, + CSR_MLME_HL_SYNC_CONFIRM_ID = 0x0245, + CSR_MLME_MEASURE_REQUEST_ID = 0x0258, + CSR_MLME_MEASURE_CONFIRM_ID = 0x0259, + CSR_MLME_MEASURE_INDICATION_ID = 0x025b, + CSR_MLME_SETKEYS_REQUEST_ID = 0x0268, + CSR_MLME_SETKEYS_CONFIRM_ID = 0x0269, + CSR_MLME_DELETEKEYS_REQUEST_ID = 0x026c, + CSR_MLME_DELETEKEYS_CONFIRM_ID = 0x026d, + CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID = 0x0287, + CSR_MLME_CONNECTED_INDICATION_ID = 0x028b, + CSR_MLME_SCAN_CANCEL_REQUEST_ID = 0x028c, + CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID = 0x0298, + CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID = 0x0299, + CSR_MLME_ADD_PERIODIC_REQUEST_ID = 0x02a0, + CSR_MLME_ADD_PERIODIC_CONFIRM_ID = 0x02a1, + CSR_MLME_DEL_PERIODIC_REQUEST_ID = 0x02a4, + CSR_MLME_DEL_PERIODIC_CONFIRM_ID = 0x02a5, + CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID = 0x02a8, + CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID = 0x02a9, + CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID = 0x02ac, + CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID = 0x02ad, + CSR_MLME_SET_PACKET_FILTER_REQUEST_ID = 0x02b8, + CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID = 0x02b9, + CSR_MLME_STOP_MEASURE_REQUEST_ID = 0x02bc, + CSR_MLME_STOP_MEASURE_CONFIRM_ID = 0x02bd, + CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID = 0x02cc, + CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID = 0x02cd, + CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID = 0x02db, + CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID = 0x02dc, + CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID = 0x02dd, + CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID = 0x02e0, + CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID = 0x02e1, + CSR_MLME_TRIGGERED_GET_INDICATION_ID = 0x02e7, + CSR_MLME_ADD_BLACKOUT_REQUEST_ID = 0x02f8, + CSR_MLME_ADD_BLACKOUT_CONFIRM_ID = 0x02f9, + CSR_MLME_BLACKOUT_ENDED_INDICATION_ID = 0x02fb, + CSR_MLME_DEL_BLACKOUT_REQUEST_ID = 0x02fc, + CSR_MLME_DEL_BLACKOUT_CONFIRM_ID = 0x02fd, + CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID = 0x0304, + CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID = 0x0305, + CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID = 0x0308, + CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID = 0x0309, + CSR_MLME_CONNECT_STATUS_REQUEST_ID = 0x0310, + CSR_MLME_CONNECT_STATUS_CONFIRM_ID = 0x0311, + CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID = 0x0314, + CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID = 0x0315, + CSR_MLME_ADD_TEMPLATE_REQUEST_ID = 0x0318, + CSR_MLME_ADD_TEMPLATE_CONFIRM_ID = 0x0319, + CSR_MLME_CONFIG_QUEUE_REQUEST_ID = 0x031c, + CSR_MLME_CONFIG_QUEUE_CONFIRM_ID = 0x031d, + CSR_MLME_ADD_TSPEC_REQUEST_ID = 0x0320, + CSR_MLME_ADD_TSPEC_CONFIRM_ID = 0x0321, + CSR_MLME_DEL_TSPEC_REQUEST_ID = 0x0324, + CSR_MLME_DEL_TSPEC_CONFIRM_ID = 0x0325, + CSR_MLME_START_AGGREGATION_REQUEST_ID = 0x0328, + CSR_MLME_START_AGGREGATION_CONFIRM_ID = 0x0329, + CSR_MLME_BLOCKACK_ERROR_INDICATION_ID = 0x032b, + CSR_MLME_STOP_AGGREGATION_REQUEST_ID = 0x032c, + CSR_MLME_STOP_AGGREGATION_CONFIRM_ID = 0x032d, + CSR_MLME_SM_START_REQUEST_ID = 0x0334, + CSR_MLME_SM_START_CONFIRM_ID = 0x0335, + CSR_MLME_LEAVE_REQUEST_ID = 0x0338, + CSR_MLME_LEAVE_CONFIRM_ID = 0x0339, + CSR_MLME_SET_TIM_REQUEST_ID = 0x033c, + CSR_MLME_SET_TIM_CONFIRM_ID = 0x033d, + CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID = 0x0340, + CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID = 0x0341, + CSR_MLME_SET_CHANNEL_REQUEST_ID = 0x034c, + CSR_MLME_SET_CHANNEL_CONFIRM_ID = 0x034d, + CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID = 0x040c, + CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID = 0x040d, + CSR_DEBUG_STRING_INDICATION_ID = 0x0803, + CSR_DEBUG_WORD16_INDICATION_ID = 0x0807, + CSR_DEBUG_GENERIC_REQUEST_ID = 0x0808, + CSR_DEBUG_GENERIC_CONFIRM_ID = 0x0809, + CSR_DEBUG_GENERIC_INDICATION_ID = 0x080b +} CSR_SIGNAL_ID; + +typedef CsrUint16 CSR_SIMPLE_POINTER; + +typedef CsrUint16 CSR_STARTING_SEQUENCE_NUMBER; + +typedef enum CSR_SYMBOL_ID +{ + CSR_SLT_END = 0x0000, + CSR_SLT_PCI_SLOT_CONFIG = 0x0001, + CSR_SLT_SDIO_SLOT_CONFIG = 0x0002, + CSR_SLT_BUILD_ID_NUMBER = 0x0003, + CSR_SLT_BUILD_ID_STRING = 0x0004, + CSR_SLT_PERSISTENT_STORE_DB = 0x0005, + CSR_SLT_RESET_VECTOR_PHY = 0x0006, + CSR_SLT_RESET_VECTOR_MAC = 0x0007, + CSR_SLT_SDIO_LOADER_CONTROL = 0x0008, + CSR_SLT_TEST_CMD = 0x0009, + CSR_SLT_TEST_ALIVE_COUNTER = 0x000a, + CSR_SLT_TEST_PARAMETERS = 0x000b, + CSR_SLT_TEST_RESULTS = 0x000c, + CSR_SLT_TEST_VERSION = 0x000d, + CSR_SLT_MIB_PSID_RANGES = 0x000e, + CSR_SLT_KIP_TABLE = 0x000f, + CSR_SLT_PANIC_DATA_PHY = 0x0010, + CSR_SLT_PANIC_DATA_MAC = 0x0011, + CSR_SLT_BOOT_LOADER_CONTROL = 0x0012, + CSR_SLT_SOFT_MAC = 0x0013 +} CSR_SYMBOL_ID; + +typedef struct CSR_TSF_TIME +{ + CsrUint8 x[8]; +} CSR_TSF_TIME; + +typedef CsrUint16 CSR_TIME_UNITS; + +typedef enum CSR_TRANSMISSION_CONTROL +{ + CSR_TRIGGERED = 0x0001, + CSR_END_OF_SERVICE = 0x0002, + CSR_NO_CONFIRM_REQUIRED = 0x0004, + CSR_ALLOW_BA = 0x0008 +} CSR_TRANSMISSION_CONTROL; + +typedef enum CSR_TRANSMISSION_STATUS +{ + CSR_TX_SUCCESSFUL = 0x0000, + CSR_TX_RETRY_LIMIT = 0x0001, + CSR_TX_LIFETIME = 0x0002, + CSR_TX_NO_BSS = 0x0003, + CSR_TX_EXCESSIVE_DATA_LENGTH = 0x0004, + CSR_TX_UNSUPPORTED_PRIORITY = 0x0006, + CSR_TX_UNAVAILABLE_PRIORITY = 0x0007, + CSR_TX_UNAVAILABLE_KEY_MAPPING = 0x000a, + CSR_TX_EDCA_TIMEOUT = 0x000b, + CSR_TX_BLOCK_ACK_TIMEOUT = 0x000c, + CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED = 0x000d, + CSR_TX_REJECTED_PEER_STATION_SLEEPING = 0x000e, + CSR_TX_REJECTED_DTIM_ENDED = 0x000f, + CSR_TX_REJECTED_DTIM_STARTED = 0x0010 +} CSR_TRANSMISSION_STATUS; + +typedef CsrUint16 CSR_TRIGGER_ID; + +typedef CsrUint16 CSR_TRIGGERED_ID; + +typedef enum CSR_HIP_VERSIONS +{ + CSR_HIP_ENG_VERSION = 0x0001, + CSR_HIP_VERSION = 0x0900 +} CSR_HIP_VERSIONS; + +typedef CsrUint16 CSR_BUFFER_HANDLE; + +typedef CsrUint16 CSR_CHANNEL_NUMBER; + +typedef struct CSR_DATA_REFERENCE +{ + CsrUint16 SlotNumber; + CsrUint16 DataLength; +} CSR_DATAREF; + +typedef CsrUint16 CSR_DIALOG_TOKEN; + +typedef struct CSR_GENERIC_POINTER +{ + CsrUint24 MemoryOffset; + CSR_MEMORY_SPACE MemorySpace; +} CSR_GENERIC_POINTER; + +typedef struct CSR_MLME_CONFIG_QUEUE_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_CONFIG_QUEUE_CONFIRM; + +typedef struct CSR_MLME_CONFIG_QUEUE_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_NATURAL16 QueueIndex; + CSR_NATURAL16 Aifs; + CSR_NATURAL16 Cwmin; + CSR_NATURAL16 Cwmax; + CSR_NATURAL16 TxopLimit; +} CSR_MLME_CONFIG_QUEUE_REQUEST; + +typedef struct CSR_MLME_GET_CONFIRM +{ + CSR_DATAREF MibAttributeValue; + CSR_DATAREF Dummydataref2; + CSR_MIB_STATUS Status; + CSR_NATURAL16 ErrorIndex; +} CSR_MLME_GET_CONFIRM; + +typedef struct CSR_MLME_GET_REQUEST +{ + CSR_DATAREF MibAttribute; + CSR_DATAREF Dummydataref2; +} CSR_MLME_GET_REQUEST; + +typedef struct CSR_MLME_GET_NEXT_CONFIRM +{ + CSR_DATAREF MibAttributeValue; + CSR_DATAREF Dummydataref2; + CSR_MIB_STATUS Status; + CSR_NATURAL16 ErrorIndex; +} CSR_MLME_GET_NEXT_CONFIRM; + +typedef struct CSR_MLME_GET_NEXT_REQUEST +{ + CSR_DATAREF MibAttribute; + CSR_DATAREF Dummydataref2; +} CSR_MLME_GET_NEXT_REQUEST; + +typedef struct CSR_MLME_HL_SYNC_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_MACADDRESS GroupAddress; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_HL_SYNC_CONFIRM; + +typedef struct CSR_MLME_HL_SYNC_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_MACADDRESS GroupAddress; +} CSR_MLME_HL_SYNC_REQUEST; + +typedef struct CSR_MLME_HL_SYNC_CANCEL_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_HL_SYNC_CANCEL_CONFIRM; + +typedef struct CSR_MLME_HL_SYNC_CANCEL_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_MACADDRESS GroupAddress; +} CSR_MLME_HL_SYNC_CANCEL_REQUEST; + +typedef struct CSR_MLME_MEASURE_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_RESULT_CODE ResultCode; + CSR_DIALOG_TOKEN DialogToken; +} CSR_MLME_MEASURE_CONFIRM; + +typedef struct CSR_MLME_MEASURE_INDICATION +{ + CSR_DATAREF MeasurementReportSet; + CSR_DATAREF Dummydataref2; + CSR_DIALOG_TOKEN DialogToken; +} CSR_MLME_MEASURE_INDICATION; + +typedef struct CSR_MLME_MEASURE_REQUEST +{ + CSR_DATAREF MeasurementRequestSet; + CSR_DATAREF Dummydataref2; + CSR_DIALOG_TOKEN DialogToken; +} CSR_MLME_MEASURE_REQUEST; + +typedef struct CSR_MLME_RESET_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_RESET_CONFIRM; + +typedef struct CSR_MLME_RESET_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_MACADDRESS StaAddress; + CsrInt16 SetDefaultMib; +} CSR_MLME_RESET_REQUEST; + +typedef struct CSR_MLME_SET_CONFIRM +{ + CSR_DATAREF MibAttributeValue; + CSR_DATAREF Dummydataref2; + CSR_MIB_STATUS Status; + CSR_NATURAL16 ErrorIndex; +} CSR_MLME_SET_CONFIRM; + +typedef struct CSR_MLME_SET_REQUEST +{ + CSR_DATAREF MibAttributeValue; + CSR_DATAREF Dummydataref2; +} CSR_MLME_SET_REQUEST; + +typedef struct CSR_MLME_STOP_MEASURE_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_RESULT_CODE ResultCode; + CSR_DIALOG_TOKEN DialogToken; +} CSR_MLME_STOP_MEASURE_CONFIRM; + +typedef struct CSR_MLME_STOP_MEASURE_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_DIALOG_TOKEN DialogToken; +} CSR_MLME_STOP_MEASURE_REQUEST; + +typedef CsrUint16 CSR_PROCESS_ID; + +typedef CsrUint16 CSR_RATE; + +typedef CsrUint16 CSR_SEQUENCE_NUMBER; + +typedef struct CSR_SIGNAL_PRIMITIVE_HEADER +{ + CsrInt16 SignalId; + CSR_PROCESS_ID ReceiverProcessId; + CSR_PROCESS_ID SenderProcessId; +} CSR_SIGNAL_PRIMITIVE_HEADER; + +typedef CsrUint16 CSR_TRAFFIC_WINDOW; + +typedef CsrUint16 CSR_VIF_IDENTIFIER; + +typedef struct CSR_DEBUG_GENERIC_CONFIRM +{ + CSR_DATAREF DebugVariable; + CSR_DATAREF Dummydataref2; + CSR_NATURAL16 DebugWords[8]; +} CSR_DEBUG_GENERIC_CONFIRM; + +typedef struct CSR_DEBUG_GENERIC_INDICATION +{ + CSR_DATAREF DebugVariable; + CSR_DATAREF Dummydataref2; + CSR_NATURAL16 DebugWords[8]; +} CSR_DEBUG_GENERIC_INDICATION; + +typedef struct CSR_DEBUG_GENERIC_REQUEST +{ + CSR_DATAREF DebugVariable; + CSR_DATAREF Dummydataref2; + CSR_NATURAL16 DebugWords[8]; +} CSR_DEBUG_GENERIC_REQUEST; + +typedef struct CSR_DEBUG_STRING_INDICATION +{ + CSR_DATAREF DebugMessage; + CSR_DATAREF Dummydataref2; +} CSR_DEBUG_STRING_INDICATION; + +typedef struct CSR_DEBUG_WORD16_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_NATURAL16 DebugWords[16]; +} CSR_DEBUG_WORD16_INDICATION; + +typedef struct CSR_MA_PACKET_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRANSMISSION_STATUS TransmissionStatus; + CSR_NATURAL16 RetryCount; + CSR_RATE Rate; + CSR_CLIENT_TAG HostTag; +} CSR_MA_PACKET_CONFIRM; + +typedef struct CSR_MA_PACKET_INDICATION +{ + CSR_DATAREF Data; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TSF_TIME LocalTime; + CSR_IFINTERFACE Ifindex; + CSR_CHANNEL_NUMBER Channel; + CSR_RECEPTION_STATUS ReceptionStatus; + CSR_DECIBELS Rssi; + CSR_DECIBELS Snr; + CSR_RATE ReceivedRate; +} CSR_MA_PACKET_INDICATION; + +typedef struct CSR_MA_PACKET_REQUEST +{ + CSR_DATAREF Data; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RATE TransmitRate; + CSR_CLIENT_TAG HostTag; + CSR_PRIORITY Priority; + CSR_MACADDRESS Ra; + CSR_TRANSMISSION_CONTROL TransmissionControl; +} CSR_MA_PACKET_REQUEST; + +typedef struct CSR_MA_PACKET_CANCEL_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_CLIENT_TAG HostTag; +} CSR_MA_PACKET_CANCEL_REQUEST; + +typedef struct CSR_MA_PACKET_ERROR_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MACADDRESS PeerQstaAddress; + CSR_PRIORITY UserPriority; + CSR_SEQUENCE_NUMBER SequenceNumber; +} CSR_MA_PACKET_ERROR_INDICATION; + +typedef struct CSR_MA_VIF_AVAILABILITY_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CsrInt16 Multicast; +} CSR_MA_VIF_AVAILABILITY_INDICATION; + +typedef struct CSR_MA_VIF_AVAILABILITY_RESPONSE +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MA_VIF_AVAILABILITY_RESPONSE; + +typedef struct CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; +} CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM; + +typedef struct CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST +{ + CSR_DATAREF ChannelList; + CSR_DATAREF InformationElements; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; + CSR_IFINTERFACE Ifindex; + CSR_CHANNEL_STARTING_FACTOR ChannelStartingFactor; + CSR_SCAN_TYPE ScanType; + CSR_MICROSECONDS32 ProbeDelay; + CSR_TIME_UNITS MinChannelTime; + CSR_TIME_UNITS MaxChannelTime; +} CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST; + +typedef struct CSR_MLME_ADD_BLACKOUT_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_BLACKOUT_ID BlackoutId; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_ADD_BLACKOUT_CONFIRM; + +typedef struct CSR_MLME_ADD_BLACKOUT_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_BLACKOUT_ID BlackoutId; + CSR_BLACKOUT_TYPE BlackoutType; + CSR_BLACKOUT_SOURCE BlackoutSource; + CSR_MICROSECONDS32 BlackoutStartReference; + CSR_MICROSECONDS32 BlackoutPeriod; + CSR_MICROSECONDS32 BlackoutDuration; + CSR_MACADDRESS PeerStaAddress; + CSR_NATURAL16 BlackoutCount; +} CSR_MLME_ADD_BLACKOUT_REQUEST; + +typedef struct CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM; + +typedef struct CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST +{ + CSR_DATAREF Data; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_NATURAL16 NumberOfMulticastGroupAddresses; +} CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST; + +typedef struct CSR_MLME_ADD_PERIODIC_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PERIODIC_ID PeriodicId; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_ADD_PERIODIC_CONFIRM; + +typedef struct CSR_MLME_ADD_PERIODIC_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PERIODIC_ID PeriodicId; + CSR_MICROSECONDS32 MaximumLatency; + CSR_PERIODIC_SCHEDULING_MODE PeriodicSchedulingMode; + CsrInt16 WakeHost; + CSR_PRIORITY UserPriority; +} CSR_MLME_ADD_PERIODIC_REQUEST; + +typedef struct CSR_MLME_ADD_RX_TRIGGER_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRIGGER_ID TriggerId; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_ADD_RX_TRIGGER_CONFIRM; + +typedef struct CSR_MLME_ADD_RX_TRIGGER_REQUEST +{ + CSR_DATAREF InformationElements; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRIGGER_ID TriggerId; + CSR_PRIORITY Priority; +} CSR_MLME_ADD_RX_TRIGGER_REQUEST; + +typedef struct CSR_MLME_ADD_TEMPLATE_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_FRAME_TYPE FrameType; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_ADD_TEMPLATE_CONFIRM; + +typedef struct CSR_MLME_ADD_TEMPLATE_REQUEST +{ + CSR_DATAREF Data1; + CSR_DATAREF Data2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_FRAME_TYPE FrameType; + CSR_RATE MinTransmitRate; +} CSR_MLME_ADD_TEMPLATE_REQUEST; + +typedef struct CSR_MLME_ADD_TRIGGERED_GET_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_TRIGGERED_ID TriggeredId; +} CSR_MLME_ADD_TRIGGERED_GET_CONFIRM; + +typedef struct CSR_MLME_ADD_TRIGGERED_GET_REQUEST +{ + CSR_DATAREF MibAttribute; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRIGGERED_ID TriggeredId; +} CSR_MLME_ADD_TRIGGERED_GET_REQUEST; + +typedef struct CSR_MLME_ADD_TSPEC_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PRIORITY UserPriority; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_ADD_TSPEC_CONFIRM; + +typedef struct CSR_MLME_ADD_TSPEC_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PRIORITY UserPriority; + CSR_DIRECTION Direction; + CSR_PS_SCHEME PsScheme; + CSR_NATURAL16 MediumTime; + CSR_MICROSECONDS32 ServiceStartTime; + CSR_MICROSECONDS32 ServiceInterval; + CSR_RATE MinimumDataRate; +} CSR_MLME_ADD_TSPEC_REQUEST; + +typedef struct CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; +} CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION; + +typedef struct CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MACADDRESS Bssid; +} CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION; + +typedef struct CSR_MLME_BLACKOUT_ENDED_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_BLACKOUT_ID BlackoutId; +} CSR_MLME_BLACKOUT_ENDED_INDICATION; + +typedef struct CSR_MLME_BLOCKACK_ERROR_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_REASON_CODE ResultCode; + CSR_MACADDRESS PeerQstaAddress; +} CSR_MLME_BLOCKACK_ERROR_INDICATION; + +typedef struct CSR_MLME_CONNECTED_INDICATION +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_CONNECTION_STATUS ConnectionStatus; + CSR_MACADDRESS PeerMacAddress; +} CSR_MLME_CONNECTED_INDICATION; + +typedef struct CSR_MLME_CONNECT_STATUS_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_CONNECT_STATUS_CONFIRM; + +typedef struct CSR_MLME_CONNECT_STATUS_REQUEST +{ + CSR_DATAREF InformationElements; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_CONNECTION_STATUS ConnectionStatus; + CSR_MACADDRESS StaAddress; + CSR_ASSOCIATION_ID AssociationId; + CSR_CAPABILITY_INFORMATION AssociationCapabilityInformation; +} CSR_MLME_CONNECT_STATUS_REQUEST; + +typedef struct CSR_MLME_DELETEKEYS_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_DELETEKEYS_CONFIRM; + +typedef struct CSR_MLME_DELETEKEYS_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_NATURAL16 KeyId; + CSR_KEY_TYPE KeyType; + CSR_MACADDRESS Address; +} CSR_MLME_DELETEKEYS_REQUEST; + +typedef struct CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; +} CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM; + +typedef struct CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; +} CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST; + +typedef struct CSR_MLME_DEL_BLACKOUT_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_BLACKOUT_ID BlackoutId; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_DEL_BLACKOUT_CONFIRM; + +typedef struct CSR_MLME_DEL_BLACKOUT_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_BLACKOUT_ID BlackoutId; +} CSR_MLME_DEL_BLACKOUT_REQUEST; + +typedef struct CSR_MLME_DEL_PERIODIC_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PERIODIC_ID PeriodicId; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_DEL_PERIODIC_CONFIRM; + +typedef struct CSR_MLME_DEL_PERIODIC_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PERIODIC_ID PeriodicId; +} CSR_MLME_DEL_PERIODIC_REQUEST; + +typedef struct CSR_MLME_DEL_RX_TRIGGER_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRIGGER_ID TriggerId; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_DEL_RX_TRIGGER_CONFIRM; + +typedef struct CSR_MLME_DEL_RX_TRIGGER_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRIGGER_ID TriggerId; +} CSR_MLME_DEL_RX_TRIGGER_REQUEST; + +typedef struct CSR_MLME_DEL_TRIGGERED_GET_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_TRIGGERED_ID TriggeredId; +} CSR_MLME_DEL_TRIGGERED_GET_CONFIRM; + +typedef struct CSR_MLME_DEL_TRIGGERED_GET_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TRIGGERED_ID TriggeredId; +} CSR_MLME_DEL_TRIGGERED_GET_REQUEST; + +typedef struct CSR_MLME_DEL_TSPEC_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PRIORITY UserPriority; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_DEL_TSPEC_CONFIRM; + +typedef struct CSR_MLME_DEL_TSPEC_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PRIORITY UserPriority; + CSR_DIRECTION Direction; +} CSR_MLME_DEL_TSPEC_REQUEST; + +typedef struct CSR_MLME_GET_KEY_SEQUENCE_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_NATURAL16 SequenceNumber[8]; +} CSR_MLME_GET_KEY_SEQUENCE_CONFIRM; + +typedef struct CSR_MLME_GET_KEY_SEQUENCE_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_NATURAL16 KeyId; + CSR_KEY_TYPE KeyType; + CSR_MACADDRESS Address; +} CSR_MLME_GET_KEY_SEQUENCE_REQUEST; + +typedef struct CSR_MLME_LEAVE_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_LEAVE_CONFIRM; + +typedef struct CSR_MLME_LEAVE_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; +} CSR_MLME_LEAVE_REQUEST; + +typedef struct CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM; + +typedef struct CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST +{ + CSR_DATAREF Data; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_TIME_UNITS BeaconPeriod; + CSR_BEACON_PERIODS DtimPeriod; + CSR_CAPABILITY_INFORMATION CapabilityInformation; + CSR_MACADDRESS Bssid; + CSR_NATURAL16 RtsThreshold; +} CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST; + +typedef struct CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; +} CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM; + +typedef struct CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_AUTONOMOUS_SCAN_ID AutonomousScanId; + CsrInt16 Pause; +} CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST; + +typedef struct CSR_MLME_POWERMGT_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_POWERMGT_CONFIRM; + +typedef struct CSR_MLME_POWERMGT_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_POWER_MANAGEMENT_MODE PowerManagementMode; + CsrInt16 ReceiveDtims; + CSR_BEACON_PERIODS ListenInterval; + CSR_TRAFFIC_WINDOW TrafficWindow; +} CSR_MLME_POWERMGT_REQUEST; + +typedef struct CSR_MLME_SCAN_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_SCAN_CONFIRM; + +typedef struct CSR_MLME_SCAN_REQUEST +{ + CSR_DATAREF ChannelList; + CSR_DATAREF InformationElements; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_IFINTERFACE Ifindex; + CSR_SCAN_TYPE ScanType; + CSR_MICROSECONDS32 ProbeDelay; + CSR_TIME_UNITS MinChannelTime; + CSR_TIME_UNITS MaxChannelTime; +} CSR_MLME_SCAN_REQUEST; + +typedef struct CSR_MLME_SCAN_CANCEL_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; +} CSR_MLME_SCAN_CANCEL_REQUEST; + +typedef struct CSR_MLME_SETKEYS_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_SETKEYS_CONFIRM; + +typedef struct CSR_MLME_SETKEYS_REQUEST +{ + CSR_DATAREF Key; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_NATURAL16 Length; + CSR_NATURAL16 KeyId; + CSR_KEY_TYPE KeyType; + CSR_MACADDRESS Address; + CSR_NATURAL16 SequenceNumber[8]; + CSR_CIPHER_SUITE_SELECTOR CipherSuiteSelector; +} CSR_MLME_SETKEYS_REQUEST; + +typedef struct CSR_MLME_SET_CHANNEL_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_SET_CHANNEL_CONFIRM; + +typedef struct CSR_MLME_SET_CHANNEL_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_IFINTERFACE Ifindex; + CSR_CHANNEL_NUMBER Channel; + CSR_MACADDRESS Address; + CSR_TIME_UNITS AvailabilityDuration; + CSR_TIME_UNITS AvailabilityInterval; +} CSR_MLME_SET_CHANNEL_REQUEST; + +typedef struct CSR_MLME_SET_PACKET_FILTER_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_SET_PACKET_FILTER_CONFIRM; + +typedef struct CSR_MLME_SET_PACKET_FILTER_REQUEST +{ + CSR_DATAREF InformationElements; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_PACKET_FILTER_MODE PacketFilterMode; + CSR_IPV4_ADDRESS ArpFilterAddress; +} CSR_MLME_SET_PACKET_FILTER_REQUEST; + +typedef struct CSR_MLME_SET_TIM_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_SET_TIM_CONFIRM; + +typedef struct CSR_MLME_SET_TIM_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_ASSOCIATION_ID AssociationId; + CsrInt16 TimValue; +} CSR_MLME_SET_TIM_REQUEST; + +typedef struct CSR_MLME_SM_START_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_SM_START_CONFIRM; + +typedef struct CSR_MLME_SM_START_REQUEST +{ + CSR_DATAREF Beacon; + CSR_DATAREF BssParameters; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_IFINTERFACE Ifindex; + CSR_CHANNEL_NUMBER Channel; + CSR_MACADDRESS InterfaceAddress; + CSR_MACADDRESS Bssid; + CSR_TIME_UNITS BeaconPeriod; + CSR_BEACON_PERIODS DtimPeriod; + CSR_CAPABILITY_INFORMATION CapabilityInformation; +} CSR_MLME_SM_START_REQUEST; + +typedef struct CSR_MLME_START_AGGREGATION_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MACADDRESS PeerQstaAddress; + CSR_PRIORITY UserPriority; + CSR_DIRECTION Direction; + CSR_RESULT_CODE ResultCode; + CSR_SEQUENCE_NUMBER SequenceNumber; +} CSR_MLME_START_AGGREGATION_CONFIRM; + +typedef struct CSR_MLME_START_AGGREGATION_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MACADDRESS PeerQstaAddress; + CSR_PRIORITY UserPriority; + CSR_DIRECTION Direction; + CSR_STARTING_SEQUENCE_NUMBER StartingSequenceNumber; + CSR_NATURAL16 BufferSize; + CSR_TIME_UNITS BlockAckTimeout; +} CSR_MLME_START_AGGREGATION_REQUEST; + +typedef struct CSR_MLME_STOP_AGGREGATION_CONFIRM +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MACADDRESS PeerQstaAddress; + CSR_PRIORITY UserPriority; + CSR_DIRECTION Direction; + CSR_RESULT_CODE ResultCode; +} CSR_MLME_STOP_AGGREGATION_CONFIRM; + +typedef struct CSR_MLME_STOP_AGGREGATION_REQUEST +{ + CSR_DATAREF Dummydataref1; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MACADDRESS PeerQstaAddress; + CSR_PRIORITY UserPriority; + CSR_DIRECTION Direction; +} CSR_MLME_STOP_AGGREGATION_REQUEST; + +typedef struct CSR_MLME_TRIGGERED_GET_INDICATION +{ + CSR_DATAREF MibAttributeValue; + CSR_DATAREF Dummydataref2; + CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier; + CSR_MIB_STATUS Status; + CSR_NATURAL16 ErrorIndex; + CSR_TRIGGERED_ID TriggeredId; +} CSR_MLME_TRIGGERED_GET_INDICATION; + +typedef struct CSR_SIGNAL_PRIMITIVE +{ + CSR_SIGNAL_PRIMITIVE_HEADER SignalPrimitiveHeader; + union + { + CSR_MA_PACKET_REQUEST MaPacketRequest; + CSR_MA_PACKET_CONFIRM MaPacketConfirm; + CSR_MA_PACKET_INDICATION MaPacketIndication; + CSR_MA_PACKET_CANCEL_REQUEST MaPacketCancelRequest; + CSR_MA_VIF_AVAILABILITY_RESPONSE MaVifAvailabilityResponse; + CSR_MA_VIF_AVAILABILITY_INDICATION MaVifAvailabilityIndication; + CSR_MA_PACKET_ERROR_INDICATION MaPacketErrorIndication; + CSR_MLME_RESET_REQUEST MlmeResetRequest; + CSR_MLME_RESET_CONFIRM MlmeResetConfirm; + CSR_MLME_GET_REQUEST MlmeGetRequest; + CSR_MLME_GET_CONFIRM MlmeGetConfirm; + CSR_MLME_SET_REQUEST MlmeSetRequest; + CSR_MLME_SET_CONFIRM MlmeSetConfirm; + CSR_MLME_GET_NEXT_REQUEST MlmeGetNextRequest; + CSR_MLME_GET_NEXT_CONFIRM MlmeGetNextConfirm; + CSR_MLME_POWERMGT_REQUEST MlmePowermgtRequest; + CSR_MLME_POWERMGT_CONFIRM MlmePowermgtConfirm; + CSR_MLME_SCAN_REQUEST MlmeScanRequest; + CSR_MLME_SCAN_CONFIRM MlmeScanConfirm; + CSR_MLME_HL_SYNC_REQUEST MlmeHlSyncRequest; + CSR_MLME_HL_SYNC_CONFIRM MlmeHlSyncConfirm; + CSR_MLME_MEASURE_REQUEST MlmeMeasureRequest; + CSR_MLME_MEASURE_CONFIRM MlmeMeasureConfirm; + CSR_MLME_MEASURE_INDICATION MlmeMeasureIndication; + CSR_MLME_SETKEYS_REQUEST MlmeSetkeysRequest; + CSR_MLME_SETKEYS_CONFIRM MlmeSetkeysConfirm; + CSR_MLME_DELETEKEYS_REQUEST MlmeDeletekeysRequest; + CSR_MLME_DELETEKEYS_CONFIRM MlmeDeletekeysConfirm; + CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION MlmeAutonomousScanLossIndication; + CSR_MLME_CONNECTED_INDICATION MlmeConnectedIndication; + CSR_MLME_SCAN_CANCEL_REQUEST MlmeScanCancelRequest; + CSR_MLME_HL_SYNC_CANCEL_REQUEST MlmeHlSyncCancelRequest; + CSR_MLME_HL_SYNC_CANCEL_CONFIRM MlmeHlSyncCancelConfirm; + CSR_MLME_ADD_PERIODIC_REQUEST MlmeAddPeriodicRequest; + CSR_MLME_ADD_PERIODIC_CONFIRM MlmeAddPeriodicConfirm; + CSR_MLME_DEL_PERIODIC_REQUEST MlmeDelPeriodicRequest; + CSR_MLME_DEL_PERIODIC_CONFIRM MlmeDelPeriodicConfirm; + CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST MlmeAddAutonomousScanRequest; + CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM MlmeAddAutonomousScanConfirm; + CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST MlmeDelAutonomousScanRequest; + CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM MlmeDelAutonomousScanConfirm; + CSR_MLME_SET_PACKET_FILTER_REQUEST MlmeSetPacketFilterRequest; + CSR_MLME_SET_PACKET_FILTER_CONFIRM MlmeSetPacketFilterConfirm; + CSR_MLME_STOP_MEASURE_REQUEST MlmeStopMeasureRequest; + CSR_MLME_STOP_MEASURE_CONFIRM MlmeStopMeasureConfirm; + CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST MlmePauseAutonomousScanRequest; + CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM MlmePauseAutonomousScanConfirm; + CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION MlmeAutonomousScanDoneIndication; + CSR_MLME_ADD_TRIGGERED_GET_REQUEST MlmeAddTriggeredGetRequest; + CSR_MLME_ADD_TRIGGERED_GET_CONFIRM MlmeAddTriggeredGetConfirm; + CSR_MLME_DEL_TRIGGERED_GET_REQUEST MlmeDelTriggeredGetRequest; + CSR_MLME_DEL_TRIGGERED_GET_CONFIRM MlmeDelTriggeredGetConfirm; + CSR_MLME_TRIGGERED_GET_INDICATION MlmeTriggeredGetIndication; + CSR_MLME_ADD_BLACKOUT_REQUEST MlmeAddBlackoutRequest; + CSR_MLME_ADD_BLACKOUT_CONFIRM MlmeAddBlackoutConfirm; + CSR_MLME_BLACKOUT_ENDED_INDICATION MlmeBlackoutEndedIndication; + CSR_MLME_DEL_BLACKOUT_REQUEST MlmeDelBlackoutRequest; + CSR_MLME_DEL_BLACKOUT_CONFIRM MlmeDelBlackoutConfirm; + CSR_MLME_ADD_RX_TRIGGER_REQUEST MlmeAddRxTriggerRequest; + CSR_MLME_ADD_RX_TRIGGER_CONFIRM MlmeAddRxTriggerConfirm; + CSR_MLME_DEL_RX_TRIGGER_REQUEST MlmeDelRxTriggerRequest; + CSR_MLME_DEL_RX_TRIGGER_CONFIRM MlmeDelRxTriggerConfirm; + CSR_MLME_CONNECT_STATUS_REQUEST MlmeConnectStatusRequest; + CSR_MLME_CONNECT_STATUS_CONFIRM MlmeConnectStatusConfirm; + CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST MlmeModifyBssParameterRequest; + CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM MlmeModifyBssParameterConfirm; + CSR_MLME_ADD_TEMPLATE_REQUEST MlmeAddTemplateRequest; + CSR_MLME_ADD_TEMPLATE_CONFIRM MlmeAddTemplateConfirm; + CSR_MLME_CONFIG_QUEUE_REQUEST MlmeConfigQueueRequest; + CSR_MLME_CONFIG_QUEUE_CONFIRM MlmeConfigQueueConfirm; + CSR_MLME_ADD_TSPEC_REQUEST MlmeAddTspecRequest; + CSR_MLME_ADD_TSPEC_CONFIRM MlmeAddTspecConfirm; + CSR_MLME_DEL_TSPEC_REQUEST MlmeDelTspecRequest; + CSR_MLME_DEL_TSPEC_CONFIRM MlmeDelTspecConfirm; + CSR_MLME_START_AGGREGATION_REQUEST MlmeStartAggregationRequest; + CSR_MLME_START_AGGREGATION_CONFIRM MlmeStartAggregationConfirm; + CSR_MLME_BLOCKACK_ERROR_INDICATION MlmeBlockackErrorIndication; + CSR_MLME_STOP_AGGREGATION_REQUEST MlmeStopAggregationRequest; + CSR_MLME_STOP_AGGREGATION_CONFIRM MlmeStopAggregationConfirm; + CSR_MLME_SM_START_REQUEST MlmeSmStartRequest; + CSR_MLME_SM_START_CONFIRM MlmeSmStartConfirm; + CSR_MLME_LEAVE_REQUEST MlmeLeaveRequest; + CSR_MLME_LEAVE_CONFIRM MlmeLeaveConfirm; + CSR_MLME_SET_TIM_REQUEST MlmeSetTimRequest; + CSR_MLME_SET_TIM_CONFIRM MlmeSetTimConfirm; + CSR_MLME_GET_KEY_SEQUENCE_REQUEST MlmeGetKeySequenceRequest; + CSR_MLME_GET_KEY_SEQUENCE_CONFIRM MlmeGetKeySequenceConfirm; + CSR_MLME_SET_CHANNEL_REQUEST MlmeSetChannelRequest; + CSR_MLME_SET_CHANNEL_CONFIRM MlmeSetChannelConfirm; + CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST MlmeAddMulticastAddressRequest; + CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM MlmeAddMulticastAddressConfirm; + CSR_DEBUG_STRING_INDICATION DebugStringIndication; + CSR_DEBUG_WORD16_INDICATION DebugWord16Indication; + CSR_DEBUG_GENERIC_REQUEST DebugGenericRequest; + CSR_DEBUG_GENERIC_CONFIRM DebugGenericConfirm; + CSR_DEBUG_GENERIC_INDICATION DebugGenericIndication; + } u; +} CSR_SIGNAL; + +#define SIG_FILTER_SIZE 6 + +CsrUint32 SigGetFilterPos(CsrUint16 aSigID); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/csr_wifi_hip_ta_sampling.c b/drivers/staging/csr/csr_wifi_hip_ta_sampling.c new file mode 100644 index 000000000000..4fa8f607f15c --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_ta_sampling.c @@ -0,0 +1,535 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_ta_sampling.c + * + * PURPOSE: + * The traffic analysis sampling module. + * This gathers data which is sent to the SME and used to analyse + * the traffic behaviour. + * + * Provides: + * unifi_ta_sampling_init - Initialise the internal state + * unifi_ta_sample - Sampling function, call this for every data packet + * + * Calls these external functions which must be provided: + * unifi_ta_indicate_sampling - Pass sample data to the SME. + * unifi_ta_indicate_protocol - Report certain data packet types to the SME. + * --------------------------------------------------------------------------- + */ + +#include "csr_wifi_hip_card_sdio.h" + +/* Maximum number of Tx frames we store each CYCLE_1, for detecting period */ +#define TA_MAX_INTERVALS_IN_C1 100 + +/* Number of intervals in CYCLE_1 (one second), for detecting periodic */ +/* Must match size of unifi_TrafficStats.intervals - 1 */ +#define TA_INTERVALS_NUM 10 + +/* Step (in msecs) between intervals, for detecting periodic */ +/* We are only interested in periods up to 100ms, i.e. between beacons */ +/* This is correct for TA_INTERVALS_NUM=10 */ +#define TA_INTERVALS_STEP 10 + + +enum ta_frame_identity +{ + TA_FRAME_UNKNOWN, + TA_FRAME_ETHERNET_UNINTERESTING, + TA_FRAME_ETHERNET_INTERESTING +}; + + +#define TA_ETHERNET_TYPE_OFFSET 6 +#define TA_LLC_HEADER_SIZE 8 +#define TA_IP_TYPE_OFFSET 17 +#define TA_UDP_SOURCE_PORT_OFFSET 28 +#define TA_UDP_DEST_PORT_OFFSET (TA_UDP_SOURCE_PORT_OFFSET + 2) +#define TA_BOOTP_CLIENT_MAC_ADDR_OFFSET 64 +#define TA_DHCP_MESSAGE_TYPE_OFFSET 278 +#define TA_DHCP_MESSAGE_TYPE_ACK 0x05 +#define TA_PROTO_TYPE_IP 0x0800 +#define TA_PROTO_TYPE_EAP 0x888E +#define TA_PROTO_TYPE_WAI 0x8864 +#define TA_PROTO_TYPE_ARP 0x0806 +#define TA_IP_TYPE_TCP 0x06 +#define TA_IP_TYPE_UDP 0x11 +#define TA_UDP_PORT_BOOTPC 0x0044 +#define TA_UDP_PORT_BOOTPS 0x0043 +#define TA_EAPOL_TYPE_OFFSET 9 +#define TA_EAPOL_TYPE_START 0x01 + +static const CsrUint8 snap_802_2[3] = { 0xAA, 0xAA, 0x03 }; +static const CsrUint8 oui_rfc1042[3] = { 0x00, 0x00, 0x00 }; +static const CsrUint8 oui_8021h[3] = { 0x00, 0x00, 0xf8 }; +static const CsrUint8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 }; + + +/* + * --------------------------------------------------------------------------- + * ta_detect_protocol + * + * Internal only. + * Detects a specific protocol in a frame and indicates a TA event. + * + * Arguments: + * ta The pointer to the TA module. + * direction The direction of the frame (tx or rx). + * data Pointer to the structure that contains the data. + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrlProtocolDirection direction, + const bulk_data_desc_t *data, + const CsrUint8 *saddr, + const CsrUint8 *sta_macaddr) +{ + ta_data_t *tad = &card->ta_sampling; + CsrUint16 proto; + CsrUint16 source_port, dest_port; + CsrWifiMacAddress srcAddress; + + if (data->data_length < TA_LLC_HEADER_SIZE) + { + return TA_FRAME_UNKNOWN; + } + + if (CsrMemCmp(data->os_data_ptr, snap_802_2, 3)) + { + return TA_FRAME_UNKNOWN; + } + + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM) + { + /* + * Here we would use the custom filter to detect interesting frames. + */ + } + + if (!CsrMemCmp(data->os_data_ptr + 3, oui_rfc1042, 3) || + !CsrMemCmp(data->os_data_ptr + 3, oui_8021h, 3)) + { + proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) + + data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1]; + + /* The only interesting IP frames are the DHCP */ + if (proto == TA_PROTO_TYPE_IP) + { + if (data->data_length > TA_IP_TYPE_OFFSET) + { + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM) + { + ta_l4stats_t *ta_l4stats = &tad->ta_l4stats; + CsrUint8 l4proto = data->os_data_ptr[TA_IP_TYPE_OFFSET]; + + if (l4proto == TA_IP_TYPE_TCP) + { + if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) + { + ta_l4stats->txTcpBytesCount += data->data_length; + } + else + { + ta_l4stats->rxTcpBytesCount += data->data_length; + } + } + else if (l4proto == TA_IP_TYPE_UDP) + { + if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) + { + ta_l4stats->txUdpBytesCount += data->data_length; + } + else + { + ta_l4stats->rxUdpBytesCount += data->data_length; + } + } + } + + /* detect DHCP frames */ + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP) + { + /* DHCP frames are UDP frames with BOOTP ports */ + if (data->os_data_ptr[TA_IP_TYPE_OFFSET] == TA_IP_TYPE_UDP) + { + if (data->data_length > TA_UDP_DEST_PORT_OFFSET) + { + source_port = (data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET] * 256) + + data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET + 1]; + dest_port = (data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET] * 256) + + data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET + 1]; + + if (((source_port == TA_UDP_PORT_BOOTPC) && (dest_port == TA_UDP_PORT_BOOTPS)) || + ((source_port == TA_UDP_PORT_BOOTPS) && (dest_port == TA_UDP_PORT_BOOTPC))) + { + /* The DHCP should have at least a message type (request, ack, nack, etc) */ + if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6) + { + CsrMemCpy(srcAddress.a, saddr, 6); + + if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) + { + unifi_ta_indicate_protocol(card->ospriv, + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP, + direction, + &srcAddress); + return TA_FRAME_ETHERNET_UNINTERESTING; + } + + /* DHCPACK is a special indication */ + if (!CsrMemCmp(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr, 6)) + { + if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK) + { + unifi_ta_indicate_protocol(card->ospriv, + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK, + direction, + &srcAddress); + } + else + { + unifi_ta_indicate_protocol(card->ospriv, + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP, + direction, + &srcAddress); + } + } + } + } + } + } + } + } + + return TA_FRAME_ETHERNET_INTERESTING; + } + + /* detect protocol type EAPOL or WAI (treated as equivalent here) */ + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL) + { + if (TA_PROTO_TYPE_EAP == proto || TA_PROTO_TYPE_WAI == proto) + { + if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) || + (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START)) + { + CsrMemCpy(srcAddress.a, saddr, 6); + unifi_ta_indicate_protocol(card->ospriv, + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL, + direction, &srcAddress); + } + return TA_FRAME_ETHERNET_UNINTERESTING; + } + } + + /* detect protocol type 0x0806 (ARP) */ + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP) + { + if (proto == TA_PROTO_TYPE_ARP) + { + CsrMemCpy(srcAddress.a, saddr, 6); + unifi_ta_indicate_protocol(card->ospriv, + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP, + direction, &srcAddress); + return TA_FRAME_ETHERNET_UNINTERESTING; + } + } + + return TA_FRAME_ETHERNET_INTERESTING; + } + else if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET) + { + /* detect Aironet frames */ + if (!CsrMemCmp(data->os_data_ptr + 3, aironet_snap, 5)) + { + CsrMemCpy(srcAddress.a, saddr, 6); + unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET, + direction, &srcAddress); + } + } + + return TA_FRAME_ETHERNET_UNINTERESTING; +} /* ta_detect_protocol() */ + + +static void tas_reset_data(ta_data_t *tad) +{ + CsrInt16 i; + + for (i = 0; i < (TA_INTERVALS_NUM + 1); i++) + { + tad->stats.intervals[i] = 0; + } + + tad->stats.rxFramesNum = 0; + tad->stats.txFramesNum = 0; + tad->stats.rxBytesCount = 0; + tad->stats.txBytesCount = 0; + tad->stats.rxMeanRate = 0; + + tad->rx_sum_rate = 0; + + tad->ta_l4stats.rxTcpBytesCount = 0; + tad->ta_l4stats.txTcpBytesCount = 0; + tad->ta_l4stats.rxUdpBytesCount = 0; + tad->ta_l4stats.txUdpBytesCount = 0; +} /* tas_reset_data() */ + + +/* + * --------------------------------------------------------------------------- + * API. + * unifi_ta_sampling_init + * + * (Re)Initialise the Traffic Analysis sampling module. + * Resets the counters and timestamps. + * + * Arguments: + * tad Pointer to a ta_data_t structure containing the + * context for this device instance. + * drv_priv An opaque pointer that the TA sampling module will + * pass in call-outs. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void unifi_ta_sampling_init(card_t *card) +{ + (void)unifi_ta_configure(card, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET, NULL); + + card->ta_sampling.packet_filter = CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE; + card->ta_sampling.traffic_type = CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL; +} /* unifi_ta_sampling_init() */ + + +/* + * --------------------------------------------------------------------------- + * API. + * unifi_ta_sample + * + * Sample a data frame for the TA module. + * This function stores all the useful information it can extract from + * the frame and detects any specific protocols. + * + * Arguments: + * tad The pointer to the TA sampling context struct. + * direction The direction of the frame (rx, tx) + * data Pointer to the frame data + * saddr Source MAC address of frame. + * timestamp Time (in msecs) that the frame was received. + * rate Reported data rate for the rx frame (0 for tx frames) + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +void unifi_ta_sample(card_t *card, + CsrWifiRouterCtrlProtocolDirection direction, + const bulk_data_desc_t *data, + const CsrUint8 *saddr, + const CsrUint8 *sta_macaddr, + CsrUint32 timestamp, + CsrUint16 rate) +{ + ta_data_t *tad = &card->ta_sampling; + enum ta_frame_identity identity; + CsrUint32 time_delta; + + + + /* Step1: Check for specific frames */ + if (tad->packet_filter != CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE) + { + identity = ta_detect_protocol(card, direction, data, saddr, sta_macaddr); + } + else + { + identity = TA_FRAME_ETHERNET_INTERESTING; + } + + + /* Step2: Update the information in the current record */ + if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX) + { + /* Update the Rx packet count and the throughput count */ + tad->stats.rxFramesNum++; + tad->stats.rxBytesCount += data->data_length; + + /* Accumulate packet Rx rates for later averaging */ + tad->rx_sum_rate += rate; + } + else + { + if (identity == TA_FRAME_ETHERNET_INTERESTING) + { + /* + * Store the period between the last and the current frame. + * There is not point storing more than TA_MAX_INTERVALS_IN_C1 periods, + * the traffic will be bursty or continuous. + */ + if (tad->stats.txFramesNum < TA_MAX_INTERVALS_IN_C1) + { + CsrUint32 interval; + CsrUint32 index_in_intervals; + + interval = timestamp - tad->tx_last_ts; + tad->tx_last_ts = timestamp; + index_in_intervals = (interval + TA_INTERVALS_STEP / 2 - 1) / TA_INTERVALS_STEP; + + /* If the interval is interesting, update the t1_intervals count */ + if (index_in_intervals <= TA_INTERVALS_NUM) + { + unifi_trace(card->ospriv, UDBG5, + "unifi_ta_sample: TX interval=%d index=%d\n", + interval, index_in_intervals); + tad->stats.intervals[index_in_intervals]++; + } + } + } + + /* Update the Tx packet count... */ + tad->stats.txFramesNum++; + /* ... and the number of bytes for throughput. */ + tad->stats.txBytesCount += data->data_length; + } + + /* + * If more than one second has elapsed since the last report, send + * another one. + */ + /* Unsigned subtraction handles wrap-around from 0xFFFFFFFF to 0 */ + time_delta = timestamp - tad->last_indication_time; + if (time_delta >= 1000) + { + /* + * rxFramesNum can be flashed in tas_reset_data() by another thread. + * Use a temp to avoid division by zero. + */ + CsrUint32 temp_rxFramesNum; + temp_rxFramesNum = tad->stats.rxFramesNum; + + /* Calculate this interval's mean frame Rx rate from the sum */ + if (temp_rxFramesNum) + { + tad->stats.rxMeanRate = tad->rx_sum_rate / temp_rxFramesNum; + } + unifi_trace(card->ospriv, UDBG5, + "unifi_ta_sample: RX fr=%lu, r=%u, sum=%lu, av=%lu\n", + tad->stats.rxFramesNum, rate, + tad->rx_sum_rate, tad->stats.rxMeanRate); + + /* + * Send the information collected in the stats struct + * to the SME and reset the counters. + */ + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM) + { + CsrUint32 rxTcpThroughput = tad->ta_l4stats.rxTcpBytesCount / time_delta; + CsrUint32 txTcpThroughput = tad->ta_l4stats.txTcpBytesCount / time_delta; + CsrUint32 rxUdpThroughput = tad->ta_l4stats.rxUdpBytesCount / time_delta; + CsrUint32 txUdpThroughput = tad->ta_l4stats.txUdpBytesCount / time_delta; + + unifi_ta_indicate_l4stats(card->ospriv, + rxTcpThroughput, + txTcpThroughput, + rxUdpThroughput, + txUdpThroughput + ); + } + unifi_ta_indicate_sampling(card->ospriv, &tad->stats); + tas_reset_data(tad); + tad->last_indication_time = timestamp; + } +} /* unifi_ta_sample() */ + + +/* + * --------------------------------------------------------------------------- + * External API. + * unifi_ta_configure + * + * Configures the TA module parameters. + * + * Arguments: + * ta The pointer to the TA module. + * config_type The type of the configuration request + * config Pointer to the configuration parameters. + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code otherwise + * --------------------------------------------------------------------------- + */ +CsrResult unifi_ta_configure(card_t *card, + CsrWifiRouterCtrlTrafficConfigType config_type, + const CsrWifiRouterCtrlTrafficConfig *config) +{ + ta_data_t *tad = &card->ta_sampling; + + /* Reinitialise our data when we are reset */ + if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET) + { + /* Reset the stats to zero */ + tas_reset_data(tad); + + /* Reset the timer variables */ + tad->tx_last_ts = 0; + tad->last_indication_time = 0; + + return CSR_RESULT_SUCCESS; + } + + if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER) + { + tad->packet_filter = config->packetFilter; + + if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM) + { + tad->custom_filter = config->customFilter; + } + + return CSR_RESULT_SUCCESS; + } + + return CSR_RESULT_SUCCESS; +} /* unifi_ta_configure() */ + + +/* + * --------------------------------------------------------------------------- + * External API. + * unifi_ta_classification + * + * Configures the current TA classification. + * + * Arguments: + * ta The pointer to the TA module. + * traffic_type The classification type + * period The traffic period if the type is periodic + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +void unifi_ta_classification(card_t *card, + CsrWifiRouterCtrlTrafficType traffic_type, + CsrUint16 period) +{ + unifi_trace(card->ospriv, UDBG3, + "Changed current ta classification to: %d\n", traffic_type); + + card->ta_sampling.traffic_type = traffic_type; +} + + diff --git a/drivers/staging/csr/csr_wifi_hip_ta_sampling.h b/drivers/staging/csr/csr_wifi_hip_ta_sampling.h new file mode 100644 index 000000000000..602943ecc1b6 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_ta_sampling.h @@ -0,0 +1,75 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_ta_sampling.h + * + * PURPOSE: + * This file contains Traffic Analysis definitions common to the + * sampling and analysis modules. + * + * --------------------------------------------------------------------------- + */ +#ifndef __TA_SAMPLING_H__ +#define __TA_SAMPLING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_wifi_hip_unifi.h" + +typedef struct ta_l4stats +{ + CsrUint32 rxTcpBytesCount; + CsrUint32 txTcpBytesCount; + CsrUint32 rxUdpBytesCount; + CsrUint32 txUdpBytesCount; +} ta_l4stats_t; + +/* + * Context structure to preserve state between calls. + */ + +typedef struct ta_data +{ + /* Current packet filter configuration */ + CsrUint16 packet_filter; + + /* Current packet custom filter configuration */ + CsrWifiRouterCtrlTrafficFilter custom_filter; + + /* The timestamp of the last tx packet processed. */ + CsrUint32 tx_last_ts; + + /* The timestamp of the last packet processed. */ + CsrUint32 last_indication_time; + + /* Statistics */ + CsrWifiRouterCtrlTrafficStats stats; + + /* Current traffic classification */ + CsrWifiRouterCtrlTrafficType traffic_type; + + /* Sum of packet rx rates for this interval used to calculate mean */ + CsrUint32 rx_sum_rate; + ta_l4stats_t ta_l4stats; +} ta_data_t; + + +void unifi_ta_sampling_init(card_t *card); + + +#ifdef __cplusplus +} +#endif + +#endif /* __TA_SAMPLING_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_udi.c b/drivers/staging/csr/csr_wifi_hip_udi.c new file mode 100644 index 000000000000..2cf028108b10 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_udi.c @@ -0,0 +1,268 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_card_udi.c + * + * PURPOSE: + * Maintain a list of callbacks to log UniFi exchanges to one or more + * debug/monitoring client applications. + * + * NOTES: + * Just call the UDI driver log fn directly for now. + * When done properly, each open() on the UDI device will install + * a log function. We will call all log fns whenever a signal is written + * to or read form the UniFi. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_card.h" + + +/* + * --------------------------------------------------------------------------- + * unifi_print_status + * + * Print status info to given character buffer. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +CsrInt32 unifi_print_status(card_t *card, CsrCharString *str, CsrInt32 *remain) +{ + CsrCharString *p = str; + sdio_config_data_t *cfg; + CsrUint16 i, n; + CsrInt32 remaining = *remain; + CsrInt32 written; +#ifdef CSR_UNSAFE_SDIO_ACCESS + CsrInt32 iostate; + CsrResult r; + static const CsrCharString *const states[] = { + "AWAKE", "DROWSY", "TORPID" + }; + #define SHARED_READ_RETRY_LIMIT 10 + CsrUint8 b; +#endif + + if (remaining <= 0) + { + return 0; + } + + i = n = 0; + written = CsrSnprintf(p, remaining, "Chip ID %u\n", + (CsrUint16)card->chip_id); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "Chip Version %04X\n", + card->chip_version); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "HIP v%u.%u\n", + (card->config_data.version >> 8) & 0xFF, + card->config_data.version & 0xFF); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "Build %lu: %s\n", + card->build_id, card->build_id_string); + UNIFI_SNPRINTF_RET(p, remaining, written); + + cfg = &card->config_data; + + written = CsrSnprintf(p, remaining, "sdio ctrl offset %u\n", + cfg->sdio_ctrl_offset); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "fromhost sigbuf handle %u\n", + cfg->fromhost_sigbuf_handle); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "tohost_sigbuf_handle %u\n", + cfg->tohost_sigbuf_handle); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "num_fromhost_sig_frags %u\n", + cfg->num_fromhost_sig_frags); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "num_tohost_sig_frags %u\n", + cfg->num_tohost_sig_frags); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "num_fromhost_data_slots %u\n", + cfg->num_fromhost_data_slots); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "num_tohost_data_slots %u\n", + cfg->num_tohost_data_slots); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "data_slot_size %u\n", + cfg->data_slot_size); + UNIFI_SNPRINTF_RET(p, remaining, written); + + /* Added by protocol version 0x0001 */ + written = CsrSnprintf(p, remaining, "overlay_size %u\n", + (CsrUint16)cfg->overlay_size); + UNIFI_SNPRINTF_RET(p, remaining, written); + + /* Added by protocol version 0x0300 */ + written = CsrSnprintf(p, remaining, "data_slot_round %u\n", + cfg->data_slot_round); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "sig_frag_size %u\n", + cfg->sig_frag_size); + UNIFI_SNPRINTF_RET(p, remaining, written); + + /* Added by protocol version 0x0300 */ + written = CsrSnprintf(p, remaining, "tohost_sig_pad %u\n", + cfg->tohost_signal_padding); + UNIFI_SNPRINTF_RET(p, remaining, written); + + written = CsrSnprintf(p, remaining, "\nInternal state:\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + + written = CsrSnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n", + card->last_phy_panic_code, card->last_phy_panic_arg); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n", + card->last_mac_panic_code, card->last_mac_panic_arg); + UNIFI_SNPRINTF_RET(p, remaining, written); + + written = CsrSnprintf(p, remaining, "fhsr: %u\n", + (CsrUint16)card->from_host_signals_r); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "fhsw: %u\n", + (CsrUint16)card->from_host_signals_w); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "thsr: %u\n", + (CsrUint16)card->to_host_signals_r); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "thsw: %u\n", + (CsrUint16)card->to_host_signals_w); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, + "fh buffer contains: %u signals, %u bytes\n", + card->fh_buffer.count, + card->fh_buffer.ptr - card->fh_buffer.buf); + UNIFI_SNPRINTF_RET(p, remaining, written); + + written = CsrSnprintf(p, remaining, "paused: "); + UNIFI_SNPRINTF_RET(p, remaining, written); + for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++) + { + written = CsrSnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0"); + UNIFI_SNPRINTF_RET(p, remaining, written); + } + written = CsrSnprintf(p, remaining, "\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + + written = CsrSnprintf(p, remaining, + "fh command q: %u waiting, %u free of %u:\n", + CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue), + CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue), + UNIFI_SOFT_COMMAND_Q_LENGTH); + UNIFI_SNPRINTF_RET(p, remaining, written); + for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) + { + written = CsrSnprintf(p, remaining, + "fh traffic q[%u]: %u waiting, %u free of %u:\n", + i, + CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]), + CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]), + UNIFI_SOFT_TRAFFIC_Q_LENGTH); + UNIFI_SNPRINTF_RET(p, remaining, written); + } + + written = CsrSnprintf(p, remaining, "fh data slots free: %u\n", + card->from_host_data?CardGetFreeFromHostDataSlots(card) : 0); + UNIFI_SNPRINTF_RET(p, remaining, written); + + + written = CsrSnprintf(p, remaining, "From host data slots:"); + UNIFI_SNPRINTF_RET(p, remaining, written); + n = card->config_data.num_fromhost_data_slots; + for (i = 0; i < n && card->from_host_data; i++) + { + written = CsrSnprintf(p, remaining, " %u", + (CsrUint16)card->from_host_data[i].bd.data_length); + UNIFI_SNPRINTF_RET(p, remaining, written); + } + written = CsrSnprintf(p, remaining, "\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + + written = CsrSnprintf(p, remaining, "To host data slots:"); + UNIFI_SNPRINTF_RET(p, remaining, written); + n = card->config_data.num_tohost_data_slots; + for (i = 0; i < n && card->to_host_data; i++) + { + written = CsrSnprintf(p, remaining, " %u", + (CsrUint16)card->to_host_data[i].data_length); + UNIFI_SNPRINTF_RET(p, remaining, written); + } + + written = CsrSnprintf(p, remaining, "\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + +#ifdef CSR_UNSAFE_SDIO_ACCESS + written = CsrSnprintf(p, remaining, "Host State: %s\n", states[card->host_state]); + UNIFI_SNPRINTF_RET(p, remaining, written); + + r = unifi_check_io_status(card, &iostate); + if (iostate == 1) + { + written = CsrSnprintf(p, remaining, "I/O Check: F1 disabled\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + } + else + { + if (iostate == 1) + { + written = CsrSnprintf(p, remaining, "I/O Check: pending interrupt\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + } + + written = CsrSnprintf(p, remaining, "BH reason interrupt = %d\n", + card->bh_reason_unifi); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "BH reason host = %d\n", + card->bh_reason_host); + UNIFI_SNPRINTF_RET(p, remaining, written); + + for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) + { + r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b); + if ((r == CSR_RESULT_SUCCESS) && (!(b & 0x80))) + { + written = CsrSnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n", + b, card->from_host_signals_r); + UNIFI_SNPRINTF_RET(p, remaining, written); + break; + } + } + iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); + written = CsrSnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n", + iostate, card->to_host_signals_w); + UNIFI_SNPRINTF_RET(p, remaining, written); + } +#endif + + written = CsrSnprintf(p, remaining, "\nStats:\n"); + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "Total SDIO bytes: R=%lu W=%lu\n", + card->sdio_bytes_read, card->sdio_bytes_written); + + UNIFI_SNPRINTF_RET(p, remaining, written); + written = CsrSnprintf(p, remaining, "Interrupts generated on card: %lu\n", + card->unifi_interrupt_seq); + UNIFI_SNPRINTF_RET(p, remaining, written); + + *remain = remaining; + return (p - str); +} /* unifi_print_status() */ + + diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h new file mode 100644 index 000000000000..feda2e051c21 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_unifi.h @@ -0,0 +1,852 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * + * FILE : csr_wifi_hip_unifi.h + * + * PURPOSE : Public API for the UniFi HIP core library. + * + * --------------------------------------------------------------------------- + */ +#ifndef __CSR_WIFI_HIP_UNIFI_H__ +#define __CSR_WIFI_HIP_UNIFI_H__ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_HIP_TA_DISABLE +#include "csr_wifi_router_ctrl_prim.h" +#include "csr_wifi_router_prim.h" +#else +#include "csr_time.h" +#endif + +/* SDIO chip ID numbers */ + +/* Manufacturer id */ +#define SDIO_MANF_ID_CSR 0x032a + +/* Device id */ +#define SDIO_CARD_ID_UNIFI_1 0x0001 +#define SDIO_CARD_ID_UNIFI_2 0x0002 +#define SDIO_CARD_ID_UNIFI_3 0x0007 +#define SDIO_CARD_ID_UNIFI_4 0x0008 + +/* Function number for WLAN */ +#define SDIO_WLAN_FUNC_ID_UNIFI_1 0x0001 +#define SDIO_WLAN_FUNC_ID_UNIFI_2 0x0001 +#define SDIO_WLAN_FUNC_ID_UNIFI_3 0x0001 +#define SDIO_WLAN_FUNC_ID_UNIFI_4 0x0002 + +/* Maximum SDIO bus clock supported. */ +#define UNIFI_SDIO_CLOCK_MAX_HZ 50000000 /* Hz */ + +/* + * Initialisation SDIO bus clock. + * + * The initialisation clock speed should be used from when the chip has been + * reset until the first MLME-reset has been received (i.e. during firmware + * initialisation), unless UNIFI_SDIO_CLOCK_SAFE_HZ applies. + */ +#define UNIFI_SDIO_CLOCK_INIT_HZ 12500000 /* Hz */ + +/* + * Safe SDIO bus clock. + * + * The safe speed should be used when the chip is in deep sleep or + * it's state is unknown (just after reset / power on). + */ +#define UNIFI_SDIO_CLOCK_SAFE_HZ 1000000 /* Hz */ + +/* I/O default block size to use for UniFi. */ +#define UNIFI_IO_BLOCK_SIZE 64 + +#define UNIFI_WOL_OFF 0 +#define UNIFI_WOL_SDIO 1 +#define UNIFI_WOL_PIO 2 + +/* The number of Tx traffic queues */ +#define UNIFI_NO_OF_TX_QS 4 + +#define CSR_WIFI_HIP_RESERVED_HOST_TAG 0xFFFFFFFF + +/* + * The number of slots in the from-host queues. + * + * UNIFI_SOFT_TRAFFIC_Q_LENGTH is the number of slots in the traffic queues + * and there will be UNIFI_NO_OF_TX_QS of them. + * Traffic queues are used for data packets. + * + * UNIFI_SOFT_COMMAND_Q_LENGTH is the number of slots in the command queue. + * The command queue is used for MLME management requests. + * + * Queues are ring buffers and so must always have 1 unused slot. + */ +#define UNIFI_SOFT_TRAFFIC_Q_LENGTH (20 + 1) +#define UNIFI_SOFT_COMMAND_Q_LENGTH (16 + 1) + +#include "csr_types.h" /* from the synergy porting folder */ +#include "csr_framework_ext.h" /* from the synergy porting folder */ +#include "csr_sdio.h" /* from the synergy porting folder */ +#include "csr_pmem.h" /* from the synergy porting folder */ +#include "csr_util.h" /* from the synergy porting folder */ +#include "csr_formatted_io.h" /* from the synergy gsp folder */ +#include "csr_wifi_result.h" + + +/* Traffic queue ordered according to priority + * EAPOL/Uncontrolled port Queue should be the last + */ +typedef enum +{ + UNIFI_TRAFFIC_Q_BK = 0, + UNIFI_TRAFFIC_Q_BE, + UNIFI_TRAFFIC_Q_VI, + UNIFI_TRAFFIC_Q_VO, + UNIFI_TRAFFIC_Q_EAPOL, /* Non existant in HIP */ + UNIFI_TRAFFIC_Q_MAX, /* Non existant */ + UNIFI_TRAFFIC_Q_MLME /* Non existant */ +} unifi_TrafficQueue; + +/* + * Structure describing a bulk data slot. + * This structure is shared between the HIP core library and the OS + * layer. See the definition of unifi_net_data_malloc() for more details. + * + * The data_length field is used to indicate empty/occupied state. + * Needs to be defined before #include "unifi_os.h". + */ +typedef struct _bulk_data_desc +{ + const CsrUint8 *os_data_ptr; + CsrUint32 data_length; + const void *os_net_buf_ptr; + CsrUint32 net_buf_length; +} bulk_data_desc_t; + +/* Structure of an entry in the Symbol Look Up Table (SLUT). */ +typedef struct _symbol +{ + CsrUint16 id; + CsrUint32 obj; +} symbol_t; + +/* + * Header files need to be included from the current directory, + * the SME library, the synergy framework and the OS layer. + * A thin OS layer needs to be implemented in the porting exercise. + * + * Note that unifi_os.h should be included only in unifi.h + */ + +#include "unifi_os.h" + +/* + * Contains the HIP core definitions selected in the porting exercise, such as + * UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE and UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE. + * Implemented in the OS layer, as part of the porting exersice. + */ +#include "unifi_config.h" + +#include "csr_wifi_hip_signals.h" /* from this dir */ + +/* + * The card structure is an opaque pointer that is used to pass context + * to the upper-edge API functions. + */ +typedef struct card card_t; + + +/* + * This structure describes all of the bulk data that 'might' be + * associated with a signal. + */ +typedef struct _bulk_data_param +{ + bulk_data_desc_t d[UNIFI_MAX_DATA_REFERENCES]; +} bulk_data_param_t; + + +/* + * This structure describes the chip and HIP core lib + * information that exposed to the OS layer. + */ +typedef struct _card_info +{ + CsrUint16 chip_id; + CsrUint16 chip_version; + CsrUint32 fw_build; + CsrUint16 fw_hip_version; + CsrUint32 sdio_block_size; +} card_info_t; + + +/* + * Mini-coredump definitions + */ +/* Definition of XAP memory ranges used by the mini-coredump system. + * Note that, these values are NOT the same as UNIFI_REGISTERS, etc + * in unifihw.h which don't allow selection of register areas for each XAP. + */ +typedef enum unifi_coredump_space +{ + UNIFI_COREDUMP_MAC_REG, + UNIFI_COREDUMP_PHY_REG, + UNIFI_COREDUMP_SH_DMEM, + UNIFI_COREDUMP_MAC_DMEM, + UNIFI_COREDUMP_PHY_DMEM, + UNIFI_COREDUMP_TRIGGER_MAGIC = 0xFEED +} unifi_coredump_space_t; + +/* Structure used to request a register value from a mini-coredump buffer */ +typedef struct unifi_coredump_req +{ + /* From user */ + CsrInt32 index; /* 0=newest, -1=oldest */ + unifi_coredump_space_t space; /* memory space */ + CsrUint32 offset; /* register offset in space */ + /* From driver */ + CsrUint32 drv_build; /* Driver build id */ + CsrUint32 chip_ver; /* Chip version */ + CsrUint32 fw_ver; /* Firmware version */ + CsrInt32 requestor; /* Requestor: 0=auto dump, 1=manual */ + CsrTime timestamp; /* time of capture by driver */ + CsrUint32 serial; /* capture serial number */ + CsrInt32 value; /* register value */ +} unifi_coredump_req_t; /* mini-coredumped reg value request */ + + +/** + * @defgroup upperedge Upper edge API + * + * The following functions are implemented in the HIP core lib. + */ + +/** + * + * Initialise the HIP core lib. + * Note that the OS layer must initialise the SDIO glue layer and obtain + * an SDIO function context, prior to this call. + * + * @param sdiopriv the SDIO function context. + * + * @param ospriv the OS layer context. + * + * @return \p card_t the HIP core lib API context. + * + * @ingroup upperedge + */ +card_t* unifi_alloc_card(CsrSdioFunction *sdiopriv, void *ospriv); + + +/** + * + * Initialise the UniFi chip. + * + * @param card the HIP core lib API context. + * + * @param led_mask the led mask to apply to UniFi. + * + * @return \b 0 if UniFi is initialized. + * + * @return \b -CSR_EIO if an I/O error occured while initializing UniFi + * + * @return \b -CSR_ENODEV if the card is no longer present. + * + * @ingroup upperedge + */ +CsrResult unifi_init_card(card_t *card, CsrInt32 led_mask); + +/** + * + * De-Initialise the HIP core lib. + * + * @param card the HIP core lib API context. + * + * @ingroup upperedge + */ +void unifi_free_card(card_t *card); + +/** + * + * Cancel all the signals pending in the HIP core lib. + * Normally used during a system suspend when the power is retained on UniFi. + * + * @param card the HIP core lib API context. + * + * @ingroup upperedge + */ +void unifi_cancel_pending_signals(card_t *card); + +/** + * + * Send a signal to UniFi. + * Normally it is called from unifi_sys_hip_req() and the OS layer + * Tx data plane. + * + * Note that the bulkdata buffers ownership is passed to the HIP core lib. + * These buffers must be allocated using unifi_net_data_malloc(). + * + * @param card the HIP core lib API context. + * + * @param sigptr pointer to the signal. + * + * @param siglen size of the signal. + * + * @param bulkdata pointer to the bulk data associated with the signal. + * + * @return \b 0 signal is sent. + * + * @return \b -CSR_EIO if an error occured while sending the signal + * + * @return \b -CSR_ENODEV if the card is no longer present. + * + * @ingroup upperedge + */ +CsrResult unifi_send_signal(card_t *card, const CsrUint8 *sigptr, + CsrUint32 siglen, + const bulk_data_param_t *bulkdata); + +/** + * + * Check if the HIP core lib has resources to send a signal. + * Normally there no need to use this function. + * + * @param card the HIP core lib API context. + * + * @param sigptr pointer to the signal. + * + * @return \b 0 if there are resources for the signal. + * + * @return \b -CSR_ENOSPC if there are not enough resources + * + * @ingroup upperedge + */ +CsrResult unifi_send_resources_available(card_t *card, const CsrUint8 *sigptr); + +/** + * + * Read the UniFi chip and the HIP core lib information. + * + * @param card the HIP core lib API context. + * + * @param card_info pointer to save the information. + * + * @ingroup upperedge + */ +void unifi_card_info(card_t *card, card_info_t *card_info); + +/** + * + * Print the UniFi I/O and Interrupt status. + * Normally it is used for debug purposes only. + * + * @param card the HIP core lib API context. + + * @param status buffer for the chip status + * + * @return \b 0 if the check was performed. + * + * @return \b -CSR_EIO if an error occured while checking the status. + * + * @return \b -CSR_ENODEV if the card is no longer present. + * + * @ingroup upperedge + */ +CsrResult unifi_check_io_status(card_t *card, CsrInt32 *status); + + +/** + * + * Run the HIP core lib Botton-Half. + * Whenever the HIP core lib want this function to be called + * by the OS layer, it calls unifi_run_bh(). + * + * @param card the HIP core lib API context. + * + * @param remaining pointer to return the time (in msecs) that this function + * should be re-scheduled. A return value of 0 means that no re-scheduling + * is required. If unifi_bh() is called before the timeout expires, + * the caller must pass in the remaining time. + * + * @return \b 0 if no error occured. + * + * @return \b -CSR_ENODEV if the card is no longer present. + * + * @return \b -CSR_E* if an error occured while running the bottom half. + * + * @ingroup upperedge + */ +CsrResult unifi_bh(card_t *card, CsrUint32 *remaining); + + +/** + * UniFi Low Power Mode (Deep Sleep Signaling) + * + * unifi_low_power_mode defines the UniFi Deep Sleep Signaling status. + * Use with unifi_configure_low_power_mode() to enable/disable + * the Deep Sleep Signaling. + */ +enum unifi_low_power_mode +{ + UNIFI_LOW_POWER_DISABLED, + UNIFI_LOW_POWER_ENABLED +}; + +/** + * Periodic Wake Host Mode + * + * unifi_periodic_wake_mode defines the Periodic Wake Host Mode. + * It can only be set to UNIFI_PERIODIC_WAKE_HOST_ENABLED if + * low_power_mode == UNIFI_LOW_POWER_ENABLED. + */ +enum unifi_periodic_wake_mode +{ + UNIFI_PERIODIC_WAKE_HOST_DISABLED, + UNIFI_PERIODIC_WAKE_HOST_ENABLED +}; + +/** + * + * Run the HIP core lib Botton-Half. + * Whenever the HIP core lib want this function to be called + * by the OS layer, it calls unifi_run_bh(). + * + * Typically, the SME is responsible for configuring these parameters, + * so unifi_sys_configure_power_mode_req() is usually implemented + * as a direct call to unifi_configure_low_power_mode(). + * + * Note: When polling mode is used instead of interrupts, + * low_power_mode must never be set to UNIFI_LOW_POWER_ENABLED. + * + * @param card the HIP core lib API context. + * + * @param low_power_mode the Low Power Mode. + * + * @param periodic_wake_mode the Periodic Wake Mode. + * + * @return \b 0 if no error occured. + * + * @return \b -CSR_E* if the request failed. + * + * @ingroup upperedge + */ +CsrResult unifi_configure_low_power_mode(card_t *card, + enum unifi_low_power_mode low_power_mode, + enum unifi_periodic_wake_mode periodic_wake_mode); + +/** + * + * Forces the UniFi chip to enter a Deep Sleep state. + * This is normally called by the OS layer when the platform suspends. + * + * Note that if the UniFi Low Power Mode is disabled this call fails. + * + * @param card the HIP core lib API context. + * + * @return \b 0 if no error occured. + * + * @return \b -CSR_ENODEV if the card is no longer present. + * + * @return \b -CSR_E* if the request failed. + * + * @ingroup upperedge + */ +CsrResult unifi_force_low_power_mode(card_t *card); + +#ifndef CSR_WIFI_HIP_TA_DISABLE +/** + * Configure the Traffic Analysis sampling + * + * Enable or disable statistics gathering. + * Enable or disable particular packet detection. + * + * @param card the HIP core context + * @param config_type the item to configure + * @param config pointer to struct containing config info + * + * @return \b 0 if configuration was successful + * + * @return \b -CSR_EINVAL if a parameter had an invalid value + * + * @ingroup upperedge + */ +CsrResult unifi_ta_configure(card_t *card, + CsrWifiRouterCtrlTrafficConfigType config_type, + const CsrWifiRouterCtrlTrafficConfig *config); + +/** + * Pass a packet for Traffic Analysis sampling + * + * @param card the HIP core context + * @param direction the direction (Rx or Tx) of the frame. + * @param data pointer to bulkdata struct containing the packet + * @param saddr the source address of the packet + * @param sta_macaddr the MAC address of the UniFi chip + * @param timestamp the current time in msecs + * + * @ingroup upperedge + */ +void unifi_ta_sample(card_t *card, + CsrWifiRouterCtrlProtocolDirection direction, + const bulk_data_desc_t *data, + const CsrUint8 *saddr, + const CsrUint8 *sta_macaddr, + CsrUint32 timestamp, + CsrUint16 rate); + +/** + * Notify the HIP core lib for a detected Traffic Classification. + * Typically, the SME is responsible for configuring these parameters, + * so unifi_sys_traffic_classification_req() is usually implemented + * as a direct call to unifi_ta_classification(). + * + * @param card the HIP core context. + * @param traffic_type the detected traffic type. + * @param period The detected period of the traffic. + * + * @ingroup upperedge + */ +void unifi_ta_classification(card_t *card, + CsrWifiRouterCtrlTrafficType traffic_type, + CsrUint16 period); + +#endif +/** + * Use software to hard reset the chip. + * This is a subset of the unifi_init_card() functionality and should + * only be used only to reset a paniced chip before a coredump is taken. + * + * @param card the HIP core context. + * + * @ingroup upperedge + */ +CsrResult unifi_card_hard_reset(card_t *card); + + +CsrResult unifi_card_readn(card_t *card, CsrUint32 unifi_addr, void *pdata, CsrUint16 len); +CsrResult unifi_card_read16(card_t *card, CsrUint32 unifi_addr, CsrUint16 *pdata); +CsrResult unifi_card_write16(card_t *card, CsrUint32 unifi_addr, CsrUint16 data); + + +enum unifi_dbg_processors_select +{ + UNIFI_PROC_MAC, + UNIFI_PROC_PHY, + UNIFI_PROC_BT, + UNIFI_PROC_BOTH, + UNIFI_PROC_INVALID +}; + +CsrResult unifi_card_stop_processor(card_t *card, enum unifi_dbg_processors_select which); + +/** + * Call-outs from the HIP core lib to the OS layer. + * The following functions need to be implemented during the porting exercise. + */ + +/** + * Selects appropriate queue according to priority + * Helps maintain uniformity in queue selection between the HIP + * and the OS layers. + * + * @param priority priority of the packet + * + * @return \b Traffic queue to which a packet of this priority belongs + * + * @ingroup upperedge + */ +unifi_TrafficQueue +unifi_frame_priority_to_queue(CSR_PRIORITY priority); + +/** + * Returns the priority corresponding to a particular Queue when that is used + * when downgrading a packet to a lower AC. + * Helps maintain uniformity in queue - priority mapping between the HIP + * and the OS layers. + * + * @param queue + * + * @return \b Highest priority corresponding to this queue + * + * @ingroup upperedge + */ +CSR_PRIORITY unifi_get_default_downgrade_priority(unifi_TrafficQueue queue); + +/** + * + * Flow control callbacks. + * unifi_pause_xmit() is called when the HIP core lib does not have any + * resources to store data packets. The OS layer needs to pause + * the Tx data plane until unifi_restart_xmit() is called. + * + * @param ospriv the OS layer context. + * + * @ingroup upperedge + */ +void unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue); +void unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue); + +/** + * + * Request to run the Bottom-Half. + * The HIP core lib calls this function to request that unifi_bh() + * needs to be run by the OS layer. It can be called anytime, i.e. + * when the unifi_bh() is running. + * Since unifi_bh() is not re-entrant, usually unifi_run_bh() sets + * an event to a thread that schedules a call to unifi_bh(). + * + * @param ospriv the OS layer context. + * + * @ingroup upperedge + */ +CsrResult unifi_run_bh(void *ospriv); + +/** + * + * Delivers a signal received from UniFi to the OS layer. + * Normally, the data signals should be delivered to the data plane + * and all the rest to the SME (unifi_sys_hip_ind()). + * + * Note that the OS layer is responsible for freeing the bulkdata + * buffers, using unifi_net_data_free(). + * + * @param ospriv the OS layer context. + * + * @param sigptr pointer to the signal. + * + * @param siglen size of the signal. + * + * @param bulkdata pointer to the bulk data associated with the signal. + * + * @ingroup upperedge + */ +void unifi_receive_event(void *ospriv, + CsrUint8 *sigdata, CsrUint32 siglen, + const bulk_data_param_t *bulkdata); + + +typedef struct +{ + CsrUint16 free_fh_sig_queue_slots[UNIFI_NO_OF_TX_QS]; + CsrUint16 free_fh_bulkdata_slots; + CsrUint16 free_fh_fw_slots; +} unifi_HipQosInfo; + +void unifi_get_hip_qos_info(card_t *card, unifi_HipQosInfo *hipqosinfo); + + +/** + * Functions that read a portion of a firmware file. + * + * Note: If the UniFi chip runs the f/w from ROM, the HIP core may never + * call these functions. Also, the HIP core may call these functions even if + * a f/w file is not available. In this case, it is safe to fail the request. + */ +#define UNIFI_FW_STA 1 /* Identify STA firmware file */ + +/** + * + * Ask the OS layer to initialise a read from a f/w file. + * + * @param ospriv the OS layer context. + * + * @param is_fw if 0 the request if for the loader file, if 1 the request + * is for a f/w file. + * + * @param info a card_info_t structure containing versions information. + * Note that some members of the structure may not be initialised. + * + * @return \p NULL if the file is not available, or a pointer which contains + * OS specific information for the file (typically the contents of the file) + * that the HIP core uses when calling unifi_fw_read() and unifi_fw_read_stop() + * + * @ingroup upperedge + */ +void* unifi_fw_read_start(void *ospriv, CsrInt8 is_fw, const card_info_t *info); + +/** + * + * Ask the OS layer to return a portion from a f/w file. + * + * @param ospriv the OS layer context. + * + * @param arg the OS pointer returned by unifi_fw_read_start(). + * + * @param offset the offset in the f/w file to read the read from. + * + * @param buf the buffer to store the returned data. + * + * @param len the size in bytes of the requested read. + * + * @ingroup upperedge + */ +CsrInt32 unifi_fw_read(void *ospriv, void *arg, CsrUint32 offset, void *buf, CsrUint32 len); + +/** + * + * Ask the OS layer to finish reading from a f/w file. + * + * @param ospriv the OS layer context. + * + * @param dlpriv the OS pointer returned by unifi_fw_read_start(). + * + * @ingroup upperedge + */ +void unifi_fw_read_stop(void *ospriv, void *dlpriv); + +/** + * + * Ask OS layer for a handle to a dynamically allocated firmware buffer + * (primarily intended for production test images which may need conversion) + * + * @param ospriv the OS layer context. + * + * @param fwbuf pointer to dynamically allocated buffer + * + * @param len length of provided buffer in bytes + * + * @ingroup upperedge + */ +void* unifi_fw_open_buffer(void *ospriv, void *fwbuf, CsrUint32 len); + +/** + * + * Release a handle to a dynamically allocated firmware buffer + * (primarily intended for production test images which may need conversion) + * + * @param ospriv the OS layer context. + * + * @param fwbuf pointer to dynamically allocated buffer + * + * @ingroup upperedge + */ +void unifi_fw_close_buffer(void *ospriv, void *fwbuf); + +#ifndef CSR_WIFI_HIP_TA_DISABLE +/* + * Driver must provide these. + * + * A simple implementation will just call + * unifi_sys_traffic_protocol_ind() or unifi_sys_traffic_classification_ind() + * respectively. See sme_csr_userspace/sme_userspace.c. + */ +/** + * + * Indicates a detected packet of type packet_type. + * Typically, this information is processed by the SME so + * unifi_ta_indicate_protocol() needs to schedule a call to + * unifi_sys_traffic_protocol_ind(). + * + * @param ospriv the OS layer context. + * + * @param packet_type the detected packet type. + * + * @param direction the direction of the packet (Rx, Tx). + * + * @param src_addr the source address of the packet. + * + * @ingroup upperedge + */ +void unifi_ta_indicate_protocol(void *ospriv, + CsrWifiRouterCtrlTrafficPacketType packet_type, + CsrWifiRouterCtrlProtocolDirection direction, + const CsrWifiMacAddress *src_addr); + +/** + * + * Indicates statistics for the sample data over a period. + * Typically, this information is processed by the SME so + * unifi_ta_indicate_sampling() needs to schedule a call to + * unifi_sys_traffic_sample_ind(). + * + * @param ospriv the OS layer context. + * + * @param stats the pointer to the structure that contains the statistics. + * + * @ingroup upperedge + */ +void unifi_ta_indicate_sampling(void *ospriv, CsrWifiRouterCtrlTrafficStats *stats); +void unifi_ta_indicate_l4stats(void *ospriv, + CsrUint32 rxTcpThroughput, + CsrUint32 txTcpThroughput, + CsrUint32 rxUdpThroughput, + CsrUint32 txUdpThroughput); +#endif + +void unifi_rx_queue_flush(void *ospriv); + +/** + * Call-out from the SDIO glue layer. + * + * The glue layer needs to call unifi_sdio_interrupt_handler() every time + * an interrupts occurs. + * + * @param card the HIP core context. + * + * @ingroup bottomedge + */ +void unifi_sdio_interrupt_handler(card_t *card); + + +/* HELPER FUNCTIONS */ + +/* + * unifi_init() and unifi_download() implement a subset of unifi_init_card functionality + * that excludes HIP initialization. + */ +CsrResult unifi_init(card_t *card); +CsrResult unifi_download(card_t *card, CsrInt32 led_mask); + +/* + * unifi_start_processors() ensures both on-chip processors are running + */ +CsrResult unifi_start_processors(card_t *card); + +CsrResult unifi_capture_panic(card_t *card); + +/* + * Configure HIP interrupt processing mode + */ +#define CSR_WIFI_INTMODE_DEFAULT 0 +#define CSR_WIFI_INTMODE_RUN_BH_ONCE 1 /* Run BH once per interrupt */ + +void unifi_set_interrupt_mode(card_t *card, CsrUint32 mode); + +/* + * unifi_request_max_clock() requests that max SDIO clock speed is set at the + * next suitable opportunity. + */ +void unifi_request_max_sdio_clock(card_t *card); + + +/* Functions to lookup bulk data command names. */ +const CsrCharString* lookup_bulkcmd_name(CsrUint16 id); + +/* Function to log HIP's global debug buffer */ +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +void unifi_debug_buf_dump(void); +#endif + +/* Mini-coredump utility functions */ +CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req); +CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req); +CsrResult unifi_coredump_request_at_next_reset(card_t *card, CsrInt8 enable); +CsrResult unifi_coredump_init(card_t *card, CsrUint16 num_dump_buffers); +void unifi_coredump_free(card_t *card); + +#ifdef __cplusplus +} +#endif + +#endif /* __CSR_WIFI_HIP_UNIFI_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c new file mode 100644 index 000000000000..ee1970dae91c --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c @@ -0,0 +1,46 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include "csr_wifi_hip_unifi.h" + +struct sig_name +{ + CsrInt16 id; + const CsrCharString *name; +}; + +static const struct sig_name Unifi_bulkcmd_names[] = { + { 0, "SignalCmd" }, + { 1, "CopyToHost" }, + { 2, "CopyToHostAck" }, + { 3, "CopyFromHost" }, + { 4, "CopyFromHostAck" }, + { 5, "ClearSlot" }, + { 6, "CopyOverlay" }, + { 7, "CopyOverlayAck" }, + { 8, "CopyFromHostAndClearSlot" }, + { 15, "Padding" } +}; + +const CsrCharString* lookup_bulkcmd_name(CsrUint16 id) +{ + if (id < 9) + { + return Unifi_bulkcmd_names[id].name; + } + if (id == 15) + { + return "Padding"; + } + + return "UNKNOWN"; +} + + diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h new file mode 100644 index 000000000000..0873b7b998e2 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h @@ -0,0 +1,76 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_unifi_udi.h + * + * PURPOSE: + * Declarations and definitions for the UniFi Debug Interface. + * + * --------------------------------------------------------------------------- + */ +#ifndef __CSR_WIFI_HIP_UNIFI_UDI_H__ +#define __CSR_WIFI_HIP_UNIFI_UDI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_signals.h" + + +/* + * Support for tracing the wire protocol. + */ +enum udi_log_direction +{ + UDI_LOG_FROM_HOST = 0x0000, + UDI_LOG_TO_HOST = 0x0001 +}; + +typedef void (*udi_func_t)(void *ospriv, CsrUint8 *sigdata, + CsrUint32 signal_len, + const bulk_data_param_t *bulkdata, + enum udi_log_direction dir); + +CsrResult unifi_set_udi_hook(card_t *card, udi_func_t udi_fn); +CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn); + + +/* + * Function to print current status info to a string. + * This is used in the linux /proc interface and might be useful + * in other systems. + */ +CsrInt32 unifi_print_status(card_t *card, CsrCharString *str, CsrInt32 *remain); + +#define UNIFI_SNPRINTF_RET(buf_p, remain, written) \ + do { \ + if (written >= remain) { \ + if (remain >= 2) { \ + buf_p[remain - 2] = '\n'; \ + buf_p[remain - 1] = 0; \ + } \ + buf_p += remain; \ + remain = 0; \ + } else if (written > 0) { \ + buf_p += written; \ + remain -= written; \ + } \ + } while (0) + + +#ifdef __cplusplus +} +#endif + +#endif /* __CSR_WIFI_HIP_UNIFI_UDI_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifihw.h b/drivers/staging/csr/csr_wifi_hip_unifihw.h new file mode 100644 index 000000000000..5ffd6ba38d3b --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_unifihw.h @@ -0,0 +1,67 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * + * File: csr_wifi_hip_unifihw.h + * + * Definitions of various chip registers, addresses, values etc. + * + * --------------------------------------------------------------------------- + */ +#ifndef __UNIFIHW_H__ +#define __UNIFIHW_H__ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Symbol Look Up Table fingerprint. IDs are in sigs.h */ +#define SLUT_FINGERPRINT 0xD397 + + +/* Values of LoaderOperation */ +#define UNIFI_LOADER_IDLE 0x00 +#define UNIFI_LOADER_COPY 0x01 +#define UNIFI_LOADER_ERROR_MASK 0xF0 + +/* Values of BootLoaderOperation */ +#define UNIFI_BOOT_LOADER_IDLE 0x00 +#define UNIFI_BOOT_LOADER_RESTART 0x01 +#define UNIFI_BOOT_LOADER_PATCH 0x02 +#define UNIFI_BOOT_LOADER_LOAD_STA 0x10 +#define UNIFI_BOOT_LOADER_LOAD_PTEST 0x11 + + +/* Memory spaces encoded in top byte of Generic Pointer type */ +#define UNIFI_SH_DMEM 0x01 /* Shared Data Memory */ +#define UNIFI_EXT_FLASH 0x02 /* External FLASH */ +#define UNIFI_EXT_SRAM 0x03 /* External SRAM */ +#define UNIFI_REGISTERS 0x04 /* Registers */ +#define UNIFI_PHY_DMEM 0x10 /* PHY Data Memory */ +#define UNIFI_PHY_PMEM 0x11 /* PHY Program Memory */ +#define UNIFI_PHY_ROM 0x12 /* PHY ROM */ +#define UNIFI_MAC_DMEM 0x20 /* MAC Data Memory */ +#define UNIFI_MAC_PMEM 0x21 /* MAC Program Memory */ +#define UNIFI_MAC_ROM 0x22 /* MAC ROM */ +#define UNIFI_BT_DMEM 0x30 /* BT Data Memory */ +#define UNIFI_BT_PMEM 0x31 /* BT Program Memory */ +#define UNIFI_BT_ROM 0x32 /* BT ROM */ + +#define UNIFI_MAKE_GP(R, O) (((UNIFI_ ## R) << 24) | (O)) +#define UNIFI_GP_OFFSET(GP) ((GP) & 0xFFFFFF) +#define UNIFI_GP_SPACE(GP) (((GP) >> 24) & 0xFF) + +#ifdef __cplusplus +} +#endif + +#endif /* __UNIFIHW_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifiversion.h b/drivers/staging/csr/csr_wifi_hip_unifiversion.h new file mode 100644 index 000000000000..e1fdbb27a463 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_unifiversion.h @@ -0,0 +1,38 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: unifiversion.h + * + * PURPOSE: + * Version information for the portable UniFi driver. + * + * --------------------------------------------------------------------------- + */ + +#ifndef __UNIFIVERSION_H__ +#define __UNIFIVERSION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The minimum version of Host Interface Protocol required by the driver. + */ +#define UNIFI_HIP_MAJOR_VERSION 9 +#define UNIFI_HIP_MINOR_VERSION 1 + +#ifdef __cplusplus +} +#endif + +#endif /* __UNIFIVERSION_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.c b/drivers/staging/csr/csr_wifi_hip_xbv.c new file mode 100644 index 000000000000..5d0fdcce1a97 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_xbv.c @@ -0,0 +1,1075 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_xbv.c + * + * PURPOSE: + * Routines for downloading firmware to UniFi. + * + * UniFi firmware files use a nested TLV (Tag-Length-Value) format. + * + * --------------------------------------------------------------------------- + */ + +#ifdef CSR_WIFI_XBV_TEST +/* Standalone test harness */ +#include "unifi_xbv.h" +#include "csr_wifi_hip_unifihw.h" +#else +/* Normal driver build */ +#include "csr_wifi_hip_unifiversion.h" +#include "csr_wifi_hip_card.h" +#define DBG_TAG(t) +#endif + +#include "csr_wifi_hip_xbv.h" + +#define STREAM_CHECKSUM 0x6d34 /* Sum of uint16s in each patch stream */ + +/* XBV sizes used in patch conversion + */ +#define PTDL_MAX_SIZE 2048 /* Max bytes allowed per PTDL */ +#define PTDL_HDR_SIZE (4 + 2 + 6 + 2) /* sizeof(fw_id, sec_len, patch_cmd, csum) */ + +/* Struct to represent a buffer for reading firmware file */ + +typedef struct +{ + void *dlpriv; + CsrInt32 ioffset; + fwreadfn_t iread; +} ct_t; + +/* Struct to represent a TLV field */ +typedef struct +{ + CsrCharString t_name[4]; + CsrUint32 t_len; +} tag_t; + + +#define TAG_EQ(i, v) (((i)[0] == (v)[0]) && \ + ((i)[1] == (v)[1]) && \ + ((i)[2] == (v)[2]) && \ + ((i)[3] == (v)[3])) + +/* We create a small stack on the stack that contains an enum + * indicating the containing list segments, and the offset at which + * those lists end. This enables a lot more error checking. */ +typedef enum +{ + xbv_xbv1, + /*xbv_info,*/ + xbv_fw, + xbv_vers, + xbv_vand, + xbv_ptch, + xbv_other +} xbv_container; + +#define XBV_STACK_SIZE 6 +#define XBV_MAX_OFFS 0x7fffffff + +typedef struct +{ + struct + { + xbv_container container; + CsrInt32 ioffset_end; + } s[XBV_STACK_SIZE]; + CsrUint32 ptr; +} xbv_stack_t; + +static CsrInt32 read_tag(card_t *card, ct_t *ct, tag_t *tag); +static CsrInt32 read_bytes(card_t *card, ct_t *ct, void *buf, CsrUint32 len); +static CsrInt32 read_uint(card_t *card, ct_t *ct, CsrUint32 *u, CsrUint32 len); +static CsrInt32 xbv_check(xbv1_t *fwinfo, const xbv_stack_t *stack, + xbv_mode new_mode, xbv_container old_cont); +static CsrInt32 xbv_push(xbv1_t *fwinfo, xbv_stack_t *stack, + xbv_mode new_mode, xbv_container old_cont, + xbv_container new_cont, CsrUint32 ioff); + +static CsrUint32 write_uint16(void *buf, const CsrUint32 offset, + const CsrUint16 val); +static CsrUint32 write_uint32(void *buf, const CsrUint32 offset, + const CsrUint32 val); +static CsrUint32 write_bytes(void *buf, const CsrUint32 offset, + const CsrUint8 *data, const CsrUint32 len); +static CsrUint32 write_tag(void *buf, const CsrUint32 offset, + const CsrCharString *tag_str); +static CsrUint32 write_chunk(void *buf, const CsrUint32 offset, + const CsrCharString *tag_str, + const CsrUint32 payload_len); +static CsrUint16 calc_checksum(void *buf, const CsrUint32 offset, + const CsrUint32 bytes_len); +static CsrUint32 calc_patch_size(const xbv1_t *fwinfo); + +static CsrUint32 write_xbv_header(void *buf, const CsrUint32 offset, + const CsrUint32 file_payload_length); +static CsrUint32 write_ptch_header(void *buf, const CsrUint32 offset, + const CsrUint32 fw_id); +static CsrUint32 write_patchcmd(void *buf, const CsrUint32 offset, + const CsrUint32 dst_genaddr, const CsrUint16 len); +static CsrUint32 write_reset_ptdl(void *buf, const CsrUint32 offset, + const xbv1_t *fwinfo, CsrUint32 fw_id); +static CsrUint32 write_fwdl_to_ptdl(void *buf, const CsrUint32 offset, + fwreadfn_t readfn, const struct FWDL *fwdl, + const void *fw_buf, const CsrUint32 fw_id, + void *rdbuf); + +/* + * --------------------------------------------------------------------------- + * parse_xbv1 + * + * Scan the firmware file to find the TLVs we are interested in. + * Actions performed: + * - check we support the file format version in VERF + * Store these TLVs if we have a firmware image: + * - SLTP Symbol Lookup Table Pointer + * - FWDL firmware download segments + * - FWOL firmware overlay segment + * - VMEQ Register probe tests to verify matching h/w + * Store these TLVs if we have a patch file: + * - FWID the firmware build ID that this file patches + * - PTDL The actual patches + * + * The structure pointed to by fwinfo is cleared and + * 'fwinfo->mode' is set to 'unknown'. The 'fwinfo->mode' + * variable is set to 'firmware' or 'patch' once we know which + * sort of XBV file we have. + * + * Arguments: + * readfn Pointer to function to call to read from the file. + * dlpriv Opaque pointer arg to pass to readfn. + * fwinfo Pointer to fwinfo struct to fill in. + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR error code on failure + * --------------------------------------------------------------------------- + */ +CsrResult xbv1_parse(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo) +{ + ct_t ct; + tag_t tag; + xbv_stack_t stack; + + ct.dlpriv = dlpriv; + ct.ioffset = 0; + ct.iread = readfn; + + CsrMemSet(fwinfo, 0, sizeof(xbv1_t)); + fwinfo->mode = xbv_unknown; + + /* File must start with XBV1 triplet */ + if (read_tag(card, &ct, &tag) <= 0) + { + unifi_error(NULL, "File is not UniFi firmware\n"); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + DBG_TAG(tag.t_name); + + if (!TAG_EQ(tag.t_name, "XBV1")) + { + unifi_error(NULL, "File is not UniFi firmware (%s)\n", tag.t_name); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + stack.ptr = 0; + stack.s[stack.ptr].container = xbv_xbv1; + stack.s[stack.ptr].ioffset_end = XBV_MAX_OFFS; + + /* Now scan the file */ + while (1) + { + CsrInt32 n; + + n = read_tag(card, &ct, &tag); + if (n < 0) + { + unifi_error(NULL, "No tag\n"); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + if (n == 0) + { + /* End of file */ + break; + } + + DBG_TAG(tag.t_name); + + /* File format version */ + if (TAG_EQ(tag.t_name, "VERF")) + { + CsrUint32 version; + + if (xbv_check(fwinfo, &stack, xbv_unknown, xbv_xbv1) || + (tag.t_len != 2) || + read_uint(card, &ct, &version, 2)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + if (version != 0) + { + unifi_error(NULL, "Unsupported firmware file version: %d.%d\n", + version >> 8, version & 0xFF); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + } + else if (TAG_EQ(tag.t_name, "LIST")) + { + CsrCharString name[4]; + CsrUint32 list_end; + + list_end = ct.ioffset + tag.t_len; + + if (read_bytes(card, &ct, name, 4)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + DBG_TAG(name); + if (TAG_EQ(name, "FW ")) + { + if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_xbv1, xbv_fw, list_end)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + } + else if (TAG_EQ(name, "VERS")) + { + if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_fw, xbv_vers, list_end) || + (fwinfo->vers.num_vand != 0)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + } + else if (TAG_EQ(name, "VAND")) + { + struct VAND *vand; + + if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_vers, xbv_vand, list_end) || + (fwinfo->vers.num_vand >= MAX_VAND)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* Get a new VAND */ + vand = fwinfo->vand + fwinfo->vers.num_vand++; + + /* Fill it in */ + vand->first = fwinfo->num_vmeq; + vand->count = 0; + } + else if (TAG_EQ(name, "PTCH")) + { + if (xbv_push(fwinfo, &stack, xbv_patch, xbv_xbv1, xbv_ptch, list_end)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + } + else + { + /* Skip over any other lists. We dont bother to push + * the new list type now as we would only pop it at + * the end of the outer loop. */ + ct.ioffset += tag.t_len - 4; + } + } + else if (TAG_EQ(tag.t_name, "SLTP")) + { + CsrUint32 addr; + + if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) || + (tag.t_len != 4) || + (fwinfo->slut_addr != 0) || + read_uint(card, &ct, &addr, 4)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + fwinfo->slut_addr = addr; + } + else if (TAG_EQ(tag.t_name, "FWDL")) + { + CsrUint32 addr; + struct FWDL *fwdl; + + if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) || + (fwinfo->num_fwdl >= MAX_FWDL) || + (read_uint(card, &ct, &addr, 4))) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + fwdl = fwinfo->fwdl + fwinfo->num_fwdl++; + + fwdl->dl_size = tag.t_len - 4; + fwdl->dl_addr = addr; + fwdl->dl_offset = ct.ioffset; + + ct.ioffset += tag.t_len - 4; + } + else if (TAG_EQ(tag.t_name, "FWOV")) + { + if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) || + (fwinfo->fwov.dl_size != 0) || + (fwinfo->fwov.dl_offset != 0)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + fwinfo->fwov.dl_size = tag.t_len; + fwinfo->fwov.dl_offset = ct.ioffset; + + ct.ioffset += tag.t_len; + } + else if (TAG_EQ(tag.t_name, "VMEQ")) + { + CsrUint32 temp[3]; + struct VAND *vand; + struct VMEQ *vmeq; + + if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_vand) || + (fwinfo->num_vmeq >= MAX_VMEQ) || + (fwinfo->vers.num_vand == 0) || + (tag.t_len != 8) || + read_uint(card, &ct, &temp[0], 4) || + read_uint(card, &ct, &temp[1], 2) || + read_uint(card, &ct, &temp[2], 2)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* Get the last VAND */ + vand = fwinfo->vand + (fwinfo->vers.num_vand - 1); + + /* Get a new VMEQ */ + vmeq = fwinfo->vmeq + fwinfo->num_vmeq++; + + /* Note that this VAND contains another VMEQ */ + vand->count++; + + /* Fill in the VMEQ */ + vmeq->addr = temp[0]; + vmeq->mask = (CsrUint16)temp[1]; + vmeq->value = (CsrUint16)temp[2]; + } + else if (TAG_EQ(tag.t_name, "FWID")) + { + CsrUint32 build_id; + + if (xbv_check(fwinfo, &stack, xbv_patch, xbv_ptch) || + (tag.t_len != 4) || + (fwinfo->build_id != 0) || + read_uint(card, &ct, &build_id, 4)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + fwinfo->build_id = build_id; + } + else if (TAG_EQ(tag.t_name, "PTDL")) + { + struct PTDL *ptdl; + + if (xbv_check(fwinfo, &stack, xbv_patch, xbv_ptch) || + (fwinfo->num_ptdl >= MAX_PTDL)) + { + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + /* Allocate a new PTDL */ + ptdl = fwinfo->ptdl + fwinfo->num_ptdl++; + + ptdl->dl_size = tag.t_len; + ptdl->dl_offset = ct.ioffset; + + ct.ioffset += tag.t_len; + } + else + { + /* + * If we get here it is a tag we are not interested in, + * just skip over it. + */ + ct.ioffset += tag.t_len; + } + + /* Check to see if we are at the end of the currently stacked + * segment. We could finish more than one list at a time. */ + while (ct.ioffset >= stack.s[stack.ptr].ioffset_end) + { + if (ct.ioffset > stack.s[stack.ptr].ioffset_end) + { + unifi_error(NULL, + "XBV file has overrun stack'd segment %d (%d > %d)\n", + stack.ptr, ct.ioffset, stack.s[stack.ptr].ioffset_end); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + if (stack.ptr <= 0) + { + unifi_error(NULL, "XBV file has underrun stack pointer\n"); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + stack.ptr--; + } + } + + if (stack.ptr != 0) + { + unifi_error(NULL, "Last list of XBV is not complete.\n"); + return CSR_WIFI_HIP_RESULT_INVALID_VALUE; + } + + return CSR_RESULT_SUCCESS; +} /* xbv1_parse() */ + + +/* Check the the XBV file is of a consistant sort (either firmware or + * patch) and that we are in the correct containing list type. */ +static CsrInt32 xbv_check(xbv1_t *fwinfo, const xbv_stack_t *stack, + xbv_mode new_mode, xbv_container old_cont) +{ + /* If the new file mode is unknown the current packet could be in + * either (any) type of XBV file, and we cant make a decission at + * this time. */ + if (new_mode != xbv_unknown) + { + if (fwinfo->mode == xbv_unknown) + { + fwinfo->mode = new_mode; + } + else if (fwinfo->mode != new_mode) + { + return -1; + } + } + /* If the current stack top doesn't match what we expect then the + * file is corrupt. */ + if (stack->s[stack->ptr].container != old_cont) + { + return -1; + } + return 0; +} + + +/* Make checks as above and then enter a new list */ +static CsrInt32 xbv_push(xbv1_t *fwinfo, xbv_stack_t *stack, + xbv_mode new_mode, xbv_container old_cont, + xbv_container new_cont, CsrUint32 new_ioff) +{ + if (xbv_check(fwinfo, stack, new_mode, old_cont)) + { + return -1; + } + + /* Check that our stack won't overflow. */ + if (stack->ptr >= (XBV_STACK_SIZE - 1)) + { + return -1; + } + + /* Add the new list element to the top of the stack. */ + stack->ptr++; + stack->s[stack->ptr].container = new_cont; + stack->s[stack->ptr].ioffset_end = new_ioff; + + return 0; +} + + +static CsrUint32 xbv2uint(CsrUint8 *ptr, CsrInt32 len) +{ + CsrUint32 u = 0; + CsrInt16 i; + + for (i = 0; i < len; i++) + { + CsrUint32 b; + b = ptr[i]; + u += b << (i * 8); + } + return u; +} + + +static CsrInt32 read_tag(card_t *card, ct_t *ct, tag_t *tag) +{ + CsrUint8 buf[8]; + CsrInt32 n; + + n = (*ct->iread)(card->ospriv, ct->dlpriv, ct->ioffset, buf, 8); + if (n <= 0) + { + return n; + } + + /* read the tag and length */ + if (n != 8) + { + return -1; + } + + /* get section tag */ + CsrMemCpy(tag->t_name, buf, 4); + + /* get section length */ + tag->t_len = xbv2uint(buf + 4, 4); + + ct->ioffset += 8; + + return 8; +} /* read_tag() */ + + +static CsrInt32 read_bytes(card_t *card, ct_t *ct, void *buf, CsrUint32 len) +{ + /* read the tag value */ + if ((*ct->iread)(card->ospriv, ct->dlpriv, ct->ioffset, buf, len) != (CsrInt32)len) + { + return -1; + } + + ct->ioffset += len; + + return 0; +} /* read_bytes() */ + + +static CsrInt32 read_uint(card_t *card, ct_t *ct, CsrUint32 *u, CsrUint32 len) +{ + CsrUint8 buf[4]; + + /* Integer cannot be more than 4 bytes */ + if (len > 4) + { + return -1; + } + + if (read_bytes(card, ct, buf, len)) + { + return -1; + } + + *u = xbv2uint(buf, len); + + return 0; +} /* read_uint() */ + + +static CsrUint32 write_uint16(void *buf, const CsrUint32 offset, const CsrUint16 val) +{ + CsrUint8 *dst = (CsrUint8 *)buf + offset; + *dst++ = (CsrUint8)(val & 0xff); /* LSB first */ + *dst = (CsrUint8)(val >> 8); + return sizeof(CsrUint16); +} + + +static CsrUint32 write_uint32(void *buf, const CsrUint32 offset, const CsrUint32 val) +{ + write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff)); + write_uint16(buf, offset + 2, (CsrUint16)(val >> 16)); + return sizeof(CsrUint32); +} + + +static CsrUint32 write_bytes(void *buf, const CsrUint32 offset, const CsrUint8 *data, const CsrUint32 len) +{ + CsrUint32 i; + CsrUint8 *dst = (CsrUint8 *)buf + offset; + + for (i = 0; i < len; i++) + { + *dst++ = *((CsrUint8 *)data + i); + } + return len; +} + + +static CsrUint32 write_tag(void *buf, const CsrUint32 offset, const CsrCharString *tag_str) +{ + CsrUint8 *dst = (CsrUint8 *)buf + offset; + CsrMemCpy(dst, tag_str, 4); + return 4; +} + + +static CsrUint32 write_chunk(void *buf, const CsrUint32 offset, const CsrCharString *tag_str, const CsrUint32 payload_len) +{ + CsrUint32 written = 0; + written += write_tag(buf, offset, tag_str); + written += write_uint32(buf, written + offset, (CsrUint32)payload_len); + + return written; +} + + +static CsrUint16 calc_checksum(void *buf, const CsrUint32 offset, const CsrUint32 bytes_len) +{ + CsrUint32 i; + CsrUint8 *src = (CsrUint8 *)buf + offset; + CsrUint16 sum = 0; + CsrUint16 val; + + for (i = 0; i < bytes_len / 2; i++) + { + /* Contents copied to file is LE, host might not be */ + val = (CsrUint16) * src++; /* LSB */ + val += (CsrUint16)(*src++) << 8; /* MSB */ + sum += val; + } + + /* Total of uint16s in the stream plus the stored check value + * should equal STREAM_CHECKSUM when decoded. + */ + return (STREAM_CHECKSUM - sum); +} + + +#define PTDL_RESET_DATA_SIZE 20 /* Size of reset vectors PTDL */ + +static CsrUint32 calc_patch_size(const xbv1_t *fwinfo) +{ + CsrInt16 i; + CsrUint32 size = 0; + + /* + * Work out how big an equivalent patch format file must be for this image. + * This only needs to be approximate, so long as it's large enough. + */ + if (fwinfo->mode != xbv_firmware) + { + return 0; + } + + /* Payload (which will get put into a series of PTDLs) */ + for (i = 0; i < fwinfo->num_fwdl; i++) + { + size += fwinfo->fwdl[i].dl_size; + } + + /* Another PTDL at the end containing reset vectors */ + size += PTDL_RESET_DATA_SIZE; + + /* PTDL headers. Add one for remainder, one for reset vectors */ + size += ((fwinfo->num_fwdl / PTDL_MAX_SIZE) + 2) * PTDL_HDR_SIZE; + + /* Another 1K sufficient to cover miscellaneous headers */ + size += 1024; + + return size; +} + + +static CsrUint32 write_xbv_header(void *buf, const CsrUint32 offset, const CsrUint32 file_payload_length) +{ + CsrUint32 written = 0; + + /* The length value given to the XBV chunk is the length of all subsequent + * contents of the file, excluding the 8 byte size of the XBV1 header itself + * (The added 6 bytes thus accounts for the size of the VERF) + */ + written += write_chunk(buf, offset + written, (CsrCharString *)"XBV1", file_payload_length + 6); + + written += write_chunk(buf, offset + written, (CsrCharString *)"VERF", 2); + written += write_uint16(buf, offset + written, 0); /* File version */ + + return written; +} + + +static CsrUint32 write_ptch_header(void *buf, const CsrUint32 offset, const CsrUint32 fw_id) +{ + CsrUint32 written = 0; + + /* LIST is written with a zero length, to be updated later */ + written += write_chunk(buf, offset + written, (CsrCharString *)"LIST", 0); + written += write_tag(buf, offset + written, (CsrCharString *)"PTCH"); /* List type */ + + written += write_chunk(buf, offset + written, (CsrCharString *)"FWID", 4); + written += write_uint32(buf, offset + written, fw_id); + + + return written; +} + + +#define UF_REGION_PHY 1 +#define UF_REGION_MAC 2 +#define UF_MEMPUT_MAC 0x0000 +#define UF_MEMPUT_PHY 0x1000 + +static CsrUint32 write_patchcmd(void *buf, const CsrUint32 offset, const CsrUint32 dst_genaddr, const CsrUint16 len) +{ + CsrUint32 written = 0; + CsrUint32 region = (dst_genaddr >> 28); + CsrUint16 cmd_and_len = UF_MEMPUT_MAC; + + if (region == UF_REGION_PHY) + { + cmd_and_len = UF_MEMPUT_PHY; + } + else if (region != UF_REGION_MAC) + { + return 0; /* invalid */ + } + + /* Write the command and data length */ + cmd_and_len |= len; + written += write_uint16(buf, offset + written, cmd_and_len); + + /* Write the destination generic address */ + written += write_uint16(buf, offset + written, (CsrUint16)(dst_genaddr >> 16)); + written += write_uint16(buf, offset + written, (CsrUint16)(dst_genaddr & 0xffff)); + + /* The data payload should be appended to the command */ + return written; +} + + +static CsrUint32 write_fwdl_to_ptdl(void *buf, const CsrUint32 offset, fwreadfn_t readfn, + const struct FWDL *fwdl, const void *dlpriv, + const CsrUint32 fw_id, void *fw_buf) +{ + CsrUint32 written = 0; + CsrInt16 chunks = 0; + CsrUint32 left = fwdl->dl_size; /* Bytes left in this fwdl */ + CsrUint32 dl_addr = fwdl->dl_addr; /* Target address of fwdl image on XAP */ + CsrUint32 dl_offs = fwdl->dl_offset; /* Offset of fwdl image data in source */ + CsrUint16 csum; + CsrUint32 csum_start_offs; /* first offset to include in checksum */ + CsrUint32 sec_data_len; /* section data byte count */ + CsrUint32 sec_len; /* section data + header byte count */ + + /* FWDL maps to one or more PTDLs, as max size for a PTDL is 1K words */ + while (left) + { + /* Calculate amount to be transferred */ + sec_data_len = CSRMIN(left, PTDL_MAX_SIZE - PTDL_HDR_SIZE); + sec_len = sec_data_len + PTDL_HDR_SIZE; + + /* Write PTDL header + entire PTDL size */ + written += write_chunk(buf, offset + written, (CsrCharString *)"PTDL", sec_len); + /* bug digest implies 4 bytes of padding here, but that seems wrong */ + + /* Checksum starts here */ + csum_start_offs = offset + written; + + /* Patch-chunk header: fw_id. Note that this is in XAP word order */ + written += write_uint16(buf, offset + written, (CsrUint16)(fw_id >> 16)); + written += write_uint16(buf, offset + written, (CsrUint16)(fw_id & 0xffff)); + + /* Patch-chunk header: section length in uint16s */ + written += write_uint16(buf, offset + written, (CsrUint16)(sec_len / 2)); + + + /* Write the appropriate patch command for the data's destination ptr */ + written += write_patchcmd(buf, offset + written, dl_addr, (CsrUint16)(sec_data_len / 2)); + + /* Write the data itself (limited to the max chunk length) */ + if (readfn(NULL, (void *)dlpriv, dl_offs, fw_buf, sec_data_len) < 0) + { + return 0; + } + + written += write_bytes(buf, + offset + written, + fw_buf, + sec_data_len); + + /* CsrUint16 checksum calculated over data written */ + csum = calc_checksum(buf, csum_start_offs, written - (csum_start_offs - offset)); + written += write_uint16(buf, offset + written, csum); + + left -= sec_data_len; + dl_addr += sec_data_len; + dl_offs += sec_data_len; + chunks++; + } + + return written; +} + + +#define SEC_CMD_LEN ((4 + 2) * 2) /* sizeof(cmd, vector) per XAP */ +#define PTDL_VEC_HDR_SIZE (4 + 2 + 2) /* sizeof(fw_id, sec_len, csum) */ +#define UF_MAC_START_VEC 0x00c00000 /* Start address of image on MAC */ +#define UF_PHY_START_VEC 0x00c00000 /* Start address of image on PHY */ +#define UF_MAC_START_CMD 0x6000 /* MAC "Set start address" command */ +#define UF_PHY_START_CMD 0x7000 /* PHY "Set start address" command */ + +static CsrUint32 write_reset_ptdl(void *buf, const CsrUint32 offset, const xbv1_t *fwinfo, CsrUint32 fw_id) +{ + CsrUint32 written = 0; + CsrUint16 csum; + CsrUint32 csum_start_offs; /* first offset to include in checksum */ + CsrUint32 sec_len; /* section data + header byte count */ + + sec_len = SEC_CMD_LEN + PTDL_VEC_HDR_SIZE; /* Total section byte length */ + + /* Write PTDL header + entire PTDL size */ + written += write_chunk(buf, offset + written, (CsrCharString *)"PTDL", sec_len); + + /* Checksum starts here */ + csum_start_offs = offset + written; + + /* Patch-chunk header: fw_id. Note that this is in XAP word order */ + written += write_uint16(buf, offset + written, (CsrUint16)(fw_id >> 16)); + written += write_uint16(buf, offset + written, (CsrUint16)(fw_id & 0xffff)); + + /* Patch-chunk header: section length in uint16s */ + written += write_uint16(buf, offset + written, (CsrUint16)(sec_len / 2)); + + /* + * Restart addresses to be executed on subsequent loader restart command. + */ + + /* Setup the MAC start address, note word ordering */ + written += write_uint16(buf, offset + written, UF_MAC_START_CMD); + written += write_uint16(buf, offset + written, (UF_MAC_START_VEC >> 16)); + written += write_uint16(buf, offset + written, (UF_MAC_START_VEC & 0xffff)); + + /* Setup the PHY start address, note word ordering */ + written += write_uint16(buf, offset + written, UF_PHY_START_CMD); + written += write_uint16(buf, offset + written, (UF_PHY_START_VEC >> 16)); + written += write_uint16(buf, offset + written, (UF_PHY_START_VEC & 0xffff)); + + /* CsrUint16 checksum calculated over data written */ + csum = calc_checksum(buf, csum_start_offs, written - (csum_start_offs - offset)); + written += write_uint16(buf, offset + written, csum); + + return written; +} + + +/* + * --------------------------------------------------------------------------- + * read_slut + * + * desc + * + * Arguments: + * readfn Pointer to function to call to read from the file. + * dlpriv Opaque pointer arg to pass to readfn. + * addr Offset into firmware image of SLUT. + * fwinfo Pointer to fwinfo struct to fill in. + * + * Returns: + * Number of SLUT entries in the f/w, or -1 if the image was corrupt. + * --------------------------------------------------------------------------- + */ +CsrInt32 xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo, + symbol_t *slut, CsrUint32 slut_len) +{ + CsrInt16 i; + CsrInt32 offset; + CsrUint32 magic; + CsrUint32 count = 0; + ct_t ct; + + if (fwinfo->mode != xbv_firmware) + { + return -1; + } + + /* Find the d/l segment containing the SLUT */ + /* This relies on the SLUT being entirely contained in one segment */ + offset = -1; + for (i = 0; i < fwinfo->num_fwdl; i++) + { + if ((fwinfo->slut_addr >= fwinfo->fwdl[i].dl_addr) && + (fwinfo->slut_addr < (fwinfo->fwdl[i].dl_addr + fwinfo->fwdl[i].dl_size))) + { + offset = fwinfo->fwdl[i].dl_offset + + (fwinfo->slut_addr - fwinfo->fwdl[i].dl_addr); + } + } + if (offset < 0) + { + return -1; + } + + ct.dlpriv = dlpriv; + ct.ioffset = offset; + ct.iread = readfn; + + if (read_uint(card, &ct, &magic, 2)) + { + return -1; + } + if (magic != SLUT_FINGERPRINT) + { + return -1; + } + + while (count < slut_len) + { + CsrUint32 id, obj; + + /* Read Symbol Id */ + if (read_uint(card, &ct, &id, 2)) + { + return -1; + } + + /* Check for end of table marker */ + if (id == CSR_SLT_END) + { + break; + } + + /* Read Symbol Value */ + if (read_uint(card, &ct, &obj, 4)) + { + return -1; + } + + slut[count].id = (CsrUint16)id; + slut[count].obj = obj; + count++; + } + + return count; +} /* read_slut() */ + + +/* + * --------------------------------------------------------------------------- + * xbv_to_patch + * + * Convert (the relevant parts of) a firmware xbv file into a patch xbv + * + * Arguments: + * card + * fw_buf - pointer to xbv firmware image + * fwinfo - structure describing the firmware image + * size - pointer to location into which size of f/w is written. + * + * Returns: + * Pointer to firmware image, or NULL on error. Caller must free this + * buffer via CsrMemFree() once it's finished with. + * + * Notes: + * The input fw_buf should have been checked via xbv1_parse prior to + * calling this function, so the input image is assumed valid. + * --------------------------------------------------------------------------- + */ +#define PTCH_LIST_SIZE 16 /* sizeof PTCH+FWID chunk in LIST header */ + +void* xbv_to_patch(card_t *card, fwreadfn_t readfn, + const void *fw_buf, const xbv1_t *fwinfo, CsrUint32 *size) +{ + void *patch_buf = NULL; + CsrUint32 patch_buf_size; + CsrUint32 payload_offs = 0; /* Start of XBV payload */ + CsrInt16 i; + CsrUint32 patch_offs = 0; + CsrUint32 list_len_offs = 0; /* Offset of PTDL LIST length parameter */ + CsrUint32 ptdl_start_offs = 0; /* Offset of first PTDL chunk */ + CsrUint32 fw_id; + void *rdbuf; + + if (!fw_buf || !fwinfo || !card) + { + return NULL; + } + + if (fwinfo->mode != xbv_firmware) + { + unifi_error(NULL, "Not a firmware file\n"); + return NULL; + } + + /* Pre-allocate read buffer for chunk conversion */ + rdbuf = CsrMemAlloc(PTDL_MAX_SIZE); + if (!rdbuf) + { + unifi_error(card, "Couldn't alloc conversion buffer\n"); + return NULL; + } + + /* Loader requires patch file's build ID to match the running firmware's */ + fw_id = card->build_id; + + /* Firmware XBV1 contains VERF, optional INFO, SLUT(s), FWDL(s) */ + /* Other chunks should get skipped. */ + /* VERF should be sanity-checked against chip version */ + + /* Patch XBV1 contains VERF, optional INFO, PTCH */ + /* PTCH contains FWID, optional INFO, PTDL(s), PTDL(start_vec) */ + /* Each FWDL is split into PTDLs (each is 1024 XAP words max) */ + /* Each PTDL contains running ROM f/w version, and checksum */ + /* MAC/PHY reset addresses (known) are added into a final PTDL */ + + /* The input image has already been parsed, and loaded into fwinfo, so we + * can use that to build the output image + */ + patch_buf_size = calc_patch_size(fwinfo); + + patch_buf = (void *)CsrMemAlloc(patch_buf_size); + if (!patch_buf) + { + CsrMemFree(rdbuf); + unifi_error(NULL, "Can't malloc buffer for patch conversion\n"); + return NULL; + } + + CsrMemSet(patch_buf, 0xdd, patch_buf_size); + + /* Write XBV + VERF headers */ + patch_offs += write_xbv_header(patch_buf, patch_offs, 0); + payload_offs = patch_offs; + + /* Write patch (LIST) header */ + list_len_offs = patch_offs + 4; /* Save LIST.length offset for later update */ + patch_offs += write_ptch_header(patch_buf, patch_offs, fw_id); + + /* Save start offset of the PTDL chunks */ + ptdl_start_offs = patch_offs; + + /* Write LIST of firmware PTDL blocks */ + for (i = 0; i < fwinfo->num_fwdl; i++) + { + patch_offs += write_fwdl_to_ptdl(patch_buf, + patch_offs, + readfn, + &fwinfo->fwdl[i], + fw_buf, + fw_id, + rdbuf); + } + + /* Write restart-vector PTDL last */ + patch_offs += write_reset_ptdl(patch_buf, patch_offs, fwinfo, fw_id); + + /* Now the length is known, update the LIST.length */ + write_uint32(patch_buf, list_len_offs, + (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE); + + /* Re write XBV headers just to fill in the correct file size */ + write_xbv_header(patch_buf, 0, (patch_offs - payload_offs)); + + unifi_trace(card->ospriv, UDBG1, "XBV:PTCH size %u, fw_id %u\n", + patch_offs, fw_id); + if (size) + { + *size = patch_offs; + } + CsrMemFree(rdbuf); + + return patch_buf; +} + + diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.h b/drivers/staging/csr/csr_wifi_hip_xbv.h new file mode 100644 index 000000000000..fdc4560676b8 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hip_xbv.h @@ -0,0 +1,127 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* + * --------------------------------------------------------------------------- + * FILE: csr_wifi_hip_xbv.h + * + * PURPOSE: + * Definitions and declarations for code to read XBV files - the UniFi + * firmware download file format. + * + * --------------------------------------------------------------------------- + */ +#ifndef __XBV_H__ +#define __XBV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_XBV_TEST +/* Driver includes */ +#include "csr_wifi_hip_unifi.h" +#endif + + +struct VMEQ +{ + CsrUint32 addr; + CsrUint16 mask; + CsrUint16 value; +}; + +struct VAND +{ + CsrUint32 first; + CsrUint32 count; +}; + +struct VERS +{ + CsrUint32 num_vand; +}; + +struct FWDL +{ + CsrUint32 dl_addr; + CsrUint32 dl_size; + CsrUint32 dl_offset; +}; + +struct FWOV +{ + CsrUint32 dl_size; + CsrUint32 dl_offset; +}; + +struct PTDL +{ + CsrUint32 dl_size; + CsrUint32 dl_offset; +}; + +#define MAX_VMEQ 64 +#define MAX_VAND 64 +#define MAX_FWDL 256 +#define MAX_PTDL 256 + +/* An XBV1 file can either contain firmware or patches (at the + * moment). The 'mode' member of the xbv1_t structure tells us which + * one is the case. */ +typedef enum +{ + xbv_unknown, + xbv_firmware, + xbv_patch +} xbv_mode; + +typedef struct +{ + xbv_mode mode; + + /* Parts of a Firmware XBV1 */ + + struct VMEQ vmeq[MAX_VMEQ]; + CsrUint32 num_vmeq; + struct VAND vand[MAX_VAND]; + struct VERS vers; + + CsrUint32 slut_addr; + + /* F/W download image, possibly more than one part */ + struct FWDL fwdl[MAX_FWDL]; + CsrInt16 num_fwdl; + + /* F/W overlay image, add r not used */ + struct FWOV fwov; + + /* Parts of a Patch XBV1 */ + + CsrUint32 build_id; + + struct PTDL ptdl[MAX_PTDL]; + CsrInt16 num_ptdl; +} xbv1_t; + + +typedef CsrInt32 (*fwreadfn_t)(void *ospriv, void *dlpriv, CsrUint32 offset, void *buf, CsrUint32 len); + +CsrResult xbv1_parse(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo); +CsrInt32 xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo, + symbol_t *slut, CsrUint32 slut_len); +void* xbv_to_patch(card_t *card, fwreadfn_t readfn, const void *fw_buf, const xbv1_t *fwinfo, + CsrUint32 *size); + +#ifdef __cplusplus +} +#endif + +#endif /* __XBV_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hostio_prim.h b/drivers/staging/csr/csr_wifi_hostio_prim.h new file mode 100644 index 000000000000..bf7c55c6e84b --- /dev/null +++ b/drivers/staging/csr/csr_wifi_hostio_prim.h @@ -0,0 +1,27 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + + +#ifndef CSR_WIFI_HOSTIO_H +#define CSR_WIFI_HOSTIO_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CSR_WIFI_HOSTIO_PRIM 0x0453 + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_HOSTIO_H */ + diff --git a/drivers/staging/csr/csr_wifi_lib.h b/drivers/staging/csr/csr_wifi_lib.h new file mode 100644 index 000000000000..4c691fc8fdfa --- /dev/null +++ b/drivers/staging/csr/csr_wifi_lib.h @@ -0,0 +1,113 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#ifndef CSR_WIFI_LIB_H__ +#define CSR_WIFI_LIB_H__ + +#include "csr_types.h" +#include "csr_wifi_fsm_event.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiFsmEventInit + * + * DESCRIPTION + * Macro to initialise the members of a CsrWifiFsmEvent. + *----------------------------------------------------------------------------*/ +#define CsrWifiFsmEventInit(evt, p_primtype, p_msgtype, p_dst, p_src) \ + (evt)->primtype = p_primtype; \ + (evt)->type = p_msgtype; \ + (evt)->destination = p_dst; \ + (evt)->source = p_src + + +/*----------------------------------------------------------------------------* + * CsrWifiEvent_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrWifiEvent + * + *----------------------------------------------------------------------------*/ +CsrWifiFsmEvent* CsrWifiEvent_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrSchedQid dst, CsrSchedQid src); + +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint8 value; +} CsrWifiEventCsrUint8; + +/*----------------------------------------------------------------------------* + * CsrWifiEventCsrUint8_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrWifiEventCsrUint8 + * + *----------------------------------------------------------------------------*/ +CsrWifiEventCsrUint8* CsrWifiEventCsrUint8_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrSchedQid dst, CsrSchedQid src, CsrUint8 value); + +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 value; +} CsrWifiEventCsrUint16; + +/*----------------------------------------------------------------------------* + * CsrWifiEventCsrUint16_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrWifiEventCsrUint16 + * + *----------------------------------------------------------------------------*/ +CsrWifiEventCsrUint16* CsrWifiEventCsrUint16_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrSchedQid dst, CsrSchedQid src, CsrUint16 value); + +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint32 value; +} CsrWifiEventCsrUint32; + +/*----------------------------------------------------------------------------* + * CsrWifiEventCsrUint32_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrWifiEventCsrUint32 + * + *----------------------------------------------------------------------------*/ +CsrWifiEventCsrUint32* CsrWifiEventCsrUint32_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrSchedQid dst, CsrSchedQid src, CsrUint32 value); + +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 value16; + CsrUint8 value8; +} CsrWifiEventCsrUint16CsrUint8; + +/*----------------------------------------------------------------------------* + * CsrWifiEventCsrUint16CsrUint8_struct + * + * DESCRIPTION + * Generic message creator. + * Allocates and fills in a message with the signature CsrWifiEventCsrUint16CsrUint8 + * + *----------------------------------------------------------------------------*/ +CsrWifiEventCsrUint16CsrUint8* CsrWifiEventCsrUint16CsrUint8_struct(CsrUint16 primtype, CsrUint16 msgtype, CsrSchedQid dst, CsrSchedQid src, CsrUint16 value16, CsrUint8 value8); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_msgconv.h b/drivers/staging/csr/csr_wifi_msgconv.h new file mode 100644 index 000000000000..d74e5953ad1c --- /dev/null +++ b/drivers/staging/csr/csr_wifi_msgconv.h @@ -0,0 +1,60 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_MSGCONV_H__ +#define CSR_WIFI_MSGCONV_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_unicode.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +void CsrUint16SerBigEndian(CsrUint8 *ptr, CsrSize *len, CsrUint16 v); +void CsrUint24SerBigEndian(CsrUint8 *ptr, CsrSize *len, CsrUint32 v); +void CsrUint32SerBigEndian(CsrUint8 *ptr, CsrSize *len, CsrUint32 v); + +void CsrUint16DesBigEndian(CsrUint16 *v, CsrUint8 *buffer, CsrSize *offset); +void CsrUint24DesBigEndian(CsrUint32 *v, CsrUint8 *buffer, CsrSize *offset); +void CsrUint32DesBigEndian(CsrUint32 *v, CsrUint8 *buffer, CsrSize *offset); + +void CsrUint24Ser(CsrUint8 *ptr, CsrSize *len, CsrUint32 v); +void CsrUint24Des(CsrUint32 *v, CsrUint8 *buffer, CsrSize *offset); + + +CsrSize CsrWifiEventSizeof(void *msg); +CsrUint8* CsrWifiEventSer(CsrUint8 *ptr, CsrSize *len, void *msg); +void* CsrWifiEventDes(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrWifiEventCsrUint8Sizeof(void *msg); +CsrUint8* CsrWifiEventCsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void* CsrWifiEventCsrUint8Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrWifiEventCsrUint16Sizeof(void *msg); +CsrUint8* CsrWifiEventCsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void* CsrWifiEventCsrUint16Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrWifiEventCsrUint32Sizeof(void *msg); +CsrUint8* CsrWifiEventCsrUint32Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void* CsrWifiEventCsrUint32Des(CsrUint8 *buffer, CsrSize length); + +CsrSize CsrWifiEventCsrUint16CsrUint8Sizeof(void *msg); +CsrUint8* CsrWifiEventCsrUint16CsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg); +void* CsrWifiEventCsrUint16CsrUint8Des(CsrUint8 *buffer, CsrSize length); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_MSGCONV_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h new file mode 100644 index 000000000000..4072c06a152d --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h @@ -0,0 +1,49 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_AP_CONVERTER_INIT_H__ +#define CSR_WIFI_NME_AP_CONVERTER_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_converter_init.h +#endif +#ifndef CSR_WIFI_AP_ENABLE +#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_converter_init.h +#endif + +#ifndef EXCLUDE_CSR_WIFI_NME_AP_MODULE + +#include "csr_msgconv.h" + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" + +extern const CsrLogPrimitiveInformation* CsrWifiNmeApTechInfoGet(void); +#endif /* CSR_LOG_ENABLE */ + +extern void CsrWifiNmeApConverterInit(void); + +#else /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */ + +#define CsrWifiNmeApConverterInit() + +#endif /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_AP_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_lib.h b/drivers/staging/csr/csr_wifi_nme_ap_lib.h new file mode 100644 index 000000000000..fc5692476ddc --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_lib.h @@ -0,0 +1,526 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_AP_LIB_H__ +#define CSR_WIFI_NME_AP_LIB_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_sched.h" +#include "csr_util.h" +#include "csr_msg_transport.h" + +#include "csr_wifi_lib.h" + +#include "csr_wifi_nme_ap_prim.h" +#include "csr_wifi_nme_task.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_lib.h +#endif +#ifndef CSR_WIFI_AP_ENABLE +#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_lib.h +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiNmeApFreeUpstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_NME_AP upstream message. Does not + * free the message itself, and can only be used for upstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_NME_AP upstream message + *----------------------------------------------------------------------------*/ +void CsrWifiNmeApFreeUpstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * CsrWifiNmeApFreeDownstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_NME_AP downstream message. Does not + * free the message itself, and can only be used for downstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_NME_AP downstream message + *----------------------------------------------------------------------------*/ +void CsrWifiNmeApFreeDownstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * Enum to string functions + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiNmeApPersCredentialTypeToString(CsrWifiNmeApPersCredentialType value); + + +/*----------------------------------------------------------------------------* + * CsrPrim Type toString function. + * Converts a message type to the String name of the Message + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiNmeApPrimTypeToString(CsrPrim msgType); + +/*----------------------------------------------------------------------------* + * Lookup arrays for PrimType name Strings + *----------------------------------------------------------------------------*/ +extern const CsrCharString *CsrWifiNmeApUpstreamPrimNames[CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT]; +extern const CsrCharString *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT]; + +/******************************************************************************* + + NAME + CsrWifiNmeApConfigSetReqSend + + DESCRIPTION + This primitive passes AP configuration info for NME. This can be sent at + any time but will be acted upon when the AP is started again. This + information is common to both P2P GO and AP + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + apConfig - AP configuration for the NME. + apMacConfig - MAC configuration to be acted on when + CSR_WIFI_NME_AP_START.request is sent. + +*******************************************************************************/ +#define CsrWifiNmeApConfigSetReqCreate(msg__, dst__, src__, apConfig__, apMacConfig__) \ + msg__ = (CsrWifiNmeApConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_CONFIG_SET_REQ, dst__, src__); \ + msg__->apConfig = (apConfig__); \ + msg__->apMacConfig = (apMacConfig__); + +#define CsrWifiNmeApConfigSetReqSendTo(dst__, src__, apConfig__, apMacConfig__) \ + { \ + CsrWifiNmeApConfigSetReq *msg__; \ + CsrWifiNmeApConfigSetReqCreate(msg__, dst__, src__, apConfig__, apMacConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApConfigSetReqSend(src__, apConfig__, apMacConfig__) \ + CsrWifiNmeApConfigSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, apConfig__, apMacConfig__) + +/******************************************************************************* + + NAME + CsrWifiNmeApConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiNmeApConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeApConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeApConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeApConfigSetCfm *msg__; \ + CsrWifiNmeApConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApConfigSetCfmSend(dst__, status__) \ + CsrWifiNmeApConfigSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStaRemoveReqSend + + DESCRIPTION + This primitive disconnects a connected station. If keepBlocking is set to + TRUE, the station with the specified MAC address is not allowed to + connect. If the requested station is not already connected,it may be + blocked based on keepBlocking parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + staMacAddress - Mac Address of the station to be disconnected or blocked + keepBlocking - If TRUE, the station is blocked. If FALSE and the station is + connected, disconnect the station. If FALSE and the station + is not connected, no action is taken. + +*******************************************************************************/ +#define CsrWifiNmeApStaRemoveReqCreate(msg__, dst__, src__, interfaceTag__, staMacAddress__, keepBlocking__) \ + msg__ = (CsrWifiNmeApStaRemoveReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApStaRemoveReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STA_REMOVE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->staMacAddress = (staMacAddress__); \ + msg__->keepBlocking = (keepBlocking__); + +#define CsrWifiNmeApStaRemoveReqSendTo(dst__, src__, interfaceTag__, staMacAddress__, keepBlocking__) \ + { \ + CsrWifiNmeApStaRemoveReq *msg__; \ + CsrWifiNmeApStaRemoveReqCreate(msg__, dst__, src__, interfaceTag__, staMacAddress__, keepBlocking__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStaRemoveReqSend(src__, interfaceTag__, staMacAddress__, keepBlocking__) \ + CsrWifiNmeApStaRemoveReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, staMacAddress__, keepBlocking__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStartReqSend + + DESCRIPTION + This primitive requests NME to started the AP operation. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface identifier; unique identifier of an interface + apType - AP Type specifies the Legacy AP or P2P GO operation + cloakSsid - Indicates whether the SSID should be cloaked (hidden and + not broadcast in beacon) or not + ssid - Service Set Identifier + ifIndex - Radio interface + channel - Channel number of the channel to use + apCredentials - Security credential configuration. + maxConnections - Maximum number of stations/P2P clients allowed + p2pGoParam - P2P specific GO parameters. + NOT USED FOR CURRENT RELEASE + wpsEnabled - Indicates whether WPS should be enabled or not + +*******************************************************************************/ +#define CsrWifiNmeApStartReqCreate(msg__, dst__, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) \ + msg__ = (CsrWifiNmeApStartReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApStartReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_START_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->apType = (apType__); \ + msg__->cloakSsid = (cloakSsid__); \ + msg__->ssid = (ssid__); \ + msg__->ifIndex = (ifIndex__); \ + msg__->channel = (channel__); \ + msg__->apCredentials = (apCredentials__); \ + msg__->maxConnections = (maxConnections__); \ + msg__->p2pGoParam = (p2pGoParam__); \ + msg__->wpsEnabled = (wpsEnabled__); + +#define CsrWifiNmeApStartReqSendTo(dst__, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) \ + { \ + CsrWifiNmeApStartReq *msg__; \ + CsrWifiNmeApStartReqCreate(msg__, dst__, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStartReqSend(src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) \ + CsrWifiNmeApStartReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStartCfmSend + + DESCRIPTION + This primitive reports the result of CSR_WIFI_NME_AP_START.request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface identifier; unique identifier of an interface + status - Status of the request. + ssid - Service Set Identifier + +*******************************************************************************/ +#define CsrWifiNmeApStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ssid__) \ + msg__ = (CsrWifiNmeApStartCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApStartCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_START_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->ssid = (ssid__); + +#define CsrWifiNmeApStartCfmSendTo(dst__, src__, interfaceTag__, status__, ssid__) \ + { \ + CsrWifiNmeApStartCfm *msg__; \ + CsrWifiNmeApStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ssid__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStartCfmSend(dst__, interfaceTag__, status__, ssid__) \ + CsrWifiNmeApStartCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, ssid__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStationIndSend + + DESCRIPTION + This primitive indicates that a station has joined or a previously joined + station has left the BSS/group + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + mediaStatus - Indicates whether the station is connected or + disconnected + peerMacAddress - MAC address of the station + peerDeviceAddress - P2P Device Address + +*******************************************************************************/ +#define CsrWifiNmeApStationIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) \ + msg__ = (CsrWifiNmeApStationInd *) CsrPmemAlloc(sizeof(CsrWifiNmeApStationInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STATION_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->mediaStatus = (mediaStatus__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->peerDeviceAddress = (peerDeviceAddress__); + +#define CsrWifiNmeApStationIndSendTo(dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) \ + { \ + CsrWifiNmeApStationInd *msg__; \ + CsrWifiNmeApStationIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStationIndSend(dst__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) \ + CsrWifiNmeApStationIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStopReqSend + + DESCRIPTION + This primitive requests NME to stop the AP operation. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiNmeApStopReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiNmeApStopReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApStopReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STOP_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiNmeApStopReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiNmeApStopReq *msg__; \ + CsrWifiNmeApStopReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStopReqSend(src__, interfaceTag__) \ + CsrWifiNmeApStopReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStopIndSend + + DESCRIPTION + Indicates that AP operation had stopped because of some unrecoverable + error after AP operation was started successfully. NME sends this signal + after failing to restart the AP operation internally following an error + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + apType - Reports AP Type (P2PGO or AP) + status - Error Status + +*******************************************************************************/ +#define CsrWifiNmeApStopIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__) \ + msg__ = (CsrWifiNmeApStopInd *) CsrPmemAlloc(sizeof(CsrWifiNmeApStopInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STOP_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->apType = (apType__); \ + msg__->status = (status__); + +#define CsrWifiNmeApStopIndSendTo(dst__, src__, interfaceTag__, apType__, status__) \ + { \ + CsrWifiNmeApStopInd *msg__; \ + CsrWifiNmeApStopIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStopIndSend(dst__, interfaceTag__, apType__, status__) \ + CsrWifiNmeApStopIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, apType__, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeApStopCfmSend + + DESCRIPTION + This primitive confirms that the AP operation is stopped. NME shall send + this primitive in response to the request even if AP operation has + already been stopped + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface identifier; unique identifier of an interface + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiNmeApStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiNmeApStopCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApStopCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STOP_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiNmeApStopCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiNmeApStopCfm *msg__; \ + CsrWifiNmeApStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApStopCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiNmeApStopCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeApWmmParamUpdateReqSend + + DESCRIPTION + Application uses this primitive to update the WMM parameters + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + wmmApParams - WMM Access point parameters per access category. The array + index corresponds to the ACI + wmmApBcParams - WMM station parameters per access category to be advertised + in the beacons and probe response The array index + corresponds to the ACI + +*******************************************************************************/ +#define CsrWifiNmeApWmmParamUpdateReqCreate(msg__, dst__, src__, wmmApParams__, wmmApBcParams__) \ + msg__ = (CsrWifiNmeApWmmParamUpdateReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApWmmParamUpdateReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_REQ, dst__, src__); \ + CsrMemCpy(msg__->wmmApParams, (wmmApParams__), sizeof(CsrWifiSmeWmmAcParams) * 4); \ + CsrMemCpy(msg__->wmmApBcParams, (wmmApBcParams__), sizeof(CsrWifiSmeWmmAcParams) * 4); + +#define CsrWifiNmeApWmmParamUpdateReqSendTo(dst__, src__, wmmApParams__, wmmApBcParams__) \ + { \ + CsrWifiNmeApWmmParamUpdateReq *msg__; \ + CsrWifiNmeApWmmParamUpdateReqCreate(msg__, dst__, src__, wmmApParams__, wmmApBcParams__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApWmmParamUpdateReqSend(src__, wmmApParams__, wmmApBcParams__) \ + CsrWifiNmeApWmmParamUpdateReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, wmmApParams__, wmmApBcParams__) + +/******************************************************************************* + + NAME + CsrWifiNmeApWmmParamUpdateCfmSend + + DESCRIPTION + A confirm for for the WMM parameters update + + PARAMETERS + queue - Destination Task Queue + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiNmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeApWmmParamUpdateCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApWmmParamUpdateCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeApWmmParamUpdateCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeApWmmParamUpdateCfm *msg__; \ + CsrWifiNmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApWmmParamUpdateCfmSend(dst__, status__) \ + CsrWifiNmeApWmmParamUpdateCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeApWpsRegisterReqSend + + DESCRIPTION + This primitive allows the NME to accept the WPS registration from an + enrollee. Such registration procedure can be cancelled by sending + CSR_WIFI_NME_WPS_CANCEL.request. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an + interface + selectedDevicePasswordId - Selected password type + selectedConfigMethod - Selected WPS configuration method type + pin - PIN value. + Relevant if selected device password ID is PIN.4 + digit pin is passed by sending the pin digits in + pin[0]..pin[3] and rest of the contents filled + with '-'. + +*******************************************************************************/ +#define CsrWifiNmeApWpsRegisterReqCreate(msg__, dst__, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) \ + msg__ = (CsrWifiNmeApWpsRegisterReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApWpsRegisterReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WPS_REGISTER_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->selectedDevicePasswordId = (selectedDevicePasswordId__); \ + msg__->selectedConfigMethod = (selectedConfigMethod__); \ + CsrMemCpy(msg__->pin, (pin__), sizeof(CsrUint8) * 8); + +#define CsrWifiNmeApWpsRegisterReqSendTo(dst__, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) \ + { \ + CsrWifiNmeApWpsRegisterReq *msg__; \ + CsrWifiNmeApWpsRegisterReqCreate(msg__, dst__, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApWpsRegisterReqSend(src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) \ + CsrWifiNmeApWpsRegisterReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) + +/******************************************************************************* + + NAME + CsrWifiNmeApWpsRegisterCfmSend + + DESCRIPTION + This primitive reports the result of WPS procedure. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface identifier; unique identifier of an interface + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiNmeApWpsRegisterCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiNmeApWpsRegisterCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApWpsRegisterCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WPS_REGISTER_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiNmeApWpsRegisterCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiNmeApWpsRegisterCfm *msg__; \ + CsrWifiNmeApWpsRegisterCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \ + } + +#define CsrWifiNmeApWpsRegisterCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiNmeApWpsRegisterCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__) + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_AP_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_prim.h b/drivers/staging/csr/csr_wifi_nme_ap_prim.h new file mode 100644 index 000000000000..e3b56b4b44e3 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_prim.h @@ -0,0 +1,504 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_AP_PRIM_H__ +#define CSR_WIFI_NME_AP_PRIM_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_wifi_common.h" +#include "csr_result.h" +#include "csr_wifi_fsm_event.h" +#include "csr_wifi_sme_ap_prim.h" +#include "csr_wifi_nme_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_prim.h +#endif +#ifndef CSR_WIFI_AP_ENABLE +#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_prim.h +#endif + +#define CSR_WIFI_NME_AP_PRIM (0x0426) + +typedef CsrPrim CsrWifiNmeApPrim; + + +/******************************************************************************* + + NAME + CsrWifiNmeApPersCredentialType + + DESCRIPTION + NME Credential Types + + VALUES + CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK + - Use PSK as credential. + CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE + - Use the specified passphrase as credential + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeApPersCredentialType; +#define CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK ((CsrWifiNmeApPersCredentialType) 0x00) +#define CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE ((CsrWifiNmeApPersCredentialType) 0x01) + + +/******************************************************************************* + + NAME + CsrWifiNmeApConfig + + DESCRIPTION + Structure holding AP config data. + + MEMBERS + apGroupkeyTimeout - Access point group key timeout. + apStrictGtkRekey - Access point strict GTK rekey flag. If set TRUE, the AP + shall rekey GTK every time a connected STA leaves BSS. + apGmkTimeout - Access point GMK timeout + apResponseTimeout - Response timeout + apRetransLimit - Max allowed retransmissions + +*******************************************************************************/ +typedef struct +{ + CsrUint16 apGroupkeyTimeout; + CsrBool apStrictGtkRekey; + CsrUint16 apGmkTimeout; + CsrUint16 apResponseTimeout; + CsrUint8 apRetransLimit; +} CsrWifiNmeApConfig; + +/******************************************************************************* + + NAME + CsrWifiNmeApAuthPers + + DESCRIPTION + + MEMBERS + authSupport - Credential type value (as defined in the + enumeration type). + rsnCapabilities - RSN capabilities mask + wapiCapabilities - WAPI capabilities mask + pskOrPassphrase - Credential type value (as defined in the + enumeration type). + authPers_credentials - Union containing credentials which depends + on credentialType parameter. + authPers_credentialspsk - + authPers_credentialspassphrase - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeApAuthSupportMask authSupport; + CsrWifiSmeApRsnCapabilitiesMask rsnCapabilities; + CsrWifiSmeApWapiCapabilitiesMask wapiCapabilities; + CsrWifiNmeApPersCredentialType pskOrPassphrase; + union { + CsrWifiNmePsk psk; + CsrWifiNmePassphrase passphrase; + } authPers_credentials; +} CsrWifiNmeApAuthPers; + +/******************************************************************************* + + NAME + CsrWifiNmeApCredentials + + DESCRIPTION + Structure containing the Credentials data. + + MEMBERS + authType - Authentication type + nmeAuthType - Authentication parameters + nmeAuthTypeopenSystemEmpty - + nmeAuthTypeauthwep - + nmeAuthTypeauthTypePersonal - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeApAuthType authType; + union { + CsrWifiSmeEmpty openSystemEmpty; + CsrWifiSmeWepAuth authwep; + CsrWifiNmeApAuthPers authTypePersonal; + } nmeAuthType; +} CsrWifiNmeApCredentials; + + +/* Downstream */ +#define CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST (0x0000) + +#define CSR_WIFI_NME_AP_CONFIG_SET_REQ ((CsrWifiNmeApPrim) (0x0000 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_WPS_REGISTER_REQ ((CsrWifiNmeApPrim) (0x0001 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_START_REQ ((CsrWifiNmeApPrim) (0x0002 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_STOP_REQ ((CsrWifiNmeApPrim) (0x0003 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_REQ ((CsrWifiNmeApPrim) (0x0004 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_STA_REMOVE_REQ ((CsrWifiNmeApPrim) (0x0005 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)) + + +#define CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0005 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST) + +/* Upstream */ +#define CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) + +#define CSR_WIFI_NME_AP_CONFIG_SET_CFM ((CsrWifiNmeApPrim)(0x0000 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_WPS_REGISTER_CFM ((CsrWifiNmeApPrim)(0x0001 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_START_CFM ((CsrWifiNmeApPrim)(0x0002 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_STOP_CFM ((CsrWifiNmeApPrim)(0x0003 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_STOP_IND ((CsrWifiNmeApPrim)(0x0004 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_CFM ((CsrWifiNmeApPrim)(0x0005 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_AP_STATION_IND ((CsrWifiNmeApPrim)(0x0006 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)) + +#define CSR_WIFI_NME_AP_PRIM_UPSTREAM_HIGHEST (0x0006 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST) + +#define CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT (CSR_WIFI_NME_AP_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST) + +/******************************************************************************* + + NAME + CsrWifiNmeApConfigSetReq + + DESCRIPTION + This primitive passes AP configuration info for NME. This can be sent at + any time but will be acted upon when the AP is started again. This + information is common to both P2P GO and AP + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + apConfig - AP configuration for the NME. + apMacConfig - MAC configuration to be acted on when + CSR_WIFI_NME_AP_START.request is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiNmeApConfig apConfig; + CsrWifiSmeApMacConfig apMacConfig; +} CsrWifiNmeApConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiNmeApWpsRegisterReq + + DESCRIPTION + This primitive allows the NME to accept the WPS registration from an + enrollee. Such registration procedure can be cancelled by sending + CSR_WIFI_NME_WPS_CANCEL.request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an + interface + selectedDevicePasswordId - Selected password type + selectedConfigMethod - Selected WPS configuration method type + pin - PIN value. + Relevant if selected device password ID is PIN.4 + digit pin is passed by sending the pin digits in + pin[0]..pin[3] and rest of the contents filled + with '-'. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeWpsDpid selectedDevicePasswordId; + CsrWifiSmeWpsConfigType selectedConfigMethod; + CsrUint8 pin[8]; +} CsrWifiNmeApWpsRegisterReq; + +/******************************************************************************* + + NAME + CsrWifiNmeApStartReq + + DESCRIPTION + This primitive requests NME to started the AP operation. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface identifier; unique identifier of an interface + apType - AP Type specifies the Legacy AP or P2P GO operation + cloakSsid - Indicates whether the SSID should be cloaked (hidden and + not broadcast in beacon) or not + ssid - Service Set Identifier + ifIndex - Radio interface + channel - Channel number of the channel to use + apCredentials - Security credential configuration. + maxConnections - Maximum number of stations/P2P clients allowed + p2pGoParam - P2P specific GO parameters. + NOT USED FOR CURRENT RELEASE + wpsEnabled - Indicates whether WPS should be enabled or not + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeApType apType; + CsrBool cloakSsid; + CsrWifiSsid ssid; + CsrWifiSmeRadioIF ifIndex; + CsrUint8 channel; + CsrWifiNmeApCredentials apCredentials; + CsrUint8 maxConnections; + CsrWifiSmeApP2pGoConfig p2pGoParam; + CsrBool wpsEnabled; +} CsrWifiNmeApStartReq; + +/******************************************************************************* + + NAME + CsrWifiNmeApStopReq + + DESCRIPTION + This primitive requests NME to stop the AP operation. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiNmeApStopReq; + +/******************************************************************************* + + NAME + CsrWifiNmeApWmmParamUpdateReq + + DESCRIPTION + Application uses this primitive to update the WMM parameters + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + wmmApParams - WMM Access point parameters per access category. The array + index corresponds to the ACI + wmmApBcParams - WMM station parameters per access category to be advertised + in the beacons and probe response The array index + corresponds to the ACI + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeWmmAcParams wmmApParams[4]; + CsrWifiSmeWmmAcParams wmmApBcParams[4]; +} CsrWifiNmeApWmmParamUpdateReq; + +/******************************************************************************* + + NAME + CsrWifiNmeApStaRemoveReq + + DESCRIPTION + This primitive disconnects a connected station. If keepBlocking is set to + TRUE, the station with the specified MAC address is not allowed to + connect. If the requested station is not already connected,it may be + blocked based on keepBlocking parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + staMacAddress - Mac Address of the station to be disconnected or blocked + keepBlocking - If TRUE, the station is blocked. If FALSE and the station is + connected, disconnect the station. If FALSE and the station + is not connected, no action is taken. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiMacAddress staMacAddress; + CsrBool keepBlocking; +} CsrWifiNmeApStaRemoveReq; + +/******************************************************************************* + + NAME + CsrWifiNmeApConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeApConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeApWpsRegisterCfm + + DESCRIPTION + This primitive reports the result of WPS procedure. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface identifier; unique identifier of an interface + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiNmeApWpsRegisterCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeApStartCfm + + DESCRIPTION + This primitive reports the result of CSR_WIFI_NME_AP_START.request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface identifier; unique identifier of an interface + status - Status of the request. + ssid - Service Set Identifier + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSsid ssid; +} CsrWifiNmeApStartCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeApStopCfm + + DESCRIPTION + This primitive confirms that the AP operation is stopped. NME shall send + this primitive in response to the request even if AP operation has + already been stopped + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface identifier; unique identifier of an interface + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiNmeApStopCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeApStopInd + + DESCRIPTION + Indicates that AP operation had stopped because of some unrecoverable + error after AP operation was started successfully. NME sends this signal + after failing to restart the AP operation internally following an error + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + apType - Reports AP Type (P2PGO or AP) + status - Error Status + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeApType apType; + CsrResult status; +} CsrWifiNmeApStopInd; + +/******************************************************************************* + + NAME + CsrWifiNmeApWmmParamUpdateCfm + + DESCRIPTION + A confirm for for the WMM parameters update + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeApWmmParamUpdateCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeApStationInd + + DESCRIPTION + This primitive indicates that a station has joined or a previously joined + station has left the BSS/group + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + mediaStatus - Indicates whether the station is connected or + disconnected + peerMacAddress - MAC address of the station + peerDeviceAddress - P2P Device Address + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeMediaStatus mediaStatus; + CsrWifiMacAddress peerMacAddress; + CsrWifiMacAddress peerDeviceAddress; +} CsrWifiNmeApStationInd; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_AP_PRIM_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_nme_ap_sef.c b/drivers/staging/csr/csr_wifi_nme_ap_sef.c new file mode 100644 index 000000000000..e048848883d5 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_sef.c @@ -0,0 +1,30 @@ +/***************************************************************************** + + FILE: csr_wifi_nme_sef.c + + (c) Cambridge Silicon Radio Limited 2010 + + Refer to LICENSE.txt included with this source for details + on the license terms. + + *****************************************************************************/ +#include "csr_wifi_nme_ap_sef.h" +#include "unifi_priv.h" + +void CsrWifiNmeApUpstreamStateHandlers(void* drvpriv, CsrWifiFsmEvent* msg) +{ + switch(msg->type) { + case CSR_WIFI_NME_AP_START_CFM: + CsrWifiNmeApStartCfmHandler(drvpriv, msg); + break; + case CSR_WIFI_NME_AP_STOP_CFM: + CsrWifiNmeApStopCfmHandler(drvpriv, msg); + break; + case CSR_WIFI_NME_AP_CONFIG_SET_CFM: + CsrWifiNmeApConfigSetCfmHandler(drvpriv,msg); + break; + default: + unifi_error(drvpriv, "CsrWifiNmeApUpstreamStateHandlers: unhandled NME_AP message type 0x%.4X\n",msg->type); + break; + } +} diff --git a/drivers/staging/csr/csr_wifi_nme_ap_sef.h b/drivers/staging/csr/csr_wifi_nme_ap_sef.h new file mode 100644 index 000000000000..3f353633fa5e --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_sef.h @@ -0,0 +1,31 @@ +/***************************************************************************** + FILE: csr_wifi_nme_sef.h + (c) Cambridge Silicon Radio Limited 2010 + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__ +#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__ + +#include "csr_wifi_nme_prim.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void CsrWifiNmeApUpstreamStateHandlers(void* drvpriv, CsrWifiFsmEvent* msg); + + +extern void CsrWifiNmeApConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiNmeApStartCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiNmeApStopCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_serialize.h b/drivers/staging/csr/csr_wifi_nme_ap_serialize.h new file mode 100644 index 000000000000..d59abf981cde --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_serialize.h @@ -0,0 +1,105 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_AP_SERIALIZE_H__ +#define CSR_WIFI_NME_AP_SERIALIZE_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_wifi_msgconv.h" + +#include "csr_wifi_nme_ap_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_serialize.h +#endif +#ifndef CSR_WIFI_AP_ENABLE +#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_serialize.h +#endif + +extern void CsrWifiNmeApPfree(void *ptr); + +extern CsrUint8* CsrWifiNmeApConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApConfigSetReqSizeof(void *msg); +extern void CsrWifiNmeApConfigSetReqSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeApWpsRegisterReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApWpsRegisterReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApWpsRegisterReqSizeof(void *msg); +#define CsrWifiNmeApWpsRegisterReqSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApStartReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApStartReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApStartReqSizeof(void *msg); +extern void CsrWifiNmeApStartReqSerFree(void *msg); + +#define CsrWifiNmeApStopReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeApStopReqDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeApStopReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeApStopReqSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApWmmParamUpdateReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApWmmParamUpdateReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApWmmParamUpdateReqSizeof(void *msg); +#define CsrWifiNmeApWmmParamUpdateReqSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApStaRemoveReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApStaRemoveReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApStaRemoveReqSizeof(void *msg); +#define CsrWifiNmeApStaRemoveReqSerFree CsrWifiNmeApPfree + +#define CsrWifiNmeApConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeApConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeApConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeApConfigSetCfmSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApWpsRegisterCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApWpsRegisterCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApWpsRegisterCfmSizeof(void *msg); +#define CsrWifiNmeApWpsRegisterCfmSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApStartCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApStartCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApStartCfmSizeof(void *msg); +#define CsrWifiNmeApStartCfmSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApStopCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApStopCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApStopCfmSizeof(void *msg); +#define CsrWifiNmeApStopCfmSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApStopIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApStopIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApStopIndSizeof(void *msg); +#define CsrWifiNmeApStopIndSerFree CsrWifiNmeApPfree + +#define CsrWifiNmeApWmmParamUpdateCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeApWmmParamUpdateCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeApWmmParamUpdateCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeApWmmParamUpdateCfmSerFree CsrWifiNmeApPfree + +extern CsrUint8* CsrWifiNmeApStationIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeApStationIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeApStationIndSizeof(void *msg); +#define CsrWifiNmeApStationIndSerFree CsrWifiNmeApPfree + + +#ifdef __cplusplus +} +#endif +#endif /* CSR_WIFI_NME_AP_SERIALIZE_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_nme_converter_init.h b/drivers/staging/csr/csr_wifi_nme_converter_init.h new file mode 100644 index 000000000000..6661914fb403 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_converter_init.h @@ -0,0 +1,46 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_CONVERTER_INIT_H__ +#define CSR_WIFI_NME_CONVERTER_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_converter_init.h +#endif + +#ifndef EXCLUDE_CSR_WIFI_NME_MODULE + +#include "csr_msgconv.h" + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" + +extern const CsrLogPrimitiveInformation* CsrWifiNmeTechInfoGet(void); +#endif /* CSR_LOG_ENABLE */ + +extern void CsrWifiNmeConverterInit(void); + +#else /* EXCLUDE_CSR_WIFI_NME_MODULE */ + +#define CsrWifiNmeConverterInit() + +#endif /* EXCLUDE_CSR_WIFI_NME_MODULE */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_lib.h b/drivers/staging/csr/csr_wifi_nme_lib.h new file mode 100644 index 000000000000..897afbf14666 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_lib.h @@ -0,0 +1,1056 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_LIB_H__ +#define CSR_WIFI_NME_LIB_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_sched.h" +#include "csr_util.h" +#include "csr_msg_transport.h" + +#include "csr_wifi_lib.h" + +#include "csr_wifi_nme_prim.h" +#include "csr_wifi_nme_task.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_lib.h +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiNmeFreeUpstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_NME upstream message. Does not + * free the message itself, and can only be used for upstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_NME upstream message + *----------------------------------------------------------------------------*/ +void CsrWifiNmeFreeUpstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * CsrWifiNmeFreeDownstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_NME downstream message. Does not + * free the message itself, and can only be used for downstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_NME downstream message + *----------------------------------------------------------------------------*/ +void CsrWifiNmeFreeDownstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * Enum to string functions + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiNmeAuthModeToString(CsrWifiNmeAuthMode value); +const CsrCharString* CsrWifiNmeBssTypeToString(CsrWifiNmeBssType value); +const CsrCharString* CsrWifiNmeCcxOptionsMaskToString(CsrWifiNmeCcxOptionsMask value); +const CsrCharString* CsrWifiNmeConfigActionToString(CsrWifiNmeConfigAction value); +const CsrCharString* CsrWifiNmeConnectionStatusToString(CsrWifiNmeConnectionStatus value); +const CsrCharString* CsrWifiNmeCredentialTypeToString(CsrWifiNmeCredentialType value); +const CsrCharString* CsrWifiNmeEapMethodToString(CsrWifiNmeEapMethod value); +const CsrCharString* CsrWifiNmeEncryptionToString(CsrWifiNmeEncryption value); +const CsrCharString* CsrWifiNmeIndicationsToString(CsrWifiNmeIndications value); +const CsrCharString* CsrWifiNmeSecErrorToString(CsrWifiNmeSecError value); +const CsrCharString* CsrWifiNmeSimCardTypeToString(CsrWifiNmeSimCardType value); +const CsrCharString* CsrWifiNmeUmtsAuthResultToString(CsrWifiNmeUmtsAuthResult value); +const CsrCharString* CsrWifiNmeWmmQosInfoToString(CsrWifiNmeWmmQosInfo value); + + +/*----------------------------------------------------------------------------* + * CsrPrim Type toString function. + * Converts a message type to the String name of the Message + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiNmePrimTypeToString(CsrPrim msgType); + +/*----------------------------------------------------------------------------* + * Lookup arrays for PrimType name Strings + *----------------------------------------------------------------------------*/ +extern const CsrCharString *CsrWifiNmeUpstreamPrimNames[CSR_WIFI_NME_PRIM_UPSTREAM_COUNT]; +extern const CsrCharString *CsrWifiNmeDownstreamPrimNames[CSR_WIFI_NME_PRIM_DOWNSTREAM_COUNT]; + +/******************************************************************************* + + NAME + CsrWifiNmeConnectionStatusGetReqSend + + DESCRIPTION + Requests the current connection status of the NME. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiNmeConnectionStatusGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiNmeConnectionStatusGetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeConnectionStatusGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_CONNECTION_STATUS_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiNmeConnectionStatusGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiNmeConnectionStatusGetReq *msg__; \ + CsrWifiNmeConnectionStatusGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeConnectionStatusGetReqSend(src__, interfaceTag__) \ + CsrWifiNmeConnectionStatusGetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiNmeConnectionStatusGetCfmSend + + DESCRIPTION + Reports the connection status of the NME. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Indicates the success or otherwise of the requested + operation. + connectionStatus - NME current connection status + +*******************************************************************************/ +#define CsrWifiNmeConnectionStatusGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStatus__) \ + msg__ = (CsrWifiNmeConnectionStatusGetCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeConnectionStatusGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_CONNECTION_STATUS_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->connectionStatus = (connectionStatus__); + +#define CsrWifiNmeConnectionStatusGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionStatus__) \ + { \ + CsrWifiNmeConnectionStatusGetCfm *msg__; \ + CsrWifiNmeConnectionStatusGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStatus__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeConnectionStatusGetCfmSend(dst__, interfaceTag__, status__, connectionStatus__) \ + CsrWifiNmeConnectionStatusGetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, connectionStatus__) + +/******************************************************************************* + + NAME + CsrWifiNmeEventMaskSetReqSend + + DESCRIPTION + The wireless manager application may register with the NME to receive + notification of interesting events. Indications will be sent only if the + wireless manager explicitly registers to be notified of that event. + indMask is a bit mask of values defined in CsrWifiNmeIndicationsMask. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + indMask - Set mask with values from CsrWifiNmeIndications + +*******************************************************************************/ +#define CsrWifiNmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__) \ + msg__ = (CsrWifiNmeEventMaskSetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeEventMaskSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_EVENT_MASK_SET_REQ, dst__, src__); \ + msg__->indMask = (indMask__); + +#define CsrWifiNmeEventMaskSetReqSendTo(dst__, src__, indMask__) \ + { \ + CsrWifiNmeEventMaskSetReq *msg__; \ + CsrWifiNmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeEventMaskSetReqSend(src__, indMask__) \ + CsrWifiNmeEventMaskSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, indMask__) + +/******************************************************************************* + + NAME + CsrWifiNmeEventMaskSetCfmSend + + DESCRIPTION + The NME calls the primitive to report the result of the request + primitive. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiNmeEventMaskSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeEventMaskSetCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeEventMaskSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_EVENT_MASK_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeEventMaskSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeEventMaskSetCfm *msg__; \ + CsrWifiNmeEventMaskSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeEventMaskSetCfmSend(dst__, status__) \ + CsrWifiNmeEventMaskSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileConnectReqSend + + DESCRIPTION + Requests the NME to attempt to connect to the specified profile. + Overrides any current connection attempt. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + profileIdentity - Identity (BSSID, SSID) of profile to be connected to. + It must match an existing profile in the NME. + +*******************************************************************************/ +#define CsrWifiNmeProfileConnectReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentity__) \ + msg__ = (CsrWifiNmeProfileConnectReq *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileConnectReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_CONNECT_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->profileIdentity = (profileIdentity__); + +#define CsrWifiNmeProfileConnectReqSendTo(dst__, src__, interfaceTag__, profileIdentity__) \ + { \ + CsrWifiNmeProfileConnectReq *msg__; \ + CsrWifiNmeProfileConnectReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentity__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileConnectReqSend(src__, interfaceTag__, profileIdentity__) \ + CsrWifiNmeProfileConnectReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, profileIdentity__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileConnectCfmSend + + DESCRIPTION + Reports the status of the NME PROFILE CONNECT REQ. If unsuccessful the + connectAttempt parameters contain details of the APs that the NME + attempted to connect to before reporting the failure of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an + interface + status - Indicates the success or otherwise of the requested + operation. + connectAttemptsCount - This parameter is relevant only if + status!=CSR_WIFI_NME_STATUS_SUCCESS. + Number of connection attempt elements provided with + this primitive + connectAttempts - This parameter is relevant only if + status!=CSR_WIFI_NME_STATUS_SUCCESS. + Points to the list of connection attempt elements + provided with this primitive + Each element of the list provides information about + an AP on which the connection attempt was made and + the error that occurred during the attempt. + +*******************************************************************************/ +#define CsrWifiNmeProfileConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) \ + msg__ = (CsrWifiNmeProfileConnectCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileConnectCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_CONNECT_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->connectAttemptsCount = (connectAttemptsCount__); \ + msg__->connectAttempts = (connectAttempts__); + +#define CsrWifiNmeProfileConnectCfmSendTo(dst__, src__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) \ + { \ + CsrWifiNmeProfileConnectCfm *msg__; \ + CsrWifiNmeProfileConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileConnectCfmSend(dst__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) \ + CsrWifiNmeProfileConnectCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteAllReqSend + + DESCRIPTION + Deletes all profiles present in the NME, but does NOT modify the + preferred profile list. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiNmeProfileDeleteAllReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiNmeProfileDeleteAllReq *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileDeleteAllReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ, dst__, src__); + +#define CsrWifiNmeProfileDeleteAllReqSendTo(dst__, src__) \ + { \ + CsrWifiNmeProfileDeleteAllReq *msg__; \ + CsrWifiNmeProfileDeleteAllReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileDeleteAllReqSend(src__) \ + CsrWifiNmeProfileDeleteAllReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteAllCfmSend + + DESCRIPTION + Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ. + Returns always CSR_WIFI_NME_STATUS_SUCCESS. + + PARAMETERS + queue - Destination Task Queue + status - Indicates the success or otherwise of the requested operation, but + in this case it always set to success. + +*******************************************************************************/ +#define CsrWifiNmeProfileDeleteAllCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeProfileDeleteAllCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileDeleteAllCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_ALL_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeProfileDeleteAllCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeProfileDeleteAllCfm *msg__; \ + CsrWifiNmeProfileDeleteAllCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileDeleteAllCfmSend(dst__, status__) \ + CsrWifiNmeProfileDeleteAllCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteReqSend + + DESCRIPTION + Will delete the profile with a matching identity, but does NOT modify the + preferred profile list. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + profileIdentity - Identity (BSSID, SSID) of profile to be deleted. + +*******************************************************************************/ +#define CsrWifiNmeProfileDeleteReqCreate(msg__, dst__, src__, profileIdentity__) \ + msg__ = (CsrWifiNmeProfileDeleteReq *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileDeleteReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_REQ, dst__, src__); \ + msg__->profileIdentity = (profileIdentity__); + +#define CsrWifiNmeProfileDeleteReqSendTo(dst__, src__, profileIdentity__) \ + { \ + CsrWifiNmeProfileDeleteReq *msg__; \ + CsrWifiNmeProfileDeleteReqCreate(msg__, dst__, src__, profileIdentity__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileDeleteReqSend(src__, profileIdentity__) \ + CsrWifiNmeProfileDeleteReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, profileIdentity__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteCfmSend + + DESCRIPTION + Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_REQ. + Returns CSR_WIFI_NME_STATUS_NOT_FOUND if there is no matching profile. + + PARAMETERS + queue - Destination Task Queue + status - Indicates the success or otherwise of the requested operation. + +*******************************************************************************/ +#define CsrWifiNmeProfileDeleteCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeProfileDeleteCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileDeleteCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeProfileDeleteCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeProfileDeleteCfm *msg__; \ + CsrWifiNmeProfileDeleteCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileDeleteCfmSend(dst__, status__) \ + CsrWifiNmeProfileDeleteCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDisconnectIndSend + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that informs that application that the current profile + connection has disconnected. The indication will contain information + about APs that it attempted to maintain the connection via i.e. in the + case of failed roaming. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an + interface + connectAttemptsCount - Number of connection attempt elements provided with + this primitive + connectAttempts - Points to the list of connection attempt elements + provided with this primitive + Each element of the list provides information about + an AP on which the connection attempt was made and + the error occurred during the attempt. + +*******************************************************************************/ +#define CsrWifiNmeProfileDisconnectIndCreate(msg__, dst__, src__, interfaceTag__, connectAttemptsCount__, connectAttempts__) \ + msg__ = (CsrWifiNmeProfileDisconnectInd *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileDisconnectInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DISCONNECT_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->connectAttemptsCount = (connectAttemptsCount__); \ + msg__->connectAttempts = (connectAttempts__); + +#define CsrWifiNmeProfileDisconnectIndSendTo(dst__, src__, interfaceTag__, connectAttemptsCount__, connectAttempts__) \ + { \ + CsrWifiNmeProfileDisconnectInd *msg__; \ + CsrWifiNmeProfileDisconnectIndCreate(msg__, dst__, src__, interfaceTag__, connectAttemptsCount__, connectAttempts__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileDisconnectIndSend(dst__, interfaceTag__, connectAttemptsCount__, connectAttempts__) \ + CsrWifiNmeProfileDisconnectIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, connectAttemptsCount__, connectAttempts__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileOrderSetReqSend + + DESCRIPTION + Defines the preferred order that profiles present in the NME should be + used during the NME auto-connect behaviour. + If profileIdentitysCount == 0, it removes any existing preferred profile + list already present in the NME, effectively disabling the auto-connect + behaviour. + NOTE: Profile identities that do not match any profile stored in the NME + are ignored during the auto-connect procedure. + NOTE: during auto-connect the NME will only attempt to join an existing + adhoc network and it will never attempt to host an adhoc network; for + hosting and adhoc network, use CSR_WIFI_NME_PROFILE_CONNECT_REQ + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an + interface + profileIdentitysCount - The number of profiles identities in the list. + profileIdentitys - Points to the list of profile identities. + +*******************************************************************************/ +#define CsrWifiNmeProfileOrderSetReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) \ + msg__ = (CsrWifiNmeProfileOrderSetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileOrderSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_ORDER_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->profileIdentitysCount = (profileIdentitysCount__); \ + msg__->profileIdentitys = (profileIdentitys__); + +#define CsrWifiNmeProfileOrderSetReqSendTo(dst__, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) \ + { \ + CsrWifiNmeProfileOrderSetReq *msg__; \ + CsrWifiNmeProfileOrderSetReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileOrderSetReqSend(src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) \ + CsrWifiNmeProfileOrderSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileOrderSetCfmSend + + DESCRIPTION + Confirmation to UNIFI_NME_PROFILE_ORDER_SET.request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Indicates the success or otherwise of the requested + operation. + +*******************************************************************************/ +#define CsrWifiNmeProfileOrderSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiNmeProfileOrderSetCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileOrderSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_ORDER_SET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiNmeProfileOrderSetCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiNmeProfileOrderSetCfm *msg__; \ + CsrWifiNmeProfileOrderSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileOrderSetCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiNmeProfileOrderSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileSetReqSend + + DESCRIPTION + Creates or updates an existing profile in the NME that matches the unique + identity of the profile. Each profile is identified by the combination of + BSSID and SSID. The profile contains all the required credentials for + attempting to connect to the network. Creating or updating a profile via + the NME PROFILE SET REQ does NOT add the profile to the preferred profile + list within the NME used for the NME auto-connect behaviour. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + profile - Specifies the identity and credentials of the network. + +*******************************************************************************/ +#define CsrWifiNmeProfileSetReqCreate(msg__, dst__, src__, profile__) \ + msg__ = (CsrWifiNmeProfileSetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_SET_REQ, dst__, src__); \ + msg__->profile = (profile__); + +#define CsrWifiNmeProfileSetReqSendTo(dst__, src__, profile__) \ + { \ + CsrWifiNmeProfileSetReq *msg__; \ + CsrWifiNmeProfileSetReqCreate(msg__, dst__, src__, profile__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileSetReqSend(src__, profile__) \ + CsrWifiNmeProfileSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, profile__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileSetCfmSend + + DESCRIPTION + Reports the status of the NME PROFILE SET REQ; the request will only fail + if the details specified in the profile contains an invalid combination + of parameters for example specifying the profile as cloaked but not + specifying the SSID. The NME doesn't limit the number of profiles that + may be created. The NME assumes that the entity configuring it is aware + of the appropriate limits. + + PARAMETERS + queue - Destination Task Queue + status - Indicates the success or otherwise of the requested operation. + +*******************************************************************************/ +#define CsrWifiNmeProfileSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeProfileSetCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeProfileSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeProfileSetCfm *msg__; \ + CsrWifiNmeProfileSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileSetCfmSend(dst__, status__) \ + CsrWifiNmeProfileSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileUpdateIndSend + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that informs that application that the contained profile has + changed. + For example, either the credentials EAP-FAST PAC file or the session data + within the profile has changed. + It is up to the application whether it stores this updated profile or + not. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + profile - The identity and credentials of the network. + +*******************************************************************************/ +#define CsrWifiNmeProfileUpdateIndCreate(msg__, dst__, src__, interfaceTag__, profile__) \ + msg__ = (CsrWifiNmeProfileUpdateInd *) CsrPmemAlloc(sizeof(CsrWifiNmeProfileUpdateInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_UPDATE_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->profile = (profile__); + +#define CsrWifiNmeProfileUpdateIndSendTo(dst__, src__, interfaceTag__, profile__) \ + { \ + CsrWifiNmeProfileUpdateInd *msg__; \ + CsrWifiNmeProfileUpdateIndCreate(msg__, dst__, src__, interfaceTag__, profile__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeProfileUpdateIndSend(dst__, interfaceTag__, profile__) \ + CsrWifiNmeProfileUpdateIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, profile__) + +/******************************************************************************* + + NAME + CsrWifiNmeSimGsmAuthIndSend + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that requests the UICC Manager to perform a GSM + authentication on behalf of the NME. This indication is generated when + the NME is attempting to connect to a profile configured for EAP-SIM. An + application MUST register to receive this indication for the NME to + support the EAP-SIM credential types. Otherwise the NME has no route to + obtain the information from the UICC. EAP-SIM authentication requires 2 + or 3 GSM authentication rounds and therefore 2 or 3 RANDS (GSM Random + Challenges) are included. + + PARAMETERS + queue - Destination Task Queue + randsLength - GSM RAND is 16 bytes long hence valid values are 32 (2 RANDS) + or 48 (3 RANDs). + rands - 2 or 3 RANDs values. + +*******************************************************************************/ +#define CsrWifiNmeSimGsmAuthIndCreate(msg__, dst__, src__, randsLength__, rands__) \ + msg__ = (CsrWifiNmeSimGsmAuthInd *) CsrPmemAlloc(sizeof(CsrWifiNmeSimGsmAuthInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_GSM_AUTH_IND, dst__, src__); \ + msg__->randsLength = (randsLength__); \ + msg__->rands = (rands__); + +#define CsrWifiNmeSimGsmAuthIndSendTo(dst__, src__, randsLength__, rands__) \ + { \ + CsrWifiNmeSimGsmAuthInd *msg__; \ + CsrWifiNmeSimGsmAuthIndCreate(msg__, dst__, src__, randsLength__, rands__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeSimGsmAuthIndSend(dst__, randsLength__, rands__) \ + CsrWifiNmeSimGsmAuthIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, randsLength__, rands__) + +/******************************************************************************* + + NAME + CsrWifiNmeSimGsmAuthResSend + + DESCRIPTION + Response from the application that received the NME SIM GSM AUTH IND. For + each GSM authentication round a GSM Ciphering key (Kc) and a signed + response (SRES) are produced. Since 2 or 3 GSM authentication rounds are + used the 2 or 3 Kc's obtained respectively are combined into one buffer + and similarly the 2 or 3 SRES's obtained are combined into another + buffer. The order of Kc values (SRES values respectively) in their buffer + is the same as that of their corresponding RAND values in the incoming + indication. + + PARAMETERS + status - Indicates the outcome of the requested operation: + STATUS_SUCCESS or STATUS_ERROR + kcsLength - Length in Bytes of Kc buffer. Legal values are: 16 or 24. + kcs - Kc buffer holding 2 or 3 Kc values. + sresLength - Length in Bytes of SRES buffer. Legal values are: 8 or 12. + sres - SRES buffer holding 2 or 3 SRES values. + +*******************************************************************************/ +#define CsrWifiNmeSimGsmAuthResCreate(msg__, dst__, src__, status__, kcsLength__, kcs__, sresLength__, sres__) \ + msg__ = (CsrWifiNmeSimGsmAuthRes *) CsrPmemAlloc(sizeof(CsrWifiNmeSimGsmAuthRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_GSM_AUTH_RES, dst__, src__); \ + msg__->status = (status__); \ + msg__->kcsLength = (kcsLength__); \ + msg__->kcs = (kcs__); \ + msg__->sresLength = (sresLength__); \ + msg__->sres = (sres__); + +#define CsrWifiNmeSimGsmAuthResSendTo(dst__, src__, status__, kcsLength__, kcs__, sresLength__, sres__) \ + { \ + CsrWifiNmeSimGsmAuthRes *msg__; \ + CsrWifiNmeSimGsmAuthResCreate(msg__, dst__, src__, status__, kcsLength__, kcs__, sresLength__, sres__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeSimGsmAuthResSend(src__, status__, kcsLength__, kcs__, sresLength__, sres__) \ + CsrWifiNmeSimGsmAuthResSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, status__, kcsLength__, kcs__, sresLength__, sres__) + +/******************************************************************************* + + NAME + CsrWifiNmeSimImsiGetIndSend + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that requests the IMSI and UICC type from the UICC Manager. + This indication is generated when the NME is attempting to connect to a + profile configured for EAP-SIM/AKA. An application MUST register to + receive this indication for the NME to support the EAP-SIM/AKA credential + types. Otherwise the NME has no route to obtain the information from the + UICC. + + PARAMETERS + queue - Destination Task Queue + +*******************************************************************************/ +#define CsrWifiNmeSimImsiGetIndCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiNmeSimImsiGetInd *) CsrPmemAlloc(sizeof(CsrWifiNmeSimImsiGetInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_IMSI_GET_IND, dst__, src__); + +#define CsrWifiNmeSimImsiGetIndSendTo(dst__, src__) \ + { \ + CsrWifiNmeSimImsiGetInd *msg__; \ + CsrWifiNmeSimImsiGetIndCreate(msg__, dst__, src__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeSimImsiGetIndSend(dst__) \ + CsrWifiNmeSimImsiGetIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE) + +/******************************************************************************* + + NAME + CsrWifiNmeSimImsiGetResSend + + DESCRIPTION + Response from the application that received the NME SIM IMSI GET IND. + + PARAMETERS + status - Indicates the outcome of the requested operation: STATUS_SUCCESS + or STATUS_ERROR. + imsi - The value of the IMSI obtained from the UICC. + cardType - The UICC type (GSM only (SIM), UMTS only (USIM), Both). + +*******************************************************************************/ +#define CsrWifiNmeSimImsiGetResCreate(msg__, dst__, src__, status__, imsi__, cardType__) \ + msg__ = (CsrWifiNmeSimImsiGetRes *) CsrPmemAlloc(sizeof(CsrWifiNmeSimImsiGetRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_IMSI_GET_RES, dst__, src__); \ + msg__->status = (status__); \ + msg__->imsi = (imsi__); \ + msg__->cardType = (cardType__); + +#define CsrWifiNmeSimImsiGetResSendTo(dst__, src__, status__, imsi__, cardType__) \ + { \ + CsrWifiNmeSimImsiGetRes *msg__; \ + CsrWifiNmeSimImsiGetResCreate(msg__, dst__, src__, status__, imsi__, cardType__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeSimImsiGetResSend(src__, status__, imsi__, cardType__) \ + CsrWifiNmeSimImsiGetResSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, status__, imsi__, cardType__) + +/******************************************************************************* + + NAME + CsrWifiNmeSimUmtsAuthIndSend + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that requests the UICC Manager to perform a UMTS + authentication on behalf of the NME. This indication is generated when + the NME is attempting to connect to a profile configured for EAP-AKA. An + application MUST register to receive this indication for the NME to + support the EAP-AKA credential types. Otherwise the NME has no route to + obtain the information from the USIM. EAP-AKA requires one UMTS + authentication round and therefore only one RAND and one AUTN values are + included. + + PARAMETERS + queue - Destination Task Queue + rand - UMTS RAND value. + autn - UMTS AUTN value. + +*******************************************************************************/ +#define CsrWifiNmeSimUmtsAuthIndCreate(msg__, dst__, src__, rand__, autn__) \ + msg__ = (CsrWifiNmeSimUmtsAuthInd *) CsrPmemAlloc(sizeof(CsrWifiNmeSimUmtsAuthInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_UMTS_AUTH_IND, dst__, src__); \ + CsrMemCpy(msg__->rand, (rand__), sizeof(CsrUint8) * 16); \ + CsrMemCpy(msg__->autn, (autn__), sizeof(CsrUint8) * 16); + +#define CsrWifiNmeSimUmtsAuthIndSendTo(dst__, src__, rand__, autn__) \ + { \ + CsrWifiNmeSimUmtsAuthInd *msg__; \ + CsrWifiNmeSimUmtsAuthIndCreate(msg__, dst__, src__, rand__, autn__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeSimUmtsAuthIndSend(dst__, rand__, autn__) \ + CsrWifiNmeSimUmtsAuthIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, rand__, autn__) + +/******************************************************************************* + + NAME + CsrWifiNmeSimUmtsAuthResSend + + DESCRIPTION + Response from the application that received the NME SIM UMTS AUTH IND. + The values of umtsCipherKey, umtsIntegrityKey, resParameterLength and + resParameter are only meanigful when result = UMTS_AUTH_RESULT_SUCCESS. + The value of auts is only meaningful when + result=UMTS_AUTH_RESULT_SYNC_FAIL. + + PARAMETERS + status - Indicates the outcome of the requested operation: + STATUS_SUCCESS or STATUS_ERROR. + result - The result of UMTS authentication as performed by the + UICC which could be: Success, Authentication Reject or + Synchronisation Failure. For all these 3 outcomes the + value of status is success. + umtsCipherKey - The UMTS Cipher Key as calculated and returned by the + UICC. + umtsIntegrityKey - The UMTS Integrity Key as calculated and returned by + the UICC. + resParameterLength - The length (in bytes) of the RES parameter (min=4; max + = 16). + resParameter - The RES parameter as calculated and returned by the + UICC. + auts - The AUTS parameter as calculated and returned by the + UICC. + +*******************************************************************************/ +#define CsrWifiNmeSimUmtsAuthResCreate(msg__, dst__, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) \ + msg__ = (CsrWifiNmeSimUmtsAuthRes *) CsrPmemAlloc(sizeof(CsrWifiNmeSimUmtsAuthRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_UMTS_AUTH_RES, dst__, src__); \ + msg__->status = (status__); \ + msg__->result = (result__); \ + CsrMemCpy(msg__->umtsCipherKey, (umtsCipherKey__), sizeof(CsrUint8) * 16); \ + CsrMemCpy(msg__->umtsIntegrityKey, (umtsIntegrityKey__), sizeof(CsrUint8) * 16); \ + msg__->resParameterLength = (resParameterLength__); \ + msg__->resParameter = (resParameter__); \ + CsrMemCpy(msg__->auts, (auts__), sizeof(CsrUint8) * 14); + +#define CsrWifiNmeSimUmtsAuthResSendTo(dst__, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) \ + { \ + CsrWifiNmeSimUmtsAuthRes *msg__; \ + CsrWifiNmeSimUmtsAuthResCreate(msg__, dst__, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeSimUmtsAuthResSend(src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) \ + CsrWifiNmeSimUmtsAuthResSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) + +/******************************************************************************* + + NAME + CsrWifiNmeWpsCancelReqSend + + DESCRIPTION + Requests the NME to cancel any WPS procedure that it is currently + performing. This includes WPS registrar activities started because of + CSR_WIFI_NME_AP_REGISTER.request + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiNmeWpsCancelReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiNmeWpsCancelReq *) CsrPmemAlloc(sizeof(CsrWifiNmeWpsCancelReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CANCEL_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiNmeWpsCancelReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiNmeWpsCancelReq *msg__; \ + CsrWifiNmeWpsCancelReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeWpsCancelReqSend(src__, interfaceTag__) \ + CsrWifiNmeWpsCancelReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiNmeWpsCancelCfmSend + + DESCRIPTION + Reports the status of the NME WPS REQ, the request is always SUCCESSFUL. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Only returns CSR_WIFI_NME_STATUS_SUCCESS + +*******************************************************************************/ +#define CsrWifiNmeWpsCancelCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiNmeWpsCancelCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeWpsCancelCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CANCEL_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiNmeWpsCancelCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiNmeWpsCancelCfm *msg__; \ + CsrWifiNmeWpsCancelCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeWpsCancelCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiNmeWpsCancelCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeWpsCfmSend + + DESCRIPTION + Reports the status of the NME WPS REQ. + If CSR_WIFI_NME_STATUS_SUCCESS, the profile parameter contains the + identity and credentials of the AP. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Indicates the success or otherwise of the requested + operation. + profile - This parameter is relevant only if + status==CSR_WIFI_NME_STATUS_SUCCESS. + The identity and credentials of the network. + +*******************************************************************************/ +#define CsrWifiNmeWpsCfmCreate(msg__, dst__, src__, interfaceTag__, status__, profile__) \ + msg__ = (CsrWifiNmeWpsCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeWpsCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->profile = (profile__); + +#define CsrWifiNmeWpsCfmSendTo(dst__, src__, interfaceTag__, status__, profile__) \ + { \ + CsrWifiNmeWpsCfm *msg__; \ + CsrWifiNmeWpsCfmCreate(msg__, dst__, src__, interfaceTag__, status__, profile__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeWpsCfmSend(dst__, interfaceTag__, status__, profile__) \ + CsrWifiNmeWpsCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, profile__) + +/******************************************************************************* + + NAME + CsrWifiNmeWpsConfigSetReqSend + + DESCRIPTION + This primitive passes the WPS information for the device to NME. This may + be accepted only if no interface is active. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + wpsConfig - WPS config. + +*******************************************************************************/ +#define CsrWifiNmeWpsConfigSetReqCreate(msg__, dst__, src__, wpsConfig__) \ + msg__ = (CsrWifiNmeWpsConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeWpsConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CONFIG_SET_REQ, dst__, src__); \ + msg__->wpsConfig = (wpsConfig__); + +#define CsrWifiNmeWpsConfigSetReqSendTo(dst__, src__, wpsConfig__) \ + { \ + CsrWifiNmeWpsConfigSetReq *msg__; \ + CsrWifiNmeWpsConfigSetReqCreate(msg__, dst__, src__, wpsConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeWpsConfigSetReqSend(src__, wpsConfig__) \ + CsrWifiNmeWpsConfigSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, wpsConfig__) + +/******************************************************************************* + + NAME + CsrWifiNmeWpsConfigSetCfmSend + + DESCRIPTION + Confirm. + + PARAMETERS + queue - Destination Task Queue + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiNmeWpsConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiNmeWpsConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeWpsConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiNmeWpsConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiNmeWpsConfigSetCfm *msg__; \ + CsrWifiNmeWpsConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeWpsConfigSetCfmSend(dst__, status__) \ + CsrWifiNmeWpsConfigSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiNmeWpsReqSend + + DESCRIPTION + Requests the NME to look for WPS enabled APs and attempt to perform WPS + to determine the appropriate security credentials to connect to the AP. + If the PIN == '00000000' then 'push button mode' is indicated, otherwise + the PIN has to match that of the AP. 4 digit pin is passed by sending the + pin digits in pin[0]..pin[3] and rest of the contents filled with '-'. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + pin - PIN value. + ssid - Service Set identifier + bssid - ID of Basic Service Set for which a WPS connection attempt is + being made. + +*******************************************************************************/ +#define CsrWifiNmeWpsReqCreate(msg__, dst__, src__, interfaceTag__, pin__, ssid__, bssid__) \ + msg__ = (CsrWifiNmeWpsReq *) CsrPmemAlloc(sizeof(CsrWifiNmeWpsReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + CsrMemCpy(msg__->pin, (pin__), sizeof(CsrUint8) * 8); \ + msg__->ssid = (ssid__); \ + msg__->bssid = (bssid__); + +#define CsrWifiNmeWpsReqSendTo(dst__, src__, interfaceTag__, pin__, ssid__, bssid__) \ + { \ + CsrWifiNmeWpsReq *msg__; \ + CsrWifiNmeWpsReqCreate(msg__, dst__, src__, interfaceTag__, pin__, ssid__, bssid__); \ + CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \ + } + +#define CsrWifiNmeWpsReqSend(src__, interfaceTag__, pin__, ssid__, bssid__) \ + CsrWifiNmeWpsReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, pin__, ssid__, bssid__) + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_prim.h b/drivers/staging/csr/csr_wifi_nme_prim.h new file mode 100644 index 000000000000..4d77d2f450c1 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_prim.h @@ -0,0 +1,1666 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_PRIM_H__ +#define CSR_WIFI_NME_PRIM_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_wifi_common.h" +#include "csr_result.h" +#include "csr_wifi_fsm_event.h" +#include "csr_wifi_sme_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_prim.h +#endif + +#define CSR_WIFI_NME_PRIM (0x0424) + +typedef CsrPrim CsrWifiNmePrim; + +typedef void (*CsrWifiNmeFrameFreeFunction)(void *frame); + +/******************************************************************************* + + NAME + CsrWifiNmeAuthMode + + DESCRIPTION + WiFi Authentication Mode + + VALUES + CSR_WIFI_NME_AUTH_MODE_80211_OPEN + - Connects to an open system network (i.e. no authentication, + no encryption) or to a WEP enabled network. + CSR_WIFI_NME_AUTH_MODE_80211_SHARED + - Connect to a WEP enabled network. + CSR_WIFI_NME_AUTH_MODE_8021X_WPA + - Connects to a WPA Enterprise enabled network. + CSR_WIFI_NME_AUTH_MODE_8021X_WPAPSK + - Connects to a WPA with Pre-Shared Key enabled network. + CSR_WIFI_NME_AUTH_MODE_8021X_WPA2 + - Connects to a WPA2 Enterprise enabled network. + CSR_WIFI_NME_AUTH_MODE_8021X_WPA2PSK + - Connects to a WPA2 with Pre-Shared Key enabled network. + CSR_WIFI_NME_AUTH_MODE_8021X_CCKM + - Connects to a CCKM enabled network. + CSR_WIFI_NME_AUTH_MODE_WAPI_WAI + - Connects to a WAPI Enterprise enabled network. + CSR_WIFI_NME_AUTH_MODE_WAPI_WAIPSK + - Connects to a WAPI with Pre-Shared Key enabled network. + CSR_WIFI_NME_AUTH_MODE_8021X_OTHER1X + - For future use. + +*******************************************************************************/ +typedef CsrUint16 CsrWifiNmeAuthMode; +#define CSR_WIFI_NME_AUTH_MODE_80211_OPEN ((CsrWifiNmeAuthMode) 0x0001) +#define CSR_WIFI_NME_AUTH_MODE_80211_SHARED ((CsrWifiNmeAuthMode) 0x0002) +#define CSR_WIFI_NME_AUTH_MODE_8021X_WPA ((CsrWifiNmeAuthMode) 0x0004) +#define CSR_WIFI_NME_AUTH_MODE_8021X_WPAPSK ((CsrWifiNmeAuthMode) 0x0008) +#define CSR_WIFI_NME_AUTH_MODE_8021X_WPA2 ((CsrWifiNmeAuthMode) 0x0010) +#define CSR_WIFI_NME_AUTH_MODE_8021X_WPA2PSK ((CsrWifiNmeAuthMode) 0x0020) +#define CSR_WIFI_NME_AUTH_MODE_8021X_CCKM ((CsrWifiNmeAuthMode) 0x0040) +#define CSR_WIFI_NME_AUTH_MODE_WAPI_WAI ((CsrWifiNmeAuthMode) 0x0080) +#define CSR_WIFI_NME_AUTH_MODE_WAPI_WAIPSK ((CsrWifiNmeAuthMode) 0x0100) +#define CSR_WIFI_NME_AUTH_MODE_8021X_OTHER1X ((CsrWifiNmeAuthMode) 0x0200) + +/******************************************************************************* + + NAME + CsrWifiNmeBssType + + DESCRIPTION + Type of BSS + + VALUES + CSR_WIFI_NME_BSS_TYPE_INFRASTRUCTURE + - Infrastructure BSS type where access to the network is via + one or several Access Points. + CSR_WIFI_NME_BSS_TYPE_ADHOC + - Adhoc or Independent BSS Type where one Station acts as a + host and future stations can join the adhoc network without + needing an access point. + CSR_WIFI_NME_BSS_TYPE_RESERVED + - To be in sync with SME.This is not used. + CSR_WIFI_NME_BSS_TYPE_P2P + - P2P mode of operation. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeBssType; +#define CSR_WIFI_NME_BSS_TYPE_INFRASTRUCTURE ((CsrWifiNmeBssType) 0x00) +#define CSR_WIFI_NME_BSS_TYPE_ADHOC ((CsrWifiNmeBssType) 0x01) +#define CSR_WIFI_NME_BSS_TYPE_RESERVED ((CsrWifiNmeBssType) 0x02) +#define CSR_WIFI_NME_BSS_TYPE_P2P ((CsrWifiNmeBssType) 0x03) + +/******************************************************************************* + + NAME + CsrWifiNmeCcxOptionsMask + + DESCRIPTION + Enumeration type defining possible mask values for setting CCX options. + + VALUES + CSR_WIFI_NME_CCX_OPTION_NONE - No CCX option is set. + CSR_WIFI_NME_CCX_OPTION_CCKM - CCX option cckm is set. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeCcxOptionsMask; +#define CSR_WIFI_NME_CCX_OPTION_NONE ((CsrWifiNmeCcxOptionsMask) 0x00) +#define CSR_WIFI_NME_CCX_OPTION_CCKM ((CsrWifiNmeCcxOptionsMask) 0x01) + +/******************************************************************************* + + NAME + CsrWifiNmeConfigAction + + DESCRIPTION + + VALUES + CSR_WIFI_PIN_ENTRY_PUSH_BUTTON - + CSR_WIFI_PIN_ENTRY_DISPLAY_PIN - + CSR_WIFI_PIN_ENTRY_ENTER_PIN - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeConfigAction; +#define CSR_WIFI_PIN_ENTRY_PUSH_BUTTON ((CsrWifiNmeConfigAction) 0x00) +#define CSR_WIFI_PIN_ENTRY_DISPLAY_PIN ((CsrWifiNmeConfigAction) 0x01) +#define CSR_WIFI_PIN_ENTRY_ENTER_PIN ((CsrWifiNmeConfigAction) 0x02) + +/******************************************************************************* + + NAME + CsrWifiNmeConnectionStatus + + DESCRIPTION + Indicate the NME Connection Status when connecting or when disconnecting + + VALUES + CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTED + - NME is disconnected. + CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTING + - NME is in the process of connecting. + CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_AUTHENTICATING + - NME is in the authentication stage of a connection attempt. + CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTED + - NME is connected. + CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTING + - NME is in the process of disconnecting. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeConnectionStatus; +#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTED ((CsrWifiNmeConnectionStatus) 0x00) +#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTING ((CsrWifiNmeConnectionStatus) 0x01) +#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_AUTHENTICATING ((CsrWifiNmeConnectionStatus) 0x02) +#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTED ((CsrWifiNmeConnectionStatus) 0x03) +#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTING ((CsrWifiNmeConnectionStatus) 0x04) + +/******************************************************************************* + + NAME + CsrWifiNmeCredentialType + + DESCRIPTION + NME Credential Types + + VALUES + CSR_WIFI_NME_CREDENTIAL_TYPE_OPEN_SYSTEM + - Credential Type Open System. + CSR_WIFI_NME_CREDENTIAL_TYPE_WEP64 + - Credential Type WEP-64 + CSR_WIFI_NME_CREDENTIAL_TYPE_WEP128 + - Credential Type WEP-128 + CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PSK + - Credential Type WPA Pre-Shared Key + CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PASSPHRASE + - Credential Type WPA pass phrase + CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PSK + - Credential Type WPA2 Pre-Shared Key. + CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PASSPHRASE + - Credential Type WPA2 pass phrase + CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PSK + - Credential Type WAPI Pre-Shared Key. + CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PASSPHRASE + - Credential Type WAPI pass phrase + CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI + - Credential Type WAPI certificates + CSR_WIFI_NME_CREDENTIAL_TYPE_8021X + - Credential Type 802.1X: the associated type supports + FAST/LEAP/TLS/TTLS/PEAP/etc. + +*******************************************************************************/ +typedef CsrUint16 CsrWifiNmeCredentialType; +#define CSR_WIFI_NME_CREDENTIAL_TYPE_OPEN_SYSTEM ((CsrWifiNmeCredentialType) 0x0000) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WEP64 ((CsrWifiNmeCredentialType) 0x0001) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WEP128 ((CsrWifiNmeCredentialType) 0x0002) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PSK ((CsrWifiNmeCredentialType) 0x0003) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PASSPHRASE ((CsrWifiNmeCredentialType) 0x0004) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PSK ((CsrWifiNmeCredentialType) 0x0005) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PASSPHRASE ((CsrWifiNmeCredentialType) 0x0006) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PSK ((CsrWifiNmeCredentialType) 0x0007) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PASSPHRASE ((CsrWifiNmeCredentialType) 0x0008) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI ((CsrWifiNmeCredentialType) 0x0009) +#define CSR_WIFI_NME_CREDENTIAL_TYPE_8021X ((CsrWifiNmeCredentialType) 0x000A) + +/******************************************************************************* + + NAME + CsrWifiNmeEapMethod + + DESCRIPTION + Outer EAP method with possibly inner method. + + VALUES + CSR_WIFI_NME_EAP_METHOD_TLS + - EAP-TLS Method. + CSR_WIFI_NME_EAP_METHOD_TTLS_MSCHAPV2 + - EAP-TTLS Method with MSCHAPV2. + CSR_WIFI_NME_EAP_METHOD_PEAP_GTC + - EAP-PEAP Method with GTC. + CSR_WIFI_NME_EAP_METHOD_PEAP_MSCHAPV2 + - EAP-PEAP Method with MSCHAPV2. + CSR_WIFI_NME_EAP_METHOD_SIM + - EAP-SIM Method. + CSR_WIFI_NME_EAP_METHOD_AKA + - EAP-AKA Method. + CSR_WIFI_NME_EAP_METHOD_FAST_GTC + - EAP-FAST Method with GTC. + CSR_WIFI_NME_EAP_METHOD_FAST_MSCHAPV2 + - EAP-FAST Method with MSCHAPV2. + CSR_WIFI_NME_EAP_METHOD_LEAP + - EAP-LEAP Method. + +*******************************************************************************/ +typedef CsrUint16 CsrWifiNmeEapMethod; +#define CSR_WIFI_NME_EAP_METHOD_TLS ((CsrWifiNmeEapMethod) 0x0001) +#define CSR_WIFI_NME_EAP_METHOD_TTLS_MSCHAPV2 ((CsrWifiNmeEapMethod) 0x0002) +#define CSR_WIFI_NME_EAP_METHOD_PEAP_GTC ((CsrWifiNmeEapMethod) 0x0004) +#define CSR_WIFI_NME_EAP_METHOD_PEAP_MSCHAPV2 ((CsrWifiNmeEapMethod) 0x0008) +#define CSR_WIFI_NME_EAP_METHOD_SIM ((CsrWifiNmeEapMethod) 0x0010) +#define CSR_WIFI_NME_EAP_METHOD_AKA ((CsrWifiNmeEapMethod) 0x0020) +#define CSR_WIFI_NME_EAP_METHOD_FAST_GTC ((CsrWifiNmeEapMethod) 0x0040) +#define CSR_WIFI_NME_EAP_METHOD_FAST_MSCHAPV2 ((CsrWifiNmeEapMethod) 0x0080) +#define CSR_WIFI_NME_EAP_METHOD_LEAP ((CsrWifiNmeEapMethod) 0x0100) + +/******************************************************************************* + + NAME + CsrWifiNmeEncryption + + DESCRIPTION + WiFi Encryption method + + VALUES + CSR_WIFI_NME_ENCRYPTION_CIPHER_NONE + - No encryprion set. + CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 + - 40 bytes WEP key for peer to peer communication. + CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 + - 104 bytes WEP key for peer to peer communication. + CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_TKIP + - TKIP key for peer to peer communication. + CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP + - CCMP key for peer to peer communication. + CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 + - SMS4 key for peer to peer communication. + CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP40 + - 40 bytes WEP key for broadcast messages. + CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP104 + - 104 bytes WEP key for broadcast messages. + CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_TKIP + - TKIP key for broadcast messages. + CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP + - CCMP key for broadcast messages + CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_SMS4 + - SMS4 key for broadcast messages. + +*******************************************************************************/ +typedef CsrUint16 CsrWifiNmeEncryption; +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_NONE ((CsrWifiNmeEncryption) 0x0000) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 ((CsrWifiNmeEncryption) 0x0001) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 ((CsrWifiNmeEncryption) 0x0002) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_TKIP ((CsrWifiNmeEncryption) 0x0004) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP ((CsrWifiNmeEncryption) 0x0008) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 ((CsrWifiNmeEncryption) 0x0010) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP40 ((CsrWifiNmeEncryption) 0x0020) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP104 ((CsrWifiNmeEncryption) 0x0040) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_TKIP ((CsrWifiNmeEncryption) 0x0080) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP ((CsrWifiNmeEncryption) 0x0100) +#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_SMS4 ((CsrWifiNmeEncryption) 0x0200) + +/******************************************************************************* + + NAME + CsrWifiNmeIndications + + DESCRIPTION + NME indications + + VALUES + CSR_WIFI_NME_INDICATIONS_IND_AP_STATION + - NME AP Station Indication. + CSR_WIFI_NME_INDICATIONS_IND_AP_STOP + - NME AP Stop Indication. + CSR_WIFI_NME_INDICATIONS_IND_SIM_UMTS_AUTH + - NME UMTS Authentication Indication. + CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_START + - NME P2P Group Start Indication. + CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_STATUS + - NME P2P Group Status Indication. + CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_ROLE + - NME P2P Group Role Indication. + CSR_WIFI_NME_INDICATIONS_IND_PROFILE_DISCONNECT + - NME Profile Disconnect Indication. + CSR_WIFI_NME_INDICATIONS_IND_PROFILE_UPDATE + - NME Profile Update Indication. + CSR_WIFI_NME_INDICATIONS_IND_SIM_IMSI_GET + - NME GET IMSI Indication. + CSR_WIFI_NME_INDICATIONS_IND_SIM_GSM_AUTH + - NME GSM Authentication Indication. + CSR_WIFI_NME_INDICATIONS_ALL + - Used to register for all available indications + +*******************************************************************************/ +typedef CsrUint32 CsrWifiNmeIndications; +#define CSR_WIFI_NME_INDICATIONS_IND_AP_STATION ((CsrWifiNmeIndications) 0x00100000) +#define CSR_WIFI_NME_INDICATIONS_IND_AP_STOP ((CsrWifiNmeIndications) 0x00200000) +#define CSR_WIFI_NME_INDICATIONS_IND_SIM_UMTS_AUTH ((CsrWifiNmeIndications) 0x01000000) +#define CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_START ((CsrWifiNmeIndications) 0x02000000) +#define CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_STATUS ((CsrWifiNmeIndications) 0x04000000) +#define CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_ROLE ((CsrWifiNmeIndications) 0x08000000) +#define CSR_WIFI_NME_INDICATIONS_IND_PROFILE_DISCONNECT ((CsrWifiNmeIndications) 0x10000000) +#define CSR_WIFI_NME_INDICATIONS_IND_PROFILE_UPDATE ((CsrWifiNmeIndications) 0x20000000) +#define CSR_WIFI_NME_INDICATIONS_IND_SIM_IMSI_GET ((CsrWifiNmeIndications) 0x40000000) +#define CSR_WIFI_NME_INDICATIONS_IND_SIM_GSM_AUTH ((CsrWifiNmeIndications) 0x80000000) +#define CSR_WIFI_NME_INDICATIONS_ALL ((CsrWifiNmeIndications) 0xFFFFFFFF) + +/******************************************************************************* + + NAME + CsrWifiNmeSecError + + DESCRIPTION + NME Security Errors + place holder for the security library abort reason + + VALUES + CSR_WIFI_NME_SEC_ERROR_SEC_ERROR_UNKNOWN + - Unknown Security Error. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeSecError; +#define CSR_WIFI_NME_SEC_ERROR_SEC_ERROR_UNKNOWN ((CsrWifiNmeSecError) 0x00) + +/******************************************************************************* + + NAME + CsrWifiNmeSimCardType + + DESCRIPTION + (U)SIM Card (or UICC) types + + VALUES + CSR_WIFI_NME_SIM_CARD_TYPE_2G - 2G SIM card, capable of performing GSM + authentication only. + CSR_WIFI_NME_SIM_CARD_TYPE_3G - UICC supporting USIM application, capable + of performing UMTS authentication only. + CSR_WIFI_NME_SIM_CARD_TYPE_2G3G - UICC supporting both USIM and SIM + applications, capable of performing both + UMTS and GSM authentications. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeSimCardType; +#define CSR_WIFI_NME_SIM_CARD_TYPE_2G ((CsrWifiNmeSimCardType) 0x01) +#define CSR_WIFI_NME_SIM_CARD_TYPE_3G ((CsrWifiNmeSimCardType) 0x02) +#define CSR_WIFI_NME_SIM_CARD_TYPE_2G3G ((CsrWifiNmeSimCardType) 0x03) + +/******************************************************************************* + + NAME + CsrWifiNmeUmtsAuthResult + + DESCRIPTION + Only relevant for UMTS Authentication. It indicates if the UICC has + successfully authenticated the network or otherwise. + + VALUES + CSR_WIFI_NME_UMTS_AUTH_RESULT_SUCCESS + - Successful outcome from USIM indicating that the card has + successfully authenticated the network. + CSR_WIFI_NME_UMTS_AUTH_RESULT_SYNC_FAIL + - Unsuccessful outcome from USIM indicating that the card is + requesting the network to synchronise and re-try again. If + no further request is received an NME timer will expire and + the authentication is aborted. + CSR_WIFI_NME_UMTS_AUTH_RESULT_REJECT + - Unsuccessful outcome from USIM indicating that the card has + rejected the network and that the authentication is + aborted. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeUmtsAuthResult; +#define CSR_WIFI_NME_UMTS_AUTH_RESULT_SUCCESS ((CsrWifiNmeUmtsAuthResult) 0x00) +#define CSR_WIFI_NME_UMTS_AUTH_RESULT_SYNC_FAIL ((CsrWifiNmeUmtsAuthResult) 0x01) +#define CSR_WIFI_NME_UMTS_AUTH_RESULT_REJECT ((CsrWifiNmeUmtsAuthResult) 0x02) + +/******************************************************************************* + + NAME + CsrWifiNmeWmmQosInfo + + DESCRIPTION + Defines bits for the QoS Info octect as defined in the WMM specification. + The values of this type are used across the NME/SME/Router API's and they + must be kept consistent with the corresponding types in the .xml of the + other interfaces + + VALUES + CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_ALL + - WMM AP may deliver all buffered frames. + CSR_WIFI_NME_WMM_QOS_INFO_AC_VO + - To enable the triggering and delivery of QoS Voice. + CSR_WIFI_NME_WMM_QOS_INFO_AC_VI + - To enable the triggering and delivery of QoS Video. + CSR_WIFI_NME_WMM_QOS_INFO_AC_BK + - To enable the triggering and delivery of QoS Background. + CSR_WIFI_NME_WMM_QOS_INFO_AC_BE + - To enable the triggering and delivery of QoS Best Effort. + CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_TWO + - WMM AP may deliver a maximum of 2 buffered frames per + Unscheduled Service Period (USP). + CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_FOUR + - WMM AP may deliver a maximum of 4 buffered frames per USP. + CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_SIX + - WMM AP may deliver a maximum of 6 buffered frames per USP. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeWmmQosInfo; +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_ALL ((CsrWifiNmeWmmQosInfo) 0x00) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_VO ((CsrWifiNmeWmmQosInfo) 0x01) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_VI ((CsrWifiNmeWmmQosInfo) 0x02) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_BK ((CsrWifiNmeWmmQosInfo) 0x04) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_BE ((CsrWifiNmeWmmQosInfo) 0x08) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_TWO ((CsrWifiNmeWmmQosInfo) 0x20) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_FOUR ((CsrWifiNmeWmmQosInfo) 0x40) +#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_SIX ((CsrWifiNmeWmmQosInfo) 0x60) + + +/******************************************************************************* + + NAME + CsrWifiNmeEapMethodMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiNmeEapMethod. + +*******************************************************************************/ +typedef CsrUint16 CsrWifiNmeEapMethodMask; +/******************************************************************************* + + NAME + CsrWifiNmeEncryptionMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiNmeEncryption + +*******************************************************************************/ +typedef CsrUint16 CsrWifiNmeEncryptionMask; +/******************************************************************************* + + NAME + CsrWifiNmeIndicationsMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiNmeIndications + +*******************************************************************************/ +typedef CsrUint32 CsrWifiNmeIndicationsMask; +/******************************************************************************* + + NAME + CsrWifiNmeNmeIndicationsMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiNmeNmeIndications. + Used to overlap the unused portion of the unifi_IndicationsMask For NME + specific indications + +*******************************************************************************/ +typedef CsrUint32 CsrWifiNmeNmeIndicationsMask; +/******************************************************************************* + + NAME + CsrWifiNmeWmmQosInfoMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiNmeWmmQosInfo + +*******************************************************************************/ +typedef CsrUint8 CsrWifiNmeWmmQosInfoMask; + + +/******************************************************************************* + + NAME + CsrWifiNmeEmpty + + DESCRIPTION + Empty Structure to indicate that no credentials are available. + + MEMBERS + empty - Only element of the empty structure (always set to 0). + +*******************************************************************************/ +typedef struct +{ + CsrUint8 empty; +} CsrWifiNmeEmpty; + +/******************************************************************************* + + NAME + CsrWifiNmePassphrase + + DESCRIPTION + Structure holding the ASCII Pass Phrase data. + + MEMBERS + encryptionMode - Encryption type as defined in CsrWifiSmeEncryption. + passphrase - Pass phrase ASCII value. + +*******************************************************************************/ +typedef struct +{ + CsrUint16 encryptionMode; + CsrCharString *passphrase; +} CsrWifiNmePassphrase; + +/******************************************************************************* + + NAME + CsrWifiNmePsk + + DESCRIPTION + Structure holding the Pre-Shared Key data. + + MEMBERS + encryptionMode - Encryption type as defined in CsrWifiSmeEncryption. + psk - Pre-Shared Key value. + +*******************************************************************************/ +typedef struct +{ + CsrUint16 encryptionMode; + CsrUint8 psk[32]; +} CsrWifiNmePsk; + +/******************************************************************************* + + NAME + CsrWifiNmeWapiCredentials + + DESCRIPTION + Structure holding WAPI credentials data. + + MEMBERS + certificateLength - Length in bytes of the following client certificate. + certificate - The actual client certificate data (if present). + DER/PEM format supported. + privateKeyLength - Length in bytes of the following private key. + privateKey - The actual private key. DER/PEM format. + caCertificateLength - Length in bytes of the following certificate authority + certificate. + caCertificate - The actual certificate authority certificate data. If + not supplied the received certificate authority + certificate is assumed to be validate, if present the + received certificate is validated against it. DER/PEM + format supported. + +*******************************************************************************/ +typedef struct +{ + CsrUint32 certificateLength; + CsrUint8 *certificate; + CsrUint16 privateKeyLength; + CsrUint8 *privateKey; + CsrUint32 caCertificateLength; + CsrUint8 *caCertificate; +} CsrWifiNmeWapiCredentials; + +/******************************************************************************* + + NAME + CsrWifiNmeConnectAttempt + + DESCRIPTION + Structure holding Connection attempt data. + + MEMBERS + bssid - Id of Basic Service Set connections attempt have been made + to. + status - Status returned to indicate the success or otherwise of the + connection attempt. + securityError - Security error status indicating the nature of the failure + to connect. + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress bssid; + CsrResult status; + CsrWifiNmeSecError securityError; +} CsrWifiNmeConnectAttempt; + +/******************************************************************************* + + NAME + CsrWifiNmeEapCredentials + + DESCRIPTION + Supports the use of multiple EAP methods via a single structure. The + methods required are indicated by the value set in the eapMethodMask + + MEMBERS + eapMethodMask + - Bit mask of supported EAP methods + Currently only supports the setting of one bit. + Required for all the EAP methods. + authMode + - Bit mask representing the authentication types that may be + supported by a suitable AP. An AP must support at least one + of the authentication types specified to be considered for + connection. Required for all EAP methods. + encryptionMode + - Bit mask representing the encryption types that may be + supported by a suitable AP. An AP must support a suitable + mix of the pairwise and group encryption types requested to + be considered for connection. Required for all EAP methods. + userName + - User name. Required for all EAP methods except: SIM or AKA. + userPassword + - User Password. Required for all EAP methods except: TLS, + SIM or AKA. + authServerUserIdentity + - Authentication server user Identity. Required for all EAP + methods except: TLS, SIM, AKA or FAST. + clientCertificateLength + - Length in bytes of the following client certificate (if + present). Only required for TLS. + clientCertificate + - The actual client certificate data (if present). Only + required for TLS. DER/PEM format supported. + certificateAuthorityCertificateLength + - Length in bytes of the following certificate authority + certificate (if present). Optional for TLS, TTLS, PEAP. + certificateAuthorityCertificate + - The actual certificate authority certificate data (if + present). If not supplied the received certificate + authority certificate is assumed to be valid, if present + the received certificate is validated against it. Optional + for TLS, TTLS, PEAP. DER/PEM format supported. + privateKeyLength + - Length in bytes of the following private key (if present). + Only required for TLS. + privateKey + - The actual private key (if present). Only required for TLS. + DER/PEM format, maybe password protected. + privateKeyPassword + - Optional password to protect the private key. + sessionLength + - Length in bytes of the following session field Supported + for all EAP methods except: SIM or AKA. + session + - Session information to support faster re-authentication. + Supported for all EAP methods except: SIM or AKA. + allowPacProvisioning + - If TRUE: PAC provisioning is allowed 'over-the_air'; + If FALSE: a PAC must be supplied. + Only required for FAST. + pacLength + - Length the following PAC field. If allowPacProvisioning is + FALSE then the PAC MUST be supplied (i.e. non-zero). Only + required for FAST. + pac + - The actual PAC data. If allowPacProvisioning is FALSE then + the PAC MUST be supplied. Only required for FAST. + pacPassword + - Optional password to protect the PAC. Only required for + FAST. + +*******************************************************************************/ +typedef struct +{ + CsrWifiNmeEapMethodMask eapMethodMask; + CsrWifiSmeAuthModeMask authMode; + CsrWifiNmeEncryptionMask encryptionMode; + CsrCharString *userName; + CsrCharString *userPassword; + CsrCharString *authServerUserIdentity; + CsrUint32 clientCertificateLength; + CsrUint8 *clientCertificate; + CsrUint32 certificateAuthorityCertificateLength; + CsrUint8 *certificateAuthorityCertificate; + CsrUint16 privateKeyLength; + CsrUint8 *privateKey; + CsrCharString *privateKeyPassword; + CsrUint32 sessionLength; + CsrUint8 *session; + CsrBool allowPacProvisioning; + CsrUint32 pacLength; + CsrUint8 *pac; + CsrCharString *pacPassword; +} CsrWifiNmeEapCredentials; + +/******************************************************************************* + + NAME + CsrWifiNmePeerConfig + + DESCRIPTION + Structure holding Peer Config data. + + MEMBERS + p2pDeviceId - + groupCapabilityMask - + groupOwnerIntent - + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress p2pDeviceId; + CsrWifiSmeP2pGroupCapabilityMask groupCapabilityMask; + CsrUint8 groupOwnerIntent; +} CsrWifiNmePeerConfig; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileIdentity + + DESCRIPTION + The identity of a profile is defined as the unique combination the BSSID + and SSID. + + MEMBERS + bssid - ID of Basic Service Set for or the P2pDevice address of the GO for + which a connection attempt was made. + ssid - Service Set Id. + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress bssid; + CsrWifiSsid ssid; +} CsrWifiNmeProfileIdentity; + +/******************************************************************************* + + NAME + CsrWifiNmeWep128Keys + + DESCRIPTION + Structure holding WEP Authentication Type and WEP keys that can be used + when using WEP128. + + MEMBERS + wepAuthType - Mask to select the WEP authentication type (Open or Shared) + selectedWepKey - Index to one of the four keys below indicating the + currently used WEP key. + key1 - Value for key number 1. + key2 - Value for key number 2. + key3 - Value for key number 3. + key4 - Value for key number 4. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeAuthModeMask wepAuthType; + CsrUint8 selectedWepKey; + CsrUint8 key1[13]; + CsrUint8 key2[13]; + CsrUint8 key3[13]; + CsrUint8 key4[13]; +} CsrWifiNmeWep128Keys; + +/******************************************************************************* + + NAME + CsrWifiNmeWep64Keys + + DESCRIPTION + Structure for holding WEP Authentication Type and WEP keys that can be + used when using WEP64. + + MEMBERS + wepAuthType - Mask to select the WEP authentication type (Open or Shared) + selectedWepKey - Index to one of the four keys below indicating the + currently used WEP key. + key1 - Value for key number 1. + key2 - Value for key number 2. + key3 - Value for key number 3. + key4 - Value for key number 4. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeAuthModeMask wepAuthType; + CsrUint8 selectedWepKey; + CsrUint8 key1[5]; + CsrUint8 key2[5]; + CsrUint8 key3[5]; + CsrUint8 key4[5]; +} CsrWifiNmeWep64Keys; + +/******************************************************************************* + + NAME + CsrWifiNmeCredentials + + DESCRIPTION + Structure containing the Credentials data. + + MEMBERS + credentialType - Credential type value (as defined in the + enumeration type). + credential - Union containing credentials which depends on + credentialType parameter. + credentialeap - + credentialwapiPassphrase - + credentialwpa2Passphrase - + credentialwpa2Psk - + credentialwapiPsk - + credentialwpaPassphrase - + credentialwapi - + credentialwep128Key - + credentialwpaPsk - + credentialopenSystem - + credentialwep64Key - + +*******************************************************************************/ +typedef struct +{ + CsrWifiNmeCredentialType credentialType; + union { + CsrWifiNmeEapCredentials eap; + CsrWifiNmePassphrase wapiPassphrase; + CsrWifiNmePassphrase wpa2Passphrase; + CsrWifiNmePsk wpa2Psk; + CsrWifiNmePsk wapiPsk; + CsrWifiNmePassphrase wpaPassphrase; + CsrWifiNmeWapiCredentials wapi; + CsrWifiNmeWep128Keys wep128Key; + CsrWifiNmePsk wpaPsk; + CsrWifiNmeEmpty openSystem; + CsrWifiNmeWep64Keys wep64Key; + } credential; +} CsrWifiNmeCredentials; + +/******************************************************************************* + + NAME + CsrWifiNmeProfile + + DESCRIPTION + Structure containing the Profile data. + + MEMBERS + profileIdentity - Profile Identity. + wmmQosInfoMask - Mask for WMM QoS information. + bssType - Type of BSS (Infrastructure or Adhoc). + channelNo - Channel Number. + ccxOptionsMask - Options mask for Cisco Compatible Extentions. + cloakedSsid - Flag to decide whether the SSID is cloaked (not + transmitted) or not. + credentials - Credentials data. + +*******************************************************************************/ +typedef struct +{ + CsrWifiNmeProfileIdentity profileIdentity; + CsrWifiNmeWmmQosInfoMask wmmQosInfoMask; + CsrWifiNmeBssType bssType; + CsrUint8 channelNo; + CsrUint8 ccxOptionsMask; + CsrBool cloakedSsid; + CsrWifiNmeCredentials credentials; +} CsrWifiNmeProfile; + + +/* Downstream */ +#define CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST (0x0000) + +#define CSR_WIFI_NME_PROFILE_SET_REQ ((CsrWifiNmePrim) (0x0000 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_DELETE_REQ ((CsrWifiNmePrim) (0x0001 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ ((CsrWifiNmePrim) (0x0002 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_ORDER_SET_REQ ((CsrWifiNmePrim) (0x0003 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_CONNECT_REQ ((CsrWifiNmePrim) (0x0004 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_WPS_REQ ((CsrWifiNmePrim) (0x0005 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_WPS_CANCEL_REQ ((CsrWifiNmePrim) (0x0006 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_CONNECTION_STATUS_GET_REQ ((CsrWifiNmePrim) (0x0007 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_SIM_IMSI_GET_RES ((CsrWifiNmePrim) (0x0008 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_SIM_GSM_AUTH_RES ((CsrWifiNmePrim) (0x0009 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_SIM_UMTS_AUTH_RES ((CsrWifiNmePrim) (0x000A + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_WPS_CONFIG_SET_REQ ((CsrWifiNmePrim) (0x000B + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_NME_EVENT_MASK_SET_REQ ((CsrWifiNmePrim) (0x000C + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)) + + +#define CSR_WIFI_NME_PRIM_DOWNSTREAM_HIGHEST (0x000C + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST) + +/* Upstream */ +#define CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) + +#define CSR_WIFI_NME_PROFILE_SET_CFM ((CsrWifiNmePrim)(0x0000 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_DELETE_CFM ((CsrWifiNmePrim)(0x0001 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_DELETE_ALL_CFM ((CsrWifiNmePrim)(0x0002 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_ORDER_SET_CFM ((CsrWifiNmePrim)(0x0003 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_CONNECT_CFM ((CsrWifiNmePrim)(0x0004 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_WPS_CFM ((CsrWifiNmePrim)(0x0005 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_WPS_CANCEL_CFM ((CsrWifiNmePrim)(0x0006 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_CONNECTION_STATUS_GET_CFM ((CsrWifiNmePrim)(0x0007 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_UPDATE_IND ((CsrWifiNmePrim)(0x0008 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_PROFILE_DISCONNECT_IND ((CsrWifiNmePrim)(0x0009 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_SIM_IMSI_GET_IND ((CsrWifiNmePrim)(0x000A + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_SIM_GSM_AUTH_IND ((CsrWifiNmePrim)(0x000B + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_SIM_UMTS_AUTH_IND ((CsrWifiNmePrim)(0x000C + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_WPS_CONFIG_SET_CFM ((CsrWifiNmePrim)(0x000D + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_NME_EVENT_MASK_SET_CFM ((CsrWifiNmePrim)(0x000E + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)) + +#define CSR_WIFI_NME_PRIM_UPSTREAM_HIGHEST (0x000E + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST) + +#define CSR_WIFI_NME_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_NME_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_NME_PRIM_UPSTREAM_COUNT (CSR_WIFI_NME_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST) + +/******************************************************************************* + + NAME + CsrWifiNmeProfileSetReq + + DESCRIPTION + Creates or updates an existing profile in the NME that matches the unique + identity of the profile. Each profile is identified by the combination of + BSSID and SSID. The profile contains all the required credentials for + attempting to connect to the network. Creating or updating a profile via + the NME PROFILE SET REQ does NOT add the profile to the preferred profile + list within the NME used for the NME auto-connect behaviour. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + profile - Specifies the identity and credentials of the network. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiNmeProfile profile; +} CsrWifiNmeProfileSetReq; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteReq + + DESCRIPTION + Will delete the profile with a matching identity, but does NOT modify the + preferred profile list. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + profileIdentity - Identity (BSSID, SSID) of profile to be deleted. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiNmeProfileIdentity profileIdentity; +} CsrWifiNmeProfileDeleteReq; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteAllReq + + DESCRIPTION + Deletes all profiles present in the NME, but does NOT modify the + preferred profile list. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiNmeProfileDeleteAllReq; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileOrderSetReq + + DESCRIPTION + Defines the preferred order that profiles present in the NME should be + used during the NME auto-connect behaviour. + If profileIdentitysCount == 0, it removes any existing preferred profile + list already present in the NME, effectively disabling the auto-connect + behaviour. + NOTE: Profile identities that do not match any profile stored in the NME + are ignored during the auto-connect procedure. + NOTE: during auto-connect the NME will only attempt to join an existing + adhoc network and it will never attempt to host an adhoc network; for + hosting and adhoc network, use CSR_WIFI_NME_PROFILE_CONNECT_REQ + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an + interface + profileIdentitysCount - The number of profiles identities in the list. + profileIdentitys - Points to the list of profile identities. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 profileIdentitysCount; + CsrWifiNmeProfileIdentity *profileIdentitys; +} CsrWifiNmeProfileOrderSetReq; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileConnectReq + + DESCRIPTION + Requests the NME to attempt to connect to the specified profile. + Overrides any current connection attempt. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + profileIdentity - Identity (BSSID, SSID) of profile to be connected to. + It must match an existing profile in the NME. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiNmeProfileIdentity profileIdentity; +} CsrWifiNmeProfileConnectReq; + +/******************************************************************************* + + NAME + CsrWifiNmeWpsReq + + DESCRIPTION + Requests the NME to look for WPS enabled APs and attempt to perform WPS + to determine the appropriate security credentials to connect to the AP. + If the PIN == '00000000' then 'push button mode' is indicated, otherwise + the PIN has to match that of the AP. 4 digit pin is passed by sending the + pin digits in pin[0]..pin[3] and rest of the contents filled with '-'. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + pin - PIN value. + ssid - Service Set identifier + bssid - ID of Basic Service Set for which a WPS connection attempt is + being made. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 pin[8]; + CsrWifiSsid ssid; + CsrWifiMacAddress bssid; +} CsrWifiNmeWpsReq; + +/******************************************************************************* + + NAME + CsrWifiNmeWpsCancelReq + + DESCRIPTION + Requests the NME to cancel any WPS procedure that it is currently + performing. This includes WPS registrar activities started because of + CSR_WIFI_NME_AP_REGISTER.request + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiNmeWpsCancelReq; + +/******************************************************************************* + + NAME + CsrWifiNmeConnectionStatusGetReq + + DESCRIPTION + Requests the current connection status of the NME. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiNmeConnectionStatusGetReq; + +/******************************************************************************* + + NAME + CsrWifiNmeSimImsiGetRes + + DESCRIPTION + Response from the application that received the NME SIM IMSI GET IND. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Indicates the outcome of the requested operation: STATUS_SUCCESS + or STATUS_ERROR. + imsi - The value of the IMSI obtained from the UICC. + cardType - The UICC type (GSM only (SIM), UMTS only (USIM), Both). + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrCharString *imsi; + CsrWifiNmeSimCardType cardType; +} CsrWifiNmeSimImsiGetRes; + +/******************************************************************************* + + NAME + CsrWifiNmeSimGsmAuthRes + + DESCRIPTION + Response from the application that received the NME SIM GSM AUTH IND. For + each GSM authentication round a GSM Ciphering key (Kc) and a signed + response (SRES) are produced. Since 2 or 3 GSM authentication rounds are + used the 2 or 3 Kc's obtained respectively are combined into one buffer + and similarly the 2 or 3 SRES's obtained are combined into another + buffer. The order of Kc values (SRES values respectively) in their buffer + is the same as that of their corresponding RAND values in the incoming + indication. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Indicates the outcome of the requested operation: + STATUS_SUCCESS or STATUS_ERROR + kcsLength - Length in Bytes of Kc buffer. Legal values are: 16 or 24. + kcs - Kc buffer holding 2 or 3 Kc values. + sresLength - Length in Bytes of SRES buffer. Legal values are: 8 or 12. + sres - SRES buffer holding 2 or 3 SRES values. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrUint8 kcsLength; + CsrUint8 *kcs; + CsrUint8 sresLength; + CsrUint8 *sres; +} CsrWifiNmeSimGsmAuthRes; + +/******************************************************************************* + + NAME + CsrWifiNmeSimUmtsAuthRes + + DESCRIPTION + Response from the application that received the NME SIM UMTS AUTH IND. + The values of umtsCipherKey, umtsIntegrityKey, resParameterLength and + resParameter are only meanigful when result = UMTS_AUTH_RESULT_SUCCESS. + The value of auts is only meaningful when + result=UMTS_AUTH_RESULT_SYNC_FAIL. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Indicates the outcome of the requested operation: + STATUS_SUCCESS or STATUS_ERROR. + result - The result of UMTS authentication as performed by the + UICC which could be: Success, Authentication Reject or + Synchronisation Failure. For all these 3 outcomes the + value of status is success. + umtsCipherKey - The UMTS Cipher Key as calculated and returned by the + UICC. + umtsIntegrityKey - The UMTS Integrity Key as calculated and returned by + the UICC. + resParameterLength - The length (in bytes) of the RES parameter (min=4; max + = 16). + resParameter - The RES parameter as calculated and returned by the + UICC. + auts - The AUTS parameter as calculated and returned by the + UICC. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiNmeUmtsAuthResult result; + CsrUint8 umtsCipherKey[16]; + CsrUint8 umtsIntegrityKey[16]; + CsrUint8 resParameterLength; + CsrUint8 *resParameter; + CsrUint8 auts[14]; +} CsrWifiNmeSimUmtsAuthRes; + +/******************************************************************************* + + NAME + CsrWifiNmeWpsConfigSetReq + + DESCRIPTION + This primitive passes the WPS information for the device to NME. This may + be accepted only if no interface is active. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + wpsConfig - WPS config. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeWpsConfig wpsConfig; +} CsrWifiNmeWpsConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiNmeEventMaskSetReq + + DESCRIPTION + The wireless manager application may register with the NME to receive + notification of interesting events. Indications will be sent only if the + wireless manager explicitly registers to be notified of that event. + indMask is a bit mask of values defined in CsrWifiNmeIndicationsMask. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + indMask - Set mask with values from CsrWifiNmeIndications + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiNmeIndicationsMask indMask; +} CsrWifiNmeEventMaskSetReq; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileSetCfm + + DESCRIPTION + Reports the status of the NME PROFILE SET REQ; the request will only fail + if the details specified in the profile contains an invalid combination + of parameters for example specifying the profile as cloaked but not + specifying the SSID. The NME doesn't limit the number of profiles that + may be created. The NME assumes that the entity configuring it is aware + of the appropriate limits. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Indicates the success or otherwise of the requested operation. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeProfileSetCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteCfm + + DESCRIPTION + Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_REQ. + Returns CSR_WIFI_NME_STATUS_NOT_FOUND if there is no matching profile. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Indicates the success or otherwise of the requested operation. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeProfileDeleteCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDeleteAllCfm + + DESCRIPTION + Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ. + Returns always CSR_WIFI_NME_STATUS_SUCCESS. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Indicates the success or otherwise of the requested operation, but + in this case it always set to success. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeProfileDeleteAllCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileOrderSetCfm + + DESCRIPTION + Confirmation to UNIFI_NME_PROFILE_ORDER_SET.request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Indicates the success or otherwise of the requested + operation. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiNmeProfileOrderSetCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileConnectCfm + + DESCRIPTION + Reports the status of the NME PROFILE CONNECT REQ. If unsuccessful the + connectAttempt parameters contain details of the APs that the NME + attempted to connect to before reporting the failure of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an + interface + status - Indicates the success or otherwise of the requested + operation. + connectAttemptsCount - This parameter is relevant only if + status!=CSR_WIFI_NME_STATUS_SUCCESS. + Number of connection attempt elements provided with + this primitive + connectAttempts - This parameter is relevant only if + status!=CSR_WIFI_NME_STATUS_SUCCESS. + Points to the list of connection attempt elements + provided with this primitive + Each element of the list provides information about + an AP on which the connection attempt was made and + the error that occurred during the attempt. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrUint8 connectAttemptsCount; + CsrWifiNmeConnectAttempt *connectAttempts; +} CsrWifiNmeProfileConnectCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeWpsCfm + + DESCRIPTION + Reports the status of the NME WPS REQ. + If CSR_WIFI_NME_STATUS_SUCCESS, the profile parameter contains the + identity and credentials of the AP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Indicates the success or otherwise of the requested + operation. + profile - This parameter is relevant only if + status==CSR_WIFI_NME_STATUS_SUCCESS. + The identity and credentials of the network. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiNmeProfile profile; +} CsrWifiNmeWpsCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeWpsCancelCfm + + DESCRIPTION + Reports the status of the NME WPS REQ, the request is always SUCCESSFUL. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Only returns CSR_WIFI_NME_STATUS_SUCCESS + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiNmeWpsCancelCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeConnectionStatusGetCfm + + DESCRIPTION + Reports the connection status of the NME. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Indicates the success or otherwise of the requested + operation. + connectionStatus - NME current connection status + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiNmeConnectionStatus connectionStatus; +} CsrWifiNmeConnectionStatusGetCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileUpdateInd + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that informs that application that the contained profile has + changed. + For example, either the credentials EAP-FAST PAC file or the session data + within the profile has changed. + It is up to the application whether it stores this updated profile or + not. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + profile - The identity and credentials of the network. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiNmeProfile profile; +} CsrWifiNmeProfileUpdateInd; + +/******************************************************************************* + + NAME + CsrWifiNmeProfileDisconnectInd + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that informs that application that the current profile + connection has disconnected. The indication will contain information + about APs that it attempted to maintain the connection via i.e. in the + case of failed roaming. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an + interface + connectAttemptsCount - Number of connection attempt elements provided with + this primitive + connectAttempts - Points to the list of connection attempt elements + provided with this primitive + Each element of the list provides information about + an AP on which the connection attempt was made and + the error occurred during the attempt. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 connectAttemptsCount; + CsrWifiNmeConnectAttempt *connectAttempts; +} CsrWifiNmeProfileDisconnectInd; + +/******************************************************************************* + + NAME + CsrWifiNmeSimImsiGetInd + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that requests the IMSI and UICC type from the UICC Manager. + This indication is generated when the NME is attempting to connect to a + profile configured for EAP-SIM/AKA. An application MUST register to + receive this indication for the NME to support the EAP-SIM/AKA credential + types. Otherwise the NME has no route to obtain the information from the + UICC. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiNmeSimImsiGetInd; + +/******************************************************************************* + + NAME + CsrWifiNmeSimGsmAuthInd + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that requests the UICC Manager to perform a GSM + authentication on behalf of the NME. This indication is generated when + the NME is attempting to connect to a profile configured for EAP-SIM. An + application MUST register to receive this indication for the NME to + support the EAP-SIM credential types. Otherwise the NME has no route to + obtain the information from the UICC. EAP-SIM authentication requires 2 + or 3 GSM authentication rounds and therefore 2 or 3 RANDS (GSM Random + Challenges) are included. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + randsLength - GSM RAND is 16 bytes long hence valid values are 32 (2 RANDS) + or 48 (3 RANDs). + rands - 2 or 3 RANDs values. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint8 randsLength; + CsrUint8 *rands; +} CsrWifiNmeSimGsmAuthInd; + +/******************************************************************************* + + NAME + CsrWifiNmeSimUmtsAuthInd + + DESCRIPTION + Indication generated from the NME (if an application subscribes to + receive it) that requests the UICC Manager to perform a UMTS + authentication on behalf of the NME. This indication is generated when + the NME is attempting to connect to a profile configured for EAP-AKA. An + application MUST register to receive this indication for the NME to + support the EAP-AKA credential types. Otherwise the NME has no route to + obtain the information from the USIM. EAP-AKA requires one UMTS + authentication round and therefore only one RAND and one AUTN values are + included. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + rand - UMTS RAND value. + autn - UMTS AUTN value. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint8 rand[16]; + CsrUint8 autn[16]; +} CsrWifiNmeSimUmtsAuthInd; + +/******************************************************************************* + + NAME + CsrWifiNmeWpsConfigSetCfm + + DESCRIPTION + Confirm. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeWpsConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiNmeEventMaskSetCfm + + DESCRIPTION + The NME calls the primitive to report the result of the request + primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiNmeEventMaskSetCfm; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_PRIM_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_nme_serialize.h b/drivers/staging/csr/csr_wifi_nme_serialize.h new file mode 100644 index 000000000000..aeca9c83dc71 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_serialize.h @@ -0,0 +1,177 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_SERIALIZE_H__ +#define CSR_WIFI_NME_SERIALIZE_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_wifi_msgconv.h" + +#include "csr_wifi_nme_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_serialize.h +#endif + +extern void CsrWifiNmePfree(void *ptr); + +extern CsrUint8* CsrWifiNmeProfileSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileSetReqSizeof(void *msg); +extern void CsrWifiNmeProfileSetReqSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeProfileDeleteReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileDeleteReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileDeleteReqSizeof(void *msg); +#define CsrWifiNmeProfileDeleteReqSerFree CsrWifiNmePfree + +#define CsrWifiNmeProfileDeleteAllReqSer CsrWifiEventSer +#define CsrWifiNmeProfileDeleteAllReqDes CsrWifiEventDes +#define CsrWifiNmeProfileDeleteAllReqSizeof CsrWifiEventSizeof +#define CsrWifiNmeProfileDeleteAllReqSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeProfileOrderSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileOrderSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileOrderSetReqSizeof(void *msg); +extern void CsrWifiNmeProfileOrderSetReqSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeProfileConnectReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileConnectReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileConnectReqSizeof(void *msg); +#define CsrWifiNmeProfileConnectReqSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeWpsReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeWpsReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeWpsReqSizeof(void *msg); +#define CsrWifiNmeWpsReqSerFree CsrWifiNmePfree + +#define CsrWifiNmeWpsCancelReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeWpsCancelReqDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeWpsCancelReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeWpsCancelReqSerFree CsrWifiNmePfree + +#define CsrWifiNmeConnectionStatusGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeConnectionStatusGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeConnectionStatusGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeConnectionStatusGetReqSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeSimImsiGetResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeSimImsiGetResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeSimImsiGetResSizeof(void *msg); +extern void CsrWifiNmeSimImsiGetResSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeSimGsmAuthResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeSimGsmAuthResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeSimGsmAuthResSizeof(void *msg); +extern void CsrWifiNmeSimGsmAuthResSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeSimUmtsAuthResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeSimUmtsAuthResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeSimUmtsAuthResSizeof(void *msg); +extern void CsrWifiNmeSimUmtsAuthResSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeWpsConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeWpsConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeWpsConfigSetReqSizeof(void *msg); +extern void CsrWifiNmeWpsConfigSetReqSerFree(void *msg); + +#define CsrWifiNmeEventMaskSetReqSer CsrWifiEventCsrUint32Ser +#define CsrWifiNmeEventMaskSetReqDes CsrWifiEventCsrUint32Des +#define CsrWifiNmeEventMaskSetReqSizeof CsrWifiEventCsrUint32Sizeof +#define CsrWifiNmeEventMaskSetReqSerFree CsrWifiNmePfree + +#define CsrWifiNmeProfileSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeProfileSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeProfileSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeProfileSetCfmSerFree CsrWifiNmePfree + +#define CsrWifiNmeProfileDeleteCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeProfileDeleteCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeProfileDeleteCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeProfileDeleteCfmSerFree CsrWifiNmePfree + +#define CsrWifiNmeProfileDeleteAllCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeProfileDeleteAllCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeProfileDeleteAllCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeProfileDeleteAllCfmSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeProfileOrderSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileOrderSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileOrderSetCfmSizeof(void *msg); +#define CsrWifiNmeProfileOrderSetCfmSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeProfileConnectCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileConnectCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileConnectCfmSizeof(void *msg); +extern void CsrWifiNmeProfileConnectCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeWpsCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeWpsCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeWpsCfmSizeof(void *msg); +extern void CsrWifiNmeWpsCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeWpsCancelCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeWpsCancelCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeWpsCancelCfmSizeof(void *msg); +#define CsrWifiNmeWpsCancelCfmSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeConnectionStatusGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeConnectionStatusGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeConnectionStatusGetCfmSizeof(void *msg); +#define CsrWifiNmeConnectionStatusGetCfmSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeProfileUpdateIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileUpdateIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileUpdateIndSizeof(void *msg); +extern void CsrWifiNmeProfileUpdateIndSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeProfileDisconnectIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeProfileDisconnectIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeProfileDisconnectIndSizeof(void *msg); +extern void CsrWifiNmeProfileDisconnectIndSerFree(void *msg); + +#define CsrWifiNmeSimImsiGetIndSer CsrWifiEventSer +#define CsrWifiNmeSimImsiGetIndDes CsrWifiEventDes +#define CsrWifiNmeSimImsiGetIndSizeof CsrWifiEventSizeof +#define CsrWifiNmeSimImsiGetIndSerFree CsrWifiNmePfree + +extern CsrUint8* CsrWifiNmeSimGsmAuthIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeSimGsmAuthIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeSimGsmAuthIndSizeof(void *msg); +extern void CsrWifiNmeSimGsmAuthIndSerFree(void *msg); + +extern CsrUint8* CsrWifiNmeSimUmtsAuthIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiNmeSimUmtsAuthIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiNmeSimUmtsAuthIndSizeof(void *msg); +#define CsrWifiNmeSimUmtsAuthIndSerFree CsrWifiNmePfree + +#define CsrWifiNmeWpsConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeWpsConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeWpsConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeWpsConfigSetCfmSerFree CsrWifiNmePfree + +#define CsrWifiNmeEventMaskSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiNmeEventMaskSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiNmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiNmeEventMaskSetCfmSerFree CsrWifiNmePfree + + +#ifdef __cplusplus +} +#endif +#endif /* CSR_WIFI_NME_SERIALIZE_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_nme_task.h b/drivers/staging/csr/csr_wifi_nme_task.h new file mode 100644 index 000000000000..2a03a19e402f --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_task.h @@ -0,0 +1,38 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_NME_TASK_H__ +#define CSR_WIFI_NME_TASK_H__ + +#include "csr_types.h" +#include "csr_sched.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_NME_ENABLE +#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_task.h +#endif + +#define CSR_WIFI_NME_LOG_ID 0x1203FFFF +extern CsrSchedQid CSR_WIFI_NME_IFACEQUEUE; +void CsrWifiNmeInit(void **gash); +void CsrWifiNmeDeinit(void **gash); +void CsrWifiNmeHandler(void **gash); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_NME_TASK_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_private_common.h b/drivers/staging/csr/csr_wifi_private_common.h new file mode 100644 index 000000000000..b1d12397bd6d --- /dev/null +++ b/drivers/staging/csr/csr_wifi_private_common.h @@ -0,0 +1,91 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_PRIVATE_COMMON_H__ +#define CSR_WIFI_PRIVATE_COMMON_H__ + +#include "csr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief maximum number of STAs allowed to be connected + * + * @par Description + * min & max Beacon Interval + */ +#define CSR_WIFI_AP_MAX_ASSOC_STA 8 + +/** Number of only b rates */ +#define CSR_WIFI_SME_AP_MAX_ONLY_B_RATES 4 + + +/** Number of mandatory b rates */ +#define CSR_WIFI_SME_AP_MAX_MANDATORY_B_RATES 2 + + +/** Number of mandatory bg rates */ +#define CSR_WIFI_SME_AP_MAX_MANDATORY_BG_RATES 4 + + +/** Number of bg rates */ +#define CSR_WIFI_SME_AP_MAX_BG_RATES 12 + + +/** Number of no b only g rates */ +#define CSR_WIFI_SME_AP_MAX_NO_B_ONLY_G_RATES 8 + + +/** Number of mandatory g rates */ +#define CSR_WIFI_SME_AP_MAX_MANDATORY_G_RATES 7 + + +/* Number of g mandatory rates */ +#define CSR_WIFI_SME_AP_G_MANDATORY_RATES_NUM 7 + + +/* Number of b mandatory rates */ +#define CSR_WIFI_SME_AP_B_MANDATORY_RATES_NUM 2 + + +/* Number of b/g mandatory rates */ +#define CSR_WIFI_SME_AP_BG_MANDATORY_RATES_NUM 4 + + +/* The maximum allowed length of SSID */ +#define CSR_WIFI_SME_AP_SSID_MAX_LENGTH 32 + +/* Refer 8.4.2.27 RSN element - we support TKIP, WPA2, WAPI and PSK only, no pmkid, group cipher suite */ +#define CSR_WIFI_SME_RSN_PACKED_SIZE (1 + 1 + 2 + 4 + 2 + 4 * 2 + 2 + 4 * 1 + 2 + 24) + +/* Refer 7.3.2.9 (ISO/IEC 8802-11:2006) WAPI element - we support WAPI PSK only, no bkid, group cipher suite */ +#define CSR_WIFI_SME_WAPI_PACKED_SIZE (1 + 1 + 2 + 2 + 4 * 1 + 2 + 4 * 1 + 4 + 2 + 24) + + +/* Common structure for NME and SME to maintain Interface mode*/ +typedef CsrUint8 CsrWifiInterfaceMode; +#define CSR_WIFI_MODE_NONE ((CsrWifiInterfaceMode) 0xFF) +#define CSR_WIFI_MODE_STA ((CsrWifiInterfaceMode) 0x00) +#define CSR_WIFI_MODE_AP ((CsrWifiInterfaceMode) 0x01) +#define CSR_WIFI_MODE_P2P_DEVICE ((CsrWifiInterfaceMode) 0x02) +#define CSR_WIFI_MODE_P2P_CLI ((CsrWifiInterfaceMode) 0x03) +#define CSR_WIFI_MODE_P2P_GO ((CsrWifiInterfaceMode) 0x04) +#define CSR_WIFI_MODE_AMP ((CsrWifiInterfaceMode) 0x05) +#define CSR_WIFI_MODE_WPS_ENROLLEE ((CsrWifiInterfaceMode) 0x06) +#define CSR_WIFI_MODE_IBSS ((CsrWifiInterfaceMode) 0x07) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/drivers/staging/csr/csr_wifi_result.h b/drivers/staging/csr/csr_wifi_result.h new file mode 100644 index 000000000000..95b73a0d71e6 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_result.h @@ -0,0 +1,36 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_RESULT_H__ +#define CSR_WIFI_RESULT_H__ + +#include "csr_types.h" +#include "csr_result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* THIS FILE SHOULD CONTAIN ONLY RESULT CODES */ + +/* Result Codes */ +#define CSR_WIFI_HIP_RESULT_INVALID_VALUE ((CsrResult) 1) /* Invalid argument value */ +#define CSR_WIFI_HIP_RESULT_NO_DEVICE ((CsrResult) 2) /* The specified device is no longer present */ +#define CSR_WIFI_HIP_RESULT_NO_SPACE ((CsrResult) 3) /* A queue or buffer is full */ +#define CSR_WIFI_HIP_RESULT_NO_MEMORY ((CsrResult) 4) /* Fatal error, no memory */ +#define CSR_WIFI_HIP_RESULT_RANGE ((CsrResult) 5) /* Request exceeds the range of a file or a buffer */ +#define CSR_WIFI_HIP_RESULT_NOT_FOUND ((CsrResult) 6) /* A file (typically a f/w patch) is not found */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_RESULT_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_router_converter_init.c b/drivers/staging/csr/csr_wifi_router_converter_init.c new file mode 100644 index 000000000000..f7ee3f0ec37d --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_converter_init.c @@ -0,0 +1,83 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_msgconv.h" +#include "csr_pmem.h" +#include "csr_util.h" + + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" +#endif + +#ifndef EXCLUDE_CSR_WIFI_ROUTER_MODULE +#include "csr_wifi_router_serialize.h" +#include "csr_wifi_router_prim.h" + +static CsrMsgConvMsgEntry csrwifirouter_conv_lut[] = { + { CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_REQ, CsrWifiRouterMaPacketSubscribeReqSizeof, CsrWifiRouterMaPacketSubscribeReqSer, CsrWifiRouterMaPacketSubscribeReqDes, CsrWifiRouterMaPacketSubscribeReqSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_REQ, CsrWifiRouterMaPacketUnsubscribeReqSizeof, CsrWifiRouterMaPacketUnsubscribeReqSer, CsrWifiRouterMaPacketUnsubscribeReqDes, CsrWifiRouterMaPacketUnsubscribeReqSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_REQ, CsrWifiRouterMaPacketReqSizeof, CsrWifiRouterMaPacketReqSer, CsrWifiRouterMaPacketReqDes, CsrWifiRouterMaPacketReqSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_RES, CsrWifiRouterMaPacketResSizeof, CsrWifiRouterMaPacketResSer, CsrWifiRouterMaPacketResDes, CsrWifiRouterMaPacketResSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_CANCEL_REQ, CsrWifiRouterMaPacketCancelReqSizeof, CsrWifiRouterMaPacketCancelReqSer, CsrWifiRouterMaPacketCancelReqDes, CsrWifiRouterMaPacketCancelReqSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_CFM, CsrWifiRouterMaPacketSubscribeCfmSizeof, CsrWifiRouterMaPacketSubscribeCfmSer, CsrWifiRouterMaPacketSubscribeCfmDes, CsrWifiRouterMaPacketSubscribeCfmSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_CFM, CsrWifiRouterMaPacketUnsubscribeCfmSizeof, CsrWifiRouterMaPacketUnsubscribeCfmSer, CsrWifiRouterMaPacketUnsubscribeCfmDes, CsrWifiRouterMaPacketUnsubscribeCfmSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_CFM, CsrWifiRouterMaPacketCfmSizeof, CsrWifiRouterMaPacketCfmSer, CsrWifiRouterMaPacketCfmDes, CsrWifiRouterMaPacketCfmSerFree }, + { CSR_WIFI_ROUTER_MA_PACKET_IND, CsrWifiRouterMaPacketIndSizeof, CsrWifiRouterMaPacketIndSer, CsrWifiRouterMaPacketIndDes, CsrWifiRouterMaPacketIndSerFree }, + + { 0, NULL, NULL, NULL, NULL }, +}; + +CsrMsgConvMsgEntry* CsrWifiRouterConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint16 msgType) +{ + if (msgType & CSR_PRIM_UPSTREAM) + { + CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT; + if (index < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) && + csrwifirouter_conv_lut[index].msgType == msgType) + { + return &csrwifirouter_conv_lut[index]; + } + } + else + { + if (msgType < CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT && + csrwifirouter_conv_lut[msgType].msgType == msgType) + { + return &csrwifirouter_conv_lut[msgType]; + } + } + return NULL; +} + + +void CsrWifiRouterConverterInit(void) +{ + CsrMsgConvInsert(CSR_WIFI_ROUTER_PRIM, csrwifirouter_conv_lut); + CsrMsgConvCustomLookupRegister(CSR_WIFI_ROUTER_PRIM, CsrWifiRouterConverterLookup); +} + + +#ifdef CSR_LOG_ENABLE +static const CsrLogPrimitiveInformation csrwifirouter_conv_info = { + CSR_WIFI_ROUTER_PRIM, + (CsrCharString *)"CSR_WIFI_ROUTER_PRIM", + csrwifirouter_conv_lut +}; +const CsrLogPrimitiveInformation* CsrWifiRouterTechInfoGet(void) +{ + return &csrwifirouter_conv_info; +} + + +#endif /* CSR_LOG_ENABLE */ +#endif /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */ diff --git a/drivers/staging/csr/csr_wifi_router_converter_init.h b/drivers/staging/csr/csr_wifi_router_converter_init.h new file mode 100644 index 000000000000..2a293e457ffb --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_converter_init.h @@ -0,0 +1,42 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_CONVERTER_INIT_H__ +#define CSR_WIFI_ROUTER_CONVERTER_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EXCLUDE_CSR_WIFI_ROUTER_MODULE + +#include "csr_msgconv.h" + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" + +extern const CsrLogPrimitiveInformation* CsrWifiRouterTechInfoGet(void); +#endif /* CSR_LOG_ENABLE */ + +extern void CsrWifiRouterConverterInit(void); + +#else /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */ + +#define CsrWifiRouterConverterInit() + +#endif /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c new file mode 100644 index 000000000000..36403fcf97e8 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c @@ -0,0 +1,132 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_msgconv.h" +#include "csr_pmem.h" +#include "csr_util.h" + + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" +#endif + +#ifndef EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE +#include "csr_wifi_router_ctrl_serialize.h" +#include "csr_wifi_router_ctrl_prim.h" + +static CsrMsgConvMsgEntry csrwifirouterctrl_conv_lut[] = { + { CSR_WIFI_ROUTER_CTRL_CONFIGURE_POWER_MODE_REQ, CsrWifiRouterCtrlConfigurePowerModeReqSizeof, CsrWifiRouterCtrlConfigurePowerModeReqSer, CsrWifiRouterCtrlConfigurePowerModeReqDes, CsrWifiRouterCtrlConfigurePowerModeReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_HIP_REQ, CsrWifiRouterCtrlHipReqSizeof, CsrWifiRouterCtrlHipReqSer, CsrWifiRouterCtrlHipReqDes, CsrWifiRouterCtrlHipReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_REQ, CsrWifiRouterCtrlMediaStatusReqSizeof, CsrWifiRouterCtrlMediaStatusReqSer, CsrWifiRouterCtrlMediaStatusReqDes, CsrWifiRouterCtrlMediaStatusReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES, CsrWifiRouterCtrlMulticastAddressResSizeof, CsrWifiRouterCtrlMulticastAddressResSer, CsrWifiRouterCtrlMulticastAddressResDes, CsrWifiRouterCtrlMulticastAddressResSerFree }, + { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_REQ, CsrWifiRouterCtrlPortConfigureReqSizeof, CsrWifiRouterCtrlPortConfigureReqSer, CsrWifiRouterCtrlPortConfigureReqDes, CsrWifiRouterCtrlPortConfigureReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_REQ, CsrWifiRouterCtrlQosControlReqSizeof, CsrWifiRouterCtrlQosControlReqSer, CsrWifiRouterCtrlQosControlReqDes, CsrWifiRouterCtrlQosControlReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_SUSPEND_RES, CsrWifiRouterCtrlSuspendResSizeof, CsrWifiRouterCtrlSuspendResSer, CsrWifiRouterCtrlSuspendResDes, CsrWifiRouterCtrlSuspendResSerFree }, + { CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ, CsrWifiRouterCtrlTclasAddReqSizeof, CsrWifiRouterCtrlTclasAddReqSer, CsrWifiRouterCtrlTclasAddReqDes, CsrWifiRouterCtrlTclasAddReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_RESUME_RES, CsrWifiRouterCtrlResumeResSizeof, CsrWifiRouterCtrlResumeResSer, CsrWifiRouterCtrlResumeResDes, CsrWifiRouterCtrlResumeResSerFree }, + { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_REQ, CsrWifiRouterCtrlRawSdioDeinitialiseReqSizeof, CsrWifiRouterCtrlRawSdioDeinitialiseReqSer, CsrWifiRouterCtrlRawSdioDeinitialiseReqDes, CsrWifiRouterCtrlRawSdioDeinitialiseReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_REQ, CsrWifiRouterCtrlRawSdioInitialiseReqSizeof, CsrWifiRouterCtrlRawSdioInitialiseReqSer, CsrWifiRouterCtrlRawSdioInitialiseReqDes, CsrWifiRouterCtrlRawSdioInitialiseReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ, CsrWifiRouterCtrlTclasDelReqSizeof, CsrWifiRouterCtrlTclasDelReqSer, CsrWifiRouterCtrlTclasDelReqDes, CsrWifiRouterCtrlTclasDelReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_TRAFFIC_CLASSIFICATION_REQ, CsrWifiRouterCtrlTrafficClassificationReqSizeof, CsrWifiRouterCtrlTrafficClassificationReqSer, CsrWifiRouterCtrlTrafficClassificationReqDes, CsrWifiRouterCtrlTrafficClassificationReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_REQ, CsrWifiRouterCtrlTrafficConfigReqSizeof, CsrWifiRouterCtrlTrafficConfigReqSer, CsrWifiRouterCtrlTrafficConfigReqDes, CsrWifiRouterCtrlTrafficConfigReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_REQ, CsrWifiRouterCtrlWifiOffReqSizeof, CsrWifiRouterCtrlWifiOffReqSer, CsrWifiRouterCtrlWifiOffReqDes, CsrWifiRouterCtrlWifiOffReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_RES, CsrWifiRouterCtrlWifiOffResSizeof, CsrWifiRouterCtrlWifiOffResSer, CsrWifiRouterCtrlWifiOffResDes, CsrWifiRouterCtrlWifiOffResSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, CsrWifiRouterCtrlWifiOnReqSizeof, CsrWifiRouterCtrlWifiOnReqSer, CsrWifiRouterCtrlWifiOnReqDes, CsrWifiRouterCtrlWifiOnReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES, CsrWifiRouterCtrlWifiOnResSizeof, CsrWifiRouterCtrlWifiOnResSer, CsrWifiRouterCtrlWifiOnResDes, CsrWifiRouterCtrlWifiOnResSerFree }, + { CSR_WIFI_ROUTER_CTRL_M4_TRANSMIT_REQ, CsrWifiRouterCtrlM4TransmitReqSizeof, CsrWifiRouterCtrlM4TransmitReqSer, CsrWifiRouterCtrlM4TransmitReqDes, CsrWifiRouterCtrlM4TransmitReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_MODE_SET_REQ, CsrWifiRouterCtrlModeSetReqSizeof, CsrWifiRouterCtrlModeSetReqSer, CsrWifiRouterCtrlModeSetReqDes, CsrWifiRouterCtrlModeSetReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_PEER_ADD_REQ, CsrWifiRouterCtrlPeerAddReqSizeof, CsrWifiRouterCtrlPeerAddReqSer, CsrWifiRouterCtrlPeerAddReqDes, CsrWifiRouterCtrlPeerAddReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_PEER_DEL_REQ, CsrWifiRouterCtrlPeerDelReqSizeof, CsrWifiRouterCtrlPeerDelReqSer, CsrWifiRouterCtrlPeerDelReqDes, CsrWifiRouterCtrlPeerDelReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_REQ, CsrWifiRouterCtrlPeerUpdateReqSizeof, CsrWifiRouterCtrlPeerUpdateReqSer, CsrWifiRouterCtrlPeerUpdateReqDes, CsrWifiRouterCtrlPeerUpdateReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, CsrWifiRouterCtrlCapabilitiesReqSizeof, CsrWifiRouterCtrlCapabilitiesReqSer, CsrWifiRouterCtrlCapabilitiesReqDes, CsrWifiRouterCtrlCapabilitiesReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, CsrWifiRouterCtrlBlockAckEnableReqSizeof, CsrWifiRouterCtrlBlockAckEnableReqSer, CsrWifiRouterCtrlBlockAckEnableReqDes, CsrWifiRouterCtrlBlockAckEnableReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, CsrWifiRouterCtrlBlockAckDisableReqSizeof, CsrWifiRouterCtrlBlockAckDisableReqSer, CsrWifiRouterCtrlBlockAckDisableReqDes, CsrWifiRouterCtrlBlockAckDisableReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, CsrWifiRouterCtrlWapiMulticastReqSizeof, CsrWifiRouterCtrlWapiMulticastReqSer, CsrWifiRouterCtrlWapiMulticastReqDes, CsrWifiRouterCtrlWapiMulticastReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, CsrWifiRouterCtrlWapiMulticastFilterReqSizeof, CsrWifiRouterCtrlWapiMulticastFilterReqSer, CsrWifiRouterCtrlWapiMulticastFilterReqDes, CsrWifiRouterCtrlWapiMulticastFilterReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, CsrWifiRouterCtrlWapiUnicastFilterReqSizeof, CsrWifiRouterCtrlWapiUnicastFilterReqSer, CsrWifiRouterCtrlWapiUnicastFilterReqDes, CsrWifiRouterCtrlWapiUnicastFilterReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_HIP_IND, CsrWifiRouterCtrlHipIndSizeof, CsrWifiRouterCtrlHipIndSer, CsrWifiRouterCtrlHipIndDes, CsrWifiRouterCtrlHipIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, CsrWifiRouterCtrlMulticastAddressIndSizeof, CsrWifiRouterCtrlMulticastAddressIndSer, CsrWifiRouterCtrlMulticastAddressIndDes, CsrWifiRouterCtrlMulticastAddressIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, CsrWifiRouterCtrlPortConfigureCfmSizeof, CsrWifiRouterCtrlPortConfigureCfmSer, CsrWifiRouterCtrlPortConfigureCfmDes, CsrWifiRouterCtrlPortConfigureCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_RESUME_IND, CsrWifiRouterCtrlResumeIndSizeof, CsrWifiRouterCtrlResumeIndSer, CsrWifiRouterCtrlResumeIndDes, CsrWifiRouterCtrlResumeIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_SUSPEND_IND, CsrWifiRouterCtrlSuspendIndSizeof, CsrWifiRouterCtrlSuspendIndSer, CsrWifiRouterCtrlSuspendIndDes, CsrWifiRouterCtrlSuspendIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_CFM, CsrWifiRouterCtrlTclasAddCfmSizeof, CsrWifiRouterCtrlTclasAddCfmSer, CsrWifiRouterCtrlTclasAddCfmDes, CsrWifiRouterCtrlTclasAddCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_CFM, CsrWifiRouterCtrlRawSdioDeinitialiseCfmSizeof, CsrWifiRouterCtrlRawSdioDeinitialiseCfmSer, CsrWifiRouterCtrlRawSdioDeinitialiseCfmDes, CsrWifiRouterCtrlRawSdioDeinitialiseCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_CFM, CsrWifiRouterCtrlRawSdioInitialiseCfmSizeof, CsrWifiRouterCtrlRawSdioInitialiseCfmSer, CsrWifiRouterCtrlRawSdioInitialiseCfmDes, CsrWifiRouterCtrlRawSdioInitialiseCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_CFM, CsrWifiRouterCtrlTclasDelCfmSizeof, CsrWifiRouterCtrlTclasDelCfmSer, CsrWifiRouterCtrlTclasDelCfmDes, CsrWifiRouterCtrlTclasDelCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_TRAFFIC_PROTOCOL_IND, CsrWifiRouterCtrlTrafficProtocolIndSizeof, CsrWifiRouterCtrlTrafficProtocolIndSer, CsrWifiRouterCtrlTrafficProtocolIndDes, CsrWifiRouterCtrlTrafficProtocolIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_TRAFFIC_SAMPLE_IND, CsrWifiRouterCtrlTrafficSampleIndSizeof, CsrWifiRouterCtrlTrafficSampleIndSer, CsrWifiRouterCtrlTrafficSampleIndDes, CsrWifiRouterCtrlTrafficSampleIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_IND, CsrWifiRouterCtrlWifiOffIndSizeof, CsrWifiRouterCtrlWifiOffIndSer, CsrWifiRouterCtrlWifiOffIndDes, CsrWifiRouterCtrlWifiOffIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_CFM, CsrWifiRouterCtrlWifiOffCfmSizeof, CsrWifiRouterCtrlWifiOffCfmSer, CsrWifiRouterCtrlWifiOffCfmDes, CsrWifiRouterCtrlWifiOffCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND, CsrWifiRouterCtrlWifiOnIndSizeof, CsrWifiRouterCtrlWifiOnIndSer, CsrWifiRouterCtrlWifiOnIndDes, CsrWifiRouterCtrlWifiOnIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_WIFI_ON_CFM, CsrWifiRouterCtrlWifiOnCfmSizeof, CsrWifiRouterCtrlWifiOnCfmSer, CsrWifiRouterCtrlWifiOnCfmDes, CsrWifiRouterCtrlWifiOnCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_M4_READY_TO_SEND_IND, CsrWifiRouterCtrlM4ReadyToSendIndSizeof, CsrWifiRouterCtrlM4ReadyToSendIndSer, CsrWifiRouterCtrlM4ReadyToSendIndDes, CsrWifiRouterCtrlM4ReadyToSendIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_M4_TRANSMITTED_IND, CsrWifiRouterCtrlM4TransmittedIndSizeof, CsrWifiRouterCtrlM4TransmittedIndSer, CsrWifiRouterCtrlM4TransmittedIndDes, CsrWifiRouterCtrlM4TransmittedIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_MIC_FAILURE_IND, CsrWifiRouterCtrlMicFailureIndSizeof, CsrWifiRouterCtrlMicFailureIndSer, CsrWifiRouterCtrlMicFailureIndDes, CsrWifiRouterCtrlMicFailureIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_CONNECTED_IND, CsrWifiRouterCtrlConnectedIndSizeof, CsrWifiRouterCtrlConnectedIndSer, CsrWifiRouterCtrlConnectedIndDes, CsrWifiRouterCtrlConnectedIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_PEER_ADD_CFM, CsrWifiRouterCtrlPeerAddCfmSizeof, CsrWifiRouterCtrlPeerAddCfmSer, CsrWifiRouterCtrlPeerAddCfmDes, CsrWifiRouterCtrlPeerAddCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_PEER_DEL_CFM, CsrWifiRouterCtrlPeerDelCfmSizeof, CsrWifiRouterCtrlPeerDelCfmSer, CsrWifiRouterCtrlPeerDelCfmDes, CsrWifiRouterCtrlPeerDelCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_UNEXPECTED_FRAME_IND, CsrWifiRouterCtrlUnexpectedFrameIndSizeof, CsrWifiRouterCtrlUnexpectedFrameIndSer, CsrWifiRouterCtrlUnexpectedFrameIndDes, CsrWifiRouterCtrlUnexpectedFrameIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_CFM, CsrWifiRouterCtrlPeerUpdateCfmSizeof, CsrWifiRouterCtrlPeerUpdateCfmSer, CsrWifiRouterCtrlPeerUpdateCfmDes, CsrWifiRouterCtrlPeerUpdateCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_CFM, CsrWifiRouterCtrlCapabilitiesCfmSizeof, CsrWifiRouterCtrlCapabilitiesCfmSer, CsrWifiRouterCtrlCapabilitiesCfmDes, CsrWifiRouterCtrlCapabilitiesCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_CFM, CsrWifiRouterCtrlBlockAckEnableCfmSizeof, CsrWifiRouterCtrlBlockAckEnableCfmSer, CsrWifiRouterCtrlBlockAckEnableCfmDes, CsrWifiRouterCtrlBlockAckEnableCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, CsrWifiRouterCtrlBlockAckDisableCfmSizeof, CsrWifiRouterCtrlBlockAckDisableCfmSer, CsrWifiRouterCtrlBlockAckDisableCfmDes, CsrWifiRouterCtrlBlockAckDisableCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, CsrWifiRouterCtrlBlockAckErrorIndSizeof, CsrWifiRouterCtrlBlockAckErrorIndSer, CsrWifiRouterCtrlBlockAckErrorIndDes, CsrWifiRouterCtrlBlockAckErrorIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, CsrWifiRouterCtrlStaInactiveIndSizeof, CsrWifiRouterCtrlStaInactiveIndSer, CsrWifiRouterCtrlStaInactiveIndDes, CsrWifiRouterCtrlStaInactiveIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, CsrWifiRouterCtrlWapiMulticastIndSizeof, CsrWifiRouterCtrlWapiMulticastIndSer, CsrWifiRouterCtrlWapiMulticastIndDes, CsrWifiRouterCtrlWapiMulticastIndSerFree }, + + { 0, NULL, NULL, NULL, NULL }, +}; + +CsrMsgConvMsgEntry* CsrWifiRouterCtrlConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint16 msgType) +{ + if (msgType & CSR_PRIM_UPSTREAM) + { + CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT; + if (index < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) && + csrwifirouterctrl_conv_lut[index].msgType == msgType) + { + return &csrwifirouterctrl_conv_lut[index]; + } + } + else + { + if (msgType < CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT && + csrwifirouterctrl_conv_lut[msgType].msgType == msgType) + { + return &csrwifirouterctrl_conv_lut[msgType]; + } + } + return NULL; +} + + +void CsrWifiRouterCtrlConverterInit(void) +{ + CsrMsgConvInsert(CSR_WIFI_ROUTER_CTRL_PRIM, csrwifirouterctrl_conv_lut); + CsrMsgConvCustomLookupRegister(CSR_WIFI_ROUTER_CTRL_PRIM, CsrWifiRouterCtrlConverterLookup); +} + + +#ifdef CSR_LOG_ENABLE +static const CsrLogPrimitiveInformation csrwifirouterctrl_conv_info = { + CSR_WIFI_ROUTER_CTRL_PRIM, + (CsrCharString *)"CSR_WIFI_ROUTER_CTRL_PRIM", + csrwifirouterctrl_conv_lut +}; +const CsrLogPrimitiveInformation* CsrWifiRouterCtrlTechInfoGet(void) +{ + return &csrwifirouterctrl_conv_info; +} + + +#endif /* CSR_LOG_ENABLE */ +#endif /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h new file mode 100644 index 000000000000..0c9d26b7a0b4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h @@ -0,0 +1,42 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ +#define CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE + +#include "csr_msgconv.h" + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" + +extern const CsrLogPrimitiveInformation* CsrWifiRouterCtrlTechInfoGet(void); +#endif /* CSR_LOG_ENABLE */ + +extern void CsrWifiRouterCtrlConverterInit(void); + +#else /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */ + +#define CsrWifiRouterCtrlConverterInit() + +#endif /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c new file mode 100644 index 000000000000..57aa36739590 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c @@ -0,0 +1,95 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_router_ctrl_prim.h" +#include "csr_wifi_router_ctrl_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiRouterCtrlFreeDownstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_ROUTER_CTRL_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiRouterCtrlFreeDownstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_ROUTER_CTRL_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiRouterCtrlPrim *) message)) + { + case CSR_WIFI_ROUTER_CTRL_HIP_REQ: + { + CsrWifiRouterCtrlHipReq *p = (CsrWifiRouterCtrlHipReq *)message; + CsrPmemFree(p->mlmeCommand); + p->mlmeCommand = NULL; + CsrPmemFree(p->dataRef1); + p->dataRef1 = NULL; + CsrPmemFree(p->dataRef2); + p->dataRef2 = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES: + { + CsrWifiRouterCtrlMulticastAddressRes *p = (CsrWifiRouterCtrlMulticastAddressRes *)message; + CsrPmemFree(p->getAddresses); + p->getAddresses = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ: + { + CsrWifiRouterCtrlTclasAddReq *p = (CsrWifiRouterCtrlTclasAddReq *)message; + CsrPmemFree(p->tclas); + p->tclas = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ: + { + CsrWifiRouterCtrlTclasDelReq *p = (CsrWifiRouterCtrlTclasDelReq *)message; + CsrPmemFree(p->tclas); + p->tclas = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES: + { + CsrWifiRouterCtrlWifiOnRes *p = (CsrWifiRouterCtrlWifiOnRes *)message; + CsrPmemFree(p->smeVersions.smeBuild); + p->smeVersions.smeBuild = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ: + { + CsrWifiRouterCtrlWapiMulticastReq *p = (CsrWifiRouterCtrlWapiMulticastReq *)message; + CsrPmemFree(p->signal); + p->signal = NULL; + CsrPmemFree(p->data); + p->data = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c new file mode 100644 index 000000000000..25e327357a32 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c @@ -0,0 +1,81 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_router_ctrl_prim.h" +#include "csr_wifi_router_ctrl_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiRouterCtrlFreeUpstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_ROUTER_CTRL_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiRouterCtrlFreeUpstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_ROUTER_CTRL_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiRouterCtrlPrim *) message)) + { + case CSR_WIFI_ROUTER_CTRL_HIP_IND: + { + CsrWifiRouterCtrlHipInd *p = (CsrWifiRouterCtrlHipInd *)message; + CsrPmemFree(p->mlmeCommand); + p->mlmeCommand = NULL; + CsrPmemFree(p->dataRef1); + p->dataRef1 = NULL; + CsrPmemFree(p->dataRef2); + p->dataRef2 = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND: + { + CsrWifiRouterCtrlMulticastAddressInd *p = (CsrWifiRouterCtrlMulticastAddressInd *)message; + CsrPmemFree(p->setAddresses); + p->setAddresses = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND: + { + CsrWifiRouterCtrlWifiOnInd *p = (CsrWifiRouterCtrlWifiOnInd *)message; + CsrPmemFree(p->versions.routerBuild); + p->versions.routerBuild = NULL; + break; + } + case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND: + { + CsrWifiRouterCtrlWapiMulticastInd *p = (CsrWifiRouterCtrlWapiMulticastInd *)message; + CsrPmemFree(p->signal); + p->signal = NULL; + CsrPmemFree(p->data); + p->data = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h new file mode 100644 index 000000000000..f0ad836b00c5 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h @@ -0,0 +1,1958 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_CTRL_LIB_H__ +#define CSR_WIFI_ROUTER_CTRL_LIB_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_sched.h" +#include "csr_util.h" +#include "csr_msg_transport.h" + +#include "csr_wifi_lib.h" + +#include "csr_wifi_router_ctrl_prim.h" +#include "csr_wifi_router_task.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiRouterCtrlFreeUpstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_ROUTER_CTRL upstream message. Does not + * free the message itself, and can only be used for upstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_ROUTER_CTRL upstream message + *----------------------------------------------------------------------------*/ +void CsrWifiRouterCtrlFreeUpstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * CsrWifiRouterCtrlFreeDownstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_ROUTER_CTRL downstream message. Does not + * free the message itself, and can only be used for downstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_ROUTER_CTRL downstream message + *----------------------------------------------------------------------------*/ +void CsrWifiRouterCtrlFreeDownstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * Enum to string functions + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiRouterCtrlBlockAckRoleToString(CsrWifiRouterCtrlBlockAckRole value); +const CsrCharString* CsrWifiRouterCtrlControlIndicationToString(CsrWifiRouterCtrlControlIndication value); +const CsrCharString* CsrWifiRouterCtrlListActionToString(CsrWifiRouterCtrlListAction value); +const CsrCharString* CsrWifiRouterCtrlLowPowerModeToString(CsrWifiRouterCtrlLowPowerMode value); +const CsrCharString* CsrWifiRouterCtrlMediaStatusToString(CsrWifiRouterCtrlMediaStatus value); +const CsrCharString* CsrWifiRouterCtrlModeToString(CsrWifiRouterCtrlMode value); +const CsrCharString* CsrWifiRouterCtrlPeerStatusToString(CsrWifiRouterCtrlPeerStatus value); +const CsrCharString* CsrWifiRouterCtrlPortActionToString(CsrWifiRouterCtrlPortAction value); +const CsrCharString* CsrWifiRouterCtrlPowersaveTypeToString(CsrWifiRouterCtrlPowersaveType value); +const CsrCharString* CsrWifiRouterCtrlProtocolDirectionToString(CsrWifiRouterCtrlProtocolDirection value); +const CsrCharString* CsrWifiRouterCtrlQoSControlToString(CsrWifiRouterCtrlQoSControl value); +const CsrCharString* CsrWifiRouterCtrlQueueConfigToString(CsrWifiRouterCtrlQueueConfig value); +const CsrCharString* CsrWifiRouterCtrlTrafficConfigTypeToString(CsrWifiRouterCtrlTrafficConfigType value); +const CsrCharString* CsrWifiRouterCtrlTrafficPacketTypeToString(CsrWifiRouterCtrlTrafficPacketType value); +const CsrCharString* CsrWifiRouterCtrlTrafficTypeToString(CsrWifiRouterCtrlTrafficType value); + + +/*----------------------------------------------------------------------------* + * CsrPrim Type toString function. + * Converts a message type to the String name of the Message + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiRouterCtrlPrimTypeToString(CsrPrim msgType); + +/*----------------------------------------------------------------------------* + * Lookup arrays for PrimType name Strings + *----------------------------------------------------------------------------*/ +extern const CsrCharString *CsrWifiRouterCtrlUpstreamPrimNames[CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT]; +extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT]; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckDisableReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + macAddress - + trafficStreamID - + role - + +*******************************************************************************/ +#define CsrWifiRouterCtrlBlockAckDisableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) \ + msg__ = (CsrWifiRouterCtrlBlockAckDisableReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckDisableReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->macAddress = (macAddress__); \ + msg__->trafficStreamID = (trafficStreamID__); \ + msg__->role = (role__); + +#define CsrWifiRouterCtrlBlockAckDisableReqSendTo(dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) \ + { \ + CsrWifiRouterCtrlBlockAckDisableReq *msg__; \ + CsrWifiRouterCtrlBlockAckDisableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlBlockAckDisableReqSend(src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) \ + CsrWifiRouterCtrlBlockAckDisableReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckDisableCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlBlockAckDisableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterCtrlBlockAckDisableCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckDisableCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlBlockAckDisableCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \ + { \ + CsrWifiRouterCtrlBlockAckDisableCfm *msg__; \ + CsrWifiRouterCtrlBlockAckDisableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlBlockAckDisableCfmSend(dst__, clientData__, interfaceTag__, status__) \ + CsrWifiRouterCtrlBlockAckDisableCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckEnableReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + macAddress - + trafficStreamID - + role - + bufferSize - + timeout - + ssn - + +*******************************************************************************/ +#define CsrWifiRouterCtrlBlockAckEnableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) \ + msg__ = (CsrWifiRouterCtrlBlockAckEnableReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckEnableReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->macAddress = (macAddress__); \ + msg__->trafficStreamID = (trafficStreamID__); \ + msg__->role = (role__); \ + msg__->bufferSize = (bufferSize__); \ + msg__->timeout = (timeout__); \ + msg__->ssn = (ssn__); + +#define CsrWifiRouterCtrlBlockAckEnableReqSendTo(dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) \ + { \ + CsrWifiRouterCtrlBlockAckEnableReq *msg__; \ + CsrWifiRouterCtrlBlockAckEnableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlBlockAckEnableReqSend(src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) \ + CsrWifiRouterCtrlBlockAckEnableReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckEnableCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlBlockAckEnableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterCtrlBlockAckEnableCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckEnableCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlBlockAckEnableCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \ + { \ + CsrWifiRouterCtrlBlockAckEnableCfm *msg__; \ + CsrWifiRouterCtrlBlockAckEnableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlBlockAckEnableCfmSend(dst__, clientData__, interfaceTag__, status__) \ + CsrWifiRouterCtrlBlockAckEnableCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckErrorIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + trafficStreamID - + peerMacAddress - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlBlockAckErrorIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) \ + msg__ = (CsrWifiRouterCtrlBlockAckErrorInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckErrorInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->trafficStreamID = (trafficStreamID__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlBlockAckErrorIndSendTo(dst__, src__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) \ + { \ + CsrWifiRouterCtrlBlockAckErrorInd *msg__; \ + CsrWifiRouterCtrlBlockAckErrorIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlBlockAckErrorIndSend(dst__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) \ + CsrWifiRouterCtrlBlockAckErrorIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlCapabilitiesReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlCapabilitiesReqCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlCapabilitiesReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlCapabilitiesReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlCapabilitiesReqSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlCapabilitiesReq *msg__; \ + CsrWifiRouterCtrlCapabilitiesReqCreate(msg__, dst__, src__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlCapabilitiesReqSend(src__, clientData__) \ + CsrWifiRouterCtrlCapabilitiesReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlCapabilitiesCfmSend + + DESCRIPTION + The router sends this primitive to confirm the size of the queues of the + HIP. + + PARAMETERS + queue - Destination Task Queue + clientData - + commandQueueSize - Size of command queue + trafficQueueSize - Size of traffic queue (per AC) + +*******************************************************************************/ +#define CsrWifiRouterCtrlCapabilitiesCfmCreate(msg__, dst__, src__, clientData__, commandQueueSize__, trafficQueueSize__) \ + msg__ = (CsrWifiRouterCtrlCapabilitiesCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlCapabilitiesCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CAPABILITIES_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->commandQueueSize = (commandQueueSize__); \ + msg__->trafficQueueSize = (trafficQueueSize__); + +#define CsrWifiRouterCtrlCapabilitiesCfmSendTo(dst__, src__, clientData__, commandQueueSize__, trafficQueueSize__) \ + { \ + CsrWifiRouterCtrlCapabilitiesCfm *msg__; \ + CsrWifiRouterCtrlCapabilitiesCfmCreate(msg__, dst__, src__, clientData__, commandQueueSize__, trafficQueueSize__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlCapabilitiesCfmSend(dst__, clientData__, commandQueueSize__, trafficQueueSize__) \ + CsrWifiRouterCtrlCapabilitiesCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, commandQueueSize__, trafficQueueSize__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlConfigurePowerModeReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + clientData - + mode - + wakeHost - + +*******************************************************************************/ +#define CsrWifiRouterCtrlConfigurePowerModeReqCreate(msg__, dst__, src__, clientData__, mode__, wakeHost__) \ + msg__ = (CsrWifiRouterCtrlConfigurePowerModeReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlConfigurePowerModeReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CONFIGURE_POWER_MODE_REQ, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->mode = (mode__); \ + msg__->wakeHost = (wakeHost__); + +#define CsrWifiRouterCtrlConfigurePowerModeReqSendTo(dst__, src__, clientData__, mode__, wakeHost__) \ + { \ + CsrWifiRouterCtrlConfigurePowerModeReq *msg__; \ + CsrWifiRouterCtrlConfigurePowerModeReqCreate(msg__, dst__, src__, clientData__, mode__, wakeHost__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlConfigurePowerModeReqSend(src__, clientData__, mode__, wakeHost__) \ + CsrWifiRouterCtrlConfigurePowerModeReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, mode__, wakeHost__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlConnectedIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + peerMacAddress - + peerStatus - + +*******************************************************************************/ +#define CsrWifiRouterCtrlConnectedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) \ + msg__ = (CsrWifiRouterCtrlConnectedInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlConnectedInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CONNECTED_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->peerStatus = (peerStatus__); + +#define CsrWifiRouterCtrlConnectedIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) \ + { \ + CsrWifiRouterCtrlConnectedInd *msg__; \ + CsrWifiRouterCtrlConnectedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlConnectedIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) \ + CsrWifiRouterCtrlConnectedIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlHipReqSend + + DESCRIPTION + This primitive is used for transferring MLME messages to the HIP. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + mlmeCommandLength - Length of the MLME signal + mlmeCommand - Pointer to the MLME signal + dataRef1Length - Length of the dataRef1 bulk data + dataRef1 - Pointer to the bulk data 1 + dataRef2Length - Length of the dataRef2 bulk data + dataRef2 - Pointer to the bulk data 2 + +*******************************************************************************/ +#define CsrWifiRouterCtrlHipReqCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \ + msg__ = (CsrWifiRouterCtrlHipReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlHipReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_HIP_REQ, dst__, src__); \ + msg__->mlmeCommandLength = (mlmeCommandLength__); \ + msg__->mlmeCommand = (mlmeCommand__); \ + msg__->dataRef1Length = (dataRef1Length__); \ + msg__->dataRef1 = (dataRef1__); \ + msg__->dataRef2Length = (dataRef2Length__); \ + msg__->dataRef2 = (dataRef2__); + +#define CsrWifiRouterCtrlHipReqSendTo(dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \ + { \ + CsrWifiRouterCtrlHipReq *msg__; \ + CsrWifiRouterCtrlHipReqCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlHipReqSend(src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \ + CsrWifiRouterCtrlHipReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlHipIndSend + + DESCRIPTION + This primitive is used for transferring MLME messages from the HIP. + + PARAMETERS + queue - Destination Task Queue + mlmeCommandLength - Length of the MLME signal + mlmeCommand - Pointer to the MLME signal + dataRef1Length - Length of the dataRef1 bulk data + dataRef1 - Pointer to the bulk data 1 + dataRef2Length - Length of the dataRef2 bulk data + dataRef2 - Pointer to the bulk data 2 + +*******************************************************************************/ +#define CsrWifiRouterCtrlHipIndCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \ + msg__ = (CsrWifiRouterCtrlHipInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlHipInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_HIP_IND, dst__, src__); \ + msg__->mlmeCommandLength = (mlmeCommandLength__); \ + msg__->mlmeCommand = (mlmeCommand__); \ + msg__->dataRef1Length = (dataRef1Length__); \ + msg__->dataRef1 = (dataRef1__); \ + msg__->dataRef2Length = (dataRef2Length__); \ + msg__->dataRef2 = (dataRef2__); + +#define CsrWifiRouterCtrlHipIndSendTo(dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \ + { \ + CsrWifiRouterCtrlHipInd *msg__; \ + CsrWifiRouterCtrlHipIndCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlHipIndSend(dst__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \ + CsrWifiRouterCtrlHipIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlM4ReadyToSendIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + peerMacAddress - + +*******************************************************************************/ +#define CsrWifiRouterCtrlM4ReadyToSendIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \ + msg__ = (CsrWifiRouterCtrlM4ReadyToSendInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlM4ReadyToSendInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_M4_READY_TO_SEND_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); + +#define CsrWifiRouterCtrlM4ReadyToSendIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \ + { \ + CsrWifiRouterCtrlM4ReadyToSendInd *msg__; \ + CsrWifiRouterCtrlM4ReadyToSendIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlM4ReadyToSendIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__) \ + CsrWifiRouterCtrlM4ReadyToSendIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlM4TransmitReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlM4TransmitReqCreate(msg__, dst__, src__, interfaceTag__, clientData__) \ + msg__ = (CsrWifiRouterCtrlM4TransmitReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlM4TransmitReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_M4_TRANSMIT_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlM4TransmitReqSendTo(dst__, src__, interfaceTag__, clientData__) \ + { \ + CsrWifiRouterCtrlM4TransmitReq *msg__; \ + CsrWifiRouterCtrlM4TransmitReqCreate(msg__, dst__, src__, interfaceTag__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlM4TransmitReqSend(src__, interfaceTag__, clientData__) \ + CsrWifiRouterCtrlM4TransmitReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlM4TransmittedIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + peerMacAddress - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlM4TransmittedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, status__) \ + msg__ = (CsrWifiRouterCtrlM4TransmittedInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlM4TransmittedInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_M4_TRANSMITTED_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlM4TransmittedIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, status__) \ + { \ + CsrWifiRouterCtrlM4TransmittedInd *msg__; \ + CsrWifiRouterCtrlM4TransmittedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlM4TransmittedIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__, status__) \ + CsrWifiRouterCtrlM4TransmittedIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMediaStatusReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + mediaStatus - + +*******************************************************************************/ +#define CsrWifiRouterCtrlMediaStatusReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mediaStatus__) \ + msg__ = (CsrWifiRouterCtrlMediaStatusReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMediaStatusReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->mediaStatus = (mediaStatus__); + +#define CsrWifiRouterCtrlMediaStatusReqSendTo(dst__, src__, interfaceTag__, clientData__, mediaStatus__) \ + { \ + CsrWifiRouterCtrlMediaStatusReq *msg__; \ + CsrWifiRouterCtrlMediaStatusReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mediaStatus__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlMediaStatusReqSend(src__, interfaceTag__, clientData__, mediaStatus__) \ + CsrWifiRouterCtrlMediaStatusReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, mediaStatus__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMicFailureIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + peerMacAddress - + unicastPdu - + +*******************************************************************************/ +#define CsrWifiRouterCtrlMicFailureIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) \ + msg__ = (CsrWifiRouterCtrlMicFailureInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMicFailureInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MIC_FAILURE_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->unicastPdu = (unicastPdu__); + +#define CsrWifiRouterCtrlMicFailureIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) \ + { \ + CsrWifiRouterCtrlMicFailureInd *msg__; \ + CsrWifiRouterCtrlMicFailureIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlMicFailureIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) \ + CsrWifiRouterCtrlMicFailureIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlModeSetReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + mode - + bssid - BSSID of the network the device is going to be a part + of + protection - Set to TRUE if encryption is enabled for the + connection/broadcast frames + intraBssDistEnabled - If set to TRUE, intra BSS destribution will be + enabled. If set to FALSE, any unicast PDU which does + not have the RA as the the local MAC address, shall be + ignored. This field is interpreted by the receive if + mode is set to CSR_WIFI_ROUTER_CTRL_MODE_P2PGO + +*******************************************************************************/ +#define CsrWifiRouterCtrlModeSetReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \ + msg__ = (CsrWifiRouterCtrlModeSetReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MODE_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->mode = (mode__); \ + msg__->bssid = (bssid__); \ + msg__->protection = (protection__); \ + msg__->intraBssDistEnabled = (intraBssDistEnabled__); + +#define CsrWifiRouterCtrlModeSetReqSendTo(dst__, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \ + { \ + CsrWifiRouterCtrlModeSetReq *msg__; \ + CsrWifiRouterCtrlModeSetReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlModeSetReqSend(src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \ + CsrWifiRouterCtrlModeSetReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMulticastAddressIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + action - + setAddressesCount - + setAddresses - + +*******************************************************************************/ +#define CsrWifiRouterCtrlMulticastAddressIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \ + msg__ = (CsrWifiRouterCtrlMulticastAddressInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMulticastAddressInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->action = (action__); \ + msg__->setAddressesCount = (setAddressesCount__); \ + msg__->setAddresses = (setAddresses__); + +#define CsrWifiRouterCtrlMulticastAddressIndSendTo(dst__, src__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \ + { \ + CsrWifiRouterCtrlMulticastAddressInd *msg__; \ + CsrWifiRouterCtrlMulticastAddressIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlMulticastAddressIndSend(dst__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \ + CsrWifiRouterCtrlMulticastAddressIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMulticastAddressResSend + + DESCRIPTION + + PARAMETERS + interfaceTag - + clientData - + status - + action - + getAddressesCount - + getAddresses - + +*******************************************************************************/ +#define CsrWifiRouterCtrlMulticastAddressResCreate(msg__, dst__, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) \ + msg__ = (CsrWifiRouterCtrlMulticastAddressRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMulticastAddressRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->status = (status__); \ + msg__->action = (action__); \ + msg__->getAddressesCount = (getAddressesCount__); \ + msg__->getAddresses = (getAddresses__); + +#define CsrWifiRouterCtrlMulticastAddressResSendTo(dst__, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) \ + { \ + CsrWifiRouterCtrlMulticastAddressRes *msg__; \ + CsrWifiRouterCtrlMulticastAddressResCreate(msg__, dst__, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlMulticastAddressResSend(src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) \ + CsrWifiRouterCtrlMulticastAddressResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerAddReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + peerMacAddress - + associationId - + staInfo - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPeerAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) \ + msg__ = (CsrWifiRouterCtrlPeerAddReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerAddReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_ADD_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->associationId = (associationId__); \ + msg__->staInfo = (staInfo__); + +#define CsrWifiRouterCtrlPeerAddReqSendTo(dst__, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) \ + { \ + CsrWifiRouterCtrlPeerAddReq *msg__; \ + CsrWifiRouterCtrlPeerAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPeerAddReqSend(src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) \ + CsrWifiRouterCtrlPeerAddReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerAddCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + peerMacAddress - + peerRecordHandle - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPeerAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) \ + msg__ = (CsrWifiRouterCtrlPeerAddCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerAddCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_ADD_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->peerRecordHandle = (peerRecordHandle__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlPeerAddCfmSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) \ + { \ + CsrWifiRouterCtrlPeerAddCfm *msg__; \ + CsrWifiRouterCtrlPeerAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPeerAddCfmSend(dst__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) \ + CsrWifiRouterCtrlPeerAddCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerDelReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + peerRecordHandle - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPeerDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__) \ + msg__ = (CsrWifiRouterCtrlPeerDelReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerDelReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_DEL_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->peerRecordHandle = (peerRecordHandle__); + +#define CsrWifiRouterCtrlPeerDelReqSendTo(dst__, src__, interfaceTag__, clientData__, peerRecordHandle__) \ + { \ + CsrWifiRouterCtrlPeerDelReq *msg__; \ + CsrWifiRouterCtrlPeerDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPeerDelReqSend(src__, interfaceTag__, clientData__, peerRecordHandle__) \ + CsrWifiRouterCtrlPeerDelReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, peerRecordHandle__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerDelCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPeerDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterCtrlPeerDelCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerDelCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_DEL_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlPeerDelCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \ + { \ + CsrWifiRouterCtrlPeerDelCfm *msg__; \ + CsrWifiRouterCtrlPeerDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPeerDelCfmSend(dst__, clientData__, interfaceTag__, status__) \ + CsrWifiRouterCtrlPeerDelCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerUpdateReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + peerRecordHandle - + powersaveMode - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPeerUpdateReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) \ + msg__ = (CsrWifiRouterCtrlPeerUpdateReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerUpdateReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->peerRecordHandle = (peerRecordHandle__); \ + msg__->powersaveMode = (powersaveMode__); + +#define CsrWifiRouterCtrlPeerUpdateReqSendTo(dst__, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) \ + { \ + CsrWifiRouterCtrlPeerUpdateReq *msg__; \ + CsrWifiRouterCtrlPeerUpdateReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPeerUpdateReqSend(src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) \ + CsrWifiRouterCtrlPeerUpdateReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerUpdateCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPeerUpdateCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterCtrlPeerUpdateCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerUpdateCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlPeerUpdateCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \ + { \ + CsrWifiRouterCtrlPeerUpdateCfm *msg__; \ + CsrWifiRouterCtrlPeerUpdateCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPeerUpdateCfmSend(dst__, clientData__, interfaceTag__, status__) \ + CsrWifiRouterCtrlPeerUpdateCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPortConfigureReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + uncontrolledPortAction - + controlledPortAction - + macAddress - + setProtection - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPortConfigureReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) \ + msg__ = (CsrWifiRouterCtrlPortConfigureReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPortConfigureReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->uncontrolledPortAction = (uncontrolledPortAction__); \ + msg__->controlledPortAction = (controlledPortAction__); \ + msg__->macAddress = (macAddress__); \ + msg__->setProtection = (setProtection__); + +#define CsrWifiRouterCtrlPortConfigureReqSendTo(dst__, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) \ + { \ + CsrWifiRouterCtrlPortConfigureReq *msg__; \ + CsrWifiRouterCtrlPortConfigureReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPortConfigureReqSend(src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) \ + CsrWifiRouterCtrlPortConfigureReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPortConfigureCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + macAddress - + +*******************************************************************************/ +#define CsrWifiRouterCtrlPortConfigureCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__, macAddress__) \ + msg__ = (CsrWifiRouterCtrlPortConfigureCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPortConfigureCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->macAddress = (macAddress__); + +#define CsrWifiRouterCtrlPortConfigureCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__, macAddress__) \ + { \ + CsrWifiRouterCtrlPortConfigureCfm *msg__; \ + CsrWifiRouterCtrlPortConfigureCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__, macAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlPortConfigureCfmSend(dst__, clientData__, interfaceTag__, status__, macAddress__) \ + CsrWifiRouterCtrlPortConfigureCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__, macAddress__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlQosControlReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + control - + queueConfig - + +*******************************************************************************/ +#define CsrWifiRouterCtrlQosControlReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, control__, queueConfig__) \ + msg__ = (CsrWifiRouterCtrlQosControlReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlQosControlReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->control = (control__); \ + msg__->queueConfig = (queueConfig__); + +#define CsrWifiRouterCtrlQosControlReqSendTo(dst__, src__, interfaceTag__, clientData__, control__, queueConfig__) \ + { \ + CsrWifiRouterCtrlQosControlReq *msg__; \ + CsrWifiRouterCtrlQosControlReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, control__, queueConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlQosControlReqSend(src__, interfaceTag__, clientData__, control__, queueConfig__) \ + CsrWifiRouterCtrlQosControlReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, control__, queueConfig__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioDeinitialiseReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlRawSdioDeinitialiseReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlRawSdioDeinitialiseReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_REQ, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlRawSdioDeinitialiseReq *msg__; \ + CsrWifiRouterCtrlRawSdioDeinitialiseReqCreate(msg__, dst__, src__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSend(src__, clientData__) \ + CsrWifiRouterCtrlRawSdioDeinitialiseReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioDeinitialiseCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + result - + +*******************************************************************************/ +#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmCreate(msg__, dst__, src__, clientData__, result__) \ + msg__ = (CsrWifiRouterCtrlRawSdioDeinitialiseCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlRawSdioDeinitialiseCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->result = (result__); + +#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmSendTo(dst__, src__, clientData__, result__) \ + { \ + CsrWifiRouterCtrlRawSdioDeinitialiseCfm *msg__; \ + CsrWifiRouterCtrlRawSdioDeinitialiseCfmCreate(msg__, dst__, src__, clientData__, result__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmSend(dst__, clientData__, result__) \ + CsrWifiRouterCtrlRawSdioDeinitialiseCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, result__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioInitialiseReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlRawSdioInitialiseReqCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlRawSdioInitialiseReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlRawSdioInitialiseReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_REQ, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlRawSdioInitialiseReqSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlRawSdioInitialiseReq *msg__; \ + CsrWifiRouterCtrlRawSdioInitialiseReqCreate(msg__, dst__, src__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlRawSdioInitialiseReqSend(src__, clientData__) \ + CsrWifiRouterCtrlRawSdioInitialiseReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioInitialiseCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + result - + byteRead - + byteWrite - + firmwareDownload - + reset - + coreDumpPrepare - + byteBlockRead - + gpRead16 - + gpWrite16 - + +*******************************************************************************/ +#define CsrWifiRouterCtrlRawSdioInitialiseCfmCreate(msg__, dst__, src__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) \ + msg__ = (CsrWifiRouterCtrlRawSdioInitialiseCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlRawSdioInitialiseCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->result = (result__); \ + msg__->byteRead = (byteRead__); \ + msg__->byteWrite = (byteWrite__); \ + msg__->firmwareDownload = (firmwareDownload__); \ + msg__->reset = (reset__); \ + msg__->coreDumpPrepare = (coreDumpPrepare__); \ + msg__->byteBlockRead = (byteBlockRead__); \ + msg__->gpRead16 = (gpRead16__); \ + msg__->gpWrite16 = (gpWrite16__); + +#define CsrWifiRouterCtrlRawSdioInitialiseCfmSendTo(dst__, src__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) \ + { \ + CsrWifiRouterCtrlRawSdioInitialiseCfm *msg__; \ + CsrWifiRouterCtrlRawSdioInitialiseCfmCreate(msg__, dst__, src__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlRawSdioInitialiseCfmSend(dst__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) \ + CsrWifiRouterCtrlRawSdioInitialiseCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlResumeIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + powerMaintained - + +*******************************************************************************/ +#define CsrWifiRouterCtrlResumeIndCreate(msg__, dst__, src__, clientData__, powerMaintained__) \ + msg__ = (CsrWifiRouterCtrlResumeInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlResumeInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RESUME_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->powerMaintained = (powerMaintained__); + +#define CsrWifiRouterCtrlResumeIndSendTo(dst__, src__, clientData__, powerMaintained__) \ + { \ + CsrWifiRouterCtrlResumeInd *msg__; \ + CsrWifiRouterCtrlResumeIndCreate(msg__, dst__, src__, clientData__, powerMaintained__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlResumeIndSend(dst__, clientData__, powerMaintained__) \ + CsrWifiRouterCtrlResumeIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, powerMaintained__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlResumeResSend + + DESCRIPTION + + PARAMETERS + clientData - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlResumeResCreate(msg__, dst__, src__, clientData__, status__) \ + msg__ = (CsrWifiRouterCtrlResumeRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlResumeRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RESUME_RES, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlResumeResSendTo(dst__, src__, clientData__, status__) \ + { \ + CsrWifiRouterCtrlResumeRes *msg__; \ + CsrWifiRouterCtrlResumeResCreate(msg__, dst__, src__, clientData__, status__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlResumeResSend(src__, clientData__, status__) \ + CsrWifiRouterCtrlResumeResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlStaInactiveIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + staAddress - + +*******************************************************************************/ +#define CsrWifiRouterCtrlStaInactiveIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, staAddress__) \ + msg__ = (CsrWifiRouterCtrlStaInactiveInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlStaInactiveInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->staAddress = (staAddress__); + +#define CsrWifiRouterCtrlStaInactiveIndSendTo(dst__, src__, clientData__, interfaceTag__, staAddress__) \ + { \ + CsrWifiRouterCtrlStaInactiveInd *msg__; \ + CsrWifiRouterCtrlStaInactiveIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, staAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlStaInactiveIndSend(dst__, clientData__, interfaceTag__, staAddress__) \ + CsrWifiRouterCtrlStaInactiveIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, staAddress__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlSuspendIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + hardSuspend - + d3Suspend - + +*******************************************************************************/ +#define CsrWifiRouterCtrlSuspendIndCreate(msg__, dst__, src__, clientData__, hardSuspend__, d3Suspend__) \ + msg__ = (CsrWifiRouterCtrlSuspendInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlSuspendInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_SUSPEND_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->hardSuspend = (hardSuspend__); \ + msg__->d3Suspend = (d3Suspend__); + +#define CsrWifiRouterCtrlSuspendIndSendTo(dst__, src__, clientData__, hardSuspend__, d3Suspend__) \ + { \ + CsrWifiRouterCtrlSuspendInd *msg__; \ + CsrWifiRouterCtrlSuspendIndCreate(msg__, dst__, src__, clientData__, hardSuspend__, d3Suspend__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlSuspendIndSend(dst__, clientData__, hardSuspend__, d3Suspend__) \ + CsrWifiRouterCtrlSuspendIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, hardSuspend__, d3Suspend__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlSuspendResSend + + DESCRIPTION + + PARAMETERS + clientData - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlSuspendResCreate(msg__, dst__, src__, clientData__, status__) \ + msg__ = (CsrWifiRouterCtrlSuspendRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlSuspendRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_SUSPEND_RES, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlSuspendResSendTo(dst__, src__, clientData__, status__) \ + { \ + CsrWifiRouterCtrlSuspendRes *msg__; \ + CsrWifiRouterCtrlSuspendResCreate(msg__, dst__, src__, clientData__, status__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlSuspendResSend(src__, clientData__, status__) \ + CsrWifiRouterCtrlSuspendResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasAddReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + tclasLength - + tclas - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTclasAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \ + msg__ = (CsrWifiRouterCtrlTclasAddReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasAddReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->tclasLength = (tclasLength__); \ + msg__->tclas = (tclas__); + +#define CsrWifiRouterCtrlTclasAddReqSendTo(dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \ + { \ + CsrWifiRouterCtrlTclasAddReq *msg__; \ + CsrWifiRouterCtrlTclasAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTclasAddReqSend(src__, interfaceTag__, clientData__, tclasLength__, tclas__) \ + CsrWifiRouterCtrlTclasAddReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, tclasLength__, tclas__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasAddCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTclasAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterCtrlTclasAddCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasAddCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlTclasAddCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \ + { \ + CsrWifiRouterCtrlTclasAddCfm *msg__; \ + CsrWifiRouterCtrlTclasAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTclasAddCfmSend(dst__, clientData__, interfaceTag__, status__) \ + CsrWifiRouterCtrlTclasAddCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasDelReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + tclasLength - + tclas - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTclasDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \ + msg__ = (CsrWifiRouterCtrlTclasDelReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasDelReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->tclasLength = (tclasLength__); \ + msg__->tclas = (tclas__); + +#define CsrWifiRouterCtrlTclasDelReqSendTo(dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \ + { \ + CsrWifiRouterCtrlTclasDelReq *msg__; \ + CsrWifiRouterCtrlTclasDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTclasDelReqSend(src__, interfaceTag__, clientData__, tclasLength__, tclas__) \ + CsrWifiRouterCtrlTclasDelReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, tclasLength__, tclas__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasDelCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTclasDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterCtrlTclasDelCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasDelCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlTclasDelCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \ + { \ + CsrWifiRouterCtrlTclasDelCfm *msg__; \ + CsrWifiRouterCtrlTclasDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTclasDelCfmSend(dst__, clientData__, interfaceTag__, status__) \ + CsrWifiRouterCtrlTclasDelCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficClassificationReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + trafficType - + period - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTrafficClassificationReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficType__, period__) \ + msg__ = (CsrWifiRouterCtrlTrafficClassificationReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficClassificationReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CLASSIFICATION_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->trafficType = (trafficType__); \ + msg__->period = (period__); + +#define CsrWifiRouterCtrlTrafficClassificationReqSendTo(dst__, src__, interfaceTag__, clientData__, trafficType__, period__) \ + { \ + CsrWifiRouterCtrlTrafficClassificationReq *msg__; \ + CsrWifiRouterCtrlTrafficClassificationReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficType__, period__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTrafficClassificationReqSend(src__, interfaceTag__, clientData__, trafficType__, period__) \ + CsrWifiRouterCtrlTrafficClassificationReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, trafficType__, period__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficConfigReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + clientData - + trafficConfigType - + config - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTrafficConfigReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficConfigType__, config__) \ + msg__ = (CsrWifiRouterCtrlTrafficConfigReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficConfigReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->clientData = (clientData__); \ + msg__->trafficConfigType = (trafficConfigType__); \ + msg__->config = (config__); + +#define CsrWifiRouterCtrlTrafficConfigReqSendTo(dst__, src__, interfaceTag__, clientData__, trafficConfigType__, config__) \ + { \ + CsrWifiRouterCtrlTrafficConfigReq *msg__; \ + CsrWifiRouterCtrlTrafficConfigReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficConfigType__, config__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTrafficConfigReqSend(src__, interfaceTag__, clientData__, trafficConfigType__, config__) \ + CsrWifiRouterCtrlTrafficConfigReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, trafficConfigType__, config__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficProtocolIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + packetType - + direction - + srcAddress - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTrafficProtocolIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) \ + msg__ = (CsrWifiRouterCtrlTrafficProtocolInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficProtocolInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PROTOCOL_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->packetType = (packetType__); \ + msg__->direction = (direction__); \ + msg__->srcAddress = (srcAddress__); + +#define CsrWifiRouterCtrlTrafficProtocolIndSendTo(dst__, src__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) \ + { \ + CsrWifiRouterCtrlTrafficProtocolInd *msg__; \ + CsrWifiRouterCtrlTrafficProtocolIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTrafficProtocolIndSend(dst__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) \ + CsrWifiRouterCtrlTrafficProtocolIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficSampleIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + stats - + +*******************************************************************************/ +#define CsrWifiRouterCtrlTrafficSampleIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, stats__) \ + msg__ = (CsrWifiRouterCtrlTrafficSampleInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficSampleInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_SAMPLE_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->stats = (stats__); + +#define CsrWifiRouterCtrlTrafficSampleIndSendTo(dst__, src__, clientData__, interfaceTag__, stats__) \ + { \ + CsrWifiRouterCtrlTrafficSampleInd *msg__; \ + CsrWifiRouterCtrlTrafficSampleIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, stats__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlTrafficSampleIndSend(dst__, clientData__, interfaceTag__, stats__) \ + CsrWifiRouterCtrlTrafficSampleIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, stats__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlUnexpectedFrameIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + peerMacAddress - + +*******************************************************************************/ +#define CsrWifiRouterCtrlUnexpectedFrameIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \ + msg__ = (CsrWifiRouterCtrlUnexpectedFrameInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlUnexpectedFrameInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_UNEXPECTED_FRAME_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); + +#define CsrWifiRouterCtrlUnexpectedFrameIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \ + { \ + CsrWifiRouterCtrlUnexpectedFrameInd *msg__; \ + CsrWifiRouterCtrlUnexpectedFrameIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlUnexpectedFrameIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__) \ + CsrWifiRouterCtrlUnexpectedFrameIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiMulticastFilterReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiRouterCtrlWapiMulticastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastFilterReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, status__) \ + { \ + CsrWifiRouterCtrlWapiMulticastFilterReq *msg__; \ + CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, status__) \ + CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiMulticastReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + signalLength - + signal - + dataLength - + data - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__) \ + msg__ = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, dst__, src__); \ + msg__->signalLength = (signalLength__); \ + msg__->signal = (signal__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); + +#define CsrWifiRouterCtrlWapiMulticastReqSendTo(dst__, src__, signalLength__, signal__, dataLength__, data__) \ + { \ + CsrWifiRouterCtrlWapiMulticastReq *msg__; \ + CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiMulticastReqSend(src__, signalLength__, signal__, dataLength__, data__) \ + CsrWifiRouterCtrlWapiMulticastReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, signalLength__, signal__, dataLength__, data__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiMulticastIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + signalLength - + signal - + dataLength - + data - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + msg__ = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->signalLength = (signalLength__); \ + msg__->signal = (signal__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); + +#define CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + { \ + CsrWifiRouterCtrlWapiMulticastInd *msg__; \ + CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiMulticastIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiUnicastFilterReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiRouterCtrlWapiUnicastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastFilterReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, status__) \ + { \ + CsrWifiRouterCtrlWapiUnicastFilterReq *msg__; \ + CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, status__) \ + CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOffReqCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlWifiOffReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOffReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_REQ, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlWifiOffReqSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlWifiOffReq *msg__; \ + CsrWifiRouterCtrlWifiOffReqCreate(msg__, dst__, src__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOffReqSend(src__, clientData__) \ + CsrWifiRouterCtrlWifiOffReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + controlIndication - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOffIndCreate(msg__, dst__, src__, clientData__, controlIndication__) \ + msg__ = (CsrWifiRouterCtrlWifiOffInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOffInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->controlIndication = (controlIndication__); + +#define CsrWifiRouterCtrlWifiOffIndSendTo(dst__, src__, clientData__, controlIndication__) \ + { \ + CsrWifiRouterCtrlWifiOffInd *msg__; \ + CsrWifiRouterCtrlWifiOffIndCreate(msg__, dst__, src__, clientData__, controlIndication__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOffIndSend(dst__, clientData__, controlIndication__) \ + CsrWifiRouterCtrlWifiOffIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, controlIndication__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffResSend + + DESCRIPTION + + PARAMETERS + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOffResCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlWifiOffRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOffRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_RES, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlWifiOffResSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlWifiOffRes *msg__; \ + CsrWifiRouterCtrlWifiOffResCreate(msg__, dst__, src__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOffResSend(src__, clientData__) \ + CsrWifiRouterCtrlWifiOffResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOffCfmCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlWifiOffCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOffCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_CFM, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlWifiOffCfmSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlWifiOffCfm *msg__; \ + CsrWifiRouterCtrlWifiOffCfmCreate(msg__, dst__, src__, clientData__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOffCfmSend(dst__, clientData__) \ + CsrWifiRouterCtrlWifiOffCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + clientData - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__) \ + msg__ = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, dst__, src__); \ + msg__->clientData = (clientData__); + +#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__) \ + { \ + CsrWifiRouterCtrlWifiOnReq *msg__; \ + CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__) \ + CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + status - + versions - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOnIndCreate(msg__, dst__, src__, clientData__, status__, versions__) \ + msg__ = (CsrWifiRouterCtrlWifiOnInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->status = (status__); \ + msg__->versions = (versions__); + +#define CsrWifiRouterCtrlWifiOnIndSendTo(dst__, src__, clientData__, status__, versions__) \ + { \ + CsrWifiRouterCtrlWifiOnInd *msg__; \ + CsrWifiRouterCtrlWifiOnIndCreate(msg__, dst__, src__, clientData__, status__, versions__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOnIndSend(dst__, clientData__, status__, versions__) \ + CsrWifiRouterCtrlWifiOnIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, status__, versions__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnResSend + + DESCRIPTION + + PARAMETERS + clientData - + status - + numInterfaceAddress - + stationMacAddress - array size 1 MUST match CSR_WIFI_NUM_INTERFACES + smeVersions - + scheduledInterrupt - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOnResCreate(msg__, dst__, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) \ + msg__ = (CsrWifiRouterCtrlWifiOnRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->status = (status__); \ + msg__->numInterfaceAddress = (numInterfaceAddress__); \ + CsrMemCpy(msg__->stationMacAddress, (stationMacAddress__), sizeof(CsrWifiMacAddress) * 2); \ + msg__->smeVersions = (smeVersions__); \ + msg__->scheduledInterrupt = (scheduledInterrupt__); + +#define CsrWifiRouterCtrlWifiOnResSendTo(dst__, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) \ + { \ + CsrWifiRouterCtrlWifiOnRes *msg__; \ + CsrWifiRouterCtrlWifiOnResCreate(msg__, dst__, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOnResSend(src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) \ + CsrWifiRouterCtrlWifiOnResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWifiOnCfmCreate(msg__, dst__, src__, clientData__, status__) \ + msg__ = (CsrWifiRouterCtrlWifiOnCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlWifiOnCfmSendTo(dst__, src__, clientData__, status__) \ + { \ + CsrWifiRouterCtrlWifiOnCfm *msg__; \ + CsrWifiRouterCtrlWifiOnCfmCreate(msg__, dst__, src__, clientData__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWifiOnCfmSend(dst__, clientData__, status__) \ + CsrWifiRouterCtrlWifiOnCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, status__) + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_CTRL_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h new file mode 100644 index 000000000000..954f600b4ff4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h @@ -0,0 +1,2018 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_CTRL_PRIM_H__ +#define CSR_WIFI_ROUTER_CTRL_PRIM_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_wifi_common.h" +#include "csr_result.h" +#include "csr_wifi_fsm_event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSR_WIFI_ROUTER_CTRL_PRIM (0x0401) + +typedef CsrPrim CsrWifiRouterCtrlPrim; + +typedef CsrResult (*CsrWifiRouterCtrlRawSdioByteWrite)(CsrUint8 func, CsrUint32 address, CsrUint8 data); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioByteRead)(CsrUint8 func, CsrUint32 address, CsrUint8 *pdata); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioFirmwareDownload)(CsrUint32 length, const CsrUint8 *pdata); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioReset)(void); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioCoreDumpPrepare)(CsrBool suspendSme); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioByteBlockRead)(CsrUint8 func, CsrUint32 address, CsrUint8 *pdata, CsrUint32 length); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioGpRead16)(CsrUint8 func, CsrUint32 address, CsrUint16 *pdata); +typedef CsrResult (*CsrWifiRouterCtrlRawSdioGpWrite16)(CsrUint8 func, CsrUint32 address, CsrUint16 data); + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckRole + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR + - + CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlBlockAckRole; +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR ((CsrWifiRouterCtrlBlockAckRole) 0x00) +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT ((CsrWifiRouterCtrlBlockAckRole) 0x01) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlControlIndication + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_ERROR + - + CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_EXIT + - + CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_USER_REQUESTED + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlControlIndication; +#define CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_ERROR ((CsrWifiRouterCtrlControlIndication) 0x01) +#define CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_EXIT ((CsrWifiRouterCtrlControlIndication) 0x02) +#define CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_USER_REQUESTED ((CsrWifiRouterCtrlControlIndication) 0x03) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlListAction + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_LIST_ACTION_GET + - + CSR_WIFI_ROUTER_CTRL_LIST_ACTION_ADD + - + CSR_WIFI_ROUTER_CTRL_LIST_ACTION_REMOVE + - + CSR_WIFI_ROUTER_CTRL_LIST_ACTION_FLUSH + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlListAction; +#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_GET ((CsrWifiRouterCtrlListAction) 0x00) +#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_ADD ((CsrWifiRouterCtrlListAction) 0x01) +#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_REMOVE ((CsrWifiRouterCtrlListAction) 0x02) +#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_FLUSH ((CsrWifiRouterCtrlListAction) 0x03) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlLowPowerMode + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED + - + CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_ENABLED + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlLowPowerMode; +#define CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED ((CsrWifiRouterCtrlLowPowerMode) 0x0000) +#define CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_ENABLED ((CsrWifiRouterCtrlLowPowerMode) 0x0001) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMediaStatus + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_CONNECTED + - + CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_DISCONNECTED + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlMediaStatus; +#define CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_CONNECTED ((CsrWifiRouterCtrlMediaStatus) 0x00) +#define CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_DISCONNECTED ((CsrWifiRouterCtrlMediaStatus) 0x01) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMode + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_MODE_NONE - + CSR_WIFI_ROUTER_CTRL_MODE_IBSS - + CSR_WIFI_ROUTER_CTRL_MODE_STA - + CSR_WIFI_ROUTER_CTRL_MODE_AP - + CSR_WIFI_ROUTER_CTRL_MODE_MONITOR - + CSR_WIFI_ROUTER_CTRL_MODE_AMP - + CSR_WIFI_ROUTER_CTRL_MODE_P2P - + CSR_WIFI_ROUTER_CTRL_MODE_P2PGO - + CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlMode; +#define CSR_WIFI_ROUTER_CTRL_MODE_NONE ((CsrWifiRouterCtrlMode) 0x00) +#define CSR_WIFI_ROUTER_CTRL_MODE_IBSS ((CsrWifiRouterCtrlMode) 0x01) +#define CSR_WIFI_ROUTER_CTRL_MODE_STA ((CsrWifiRouterCtrlMode) 0x02) +#define CSR_WIFI_ROUTER_CTRL_MODE_AP ((CsrWifiRouterCtrlMode) 0x03) +#define CSR_WIFI_ROUTER_CTRL_MODE_MONITOR ((CsrWifiRouterCtrlMode) 0x04) +#define CSR_WIFI_ROUTER_CTRL_MODE_AMP ((CsrWifiRouterCtrlMode) 0x05) +#define CSR_WIFI_ROUTER_CTRL_MODE_P2P ((CsrWifiRouterCtrlMode) 0x06) +#define CSR_WIFI_ROUTER_CTRL_MODE_P2PGO ((CsrWifiRouterCtrlMode) 0x07) +#define CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI ((CsrWifiRouterCtrlMode) 0x08) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerStatus + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE + - + CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE + - + CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlPeerStatus; +#define CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE ((CsrWifiRouterCtrlPeerStatus) 0x00) +#define CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE ((CsrWifiRouterCtrlPeerStatus) 0x01) +#define CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED ((CsrWifiRouterCtrlPeerStatus) 0x02) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPortAction + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN + - + CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD + - + CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlPortAction; +#define CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN ((CsrWifiRouterCtrlPortAction) 0x0000) +#define CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD ((CsrWifiRouterCtrlPortAction) 0x0001) +#define CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK ((CsrWifiRouterCtrlPortAction) 0x0002) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPowersaveType + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_AC_BK_PS_INFO_PRESENT + - If set, AC BK PS info is present in b4 and b5 + CSR_WIFI_ROUTER_CTRL_AC_BE_PS_INFO_PRESENT + - If set, AC BE PS info is present in b6 and b7 + CSR_WIFI_ROUTER_CTRL_AC_VI_PS_INFO_PRESENT + - If set, AC VI PS info is present in b8 and b9 + CSR_WIFI_ROUTER_CTRL_AC_VO_PS_INFO_PRESENT + - If set, AC VO PS info is present in b10 and b11 + CSR_WIFI_ROUTER_CTRL_AC_BK_TRIGGER_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_BK_DELIVERY_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_BE_TRIGGER_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_BE_DELIVERY_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_VI_TRIGGER_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_VI_DELIVERY_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_VO_TRIGGER_ENABLED + - + CSR_WIFI_ROUTER_CTRL_AC_VO_DELIVERY_ENABLED + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlPowersaveType; +#define CSR_WIFI_ROUTER_CTRL_AC_BK_PS_INFO_PRESENT ((CsrWifiRouterCtrlPowersaveType) 0x0001) +#define CSR_WIFI_ROUTER_CTRL_AC_BE_PS_INFO_PRESENT ((CsrWifiRouterCtrlPowersaveType) 0x0002) +#define CSR_WIFI_ROUTER_CTRL_AC_VI_PS_INFO_PRESENT ((CsrWifiRouterCtrlPowersaveType) 0x0004) +#define CSR_WIFI_ROUTER_CTRL_AC_VO_PS_INFO_PRESENT ((CsrWifiRouterCtrlPowersaveType) 0x0008) +#define CSR_WIFI_ROUTER_CTRL_AC_BK_TRIGGER_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0010) +#define CSR_WIFI_ROUTER_CTRL_AC_BK_DELIVERY_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0020) +#define CSR_WIFI_ROUTER_CTRL_AC_BE_TRIGGER_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0040) +#define CSR_WIFI_ROUTER_CTRL_AC_BE_DELIVERY_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0080) +#define CSR_WIFI_ROUTER_CTRL_AC_VI_TRIGGER_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0100) +#define CSR_WIFI_ROUTER_CTRL_AC_VI_DELIVERY_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0200) +#define CSR_WIFI_ROUTER_CTRL_AC_VO_TRIGGER_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0400) +#define CSR_WIFI_ROUTER_CTRL_AC_VO_DELIVERY_ENABLED ((CsrWifiRouterCtrlPowersaveType) 0x0800) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlProtocolDirection + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX + - + CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlProtocolDirection; +#define CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX ((CsrWifiRouterCtrlProtocolDirection) 0x0000) +#define CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX ((CsrWifiRouterCtrlProtocolDirection) 0x0001) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlQoSControl + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_OFF + - + CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON + - + CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_80211_ON + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlQoSControl; +#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_OFF ((CsrWifiRouterCtrlQoSControl) 0x0000) +#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON ((CsrWifiRouterCtrlQoSControl) 0x0001) +#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_80211_ON ((CsrWifiRouterCtrlQoSControl) 0x0002) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlQueueConfig + + DESCRIPTION + Defines which Queues are enabled for use. + + VALUES + CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE + - + CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE + - + CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE + - + CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlQueueConfig; +#define CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE ((CsrWifiRouterCtrlQueueConfig) 0x01) +#define CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE ((CsrWifiRouterCtrlQueueConfig) 0x02) +#define CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE ((CsrWifiRouterCtrlQueueConfig) 0x04) +#define CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE ((CsrWifiRouterCtrlQueueConfig) 0x08) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficConfigType + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_CLS + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlTrafficConfigType; +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET ((CsrWifiRouterCtrlTrafficConfigType) 0x0000) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER ((CsrWifiRouterCtrlTrafficConfigType) 0x0001) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_CLS ((CsrWifiRouterCtrlTrafficConfigType) 0x0002) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficPacketType + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ALL + - + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlTrafficPacketType; +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE ((CsrWifiRouterCtrlTrafficPacketType) 0x0000) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL ((CsrWifiRouterCtrlTrafficPacketType) 0x0001) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP ((CsrWifiRouterCtrlTrafficPacketType) 0x0002) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK ((CsrWifiRouterCtrlTrafficPacketType) 0x0004) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP ((CsrWifiRouterCtrlTrafficPacketType) 0x0008) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET ((CsrWifiRouterCtrlTrafficPacketType) 0x0010) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM ((CsrWifiRouterCtrlTrafficPacketType) 0x0020) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ALL ((CsrWifiRouterCtrlTrafficPacketType) 0x00FF) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficType + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_BURSTY + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC + - + CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_CONTINUOUS + - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlTrafficType; +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL ((CsrWifiRouterCtrlTrafficType) 0x00) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_BURSTY ((CsrWifiRouterCtrlTrafficType) 0x01) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC ((CsrWifiRouterCtrlTrafficType) 0x02) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_CONTINUOUS ((CsrWifiRouterCtrlTrafficType) 0x03) + + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerRecordHandle + + DESCRIPTION + +*******************************************************************************/ +typedef CsrUint32 CsrWifiRouterCtrlPeerRecordHandle; +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPowersaveTypeMask + + DESCRIPTION + Mask type for use with the values defined by + CsrWifiRouterCtrlPowersaveType + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlPowersaveTypeMask; +/******************************************************************************* + + NAME + CsrWifiRouterCtrlQueueConfigMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiRouterCtrlQueueConfig + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlQueueConfigMask; +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRequestorInfo + + DESCRIPTION + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterCtrlRequestorInfo; +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficStreamId + + DESCRIPTION + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterCtrlTrafficStreamId; + + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlSmeVersions + + DESCRIPTION + + MEMBERS + firmwarePatch - + smeBuild - + smeHip - + +*******************************************************************************/ +typedef struct +{ + CsrUint32 firmwarePatch; + CsrCharString *smeBuild; + CsrUint32 smeHip; +} CsrWifiRouterCtrlSmeVersions; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlStaInfo + + DESCRIPTION + + MEMBERS + wmmOrQosEnabled - + powersaveMode - + maxSpLength - + listenIntervalInTus - + +*******************************************************************************/ +typedef struct +{ + CsrBool wmmOrQosEnabled; + CsrWifiRouterCtrlPowersaveTypeMask powersaveMode; + CsrUint8 maxSpLength; + CsrUint16 listenIntervalInTus; +} CsrWifiRouterCtrlStaInfo; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficFilter + + DESCRIPTION + + MEMBERS + etherType - + ipType - + udpSourcePort - + udpDestPort - + +*******************************************************************************/ +typedef struct +{ + CsrUint32 etherType; + CsrUint8 ipType; + CsrUint32 udpSourcePort; + CsrUint32 udpDestPort; +} CsrWifiRouterCtrlTrafficFilter; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficStats + + DESCRIPTION + + MEMBERS + rxMeanRate - Mean rx data rate over the interval + rxFramesNum - Keep number of Rx frames per second, for CYCLE_3. + txFramesNum - Keep number of Tx frames per second, for CYCLE_3. + rxBytesCount - Keep calculated Rx throughput per second, for CYCLE_2. + txBytesCount - Keep calculated Tx throughput per second, for CYCLE_2. + intervals - array size 11 MUST match TA_INTERVALS_NUM + +*******************************************************************************/ +typedef struct +{ + CsrUint32 rxMeanRate; + CsrUint32 rxFramesNum; + CsrUint32 txFramesNum; + CsrUint32 rxBytesCount; + CsrUint32 txBytesCount; + CsrUint8 intervals[11]; +} CsrWifiRouterCtrlTrafficStats; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlVersions + + DESCRIPTION + + MEMBERS + chipId - + chipVersion - + firmwareBuild - + firmwareHip - + routerBuild - + routerHip - + +*******************************************************************************/ +typedef struct +{ + CsrUint32 chipId; + CsrUint32 chipVersion; + CsrUint32 firmwareBuild; + CsrUint32 firmwareHip; + CsrCharString *routerBuild; + CsrUint32 routerHip; +} CsrWifiRouterCtrlVersions; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficConfig + + DESCRIPTION + + MEMBERS + packetFilter - + customFilter - + +*******************************************************************************/ +typedef struct +{ + CsrUint16 packetFilter; + CsrWifiRouterCtrlTrafficFilter customFilter; +} CsrWifiRouterCtrlTrafficConfig; + + +/* Downstream */ +#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST (0x0000) + +#define CSR_WIFI_ROUTER_CTRL_CONFIGURE_POWER_MODE_REQ ((CsrWifiRouterCtrlPrim) (0x0000 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_HIP_REQ ((CsrWifiRouterCtrlPrim) (0x0001 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_REQ ((CsrWifiRouterCtrlPrim) (0x0002 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES ((CsrWifiRouterCtrlPrim) (0x0003 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_REQ ((CsrWifiRouterCtrlPrim) (0x0004 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_REQ ((CsrWifiRouterCtrlPrim) (0x0005 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_SUSPEND_RES ((CsrWifiRouterCtrlPrim) (0x0006 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ ((CsrWifiRouterCtrlPrim) (0x0007 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_RESUME_RES ((CsrWifiRouterCtrlPrim) (0x0008 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_REQ ((CsrWifiRouterCtrlPrim) (0x0009 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_REQ ((CsrWifiRouterCtrlPrim) (0x000A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ ((CsrWifiRouterCtrlPrim) (0x000B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CLASSIFICATION_REQ ((CsrWifiRouterCtrlPrim) (0x000C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_REQ ((CsrWifiRouterCtrlPrim) (0x000D + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_REQ ((CsrWifiRouterCtrlPrim) (0x000E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_RES ((CsrWifiRouterCtrlPrim) (0x000F + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ ((CsrWifiRouterCtrlPrim) (0x0010 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES ((CsrWifiRouterCtrlPrim) (0x0011 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_M4_TRANSMIT_REQ ((CsrWifiRouterCtrlPrim) (0x0012 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_MODE_SET_REQ ((CsrWifiRouterCtrlPrim) (0x0013 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PEER_ADD_REQ ((CsrWifiRouterCtrlPrim) (0x0014 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PEER_DEL_REQ ((CsrWifiRouterCtrlPrim) (0x0015 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_REQ ((CsrWifiRouterCtrlPrim) (0x0016 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ ((CsrWifiRouterCtrlPrim) (0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) + + +#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) + +/* Upstream */ +#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) + +#define CSR_WIFI_ROUTER_CTRL_HIP_IND ((CsrWifiRouterCtrlPrim)(0x0000 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND ((CsrWifiRouterCtrlPrim)(0x0001 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM ((CsrWifiRouterCtrlPrim)(0x0002 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_RESUME_IND ((CsrWifiRouterCtrlPrim)(0x0003 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_SUSPEND_IND ((CsrWifiRouterCtrlPrim)(0x0004 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_CFM ((CsrWifiRouterCtrlPrim)(0x0005 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_CFM ((CsrWifiRouterCtrlPrim)(0x0006 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_CFM ((CsrWifiRouterCtrlPrim)(0x0007 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_CFM ((CsrWifiRouterCtrlPrim)(0x0008 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PROTOCOL_IND ((CsrWifiRouterCtrlPrim)(0x0009 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_SAMPLE_IND ((CsrWifiRouterCtrlPrim)(0x000A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_IND ((CsrWifiRouterCtrlPrim)(0x000B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_CFM ((CsrWifiRouterCtrlPrim)(0x000C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND ((CsrWifiRouterCtrlPrim)(0x000D + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_CFM ((CsrWifiRouterCtrlPrim)(0x000E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_M4_READY_TO_SEND_IND ((CsrWifiRouterCtrlPrim)(0x000F + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_M4_TRANSMITTED_IND ((CsrWifiRouterCtrlPrim)(0x0010 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_MIC_FAILURE_IND ((CsrWifiRouterCtrlPrim)(0x0011 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_CONNECTED_IND ((CsrWifiRouterCtrlPrim)(0x0012 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PEER_ADD_CFM ((CsrWifiRouterCtrlPrim)(0x0013 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PEER_DEL_CFM ((CsrWifiRouterCtrlPrim)(0x0014 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_UNEXPECTED_FRAME_IND ((CsrWifiRouterCtrlPrim)(0x0015 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_CFM ((CsrWifiRouterCtrlPrim)(0x0016 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_CFM ((CsrWifiRouterCtrlPrim)(0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_CFM ((CsrWifiRouterCtrlPrim)(0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM ((CsrWifiRouterCtrlPrim)(0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND ((CsrWifiRouterCtrlPrim)(0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND ((CsrWifiRouterCtrlPrim)(0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) + +#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) + +#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlConfigurePowerModeReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + mode - + wakeHost - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlLowPowerMode mode; + CsrBool wakeHost; +} CsrWifiRouterCtrlConfigurePowerModeReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlHipReq + + DESCRIPTION + This primitive is used for transferring MLME messages to the HIP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + mlmeCommandLength - Length of the MLME signal + mlmeCommand - Pointer to the MLME signal + dataRef1Length - Length of the dataRef1 bulk data + dataRef1 - Pointer to the bulk data 1 + dataRef2Length - Length of the dataRef2 bulk data + dataRef2 - Pointer to the bulk data 2 + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 mlmeCommandLength; + CsrUint8 *mlmeCommand; + CsrUint16 dataRef1Length; + CsrUint8 *dataRef1; + CsrUint16 dataRef2Length; + CsrUint8 *dataRef2; +} CsrWifiRouterCtrlHipReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMediaStatusReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + mediaStatus - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlMediaStatus mediaStatus; +} CsrWifiRouterCtrlMediaStatusReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMulticastAddressRes + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + status - + action - + getAddressesCount - + getAddresses - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult status; + CsrWifiRouterCtrlListAction action; + CsrUint8 getAddressesCount; + CsrWifiMacAddress *getAddresses; +} CsrWifiRouterCtrlMulticastAddressRes; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPortConfigureReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + uncontrolledPortAction - + controlledPortAction - + macAddress - + setProtection - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlPortAction uncontrolledPortAction; + CsrWifiRouterCtrlPortAction controlledPortAction; + CsrWifiMacAddress macAddress; + CsrBool setProtection; +} CsrWifiRouterCtrlPortConfigureReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlQosControlReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + control - + queueConfig - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlQoSControl control; + CsrWifiRouterCtrlQueueConfigMask queueConfig; +} CsrWifiRouterCtrlQosControlReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlSuspendRes + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult status; +} CsrWifiRouterCtrlSuspendRes; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasAddReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + tclasLength - + tclas - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 tclasLength; + CsrUint8 *tclas; +} CsrWifiRouterCtrlTclasAddReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlResumeRes + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult status; +} CsrWifiRouterCtrlResumeRes; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioDeinitialiseReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlRawSdioDeinitialiseReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioInitialiseReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlRawSdioInitialiseReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasDelReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + tclasLength - + tclas - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 tclasLength; + CsrUint8 *tclas; +} CsrWifiRouterCtrlTclasDelReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficClassificationReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + trafficType - + period - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlTrafficType trafficType; + CsrUint16 period; +} CsrWifiRouterCtrlTrafficClassificationReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficConfigReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + trafficConfigType - + config - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlTrafficConfigType trafficConfigType; + CsrWifiRouterCtrlTrafficConfig config; +} CsrWifiRouterCtrlTrafficConfigReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlWifiOffReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffRes + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlWifiOffRes; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlWifiOnReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnRes + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + status - + numInterfaceAddress - + stationMacAddress - array size 1 MUST match CSR_WIFI_NUM_INTERFACES + smeVersions - + scheduledInterrupt - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult status; + CsrUint16 numInterfaceAddress; + CsrWifiMacAddress stationMacAddress[2]; + CsrWifiRouterCtrlSmeVersions smeVersions; + CsrBool scheduledInterrupt; +} CsrWifiRouterCtrlWifiOnRes; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlM4TransmitReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlM4TransmitReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlModeSetReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + mode - + bssid - BSSID of the network the device is going to be a part + of + protection - Set to TRUE if encryption is enabled for the + connection/broadcast frames + intraBssDistEnabled - If set to TRUE, intra BSS destribution will be + enabled. If set to FALSE, any unicast PDU which does + not have the RA as the the local MAC address, shall be + ignored. This field is interpreted by the receive if + mode is set to CSR_WIFI_ROUTER_CTRL_MODE_P2PGO + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlMode mode; + CsrWifiMacAddress bssid; + CsrBool protection; + CsrBool intraBssDistEnabled; +} CsrWifiRouterCtrlModeSetReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerAddReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + peerMacAddress - + associationId - + staInfo - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiMacAddress peerMacAddress; + CsrUint16 associationId; + CsrWifiRouterCtrlStaInfo staInfo; +} CsrWifiRouterCtrlPeerAddReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerDelReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + peerRecordHandle - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlPeerRecordHandle peerRecordHandle; +} CsrWifiRouterCtrlPeerDelReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerUpdateReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + peerRecordHandle - + powersaveMode - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlPeerRecordHandle peerRecordHandle; + CsrWifiRouterCtrlPowersaveTypeMask powersaveMode; +} CsrWifiRouterCtrlPeerUpdateReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlCapabilitiesReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlCapabilitiesReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckEnableReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + macAddress - + trafficStreamID - + role - + bufferSize - + timeout - + ssn - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiMacAddress macAddress; + CsrWifiRouterCtrlTrafficStreamId trafficStreamID; + CsrWifiRouterCtrlBlockAckRole role; + CsrUint16 bufferSize; + CsrUint16 timeout; + CsrUint16 ssn; +} CsrWifiRouterCtrlBlockAckEnableReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckDisableReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + clientData - + macAddress - + trafficStreamID - + role - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiMacAddress macAddress; + CsrWifiRouterCtrlTrafficStreamId trafficStreamID; + CsrWifiRouterCtrlBlockAckRole role; +} CsrWifiRouterCtrlBlockAckDisableReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiMulticastReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + signalLength - + signal - + dataLength - + data - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 signalLength; + CsrUint8 *signal; + CsrUint16 dataLength; + CsrUint8 *data; +} CsrWifiRouterCtrlWapiMulticastReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiMulticastFilterReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint8 status; +} CsrWifiRouterCtrlWapiMulticastFilterReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiUnicastFilterReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint8 status; +} CsrWifiRouterCtrlWapiUnicastFilterReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlHipInd + + DESCRIPTION + This primitive is used for transferring MLME messages from the HIP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + mlmeCommandLength - Length of the MLME signal + mlmeCommand - Pointer to the MLME signal + dataRef1Length - Length of the dataRef1 bulk data + dataRef1 - Pointer to the bulk data 1 + dataRef2Length - Length of the dataRef2 bulk data + dataRef2 - Pointer to the bulk data 2 + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 mlmeCommandLength; + CsrUint8 *mlmeCommand; + CsrUint16 dataRef1Length; + CsrUint8 *dataRef1; + CsrUint16 dataRef2Length; + CsrUint8 *dataRef2; +} CsrWifiRouterCtrlHipInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMulticastAddressInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + action - + setAddressesCount - + setAddresses - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlListAction action; + CsrUint8 setAddressesCount; + CsrWifiMacAddress *setAddresses; +} CsrWifiRouterCtrlMulticastAddressInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPortConfigureCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + macAddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiMacAddress macAddress; +} CsrWifiRouterCtrlPortConfigureCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlResumeInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + powerMaintained - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrBool powerMaintained; +} CsrWifiRouterCtrlResumeInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlSuspendInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + hardSuspend - + d3Suspend - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrBool hardSuspend; + CsrBool d3Suspend; +} CsrWifiRouterCtrlSuspendInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasAddCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterCtrlTclasAddCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioDeinitialiseCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + result - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult result; +} CsrWifiRouterCtrlRawSdioDeinitialiseCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlRawSdioInitialiseCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + result - + byteRead - + byteWrite - + firmwareDownload - + reset - + coreDumpPrepare - + byteBlockRead - + gpRead16 - + gpWrite16 - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult result; + CsrWifiRouterCtrlRawSdioByteRead byteRead; + CsrWifiRouterCtrlRawSdioByteWrite byteWrite; + CsrWifiRouterCtrlRawSdioFirmwareDownload firmwareDownload; + CsrWifiRouterCtrlRawSdioReset reset; + CsrWifiRouterCtrlRawSdioCoreDumpPrepare coreDumpPrepare; + CsrWifiRouterCtrlRawSdioByteBlockRead byteBlockRead; + CsrWifiRouterCtrlRawSdioGpRead16 gpRead16; + CsrWifiRouterCtrlRawSdioGpWrite16 gpWrite16; +} CsrWifiRouterCtrlRawSdioInitialiseCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTclasDelCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterCtrlTclasDelCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficProtocolInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + packetType - + direction - + srcAddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlTrafficPacketType packetType; + CsrWifiRouterCtrlProtocolDirection direction; + CsrWifiMacAddress srcAddress; +} CsrWifiRouterCtrlTrafficProtocolInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlTrafficSampleInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + stats - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlTrafficStats stats; +} CsrWifiRouterCtrlTrafficSampleInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + controlIndication - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrWifiRouterCtrlControlIndication controlIndication; +} CsrWifiRouterCtrlWifiOffInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOffCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; +} CsrWifiRouterCtrlWifiOffCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + status - + versions - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult status; + CsrWifiRouterCtrlVersions versions; +} CsrWifiRouterCtrlWifiOnInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWifiOnCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrResult status; +} CsrWifiRouterCtrlWifiOnCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlM4ReadyToSendInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + peerMacAddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; +} CsrWifiRouterCtrlM4ReadyToSendInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlM4TransmittedInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + peerMacAddress - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; + CsrResult status; +} CsrWifiRouterCtrlM4TransmittedInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlMicFailureInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + peerMacAddress - + unicastPdu - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; + CsrBool unicastPdu; +} CsrWifiRouterCtrlMicFailureInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlConnectedInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + peerMacAddress - + peerStatus - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; + CsrWifiRouterCtrlPeerStatus peerStatus; +} CsrWifiRouterCtrlConnectedInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerAddCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + peerMacAddress - + peerRecordHandle - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; + CsrWifiRouterCtrlPeerRecordHandle peerRecordHandle; + CsrResult status; +} CsrWifiRouterCtrlPeerAddCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerDelCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterCtrlPeerDelCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlUnexpectedFrameInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + peerMacAddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; +} CsrWifiRouterCtrlUnexpectedFrameInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlPeerUpdateCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterCtrlPeerUpdateCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlCapabilitiesCfm + + DESCRIPTION + The router sends this primitive to confirm the size of the queues of the + HIP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + commandQueueSize - Size of command queue + trafficQueueSize - Size of traffic queue (per AC) + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 commandQueueSize; + CsrUint16 trafficQueueSize; +} CsrWifiRouterCtrlCapabilitiesCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckEnableCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterCtrlBlockAckEnableCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckDisableCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterCtrlBlockAckDisableCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlBlockAckErrorInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + trafficStreamID - + peerMacAddress - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlTrafficStreamId trafficStreamID; + CsrWifiMacAddress peerMacAddress; + CsrResult status; +} CsrWifiRouterCtrlBlockAckErrorInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlStaInactiveInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + staAddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiMacAddress staAddress; +} CsrWifiRouterCtrlStaInactiveInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiMulticastInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + signalLength - + signal - + dataLength - + data - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrUint16 signalLength; + CsrUint8 *signal; + CsrUint16 dataLength; + CsrUint8 *data; +} CsrWifiRouterCtrlWapiMulticastInd; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_CTRL_PRIM_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c new file mode 100644 index 000000000000..b7fa6a1eb521 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c @@ -0,0 +1,43 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + + *****************************************************************************/ +#include "csr_wifi_router_ctrl_sef.h" + +const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = +{ + /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler, + /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler, + /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler, + /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler, + /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler, + /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler, + /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler, + /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler, + /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler, + /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler, + /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler, + /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler, + /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler, + /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler, + /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler, + /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler, + /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler, + /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler, + /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler, + /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler, + /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler, + /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, + /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, + /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, + CsrWifiRouterCtrlBlockAckEnableReqHandler, /* 0x0018 */ + CsrWifiRouterCtrlBlockAckDisableReqHandler, /* 0x0019 */ + CsrWifiRouterCtrlWapiMulticastReqHandler, /* 0x001A */ + CsrWifiRouterCtrlWapiMulticastFilterReqHandler, /* 0x001B */ + CsrWifiRouterCtrlWapiUnicastFilterReqHandler, /* 0x001C */ +}; diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h new file mode 100644 index 000000000000..07382ef8cce4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h @@ -0,0 +1,56 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + + *****************************************************************************/ +#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__ +#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__ + +#include "csr_wifi_router_ctrl_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef void (*CsrWifiRouterCtrlStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg); + + extern const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT]; + + extern void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c new file mode 100644 index 000000000000..cb1f6dc29888 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c @@ -0,0 +1,2369 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_msgconv.h" +#include "csr_unicode.h" + + +#include "csr_wifi_router_ctrl_prim.h" +#include "csr_wifi_router_ctrl_serialize.h" + +void CsrWifiRouterCtrlPfree(void *ptr) +{ + CsrPmemFree(ptr); +} + + +CsrSize CsrWifiRouterCtrlConfigurePowerModeReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrWifiRouterCtrlLowPowerMode primitive->mode */ + bufferSize += 1; /* CsrBool primitive->wakeHost */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlConfigurePowerModeReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlConfigurePowerModeReq *primitive = (CsrWifiRouterCtrlConfigurePowerModeReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mode); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wakeHost); + return(ptr); +} + + +void* CsrWifiRouterCtrlConfigurePowerModeReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlConfigurePowerModeReq *primitive = (CsrWifiRouterCtrlConfigurePowerModeReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlConfigurePowerModeReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mode, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wakeHost, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlHipReqSizeof(void *msg) +{ + CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */ + bufferSize += 2; /* CsrUint16 primitive->mlmeCommandLength */ + bufferSize += primitive->mlmeCommandLength; /* CsrUint8 primitive->mlmeCommand */ + bufferSize += 2; /* CsrUint16 primitive->dataRef1Length */ + bufferSize += primitive->dataRef1Length; /* CsrUint8 primitive->dataRef1 */ + bufferSize += 2; /* CsrUint16 primitive->dataRef2Length */ + bufferSize += primitive->dataRef2Length; /* CsrUint8 primitive->dataRef2 */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlHipReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mlmeCommandLength); + if (primitive->mlmeCommandLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mlmeCommand, ((CsrUint16) (primitive->mlmeCommandLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataRef1Length); + if (primitive->dataRef1Length) + { + CsrMemCpySer(ptr, len, (const void *) primitive->dataRef1, ((CsrUint16) (primitive->dataRef1Length))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataRef2Length); + if (primitive->dataRef2Length) + { + CsrMemCpySer(ptr, len, (const void *) primitive->dataRef2, ((CsrUint16) (primitive->dataRef2Length))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlHipReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlHipReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mlmeCommandLength, buffer, &offset); + if (primitive->mlmeCommandLength) + { + primitive->mlmeCommand = (CsrUint8 *)CsrPmemAlloc(primitive->mlmeCommandLength); + CsrMemCpyDes(primitive->mlmeCommand, buffer, &offset, ((CsrUint16) (primitive->mlmeCommandLength))); + } + else + { + primitive->mlmeCommand = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->dataRef1Length, buffer, &offset); + if (primitive->dataRef1Length) + { + primitive->dataRef1 = (CsrUint8 *)CsrPmemAlloc(primitive->dataRef1Length); + CsrMemCpyDes(primitive->dataRef1, buffer, &offset, ((CsrUint16) (primitive->dataRef1Length))); + } + else + { + primitive->dataRef1 = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->dataRef2Length, buffer, &offset); + if (primitive->dataRef2Length) + { + primitive->dataRef2 = (CsrUint8 *)CsrPmemAlloc(primitive->dataRef2Length); + CsrMemCpyDes(primitive->dataRef2, buffer, &offset, ((CsrUint16) (primitive->dataRef2Length))); + } + else + { + primitive->dataRef2 = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlHipReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *) voidPrimitivePointer; + CsrPmemFree(primitive->mlmeCommand); + CsrPmemFree(primitive->dataRef1); + CsrPmemFree(primitive->dataRef2); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlMediaStatusReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 1; /* CsrWifiRouterCtrlMediaStatus primitive->mediaStatus */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlMediaStatusReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlMediaStatusReq *primitive = (CsrWifiRouterCtrlMediaStatusReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mediaStatus); + return(ptr); +} + + +void* CsrWifiRouterCtrlMediaStatusReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlMediaStatusReq *primitive = (CsrWifiRouterCtrlMediaStatusReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMediaStatusReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mediaStatus, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlMulticastAddressResSizeof(void *msg) +{ + CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiRouterCtrlListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->getAddressesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressesCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->getAddresses[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlMulticastAddressResSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->getAddressesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressesCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->getAddresses[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiRouterCtrlMulticastAddressResDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMulticastAddressRes)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->getAddressesCount, buffer, &offset); + primitive->getAddresses = NULL; + if (primitive->getAddressesCount) + { + primitive->getAddresses = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->getAddressesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressesCount; i1++) + { + CsrMemCpyDes(primitive->getAddresses[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +void CsrWifiRouterCtrlMulticastAddressResSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *) voidPrimitivePointer; + CsrPmemFree(primitive->getAddresses); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlPortConfigureReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 18) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrWifiRouterCtrlPortAction primitive->uncontrolledPortAction */ + bufferSize += 2; /* CsrWifiRouterCtrlPortAction primitive->controlledPortAction */ + bufferSize += 6; /* CsrUint8 primitive->macAddress.a[6] */ + bufferSize += 1; /* CsrBool primitive->setProtection */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPortConfigureReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPortConfigureReq *primitive = (CsrWifiRouterCtrlPortConfigureReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->uncontrolledPortAction); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->controlledPortAction); + CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->setProtection); + return(ptr); +} + + +void* CsrWifiRouterCtrlPortConfigureReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPortConfigureReq *primitive = (CsrWifiRouterCtrlPortConfigureReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPortConfigureReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->uncontrolledPortAction, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->controlledPortAction, buffer, &offset); + CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->setProtection, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlQosControlReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrWifiRouterCtrlQoSControl primitive->control */ + bufferSize += 1; /* CsrWifiRouterCtrlQueueConfigMask primitive->queueConfig */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlQosControlReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlQosControlReq *primitive = (CsrWifiRouterCtrlQosControlReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->control); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->queueConfig); + return(ptr); +} + + +void* CsrWifiRouterCtrlQosControlReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlQosControlReq *primitive = (CsrWifiRouterCtrlQosControlReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlQosControlReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->control, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->queueConfig, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlSuspendResSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlSuspendResSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlSuspendRes *primitive = (CsrWifiRouterCtrlSuspendRes *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlSuspendResDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlSuspendRes *primitive = (CsrWifiRouterCtrlSuspendRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlSuspendRes)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTclasAddReqSizeof(void *msg) +{ + CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->tclasLength */ + bufferSize += primitive->tclasLength; /* CsrUint8 primitive->tclas */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTclasAddReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->tclasLength); + if (primitive->tclasLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->tclas, ((CsrUint16) (primitive->tclasLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlTclasAddReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasAddReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->tclasLength, buffer, &offset); + if (primitive->tclasLength) + { + primitive->tclas = (CsrUint8 *)CsrPmemAlloc(primitive->tclasLength); + CsrMemCpyDes(primitive->tclas, buffer, &offset, ((CsrUint16) (primitive->tclasLength))); + } + else + { + primitive->tclas = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlTclasAddReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *) voidPrimitivePointer; + CsrPmemFree(primitive->tclas); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlResumeResSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlResumeResSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlResumeRes *primitive = (CsrWifiRouterCtrlResumeRes *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlResumeResDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlResumeRes *primitive = (CsrWifiRouterCtrlResumeRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlResumeRes)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTclasDelReqSizeof(void *msg) +{ + CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->tclasLength */ + bufferSize += primitive->tclasLength; /* CsrUint8 primitive->tclas */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTclasDelReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->tclasLength); + if (primitive->tclasLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->tclas, ((CsrUint16) (primitive->tclasLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlTclasDelReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasDelReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->tclasLength, buffer, &offset); + if (primitive->tclasLength) + { + primitive->tclas = (CsrUint8 *)CsrPmemAlloc(primitive->tclasLength); + CsrMemCpyDes(primitive->tclas, buffer, &offset, ((CsrUint16) (primitive->tclasLength))); + } + else + { + primitive->tclas = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlTclasDelReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *) voidPrimitivePointer; + CsrPmemFree(primitive->tclas); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlTrafficClassificationReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 1; /* CsrWifiRouterCtrlTrafficType primitive->trafficType */ + bufferSize += 2; /* CsrUint16 primitive->period */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTrafficClassificationReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTrafficClassificationReq *primitive = (CsrWifiRouterCtrlTrafficClassificationReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->trafficType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->period); + return(ptr); +} + + +void* CsrWifiRouterCtrlTrafficClassificationReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTrafficClassificationReq *primitive = (CsrWifiRouterCtrlTrafficClassificationReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficClassificationReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->trafficType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->period, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTrafficConfigReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 24) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrWifiRouterCtrlTrafficConfigType primitive->trafficConfigType */ + bufferSize += 2; /* CsrUint16 primitive->config.packetFilter */ + bufferSize += 4; /* CsrUint32 primitive->config.customFilter.etherType */ + bufferSize += 1; /* CsrUint8 primitive->config.customFilter.ipType */ + bufferSize += 4; /* CsrUint32 primitive->config.customFilter.udpSourcePort */ + bufferSize += 4; /* CsrUint32 primitive->config.customFilter.udpDestPort */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTrafficConfigReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTrafficConfigReq *primitive = (CsrWifiRouterCtrlTrafficConfigReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->trafficConfigType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->config.packetFilter); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->config.customFilter.etherType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->config.customFilter.ipType); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->config.customFilter.udpSourcePort); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->config.customFilter.udpDestPort); + return(ptr); +} + + +void* CsrWifiRouterCtrlTrafficConfigReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTrafficConfigReq *primitive = (CsrWifiRouterCtrlTrafficConfigReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficConfigReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->trafficConfigType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->config.packetFilter, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->config.customFilter.etherType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->config.customFilter.ipType, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->config.customFilter.udpSourcePort, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->config.customFilter.udpDestPort, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlWifiOnResSizeof(void *msg) +{ + CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 30) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->numInterfaceAddress */ + { + CsrUint16 i1; + for (i1 = 0; i1 < 2; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->stationMacAddress[i1].a[6] */ + } + } + bufferSize += 4; /* CsrUint32 primitive->smeVersions.firmwarePatch */ + bufferSize += (primitive->smeVersions.smeBuild?CsrStrLen(primitive->smeVersions.smeBuild) : 0) + 1; /* CsrCharString* primitive->smeVersions.smeBuild (0 byte len + 1 for NULL Term) */ + bufferSize += 4; /* CsrUint32 primitive->smeVersions.smeHip */ + bufferSize += 1; /* CsrBool primitive->scheduledInterrupt */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWifiOnResSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->numInterfaceAddress); + { + CsrUint16 i1; + for (i1 = 0; i1 < 2; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->stationMacAddress[i1].a, ((CsrUint16) (6))); + } + } + CsrUint32Ser(ptr, len, (CsrUint32) primitive->smeVersions.firmwarePatch); + CsrCharStringSer(ptr, len, primitive->smeVersions.smeBuild); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->smeVersions.smeHip); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scheduledInterrupt); + return(ptr); +} + + +void* CsrWifiRouterCtrlWifiOnResDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnRes)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->numInterfaceAddress, buffer, &offset); + { + CsrUint16 i1; + for (i1 = 0; i1 < 2; i1++) + { + CsrMemCpyDes(primitive->stationMacAddress[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + CsrUint32Des((CsrUint32 *) &primitive->smeVersions.firmwarePatch, buffer, &offset); + CsrCharStringDes(&primitive->smeVersions.smeBuild, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->smeVersions.smeHip, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scheduledInterrupt, buffer, &offset); + + return primitive; +} + + +void CsrWifiRouterCtrlWifiOnResSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) voidPrimitivePointer; + CsrPmemFree(primitive->smeVersions.smeBuild); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlM4TransmitReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlM4TransmitReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlM4TransmitReq *primitive = (CsrWifiRouterCtrlM4TransmitReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + return(ptr); +} + + +void* CsrWifiRouterCtrlM4TransmitReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlM4TransmitReq *primitive = (CsrWifiRouterCtrlM4TransmitReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlM4TransmitReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlModeSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 16) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 1; /* CsrWifiRouterCtrlMode primitive->mode */ + bufferSize += 6; /* CsrUint8 primitive->bssid.a[6] */ + bufferSize += 1; /* CsrBool primitive->protection */ + bufferSize += 1; /* CsrBool primitive->intraBssDistEnabled */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlModeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlModeSetReq *primitive = (CsrWifiRouterCtrlModeSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mode); + CsrMemCpySer(ptr, len, (const void *) primitive->bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->protection); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->intraBssDistEnabled); + return(ptr); +} + + +void* CsrWifiRouterCtrlModeSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlModeSetReq *primitive = (CsrWifiRouterCtrlModeSetReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mode, buffer, &offset); + CsrMemCpyDes(primitive->bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->protection, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->intraBssDistEnabled, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlPeerAddReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 21) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 2; /* CsrUint16 primitive->associationId */ + bufferSize += 1; /* CsrBool primitive->staInfo.wmmOrQosEnabled */ + bufferSize += 2; /* CsrWifiRouterCtrlPowersaveTypeMask primitive->staInfo.powersaveMode */ + bufferSize += 1; /* CsrUint8 primitive->staInfo.maxSpLength */ + bufferSize += 2; /* CsrUint16 primitive->staInfo.listenIntervalInTus */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPeerAddReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPeerAddReq *primitive = (CsrWifiRouterCtrlPeerAddReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->associationId); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->staInfo.wmmOrQosEnabled); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->staInfo.powersaveMode); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->staInfo.maxSpLength); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->staInfo.listenIntervalInTus); + return(ptr); +} + + +void* CsrWifiRouterCtrlPeerAddReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPeerAddReq *primitive = (CsrWifiRouterCtrlPeerAddReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerAddReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->associationId, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->staInfo.wmmOrQosEnabled, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->staInfo.powersaveMode, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->staInfo.maxSpLength, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->staInfo.listenIntervalInTus, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlPeerDelReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 4; /* CsrWifiRouterCtrlPeerRecordHandle primitive->peerRecordHandle */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPeerDelReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPeerDelReq *primitive = (CsrWifiRouterCtrlPeerDelReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->peerRecordHandle); + return(ptr); +} + + +void* CsrWifiRouterCtrlPeerDelReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPeerDelReq *primitive = (CsrWifiRouterCtrlPeerDelReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerDelReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->peerRecordHandle, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlPeerUpdateReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 4; /* CsrWifiRouterCtrlPeerRecordHandle primitive->peerRecordHandle */ + bufferSize += 2; /* CsrWifiRouterCtrlPowersaveTypeMask primitive->powersaveMode */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPeerUpdateReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPeerUpdateReq *primitive = (CsrWifiRouterCtrlPeerUpdateReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->peerRecordHandle); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->powersaveMode); + return(ptr); +} + + +void* CsrWifiRouterCtrlPeerUpdateReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPeerUpdateReq *primitive = (CsrWifiRouterCtrlPeerUpdateReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerUpdateReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->peerRecordHandle, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->powersaveMode, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlBlockAckEnableReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 21) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 6; /* CsrUint8 primitive->macAddress.a[6] */ + bufferSize += 1; /* CsrWifiRouterCtrlTrafficStreamId primitive->trafficStreamID */ + bufferSize += 1; /* CsrWifiRouterCtrlBlockAckRole primitive->role */ + bufferSize += 2; /* CsrUint16 primitive->bufferSize */ + bufferSize += 2; /* CsrUint16 primitive->timeout */ + bufferSize += 2; /* CsrUint16 primitive->ssn */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlBlockAckEnableReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlBlockAckEnableReq *primitive = (CsrWifiRouterCtrlBlockAckEnableReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->trafficStreamID); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->role); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->bufferSize); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->timeout); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->ssn); + return(ptr); +} + + +void* CsrWifiRouterCtrlBlockAckEnableReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlBlockAckEnableReq *primitive = (CsrWifiRouterCtrlBlockAckEnableReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckEnableReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->trafficStreamID, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->role, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->bufferSize, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->timeout, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->ssn, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 6; /* CsrUint8 primitive->macAddress.a[6] */ + bufferSize += 1; /* CsrWifiRouterCtrlTrafficStreamId primitive->trafficStreamID */ + bufferSize += 1; /* CsrWifiRouterCtrlBlockAckRole primitive->role */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlBlockAckDisableReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlBlockAckDisableReq *primitive = (CsrWifiRouterCtrlBlockAckDisableReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->trafficStreamID); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->role); + return(ptr); +} + + +void* CsrWifiRouterCtrlBlockAckDisableReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlBlockAckDisableReq *primitive = (CsrWifiRouterCtrlBlockAckDisableReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckDisableReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->trafficStreamID, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->role, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg) +{ + CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrUint16 primitive->signalLength */ + bufferSize += primitive->signalLength; /* CsrUint8 primitive->signal */ + bufferSize += 2; /* CsrUint16 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->signalLength); + if (primitive->signalLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->signal, ((CsrUint16) (primitive->signalLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->signalLength, buffer, &offset); + if (primitive->signalLength) + { + primitive->signal = (CsrUint8 *)CsrPmemAlloc(primitive->signalLength); + CsrMemCpyDes(primitive->signal, buffer, &offset, ((CsrUint16) (primitive->signalLength))); + } + else + { + primitive->signal = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) voidPrimitivePointer; + CsrPmemFree(primitive->signal); + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg) +{ + CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */ + bufferSize += 2; /* CsrUint16 primitive->mlmeCommandLength */ + bufferSize += primitive->mlmeCommandLength; /* CsrUint8 primitive->mlmeCommand */ + bufferSize += 2; /* CsrUint16 primitive->dataRef1Length */ + bufferSize += primitive->dataRef1Length; /* CsrUint8 primitive->dataRef1 */ + bufferSize += 2; /* CsrUint16 primitive->dataRef2Length */ + bufferSize += primitive->dataRef2Length; /* CsrUint8 primitive->dataRef2 */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlHipIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mlmeCommandLength); + if (primitive->mlmeCommandLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mlmeCommand, ((CsrUint16) (primitive->mlmeCommandLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataRef1Length); + if (primitive->dataRef1Length) + { + CsrMemCpySer(ptr, len, (const void *) primitive->dataRef1, ((CsrUint16) (primitive->dataRef1Length))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataRef2Length); + if (primitive->dataRef2Length) + { + CsrMemCpySer(ptr, len, (const void *) primitive->dataRef2, ((CsrUint16) (primitive->dataRef2Length))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlHipIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlHipInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mlmeCommandLength, buffer, &offset); + if (primitive->mlmeCommandLength) + { + primitive->mlmeCommand = (CsrUint8 *)CsrPmemAlloc(primitive->mlmeCommandLength); + CsrMemCpyDes(primitive->mlmeCommand, buffer, &offset, ((CsrUint16) (primitive->mlmeCommandLength))); + } + else + { + primitive->mlmeCommand = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->dataRef1Length, buffer, &offset); + if (primitive->dataRef1Length) + { + primitive->dataRef1 = (CsrUint8 *)CsrPmemAlloc(primitive->dataRef1Length); + CsrMemCpyDes(primitive->dataRef1, buffer, &offset, ((CsrUint16) (primitive->dataRef1Length))); + } + else + { + primitive->dataRef1 = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->dataRef2Length, buffer, &offset); + if (primitive->dataRef2Length) + { + primitive->dataRef2 = (CsrUint8 *)CsrPmemAlloc(primitive->dataRef2Length); + CsrMemCpyDes(primitive->dataRef2, buffer, &offset, ((CsrUint16) (primitive->dataRef2Length))); + } + else + { + primitive->dataRef2 = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlHipIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) voidPrimitivePointer; + CsrPmemFree(primitive->mlmeCommand); + CsrPmemFree(primitive->dataRef1); + CsrPmemFree(primitive->dataRef2); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlMulticastAddressIndSizeof(void *msg) +{ + CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiRouterCtrlListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->setAddressesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressesCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->setAddresses[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlMulticastAddressIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->setAddressesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressesCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->setAddresses[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiRouterCtrlMulticastAddressIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMulticastAddressInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->setAddressesCount, buffer, &offset); + primitive->setAddresses = NULL; + if (primitive->setAddressesCount) + { + primitive->setAddresses = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->setAddressesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressesCount; i1++) + { + CsrMemCpyDes(primitive->setAddresses[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +void CsrWifiRouterCtrlMulticastAddressIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *) voidPrimitivePointer; + CsrPmemFree(primitive->setAddresses); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlPortConfigureCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 6; /* CsrUint8 primitive->macAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPortConfigureCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPortConfigureCfm *primitive = (CsrWifiRouterCtrlPortConfigureCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiRouterCtrlPortConfigureCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPortConfigureCfm *primitive = (CsrWifiRouterCtrlPortConfigureCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPortConfigureCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlSuspendIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 1; /* CsrBool primitive->hardSuspend */ + bufferSize += 1; /* CsrBool primitive->d3Suspend */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlSuspendIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlSuspendInd *primitive = (CsrWifiRouterCtrlSuspendInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->hardSuspend); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->d3Suspend); + return(ptr); +} + + +void* CsrWifiRouterCtrlSuspendIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlSuspendInd *primitive = (CsrWifiRouterCtrlSuspendInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlSuspendInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->hardSuspend, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->d3Suspend, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTclasAddCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTclasAddCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTclasAddCfm *primitive = (CsrWifiRouterCtrlTclasAddCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlTclasAddCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTclasAddCfm *primitive = (CsrWifiRouterCtrlTclasAddCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasAddCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlRawSdioDeinitialiseCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->result */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlRawSdioDeinitialiseCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlRawSdioDeinitialiseCfm *primitive = (CsrWifiRouterCtrlRawSdioDeinitialiseCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result); + return(ptr); +} + + +void* CsrWifiRouterCtrlRawSdioDeinitialiseCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlRawSdioDeinitialiseCfm *primitive = (CsrWifiRouterCtrlRawSdioDeinitialiseCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlRawSdioDeinitialiseCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlRawSdioInitialiseCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 39) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->result */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioByteRead primitive->byteRead */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioByteWrite primitive->byteWrite */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioFirmwareDownload primitive->firmwareDownload */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioReset primitive->reset */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioCoreDumpPrepare primitive->coreDumpPrepare */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioByteBlockRead primitive->byteBlockRead */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioGpRead16 primitive->gpRead16 */ + bufferSize += 4; /* CsrWifiRouterCtrlRawSdioGpWrite16 primitive->gpWrite16 */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlRawSdioInitialiseCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlRawSdioInitialiseCfm *primitive = (CsrWifiRouterCtrlRawSdioInitialiseCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result); + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->byteRead */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->byteWrite */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->firmwareDownload */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->reset */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->coreDumpPrepare */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->byteBlockRead */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->gpRead16 */ + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->gpWrite16 */ + return(ptr); +} + + +void* CsrWifiRouterCtrlRawSdioInitialiseCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlRawSdioInitialiseCfm *primitive = (CsrWifiRouterCtrlRawSdioInitialiseCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlRawSdioInitialiseCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result, buffer, &offset); + primitive->byteRead = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->byteWrite = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->firmwareDownload = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->reset = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->coreDumpPrepare = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->byteBlockRead = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->gpRead16 = NULL; /* Special for Function Pointers... */ + offset += 4; + primitive->gpWrite16 = NULL; /* Special for Function Pointers... */ + offset += 4; + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTclasDelCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTclasDelCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTclasDelCfm *primitive = (CsrWifiRouterCtrlTclasDelCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlTclasDelCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTclasDelCfm *primitive = (CsrWifiRouterCtrlTclasDelCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTclasDelCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTrafficProtocolIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiRouterCtrlTrafficPacketType primitive->packetType */ + bufferSize += 2; /* CsrWifiRouterCtrlProtocolDirection primitive->direction */ + bufferSize += 6; /* CsrUint8 primitive->srcAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTrafficProtocolIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTrafficProtocolInd *primitive = (CsrWifiRouterCtrlTrafficProtocolInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->packetType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->direction); + CsrMemCpySer(ptr, len, (const void *) primitive->srcAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiRouterCtrlTrafficProtocolIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTrafficProtocolInd *primitive = (CsrWifiRouterCtrlTrafficProtocolInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficProtocolInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->packetType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->direction, buffer, &offset); + CsrMemCpyDes(primitive->srcAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlTrafficSampleIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 38) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 4; /* CsrUint32 primitive->stats.rxMeanRate */ + bufferSize += 4; /* CsrUint32 primitive->stats.rxFramesNum */ + bufferSize += 4; /* CsrUint32 primitive->stats.txFramesNum */ + bufferSize += 4; /* CsrUint32 primitive->stats.rxBytesCount */ + bufferSize += 4; /* CsrUint32 primitive->stats.txBytesCount */ + bufferSize += 11; /* CsrUint8 primitive->stats.intervals[11] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlTrafficSampleIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlTrafficSampleInd *primitive = (CsrWifiRouterCtrlTrafficSampleInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->stats.rxMeanRate); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->stats.rxFramesNum); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->stats.txFramesNum); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->stats.rxBytesCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->stats.txBytesCount); + CsrMemCpySer(ptr, len, (const void *) primitive->stats.intervals, ((CsrUint16) (11))); + return(ptr); +} + + +void* CsrWifiRouterCtrlTrafficSampleIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlTrafficSampleInd *primitive = (CsrWifiRouterCtrlTrafficSampleInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlTrafficSampleInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->stats.rxMeanRate, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->stats.rxFramesNum, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->stats.txFramesNum, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->stats.rxBytesCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->stats.txBytesCount, buffer, &offset); + CsrMemCpyDes(primitive->stats.intervals, buffer, &offset, ((CsrUint16) (11))); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlWifiOnIndSizeof(void *msg) +{ + CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 27) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 4; /* CsrUint32 primitive->versions.chipId */ + bufferSize += 4; /* CsrUint32 primitive->versions.chipVersion */ + bufferSize += 4; /* CsrUint32 primitive->versions.firmwareBuild */ + bufferSize += 4; /* CsrUint32 primitive->versions.firmwareHip */ + bufferSize += (primitive->versions.routerBuild?CsrStrLen(primitive->versions.routerBuild) : 0) + 1; /* CsrCharString* primitive->versions.routerBuild (0 byte len + 1 for NULL Term) */ + bufferSize += 4; /* CsrUint32 primitive->versions.routerHip */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWifiOnIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.chipId); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.chipVersion); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.firmwareBuild); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.firmwareHip); + CsrCharStringSer(ptr, len, primitive->versions.routerBuild); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.routerHip); + return(ptr); +} + + +void* CsrWifiRouterCtrlWifiOnIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.chipId, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.chipVersion, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.firmwareBuild, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.firmwareHip, buffer, &offset); + CsrCharStringDes(&primitive->versions.routerBuild, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.routerHip, buffer, &offset); + + return primitive; +} + + +void CsrWifiRouterCtrlWifiOnIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *) voidPrimitivePointer; + CsrPmemFree(primitive->versions.routerBuild); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterCtrlWifiOnCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWifiOnCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWifiOnCfm *primitive = (CsrWifiRouterCtrlWifiOnCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlWifiOnCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWifiOnCfm *primitive = (CsrWifiRouterCtrlWifiOnCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlM4ReadyToSendIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlM4ReadyToSendIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlM4ReadyToSendInd *primitive = (CsrWifiRouterCtrlM4ReadyToSendInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiRouterCtrlM4ReadyToSendIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlM4ReadyToSendInd *primitive = (CsrWifiRouterCtrlM4ReadyToSendInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlM4ReadyToSendInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlM4TransmittedIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlM4TransmittedIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlM4TransmittedInd *primitive = (CsrWifiRouterCtrlM4TransmittedInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlM4TransmittedIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlM4TransmittedInd *primitive = (CsrWifiRouterCtrlM4TransmittedInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlM4TransmittedInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlMicFailureIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 1; /* CsrBool primitive->unicastPdu */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlMicFailureIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlMicFailureInd *primitive = (CsrWifiRouterCtrlMicFailureInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->unicastPdu); + return(ptr); +} + + +void* CsrWifiRouterCtrlMicFailureIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlMicFailureInd *primitive = (CsrWifiRouterCtrlMicFailureInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlMicFailureInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->unicastPdu, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlConnectedIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 1; /* CsrWifiRouterCtrlPeerStatus primitive->peerStatus */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlConnectedIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlConnectedInd *primitive = (CsrWifiRouterCtrlConnectedInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->peerStatus); + return(ptr); +} + + +void* CsrWifiRouterCtrlConnectedIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlConnectedInd *primitive = (CsrWifiRouterCtrlConnectedInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlConnectedInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->peerStatus, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlPeerAddCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 19) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 4; /* CsrWifiRouterCtrlPeerRecordHandle primitive->peerRecordHandle */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPeerAddCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPeerAddCfm *primitive = (CsrWifiRouterCtrlPeerAddCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->peerRecordHandle); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlPeerAddCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPeerAddCfm *primitive = (CsrWifiRouterCtrlPeerAddCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerAddCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint32Des((CsrUint32 *) &primitive->peerRecordHandle, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlPeerDelCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPeerDelCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPeerDelCfm *primitive = (CsrWifiRouterCtrlPeerDelCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlPeerDelCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPeerDelCfm *primitive = (CsrWifiRouterCtrlPeerDelCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerDelCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlUnexpectedFrameIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlUnexpectedFrameIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlUnexpectedFrameInd *primitive = (CsrWifiRouterCtrlUnexpectedFrameInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiRouterCtrlUnexpectedFrameIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlUnexpectedFrameInd *primitive = (CsrWifiRouterCtrlUnexpectedFrameInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlUnexpectedFrameInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlPeerUpdateCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlPeerUpdateCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlPeerUpdateCfm *primitive = (CsrWifiRouterCtrlPeerUpdateCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlPeerUpdateCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlPeerUpdateCfm *primitive = (CsrWifiRouterCtrlPeerUpdateCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlPeerUpdateCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlCapabilitiesCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->commandQueueSize */ + bufferSize += 2; /* CsrUint16 primitive->trafficQueueSize */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlCapabilitiesCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlCapabilitiesCfm *primitive = (CsrWifiRouterCtrlCapabilitiesCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->commandQueueSize); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->trafficQueueSize); + return(ptr); +} + + +void* CsrWifiRouterCtrlCapabilitiesCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlCapabilitiesCfm *primitive = (CsrWifiRouterCtrlCapabilitiesCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlCapabilitiesCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->commandQueueSize, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->trafficQueueSize, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlBlockAckEnableCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlBlockAckEnableCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlBlockAckEnableCfm *primitive = (CsrWifiRouterCtrlBlockAckEnableCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlBlockAckEnableCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlBlockAckEnableCfm *primitive = (CsrWifiRouterCtrlBlockAckEnableCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckEnableCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlBlockAckDisableCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlBlockAckDisableCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlBlockAckDisableCfm *primitive = (CsrWifiRouterCtrlBlockAckDisableCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlBlockAckDisableCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlBlockAckDisableCfm *primitive = (CsrWifiRouterCtrlBlockAckDisableCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckDisableCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlBlockAckErrorIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 16) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiRouterCtrlTrafficStreamId primitive->trafficStreamID */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlBlockAckErrorIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlBlockAckErrorInd *primitive = (CsrWifiRouterCtrlBlockAckErrorInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->trafficStreamID); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlBlockAckErrorIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlBlockAckErrorInd *primitive = (CsrWifiRouterCtrlBlockAckErrorInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlBlockAckErrorInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->trafficStreamID, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->staAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlStaInactiveIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlStaInactiveInd *primitive = (CsrWifiRouterCtrlStaInactiveInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->staAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiRouterCtrlStaInactiveIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlStaInactiveInd *primitive = (CsrWifiRouterCtrlStaInactiveInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlStaInactiveInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->staAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg) +{ + CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrUint16 primitive->signalLength */ + bufferSize += primitive->signalLength; /* CsrUint8 primitive->signal */ + bufferSize += 2; /* CsrUint16 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->signalLength); + if (primitive->signalLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->signal, ((CsrUint16) (primitive->signalLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->signalLength, buffer, &offset); + if (primitive->signalLength) + { + primitive->signal = (CsrUint8 *)CsrPmemAlloc(primitive->signalLength); + CsrMemCpyDes(primitive->signal, buffer, &offset, ((CsrUint16) (primitive->signalLength))); + } + else + { + primitive->signal = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) voidPrimitivePointer; + CsrPmemFree(primitive->signal); + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h new file mode 100644 index 000000000000..5d82f8d0daa6 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h @@ -0,0 +1,323 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__ +#define CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_wifi_msgconv.h" + +#include "csr_wifi_router_ctrl_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void CsrWifiRouterCtrlPfree(void *ptr); + +extern CsrUint8* CsrWifiRouterCtrlConfigurePowerModeReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlConfigurePowerModeReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlConfigurePowerModeReqSizeof(void *msg); +#define CsrWifiRouterCtrlConfigurePowerModeReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlHipReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlHipReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlHipReqSizeof(void *msg); +extern void CsrWifiRouterCtrlHipReqSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlMediaStatusReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlMediaStatusReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlMediaStatusReqSizeof(void *msg); +#define CsrWifiRouterCtrlMediaStatusReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlMulticastAddressResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlMulticastAddressResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlMulticastAddressResSizeof(void *msg); +extern void CsrWifiRouterCtrlMulticastAddressResSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlPortConfigureReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPortConfigureReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPortConfigureReqSizeof(void *msg); +#define CsrWifiRouterCtrlPortConfigureReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlQosControlReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlQosControlReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlQosControlReqSizeof(void *msg); +#define CsrWifiRouterCtrlQosControlReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlSuspendResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlSuspendResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlSuspendResSizeof(void *msg); +#define CsrWifiRouterCtrlSuspendResSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTclasAddReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTclasAddReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTclasAddReqSizeof(void *msg); +extern void CsrWifiRouterCtrlTclasAddReqSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlResumeResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlResumeResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlResumeResSizeof(void *msg); +#define CsrWifiRouterCtrlResumeResSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlRawSdioInitialiseReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlRawSdioInitialiseReqDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlRawSdioInitialiseReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlRawSdioInitialiseReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTclasDelReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTclasDelReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTclasDelReqSizeof(void *msg); +extern void CsrWifiRouterCtrlTclasDelReqSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlTrafficClassificationReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTrafficClassificationReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTrafficClassificationReqSizeof(void *msg); +#define CsrWifiRouterCtrlTrafficClassificationReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTrafficConfigReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTrafficConfigReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTrafficConfigReqSizeof(void *msg); +#define CsrWifiRouterCtrlTrafficConfigReqSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlWifiOffReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlWifiOffReqDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlWifiOffReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlWifiOffReqSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlWifiOffResSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlWifiOffResDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlWifiOffResSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlWifiOffResSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlWifiOnReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlWifiOnReqDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlWifiOnReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlWifiOnReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlWifiOnResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWifiOnResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWifiOnResSizeof(void *msg); +extern void CsrWifiRouterCtrlWifiOnResSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlM4TransmitReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlM4TransmitReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlM4TransmitReqSizeof(void *msg); +#define CsrWifiRouterCtrlM4TransmitReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlModeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlModeSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlModeSetReqSizeof(void *msg); +#define CsrWifiRouterCtrlModeSetReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlPeerAddReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPeerAddReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPeerAddReqSizeof(void *msg); +#define CsrWifiRouterCtrlPeerAddReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlPeerDelReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPeerDelReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPeerDelReqSizeof(void *msg); +#define CsrWifiRouterCtrlPeerDelReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlPeerUpdateReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPeerUpdateReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPeerUpdateReqSizeof(void *msg); +#define CsrWifiRouterCtrlPeerUpdateReqSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlCapabilitiesReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlCapabilitiesReqDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlCapabilitiesReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlCapabilitiesReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlBlockAckEnableReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlBlockAckEnableReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlBlockAckEnableReqSizeof(void *msg); +#define CsrWifiRouterCtrlBlockAckEnableReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlBlockAckDisableReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlBlockAckDisableReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg); +#define CsrWifiRouterCtrlBlockAckDisableReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg); +extern void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *msg); + +#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint8Ser +#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint8Des +#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint8Sizeof +#define CsrWifiRouterCtrlWapiMulticastFilterReqSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint8Ser +#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint8Des +#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint8Sizeof +#define CsrWifiRouterCtrlWapiUnicastFilterReqSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlHipIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlHipIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg); +extern void CsrWifiRouterCtrlHipIndSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlMulticastAddressIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlMulticastAddressIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlMulticastAddressIndSizeof(void *msg); +extern void CsrWifiRouterCtrlMulticastAddressIndSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlPortConfigureCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPortConfigureCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPortConfigureCfmSizeof(void *msg); +#define CsrWifiRouterCtrlPortConfigureCfmSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlResumeIndSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiRouterCtrlResumeIndDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiRouterCtrlResumeIndSizeof CsrWifiEventCsrUint16CsrUint8Sizeof +#define CsrWifiRouterCtrlResumeIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlSuspendIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlSuspendIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlSuspendIndSizeof(void *msg); +#define CsrWifiRouterCtrlSuspendIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTclasAddCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTclasAddCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTclasAddCfmSizeof(void *msg); +#define CsrWifiRouterCtrlTclasAddCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlRawSdioDeinitialiseCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlRawSdioDeinitialiseCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlRawSdioDeinitialiseCfmSizeof(void *msg); +#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlRawSdioInitialiseCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlRawSdioInitialiseCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlRawSdioInitialiseCfmSizeof(void *msg); +#define CsrWifiRouterCtrlRawSdioInitialiseCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTclasDelCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTclasDelCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTclasDelCfmSizeof(void *msg); +#define CsrWifiRouterCtrlTclasDelCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTrafficProtocolIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTrafficProtocolIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTrafficProtocolIndSizeof(void *msg); +#define CsrWifiRouterCtrlTrafficProtocolIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlTrafficSampleIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlTrafficSampleIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlTrafficSampleIndSizeof(void *msg); +#define CsrWifiRouterCtrlTrafficSampleIndSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlWifiOffIndSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiRouterCtrlWifiOffIndDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiRouterCtrlWifiOffIndSizeof CsrWifiEventCsrUint16CsrUint8Sizeof +#define CsrWifiRouterCtrlWifiOffIndSerFree CsrWifiRouterCtrlPfree + +#define CsrWifiRouterCtrlWifiOffCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiRouterCtrlWifiOffCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiRouterCtrlWifiOffCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiRouterCtrlWifiOffCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlWifiOnIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWifiOnIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWifiOnIndSizeof(void *msg); +extern void CsrWifiRouterCtrlWifiOnIndSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlWifiOnCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWifiOnCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWifiOnCfmSizeof(void *msg); +#define CsrWifiRouterCtrlWifiOnCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlM4ReadyToSendIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlM4ReadyToSendIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlM4ReadyToSendIndSizeof(void *msg); +#define CsrWifiRouterCtrlM4ReadyToSendIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlM4TransmittedIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlM4TransmittedIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlM4TransmittedIndSizeof(void *msg); +#define CsrWifiRouterCtrlM4TransmittedIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlMicFailureIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlMicFailureIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlMicFailureIndSizeof(void *msg); +#define CsrWifiRouterCtrlMicFailureIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlConnectedIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlConnectedIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlConnectedIndSizeof(void *msg); +#define CsrWifiRouterCtrlConnectedIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlPeerAddCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPeerAddCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPeerAddCfmSizeof(void *msg); +#define CsrWifiRouterCtrlPeerAddCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlPeerDelCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPeerDelCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPeerDelCfmSizeof(void *msg); +#define CsrWifiRouterCtrlPeerDelCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlUnexpectedFrameIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlUnexpectedFrameIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlUnexpectedFrameIndSizeof(void *msg); +#define CsrWifiRouterCtrlUnexpectedFrameIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlPeerUpdateCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlPeerUpdateCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlPeerUpdateCfmSizeof(void *msg); +#define CsrWifiRouterCtrlPeerUpdateCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlCapabilitiesCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlCapabilitiesCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlCapabilitiesCfmSizeof(void *msg); +#define CsrWifiRouterCtrlCapabilitiesCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlBlockAckEnableCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlBlockAckEnableCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlBlockAckEnableCfmSizeof(void *msg); +#define CsrWifiRouterCtrlBlockAckEnableCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlBlockAckDisableCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlBlockAckDisableCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlBlockAckDisableCfmSizeof(void *msg); +#define CsrWifiRouterCtrlBlockAckDisableCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlBlockAckErrorIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlBlockAckErrorIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlBlockAckErrorIndSizeof(void *msg); +#define CsrWifiRouterCtrlBlockAckErrorIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlStaInactiveIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlStaInactiveIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg); +#define CsrWifiRouterCtrlStaInactiveIndSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg); +extern void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *msg); + + +#ifdef __cplusplus +} +#endif +#endif /* CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c new file mode 100644 index 000000000000..9ae6cff640ec --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c @@ -0,0 +1,54 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_router_prim.h" +#include "csr_wifi_router_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiRouterFreeDownstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_ROUTER_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiRouterFreeDownstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_ROUTER_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiRouterPrim *) message)) + { + case CSR_WIFI_ROUTER_MA_PACKET_REQ: + { + CsrWifiRouterMaPacketReq *p = (CsrWifiRouterMaPacketReq *)message; + CsrPmemFree(p->frame); + p->frame = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c new file mode 100644 index 000000000000..19d9c23f6dd0 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c @@ -0,0 +1,54 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_router_prim.h" +#include "csr_wifi_router_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiRouterFreeUpstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_ROUTER_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiRouterFreeUpstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_ROUTER_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiRouterPrim *) message)) + { + case CSR_WIFI_ROUTER_MA_PACKET_IND: + { + CsrWifiRouterMaPacketInd *p = (CsrWifiRouterMaPacketInd *)message; + CsrPmemFree(p->frame); + p->frame = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_router_lib.h b/drivers/staging/csr/csr_wifi_router_lib.h new file mode 100644 index 000000000000..553e7d36e35c --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_lib.h @@ -0,0 +1,429 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_LIB_H__ +#define CSR_WIFI_ROUTER_LIB_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_sched.h" +#include "csr_util.h" +#include "csr_msg_transport.h" + +#include "csr_wifi_lib.h" + +#include "csr_wifi_router_prim.h" +#include "csr_wifi_router_task.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiRouterFreeUpstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_ROUTER upstream message. Does not + * free the message itself, and can only be used for upstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_ROUTER upstream message + *----------------------------------------------------------------------------*/ +void CsrWifiRouterFreeUpstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * CsrWifiRouterFreeDownstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_ROUTER downstream message. Does not + * free the message itself, and can only be used for downstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_ROUTER downstream message + *----------------------------------------------------------------------------*/ +void CsrWifiRouterFreeDownstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * Enum to string functions + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiRouterAppTypeToString(CsrWifiRouterAppType value); +const CsrCharString* CsrWifiRouterEncapsulationToString(CsrWifiRouterEncapsulation value); +const CsrCharString* CsrWifiRouterOuiToString(CsrWifiRouterOui value); +const CsrCharString* CsrWifiRouterPriorityToString(CsrWifiRouterPriority value); + + +/*----------------------------------------------------------------------------* + * CsrPrim Type toString function. + * Converts a message type to the String name of the Message + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiRouterPrimTypeToString(CsrPrim msgType); + +/*----------------------------------------------------------------------------* + * Lookup arrays for PrimType name Strings + *----------------------------------------------------------------------------*/ +extern const CsrCharString *CsrWifiRouterUpstreamPrimNames[CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT]; +extern const CsrCharString *CsrWifiRouterDownstreamPrimNames[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT]; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketCancelReqSend + + DESCRIPTION + This primitive is used to request cancellation of a previously send + CsrWifiRouterMaPacketReq. + The frame may already have been transmitted so there is no guarantees + that the CsrWifiRouterMaPacketCancelReq actually cancels the transmission + of the frame in question. + If the cancellation fails, the Router will send, if required, + CsrWifiRouterMaPacketCfm. + If the cancellation succeeds, the Router will not send + CsrWifiRouterMaPacketCfm. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + hostTag - The hostTag for the frame, which should be cancelled. + priority - Priority of the frame, which should be cancelled + peerMacAddress - Destination MAC address of the frame, which should be + cancelled + +*******************************************************************************/ +#define CsrWifiRouterMaPacketCancelReqCreate(msg__, dst__, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) \ + msg__ = (CsrWifiRouterMaPacketCancelReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketCancelReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_CANCEL_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->hostTag = (hostTag__); \ + msg__->priority = (priority__); \ + msg__->peerMacAddress = (peerMacAddress__); + +#define CsrWifiRouterMaPacketCancelReqSendTo(dst__, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) \ + { \ + CsrWifiRouterMaPacketCancelReq *msg__; \ + CsrWifiRouterMaPacketCancelReqCreate(msg__, dst__, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketCancelReqSend(src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) \ + CsrWifiRouterMaPacketCancelReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketReqSend + + DESCRIPTION + A task sends this primitive to transmit a frame. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + frameLength - Length of the frame to be sent in bytes + frame - Pointer to the frame to be sent + freeFunction - Pointer to function to be used to free the frame + priority - Priority of the frame, which should be sent + hostTag - An application shall set the bits b31..b28 using one of + the CSR_WIFI_ROUTER_APP_TYPE_* masks. Bits b0..b27 can + be used by the requestor without any restrictions, but + the hostTag shall be unique so the hostTag for + CSR_WIFI_ROUTER_APP _TYPE_OTHER should be constructured + in the following way [ CSR_WIFI_ROUTER_APP_TYPE_OTHER + (4 bits) | SubscriptionHandle (8 bits) | Sequence no. + (20 bits) ]. If the hostTag is not unique, the + behaviour of the system is unpredicatable with respect + to data/management frame transfer. + cfmRequested - Indicates if the requestor needs a confirm for packet + requests sent under this subscription. If set to TRUE, + the router will send a confirm, else it will not send + any confirm + +*******************************************************************************/ +#define CsrWifiRouterMaPacketReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) \ + msg__ = (CsrWifiRouterMaPacketReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->subscriptionHandle = (subscriptionHandle__); \ + msg__->frameLength = (frameLength__); \ + msg__->frame = (frame__); \ + msg__->freeFunction = (freeFunction__); \ + msg__->priority = (priority__); \ + msg__->hostTag = (hostTag__); \ + msg__->cfmRequested = (cfmRequested__); + +#define CsrWifiRouterMaPacketReqSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) \ + { \ + CsrWifiRouterMaPacketReq *msg__; \ + CsrWifiRouterMaPacketReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketReqSend(src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) \ + CsrWifiRouterMaPacketReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketIndSend + + DESCRIPTION + The router sends the primitive to a subscribed task when it receives a + frame matching the subscription. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + result - Status of the operation + frameLength - Length of the received frame in bytes + frame - Pointer to the received frame + freeFunction - Pointer to function to be used to free the frame + rssi - Received signal strength indication in dBm + snr - Signal to Noise Ratio + rate - Transmission/Reception rate + +*******************************************************************************/ +#define CsrWifiRouterMaPacketIndCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) \ + msg__ = (CsrWifiRouterMaPacketInd *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->subscriptionHandle = (subscriptionHandle__); \ + msg__->result = (result__); \ + msg__->frameLength = (frameLength__); \ + msg__->frame = (frame__); \ + msg__->freeFunction = (freeFunction__); \ + msg__->rssi = (rssi__); \ + msg__->snr = (snr__); \ + msg__->rate = (rate__); + +#define CsrWifiRouterMaPacketIndSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) \ + { \ + CsrWifiRouterMaPacketInd *msg__; \ + CsrWifiRouterMaPacketIndCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketIndSend(dst__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) \ + CsrWifiRouterMaPacketIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketResSend + + DESCRIPTION + A task send this primitive to confirm the reception of the received + frame. + + PARAMETERS + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + result - Status of the operation + +*******************************************************************************/ +#define CsrWifiRouterMaPacketResCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__) \ + msg__ = (CsrWifiRouterMaPacketRes *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketRes)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_RES, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->subscriptionHandle = (subscriptionHandle__); \ + msg__->result = (result__); + +#define CsrWifiRouterMaPacketResSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, result__) \ + { \ + CsrWifiRouterMaPacketRes *msg__; \ + CsrWifiRouterMaPacketResCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketResSend(src__, interfaceTag__, subscriptionHandle__, result__) \ + CsrWifiRouterMaPacketResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, subscriptionHandle__, result__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketCfmSend + + DESCRIPTION + The router sends the primitive to confirm the result of the transmission + of the packet of the corresponding CSR_WIFI_ROUTER MA_PACKET_REQ request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + result - Status of the operation + hostTag - The hostTrag will match the hostTag sent in the request. + rate - Transmission/Reception rate + +*******************************************************************************/ +#define CsrWifiRouterMaPacketCfmCreate(msg__, dst__, src__, interfaceTag__, result__, hostTag__, rate__) \ + msg__ = (CsrWifiRouterMaPacketCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->result = (result__); \ + msg__->hostTag = (hostTag__); \ + msg__->rate = (rate__); + +#define CsrWifiRouterMaPacketCfmSendTo(dst__, src__, interfaceTag__, result__, hostTag__, rate__) \ + { \ + CsrWifiRouterMaPacketCfm *msg__; \ + CsrWifiRouterMaPacketCfmCreate(msg__, dst__, src__, interfaceTag__, result__, hostTag__, rate__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketCfmSend(dst__, interfaceTag__, result__, hostTag__, rate__) \ + CsrWifiRouterMaPacketCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, result__, hostTag__, rate__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketSubscribeReqSend + + DESCRIPTION + A task can use this primitive to subscribe for a particular OUI/protocol + and transmit and receive frames matching the subscription. + NOTE: Multiple subscriptions for a given protocol and OUI will result in + the first subscription receiving the data and not the subsequent + subscriptions. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + encapsulation - Specifies the encapsulation type, which will be used for the + subscription + protocol - Together with the OUI, specifies the protocol, which a task + wants to subscribe to + oui - Specifies the OUI for the protocol, which a task wants to + subscribe to + +*******************************************************************************/ +#define CsrWifiRouterMaPacketSubscribeReqCreate(msg__, dst__, src__, interfaceTag__, encapsulation__, protocol__, oui__) \ + msg__ = (CsrWifiRouterMaPacketSubscribeReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketSubscribeReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->encapsulation = (encapsulation__); \ + msg__->protocol = (protocol__); \ + msg__->oui = (oui__); + +#define CsrWifiRouterMaPacketSubscribeReqSendTo(dst__, src__, interfaceTag__, encapsulation__, protocol__, oui__) \ + { \ + CsrWifiRouterMaPacketSubscribeReq *msg__; \ + CsrWifiRouterMaPacketSubscribeReqCreate(msg__, dst__, src__, interfaceTag__, encapsulation__, protocol__, oui__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketSubscribeReqSend(src__, interfaceTag__, encapsulation__, protocol__, oui__) \ + CsrWifiRouterMaPacketSubscribeReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, encapsulation__, protocol__, oui__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketSubscribeCfmSend + + DESCRIPTION + The router sends this primitive to confirm the result of the + subscription. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - Handle to the subscription + This handle must be used in all subsequent requests + status - Status of the operation + allocOffset - Size of the offset for the frames of the subscription + +*******************************************************************************/ +#define CsrWifiRouterMaPacketSubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, status__, allocOffset__) \ + msg__ = (CsrWifiRouterMaPacketSubscribeCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketSubscribeCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->subscriptionHandle = (subscriptionHandle__); \ + msg__->status = (status__); \ + msg__->allocOffset = (allocOffset__); + +#define CsrWifiRouterMaPacketSubscribeCfmSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, status__, allocOffset__) \ + { \ + CsrWifiRouterMaPacketSubscribeCfm *msg__; \ + CsrWifiRouterMaPacketSubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, status__, allocOffset__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketSubscribeCfmSend(dst__, interfaceTag__, subscriptionHandle__, status__, allocOffset__) \ + CsrWifiRouterMaPacketSubscribeCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, subscriptionHandle__, status__, allocOffset__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketUnsubscribeReqSend + + DESCRIPTION + A task sends this primitive to unsubscribe a subscription + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + +*******************************************************************************/ +#define CsrWifiRouterMaPacketUnsubscribeReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__) \ + msg__ = (CsrWifiRouterMaPacketUnsubscribeReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketUnsubscribeReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->subscriptionHandle = (subscriptionHandle__); + +#define CsrWifiRouterMaPacketUnsubscribeReqSendTo(dst__, src__, interfaceTag__, subscriptionHandle__) \ + { \ + CsrWifiRouterMaPacketUnsubscribeReq *msg__; \ + CsrWifiRouterMaPacketUnsubscribeReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketUnsubscribeReqSend(src__, interfaceTag__, subscriptionHandle__) \ + CsrWifiRouterMaPacketUnsubscribeReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, subscriptionHandle__) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketUnsubscribeCfmSend + + DESCRIPTION + The router sends this primitive to confirm the result of the + unsubscription. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Status of the operation + +*******************************************************************************/ +#define CsrWifiRouterMaPacketUnsubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiRouterMaPacketUnsubscribeCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketUnsubscribeCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiRouterMaPacketUnsubscribeCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiRouterMaPacketUnsubscribeCfm *msg__; \ + CsrWifiRouterMaPacketUnsubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \ + } + +#define CsrWifiRouterMaPacketUnsubscribeCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiRouterMaPacketUnsubscribeCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, status__) + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_prim.h b/drivers/staging/csr/csr_wifi_router_prim.h new file mode 100644 index 000000000000..67b71a4739a9 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_prim.h @@ -0,0 +1,430 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_PRIM_H__ +#define CSR_WIFI_ROUTER_PRIM_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_wifi_common.h" +#include "csr_result.h" +#include "csr_wifi_fsm_event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSR_WIFI_ROUTER_PRIM (0x0400) + +typedef CsrPrim CsrWifiRouterPrim; + +typedef void (*CsrWifiRouterFrameFreeFunction)(void *frame); + +/******************************************************************************* + + NAME + CsrWifiRouterAppType + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_APP_TYPE_SME - + CSR_WIFI_ROUTER_APP_TYPE_PAL - + CSR_WIFI_ROUTER_APP_TYPE_NME - + CSR_WIFI_ROUTER_APP_TYPE_OTHER - + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterAppType; +#define CSR_WIFI_ROUTER_APP_TYPE_SME ((CsrWifiRouterAppType) 0x0) +#define CSR_WIFI_ROUTER_APP_TYPE_PAL ((CsrWifiRouterAppType) 0x1) +#define CSR_WIFI_ROUTER_APP_TYPE_NME ((CsrWifiRouterAppType) 0x2) +#define CSR_WIFI_ROUTER_APP_TYPE_OTHER ((CsrWifiRouterAppType) 0x3) + +/******************************************************************************* + + NAME + CsrWifiRouterEncapsulation + + DESCRIPTION + Indicates the type of encapsulation used for the subscription + + VALUES + CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET + - Ethernet encapsulation + CSR_WIFI_ROUTER_ENCAPSULATION_LLC_SNAP + - LLC/SNAP encapsulation + +*******************************************************************************/ +typedef CsrUint8 CsrWifiRouterEncapsulation; +#define CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET ((CsrWifiRouterEncapsulation) 0x00) +#define CSR_WIFI_ROUTER_ENCAPSULATION_LLC_SNAP ((CsrWifiRouterEncapsulation) 0x01) + +/******************************************************************************* + + NAME + CsrWifiRouterOui + + DESCRIPTION + + VALUES + CSR_WIFI_ROUTER_OUI_RFC_1042 - + CSR_WIFI_ROUTER_OUI_BT - + +*******************************************************************************/ +typedef CsrUint32 CsrWifiRouterOui; +#define CSR_WIFI_ROUTER_OUI_RFC_1042 ((CsrWifiRouterOui) 0x000000) +#define CSR_WIFI_ROUTER_OUI_BT ((CsrWifiRouterOui) 0x001958) + +/******************************************************************************* + + NAME + CsrWifiRouterPriority + + DESCRIPTION + As defined in the IEEE 802.11 standards + + VALUES + CSR_WIFI_ROUTER_PRIORITY_QOS_UP0 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP1 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP2 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP3 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP4 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP5 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP6 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_QOS_UP7 + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_CONTENTION + - See IEEE 802.11 Standard + CSR_WIFI_ROUTER_PRIORITY_MANAGEMENT + - See IEEE 802.11 Standard + +*******************************************************************************/ +typedef CsrUint16 CsrWifiRouterPriority; +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP0 ((CsrWifiRouterPriority) 0x0000) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP1 ((CsrWifiRouterPriority) 0x0001) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP2 ((CsrWifiRouterPriority) 0x0002) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP3 ((CsrWifiRouterPriority) 0x0003) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP4 ((CsrWifiRouterPriority) 0x0004) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP5 ((CsrWifiRouterPriority) 0x0005) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP6 ((CsrWifiRouterPriority) 0x0006) +#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP7 ((CsrWifiRouterPriority) 0x0007) +#define CSR_WIFI_ROUTER_PRIORITY_CONTENTION ((CsrWifiRouterPriority) 0x8000) +#define CSR_WIFI_ROUTER_PRIORITY_MANAGEMENT ((CsrWifiRouterPriority) 0x8010) + + +/* Downstream */ +#define CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST (0x0000) + +#define CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_REQ ((CsrWifiRouterPrim) (0x0000 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_REQ ((CsrWifiRouterPrim) (0x0001 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_REQ ((CsrWifiRouterPrim) (0x0002 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_RES ((CsrWifiRouterPrim) (0x0003 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_CANCEL_REQ ((CsrWifiRouterPrim) (0x0004 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)) + + +#define CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_HIGHEST (0x0004 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST) + +/* Upstream */ +#define CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) + +#define CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_CFM ((CsrWifiRouterPrim)(0x0000 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_CFM ((CsrWifiRouterPrim)(0x0001 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_CFM ((CsrWifiRouterPrim)(0x0002 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_MA_PACKET_IND ((CsrWifiRouterPrim)(0x0003 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST)) + +#define CSR_WIFI_ROUTER_PRIM_UPSTREAM_HIGHEST (0x0003 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST) + +#define CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT (CSR_WIFI_ROUTER_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST) + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketSubscribeReq + + DESCRIPTION + A task can use this primitive to subscribe for a particular OUI/protocol + and transmit and receive frames matching the subscription. + NOTE: Multiple subscriptions for a given protocol and OUI will result in + the first subscription receiving the data and not the subsequent + subscriptions. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + encapsulation - Specifies the encapsulation type, which will be used for the + subscription + protocol - Together with the OUI, specifies the protocol, which a task + wants to subscribe to + oui - Specifies the OUI for the protocol, which a task wants to + subscribe to + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiRouterEncapsulation encapsulation; + CsrUint16 protocol; + CsrUint32 oui; +} CsrWifiRouterMaPacketSubscribeReq; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketUnsubscribeReq + + DESCRIPTION + A task sends this primitive to unsubscribe a subscription + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 subscriptionHandle; +} CsrWifiRouterMaPacketUnsubscribeReq; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketReq + + DESCRIPTION + A task sends this primitive to transmit a frame. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + frameLength - Length of the frame to be sent in bytes + frame - Pointer to the frame to be sent + freeFunction - Pointer to function to be used to free the frame + priority - Priority of the frame, which should be sent + hostTag - An application shall set the bits b31..b28 using one of + the CSR_WIFI_ROUTER_APP_TYPE_* masks. Bits b0..b27 can + be used by the requestor without any restrictions, but + the hostTag shall be unique so the hostTag for + CSR_WIFI_ROUTER_APP _TYPE_OTHER should be constructured + in the following way [ CSR_WIFI_ROUTER_APP_TYPE_OTHER + (4 bits) | SubscriptionHandle (8 bits) | Sequence no. + (20 bits) ]. If the hostTag is not unique, the + behaviour of the system is unpredicatable with respect + to data/management frame transfer. + cfmRequested - Indicates if the requestor needs a confirm for packet + requests sent under this subscription. If set to TRUE, + the router will send a confirm, else it will not send + any confirm + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 subscriptionHandle; + CsrUint16 frameLength; + CsrUint8 *frame; + CsrWifiRouterFrameFreeFunction freeFunction; + CsrWifiRouterPriority priority; + CsrUint32 hostTag; + CsrBool cfmRequested; +} CsrWifiRouterMaPacketReq; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketRes + + DESCRIPTION + A task send this primitive to confirm the reception of the received + frame. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + result - Status of the operation + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 subscriptionHandle; + CsrResult result; +} CsrWifiRouterMaPacketRes; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketCancelReq + + DESCRIPTION + This primitive is used to request cancellation of a previously send + CsrWifiRouterMaPacketReq. + The frame may already have been transmitted so there is no guarantees + that the CsrWifiRouterMaPacketCancelReq actually cancels the transmission + of the frame in question. + If the cancellation fails, the Router will send, if required, + CsrWifiRouterMaPacketCfm. + If the cancellation succeeds, the Router will not send + CsrWifiRouterMaPacketCfm. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + hostTag - The hostTag for the frame, which should be cancelled. + priority - Priority of the frame, which should be cancelled + peerMacAddress - Destination MAC address of the frame, which should be + cancelled + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint32 hostTag; + CsrWifiRouterPriority priority; + CsrWifiMacAddress peerMacAddress; +} CsrWifiRouterMaPacketCancelReq; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketSubscribeCfm + + DESCRIPTION + The router sends this primitive to confirm the result of the + subscription. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - Handle to the subscription + This handle must be used in all subsequent requests + status - Status of the operation + allocOffset - Size of the offset for the frames of the subscription + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 subscriptionHandle; + CsrResult status; + CsrUint16 allocOffset; +} CsrWifiRouterMaPacketSubscribeCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketUnsubscribeCfm + + DESCRIPTION + The router sends this primitive to confirm the result of the + unsubscription. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Status of the operation + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiRouterMaPacketUnsubscribeCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketCfm + + DESCRIPTION + The router sends the primitive to confirm the result of the transmission + of the packet of the corresponding CSR_WIFI_ROUTER MA_PACKET_REQ request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + result - Status of the operation + hostTag - The hostTrag will match the hostTag sent in the request. + rate - Transmission/Reception rate + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult result; + CsrUint32 hostTag; + CsrUint16 rate; +} CsrWifiRouterMaPacketCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterMaPacketInd + + DESCRIPTION + The router sends the primitive to a subscribed task when it receives a + frame matching the subscription. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + subscriptionHandle - The handle of the subscription + result - Status of the operation + frameLength - Length of the received frame in bytes + frame - Pointer to the received frame + freeFunction - Pointer to function to be used to free the frame + rssi - Received signal strength indication in dBm + snr - Signal to Noise Ratio + rate - Transmission/Reception rate + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 subscriptionHandle; + CsrResult result; + CsrUint16 frameLength; + CsrUint8 *frame; + CsrWifiRouterFrameFreeFunction freeFunction; + CsrInt16 rssi; + CsrInt16 snr; + CsrUint16 rate; +} CsrWifiRouterMaPacketInd; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_PRIM_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_router_sef.c b/drivers/staging/csr/csr_wifi_router_sef.c new file mode 100644 index 000000000000..45a10fb77296 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_sef.c @@ -0,0 +1,19 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + + *****************************************************************************/ +#include "csr_wifi_router_sef.h" + +const CsrWifiRouterStateHandlerType CsrWifiRouterDownstreamStateHandlers[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT] = +{ + /* 0x0000 */ CsrWifiRouterMaPacketSubscribeReqHandler, + /* 0x0001 */ CsrWifiRouterMaPacketUnsubscribeReqHandler, + /* 0x0002 */ CsrWifiRouterMaPacketReqHandler, + /* 0x0003 */ CsrWifiRouterMaPacketResHandler, + /* 0x0004 */ CsrWifiRouterMaPacketCancelReqHandler, +}; diff --git a/drivers/staging/csr/csr_wifi_router_sef.h b/drivers/staging/csr/csr_wifi_router_sef.h new file mode 100644 index 000000000000..49dd158fa98d --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_sef.h @@ -0,0 +1,33 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + + *****************************************************************************/ +#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__ +#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__ + +#include "csr_wifi_router_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef void (*CsrWifiRouterStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg); + + extern const CsrWifiRouterStateHandlerType CsrWifiRouterDownstreamStateHandlers[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT]; + + extern void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_serialize.c b/drivers/staging/csr/csr_wifi_router_serialize.c new file mode 100644 index 000000000000..e1adf8f03646 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_serialize.c @@ -0,0 +1,422 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_msgconv.h" +#include "csr_unicode.h" + + +#include "csr_wifi_router_prim.h" +#include "csr_wifi_router_serialize.h" + +void CsrWifiRouterPfree(void *ptr) +{ + CsrPmemFree(ptr); +} + + +CsrSize CsrWifiRouterMaPacketSubscribeReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiRouterEncapsulation primitive->encapsulation */ + bufferSize += 2; /* CsrUint16 primitive->protocol */ + bufferSize += 4; /* CsrUint32 primitive->oui */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketSubscribeReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketSubscribeReq *primitive = (CsrWifiRouterMaPacketSubscribeReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->encapsulation); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->protocol); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->oui); + return(ptr); +} + + +void* CsrWifiRouterMaPacketSubscribeReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketSubscribeReq *primitive = (CsrWifiRouterMaPacketSubscribeReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketSubscribeReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->encapsulation, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->protocol, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->oui, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterMaPacketReqSizeof(void *msg) +{ + CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 20) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->subscriptionHandle */ + bufferSize += 2; /* CsrUint16 primitive->frameLength */ + bufferSize += primitive->frameLength; /* CsrUint8 primitive->frame */ + bufferSize += 4; /* CsrWifiRouterFrameFreeFunction primitive->freeFunction */ + bufferSize += 2; /* CsrWifiRouterPriority primitive->priority */ + bufferSize += 4; /* CsrUint32 primitive->hostTag */ + bufferSize += 1; /* CsrBool primitive->cfmRequested */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->subscriptionHandle); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->frameLength); + if (primitive->frameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->frame, ((CsrUint16) (primitive->frameLength))); + } + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->freeFunction */ + CsrUint16Ser(ptr, len, (CsrUint16) primitive->priority); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->hostTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->cfmRequested); + return(ptr); +} + + +void* CsrWifiRouterMaPacketReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->subscriptionHandle, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->frameLength, buffer, &offset); + if (primitive->frameLength) + { + primitive->frame = (CsrUint8 *)CsrPmemAlloc(primitive->frameLength); + CsrMemCpyDes(primitive->frame, buffer, &offset, ((CsrUint16) (primitive->frameLength))); + } + else + { + primitive->frame = NULL; + } + primitive->freeFunction = NULL; /* Special for Function Pointers... */ + offset += 4; + CsrUint16Des((CsrUint16 *) &primitive->priority, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->hostTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->cfmRequested, buffer, &offset); + + return primitive; +} + + +void CsrWifiRouterMaPacketReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *) voidPrimitivePointer; + CsrPmemFree(primitive->frame); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiRouterMaPacketResSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->subscriptionHandle */ + bufferSize += 2; /* CsrResult primitive->result */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketResSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketRes *primitive = (CsrWifiRouterMaPacketRes *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->subscriptionHandle); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result); + return(ptr); +} + + +void* CsrWifiRouterMaPacketResDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketRes *primitive = (CsrWifiRouterMaPacketRes *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketRes)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->subscriptionHandle, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterMaPacketCancelReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 4; /* CsrUint32 primitive->hostTag */ + bufferSize += 2; /* CsrWifiRouterPriority primitive->priority */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketCancelReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketCancelReq *primitive = (CsrWifiRouterMaPacketCancelReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->hostTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->priority); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiRouterMaPacketCancelReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketCancelReq *primitive = (CsrWifiRouterMaPacketCancelReq *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketCancelReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->hostTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->priority, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiRouterMaPacketSubscribeCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->subscriptionHandle */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->allocOffset */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketSubscribeCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketSubscribeCfm *primitive = (CsrWifiRouterMaPacketSubscribeCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->subscriptionHandle); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->allocOffset); + return(ptr); +} + + +void* CsrWifiRouterMaPacketSubscribeCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketSubscribeCfm *primitive = (CsrWifiRouterMaPacketSubscribeCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketSubscribeCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->subscriptionHandle, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->allocOffset, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterMaPacketUnsubscribeCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketUnsubscribeCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketUnsubscribeCfm *primitive = (CsrWifiRouterMaPacketUnsubscribeCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterMaPacketUnsubscribeCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketUnsubscribeCfm *primitive = (CsrWifiRouterMaPacketUnsubscribeCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketUnsubscribeCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterMaPacketCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->result */ + bufferSize += 4; /* CsrUint32 primitive->hostTag */ + bufferSize += 2; /* CsrUint16 primitive->rate */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketCfm *primitive = (CsrWifiRouterMaPacketCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->hostTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->rate); + return(ptr); +} + + +void* CsrWifiRouterMaPacketCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketCfm *primitive = (CsrWifiRouterMaPacketCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->hostTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->rate, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterMaPacketIndSizeof(void *msg) +{ + CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 21) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->subscriptionHandle */ + bufferSize += 2; /* CsrResult primitive->result */ + bufferSize += 2; /* CsrUint16 primitive->frameLength */ + bufferSize += primitive->frameLength; /* CsrUint8 primitive->frame */ + bufferSize += 4; /* CsrWifiRouterFrameFreeFunction primitive->freeFunction */ + bufferSize += 2; /* CsrInt16 primitive->rssi */ + bufferSize += 2; /* CsrInt16 primitive->snr */ + bufferSize += 2; /* CsrUint16 primitive->rate */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterMaPacketIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->subscriptionHandle); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->frameLength); + if (primitive->frameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->frame, ((CsrUint16) (primitive->frameLength))); + } + CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->freeFunction */ + CsrUint16Ser(ptr, len, (CsrUint16) primitive->rssi); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->snr); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->rate); + return(ptr); +} + + +void* CsrWifiRouterMaPacketIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *) CsrPmemAlloc(sizeof(CsrWifiRouterMaPacketInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->subscriptionHandle, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->frameLength, buffer, &offset); + if (primitive->frameLength) + { + primitive->frame = (CsrUint8 *)CsrPmemAlloc(primitive->frameLength); + CsrMemCpyDes(primitive->frame, buffer, &offset, ((CsrUint16) (primitive->frameLength))); + } + else + { + primitive->frame = NULL; + } + primitive->freeFunction = NULL; /* Special for Function Pointers... */ + offset += 4; + CsrUint16Des((CsrUint16 *) &primitive->rssi, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->snr, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->rate, buffer, &offset); + + return primitive; +} + + +void CsrWifiRouterMaPacketIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *) voidPrimitivePointer; + CsrPmemFree(primitive->frame); + CsrPmemFree(primitive); +} + + diff --git a/drivers/staging/csr/csr_wifi_router_serialize.h b/drivers/staging/csr/csr_wifi_router_serialize.h new file mode 100644 index 000000000000..183a5a48bb4e --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_serialize.h @@ -0,0 +1,78 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_SERIALIZE_H__ +#define CSR_WIFI_ROUTER_SERIALIZE_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_wifi_msgconv.h" + +#include "csr_wifi_router_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void CsrWifiRouterPfree(void *ptr); + +extern CsrUint8* CsrWifiRouterMaPacketSubscribeReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketSubscribeReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketSubscribeReqSizeof(void *msg); +#define CsrWifiRouterMaPacketSubscribeReqSerFree CsrWifiRouterPfree + +#define CsrWifiRouterMaPacketUnsubscribeReqSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiRouterMaPacketUnsubscribeReqDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiRouterMaPacketUnsubscribeReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof +#define CsrWifiRouterMaPacketUnsubscribeReqSerFree CsrWifiRouterPfree + +extern CsrUint8* CsrWifiRouterMaPacketReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketReqSizeof(void *msg); +extern void CsrWifiRouterMaPacketReqSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterMaPacketResSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketResDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketResSizeof(void *msg); +#define CsrWifiRouterMaPacketResSerFree CsrWifiRouterPfree + +extern CsrUint8* CsrWifiRouterMaPacketCancelReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketCancelReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketCancelReqSizeof(void *msg); +#define CsrWifiRouterMaPacketCancelReqSerFree CsrWifiRouterPfree + +extern CsrUint8* CsrWifiRouterMaPacketSubscribeCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketSubscribeCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketSubscribeCfmSizeof(void *msg); +#define CsrWifiRouterMaPacketSubscribeCfmSerFree CsrWifiRouterPfree + +extern CsrUint8* CsrWifiRouterMaPacketUnsubscribeCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketUnsubscribeCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketUnsubscribeCfmSizeof(void *msg); +#define CsrWifiRouterMaPacketUnsubscribeCfmSerFree CsrWifiRouterPfree + +extern CsrUint8* CsrWifiRouterMaPacketCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketCfmSizeof(void *msg); +#define CsrWifiRouterMaPacketCfmSerFree CsrWifiRouterPfree + +extern CsrUint8* CsrWifiRouterMaPacketIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterMaPacketIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterMaPacketIndSizeof(void *msg); +extern void CsrWifiRouterMaPacketIndSerFree(void *msg); + + +#ifdef __cplusplus +} +#endif +#endif /* CSR_WIFI_ROUTER_SERIALIZE_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_router_task.h b/drivers/staging/csr/csr_wifi_router_task.h new file mode 100644 index 000000000000..5bc460e4a393 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_task.h @@ -0,0 +1,34 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_ROUTER_TASK_H__ +#define CSR_WIFI_ROUTER_TASK_H__ + +#include "csr_types.h" +#include "csr_sched.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSR_WIFI_ROUTER_LOG_ID 0x1201FFFF +extern CsrSchedQid CSR_WIFI_ROUTER_IFACEQUEUE; +void CsrWifiRouterInit(void **gash); +void CsrWifiRouterDeinit(void **gash); +void CsrWifiRouterHandler(void **gash); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_TASK_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_router_transport.c b/drivers/staging/csr/csr_wifi_router_transport.c new file mode 100644 index 000000000000..ec7e01dda40c --- /dev/null +++ b/drivers/staging/csr/csr_wifi_router_transport.c @@ -0,0 +1,210 @@ +/** @file router_transport.c + * + * + * Copyright (C) Cambridge Silicon Radio Ltd 2006-2010. All rights reserved. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + ****************************************************************************/ + +#include "unifi_priv.h" + +#include "csr_types.h" +#include "csr_sched.h" +#include "csr_msgconv.h" + +#include "sme_userspace.h" + +#include "csr_wifi_hostio_prim.h" +#include "csr_wifi_router_lib.h" +#include "csr_wifi_router_sef.h" +#include "csr_wifi_router_converter_init.h" +#include "csr_wifi_router_ctrl_lib.h" +#include "csr_wifi_router_ctrl_sef.h" +#include "csr_wifi_router_ctrl_converter_init.h" +#include "csr_wifi_sme_prim.h" +#include "csr_wifi_sme_sef.h" +#include "csr_wifi_sme_converter_init.h" +#ifdef CSR_SUPPORT_WEXT +#ifdef CSR_SUPPORT_WEXT_AP +#include "csr_wifi_nme_ap_prim.h" +#include "csr_wifi_nme_ap_sef.h" +#include "csr_wifi_nme_ap_converter_init.h" +#endif +#endif + +static unifi_priv_t *drvpriv = NULL; +void CsrWifiRouterTransportInit(unifi_priv_t *priv) +{ + unifi_trace(priv, UDBG1, "CsrWifiRouterTransportInit: \n"); + + drvpriv = priv; + (void)CsrMsgConvInit(); + CsrWifiRouterConverterInit(); + CsrWifiRouterCtrlConverterInit(); + CsrWifiSmeConverterInit(); +#ifdef CSR_SUPPORT_WEXT +#ifdef CSR_SUPPORT_WEXT_AP + CsrWifiNmeApConverterInit(); +#endif +#endif +} + +void CsrWifiRouterTransportDeinit(unifi_priv_t *priv) +{ + unifi_trace(priv, UDBG1, "CsrWifiRouterTransportDeinit: \n"); + if (priv == drvpriv) + { + CsrMsgConvDeinit(); + drvpriv = NULL; + } +} + +void CsrWifiRouterTransportRecv(unifi_priv_t *priv, CsrUint8* buffer, CsrSize bufferLength) +{ + CsrMsgConvMsgEntry* msgEntry; + CsrUint16 primType; + CsrSchedQid src; + CsrSchedQid dest; + CsrUint16 msgType; + CsrSize offset = 0; + CsrWifiFsmEvent* msg; + + /* Decode the prim and message type */ + CsrUint16Des(&primType, buffer, &offset); + CsrUint16Des(&src, buffer, &offset); + CsrUint16Des(&dest, buffer, &offset); + CsrUint16Des(&msgType, buffer, &offset); + offset -= 2; /* Adjust as the Deserialise Function will read this as well */ + + unifi_trace(priv, UDBG4, "CsrWifiRouterTransportRecv: primType=0x%.4X, msgType=0x%.4X, bufferLength=%d\n", + primType, msgType, bufferLength); + + /* Special handling for HOSTIO messages.... */ + if (primType == CSR_WIFI_HOSTIO_PRIM) + { + CsrWifiRouterCtrlHipReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, CSR_WIFI_ROUTER_CTRL_PRIM, dest, src, NULL}, 0, NULL, 0, NULL, 0, NULL}; + + req.mlmeCommandLength = bufferLength; + req.mlmeCommand = buffer; + + offset += 8;/* Skip the id, src, dest and slot number */ + CsrUint16Des(&req.dataRef1Length, buffer, &offset); + offset += 2; /* Skip the slot number */ + CsrUint16Des(&req.dataRef2Length, buffer, &offset); + + if (req.dataRef1Length) + { + CsrUint16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length; + req.dataRef1 = &buffer[dr1Offset]; + } + + if (req.dataRef2Length) + { + CsrUint16 dr2Offset = bufferLength - req.dataRef2Length; + req.dataRef2 = &buffer[dr2Offset]; + } + + /* Copy the hip data but strip off the prim type */ + req.mlmeCommandLength -= (req.dataRef1Length + req.dataRef2Length + 6); + req.mlmeCommand = &buffer[6]; + + CsrWifiRouterCtrlHipReqHandler(priv, &req.common); + return; + } + + msgEntry = CsrMsgConvFindEntry(primType, msgType); + if (!msgEntry) + { + unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n", + primType, msgType); + dump(buffer, bufferLength); + return; + } + + msg = (CsrWifiFsmEvent*)(msgEntry->deserFunc)(&buffer[offset], bufferLength - offset); + + msg->primtype = primType; + msg->type = msgType; + msg->source = src; + msg->destination = dest; + + switch(primType) + { + case CSR_WIFI_ROUTER_CTRL_PRIM: + CsrWifiRouterCtrlDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST](priv, msg); + CsrWifiRouterCtrlFreeDownstreamMessageContents(CSR_WIFI_ROUTER_CTRL_PRIM, msg); + break; + case CSR_WIFI_ROUTER_PRIM: + CsrWifiRouterDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST](priv, msg); + CsrWifiRouterFreeDownstreamMessageContents(CSR_WIFI_ROUTER_PRIM, msg); + break; + case CSR_WIFI_SME_PRIM: + CsrWifiSmeUpstreamStateHandlers[msg->type - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST](priv, msg); + CsrWifiSmeFreeUpstreamMessageContents(CSR_WIFI_SME_PRIM, msg); + break; +#ifdef CSR_SUPPORT_WEXT +#ifdef CSR_SUPPORT_WEXT_AP + case CSR_WIFI_NME_AP_PRIM: + CsrWifiNmeApUpstreamStateHandlers(priv, msg); + CsrWifiNmeApFreeUpstreamMessageContents(CSR_WIFI_NME_AP_PRIM, msg); + break; +#endif +#endif + default: + unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType); + break; + } + CsrPmemFree(msg); +} + +static void CsrWifiRouterTransportSerialiseAndSend(CsrUint16 primType, void* msg) +{ + CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)msg; + CsrMsgConvMsgEntry* msgEntry; + CsrSize msgSize; + CsrSize encodeBufferLen = 0; + CsrSize offset = 0; + CsrUint8* encodeBuffer; + + unifi_trace(drvpriv, UDBG4, "CsrWifiRouterTransportSerialiseAndSend: primType=0x%.4X, msgType=0x%.4X\n", + primType, evt->type); + + msgEntry = CsrMsgConvFindEntry(primType, evt->type); + if (!msgEntry) + { + unifi_error(drvpriv, "CsrWifiRouterTransportSerialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n", + primType, evt->type); + return; + } + + msgSize = 6 + (msgEntry->sizeofFunc)((void*)msg); + + encodeBuffer = CsrPmemAlloc(msgSize); + + /* Encode PrimType */ + CsrUint16Ser(encodeBuffer, &encodeBufferLen, primType); + CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->source); + CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->destination); + + (void)(msgEntry->serFunc)(&encodeBuffer[encodeBufferLen], &offset, msg); + encodeBufferLen += offset; + + uf_sme_queue_message(drvpriv, encodeBuffer, encodeBufferLen); + + /* Do not use msgEntry->freeFunc because the memory is owned by the driver */ + CsrPmemFree(msg); +} + +#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) +void CsrSchedMessagePutStringLog(CsrSchedQid q, CsrUint16 mi, void *mv, CsrUint32 line, CsrCharString *file) +#else +void CsrSchedMessagePut(CsrSchedQid q, CsrUint16 mi, void *mv) +#endif +{ + CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv; + evt->destination = q; + CsrWifiRouterTransportSerialiseAndSend(mi, mv); +} + diff --git a/drivers/staging/csr/csr_wifi_serialize_primitive_types.c b/drivers/staging/csr/csr_wifi_serialize_primitive_types.c new file mode 100644 index 000000000000..155bf6562569 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_serialize_primitive_types.c @@ -0,0 +1,257 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_util.h" +#include "csr_msgconv.h" +#include "csr_wifi_msgconv.h" +#include "csr_wifi_lib.h" + +void CsrUint24Des(CsrUint32 *v, CsrUint8 *buffer, CsrSize *offset) +{ + CsrUint32 val; + + val = ((buffer[(*offset) + 2] << 16) | + (buffer[(*offset) + 1] << 8) | + (buffer[(*offset)])); + + *offset += 3; + *v = val; +} + + +/* Big endian :e.g WSC, TCLAS */ +void CsrUint16DesBigEndian(CsrUint16 *v, CsrUint8 *buffer, CsrSize *offset) +{ + CsrUint16 val; + + val = (buffer[(*offset)] << 8) | (buffer[(*offset) + 1]); + *offset += 2; + + *v = val; +} + + +void CsrUint24DesBigEndian(CsrUint32 *v, CsrUint8 *buffer, CsrSize *offset) +{ + CsrUint32 val; + + val = ((buffer[(*offset)] << 16) | + (buffer[(*offset) + 1] << 8) | + (buffer[(*offset) + 2])); + + *offset += 3; + *v = val; +} + + +void CsrUint32DesBigEndian(CsrUint32 *v, CsrUint8 *buffer, CsrSize *offset) +{ + CsrUint32 val; + + val = ((buffer[(*offset)] << 24) | + (buffer[(*offset) + 1] << 16) | + (buffer[(*offset) + 2] << 8) | + (buffer[(*offset) + 3])); + + *offset += 4; + *v = val; +} + + +void CsrUint24Ser(CsrUint8 *ptr, CsrSize *len, CsrUint32 v) +{ + ptr[(*len) + 2] = (CsrUint8)((v & 0x00ff0000) >> 16); + ptr[(*len) + 1] = (CsrUint8)((v & 0x0000ff00) >> 8); + ptr[(*len)] = (CsrUint8)((v & 0x000000ff)); + + *len += 3; +} + + +/* Big endian :e.g WSC, TCLAS */ +void CsrUint16SerBigEndian(CsrUint8 *ptr, CsrSize *len, CsrUint16 v) +{ + ptr[(*len)] = (CsrUint8)((v & 0xff00) >> 8); + ptr[(*len) + 1] = (CsrUint8)((v & 0x00ff)); + + *len += 2; +} + + +void CsrUint32SerBigEndian(CsrUint8 *ptr, CsrSize *len, CsrUint32 v) +{ + ptr[(*len)] = (CsrUint8)((v & 0xff000000) >> 24); + ptr[(*len) + 1] = (CsrUint8)((v & 0x00ff0000) >> 16); + ptr[(*len) + 2] = (CsrUint8)((v & 0x0000ff00) >> 8); + ptr[(*len) + 3] = (CsrUint8)((v & 0x000000ff)); + + *len += 4; +} + + +void CsrUint24SerBigEndian(CsrUint8 *ptr, CsrSize *len, CsrUint32 v) +{ + ptr[(*len)] = (CsrUint8)((v & 0x00ff0000) >> 16); + ptr[(*len) + 1] = (CsrUint8)((v & 0x0000ff00) >> 8); + ptr[(*len) + 2] = (CsrUint8)((v & 0x000000ff)); + + *len += 3; +} + + +CsrSize CsrWifiEventSizeof(void *msg) +{ + return 2; +} +EXPORT_SYMBOL_GPL(CsrWifiEventSizeof); + +CsrUint8* CsrWifiEventSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiFsmEvent *primitive = (CsrWifiFsmEvent *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->type); + return(ptr); +} +EXPORT_SYMBOL_GPL(CsrWifiEventSer); + +void* CsrWifiEventDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiFsmEvent *primitive = (CsrWifiFsmEvent *) CsrPmemAlloc(sizeof(CsrWifiFsmEvent)); + CsrSize offset = 0; + CsrUint16Des(&primitive->type, buffer, &offset); + + return primitive; +} +EXPORT_SYMBOL_GPL(CsrWifiEventDes); + +CsrSize CsrWifiEventCsrUint8Sizeof(void *msg) +{ + return 3; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint8Sizeof); + +CsrUint8* CsrWifiEventCsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiEventCsrUint8 *primitive = (CsrWifiEventCsrUint8 *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, primitive->value); + return(ptr); +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint8Ser); + + +void* CsrWifiEventCsrUint8Des(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiEventCsrUint8 *primitive = (CsrWifiEventCsrUint8 *) CsrPmemAlloc(sizeof(CsrWifiEventCsrUint8)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des(&primitive->value, buffer, &offset); + + return primitive; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint8Des); + + +CsrSize CsrWifiEventCsrUint16Sizeof(void *msg) +{ + return 4; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16Sizeof); + + +CsrUint8* CsrWifiEventCsrUint16Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiEventCsrUint16 *primitive = (CsrWifiEventCsrUint16 *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, primitive->value); + return(ptr); +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16Ser); + +void* CsrWifiEventCsrUint16Des(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiEventCsrUint16 *primitive = (CsrWifiEventCsrUint16 *) CsrPmemAlloc(sizeof(CsrWifiEventCsrUint16)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des(&primitive->value, buffer, &offset); + + return primitive; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16Des); + + +CsrSize CsrWifiEventCsrUint32Sizeof(void *msg) +{ + return 6; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint32Sizeof); + +CsrUint8* CsrWifiEventCsrUint32Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiEventCsrUint32 *primitive = (CsrWifiEventCsrUint32 *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint32Ser(ptr, len, primitive->value); + return(ptr); +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint32Ser); + + +void* CsrWifiEventCsrUint32Des(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiEventCsrUint32 *primitive = (CsrWifiEventCsrUint32 *) CsrPmemAlloc(sizeof(CsrWifiEventCsrUint32)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint32Des(&primitive->value, buffer, &offset); + + return primitive; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint32Des); + +CsrSize CsrWifiEventCsrUint16CsrUint8Sizeof(void *msg) +{ + return 5; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16CsrUint8Sizeof); + +CsrUint8* CsrWifiEventCsrUint16CsrUint8Ser(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiEventCsrUint16CsrUint8 *primitive = (CsrWifiEventCsrUint16CsrUint8 *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, primitive->value16); + CsrUint8Ser(ptr, len, primitive->value8); + return(ptr); +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16CsrUint8Ser); + + +void* CsrWifiEventCsrUint16CsrUint8Des(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiEventCsrUint16CsrUint8 *primitive = (CsrWifiEventCsrUint16CsrUint8 *) CsrPmemAlloc(sizeof(CsrWifiEventCsrUint16CsrUint8)); + + CsrSize offset = 0; + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des(&primitive->value16, buffer, &offset); + CsrUint8Des(&primitive->value8, buffer, &offset); + + return primitive; +} +EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16CsrUint8Des); + + diff --git a/drivers/staging/csr/csr_wifi_sme_ap_lib.h b/drivers/staging/csr/csr_wifi_sme_ap_lib.h new file mode 100644 index 000000000000..edef7c8de409 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_ap_lib.h @@ -0,0 +1,656 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_AP_LIB_H__ +#define CSR_WIFI_SME_AP_LIB_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_sched.h" +#include "csr_util.h" +#include "csr_msg_transport.h" + +#include "csr_wifi_lib.h" + +#include "csr_wifi_sme_ap_prim.h" +#include "csr_wifi_sme_task.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_AP_ENABLE +#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_lib.h +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiSmeApFreeUpstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_SME_AP upstream message. Does not + * free the message itself, and can only be used for upstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_SME_AP upstream message + *----------------------------------------------------------------------------*/ +void CsrWifiSmeApFreeUpstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * CsrWifiSmeApFreeDownstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_SME_AP downstream message. Does not + * free the message itself, and can only be used for downstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_SME_AP downstream message + *----------------------------------------------------------------------------*/ +void CsrWifiSmeApFreeDownstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * Enum to string functions + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiSmeApAccessTypeToString(CsrWifiSmeApAccessType value); +const CsrCharString* CsrWifiSmeApAuthSupportToString(CsrWifiSmeApAuthSupport value); +const CsrCharString* CsrWifiSmeApAuthTypeToString(CsrWifiSmeApAuthType value); +const CsrCharString* CsrWifiSmeApPhySupportToString(CsrWifiSmeApPhySupport value); +const CsrCharString* CsrWifiSmeApTypeToString(CsrWifiSmeApType value); + + +/*----------------------------------------------------------------------------* + * CsrPrim Type toString function. + * Converts a message type to the String name of the Message + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiSmeApPrimTypeToString(CsrPrim msgType); + +/*----------------------------------------------------------------------------* + * Lookup arrays for PrimType name Strings + *----------------------------------------------------------------------------*/ +extern const CsrCharString *CsrWifiSmeApUpstreamPrimNames[CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT]; +extern const CsrCharString *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT]; + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStartReqSend + + DESCRIPTION + This primitive requests the SME to start AP or GO functionality + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + initialPresence - Set to 0, if Not in a group fomration phase, set to 1 , + during group formation phase + apType - apType : Legacy AP or P2PGO + cloakSsid - cloakSsid flag. + ssid - ssid. + ifIndex - Radio Interface + channel - channel. + maxConnections - Maximum Stations + P2PClients allowed + apCredentials - AP security credeitals used to advertise in beacon /probe + response + smeApConfig - AP configuration + p2pGoParam - P2P specific GO parameters. Ignored if it is a leagacy AP + +*******************************************************************************/ +#define CsrWifiSmeApBeaconingStartReqCreate(msg__, dst__, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) \ + msg__ = (CsrWifiSmeApBeaconingStartReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApBeaconingStartReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_START_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->initialPresence = (initialPresence__); \ + msg__->apType = (apType__); \ + msg__->cloakSsid = (cloakSsid__); \ + msg__->ssid = (ssid__); \ + msg__->ifIndex = (ifIndex__); \ + msg__->channel = (channel__); \ + msg__->maxConnections = (maxConnections__); \ + msg__->apCredentials = (apCredentials__); \ + msg__->smeApConfig = (smeApConfig__); \ + msg__->p2pGoParam = (p2pGoParam__); + +#define CsrWifiSmeApBeaconingStartReqSendTo(dst__, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) \ + { \ + CsrWifiSmeApBeaconingStartReq *msg__; \ + CsrWifiSmeApBeaconingStartReqCreate(msg__, dst__, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApBeaconingStartReqSend(src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) \ + CsrWifiSmeApBeaconingStartReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStartCfmSend + + DESCRIPTION + This primitive confirms the completion of the request along with the + status + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - + secIeLength - + secIe - + +*******************************************************************************/ +#define CsrWifiSmeApBeaconingStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, secIeLength__, secIe__) \ + msg__ = (CsrWifiSmeApBeaconingStartCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApBeaconingStartCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_START_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->secIeLength = (secIeLength__); \ + msg__->secIe = (secIe__); + +#define CsrWifiSmeApBeaconingStartCfmSendTo(dst__, src__, interfaceTag__, status__, secIeLength__, secIe__) \ + { \ + CsrWifiSmeApBeaconingStartCfm *msg__; \ + CsrWifiSmeApBeaconingStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, secIeLength__, secIe__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApBeaconingStartCfmSend(dst__, interfaceTag__, status__, secIeLength__, secIe__) \ + CsrWifiSmeApBeaconingStartCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, secIeLength__, secIe__) + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStopReqSend + + DESCRIPTION + This primitive requests the SME to STOP AP or P2PGO operation + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + +*******************************************************************************/ +#define CsrWifiSmeApBeaconingStopReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeApBeaconingStopReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApBeaconingStopReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_STOP_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeApBeaconingStopReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeApBeaconingStopReq *msg__; \ + CsrWifiSmeApBeaconingStopReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApBeaconingStopReqSend(src__, interfaceTag__) \ + CsrWifiSmeApBeaconingStopReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStopCfmSend + + DESCRIPTION + This primitive confirms AP or P2PGO operation is terminated + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiSmeApBeaconingStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeApBeaconingStopCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApBeaconingStopCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_STOP_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeApBeaconingStopCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeApBeaconingStopCfm *msg__; \ + CsrWifiSmeApBeaconingStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApBeaconingStopCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeApBeaconingStopCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeApErrorIndSend + + DESCRIPTION + This primitve is sent by SME to indicate some error in AP operationi + after AP operations were started successfully and continuing the AP + operation may lead to undesired behaviour. It is the responsibility of + the upper layers to stop AP operation if needed + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Range 0-1 + apType - + status - Contains the error status + +*******************************************************************************/ +#define CsrWifiSmeApErrorIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__) \ + msg__ = (CsrWifiSmeApErrorInd *) CsrPmemAlloc(sizeof(CsrWifiSmeApErrorInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ERROR_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->apType = (apType__); \ + msg__->status = (status__); + +#define CsrWifiSmeApErrorIndSendTo(dst__, src__, interfaceTag__, apType__, status__) \ + { \ + CsrWifiSmeApErrorInd *msg__; \ + CsrWifiSmeApErrorIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApErrorIndSend(dst__, interfaceTag__, apType__, status__) \ + CsrWifiSmeApErrorIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, apType__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeApStaConnectStartIndSend + + DESCRIPTION + This primitive indicates that a stations request to join the group/BSS is + accepted + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + peerMacAddress - + +*******************************************************************************/ +#define CsrWifiSmeApStaConnectStartIndCreate(msg__, dst__, src__, interfaceTag__, peerMacAddress__) \ + msg__ = (CsrWifiSmeApStaConnectStartInd *) CsrPmemAlloc(sizeof(CsrWifiSmeApStaConnectStartInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_CONNECT_START_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->peerMacAddress = (peerMacAddress__); + +#define CsrWifiSmeApStaConnectStartIndSendTo(dst__, src__, interfaceTag__, peerMacAddress__) \ + { \ + CsrWifiSmeApStaConnectStartInd *msg__; \ + CsrWifiSmeApStaConnectStartIndCreate(msg__, dst__, src__, interfaceTag__, peerMacAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApStaConnectStartIndSend(dst__, interfaceTag__, peerMacAddress__) \ + CsrWifiSmeApStaConnectStartIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, peerMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiSmeApStaDisconnectReqSend + + DESCRIPTION + This primitive tells SME to deauth ot disassociate a particular station + within BSS + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + deauthReason - + disassocReason - + peerMacaddress - + keepBlocking - If TRUE, the station is blocked. If FALSE and the station + is connected, disconnect the station. If FALSE and the + station is not connected, no action is taken. + +*******************************************************************************/ +#define CsrWifiSmeApStaDisconnectReqCreate(msg__, dst__, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) \ + msg__ = (CsrWifiSmeApStaDisconnectReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApStaDisconnectReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_DISCONNECT_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->deauthReason = (deauthReason__); \ + msg__->disassocReason = (disassocReason__); \ + msg__->peerMacaddress = (peerMacaddress__); \ + msg__->keepBlocking = (keepBlocking__); + +#define CsrWifiSmeApStaDisconnectReqSendTo(dst__, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) \ + { \ + CsrWifiSmeApStaDisconnectReq *msg__; \ + CsrWifiSmeApStaDisconnectReqCreate(msg__, dst__, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApStaDisconnectReqSend(src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) \ + CsrWifiSmeApStaDisconnectReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) + +/******************************************************************************* + + NAME + CsrWifiSmeApStaDisconnectCfmSend + + DESCRIPTION + This primitive confirms the station is disconnected + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - + peerMacaddress - + +*******************************************************************************/ +#define CsrWifiSmeApStaDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, peerMacaddress__) \ + msg__ = (CsrWifiSmeApStaDisconnectCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApStaDisconnectCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_DISCONNECT_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->peerMacaddress = (peerMacaddress__); + +#define CsrWifiSmeApStaDisconnectCfmSendTo(dst__, src__, interfaceTag__, status__, peerMacaddress__) \ + { \ + CsrWifiSmeApStaDisconnectCfm *msg__; \ + CsrWifiSmeApStaDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, peerMacaddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApStaDisconnectCfmSend(dst__, interfaceTag__, status__, peerMacaddress__) \ + CsrWifiSmeApStaDisconnectCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, peerMacaddress__) + +/******************************************************************************* + + NAME + CsrWifiSmeApStaNotifyIndSend + + DESCRIPTION + This primitive indicates that a station has joined or a previously joined + station has left the BSS/group + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + mediaStatus - + peerMacAddress - + peerDeviceAddress - + disassocReason - + deauthReason - + WpsRegistration - + secIeLength - + secIe - + groupKeyId - + seqNumber - + +*******************************************************************************/ +#define CsrWifiSmeApStaNotifyIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) \ + msg__ = (CsrWifiSmeApStaNotifyInd *) CsrPmemAlloc(sizeof(CsrWifiSmeApStaNotifyInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_NOTIFY_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->mediaStatus = (mediaStatus__); \ + msg__->peerMacAddress = (peerMacAddress__); \ + msg__->peerDeviceAddress = (peerDeviceAddress__); \ + msg__->disassocReason = (disassocReason__); \ + msg__->deauthReason = (deauthReason__); \ + msg__->WpsRegistration = (WpsRegistration__); \ + msg__->secIeLength = (secIeLength__); \ + msg__->secIe = (secIe__); \ + msg__->groupKeyId = (groupKeyId__); \ + CsrMemCpy(msg__->seqNumber, (seqNumber__), sizeof(CsrUint16) * 8); + +#define CsrWifiSmeApStaNotifyIndSendTo(dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) \ + { \ + CsrWifiSmeApStaNotifyInd *msg__; \ + CsrWifiSmeApStaNotifyIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApStaNotifyIndSend(dst__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) \ + CsrWifiSmeApStaNotifyIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWmmParamUpdateReqSend + + DESCRIPTION + Application uses this primitive to update the WMM parameters on the fly + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + wmmApParams - WMM parameters to be used for local firmware queue + configuration + wmmApBcParams - WMM parameters to be advertised in beacon/probe response + +*******************************************************************************/ +#define CsrWifiSmeApWmmParamUpdateReqCreate(msg__, dst__, src__, interfaceTag__, wmmApParams__, wmmApBcParams__) \ + msg__ = (CsrWifiSmeApWmmParamUpdateReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApWmmParamUpdateReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + CsrMemCpy(msg__->wmmApParams, (wmmApParams__), sizeof(CsrWifiSmeWmmAcParams) * 4); \ + CsrMemCpy(msg__->wmmApBcParams, (wmmApBcParams__), sizeof(CsrWifiSmeWmmAcParams) * 4); + +#define CsrWifiSmeApWmmParamUpdateReqSendTo(dst__, src__, interfaceTag__, wmmApParams__, wmmApBcParams__) \ + { \ + CsrWifiSmeApWmmParamUpdateReq *msg__; \ + CsrWifiSmeApWmmParamUpdateReqCreate(msg__, dst__, src__, interfaceTag__, wmmApParams__, wmmApBcParams__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWmmParamUpdateReqSend(src__, interfaceTag__, wmmApParams__, wmmApBcParams__) \ + CsrWifiSmeApWmmParamUpdateReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, wmmApParams__, wmmApBcParams__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWmmParamUpdateCfmSend + + DESCRIPTION + A confirm for CSR_WIFI_SME_AP_WMM_PARAM_UPDATE.request + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiSmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeApWmmParamUpdateCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApWmmParamUpdateCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeApWmmParamUpdateCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeApWmmParamUpdateCfm *msg__; \ + CsrWifiSmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWmmParamUpdateCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeApWmmParamUpdateCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsConfigurationReqSend + + DESCRIPTION + This primitive passes the WPS information for the device to SME. This may + be accepted only if no interface is active. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + wpsConfig - WPS config. + +*******************************************************************************/ +#define CsrWifiSmeApWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__) \ + msg__ = (CsrWifiSmeApWpsConfigurationReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApWpsConfigurationReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ, dst__, src__); \ + msg__->wpsConfig = (wpsConfig__); + +#define CsrWifiSmeApWpsConfigurationReqSendTo(dst__, src__, wpsConfig__) \ + { \ + CsrWifiSmeApWpsConfigurationReq *msg__; \ + CsrWifiSmeApWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWpsConfigurationReqSend(src__, wpsConfig__) \ + CsrWifiSmeApWpsConfigurationReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, wpsConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsConfigurationCfmSend + + DESCRIPTION + Confirm. + + PARAMETERS + queue - Destination Task Queue + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiSmeApWpsConfigurationCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeApWpsConfigurationCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApWpsConfigurationCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeApWpsConfigurationCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeApWpsConfigurationCfm *msg__; \ + CsrWifiSmeApWpsConfigurationCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWpsConfigurationCfmSend(dst__, status__) \ + CsrWifiSmeApWpsConfigurationCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationFinishedReqSend + + DESCRIPTION + This primitive tells SME that WPS registration procedure has finished + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + +*******************************************************************************/ +#define CsrWifiSmeApWpsRegistrationFinishedReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeApWpsRegistrationFinishedReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApWpsRegistrationFinishedReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeApWpsRegistrationFinishedReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeApWpsRegistrationFinishedReq *msg__; \ + CsrWifiSmeApWpsRegistrationFinishedReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWpsRegistrationFinishedReqSend(src__, interfaceTag__) \ + CsrWifiSmeApWpsRegistrationFinishedReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationFinishedCfmSend + + DESCRIPTION + A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_FINISHED.request + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiSmeApWpsRegistrationFinishedCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeApWpsRegistrationFinishedCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApWpsRegistrationFinishedCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeApWpsRegistrationFinishedCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeApWpsRegistrationFinishedCfm *msg__; \ + CsrWifiSmeApWpsRegistrationFinishedCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWpsRegistrationFinishedCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeApWpsRegistrationFinishedCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationStartedReqSend + + DESCRIPTION + This primitive tells SME that WPS registration procedure has started + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + SelectedDevicePasswordId - + SelectedconfigMethod - + +*******************************************************************************/ +#define CsrWifiSmeApWpsRegistrationStartedReqCreate(msg__, dst__, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) \ + msg__ = (CsrWifiSmeApWpsRegistrationStartedReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApWpsRegistrationStartedReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->SelectedDevicePasswordId = (SelectedDevicePasswordId__); \ + msg__->SelectedconfigMethod = (SelectedconfigMethod__); + +#define CsrWifiSmeApWpsRegistrationStartedReqSendTo(dst__, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) \ + { \ + CsrWifiSmeApWpsRegistrationStartedReq *msg__; \ + CsrWifiSmeApWpsRegistrationStartedReqCreate(msg__, dst__, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWpsRegistrationStartedReqSend(src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) \ + CsrWifiSmeApWpsRegistrationStartedReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationStartedCfmSend + + DESCRIPTION + A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_STARTED.request + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - + +*******************************************************************************/ +#define CsrWifiSmeApWpsRegistrationStartedCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeApWpsRegistrationStartedCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApWpsRegistrationStartedCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeApWpsRegistrationStartedCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeApWpsRegistrationStartedCfm *msg__; \ + CsrWifiSmeApWpsRegistrationStartedCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApWpsRegistrationStartedCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeApWpsRegistrationStartedCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_SME_AP_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_ap_prim.h b/drivers/staging/csr/csr_wifi_sme_ap_prim.h new file mode 100644 index 000000000000..3310cd287fdc --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_ap_prim.h @@ -0,0 +1,904 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_AP_PRIM_H__ +#define CSR_WIFI_SME_AP_PRIM_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_wifi_common.h" +#include "csr_result.h" +#include "csr_wifi_fsm_event.h" +#include "csr_wifi_sme_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSR_WIFI_AP_ENABLE +#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_prim.h +#endif + +#define CSR_WIFI_SME_AP_PRIM (0x0407) + +typedef CsrPrim CsrWifiSmeApPrim; + + +/******************************************************************************* + + NAME + CsrWifiSmeApAccessType + + DESCRIPTION + Allow or deny STAs based on MAC address + + VALUES + CSR_WIFI_AP_ACCESS_TYPE_NONE - None + CSR_WIFI_AP_ACCESS_TYPE_ALLOW - Allow only if MAC address is from the list + CSR_WIFI_AP_ACCESS_TYPE_DENY - Disallow if MAC address is from the list + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApAccessType; +#define CSR_WIFI_AP_ACCESS_TYPE_NONE ((CsrWifiSmeApAccessType) 0x00) +#define CSR_WIFI_AP_ACCESS_TYPE_ALLOW ((CsrWifiSmeApAccessType) 0x01) +#define CSR_WIFI_AP_ACCESS_TYPE_DENY ((CsrWifiSmeApAccessType) 0x02) + +/******************************************************************************* + + NAME + CsrWifiSmeApAuthSupport + + DESCRIPTION + Define bits for AP authentication support + + VALUES + CSR_WIFI_SME_RSN_AUTH_WPAPSK - RSN WPA-PSK Support + CSR_WIFI_SME_RSN_AUTH_WPA2PSK - RSN WPA2-PSK Support + CSR_WIFI_SME_AUTH_WAPIPSK - WAPI-PSK Support + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApAuthSupport; +#define CSR_WIFI_SME_RSN_AUTH_WPAPSK ((CsrWifiSmeApAuthSupport) 0x01) +#define CSR_WIFI_SME_RSN_AUTH_WPA2PSK ((CsrWifiSmeApAuthSupport) 0x02) +#define CSR_WIFI_SME_AUTH_WAPIPSK ((CsrWifiSmeApAuthSupport) 0x04) + +/******************************************************************************* + + NAME + CsrWifiSmeApAuthType + + DESCRIPTION + Definition of the SME AP Authentication Options + + VALUES + CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM + - Open authentication + CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL + - Personal authentication using a passphrase or a pre-shared + key. + CSR_WIFI_SME_AP_AUTH_TYPE_WEP + - WEP authentication. This can be either open or shared key + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApAuthType; +#define CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM ((CsrWifiSmeApAuthType) 0x00) +#define CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL ((CsrWifiSmeApAuthType) 0x01) +#define CSR_WIFI_SME_AP_AUTH_TYPE_WEP ((CsrWifiSmeApAuthType) 0x02) + +/******************************************************************************* + + NAME + CsrWifiSmeApPhySupport + + DESCRIPTION + Define bits for CsrWifiSmeApPhySupportMask + + VALUES + CSR_WIFI_SME_AP_PHY_SUPPORT_A - 802.11a. It is not supported in the current + release. + CSR_WIFI_SME_AP_PHY_SUPPORT_B - 802.11b + CSR_WIFI_SME_AP_PHY_SUPPORT_G - 802.11g + CSR_WIFI_SME_AP_PHY_SUPPORT_N - 802.11n + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApPhySupport; +#define CSR_WIFI_SME_AP_PHY_SUPPORT_A ((CsrWifiSmeApPhySupport) 0x01) +#define CSR_WIFI_SME_AP_PHY_SUPPORT_B ((CsrWifiSmeApPhySupport) 0x02) +#define CSR_WIFI_SME_AP_PHY_SUPPORT_G ((CsrWifiSmeApPhySupport) 0x04) +#define CSR_WIFI_SME_AP_PHY_SUPPORT_N ((CsrWifiSmeApPhySupport) 0x08) + +/******************************************************************************* + + NAME + CsrWifiSmeApType + + DESCRIPTION + Definition of AP types + + VALUES + CSR_WIFI_AP_TYPE_LEGACY - Legacy AP + CSR_WIFI_AP_TYPE_P2P - P2P Group Owner(GO) + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApType; +#define CSR_WIFI_AP_TYPE_LEGACY ((CsrWifiSmeApType) 0x00) +#define CSR_WIFI_AP_TYPE_P2P ((CsrWifiSmeApType) 0x01) + + +/******************************************************************************* + + NAME + CsrWifiSmeApAuthSupportMask + + DESCRIPTION + See CsrWifiSmeApAuthSupport for bit definitions + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApAuthSupportMask; +/******************************************************************************* + + NAME + CsrWifiSmeApPhySupportMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeApPhySupport + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApPhySupportMask; +/******************************************************************************* + + NAME + CsrWifiSmeApRsnCapabilities + + DESCRIPTION + Set to 0 for the current release + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeApRsnCapabilities; +/******************************************************************************* + + NAME + CsrWifiSmeApRsnCapabilitiesMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeApRsnCapabilities + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeApRsnCapabilitiesMask; +/******************************************************************************* + + NAME + CsrWifiSmeApWapiCapabilities + + DESCRIPTION + Ignored by the stack as WAPI is not supported for AP operations in the + current release + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeApWapiCapabilities; +/******************************************************************************* + + NAME + CsrWifiSmeApWapiCapabilitiesMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeApWapiCapabilities + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeApWapiCapabilitiesMask; + + +/******************************************************************************* + + NAME + CsrWifiSmeApHtParams + + DESCRIPTION + Structure holding HT parameters + + MEMBERS + greenfieldSupported - Indicates if the AP supports Htgreenfield operation + subject to the chip capability. If the chip does not + support Htgreenfield operation, this parameter will be + ignored. + NOTE: if shortGi20MHz is set to TRUE and the chip + supports short GI operation for 20MHz this field will + be be ignored and the AP will not support Htgreenfield + operation. + NOTE: This field is ignored by the Wi-Fi stack for the + current release. It implies that AP does not support + greenfield operation. + shortGi20MHz - Indicates if the AP support short GI operation for + 20MHz subject to the chip capability.If the chip does + not support short GI for 20MHz, this parameter is + ignored + rxStbc - Support for STBC for receive. 0 => No support for STBC + , 1=> Use STBC for Rx + rifsModeAllowed - RIFS Mode is allowed to protect overlapping non-HT BSS + htProtection - Deprecated + dualCtsProtection - Dual CTS Protection enabled + +*******************************************************************************/ +typedef struct +{ + CsrBool greenfieldSupported; + CsrBool shortGi20MHz; + CsrUint8 rxStbc; + CsrBool rifsModeAllowed; + CsrUint8 htProtection; + CsrBool dualCtsProtection; +} CsrWifiSmeApHtParams; + +/******************************************************************************* + + NAME + CsrWifiSmeApP2pOperatingChanEntry + + DESCRIPTION + + MEMBERS + operatingClass - Channel operating class + operatingChannelCount - Number of channels in this entry + operatingChannel - List of channels + +*******************************************************************************/ +typedef struct +{ + CsrUint8 operatingClass; + CsrUint8 operatingChannelCount; + CsrUint8 *operatingChannel; +} CsrWifiSmeApP2pOperatingChanEntry; + +/******************************************************************************* + + NAME + CsrWifiSmeApP2pOperatingChanList + + DESCRIPTION + This structure contains the lists of P2P operating channels + + MEMBERS + country - Country + channelEntryListCount - Number of entries + channelEntryList - List of entries + +*******************************************************************************/ +typedef struct +{ + CsrUint8 country[3]; + CsrUint8 channelEntryListCount; + CsrWifiSmeApP2pOperatingChanEntry *channelEntryList; +} CsrWifiSmeApP2pOperatingChanList; + +/******************************************************************************* + + NAME + CsrWifiSmeApAuthPers + + DESCRIPTION + + MEMBERS + authSupport - + encryptionModeMask - + rsnCapabilities - + wapiCapabilities - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeApAuthSupportMask authSupport; + CsrWifiSmeEncryptionMask encryptionModeMask; + CsrWifiSmeApRsnCapabilitiesMask rsnCapabilities; + CsrWifiSmeApWapiCapabilitiesMask wapiCapabilities; +} CsrWifiSmeApAuthPers; + +/******************************************************************************* + + NAME + CsrWifiSmeApMacConfig + + DESCRIPTION + Structure holding AP MAC configuration. + + MEMBERS + phySupportedBitmap - Indicates supported physical layers + beaconInterval - Beacon interval in terms of TUs + dtimPeriod - DTIM period in terms of number of beacon intervals + maxListenInterval - Maximum allowed listen interval as number of beacon + intervals + supportedRatesCount - Number of supported rates. Range : 0 to 20 + supportedRates - List of supportedRates. A rate is specied in the + units of 500kbps. An entry for a basic rate shall + have the MSB set to 1. + preamble - Preamble to be advertised in beacons and probe + responses + shortSlotTimeEnabled - TRUE indicates the AP shall use short slot time if + all the stations use short slot operation. + ctsProtectionType - CTS protection to be used + wmmEnabled - Indicate whether WMM is enabled or not. If set to + FALSE,the WMM parameters shall be ignored by the + receiver. + wmmApParams - WMM parameters to be used for local firmware queue + configuration. Array index corresponds to the ACI. + wmmApBcParams - WMM parameters to be advertised in beacon/probe + response. Array index corresponds to the ACI + accessType - Specifies whether the MAC addresses from the list + should be allowed or denied + macAddressListCount - Number of MAC addresses + macAddressList - List of MAC addresses + apHtParams - AP HT parameters. The stack shall use these + parameters only if phySupportedBitmap indicates + support for IEEE 802.11n + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeApPhySupportMask phySupportedBitmap; + CsrUint16 beaconInterval; + CsrUint8 dtimPeriod; + CsrUint16 maxListenInterval; + CsrUint8 supportedRatesCount; + CsrUint8 supportedRates[20]; + CsrWifiSmePreambleType preamble; + CsrBool shortSlotTimeEnabled; + CsrWifiSmeCtsProtectionType ctsProtectionType; + CsrBool wmmEnabled; + CsrWifiSmeWmmAcParams wmmApParams[4]; + CsrWifiSmeWmmAcParams wmmApBcParams[4]; + CsrWifiSmeApAccessType accessType; + CsrUint8 macAddressListCount; + CsrWifiMacAddress *macAddressList; + CsrWifiSmeApHtParams apHtParams; +} CsrWifiSmeApMacConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeApP2pGoConfig + + DESCRIPTION + + MEMBERS + groupCapability - Indicates the P2P group capabilities + operatingChanList - List of operating channels in the order of + decreasing priority. It may contain channel + entry/entries not supported by the wifi stack. + These shall be filtered out by the wifi stack + opPsEnabled - Indicates whether opportunistic power save can + be used. + Note: This parameter is ignored by the WiFi + stack for the current release + ctWindow - Define Client Traffic window to be used in terms + of number of TUs. Range: 0 to 127. + Note: This parameter is ignored by the WiFi + stack for the current release. + noaConfigMethod - Notice of Absence configuration method. + Note: This parameter is ignored by the WiFi + stack for the current release. + allowNoaWithNonP2pDevices - Indicates if NOA should be allowed if non P2P + devices are connected. If allowed the non P2P + devices may suffer in throughput. + Note: This parameter is ignored by the WiFi + stack for the current release. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeP2pGroupCapabilityMask groupCapability; + CsrWifiSmeApP2pOperatingChanList operatingChanList; + CsrBool opPsEnabled; + CsrUint8 ctWindow; + CsrWifiSmeP2pNoaConfigMethod noaConfigMethod; + CsrBool allowNoaWithNonP2pDevices; +} CsrWifiSmeApP2pGoConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeApCredentials + + DESCRIPTION + + MEMBERS + authType - + smeAuthType - + smeAuthTypeopenSystemEmpty - + smeAuthTypeauthwep - + smeAuthTypeauthPers - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeApAuthType authType; + union { + CsrWifiSmeEmpty openSystemEmpty; + CsrWifiSmeWepAuth authwep; + CsrWifiSmeApAuthPers authPers; + } smeAuthType; +} CsrWifiSmeApCredentials; + +/******************************************************************************* + + NAME + CsrWifiSmeApSecConfig + + DESCRIPTION + + MEMBERS + apCredentials - + wpsEnabled - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeApCredentials apCredentials; + CsrBool wpsEnabled; +} CsrWifiSmeApSecConfig; + + +/* Downstream */ +#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST (0x0000) + +#define CSR_WIFI_SME_AP_BEACONING_START_REQ ((CsrWifiSmeApPrim) (0x0000 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_BEACONING_STOP_REQ ((CsrWifiSmeApPrim) (0x0001 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_REQ ((CsrWifiSmeApPrim) (0x0002 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_REQ ((CsrWifiSmeApPrim) (0x0003 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ ((CsrWifiSmeApPrim) (0x0004 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_STA_DISCONNECT_REQ ((CsrWifiSmeApPrim) (0x0005 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ ((CsrWifiSmeApPrim) (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) + + +#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) + +/* Upstream */ +#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) + +#define CSR_WIFI_SME_AP_BEACONING_START_CFM ((CsrWifiSmeApPrim)(0x0000 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_BEACONING_STOP_CFM ((CsrWifiSmeApPrim)(0x0001 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_STA_NOTIFY_IND ((CsrWifiSmeApPrim)(0x0002 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_STA_CONNECT_START_IND ((CsrWifiSmeApPrim)(0x0003 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_CFM ((CsrWifiSmeApPrim)(0x0004 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_CFM ((CsrWifiSmeApPrim)(0x0005 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_CFM ((CsrWifiSmeApPrim)(0x0006 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_STA_DISCONNECT_CFM ((CsrWifiSmeApPrim)(0x0007 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM ((CsrWifiSmeApPrim)(0x0008 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_ERROR_IND ((CsrWifiSmeApPrim)(0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) + +#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) + +#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStartReq + + DESCRIPTION + This primitive requests the SME to start AP or GO functionality + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + initialPresence - Set to 0, if Not in a group fomration phase, set to 1 , + during group formation phase + apType - apType : Legacy AP or P2PGO + cloakSsid - cloakSsid flag. + ssid - ssid. + ifIndex - Radio Interface + channel - channel. + maxConnections - Maximum Stations + P2PClients allowed + apCredentials - AP security credeitals used to advertise in beacon /probe + response + smeApConfig - AP configuration + p2pGoParam - P2P specific GO parameters. Ignored if it is a leagacy AP + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 initialPresence; + CsrWifiSmeApType apType; + CsrBool cloakSsid; + CsrWifiSsid ssid; + CsrWifiSmeRadioIF ifIndex; + CsrUint8 channel; + CsrUint8 maxConnections; + CsrWifiSmeApSecConfig apCredentials; + CsrWifiSmeApMacConfig smeApConfig; + CsrWifiSmeApP2pGoConfig p2pGoParam; +} CsrWifiSmeApBeaconingStartReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStopReq + + DESCRIPTION + This primitive requests the SME to STOP AP or P2PGO operation + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeApBeaconingStopReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationStartedReq + + DESCRIPTION + This primitive tells SME that WPS registration procedure has started + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + SelectedDevicePasswordId - + SelectedconfigMethod - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeWpsDpid SelectedDevicePasswordId; + CsrWifiSmeWpsConfigType SelectedconfigMethod; +} CsrWifiSmeApWpsRegistrationStartedReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationFinishedReq + + DESCRIPTION + This primitive tells SME that WPS registration procedure has finished + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeApWpsRegistrationFinishedReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApWmmParamUpdateReq + + DESCRIPTION + Application uses this primitive to update the WMM parameters on the fly + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + wmmApParams - WMM parameters to be used for local firmware queue + configuration + wmmApBcParams - WMM parameters to be advertised in beacon/probe response + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeWmmAcParams wmmApParams[4]; + CsrWifiSmeWmmAcParams wmmApBcParams[4]; +} CsrWifiSmeApWmmParamUpdateReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApStaDisconnectReq + + DESCRIPTION + This primitive tells SME to deauth ot disassociate a particular station + within BSS + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + deauthReason - + disassocReason - + peerMacaddress - + keepBlocking - If TRUE, the station is blocked. If FALSE and the station + is connected, disconnect the station. If FALSE and the + station is not connected, no action is taken. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeIEEE80211Reason deauthReason; + CsrWifiSmeIEEE80211Reason disassocReason; + CsrWifiMacAddress peerMacaddress; + CsrBool keepBlocking; +} CsrWifiSmeApStaDisconnectReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsConfigurationReq + + DESCRIPTION + This primitive passes the WPS information for the device to SME. This may + be accepted only if no interface is active. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + wpsConfig - WPS config. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeWpsConfig wpsConfig; +} CsrWifiSmeApWpsConfigurationReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStartCfm + + DESCRIPTION + This primitive confirms the completion of the request along with the + status + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - + secIeLength - + secIe - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrUint16 secIeLength; + CsrUint8 *secIe; +} CsrWifiSmeApBeaconingStartCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApBeaconingStopCfm + + DESCRIPTION + This primitive confirms AP or P2PGO operation is terminated + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeApBeaconingStopCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApStaNotifyInd + + DESCRIPTION + This primitive indicates that a station has joined or a previously joined + station has left the BSS/group + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + mediaStatus - + peerMacAddress - + peerDeviceAddress - + disassocReason - + deauthReason - + WpsRegistration - + secIeLength - + secIe - + groupKeyId - + seqNumber - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeMediaStatus mediaStatus; + CsrWifiMacAddress peerMacAddress; + CsrWifiMacAddress peerDeviceAddress; + CsrWifiSmeIEEE80211Reason disassocReason; + CsrWifiSmeIEEE80211Reason deauthReason; + CsrWifiSmeWpsRegistration WpsRegistration; + CsrUint8 secIeLength; + CsrUint8 *secIe; + CsrUint8 groupKeyId; + CsrUint16 seqNumber[8]; +} CsrWifiSmeApStaNotifyInd; + +/******************************************************************************* + + NAME + CsrWifiSmeApStaConnectStartInd + + DESCRIPTION + This primitive indicates that a stations request to join the group/BSS is + accepted + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + peerMacAddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiMacAddress peerMacAddress; +} CsrWifiSmeApStaConnectStartInd; + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationStartedCfm + + DESCRIPTION + A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_STARTED.request + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeApWpsRegistrationStartedCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsRegistrationFinishedCfm + + DESCRIPTION + A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_FINISHED.request + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeApWpsRegistrationFinishedCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApWmmParamUpdateCfm + + DESCRIPTION + A confirm for CSR_WIFI_SME_AP_WMM_PARAM_UPDATE.request + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeApWmmParamUpdateCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApStaDisconnectCfm + + DESCRIPTION + This primitive confirms the station is disconnected + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - + peerMacaddress - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiMacAddress peerMacaddress; +} CsrWifiSmeApStaDisconnectCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApWpsConfigurationCfm + + DESCRIPTION + Confirm. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeApWpsConfigurationCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApErrorInd + + DESCRIPTION + This primitve is sent by SME to indicate some error in AP operationi + after AP operations were started successfully and continuing the AP + operation may lead to undesired behaviour. It is the responsibility of + the upper layers to stop AP operation if needed + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Range 0-1 + apType - + status - Contains the error status + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeApType apType; + CsrResult status; +} CsrWifiSmeApErrorInd; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_SME_AP_PRIM_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.c b/drivers/staging/csr/csr_wifi_sme_converter_init.c new file mode 100644 index 000000000000..bafd1b411a90 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_converter_init.c @@ -0,0 +1,201 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_msgconv.h" +#include "csr_pmem.h" +#include "csr_util.h" + + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" +#endif + +#ifndef EXCLUDE_CSR_WIFI_SME_MODULE +#include "csr_wifi_sme_serialize.h" +#include "csr_wifi_sme_prim.h" + +static CsrMsgConvMsgEntry csrwifisme_conv_lut[] = { + { CSR_WIFI_SME_ACTIVATE_REQ, CsrWifiSmeActivateReqSizeof, CsrWifiSmeActivateReqSer, CsrWifiSmeActivateReqDes, CsrWifiSmeActivateReqSerFree }, + { CSR_WIFI_SME_ADHOC_CONFIG_GET_REQ, CsrWifiSmeAdhocConfigGetReqSizeof, CsrWifiSmeAdhocConfigGetReqSer, CsrWifiSmeAdhocConfigGetReqDes, CsrWifiSmeAdhocConfigGetReqSerFree }, + { CSR_WIFI_SME_ADHOC_CONFIG_SET_REQ, CsrWifiSmeAdhocConfigSetReqSizeof, CsrWifiSmeAdhocConfigSetReqSer, CsrWifiSmeAdhocConfigSetReqDes, CsrWifiSmeAdhocConfigSetReqSerFree }, + { CSR_WIFI_SME_BLACKLIST_REQ, CsrWifiSmeBlacklistReqSizeof, CsrWifiSmeBlacklistReqSer, CsrWifiSmeBlacklistReqDes, CsrWifiSmeBlacklistReqSerFree }, + { CSR_WIFI_SME_CALIBRATION_DATA_GET_REQ, CsrWifiSmeCalibrationDataGetReqSizeof, CsrWifiSmeCalibrationDataGetReqSer, CsrWifiSmeCalibrationDataGetReqDes, CsrWifiSmeCalibrationDataGetReqSerFree }, + { CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ, CsrWifiSmeCalibrationDataSetReqSizeof, CsrWifiSmeCalibrationDataSetReqSer, CsrWifiSmeCalibrationDataSetReqDes, CsrWifiSmeCalibrationDataSetReqSerFree }, + { CSR_WIFI_SME_CCX_CONFIG_GET_REQ, CsrWifiSmeCcxConfigGetReqSizeof, CsrWifiSmeCcxConfigGetReqSer, CsrWifiSmeCcxConfigGetReqDes, CsrWifiSmeCcxConfigGetReqSerFree }, + { CSR_WIFI_SME_CCX_CONFIG_SET_REQ, CsrWifiSmeCcxConfigSetReqSizeof, CsrWifiSmeCcxConfigSetReqSer, CsrWifiSmeCcxConfigSetReqDes, CsrWifiSmeCcxConfigSetReqSerFree }, + { CSR_WIFI_SME_COEX_CONFIG_GET_REQ, CsrWifiSmeCoexConfigGetReqSizeof, CsrWifiSmeCoexConfigGetReqSer, CsrWifiSmeCoexConfigGetReqDes, CsrWifiSmeCoexConfigGetReqSerFree }, + { CSR_WIFI_SME_COEX_CONFIG_SET_REQ, CsrWifiSmeCoexConfigSetReqSizeof, CsrWifiSmeCoexConfigSetReqSer, CsrWifiSmeCoexConfigSetReqDes, CsrWifiSmeCoexConfigSetReqSerFree }, + { CSR_WIFI_SME_COEX_INFO_GET_REQ, CsrWifiSmeCoexInfoGetReqSizeof, CsrWifiSmeCoexInfoGetReqSer, CsrWifiSmeCoexInfoGetReqDes, CsrWifiSmeCoexInfoGetReqSerFree }, + { CSR_WIFI_SME_CONNECT_REQ, CsrWifiSmeConnectReqSizeof, CsrWifiSmeConnectReqSer, CsrWifiSmeConnectReqDes, CsrWifiSmeConnectReqSerFree }, + { CSR_WIFI_SME_CONNECTION_CONFIG_GET_REQ, CsrWifiSmeConnectionConfigGetReqSizeof, CsrWifiSmeConnectionConfigGetReqSer, CsrWifiSmeConnectionConfigGetReqDes, CsrWifiSmeConnectionConfigGetReqSerFree }, + { CSR_WIFI_SME_CONNECTION_INFO_GET_REQ, CsrWifiSmeConnectionInfoGetReqSizeof, CsrWifiSmeConnectionInfoGetReqSer, CsrWifiSmeConnectionInfoGetReqDes, CsrWifiSmeConnectionInfoGetReqSerFree }, + { CSR_WIFI_SME_CONNECTION_STATS_GET_REQ, CsrWifiSmeConnectionStatsGetReqSizeof, CsrWifiSmeConnectionStatsGetReqSer, CsrWifiSmeConnectionStatsGetReqDes, CsrWifiSmeConnectionStatsGetReqSerFree }, + { CSR_WIFI_SME_DEACTIVATE_REQ, CsrWifiSmeDeactivateReqSizeof, CsrWifiSmeDeactivateReqSer, CsrWifiSmeDeactivateReqDes, CsrWifiSmeDeactivateReqSerFree }, + { CSR_WIFI_SME_DISCONNECT_REQ, CsrWifiSmeDisconnectReqSizeof, CsrWifiSmeDisconnectReqSer, CsrWifiSmeDisconnectReqDes, CsrWifiSmeDisconnectReqSerFree }, + { CSR_WIFI_SME_EVENT_MASK_SET_REQ, CsrWifiSmeEventMaskSetReqSizeof, CsrWifiSmeEventMaskSetReqSer, CsrWifiSmeEventMaskSetReqDes, CsrWifiSmeEventMaskSetReqSerFree }, + { CSR_WIFI_SME_HOST_CONFIG_GET_REQ, CsrWifiSmeHostConfigGetReqSizeof, CsrWifiSmeHostConfigGetReqSer, CsrWifiSmeHostConfigGetReqDes, CsrWifiSmeHostConfigGetReqSerFree }, + { CSR_WIFI_SME_HOST_CONFIG_SET_REQ, CsrWifiSmeHostConfigSetReqSizeof, CsrWifiSmeHostConfigSetReqSer, CsrWifiSmeHostConfigSetReqDes, CsrWifiSmeHostConfigSetReqSerFree }, + { CSR_WIFI_SME_KEY_REQ, CsrWifiSmeKeyReqSizeof, CsrWifiSmeKeyReqSer, CsrWifiSmeKeyReqDes, CsrWifiSmeKeyReqSerFree }, + { CSR_WIFI_SME_LINK_QUALITY_GET_REQ, CsrWifiSmeLinkQualityGetReqSizeof, CsrWifiSmeLinkQualityGetReqSer, CsrWifiSmeLinkQualityGetReqDes, CsrWifiSmeLinkQualityGetReqSerFree }, + { CSR_WIFI_SME_MIB_CONFIG_GET_REQ, CsrWifiSmeMibConfigGetReqSizeof, CsrWifiSmeMibConfigGetReqSer, CsrWifiSmeMibConfigGetReqDes, CsrWifiSmeMibConfigGetReqSerFree }, + { CSR_WIFI_SME_MIB_CONFIG_SET_REQ, CsrWifiSmeMibConfigSetReqSizeof, CsrWifiSmeMibConfigSetReqSer, CsrWifiSmeMibConfigSetReqDes, CsrWifiSmeMibConfigSetReqSerFree }, + { CSR_WIFI_SME_MIB_GET_NEXT_REQ, CsrWifiSmeMibGetNextReqSizeof, CsrWifiSmeMibGetNextReqSer, CsrWifiSmeMibGetNextReqDes, CsrWifiSmeMibGetNextReqSerFree }, + { CSR_WIFI_SME_MIB_GET_REQ, CsrWifiSmeMibGetReqSizeof, CsrWifiSmeMibGetReqSer, CsrWifiSmeMibGetReqDes, CsrWifiSmeMibGetReqSerFree }, + { CSR_WIFI_SME_MIB_SET_REQ, CsrWifiSmeMibSetReqSizeof, CsrWifiSmeMibSetReqSer, CsrWifiSmeMibSetReqDes, CsrWifiSmeMibSetReqSerFree }, + { CSR_WIFI_SME_MULTICAST_ADDRESS_REQ, CsrWifiSmeMulticastAddressReqSizeof, CsrWifiSmeMulticastAddressReqSer, CsrWifiSmeMulticastAddressReqDes, CsrWifiSmeMulticastAddressReqSerFree }, + { CSR_WIFI_SME_PACKET_FILTER_SET_REQ, CsrWifiSmePacketFilterSetReqSizeof, CsrWifiSmePacketFilterSetReqSer, CsrWifiSmePacketFilterSetReqDes, CsrWifiSmePacketFilterSetReqSerFree }, + { CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_REQ, CsrWifiSmePermanentMacAddressGetReqSizeof, CsrWifiSmePermanentMacAddressGetReqSer, CsrWifiSmePermanentMacAddressGetReqDes, CsrWifiSmePermanentMacAddressGetReqSerFree }, + { CSR_WIFI_SME_PMKID_REQ, CsrWifiSmePmkidReqSizeof, CsrWifiSmePmkidReqSer, CsrWifiSmePmkidReqDes, CsrWifiSmePmkidReqSerFree }, + { CSR_WIFI_SME_POWER_CONFIG_GET_REQ, CsrWifiSmePowerConfigGetReqSizeof, CsrWifiSmePowerConfigGetReqSer, CsrWifiSmePowerConfigGetReqDes, CsrWifiSmePowerConfigGetReqSerFree }, + { CSR_WIFI_SME_POWER_CONFIG_SET_REQ, CsrWifiSmePowerConfigSetReqSizeof, CsrWifiSmePowerConfigSetReqSer, CsrWifiSmePowerConfigSetReqDes, CsrWifiSmePowerConfigSetReqSerFree }, + { CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_REQ, CsrWifiSmeRegulatoryDomainInfoGetReqSizeof, CsrWifiSmeRegulatoryDomainInfoGetReqSer, CsrWifiSmeRegulatoryDomainInfoGetReqDes, CsrWifiSmeRegulatoryDomainInfoGetReqSerFree }, + { CSR_WIFI_SME_ROAMING_CONFIG_GET_REQ, CsrWifiSmeRoamingConfigGetReqSizeof, CsrWifiSmeRoamingConfigGetReqSer, CsrWifiSmeRoamingConfigGetReqDes, CsrWifiSmeRoamingConfigGetReqSerFree }, + { CSR_WIFI_SME_ROAMING_CONFIG_SET_REQ, CsrWifiSmeRoamingConfigSetReqSizeof, CsrWifiSmeRoamingConfigSetReqSer, CsrWifiSmeRoamingConfigSetReqDes, CsrWifiSmeRoamingConfigSetReqSerFree }, + { CSR_WIFI_SME_SCAN_CONFIG_GET_REQ, CsrWifiSmeScanConfigGetReqSizeof, CsrWifiSmeScanConfigGetReqSer, CsrWifiSmeScanConfigGetReqDes, CsrWifiSmeScanConfigGetReqSerFree }, + { CSR_WIFI_SME_SCAN_CONFIG_SET_REQ, CsrWifiSmeScanConfigSetReqSizeof, CsrWifiSmeScanConfigSetReqSer, CsrWifiSmeScanConfigSetReqDes, CsrWifiSmeScanConfigSetReqSerFree }, + { CSR_WIFI_SME_SCAN_FULL_REQ, CsrWifiSmeScanFullReqSizeof, CsrWifiSmeScanFullReqSer, CsrWifiSmeScanFullReqDes, CsrWifiSmeScanFullReqSerFree }, + { CSR_WIFI_SME_SCAN_RESULTS_FLUSH_REQ, CsrWifiSmeScanResultsFlushReqSizeof, CsrWifiSmeScanResultsFlushReqSer, CsrWifiSmeScanResultsFlushReqDes, CsrWifiSmeScanResultsFlushReqSerFree }, + { CSR_WIFI_SME_SCAN_RESULTS_GET_REQ, CsrWifiSmeScanResultsGetReqSizeof, CsrWifiSmeScanResultsGetReqSer, CsrWifiSmeScanResultsGetReqDes, CsrWifiSmeScanResultsGetReqSerFree }, + { CSR_WIFI_SME_SME_STA_CONFIG_GET_REQ, CsrWifiSmeSmeStaConfigGetReqSizeof, CsrWifiSmeSmeStaConfigGetReqSer, CsrWifiSmeSmeStaConfigGetReqDes, CsrWifiSmeSmeStaConfigGetReqSerFree }, + { CSR_WIFI_SME_SME_STA_CONFIG_SET_REQ, CsrWifiSmeSmeStaConfigSetReqSizeof, CsrWifiSmeSmeStaConfigSetReqSer, CsrWifiSmeSmeStaConfigSetReqDes, CsrWifiSmeSmeStaConfigSetReqSerFree }, + { CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_REQ, CsrWifiSmeStationMacAddressGetReqSizeof, CsrWifiSmeStationMacAddressGetReqSer, CsrWifiSmeStationMacAddressGetReqDes, CsrWifiSmeStationMacAddressGetReqSerFree }, + { CSR_WIFI_SME_TSPEC_REQ, CsrWifiSmeTspecReqSizeof, CsrWifiSmeTspecReqSer, CsrWifiSmeTspecReqDes, CsrWifiSmeTspecReqSerFree }, + { CSR_WIFI_SME_VERSIONS_GET_REQ, CsrWifiSmeVersionsGetReqSizeof, CsrWifiSmeVersionsGetReqSer, CsrWifiSmeVersionsGetReqDes, CsrWifiSmeVersionsGetReqSerFree }, + { CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ, CsrWifiSmeWifiFlightmodeReqSizeof, CsrWifiSmeWifiFlightmodeReqSer, CsrWifiSmeWifiFlightmodeReqDes, CsrWifiSmeWifiFlightmodeReqSerFree }, + { CSR_WIFI_SME_WIFI_OFF_REQ, CsrWifiSmeWifiOffReqSizeof, CsrWifiSmeWifiOffReqSer, CsrWifiSmeWifiOffReqDes, CsrWifiSmeWifiOffReqSerFree }, + { CSR_WIFI_SME_WIFI_ON_REQ, CsrWifiSmeWifiOnReqSizeof, CsrWifiSmeWifiOnReqSer, CsrWifiSmeWifiOnReqDes, CsrWifiSmeWifiOnReqSerFree }, + { CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ, CsrWifiSmeCloakedSsidsSetReqSizeof, CsrWifiSmeCloakedSsidsSetReqSer, CsrWifiSmeCloakedSsidsSetReqDes, CsrWifiSmeCloakedSsidsSetReqSerFree }, + { CSR_WIFI_SME_CLOAKED_SSIDS_GET_REQ, CsrWifiSmeCloakedSsidsGetReqSizeof, CsrWifiSmeCloakedSsidsGetReqSer, CsrWifiSmeCloakedSsidsGetReqDes, CsrWifiSmeCloakedSsidsGetReqSerFree }, + { CSR_WIFI_SME_SME_COMMON_CONFIG_GET_REQ, CsrWifiSmeSmeCommonConfigGetReqSizeof, CsrWifiSmeSmeCommonConfigGetReqSer, CsrWifiSmeSmeCommonConfigGetReqDes, CsrWifiSmeSmeCommonConfigGetReqSerFree }, + { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, CsrWifiSmeSmeCommonConfigSetReqSizeof, CsrWifiSmeSmeCommonConfigSetReqSer, CsrWifiSmeSmeCommonConfigSetReqDes, CsrWifiSmeSmeCommonConfigSetReqSerFree }, + { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, CsrWifiSmeInterfaceCapabilityGetReqSizeof, CsrWifiSmeInterfaceCapabilityGetReqSer, CsrWifiSmeInterfaceCapabilityGetReqDes, CsrWifiSmeInterfaceCapabilityGetReqSerFree }, + { CSR_WIFI_SME_WPS_CONFIGURATION_REQ, CsrWifiSmeWpsConfigurationReqSizeof, CsrWifiSmeWpsConfigurationReqSer, CsrWifiSmeWpsConfigurationReqDes, CsrWifiSmeWpsConfigurationReqSerFree }, + { CSR_WIFI_SME_ACTIVATE_CFM, CsrWifiSmeActivateCfmSizeof, CsrWifiSmeActivateCfmSer, CsrWifiSmeActivateCfmDes, CsrWifiSmeActivateCfmSerFree }, + { CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, CsrWifiSmeAdhocConfigGetCfmSizeof, CsrWifiSmeAdhocConfigGetCfmSer, CsrWifiSmeAdhocConfigGetCfmDes, CsrWifiSmeAdhocConfigGetCfmSerFree }, + { CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, CsrWifiSmeAdhocConfigSetCfmSizeof, CsrWifiSmeAdhocConfigSetCfmSer, CsrWifiSmeAdhocConfigSetCfmDes, CsrWifiSmeAdhocConfigSetCfmSerFree }, + { CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND, CsrWifiSmeAssociationCompleteIndSizeof, CsrWifiSmeAssociationCompleteIndSer, CsrWifiSmeAssociationCompleteIndDes, CsrWifiSmeAssociationCompleteIndSerFree }, + { CSR_WIFI_SME_ASSOCIATION_START_IND, CsrWifiSmeAssociationStartIndSizeof, CsrWifiSmeAssociationStartIndSer, CsrWifiSmeAssociationStartIndDes, CsrWifiSmeAssociationStartIndSerFree }, + { CSR_WIFI_SME_BLACKLIST_CFM, CsrWifiSmeBlacklistCfmSizeof, CsrWifiSmeBlacklistCfmSer, CsrWifiSmeBlacklistCfmDes, CsrWifiSmeBlacklistCfmSerFree }, + { CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM, CsrWifiSmeCalibrationDataGetCfmSizeof, CsrWifiSmeCalibrationDataGetCfmSer, CsrWifiSmeCalibrationDataGetCfmDes, CsrWifiSmeCalibrationDataGetCfmSerFree }, + { CSR_WIFI_SME_CALIBRATION_DATA_SET_CFM, CsrWifiSmeCalibrationDataSetCfmSizeof, CsrWifiSmeCalibrationDataSetCfmSer, CsrWifiSmeCalibrationDataSetCfmDes, CsrWifiSmeCalibrationDataSetCfmSerFree }, + { CSR_WIFI_SME_CCX_CONFIG_GET_CFM, CsrWifiSmeCcxConfigGetCfmSizeof, CsrWifiSmeCcxConfigGetCfmSer, CsrWifiSmeCcxConfigGetCfmDes, CsrWifiSmeCcxConfigGetCfmSerFree }, + { CSR_WIFI_SME_CCX_CONFIG_SET_CFM, CsrWifiSmeCcxConfigSetCfmSizeof, CsrWifiSmeCcxConfigSetCfmSer, CsrWifiSmeCcxConfigSetCfmDes, CsrWifiSmeCcxConfigSetCfmSerFree }, + { CSR_WIFI_SME_COEX_CONFIG_GET_CFM, CsrWifiSmeCoexConfigGetCfmSizeof, CsrWifiSmeCoexConfigGetCfmSer, CsrWifiSmeCoexConfigGetCfmDes, CsrWifiSmeCoexConfigGetCfmSerFree }, + { CSR_WIFI_SME_COEX_CONFIG_SET_CFM, CsrWifiSmeCoexConfigSetCfmSizeof, CsrWifiSmeCoexConfigSetCfmSer, CsrWifiSmeCoexConfigSetCfmDes, CsrWifiSmeCoexConfigSetCfmSerFree }, + { CSR_WIFI_SME_COEX_INFO_GET_CFM, CsrWifiSmeCoexInfoGetCfmSizeof, CsrWifiSmeCoexInfoGetCfmSer, CsrWifiSmeCoexInfoGetCfmDes, CsrWifiSmeCoexInfoGetCfmSerFree }, + { CSR_WIFI_SME_CONNECT_CFM, CsrWifiSmeConnectCfmSizeof, CsrWifiSmeConnectCfmSer, CsrWifiSmeConnectCfmDes, CsrWifiSmeConnectCfmSerFree }, + { CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM, CsrWifiSmeConnectionConfigGetCfmSizeof, CsrWifiSmeConnectionConfigGetCfmSer, CsrWifiSmeConnectionConfigGetCfmDes, CsrWifiSmeConnectionConfigGetCfmSerFree }, + { CSR_WIFI_SME_CONNECTION_INFO_GET_CFM, CsrWifiSmeConnectionInfoGetCfmSizeof, CsrWifiSmeConnectionInfoGetCfmSer, CsrWifiSmeConnectionInfoGetCfmDes, CsrWifiSmeConnectionInfoGetCfmSerFree }, + { CSR_WIFI_SME_CONNECTION_QUALITY_IND, CsrWifiSmeConnectionQualityIndSizeof, CsrWifiSmeConnectionQualityIndSer, CsrWifiSmeConnectionQualityIndDes, CsrWifiSmeConnectionQualityIndSerFree }, + { CSR_WIFI_SME_CONNECTION_STATS_GET_CFM, CsrWifiSmeConnectionStatsGetCfmSizeof, CsrWifiSmeConnectionStatsGetCfmSer, CsrWifiSmeConnectionStatsGetCfmDes, CsrWifiSmeConnectionStatsGetCfmSerFree }, + { CSR_WIFI_SME_DEACTIVATE_CFM, CsrWifiSmeDeactivateCfmSizeof, CsrWifiSmeDeactivateCfmSer, CsrWifiSmeDeactivateCfmDes, CsrWifiSmeDeactivateCfmSerFree }, + { CSR_WIFI_SME_DISCONNECT_CFM, CsrWifiSmeDisconnectCfmSizeof, CsrWifiSmeDisconnectCfmSer, CsrWifiSmeDisconnectCfmDes, CsrWifiSmeDisconnectCfmSerFree }, + { CSR_WIFI_SME_EVENT_MASK_SET_CFM, CsrWifiSmeEventMaskSetCfmSizeof, CsrWifiSmeEventMaskSetCfmSer, CsrWifiSmeEventMaskSetCfmDes, CsrWifiSmeEventMaskSetCfmSerFree }, + { CSR_WIFI_SME_HOST_CONFIG_GET_CFM, CsrWifiSmeHostConfigGetCfmSizeof, CsrWifiSmeHostConfigGetCfmSer, CsrWifiSmeHostConfigGetCfmDes, CsrWifiSmeHostConfigGetCfmSerFree }, + { CSR_WIFI_SME_HOST_CONFIG_SET_CFM, CsrWifiSmeHostConfigSetCfmSizeof, CsrWifiSmeHostConfigSetCfmSer, CsrWifiSmeHostConfigSetCfmDes, CsrWifiSmeHostConfigSetCfmSerFree }, + { CSR_WIFI_SME_IBSS_STATION_IND, CsrWifiSmeIbssStationIndSizeof, CsrWifiSmeIbssStationIndSer, CsrWifiSmeIbssStationIndDes, CsrWifiSmeIbssStationIndSerFree }, + { CSR_WIFI_SME_KEY_CFM, CsrWifiSmeKeyCfmSizeof, CsrWifiSmeKeyCfmSer, CsrWifiSmeKeyCfmDes, CsrWifiSmeKeyCfmSerFree }, + { CSR_WIFI_SME_LINK_QUALITY_GET_CFM, CsrWifiSmeLinkQualityGetCfmSizeof, CsrWifiSmeLinkQualityGetCfmSer, CsrWifiSmeLinkQualityGetCfmDes, CsrWifiSmeLinkQualityGetCfmSerFree }, + { CSR_WIFI_SME_MEDIA_STATUS_IND, CsrWifiSmeMediaStatusIndSizeof, CsrWifiSmeMediaStatusIndSer, CsrWifiSmeMediaStatusIndDes, CsrWifiSmeMediaStatusIndSerFree }, + { CSR_WIFI_SME_MIB_CONFIG_GET_CFM, CsrWifiSmeMibConfigGetCfmSizeof, CsrWifiSmeMibConfigGetCfmSer, CsrWifiSmeMibConfigGetCfmDes, CsrWifiSmeMibConfigGetCfmSerFree }, + { CSR_WIFI_SME_MIB_CONFIG_SET_CFM, CsrWifiSmeMibConfigSetCfmSizeof, CsrWifiSmeMibConfigSetCfmSer, CsrWifiSmeMibConfigSetCfmDes, CsrWifiSmeMibConfigSetCfmSerFree }, + { CSR_WIFI_SME_MIB_GET_CFM, CsrWifiSmeMibGetCfmSizeof, CsrWifiSmeMibGetCfmSer, CsrWifiSmeMibGetCfmDes, CsrWifiSmeMibGetCfmSerFree }, + { CSR_WIFI_SME_MIB_GET_NEXT_CFM, CsrWifiSmeMibGetNextCfmSizeof, CsrWifiSmeMibGetNextCfmSer, CsrWifiSmeMibGetNextCfmDes, CsrWifiSmeMibGetNextCfmSerFree }, + { CSR_WIFI_SME_MIB_SET_CFM, CsrWifiSmeMibSetCfmSizeof, CsrWifiSmeMibSetCfmSer, CsrWifiSmeMibSetCfmDes, CsrWifiSmeMibSetCfmSerFree }, + { CSR_WIFI_SME_MIC_FAILURE_IND, CsrWifiSmeMicFailureIndSizeof, CsrWifiSmeMicFailureIndSer, CsrWifiSmeMicFailureIndDes, CsrWifiSmeMicFailureIndSerFree }, + { CSR_WIFI_SME_MULTICAST_ADDRESS_CFM, CsrWifiSmeMulticastAddressCfmSizeof, CsrWifiSmeMulticastAddressCfmSer, CsrWifiSmeMulticastAddressCfmDes, CsrWifiSmeMulticastAddressCfmSerFree }, + { CSR_WIFI_SME_PACKET_FILTER_SET_CFM, CsrWifiSmePacketFilterSetCfmSizeof, CsrWifiSmePacketFilterSetCfmSer, CsrWifiSmePacketFilterSetCfmDes, CsrWifiSmePacketFilterSetCfmSerFree }, + { CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_CFM, CsrWifiSmePermanentMacAddressGetCfmSizeof, CsrWifiSmePermanentMacAddressGetCfmSer, CsrWifiSmePermanentMacAddressGetCfmDes, CsrWifiSmePermanentMacAddressGetCfmSerFree }, + { CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND, CsrWifiSmePmkidCandidateListIndSizeof, CsrWifiSmePmkidCandidateListIndSer, CsrWifiSmePmkidCandidateListIndDes, CsrWifiSmePmkidCandidateListIndSerFree }, + { CSR_WIFI_SME_PMKID_CFM, CsrWifiSmePmkidCfmSizeof, CsrWifiSmePmkidCfmSer, CsrWifiSmePmkidCfmDes, CsrWifiSmePmkidCfmSerFree }, + { CSR_WIFI_SME_POWER_CONFIG_GET_CFM, CsrWifiSmePowerConfigGetCfmSizeof, CsrWifiSmePowerConfigGetCfmSer, CsrWifiSmePowerConfigGetCfmDes, CsrWifiSmePowerConfigGetCfmSerFree }, + { CSR_WIFI_SME_POWER_CONFIG_SET_CFM, CsrWifiSmePowerConfigSetCfmSizeof, CsrWifiSmePowerConfigSetCfmSer, CsrWifiSmePowerConfigSetCfmDes, CsrWifiSmePowerConfigSetCfmSerFree }, + { CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_CFM, CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof, CsrWifiSmeRegulatoryDomainInfoGetCfmSer, CsrWifiSmeRegulatoryDomainInfoGetCfmDes, CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree }, + { CSR_WIFI_SME_ROAM_COMPLETE_IND, CsrWifiSmeRoamCompleteIndSizeof, CsrWifiSmeRoamCompleteIndSer, CsrWifiSmeRoamCompleteIndDes, CsrWifiSmeRoamCompleteIndSerFree }, + { CSR_WIFI_SME_ROAM_START_IND, CsrWifiSmeRoamStartIndSizeof, CsrWifiSmeRoamStartIndSer, CsrWifiSmeRoamStartIndDes, CsrWifiSmeRoamStartIndSerFree }, + { CSR_WIFI_SME_ROAMING_CONFIG_GET_CFM, CsrWifiSmeRoamingConfigGetCfmSizeof, CsrWifiSmeRoamingConfigGetCfmSer, CsrWifiSmeRoamingConfigGetCfmDes, CsrWifiSmeRoamingConfigGetCfmSerFree }, + { CSR_WIFI_SME_ROAMING_CONFIG_SET_CFM, CsrWifiSmeRoamingConfigSetCfmSizeof, CsrWifiSmeRoamingConfigSetCfmSer, CsrWifiSmeRoamingConfigSetCfmDes, CsrWifiSmeRoamingConfigSetCfmSerFree }, + { CSR_WIFI_SME_SCAN_CONFIG_GET_CFM, CsrWifiSmeScanConfigGetCfmSizeof, CsrWifiSmeScanConfigGetCfmSer, CsrWifiSmeScanConfigGetCfmDes, CsrWifiSmeScanConfigGetCfmSerFree }, + { CSR_WIFI_SME_SCAN_CONFIG_SET_CFM, CsrWifiSmeScanConfigSetCfmSizeof, CsrWifiSmeScanConfigSetCfmSer, CsrWifiSmeScanConfigSetCfmDes, CsrWifiSmeScanConfigSetCfmSerFree }, + { CSR_WIFI_SME_SCAN_FULL_CFM, CsrWifiSmeScanFullCfmSizeof, CsrWifiSmeScanFullCfmSer, CsrWifiSmeScanFullCfmDes, CsrWifiSmeScanFullCfmSerFree }, + { CSR_WIFI_SME_SCAN_RESULT_IND, CsrWifiSmeScanResultIndSizeof, CsrWifiSmeScanResultIndSer, CsrWifiSmeScanResultIndDes, CsrWifiSmeScanResultIndSerFree }, + { CSR_WIFI_SME_SCAN_RESULTS_FLUSH_CFM, CsrWifiSmeScanResultsFlushCfmSizeof, CsrWifiSmeScanResultsFlushCfmSer, CsrWifiSmeScanResultsFlushCfmDes, CsrWifiSmeScanResultsFlushCfmSerFree }, + { CSR_WIFI_SME_SCAN_RESULTS_GET_CFM, CsrWifiSmeScanResultsGetCfmSizeof, CsrWifiSmeScanResultsGetCfmSer, CsrWifiSmeScanResultsGetCfmDes, CsrWifiSmeScanResultsGetCfmSerFree }, + { CSR_WIFI_SME_SME_STA_CONFIG_GET_CFM, CsrWifiSmeSmeStaConfigGetCfmSizeof, CsrWifiSmeSmeStaConfigGetCfmSer, CsrWifiSmeSmeStaConfigGetCfmDes, CsrWifiSmeSmeStaConfigGetCfmSerFree }, + { CSR_WIFI_SME_SME_STA_CONFIG_SET_CFM, CsrWifiSmeSmeStaConfigSetCfmSizeof, CsrWifiSmeSmeStaConfigSetCfmSer, CsrWifiSmeSmeStaConfigSetCfmDes, CsrWifiSmeSmeStaConfigSetCfmSerFree }, + { CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_CFM, CsrWifiSmeStationMacAddressGetCfmSizeof, CsrWifiSmeStationMacAddressGetCfmSer, CsrWifiSmeStationMacAddressGetCfmDes, CsrWifiSmeStationMacAddressGetCfmSerFree }, + { CSR_WIFI_SME_TSPEC_IND, CsrWifiSmeTspecIndSizeof, CsrWifiSmeTspecIndSer, CsrWifiSmeTspecIndDes, CsrWifiSmeTspecIndSerFree }, + { CSR_WIFI_SME_TSPEC_CFM, CsrWifiSmeTspecCfmSizeof, CsrWifiSmeTspecCfmSer, CsrWifiSmeTspecCfmDes, CsrWifiSmeTspecCfmSerFree }, + { CSR_WIFI_SME_VERSIONS_GET_CFM, CsrWifiSmeVersionsGetCfmSizeof, CsrWifiSmeVersionsGetCfmSer, CsrWifiSmeVersionsGetCfmDes, CsrWifiSmeVersionsGetCfmSerFree }, + { CSR_WIFI_SME_WIFI_FLIGHTMODE_CFM, CsrWifiSmeWifiFlightmodeCfmSizeof, CsrWifiSmeWifiFlightmodeCfmSer, CsrWifiSmeWifiFlightmodeCfmDes, CsrWifiSmeWifiFlightmodeCfmSerFree }, + { CSR_WIFI_SME_WIFI_OFF_IND, CsrWifiSmeWifiOffIndSizeof, CsrWifiSmeWifiOffIndSer, CsrWifiSmeWifiOffIndDes, CsrWifiSmeWifiOffIndSerFree }, + { CSR_WIFI_SME_WIFI_OFF_CFM, CsrWifiSmeWifiOffCfmSizeof, CsrWifiSmeWifiOffCfmSer, CsrWifiSmeWifiOffCfmDes, CsrWifiSmeWifiOffCfmSerFree }, + { CSR_WIFI_SME_WIFI_ON_CFM, CsrWifiSmeWifiOnCfmSizeof, CsrWifiSmeWifiOnCfmSer, CsrWifiSmeWifiOnCfmDes, CsrWifiSmeWifiOnCfmSerFree }, + { CSR_WIFI_SME_CLOAKED_SSIDS_SET_CFM, CsrWifiSmeCloakedSsidsSetCfmSizeof, CsrWifiSmeCloakedSsidsSetCfmSer, CsrWifiSmeCloakedSsidsSetCfmDes, CsrWifiSmeCloakedSsidsSetCfmSerFree }, + { CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM, CsrWifiSmeCloakedSsidsGetCfmSizeof, CsrWifiSmeCloakedSsidsGetCfmSer, CsrWifiSmeCloakedSsidsGetCfmDes, CsrWifiSmeCloakedSsidsGetCfmSerFree }, + { CSR_WIFI_SME_WIFI_ON_IND, CsrWifiSmeWifiOnIndSizeof, CsrWifiSmeWifiOnIndSer, CsrWifiSmeWifiOnIndDes, CsrWifiSmeWifiOnIndSerFree }, + { CSR_WIFI_SME_SME_COMMON_CONFIG_GET_CFM, CsrWifiSmeSmeCommonConfigGetCfmSizeof, CsrWifiSmeSmeCommonConfigGetCfmSer, CsrWifiSmeSmeCommonConfigGetCfmDes, CsrWifiSmeSmeCommonConfigGetCfmSerFree }, + { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_CFM, CsrWifiSmeSmeCommonConfigSetCfmSizeof, CsrWifiSmeSmeCommonConfigSetCfmSer, CsrWifiSmeSmeCommonConfigSetCfmDes, CsrWifiSmeSmeCommonConfigSetCfmSerFree }, + { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_CFM, CsrWifiSmeInterfaceCapabilityGetCfmSizeof, CsrWifiSmeInterfaceCapabilityGetCfmSer, CsrWifiSmeInterfaceCapabilityGetCfmDes, CsrWifiSmeInterfaceCapabilityGetCfmSerFree }, + { CSR_WIFI_SME_ERROR_IND, CsrWifiSmeErrorIndSizeof, CsrWifiSmeErrorIndSer, CsrWifiSmeErrorIndDes, CsrWifiSmeErrorIndSerFree }, + { CSR_WIFI_SME_INFO_IND, CsrWifiSmeInfoIndSizeof, CsrWifiSmeInfoIndSer, CsrWifiSmeInfoIndDes, CsrWifiSmeInfoIndSerFree }, + { CSR_WIFI_SME_CORE_DUMP_IND, CsrWifiSmeCoreDumpIndSizeof, CsrWifiSmeCoreDumpIndSer, CsrWifiSmeCoreDumpIndDes, CsrWifiSmeCoreDumpIndSerFree }, + { CSR_WIFI_SME_AMP_STATUS_CHANGE_IND, CsrWifiSmeAmpStatusChangeIndSizeof, CsrWifiSmeAmpStatusChangeIndSer, CsrWifiSmeAmpStatusChangeIndDes, CsrWifiSmeAmpStatusChangeIndSerFree }, + { CSR_WIFI_SME_WPS_CONFIGURATION_CFM, CsrWifiSmeWpsConfigurationCfmSizeof, CsrWifiSmeWpsConfigurationCfmSer, CsrWifiSmeWpsConfigurationCfmDes, CsrWifiSmeWpsConfigurationCfmSerFree }, + + { 0, NULL, NULL, NULL, NULL }, +}; + +CsrMsgConvMsgEntry* CsrWifiSmeConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint16 msgType) +{ + if (msgType & CSR_PRIM_UPSTREAM) + { + CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT; + if (index < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) && + csrwifisme_conv_lut[index].msgType == msgType) + { + return &csrwifisme_conv_lut[index]; + } + } + else + { + if (msgType < CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT && + csrwifisme_conv_lut[msgType].msgType == msgType) + { + return &csrwifisme_conv_lut[msgType]; + } + } + return NULL; +} + + +void CsrWifiSmeConverterInit(void) +{ + CsrMsgConvInsert(CSR_WIFI_SME_PRIM, csrwifisme_conv_lut); + CsrMsgConvCustomLookupRegister(CSR_WIFI_SME_PRIM, CsrWifiSmeConverterLookup); +} + + +#ifdef CSR_LOG_ENABLE +static const CsrLogPrimitiveInformation csrwifisme_conv_info = { + CSR_WIFI_SME_PRIM, + (CsrCharString *)"CSR_WIFI_SME_PRIM", + csrwifisme_conv_lut +}; +const CsrLogPrimitiveInformation* CsrWifiSmeTechInfoGet(void) +{ + return &csrwifisme_conv_info; +} + + +#endif /* CSR_LOG_ENABLE */ +#endif /* EXCLUDE_CSR_WIFI_SME_MODULE */ diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.h b/drivers/staging/csr/csr_wifi_sme_converter_init.h new file mode 100644 index 000000000000..8637eb7baafe --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_converter_init.h @@ -0,0 +1,42 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_CONVERTER_INIT_H__ +#define CSR_WIFI_SME_CONVERTER_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EXCLUDE_CSR_WIFI_SME_MODULE + +#include "csr_msgconv.h" + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" + +extern const CsrLogPrimitiveInformation* CsrWifiSmeTechInfoGet(void); +#endif /* CSR_LOG_ENABLE */ + +extern void CsrWifiSmeConverterInit(void); + +#else /* EXCLUDE_CSR_WIFI_SME_MODULE */ + +#define CsrWifiSmeConverterInit() + +#endif /* EXCLUDE_CSR_WIFI_SME_MODULE */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_SME_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c new file mode 100644 index 000000000000..c8e66be899cd --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c @@ -0,0 +1,181 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_sme_prim.h" +#include "csr_wifi_sme_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiSmeFreeDownstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_SME_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiSmeFreeDownstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_SME_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiSmePrim *) message)) + { + case CSR_WIFI_SME_BLACKLIST_REQ: + { + CsrWifiSmeBlacklistReq *p = (CsrWifiSmeBlacklistReq *)message; + CsrPmemFree(p->setAddresses); + p->setAddresses = NULL; + break; + } + case CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ: + { + CsrWifiSmeCalibrationDataSetReq *p = (CsrWifiSmeCalibrationDataSetReq *)message; + CsrPmemFree(p->calibrationData); + p->calibrationData = NULL; + break; + } + case CSR_WIFI_SME_CONNECT_REQ: + { + CsrWifiSmeConnectReq *p = (CsrWifiSmeConnectReq *)message; + CsrPmemFree(p->connectionConfig.mlmeAssociateReqInformationElements); + p->connectionConfig.mlmeAssociateReqInformationElements = NULL; + break; + } + case CSR_WIFI_SME_MIB_GET_NEXT_REQ: + { + CsrWifiSmeMibGetNextReq *p = (CsrWifiSmeMibGetNextReq *)message; + CsrPmemFree(p->mibAttribute); + p->mibAttribute = NULL; + break; + } + case CSR_WIFI_SME_MIB_GET_REQ: + { + CsrWifiSmeMibGetReq *p = (CsrWifiSmeMibGetReq *)message; + CsrPmemFree(p->mibAttribute); + p->mibAttribute = NULL; + break; + } + case CSR_WIFI_SME_MIB_SET_REQ: + { + CsrWifiSmeMibSetReq *p = (CsrWifiSmeMibSetReq *)message; + CsrPmemFree(p->mibAttribute); + p->mibAttribute = NULL; + break; + } + case CSR_WIFI_SME_MULTICAST_ADDRESS_REQ: + { + CsrWifiSmeMulticastAddressReq *p = (CsrWifiSmeMulticastAddressReq *)message; + CsrPmemFree(p->setAddresses); + p->setAddresses = NULL; + break; + } + case CSR_WIFI_SME_PACKET_FILTER_SET_REQ: + { + CsrWifiSmePacketFilterSetReq *p = (CsrWifiSmePacketFilterSetReq *)message; + CsrPmemFree(p->filter); + p->filter = NULL; + break; + } + case CSR_WIFI_SME_PMKID_REQ: + { + CsrWifiSmePmkidReq *p = (CsrWifiSmePmkidReq *)message; + CsrPmemFree(p->setPmkids); + p->setPmkids = NULL; + break; + } + case CSR_WIFI_SME_SCAN_CONFIG_SET_REQ: + { + CsrWifiSmeScanConfigSetReq *p = (CsrWifiSmeScanConfigSetReq *)message; + CsrPmemFree(p->scanConfig.passiveChannelList); + p->scanConfig.passiveChannelList = NULL; + break; + } + case CSR_WIFI_SME_SCAN_FULL_REQ: + { + CsrWifiSmeScanFullReq *p = (CsrWifiSmeScanFullReq *)message; + CsrPmemFree(p->ssid); + p->ssid = NULL; + CsrPmemFree(p->channelList); + p->channelList = NULL; + CsrPmemFree(p->probeIe); + p->probeIe = NULL; + break; + } + case CSR_WIFI_SME_TSPEC_REQ: + { + CsrWifiSmeTspecReq *p = (CsrWifiSmeTspecReq *)message; + CsrPmemFree(p->tspec); + p->tspec = NULL; + CsrPmemFree(p->tclas); + p->tclas = NULL; + break; + } + case CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ: + { + CsrWifiSmeWifiFlightmodeReq *p = (CsrWifiSmeWifiFlightmodeReq *)message; + { + CsrUint16 i1; + for (i1 = 0; i1 < p->mibFilesCount; i1++) + { + CsrPmemFree(p->mibFiles[i1].data); + p->mibFiles[i1].data = NULL; + } + } + CsrPmemFree(p->mibFiles); + p->mibFiles = NULL; + break; + } + case CSR_WIFI_SME_WIFI_ON_REQ: + { + CsrWifiSmeWifiOnReq *p = (CsrWifiSmeWifiOnReq *)message; + { + CsrUint16 i1; + for (i1 = 0; i1 < p->mibFilesCount; i1++) + { + CsrPmemFree(p->mibFiles[i1].data); + p->mibFiles[i1].data = NULL; + } + } + CsrPmemFree(p->mibFiles); + p->mibFiles = NULL; + break; + } + case CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ: + { + CsrWifiSmeCloakedSsidsSetReq *p = (CsrWifiSmeCloakedSsidsSetReq *)message; + CsrPmemFree(p->cloakedSsids.cloakedSsids); + p->cloakedSsids.cloakedSsids = NULL; + break; + } + case CSR_WIFI_SME_WPS_CONFIGURATION_REQ: + { + CsrWifiSmeWpsConfigurationReq *p = (CsrWifiSmeWpsConfigurationReq *)message; + CsrPmemFree(p->wpsConfig.secondaryDeviceType); + p->wpsConfig.secondaryDeviceType = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c new file mode 100644 index 000000000000..c32bf6877bff --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c @@ -0,0 +1,276 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_sme_prim.h" +#include "csr_wifi_sme_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiSmeFreeUpstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_SME_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiSmeFreeUpstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_SME_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiSmePrim *) message)) + { + case CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND: + { + CsrWifiSmeAssociationCompleteInd *p = (CsrWifiSmeAssociationCompleteInd *)message; + CsrPmemFree(p->connectionInfo.beaconFrame); + p->connectionInfo.beaconFrame = NULL; + CsrPmemFree(p->connectionInfo.associationReqFrame); + p->connectionInfo.associationReqFrame = NULL; + CsrPmemFree(p->connectionInfo.associationRspFrame); + p->connectionInfo.associationRspFrame = NULL; + CsrPmemFree(p->connectionInfo.assocScanInfoElements); + p->connectionInfo.assocScanInfoElements = NULL; + CsrPmemFree(p->connectionInfo.assocReqInfoElements); + p->connectionInfo.assocReqInfoElements = NULL; + CsrPmemFree(p->connectionInfo.assocRspInfoElements); + p->connectionInfo.assocRspInfoElements = NULL; + break; + } + case CSR_WIFI_SME_BLACKLIST_CFM: + { + CsrWifiSmeBlacklistCfm *p = (CsrWifiSmeBlacklistCfm *)message; + CsrPmemFree(p->getAddresses); + p->getAddresses = NULL; + break; + } + case CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM: + { + CsrWifiSmeCalibrationDataGetCfm *p = (CsrWifiSmeCalibrationDataGetCfm *)message; + CsrPmemFree(p->calibrationData); + p->calibrationData = NULL; + break; + } + case CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM: + { + CsrWifiSmeConnectionConfigGetCfm *p = (CsrWifiSmeConnectionConfigGetCfm *)message; + CsrPmemFree(p->connectionConfig.mlmeAssociateReqInformationElements); + p->connectionConfig.mlmeAssociateReqInformationElements = NULL; + break; + } + case CSR_WIFI_SME_CONNECTION_INFO_GET_CFM: + { + CsrWifiSmeConnectionInfoGetCfm *p = (CsrWifiSmeConnectionInfoGetCfm *)message; + CsrPmemFree(p->connectionInfo.beaconFrame); + p->connectionInfo.beaconFrame = NULL; + CsrPmemFree(p->connectionInfo.associationReqFrame); + p->connectionInfo.associationReqFrame = NULL; + CsrPmemFree(p->connectionInfo.associationRspFrame); + p->connectionInfo.associationRspFrame = NULL; + CsrPmemFree(p->connectionInfo.assocScanInfoElements); + p->connectionInfo.assocScanInfoElements = NULL; + CsrPmemFree(p->connectionInfo.assocReqInfoElements); + p->connectionInfo.assocReqInfoElements = NULL; + CsrPmemFree(p->connectionInfo.assocRspInfoElements); + p->connectionInfo.assocRspInfoElements = NULL; + break; + } + case CSR_WIFI_SME_MEDIA_STATUS_IND: + { + CsrWifiSmeMediaStatusInd *p = (CsrWifiSmeMediaStatusInd *)message; + CsrPmemFree(p->connectionInfo.beaconFrame); + p->connectionInfo.beaconFrame = NULL; + CsrPmemFree(p->connectionInfo.associationReqFrame); + p->connectionInfo.associationReqFrame = NULL; + CsrPmemFree(p->connectionInfo.associationRspFrame); + p->connectionInfo.associationRspFrame = NULL; + CsrPmemFree(p->connectionInfo.assocScanInfoElements); + p->connectionInfo.assocScanInfoElements = NULL; + CsrPmemFree(p->connectionInfo.assocReqInfoElements); + p->connectionInfo.assocReqInfoElements = NULL; + CsrPmemFree(p->connectionInfo.assocRspInfoElements); + p->connectionInfo.assocRspInfoElements = NULL; + break; + } + case CSR_WIFI_SME_MIB_GET_CFM: + { + CsrWifiSmeMibGetCfm *p = (CsrWifiSmeMibGetCfm *)message; + CsrPmemFree(p->mibAttribute); + p->mibAttribute = NULL; + break; + } + case CSR_WIFI_SME_MIB_GET_NEXT_CFM: + { + CsrWifiSmeMibGetNextCfm *p = (CsrWifiSmeMibGetNextCfm *)message; + CsrPmemFree(p->mibAttribute); + p->mibAttribute = NULL; + break; + } + case CSR_WIFI_SME_MULTICAST_ADDRESS_CFM: + { + CsrWifiSmeMulticastAddressCfm *p = (CsrWifiSmeMulticastAddressCfm *)message; + CsrPmemFree(p->getAddresses); + p->getAddresses = NULL; + break; + } + case CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND: + { + CsrWifiSmePmkidCandidateListInd *p = (CsrWifiSmePmkidCandidateListInd *)message; + CsrPmemFree(p->pmkidCandidates); + p->pmkidCandidates = NULL; + break; + } + case CSR_WIFI_SME_PMKID_CFM: + { + CsrWifiSmePmkidCfm *p = (CsrWifiSmePmkidCfm *)message; + CsrPmemFree(p->getPmkids); + p->getPmkids = NULL; + break; + } + case CSR_WIFI_SME_SCAN_CONFIG_GET_CFM: + { + CsrWifiSmeScanConfigGetCfm *p = (CsrWifiSmeScanConfigGetCfm *)message; + CsrPmemFree(p->scanConfig.passiveChannelList); + p->scanConfig.passiveChannelList = NULL; + break; + } + case CSR_WIFI_SME_SCAN_RESULT_IND: + { + CsrWifiSmeScanResultInd *p = (CsrWifiSmeScanResultInd *)message; + CsrPmemFree(p->result.informationElements); + p->result.informationElements = NULL; + switch (p->result.p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_GO: + { + CsrUint16 i4; + for (i4 = 0; i4 < p->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrPmemFree(p->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType); + p->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL; + } + } + CsrPmemFree(p->result.deviceInfo.groupInfo.p2PClientInfo); + p->result.deviceInfo.groupInfo.p2PClientInfo = NULL; + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrPmemFree(p->result.deviceInfo.standalonedevInfo.secDeviceType); + p->result.deviceInfo.standalonedevInfo.secDeviceType = NULL; + break; + default: + break; + } + break; + } + case CSR_WIFI_SME_SCAN_RESULTS_GET_CFM: + { + CsrWifiSmeScanResultsGetCfm *p = (CsrWifiSmeScanResultsGetCfm *)message; + { + CsrUint16 i1; + for (i1 = 0; i1 < p->scanResultsCount; i1++) + { + CsrPmemFree(p->scanResults[i1].informationElements); + p->scanResults[i1].informationElements = NULL; + switch (p->scanResults[i1].p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_GO: + { + CsrUint16 i4; + for (i4 = 0; i4 < p->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrPmemFree(p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType); + p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL; + } + } + CsrPmemFree(p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo); + p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo = NULL; + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrPmemFree(p->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType); + p->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType = NULL; + break; + default: + break; + } + } + } + CsrPmemFree(p->scanResults); + p->scanResults = NULL; + break; + } + case CSR_WIFI_SME_TSPEC_IND: + { + CsrWifiSmeTspecInd *p = (CsrWifiSmeTspecInd *)message; + CsrPmemFree(p->tspec); + p->tspec = NULL; + break; + } + case CSR_WIFI_SME_TSPEC_CFM: + { + CsrWifiSmeTspecCfm *p = (CsrWifiSmeTspecCfm *)message; + CsrPmemFree(p->tspec); + p->tspec = NULL; + break; + } + case CSR_WIFI_SME_VERSIONS_GET_CFM: + { + CsrWifiSmeVersionsGetCfm *p = (CsrWifiSmeVersionsGetCfm *)message; + CsrPmemFree(p->versions.routerBuild); + p->versions.routerBuild = NULL; + CsrPmemFree(p->versions.smeBuild); + p->versions.smeBuild = NULL; + break; + } + case CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM: + { + CsrWifiSmeCloakedSsidsGetCfm *p = (CsrWifiSmeCloakedSsidsGetCfm *)message; + CsrPmemFree(p->cloakedSsids.cloakedSsids); + p->cloakedSsids.cloakedSsids = NULL; + break; + } + case CSR_WIFI_SME_ERROR_IND: + { + CsrWifiSmeErrorInd *p = (CsrWifiSmeErrorInd *)message; + CsrPmemFree(p->errorMessage); + p->errorMessage = NULL; + break; + } + case CSR_WIFI_SME_INFO_IND: + { + CsrWifiSmeInfoInd *p = (CsrWifiSmeInfoInd *)message; + CsrPmemFree(p->infoMessage); + p->infoMessage = NULL; + break; + } + case CSR_WIFI_SME_CORE_DUMP_IND: + { + CsrWifiSmeCoreDumpInd *p = (CsrWifiSmeCoreDumpInd *)message; + CsrPmemFree(p->data); + p->data = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_sme_lib.h b/drivers/staging/csr/csr_wifi_sme_lib.h new file mode 100644 index 000000000000..16053fb6ed43 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_lib.h @@ -0,0 +1,4282 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_LIB_H__ +#define CSR_WIFI_SME_LIB_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_sched.h" +#include "csr_util.h" +#include "csr_msg_transport.h" + +#include "csr_wifi_lib.h" + +#include "csr_wifi_sme_prim.h" +#include "csr_wifi_sme_task.h" + + +#ifndef CSR_WIFI_SME_LIB_DESTINATION_QUEUE +# ifdef CSR_WIFI_NME_ENABLE +# include "csr_wifi_nme_task.h" +# define CSR_WIFI_SME_LIB_DESTINATION_QUEUE CSR_WIFI_NME_IFACEQUEUE +# else +# define CSR_WIFI_SME_LIB_DESTINATION_QUEUE CSR_WIFI_SME_IFACEQUEUE +# endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------------------------* + * CsrWifiSmeFreeUpstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_SME upstream message. Does not + * free the message itself, and can only be used for upstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_SME upstream message + *----------------------------------------------------------------------------*/ +void CsrWifiSmeFreeUpstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * CsrWifiSmeFreeDownstreamMessageContents + * + * DESCRIPTION + * Free the allocated memory in a CSR_WIFI_SME downstream message. Does not + * free the message itself, and can only be used for downstream messages. + * + * PARAMETERS + * Deallocates the resources in a CSR_WIFI_SME downstream message + *----------------------------------------------------------------------------*/ +void CsrWifiSmeFreeDownstreamMessageContents(CsrUint16 eventClass, void *message); + +/*----------------------------------------------------------------------------* + * Enum to string functions + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiSme80211NetworkTypeToString(CsrWifiSme80211NetworkType value); +const CsrCharString* CsrWifiSme80211PrivacyModeToString(CsrWifiSme80211PrivacyMode value); +const CsrCharString* CsrWifiSme80211dTrustLevelToString(CsrWifiSme80211dTrustLevel value); +const CsrCharString* CsrWifiSmeAmpStatusToString(CsrWifiSmeAmpStatus value); +const CsrCharString* CsrWifiSmeAuthModeToString(CsrWifiSmeAuthMode value); +const CsrCharString* CsrWifiSmeBasicUsabilityToString(CsrWifiSmeBasicUsability value); +const CsrCharString* CsrWifiSmeBssTypeToString(CsrWifiSmeBssType value); +const CsrCharString* CsrWifiSmeCoexSchemeToString(CsrWifiSmeCoexScheme value); +const CsrCharString* CsrWifiSmeControlIndicationToString(CsrWifiSmeControlIndication value); +const CsrCharString* CsrWifiSmeCtsProtectionTypeToString(CsrWifiSmeCtsProtectionType value); +const CsrCharString* CsrWifiSmeD3AutoScanModeToString(CsrWifiSmeD3AutoScanMode value); +const CsrCharString* CsrWifiSmeEncryptionToString(CsrWifiSmeEncryption value); +const CsrCharString* CsrWifiSmeFirmwareDriverInterfaceToString(CsrWifiSmeFirmwareDriverInterface value); +const CsrCharString* CsrWifiSmeHostPowerModeToString(CsrWifiSmeHostPowerMode value); +const CsrCharString* CsrWifiSmeIEEE80211ReasonToString(CsrWifiSmeIEEE80211Reason value); +const CsrCharString* CsrWifiSmeIEEE80211ResultToString(CsrWifiSmeIEEE80211Result value); +const CsrCharString* CsrWifiSmeIndicationsToString(CsrWifiSmeIndications value); +const CsrCharString* CsrWifiSmeKeyTypeToString(CsrWifiSmeKeyType value); +const CsrCharString* CsrWifiSmeListActionToString(CsrWifiSmeListAction value); +const CsrCharString* CsrWifiSmeMediaStatusToString(CsrWifiSmeMediaStatus value); +const CsrCharString* CsrWifiSmeP2pCapabilityToString(CsrWifiSmeP2pCapability value); +const CsrCharString* CsrWifiSmeP2pGroupCapabilityToString(CsrWifiSmeP2pGroupCapability value); +const CsrCharString* CsrWifiSmeP2pNoaConfigMethodToString(CsrWifiSmeP2pNoaConfigMethod value); +const CsrCharString* CsrWifiSmeP2pRoleToString(CsrWifiSmeP2pRole value); +const CsrCharString* CsrWifiSmeP2pStatusToString(CsrWifiSmeP2pStatus value); +const CsrCharString* CsrWifiSmePacketFilterModeToString(CsrWifiSmePacketFilterMode value); +const CsrCharString* CsrWifiSmePowerSaveLevelToString(CsrWifiSmePowerSaveLevel value); +const CsrCharString* CsrWifiSmePreambleTypeToString(CsrWifiSmePreambleType value); +const CsrCharString* CsrWifiSmeRadioIFToString(CsrWifiSmeRadioIF value); +const CsrCharString* CsrWifiSmeRegulatoryDomainToString(CsrWifiSmeRegulatoryDomain value); +const CsrCharString* CsrWifiSmeRoamReasonToString(CsrWifiSmeRoamReason value); +const CsrCharString* CsrWifiSmeScanTypeToString(CsrWifiSmeScanType value); +const CsrCharString* CsrWifiSmeTrafficTypeToString(CsrWifiSmeTrafficType value); +const CsrCharString* CsrWifiSmeTspecCtrlToString(CsrWifiSmeTspecCtrl value); +const CsrCharString* CsrWifiSmeTspecResultCodeToString(CsrWifiSmeTspecResultCode value); +const CsrCharString* CsrWifiSmeWepAuthModeToString(CsrWifiSmeWepAuthMode value); +const CsrCharString* CsrWifiSmeWepCredentialTypeToString(CsrWifiSmeWepCredentialType value); +const CsrCharString* CsrWifiSmeWmmModeToString(CsrWifiSmeWmmMode value); +const CsrCharString* CsrWifiSmeWmmQosInfoToString(CsrWifiSmeWmmQosInfo value); +const CsrCharString* CsrWifiSmeWpsConfigTypeToString(CsrWifiSmeWpsConfigType value); +const CsrCharString* CsrWifiSmeWpsDeviceCategoryToString(CsrWifiSmeWpsDeviceCategory value); +const CsrCharString* CsrWifiSmeWpsDeviceSubCategoryToString(CsrWifiSmeWpsDeviceSubCategory value); +const CsrCharString* CsrWifiSmeWpsDpidToString(CsrWifiSmeWpsDpid value); +const CsrCharString* CsrWifiSmeWpsRegistrationToString(CsrWifiSmeWpsRegistration value); + + +/*----------------------------------------------------------------------------* + * CsrPrim Type toString function. + * Converts a message type to the String name of the Message + *----------------------------------------------------------------------------*/ +const CsrCharString* CsrWifiSmePrimTypeToString(CsrPrim msgType); + +/*----------------------------------------------------------------------------* + * Lookup arrays for PrimType name Strings + *----------------------------------------------------------------------------*/ +extern const CsrCharString *CsrWifiSmeUpstreamPrimNames[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT]; +extern const CsrCharString *CsrWifiSmeDownstreamPrimNames[CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT]; + +/******************************************************************************* + + NAME + CsrWifiSmeActivateReqSend + + DESCRIPTION + The WMA sends this primitive to activate the SME. + The WMA must activate the SME before it can send any other primitive. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeActivateReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeActivateReq *) CsrPmemAlloc(sizeof(CsrWifiSmeActivateReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ACTIVATE_REQ, dst__, src__); + +#define CsrWifiSmeActivateReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeActivateReq *msg__; \ + CsrWifiSmeActivateReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeActivateReqSend(src__) \ + CsrWifiSmeActivateReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeActivateCfmSend + + DESCRIPTION + The SME sends this primitive when the activation is complete. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeActivateCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeActivateCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeActivateCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ACTIVATE_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeActivateCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeActivateCfm *msg__; \ + CsrWifiSmeActivateCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeActivateCfmSend(dst__, status__) \ + CsrWifiSmeActivateCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the adHocConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeAdhocConfigGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeAdhocConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeAdhocConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_GET_REQ, dst__, src__); + +#define CsrWifiSmeAdhocConfigGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeAdhocConfigGetReq *msg__; \ + CsrWifiSmeAdhocConfigGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAdhocConfigGetReqSend(src__) \ + CsrWifiSmeAdhocConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + adHocConfig - Contains the values used when starting an Ad-hoc (IBSS) + connection. + +*******************************************************************************/ +#define CsrWifiSmeAdhocConfigGetCfmCreate(msg__, dst__, src__, status__, adHocConfig__) \ + msg__ = (CsrWifiSmeAdhocConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeAdhocConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->adHocConfig = (adHocConfig__); + +#define CsrWifiSmeAdhocConfigGetCfmSendTo(dst__, src__, status__, adHocConfig__) \ + { \ + CsrWifiSmeAdhocConfigGetCfm *msg__; \ + CsrWifiSmeAdhocConfigGetCfmCreate(msg__, dst__, src__, status__, adHocConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAdhocConfigGetCfmSend(dst__, status__, adHocConfig__) \ + CsrWifiSmeAdhocConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, adHocConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the adHocConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + adHocConfig - Sets the values to use when starting an ad hoc network. + +*******************************************************************************/ +#define CsrWifiSmeAdhocConfigSetReqCreate(msg__, dst__, src__, adHocConfig__) \ + msg__ = (CsrWifiSmeAdhocConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeAdhocConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_SET_REQ, dst__, src__); \ + msg__->adHocConfig = (adHocConfig__); + +#define CsrWifiSmeAdhocConfigSetReqSendTo(dst__, src__, adHocConfig__) \ + { \ + CsrWifiSmeAdhocConfigSetReq *msg__; \ + CsrWifiSmeAdhocConfigSetReqCreate(msg__, dst__, src__, adHocConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAdhocConfigSetReqSend(src__, adHocConfig__) \ + CsrWifiSmeAdhocConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, adHocConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeAdhocConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeAdhocConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeAdhocConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeAdhocConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeAdhocConfigSetCfm *msg__; \ + CsrWifiSmeAdhocConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAdhocConfigSetCfmSend(dst__, status__) \ + CsrWifiSmeAdhocConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeAmpStatusChangeIndSend + + DESCRIPTION + Indication of change to AMP activity. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface on which the AMP activity changed. + ampStatus - The new status of AMP activity.Range: {AMP_ACTIVE, + AMP_INACTIVE}. + +*******************************************************************************/ +#define CsrWifiSmeAmpStatusChangeIndCreate(msg__, dst__, src__, interfaceTag__, ampStatus__) \ + msg__ = (CsrWifiSmeAmpStatusChangeInd *) CsrPmemAlloc(sizeof(CsrWifiSmeAmpStatusChangeInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_AMP_STATUS_CHANGE_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->ampStatus = (ampStatus__); + +#define CsrWifiSmeAmpStatusChangeIndSendTo(dst__, src__, interfaceTag__, ampStatus__) \ + { \ + CsrWifiSmeAmpStatusChangeInd *msg__; \ + CsrWifiSmeAmpStatusChangeIndCreate(msg__, dst__, src__, interfaceTag__, ampStatus__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAmpStatusChangeIndSend(dst__, interfaceTag__, ampStatus__) \ + CsrWifiSmeAmpStatusChangeIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, ampStatus__) + +/******************************************************************************* + + NAME + CsrWifiSmeAssociationCompleteIndSend + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it completes an attempt to associate with an AP. If + the association was successful, status will be set to + CSR_WIFI_SME_STATUS_SUCCESS, otherwise status and deauthReason shall be + set to appropriate error codes. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the association procedure + connectionInfo - This parameter is relevant only if result is + CSR_WIFI_SME_STATUS_SUCCESS: + it points to the connection information for the new network + deauthReason - This parameter is relevant only if result is not + CSR_WIFI_SME_STATUS_SUCCESS: + if the AP deauthorised the station, it gives the reason of + the deauthorization + +*******************************************************************************/ +#define CsrWifiSmeAssociationCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__, deauthReason__) \ + msg__ = (CsrWifiSmeAssociationCompleteInd *) CsrPmemAlloc(sizeof(CsrWifiSmeAssociationCompleteInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->connectionInfo = (connectionInfo__); \ + msg__->deauthReason = (deauthReason__); + +#define CsrWifiSmeAssociationCompleteIndSendTo(dst__, src__, interfaceTag__, status__, connectionInfo__, deauthReason__) \ + { \ + CsrWifiSmeAssociationCompleteInd *msg__; \ + CsrWifiSmeAssociationCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__, deauthReason__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAssociationCompleteIndSend(dst__, interfaceTag__, status__, connectionInfo__, deauthReason__) \ + CsrWifiSmeAssociationCompleteIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionInfo__, deauthReason__) + +/******************************************************************************* + + NAME + CsrWifiSmeAssociationStartIndSend + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it begins an attempt to associate with an AP. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + address - BSSID of the associating network + ssid - Service Set identifier of the associating network + +*******************************************************************************/ +#define CsrWifiSmeAssociationStartIndCreate(msg__, dst__, src__, interfaceTag__, address__, ssid__) \ + msg__ = (CsrWifiSmeAssociationStartInd *) CsrPmemAlloc(sizeof(CsrWifiSmeAssociationStartInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ASSOCIATION_START_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->address = (address__); \ + msg__->ssid = (ssid__); + +#define CsrWifiSmeAssociationStartIndSendTo(dst__, src__, interfaceTag__, address__, ssid__) \ + { \ + CsrWifiSmeAssociationStartInd *msg__; \ + CsrWifiSmeAssociationStartIndCreate(msg__, dst__, src__, interfaceTag__, address__, ssid__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeAssociationStartIndSend(dst__, interfaceTag__, address__, ssid__) \ + CsrWifiSmeAssociationStartIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, address__, ssid__) + +/******************************************************************************* + + NAME + CsrWifiSmeBlacklistReqSend + + DESCRIPTION + The wireless manager application should call this primitive to notify the + driver of any networks that should not be connected to. The interface + allows the wireless manager application to query, add, remove, and flush + the BSSIDs that the driver may not connect or roam to. + When this primitive adds to the black list the BSSID to which the SME is + currently connected, the SME will try to roam, if applicable, to another + BSSID in the same ESS; if the roaming procedure fails, the SME will + disconnect. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter instructs + the driver to modify or provide the list of blacklisted + networks. + setAddressCount - Number of BSSIDs sent with this primitive + setAddresses - Pointer to the list of BBSIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +#define CsrWifiSmeBlacklistReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressCount__, setAddresses__) \ + msg__ = (CsrWifiSmeBlacklistReq *) CsrPmemAlloc(sizeof(CsrWifiSmeBlacklistReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_BLACKLIST_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->action = (action__); \ + msg__->setAddressCount = (setAddressCount__); \ + msg__->setAddresses = (setAddresses__); + +#define CsrWifiSmeBlacklistReqSendTo(dst__, src__, interfaceTag__, action__, setAddressCount__, setAddresses__) \ + { \ + CsrWifiSmeBlacklistReq *msg__; \ + CsrWifiSmeBlacklistReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressCount__, setAddresses__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeBlacklistReqSend(src__, interfaceTag__, action__, setAddressCount__, setAddresses__) \ + CsrWifiSmeBlacklistReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, setAddressCount__, setAddresses__) + +/******************************************************************************* + + NAME + CsrWifiSmeBlacklistCfmSend + + DESCRIPTION + The SME will call this primitive when the action on the blacklist has + completed. For a GET action, this primitive also reports the list of + BBSIDs in the blacklist. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + getAddressCount - This parameter is only relevant if action is + CSR_WIFI_SME_LIST_ACTION_GET: + number of BSSIDs sent with this primitive + getAddresses - Pointer to the list of BBSIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +#define CsrWifiSmeBlacklistCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) \ + msg__ = (CsrWifiSmeBlacklistCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeBlacklistCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_BLACKLIST_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->action = (action__); \ + msg__->getAddressCount = (getAddressCount__); \ + msg__->getAddresses = (getAddresses__); + +#define CsrWifiSmeBlacklistCfmSendTo(dst__, src__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) \ + { \ + CsrWifiSmeBlacklistCfm *msg__; \ + CsrWifiSmeBlacklistCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeBlacklistCfmSend(dst__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) \ + CsrWifiSmeBlacklistCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataGetReqSend + + DESCRIPTION + This primitive retrieves the Wi-Fi radio calibration data. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeCalibrationDataGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeCalibrationDataGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCalibrationDataGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_GET_REQ, dst__, src__); + +#define CsrWifiSmeCalibrationDataGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeCalibrationDataGetReq *msg__; \ + CsrWifiSmeCalibrationDataGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCalibrationDataGetReqSend(src__) \ + CsrWifiSmeCalibrationDataGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + calibrationDataLength - Number of bytes in the buffer pointed by + calibrationData + calibrationData - Pointer to a buffer of length calibrationDataLength + containing the calibration data + +*******************************************************************************/ +#define CsrWifiSmeCalibrationDataGetCfmCreate(msg__, dst__, src__, status__, calibrationDataLength__, calibrationData__) \ + msg__ = (CsrWifiSmeCalibrationDataGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCalibrationDataGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->calibrationDataLength = (calibrationDataLength__); \ + msg__->calibrationData = (calibrationData__); + +#define CsrWifiSmeCalibrationDataGetCfmSendTo(dst__, src__, status__, calibrationDataLength__, calibrationData__) \ + { \ + CsrWifiSmeCalibrationDataGetCfm *msg__; \ + CsrWifiSmeCalibrationDataGetCfmCreate(msg__, dst__, src__, status__, calibrationDataLength__, calibrationData__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCalibrationDataGetCfmSend(dst__, status__, calibrationDataLength__, calibrationData__) \ + CsrWifiSmeCalibrationDataGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, calibrationDataLength__, calibrationData__) + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataSetReqSend + + DESCRIPTION + This primitive sets the Wi-Fi radio calibration data. + The usage of the primitive with proper calibration data will avoid + time-consuming configuration after power-up. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + calibrationDataLength - Number of bytes in the buffer pointed by + calibrationData + calibrationData - Pointer to a buffer of length calibrationDataLength + containing the calibration data + +*******************************************************************************/ +#define CsrWifiSmeCalibrationDataSetReqCreate(msg__, dst__, src__, calibrationDataLength__, calibrationData__) \ + msg__ = (CsrWifiSmeCalibrationDataSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCalibrationDataSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ, dst__, src__); \ + msg__->calibrationDataLength = (calibrationDataLength__); \ + msg__->calibrationData = (calibrationData__); + +#define CsrWifiSmeCalibrationDataSetReqSendTo(dst__, src__, calibrationDataLength__, calibrationData__) \ + { \ + CsrWifiSmeCalibrationDataSetReq *msg__; \ + CsrWifiSmeCalibrationDataSetReqCreate(msg__, dst__, src__, calibrationDataLength__, calibrationData__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCalibrationDataSetReqSend(src__, calibrationDataLength__, calibrationData__) \ + CsrWifiSmeCalibrationDataSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, calibrationDataLength__, calibrationData__) + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeCalibrationDataSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeCalibrationDataSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCalibrationDataSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeCalibrationDataSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeCalibrationDataSetCfm *msg__; \ + CsrWifiSmeCalibrationDataSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCalibrationDataSetCfmSend(dst__, status__) \ + CsrWifiSmeCalibrationDataSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the CcxConfig parameter. + CURRENTLY NOT SUPPORTED. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeCcxConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeCcxConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeCcxConfigGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeCcxConfigGetReq *msg__; \ + CsrWifiSmeCcxConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCcxConfigGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeCcxConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + ccxConfig - Currently not supported + +*******************************************************************************/ +#define CsrWifiSmeCcxConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ccxConfig__) \ + msg__ = (CsrWifiSmeCcxConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->ccxConfig = (ccxConfig__); + +#define CsrWifiSmeCcxConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, ccxConfig__) \ + { \ + CsrWifiSmeCcxConfigGetCfm *msg__; \ + CsrWifiSmeCcxConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ccxConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCcxConfigGetCfmSend(dst__, interfaceTag__, status__, ccxConfig__) \ + CsrWifiSmeCcxConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, ccxConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the CcxConfig parameter. + CURRENTLY NOT SUPPORTED. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + ccxConfig - Currently not supported + +*******************************************************************************/ +#define CsrWifiSmeCcxConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, ccxConfig__) \ + msg__ = (CsrWifiSmeCcxConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->ccxConfig = (ccxConfig__); + +#define CsrWifiSmeCcxConfigSetReqSendTo(dst__, src__, interfaceTag__, ccxConfig__) \ + { \ + CsrWifiSmeCcxConfigSetReq *msg__; \ + CsrWifiSmeCcxConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, ccxConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCcxConfigSetReqSend(src__, interfaceTag__, ccxConfig__) \ + CsrWifiSmeCcxConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, ccxConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeCcxConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeCcxConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_SET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeCcxConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeCcxConfigSetCfm *msg__; \ + CsrWifiSmeCcxConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCcxConfigSetCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeCcxConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsGetReqSend + + DESCRIPTION + This primitive gets the value of the CloakedSsids parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeCloakedSsidsGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeCloakedSsidsGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCloakedSsidsGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_GET_REQ, dst__, src__); + +#define CsrWifiSmeCloakedSsidsGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeCloakedSsidsGetReq *msg__; \ + CsrWifiSmeCloakedSsidsGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCloakedSsidsGetReqSend(src__) \ + CsrWifiSmeCloakedSsidsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + cloakedSsids - Reports list of cloaked SSIDs that are explicitly scanned for + by the driver + +*******************************************************************************/ +#define CsrWifiSmeCloakedSsidsGetCfmCreate(msg__, dst__, src__, status__, cloakedSsids__) \ + msg__ = (CsrWifiSmeCloakedSsidsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCloakedSsidsGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->cloakedSsids = (cloakedSsids__); + +#define CsrWifiSmeCloakedSsidsGetCfmSendTo(dst__, src__, status__, cloakedSsids__) \ + { \ + CsrWifiSmeCloakedSsidsGetCfm *msg__; \ + CsrWifiSmeCloakedSsidsGetCfmCreate(msg__, dst__, src__, status__, cloakedSsids__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCloakedSsidsGetCfmSend(dst__, status__, cloakedSsids__) \ + CsrWifiSmeCloakedSsidsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, cloakedSsids__) + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsSetReqSend + + DESCRIPTION + This primitive sets the list of cloaked SSIDs for which the WMA possesses + profiles. + When the driver detects a cloaked AP, the SME will explicitly scan for it + using the list of cloaked SSIDs provided it, and, if the scan succeeds, + it will report the AP to the WMA either via CSR_WIFI_SME_SCAN_RESULT_IND + (if registered) or via CSR_WIFI_SCAN_RESULT_GET_CFM. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + cloakedSsids - Sets the list of cloaked SSIDs + +*******************************************************************************/ +#define CsrWifiSmeCloakedSsidsSetReqCreate(msg__, dst__, src__, cloakedSsids__) \ + msg__ = (CsrWifiSmeCloakedSsidsSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCloakedSsidsSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ, dst__, src__); \ + msg__->cloakedSsids = (cloakedSsids__); + +#define CsrWifiSmeCloakedSsidsSetReqSendTo(dst__, src__, cloakedSsids__) \ + { \ + CsrWifiSmeCloakedSsidsSetReq *msg__; \ + CsrWifiSmeCloakedSsidsSetReqCreate(msg__, dst__, src__, cloakedSsids__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCloakedSsidsSetReqSend(src__, cloakedSsids__) \ + CsrWifiSmeCloakedSsidsSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, cloakedSsids__) + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeCloakedSsidsSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeCloakedSsidsSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCloakedSsidsSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeCloakedSsidsSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeCloakedSsidsSetCfm *msg__; \ + CsrWifiSmeCloakedSsidsSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCloakedSsidsSetCfmSend(dst__, status__) \ + CsrWifiSmeCloakedSsidsSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the CoexConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeCoexConfigGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeCoexConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_GET_REQ, dst__, src__); + +#define CsrWifiSmeCoexConfigGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeCoexConfigGetReq *msg__; \ + CsrWifiSmeCoexConfigGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoexConfigGetReqSend(src__) \ + CsrWifiSmeCoexConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + coexConfig - Reports the parameters used to configure the coexistence + behaviour + +*******************************************************************************/ +#define CsrWifiSmeCoexConfigGetCfmCreate(msg__, dst__, src__, status__, coexConfig__) \ + msg__ = (CsrWifiSmeCoexConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->coexConfig = (coexConfig__); + +#define CsrWifiSmeCoexConfigGetCfmSendTo(dst__, src__, status__, coexConfig__) \ + { \ + CsrWifiSmeCoexConfigGetCfm *msg__; \ + CsrWifiSmeCoexConfigGetCfmCreate(msg__, dst__, src__, status__, coexConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoexConfigGetCfmSend(dst__, status__, coexConfig__) \ + CsrWifiSmeCoexConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, coexConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the CoexConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + coexConfig - Configures the coexistence behaviour + +*******************************************************************************/ +#define CsrWifiSmeCoexConfigSetReqCreate(msg__, dst__, src__, coexConfig__) \ + msg__ = (CsrWifiSmeCoexConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_SET_REQ, dst__, src__); \ + msg__->coexConfig = (coexConfig__); + +#define CsrWifiSmeCoexConfigSetReqSendTo(dst__, src__, coexConfig__) \ + { \ + CsrWifiSmeCoexConfigSetReq *msg__; \ + CsrWifiSmeCoexConfigSetReqCreate(msg__, dst__, src__, coexConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoexConfigSetReqSend(src__, coexConfig__) \ + CsrWifiSmeCoexConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, coexConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeCoexConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeCoexConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeCoexConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeCoexConfigSetCfm *msg__; \ + CsrWifiSmeCoexConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoexConfigSetCfmSend(dst__, status__) \ + CsrWifiSmeCoexConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexInfoGetReqSend + + DESCRIPTION + This primitive gets the value of the CoexInfo parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeCoexInfoGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeCoexInfoGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexInfoGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_INFO_GET_REQ, dst__, src__); + +#define CsrWifiSmeCoexInfoGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeCoexInfoGetReq *msg__; \ + CsrWifiSmeCoexInfoGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoexInfoGetReqSend(src__) \ + CsrWifiSmeCoexInfoGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexInfoGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + coexInfo - Reports information and state related to coexistence. + +*******************************************************************************/ +#define CsrWifiSmeCoexInfoGetCfmCreate(msg__, dst__, src__, status__, coexInfo__) \ + msg__ = (CsrWifiSmeCoexInfoGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexInfoGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_INFO_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->coexInfo = (coexInfo__); + +#define CsrWifiSmeCoexInfoGetCfmSendTo(dst__, src__, status__, coexInfo__) \ + { \ + CsrWifiSmeCoexInfoGetCfm *msg__; \ + CsrWifiSmeCoexInfoGetCfmCreate(msg__, dst__, src__, status__, coexInfo__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoexInfoGetCfmSend(dst__, status__, coexInfo__) \ + CsrWifiSmeCoexInfoGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, coexInfo__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectReqSend + + DESCRIPTION + The wireless manager application calls this primitive to start the + process of joining an 802.11 wireless network or to start an ad hoc + network. + The structure pointed by connectionConfig contains parameters describing + the network to join or, in case of an ad hoc network, to host or join. + The SME will select a network, perform the IEEE 802.11 Join, Authenticate + and Associate exchanges. + The SME selects the networks from the current scan list that match both + the SSID and BSSID, however either or both of these may be the wildcard + value. Using this rule, the following operations are possible: + * To connect to a network by name, specify the SSID and set the BSSID to + 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF. If there are two or more networks visible, + the SME will select the one with the strongest signal. + * To connect to a specific network, specify the BSSID. The SSID is + optional, but if given it must match the SSID of the network. An empty + SSID may be specified by setting the SSID length to zero. Please note + that if the BSSID is specified (i.e. not equal to 0xFF 0xFF 0xFF 0xFF + 0xFF 0xFF), the SME will not attempt to roam if signal conditions become + poor, even if there is an alternative AP with an SSID that matches the + current network SSID. + * To connect to any network matching the other parameters (i.e. security, + etc), set the SSID length to zero and set the BSSID to 0xFF 0xFF 0xFF + 0xFF 0xFF 0xFF. In this case, the SME will order all available networks + by their signal strengths and will iterate through this list until it + successfully connects. + NOTE: Specifying the BSSID will restrict the selection to one specific + network. If SSID and BSSID are given, they must both match the network + for it to be selected. To select a network based on the SSID only, the + wireless manager application must set the BSSID to 0xFF 0xFF 0xFF 0xFF + 0xFF 0xFF. + The SME will try to connect to each network that matches the provided + parameters, one by one, until it succeeds or has tried unsuccessfully + with all the matching networks. + If there is no network that matches the parameters and the request allows + to host an ad hoc network, the SME will advertise a new ad hoc network + instead. + If the SME cannot connect, it will notify the failure in the confirm. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + connectionConfig - Describes the candidate network to join or to host. + +*******************************************************************************/ +#define CsrWifiSmeConnectReqCreate(msg__, dst__, src__, interfaceTag__, connectionConfig__) \ + msg__ = (CsrWifiSmeConnectReq *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECT_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->connectionConfig = (connectionConfig__); + +#define CsrWifiSmeConnectReqSendTo(dst__, src__, interfaceTag__, connectionConfig__) \ + { \ + CsrWifiSmeConnectReq *msg__; \ + CsrWifiSmeConnectReqCreate(msg__, dst__, src__, interfaceTag__, connectionConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectReqSend(src__, interfaceTag__, connectionConfig__) \ + CsrWifiSmeConnectReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, connectionConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectCfmSend + + DESCRIPTION + The SME calls this primitive when the connection exchange is complete or + all connection attempts fail. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request. + CSR_WIFI_SME_STATUS_NOT_FOUND: all attempts by the SME to + locate the requested AP failed + +*******************************************************************************/ +#define CsrWifiSmeConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeConnectCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECT_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeConnectCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeConnectCfm *msg__; \ + CsrWifiSmeConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeConnectCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the ConnectionConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeConnectionConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeConnectionConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_CONFIG_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeConnectionConfigGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeConnectionConfigGetReq *msg__; \ + CsrWifiSmeConnectionConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionConfigGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeConnectionConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + connectionConfig - Parameters used by the SME for selecting a network + +*******************************************************************************/ +#define CsrWifiSmeConnectionConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionConfig__) \ + msg__ = (CsrWifiSmeConnectionConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->connectionConfig = (connectionConfig__); + +#define CsrWifiSmeConnectionConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionConfig__) \ + { \ + CsrWifiSmeConnectionConfigGetCfm *msg__; \ + CsrWifiSmeConnectionConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionConfigGetCfmSend(dst__, interfaceTag__, status__, connectionConfig__) \ + CsrWifiSmeConnectionConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionInfoGetReqSend + + DESCRIPTION + This primitive gets the value of the ConnectionInfo parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeConnectionInfoGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeConnectionInfoGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionInfoGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_INFO_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeConnectionInfoGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeConnectionInfoGetReq *msg__; \ + CsrWifiSmeConnectionInfoGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionInfoGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeConnectionInfoGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionInfoGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + connectionInfo - Information about the current connection + +*******************************************************************************/ +#define CsrWifiSmeConnectionInfoGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__) \ + msg__ = (CsrWifiSmeConnectionInfoGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionInfoGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_INFO_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->connectionInfo = (connectionInfo__); + +#define CsrWifiSmeConnectionInfoGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionInfo__) \ + { \ + CsrWifiSmeConnectionInfoGetCfm *msg__; \ + CsrWifiSmeConnectionInfoGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionInfoGetCfmSend(dst__, interfaceTag__, status__, connectionInfo__) \ + CsrWifiSmeConnectionInfoGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionInfo__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionQualityIndSend + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it whenever the value of the current connection quality + parameters change by more than a certain configurable amount. + The wireless manager application may configure the trigger thresholds for + this indication using the field in smeConfig parameter of + CSR_WIFI_SME_SME_CONFIG_SET_REQ. + Connection quality messages can be suppressed by setting both thresholds + to zero. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + linkQuality - Indicates the quality of the link + +*******************************************************************************/ +#define CsrWifiSmeConnectionQualityIndCreate(msg__, dst__, src__, interfaceTag__, linkQuality__) \ + msg__ = (CsrWifiSmeConnectionQualityInd *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionQualityInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_QUALITY_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->linkQuality = (linkQuality__); + +#define CsrWifiSmeConnectionQualityIndSendTo(dst__, src__, interfaceTag__, linkQuality__) \ + { \ + CsrWifiSmeConnectionQualityInd *msg__; \ + CsrWifiSmeConnectionQualityIndCreate(msg__, dst__, src__, interfaceTag__, linkQuality__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionQualityIndSend(dst__, interfaceTag__, linkQuality__) \ + CsrWifiSmeConnectionQualityIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, linkQuality__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionStatsGetReqSend + + DESCRIPTION + This primitive gets the value of the ConnectionStats parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeConnectionStatsGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeConnectionStatsGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionStatsGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_STATS_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeConnectionStatsGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeConnectionStatsGetReq *msg__; \ + CsrWifiSmeConnectionStatsGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionStatsGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeConnectionStatsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionStatsGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + connectionStats - Statistics for current connection. + +*******************************************************************************/ +#define CsrWifiSmeConnectionStatsGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStats__) \ + msg__ = (CsrWifiSmeConnectionStatsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionStatsGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_STATS_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->connectionStats = (connectionStats__); + +#define CsrWifiSmeConnectionStatsGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionStats__) \ + { \ + CsrWifiSmeConnectionStatsGetCfm *msg__; \ + CsrWifiSmeConnectionStatsGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStats__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeConnectionStatsGetCfmSend(dst__, interfaceTag__, status__, connectionStats__) \ + CsrWifiSmeConnectionStatsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionStats__) + +/******************************************************************************* + + NAME + CsrWifiSmeCoreDumpIndSend + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive Wi-Fi Chip core dump data. + The core dump data may be fragmented and sent using more than one + indication. + To indicate that all the data has been sent, the last indication contains + a 'length' of 0 and 'data' of NULL. + + PARAMETERS + queue - Destination Task Queue + dataLength - Number of bytes in the buffer pointed to by 'data' + data - Pointer to the buffer containing 'dataLength' bytes of core + dump data + +*******************************************************************************/ +#define CsrWifiSmeCoreDumpIndCreate(msg__, dst__, src__, dataLength__, data__) \ + msg__ = (CsrWifiSmeCoreDumpInd *) CsrPmemAlloc(sizeof(CsrWifiSmeCoreDumpInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CORE_DUMP_IND, dst__, src__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); + +#define CsrWifiSmeCoreDumpIndSendTo(dst__, src__, dataLength__, data__) \ + { \ + CsrWifiSmeCoreDumpInd *msg__; \ + CsrWifiSmeCoreDumpIndCreate(msg__, dst__, src__, dataLength__, data__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeCoreDumpIndSend(dst__, dataLength__, data__) \ + CsrWifiSmeCoreDumpIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, dataLength__, data__) + +/******************************************************************************* + + NAME + CsrWifiSmeDeactivateReqSend + + DESCRIPTION + The WMA sends this primitive to deactivate the SME. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeDeactivateReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeDeactivateReq *) CsrPmemAlloc(sizeof(CsrWifiSmeDeactivateReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DEACTIVATE_REQ, dst__, src__); + +#define CsrWifiSmeDeactivateReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeDeactivateReq *msg__; \ + CsrWifiSmeDeactivateReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeDeactivateReqSend(src__) \ + CsrWifiSmeDeactivateReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeDeactivateCfmSend + + DESCRIPTION + The SME sends this primitive when the deactivation is complete. + The WMA cannot send any more primitives until it actives the SME again + sending another CSR_WIFI_SME_ACTIVATE_REQ. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeDeactivateCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeDeactivateCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeDeactivateCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DEACTIVATE_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeDeactivateCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeDeactivateCfm *msg__; \ + CsrWifiSmeDeactivateCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeDeactivateCfmSend(dst__, status__) \ + CsrWifiSmeDeactivateCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeDisconnectReqSend + + DESCRIPTION + The wireless manager application may disconnect from the current network + by calling this primitive + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeDisconnectReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeDisconnectReq *) CsrPmemAlloc(sizeof(CsrWifiSmeDisconnectReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DISCONNECT_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeDisconnectReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeDisconnectReq *msg__; \ + CsrWifiSmeDisconnectReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeDisconnectReqSend(src__, interfaceTag__) \ + CsrWifiSmeDisconnectReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeDisconnectCfmSend + + DESCRIPTION + On reception of CSR_WIFI_SME_DISCONNECT_REQ the SME will perform a + disconnect operation, sending a CsrWifiSmeMediaStatusInd with + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED and then call this primitive when + disconnection is complete. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeDisconnectCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeDisconnectCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DISCONNECT_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeDisconnectCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeDisconnectCfm *msg__; \ + CsrWifiSmeDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeDisconnectCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeDisconnectCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeErrorIndSend + + DESCRIPTION + Important error message indicating a error of some importance + + PARAMETERS + queue - Destination Task Queue + errorMessage - Contains the error message. + +*******************************************************************************/ +#define CsrWifiSmeErrorIndCreate(msg__, dst__, src__, errorMessage__) \ + msg__ = (CsrWifiSmeErrorInd *) CsrPmemAlloc(sizeof(CsrWifiSmeErrorInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ERROR_IND, dst__, src__); \ + msg__->errorMessage = (errorMessage__); + +#define CsrWifiSmeErrorIndSendTo(dst__, src__, errorMessage__) \ + { \ + CsrWifiSmeErrorInd *msg__; \ + CsrWifiSmeErrorIndCreate(msg__, dst__, src__, errorMessage__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeErrorIndSend(dst__, errorMessage__) \ + CsrWifiSmeErrorIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, errorMessage__) + +/******************************************************************************* + + NAME + CsrWifiSmeEventMaskSetReqSend + + DESCRIPTION + The wireless manager application may register with the SME to receive + notification of interesting events. Indications will be sent only if the + wireless manager explicitly registers to be notified of that event. + indMask is a bit mask of values defined in CsrWifiSmeIndicationsMask. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + indMask - Set mask with values from CsrWifiSmeIndications + +*******************************************************************************/ +#define CsrWifiSmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__) \ + msg__ = (CsrWifiSmeEventMaskSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeEventMaskSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_EVENT_MASK_SET_REQ, dst__, src__); \ + msg__->indMask = (indMask__); + +#define CsrWifiSmeEventMaskSetReqSendTo(dst__, src__, indMask__) \ + { \ + CsrWifiSmeEventMaskSetReq *msg__; \ + CsrWifiSmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeEventMaskSetReqSend(src__, indMask__) \ + CsrWifiSmeEventMaskSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, indMask__) + +/******************************************************************************* + + NAME + CsrWifiSmeEventMaskSetCfmSend + + DESCRIPTION + The SME calls the primitive to report the result of the request + primitive. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeEventMaskSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeEventMaskSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeEventMaskSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_EVENT_MASK_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeEventMaskSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeEventMaskSetCfm *msg__; \ + CsrWifiSmeEventMaskSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeEventMaskSetCfmSend(dst__, status__) \ + CsrWifiSmeEventMaskSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the hostConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeHostConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeHostConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeHostConfigGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeHostConfigGetReq *msg__; \ + CsrWifiSmeHostConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeHostConfigGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeHostConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + hostConfig - Current host power state. + +*******************************************************************************/ +#define CsrWifiSmeHostConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, hostConfig__) \ + msg__ = (CsrWifiSmeHostConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->hostConfig = (hostConfig__); + +#define CsrWifiSmeHostConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, hostConfig__) \ + { \ + CsrWifiSmeHostConfigGetCfm *msg__; \ + CsrWifiSmeHostConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, hostConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeHostConfigGetCfmSend(dst__, interfaceTag__, status__, hostConfig__) \ + CsrWifiSmeHostConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, hostConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the hostConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + hostConfig - Communicates a change of host power state (for example, on + mains power, on battery power etc) and of the periodicity of + traffic data + +*******************************************************************************/ +#define CsrWifiSmeHostConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, hostConfig__) \ + msg__ = (CsrWifiSmeHostConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->hostConfig = (hostConfig__); + +#define CsrWifiSmeHostConfigSetReqSendTo(dst__, src__, interfaceTag__, hostConfig__) \ + { \ + CsrWifiSmeHostConfigSetReq *msg__; \ + CsrWifiSmeHostConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, hostConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeHostConfigSetReqSend(src__, interfaceTag__, hostConfig__) \ + CsrWifiSmeHostConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, hostConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeHostConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeHostConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_SET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeHostConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeHostConfigSetCfm *msg__; \ + CsrWifiSmeHostConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeHostConfigSetCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeHostConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeIbssStationIndSend + + DESCRIPTION + The SME will send this primitive to indicate that a station has joined or + left the ad-hoc network. + + PARAMETERS + queue - Destination Task Queue + address - MAC address of the station that has joined or left + isconnected - TRUE if the station joined, FALSE if the station left + +*******************************************************************************/ +#define CsrWifiSmeIbssStationIndCreate(msg__, dst__, src__, address__, isconnected__) \ + msg__ = (CsrWifiSmeIbssStationInd *) CsrPmemAlloc(sizeof(CsrWifiSmeIbssStationInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_IBSS_STATION_IND, dst__, src__); \ + msg__->address = (address__); \ + msg__->isconnected = (isconnected__); + +#define CsrWifiSmeIbssStationIndSendTo(dst__, src__, address__, isconnected__) \ + { \ + CsrWifiSmeIbssStationInd *msg__; \ + CsrWifiSmeIbssStationIndCreate(msg__, dst__, src__, address__, isconnected__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeIbssStationIndSend(dst__, address__, isconnected__) \ + CsrWifiSmeIbssStationIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, address__, isconnected__) + +/******************************************************************************* + + NAME + CsrWifiSmeInfoIndSend + + DESCRIPTION + Message indicating a some info about current activity. Mostly of interest + in testing but may be useful in the field. + + PARAMETERS + queue - Destination Task Queue + infoMessage - Contains the message. + +*******************************************************************************/ +#define CsrWifiSmeInfoIndCreate(msg__, dst__, src__, infoMessage__) \ + msg__ = (CsrWifiSmeInfoInd *) CsrPmemAlloc(sizeof(CsrWifiSmeInfoInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_INFO_IND, dst__, src__); \ + msg__->infoMessage = (infoMessage__); + +#define CsrWifiSmeInfoIndSendTo(dst__, src__, infoMessage__) \ + { \ + CsrWifiSmeInfoInd *msg__; \ + CsrWifiSmeInfoIndCreate(msg__, dst__, src__, infoMessage__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeInfoIndSend(dst__, infoMessage__) \ + CsrWifiSmeInfoIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, infoMessage__) + +/******************************************************************************* + + NAME + CsrWifiSmeInterfaceCapabilityGetReqSend + + DESCRIPTION + The Wireless Manager calls this primitive to ask the SME for the + capabilities of the supported interfaces + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeInterfaceCapabilityGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeInterfaceCapabilityGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeInterfaceCapabilityGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, dst__, src__); + +#define CsrWifiSmeInterfaceCapabilityGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeInterfaceCapabilityGetReq *msg__; \ + CsrWifiSmeInterfaceCapabilityGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeInterfaceCapabilityGetReqSend(src__) \ + CsrWifiSmeInterfaceCapabilityGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeInterfaceCapabilityGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Result of the request + numInterfaces - Number of the interfaces supported + capBitmap - Points to the list of capabilities bitmaps provided for each + interface. + The bits represent the following capabilities: + -bits 7 to 4-Reserved + -bit 3-AMP + -bit 2-P2P + -bit 1-AP + -bit 0-STA + +*******************************************************************************/ +#define CsrWifiSmeInterfaceCapabilityGetCfmCreate(msg__, dst__, src__, status__, numInterfaces__, capBitmap__) \ + msg__ = (CsrWifiSmeInterfaceCapabilityGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeInterfaceCapabilityGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->numInterfaces = (numInterfaces__); \ + CsrMemCpy(msg__->capBitmap, (capBitmap__), sizeof(CsrUint8) * 2); + +#define CsrWifiSmeInterfaceCapabilityGetCfmSendTo(dst__, src__, status__, numInterfaces__, capBitmap__) \ + { \ + CsrWifiSmeInterfaceCapabilityGetCfm *msg__; \ + CsrWifiSmeInterfaceCapabilityGetCfmCreate(msg__, dst__, src__, status__, numInterfaces__, capBitmap__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeInterfaceCapabilityGetCfmSend(dst__, status__, numInterfaces__, capBitmap__) \ + CsrWifiSmeInterfaceCapabilityGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, numInterfaces__, capBitmap__) + +/******************************************************************************* + + NAME + CsrWifiSmeKeyReqSend + + DESCRIPTION + The wireless manager application calls this primitive to add or remove + keys that the chip should use for encryption of data. + The interface allows the wireless manager application to add and remove + keys according to the specified action. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter instructs the + driver to modify or provide the list of keys. + CSR_WIFI_SME_LIST_ACTION_GET is not supported here. + key - Key to be added or removed + +*******************************************************************************/ +#define CsrWifiSmeKeyReqCreate(msg__, dst__, src__, interfaceTag__, action__, key__) \ + msg__ = (CsrWifiSmeKeyReq *) CsrPmemAlloc(sizeof(CsrWifiSmeKeyReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_KEY_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->action = (action__); \ + msg__->key = (key__); + +#define CsrWifiSmeKeyReqSendTo(dst__, src__, interfaceTag__, action__, key__) \ + { \ + CsrWifiSmeKeyReq *msg__; \ + CsrWifiSmeKeyReqCreate(msg__, dst__, src__, interfaceTag__, action__, key__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeKeyReqSend(src__, interfaceTag__, action__, key__) \ + CsrWifiSmeKeyReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, key__) + +/******************************************************************************* + + NAME + CsrWifiSmeKeyCfmSend + + DESCRIPTION + The SME calls the primitive to report the result of the request + primitive. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + keyType - Type of the key added/deleted + peerMacAddress - Peer MAC Address of the key added/deleted + +*******************************************************************************/ +#define CsrWifiSmeKeyCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, keyType__, peerMacAddress__) \ + msg__ = (CsrWifiSmeKeyCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeKeyCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_KEY_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->action = (action__); \ + msg__->keyType = (keyType__); \ + msg__->peerMacAddress = (peerMacAddress__); + +#define CsrWifiSmeKeyCfmSendTo(dst__, src__, interfaceTag__, status__, action__, keyType__, peerMacAddress__) \ + { \ + CsrWifiSmeKeyCfm *msg__; \ + CsrWifiSmeKeyCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, keyType__, peerMacAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeKeyCfmSend(dst__, interfaceTag__, status__, action__, keyType__, peerMacAddress__) \ + CsrWifiSmeKeyCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, keyType__, peerMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiSmeLinkQualityGetReqSend + + DESCRIPTION + This primitive gets the value of the LinkQuality parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeLinkQualityGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeLinkQualityGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeLinkQualityGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_LINK_QUALITY_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeLinkQualityGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeLinkQualityGetReq *msg__; \ + CsrWifiSmeLinkQualityGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeLinkQualityGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeLinkQualityGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeLinkQualityGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + linkQuality - Indicates the quality of the link + +*******************************************************************************/ +#define CsrWifiSmeLinkQualityGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, linkQuality__) \ + msg__ = (CsrWifiSmeLinkQualityGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeLinkQualityGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_LINK_QUALITY_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->linkQuality = (linkQuality__); + +#define CsrWifiSmeLinkQualityGetCfmSendTo(dst__, src__, interfaceTag__, status__, linkQuality__) \ + { \ + CsrWifiSmeLinkQualityGetCfm *msg__; \ + CsrWifiSmeLinkQualityGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, linkQuality__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeLinkQualityGetCfmSend(dst__, interfaceTag__, status__, linkQuality__) \ + CsrWifiSmeLinkQualityGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, linkQuality__) + +/******************************************************************************* + + NAME + CsrWifiSmeMediaStatusIndSend + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it when a network connection is established, lost or has moved to + another AP. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + mediaStatus - Indicates the media status + connectionInfo - This parameter is relevant only if the mediaStatus is + CSR_WIFI_SME_MEDIA_STATUS_CONNECTED: + it points to the connection information for the new network + disassocReason - This parameter is relevant only if the mediaStatus is + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED: + if a disassociation has occurred it gives the reason of the + disassociation + deauthReason - This parameter is relevant only if the mediaStatus is + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED: + if a deauthentication has occurred it gives the reason of + the deauthentication + +*******************************************************************************/ +#define CsrWifiSmeMediaStatusIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) \ + msg__ = (CsrWifiSmeMediaStatusInd *) CsrPmemAlloc(sizeof(CsrWifiSmeMediaStatusInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MEDIA_STATUS_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->mediaStatus = (mediaStatus__); \ + msg__->connectionInfo = (connectionInfo__); \ + msg__->disassocReason = (disassocReason__); \ + msg__->deauthReason = (deauthReason__); + +#define CsrWifiSmeMediaStatusIndSendTo(dst__, src__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) \ + { \ + CsrWifiSmeMediaStatusInd *msg__; \ + CsrWifiSmeMediaStatusIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMediaStatusIndSend(dst__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) \ + CsrWifiSmeMediaStatusIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the MibConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeMibConfigGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeMibConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_GET_REQ, dst__, src__); + +#define CsrWifiSmeMibConfigGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeMibConfigGetReq *msg__; \ + CsrWifiSmeMibConfigGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibConfigGetReqSend(src__) \ + CsrWifiSmeMibConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + mibConfig - Reports various IEEE 802.11 attributes as currently configured + +*******************************************************************************/ +#define CsrWifiSmeMibConfigGetCfmCreate(msg__, dst__, src__, status__, mibConfig__) \ + msg__ = (CsrWifiSmeMibConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->mibConfig = (mibConfig__); + +#define CsrWifiSmeMibConfigGetCfmSendTo(dst__, src__, status__, mibConfig__) \ + { \ + CsrWifiSmeMibConfigGetCfm *msg__; \ + CsrWifiSmeMibConfigGetCfmCreate(msg__, dst__, src__, status__, mibConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibConfigGetCfmSend(dst__, status__, mibConfig__) \ + CsrWifiSmeMibConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, mibConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the MibConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + mibConfig - Conveys the desired value of various IEEE 802.11 attributes as + currently configured + +*******************************************************************************/ +#define CsrWifiSmeMibConfigSetReqCreate(msg__, dst__, src__, mibConfig__) \ + msg__ = (CsrWifiSmeMibConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_SET_REQ, dst__, src__); \ + msg__->mibConfig = (mibConfig__); + +#define CsrWifiSmeMibConfigSetReqSendTo(dst__, src__, mibConfig__) \ + { \ + CsrWifiSmeMibConfigSetReq *msg__; \ + CsrWifiSmeMibConfigSetReqCreate(msg__, dst__, src__, mibConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibConfigSetReqSend(src__, mibConfig__) \ + CsrWifiSmeMibConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeMibConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeMibConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeMibConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeMibConfigSetCfm *msg__; \ + CsrWifiSmeMibConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibConfigSetCfmSend(dst__, status__) \ + CsrWifiSmeMibConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetCfmSend + + DESCRIPTION + The SME calls this primitive to return the requested MIB variable values. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to the VarBind or VarBindList containing the + names and values of the MIB variables requested + +*******************************************************************************/ +#define CsrWifiSmeMibGetCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__) \ + msg__ = (CsrWifiSmeMibGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->mibAttributeLength = (mibAttributeLength__); \ + msg__->mibAttribute = (mibAttribute__); + +#define CsrWifiSmeMibGetCfmSendTo(dst__, src__, status__, mibAttributeLength__, mibAttribute__) \ + { \ + CsrWifiSmeMibGetCfm *msg__; \ + CsrWifiSmeMibGetCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibGetCfmSend(dst__, status__, mibAttributeLength__, mibAttribute__) \ + CsrWifiSmeMibGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, mibAttributeLength__, mibAttribute__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetNextReqSend + + DESCRIPTION + To read a sequence of MIB parameters, for example a table, call this + primitive to find the name of the next MIB variable + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to a VarBind or VarBindList containing the + name(s) of the MIB variable(s) to search from. + +*******************************************************************************/ +#define CsrWifiSmeMibGetNextReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__) \ + msg__ = (CsrWifiSmeMibGetNextReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetNextReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_NEXT_REQ, dst__, src__); \ + msg__->mibAttributeLength = (mibAttributeLength__); \ + msg__->mibAttribute = (mibAttribute__); + +#define CsrWifiSmeMibGetNextReqSendTo(dst__, src__, mibAttributeLength__, mibAttribute__) \ + { \ + CsrWifiSmeMibGetNextReq *msg__; \ + CsrWifiSmeMibGetNextReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibGetNextReqSend(src__, mibAttributeLength__, mibAttribute__) \ + CsrWifiSmeMibGetNextReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibAttributeLength__, mibAttribute__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetNextCfmSend + + DESCRIPTION + The SME calls this primitive to return the requested MIB name(s). + The wireless manager application can then read the value of the MIB + variable using CSR_WIFI_SME_MIB_GET_REQ, using the names provided. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to a VarBind or VarBindList containing the + name(s) of the MIB variable(s) lexicographically + following the name(s) given in the request + +*******************************************************************************/ +#define CsrWifiSmeMibGetNextCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__) \ + msg__ = (CsrWifiSmeMibGetNextCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetNextCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_NEXT_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->mibAttributeLength = (mibAttributeLength__); \ + msg__->mibAttribute = (mibAttribute__); + +#define CsrWifiSmeMibGetNextCfmSendTo(dst__, src__, status__, mibAttributeLength__, mibAttribute__) \ + { \ + CsrWifiSmeMibGetNextCfm *msg__; \ + CsrWifiSmeMibGetNextCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibGetNextCfmSend(dst__, status__, mibAttributeLength__, mibAttribute__) \ + CsrWifiSmeMibGetNextCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, mibAttributeLength__, mibAttribute__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetReqSend + + DESCRIPTION + The wireless manager application calls this primitive to retrieve one or + more MIB variables. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to the VarBind or VarBindList containing the + names of the MIB variables to be retrieved + +*******************************************************************************/ +#define CsrWifiSmeMibGetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__) \ + msg__ = (CsrWifiSmeMibGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_REQ, dst__, src__); \ + msg__->mibAttributeLength = (mibAttributeLength__); \ + msg__->mibAttribute = (mibAttribute__); + +#define CsrWifiSmeMibGetReqSendTo(dst__, src__, mibAttributeLength__, mibAttribute__) \ + { \ + CsrWifiSmeMibGetReq *msg__; \ + CsrWifiSmeMibGetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibGetReqSend(src__, mibAttributeLength__, mibAttribute__) \ + CsrWifiSmeMibGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibAttributeLength__, mibAttribute__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibSetReqSend + + DESCRIPTION + The SME provides raw access to the MIB on the chip, which may be used by + some configuration or diagnostic utilities, but is not normally needed by + the wireless manager application. + The MIB access functions use BER encoded names (OID) of the MIB + parameters and BER encoded values, as described in the chip Host + Interface Protocol Specification. + The MIB parameters are described in 'Wi-Fi 5.0.0 Management Information + Base Reference Guide'. + The wireless manager application calls this primitive to set one or more + MIB variables + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to the VarBind or VarBindList containing the + names and values of the MIB variables to set + +*******************************************************************************/ +#define CsrWifiSmeMibSetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__) \ + msg__ = (CsrWifiSmeMibSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_SET_REQ, dst__, src__); \ + msg__->mibAttributeLength = (mibAttributeLength__); \ + msg__->mibAttribute = (mibAttribute__); + +#define CsrWifiSmeMibSetReqSendTo(dst__, src__, mibAttributeLength__, mibAttribute__) \ + { \ + CsrWifiSmeMibSetReq *msg__; \ + CsrWifiSmeMibSetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibSetReqSend(src__, mibAttributeLength__, mibAttribute__) \ + CsrWifiSmeMibSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibAttributeLength__, mibAttribute__) + +/******************************************************************************* + + NAME + CsrWifiSmeMibSetCfmSend + + DESCRIPTION + The SME calls the primitive to report the result of the set primitive. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeMibSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeMibSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeMibSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeMibSetCfm *msg__; \ + CsrWifiSmeMibSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMibSetCfmSend(dst__, status__) \ + CsrWifiSmeMibSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeMicFailureIndSend + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it whenever the chip firmware reports a MIC failure. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + secondFailure - TRUE if this indication is for a second failure in 60 + seconds + count - The number of MIC failure events since the connection was + established + address - MAC address of the transmitter that caused the MIC failure + keyType - Type of key for which the failure occurred + +*******************************************************************************/ +#define CsrWifiSmeMicFailureIndCreate(msg__, dst__, src__, interfaceTag__, secondFailure__, count__, address__, keyType__) \ + msg__ = (CsrWifiSmeMicFailureInd *) CsrPmemAlloc(sizeof(CsrWifiSmeMicFailureInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIC_FAILURE_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->secondFailure = (secondFailure__); \ + msg__->count = (count__); \ + msg__->address = (address__); \ + msg__->keyType = (keyType__); + +#define CsrWifiSmeMicFailureIndSendTo(dst__, src__, interfaceTag__, secondFailure__, count__, address__, keyType__) \ + { \ + CsrWifiSmeMicFailureInd *msg__; \ + CsrWifiSmeMicFailureIndCreate(msg__, dst__, src__, interfaceTag__, secondFailure__, count__, address__, keyType__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMicFailureIndSend(dst__, interfaceTag__, secondFailure__, count__, address__, keyType__) \ + CsrWifiSmeMicFailureIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, secondFailure__, count__, address__, keyType__) + +/******************************************************************************* + + NAME + CsrWifiSmeMulticastAddressReqSend + + DESCRIPTION + The wireless manager application calls this primitive to specify the + multicast addresses which the chip should recognise. The interface allows + the wireless manager application to query, add, remove and flush the + multicast addresses for the network interface according to the specified + action. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter + instructs the driver to modify or provide the list of + MAC addresses. + setAddressesCount - Number of MAC addresses sent with the primitive + setAddresses - Pointer to the list of MAC Addresses sent with the + primitive, set to NULL if none is sent. + +*******************************************************************************/ +#define CsrWifiSmeMulticastAddressReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \ + msg__ = (CsrWifiSmeMulticastAddressReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMulticastAddressReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MULTICAST_ADDRESS_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->action = (action__); \ + msg__->setAddressesCount = (setAddressesCount__); \ + msg__->setAddresses = (setAddresses__); + +#define CsrWifiSmeMulticastAddressReqSendTo(dst__, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \ + { \ + CsrWifiSmeMulticastAddressReq *msg__; \ + CsrWifiSmeMulticastAddressReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMulticastAddressReqSend(src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \ + CsrWifiSmeMulticastAddressReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) + +/******************************************************************************* + + NAME + CsrWifiSmeMulticastAddressCfmSend + + DESCRIPTION + The SME will call this primitive when the operation is complete. For a + GET action, this primitive reports the current list of MAC addresses. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + getAddressesCount - This parameter is only relevant if action is + CSR_WIFI_SME_LIST_ACTION_GET: + number of MAC addresses sent with the primitive + getAddresses - Pointer to the list of MAC Addresses sent with the + primitive, set to NULL if none is sent. + +*******************************************************************************/ +#define CsrWifiSmeMulticastAddressCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) \ + msg__ = (CsrWifiSmeMulticastAddressCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMulticastAddressCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MULTICAST_ADDRESS_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->action = (action__); \ + msg__->getAddressesCount = (getAddressesCount__); \ + msg__->getAddresses = (getAddresses__); + +#define CsrWifiSmeMulticastAddressCfmSendTo(dst__, src__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) \ + { \ + CsrWifiSmeMulticastAddressCfm *msg__; \ + CsrWifiSmeMulticastAddressCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeMulticastAddressCfmSend(dst__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) \ + CsrWifiSmeMulticastAddressCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) + +/******************************************************************************* + + NAME + CsrWifiSmePacketFilterSetReqSend + + DESCRIPTION + The wireless manager application should call this primitive to enable or + disable filtering of broadcast packets: uninteresting broadcast packets + will be dropped by the Wi-Fi chip, instead of passing them up to the + host. + This has the advantage of saving power in the host application processor + as it removes the need to process unwanted packets. + All broadcast packets are filtered according to the filter and the filter + mode provided, except ARP packets, which are filtered using + arpFilterAddress. + Filters are not cumulative: only the parameters specified in the most + recent successful request are significant. + For more information, see 'UniFi Firmware API Specification'. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + filterLength - Length of the filter in bytes. + filterLength=0 disables the filter previously set + filter - Points to the first byte of the filter provided, if any. + This shall include zero or more instance of the + information elements of one of these types + * Traffic Classification (TCLAS) elements + * WMM-SA TCLAS elements + mode - Specifies whether the filter selects or excludes packets + matching the filter + arpFilterAddress - IPv4 address to be used for filtering the ARP packets. + * If the specified address is the IPv4 broadcast address + (255.255.255.255), all ARP packets are reported to the + host, + * If the specified address is NOT the IPv4 broadcast + address, only ARP packets with the specified address in + the Source or Target Protocol Address fields are reported + to the host + +*******************************************************************************/ +#define CsrWifiSmePacketFilterSetReqCreate(msg__, dst__, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) \ + msg__ = (CsrWifiSmePacketFilterSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmePacketFilterSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PACKET_FILTER_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->filterLength = (filterLength__); \ + msg__->filter = (filter__); \ + msg__->mode = (mode__); \ + msg__->arpFilterAddress = (arpFilterAddress__); + +#define CsrWifiSmePacketFilterSetReqSendTo(dst__, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) \ + { \ + CsrWifiSmePacketFilterSetReq *msg__; \ + CsrWifiSmePacketFilterSetReqCreate(msg__, dst__, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePacketFilterSetReqSend(src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) \ + CsrWifiSmePacketFilterSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) + +/******************************************************************************* + + NAME + CsrWifiSmePacketFilterSetCfmSend + + DESCRIPTION + The SME calls the primitive to report the result of the set primitive. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmePacketFilterSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmePacketFilterSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePacketFilterSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PACKET_FILTER_SET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmePacketFilterSetCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmePacketFilterSetCfm *msg__; \ + CsrWifiSmePacketFilterSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePacketFilterSetCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmePacketFilterSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmePermanentMacAddressGetReqSend + + DESCRIPTION + This primitive retrieves the MAC address stored in EEPROM + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmePermanentMacAddressGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmePermanentMacAddressGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmePermanentMacAddressGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_REQ, dst__, src__); + +#define CsrWifiSmePermanentMacAddressGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmePermanentMacAddressGetReq *msg__; \ + CsrWifiSmePermanentMacAddressGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePermanentMacAddressGetReqSend(src__) \ + CsrWifiSmePermanentMacAddressGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmePermanentMacAddressGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + permanentMacAddress - MAC address stored in the EEPROM + +*******************************************************************************/ +#define CsrWifiSmePermanentMacAddressGetCfmCreate(msg__, dst__, src__, status__, permanentMacAddress__) \ + msg__ = (CsrWifiSmePermanentMacAddressGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePermanentMacAddressGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->permanentMacAddress = (permanentMacAddress__); + +#define CsrWifiSmePermanentMacAddressGetCfmSendTo(dst__, src__, status__, permanentMacAddress__) \ + { \ + CsrWifiSmePermanentMacAddressGetCfm *msg__; \ + CsrWifiSmePermanentMacAddressGetCfmCreate(msg__, dst__, src__, status__, permanentMacAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePermanentMacAddressGetCfmSend(dst__, status__, permanentMacAddress__) \ + CsrWifiSmePermanentMacAddressGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, permanentMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiSmePmkidCandidateListIndSend + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it when a new network supporting preauthentication and/or PMK + caching is seen. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an + interface + pmkidCandidatesCount - Number of PMKID candidates provided + pmkidCandidates - Points to the first PMKID candidate + +*******************************************************************************/ +#define CsrWifiSmePmkidCandidateListIndCreate(msg__, dst__, src__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) \ + msg__ = (CsrWifiSmePmkidCandidateListInd *) CsrPmemAlloc(sizeof(CsrWifiSmePmkidCandidateListInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->pmkidCandidatesCount = (pmkidCandidatesCount__); \ + msg__->pmkidCandidates = (pmkidCandidates__); + +#define CsrWifiSmePmkidCandidateListIndSendTo(dst__, src__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) \ + { \ + CsrWifiSmePmkidCandidateListInd *msg__; \ + CsrWifiSmePmkidCandidateListIndCreate(msg__, dst__, src__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePmkidCandidateListIndSend(dst__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) \ + CsrWifiSmePmkidCandidateListIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) + +/******************************************************************************* + + NAME + CsrWifiSmePmkidReqSend + + DESCRIPTION + The wireless manager application calls this primitive to request an + operation on the SME PMKID list. + The action argument specifies the operation to perform. + When the connection is complete, the wireless manager application may + then send and receive EAPOL packets to complete WPA or WPA2 + authentication if appropriate. + The wireless manager application can then pass the resulting encryption + keys using this primitive. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter instructs + the driver to modify or provide the list of PMKIDs. + setPmkidsCount - Number of PMKIDs sent with the primitive + setPmkids - Pointer to the list of PMKIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +#define CsrWifiSmePmkidReqCreate(msg__, dst__, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) \ + msg__ = (CsrWifiSmePmkidReq *) CsrPmemAlloc(sizeof(CsrWifiSmePmkidReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PMKID_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->action = (action__); \ + msg__->setPmkidsCount = (setPmkidsCount__); \ + msg__->setPmkids = (setPmkids__); + +#define CsrWifiSmePmkidReqSendTo(dst__, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) \ + { \ + CsrWifiSmePmkidReq *msg__; \ + CsrWifiSmePmkidReqCreate(msg__, dst__, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePmkidReqSend(src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) \ + CsrWifiSmePmkidReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) + +/******************************************************************************* + + NAME + CsrWifiSmePmkidCfmSend + + DESCRIPTION + The SME will call this primitive when the operation is complete. For a + GET action, this primitive reports the current list of PMKIDs + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + getPmkidsCount - This parameter is only relevant if action is + CSR_WIFI_SME_LIST_ACTION_GET: + number of PMKIDs sent with the primitive + getPmkids - Pointer to the list of PMKIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +#define CsrWifiSmePmkidCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) \ + msg__ = (CsrWifiSmePmkidCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePmkidCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PMKID_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->action = (action__); \ + msg__->getPmkidsCount = (getPmkidsCount__); \ + msg__->getPmkids = (getPmkids__); + +#define CsrWifiSmePmkidCfmSendTo(dst__, src__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) \ + { \ + CsrWifiSmePmkidCfm *msg__; \ + CsrWifiSmePmkidCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePmkidCfmSend(dst__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) \ + CsrWifiSmePmkidCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the PowerConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmePowerConfigGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmePowerConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmePowerConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_GET_REQ, dst__, src__); + +#define CsrWifiSmePowerConfigGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmePowerConfigGetReq *msg__; \ + CsrWifiSmePowerConfigGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePowerConfigGetReqSend(src__) \ + CsrWifiSmePowerConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + powerConfig - Returns the current parameters for the power configuration of + the firmware + +*******************************************************************************/ +#define CsrWifiSmePowerConfigGetCfmCreate(msg__, dst__, src__, status__, powerConfig__) \ + msg__ = (CsrWifiSmePowerConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePowerConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->powerConfig = (powerConfig__); + +#define CsrWifiSmePowerConfigGetCfmSendTo(dst__, src__, status__, powerConfig__) \ + { \ + CsrWifiSmePowerConfigGetCfm *msg__; \ + CsrWifiSmePowerConfigGetCfmCreate(msg__, dst__, src__, status__, powerConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePowerConfigGetCfmSend(dst__, status__, powerConfig__) \ + CsrWifiSmePowerConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, powerConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the PowerConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + powerConfig - Power saving configuration + +*******************************************************************************/ +#define CsrWifiSmePowerConfigSetReqCreate(msg__, dst__, src__, powerConfig__) \ + msg__ = (CsrWifiSmePowerConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmePowerConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_SET_REQ, dst__, src__); \ + msg__->powerConfig = (powerConfig__); + +#define CsrWifiSmePowerConfigSetReqSendTo(dst__, src__, powerConfig__) \ + { \ + CsrWifiSmePowerConfigSetReq *msg__; \ + CsrWifiSmePowerConfigSetReqCreate(msg__, dst__, src__, powerConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePowerConfigSetReqSend(src__, powerConfig__) \ + CsrWifiSmePowerConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, powerConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmePowerConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmePowerConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePowerConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmePowerConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmePowerConfigSetCfm *msg__; \ + CsrWifiSmePowerConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmePowerConfigSetCfmSend(dst__, status__) \ + CsrWifiSmePowerConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeRegulatoryDomainInfoGetReqSend + + DESCRIPTION + This primitive gets the value of the RegulatoryDomainInfo parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeRegulatoryDomainInfoGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeRegulatoryDomainInfoGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeRegulatoryDomainInfoGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_REQ, dst__, src__); + +#define CsrWifiSmeRegulatoryDomainInfoGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeRegulatoryDomainInfoGetReq *msg__; \ + CsrWifiSmeRegulatoryDomainInfoGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRegulatoryDomainInfoGetReqSend(src__) \ + CsrWifiSmeRegulatoryDomainInfoGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeRegulatoryDomainInfoGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + regDomInfo - Reports information and state related to regulatory domain + operation. + +*******************************************************************************/ +#define CsrWifiSmeRegulatoryDomainInfoGetCfmCreate(msg__, dst__, src__, status__, regDomInfo__) \ + msg__ = (CsrWifiSmeRegulatoryDomainInfoGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeRegulatoryDomainInfoGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->regDomInfo = (regDomInfo__); + +#define CsrWifiSmeRegulatoryDomainInfoGetCfmSendTo(dst__, src__, status__, regDomInfo__) \ + { \ + CsrWifiSmeRegulatoryDomainInfoGetCfm *msg__; \ + CsrWifiSmeRegulatoryDomainInfoGetCfmCreate(msg__, dst__, src__, status__, regDomInfo__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRegulatoryDomainInfoGetCfmSend(dst__, status__, regDomInfo__) \ + CsrWifiSmeRegulatoryDomainInfoGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, regDomInfo__) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamCompleteIndSend + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it completes an attempt to roam to an AP. If the roam + attempt was successful, status will be set to CSR_WIFI_SME_SUCCESS, + otherwise it shall be set to the appropriate error code. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the roaming procedure + +*******************************************************************************/ +#define CsrWifiSmeRoamCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeRoamCompleteInd *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamCompleteInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAM_COMPLETE_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeRoamCompleteIndSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeRoamCompleteInd *msg__; \ + CsrWifiSmeRoamCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRoamCompleteIndSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeRoamCompleteIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamStartIndSend + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it begins an attempt to roam to an AP. + If the wireless manager application connect request specified the SSID + and the BSSID was set to the broadcast address (0xFF 0xFF 0xFF 0xFF 0xFF + 0xFF), the SME monitors the signal quality and maintains a list of + candidates to roam to. When the signal quality of the current connection + falls below a threshold, and there is a candidate with better quality, + the SME will attempt to the candidate AP. + If the roaming procedure succeeds, the SME will also issue a Media + Connect indication to inform the wireless manager application of the + change. + NOTE: to prevent the SME from initiating roaming the WMA must specify the + BSSID in the connection request; this forces the SME to connect only to + that AP. + The wireless manager application can obtain statistics for roaming + purposes using CSR_WIFI_SME_CONNECTION_QUALITY_IND and + CSR_WIFI_SME_CONNECTION_STATS_GET_REQ. + When the wireless manager application wishes to roam to another AP, it + must issue a connection request specifying the BSSID of the desired AP. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + roamReason - Indicates the reason for starting the roaming procedure + reason80211 - Indicates the reason for deauthentication or disassociation + +*******************************************************************************/ +#define CsrWifiSmeRoamStartIndCreate(msg__, dst__, src__, interfaceTag__, roamReason__, reason80211__) \ + msg__ = (CsrWifiSmeRoamStartInd *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamStartInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAM_START_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->roamReason = (roamReason__); \ + msg__->reason80211 = (reason80211__); + +#define CsrWifiSmeRoamStartIndSendTo(dst__, src__, interfaceTag__, roamReason__, reason80211__) \ + { \ + CsrWifiSmeRoamStartInd *msg__; \ + CsrWifiSmeRoamStartIndCreate(msg__, dst__, src__, interfaceTag__, roamReason__, reason80211__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRoamStartIndSend(dst__, interfaceTag__, roamReason__, reason80211__) \ + CsrWifiSmeRoamStartIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, roamReason__, reason80211__) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the RoamingConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeRoamingConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeRoamingConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeRoamingConfigGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeRoamingConfigGetReq *msg__; \ + CsrWifiSmeRoamingConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRoamingConfigGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeRoamingConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + roamingConfig - Reports the roaming behaviour of the driver and firmware + +*******************************************************************************/ +#define CsrWifiSmeRoamingConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, roamingConfig__) \ + msg__ = (CsrWifiSmeRoamingConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->roamingConfig = (roamingConfig__); + +#define CsrWifiSmeRoamingConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, roamingConfig__) \ + { \ + CsrWifiSmeRoamingConfigGetCfm *msg__; \ + CsrWifiSmeRoamingConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, roamingConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRoamingConfigGetCfmSend(dst__, interfaceTag__, status__, roamingConfig__) \ + CsrWifiSmeRoamingConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, roamingConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the RoamingConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + roamingConfig - Desired roaming behaviour values + +*******************************************************************************/ +#define CsrWifiSmeRoamingConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, roamingConfig__) \ + msg__ = (CsrWifiSmeRoamingConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->roamingConfig = (roamingConfig__); + +#define CsrWifiSmeRoamingConfigSetReqSendTo(dst__, src__, interfaceTag__, roamingConfig__) \ + { \ + CsrWifiSmeRoamingConfigSetReq *msg__; \ + CsrWifiSmeRoamingConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, roamingConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRoamingConfigSetReqSend(src__, interfaceTag__, roamingConfig__) \ + CsrWifiSmeRoamingConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, roamingConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigSetCfmSend + + DESCRIPTION + This primitive sets the value of the RoamingConfig parameter. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeRoamingConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeRoamingConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_SET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeRoamingConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeRoamingConfigSetCfm *msg__; \ + CsrWifiSmeRoamingConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeRoamingConfigSetCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeRoamingConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the ScanConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeScanConfigGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeScanConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_GET_REQ, dst__, src__); + +#define CsrWifiSmeScanConfigGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeScanConfigGetReq *msg__; \ + CsrWifiSmeScanConfigGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanConfigGetReqSend(src__) \ + CsrWifiSmeScanConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + scanConfig - Returns the current parameters for the autonomous scanning + behaviour of the firmware + +*******************************************************************************/ +#define CsrWifiSmeScanConfigGetCfmCreate(msg__, dst__, src__, status__, scanConfig__) \ + msg__ = (CsrWifiSmeScanConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->scanConfig = (scanConfig__); + +#define CsrWifiSmeScanConfigGetCfmSendTo(dst__, src__, status__, scanConfig__) \ + { \ + CsrWifiSmeScanConfigGetCfm *msg__; \ + CsrWifiSmeScanConfigGetCfmCreate(msg__, dst__, src__, status__, scanConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanConfigGetCfmSend(dst__, status__, scanConfig__) \ + CsrWifiSmeScanConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, scanConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the ScanConfig parameter. + The SME normally configures the firmware to perform autonomous scanning + without involving the host. + The firmware passes beacon / probe response or indicates loss of beacon + on certain changes of state, for example: + * A new AP is seen for the first time + * An AP is no longer visible + * The signal strength of an AP changes by more than a certain amount, as + configured by the thresholds in the scanConfig parameter + In addition to the autonomous scan, the wireless manager application may + request a scan at any time using CSR_WIFI_SME_SCAN_FULL_REQ. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + scanConfig - Reports the configuration for the autonomous scanning behaviour + of the firmware + +*******************************************************************************/ +#define CsrWifiSmeScanConfigSetReqCreate(msg__, dst__, src__, scanConfig__) \ + msg__ = (CsrWifiSmeScanConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_SET_REQ, dst__, src__); \ + msg__->scanConfig = (scanConfig__); + +#define CsrWifiSmeScanConfigSetReqSendTo(dst__, src__, scanConfig__) \ + { \ + CsrWifiSmeScanConfigSetReq *msg__; \ + CsrWifiSmeScanConfigSetReqCreate(msg__, dst__, src__, scanConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanConfigSetReqSend(src__, scanConfig__) \ + CsrWifiSmeScanConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, scanConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeScanConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeScanConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeScanConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeScanConfigSetCfm *msg__; \ + CsrWifiSmeScanConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanConfigSetCfmSend(dst__, status__) \ + CsrWifiSmeScanConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanFullReqSend + + DESCRIPTION + The wireless manager application should call this primitive to request a + full scan. + Channels are scanned actively or passively according to the requirement + set by regulatory domain. + If the SME receives this primitive while a full scan is going on, the new + request is buffered and it will be served after the current full scan is + completed. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + ssidCount - Number of SSIDs provided. + If it is 0, the SME will attempt to detect any network + ssid - Points to the first SSID provided, if any. + bssid - BSS identifier. + If it is equal to FF-FF-FF-FF-FF, the SME will listen for + messages from any BSS. + If it is different from FF-FF-FF-FF-FF and any SSID is + provided, one SSID must match the network of the BSS. + forceScan - Forces the scan even if the SME is in a state which would + normally prevent it (e.g. autonomous scan is running). + bssType - Type of BSS to scan for + scanType - Type of scan to perform + channelListCount - Number of channels provided. + If it is 0, the SME will initiate a scan of all the + supported channels that are permitted by the current + regulatory domain. + channelList - Points to the first channel , or NULL if channelListCount + is zero. + probeIeLength - Length of the information element in bytes to be sent + with the probe message. + probeIe - Points to the first byte of the information element to be + sent with the probe message. + +*******************************************************************************/ +#define CsrWifiSmeScanFullReqCreate(msg__, dst__, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) \ + msg__ = (CsrWifiSmeScanFullReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanFullReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_FULL_REQ, dst__, src__); \ + msg__->ssidCount = (ssidCount__); \ + msg__->ssid = (ssid__); \ + msg__->bssid = (bssid__); \ + msg__->forceScan = (forceScan__); \ + msg__->bssType = (bssType__); \ + msg__->scanType = (scanType__); \ + msg__->channelListCount = (channelListCount__); \ + msg__->channelList = (channelList__); \ + msg__->probeIeLength = (probeIeLength__); \ + msg__->probeIe = (probeIe__); + +#define CsrWifiSmeScanFullReqSendTo(dst__, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) \ + { \ + CsrWifiSmeScanFullReq *msg__; \ + CsrWifiSmeScanFullReqCreate(msg__, dst__, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanFullReqSend(src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) \ + CsrWifiSmeScanFullReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanFullCfmSend + + DESCRIPTION + The SME calls this primitive when the results from the scan are + available. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeScanFullCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeScanFullCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanFullCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_FULL_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeScanFullCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeScanFullCfm *msg__; \ + CsrWifiSmeScanFullCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanFullCfmSend(dst__, status__) \ + CsrWifiSmeScanFullCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultIndSend + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it whenever a scan indication is received from the firmware. + + PARAMETERS + queue - Destination Task Queue + result - Points to a buffer containing a scan result. + +*******************************************************************************/ +#define CsrWifiSmeScanResultIndCreate(msg__, dst__, src__, result__) \ + msg__ = (CsrWifiSmeScanResultInd *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULT_IND, dst__, src__); \ + msg__->result = (result__); + +#define CsrWifiSmeScanResultIndSendTo(dst__, src__, result__) \ + { \ + CsrWifiSmeScanResultInd *msg__; \ + CsrWifiSmeScanResultIndCreate(msg__, dst__, src__, result__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanResultIndSend(dst__, result__) \ + CsrWifiSmeScanResultIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, result__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsFlushReqSend + + DESCRIPTION + The Wireless Manager calls this primitive to ask the SME to delete all + scan results from its cache, except for the scan result of any currently + connected network. + As scan results are received by the SME from the firmware, they are + cached in the SME memory. + Any time the Wireless Manager requests scan results, they are returned + from the SME internal cache. + For some applications it may be desirable to clear this cache prior to + requesting that a scan be performed; this will ensure that the cache then + only contains the networks detected in the most recent scan. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeScanResultsFlushReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeScanResultsFlushReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultsFlushReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_FLUSH_REQ, dst__, src__); + +#define CsrWifiSmeScanResultsFlushReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeScanResultsFlushReq *msg__; \ + CsrWifiSmeScanResultsFlushReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanResultsFlushReqSend(src__) \ + CsrWifiSmeScanResultsFlushReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsFlushCfmSend + + DESCRIPTION + The SME will call this primitive when the cache has been cleared. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeScanResultsFlushCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeScanResultsFlushCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultsFlushCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_FLUSH_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeScanResultsFlushCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeScanResultsFlushCfm *msg__; \ + CsrWifiSmeScanResultsFlushCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanResultsFlushCfmSend(dst__, status__) \ + CsrWifiSmeScanResultsFlushCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsGetReqSend + + DESCRIPTION + The wireless manager application calls this primitive to retrieve the + current set of scan results, either after receiving a successful + CSR_WIFI_SME_SCAN_FULL_CFM, or to get autonomous scan results. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeScanResultsGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeScanResultsGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultsGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_GET_REQ, dst__, src__); + +#define CsrWifiSmeScanResultsGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeScanResultsGetReq *msg__; \ + CsrWifiSmeScanResultsGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanResultsGetReqSend(src__) \ + CsrWifiSmeScanResultsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsGetCfmSend + + DESCRIPTION + The SME sends this primitive to provide the current set of scan results. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + scanResultsCount - Number of scan results + scanResults - Points to a buffer containing an array of + CsrWifiSmeScanResult structures. + +*******************************************************************************/ +#define CsrWifiSmeScanResultsGetCfmCreate(msg__, dst__, src__, status__, scanResultsCount__, scanResults__) \ + msg__ = (CsrWifiSmeScanResultsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultsGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->scanResultsCount = (scanResultsCount__); \ + msg__->scanResults = (scanResults__); + +#define CsrWifiSmeScanResultsGetCfmSendTo(dst__, src__, status__, scanResultsCount__, scanResults__) \ + { \ + CsrWifiSmeScanResultsGetCfm *msg__; \ + CsrWifiSmeScanResultsGetCfmCreate(msg__, dst__, src__, status__, scanResultsCount__, scanResults__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeScanResultsGetCfmSend(dst__, status__, scanResultsCount__, scanResults__) \ + CsrWifiSmeScanResultsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, scanResultsCount__, scanResults__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the Sme common parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeSmeCommonConfigGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeSmeCommonConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeCommonConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_GET_REQ, dst__, src__); + +#define CsrWifiSmeSmeCommonConfigGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeSmeCommonConfigGetReq *msg__; \ + CsrWifiSmeSmeCommonConfigGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeCommonConfigGetReqSend(src__) \ + CsrWifiSmeSmeCommonConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + deviceConfig - Configuration options in the SME + +*******************************************************************************/ +#define CsrWifiSmeSmeCommonConfigGetCfmCreate(msg__, dst__, src__, status__, deviceConfig__) \ + msg__ = (CsrWifiSmeSmeCommonConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeCommonConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->deviceConfig = (deviceConfig__); + +#define CsrWifiSmeSmeCommonConfigGetCfmSendTo(dst__, src__, status__, deviceConfig__) \ + { \ + CsrWifiSmeSmeCommonConfigGetCfm *msg__; \ + CsrWifiSmeSmeCommonConfigGetCfmCreate(msg__, dst__, src__, status__, deviceConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeCommonConfigGetCfmSend(dst__, status__, deviceConfig__) \ + CsrWifiSmeSmeCommonConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, deviceConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the Sme common. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + deviceConfig - Configuration options in the SME + +*******************************************************************************/ +#define CsrWifiSmeSmeCommonConfigSetReqCreate(msg__, dst__, src__, deviceConfig__) \ + msg__ = (CsrWifiSmeSmeCommonConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeCommonConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, dst__, src__); \ + msg__->deviceConfig = (deviceConfig__); + +#define CsrWifiSmeSmeCommonConfigSetReqSendTo(dst__, src__, deviceConfig__) \ + { \ + CsrWifiSmeSmeCommonConfigSetReq *msg__; \ + CsrWifiSmeSmeCommonConfigSetReqCreate(msg__, dst__, src__, deviceConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeCommonConfigSetReqSend(src__, deviceConfig__) \ + CsrWifiSmeSmeCommonConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, deviceConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigSetCfmSend + + DESCRIPTION + Reports the result of the request + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeSmeCommonConfigSetCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeSmeCommonConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeCommonConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_SET_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeSmeCommonConfigSetCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeSmeCommonConfigSetCfm *msg__; \ + CsrWifiSmeSmeCommonConfigSetCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeCommonConfigSetCfmSend(dst__, status__) \ + CsrWifiSmeSmeCommonConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigGetReqSend + + DESCRIPTION + This primitive gets the value of the SmeStaConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +#define CsrWifiSmeSmeStaConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeSmeStaConfigGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeSmeStaConfigGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeSmeStaConfigGetReq *msg__; \ + CsrWifiSmeSmeStaConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeStaConfigGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeSmeStaConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + smeConfig - Current SME Station Parameters + +*******************************************************************************/ +#define CsrWifiSmeSmeStaConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, smeConfig__) \ + msg__ = (CsrWifiSmeSmeStaConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->smeConfig = (smeConfig__); + +#define CsrWifiSmeSmeStaConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, smeConfig__) \ + { \ + CsrWifiSmeSmeStaConfigGetCfm *msg__; \ + CsrWifiSmeSmeStaConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, smeConfig__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeStaConfigGetCfmSend(dst__, interfaceTag__, status__, smeConfig__) \ + CsrWifiSmeSmeStaConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, smeConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigSetReqSend + + DESCRIPTION + This primitive sets the value of the SmeConfig parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + smeConfig - SME Station Parameters to be set + +*******************************************************************************/ +#define CsrWifiSmeSmeStaConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, smeConfig__) \ + msg__ = (CsrWifiSmeSmeStaConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_SET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->smeConfig = (smeConfig__); + +#define CsrWifiSmeSmeStaConfigSetReqSendTo(dst__, src__, interfaceTag__, smeConfig__) \ + { \ + CsrWifiSmeSmeStaConfigSetReq *msg__; \ + CsrWifiSmeSmeStaConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, smeConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeStaConfigSetReqSend(src__, interfaceTag__, smeConfig__) \ + CsrWifiSmeSmeStaConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, smeConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigSetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeSmeStaConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \ + msg__ = (CsrWifiSmeSmeStaConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_SET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); + +#define CsrWifiSmeSmeStaConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \ + { \ + CsrWifiSmeSmeStaConfigSetCfm *msg__; \ + CsrWifiSmeSmeStaConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSmeStaConfigSetCfmSend(dst__, interfaceTag__, status__) \ + CsrWifiSmeSmeStaConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeStationMacAddressGetReqSend + + DESCRIPTION + This primitives is used to retrieve the current MAC address used by the + station. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeStationMacAddressGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeStationMacAddressGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeStationMacAddressGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_REQ, dst__, src__); + +#define CsrWifiSmeStationMacAddressGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeStationMacAddressGetReq *msg__; \ + CsrWifiSmeStationMacAddressGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeStationMacAddressGetReqSend(src__) \ + CsrWifiSmeStationMacAddressGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeStationMacAddressGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + stationMacAddress - Current MAC address of the station. + +*******************************************************************************/ +#define CsrWifiSmeStationMacAddressGetCfmCreate(msg__, dst__, src__, status__, stationMacAddress__) \ + msg__ = (CsrWifiSmeStationMacAddressGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeStationMacAddressGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + CsrMemCpy(msg__->stationMacAddress, (stationMacAddress__), sizeof(CsrWifiMacAddress) * 2); + +#define CsrWifiSmeStationMacAddressGetCfmSendTo(dst__, src__, status__, stationMacAddress__) \ + { \ + CsrWifiSmeStationMacAddressGetCfm *msg__; \ + CsrWifiSmeStationMacAddressGetCfmCreate(msg__, dst__, src__, status__, stationMacAddress__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeStationMacAddressGetCfmSend(dst__, status__, stationMacAddress__) \ + CsrWifiSmeStationMacAddressGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, stationMacAddress__) + +/******************************************************************************* + + NAME + CsrWifiSmeTspecReqSend + + DESCRIPTION + The wireless manager application should call this primitive to use the + TSPEC feature. + The chip supports the use of TSPECs and TCLAS for the use of IEEE + 802.11/WMM Quality of Service features. + The API allows the wireless manager application to supply a correctly + formatted TSPEC and TCLAS pair to the driver. + After performing basic validation, the driver negotiates the installation + of the TSPEC with the AP as defined by the 802.11 specification. + The driver retains all TSPEC and TCLAS pairs until they are specifically + removed. + It is not compulsory for a TSPEC to have a TCLAS (NULL is used to + indicate that no TCLAS is supplied), while a TCLASS always require a + TSPEC. + The format of the TSPEC element is specified in 'WMM (including WMM Power + Save) Specification - Version 1.1' and 'ANSI/IEEE Std 802.11-REVmb/D3.0'. + For more information, see 'UniFi Configuring WMM and WMM-PS'. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - Interface Identifier; unique identifier of an interface + action - Specifies the action to be carried out on the list of TSPECs. + CSR_WIFI_SME_LIST_ACTION_FLUSH is not applicable here. + transactionId - Unique Transaction ID for the TSPEC, as assigned by the + driver + strict - If it set to false, allows the SME to perform automatic + TSPEC negotiation + ctrlMask - Additional TSPEC configuration for CCX. + Set mask with values from CsrWifiSmeTspecCtrl. + CURRENTLY NOT SUPPORTED + tspecLength - Length of the TSPEC. + tspec - Points to the first byte of the TSPEC + tclasLength - Length of the TCLAS. + If it is equal to 0, no TCLASS is provided for the TSPEC + tclas - Points to the first byte of the TCLAS, if any. + +*******************************************************************************/ +#define CsrWifiSmeTspecReqCreate(msg__, dst__, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) \ + msg__ = (CsrWifiSmeTspecReq *) CsrPmemAlloc(sizeof(CsrWifiSmeTspecReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_TSPEC_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->action = (action__); \ + msg__->transactionId = (transactionId__); \ + msg__->strict = (strict__); \ + msg__->ctrlMask = (ctrlMask__); \ + msg__->tspecLength = (tspecLength__); \ + msg__->tspec = (tspec__); \ + msg__->tclasLength = (tclasLength__); \ + msg__->tclas = (tclas__); + +#define CsrWifiSmeTspecReqSendTo(dst__, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) \ + { \ + CsrWifiSmeTspecReq *msg__; \ + CsrWifiSmeTspecReqCreate(msg__, dst__, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeTspecReqSend(src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) \ + CsrWifiSmeTspecReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) + +/******************************************************************************* + + NAME + CsrWifiSmeTspecIndSend + + DESCRIPTION + The SME will send this primitive to all the task that have registered to + receive it when a status change in the TSPEC occurs. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + transactionId - Unique Transaction ID for the TSPEC, as assigned by the + driver + tspecResultCode - Specifies the TSPEC operation requested by the peer + station + tspecLength - Length of the TSPEC. + tspec - Points to the first byte of the TSPEC + +*******************************************************************************/ +#define CsrWifiSmeTspecIndCreate(msg__, dst__, src__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \ + msg__ = (CsrWifiSmeTspecInd *) CsrPmemAlloc(sizeof(CsrWifiSmeTspecInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_TSPEC_IND, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->transactionId = (transactionId__); \ + msg__->tspecResultCode = (tspecResultCode__); \ + msg__->tspecLength = (tspecLength__); \ + msg__->tspec = (tspec__); + +#define CsrWifiSmeTspecIndSendTo(dst__, src__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \ + { \ + CsrWifiSmeTspecInd *msg__; \ + CsrWifiSmeTspecIndCreate(msg__, dst__, src__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeTspecIndSend(dst__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \ + CsrWifiSmeTspecIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) + +/******************************************************************************* + + NAME + CsrWifiSmeTspecCfmSend + + DESCRIPTION + The SME calls the primitive to report the result of the TSpec primitive + request. + + PARAMETERS + queue - Destination Task Queue + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + transactionId - Unique Transaction ID for the TSPEC, as assigned by the + driver + tspecResultCode - Specifies the result of the negotiated TSPEC operation + tspecLength - Length of the TSPEC. + tspec - Points to the first byte of the TSPEC + +*******************************************************************************/ +#define CsrWifiSmeTspecCfmCreate(msg__, dst__, src__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \ + msg__ = (CsrWifiSmeTspecCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeTspecCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_TSPEC_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->transactionId = (transactionId__); \ + msg__->tspecResultCode = (tspecResultCode__); \ + msg__->tspecLength = (tspecLength__); \ + msg__->tspec = (tspec__); + +#define CsrWifiSmeTspecCfmSendTo(dst__, src__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \ + { \ + CsrWifiSmeTspecCfm *msg__; \ + CsrWifiSmeTspecCfmCreate(msg__, dst__, src__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeTspecCfmSend(dst__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \ + CsrWifiSmeTspecCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) + +/******************************************************************************* + + NAME + CsrWifiSmeVersionsGetReqSend + + DESCRIPTION + This primitive gets the value of the Versions parameter. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeVersionsGetReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeVersionsGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeVersionsGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_VERSIONS_GET_REQ, dst__, src__); + +#define CsrWifiSmeVersionsGetReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeVersionsGetReq *msg__; \ + CsrWifiSmeVersionsGetReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeVersionsGetReqSend(src__) \ + CsrWifiSmeVersionsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeVersionsGetCfmSend + + DESCRIPTION + This primitive reports the result of the request. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + versions - Version IDs of the product + +*******************************************************************************/ +#define CsrWifiSmeVersionsGetCfmCreate(msg__, dst__, src__, status__, versions__) \ + msg__ = (CsrWifiSmeVersionsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeVersionsGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_VERSIONS_GET_CFM, dst__, src__); \ + msg__->status = (status__); \ + msg__->versions = (versions__); + +#define CsrWifiSmeVersionsGetCfmSendTo(dst__, src__, status__, versions__) \ + { \ + CsrWifiSmeVersionsGetCfm *msg__; \ + CsrWifiSmeVersionsGetCfmCreate(msg__, dst__, src__, status__, versions__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeVersionsGetCfmSend(dst__, status__, versions__) \ + CsrWifiSmeVersionsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, versions__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiFlightmodeReqSend + + DESCRIPTION + The wireless manager application may call this primitive on boot-up of + the platform to ensure that the chip is placed in a mode that prevents + any emission of RF energy. + This primitive is an alternative to CSR_WIFI_SME_WIFI_ON_REQ. + As in CSR_WIFI_SME_WIFI_ON_REQ, it causes the download of the patch file + (if any) and the programming of the initial MIB settings (if supplied by + the WMA), but it also ensures that the chip is left in its lowest + possible power-mode with the radio subsystems disabled. + This feature is useful on platforms where power cannot be removed from + the chip (leaving the chip not initialised will cause it to consume more + power so calling this function ensures that the chip is initialised into + a low power mode but without entering a state where it could emit any RF + energy). + NOTE: this primitive does not cause the Wi-Fi to change state: Wi-Fi + stays conceptually off. Configuration primitives can be sent after + CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ and the configuration will be maintained. + Requests that require the state of the Wi-Fi to be ON will return + CSR_WIFI_SME_STATUS_WIFI_OFF in their confirms. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + address - Optionally specifies a station MAC address. + In normal use, the manager should set the address to 0xFF + 0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use + the MAC address in the MIB. + mibFilesCount - Number of provided data blocks with initial MIB values + mibFiles - Points to the first data block with initial MIB values. + These data blocks are typically the contents of the provided + files ufmib.dat and localmib.dat, available from the host + file system, if they exist. + These files typically contain radio tuning and calibration + values. + More values can be created using the Host Tools. + +*******************************************************************************/ +#define CsrWifiSmeWifiFlightmodeReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__) \ + msg__ = (CsrWifiSmeWifiFlightmodeReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiFlightmodeReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ, dst__, src__); \ + msg__->address = (address__); \ + msg__->mibFilesCount = (mibFilesCount__); \ + msg__->mibFiles = (mibFiles__); + +#define CsrWifiSmeWifiFlightmodeReqSendTo(dst__, src__, address__, mibFilesCount__, mibFiles__) \ + { \ + CsrWifiSmeWifiFlightmodeReq *msg__; \ + CsrWifiSmeWifiFlightmodeReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiFlightmodeReqSend(src__, address__, mibFilesCount__, mibFiles__) \ + CsrWifiSmeWifiFlightmodeReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, address__, mibFilesCount__, mibFiles__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiFlightmodeCfmSend + + DESCRIPTION + The SME calls this primitive when the chip is initialised for low power + mode and with the radio subsystem disabled. To leave flight mode, and + enable Wi-Fi, the wireless manager application should call + CSR_WIFI_SME_WIFI_ON_REQ. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeWifiFlightmodeCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeWifiFlightmodeCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiFlightmodeCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_FLIGHTMODE_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeWifiFlightmodeCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeWifiFlightmodeCfm *msg__; \ + CsrWifiSmeWifiFlightmodeCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiFlightmodeCfmSend(dst__, status__) \ + CsrWifiSmeWifiFlightmodeCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOffReqSend + + DESCRIPTION + The wireless manager application calls this primitive to turn off the + chip, thus saving power when Wi-Fi is not in use. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + +*******************************************************************************/ +#define CsrWifiSmeWifiOffReqCreate(msg__, dst__, src__) \ + msg__ = (CsrWifiSmeWifiOffReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOffReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_OFF_REQ, dst__, src__); + +#define CsrWifiSmeWifiOffReqSendTo(dst__, src__) \ + { \ + CsrWifiSmeWifiOffReq *msg__; \ + CsrWifiSmeWifiOffReqCreate(msg__, dst__, src__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiOffReqSend(src__) \ + CsrWifiSmeWifiOffReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOffIndSend + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it to report that the chip has been turned off. + + PARAMETERS + queue - Destination Task Queue + reason - Indicates the reason why the Wi-Fi has been switched off. + +*******************************************************************************/ +#define CsrWifiSmeWifiOffIndCreate(msg__, dst__, src__, reason__) \ + msg__ = (CsrWifiSmeWifiOffInd *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOffInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_OFF_IND, dst__, src__); \ + msg__->reason = (reason__); + +#define CsrWifiSmeWifiOffIndSendTo(dst__, src__, reason__) \ + { \ + CsrWifiSmeWifiOffInd *msg__; \ + CsrWifiSmeWifiOffIndCreate(msg__, dst__, src__, reason__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiOffIndSend(dst__, reason__) \ + CsrWifiSmeWifiOffIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, reason__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOffCfmSend + + DESCRIPTION + After receiving CSR_WIFI_SME_WIFI_OFF_REQ, if the chip is connected to a + network, the SME will perform a disconnect operation, will send a + CSR_WIFI_SME_MEDIA_STATUS_IND with + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED, and then will call + CSR_WIFI_SME_WIFI_OFF_CFM when the chip is off. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeWifiOffCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeWifiOffCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOffCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_OFF_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeWifiOffCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeWifiOffCfm *msg__; \ + CsrWifiSmeWifiOffCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiOffCfmSend(dst__, status__) \ + CsrWifiSmeWifiOffCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOnReqSend + + DESCRIPTION + The wireless manager application calls this primitive to turn on the + Wi-Fi chip. + If the Wi-Fi chip is currently off, the SME turns the Wi-Fi chip on, + downloads the patch file (if any), and programs the initial MIB settings + (if supplied by the WMA). + The patch file is not provided with the SME API; its downloading is + automatic and handled internally by the system. + The MIB settings, when provided, override the default values that the + firmware loads from EEPROM. + If the Wi-Fi chip is already on, the SME takes no action and returns a + successful status in the confirm. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + address - Optionally specifies a station MAC address. + In normal use, the manager should set the address to 0xFF + 0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use + the MAC address in the MIB + mibFilesCount - Number of provided data blocks with initial MIB values + mibFiles - Points to the first data block with initial MIB values. + These data blocks are typically the contents of the provided + files ufmib.dat and localmib.dat, available from the host + file system, if they exist. + These files typically contain radio tuning and calibration + values. + More values can be created using the Host Tools. + +*******************************************************************************/ +#define CsrWifiSmeWifiOnReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__) \ + msg__ = (CsrWifiSmeWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOnReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_ON_REQ, dst__, src__); \ + msg__->address = (address__); \ + msg__->mibFilesCount = (mibFilesCount__); \ + msg__->mibFiles = (mibFiles__); + +#define CsrWifiSmeWifiOnReqSendTo(dst__, src__, address__, mibFilesCount__, mibFiles__) \ + { \ + CsrWifiSmeWifiOnReq *msg__; \ + CsrWifiSmeWifiOnReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiOnReqSend(src__, address__, mibFilesCount__, mibFiles__) \ + CsrWifiSmeWifiOnReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, address__, mibFilesCount__, mibFiles__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOnIndSend + + DESCRIPTION + The SME sends this primitive to all tasks that have registered to receive + it once the chip becomes available and ready to use. + + PARAMETERS + queue - Destination Task Queue + address - Current MAC address + +*******************************************************************************/ +#define CsrWifiSmeWifiOnIndCreate(msg__, dst__, src__, address__) \ + msg__ = (CsrWifiSmeWifiOnInd *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOnInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_ON_IND, dst__, src__); \ + msg__->address = (address__); + +#define CsrWifiSmeWifiOnIndSendTo(dst__, src__, address__) \ + { \ + CsrWifiSmeWifiOnInd *msg__; \ + CsrWifiSmeWifiOnIndCreate(msg__, dst__, src__, address__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiOnIndSend(dst__, address__) \ + CsrWifiSmeWifiOnIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, address__) + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOnCfmSend + + DESCRIPTION + The SME sends this primitive to the task that has sent the request once + the chip has been initialised and is available for use. + + PARAMETERS + queue - Destination Task Queue + status - Reports the result of the request + +*******************************************************************************/ +#define CsrWifiSmeWifiOnCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeWifiOnCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOnCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_ON_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeWifiOnCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeWifiOnCfm *msg__; \ + CsrWifiSmeWifiOnCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWifiOnCfmSend(dst__, status__) \ + CsrWifiSmeWifiOnCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfigurationReqSend + + DESCRIPTION + This primitive passes the WPS information for the device to SME. This may + be accepted only if no interface is active. + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + wpsConfig - WPS config. + +*******************************************************************************/ +#define CsrWifiSmeWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__) \ + msg__ = (CsrWifiSmeWpsConfigurationReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWpsConfigurationReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WPS_CONFIGURATION_REQ, dst__, src__); \ + msg__->wpsConfig = (wpsConfig__); + +#define CsrWifiSmeWpsConfigurationReqSendTo(dst__, src__, wpsConfig__) \ + { \ + CsrWifiSmeWpsConfigurationReq *msg__; \ + CsrWifiSmeWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWpsConfigurationReqSend(src__, wpsConfig__) \ + CsrWifiSmeWpsConfigurationReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, wpsConfig__) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfigurationCfmSend + + DESCRIPTION + Confirm. + + PARAMETERS + queue - Destination Task Queue + status - Status of the request. + +*******************************************************************************/ +#define CsrWifiSmeWpsConfigurationCfmCreate(msg__, dst__, src__, status__) \ + msg__ = (CsrWifiSmeWpsConfigurationCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeWpsConfigurationCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WPS_CONFIGURATION_CFM, dst__, src__); \ + msg__->status = (status__); + +#define CsrWifiSmeWpsConfigurationCfmSendTo(dst__, src__, status__) \ + { \ + CsrWifiSmeWpsConfigurationCfm *msg__; \ + CsrWifiSmeWpsConfigurationCfmCreate(msg__, dst__, src__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeWpsConfigurationCfmSend(dst__, status__) \ + CsrWifiSmeWpsConfigurationCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_SME_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_prim.h b/drivers/staging/csr/csr_wifi_sme_prim.h new file mode 100644 index 000000000000..4bc8520dbd0c --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_prim.h @@ -0,0 +1,6494 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_PRIM_H__ +#define CSR_WIFI_SME_PRIM_H__ + +#include "csr_types.h" +#include "csr_prim_defs.h" +#include "csr_sched.h" +#include "csr_wifi_common.h" +#include "csr_result.h" +#include "csr_wifi_fsm_event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSR_WIFI_SME_PRIM (0x0404) + +typedef CsrPrim CsrWifiSmePrim; + + +/******************************************************************************* + + NAME + CsrWifiSme80211NetworkType + + DESCRIPTION + Indicates the physical layer of the network + + VALUES + CSR_WIFI_SME_80211_NETWORK_TYPE_DS + - Direct-sequence spread spectrum + CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM24 + - Orthogonal Frequency Division Multiplexing at 2.4 GHz + CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM5 + - Orthogonal Frequency Division Multiplexing at 5 GHz + CSR_WIFI_SME_80211_NETWORK_TYPE_AUTO + - Automatic + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSme80211NetworkType; +#define CSR_WIFI_SME_80211_NETWORK_TYPE_DS ((CsrWifiSme80211NetworkType) 0x00) +#define CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM24 ((CsrWifiSme80211NetworkType) 0x01) +#define CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM5 ((CsrWifiSme80211NetworkType) 0x02) +#define CSR_WIFI_SME_80211_NETWORK_TYPE_AUTO ((CsrWifiSme80211NetworkType) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSme80211PrivacyMode + + DESCRIPTION + Bits to enable or disable the privacy mode + + VALUES + CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED + - Privacy mode is enabled: use of WEP for confidentiality is + required. + CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED + - Privacy mode is disabled + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSme80211PrivacyMode; +#define CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED ((CsrWifiSme80211PrivacyMode) 0x00) +#define CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED ((CsrWifiSme80211PrivacyMode) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSme80211dTrustLevel + + DESCRIPTION + Level of trust for the information coming from the network + + VALUES + CSR_WIFI_SME_80211D_TRUST_LEVEL_STRICT + - Start with passive scanning and only accept country IE for + updating channel lists + CSR_WIFI_SME_80211D_TRUST_LEVEL_ADJUNCT + - As above plus accept adjunct technology location + information + CSR_WIFI_SME_80211D_TRUST_LEVEL_BSS + - As above accept plus receiving channel from infrastructure + networks + CSR_WIFI_SME_80211D_TRUST_LEVEL_IBSS + - As above accept plus receiving channel from the ad hoc + networks + CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB + - Start with active scanning with list of active channels + from the MIB and accept as above + CSR_WIFI_SME_80211D_TRUST_LEVEL_DISABLED + - Start with active scanning with list of active channels + from the MIB and ignore any channel information from the + network + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSme80211dTrustLevel; +#define CSR_WIFI_SME_80211D_TRUST_LEVEL_STRICT ((CsrWifiSme80211dTrustLevel) 0x01) +#define CSR_WIFI_SME_80211D_TRUST_LEVEL_ADJUNCT ((CsrWifiSme80211dTrustLevel) 0x02) +#define CSR_WIFI_SME_80211D_TRUST_LEVEL_BSS ((CsrWifiSme80211dTrustLevel) 0x03) +#define CSR_WIFI_SME_80211D_TRUST_LEVEL_IBSS ((CsrWifiSme80211dTrustLevel) 0x04) +#define CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB ((CsrWifiSme80211dTrustLevel) 0x05) +#define CSR_WIFI_SME_80211D_TRUST_LEVEL_DISABLED ((CsrWifiSme80211dTrustLevel) 0x06) + +/******************************************************************************* + + NAME + CsrWifiSmeAmpStatus + + DESCRIPTION + AMP Current Status + + VALUES + CSR_WIFI_SME_AMP_ACTIVE - AMP ACTIVE. + CSR_WIFI_SME_AMP_INACTIVE - AMP INACTIVE + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeAmpStatus; +#define CSR_WIFI_SME_AMP_ACTIVE ((CsrWifiSmeAmpStatus) 0x00) +#define CSR_WIFI_SME_AMP_INACTIVE ((CsrWifiSmeAmpStatus) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSmeAuthMode + + DESCRIPTION + Define bits for CsrWifiSmeAuthMode + + VALUES + CSR_WIFI_SME_AUTH_MODE_80211_OPEN + - Connects to an open system network (i.e. no authentication, + no encryption) or to a WEP enabled network. + CSR_WIFI_SME_AUTH_MODE_80211_SHARED + - Connect to a WEP enabled network. + CSR_WIFI_SME_AUTH_MODE_8021X_WPA + - Connects to a WPA Enterprise enabled network. + CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK + - Connects to a WPA with Pre-Shared Key enabled network. + CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 + - Connects to a WPA2 Enterprise enabled network. + CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK + - Connects to a WPA2 with Pre-Shared Key enabled network. + CSR_WIFI_SME_AUTH_MODE_8021X_CCKM + - Connects to a CCKM enabled network. + CSR_WIFI_SME_AUTH_MODE_WAPI_WAI + - Connects to a WAPI Enterprise enabled network. + CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK + - Connects to a WAPI with Pre-Shared Key enabled network. + CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X + - For future use. + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeAuthMode; +#define CSR_WIFI_SME_AUTH_MODE_80211_OPEN ((CsrWifiSmeAuthMode) 0x0001) +#define CSR_WIFI_SME_AUTH_MODE_80211_SHARED ((CsrWifiSmeAuthMode) 0x0002) +#define CSR_WIFI_SME_AUTH_MODE_8021X_WPA ((CsrWifiSmeAuthMode) 0x0004) +#define CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK ((CsrWifiSmeAuthMode) 0x0008) +#define CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 ((CsrWifiSmeAuthMode) 0x0010) +#define CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK ((CsrWifiSmeAuthMode) 0x0020) +#define CSR_WIFI_SME_AUTH_MODE_8021X_CCKM ((CsrWifiSmeAuthMode) 0x0040) +#define CSR_WIFI_SME_AUTH_MODE_WAPI_WAI ((CsrWifiSmeAuthMode) 0x0080) +#define CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK ((CsrWifiSmeAuthMode) 0x0100) +#define CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X ((CsrWifiSmeAuthMode) 0x0200) + +/******************************************************************************* + + NAME + CsrWifiSmeBasicUsability + + DESCRIPTION + Indicates the usability level of a channel + + VALUES + CSR_WIFI_SME_BASIC_USABILITY_UNUSABLE + - Not usable; connection not recommended + CSR_WIFI_SME_BASIC_USABILITY_POOR + - Poor quality; connect only if nothing better is available + CSR_WIFI_SME_BASIC_USABILITY_SATISFACTORY + - Quality is satisfactory + CSR_WIFI_SME_BASIC_USABILITY_NOT_CONNECTED + - Not connected + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeBasicUsability; +#define CSR_WIFI_SME_BASIC_USABILITY_UNUSABLE ((CsrWifiSmeBasicUsability) 0x00) +#define CSR_WIFI_SME_BASIC_USABILITY_POOR ((CsrWifiSmeBasicUsability) 0x01) +#define CSR_WIFI_SME_BASIC_USABILITY_SATISFACTORY ((CsrWifiSmeBasicUsability) 0x02) +#define CSR_WIFI_SME_BASIC_USABILITY_NOT_CONNECTED ((CsrWifiSmeBasicUsability) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeBssType + + DESCRIPTION + Indicates the BSS type + + VALUES + CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE + - Infrastructure BSS. + CSR_WIFI_SME_BSS_TYPE_ADHOC + - Ad hoc or Independent BSS. + CSR_WIFI_SME_BSS_TYPE_ANY_BSS + - Specifies any type of BSS + CSR_WIFI_SME_BSS_TYPE_P2P + - Specifies P2P + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeBssType; +#define CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE ((CsrWifiSmeBssType) 0x00) +#define CSR_WIFI_SME_BSS_TYPE_ADHOC ((CsrWifiSmeBssType) 0x01) +#define CSR_WIFI_SME_BSS_TYPE_ANY_BSS ((CsrWifiSmeBssType) 0x02) +#define CSR_WIFI_SME_BSS_TYPE_P2P ((CsrWifiSmeBssType) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeCoexScheme + + DESCRIPTION + Options for the coexistence signalling + Same as MibValues + + VALUES + CSR_WIFI_SME_COEX_SCHEME_DISABLED + - The coexistence signalling is disabled + CSR_WIFI_SME_COEX_SCHEME_CSR + - Basic CSR coexistence signalling + CSR_WIFI_SME_COEX_SCHEME_CSR_CHANNEL + - Full CSR coexistence signalling + CSR_WIFI_SME_COEX_SCHEME_PTA + - Packet Traffic Arbitrator coexistence signalling + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeCoexScheme; +#define CSR_WIFI_SME_COEX_SCHEME_DISABLED ((CsrWifiSmeCoexScheme) 0x00) +#define CSR_WIFI_SME_COEX_SCHEME_CSR ((CsrWifiSmeCoexScheme) 0x01) +#define CSR_WIFI_SME_COEX_SCHEME_CSR_CHANNEL ((CsrWifiSmeCoexScheme) 0x02) +#define CSR_WIFI_SME_COEX_SCHEME_PTA ((CsrWifiSmeCoexScheme) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeControlIndication + + DESCRIPTION + Indicates the reason why the Wi-Fi has been switched off. + The values of this type are used across the NME/SME/Router API's and they + must be kept consistent with the corresponding types in the .xml of the + ottherinterfaces + + VALUES + CSR_WIFI_SME_CONTROL_INDICATION_ERROR + - An unrecoverable error (for example, an unrecoverable SDIO + error) has occurred. + The wireless manager application should reinitialise the + chip by calling CSR_WIFI_SME_WIFI_ON_REQ. + CSR_WIFI_SME_CONTROL_INDICATION_EXIT + - The chip became unavailable due to an external action, for + example, when a plug-in card is ejected or the driver is + unloaded. + CSR_WIFI_SME_CONTROL_INDICATION_USER_REQUESTED + - The Wi-Fi has been switched off as the wireless manager + application has sent CSR_WIFI_SME_WIFI_OFF_REQ + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeControlIndication; +#define CSR_WIFI_SME_CONTROL_INDICATION_ERROR ((CsrWifiSmeControlIndication) 0x01) +#define CSR_WIFI_SME_CONTROL_INDICATION_EXIT ((CsrWifiSmeControlIndication) 0x02) +#define CSR_WIFI_SME_CONTROL_INDICATION_USER_REQUESTED ((CsrWifiSmeControlIndication) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeCtsProtectionType + + DESCRIPTION + SME CTS Protection Types + + VALUES + CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC + - AP CTS Protection automatic based on non-ERP station in own + BSS or neighbouring BSS on the same channel based on OLBC. + This requires monitoring of beacons from other APs. + CSR_WIFI_SME_CTS_PROTECTION_FORCE_ENABLED + - AP CTS Protection Force enabled + CSR_WIFI_SME_CTS_PROTECTION_FORCE_DISABLED + - AP CTS Protection Force disabled. + CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC_NO_OLBC + - AP CTS Protection automatic without considering OLBC but + considering non-ERP station in the own BSS Valid only if AP + is configured to work in 802.11bg or 802.11g mode otherwise + this option specifies the same behaviour as AUTOMATIC + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeCtsProtectionType; +#define CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC ((CsrWifiSmeCtsProtectionType) 0x00) +#define CSR_WIFI_SME_CTS_PROTECTION_FORCE_ENABLED ((CsrWifiSmeCtsProtectionType) 0x01) +#define CSR_WIFI_SME_CTS_PROTECTION_FORCE_DISABLED ((CsrWifiSmeCtsProtectionType) 0x02) +#define CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC_NO_OLBC ((CsrWifiSmeCtsProtectionType) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeD3AutoScanMode + + DESCRIPTION + Autonomous scan status while in D3 suspended period + + VALUES + CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSON + - Autonomous scan stays on + CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSOFF + - Autonomous scan is switched off + CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSAUTO + - Automatically select autoscanning behaviour. + CURRENTLY NOT SUPPORTED + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeD3AutoScanMode; +#define CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSON ((CsrWifiSmeD3AutoScanMode) 0x00) +#define CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSOFF ((CsrWifiSmeD3AutoScanMode) 0x01) +#define CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSAUTO ((CsrWifiSmeD3AutoScanMode) 0x02) + +/******************************************************************************* + + NAME + CsrWifiSmeEncryption + + DESCRIPTION + Defines bits for CsrWifiSmeEncryption + For a WEP enabled network, the caller must specify the correct + combination of flags in the encryptionModeMask. + + VALUES + CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE + - No encryption set + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 + - Selects 40 byte key WEP for unicast communication + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 + - Selects 104 byte key WEP for unicast communication + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP + - Selects TKIP for unicast communication + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP + - Selects CCMP for unicast communication + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 + - Selects SMS4 for unicast communication + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 + - Selects 40 byte key WEP for broadcast messages + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104 + - Selects 104 byte key WEP for broadcast messages + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP + - Selects a TKIP for broadcast messages + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP + - Selects CCMP for broadcast messages + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4 + - Selects SMS4 for broadcast messages + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeEncryption; +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE ((CsrWifiSmeEncryption) 0x0000) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 ((CsrWifiSmeEncryption) 0x0001) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 ((CsrWifiSmeEncryption) 0x0002) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP ((CsrWifiSmeEncryption) 0x0004) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP ((CsrWifiSmeEncryption) 0x0008) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 ((CsrWifiSmeEncryption) 0x0010) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 ((CsrWifiSmeEncryption) 0x0020) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104 ((CsrWifiSmeEncryption) 0x0040) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP ((CsrWifiSmeEncryption) 0x0080) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP ((CsrWifiSmeEncryption) 0x0100) +#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4 ((CsrWifiSmeEncryption) 0x0200) + +/******************************************************************************* + + NAME + CsrWifiSmeFirmwareDriverInterface + + DESCRIPTION + Type of communication between Host and Firmware + + VALUES + CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_UNIT_DATA_INTERFACE + - No preformated header. NOT SUPPORTED in the current release + CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_PACKET_INTERFACE + - Preformated IEEE 802.11 header for user plane + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeFirmwareDriverInterface; +#define CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_UNIT_DATA_INTERFACE ((CsrWifiSmeFirmwareDriverInterface) 0x00) +#define CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_PACKET_INTERFACE ((CsrWifiSmeFirmwareDriverInterface) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSmeHostPowerMode + + DESCRIPTION + Defines the power mode + + VALUES + CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE + - Host device is running on external power. + CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE + - Host device is running on (internal) battery power. + CSR_WIFI_SME_HOST_POWER_MODE_FULL_POWER_SAVE + - For future use. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeHostPowerMode; +#define CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE ((CsrWifiSmeHostPowerMode) 0x00) +#define CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE ((CsrWifiSmeHostPowerMode) 0x01) +#define CSR_WIFI_SME_HOST_POWER_MODE_FULL_POWER_SAVE ((CsrWifiSmeHostPowerMode) 0x02) + +/******************************************************************************* + + NAME + CsrWifiSmeIEEE80211Reason + + DESCRIPTION + As definined in the IEEE 802.11 standards + + VALUES + CSR_WIFI_SME_IEEE80211_REASON_SUCCESS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNSPECIFIED_REASON + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_AUTHENTICATION_NOT_VALID + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_DEAUTHENTICATED_LEAVE_BSS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_INACTIVITY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_AP_OVERLOAD + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_CLASS_2FRAME_ERROR + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_CLASS_3FRAME_ERROR + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_LEAVE_BSS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_ASSOCIATION_NOT_AUTHENTICATED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_POWER_CAPABILITY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_SUPPORTED_CHANNELS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_INFORMATION_ELEMENT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_MICHAEL_MIC_FAILURE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_FOURWAY_HANDSHAKE_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_HANDSHAKE_ELEMENT_DIFFERENT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_GROUP_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_PAIRWISE_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_AKMP + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_RSN_IEVERSION + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_RSN_IECAPABILITIES + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_DOT1X_AUTH_FAILED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_CIPHER_REJECTED_BY_POLICY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_SERVICE_CHANGE_PRECLUDES_TS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_QOS_UNSPECIFIED_REASON + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_QOS_INSUFFICIENT_BANDWIDTH + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_QOS_EXCESSIVE_NOT_ACK + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_QOS_TXOPLIMIT_EXCEEDED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_QSTA_LEAVING + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_END_TS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_END_DLS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_END_BA + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_TS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_BA + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_DLS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_STAKEY_MISMATCH + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNICAST_KEY_NEGOTIATION_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_MULTICAST_KEY_ANNOUNCEMENT_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INCOMPATIBLE_UNICAST_KEY_NEGOTIATION_IE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_MULTICAST_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_UNICAST_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_WAPI_IE_VERSION + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_INVALID_WAPI_CAPABILITY_IE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_REASON_WAI_CERTIFICATE_AUTHENTICATION_FAILED + - See IEEE 802.11 Standard + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeIEEE80211Reason; +#define CSR_WIFI_SME_IEEE80211_REASON_SUCCESS ((CsrWifiSmeIEEE80211Reason) 0x0000) +#define CSR_WIFI_SME_IEEE80211_REASON_UNSPECIFIED_REASON ((CsrWifiSmeIEEE80211Reason) 0x0001) +#define CSR_WIFI_SME_IEEE80211_REASON_AUTHENTICATION_NOT_VALID ((CsrWifiSmeIEEE80211Reason) 0x0002) +#define CSR_WIFI_SME_IEEE80211_REASON_DEAUTHENTICATED_LEAVE_BSS ((CsrWifiSmeIEEE80211Reason) 0x0003) +#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_INACTIVITY ((CsrWifiSmeIEEE80211Reason) 0x0004) +#define CSR_WIFI_SME_IEEE80211_REASON_AP_OVERLOAD ((CsrWifiSmeIEEE80211Reason) 0x0005) +#define CSR_WIFI_SME_IEEE80211_REASON_CLASS_2FRAME_ERROR ((CsrWifiSmeIEEE80211Reason) 0x0006) +#define CSR_WIFI_SME_IEEE80211_REASON_CLASS_3FRAME_ERROR ((CsrWifiSmeIEEE80211Reason) 0x0007) +#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_LEAVE_BSS ((CsrWifiSmeIEEE80211Reason) 0x0008) +#define CSR_WIFI_SME_IEEE80211_REASON_ASSOCIATION_NOT_AUTHENTICATED ((CsrWifiSmeIEEE80211Reason) 0x0009) +#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_POWER_CAPABILITY ((CsrWifiSmeIEEE80211Reason) 0x000a) +#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_SUPPORTED_CHANNELS ((CsrWifiSmeIEEE80211Reason) 0x000b) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_INFORMATION_ELEMENT ((CsrWifiSmeIEEE80211Reason) 0x000d) +#define CSR_WIFI_SME_IEEE80211_REASON_MICHAEL_MIC_FAILURE ((CsrWifiSmeIEEE80211Reason) 0x000e) +#define CSR_WIFI_SME_IEEE80211_REASON_FOURWAY_HANDSHAKE_TIMEOUT ((CsrWifiSmeIEEE80211Reason) 0x000f) +#define CSR_WIFI_SME_IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT ((CsrWifiSmeIEEE80211Reason) 0x0010) +#define CSR_WIFI_SME_IEEE80211_REASON_HANDSHAKE_ELEMENT_DIFFERENT ((CsrWifiSmeIEEE80211Reason) 0x0011) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_GROUP_CIPHER ((CsrWifiSmeIEEE80211Reason) 0x0012) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_PAIRWISE_CIPHER ((CsrWifiSmeIEEE80211Reason) 0x0013) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_AKMP ((CsrWifiSmeIEEE80211Reason) 0x0014) +#define CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_RSN_IEVERSION ((CsrWifiSmeIEEE80211Reason) 0x0015) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_RSN_IECAPABILITIES ((CsrWifiSmeIEEE80211Reason) 0x0016) +#define CSR_WIFI_SME_IEEE80211_REASON_DOT1X_AUTH_FAILED ((CsrWifiSmeIEEE80211Reason) 0x0017) +#define CSR_WIFI_SME_IEEE80211_REASON_CIPHER_REJECTED_BY_POLICY ((CsrWifiSmeIEEE80211Reason) 0x0018) +#define CSR_WIFI_SME_IEEE80211_REASON_SERVICE_CHANGE_PRECLUDES_TS ((CsrWifiSmeIEEE80211Reason) 0x001F) +#define CSR_WIFI_SME_IEEE80211_REASON_QOS_UNSPECIFIED_REASON ((CsrWifiSmeIEEE80211Reason) 0x0020) +#define CSR_WIFI_SME_IEEE80211_REASON_QOS_INSUFFICIENT_BANDWIDTH ((CsrWifiSmeIEEE80211Reason) 0x0021) +#define CSR_WIFI_SME_IEEE80211_REASON_QOS_EXCESSIVE_NOT_ACK ((CsrWifiSmeIEEE80211Reason) 0x0022) +#define CSR_WIFI_SME_IEEE80211_REASON_QOS_TXOPLIMIT_EXCEEDED ((CsrWifiSmeIEEE80211Reason) 0x0023) +#define CSR_WIFI_SME_IEEE80211_REASON_QSTA_LEAVING ((CsrWifiSmeIEEE80211Reason) 0x0024) +#define CSR_WIFI_SME_IEEE80211_REASON_END_TS ((CsrWifiSmeIEEE80211Reason) 0x0025) +#define CSR_WIFI_SME_IEEE80211_REASON_END_DLS ((CsrWifiSmeIEEE80211Reason) 0x0025) +#define CSR_WIFI_SME_IEEE80211_REASON_END_BA ((CsrWifiSmeIEEE80211Reason) 0x0025) +#define CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_TS ((CsrWifiSmeIEEE80211Reason) 0x0026) +#define CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_BA ((CsrWifiSmeIEEE80211Reason) 0x0026) +#define CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_DLS ((CsrWifiSmeIEEE80211Reason) 0x0026) +#define CSR_WIFI_SME_IEEE80211_REASON_TIMEOUT ((CsrWifiSmeIEEE80211Reason) 0x0027) +#define CSR_WIFI_SME_IEEE80211_REASON_STAKEY_MISMATCH ((CsrWifiSmeIEEE80211Reason) 0x002d) +#define CSR_WIFI_SME_IEEE80211_REASON_UNICAST_KEY_NEGOTIATION_TIMEOUT ((CsrWifiSmeIEEE80211Reason) 0xf019) +#define CSR_WIFI_SME_IEEE80211_REASON_MULTICAST_KEY_ANNOUNCEMENT_TIMEOUT ((CsrWifiSmeIEEE80211Reason) 0xf01a) +#define CSR_WIFI_SME_IEEE80211_REASON_INCOMPATIBLE_UNICAST_KEY_NEGOTIATION_IE ((CsrWifiSmeIEEE80211Reason) 0xf01b) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_MULTICAST_CIPHER ((CsrWifiSmeIEEE80211Reason) 0xf01c) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_UNICAST_CIPHER ((CsrWifiSmeIEEE80211Reason) 0xf01d) +#define CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_WAPI_IE_VERSION ((CsrWifiSmeIEEE80211Reason) 0xf01e) +#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_WAPI_CAPABILITY_IE ((CsrWifiSmeIEEE80211Reason) 0xf01f) +#define CSR_WIFI_SME_IEEE80211_REASON_WAI_CERTIFICATE_AUTHENTICATION_FAILED ((CsrWifiSmeIEEE80211Reason) 0xf020) + +/******************************************************************************* + + NAME + CsrWifiSmeIEEE80211Result + + DESCRIPTION + As definined in the IEEE 802.11 standards + + VALUES + CSR_WIFI_SME_IEEE80211_RESULT_SUCCESS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_FAILURE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CAPABILITIES_MISMATCH + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REASSOCIATION_DENIED_NO_ASSOCIATION + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_EXTERNAL_REASON + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_MISMATCH + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_INVALID_AUTHENTICATION_SEQUENCE_NUMBER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHALLENGE_FAILURE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_OUT_OF_MEMORY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_BASIC_RATES_MISMATCH + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_PREAMBLE_REQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PBCC_MODULATION_REQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHANNEL_AGILITY_REQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SPECTRUM_MANAGEMENT_REQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POWER_CAPABILITY_UNACCEPTABLE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SUPPORTED_CHANNELS_UNACCEPTABLE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_SLOT_REQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_DSSS_OFDMREQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NO_HT_SUPPORT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_R0KH_UNREACHABLE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PCO_TRANSITION_SUPPORT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_ASSOCIATION_REQUEST_REJECTED_TEMPORARILY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_ROBUST_MANAGEMENT_FRAME_POLICY_VIOLATION + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_FAILURE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_BANDWIDTH_INSUFFICIENT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POOR_OPERATING_CHANNEL + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_QOS_REQUIRED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_REASON_UNSPECIFIED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PARAMETERS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_WITH_SUGGESTED_TSPEC_CHANGES + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_IE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_GROUP_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_PAIRWISE_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_AKMP + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_UNSUPPORTED_RSN_VERSION + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_RSN_CAPABILITY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_SECURITY_POLICY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_FOR_DELAY_PERIOD + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_NOT_ALLOWED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_NOT_PRESENT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_NOT_QSTA + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_LISTEN_INTERVAL_TOO_LARGE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FT_ACTION_FRAME_COUNT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PMKID + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MDIE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FTIE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_QOS_FAILURE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_WRONG_POLICY + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INSUFFICIENT_BANDWIDTH + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_TSPEC_PARAMETERS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_TIMEOUT + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_TOO_MANY_SIMULTANEOUS_REQUESTS + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_BSS_ALREADY_STARTED_OR_JOINED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_NOT_SUPPORTED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_TRANSMISSION_FAILURE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NOT_AUTHENTICATED + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_RESET_REQUIRED_BEFORE_START + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_LM_INFO_UNAVAILABLE + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_UNICAST_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MULTICAST_CIPHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_UNSUPPORTED_WAPI_IE_VERSION + - See IEEE 802.11 Standard + CSR_WIFI_SME_IEEE80211_RESULT_INVALID_WAPI_CAPABILITY_IE + - See IEEE 802.11 Standard + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeIEEE80211Result; +#define CSR_WIFI_SME_IEEE80211_RESULT_SUCCESS ((CsrWifiSmeIEEE80211Result) 0x0000) +#define CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_FAILURE ((CsrWifiSmeIEEE80211Result) 0x0001) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CAPABILITIES_MISMATCH ((CsrWifiSmeIEEE80211Result) 0x000a) +#define CSR_WIFI_SME_IEEE80211_RESULT_REASSOCIATION_DENIED_NO_ASSOCIATION ((CsrWifiSmeIEEE80211Result) 0x000b) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_EXTERNAL_REASON ((CsrWifiSmeIEEE80211Result) 0x000c) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_MISMATCH ((CsrWifiSmeIEEE80211Result) 0x000d) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_INVALID_AUTHENTICATION_SEQUENCE_NUMBER ((CsrWifiSmeIEEE80211Result) 0x000e) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHALLENGE_FAILURE ((CsrWifiSmeIEEE80211Result) 0x000f) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_TIMEOUT ((CsrWifiSmeIEEE80211Result) 0x0010) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_OUT_OF_MEMORY ((CsrWifiSmeIEEE80211Result) 0x0011) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_BASIC_RATES_MISMATCH ((CsrWifiSmeIEEE80211Result) 0x0012) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_PREAMBLE_REQUIRED ((CsrWifiSmeIEEE80211Result) 0x0013) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PBCC_MODULATION_REQUIRED ((CsrWifiSmeIEEE80211Result) 0x0014) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHANNEL_AGILITY_REQUIRED ((CsrWifiSmeIEEE80211Result) 0x0015) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SPECTRUM_MANAGEMENT_REQUIRED ((CsrWifiSmeIEEE80211Result) 0x0016) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POWER_CAPABILITY_UNACCEPTABLE ((CsrWifiSmeIEEE80211Result) 0x0017) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SUPPORTED_CHANNELS_UNACCEPTABLE ((CsrWifiSmeIEEE80211Result) 0x0018) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_SLOT_REQUIRED ((CsrWifiSmeIEEE80211Result) 0x0019) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_DSSS_OFDMREQUIRED ((CsrWifiSmeIEEE80211Result) 0x001a) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NO_HT_SUPPORT ((CsrWifiSmeIEEE80211Result) 0x001b) +#define CSR_WIFI_SME_IEEE80211_RESULT_R0KH_UNREACHABLE ((CsrWifiSmeIEEE80211Result) 0x001c) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PCO_TRANSITION_SUPPORT ((CsrWifiSmeIEEE80211Result) 0x001d) +#define CSR_WIFI_SME_IEEE80211_RESULT_ASSOCIATION_REQUEST_REJECTED_TEMPORARILY ((CsrWifiSmeIEEE80211Result) 0x001e) +#define CSR_WIFI_SME_IEEE80211_RESULT_ROBUST_MANAGEMENT_FRAME_POLICY_VIOLATION ((CsrWifiSmeIEEE80211Result) 0x001f) +#define CSR_WIFI_SME_IEEE80211_RESULT_FAILURE ((CsrWifiSmeIEEE80211Result) 0x0020) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_BANDWIDTH_INSUFFICIENT ((CsrWifiSmeIEEE80211Result) 0x0021) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POOR_OPERATING_CHANNEL ((CsrWifiSmeIEEE80211Result) 0x0022) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_QOS_REQUIRED ((CsrWifiSmeIEEE80211Result) 0x0023) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_REASON_UNSPECIFIED ((CsrWifiSmeIEEE80211Result) 0x0025) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED ((CsrWifiSmeIEEE80211Result) 0x0025) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PARAMETERS ((CsrWifiSmeIEEE80211Result) 0x0026) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_WITH_SUGGESTED_TSPEC_CHANGES ((CsrWifiSmeIEEE80211Result) 0x0027) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_IE ((CsrWifiSmeIEEE80211Result) 0x0028) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_GROUP_CIPHER ((CsrWifiSmeIEEE80211Result) 0x0029) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_PAIRWISE_CIPHER ((CsrWifiSmeIEEE80211Result) 0x002a) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_AKMP ((CsrWifiSmeIEEE80211Result) 0x002b) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_UNSUPPORTED_RSN_VERSION ((CsrWifiSmeIEEE80211Result) 0x002c) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_RSN_CAPABILITY ((CsrWifiSmeIEEE80211Result) 0x002d) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_SECURITY_POLICY ((CsrWifiSmeIEEE80211Result) 0x002e) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_FOR_DELAY_PERIOD ((CsrWifiSmeIEEE80211Result) 0x002f) +#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_ALLOWED ((CsrWifiSmeIEEE80211Result) 0x0030) +#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_PRESENT ((CsrWifiSmeIEEE80211Result) 0x0031) +#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_QSTA ((CsrWifiSmeIEEE80211Result) 0x0032) +#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_LISTEN_INTERVAL_TOO_LARGE ((CsrWifiSmeIEEE80211Result) 0x0033) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FT_ACTION_FRAME_COUNT ((CsrWifiSmeIEEE80211Result) 0x0034) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PMKID ((CsrWifiSmeIEEE80211Result) 0x0035) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MDIE ((CsrWifiSmeIEEE80211Result) 0x0036) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FTIE ((CsrWifiSmeIEEE80211Result) 0x0037) +#define CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_QOS_FAILURE ((CsrWifiSmeIEEE80211Result) 0x00c8) +#define CSR_WIFI_SME_IEEE80211_RESULT_WRONG_POLICY ((CsrWifiSmeIEEE80211Result) 0x00c9) +#define CSR_WIFI_SME_IEEE80211_RESULT_INSUFFICIENT_BANDWIDTH ((CsrWifiSmeIEEE80211Result) 0x00ca) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_TSPEC_PARAMETERS ((CsrWifiSmeIEEE80211Result) 0x00cb) +#define CSR_WIFI_SME_IEEE80211_RESULT_TIMEOUT ((CsrWifiSmeIEEE80211Result) 0x8000) +#define CSR_WIFI_SME_IEEE80211_RESULT_TOO_MANY_SIMULTANEOUS_REQUESTS ((CsrWifiSmeIEEE80211Result) 0x8001) +#define CSR_WIFI_SME_IEEE80211_RESULT_BSS_ALREADY_STARTED_OR_JOINED ((CsrWifiSmeIEEE80211Result) 0x8002) +#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_SUPPORTED ((CsrWifiSmeIEEE80211Result) 0x8003) +#define CSR_WIFI_SME_IEEE80211_RESULT_TRANSMISSION_FAILURE ((CsrWifiSmeIEEE80211Result) 0x8004) +#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NOT_AUTHENTICATED ((CsrWifiSmeIEEE80211Result) 0x8005) +#define CSR_WIFI_SME_IEEE80211_RESULT_RESET_REQUIRED_BEFORE_START ((CsrWifiSmeIEEE80211Result) 0x8006) +#define CSR_WIFI_SME_IEEE80211_RESULT_LM_INFO_UNAVAILABLE ((CsrWifiSmeIEEE80211Result) 0x8007) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_UNICAST_CIPHER ((CsrWifiSmeIEEE80211Result) 0xf02f) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MULTICAST_CIPHER ((CsrWifiSmeIEEE80211Result) 0xf030) +#define CSR_WIFI_SME_IEEE80211_RESULT_UNSUPPORTED_WAPI_IE_VERSION ((CsrWifiSmeIEEE80211Result) 0xf031) +#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_WAPI_CAPABILITY_IE ((CsrWifiSmeIEEE80211Result) 0xf032) + +/******************************************************************************* + + NAME + CsrWifiSmeIndications + + DESCRIPTION + Defines bits for CsrWifiSmeIndicationsMask + + VALUES + CSR_WIFI_SME_INDICATIONS_NONE + - Used to cancel the registrations for receiving indications + CSR_WIFI_SME_INDICATIONS_WIFIOFF + - Used to register for CSR_WIFI_SME_WIFI_OFF_IND events + CSR_WIFI_SME_INDICATIONS_SCANRESULT + - Used to register for CSR_WIFI_SME_SCAN_RESULT_IND events + CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY + - Used to register for CSR_WIFI_SME_CONNECTION_QUALITY_IND + events + CSR_WIFI_SME_INDICATIONS_MEDIASTATUS + - Used to register for CSR_WIFI_SME_MEDIA_STATUS_IND events + CSR_WIFI_SME_INDICATIONS_MICFAILURE + - Used to register for CSR_WIFI_SME_MICFAILURE_IND events + CSR_WIFI_SME_INDICATIONS_PMKIDCANDIDATELIST + - Used to register for CSR_WIFI_SME_PMKIDCANDIDATE_LIST_IND + events + CSR_WIFI_SME_INDICATIONS_TSPEC + - Used to register for CSR_WIFI_SME_TSPEC_IND events + CSR_WIFI_SME_INDICATIONS_ROAMSTART + - Used to register for CSR_WIFI_SME_ROAM_START_IND events + CSR_WIFI_SME_INDICATIONS_ROAMCOMPLETE + - Used to register for CSR_WIFI_SME_ROAM_COMPLETE_IND events + CSR_WIFI_SME_INDICATIONS_ASSOCIATIONSTART + - Used to register for CSR_WIFI_SME_ASSOCIATION_START_IND + events + CSR_WIFI_SME_INDICATIONS_ASSOCIATIONCOMPLETE + - Used to register for CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND + events + CSR_WIFI_SME_INDICATIONS_IBSSSTATION + - Used to register for CSR_WIFI_SME_IBSS_STATION_IND events + CSR_WIFI_SME_INDICATIONS_WIFION + - Used to register for CSR_WIFI_SME_WIFI_ON_IND events + CSR_WIFI_SME_INDICATIONS_ERROR + - Used to register for CSR_WIFI_SME_ERROR_IND events + CSR_WIFI_SME_INDICATIONS_INFO + - Used to register for CSR_WIFI_SME_INFO_IND events + CSR_WIFI_SME_INDICATIONS_COREDUMP + - Used to register for CSR_WIFI_SME_CORE_DUMP_IND events + CSR_WIFI_SME_INDICATIONS_ALL + - Used to register for all available indications + +*******************************************************************************/ +typedef CsrUint32 CsrWifiSmeIndications; +#define CSR_WIFI_SME_INDICATIONS_NONE ((CsrWifiSmeIndications) 0x00000000) +#define CSR_WIFI_SME_INDICATIONS_WIFIOFF ((CsrWifiSmeIndications) 0x00000001) +#define CSR_WIFI_SME_INDICATIONS_SCANRESULT ((CsrWifiSmeIndications) 0x00000002) +#define CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY ((CsrWifiSmeIndications) 0x00000004) +#define CSR_WIFI_SME_INDICATIONS_MEDIASTATUS ((CsrWifiSmeIndications) 0x00000008) +#define CSR_WIFI_SME_INDICATIONS_MICFAILURE ((CsrWifiSmeIndications) 0x00000010) +#define CSR_WIFI_SME_INDICATIONS_PMKIDCANDIDATELIST ((CsrWifiSmeIndications) 0x00000020) +#define CSR_WIFI_SME_INDICATIONS_TSPEC ((CsrWifiSmeIndications) 0x00000040) +#define CSR_WIFI_SME_INDICATIONS_ROAMSTART ((CsrWifiSmeIndications) 0x00000080) +#define CSR_WIFI_SME_INDICATIONS_ROAMCOMPLETE ((CsrWifiSmeIndications) 0x00000100) +#define CSR_WIFI_SME_INDICATIONS_ASSOCIATIONSTART ((CsrWifiSmeIndications) 0x00000200) +#define CSR_WIFI_SME_INDICATIONS_ASSOCIATIONCOMPLETE ((CsrWifiSmeIndications) 0x00000400) +#define CSR_WIFI_SME_INDICATIONS_IBSSSTATION ((CsrWifiSmeIndications) 0x00000800) +#define CSR_WIFI_SME_INDICATIONS_WIFION ((CsrWifiSmeIndications) 0x00001000) +#define CSR_WIFI_SME_INDICATIONS_ERROR ((CsrWifiSmeIndications) 0x00002000) +#define CSR_WIFI_SME_INDICATIONS_INFO ((CsrWifiSmeIndications) 0x00004000) +#define CSR_WIFI_SME_INDICATIONS_COREDUMP ((CsrWifiSmeIndications) 0x00008000) +#define CSR_WIFI_SME_INDICATIONS_ALL ((CsrWifiSmeIndications) 0xFFFFFFFF) + +/******************************************************************************* + + NAME + CsrWifiSmeKeyType + + DESCRIPTION + Indicates the type of the key + + VALUES + CSR_WIFI_SME_KEY_TYPE_GROUP - Key for broadcast communication + CSR_WIFI_SME_KEY_TYPE_PAIRWISE - Key for unicast communication + CSR_WIFI_SME_KEY_TYPE_STAKEY - Key for direct link communication to + another station in infrastructure networks + CSR_WIFI_SME_KEY_TYPE_IGTK - Integrity Group Temporal Key + CSR_WIFI_SME_KEY_TYPE_CCKM - Key for Cisco Centralized Key Management + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeKeyType; +#define CSR_WIFI_SME_KEY_TYPE_GROUP ((CsrWifiSmeKeyType) 0x00) +#define CSR_WIFI_SME_KEY_TYPE_PAIRWISE ((CsrWifiSmeKeyType) 0x01) +#define CSR_WIFI_SME_KEY_TYPE_STAKEY ((CsrWifiSmeKeyType) 0x02) +#define CSR_WIFI_SME_KEY_TYPE_IGTK ((CsrWifiSmeKeyType) 0x03) +#define CSR_WIFI_SME_KEY_TYPE_CCKM ((CsrWifiSmeKeyType) 0x04) + +/******************************************************************************* + + NAME + CsrWifiSmeListAction + + DESCRIPTION + Identifies the type of action to be performed on a list of items + The values of this type are used across the NME/SME/Router API's and they + must be kept consistent with the corresponding types in the .xml of the + ottherinterfaces + + VALUES + CSR_WIFI_SME_LIST_ACTION_GET - Retrieve the current list of items + CSR_WIFI_SME_LIST_ACTION_ADD - Add one or more items + CSR_WIFI_SME_LIST_ACTION_REMOVE - Remove one or more items + CSR_WIFI_SME_LIST_ACTION_FLUSH - Remove all items + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeListAction; +#define CSR_WIFI_SME_LIST_ACTION_GET ((CsrWifiSmeListAction) 0x00) +#define CSR_WIFI_SME_LIST_ACTION_ADD ((CsrWifiSmeListAction) 0x01) +#define CSR_WIFI_SME_LIST_ACTION_REMOVE ((CsrWifiSmeListAction) 0x02) +#define CSR_WIFI_SME_LIST_ACTION_FLUSH ((CsrWifiSmeListAction) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeMediaStatus + + DESCRIPTION + Indicates the connection status + The values of this type are used across the NME/SME/Router API's and they + must be kept consistent with the corresponding types in the .xml of the + ottherinterfaces + + VALUES + CSR_WIFI_SME_MEDIA_STATUS_CONNECTED + - Value CSR_WIFI_SME_MEDIA_STATUS_CONNECTED can happen in two + situations: + * A network connection is established. Specifically, this is + when the MLME_ASSOCIATION completes or the first peer + relationship is established in an IBSS. In a WPA/WPA2 + network, this indicates that the stack is ready to perform + the 4-way handshake or 802.1x authentication if CSR NME + security library is not used. If CSR NME security library + is used this indicates, completion of 4way handshake or + 802.1x authentication + * The SME roams to another AP on the same ESS + During the AP operation, it indicates that the peer station + is connected to the AP and is ready for data transfer. + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED + - Value CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED can happen in + two situations: + * when the connection to a network is lost and there is no + alternative on the same ESS to roam to + * when a CSR_WIFI_SME_DISCONNECT_REQ request is issued + During AP or P2PGO operation, it indicates that the peer + station has disconnected from the AP + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeMediaStatus; +#define CSR_WIFI_SME_MEDIA_STATUS_CONNECTED ((CsrWifiSmeMediaStatus) 0x00) +#define CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED ((CsrWifiSmeMediaStatus) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSmeP2pCapability + + DESCRIPTION + Defines P2P Device Capabilities + + VALUES + CSR_WIFI_SME_P2P_SERVICE_DISCOVERY_CAPABILITY + - This field is set to 1 if the P2P Device supports Service + Discovery, and to 0 otherwise + CSR_WIFI_SME_P2P_CLIENT_DISCOVERABILITY_CAPABILITY + - This field is set to 1 when the P2P Device supports P2P + Client Discoverability, and to 0 otherwise. + CSR_WIFI_SME_P2P_CONCURRENT_OPERATION_CAPABILITY + - This field is set to 1 when the P2P Device supports + Concurrent Operation with WLAN, and to 0 otherwise. + CSR_WIFI_SME_P2P_MANAGED_DEVICE_CAPABILITY + - This field is set to 1 when the P2P interface of the P2P + Device is capable of being managed by the WLAN + (infrastructure network) based on P2P coexistence + parameters, and to 0 otherwise + CSR_WIFI_SME_P2P_INVITAION_CAPABILITY + - This field is set to 1 if the P2P Device is capable of + processing P2P Invitation Procedure signaling, and to 0 + otherwise. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pCapability; +#define CSR_WIFI_SME_P2P_SERVICE_DISCOVERY_CAPABILITY ((CsrWifiSmeP2pCapability) 0x01) +#define CSR_WIFI_SME_P2P_CLIENT_DISCOVERABILITY_CAPABILITY ((CsrWifiSmeP2pCapability) 0x02) +#define CSR_WIFI_SME_P2P_CONCURRENT_OPERATION_CAPABILITY ((CsrWifiSmeP2pCapability) 0x04) +#define CSR_WIFI_SME_P2P_MANAGED_DEVICE_CAPABILITY ((CsrWifiSmeP2pCapability) 0x08) +#define CSR_WIFI_SME_P2P_INVITAION_CAPABILITY ((CsrWifiSmeP2pCapability) 0x20) + +/******************************************************************************* + + NAME + CsrWifiSmeP2pGroupCapability + + DESCRIPTION + Define bits for P2P Group Capability + + VALUES + CSR_WIFI_P2P_GRP_CAP_GO + - Indicates if the local device has become a GO after GO + negotiation + CSR_WIFI_P2P_GRP_CAP_PERSISTENT + - Persistent group + CSR_WIFI_P2P_GRP_CAP_INTRABSS_DIST + - Intra-BSS data distribution support + CSR_WIFI_P2P_GRP_CAP_CROSS_CONN + - Support of cross connection + CSR_WIFI_P2P_GRP_CAP_PERSISTENT_RECONNECT + - Support of persistent reconnect + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pGroupCapability; +#define CSR_WIFI_P2P_GRP_CAP_GO ((CsrWifiSmeP2pGroupCapability) 0x01) +#define CSR_WIFI_P2P_GRP_CAP_PERSISTENT ((CsrWifiSmeP2pGroupCapability) 0x02) +#define CSR_WIFI_P2P_GRP_CAP_INTRABSS_DIST ((CsrWifiSmeP2pGroupCapability) 0x08) +#define CSR_WIFI_P2P_GRP_CAP_CROSS_CONN ((CsrWifiSmeP2pGroupCapability) 0x10) +#define CSR_WIFI_P2P_GRP_CAP_PERSISTENT_RECONNECT ((CsrWifiSmeP2pGroupCapability) 0x20) + +/******************************************************************************* + + NAME + CsrWifiSmeP2pNoaConfigMethod + + DESCRIPTION + Notice of Absece Configuration + + VALUES + CSR_WIFI_P2P_NOA_NONE - Do not use NOA + CSR_WIFI_P2P_NOA_AUTONOMOUS - NOA based on the traffic analysis + CSR_WIFI_P2P_NOA_USER_DEFINED - NOA as specified by the user + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pNoaConfigMethod; +#define CSR_WIFI_P2P_NOA_NONE ((CsrWifiSmeP2pNoaConfigMethod) 0x00) +#define CSR_WIFI_P2P_NOA_AUTONOMOUS ((CsrWifiSmeP2pNoaConfigMethod) 0x01) +#define CSR_WIFI_P2P_NOA_USER_DEFINED ((CsrWifiSmeP2pNoaConfigMethod) 0x02) + +/******************************************************************************* + + NAME + CsrWifiSmeP2pRole + + DESCRIPTION + Definition of roles for a P2P Device + + VALUES + CSR_WIFI_SME_P2P_ROLE_NONE - A non-P2PDevice device + CSR_WIFI_SME_P2P_ROLE_STANDALONE - A Standalone P2P device + CSR_WIFI_SME_P2P_ROLE_GO - Role Assumed is that of a Group Owner + within a P2P Group + CSR_WIFI_SME_P2P_ROLE_CLI - Role Assumed is that of a P2P Client + within a P2P Group + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pRole; +#define CSR_WIFI_SME_P2P_ROLE_NONE ((CsrWifiSmeP2pRole) 0x00) +#define CSR_WIFI_SME_P2P_ROLE_STANDALONE ((CsrWifiSmeP2pRole) 0x01) +#define CSR_WIFI_SME_P2P_ROLE_GO ((CsrWifiSmeP2pRole) 0x02) +#define CSR_WIFI_SME_P2P_ROLE_CLI ((CsrWifiSmeP2pRole) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeP2pStatus + + DESCRIPTION + This data type enumerates the outcome of P2P procedure + + VALUES + CSR_WIFI_SME_P2P_STATUS_SUCCESS + - Success + CSR_WIFI_SME_P2P_STATUS_FAIL_INFO_UNAVAILABLE + - Fail; information is currently unavailable + CSR_WIFI_SME_P2P_STATUS_FAIL_INCOMPATIBLE_PARAM + - Fail; incompatible parameters + CSR_WIFI_SME_P2P_STATUS_FAIL_LIMIT_REACHED + - Fail; limit reached + CSR_WIFI_SME_P2P_STATUS_FAIL_INVALID_PARAM + - Fail; invalid parameters + CSR_WIFI_SME_P2P_STATUS_FAIL_ACCOMODATE + - Fail; unable to accommodate request + CSR_WIFI_SME_P2P_STATUS_FAIL_PREV_ERROR + - Fail; previous protocol error, or disruptive behavior + CSR_WIFI_SME_P2P_STATUS_FAIL_COMMON_CHANNELS + - Fail; no common channels + CSR_WIFI_SME_P2P_STATUS_FAIL_UNKNOWN_GROUP + - Fail; unknown P2P Group + CSR_WIFI_SME_P2P_STATUS_FAIL_GO_INTENT + - Fail: both P2P Devices indicated an Intent of 15 in Group + Owner Negotiation + CSR_WIFI_SME_P2P_STATUS_FAIL_PROVISION_METHOD_INCOMPATIBLE + - Fail; incompatible provisioning method + CSR_WIFI_SME_P2P_STATUS_FAIL_REJECT + - Fail: rejected by user + CSR_WIFI_SME_P2P_STATUS_FAIL_RESERVED + - Fail; Status Reserved + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pStatus; +#define CSR_WIFI_SME_P2P_STATUS_SUCCESS ((CsrWifiSmeP2pStatus) 0x00) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_INFO_UNAVAILABLE ((CsrWifiSmeP2pStatus) 0x01) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_INCOMPATIBLE_PARAM ((CsrWifiSmeP2pStatus) 0x02) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_LIMIT_REACHED ((CsrWifiSmeP2pStatus) 0x03) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_INVALID_PARAM ((CsrWifiSmeP2pStatus) 0x04) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_ACCOMODATE ((CsrWifiSmeP2pStatus) 0x05) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_PREV_ERROR ((CsrWifiSmeP2pStatus) 0x06) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_COMMON_CHANNELS ((CsrWifiSmeP2pStatus) 0x07) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_UNKNOWN_GROUP ((CsrWifiSmeP2pStatus) 0x08) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_GO_INTENT ((CsrWifiSmeP2pStatus) 0x09) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_PROVISION_METHOD_INCOMPATIBLE ((CsrWifiSmeP2pStatus) 0x0A) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_REJECT ((CsrWifiSmeP2pStatus) 0x0B) +#define CSR_WIFI_SME_P2P_STATUS_FAIL_RESERVED ((CsrWifiSmeP2pStatus) 0xFF) + +/******************************************************************************* + + NAME + CsrWifiSmePacketFilterMode + + DESCRIPTION + Options for the filter mode parameter. + The Values here match the HIP interface + + VALUES + CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_OUT + - Broadcast packets are always reported to the host unless + they match at least one of the specified TCLAS IEs. + CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_IN + - Broadcast packets are reported to the host only if they + match at least one of the specified TCLAS IEs. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmePacketFilterMode; +#define CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_OUT ((CsrWifiSmePacketFilterMode) 0x00) +#define CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_IN ((CsrWifiSmePacketFilterMode) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmePowerSaveLevel + + DESCRIPTION + Power Save Level options as defined in the IEEE 802.11 standards + First 3 values are set to match the mlme PowerManagementMode + + VALUES + CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW - No power save: the driver will remain + active at all times + CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH - Enter power save after all packets in + the queues are transmitted and received + CSR_WIFI_SME_POWER_SAVE_LEVEL_MED - Enter power save after all packets in + the queues are transmitted and received + and a further configurable delay + (default 1s) has elapsed + CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO - The SME will decide when to enter power + save mode according to the traffic + analysis + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmePowerSaveLevel; +#define CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW ((CsrWifiSmePowerSaveLevel) 0x00) +#define CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH ((CsrWifiSmePowerSaveLevel) 0x01) +#define CSR_WIFI_SME_POWER_SAVE_LEVEL_MED ((CsrWifiSmePowerSaveLevel) 0x02) +#define CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO ((CsrWifiSmePowerSaveLevel) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmePreambleType + + DESCRIPTION + SME Preamble Types + + VALUES + CSR_WIFI_SME_USE_LONG_PREAMBLE - Use legacy (long) preamble + CSR_WIFI_SME_USE_SHORT_PREAMBLE - Use short PPDU format + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmePreambleType; +#define CSR_WIFI_SME_USE_LONG_PREAMBLE ((CsrWifiSmePreambleType) 0x00) +#define CSR_WIFI_SME_USE_SHORT_PREAMBLE ((CsrWifiSmePreambleType) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSmeRadioIF + + DESCRIPTION + Indicates the frequency + + VALUES + CSR_WIFI_SME_RADIO_IF_GHZ_2_4 - Indicates the 2.4 GHZ frequency + CSR_WIFI_SME_RADIO_IF_GHZ_5_0 - Future use: currently not supported + CSR_WIFI_SME_RADIO_IF_BOTH - Future use: currently not supported + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeRadioIF; +#define CSR_WIFI_SME_RADIO_IF_GHZ_2_4 ((CsrWifiSmeRadioIF) 0x01) +#define CSR_WIFI_SME_RADIO_IF_GHZ_5_0 ((CsrWifiSmeRadioIF) 0x02) +#define CSR_WIFI_SME_RADIO_IF_BOTH ((CsrWifiSmeRadioIF) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeRegulatoryDomain + + DESCRIPTION + Indicates the regulatory domain as defined in IEEE 802.11 standards + + VALUES + CSR_WIFI_SME_REGULATORY_DOMAIN_OTHER + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_FCC + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_IC + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_ETSI + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_SPAIN + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_FRANCE + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_JAPAN + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_JAPANBIS + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_CHINA + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_CHINABIS + - See IEEE 802.11 Standard + CSR_WIFI_SME_REGULATORY_DOMAIN_NONE + - See IEEE 802.11 Standard + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeRegulatoryDomain; +#define CSR_WIFI_SME_REGULATORY_DOMAIN_OTHER ((CsrWifiSmeRegulatoryDomain) 0x00) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_FCC ((CsrWifiSmeRegulatoryDomain) 0x10) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_IC ((CsrWifiSmeRegulatoryDomain) 0x20) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_ETSI ((CsrWifiSmeRegulatoryDomain) 0x30) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_SPAIN ((CsrWifiSmeRegulatoryDomain) 0x31) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_FRANCE ((CsrWifiSmeRegulatoryDomain) 0x32) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_JAPAN ((CsrWifiSmeRegulatoryDomain) 0x40) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_JAPANBIS ((CsrWifiSmeRegulatoryDomain) 0x41) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_CHINA ((CsrWifiSmeRegulatoryDomain) 0x50) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_CHINABIS ((CsrWifiSmeRegulatoryDomain) 0x51) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_NONE ((CsrWifiSmeRegulatoryDomain) 0xFF) + +/******************************************************************************* + + NAME + CsrWifiSmeRoamReason + + DESCRIPTION + Indicates the reason for roaming + + VALUES + CSR_WIFI_SME_ROAM_REASON_BEACONLOST + - The station cannot receive the beacon signal any more + CSR_WIFI_SME_ROAM_REASON_DISASSOCIATED + - The station has been disassociated + CSR_WIFI_SME_ROAM_REASON_DEAUTHENTICATED + - The station has been deauthenticated + CSR_WIFI_SME_ROAM_REASON_BETTERAPFOUND + - A better AP has been found + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeRoamReason; +#define CSR_WIFI_SME_ROAM_REASON_BEACONLOST ((CsrWifiSmeRoamReason) 0x00) +#define CSR_WIFI_SME_ROAM_REASON_DISASSOCIATED ((CsrWifiSmeRoamReason) 0x01) +#define CSR_WIFI_SME_ROAM_REASON_DEAUTHENTICATED ((CsrWifiSmeRoamReason) 0x02) +#define CSR_WIFI_SME_ROAM_REASON_BETTERAPFOUND ((CsrWifiSmeRoamReason) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeScanType + + DESCRIPTION + Identifies the type of scan to be performed + + VALUES + CSR_WIFI_SME_SCAN_TYPE_ALL - Scan actively or passively according to the + regulatory domain restrictions + CSR_WIFI_SME_SCAN_TYPE_ACTIVE - Scan actively only: send probes and listen + for answers + CSR_WIFI_SME_SCAN_TYPE_PASSIVE - Scan passively only: listen for beacon + messages + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeScanType; +#define CSR_WIFI_SME_SCAN_TYPE_ALL ((CsrWifiSmeScanType) 0x00) +#define CSR_WIFI_SME_SCAN_TYPE_ACTIVE ((CsrWifiSmeScanType) 0x01) +#define CSR_WIFI_SME_SCAN_TYPE_PASSIVE ((CsrWifiSmeScanType) 0x02) + +/******************************************************************************* + + NAME + CsrWifiSmeTrafficType + + DESCRIPTION + Identifies the type of traffic going on on the connection. + The values of this type are used across the NME/SME/Router API's and they + must be kept consistent with the corresponding types in the .xml of the + ottherinterfaces + + VALUES + CSR_WIFI_SME_TRAFFIC_TYPE_OCCASIONAL + - During the last 30 seconds there were fewer than 20 packets + per seconds in each second in both directions + CSR_WIFI_SME_TRAFFIC_TYPE_BURSTY + - During the last 30 seconds there was at least one second + during which more than 20 packets were received in either + direction + CSR_WIFI_SME_TRAFFIC_TYPE_PERIODIC + - During the last 5 seconds there were at least 10 packets + received each second and a defined period for the traffic + can be recognized + CSR_WIFI_SME_TRAFFIC_TYPE_CONTINUOUS + - During the last 5 seconds there were at least 20 packets + received each second in either direction + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeTrafficType; +#define CSR_WIFI_SME_TRAFFIC_TYPE_OCCASIONAL ((CsrWifiSmeTrafficType) 0x00) +#define CSR_WIFI_SME_TRAFFIC_TYPE_BURSTY ((CsrWifiSmeTrafficType) 0x01) +#define CSR_WIFI_SME_TRAFFIC_TYPE_PERIODIC ((CsrWifiSmeTrafficType) 0x02) +#define CSR_WIFI_SME_TRAFFIC_TYPE_CONTINUOUS ((CsrWifiSmeTrafficType) 0x03) + +/******************************************************************************* + + NAME + CsrWifiSmeTspecCtrl + + DESCRIPTION + Defines bits for CsrWifiSmeTspecCtrlMask for additional CCX configuration. + CURRENTLY NOT SUPPORTED. + + VALUES + CSR_WIFI_SME_TSPEC_CTRL_STRICT + - No automatic negotiation + CSR_WIFI_SME_TSPEC_CTRL_CCX_SIGNALLING + - Signalling TSPEC + CSR_WIFI_SME_TSPEC_CTRL_CCX_VOICE + - Voice traffic TSPEC + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeTspecCtrl; +#define CSR_WIFI_SME_TSPEC_CTRL_STRICT ((CsrWifiSmeTspecCtrl) 0x01) +#define CSR_WIFI_SME_TSPEC_CTRL_CCX_SIGNALLING ((CsrWifiSmeTspecCtrl) 0x02) +#define CSR_WIFI_SME_TSPEC_CTRL_CCX_VOICE ((CsrWifiSmeTspecCtrl) 0x04) + +/******************************************************************************* + + NAME + CsrWifiSmeTspecResultCode + + DESCRIPTION + Defines the result of the TSPEC exchanges with the AP + + VALUES + CSR_WIFI_SME_TSPEC_RESULT_SUCCESS + - TSPEC command has been processed correctly + CSR_WIFI_SME_TSPEC_RESULT_UNSPECIFIED_QOS_FAILURE + - The Access Point reported a failure + CSR_WIFI_SME_TSPEC_RESULT_FAILURE + - Internal failure in the SME + CSR_WIFI_SME_TSPEC_RESULT_INVALID_TSPEC_PARAMETERS + - The TSPEC parameters are invalid + CSR_WIFI_SME_TSPEC_RESULT_INVALID_TCLAS_PARAMETERS + - The TCLASS parameters are invalid + CSR_WIFI_SME_TSPEC_RESULT_INSUFFICIENT_BANDWIDTH + - As specified by the WMM Spec + CSR_WIFI_SME_TSPEC_RESULT_WRONG_POLICY + - As specified by the WMM Spec + CSR_WIFI_SME_TSPEC_RESULT_REJECTED_WITH_SUGGESTED_CHANGES + - As specified by the WMM Spec + CSR_WIFI_SME_TSPEC_RESULT_TIMEOUT + - The TSPEC negotiation timed out + CSR_WIFI_SME_TSPEC_RESULT_NOT_SUPPORTED + - The Access Point does not support the TSPEC + CSR_WIFI_SME_TSPEC_RESULT_IE_LENGTH_INCORRECT + - The length of the TSPEC is not correct + CSR_WIFI_SME_TSPEC_RESULT_INVALID_TRANSACTION_ID + - The TSPEC transaction id is not in the list + CSR_WIFI_SME_TSPEC_RESULT_INSTALLED + - The TSPEC has been installed and it is now active. + CSR_WIFI_SME_TSPEC_RESULT_TID_ALREADY_INSTALLED + - The Traffic ID has already been installed + CSR_WIFI_SME_TSPEC_RESULT_TSPEC_REMOTELY_DELETED + - The AP has deleted the TSPEC + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeTspecResultCode; +#define CSR_WIFI_SME_TSPEC_RESULT_SUCCESS ((CsrWifiSmeTspecResultCode) 0x00) +#define CSR_WIFI_SME_TSPEC_RESULT_UNSPECIFIED_QOS_FAILURE ((CsrWifiSmeTspecResultCode) 0x01) +#define CSR_WIFI_SME_TSPEC_RESULT_FAILURE ((CsrWifiSmeTspecResultCode) 0x02) +#define CSR_WIFI_SME_TSPEC_RESULT_INVALID_TSPEC_PARAMETERS ((CsrWifiSmeTspecResultCode) 0x05) +#define CSR_WIFI_SME_TSPEC_RESULT_INVALID_TCLAS_PARAMETERS ((CsrWifiSmeTspecResultCode) 0x06) +#define CSR_WIFI_SME_TSPEC_RESULT_INSUFFICIENT_BANDWIDTH ((CsrWifiSmeTspecResultCode) 0x07) +#define CSR_WIFI_SME_TSPEC_RESULT_WRONG_POLICY ((CsrWifiSmeTspecResultCode) 0x08) +#define CSR_WIFI_SME_TSPEC_RESULT_REJECTED_WITH_SUGGESTED_CHANGES ((CsrWifiSmeTspecResultCode) 0x09) +#define CSR_WIFI_SME_TSPEC_RESULT_TIMEOUT ((CsrWifiSmeTspecResultCode) 0x0D) +#define CSR_WIFI_SME_TSPEC_RESULT_NOT_SUPPORTED ((CsrWifiSmeTspecResultCode) 0x0E) +#define CSR_WIFI_SME_TSPEC_RESULT_IE_LENGTH_INCORRECT ((CsrWifiSmeTspecResultCode) 0x10) +#define CSR_WIFI_SME_TSPEC_RESULT_INVALID_TRANSACTION_ID ((CsrWifiSmeTspecResultCode) 0x11) +#define CSR_WIFI_SME_TSPEC_RESULT_INSTALLED ((CsrWifiSmeTspecResultCode) 0x12) +#define CSR_WIFI_SME_TSPEC_RESULT_TID_ALREADY_INSTALLED ((CsrWifiSmeTspecResultCode) 0x13) +#define CSR_WIFI_SME_TSPEC_RESULT_TSPEC_REMOTELY_DELETED ((CsrWifiSmeTspecResultCode) 0x14) + +/******************************************************************************* + + NAME + CsrWifiSmeWepAuthMode + + DESCRIPTION + Define bits for CsrWifiSmeWepAuthMode + + VALUES + CSR_WIFI_SME_WEP_AUTH_MODE_OPEN - Open-WEP enabled network + CSR_WIFI_SME_WEP_AUTH_MODE_SHARED - Shared-key WEP enabled network. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWepAuthMode; +#define CSR_WIFI_SME_WEP_AUTH_MODE_OPEN ((CsrWifiSmeWepAuthMode) 0x00) +#define CSR_WIFI_SME_WEP_AUTH_MODE_SHARED ((CsrWifiSmeWepAuthMode) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSmeWepCredentialType + + DESCRIPTION + Definition of types of WEP Credentials + + VALUES + CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64 + - WEP 64 credential + CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128 + - WEP 128 credential + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWepCredentialType; +#define CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64 ((CsrWifiSmeWepCredentialType) 0x00) +#define CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128 ((CsrWifiSmeWepCredentialType) 0x01) + +/******************************************************************************* + + NAME + CsrWifiSmeWmmMode + + DESCRIPTION + Defines bits for wmmModeMask: enable/disable WMM features. + + VALUES + CSR_WIFI_SME_WMM_MODE_DISABLED - Disables the WMM features. + CSR_WIFI_SME_WMM_MODE_AC_ENABLED - Enables support for WMM-AC. + CSR_WIFI_SME_WMM_MODE_PS_ENABLED - Enables support for WMM Power Save. + CSR_WIFI_SME_WMM_MODE_SA_ENABLED - Currently not supported + CSR_WIFI_SME_WMM_MODE_ENABLED - Enables support for all currently + available WMM features. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWmmMode; +#define CSR_WIFI_SME_WMM_MODE_DISABLED ((CsrWifiSmeWmmMode) 0x00) +#define CSR_WIFI_SME_WMM_MODE_AC_ENABLED ((CsrWifiSmeWmmMode) 0x01) +#define CSR_WIFI_SME_WMM_MODE_PS_ENABLED ((CsrWifiSmeWmmMode) 0x02) +#define CSR_WIFI_SME_WMM_MODE_SA_ENABLED ((CsrWifiSmeWmmMode) 0x04) +#define CSR_WIFI_SME_WMM_MODE_ENABLED ((CsrWifiSmeWmmMode) 0xFF) + +/******************************************************************************* + + NAME + CsrWifiSmeWmmQosInfo + + DESCRIPTION + Defines bits for the QoS Info Octect as defined in the WMM specification. + The first four values define one bit each that can be set or cleared. + Each of the last four values define all the remaining 4 bits and only one + of them at the time shall be used. + For more information, see 'WMM (including WMM Power Save) Specification - + Version 1.1' and 'UniFi Configuring WMM and WMM-PS, Application Note'. + + VALUES + CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_ALL + - WMM AP may deliver all buffered frames + CSR_WIFI_SME_WMM_QOS_INFO_AC_VO + - Enable UAPSD(both trigger and delivery) for Voice Access + Category + CSR_WIFI_SME_WMM_QOS_INFO_AC_VI + - Enable UAPSD(both trigger and delivery) for Video Access + Category + CSR_WIFI_SME_WMM_QOS_INFO_AC_BK + - Enable UAPSD(both trigger and delivery) for Background + Access Category + CSR_WIFI_SME_WMM_QOS_INFO_AC_BE + - Enable UAPSD(both trigger and delivery) for Best Effort + Access Category + CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_TWO + - WMM AP may deliver a maximum of 2 buffered frames (MSDUs + and MMPDUs) per USP + CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_FOUR + - WMM AP may deliver a maximum of 4 buffered frames (MSDUs + and MMPDUs) per USP + CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_SIX + - WMM AP may deliver a maximum of 6 buffered frames (MSDUs + and MMPDUs) per USP + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWmmQosInfo; +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_ALL ((CsrWifiSmeWmmQosInfo) 0x00) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_VO ((CsrWifiSmeWmmQosInfo) 0x01) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_VI ((CsrWifiSmeWmmQosInfo) 0x02) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_BK ((CsrWifiSmeWmmQosInfo) 0x04) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_BE ((CsrWifiSmeWmmQosInfo) 0x08) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_TWO ((CsrWifiSmeWmmQosInfo) 0x20) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_FOUR ((CsrWifiSmeWmmQosInfo) 0x40) +#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_SIX ((CsrWifiSmeWmmQosInfo) 0x60) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfigType + + DESCRIPTION + WPS config methods supported/used by a device + + VALUES + CSR_WIFI_WPS_CONFIG_LABEL + - Label + CSR_WIFI_WPS_CONFIG_DISPLAY + - Display + CSR_WIFI_WPS_CONFIG_EXT_NFC + - External NFC : Not supported in this release + CSR_WIFI_WPS_CONFIG_INT_NFC + - Internal NFC : Not supported in this release + CSR_WIFI_WPS_CONFIG_NFC_IFACE + - NFC interface : Not supported in this release + CSR_WIFI_WPS_CONFIG_PBC + - PBC + CSR_WIFI_WPS_CONFIG_KEYPAD + - KeyPad + CSR_WIFI_WPS_CONFIG_VIRTUAL_PBC + - PBC through software user interface + CSR_WIFI_WPS_CONFIG_PHYSICAL_PBC + - Physical PBC + CSR_WIFI_WPS_CONFIG_VIRTUAL_DISPLAY + - Virtual Display : via html config page etc + CSR_WIFI_WPS_CONFIG_PHYSICAL_DISPLAY + - Physical Display : Attached to the device + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeWpsConfigType; +#define CSR_WIFI_WPS_CONFIG_LABEL ((CsrWifiSmeWpsConfigType) 0x0004) +#define CSR_WIFI_WPS_CONFIG_DISPLAY ((CsrWifiSmeWpsConfigType) 0x0008) +#define CSR_WIFI_WPS_CONFIG_EXT_NFC ((CsrWifiSmeWpsConfigType) 0x0010) +#define CSR_WIFI_WPS_CONFIG_INT_NFC ((CsrWifiSmeWpsConfigType) 0x0020) +#define CSR_WIFI_WPS_CONFIG_NFC_IFACE ((CsrWifiSmeWpsConfigType) 0x0040) +#define CSR_WIFI_WPS_CONFIG_PBC ((CsrWifiSmeWpsConfigType) 0x0080) +#define CSR_WIFI_WPS_CONFIG_KEYPAD ((CsrWifiSmeWpsConfigType) 0x0100) +#define CSR_WIFI_WPS_CONFIG_VIRTUAL_PBC ((CsrWifiSmeWpsConfigType) 0x0280) +#define CSR_WIFI_WPS_CONFIG_PHYSICAL_PBC ((CsrWifiSmeWpsConfigType) 0x0480) +#define CSR_WIFI_WPS_CONFIG_VIRTUAL_DISPLAY ((CsrWifiSmeWpsConfigType) 0x2008) +#define CSR_WIFI_WPS_CONFIG_PHYSICAL_DISPLAY ((CsrWifiSmeWpsConfigType) 0x4008) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsDeviceCategory + + DESCRIPTION + Wps Primary Device Types + + VALUES + CSR_WIFI_SME_WPS_CATEGORY_UNSPECIFIED + - Unspecified. + CSR_WIFI_SME_WPS_CATEGORY_COMPUTER + - Computer. + CSR_WIFI_SME_WPS_CATEGORY_INPUT_DEV + - Input device + CSR_WIFI_SME_WPS_CATEGORY_PRT_SCAN_FX_CP + - Printer Scanner Fax Copier etc + CSR_WIFI_SME_WPS_CATEGORY_CAMERA + - Camera + CSR_WIFI_SME_WPS_CATEGORY_STORAGE + - Storage + CSR_WIFI_SME_WPS_CATEGORY_NET_INFRA + - Net Infra + CSR_WIFI_SME_WPS_CATEGORY_DISPLAY + - Display + CSR_WIFI_SME_WPS_CATEGORY_MULTIMEDIA + - Multimedia + CSR_WIFI_SME_WPS_CATEGORY_GAMING + - Gaming. + CSR_WIFI_SME_WPS_CATEGORY_TELEPHONE + - Telephone. + CSR_WIFI_SME_WPS_CATEGORY_AUDIO + - Audio + CSR_WIFI_SME_WPS_CATEOARY_OTHERS + - Others. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWpsDeviceCategory; +#define CSR_WIFI_SME_WPS_CATEGORY_UNSPECIFIED ((CsrWifiSmeWpsDeviceCategory) 0x00) +#define CSR_WIFI_SME_WPS_CATEGORY_COMPUTER ((CsrWifiSmeWpsDeviceCategory) 0x01) +#define CSR_WIFI_SME_WPS_CATEGORY_INPUT_DEV ((CsrWifiSmeWpsDeviceCategory) 0x02) +#define CSR_WIFI_SME_WPS_CATEGORY_PRT_SCAN_FX_CP ((CsrWifiSmeWpsDeviceCategory) 0x03) +#define CSR_WIFI_SME_WPS_CATEGORY_CAMERA ((CsrWifiSmeWpsDeviceCategory) 0x04) +#define CSR_WIFI_SME_WPS_CATEGORY_STORAGE ((CsrWifiSmeWpsDeviceCategory) 0x05) +#define CSR_WIFI_SME_WPS_CATEGORY_NET_INFRA ((CsrWifiSmeWpsDeviceCategory) 0x06) +#define CSR_WIFI_SME_WPS_CATEGORY_DISPLAY ((CsrWifiSmeWpsDeviceCategory) 0x07) +#define CSR_WIFI_SME_WPS_CATEGORY_MULTIMEDIA ((CsrWifiSmeWpsDeviceCategory) 0x08) +#define CSR_WIFI_SME_WPS_CATEGORY_GAMING ((CsrWifiSmeWpsDeviceCategory) 0x09) +#define CSR_WIFI_SME_WPS_CATEGORY_TELEPHONE ((CsrWifiSmeWpsDeviceCategory) 0x0A) +#define CSR_WIFI_SME_WPS_CATEGORY_AUDIO ((CsrWifiSmeWpsDeviceCategory) 0x0B) +#define CSR_WIFI_SME_WPS_CATEOARY_OTHERS ((CsrWifiSmeWpsDeviceCategory) 0xFF) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsDeviceSubCategory + + DESCRIPTION + Wps Secondary Device Types + + VALUES + CSR_WIFI_SME_WPS_SUB_CATEGORY_UNSPECIFIED + - Unspecied + CSR_WIFI_SME_WPS_STORAGE_SUB_CATEGORY_NAS + - Network Associated Storage + CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_PRNTR + - Printer or print server + CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_WM + - Windows mobile + CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_TUNER + - Audio tuner/receiver + CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_DIG_STL + - Digital still camera + CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_AP + - Access Point + CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_TV + - TV. + CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_DAR + - DAR. + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_KEYBD + - Keyboard. + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_PC + - PC. + CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX + - Xbox. + CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_SCNR + - Scanner + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_SERVER + - Server + CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_ROUTER + - Router + CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_PVR + - PVR + CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_SPEAKER + - Speaker + CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_SM + - Feature phone - Single mode + CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_VIDEO + - Video camera + CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PIC_FRM + - Picture frame + CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX_360 + - Xbox360 + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_MOUSE + - Mouse + CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_SWITCH + - Switch + CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_PMP + - Portable music player + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_JOYSTK + - Joy stick + CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PLAY_STN + - Play-station + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MED_CENT + - Media Center + CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MCX + - MCX + CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_DM + - Feature phone - Dual mode + CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_WEB + - Web camera + CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_FAX + - Fax + CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PROJECTOR + - Projector + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TRKBL + - Track Ball + CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_ST_BOX + - Set-Top-Box + CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_GATEWAY + - GateWay. + CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_SECURITY + - Security camera + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_ULTRA_MOB_PC + - Ultra mobile PC. + CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_CONSOLE + - Game console/Game console adapter + CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_CPR + - Copier + CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADSET + - Headset(headphones + microphone) + CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_SM + - Smart phone - Single mode + CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_MONITOR + - Monitor. + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_GAME_CTRL + - Game control. + CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_ALL + - All-in-One + CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MEDIA + - Media Server/Media Adapter/Media Extender + CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_DM + - Smart phone - Dual mode + CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PORT_DEV + - Portable gaming device + CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADPHONE + - Headphone. + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NOTEBOOK + - Notebook. + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_REMOTE + - Remote control + CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_MIC + - Microphone + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_DESKTOP + - Desktop. + CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_VP + - Portable video player + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MID + - Mobile internet device + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TOUCH_SCRN + - Touch screen + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BIOMET_RDR + - Biometric reader + CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NETBOOK + - Netbook + CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BRCD_RDR + - Bar code reader. + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWpsDeviceSubCategory; +#define CSR_WIFI_SME_WPS_SUB_CATEGORY_UNSPECIFIED ((CsrWifiSmeWpsDeviceSubCategory) 0x00) +#define CSR_WIFI_SME_WPS_STORAGE_SUB_CATEGORY_NAS ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_PRNTR ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_WM ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_TUNER ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_DIG_STL ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_AP ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_TV ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_DAR ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_KEYBD ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_PC ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX ((CsrWifiSmeWpsDeviceSubCategory) 0x01) +#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_SCNR ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_SERVER ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_ROUTER ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_PVR ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_SPEAKER ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_SM ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_VIDEO ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PIC_FRM ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX_360 ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_MOUSE ((CsrWifiSmeWpsDeviceSubCategory) 0x02) +#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_SWITCH ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_PMP ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_JOYSTK ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PLAY_STN ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MED_CENT ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MCX ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_DM ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_WEB ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_FAX ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PROJECTOR ((CsrWifiSmeWpsDeviceSubCategory) 0x03) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TRKBL ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_ST_BOX ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_GATEWAY ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_SECURITY ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_ULTRA_MOB_PC ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_CONSOLE ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_CPR ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADSET ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_SM ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_MONITOR ((CsrWifiSmeWpsDeviceSubCategory) 0x04) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_GAME_CTRL ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_ALL ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MEDIA ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_DM ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PORT_DEV ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADPHONE ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NOTEBOOK ((CsrWifiSmeWpsDeviceSubCategory) 0x05) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_REMOTE ((CsrWifiSmeWpsDeviceSubCategory) 0x06) +#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_MIC ((CsrWifiSmeWpsDeviceSubCategory) 0x06) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_DESKTOP ((CsrWifiSmeWpsDeviceSubCategory) 0x06) +#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_VP ((CsrWifiSmeWpsDeviceSubCategory) 0x06) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MID ((CsrWifiSmeWpsDeviceSubCategory) 0x07) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TOUCH_SCRN ((CsrWifiSmeWpsDeviceSubCategory) 0x07) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BIOMET_RDR ((CsrWifiSmeWpsDeviceSubCategory) 0x08) +#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NETBOOK ((CsrWifiSmeWpsDeviceSubCategory) 0x08) +#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BRCD_RDR ((CsrWifiSmeWpsDeviceSubCategory) 0x09) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsDpid + + DESCRIPTION + Device Password ID for the chosen config method + + VALUES + CSR_WIFI_SME_WPS_DPID_PIN - PIN + CSR_WIFI_SME_WPS_DPID_USER - User specified : Used only during P2P GO + negotiation procedure + CSR_WIFI_SME_WPS_DPID_MACHINE - Machine specified i: Not used in this + release + CSR_WIFI_SME_WPS_DPID_REKEY - Rekey : Not used in this release + CSR_WIFI_SME_WPS_DPID_PBC - PBC + CSR_WIFI_SME_WPS_DPID_REGISTRAR - Registrar specified : Used only in P2P Go + negotiation procedure + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeWpsDpid; +#define CSR_WIFI_SME_WPS_DPID_PIN ((CsrWifiSmeWpsDpid) 0x0000) +#define CSR_WIFI_SME_WPS_DPID_USER ((CsrWifiSmeWpsDpid) 0x0001) +#define CSR_WIFI_SME_WPS_DPID_MACHINE ((CsrWifiSmeWpsDpid) 0x0002) +#define CSR_WIFI_SME_WPS_DPID_REKEY ((CsrWifiSmeWpsDpid) 0x0003) +#define CSR_WIFI_SME_WPS_DPID_PBC ((CsrWifiSmeWpsDpid) 0x0004) +#define CSR_WIFI_SME_WPS_DPID_REGISTRAR ((CsrWifiSmeWpsDpid) 0x0005) + +/******************************************************************************* + + NAME + CsrWifiSmeWpsRegistration + + DESCRIPTION + + VALUES + CSR_WIFI_SME_WPS_REG_NOT_REQUIRED - No encryption set + CSR_WIFI_SME_WPS_REG_REQUIRED - No encryption set + CSR_WIFI_SME_WPS_REG_UNKNOWN - No encryption set + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWpsRegistration; +#define CSR_WIFI_SME_WPS_REG_NOT_REQUIRED ((CsrWifiSmeWpsRegistration) 0x00) +#define CSR_WIFI_SME_WPS_REG_REQUIRED ((CsrWifiSmeWpsRegistration) 0x01) +#define CSR_WIFI_SME_WPS_REG_UNKNOWN ((CsrWifiSmeWpsRegistration) 0x02) + + +/******************************************************************************* + + NAME + CsrWifiSmeAuthModeMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeAuthMode + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeAuthModeMask; +/******************************************************************************* + + NAME + CsrWifiSmeEncryptionMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeEncryption + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeEncryptionMask; +/******************************************************************************* + + NAME + CsrWifiSmeIndicationsMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeIndications + +*******************************************************************************/ +typedef CsrUint32 CsrWifiSmeIndicationsMask; +/******************************************************************************* + + NAME + CsrWifiSmeP2pCapabilityMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeP2pCapability + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pCapabilityMask; +/******************************************************************************* + + NAME + CsrWifiSmeP2pGroupCapabilityMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeP2pGroupCapability + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeP2pGroupCapabilityMask; +/******************************************************************************* + + NAME + CsrWifiSmeTspecCtrlMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeTspecCtrl + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeTspecCtrlMask; +/******************************************************************************* + + NAME + CsrWifiSmeWmmModeMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeWmmMode + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWmmModeMask; +/******************************************************************************* + + NAME + CsrWifiSmeWmmQosInfoMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeWmmQosInfo + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeWmmQosInfoMask; +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfigTypeMask + + DESCRIPTION + Mask type for use with the values defined by CsrWifiSmeWpsConfigType + +*******************************************************************************/ +typedef CsrUint16 CsrWifiSmeWpsConfigTypeMask; + + +/******************************************************************************* + + NAME + CsrWifiSmeAdHocConfig + + DESCRIPTION + Defines values to use when starting an Ad-hoc (IBSS) network. + + MEMBERS + atimWindowTu - ATIM window specified for IBSS + beaconPeriodTu - Interval between beacon packets + joinOnlyAttempts - Maximum number of attempts to join an ad-hoc network. + The default value is 1. + Set to 0 for infinite attempts. + joinAttemptIntervalMs - Time between scans for joining the requested IBSS. + +*******************************************************************************/ +typedef struct +{ + CsrUint16 atimWindowTu; + CsrUint16 beaconPeriodTu; + CsrUint16 joinOnlyAttempts; + CsrUint16 joinAttemptIntervalMs; +} CsrWifiSmeAdHocConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeAvailabilityConfig + + DESCRIPTION + + MEMBERS + listenChannel - + availabilityDuration - + avalabilityPeriod - + +*******************************************************************************/ +typedef struct +{ + CsrUint8 listenChannel; + CsrUint16 availabilityDuration; + CsrUint16 avalabilityPeriod; +} CsrWifiSmeAvailabilityConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfig + + DESCRIPTION + This type is reserved for future use and should not be used. + + MEMBERS + keepAliveTimeMs - NOT USED + apRoamingEnabled - NOT USED + measurementsMask - NOT USED + ccxRadioMgtEnabled - NOT USED + +*******************************************************************************/ +typedef struct +{ + CsrUint8 keepAliveTimeMs; + CsrBool apRoamingEnabled; + CsrUint8 measurementsMask; + CsrBool ccxRadioMgtEnabled; +} CsrWifiSmeCcxConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfig + + DESCRIPTION + Parameters for the coexistence behaviour. + + MEMBERS + coexEnableSchemeManagement - Enables the Coexistence Management Scheme + coexPeriodicWakeHost - If TRUE the firmware wakes up the host + periodically according to the traffic + period and latency parameters; the host + will then send the data to transmit only + when woken up. + If FALSE, the firmware does not wake up the + host and the host will send the data to + transmit to the firmware whenever there is + data to transmit + coexTrafficBurstyLatencyMs - Period of awakening for the firmware used + when bursty traffic is detected + coexTrafficContinuousLatencyMs - Period of awakening for the firmware used + when continuous traffic is detected + coexObexBlackoutDurationMs - Blackout Duration when a Obex Connection is + used + coexObexBlackoutPeriodMs - Blackout Period when a Obex Connection is + used + coexA2dpBrBlackoutDurationMs - Blackout Duration when a Basic Rate A2DP + Connection streaming data + coexA2dpBrBlackoutPeriodMs - Blackout Period when a Basic Rate A2DP + Connection streaming data + coexA2dpEdrBlackoutDurationMs - Blackout Duration when an Enhanced Data + Rate A2DP Connection streaming data + coexA2dpEdrBlackoutPeriodMs - Blackout Period when an Enhanced Data Rate + A2DP Connection streaming data + coexPagingBlackoutDurationMs - Blackout Duration when a BT page is active + coexPagingBlackoutPeriodMs - Blackout Period when a BT page is active + coexInquiryBlackoutDurationMs - Blackout Duration when a BT inquiry is + active + coexInquiryBlackoutPeriodMs - Blackout Period when a BT inquiry is active + +*******************************************************************************/ +typedef struct +{ + CsrBool coexEnableSchemeManagement; + CsrBool coexPeriodicWakeHost; + CsrUint16 coexTrafficBurstyLatencyMs; + CsrUint16 coexTrafficContinuousLatencyMs; + CsrUint16 coexObexBlackoutDurationMs; + CsrUint16 coexObexBlackoutPeriodMs; + CsrUint16 coexA2dpBrBlackoutDurationMs; + CsrUint16 coexA2dpBrBlackoutPeriodMs; + CsrUint16 coexA2dpEdrBlackoutDurationMs; + CsrUint16 coexA2dpEdrBlackoutPeriodMs; + CsrUint16 coexPagingBlackoutDurationMs; + CsrUint16 coexPagingBlackoutPeriodMs; + CsrUint16 coexInquiryBlackoutDurationMs; + CsrUint16 coexInquiryBlackoutPeriodMs; +} CsrWifiSmeCoexConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionStats + + DESCRIPTION + Indicates the statistics of the connection. + The dot11 fields are defined in the Annex D of the IEEE 802.11 standard. + + MEMBERS + unifiTxDataRate + - The bit rate currently in use for transmissions of unicast + data frames; a data rate in units of 500kbit/s. + On an infrastructure BSS, this is the data rate used in + communicating with the associated access point; if there is + none, an error is returned. + On an IBSS, this is the data rate used for the last + transmission of a unicast data frame to any station in the + IBSS. If no such transmission has been made, an error is + returned. + unifiRxDataRate + - As above for receiving data + dot11RetryCount + - See IEEE 802.11 Standard + dot11MultipleRetryCount + - See IEEE 802.11 Standard + dot11AckFailureCount + - See IEEE 802.11 Standard + dot11FrameDuplicateCount + - See IEEE 802.11 Standard + dot11FcsErrorCount + - See IEEE 802.11 Standard + dot11RtsSuccessCount + - See IEEE 802.11 Standard + dot11RtsFailureCount + - See IEEE 802.11 Standard + dot11FailedCount + - See IEEE 802.11 Standard + dot11TransmittedFragmentCount + - See IEEE 802.11 Standard + dot11TransmittedFrameCount + - See IEEE 802.11 Standard + dot11WepExcludedCount + - See IEEE 802.11 Standard + dot11WepIcvErrorCount + - See IEEE 802.11 Standard + dot11WepUndecryptableCount + - See IEEE 802.11 Standard + dot11MulticastReceivedFrameCount + - See IEEE 802.11 Standard + dot11MulticastTransmittedFrameCount + - See IEEE 802.11 Standard + dot11ReceivedFragmentCount + - See IEEE 802.11 Standard + dot11Rsna4WayHandshakeFailures + - See IEEE 802.11 Standard + dot11RsnaTkipCounterMeasuresInvoked + - See IEEE 802.11 Standard + dot11RsnaStatsTkipLocalMicFailures + - See IEEE 802.11 Standard + dot11RsnaStatsTkipReplays + - See IEEE 802.11 Standard + dot11RsnaStatsTkipIcvErrors + - See IEEE 802.11 Standard + dot11RsnaStatsCcmpReplays + - See IEEE 802.11 Standard + dot11RsnaStatsCcmpDecryptErrors + - See IEEE 802.11 Standard + +*******************************************************************************/ +typedef struct +{ + CsrUint8 unifiTxDataRate; + CsrUint8 unifiRxDataRate; + CsrUint32 dot11RetryCount; + CsrUint32 dot11MultipleRetryCount; + CsrUint32 dot11AckFailureCount; + CsrUint32 dot11FrameDuplicateCount; + CsrUint32 dot11FcsErrorCount; + CsrUint32 dot11RtsSuccessCount; + CsrUint32 dot11RtsFailureCount; + CsrUint32 dot11FailedCount; + CsrUint32 dot11TransmittedFragmentCount; + CsrUint32 dot11TransmittedFrameCount; + CsrUint32 dot11WepExcludedCount; + CsrUint32 dot11WepIcvErrorCount; + CsrUint32 dot11WepUndecryptableCount; + CsrUint32 dot11MulticastReceivedFrameCount; + CsrUint32 dot11MulticastTransmittedFrameCount; + CsrUint32 dot11ReceivedFragmentCount; + CsrUint32 dot11Rsna4WayHandshakeFailures; + CsrUint32 dot11RsnaTkipCounterMeasuresInvoked; + CsrUint32 dot11RsnaStatsTkipLocalMicFailures; + CsrUint32 dot11RsnaStatsTkipReplays; + CsrUint32 dot11RsnaStatsTkipIcvErrors; + CsrUint32 dot11RsnaStatsCcmpReplays; + CsrUint32 dot11RsnaStatsCcmpDecryptErrors; +} CsrWifiSmeConnectionStats; + +/******************************************************************************* + + NAME + CsrWifiSmeDataBlock + + DESCRIPTION + Holds a generic data block to be passed through the interface + + MEMBERS + length - Length of the data block + data - Points to the first byte of the data block + +*******************************************************************************/ +typedef struct +{ + CsrUint16 length; + CsrUint8 *data; +} CsrWifiSmeDataBlock; + +/******************************************************************************* + + NAME + CsrWifiSmeEmpty + + DESCRIPTION + Empty Structure to indicate that no parameters are available. + + MEMBERS + empty - Only element of the empty structure (always set to 0). + +*******************************************************************************/ +typedef struct +{ + CsrUint8 empty; +} CsrWifiSmeEmpty; + +/******************************************************************************* + + NAME + CsrWifiSmeLinkQuality + + DESCRIPTION + Indicates the quality of the link + + MEMBERS + unifiRssi - Indicates the received signal strength indication of the link in + dBm + unifiSnr - Indicates the signal to noise ratio of the link in dB + +*******************************************************************************/ +typedef struct +{ + CsrInt16 unifiRssi; + CsrInt16 unifiSnr; +} CsrWifiSmeLinkQuality; + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfig + + DESCRIPTION + Allows low level configuration in the chip. + + MEMBERS + unifiFixMaxTxDataRate - This attribute is used in combination with + unifiFixTxDataRate. If it is FALSE, then + unifiFixTxDataRate specifies a specific data + rate to use. If it is TRUE, unifiFixTxDataRate + instead specifies a maximum data rate. + unifiFixTxDataRate - Transmit rate for unicast data. + See MIB description for more details + dot11RtsThreshold - See IEEE 802.11 Standard + dot11FragmentationThreshold - See IEEE 802.11 Standard + dot11CurrentTxPowerLevel - See IEEE 802.11 Standard + +*******************************************************************************/ +typedef struct +{ + CsrBool unifiFixMaxTxDataRate; + CsrUint8 unifiFixTxDataRate; + CsrUint16 dot11RtsThreshold; + CsrUint16 dot11FragmentationThreshold; + CsrUint16 dot11CurrentTxPowerLevel; +} CsrWifiSmeMibConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeP2pProfileIdentity + + DESCRIPTION + Details to be filled in + + MEMBERS + listenChannel - + availabilityDuration - + avalabilityPeriod - + +*******************************************************************************/ +typedef struct +{ + CsrUint8 listenChannel; + CsrUint16 availabilityDuration; + CsrUint16 avalabilityPeriod; +} CsrWifiSmeP2pProfileIdentity; + +/******************************************************************************* + + NAME + CsrWifiSmePmkid + + DESCRIPTION + Defines a PMKID association with BSS + + MEMBERS + bssid - BSS identifier + pmkid - PMKID + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress bssid; + CsrUint8 pmkid[16]; +} CsrWifiSmePmkid; + +/******************************************************************************* + + NAME + CsrWifiSmePmkidCandidate + + DESCRIPTION + Information for a PMKID candidate + + MEMBERS + bssid - BSS identifier + preAuthAllowed - Indicates whether preauthentication is allowed + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress bssid; + CsrBool preAuthAllowed; +} CsrWifiSmePmkidCandidate; + +/******************************************************************************* + + NAME + CsrWifiSmePmkidList + + DESCRIPTION + NOT USED + Used in the Sync access API + + MEMBERS + pmkidsCount - Number of PMKIDs in the list + pmkids - Points to the first PMKID in the list + +*******************************************************************************/ +typedef struct +{ + CsrUint8 pmkidsCount; + CsrWifiSmePmkid *pmkids; +} CsrWifiSmePmkidList; + +/******************************************************************************* + + NAME + CsrWifiSmeRegulatoryDomainInfo + + DESCRIPTION + Regulatory domain options. + + MEMBERS + dot11MultiDomainCapabilityImplemented + - TRUE is the multi domain capability is implemented + dot11MultiDomainCapabilityEnabled + - TRUE is the multi domain capability is enabled + currentRegulatoryDomain + - Current regulatory domain + currentCountryCode + - Current country code as defined by the IEEE 802.11 + standards + +*******************************************************************************/ +typedef struct +{ + CsrBool dot11MultiDomainCapabilityImplemented; + CsrBool dot11MultiDomainCapabilityEnabled; + CsrWifiSmeRegulatoryDomain currentRegulatoryDomain; + CsrUint8 currentCountryCode[2]; +} CsrWifiSmeRegulatoryDomainInfo; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingBandData + + DESCRIPTION + Thresholds to define one usability level category for the received signal + + MEMBERS + rssiHighThreshold - Received Signal Strength Indication upper bound in dBm + for the usability level + rssiLowThreshold - Received Signal Strength Indication lower bound in dBm + for the usability level + snrHighThreshold - Signal to Noise Ratio upper bound in dB for the + usability level + snrLowThreshold - Signal to Noise Ratio lower bound in dB for the + usability level + +*******************************************************************************/ +typedef struct +{ + CsrInt16 rssiHighThreshold; + CsrInt16 rssiLowThreshold; + CsrInt16 snrHighThreshold; + CsrInt16 snrLowThreshold; +} CsrWifiSmeRoamingBandData; + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigData + + DESCRIPTION + Configures the scanning behaviour of the driver and firmware + + MEMBERS + intervalSeconds - All the channels will be scanned once in this time + interval. + If connected, the channel scans are spread across + the interval. + If disconnected, all the channels will be scanned + together + validitySeconds - How long the scan result are cached + minActiveChannelTimeTu - Minimum time of listening on a channel being + actively scanned before leaving if no probe + responses or beacon frames have been received + maxActiveChannelTimeTu - Maximum time of listening on a channel being + actively scanned + minPassiveChannelTimeTu - Minimum time of listening on a channel being + passive scanned before leaving if no beacon frames + have been received + maxPassiveChannelTimeTu - Maximum time of listening on a channel being + passively scanned + +*******************************************************************************/ +typedef struct +{ + CsrUint16 intervalSeconds; + CsrUint16 validitySeconds; + CsrUint16 minActiveChannelTimeTu; + CsrUint16 maxActiveChannelTimeTu; + CsrUint16 minPassiveChannelTimeTu; + CsrUint16 maxPassiveChannelTimeTu; +} CsrWifiSmeScanConfigData; + +/******************************************************************************* + + NAME + CsrWifiSmeStaConfig + + DESCRIPTION + Station configuration options in the SME + + MEMBERS + connectionQualityRssiChangeTrigger - Sets the difference of RSSI + measurements which triggers reports + from the Firmware + connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements + which triggers reports from the + Firmware + wmmModeMask - Mask containing one or more values from + CsrWifiSmeWmmMode + ifIndex - Indicates the band of frequencies used + allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise + keys if no pairwise key is specified + enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key + Caching feature + +*******************************************************************************/ +typedef struct +{ + CsrUint8 connectionQualityRssiChangeTrigger; + CsrUint8 connectionQualitySnrChangeTrigger; + CsrUint8 wmmModeMask; + CsrWifiSmeRadioIF ifIndex; + CsrBool allowUnicastUseGroupCipher; + CsrBool enableOpportunisticKeyCaching; +} CsrWifiSmeStaConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeTsfTime + + DESCRIPTION + Time stamp representation + + MEMBERS + data - TSF Bytes + +*******************************************************************************/ +typedef struct +{ + CsrUint8 data[8]; +} CsrWifiSmeTsfTime; + +/******************************************************************************* + + NAME + CsrWifiSmeVersions + + DESCRIPTION + Reports version information for the chip, the firmware and the driver and + the SME. + + MEMBERS + chipId - Chip ID + chipVersion - Chip version ID + firmwareBuild - Firmware Rom build number + firmwarePatch - Firmware Patch build number (if applicable) + firmwareHip - Firmware HIP protocol version number + routerBuild - Router build number + routerHip - Router HIP protocol version number + smeBuild - SME build number + smeHip - SME HIP protocol version number + +*******************************************************************************/ +typedef struct +{ + CsrUint32 chipId; + CsrUint32 chipVersion; + CsrUint32 firmwareBuild; + CsrUint32 firmwarePatch; + CsrUint32 firmwareHip; + CsrCharString *routerBuild; + CsrUint32 routerHip; + CsrCharString *smeBuild; + CsrUint32 smeHip; +} CsrWifiSmeVersions; + +/******************************************************************************* + + NAME + CsrWifiSmeWmmAcParams + + DESCRIPTION + Structure holding WMM AC params data. + + MEMBERS + cwMin - Exponent for the calculation of CWmin. Range: 0 + to 15 + cwMax - Exponent for the calculation of CWmax. Range: 0 + to15 + aifs - Arbitration Inter Frame Spacing in terms of + number of timeslots. Range 2 to 15 + txopLimit - TXOP Limit in the units of 32 microseconds + admissionControlMandatory - Indicates whether the admission control is + mandatory or not. Current release does not + support admission control , hence shall be set + to FALSE. + +*******************************************************************************/ +typedef struct +{ + CsrUint8 cwMin; + CsrUint8 cwMax; + CsrUint8 aifs; + CsrUint16 txopLimit; + CsrBool admissionControlMandatory; +} CsrWifiSmeWmmAcParams; + +/******************************************************************************* + + NAME + CsrWifiSmeWpsDeviceType + + DESCRIPTION + Structure holding AP WPS device type data. + + MEMBERS + deviceDetails - category , sub category etc + +*******************************************************************************/ +typedef struct +{ + CsrUint8 deviceDetails[8]; +} CsrWifiSmeWpsDeviceType; + +/******************************************************************************* + + NAME + CsrWifiSmeWpsDeviceTypeCommon + + DESCRIPTION + + MEMBERS + spportWps - + deviceType - + +*******************************************************************************/ +typedef struct +{ + CsrBool spportWps; + CsrUint8 deviceType; +} CsrWifiSmeWpsDeviceTypeCommon; + +/******************************************************************************* + + NAME + CsrWifiSmeWpsInfo + + DESCRIPTION + + MEMBERS + version - + configMethods - + devicePassworId - + +*******************************************************************************/ +typedef struct +{ + CsrUint16 version; + CsrUint16 configMethods; + CsrUint16 devicePassworId; +} CsrWifiSmeWpsInfo; + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidConfig + + DESCRIPTION + List of cloaked SSIDs . + + MEMBERS + cloakedSsidsCount - Number of cloaked SSID + cloakedSsids - Points to the first byte of the first SSID provided + +*******************************************************************************/ +typedef struct +{ + CsrUint8 cloakedSsidsCount; + CsrWifiSsid *cloakedSsids; +} CsrWifiSmeCloakedSsidConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexInfo + + DESCRIPTION + Information and state related to coexistence. + + MEMBERS + hasTrafficData - TRUE if any Wi-Fi traffic is detected + currentTrafficType - Current type of traffic + currentPeriodMs - Period of the traffic as detected by the traffic + analysis. + If the traffic is not periodic, it is set to 0. + currentPowerSave - Current power save level + currentCoexPeriodMs - Period of awakening for the firmware used when + periodic traffic is detected. + If the traffic is not periodic, it is set to 0. + currentCoexLatencyMs - Period of awakening for the firmware used when + non-periodic traffic is detected + hasBtDevice - TRUE if there is a Bluetooth device connected + currentBlackoutDurationUs - Current blackout duration for protecting + Bluetooth + currentBlackoutPeriodUs - Current blackout period + currentCoexScheme - Defines the scheme for the coexistence + signalling + +*******************************************************************************/ +typedef struct +{ + CsrBool hasTrafficData; + CsrWifiSmeTrafficType currentTrafficType; + CsrUint16 currentPeriodMs; + CsrWifiSmePowerSaveLevel currentPowerSave; + CsrUint16 currentCoexPeriodMs; + CsrUint16 currentCoexLatencyMs; + CsrBool hasBtDevice; + CsrUint32 currentBlackoutDurationUs; + CsrUint32 currentBlackoutPeriodUs; + CsrWifiSmeCoexScheme currentCoexScheme; +} CsrWifiSmeCoexInfo; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionConfig + + DESCRIPTION + Specifies the parameters that the SME should use in selecting a network. + + MEMBERS + ssid + - Service Set identifier + bssid + - BSS identifier + bssType + - Indicates the type of BSS + ifIndex + - Indicates the radio interface + privacyMode + - Specifies whether the privacy mode is enabled or disabled. + authModeMask + - Sets the authentication options that the SME can use while + associating to the AP + Set mask with values from CsrWifiSmeAuthMode + encryptionModeMask + - Sets the encryption options that the SME can use while + associating to the AP + Set mask with values from CsrWifiSmeEncryption + mlmeAssociateReqInformationElementsLength + - Length in bytes of information elements to be sent in the + Association Request. + mlmeAssociateReqInformationElements + - Points to the first byte of the information elements, if + any. + wmmQosInfo + - This parameter allows the driver's WMM behaviour to be + configured. + To enable support for WMM, use + CSR_WIFI_SME_SME_CONFIG_SET_REQ with the + CSR_WIFI_SME_WMM_MODE_AC_ENABLED bit set in wmmModeMask + field in smeConfig parameter. + Set mask with values from CsrWifiSmeWmmQosInfo + adhocJoinOnly + - This parameter is relevant only if bssType is NOT set to + CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE: + if TRUE the SME will only try to join an ad-hoc network if + there is one already established; + if FALSE the SME will try to join an ad-hoc network if + there is one already established or it will try to + establish a new one + adhocChannel + - This parameter is relevant only if bssType is NOT set to + CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE: + it indicates the channel to use joining an ad hoc network. + Setting this to 0 causes the SME to select a channel from + those permitted in the regulatory domain. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSsid ssid; + CsrWifiMacAddress bssid; + CsrWifiSmeBssType bssType; + CsrWifiSmeRadioIF ifIndex; + CsrWifiSme80211PrivacyMode privacyMode; + CsrWifiSmeAuthModeMask authModeMask; + CsrWifiSmeEncryptionMask encryptionModeMask; + CsrUint16 mlmeAssociateReqInformationElementsLength; + CsrUint8 *mlmeAssociateReqInformationElements; + CsrWifiSmeWmmQosInfoMask wmmQosInfo; + CsrBool adhocJoinOnly; + CsrUint8 adhocChannel; +} CsrWifiSmeConnectionConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionInfo + + DESCRIPTION + Parameters that the SME should use in selecting a network + + MEMBERS + ssid - Service set identifier + bssid - BSS identifier + networkType80211 - Physical layer used for the connection + channelNumber - Channel number + channelFrequency - Channel frequency + authMode - Authentication mode used for the connection + pairwiseCipher - Encryption type for peer to peer communication + groupCipher - Encryption type for broadcast and multicast + communication + ifIndex - Indicates the radio interface + atimWindowTu - ATIM window specified for IBSS + beaconPeriodTu - Interval between beacon packets + reassociation - Indicates whether a reassociation occurred + beaconFrameLength - Indicates the number of bytes of the beacon + frame + beaconFrame - Points at the first byte of the beacon frame + associationReqFrameLength - Indicates the number of bytes of the + association request frame + associationReqFrame - Points at the first byte of the association + request frame + associationRspFrameLength - Indicates the number of bytes of the + association response frame + associationRspFrame - Points at the first byte of the association + response frame + assocScanInfoElementsLength - Indicates the number of bytes in the buffer + pointed by assocScanInfoElements + assocScanInfoElements - Pointer to the buffer containing the + information elements of the probe response + received after the probe requests sent before + attempting to authenticate to the network + assocReqCapabilities - Reports the content of the Capability + information element as specified in the + association request. + assocReqListenIntervalTu - Listen Interval specified in the association + request + assocReqApAddress - AP address to which the association requests + has been sent + assocReqInfoElementsLength - Indicates the number of bytes of the + association request information elements + assocReqInfoElements - Points at the first byte of the association + request information elements + assocRspResult - Result reported in the association response + assocRspCapabilityInfo - Reports the content of the Capability + information element as received in the + association response. + assocRspAssociationId - Reports the association ID received in the + association response. + assocRspInfoElementsLength - Indicates the number of bytes of the + association response information elements + assocRspInfoElements - Points at the first byte of the association + response information elements + +*******************************************************************************/ +typedef struct +{ + CsrWifiSsid ssid; + CsrWifiMacAddress bssid; + CsrWifiSme80211NetworkType networkType80211; + CsrUint8 channelNumber; + CsrUint16 channelFrequency; + CsrWifiSmeAuthMode authMode; + CsrWifiSmeEncryption pairwiseCipher; + CsrWifiSmeEncryption groupCipher; + CsrWifiSmeRadioIF ifIndex; + CsrUint16 atimWindowTu; + CsrUint16 beaconPeriodTu; + CsrBool reassociation; + CsrUint16 beaconFrameLength; + CsrUint8 *beaconFrame; + CsrUint16 associationReqFrameLength; + CsrUint8 *associationReqFrame; + CsrUint16 associationRspFrameLength; + CsrUint8 *associationRspFrame; + CsrUint16 assocScanInfoElementsLength; + CsrUint8 *assocScanInfoElements; + CsrUint16 assocReqCapabilities; + CsrUint16 assocReqListenIntervalTu; + CsrWifiMacAddress assocReqApAddress; + CsrUint16 assocReqInfoElementsLength; + CsrUint8 *assocReqInfoElements; + CsrWifiSmeIEEE80211Result assocRspResult; + CsrUint16 assocRspCapabilityInfo; + CsrUint16 assocRspAssociationId; + CsrUint16 assocRspInfoElementsLength; + CsrUint8 *assocRspInfoElements; +} CsrWifiSmeConnectionInfo; + +/******************************************************************************* + + NAME + CsrWifiSmeDeviceConfig + + DESCRIPTION + General configuration options in the SME + + MEMBERS + trustLevel - Level of trust of the information coming from the + network + countryCode - Country code as specified by IEEE 802.11 standard + firmwareDriverInterface - Specifies the type of communication between Host + and Firmware + enableStrictDraftN - If TRUE TKIP is disallowed when connecting to + 802.11n enabled access points + +*******************************************************************************/ +typedef struct +{ + CsrWifiSme80211dTrustLevel trustLevel; + CsrUint8 countryCode[2]; + CsrWifiSmeFirmwareDriverInterface firmwareDriverInterface; + CsrBool enableStrictDraftN; +} CsrWifiSmeDeviceConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeDeviceInfo + + DESCRIPTION + P2P Information for a P2P Device + + MEMBERS + deviceAddress - Device Address of the P2P device + configMethods - Supported WPS configuration methods. + p2PDeviceCap - P2P device capabilities + primDeviceType - Primary WPS device type + secondaryDeviceTypeCount - Number of secondary device types + secDeviceType - list of secondary WPS device types + deviceName - Device name without up to 32 characters'\0'. + deviceNameLength - Number of characters of the device name + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress deviceAddress; + CsrWifiSmeWpsConfigTypeMask configMethods; + CsrWifiSmeP2pCapabilityMask p2PDeviceCap; + CsrWifiSmeWpsDeviceType primDeviceType; + CsrUint8 secondaryDeviceTypeCount; + CsrWifiSmeWpsDeviceType *secDeviceType; + CsrUint8 deviceName[32]; + CsrUint8 deviceNameLength; +} CsrWifiSmeDeviceInfo; + +/******************************************************************************* + + NAME + CsrWifiSmeDeviceInfoCommon + + DESCRIPTION + Structure holding device information. + + MEMBERS + p2pDeviceAddress - + primaryDeviceType - + secondaryDeviceTypesCount - + secondaryDeviceTypes - + deviceNameLength - + deviceName - + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress p2pDeviceAddress; + CsrWifiSmeWpsDeviceTypeCommon primaryDeviceType; + CsrUint8 secondaryDeviceTypesCount; + CsrUint8 secondaryDeviceTypes[10]; + CsrUint8 deviceNameLength; + CsrUint8 deviceName[32]; +} CsrWifiSmeDeviceInfoCommon; + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfig + + DESCRIPTION + Defines the host power state (for example, on mains power, on battery + power etc) and the periodicity of the traffic data. + + MEMBERS + powerMode - The wireless manager application should use the + powerMode parameter to inform the SME of the host + power state. + applicationDataPeriodMs - The applicationDataPeriodMs parameter allows a + wireless manager application to inform the SME + that an application is running that generates + periodic network traffic and the period of the + traffic. + An example of such an application is a VoIP client. + The wireless manager application should set + applicationDataPeriodMs to the period in + milliseconds between data packets or zero if no + periodic application is running. + Voip etc 0 = No Periodic Data + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeHostPowerMode powerMode; + CsrUint16 applicationDataPeriodMs; +} CsrWifiSmeHostConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeKey + + DESCRIPTION + Information for a key to be used for encryption + + MEMBERS + keyType - Specifies whether the key is a pairwise or group key; it + should be set to CSR_WIFI_SME_GROUP_KEY or + CSR_WIFI_SME_PAIRWISE_KEY, as required. + keyIndex - Specifies which WEP key (0-3) to set; it should be set to 0 + for a WPA/WPA2 pairwise key and non-zero for a WPA/WPA2 + group key. + wepTxKey - If wepTxKey is TRUE, and the key is a WEP key, the key will + be selected for encrypting transmitted packets. + To select a previously defined key as the transmit + encryption key, set keyIndex to the required key, wepTxKey + to TRUE and the keyLength to 0. + keyRsc - Key Receive Sequence Counter + authenticator - If TRUE the WMA will act as authenticator. + CURRENTLY NOT SUPPORTED + address - BSS identifier of the AP + keyLength - Length of the key in bytes + key - Points to the first byte of the key + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeKeyType keyType; + CsrUint8 keyIndex; + CsrBool wepTxKey; + CsrUint16 keyRsc[8]; + CsrBool authenticator; + CsrWifiMacAddress address; + CsrUint8 keyLength; + CsrUint8 key[32]; +} CsrWifiSmeKey; + +/******************************************************************************* + + NAME + CsrWifiSmeP2pClientInfoType + + DESCRIPTION + P2P Information for a P2P Client + + MEMBERS + p2PClientInterfaceAddress - MAC address of the P2P Client + clientDeviceInfo - Device Information + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress p2PClientInterfaceAddress; + CsrWifiSmeDeviceInfo clientDeviceInfo; +} CsrWifiSmeP2pClientInfoType; + +/******************************************************************************* + + NAME + CsrWifiSmeP2pGroupInfo + + DESCRIPTION + P2P Information for a P2P Group + + MEMBERS + groupCapability - P2P group capabilities + p2pDeviceAddress - Device Address of the GO + p2pClientInfoCount - Number of P2P Clients that belong to the group. + p2PClientInfo - Pointer to the list containing client information for + each client in the group + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeP2pGroupCapabilityMask groupCapability; + CsrWifiMacAddress p2pDeviceAddress; + CsrUint8 p2pClientInfoCount; + CsrWifiSmeP2pClientInfoType *p2PClientInfo; +} CsrWifiSmeP2pGroupInfo; + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfig + + DESCRIPTION + Configures the power-save behaviour of the driver and firmware. + + MEMBERS + powerSaveLevel - Power Save Level option + listenIntervalTu - Interval for waking to receive beacon frames + rxDtims - If TRUE, wake for DTIM every beacon period, to + allow the reception broadcast packets + d3AutoScanMode - Defines whether the autonomous scanning will be + turned off or will stay on during a D3 suspended + period + clientTrafficWindow - Deprecated + opportunisticPowerSave - Deprecated + noticeOfAbsence - Deprecated + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmePowerSaveLevel powerSaveLevel; + CsrUint16 listenIntervalTu; + CsrBool rxDtims; + CsrWifiSmeD3AutoScanMode d3AutoScanMode; + CsrUint8 clientTrafficWindow; + CsrBool opportunisticPowerSave; + CsrBool noticeOfAbsence; +} CsrWifiSmePowerConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfig + + DESCRIPTION + Configures the roaming behaviour of the driver and firmware + + MEMBERS + roamingBands - Defines the thresholds to determine the usability + level of the current connection. + roamingBands is indexed by the first 3 entries of + the CsrWifiSmeBasicUsability enum + disableSmoothRoaming - Disable the RSSI/SNR triggers from the Firmware + that the SME uses to detect the quality of the + connection. + This implicitly disables disableRoamScans + disableRoamScans - Disables the scanning for the roaming operation + reconnectLimit - Maximum number of times SME may reconnect in the + given interval + reconnectLimitIntervalMs - Interval for maximum number of times SME may + reconnect to the same Access Point + roamScanCfg - Scanning behaviour for the specifically aimed at + improving roaming performance. + roamScanCfg is indexed by the first 3 entries of + the CsrWifiSmeBasicUsability enum + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeRoamingBandData roamingBands[3]; + CsrBool disableSmoothRoaming; + CsrBool disableRoamScans; + CsrUint8 reconnectLimit; + CsrUint16 reconnectLimitIntervalMs; + CsrWifiSmeScanConfigData roamScanCfg[3]; +} CsrWifiSmeRoamingConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfig + + DESCRIPTION + Parameters for the autonomous scanning behaviour of the system + + MEMBERS + scanCfg - Scan configuration data. + Indexed by the CsrWifiSmeBasicUsability enum + disableAutonomousScans - Enables or disables the autonomous scan + maxResults - Maximum number of results to be cached in the SME + highRssiThreshold - High received signal strength indication threshold + in dBm for an AP above which the system will + report scan indications + lowRssiThreshold - Low received signal strength indication threshold + in dBm for an AP below which the system will + report scan indications + deltaRssiThreshold - Minimum difference for received signal strength + indication in dBm for an AP which trigger a scan + indication to be sent. + highSnrThreshold - High Signal to Noise Ratio threshold in dB for an + AP above which the system will report scan + indications + lowSnrThreshold - Low Signal to Noise Ratio threshold in dB for an + AP below which the system will report scan + indications + deltaSnrThreshold - Minimum difference for Signal to Noise Ratio in dB + for an AP which trigger a scan indication to be + sent. + passiveChannelListCount - Number of channels to be scanned passively. + passiveChannelList - Points to the first channel to be scanned + passively , if any. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeScanConfigData scanCfg[4]; + CsrBool disableAutonomousScans; + CsrUint16 maxResults; + CsrInt8 highRssiThreshold; + CsrInt8 lowRssiThreshold; + CsrInt8 deltaRssiThreshold; + CsrInt8 highSnrThreshold; + CsrInt8 lowSnrThreshold; + CsrInt8 deltaSnrThreshold; + CsrUint16 passiveChannelListCount; + CsrUint8 *passiveChannelList; +} CsrWifiSmeScanConfig; + +/******************************************************************************* + + NAME + CsrWifiSmeScanResult + + DESCRIPTION + This structure defines the scan result for each BSS found + + MEMBERS + ssid - Service set identifier + bssid - BSS identifier + rssi - Received signal strength indication in dBm + snr - Signal to noise ratio in dB + ifIndex - Indicates the radio interface + beaconPeriodTu - Interval between beacon frames + timeStamp - Timestamp in the BSS + localTime - Timestamp in the Access Point + channelFrequency - Channel frequency + capabilityInformation - Capabilities of the BSS. + channelNumber - Channel number + usability - Indicates the usability level. + bssType - Type of BSS. + informationElementsLength - Number of bytes of the information elements + received as part of the beacon or probe + response. + informationElements - Points to the first byte of the IEs received + as part of the beacon or probe response. + The format of the IEs is as specified in the + IEEE 802.11 specification. + p2pDeviceRole - Role of the P2P device. + Relevant only if bssType is + CSR_WIFI_SME_BSS_TYPE_P2P + deviceInfo - Union containing P2P device info which + depends on p2pDeviceRole parameter. + deviceInforeservedCli - + deviceInfogroupInfo - + deviceInforeservedNone - + deviceInfostandalonedevInfo - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSsid ssid; + CsrWifiMacAddress bssid; + CsrInt16 rssi; + CsrInt16 snr; + CsrWifiSmeRadioIF ifIndex; + CsrUint16 beaconPeriodTu; + CsrWifiSmeTsfTime timeStamp; + CsrWifiSmeTsfTime localTime; + CsrUint16 channelFrequency; + CsrUint16 capabilityInformation; + CsrUint8 channelNumber; + CsrWifiSmeBasicUsability usability; + CsrWifiSmeBssType bssType; + CsrUint16 informationElementsLength; + CsrUint8 *informationElements; + CsrWifiSmeP2pRole p2pDeviceRole; + union { + CsrWifiSmeEmpty reservedCli; + CsrWifiSmeP2pGroupInfo groupInfo; + CsrWifiSmeEmpty reservedNone; + CsrWifiSmeDeviceInfo standalonedevInfo; + } deviceInfo; +} CsrWifiSmeScanResult; + +/******************************************************************************* + + NAME + CsrWifiSmeWep128Keys + + DESCRIPTION + Structure holding WEP Authentication Type and WEP keys that can be used + when using WEP128. + + MEMBERS + wepAuthType - Mask to select the WEP authentication type (Open or Shared) + selectedWepKey - Index to one of the four keys below indicating the + currently used WEP key. Mapping From SME/User -> firmware. + Key 1 -> Index 0. Key 2 -> Index 1. key 3 -> Index 2. Key + 4-> Index 3. + key1 - Value for key number 1. + key2 - Value for key number 2. + key3 - Value for key number 3. + key4 - Value for key number 4. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeWepAuthMode wepAuthType; + CsrUint8 selectedWepKey; + CsrUint8 key1[13]; + CsrUint8 key2[13]; + CsrUint8 key3[13]; + CsrUint8 key4[13]; +} CsrWifiSmeWep128Keys; + +/******************************************************************************* + + NAME + CsrWifiSmeWep64Keys + + DESCRIPTION + Structure holding WEP Authentication Type and WEP keys that can be used + when using WEP64. + + MEMBERS + wepAuthType - Mask to select the WEP authentication type (Open or Shared) + selectedWepKey - Index to one of the four keys below indicating the + currently used WEP key. Mapping From SME/User -> firmware. + Key 1 -> Index 0. Key 2 -> Index 1. key 3 -> Index 2. Key + 4-> Index 3. + key1 - Value for key number 1. + key2 - Value for key number 2. + key3 - Value for key number 3. + key4 - Value for key number 4. + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeWepAuthMode wepAuthType; + CsrUint8 selectedWepKey; + CsrUint8 key1[5]; + CsrUint8 key2[5]; + CsrUint8 key3[5]; + CsrUint8 key4[5]; +} CsrWifiSmeWep64Keys; + +/******************************************************************************* + + NAME + CsrWifiSmeWepAuth + + DESCRIPTION + WEP authentication parameter structure + + MEMBERS + wepKeyType - WEP key try (128 bit or 64 bit) + wepCredentials - Union containing credentials which depends on + wepKeyType parameter. + wepCredentialswep128Key - + wepCredentialswep64Key - + +*******************************************************************************/ +typedef struct +{ + CsrWifiSmeWepCredentialType wepKeyType; + union { + CsrWifiSmeWep128Keys wep128Key; + CsrWifiSmeWep64Keys wep64Key; + } wepCredentials; +} CsrWifiSmeWepAuth; + +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfig + + DESCRIPTION + Structure holding AP WPS Config data. + + MEMBERS + wpsVersion - wpsVersion should be 0x10 for WPS1.0h or 0x20 for + WSC2.0 + uuid - uuid. + deviceName - Device name upto 32 characters without '\0'. + deviceNameLength - deviceNameLen. + manufacturer - manufacturer: CSR + manufacturerLength - manufacturerLen. + modelName - modelName Unifi + modelNameLength - modelNameLen. + modelNumber - modelNumber + modelNumberLength - modelNumberLen. + serialNumber - serialNumber + primDeviceType - Primary WPS device type + secondaryDeviceTypeCount - Number of secondary device types + secondaryDeviceType - list of secondary WPS device types + configMethods - Supported WPS config methods + rfBands - RfBands. + osVersion - Os version on which the device is running + +*******************************************************************************/ +typedef struct +{ + CsrUint8 wpsVersion; + CsrUint8 uuid[16]; + CsrUint8 deviceName[32]; + CsrUint8 deviceNameLength; + CsrUint8 manufacturer[64]; + CsrUint8 manufacturerLength; + CsrUint8 modelName[32]; + CsrUint8 modelNameLength; + CsrUint8 modelNumber[32]; + CsrUint8 modelNumberLength; + CsrUint8 serialNumber[32]; + CsrWifiSmeWpsDeviceType primDeviceType; + CsrUint8 secondaryDeviceTypeCount; + CsrWifiSmeWpsDeviceType *secondaryDeviceType; + CsrWifiSmeWpsConfigTypeMask configMethods; + CsrUint8 rfBands; + CsrUint8 osVersion[4]; +} CsrWifiSmeWpsConfig; + + +/* Downstream */ +#define CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST (0x0000) + +#define CSR_WIFI_SME_ACTIVATE_REQ ((CsrWifiSmePrim) (0x0000 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_ADHOC_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0001 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_ADHOC_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0002 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_BLACKLIST_REQ ((CsrWifiSmePrim) (0x0003 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CALIBRATION_DATA_GET_REQ ((CsrWifiSmePrim) (0x0004 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ ((CsrWifiSmePrim) (0x0005 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CCX_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0006 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CCX_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0007 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_COEX_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0008 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_COEX_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0009 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_COEX_INFO_GET_REQ ((CsrWifiSmePrim) (0x000A + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECT_REQ ((CsrWifiSmePrim) (0x000B + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x000C + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_INFO_GET_REQ ((CsrWifiSmePrim) (0x000D + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_STATS_GET_REQ ((CsrWifiSmePrim) (0x000E + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_DEACTIVATE_REQ ((CsrWifiSmePrim) (0x000F + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_DISCONNECT_REQ ((CsrWifiSmePrim) (0x0010 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_EVENT_MASK_SET_REQ ((CsrWifiSmePrim) (0x0011 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_HOST_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0012 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_HOST_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0013 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_KEY_REQ ((CsrWifiSmePrim) (0x0014 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_LINK_QUALITY_GET_REQ ((CsrWifiSmePrim) (0x0015 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0016 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0017 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_GET_NEXT_REQ ((CsrWifiSmePrim) (0x0018 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_GET_REQ ((CsrWifiSmePrim) (0x0019 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_SET_REQ ((CsrWifiSmePrim) (0x001A + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_MULTICAST_ADDRESS_REQ ((CsrWifiSmePrim) (0x001B + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_PACKET_FILTER_SET_REQ ((CsrWifiSmePrim) (0x001C + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_REQ ((CsrWifiSmePrim) (0x001D + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_PMKID_REQ ((CsrWifiSmePrim) (0x001E + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_POWER_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x001F + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_POWER_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0020 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_REQ ((CsrWifiSmePrim) (0x0021 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_ROAMING_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0022 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_ROAMING_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0023 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0024 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0025 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_FULL_REQ ((CsrWifiSmePrim) (0x0026 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_RESULTS_FLUSH_REQ ((CsrWifiSmePrim) (0x0027 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_RESULTS_GET_REQ ((CsrWifiSmePrim) (0x0028 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_STA_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0029 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_STA_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x002A + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_REQ ((CsrWifiSmePrim) (0x002B + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_TSPEC_REQ ((CsrWifiSmePrim) (0x002C + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_VERSIONS_GET_REQ ((CsrWifiSmePrim) (0x002D + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ ((CsrWifiSmePrim) (0x002E + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_OFF_REQ ((CsrWifiSmePrim) (0x002F + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_ON_REQ ((CsrWifiSmePrim) (0x0030 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ ((CsrWifiSmePrim) (0x0031 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_CLOAKED_SSIDS_GET_REQ ((CsrWifiSmePrim) (0x0032 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_COMMON_CONFIG_GET_REQ ((CsrWifiSmePrim) (0x0033 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0034 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ ((CsrWifiSmePrim) (0x0035 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_WPS_CONFIGURATION_REQ ((CsrWifiSmePrim) (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) + + +#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST) + +/* Upstream */ +#define CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) + +#define CSR_WIFI_SME_ACTIVATE_CFM ((CsrWifiSmePrim)(0x0000 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x0001 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x0002 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND ((CsrWifiSmePrim)(0x0003 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ASSOCIATION_START_IND ((CsrWifiSmePrim)(0x0004 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_BLACKLIST_CFM ((CsrWifiSmePrim)(0x0005 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM ((CsrWifiSmePrim)(0x0006 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CALIBRATION_DATA_SET_CFM ((CsrWifiSmePrim)(0x0007 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CCX_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x0008 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CCX_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x0009 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_COEX_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x000A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_COEX_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x000B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_COEX_INFO_GET_CFM ((CsrWifiSmePrim)(0x000C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECT_CFM ((CsrWifiSmePrim)(0x000D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x000E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_INFO_GET_CFM ((CsrWifiSmePrim)(0x000F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_QUALITY_IND ((CsrWifiSmePrim)(0x0010 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CONNECTION_STATS_GET_CFM ((CsrWifiSmePrim)(0x0011 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_DEACTIVATE_CFM ((CsrWifiSmePrim)(0x0012 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_DISCONNECT_CFM ((CsrWifiSmePrim)(0x0013 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_EVENT_MASK_SET_CFM ((CsrWifiSmePrim)(0x0014 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_HOST_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x0015 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_HOST_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x0016 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_IBSS_STATION_IND ((CsrWifiSmePrim)(0x0017 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_KEY_CFM ((CsrWifiSmePrim)(0x0018 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_LINK_QUALITY_GET_CFM ((CsrWifiSmePrim)(0x0019 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MEDIA_STATUS_IND ((CsrWifiSmePrim)(0x001A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x001B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x001C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_GET_CFM ((CsrWifiSmePrim)(0x001D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_GET_NEXT_CFM ((CsrWifiSmePrim)(0x001E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIB_SET_CFM ((CsrWifiSmePrim)(0x001F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MIC_FAILURE_IND ((CsrWifiSmePrim)(0x0020 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_MULTICAST_ADDRESS_CFM ((CsrWifiSmePrim)(0x0021 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_PACKET_FILTER_SET_CFM ((CsrWifiSmePrim)(0x0022 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_CFM ((CsrWifiSmePrim)(0x0023 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND ((CsrWifiSmePrim)(0x0024 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_PMKID_CFM ((CsrWifiSmePrim)(0x0025 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_POWER_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x0026 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_POWER_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x0027 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_CFM ((CsrWifiSmePrim)(0x0028 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ROAM_COMPLETE_IND ((CsrWifiSmePrim)(0x0029 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ROAM_START_IND ((CsrWifiSmePrim)(0x002A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ROAMING_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x002B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ROAMING_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x002C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x002D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x002E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_FULL_CFM ((CsrWifiSmePrim)(0x002F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_RESULT_IND ((CsrWifiSmePrim)(0x0030 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_RESULTS_FLUSH_CFM ((CsrWifiSmePrim)(0x0031 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SCAN_RESULTS_GET_CFM ((CsrWifiSmePrim)(0x0032 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_STA_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x0033 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_STA_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x0034 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_CFM ((CsrWifiSmePrim)(0x0035 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_TSPEC_IND ((CsrWifiSmePrim)(0x0036 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_TSPEC_CFM ((CsrWifiSmePrim)(0x0037 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_VERSIONS_GET_CFM ((CsrWifiSmePrim)(0x0038 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_FLIGHTMODE_CFM ((CsrWifiSmePrim)(0x0039 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_OFF_IND ((CsrWifiSmePrim)(0x003A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_OFF_CFM ((CsrWifiSmePrim)(0x003B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_ON_CFM ((CsrWifiSmePrim)(0x003C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CLOAKED_SSIDS_SET_CFM ((CsrWifiSmePrim)(0x003D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM ((CsrWifiSmePrim)(0x003E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_WIFI_ON_IND ((CsrWifiSmePrim)(0x003F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_COMMON_CONFIG_GET_CFM ((CsrWifiSmePrim)(0x0040 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_CFM ((CsrWifiSmePrim)(0x0041 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_CFM ((CsrWifiSmePrim)(0x0042 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_ERROR_IND ((CsrWifiSmePrim)(0x0043 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_INFO_IND ((CsrWifiSmePrim)(0x0044 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_CORE_DUMP_IND ((CsrWifiSmePrim)(0x0045 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AMP_STATUS_CHANGE_IND ((CsrWifiSmePrim)(0x0046 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_WPS_CONFIGURATION_CFM ((CsrWifiSmePrim)(0x0047 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)) + +#define CSR_WIFI_SME_PRIM_UPSTREAM_HIGHEST (0x0047 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST) + +#define CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_SME_PRIM_UPSTREAM_COUNT (CSR_WIFI_SME_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST) + +/******************************************************************************* + + NAME + CsrWifiSmeActivateReq + + DESCRIPTION + The WMA sends this primitive to activate the SME. + The WMA must activate the SME before it can send any other primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeActivateReq; + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigGetReq + + DESCRIPTION + This primitive gets the value of the adHocConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeAdhocConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigSetReq + + DESCRIPTION + This primitive sets the value of the adHocConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + adHocConfig - Sets the values to use when starting an ad hoc network. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeAdHocConfig adHocConfig; +} CsrWifiSmeAdhocConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeBlacklistReq + + DESCRIPTION + The wireless manager application should call this primitive to notify the + driver of any networks that should not be connected to. The interface + allows the wireless manager application to query, add, remove, and flush + the BSSIDs that the driver may not connect or roam to. + When this primitive adds to the black list the BSSID to which the SME is + currently connected, the SME will try to roam, if applicable, to another + BSSID in the same ESS; if the roaming procedure fails, the SME will + disconnect. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter instructs + the driver to modify or provide the list of blacklisted + networks. + setAddressCount - Number of BSSIDs sent with this primitive + setAddresses - Pointer to the list of BBSIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeListAction action; + CsrUint8 setAddressCount; + CsrWifiMacAddress *setAddresses; +} CsrWifiSmeBlacklistReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataGetReq + + DESCRIPTION + This primitive retrieves the Wi-Fi radio calibration data. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeCalibrationDataGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataSetReq + + DESCRIPTION + This primitive sets the Wi-Fi radio calibration data. + The usage of the primitive with proper calibration data will avoid + time-consuming configuration after power-up. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + calibrationDataLength - Number of bytes in the buffer pointed by + calibrationData + calibrationData - Pointer to a buffer of length calibrationDataLength + containing the calibration data + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 calibrationDataLength; + CsrUint8 *calibrationData; +} CsrWifiSmeCalibrationDataSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigGetReq + + DESCRIPTION + This primitive gets the value of the CcxConfig parameter. + CURRENTLY NOT SUPPORTED. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeCcxConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigSetReq + + DESCRIPTION + This primitive sets the value of the CcxConfig parameter. + CURRENTLY NOT SUPPORTED. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + ccxConfig - Currently not supported + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeCcxConfig ccxConfig; +} CsrWifiSmeCcxConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigGetReq + + DESCRIPTION + This primitive gets the value of the CoexConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeCoexConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigSetReq + + DESCRIPTION + This primitive sets the value of the CoexConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + coexConfig - Configures the coexistence behaviour + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeCoexConfig coexConfig; +} CsrWifiSmeCoexConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexInfoGetReq + + DESCRIPTION + This primitive gets the value of the CoexInfo parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeCoexInfoGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectReq + + DESCRIPTION + The wireless manager application calls this primitive to start the + process of joining an 802.11 wireless network or to start an ad hoc + network. + The structure pointed by connectionConfig contains parameters describing + the network to join or, in case of an ad hoc network, to host or join. + The SME will select a network, perform the IEEE 802.11 Join, Authenticate + and Associate exchanges. + The SME selects the networks from the current scan list that match both + the SSID and BSSID, however either or both of these may be the wildcard + value. Using this rule, the following operations are possible: + * To connect to a network by name, specify the SSID and set the BSSID to + 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF. If there are two or more networks visible, + the SME will select the one with the strongest signal. + * To connect to a specific network, specify the BSSID. The SSID is + optional, but if given it must match the SSID of the network. An empty + SSID may be specified by setting the SSID length to zero. Please note + that if the BSSID is specified (i.e. not equal to 0xFF 0xFF 0xFF 0xFF + 0xFF 0xFF), the SME will not attempt to roam if signal conditions become + poor, even if there is an alternative AP with an SSID that matches the + current network SSID. + * To connect to any network matching the other parameters (i.e. security, + etc), set the SSID length to zero and set the BSSID to 0xFF 0xFF 0xFF + 0xFF 0xFF 0xFF. In this case, the SME will order all available networks + by their signal strengths and will iterate through this list until it + successfully connects. + NOTE: Specifying the BSSID will restrict the selection to one specific + network. If SSID and BSSID are given, they must both match the network + for it to be selected. To select a network based on the SSID only, the + wireless manager application must set the BSSID to 0xFF 0xFF 0xFF 0xFF + 0xFF 0xFF. + The SME will try to connect to each network that matches the provided + parameters, one by one, until it succeeds or has tried unsuccessfully + with all the matching networks. + If there is no network that matches the parameters and the request allows + to host an ad hoc network, the SME will advertise a new ad hoc network + instead. + If the SME cannot connect, it will notify the failure in the confirm. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + connectionConfig - Describes the candidate network to join or to host. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeConnectionConfig connectionConfig; +} CsrWifiSmeConnectReq; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionConfigGetReq + + DESCRIPTION + This primitive gets the value of the ConnectionConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeConnectionConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionInfoGetReq + + DESCRIPTION + This primitive gets the value of the ConnectionInfo parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeConnectionInfoGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionStatsGetReq + + DESCRIPTION + This primitive gets the value of the ConnectionStats parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeConnectionStatsGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeDeactivateReq + + DESCRIPTION + The WMA sends this primitive to deactivate the SME. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeDeactivateReq; + +/******************************************************************************* + + NAME + CsrWifiSmeDisconnectReq + + DESCRIPTION + The wireless manager application may disconnect from the current network + by calling this primitive + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeDisconnectReq; + +/******************************************************************************* + + NAME + CsrWifiSmeEventMaskSetReq + + DESCRIPTION + The wireless manager application may register with the SME to receive + notification of interesting events. Indications will be sent only if the + wireless manager explicitly registers to be notified of that event. + indMask is a bit mask of values defined in CsrWifiSmeIndicationsMask. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + indMask - Set mask with values from CsrWifiSmeIndications + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeIndicationsMask indMask; +} CsrWifiSmeEventMaskSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigGetReq + + DESCRIPTION + This primitive gets the value of the hostConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeHostConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigSetReq + + DESCRIPTION + This primitive sets the value of the hostConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + hostConfig - Communicates a change of host power state (for example, on + mains power, on battery power etc) and of the periodicity of + traffic data + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeHostConfig hostConfig; +} CsrWifiSmeHostConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeKeyReq + + DESCRIPTION + The wireless manager application calls this primitive to add or remove + keys that the chip should use for encryption of data. + The interface allows the wireless manager application to add and remove + keys according to the specified action. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter instructs the + driver to modify or provide the list of keys. + CSR_WIFI_SME_LIST_ACTION_GET is not supported here. + key - Key to be added or removed + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeListAction action; + CsrWifiSmeKey key; +} CsrWifiSmeKeyReq; + +/******************************************************************************* + + NAME + CsrWifiSmeLinkQualityGetReq + + DESCRIPTION + This primitive gets the value of the LinkQuality parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeLinkQualityGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigGetReq + + DESCRIPTION + This primitive gets the value of the MibConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeMibConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigSetReq + + DESCRIPTION + This primitive sets the value of the MibConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + mibConfig - Conveys the desired value of various IEEE 802.11 attributes as + currently configured + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeMibConfig mibConfig; +} CsrWifiSmeMibConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetNextReq + + DESCRIPTION + To read a sequence of MIB parameters, for example a table, call this + primitive to find the name of the next MIB variable + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to a VarBind or VarBindList containing the + name(s) of the MIB variable(s) to search from. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 mibAttributeLength; + CsrUint8 *mibAttribute; +} CsrWifiSmeMibGetNextReq; + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetReq + + DESCRIPTION + The wireless manager application calls this primitive to retrieve one or + more MIB variables. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to the VarBind or VarBindList containing the + names of the MIB variables to be retrieved + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 mibAttributeLength; + CsrUint8 *mibAttribute; +} CsrWifiSmeMibGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeMibSetReq + + DESCRIPTION + The SME provides raw access to the MIB on the chip, which may be used by + some configuration or diagnostic utilities, but is not normally needed by + the wireless manager application. + The MIB access functions use BER encoded names (OID) of the MIB + parameters and BER encoded values, as described in the chip Host + Interface Protocol Specification. + The MIB parameters are described in 'Wi-Fi 5.0.0 Management Information + Base Reference Guide'. + The wireless manager application calls this primitive to set one or more + MIB variables + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to the VarBind or VarBindList containing the + names and values of the MIB variables to set + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 mibAttributeLength; + CsrUint8 *mibAttribute; +} CsrWifiSmeMibSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeMulticastAddressReq + + DESCRIPTION + The wireless manager application calls this primitive to specify the + multicast addresses which the chip should recognise. The interface allows + the wireless manager application to query, add, remove and flush the + multicast addresses for the network interface according to the specified + action. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter + instructs the driver to modify or provide the list of + MAC addresses. + setAddressesCount - Number of MAC addresses sent with the primitive + setAddresses - Pointer to the list of MAC Addresses sent with the + primitive, set to NULL if none is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeListAction action; + CsrUint8 setAddressesCount; + CsrWifiMacAddress *setAddresses; +} CsrWifiSmeMulticastAddressReq; + +/******************************************************************************* + + NAME + CsrWifiSmePacketFilterSetReq + + DESCRIPTION + The wireless manager application should call this primitive to enable or + disable filtering of broadcast packets: uninteresting broadcast packets + will be dropped by the Wi-Fi chip, instead of passing them up to the + host. + This has the advantage of saving power in the host application processor + as it removes the need to process unwanted packets. + All broadcast packets are filtered according to the filter and the filter + mode provided, except ARP packets, which are filtered using + arpFilterAddress. + Filters are not cumulative: only the parameters specified in the most + recent successful request are significant. + For more information, see 'UniFi Firmware API Specification'. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + filterLength - Length of the filter in bytes. + filterLength=0 disables the filter previously set + filter - Points to the first byte of the filter provided, if any. + This shall include zero or more instance of the + information elements of one of these types + * Traffic Classification (TCLAS) elements + * WMM-SA TCLAS elements + mode - Specifies whether the filter selects or excludes packets + matching the filter + arpFilterAddress - IPv4 address to be used for filtering the ARP packets. + * If the specified address is the IPv4 broadcast address + (255.255.255.255), all ARP packets are reported to the + host, + * If the specified address is NOT the IPv4 broadcast + address, only ARP packets with the specified address in + the Source or Target Protocol Address fields are reported + to the host + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint16 filterLength; + CsrUint8 *filter; + CsrWifiSmePacketFilterMode mode; + CsrWifiIp4Address arpFilterAddress; +} CsrWifiSmePacketFilterSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmePermanentMacAddressGetReq + + DESCRIPTION + This primitive retrieves the MAC address stored in EEPROM + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmePermanentMacAddressGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmePmkidReq + + DESCRIPTION + The wireless manager application calls this primitive to request an + operation on the SME PMKID list. + The action argument specifies the operation to perform. + When the connection is complete, the wireless manager application may + then send and receive EAPOL packets to complete WPA or WPA2 + authentication if appropriate. + The wireless manager application can then pass the resulting encryption + keys using this primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + action - The value of the CsrWifiSmeListAction parameter instructs + the driver to modify or provide the list of PMKIDs. + setPmkidsCount - Number of PMKIDs sent with the primitive + setPmkids - Pointer to the list of PMKIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeListAction action; + CsrUint8 setPmkidsCount; + CsrWifiSmePmkid *setPmkids; +} CsrWifiSmePmkidReq; + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigGetReq + + DESCRIPTION + This primitive gets the value of the PowerConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmePowerConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigSetReq + + DESCRIPTION + This primitive sets the value of the PowerConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + powerConfig - Power saving configuration + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmePowerConfig powerConfig; +} CsrWifiSmePowerConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeRegulatoryDomainInfoGetReq + + DESCRIPTION + This primitive gets the value of the RegulatoryDomainInfo parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeRegulatoryDomainInfoGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigGetReq + + DESCRIPTION + This primitive gets the value of the RoamingConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeRoamingConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigSetReq + + DESCRIPTION + This primitive sets the value of the RoamingConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + roamingConfig - Desired roaming behaviour values + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeRoamingConfig roamingConfig; +} CsrWifiSmeRoamingConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigGetReq + + DESCRIPTION + This primitive gets the value of the ScanConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeScanConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigSetReq + + DESCRIPTION + This primitive sets the value of the ScanConfig parameter. + The SME normally configures the firmware to perform autonomous scanning + without involving the host. + The firmware passes beacon / probe response or indicates loss of beacon + on certain changes of state, for example: + * A new AP is seen for the first time + * An AP is no longer visible + * The signal strength of an AP changes by more than a certain amount, as + configured by the thresholds in the scanConfig parameter + In addition to the autonomous scan, the wireless manager application may + request a scan at any time using CSR_WIFI_SME_SCAN_FULL_REQ. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + scanConfig - Reports the configuration for the autonomous scanning behaviour + of the firmware + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeScanConfig scanConfig; +} CsrWifiSmeScanConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeScanFullReq + + DESCRIPTION + The wireless manager application should call this primitive to request a + full scan. + Channels are scanned actively or passively according to the requirement + set by regulatory domain. + If the SME receives this primitive while a full scan is going on, the new + request is buffered and it will be served after the current full scan is + completed. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + ssidCount - Number of SSIDs provided. + If it is 0, the SME will attempt to detect any network + ssid - Points to the first SSID provided, if any. + bssid - BSS identifier. + If it is equal to FF-FF-FF-FF-FF, the SME will listen for + messages from any BSS. + If it is different from FF-FF-FF-FF-FF and any SSID is + provided, one SSID must match the network of the BSS. + forceScan - Forces the scan even if the SME is in a state which would + normally prevent it (e.g. autonomous scan is running). + bssType - Type of BSS to scan for + scanType - Type of scan to perform + channelListCount - Number of channels provided. + If it is 0, the SME will initiate a scan of all the + supported channels that are permitted by the current + regulatory domain. + channelList - Points to the first channel , or NULL if channelListCount + is zero. + probeIeLength - Length of the information element in bytes to be sent + with the probe message. + probeIe - Points to the first byte of the information element to be + sent with the probe message. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint8 ssidCount; + CsrWifiSsid *ssid; + CsrWifiMacAddress bssid; + CsrBool forceScan; + CsrWifiSmeBssType bssType; + CsrWifiSmeScanType scanType; + CsrUint16 channelListCount; + CsrUint8 *channelList; + CsrUint16 probeIeLength; + CsrUint8 *probeIe; +} CsrWifiSmeScanFullReq; + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsFlushReq + + DESCRIPTION + The Wireless Manager calls this primitive to ask the SME to delete all + scan results from its cache, except for the scan result of any currently + connected network. + As scan results are received by the SME from the firmware, they are + cached in the SME memory. + Any time the Wireless Manager requests scan results, they are returned + from the SME internal cache. + For some applications it may be desirable to clear this cache prior to + requesting that a scan be performed; this will ensure that the cache then + only contains the networks detected in the most recent scan. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeScanResultsFlushReq; + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsGetReq + + DESCRIPTION + The wireless manager application calls this primitive to retrieve the + current set of scan results, either after receiving a successful + CSR_WIFI_SME_SCAN_FULL_CFM, or to get autonomous scan results. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeScanResultsGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigGetReq + + DESCRIPTION + This primitive gets the value of the SmeStaConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeSmeStaConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigSetReq + + DESCRIPTION + This primitive sets the value of the SmeConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + smeConfig - SME Station Parameters to be set + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeStaConfig smeConfig; +} CsrWifiSmeSmeStaConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeStationMacAddressGetReq + + DESCRIPTION + This primitives is used to retrieve the current MAC address used by the + station. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeStationMacAddressGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeTspecReq + + DESCRIPTION + The wireless manager application should call this primitive to use the + TSPEC feature. + The chip supports the use of TSPECs and TCLAS for the use of IEEE + 802.11/WMM Quality of Service features. + The API allows the wireless manager application to supply a correctly + formatted TSPEC and TCLAS pair to the driver. + After performing basic validation, the driver negotiates the installation + of the TSPEC with the AP as defined by the 802.11 specification. + The driver retains all TSPEC and TCLAS pairs until they are specifically + removed. + It is not compulsory for a TSPEC to have a TCLAS (NULL is used to + indicate that no TCLAS is supplied), while a TCLASS always require a + TSPEC. + The format of the TSPEC element is specified in 'WMM (including WMM Power + Save) Specification - Version 1.1' and 'ANSI/IEEE Std 802.11-REVmb/D3.0'. + For more information, see 'UniFi Configuring WMM and WMM-PS'. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + action - Specifies the action to be carried out on the list of TSPECs. + CSR_WIFI_SME_LIST_ACTION_FLUSH is not applicable here. + transactionId - Unique Transaction ID for the TSPEC, as assigned by the + driver + strict - If it set to false, allows the SME to perform automatic + TSPEC negotiation + ctrlMask - Additional TSPEC configuration for CCX. + Set mask with values from CsrWifiSmeTspecCtrl. + CURRENTLY NOT SUPPORTED + tspecLength - Length of the TSPEC. + tspec - Points to the first byte of the TSPEC + tclasLength - Length of the TCLAS. + If it is equal to 0, no TCLASS is provided for the TSPEC + tclas - Points to the first byte of the TCLAS, if any. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeListAction action; + CsrUint32 transactionId; + CsrBool strict; + CsrWifiSmeTspecCtrlMask ctrlMask; + CsrUint16 tspecLength; + CsrUint8 *tspec; + CsrUint16 tclasLength; + CsrUint8 *tclas; +} CsrWifiSmeTspecReq; + +/******************************************************************************* + + NAME + CsrWifiSmeVersionsGetReq + + DESCRIPTION + This primitive gets the value of the Versions parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeVersionsGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiFlightmodeReq + + DESCRIPTION + The wireless manager application may call this primitive on boot-up of + the platform to ensure that the chip is placed in a mode that prevents + any emission of RF energy. + This primitive is an alternative to CSR_WIFI_SME_WIFI_ON_REQ. + As in CSR_WIFI_SME_WIFI_ON_REQ, it causes the download of the patch file + (if any) and the programming of the initial MIB settings (if supplied by + the WMA), but it also ensures that the chip is left in its lowest + possible power-mode with the radio subsystems disabled. + This feature is useful on platforms where power cannot be removed from + the chip (leaving the chip not initialised will cause it to consume more + power so calling this function ensures that the chip is initialised into + a low power mode but without entering a state where it could emit any RF + energy). + NOTE: this primitive does not cause the Wi-Fi to change state: Wi-Fi + stays conceptually off. Configuration primitives can be sent after + CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ and the configuration will be maintained. + Requests that require the state of the Wi-Fi to be ON will return + CSR_WIFI_SME_STATUS_WIFI_OFF in their confirms. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + address - Optionally specifies a station MAC address. + In normal use, the manager should set the address to 0xFF + 0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use + the MAC address in the MIB. + mibFilesCount - Number of provided data blocks with initial MIB values + mibFiles - Points to the first data block with initial MIB values. + These data blocks are typically the contents of the provided + files ufmib.dat and localmib.dat, available from the host + file system, if they exist. + These files typically contain radio tuning and calibration + values. + More values can be created using the Host Tools. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiMacAddress address; + CsrUint16 mibFilesCount; + CsrWifiSmeDataBlock *mibFiles; +} CsrWifiSmeWifiFlightmodeReq; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOffReq + + DESCRIPTION + The wireless manager application calls this primitive to turn off the + chip, thus saving power when Wi-Fi is not in use. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeWifiOffReq; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOnReq + + DESCRIPTION + The wireless manager application calls this primitive to turn on the + Wi-Fi chip. + If the Wi-Fi chip is currently off, the SME turns the Wi-Fi chip on, + downloads the patch file (if any), and programs the initial MIB settings + (if supplied by the WMA). + The patch file is not provided with the SME API; its downloading is + automatic and handled internally by the system. + The MIB settings, when provided, override the default values that the + firmware loads from EEPROM. + If the Wi-Fi chip is already on, the SME takes no action and returns a + successful status in the confirm. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + address - Optionally specifies a station MAC address. + In normal use, the manager should set the address to 0xFF + 0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use + the MAC address in the MIB + mibFilesCount - Number of provided data blocks with initial MIB values + mibFiles - Points to the first data block with initial MIB values. + These data blocks are typically the contents of the provided + files ufmib.dat and localmib.dat, available from the host + file system, if they exist. + These files typically contain radio tuning and calibration + values. + More values can be created using the Host Tools. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiMacAddress address; + CsrUint16 mibFilesCount; + CsrWifiSmeDataBlock *mibFiles; +} CsrWifiSmeWifiOnReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsSetReq + + DESCRIPTION + This primitive sets the list of cloaked SSIDs for which the WMA possesses + profiles. + When the driver detects a cloaked AP, the SME will explicitly scan for it + using the list of cloaked SSIDs provided it, and, if the scan succeeds, + it will report the AP to the WMA either via CSR_WIFI_SME_SCAN_RESULT_IND + (if registered) or via CSR_WIFI_SCAN_RESULT_GET_CFM. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + cloakedSsids - Sets the list of cloaked SSIDs + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeCloakedSsidConfig cloakedSsids; +} CsrWifiSmeCloakedSsidsSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsGetReq + + DESCRIPTION + This primitive gets the value of the CloakedSsids parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeCloakedSsidsGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigGetReq + + DESCRIPTION + This primitive gets the value of the Sme common parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeSmeCommonConfigGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigSetReq + + DESCRIPTION + This primitive sets the value of the Sme common. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + deviceConfig - Configuration options in the SME + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeDeviceConfig deviceConfig; +} CsrWifiSmeSmeCommonConfigSetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeInterfaceCapabilityGetReq + + DESCRIPTION + The Wireless Manager calls this primitive to ask the SME for the + capabilities of the supported interfaces + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; +} CsrWifiSmeInterfaceCapabilityGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfigurationReq + + DESCRIPTION + This primitive passes the WPS information for the device to SME. This may + be accepted only if no interface is active. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + wpsConfig - WPS config. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeWpsConfig wpsConfig; +} CsrWifiSmeWpsConfigurationReq; + +/******************************************************************************* + + NAME + CsrWifiSmeActivateCfm + + DESCRIPTION + The SME sends this primitive when the activation is complete. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeActivateCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + adHocConfig - Contains the values used when starting an Ad-hoc (IBSS) + connection. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeAdHocConfig adHocConfig; +} CsrWifiSmeAdhocConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeAdhocConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeAdhocConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeAssociationCompleteInd + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it completes an attempt to associate with an AP. If + the association was successful, status will be set to + CSR_WIFI_SME_STATUS_SUCCESS, otherwise status and deauthReason shall be + set to appropriate error codes. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the association procedure + connectionInfo - This parameter is relevant only if result is + CSR_WIFI_SME_STATUS_SUCCESS: + it points to the connection information for the new network + deauthReason - This parameter is relevant only if result is not + CSR_WIFI_SME_STATUS_SUCCESS: + if the AP deauthorised the station, it gives the reason of + the deauthorization + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeConnectionInfo connectionInfo; + CsrWifiSmeIEEE80211Reason deauthReason; +} CsrWifiSmeAssociationCompleteInd; + +/******************************************************************************* + + NAME + CsrWifiSmeAssociationStartInd + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it begins an attempt to associate with an AP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + address - BSSID of the associating network + ssid - Service Set identifier of the associating network + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiMacAddress address; + CsrWifiSsid ssid; +} CsrWifiSmeAssociationStartInd; + +/******************************************************************************* + + NAME + CsrWifiSmeBlacklistCfm + + DESCRIPTION + The SME will call this primitive when the action on the blacklist has + completed. For a GET action, this primitive also reports the list of + BBSIDs in the blacklist. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + getAddressCount - This parameter is only relevant if action is + CSR_WIFI_SME_LIST_ACTION_GET: + number of BSSIDs sent with this primitive + getAddresses - Pointer to the list of BBSIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeListAction action; + CsrUint8 getAddressCount; + CsrWifiMacAddress *getAddresses; +} CsrWifiSmeBlacklistCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + calibrationDataLength - Number of bytes in the buffer pointed by + calibrationData + calibrationData - Pointer to a buffer of length calibrationDataLength + containing the calibration data + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrUint16 calibrationDataLength; + CsrUint8 *calibrationData; +} CsrWifiSmeCalibrationDataGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCalibrationDataSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeCalibrationDataSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + ccxConfig - Currently not supported + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeCcxConfig ccxConfig; +} CsrWifiSmeCcxConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCcxConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeCcxConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + coexConfig - Reports the parameters used to configure the coexistence + behaviour + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeCoexConfig coexConfig; +} CsrWifiSmeCoexConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeCoexConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCoexInfoGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + coexInfo - Reports information and state related to coexistence. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeCoexInfo coexInfo; +} CsrWifiSmeCoexInfoGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectCfm + + DESCRIPTION + The SME calls this primitive when the connection exchange is complete or + all connection attempts fail. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request. + CSR_WIFI_SME_STATUS_NOT_FOUND: all attempts by the SME to + locate the requested AP failed + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeConnectCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + connectionConfig - Parameters used by the SME for selecting a network + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeConnectionConfig connectionConfig; +} CsrWifiSmeConnectionConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionInfoGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + connectionInfo - Information about the current connection + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeConnectionInfo connectionInfo; +} CsrWifiSmeConnectionInfoGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionQualityInd + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it whenever the value of the current connection quality + parameters change by more than a certain configurable amount. + The wireless manager application may configure the trigger thresholds for + this indication using the field in smeConfig parameter of + CSR_WIFI_SME_SME_CONFIG_SET_REQ. + Connection quality messages can be suppressed by setting both thresholds + to zero. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + linkQuality - Indicates the quality of the link + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeLinkQuality linkQuality; +} CsrWifiSmeConnectionQualityInd; + +/******************************************************************************* + + NAME + CsrWifiSmeConnectionStatsGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + connectionStats - Statistics for current connection. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeConnectionStats connectionStats; +} CsrWifiSmeConnectionStatsGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeDeactivateCfm + + DESCRIPTION + The SME sends this primitive when the deactivation is complete. + The WMA cannot send any more primitives until it actives the SME again + sending another CSR_WIFI_SME_ACTIVATE_REQ. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeDeactivateCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeDisconnectCfm + + DESCRIPTION + On reception of CSR_WIFI_SME_DISCONNECT_REQ the SME will perform a + disconnect operation, sending a CsrWifiSmeMediaStatusInd with + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED and then call this primitive when + disconnection is complete. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeDisconnectCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeEventMaskSetCfm + + DESCRIPTION + The SME calls the primitive to report the result of the request + primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeEventMaskSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + hostConfig - Current host power state. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeHostConfig hostConfig; +} CsrWifiSmeHostConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeHostConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeHostConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeIbssStationInd + + DESCRIPTION + The SME will send this primitive to indicate that a station has joined or + left the ad-hoc network. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + address - MAC address of the station that has joined or left + isconnected - TRUE if the station joined, FALSE if the station left + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiMacAddress address; + CsrBool isconnected; +} CsrWifiSmeIbssStationInd; + +/******************************************************************************* + + NAME + CsrWifiSmeKeyCfm + + DESCRIPTION + The SME calls the primitive to report the result of the request + primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + keyType - Type of the key added/deleted + peerMacAddress - Peer MAC Address of the key added/deleted + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeListAction action; + CsrWifiSmeKeyType keyType; + CsrWifiMacAddress peerMacAddress; +} CsrWifiSmeKeyCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeLinkQualityGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + linkQuality - Indicates the quality of the link + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeLinkQuality linkQuality; +} CsrWifiSmeLinkQualityGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeMediaStatusInd + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it when a network connection is established, lost or has moved to + another AP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + mediaStatus - Indicates the media status + connectionInfo - This parameter is relevant only if the mediaStatus is + CSR_WIFI_SME_MEDIA_STATUS_CONNECTED: + it points to the connection information for the new network + disassocReason - This parameter is relevant only if the mediaStatus is + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED: + if a disassociation has occurred it gives the reason of the + disassociation + deauthReason - This parameter is relevant only if the mediaStatus is + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED: + if a deauthentication has occurred it gives the reason of + the deauthentication + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeMediaStatus mediaStatus; + CsrWifiSmeConnectionInfo connectionInfo; + CsrWifiSmeIEEE80211Reason disassocReason; + CsrWifiSmeIEEE80211Reason deauthReason; +} CsrWifiSmeMediaStatusInd; + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + mibConfig - Reports various IEEE 802.11 attributes as currently configured + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeMibConfig mibConfig; +} CsrWifiSmeMibConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeMibConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeMibConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetCfm + + DESCRIPTION + The SME calls this primitive to return the requested MIB variable values. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to the VarBind or VarBindList containing the + names and values of the MIB variables requested + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrUint16 mibAttributeLength; + CsrUint8 *mibAttribute; +} CsrWifiSmeMibGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeMibGetNextCfm + + DESCRIPTION + The SME calls this primitive to return the requested MIB name(s). + The wireless manager application can then read the value of the MIB + variable using CSR_WIFI_SME_MIB_GET_REQ, using the names provided. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + mibAttributeLength - Length of mibAttribute + mibAttribute - Points to a VarBind or VarBindList containing the + name(s) of the MIB variable(s) lexicographically + following the name(s) given in the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrUint16 mibAttributeLength; + CsrUint8 *mibAttribute; +} CsrWifiSmeMibGetNextCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeMibSetCfm + + DESCRIPTION + The SME calls the primitive to report the result of the set primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeMibSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeMicFailureInd + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it whenever the chip firmware reports a MIC failure. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + secondFailure - TRUE if this indication is for a second failure in 60 + seconds + count - The number of MIC failure events since the connection was + established + address - MAC address of the transmitter that caused the MIC failure + keyType - Type of key for which the failure occurred + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrBool secondFailure; + CsrUint16 count; + CsrWifiMacAddress address; + CsrWifiSmeKeyType keyType; +} CsrWifiSmeMicFailureInd; + +/******************************************************************************* + + NAME + CsrWifiSmeMulticastAddressCfm + + DESCRIPTION + The SME will call this primitive when the operation is complete. For a + GET action, this primitive reports the current list of MAC addresses. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + getAddressesCount - This parameter is only relevant if action is + CSR_WIFI_SME_LIST_ACTION_GET: + number of MAC addresses sent with the primitive + getAddresses - Pointer to the list of MAC Addresses sent with the + primitive, set to NULL if none is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeListAction action; + CsrUint8 getAddressesCount; + CsrWifiMacAddress *getAddresses; +} CsrWifiSmeMulticastAddressCfm; + +/******************************************************************************* + + NAME + CsrWifiSmePacketFilterSetCfm + + DESCRIPTION + The SME calls the primitive to report the result of the set primitive. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmePacketFilterSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmePermanentMacAddressGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + permanentMacAddress - MAC address stored in the EEPROM + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiMacAddress permanentMacAddress; +} CsrWifiSmePermanentMacAddressGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmePmkidCandidateListInd + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it when a new network supporting preauthentication and/or PMK + caching is seen. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an + interface + pmkidCandidatesCount - Number of PMKID candidates provided + pmkidCandidates - Points to the first PMKID candidate + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint8 pmkidCandidatesCount; + CsrWifiSmePmkidCandidate *pmkidCandidates; +} CsrWifiSmePmkidCandidateListInd; + +/******************************************************************************* + + NAME + CsrWifiSmePmkidCfm + + DESCRIPTION + The SME will call this primitive when the operation is complete. For a + GET action, this primitive reports the current list of PMKIDs + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + action - Action in the request + getPmkidsCount - This parameter is only relevant if action is + CSR_WIFI_SME_LIST_ACTION_GET: + number of PMKIDs sent with the primitive + getPmkids - Pointer to the list of PMKIDs sent with the primitive, set + to NULL if none is sent. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeListAction action; + CsrUint8 getPmkidsCount; + CsrWifiSmePmkid *getPmkids; +} CsrWifiSmePmkidCfm; + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + powerConfig - Returns the current parameters for the power configuration of + the firmware + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmePowerConfig powerConfig; +} CsrWifiSmePowerConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmePowerConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmePowerConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeRegulatoryDomainInfoGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + regDomInfo - Reports information and state related to regulatory domain + operation. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeRegulatoryDomainInfo regDomInfo; +} CsrWifiSmeRegulatoryDomainInfoGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamCompleteInd + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it completes an attempt to roam to an AP. If the roam + attempt was successful, status will be set to CSR_WIFI_SME_SUCCESS, + otherwise it shall be set to the appropriate error code. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the roaming procedure + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeRoamCompleteInd; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamStartInd + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive it whenever it begins an attempt to roam to an AP. + If the wireless manager application connect request specified the SSID + and the BSSID was set to the broadcast address (0xFF 0xFF 0xFF 0xFF 0xFF + 0xFF), the SME monitors the signal quality and maintains a list of + candidates to roam to. When the signal quality of the current connection + falls below a threshold, and there is a candidate with better quality, + the SME will attempt to the candidate AP. + If the roaming procedure succeeds, the SME will also issue a Media + Connect indication to inform the wireless manager application of the + change. + NOTE: to prevent the SME from initiating roaming the WMA must specify the + BSSID in the connection request; this forces the SME to connect only to + that AP. + The wireless manager application can obtain statistics for roaming + purposes using CSR_WIFI_SME_CONNECTION_QUALITY_IND and + CSR_WIFI_SME_CONNECTION_STATS_GET_REQ. + When the wireless manager application wishes to roam to another AP, it + must issue a connection request specifying the BSSID of the desired AP. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + roamReason - Indicates the reason for starting the roaming procedure + reason80211 - Indicates the reason for deauthentication or disassociation + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeRoamReason roamReason; + CsrWifiSmeIEEE80211Reason reason80211; +} CsrWifiSmeRoamStartInd; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + roamingConfig - Reports the roaming behaviour of the driver and firmware + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeRoamingConfig roamingConfig; +} CsrWifiSmeRoamingConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeRoamingConfigSetCfm + + DESCRIPTION + This primitive sets the value of the RoamingConfig parameter. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeRoamingConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + scanConfig - Returns the current parameters for the autonomous scanning + behaviour of the firmware + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeScanConfig scanConfig; +} CsrWifiSmeScanConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeScanConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeScanConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeScanFullCfm + + DESCRIPTION + The SME calls this primitive when the results from the scan are + available. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeScanFullCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultInd + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it whenever a scan indication is received from the firmware. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + result - Points to a buffer containing a scan result. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeScanResult result; +} CsrWifiSmeScanResultInd; + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsFlushCfm + + DESCRIPTION + The SME will call this primitive when the cache has been cleared. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeScanResultsFlushCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeScanResultsGetCfm + + DESCRIPTION + The SME sends this primitive to provide the current set of scan results. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + scanResultsCount - Number of scan results + scanResults - Points to a buffer containing an array of + CsrWifiSmeScanResult structures. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrUint16 scanResultsCount; + CsrWifiSmeScanResult *scanResults; +} CsrWifiSmeScanResultsGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + smeConfig - Current SME Station Parameters + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeStaConfig smeConfig; +} CsrWifiSmeSmeStaConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeStaConfigSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; +} CsrWifiSmeSmeStaConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeStationMacAddressGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + stationMacAddress - Current MAC address of the station. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiMacAddress stationMacAddress[2]; +} CsrWifiSmeStationMacAddressGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeTspecInd + + DESCRIPTION + The SME will send this primitive to all the task that have registered to + receive it when a status change in the TSPEC occurs. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + transactionId - Unique Transaction ID for the TSPEC, as assigned by the + driver + tspecResultCode - Specifies the TSPEC operation requested by the peer + station + tspecLength - Length of the TSPEC. + tspec - Points to the first byte of the TSPEC + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint32 transactionId; + CsrWifiSmeTspecResultCode tspecResultCode; + CsrUint16 tspecLength; + CsrUint8 *tspec; +} CsrWifiSmeTspecInd; + +/******************************************************************************* + + NAME + CsrWifiSmeTspecCfm + + DESCRIPTION + The SME calls the primitive to report the result of the TSpec primitive + request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface Identifier; unique identifier of an interface + status - Reports the result of the request + transactionId - Unique Transaction ID for the TSPEC, as assigned by the + driver + tspecResultCode - Specifies the result of the negotiated TSPEC operation + tspecLength - Length of the TSPEC. + tspec - Points to the first byte of the TSPEC + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrUint32 transactionId; + CsrWifiSmeTspecResultCode tspecResultCode; + CsrUint16 tspecLength; + CsrUint8 *tspec; +} CsrWifiSmeTspecCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeVersionsGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + versions - Version IDs of the product + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeVersions versions; +} CsrWifiSmeVersionsGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiFlightmodeCfm + + DESCRIPTION + The SME calls this primitive when the chip is initialised for low power + mode and with the radio subsystem disabled. To leave flight mode, and + enable Wi-Fi, the wireless manager application should call + CSR_WIFI_SME_WIFI_ON_REQ. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeWifiFlightmodeCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOffInd + + DESCRIPTION + The SME sends this primitive to all the tasks that have registered to + receive it to report that the chip has been turned off. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + reason - Indicates the reason why the Wi-Fi has been switched off. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiSmeControlIndication reason; +} CsrWifiSmeWifiOffInd; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOffCfm + + DESCRIPTION + After receiving CSR_WIFI_SME_WIFI_OFF_REQ, if the chip is connected to a + network, the SME will perform a disconnect operation, will send a + CSR_WIFI_SME_MEDIA_STATUS_IND with + CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED, and then will call + CSR_WIFI_SME_WIFI_OFF_CFM when the chip is off. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeWifiOffCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOnCfm + + DESCRIPTION + The SME sends this primitive to the task that has sent the request once + the chip has been initialised and is available for use. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeWifiOnCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsSetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeCloakedSsidsSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeCloakedSsidsGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + cloakedSsids - Reports list of cloaked SSIDs that are explicitly scanned for + by the driver + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeCloakedSsidConfig cloakedSsids; +} CsrWifiSmeCloakedSsidsGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeWifiOnInd + + DESCRIPTION + The SME sends this primitive to all tasks that have registered to receive + it once the chip becomes available and ready to use. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + address - Current MAC address + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiMacAddress address; +} CsrWifiSmeWifiOnInd; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + deviceConfig - Configuration options in the SME + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrWifiSmeDeviceConfig deviceConfig; +} CsrWifiSmeSmeCommonConfigGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeSmeCommonConfigSetCfm + + DESCRIPTION + Reports the result of the request + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Reports the result of the request + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeSmeCommonConfigSetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeInterfaceCapabilityGetCfm + + DESCRIPTION + This primitive reports the result of the request. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Result of the request + numInterfaces - Number of the interfaces supported + capBitmap - Points to the list of capabilities bitmaps provided for each + interface. + The bits represent the following capabilities: + -bits 7 to 4-Reserved + -bit 3-AMP + -bit 2-P2P + -bit 1-AP + -bit 0-STA + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; + CsrUint16 numInterfaces; + CsrUint8 capBitmap[2]; +} CsrWifiSmeInterfaceCapabilityGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeErrorInd + + DESCRIPTION + Important error message indicating a error of some importance + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + errorMessage - Contains the error message. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrCharString *errorMessage; +} CsrWifiSmeErrorInd; + +/******************************************************************************* + + NAME + CsrWifiSmeInfoInd + + DESCRIPTION + Message indicating a some info about current activity. Mostly of interest + in testing but may be useful in the field. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + infoMessage - Contains the message. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrCharString *infoMessage; +} CsrWifiSmeInfoInd; + +/******************************************************************************* + + NAME + CsrWifiSmeCoreDumpInd + + DESCRIPTION + The SME will send this primitive to all the tasks that have registered to + receive Wi-Fi Chip core dump data. + The core dump data may be fragmented and sent using more than one + indication. + To indicate that all the data has been sent, the last indication contains + a 'length' of 0 and 'data' of NULL. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + dataLength - Number of bytes in the buffer pointed to by 'data' + data - Pointer to the buffer containing 'dataLength' bytes of core + dump data + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint32 dataLength; + CsrUint8 *data; +} CsrWifiSmeCoreDumpInd; + +/******************************************************************************* + + NAME + CsrWifiSmeAmpStatusChangeInd + + DESCRIPTION + Indication of change to AMP activity. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - Interface on which the AMP activity changed. + ampStatus - The new status of AMP activity.Range: {AMP_ACTIVE, + AMP_INACTIVE}. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeAmpStatus ampStatus; +} CsrWifiSmeAmpStatusChangeInd; + +/******************************************************************************* + + NAME + CsrWifiSmeWpsConfigurationCfm + + DESCRIPTION + Confirm. + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + status - Status of the request. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrResult status; +} CsrWifiSmeWpsConfigurationCfm; + + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_SME_PRIM_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_sme_sef.c b/drivers/staging/csr/csr_wifi_sme_sef.c new file mode 100644 index 000000000000..cf32254335c4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_sef.c @@ -0,0 +1,85 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + + *****************************************************************************/ +#include "csr_wifi_sme_sef.h" + +const CsrWifiSmeStateHandlerType CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT] = +{ + /* 0x8000 */ CsrWifiSmeActivateCfmHandler, + /* 0x8001 */ CsrWifiSmeAdhocConfigGetCfmHandler, + /* 0x8002 */ CsrWifiSmeAdhocConfigSetCfmHandler, + /* 0x8003 */ CsrWifiSmeAssociationCompleteIndHandler, + /* 0x8004 */ CsrWifiSmeAssociationStartIndHandler, + /* 0x8005 */ CsrWifiSmeBlacklistCfmHandler, + /* 0x8006 */ CsrWifiSmeCalibrationDataGetCfmHandler, + /* 0x8007 */ CsrWifiSmeCalibrationDataSetCfmHandler, + /* 0x8008 */ CsrWifiSmeCcxConfigGetCfmHandler, + /* 0x8009 */ CsrWifiSmeCcxConfigSetCfmHandler, + /* 0x800A */ CsrWifiSmeCoexConfigGetCfmHandler, + /* 0x800B */ CsrWifiSmeCoexConfigSetCfmHandler, + /* 0x800C */ CsrWifiSmeCoexInfoGetCfmHandler, + /* 0x800D */ CsrWifiSmeConnectCfmHandler, + /* 0x800E */ CsrWifiSmeConnectionConfigGetCfmHandler, + /* 0x800F */ CsrWifiSmeConnectionInfoGetCfmHandler, + /* 0x8010 */ CsrWifiSmeConnectionQualityIndHandler, + /* 0x8011 */ CsrWifiSmeConnectionStatsGetCfmHandler, + /* 0x8012 */ CsrWifiSmeDeactivateCfmHandler, + /* 0x8013 */ CsrWifiSmeDisconnectCfmHandler, + /* 0x8014 */ CsrWifiSmeEventMaskSetCfmHandler, + /* 0x8015 */ CsrWifiSmeHostConfigGetCfmHandler, + /* 0x8016 */ CsrWifiSmeHostConfigSetCfmHandler, + /* 0x8017 */ CsrWifiSmeIbssStationIndHandler, + /* 0x8018 */ CsrWifiSmeKeyCfmHandler, + /* 0x8019 */ CsrWifiSmeLinkQualityGetCfmHandler, + /* 0x801A */ CsrWifiSmeMediaStatusIndHandler, + /* 0x801B */ CsrWifiSmeMibConfigGetCfmHandler, + /* 0x801C */ CsrWifiSmeMibConfigSetCfmHandler, + /* 0x801D */ CsrWifiSmeMibGetCfmHandler, + /* 0x801E */ CsrWifiSmeMibGetNextCfmHandler, + /* 0x801F */ CsrWifiSmeMibSetCfmHandler, + /* 0x8020 */ CsrWifiSmeMicFailureIndHandler, + /* 0x8021 */ CsrWifiSmeMulticastAddressCfmHandler, + /* 0x8022 */ CsrWifiSmePacketFilterSetCfmHandler, + /* 0x8023 */ CsrWifiSmePermanentMacAddressGetCfmHandler, + /* 0x8024 */ CsrWifiSmePmkidCandidateListIndHandler, + /* 0x8025 */ CsrWifiSmePmkidCfmHandler, + /* 0x8026 */ CsrWifiSmePowerConfigGetCfmHandler, + /* 0x8027 */ CsrWifiSmePowerConfigSetCfmHandler, + /* 0x8028 */ CsrWifiSmeRegulatoryDomainInfoGetCfmHandler, + /* 0x8029 */ CsrWifiSmeRoamCompleteIndHandler, + /* 0x802A */ CsrWifiSmeRoamStartIndHandler, + /* 0x802B */ CsrWifiSmeRoamingConfigGetCfmHandler, + /* 0x802C */ CsrWifiSmeRoamingConfigSetCfmHandler, + /* 0x802D */ CsrWifiSmeScanConfigGetCfmHandler, + /* 0x802E */ CsrWifiSmeScanConfigSetCfmHandler, + /* 0x802F */ CsrWifiSmeScanFullCfmHandler, + /* 0x8030 */ CsrWifiSmeScanResultIndHandler, + /* 0x8031 */ CsrWifiSmeScanResultsFlushCfmHandler, + /* 0x8032 */ CsrWifiSmeScanResultsGetCfmHandler, + /* 0x8033 */ CsrWifiSmeSmeStaConfigGetCfmHandler, + /* 0x8034 */ CsrWifiSmeSmeStaConfigSetCfmHandler, + /* 0x8035 */ CsrWifiSmeStationMacAddressGetCfmHandler, + /* 0x8036 */ CsrWifiSmeTspecIndHandler, + /* 0x8037 */ CsrWifiSmeTspecCfmHandler, + /* 0x8038 */ CsrWifiSmeVersionsGetCfmHandler, + /* 0x8039 */ CsrWifiSmeWifiFlightmodeCfmHandler, + /* 0x803A */ CsrWifiSmeWifiOffIndHandler, + /* 0x803B */ CsrWifiSmeWifiOffCfmHandler, + /* 0x803C */ CsrWifiSmeWifiOnCfmHandler, + /* 0x803D */ CsrWifiSmeCloakedSsidsSetCfmHandler, + /* 0x803E */ CsrWifiSmeCloakedSsidsGetCfmHandler, + /* 0x803F */ CsrWifiSmeWifiOnIndHandler, + /* 0x8040 */ CsrWifiSmeSmeCommonConfigGetCfmHandler, + /* 0x8041 */ CsrWifiSmeSmeCommonConfigSetCfmHandler, + /* 0x8042 */ CsrWifiSmeGetInterfaceCapabilityCfmHandler, + /* 0x8043 */ CsrWifiSmeErrorIndHandler, + /* 0x8044 */ CsrWifiSmeInfoIndHandler, + /* 0x8045 */ CsrWifiSmeCoreDumpIndHandler, + /* 0x8046 */ CsrWifiSmeAmpStatusChangeIndHandler, +}; diff --git a/drivers/staging/csr/csr_wifi_sme_sef.h b/drivers/staging/csr/csr_wifi_sme_sef.h new file mode 100644 index 000000000000..c8741811b2e4 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_sef.h @@ -0,0 +1,101 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ +#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ +#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ + +#include "csr_wifi_sme_prim.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*CsrWifiSmeStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg); + +extern const CsrWifiSmeStateHandlerType CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT]; + + +extern void CsrWifiSmeActivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeAdhocConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeAdhocConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeAssociationCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeAssociationStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeBlacklistCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCalibrationDataGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCalibrationDataSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCcxConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCcxConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCoexConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCoexConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCoexInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeConnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeConnectionConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeConnectionInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeConnectionQualityIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeConnectionStatsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeDeactivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeDisconnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeEventMaskSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeHostConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeHostConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeIbssStationIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeKeyCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeLinkQualityGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMediaStatusIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMibConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMibConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMibGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMibGetNextCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMibSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMicFailureIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeMulticastAddressCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmePacketFilterSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmePmkidCandidateListIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmePmkidCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmePowerConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmePowerConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeRoamCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeRoamStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeRoamingConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeRoamingConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeScanConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeScanConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeScanFullCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeScanResultIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeScanResultsFlushCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeScanResultsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeStationMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeTspecIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeTspecCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeVersionsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeWifiFlightmodeCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeWifiOffIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeWifiOffCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeWifiOnCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeWifiOnIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeErrorIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeInfoIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeCoreDumpIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeAmpStatusChangeIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.c b/drivers/staging/csr/csr_wifi_sme_serialize.c new file mode 100644 index 000000000000..489c378186bd --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_serialize.c @@ -0,0 +1,5756 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_msgconv.h" +#include "csr_unicode.h" + + +#include "csr_wifi_sme_prim.h" +#include "csr_wifi_sme_serialize.h" + +void CsrWifiSmePfree(void *ptr) +{ + CsrPmemFree(ptr); +} + + +CsrSize CsrWifiSmeAdhocConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.atimWindowTu */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.beaconPeriodTu */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.joinOnlyAttempts */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.joinAttemptIntervalMs */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeAdhocConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeAdhocConfigSetReq *primitive = (CsrWifiSmeAdhocConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.atimWindowTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.beaconPeriodTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.joinOnlyAttempts); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.joinAttemptIntervalMs); + return(ptr); +} + + +void* CsrWifiSmeAdhocConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeAdhocConfigSetReq *primitive = (CsrWifiSmeAdhocConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeAdhocConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.atimWindowTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.beaconPeriodTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.joinOnlyAttempts, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.joinAttemptIntervalMs, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeBlacklistReqSizeof(void *msg) +{ + CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->setAddressCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->setAddresses[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeBlacklistReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->setAddressCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->setAddresses[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiSmeBlacklistReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *) CsrPmemAlloc(sizeof(CsrWifiSmeBlacklistReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->setAddressCount, buffer, &offset); + primitive->setAddresses = NULL; + if (primitive->setAddressCount) + { + primitive->setAddresses = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->setAddressCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressCount; i1++) + { + CsrMemCpyDes(primitive->setAddresses[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +void CsrWifiSmeBlacklistReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *) voidPrimitivePointer; + CsrPmemFree(primitive->setAddresses); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCalibrationDataSetReqSizeof(void *msg) +{ + CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */ + bufferSize += 2; /* CsrUint16 primitive->calibrationDataLength */ + bufferSize += primitive->calibrationDataLength; /* CsrUint8 primitive->calibrationData */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCalibrationDataSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->calibrationDataLength); + if (primitive->calibrationDataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->calibrationData, ((CsrUint16) (primitive->calibrationDataLength))); + } + return(ptr); +} + + +void* CsrWifiSmeCalibrationDataSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCalibrationDataSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->calibrationDataLength, buffer, &offset); + if (primitive->calibrationDataLength) + { + primitive->calibrationData = (CsrUint8 *)CsrPmemAlloc(primitive->calibrationDataLength); + CsrMemCpyDes(primitive->calibrationData, buffer, &offset, ((CsrUint16) (primitive->calibrationDataLength))); + } + else + { + primitive->calibrationData = NULL; + } + + return primitive; +} + + +void CsrWifiSmeCalibrationDataSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->calibrationData); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCcxConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->ccxConfig.keepAliveTimeMs */ + bufferSize += 1; /* CsrBool primitive->ccxConfig.apRoamingEnabled */ + bufferSize += 1; /* CsrUint8 primitive->ccxConfig.measurementsMask */ + bufferSize += 1; /* CsrBool primitive->ccxConfig.ccxRadioMgtEnabled */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCcxConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCcxConfigSetReq *primitive = (CsrWifiSmeCcxConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.keepAliveTimeMs); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.apRoamingEnabled); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.measurementsMask); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.ccxRadioMgtEnabled); + return(ptr); +} + + +void* CsrWifiSmeCcxConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCcxConfigSetReq *primitive = (CsrWifiSmeCcxConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.keepAliveTimeMs, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.apRoamingEnabled, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.measurementsMask, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.ccxRadioMgtEnabled, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeCoexConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 29) */ + bufferSize += 1; /* CsrBool primitive->coexConfig.coexEnableSchemeManagement */ + bufferSize += 1; /* CsrBool primitive->coexConfig.coexPeriodicWakeHost */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexTrafficBurstyLatencyMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexTrafficContinuousLatencyMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexObexBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexObexBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpBrBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpBrBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpEdrBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexPagingBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexPagingBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexInquiryBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexInquiryBlackoutPeriodMs */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCoexConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCoexConfigSetReq *primitive = (CsrWifiSmeCoexConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexConfig.coexEnableSchemeManagement); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexConfig.coexPeriodicWakeHost); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexTrafficBurstyLatencyMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexTrafficContinuousLatencyMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexObexBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexObexBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpBrBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpBrBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpEdrBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexPagingBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexPagingBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexInquiryBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexInquiryBlackoutPeriodMs); + return(ptr); +} + + +void* CsrWifiSmeCoexConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCoexConfigSetReq *primitive = (CsrWifiSmeCoexConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexConfig.coexEnableSchemeManagement, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexConfig.coexPeriodicWakeHost, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexTrafficBurstyLatencyMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexTrafficContinuousLatencyMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexObexBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexObexBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpBrBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpBrBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpEdrBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexPagingBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexPagingBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexInquiryBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexInquiryBlackoutPeriodMs, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeConnectReqSizeof(void *msg) +{ + CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 57) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 32; /* CsrUint8 primitive->connectionConfig.ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->connectionConfig.ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->connectionConfig.bssid.a[6] */ + bufferSize += 1; /* CsrWifiSmeBssType primitive->connectionConfig.bssType */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->connectionConfig.ifIndex */ + bufferSize += 1; /* CsrWifiSme80211PrivacyMode primitive->connectionConfig.privacyMode */ + bufferSize += 2; /* CsrWifiSmeAuthModeMask primitive->connectionConfig.authModeMask */ + bufferSize += 2; /* CsrWifiSmeEncryptionMask primitive->connectionConfig.encryptionModeMask */ + bufferSize += 2; /* CsrUint16 primitive->connectionConfig.mlmeAssociateReqInformationElementsLength */ + bufferSize += primitive->connectionConfig.mlmeAssociateReqInformationElementsLength; /* CsrUint8 primitive->connectionConfig.mlmeAssociateReqInformationElements */ + bufferSize += 1; /* CsrWifiSmeWmmQosInfoMask primitive->connectionConfig.wmmQosInfo */ + bufferSize += 1; /* CsrBool primitive->connectionConfig.adhocJoinOnly */ + bufferSize += 1; /* CsrUint8 primitive->connectionConfig.adhocChannel */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeConnectReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.bssType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.ifIndex); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.privacyMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionConfig.authModeMask); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionConfig.encryptionModeMask); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionConfig.mlmeAssociateReqInformationElementsLength); + if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.mlmeAssociateReqInformationElements, ((CsrUint16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength))); + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.wmmQosInfo); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.adhocJoinOnly); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.adhocChannel); + return(ptr); +} + + +void* CsrWifiSmeConnectReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->connectionConfig.ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->connectionConfig.bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.bssType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.ifIndex, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.privacyMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionConfig.authModeMask, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionConfig.encryptionModeMask, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionConfig.mlmeAssociateReqInformationElementsLength, buffer, &offset); + if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength) + { + primitive->connectionConfig.mlmeAssociateReqInformationElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionConfig.mlmeAssociateReqInformationElementsLength); + CsrMemCpyDes(primitive->connectionConfig.mlmeAssociateReqInformationElements, buffer, &offset, ((CsrUint16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength))); + } + else + { + primitive->connectionConfig.mlmeAssociateReqInformationElements = NULL; + } + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.wmmQosInfo, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.adhocJoinOnly, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.adhocChannel, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeConnectReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *) voidPrimitivePointer; + CsrPmemFree(primitive->connectionConfig.mlmeAssociateReqInformationElements); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeHostConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeHostPowerMode primitive->hostConfig.powerMode */ + bufferSize += 2; /* CsrUint16 primitive->hostConfig.applicationDataPeriodMs */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeHostConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeHostConfigSetReq *primitive = (CsrWifiSmeHostConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->hostConfig.powerMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->hostConfig.applicationDataPeriodMs); + return(ptr); +} + + +void* CsrWifiSmeHostConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeHostConfigSetReq *primitive = (CsrWifiSmeHostConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->hostConfig.powerMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->hostConfig.applicationDataPeriodMs, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeKeyReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 65) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrWifiSmeKeyType primitive->key.keyType */ + bufferSize += 1; /* CsrUint8 primitive->key.keyIndex */ + bufferSize += 1; /* CsrBool primitive->key.wepTxKey */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 8; i2++) + { + bufferSize += 2; /* CsrUint16 primitive->key.keyRsc[8] */ + } + } + bufferSize += 1; /* CsrBool primitive->key.authenticator */ + bufferSize += 6; /* CsrUint8 primitive->key.address.a[6] */ + bufferSize += 1; /* CsrUint8 primitive->key.keyLength */ + bufferSize += 32; /* CsrUint8 primitive->key.key[32] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeKeyReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeKeyReq *primitive = (CsrWifiSmeKeyReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->key.keyType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->key.keyIndex); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->key.wepTxKey); + { + CsrUint16 i2; + for (i2 = 0; i2 < 8; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->key.keyRsc[i2]); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->key.authenticator); + CsrMemCpySer(ptr, len, (const void *) primitive->key.address.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->key.keyLength); + CsrMemCpySer(ptr, len, (const void *) primitive->key.key, ((CsrUint16) (32))); + return(ptr); +} + + +void* CsrWifiSmeKeyReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeKeyReq *primitive = (CsrWifiSmeKeyReq *) CsrPmemAlloc(sizeof(CsrWifiSmeKeyReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->key.keyType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->key.keyIndex, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->key.wepTxKey, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 8; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->key.keyRsc[i2], buffer, &offset); + } + } + CsrUint8Des((CsrUint8 *) &primitive->key.authenticator, buffer, &offset); + CsrMemCpyDes(primitive->key.address.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->key.keyLength, buffer, &offset); + CsrMemCpyDes(primitive->key.key, buffer, &offset, ((CsrUint16) (32))); + + return primitive; +} + + +CsrSize CsrWifiSmeMibConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 1; /* CsrBool primitive->mibConfig.unifiFixMaxTxDataRate */ + bufferSize += 1; /* CsrUint8 primitive->mibConfig.unifiFixTxDataRate */ + bufferSize += 2; /* CsrUint16 primitive->mibConfig.dot11RtsThreshold */ + bufferSize += 2; /* CsrUint16 primitive->mibConfig.dot11FragmentationThreshold */ + bufferSize += 2; /* CsrUint16 primitive->mibConfig.dot11CurrentTxPowerLevel */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibConfigSetReq *primitive = (CsrWifiSmeMibConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mibConfig.unifiFixMaxTxDataRate); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mibConfig.unifiFixTxDataRate); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibConfig.dot11RtsThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibConfig.dot11FragmentationThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibConfig.dot11CurrentTxPowerLevel); + return(ptr); +} + + +void* CsrWifiSmeMibConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibConfigSetReq *primitive = (CsrWifiSmeMibConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mibConfig.unifiFixMaxTxDataRate, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mibConfig.unifiFixTxDataRate, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibConfig.dot11RtsThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibConfig.dot11FragmentationThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibConfig.dot11CurrentTxPowerLevel, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeMibGetNextReqSizeof(void *msg) +{ + CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */ + bufferSize += 2; /* CsrUint16 primitive->mibAttributeLength */ + bufferSize += primitive->mibAttributeLength; /* CsrUint8 primitive->mibAttribute */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibGetNextReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibAttributeLength); + if (primitive->mibAttributeLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((CsrUint16) (primitive->mibAttributeLength))); + } + return(ptr); +} + + +void* CsrWifiSmeMibGetNextReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetNextReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibAttributeLength, buffer, &offset); + if (primitive->mibAttributeLength) + { + primitive->mibAttribute = (CsrUint8 *)CsrPmemAlloc(primitive->mibAttributeLength); + CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((CsrUint16) (primitive->mibAttributeLength))); + } + else + { + primitive->mibAttribute = NULL; + } + + return primitive; +} + + +void CsrWifiSmeMibGetNextReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *) voidPrimitivePointer; + CsrPmemFree(primitive->mibAttribute); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeMibGetReqSizeof(void *msg) +{ + CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */ + bufferSize += 2; /* CsrUint16 primitive->mibAttributeLength */ + bufferSize += primitive->mibAttributeLength; /* CsrUint8 primitive->mibAttribute */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibGetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibAttributeLength); + if (primitive->mibAttributeLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((CsrUint16) (primitive->mibAttributeLength))); + } + return(ptr); +} + + +void* CsrWifiSmeMibGetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibAttributeLength, buffer, &offset); + if (primitive->mibAttributeLength) + { + primitive->mibAttribute = (CsrUint8 *)CsrPmemAlloc(primitive->mibAttributeLength); + CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((CsrUint16) (primitive->mibAttributeLength))); + } + else + { + primitive->mibAttribute = NULL; + } + + return primitive; +} + + +void CsrWifiSmeMibGetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->mibAttribute); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeMibSetReqSizeof(void *msg) +{ + CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */ + bufferSize += 2; /* CsrUint16 primitive->mibAttributeLength */ + bufferSize += primitive->mibAttributeLength; /* CsrUint8 primitive->mibAttribute */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibAttributeLength); + if (primitive->mibAttributeLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((CsrUint16) (primitive->mibAttributeLength))); + } + return(ptr); +} + + +void* CsrWifiSmeMibSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMibSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibAttributeLength, buffer, &offset); + if (primitive->mibAttributeLength) + { + primitive->mibAttribute = (CsrUint8 *)CsrPmemAlloc(primitive->mibAttributeLength); + CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((CsrUint16) (primitive->mibAttributeLength))); + } + else + { + primitive->mibAttribute = NULL; + } + + return primitive; +} + + +void CsrWifiSmeMibSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->mibAttribute); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeMulticastAddressReqSizeof(void *msg) +{ + CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->setAddressesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressesCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->setAddresses[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMulticastAddressReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->setAddressesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressesCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->setAddresses[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiSmeMulticastAddressReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *) CsrPmemAlloc(sizeof(CsrWifiSmeMulticastAddressReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->setAddressesCount, buffer, &offset); + primitive->setAddresses = NULL; + if (primitive->setAddressesCount) + { + primitive->setAddresses = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->setAddressesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setAddressesCount; i1++) + { + CsrMemCpyDes(primitive->setAddresses[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +void CsrWifiSmeMulticastAddressReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *) voidPrimitivePointer; + CsrPmemFree(primitive->setAddresses); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmePacketFilterSetReqSizeof(void *msg) +{ + CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrUint16 primitive->filterLength */ + bufferSize += primitive->filterLength; /* CsrUint8 primitive->filter */ + bufferSize += 1; /* CsrWifiSmePacketFilterMode primitive->mode */ + bufferSize += 4; /* CsrUint8 primitive->arpFilterAddress.a[4] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmePacketFilterSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->filterLength); + if (primitive->filterLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->filter, ((CsrUint16) (primitive->filterLength))); + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mode); + CsrMemCpySer(ptr, len, (const void *) primitive->arpFilterAddress.a, ((CsrUint16) (4))); + return(ptr); +} + + +void* CsrWifiSmePacketFilterSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmePacketFilterSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->filterLength, buffer, &offset); + if (primitive->filterLength) + { + primitive->filter = (CsrUint8 *)CsrPmemAlloc(primitive->filterLength); + CsrMemCpyDes(primitive->filter, buffer, &offset, ((CsrUint16) (primitive->filterLength))); + } + else + { + primitive->filter = NULL; + } + CsrUint8Des((CsrUint8 *) &primitive->mode, buffer, &offset); + CsrMemCpyDes(primitive->arpFilterAddress.a, buffer, &offset, ((CsrUint16) (4))); + + return primitive; +} + + +void CsrWifiSmePacketFilterSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->filter); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmePmkidReqSizeof(void *msg) +{ + CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 29) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->setPmkidsCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setPmkidsCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->setPmkids[i1].bssid.a[6] */ + bufferSize += 16; /* CsrUint8 primitive->setPmkids[i1].pmkid[16] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmePmkidReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->setPmkidsCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setPmkidsCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->setPmkids[i1].bssid.a, ((CsrUint16) (6))); + CsrMemCpySer(ptr, len, (const void *) primitive->setPmkids[i1].pmkid, ((CsrUint16) (16))); + } + } + return(ptr); +} + + +void* CsrWifiSmePmkidReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *) CsrPmemAlloc(sizeof(CsrWifiSmePmkidReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->setPmkidsCount, buffer, &offset); + primitive->setPmkids = NULL; + if (primitive->setPmkidsCount) + { + primitive->setPmkids = (CsrWifiSmePmkid *)CsrPmemAlloc(sizeof(CsrWifiSmePmkid) * primitive->setPmkidsCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->setPmkidsCount; i1++) + { + CsrMemCpyDes(primitive->setPmkids[i1].bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrMemCpyDes(primitive->setPmkids[i1].pmkid, buffer, &offset, ((CsrUint16) (16))); + } + } + + return primitive; +} + + +void CsrWifiSmePmkidReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *) voidPrimitivePointer; + CsrPmemFree(primitive->setPmkids); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmePowerConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 1; /* CsrWifiSmePowerSaveLevel primitive->powerConfig.powerSaveLevel */ + bufferSize += 2; /* CsrUint16 primitive->powerConfig.listenIntervalTu */ + bufferSize += 1; /* CsrBool primitive->powerConfig.rxDtims */ + bufferSize += 1; /* CsrWifiSmeD3AutoScanMode primitive->powerConfig.d3AutoScanMode */ + bufferSize += 1; /* CsrUint8 primitive->powerConfig.clientTrafficWindow */ + bufferSize += 1; /* CsrBool primitive->powerConfig.opportunisticPowerSave */ + bufferSize += 1; /* CsrBool primitive->powerConfig.noticeOfAbsence */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmePowerConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePowerConfigSetReq *primitive = (CsrWifiSmePowerConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.powerSaveLevel); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->powerConfig.listenIntervalTu); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.rxDtims); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.d3AutoScanMode); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.clientTrafficWindow); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.opportunisticPowerSave); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.noticeOfAbsence); + return(ptr); +} + + +void* CsrWifiSmePowerConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePowerConfigSetReq *primitive = (CsrWifiSmePowerConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmePowerConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.powerSaveLevel, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->powerConfig.listenIntervalTu, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.rxDtims, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.d3AutoScanMode, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.clientTrafficWindow, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.opportunisticPowerSave, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.noticeOfAbsence, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeRoamingConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 70) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].rssiHighThreshold */ + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].rssiLowThreshold */ + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].snrHighThreshold */ + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].snrLowThreshold */ + } + } + bufferSize += 1; /* CsrBool primitive->roamingConfig.disableSmoothRoaming */ + bufferSize += 1; /* CsrBool primitive->roamingConfig.disableRoamScans */ + bufferSize += 1; /* CsrUint8 primitive->roamingConfig.reconnectLimit */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.reconnectLimitIntervalMs */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].intervalSeconds */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].validitySeconds */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeRoamingConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeRoamingConfigSetReq *primitive = (CsrWifiSmeRoamingConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].rssiHighThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].rssiLowThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].snrHighThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].snrLowThreshold); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamingConfig.disableSmoothRoaming); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamingConfig.disableRoamScans); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamingConfig.reconnectLimit); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.reconnectLimitIntervalMs); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].intervalSeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].validitySeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu); + } + } + return(ptr); +} + + +void* CsrWifiSmeRoamingConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeRoamingConfigSetReq *primitive = (CsrWifiSmeRoamingConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].rssiHighThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].rssiLowThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].snrHighThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].snrLowThreshold, buffer, &offset); + } + } + CsrUint8Des((CsrUint8 *) &primitive->roamingConfig.disableSmoothRoaming, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->roamingConfig.disableRoamScans, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->roamingConfig.reconnectLimit, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.reconnectLimitIntervalMs, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].intervalSeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].validitySeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset); + } + } + + return primitive; +} + + +CsrSize CsrWifiSmeScanConfigSetReqSizeof(void *msg) +{ + CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 63) */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].intervalSeconds */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].validitySeconds */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu */ + } + } + bufferSize += 1; /* CsrBool primitive->scanConfig.disableAutonomousScans */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.maxResults */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.highRssiThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.lowRssiThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.deltaRssiThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.highSnrThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.lowSnrThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.deltaSnrThreshold */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.passiveChannelListCount */ + bufferSize += primitive->scanConfig.passiveChannelListCount; /* CsrUint8 primitive->scanConfig.passiveChannelList */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeScanConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].intervalSeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].validitySeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.disableAutonomousScans); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.maxResults); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.highRssiThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.lowRssiThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.deltaRssiThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.highSnrThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.lowSnrThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.deltaSnrThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.passiveChannelListCount); + if (primitive->scanConfig.passiveChannelListCount) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanConfig.passiveChannelList, ((CsrUint16) (primitive->scanConfig.passiveChannelListCount))); + } + return(ptr); +} + + +void* CsrWifiSmeScanConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].intervalSeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].validitySeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset); + } + } + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.disableAutonomousScans, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.maxResults, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.highRssiThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.lowRssiThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.deltaRssiThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.highSnrThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.lowSnrThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.deltaSnrThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.passiveChannelListCount, buffer, &offset); + if (primitive->scanConfig.passiveChannelListCount) + { + primitive->scanConfig.passiveChannelList = (CsrUint8 *)CsrPmemAlloc(primitive->scanConfig.passiveChannelListCount); + CsrMemCpyDes(primitive->scanConfig.passiveChannelList, buffer, &offset, ((CsrUint16) (primitive->scanConfig.passiveChannelListCount))); + } + else + { + primitive->scanConfig.passiveChannelList = NULL; + } + + return primitive; +} + + +void CsrWifiSmeScanConfigSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->scanConfig.passiveChannelList); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeScanFullReqSizeof(void *msg) +{ + CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 52) */ + bufferSize += 1; /* CsrUint8 primitive->ssidCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->ssidCount; i1++) + { + bufferSize += 32; /* CsrUint8 primitive->ssid[i1].ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->ssid[i1].length */ + } + } + bufferSize += 6; /* CsrUint8 primitive->bssid.a[6] */ + bufferSize += 1; /* CsrBool primitive->forceScan */ + bufferSize += 1; /* CsrWifiSmeBssType primitive->bssType */ + bufferSize += 1; /* CsrWifiSmeScanType primitive->scanType */ + bufferSize += 2; /* CsrUint16 primitive->channelListCount */ + bufferSize += primitive->channelListCount; /* CsrUint8 primitive->channelList */ + bufferSize += 2; /* CsrUint16 primitive->probeIeLength */ + bufferSize += primitive->probeIeLength; /* CsrUint8 primitive->probeIe */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeScanFullReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ssidCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->ssidCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->ssid[i1].ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ssid[i1].length); + } + } + CsrMemCpySer(ptr, len, (const void *) primitive->bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->forceScan); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->bssType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->channelListCount); + if (primitive->channelListCount) + { + CsrMemCpySer(ptr, len, (const void *) primitive->channelList, ((CsrUint16) (primitive->channelListCount))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->probeIeLength); + if (primitive->probeIeLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->probeIe, ((CsrUint16) (primitive->probeIeLength))); + } + return(ptr); +} + + +void* CsrWifiSmeScanFullReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *) CsrPmemAlloc(sizeof(CsrWifiSmeScanFullReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ssidCount, buffer, &offset); + primitive->ssid = NULL; + if (primitive->ssidCount) + { + primitive->ssid = (CsrWifiSsid *)CsrPmemAlloc(sizeof(CsrWifiSsid) * primitive->ssidCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->ssidCount; i1++) + { + CsrMemCpyDes(primitive->ssid[i1].ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->ssid[i1].length, buffer, &offset); + } + } + CsrMemCpyDes(primitive->bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->forceScan, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->bssType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->channelListCount, buffer, &offset); + if (primitive->channelListCount) + { + primitive->channelList = (CsrUint8 *)CsrPmemAlloc(primitive->channelListCount); + CsrMemCpyDes(primitive->channelList, buffer, &offset, ((CsrUint16) (primitive->channelListCount))); + } + else + { + primitive->channelList = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->probeIeLength, buffer, &offset); + if (primitive->probeIeLength) + { + primitive->probeIe = (CsrUint8 *)CsrPmemAlloc(primitive->probeIeLength); + CsrMemCpyDes(primitive->probeIe, buffer, &offset, ((CsrUint16) (primitive->probeIeLength))); + } + else + { + primitive->probeIe = NULL; + } + + return primitive; +} + + +void CsrWifiSmeScanFullReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *) voidPrimitivePointer; + CsrPmemFree(primitive->ssid); + CsrPmemFree(primitive->channelList); + CsrPmemFree(primitive->probeIe); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */ + bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */ + bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */ + bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */ + bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeSmeStaConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeSmeStaConfigSetReq *primitive = (CsrWifiSmeSmeStaConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.connectionQualityRssiChangeTrigger); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.connectionQualitySnrChangeTrigger); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.wmmModeMask); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.ifIndex); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.allowUnicastUseGroupCipher); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.enableOpportunisticKeyCaching); + return(ptr); +} + + +void* CsrWifiSmeSmeStaConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeSmeStaConfigSetReq *primitive = (CsrWifiSmeSmeStaConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.connectionQualityRssiChangeTrigger, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.connectionQualitySnrChangeTrigger, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.wmmModeMask, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.ifIndex, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.allowUnicastUseGroupCipher, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.enableOpportunisticKeyCaching, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeTspecReqSizeof(void *msg) +{ + CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 18) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 4; /* CsrUint32 primitive->transactionId */ + bufferSize += 1; /* CsrBool primitive->strict */ + bufferSize += 1; /* CsrWifiSmeTspecCtrlMask primitive->ctrlMask */ + bufferSize += 2; /* CsrUint16 primitive->tspecLength */ + bufferSize += primitive->tspecLength; /* CsrUint8 primitive->tspec */ + bufferSize += 2; /* CsrUint16 primitive->tclasLength */ + bufferSize += primitive->tclasLength; /* CsrUint8 primitive->tclas */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeTspecReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->transactionId); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->strict); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ctrlMask); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->tspecLength); + if (primitive->tspecLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->tspec, ((CsrUint16) (primitive->tspecLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->tclasLength); + if (primitive->tclasLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->tclas, ((CsrUint16) (primitive->tclasLength))); + } + return(ptr); +} + + +void* CsrWifiSmeTspecReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *) CsrPmemAlloc(sizeof(CsrWifiSmeTspecReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->transactionId, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->strict, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ctrlMask, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->tspecLength, buffer, &offset); + if (primitive->tspecLength) + { + primitive->tspec = (CsrUint8 *)CsrPmemAlloc(primitive->tspecLength); + CsrMemCpyDes(primitive->tspec, buffer, &offset, ((CsrUint16) (primitive->tspecLength))); + } + else + { + primitive->tspec = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->tclasLength, buffer, &offset); + if (primitive->tclasLength) + { + primitive->tclas = (CsrUint8 *)CsrPmemAlloc(primitive->tclasLength); + CsrMemCpyDes(primitive->tclas, buffer, &offset, ((CsrUint16) (primitive->tclasLength))); + } + else + { + primitive->tclas = NULL; + } + + return primitive; +} + + +void CsrWifiSmeTspecReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *) voidPrimitivePointer; + CsrPmemFree(primitive->tspec); + CsrPmemFree(primitive->tclas); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeWifiFlightmodeReqSizeof(void *msg) +{ + CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */ + bufferSize += 6; /* CsrUint8 primitive->address.a[6] */ + bufferSize += 2; /* CsrUint16 primitive->mibFilesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + bufferSize += 2; /* CsrUint16 primitive->mibFiles[i1].length */ + bufferSize += primitive->mibFiles[i1].length; /* CsrUint8 primitive->mibFiles[i1].data */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeWifiFlightmodeReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibFilesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibFiles[i1].length); + if (primitive->mibFiles[i1].length) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibFiles[i1].data, ((CsrUint16) (primitive->mibFiles[i1].length))); + } + } + } + return(ptr); +} + + +void* CsrWifiSmeWifiFlightmodeReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiFlightmodeReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrMemCpyDes(primitive->address.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->mibFilesCount, buffer, &offset); + primitive->mibFiles = NULL; + if (primitive->mibFilesCount) + { + primitive->mibFiles = (CsrWifiSmeDataBlock *)CsrPmemAlloc(sizeof(CsrWifiSmeDataBlock) * primitive->mibFilesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + CsrUint16Des((CsrUint16 *) &primitive->mibFiles[i1].length, buffer, &offset); + if (primitive->mibFiles[i1].length) + { + primitive->mibFiles[i1].data = (CsrUint8 *)CsrPmemAlloc(primitive->mibFiles[i1].length); + CsrMemCpyDes(primitive->mibFiles[i1].data, buffer, &offset, ((CsrUint16) (primitive->mibFiles[i1].length))); + } + else + { + primitive->mibFiles[i1].data = NULL; + } + } + } + + return primitive; +} + + +void CsrWifiSmeWifiFlightmodeReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *) voidPrimitivePointer; + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + CsrPmemFree(primitive->mibFiles[i1].data); + } + } + CsrPmemFree(primitive->mibFiles); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeWifiOnReqSizeof(void *msg) +{ + CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */ + bufferSize += 6; /* CsrUint8 primitive->address.a[6] */ + bufferSize += 2; /* CsrUint16 primitive->mibFilesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + bufferSize += 2; /* CsrUint16 primitive->mibFiles[i1].length */ + bufferSize += primitive->mibFiles[i1].length; /* CsrUint8 primitive->mibFiles[i1].data */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibFilesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibFiles[i1].length); + if (primitive->mibFiles[i1].length) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibFiles[i1].data, ((CsrUint16) (primitive->mibFiles[i1].length))); + } + } + } + return(ptr); +} + + +void* CsrWifiSmeWifiOnReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOnReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrMemCpyDes(primitive->address.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->mibFilesCount, buffer, &offset); + primitive->mibFiles = NULL; + if (primitive->mibFilesCount) + { + primitive->mibFiles = (CsrWifiSmeDataBlock *)CsrPmemAlloc(sizeof(CsrWifiSmeDataBlock) * primitive->mibFilesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + CsrUint16Des((CsrUint16 *) &primitive->mibFiles[i1].length, buffer, &offset); + if (primitive->mibFiles[i1].length) + { + primitive->mibFiles[i1].data = (CsrUint8 *)CsrPmemAlloc(primitive->mibFiles[i1].length); + CsrMemCpyDes(primitive->mibFiles[i1].data, buffer, &offset, ((CsrUint16) (primitive->mibFiles[i1].length))); + } + else + { + primitive->mibFiles[i1].data = NULL; + } + } + } + + return primitive; +} + + +void CsrWifiSmeWifiOnReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *) voidPrimitivePointer; + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->mibFilesCount; i1++) + { + CsrPmemFree(primitive->mibFiles[i1].data); + } + } + CsrPmemFree(primitive->mibFiles); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCloakedSsidsSetReqSizeof(void *msg) +{ + CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 37) */ + bufferSize += 1; /* CsrUint8 primitive->cloakedSsids.cloakedSsidsCount */ + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++) + { + bufferSize += 32; /* CsrUint8 primitive->cloakedSsids.cloakedSsids[i2].ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->cloakedSsids.cloakedSsids[i2].length */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCloakedSsidsSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->cloakedSsids.cloakedSsidsCount); + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->cloakedSsids.cloakedSsids[i2].ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->cloakedSsids.cloakedSsids[i2].length); + } + } + return(ptr); +} + + +void* CsrWifiSmeCloakedSsidsSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeCloakedSsidsSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->cloakedSsids.cloakedSsidsCount, buffer, &offset); + primitive->cloakedSsids.cloakedSsids = NULL; + if (primitive->cloakedSsids.cloakedSsidsCount) + { + primitive->cloakedSsids.cloakedSsids = (CsrWifiSsid *)CsrPmemAlloc(sizeof(CsrWifiSsid) * primitive->cloakedSsids.cloakedSsidsCount); + } + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++) + { + CsrMemCpyDes(primitive->cloakedSsids.cloakedSsids[i2].ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->cloakedSsids.cloakedSsids[i2].length, buffer, &offset); + } + } + + return primitive; +} + + +void CsrWifiSmeCloakedSsidsSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->cloakedSsids.cloakedSsids); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 1; /* CsrWifiSme80211dTrustLevel primitive->deviceConfig.trustLevel */ + bufferSize += 2; /* CsrUint8 primitive->deviceConfig.countryCode[2] */ + bufferSize += 1; /* CsrWifiSmeFirmwareDriverInterface primitive->deviceConfig.firmwareDriverInterface */ + bufferSize += 1; /* CsrBool primitive->deviceConfig.enableStrictDraftN */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeSmeCommonConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeSmeCommonConfigSetReq *primitive = (CsrWifiSmeSmeCommonConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->deviceConfig.trustLevel); + CsrMemCpySer(ptr, len, (const void *) primitive->deviceConfig.countryCode, ((CsrUint16) (2))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->deviceConfig.firmwareDriverInterface); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->deviceConfig.enableStrictDraftN); + return(ptr); +} + + +void* CsrWifiSmeSmeCommonConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeSmeCommonConfigSetReq *primitive = (CsrWifiSmeSmeCommonConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeCommonConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->deviceConfig.trustLevel, buffer, &offset); + CsrMemCpyDes(primitive->deviceConfig.countryCode, buffer, &offset, ((CsrUint16) (2))); + CsrUint8Des((CsrUint8 *) &primitive->deviceConfig.firmwareDriverInterface, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->deviceConfig.enableStrictDraftN, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeWpsConfigurationReqSizeof(void *msg) +{ + CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 240) */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.wpsVersion */ + bufferSize += 16; /* CsrUint8 primitive->wpsConfig.uuid[16] */ + bufferSize += 32; /* CsrUint8 primitive->wpsConfig.deviceName[32] */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.deviceNameLength */ + bufferSize += 64; /* CsrUint8 primitive->wpsConfig.manufacturer[64] */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.manufacturerLength */ + bufferSize += 32; /* CsrUint8 primitive->wpsConfig.modelName[32] */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.modelNameLength */ + bufferSize += 32; /* CsrUint8 primitive->wpsConfig.modelNumber[32] */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.modelNumberLength */ + bufferSize += 32; /* CsrUint8 primitive->wpsConfig.serialNumber[32] */ + bufferSize += 8; /* CsrUint8 primitive->wpsConfig.primDeviceType.deviceDetails[8] */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.secondaryDeviceTypeCount */ + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->wpsConfig.secondaryDeviceTypeCount; i2++) + { + bufferSize += 8; /* CsrUint8 primitive->wpsConfig.secondaryDeviceType[i2].deviceDetails[8] */ + } + } + bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->wpsConfig.configMethods */ + bufferSize += 1; /* CsrUint8 primitive->wpsConfig.rfBands */ + bufferSize += 4; /* CsrUint8 primitive->wpsConfig.osVersion[4] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeWpsConfigurationReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.wpsVersion); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.uuid, ((CsrUint16) (16))); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.deviceName, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.deviceNameLength); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.manufacturer, ((CsrUint16) (64))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.manufacturerLength); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.modelName, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.modelNameLength); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.modelNumber, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.modelNumberLength); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.serialNumber, ((CsrUint16) (32))); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.primDeviceType.deviceDetails, ((CsrUint16) (8))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.secondaryDeviceTypeCount); + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->wpsConfig.secondaryDeviceTypeCount; i2++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.secondaryDeviceType[i2].deviceDetails, ((CsrUint16) (8))); + } + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->wpsConfig.configMethods); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsConfig.rfBands); + CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.osVersion, ((CsrUint16) (4))); + return(ptr); +} + + +void* CsrWifiSmeWpsConfigurationReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *) CsrPmemAlloc(sizeof(CsrWifiSmeWpsConfigurationReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.wpsVersion, buffer, &offset); + CsrMemCpyDes(primitive->wpsConfig.uuid, buffer, &offset, ((CsrUint16) (16))); + CsrMemCpyDes(primitive->wpsConfig.deviceName, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.deviceNameLength, buffer, &offset); + CsrMemCpyDes(primitive->wpsConfig.manufacturer, buffer, &offset, ((CsrUint16) (64))); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.manufacturerLength, buffer, &offset); + CsrMemCpyDes(primitive->wpsConfig.modelName, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.modelNameLength, buffer, &offset); + CsrMemCpyDes(primitive->wpsConfig.modelNumber, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.modelNumberLength, buffer, &offset); + CsrMemCpyDes(primitive->wpsConfig.serialNumber, buffer, &offset, ((CsrUint16) (32))); + CsrMemCpyDes(primitive->wpsConfig.primDeviceType.deviceDetails, buffer, &offset, ((CsrUint16) (8))); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.secondaryDeviceTypeCount, buffer, &offset); + primitive->wpsConfig.secondaryDeviceType = NULL; + if (primitive->wpsConfig.secondaryDeviceTypeCount) + { + primitive->wpsConfig.secondaryDeviceType = (CsrWifiSmeWpsDeviceType *)CsrPmemAlloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->wpsConfig.secondaryDeviceTypeCount); + } + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->wpsConfig.secondaryDeviceTypeCount; i2++) + { + CsrMemCpyDes(primitive->wpsConfig.secondaryDeviceType[i2].deviceDetails, buffer, &offset, ((CsrUint16) (8))); + } + } + CsrUint16Des((CsrUint16 *) &primitive->wpsConfig.configMethods, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wpsConfig.rfBands, buffer, &offset); + CsrMemCpyDes(primitive->wpsConfig.osVersion, buffer, &offset, ((CsrUint16) (4))); + + return primitive; +} + + +void CsrWifiSmeWpsConfigurationReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *) voidPrimitivePointer; + CsrPmemFree(primitive->wpsConfig.secondaryDeviceType); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.atimWindowTu */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.beaconPeriodTu */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.joinOnlyAttempts */ + bufferSize += 2; /* CsrUint16 primitive->adHocConfig.joinAttemptIntervalMs */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeAdhocConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeAdhocConfigGetCfm *primitive = (CsrWifiSmeAdhocConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.atimWindowTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.beaconPeriodTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.joinOnlyAttempts); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->adHocConfig.joinAttemptIntervalMs); + return(ptr); +} + + +void* CsrWifiSmeAdhocConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeAdhocConfigGetCfm *primitive = (CsrWifiSmeAdhocConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeAdhocConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.atimWindowTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.beaconPeriodTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.joinOnlyAttempts, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->adHocConfig.joinAttemptIntervalMs, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeAssociationCompleteIndSizeof(void *msg) +{ + CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 98) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 32; /* CsrUint8 primitive->connectionInfo.ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->connectionInfo.ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->connectionInfo.bssid.a[6] */ + bufferSize += 1; /* CsrWifiSme80211NetworkType primitive->connectionInfo.networkType80211 */ + bufferSize += 1; /* CsrUint8 primitive->connectionInfo.channelNumber */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.channelFrequency */ + bufferSize += 2; /* CsrWifiSmeAuthMode primitive->connectionInfo.authMode */ + bufferSize += 2; /* CsrWifiSmeEncryption primitive->connectionInfo.pairwiseCipher */ + bufferSize += 2; /* CsrWifiSmeEncryption primitive->connectionInfo.groupCipher */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->connectionInfo.ifIndex */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.atimWindowTu */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.beaconPeriodTu */ + bufferSize += 1; /* CsrBool primitive->connectionInfo.reassociation */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.beaconFrameLength */ + bufferSize += primitive->connectionInfo.beaconFrameLength; /* CsrUint8 primitive->connectionInfo.beaconFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.associationReqFrameLength */ + bufferSize += primitive->connectionInfo.associationReqFrameLength; /* CsrUint8 primitive->connectionInfo.associationReqFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.associationRspFrameLength */ + bufferSize += primitive->connectionInfo.associationRspFrameLength; /* CsrUint8 primitive->connectionInfo.associationRspFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocScanInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocScanInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocScanInfoElements */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqCapabilities */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqListenIntervalTu */ + bufferSize += 6; /* CsrUint8 primitive->connectionInfo.assocReqApAddress.a[6] */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocReqInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocReqInfoElements */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Result primitive->connectionInfo.assocRspResult */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspCapabilityInfo */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspAssociationId */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocRspInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocRspInfoElements */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Reason primitive->deauthReason */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeAssociationCompleteIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.networkType80211); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.channelNumber); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.channelFrequency); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.authMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.pairwiseCipher); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.groupCipher); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.ifIndex); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.atimWindowTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.beaconPeriodTu); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.reassociation); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.beaconFrameLength); + if (primitive->connectionInfo.beaconFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.beaconFrame, ((CsrUint16) (primitive->connectionInfo.beaconFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.associationReqFrameLength); + if (primitive->connectionInfo.associationReqFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationReqFrame, ((CsrUint16) (primitive->connectionInfo.associationReqFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.associationRspFrameLength); + if (primitive->connectionInfo.associationRspFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationRspFrame, ((CsrUint16) (primitive->connectionInfo.associationRspFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocScanInfoElementsLength); + if (primitive->connectionInfo.assocScanInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocScanInfoElements, ((CsrUint16) (primitive->connectionInfo.assocScanInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqCapabilities); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqListenIntervalTu); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqApAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqInfoElementsLength); + if (primitive->connectionInfo.assocReqInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqInfoElements, ((CsrUint16) (primitive->connectionInfo.assocReqInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspResult); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspCapabilityInfo); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspAssociationId); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspInfoElementsLength); + if (primitive->connectionInfo.assocRspInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocRspInfoElements, ((CsrUint16) (primitive->connectionInfo.assocRspInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->deauthReason); + return(ptr); +} + + +void* CsrWifiSmeAssociationCompleteIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *) CsrPmemAlloc(sizeof(CsrWifiSmeAssociationCompleteInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.networkType80211, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.channelNumber, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.channelFrequency, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.authMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.pairwiseCipher, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.groupCipher, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.ifIndex, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.atimWindowTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.beaconPeriodTu, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.reassociation, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.beaconFrameLength, buffer, &offset); + if (primitive->connectionInfo.beaconFrameLength) + { + primitive->connectionInfo.beaconFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.beaconFrameLength); + CsrMemCpyDes(primitive->connectionInfo.beaconFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.beaconFrameLength))); + } + else + { + primitive->connectionInfo.beaconFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.associationReqFrameLength, buffer, &offset); + if (primitive->connectionInfo.associationReqFrameLength) + { + primitive->connectionInfo.associationReqFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.associationReqFrameLength); + CsrMemCpyDes(primitive->connectionInfo.associationReqFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.associationReqFrameLength))); + } + else + { + primitive->connectionInfo.associationReqFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.associationRspFrameLength, buffer, &offset); + if (primitive->connectionInfo.associationRspFrameLength) + { + primitive->connectionInfo.associationRspFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.associationRspFrameLength); + CsrMemCpyDes(primitive->connectionInfo.associationRspFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.associationRspFrameLength))); + } + else + { + primitive->connectionInfo.associationRspFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocScanInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocScanInfoElementsLength) + { + primitive->connectionInfo.assocScanInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocScanInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocScanInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocScanInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocScanInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqCapabilities, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqListenIntervalTu, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.assocReqApAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocReqInfoElementsLength) + { + primitive->connectionInfo.assocReqInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocReqInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocReqInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocReqInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocReqInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspResult, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspCapabilityInfo, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspAssociationId, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocRspInfoElementsLength) + { + primitive->connectionInfo.assocRspInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocRspInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocRspInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocRspInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocRspInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->deauthReason, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeAssociationCompleteIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *) voidPrimitivePointer; + CsrPmemFree(primitive->connectionInfo.beaconFrame); + CsrPmemFree(primitive->connectionInfo.associationReqFrame); + CsrPmemFree(primitive->connectionInfo.associationRspFrame); + CsrPmemFree(primitive->connectionInfo.assocScanInfoElements); + CsrPmemFree(primitive->connectionInfo.assocReqInfoElements); + CsrPmemFree(primitive->connectionInfo.assocRspInfoElements); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeAssociationStartIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 44) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->address.a[6] */ + bufferSize += 32; /* CsrUint8 primitive->ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->ssid.length */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeAssociationStartIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeAssociationStartInd *primitive = (CsrWifiSmeAssociationStartInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((CsrUint16) (6))); + CsrMemCpySer(ptr, len, (const void *) primitive->ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ssid.length); + return(ptr); +} + + +void* CsrWifiSmeAssociationStartIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeAssociationStartInd *primitive = (CsrWifiSmeAssociationStartInd *) CsrPmemAlloc(sizeof(CsrWifiSmeAssociationStartInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->address.a, buffer, &offset, ((CsrUint16) (6))); + CsrMemCpyDes(primitive->ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->ssid.length, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeBlacklistCfmSizeof(void *msg) +{ + CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->getAddressCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->getAddresses[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeBlacklistCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->getAddressCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->getAddresses[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiSmeBlacklistCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeBlacklistCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->getAddressCount, buffer, &offset); + primitive->getAddresses = NULL; + if (primitive->getAddressCount) + { + primitive->getAddresses = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->getAddressCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressCount; i1++) + { + CsrMemCpyDes(primitive->getAddresses[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +void CsrWifiSmeBlacklistCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->getAddresses); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCalibrationDataGetCfmSizeof(void *msg) +{ + CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->calibrationDataLength */ + bufferSize += primitive->calibrationDataLength; /* CsrUint8 primitive->calibrationData */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCalibrationDataGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->calibrationDataLength); + if (primitive->calibrationDataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->calibrationData, ((CsrUint16) (primitive->calibrationDataLength))); + } + return(ptr); +} + + +void* CsrWifiSmeCalibrationDataGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCalibrationDataGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->calibrationDataLength, buffer, &offset); + if (primitive->calibrationDataLength) + { + primitive->calibrationData = (CsrUint8 *)CsrPmemAlloc(primitive->calibrationDataLength); + CsrMemCpyDes(primitive->calibrationData, buffer, &offset, ((CsrUint16) (primitive->calibrationDataLength))); + } + else + { + primitive->calibrationData = NULL; + } + + return primitive; +} + + +void CsrWifiSmeCalibrationDataGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->calibrationData); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCcxConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrUint8 primitive->ccxConfig.keepAliveTimeMs */ + bufferSize += 1; /* CsrBool primitive->ccxConfig.apRoamingEnabled */ + bufferSize += 1; /* CsrUint8 primitive->ccxConfig.measurementsMask */ + bufferSize += 1; /* CsrBool primitive->ccxConfig.ccxRadioMgtEnabled */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCcxConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCcxConfigGetCfm *primitive = (CsrWifiSmeCcxConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.keepAliveTimeMs); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.apRoamingEnabled); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.measurementsMask); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ccxConfig.ccxRadioMgtEnabled); + return(ptr); +} + + +void* CsrWifiSmeCcxConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCcxConfigGetCfm *primitive = (CsrWifiSmeCcxConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.keepAliveTimeMs, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.apRoamingEnabled, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.measurementsMask, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ccxConfig.ccxRadioMgtEnabled, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeCcxConfigSetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCcxConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCcxConfigSetCfm *primitive = (CsrWifiSmeCcxConfigSetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeCcxConfigSetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCcxConfigSetCfm *primitive = (CsrWifiSmeCcxConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCcxConfigSetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeCoexConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 31) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrBool primitive->coexConfig.coexEnableSchemeManagement */ + bufferSize += 1; /* CsrBool primitive->coexConfig.coexPeriodicWakeHost */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexTrafficBurstyLatencyMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexTrafficContinuousLatencyMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexObexBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexObexBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpBrBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpBrBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpEdrBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexPagingBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexPagingBlackoutPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexInquiryBlackoutDurationMs */ + bufferSize += 2; /* CsrUint16 primitive->coexConfig.coexInquiryBlackoutPeriodMs */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCoexConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCoexConfigGetCfm *primitive = (CsrWifiSmeCoexConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexConfig.coexEnableSchemeManagement); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexConfig.coexPeriodicWakeHost); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexTrafficBurstyLatencyMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexTrafficContinuousLatencyMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexObexBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexObexBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpBrBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpBrBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpEdrBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexPagingBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexPagingBlackoutPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexInquiryBlackoutDurationMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexConfig.coexInquiryBlackoutPeriodMs); + return(ptr); +} + + +void* CsrWifiSmeCoexConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCoexConfigGetCfm *primitive = (CsrWifiSmeCoexConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexConfig.coexEnableSchemeManagement, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexConfig.coexPeriodicWakeHost, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexTrafficBurstyLatencyMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexTrafficContinuousLatencyMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexObexBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexObexBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpBrBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpBrBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpEdrBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexPagingBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexPagingBlackoutPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexInquiryBlackoutDurationMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexConfig.coexInquiryBlackoutPeriodMs, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeCoexInfoGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 24) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrBool primitive->coexInfo.hasTrafficData */ + bufferSize += 1; /* CsrWifiSmeTrafficType primitive->coexInfo.currentTrafficType */ + bufferSize += 2; /* CsrUint16 primitive->coexInfo.currentPeriodMs */ + bufferSize += 1; /* CsrWifiSmePowerSaveLevel primitive->coexInfo.currentPowerSave */ + bufferSize += 2; /* CsrUint16 primitive->coexInfo.currentCoexPeriodMs */ + bufferSize += 2; /* CsrUint16 primitive->coexInfo.currentCoexLatencyMs */ + bufferSize += 1; /* CsrBool primitive->coexInfo.hasBtDevice */ + bufferSize += 4; /* CsrUint32 primitive->coexInfo.currentBlackoutDurationUs */ + bufferSize += 4; /* CsrUint32 primitive->coexInfo.currentBlackoutPeriodUs */ + bufferSize += 1; /* CsrWifiSmeCoexScheme primitive->coexInfo.currentCoexScheme */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCoexInfoGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCoexInfoGetCfm *primitive = (CsrWifiSmeCoexInfoGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexInfo.hasTrafficData); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexInfo.currentTrafficType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexInfo.currentPeriodMs); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexInfo.currentPowerSave); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexInfo.currentCoexPeriodMs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->coexInfo.currentCoexLatencyMs); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexInfo.hasBtDevice); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->coexInfo.currentBlackoutDurationUs); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->coexInfo.currentBlackoutPeriodUs); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->coexInfo.currentCoexScheme); + return(ptr); +} + + +void* CsrWifiSmeCoexInfoGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCoexInfoGetCfm *primitive = (CsrWifiSmeCoexInfoGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCoexInfoGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexInfo.hasTrafficData, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexInfo.currentTrafficType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexInfo.currentPeriodMs, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexInfo.currentPowerSave, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexInfo.currentCoexPeriodMs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->coexInfo.currentCoexLatencyMs, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexInfo.hasBtDevice, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->coexInfo.currentBlackoutDurationUs, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->coexInfo.currentBlackoutPeriodUs, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->coexInfo.currentCoexScheme, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeConnectCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeConnectCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeConnectCfm *primitive = (CsrWifiSmeConnectCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeConnectCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeConnectCfm *primitive = (CsrWifiSmeConnectCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeConnectionConfigGetCfmSizeof(void *msg) +{ + CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 59) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 32; /* CsrUint8 primitive->connectionConfig.ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->connectionConfig.ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->connectionConfig.bssid.a[6] */ + bufferSize += 1; /* CsrWifiSmeBssType primitive->connectionConfig.bssType */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->connectionConfig.ifIndex */ + bufferSize += 1; /* CsrWifiSme80211PrivacyMode primitive->connectionConfig.privacyMode */ + bufferSize += 2; /* CsrWifiSmeAuthModeMask primitive->connectionConfig.authModeMask */ + bufferSize += 2; /* CsrWifiSmeEncryptionMask primitive->connectionConfig.encryptionModeMask */ + bufferSize += 2; /* CsrUint16 primitive->connectionConfig.mlmeAssociateReqInformationElementsLength */ + bufferSize += primitive->connectionConfig.mlmeAssociateReqInformationElementsLength; /* CsrUint8 primitive->connectionConfig.mlmeAssociateReqInformationElements */ + bufferSize += 1; /* CsrWifiSmeWmmQosInfoMask primitive->connectionConfig.wmmQosInfo */ + bufferSize += 1; /* CsrBool primitive->connectionConfig.adhocJoinOnly */ + bufferSize += 1; /* CsrUint8 primitive->connectionConfig.adhocChannel */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeConnectionConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.bssType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.ifIndex); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.privacyMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionConfig.authModeMask); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionConfig.encryptionModeMask); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionConfig.mlmeAssociateReqInformationElementsLength); + if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.mlmeAssociateReqInformationElements, ((CsrUint16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength))); + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.wmmQosInfo); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.adhocJoinOnly); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionConfig.adhocChannel); + return(ptr); +} + + +void* CsrWifiSmeConnectionConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrMemCpyDes(primitive->connectionConfig.ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->connectionConfig.bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.bssType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.ifIndex, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.privacyMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionConfig.authModeMask, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionConfig.encryptionModeMask, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionConfig.mlmeAssociateReqInformationElementsLength, buffer, &offset); + if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength) + { + primitive->connectionConfig.mlmeAssociateReqInformationElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionConfig.mlmeAssociateReqInformationElementsLength); + CsrMemCpyDes(primitive->connectionConfig.mlmeAssociateReqInformationElements, buffer, &offset, ((CsrUint16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength))); + } + else + { + primitive->connectionConfig.mlmeAssociateReqInformationElements = NULL; + } + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.wmmQosInfo, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.adhocJoinOnly, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionConfig.adhocChannel, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeConnectionConfigGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->connectionConfig.mlmeAssociateReqInformationElements); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeConnectionInfoGetCfmSizeof(void *msg) +{ + CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 96) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 32; /* CsrUint8 primitive->connectionInfo.ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->connectionInfo.ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->connectionInfo.bssid.a[6] */ + bufferSize += 1; /* CsrWifiSme80211NetworkType primitive->connectionInfo.networkType80211 */ + bufferSize += 1; /* CsrUint8 primitive->connectionInfo.channelNumber */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.channelFrequency */ + bufferSize += 2; /* CsrWifiSmeAuthMode primitive->connectionInfo.authMode */ + bufferSize += 2; /* CsrWifiSmeEncryption primitive->connectionInfo.pairwiseCipher */ + bufferSize += 2; /* CsrWifiSmeEncryption primitive->connectionInfo.groupCipher */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->connectionInfo.ifIndex */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.atimWindowTu */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.beaconPeriodTu */ + bufferSize += 1; /* CsrBool primitive->connectionInfo.reassociation */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.beaconFrameLength */ + bufferSize += primitive->connectionInfo.beaconFrameLength; /* CsrUint8 primitive->connectionInfo.beaconFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.associationReqFrameLength */ + bufferSize += primitive->connectionInfo.associationReqFrameLength; /* CsrUint8 primitive->connectionInfo.associationReqFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.associationRspFrameLength */ + bufferSize += primitive->connectionInfo.associationRspFrameLength; /* CsrUint8 primitive->connectionInfo.associationRspFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocScanInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocScanInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocScanInfoElements */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqCapabilities */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqListenIntervalTu */ + bufferSize += 6; /* CsrUint8 primitive->connectionInfo.assocReqApAddress.a[6] */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocReqInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocReqInfoElements */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Result primitive->connectionInfo.assocRspResult */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspCapabilityInfo */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspAssociationId */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocRspInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocRspInfoElements */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeConnectionInfoGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.networkType80211); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.channelNumber); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.channelFrequency); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.authMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.pairwiseCipher); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.groupCipher); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.ifIndex); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.atimWindowTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.beaconPeriodTu); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.reassociation); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.beaconFrameLength); + if (primitive->connectionInfo.beaconFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.beaconFrame, ((CsrUint16) (primitive->connectionInfo.beaconFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.associationReqFrameLength); + if (primitive->connectionInfo.associationReqFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationReqFrame, ((CsrUint16) (primitive->connectionInfo.associationReqFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.associationRspFrameLength); + if (primitive->connectionInfo.associationRspFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationRspFrame, ((CsrUint16) (primitive->connectionInfo.associationRspFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocScanInfoElementsLength); + if (primitive->connectionInfo.assocScanInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocScanInfoElements, ((CsrUint16) (primitive->connectionInfo.assocScanInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqCapabilities); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqListenIntervalTu); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqApAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqInfoElementsLength); + if (primitive->connectionInfo.assocReqInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqInfoElements, ((CsrUint16) (primitive->connectionInfo.assocReqInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspResult); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspCapabilityInfo); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspAssociationId); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspInfoElementsLength); + if (primitive->connectionInfo.assocRspInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocRspInfoElements, ((CsrUint16) (primitive->connectionInfo.assocRspInfoElementsLength))); + } + return(ptr); +} + + +void* CsrWifiSmeConnectionInfoGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionInfoGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.networkType80211, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.channelNumber, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.channelFrequency, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.authMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.pairwiseCipher, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.groupCipher, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.ifIndex, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.atimWindowTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.beaconPeriodTu, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.reassociation, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.beaconFrameLength, buffer, &offset); + if (primitive->connectionInfo.beaconFrameLength) + { + primitive->connectionInfo.beaconFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.beaconFrameLength); + CsrMemCpyDes(primitive->connectionInfo.beaconFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.beaconFrameLength))); + } + else + { + primitive->connectionInfo.beaconFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.associationReqFrameLength, buffer, &offset); + if (primitive->connectionInfo.associationReqFrameLength) + { + primitive->connectionInfo.associationReqFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.associationReqFrameLength); + CsrMemCpyDes(primitive->connectionInfo.associationReqFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.associationReqFrameLength))); + } + else + { + primitive->connectionInfo.associationReqFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.associationRspFrameLength, buffer, &offset); + if (primitive->connectionInfo.associationRspFrameLength) + { + primitive->connectionInfo.associationRspFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.associationRspFrameLength); + CsrMemCpyDes(primitive->connectionInfo.associationRspFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.associationRspFrameLength))); + } + else + { + primitive->connectionInfo.associationRspFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocScanInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocScanInfoElementsLength) + { + primitive->connectionInfo.assocScanInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocScanInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocScanInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocScanInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocScanInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqCapabilities, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqListenIntervalTu, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.assocReqApAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocReqInfoElementsLength) + { + primitive->connectionInfo.assocReqInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocReqInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocReqInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocReqInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocReqInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspResult, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspCapabilityInfo, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspAssociationId, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocRspInfoElementsLength) + { + primitive->connectionInfo.assocRspInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocRspInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocRspInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocRspInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocRspInfoElements = NULL; + } + + return primitive; +} + + +void CsrWifiSmeConnectionInfoGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->connectionInfo.beaconFrame); + CsrPmemFree(primitive->connectionInfo.associationReqFrame); + CsrPmemFree(primitive->connectionInfo.associationRspFrame); + CsrPmemFree(primitive->connectionInfo.assocScanInfoElements); + CsrPmemFree(primitive->connectionInfo.assocReqInfoElements); + CsrPmemFree(primitive->connectionInfo.assocRspInfoElements); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeConnectionQualityIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrInt16 primitive->linkQuality.unifiRssi */ + bufferSize += 2; /* CsrInt16 primitive->linkQuality.unifiSnr */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeConnectionQualityIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeConnectionQualityInd *primitive = (CsrWifiSmeConnectionQualityInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->linkQuality.unifiRssi); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->linkQuality.unifiSnr); + return(ptr); +} + + +void* CsrWifiSmeConnectionQualityIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeConnectionQualityInd *primitive = (CsrWifiSmeConnectionQualityInd *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionQualityInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->linkQuality.unifiRssi, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->linkQuality.unifiSnr, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 101) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrUint8 primitive->connectionStats.unifiTxDataRate */ + bufferSize += 1; /* CsrUint8 primitive->connectionStats.unifiRxDataRate */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RetryCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11MultipleRetryCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11AckFailureCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11FrameDuplicateCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11FcsErrorCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RtsSuccessCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RtsFailureCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11FailedCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11TransmittedFragmentCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11TransmittedFrameCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11WepExcludedCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11WepIcvErrorCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11WepUndecryptableCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11MulticastReceivedFrameCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11MulticastTransmittedFrameCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11ReceivedFragmentCount */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11Rsna4WayHandshakeFailures */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RsnaTkipCounterMeasuresInvoked */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RsnaStatsTkipLocalMicFailures */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RsnaStatsTkipReplays */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RsnaStatsTkipIcvErrors */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RsnaStatsCcmpReplays */ + bufferSize += 4; /* CsrUint32 primitive->connectionStats.dot11RsnaStatsCcmpDecryptErrors */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeConnectionStatsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeConnectionStatsGetCfm *primitive = (CsrWifiSmeConnectionStatsGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionStats.unifiTxDataRate); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionStats.unifiRxDataRate); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RetryCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11MultipleRetryCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11AckFailureCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11FrameDuplicateCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11FcsErrorCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RtsSuccessCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RtsFailureCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11FailedCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11TransmittedFragmentCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11TransmittedFrameCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11WepExcludedCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11WepIcvErrorCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11WepUndecryptableCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11MulticastReceivedFrameCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11MulticastTransmittedFrameCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11ReceivedFragmentCount); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11Rsna4WayHandshakeFailures); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RsnaTkipCounterMeasuresInvoked); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RsnaStatsTkipLocalMicFailures); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RsnaStatsTkipReplays); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RsnaStatsTkipIcvErrors); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RsnaStatsCcmpReplays); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->connectionStats.dot11RsnaStatsCcmpDecryptErrors); + return(ptr); +} + + +void* CsrWifiSmeConnectionStatsGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeConnectionStatsGetCfm *primitive = (CsrWifiSmeConnectionStatsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeConnectionStatsGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionStats.unifiTxDataRate, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionStats.unifiRxDataRate, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RetryCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11MultipleRetryCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11AckFailureCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11FrameDuplicateCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11FcsErrorCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RtsSuccessCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RtsFailureCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11FailedCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11TransmittedFragmentCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11TransmittedFrameCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11WepExcludedCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11WepIcvErrorCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11WepUndecryptableCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11MulticastReceivedFrameCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11MulticastTransmittedFrameCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11ReceivedFragmentCount, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11Rsna4WayHandshakeFailures, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RsnaTkipCounterMeasuresInvoked, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RsnaStatsTkipLocalMicFailures, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RsnaStatsTkipReplays, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RsnaStatsTkipIcvErrors, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RsnaStatsCcmpReplays, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->connectionStats.dot11RsnaStatsCcmpDecryptErrors, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeDisconnectCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeDisconnectCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeDisconnectCfm *primitive = (CsrWifiSmeDisconnectCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeDisconnectCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeDisconnectCfm *primitive = (CsrWifiSmeDisconnectCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeDisconnectCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeHostConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSmeHostPowerMode primitive->hostConfig.powerMode */ + bufferSize += 2; /* CsrUint16 primitive->hostConfig.applicationDataPeriodMs */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeHostConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeHostConfigGetCfm *primitive = (CsrWifiSmeHostConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->hostConfig.powerMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->hostConfig.applicationDataPeriodMs); + return(ptr); +} + + +void* CsrWifiSmeHostConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeHostConfigGetCfm *primitive = (CsrWifiSmeHostConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->hostConfig.powerMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->hostConfig.applicationDataPeriodMs, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeHostConfigSetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeHostConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeHostConfigSetCfm *primitive = (CsrWifiSmeHostConfigSetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeHostConfigSetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeHostConfigSetCfm *primitive = (CsrWifiSmeHostConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeHostConfigSetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeIbssStationIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 6; /* CsrUint8 primitive->address.a[6] */ + bufferSize += 1; /* CsrBool primitive->isconnected */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeIbssStationIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeIbssStationInd *primitive = (CsrWifiSmeIbssStationInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->isconnected); + return(ptr); +} + + +void* CsrWifiSmeIbssStationIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeIbssStationInd *primitive = (CsrWifiSmeIbssStationInd *) CsrPmemAlloc(sizeof(CsrWifiSmeIbssStationInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrMemCpyDes(primitive->address.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->isconnected, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeKeyCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrWifiSmeKeyType primitive->keyType */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeKeyCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeKeyCfm *primitive = (CsrWifiSmeKeyCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->keyType); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiSmeKeyCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeKeyCfm *primitive = (CsrWifiSmeKeyCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeKeyCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->keyType, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiSmeLinkQualityGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrInt16 primitive->linkQuality.unifiRssi */ + bufferSize += 2; /* CsrInt16 primitive->linkQuality.unifiSnr */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeLinkQualityGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeLinkQualityGetCfm *primitive = (CsrWifiSmeLinkQualityGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->linkQuality.unifiRssi); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->linkQuality.unifiSnr); + return(ptr); +} + + +void* CsrWifiSmeLinkQualityGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeLinkQualityGetCfm *primitive = (CsrWifiSmeLinkQualityGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeLinkQualityGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->linkQuality.unifiRssi, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->linkQuality.unifiSnr, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeMediaStatusIndSizeof(void *msg) +{ + CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 99) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeMediaStatus primitive->mediaStatus */ + bufferSize += 32; /* CsrUint8 primitive->connectionInfo.ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->connectionInfo.ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->connectionInfo.bssid.a[6] */ + bufferSize += 1; /* CsrWifiSme80211NetworkType primitive->connectionInfo.networkType80211 */ + bufferSize += 1; /* CsrUint8 primitive->connectionInfo.channelNumber */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.channelFrequency */ + bufferSize += 2; /* CsrWifiSmeAuthMode primitive->connectionInfo.authMode */ + bufferSize += 2; /* CsrWifiSmeEncryption primitive->connectionInfo.pairwiseCipher */ + bufferSize += 2; /* CsrWifiSmeEncryption primitive->connectionInfo.groupCipher */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->connectionInfo.ifIndex */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.atimWindowTu */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.beaconPeriodTu */ + bufferSize += 1; /* CsrBool primitive->connectionInfo.reassociation */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.beaconFrameLength */ + bufferSize += primitive->connectionInfo.beaconFrameLength; /* CsrUint8 primitive->connectionInfo.beaconFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.associationReqFrameLength */ + bufferSize += primitive->connectionInfo.associationReqFrameLength; /* CsrUint8 primitive->connectionInfo.associationReqFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.associationRspFrameLength */ + bufferSize += primitive->connectionInfo.associationRspFrameLength; /* CsrUint8 primitive->connectionInfo.associationRspFrame */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocScanInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocScanInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocScanInfoElements */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqCapabilities */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqListenIntervalTu */ + bufferSize += 6; /* CsrUint8 primitive->connectionInfo.assocReqApAddress.a[6] */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocReqInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocReqInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocReqInfoElements */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Result primitive->connectionInfo.assocRspResult */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspCapabilityInfo */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspAssociationId */ + bufferSize += 2; /* CsrUint16 primitive->connectionInfo.assocRspInfoElementsLength */ + bufferSize += primitive->connectionInfo.assocRspInfoElementsLength; /* CsrUint8 primitive->connectionInfo.assocRspInfoElements */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Reason primitive->disassocReason */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Reason primitive->deauthReason */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMediaStatusIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mediaStatus); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.networkType80211); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.channelNumber); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.channelFrequency); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.authMode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.pairwiseCipher); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.groupCipher); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.ifIndex); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.atimWindowTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.beaconPeriodTu); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->connectionInfo.reassociation); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.beaconFrameLength); + if (primitive->connectionInfo.beaconFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.beaconFrame, ((CsrUint16) (primitive->connectionInfo.beaconFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.associationReqFrameLength); + if (primitive->connectionInfo.associationReqFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationReqFrame, ((CsrUint16) (primitive->connectionInfo.associationReqFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.associationRspFrameLength); + if (primitive->connectionInfo.associationRspFrameLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationRspFrame, ((CsrUint16) (primitive->connectionInfo.associationRspFrameLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocScanInfoElementsLength); + if (primitive->connectionInfo.assocScanInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocScanInfoElements, ((CsrUint16) (primitive->connectionInfo.assocScanInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqCapabilities); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqListenIntervalTu); + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqApAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocReqInfoElementsLength); + if (primitive->connectionInfo.assocReqInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqInfoElements, ((CsrUint16) (primitive->connectionInfo.assocReqInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspResult); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspCapabilityInfo); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspAssociationId); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->connectionInfo.assocRspInfoElementsLength); + if (primitive->connectionInfo.assocRspInfoElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocRspInfoElements, ((CsrUint16) (primitive->connectionInfo.assocRspInfoElementsLength))); + } + CsrUint16Ser(ptr, len, (CsrUint16) primitive->disassocReason); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->deauthReason); + return(ptr); +} + + +void* CsrWifiSmeMediaStatusIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *) CsrPmemAlloc(sizeof(CsrWifiSmeMediaStatusInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mediaStatus, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.networkType80211, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.channelNumber, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.channelFrequency, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.authMode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.pairwiseCipher, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.groupCipher, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.ifIndex, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.atimWindowTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.beaconPeriodTu, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->connectionInfo.reassociation, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.beaconFrameLength, buffer, &offset); + if (primitive->connectionInfo.beaconFrameLength) + { + primitive->connectionInfo.beaconFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.beaconFrameLength); + CsrMemCpyDes(primitive->connectionInfo.beaconFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.beaconFrameLength))); + } + else + { + primitive->connectionInfo.beaconFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.associationReqFrameLength, buffer, &offset); + if (primitive->connectionInfo.associationReqFrameLength) + { + primitive->connectionInfo.associationReqFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.associationReqFrameLength); + CsrMemCpyDes(primitive->connectionInfo.associationReqFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.associationReqFrameLength))); + } + else + { + primitive->connectionInfo.associationReqFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.associationRspFrameLength, buffer, &offset); + if (primitive->connectionInfo.associationRspFrameLength) + { + primitive->connectionInfo.associationRspFrame = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.associationRspFrameLength); + CsrMemCpyDes(primitive->connectionInfo.associationRspFrame, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.associationRspFrameLength))); + } + else + { + primitive->connectionInfo.associationRspFrame = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocScanInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocScanInfoElementsLength) + { + primitive->connectionInfo.assocScanInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocScanInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocScanInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocScanInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocScanInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqCapabilities, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqListenIntervalTu, buffer, &offset); + CsrMemCpyDes(primitive->connectionInfo.assocReqApAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocReqInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocReqInfoElementsLength) + { + primitive->connectionInfo.assocReqInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocReqInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocReqInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocReqInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocReqInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspResult, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspCapabilityInfo, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspAssociationId, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->connectionInfo.assocRspInfoElementsLength, buffer, &offset); + if (primitive->connectionInfo.assocRspInfoElementsLength) + { + primitive->connectionInfo.assocRspInfoElements = (CsrUint8 *)CsrPmemAlloc(primitive->connectionInfo.assocRspInfoElementsLength); + CsrMemCpyDes(primitive->connectionInfo.assocRspInfoElements, buffer, &offset, ((CsrUint16) (primitive->connectionInfo.assocRspInfoElementsLength))); + } + else + { + primitive->connectionInfo.assocRspInfoElements = NULL; + } + CsrUint16Des((CsrUint16 *) &primitive->disassocReason, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->deauthReason, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeMediaStatusIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *) voidPrimitivePointer; + CsrPmemFree(primitive->connectionInfo.beaconFrame); + CsrPmemFree(primitive->connectionInfo.associationReqFrame); + CsrPmemFree(primitive->connectionInfo.associationRspFrame); + CsrPmemFree(primitive->connectionInfo.assocScanInfoElements); + CsrPmemFree(primitive->connectionInfo.assocReqInfoElements); + CsrPmemFree(primitive->connectionInfo.assocRspInfoElements); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeMibConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrBool primitive->mibConfig.unifiFixMaxTxDataRate */ + bufferSize += 1; /* CsrUint8 primitive->mibConfig.unifiFixTxDataRate */ + bufferSize += 2; /* CsrUint16 primitive->mibConfig.dot11RtsThreshold */ + bufferSize += 2; /* CsrUint16 primitive->mibConfig.dot11FragmentationThreshold */ + bufferSize += 2; /* CsrUint16 primitive->mibConfig.dot11CurrentTxPowerLevel */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibConfigGetCfm *primitive = (CsrWifiSmeMibConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mibConfig.unifiFixMaxTxDataRate); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mibConfig.unifiFixTxDataRate); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibConfig.dot11RtsThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibConfig.dot11FragmentationThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibConfig.dot11CurrentTxPowerLevel); + return(ptr); +} + + +void* CsrWifiSmeMibConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibConfigGetCfm *primitive = (CsrWifiSmeMibConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mibConfig.unifiFixMaxTxDataRate, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mibConfig.unifiFixTxDataRate, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibConfig.dot11RtsThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibConfig.dot11FragmentationThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibConfig.dot11CurrentTxPowerLevel, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeMibGetCfmSizeof(void *msg) +{ + CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->mibAttributeLength */ + bufferSize += primitive->mibAttributeLength; /* CsrUint8 primitive->mibAttribute */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibAttributeLength); + if (primitive->mibAttributeLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((CsrUint16) (primitive->mibAttributeLength))); + } + return(ptr); +} + + +void* CsrWifiSmeMibGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibAttributeLength, buffer, &offset); + if (primitive->mibAttributeLength) + { + primitive->mibAttribute = (CsrUint8 *)CsrPmemAlloc(primitive->mibAttributeLength); + CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((CsrUint16) (primitive->mibAttributeLength))); + } + else + { + primitive->mibAttribute = NULL; + } + + return primitive; +} + + +void CsrWifiSmeMibGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->mibAttribute); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeMibGetNextCfmSizeof(void *msg) +{ + CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->mibAttributeLength */ + bufferSize += primitive->mibAttributeLength; /* CsrUint8 primitive->mibAttribute */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMibGetNextCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->mibAttributeLength); + if (primitive->mibAttributeLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((CsrUint16) (primitive->mibAttributeLength))); + } + return(ptr); +} + + +void* CsrWifiSmeMibGetNextCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMibGetNextCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->mibAttributeLength, buffer, &offset); + if (primitive->mibAttributeLength) + { + primitive->mibAttribute = (CsrUint8 *)CsrPmemAlloc(primitive->mibAttributeLength); + CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((CsrUint16) (primitive->mibAttributeLength))); + } + else + { + primitive->mibAttribute = NULL; + } + + return primitive; +} + + +void CsrWifiSmeMibGetNextCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->mibAttribute); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeMicFailureIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrBool primitive->secondFailure */ + bufferSize += 2; /* CsrUint16 primitive->count */ + bufferSize += 6; /* CsrUint8 primitive->address.a[6] */ + bufferSize += 1; /* CsrWifiSmeKeyType primitive->keyType */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMicFailureIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMicFailureInd *primitive = (CsrWifiSmeMicFailureInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->secondFailure); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->count); + CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->keyType); + return(ptr); +} + + +void* CsrWifiSmeMicFailureIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMicFailureInd *primitive = (CsrWifiSmeMicFailureInd *) CsrPmemAlloc(sizeof(CsrWifiSmeMicFailureInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->secondFailure, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->count, buffer, &offset); + CsrMemCpyDes(primitive->address.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->keyType, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeMulticastAddressCfmSizeof(void *msg) +{ + CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->getAddressesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressesCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->getAddresses[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeMulticastAddressCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->getAddressesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressesCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->getAddresses[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiSmeMulticastAddressCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeMulticastAddressCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->getAddressesCount, buffer, &offset); + primitive->getAddresses = NULL; + if (primitive->getAddressesCount) + { + primitive->getAddresses = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->getAddressesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getAddressesCount; i1++) + { + CsrMemCpyDes(primitive->getAddresses[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +void CsrWifiSmeMulticastAddressCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->getAddresses); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmePacketFilterSetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmePacketFilterSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePacketFilterSetCfm *primitive = (CsrWifiSmePacketFilterSetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmePacketFilterSetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePacketFilterSetCfm *primitive = (CsrWifiSmePacketFilterSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePacketFilterSetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 6; /* CsrUint8 primitive->permanentMacAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmePermanentMacAddressGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePermanentMacAddressGetCfm *primitive = (CsrWifiSmePermanentMacAddressGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrMemCpySer(ptr, len, (const void *) primitive->permanentMacAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiSmePermanentMacAddressGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePermanentMacAddressGetCfm *primitive = (CsrWifiSmePermanentMacAddressGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePermanentMacAddressGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrMemCpyDes(primitive->permanentMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiSmePmkidCandidateListIndSizeof(void *msg) +{ + CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrUint8 primitive->pmkidCandidatesCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->pmkidCandidatesCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->pmkidCandidates[i1].bssid.a[6] */ + bufferSize += 1; /* CsrBool primitive->pmkidCandidates[i1].preAuthAllowed */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmePmkidCandidateListIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->pmkidCandidatesCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->pmkidCandidatesCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->pmkidCandidates[i1].bssid.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->pmkidCandidates[i1].preAuthAllowed); + } + } + return(ptr); +} + + +void* CsrWifiSmePmkidCandidateListIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *) CsrPmemAlloc(sizeof(CsrWifiSmePmkidCandidateListInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->pmkidCandidatesCount, buffer, &offset); + primitive->pmkidCandidates = NULL; + if (primitive->pmkidCandidatesCount) + { + primitive->pmkidCandidates = (CsrWifiSmePmkidCandidate *)CsrPmemAlloc(sizeof(CsrWifiSmePmkidCandidate) * primitive->pmkidCandidatesCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->pmkidCandidatesCount; i1++) + { + CsrMemCpyDes(primitive->pmkidCandidates[i1].bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->pmkidCandidates[i1].preAuthAllowed, buffer, &offset); + } + } + + return primitive; +} + + +void CsrWifiSmePmkidCandidateListIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *) voidPrimitivePointer; + CsrPmemFree(primitive->pmkidCandidates); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmePmkidCfmSizeof(void *msg) +{ + CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 31) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSmeListAction primitive->action */ + bufferSize += 1; /* CsrUint8 primitive->getPmkidsCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getPmkidsCount; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->getPmkids[i1].bssid.a[6] */ + bufferSize += 16; /* CsrUint8 primitive->getPmkids[i1].pmkid[16] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmePmkidCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->action); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->getPmkidsCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getPmkidsCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->getPmkids[i1].bssid.a, ((CsrUint16) (6))); + CsrMemCpySer(ptr, len, (const void *) primitive->getPmkids[i1].pmkid, ((CsrUint16) (16))); + } + } + return(ptr); +} + + +void* CsrWifiSmePmkidCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePmkidCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->action, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->getPmkidsCount, buffer, &offset); + primitive->getPmkids = NULL; + if (primitive->getPmkidsCount) + { + primitive->getPmkids = (CsrWifiSmePmkid *)CsrPmemAlloc(sizeof(CsrWifiSmePmkid) * primitive->getPmkidsCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->getPmkidsCount; i1++) + { + CsrMemCpyDes(primitive->getPmkids[i1].bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrMemCpyDes(primitive->getPmkids[i1].pmkid, buffer, &offset, ((CsrUint16) (16))); + } + } + + return primitive; +} + + +void CsrWifiSmePmkidCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->getPmkids); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmePowerConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSmePowerSaveLevel primitive->powerConfig.powerSaveLevel */ + bufferSize += 2; /* CsrUint16 primitive->powerConfig.listenIntervalTu */ + bufferSize += 1; /* CsrBool primitive->powerConfig.rxDtims */ + bufferSize += 1; /* CsrWifiSmeD3AutoScanMode primitive->powerConfig.d3AutoScanMode */ + bufferSize += 1; /* CsrUint8 primitive->powerConfig.clientTrafficWindow */ + bufferSize += 1; /* CsrBool primitive->powerConfig.opportunisticPowerSave */ + bufferSize += 1; /* CsrBool primitive->powerConfig.noticeOfAbsence */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmePowerConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmePowerConfigGetCfm *primitive = (CsrWifiSmePowerConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.powerSaveLevel); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->powerConfig.listenIntervalTu); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.rxDtims); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.d3AutoScanMode); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.clientTrafficWindow); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.opportunisticPowerSave); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->powerConfig.noticeOfAbsence); + return(ptr); +} + + +void* CsrWifiSmePowerConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmePowerConfigGetCfm *primitive = (CsrWifiSmePowerConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmePowerConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.powerSaveLevel, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->powerConfig.listenIntervalTu, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.rxDtims, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.d3AutoScanMode, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.clientTrafficWindow, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.opportunisticPowerSave, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->powerConfig.noticeOfAbsence, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrBool primitive->regDomInfo.dot11MultiDomainCapabilityImplemented */ + bufferSize += 1; /* CsrBool primitive->regDomInfo.dot11MultiDomainCapabilityEnabled */ + bufferSize += 1; /* CsrWifiSmeRegulatoryDomain primitive->regDomInfo.currentRegulatoryDomain */ + bufferSize += 2; /* CsrUint8 primitive->regDomInfo.currentCountryCode[2] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeRegulatoryDomainInfoGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeRegulatoryDomainInfoGetCfm *primitive = (CsrWifiSmeRegulatoryDomainInfoGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->regDomInfo.dot11MultiDomainCapabilityImplemented); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->regDomInfo.dot11MultiDomainCapabilityEnabled); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->regDomInfo.currentRegulatoryDomain); + CsrMemCpySer(ptr, len, (const void *) primitive->regDomInfo.currentCountryCode, ((CsrUint16) (2))); + return(ptr); +} + + +void* CsrWifiSmeRegulatoryDomainInfoGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeRegulatoryDomainInfoGetCfm *primitive = (CsrWifiSmeRegulatoryDomainInfoGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeRegulatoryDomainInfoGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->regDomInfo.dot11MultiDomainCapabilityImplemented, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->regDomInfo.dot11MultiDomainCapabilityEnabled, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->regDomInfo.currentRegulatoryDomain, buffer, &offset); + CsrMemCpyDes(primitive->regDomInfo.currentCountryCode, buffer, &offset, ((CsrUint16) (2))); + + return primitive; +} + + +CsrSize CsrWifiSmeRoamCompleteIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeRoamCompleteIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeRoamCompleteInd *primitive = (CsrWifiSmeRoamCompleteInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeRoamCompleteIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeRoamCompleteInd *primitive = (CsrWifiSmeRoamCompleteInd *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamCompleteInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeRoamStartIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeRoamReason primitive->roamReason */ + bufferSize += 2; /* CsrWifiSmeIEEE80211Reason primitive->reason80211 */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeRoamStartIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeRoamStartInd *primitive = (CsrWifiSmeRoamStartInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamReason); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->reason80211); + return(ptr); +} + + +void* CsrWifiSmeRoamStartIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeRoamStartInd *primitive = (CsrWifiSmeRoamStartInd *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamStartInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->roamReason, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->reason80211, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeRoamingConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 72) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].rssiHighThreshold */ + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].rssiLowThreshold */ + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].snrHighThreshold */ + bufferSize += 2; /* CsrInt16 primitive->roamingConfig.roamingBands[i2].snrLowThreshold */ + } + } + bufferSize += 1; /* CsrBool primitive->roamingConfig.disableSmoothRoaming */ + bufferSize += 1; /* CsrBool primitive->roamingConfig.disableRoamScans */ + bufferSize += 1; /* CsrUint8 primitive->roamingConfig.reconnectLimit */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.reconnectLimitIntervalMs */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].intervalSeconds */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].validitySeconds */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeRoamingConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeRoamingConfigGetCfm *primitive = (CsrWifiSmeRoamingConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].rssiHighThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].rssiLowThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].snrHighThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamingBands[i2].snrLowThreshold); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamingConfig.disableSmoothRoaming); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamingConfig.disableRoamScans); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->roamingConfig.reconnectLimit); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.reconnectLimitIntervalMs); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].intervalSeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].validitySeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu); + } + } + return(ptr); +} + + +void* CsrWifiSmeRoamingConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeRoamingConfigGetCfm *primitive = (CsrWifiSmeRoamingConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].rssiHighThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].rssiLowThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].snrHighThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamingBands[i2].snrLowThreshold, buffer, &offset); + } + } + CsrUint8Des((CsrUint8 *) &primitive->roamingConfig.disableSmoothRoaming, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->roamingConfig.disableRoamScans, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->roamingConfig.reconnectLimit, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.reconnectLimitIntervalMs, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 3; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].intervalSeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].validitySeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset); + } + } + + return primitive; +} + + +CsrSize CsrWifiSmeRoamingConfigSetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeRoamingConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeRoamingConfigSetCfm *primitive = (CsrWifiSmeRoamingConfigSetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeRoamingConfigSetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeRoamingConfigSetCfm *primitive = (CsrWifiSmeRoamingConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeRoamingConfigSetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeScanConfigGetCfmSizeof(void *msg) +{ + CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 65) */ + bufferSize += 2; /* CsrResult primitive->status */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].intervalSeconds */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].validitySeconds */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu */ + } + } + bufferSize += 1; /* CsrBool primitive->scanConfig.disableAutonomousScans */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.maxResults */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.highRssiThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.lowRssiThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.deltaRssiThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.highSnrThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.lowSnrThreshold */ + bufferSize += 1; /* CsrInt8 primitive->scanConfig.deltaSnrThreshold */ + bufferSize += 2; /* CsrUint16 primitive->scanConfig.passiveChannelListCount */ + bufferSize += primitive->scanConfig.passiveChannelListCount; /* CsrUint8 primitive->scanConfig.passiveChannelList */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeScanConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].intervalSeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].validitySeconds); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.disableAutonomousScans); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.maxResults); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.highRssiThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.lowRssiThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.deltaRssiThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.highSnrThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.lowSnrThreshold); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanConfig.deltaSnrThreshold); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanConfig.passiveChannelListCount); + if (primitive->scanConfig.passiveChannelListCount) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanConfig.passiveChannelList, ((CsrUint16) (primitive->scanConfig.passiveChannelListCount))); + } + return(ptr); +} + + +void* CsrWifiSmeScanConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].intervalSeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].validitySeconds, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset); + } + } + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.disableAutonomousScans, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.maxResults, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.highRssiThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.lowRssiThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.deltaRssiThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.highSnrThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.lowSnrThreshold, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanConfig.deltaSnrThreshold, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanConfig.passiveChannelListCount, buffer, &offset); + if (primitive->scanConfig.passiveChannelListCount) + { + primitive->scanConfig.passiveChannelList = (CsrUint8 *)CsrPmemAlloc(primitive->scanConfig.passiveChannelListCount); + CsrMemCpyDes(primitive->scanConfig.passiveChannelList, buffer, &offset, ((CsrUint16) (primitive->scanConfig.passiveChannelListCount))); + } + else + { + primitive->scanConfig.passiveChannelList = NULL; + } + + return primitive; +} + + +void CsrWifiSmeScanConfigGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->scanConfig.passiveChannelList); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeScanResultIndSizeof(void *msg) +{ + CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 149) */ + bufferSize += 32; /* CsrUint8 primitive->result.ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->result.ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->result.bssid.a[6] */ + bufferSize += 2; /* CsrInt16 primitive->result.rssi */ + bufferSize += 2; /* CsrInt16 primitive->result.snr */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->result.ifIndex */ + bufferSize += 2; /* CsrUint16 primitive->result.beaconPeriodTu */ + bufferSize += 8; /* CsrUint8 primitive->result.timeStamp.data[8] */ + bufferSize += 8; /* CsrUint8 primitive->result.localTime.data[8] */ + bufferSize += 2; /* CsrUint16 primitive->result.channelFrequency */ + bufferSize += 2; /* CsrUint16 primitive->result.capabilityInformation */ + bufferSize += 1; /* CsrUint8 primitive->result.channelNumber */ + bufferSize += 1; /* CsrWifiSmeBasicUsability primitive->result.usability */ + bufferSize += 1; /* CsrWifiSmeBssType primitive->result.bssType */ + bufferSize += 2; /* CsrUint16 primitive->result.informationElementsLength */ + bufferSize += primitive->result.informationElementsLength; /* CsrUint8 primitive->result.informationElements */ + bufferSize += 1; /* CsrWifiSmeP2pRole primitive->result.p2pDeviceRole */ + switch (primitive->result.p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_CLI: + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.reservedCli.empty */ + break; + case CSR_WIFI_SME_P2P_ROLE_GO: + bufferSize += 1; /* CsrWifiSmeP2pGroupCapabilityMask primitive->result.deviceInfo.groupInfo.groupCapability */ + bufferSize += 6; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2pDeviceAddress.a[6] */ + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2pClientInfoCount */ + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + bufferSize += 6; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a[6] */ + bufferSize += 6; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a[6] */ + bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods */ + bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap */ + bufferSize += 8; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails[8] */ + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount */ + { + CsrUint16 i6; + for (i6 = 0; i6 < primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++) + { + bufferSize += 8; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails[8] */ + } + } + bufferSize += 32; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName[32] */ + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength */ + } + } + break; + case CSR_WIFI_SME_P2P_ROLE_NONE: + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.reservedNone.empty */ + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + bufferSize += 6; /* CsrUint8 primitive->result.deviceInfo.standalonedevInfo.deviceAddress.a[6] */ + bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->result.deviceInfo.standalonedevInfo.configMethods */ + bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->result.deviceInfo.standalonedevInfo.p2PDeviceCap */ + bufferSize += 8; /* CsrUint8 primitive->result.deviceInfo.standalonedevInfo.primDeviceType.deviceDetails[8] */ + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount */ + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++) + { + bufferSize += 8; /* CsrUint8 primitive->result.deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails[8] */ + } + } + bufferSize += 32; /* CsrUint8 primitive->result.deviceInfo.standalonedevInfo.deviceName[32] */ + bufferSize += 1; /* CsrUint8 primitive->result.deviceInfo.standalonedevInfo.deviceNameLength */ + break; + default: + break; + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeScanResultIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrMemCpySer(ptr, len, (const void *) primitive->result.ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->result.bssid.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.rssi); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.snr); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.ifIndex); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.beaconPeriodTu); + CsrMemCpySer(ptr, len, (const void *) primitive->result.timeStamp.data, ((CsrUint16) (8))); + CsrMemCpySer(ptr, len, (const void *) primitive->result.localTime.data, ((CsrUint16) (8))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.channelFrequency); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.capabilityInformation); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.channelNumber); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.usability); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.bssType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.informationElementsLength); + if (primitive->result.informationElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->result.informationElements, ((CsrUint16) (primitive->result.informationElementsLength))); + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.p2pDeviceRole); + switch (primitive->result.p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_CLI: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.reservedCli.empty); + break; + case CSR_WIFI_SME_P2P_ROLE_GO: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.groupInfo.groupCapability); + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2pDeviceAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.groupInfo.p2pClientInfoCount); + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, ((CsrUint16) (6))); + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap); + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, ((CsrUint16) (8))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount); + { + CsrUint16 i6; + for (i6 = 0; i6 < primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, ((CsrUint16) (8))); + } + } + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength); + } + } + break; + case CSR_WIFI_SME_P2P_ROLE_NONE: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.reservedNone.empty); + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.deviceAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->result.deviceInfo.standalonedevInfo.configMethods); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.standalonedevInfo.p2PDeviceCap); + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, ((CsrUint16) (8))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount); + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, ((CsrUint16) (8))); + } + } + CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.deviceName, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->result.deviceInfo.standalonedevInfo.deviceNameLength); + break; + default: + break; + } + return(ptr); +} + + +void* CsrWifiSmeScanResultIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrMemCpyDes(primitive->result.ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->result.ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->result.bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->result.rssi, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result.snr, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->result.ifIndex, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result.beaconPeriodTu, buffer, &offset); + CsrMemCpyDes(primitive->result.timeStamp.data, buffer, &offset, ((CsrUint16) (8))); + CsrMemCpyDes(primitive->result.localTime.data, buffer, &offset, ((CsrUint16) (8))); + CsrUint16Des((CsrUint16 *) &primitive->result.channelFrequency, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result.capabilityInformation, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->result.channelNumber, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->result.usability, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->result.bssType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->result.informationElementsLength, buffer, &offset); + if (primitive->result.informationElementsLength) + { + primitive->result.informationElements = (CsrUint8 *)CsrPmemAlloc(primitive->result.informationElementsLength); + CsrMemCpyDes(primitive->result.informationElements, buffer, &offset, ((CsrUint16) (primitive->result.informationElementsLength))); + } + else + { + primitive->result.informationElements = NULL; + } + CsrUint8Des((CsrUint8 *) &primitive->result.p2pDeviceRole, buffer, &offset); + switch (primitive->result.p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_CLI: + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.reservedCli.empty, buffer, &offset); + break; + case CSR_WIFI_SME_P2P_ROLE_GO: + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.groupInfo.groupCapability, buffer, &offset); + CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2pDeviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.groupInfo.p2pClientInfoCount, buffer, &offset); + primitive->result.deviceInfo.groupInfo.p2PClientInfo = NULL; + if (primitive->result.deviceInfo.groupInfo.p2pClientInfoCount) + { + primitive->result.deviceInfo.groupInfo.p2PClientInfo = (CsrWifiSmeP2pClientInfoType *)CsrPmemAlloc(sizeof(CsrWifiSmeP2pClientInfoType) * primitive->result.deviceInfo.groupInfo.p2pClientInfoCount); + } + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap, buffer, &offset); + CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, buffer, &offset, ((CsrUint16) (8))); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount, buffer, &offset); + primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL; + if (primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount) + { + primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = (CsrWifiSmeWpsDeviceType *)CsrPmemAlloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount); + } + { + CsrUint16 i6; + for (i6 = 0; i6 < primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++) + { + CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, buffer, &offset, ((CsrUint16) (8))); + } + } + CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength, buffer, &offset); + } + } + break; + case CSR_WIFI_SME_P2P_ROLE_NONE: + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.reservedNone.empty, buffer, &offset); + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.deviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->result.deviceInfo.standalonedevInfo.configMethods, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.standalonedevInfo.p2PDeviceCap, buffer, &offset); + CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, buffer, &offset, ((CsrUint16) (8))); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount, buffer, &offset); + primitive->result.deviceInfo.standalonedevInfo.secDeviceType = NULL; + if (primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount) + { + primitive->result.deviceInfo.standalonedevInfo.secDeviceType = (CsrWifiSmeWpsDeviceType *)CsrPmemAlloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount); + } + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++) + { + CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, buffer, &offset, ((CsrUint16) (8))); + } + } + CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.deviceName, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->result.deviceInfo.standalonedevInfo.deviceNameLength, buffer, &offset); + break; + default: + break; + } + + return primitive; +} + + +void CsrWifiSmeScanResultIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *) voidPrimitivePointer; + CsrPmemFree(primitive->result.informationElements); + switch (primitive->result.p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_GO: + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrPmemFree(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType); + } + } + CsrPmemFree(primitive->result.deviceInfo.groupInfo.p2PClientInfo); + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrPmemFree(primitive->result.deviceInfo.standalonedevInfo.secDeviceType); + break; + default: + break; + } + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeScanResultsGetCfmSizeof(void *msg) +{ + CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 153) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->scanResultsCount */ + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->scanResultsCount; i1++) + { + bufferSize += 32; /* CsrUint8 primitive->scanResults[i1].ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].ssid.length */ + bufferSize += 6; /* CsrUint8 primitive->scanResults[i1].bssid.a[6] */ + bufferSize += 2; /* CsrInt16 primitive->scanResults[i1].rssi */ + bufferSize += 2; /* CsrInt16 primitive->scanResults[i1].snr */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->scanResults[i1].ifIndex */ + bufferSize += 2; /* CsrUint16 primitive->scanResults[i1].beaconPeriodTu */ + bufferSize += 8; /* CsrUint8 primitive->scanResults[i1].timeStamp.data[8] */ + bufferSize += 8; /* CsrUint8 primitive->scanResults[i1].localTime.data[8] */ + bufferSize += 2; /* CsrUint16 primitive->scanResults[i1].channelFrequency */ + bufferSize += 2; /* CsrUint16 primitive->scanResults[i1].capabilityInformation */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].channelNumber */ + bufferSize += 1; /* CsrWifiSmeBasicUsability primitive->scanResults[i1].usability */ + bufferSize += 1; /* CsrWifiSmeBssType primitive->scanResults[i1].bssType */ + bufferSize += 2; /* CsrUint16 primitive->scanResults[i1].informationElementsLength */ + bufferSize += primitive->scanResults[i1].informationElementsLength; /* CsrUint8 primitive->scanResults[i1].informationElements */ + bufferSize += 1; /* CsrWifiSmeP2pRole primitive->scanResults[i1].p2pDeviceRole */ + switch (primitive->scanResults[i1].p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_CLI: + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.reservedCli.empty */ + break; + case CSR_WIFI_SME_P2P_ROLE_GO: + bufferSize += 1; /* CsrWifiSmeP2pGroupCapabilityMask primitive->scanResults[i1].deviceInfo.groupInfo.groupCapability */ + bufferSize += 6; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2pDeviceAddress.a[6] */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount */ + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + bufferSize += 6; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a[6] */ + bufferSize += 6; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a[6] */ + bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods */ + bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap */ + bufferSize += 8; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails[8] */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount */ + { + CsrUint16 i6; + for (i6 = 0; i6 < primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++) + { + bufferSize += 8; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails[8] */ + } + } + bufferSize += 32; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName[32] */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength */ + } + } + break; + case CSR_WIFI_SME_P2P_ROLE_NONE: + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.reservedNone.empty */ + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + bufferSize += 6; /* CsrUint8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceAddress.a[6] */ + bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->scanResults[i1].deviceInfo.standalonedevInfo.configMethods */ + bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->scanResults[i1].deviceInfo.standalonedevInfo.p2PDeviceCap */ + bufferSize += 8; /* CsrUint8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.primDeviceType.deviceDetails[8] */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount */ + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++) + { + bufferSize += 8; /* CsrUint8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails[8] */ + } + } + bufferSize += 32; /* CsrUint8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceName[32] */ + bufferSize += 1; /* CsrUint8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceNameLength */ + break; + default: + break; + } + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeScanResultsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResultsCount); + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->scanResultsCount; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].ssid.length); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].bssid.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].rssi); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].snr); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].ifIndex); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].beaconPeriodTu); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].timeStamp.data, ((CsrUint16) (8))); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].localTime.data, ((CsrUint16) (8))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].channelFrequency); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].capabilityInformation); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].channelNumber); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].usability); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].bssType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].informationElementsLength); + if (primitive->scanResults[i1].informationElementsLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].informationElements, ((CsrUint16) (primitive->scanResults[i1].informationElementsLength))); + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].p2pDeviceRole); + switch (primitive->scanResults[i1].p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_CLI: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.reservedCli.empty); + break; + case CSR_WIFI_SME_P2P_ROLE_GO: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.groupInfo.groupCapability); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2pDeviceAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount); + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, ((CsrUint16) (6))); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, ((CsrUint16) (8))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount); + { + CsrUint16 i6; + for (i6 = 0; i6 < primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, ((CsrUint16) (8))); + } + } + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength); + } + } + break; + case CSR_WIFI_SME_P2P_ROLE_NONE: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.reservedNone.empty); + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceAddress.a, ((CsrUint16) (6))); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->scanResults[i1].deviceInfo.standalonedevInfo.configMethods); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.standalonedevInfo.p2PDeviceCap); + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, ((CsrUint16) (8))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount); + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, ((CsrUint16) (8))); + } + } + CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceName, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceNameLength); + break; + default: + break; + } + } + } + return(ptr); +} + + +void* CsrWifiSmeScanResultsGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeScanResultsGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanResultsCount, buffer, &offset); + primitive->scanResults = NULL; + if (primitive->scanResultsCount) + { + primitive->scanResults = (CsrWifiSmeScanResult *)CsrPmemAlloc(sizeof(CsrWifiSmeScanResult) * primitive->scanResultsCount); + } + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->scanResultsCount; i1++) + { + CsrMemCpyDes(primitive->scanResults[i1].ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].ssid.length, buffer, &offset); + CsrMemCpyDes(primitive->scanResults[i1].bssid.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].rssi, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].snr, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].ifIndex, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].beaconPeriodTu, buffer, &offset); + CsrMemCpyDes(primitive->scanResults[i1].timeStamp.data, buffer, &offset, ((CsrUint16) (8))); + CsrMemCpyDes(primitive->scanResults[i1].localTime.data, buffer, &offset, ((CsrUint16) (8))); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].channelFrequency, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].capabilityInformation, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].channelNumber, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].usability, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].bssType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].informationElementsLength, buffer, &offset); + if (primitive->scanResults[i1].informationElementsLength) + { + primitive->scanResults[i1].informationElements = (CsrUint8 *)CsrPmemAlloc(primitive->scanResults[i1].informationElementsLength); + CsrMemCpyDes(primitive->scanResults[i1].informationElements, buffer, &offset, ((CsrUint16) (primitive->scanResults[i1].informationElementsLength))); + } + else + { + primitive->scanResults[i1].informationElements = NULL; + } + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].p2pDeviceRole, buffer, &offset); + switch (primitive->scanResults[i1].p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_CLI: + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.reservedCli.empty, buffer, &offset); + break; + case CSR_WIFI_SME_P2P_ROLE_GO: + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.groupCapability, buffer, &offset); + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2pDeviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount, buffer, &offset); + primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo = NULL; + if (primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount) + { + primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo = (CsrWifiSmeP2pClientInfoType *)CsrPmemAlloc(sizeof(CsrWifiSmeP2pClientInfoType) * primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount); + } + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap, buffer, &offset); + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, buffer, &offset, ((CsrUint16) (8))); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount, buffer, &offset); + primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL; + if (primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount) + { + primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = (CsrWifiSmeWpsDeviceType *)CsrPmemAlloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount); + } + { + CsrUint16 i6; + for (i6 = 0; i6 < primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++) + { + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, buffer, &offset, ((CsrUint16) (8))); + } + } + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength, buffer, &offset); + } + } + break; + case CSR_WIFI_SME_P2P_ROLE_NONE: + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.reservedNone.empty, buffer, &offset); + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint16Des((CsrUint16 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.configMethods, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.p2PDeviceCap, buffer, &offset); + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, buffer, &offset, ((CsrUint16) (8))); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount, buffer, &offset); + primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType = NULL; + if (primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount) + { + primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType = (CsrWifiSmeWpsDeviceType *)CsrPmemAlloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount); + } + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++) + { + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, buffer, &offset, ((CsrUint16) (8))); + } + } + CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceName, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceNameLength, buffer, &offset); + break; + default: + break; + } + } + } + + return primitive; +} + + +void CsrWifiSmeScanResultsGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *) voidPrimitivePointer; + { + CsrUint16 i1; + for (i1 = 0; i1 < primitive->scanResultsCount; i1++) + { + CsrPmemFree(primitive->scanResults[i1].informationElements); + switch (primitive->scanResults[i1].p2pDeviceRole) + { + case CSR_WIFI_SME_P2P_ROLE_GO: + { + CsrUint16 i4; + for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++) + { + CsrPmemFree(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType); + } + } + CsrPmemFree(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo); + break; + case CSR_WIFI_SME_P2P_ROLE_STANDALONE: + CsrPmemFree(primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType); + break; + default: + break; + } + } + } + CsrPmemFree(primitive->scanResults); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */ + bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */ + bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */ + bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */ + bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeSmeStaConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeSmeStaConfigGetCfm *primitive = (CsrWifiSmeSmeStaConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.connectionQualityRssiChangeTrigger); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.connectionQualitySnrChangeTrigger); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.wmmModeMask); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.ifIndex); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.allowUnicastUseGroupCipher); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->smeConfig.enableOpportunisticKeyCaching); + return(ptr); +} + + +void* CsrWifiSmeSmeStaConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeSmeStaConfigGetCfm *primitive = (CsrWifiSmeSmeStaConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.connectionQualityRssiChangeTrigger, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.connectionQualitySnrChangeTrigger, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.wmmModeMask, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.ifIndex, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.allowUnicastUseGroupCipher, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->smeConfig.enableOpportunisticKeyCaching, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeSmeStaConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeSmeStaConfigSetCfm *primitive = (CsrWifiSmeSmeStaConfigSetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiSmeSmeStaConfigSetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeSmeStaConfigSetCfm *primitive = (CsrWifiSmeSmeStaConfigSetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeStaConfigSetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */ + bufferSize += 2; /* CsrResult primitive->status */ + { + CsrUint16 i1; + for (i1 = 0; i1 < 2; i1++) + { + bufferSize += 6; /* CsrUint8 primitive->stationMacAddress[i1].a[6] */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeStationMacAddressGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeStationMacAddressGetCfm *primitive = (CsrWifiSmeStationMacAddressGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + { + CsrUint16 i1; + for (i1 = 0; i1 < 2; i1++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->stationMacAddress[i1].a, ((CsrUint16) (6))); + } + } + return(ptr); +} + + +void* CsrWifiSmeStationMacAddressGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeStationMacAddressGetCfm *primitive = (CsrWifiSmeStationMacAddressGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeStationMacAddressGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + { + CsrUint16 i1; + for (i1 = 0; i1 < 2; i1++) + { + CsrMemCpyDes(primitive->stationMacAddress[i1].a, buffer, &offset, ((CsrUint16) (6))); + } + } + + return primitive; +} + + +CsrSize CsrWifiSmeTspecIndSizeof(void *msg) +{ + CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 4; /* CsrUint32 primitive->transactionId */ + bufferSize += 1; /* CsrWifiSmeTspecResultCode primitive->tspecResultCode */ + bufferSize += 2; /* CsrUint16 primitive->tspecLength */ + bufferSize += primitive->tspecLength; /* CsrUint8 primitive->tspec */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeTspecIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->transactionId); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->tspecResultCode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->tspecLength); + if (primitive->tspecLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->tspec, ((CsrUint16) (primitive->tspecLength))); + } + return(ptr); +} + + +void* CsrWifiSmeTspecIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *) CsrPmemAlloc(sizeof(CsrWifiSmeTspecInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->transactionId, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->tspecResultCode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->tspecLength, buffer, &offset); + if (primitive->tspecLength) + { + primitive->tspec = (CsrUint8 *)CsrPmemAlloc(primitive->tspecLength); + CsrMemCpyDes(primitive->tspec, buffer, &offset, ((CsrUint16) (primitive->tspecLength))); + } + else + { + primitive->tspec = NULL; + } + + return primitive; +} + + +void CsrWifiSmeTspecIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *) voidPrimitivePointer; + CsrPmemFree(primitive->tspec); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeTspecCfmSizeof(void *msg) +{ + CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 4; /* CsrUint32 primitive->transactionId */ + bufferSize += 1; /* CsrWifiSmeTspecResultCode primitive->tspecResultCode */ + bufferSize += 2; /* CsrUint16 primitive->tspecLength */ + bufferSize += primitive->tspecLength; /* CsrUint8 primitive->tspec */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeTspecCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->transactionId); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->tspecResultCode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->tspecLength); + if (primitive->tspecLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->tspec, ((CsrUint16) (primitive->tspecLength))); + } + return(ptr); +} + + +void* CsrWifiSmeTspecCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeTspecCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->transactionId, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->tspecResultCode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->tspecLength, buffer, &offset); + if (primitive->tspecLength) + { + primitive->tspec = (CsrUint8 *)CsrPmemAlloc(primitive->tspecLength); + CsrMemCpyDes(primitive->tspec, buffer, &offset, ((CsrUint16) (primitive->tspecLength))); + } + else + { + primitive->tspec = NULL; + } + + return primitive; +} + + +void CsrWifiSmeTspecCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->tspec); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeVersionsGetCfmSizeof(void *msg) +{ + CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 33) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 4; /* CsrUint32 primitive->versions.chipId */ + bufferSize += 4; /* CsrUint32 primitive->versions.chipVersion */ + bufferSize += 4; /* CsrUint32 primitive->versions.firmwareBuild */ + bufferSize += 4; /* CsrUint32 primitive->versions.firmwarePatch */ + bufferSize += 4; /* CsrUint32 primitive->versions.firmwareHip */ + bufferSize += (primitive->versions.routerBuild?CsrStrLen(primitive->versions.routerBuild) : 0) + 1; /* CsrCharString* primitive->versions.routerBuild (0 byte len + 1 for NULL Term) */ + bufferSize += 4; /* CsrUint32 primitive->versions.routerHip */ + bufferSize += (primitive->versions.smeBuild?CsrStrLen(primitive->versions.smeBuild) : 0) + 1; /* CsrCharString* primitive->versions.smeBuild (0 byte len + 1 for NULL Term) */ + bufferSize += 4; /* CsrUint32 primitive->versions.smeHip */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeVersionsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.chipId); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.chipVersion); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.firmwareBuild); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.firmwarePatch); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.firmwareHip); + CsrCharStringSer(ptr, len, primitive->versions.routerBuild); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.routerHip); + CsrCharStringSer(ptr, len, primitive->versions.smeBuild); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->versions.smeHip); + return(ptr); +} + + +void* CsrWifiSmeVersionsGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeVersionsGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.chipId, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.chipVersion, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.firmwareBuild, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.firmwarePatch, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.firmwareHip, buffer, &offset); + CsrCharStringDes(&primitive->versions.routerBuild, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.routerHip, buffer, &offset); + CsrCharStringDes(&primitive->versions.smeBuild, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->versions.smeHip, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeVersionsGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->versions.routerBuild); + CsrPmemFree(primitive->versions.smeBuild); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCloakedSsidsGetCfmSizeof(void *msg) +{ + CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 39) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrUint8 primitive->cloakedSsids.cloakedSsidsCount */ + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++) + { + bufferSize += 32; /* CsrUint8 primitive->cloakedSsids.cloakedSsids[i2].ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->cloakedSsids.cloakedSsids[i2].length */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCloakedSsidsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->cloakedSsids.cloakedSsidsCount); + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->cloakedSsids.cloakedSsids[i2].ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->cloakedSsids.cloakedSsids[i2].length); + } + } + return(ptr); +} + + +void* CsrWifiSmeCloakedSsidsGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeCloakedSsidsGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->cloakedSsids.cloakedSsidsCount, buffer, &offset); + primitive->cloakedSsids.cloakedSsids = NULL; + if (primitive->cloakedSsids.cloakedSsidsCount) + { + primitive->cloakedSsids.cloakedSsids = (CsrWifiSsid *)CsrPmemAlloc(sizeof(CsrWifiSsid) * primitive->cloakedSsids.cloakedSsidsCount); + } + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++) + { + CsrMemCpyDes(primitive->cloakedSsids.cloakedSsids[i2].ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->cloakedSsids.cloakedSsids[i2].length, buffer, &offset); + } + } + + return primitive; +} + + +void CsrWifiSmeCloakedSsidsGetCfmSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *) voidPrimitivePointer; + CsrPmemFree(primitive->cloakedSsids.cloakedSsids); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeWifiOnIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 6; /* CsrUint8 primitive->address.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeWifiOnIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeWifiOnInd *primitive = (CsrWifiSmeWifiOnInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiSmeWifiOnIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeWifiOnInd *primitive = (CsrWifiSmeWifiOnInd *) CsrPmemAlloc(sizeof(CsrWifiSmeWifiOnInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrMemCpyDes(primitive->address.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +CsrSize CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 1; /* CsrWifiSme80211dTrustLevel primitive->deviceConfig.trustLevel */ + bufferSize += 2; /* CsrUint8 primitive->deviceConfig.countryCode[2] */ + bufferSize += 1; /* CsrWifiSmeFirmwareDriverInterface primitive->deviceConfig.firmwareDriverInterface */ + bufferSize += 1; /* CsrBool primitive->deviceConfig.enableStrictDraftN */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeSmeCommonConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeSmeCommonConfigGetCfm *primitive = (CsrWifiSmeSmeCommonConfigGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->deviceConfig.trustLevel); + CsrMemCpySer(ptr, len, (const void *) primitive->deviceConfig.countryCode, ((CsrUint16) (2))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->deviceConfig.firmwareDriverInterface); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->deviceConfig.enableStrictDraftN); + return(ptr); +} + + +void* CsrWifiSmeSmeCommonConfigGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeSmeCommonConfigGetCfm *primitive = (CsrWifiSmeSmeCommonConfigGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeSmeCommonConfigGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->deviceConfig.trustLevel, buffer, &offset); + CsrMemCpyDes(primitive->deviceConfig.countryCode, buffer, &offset, ((CsrUint16) (2))); + CsrUint8Des((CsrUint8 *) &primitive->deviceConfig.firmwareDriverInterface, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->deviceConfig.enableStrictDraftN, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 2; /* CsrUint16 primitive->numInterfaces */ + bufferSize += 2; /* CsrUint8 primitive->capBitmap[2] */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeInterfaceCapabilityGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeInterfaceCapabilityGetCfm *primitive = (CsrWifiSmeInterfaceCapabilityGetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->numInterfaces); + CsrMemCpySer(ptr, len, (const void *) primitive->capBitmap, ((CsrUint16) (2))); + return(ptr); +} + + +void* CsrWifiSmeInterfaceCapabilityGetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeInterfaceCapabilityGetCfm *primitive = (CsrWifiSmeInterfaceCapabilityGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeInterfaceCapabilityGetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->numInterfaces, buffer, &offset); + CsrMemCpyDes(primitive->capBitmap, buffer, &offset, ((CsrUint16) (2))); + + return primitive; +} + + +CsrSize CsrWifiSmeErrorIndSizeof(void *msg) +{ + CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 3) */ + bufferSize += (primitive->errorMessage?CsrStrLen(primitive->errorMessage) : 0) + 1; /* CsrCharString* primitive->errorMessage (0 byte len + 1 for NULL Term) */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeErrorIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrCharStringSer(ptr, len, primitive->errorMessage); + return(ptr); +} + + +void* CsrWifiSmeErrorIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *) CsrPmemAlloc(sizeof(CsrWifiSmeErrorInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrCharStringDes(&primitive->errorMessage, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeErrorIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *) voidPrimitivePointer; + CsrPmemFree(primitive->errorMessage); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeInfoIndSizeof(void *msg) +{ + CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 3) */ + bufferSize += (primitive->infoMessage?CsrStrLen(primitive->infoMessage) : 0) + 1; /* CsrCharString* primitive->infoMessage (0 byte len + 1 for NULL Term) */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeInfoIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrCharStringSer(ptr, len, primitive->infoMessage); + return(ptr); +} + + +void* CsrWifiSmeInfoIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *) CsrPmemAlloc(sizeof(CsrWifiSmeInfoInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrCharStringDes(&primitive->infoMessage, buffer, &offset); + + return primitive; +} + + +void CsrWifiSmeInfoIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *) voidPrimitivePointer; + CsrPmemFree(primitive->infoMessage); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiSmeCoreDumpIndSizeof(void *msg) +{ + CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 4; /* CsrUint32 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeCoreDumpIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiSmeCoreDumpIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *) CsrPmemAlloc(sizeof(CsrWifiSmeCoreDumpInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiSmeCoreDumpIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *) voidPrimitivePointer; + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h new file mode 100644 index 000000000000..c2d7fd68c4ae --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_serialize.h @@ -0,0 +1,668 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_SERIALIZE_H__ +#define CSR_WIFI_SME_SERIALIZE_H__ + +#include "csr_types.h" +#include "csr_pmem.h" +#include "csr_wifi_msgconv.h" + +#include "csr_wifi_sme_prim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void CsrWifiSmePfree(void *ptr); + +#define CsrWifiSmeActivateReqSer CsrWifiEventSer +#define CsrWifiSmeActivateReqDes CsrWifiEventDes +#define CsrWifiSmeActivateReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeActivateReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeAdhocConfigGetReqSer CsrWifiEventSer +#define CsrWifiSmeAdhocConfigGetReqDes CsrWifiEventDes +#define CsrWifiSmeAdhocConfigGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeAdhocConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeAdhocConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeAdhocConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeAdhocConfigSetReqSizeof(void *msg); +#define CsrWifiSmeAdhocConfigSetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeBlacklistReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeBlacklistReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeBlacklistReqSizeof(void *msg); +extern void CsrWifiSmeBlacklistReqSerFree(void *msg); + +#define CsrWifiSmeCalibrationDataGetReqSer CsrWifiEventSer +#define CsrWifiSmeCalibrationDataGetReqDes CsrWifiEventDes +#define CsrWifiSmeCalibrationDataGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeCalibrationDataGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCalibrationDataSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCalibrationDataSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCalibrationDataSetReqSizeof(void *msg); +extern void CsrWifiSmeCalibrationDataSetReqSerFree(void *msg); + +#define CsrWifiSmeCcxConfigGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeCcxConfigGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeCcxConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeCcxConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCcxConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCcxConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCcxConfigSetReqSizeof(void *msg); +#define CsrWifiSmeCcxConfigSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeCoexConfigGetReqSer CsrWifiEventSer +#define CsrWifiSmeCoexConfigGetReqDes CsrWifiEventDes +#define CsrWifiSmeCoexConfigGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeCoexConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCoexConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCoexConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCoexConfigSetReqSizeof(void *msg); +#define CsrWifiSmeCoexConfigSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeCoexInfoGetReqSer CsrWifiEventSer +#define CsrWifiSmeCoexInfoGetReqDes CsrWifiEventDes +#define CsrWifiSmeCoexInfoGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeCoexInfoGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeConnectReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeConnectReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeConnectReqSizeof(void *msg); +extern void CsrWifiSmeConnectReqSerFree(void *msg); + +#define CsrWifiSmeConnectionConfigGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeConnectionConfigGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeConnectionConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeConnectionConfigGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeConnectionInfoGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeConnectionInfoGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeConnectionInfoGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeConnectionInfoGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeConnectionStatsGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeConnectionStatsGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeConnectionStatsGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeConnectionStatsGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeDeactivateReqSer CsrWifiEventSer +#define CsrWifiSmeDeactivateReqDes CsrWifiEventDes +#define CsrWifiSmeDeactivateReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeDeactivateReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeDisconnectReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeDisconnectReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeDisconnectReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeDisconnectReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeEventMaskSetReqSer CsrWifiEventCsrUint32Ser +#define CsrWifiSmeEventMaskSetReqDes CsrWifiEventCsrUint32Des +#define CsrWifiSmeEventMaskSetReqSizeof CsrWifiEventCsrUint32Sizeof +#define CsrWifiSmeEventMaskSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeHostConfigGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeHostConfigGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeHostConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeHostConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeHostConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeHostConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeHostConfigSetReqSizeof(void *msg); +#define CsrWifiSmeHostConfigSetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeKeyReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeKeyReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeKeyReqSizeof(void *msg); +#define CsrWifiSmeKeyReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeLinkQualityGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeLinkQualityGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeLinkQualityGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeLinkQualityGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeMibConfigGetReqSer CsrWifiEventSer +#define CsrWifiSmeMibConfigGetReqDes CsrWifiEventDes +#define CsrWifiSmeMibConfigGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeMibConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeMibConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibConfigSetReqSizeof(void *msg); +#define CsrWifiSmeMibConfigSetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeMibGetNextReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibGetNextReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibGetNextReqSizeof(void *msg); +extern void CsrWifiSmeMibGetNextReqSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeMibGetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibGetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibGetReqSizeof(void *msg); +extern void CsrWifiSmeMibGetReqSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeMibSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibSetReqSizeof(void *msg); +extern void CsrWifiSmeMibSetReqSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeMulticastAddressReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMulticastAddressReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMulticastAddressReqSizeof(void *msg); +extern void CsrWifiSmeMulticastAddressReqSerFree(void *msg); + +extern CsrUint8* CsrWifiSmePacketFilterSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePacketFilterSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePacketFilterSetReqSizeof(void *msg); +extern void CsrWifiSmePacketFilterSetReqSerFree(void *msg); + +#define CsrWifiSmePermanentMacAddressGetReqSer CsrWifiEventSer +#define CsrWifiSmePermanentMacAddressGetReqDes CsrWifiEventDes +#define CsrWifiSmePermanentMacAddressGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmePermanentMacAddressGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmePmkidReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePmkidReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePmkidReqSizeof(void *msg); +extern void CsrWifiSmePmkidReqSerFree(void *msg); + +#define CsrWifiSmePowerConfigGetReqSer CsrWifiEventSer +#define CsrWifiSmePowerConfigGetReqDes CsrWifiEventDes +#define CsrWifiSmePowerConfigGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmePowerConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmePowerConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePowerConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePowerConfigSetReqSizeof(void *msg); +#define CsrWifiSmePowerConfigSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeRegulatoryDomainInfoGetReqSer CsrWifiEventSer +#define CsrWifiSmeRegulatoryDomainInfoGetReqDes CsrWifiEventDes +#define CsrWifiSmeRegulatoryDomainInfoGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeRegulatoryDomainInfoGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeRoamingConfigGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeRoamingConfigGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeRoamingConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeRoamingConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeRoamingConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeRoamingConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeRoamingConfigSetReqSizeof(void *msg); +#define CsrWifiSmeRoamingConfigSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeScanConfigGetReqSer CsrWifiEventSer +#define CsrWifiSmeScanConfigGetReqDes CsrWifiEventDes +#define CsrWifiSmeScanConfigGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeScanConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeScanConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeScanConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeScanConfigSetReqSizeof(void *msg); +extern void CsrWifiSmeScanConfigSetReqSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeScanFullReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeScanFullReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeScanFullReqSizeof(void *msg); +extern void CsrWifiSmeScanFullReqSerFree(void *msg); + +#define CsrWifiSmeScanResultsFlushReqSer CsrWifiEventSer +#define CsrWifiSmeScanResultsFlushReqDes CsrWifiEventDes +#define CsrWifiSmeScanResultsFlushReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeScanResultsFlushReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeScanResultsGetReqSer CsrWifiEventSer +#define CsrWifiSmeScanResultsGetReqDes CsrWifiEventDes +#define CsrWifiSmeScanResultsGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeScanResultsGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeSmeStaConfigGetReqSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeSmeStaConfigGetReqDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeSmeStaConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeSmeStaConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeSmeStaConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeSmeStaConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg); +#define CsrWifiSmeSmeStaConfigSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeStationMacAddressGetReqSer CsrWifiEventSer +#define CsrWifiSmeStationMacAddressGetReqDes CsrWifiEventDes +#define CsrWifiSmeStationMacAddressGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeStationMacAddressGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeTspecReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeTspecReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeTspecReqSizeof(void *msg); +extern void CsrWifiSmeTspecReqSerFree(void *msg); + +#define CsrWifiSmeVersionsGetReqSer CsrWifiEventSer +#define CsrWifiSmeVersionsGetReqDes CsrWifiEventDes +#define CsrWifiSmeVersionsGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeVersionsGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeWifiFlightmodeReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeWifiFlightmodeReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeWifiFlightmodeReqSizeof(void *msg); +extern void CsrWifiSmeWifiFlightmodeReqSerFree(void *msg); + +#define CsrWifiSmeWifiOffReqSer CsrWifiEventSer +#define CsrWifiSmeWifiOffReqDes CsrWifiEventDes +#define CsrWifiSmeWifiOffReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeWifiOffReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeWifiOnReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeWifiOnReqSizeof(void *msg); +extern void CsrWifiSmeWifiOnReqSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeCloakedSsidsSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCloakedSsidsSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCloakedSsidsSetReqSizeof(void *msg); +extern void CsrWifiSmeCloakedSsidsSetReqSerFree(void *msg); + +#define CsrWifiSmeCloakedSsidsGetReqSer CsrWifiEventSer +#define CsrWifiSmeCloakedSsidsGetReqDes CsrWifiEventDes +#define CsrWifiSmeCloakedSsidsGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeCloakedSsidsGetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeSmeCommonConfigGetReqSer CsrWifiEventSer +#define CsrWifiSmeSmeCommonConfigGetReqDes CsrWifiEventDes +#define CsrWifiSmeSmeCommonConfigGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeSmeCommonConfigGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeSmeCommonConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeSmeCommonConfigSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg); +#define CsrWifiSmeSmeCommonConfigSetReqSerFree CsrWifiSmePfree + +#define CsrWifiSmeInterfaceCapabilityGetReqSer CsrWifiEventSer +#define CsrWifiSmeInterfaceCapabilityGetReqDes CsrWifiEventDes +#define CsrWifiSmeInterfaceCapabilityGetReqSizeof CsrWifiEventSizeof +#define CsrWifiSmeInterfaceCapabilityGetReqSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeWpsConfigurationReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeWpsConfigurationReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeWpsConfigurationReqSizeof(void *msg); +extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg); + +#define CsrWifiSmeActivateCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeActivateCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeActivateCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeAdhocConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeAdhocConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeAdhocConfigGetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeAdhocConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeAdhocConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeAdhocConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeAdhocConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeAssociationCompleteIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeAssociationCompleteIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeAssociationCompleteIndSizeof(void *msg); +extern void CsrWifiSmeAssociationCompleteIndSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeAssociationStartIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeAssociationStartIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeAssociationStartIndSizeof(void *msg); +#define CsrWifiSmeAssociationStartIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeBlacklistCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeBlacklistCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeBlacklistCfmSizeof(void *msg); +extern void CsrWifiSmeBlacklistCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeCalibrationDataGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCalibrationDataGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCalibrationDataGetCfmSizeof(void *msg); +extern void CsrWifiSmeCalibrationDataGetCfmSerFree(void *msg); + +#define CsrWifiSmeCalibrationDataSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeCalibrationDataSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeCalibrationDataSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeCalibrationDataSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCcxConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCcxConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCcxConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeCcxConfigGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCcxConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCcxConfigSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCcxConfigSetCfmSizeof(void *msg); +#define CsrWifiSmeCcxConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCoexConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCoexConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCoexConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeCoexConfigGetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeCoexConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeCoexConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeCoexConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeCoexConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCoexInfoGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCoexInfoGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCoexInfoGetCfmSizeof(void *msg); +#define CsrWifiSmeCoexInfoGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeConnectCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeConnectCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeConnectCfmSizeof(void *msg); +#define CsrWifiSmeConnectCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeConnectionConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeConnectionConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeConnectionConfigGetCfmSizeof(void *msg); +extern void CsrWifiSmeConnectionConfigGetCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeConnectionInfoGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeConnectionInfoGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeConnectionInfoGetCfmSizeof(void *msg); +extern void CsrWifiSmeConnectionInfoGetCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeConnectionQualityIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeConnectionQualityIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeConnectionQualityIndSizeof(void *msg); +#define CsrWifiSmeConnectionQualityIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeConnectionStatsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeConnectionStatsGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg); +#define CsrWifiSmeConnectionStatsGetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeDeactivateCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeDeactivateCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeDeactivateCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeDeactivateCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeDisconnectCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeDisconnectCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeDisconnectCfmSizeof(void *msg); +#define CsrWifiSmeDisconnectCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeEventMaskSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeEventMaskSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeEventMaskSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeHostConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeHostConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeHostConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeHostConfigGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeHostConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeHostConfigSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeHostConfigSetCfmSizeof(void *msg); +#define CsrWifiSmeHostConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeIbssStationIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeIbssStationIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeIbssStationIndSizeof(void *msg); +#define CsrWifiSmeIbssStationIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeKeyCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeKeyCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeKeyCfmSizeof(void *msg); +#define CsrWifiSmeKeyCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeLinkQualityGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeLinkQualityGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeLinkQualityGetCfmSizeof(void *msg); +#define CsrWifiSmeLinkQualityGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeMediaStatusIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMediaStatusIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMediaStatusIndSizeof(void *msg); +extern void CsrWifiSmeMediaStatusIndSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeMibConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeMibConfigGetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeMibConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeMibConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeMibConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeMibConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeMibGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibGetCfmSizeof(void *msg); +extern void CsrWifiSmeMibGetCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeMibGetNextCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMibGetNextCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMibGetNextCfmSizeof(void *msg); +extern void CsrWifiSmeMibGetNextCfmSerFree(void *msg); + +#define CsrWifiSmeMibSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeMibSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeMibSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeMibSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeMicFailureIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMicFailureIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMicFailureIndSizeof(void *msg); +#define CsrWifiSmeMicFailureIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeMulticastAddressCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeMulticastAddressCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeMulticastAddressCfmSizeof(void *msg); +extern void CsrWifiSmeMulticastAddressCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmePacketFilterSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePacketFilterSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePacketFilterSetCfmSizeof(void *msg); +#define CsrWifiSmePacketFilterSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmePermanentMacAddressGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePermanentMacAddressGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg); +#define CsrWifiSmePermanentMacAddressGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmePmkidCandidateListIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePmkidCandidateListIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePmkidCandidateListIndSizeof(void *msg); +extern void CsrWifiSmePmkidCandidateListIndSerFree(void *msg); + +extern CsrUint8* CsrWifiSmePmkidCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePmkidCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePmkidCfmSizeof(void *msg); +extern void CsrWifiSmePmkidCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmePowerConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmePowerConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmePowerConfigGetCfmSizeof(void *msg); +#define CsrWifiSmePowerConfigGetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmePowerConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmePowerConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmePowerConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmePowerConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeRegulatoryDomainInfoGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeRegulatoryDomainInfoGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg); +#define CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeRoamCompleteIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeRoamCompleteIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeRoamCompleteIndSizeof(void *msg); +#define CsrWifiSmeRoamCompleteIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeRoamStartIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeRoamStartIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeRoamStartIndSizeof(void *msg); +#define CsrWifiSmeRoamStartIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeRoamingConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeRoamingConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeRoamingConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeRoamingConfigGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeRoamingConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeRoamingConfigSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeRoamingConfigSetCfmSizeof(void *msg); +#define CsrWifiSmeRoamingConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeScanConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeScanConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeScanConfigGetCfmSizeof(void *msg); +extern void CsrWifiSmeScanConfigGetCfmSerFree(void *msg); + +#define CsrWifiSmeScanConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeScanConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeScanConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeScanConfigSetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeScanFullCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeScanFullCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeScanFullCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeScanFullCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeScanResultIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeScanResultIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeScanResultIndSizeof(void *msg); +extern void CsrWifiSmeScanResultIndSerFree(void *msg); + +#define CsrWifiSmeScanResultsFlushCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeScanResultsFlushCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeScanResultsFlushCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeScanResultsFlushCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeScanResultsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeScanResultsGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeScanResultsGetCfmSizeof(void *msg); +extern void CsrWifiSmeScanResultsGetCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeSmeStaConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeSmeStaConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeSmeStaConfigGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeSmeStaConfigSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeSmeStaConfigSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg); +#define CsrWifiSmeSmeStaConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeStationMacAddressGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeStationMacAddressGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg); +#define CsrWifiSmeStationMacAddressGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeTspecIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeTspecIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeTspecIndSizeof(void *msg); +extern void CsrWifiSmeTspecIndSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeTspecCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeTspecCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeTspecCfmSizeof(void *msg); +extern void CsrWifiSmeTspecCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeVersionsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeVersionsGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeVersionsGetCfmSizeof(void *msg); +extern void CsrWifiSmeVersionsGetCfmSerFree(void *msg); + +#define CsrWifiSmeWifiFlightmodeCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeWifiFlightmodeCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeWifiFlightmodeCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeWifiFlightmodeCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeWifiOffIndSer CsrWifiEventCsrUint8Ser +#define CsrWifiSmeWifiOffIndDes CsrWifiEventCsrUint8Des +#define CsrWifiSmeWifiOffIndSizeof CsrWifiEventCsrUint8Sizeof +#define CsrWifiSmeWifiOffIndSerFree CsrWifiSmePfree + +#define CsrWifiSmeWifiOffCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeWifiOffCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeWifiOffCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeWifiOffCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeWifiOnCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeWifiOnCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeWifiOnCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeWifiOnCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeCloakedSsidsSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeCloakedSsidsSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeCloakedSsidsSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeCloakedSsidsSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeCloakedSsidsGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCloakedSsidsGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCloakedSsidsGetCfmSizeof(void *msg); +extern void CsrWifiSmeCloakedSsidsGetCfmSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeWifiOnIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeWifiOnIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeWifiOnIndSizeof(void *msg); +#define CsrWifiSmeWifiOnIndSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeSmeCommonConfigGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeSmeCommonConfigGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg); +#define CsrWifiSmeSmeCommonConfigGetCfmSerFree CsrWifiSmePfree + +#define CsrWifiSmeSmeCommonConfigSetCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeSmeCommonConfigSetCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeSmeCommonConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeSmeCommonConfigSetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeInterfaceCapabilityGetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeInterfaceCapabilityGetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg); +#define CsrWifiSmeInterfaceCapabilityGetCfmSerFree CsrWifiSmePfree + +extern CsrUint8* CsrWifiSmeErrorIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeErrorIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeErrorIndSizeof(void *msg); +extern void CsrWifiSmeErrorIndSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeInfoIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeInfoIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeInfoIndSizeof(void *msg); +extern void CsrWifiSmeInfoIndSerFree(void *msg); + +extern CsrUint8* CsrWifiSmeCoreDumpIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeCoreDumpIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeCoreDumpIndSizeof(void *msg); +extern void CsrWifiSmeCoreDumpIndSerFree(void *msg); + +#define CsrWifiSmeAmpStatusChangeIndSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiSmeAmpStatusChangeIndDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiSmeAmpStatusChangeIndSizeof CsrWifiEventCsrUint16CsrUint8Sizeof +#define CsrWifiSmeAmpStatusChangeIndSerFree CsrWifiSmePfree + +#define CsrWifiSmeWpsConfigurationCfmSer CsrWifiEventCsrUint16Ser +#define CsrWifiSmeWpsConfigurationCfmDes CsrWifiEventCsrUint16Des +#define CsrWifiSmeWpsConfigurationCfmSizeof CsrWifiEventCsrUint16Sizeof +#define CsrWifiSmeWpsConfigurationCfmSerFree CsrWifiSmePfree + + +#ifdef __cplusplus +} +#endif +#endif /* CSR_WIFI_SME_SERIALIZE_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_sme_task.h b/drivers/staging/csr/csr_wifi_sme_task.h new file mode 100644 index 000000000000..62cc8b77fe4a --- /dev/null +++ b/drivers/staging/csr/csr_wifi_sme_task.h @@ -0,0 +1,34 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#ifndef CSR_WIFI_SME_TASK_H__ +#define CSR_WIFI_SME_TASK_H__ + +#include "csr_types.h" +#include "csr_sched.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSR_WIFI_SME_LOG_ID 0x1202FFFF +extern CsrSchedQid CSR_WIFI_SME_IFACEQUEUE; +void CsrWifiSmeInit(void **gash); +void CsrWifiSmeDeinit(void **gash); +void CsrWifiSmeHandler(void **gash); + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_SME_TASK_H__ */ + diff --git a/drivers/staging/csr/csr_wifi_vif_utils.h b/drivers/staging/csr/csr_wifi_vif_utils.h new file mode 100644 index 000000000000..c534588c4c56 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_vif_utils.h @@ -0,0 +1,108 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#ifndef CSR_WIFI_VIF_UTILS_H +#define CSR_WIFI_VIF_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* STANDARD INCLUDES ********************************************************/ + +/* PROJECT INCLUDES *********************************************************/ +/* including this file for CsrWifiInterfaceMode*/ +#include "csr_wifi_private_common.h" + +/* MACROS *******************************************************************/ + +/* Common macros for NME and SME to be used temporarily until SoftMAC changes are made */ +#define CSR_WIFI_NUM_INTERFACES (CsrUint8)0x1 +#define CSR_WIFI_INTERFACE_IN_USE (CsrUint16)0x0 + +/* This is used at places where interface Id isn't available*/ +#define CSR_WIFI_INTERFACE_ZERO 0 +#define CSR_WIFI_INTERFACE_STA 0 +#define CSR_WIFI_INTERFACE_AMP 0 + + +#define CSR_WIFI_VIF_UTILS_UNDEFINED_TAG 0xFFFF + +/* Extract the Interface Id from the event */ +#define CsrWifiVifUtilsGetVifTagFromEvent(msg) \ + ((CsrUint16) * ((CsrUint16 *) ((CsrUint8 *) (msg) + sizeof(CsrWifiFsmEvent)))) + +/* The HPI Vif combines the type and the interface id */ +#define CsrWifiVifUtilsGetVifTagFromHipEvent(msg) \ + ((msg)->virtualInterfaceIdentifier & 0x00FF) + +#define CsrWifiVifUtilsPackHipEventVif(type, interfaceId) \ + ((CsrUint16)((interfaceId) | ((type) << 8))) + + +/* TYPES DEFINITIONS ********************************************************/ + +/* GLOBAL VARIABLE DECLARATIONS *********************************************/ + +/* PUBLIC FUNCTION PROTOTYPES ***********************************************/ + +/** + * @brief + * First checks if the mode is supported capability bitmap of the interface. + * If this succeeds, then checks if running this mode on this interface is allowed. + * + * @param[in] CsrUint8 : interface capability bitmap + * @param[in] CsrUint8* : pointer to the array of current interface modes + * @param[in] CsrUint16 : interfaceTag + * @param[in] CsrWifiInterfaceMode : mode + * + * @return + * CsrBool : returns true if the interface is allowed to operate in the mode otherwise false. + */ +extern CsrBool CsrWifiVifUtilsCheckCompatibility(CsrUint8 interfaceCapability, + CsrUint8 *currentInterfaceModes, + CsrUint16 interfaceTag, + CsrWifiInterfaceMode mode); + +/** + * @brief + * Checks if the specified interface is supported. + * NOTE: Only checks that the interface is supported, no checks are made to + * determine whether a supported interface may be made active. + * + * @param[in] CsrUint16 : interfaceTag + * + * @return + * CsrBool : returns true if the interface is supported, otherwise false. + */ +extern CsrBool CsrWifiVifUtilsIsSupported(CsrUint16 interfaceTag); + +#ifdef CSR_LOG_ENABLE +/** + * @brief + * Registers the virtual interface utils logging details. + * Should only be called once at initialisation. + * + * @param[in/out] None + * + * @return + * None + */ +void CsrWifiVifUtilsLogTextRegister(void); +#else +#define CsrWifiVifUtilsLogTextRegister() +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CSR_WIFI_VIF_UTILS_H */ + diff --git a/drivers/staging/csr/data_tx.c b/drivers/staging/csr/data_tx.c new file mode 100644 index 000000000000..c5858a58f3c1 --- /dev/null +++ b/drivers/staging/csr/data_tx.c @@ -0,0 +1,57 @@ +/* + * --------------------------------------------------------------------------- + * FILE: data_tx.c + * + * PURPOSE: + * This file provides functions to send data requests to the UniFi. + * + * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" + +int +uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int length) +{ + const unsigned char *p = packet; + CsrUint16 keyinfo; + + + if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8)) { + return 1; + } + + p += 8; + keyinfo = p[5] << 8 | p[6]; /* big-endian */ + if ( + (p[0] == 1 || p[0] == 2) /* protocol version 802.1X-2001 (WPA) or -2004 (WPA2) */ && + p[1] == 3 /* EAPOL-Key */ && + /* don't bother checking p[2] p[3] (hh ll, packet body length) */ + (p[4] == 254 || p[4] == 2) /* descriptor type P802.1i-D3.0 (WPA) or 802.11i-2004 (WPA2) */ && + ((keyinfo & 0x0007) == 1 || (keyinfo & 0x0007) == 2) /* key descriptor version */ && + (keyinfo & ~0x0207U) == 0x0108 && /* key info for 4/4 or 4/2 -- ignore key desc version and sec bit (since varies in WPA 4/4) */ + (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */ + p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0) + ) { + unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected \n"); + return 0; + } + else + { + return 1; + } +} + +/* + * --------------------------------------------------------------------------- + * + * Data transport signals. + * + * --------------------------------------------------------------------------- + */ + diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c new file mode 100644 index 000000000000..4545fb2b063b --- /dev/null +++ b/drivers/staging/csr/drv.c @@ -0,0 +1,2150 @@ +/* + * --------------------------------------------------------------------------- + * FILE: drv.c + * + * PURPOSE: + * Conventional device interface for debugging/monitoring of the + * driver and h/w using unicli. This interface is also being used + * by the SME linux implementation and the helper apps. + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + + + +/* + * Porting Notes: + * Part of this file contains an example for how to glue the OS layer + * with the HIP core lib, the SDIO glue layer, and the SME. + * + * When the unifi_sdio.ko modules loads, the linux kernel calls unifi_load(). + * unifi_load() calls uf_sdio_load() which is exported by the SDIO glue + * layer. uf_sdio_load() registers this driver with the underlying SDIO driver. + * When a card is detected, the SDIO glue layer calls register_unifi_sdio() + * to pass the SDIO function context and ask the OS layer to initialise + * the card. register_unifi_sdio() allocates all the private data of the OS + * layer and calls uf_run_unifihelper() to start the SME. The SME calls + * unifi_sys_wifi_on_req() which uses the HIP core lib to initialise the card. + */ + +#include +#include +#include +#include +#include + +#include "csr_wifi_hip_unifiversion.h" +#include "unifi_priv.h" +#include "csr_wifi_hip_conversions.h" +#include "unifi_native.h" + +/* Module parameter variables */ +int buswidth = 0; /* 0 means use default, values 1,4 */ +int sdio_clock = 50000; /* kHz */ +int unifi_debug = 0; +/* + * fw_init prevents f/w initialisation on error. + * Unless necessary, avoid usage in the CSR_SME_EMB build because it prevents + * UniFi initialisation after getting out of suspend and also leaves + * UniFi powered when the module unloads. + */ +int fw_init[MAX_UNIFI_DEVS] = {-1, -1}; +int use_5g = 0; +int led_mask = 0; /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */ +int disable_hw_reset = 0; +int disable_power_control = 0; +int enable_wol = UNIFI_WOL_OFF; /* 0 for none, 1 for SDIO IRQ, 2 for PIO */ +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) +int tl_80211d = (int)CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB; +#endif +int sdio_block_size = -1; /* Override SDIO block size */ +int sdio_byte_mode = 0; /* 0 for block mode + padding, 1 for byte mode */ +int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS; +int run_bh_once = -1; /* Set for scheduled interrupt mode, -1 = default */ +int bh_priority = -1; + +MODULE_DESCRIPTION("CSR UniFi (SDIO)"); + +module_param(buswidth, int, S_IRUGO|S_IWUSR); +module_param(sdio_clock, int, S_IRUGO|S_IWUSR); +module_param(unifi_debug, int, S_IRUGO|S_IWUSR); +module_param_array(fw_init, int, NULL, S_IRUGO|S_IWUSR); +module_param(use_5g, int, S_IRUGO|S_IWUSR); +module_param(led_mask, int, S_IRUGO|S_IWUSR); +module_param(disable_hw_reset, int, S_IRUGO|S_IWUSR); +module_param(disable_power_control, int, S_IRUGO|S_IWUSR); +module_param(enable_wol, int, S_IRUGO|S_IWUSR); +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) +module_param(tl_80211d, int, S_IRUGO|S_IWUSR); +#endif +module_param(sdio_block_size, int, S_IRUGO|S_IWUSR); +module_param(sdio_byte_mode, int, S_IRUGO|S_IWUSR); +module_param(coredump_max, int, S_IRUGO|S_IWUSR); +module_param(run_bh_once, int, S_IRUGO|S_IWUSR); +module_param(bh_priority, int, S_IRUGO|S_IWUSR); + +MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode"); +MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)"); +MODULE_PARM_DESC(unifi_debug, "Diagnostic reporting level"); +MODULE_PARM_DESC(fw_init, "Set to 0 to prevent f/w initialization on error"); +MODULE_PARM_DESC(use_5g, "Use the 5G (802.11a) radio band"); +MODULE_PARM_DESC(led_mask, "LED mask flags"); +MODULE_PARM_DESC(disable_hw_reset, "Set to 1 to disable hardware reset"); +MODULE_PARM_DESC(disable_power_control, "Set to 1 to disable SDIO power control"); +MODULE_PARM_DESC(enable_wol, "Enable wake-on-wlan function 0=off, 1=SDIO, 2=PIO"); +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) +MODULE_PARM_DESC(tl_80211d, "802.11d Trust Level (1-6, default = 5)"); +#endif +MODULE_PARM_DESC(sdio_block_size, "Set to override SDIO block size"); +MODULE_PARM_DESC(sdio_byte_mode, "Set to 1 for byte mode SDIO"); +MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate"); +MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts"); +MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority"); + +/* Callback for event logging to UDI clients */ +static void udi_log_event(ul_client_t *client, + const u8 *signal, int signal_len, + const bulk_data_param_t *bulkdata, + int dir); + +static void udi_set_log_filter(ul_client_t *pcli, + unifiio_filter_t *udi_filter); + + +/* Mutex to protect access to priv->sme_cli */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) +DEFINE_SEMAPHORE(udi_mutex); +#else +DECLARE_MUTEX(udi_mutex); +#endif + +CsrInt32 CsrHipResultToStatus(CsrResult csrResult) +{ + CsrInt32 r = -EIO; + + switch (csrResult) + { + case CSR_RESULT_SUCCESS: + r = 0; + break; + case CSR_WIFI_HIP_RESULT_RANGE: + r = -ERANGE; + break; + case CSR_WIFI_HIP_RESULT_NO_DEVICE: + r = -ENODEV; + break; + case CSR_WIFI_HIP_RESULT_INVALID_VALUE: + r = -EINVAL; + break; + case CSR_WIFI_HIP_RESULT_NOT_FOUND: + r = -ENOENT; + break; + case CSR_WIFI_HIP_RESULT_NO_SPACE: + r = -ENOSPC; + break; + case CSR_WIFI_HIP_RESULT_NO_MEMORY: + r = -ENOMEM; + break; + case CSR_RESULT_FAILURE: + r = -EIO; + break; + default: + /*unifi_warning(card->ospriv, "CsrHipResultToStatus: Unrecognised csrResult error code: %d\n", csrResult);*/ + r = -EIO; + } + return r; +} + + +static const char* +trace_putest_cmdid(unifi_putest_command_t putest_cmd) +{ + switch (putest_cmd) + { + case UNIFI_PUTEST_START: + return "START"; + case UNIFI_PUTEST_STOP: + return "STOP"; + case UNIFI_PUTEST_SET_SDIO_CLOCK: + return "SET CLOCK"; + case UNIFI_PUTEST_CMD52_READ: + return "CMD52R"; + case UNIFI_PUTEST_CMD52_BLOCK_READ: + return "CMD52BR"; + case UNIFI_PUTEST_CMD52_WRITE: + return "CMD52W"; + case UNIFI_PUTEST_DL_FW: + return "D/L FW"; + case UNIFI_PUTEST_DL_FW_BUFF: + return "D/L FW BUFFER"; + case UNIFI_PUTEST_COREDUMP_PREPARE: + return "PREPARE COREDUMP"; + case UNIFI_PUTEST_GP_READ16: + return "GP16R"; + case UNIFI_PUTEST_GP_WRITE16: + return "GP16W"; + default: + return "ERROR: unrecognised command"; + } + } + + + +/* + * --------------------------------------------------------------------------- + * unifi_open + * unifi_release + * + * Open and release entry points for the UniFi debug driver. + * + * Arguments: + * Normal linux driver args. + * + * Returns: + * Linux error code. + * --------------------------------------------------------------------------- + */ +static int +unifi_open(struct inode *inode, struct file *file) +{ + int devno; + unifi_priv_t *priv; + ul_client_t *udi_cli; + + func_enter(); + + devno = MINOR(inode->i_rdev) >> 1; + + /* + * Increase the ref_count for the char device clients. + * Make sure you call uf_put_instance() to decreace it if + * unifi_open returns an error. + */ + priv = uf_get_instance(devno); + if (priv == NULL) { + unifi_error(NULL, "unifi_open: No device present\n"); + func_exit(); + return -ENODEV; + } + + /* Register this instance in the client's list. */ + /* The minor number determines the nature of the client (Unicli or SME). */ + if (MINOR(inode->i_rdev) & 0x1) { + udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event); + if (udi_cli == NULL) { + /* Too many clients already using this device */ + unifi_error(priv, "Too many clients already open\n"); + uf_put_instance(devno); + func_exit(); + return -ENOSPC; + } + unifi_trace(priv, UDBG1, "Client is registered to /dev/unifiudi%d\n", devno); + } else { + /* + * Even-numbered device nodes are the control application. + * This is the userspace helper containing SME or + * unifi_manager. + */ + + down(&udi_mutex); + +#ifdef CSR_SME_USERSPACE + /* Check if a config client is already attached */ + if (priv->sme_cli) { + up(&udi_mutex); + uf_put_instance(devno); + + unifi_info(priv, "There is already a configuration client using the character device\n"); + func_exit(); + return -EBUSY; + } +#endif /* CSR_SME_USERSPACE */ + +#ifdef CSR_SUPPORT_SME + udi_cli = ul_register_client(priv, + CLI_USING_WIRE_FORMAT | CLI_SME_USERSPACE, + sme_log_event); +#else + /* Config client for native driver */ + udi_cli = ul_register_client(priv, + 0, + sme_native_log_event); +#endif + if (udi_cli == NULL) { + /* Too many clients already using this device */ + up(&udi_mutex); + uf_put_instance(devno); + + unifi_error(priv, "Too many clients already open\n"); + func_exit(); + return -ENOSPC; + } + + /* + * Fill-in the pointer to the configuration client. + * This is the SME userspace helper or unifi_manager. + * Not used in the SME embedded version. + */ + unifi_trace(priv, UDBG1, "SME client (id:%d s:0x%X) is registered\n", + udi_cli->client_id, udi_cli->sender_id); + /* Store the SME UniFi Linux Client */ + if (priv->sme_cli == NULL) { + priv->sme_cli = udi_cli; + } + + up(&udi_mutex); + } + + + /* + * Store the pointer to the client. + * All char driver's entry points will pass this pointer. + */ + file->private_data = udi_cli; + + func_exit(); + return 0; +} /* unifi_open() */ + + + +static int +unifi_release(struct inode *inode, struct file *filp) +{ + ul_client_t *udi_cli = (void*)filp->private_data; + int devno; + unifi_priv_t *priv; + + func_enter(); + + priv = uf_find_instance(udi_cli->instance); + if (!priv) { + unifi_error(priv, "unifi_close: instance for device not found\n"); + return -ENODEV; + } + + devno = MINOR(inode->i_rdev) >> 1; + + /* Even device nodes are the config client (i.e. SME or unifi_manager) */ + if ((MINOR(inode->i_rdev) & 0x1) == 0) { + + if (priv->sme_cli != udi_cli) { + unifi_notice(priv, "Surprise closing config device: not the sme client\n"); + } + unifi_notice(priv, "SME client close (unifi%d)\n", devno); + + /* + * Clear sme_cli before calling unifi_sys_... so it doesn't try to + * queue a reply to the (now gone) SME. + */ + down(&udi_mutex); + priv->sme_cli = NULL; + up(&udi_mutex); + +#ifdef CSR_SME_USERSPACE + /* Power-down when config client closes */ + { + CsrWifiRouterCtrlWifiOffReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, 0, 0, 0, NULL}}; + CsrWifiRouterCtrlWifiOffReqHandler(priv, &req.common); + } + + uf_sme_deinit(priv); +#endif /* CSR_SME_USERSPACE */ + } else { + + unifi_trace(priv, UDBG2, "UDI client close (unifiudi%d)\n", devno); + + /* If the pointer matches the logging client, stop logging. */ + down(&priv->udi_logging_mutex); + if (udi_cli == priv->logging_client) { + priv->logging_client = NULL; + } + up(&priv->udi_logging_mutex); + + if (udi_cli == priv->amp_client) { + priv->amp_client = NULL; + } + } + + /* Deregister this instance from the client's list. */ + ul_deregister_client(udi_cli); + + uf_put_instance(devno); + + return 0; +} /* unifi_release() */ + + + +/* + * --------------------------------------------------------------------------- + * unifi_read + * + * The read() driver entry point. + * + * Arguments: + * filp The file descriptor returned by unifi_open() + * p The user space buffer to copy the read data + * len The size of the p buffer + * poff + * + * Returns: + * number of bytes read or an error code on failure + * --------------------------------------------------------------------------- + */ +static ssize_t +unifi_read(struct file *filp, char *p, size_t len, loff_t *poff) +{ + ul_client_t *pcli = (void*)filp->private_data; + unifi_priv_t *priv; + udi_log_t *logptr = NULL; + udi_msg_t *msgptr; + struct list_head *l; + int msglen; + + func_enter(); + + priv = uf_find_instance(pcli->instance); + if (!priv) { + unifi_error(priv, "invalid priv\n"); + return -ENODEV; + } + + if (!pcli->udi_enabled) { + unifi_error(priv, "unifi_read: unknown client."); + return -EINVAL; + } + + if (list_empty(&pcli->udi_log)) { + if (filp->f_flags & O_NONBLOCK) { + /* Non-blocking - just return if the udi_log is empty */ + return 0; + } else { + /* Blocking - wait on the UDI wait queue */ + if (wait_event_interruptible(pcli->udi_wq, + !list_empty(&pcli->udi_log))) + { + unifi_error(priv, "unifi_read: wait_event_interruptible failed."); + return -ERESTARTSYS; + } + } + } + + /* Read entry from list head and remove it from the list */ + if (down_interruptible(&pcli->udi_sem)) { + return -ERESTARTSYS; + } + l = pcli->udi_log.next; + list_del(l); + up(&pcli->udi_sem); + + /* Get a pointer to whole struct */ + logptr = list_entry(l, udi_log_t, q); + if (logptr == NULL) { + unifi_error(priv, "unifi_read: failed to get event.\n"); + return -EINVAL; + } + + /* Get the real message */ + msgptr = &logptr->msg; + msglen = msgptr->length; + if (msglen > len) { + printk(KERN_WARNING "truncated read to %d actual msg len is %lu\n", msglen, (long unsigned int)len); + msglen = len; + } + + /* and pass it to the client (SME or Unicli). */ + if (copy_to_user(p, msgptr, msglen)) + { + printk(KERN_ERR "Failed to copy UDI log to user\n"); + kfree(logptr); + return -EFAULT; + } + + /* It is our resposibility to free the message buffer. */ + kfree(logptr); + + func_exit_r(msglen); + return msglen; + +} /* unifi_read() */ + + + +/* + * --------------------------------------------------------------------------- + * udi_send_signal_unpacked + * + * Sends an unpacked signal to UniFi. + * + * Arguments: + * priv Pointer to private context struct + * data Pointer to request structure and data to send + * data_len Length of data in data pointer. + * + * Returns: + * Number of bytes written, error otherwise. + * + * Notes: + * All clients that use this function to send a signal to the unifi + * must use the host formatted structures. + * --------------------------------------------------------------------------- + */ +static int +udi_send_signal_unpacked(unifi_priv_t *priv, unsigned char* data, uint data_len) +{ + CSR_SIGNAL *sigptr = (CSR_SIGNAL*)data; + CSR_DATAREF *datarefptr; + bulk_data_param_t bulk_data; + uint signal_size, i; + uint bulk_data_offset = 0; + int bytecount, r; + CsrResult csrResult; + + /* Number of bytes in the signal */ + signal_size = SigGetSize(sigptr); + if (!signal_size || (signal_size > data_len)) { + unifi_error(priv, "unifi_sme_mlme_req - Invalid signal 0x%x size should be %d bytes\n", + sigptr->SignalPrimitiveHeader.SignalId, + signal_size); + return -EINVAL; + } + bytecount = signal_size; + + /* Get a pointer to the information of the first data reference */ + datarefptr = (CSR_DATAREF*)&sigptr->u; + + /* Initialize the offset in the data buffer, bulk data is right after the signal. */ + bulk_data_offset = signal_size; + + /* store the references and the size of the bulk data to the bulkdata structure */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + /* the length of the bulk data is in the signal */ + if ((datarefptr+i)->DataLength) { + void *dest; + + csrResult = unifi_net_data_malloc(priv, &bulk_data.d[i], (datarefptr+i)->DataLength); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "udi_send_signal_unpacked: failed to allocate request_data.\n"); + return -EIO; + } + + dest = (void*)bulk_data.d[i].os_data_ptr; + memcpy(dest, data + bulk_data_offset, bulk_data.d[i].data_length); + } else { + bulk_data.d[i].data_length = 0; + } + + bytecount += bulk_data.d[i].data_length; + /* advance the offset, to point the next bulk data */ + bulk_data_offset += bulk_data.d[i].data_length; + } + + + unifi_trace(priv, UDBG3, "SME Send: signal 0x%.4X\n", sigptr->SignalPrimitiveHeader.SignalId); + + /* Send the signal. */ + r = ul_send_signal_unpacked(priv, sigptr, &bulk_data); + if (r < 0) { + unifi_error(priv, "udi_send_signal_unpacked: send failed (%d)\n", r); + for(i=0;i buflen)) { + unifi_error(priv, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n", + sig_id); + func_exit(); + return -EINVAL; + } + unifi_trace(priv, UDBG2, "udi_send_signal_raw: signal 0x%.4X len:%d\n", + sig_id, signal_size); + /* Zero the data ref arrays */ + memset(&data_ptrs, 0, sizeof(data_ptrs)); + + /* + * Find the number of associated bulk data packets. Scan through + * the data refs to check that we have enough data and pick out + * pointers to appended bulk data. + */ + num_data_refs = 0; + bytecount = signal_size; + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) + { + unsigned int len = GET_PACKED_DATAREF_LEN(buf, i); + unifi_trace(priv, UDBG3, "udi_send_signal_raw: data_ref length = %d\n", len); + + if (len != 0) { + void *dest; + + csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[i], len); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "udi_send_signal_raw: failed to allocate request_data.\n"); + return -EIO; + } + + dest = (void*)data_ptrs.d[i].os_data_ptr; + memcpy(dest, buf + bytecount, len); + + bytecount += len; + num_data_refs++; + } + data_ptrs.d[i].data_length = len; + } + + unifi_trace(priv, UDBG3, "Queueing signal 0x%.4X from UDI with %u data refs\n", + sig_id, + num_data_refs); + + if (bytecount > buflen) { + unifi_error(priv, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount); + func_exit(); + return -EINVAL; + } + + /* Send the signal calling the function that uses the wire-formatted signals. */ + r = ul_send_signal_raw(priv, buf, signal_size, &data_ptrs); + if (r < 0) { + unifi_error(priv, "udi_send_signal_raw: send failed (%d)\n", r); + func_exit(); + return -EIO; + } + +#ifdef CSR_NATIVE_LINUX + if (sig_id == CSR_MLME_POWERMGT_REQUEST_ID) { + int power_mode = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((buf + + SIZEOF_SIGNAL_HEADER + (UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF))); +#ifdef CSR_SUPPORT_WEXT + /* Overide the wext power mode to the new value */ + priv->wext_conf.power_mode = power_mode; +#endif + /* Configure deep sleep signaling */ + if (power_mode || (priv->interfacePriv[0]->connected == UnifiNotConnected)) { + csrResult = unifi_configure_low_power_mode(priv->card, + UNIFI_LOW_POWER_ENABLED, + UNIFI_PERIODIC_WAKE_HOST_DISABLED); + } else { + csrResult = unifi_configure_low_power_mode(priv->card, + UNIFI_LOW_POWER_DISABLED, + UNIFI_PERIODIC_WAKE_HOST_DISABLED); + } + } +#endif + + func_exit_r(bytecount); + + return bytecount; +} /* udi_send_signal_raw */ + +/* + * --------------------------------------------------------------------------- + * unifi_write + * + * The write() driver entry point. + * A UniFi Debug Interface client such as unicli can write a signal + * plus bulk data to the driver for sending to the UniFi chip. + * + * Only one signal may be sent per write operation. + * + * Arguments: + * filp The file descriptor returned by unifi_open() + * p The user space buffer to get the data from + * len The size of the p buffer + * poff + * + * Returns: + * number of bytes written or an error code on failure + * --------------------------------------------------------------------------- + */ +static ssize_t +unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) +{ + ul_client_t *pcli = (ul_client_t*)filp->private_data; + unifi_priv_t *priv; + unsigned char *buf; + unsigned char *bufptr; + int remaining; + int bytes_written; + int r; + bulk_data_param_t bulkdata; + CsrResult csrResult; + + func_enter(); + + priv = uf_find_instance(pcli->instance); + if (!priv) { + unifi_error(priv, "invalid priv\n"); + return -ENODEV; + } + + unifi_trace(priv, UDBG5, "unifi_write: len = %d\n", len); + + if (!pcli->udi_enabled) { + unifi_error(priv, "udi disabled\n"); + return -EINVAL; + } + + /* + * AMP client sends only one signal at a time, so we can use + * unifi_net_data_malloc to save the extra copy. + */ + if (pcli == priv->amp_client) { + int signal_size; + int sig_id; + unsigned char *signal_buf; + char *user_data_buf; + + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], len); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "unifi_write: failed to allocate request_data.\n"); + func_exit(); + return -ENOMEM; + } + + user_data_buf = (char*)bulkdata.d[0].os_data_ptr; + + /* Get the data from the AMP client. */ + if (copy_from_user((void*)user_data_buf, p, len)) { + unifi_error(priv, "unifi_write: copy from user failed\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + func_exit(); + return -EFAULT; + } + + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].data_length = 0; + + /* Number of bytes in the signal */ + sig_id = GET_SIGNAL_ID(bulkdata.d[0].os_data_ptr); + signal_size = len; + signal_size -= GET_PACKED_DATAREF_LEN(bulkdata.d[0].os_data_ptr, 0); + signal_size -= GET_PACKED_DATAREF_LEN(bulkdata.d[0].os_data_ptr, 1); + if ((signal_size <= 0) || (signal_size > len)) { + unifi_error(priv, "unifi_write - Couldn't find length of signal 0x%x\n", + sig_id); + unifi_net_data_free(priv, &bulkdata.d[0]); + func_exit(); + return -EINVAL; + } + + unifi_trace(priv, UDBG2, "unifi_write: signal 0x%.4X len:%d\n", + sig_id, signal_size); + + /* Allocate a buffer for the signal */ + signal_buf = kmalloc(signal_size, GFP_KERNEL); + if (!signal_buf) { + unifi_net_data_free(priv, &bulkdata.d[0]); + func_exit(); + return -ENOMEM; + } + + /* Get the signal from the os_data_ptr */ + memcpy(signal_buf, bulkdata.d[0].os_data_ptr, signal_size); + signal_buf[5] = (pcli->sender_id >> 8) & 0xff; + + if (signal_size < len) { + /* Remove the signal from the os_data_ptr */ + bulkdata.d[0].data_length -= signal_size; + bulkdata.d[0].os_data_ptr += signal_size; + } else { + bulkdata.d[0].data_length = 0; + bulkdata.d[0].os_data_ptr = NULL; + } + + /* Send the signal calling the function that uses the wire-formatted signals. */ + r = ul_send_signal_raw(priv, signal_buf, signal_size, &bulkdata); + if (r < 0) { + unifi_error(priv, "unifi_write: send failed (%d)\n", r); + if (bulkdata.d[0].os_data_ptr != NULL) { + unifi_net_data_free(priv, &bulkdata.d[0]); + } + } + + /* Free the signal buffer and return */ + kfree(signal_buf); + return len; + } + + buf = kmalloc(len, GFP_KERNEL); + if (!buf) { + return -ENOMEM; + } + + /* Get the data from the client (SME or Unicli). */ + if (copy_from_user((void*)buf, p, len)) { + unifi_error(priv, "copy from user failed\n"); + kfree(buf); + return -EFAULT; + } + + /* + * In SME userspace build read() contains a SYS or MGT message. + * Note that even though the SME sends one signal at a time, we can not + * use unifi_net_data_malloc because in the early stages, before having + * initialised the core, it will fail since the I/O block size is unknown. + */ +#ifdef CSR_SME_USERSPACE + if (pcli->configuration & CLI_SME_USERSPACE) { + CsrWifiRouterTransportRecv(priv, buf, len); + kfree(buf); + return len; + } +#endif + + /* ul_send_signal_raw will do a sanity check of len against signal content */ + + /* + * udi_send_signal_raw() and udi_send_signal_unpacked() return the number of bytes consumed. + * A write call can pass multiple signal concatenated together. + */ + bytes_written = 0; + remaining = len; + bufptr = buf; + while (remaining > 0) + { + int r; + + /* + * Set the SenderProcessId. + * The SignalPrimitiveHeader is the first 3 16-bit words of the signal, + * the SenderProcessId is bytes 4,5. + * The MSB of the sender ID needs to be set to the client ID. + * The LSB is controlled by the SME. + */ + bufptr[5] = (pcli->sender_id >> 8) & 0xff; + + /* use the appropriate interface, depending on the clients' configuration */ + if (pcli->configuration & CLI_USING_WIRE_FORMAT) { + unifi_trace(priv, UDBG1, "unifi_write: call udi_send_signal().\n"); + r = udi_send_signal_raw(priv, bufptr, remaining); + } else { + r = udi_send_signal_unpacked(priv, bufptr, remaining); + } + if (r < 0) { + /* Set the return value to the error code */ + unifi_error(priv, "unifi_write: (udi or sme)_send_signal() returns %d\n", r); + bytes_written = r; + break; + } + bufptr += r; + remaining -= r; + bytes_written += r; + } + + kfree(buf); + + func_exit_r(bytes_written); + + return bytes_written; +} /* unifi_write() */ + + +static const char* build_type_to_string(unsigned char build_type) +{ + switch (build_type) + { + case UNIFI_BUILD_NME: return "NME"; + case UNIFI_BUILD_WEXT: return "WEXT"; + case UNIFI_BUILD_AP: return "AP"; + } + return "unknown"; +} + + +/* + * ---------------------------------------------------------------- + * unifi_ioctl + * + * Ioctl handler for unifi driver. + * + * Arguments: + * inodep Pointer to inode structure. + * filp Pointer to file structure. + * cmd Ioctl cmd passed by user. + * arg Ioctl arg passed by user. + * + * Returns: + * 0 on success, -ve error code on error. + * ---------------------------------------------------------------- + */ +static long +unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + ul_client_t *pcli = (ul_client_t*)filp->private_data; + unifi_priv_t *priv; + struct net_device *dev; + int r = 0; + int int_param, i; + u8* buf; + CsrResult csrResult; +#if (defined CSR_SUPPORT_SME) + unifi_cfg_command_t cfg_cmd; +#if (defined CSR_SUPPORT_WEXT) + CsrWifiSmeCoexConfig coex_config; + unsigned char uchar_param; + unsigned char varbind[MAX_VARBIND_LENGTH]; + int vblen; +#endif +#endif + unifi_putest_command_t putest_cmd; + + priv = uf_find_instance(pcli->instance); + if (!priv) { + unifi_error(priv, "ioctl error: unknown instance=%d\n", pcli->instance); + r = -ENODEV; + goto out; + } + unifi_trace(priv, UDBG5, "unifi_ioctl: cmd=0x%X, arg=0x%lX\n", cmd, arg); + + switch (cmd) { + + case UNIFI_GET_UDI_ENABLE: + unifi_trace(priv, UDBG4, "UniFi Get UDI Enable\n"); + + down(&priv->udi_logging_mutex); + int_param = (priv->logging_client == NULL) ? 0 : 1; + up(&priv->udi_logging_mutex); + + if (put_user(int_param, (int*)arg)) + { + unifi_error(priv, "UNIFI_GET_UDI_ENABLE: Failed to copy to user\n"); + r = -EFAULT; + goto out; + } + break; + + case UNIFI_SET_UDI_ENABLE: + unifi_trace(priv, UDBG4, "UniFi Set UDI Enable\n"); + if (get_user(int_param, (int*)arg)) + { + unifi_error(priv, "UNIFI_SET_UDI_ENABLE: Failed to copy from user\n"); + r = -EFAULT; + goto out; + } + + down(&priv->udi_logging_mutex); + if (int_param) { + pcli->event_hook = udi_log_event; + unifi_set_udi_hook(priv->card, logging_handler); + /* Log all signals by default */ + for (i = 0; i < SIG_FILTER_SIZE; i++) { + pcli->signal_filter[i] = 0xFFFF; + } + priv->logging_client = pcli; + + } else { + priv->logging_client = NULL; + pcli->event_hook = NULL; + } + up(&priv->udi_logging_mutex); + + break; + + case UNIFI_SET_MIB: + unifi_trace(priv, UDBG4, "UniFi Set MIB\n"); +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + /* Read first 2 bytes and check length */ + if (copy_from_user((void*)varbind, (void*)arg, 2)) { + unifi_error(priv, + "UNIFI_SET_MIB: Failed to copy in varbind header\n"); + r = -EFAULT; + goto out; + } + vblen = varbind[1]; + if ((vblen + 2) > MAX_VARBIND_LENGTH) { + unifi_error(priv, + "UNIFI_SET_MIB: Varbind too long (%d, limit %d)\n", + (vblen+2), MAX_VARBIND_LENGTH); + r = -EINVAL; + goto out; + } + /* Read rest of varbind */ + if (copy_from_user((void*)(varbind+2), (void*)(arg+2), vblen)) { + unifi_error(priv, "UNIFI_SET_MIB: Failed to copy in varbind\n"); + r = -EFAULT; + goto out; + } + + /* send to SME */ + vblen += 2; + r = sme_mgt_mib_set(priv, varbind, vblen); + if (r) { + goto out; + } +#else + unifi_notice(priv, "UNIFI_SET_MIB: Unsupported.\n"); +#endif /* CSR_SUPPORT_WEXT */ + break; + + case UNIFI_GET_MIB: + unifi_trace(priv, UDBG4, "UniFi Get MIB\n"); +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + /* Read first 2 bytes and check length */ + if (copy_from_user((void*)varbind, (void*)arg, 2)) { + unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind header\n"); + r = -EFAULT; + goto out; + } + vblen = varbind[1]; + if ((vblen+2) > MAX_VARBIND_LENGTH) { + unifi_error(priv, "UNIFI_GET_MIB: Varbind too long (%d, limit %d)\n", + (vblen+2), MAX_VARBIND_LENGTH); + r = -EINVAL; + goto out; + } + /* Read rest of varbind */ + if (copy_from_user((void*)(varbind+2), (void*)(arg+2), vblen)) { + unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind\n"); + r = -EFAULT; + goto out; + } + + vblen += 2; + r = sme_mgt_mib_get(priv, varbind, &vblen); + if (r) { + goto out; + } + /* copy out varbind */ + if (vblen > MAX_VARBIND_LENGTH) { + unifi_error(priv, + "UNIFI_GET_MIB: Varbind result too long (%d, limit %d)\n", + vblen, MAX_VARBIND_LENGTH); + r = -EINVAL; + goto out; + } + if (copy_to_user((void*)arg, varbind, vblen)) { + r = -EFAULT; + goto out; + } +#else + unifi_notice(priv, "UNIFI_GET_MIB: Unsupported.\n"); +#endif /* CSR_SUPPORT_WEXT */ + break; + + case UNIFI_CFG: +#if (defined CSR_SUPPORT_SME) + if (get_user(cfg_cmd, (unifi_cfg_command_t*)arg)) + { + unifi_error(priv, "UNIFI_CFG: Failed to get the command\n"); + r = -EFAULT; + goto out; + } + + unifi_trace(priv, UDBG1, "UNIFI_CFG: Command is %d (t=%u) sz=%d\n", + cfg_cmd, jiffies_to_msecs(jiffies), sizeof(unifi_cfg_command_t)); + switch (cfg_cmd) { + case UNIFI_CFG_POWER: + r = unifi_cfg_power(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_POWERSAVE: + r = unifi_cfg_power_save(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_POWERSUPPLY: + r = unifi_cfg_power_supply(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_FILTER: + r = unifi_cfg_packet_filters(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_GET: + r = unifi_cfg_get_info(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_WMM_QOSINFO: + r = unifi_cfg_wmm_qos_info(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_WMM_ADDTS: + r = unifi_cfg_wmm_addts(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_WMM_DELTS: + r = unifi_cfg_wmm_delts(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_STRICT_DRAFT_N: + r = unifi_cfg_strict_draft_n(priv, (unsigned char*)arg); + break; + case UNIFI_CFG_ENABLE_OKC: + r = unifi_cfg_enable_okc(priv, (unsigned char*)arg); + break; +#ifdef CSR_SUPPORT_SME + case UNIFI_CFG_CORE_DUMP: + CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR); + unifi_trace(priv, UDBG2, "UNIFI_CFG_CORE_DUMP: sent wifi off indication\n"); + break; +#endif +#ifdef CSR_SUPPORT_WEXT_AP + case UNIFI_CFG_SET_AP_CONFIG: + r= unifi_cfg_set_ap_config(priv,(unsigned char*)arg); + break; +#endif + default: + unifi_error(priv, "UNIFI_CFG: Unknown Command (%d)\n", cfg_cmd); + r = -EINVAL; + goto out; + } +#endif + + break; + + case UNIFI_PUTEST: + if (get_user(putest_cmd, (unifi_putest_command_t*)arg)) + { + unifi_error(priv, "UNIFI_PUTEST: Failed to get the command\n"); + r = -EFAULT; + goto out; + } + + unifi_trace(priv, UDBG1, "UNIFI_PUTEST: Command is %s\n", + trace_putest_cmdid(putest_cmd)); + switch (putest_cmd) { + case UNIFI_PUTEST_START: + r = unifi_putest_start(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_STOP: + r = unifi_putest_stop(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_SET_SDIO_CLOCK: + r = unifi_putest_set_sdio_clock(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_CMD52_READ: + r = unifi_putest_cmd52_read(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_CMD52_BLOCK_READ: + r = unifi_putest_cmd52_block_read(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_CMD52_WRITE: + r = unifi_putest_cmd52_write(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_DL_FW: + r = unifi_putest_dl_fw(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_DL_FW_BUFF: + r = unifi_putest_dl_fw_buff(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_COREDUMP_PREPARE: + r = unifi_putest_coredump_prepare(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_GP_READ16: + r = unifi_putest_gp_read16(priv, (unsigned char*)arg); + break; + case UNIFI_PUTEST_GP_WRITE16: + r = unifi_putest_gp_write16(priv, (unsigned char*)arg); + break; + default: + unifi_error(priv, "UNIFI_PUTEST: Unknown Command (%d)\n", putest_cmd); + r = -EINVAL; + goto out; + } + + break; + case UNIFI_BUILD_TYPE: + unifi_trace(priv, UDBG2, "UNIFI_BUILD_TYPE userspace=%s\n", build_type_to_string(*(unsigned char*)arg)); +#ifndef CSR_SUPPORT_WEXT_AP + if (UNIFI_BUILD_AP == *(unsigned char*)arg) + { + unifi_error(priv, "Userspace has AP support, which is incompatible\n"); + } +#endif + +#ifndef CSR_SUPPORT_WEXT + if (UNIFI_BUILD_WEXT == *(unsigned char*)arg) + { + unifi_error(priv, "Userspace has WEXT support, which is incompatible\n"); + } +#endif + break; + case UNIFI_INIT_HW: + unifi_trace(priv, UDBG2, "UNIFI_INIT_HW.\n"); + priv->init_progress = UNIFI_INIT_NONE; + +#if defined(CSR_SUPPORT_WEXT) || defined (CSR_NATIVE_LINUX) + /* At this point we are ready to start the SME. */ + r = sme_mgt_wifi_on(priv); + if (r) { + goto out; + } +#endif + + break; + + case UNIFI_INIT_NETDEV: + { + /* get the proper interfaceTagId */ + CsrUint16 interfaceTag=0; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + dev = priv->netdev[interfaceTag]; + unifi_trace(priv, UDBG2, "UNIFI_INIT_NETDEV.\n"); + + if (copy_from_user((void*)dev->dev_addr, (void*)arg, 6)) { + r = -EFAULT; + goto out; + } + + /* Attach the network device to the stack */ + if (!interfacePriv->netdev_registered) + { + r = uf_register_netdev(priv,interfaceTag); + if (r) { + unifi_error(priv, "Failed to register the network device.\n"); + goto out; + } + } + + /* Apply scheduled interrupt mode, if requested by module param */ + if (run_bh_once != -1) { + unifi_set_interrupt_mode(priv->card, (CsrUint32)run_bh_once); + } + + priv->init_progress = UNIFI_INIT_COMPLETED; + + /* Firmware initialisation is complete, so let the SDIO bus + * clock be raised when convienent to the core. + */ + unifi_request_max_sdio_clock(priv->card); + +#ifdef CSR_SUPPORT_WEXT + /* Notify the Android wpa_supplicant that we are ready */ + wext_send_started_event(priv); +#endif + + unifi_info(priv, "UniFi ready\n"); + +#ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */ + { + struct net_device *dev = priv->netdev[interfaceTag]; +#ifdef CSR_SUPPORT_WEXT + interfacePriv->wait_netdev_change = TRUE; +#endif + netif_carrier_on(dev); + } +#endif + } + break; + case UNIFI_GET_INIT_STATUS: + unifi_trace(priv, UDBG2, "UNIFI_GET_INIT_STATUS.\n"); + if (put_user(priv->init_progress, (int*)arg)) + { + printk(KERN_ERR "UNIFI_GET_INIT_STATUS: Failed to copy to user\n"); + r = -EFAULT; + goto out; + } + break; + + case UNIFI_KICK: + unifi_trace(priv, UDBG4, "Kick UniFi\n"); + unifi_sdio_interrupt_handler(priv->card); + break; + + case UNIFI_SET_DEBUG: + unifi_debug = arg; + unifi_trace(priv, UDBG4, "unifi_debug set to %d\n", unifi_debug); + break; + + case UNIFI_SET_TRACE: + /* no longer supported */ + r = -EINVAL; + break; + + + case UNIFI_SET_UDI_LOG_MASK: + { + unifiio_filter_t udi_filter; + uint16_t *sig_ids_addr; +#define UF_MAX_SIG_IDS 128 /* Impose a sensible limit */ + + if (copy_from_user((void*)(&udi_filter), (void*)arg, sizeof(udi_filter))) { + r = -EFAULT; + goto out; + } + if ((udi_filter.action < UfSigFil_AllOn) || + (udi_filter.action > UfSigFil_SelectOff)) + { + printk(KERN_WARNING + "UNIFI_SET_UDI_LOG_MASK: Bad action value: %d\n", + udi_filter.action); + r = -EINVAL; + goto out; + } + /* No signal list for "All" actions */ + if ((udi_filter.action == UfSigFil_AllOn) || + (udi_filter.action == UfSigFil_AllOff)) + { + udi_filter.num_sig_ids = 0; + } + + if (udi_filter.num_sig_ids > UF_MAX_SIG_IDS) { + printk(KERN_WARNING + "UNIFI_SET_UDI_LOG_MASK: too many signal ids (%d, max %d)\n", + udi_filter.num_sig_ids, UF_MAX_SIG_IDS); + r = -EINVAL; + goto out; + } + + /* Copy in signal id list if given */ + if (udi_filter.num_sig_ids > 0) { + /* Preserve userspace address of sig_ids array */ + sig_ids_addr = udi_filter.sig_ids; + /* Allocate kernel memory for sig_ids and copy to it */ + udi_filter.sig_ids = + kmalloc(udi_filter.num_sig_ids * sizeof(uint16_t), GFP_KERNEL); + if (!udi_filter.sig_ids) { + r = -ENOMEM; + goto out; + } + if (copy_from_user((void*)udi_filter.sig_ids, + (void*)sig_ids_addr, + udi_filter.num_sig_ids * sizeof(uint16_t))) + { + kfree(udi_filter.sig_ids); + r = -EFAULT; + goto out; + } + } + + udi_set_log_filter(pcli, &udi_filter); + + if (udi_filter.num_sig_ids > 0) { + kfree(udi_filter.sig_ids); + } + } + break; + + case UNIFI_SET_AMP_ENABLE: + unifi_trace(priv, UDBG4, "UniFi Set AMP Enable\n"); + if (get_user(int_param, (int*)arg)) + { + unifi_error(priv, "UNIFI_SET_AMP_ENABLE: Failed to copy from user\n"); + r = -EFAULT; + goto out; + } + + if (int_param) { + priv->amp_client = pcli; + } else { + priv->amp_client = NULL; + } + + int_param = 0; + buf = (u8*)&int_param; + buf[0] = UNIFI_SOFT_COMMAND_Q_LENGTH - 1; + buf[1] = UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1; + if (copy_to_user((void*)arg, &int_param, sizeof(int))) { + r = -EFAULT; + goto out; + } + break; + + case UNIFI_SET_UDI_SNAP_MASK: + { + unifiio_snap_filter_t snap_filter; + + if (copy_from_user((void*)(&snap_filter), (void*)arg, sizeof(snap_filter))) { + r = -EFAULT; + goto out; + } + + if (pcli->snap_filter.count) { + pcli->snap_filter.count = 0; + CsrPmemFree(pcli->snap_filter.protocols); + } + + if (snap_filter.count == 0) { + break; + } + + pcli->snap_filter.protocols = CsrPmemAlloc(snap_filter.count * sizeof(CsrUint16)); + if (!pcli->snap_filter.protocols) { + r = -ENOMEM; + goto out; + } + if (copy_from_user((void*)pcli->snap_filter.protocols, + (void*)snap_filter.protocols, + snap_filter.count * sizeof(CsrUint16))) + { + CsrPmemFree(pcli->snap_filter.protocols); + r = -EFAULT; + goto out; + } + + pcli->snap_filter.count = snap_filter.count; + + } + break; + + case UNIFI_SME_PRESENT: + { + u8 ind; + unifi_trace(priv, UDBG4, "UniFi SME Present IOCTL.\n"); + if (copy_from_user((void*)(&int_param), (void*)arg, sizeof(int))) + { + printk(KERN_ERR "UNIFI_SME_PRESENT: Failed to copy from user\n"); + r = -EFAULT; + goto out; + } + + priv->sme_is_present = int_param; + if (priv->sme_is_present == 1) { + ind = CONFIG_SME_PRESENT; + } else { + ind = CONFIG_SME_NOT_PRESENT; + } + /* Send an indication to the helper app. */ + ul_log_config_ind(priv, &ind, sizeof(u8)); + } + break; + + case UNIFI_CFG_PERIOD_TRAFFIC: + { +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + CsrWifiSmeCoexConfig coexConfig; +#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */ + unifi_trace(priv, UDBG4, "UniFi Configure Periodic Traffic.\n"); +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + if (copy_from_user((void*)(&uchar_param), (void*)arg, sizeof(unsigned char))) { + unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n"); + r = -EFAULT; + goto out; + } + + if (uchar_param == 0) { + r = sme_mgt_coex_config_get(priv, &coexConfig); + if (r) { + unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Get unifi_CoexInfoValue failed.\n"); + goto out; + } + if (copy_to_user((void*)(arg + 1), + (void*)&coexConfig, + sizeof(CsrWifiSmeCoexConfig))) { + r = -EFAULT; + goto out; + } + goto out; + } + + if (copy_from_user((void*)(&coex_config), (void*)(arg + 1), sizeof(CsrWifiSmeCoexConfig))) + { + unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n"); + r = -EFAULT; + goto out; + } + + coexConfig = coex_config; + r = sme_mgt_coex_config_set(priv, &coexConfig); + if (r) { + unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Set unifi_CoexInfoValue failed.\n"); + goto out; + } + +#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */ + break; + } + case UNIFI_CFG_UAPSD_TRAFFIC: + unifi_trace(priv, UDBG4, "UniFi Configure U-APSD Mask.\n"); +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + if (copy_from_user((void*)(&uchar_param), (void*)arg, sizeof(unsigned char))) { + unifi_error(priv, "UNIFI_CFG_UAPSD_TRAFFIC: Failed to copy from user\n"); + r = -EFAULT; + goto out; + } + unifi_trace(priv, UDBG4, "New U-APSD Mask: 0x%x\n", uchar_param); +#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */ + break; + +#ifndef UNIFI_DISABLE_COREDUMP + case UNIFI_COREDUMP_GET_REG: + unifi_trace(priv, UDBG4, "Mini-coredump data request\n"); + { + unifiio_coredump_req_t dump_req; /* Public OS layer structure */ + unifi_coredump_req_t priv_req; /* Private HIP structure */ + + if (copy_from_user((void*)(&dump_req), (void*)arg, sizeof(dump_req))) { + r = -EFAULT; + goto out; + } + memset(&priv_req, 0, sizeof(priv_req)); + priv_req.index = dump_req.index; + priv_req.offset = dump_req.offset; + + /* Convert OS-layer's XAP memory space ID to HIP's ID in case they differ */ + switch (dump_req.space) { + case UNIFIIO_COREDUMP_MAC_REG: priv_req.space = UNIFI_COREDUMP_MAC_REG; break; + case UNIFIIO_COREDUMP_PHY_REG: priv_req.space = UNIFI_COREDUMP_PHY_REG; break; + case UNIFIIO_COREDUMP_SH_DMEM: priv_req.space = UNIFI_COREDUMP_SH_DMEM; break; + case UNIFIIO_COREDUMP_MAC_DMEM: priv_req.space = UNIFI_COREDUMP_MAC_DMEM; break; + case UNIFIIO_COREDUMP_PHY_DMEM: priv_req.space = UNIFI_COREDUMP_PHY_DMEM; break; + case UNIFIIO_COREDUMP_TRIGGER_MAGIC: priv_req.space = UNIFI_COREDUMP_TRIGGER_MAGIC; break; + default: + r = -EINVAL; + goto out; + } + + if (priv_req.space == UNIFI_COREDUMP_TRIGGER_MAGIC) { + /* Force a coredump grab now */ + unifi_trace(priv, UDBG2, "UNIFI_COREDUMP_GET_REG: Force capture\n"); + csrResult = unifi_coredump_capture(priv->card, &priv_req); + r = CsrHipResultToStatus(csrResult); + unifi_trace(priv, UDBG5, "UNIFI_COREDUMP_GET_REG: status %d\n", r); + } else { + /* Retrieve the appropriate register entry */ + csrResult = unifi_coredump_get_value(priv->card, &priv_req); + r = CsrHipResultToStatus(csrResult); + if (r) { + unifi_trace(priv, UDBG5, "UNIFI_COREDUMP_GET_REG: Status %d\n", r); + goto out; + } + /* Update the OS-layer structure with values returned in the private */ + dump_req.value = priv_req.value; + dump_req.timestamp = priv_req.timestamp; + dump_req.requestor = priv_req.requestor; + dump_req.serial = priv_req.serial; + dump_req.chip_ver = priv_req.chip_ver; + dump_req.fw_ver = priv_req.fw_ver; + dump_req.drv_build = 0; + + unifi_trace(priv, UDBG6, + "Dump: %d (seq %d): V:0x%04x (%d) @0x%02x:%04x = 0x%04x\n", + dump_req.index, dump_req.serial, + dump_req.chip_ver, dump_req.drv_build, + dump_req.space, dump_req.offset, dump_req.value); + } + if (copy_to_user((void*)arg, (void*)&dump_req, sizeof(dump_req))) { + r = -EFAULT; + goto out; + } + } + break; +#endif + default: + r = -EINVAL; + } + +out: + return (long)r; +} /* unifi_ioctl() */ + + + +static unsigned int +unifi_poll(struct file *filp, poll_table *wait) +{ + ul_client_t *pcli = (ul_client_t*)filp->private_data; + unsigned int mask = 0; + int ready; + + func_enter(); + + ready = !list_empty(&pcli->udi_log); + + poll_wait(filp, &pcli->udi_wq, wait); + + if (ready) { + mask |= POLLIN | POLLRDNORM; /* readable */ + } + + func_exit(); + + return mask; +} /* unifi_poll() */ + + + +/* + * --------------------------------------------------------------------------- + * udi_set_log_filter + * + * Configure the bit mask that determines which signal primitives are + * passed to the logging process. + * + * Arguments: + * pcli Pointer to the client to configure. + * udi_filter Pointer to a unifiio_filter_t containing instructions. + * + * Returns: + * None. + * + * Notes: + * SigGetFilterPos() returns a 32-bit value that contains an index and a + * mask for accessing a signal_filter array. The top 16 bits specify an + * index into a signal_filter, the bottom 16 bits specify a mask to + * apply. + * --------------------------------------------------------------------------- + */ +static void +udi_set_log_filter(ul_client_t *pcli, unifiio_filter_t *udi_filter) +{ + CsrUint32 filter_pos; + int i; + + if (udi_filter->action == UfSigFil_AllOn) + { + for (i = 0; i < SIG_FILTER_SIZE; i++) { + pcli->signal_filter[i] = 0xFFFF; + } + } + else if (udi_filter->action == UfSigFil_AllOff) + { + for (i = 0; i < SIG_FILTER_SIZE; i++) { + pcli->signal_filter[i] = 0; + } + } + else if (udi_filter->action == UfSigFil_SelectOn) + { + for (i = 0; i < udi_filter->num_sig_ids; i++) { + filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]); + if (filter_pos == 0xFFFFFFFF) + { + printk(KERN_WARNING + "Unrecognised signal id (0x%X) specifed in logging filter\n", + udi_filter->sig_ids[i]); + } else { + pcli->signal_filter[filter_pos >> 16] |= (filter_pos & 0xFFFF); + } + } + } + else if (udi_filter->action == UfSigFil_SelectOff) + { + for (i = 0; i < udi_filter->num_sig_ids; i++) { + filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]); + if (filter_pos == 0xFFFFFFFF) + { + printk(KERN_WARNING + "Unrecognised signal id (0x%X) specifed in logging filter\n", + udi_filter->sig_ids[i]); + } else { + pcli->signal_filter[filter_pos >> 16] &= ~(filter_pos & 0xFFFF); + } + } + } + +} /* udi_set_log_filter() */ + + +/* + * --------------------------------------------------------------------------- + * udi_log_event + * + * Callback function to be registered as the UDI hook callback. + * Copies the signal content into a new udi_log_t struct and adds + * it to the read queue for this UDI client. + * + * Arguments: + * pcli A pointer to the client instance. + * signal Pointer to the received signal. + * signal_len Size of the signal structure in bytes. + * bulkdata Pointers to any associated bulk data. + * dir Direction of the signal. Zero means from host, + * non-zero means to host. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +udi_log_event(ul_client_t *pcli, + const u8 *signal, int signal_len, + const bulk_data_param_t *bulkdata, + int dir) +{ + udi_log_t *logptr; + u8 *p; + int i; + int total_len; + udi_msg_t *msgptr; + CsrUint32 filter_pos; +#ifdef OMNICLI_LINUX_EXTRA_LOG + static volatile unsigned int printk_cpu = UINT_MAX; + unsigned long long t; + unsigned long nanosec_rem; + unsigned long n_1000; +#endif + + func_enter(); + + /* Just a sanity check */ + if ((signal == NULL) || (signal_len <= 0)) { + return; + } + +#ifdef CSR_NATIVE_LINUX + uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir); +#endif + + /* + * Apply the logging filter - only report signals that have their + * bit set in the filter mask. + */ + filter_pos = SigGetFilterPos(GET_SIGNAL_ID(signal)); + + if ((filter_pos != 0xFFFFFFFF) && + ((pcli->signal_filter[filter_pos >> 16] & (filter_pos & 0xFFFF)) == 0)) + { + /* Signal is not wanted by client */ + return; + } + + + /* Calculate the buffer we need to store signal plus bulk data */ + total_len = signal_len; + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + total_len += bulkdata->d[i].data_length; + } + + /* Allocate log structure plus actual signal. */ + logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL); + + if (logptr == NULL) { + printk(KERN_ERR + "Failed to allocate %lu bytes for a UDI log record\n", + (long unsigned int)(sizeof(udi_log_t) + total_len)); + return; + } + + /* Fill in udi_log struct */ + INIT_LIST_HEAD(&logptr->q); + msgptr = &logptr->msg; + msgptr->length = sizeof(udi_msg_t) + total_len; +#ifdef OMNICLI_LINUX_EXTRA_LOG + t = cpu_clock(printk_cpu); + nanosec_rem = do_div(t, 1000000000); + n_1000 = nanosec_rem/1000; + msgptr->timestamp = (t <<10 ) | ((unsigned long)(n_1000 >> 10) & 0x3ff); +#else + msgptr->timestamp = jiffies_to_msecs(jiffies); +#endif + msgptr->direction = dir; + msgptr->signal_length = signal_len; + + /* Copy signal and bulk data to the log */ + p = (u8 *)(msgptr + 1); + memcpy(p, signal, signal_len); + p += signal_len; + + /* Append any bulk data */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + int len = bulkdata->d[i].data_length; + + /* + * Len here might not be the same as the length in the bulk data slot. + * The slot length will always be even, but len could be odd. + */ + if (len > 0) { + if (bulkdata->d[i].os_data_ptr) { + memcpy(p, bulkdata->d[i].os_data_ptr, len); + } else { + memset(p, 0, len); + } + p += len; + } + } + + /* Add to tail of log queue */ + if (down_interruptible(&pcli->udi_sem)) { + printk(KERN_WARNING "udi_log_event_q: Failed to get udi sem\n"); + kfree(logptr); + func_exit(); + return; + } + list_add_tail(&logptr->q, &pcli->udi_log); + up(&pcli->udi_sem); + + /* Wake any waiting user process */ + wake_up_interruptible(&pcli->udi_wq); + + func_exit(); +} /* udi_log_event() */ + +#ifdef CSR_SME_USERSPACE +int +uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) +{ + udi_log_t *logptr; + udi_msg_t *msgptr; + u8 *p; + + func_enter(); + + /* Just a sanity check */ + if ((buffer == NULL) || (length <= 0)) { + return -EINVAL; + } + + /* Allocate log structure plus actual signal. */ + logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + length, GFP_ATOMIC); + if (logptr == NULL) { + unifi_error(priv, "Failed to allocate %d bytes for an SME message\n", + sizeof(udi_log_t) + length); + CsrPmemFree(buffer); + return -ENOMEM; + } + + /* Fill in udi_log struct */ + INIT_LIST_HEAD(&logptr->q); + msgptr = &logptr->msg; + msgptr->length = sizeof(udi_msg_t) + length; + msgptr->signal_length = length; + + /* Copy signal and bulk data to the log */ + p = (u8 *)(msgptr + 1); + memcpy(p, buffer, length); + + /* Add to tail of log queue */ + down(&udi_mutex); + if (priv->sme_cli == NULL) { + kfree(logptr); + CsrPmemFree(buffer); + up(&udi_mutex); + unifi_info(priv, "Message for the SME dropped, SME has gone away\n"); + return 0; + } + + down(&priv->sme_cli->udi_sem); + list_add_tail(&logptr->q, &priv->sme_cli->udi_log); + up(&priv->sme_cli->udi_sem); + + /* Wake any waiting user process */ + wake_up_interruptible(&priv->sme_cli->udi_wq); + up(&udi_mutex); + + /* It is our responsibility to free the buffer allocated in build_packed_*() */ + CsrPmemFree(buffer); + + func_exit(); + + return 0; + +} /* uf_sme_queue_message() */ +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ + device_create(_class, _parent, _devno, _priv, _fmt, _args) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ + device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args) +#else +#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ + device_create(_class, _parent, _devno, _fmt, _args) +#endif + +/* + **************************************************************************** + * + * Driver instantiation + * + **************************************************************************** + */ +static struct file_operations unifi_fops = { + .owner = THIS_MODULE, + .open = unifi_open, + .release = unifi_release, + .read = unifi_read, + .write = unifi_write, + .unlocked_ioctl = unifi_ioctl, + .poll = unifi_poll, +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ + device_create(_class, _parent, _devno, _priv, _fmt, _args) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ + device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args) +#else +#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \ + device_create(_class, _parent, _devno, _fmt, _args) +#endif + +static dev_t unifi_first_devno; +static struct class *unifi_class; + + +int uf_create_device_nodes(unifi_priv_t *priv, int bus_id) +{ + dev_t devno; + int r; + + cdev_init(&priv->unifi_cdev, &unifi_fops); + + /* cdev_init() should set the cdev owner, but it does not */ + priv->unifi_cdev.owner = THIS_MODULE; + + devno = MKDEV(MAJOR(unifi_first_devno), + MINOR(unifi_first_devno) + (bus_id * 2)); + r = cdev_add(&priv->unifi_cdev, devno, 1); + if (r) { + return r; + } + +#ifdef SDIO_EXPORTS_STRUCT_DEVICE + if (!UF_DEVICE_CREATE(unifi_class, priv->unifi_device, + devno, priv, "unifi%d", bus_id)) { +#else + priv->unifi_device = UF_DEVICE_CREATE(unifi_class, NULL, + devno, priv, "unifi%d", bus_id); + if (priv->unifi_device == NULL) { +#endif /* SDIO_EXPORTS_STRUCT_DEVICE */ + + cdev_del(&priv->unifi_cdev); + return -EINVAL; + } + + cdev_init(&priv->unifiudi_cdev, &unifi_fops); + + /* cdev_init() should set the cdev owner, but it does not */ + priv->unifiudi_cdev.owner = THIS_MODULE; + + devno = MKDEV(MAJOR(unifi_first_devno), + MINOR(unifi_first_devno) + (bus_id * MAX_UNIFI_DEVS) + 1); + r = cdev_add(&priv->unifiudi_cdev, devno, 1); + if (r) { + device_destroy(unifi_class, priv->unifi_cdev.dev); + cdev_del(&priv->unifi_cdev); + return r; + } + + if (!UF_DEVICE_CREATE(unifi_class, +#ifdef SDIO_EXPORTS_STRUCT_DEVICE + priv->unifi_device, +#else + NULL, +#endif /* SDIO_EXPORTS_STRUCT_DEVICE */ + devno, priv, "unifiudi%d", bus_id)) { + device_destroy(unifi_class, priv->unifi_cdev.dev); + cdev_del(&priv->unifiudi_cdev); + cdev_del(&priv->unifi_cdev); + return -EINVAL; + } + + return 0; +} + + +void uf_destroy_device_nodes(unifi_priv_t *priv) +{ + device_destroy(unifi_class, priv->unifiudi_cdev.dev); + device_destroy(unifi_class, priv->unifi_cdev.dev); + cdev_del(&priv->unifiudi_cdev); + cdev_del(&priv->unifi_cdev); +} + + + +/* + * ---------------------------------------------------------------- + * uf_create_debug_device + * + * Allocates device numbers for unifi character device nodes + * and creates a unifi class in sysfs + * + * Arguments: + * fops Pointer to the char device operations structure. + * + * Returns: + * 0 on success, -ve error code on error. + * ---------------------------------------------------------------- + */ +static int +uf_create_debug_device(struct file_operations *fops) +{ + int ret; + + /* Allocate two device numbers for each device. */ + ret = alloc_chrdev_region(&unifi_first_devno, 0, MAX_UNIFI_DEVS*2, UNIFI_NAME); + if (ret) { + unifi_error(NULL, "Failed to add alloc dev numbers: %d\n", ret); + return ret; + } + + /* Create a UniFi class */ + unifi_class = class_create(THIS_MODULE, UNIFI_NAME); + if (IS_ERR(unifi_class)) { + unifi_error(NULL, "Failed to create UniFi class\n"); + + /* Release device numbers */ + unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2); + unifi_first_devno = 0; + return -EINVAL; + } + + return 0; +} /* uf_create_debug_device() */ + + +/* + * ---------------------------------------------------------------- + * uf_remove_debug_device + * + * Destroys the unifi class and releases the allocated + * device numbers for unifi character device nodes. + * + * Arguments: + * + * Returns: + * ---------------------------------------------------------------- + */ +static void +uf_remove_debug_device(void) +{ + /* Destroy the UniFi class */ + class_destroy(unifi_class); + + /* Release device numbers */ + unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2); + unifi_first_devno = 0; + +} /* uf_remove_debug_device() */ + + +/* + * --------------------------------------------------------------------------- + * + * Module loading. + * + * --------------------------------------------------------------------------- + */ +int __init +unifi_load(void) +{ + int r; + + printk("UniFi SDIO Driver: %s %s %s\n", + CSR_WIFI_VERSION, + __DATE__, __TIME__); + +#ifdef CSR_SME_USERSPACE +#ifdef CSR_SUPPORT_WEXT + printk("CSR SME with WEXT support\n"); +#else + printk("CSR SME no WEXT support\n"); +#endif /* CSR_SUPPORT_WEXT */ +#endif /* CSR_SME_USERSPACE */ + +#ifdef CSR_NATIVE_LINUX +#ifdef CSR_SUPPORT_WEXT +#error WEXT unsupported in the native driver +#endif + printk("CSR native no WEXT support\n"); +#endif + + printk("Kernel %d.%d.%d\n", + ((LINUX_VERSION_CODE) >> 16) & 0xff, + ((LINUX_VERSION_CODE) >> 8) & 0xff, + (LINUX_VERSION_CODE) & 0xff); + /* + * Instantiate the /dev/unifi* device nodes. + * We must do this before registering with the SDIO driver because it + * will immediately call the "insert" callback if the card is + * already present. + */ + r = uf_create_debug_device(&unifi_fops); + if (r) { + return r; + } + + /* Now register with the SDIO driver */ + r = uf_sdio_load(); + if (r) { + uf_remove_debug_device(); + return r; + } + + if (sdio_block_size > -1) { + unifi_info(NULL, "sdio_block_size %d\n", sdio_block_size); + } + + if (sdio_byte_mode) { + unifi_info(NULL, "sdio_byte_mode\n"); + } + + if (disable_power_control) { + unifi_info(NULL, "disable_power_control\n"); + } + + if (disable_hw_reset) { + unifi_info(NULL, "disable_hw_reset\n"); + } + + if (enable_wol) { + unifi_info(NULL, "enable_wol %d\n", enable_wol); + } + + if (run_bh_once != -1) { + unifi_info(NULL, "run_bh_once %d\n", run_bh_once); + } + + return 0; +} /* unifi_load() */ + + +void __exit +unifi_unload(void) +{ + /* The SDIO remove hook will call unifi_disconnect(). */ + uf_sdio_unload(); + + uf_remove_debug_device(); + +} /* unifi_unload() */ + +module_init(unifi_load); +module_exit(unifi_unload); + +MODULE_DESCRIPTION("UniFi Device driver"); +MODULE_AUTHOR("Cambridge Silicon Radio Ltd."); +MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c new file mode 100644 index 000000000000..4ac3c89baa5d --- /dev/null +++ b/drivers/staging/csr/firmware.c @@ -0,0 +1,398 @@ +/* + * --------------------------------------------------------------------------- + * FILE: firmware.c + * + * PURPOSE: + * Implements the f/w related HIP core lib API. + * It is part of the porting exercise in Linux. + * + * Also, it contains example code for reading the loader and f/w files + * from the userspace and starting the SME in Linux. + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include +#include +#include +#include +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_unifi_udi.h" +#include "unifiio.h" +#include "unifi_priv.h" + +/* + * --------------------------------------------------------------------------- + * + * F/W download. Part of the HIP core API + * + * --------------------------------------------------------------------------- + */ + + +/* + * --------------------------------------------------------------------------- + * unifi_fw_read_start + * + * Returns a structure to be passed in unifi_fw_read(). + * This structure is an OS specific description of the f/w file. + * In the linux implementation it is a buffer with the f/w and its' length. + * The HIP driver calls this functions to request for the loader or + * the firmware file. + * The structure pointer can be freed when unifi_fw_read_stop() is called. + * + * Arguments: + * ospriv Pointer to driver context. + * is_fw Type of firmware to retrieve + * info Versions information. Can be used to determine + * the appropriate f/w file to load. + * + * Returns: + * O on success, non-zero otherwise. + * + * --------------------------------------------------------------------------- + */ +void* +unifi_fw_read_start(void *ospriv, CsrInt8 is_fw, const card_info_t *info) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + CSR_UNUSED(info); + + func_enter(); + + if (is_fw == UNIFI_FW_STA) { + /* F/w may have been released after a previous successful download. */ + if (priv->fw_sta.dl_data == NULL) { + unifi_trace(priv, UDBG2, "Attempt reload of sta f/w\n"); + uf_request_firmware_files(priv, UNIFI_FW_STA); + } + /* Set up callback struct for readfunc() */ + if (priv->fw_sta.dl_data != NULL) { + func_exit(); + return &priv->fw_sta; + } + + } else { + unifi_error(priv, "downloading firmware... unknown request: %d\n", is_fw); + } + + func_exit(); + return NULL; +} /* unifi_fw_read_start() */ + + + +/* + * --------------------------------------------------------------------------- + * unifi_fw_read_stop + * + * Called when the HIP driver has finished using the loader or + * the firmware file. + * The firmware buffer may be released now. + * + * Arguments: + * ospriv Pointer to driver context. + * dlpriv The pointer returned by unifi_fw_read_start() + * + * --------------------------------------------------------------------------- + */ +void +unifi_fw_read_stop(void *ospriv, void *dlpriv) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + struct dlpriv *dl_struct = (struct dlpriv *)dlpriv; + func_enter(); + + if (dl_struct != NULL) { + if (dl_struct->dl_data != NULL) { + unifi_trace(priv, UDBG2, "Release f/w buffer %p, %d bytes\n", + dl_struct->dl_data, dl_struct->dl_len); + } + uf_release_firmware(priv, dl_struct); + } + + func_exit(); +} /* unifi_fw_read_stop() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_fw_open_buffer + * + * Returns a handle for a buffer dynamically allocated by the driver, + * e.g. into which a firmware file may have been converted from another format + * which is the case with some production test images. + * + * The handle may then be used by unifi_fw_read() to access the contents of + * the buffer. + * + * Arguments: + * ospriv Pointer to driver context. + * fwbuf Buffer containing firmware image + * len Length of buffer in bytes + * + * Returns + * Handle for buffer, or NULL on error + * --------------------------------------------------------------------------- + */ +void * +unifi_fw_open_buffer(void *ospriv, void *fwbuf, CsrUint32 len) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + func_enter(); + + if (fwbuf == NULL) { + func_exit(); + return NULL; + } + priv->fw_conv.dl_data = fwbuf; + priv->fw_conv.dl_len = len; + priv->fw_conv.fw_desc = NULL; /* No OS f/w resource is associated */ + + func_exit(); + return &priv->fw_conv; +} + +/* + * --------------------------------------------------------------------------- + * unifi_fw_close_buffer + * + * Releases any handle for a buffer dynamically allocated by the driver, + * e.g. into which a firmware file may have been converted from another format + * which is the case with some production test images. + * + * + * Arguments: + * ospriv Pointer to driver context. + * fwbuf Buffer containing firmware image + * + * Returns + * Handle for buffer, or NULL on error + * --------------------------------------------------------------------------- + */ +void unifi_fw_close_buffer(void *ospriv, void *fwbuf) +{ +} + +/* + * --------------------------------------------------------------------------- + * unifi_fw_read + * + * The HIP driver calls this function to ask for a part of the loader or + * the firmware file. + * + * Arguments: + * ospriv Pointer to driver context. + * arg The pointer returned by unifi_fw_read_start(). + * offset The offset in the file to return from. + * buf A buffer to store the requested data. + * len The size of the buf and the size of the requested data. + * + * Returns + * The number of bytes read from the firmware image, or -ve on error + * --------------------------------------------------------------------------- + */ +CsrInt32 +unifi_fw_read(void *ospriv, void *arg, CsrUint32 offset, void *buf, CsrUint32 len) +{ + const struct dlpriv *dlpriv = arg; + + if (offset >= dlpriv->dl_len) { + /* at end of file */ + return 0; + } + + if ((offset + len) > dlpriv->dl_len) { + /* attempt to read past end of file */ + return -1; + } + + memcpy(buf, dlpriv->dl_data+offset, len); + + return len; + +} /* unifi_fw_read() */ + + + + +#define UNIFIHELPER_INIT_MODE_SMEEMB 0 +#define UNIFIHELPER_INIT_MODE_SMEUSER 2 +#define UNIFIHELPER_INIT_MODE_NATIVE 1 + +/* + * --------------------------------------------------------------------------- + * uf_run_unifihelper + * + * Ask userspace to send us firmware for download by running + * '/usr/sbin/unififw'. + * The same script starts the SME userspace application. + * Derived from net_run_sbin_hotplug(). + * + * Arguments: + * priv Pointer to OS private struct. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +int +uf_run_unifihelper(unifi_priv_t *priv) +{ +#ifdef CONFIG_HOTPLUG + +#ifdef ANDROID_BUILD + char *prog = "/system/bin/unififw"; +#else + char *prog = "/usr/sbin/unififw"; +#endif /* ANDROID_BUILD */ + + char *argv[6], *envp[4]; + char inst_str[8]; + char init_mode[8]; + int i, r; + +#if (defined CSR_SME_USERSPACE) && (!defined CSR_SUPPORT_WEXT) + unifi_trace(priv, UDBG1, "SME userspace build: run unifi_helper manually\n"); + return 0; +#endif + + unifi_trace(priv, UDBG1, "starting %s\n", prog); + + snprintf(inst_str, 8, "%d", priv->instance); +#if (defined CSR_SME_USERSPACE) + snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_SMEUSER); +#else + snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_NATIVE); +#endif /* CSR_SME_USERSPACE */ + + i = 0; + argv[i++] = prog; + argv[i++] = inst_str; + argv[i++] = init_mode; + argv[i++] = 0; + argv[i] = 0; + /* Don't add more args without making argv bigger */ + + /* minimal command environment */ + i = 0; + envp[i++] = "HOME=/"; + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + envp[i] = 0; + /* Don't add more without making envp bigger */ + + unifi_trace(priv, UDBG2, "running %s %s %s\n", argv[0], argv[1], argv[2]); + + r = call_usermodehelper(argv[0], argv, envp, 0); + + return r; +#else + unifi_trace(priv, UDBG1, "Can't automatically download firmware because kernel does not have HOTPLUG\n"); + return -1; +#endif +} /* uf_run_unifihelper() */ + + + +/* + * --------------------------------------------------------------------------- + * uf_request_firmware_files + * + * Get the firmware files from userspace. + * + * Arguments: + * priv Pointer to OS private struct. + * is_fw type of firmware to load (UNIFI_FW_STA/LOADER) + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +int uf_request_firmware_files(unifi_priv_t *priv, int is_fw) +{ + /* uses the default method to get the firmware */ + const struct firmware *fw_entry; + int postfix; +#define UNIFI_MAX_FW_PATH_LEN 32 + char fw_name[UNIFI_MAX_FW_PATH_LEN]; + int r; + +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + if (priv->mib_data.length) { + vfree(priv->mib_data.data); + priv->mib_data.data = NULL; + priv->mib_data.length = 0; + } +#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/ + + postfix = priv->instance; + + if (is_fw == UNIFI_FW_STA) { + /* Free kernel buffer and reload */ + uf_release_firmware(priv, &priv->fw_sta); + scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s", + postfix, "sta.xbv"); + r = request_firmware(&fw_entry, fw_name, priv->unifi_device); + if (r == 0) { + priv->fw_sta.dl_data = fw_entry->data; + priv->fw_sta.dl_len = fw_entry->size; + priv->fw_sta.fw_desc = (void *)fw_entry; + } else { + unifi_trace(priv, UDBG2, "Firmware file not available\n"); + } + } + + return 0; + +} /* uf_request_firmware_files() */ + +/* + * --------------------------------------------------------------------------- + * uf_release_firmware_files + * + * Release all buffers used to store firmware files + * + * Arguments: + * priv Pointer to OS private struct. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +int uf_release_firmware_files(unifi_priv_t *priv) +{ + uf_release_firmware(priv, &priv->fw_sta); + + return 0; +} + +/* + * --------------------------------------------------------------------------- + * uf_release_firmware + * + * Release specific buffer used to store firmware + * + * Arguments: + * priv Pointer to OS private struct. + * to_free Pointer to specific buffer to release + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +int uf_release_firmware(unifi_priv_t *priv, struct dlpriv *to_free) +{ + if (to_free != NULL) { + if (to_free->fw_desc != NULL) { + release_firmware((const struct firmware *)to_free->fw_desc); + } + to_free->fw_desc = NULL; + to_free->dl_data = NULL; + to_free->dl_len = 0; + } + return 0; +} diff --git a/drivers/staging/csr/indications.c b/drivers/staging/csr/indications.c new file mode 100644 index 000000000000..834b5f3e3b5d --- /dev/null +++ b/drivers/staging/csr/indications.c @@ -0,0 +1,18 @@ +/* + * *************************************************************************** + * FILE: indications.c + * + * PURPOSE: + * Callbacks to process signals sent to us by the UniFi chip. + * + * This file is linux-specific. + * + * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" diff --git a/drivers/staging/csr/inet.c b/drivers/staging/csr/inet.c new file mode 100644 index 000000000000..b4acb54ecc62 --- /dev/null +++ b/drivers/staging/csr/inet.c @@ -0,0 +1,106 @@ +/* + * --------------------------------------------------------------------------- + * FILE: inet.c + * + * PURPOSE: + * Routines related to IP address changes. + * Optional part of the porting exercise. It uses system network + * handlers to obtain the UniFi IP address and pass it to the SME + * using the unifi_sys_ip_configured_ind(). + * + * Copyright (C) 2008-2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include +#include + +#include "unifi_priv.h" +#include "csr_wifi_hip_conversions.h" + +/* + * The inet notifier is global and not per-netdev. To avoid having a + * notifier registered when there are no unifi devices present, it's + * registered after the first unifi network device is registered, and + * unregistered when the last unifi network device is unregistered. + */ + +static atomic_t inet_notif_refs = ATOMIC_INIT(0); + +static int uf_inetaddr_event(struct notifier_block *notif, unsigned long event, void *ifa) +{ + struct net_device *ndev; + unifi_priv_t *priv; + struct in_ifaddr *if_addr; + netInterface_priv_t *InterfacePriv = (netInterface_priv_t *)NULL; + + if (!ifa || !((struct in_ifaddr *)ifa)->ifa_dev) { + unifi_trace(NULL, UDBG1, "uf_inetaddr_event (%lu) ifa=%p\n", event, ifa); + return NOTIFY_DONE; + } + + ndev = ((struct in_ifaddr *)ifa)->ifa_dev->dev; + InterfacePriv = (netInterface_priv_t*) netdev_priv(ndev); + + /* As the notifier is global, the call may be for a non-UniFi netdev. + * Therefore check the netdev_priv to make sure it's a known UniFi one. + */ + if (uf_find_netdev_priv(InterfacePriv) == -1) { + unifi_trace(NULL, UDBG1, "uf_inetaddr_event (%lu) ndev=%p, other netdev_priv=%p\n", + event, ndev, InterfacePriv); + return NOTIFY_DONE; + } + + if (!InterfacePriv->privPtr) { + unifi_error(NULL, "uf_inetaddr_event null priv (%lu) ndev=%p, InterfacePriv=%p\n", + event, ndev, InterfacePriv); + return NOTIFY_DONE; + } + + priv = InterfacePriv->privPtr; + if_addr = (struct in_ifaddr *)ifa; + + /* If this event is for a UniFi device, notify the SME that an IP + * address has been added or removed. */ + if (uf_find_priv(priv) != -1) { + switch (event) { + case NETDEV_UP: + unifi_info(priv, "IP address assigned for %s\n", priv->netdev[InterfacePriv->InterfaceTag]->name); + priv->sta_ip_address = if_addr->ifa_address; +#ifdef CSR_SUPPORT_WEXT + sme_mgt_packet_filter_set(priv); +#endif + break; + case NETDEV_DOWN: + unifi_info(priv, "IP address removed for %s\n", priv->netdev[InterfacePriv->InterfaceTag]->name); + priv->sta_ip_address = 0xFFFFFFFF; +#ifdef CSR_SUPPORT_WEXT + sme_mgt_packet_filter_set(priv); +#endif + break; + } + } + + return NOTIFY_DONE; +} + +static struct notifier_block uf_inetaddr_notifier = { + .notifier_call = uf_inetaddr_event, +}; + +void uf_register_inet_notifier(void) +{ + if (atomic_inc_return(&inet_notif_refs) == 1) { + register_inetaddr_notifier(&uf_inetaddr_notifier); + } +} + +void uf_unregister_inet_notifier(void) +{ + if (atomic_dec_return(&inet_notif_refs) == 0) { + unregister_inetaddr_notifier(&uf_inetaddr_notifier); + } +} diff --git a/drivers/staging/csr/init_hw.c b/drivers/staging/csr/init_hw.c new file mode 100644 index 000000000000..3b8a4babf9a6 --- /dev/null +++ b/drivers/staging/csr/init_hw.c @@ -0,0 +1,108 @@ +/* + * --------------------------------------------------------------------------- + * FILE: init_hw.c + * + * PURPOSE: + * Use the HIP core lib to initialise the UniFi chip. + * It is part of the porting exercise in Linux. + * + * Copyright (C) 2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" + + +#define MAX_INIT_ATTEMPTS 4 + +extern int led_mask; + + +/* + * --------------------------------------------------------------------------- + * uf_init_hw + * + * Resets hardware, downloads and initialises f/w. + * This function demonstrates how to use the HIP core lib API + * to implement the SME unifi_sys_wifi_on_req() part of the SYS API. + * + * In a simple implementation, all this function needs to do is call + * unifi_init_card() and then unifi_card_info(). + * In the Linux implementation, it will retry to initialise UniFi or + * try to debug the reasons if unifi_init_card() returns an error. + * + * Arguments: + * ospriv Pointer to OS driver structure for the device. + * + * Returns: + * O on success, non-zero otherwise. + * + * --------------------------------------------------------------------------- + */ +int +uf_init_hw(unifi_priv_t *priv) +{ + int attempts = 0; + int priv_instance; + CsrResult csrResult = CSR_RESULT_FAILURE; + + priv_instance = uf_find_priv(priv); + if (priv_instance == -1) { + unifi_warning(priv, "uf_init_hw: Unknown priv instance, will use fw_init[0]\n"); + priv_instance = 0; + } + + while (1) { + if (attempts > MAX_INIT_ATTEMPTS) { + unifi_error(priv, "Failed to initialise UniFi after %d attempts, " + "giving up.\n", + attempts); + break; + } + attempts++; + + unifi_info(priv, "Initialising UniFi, attempt %d\n", attempts); + + if (fw_init[priv_instance] > 0) { + unifi_notice(priv, "f/w init prevented by module parameter\n"); + break; + } else if (fw_init[priv_instance] == 0) { + fw_init[priv_instance] ++; + } + + /* + * Initialise driver core. This will perform a reset of UniFi + * internals, but not the SDIO CCCR. + */ + CsrSdioClaim(priv->sdio); + csrResult = unifi_init_card(priv->card, led_mask); + CsrSdioRelease(priv->sdio); + + if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) { + return CsrHipResultToStatus(csrResult); + } + if (csrResult == CSR_WIFI_HIP_RESULT_NOT_FOUND) { + unifi_error(priv, "Firmware file required, but not found.\n"); + return CsrHipResultToStatus(csrResult); + } + if (csrResult != CSR_RESULT_SUCCESS) { + /* failed. Reset h/w and try again */ + unifi_error(priv, "Failed to initialise UniFi chip.\n"); + continue; + } + + /* Get the version information from the lib_hip */ + unifi_card_info(priv->card, &priv->card_info); + + return CsrHipResultToStatus(csrResult); + } + + return CsrHipResultToStatus(csrResult); + +} /* uf_init_hw */ + + diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c new file mode 100644 index 000000000000..fbf1b2099cc9 --- /dev/null +++ b/drivers/staging/csr/io.c @@ -0,0 +1,1146 @@ +/* + * --------------------------------------------------------------------------- + * FILE: io.c + * + * PURPOSE: + * This file contains routines that the SDIO driver can call when a + * UniFi card is first inserted (or detected) and removed. + * + * When used with sdioemb, the udev scripts (at least on Ubuntu) don't + * recognise a UniFi being added to the system. This is because sdioemb + * does not register itself as a device_driver, it uses it's own code + * to handle insert and remove. + * To have Ubuntu recognise UniFi, edit /etc/udev/rules.d/85-ifupdown.rules + * to change this line: + * SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start" + * to these: + * #SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start" + * SUBSYSTEM=="net", GOTO="net_start" + * + * Then you can add a stanza to /etc/network/interfaces like this: + * auto eth1 + * iface eth1 inet dhcp + * wpa-conf /etc/wpa_supplicant.conf + * This will then automatically associate when a car dis inserted. + * + * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_unifiversion.h" +#include "csr_wifi_hip_unifi_udi.h" /* for unifi_print_status() */ +#include "unifiio.h" +#include "unifi_priv.h" + + +/* + * Array of pointers to context structs for unifi devices that are present. + * The index in the array corresponds to the wlan interface number + * (if "wlan*" is used). If "eth*" is used, the eth* numbers are allocated + * after any Ethernet cards. + * + * The Arasan PCI-SDIO controller card supported by this driver has 2 slots, + * hence a max of 2 devices. + */ +static unifi_priv_t *Unifi_instances[MAX_UNIFI_DEVS]; + +/* Array of pointers to netdev objects used by the UniFi driver, as there + * are now many per instance. This is used to determine which netdev events + * are for UniFi as opposed to other net interfaces. + */ +static netInterface_priv_t *Unifi_netdev_instances[MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES]; + +/* + * Array to hold the status of each unifi device in each slot. + * We only process an insert event when In_use[] for the slot is + * UNIFI_DEV_NOT_IN_USE. Otherwise, it means that the slot is in use or + * we are in the middle of a cleanup (the action on unplug). + */ +#define UNIFI_DEV_NOT_IN_USE 0 +#define UNIFI_DEV_IN_USE 1 +#define UNIFI_DEV_CLEANUP 2 +static int In_use[MAX_UNIFI_DEVS]; +/* + * Mutex to prevent UDI clients to open the character device before the priv + * is created and initialised. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) +DEFINE_SEMAPHORE(Unifi_instance_mutex); +#else +DECLARE_MUTEX(Unifi_instance_mutex); +#endif +/* + * When the device is removed, unregister waits on Unifi_cleanup_wq + * until all the UDI clients release the character device. + */ +DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq); + + +static int uf_read_proc(char *page, char **start, off_t offset, int count, + int *eof, void *data); + +#ifdef CSR_WIFI_RX_PATH_SPLIT + +static CsrResult signal_buffer_init(unifi_priv_t * priv, int size) +{ + int i; + func_enter(); + + priv->rxSignalBuffer.writePointer = + priv->rxSignalBuffer.readPointer = 0; + priv->rxSignalBuffer.size = size; + /* Allocating Memory for Signal primitive pointer */ + for(i=0; irxSignalBuffer.rx_buff[i].sig_len=0; + priv->rxSignalBuffer.rx_buff[i].bufptr = CsrMemAlloc(UNIFI_PACKED_SIGBUF_SIZE); + if (priv->rxSignalBuffer.rx_buff[i].bufptr == NULL) + { + int j; + unifi_error(priv,"signal_buffer_init:Failed to Allocate shared memory for T-H signals \n"); + for(j=0;jrxSignalBuffer.rx_buff[j].sig_len=0; + CsrMemFree(priv->rxSignalBuffer.rx_buff[j].bufptr); + priv->rxSignalBuffer.rx_buff[j].bufptr = NULL; + } + func_exit(); + return -1; + } + } + func_exit(); + return 0; +} + + +static void signal_buffer_free(unifi_priv_t * priv, int size) +{ + int i; + + for(i=0; irxSignalBuffer.rx_buff[i].sig_len=0; + CsrMemFree(priv->rxSignalBuffer.rx_buff[i].bufptr); + priv->rxSignalBuffer.rx_buff[i].bufptr = NULL; + } +} +#endif +/* + * --------------------------------------------------------------------------- + * uf_register_netdev + * + * Registers the network interface, installes the qdisc, + * and registers the inet handler. + * In the porting exercise, register the driver to the network + * stack if necessary. + * + * Arguments: + * priv Pointer to driver context. + * + * Returns: + * O on success, non-zero otherwise. + * + * Notes: + * We will only unregister when the card is ejected, so we must + * only do it once. + * --------------------------------------------------------------------------- + */ +int +uf_register_netdev(unifi_priv_t *priv, int interfaceTag) +{ + int r; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_register_netdev bad interfaceTag\n"); + return -EINVAL; + } + + /* + * Allocates a device number and registers device with the network + * stack. + */ + unifi_trace(priv, UDBG5, "uf_register_netdev: netdev %d - 0x%p\n", + interfaceTag, priv->netdev[interfaceTag]); + r = register_netdev(priv->netdev[interfaceTag]); + if (r) { + unifi_error(priv, "Failed to register net device\n"); + return -EINVAL; + } + + /* The device is registed */ + interfacePriv->netdev_registered = 1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +#ifdef CONFIG_NET_SCHED + /* + * IMPORTANT: + * uf_install_qdisc() holds the network device lock, we can not + * install the qdisk before the network device is registered. + */ + r = uf_install_qdisc(priv->netdev[interfaceTag]); + if (r) { + unifi_error(priv, "Failed to install qdisc\n"); + return r; + } +#endif /* CONFIG_NET_SCHED */ +#endif /* LINUX_VERSION_CODE */ + +#ifdef CSR_SUPPORT_SME + /* + * Register the inet handler; it notifies us for changes in the IP address. + */ + uf_register_inet_notifier(); +#endif /* CSR_SUPPORT_SME */ + + unifi_notice(priv, "unifi%d is %s\n", + priv->instance, priv->netdev[interfaceTag]->name); + + return 0; +} /* uf_register_netdev */ + + +/* + * --------------------------------------------------------------------------- + * uf_unregister_netdev + * + * Unregisters the network interface and the inet handler. + * + * Arguments: + * priv Pointer to driver context. + * + * Returns: + * None. + * + * --------------------------------------------------------------------------- + */ +void +uf_unregister_netdev(unifi_priv_t *priv) +{ + int i=0; + +#ifdef CSR_SUPPORT_SME + /* Unregister the inet handler... */ + uf_unregister_inet_notifier(); +#endif /* CSR_SUPPORT_SME */ + + for (i=0; iinterfacePriv[i]; + if (interfacePriv->netdev_registered) { + unifi_trace(priv, UDBG5, + "uf_unregister_netdev: netdev %d - 0x%p\n", + i, priv->netdev[i]); + + /* ... and the netdev */ + unregister_netdev(priv->netdev[i]); + interfacePriv->netdev_registered = 0; + } + + interfacePriv->interfaceMode = 0; + + /* Enable all queues by default */ + interfacePriv->queueEnabled[0] = 1; + interfacePriv->queueEnabled[1] = 1; + interfacePriv->queueEnabled[2] = 1; + interfacePriv->queueEnabled[3] = 1; + } + + priv->totalInterfaceCount = 0; +} /* uf_unregister_netdev() */ + + +/* + * --------------------------------------------------------------------------- + * register_unifi_sdio + * + * This function is called from the Probe (or equivalent) method of + * the SDIO driver when a UniFi card is detected. + * We allocate the Linux net_device struct, initialise the HIP core + * lib, create the char device nodes and start the userspace helper + * to initialise the device. + * + * Arguments: + * sdio_dev Pointer to SDIO context handle to use for all + * SDIO ops. + * bus_id A small number indicating the SDIO card position on the + * bus. Typically this is the slot number, e.g. 0, 1 etc. + * Valid values are 0 to MAX_UNIFI_DEVS-1. + * dev Pointer to kernel device manager struct. + * + * Returns: + * Pointer to the unifi instance, or NULL on error. + * --------------------------------------------------------------------------- + */ +static unifi_priv_t * +register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) +{ + unifi_priv_t *priv = NULL; + int r = -1; + CsrResult csrResult; + + func_enter(); + + if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { + unifi_error(priv, "register_unifi_sdio: invalid device %d\n", + bus_id); + return NULL; + } + + down(&Unifi_instance_mutex); + + if (In_use[bus_id] != UNIFI_DEV_NOT_IN_USE) { + unifi_error(priv, "register_unifi_sdio: device %d is already in use\n", + bus_id); + goto failed0; + } + + + /* Allocate device private and net_device structs */ + priv = uf_alloc_netdevice(sdio_dev, bus_id); + if (priv == NULL) { + unifi_error(priv, "Failed to allocate driver private\n"); + goto failed0; + } + + priv->unifi_device = dev; + + SET_NETDEV_DEV(priv->netdev[0], dev); + + /* We are not ready to send data yet. */ + netif_carrier_off(priv->netdev[0]); + + /* Allocate driver context. */ + priv->card = unifi_alloc_card(priv->sdio, priv); + if (priv->card == NULL) { + unifi_error(priv, "Failed to allocate UniFi driver card struct.\n"); + goto failed1; + } + + if (Unifi_instances[bus_id]) { + unifi_error(priv, "Internal error: instance for slot %d is already taken\n", + bus_id); + } + Unifi_instances[bus_id] = priv; + In_use[bus_id] = UNIFI_DEV_IN_USE; + + /* Save the netdev_priv for use by the netdev event callback mechanism */ + Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES] = netdev_priv(priv->netdev[0]); + + /* Initialise the mini-coredump capture buffers */ + csrResult = unifi_coredump_init(priv->card, (CsrUint16)coredump_max); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Couldn't allocate mini-coredump buffers\n"); + } + + /* Create the character device nodes */ + r = uf_create_device_nodes(priv, bus_id); + if (r) { + goto failed1; + } + + /* + * We use the slot number as unifi device index. + */ + snprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance); + /* + * The following complex casting is in place in order to eliminate 64-bit compilation warning + * "cast to/from pointer from/to integer of different size" + */ + if (!create_proc_read_entry(priv->proc_entry_name, 0, 0, + uf_read_proc, (void *)(long)priv->instance)) + { + unifi_error(priv, "unifi: can't create /proc/driver/unifi\n"); + } + + /* Allocate the net_device for interfaces other than 0. */ + { + int i; + priv->totalInterfaceCount =0; + + for(i=1;inetdev[i], dev); + + /* We are not ready to send data yet. */ + netif_carrier_off(priv->netdev[i]); + + /* Save the netdev_priv for use by the netdev event callback mechanism */ + Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES + i] = netdev_priv(priv->netdev[i]); + } + } + + for(i=0;iinterfacePriv[i]; + interfacePriv->netdev_registered=0; + } + } + +#ifdef CSR_WIFI_RX_PATH_SPLIT + if (signal_buffer_init(priv, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE)) + { + unifi_error(priv,"Failed to allocate shared memory for T-H signals\n"); + goto failed2; + } + priv->rx_workqueue = create_singlethread_workqueue("rx_workq"); + if (priv->rx_workqueue == NULL) { + unifi_error(priv,"create_singlethread_workqueue failed \n"); + goto failed3; + } + INIT_WORK(&priv->rx_work_struct, rx_wq_handler); +#endif + + /* Initialise the SME related threads and parameters */ + r = uf_sme_init(priv); + if (r) { + unifi_error(priv, "SME initialisation failed.\n"); + goto failed4; + } + + /* + * Run the userspace helper program (unififw) to perform + * the device initialisation. + */ + unifi_trace(priv, UDBG1, "run UniFi helper app...\n"); + r = uf_run_unifihelper(priv); + if (r) { + unifi_notice(priv, "unable to run UniFi helper app\n"); + /* Not a fatal error. */ + } + + up(&Unifi_instance_mutex); + + func_exit(); + return priv; + +failed4: +#ifdef CSR_WIFI_RX_PATH_SPLIT + flush_workqueue(priv->rx_workqueue); + destroy_workqueue(priv->rx_workqueue); +failed3: + signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE); +failed2: +#endif + /* Remove the device nodes */ + uf_destroy_device_nodes(priv); +failed1: + /* Deregister priv->netdev_client */ + ul_deregister_client(priv->netdev_client); + +failed0: + if (priv && priv->card) { + unifi_coredump_free(priv->card); + unifi_free_card(priv->card); + } + if (priv) { + uf_free_netdevice(priv); + } + + up(&Unifi_instance_mutex); + + func_exit(); + return NULL; +} /* register_unifi_sdio() */ + + +/* + * --------------------------------------------------------------------------- + * ask_unifi_sdio_cleanup + * + * We can not free our private context, until all the char device + * clients have closed the file handles. unregister_unifi_sdio() which + * is called when a card is removed, waits on Unifi_cleanup_wq until + * the reference count becomes zero. It is time to wake it up now. + * + * Arguments: + * priv Pointer to driver context. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +ask_unifi_sdio_cleanup(unifi_priv_t *priv) +{ + func_enter(); + + /* + * Now clear the flag that says the old instance is in use. + * This is used to prevent a new instance being started before old + * one has finshed closing down, for example if bounce makes the card + * appear to be ejected and re-inserted quickly. + */ + In_use[priv->instance] = UNIFI_DEV_CLEANUP; + + unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n"); + wake_up(&Unifi_cleanup_wq); + + func_exit(); + +} /* ask_unifi_sdio_cleanup() */ + + +/* + * --------------------------------------------------------------------------- + * cleanup_unifi_sdio + * + * Release any resources owned by a unifi instance. + * + * Arguments: + * priv Pointer to the instance to free. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +cleanup_unifi_sdio(unifi_priv_t *priv) +{ + int priv_instance; + int i; + static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + + func_enter(); + + /* Remove the device nodes */ + uf_destroy_device_nodes(priv); + + /* Mark this device as gone away by NULLing the entry in Unifi_instances */ + Unifi_instances[priv->instance] = NULL; + + unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: remove_proc_entry\n"); + /* + * Free the children of priv before unifi_free_netdevice() frees + * the priv struct + */ + remove_proc_entry(priv->proc_entry_name, 0); + + + /* Unregister netdev as a client. */ + if (priv->netdev_client) { + unifi_trace(priv, UDBG2, "Netdev client (id:%d s:0x%X) is unregistered\n", + priv->netdev_client->client_id, priv->netdev_client->sender_id); + ul_deregister_client(priv->netdev_client); + } + + /* Destroy the SME related threads and parameters */ + uf_sme_deinit(priv); + +#ifdef CSR_SME_USERSPACE + priv->smepriv = NULL; +#endif + + /* Free any packets left in the Rx queues */ + for(i=0;icard) { + unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: free card\n"); + unifi_coredump_free(priv->card); + unifi_free_card(priv->card); + priv->card = NULL; + } + + /* + * Unregister the network device. + * We can not unregister the netdev before we release + * all pending packets in the core. + */ + uf_unregister_netdev(priv); + priv->totalInterfaceCount = 0; + + /* Clear the table of registered netdev_priv's */ + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + Unifi_netdev_instances[priv->instance * CSR_WIFI_NUM_INTERFACES + i] = NULL; + } + + unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: uf_free_netdevice\n"); + /* + * When uf_free_netdevice() returns, the priv is invalid + * so we need to remember the instance to clear the global flag later. + */ + priv_instance = priv->instance; + +#ifdef CSR_WIFI_RX_PATH_SPLIT + flush_workqueue(priv->rx_workqueue); + destroy_workqueue(priv->rx_workqueue); + signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE); +#endif + + /* Priv is freed as part of the net_device */ + uf_free_netdevice(priv); + + /* + * Now clear the flag that says the old instance is in use. + * This is used to prevent a new instance being started before old + * one has finshed closing down, for example if bounce makes the card + * appear to be ejected and re-inserted quickly. + */ + In_use[priv_instance] = UNIFI_DEV_NOT_IN_USE; + + unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n"); + + func_exit(); + +} /* cleanup_unifi_sdio() */ + + +/* + * --------------------------------------------------------------------------- + * unregister_unifi_sdio + * + * Call from SDIO driver when it detects that UniFi has been removed. + * + * Arguments: + * bus_id Number of the card that was ejected. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +unregister_unifi_sdio(int bus_id) +{ + unifi_priv_t *priv; + int interfaceTag=0; + u8 reason = CONFIG_IND_EXIT; + + if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { + unifi_error(NULL, "unregister_unifi_sdio: invalid device %d\n", + bus_id); + return; + } + + priv = Unifi_instances[bus_id]; + if (priv == NULL) { + unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n", + bus_id); + func_exit(); + return; + } + + /* Stop the network traffic before freeing the core. */ + for(interfaceTag=0;interfaceTagtotalInterfaceCount;interfaceTag++) + { + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + if(interfacePriv->netdev_registered) + { + netif_carrier_off(priv->netdev[interfaceTag]); + UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); + } + } + +#ifdef CSR_NATIVE_LINUX + /* + * If the unifi thread was started, signal it to stop. This + * should cause any userspace processes with open unifi device to + * close them. + */ + uf_stop_thread(priv, &priv->bh_thread); + + /* Unregister the interrupt handler */ + if (csr_sdio_linux_remove_irq(priv->sdio)) { + unifi_notice(priv, + "csr_sdio_linux_remove_irq failed to talk to card.\n"); + } + + /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */ + uf_abort_mlme(priv); +#endif /* CSR_NATIVE_LINUX */ + + ul_log_config_ind(priv, &reason, sizeof(u8)); + + /* Deregister the UDI hook from the core. */ + unifi_remove_udi_hook(priv->card, logging_handler); + + uf_put_instance(bus_id); + + /* + * Wait until the device is cleaned up. i.e., when all userspace + * processes have closed any open unifi devices. + */ + wait_event(Unifi_cleanup_wq, In_use[bus_id] == UNIFI_DEV_CLEANUP); + unifi_trace(NULL, UDBG5, "Received clean up event\n"); + + /* Now we can free the private context and the char device nodes */ + cleanup_unifi_sdio(priv); + +} /* unregister_unifi_sdio() */ + + +/* + * --------------------------------------------------------------------------- + * uf_find_instance + * + * Find the context structure for a given UniFi device instance. + * + * Arguments: + * inst The instance number to look for. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +unifi_priv_t * +uf_find_instance(int inst) +{ + if ((inst < 0) || (inst >= MAX_UNIFI_DEVS)) { + return NULL; + } + return Unifi_instances[inst]; +} /* uf_find_instance() */ + + +/* + * --------------------------------------------------------------------------- + * uf_find_priv + * + * Find the device instance for a given context structure. + * + * Arguments: + * priv The context structure pointer to look for. + * + * Returns: + * index of instance, -1 otherwise. + * --------------------------------------------------------------------------- + */ +int +uf_find_priv(unifi_priv_t *priv) +{ + int inst; + + if (!priv) { + return -1; + } + + for (inst = 0; inst < MAX_UNIFI_DEVS; inst++) { + if (Unifi_instances[inst] == priv) { + return inst; + } + } + + return -1; +} /* uf_find_priv() */ + +/* + * --------------------------------------------------------------------------- + * uf_find_netdev_priv + * + * Find the device instance for a given netdev context structure. + * + * Arguments: + * priv The context structure pointer to look for. + * + * Returns: + * index of instance, -1 otherwise. + * --------------------------------------------------------------------------- + */ +int +uf_find_netdev_priv(netInterface_priv_t *priv) +{ + int inst; + + if (!priv) { + return -1; + } + + for (inst = 0; inst < MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES; inst++) { + if (Unifi_netdev_instances[inst] == priv) { + return inst; + } + } + + return -1; +} /* uf_find_netdev_priv() */ + +/* + * --------------------------------------------------------------------------- + * uf_get_instance + * + * Find the context structure for a given UniFi device instance + * and increment the reference count. + * + * Arguments: + * inst The instance number to look for. + * + * Returns: + * Pointer to the instance or NULL if no instance exists. + * --------------------------------------------------------------------------- + */ +unifi_priv_t * +uf_get_instance(int inst) +{ + unifi_priv_t *priv; + + down(&Unifi_instance_mutex); + + priv = uf_find_instance(inst); + if (priv) { + priv->ref_count++; + } + + up(&Unifi_instance_mutex); + + return priv; +} + +/* + * --------------------------------------------------------------------------- + * uf_put_instance + * + * Decrement the context reference count, freeing resources and + * shutting down the driver when the count reaches zero. + * + * Arguments: + * inst The instance number to look for. + * + * Returns: + * Pointer to the instance or NULL if no instance exists. + * --------------------------------------------------------------------------- + */ +void +uf_put_instance(int inst) +{ + unifi_priv_t *priv; + + down(&Unifi_instance_mutex); + + priv = uf_find_instance(inst); + if (priv) { + priv->ref_count--; + if (priv->ref_count == 0) { + ask_unifi_sdio_cleanup(priv); + } + } + + up(&Unifi_instance_mutex); +} + + +/* + * --------------------------------------------------------------------------- + * uf_read_proc + * + * Read method for driver node in /proc/driver/unifi0 + * + * Arguments: + * page + * start + * offset + * count + * eof + * data + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +#ifdef CONFIG_PROC_FS +static int +uf_read_proc(char *page, char **start, off_t offset, int count, + int *eof, void *data) +{ +#define UNIFI_DEBUG_TXT_BUFFER 8*1024 + unifi_priv_t *priv; + int actual_amount_to_copy; + char *p, *orig_p; + CsrInt32 remain = UNIFI_DEBUG_TXT_BUFFER; + CsrInt32 written; + int i; + + /* + * The following complex casting is in place in order to eliminate 64-bit compilation warning + * "cast to/from pointer from/to integer of different size" + */ + priv = uf_find_instance((int)(long)data); + if (!priv) { + return 0; + } + + p = kmalloc( UNIFI_DEBUG_TXT_BUFFER, GFP_KERNEL ); + + orig_p = p; + + written = CsrSnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n", + CSR_WIFI_VERSION, __DATE__, __TIME__); + UNIFI_SNPRINTF_RET(p, remain, written); +#ifdef CSR_SME_USERSPACE + written = CsrSnprintf(p, remain, "SME: CSR userspace "); + UNIFI_SNPRINTF_RET(p, remain, written); +#ifdef CSR_SUPPORT_WEXT + written = CsrSnprintf(p, remain, "with WEXT support\n"); +#else + written = CsrSnprintf(p, remain, "\n"); +#endif /* CSR_SUPPORT_WEXT */ + UNIFI_SNPRINTF_RET(p, remain, written); +#endif /* CSR_SME_USERSPACE */ +#ifdef CSR_NATIVE_LINUX + written = CsrSnprintf(p, remain, "SME: native\n"); + UNIFI_SNPRINTF_RET(p, remain, written); +#endif + +#ifdef CSR_SUPPORT_SME + written = CsrSnprintf(p, remain, + "Firmware (ROM) build:%lu, Patch:%lu\n", + priv->card_info.fw_build, + priv->sme_versions.firmwarePatch); + UNIFI_SNPRINTF_RET(p, remain, written); +#endif + p += unifi_print_status(priv->card, p, &remain); + + written = CsrSnprintf(p, remain, "Last dbg str: %s\n", + priv->last_debug_string); + UNIFI_SNPRINTF_RET(p, remain, written); + + written = CsrSnprintf(p, remain, "Last dbg16:"); + UNIFI_SNPRINTF_RET(p, remain, written); + for (i = 0; i < 8; i++) { + written = CsrSnprintf(p, remain, " %04X", + priv->last_debug_word16[i]); + UNIFI_SNPRINTF_RET(p, remain, written); + } + written = CsrSnprintf(p, remain, "\n"); + UNIFI_SNPRINTF_RET(p, remain, written); + written = CsrSnprintf(p, remain, " "); + UNIFI_SNPRINTF_RET(p, remain, written); + for (; i < 16; i++) { + written = CsrSnprintf(p, remain, " %04X", + priv->last_debug_word16[i]); + UNIFI_SNPRINTF_RET(p, remain, written); + } + written = CsrSnprintf(p, remain, "\n"); + UNIFI_SNPRINTF_RET(p, remain, written); + *start = page; + + written = UNIFI_DEBUG_TXT_BUFFER - remain; + + if( offset >= written ) + { + *eof = 1; + kfree( orig_p ); + return(0); + } + + if( offset + count > written ) + { + actual_amount_to_copy = written - offset; + *eof = 1; + } + else + { + actual_amount_to_copy = count; + } + + memcpy( page, &(orig_p[offset]), actual_amount_to_copy ); + + kfree( orig_p ); + + return( actual_amount_to_copy ); +} /* uf_read_proc() */ +#endif + + + + +static void +uf_lx_suspend(CsrSdioFunction *sdio_ctx) +{ + unifi_priv_t *priv = sdio_ctx->driverData; + unifi_suspend(priv); + + CsrSdioSuspendAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); +} + +static void +uf_lx_resume(CsrSdioFunction *sdio_ctx) +{ + unifi_priv_t *priv = sdio_ctx->driverData; + unifi_resume(priv); + + CsrSdioResumeAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); +} + +static int active_slot = MAX_UNIFI_DEVS; +static struct device *os_devices[MAX_UNIFI_DEVS]; + +void +uf_add_os_device(int bus_id, struct device *os_device) +{ + if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { + unifi_error(NULL, "uf_add_os_device: invalid device %d\n", + bus_id); + return; + } + + active_slot = bus_id; + os_devices[bus_id] = os_device; +} /* uf_add_os_device() */ + +void +uf_remove_os_device(int bus_id) +{ + if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { + unifi_error(NULL, "uf_remove_os_device: invalid device %d\n", + bus_id); + return; + } + + active_slot = bus_id; + os_devices[bus_id] = NULL; +} /* uf_remove_os_device() */ + +static void +uf_sdio_inserted(CsrSdioFunction *sdio_ctx) +{ + unifi_priv_t *priv; + + unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n", + sdio_ctx, active_slot, os_devices[active_slot]); + + priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]); + if (priv == NULL) { + CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE); + return; + } + + sdio_ctx->driverData = priv; + + CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); +} /* uf_sdio_inserted() */ + + +static void +uf_sdio_removed(CsrSdioFunction *sdio_ctx) +{ + unregister_unifi_sdio(active_slot); + CsrSdioRemovedAcknowledge(sdio_ctx); +} /* uf_sdio_removed() */ + + +static void +uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx) +{ + unifi_priv_t *priv = sdio_ctx->driverData; + + unifi_sdio_interrupt_handler(priv->card); +} /* uf_sdio_dsr_handler() */ + +/* + * --------------------------------------------------------------------------- + * uf_sdio_int_handler + * + * Interrupt callback function for SDIO interrupts. + * This is called in kernel context (i.e. not interrupt context). + * We retrieve the unifi context pointer and call the main UniFi + * interrupt handler. + * + * Arguments: + * fdev SDIO context pointer + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static CsrSdioInterruptDsrCallback +uf_sdio_int_handler(CsrSdioFunction *sdio_ctx) +{ + return uf_sdio_dsr_handler; +} /* uf_sdio_int_handler() */ + + + + +static CsrSdioFunctionId unifi_ids[] = +{ + { + .manfId = SDIO_MANF_ID_CSR, + .cardId = SDIO_CARD_ID_UNIFI_3, + .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3, + .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, + }, + { + .manfId = SDIO_MANF_ID_CSR, + .cardId = SDIO_CARD_ID_UNIFI_4, + .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4, + .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, + } +}; + + +/* + * Structure to register with the glue layer. + */ +static CsrSdioFunctionDriver unifi_sdioFunction_drv = +{ + .inserted = uf_sdio_inserted, + .removed = uf_sdio_removed, + .intr = uf_sdio_int_handler, + .suspend = uf_lx_suspend, + .resume = uf_lx_resume, + + .ids = unifi_ids, + .idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0]) +}; + + +/* + * --------------------------------------------------------------------------- + * uf_sdio_load + * uf_sdio_unload + * + * These functions are called from the main module load and unload + * functions. They perform the appropriate operations for the monolithic + * driver. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +int __init +uf_sdio_load(void) +{ + CsrResult csrResult; + + csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult); + return -EIO; + } + + return 0; +} /* uf_sdio_load() */ + + + +void __exit +uf_sdio_unload(void) +{ + CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv); +} /* uf_sdio_unload() */ + diff --git a/drivers/staging/csr/mlme.c b/drivers/staging/csr/mlme.c new file mode 100644 index 000000000000..790d5d77375f --- /dev/null +++ b/drivers/staging/csr/mlme.c @@ -0,0 +1,441 @@ +/* + * --------------------------------------------------------------------------- + * FILE: mlme.c + * + * PURPOSE: + * This file provides functions to send MLME requests to the UniFi. + * + * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" + + +/* The additional time taken by the UniFi to do a scan per channel */ +#define SCAN_STARTUP_TIME 300 /* in millisecs */ + + +/* + * --------------------------------------------------------------------------- + * unifi_mlme_wait_for_reply + * + * Wait for a reply after sending a signal. + * + * Arguments: + * priv Pointer to device private context struct + * ul_client Pointer to linux client + * sig_reply_id ID of the expected reply (defined in sigs.h). + * timeout timeout in ms + * + * Returns: + * 0 on success, -ve POSIX code on error. + * + * Notes: + * This function waits for a specific (sig_reply_id) signal from UniFi. + * It also match the sequence number of the received (cfm) signal, with + * the latest sequence number of the signal (req) we have sent. + * These two number match be equal. + * Should only be used for waiting xxx.cfm signals and only after + * we have sent the matching xxx.req signal to UniFi. + * If no response is received within the expected time (timeout), we assume + * that the UniFi is busy and return an error. + * If the wait is aborted by a kernel signal arriving, we stop waiting. + * If a response from UniFi is not what we expected, we discard it and + * wait again. This could be a response from an aborted request. If we + * see several bad responses we assume we have lost synchronisation with + * UniFi. + * --------------------------------------------------------------------------- + */ +static int +unifi_mlme_wait_for_reply(unifi_priv_t *priv, ul_client_t *pcli, int sig_reply_id, int timeout) +{ + int retries = 0; + long r; + long t = timeout; + unsigned int sent_seq_no; + + /* Convert t in ms to jiffies */ + t = msecs_to_jiffies(t); + + do { + /* Wait for the confirm or timeout. */ + r = wait_event_interruptible_timeout(pcli->udi_wq, + (pcli->wake_up_wq_id) || (priv->io_aborted == 1), + t); + /* Check for general i/o error */ + if (priv->io_aborted) { + unifi_error(priv, "MLME operation aborted\n"); + return -EIO; + } + + /* + * If r=0 the request has timed-out. + * If r>0 the request has completed successfully. + * If r=-ERESTARTSYS an event (kill signal) has interrupted the wait_event. + */ + if ((r == 0) && (pcli->wake_up_wq_id == 0)) { + unifi_error(priv, "mlme_wait: timed-out waiting for 0x%.4X, after %lu msec.\n", + sig_reply_id, jiffies_to_msecs(t)); + pcli->wake_up_wq_id = 0; + return -ETIMEDOUT; + } else if (r == -ERESTARTSYS) { + unifi_error(priv, "mlme_wait: waiting for 0x%.4X was aborted.\n", sig_reply_id); + pcli->wake_up_wq_id = 0; + return -EINTR; + } else { + /* Get the sequence number of the signal that we previously set. */ + if (pcli->seq_no != 0) { + sent_seq_no = pcli->seq_no - 1; + } else { + sent_seq_no = 0x0F; + } + + unifi_trace(priv, UDBG5, "Received 0x%.4X, seq: (r:%d, s:%d)\n", + pcli->wake_up_wq_id, + pcli->wake_seq_no, sent_seq_no); + + /* The two sequence ids must match. */ + if (pcli->wake_seq_no == sent_seq_no) { + /* and the signal ids must match. */ + if (sig_reply_id == pcli->wake_up_wq_id) { + /* Found the expected signal */ + break; + } else { + /* This should never happen ... */ + unifi_error(priv, "mlme_wait: mismatching signal id (0x%.4X - exp 0x%.4X) (seq %d)\n", + pcli->wake_up_wq_id, + sig_reply_id, + pcli->wake_seq_no); + pcli->wake_up_wq_id = 0; + return -EIO; + } + } + /* Wait for the next signal. */ + pcli->wake_up_wq_id = 0; + + retries ++; + if (retries >= 3) { + unifi_error(priv, "mlme_wait: confirm wait retries exhausted (0x%.4X - exp 0x%.4X)\n", + pcli->wake_up_wq_id, + sig_reply_id); + pcli->wake_up_wq_id = 0; + return -EIO; + } + } + } while (1); + + pcli->wake_up_wq_id = 0; + + return 0; +} /* unifi_mlme_wait_for_reply() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_mlme_blocking_request + * + * Send a MLME request signal to UniFi. + * + * Arguments: + * priv Pointer to device private context struct + * pcli Pointer to context of calling process + * sig Pointer to the signal to send + * data_ptrs Pointer to the bulk data of the signal + * timeout The request's timeout. + * + * Returns: + * 0 on success, 802.11 result code on error. + * --------------------------------------------------------------------------- + */ +int +unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli, + CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs, + int timeout) +{ + int r; + + func_enter(); + + if (sig->SignalPrimitiveHeader.SignalId == 0) { + unifi_error(priv, "unifi_mlme_blocking_request: Invalid Signal Id (0x%x)\n", + sig->SignalPrimitiveHeader.SignalId); + return -EINVAL; + } + + down(&priv->mlme_blocking_mutex); + + sig->SignalPrimitiveHeader.ReceiverProcessId = 0; + sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id | pcli->seq_no; + + unifi_trace(priv, UDBG2, "Send client=%d, S:0x%04X, sig 0x%.4X\n", + pcli->client_id, + sig->SignalPrimitiveHeader.SenderProcessId, + sig->SignalPrimitiveHeader.SignalId); + /* Send the signal to UniFi */ + r = ul_send_signal_unpacked(priv, sig, data_ptrs); + if (r) { + up(&priv->mlme_blocking_mutex); + unifi_error(priv, "Error queueing MLME REQUEST signal\n"); + return r; + } + + unifi_trace(priv, UDBG5, "Send 0x%.4X, seq = %d\n", + sig->SignalPrimitiveHeader.SignalId, pcli->seq_no); + + /* + * Advance the sequence number of the last sent signal, only + * if the signal has been successfully set. + */ + pcli->seq_no++; + if (pcli->seq_no > 0x0F) { + pcli->seq_no = 0; + } + + r = unifi_mlme_wait_for_reply(priv, pcli, (sig->SignalPrimitiveHeader.SignalId + 1), timeout); + up(&priv->mlme_blocking_mutex); + + if (r) { + unifi_error(priv, "Error waiting for MLME CONFIRM signal\n"); + return r; + } + + func_exit(); + return 0; +} /* unifi_mlme_blocking_request() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_mlme_copy_reply_and_wakeup_client + * + * Copy the reply signal from UniFi to the client's structure + * and wake up the waiting client. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli, + CSR_SIGNAL *signal, int signal_len, + const bulk_data_param_t *bulkdata) +{ + int i; + + /* Copy the signal to the reply */ + memcpy(pcli->reply_signal, signal, signal_len); + + /* Get the sequence number of the signal that woke us up. */ + pcli->wake_seq_no = pcli->reply_signal->SignalPrimitiveHeader.ReceiverProcessId & 0x0F; + + /* Append any bulk data */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length > 0) { + if (bulkdata->d[i].os_data_ptr) { + memcpy(pcli->reply_bulkdata[i]->ptr, bulkdata->d[i].os_data_ptr, bulkdata->d[i].data_length); + pcli->reply_bulkdata[i]->length = bulkdata->d[i].data_length; + } else { + pcli->reply_bulkdata[i]->length = 0; + } + } + } + + /* Wake the requesting MLME function. */ + pcli->wake_up_wq_id = pcli->reply_signal->SignalPrimitiveHeader.SignalId; + wake_up_interruptible(&pcli->udi_wq); + +} /* unifi_mlme_copy_reply_and_wakeup_client() */ + + +/* + * --------------------------------------------------------------------------- + * uf_abort_mlme + * + * Abort any MLME operation in progress. + * This is used in the error recovery mechanism. + * + * Arguments: + * priv Pointer to driver context. + * + * Returns: + * 0 on success. + * --------------------------------------------------------------------------- + */ +int +uf_abort_mlme(unifi_priv_t *priv) +{ + ul_client_t *ul_cli; + + /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */ + priv->io_aborted = 1; + + ul_cli = priv->netdev_client; + if (ul_cli) { + wake_up_interruptible(&ul_cli->udi_wq); + } + + ul_cli = priv->wext_client; + if (ul_cli) { + wake_up_interruptible(&ul_cli->udi_wq); + } + + return 0; +} /* uf_abort_mlme() */ + + + +/* + * --------------------------------------------------------------------------- + * + * Human-readable decoding of Reason and Result codes. + * + * --------------------------------------------------------------------------- + */ + +struct mlme_code { + const char *name; + int id; +}; + +static const struct mlme_code Result_codes[] = { + { "Success", 0x0000 }, + { "Unspecified Failure", 0x0001 }, + /* (Reserved) 0x0002 - 0x0009 */ + { "Refused Capabilities Mismatch", 0x000A }, + /* (Reserved) 0x000B */ + { "Refused External Reason", 0x000C }, + /* (Reserved) 0x000D - 0x0010 */ + { "Refused AP Out Of Memory", 0x0011 }, + { "Refused Basic Rates Mismatch", 0x0012 }, + /* (Reserved) 0x0013 - 0x001F */ + { "Failure", 0x0020 }, + /* (Reserved) 0x0021 - 0x0024 */ + { "Refused Reason Unspecified", 0x0025 }, + { "Invalid Parameters", 0x0026 }, + { "Rejected With Suggested Changes", 0x0027 }, + /* (Reserved) 0x0028 - 0x002E */ + { "Rejected For Delay Period", 0x002F }, + { "Not Allowed", 0x0030 }, + { "Not Present", 0x0031 }, + { "Not QSTA", 0x0032 }, + /* (Reserved) 0x0033 - 0x7FFF */ + { "Timeout", 0x8000 }, + { "Too Many Simultaneous Requests", 0x8001 }, + { "BSS Already Started Or Joined", 0x8002 }, + { "Not Supported", 0x8003 }, + { "Transmission Failure", 0x8004 }, + { "Refused Not Authenticated", 0x8005 }, + { "Reset Required Before Start", 0x8006 }, + { "LM Info Unavailable", 0x8007 }, + { NULL, -1 } +}; + +static const struct mlme_code Reason_codes[] = { + /* (Reserved) 0x0000 */ + { "Unspecified Reason", 0x0001 }, + { "Authentication Not Valid", 0x0002 }, + { "Deauthenticated Leave BSS", 0x0003 }, + { "Disassociated Inactivity", 0x0004 }, + { "AP Overload", 0x0005 }, + { "Class2 Frame Error", 0x0006 }, + { "Class3 Frame Error", 0x0007 }, + { "Disassociated Leave BSS", 0x0008 }, + { "Association Not Authenticated", 0x0009 }, + { "Disassociated Power Capability", 0x000A }, + { "Disassociated Supported Channels", 0x000B }, + /* (Reserved) 0x000C */ + { "Invalid Information Element", 0x000D }, + { "Michael MIC Failure", 0x000E }, + { "Fourway Handshake Timeout", 0x000F }, + { "Group Key Update Timeout", 0x0010 }, + { "Handshake Element Different", 0x0011 }, + { "Invalid Group Cipher", 0x0012 }, + { "Invalid Pairwise Cipher", 0x0013 }, + { "Invalid AKMP", 0x0014 }, + { "Unsupported RSN IE Version", 0x0015 }, + { "Invalid RSN IE Capabilities", 0x0016 }, + { "Dot1X Auth Failed", 0x0017 }, + { "Cipher Rejected By Policy", 0x0018 }, + /* (Reserved) 0x0019 - 0x001F */ + { "QoS Unspecified Reason", 0x0020 }, + { "QoS Insufficient Bandwidth", 0x0021 }, + { "QoS Excessive Not Ack", 0x0022 }, + { "QoS TXOP Limit Exceeded", 0x0023 }, + { "QSTA Leaving", 0x0024 }, + { "End TS, End DLS, End BA", 0x0025 }, + { "Unknown TS, Unknown DLS, Unknown BA", 0x0026 }, + { "Timeout", 0x0027 }, + /* (Reserved) 0x0028 - 0x002C */ + { "STAKey Mismatch", 0x002D }, + { NULL, -1 } +}; + + +static const char * +lookup_something(const struct mlme_code *n, int id) +{ + for (; n->name; n++) { + if (n->id == id) { + return n->name; + } + } + + /* not found */ + return NULL; +} /* lookup_something() */ + + +const char * +lookup_result_code(int result) +{ + static char fallback[16]; + const char *str; + + str = lookup_something(Result_codes, result); + + if (str == NULL) { + snprintf(fallback, 16, "%d", result); + str = fallback; + } + + return str; +} /* lookup_result_code() */ + + +/* + * --------------------------------------------------------------------------- + * lookup_reason + * + * Return a description string for a WiFi MLME ReasonCode. + * + * Arguments: + * reason The ReasonCode to interpret. + * + * Returns: + * Pointer to description string. + * --------------------------------------------------------------------------- + */ +const char * +lookup_reason_code(int reason) +{ + static char fallback[16]; + const char *str; + + str = lookup_something(Reason_codes, reason); + + if (str == NULL) { + snprintf(fallback, 16, "%d", reason); + str = fallback; + } + + return str; +} /* lookup_reason_code() */ + diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c new file mode 100644 index 000000000000..7648d2bbad43 --- /dev/null +++ b/drivers/staging/csr/monitor.c @@ -0,0 +1,458 @@ +/* + * --------------------------------------------------------------------------- + * FILE: monitor.c + * + * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + +#include "unifi_priv.h" + +#ifdef UNIFI_SNIFF_ARPHRD + + +#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP) +#include +#endif + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW ETH_P_ALL +#endif + + + +/* + * --------------------------------------------------------------------------- + * uf_start_sniff + * + * Start UniFi capture in SNIFF mode, i.e capture everything it hears. + * + * Arguments: + * priv Pointer to device private context struct + * + * Returns: + * 0 on success or kernel error code + * --------------------------------------------------------------------------- + */ +int +uf_start_sniff(unifi_priv_t *priv) +{ + ul_client_t *pcli = priv->wext_client; + CSR_SIGNAL signal; + CSR_MLME_SNIFFJOIN_REQUEST *req = &signal.u.MlmeSniffjoinRequest; + int timeout = 1000; + int r; + + req->Ifindex = priv->if_index; + req->Channel = priv->wext_conf.channel; + req->ChannelStartingFactor = 0; + +#if 0 + printk("SniffJoin: Ifindex=%d, Channel=%d, ChannelStartingFactor=%d\n", + req->Ifindex, + req->Channel, + req->ChannelStartingFactor); +#endif + + signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SNIFFJOIN_REQUEST_ID; + + r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout); + if (r < 0) { + unifi_error(priv, "failed to send SNIFFJOIN request, error %d\n", r); + return r; + } + + r = pcli->reply_signal->u.MlmeSniffjoinConfirm.Resultcode; + if (r) { + unifi_notice(priv, "SNIFFJOIN request was rejected with result 0x%X (%s)\n", + r, lookup_result_code(r)); + return -EIO; + } + + return 0; +} /* uf_start_sniff() */ + + + +/* + * --------------------------------------------------------------------------- + * netrx_radiotap + * + * Reformat a UniFi SNIFFDATA signal into a radiotap packet. + * + * Arguments: + * priv OS private context pointer. + * ind Pointer to a MA_UNITDATA_INDICATION or + * DS_UNITDATA_INDICATION indication structure. + * + * Notes: + * Radiotap header values are all little-endian, UniFi signals will have + * been converted to host-endian. + * --------------------------------------------------------------------------- + */ +#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP) +static void +netrx_radiotap(unifi_priv_t *priv, + const CSR_MA_SNIFFDATA_INDICATION *ind, + struct sk_buff *skb_orig) +{ + struct net_device *dev = priv->netdev; + struct sk_buff *skb = NULL; + unsigned char *ptr; + unsigned char *base; + int ind_data_len = skb_orig->len - 2 - ETH_HLEN; + struct unifi_rx_radiotap_header { + struct ieee80211_radiotap_header rt_hdr; + /* IEEE80211_RADIOTAP_TSFT */ + u64 rt_tsft; + /* IEEE80211_RADIOTAP_FLAGS */ + u8 rt_flags; + /* IEEE80211_RADIOTAP_RATE */ + u8 rt_rate; + /* IEEE80211_RADIOTAP_CHANNEL */ + u16 rt_chan; + u16 rt_chan_flags; + /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ + u8 rt_dbm_antsignal; + /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ + u8 rt_dbm_antnoise; + /* IEEE80211_RADIOTAP_ANTENNA */ + u8 rt_antenna; + + /* pad to 4-byte boundary */ + u8 pad[3]; + } __attribute__((__packed__)); + + struct unifi_rx_radiotap_header *unifi_rt; + int signal, noise, snr; + + func_enter(); + + if (ind_data_len <= 0) { + unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n"); + return; + } + + /* + * Allocate a SKB for the received data packet, including radiotap + * header. + */ + skb = dev_alloc_skb(ind_data_len + sizeof(struct unifi_rx_radiotap_header) + 4); + if (! skb) { + unifi_error(priv, "alloc_skb failed.\n"); + priv->stats.rx_errors++; + return; + } + + base = skb->data; + + /* Reserve the radiotap header at the front of skb */ + unifi_rt = (struct unifi_rx_radiotap_header *) + skb_put(skb, sizeof(struct unifi_rx_radiotap_header)); + + /* Copy in the 802.11 frame */ + ptr = skb_put(skb, ind_data_len); + memcpy(ptr, skb_orig->data, ind_data_len); + + unifi_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; + unifi_rt->rt_hdr.it_pad = 0; /* always good to zero */ + unifi_rt->rt_hdr.it_len = sizeof(struct unifi_rx_radiotap_header); + + /* Big bitfield of all the fields we provide in radiotap */ + unifi_rt->rt_hdr.it_present = 0 + | (1 << IEEE80211_RADIOTAP_TSFT) + | (1 << IEEE80211_RADIOTAP_FLAGS) + | (1 << IEEE80211_RADIOTAP_RATE) + | (1 << IEEE80211_RADIOTAP_CHANNEL) + | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) + | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) + | (1 << IEEE80211_RADIOTAP_ANTENNA) + ; + + + /* No flags to set */ + unifi_rt->rt_tsft = (((u64)ind->Timestamp.x[7]) | (((u64)ind->Timestamp.x[6]) << 8) | + (((u64)ind->Timestamp.x[5]) << 16) | (((u64)ind->Timestamp.x[4]) << 24) | + (((u64)ind->Timestamp.x[3]) << 32) | (((u64)ind->Timestamp.x[2]) << 40) | + (((u64)ind->Timestamp.x[1]) << 48) | (((u64)ind->Timestamp.x[0]) << 56)); + + unifi_rt->rt_flags = 0; + + unifi_rt->rt_rate = ind->Rate; + + unifi_rt->rt_chan = cpu_to_le16(ieee80211chan2mhz(priv->wext_conf.channel)); + unifi_rt->rt_chan_flags = 0; + + /* Convert signal to dBm */ + signal = (s16)unifi2host_16(ind->Rssi); /* in dBm */ + snr = (s16)unifi2host_16(ind->Snr); /* in dB */ + noise = signal - snr; + + unifi_rt->rt_dbm_antsignal = signal; + unifi_rt->rt_dbm_antnoise = noise; + + unifi_rt->rt_antenna = ind->AntennaId; + + +#if 0 + printk("skb datalen=%d\n", skb->len); + dump(skb->data, 48); +#endif + + skb->dev = dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + skb->mac_header = skb->data; +#else + skb->mac.raw = skb->data; +#endif + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = __constant_htons(ETH_P_80211_RAW); + memset(skb->cb, 0, sizeof(skb->cb)); + + /* Pass up to Linux network stack */ + netif_rx_ni(skb); + + dev->last_rx = jiffies; + + /* Bump the rx stats */ + priv->stats.rx_packets++; + priv->stats.rx_bytes += ind_data_len; + + func_exit(); +} /* netrx_radiotap() */ +#endif /* RADIOTAP */ + + +/* + * --------------------------------------------------------------------------- + * netrx_prism + * + * Reformat a UniFi SNIFFDATA signal into a Prism format sniff packet. + * + * Arguments: + * priv OS private context pointer. + * ind Pointer to a MA_UNITDATA_INDICATION or + * DS_UNITDATA_INDICATION indication structure. + * + * Notes: + * Radiotap header values are all little-endian, UniFi signals will have + * been converted to host-endian. + * --------------------------------------------------------------------------- + */ +#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_PRISM) +static void +netrx_prism(unifi_priv_t *priv, + const CSR_MA_SNIFFDATA_INDICATION *ind, + struct sk_buff *skb_orig) +{ + struct net_device *dev = priv->netdev; + struct sk_buff *skb = NULL; + unsigned char *ptr; + unsigned char *base; + int ind_data_len = skb_orig->len - 2 - ETH_HLEN; +#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000 +#define WLANCAP_MAGIC_COOKIE_V1 0x80211001 +#define WLANCAP_MAGIC_COOKIE_V2 0x80211002 + struct avs_header_v1 { + uint32 version; + uint32 length; + uint64 mactime; + uint64 hosttime; + uint32 phytype; + uint32 channel; + uint32 datarate; + uint32 antenna; + uint32 priority; + uint32 ssi_type; + int32 ssi_signal; + int32 ssi_noise; + uint32 preamble; + uint32 encoding; + } *avs; + int signal, noise, snr; + + func_enter(); + + if (ind_data_len <= 0) { + unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n"); + return; + } + +#if 0 + printk("MA-SINFFDATA.ind: DataLen=%d bytes, TSF %02X %02X %02X %02X %02X %02X %02X %02X, Rate=%d, Antenna=%d\n", + ind->Data.DataLength, + ind->Timestamp.x[0], + ind->Timestamp.x[1], + ind->Timestamp.x[2], + ind->Timestamp.x[3], + ind->Timestamp.x[4], + ind->Timestamp.x[5], + ind->Timestamp.x[6], + ind->Timestamp.x[7], + ind->Rate, + ind->Antenna); + + printk("payload, len %d\n", length); + dump((unsigned char *)payload, 32); +#endif + + /* + * Allocate a SKB for the received data packet, including radiotap + * header. + */ + skb = dev_alloc_skb(ind_data_len + sizeof(struct avs_header_v1) + 4); + if (! skb) { + unifi_error(priv, "alloc_skb failed.\n"); + priv->stats.rx_errors++; + return; + } + + base = skb->data; + + /* Reserve the radiotap header at the front of skb */ + avs = (struct avs_header_v1 *)skb_put(skb, sizeof(struct avs_header_v1)); + + /* Copy in the 802.11 frame */ + ptr = skb_put(skb, ind_data_len); + memcpy(ptr, skb_orig->data, ind_data_len); + + /* Convert signal to dBm */ + signal = 0x10000 - ((s16)unifi2host_16(ind->Rssi)); /* in dBm */ + snr = (s16)unifi2host_16(ind->Snr); /* in dB */ + noise = signal - snr; + + avs->version = htonl(WLANCAP_MAGIC_COOKIE_V1); + avs->length = htonl(sizeof(struct avs_header_v1)); + avs->mactime = __cpu_to_be64(ind->Timestamp); + avs->hosttime = __cpu_to_be64(jiffies); + avs->phytype = htonl(9); /* dss_ofdm_dot11_g */ + avs->channel = htonl(priv->wext_conf.channel); + avs->datarate = htonl(ind->Rate * 5); + avs->antenna = htonl(ind->Antenna); + avs->priority = htonl(0); /* unknown */ + avs->ssi_type = htonl(2); /* dBm */ + avs->ssi_signal = htonl(signal); + avs->ssi_noise = htonl(noise); + avs->preamble = htonl(0); /* unknown */ + avs->encoding = htonl(0); /* unknown */ + + +#if 0 + printk("skb datalen=%d\n", skb->len); + dump(skb->data, 48); +#endif + + skb->dev = dev; + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = __constant_htons(ETH_P_80211_RAW); + memset(skb->cb, 0, sizeof(skb->cb)); + + /* Pass up to Linux network stack */ + netif_rx_ni(skb); + + dev->last_rx = jiffies; + + /* Bump the rx stats */ + priv->stats.rx_packets++; + priv->stats.rx_bytes += ind_data_len; + + func_exit(); +} /* netrx_prism() */ +#endif /* PRISM */ + + +/* + * --------------------------------------------------------------------------- + * ma_sniffdata_ind + * + * Reformat a UniFi SNIFFDATA signal into a network + * + * Arguments: + * ospriv OS private context pointer. + * ind Pointer to a MA_UNITDATA_INDICATION or + * DS_UNITDATA_INDICATION indication structure. + * bulkdata Pointer to a bulk data structure, describing + * the data received. + * + * Notes: + * Radiotap header values are all little-endian, UniFi signals will have + * been converted to host-endian. + * --------------------------------------------------------------------------- + */ +void +ma_sniffdata_ind(void *ospriv, + const CSR_MA_SNIFFDATA_INDICATION *ind, + const bulk_data_param_t *bulkdata) +{ + unifi_priv_t *priv = ospriv; + struct net_device *dev = priv->netdev; + struct sk_buff *skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; + + func_enter(); + + if (bulkdata->d[0].data_length == 0) { + unifi_warning(priv, "rx: MA-SNIFFDATA indication with zero bulk data\n"); + func_exit(); + return; + } + + skb->len = bulkdata->d[0].data_length; +#if 0 + printk("MA-SNIFFDATA.ind: DataLen=%d bytes, TSF %02X %02X %02X %02X %02X %02X %02X %02X, Rate=%d, Antenna=%d\n", + ind->Data.DataLength, + ind->Timestamp.x[0], + ind->Timestamp.x[1], + ind->Timestamp.x[2], + ind->Timestamp.x[3], + ind->Timestamp.x[4], + ind->Timestamp.x[5], + ind->Timestamp.x[6], + ind->Timestamp.x[7], + ind->Rate, + ind->AntennaId); + + printk("payload, len %lu\n", bulkdata->d[0].data_length); + if (bulkdata->d[0].os_data_ptr && (bulkdata->d[0].data_length >= 32)) { + dump((unsigned char *)bulkdata->d[0].os_data_ptr, 32); + } +#endif + + /* We only process data packets if the interface is open */ + if (unlikely(!netif_running(dev))) { + priv->stats.rx_dropped++; + priv->wext_conf.wireless_stats.discard.misc++; +#if 0 + printk("Dropping packet while interface is not up.\n"); +#endif + dev_kfree_skb(skb); + return; + } + + if (ind->ReceptionStatus) { + priv->stats.rx_dropped++; + priv->wext_conf.wireless_stats.discard.misc++; + printk(KERN_INFO "unifi: Dropping corrupt sniff packet\n"); + dev_kfree_skb(skb); + return; + } + +#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_PRISM) + netrx_prism(priv, ind, skb); +#endif /* PRISM */ + +#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP) + netrx_radiotap(priv, ind, skb); +#endif /* RADIOTAP */ + + dev_kfree_skb(skb); + +} /* ma_sniffdata_ind() */ + + +#endif /* UNIFI_SNIFF_ARPHRD */ + diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c new file mode 100644 index 000000000000..b0335f6fff4e --- /dev/null +++ b/drivers/staging/csr/netdev.c @@ -0,0 +1,3902 @@ +/* + * --------------------------------------------------------------------------- + * FILE: netdev.c + * + * PURPOSE: + * This file provides the upper edge interface to the linux netdevice + * and wireless extensions. + * It is part of the porting exercise. + * + * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + + +/* + * Porting Notes: + * This file implements the data plane of the UniFi linux driver. + * + * All the Tx packets are passed to the HIP core lib, using the + * unifi_send_signal() API. For EAPOL packets use the MLME-EAPOL.req + * signal, for all other use the MLME-UNITDATA.req. The unifi_send_signal() + * expects the wire-formatted (packed) signal. For convenience, in the OS + * layer we only use the native (unpacked) signal structures. The HIP core lib + * provides the write_pack() helper function to convert to the packed signal. + * The packet is stored in the bulk data of the signal. We do not need to + * allocate new memory to store the packet, because unifi_net_data_malloc() + * is implemented to return a skb, which is the format of packet in Linux. + * The HIP core lib frees the bulk data buffers, so we do not need to do + * this in the OS layer. + * + * All the Rx packets are MLME-UNITDATA.ind signals, passed by the HIP core lib + * in unifi_receive_event(). We do not need to allocate an skb and copy the + * received packet because the HIP core lib has stored in memory allocated by + * unifi_net_data_malloc(). Also, we can perform the 802.11 to Ethernet + * translation in-place because we allocate the extra memory allocated in + * unifi_net_data_malloc(). + * + * If possible, the porting exercise should appropriately implement + * unifi_net_data_malloc() and unifi_net_data_free() to save copies between + * network and driver buffers. + */ + +#include +#include +#include +#include + +#include +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "unifi_priv.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) +#include +#endif +#include + + +/* ALLOW_Q_PAUSE: Pre 2.6.28 kernels do not support multiple driver queues (required for QoS). + * In order to support QoS in these kernels, multiple queues are implemented in the driver. But since + * there is only a single queue in the kernel (leading to multiple queues in the driver) there is no possibility + * of stopping a particular queue in the kernel. Stopping the single kernel queue leads to undesirable starvation + * of driver queues. One of the proposals is to not stop the kernel queue but to prevent dequeuing from the + * 'stopped' driver queue. Allow q pause is an experimental implementation of this scheme for pre 2.6.28 kernels. + * When NOT defined, queues are paused locally in the driver and packets are dequeued for transmission only from the + * unpaused queues. When Allow q pause is defined the kernel queue is stopped whenever any driver queue is paused. + */ +#define ALLOW_Q_PAUSE + +#define ieee2host16(n) __le16_to_cpu(n) +#define ieee2host32(n) __le32_to_cpu(n) +#define host2ieee16(n) __cpu_to_le16(n) +#define host2ieee32(n) __cpu_to_le32(n) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) +#ifdef UNIFI_NET_NAME +#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ + do { \ + static char name[8]; \ + sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \ + _dev = alloc_netdev_mq(_size, name, _setup, _num_of_queues); \ + } while (0); +#else +#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ + do { \ + _dev = alloc_etherdev_mq(_size, _num_of_queues); \ + } while (0); +#endif /* UNIFI_NET_NAME */ +#else +#ifdef UNIFI_NET_NAME +#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ + do { \ + static char name[8]; \ + sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \ + _dev = alloc_netdev(_size, name, _setup); \ + } while (0); +#else +#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \ + do { \ + _dev = alloc_etherdev(_size); \ + } while (0); +#endif /* UNIFI_NET_NAME */ +#endif /* LINUX_VERSION_CODE */ + + +/* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */ +#ifdef CSR_SUPPORT_WEXT +extern struct iw_handler_def unifi_iw_handler_def; +#endif /* CSR_SUPPORT_WEXT */ +static void check_ba_frame_age_timeout( unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session); +static void process_ba_frame(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session, + frame_desc_struct *frame_desc); +static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv); +static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata); +static void process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata); +static int uf_net_open(struct net_device *dev); +static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int uf_net_stop(struct net_device *dev); +static struct net_device_stats *uf_net_get_stats(struct net_device *dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) +static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb); +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev); +#else +static int uf_net_xmit(struct sk_buff *skb, struct net_device *dev); +#ifndef NETDEV_TX_OK +#define NETDEV_TX_OK 0 +#endif +#ifndef NETDEV_TX_BUSY +#define NETDEV_TX_BUSY 1 +#endif +#endif +static void uf_set_multicast_list(struct net_device *dev); + + +typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority); + +#ifdef CONFIG_NET_SCHED +/* + * Queueing Discipline Interface + * Only used if kernel is configured with CONFIG_NET_SCHED + */ + +/* + * The driver uses the qdisc interface to buffer and control all + * outgoing traffic. We create a root qdisc, register our qdisc operations + * and later we create two subsiduary pfifo queues for the uncontrolled + * and controlled ports. + * + * The network stack delivers all outgoing packets in our enqueue handler. + * There, we classify the packet and decide whether to store it or drop it + * (if the controlled port state is set to "discard"). + * If the packet is enqueued, the network stack call our dequeue handler. + * There, we decide whether we can send the packet, delay it or drop it + * (the controlled port configuration might have changed meanwhile). + * If a packet is dequeued, then the network stack calls our hard_start_xmit + * handler where finally we send the packet. + * + * If the hard_start_xmit handler fails to send the packet, we return + * NETDEV_TX_BUSY and the network stack call our requeue handler where + * we put the packet back in the same queue in came from. + * + */ + +struct uf_sched_data +{ + /* Traffic Classifier TBD */ + struct tcf_proto *filter_list; + /* Our two queues */ + struct Qdisc *queues[UNIFI_TRAFFIC_Q_MAX]; +}; + +struct uf_tx_packet_data { + /* Queue the packet is stored in */ + unifi_TrafficQueue queue; + /* QoS Priority determined when enqueing packet */ + CSR_PRIORITY priority; + /* Debug */ + unsigned long host_tag; +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd); +static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd); +static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd); +static void uf_qdiscop_reset(struct Qdisc* qd); +static void uf_qdiscop_destroy(struct Qdisc* qd); +static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt); +static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt); +#else +static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt); +static int uf_qdiscop_init(struct Qdisc *qd, struct rtattr *opt); +#endif +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +/* queueing discipline operations */ +static struct Qdisc_ops uf_qdisc_ops = +{ + .next = NULL, + .cl_ops = NULL, + .id = "UniFi Qdisc", + .priv_size = sizeof(struct uf_sched_data), + + .enqueue = uf_qdiscop_enqueue, + .dequeue = uf_qdiscop_dequeue, + .requeue = uf_qdiscop_requeue, + .drop = NULL, /* drop not needed since we are always the root qdisc */ + + .init = uf_qdiscop_init, + .reset = uf_qdiscop_reset, + .destroy = uf_qdiscop_destroy, + .change = uf_qdiscop_tune, + + .dump = uf_qdiscop_dump, +}; +#endif /* LINUX_VERSION_CODE */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) +#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ + qdisc_create_dflt(dev, netdev_get_tx_queue(_dev, 0), _ops, _root) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ + qdisc_create_dflt(dev, _ops, _root) +#else +#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \ + qdisc_create_dflt(dev, _ops) +#endif /* LINUX_VERSION_CODE */ + +#endif /* CONFIG_NET_SCHED */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +static const struct net_device_ops uf_netdev_ops = +{ + .ndo_open = uf_net_open, + .ndo_stop = uf_net_stop, + .ndo_start_xmit = uf_net_xmit, + .ndo_do_ioctl = uf_net_ioctl, + .ndo_get_stats = uf_net_get_stats, /* called by /proc/net/dev */ + .ndo_set_rx_mode = uf_set_multicast_list, + .ndo_select_queue = uf_net_select_queue, +}; +#endif + +static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; +static u8 oui_8021h[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; + + +/* Callback for event logging to blocking clients */ +static void netdev_mlme_event_handler(ul_client_t *client, + const u8 *sig_packed, int sig_len, + const bulk_data_param_t *bulkdata, + int dir); + +#ifdef CSR_SUPPORT_WEXT +/* Declare netdev_notifier block which will contain the state change + * handler callback function + */ +static struct notifier_block uf_netdev_notifier; +#endif + +/* + * --------------------------------------------------------------------------- + * uf_alloc_netdevice + * + * Allocate memory for the net_device and device private structs + * for this interface. + * Fill in the fields, but don't register the interface yet. + * We need to configure the UniFi first. + * + * Arguments: + * sdio_dev Pointer to SDIO context handle to use for all + * SDIO ops. + * bus_id A small number indicating the SDIO card position on the + * bus. Typically this is the slot number, e.g. 0, 1 etc. + * Valid values are 0 to MAX_UNIFI_DEVS-1. + * + * Returns: + * Pointer to device private struct. + * + * Notes: + * The net_device and device private structs are allocated together + * and should be freed by freeing the net_device pointer. + * --------------------------------------------------------------------------- + */ +unifi_priv_t * +uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) +{ + struct net_device *dev; + unifi_priv_t *priv; + netInterface_priv_t *interfacePriv; +#ifdef CSR_SUPPORT_WEXT + int rc; +#endif + unsigned char i; /* loop index */ + + /* + * Allocate netdevice struct, assign name template and + * setup as an ethernet device. + * The net_device and private structs are zeroed. Ether_setup() then + * sets up ethernet handlers and values. + * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices, + * so use "eth*" (like other wireless extns drivers). + */ + UF_ALLOC_NETDEV(dev, sizeof(unifi_priv_t)+sizeof(netInterface_priv_t), "%d", ether_setup, UNIFI_TRAFFIC_Q_MAX); + + if (dev == NULL) { + return NULL; + } + + /* Set up back pointer from priv to netdev */ + interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + priv = (unifi_priv_t *)(interfacePriv + 1); + interfacePriv->privPtr = priv; + interfacePriv->InterfaceTag = 0; + + + /* Initialize all supported netdev interface to be NULL */ + for(i=0; inetdev[i] = NULL; + priv->interfacePriv[i] = NULL; + } + priv->netdev[0] = dev; + priv->interfacePriv[0] = interfacePriv; + + /* Setup / override net_device fields */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + dev->netdev_ops = &uf_netdev_ops; +#else + dev->open = uf_net_open; + dev->stop = uf_net_stop; + dev->hard_start_xmit = uf_net_xmit; + dev->do_ioctl = uf_net_ioctl; + + /* called by /proc/net/dev */ + dev->get_stats = uf_net_get_stats; + + dev->set_multicast_list = uf_set_multicast_list; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + dev->select_queue = uf_net_select_queue; +#endif +#endif + +#ifdef CSR_SUPPORT_WEXT + dev->wireless_handlers = &unifi_iw_handler_def; +#if IW_HANDLER_VERSION < 6 + dev->get_wireless_stats = unifi_get_wireless_stats; +#endif /* IW_HANDLER_VERSION */ +#endif /* CSR_SUPPORT_WEXT */ + + /* This gives us enough headroom to add the 802.11 header */ + dev->needed_headroom = 32; + + /* Use bus_id as instance number */ + priv->instance = bus_id; + /* Store SDIO pointer to pass in the core */ + priv->sdio = sdio_dev; + + sdio_dev->driverData = (void*)priv; + /* Consider UniFi to be uninitialised */ + priv->init_progress = UNIFI_INIT_NONE; + + priv->prev_queue = 0; + + /* + * Initialise the clients structure array. + * We do not need protection around ul_init_clients() because + * the character device can not be used until uf_alloc_netdevice() + * returns and Unifi_instances[bus_id]=priv is set, since unifi_open() + * will return -ENODEV. + */ + ul_init_clients(priv); + + /* + * Register a new ul client to send the multicast list signals. + * Note: priv->instance must be set before calling this. + */ + priv->netdev_client = ul_register_client(priv, + 0, + netdev_mlme_event_handler); + if (priv->netdev_client == NULL) { + unifi_error(priv, + "Failed to register a unifi client for background netdev processing\n"); + free_netdev(priv->netdev[0]); + return NULL; + } + unifi_trace(priv, UDBG2, "Netdev %p client (id:%d s:0x%X) is registered\n", + dev, priv->netdev_client->client_id, priv->netdev_client->sender_id); + + priv->sta_wmm_capabilities = 0; + + priv->wapi_multicast_filter = 0; + priv->wapi_unicast_filter = 0; + priv->wapi_unicast_queued_pkt_filter = 0; + + /* Enable all queues by default */ + interfacePriv->queueEnabled[0] = 1; + interfacePriv->queueEnabled[1] = 1; + interfacePriv->queueEnabled[2] = 1; + interfacePriv->queueEnabled[3] = 1; + +#ifdef CSR_SUPPORT_SME + priv->allPeerDozing = 0; +#endif + /* + * Initialise the OS private struct. + */ + /* + * Instead of deciding in advance to use 11bg or 11a, we could do a more + * clever scan on both radios. + */ + if (use_5g) { + priv->if_index = CSR_INDEX_5G; + unifi_info(priv, "Using the 802.11a radio\n"); + } else { + priv->if_index = CSR_INDEX_2G4; + } + + /* Initialise bh thread structure */ + priv->bh_thread.thread_task = NULL; + priv->bh_thread.block_thread = 1; + init_waitqueue_head(&priv->bh_thread.wakeup_q); + priv->bh_thread.wakeup_flag = 0; + sprintf(priv->bh_thread.name, "uf_bh_thread"); + + /* reset the connected state for the interface */ + interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */ + +#ifdef USE_DRIVER_LOCK +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) + sema_init(&priv->lock, 1); +#else + init_MUTEX(&priv->lock); +#endif +#endif /* USE_DRIVER_LOCK */ + + spin_lock_init(&priv->send_signal_lock); + + spin_lock_init(&priv->m4_lock); + spin_lock_init(&priv->ba_lock); + +#ifdef CSR_SUPPORT_SME + spin_lock_init(&priv->staRecord_lock); + spin_lock_init(&priv->tx_q_lock); +#endif + + /* Create the Traffic Analysis workqueue */ + priv->unifi_workqueue = create_singlethread_workqueue("unifi_workq"); + if (priv->unifi_workqueue == NULL) { + /* Deregister priv->netdev_client */ + ul_deregister_client(priv->netdev_client); + free_netdev(priv->netdev[0]); + return NULL; + } + +#ifdef CSR_SUPPORT_SME + /* Create the Multicast Addresses list work structure */ + INIT_WORK(&priv->multicast_list_task, uf_multicast_list_wq); + + /* Create m4 buffering work structure */ + INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +#ifdef CONFIG_NET_SCHED + /* Register the qdisc operations */ + register_qdisc(&uf_qdisc_ops); +#endif /* CONFIG_NET_SCHED */ +#endif /* LINUX_VERSION_CODE */ + + priv->ref_count = 1; + + + priv->amp_client = NULL; + priv->coredump_mode = 0; + priv->ptest_mode = 0; + priv->wol_suspend = FALSE; + INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list); + INIT_LIST_HEAD(&interfacePriv->rx_controlled_list); + sema_init(&priv->rx_q_sem, 1); + +#ifdef CSR_SUPPORT_WEXT + interfacePriv->netdev_callback_registered = FALSE; + interfacePriv->wait_netdev_change = FALSE; + /* Register callback for netdevice state changes */ + if ((rc = register_netdevice_notifier(&uf_netdev_notifier)) == 0) { + interfacePriv->netdev_callback_registered = TRUE; + } + else { + unifi_warning(priv, "Failed to register netdevice notifier : %d %p\n", rc, dev); + } +#endif /* CSR_SUPPORT_WEXT */ + + return priv; +} /* uf_alloc_netdevice() */ + +/* + *--------------------------------------------------------------------------- + * uf_alloc_netdevice_for_other_interfaces + * + * Allocate memory for the net_device and device private structs + * for this interface. + * Fill in the fields, but don't register the interface yet. + * We need to configure the UniFi first. + * + * Arguments: + * interfaceTag Interface number. + * sdio_dev Pointer to SDIO context handle to use for all + * SDIO ops. + * bus_id A small number indicating the SDIO card position on the + * bus. Typically this is the slot number, e.g. 0, 1 etc. + * Valid values are 0 to MAX_UNIFI_DEVS-1. + * + * Returns: + * Pointer to device private struct. + * + * Notes: + * The device private structure contains the interfaceTag and pointer to the unifi_priv + * structure created allocated by net_device od interface0. + * The net_device and device private structs are allocated together + * and should be freed by freeing the net_device pointer. + * --------------------------------------------------------------------------- + */ +CsrBool +uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, CsrUint16 interfaceTag) +{ + struct net_device *dev; + netInterface_priv_t *interfacePriv; + + /* + * Allocate netdevice struct, assign name template and + * setup as an ethernet device. + * The net_device and private structs are zeroed. Ether_setup() then + * sets up ethernet handlers and values. + * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices, + * so use "eth*" (like other wireless extns drivers). + */ + UF_ALLOC_NETDEV(dev, sizeof(netInterface_priv_t), "%d", ether_setup, 1); + if (dev == NULL) { + return FALSE; + } + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_alloc_netdevice_for_other_interfaces bad interfaceTag\n"); + return FALSE; + } + + /* Set up back pointer from priv to netdev */ + interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + interfacePriv->privPtr = priv; + interfacePriv->InterfaceTag = interfaceTag; + priv->netdev[interfaceTag] = dev; + priv->interfacePriv[interfacePriv->InterfaceTag] = interfacePriv; + + /* reset the connected state for the interface */ + interfacePriv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */ + INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list); + INIT_LIST_HEAD(&interfacePriv->rx_controlled_list); + + /* Setup / override net_device fields */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + dev->netdev_ops = &uf_netdev_ops; +#else + dev->open = uf_net_open; + dev->stop = uf_net_stop; + dev->hard_start_xmit = uf_net_xmit; + dev->do_ioctl = uf_net_ioctl; + + /* called by /proc/net/dev */ + dev->get_stats = uf_net_get_stats; + + dev->set_multicast_list = uf_set_multicast_list; +#endif + +#ifdef CSR_SUPPORT_WEXT + dev->wireless_handlers = &unifi_iw_handler_def; +#if IW_HANDLER_VERSION < 6 + dev->get_wireless_stats = unifi_get_wireless_stats; +#endif /* IW_HANDLER_VERSION */ +#endif /* CSR_SUPPORT_WEXT */ + return TRUE; +} /* uf_alloc_netdevice() */ + + + +/* + * --------------------------------------------------------------------------- + * uf_free_netdevice + * + * Unregister the network device and free the memory allocated for it. + * NB This includes the memory for the priv struct. + * + * Arguments: + * priv Device private pointer. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +int +uf_free_netdevice(unifi_priv_t *priv) +{ + int i; + unsigned long flags; + + func_enter(); + + unifi_trace(priv, UDBG1, "uf_free_netdevice\n"); + + if (!priv) { + return -EINVAL; + } + + /* + * Free any buffers used for holding firmware + */ + uf_release_firmware_files(priv); + +#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT) + if (priv->connection_config.mlmeAssociateReqInformationElements) { + kfree(priv->connection_config.mlmeAssociateReqInformationElements); + } + priv->connection_config.mlmeAssociateReqInformationElements = NULL; + priv->connection_config.mlmeAssociateReqInformationElementsLength = 0; + + if (priv->mib_data.length) { + vfree(priv->mib_data.data); + } + priv->mib_data.data = NULL; + priv->mib_data.length = 0; + +#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/ + + /* Free any bulkdata buffers allocated for M4 caching */ + spin_lock_irqsave(&priv->m4_lock, flags); + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; + if (interfacePriv->m4_bulk_data.data_length > 0) { + unifi_trace(priv, UDBG5, "uf_free_netdevice: free M4 bulkdata %d\n", i); + unifi_net_data_free(priv, &interfacePriv->m4_bulk_data); + } + } + spin_unlock_irqrestore(&priv->m4_lock, flags); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +#ifdef CONFIG_NET_SCHED + /* Unregister the qdisc operations */ + unregister_qdisc(&uf_qdisc_ops); +#endif /* CONFIG_NET_SCHED */ +#endif /* LINUX_VERSION_CODE */ + +#ifdef CSR_SUPPORT_WEXT + /* Unregister callback for netdevice state changes */ + unregister_netdevice_notifier(&uf_netdev_notifier); +#endif /* CSR_SUPPORT_WEXT */ + +#ifdef CSR_SUPPORT_SME + /* Cancel work items and destroy the workqueue */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) + cancel_work_sync(&priv->multicast_list_task); +#endif +#endif +/* Destroy the workqueues. */ + flush_workqueue(priv->unifi_workqueue); + destroy_workqueue(priv->unifi_workqueue); + + /* Free up netdev in reverse order: priv is allocated with netdev[0]. + * So, netdev[0] should be freed after all other netdevs are freed up + */ + for (i=CSR_WIFI_NUM_INTERFACES-1; i>=0; i--) { + /*Free the netdev struct and priv, which are all one lump*/ + if (priv->netdev[i]) { + unifi_error(priv, "uf_free_netdevice: netdev %d %p\n", i, priv->netdev[i]); + free_netdev(priv->netdev[i]); + } + } + + func_exit(); + return 0; +} /* uf_free_netdevice() */ + + +/* + * --------------------------------------------------------------------------- + * uf_net_open + * + * Called when userland does "ifconfig wlan0 up". + * + * Arguments: + * dev Device pointer. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static int +uf_net_open(struct net_device *dev) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + func_enter(); + + /* If we haven't finished UniFi initialisation, we can't start */ + if (priv->init_progress != UNIFI_INIT_COMPLETED) { + unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__); + return -EINVAL; + } + +#if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT) + /* + * To sniff, the user must do "iwconfig mode monitor", which sets + * priv->wext_conf.mode to IW_MODE_MONITOR. + * Then he/she must do "ifconfig ethn up", which calls this fn. + * There is no point in starting the sniff with SNIFFJOIN until + * this point. + */ + if (priv->wext_conf.mode == IW_MODE_MONITOR) { + int err; + err = uf_start_sniff(priv); + if (err) { + return err; + } + netif_carrier_on(dev); + } +#endif + +#ifdef CSR_SUPPORT_WEXT + if (interfacePriv->wait_netdev_change) { + unifi_trace(priv, UDBG1, "%s: Waiting for NETDEV_CHANGE, assume connected\n", + __FUNCTION__); + interfacePriv->connected = UnifiConnected; + interfacePriv->wait_netdev_change = FALSE; + } +#endif + + UF_NETIF_TX_START_ALL_QUEUES(dev); + + func_exit(); + return 0; +} /* uf_net_open() */ + + +static int +uf_net_stop(struct net_device *dev) +{ +#if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT) + netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + func_enter(); + + /* Stop sniffing if in Monitor mode */ + if (priv->wext_conf.mode == IW_MODE_MONITOR) { + if (priv->card) { + int err; + err = unifi_reset_state(priv, dev->dev_addr, 1); + if (err) { + return err; + } + } + } +#else + func_enter(); +#endif + + UF_NETIF_TX_STOP_ALL_QUEUES(dev); + + func_exit(); + return 0; +} /* uf_net_stop() */ + + +/* This is called after the WE handlers */ +static int +uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc; + + rc = -EOPNOTSUPP; + + return rc; +} /* uf_net_ioctl() */ + + + +static struct net_device_stats * +uf_net_get_stats(struct net_device *dev) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + + return &interfacePriv->stats; +} /* uf_net_get_stats() */ + +static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv_t *interfacePriv, struct sk_buff *skb, const int proto) +{ + CSR_PRIORITY priority = CSR_CONTENTION; + + func_enter(); + priority = (CSR_PRIORITY) (skb->priority >> 5); + + if (priority == CSR_QOS_UP0) { /* 0 */ + + unifi_trace(priv, UDBG5, "uf_get_packet_priority: proto = 0x%.4X\n", proto); + + switch (proto) { + case 0x0800: /* IPv4 */ + case 0x814C: /* SNMP */ + case 0x880C: /* GSMP */ + priority = (CSR_PRIORITY) (skb->data[1 + ETH_HLEN] >> 5); + break; + + case 0x8100: /* VLAN */ + priority = (CSR_PRIORITY) (skb->data[0 + ETH_HLEN] >> 5); + break; + + case 0x86DD: /* IPv6 */ + priority = (CSR_PRIORITY) ((skb->data[0 + ETH_HLEN] & 0x0E) >> 1); + break; + + default: + priority = CSR_QOS_UP0; + break; + } + } + + /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower + * priority */ + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) { + unifi_TrafficQueue queue; + + /* Keep trying lower priorities until we find a queue + * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */ + queue = unifi_frame_priority_to_queue(priority); + + while (queue > UNIFI_TRAFFIC_Q_BK && !interfacePriv->queueEnabled[queue]) { + queue--; + priority = unifi_get_default_downgrade_priority(queue); + } + } + + unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority); + + func_exit(); + return priority; +} + +/* + */ +/* + * --------------------------------------------------------------------------- + * get_packet_priority + * + * Arguments: + * priv private data area of functional driver + * skb socket buffer + * ehdr ethernet header to fetch protocol + * interfacePriv For accessing station record database + * + * + * Returns: + * CSR_PRIORITY. + * --------------------------------------------------------------------------- + */ +CSR_PRIORITY +get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv) +{ + CSR_PRIORITY priority = CSR_CONTENTION; + const int proto = ntohs(ehdr->h_proto); + + CsrUint8 interfaceMode = interfacePriv->interfaceMode; + + func_enter(); + + /* Priority Mapping for all the Modes */ + switch(interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + unifi_trace(priv, UDBG4, "mode is STA \n"); + if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1) { + priority = uf_get_packet_priority(priv, interfacePriv, skb, proto); + } else { + priority = CSR_CONTENTION; + } + break; +#ifdef CSR_SUPPORT_SME + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + { + CsrWifiRouterCtrlStaInfo_t * dstStaInfo = + CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,ehdr->h_dest, interfacePriv->InterfaceTag); + unifi_trace(priv, UDBG4, "mode is AP \n"); + if (!(ehdr->h_dest[0] & 0x01) && dstStaInfo && dstStaInfo->wmmOrQosEnabled) { + /* If packet is not Broadcast/multicast */ + priority = uf_get_packet_priority(priv, interfacePriv, skb, proto); + } else { + /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */ + unifi_trace(priv, UDBG4, "Destination is not QSTA or BroadCast/Multicast\n"); + priority = CSR_CONTENTION; + } + } + break; +#endif + default: + unifi_trace(priv, UDBG3, " mode unknown in %s func, mode=%x\n", __FUNCTION__, interfaceMode); + } + unifi_trace(priv, UDBG5, "priority = %x\n", priority); + + func_exit(); + return priority; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) +/* + * --------------------------------------------------------------------------- + * uf_net_select_queue + * + * Called by the kernel to select which queue to put the packet in + * + * Arguments: + * dev Device pointer + * skb Packet + * + * Returns: + * Queue index + * --------------------------------------------------------------------------- + */ +static u16 +uf_net_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = (unifi_priv_t *)interfacePriv->privPtr; + struct ethhdr ehdr; + unifi_TrafficQueue queue; + int proto; + CSR_PRIORITY priority; + + func_enter(); + + memcpy(&ehdr, skb->data, ETH_HLEN); + proto = ntohs(ehdr.h_proto); + + /* 802.1x - apply controlled/uncontrolled port rules */ + if ((proto != ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + && (proto != ETH_P_WAI) +#endif + ) { + /* queues 0 - 3 */ + priority = get_packet_priority(priv, skb, &ehdr, interfacePriv); + queue = unifi_frame_priority_to_queue(priority); + } else { + /* queue 4 */ + queue = UNIFI_TRAFFIC_Q_EAPOL; + } + + + func_exit(); + return (u16)queue; +} /* uf_net_select_queue() */ +#endif + +int +skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto) +{ + llc_snap_hdr_t *snap; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int headroom; + + /* get the headroom available in skb */ + headroom = skb_headroom(skb); + /* step 1: classify ether frame, DIX or 802.3? */ + + if (proto < 0x600) { + /* codes <= 1500 reserved for 802.3 lengths */ + /* it's 802.3, pass ether payload unchanged, */ + unifi_trace(priv, UDBG3, "802.3 len: %d\n", skb->len); + + /* leave off any PAD octets. */ + skb_trim(skb, proto); + } else if (proto == ETH_P_8021Q) { + + /* Store the VLAN SNAP (should be 87-65). */ + u16 vlan_snap = *(u16*)skb->data; + /* check for headroom availability before skb_push 14 = (4 + 10) */ + if (headroom < 14) { + unifi_trace(priv, UDBG3, "cant append vlan snap: debug\n"); + return -1; + } + /* Add AA-AA-03-00-00-00 */ + snap = (llc_snap_hdr_t *)skb_push(skb, 4); + snap->dsap = snap->ssap = 0xAA; + snap->ctrl = 0x03; + memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN); + + /* Add AA-AA-03-00-00-00 */ + snap = (llc_snap_hdr_t *)skb_push(skb, 10); + snap->dsap = snap->ssap = 0xAA; + snap->ctrl = 0x03; + memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN); + + /* Add the VLAN specific information */ + snap->protocol = htons(proto); + *(u16*)(snap + 1) = vlan_snap; + + } else + { + /* it's DIXII, time for some conversion */ + unifi_trace(priv, UDBG3, "DIXII len: %d\n", skb->len); + + /* check for headroom availability before skb_push */ + if (headroom < sizeof(llc_snap_hdr_t)) { + unifi_trace(priv, UDBG3, "cant append snap: debug\n"); + return -1; + } + /* tack on SNAP */ + snap = (llc_snap_hdr_t *)skb_push(skb, sizeof(llc_snap_hdr_t)); + snap->dsap = snap->ssap = 0xAA; + snap->ctrl = 0x03; + /* Use the appropriate OUI. */ + if ((proto == ETH_P_AARP) || (proto == ETH_P_IPX)) { + memcpy(snap->oui, oui_8021h, P80211_OUI_LEN); + } else { + memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN); + } + snap->protocol = htons(proto); + } + + return 0; +} /* skb_add_llc_snap() */ + +#ifdef CSR_SUPPORT_SME +static int +_identify_sme_ma_pkt_ind(unifi_priv_t *priv, + const CsrInt8 *oui, CsrUint16 protocol, + const CSR_SIGNAL *signal, + bulk_data_param_t *bulkdata, + const unsigned char *daddr, + const unsigned char *saddr) +{ + CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication; + int r; + CsrUint8 i; + + unifi_trace(priv, UDBG5, + "_identify_sme_ma_pkt_ind -->\n"); + for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) { + if (priv->sme_unidata_ind_filters[i].in_use) { + if (!memcmp(oui, priv->sme_unidata_ind_filters[i].oui, 3) && + (protocol == priv->sme_unidata_ind_filters[i].protocol)) { + + /* Send to client */ + if (priv->sme_cli) { + /* + * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind(). + * The frame needs to be converted according to the encapsulation. + */ + unifi_trace(priv, UDBG1, + "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n", + i, priv->sme_unidata_ind_filters[i].encapsulation, + priv->sme_unidata_ind_filters[i].protocol); + if (priv->sme_unidata_ind_filters[i].encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) { + struct sk_buff *skb; + /* The translation is performed on skb... */ + skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; + skb->len = bulkdata->d[0].data_length; + + unifi_trace(priv, UDBG1, + "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n"); + r = skb_80211_to_ether(priv, skb, daddr, saddr, + signal, bulkdata); + unifi_trace(priv, UDBG1, + "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n"); + if (r) { + return -EINVAL; + } + + /* ... but we indicate buffer and length */ + bulkdata->d[0].os_data_ptr = skb->data; + bulkdata->d[0].data_length = skb->len; + } else { + /* Add the MAC addresses before the SNAP */ + bulkdata->d[0].os_data_ptr -= 2*ETH_ALEN; + bulkdata->d[0].data_length += 2*ETH_ALEN; + memcpy((void*)bulkdata->d[0].os_data_ptr, daddr, ETH_ALEN); + memcpy((void*)bulkdata->d[0].os_data_ptr + ETH_ALEN, saddr, ETH_ALEN); + } + + unifi_trace(priv, UDBG1, + "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n"); + CsrWifiRouterMaPacketIndSend(priv->sme_unidata_ind_filters[i].appHandle, + (pkt_ind->VirtualInterfaceIdentifier & 0xff), + i, + pkt_ind->ReceptionStatus, + bulkdata->d[0].data_length, + (CsrUint8*)bulkdata->d[0].os_data_ptr, + NULL, + pkt_ind->Rssi, + pkt_ind->Snr, + pkt_ind->ReceivedRate); + + + unifi_trace(priv, UDBG1, + "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n"); + } + + return 1; + } + } + } + + return -1; +} +#endif /* CSR_SUPPORT_SME */ + +/* + * --------------------------------------------------------------------------- + * skb_80211_to_ether + * + * Make sure the received frame is in Ethernet (802.3) form. + * De-encapsulates SNAP if necessary, adds a ethernet header. + * The source buffer should not contain an 802.11 MAC header + * + * Arguments: + * payload Pointer to packet data received from UniFi. + * payload_length Number of bytes of data received from UniFi. + * daddr Destination MAC address. + * saddr Source MAC address. + * + * Returns: + * 0 on success, -1 if the packet is bad and should be dropped, + * 1 if the packet was forwarded to the SME or AMP client. + * --------------------------------------------------------------------------- + */ +int +skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb, + const unsigned char *daddr, const unsigned char *saddr, + const CSR_SIGNAL *signal, + bulk_data_param_t *bulkdata) +{ + unsigned char *payload; + int payload_length; + struct ethhdr *eth; + llc_snap_hdr_t *snap; + int headroom; +#define UF_VLAN_LLC_HEADER_SIZE 18 + static const u8 vlan_inner_snap[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; +#if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME) + const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication; +#endif + + if(skb== NULL || daddr == NULL || saddr == NULL){ + unifi_error(priv,"skb_80211_to_ether: PBC fail\n"); + return 1; + } + + payload = skb->data; + payload_length = skb->len; + + snap = (llc_snap_hdr_t *)payload; + eth = (struct ethhdr *)payload; + + /* get the skb headroom size */ + headroom = skb_headroom(skb); + + /* + * Test for the various encodings + */ + if ((payload_length >= sizeof(llc_snap_hdr_t)) && + (snap->dsap == 0xAA) && + (snap->ssap == 0xAA) && + (snap->ctrl == 0x03) && + (snap->oui[0] == 0) && + (snap->oui[1] == 0) && + ((snap->oui[2] == 0) || (snap->oui[2] == 0xF8))) + { + /* AppleTalk AARP (2) or IPX SNAP */ + if ((snap->oui[2] == 0) && + ((ntohs(snap->protocol) == ETH_P_AARP) || (ntohs(snap->protocol) == ETH_P_IPX))) + { + u16 len; + + unifi_trace(priv, UDBG3, "%s len: %d\n", + (ntohs(snap->protocol) == ETH_P_AARP) ? "ETH_P_AARP" : "ETH_P_IPX", + payload_length); + + /* check for headroom availability before skb_push */ + if (headroom < (2 * ETH_ALEN + 2)) { + unifi_warning(priv, "headroom not available to skb_push ether header\n"); + return -1; + } + + /* Add 802.3 header and leave full payload */ + len = htons(skb->len); + memcpy(skb_push(skb, 2), &len, 2); + memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN); + memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN); + + return 0; + } + /* VLAN-tagged IP */ + if ((snap->oui[2] == 0) && (ntohs(snap->protocol) == ETH_P_8021Q)) + { + /* + * The translation doesn't change the packet length, so is done in-place. + * + * Example header (from Std 802.11-2007 Annex M): + * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06 + * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2 + * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2 + * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06 + */ + u16 vlan_snap; + + if (payload_length < UF_VLAN_LLC_HEADER_SIZE) { + unifi_warning(priv, "VLAN SNAP header too short: %d bytes\n", payload_length); + return -1; + } + + if (memcmp(payload + 10, vlan_inner_snap, 6)) { + unifi_warning(priv, "VLAN malformatted SNAP header.\n"); + return -1; + } + + unifi_trace(priv, UDBG3, "VLAN SNAP: %02x-%02x\n", payload[8], payload[9]); + unifi_trace(priv, UDBG3, "VLAN len: %d\n", payload_length); + + /* Create the 802.3 header */ + + vlan_snap = *((u16*)(payload + 8)); + + /* Create LLC header without byte-swapping */ + eth->h_proto = snap->protocol; + + memcpy(eth->h_dest, daddr, ETH_ALEN); + memcpy(eth->h_source, saddr, ETH_ALEN); + *(u16*)(eth + 1) = vlan_snap; + return 0; + } + + /* it's a SNAP + RFC1042 frame */ + unifi_trace(priv, UDBG3, "SNAP+RFC1042 len: %d\n", payload_length); + + /* chop SNAP+llc header from skb. */ + skb_pull(skb, sizeof(llc_snap_hdr_t)); + + /* Since skb_pull called above to chop snap+llc, no need to check for headroom + * availability before skb_push + */ + /* create 802.3 header at beginning of skb. */ + eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); + memcpy(eth->h_dest, daddr, ETH_ALEN); + memcpy(eth->h_source, saddr, ETH_ALEN); + /* Copy protocol field without byte-swapping */ + eth->h_proto = snap->protocol; + } else { + u16 len; + + /* check for headroom availability before skb_push */ + if (headroom < (2 * ETH_ALEN + 2)) { + unifi_warning(priv, "headroom not available to skb_push ether header\n"); + return -1; + } + /* Add 802.3 header and leave full payload */ + len = htons(skb->len); + memcpy(skb_push(skb, 2), &len, 2); + memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN); + memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN); + + return 1; + } + + return 0; +} /* skb_80211_to_ether() */ + + +static CsrWifiRouterCtrlPortAction verify_port(unifi_priv_t *priv, unsigned char *address, int queue, CsrUint16 interfaceTag) +{ +#ifdef CSR_NATIVE_LINUX +#ifdef CSR_SUPPORT_WEXT + if (queue == UF_CONTROLLED_PORT_Q) { + return priv->wext_conf.block_controlled_port; + } else { + return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; + } +#else + return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; /* default to open for softmac dev */ +#endif +#else + return uf_sme_port_state(priv, address, queue, interfaceTag); +#endif +} + +/* + * --------------------------------------------------------------------------- + * prepare_and_add_macheader + * + * + * These functions adds mac header for packet from netdev + * to UniFi for transmission. + * EAP protocol packets are also appended with Mac header & + * sent using send_ma_pkt_request(). + * + * Arguments: + * priv Pointer to device private context struct + * skb Socket buffer containing data packet to transmit + * newSkb Socket buffer containing data packet + Mac header if no sufficient headroom in skb + * serviceClass to append QOS control header in Mac header + * bulkdata if newSkb allocated then bulkdata updated to send to unifi + * interfaceTag the interfaceID on which activity going on + * daddr destination address + * saddr source address + * protection protection bit set in framce control of mac header + * + * Returns: + * Zero on success or error code. + * --------------------------------------------------------------------------- + */ + +int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk_buff *newSkb, + CSR_PRIORITY priority, + bulk_data_param_t *bulkdata, + CsrUint16 interfaceTag, + const CsrUint8 *daddr, + const CsrUint8 *saddr, + CsrBool protection) +{ + CsrUint16 fc = 0; + CsrUint8 qc = 0; + CsrUint8 macHeaderLengthInBytes = MAC_HEADER_SIZE, *bufPtr = NULL; + bulk_data_param_t data_ptrs; + CsrResult csrResult; + int headroom =0; + CsrUint8 direction = 0; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrUint8 *addressOne; + CsrBool bQosNull = false; + + if (skb == NULL) { + unifi_error(priv,"prepare_and_add_macheader: Invalid SKB reference\n"); + return -1; + } + + /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */ + if (priority != CSR_CONTENTION) { + /* EAPOL packets don't go as QOS_DATA */ + if (priority == CSR_MANAGEMENT) { + fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA); + } else { + /* Qos Control Field */ + macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE; + + if (skb->len) { + + fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA); + } else { + fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL); + bQosNull = true; + } + } + } else { + if(skb->len == 0) { + fc |= cpu_to_le16(IEEE802_11_FC_TYPE_NULL); + } else { + fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA); + } + } + + switch (interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + direction = 2; + fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK); + break; + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + direction = 0; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + direction = 1; + fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK); + break; + case CSR_WIFI_ROUTER_CTRL_MODE_AMP: + if (priority == CSR_MANAGEMENT ) { + + direction = 2; + fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK); + } else { + /* Data frames have to use WDS 4 address frames */ + direction = 3; + fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK | IEEE802_11_FC_FROM_DS_MASK); + macHeaderLengthInBytes += 6; + } + break; + default: + unifi_warning(priv, "prepare_and_add_macheader: Unknown mode %d\n", + interfacePriv->interfaceMode); + } + + + /* If Sta is QOS & HTC is supported then need to set 'order' bit */ + /* We don't support HT Control for now */ + + if(protection) { + fc |= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK); + } + + /* check the skb headroom before pushing mac header */ + headroom = skb_headroom(skb); + + if (headroom < macHeaderLengthInBytes) { + unifi_trace(priv, UDBG5, + "prepare_and_add_macheader: Allocate headroom extra %d bytes\n", + macHeaderLengthInBytes); + + csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, " failed to allocate request_data. in %s func\n", __FUNCTION__); + return -1; + } + newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr); + newSkb->len = skb->len + macHeaderLengthInBytes; + + memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes, + skb->data, skb->len); + + bulkdata->d[0].os_data_ptr = newSkb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb; + bulkdata->d[0].data_length = newSkb->len; + + bufPtr = (CsrUint8*)data_ptrs.d[0].os_data_ptr; + + /* The old skb will not be used again */ + kfree_skb(skb); + } else { + + /* headroom has sufficient size, so will get proper pointer */ + bufPtr = (CsrUint8*)skb_push(skb, macHeaderLengthInBytes); + bulkdata->d[0].os_data_ptr = skb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata->d[0].data_length = skb->len; + } + + /* Frame the actual MAC header */ + + memset(bufPtr, 0, macHeaderLengthInBytes); + + /* copy frameControl field */ + memcpy(bufPtr, &fc, sizeof(fc)); + bufPtr += sizeof(fc); + macHeaderLengthInBytes -= sizeof(fc); + + /* Duration/ID field which is 2 bytes */ + bufPtr += 2; + macHeaderLengthInBytes -= 2; + + switch(direction) + { + case 0: + /* Its an Ad-Hoc no need to route it through AP */ + /* Address1: MAC address of the destination from eth header */ + memcpy(bufPtr, daddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address2: MAC address of the source */ + memcpy(bufPtr, saddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */ + memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + break; + case 1: + /* Address1: MAC address of the actual destination */ + memcpy(bufPtr, daddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + /* Address2: The MAC address of the AP */ + memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address3: MAC address of the source from eth header */ + memcpy(bufPtr, saddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + break; + case 2: + /* Address1: To AP is the MAC address of the AP to which its associated */ + memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address2: MAC address of the source from eth header */ + memcpy(bufPtr, saddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address3: MAC address of the actual destination on the distribution system */ + memcpy(bufPtr, daddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + break; + case 3: + memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address2: MAC address of the source from eth header */ + memcpy(bufPtr, saddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + + /* Address3: MAC address of the actual destination on the distribution system */ + memcpy(bufPtr, daddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + break; + default: + unifi_error(priv,"Unknown direction =%d : Not handled now\n",direction); + return -1; + } + /* 2 bytes of frame control field, appended by firmware */ + bufPtr += 2; + macHeaderLengthInBytes -= 2; + + if (3 == direction) { + /* Address4: MAC address of the source */ + memcpy(bufPtr, saddr, ETH_ALEN); + bufPtr += ETH_ALEN; + macHeaderLengthInBytes -= ETH_ALEN; + } + + /* IF Qos Data or Qos Null Data then set QosControl field */ + if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) { + + if (priority >= 7) { + unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority); + qc |= 7; + } else { + qc |= priority; + } + /*assigning address1 + * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction + * Address4 don't exit + */ + + addressOne = bufPtr- ADDRESS_ONE_OFFSET; + + if (addressOne[0] & 0x1) { + /* multicast/broadcast frames, no acknowledgement needed */ + qc |= 1 << 5; + } + /* non-AP mode only for now */ + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) { + /* In case of STA and IBSS case eosp and txop limit is 0. */ + } else { + if(bQosNull) { + qc |= 1 << 4; + } + } + + /* append Qos control field to mac header */ + bufPtr[0] = qc; + /* txop limit is 0 */ + bufPtr[1] = 0; + macHeaderLengthInBytes -= QOS_CONTROL_HEADER_SIZE; + } + if (macHeaderLengthInBytes) { + unifi_warning(priv, " Mac header not appended properly\n"); + return -1; + } + return 0; +} + +/* + * --------------------------------------------------------------------------- + * send_ma_pkt_request + * + * These functions send a data packet to UniFi for transmission. + * EAP protocol packets are also sent as send_ma_pkt_request(). + * + * Arguments: + * priv Pointer to device private context struct + * skb Socket buffer containing data packet to transmit + * ehdr Pointer to Ethernet header within skb. + * + * Returns: + * Zero on success or error code. + * --------------------------------------------------------------------------- + */ + +static int +send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority) +{ + int r; + CsrUint16 i; + CsrBool eapolStore = FALSE; + struct sk_buff *newSkb = NULL; + bulk_data_param_t bulkdata; + const int proto = ntohs(ehdr->h_proto); + CsrUint16 interfaceTag; + CsrWifiMacAddress peerAddress; + CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED; + CsrInt8 protection; + netInterface_priv_t *interfacePriv = NULL; + + unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n"); + + /* Get the interface Tag by means of source Mac address */ + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + if (!memcmp(priv->netdev[i]->dev_addr, ehdr->h_source, ETH_ALEN)) { + interfaceTag = i; + interfacePriv = priv->interfacePriv[interfaceTag]; + break; + } + } + + if (interfacePriv == NULL) { + /* No match found - error */ + interfaceTag = 0; + interfacePriv = priv->interfacePriv[interfaceTag]; + unifi_warning(priv, "Mac address not matching ... debugging needed\n"); + interfacePriv->stats.tx_dropped++; + kfree_skb(skb); + return -1; + } + + /* Add a SNAP header if necessary */ + if (skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto) != 0) { + /* convert failed */ + unifi_error(priv, "skb_add_llc_snap failed.\n"); + kfree_skb(skb); + return -1; + } + + bulkdata.d[0].os_data_ptr = skb->data; + bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len; + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].os_net_buf_ptr = NULL; + bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0; + +#ifdef CSR_SUPPORT_SME + /* Notify the TA module for the Tx frame for non AP/P2PGO mode*/ + if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) && + (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) { + unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX, + &bulkdata.d[0], ehdr->h_source, + priv->netdev[interfaceTag]->dev_addr, + jiffies_to_msecs(jiffies), + 0); /* rate is unknown on tx */ + } +#endif /* CSR_SUPPORT_SME */ + + if ((proto == ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + || (proto == ETH_P_WAI) +#endif + ) + { + /* check for m4 detection */ + if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) { + eapolStore = TRUE; + } + } + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + if (proto == ETH_P_WAI) + { + protection = 0; /*WAI packets always sent unencrypted*/ + } + else + { +#endif +#ifdef CSR_SUPPORT_SME + if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, ehdr->h_dest)) < 0) { + unifi_warning(priv, "unicast address, but destination not in station record database\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + return -1; + } +#else + protection = 0; +#endif +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + } +#endif + + /* append Mac header for Eapol as well as data packet */ + if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, ehdr->h_dest, ehdr->h_source, protection)) { + unifi_error(priv, "failed to create MAC header\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + return -1; + } + + /* RA adrress must contain the immediate destination MAC address that is similiar to + * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID)) + * which is address 1 field + */ + memcpy(peerAddress.a, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN); + + unifi_trace(priv, UDBG5, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n", + peerAddress.a[0],peerAddress.a[1], peerAddress.a[2], peerAddress.a[3], + peerAddress.a[4],peerAddress.a[5]); + + + if ((proto == ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + || (proto == ETH_P_WAI) +#endif + ) + { + CSR_SIGNAL signal; + CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest; + + /* initialize signal to zero */ + memset(&signal, 0, sizeof(CSR_SIGNAL)); + + /* Frame MA_PACKET request */ + signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID; + signal.SignalPrimitiveHeader.ReceiverProcessId = 0; + signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id; + + transmissionControl = req->TransmissionControl = 0; +#ifdef CSR_SUPPORT_SME + if (eapolStore) + { + netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]); + + /* Fill the MA-PACKET.req */ + + req->Priority = priority; + unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority); + + /* rate selected by firmware */ + req->TransmitRate = 0; + req->HostTag = CSR_WIFI_EAPOL_M4_HOST_TAG; + /* RA address matching with address 1 of Mac header */ + memcpy(req->Ra.x, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN); + + spin_lock(&priv->m4_lock); + /* Store the M4-PACKET.req for later */ + interfacePriv->m4_signal = signal; + interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length; + interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length; + interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr; + interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr; + spin_unlock(&priv->m4_lock); + + /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend(). + * It cannot be called directly from the tx path because it + * does a non-atomic kmalloc via the framework's CsrPmemAlloc(). + */ + queue_work(priv->unifi_workqueue, &netpriv->send_m4_ready_task); + + return 0; + } +#endif + } + + /* Send UniFi msg */ + /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */ + r = uf_process_ma_packet_req(priv, + peerAddress.a, + 0xffffffff, /* Ask for a new HostTag */ + interfaceTag, + transmissionControl, + (CSR_RATE)0, + priority, + priv->netdev_client->sender_id, + &bulkdata); + + if (r) { + unifi_trace(priv, UDBG1, "(HIP validation failure) r = %x\n", r); + unifi_net_data_free(priv, &bulkdata.d[0]); + return -1; + } + + unifi_trace(priv, UDBG3, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r); + + return r; +} /* send_ma_pkt_request() */ + +/* + * --------------------------------------------------------------------------- + * uf_net_xmit + * + * This function is called by the higher level stack to transmit an + * ethernet packet. + * + * Arguments: + * skb Ethernet packet to send. + * dev Pointer to the linux net device. + * + * Returns: + * 0 on success (packet was consumed, not necessarily transmitted) + * 1 if packet was requeued + * -1 on error + * + * + * Notes: + * The controlled port is handled in the qdisc dequeue handler. + * --------------------------------------------------------------------------- + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +static netdev_tx_t +#else +static int +#endif +uf_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct ethhdr ehdr; + int proto, port; + int result; + static tx_signal_handler tx_handler; + CSR_PRIORITY priority; +#if !defined (CONFIG_NET_SCHED) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) + CsrWifiRouterCtrlPortAction port_action; +#endif /* CONFIG_NET_SCHED */ + + func_enter(); + + unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb); + + memcpy(&ehdr, skb->data, ETH_HLEN); + proto = ntohs(ehdr.h_proto); + priority = get_packet_priority(priv, skb, &ehdr, interfacePriv); + + /* All frames are sent as MA-PACKET.req (EAPOL also) */ + tx_handler = send_ma_pkt_request; + + /* 802.1x - apply controlled/uncontrolled port rules */ + if ((proto != ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + && (proto != ETH_P_WAI) +#endif + ) { + port = UF_CONTROLLED_PORT_Q; + } else { + /* queue 4 */ + port = UF_UNCONTROLLED_PORT_Q; + } + +#if defined (CONFIG_NET_SCHED) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) + /* Remove the ethernet header */ + skb_pull(skb, ETH_HLEN); + result = tx_handler(priv, skb, &ehdr, priority); +#else + /* Uncontrolled port rules apply */ + port_action = verify_port(priv + , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI== interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest) + , port + , interfacePriv->InterfaceTag); + + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { + unifi_trace(priv, UDBG5, + "uf_net_xmit: %s controlled port open\n", + port ? "" : "un"); + /* Remove the ethernet header */ + skb_pull(skb, ETH_HLEN); + result = tx_handler(priv, skb, &ehdr, priority); + } else { + + /* Discard the packet if necessary */ + unifi_trace(priv, UDBG2, + "uf_net_xmit: %s controlled port %s\n", + port ? "" : "un", port_action==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK ? "blocked" : "closed"); + interfacePriv->stats.tx_dropped++; + kfree_skb(skb); + + func_exit(); + return NETDEV_TX_OK; + } +#endif /* CONFIG_NET_SCHED */ + + if (result == NETDEV_TX_OK) { + + dev->trans_start = jiffies; + + /* + * Should really count tx stats in the UNITDATA.status signal but + * that doesn't have the length. + */ + interfacePriv->stats.tx_packets++; + /* count only the packet payload */ + interfacePriv->stats.tx_bytes += skb->len; + + } else if (result < 0) { + + /* Failed to send: fh queue was full, and the skb was discarded. + * Return OK to indicate that the buffer was consumed, to stop the + * kernel re-transmitting the freed buffer. + */ + interfacePriv->stats.tx_dropped++; + unifi_trace(priv, UDBG1, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped); + result = NETDEV_TX_OK; + } + + /* The skb will have been freed by send_XXX_request() */ + + func_exit(); + return result; +} /* uf_net_xmit() */ + +/* + * --------------------------------------------------------------------------- + * unifi_pause_xmit + * unifi_restart_xmit + * + * These functions are called from the UniFi core to control the flow + * of packets from the upper layers. + * unifi_pause_xmit() is called when the internal queue is full and + * should take action to stop unifi_ma_unitdata() being called. + * When the queue has drained, unifi_restart_xmit() will be called to + * re-enable the flow of packets for transmission. + * + * Arguments: + * ospriv OS private context pointer. + * + * Returns: + * unifi_pause_xmit() is called from interrupt context. + * --------------------------------------------------------------------------- + */ +void +unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue) +{ + unifi_priv_t *priv = ospriv; + int i; /* used as a loop counter */ + + func_enter(); + unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + for(i=0;inetdev[i])) + { + netif_stop_subqueue(priv->netdev[i], (u16)queue); + } + } +#else +#ifdef ALLOW_Q_PAUSE + unifi_trace(priv, UDBG2, "Stopping netif\n"); + /* stop the traffic from all the interfaces. */ + for(i=0;inetdev[i])) { + UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]); + } + } +#else + if (net_is_tx_q_paused(priv, queue)) { + unifi_trace(priv, UDBG2, "Queue already stopped\n"); + return; + } + net_tx_q_pause(priv, queue); +#endif +#endif + +#ifdef CSR_SUPPORT_SME + if(queue<=3) { + routerStartBuffering(priv,queue); + unifi_trace(priv,UDBG2,"Start buffering %d\n", queue); + } else { + routerStartBuffering(priv,0); + unifi_error(priv, "Start buffering %d defaulting to 0\n", queue); + } +#endif + func_exit(); + +} /* unifi_pause_xmit() */ + +void +unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue) +{ + unifi_priv_t *priv = ospriv; + int i=0; /* used as a loop counter */ + + func_enter(); + unifi_trace(priv, UDBG2, "Waking queue %d\n", queue); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + for(i=0;inetdev[i])) + { + netif_wake_subqueue(priv->netdev[i], (u16)queue); + } + } +#else +#ifdef ALLOW_Q_PAUSE + /* Need to supply queue number depending on Kernel support */ + /* Resume the traffic from all the interfaces */ + for(i=0;inetdev[i])) { + UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[i]); + } + } +#else + if (!(net_is_tx_q_paused(priv, queue))) { + unifi_trace(priv, UDBG2, "Queue already running\n"); + func_exit(); + return; + } + net_tx_q_unpause(priv, queue); +#endif +#endif + +#ifdef CSR_SUPPORT_SME + if(queue <=3) { + routerStopBuffering(priv,queue); + uf_send_buffered_frames(priv,queue); + } else { + routerStopBuffering(priv,0); + uf_send_buffered_frames(priv,0); + } +#endif + func_exit(); +} /* unifi_restart_xmit() */ + + +static void +indicate_rx_skb(unifi_priv_t *priv, CsrUint16 ifTag, CsrUint8* dst_a, CsrUint8* src_a, struct sk_buff *skb, CSR_SIGNAL *signal, + bulk_data_param_t *bulkdata) +{ + int r, sr = 0; + struct net_device *dev; + +#ifdef CSR_SUPPORT_SME + llc_snap_hdr_t *snap; + + snap = (llc_snap_hdr_t *)skb->data; + + sr = _identify_sme_ma_pkt_ind(priv, + snap->oui, ntohs(snap->protocol), + signal, + bulkdata, + dst_a, src_a ); +#endif + + /* + * Decapsulate any SNAP header and + * prepend an ethernet header so that the skb manipulation and ARP + * stuff works. + */ + r = skb_80211_to_ether(priv, skb, dst_a, src_a, + signal, bulkdata); + if (r == -1) { + /* Drop the packet and return */ + priv->interfacePriv[ifTag]->stats.rx_errors++; + priv->interfacePriv[ifTag]->stats.rx_frame_errors++; + unifi_net_data_free(priv, &bulkdata->d[0]); + unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n"); + func_exit(); + return; + } + + /* Handle the case where packet is sent up through the subscription + * API but should not be given to the network stack (AMP PAL case) + * LLC header is different from WiFi and the packet has been subscribed for + */ + if (r == 1 && sr == 1) { + unifi_net_data_free(priv, &bulkdata->d[0]); + unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription" + "API, not being given to kernel\n"); + func_exit(); + return; + } + + dev = priv->netdev[ifTag]; + /* Now we look like a regular ethernet frame */ + /* Fill in SKB meta data */ + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* Test for an overlength frame */ + if (skb->len > (dev->mtu + ETH_HLEN)) { + /* A bogus length ethfrm has been encap'd. */ + /* Is someone trying an oflow attack? */ + unifi_error(priv, "%s: oversize frame (%d > %d)\n", + dev->name, + skb->len, dev->mtu + ETH_HLEN); + + /* Drop the packet and return */ + priv->interfacePriv[ifTag]->stats.rx_errors++; + priv->interfacePriv[ifTag]->stats.rx_length_errors++; + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + + /* Pass SKB up the stack */ +#ifdef CSR_WIFI_USE_NETIF_RX + netif_rx(skb); +#else + netif_rx_ni(skb); +#endif + + if (dev != NULL) { + dev->last_rx = jiffies; + } + + /* Bump rx stats */ + priv->interfacePriv[ifTag]->stats.rx_packets++; + priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length; + + func_exit(); + return; +} + +void +uf_process_rx_pending_queue(unifi_priv_t *priv, int queue, + CsrWifiMacAddress source_address, + int indicate, CsrUint16 interfaceTag) +{ + rx_buffered_packets_t *rx_q_item; + struct list_head *rx_list; + struct list_head *n; + struct list_head *l_h; + static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_process_rx_pending_queue bad interfaceTag\n"); + return; + } + + if (queue == UF_CONTROLLED_PORT_Q) { + rx_list = &interfacePriv->rx_controlled_list; + } else { + rx_list = &interfacePriv->rx_uncontrolled_list; + } + + down(&priv->rx_q_sem); + list_for_each_safe(l_h, n, rx_list) { + rx_q_item = list_entry(l_h, rx_buffered_packets_t, q); + + /* Validate against the source address */ + if (memcmp(broadcast_address.a, source_address.a, ETH_ALEN) && + memcmp(rx_q_item->sa.a, source_address.a, ETH_ALEN)) { + + unifi_trace(priv, UDBG2, + "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n", + rx_q_item->sa.a[0], rx_q_item->sa.a[1], + rx_q_item->sa.a[2], rx_q_item->sa.a[3], + rx_q_item->sa.a[4], rx_q_item->sa.a[5], + rx_q_item->skb, &rx_q_item->bulkdata.d[0]); + continue; + } + + list_del(l_h); + + + unifi_trace(priv, UDBG2, + "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n", + rx_q_item->skb, &rx_q_item->bulkdata); + + if (indicate) { + indicate_rx_skb(priv, interfaceTag, rx_q_item->da.a, rx_q_item->sa.a, rx_q_item->skb, &rx_q_item->signal, &rx_q_item->bulkdata); + } else { + interfacePriv->stats.rx_dropped++; + unifi_net_data_free(priv, &rx_q_item->bulkdata.d[0]); + } + + /* It is our resposibility to free the Rx structure object. */ + kfree(rx_q_item); + } + up(&priv->rx_q_sem); +} + +/* + * --------------------------------------------------------------------------- + * uf_resume_data_plane + * + * Is called when the (un)controlled port is set to open, + * to notify the network stack to schedule for transmission + * any packets queued in the qdisk while port was closed and + * indicated to the stack any packets buffered in the Rx queues. + * + * Arguments: + * priv Pointer to device private struct + * + * Returns: + * --------------------------------------------------------------------------- + */ +void +uf_resume_data_plane(unifi_priv_t *priv, int queue, + CsrWifiMacAddress peer_address, + CsrUint16 interfaceTag) +{ +#ifdef CSR_SUPPORT_WEXT + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; +#endif + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_resume_data_plane bad interfaceTag\n"); + return; + } + + unifi_trace(priv, UDBG2, "Resuming netif\n"); + + /* + * If we are waiting for the net device to enter the up state, don't + * process the rx queue yet as it will be done by the callback when + * the device is ready. + */ +#ifdef CSR_SUPPORT_WEXT + if (!interfacePriv->wait_netdev_change) +#endif + { +#ifdef CONFIG_NET_SCHED + if (netif_running(priv->netdev[interfaceTag])) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + netif_tx_schedule_all(priv->netdev[interfaceTag]); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + netif_schedule_queue(netdev_get_tx_queue(priv->netdev[interfaceTag], 0)); +#else + netif_schedule(priv->netdev[interfaceTag]); +#endif /* LINUX_VERSION_CODE */ + } +#endif + uf_process_rx_pending_queue(priv, queue, peer_address, 1,interfaceTag); + } +} /* uf_resume_data_plane() */ + + +void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address,CsrUint16 interfaceTag) +{ + uf_process_rx_pending_queue(priv, queue, peer_address, 0,interfaceTag); + +} /* uf_free_pending_rx_packets() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_rx + * + * Reformat a UniFi data received packet into a p80211 packet and + * pass it up the protocol stack. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) +{ + CsrUint16 interfaceTag; + bulk_data_desc_t *pData; + const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication; + struct sk_buff *skb; + CsrWifiRouterCtrlPortAction port_action; + CsrUint8 dataFrameType; + int proto; + int queue; + + CsrUint8 da[ETH_ALEN], sa[ETH_ALEN]; + CsrUint8 toDs, fromDs, frameType, macHeaderLengthInBytes = MAC_HEADER_SIZE; + CsrUint16 frameControl; + netInterface_priv_t *interfacePriv; + struct ethhdr ehdr; + + func_enter(); + + interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff); + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* Sanity check that the VIF refers to a sensible interface */ + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + + /* Sanity check that the VIF refers to an allocated netdev */ + if (!interfacePriv->netdev_registered) + { + unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag); + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + if (bulkdata->d[0].data_length == 0) { + unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__); + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + + + skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; + skb->len = bulkdata->d[0].data_length; + + /* Point to the addresses */ + toDs = (skb->data[1] & 0x01) ? 1 : 0; + fromDs = (skb->data[1] & 0x02) ? 1 : 0; + + memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */ + memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */ + + + pData = &bulkdata->d[0]; + frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr); + frameType = ((frameControl & 0x000C) >> 2); + + dataFrameType =((frameControl & 0x00f0) >> 4); + unifi_trace(priv, UDBG6, + "%s: Receive Data Frame Type %d \n", __FUNCTION__,dataFrameType); + + switch(dataFrameType) + { + case QOS_DATA: + case QOS_DATA_NULL: + /* If both are set then the Address4 exists (only for AP) */ + if (fromDs && toDs) + { + /* 6 is the size of Address4 field */ + macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6); + } + else + { + macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE; + } + + /* If order bit set then HT control field is the part of MAC header */ + if (frameControl & FRAME_CONTROL_ORDER_BIT) + macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE; + break; + default: + if (fromDs && toDs) + macHeaderLengthInBytes += 6; + } + + /* Prepare the ethernet header from snap header of skb data */ + switch(dataFrameType) + { + case DATA_NULL: + case QOS_DATA_NULL: + /* This is for only queue info fetching, EAPOL wont come as + * null data so the proto is initialized as zero + */ + proto = 0x0; + break; + default: + { + llc_snap_hdr_t *snap; + /* Fetch a snap header to find protocol (for IPV4/IPV6 packets + * the snap header fetching offset is same) + */ + snap = (llc_snap_hdr_t *) (skb->data + macHeaderLengthInBytes); + + /* prepare the ethernet header from the snap header & addresses */ + ehdr.h_proto = snap->protocol; + memcpy(ehdr.h_dest, da, ETH_ALEN); + memcpy(ehdr.h_source, sa, ETH_ALEN); + } + proto = ntohs(ehdr.h_proto); + } + unifi_trace(priv, UDBG3, "in unifi_rx protocol from snap header = 0x%x\n", proto); + + if ((proto != ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + && (proto != ETH_P_WAI) +#endif + ) { + queue = UF_CONTROLLED_PORT_Q; + } else { + queue = UF_UNCONTROLLED_PORT_Q; + } + + port_action = verify_port(priv, (unsigned char*)sa, queue, interfaceTag); + unifi_trace(priv, UDBG3, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action, queue); + +#ifdef CSR_SUPPORT_SME + /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/ + if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) && + (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) + { + /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */ + skb_pull(skb, macHeaderLengthInBytes); + pData->os_data_ptr = skb->data; + pData->data_length -= macHeaderLengthInBytes; + + if (pData->data_length) { + unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX, + &bulkdata->d[0], + sa, priv->netdev[interfaceTag]->dev_addr, + jiffies_to_msecs(jiffies), + pkt_ind->ReceivedRate); + } + } else { + + /* AP/P2PGO specific handling here */ + CsrWifiRouterCtrlStaInfo_t * srcStaInfo = + CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag); + + /* Defensive check only; Source address is already checked in + process_ma_packet_ind and we should have a valid source address here */ + + if(srcStaInfo == NULL) { + CsrWifiMacAddress peerMacAddress; + /* Unknown data PDU */ + memcpy(peerMacAddress.a,sa,ETH_ALEN); + unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__, + sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]); + CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress); + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + /* For AP GO mode, don't store the PDUs */ + if (port_action != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { + /* Drop the packet and return */ + CsrWifiMacAddress peerMacAddress; + memcpy(peerMacAddress.a,sa,ETH_ALEN); + unifi_trace(priv, UDBG3, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", + __FUNCTION__, sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]); + + CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress); + interfacePriv->stats.rx_dropped++; + unifi_net_data_free(priv, &bulkdata->d[0]); + unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__, + proto, queue ? "Controlled" : "Un-controlled"); + func_exit(); + return; + } + + /* Qos NULL/Data NULL are freed here and not processed further */ + if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){ + unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__); + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + /* Now we have done with MAC header so proceed with the real data part*/ + /* This function takes care of appropriate routing for AP/P2PGO case*/ + /* the function hadnles following things + 2. Routing the PDU to appropriate location + 3. Error case handling + */ + if(!(uf_ap_process_data_pdu(priv, skb, &ehdr, srcStaInfo, + signal, + bulkdata, + macHeaderLengthInBytes))) + { + func_exit(); + return; + } + unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes); + /* Remove the MAC header for subsequent conversion */ + skb_pull(skb, macHeaderLengthInBytes); + pData->os_data_ptr = skb->data; + pData->data_length -= macHeaderLengthInBytes; + pData->os_net_buf_ptr = (unsigned char*)skb; + pData->net_buf_length = skb->len; + } +#endif /* CSR_SUPPORT_SME */ + + + /* Now that the MAC header is removed, null-data frames have zero length + * and can be dropped + */ + if (pData->data_length == 0) { + if (((frameControl & 0x00f0) >> 4) != QOS_DATA_NULL && + ((frameControl & 0x00f0) >> 4) != DATA_NULL) { + unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl); + } + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) { + /* Drop the packet and return */ + interfacePriv->stats.rx_dropped++; + unifi_net_data_free(priv, &bulkdata->d[0]); + unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", + __FUNCTION__, proto, queue ? "controlled" : "uncontrolled"); + func_exit(); + return; + } else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) || + (interfacePriv->connected != UnifiConnected) ) { + + /* Buffer the packet into the Rx queues */ + rx_buffered_packets_t *rx_q_item; + struct list_head *rx_list; + + rx_q_item = (rx_buffered_packets_t *)kmalloc(sizeof(rx_buffered_packets_t), + GFP_KERNEL); + if (rx_q_item == NULL) { + unifi_error(priv, "%s: Failed to allocate %d bytes for rx packet record\n", + __FUNCTION__, sizeof(rx_buffered_packets_t)); + interfacePriv->stats.rx_dropped++; + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + INIT_LIST_HEAD(&rx_q_item->q); + rx_q_item->bulkdata = *bulkdata; + rx_q_item->skb = skb; + rx_q_item->signal = *signal; + memcpy(rx_q_item->sa.a, sa, ETH_ALEN); + memcpy(rx_q_item->da.a, da, ETH_ALEN); + unifi_trace(priv, UDBG2, "%s: Blocked skb=%p, bulkdata=%p\n", + __FUNCTION__, rx_q_item->skb, &rx_q_item->bulkdata); + + if (queue == UF_CONTROLLED_PORT_Q) { + rx_list = &interfacePriv->rx_controlled_list; + } else { + rx_list = &interfacePriv->rx_uncontrolled_list; + } + + /* Add to tail of packets queue */ + down(&priv->rx_q_sem); + list_add_tail(&rx_q_item->q, rx_list); + up(&priv->rx_q_sem); + + func_exit(); + return; + + } + + indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata); + + func_exit(); + +} /* unifi_rx() */ + +static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) +{ + CsrUint16 interfaceTag; + const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm; + netInterface_priv_t *interfacePriv; + + func_enter(); + interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff); + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* Sanity check that the VIF refers to a sensible interface */ + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); + func_exit(); + return; + } +#ifdef CSR_SUPPORT_SME + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + + uf_process_ma_pkt_cfm_for_ap(priv,interfaceTag,pkt_cfm); + } else if (interfacePriv->m4_sent && (pkt_cfm->HostTag == interfacePriv->m4_hostTag)) { + /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/ + CsrResult result = pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE; + CsrWifiMacAddress peerMacAddress; + memcpy(peerMacAddress.a, interfacePriv->m4_signal.u.MaPacketRequest.Ra.x, ETH_ALEN); + + unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__); + CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, + interfaceTag, + peerMacAddress, + result); + interfacePriv->m4_sent = FALSE; + interfacePriv->m4_hostTag = 0xffffffff; + } +#endif + func_exit(); + return; +} + + +/* + * --------------------------------------------------------------------------- + * unifi_rx + * + * Reformat a UniFi data received packet into a p80211 packet and + * pass it up the protocol stack. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) +{ + CsrUint16 interfaceTag; + bulk_data_desc_t *pData; + CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication; + struct sk_buff *skb; + CsrUint16 frameControl; + netInterface_priv_t *interfacePriv; + CsrUint8 da[ETH_ALEN], sa[ETH_ALEN]; + CsrUint8 *bssid = NULL, *ba_addr = NULL; + CsrUint8 toDs, fromDs, frameType; + CsrUint8 i =0; + +#ifdef CSR_SUPPORT_SME + CsrUint8 dataFrameType = 0; + CsrBool powerSaveChanged = FALSE; + CsrUint8 pmBit = 0; + CsrWifiRouterCtrlStaInfo_t *srcStaInfo = NULL; + CsrUint16 qosControl; + +#endif + + func_enter(); + + interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff); + interfacePriv = priv->interfacePriv[interfaceTag]; + + + /* Sanity check that the VIF refers to a sensible interface */ + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + + /* Sanity check that the VIF refers to an allocated netdev */ + if (!interfacePriv->netdev_registered) + { + unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag); + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + if (bulkdata->d[0].data_length == 0) { + unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__); + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + /* For monitor mode we need to pass this indication to the registered application + handle this seperately*/ + /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/ + if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS) + { + unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus); + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + + + skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; + skb->len = bulkdata->d[0].data_length; + + /* Point to the addresses */ + toDs = (skb->data[1] & 0x01) ? 1 : 0; + fromDs = (skb->data[1] & 0x02) ? 1 : 0; + + memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */ + memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */ + + /* Find the BSSID, which will be used to match the BA session */ + if (toDs && fromDs) + { + unifi_trace(priv, UDBG6, "4 address frame - don't try to find BSSID\n"); + bssid = NULL; + } + else + { + bssid = (CsrUint8 *) (skb->data + 4 + 12 - (fromDs * 6) - (toDs * 12)); + } + + pData = &bulkdata->d[0]; + frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr); + frameType = ((frameControl & 0x000C) >> 2); + + unifi_trace(priv, UDBG3, "Rx Frame Type: %d sn: %d\n",frameType, + (le16_to_cpu(*((CsrUint16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff); + if(frameType == IEEE802_11_FRAMETYPE_CONTROL){ +#ifdef CSR_SUPPORT_SME + unifi_trace(priv, UDBG6, "%s: Received Control Frame\n", __FUNCTION__); + + if((frameControl & 0x00f0) == 0x00A0){ + /* This is a PS-POLL request */ + CsrUint8 pmBit = (frameControl & 0x1000)?0x01:0x00; + unifi_trace(priv, UDBG6, "%s: Received PS-POLL Frame\n", __FUNCTION__); + + uf_process_ps_poll(priv,sa,da,pmBit,interfaceTag); + } + else { + unifi_warning(priv, "%s: Non PS-POLL control frame is received\n", __FUNCTION__); + } +#endif + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + if(frameType != IEEE802_11_FRAMETYPE_DATA) { + unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__); + unifi_net_data_free(priv,&bulkdata->d[0]); + func_exit(); + return; + } + +#ifdef CSR_SUPPORT_SME + if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) || + (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)){ + + srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag); + + if(srcStaInfo == NULL) { + CsrWifiMacAddress peerMacAddress; + /* Unknown data PDU */ + memcpy(peerMacAddress.a,sa,ETH_ALEN); + unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__, + sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]); + CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress); + unifi_net_data_free(priv, &bulkdata->d[0]); + func_exit(); + return; + } + + /* + verify power management bit here so as to ensure host and unifi are always + in sync with power management status of peer. + + If we do it later, it may so happen we have stored the frame in BA re-ordering + buffer and hence host and unifi are out of sync for power management status + */ + + pmBit = (frameControl & 0x1000)?0x01:0x00; + powerSaveChanged = uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag); + + /* Update station last activity time */ + srcStaInfo->activity_flag = TRUE; + + /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be + considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */ + + dataFrameType = ((frameControl & 0x00f0) >> 4); + + if((powerSaveChanged == FALSE)&&(srcStaInfo->wmmOrQosEnabled == TRUE)&& + (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)){ + + if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){ + + /* + QoS control field is offset from frame control by 2 (frame control) + + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN + */ + if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){ + qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30); + } + else{ + qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24); + } + + if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){ + CSR_PRIORITY priority; + unifi_TrafficQueue priority_q; + priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK); + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); + if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) + ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){ + unsigned long lock_flags; + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->uapsdSuspended = TRUE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + unifi_trace(priv, UDBG3, "%s: qos Trigger Frame received while DTIM Active for staid: 0x%x\n",__FUNCTION__,srcStaInfo->aid); + } + } + else{ + + + unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl); + uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag); + } + } + } + } + +#endif + + if( ((frameControl & 0x00f0) >> 4) == QOS_DATA) { + CsrUint8 *qos_control_ptr = (CsrUint8*)bulkdata->d[0].os_data_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24); + int tID = *qos_control_ptr & IEEE802_11_QC_TID_MASK; /* using ls octet of qos control */ + ba_session_rx_struct *ba_session; + CsrUint8 ba_session_idx = 0; + /* Get the BA originator address */ + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){ + ba_addr = sa; + }else{ + ba_addr = bssid; + } + + spin_lock(&priv->ba_lock); + for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ + ba_session = interfacePriv->ba_session_rx[ba_session_idx]; + if (ba_session){ + unifi_trace(priv, UDBG6, "found ba_session=0x%x ba_session_idx=%d", ba_session, ba_session_idx); + if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == tID)){ + frame_desc_struct frame_desc; + frame_desc.bulkdata = *bulkdata; + frame_desc.signal = *signal; + frame_desc.sn = (le16_to_cpu(*((CsrUint16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff; + frame_desc.active = TRUE; + unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx); + process_ba_frame(priv, interfacePriv, ba_session, &frame_desc); + spin_unlock(&priv->ba_lock); + process_ba_complete(priv, interfacePriv); + break; + } + } + } + if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){ + spin_unlock(&priv->ba_lock); + unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__); + process_amsdu(priv, signal, bulkdata); + } + } else { + unifi_trace(priv, UDBG6, "calling unifi_rx()"); + unifi_rx(priv, signal, bulkdata); + } + + /* check if the frames in reorder buffer has aged, the check + * is done after receive processing so that if the missing frame + * has arrived in this receive process, then it is handled cleanly. + * + * And also this code here takes care that timeout check is made for all + * the receive indications + */ + spin_lock(&priv->ba_lock); + for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){ + ba_session_rx_struct *ba_session; + ba_session = interfacePriv->ba_session_rx[i]; + if (ba_session){ + check_ba_frame_age_timeout(priv, interfacePriv, ba_session); + } + } + process_ba_complete(priv, interfacePriv); + spin_unlock(&priv->ba_lock); + + func_exit(); +} +/* + * --------------------------------------------------------------------------- + * uf_set_multicast_list + * + * This function is called by the higher level stack to set + * a list of multicast rx addresses. + * + * Arguments: + * dev Network Device pointer. + * + * Returns: + * None. + * + * Notes: + * --------------------------------------------------------------------------- + */ + +static void +uf_set_multicast_list(struct net_device *dev) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + +#ifdef CSR_NATIVE_LINUX + unifi_trace(priv, UDBG3, "uf_set_multicast_list unsupported\n"); + return; +#else + + u8 *mc_list = interfacePriv->mc_list; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) + struct netdev_hw_addr *mc_addr; + int mc_addr_count; +#else + struct dev_mc_list *p; /* Pointer to the addresses structure. */ + int i; +#endif + + if (priv->init_progress != UNIFI_INIT_COMPLETED) { + return; + } + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) + mc_addr_count = netdev_mc_count(dev); + + unifi_trace(priv, UDBG3, + "uf_set_multicast_list (count=%d)\n", mc_addr_count); + + + /* Not enough space? */ + if (mc_addr_count > UNIFI_MAX_MULTICAST_ADDRESSES) { + return; + } + + /* Store the list to be processed by the work item. */ + interfacePriv->mc_list_count = mc_addr_count; + netdev_hw_addr_list_for_each(mc_addr, &dev->mc) { + memcpy(mc_list, mc_addr->addr, ETH_ALEN); + mc_list += ETH_ALEN; + } + +#else + unifi_trace(priv, UDBG3, + "uf_set_multicast_list (count=%d)\n", dev->mc_count); + + /* Not enough space? */ + if (dev->mc_count > UNIFI_MAX_MULTICAST_ADDRESSES) { + return; + } + + /* Store the list to be processed by the work item. */ + interfacePriv->mc_list_count = dev->mc_count; + p = dev->mc_list; + for (i = 0; i < dev->mc_count; i++) { + memcpy(mc_list, p->dmi_addr, ETH_ALEN); + p = p->next; + mc_list += ETH_ALEN; + } +#endif + + /* Send a message to the workqueue */ + queue_work(priv->unifi_workqueue, &priv->multicast_list_task); +#endif + +} /* uf_set_multicast_list() */ + +/* + * --------------------------------------------------------------------------- + * netdev_mlme_event_handler + * + * Callback function to be used as the udi_event_callback when registering + * as a netdev client. + * To use it, a client specifies this function as the udi_event_callback + * to ul_register_client(). The signal dispatcher in + * unifi_receive_event() will call this function to deliver a signal. + * + * Arguments: + * pcli Pointer to the client instance. + * signal Pointer to the received signal. + * signal_len Size of the signal structure in bytes. + * bulkdata Pointer to structure containing any associated bulk data. + * dir Direction of the signal. Zero means from host, + * non-zero means to host. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len, + const bulk_data_param_t *bulkdata_o, int dir) +{ + CSR_SIGNAL signal; + unifi_priv_t *priv = uf_find_instance(pcli->instance); + int id, r; + bulk_data_param_t bulkdata; + + func_enter(); + + /* Just a sanity check */ + if (sig_packed == NULL) { + return; + } + + /* + * This copy is to silence a compiler warning about discarding the + * const qualifier. + */ + bulkdata = *bulkdata_o; + + /* Get the unpacked signal */ + r = read_unpack_signal(sig_packed, &signal); + if (r) { + /* + * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will + * fall through this case. It is safe to ignore this signal. + */ + unifi_trace(priv, UDBG1, + "Netdev - Received unknown signal 0x%.4X.\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed)); + return; + } + + id = signal.SignalPrimitiveHeader.SignalId; + unifi_trace(priv, UDBG3, "Netdev - Process signal 0x%.4X\n", id); + + /* + * Take the appropriate action for the signal. + */ + switch (id) { + case CSR_MA_PACKET_ERROR_INDICATION_ID: + process_ma_packet_error_ind(priv, &signal, &bulkdata); + break; + case CSR_MA_PACKET_INDICATION_ID: + process_ma_packet_ind(priv, &signal, &bulkdata); + break; + case CSR_MA_PACKET_CONFIRM_ID: + process_ma_packet_cfm(priv, &signal, &bulkdata); + break; +#ifdef CSR_SUPPORT_SME + case CSR_MLME_SET_TIM_CONFIRM_ID: + /* Handle TIM confirms from FW & set the station record's TIM state appropriately, + * In case of failures, tries with max_retransmit limit + */ + uf_handle_tim_cfm(priv, &signal.u.MlmeSetTimConfirm, signal.SignalPrimitiveHeader.ReceiverProcessId); + break; +#endif + case CSR_DEBUG_STRING_INDICATION_ID: + debug_string_indication(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length); + break; + + case CSR_DEBUG_WORD16_INDICATION_ID: + debug_word16_indication(priv, &signal); + break; + + case CSR_DEBUG_GENERIC_CONFIRM_ID: + case CSR_DEBUG_GENERIC_INDICATION_ID: + debug_generic_indication(priv, &signal); + break; + default: + break; + } + + func_exit(); +} /* netdev_mlme_event_handler() */ + + +/* + * --------------------------------------------------------------------------- + * uf_net_get_name + * + * Retrieve the name (e.g. eth1) associated with this network device + * + * Arguments: + * dev Pointer to the network device. + * name Buffer to write name + * len Size of buffer in bytes + * + * Returns: + * None + * + * Notes: + * --------------------------------------------------------------------------- + */ +void uf_net_get_name(struct net_device *dev, char *name, int len) +{ + *name = '\0'; + if (dev) { + strlcpy(name, dev->name, (len > IFNAMSIZ) ? IFNAMSIZ : len); + } + +} /* uf_net_get_name */ + + + + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +#ifdef CONFIG_NET_SCHED + +/* + * --------------------------------------------------------------------------- + * uf_install_qdisc + * + * Creates a root qdisc, registers our qdisc handlers and + * overrides the device's qdisc_sleeping to prevent the system + * from creating a new one for our network device. + * + * Arguments: + * dev Pointer to the network device. + * + * Returns: + * 0 on success, Linux error code otherwise. + * + * Notes: + * This function holds the qdisk lock so it needs to be called + * after registering the network device in uf_register_netdev(). + * Also, the qdisc_create_dflt() API has changed in 2.6.20 to + * include the parentid. + * --------------------------------------------------------------------------- + */ +int uf_install_qdisc(struct net_device *dev) +{ + struct Qdisc *qdisc; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + struct netdev_queue *queue0; +#endif /* LINUX_VERSION_CODE */ + + + func_enter(); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + /* + * check that there is no qdisc currently attached to device + * this ensures that we will be the root qdisc. (I can't find a better + * way to test this explicitly) + */ + if (dev->qdisc_sleeping != &noop_qdisc) { + func_exit_r(-EFAULT); + return -EINVAL; + } +#endif /* LINUX_VERSION_CODE */ + + qdisc = UF_QDISC_CREATE_DFLT(dev, &uf_qdisc_ops, TC_H_ROOT); + if (!qdisc) { + unifi_error(NULL, "%s: qdisc installation failed\n", dev->name); + func_exit_r(-EFAULT); + return -EFAULT; + } + unifi_trace(NULL, UDBG5, "%s: parent qdisc=0x%p\n", + dev->name, qdisc); + + qdisc->handle = 0x80020000; + qdisc->flags = 0x0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + queue0 = netdev_get_tx_queue(dev, 0); + if (queue0 == NULL) { + unifi_error(NULL, "%s: netdev_get_tx_queue returned no queue\n", + dev->name); + func_exit_r(-EFAULT); + return -EFAULT; + } + queue0->qdisc = qdisc; + queue0->qdisc_sleeping = qdisc; +#else + qdisc_lock_tree(dev); + list_add_tail(&qdisc->list, &dev->qdisc_list); + dev->qdisc_sleeping = qdisc; + qdisc_unlock_tree(dev); +#endif /* LINUX_VERSION_CODE */ + + func_exit_r(0); + return 0; + +} /* uf_install_qdisc() */ + +static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev_queue->dev); +#else + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev); +#endif /* LINUX_VERSION_CODE */ + unifi_priv_t *priv = interfacePriv->privPtr; + struct uf_sched_data *q = qdisc_priv(qd); + struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb; + struct ethhdr ehdr; + struct Qdisc *qdisc; + int r, proto; + + func_enter(); + + memcpy(&ehdr, skb->data, ETH_HLEN); + proto = ntohs(ehdr.h_proto); + + /* 802.1x - apply controlled/uncontrolled port rules */ + if ((proto != ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + && (proto != ETH_P_WAI) +#endif + ) { + /* queues 0 - 3 */ + pkt_data->priority = get_packet_priority(priv, skb, &ehdr, interfacePriv); + pkt_data->queue = unifi_frame_priority_to_queue(pkt_data->priority); + } else { + pkt_data->queue = UNIFI_TRAFFIC_Q_EAPOL; + } + + qdisc = q->queues[pkt_data->queue]; + r = qdisc->enqueue(skb, qdisc); + if (r == NET_XMIT_SUCCESS) { + qd->q.qlen++; + qd->bstats.bytes += skb->len; + qd->bstats.packets++; + func_exit_r(NET_XMIT_SUCCESS); + return NET_XMIT_SUCCESS; + } + + unifi_error(priv, "uf_qdiscop_enqueue: dropped\n"); + qd->qstats.drops++; + + func_exit_r(r); + return r; + +} /* uf_qdiscop_enqueue() */ + + +static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(qd->dev_queue->dev); +#else + netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(qd->dev); +#endif /* LINUX_VERSION_CODE */ + unifi_priv_t *priv = interfacePriv->privPtr; + struct uf_sched_data *q = qdisc_priv(qd); + struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb; + struct Qdisc *qdisc; + int r; + + func_enter(); + + unifi_trace(priv, UDBG5, "uf_qdiscop_requeue: (q=%d), tag=%u\n", + pkt_data->queue, pkt_data->host_tag); + + /* we recorded which queue to use earlier! */ + qdisc = q->queues[pkt_data->queue]; + + if ((r = qdisc->ops->requeue(skb, qdisc)) == 0) { + qd->q.qlen++; + func_exit_r(0); + return 0; + } + + unifi_error(priv, "uf_qdiscop_requeue: dropped\n"); + qd->qstats.drops++; + + func_exit_r(r); + return r; +} /* uf_qdiscop_requeue() */ + +static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev_queue->dev); +#else + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(qd->dev); +#endif /* LINUX_VERSION_CODE */ + unifi_priv_t *priv = interfacePriv->privPtr; + struct uf_sched_data *q = qdisc_priv(qd); + struct sk_buff *skb; + struct Qdisc *qdisc; + int queue, i; + struct ethhdr ehdr; + struct uf_tx_packet_data *pkt_data; + CsrWifiRouterCtrlPortAction port_action; + + func_enter(); + + /* check all the queues */ + for (i = UNIFI_TRAFFIC_Q_MAX - 1; i >= 0; i--) { + + if (i != UNIFI_TRAFFIC_Q_EAPOL) { + queue = priv->prev_queue; + if (++priv->prev_queue >= UNIFI_TRAFFIC_Q_EAPOL) { + priv->prev_queue = 0; + } + } else { + queue = i; + } + +#ifndef ALLOW_Q_PAUSE + /* If queue is paused, do not dequeue */ + if (net_is_tx_q_paused(priv, queue)) { + unifi_trace(priv, UDBG5, + "uf_qdiscop_dequeue: tx queue paused (q=%d)\n", queue); + continue; + } +#endif + + qdisc = q->queues[queue]; + skb = qdisc->dequeue(qdisc); + if (skb) { + /* A packet has been dequeued, decrease the queued packets count */ + qd->q.qlen--; + + pkt_data = (struct uf_tx_packet_data *) skb->cb; + + /* Check the (un)controlled port status */ + memcpy(&ehdr, skb->data, ETH_HLEN); + + port_action = verify_port(priv + , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) ||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI == interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest) + , (UNIFI_TRAFFIC_Q_EAPOL == queue? UF_UNCONTROLLED_PORT_Q: UF_CONTROLLED_PORT_Q) + , interfacePriv->InterfaceTag); + + /* Dequeue packet if port is open */ + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { + unifi_trace(priv, UDBG5, + "uf_qdiscop_dequeue: new (q=%d), tag=%u\n", + queue, pkt_data->host_tag); + + func_exit(); + return skb; + } + + /* Discard or block the packet if necessary */ + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) { + unifi_trace(priv, UDBG5, + "uf_qdiscop_dequeue: drop (q=%d), tag=%u\n", + queue, pkt_data->host_tag); + kfree_skb(skb); + break; + } + + /* We can not send the packet now, put it back to the queue */ + if (qdisc->ops->requeue(skb, qdisc) != 0) { + unifi_error(priv, + "uf_qdiscop_dequeue: requeue (q=%d) failed, tag=%u, drop it\n", + queue, pkt_data->host_tag); + + /* Requeue failed, drop the packet */ + kfree_skb(skb); + break; + } + /* We requeued the packet, increase the queued packets count */ + qd->q.qlen++; + + unifi_trace(priv, UDBG5, + "uf_qdiscop_dequeue: skip (q=%d), tag=%u\n", + queue, pkt_data->host_tag); + } + } + + func_exit(); + return NULL; +} /* uf_qdiscop_dequeue() */ + + +static void uf_qdiscop_reset(struct Qdisc* qd) +{ + struct uf_sched_data *q = qdisc_priv(qd); + int queue; + func_enter(); + + for (queue = 0; queue < UNIFI_TRAFFIC_Q_MAX; queue++) { + qdisc_reset(q->queues[queue]); + } + qd->q.qlen = 0; + + func_exit(); +} /* uf_qdiscop_reset() */ + + +static void uf_qdiscop_destroy(struct Qdisc* qd) +{ + struct uf_sched_data *q = qdisc_priv(qd); + int queue; + + func_enter(); + + for (queue=0; queue < UNIFI_TRAFFIC_Q_MAX; queue++) { + qdisc_destroy(q->queues[queue]); + q->queues[queue] = &noop_qdisc; + } + + func_exit(); +} /* uf_qdiscop_destroy() */ + + +/* called whenever parameters are updated on existing qdisc */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) +#else +static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt) +#endif +{ + func_enter(); + func_exit(); + return 0; +} /* uf_qdiscop_tune() */ + + +/* called during initial creation of qdisc on device */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) +#else +static int uf_qdiscop_init(struct Qdisc *qd, struct rtattr *opt) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + struct net_device *dev = qd->dev_queue->dev; +#else + struct net_device *dev = qd->dev; +#endif /* LINUX_VERSION_CODE */ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct uf_sched_data *q = qdisc_priv(qd); + int err = 0, i; + + func_enter(); + + /* make sure we do not mess with the ingress qdisc */ + if (qd->flags & TCQ_F_INGRESS) { + func_exit(); + return -EINVAL; + } + + /* if options were passed in, set them */ + if (opt) { + err = uf_qdiscop_tune(qd, opt); + } + + /* create child queues */ + for (i = 0; i < UNIFI_TRAFFIC_Q_MAX; i++) { + q->queues[i] = UF_QDISC_CREATE_DFLT(dev, &pfifo_qdisc_ops, + qd->handle); + if (!q->queues[i]) { + q->queues[i] = &noop_qdisc; + unifi_error(priv, "%s child qdisc %i creation failed\n"); + } + + unifi_trace(priv, UDBG5, "%s: child qdisc=0x%p\n", + dev->name, q->queues[i]); + } + + func_exit_r(err); + return err; +} /* uf_qdiscop_init() */ + + +static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) +{ + func_enter(); + func_exit_r(skb->len); + return skb->len; +} /* uf_qdiscop_dump() */ + +#endif /* CONFIG_NET_SCHED */ +#endif /* LINUX_VERSION_CODE */ + +#ifdef CSR_SUPPORT_WEXT + +/* + * --------------------------------------------------------------------------- + * uf_netdev_event + * + * Callback function to handle netdev state changes + * + * Arguments: + * notif Pointer to a notifier_block. + * event Event prompting notification + * ptr net_device pointer + * + * Returns: + * None + * + * Notes: + * The event handler is global, and may occur on non-UniFi netdevs. + * --------------------------------------------------------------------------- + */ +static int +uf_netdev_event(struct notifier_block *notif, unsigned long event, void* ptr) { + struct net_device *netdev = ptr; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(netdev); + unifi_priv_t *priv = NULL; + static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + + /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv + * structure is not safe to use. + */ + if (uf_find_netdev_priv(interfacePriv) == -1) { + unifi_trace(NULL, UDBG1, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n", + event, ptr, interfacePriv, netdev->name); + return 0; + } + + switch(event) { + case NETDEV_CHANGE: + priv = interfacePriv->privPtr; + unifi_trace(priv, UDBG1, "NETDEV_CHANGE: %p %s %s waiting for it\n", + ptr, + netdev->name, + interfacePriv->wait_netdev_change ? "" : "not"); + + if (interfacePriv->wait_netdev_change) { + UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[interfacePriv->InterfaceTag]); + interfacePriv->connected = UnifiConnected; + interfacePriv->wait_netdev_change = FALSE; + /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */ + uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag); + uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag); + } + break; + + default: + break; + } + return 0; +} + +static struct notifier_block uf_netdev_notifier = { + .notifier_call = uf_netdev_event, +}; +#endif /* CSR_SUPPORT_WEXT */ + + +static void + process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) +{ + CsrUint32 offset; + CsrUint32 length = bulkdata->d[0].data_length; + CsrUint32 subframe_length, subframe_body_length, dot11_hdr_size; + CsrUint8 *ptr; + bulk_data_param_t subframe_bulkdata; + CsrUint8 *dot11_hdr_ptr = (CsrUint8*)bulkdata->d[0].os_data_ptr; + CsrResult csrResult; + CsrUint16 frameControl; + CsrUint8 *qos_control_ptr; + + frameControl = le16_to_cpu(*((CsrUint16*)dot11_hdr_ptr)); + qos_control_ptr = dot11_hdr_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24); + if(!(*qos_control_ptr & IEEE802_11_QC_A_MSDU_PRESENT)) { + unifi_trace(priv, UDBG6, "%s: calling unifi_rx()", __FUNCTION__); + unifi_rx(priv, signal, bulkdata); + return; + } + *qos_control_ptr &= ~(IEEE802_11_QC_A_MSDU_PRESENT); + + ptr = qos_control_ptr + 2; + offset = dot11_hdr_size = ptr - dot11_hdr_ptr; + + while(length > (offset + sizeof(struct ethhdr) + sizeof(llc_snap_hdr_t))) { + subframe_body_length = ntohs(((struct ethhdr*)ptr)->h_proto); + if(subframe_body_length > IEEE802_11_MAX_DATA_LEN) { + unifi_error(priv, "%s: bad subframe_body_length = %d\n", __FUNCTION__, subframe_body_length); + break; + } + subframe_length = sizeof(struct ethhdr) + subframe_body_length; + memset(&subframe_bulkdata, 0, sizeof(bulk_data_param_t)); + + csrResult = unifi_net_data_malloc(priv, &subframe_bulkdata.d[0], dot11_hdr_size + subframe_body_length); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "%s: unifi_net_data_malloc failed\n", __FUNCTION__); + break; + } + + memcpy((CsrUint8*)subframe_bulkdata.d[0].os_data_ptr, dot11_hdr_ptr, dot11_hdr_size); + + + /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */ + if ((frameControl & IEEE802_11_FC_TO_DS_MASK) && !(frameControl & IEEE802_11_FC_FROM_DS_MASK)){ + memcpy((CsrUint8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, ((struct ethhdr*)ptr)->h_dest, ETH_ALEN); + } + else if (!(frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){ + memcpy((CsrUint8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, + ((struct ethhdr*)ptr)->h_source, + ETH_ALEN); + } + + memcpy((CsrUint8*)subframe_bulkdata.d[0].os_data_ptr + dot11_hdr_size, + ptr + sizeof(struct ethhdr), + subframe_body_length); + unifi_trace(priv, UDBG6, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__, length, subframe_length); + unifi_rx(priv, signal, &subframe_bulkdata); + + subframe_length = (subframe_length + 3)&(~0x3); + ptr += subframe_length; + offset += subframe_length; + } + unifi_net_data_free(priv, &bulkdata->d[0]); +} + + +#define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size) + + +#define ADVANCE_EXPECTED_SN(__ba_session) \ +{ \ + __ba_session->expected_sn++; \ + __ba_session->expected_sn &= 0xFFF; \ +} + +#define FREE_BUFFER_SLOT(__ba_session, __index) \ +{ \ + __ba_session->occupied_slots--; \ + __ba_session->buffer[__index].active = FALSE; \ + ADVANCE_EXPECTED_SN(__ba_session); \ +} + +static void add_frame_to_ba_complete(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + frame_desc_struct *frame_desc) +{ + interfacePriv->ba_complete[interfacePriv->ba_complete_index] = *frame_desc; + interfacePriv->ba_complete_index++; +} + + +static void update_expected_sn(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session, + CsrUint16 sn) +{ + int i, j; + CsrUint16 gap; + + gap = (sn - ba_session->expected_sn) & 0xFFF; + unifi_trace(priv, UDBG6, "%s: proccess the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap); + for(j = 0; j < gap && j < ba_session->wind_size; j++) { + i = SN_TO_INDEX(ba_session, ba_session->expected_sn); + unifi_trace(priv, UDBG6, "%s: proccess the slot index = %d\n", __FUNCTION__, i); + if(ba_session->buffer[i].active) { + add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]); + unifi_trace(priv, UDBG6, "%s: proccess the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn); + FREE_BUFFER_SLOT(ba_session, i); + } else { + unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i); + ADVANCE_EXPECTED_SN(ba_session); + } + } + ba_session->expected_sn = sn; +} + + +static void complete_ready_sequence(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session) +{ + int i; + + i = SN_TO_INDEX(ba_session, ba_session->expected_sn); + while (ba_session->buffer[i].active) { + add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]); + unifi_trace(priv, UDBG6, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__, ba_session->expected_sn, i); + FREE_BUFFER_SLOT(ba_session, i); + i = SN_TO_INDEX(ba_session, ba_session->expected_sn); + } +} + + +void scroll_ba_window(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session, + CsrUint16 sn) +{ + if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) { + update_expected_sn(priv, interfacePriv, ba_session, sn); + complete_ready_sequence(priv, interfacePriv, ba_session); + } +} + + +static int consume_frame_or_get_buffer_index(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session, + CsrUint16 sn, + frame_desc_struct *frame_desc) { + int i; + CsrUint16 sn_temp; + + if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) { + + /* once we are in BA window, set the flag for BA trigger */ + if(!ba_session->trigger_ba_after_ssn){ + ba_session->trigger_ba_after_ssn = TRUE; + } + + sn_temp = ba_session->expected_sn + ba_session->wind_size; + unifi_trace(priv, UDBG6, "%s: new frame: sn=%d\n", __FUNCTION__, sn); + if(!(((sn - sn_temp) & 0xFFF) > 2048)) { + CsrUint16 new_expected_sn; + unifi_trace(priv, UDBG6, "%s: frame is out of window\n", __FUNCTION__); + sn_temp = (sn - ba_session->wind_size) & 0xFFF; + new_expected_sn = (sn_temp + 1) & 0xFFF; + update_expected_sn(priv, interfacePriv, ba_session, new_expected_sn); + } + i = -1; + if (sn == ba_session->expected_sn) { + unifi_trace(priv, UDBG6, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__, sn); + ADVANCE_EXPECTED_SN(ba_session); + add_frame_to_ba_complete(priv, interfacePriv, frame_desc); + } else { + i = SN_TO_INDEX(ba_session, sn); + unifi_trace(priv, UDBG6, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__, sn, ba_session->expected_sn, i); + if (ba_session->buffer[i].active) { + unifi_trace(priv, UDBG6, "%s: free frame at i = %d\n", __FUNCTION__, i); + i = -1; + unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]); + } + } + } else { + i = -1; + if(!ba_session->trigger_ba_after_ssn){ + unifi_trace(priv, UDBG6, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__, sn); + add_frame_to_ba_complete(priv, interfacePriv, frame_desc); + }else{ + unifi_trace(priv, UDBG6, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__, sn, ba_session->expected_sn); + unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]); + } + } + return i; +} + + + +static void process_ba_frame(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session, + frame_desc_struct *frame_desc) +{ + int i; + CsrUint16 sn = frame_desc->sn; + + if (ba_session->timeout) { + mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024))); + } + unifi_trace(priv, UDBG6, "%s: got frame(sn=%d)\n", __FUNCTION__, sn); + + i = consume_frame_or_get_buffer_index(priv, interfacePriv, ba_session, sn, frame_desc); + if(i >= 0) { + unifi_trace(priv, UDBG6, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__, sn, i); + ba_session->buffer[i] = *frame_desc; + ba_session->buffer[i].recv_time = CsrTimeGet(NULL); + ba_session->occupied_slots++; + } else { + unifi_trace(priv, UDBG6, "%s: frame consumed - sn = %d\n", __FUNCTION__, sn); + } + complete_ready_sequence(priv, interfacePriv, ba_session); +} + + +static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv) +{ + frame_desc_struct *frame_desc; + CsrUint8 i; + + for(i = 0; i < interfacePriv->ba_complete_index; i++) { + frame_desc = &interfacePriv->ba_complete[i]; + unifi_trace(priv, UDBG6, "%s: calling process_amsdu()\n", __FUNCTION__); + process_amsdu(priv, &frame_desc->signal, &frame_desc->bulkdata); + } + interfacePriv->ba_complete_index = 0; + +} + + +/* Check if the frames in BA reoder buffer has aged and + * if so release the frames to upper processes and move + * the window + */ +static void check_ba_frame_age_timeout( unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session) +{ + CsrTime now; + CsrTime age; + CsrUint8 i, j; + CsrUint16 sn_temp; + + /* gap is started at 1 because we have buffered frames and + * hence a minimum gap of 1 exists + */ + CsrUint8 gap=1; + + now = CsrTimeGet(NULL); + + if (ba_session->occupied_slots) + { + /* expected sequence has not arrived so start searching from next + * sequence number until a frame is available and determine the gap. + * Check if the frame available has timedout, if so advance the + * expected sequence number and release the frames + */ + sn_temp = (ba_session->expected_sn + 1) & 0xFFF; + + for(j = 0; j < ba_session->wind_size; j++) + { + i = SN_TO_INDEX(ba_session, sn_temp); + + if(ba_session->buffer[i].active) + { + unifi_trace(priv, UDBG6, "check age at slot index = %d sn = %d recv_time = %u now = %u\n", + i, + ba_session->buffer[i].sn, + ba_session->buffer[i].recv_time, + now); + + if (ba_session->buffer[i].recv_time > now) + { + /* timer wrap */ + age = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now); + } + else + { + age = (CsrTime)CsrTimeSub(now, ba_session->buffer[i].recv_time); + } + + if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT) + { + unifi_trace(priv, UDBG2, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n", + i, + gap, + ba_session->expected_sn, + ba_session->buffer[i].sn); + + /* if it has timedout don't wait for missing frames, move the window */ + while (gap--) + { + ADVANCE_EXPECTED_SN(ba_session); + } + add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]); + FREE_BUFFER_SLOT(ba_session, i); + complete_ready_sequence(priv, interfacePriv, ba_session); + } + break; + + } + else + { + /* advance temp sequence number and frame gap */ + sn_temp = (sn_temp + 1) & 0xFFF; + gap++; + } + } + } +} + + +static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) +{ + CsrUint16 interfaceTag; + const CSR_MA_PACKET_ERROR_INDICATION *pkt_err_ind = &signal->u.MaPacketErrorIndication; + netInterface_priv_t *interfacePriv; + ba_session_rx_struct *ba_session; + CsrUint8 ba_session_idx = 0; + CSR_PRIORITY UserPriority; + CSR_SEQUENCE_NUMBER sn; + + func_enter(); + + interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff); + + + /* Sanity check that the VIF refers to a sensible interface */ + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); + func_exit(); + return; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + UserPriority = pkt_err_ind->UserPriority; + if(UserPriority > 15) { + unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority); + func_exit(); + } + sn = pkt_err_ind->SequenceNumber; + + spin_lock(&priv->ba_lock); + /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */ + for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ + ba_session = interfacePriv->ba_session_rx[ba_session_idx]; + if (ba_session){ + if ((!memcmp(ba_session->macAddress.a, pkt_err_ind->PeerQstaAddress.x, ETH_ALEN)) && (ba_session->tID == UserPriority)){ + if (ba_session->timeout) { + mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024))); + } + scroll_ba_window(priv, interfacePriv, ba_session, sn); + break; + } + } + } + + spin_unlock(&priv->ba_lock); + process_ba_complete(priv, interfacePriv); + func_exit(); +} + + diff --git a/drivers/staging/csr/os.c b/drivers/staging/csr/os.c new file mode 100644 index 000000000000..6dfce4226750 --- /dev/null +++ b/drivers/staging/csr/os.c @@ -0,0 +1,479 @@ +/* + * --------------------------------------------------------------------------- + * FILE: os.c + * + * PURPOSE: + * Routines to fulfil the OS-abstraction for the HIP lib. + * It is part of the porting exercise. + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + +/** + * The HIP lib OS abstraction consists of the implementation + * of the functions in this file. It is part of the porting exercise. + */ + +#include "unifi_priv.h" + + +/* + * --------------------------------------------------------------------------- + * unifi_net_data_malloc + * + * Allocate an OS specific net data buffer of "size" bytes. + * The bulk_data_slot.os_data_ptr must be initialised to point + * to the buffer allocated. The bulk_data_slot.length must be + * initialised to the requested size, zero otherwise. + * The bulk_data_slot.os_net_buf_ptr can be initialised to + * an OS specific pointer to be used in the unifi_net_data_free(). + * + * + * Arguments: + * ospriv Pointer to device private context struct. + * bulk_data_slot Pointer to the bulk data structure to initialise. + * size Size of the buffer to be allocated. + * + * Returns: + * CSR_RESULT_SUCCESS on success, CSR_RESULT_FAILURE otherwise. + * --------------------------------------------------------------------------- + */ +CsrResult +unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size) +{ + struct sk_buff *skb; + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + int rounded_length; + + if (priv->card_info.sdio_block_size == 0) { + unifi_error(priv, "unifi_net_data_malloc: Invalid SDIO block size\n"); + return CSR_RESULT_FAILURE; + } + + rounded_length = (size + priv->card_info.sdio_block_size - 1) & ~(priv->card_info.sdio_block_size - 1); + + /* + * (ETH_HLEN + 2) bytes tailroom for header manipulation + * CSR_WIFI_ALIGN_BYTES bytes headroom for alignment manipulation + */ + skb = dev_alloc_skb(rounded_length + 2 + ETH_HLEN + CSR_WIFI_ALIGN_BYTES); + if (! skb) { + unifi_error(ospriv, "alloc_skb failed.\n"); + bulk_data_slot->os_net_buf_ptr = NULL; + bulk_data_slot->net_buf_length = 0; + bulk_data_slot->os_data_ptr = NULL; + bulk_data_slot->data_length = 0; + return CSR_RESULT_FAILURE; + } + + bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb; + bulk_data_slot->net_buf_length = rounded_length + 2 + ETH_HLEN + CSR_WIFI_ALIGN_BYTES; + bulk_data_slot->os_data_ptr = (const void*)skb->data; + bulk_data_slot->data_length = size; + + return CSR_RESULT_SUCCESS; +} /* unifi_net_data_malloc() */ + +/* + * --------------------------------------------------------------------------- + * unifi_net_data_free + * + * Free an OS specific net data buffer. + * The bulk_data_slot.length must be initialised to 0. + * + * + * Arguments: + * ospriv Pointer to device private context struct. + * bulk_data_slot Pointer to the bulk data structure that + * holds the data to be freed. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot) +{ + struct sk_buff *skb; + CSR_UNUSED(ospriv); + + skb = (struct sk_buff *)bulk_data_slot->os_net_buf_ptr; + dev_kfree_skb(skb); + + bulk_data_slot->net_buf_length = 0; + bulk_data_slot->data_length = 0; + bulk_data_slot->os_data_ptr = bulk_data_slot->os_net_buf_ptr = NULL; + +} /* unifi_net_data_free() */ + + +/* +* --------------------------------------------------------------------------- +* unifi_net_dma_align +* +* DMA align an OS specific net data buffer. +* The buffer must be empty. +* +* +* Arguments: +* ospriv Pointer to device private context struct. +* bulk_data_slot Pointer to the bulk data structure that +* holds the data to be aligned. +* +* Returns: +* None. +* --------------------------------------------------------------------------- +*/ +CsrResult +unifi_net_dma_align(void *ospriv, bulk_data_desc_t *bulk_data_slot) +{ + struct sk_buff *skb; + unsigned long buf_address; + int offset; + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + + if ((bulk_data_slot == NULL) || (CSR_WIFI_ALIGN_BYTES == 0)) { + return CSR_RESULT_SUCCESS; + } + + if ((bulk_data_slot->os_data_ptr == NULL) || (bulk_data_slot->data_length == 0)) { + return CSR_RESULT_SUCCESS; + } + + buf_address = (unsigned long)(bulk_data_slot->os_data_ptr) & (CSR_WIFI_ALIGN_BYTES - 1); + + unifi_trace(priv, UDBG5, + "unifi_net_dma_align: Allign buffer (0x%p) by %d bytes\n", + bulk_data_slot->os_data_ptr, buf_address); + + offset = CSR_WIFI_ALIGN_BYTES - buf_address; + if (offset < 0) { + unifi_error(priv, "unifi_net_dma_align: Failed (offset=%d)\n", offset); + return CSR_RESULT_FAILURE; + } + + skb = (struct sk_buff*)(bulk_data_slot->os_net_buf_ptr); + skb_reserve(skb, offset); + bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb; + bulk_data_slot->os_data_ptr = (const void*)(skb->data); + + return CSR_RESULT_SUCCESS; + +} /* unifi_net_dma_align() */ + +#ifdef ANDROID_TIMESTAMP +static volatile unsigned int printk_cpu = UINT_MAX; +char tbuf[30]; + +char* print_time(void ) +{ + unsigned long long t; + unsigned long nanosec_rem; + + t = cpu_clock(printk_cpu); + nanosec_rem = do_div(t, 1000000000); + sprintf(tbuf, "[%5lu.%06lu] ", + (unsigned long) t, + nanosec_rem / 1000); + + return tbuf; +} +#endif + + +/* Module parameters */ +extern int unifi_debug; + +#ifdef UNIFI_DEBUG +#define DEBUG_BUFFER_SIZE 120 + +#define FORMAT_TRACE(_s, _len, _args, _fmt) \ + do { \ + va_start(_args, _fmt); \ + _len += vsnprintf(&(_s)[_len], \ + (DEBUG_BUFFER_SIZE - _len), \ + _fmt, _args); \ + va_end(_args); \ + if (_len >= DEBUG_BUFFER_SIZE) { \ + (_s)[DEBUG_BUFFER_SIZE - 2] = '\n'; \ + (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \ + } \ + } while (0) +#endif /* UNIFI_DEBUG */ + +void +unifi_error(void* ospriv, const char *fmt, ...) +{ +#ifdef UNIFI_DEBUG + unifi_priv_t *priv = (unifi_priv_t*) ospriv; + char s[DEBUG_BUFFER_SIZE]; + va_list args; + unsigned int len; +#ifdef ANDROID_TIMESTAMP + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi%d: ", print_time(), priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi: ", print_time()); + } +#else + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: "); + } +#endif /* ANDROID_TIMESTAMP */ + FORMAT_TRACE(s, len, args, fmt); + + printk("%s", s); +#endif /* UNIFI_DEBUG */ +} + +void +unifi_warning(void* ospriv, const char *fmt, ...) +{ +#ifdef UNIFI_DEBUG + unifi_priv_t *priv = (unifi_priv_t*) ospriv; + char s[DEBUG_BUFFER_SIZE]; + va_list args; + unsigned int len; + +#ifdef ANDROID_TIMESTAMP + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "%s unifi%d: ", print_time(), priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "%s unifi: ", print_time()); + } +#else + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi%d: ", priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi: "); + } +#endif /* ANDROID_TIMESTAMP */ + + FORMAT_TRACE(s, len, args, fmt); + + printk("%s", s); +#endif /* UNIFI_DEBUG */ +} + + +void +unifi_notice(void* ospriv, const char *fmt, ...) +{ +#ifdef UNIFI_DEBUG + unifi_priv_t *priv = (unifi_priv_t*) ospriv; + char s[DEBUG_BUFFER_SIZE]; + va_list args; + unsigned int len; + +#ifdef ANDROID_TIMESTAMP + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "%s unifi%d: ", print_time(), priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "%s unifi: ", print_time()); + } +#else + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi%d: ", priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi: "); + } +#endif /* ANDROID_TIMESTAMP */ + + FORMAT_TRACE(s, len, args, fmt); + + printk("%s", s); +#endif /* UNIFI_DEBUG */ +} + + +void +unifi_info(void* ospriv, const char *fmt, ...) +{ +#ifdef UNIFI_DEBUG + unifi_priv_t *priv = (unifi_priv_t*) ospriv; + char s[DEBUG_BUFFER_SIZE]; + va_list args; + unsigned int len; + +#ifdef ANDROID_TIMESTAMP + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "%s unifi%d: ", print_time(), priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "%s unifi: ", print_time()); + } +#else + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi%d: ", priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi: "); + } +#endif /* ANDROID_TIMESTAMP */ + + FORMAT_TRACE(s, len, args, fmt); + + printk("%s", s); +#endif /* UNIFI_DEBUG */ +} + +/* debugging */ +void +unifi_trace(void* ospriv, int level, const char *fmt, ...) +{ +#ifdef UNIFI_DEBUG + unifi_priv_t *priv = (unifi_priv_t*) ospriv; + char s[DEBUG_BUFFER_SIZE]; + va_list args; + unsigned int len; + + if (unifi_debug >= level) { +#ifdef ANDROID_TIMESTAMP + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi%d: ", print_time(), priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi: ", print_time()); + } +#else + if (priv != NULL) { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance); + } else { + len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: "); + } +#endif /* ANDROID_TIMESTAMP */ + + FORMAT_TRACE(s, len, args, fmt); + + printk("%s", s); + } +#endif /* UNIFI_DEBUG */ +} + +/* + * --------------------------------------------------------------------------- + * + * Debugging support. + * + * --------------------------------------------------------------------------- + */ + +#ifdef UNIFI_DEBUG + +/* Memory dump with level filter controlled by unifi_debug */ +void +unifi_dump(void *ospriv, int level, const char *msg, void *mem, CsrUint16 len) +{ + unifi_priv_t *priv = (unifi_priv_t*) ospriv; + + if (unifi_debug >= level) { +#ifdef ANDROID_TIMESTAMP + if (priv != NULL) { + printk(KERN_ERR "%s unifi%d: --- dump: %s ---\n", print_time(), priv->instance, msg ? msg : ""); + } else { + printk(KERN_ERR "%s unifi: --- dump: %s ---\n", print_time(), msg ? msg : ""); + } +#else + if (priv != NULL) { + printk(KERN_ERR "unifi%d: --- dump: %s ---\n", priv->instance, msg ? msg : ""); + } else { + printk(KERN_ERR "unifi: --- dump: %s ---\n", msg ? msg : ""); + } +#endif /* ANDROID_TIMESTAMP */ + dump(mem, len); + + if (priv != NULL) { + printk(KERN_ERR "unifi%d: --- end of dump ---\n", priv->instance); + } else { + printk(KERN_ERR "unifi: --- end of dump ---\n"); + } + } +} + +/* Memory dump that appears all the time, use sparingly */ +void +dump(void *mem, CsrUint16 len) +{ + int i, col = 0; + unsigned char *pdata = (unsigned char *)mem; +#ifdef ANDROID_TIMESTAMP + printk("timestamp %s \n", print_time()); +#endif /* ANDROID_TIMESTAMP */ + if (mem == NULL) { + printk("(null dump)\n"); + return; + } + for (i = 0; i < len; i++) { + if (col == 0) { + printk("0x%02X: ", i); + } + + printk(" %02X", pdata[i]); + + if (++col == 16) { + printk("\n"); + col = 0; + } + } + if (col) { + printk("\n"); + } +} /* dump() */ + + +void +dump16(void *mem, CsrUint16 len) +{ + int i, col=0; + unsigned short *p = (unsigned short *)mem; +#ifdef ANDROID_TIMESTAMP + printk("timestamp %s \n", print_time()); +#endif /* ANDROID_TIMESTAMP */ + for (i = 0; i < len; i+=2) { + if (col == 0) { + printk("0x%02X: ", i); + } + + printk(" %04X", *p++); + + if (++col == 8) { + printk("\n"); + col = 0; + } + } + if (col) { + printk("\n"); + } +} + + +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +void +dump_str(void *mem, CsrUint16 len) +{ + int i, col = 0; + unsigned char *pdata = (unsigned char *)mem; +#ifdef ANDROID_TIMESTAMP + printk("timestamp %s \n", print_time()); +#endif /* ANDROID_TIMESTAMP */ + for (i = 0; i < len; i++) { + printk("%c", pdata[i]); + } + if (col) { + printk("\n"); + } + +} /* dump_str() */ +#endif /* CSR_ONLY_NOTES */ + + +#endif /* UNIFI_DEBUG */ + + +/* --------------------------------------------------------------------------- + * - End - + * ------------------------------------------------------------------------- */ diff --git a/drivers/staging/csr/putest.c b/drivers/staging/csr/putest.c new file mode 100644 index 000000000000..1b2c7c299a6c --- /dev/null +++ b/drivers/staging/csr/putest.c @@ -0,0 +1,664 @@ +/* + * *************************************************************************** + * FILE: putest.c + * + * PURPOSE: putest related functions. + * + * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ + +#include +#include + +#include "unifi_priv.h" +#include "csr_wifi_hip_chiphelper.h" + +#define UNIFI_PROC_BOTH 3 + + +int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg) +{ + struct unifi_putest_cmd52 cmd52_params; + CsrUint8 *arg_pos; + unsigned int cmd_param_size; + int r; + CsrResult csrResult; + unsigned char ret_buffer[32]; + CsrUint8 *ret_buffer_pos; + CsrUint8 retries; + + arg_pos = (CsrUint8*)(((unifi_putest_command_t*)arg) + 1); + if (get_user(cmd_param_size, (int*)arg_pos)) { + unifi_error(priv, + "unifi_putest_cmd52_read: Failed to get the argument\n"); + return -EFAULT; + } + + if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) { + unifi_error(priv, + "unifi_putest_cmd52_read: cmd52 struct mismatch\n"); + return -EINVAL; + } + + arg_pos += sizeof(unsigned int); + if (copy_from_user(&cmd52_params, + (void*)arg_pos, + sizeof(struct unifi_putest_cmd52))) { + unifi_error(priv, + "unifi_putest_cmd52_read: Failed to get the cmd52 params\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "cmd52r: func=%d addr=0x%x ", + cmd52_params.funcnum, cmd52_params.addr); + + retries = 3; + CsrSdioClaim(priv->sdio); + do { + if (cmd52_params.funcnum == 0) { + csrResult = CsrSdioF0Read8(priv->sdio, cmd52_params.addr, &cmd52_params.data); + } else { + csrResult = CsrSdioRead8(priv->sdio, cmd52_params.addr, &cmd52_params.data); + } + } while (--retries && ((csrResult == CSR_SDIO_RESULT_CRC_ERROR) || (csrResult == CSR_SDIO_RESULT_TIMEOUT))); + CsrSdioRelease(priv->sdio); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "\nunifi_putest_cmd52_read: Read8() failed (csrResult=0x%x)\n", csrResult); + return -EFAULT; + } + unifi_trace(priv, UDBG2, "data=%d\n", cmd52_params.data); + + /* Copy the info to the out buffer */ + *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_CMD52_READ; + ret_buffer_pos = (CsrUint8*)(((unifi_putest_command_t*)ret_buffer) + 1); + *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_cmd52); + ret_buffer_pos += sizeof(unsigned int); + memcpy(ret_buffer_pos, &cmd52_params, sizeof(struct unifi_putest_cmd52)); + ret_buffer_pos += sizeof(struct unifi_putest_cmd52); + + r = copy_to_user((void*)arg, + ret_buffer, + ret_buffer_pos - ret_buffer); + if (r) { + unifi_error(priv, + "unifi_putest_cmd52_read: Failed to return the data\n"); + return -EFAULT; + } + + return 0; +} + + +int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg) +{ + struct unifi_putest_cmd52 cmd52_params; + CsrUint8 *arg_pos; + unsigned int cmd_param_size; + CsrResult csrResult; + CsrUint8 retries; + + arg_pos = (CsrUint8*)(((unifi_putest_command_t*)arg) + 1); + if (get_user(cmd_param_size, (int*)arg_pos)) { + unifi_error(priv, + "unifi_putest_cmd52_write: Failed to get the argument\n"); + return -EFAULT; + } + + if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) { + unifi_error(priv, + "unifi_putest_cmd52_write: cmd52 struct mismatch\n"); + return -EINVAL; + } + + arg_pos += sizeof(unsigned int); + if (copy_from_user(&cmd52_params, + (void*)(arg_pos), + sizeof(struct unifi_putest_cmd52))) { + unifi_error(priv, + "unifi_putest_cmd52_write: Failed to get the cmd52 params\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "cmd52w: func=%d addr=0x%x data=%d\n", + cmd52_params.funcnum, cmd52_params.addr, cmd52_params.data); + + retries = 3; + CsrSdioClaim(priv->sdio); + do { + if (cmd52_params.funcnum == 0) { + csrResult = CsrSdioF0Write8(priv->sdio, cmd52_params.addr, cmd52_params.data); + } else { + csrResult = CsrSdioWrite8(priv->sdio, cmd52_params.addr, cmd52_params.data); + } + } while (--retries && ((csrResult == CSR_SDIO_RESULT_CRC_ERROR) || (csrResult == CSR_SDIO_RESULT_TIMEOUT))); + CsrSdioRelease(priv->sdio); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_cmd52_write: Write8() failed (csrResult=0x%x)\n", csrResult); + return -EFAULT; + } + + return 0; +} + +int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg) +{ + struct unifi_putest_gp_rw16 gp_r16_params; + CsrUint8 *arg_pos; + unsigned int cmd_param_size; + int r; + CsrResult csrResult; + unsigned char ret_buffer[32]; + CsrUint8 *ret_buffer_pos; + + arg_pos = (CsrUint8*)(((unifi_putest_command_t*)arg) + 1); + if (get_user(cmd_param_size, (int*)arg_pos)) { + unifi_error(priv, + "unifi_putest_gp_read16: Failed to get the argument\n"); + return -EFAULT; + } + + if (cmd_param_size != sizeof(struct unifi_putest_gp_rw16)) { + unifi_error(priv, + "unifi_putest_gp_read16: struct mismatch\n"); + return -EINVAL; + } + + arg_pos += sizeof(unsigned int); + if (copy_from_user(&gp_r16_params, + (void*)arg_pos, + sizeof(struct unifi_putest_gp_rw16))) { + unifi_error(priv, + "unifi_putest_gp_read16: Failed to get the params\n"); + return -EFAULT; + } + + csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "gp_r16: GP=0x%08x, data=0x%04x\n", gp_r16_params.addr, gp_r16_params.data); + + /* Copy the info to the out buffer */ + *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_GP_READ16; + ret_buffer_pos = (CsrUint8*)(((unifi_putest_command_t*)ret_buffer) + 1); + *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_gp_rw16); + ret_buffer_pos += sizeof(unsigned int); + memcpy(ret_buffer_pos, &gp_r16_params, sizeof(struct unifi_putest_gp_rw16)); + ret_buffer_pos += sizeof(struct unifi_putest_gp_rw16); + + r = copy_to_user((void*)arg, + ret_buffer, + ret_buffer_pos - ret_buffer); + if (r) { + unifi_error(priv, + "unifi_putest_gp_read16: Failed to return the data\n"); + return -EFAULT; + } + + return 0; +} + +int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg) +{ + struct unifi_putest_gp_rw16 gp_w16_params; + CsrUint8 *arg_pos; + unsigned int cmd_param_size; + CsrResult csrResult; + + arg_pos = (CsrUint8*)(((unifi_putest_command_t*)arg) + 1); + if (get_user(cmd_param_size, (int*)arg_pos)) { + unifi_error(priv, + "unifi_putest_gp_write16: Failed to get the argument\n"); + return -EFAULT; + } + + if (cmd_param_size != sizeof(struct unifi_putest_gp_rw16)) { + unifi_error(priv, + "unifi_putest_gp_write16: struct mismatch\n"); + return -EINVAL; + } + + arg_pos += sizeof(unsigned int); + if (copy_from_user(&gp_w16_params, + (void*)(arg_pos), + sizeof(struct unifi_putest_gp_rw16))) { + unifi_error(priv, + "unifi_putest_gp_write16: Failed to get the params\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data); + + csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult); + return -EFAULT; + } + + return 0; +} + +int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg) +{ + int sdio_clock_speed; + CsrResult csrResult; + + if (get_user(sdio_clock_speed, (int*)(((unifi_putest_command_t*)arg) + 1))) { + unifi_error(priv, + "unifi_putest_set_sdio_clock: Failed to get the argument\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed); + + CsrSdioClaim(priv->sdio); + csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed); + CsrSdioRelease(priv->sdio); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_set_sdio_clock: Set clock failed (csrResult=0x%x)\n", csrResult); + return -EFAULT; + } + + return 0; +} + + +int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg) +{ + int r; + CsrResult csrResult; + int already_in_test = priv->ptest_mode; + + /* Ensure that sme_sys_suspend() doesn't power down the chip because: + * 1) Power is needed anyway for ptest. + * 2) The app code uses the START ioctl as a reset, so it gets called + * multiple times. If the app stops the XAPs, but the power_down/up + * sequence doesn't actually power down the chip, there can be problems + * resetting, because part of the power_up sequence disables function 1 + */ + priv->ptest_mode = 1; + + /* Suspend the SME and UniFi */ + if (priv->sme_cli) { + r = sme_sys_suspend(priv); + if (r) { + unifi_error(priv, + "unifi_putest_start: failed to suspend UniFi\n"); + return r; + } + } + + /* Application may have stopped the XAPs, but they are needed for reset */ + if (already_in_test) { + csrResult = unifi_start_processors(priv->card); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); + } + } else { + /* Ensure chip is powered for the case where there's no unifi_helper */ + CsrSdioClaim(priv->sdio); + csrResult = CsrSdioPowerOn(priv->sdio); + CsrSdioRelease(priv->sdio); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult); + } + } + + csrResult = unifi_init(priv->card); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_start: failed to init UniFi\n"); + return CsrHipResultToStatus(csrResult); + } + + return 0; +} + + +int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg) +{ + int r = 0; + CsrResult csrResult; + + /* Application may have stopped the XAPs, but they are needed for reset */ + csrResult = unifi_start_processors(priv->card); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); + } + + /* PUTEST_STOP is also used to resume the XAPs after SME coredump. + * Don't power off the chip, leave that to the normal wifi-off which is + * about to carry on. No need to resume the SME either, as it wasn't suspended. + */ + if (priv->coredump_mode) { + priv->coredump_mode = 0; + return 0; + } + + /* At this point function 1 is enabled and the XAPs are running, so it is + * safe to let the card power down. Power is restored later, asynchronously, + * during the wifi_on requested by the SME. + */ + CsrSdioClaim(priv->sdio); + CsrSdioPowerOff(priv->sdio); + CsrSdioRelease(priv->sdio); + + /* Resume the SME and UniFi */ + if (priv->sme_cli) { + r = sme_sys_resume(priv); + if (r) { + unifi_error(priv, + "unifi_putest_stop: failed to resume SME\n"); + } + } + priv->ptest_mode = 0; + + return r; +} + + +int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg) +{ +#define UF_PUTEST_MAX_FW_FILE_NAME 16 +#define UNIFI_MAX_FW_PATH_LEN 32 + unsigned int fw_name_length; + unsigned char fw_name[UF_PUTEST_MAX_FW_FILE_NAME+1]; + unsigned char *name_buffer; + int postfix; + char fw_path[UNIFI_MAX_FW_PATH_LEN]; + const struct firmware *fw_entry; + struct dlpriv temp_fw_sta; + int r; + CsrResult csrResult; + + /* Get the f/w file name length */ + if (get_user(fw_name_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) { + unifi_error(priv, + "unifi_putest_dl_fw: Failed to get the length argument\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file name size = %d\n", fw_name_length); + + /* Sanity check for the f/w file name length */ + if (fw_name_length > UF_PUTEST_MAX_FW_FILE_NAME) { + unifi_error(priv, + "unifi_putest_dl_fw: F/W file name is too long\n"); + return -EINVAL; + } + + /* Get the f/w file name */ + name_buffer = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int); + if (copy_from_user(fw_name, (void*)name_buffer, fw_name_length)) { + unifi_error(priv, "unifi_putest_dl_fw: Failed to get the file name\n"); + return -EFAULT; + } + fw_name[fw_name_length] = '\0'; + unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file = %s\n", fw_name); + + /* Keep the existing f/w to a temp, we need to restore it later */ + temp_fw_sta = priv->fw_sta; + + /* Get the putest f/w */ + postfix = priv->instance; + scnprintf(fw_path, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s", + postfix, fw_name); + r = request_firmware(&fw_entry, fw_path, priv->unifi_device); + if (r == 0) { + priv->fw_sta.fw_desc = (void *)fw_entry; + priv->fw_sta.dl_data = fw_entry->data; + priv->fw_sta.dl_len = fw_entry->size; + } else { + unifi_error(priv, "Firmware file not available\n"); + return -EINVAL; + } + + /* Application may have stopped the XAPs, but they are needed for reset */ + csrResult = unifi_start_processors(priv->card); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); + } + + /* Download the f/w. On UF6xxx this will cause the f/w file to convert + * into patch format and download via the ROM boot loader + */ + csrResult = unifi_download(priv->card, 0x0c00); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_dl_fw: failed to download the f/w\n"); + goto free_fw; + } + + /* Free the putest f/w... */ +free_fw: + uf_release_firmware(priv, &priv->fw_sta); + /* ... and restore the original f/w */ + priv->fw_sta = temp_fw_sta; + + return CsrHipResultToStatus(csrResult); +} + + +int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg) +{ + unsigned int fw_length; + unsigned char *fw_buf = NULL; + unsigned char *fw_user_ptr; + struct dlpriv temp_fw_sta; + CsrResult csrResult; + + /* Get the f/w buffer length */ + if (get_user(fw_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) { + unifi_error(priv, + "unifi_putest_dl_fw_buff: Failed to get the length arg\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "unifi_putest_dl_fw_buff: size = %d\n", fw_length); + + /* Sanity check for the buffer length */ + if (fw_length == 0 || fw_length > 0xfffffff) { + unifi_error(priv, + "unifi_putest_dl_fw_buff: buffer length bad %u\n", fw_length); + return -EINVAL; + } + + /* Buffer for kernel copy of the f/w image */ + fw_buf = CsrPmemAlloc(fw_length); + if (!fw_buf) { + unifi_error(priv, "unifi_putest_dl_fw_buff: malloc fail\n"); + return -ENOMEM; + } + + /* Get the f/w image */ + fw_user_ptr = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int); + if (copy_from_user(fw_buf, (void*)fw_user_ptr, fw_length)) { + unifi_error(priv, "unifi_putest_dl_fw_buff: Failed to get the buffer\n"); + CsrPmemFree(fw_buf); + return -EFAULT; + } + + /* Save the existing f/w to a temp, we need to restore it later */ + temp_fw_sta = priv->fw_sta; + + /* Setting fw_desc NULL indicates to the core that no f/w file was loaded + * via the kernel request_firmware() mechanism. This indicates to the core + * that it shouldn't call release_firmware() after the download is done. + */ + priv->fw_sta.fw_desc = NULL; /* No OS f/w resource */ + priv->fw_sta.dl_data = fw_buf; + priv->fw_sta.dl_len = fw_length; + + /* Application may have stopped the XAPs, but they are needed for reset */ + csrResult = unifi_start_processors(priv->card); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); + } + + /* Download the f/w. On UF6xxx this will cause the f/w file to convert + * into patch format and download via the ROM boot loader + */ + csrResult = unifi_download(priv->card, 0x0c00); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, + "unifi_putest_dl_fw_buff: failed to download the f/w\n"); + goto free_fw; + } + +free_fw: + /* Finished with the putest f/w, so restore the station f/w */ + priv->fw_sta = temp_fw_sta; + CsrPmemFree(fw_buf); + + return CsrHipResultToStatus(csrResult); +} + + +int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg) +{ + CsrUint16 data_u16; + CsrInt32 i; + CsrResult r; + + unifi_info(priv, "Preparing for SDIO coredump\n"); +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) + unifi_debug_buf_dump(); +#endif + + /* Sanity check that userspace hasn't called a PUTEST_START, because that + * would have reset UniFi, potentially power cycling it and losing context + */ + if (priv->ptest_mode) { + unifi_error(priv, "PUTEST_START shouldn't be used before a coredump\n"); + } + + /* Flag that the userspace has requested coredump. Even if this preparation + * fails, the SME will call PUTEST_STOP to tidy up. + */ + priv->coredump_mode = 1; + + for (i = 0; i < 3; i++) { + CsrSdioClaim(priv->sdio); + r = CsrSdioRead16(priv->sdio, CHIP_HELPER_UNIFI_GBL_CHIP_VERSION*2, &data_u16); + CsrSdioRelease(priv->sdio); + if (r != CSR_RESULT_SUCCESS) { + unifi_info(priv, "Failed to read chip version! Try %d\n", i); + + /* First try, re-enable function which may have been disabled by f/w panic */ + if (i == 0) { + unifi_info(priv, "Try function enable\n"); + CsrSdioClaim(priv->sdio); + r = CsrSdioFunctionEnable(priv->sdio); + CsrSdioRelease(priv->sdio); + if (r != CSR_RESULT_SUCCESS) { + unifi_error(priv, "CsrSdioFunctionEnable failed %d\n", r); + } + continue; + } + + /* Subsequent tries, reset */ + + /* Set clock speed low */ + CsrSdioClaim(priv->sdio); + r = CsrSdioMaxBusClockFrequencySet(priv->sdio, UNIFI_SDIO_CLOCK_SAFE_HZ); + CsrSdioRelease(priv->sdio); + if (r != CSR_RESULT_SUCCESS) { + unifi_error(priv, "CsrSdioMaxBusClockFrequencySet() failed %d\n", r); + } + + /* Card software reset */ + r = unifi_card_hard_reset(priv->card); + if (r != CSR_RESULT_SUCCESS) { + unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r); + } + } else { + unifi_info(priv, "Read chip version of 0x%04x\n", data_u16); + break; + } + } + + if (r != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Failed to prepare chip\n"); + return -EIO; + } + + /* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at + * Raw SDIO deinit, to resume them. + */ + r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH); + if (r != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Failed to stop processors\n"); + } + + return 0; +} + +int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg) +{ + struct unifi_putest_block_cmd52_r block_cmd52; + CsrUint8 *arg_pos; + unsigned int cmd_param_size; + CsrResult r; + CsrUint8 *block_local_buffer; + + arg_pos = (CsrUint8*)(((unifi_putest_command_t*)arg) + 1); + if (get_user(cmd_param_size, (int*)arg_pos)) { + unifi_error(priv, + "cmd52r_block: Failed to get the argument\n"); + return -EFAULT; + } + + if (cmd_param_size != sizeof(struct unifi_putest_block_cmd52_r)) { + unifi_error(priv, + "cmd52r_block: cmd52 struct mismatch\n"); + return -EINVAL; + } + + arg_pos += sizeof(unsigned int); + if (copy_from_user(&block_cmd52, + (void*)arg_pos, + sizeof(struct unifi_putest_block_cmd52_r))) { + unifi_error(priv, + "cmd52r_block: Failed to get the cmd52 params\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG2, "cmd52r_block: func=%d addr=0x%x len=0x%x ", + block_cmd52.funcnum, block_cmd52.addr, block_cmd52.length); + + block_local_buffer = vmalloc(block_cmd52.length); + if (block_local_buffer == NULL) { + unifi_error(priv, "cmd52r_block: Failed to allocate buffer\n"); + return -ENOMEM; + } + + r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length); + if (r != CSR_RESULT_SUCCESS) { + unifi_error(priv, "cmd52r_block: unifi_readn failed\n"); + return -EIO; + } + + if (copy_to_user((void*)block_cmd52.data, + block_local_buffer, + block_cmd52.length)) { + unifi_error(priv, + "cmd52r_block: Failed to return the data\n"); + return -EFAULT; + } + + return 0; +} diff --git a/drivers/staging/csr/sdio_emb.c b/drivers/staging/csr/sdio_emb.c new file mode 100644 index 000000000000..f61fdb130e61 --- /dev/null +++ b/drivers/staging/csr/sdio_emb.c @@ -0,0 +1,732 @@ +/* + * --------------------------------------------------------------------------- + * + * FILE: sdio_emb.c + * + * PURPOSE: Driver instantiation and deletion for SDIO on Linux. + * + * This file brings together the SDIO bus interface, the UniFi + * driver core and the Linux net_device stack. + * + * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include +#include +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" + +#include "sdioemb/sdio_api.h" + +/* The function driver context, i.e the UniFi Driver */ +static CsrSdioFunctionDriver *sdio_func_drv; + + + +/* sdioemb driver uses POSIX error codes */ +static CsrResult +ConvertSdioToCsrSdioResult(int r) +{ + CsrResult csrResult = CSR_RESULT_FAILURE; + + switch (r) { + case 0: + csrResult = CSR_RESULT_SUCCESS; + break; + case -EIO: + csrResult = CSR_SDIO_RESULT_CRC_ERROR; + break; + /* Timeout errors */ + case -ETIMEDOUT: + case -EBUSY: + csrResult = CSR_SDIO_RESULT_TIMEOUT; + break; + case -ENODEV: + case -ENOMEDIUM: + csrResult = CSR_SDIO_RESULT_NO_DEVICE; + break; + case -EINVAL: + csrResult = CSR_SDIO_RESULT_INVALID_VALUE; + break; + case -ENOMEM: + case -ENOSYS: + case -EILSEQ: + case -ERANGE: + case -ENXIO: + csrResult = CSR_RESULT_FAILURE; + break; + default: + unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r); + break; + } + + return csrResult; +} + + +CsrResult +CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int err; + err = sdioemb_read8(fdev, address, data); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioRead8() */ + +CsrResult +CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int err; + err = sdioemb_write8(fdev, address, data); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioWrite8() */ + +CsrResult +CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + r = sdioemb_read16(fdev, address, data); + if (r) { + return ConvertSdioToCsrSdioResult(r); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioRead16() */ + +CsrResult +CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + r = sdioemb_write16(fdev, address, data); + if (r) { + return ConvertSdioToCsrSdioResult(r); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioWrite16() */ + + +CsrResult +CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int err; + err = sdioemb_f0_read8(fdev, address, data); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioF0Read8() */ + + +CsrResult +CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int err; + err = sdioemb_f0_write8(fdev, address, data); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioF0Write8() */ + +CsrResult +CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int err; + err = sdioemb_read(fdev, address, data, length); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioRead() */ + +CsrResult +CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int err; + err = sdioemb_write(fdev, address, data, length); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioWrite() */ + + +CsrResult +CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r = 0; + + /* Module parameter overrides */ + if (sdio_block_size > -1) { + blockSize = sdio_block_size; + } + + unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n", + blockSize); + + r = sdioemb_set_block_size(fdev, blockSize); + if (r) { + unifi_error(NULL, "Error %d setting block size\n", r); + } + + /* Determine the achieved block size to report to the core */ + function->blockSize = fdev->blocksize; + + return ConvertSdioToCsrSdioResult(r); +} /* CsrSdioBlockSizeSet() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioMaxBusClockFrequencySet + * + * Set the maximum SDIO bus clock speed to use. + * + * Arguments: + * sdio SDIO context pointer + * maxFrequency maximum clock speed in Hz + * + * Returns: + * an error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + CsrUint32 max_khz = maxFrequency/1000; + + if (!max_khz || max_khz > sdio_clock) { + max_khz = sdio_clock; + } + unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", max_khz); + sdioemb_set_max_bus_freq(fdev, 1000 * max_khz); + + return CSR_RESULT_SUCCESS; +} /* CsrSdioMaxBusClockFrequencySet() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioInterruptEnable + * CsrSdioInterruptDisable + * + * Enable or disable the SDIO interrupt. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * Zero on success or a UniFi driver error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioInterruptEnable(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + r = sdioemb_interrupt_enable(fdev); + if (r) { + return ConvertSdioToCsrSdioResult(r); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioInterruptEnable() */ + +CsrResult +CsrSdioInterruptDisable(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + r = sdioemb_interrupt_disable(fdev); + if (r) { + return ConvertSdioToCsrSdioResult(r); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioInterruptDisable() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioInterruptAcknowledge + * + * Acknowledge an SDIO interrupt. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * Zero on success or a UniFi driver error code. + * --------------------------------------------------------------------------- + */ +void CsrSdioInterruptAcknowledge(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + + sdioemb_interrupt_acknowledge(fdev); +} /* CsrSdioInterruptAcknowledge() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionEnable + * + * Enable i/o on this function. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioFunctionEnable(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + /* Enable UniFi function (the 802.11 part). */ + r = sdioemb_enable_function(fdev); + if (r) { + unifi_error(NULL, "Failed to enable SDIO function %d\n", fdev->function); + return ConvertSdioToCsrSdioResult(r); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioFunctionEnable() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionDisable + * + * Disable i/o on this function. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioFunctionDisable(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + /* Disable UniFi function (the 802.11 part). */ + r = sdioemb_disable_function(fdev); + if (r) { + unifi_error(NULL, "Failed to disable SDIO function %d\n", fdev->function); + return ConvertSdioToCsrSdioResult(r); + } + return CSR_RESULT_SUCCESS; +} /* CsrSdioFunctionDisable() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionActive + * + * No-op as the bus goes to an active state at the start of every + * command. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +void +CsrSdioFunctionActive(CsrSdioFunction *function) +{ +} /* CsrSdioFunctionActive() */ + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionIdle + * + * Set the function as idle. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +void +CsrSdioFunctionIdle(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + + sdioemb_idle_function(fdev); +} /* CsrSdioFunctionIdle() */ + + +CsrResult +CsrSdioPowerOn(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + + if (disable_power_control != 1) { + sdioemb_power_on(fdev); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioPowerOn() */ + +void +CsrSdioPowerOff(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + if (disable_power_control != 1) { + sdioemb_power_off(fdev); + } +} /* CsrSdioPowerOff() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioHardReset + * + * Hard Resets UniFi is possible. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * 1 if the SDIO driver is not capable of doing a hard reset. + * 0 if a hard reset was successfully performed. + * -CSR_EIO if an I/O error occured while re-initializing the card. + * This is a fatal, non-recoverable error. + * -CSR_ENODEV if the card is no longer present. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioHardReset(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + int r; + + /* Hard reset can be disabled by a module parameter */ + r = 1; + if (disable_hw_reset != 1) { + r = sdioemb_hard_reset(fdev); /* may return 1 if can't reset */ + if (r < 0) { + return ConvertSdioToCsrSdioResult(r); /* fatal error */ + } + } + + /* Set the SDIO bus width after a hard reset */ + if (buswidth == 1) { + unifi_info(NULL, "Setting SDIO bus width to 1\n"); + sdioemb_set_bus_width(fdev, buswidth); + } else if (buswidth == 4) { + unifi_info(NULL, "Setting SDIO bus width to 4\n"); + sdioemb_set_bus_width(fdev, buswidth); + } + + if(r == 1) + { + return CSR_SDIO_RESULT_NOT_RESET; + } + + return ConvertSdioToCsrSdioResult(r); + +} /* CsrSdioHardReset() */ + + +int csr_sdio_linux_remove_irq(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + + return sdioemb_interrupt_disable(fdev); +} + +int csr_sdio_linux_install_irq(CsrSdioFunction *function) +{ + struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv; + + return sdioemb_interrupt_enable(fdev); +} + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_int_handler + * Card interrupt callback. + * + * Arguments: + * fdev SDIO context pointer + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +uf_glue_sdio_int_handler(struct sdioemb_dev *fdev) +{ + CsrSdioFunction *sdio_ctx = fdev->drv_data; + CsrSdioInterruptDsrCallback func_dsr_callback; + + /* If the function driver has registered a handler, call it */ + if (sdio_func_drv && sdio_func_drv->intr) { + /* The function driver may return a DSR. */ + func_dsr_callback = sdio_func_drv->intr(sdio_ctx); + /* If it did return a DSR handle, call it */ + if (func_dsr_callback) { + func_dsr_callback(sdio_ctx); + } + } +} + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_probe + * + * Card insert callback. + * + * Arguments: + * fdev SDIO context pointer + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +static int +uf_glue_sdio_probe(struct sdioemb_dev *fdev) +{ + CsrSdioFunction *sdio_ctx; + + unifi_info(NULL, "UniFi card inserted\n"); + + /* Allocate context and private in one lump */ + sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction), + GFP_KERNEL); + if (sdio_ctx == NULL) { + return -ENOMEM; + } + + + sdio_ctx->sdioId.manfId = fdev->vendor_id; + sdio_ctx->sdioId.cardId = fdev->device_id; + sdio_ctx->sdioId.sdioFunction = fdev->function; + sdio_ctx->sdioId.sdioInterface = 0; + sdio_ctx->blockSize = fdev->blocksize; + sdio_ctx->priv = (void *)fdev; + sdio_ctx->features = 0; + + /* Module parameter enables byte mode */ + if (sdio_byte_mode) { + sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE; + } + + /* Set up pointer to func_priv in middle of lump */ + fdev->drv_data = sdio_ctx; + + /* Always override default SDIO bus clock */ + unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock); + sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock); + + /* Call the main UniFi driver inserted handler */ + if (sdio_func_drv && sdio_func_drv->inserted) { + uf_add_os_device(fdev->slot_id, fdev->os_device); + sdio_func_drv->inserted(sdio_ctx); + } + + return 0; +} /* uf_glue_sdio_probe() */ + + +/* + * --------------------------------------------------------------------------- + * uf_sdio_remove + * + * Card removal callback. + * + * Arguments: + * fdev SDIO device + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +static void +uf_sdio_remove(struct sdioemb_dev *fdev) +{ + CsrSdioFunction *sdio_ctx = fdev->drv_data; + + unifi_info(NULL, "UniFi card removed\n"); + + /* Clean up the SDIO function driver */ + if (sdio_func_drv && sdio_func_drv->removed) { + sdio_func_drv->removed(sdio_ctx); + } + + kfree(sdio_ctx); + +} /* uf_sdio_remove */ + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_suspend + * + * System suspend callback. + * + * Arguments: + * fdev SDIO device + * + * Returns: + * + * --------------------------------------------------------------------------- + */ +static void +uf_glue_sdio_suspend(struct sdioemb_dev *fdev) +{ + CsrSdioFunction *sdio_ctx = fdev->drv_data; + + unifi_trace(NULL, UDBG3, "Suspending...\n"); + + /* Pass event to UniFi Driver. */ + if (sdio_func_drv && sdio_func_drv->suspend) { + sdio_func_drv->suspend(sdio_ctx); + } + +} /* uf_glue_sdio_suspend() */ + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_resume + * + * System resume callback. + * + * Arguments: + * fdev SDIO device + * + * Returns: + * + * --------------------------------------------------------------------------- + */ +static void +uf_glue_sdio_resume(struct sdioemb_dev *fdev) +{ + CsrSdioFunction *sdio_ctx = fdev->drv_data; + + unifi_trace(NULL, UDBG3, "Resuming...\n"); + + /* Pass event to UniFi Driver. */ + if (sdio_func_drv && sdio_func_drv->resume) { + sdio_func_drv->resume(sdio_ctx); + } +} /* uf_glue_sdio_resume() */ + + + + +static struct sdioemb_func_driver unifi_sdioemb = { + .name = "unifi", + .id_table = NULL, /* Filled in when main driver registers */ + + .probe = uf_glue_sdio_probe, + .remove = uf_sdio_remove, + .card_int_handler = uf_glue_sdio_int_handler, + .suspend = uf_glue_sdio_suspend, + .resume = uf_glue_sdio_resume, +}; + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionDriverRegister + * CsrSdioFunctionDriverUnregister + * + * These functions are called from the main module load and unload + * functions. They perform the appropriate operations for the + * SDIOemb driver. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv) +{ + int r; + int i; + + printk("Unifi: Using CSR embedded SDIO driver\n"); + + if (sdio_func_drv) { + unifi_error(NULL, "sdio_emb: UniFi driver already registered\n"); + return CSR_SDIO_RESULT_INVALID_VALUE; + } + + /* Build ID table to pass to sdioemb */ + unifi_sdioemb.id_table = CsrPmemAlloc(sizeof(struct sdioemb_id_table) * (sdio_drv->idsCount + 1)); + if (unifi_sdioemb.id_table == NULL) { + unifi_error(NULL, "sdio_emb: Failed to allocate memory for ID table (%d IDs)\n", sdio_drv->idsCount); + return CSR_RESULT_FAILURE; + } + for (i = 0; i < sdio_drv->idsCount; i++) { + unifi_sdioemb.id_table[i].vendor_id = sdio_drv->ids[i].manfId; + unifi_sdioemb.id_table[i].device_id = sdio_drv->ids[i].cardId; + unifi_sdioemb.id_table[i].function = sdio_drv->ids[i].sdioFunction; + unifi_sdioemb.id_table[i].interface = sdio_drv->ids[i].sdioInterface; + } + unifi_sdioemb.id_table[i].vendor_id = 0; + unifi_sdioemb.id_table[i].device_id = 0; + unifi_sdioemb.id_table[i].function = 0; + unifi_sdioemb.id_table[i].interface = 0; + + /* Save the registered driver description */ + sdio_func_drv = sdio_drv; + + /* Register ourself with sdioemb */ + r = sdioemb_driver_register(&unifi_sdioemb); + if (r) { + unifi_error(NULL, "Failed to register UniFi SDIO driver: %d\n", r); + return ConvertSdioToCsrSdioResult(r); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioFunctionDriverRegister() */ + + +void +CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv) +{ + sdioemb_driver_unregister(&unifi_sdioemb); + + sdio_func_drv = NULL; + + CsrPmemFree(unifi_sdioemb.id_table); + unifi_sdioemb.id_table = NULL; +} /* CsrSdioFunctionDriverUnregister() */ + diff --git a/drivers/staging/csr/sdio_events.c b/drivers/staging/csr/sdio_events.c new file mode 100644 index 000000000000..e4f2d0d82fbf --- /dev/null +++ b/drivers/staging/csr/sdio_events.c @@ -0,0 +1,87 @@ +/* + * --------------------------------------------------------------------------- + * FILE: sdio_events.c + * + * PURPOSE: + * Process the events received by the SDIO glue layer. + * Optional part of the porting exercise. + * + * Copyright (C) 2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include "unifi_priv.h" + + +/* + * Porting Notes: + * There are two ways to support the suspend/resume system events in a driver. + * In some operating systems these events are delivered to the OS driver + * directly from the system. In this case, the OS driver needs to pass these + * events to the API described in the CSR SDIO Abstration API document. + * In Linux, and other embedded operating systems, the suspend/resume events + * come from the SDIO driver. In this case, simply get these events in the + * SDIO glue layer and notify the OS layer. + * + * In either case, typically, the events are processed by the SME. + * Use the unifi_sys_suspend_ind() and unifi_sys_resume_ind() to pass + * the events to the SME. + */ + +/* + * --------------------------------------------------------------------------- + * unifi_suspend + * + * Handles a suspend request from the SDIO driver. + * + * Arguments: + * ospriv Pointer to OS driver context. + * + * --------------------------------------------------------------------------- + */ +void unifi_suspend(void *ospriv) +{ + unifi_priv_t *priv = ospriv; + int interfaceTag=0; + + /* Stop network traffic. */ + /* need to stop all the netdevices*/ + for( interfaceTag=0;interfaceTaginterfacePriv[interfaceTag]; + if (interfacePriv->netdev_registered == 1) + { + netif_carrier_off(priv->netdev[interfaceTag]); + UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); + } + } + sme_sys_suspend(priv); +} /* unifi_suspend() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_resume + * + * Handles a resume request from the SDIO driver. + * + * Arguments: + * ospriv Pointer to OS driver context. + * + * --------------------------------------------------------------------------- + */ +void unifi_resume(void *ospriv) +{ + unifi_priv_t *priv = ospriv; + int r; + + r = sme_sys_resume(priv); + if (r) { + unifi_error(priv, "Failed to resume UniFi\n"); + } + +} /* unifi_resume() */ + diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c new file mode 100644 index 000000000000..c8508341597a --- /dev/null +++ b/drivers/staging/csr/sdio_mmc.c @@ -0,0 +1,1165 @@ +/* + * --------------------------------------------------------------------------- + * + * FILE: sdio_mmc.c + * + * PURPOSE: SDIO driver interface for generic MMC stack. + * + * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd. + * + * --------------------------------------------------------------------------- + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "unifi_priv.h" + + +static CsrSdioFunctionDriver *sdio_func_drv; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +/* + * We need to keep track of the power on/off because we can not call + * mmc_power_restore_host() when the card is already powered. + * Even then, we need to patch the MMC driver to add a power_restore handler + * in the mmc_sdio_ops structure. If the MMC driver is not patched, + * mmc_power_save_host() and mmc_power_restore_host() are no-ops. + */ +static int card_is_powered = 1; +#endif /* 2.6.32 */ + +/* MMC uses ENOMEDIUM to indicate card gone away */ + +static CsrResult +ConvertSdioToCsrSdioResult(int r) +{ + CsrResult csrResult = CSR_RESULT_FAILURE; + + switch (r) { + case 0: + csrResult = CSR_RESULT_SUCCESS; + break; + case -EIO: + case -EILSEQ: + csrResult = CSR_SDIO_RESULT_CRC_ERROR; + break; + /* Timeout errors */ + case -ETIMEDOUT: + case -EBUSY: + csrResult = CSR_SDIO_RESULT_TIMEOUT; + break; + case -ENODEV: + case -ENOMEDIUM: + csrResult = CSR_SDIO_RESULT_NO_DEVICE; + break; + case -EINVAL: + csrResult = CSR_SDIO_RESULT_INVALID_VALUE; + break; + case -ENOMEM: + case -ENOSYS: + case -ERANGE: + case -ENXIO: + csrResult = CSR_RESULT_FAILURE; + break; + default: + unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r); + break; + } + + return csrResult; +} + + +static int +csr_io_rw_direct(struct mmc_card *card, int write, uint8_t fn, + uint32_t addr, uint8_t in, uint8_t* out) +{ + struct mmc_command cmd; + int err; + + BUG_ON(!card); + BUG_ON(fn > 7); + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_IO_RW_DIRECT; + cmd.arg = write ? 0x80000000 : 0x00000000; + cmd.arg |= fn << 28; + cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; + cmd.arg |= addr << 9; + cmd.arg |= in; + cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err) + return err; + + /* this function is not exported, so we will need to sort it out here + * for now, lets hard code it to sdio */ + if (0) { + /* old arg (mmc_host_is_spi(card->host)) { */ + /* host driver already reported errors */ + } else { + if (cmd.resp[0] & R5_ERROR) { + printk(KERN_ERR "%s: r5 error 0x%02x\n", + __FUNCTION__, cmd.resp[0]); + return -EIO; + } + if (cmd.resp[0] & R5_FUNCTION_NUMBER) + return -EINVAL; + if (cmd.resp[0] & R5_OUT_OF_RANGE) + return -ERANGE; + } + + if (out) { + if (0) { /* old argument (mmc_host_is_spi(card->host)) */ + *out = (cmd.resp[0] >> 8) & 0xFF; + } + else { + *out = cmd.resp[0] & 0xFF; + } + } + + return CSR_RESULT_SUCCESS; +} + + +CsrResult +CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err = 0; + + _sdio_claim_host(func); + *data = sdio_readb(func, address, &err); + _sdio_release_host(func); + + if (err) { + func_exit_r(err); + return ConvertSdioToCsrSdioResult(err); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioRead8() */ + +CsrResult +CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err = 0; + + _sdio_claim_host(func); + sdio_writeb(func, data, address, &err); + _sdio_release_host(func); + + if (err) { + func_exit_r(err); + return ConvertSdioToCsrSdioResult(err); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioWrite8() */ + +CsrResult +CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err; + uint8_t b0, b1; + + _sdio_claim_host(func); + b0 = sdio_readb(func, address, &err); + if (err) { + _sdio_release_host(func); + return ConvertSdioToCsrSdioResult(err); + } + + b1 = sdio_readb(func, address+1, &err); + if (err) { + _sdio_release_host(func); + return ConvertSdioToCsrSdioResult(err); + } + _sdio_release_host(func); + + *data = ((uint16_t)b1 << 8) | b0; + + return CSR_RESULT_SUCCESS; +} /* CsrSdioRead16() */ + + +CsrResult +CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err; + uint8_t b0, b1; + + _sdio_claim_host(func); + b1 = (data >> 8) & 0xFF; + sdio_writeb(func, b1, address+1, &err); + if (err) { + _sdio_release_host(func); + return ConvertSdioToCsrSdioResult(err); + } + + b0 = data & 0xFF; + sdio_writeb(func, b0, address, &err); + if (err) { + _sdio_release_host(func); + return ConvertSdioToCsrSdioResult(err); + } + + _sdio_release_host(func); + return CSR_RESULT_SUCCESS; +} /* CsrSdioWrite16() */ + + +CsrResult +CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err = 0; + + _sdio_claim_host(func); +#ifdef MMC_QUIRK_LENIENT_FN0 + *data = sdio_f0_readb(func, address, &err); +#else + err = csr_io_rw_direct(func->card, 0, 0, address, 0, data); +#endif + _sdio_release_host(func); + + if (err) { + func_exit_r(err); + return ConvertSdioToCsrSdioResult(err); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioF0Read8() */ + +CsrResult +CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err = 0; + + _sdio_claim_host(func); +#ifdef MMC_QUIRK_LENIENT_FN0 + sdio_f0_writeb(func, data, address, &err); +#else + err = csr_io_rw_direct(func->card, 1, 0, address, data, NULL); +#endif + _sdio_release_host(func); + + if (err) { + func_exit_r(err); + return ConvertSdioToCsrSdioResult(err); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioF0Write8() */ + + +CsrResult +CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err; + + _sdio_claim_host(func); + err = sdio_readsb(func, data, address, length); + _sdio_release_host(func); + + if (err) { + func_exit_r(err); + return ConvertSdioToCsrSdioResult(err); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioRead() */ + +CsrResult +CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err; + + _sdio_claim_host(func); + err = sdio_writesb(func, address, (void*)data, length); + _sdio_release_host(func); + + if (err) { + func_exit_r(err); + return ConvertSdioToCsrSdioResult(err); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioWrite() */ + + +static int +csr_sdio_enable_hs(struct mmc_card *card) +{ + int ret; + u8 speed; + + if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) + return 0; + + if (!card->cccr.high_speed) + return 0; + + ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); + if (ret) + return ret; + + speed |= SDIO_SPEED_EHS; + + ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); + if (ret) + return ret; + + mmc_card_set_highspeed(card); + card->host->ios.timing = MMC_TIMING_SD_HS; + card->host->ops->set_ios(card->host, &card->host->ios); + + return 0; +} + +static int +csr_sdio_disable_hs(struct mmc_card *card) +{ + int ret; + u8 speed; + + if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) + return 0; + + if (!card->cccr.high_speed) + return 0; + + ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); + if (ret) + return ret; + + speed &= ~SDIO_SPEED_EHS; + + ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); + if (ret) + return ret; + + card->state &= ~MMC_STATE_HIGHSPEED; + card->host->ios.timing = MMC_TIMING_LEGACY; + card->host->ops->set_ios(card->host, &card->host->ios); + + return 0; +} + + +/* + * --------------------------------------------------------------------------- + * CsrSdioMaxBusClockFrequencySet + * + * Set the maximum SDIO bus clock speed to use. + * + * Arguments: + * sdio SDIO context pointer + * maxFrequency maximum clock speed in Hz + * + * Returns: + * an error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + struct mmc_host *host = func->card->host; + struct mmc_ios *ios = &host->ios; + unsigned int max_hz; + int err; + CsrUint32 max_khz = maxFrequency/1000; + + if (!max_khz || max_khz > sdio_clock) { + max_khz = sdio_clock; + } + + _sdio_claim_host(func); + max_hz = 1000 * max_khz; + if (max_hz > host->f_max) { + max_hz = host->f_max; + } + + if (max_hz > 25000000) { + err = csr_sdio_enable_hs(func->card); + } else { + err = csr_sdio_disable_hs(func->card); + } + if (err) { + printk(KERN_ERR "SDIO warning: Failed to configure SDIO clock mode\n"); + _sdio_release_host(func); + return CSR_RESULT_SUCCESS; + } + + ios->clock = max_hz; + host->ops->set_ios(host, ios); + + _sdio_release_host(func); + + return CSR_RESULT_SUCCESS; +} /* CsrSdioMaxBusClockFrequencySet() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioInterruptEnable + * CsrSdioInterruptDisable + * + * Enable or disable the SDIO interrupt. + * The driver disables the SDIO interrupt until the i/o thread can + * process it. + * The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE + * register in the Card Common Control Register block, but this requires + * two CMD52 operations. A better solution is to mask the interrupt at + * the host controller. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * Zero on success or a UniFi driver error code. + * + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioInterruptEnable(CsrSdioFunction *function) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err = 0; + +#ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD + sdio_unblock_card_irq(func); +#else + _sdio_claim_host(func); + /* Write the Int Enable in CCCR block */ +#ifdef MMC_QUIRK_LENIENT_FN0 + sdio_f0_writeb(func, 0x3, SDIO_CCCR_IENx, &err); +#else + err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x03, NULL); +#endif + _sdio_release_host(func); + + func_exit(); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } +#endif + return CSR_RESULT_SUCCESS; +} /* CsrSdioInterruptEnable() */ + +CsrResult +CsrSdioInterruptDisable(CsrSdioFunction *function) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err = 0; + +#ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD + sdio_block_card_irq(func); +#else + _sdio_claim_host(func); + /* Write the Int Enable in CCCR block */ +#ifdef MMC_QUIRK_LENIENT_FN0 + sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &err); +#else + err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL); +#endif + _sdio_release_host(func); + + func_exit(); + if (err) { + return ConvertSdioToCsrSdioResult(err); + } +#endif + return CSR_RESULT_SUCCESS; +} /* CsrSdioInterruptDisable() */ + + +void CsrSdioInterruptAcknowledge(CsrSdioFunction *function) +{ +} + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionEnable + * + * Enable i/o on function 1. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioFunctionEnable(CsrSdioFunction *function) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err; + + func_enter(); + + /* Enable UniFi function 1 (the 802.11 part). */ + _sdio_claim_host(func); + err = sdio_enable_func(func); + _sdio_release_host(func); + if (err) { + unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num); + } + + func_exit(); + return ConvertSdioToCsrSdioResult(err); +} /* CsrSdioFunctionEnable() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionDisable + * + * Enable i/o on function 1. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioFunctionDisable(CsrSdioFunction *function) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int err; + + func_enter(); + + /* Disable UniFi function 1 (the 802.11 part). */ + _sdio_claim_host(func); + err = sdio_disable_func(func); + _sdio_release_host(func); + if (err) { + unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num); + } + + func_exit(); + return ConvertSdioToCsrSdioResult(err); +} /* CsrSdioFunctionDisable() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionActive + * + * No-op as the bus goes to an active state at the start of every + * command. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +void +CsrSdioFunctionActive(CsrSdioFunction *function) +{ +} /* CsrSdioFunctionActive() */ + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionIdle + * + * Set the function as idle. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +void +CsrSdioFunctionIdle(CsrSdioFunction *function) +{ +} /* CsrSdioFunctionIdle() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioPowerOn + * + * Power on UniFi. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioPowerOn(CsrSdioFunction *function) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + struct sdio_func *func = (struct sdio_func *)function->priv; + struct mmc_host *host = func->card->host; + + _sdio_claim_host(func); + if (!card_is_powered) { + mmc_power_restore_host(host); + card_is_powered = 1; + } else { + printk(KERN_INFO "SDIO: Skip power on; card is already powered.\n"); + } + _sdio_release_host(func); +#endif /* 2.6.32 */ + + return CSR_RESULT_SUCCESS; +} /* CsrSdioPowerOn() */ + +/* + * --------------------------------------------------------------------------- + * CsrSdioPowerOff + * + * Power off UniFi. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +void +CsrSdioPowerOff(CsrSdioFunction *function) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + struct sdio_func *func = (struct sdio_func *)function->priv; + struct mmc_host *host = func->card->host; + + _sdio_claim_host(func); + if (card_is_powered) { + mmc_power_save_host(host); + card_is_powered = 0; + } else { + printk(KERN_INFO "SDIO: Skip power off; card is already powered off.\n"); + } + _sdio_release_host(func); +#endif /* 2.6.32 */ +} /* CsrSdioPowerOff() */ + + +static int +sdio_set_block_size_ignore_first_error(struct sdio_func *func, unsigned blksz) +{ + int ret; + + if (blksz > func->card->host->max_blk_size) + return -EINVAL; + + if (blksz == 0) { + blksz = min(func->max_blksize, func->card->host->max_blk_size); + blksz = min(blksz, 512u); + } + + /* + * Ignore -ERANGE (OUT_OF_RANGE in R5) on the first byte as + * the block size may be invalid until both bytes are written. + */ + ret = csr_io_rw_direct(func->card, 1, 0, + SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE, + blksz & 0xff, NULL); + if (ret && ret != -ERANGE) + return ret; + ret = csr_io_rw_direct(func->card, 1, 0, + SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1, + (blksz >> 8) & 0xff, NULL); + if (ret) + return ret; + func->cur_blksize = blksz; + + return 0; +} + +CsrResult +CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int r = 0; + + /* Module parameter overrides */ + if (sdio_block_size > -1) { + blockSize = sdio_block_size; + } + + unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n", + blockSize); + + _sdio_claim_host(func); + r = sdio_set_block_size(func, blockSize); + _sdio_release_host(func); + + /* + * The MMC driver for kernels prior to 2.6.32 may fail this request + * with -ERANGE. In this case use our workaround. + */ + if (r == -ERANGE) { + _sdio_claim_host(func); + r = sdio_set_block_size_ignore_first_error(func, blockSize); + _sdio_release_host(func); + } + if (r) { + unifi_error(NULL, "Error %d setting block size\n", r); + } + + /* Determine the achieved block size to pass to the core */ + function->blockSize = func->cur_blksize; + + return ConvertSdioToCsrSdioResult(r); +} /* CsrSdioBlockSizeSet() */ + + +/* + * --------------------------------------------------------------------------- + * CsrSdioHardReset + * + * Hard Resets UniFi is possible. + * + * Arguments: + * sdio SDIO context pointer + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioHardReset(CsrSdioFunction *function) +{ + return CSR_RESULT_FAILURE; +} /* CsrSdioHardReset() */ + + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_int_handler + * + * Interrupt callback function for SDIO interrupts. + * This is called in kernel context (i.e. not interrupt context). + * + * Arguments: + * func SDIO context pointer + * + * Returns: + * None. + * + * Note: Called with host already claimed. + * --------------------------------------------------------------------------- + */ +static void +uf_glue_sdio_int_handler(struct sdio_func *func) +{ + CsrSdioFunction *sdio_ctx; + CsrSdioInterruptDsrCallback func_dsr_callback; + int r; + + sdio_ctx = sdio_get_drvdata(func); + if (!sdio_ctx) { + return; + } +#ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD + /* + * Normally, we are not allowed to do any SDIO commands here. + * However, this is called in a thread context and with the SDIO lock + * so we disable the interrupts here instead of trying to do complicated + * things with the SDIO lock. + */ +#ifdef MMC_QUIRK_LENIENT_FN0 + sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &r); +#else + r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL); +#endif + if (r) { + printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts\n"); + } +#endif + + /* If the function driver has registered a handler, call it */ + if (sdio_func_drv && sdio_func_drv->intr) { + + func_dsr_callback = sdio_func_drv->intr(sdio_ctx); + + /* If interrupt handle returns a DSR handle, call it */ + if (func_dsr_callback) { + func_dsr_callback(sdio_ctx); + } + } + +} /* uf_glue_sdio_int_handler() */ + + + +/* + * --------------------------------------------------------------------------- + * csr_sdio_linux_remove_irq + * + * Unregister the interrupt handler. + * This means that the linux layer can not process interrupts any more. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * Status of the removal. + * --------------------------------------------------------------------------- + */ +int +csr_sdio_linux_remove_irq(CsrSdioFunction *function) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int r; + + sdio_claim_host(func); + r = sdio_release_irq(func); + sdio_release_host(func); + + return r; + +} /* csr_sdio_linux_remove_irq() */ + + +/* + * --------------------------------------------------------------------------- + * csr_sdio_linux_install_irq + * + * Register the interrupt handler. + * This means that the linux layer can process interrupts. + * + * Arguments: + * sdio SDIO context pointer + * + * Returns: + * Status of the removal. + * --------------------------------------------------------------------------- + */ +int +csr_sdio_linux_install_irq(CsrSdioFunction *function) +{ + struct sdio_func *func = (struct sdio_func *)function->priv; + int r; + + /* Register our interrupt handle */ + sdio_claim_host(func); + r = sdio_claim_irq(func, uf_glue_sdio_int_handler); + sdio_release_host(func); + + /* If the interrupt was installed earlier, is fine */ + if (r == -EBUSY) { + r = 0; + } + + return r; +} /* csr_sdio_linux_install_irq() */ + + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_probe + * + * Card insert callback. + * + * Arguments: + * func Our (glue layer) context pointer. + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +static int +uf_glue_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int instance; + CsrSdioFunction *sdio_ctx; + + func_enter(); + + /* First of all claim the SDIO driver */ + sdio_claim_host(func); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + /* Assume that the card is already powered */ + card_is_powered = 1; +#endif + + /* Assumes one card per host, which is true for SDIO */ + instance = func->card->host->index; + printk("sdio bus_id: %16s - UniFi card 0x%X inserted\n", + sdio_func_id(func), instance); + + /* Allocate context */ + sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction), + GFP_KERNEL); + if (sdio_ctx == NULL) { + sdio_release_host(func); + return -ENOMEM; + } + + /* Initialise the context */ + sdio_ctx->sdioId.manfId = func->vendor; + sdio_ctx->sdioId.cardId = func->device; + sdio_ctx->sdioId.sdioFunction = func->num; + sdio_ctx->sdioId.sdioInterface = func->class; + sdio_ctx->blockSize = func->cur_blksize; + sdio_ctx->priv = (void *)func; + sdio_ctx->features = 0; + + /* Module parameter enables byte mode */ + if (sdio_byte_mode) { + sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE; + } + +#ifdef MMC_QUIRK_LENIENT_FN0 + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; +#endif + + /* Pass context to the SDIO driver */ + sdio_set_drvdata(func, sdio_ctx); + + /* Register this device with the SDIO function driver */ + /* Call the main UniFi driver inserted handler */ + if (sdio_func_drv && sdio_func_drv->inserted) { + uf_add_os_device(instance, &func->dev); + sdio_func_drv->inserted(sdio_ctx); + } + + /* We have finished, so release the SDIO driver */ + sdio_release_host(func); + + func_exit(); + return 0; +} /* uf_glue_sdio_probe() */ + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_remove + * + * Card removal callback. + * + * Arguments: + * func Our (glue layer) context pointer. + * + * Returns: + * UniFi driver error code. + * --------------------------------------------------------------------------- + */ +static void +uf_glue_sdio_remove(struct sdio_func *func) +{ + CsrSdioFunction *sdio_ctx; + + sdio_ctx = sdio_get_drvdata(func); + if (!sdio_ctx) { + return; + } + + func_enter(); + + unifi_info(NULL, "UniFi card removed\n"); + + /* Clean up the SDIO function driver */ + if (sdio_func_drv && sdio_func_drv->removed) { + uf_remove_os_device(func->card->host->index); + sdio_func_drv->removed(sdio_ctx); + } + + kfree(sdio_ctx); + + func_exit(); + +} /* uf_glue_sdio_remove */ + + +/* + * SDIO ids *must* be statically declared, so we can't take + * them from the list passed in csr_sdio_register_driver(). + */ +static const struct sdio_device_id unifi_ids[] = { + { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_3) }, + { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_4) }, + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(sdio, unifi_ids); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#ifdef CONFIG_PM + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_suspend + * + * Card suspend callback. + * + * Arguments: + * dev The struct device owned by the MMC driver + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +static int +uf_glue_sdio_suspend(struct device *dev) +{ + struct sdio_func *func; + CsrSdioFunction *sdio_ctx; + + func_enter(); + + func = dev_to_sdio_func(dev); + WARN_ON(!func); + + sdio_ctx = sdio_get_drvdata(func); + WARN_ON(!sdio_ctx); + + unifi_trace(NULL, UDBG1, "System Suspend...\n"); + + /* Clean up the SDIO function driver */ + if (sdio_func_drv && sdio_func_drv->suspend) { + sdio_func_drv->suspend(sdio_ctx); + } + + func_exit(); + return 0; +} /* uf_glue_sdio_suspend */ + + +/* + * --------------------------------------------------------------------------- + * uf_glue_sdio_resume + * + * Card resume callback. + * + * Arguments: + * dev The struct device owned by the MMC driver + * + * Returns: + * None + * --------------------------------------------------------------------------- + */ +static int +uf_glue_sdio_resume(struct device *dev) +{ + struct sdio_func *func; + CsrSdioFunction *sdio_ctx; + + func_enter(); + + func = dev_to_sdio_func(dev); + WARN_ON(!func); + + sdio_ctx = sdio_get_drvdata(func); + WARN_ON(!sdio_ctx); + + unifi_trace(NULL, UDBG1, "System Resume...\n"); + + /* Clean up the SDIO function driver */ + if (sdio_func_drv && sdio_func_drv->resume) { + sdio_func_drv->resume(sdio_ctx); + } + + func_exit(); + return 0; + +} /* uf_glue_sdio_resume */ + +static struct dev_pm_ops unifi_pm_ops = { + .suspend = uf_glue_sdio_suspend, + .resume = uf_glue_sdio_resume, +}; + +#define UNIFI_PM_OPS (&unifi_pm_ops) + +#else + +#define UNIFI_PM_OPS NULL + +#endif /* CONFIG_PM */ +#endif /* 2.6.32 */ + +static struct sdio_driver unifi_driver = { + .probe = uf_glue_sdio_probe, + .remove = uf_glue_sdio_remove, + .name = "unifi", + .id_table = unifi_ids, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + .drv.pm = UNIFI_PM_OPS, +#endif /* 2.6.32 */ +}; + + +/* + * --------------------------------------------------------------------------- + * CsrSdioFunctionDriverRegister + * CsrSdioFunctionDriverUnregister + * + * These functions are called from the main module load and unload + * functions. They perform the appropriate operations for the + * linux MMC/SDIO driver. + * + * Arguments: + * sdio_drv Pointer to the function driver's SDIO structure. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +CsrResult +CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv) +{ + int r; + + printk("UniFi: Using native Linux MMC driver for SDIO.\n"); + + if (sdio_func_drv) { + unifi_error(NULL, "sdio_mmc: UniFi driver already registered\n"); + return CSR_SDIO_RESULT_INVALID_VALUE; + } + + /* Save the registered driver description */ + /* + * FIXME: + * Need a table here to handle a call to register for just one function. + * mmc only allows us to register for the whole device + */ + sdio_func_drv = sdio_drv; + + /* Register ourself with mmc_core */ + r = sdio_register_driver(&unifi_driver); + if (r) { + printk(KERN_ERR "unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r); + return ConvertSdioToCsrSdioResult(r); + } + + return CSR_RESULT_SUCCESS; +} /* CsrSdioFunctionDriverRegister() */ + + + +void +CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv) +{ + printk(KERN_INFO "UniFi: unregister from MMC sdio\n"); + sdio_unregister_driver(&unifi_driver); + + sdio_func_drv = NULL; + +} /* CsrSdioFunctionDriverUnregister() */ + diff --git a/drivers/staging/csr/sdio_stubs.c b/drivers/staging/csr/sdio_stubs.c new file mode 100644 index 000000000000..bc6a3697c000 --- /dev/null +++ b/drivers/staging/csr/sdio_stubs.c @@ -0,0 +1,82 @@ +/* + * Stubs for some of the bottom edge functions. + * + * These stubs are optional functions in the bottom edge (SDIO driver + * interface) API that not all platforms or SDIO drivers may support. + * + * They're declared as weak symbols so they can be overridden by + * simply providing a non-weak declaration. + * + * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + */ +#include "csr_wifi_hip_unifi.h" + +void __attribute__((weak)) CsrSdioFunctionIdle(CsrSdioFunction *function) +{ +} + +void __attribute__((weak)) CsrSdioFunctionActive(CsrSdioFunction *function) +{ +} + +CsrResult __attribute__((weak)) CsrSdioPowerOn(CsrSdioFunction *function) +{ + return CSR_RESULT_SUCCESS; +} + +void __attribute__((weak)) CsrSdioPowerOff(CsrSdioFunction *function) +{ +} + +CsrResult __attribute__((weak)) CsrSdioHardReset(CsrSdioFunction *function) +{ + return CSR_SDIO_RESULT_NOT_RESET; +} + +CsrResult __attribute__((weak)) CsrSdioBlockSizeSet(CsrSdioFunction *function, + CsrUint16 blockSize) +{ + return CSR_RESULT_SUCCESS; +} + +CsrResult __attribute__((weak)) CsrSdioSuspend(CsrSdioFunction *function) +{ + return CSR_RESULT_SUCCESS; +} + +CsrResult __attribute__((weak)) CsrSdioResume(CsrSdioFunction *function) +{ + return CSR_RESULT_SUCCESS; +} + +int __attribute__((weak)) csr_sdio_linux_install_irq(CsrSdioFunction *function) +{ + return 0; +} + +int __attribute__((weak)) csr_sdio_linux_remove_irq(CsrSdioFunction *function) +{ + return 0; +} + +void __attribute__((weak)) CsrSdioInsertedAcknowledge(CsrSdioFunction *function, CsrResult result) +{ +} + +void __attribute__((weak)) CsrSdioRemovedAcknowledge(CsrSdioFunction *function) +{ +} + +void __attribute__((weak)) CsrSdioSuspendAcknowledge(CsrSdioFunction *function, CsrResult result) +{ +} + +void __attribute__((weak)) CsrSdioResumeAcknowledge(CsrSdioFunction *function, CsrResult result) +{ +} + + diff --git a/drivers/staging/csr/sdioemb/cspi.h b/drivers/staging/csr/sdioemb/cspi.h new file mode 100644 index 000000000000..b0a2886970ab --- /dev/null +++ b/drivers/staging/csr/sdioemb/cspi.h @@ -0,0 +1,62 @@ +/* + * CSPI definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef SDIOEMB_CSPI_H +#define SDIOEMB_CSPI_H + +/** + * @addtogroup sdriver + *@{*/ + +#define CSPI_FUNC(f) (f) +#define CSPI_READ 0x10 +#define CSPI_WRITE 0x20 +#define CSPI_BURST 0x40 +#define CSPI_TYPE_MASK 0x70 + +/** + * CSPI_MODE function 0 register. + * + * Various CSPI mode settings. + * + * @see CSPI specification (CS-110124-SP) + */ +#define CSPI_MODE 0xf7 +# define CSPI_MODE_PADDED_WRITE_HDRS (1 << 7) +# define CSPI_MODE_PADDED_READ_HDRS (1 << 6) +/** + * BigEndianRegisters bit of \ref CSPI_MODE -- enable big-endian CSPI + * register reads and writes. + * + * @warning This bit should never be set as it's not possible to use + * this mode without knowledge of which registers are 8 bit and which + * are 16 bit. + */ +# define CSPI_MODE_BE_REG (1 << 5) +# define CSPI_MODE_BE_BURST (1 << 4) +# define CSPI_MODE_INT_ACTIVE_HIGH (1 << 3) +# define CSPI_MODE_INT_ON_ERR (1 << 2) +# define CSPI_MODE_LEN_FIELD_PRESENT (1 << 1) +# define CSPI_MODE_DRV_MISO_ON_RISING_CLK (1 << 0) + +#define CSPI_STATUS 0xf8 + +#define CSPI_PADDING 0xf9 +# define CSPI_PADDING_REG(p) ((p) << 0) +# define CSPI_PADDING_BURST(p) ((p) << 4) + +#define CSPI_PADDING_MAX 15 +#define CSPI_PADDING_REG_DFLT 0 +#define CSPI_PADDING_BURST_DFLT 2 + +/* cmd byte, 3 byte addr, padding, error byte, data word */ +#define CSPI_REG_TRANSFER_LEN (1 + 3 + CSPI_PADDING_MAX + 1 + 2) + +/*@}*/ + +#endif /* #ifndef SDIOEMB_CSPI_H */ diff --git a/drivers/staging/csr/sdioemb/csr_result.h b/drivers/staging/csr/sdioemb/csr_result.h new file mode 100644 index 000000000000..9813f3f86ee6 --- /dev/null +++ b/drivers/staging/csr/sdioemb/csr_result.h @@ -0,0 +1,16 @@ +/* + * Synergy compatible API -- common result codes. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef CSR_RESULT_H__ +#define CSR_RESULT_H__ + +typedef CsrUint16 CsrResult; +#define CSR_RESULT_SUCCESS ((CsrResult) 0x0000) +#define CSR_RESULT_FAILURE ((CsrResult) 0xffff) + +#endif diff --git a/drivers/staging/csr/sdioemb/csr_sdio.h b/drivers/staging/csr/sdioemb/csr_sdio.h new file mode 100644 index 000000000000..5d05d96d3958 --- /dev/null +++ b/drivers/staging/csr/sdioemb/csr_sdio.h @@ -0,0 +1,711 @@ +/* + * Synergy compatible API -- SDIO. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef CSR_SDIO_H__ +#define CSR_SDIO_H__ + +#include "csr_types.h" +#include "csr_result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Result Codes */ +#define CSR_SDIO_RESULT_INVALID_VALUE ((CsrResult) 1) /* Invalid argument value */ +#define CSR_SDIO_RESULT_NO_DEVICE ((CsrResult) 2) /* The specified device is no longer present */ +#define CSR_SDIO_RESULT_CRC_ERROR ((CsrResult) 3) /* The transmitted/received data or command response contained a CRC error */ +#define CSR_SDIO_RESULT_TIMEOUT ((CsrResult) 4) /* No command response or data received from device, or function enable/disable did not succeed within timeout period */ +#define CSR_SDIO_RESULT_NOT_RESET ((CsrResult) 5) /* The device was not reset */ + +/* Features (for use in features member of CsrSdioFunction) */ +#define CSR_SDIO_FEATURE_BYTE_MODE 0x00000001 /* Transfer sizes do not have to be a multiple of block size */ +#define CSR_SDIO_FEATURE_DMA_CAPABLE_MEM_REQUIRED 0x00000002 /* Bulk operations require DMA friendly memory */ + +/* CsrSdioFunctionId wildcards (for use in CsrSdioFunctionId members) */ +#define CSR_SDIO_ANY_MANF_ID 0xFFFF +#define CSR_SDIO_ANY_CARD_ID 0xFFFF +#define CSR_SDIO_ANY_SDIO_FUNCTION 0xFF +#define CSR_SDIO_ANY_SDIO_INTERFACE 0xFF + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionId + * + * DESCRIPTION + * This structure describes one or more functions of a device, based on + * four qualitative measures. The CsrSdioFunctionId wildcard defines can be + * used for making the CsrSdioFunctionId match more than one function. + * + * MEMBERS + * manfId - Vendor ID (or CSR_SDIO_ANY_MANF_ID). + * cardId - Device ID (or CSR_SDIO_ANY_CARD_ID). + * sdioFunction - SDIO Function number (or CSR_SDIO_ANY_SDIO_FUNCTION). + * sdioInterface - SDIO Standard Interface Code (or CSR_SDIO_ANY_SDIO_INTERFACE) + * + *----------------------------------------------------------------------------*/ +typedef struct +{ + CsrUint16 manfId; /* Vendor ID to match or CSR_SDIO_ANY_MANF_ID */ + CsrUint16 cardId; /* Device ID to match or CSR_SDIO_ANY_CARD_ID */ + CsrUint8 sdioFunction; /* SDIO Function number to match or CSR_SDIO_ANY_SDIO_FUNCTION */ + CsrUint8 sdioInterface; /* SDIO Standard Interface Code to match or CSR_SDIO_ANY_SDIO_INTERFACE */ +} CsrSdioFunctionId; + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunction + * + * DESCRIPTION + * This structure represents a single function on a device. + * + * MEMBERS + * sdioId - A CsrSdioFunctionId describing this particular function. The + * subfield shall not contain any CsrSdioFunctionId wildcards. The + * subfields shall describe the specific single function + * represented by this structure. + * blockSize - Actual configured block size, or 0 if unconfigured. + * features - Bit mask with any of CSR_SDIO_FEATURE_* set. + * driverData - For use by the Function Driver. The SDIO Driver shall not + * attempt to dereference the pointer. + * priv - For use by the SDIO Driver. The Function Driver shall not attempt + * to dereference the pointer. + * + *----------------------------------------------------------------------------*/ +typedef struct +{ + CsrSdioFunctionId sdioId; + CsrUint16 blockSize; /* Actual configured block size, or 0 if unconfigured */ + CsrUint32 features; /* Bit mask with any of CSR_SDIO_FEATURE_* set */ + void *cardHandle; /* An opaque handle for this function's card. */ + void *osDevice; + void *driverData; /* For use by the Function Driver */ + void *priv; /* For use by the SDIO Driver */ +} CsrSdioFunction; + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInsertedCallback, CsrSdioRemovedCallback + * + * DESCRIPTION + * CsrSdioInsertedCallback is called when a function becomes available to + * a registered Function Driver that supports the function. + * CsrSdioRemovedCallback is called when a function is no longer available + * to a Function Driver, either because the device has been removed, or the + * Function Driver has been unregistered. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the CsrSdioFunctionDriver struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioInsertedCallback)(CsrSdioFunction *function); +typedef void (*CsrSdioRemovedCallback)(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInterruptDsrCallback, CsrSdioInterruptCallback + * + * DESCRIPTION + * CsrSdioInterruptCallback is called when an interrupt occurs on the + * the device associated with the specified function. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the CsrSdioFunctionDriver struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + * RETURNS (only CsrSdioInterruptCallback) + * A pointer to a CsrSdioInterruptDsrCallback function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioInterruptDsrCallback)(CsrSdioFunction *function); +typedef CsrSdioInterruptDsrCallback (*CsrSdioInterruptCallback)(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioSuspendCallback, CsrSdioResumeCallback + * + * DESCRIPTION + * CsrSdioSuspendCallback is called when the system is preparing to go + * into a suspended state. CsrSdioResumeCallback is called when the system + * has entered an active state again. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the CsrSdioFunctionDriver struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioSuspendCallback)(CsrSdioFunction *function); +typedef void (*CsrSdioResumeCallback)(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioAsyncCallback, CsrSdioAsyncDsrCallback + * + * DESCRIPTION + * CsrSdioAsyncCallback is called when an asynchronous operation completes. + * + * NOTE: These functions are implemented by the Function Driver, and are + * passed as function pointers in the function calls that initiate + * the operation. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * result - The result of the operation that completed. See the description + * of the initiating function for possible result values. + * + * RETURNS (only CsrSdioAsyncCallback) + * A pointer to a CsrSdioAsyncDsrCallback function. + * + *----------------------------------------------------------------------------*/ +typedef void (*CsrSdioAsyncDsrCallback)(CsrSdioFunction *function, CsrResult result); +typedef CsrSdioAsyncDsrCallback (*CsrSdioAsyncCallback)(CsrSdioFunction *function, CsrResult result); + +typedef struct +{ + CsrSdioInsertedCallback inserted; + CsrSdioRemovedCallback removed; + CsrSdioInterruptCallback intr; + CsrSdioSuspendCallback suspend; + CsrSdioResumeCallback resume; + CsrSdioFunctionId *ids; + CsrUint8 idsCount; + void *priv; +} CsrSdioFunctionDriver; + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionDriverRegister + * + * DESCRIPTION + * Register a Function Driver. + * + * PARAMETERS + * functionDriver - Pointer to struct describing the Function Driver. + * + * RETURNS + * CSR_RESULT_SUCCESS - The Function Driver was successfully + * registered. + * CSR_RESULT_FAILURE - Unable to register the function driver, + * because of an unspecified/unknown error. The + * Function Driver has not been registered. + * CSR_SDIO_RESULT_INVALID_VALUE - The specified Function Driver pointer + * does not point at a valid Function + * Driver structure, or some of the members + * contain invalid entries. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *functionDriver); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionDriverUnregister + * + * DESCRIPTION + * Unregister a previously registered Function Driver. + * + * PARAMETERS + * functionDriver - pointer to struct describing the Function Driver. + * + *----------------------------------------------------------------------------*/ +void CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *functionDriver); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionEnable, CsrSdioFunctionDisable + * + * DESCRIPTION + * Enable/disable the specified function by setting/clearing the + * corresponding bit in the I/O Enable register in function 0, and then + * periodically reading the related bit in the I/O Ready register until it + * is set/clear, limited by an implementation defined timeout. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + * RETURNS + * CSR_RESULT_SUCCESS - The specified function was enabled/disabled. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The state of the + * related bit in the I/O Enable register is + * undefined. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device, or the related + * bit in the I/O ready register was not + * set/cleared within the timeout period. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioFunctionEnable(CsrSdioFunction *function); +CsrResult CsrSdioFunctionDisable(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInterruptEnable, CsrSdioInterruptDisable + * + * DESCRIPTION + * Enable/disable the interrupt for the specified function by + * setting/clearing the corresponding bit in the INT Enable register in + * function 0. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + * RETURNS + * CSR_RESULT_SUCCESS - The specified function was enabled/disabled. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The state of the + * related bit in the INT Enable register is + * unchanged. + * CSR_SDIO_RESULT_INVALID_VALUE - The specified function cannot be + * enabled/disabled, because it either + * does not exist or it is not possible to + * individually enable/disable functions. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioInterruptEnable(CsrSdioFunction *function); +CsrResult CsrSdioInterruptDisable(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInterruptAcknowledge + * + * DESCRIPTION + * Acknowledge that a signalled interrupt has been handled. Shall only + * be called once, and exactly once for each signalled interrupt to the + * corresponding function. + * + * PARAMETERS + * function - Pointer to struct representing the function to which the + * event was signalled. + * + *----------------------------------------------------------------------------*/ +void CsrSdioInterruptAcknowledge(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioInsertedAcknowledge, CsrSdioRemovedAcknowledge + * + * DESCRIPTION + * Acknowledge that a signalled inserted/removed event has been handled. + * Shall only be called once, and exactly once for each signalled event to + * the corresponding function. + * + * PARAMETERS + * function - Pointer to struct representing the function to which the + * inserted was signalled. + * result (CsrSdioInsertedAcknowledge only) + * CSR_RESULT_SUCCESS - The Function Driver has accepted the + * function, and the function is attached to + * the Function Driver until the + * CsrSdioRemovedCallback is called and + * acknowledged. + * CSR_RESULT_FAILURE - Unable to accept the function. The + * function is not attached to the Function + * Driver, and it may be passed to another + * Function Driver which supports the + * function. + * + *----------------------------------------------------------------------------*/ +void CsrSdioInsertedAcknowledge(CsrSdioFunction *function, CsrResult result); +void CsrSdioRemovedAcknowledge(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioSuspendAcknowledge, CsrSdioResumeAcknowledge + * + * DESCRIPTION + * Acknowledge that a signalled suspend event has been handled. Shall only + * be called once, and exactly once for each signalled event to the + * corresponding function. + * + * PARAMETERS + * function - Pointer to struct representing the function to which the + * event was signalled. + * result + * CSR_RESULT_SUCCESS - Successfully suspended/resumed. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * + *----------------------------------------------------------------------------*/ +void CsrSdioSuspendAcknowledge(CsrSdioFunction *function, CsrResult result); +void CsrSdioResumeAcknowledge(CsrSdioFunction *function, CsrResult result); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioBlockSizeSet + * + * DESCRIPTION + * Set the block size to use for the function. The actual configured block + * size shall be the minimum of: + * 1) Maximum block size supported by the function. + * 2) Maximum block size supported by the host controller. + * 3) The block size specified by the blockSize argument. + * + * When this function returns, the actual configured block size is + * available in the blockSize member of the function struct. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * blockSize - Block size to use for the function. Valid range is 1 to + * 2048. + * + * RETURNS + * CSR_RESULT_SUCCESS - The block size register on the chip + * was updated. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The configured block + * size is undefined. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER + * bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned. + * If the ERROR bit is set (but not FUNCTION_NUMBER), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: Setting the block size requires two individual operations. The + * implementation shall ignore the OUT_OF_RANGE bit of the SDIO R5 + * response for the first operation, as the partially configured + * block size may be out of range, even if the final block size + * (after the second operation) is in the valid range. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioMaxBusClockFrequencySet + * + * DESCRIPTION + * Set the maximum clock frequency to use for the device associated with + * the specified function. The actual configured clock frequency for the + * device shall be the minimum of: + * 1) Maximum clock frequency supported by the device. + * 2) Maximum clock frequency supported by the host controller. + * 3) Maximum clock frequency specified for any function on the same + * device. + * + * If the clock frequency exceeds 25MHz, it is the responsibility of the + * SDIO driver to enable high speed mode on the device, using the standard + * defined procedure, before increasing the frequency beyond the limit. + * + * Note that the clock frequency configured affects all functions on the + * same device. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * maxFrequency - The maximum clock frequency for the function in Hertz. + * + * RETURNS + * CSR_RESULT_SUCCESS - The maximum clock frequency was succesfully + * set for the function. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * + * NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER + * bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned. + * If the ERROR bit is set (but not FUNCTION_NUMBER), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioRead8, CsrSdioWrite8, CsrSdioRead8Async, CsrSdioWrite8Async + * + * DESCRIPTION + * Read/write an 8bit value from/to the specified register address. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. No data read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioRead8Async and CsrSdioWrite8Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data); +CsrResult CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data); +void CsrSdioRead8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data, CsrSdioAsyncCallback callback); +void CsrSdioWrite8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioRead16, CsrSdioWrite16, CsrSdioRead16Async, CsrSdioWrite16Async + * + * DESCRIPTION + * Read/write a 16bit value from/to the specified register address. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. Data may have been + * partially read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioRead16Async and CsrSdioWrite16Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data); +CsrResult CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data); +void CsrSdioRead16Async(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data, CsrSdioAsyncCallback callback); +void CsrSdioWrite16Async(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioF0Read8, CsrSdioF0Write8, CsrSdioF0Read8Async, + * CsrSdioF0Write8Async + * + * DESCRIPTION + * Read/write an 8bit value from/to the specified register address in + * function 0. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. No data read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data); +CsrResult CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data); +void CsrSdioF0Read8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data, CsrSdioAsyncCallback callback); +void CsrSdioF0Write8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioRead, CsrSdioWrite, CsrSdioReadAsync, CsrSdioWriteAsync + * + * DESCRIPTION + * Read/write a specified number of bytes from/to the specified register + * address. + * + * PARAMETERS + * function - Pointer to struct representing the function. + * address - Register address within the function. + * data - The data to read/write. + * length - Number of byte to read/write. + * callback - The function to call on operation completion. + * + * RETURNS + * CSR_RESULT_SUCCESS - The data was successfully read/written. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. Data may have been + * partially read/written. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device. + * + * NOTE: If the SDIO R5 response is available, and either of the + * FUNCTION_NUMBER or OUT_OF_RANGE bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit + * is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE), + * CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and + * COM_CRC_ERROR bits shall be ignored. + * + * If the CSPI response is available, and any of the + * FUNCTION_DISABLED or CLOCK_DISABLED bits are set, + * CSR_SDIO_RESULT_INVALID_VALUE will be returned. + * + * NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return + * immediately, and the supplied callback function is called when the + * operation is complete. The result value is given as an argument to + * the callback function. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length); +CsrResult CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length); +void CsrSdioReadAsync(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length, CsrSdioAsyncCallback callback); +void CsrSdioWriteAsync(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length, CsrSdioAsyncCallback callback); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioPowerOn, CsrSdioPowerOff + * + * DESCRIPTION + * Power on/off the device. + * + * PARAMETERS + * function - Pointer to struct representing the function that resides on + * the device to power on/off. + * + * RETURNS (only CsrSdioPowerOn) + * CSR_RESULT_SUCCESS - Power was succesfully reapplied and the device + * has been reinitialised. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured during reinitialisation. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device during + * reinitialisation. + * CSR_SDIO_RESULT_NOT_RESET - The power was not removed by the + * CsrSdioPowerOff call. The state of the + * device is unchanged. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioPowerOn(CsrSdioFunction *function); +void CsrSdioPowerOff(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioHardReset + * + * DESCRIPTION + * Perform a hardware reset of the device. + * + * PARAMETERS + * function - Pointer to struct representing the function that resides on + * the device to hard reset. + * + * RETURNS + * CSR_RESULT_SUCCESS - Reset was succesfully performed and the device + * has been reinitialised. + * CSR_RESULT_FAILURE - Unspecified/unknown error. + * CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore. + * CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured during reinitialisation. + * CSR_SDIO_RESULT_TIMEOUT - No response from the device during + * reinitialisation. + * CSR_SDIO_RESULT_NOT_RESET - The reset was not applied because it is not + * supported. The state of the device is + * unchanged. + * + *----------------------------------------------------------------------------*/ +CsrResult CsrSdioHardReset(CsrSdioFunction *function); + +/*----------------------------------------------------------------------------* + * NAME + * CsrSdioFunctionActive, CsrSdioFunctionIdle + * + * DESCRIPTION + * + * PARAMETERS + * function - Pointer to struct representing the function. + * + *----------------------------------------------------------------------------*/ +void CsrSdioFunctionActive(CsrSdioFunction *function); +void CsrSdioFunctionIdle(CsrSdioFunction *function); + +void CsrSdioCallbackInhibitEnter(CsrSdioFunction *function); +void CsrSdioCallbackInhibitLeave(CsrSdioFunction *function); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/staging/csr/sdioemb/csr_sdio_lib.h b/drivers/staging/csr/sdioemb/csr_sdio_lib.h new file mode 100644 index 000000000000..15c70f6e716c --- /dev/null +++ b/drivers/staging/csr/sdioemb/csr_sdio_lib.h @@ -0,0 +1,30 @@ +/* + * Synergy compatible API -- SDIO utility library. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef CSR_SDIO_LIB_H__ +#define CSR_SDIO_LIB_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +CsrResult CsrSdioFunctionReenable(CsrSdioFunction *function); + +typedef int CsrStatus; /* platform specific */ +#define CSR_STATUS_FAILURE(status) ((status) < 0) /* platform specific */ + +CsrResult CsrSdioStatusToResult(CsrStatus status); +CsrStatus CsrSdioResultToStatus(CsrResult result); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* #ifndef CSR_SDIO_LIB_H__ */ diff --git a/drivers/staging/csr/sdioemb/csr_sdio_wdf.h b/drivers/staging/csr/sdioemb/csr_sdio_wdf.h new file mode 100644 index 000000000000..6f0d71c47336 --- /dev/null +++ b/drivers/staging/csr/sdioemb/csr_sdio_wdf.h @@ -0,0 +1,22 @@ +/* + * Synergy compatible API -- helpers for Windows Driver Framework drivers. + * + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef CSR_SDIO_WDF_H__ +#define CSR_SDIO_WDF_H__ + +#include + +NTSTATUS CsrSdioWdfDeviceInit(WDFDEVICE device); +void CsrSdioWdfDeviceCleanup(WDFDEVICE device); + +NTSTATUS CsrSdioWdfDeviceAdd(WDFDEVICE device); +void CsrSdioWdfDeviceDel(WDFDEVICE device); + +NTSTATUS CsrSdioWdfDeviceSuspend(WDFDEVICE device); +NTSTATUS CsrSdioWdfDeviceResume(WDFDEVICE device); + +#endif /* #ifndef CSR_SDIO_WDF_H__ */ diff --git a/drivers/staging/csr/sdioemb/csr_types.h b/drivers/staging/csr/sdioemb/csr_types.h new file mode 100644 index 000000000000..c0d95b33e758 --- /dev/null +++ b/drivers/staging/csr/sdioemb/csr_types.h @@ -0,0 +1,53 @@ +/* + * Synergy compatible API -- basic types. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef CSR_TYPES_H__ +#define CSR_TYPES_H__ + +#include + +#ifndef FALSE +#define FALSE false +#endif + +#ifndef TRUE +#define TRUE true +#endif + +/* Data types */ + +typedef size_t CsrSize; + +typedef uint8_t CsrUint8; +typedef uint16_t CsrUint16; +typedef uint32_t CsrUint32; + +typedef int8_t CsrInt8; +typedef int16_t CsrInt16; +typedef int32_t CsrInt32; + +typedef bool CsrBool; + +typedef char CsrCharString; +typedef unsigned char CsrUtf8String; +typedef CsrUint16 CsrUtf16String; /* 16-bit UTF16 strings */ +typedef CsrUint32 CsrUint24; + +/* + * 64-bit integers + * + * Note: If a given compiler does not support 64-bit types, it is + * OK to omit these definitions; 32-bit versions of the code using + * these types may be available. Consult the relevant documentation + * or the customer support group for information on this. + */ +#define CSR_HAVE_64_BIT_INTEGERS +typedef uint64_t CsrUint64; +typedef int64_t CsrInt64; + +#endif diff --git a/drivers/staging/csr/sdioemb/libsdio.h b/drivers/staging/csr/sdioemb/libsdio.h new file mode 100644 index 000000000000..29ac4115d60a --- /dev/null +++ b/drivers/staging/csr/sdioemb/libsdio.h @@ -0,0 +1,404 @@ +/* + * SDIO Userspace Interface library. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef SDIOEMB_LIBSDIO_H +#define SDIOEMB_LIBSDIO_H + +/** + * \defgroup libsdio Userspace SDIO library (libsdio) + * + * \brief \e libsdio is a Linux C library for accessing SDIO cards. + * + * Use of this library requires several \e sdioemb kernel modules to be + * loaded: + * - \c sdio. + * - \c An SDIO slot driver (e.g., \c slot_shc for a standard PCI + * SDIO Host Controller). + * - \c sdio_uif which provides the required character devices + * (/dev/sdio_uif0 for the card in SDIO slot 0 etc.). + */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +# define LIBSDIOAPI __stdcall +#else +# define LIBSDIOAPI +#endif + +struct sdio_uif; + +/** + * Handle to an opened SDIO Userspace Interface device. + */ +typedef struct sdio_uif *sdio_uif_t; + +enum sdio_status { + SDIO_SUCCESS = 0, + SDIO_EAGAIN = -1, + SDIO_EINVAL = -2, + SDIO_EIO = -3, + SDIO_ENODEV = -4, + SDIO_ENOMEM = -5, + SDIO_ENOTSUPP = -6, + SDIO_ENXIO = -7, + SDIO_ETIMEDOUT = -8, +}; + +/** + * Card interrupt handler function. + * + * @param uif handle to the interrupting device. + * @param arg data supplied by the caller of sdio_open(). + */ +typedef void (LIBSDIOAPI *sdio_int_handler_t)(sdio_uif_t uif, void *arg); + +/** + * Asynchronous IO completion callback function. + * + * @param uif handle to the device that completed the IO operation. + * @param arg data supplied by the caller of the asynchronous IO operation. + * @param status status of the IO operation. 0 is success; -EIO, + * -EINVAL, -ETIMEDOUT etc. on an error. + */ +typedef void (LIBSDIOAPI *sdio_io_callback_t)(sdio_uif_t uif, void *arg, int status); + +/** + * Open a SDIO Userspace Interface device and (optionally) register a + * card interrupt handler and enable card interrupts. + * + * Card interrupts are masked before calling int_handler and are + * unmasked when int_handler returns (unless sdio_interrupt_mask() is + * called). + * + * @param dev_filename filename of the device to open. + * @param int_handler card interrupt handler; or NULL if no + * interrupt handler is required. + * @param arg argument to be passed to the interrupt handler. + * + * @return handle to the opened device; or NULL on error with errno + * set. + */ +sdio_uif_t LIBSDIOAPI sdio_open(const char *dev_filename, + sdio_int_handler_t int_handler, void *arg); + +/** + * Mask the SDIO interrupt. + * + * Call this in an interrupt handler to allow the processing of + * interrupts to be deferred until after the interrupt handler has + * returned. + * + * @note \e Must only be called from within the interrupt handler + * registered with sdio_open(). + * + * @param uif device handle. + */ +void LIBSDIOAPI sdio_interrupt_mask(sdio_uif_t uif); + +/** + * Unmask the SDIO interrupt. + * + * Unmasks the SDIO interrupt if it had previously been masked with + * sdio_interrupt_mask(). + * + * @param uif device handle. + */ +void LIBSDIOAPI sdio_interrupt_unmask(sdio_uif_t uif); + +/** + * Close an opened SDIO Userspace Interface device, freeing all + * associated resources. + * + * @param uif handle to the device. + */ +void LIBSDIOAPI sdio_close(sdio_uif_t uif); + +/** + * Return the number of functions the card has. + * + * @param uif device handle. + * + * @return number of card functions. + */ +int LIBSDIOAPI sdio_num_functions(sdio_uif_t uif); + +/** + * Set an SDIO bus to 1 bit or 4 bit wide mode. + * + * The CCCR bus interface control register will be read and rewritten + * with the new bus width. + * + * @param uif device handle. + * @param bus_width bus width (1 or 4). + * + * @return 0 on success; -ve on error with errno set. + * + * @note The card capabilities are \e not checked. The user should + * ensure 4 bit mode is not enabled on a card that does not support + * it. + */ +int LIBSDIOAPI sdio_set_bus_width(sdio_uif_t uif, int bus_width); + +/** + * Limit the frequency of (or stop) the SD bus clock. + * + * The frequency cannot be set greater than that supported by the card + * or the controller. + * + * @note Stopping the bus clock while other device drivers are + * executing commands may result in those commands not completing + * until the bus clock is restarted. + * + * @param uif device handle. + * @param max_freq maximum frequency (Hz) or 0 to stop the bus clock + * until the start of the next command. + */ +void LIBSDIOAPI sdio_set_max_bus_freq(sdio_uif_t uif, int max_freq); + +/** + * Return the card's manufacturer (vendor) ID. + * + * @param uif device handle. + * + * @return manufacturer ID. + */ +uint16_t LIBSDIOAPI sdio_manf_id(sdio_uif_t uif); + +/** + * Return the card's card (device) ID. + * + * @param uif device handle. + * + * @return card ID. + */ +uint16_t LIBSDIOAPI sdio_card_id(sdio_uif_t uif); + +/** + * Return the standard interface code for a function. + * + * @param uif device handle. + * @param func card function to query. + * + * @return the standard interface. + */ +uint8_t LIBSDIOAPI sdio_std_if(sdio_uif_t uif, int func); + +/** + * Return a function's maximum supported block size. + * + * @param uif device handle. + * @param func card function to query. + * + * @return maximum block size. + */ +int LIBSDIOAPI sdio_max_block_size(sdio_uif_t uif, int func); + +/** + * Return a function's current block size. + * + * @note This returns the driver's view of the block size and not the + * value in the function's block size register. + * + * @param uif device handle. + * @param func card function to query. + * + * @return the current block size. + */ +int LIBSDIOAPI sdio_block_size(sdio_uif_t uif, int func); + +/** + * Set a function's block size. + * + * The function's block size registers will be written if necessary. + * + * @param uif device handle. + * @param func function to modify. + * @param blksz the new block size; or 0 for the default size. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_set_block_size(sdio_uif_t uif, int func, int blksz); + +/** + * Read an 8 bit register. + * + * @param uif device handle. + * @param func card function. + * @param addr register address. + * @param data the data read. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_read8(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data); + +/** + * Write an 8 bit register. + * + * @param uif device handle. + * @param func card function. + * @param addr register address. + * @param data the data to write. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_write8(sdio_uif_t uif, int func, uint32_t addr, uint8_t data); + +/** + * Read a buffer from a 8 bit wide register/FIFO. + * + * The buffer read uses a fixed (not incrementing) address. + * + * \a block_size \e must be set to the value writted into \a func's + * I/O block size FBR register. + * + * If \a len % \a block_size == 0, a block mode transfer is used; a + * byte mode transfer is used if \a len < \a block_size. + * + * @param uif device handle. + * @param func card function. + * @param addr register/FIFO address. + * @param data buffer to store the data read. + * @param len length of data to read. + * @param block_size block size to use for this transfer. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_read(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data, + size_t len, int block_size); + +/** + * Write a buffer to an 8 bit wide register/FIFO. + * + * The buffer write uses a fixed (not incrementing) address. + * + * \a block_size \e must be set to the value writted into \a func's + * I/O block size FBR register. + * + * If \a len % \a block_size == 0, a block mode transfer is used; a + * byte mode transfer is used if \a len < \a block_size. + * + * @param uif device handle. + * @param func card function. + * @param addr register/FIFO address. + * @param data buffer of data to write. + * @param len length of the data to write. + * @param block_size block size to use for this transfer. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_write(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data, + size_t len, int block_size); + +/** + * Read an 8 bit register, without waiting for completion. + * + * @param uif device handle. + * @param func card function. + * @param addr register address. + * @param data the data read. + * @param callback function to be called when the read completes. + * @param arg argument to be passed to callback. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_read8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data, + sdio_io_callback_t callback, void *arg); + +/** + * Write an 8 bit register, without waiting for completion. + * + * @param uif device handle. + * @param func card function. + * @param addr register address. + * @param data the data to write. + * @param callback function to be called when the write completes. + * @param arg argument to be passed to callback. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_write8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t data, + sdio_io_callback_t callback, void *arg); + +/** + * Read a buffer from a 8 bit wide register/FIFO, without waiting for + * completion. + * + * The buffer read uses a fixed (not incrementing) address. + * + * \a block_size \e must be set to the value writted into \a func's + * I/O block size FBR register. + * + * If \a len % \a block_size == 0, a block mode transfer is used; a + * byte mode transfer is used if \a len < \a block_size. + * + * @param uif device handle. + * @param func card function. + * @param addr register/FIFO address. + * @param data buffer to store the data read. + * @param len length of data to read. + * @param block_size block size to use for this transfer. + * @param callback function to be called when the read completes. + * @param arg argument to be passed to callback. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_read_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data, + size_t len, int block_size, + sdio_io_callback_t callback, void *arg); + +/** + * Write a buffer to an 8 bit wide register/FIFO, without waiting for + * completion. + * + * The buffer write uses a fixed (not incrementing) address. + * + * \a block_size \e must be set to the value writted into \a func's + * I/O block size FBR register. + * + * If \a len % \a block_size == 0, a block mode transfer is used; a + * byte mode transfer is used if \a len < \a block_size. + * + * @param uif device handle. + * @param func card function. + * @param addr register/FIFO address. + * @param data buffer of data to write. + * @param len length of the data to write. + * @param block_size block size to use for this transfer. + * @param callback function to be called when the write completes. + * @param arg argument to be passed to callback. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_write_async(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data, + size_t len, int block_size, + sdio_io_callback_t callback, void *arg); +/** + * Force a card removal and reinsertion. + * + * This will power cycle the card if the slot hardware supports power + * control. + * + * @note The device handle will no longer be valid. + * + * @param uif device handle. + * + * @return 0 on success; or -ve on error with errno set. + */ +int LIBSDIOAPI sdio_reinsert_card(sdio_uif_t uif); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*@}*/ + +#endif /* #ifndef SDIOEMB_LIBSDIO_H */ diff --git a/drivers/staging/csr/sdioemb/linux.h b/drivers/staging/csr/sdioemb/linux.h new file mode 100644 index 000000000000..f574f716d74c --- /dev/null +++ b/drivers/staging/csr/sdioemb/linux.h @@ -0,0 +1,16 @@ +/* + * Linux helpers for slot drivers. + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef SDIOEMB_LINUX_H +#define SDIOEMB_LINUX_H + +#include + +int sdioemb_linux_slot_register(struct sdioemb_slot *slot); + +#endif /* #ifndef SDIOEMB_LINUX_H */ diff --git a/drivers/staging/csr/sdioemb/sdio.h b/drivers/staging/csr/sdioemb/sdio.h new file mode 100644 index 000000000000..50bb8fdd6b0f --- /dev/null +++ b/drivers/staging/csr/sdioemb/sdio.h @@ -0,0 +1,117 @@ +/* + * Standard SDIO definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef SDIOEMB_SDIO_H +#define SDIOEMB_SDIO_H + +/* Maximum time for VDD to rise to VDD min. */ +#define SDIO_POWER_UP_TIME_MS 250 + +/* Minimum SD bus clock a card must support (Hz). */ +#define SDIO_CLOCK_FREQ_MIN 400000 + +/* Maximum clock frequency for normal mode (Hz). + * + * Although high speed mode should be suitable for all speeds not all + * controller/card combinations are capable of meeting the higher + * tolerances for (e.g.) clock rise/fall times. Therefore, default + * mode is used where possible for improved compatibility. */ +#define SDIO_CLOCK_FREQ_NORMAL_SPD 25000000 + +/* Maximum clock frequency for high speed mode (Hz). */ +#define SDIO_CLOCK_FREQ_HIGH_SPD 50000000 + +#define SDIO_MAX_FUNCTIONS 8 /* incl. F0 */ + +/* Command argument format. */ + +#define SDIO_CMD52_ARG_WRITE 0x80000000 +#define SDIO_CMD52_ARG_FUNC(f) ((f) << 28) +#define SDIO_CMD52_ARG_ADDR(a) ((a) << 9) +#define SDIO_CMD52_ARG_DATA(d) ((d) << 0) + +#define SDIO_CMD53_ARG_WRITE 0x80000000 +#define SDIO_CMD53_ARG_FUNC(f) ((f) << 28) +#define SDIO_CMD53_ARG_BLK_MODE 0x08000000 +#define SDIO_CMD53_ARG_ADDR(a) ((a) << 9) +#define SDIO_CMD53_ARG_CNT(c) ((c) << 0) + +/* Response format. */ + +#define SDIO_R5_DATA(r) (((r) >> 0) & 0xff) +#define SDIO_R5_OUT_OF_RANGE (1 << 8) +#define SDIO_R5_FUNCTION_NUMBER (1 << 9) +#define SDIO_R5_ERROR (1 << 11) + +/* Register offsets and bits. */ + +#define SDIO_OCR_CARD_READY 0x80000000 +#define SDIO_OCR_NUM_FUNCS_MASK 0x70000000 +#define SDIO_OCR_NUM_FUNCS_OFFSET 28 +#define SDIO_OCR_VOLTAGE_3V3 0x00300000 /* 3.2-3.3V & 3.3-3.4V */ + +#define SDIO_CCCR_SDIO_REV 0x00 +#define SDIO_CCCR_SD_REV 0x01 +#define SDIO_CCCR_IO_EN 0x02 +#define SDIO_CCCR_IO_READY 0x03 +#define SDIO_CCCR_INT_EN 0x04 +# define SDIO_CCCR_INT_EN_MIE 0x01 +#define SDIO_CCCR_INT_PENDING 0x05 +#define SDIO_CCCR_IO_ABORT 0x06 +#define SDIO_CCCR_BUS_IFACE_CNTL 0x07 +# define SDIO_CCCR_BUS_IFACE_CNTL_CD_R_DISABLE 0x80 +# define SDIO_CCCR_BUS_IFACE_CNTL_ECSI 0x20 +# define SDIO_CCCR_BUS_IFACE_CNTL_4BIT_BUS 0x02 +#define SDIO_CCCR_CARD_CAPS 0x08 +# define SDIO_CCCR_CARD_CAPS_LSC 0x40 +# define SDIO_CCCR_CARD_CAPS_4BLS 0x80 +#define SDIO_CCCR_CIS_PTR 0x09 +#define SDIO_CCCR_BUS_SUSPEND 0x0c +#define SDIO_CCCR_FUNC_SEL 0x0d +#define SDIO_CCCR_EXEC_FLAGS 0x0e +#define SDIO_CCCR_READY_FLAGS 0x0f +#define SDIO_CCCR_F0_BLK_SIZE 0x10 +#define SDIO_CCCR_PWR_CNTL 0x12 +#define SDIO_CCCR_HIGH_SPEED 0x13 +# define SDIO_CCCR_HIGH_SPEED_SHS 0x01 +# define SDIO_CCCR_HIGH_SPEED_EHS 0x02 + +#define SDIO_FBR_REG(f, r) (0x100*(f) + (r)) + +#define SDIO_FBR_STD_IFACE(f) SDIO_FBR_REG(f, 0x00) +#define SDIO_FBR_STD_IFACE_EXT(f) SDIO_FBR_REG(f, 0x01) +#define SDIO_FBR_CIS_PTR(f) SDIO_FBR_REG(f, 0x09) +#define SDIO_FBR_CSA_PTR(f) SDIO_FBR_REG(f, 0x0c) +#define SDIO_FBR_CSA_DATA(f) SDIO_FBR_REG(f, 0x0f) +#define SDIO_FBR_BLK_SIZE(f) SDIO_FBR_REG(f, 0x10) + +#define SDIO_STD_IFACE_UART 0x01 +#define SDIO_STD_IFACE_BT_TYPE_A 0x02 +#define SDIO_STD_IFACE_BT_TYPE_B 0x03 +#define SDIO_STD_IFACE_GPS 0x04 +#define SDIO_STD_IFACE_CAMERA 0x05 +#define SDIO_STD_IFACE_PHS 0x06 +#define SDIO_STD_IFACE_WLAN 0x07 +#define SDIO_STD_IFACE_BT_TYPE_A_AMP 0x09 + +/* + * Manufacturer and card IDs. + */ +#define SDIO_MANF_ID_CSR 0x032a + +#define SDIO_CARD_ID_CSR_UNIFI_1 0x0001 +#define SDIO_CARD_ID_CSR_UNIFI_2 0x0002 +#define SDIO_CARD_ID_CSR_BC6 0x0004 +#define SDIO_CARD_ID_CSR_DASH_D00 0x0005 +#define SDIO_CARD_ID_CSR_BC7 0x0006 +#define SDIO_CARD_ID_CSR_CINDERELLA 0x0007 +#define SDIO_CARD_ID_CSR_UNIFI_3 0x0007 +#define SDIO_CARD_ID_CSR_UNIFI_4 0x0008 +#define SDIO_CARD_ID_CSR_DASH 0x0010 + +#endif /* #ifndef SDIOEMB_SDIO_H */ diff --git a/drivers/staging/csr/sdioemb/sdio_api.h b/drivers/staging/csr/sdioemb/sdio_api.h new file mode 100644 index 000000000000..cd8aded7229f --- /dev/null +++ b/drivers/staging/csr/sdioemb/sdio_api.h @@ -0,0 +1,408 @@ +/* + * SDIO device driver API. + * + * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SDIO_API_H +#define _SDIO_API_H + +/** + * @defgroup fdriver SDIO function driver API + * + * @brief The SDIO function driver API is used to implement drivers + * for SDIO card functions. + * + * Function drivers register with the SDIO driver core + * (sdio_register_driver()), listing which functions it supports and + * providing callback functions for card inserts, removes and + * interrupts. + * + * @par \anchor card_io_ops Card I/O operations: + * + * - \link sdioemb_read8(struct sdioemb_dev *, uint32_t, uint8_t *) sdioemb_read8()\endlink + * - \link sdioemb_read16(struct sdioemb_dev *, uint32_t, uint16_t *) sdioemb_read16()\endlink + * - \link sdioemb_write8(struct sdioemb_dev *, uint32_t, uint8_t) sdioemb_write8()\endlink + * - \link sdioemb_write16(struct sdioemb_dev *, uint32_t, uint16_t) sdioemb_write16()\endlink + * - \link sdioemb_f0_read8(struct sdioemb_dev *, uint32_t, uint8_t *) sdioemb_f0_read8()\endlink + * - \link sdioemb_f0_write8(struct sdioemb_dev *, uint32_t, uint8_t) sdioemb_f0_write8()\endlink + * - \link sdioemb_read(struct sdioemb_dev *, uint32_t, void *, size_t) sdioemb_read()\endlink + * - \link sdioemb_write(struct sdioemb_dev *, uint32_t, const void *, size_t) sdioemb_write()\endlink + */ + +struct sdioemb_func_driver; +struct sdioemb_dev; +struct sdioemb_dev_priv; + +/** + * An SDIO device. + * + * Each SDIO card will have an sdio_dev for each function. + * + * None of the fields (except for drv_data) should be written. + * + * @ingroup fdriver + */ +struct sdioemb_dev { + struct sdioemb_func_driver *driver; /**< Function driver for this device. */ + uint16_t vendor_id; /**< Vendor ID of the card. */ + uint16_t device_id; /**< Device ID of the card. */ + int function; /**< Function number of this device. */ + uint8_t interface; /**< SDIO standard interface number. */ + uint16_t max_blocksize; /**< Maximum block size supported. */ + uint16_t blocksize; /**< Blocksize in use. */ + int slot_id; /**< ID of the slot this card is inserted into. */ + void * os_device; /**< Pointer to an OS-specific device structure. */ + struct sdioemb_dev_priv *priv; /**< Data private to the SDIO core. */ + void * drv_data; /**< Data private to the function driver. */ +}; + +#define SDIOEMB_ANY_ID 0xffff +#define SDIOEMB_UIF_FUNC 0 +#define SDIOEMB_ANY_FUNC 0xff +#define SDIOEMB_ANY_IFACE 0xff + +/** + * An entry for an SDIO device ID table. + * + * Functions are matched to drivers using any combination of vendor + * ID, device ID, function number or standard interface. + * + * Matching on #function == SDIOEMB_UIF_FUNC is reserved for the SDIO + * Userspace Interface driver. Card management drivers can match on + * #function == 0, these will be probed before any function drivers. + * + * @ingroup fdriver + */ +struct sdioemb_id_table { + uint16_t vendor_id; /**< Vendor ID to match or SDIOEMB_ANY_ID */ + uint16_t device_id; /**< Device ID to match or SDIOEMB_ANY_ID */ + int function; /**< Function number to match or SDIOEMB_ANY_FUNC */ + uint8_t interface; /**< SDIO standard interface to match or SDIOEMB_ANY_IFACE */ +}; + +/** + * A driver for an SDIO function. + * + * @ingroup fdriver + */ +struct sdioemb_func_driver { + /** + * Driver name used in diagnostics. + */ + const char *name; + + /** + * 0 terminated array of functions supported by this device. + * + * The driver may (for example) match on a number of vendor + * ID/device ID/function number triplets or on an SDIO standard + * interface. + */ + struct sdioemb_id_table *id_table; + + /** + * Called by the core when an inserted card has functions which + * match those listed in id_table. + * + * The driver's implementation should (if required): + * + * - perform any additional probing + * - do function specific initialization + * - allocate and register any function/OS specific devices or interfaces. + * + * Called in: thread context. + * + * @param fdev the newly inserted device. + * + * @return 0 on success; -ve on error. + */ + int (*probe)(struct sdioemb_dev *fdev); + + /** + * Called by the core when a card is removed. This is only called + * if the probe() call succeeded. + * + * The driver's implementation should (if required); + * + * - do any function specific shutdown. + * - cleanup any data structures created/registers during probe(). + * + * Called in: thread context. + * + * @param fdev the device being removed. + */ + void (*remove)(struct sdioemb_dev *fdev); + + /** + * Called by the core to signal an SDIO interrupt for this card + * occurs, if interrupts have been enabled with + * sdioemb_interrupt_enable(). + * + * The driver's implementation should signal a thread (or similar) + * to actually handle the interrupt as no card I/O may be + * performed whilst in interrupt context. When the interrupt is + * handled, the driver should call sdioemb_interrupt_acknowledge() to + * enable further interrupts to be signalled. + * + * Called in: interrupt context. + * + * @param fdev the device which may have raised the interrupt. + */ + void (*card_int_handler)(struct sdioemb_dev *fdev); + + /** + * Called by the core to signal a suspend power management + * event occured. + * + * The driver's implementation should (if required) + * set the card to a low power mode and return as soon + * as possible. After this function returns, the + * driver should not start any SDIO commands. + * + * Called in: thread context. + * + * @param fdev the device handler. + */ + void (*suspend)(struct sdioemb_dev *fdev); + + /** + * Called by the core to signal a resume power management + * event occured. + * + * The driver's implementation should (if required) + * initialise the card to an operational mode and return + * as soon as possible. If the card has been powered off + * during suspend, the driver would have to initialise + * the card from scratch (f/w download, h/w initialisation, etc.). + * + * Called in: thread context. + * + * @param fdev the device handler. + */ + void (*resume)(struct sdioemb_dev *fdev); +}; + +int sdioemb_driver_register(struct sdioemb_func_driver *fdriver); +void sdioemb_driver_unregister(struct sdioemb_func_driver *fdriver); + +int sdioemb_driver_probe(struct sdioemb_func_driver *fdriver, struct sdioemb_dev *fdev); +void sdioemb_driver_remove(struct sdioemb_func_driver *fdriver, struct sdioemb_dev *fdev); + +/* For backward compatibility. */ +#define sdio_register_driver sdioemb_driver_register +#define sdio_unregister_driver sdioemb_driver_unregister + +int sdioemb_set_block_size(struct sdioemb_dev *fdev, uint16_t blksz); +void sdioemb_set_max_bus_freq(struct sdioemb_dev *fdev, int max_freq); +int sdioemb_set_bus_width(struct sdioemb_dev *fdev, int bus_width); + +int sdioemb_enable_function(struct sdioemb_dev *fdev); +int sdioemb_disable_function(struct sdioemb_dev *fdev); +int sdioemb_reenable_csr_function(struct sdioemb_dev *dev); +void sdioemb_idle_function(struct sdioemb_dev *fdev); + +int sdioemb_read8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t *val); +int sdioemb_read16(struct sdioemb_dev *fdev, uint32_t addr, uint16_t *val); +int sdioemb_write8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t val); +int sdioemb_write16(struct sdioemb_dev *fdev, uint32_t addr, uint16_t val); +int sdioemb_f0_read8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t *val); +int sdioemb_f0_write8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t val); +int sdioemb_read(struct sdioemb_dev *fdev, uint32_t addr, void *data, size_t len); +int sdioemb_write(struct sdioemb_dev *fdev, uint32_t addr, const void *data, size_t len); + +int sdioemb_hard_reset(struct sdioemb_dev *fdev); + +void sdioemb_power_on(struct sdioemb_dev *fdev); +void sdioemb_power_off(struct sdioemb_dev *fdev); + +int sdioemb_interrupt_enable(struct sdioemb_dev *fdev); +int sdioemb_interrupt_disable(struct sdioemb_dev *fdev); +void sdioemb_interrupt_acknowledge(struct sdioemb_dev *fdev); + +int sdioemb_cis_get_tuple(struct sdioemb_dev *fdev, uint8_t tuple, + void *buf, size_t len); + +void sdioemb_suspend_function(struct sdioemb_dev *fdev); +void sdioemb_resume_function(struct sdioemb_dev *fdev); + +/** + * SDIO command status. + * + * @ingroup fdriver + */ +enum sdioemb_cmd_status { + SDIOEMB_CMD_OK = 0x00, /**< Command successful. */ + + SDIOEMB_CMD_ERR_CMD = 0x01, + SDIOEMB_CMD_ERR_DAT = 0x02, + + SDIOEMB_CMD_ERR_CRC = 0x10, + SDIOEMB_CMD_ERR_TIMEOUT = 0x20, + SDIOEMB_CMD_ERR_OTHER = 0x40, + + SDIOEMB_CMD_ERR_CMD_CRC = SDIOEMB_CMD_ERR_CMD | SDIOEMB_CMD_ERR_CRC, /**< Response CRC error. */ + SDIOEMB_CMD_ERR_CMD_TIMEOUT = SDIOEMB_CMD_ERR_CMD | SDIOEMB_CMD_ERR_TIMEOUT, /**< Response time out. */ + SDIOEMB_CMD_ERR_CMD_OTHER = SDIOEMB_CMD_ERR_CMD | SDIOEMB_CMD_ERR_OTHER, /**< Other response error. */ + SDIOEMB_CMD_ERR_DAT_CRC = SDIOEMB_CMD_ERR_DAT | SDIOEMB_CMD_ERR_CRC, /**< Data CRC error. */ + SDIOEMB_CMD_ERR_DAT_TIMEOUT = SDIOEMB_CMD_ERR_DAT | SDIOEMB_CMD_ERR_TIMEOUT, /**< Data receive time out. */ + SDIOEMB_CMD_ERR_DAT_OTHER = SDIOEMB_CMD_ERR_DAT | SDIOEMB_CMD_ERR_OTHER, /**< Other data error. */ + + SDIOEMB_CMD_ERR_NO_CARD = 0x04, /**< No card present. */ + + SDIOEMB_CMD_IN_PROGRESS = 0xff, /**< Command still in progress. */ +}; + +/** + * A response to an SDIO command. + * + * For R1, R4, R5, and R6 responses only the middle 32 bits of the + * response are stored, the leading octet (start and direction bits + * and command index) and trailing octet (CRC and stop bit) are + * discarded. + * + * @bug R2 and R3 responses are not used by SDIO and are not + * supported. + * + * @ingroup fdriver + */ +union sdioemb_response { + uint32_t r1; + uint32_t r4; + uint32_t r5; + uint32_t r6; +}; + +/** + * SDIO command parameters and response. + */ +struct sdioemb_cmd_resp { + uint8_t cmd; /**< Command index (0 to 63). */ + uint32_t arg; /**< Command argument. */ + union sdioemb_response response; /**< Response to the command. Valid + iff the command has completed and + (sdio_cmd::status & SDIOEMB_CMD_ERR_CMD) == 0.*/ +}; + +/** + * CSPI command parameters and response. + */ +struct cspi_cmd_resp { + unsigned cmd : 8; /**< Command octet (type, and function). */ + unsigned addr: 24; /**< 24 bit address. */ + uint16_t val; /**< Word to write or read from the card (for non-burst commands). */ + uint8_t response; /**< Response octet. Valid iff the command has completed and + (sdio_cmd::status & SDIOEMB_CMD_ERR_CMD) == 0. */ +}; + + +/** + * An SDIO command, its status and response. + * + * sdio_cmd is used to submit SDIO commands to a device and return its + * status and any response or data. + * + * @ingroup fdriver + */ +struct sdioemb_cmd { + /** + * The SDIO device which submitted the command. Set by the + * core. + */ + struct sdioemb_dev *owner; + + /** + * Called by the core when the command has been completed. + * + * Called in: interrupt context. + * + * @param cmd the completed command. + */ + void (*callback)(struct sdioemb_cmd *cmd); + + /** + * Set of flags specifying the response type, data transfer + * direction and other parameters. + * + * For SDIO commands set at least one of the response types: + * - #SDIOEMB_CMD_FLAG_RESP_NONE + * - #SDIOEMB_CMD_FLAG_RESP_R1 + * - #SDIOEMB_CMD_FLAG_RESP_R1B + * - #SDIOEMB_CMD_FLAG_RESP_R2 + * - #SDIOEMB_CMD_FLAG_RESP_R3 + * - #SDIOEMB_CMD_FLAG_RESP_R4 + * - #SDIOEMB_CMD_FLAG_RESP_R5 + * - #SDIOEMB_CMD_FLAG_RESP_R5B + * - #SDIOEMB_CMD_FLAG_RESP_R6 + * + * and any of the additional flags: + * - #SDIOEMB_CMD_FLAG_READ + * + * For CSPI commands set: + * - #SDIOEMB_CMD_FLAG_CSPI + */ + unsigned flags; + + /** + * SDIO command parameters and response. + * + * Valid only if #SDIOEMB_CMD_FLAG_CSPI is \e not set in #flags. + */ + struct sdioemb_cmd_resp sdio; + + /** + * CSPI command parameters and response. + * + * Valid only if #SDIOEMB_CMD_FLAG_CSPI is set in #flags. + */ + struct cspi_cmd_resp cspi; + + /** + * Buffer of data to read or write. + * + * Must be set to NULL if the command is not a data transfer. + */ + uint8_t *data; + + /** + * Length of #data in octets. + * + * len must be either: less than the device's sdio_dev::blocksize; + * or a multiple of the device's sdio_dev::blocksize. + */ + size_t len; + + /** + * Status of the command after it has completed. + */ + enum sdioemb_cmd_status status; + + /** + * Data private to caller of sdioemb_start_cmd(). + */ + void *priv; +}; + +/** @addtogroup fdriver + *@{*/ +#define SDIOEMB_CMD_FLAG_RESP_NONE 0x00 /**< No response. */ +#define SDIOEMB_CMD_FLAG_RESP_R1 0x01 /**< R1 response. */ +#define SDIOEMB_CMD_FLAG_RESP_R1B 0x02 /**< R1b response. */ +#define SDIOEMB_CMD_FLAG_RESP_R2 0x03 /**< R2 response. */ +#define SDIOEMB_CMD_FLAG_RESP_R3 0x04 /**< R3 response. */ +#define SDIOEMB_CMD_FLAG_RESP_R4 0x05 /**< R4 response. */ +#define SDIOEMB_CMD_FLAG_RESP_R5 0x06 /**< R5 response. */ +#define SDIOEMB_CMD_FLAG_RESP_R5B 0x07 /**< R5b response. */ +#define SDIOEMB_CMD_FLAG_RESP_R6 0x08 /**< R6 response. */ +#define SDIOEMB_CMD_FLAG_RESP_MASK 0xff /**< Mask for response type. */ +#define SDIOEMB_CMD_FLAG_RAW 0x0100 /**< @internal Bypass the command queues. */ +#define SDIOEMB_CMD_FLAG_READ 0x0200 /**< Data transfer is a read, not a write. */ +#define SDIOEMB_CMD_FLAG_CSPI 0x0400 /**< CSPI transfer, not SDIO or SDIO-SPI. */ +#define SDIOEMB_CMD_FLAG_ABORT 0x0800 /**< Data transfer abort command. */ +/*@}*/ + +int sdioemb_start_cmd(struct sdioemb_dev *fdev, struct sdioemb_cmd *cmd); + +#endif /* #ifndef _SDIO_API_H */ diff --git a/drivers/staging/csr/sdioemb/sdio_bt_a.h b/drivers/staging/csr/sdioemb/sdio_bt_a.h new file mode 100644 index 000000000000..9efe4a390db5 --- /dev/null +++ b/drivers/staging/csr/sdioemb/sdio_bt_a.h @@ -0,0 +1,143 @@ +/* + * SDIO Bluetooth Type-A interface definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef SDIOEMB_SDIO_BT_A_H +#define SDIOEMB_SDIO_BT_A_H + +#include +#include + +/* + * Standard SDIO function registers for a Bluetooth Type-A interface. + */ +#define SDIO_BT_A_RD 0x00 +#define SDIO_BT_A_TD 0x00 + +#define SDIO_BT_A_RX_PKT_CTRL 0x10 +# define PC_RRT 0x01 + +#define SDIO_BT_A_TX_PKT_CTRL 0x11 +# define PC_WRT 0x01 + +#define SDIO_BT_A_RETRY_CTRL 0x12 +# define RTC_STAT 0x01 +# define RTC_SET 0x01 + +#define SDIO_BT_A_INTRD 0x13 +# define INTRD 0x01 +# define CL_INTRD 0x01 + +#define SDIO_BT_A_INT_EN 0x14 +# define EN_INTRD 0x01 + +#define SDIO_BT_A_BT_MODE 0x20 +# define MD_STAT 0x01 + +/* + * Length of the Type-A header. + * + * Packet length (3 octets) plus Service ID (1 octet). + */ +#define SDIO_BT_A_HEADER_LEN 4 + +/* + * Maximum length of a Type-A transport packet. + * + * Type-A header length and maximum length of a HCI packet (65535 + * octets). + */ +#define SDIO_BT_A_PACKET_LEN_MAX 65543 + +enum sdioemb_bt_a_service_id { + SDIO_BT_A_SID_CMD = 0x01, + SDIO_BT_A_SID_ACL = 0x02, + SDIO_BT_A_SID_SCO = 0x03, + SDIO_BT_A_SID_EVT = 0x04, + SDIO_BT_A_SID_VENDOR = 0xfe, +}; + +static __inline int sdioemb_bt_a_packet_len(const char *p) +{ + return (p[0] & 0xff) | ((p[1] & 0xff) << 8) | ((p[2] & 0xff) << 16); +} + +static __inline int sdioemb_bt_a_service_id(const char *p) +{ + return p[3]; +} + +/* + * Minimum amount to read (including the Type-A header). This allows + * short packets (e.g., flow control packets) to be read with a single + * command. + */ +#define SDIO_BT_A_MIN_READ 32 + +#define SDIO_BT_A_NAME_LEN 16 + +struct sdioemb_bt_a_dev { + CsrSdioFunction *func; + char name[SDIO_BT_A_NAME_LEN]; + void *drv_data; + + /** + * Get a buffer to receive a packet into. + * + * @param bt the BT device. + * @param header a buffer of length #SDIO_BT_A_MIN_READ containing + * (part of) the packet the buffer is for. It will contain + * the Type-A header and as much of the payload that will + * fit. + * @param buffer_min_len the minimum length of buffer required to + * receive the whole packet. This includes space for padding + * the read to a whole number of blocks (if more than 512 + * octets is still to be read). + * @param buffer returns the buffer. The packet (including the + * Type-A header will be placed at the beginning of this + * buffer. + * @param buffer_handle returns a buffer handle passed to the + * subsequent call of the receive() callback. + * + * @return 0 if a buffer was provided. + * @return -ENOMEM if no buffer could be provided. + */ + int (*get_rx_buffer)(struct sdioemb_bt_a_dev *bt, const uint8_t *header, + size_t buffer_min_len, uint8_t **buffer, void **buffer_handle); + void (*receive)(struct sdioemb_bt_a_dev *bt, void *buffer_handle, int status); + void (*sleep_state_changed)(struct sdioemb_bt_a_dev *bt); + + enum sdio_sleep_state sleep_state; + + uint8_t max_tx_retries; + uint8_t max_rx_retries; + unsigned needs_read_ack:1; + unsigned wait_for_firmware:1; + + unsigned rx_off:1; + + /** + * A buffer to read the packet header into before the real buffer + * is requested with the get_rx_buffer() callback. + * + * @internal + */ + uint8_t *header; +}; + +int sdioemb_bt_a_setup(struct sdioemb_bt_a_dev *bt, CsrSdioFunction *func); +void sdioemb_bt_a_cleanup(struct sdioemb_bt_a_dev *bt); +int sdioemb_bt_a_send(struct sdioemb_bt_a_dev *bt, const uint8_t *packet, size_t len); +void sdioemb_bt_a_handle_interrupt(struct sdioemb_bt_a_dev *bt); +void sdioemb_bt_a_set_sleep_state(struct sdioemb_bt_a_dev *bt, enum sdio_sleep_state state); +int sdioemb_bt_a_check_for_reset(struct sdioemb_bt_a_dev *bt); +void sdioemb_bt_a_start(struct sdioemb_bt_a_dev *bt); +void sdioemb_bt_a_stop(struct sdioemb_bt_a_dev *bt); +void sdioemb_bt_a_rx_on(struct sdioemb_bt_a_dev *bt); +void sdioemb_bt_a_rx_off(struct sdioemb_bt_a_dev *bt); + +#endif /* #ifndef SDIOEMB_SDIO_BT_A_H */ diff --git a/drivers/staging/csr/sdioemb/sdio_cis.h b/drivers/staging/csr/sdioemb/sdio_cis.h new file mode 100644 index 000000000000..ec5e8fc38006 --- /dev/null +++ b/drivers/staging/csr/sdioemb/sdio_cis.h @@ -0,0 +1,27 @@ +/* + * SDIO CIS definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SDIO_CIS_H +#define _SDIO_CIS_H + +#define CISTPL_NULL 0x00 +#define CISTPL_CHECKSUM 0x10 +#define CISTPL_VERS_1 0x15 +#define CISTPL_ALTSTR 0x16 +#define CISTPL_MANFID 0x20 +# define CISTPL_MANFID_SIZE 0x04 +#define CISTPL_FUNCID 0x21 +#define CISTPL_FUNCE 0x22 +#define CISTPL_SDIO_STD 0x91 +#define CISTPL_SDIO_EXT 0x92 +#define CISTPL_END 0xff +#define CISTPL_FUNCE 0x22 +# define CISTPL_FUNCE_00_SIZE 0x04 +# define CISTPL_FUNCE_01_SIZE 0x2a + +#endif /* #ifndef _SDIO_CIS_H */ diff --git a/drivers/staging/csr/sdioemb/sdio_csr.h b/drivers/staging/csr/sdioemb/sdio_csr.h new file mode 100644 index 000000000000..3b00e4626cab --- /dev/null +++ b/drivers/staging/csr/sdioemb/sdio_csr.h @@ -0,0 +1,134 @@ +/* + * CSR specific SDIO registers. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef SDIOEMB_SDIO_CSR_H +#define SDIOEMB_SDIO_CSR_H + +/** + * @defgroup registers CSR specific SDIO registers + * + * Registers at 0xF0 - 0xFF in the CCCR are reserved for vendor + * specific registers. The registers documented here are specific to + * following CSR chips: + * + * - BlueCore (6 and later) + * - UltraCore + *@{ + */ + +/** + * Interrupt status/host wakeup register. + * + * This controls a function's deep sleep state. + * + * @see enum sdio_sleep_state + */ +#define SDIO_CSR_SLEEP_STATE 0xf0 +# define SDIO_CSR_SLEEP_STATE_FUNC(f) ((f) << 4) +# define SDIO_CSR_SLEEP_STATE_RDY_INT_EN 0x02 +# define SDIO_CSR_SLEEP_STATE_WAKE_REQ 0x01 + +/** + * Host interrupt clear register. + * + * Writing a 1 to bit 0 clears an SDIO interrupt raised by a generic + * function. + */ +#define SDIO_CSR_HOST_INT 0xf1 +# define SDIO_CSR_HOST_INT_CL 0x01 + +/** + * From host scratch register 0. + * + * A read/write register that can be used for signalling between the + * host and the chip. + * + * The usage of this register depends on the version of the chip or + * firmware. + */ +#define SDIO_CSR_FROM_HOST_SCRATCH0 0xf2 + +/** + * From host scratch register 1. + * + * @see SDIO_CSR_FROM_HOST_SCRATCH0 + */ +#define SDIO_CSR_FROM_HOST_SCRATCH1 0xf3 + +/** + * To host scratch register 0. + * + * A read only register that may be used for signalling between the + * chip and the host. + * + * The usage of this register depends on the version of the chip or + * firmware. + */ +#define SDIO_CSR_TO_HOST_SCRATCH0 0xf4 + +/** + * To host scratch register 1. + * + * @see SDIO_CSR_TO_HOST_SCRATCH0 + */ +#define SDIO_CSR_TO_HOST_SCRATCH1 0xf5 + +/** + * Extended I/O enable. + * + * Similar to the standard CCCR I/O Enable register, this is used to + * detect if an internal reset of a function has occured and + * (optionally) reenable it. + * + * An internal reset is detected by CCCR I/O Enable bit being set and + * the corresponding EXT_IO_EN bit being clear. + */ +#define SDIO_CSR_EXT_IO_EN 0xf6 + +/** + * Deep sleep states as set via the sleep state register. + * + * These states are used to control when the chip may go into a deep + * sleep (a low power mode). + * + * Since a chip in deep sleep may not respond to SDIO commands, the + * host should ensure that the chip is not in deep sleep before + * attempting SDIO commands to functions 1 to 7. + * + * The available states are: + * + * AWAKE - chip must not enter deep sleep and should exit deep sleep + * if it's currently sleeping. + * + * TORPID - chip may enter deep sleep. + * + * DROWSY - a transition state between TORPID and AWAKE. This is + * AWAKE plus the chip asserts an interrupt when the chip is awake. + * + * @see SDIO_CSR_SLEEP_STATE + */ +enum sdio_sleep_state { + SLEEP_STATE_AWAKE = SDIO_CSR_SLEEP_STATE_WAKE_REQ, + SLEEP_STATE_DROWSY = SDIO_CSR_SLEEP_STATE_WAKE_REQ | SDIO_CSR_SLEEP_STATE_RDY_INT_EN, + SLEEP_STATE_TORPID = 0x00, +}; + +/*@}*/ + +/* + * Generic function registers (with byte addresses). + */ + +/* + * SDIO_MODE is chip dependant, see the sdio_mode table in sdio_cspi.c + * to add support for new chips. + */ +#define SDIO_MODE /* chip dependant */ +# define SDIO_MODE_CSPI_EN 0x40 + +#endif /* SDIOEMB_SDIO_CSR_H */ diff --git a/drivers/staging/csr/sdioemb/slot_api.h b/drivers/staging/csr/sdioemb/slot_api.h new file mode 100644 index 000000000000..777bdd4a6df8 --- /dev/null +++ b/drivers/staging/csr/sdioemb/slot_api.h @@ -0,0 +1,313 @@ +/* + * Slot driver API. + * + * Copyright (C) 2007-2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SLOT_API_H +#define _SLOT_API_H + +#include + +struct sdioemb_slot; + +/** + * @defgroup sdriver SDIO slot driver API + * + * @brief The SDIO slot driver API provides an interface for the SDIO + * layer to driver an SDIO slot (socket). + * + * Slot drivers register with the SDIO layer (sdioemb_slot_register()), + * providing functions to starting commands, enabling/disable card + * interrupts, card detection and bus power control. + * + * Functions are provided to notify the SDIO layer when a command has + * completed (sdioemb_cmd_complete()) and when an SDIO card interrupt has + * occurred (sdioemb_interrupt()). + */ + +#define SDIOEMB_BUS_FREQ_OFF 0 +#define SDIOEMB_BUS_FREQ_DEFAULT -1 +#define SDIOEMB_BUS_FREQ_IDLE -2 + +/** + * Valid SDIO bus voltage levels. + * + * @ingroup sdriver + */ +enum sdioemb_power { + SDIOEMB_POWER_OFF = 0, /**< Power switched off. */ + SDIOEMB_POWER_3V3 = 33, /**< Voltage set to 3.3V. */ +}; + +/** + * SDIO slot capabilities. + * + * @ingroup sdriver + */ +struct slot_caps { + int max_bus_freq; /**< Maximum bus frequency (Hz). */ + int max_bus_width; /**< Maximum bus width supported (1 or 4 data lines). */ + uint8_t cspi_mode; /**< CSPI_MODE register value (for CSPI capable slots). */ +}; + +/** + * Controller hardware type. + * + * @ingroup sdriver + */ +enum slot_controller_type { + SDIOEMB_SLOT_TYPE_SD = 0, /**< SD/SDIO controller. */ + SDIOEMB_SLOT_TYPE_SPI, /**< SPI controller. */ + SDIOEMB_SLOT_TYPE_SPI_CSPI, /**< SPI controller capable of CSPI. */ +}; + +/** + * Return values from the add_function() notifier. + * + * @ingroup sdriver + */ +enum sdioemb_add_func_status { + /** + * The core will call sdioemb_add_function(). + */ + SDIOEMB_ADD_FUNC_NOW = 0, + /** + * The slot driver will call sdioemb_add_function() or the + * function driver will call sdioemb_driver_probe() directly. + */ + SDIOEMB_ADD_FUNC_DEFERRED = 1, +}; + +/** + * Slot/card event notifiers. + * + * A slot driver may be notified when certain slot or card events + * occur. + * + * @ingroup sdriver + */ +struct sdioemb_slot_notifiers { + /** + * This is called when a card function has been enumerated + * and initialized but before can be bound to a function driver. + * + * A slot driver may use this to create an OS-specific object for + * the function. The slot driver must either (a) return + * SDIOEMB_ADD_FUNC_NOW; (b) return SDIOEMB_ADD_FUNC_DEFERRED and + * call sdioemb_add_function() later on; (c) return + * SDIOEMB_ADD_FUNC_DEFERRED and pass the fdev to the function + * driver for it to call sdioemb_driver_probe() directly; or (d) + * return an error. + * + * The slot driver may need to get a reference to the fdev with + * sdioemb_get_function() if the lifetime of the OS-specific + * object extends beyond the subsequent return of the + * del_function() callback. + * + * If this is non-NULL the slot driver must also provide + * del_function(). + * + * @param slot the SDIO slot producing the notification. + * @param fdev the SDIO function being added. + * + * @return SDIOEMB_ADD_FUNC_NOW if the function is ready for use. + * @return SDIOEMB_ADD_FUNC_DEFERRED if sdioemb_add_function() or + * sdioemb_driver_probe() will be called later. + * @return -ve on a error. + */ + int (*add_function)(struct sdioemb_slot *slot, struct sdioemb_dev *fdev); + + /** + * This is called when a card function is being removed and after + * any function driver has been unbound. + * + * A slot driver may use this to delete any OS-specific object + * created by the add_function() notifier. + * + * @param slot the SDIO slot producing the notification. + * @param fdev the SDIO function being deleted. + */ + void (*del_function)(struct sdioemb_slot *slot, struct sdioemb_dev *fdev); +}; + +struct sdioemb_slot_priv; + +/** + * An SDIO slot driver. + * + * Allocate and free with sdioemb_slot_alloc() and sdioemb_slot_free(). + * + * @ingroup sdriver + */ +struct sdioemb_slot { + /** + * Name of the slot used in diagnostic messages. + * + * This would typically include the name of the SDIO controller + * and the slot number if the controller has multiple slots. + * + * This will be set by sdioemb_slot_register() if it is left as an + * empty string. + */ + char name[64]; + + /** + * Controller hardware type. + */ + enum slot_controller_type type; + + /** + * Set the SD bus clock frequency. + * + * The driver's implementation should set the SD bus clock to not + * more than \a clk Hz (unless \a clk is equal to + * #SDIOEMB_BUS_FREQ_OFF or #SDIOEMB_BUS_FREQ_IDLE). + * + * If \a clk == SDIOEMB_BUS_FREQ_OFF the clock should be stopped. + * + * \a clk == SDIOEMB_BUS_FREQ_IDLE indicates that the bus is idle + * (currently unused) and the host controller may slow (or stop) + * the SD bus clock to save power on the card. During this idle + * state the host controller must be capable of receiving SDIO + * interrupts (for certain host controllers this may require + * leaving the clock running). + * + * If \a clk is greater than #SDIO_CLOCK_FREQ_NORMAL_SPD (25 MHz) + * subsequent commands should be done with the controller in high + * speed mode. + * + * Called from: interrupt context. + * + * @param slot the slot to configure. + * @param clk new SD bus clock frequency in Hz, SDIOEMB_BUS_FREQ_OFF + * or SDIOEMB_BUS_FREQ_IDLE. + * + * @return The bus frequency actually configured in Hz. + */ + int (*set_bus_freq)(struct sdioemb_slot *slot, int clk); + + /** + * Set the SD bus width. + * + * The driver's implementation should set the width of the SD bus + * for all subsequent data transfers to the specified value. + * + * This may be NULL if the driver sets the bus width when starting + * a command, or the driver is for an SDIO-SPI or CSPI controller. + * + * Called from: thread context. + * + * @param slot the slot to configure. + * @param bus_width new SD bus width (either 1 or 4). + * + * @return 0 on success. + * @return -ve if a low-level error occured when setting the bus width. + */ + int (*set_bus_width)(struct sdioemb_slot *slot, int bus_width); + + /** + * Start an SDIO command. + * + * The driver's implementation should: + * + * - set the controller's bus width to #bus_width, + * - program the controller to start the command. + * + * Called from: interrupt context. + * + * @param slot slot to perform the command. + * @param cmd SDIO command to start. + */ + int (*start_cmd)(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd); + + /** + * Detect if a card is inserted into the slot. + * + * Called from: thread context. + * + * @param slot slot to check. + * + * @return non-zero if a card is inserted; 0 otherwise. + */ + int (*card_present)(struct sdioemb_slot *slot); + + /** + * Switch on/off the SDIO bus power and set the SDIO bus voltage. + * + * Called from: thread context. + * + * @param slot the slot. + * @param power the requested voltage. + * + * @return 0 on success; -ve on error: -EINVAL - requested voltage + * is not supported. + */ + int (*card_power)(struct sdioemb_slot *slot, enum sdioemb_power power); + + /** + * Enable (unmask) the SDIO card interrupt on the controller. + * + * Called from: interrupt context. + * + * @param slot the slot to enable the interrupt on.. + */ + void (*enable_card_int)(struct sdioemb_slot *slot); + + /** + * Disable (mask) the SDIO card interrupt on the controller. + * + * Called from: thread context. + * + * @param slot the slot to disable the interrupt on. + */ + void (*disable_card_int)(struct sdioemb_slot *slot); + + /** + * Perform a hard reset of the card. + * + * Hard resets can be achieved in two ways: + * + * -# Power cycle (if the slot has power control). + * -# Platform-specific assertion of a card/chip reset line. + * + * If hard resets are not supported, either return 0 or set + * hard_reset to NULL. + * + * @param slot the slot for the card to reset. + * + * @return 0 if a hard reset was performed. + * @return 1 if hard resets are not supported. + */ + int (*hard_reset)(struct sdioemb_slot *slot); + + struct slot_caps caps; /**< Slot capabilities. */ + int clock_freq; /**< SD bus frequency requested by the SDIO layer. */ + int bus_width; /**< Bus width requested by the SDIO layer. */ + struct sdioemb_slot_notifiers notifs; /**< Slot event notifiers. */ + int cspi_reg_pad; /**< Padding for CSPI register reads. */ + int cspi_burst_pad; /**< Padding for CSPI burst reads. */ + struct sdioemb_slot_priv *priv; /**< Data private to the SDIO layer. */ + void * drv_data; /**< Data private to the slot driver. */ +}; + +struct sdioemb_slot *sdioemb_slot_alloc(size_t drv_data_size); +void sdioemb_slot_free(struct sdioemb_slot *slot); +int sdioemb_slot_register(struct sdioemb_slot *slot); +void sdioemb_slot_unregister(struct sdioemb_slot *slot); +int sdioemb_card_inserted(struct sdioemb_slot *slot); +void sdioemb_card_removed(struct sdioemb_slot *slot); +void sdioemb_interrupt(struct sdioemb_slot *slot); +void sdioemb_cmd_complete(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd); + +void sdioemb_suspend(struct sdioemb_slot *slot); +void sdioemb_resume(struct sdioemb_slot *slot); + +void sdioemb_add_function(struct sdioemb_dev *fdev); +void sdioemb_del_function(struct sdioemb_dev *fdev); +void sdioemb_get_function(struct sdioemb_dev *fdev); +void sdioemb_put_function(struct sdioemb_dev *fdev); + +#endif /* #ifndef _SLOT_API_H */ diff --git a/drivers/staging/csr/sdioemb/slot_imx27.h b/drivers/staging/csr/sdioemb/slot_imx27.h new file mode 100644 index 000000000000..3aa2235d87c1 --- /dev/null +++ b/drivers/staging/csr/sdioemb/slot_imx27.h @@ -0,0 +1,86 @@ +/* + * i.MX27 SDHC definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SLOT_IMX27_H +#define _SLOT_IMX27_H + +/* + * i.MX27 SDHC registers. + */ + +#define SDHC_STR_STP_CLK 0x00 +# define STR_STP_CLK_MMCSD_RESET 0x0008 +# define STR_STP_CLK_START_CLK 0x0002 +# define STR_STP_CLK_STOP_CLK 0x0001 + +#define SDHC_STATUS 0x04 +# define STATUS_CARD_PRESENCE 0x8000 +# define STATUS_SDIO_INT_ACTIVE 0x4000 +# define STATUS_END_CMD_RESP 0x2000 +# define STATUS_WRITE_OP_DONE 0x1000 +# define STATUS_READ_OP_DONE 0x0800 +# define STATUS_CARD_BUS_CLK_RUN 0x0100 +# define STATUS_APPL_BUFF_FF 0x0080 +# define STATUS_APPL_BUFF_FE 0x0040 +# define STATUS_RESP_CRC_ERR 0x0020 +# define STATUS_CRC_READ_ERR 0x0008 +# define STATUS_CRC_WRITE_ERR 0x0004 +# define STATUS_TIME_OUT_RESP 0x0002 +# define STATUS_TIME_OUT_READ 0x0001 +# define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP) +# define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ) +# define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK) + +#define SDHC_CLK_RATE 0x08 + +#define SDHC_CMD_DAT_CTRL 0x0c /* CMD_DAT_CONT */ +# define CMD_DAT_CTRL_CMD_RESUME 0x8000 +# define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000 +# define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800 +# define CMD_DAT_CTRL_START_READ_WAIT 0x0400 +# define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200 +# define CMD_DAT_CTRL_INIT 0x0080 +# define CMD_DAT_CTRL_WRITE 0x0010 +# define CMD_DAT_CTRL_DATA_ENABLE 0x0008 +# define CMD_DAT_CTRL_RESP_NONE 0x0000 +# define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001 +# define CMD_DAT_CTRL_RESP_R2 0x0002 +# define CMD_DAT_CTRL_RESP_R3_R4 0x0003 + +#define SDHC_RES_TO 0x10 + +#define SDHC_READ_TO 0x14 +# define READ_TO_RECOMMENDED 0x2db4 + +#define SDHC_BLK_LEN 0x18 + +#define SDHC_NOB 0x1c + +#define SDHC_REV_NO 0x20 + +#define SDHC_INT_CTRL 0x24 /* INT_CNTR */ +# define INT_CTRL_CARD_INSERTION_EN 0x8000 +# define INT_CTRL_SDIO_REMOVAL_EN 0x4000 +# define INT_CTRL_SDIO_IRQ_EN 0x2000 +# define INT_CTRL_DAT0_EN 0x1000 +# define INT_CTRL_BUF_READ_EN 0x0010 +# define INT_CTRL_BUF_WRITE_EN 0x0008 +# define INT_CTRL_END_CMD_RES 0x0004 +# define INT_CTRL_WRITE_OP_DONE 0x0002 +# define INT_CTRL_READ_OP_DONE 0x0001 +# define INT_CTRL_INT_EN_MASK 0xe01f + +#define SDHC_CMD 0x28 + +#define SDHC_ARG 0x2c + +#define SDHC_RES_FIFO 0x34 + +#define SDHC_BUFFER_ACCESS 0x38 + +#endif /* #ifndef _SLOT_IMX27_H */ diff --git a/drivers/staging/csr/sdioemb/slot_imx31.h b/drivers/staging/csr/sdioemb/slot_imx31.h new file mode 100644 index 000000000000..b11894a4baec --- /dev/null +++ b/drivers/staging/csr/sdioemb/slot_imx31.h @@ -0,0 +1,86 @@ +/* + * i.MX31 SDHC definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SLOT_IMX31_H +#define _SLOT_IMX31_H + +/* + * i.MX31 SDHC registers. + */ + +#define SDHC_STR_STP_CLK 0x00 +# define STR_STP_CLK_MMCSD_RESET 0x0008 +# define STR_STP_CLK_START_CLK 0x0002 +# define STR_STP_CLK_STOP_CLK 0x0001 + +#define SDHC_STATUS 0x04 +# define STATUS_CARD_PRESENCE 0x8000 +# define STATUS_SDIO_INT_ACTIVE 0x4000 +# define STATUS_END_CMD_RESP 0x2000 +# define STATUS_WRITE_OP_DONE 0x1000 +# define STATUS_READ_OP_DONE 0x0800 +# define STATUS_CARD_BUS_CLK_RUN 0x0100 +# define STATUS_APPL_BUFF_FF 0x0080 +# define STATUS_APPL_BUFF_FE 0x0040 +# define STATUS_RESP_CRC_ERR 0x0020 +# define STATUS_CRC_READ_ERR 0x0008 +# define STATUS_CRC_WRITE_ERR 0x0004 +# define STATUS_TIME_OUT_RESP 0x0002 +# define STATUS_TIME_OUT_READ 0x0001 +# define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP) +# define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ) +# define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK) + +#define SDHC_CLK_RATE 0x08 + +#define SDHC_CMD_DAT_CTRL 0x0c /* CMD_DAT_CONT */ +# define CMD_DAT_CTRL_CMD_RESUME 0x8000 +# define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000 +# define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800 +# define CMD_DAT_CTRL_START_READ_WAIT 0x0400 +# define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200 +# define CMD_DAT_CTRL_INIT 0x0080 +# define CMD_DAT_CTRL_WRITE 0x0010 +# define CMD_DAT_CTRL_DATA_ENABLE 0x0008 +# define CMD_DAT_CTRL_RESP_NONE 0x0000 +# define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001 +# define CMD_DAT_CTRL_RESP_R2 0x0002 +# define CMD_DAT_CTRL_RESP_R3_R4 0x0003 + +#define SDHC_RES_TO 0x10 + +#define SDHC_READ_TO 0x14 +# define READ_TO_RECOMMENDED 0x2db4 + +#define SDHC_BLK_LEN 0x18 + +#define SDHC_NOB 0x1c + +#define SDHC_REV_NO 0x20 + +#define SDHC_INT_CTRL 0x24 /* INT_CNTR */ +# define INT_CTRL_CARD_INSERTION_EN 0x8000 +# define INT_CTRL_SDIO_REMOVAL_EN 0x4000 +# define INT_CTRL_SDIO_IRQ_EN 0x2000 +# define INT_CTRL_DAT0_EN 0x1000 +# define INT_CTRL_BUF_READ_EN 0x0010 +# define INT_CTRL_BUF_WRITE_EN 0x0008 +# define INT_CTRL_END_CMD_RES 0x0004 +# define INT_CTRL_WRITE_OP_DONE 0x0002 +# define INT_CTRL_READ_OP_DONE 0x0001 +# define INT_CTRL_INT_EN_MASK 0xe01f + +#define SDHC_CMD 0x28 + +#define SDHC_ARG 0x2c + +#define SDHC_RES_FIFO 0x34 + +#define SDHC_BUFFER_ACCESS 0x38 + +#endif /* #ifndef _SLOT_IMX31_H */ diff --git a/drivers/staging/csr/sdioemb/slot_pxa27x.h b/drivers/staging/csr/sdioemb/slot_pxa27x.h new file mode 100644 index 000000000000..cca853ad0e05 --- /dev/null +++ b/drivers/staging/csr/sdioemb/slot_pxa27x.h @@ -0,0 +1,70 @@ +/* + * PXA27x MMC/SD controller definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SLOT_PXA27X_H +#define _SLOT_PXA27X_H + +#define PXA27X_MMC_MMCLK_BASE_FREQ 19500000 +#define PXA27X_MMC_FIFO_SIZE 32 + +#define STOP_CLOCK (1 << 0) +#define START_CLOCK (2 << 0) + +#define STAT_END_CMD_RES (1 << 13) +#define STAT_PRG_DONE (1 << 12) +#define STAT_DATA_TRAN_DONE (1 << 11) +#define STAT_CLK_EN (1 << 8) +#define STAT_RECV_FIFO_FULL (1 << 7) +#define STAT_XMIT_FIFO_EMPTY (1 << 6) +#define STAT_RES_CRC_ERR (1 << 5) +#define STAT_SPI_READ_ERROR_TOKEN (1 << 4) +#define STAT_CRC_READ_ERROR (1 << 3) +#define STAT_CRC_WRITE_ERROR (1 << 2) +#define STAT_TIME_OUT_RESPONSE (1 << 1) +#define STAT_READ_TIME_OUT (1 << 0) + +#define SPI_CS_ADDRESS (1 << 3) +#define SPI_CS_EN (1 << 2) +#define CRC_ON (1 << 1) +#define SPI_EN (1 << 0) + +#define CMDAT_SDIO_INT_EN (1 << 11) +#define CMDAT_STOP_TRAN (1 << 10) +#define CMDAT_SD_4DAT (1 << 8) +#define CMDAT_DMAEN (1 << 7) +#define CMDAT_INIT (1 << 6) +#define CMDAT_BUSY (1 << 5) +#define CMDAT_STREAM (1 << 4) /* 1 = stream */ +#define CMDAT_WRITE (1 << 3) /* 1 = write */ +#define CMDAT_DATAEN (1 << 2) +#define CMDAT_RESP_NONE (0 << 0) +#define CMDAT_RESP_SHORT (1 << 0) +#define CMDAT_RESP_R2 (2 << 0) +#define CMDAT_RESP_R3 (3 << 0) + +#define RDTO_MAX 0xffff + +#define BUF_PART_FULL (1 << 0) + +#define SDIO_SUSPEND_ACK (1 << 12) +#define SDIO_INT (1 << 11) +#define RD_STALLED (1 << 10) +#define RES_ERR (1 << 9) +#define DAT_ERR (1 << 8) +#define TINT (1 << 7) +#define TXFIFO_WR_REQ (1 << 6) +#define RXFIFO_RD_REQ (1 << 5) +#define CLK_IS_OFF (1 << 4) +#define STOP_CMD (1 << 3) +#define END_CMD_RES (1 << 2) +#define PRG_DONE (1 << 1) +#define DATA_TRAN_DONE (1 << 0) + +#define MMC_I_MASK_ALL 0x00001fff + +#endif /* #ifndef _SLOT_PXA27X_H */ diff --git a/drivers/staging/csr/sdioemb/slot_shc.h b/drivers/staging/csr/sdioemb/slot_shc.h new file mode 100644 index 000000000000..0eb5e535a5a2 --- /dev/null +++ b/drivers/staging/csr/sdioemb/slot_shc.h @@ -0,0 +1,223 @@ +/* + * Standard Host Controller definitions. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SLOT_SHC_H +#define _SLOT_SHC_H + +#include + +/* SHC registers */ +#define SHC_SYSTEM_ADDRESS 0x00 + +#define SHC_BLOCK_SIZE 0x04 +# define SHC_BLOCK_SIZE_DMA_BOUNDARY_4K (0x0 << 12) +# define SHC_BLOCK_SIZE_DMA_BOUNDARY_512K (0x7 << 12) + +#define SHC_BLOCK_COUNT 0x06 +#define SHC_ARG 0x08 + +#define SHC_TRANSFER_MODE 0x0c +# define SHC_TRANSFER_MODE_DMA_EN 0x0001 +# define SHC_TRANSFER_MODE_BLK_CNT_EN 0x0002 +# define SHC_TRANSFER_MODE_AUTO_CMD12_EN 0x0004 +# define SHC_TRANSFER_MODE_DATA_READ 0x0010 +# define SHC_TRANSFER_MODE_MULTI_BLK 0x0020 + +#define SHC_CMD 0x0e +# define SHC_CMD_RESP_NONE 0x0000 +# define SHC_CMD_RESP_136 0x0001 +# define SHC_CMD_RESP_48 0x0002 +# define SHC_CMD_RESP_48B 0x0003 +# define SHC_CMD_RESP_CRC_CHK 0x0008 +# define SHC_CMD_RESP_IDX_CHK 0x0010 +# define SHC_CMD_DATA_PRESENT 0x0020 +# define SHC_CMD_TYPE_ABORT (0x3 << 6) +# define SHC_CMD_IDX(c) ((c) << 8) + +#define SHC_RESPONSE_0_31 0x10 + +#define SHC_BUFFER_DATA_PORT 0x20 + +#define SHC_PRESENT_STATE 0x24 +# define SHC_PRESENT_STATE_CMD_INHIBIT 0x00000001 +# define SHC_PRESENT_STATE_DAT_INHIBIT 0x00000002 +# define SHC_PRESENT_STATE_CARD_PRESENT 0x00010000 + +#define SHC_HOST_CTRL 0x28 +# define SHC_HOST_CTRL_LED_ON 0x01 +# define SHC_HOST_CTRL_4BIT 0x02 +# define SHC_HOST_CTRL_HIGH_SPD_EN 0x04 + + +#define SHC_PWR_CTRL 0x29 +# define SHC_PWR_CTRL_3V3 0x0e +# define SHC_PWR_CTRL_ON 0x01 + +#define SHC_BLOCK_GAP_CTRL 0x2a +#define SHC_WAKEUP_CTRL 0x2b + +#define SHC_CLOCK_CTRL 0x2c +# define SHC_CLOCK_CTRL_INT_CLK_EN 0x01 +# define SHC_CLOCK_CTRL_INT_CLK_STABLE 0x02 +# define SHC_CLOCK_CTRL_SD_CLK_EN 0x04 +# define SHC_CLOCK_CTRL_DIV(d) (((d) >> 1) << 8) /* divisor must be power of 2 */ + +#define SHC_TIMEOUT_CTRL 0x2e +# define SHC_TIMEOUT_CTRL_MAX 0x0e + +#define SHC_SOFTWARE_RST 0x2f +# define SHC_SOFTWARE_RST_ALL 0x01 +# define SHC_SOFTWARE_RST_CMD 0x02 +# define SHC_SOFTWARE_RST_DAT 0x04 + +#define SHC_INT_STATUS 0x30 +#define SHC_INT_STATUS_EN 0x34 +#define SHC_INT_SIGNAL_EN 0x38 +# define SHC_INT_CMD_COMPLETE 0x00000001 +# define SHC_INT_TRANSFER_COMPLETE 0x00000002 +# define SHC_INT_BLOCK_GAP 0x00000004 +# define SHC_INT_DMA 0x00000008 +# define SHC_INT_WR_BUF_RDY 0x00000010 +# define SHC_INT_RD_BUF_RDY 0x00000020 +# define SHC_INT_CARD_INSERTED 0x00000040 +# define SHC_INT_CARD_REMOVED 0x00000080 +# define SHC_INT_CARD_INT 0x00000100 +# define SHC_INT_ERR_ANY 0x00008000 +# define SHC_INT_ERR_CMD_TIMEOUT 0x00010000 +# define SHC_INT_ERR_CMD_CRC 0x00020000 +# define SHC_INT_ERR_CMD_ENDBIT 0x00040000 +# define SHC_INT_ERR_CMD_INDEX 0x00080000 +# define SHC_INT_ERR_CMD_ALL 0x000f0000 +# define SHC_INT_ERR_DAT_TIMEOUT 0x00100000 +# define SHC_INT_ERR_DAT_CRC 0x00200000 +# define SHC_INT_ERR_DAT_ENDBIT 0x00400000 +# define SHC_INT_ERR_DAT_ALL 0x00700000 +# define SHC_INT_ERR_CURRENT_LIMIT 0x00800000 +# define SHC_INT_ERR_AUTO_CMD12 0x01000000 +# define SHC_INT_ERR_ALL 0x01ff0000 +# define SHC_INT_ALL 0x01ff81ff + +#define SHC_AUTO_CMD12_STATUS 0x3c + +#define SHC_CAPS 0x40 +# define SHC_CAPS_TO_BASE_CLK_FREQ(c) (((c) & 0x00003f00) >> 8) +# define SHC_CAPS_PWR_3V3 (1 << 24) + +#define SHC_MAX_CURRENT_CAPS 0x4c + +/* PCI configuration registers. */ +#define PCI_SHC_SLOT_INFO 0x40 + +/* Maximum time to wait for a software reset. */ +#define SHC_RESET_TIMEOUT_MS 100 /* ms */ + +/* Maximum time to wait for internal clock to stabilize */ +#define SHC_INT_CLK_STABLE_TIMEOUT_MS 100 + +/* + * No supported voltages in the capabilities register. + * + * Workaround: Assume 3.3V is supported. + */ +#define SLOT_SHC_QUIRK_NO_VOLTAGE_CAPS (1 << 0) + +/* + * Commands with an R5B (busy) response do not complete. + * + * Workaround: Use R5 instead. This will only work if the busy signal + * is cleared sufficiently quickly before the next command is started. + */ +#define SLOT_SHC_QUIRK_R5B_BROKEN (1 << 1) + +/* + * High speed mode doesn't work. + * + * Workaround: limit maximum bus frequency to 25 MHz. + */ +#define SLOT_SHC_QUIRK_HIGH_SPD_BROKEN (1 << 2) + +/* + * Data timeout (TIMEOUT_CTRL) uses SDCLK and not TMCLK. + * + * Workaround: set TIMEOUT_CTRL using SDCLK. + */ +#define SLOT_SHC_QUIRK_DATA_TIMEOUT_USES_SDCLK (1 << 3) + +/* + * Controller can only start DMA on dword (32 bit) aligned addresses. + * + * Workaround: PIO is used on data transfers with a non-dword aligned + * address. + */ +#define SHC_QUIRK_DMA_NEEDS_DWORD_ALIGNED_ADDR (1 << 4) + +/* + * Controller is unreliable following multiple transfers + * + * Workaround: The controller is reset following every command, not just + * erroneous ones + */ +#define SHC_QUIRK_RESET_EVERY_CMD_COMPLETE (1 << 5) + +/* + * JMicron JMB381 to JMB385 controllers require some non-standard PCI + * config space writes. + */ +#define SHC_QUIRK_JMICRON_JMB38X (1 << 6) + +/* + * Controller can only do DMA if the length is a whole number of + * dwords. + * + * Controller with this quirk probably also need + * SHC_QUIRK_DMA_NEEDS_DWORD_ALIGNED_ADDR. + * + * Workaround: PIO is used on data transfers that don't end on an + * aligned address. + */ +#define SHC_QUIRK_DMA_NEEDS_DWORD_ALIGNED_LEN (1 << 7) + +struct sdioemb_shc { + struct sdioemb_slot *slot; + void (*enable_int)(struct sdioemb_slot *slot, uint32_t ints); + void (*disable_int)(struct sdioemb_slot *slot, uint32_t ints); + void (*cmd_complete)(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd); + uint32_t quirks; + os_io_mem_t addr; + + os_spinlock_t lock; + os_timer_t lockup_timer; + uint32_t base_clk; + struct sdioemb_cmd *current_cmd; + uint8_t *data; + size_t remaining; + size_t block_size; +}; + +void sdioemb_shc_init(struct sdioemb_shc *shc); +void sdioemb_shc_clean_up(struct sdioemb_shc *shc); + +int sdioemb_shc_start(struct sdioemb_shc *shc); +void sdioemb_shc_stop(struct sdioemb_shc *shc); + +bool sdioemb_shc_isr(struct sdioemb_shc *shc, uint32_t *int_stat); +void sdioemb_shc_dsr(struct sdioemb_shc *shc, uint32_t int_stat); + +int sdioemb_shc_set_bus_freq(struct sdioemb_shc *shc, int clk); +int sdioemb_shc_set_bus_width(struct sdioemb_shc *shc, int bus_width); +int sdioemb_shc_start_cmd(struct sdioemb_shc *shc, struct sdioemb_cmd *cmd, + bool use_dma, uint64_t dma_addr); +int sdioemb_shc_card_present(struct sdioemb_shc *shc); +int sdioemb_shc_card_power(struct sdioemb_shc *shc, enum sdioemb_power power); +void sdioemb_shc_enable_card_int(struct sdioemb_shc *shc); +void sdioemb_shc_disable_card_int(struct sdioemb_shc *shc); +int sdioemb_shc_hard_reset(struct sdioemb_shc *shc); + +void sdioemb_shc_show_quirks(struct sdioemb_shc *shc); + +#endif /* #ifndef _SLOT_SHC_H */ diff --git a/drivers/staging/csr/sdioemb/slot_ushc.h b/drivers/staging/csr/sdioemb/slot_ushc.h new file mode 100644 index 000000000000..efe3310ee37c --- /dev/null +++ b/drivers/staging/csr/sdioemb/slot_ushc.h @@ -0,0 +1,133 @@ +/* + * USB Standard Host Controller definitions. + * + * Copyright (C) 2010 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef _SLOT_USHC_H +#define _SLOT_USHC_H + +#include + +enum ushc_request +{ + USHC_GET_CAPS = 0x00, + USHC_HOST_CTRL = 0x01, + USHC_PWR_CTRL = 0x02, + USHC_CLK_FREQ = 0x03, + USHC_EXEC_CMD = 0x04, + USHC_READ_RESP = 0x05, + USHC_RESET = 0x06 +}; + +enum ushc_request_recipient +{ + USHC_RECIPIENT_DEVICE = 0x00, + USHC_RECIPIENT_INTERFACE = 0x01, + USHC_RECIPIENT_ENDPOINT = 0x02, + USHC_RECIPIENT_OTHER = 0x03 +}; + +enum ushc_request_direction +{ + USHC_HOST_TO_DEVICE = 0x00, + USHC_DEVICE_TO_HOST = 0x01 +}; + +struct sdioemb_ushc +{ + struct sdioemb_slot *slot; + + void (*enable_int)(struct sdioemb_slot *slot, uint32_t ints); + void (*disable_int)(struct sdioemb_slot *slot, uint32_t ints); + void (*cmd_complete)(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd); + int (*set_host_ctrl)(struct sdioemb_slot *slot, uint16_t controler_state); + int (*submit_vendor_request)(struct sdioemb_slot *slot, + enum ushc_request request, + enum ushc_request_direction direction, + enum ushc_request_recipient recipient, + uint16_t value, + uint16_t index, + void* io_buffer, + uint32_t io_buffer_length); + int (*submit_cbw_request)(struct sdioemb_slot *slot, uint8_t cmd_index, uint16_t block_size, uint32_t cmd_arg); + int (*submit_data_request)(struct sdioemb_slot *slot, + enum ushc_request_direction direction, + void* request_buffer, + uint32_t request_buffer_length); + int (*submit_csw_request)(struct sdioemb_slot *slot); + + os_spinlock_t lock; + + uint32_t base_clock; + uint32_t controler_capabilities; + uint16_t controler_state; + struct sdioemb_cmd* current_cmd; + +#define DISCONNECTED 0 +#define INT_EN 1 +#define IGNORE_NEXT_INT 2 +#define STOP 4 + uint32_t flags; + +#define USHC_INT_STATUS_SDIO_INT (1 << 1) +#define USHC_INT_STATUS_CARD_PRESENT (1 << 0) + uint8_t interrupt_status; + + size_t block_size; +}; + +#define USHC_GET_CAPS_VERSION_MASK 0xff +#define USHC_GET_CAPS_3V3 (1 << 8) +#define USHC_GET_CAPS_3V0 (1 << 9) +#define USHC_GET_CAPS_1V8 (1 << 10) +#define USHC_GET_CAPS_HIGH_SPD (1 << 16) + +#define USHC_PWR_CTRL_OFF 0x00 +#define USHC_PWR_CTRL_3V3 0x01 +#define USHC_PWR_CTRL_3V0 0x02 +#define USHC_PWR_CTRL_1V8 0x03 + +#define USHC_HOST_CTRL_4BIT (1 << 1) +#define USHC_HOST_CTRL_HIGH_SPD (1 << 0) + +#define USHC_READ_RESP_BUSY (1 << 4) +#define USHC_READ_RESP_ERR_TIMEOUT (1 << 3) +#define USHC_READ_RESP_ERR_CRC (1 << 2) +#define USHC_READ_RESP_ERR_DAT (1 << 1) +#define USHC_READ_RESP_ERR_CMD (1 << 0) +#define USHC_READ_RESP_ERR_MASK 0x0f + +void sdioemb_ushc_init(struct sdioemb_ushc* ushc); +void sdioemb_ushc_clean_up(struct sdioemb_ushc* ushc); + +int sdioemb_ushc_start(struct sdioemb_ushc* ushc); +void sdioemb_ushc_stop(struct sdioemb_ushc* ushc); + +bool sdioemb_ushc_isr(struct sdioemb_ushc* ushc, uint8_t int_stat); + +int sdioemb_ushc_set_bus_freq(struct sdioemb_ushc* ushc, int clk); +int sdioemb_ushc_set_bus_width(struct sdioemb_ushc* ushc, int bus_width); +int sdioemb_ushc_start_cmd(struct sdioemb_ushc* ushc, struct sdioemb_cmd *cmd); +int sdioemb_ushc_card_present(struct sdioemb_ushc* ushc); +int sdioemb_ushc_card_power(struct sdioemb_ushc* ushc, enum sdioemb_power power); +void sdioemb_ushc_enable_card_int(struct sdioemb_ushc* ushc); +void sdioemb_ushc_disable_card_int(struct sdioemb_ushc* ushc); +int sdioemb_ushc_hard_reset(struct sdioemb_ushc* ushc); + +void sdioemb_ushc_command_complete(struct sdioemb_ushc* ushc, uint8_t status, uint32_t respones); + +int ushc_hw_get_caps(struct sdioemb_ushc* ushc); +static int ushc_hw_set_host_ctrl(struct sdioemb_ushc* ushc, uint16_t mask, uint16_t val); +static int ushc_hw_submit_vendor_request(struct sdioemb_ushc* ushc, + enum ushc_request request, + enum ushc_request_recipient recipient, + enum ushc_request_direction direction, + uint16_t value, + uint16_t index, + void* io_buffer, + uint32_t io_buffer_length); + +#endif diff --git a/drivers/staging/csr/sdioemb/trace.h b/drivers/staging/csr/sdioemb/trace.h new file mode 100644 index 000000000000..57cbb010eced --- /dev/null +++ b/drivers/staging/csr/sdioemb/trace.h @@ -0,0 +1,19 @@ +/* + * Sdioemb trace messages. + * + * Copyright (C) 2009 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ + +#ifndef SDIOEMB_TRACE_H +#define SDIOEMB_TRACE_H + +#if defined(__linux__) +# define OS_TRACE_PREFIX "sdioemb: " +#endif + +#include + +#endif /* #ifndef SDIOEMB_TRACE_H */ diff --git a/drivers/staging/csr/sdioemb/uif.h b/drivers/staging/csr/sdioemb/uif.h new file mode 100644 index 000000000000..c09357fd2fbc --- /dev/null +++ b/drivers/staging/csr/sdioemb/uif.h @@ -0,0 +1,41 @@ +/* + * Userspace interface to the SDIO Userspace Interface driver. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + */ +#ifndef LINUX_SDIOEMB_UIF_H +#define LINUX_SDIOEMB_UIF_H + +enum sdioemb_uif_cmd_type { + SDIOEMB_UIF_CMD52_READ, SDIOEMB_UIF_CMD52_WRITE, + SDIOEMB_UIF_CMD53_READ, SDIOEMB_UIF_CMD53_WRITE, +}; + +struct sdioemb_uif_cmd { + enum sdioemb_uif_cmd_type type; + int function; + uint32_t address; + uint8_t * data; + size_t len; + int block_size; +}; + +#define SDIOEMB_UIF_IOC_MAGIC 's' + +#define SDIOEMB_UIF_IOCQNUMFUNCS _IO(SDIOEMB_UIF_IOC_MAGIC, 0) +#define SDIOEMB_UIF_IOCCMD _IOWR(SDIOEMB_UIF_IOC_MAGIC, 1, struct sdioemb_uif_cmd) +#define SDIOEMB_UIF_IOCWAITFORINT _IO(SDIOEMB_UIF_IOC_MAGIC, 2) +#define SDIOEMB_UIF_IOCTBUSWIDTH _IO(SDIOEMB_UIF_IOC_MAGIC, 3) +#define SDIOEMB_UIF_IOCREINSERT _IO(SDIOEMB_UIF_IOC_MAGIC, 4) +#define SDIOEMB_UIF_IOCTBUSFREQ _IO(SDIOEMB_UIF_IOC_MAGIC, 5) +#define SDIOEMB_UIF_IOCQMANFID _IO(SDIOEMB_UIF_IOC_MAGIC, 6) +#define SDIOEMB_UIF_IOCQCARDID _IO(SDIOEMB_UIF_IOC_MAGIC, 7) +#define SDIOEMB_UIF_IOCQSTDIF _IO(SDIOEMB_UIF_IOC_MAGIC, 8) +#define SDIOEMB_UIF_IOCQMAXBLKSZ _IO(SDIOEMB_UIF_IOC_MAGIC, 9) +#define SDIOEMB_UIF_IOCQBLKSZ _IO(SDIOEMB_UIF_IOC_MAGIC, 10) +#define SDIOEMB_UIF_IOCTBLKSZ _IO(SDIOEMB_UIF_IOC_MAGIC, 11) + +#endif /* #ifndef LINUX_SDIOEMB_UIF_H */ diff --git a/drivers/staging/csr/sdioemb/version.h b/drivers/staging/csr/sdioemb/version.h new file mode 100644 index 000000000000..b88ef6e4ec9f --- /dev/null +++ b/drivers/staging/csr/sdioemb/version.h @@ -0,0 +1,11 @@ +/* Autogenerated by the sdioemb release procedure. */ +#ifndef SDIOEMB_VERSION_H +#define SDIOEMB_VERSION_H + +#define SDIOEMB_RELEASE 31 + +#ifndef SDIOEMB_RELEASE_EXTRA +#define SDIOEMB_RELEASE_EXTRA "" +#endif + +#endif /* #ifndef SDIOEMB_VERSION_H */ diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c new file mode 100644 index 000000000000..f30eda950ad6 --- /dev/null +++ b/drivers/staging/csr/sme_blocking.c @@ -0,0 +1,1468 @@ +/* + * --------------------------------------------------------------------------- + * FILE: sme_mgt_blocking.c + * + * PURPOSE: + * This file contains the driver specific implementation of + * the WEXT <==> SME MGT interface for all SME builds that support WEXT. + * + * Copyright (C) 2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + +#include "unifi_priv.h" + + +/* + * This file also contains the implementation of the asyncronous + * requests to the SME. + * + * Before calling an asyncronous SME function, we call sme_init_request() + * which gets hold of the SME semaphore and updates the request status. + * The semaphore makes sure that there is only one pending request to + * the SME at a time. + * + * Now we are ready to call the SME function, but only if + * sme_init_request() has returned 0. + * + * When the SME function returns, we need to wait + * for the reply. This is done in sme_wait_for_reply(). + * If the request times-out, the request status is set to SME_REQUEST_TIMEDOUT + * and the sme_wait_for_reply() returns. + * + * If the SME replies in time, we call sme_complete_request(). + * There we change the request status to SME_REQUEST_RECEIVED. This will + * wake up the process waiting on sme_wait_for_reply(). + * It is important that we copy the reply data in priv->sme_reply + * before calling sme_complete_request(). + * + * Handling the wext requests, we need to block + * until the SME sends the response to our request. + * We use the sme_init_request() and sme_wait_for_reply() + * to implement this behavior in the following functions: + * sme_mgt_wifi_on() + * sme_mgt_wifi_off() + * sme_mgt_scan_full() + * sme_mgt_scan_results_get_async() + * sme_mgt_connect() + * unifi_mgt_media_status_ind() + * sme_mgt_disconnect() + * sme_mgt_pmkid() + * sme_mgt_key() + * sme_mgt_mib_get() + * sme_mgt_mib_set() + * sme_mgt_versions_get() + * sme_mgt_set_value() + * sme_mgt_get_value() + * sme_mgt_set_value_async() + * sme_mgt_get_value_async() + * sme_mgt_packet_filter_set() + * sme_mgt_tspec() + */ + + +/* + * Handling the suspend and resume system events, we need to block + * until the SME sends the response to our indication. + * We use the sme_init_request() and sme_wait_for_reply() + * to implement this behavior in the following functions: + * sme_sys_suspend() + * sme_sys_resume() + */ + +#define UNIFI_SME_MGT_SHORT_TIMEOUT 10000 +#define UNIFI_SME_MGT_LONG_TIMEOUT 19000 +#define UNIFI_SME_SYS_LONG_TIMEOUT 10000 + +#ifdef UNIFI_DEBUG +# define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, __func__) +#else +# define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, NULL) +#endif + +static int +sme_init_request(unifi_priv_t *priv) +{ + if (priv == NULL) { + unifi_error(priv, "sme_init_request: Invalid priv\n"); + return -EIO; + } + + /* Grab the SME semaphore until the reply comes, or timeout */ + if (down_interruptible(&priv->sme_sem)) { + unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n"); + return -EIO; + } + priv->sme_reply.request_status = SME_REQUEST_PENDING; + + return 0; + +} /* sme_init_request() */ + + +void +uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func) +{ + if (priv == NULL) { + unifi_error(priv, "sme_complete_request: Invalid priv\n"); + return; + } + + if (priv->sme_reply.request_status != SME_REQUEST_PENDING) { + unifi_notice(priv, + "sme_complete_request: request not pending %s (s:%d)\n", + (func ? func : ""), priv->sme_reply.request_status); + return; + } + priv->sme_reply.request_status = SME_REQUEST_RECEIVED; + priv->sme_reply.reply_status = reply_status; + + wake_up_interruptible(&priv->sme_request_wq); + + return; +} + + +static int +_sme_wait_for_reply(unifi_priv_t *priv, + unsigned long timeout, const char *func) +{ + long r; + + unifi_trace(priv, UDBG5, "sme_wait_for_reply: sleep\n"); + r = wait_event_interruptible_timeout(priv->sme_request_wq, + (priv->sme_reply.request_status != SME_REQUEST_PENDING), + msecs_to_jiffies(timeout)); + unifi_trace(priv, UDBG5, "sme_wait_for_reply: awake\n"); + + if (r == -ERESTARTSYS) { + /* The thread was killed */ + up(&priv->sme_sem); + return r; + } + if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) { + unifi_notice(priv, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n", + (func ? func : ""), priv->sme_reply.request_status, timeout); + + priv->sme_reply.request_status = SME_REQUEST_TIMEDOUT; + + /* Release the SME semaphore that was downed in sme_init_request() */ + up(&priv->sme_sem); + + return -ETIMEDOUT; + } + + /* Release the SME semaphore that was downed in sme_init_request() */ + up(&priv->sme_sem); + + return 0; +} /* sme_wait_for_reply() */ + + + + +#ifdef CSR_SUPPORT_WEXT +int sme_mgt_wifi_on(unifi_priv_t *priv) +{ + CsrUint16 numElements; + CsrWifiSmeDataBlock* dataList; +#ifdef CSR_SUPPORT_WEXT_AP + int r; +#endif + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_wifi_on: invalid smepriv\n"); + return -EIO; + } + + if (priv->mib_data.length) { + numElements = 1; + dataList = &priv->mib_data; + } else { + numElements = 0; + dataList = NULL; + } + /* Start the SME */ +#ifdef CSR_SUPPORT_WEXT_AP + r = sme_init_request(priv); + if (r) { + return -EIO; + } +#endif + CsrWifiSmeWifiOnReqSend(0, priv->sta_mac_address, numElements, dataList); +#ifdef CSR_SUPPORT_WEXT_AP + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); + unifi_trace(priv, UDBG4, + "sme_mgt_wifi_on: unifi_mgt_wifi_oo_req <-- (r=%d, status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +#else + return 0; +#endif +} /* sme_mgt_wifi_on() */ + + +int sme_mgt_wifi_off(unifi_priv_t *priv) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_wifi_off: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + /* Stop the SME */ + CsrWifiSmeWifiOffReqSend(0); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (r=%d, status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); + +} /* sme_mgt_wifi_off */ + +int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key, + CsrWifiSmeListAction action) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_key: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeKeyReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, *sme_key); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + return convert_sme_error(priv->sme_reply.reply_status); +} + + +int sme_mgt_scan_full(unifi_priv_t *priv, + CsrWifiSsid *specific_ssid, + int num_channels, + unsigned char *channel_list) +{ + CsrWifiMacAddress bcastAddress = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }}; + CsrBool is_active = (num_channels > 0) ? TRUE : FALSE; + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_scan_full: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_scan_full: -->\n"); + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + /* If a channel list is provided, do an active scan */ + if (is_active) { + unifi_trace(priv, UDBG1, + "channel list - num_channels: %d, active scan\n", + num_channels); + } + + CsrWifiSmeScanFullReqSend(0, + specific_ssid->length?1:0, /* 0 or 1 SSIDS */ + specific_ssid, + bcastAddress, + is_active, + CSR_WIFI_SME_BSS_TYPE_ANY_BSS, + CSR_WIFI_SME_SCAN_TYPE_ALL, + (CsrUint16)num_channels, channel_list, + 0, NULL); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, "sme_mgt_scan_full: <-- (status=%d)\n", priv->sme_reply.reply_status); + if (priv->sme_reply.reply_status == CSR_WIFI_RESULT_UNAVAILABLE) { + return 0; /* initial scan already underway */ + } else { + return convert_sme_error(priv->sme_reply.reply_status); + } +} + + +int sme_mgt_scan_results_get_async(unifi_priv_t *priv, + struct iw_request_info *info, + char *scan_results, + long scan_results_len) +{ + CsrUint16 scan_result_list_count; + CsrWifiSmeScanResult *scan_result_list; + CsrWifiSmeScanResult *scan_result; + int r; + int i; + char *current_ev = scan_results; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_scan_results_get_async: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeScanResultsGetReqSend(0); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); + if (r) { + return r; + } + + scan_result_list_count = priv->sme_reply.reply_scan_results_count; + scan_result_list = priv->sme_reply.reply_scan_results; + unifi_trace(priv, UDBG2, + "scan_results: Scan returned %d, numElements=%d\n", + r, scan_result_list_count); + + /* OK, now we have the scan results */ + for (i = 0; i < scan_result_list_count; ++i) { + scan_result = &scan_result_list[i]; + + unifi_trace(priv, UDBG2, "Scan Result: %.*s\n", + scan_result->ssid.length, + scan_result->ssid.ssid); + + r = unifi_translate_scan(priv->netdev[0], info, + current_ev, + scan_results + scan_results_len, + scan_result, i+1); + + if (r < 0) { + CsrPmemFree(scan_result_list); + priv->sme_reply.reply_scan_results_count = 0; + priv->sme_reply.reply_scan_results = NULL; + return r; + } + + current_ev += r; + } + + /* + * Free the scan results allocated in unifi_mgt_scan_results_get_cfm() + * and invalidate the reply_scan_results to avoid re-using + * the freed pointers. + */ + CsrPmemFree(scan_result_list); + priv->sme_reply.reply_scan_results_count = 0; + priv->sme_reply.reply_scan_results = NULL; + + unifi_trace(priv, UDBG2, + "scan_results: Scan translated to %d bytes\n", + current_ev - scan_results); + return (current_ev - scan_results); +} + + +int sme_mgt_connect(unifi_priv_t *priv) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_connect: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG2, "sme_mgt_connect: %.*s\n", + priv->connection_config.ssid.length, + priv->connection_config.ssid.ssid); + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE, priv->connection_config); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + if (priv->sme_reply.reply_status) { + unifi_trace(priv, UDBG1, "sme_mgt_connect: failed with SME status %d\n", + priv->sme_reply.reply_status); + } + + return convert_sme_error(priv->sme_reply.reply_status); +} + + +int sme_mgt_disconnect(unifi_priv_t *priv) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_disconnect: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeDisconnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, "sme_mgt_disconnect: <-- (status=%d)\n", priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + + +int sme_mgt_pmkid(unifi_priv_t *priv, + CsrWifiSmeListAction action, + CsrWifiSmePmkidList *pmkid_list) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_pmkid: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmePmkidReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, + pmkid_list->pmkidsCount, pmkid_list->pmkids); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, "sme_mgt_pmkid: <-- (status=%d)\n", priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + + +int sme_mgt_mib_get(unifi_priv_t *priv, + unsigned char *varbind, int *length) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + priv->mib_cfm_buffer = varbind; + priv->mib_cfm_buffer_length = MAX_VARBIND_LENGTH; + + CsrWifiSmeMibGetReqSend(0, *length, varbind); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + priv->mib_cfm_buffer_length = 0; + priv->mib_cfm_buffer = NULL; + return r; + } + + *length = priv->mib_cfm_buffer_length; + + priv->mib_cfm_buffer_length = 0; + priv->mib_cfm_buffer = NULL; + unifi_trace(priv, UDBG4, "sme_mgt_mib_get: <-- (status=%d)\n", priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + +int sme_mgt_mib_set(unifi_priv_t *priv, + unsigned char *varbind, int length) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeMibSetReqSend(0, length, varbind); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, "sme_mgt_mib_set: <-- (status=%d)\n", priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + +#endif /* CSR_SUPPORT_WEXT */ + +int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_set_value_async: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmePowerConfigSetReqSend(0, *powerConfig); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_mgt_set_value_async: unifi_mgt_set_value_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_set_value: invalid smepriv\n"); + return -EIO; + } + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtPowerConfigSetReq(priv->smepriv, *powerConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeSmeStaConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *staConfig); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + unifi_trace(priv, UDBG4, + "sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n"); + return -EIO; + } + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtSmeConfigSetReq(priv->smepriv, *staConfig); + status = CsrWifiSmeMgtDeviceConfigSetReq(priv->smepriv, *deviceConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +#ifdef CSR_SUPPORT_WEXT + +int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_mib_config_set: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeMibConfigSetReqSend(0, *mibConfig); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_mgt_mib_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_mib_config_set: invalid smepriv\n"); + return -EIO; + } + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtMibConfigSetReq(priv->smepriv, *mibConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_coex_config_set: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeCoexConfigSetReqSend(0, *coexConfig); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_mgt_coex_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_coex_config_set: invalid smepriv\n"); + return -EIO; + } + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtCoexConfigSetReq(priv->smepriv, *coexConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +#endif /* CSR_SUPPORT_WEXT */ + +int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_host_config_set: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeHostConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *hostConfig); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_mgt_host_config_set: unifi_mgt_set_host_config_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_host_config_set: invalid smepriv\n"); + return -EIO; + } + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtHostConfigSetReq(priv->smepriv, *hostConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +#ifdef CSR_SUPPORT_WEXT + +int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_versions_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_versions_get: unifi_mgt_versions_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeVersionsGetReqSend(0); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (versions != NULL) { + memcpy((unsigned char*)versions, + (unsigned char*)&priv->sme_reply.versions, + sizeof(CsrWifiSmeVersions)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_versions_get: unifi_mgt_versions_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtVersionsGetReq(priv->smepriv, versions); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +#endif /* CSR_SUPPORT_WEXT */ + +int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_power_config_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_power_config_get: unifi_mgt_power_config_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmePowerConfigGetReqSend(0); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (powerConfig != NULL) { + memcpy((unsigned char*)powerConfig, + (unsigned char*)&priv->sme_reply.powerConfig, + sizeof(CsrWifiSmePowerConfig)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_get_versions: unifi_mgt_power_config_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtPowerConfigGetReq(priv->smepriv, powerConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_host_config_get(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_host_config_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeHostConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (hostConfig != NULL) { + memcpy((unsigned char*)hostConfig, + (unsigned char*)&priv->sme_reply.hostConfig, + sizeof(CsrWifiSmeHostConfig)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_host_config_get: unifi_mgt_host_config_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtHostConfigGetReq(priv->smepriv, hostConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_sme_config_get(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_sme_config_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req -->\n"); + + /* Common device config */ + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeSmeCommonConfigGetReqSend(0); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (deviceConfig != NULL) { + memcpy((unsigned char*)deviceConfig, + (unsigned char*)&priv->sme_reply.deviceConfig, + sizeof(CsrWifiSmeDeviceConfig)); + } + + /* STA config */ + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeSmeStaConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (staConfig != NULL) { + memcpy((unsigned char*)staConfig, + (unsigned char*)&priv->sme_reply.staConfig, + sizeof(CsrWifiSmeStaConfig)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtSmeConfigGetReq(priv->smepriv, staConfig); + status = CsrWifiSmeMgtDeviceConfigGetReq(priv->smepriv, deviceConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_coex_info_get(unifi_priv_t *priv, CsrWifiSmeCoexInfo *coexInfo) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_coex_info_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeCoexInfoGetReqSend(0); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (coexInfo != NULL) { + memcpy((unsigned char*)coexInfo, + (unsigned char*)&priv->sme_reply.coexInfo, + sizeof(CsrWifiSmeCoexInfo)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtCoexInfoGetReq(priv->smepriv, coexInfo); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +#ifdef CSR_SUPPORT_WEXT + +int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_coex_config_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeCoexConfigGetReqSend(0); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (coexConfig != NULL) { + memcpy((unsigned char*)coexConfig, + (unsigned char*)&priv->sme_reply.coexConfig, + sizeof(CsrWifiSmeCoexConfig)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtCoexConfigGetReq(priv->smepriv, coexConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_mib_config_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeMibConfigGetReqSend(0); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (mibConfig != NULL) { + memcpy((unsigned char*)mibConfig, + (unsigned char*)&priv->sme_reply.mibConfig, + sizeof(CsrWifiSmeMibConfig)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtMibConfigGetReq(priv->smepriv, mibConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_connection_info_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeConnectionInfoGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (connectionInfo != NULL) { + memcpy((unsigned char*)connectionInfo, + (unsigned char*)&priv->sme_reply.connectionInfo, + sizeof(CsrWifiSmeConnectionInfo)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtConnectionInfoGetReq(priv->smepriv, connectionInfo); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_connection_config_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeConnectionConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (connectionConfig != NULL) { + memcpy((unsigned char*)connectionConfig, + (unsigned char*)&priv->sme_reply.connectionConfig, + sizeof(CsrWifiSmeConnectionConfig)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtConnectionConfigGetReq(priv->smepriv, connectionConfig); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *connectionStats) +{ +#ifdef CSR_SME_USERSPACE + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_connection_stats_get: invalid smepriv\n"); + return -EIO; + } + + unifi_trace(priv, UDBG4, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req -->\n"); + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeConnectionStatsGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + /* store the reply */ + if (connectionStats != NULL) { + memcpy((unsigned char*)connectionStats, + (unsigned char*)&priv->sme_reply.connectionStats, + sizeof(CsrWifiSmeConnectionStats)); + } + + unifi_trace(priv, UDBG4, + "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + + return convert_sme_error(priv->sme_reply.reply_status); +#else + CsrResult status; + CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); + status = CsrWifiSmeMgtConnectionStatsGetReq(priv->smepriv, connectionStats); + CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); + return convert_sme_error(status); +#endif +} + +#endif /* CSR_SUPPORT_WEXT */ + +int sme_mgt_packet_filter_set(unifi_priv_t *priv) +{ + CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }}; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n"); + return -EIO; + } + if (priv->packet_filters.arp_filter) { + ipAddress.a[0] = (priv->sta_ip_address ) & 0xFF; + ipAddress.a[1] = (priv->sta_ip_address >> 8) & 0xFF; + ipAddress.a[2] = (priv->sta_ip_address >> 16) & 0xFF; + ipAddress.a[3] = (priv->sta_ip_address >> 24) & 0xFF; + } + + unifi_trace(priv, UDBG5, + "sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n", + ipAddress.a[0], ipAddress.a[1], + ipAddress.a[2], ipAddress.a[3]); + + /* Doesn't block for a confirm */ + CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, + priv->packet_filters.tclas_ies_length, + priv->filter_tclas_ies, + priv->packet_filters.filter_mode, + ipAddress); + return 0; +} + +int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action, + CsrUint32 tid, CsrWifiSmeDataBlock *tspec, CsrWifiSmeDataBlock *tclas) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE, + action, tid, TRUE, 0, + tspec->length, tspec->data, + tclas->length, tclas->data); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + + + +int sme_sys_suspend(unifi_priv_t *priv) +{ + int r; + CsrResult csrResult; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_sys_suspend: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */ + priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; + + /* Suspend the SME, which will cause it to power down UniFi */ + CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend); + r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); + if (r) { + /* No reply - forcibly power down in case the request wasn't processed */ + unifi_notice(priv, + "suspend: SME did not reply %s, ", + priv->ptest_mode ? "leave powered" : "power off UniFi anyway\n"); + + /* Leave power on for production test, though */ + if (!priv->ptest_mode) { + /* Put UniFi to deep sleep, in case we can not power it off */ + CsrSdioClaim(priv->sdio); + csrResult = unifi_force_low_power_mode(priv->card); + + /* For WOL, the UniFi must stay powered */ + if (!priv->wol_suspend) { + unifi_trace(priv, UDBG1, "Power off\n"); + CsrSdioPowerOff(priv->sdio); + } + CsrSdioRelease(priv->sdio); + } + } + + if (priv->wol_suspend) { + unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n"); + + /* For PIO WOL, disable SDIO interrupt to enable PIO mode in the f/w */ + if (enable_wol == UNIFI_WOL_PIO) { + unifi_trace(priv, UDBG1, "Remove IRQ to enable PIO WOL\n"); + if (csr_sdio_linux_remove_irq(priv->sdio)) { + unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n"); + } + } + } + + /* Consider UniFi to be uninitialised */ + priv->init_progress = UNIFI_INIT_NONE; + + unifi_trace(priv, UDBG1, "sme_sys_suspend: <-- (r=%d status=%d)\n", r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + + +int sme_sys_resume(unifi_priv_t *priv) +{ + int r; + + unifi_trace(priv, UDBG1, "sme_sys_resume %s\n", priv->wol_suspend ? "warm" : ""); + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_sys_resume: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend); + + if (priv->ptest_mode == 1) { + r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); + if (r) { + /* No reply - forcibly power down in case the request wasn't processed */ + unifi_notice(priv, + "resume: SME did not reply, return success anyway\n"); + } + } else { + + /* + * We are not going to wait for the reply because the SME might be in + * the userspace. In this case the event will reach it when the kernel + * resumes. So, release now the SME semaphore that was downed in + * sme_init_request(). + */ + up(&priv->sme_sem); + } + + return 0; +} + +#ifdef CSR_SUPPORT_WEXT_AP +int sme_ap_stop(unifi_priv_t *priv,CsrUint16 interface_tag) +{ + int r; + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_ap_stop: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiNmeApStopReqSend(0,interface_tag); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_ap_stop <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); + +} + +int sme_ap_start(unifi_priv_t *priv,CsrUint16 interface_tag, + CsrWifiSmeApConfig_t * ap_config) +{ + int r; + CsrWifiSmeApP2pGoConfig p2p_go_param; + memset(&p2p_go_param,0,sizeof(CsrWifiSmeApP2pGoConfig)); + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_ap_start: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiNmeApStartReqSend(0,interface_tag,CSR_WIFI_AP_TYPE_LEGACY,FALSE, + ap_config->ssid,1,ap_config->channel, + ap_config->credentials,ap_config->max_connections, + p2p_go_param,FALSE); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } + + unifi_trace(priv, UDBG4, + "sme_ap_start <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} + +int sme_ap_config(unifi_priv_t *priv, + CsrWifiSmeApMacConfig *ap_mac_config, + CsrWifiNmeApConfig *group_security_config) +{ + int r; + CsrWifiSmeApP2pGoConfig p2p_go_param; + memset(&p2p_go_param,0,sizeof(CsrWifiSmeApP2pGoConfig)); + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_ap_config: invalid smepriv\n"); + return -EIO; + } + + r = sme_init_request(priv); + if (r) { + return -EIO; + } + + CsrWifiNmeApConfigSetReqSend(0,*group_security_config, + *ap_mac_config); + + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + + unifi_trace(priv, UDBG4, + "sme_ap_config <-- (r=%d status=%d)\n", + r, priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); +} +#endif diff --git a/drivers/staging/csr/sme_mgt.c b/drivers/staging/csr/sme_mgt.c new file mode 100644 index 000000000000..ab70216516b3 --- /dev/null +++ b/drivers/staging/csr/sme_mgt.c @@ -0,0 +1,1018 @@ +/* + * --------------------------------------------------------------------------- + * FILE: sme_mgt.c + * + * PURPOSE: + * This file contains the driver specific implementation of + * the SME MGT SAP. + * It is part of the porting exercise. + * + * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + +#include "csr_wifi_hip_unifiversion.h" +#include "unifi_priv.h" +#include "csr_wifi_hip_conversions.h" +/* + * This file implements the SME MGT API. It contains the following functions: + * CsrWifiSmeWifiFlightmodeCfmSend() + * CsrWifiSmeWifiOnCfmSend() + * CsrWifiSmeWifiOffCfmSend() + * CsrWifiSmeWifiOffIndSend() + * CsrWifiSmeScanFullCfmSend() + * CsrWifiSmeScanResultsGetCfmSend() + * CsrWifiSmeScanResultIndSend() + * CsrWifiSmeScanResultsFlushCfmSend() + * CsrWifiSmeConnectCfmSend() + * CsrWifiSmeMediaStatusIndSend() + * CsrWifiSmeDisconnectCfmSend() + * CsrWifiSmeKeyCfmSend() + * CsrWifiSmeMulticastAddressCfmSend() + * CsrWifiSmeSetValueCfmSend() + * CsrWifiSmeGetValueCfmSend() + * CsrWifiSmeMicFailureIndSend() + * CsrWifiSmePmkidCfmSend() + * CsrWifiSmePmkidCandidateListIndSend() + * CsrWifiSmeMibSetCfmSend() + * CsrWifiSmeMibGetCfmSend() + * CsrWifiSmeMibGetNextCfmSend() + * CsrWifiSmeConnectionQualityIndSend() + * CsrWifiSmePacketFilterSetCfmSend() + * CsrWifiSmeTspecCfmSend() + * CsrWifiSmeTspecIndSend() + * CsrWifiSmeBlacklistCfmSend() + * CsrWifiSmeEventMaskSetCfmSend() + * CsrWifiSmeRoamStartIndSend() + * CsrWifiSmeRoamCompleteIndSend() + * CsrWifiSmeAssociationStartIndSend() + * CsrWifiSmeAssociationCompleteIndSend() + * CsrWifiSmeIbssStationIndSend() + */ + + +void CsrWifiSmeMicFailureIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMicFailureInd* ind = (CsrWifiSmeMicFailureInd*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeMicFailureIndSend: invalid priv\n"); + return; + } + + unifi_trace(priv, UDBG1, + "CsrWifiSmeMicFailureIndSend: count=%d, KeyType=%d\n", + ind->count, ind->keyType); + + wext_send_michaelmicfailure_event(priv, ind->count, ind->address, ind->keyType, ind->interfaceTag); +#endif +} + + +void CsrWifiSmePmkidCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmePmkidCfm* cfm = (CsrWifiSmePmkidCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmePmkidCfmSend: Invalid ospriv.\n"); + return; + } + + /* + * WEXT never does a GET operation the PMKIDs, so we don't need + * handle data returned in pmkids. + */ + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmePmkidCandidateListIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmePmkidCandidateListInd* ind = (CsrWifiSmePmkidCandidateListInd*)msg; + int i; + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiSmePmkidCandidateListIndSend: invalid smepriv\n"); + return; + } + + for (i = 0; i < ind->pmkidCandidatesCount; i++) + { + wext_send_pmkid_candidate_event(priv, ind->pmkidCandidates[i].bssid, ind->pmkidCandidates[i].preAuthAllowed, ind->interfaceTag); + } +#endif +} + +void CsrWifiSmeScanResultsFlushCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeScanResultsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeScanResultsGetCfm* cfm = (CsrWifiSmeScanResultsGetCfm*)msg; + int bytesRequired = cfm->scanResultsCount * sizeof(CsrWifiSmeScanResult); + int i; + CsrUint8* current_buff; + CsrWifiSmeScanResult* scanCopy; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeScanResultsGetCfmSend: Invalid ospriv.\n"); + return; + } + + /* Calc the size of the buffer reuired */ + for (i = 0; i < cfm->scanResultsCount; ++i) { + const CsrWifiSmeScanResult *scan_result = &cfm->scanResults[i]; + bytesRequired += scan_result->informationElementsLength; + } + + /* Take a Copy of the scan Results :-) */ + scanCopy = CsrPmemAlloc(bytesRequired); + memcpy(scanCopy, cfm->scanResults, sizeof(CsrWifiSmeScanResult) * cfm->scanResultsCount); + + /* Take a Copy of the Info Elements AND update the scan result pointers */ + current_buff = (CsrUint8*)&scanCopy[cfm->scanResultsCount]; + for (i = 0; i < cfm->scanResultsCount; ++i) + { + CsrWifiSmeScanResult *scan_result = &scanCopy[i]; + CsrMemCpy(current_buff, scan_result->informationElements, scan_result->informationElementsLength); + scan_result->informationElements = current_buff; + current_buff += scan_result->informationElementsLength; + } + + priv->sme_reply.reply_scan_results_count = cfm->scanResultsCount; + priv->sme_reply.reply_scan_results = scanCopy; + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeScanFullCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeScanFullCfm* cfm = (CsrWifiSmeScanFullCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeScanFullCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeScanResultIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + +} + + +void CsrWifiSmeConnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeConnectCfm* cfm = (CsrWifiSmeConnectCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeConnectCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeDisconnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeDisconnectCfm* cfm = (CsrWifiSmeDisconnectCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeDisconnectCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeKeyCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeKeyCfm* cfm = (CsrWifiSmeKeyCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeKeyCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeMulticastAddressCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMulticastAddressCfm* cfm = (CsrWifiSmeMulticastAddressCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeMulticastAddressCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeWifiFlightmodeCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeWifiFlightmodeCfm* cfm = (CsrWifiSmeWifiFlightmodeCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeWifiFlightmodeCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeWifiOnCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeWifiOnCfm* cfm = (CsrWifiSmeWifiOnCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeWifiOnCfmSend: Invalid ospriv.\n"); + return; + } + + unifi_trace(priv, UDBG4, + "CsrWifiSmeWifiOnCfmSend: wake up status %d\n", cfm->status); +#ifdef CSR_SUPPORT_WEXT_AP + sme_complete_request(priv, cfm->status); +#endif + +#endif +} + +void CsrWifiSmeWifiOffCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeWifiOffCfm* cfm = (CsrWifiSmeWifiOffCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeWifiOffCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeWifiOffIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeWifiOffInd* ind = (CsrWifiSmeWifiOffInd*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiRouterCtrlStoppedReqSend: Invalid ospriv.\n"); + return; + } + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlStoppedReqSend: invalid smepriv\n"); + return; + } + + /* + * If the status indicates an error, the SME is in a stopped state. + * We need to start it again in order to reinitialise UniFi. + */ + switch (ind->reason) { + case CSR_WIFI_SME_CONTROL_INDICATION_ERROR: + unifi_trace(priv, UDBG1, + "CsrWifiRouterCtrlStoppedReqSend: Restarting SME (ind:%d)\n", + ind->reason); + + /* On error, restart the SME */ + sme_mgt_wifi_on(priv); + break; + case CSR_WIFI_SME_CONTROL_INDICATION_EXIT: +#ifdef CSR_SUPPORT_WEXT_AP + sme_complete_request(priv, 0); +#endif + break; + default: + break; + } + +#endif +} + +void CsrWifiSmeVersionsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeVersionsGetCfm* cfm = (CsrWifiSmeVersionsGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeVersionsGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.versions = cfm->versions; + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmePowerConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmePowerConfigGetCfm* cfm = (CsrWifiSmePowerConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmePowerConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.powerConfig = cfm->powerConfig; + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeHostConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeHostConfigGetCfm* cfm = (CsrWifiSmeHostConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeHostConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.hostConfig = cfm->hostConfig; + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeCoexInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeCoexInfoGetCfm* cfm = (CsrWifiSmeCoexInfoGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeCoexInfoGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.coexInfo = cfm->coexInfo; + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeCoexConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeCoexConfigGetCfm* cfm = (CsrWifiSmeCoexConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeCoexConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.coexConfig = cfm->coexConfig; + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeMibConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMibConfigGetCfm* cfm = (CsrWifiSmeMibConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeMibConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.mibConfig = cfm->mibConfig; + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeConnectionInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeConnectionInfoGetCfm* cfm = (CsrWifiSmeConnectionInfoGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeConnectionInfoGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.connectionInfo = cfm->connectionInfo; + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeConnectionConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeConnectionConfigGetCfm* cfm = (CsrWifiSmeConnectionConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeConnectionConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.connectionConfig = cfm->connectionConfig; + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeConnectionStatsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeConnectionStatsGetCfm* cfm = (CsrWifiSmeConnectionStatsGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeConnectionStatsGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.connectionStats = cfm->connectionStats; + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeMibSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMibSetCfm* cfm = (CsrWifiSmeMibSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeMibSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeMibGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMibGetCfm* cfm = (CsrWifiSmeMibGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeMibGetCfmSend: Invalid ospriv.\n"); + return; + } + + if (cfm->mibAttribute == NULL) { + unifi_error(priv, "CsrWifiSmeMibGetCfmSend: Empty reply.\n"); + sme_complete_request(priv, cfm->status); + return; + } + + if ((priv->mib_cfm_buffer != NULL) && + (priv->mib_cfm_buffer_length >= cfm->mibAttributeLength)) { + memcpy(priv->mib_cfm_buffer, cfm->mibAttribute, cfm->mibAttributeLength); + priv->mib_cfm_buffer_length = cfm->mibAttributeLength; + } else { + unifi_error(priv, + "CsrWifiSmeMibGetCfmSend: No room to store MIB data (have=%d need=%d).\n", + priv->mib_cfm_buffer_length, cfm->mibAttributeLength); + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeMibGetNextCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMibGetNextCfm* cfm = (CsrWifiSmeMibGetNextCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeMibGetNextCfmSend: Invalid ospriv.\n"); + return; + } + + /* Need to copy MIB data */ + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeConnectionQualityIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeConnectionQualityInd* ind = (CsrWifiSmeConnectionQualityInd*)msg; + int signal, noise, snr; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeConnectionQualityIndSend: Invalid ospriv.\n"); + return; + } + + /* + * level and noise below are mapped into an unsigned 8 bit number, + * ranging from [-192; 63]. The way this is achieved is simply to + * add 0x100 onto the number if it is negative, + * once clipped to the correct range. + */ + signal = ind->linkQuality.unifiRssi; + /* Clip range of snr */ + snr = (ind->linkQuality.unifiSnr > 0) ? ind->linkQuality.unifiSnr : 0; /* In dB relative, from 0 - 255 */ + snr = (snr < 255) ? snr : 255; + noise = signal - snr; + + /* Clip range of signal */ + signal = (signal < 63) ? signal : 63; + signal = (signal > -192) ? signal : -192; + + /* Clip range of noise */ + noise = (noise < 63) ? noise : 63; + noise = (noise > -192) ? noise : -192; + + /* Make u8 */ + signal = ( signal < 0 ) ? signal + 0x100 : signal; + noise = ( noise < 0 ) ? noise + 0x100 : noise; + + priv->wext_wireless_stats.qual.level = (u8)signal; /* -192 : 63 */ + priv->wext_wireless_stats.qual.noise = (u8)noise; /* -192 : 63 */ + priv->wext_wireless_stats.qual.qual = snr; /* 0 : 255 */ + priv->wext_wireless_stats.qual.updated = 0; + +#if WIRELESS_EXT > 16 + priv->wext_wireless_stats.qual.updated |= IW_QUAL_LEVEL_UPDATED | + IW_QUAL_NOISE_UPDATED | + IW_QUAL_QUAL_UPDATED; +#if WIRELESS_EXT > 18 + priv->wext_wireless_stats.qual.updated |= IW_QUAL_DBM; +#endif +#endif +#endif +} + +void CsrWifiSmePacketFilterSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmePacketFilterSetCfmSend: Invalid ospriv.\n"); + return; + } + + /* The packet filter set request does not block for a reply */ +} + +void CsrWifiSmeTspecCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeTspecCfm* cfm = (CsrWifiSmeTspecCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeTspecCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeTspecIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeBlacklistCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeEventMaskSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + + +void CsrWifiSmeRoamStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeRoamCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + /* This is called when the association completes, before any 802.1x authentication */ +} + +void CsrWifiSmeAssociationStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeAssociationCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeIbssStationIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeWifiOnIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeRestrictedAccessEnableCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeRestrictedAccessDisableCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + + +void CsrWifiSmeAdhocConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeAdhocConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeAdhocConfigSetCfm* cfm = (CsrWifiSmeAdhocConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeCalibrationDataGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeCalibrationDataSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeCalibrationDataSetCfm* cfm = (CsrWifiSmeCalibrationDataSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeCcxConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeCcxConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeCcxConfigSetCfm* cfm = (CsrWifiSmeCcxConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeCloakedSsidsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeCloakedSsidsSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeCloakedSsidsSetCfm* cfm = (CsrWifiSmeCloakedSsidsSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + + +void CsrWifiSmeCoexConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeCoexConfigSetCfm* cfm = (CsrWifiSmeCoexConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeHostConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeHostConfigSetCfm* cfm = (CsrWifiSmeHostConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeLinkQualityGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + + +void CsrWifiSmeMibConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMibConfigSetCfm* cfm = (CsrWifiSmeMibConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmePermanentMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmePowerConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmePowerConfigSetCfm* cfm = (CsrWifiSmePowerConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeRoamingConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeMediaStatusIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeMediaStatusInd* ind = (CsrWifiSmeMediaStatusInd*)msg; + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiSmeMediaStatusIndSend: invalid smepriv\n"); + return; + } + + if (ind->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) { + /* + * Send wireless-extension event up to userland to announce + * connection. + */ + wext_send_assoc_event(priv, + (unsigned char *)ind->connectionInfo.bssid.a, + (unsigned char *)ind->connectionInfo.assocReqInfoElements, + ind->connectionInfo.assocReqInfoElementsLength, + (unsigned char *)ind->connectionInfo.assocRspInfoElements, + ind->connectionInfo.assocRspInfoElementsLength, + (unsigned char *)ind->connectionInfo.assocScanInfoElements, + ind->connectionInfo.assocScanInfoElementsLength); + + unifi_trace(priv, UDBG2, + "CsrWifiSmeMediaStatusIndSend: IBSS=%02X:%02X:%02X:%02X:%02X:%02X\n", + ind->connectionInfo.bssid.a[0], + ind->connectionInfo.bssid.a[1], + ind->connectionInfo.bssid.a[2], + ind->connectionInfo.bssid.a[3], + ind->connectionInfo.bssid.a[4], + ind->connectionInfo.bssid.a[5]); + + sme_mgt_packet_filter_set(priv); + + } else { + /* + * Send wireless-extension event up to userland to announce + * connection lost to a BSS. + */ + wext_send_disassoc_event(priv); + } +#endif +} + +void CsrWifiSmeRoamingConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeRoamingConfigSetCfm* cfm = (CsrWifiSmeRoamingConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeRoamingConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeScanConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeScanConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_SUPPORT_WEXT + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeScanConfigSetCfm* cfm = (CsrWifiSmeScanConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +#endif +} + +void CsrWifiSmeStationMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeSmeCommonConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeSmeCommonConfigGetCfm* cfm = (CsrWifiSmeSmeCommonConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeCommonConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.deviceConfig = cfm->deviceConfig; + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeSmeStaConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeSmeStaConfigGetCfm* cfm = (CsrWifiSmeSmeStaConfigGetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeStaConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + priv->sme_reply.staConfig = cfm->smeConfig; + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeSmeCommonConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeSmeCommonConfigSetCfm* cfm = (CsrWifiSmeSmeCommonConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeCommonConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeSmeStaConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiSmeSmeStaConfigSetCfm* cfm = (CsrWifiSmeSmeStaConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiSmeSmeStaConfigGetCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeErrorIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeInfoIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeCoreDumpIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} +void CsrWifiSmeAmpStatusChangeIndHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiSmeActivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} +void CsrWifiSmeDeactivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +#ifdef CSR_SUPPORT_WEXT +#ifdef CSR_SUPPORT_WEXT_AP +void CsrWifiNmeApStartCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiNmeApStartCfm* cfm = (CsrWifiNmeApStartCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiNmeApStartCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiNmeApStopCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiNmeApStopCfm* cfm = (CsrWifiNmeApStopCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiNmeApStopCfmSend: Invalid ospriv.\n"); + return; + } + + sme_complete_request(priv, cfm->status); +} + +void CsrWifiNmeApConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiNmeApConfigSetCfm* cfm = (CsrWifiNmeApConfigSetCfm*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiNmeApConfigSetCfmSend: Invalid ospriv.\n"); + return; + } + sme_complete_request(priv, cfm->status); +} +#endif +#endif diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c new file mode 100644 index 000000000000..2091109f7c16 --- /dev/null +++ b/drivers/staging/csr/sme_native.c @@ -0,0 +1,591 @@ +/* + * *************************************************************************** + * + * FILE: sme_native.c + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ + +#include + +#include "unifi_priv.h" +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" + +static const unsigned char wildcard_address[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +int +uf_sme_init(unifi_priv_t *priv) +{ + func_enter(); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) + sema_init(&priv->mlme_blocking_mutex, 1); +#else + init_MUTEX(&priv->mlme_blocking_mutex); +#endif + +#ifdef CSR_SUPPORT_WEXT + { + int r = uf_init_wext_interface(priv); + if (r != 0) { + func_exit(); + return r; + } + } +#endif + + + + func_exit(); + return 0; +} /* uf_sme_init() */ + + +void +uf_sme_deinit(unifi_priv_t *priv) +{ + + func_enter(); + + /* Free memory allocated for the scan table */ +/* unifi_clear_scan_table(priv); */ + + /* Cancel any pending workqueue tasks */ + flush_workqueue(priv->unifi_workqueue); + +#ifdef CSR_SUPPORT_WEXT + uf_deinit_wext_interface(priv); +#endif + + + func_exit(); +} /* uf_sme_deinit() */ + + +int sme_mgt_wifi_on(unifi_priv_t *priv) +{ + int r,i; + CsrInt32 csrResult; + + if (priv == NULL) { + return -EINVAL; + } + /* Initialize the interface mode to None */ + for (i=0; iinterfacePriv[i]->interfaceMode = 0; + } + + /* Set up interface mode so that get_packet_priority() can + * select the right QOS priority when WMM is enabled. + */ + priv->interfacePriv[0]->interfaceMode = CSR_WIFI_ROUTER_CTRL_MODE_STA; + + r = uf_request_firmware_files(priv, UNIFI_FW_STA); + if (r) { + unifi_error(priv, "sme_mgt_wifi_on: Failed to get f/w\n"); + return r; + } + + /* + * The request to initialise UniFi might come while UniFi is running. + * We need to block all I/O activity until the reset completes, otherwise + * an SDIO error might occur resulting an indication to the SME which + * makes it think that the initialisation has failed. + */ + priv->bh_thread.block_thread = 1; + + /* Power on UniFi */ + CsrSdioClaim(priv->sdio); + csrResult = CsrSdioPowerOn(priv->sdio); + CsrSdioRelease(priv->sdio); + if(csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) { + return -EIO; + } + + if (csrResult == CSR_RESULT_SUCCESS) { + /* Initialise UniFi hardware */ + r = uf_init_hw(priv); + if (r) { + return r; + } + } + + /* Re-enable the I/O thread */ + priv->bh_thread.block_thread = 0; + + /* Disable deep sleep signalling during the firmware initialisation, to + * prevent the wakeup mechanism raising the SDIO clock beyond INIT before + * the first MLME-RESET.ind. It gets re-enabled at the CONNECTED.ind, + * immediately after the MLME-RESET.ind + */ + csrResult = unifi_configure_low_power_mode(priv->card, + UNIFI_LOW_POWER_DISABLED, + UNIFI_PERIODIC_WAKE_HOST_DISABLED); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_warning(priv, + "sme_mgt_wifi_on: unifi_configure_low_power_mode() returned an error\n"); + } + + + /* Start the I/O thread */ + CsrSdioClaim(priv->sdio); + r = uf_init_bh(priv); + if (r) { + CsrSdioPowerOff(priv->sdio); + CsrSdioRelease(priv->sdio); + return r; + } + CsrSdioRelease(priv->sdio); + + priv->init_progress = UNIFI_INIT_FW_DOWNLOADED; + + return 0; +} + +int +sme_sys_suspend(unifi_priv_t *priv) +{ + const int interfaceNum = 0; /* FIXME */ + CsrResult csrResult; + + /* Abort any pending requests. */ + uf_abort_mlme(priv); + + /* Allow our mlme request to go through. */ + priv->io_aborted = 0; + + /* Send MLME-RESET.req to UniFi. */ + unifi_reset_state(priv, priv->netdev[interfaceNum]->dev_addr, 0); + + /* Stop the network traffic */ + netif_carrier_off(priv->netdev[interfaceNum]); + + /* Put UniFi to deep sleep */ + CsrSdioClaim(priv->sdio); + csrResult = unifi_force_low_power_mode(priv->card); + CsrSdioRelease(priv->sdio); + + return 0; +} /* sme_sys_suspend() */ + + +int +sme_sys_resume(unifi_priv_t *priv) +{ +#ifdef CSR_SUPPORT_WEXT + /* Send disconnect event so clients will re-initialise connection. */ + memset(priv->wext_conf.current_ssid, 0, UNIFI_MAX_SSID_LEN); + memset((void*)priv->wext_conf.current_bssid, 0, ETH_ALEN); + priv->wext_conf.capability = 0; + wext_send_disassoc_event(priv); +#endif + return 0; +} /* sme_sys_resume() */ + + +/* + * --------------------------------------------------------------------------- + * sme_native_log_event + * + * Callback function to be registered as the SME event callback. + * Copies the signal content into a new udi_log_t struct and adds + * it to the read queue for the SME client. + * + * Arguments: + * arg This is the value given to unifi_add_udi_hook, in + * this case a pointer to the client instance. + * signal Pointer to the received signal. + * signal_len Size of the signal structure in bytes. + * bulkdata Pointers to any associated bulk data. + * dir Direction of the signal. Zero means from host, + * non-zero means to host. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +sme_native_log_event(ul_client_t *pcli, + const u8 *sig_packed, int sig_len, + const bulk_data_param_t *bulkdata, + int dir) +{ + unifi_priv_t *priv; + udi_log_t *logptr; + u8 *p; + int i, r; + int signal_len; + int total_len; + udi_msg_t *msgptr; + CSR_SIGNAL signal; + ul_client_t *client = pcli; + + func_enter(); + + if (client == NULL) { + unifi_error(NULL, "sme_native_log_event: client has exited\n"); + return; + } + + priv = uf_find_instance(client->instance); + if (!priv) { + unifi_error(priv, "invalid priv\n"); + return; + } + + /* Just a sanity check */ + if ((sig_packed == NULL) || (sig_len <= 0)) { + return; + } + + /* Get the unpacked signal */ + r = read_unpack_signal(sig_packed, &signal); + if (r == 0) { + signal_len = SigGetSize(&signal); + } else { + CsrUint16 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sig_packed) + sizeof(CsrUint16)) & 0xFF00; + + /* The control indications are 1 byte, pass them to client. */ + if (sig_len == 1) { + unifi_trace(priv, UDBG5, + "Control indication (0x%x) for native SME.\n", + *sig_packed); + + *(u8*)&signal = *sig_packed; + signal_len = sig_len; + } else if (receiver_id == 0) { + /* + * Also "unknown" signals with a ReceiverId of 0 are passed to the client + * without unpacking. (This is a code size optimisation to allow signals + * that the driver not interested in to be dropped from the unpack code). + */ + unifi_trace(priv, UDBG5, + "Signal 0x%.4X with ReceiverId 0 for native SME.\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed)); + + *(u8*)&signal = *sig_packed; + signal_len = sig_len; + } else { + unifi_error(priv, + "sme_native_log_event - Received unknown signal 0x%.4X.\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed)); + return; + } + } + + unifi_trace(priv, UDBG3, "sme_native_log_event: signal 0x%.4X for %d\n", + signal.SignalPrimitiveHeader.SignalId, + client->client_id); + + total_len = signal_len; + /* Calculate the buffer we need to store signal plus bulk data */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + total_len += bulkdata->d[i].data_length; + } + + /* Allocate log structure plus actual signal. */ + logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL); + + if (logptr == NULL) { + unifi_error(priv, + "Failed to allocate %d bytes for a UDI log record\n", + sizeof(udi_log_t) + total_len); + return; + } + + /* Fill in udi_log struct */ + INIT_LIST_HEAD(&logptr->q); + msgptr = &logptr->msg; + msgptr->length = sizeof(udi_msg_t) + total_len; + msgptr->timestamp = jiffies_to_msecs(jiffies); + msgptr->direction = dir; + msgptr->signal_length = signal_len; + + /* Copy signal and bulk data to the log */ + p = (u8 *)(msgptr + 1); + memcpy(p, &signal, signal_len); + p += signal_len; + + /* Append any bulk data */ + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + int len = bulkdata->d[i].data_length; + + /* + * Len here might not be the same as the length in the bulk data slot. + * The slot length will always be even, but len could be odd. + */ + if (len > 0) { + if (bulkdata->d[i].os_data_ptr) { + memcpy(p, bulkdata->d[i].os_data_ptr, len); + } else { + memset(p, 0, len); + } + p += len; + } + } + + /* Add to tail of log queue */ + down(&client->udi_sem); + list_add_tail(&logptr->q, &client->udi_log); + up(&client->udi_sem); + + /* Wake any waiting user process */ + wake_up_interruptible(&client->udi_wq); + + func_exit(); + +} /* sme_native_log_event() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_ta_indicate_protocol + * + * Report that a packet of a particular type has been seen + * + * Arguments: + * drv_priv The device context pointer passed to ta_init. + * protocol The protocol type enum value. + * direction Whether the packet was a tx or rx. + * src_addr The source MAC address from the data packet. + * + * Returns: + * None. + * + * Notes: + * We defer the actual sending to a background workqueue, + * see uf_ta_ind_wq(). + * --------------------------------------------------------------------------- + */ +void +unifi_ta_indicate_protocol(void *ospriv, + CsrWifiRouterCtrlTrafficPacketType packet_type, + CsrWifiRouterCtrlProtocolDirection direction, + const CsrWifiMacAddress *src_addr) +{ + +} /* unifi_ta_indicate_protocol */ + +/* + * --------------------------------------------------------------------------- + * unifi_ta_indicate_sampling + * + * Send the TA sampling information to the SME. + * + * Arguments: + * drv_priv The device context pointer passed to ta_init. + * stats The TA sampling data to send. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +unifi_ta_indicate_sampling(void *ospriv, CsrWifiRouterCtrlTrafficStats *stats) +{ + +} /* unifi_ta_indicate_sampling() */ + + +void +unifi_ta_indicate_l4stats(void *ospriv, + CsrUint32 rxTcpThroughput, + CsrUint32 txTcpThroughput, + CsrUint32 rxUdpThroughput, + CsrUint32 txUdpThroughput) +{ + +} /* unifi_ta_indicate_l4stats() */ + +/* + * --------------------------------------------------------------------------- + * uf_native_process_udi_signal + * + * Process interesting signals from the UDI interface. + * + * Arguments: + * pcli A pointer to the client instance. + * signal Pointer to the received signal. + * signal_len Size of the signal structure in bytes. + * bulkdata Pointers to any associated bulk data. + * dir Direction of the signal. Zero means from host, + * non-zero means to host. + * + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +uf_native_process_udi_signal(ul_client_t *pcli, + const u8 *packed_signal, int packed_signal_len, + const bulk_data_param_t *bulkdata, int dir) +{ + +} /* uf_native_process_udi_signal() */ + + +/* + * --------------------------------------------------------------------------- + * sme_native_mlme_event_handler + * + * Callback function to be used as the udi_event_callback when registering + * as a client. + * This function implements a blocking request-reply interface for WEXT. + * To use it, a client specifies this function as the udi_event_callback + * to ul_register_client(). The signal dispatcher in + * unifi_receive_event() will call this function to deliver a signal. + * + * Arguments: + * pcli Pointer to the client instance. + * signal Pointer to the received signal. + * signal_len Size of the signal structure in bytes. + * bulkdata Pointer to structure containing any associated bulk data. + * dir Direction of the signal. Zero means from host, + * non-zero means to host. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +sme_native_mlme_event_handler(ul_client_t *pcli, + const u8 *sig_packed, int sig_len, + const bulk_data_param_t *bulkdata, + int dir) +{ + CSR_SIGNAL signal; + int signal_len; + unifi_priv_t *priv = uf_find_instance(pcli->instance); + int id, r; + + func_enter(); + + /* Just a sanity check */ + if ((sig_packed == NULL) || (sig_len <= 0)) { + return; + } + + /* Get the unpacked signal */ + r = read_unpack_signal(sig_packed, &signal); + if (r == 0) { + signal_len = SigGetSize(&signal); + } else { + unifi_error(priv, + "sme_native_mlme_event_handler - Received unknown signal 0x%.4X.\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed)); + return; + } + + id = signal.SignalPrimitiveHeader.SignalId; + unifi_trace(priv, UDBG4, "wext - Process signal 0x%.4X\n", id); + + /* + * Take the appropriate action for the signal. + */ + switch (id) { + /* + * Confirm replies from UniFi. + * These all have zero or one CSR_DATAREF member. (FIXME: check this is still true for softmac) + */ + case CSR_MA_PACKET_CONFIRM_ID: + case CSR_MLME_RESET_CONFIRM_ID: + case CSR_MLME_GET_CONFIRM_ID: + case CSR_MLME_SET_CONFIRM_ID: + case CSR_MLME_GET_NEXT_CONFIRM_ID: + case CSR_MLME_POWERMGT_CONFIRM_ID: + case CSR_MLME_SCAN_CONFIRM_ID: + case CSR_MLME_HL_SYNC_CONFIRM_ID: + case CSR_MLME_MEASURE_CONFIRM_ID: + case CSR_MLME_SETKEYS_CONFIRM_ID: + case CSR_MLME_DELETEKEYS_CONFIRM_ID: + case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID: + case CSR_MLME_ADD_PERIODIC_CONFIRM_ID: + case CSR_MLME_DEL_PERIODIC_CONFIRM_ID: + case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID: + case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID: + case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID: + case CSR_MLME_STOP_MEASURE_CONFIRM_ID: + case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID: + case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID: + case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID: + case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID: + case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID: + case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID: + case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID: + case CSR_MLME_CONNECT_STATUS_CONFIRM_ID: + case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID: + case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID: + case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID: + case CSR_MLME_ADD_TSPEC_CONFIRM_ID: + case CSR_MLME_DEL_TSPEC_CONFIRM_ID: + case CSR_MLME_START_AGGREGATION_CONFIRM_ID: + case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID: + case CSR_MLME_SM_START_CONFIRM_ID: + case CSR_MLME_LEAVE_CONFIRM_ID: + case CSR_MLME_SET_TIM_CONFIRM_ID: + case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID: + case CSR_MLME_SET_CHANNEL_CONFIRM_ID: + case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID: + case CSR_DEBUG_GENERIC_CONFIRM_ID: + unifi_mlme_copy_reply_and_wakeup_client(pcli, &signal, signal_len, bulkdata); + break; + + case CSR_MLME_CONNECTED_INDICATION_ID: + /* We currently ignore the connected-ind for softmac f/w development */ + unifi_info(priv, "CSR_MLME_CONNECTED_INDICATION_ID ignored\n"); + break; + + default: + break; + } + + func_exit(); +} /* sme_native_mlme_event_handler() */ + + + +/* + * ------------------------------------------------------------------------- + * unifi_reset_state + * + * Ensure that a MAC address has been set. + * Send the MLME-RESET signal. + * This must be called at least once before starting to do any + * network activities (e.g. scan, join etc). + * + * Arguments: + * priv Pointer to device private context struct + * macaddr Pointer to chip MAC address. + * If this is FF:FF:FF:FF:FF:FF it will be replaced + * with the MAC address from the chip. + * set_default_mib 1 if the f/w must reset the MIB to the default values + * 0 otherwise + * + * Returns: + * 0 on success, an error code otherwise. + * ------------------------------------------------------------------------- + */ +int +unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr, + unsigned char set_default_mib) +{ + int r = 0; + + func_enter(); + +#ifdef CSR_SUPPORT_WEXT + /* The reset clears any 802.11 association. */ + priv->wext_conf.flag_associated = 0; +#endif + + func_exit(); + return r; +} /* unifi_reset_state() */ + diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c new file mode 100644 index 000000000000..f5760444bfea --- /dev/null +++ b/drivers/staging/csr/sme_sys.c @@ -0,0 +1,2950 @@ +/* + * --------------------------------------------------------------------------- + * FILE: sme_sys.c + * + * PURPOSE: + * Driver specific implementation of the SME SYS SAP. + * It is part of the porting exercise. + * + * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + +#include "csr_wifi_hip_unifiversion.h" +#include "unifi_priv.h" +#include "csr_wifi_hip_conversions.h" +#ifdef CSR_SUPPORT_WEXT_AP +#include "sme_csr/csr_wifi_sme_sef.h" +#endif +/* + * This file implements the SME SYS API and contains the following functions: + * CsrWifiRouterCtrlMediaStatusReqHandler() + * CsrWifiRouterCtrlHipReqHandler() + * CsrWifiRouterCtrlPortConfigureReqHandler() + * CsrWifiRouterCtrlWifiOnReqHandler() + * CsrWifiRouterCtrlWifiOffReqHandler() + * CsrWifiRouterCtrlSuspendResHandler() + * CsrWifiRouterCtrlResumeResHandler() + * CsrWifiRouterCtrlQosControlReqHandler() + * CsrWifiRouterCtrlConfigurePowerModeReqHandler() + * CsrWifiRouterCtrlWifiOnResHandler() + * CsrWifiRouterCtrlWifiOffRspHandler() + * CsrWifiRouterCtrlMulticastAddressResHandler() + * CsrWifiRouterCtrlTrafficConfigReqHandler() + * CsrWifiRouterCtrlTrafficClassificationReqHandler() + * CsrWifiRouterCtrlTclasAddReqHandler() + * CsrWifiRouterCtrlTclasDelReqHandler() + * CsrWifiRouterCtrlSetModeReqHandler() + * CsrWifiRouterCtrlWapiMulticastFilterReqHandler() + * CsrWifiRouterCtrlWapiMulticastReqHandler() + * CsrWifiRouterCtrlWapiUnicastFilterReqHandler() + */ + +#ifdef CSR_SUPPORT_SME +static void check_inactivity_timer_expire_func(unsigned long data); +void uf_send_disconnected_ind_wq(struct work_struct *work); +#endif + +void send_auto_ma_packet_confirm(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + struct list_head *buffered_frames_list) +{ + tx_buffered_packets_t *buffered_frame_item = NULL; + struct list_head *listHead; + struct list_head *placeHolder; + int client_id; + + CSR_SIGNAL unpacked_signal; + CsrUint8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE]; + CsrUint16 packed_siglen; + + + list_for_each_safe(listHead, placeHolder, buffered_frames_list) + { + buffered_frame_item = list_entry(listHead, tx_buffered_packets_t, q); + + if(!buffered_frame_item) { + unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n"); + continue; + } + + if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_NONE) && + (priv->wifi_on_state == wifi_on_done)) + { + + unifi_warning(priv, "Send MA_PACKET_CONFIRM to SenderProcessId = %x for (HostTag = %x TransmissionControl = %x)\n", + (buffered_frame_item->leSenderProcessId), + buffered_frame_item->hostTag, + buffered_frame_item->transmissionControl); + + client_id = buffered_frame_item->leSenderProcessId & 0xFF00; + + if (client_id == priv->sme_cli->sender_id) + { + /* construct a MA-PACKET.confirm message for SME */ + memset(&unpacked_signal, 0, sizeof(unpacked_signal)); + unpacked_signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_CONFIRM_ID; + unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId = buffered_frame_item->leSenderProcessId; + unpacked_signal.SignalPrimitiveHeader.SenderProcessId = CSR_WIFI_ROUTER_IFACEQUEUE; + + unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode, + interfacePriv->InterfaceTag); + unpacked_signal.u.MaPacketConfirm.TransmissionStatus = CSR_RESULT_FAILURE; + unpacked_signal.u.MaPacketConfirm.RetryCount = 0; + unpacked_signal.u.MaPacketConfirm.Rate = buffered_frame_item->rate; + unpacked_signal.u.MaPacketConfirm.HostTag = buffered_frame_item->hostTag; + + write_pack(&unpacked_signal, sigbuf, &packed_siglen); + unifi_warning(priv, "MA_PACKET_CONFIRM for SME (0x%x, 0x%x, 0x%x, 0x%x)\n", + unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId, + unpacked_signal.SignalPrimitiveHeader.SenderProcessId, + unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier, + unpacked_signal.u.MaPacketConfirm.HostTag); + + CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, + packed_siglen, + (CsrUint8 *)sigbuf, + 0, NULL, + 0, NULL); + } + else if((buffered_frame_item->hostTag & 0x80000000)) + { + /* construct a MA-PACKET.confirm message for NME */ + unifi_warning(priv, "MA_PACKET_CONFIRM for NME (0x%x, 0x%x, 0x%x, 0x%x)\n", + buffered_frame_item->leSenderProcessId, + buffered_frame_item->interfaceTag, + buffered_frame_item->transmissionControl, + (buffered_frame_item->hostTag & 0x3FFFFFFF)); + + CsrWifiRouterMaPacketCfmSend((buffered_frame_item->leSenderProcessId & 0xFF), + buffered_frame_item->interfaceTag, + CSR_RESULT_FAILURE, + (buffered_frame_item->hostTag & 0x3FFFFFFF), + buffered_frame_item->rate); + + } + else + { + unifi_warning(priv, "Buffered packet dropped without sending a confirm\n"); + } + + } + + list_del(listHead); + kfree(buffered_frame_item); + buffered_frame_item = NULL; + } +} + +void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlMediaStatusReq* req = (CsrWifiRouterCtrlMediaStatusReq*)msg; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + unsigned long flags; + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid smepriv\n"); + return; + } + if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid interfaceTag\n"); + return; + } + unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlMediaStatusReqHandler: Mode = %d req->mediaStatus = %d\n",interfacePriv->interfaceMode,req->mediaStatus); + if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AMP) { + bulk_data_desc_t bulk_data; + + bulk_data.data_length = 0; + + spin_lock_irqsave(&priv->m4_lock, flags); + if (interfacePriv->m4_bulk_data.data_length > 0) { + bulk_data = interfacePriv->m4_bulk_data; + interfacePriv->m4_bulk_data.net_buf_length = 0; + interfacePriv->m4_bulk_data.data_length = 0; + interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL; + } + spin_unlock_irqrestore(&priv->m4_lock, flags); + + if (bulk_data.data_length != 0) { + unifi_trace(priv, UDBG5, "CsrWifiRouterCtrlMediaStatusReqHandler: free M4\n"); + unifi_net_data_free(priv, &bulk_data); + } + + if ((req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) && + (interfacePriv->connected != UnifiConnected)) { + + switch(interfacePriv->interfaceMode){ + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + interfacePriv->connected = UnifiConnected; + netif_carrier_on(priv->netdev[req->interfaceTag]); +#ifdef CSR_SUPPORT_WEXT + wext_send_started_event(priv); +#endif + unifi_trace(priv, UDBG1, + "CsrWifiRouterCtrlMediaStatusReqHandler: AP/P2PGO setting netif_carrier_on\n"); + UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[req->interfaceTag]); + break; + + default: +#ifdef CSR_SUPPORT_WEXT + /* In the WEXT builds (sme and native), the userspace is not ready + * to process any EAPOL or WAPI packets, until it has been informed + * of the NETDEV_CHANGE. + */ + if (interfacePriv->netdev_callback_registered && (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI)) { + interfacePriv->wait_netdev_change = TRUE; + unifi_trace(priv, UDBG1, + "CsrWifiRouterCtrlMediaStatusReqHandler: waiting for NETDEV_CHANGE\n"); + /* + * Carrier can go to on, only after wait_netdev_change is set to TRUE. + * Otherwise there can be a race in uf_netdev_event(). + */ + netif_carrier_on(priv->netdev[req->interfaceTag]); + unifi_trace(priv, UDBG1, + "CsrWifiRouterCtrlMediaStatusReqHandler: STA/P2PCLI setting netif_carrier_on\n"); + } + else +#endif + { + /* In the NME build, the userspace does not wait for the NETDEV_CHANGE + * so it is ready to process all the EAPOL or WAPI packets. + * At this point, we enable all the Tx queues, and we indicate any packets + * that are queued (and the respective port is opened). + */ + static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + interfacePriv->connected = UnifiConnected; + unifi_trace(priv, UDBG1, + "CsrWifiRouterMediaStatusReqHandler: UnifiConnected && netif_carrier_on\n"); + netif_carrier_on(priv->netdev[req->interfaceTag]); + UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev[req->interfaceTag]); + uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag); + uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag); + } + break; + } + } + + if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED) { +#ifdef CSR_SUPPORT_WEXT + unifi_trace(priv, UDBG1, + "CsrWifiRouterMediaStatusReqHandler: cancel waiting for NETDEV_CHANGE\n"); + interfacePriv->wait_netdev_change = FALSE; +#endif + unifi_trace(priv, UDBG1, + "CsrWifiRouterMediaStatusReqHandler: setting netif_carrier_off\n"); + netif_carrier_off(priv->netdev[req->interfaceTag]); +#ifdef CSR_SUPPORT_WEXT + switch(interfacePriv->interfaceMode){ + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + wext_send_started_event(priv); + break; + default: + break; + } +#endif + interfacePriv->connected = UnifiNotConnected; + } + } else { + /* For AMP, just update the L2 connected flag */ + if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) { + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP connected\n"); + interfacePriv->connected = UnifiConnected; + } else { + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP disconnected\n"); + interfacePriv->connected = UnifiNotConnected; + } + } +} + + +void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlHipReq* hipreq = (CsrWifiRouterCtrlHipReq*)msg; + bulk_data_param_t bulkdata; + u8 *signal_ptr; + int signal_length; + int r=0; + void *dest; + CsrResult csrResult; + CSR_SIGNAL *signal; + CsrUint16 interfaceTag = 0; + CSR_MA_PACKET_REQUEST *req; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if (priv == NULL) { + return; + } + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid smepriv\n"); + return; + } + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid interfaceTag\n"); + return; + } + + /* Initialize bulkdata to avoid os_net_buf is garbage */ + memset(&bulkdata, 0, sizeof(bulk_data_param_t)); + + signal = (CSR_SIGNAL *)hipreq->mlmeCommand; + + unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: 0x04%X ---->\n", + *((CsrUint16*)hipreq->mlmeCommand)); + + /* Construct the signal. */ + signal_ptr = (u8*)hipreq->mlmeCommand; + signal_length = hipreq->mlmeCommandLength; + + /* + * The MSB of the sender ID needs to be set to the client ID. + * The LSB is controlled by the SME. + */ + signal_ptr[5] = (priv->sme_cli->sender_id >> 8) & 0xff; + + /* Allocate buffers for the bulk data. */ + if (hipreq->dataRef1Length) { + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], hipreq->dataRef1Length); + if (csrResult == CSR_RESULT_SUCCESS) { + dest = (void*)bulkdata.d[0].os_data_ptr; + memcpy(dest, hipreq->dataRef1, hipreq->dataRef1Length); + bulkdata.d[0].data_length = hipreq->dataRef1Length; + } else { + unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n"); + return; + } + } else { + bulkdata.d[0].os_data_ptr = NULL; + bulkdata.d[0].data_length = 0; + } + if (hipreq->dataRef2Length) { + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[1], hipreq->dataRef2Length); + if (csrResult == CSR_RESULT_SUCCESS) { + dest = (void*)bulkdata.d[1].os_data_ptr; + memcpy(dest, hipreq->dataRef2, hipreq->dataRef2Length); + bulkdata.d[1].data_length = hipreq->dataRef2Length; + } else { + if (bulkdata.d[0].data_length) + { + unifi_net_data_free(priv, &bulkdata.d[0]); + } + unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n"); + return; + } + } else { + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].data_length = 0; + } + + unifi_trace(priv, UDBG3, "SME SEND: Signal 0x%.4X \n", + *((CsrUint16*)signal_ptr)); + if (signal->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID) + { + CSR_SIGNAL unpacked_signal; + read_unpack_signal((u8 *) signal, &unpacked_signal); + req = &unpacked_signal.u.MaPacketRequest; + interfaceTag = req->VirtualInterfaceIdentifier & 0xff; + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_NONE: + unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid mode: NONE \n"); + break; + default: + unifi_trace(priv, UDBG5, "mode is %x\n", interfacePriv->interfaceMode); + } + /* While sending ensure that first 2 bits b31 and b30 are 00. These are used for local routing*/ + r = uf_process_ma_packet_req(priv, req->Ra.x, (req->HostTag & 0x3FFFFFFF), interfaceTag, + req->TransmissionControl, req->TransmitRate, + req->Priority, signal->SignalPrimitiveHeader.SenderProcessId, + &bulkdata); + if (r) + { + if (bulkdata.d[0].data_length) + { + unifi_net_data_free(priv, &bulkdata.d[0]); + } + if (bulkdata.d[1].data_length) + { + unifi_net_data_free(priv, &bulkdata.d[1]); + } + } + } else { + /* ul_send_signal_raw frees the bulk data if it fails */ + r = ul_send_signal_raw(priv, signal_ptr, signal_length, &bulkdata); + } + + if (r) { + unifi_error(priv, + "CsrWifiRouterCtrlHipReqHandler: Failed to send signal (0x%.4X - %u)\n", + *((CsrUint16*)signal_ptr), r); + CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR); + } + + unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: <----\n"); +} + +#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP +static void +uf_send_gratuitous_arp(unifi_priv_t *priv, CsrUint16 interfaceTag) +{ + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CSR_PRIORITY priority; + CSR_SIGNAL signal; + bulk_data_param_t bulkdata; + CsrResult csrResult; + struct sk_buff *skb, *newSkb = NULL; + CsrInt8 protection; + int r; + static const CsrUint8 arp_req[36] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0x00, 0x02, 0x5f, 0x20, 0x2f, 0x02, + 0xc0, 0xa8, 0x00, 0x02, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc0, 0xa8, 0x00, 0x02}; + + func_enter(); + + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req)); + if (csrResult != CSR_RESULT_SUCCESS) + { + unifi_error(priv, "Failed to allocate bulk data in CsrWifiSmeRoamCompleteIndHandler()\n"); + return; + } + skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr); + skb->len = bulkdata.d[0].data_length; + + memcpy(skb->data, arp_req, sizeof(arp_req)); + /* add MAC and IP address */ + memcpy(skb->data + 16, priv->netdev[interfaceTag]->dev_addr, ETH_ALEN); + skb->data[22] = (priv->sta_ip_address ) & 0xFF; + skb->data[23] = (priv->sta_ip_address >> 8) & 0xFF; + skb->data[24] = (priv->sta_ip_address >> 16) & 0xFF; + skb->data[25] = (priv->sta_ip_address >> 24) & 0xFF; + skb->data[32] = (priv->sta_ip_address ) & 0xFF; + skb->data[33] = (priv->sta_ip_address >> 8) & 0xFF; + skb->data[34] = (priv->sta_ip_address >> 16) & 0xFF; + skb->data[35] = (priv->sta_ip_address >> 24) & 0xFF; + + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].os_net_buf_ptr = NULL; + bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0; + + if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, &arp_req[26])) < 0) + { + unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: Failed to determine protection mode\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + return; + } + + if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1) + { + priority = CSR_QOS_UP0; + } + else + { + priority = CSR_CONTENTION; + } + + if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, + interfaceTag, &arp_req[26], + priv->netdev[interfaceTag]->dev_addr, protection)) + { + unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to create MAC header\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + return; + } + bulkdata.d[0].os_data_ptr = skb->data; + bulkdata.d[0].os_net_buf_ptr = skb; + bulkdata.d[0].data_length = skb->len; + + unifi_frame_ma_packet_req(priv, priority, 0, 0xffffffff, interfaceTag, + CSR_NO_CONFIRM_REQUIRED, priv->netdev_client->sender_id, + interfacePriv->bssid.a, &signal); + + r = ul_send_signal_unpacked(priv, &signal, &bulkdata); + if (r) + { + unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to send QOS data null packet result: %d\n",r); + unifi_net_data_free(priv, &bulkdata.d[0]); + return; + } + + func_exit(); + +} +#endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */ + +/* + * --------------------------------------------------------------------------- + * configure_data_port + * + * Store the new controlled port configuration. + * + * Arguments: + * priv Pointer to device private context struct + * port_cfg Pointer to the port configuration + * + * Returns: + * An unifi_ControlledPortAction value. + * --------------------------------------------------------------------------- + */ +static int +configure_data_port(unifi_priv_t *priv, + CsrWifiRouterCtrlPortAction port_action, + const CsrWifiMacAddress *macAddress, + const int queue, + CsrUint16 interfaceTag) +{ + const CsrUint8 broadcast_mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + unifi_port_config_t *port; + netInterface_priv_t *interfacePriv; + int i; + const char* controlled_string; /* cosmetic "controlled"/"uncontrolled" for trace */ + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "configure_data_port: bad interfaceTag\n"); + return -EFAULT; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + if (queue == UF_CONTROLLED_PORT_Q) { + port = &interfacePriv->controlled_data_port; + controlled_string = "controlled"; + } else { + port = &interfacePriv->uncontrolled_data_port; + controlled_string = "uncontrolled"; + } + + unifi_trace(priv, UDBG2, "port config request %02x:%02x:%02x:%02x:%02x:%02x %s with port_action %d.\n", + macAddress->a[0], macAddress->a[1], macAddress->a[2], + macAddress->a[3], macAddress->a[4], macAddress->a[5], + controlled_string, port_action); + + + /* If the new configuration has the broadcast MAC address or if we are in infrastructure mode then clear the list first and set port overide mode */ + if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) || + !memcmp(macAddress->a, broadcast_mac_address, ETH_ALEN)) { + + port->port_cfg[0].port_action = port_action; + port->port_cfg[0].mac_address = *macAddress; + port->port_cfg[0].in_use = TRUE; + port->entries_in_use = 1; + port->overide_action = UF_DATA_PORT_OVERIDE; + + unifi_trace(priv, UDBG2, "%s port override on\n", + (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled"); + + /* Discard the remaining entries in the port config table */ + for (i = 1; i < UNIFI_MAX_CONNECTIONS; i++) { + port->port_cfg[i].in_use = FALSE; + } + + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { + unifi_trace(priv, UDBG1, "%s port broadcast set to open.\n", + (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled"); + + /* + * Ask stack to schedule for transmission any packets queued + * while controlled port was not open. + * Use netif_schedule() instead of netif_wake_queue() because + * transmission should be already enabled at this point. If it + * is not, probably the interface is down and should remain as is. + */ + uf_resume_data_plane(priv, queue, *macAddress, interfaceTag); + +#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP + if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && + (queue == UF_CONTROLLED_PORT_Q) && (priv->sta_ip_address != 0xFFFFFFFF)) + { + uf_send_gratuitous_arp(priv, interfaceTag); + } +#endif + } else { + unifi_trace(priv, UDBG1, "%s port broadcast set to %s.\n", + (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled", + (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) ? "discard": "closed"); + + /* If port is closed, discard all the pending Rx packets */ + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) { + uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag); + } + } + } else { + /* store the new configuration, either in the entry with matching mac address (if already present), + * otherwise in a new entry + */ + + int found_entry_flag; + int first_free_slot = -1; + + /* If leaving override mode, free the port entry used for override */ + if (port->overide_action == UF_DATA_PORT_OVERIDE) { + port->port_cfg[0].in_use = FALSE; + port->entries_in_use = 0; + port->overide_action = UF_DATA_PORT_NOT_OVERIDE; + + unifi_trace(priv, UDBG2, "%s port override off\n", + (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled"); + } + + found_entry_flag = 0; + for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + if (port->port_cfg[i].in_use) { + if (!memcmp(&port->port_cfg[i].mac_address.a, macAddress->a, ETH_ALEN)) { + /* We've seen this address before, reconfigure it */ + port->port_cfg[i].port_action = port_action; + found_entry_flag = 1; + break; + } + } else if (first_free_slot == -1) { + /* Remember the first free slot on the way past so it can be claimed + * if this turns out to be a new MAC address (to save walking the list again). + */ + first_free_slot = i; + } + } + + /* At this point we found an existing entry and have updated it, or need to + * add a new entry. If all slots are allocated, give up and return an error. + */ + if (!found_entry_flag) { + if (first_free_slot == -1) { + unifi_error(priv, "no free slot found in port config array (%d used)\n", port->entries_in_use); + return -EFAULT; + } else { + port->entries_in_use++; + } + + unifi_trace(priv, UDBG3, "port config index assigned in config_data_port = %d\n", first_free_slot); + port->port_cfg[first_free_slot].in_use = TRUE; + port->port_cfg[first_free_slot].port_action = port_action; + port->port_cfg[first_free_slot].mac_address = *macAddress; + } + + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { + /* + * Ask stack to schedule for transmission any packets queued + * while controlled port was not open. + * Use netif_schedule() instead of netif_wake_queue() because + * transmission should be already enabled at this point. If it + * is not, probably the interface is down and should remain as is. + */ + uf_resume_data_plane(priv, queue, *macAddress, interfaceTag); + } + + /* + * If port is closed, discard all the pending Rx packets + * coming from the peer station. + */ + if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) { + uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag); + } + + unifi_trace(priv, UDBG2, "port config %02x:%02x:%02x:%02x:%02x:%02x with port_action %d.\n", + *(macAddress->a+0), *(macAddress->a+1), *(macAddress->a+2), + *(macAddress->a+3), *(macAddress->a+4), *(macAddress->a+5), + port_action); + } + return 0; +} /* configure_data_port() */ + + +void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlPortConfigureReq* req = (CsrWifiRouterCtrlPortConfigureReq*)msg; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + + unifi_trace(priv, UDBG3, "entering CsrWifiRouterCtrlPortConfigureReqHandler\n"); + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlPortConfigureReqHandler: invalid smepriv\n"); + return; + } + + /* To update the protection status of the peer/station */ + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_AMP: + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + /* Since for Unifi as a station, the station record not maintained & interfaceID is + * only needed to update the peer protection status + */ + interfacePriv->protect = req->setProtection; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + { + CsrUint8 i; + CsrWifiRouterCtrlStaInfo_t *staRecord; + /* Ifscontrolled port is open means, The peer has been added to station record + * so that the protection corresponding to the peer is valid in this req + */ + if (req->controlledPortAction == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) { + for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) { + staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]); + if (staRecord) { + /* Find the matching station record & set the protection type */ + if (!memcmp(req->macAddress.a, staRecord->peerMacAddress.a, ETH_ALEN)) { + staRecord->protection = req->setProtection; + break; + } + } + } + } + } + break; + default: + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlPortConfigureReqHandler(0x%.4X) Uncaught mode %d\n", + msg->source, interfacePriv->interfaceMode); + } + + configure_data_port(priv, req->uncontrolledPortAction, (const CsrWifiMacAddress *)&req->macAddress, + UF_UNCONTROLLED_PORT_Q, req->interfaceTag); + configure_data_port(priv, req->controlledPortAction, (const CsrWifiMacAddress *)&req->macAddress, + UF_CONTROLLED_PORT_Q, req->interfaceTag); + + CsrWifiRouterCtrlPortConfigureCfmSend(msg->source,req->clientData,req->interfaceTag, + CSR_RESULT_SUCCESS, req->macAddress); + unifi_trace(priv, UDBG3, "leaving CsrWifiRouterCtrlPortConfigureReqHandler\n"); +} + + +void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlVersions versions; + CsrWifiRouterCtrlWifiOnReq* req = (CsrWifiRouterCtrlWifiOnReq*)msg; + int r,i; + CsrResult csrResult; + + if (priv == NULL) { + return; + } + for (i=0; iinterfacePriv[i]->interfaceMode = 0; + } + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X)\n", msg->source); + + /* + * The request to initialise UniFi might come while UniFi is running. + * We need to block all I/O activity until the reset completes, otherwise + * an SDIO error might occur resulting an indication to the SME which + * makes it think that the initialisation has failed. + */ + priv->bh_thread.block_thread = 1; + + /* Update the wifi_on state */ + priv->wifi_on_state = wifi_on_in_progress; + + r = uf_request_firmware_files(priv, UNIFI_FW_STA); + if (r) { + unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n"); + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); + return; + } + + /* Power on UniFi (which may not necessarily have been off) */ + CsrSdioClaim(priv->sdio); + csrResult = CsrSdioPowerOn(priv->sdio); + CsrSdioRelease(priv->sdio); + if (csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) { + unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to power on UniFi\n"); + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); + return; + } + + /* If CsrSdioPowerOn() returns CSR_RESULT_SUCCESS, it means that we need to initialise UniFi */ + if (csrResult == CSR_RESULT_SUCCESS && !priv->wol_suspend) { + /* Initialise UniFi hardware */ + r = uf_init_hw(priv); + if (r) { + unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r); + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); + return; + } + } else { + unifi_trace(priv, UDBG1, "UniFi already initialised\n"); + } + + /* Completed handling of wake up from suspend with UniFi powered */ + priv->wol_suspend = FALSE; + + /* Re-enable the I/O thread */ + priv->bh_thread.block_thread = 0; + + /* + * Start the I/O thread. The thread might be already running. + * This fine, just carry on with the request. + */ + r = uf_init_bh(priv); + if (r) { + CsrSdioClaim(priv->sdio); + CsrSdioPowerOff(priv->sdio); + CsrSdioRelease(priv->sdio); + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); + return; + } + + /* Get the version information from the core */ + unifi_card_info(priv->card, &priv->card_info); + + /* Set the sme queue id */ + priv->CSR_WIFI_SME_IFACEQUEUE = msg->source; + CSR_WIFI_SME_IFACEQUEUE = msg->source; + + + /* Copy to the unifiio_card_info structure. */ + versions.chipId = priv->card_info.chip_id; + versions.chipVersion = priv->card_info.chip_version; + versions.firmwareBuild = priv->card_info.fw_build; + versions.firmwareHip = priv->card_info.fw_hip_version; + versions.routerBuild = (CsrCharString*)CSR_WIFI_VERSION; + versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION; + + CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions); + + /* Update the wifi_on state */ + priv->wifi_on_state = wifi_on_done; +} + + +/* + * wifi_off: + * Common code for CsrWifiRouterCtrlWifiOffReqHandler() and + * CsrWifiRouterCtrlWifiOffRspHandler(). + */ +static void +wifi_off(unifi_priv_t *priv) +{ + int power_off; + int priv_instance; + int i; + CsrResult csrResult; + + unifi_trace(priv, UDBG1, "wifi_off\n"); + + /* Destroy the Traffic Analysis Module */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) + cancel_work_sync(&priv->ta_ind_work.task); + cancel_work_sync(&priv->ta_sample_ind_work.task); +#ifdef CSR_SUPPORT_WEXT + cancel_work_sync(&priv->sme_config_task); +#endif + + /* Cancel pending M4 stuff */ + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + if (priv->netdev[i]) { + netInterface_priv_t *netpriv = (netInterface_priv_t *) netdev_priv(priv->netdev[i]); + cancel_work_sync(&netpriv->send_m4_ready_task); + } + } +#endif + flush_workqueue(priv->unifi_workqueue); + + /* fw_init parameter can prevent power off UniFi, for debugging */ + priv_instance = uf_find_priv(priv); + if (priv_instance == -1) { + unifi_warning(priv, + "CsrWifiRouterCtrlStopReqHandler: Unknown priv instance, will power off card.\n"); + power_off = 1; + } else { + power_off = (fw_init[priv_instance] > 0) ? 0 : 1; + } + + /* Production test mode requires power to the chip, too */ + if (priv->ptest_mode) { + power_off = 0; + } + + /* Stop the bh_thread */ + uf_stop_thread(priv, &priv->bh_thread); + + /* Read the f/w panic codes, if any. Protect against second wifi_off() call, + * which may happen if SME requests a wifi_off and closes the char device */ + if (priv->init_progress != UNIFI_INIT_NONE) { + CsrSdioClaim(priv->sdio); + unifi_capture_panic(priv->card); + CsrSdioRelease(priv->sdio); + } + + /* Unregister the interrupt handler */ + if (csr_sdio_linux_remove_irq(priv->sdio)) { + unifi_notice(priv, + "csr_sdio_linux_remove_irq failed to talk to card.\n"); + } + + if (power_off) { + unifi_trace(priv, UDBG2, + "Force low power and try to power off\n"); + /* Put UniFi to deep sleep, in case we can not power it off */ + CsrSdioClaim(priv->sdio); + csrResult = unifi_force_low_power_mode(priv->card); + CsrSdioRelease(priv->sdio); + + CsrSdioPowerOff(priv->sdio); + } + + /* Consider UniFi to be uninitialised */ + priv->init_progress = UNIFI_INIT_NONE; + priv->wifi_on_state = wifi_on_unspecified; + + +} /* wifi_off() */ + + +void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg; + int i = 0; +#ifdef CSR_SUPPORT_WEXT_AP + CsrWifiSmeWifiOffCfm cfm; +#endif + + if (priv == NULL) { + return; + } + + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOffReqHandler(0x%.4X)\n", msg->source); + + /* Stop the network traffic on all interfaces before freeing the core. */ + for (i=0; iinterfacePriv[i]; + if (interfacePriv->netdev_registered == 1) { + netif_carrier_off(priv->netdev[i]); + UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]); + } + interfacePriv->interfaceMode = 0; + + /* Enable all queues by default */ + interfacePriv->queueEnabled[0] = 1; + interfacePriv->queueEnabled[1] = 1; + interfacePriv->queueEnabled[2] = 1; + interfacePriv->queueEnabled[3] = 1; + } + wifi_off(priv); + + CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData); +#ifdef CSR_SUPPORT_WEXT_AP + /* Router is turned off when WifiOffCfm is received + * hence for wext we don't see WifiOffCfm in the wext + * files. So just tell the waiting process that + * Wifi off is successful + */ + cfm.status = CSR_RESULT_SUCCESS; + CsrWifiSmeWifiOffCfmHandler(priv,(CsrWifiFsmEvent*)(&cfm)); +#endif +} + + +void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlQosControlReq* req = (CsrWifiRouterCtrlQosControlReq*)msg; + netInterface_priv_t *interfacePriv; + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: invalid smepriv\n"); + return; + } + + unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlQosControlReqHandler:scontrol = %d", req->control); + + if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n"); + return; + } + interfacePriv = priv->interfacePriv[req->interfaceTag]; + + if (req->control == CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON) { + priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED; + unifi_trace(priv, UDBG1, "WMM enabled\n"); + + unifi_trace(priv, UDBG1, "Queue Config %x\n", req->queueConfig); + + interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BK] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE)?1:0; + interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BE] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE)?1:0; + interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VI] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE)?1:0; + interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VO] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE)?1:0; + + } else { + priv->sta_wmm_capabilities = 0; + unifi_trace(priv, UDBG1, "WMM disabled\n"); + } +} + + +void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlTclasAddReq* req = (CsrWifiRouterCtrlTclasAddReq*)msg; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlTclasAddReqHandler: invalid smepriv\n"); + return; + } + + CsrWifiRouterCtrlTclasAddCfmSend(msg->source, req->clientData, req->interfaceTag , CSR_RESULT_SUCCESS); +} + +void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlTclasDelReq* req = (CsrWifiRouterCtrlTclasDelReq*)msg; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlTclasDelReqHandler: invalid smepriv\n"); + return; + } + + CsrWifiRouterCtrlTclasDelCfmSend(msg->source, req->clientData, req->interfaceTag, CSR_RESULT_SUCCESS); +} + + +void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlConfigurePowerModeReq* req = (CsrWifiRouterCtrlConfigurePowerModeReq*)msg; + enum unifi_low_power_mode pm; + CsrResult csrResult; + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlConfigurePowerModeReqHandler: invalid smepriv\n"); + return; + } + + if (req->mode == CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED) { + pm = UNIFI_LOW_POWER_DISABLED; + } else { + pm = UNIFI_LOW_POWER_ENABLED; + } + + unifi_trace(priv, UDBG2, + "CsrWifiRouterCtrlConfigurePowerModeReqHandler (mode=%d, wake=%d)\n", + req->mode, req->wakeHost); + csrResult = unifi_configure_low_power_mode(priv->card, pm, + (req->wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED)); +} + + +void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWifiOnRes* res = (CsrWifiRouterCtrlWifiOnRes*)msg; + + if (priv == NULL) { + unifi_error(NULL, "CsrWifiRouterCtrlWifiOnResHandler: Invalid ospriv.\n"); + return; + } + + unifi_trace(priv, UDBG1, + "CsrWifiRouterCtrlWifiOnResHandler: status %d (patch %u)\n", res->status, res->smeVersions.firmwarePatch); + + if (res->smeVersions.firmwarePatch != 0) { + unifi_info(priv, "Firmware patch %d\n", res->smeVersions.firmwarePatch); + } + + if (res->numInterfaceAddress > CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "WifiOnResHandler bad numInterfaceAddress %d\n", res->numInterfaceAddress); + return; + } + + /* UniFi is now initialised, complete the init. */ + if (res->status == CSR_RESULT_SUCCESS) + { + int i; /* used as a loop counter */ + CsrUint32 intmode = CSR_WIFI_INTMODE_DEFAULT; + + /* Register the UniFi device with the OS network manager */ + unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n"); + + /* Store the MAC address in the netdev */ + for(i=0;inumInterfaceAddress;i++) + { + memcpy(priv->netdev[i]->dev_addr, res->stationMacAddress[i].a, ETH_ALEN); + } + + /* Copy version structure into the private versions field */ + priv->sme_versions = res->smeVersions; + + unifi_trace(priv, UDBG2, "network interfaces count = %d\n", + res->numInterfaceAddress); + + /* Register the netdevs for each interface. */ + for(i=0;inumInterfaceAddress;i++) + { + netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; + if(!interfacePriv->netdev_registered) + { + int r; + unifi_trace(priv, UDBG3, "registering net device %d\n", i); + r = uf_register_netdev(priv, i); + if (r) + { + /* unregister the net_device that are registered in the previous iterations */ + uf_unregister_netdev(priv); + unifi_error(priv, "Failed to register the network device.\n"); + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE); + return; + } + } + } + priv->totalInterfaceCount = res->numInterfaceAddress; + + /* If the MIB has selected f/w scheduled interrupt mode, apply it now + * but let module param override. + */ + if (run_bh_once != -1) { + intmode = (CsrUint32)run_bh_once; + } else if (res->scheduledInterrupt) { + intmode = CSR_WIFI_INTMODE_RUN_BH_ONCE; + } + unifi_set_interrupt_mode(priv->card, intmode); + + priv->init_progress = UNIFI_INIT_COMPLETED; + + /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */ + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS); + + unifi_info(priv, "UniFi ready\n"); + + /* Firmware initialisation is complete, so let the SDIO bus + * clock be raised when convienent to the core. + */ + unifi_request_max_sdio_clock(priv->card); + +#ifdef CSR_SUPPORT_WEXT + /* Notify the Android wpa_supplicant that we are ready */ + wext_send_started_event(priv); + + queue_work(priv->unifi_workqueue, &priv->sme_config_task); +#endif + + } else { + /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */ + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE); + } +} + + +void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + + +void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + + +void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterMaPacketSubscribeReq* req = (CsrWifiRouterMaPacketSubscribeReq*)msg; + CsrUint8 i; + CsrResult result; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterMaPacketSubscribeReqHandler: invalid priv\n"); + return; + } + + /* Look for an unused filter */ + + result = CSR_WIFI_RESULT_NO_ROOM; + for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) { + + if (!priv->sme_unidata_ind_filters[i].in_use) { + + priv->sme_unidata_ind_filters[i].in_use = 1; + priv->sme_unidata_ind_filters[i].appHandle = msg->source; + priv->sme_unidata_ind_filters[i].encapsulation = req->encapsulation; + priv->sme_unidata_ind_filters[i].protocol = req->protocol; + + priv->sme_unidata_ind_filters[i].oui[2] = (CsrUint8) (req->oui & 0xFF); + priv->sme_unidata_ind_filters[i].oui[1] = (CsrUint8) ((req->oui >> 8) & 0xFF); + priv->sme_unidata_ind_filters[i].oui[0] = (CsrUint8) ((req->oui >> 16) & 0xFF); + + result = CSR_RESULT_SUCCESS; + break; + } + } + + unifi_trace(priv, UDBG1, + "subscribe_req: encap=%d, handle=%d, result=%d\n", + req->encapsulation, i, result); + CsrWifiRouterMaPacketSubscribeCfmSend(msg->source,req->interfaceTag, i, result, 0); +} + + +void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterMaPacketUnsubscribeReq* req = (CsrWifiRouterMaPacketUnsubscribeReq*)msg; + CsrResult result; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterMaPacketUnsubscribeReqHandler: invalid priv\n"); + return; + } + + result = CSR_WIFI_RESULT_NOT_FOUND; + + if (req->subscriptionHandle < MAX_MA_UNIDATA_IND_FILTERS) { + if (priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use) { + priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use = 0; + result = CSR_RESULT_SUCCESS; + } else { + result = CSR_WIFI_RESULT_NOT_FOUND; + } + } + + unifi_trace(priv, UDBG1, + "unsubscribe_req: handle=%d, result=%d\n", + req->subscriptionHandle, result); + CsrWifiRouterMaPacketUnsubscribeCfmSend(msg->source,req->interfaceTag, result); +} + + +void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlCapabilitiesReq* req = (CsrWifiRouterCtrlCapabilitiesReq*)msg; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlCapabilitiesReqHandler: invalid priv\n"); + return; + } + + CsrWifiRouterCtrlCapabilitiesCfmSend(msg->source,req->clientData, + UNIFI_SOFT_COMMAND_Q_LENGTH - 1, + UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1); +} + + +void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlSuspendRes* res = (CsrWifiRouterCtrlSuspendRes*)msg; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlSuspendResHandler: invalid priv\n"); + return; + } + + sme_complete_request(priv, res->status); +} + + +void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlResumeRes* res = (CsrWifiRouterCtrlResumeRes*)msg; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlResumeResHandler: invalid priv\n"); + return; + } + + /* + * Unless we are in ptest mode, nothing is waiting for the response. + * Do not call sme_complete_request(), otherwise the driver + * and the SME will be out of step. + */ + if (priv->ptest_mode == 1) { + sme_complete_request(priv, res->status); + } + +} + + +void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlTrafficConfigReq* req = (CsrWifiRouterCtrlTrafficConfigReq*)msg; + CsrResult csrResult; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlTrafficConfigReqHandler: invalid smepriv\n"); + return; + } + if (req->trafficConfigType == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER) + { + req->config.packetFilter |= CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM; + } + csrResult = unifi_ta_configure(priv->card, req->trafficConfigType, (const CsrWifiRouterCtrlTrafficConfig *)&req->config); +} + +void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlTrafficClassificationReq* req = (CsrWifiRouterCtrlTrafficClassificationReq*)msg; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlTrafficClassificationReqHandler: invalid smepriv\n"); + return; + } + + unifi_ta_classification(priv->card, req->trafficType, req->period); +} + +static int +_sys_packet_req(unifi_priv_t *priv, const CSR_SIGNAL *signal, + CsrUint8 subscriptionHandle, + CsrUint16 frameLength, CsrUint8 *frame, + int proto) +{ + int r; + const sme_ma_unidata_ind_filter_t *subs; + bulk_data_param_t bulkdata; + CSR_MA_PACKET_REQUEST req = signal->u.MaPacketRequest; + struct sk_buff *skb, *newSkb = NULL; + CsrWifiMacAddress peerMacAddress; + CsrResult csrResult; + CsrUint16 interfaceTag = req.VirtualInterfaceIdentifier & 0xff; + CsrBool eapolStore = FALSE; + CsrInt8 protection = 0; + netInterface_priv_t *interfacePriv; + unsigned long flags; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "_sys_packet_req: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n"); + return -EINVAL; + } + interfacePriv = priv->interfacePriv[interfaceTag]; + if (!priv->sme_unidata_ind_filters[subscriptionHandle].in_use) { + unifi_error(priv, "_sys_packet_req: unknown subscription.\n"); + return -EINVAL; + } + + subs = &priv->sme_unidata_ind_filters[subscriptionHandle]; + unifi_trace(priv, UDBG1, + "_sys_packet_req: handle=%d, subs=%p, encap=%d\n", + subscriptionHandle, subs, subs->encapsulation); + + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], frameLength); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "_sys_packet_req: failed to allocate bulkdata.\n"); + return (int)CsrHipResultToStatus(csrResult); + } + + /* get the peer Mac address */ + memcpy(&peerMacAddress, frame, ETH_ALEN); + + /* Determine if we need to add encapsulation header */ + if (subs->encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) { + memcpy((void*)bulkdata.d[0].os_data_ptr, frame, frameLength); + + /* The translation is performed on the skb */ + skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr; + + unifi_trace(priv, UDBG1, + "_sys_packet_req: skb_add_llc_snap -->\n"); + r = skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto); + unifi_trace(priv, UDBG1, + "_sys_packet_req: skb_add_llc_snap <--\n"); + if (r) { + unifi_error(priv, + "_sys_packet_req: failed to translate eth frame.\n"); + unifi_net_data_free(priv,&bulkdata.d[0]); + return r; + } + + bulkdata.d[0].data_length = skb->len; + } else { + /* Crop the MAC addresses from the packet */ + memcpy((void*)bulkdata.d[0].os_data_ptr, frame + 2*ETH_ALEN, frameLength - 2*ETH_ALEN); + bulkdata.d[0].data_length = frameLength - 2*ETH_ALEN; + skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr; + skb->len = bulkdata.d[0].data_length; + + } + + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].os_net_buf_ptr = NULL; + bulkdata.d[1].data_length = 0; + + /* check for m4 detection */ + if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) { + eapolStore = TRUE; + } + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + if (proto == ETH_P_WAI) + { + protection = 0; /*WAI packets always sent unencrypted*/ + } + else + { +#endif + +#ifdef CSR_SUPPORT_SME + if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, peerMacAddress.a)) < 0) { + unifi_error(priv, "unicast address, but destination not in station record database\n"); + unifi_net_data_free(priv,&bulkdata.d[0]); + return -1; + } +#else + protection = 0; +#endif + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + } +#endif + + /* add Mac header */ + if (prepare_and_add_macheader(priv, skb, newSkb, req.Priority, &bulkdata, interfaceTag, frame, frame + ETH_ALEN, protection)) { + unifi_error(priv, "failed to create MAC header\n"); + unifi_net_data_free(priv,&bulkdata.d[0]); + return -1; + } + + if (eapolStore) { + spin_lock_irqsave(&priv->m4_lock, flags); + /* Store the EAPOL M4 packet for later */ + interfacePriv->m4_signal = *signal; + interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length; + interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length; + interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr; + interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr; + spin_unlock_irqrestore(&priv->m4_lock, flags); + /* Send a signal to SME */ + unifi_trace(priv, UDBG1, "_sys_packet_req: Sending CsrWifiRouterCtrlM4ReadyToSendInd\n"); + CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress); + return 0; + } + + /* Send the signal to UniFi */ + /* Set the B31 to 1 for local routing*/ + r= uf_process_ma_packet_req(priv, peerMacAddress.a, (req.HostTag | 0x80000000), interfaceTag, 0, + (CSR_RATE)0, req.Priority, signal->SignalPrimitiveHeader.SenderProcessId, &bulkdata); + if (r) { + unifi_error(priv, + "_sys_packet_req: failed to send signal.\n"); + unifi_net_data_free(priv,&bulkdata.d[0]); + return r; + } + /* The final CsrWifiRouterMaPacketCfmSend() will called when the actual MA-PACKET.cfm is received from the chip */ + + return 0; +} + +void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + int r; + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterMaPacketReq* mareq = (CsrWifiRouterMaPacketReq*)msg; + llc_snap_hdr_t *snap; + CsrUint16 snap_protocol; + CSR_SIGNAL signal; + CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest; + CsrWifiRouterCtrlPortAction controlPortaction; + CsrUint8 *daddr, *saddr; + CsrUint16 interfaceTag = mareq->interfaceTag & 0x00ff; + int queue; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if (!mareq->frame || !priv || !priv->smepriv) + { + unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: invalid frame/priv/priv->smepriv\n"); + return; + } + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n"); + return; + } + /* get a pointer to dest & source Mac address */ + daddr = mareq->frame; + saddr = (mareq->frame + ETH_ALEN); + /* point to the proper position of frame, since frame has MAC header */ + snap = (llc_snap_hdr_t *) (mareq->frame + 2 * ETH_ALEN); + snap_protocol = ntohs(snap->protocol); + if((snap_protocol == ETH_P_PAE) +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + || (snap_protocol == ETH_P_WAI) +#endif + ) + { + queue = UF_UNCONTROLLED_PORT_Q; + } + else + { + queue = UF_CONTROLLED_PORT_Q; + } + + /* Controlled port restrictions apply to the packets */ + controlPortaction = uf_sme_port_state(priv, daddr, queue, interfaceTag); + if (controlPortaction != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) + { + unifi_warning(priv, "CsrWifiRouterMaPacketReqHandler: (%s)controlled port is closed.\n", (queue == UF_CONTROLLED_PORT_Q)?"":"un"); + if(mareq->cfmRequested) + { + CsrWifiRouterMaPacketCfmSend(msg->source, + interfaceTag, + CSR_RESULT_FAILURE, + mareq->hostTag, 0); + } + return; + } + + signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID; + /* Store the appHandle in the LSB of the SenderId. */ + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->sme_cli->sender_id & 0xff00) | (unsigned int)msg->source), + (u8*)&signal.SignalPrimitiveHeader.SenderProcessId); + signal.SignalPrimitiveHeader.ReceiverProcessId = 0; + + /* Fill in the MA-PACKET.req signal */ + memcpy(req->Ra.x, daddr, ETH_ALEN); + req->Priority = mareq->priority; + req->TransmitRate = 0; /* Let firmware select the rate*/ + req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag); + req->HostTag = mareq->hostTag; + + if(mareq->cfmRequested) + req->TransmissionControl = 0; + else + req->TransmissionControl = CSR_NO_CONFIRM_REQUIRED; + + r = _sys_packet_req(priv, &signal, mareq->subscriptionHandle, + mareq->frameLength, mareq->frame, snap_protocol); + +#define MAX_RETRY 2 + if (r && mareq->cfmRequested) + { + CsrWifiRouterMaPacketCfmSend(msg->source,interfaceTag, + CSR_RESULT_FAILURE, + mareq->hostTag, 0); + } + return; +} + +void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlM4TransmitReq* req = (CsrWifiRouterCtrlM4TransmitReq*)msg; + int r; + bulk_data_param_t bulkdata; + netInterface_priv_t *interfacePriv; + CSR_SIGNAL m4_signal; + unsigned long flags; + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid smepriv\n"); + return; + } + if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "M4TransmitReqHandler: interfaceTag >= CSR_WIFI_NUM_INTERFACES\n"); + return; + } + + interfacePriv = priv->interfacePriv[req->interfaceTag]; + spin_lock_irqsave(&priv->m4_lock, flags); + if (interfacePriv->m4_bulk_data.data_length == 0) { + spin_unlock_irqrestore(&priv->m4_lock, flags); + unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid buffer\n"); + return; + } + + memcpy(&bulkdata.d[0], &interfacePriv->m4_bulk_data, sizeof(bulk_data_desc_t)); + + interfacePriv->m4_bulk_data.net_buf_length = 0; + interfacePriv->m4_bulk_data.data_length = 0; + interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL; + m4_signal = interfacePriv->m4_signal; + spin_unlock_irqrestore(&priv->m4_lock, flags); + + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].data_length = 0; + + interfacePriv->m4_sent = TRUE; + m4_signal.u.MaPacketRequest.HostTag |= 0x80000000; + /* Store the hostTag for later varification */ + interfacePriv->m4_hostTag = m4_signal.u.MaPacketRequest.HostTag; + r = ul_send_signal_unpacked(priv, &m4_signal, &bulkdata); + unifi_trace(priv, UDBG1, + "CsrWifiRouterCtrlM4TransmitReqHandler: sent\n"); + if (r) { + unifi_error(priv, + "CsrWifiRouterCtrlM4TransmitReqHandler: failed to send signal.\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + } +} + +/* reset the station records when the mode is set as CSR_WIFI_ROUTER_CTRL_MODE_NONE */ +static void CsrWifiRouterCtrlResetStationRecordList(unifi_priv_t *priv, CsrUint16 interfaceTag) +{ + CsrUint8 i,j; + CsrWifiRouterCtrlStaInfo_t *staInfo=NULL; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + unsigned long lock_flags; + + /* create a list for sending confirms of un-delivered packets */ + struct list_head send_cfm_list; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "CsrWifiRouterCtrlResetStationRecordList: bad interfaceTag\n"); + return; + } + + INIT_LIST_HEAD(&send_cfm_list); + + /* Reset the station record to NULL if mode is NONE */ + for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + if ((staInfo=interfacePriv->staInfo[i]) != NULL) { + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staInfo->mgtFrames)); + uf_flush_list(priv,&(staInfo->mgtFrames)); + for(j=0;jdataPdu[j])); + uf_flush_list(priv,&(staInfo->dataPdu[j])); + } + + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + /* Removing station record information from port config array */ + memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t)); + staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + staInfo->peerControlledPort->in_use = FALSE; + interfacePriv->controlled_data_port.entries_in_use--; + + memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t)); + staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + staInfo->peerUnControlledPort->in_use = FALSE; + interfacePriv->uncontrolled_data_port.entries_in_use--; + + kfree(interfacePriv->staInfo[i]); + interfacePriv->staInfo[i] = NULL; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } + } + /* after the critical region process the list of frames that requested cfm + * and send cfm to requestor one by one + */ + send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list); + +#ifdef CSR_SUPPORT_SME + /* Interface Independent, no of packet queued, incase of mode is None or AP set to 0 */ + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + case CSR_WIFI_ROUTER_CTRL_MODE_NONE: + if (priv->noOfPktQueuedInDriver) { + unifi_warning(priv, "After reset the noOfPktQueuedInDriver = %x\n", priv->noOfPktQueuedInDriver); + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + priv->noOfPktQueuedInDriver = 0; + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + } + break; + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + break; + default: + unifi_error(priv, "interfacemode is not correct in CsrWifiRouterCtrlResetStationRecordList: debug\n"); + } +#endif + + if (((interfacePriv->controlled_data_port.entries_in_use != 0) || (interfacePriv->uncontrolled_data_port.entries_in_use != 0)) + && (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE)) { + /* Print in case if the value of entries goes to -ve/+ve (apart from 0) + * we expect the entries should be zero here if mode is set as NONE + */ + unifi_trace(priv, UDBG3, "In %s controlled port entries = %d, uncontrolled port entries = %d\n", + __FUNCTION__, interfacePriv->controlled_data_port.entries_in_use, + interfacePriv->uncontrolled_data_port.entries_in_use); + } +} + +void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, CsrUint16 interfaceTag) +{ + netInterface_priv_t *interfacePriv; + + /* create a list for sending confirms of un-delivered packets */ + struct list_head send_cfm_list; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "CsrWifiRouterCtrlInterfaceReset: bad interfaceTag\n"); + return; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + INIT_LIST_HEAD(&send_cfm_list); + + /* Enable all queues by default */ + interfacePriv->queueEnabled[0] = 1; + interfacePriv->queueEnabled[1] = 1; + interfacePriv->queueEnabled[2] = 1; + interfacePriv->queueEnabled[3] = 1; + + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(interfacePriv->genericMgtFrames)); + uf_flush_list(priv,&(interfacePriv->genericMgtFrames)); + + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(interfacePriv->genericMulticastOrBroadCastMgtFrames)); + uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastMgtFrames)); + + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(interfacePriv->genericMulticastOrBroadCastFrames)); + + uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames)); + uf_flush_maPktlist(priv,&(interfacePriv->directedMaPktReq)); + + /* process the list of frames that requested cfm + and send cfm to requestor one by one */ + send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list); + + /* Reset the station record to NULL if mode is tried to set as NONE */ + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR: + case CSR_WIFI_ROUTER_CTRL_MODE_AMP: + /* station records not available in these modes */ + break; + default: + CsrWifiRouterCtrlResetStationRecordList(priv,interfaceTag); + } + + interfacePriv->num_stations_joined = 0; + interfacePriv->sta_activity_check_enabled = FALSE; +} + + +void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlModeSetReq* req = (CsrWifiRouterCtrlModeSetReq*)msg; + + if (priv == NULL) + { + unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid smepriv\n"); + return; + } + + if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES) + { + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n", + interfacePriv->interfaceMode); + + /* Cleanup the database first for current existing mode, Then take + * care of setting the new mode (Transition seq: AnyMode->NoneMode->newMode) + * So for Every mode changes, Database Initialization/cleanup needed + */ + CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag); + + interfacePriv->interfaceMode = req->mode; + interfacePriv->bssid = req->bssid; + /* For modes other than AP/P2PGO, set below member FALSE */ + interfacePriv->intraBssEnabled = FALSE; + + + if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + interfacePriv->protect = req->protection; + interfacePriv->dtimActive=FALSE; + interfacePriv->multicastPduHostTag = 0xffffffff; + /* For AP/P2PGO mode SME sending intraBssDistEnabled + * i.e. for AP: intraBssDistEnabled = TRUE, for P2PGO + * intraBssDistEnabled = TRUE/FALSE on requirement + */ + interfacePriv->intraBssEnabled = req->intraBssDistEnabled; + unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlModeSetReqHandler: IntraBssDisEnabled = %d\n", + req->intraBssDistEnabled); + } else if (req->mode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) { + netif_carrier_off(priv->netdev[req->interfaceTag]); + interfacePriv->connected = UnifiConnectedUnknown; + } + } + else { + unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid interfaceTag :%d\n",req->interfaceTag); + } +} + +void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +} + +/* delete the station record from the station record data base */ +static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *req) +{ + CsrUint8 j; + CsrWifiRouterCtrlStaInfo_t *staInfo = NULL; + unifi_port_config_t *controlledPort; + unifi_port_config_t *unControlledPort; + netInterface_priv_t *interfacePriv; + maPktReqList_t *maPktreq; + struct list_head *listHeadMaPktreq,*placeHolderMaPktreq; + + CsrUint8 ba_session_idx = 0; + ba_session_rx_struct *ba_session_rx = NULL; + ba_session_tx_struct *ba_session_tx = NULL; + + /* create a list for sending confirms of un-delivered packets */ + struct list_head send_cfm_list; + + unsigned long lock_flags; + + if ((req->peerRecordHandle >= UNIFI_MAX_CONNECTIONS) || (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)) { + unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", req->peerRecordHandle, req->interfaceTag); + return CSR_RESULT_FAILURE; + } + + INIT_LIST_HEAD(&send_cfm_list); + + interfacePriv = priv->interfacePriv[req->interfaceTag]; + /* remove the station record & make it NULL */ + if ((staInfo=interfacePriv->staInfo[req->peerRecordHandle])!=NULL) { + + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staInfo->mgtFrames)); + + uf_flush_list(priv,&(staInfo->mgtFrames)); + for(j=0;jdataPdu[j])); + uf_flush_list(priv,&(staInfo->dataPdu[j])); + } + + /* There may be race condition + before getting the ma_packet_cfm from f/w, driver may receive peer del from SME + */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) { + maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q); + if(maPktreq->staHandler== staInfo->assignedHandle){ + dev_kfree_skb(maPktreq->skb); + list_del(listHeadMaPktreq); + kfree(maPktreq); + } + + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + /* clear the port configure array info, for the corresponding peer entry */ + controlledPort = &interfacePriv->controlled_data_port; + unControlledPort = &interfacePriv->uncontrolled_data_port; + + unifi_trace(priv, UDBG1, "peer_delete_record: Peer found handle = %d, port in use: cont(%d), unCont(%d)\n", + req->peerRecordHandle, controlledPort->entries_in_use, unControlledPort->entries_in_use); + + memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t)); + staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + staInfo->peerControlledPort->in_use = FALSE; + if (controlledPort->entries_in_use) { + controlledPort->entries_in_use--; + } else { + unifi_warning(priv, "number of controlled port entries is zero, trying to decrement: debug\n"); + } + + memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t)); + staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + staInfo->peerUnControlledPort->in_use = FALSE; + if (unControlledPort->entries_in_use) { + unControlledPort->entries_in_use--; + } else { + unifi_warning(priv, "number of uncontrolled port entries is zero, trying to decrement: debug\n"); + } + + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + /* update the TIM with zero */ + if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS && + staInfo->timSet == CSR_WIFI_TIM_SET) { + unifi_trace(priv, UDBG3, "peer is deleted so TIM updated to 0, in firmware\n"); + update_tim(priv,staInfo->aid,0,req->interfaceTag, req->peerRecordHandle); + } + + + /* Stop BA session if it is active, for this peer address all BA sessions + (per tID per role) are closed */ + + spin_lock(&priv->ba_lock); + for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ + ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx]; + if(ba_session_rx) { + if(!memcmp(ba_session_rx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){ + blockack_session_stop(priv, + req->interfaceTag, + CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT, + ba_session_rx->tID, + ba_session_rx->macAddress); + } + } + } + + for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){ + ba_session_tx = priv->interfacePriv[req->interfaceTag]->ba_session_tx[ba_session_idx]; + if(ba_session_tx) { + if(!memcmp(ba_session_tx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){ + blockack_session_stop(priv, + req->interfaceTag, + CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR, + ba_session_tx->tID, + ba_session_tx->macAddress); + } + } + } + + spin_unlock(&priv->ba_lock); + +#ifdef CSR_SUPPORT_SME + unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid); + cancel_work_sync(&staInfo->send_disconnected_ind_task); +#endif + + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); +#ifdef CSR_SUPPORT_SME + interfacePriv->num_stations_joined--; + + staInfo->nullDataHostTag = INVALID_HOST_TAG; + + if ((interfacePriv->sta_activity_check_enabled) && + (interfacePriv->num_stations_joined < STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)) + { + unifi_trace(priv, UDBG1, "STOPPING the Inactivity Timer (num of stations = %d)\n", interfacePriv->num_stations_joined); + interfacePriv->sta_activity_check_enabled = FALSE; + del_timer_sync(&interfacePriv->sta_activity_check_timer); + } +#endif + + /* Free the station record for corresponding peer */ + kfree(interfacePriv->staInfo[req->peerRecordHandle]); + interfacePriv->staInfo[req->peerRecordHandle] = NULL; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + /* after the critical region process the list of frames that requested cfm + and send cfm to requestor one by one */ + send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list); + + + } + else + { + unifi_trace(priv, UDBG3, " peer not found: Delete request Peer handle[%d]\n", req->peerRecordHandle); + } + + return CSR_RESULT_SUCCESS; +} + +void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + CsrWifiRouterCtrlPeerDelReq* req = (CsrWifiRouterCtrlPeerDelReq*)msg; + CsrResult status = CSR_RESULT_SUCCESS; + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + + unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerDelReqHandler \n"); + if (priv == NULL) + { + unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: invalid smepriv\n"); + return; + } + + if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: bad interfaceTag\n"); + return; + } + + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + /* remove the station from station record data base */ + status = peer_delete_record(priv, req); + break; + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + default: + /* No station record to maintain in these modes */ + break; + } + + CsrWifiRouterCtrlPeerDelCfmSend(msg->source,req->clientData,req->interfaceTag,status); + unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerDelReqHandler \n"); +} + +/* Add the new station to the station record data base */ +static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *req,CsrUint32 *handle) +{ + CsrUint8 i, powerModeTemp = 0; + CsrBool freeSlotFound = FALSE; + CsrWifiRouterCtrlStaInfo_t *newRecord = NULL; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + CsrTime currentTime, currentTimeHi; + unsigned long lock_flags; + + if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "peer_add_new_record: bad interfaceTag\n"); + return CSR_RESULT_FAILURE; + } + + currentTime = CsrTimeGet(¤tTimeHi); + + for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + if(interfacePriv->staInfo[i] == NULL) { + /* Slot is empty, so can be used for station record */ + freeSlotFound = TRUE; + *handle = i; + + /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER & + * DEL_PEER the allocation made atomic memory rather than kernel memory + */ + newRecord = (CsrWifiRouterCtrlStaInfo_t *) kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC); + if (!newRecord) { + unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n", + sizeof(CsrWifiRouterCtrlStaInfo_t)); + return CSR_RESULT_FAILURE; + } + + unifi_trace(priv, UDBG1, "peer_add_new_record: handle = %d AID = %d addr = %x:%x:%x:%x:%x:%x LI=%u\n", + *handle, req->associationId, req->peerMacAddress.a[0], req->peerMacAddress.a[1], req->peerMacAddress.a[2], + req->peerMacAddress.a[3], req->peerMacAddress.a[4], req->peerMacAddress.a[5], + req->staInfo.listenIntervalInTus); + + /* disable the preemption until station record updated */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + + interfacePriv->staInfo[i] = newRecord; + /* Initialize the record*/ + memset(newRecord,0,sizeof(CsrWifiRouterCtrlStaInfo_t)); + /* update the station record */ + memcpy(newRecord->peerMacAddress.a, req->peerMacAddress.a, ETH_ALEN); + newRecord->wmmOrQosEnabled = req->staInfo.wmmOrQosEnabled; + + /* maxSpLength is bit map in qosInfo field, so converting accordingly */ + newRecord->maxSpLength = req->staInfo.maxSpLength * 2; + + /*Max SP 0 mean any number of packets. since we buffer only 512 + packets we are hard coding this to zero for the moment */ + + if(newRecord->maxSpLength == 0) + newRecord->maxSpLength=512; + + newRecord->assignedHandle = i; + + /* copy power save mode of all access catagory (Trigger/Delivery/both enabled/disabled) */ + powerModeTemp = (CsrUint8) ((req->staInfo.powersaveMode >> 4) & 0xff); + + if(!(req->staInfo.powersaveMode & 0x0001)) + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= CSR_WIFI_AC_LEGACY_POWER_SAVE; + else + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= powerModeTemp & 0x03; + + if(!(req->staInfo.powersaveMode & 0x0002)) + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= CSR_WIFI_AC_LEGACY_POWER_SAVE; + else + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= ((powerModeTemp & 0x0C)>> 2); + + if(!(req->staInfo.powersaveMode & 0x0004)) + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= CSR_WIFI_AC_LEGACY_POWER_SAVE; + else + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= ((powerModeTemp & 0x30)>> 4); + + if(!(req->staInfo.powersaveMode & 0x0008)) + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= CSR_WIFI_AC_LEGACY_POWER_SAVE; + else + newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= ((powerModeTemp & 0xC0)>> 6); + + { + CsrUint8 k; + for(k=0; k< MAX_ACCESS_CATOGORY ;k++) + unifi_trace(priv, UDBG2, "peer_add_new_record: WMM : %d ,AC %d, powersaveMode %x \n", + req->staInfo.wmmOrQosEnabled,k,newRecord->powersaveMode[k]); + } + + unifi_trace(priv, UDBG3, "newRecord->wmmOrQosEnabled : %d , MAX SP : %d\n", + newRecord->wmmOrQosEnabled,newRecord->maxSpLength); + + /* Initialize the mgtFrames & data Pdu list */ + { + CsrUint8 j; + INIT_LIST_HEAD(&newRecord->mgtFrames); + for(j = 0; j < MAX_ACCESS_CATOGORY; j++) { + INIT_LIST_HEAD(&newRecord->dataPdu[j]); + } + } + + newRecord->lastActivity = currentTime; + newRecord->activity_flag = TRUE; + + /* enable the preemption as station record updated */ + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + /* First time port actions are set for the peer with below information */ + configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress, + UF_UNCONTROLLED_PORT_Q, req->interfaceTag); + + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) { + configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress, + UF_CONTROLLED_PORT_Q, req->interfaceTag); + } else { + configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD, &newRecord->peerMacAddress, + UF_CONTROLLED_PORT_Q, req->interfaceTag); + } + + + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + /* Port status must be already set before calling the Add Peer request */ + newRecord->peerControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a, + UF_CONTROLLED_PORT_Q, req->interfaceTag); + newRecord->peerUnControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a, + UF_UNCONTROLLED_PORT_Q, req->interfaceTag); + + if (!newRecord->peerControlledPort || !newRecord->peerUnControlledPort) { + /* enable the preemption as station record failed to update */ + unifi_warning(priv, "Un/ControlledPort record not found in port configuration array index = %d\n", i); + kfree(interfacePriv->staInfo[i]); + interfacePriv->staInfo[i] = NULL; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + return CSR_RESULT_FAILURE; + } + + newRecord->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE; + + /* changes done during block ack handling */ + newRecord->txSuspend = FALSE; + + /*U-APSD related data structure*/ + newRecord->uapsdActive = FALSE; + newRecord->noOfSpFramesSent =0; + + /* The protection bit is updated once the port opens for corresponding peer in + * routerPortConfigure request */ + + /* update the association ID */ + newRecord->aid = req->associationId; + +#ifdef CSR_SUPPORT_SME + interfacePriv->num_stations_joined++; + newRecord->interfacePriv = interfacePriv; + newRecord->listenIntervalInTus = req->staInfo.listenIntervalInTus; + newRecord->nullDataHostTag = INVALID_HOST_TAG; + + INIT_WORK(&newRecord->send_disconnected_ind_task, uf_send_disconnected_ind_wq); + + if(!(interfacePriv->sta_activity_check_enabled) && + (interfacePriv->num_stations_joined >= STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)){ + unifi_trace(priv, UDBG1, + "peer_add_new_record: STARTING the Inactivity Timer (num of stations = %d)", + interfacePriv->num_stations_joined); + + interfacePriv->sta_activity_check_enabled = TRUE; + interfacePriv->sta_activity_check_timer.function = check_inactivity_timer_expire_func; + interfacePriv->sta_activity_check_timer.data = (unsigned long)interfacePriv; + + init_timer(&interfacePriv->sta_activity_check_timer); + mod_timer(&interfacePriv->sta_activity_check_timer, + (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000))); + + } +#endif + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + break; + } + } + + if(!freeSlotFound) { + unifi_error(priv, "Limited connectivity, Free slot not found for station record addition\n"); + return CSR_RESULT_FAILURE; + } + return CSR_RESULT_SUCCESS; +} + +#ifdef CSR_SUPPORT_SME +static void check_inactivity_timer_expire_func(unsigned long data) +{ + struct unifi_priv *priv; + CsrWifiRouterCtrlStaInfo_t *sta_record = NULL; + CsrUint8 i = 0; + CsrTime now; + CsrTime inactive_time; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data; + + if (!interfacePriv) + { + return; + } + + priv = interfacePriv->privPtr; + + if (interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "check_inactivity_timer_expire_func: Invalid interfaceTag\n"); + return; + } + + /* RUN Algorithm to check inactivity for each connected station */ + now = CsrTimeGet(NULL); + + for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + if(interfacePriv->staInfo[i] != NULL) { + sta_record = interfacePriv->staInfo[i]; + + if (sta_record->activity_flag == TRUE){ + sta_record->activity_flag = FALSE; + sta_record->lastActivity = now; + continue; + } + + if (sta_record->lastActivity > now) + { + /* simple timer wrap (for 1 wrap) */ + inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now); + } + else + { + inactive_time = (CsrTime)CsrTimeSub(now, sta_record->lastActivity); + } + + if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) + { + unifi_trace(priv, UDBG1, "STA is Inactive - AID = %d inactive_time = %d\n", + sta_record->aid, + inactive_time); + + /* station is in-active, if it is in active mode send a null frame + * and the station should acknowledge the null frame, if acknowledgement + * is not received throw out the station. + * If the station is in Power Save, update TIM for the station so + * that it wakes up and register some activity through PS-Poll or + * trigger frame. + */ + if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) + { + unifi_trace(priv, UDBG1, "STA power save state - Active, send a NULL frame to check if it is ALIVE\n"); + uf_send_nulldata ( priv, + sta_record->interfacePriv->InterfaceTag, + sta_record->peerMacAddress.a, + CSR_CONTENTION, + sta_record); + } + else if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + { + if((sta_record->timSet == CSR_WIFI_TIM_SET) || + (sta_record->timSet == CSR_WIFI_TIM_SETTING)) + { + unifi_trace(priv, UDBG1, "STA power save state - PS, TIM is already SET\n"); + + /* If TIM is set and we do not have any activity for + * more than 3 listen intervals then send a disconnected + * indication to SME, to delete the station from station + * record list. + * The inactivity is already more than STA_INACTIVE_TIMEOUT_VAL + * and this check ensures if the listen interval is a larger + * value than STA_INACTIVE_TIMEOUT_VAL. + */ + if (inactive_time > (3 * (sta_record->listenIntervalInTus * 1024))) + { + unifi_trace(priv, UDBG1, "STA is inactive for more than 3 listen intervals\n"); + queue_work( priv->unifi_workqueue, + &sta_record->send_disconnected_ind_task); + } + + } + else + { + unifi_trace(priv, UDBG1, "STA power save state - PS, update TIM to see if it is ALIVE\n"); + update_tim(priv, + sta_record->aid, + CSR_WIFI_TIM_SET, + interfacePriv->InterfaceTag, + sta_record->assignedHandle); + } + } + } + } + } + + /* re-run the timer interrupt */ + mod_timer(&interfacePriv->sta_activity_check_timer, + (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000))); + +} + + +void uf_send_disconnected_ind_wq(struct work_struct *work) +{ + + CsrWifiRouterCtrlStaInfo_t *staInfo = container_of(work, CsrWifiRouterCtrlStaInfo_t, send_disconnected_ind_task); + unifi_priv_t *priv; + CsrUint16 interfaceTag; + struct list_head send_cfm_list; + CsrUint8 j; + + func_enter(); + + if(!staInfo) { + return; + } + + if(!staInfo->interfacePriv) { + return; + } + + priv = staInfo->interfacePriv->privPtr; + interfaceTag = staInfo->interfacePriv->InterfaceTag; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_send_disconnected_ind_wq: invalid interfaceTag\n"); + return; + } + + /* The SME/NME may be waiting for confirmation for requested frames to this station. + * So loop through buffered frames for this station and if confirmation is + * requested, send auto confirmation with failure status. Also flush the frames so + * that these are not processed again in PEER_DEL_REQ handler. + */ + INIT_LIST_HEAD(&send_cfm_list); + + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staInfo->mgtFrames)); + + uf_flush_list(priv, &(staInfo->mgtFrames)); + + for(j = 0; j < MAX_ACCESS_CATOGORY; j++){ + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staInfo->dataPdu[j])); + + uf_flush_list(priv,&(staInfo->dataPdu[j])); + } + + send_auto_ma_packet_confirm(priv, staInfo->interfacePriv, &send_cfm_list); + + unifi_warning(priv, "uf_send_disconnected_ind_wq: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n", + staInfo->peerMacAddress.a[0], + staInfo->peerMacAddress.a[1], + staInfo->peerMacAddress.a[2], + staInfo->peerMacAddress.a[3], + staInfo->peerMacAddress.a[4], + staInfo->peerMacAddress.a[5]); + + CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, + 0, + staInfo->interfacePriv->InterfaceTag, + staInfo->peerMacAddress, + CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED); + + + return; +} + + +#endif +void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv,CsrWifiFsmEvent* msg) +{ + CsrWifiRouterCtrlPeerAddReq* req = (CsrWifiRouterCtrlPeerAddReq*)msg; + CsrResult status = CSR_RESULT_SUCCESS; + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrUint32 handle = 0; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + + unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerAddReqHandler \n"); + if (priv == NULL) + { + unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: invalid smepriv\n"); + return; + } + + if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: bad interfaceTag\n"); + return; + } + + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + /* Add station record */ + status = peer_add_new_record(priv,req,&handle); + break; + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + default: + /* No station record to maintain in these modes */ + break; + } + + CsrWifiRouterCtrlPeerAddCfmSend(msg->source,req->clientData,req->interfaceTag,req->peerMacAddress,handle,status); + unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerAddReqHandler \n"); +} + +void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv,CsrWifiFsmEvent* msg) +{ + CsrWifiRouterCtrlPeerUpdateReq* req = (CsrWifiRouterCtrlPeerUpdateReq*)msg; + CsrResult status = CSR_RESULT_SUCCESS; + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + + unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerUpdateReqHandler \n"); + if (priv == NULL) + { + unifi_error(priv, "CsrWifiRouterCtrlPeerUpdateReqHandler: invalid smepriv\n"); + return; + } + + CsrWifiRouterCtrlPeerUpdateCfmSend(msg->source,req->clientData,req->interfaceTag,status); + unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerUpdateReqHandler \n"); +} + + + void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + /* This will never be called as it is intercepted in the Userspace */ +} + +void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + /* This will never be called as it is intercepted in the Userspace */ +} + +void +uf_send_ba_err_wq(struct work_struct *work) +{ + ba_session_rx_struct *ba_session = container_of(work, ba_session_rx_struct, send_ba_err_task); + unifi_priv_t *priv; + + if(!ba_session) { + return; + } + + if(!ba_session->interfacePriv) { + return; + } + + priv = ba_session->interfacePriv->privPtr; + + if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__); + return; + } + + unifi_warning(priv, "%s: Calling CsrWifiRouterCtrlBlockAckErrorIndSend(%d, %d, %d, %d, %x:%x:%x:%x:%x:%x, %d)\n", + __FUNCTION__, + priv->CSR_WIFI_SME_IFACEQUEUE, + 0, + ba_session->interfacePriv->InterfaceTag, + ba_session->tID, + ba_session->macAddress.a[0], + ba_session->macAddress.a[1], + ba_session->macAddress.a[2], + ba_session->macAddress.a[3], + ba_session->macAddress.a[4], + ba_session->macAddress.a[5], + CSR_RESULT_SUCCESS + ); + CsrWifiRouterCtrlBlockAckErrorIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, + 0, + ba_session->interfacePriv->InterfaceTag, + ba_session->tID, + ba_session->macAddress, + CSR_RESULT_SUCCESS); +} + + +static void ba_session_terminate_timer_func(unsigned long data) +{ + ba_session_rx_struct *ba_session = (ba_session_rx_struct*)data; + struct unifi_priv *priv; + + if(!ba_session) { + return; + } + + if(!ba_session->interfacePriv) { + return; + } + + priv = ba_session->interfacePriv->privPtr; + + if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__); + return; + } + + queue_work(priv->unifi_workqueue, &ba_session->send_ba_err_task); +} + + +CsrBool blockack_session_stop(unifi_priv_t *priv, + CsrUint16 interfaceTag, + CsrWifiRouterCtrlBlockAckRole role, + CsrUint16 tID, + CsrWifiMacAddress macAddress) +{ + netInterface_priv_t *interfacePriv; + ba_session_rx_struct *ba_session_rx = NULL; + ba_session_tx_struct *ba_session_tx = NULL; + CsrUint8 ba_session_idx = 0; + int i; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag); + return FALSE; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + if(!interfacePriv) { + unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__); + return FALSE; + } + + if(tID > 15) { + unifi_error(priv, "%s: bad tID = %d\n", __FUNCTION__, tID); + return FALSE; + } + + if((role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR) && + (role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT)) { + unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role); + return FALSE; + } + + unifi_warning(priv, "%s: stopping ba_session for peer = %02x:%02x:%02x:%02x:%02x:%02x role = %d tID = %d\n", __FUNCTION__, + macAddress.a[0], macAddress.a[1], macAddress.a[2], + macAddress.a[3], macAddress.a[4], macAddress.a[5], + role, + tID); + + /* find out the appropriate ba session (/station /tid /role) for which stop is requested */ + if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){ + for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ + + ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx]; + + if(ba_session_rx){ + if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){ + break; + } + } + } + + if (!ba_session_rx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX)) { + unifi_error(priv, "%s: bad ba_session for Rx [tID=%d]\n", __FUNCTION__, tID); + return FALSE; + } + + + if(ba_session_rx->timeout) { + del_timer_sync(&ba_session_rx->timer); + } + cancel_work_sync(&ba_session_rx->send_ba_err_task); + for (i = 0; i < ba_session_rx->wind_size; i++) { + if(ba_session_rx->buffer[i].active) { + frame_desc_struct *frame_desc = &ba_session_rx->buffer[i]; + unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]); + } + } + kfree(ba_session_rx->buffer); + + interfacePriv->ba_session_rx[ba_session_idx] = NULL; + kfree(ba_session_rx); + }else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){ + for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){ + ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx]; + if(ba_session_tx){ + if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){ + break; + } + } + } + + if (!ba_session_tx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX)) { + unifi_error(priv, "%s: bad ba_session for Tx [tID=%d]\n", __FUNCTION__, tID); + return FALSE; + } + interfacePriv->ba_session_tx[ba_session_idx] = NULL; + kfree(ba_session_tx); + + } + + return TRUE; +} + + +void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + CsrWifiRouterCtrlBlockAckDisableReq* req = (CsrWifiRouterCtrlBlockAckDisableReq*)msg; + CsrBool r; + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + + unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__); + + spin_lock(&priv->ba_lock); + r = blockack_session_stop(priv, + req->interfaceTag, + req->role, + req->trafficStreamID, + req->macAddress); + spin_unlock(&priv->ba_lock); + + CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source, + req->clientData, + req->interfaceTag, + r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE); + + unifi_trace(priv, UDBG6, "%s: out ok\n", __FUNCTION__); +} + + +CsrBool blockack_session_start(unifi_priv_t *priv, + CsrUint16 interfaceTag, + CsrUint16 tID, + CsrUint16 timeout, + CsrWifiRouterCtrlBlockAckRole role, + CsrUint16 wind_size, + CsrUint16 start_sn, + CsrWifiMacAddress macAddress + ) +{ + netInterface_priv_t *interfacePriv; + ba_session_rx_struct *ba_session_rx = NULL; + ba_session_tx_struct *ba_session_tx = NULL; + CsrUint8 ba_session_idx = 0; + + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag); + return FALSE; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + if(!interfacePriv) { + unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__); + return FALSE; + } + + if(tID > 15) + { + unifi_error(priv, "%s: bad tID=%d\n", __FUNCTION__, tID); + return FALSE; + } + + if(wind_size > MAX_BA_WIND_SIZE) { + unifi_error(priv, "%s: bad wind_size = %d\n", __FUNCTION__, wind_size); + return FALSE; + } + + if(role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR && + role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT) { + unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role); + return FALSE; + } + + unifi_warning(priv, "%s: ba session with peer= (%02x:%02x:%02x:%02x:%02x:%02x)\n", __FUNCTION__, + macAddress.a[0], macAddress.a[1], macAddress.a[2], + macAddress.a[3], macAddress.a[4], macAddress.a[5]); + + unifi_warning(priv, "%s: ba session for tID=%d timeout=%d role=%d wind_size=%d start_sn=%d\n", __FUNCTION__, + tID, + timeout, + role, + wind_size, + start_sn); + + /* Check if BA session exists for per station, per TID, per role or not. + if BA session exists update parameters and if it does not exist + create a new BA session */ + if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){ + for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){ + ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx]; + if (ba_session_tx) { + if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){ + unifi_warning(priv, "%s: ba_session for Tx already exists\n", __FUNCTION__); + return TRUE; + } + } + } + + /* we have to create new ba_session_tx struct */ + ba_session_tx = NULL; + + /* loop through until an empty BA session slot is there and save the session there */ + for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX ; ba_session_idx++){ + if (!(interfacePriv->ba_session_tx[ba_session_idx])){ + break; + } + } + if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX){ + unifi_error(priv, "%s: All ba_session used for Tx, NO free session available\n", __FUNCTION__); + return FALSE; + } + + /* create and populate the new BA session structure */ + ba_session_tx = kmalloc(sizeof(ba_session_tx_struct), GFP_KERNEL); + if (!ba_session_tx) { + unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__); + return FALSE; + } + memset(ba_session_tx, 0, sizeof(ba_session_tx_struct)); + + ba_session_tx->interfacePriv = interfacePriv; + ba_session_tx->tID = tID; + ba_session_tx->macAddress = macAddress; + + interfacePriv->ba_session_tx[ba_session_idx] = ba_session_tx; + + } else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){ + + for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ + ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx]; + if (ba_session_rx) { + if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){ + unifi_warning(priv, "%s: ba_session for Rx[tID = %d] already exists\n", __FUNCTION__, tID); + + if(ba_session_rx->wind_size == wind_size && + ba_session_rx->timeout == timeout && + ba_session_rx->expected_sn == start_sn) { + return TRUE; + } + + if(ba_session_rx->timeout) { + del_timer_sync(&ba_session_rx->timer); + ba_session_rx->timeout = 0; + } + + if(ba_session_rx->wind_size != wind_size) { + blockack_session_stop(priv, interfaceTag, role, tID, macAddress); + } else { + if (timeout) { + ba_session_rx->timeout = timeout; + ba_session_rx->timer.function = ba_session_terminate_timer_func; + ba_session_rx->timer.data = (unsigned long)ba_session_rx; + init_timer(&ba_session_rx->timer); + mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024))); + } + return TRUE; + } + } + } + } + + /* we could have a valid BA session pointer here or un-initialized + ba session pointer. but in any case we have to create a new session. + so re-initialize the ba_session pointer */ + ba_session_rx = NULL; + + /* loop through until an empty BA session slot is there and save the session there */ + for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX ; ba_session_idx++){ + if (!(interfacePriv->ba_session_rx[ba_session_idx])){ + break; + } + } + if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){ + unifi_error(priv, "%s: All ba_session used for Rx, NO free session available\n", __FUNCTION__); + return FALSE; + } + + + ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL); + if (!ba_session_rx) { + unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__); + return FALSE; + } + memset(ba_session_rx, 0, sizeof(ba_session_rx_struct)); + + ba_session_rx->wind_size = wind_size; + ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn; + ba_session_rx->trigger_ba_after_ssn = FALSE; + + ba_session_rx->buffer = kmalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL); + if (!ba_session_rx->buffer) { + kfree(ba_session_rx); + unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__); + return FALSE; + } + + memset(ba_session_rx->buffer, 0, ba_session_rx->wind_size*sizeof(frame_desc_struct)); + + INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq); + if (timeout) { + ba_session_rx->timeout = timeout; + ba_session_rx->timer.function = ba_session_terminate_timer_func; + ba_session_rx->timer.data = (unsigned long)ba_session_rx; + init_timer(&ba_session_rx->timer); + mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024))); + } + + ba_session_rx->interfacePriv = interfacePriv; + ba_session_rx->tID = tID; + ba_session_rx->macAddress = macAddress; + + interfacePriv->ba_session_rx[ba_session_idx] = ba_session_rx; + } + return TRUE; +} + +void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + CsrWifiRouterCtrlBlockAckEnableReq* req = (CsrWifiRouterCtrlBlockAckEnableReq*)msg; + CsrBool r; + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + spin_lock(&priv->ba_lock); + r = blockack_session_start(priv, + req->interfaceTag, + req->trafficStreamID, + req->timeout, + req->role, + req->bufferSize, + req->ssn, + req->macAddress + ); + spin_unlock(&priv->ba_lock); + + CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source, + req->clientData, + req->interfaceTag, + r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE); + unifi_trace(priv, UDBG6, "<<%s: r=%d\n", __FUNCTION__, r); + +} + +void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg; + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status); + + /* status 1 - Filter on + * status 0 - Filter off */ + priv->wapi_multicast_filter = req->status; + + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); +} + +void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg; + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status); + + if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) { + /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */ + priv->wapi_unicast_queued_pkt_filter = 1; + } + + /* status 1 - Filter ON + * status 0 - Filter OFF */ + priv->wapi_unicast_filter = req->status; + + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); +} + + +void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWapiMulticastReq* req = (CsrWifiRouterCtrlWapiMulticastReq*)msg; + + int client_id, receiver_id; + bulk_data_param_t bulkdata; + CsrResult res; + ul_client_t *client; + + CSR_SIGNAL signal; + CSR_MA_PACKET_INDICATION *pkt_ind; + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlWapiMulticastReqHandler: \n"); + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid priv\n",__FUNCTION__); + return; + } + + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid sme priv\n",__FUNCTION__); + return; + } + + if (req->dataLength == 0 || req->data == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: invalid request\n",__FUNCTION__); + return; + } + + res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength); + if (res != CSR_RESULT_SUCCESS) { + unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: Could not allocate net data\n",__FUNCTION__); + return; + } + + /* This function is expected to be called only when the MIC has been verified by SME to be correct + * So reset the reception status to rx_success */ + res = read_unpack_signal(req->signal, &signal); + if (res) { + unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Received unknown or corrupted signal.\n"); + return; + } + pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication); + if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) { + unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus); + return; + } + else { + unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiMulticastReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__); + pkt_ind->ReceptionStatus = CSR_RX_SUCCESS; + write_pack(&signal, req->signal, &(req->signalLength)); + } + + memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength); + + receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0; + client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; + + client = &priv->ul_clients[client_id]; + + if (client && client->event_hook) { + unifi_trace(priv, UDBG3, + "CsrWifiRouterCtrlWapiMulticastReqHandler: " + "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n", + client->client_id, client->sender_id, receiver_id, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal)); + + client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST); + } + else { + unifi_trace(priv, UDBG4, "No client to give the packet to\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + } + + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); +} diff --git a/drivers/staging/csr/sme_userspace.c b/drivers/staging/csr/sme_userspace.c new file mode 100644 index 000000000000..38df94b69e9f --- /dev/null +++ b/drivers/staging/csr/sme_userspace.c @@ -0,0 +1,316 @@ +/* + ***************************************************************************** + * + * FILE : sme_userspace.c + * + * PURPOSE : Support functions for userspace SME helper application. + * + * + * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + ***************************************************************************** + */ + +#include "unifi_priv.h" + +/* + * Fix Me..... These need to be the correct values... + * Dynamic from the user space. + */ +CsrSchedQid CSR_WIFI_ROUTER_IFACEQUEUE = 0xFFFF; +CsrSchedQid CSR_WIFI_SME_IFACEQUEUE = 0xFFFF; +#ifdef CSR_SUPPORT_WEXT_AP +CsrSchedQid CSR_WIFI_NME_IFACEQUEUE = 0xFFFF; +#endif +int +uf_sme_init(unifi_priv_t *priv) +{ + int i, j; + + CsrWifiRouterTransportInit(priv); + + priv->smepriv = priv; + + init_waitqueue_head(&priv->sme_request_wq); + + priv->filter_tclas_ies = NULL; + memset(&priv->packet_filters, 0, sizeof(uf_cfg_bcast_packet_filter_t)); + +#ifdef CSR_SUPPORT_WEXT + priv->ignore_bssid_join = FALSE; + priv->mib_data.length = 0; + + uf_sme_wext_set_defaults(priv); +#endif /* CSR_SUPPORT_WEXT*/ + + priv->sta_ip_address = 0xFFFFFFFF; + + priv->wifi_on_state = wifi_on_unspecified; + + sema_init(&priv->sme_sem, 1); + memset(&priv->sme_reply, 0, sizeof(sme_reply_t)); + + priv->ta_ind_work.in_use = 0; + priv->ta_sample_ind_work.in_use = 0; + + priv->CSR_WIFI_SME_IFACEQUEUE = 0xFFFF; + + for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) { + priv->sme_unidata_ind_filters[i].in_use = 0; + } + + /* Create a work queue item for Traffic Analysis indications to SME */ + INIT_WORK(&priv->ta_ind_work.task, uf_ta_ind_wq); + INIT_WORK(&priv->ta_sample_ind_work.task, uf_ta_sample_ind_wq); +#ifdef CSR_SUPPORT_WEXT + INIT_WORK(&priv->sme_config_task, uf_sme_config_wq); +#endif + + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; + interfacePriv->m4_sent = FALSE; + interfacePriv->m4_bulk_data.net_buf_length = 0; + interfacePriv->m4_bulk_data.data_length = 0; + interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL; + + memset(&interfacePriv->controlled_data_port, 0, sizeof(unifi_port_config_t)); + interfacePriv->controlled_data_port.entries_in_use = 1; + interfacePriv->controlled_data_port.port_cfg[0].in_use = TRUE; + interfacePriv->controlled_data_port.port_cfg[0].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + interfacePriv->controlled_data_port.overide_action = UF_DATA_PORT_OVERIDE; + + memset(&interfacePriv->uncontrolled_data_port, 0, sizeof(unifi_port_config_t)); + interfacePriv->uncontrolled_data_port.entries_in_use = 1; + interfacePriv->uncontrolled_data_port.port_cfg[0].in_use = TRUE; + interfacePriv->uncontrolled_data_port.port_cfg[0].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + interfacePriv->uncontrolled_data_port.overide_action = UF_DATA_PORT_OVERIDE; + + /* Mark the remainder of the port config table as unallocated */ + for(j = 1; j < UNIFI_MAX_CONNECTIONS; j++) { + interfacePriv->controlled_data_port.port_cfg[j].in_use = FALSE; + interfacePriv->controlled_data_port.port_cfg[j].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + + interfacePriv->uncontrolled_data_port.port_cfg[j].in_use = FALSE; + interfacePriv->uncontrolled_data_port.port_cfg[j].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + } + + /* intializing the lists */ + INIT_LIST_HEAD(&interfacePriv->genericMgtFrames); + INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastMgtFrames); + INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastFrames); + INIT_LIST_HEAD(&interfacePriv->directedMaPktReq); + + for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) { + interfacePriv->staInfo[j] = NULL; + } + + interfacePriv->num_stations_joined = 0; + interfacePriv->sta_activity_check_enabled = FALSE; + } + + + return 0; +} /* uf_sme_init() */ + + +void +uf_sme_deinit(unifi_priv_t *priv) +{ + int i,j; + CsrUint8 ba_session_idx; + ba_session_rx_struct *ba_session_rx = NULL; + ba_session_tx_struct *ba_session_tx = NULL; + CsrWifiRouterCtrlStaInfo_t *staInfo = NULL; + netInterface_priv_t *interfacePriv = NULL; + + /* Free any TCLASs previously allocated */ + if (priv->packet_filters.tclas_ies_length) { + priv->packet_filters.tclas_ies_length = 0; + CsrPmemFree(priv->filter_tclas_ies); + priv->filter_tclas_ies = NULL; + } + + for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) { + priv->sme_unidata_ind_filters[i].in_use = 0; + } + + /* Remove all the Peer database, before going down */ + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + spin_lock(&priv->ba_lock); + for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ + ba_session_rx = priv->interfacePriv[i]->ba_session_rx[ba_session_idx]; + if(ba_session_rx) { + blockack_session_stop(priv, + i, + CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT, + ba_session_rx->tID, + ba_session_rx->macAddress); + } + } + for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){ + ba_session_tx = priv->interfacePriv[i]->ba_session_tx[ba_session_idx]; + if(ba_session_tx) { + blockack_session_stop(priv, + i, + CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR, + ba_session_tx->tID, + ba_session_tx->macAddress); + } + } + + spin_unlock(&priv->ba_lock); + interfacePriv = priv->interfacePriv[i]; + if(interfacePriv){ + for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) { + if ((staInfo=interfacePriv->staInfo[j]) != NULL) { + /* Clear the STA activity parameters before freeing station Record */ + unifi_trace(priv, UDBG1, "uf_sme_deinit: Canceling work queue for STA with AID: %d\n", staInfo->aid); + cancel_work_sync(&staInfo->send_disconnected_ind_task); + staInfo->nullDataHostTag = INVALID_HOST_TAG; + } + } + if (interfacePriv->sta_activity_check_enabled){ + interfacePriv->sta_activity_check_enabled = FALSE; + del_timer_sync(&interfacePriv->sta_activity_check_timer); + } + } + CsrWifiRouterCtrlInterfaceReset(priv, i); + priv->interfacePriv[i]->interfaceMode = CSR_WIFI_ROUTER_CTRL_MODE_NONE; + } + + +} /* uf_sme_deinit() */ + + + + + +/* + * --------------------------------------------------------------------------- + * unifi_ta_indicate_protocol + * + * Report that a packet of a particular type has been seen + * + * Arguments: + * drv_priv The device context pointer passed to ta_init. + * protocol The protocol type enum value. + * direction Whether the packet was a tx or rx. + * src_addr The source MAC address from the data packet. + * + * Returns: + * None. + * + * Notes: + * We defer the actual sending to a background workqueue, + * see uf_ta_ind_wq(). + * --------------------------------------------------------------------------- + */ +void +unifi_ta_indicate_protocol(void *ospriv, + CsrWifiRouterCtrlTrafficPacketType packet_type, + CsrWifiRouterCtrlProtocolDirection direction, + const CsrWifiMacAddress *src_addr) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + + if (priv->ta_ind_work.in_use) { + unifi_warning(priv, + "unifi_ta_indicate_protocol: workqueue item still in use, not sending\n"); + return; + } + + if (CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX == direction) + { + CsrUint16 interfaceTag = 0; + CsrWifiRouterCtrlTrafficProtocolIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, + interfaceTag, + packet_type, + direction, + *src_addr); + } + else + { + priv->ta_ind_work.packet_type = packet_type; + priv->ta_ind_work.direction = direction; + priv->ta_ind_work.src_addr = *src_addr; + + queue_work(priv->unifi_workqueue, &priv->ta_ind_work.task); + } + +} /* unifi_ta_indicate_protocol() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_ta_indicate_sampling + * + * Send the TA sampling information to the SME. + * + * Arguments: + * drv_priv The device context pointer passed to ta_init. + * stats The TA sampling data to send. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +unifi_ta_indicate_sampling(void *ospriv, CsrWifiRouterCtrlTrafficStats *stats) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + + if (!priv) { + return; + } + + if (priv->ta_sample_ind_work.in_use) { + unifi_warning(priv, + "unifi_ta_indicate_sampling: workqueue item still in use, not sending\n"); + return; + } + + priv->ta_sample_ind_work.stats = *stats; + + queue_work(priv->unifi_workqueue, &priv->ta_sample_ind_work.task); + +} /* unifi_ta_indicate_sampling() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_ta_indicate_l4stats + * + * Send the TA TCP/UDP throughput information to the driver. + * + * Arguments: + * drv_priv The device context pointer passed to ta_init. + * rxTcpThroughput TCP RX throughput in KiloBytes + * txTcpThroughput TCP TX throughput in KiloBytes + * rxUdpThroughput UDP RX throughput in KiloBytes + * txUdpThroughput UDP TX throughput in KiloBytes + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +unifi_ta_indicate_l4stats(void *ospriv, + CsrUint32 rxTcpThroughput, + CsrUint32 txTcpThroughput, + CsrUint32 rxUdpThroughput, + CsrUint32 txUdpThroughput) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + + if (!priv) { + return; + } + /* Save the info. The actual action will be taken in unifi_ta_indicate_sampling() */ + priv->rxTcpThroughput = rxTcpThroughput; + priv->txTcpThroughput = txTcpThroughput; + priv->rxUdpThroughput = rxUdpThroughput; + priv->txUdpThroughput = txUdpThroughput; +} /* unifi_ta_indicate_l4stats() */ diff --git a/drivers/staging/csr/sme_userspace.h b/drivers/staging/csr/sme_userspace.h new file mode 100644 index 000000000000..19f484f863b1 --- /dev/null +++ b/drivers/staging/csr/sme_userspace.h @@ -0,0 +1,38 @@ +/* + * *************************************************************************** + * FILE: sme_userspace.h + * + * PURPOSE: SME related definitions. + * + * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ +#ifndef __LINUX_SME_USERSPACE_H__ +#define __LINUX_SME_USERSPACE_H__ 1 + +#include + +int uf_sme_init(unifi_priv_t *priv); +void uf_sme_deinit(unifi_priv_t *priv); +int uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length); + + +#include "csr_wifi_router_lib.h" +#include "csr_wifi_router_sef.h" +#include "csr_wifi_router_ctrl_lib.h" +#include "csr_wifi_router_ctrl_sef.h" +#include "csr_wifi_sme_task.h" +#ifdef CSR_SUPPORT_WEXT_AP +#include "csr_wifi_nme_ap_lib.h" +#endif +#include "csr_wifi_sme_lib.h" + +void CsrWifiRouterTransportInit(unifi_priv_t *priv); +void CsrWifiRouterTransportRecv(unifi_priv_t *priv, CsrUint8* buffer, CsrSize bufferLength); +void CsrWifiRouterTransportDeInit(unifi_priv_t *priv); + +#endif /* __LINUX_SME_USERSPACE_H__ */ diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c new file mode 100644 index 000000000000..384ccd46982e --- /dev/null +++ b/drivers/staging/csr/sme_wext.c @@ -0,0 +1,3394 @@ +/* + * --------------------------------------------------------------------------- + * FILE: sme_wext.c + * + * PURPOSE: + * Handlers for ioctls from iwconfig. + * These provide the control plane operations. + * + * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include +#include +#include +#include +#include +#include "unifi_priv.h" +#include + +#define CHECK_INITED(_priv) \ + do { \ + if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \ + unifi_trace(_priv, UDBG2, "%s unifi not ready, failing wext call\n", __FUNCTION__); \ + return -ENODEV; \ + } \ + } while (0) + +/* Workaround for the wpa_supplicant hanging issue */ +#define CSR_WIFI_WEXT_HANG_WORKAROUND + +#ifdef CSR_WIFI_WEXT_HANG_WORKAROUND +# define UF_RTNL_LOCK() rtnl_lock() +# define UF_RTNL_UNLOCK() rtnl_unlock() +#else +# define UF_RTNL_LOCK() +# define UF_RTNL_UNLOCK() +#endif + + +/* + * --------------------------------------------------------------------------- + * Helper functions + * --------------------------------------------------------------------------- + */ + +/* + * --------------------------------------------------------------------------- + * wext_freq_to_channel + * channel_to_mhz + * + * These functions convert between channel number and frequency. + * + * Arguments: + * ch Channel number, as defined in 802.11 specs + * m, e Mantissa and exponent as provided by wireless extension. + * + * Returns: + * channel or frequency (in MHz) value + * --------------------------------------------------------------------------- + */ +static int +wext_freq_to_channel(int m, int e) +{ + int mhz; + + mhz = m; + while (e < 6) { + mhz /= 10; + e++; + } + while (e > 6) { + mhz *= 10; + e--; + } + + if (mhz >= 5000) { + return ((mhz - 5000) / 5); + } + + if (mhz == 2482) { + return 14; + } + + if (mhz >= 2407) { + return ((mhz - 2407) / 5); + } + + return 0; +} /* wext_freq_to_channel() */ + +static int +channel_to_mhz(int ch, int dot11a) +{ + + if (ch == 0) return 0; + if (ch > 200) return 0; + + /* 5G */ + if (dot11a) { + return (5000 + (5 * ch)); + } + + /* 2.4G */ + if (ch == 14) { + return 2484; + } + + if ((ch < 14) && (ch > 0)) { + return (2407 + (5 * ch)); + } + + return 0; +} +#ifdef CSR_SUPPORT_WEXT_AP +void uf_sme_wext_ap_set_defaults(unifi_priv_t *priv) +{ + memcpy(priv->ap_config.ssid.ssid,"defaultssid",sizeof("defaultssid")); + + priv->ap_config.ssid.length = 8; + priv->ap_config.channel = 6; + priv->ap_config.if_index = 1; + priv->ap_config.credentials.authType = 0; + priv->ap_config.max_connections=8; + + priv->group_sec_config.apGroupkeyTimeout = 0; + priv->group_sec_config.apStrictGtkRekey = 0; + priv->group_sec_config.apGmkTimeout = 0; + priv->group_sec_config.apResponseTimeout = 100; /* Default*/ + priv->group_sec_config.apRetransLimit = 3; /* Default*/ + /* Set default params even if they may not be used*/ + /* Until Here*/ + + priv->ap_mac_config.preamble = CSR_WIFI_SME_USE_LONG_PREAMBLE; + priv->ap_mac_config.shortSlotTimeEnabled = FALSE; + priv->ap_mac_config.ctsProtectionType=CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC; + + priv->ap_mac_config.wmmEnabled = TRUE; + priv->ap_mac_config.wmmApParams[0].cwMin=4; + priv->ap_mac_config.wmmApParams[0].cwMax=10; + priv->ap_mac_config.wmmApParams[0].aifs=3; + priv->ap_mac_config.wmmApParams[0].txopLimit=0; + priv->ap_mac_config.wmmApParams[0].admissionControlMandatory=FALSE; + priv->ap_mac_config.wmmApParams[1].cwMin=4; + priv->ap_mac_config.wmmApParams[1].cwMax=10; + priv->ap_mac_config.wmmApParams[1].aifs=7; + priv->ap_mac_config.wmmApParams[1].txopLimit=0; + priv->ap_mac_config.wmmApParams[1].admissionControlMandatory=FALSE; + priv->ap_mac_config.wmmApParams[2].cwMin=3; + priv->ap_mac_config.wmmApParams[2].cwMax=4; + priv->ap_mac_config.wmmApParams[2].aifs=1; + priv->ap_mac_config.wmmApParams[2].txopLimit=94; + priv->ap_mac_config.wmmApParams[2].admissionControlMandatory=FALSE; + priv->ap_mac_config.wmmApParams[3].cwMin=2; + priv->ap_mac_config.wmmApParams[3].cwMax=3; + priv->ap_mac_config.wmmApParams[3].aifs=1; + priv->ap_mac_config.wmmApParams[3].txopLimit=47; + priv->ap_mac_config.wmmApParams[3].admissionControlMandatory=FALSE; + + priv->ap_mac_config.wmmApBcParams[0].cwMin=4; + priv->ap_mac_config.wmmApBcParams[0].cwMax=10; + priv->ap_mac_config.wmmApBcParams[0].aifs=3; + priv->ap_mac_config.wmmApBcParams[0].txopLimit=0; + priv->ap_mac_config.wmmApBcParams[0].admissionControlMandatory=FALSE; + priv->ap_mac_config.wmmApBcParams[1].cwMin=4; + priv->ap_mac_config.wmmApBcParams[1].cwMax=10; + priv->ap_mac_config.wmmApBcParams[1].aifs=7; + priv->ap_mac_config.wmmApBcParams[1].txopLimit=0; + priv->ap_mac_config.wmmApBcParams[1].admissionControlMandatory=FALSE; + priv->ap_mac_config.wmmApBcParams[2].cwMin=3; + priv->ap_mac_config.wmmApBcParams[2].cwMax=4; + priv->ap_mac_config.wmmApBcParams[2].aifs=2; + priv->ap_mac_config.wmmApBcParams[2].txopLimit=94; + priv->ap_mac_config.wmmApBcParams[2].admissionControlMandatory=FALSE; + priv->ap_mac_config.wmmApBcParams[3].cwMin=2; + priv->ap_mac_config.wmmApBcParams[3].cwMax=3; + priv->ap_mac_config.wmmApBcParams[3].aifs=2; + priv->ap_mac_config.wmmApBcParams[3].txopLimit=47; + priv->ap_mac_config.wmmApBcParams[3].admissionControlMandatory=FALSE; + + priv->ap_mac_config.accessType=CSR_WIFI_AP_ACCESS_TYPE_NONE; + priv->ap_mac_config.macAddressListCount=0; + priv->ap_mac_config.macAddressList=NULL; + + priv->ap_mac_config.apHtParams.rxStbc=1; + priv->ap_mac_config.apHtParams.rifsModeAllowed=TRUE; + priv->ap_mac_config.apHtParams.greenfieldSupported=FALSE; + priv->ap_mac_config.apHtParams.shortGi20MHz=TRUE; + priv->ap_mac_config.apHtParams.htProtection=0; + priv->ap_mac_config.apHtParams.dualCtsProtection=FALSE; + + priv->ap_mac_config.phySupportedBitmap = + (CSR_WIFI_SME_AP_PHY_SUPPORT_B|CSR_WIFI_SME_AP_PHY_SUPPORT_G|CSR_WIFI_SME_AP_PHY_SUPPORT_N); + priv->ap_mac_config.beaconInterval= 100; + priv->ap_mac_config.dtimPeriod=3; + priv->ap_mac_config.maxListenInterval=0x00ff;/* Set it to a large value + to enable different types of + devices to join us */ + priv->ap_mac_config.supportedRatesCount = + uf_configure_supported_rates(priv->ap_mac_config.supportedRates,priv->ap_mac_config.phySupportedBitmap); +} +#endif +/* + * --------------------------------------------------------------------------- + * uf_sme_wext_set_defaults + * + * Set up power-on defaults for driver config. + * + * Note: The SME Management API *cannot* be used in this function. + * + * Arguments: + * priv Pointer to device private context struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +uf_sme_wext_set_defaults(unifi_priv_t *priv) +{ + memset(&priv->connection_config, 0, sizeof(CsrWifiSmeConnectionConfig)); + + priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE; + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE; + priv->connection_config.privacyMode = CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED; + priv->connection_config.wmmQosInfo = 0xFF; + priv->connection_config.ifIndex = CSR_WIFI_SME_RADIO_IF_BOTH; + priv->connection_config.adhocJoinOnly = FALSE; + priv->connection_config.adhocChannel = 6; + + priv->wep_tx_key_index = 0; + + priv->wext_wireless_stats.qual.qual = 0; + priv->wext_wireless_stats.qual.level = 0; + priv->wext_wireless_stats.qual.noise = 0; + priv->wext_wireless_stats.qual.updated = 0x70; +#ifdef CSR_SUPPORT_WEXT_AP + /* Initialize the default configuration for AP */ + uf_sme_wext_ap_set_defaults(priv); +#endif + + +} /* uf_sme_wext_set_defaults() */ + + +/* + * --------------------------------------------------------------------------- + * WEXT methods + * --------------------------------------------------------------------------- + */ + +/* + * --------------------------------------------------------------------------- + * unifi_giwname - handler for SIOCGIWNAME + * unifi_siwfreq - handler for SIOCSIWFREQ + * unifi_giwfreq - handler for SIOCGIWFREQ + * unifi_siwmode - handler for SIOCSIWMODE + * unifi_giwmode - handler for SIOCGIWMODE + * unifi_giwrange - handler for SIOCGIWRANGE + * unifi_siwap - handler for SIOCSIWAP + * unifi_giwap - handler for SIOCGIWAP + * unifi_siwscan - handler for SIOCSIWSCAN + * unifi_giwscan - handler for SIOCGIWSCAN + * unifi_siwessid - handler for SIOCSIWESSID + * unifi_giwessid - handler for SIOCGIWESSID + * unifi_siwencode - handler for SIOCSIWENCODE + * unifi_giwencode - handler for SIOCGIWENCODE + * + * Handler functions for IW extensions. + * These are registered via the unifi_iw_handler_def struct below + * and called by the generic IW driver support code. + * See include/net/iw_handler.h. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static int +iwprivsdefs(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int r; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + CsrWifiSmeMibConfig mibConfig; + CsrWifiSmePowerConfig powerConfig; + + unifi_trace(priv, UDBG1, "iwprivs80211defaults: reload defaults\n"); + + uf_sme_wext_set_defaults(priv); + + /* Get, modify and set the MIB data */ + r = sme_mgt_mib_config_get(priv, &mibConfig); + if (r) { + unifi_error(priv, "iwprivs80211defaults: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + mibConfig.dot11RtsThreshold = 2347; + mibConfig.dot11FragmentationThreshold = 2346; + r = sme_mgt_mib_config_set(priv, &mibConfig); + if (r) { + unifi_error(priv, "iwprivs80211defaults: Set CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW; + powerConfig.listenIntervalTu = 100; + powerConfig.rxDtims = 1; + + r = sme_mgt_power_config_set(priv, &powerConfig); + if (r) { + unifi_error(priv, "iwprivs80211defaults: Set unifi_PowerConfigValue failed.\n"); + return r; + } + + return 0; +} /* iwprivsdefs() */ + +static int +iwprivs80211ps(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int r = 0; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + int ps_mode = (int)(*extra); + CsrWifiSmePowerConfig powerConfig; + + unifi_trace(priv, UDBG1, "iwprivs80211ps: power save mode = %d\n", ps_mode); + + r = sme_mgt_power_config_get(priv, &powerConfig); + if (r) { + unifi_error(priv, "iwprivs80211ps: Get unifi_PowerConfigValue failed.\n"); + return r; + } + + switch (ps_mode) { + case CSR_PMM_ACTIVE_MODE: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW; + break; + case CSR_PMM_POWER_SAVE: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH; + break; + case CSR_PMM_FAST_POWER_SAVE: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED; + break; + default: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO; + break; + } + + r = sme_mgt_power_config_set(priv, &powerConfig); + if (r) { + unifi_error(priv, "iwprivs80211ps: Set unifi_PowerConfigValue failed.\n"); + } + + return r; +} + +static int +iwprivg80211ps(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + CsrWifiSmePowerConfig powerConfig; + int r; + + r = sme_mgt_power_config_get(priv, &powerConfig); + if (r) { + unifi_error(priv, "iwprivg80211ps: Get 802.11 power mode failed.\n"); + return r; + } + + switch (powerConfig.powerSaveLevel) { + case CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW: + snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING, + "Power save mode: %d (Active)", + powerConfig.powerSaveLevel); + break; + case CSR_WIFI_SME_POWER_SAVE_LEVEL_MED: + snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING, + "Power save mode: %d (Fast)", + powerConfig.powerSaveLevel); + break; + case CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH: + snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING, + "Power save mode: %d (Full)", + powerConfig.powerSaveLevel); + break; + case CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO: + snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING, + "Power save mode: %d (Auto)", + powerConfig.powerSaveLevel); + break; + default: + snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING, + "Power save mode: %d (Unknown)", + powerConfig.powerSaveLevel); + break; + } + + wrqu->data.length = strlen(extra) + 1; + + return 0; +} + +static int +iwprivssmedebug(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* No longer supported on the API */ +#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) + unifi_debug_buf_dump(); +#endif + + return 0; +} + +#ifdef CSR_SUPPORT_WEXT_AP +#define PARAM_TYPE_INT 0 +#define PARAM_TYPE_STRING 1 +#define CSR_WIFI_MAX_SSID_LEN 32 +#define CSR_WIFI_MAX_SEC_LEN 16 +#define CSR_WIFI_MAX_KEY_LEN 65 + +static int hex_look_up(char x) +{ + if(x>='0' && x<='9') + return (x-48); + if(x>= 'a' && x <= 'f') + return (x-87); + return -1; +} + +static int power (int a, int b) +{ + int i; + int num =1; + for(i=0;i param_max_len) { + unifi_notice(priv,"extracted param len:%d is > MAX:%d\n",param_str_len, param_max_len); + param_str_len = param_max_len; + } + switch (param_type) { + case PARAM_TYPE_INT: + { + CsrUint32 *pdst_int = dst,num =0; + int i,j=0; + if (param_str_len > sizeof(int_str)) { + param_str_len = sizeof(int_str); + } + memcpy(int_str, param_str_begin, param_str_len); + for(i = param_str_len; i>0;i--) { + if(int_str[i-1] >= '0' && int_str[i-1] <='9') { + num += ((int_str[i-1]-'0')*power(10,j)); + j++; + } else { + unifi_error(priv,"decode_parameter_from_string:not a number %c\n",(int_str[i-1])); + return -1; + } + } + *pdst_int = num; + unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded int = %d\n",*pdst_int); + } + break; + default: + memcpy(dst, param_str_begin, param_str_len); + *((char *)dst + param_str_len) = 0; + unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded string = %s\n",(char *)dst); + break; + } + } else { + unifi_error(priv,"decode_parameter_from_string: Token:%s not found in %s \n",token,orig_str); + return -1; + } + return 0; +} +static int store_ap_advanced_config_from_string(unifi_priv_t *priv, char *param_str) +{ + char * str_ptr=param_str; + int ret = 0,tmp_var; + char phy_mode[6]; + CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config; + + /* Check for BI */ + ret = decode_parameter_from_string(priv, &str_ptr, "BI=", + PARAM_TYPE_INT, &tmp_var, 5); + if(ret) { + unifi_error(priv,"store_ap_advanced_config_from_string: BI not found\n"); + return -1; + } + ap_mac_config->beaconInterval = tmp_var; + ret = decode_parameter_from_string(priv, &str_ptr, "DTIM_PER=", + PARAM_TYPE_INT, &tmp_var, 5); + if(ret) { + unifi_error(priv,"store_ap_advanced_config_from_string: DTIM_PER not found\n"); + return -1; + } + ap_mac_config->dtimPeriod = tmp_var; + ret = decode_parameter_from_string(priv, &str_ptr, "WMM=", + PARAM_TYPE_INT, &tmp_var, 5); + if(ret) { + unifi_error(priv,"store_ap_advanced_config_from_string: WMM not found\n"); + return -1; + } + ap_mac_config->wmmEnabled = tmp_var; + ret = decode_parameter_from_string(priv, &str_ptr, "PHY=", + PARAM_TYPE_STRING, phy_mode, 5); + if(ret) { + unifi_error(priv,"store_ap_advanced_config_from_string: PHY not found\n"); + } else { + if(strstr(phy_mode,"b")){ + ap_mac_config->phySupportedBitmap = CSR_WIFI_SME_AP_PHY_SUPPORT_B; + } + if(strstr(phy_mode,"g")) { + ap_mac_config->phySupportedBitmap |= CSR_WIFI_SME_AP_PHY_SUPPORT_G; + } + if(strstr(phy_mode,"n")) { + ap_mac_config->phySupportedBitmap |= CSR_WIFI_SME_AP_PHY_SUPPORT_N; + } + ap_mac_config->supportedRatesCount = + uf_configure_supported_rates(ap_mac_config->supportedRates, ap_mac_config->phySupportedBitmap); + } + return ret; +} + +static int store_ap_config_from_string( unifi_priv_t * priv,char *param_str) + +{ + char *str_ptr = param_str; + char sub_cmd[16]; + char sec[CSR_WIFI_MAX_SEC_LEN]; + char key[CSR_WIFI_MAX_KEY_LEN]; + int ret = 0,tmp_var; + CsrWifiSmeApConfig_t *ap_config = &priv->ap_config; + CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config; + memset(sub_cmd, 0, sizeof(sub_cmd)); + if(!strstr(param_str,"END")) { + unifi_error(priv,"store_ap_config_from_string:Invalid config string:%s\n",param_str); + return -1; + } + if (decode_parameter_from_string(priv,&str_ptr, "ASCII_CMD=", + PARAM_TYPE_STRING, sub_cmd, 6) != 0) { + return -1; + } + if (strncmp(sub_cmd, "AP_CFG", 6)) { + + if(!strncmp(sub_cmd ,"ADVCFG", 6)) { + return store_ap_advanced_config_from_string(priv, str_ptr); + } + unifi_error(priv,"store_ap_config_from_string: sub_cmd:%s != 'AP_CFG or ADVCFG'!\n", sub_cmd); + return -1; + } + memset(ap_config, 0, sizeof(CsrWifiSmeApConfig_t)); + ret = decode_parameter_from_string(priv,&str_ptr, "SSID=", + PARAM_TYPE_STRING, ap_config->ssid.ssid, + CSR_WIFI_MAX_SSID_LEN); + if(ret) { + unifi_error(priv,"store_ap_config_from_string: SSID not found\n"); + return -1; + } + ap_config->ssid.length = strlen(ap_config->ssid.ssid); + + ret = decode_parameter_from_string(priv, &str_ptr, "SEC=", + PARAM_TYPE_STRING, sec, CSR_WIFI_MAX_SEC_LEN); + if(ret) { + unifi_error(priv,"store_ap_config_from_string: SEC not found\n"); + return -1; + } + ret = decode_parameter_from_string(priv,&str_ptr, "KEY=", + PARAM_TYPE_STRING, key, CSR_WIFI_MAX_KEY_LEN); + if(!strcasecmp(sec,"open")) { + unifi_trace(priv,UDBG2,"store_ap_config_from_string: security open"); + ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM; + if(ret) { + unifi_notice(priv,"store_ap_config_from_string: KEY not found:fine with Open\n"); + } + } + else if(!strcasecmp(sec,"wpa2-psk")) { + int i,j=0; + CsrWifiNmeApAuthPers *pers = + ((CsrWifiNmeApAuthPers *)&(ap_config->credentials.nmeAuthType.authTypePersonal)); + CsrUint8 *psk = pers->authPers_credentials.psk.psk; + + unifi_trace(priv,UDBG2,"store_ap_config_from_string: security WPA2"); + if(ret) { + unifi_error(priv,"store_ap_config_from_string: KEY not found for WPA2\n"); + return -1; + } + ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL; + pers->authSupport = CSR_WIFI_SME_RSN_AUTH_WPA2PSK; + pers->rsnCapabilities =0; + pers->wapiCapabilities =0; + pers->pskOrPassphrase=CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK; + pers->authPers_credentials.psk.encryptionMode = + (CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP |CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP) ; + for(i=0;i<32;i++){ + psk[i] = (16*hex_look_up(key[j]))+hex_look_up(key[j+1]); + j+=2; + } + + } else { + unifi_notice(priv,"store_ap_config_from_string: Unknown security: Assuming Open"); + ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM; + return -1; + } + /* Get the decoded value in a temp int variable to ensure that other fields within the struct + which are of type other than int are not over written */ + ret = decode_parameter_from_string(priv,&str_ptr, "CHANNEL=", PARAM_TYPE_INT, &tmp_var, 5); + if(ret) + return -1; + ap_config->channel = tmp_var; + ret = decode_parameter_from_string(priv,&str_ptr, "PREAMBLE=", PARAM_TYPE_INT, &tmp_var, 5); + if(ret) + return -1; + ap_mac_config->preamble = tmp_var; + ret = decode_parameter_from_string(priv,&str_ptr, "MAX_SCB=", PARAM_TYPE_INT, &tmp_var, 5); + ap_config->max_connections = tmp_var; + return ret; +} + +static int +iwprivsapstart(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int r; + + unifi_trace(priv, UDBG1, "iwprivsapstart\n" ); + r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config); + if(r) { + unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r); + } + return r; +} + +static int +iwprivsapconfig(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + char *cfg_str = NULL; + int r; + + unifi_trace(priv, UDBG1, "iwprivsapconfig\n" ); + if (wrqu->data.length != 0) { + char *str; + if (!(cfg_str = kmalloc(wrqu->data.length+1, GFP_KERNEL))) + { + return -ENOMEM; + } + if (copy_from_user(cfg_str, wrqu->data.pointer, wrqu->data.length)) { + kfree(cfg_str); + return -EFAULT; + } + cfg_str[wrqu->data.length] = 0; + unifi_trace(priv,UDBG2,"length:%d\n",wrqu->data.length); + unifi_trace(priv,UDBG2,"AP configuration string:%s\n",cfg_str); + str = cfg_str; + if ((r = store_ap_config_from_string(priv,str))) { + unifi_error(priv, "iwprivsapconfig:Failed to decode the string %d\n",r); + kfree(cfg_str); + return -EIO; + + } + } else { + unifi_error(priv,"iwprivsapconfig argument length = 0 \n"); + return -EIO; + } + r = sme_ap_config(priv, &priv->ap_mac_config, &priv->group_sec_config); + if(r) { + unifi_error(priv,"iwprivsapstop AP Config failed : %d\n",-r); + } else if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_trace(priv, UDBG1, "iwprivsapconfig: Starting the AP"); + r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config); + if(r) { + unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r); + } + } + kfree(cfg_str); + return r; +} + +static int +iwprivsapstop(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int r; + CsrUint16 interface_tag = interfacePriv->InterfaceTag; + + unifi_trace(priv, UDBG1, "iwprivsapstop\n" ); + r = sme_ap_stop(priv,interface_tag); + if(r) { + unifi_error(priv,"iwprivsapstop AP STOP failed : %d\n",-r); + } + return r; +} + +#ifdef ANDROID_BUILD +static int +iwprivsapfwreload(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + unifi_trace(priv, UDBG1, "iwprivsapfwreload\n" ); + return 0; +} + +static int +iwprivsstackstart(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + unifi_trace(priv, UDBG1, "iwprivsstackstart\n" ); + return 0; +} + +static int +iwprivsstackstop(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int r = 0; + CsrUint16 interface_tag = interfacePriv->InterfaceTag; + + unifi_trace(priv, UDBG1, "iwprivsstackstop\n" ); + + switch(interfacePriv->interfaceMode) { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + r = sme_mgt_disconnect(priv); + break; + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + r = sme_ap_stop(priv,interface_tag); + break; + default : + break; + } + + if(r) { + unifi_error(priv,"iwprivsstackstop Stack stop failed : %d\n",-r); + } + return 0; +} +#endif /* ANDROID_BUILD */ +#endif /* CSR_SUPPORT_WEXT_AP */ + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE +static int +iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + CsrUint8 enable; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + func_enter(); + + unifi_trace(priv, UDBG1, "iwprivsconfwapi\n" ); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "iwprivsconfwapi: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + enable = *(CsrUint8*)(extra); + + if (enable) { + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI); + priv->connection_config.encryptionModeMask |= + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4; + } else { + priv->connection_config.authModeMask &= ~(CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI); + priv->connection_config.encryptionModeMask &= + ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4); + } + + func_exit(); + return 0; +} + +static int +iwprivswpikey(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int r = 0, i; + CsrWifiSmeKey key; + unifiio_wapi_key_t inKey; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + func_enter(); + + unifi_trace(priv, UDBG1, "iwprivswpikey\n" ); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + inKey = *(unifiio_wapi_key_t*)(extra); + + if (inKey.unicastKey) { + key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE; + } else { + key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP; + } + + key.keyIndex = inKey.keyIndex; + + /* memcpy(key.keyRsc, inKey.keyRsc, 16); */ + for (i = 0; i < 16; i+= 2) + { + key.keyRsc[i/2] = inKey.keyRsc[i+1] << 8 | inKey.keyRsc[i]; + } + + memcpy(key.address.a, inKey.address, 6); + key.keyLength = 32; + memcpy(key.key, inKey.key, 32); + key.authenticator = 0; + key.wepTxKey = 0; + + unifi_trace(priv, UDBG1, "keyType = %d, keyIndex = %d, wepTxKey = %d, keyRsc = %x:%x, auth = %d, address = %x:%x, " + "keylength = %d, key = %x:%x\n", key.keyType, key.keyIndex, key.wepTxKey, + key.keyRsc[0], key.keyRsc[7], key.authenticator, + key.address.a[0], key.address.a[5], key.keyLength, key.key[0], + key.key[15]); + + r = sme_mgt_key(priv, &key, CSR_WIFI_SME_LIST_ACTION_ADD); + if (r) { + unifi_error(priv, "SETKEYS request was rejected with result %d\n", r); + return convert_sme_error(r); + } + + func_exit(); + return r; +} +#endif + + +static int +unifi_giwname(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + char *name = wrqu->name; + unifi_trace(priv, UDBG2, "unifi_giwname\n"); + + if (priv->if_index == CSR_INDEX_5G) { + strcpy(name, "IEEE 802.11-a"); + } else { + strcpy(name, "IEEE 802.11-bgn"); + } + return 0; +} /* unifi_giwname() */ + + +static int +unifi_siwfreq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_freq *freq = (struct iw_freq *)wrqu; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_siwfreq\n"); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwfreq: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + /* + * Channel is stored in the connection configuration, + * and set later when ask for a connection. + */ + if ((freq->e == 0) && (freq->m <= 1000)) { + priv->connection_config.adhocChannel = freq->m; + } else { + priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e); + } + + func_exit(); + return 0; +} /* unifi_siwfreq() */ + + +static int +unifi_giwfreq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_freq *freq = (struct iw_freq *)wrqu; + int err = 0; + CsrWifiSmeConnectionInfo connectionInfo; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_giwfreq\n"); + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_giwfreq: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + UF_RTNL_UNLOCK(); + err = sme_mgt_connection_info_get(priv, &connectionInfo); + UF_RTNL_LOCK(); + + freq->m = channel_to_mhz(connectionInfo.channelNumber, + (connectionInfo.networkType80211 == CSR_WIFI_SME_RADIO_IF_GHZ_5_0)); + freq->e = 6; + + func_exit(); + return convert_sme_error(err); +} /* unifi_giwfreq() */ + + +static int +unifi_siwmode(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_siwmode\n"); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwmode: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + switch(wrqu->mode) { + case IW_MODE_ADHOC: + priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ADHOC; + break; + case IW_MODE_INFRA: + priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE; + break; + case IW_MODE_AUTO: + priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ANY_BSS; + break; + default: + unifi_notice(priv, "Unknown IW MODE value.\n"); + } + + /* Clear the SSID and BSSID configuration */ + priv->connection_config.ssid.length = 0; + memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN); + + func_exit(); + return 0; +} /* unifi_siwmode() */ + + + +static int +unifi_giwmode(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int r = 0; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + CsrWifiSmeConnectionConfig connectionConfig; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_giwmode\n"); + CHECK_INITED(priv); + + unifi_trace(priv, UDBG2, "unifi_giwmode: Exisitng mode = 0x%x\n", + interfacePriv->interfaceMode); + switch(interfacePriv->interfaceMode) { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + wrqu->mode = IW_MODE_INFRA; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + wrqu->mode = IW_MODE_MASTER; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + wrqu->mode = IW_MODE_ADHOC; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_P2P: + case CSR_WIFI_ROUTER_CTRL_MODE_NONE: + UF_RTNL_UNLOCK(); + r = sme_mgt_connection_config_get(priv, &connectionConfig); + UF_RTNL_LOCK(); + if (r == 0) { + switch(connectionConfig.bssType) { + case CSR_WIFI_SME_BSS_TYPE_ADHOC: + wrqu->mode = IW_MODE_ADHOC; + break; + case CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE: + wrqu->mode = IW_MODE_INFRA; + break; + default: + wrqu->mode = IW_MODE_AUTO; + unifi_notice(priv, "Unknown IW MODE value.\n"); + } + } + break; + default: + wrqu->mode = IW_MODE_AUTO; + unifi_notice(priv, "Unknown IW MODE value.\n"); + + } + unifi_trace(priv, UDBG4, "unifi_giwmode: mode = 0x%x\n", wrqu->mode); + func_exit(); + return r; +} /* unifi_giwmode() */ + + + +static int +unifi_giwrange(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + struct iw_range *range = (struct iw_range *) extra; + int i; + + unifi_trace(NULL, UDBG2, "unifi_giwrange\n"); + + dwrq->length = sizeof(struct iw_range); + memset(range, 0, sizeof(*range)); + range->min_nwid = 0x0000; + range->max_nwid = 0x0000; + + /* + * Don't report the frequency/channel table, then the channel + * number returned elsewhere will be printed as a channel number. + */ + + /* Ranges of values reported in quality structs */ + range->max_qual.qual = 40; /* Max expected qual value */ + range->max_qual.level = -120; /* Noise floor in dBm */ + range->max_qual.noise = -120; /* Noise floor in dBm */ + + + /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */ + i = 0; +#if WIRELESS_EXT > 15 + range->bitrate[i++] = 2 * 500000; + range->bitrate[i++] = 4 * 500000; + range->bitrate[i++] = 11 * 500000; + range->bitrate[i++] = 22 * 500000; + range->bitrate[i++] = 12 * 500000; + range->bitrate[i++] = 18 * 500000; + range->bitrate[i++] = 24 * 500000; + range->bitrate[i++] = 36 * 500000; + range->bitrate[i++] = 48 * 500000; + range->bitrate[i++] = 72 * 500000; + range->bitrate[i++] = 96 * 500000; + range->bitrate[i++] = 108 * 500000; +#else + range->bitrate[i++] = 2 * 500000; + range->bitrate[i++] = 4 * 500000; + range->bitrate[i++] = 11 * 500000; + range->bitrate[i++] = 22 * 500000; + range->bitrate[i++] = 24 * 500000; + range->bitrate[i++] = 48 * 500000; + range->bitrate[i++] = 96 * 500000; + range->bitrate[i++] = 108 * 500000; +#endif /* WIRELESS_EXT < 16 */ + range->num_bitrates = i; + + range->max_encoding_tokens = NUM_WEPKEYS; + range->num_encoding_sizes = 2; + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + + range->we_version_source = 20; + range->we_version_compiled = WIRELESS_EXT; + + /* Number of channels available in h/w */ + range->num_channels = 14; + /* Number of entries in freq[] array */ + range->num_frequency = 14; + for (i = 0; (i < range->num_frequency) && (i < IW_MAX_FREQUENCIES); i++) { + int chan = i + 1; + range->freq[i].i = chan; + range->freq[i].m = channel_to_mhz(chan, 0); + range->freq[i].e = 6; + } + if ((i+3) < IW_MAX_FREQUENCIES) { + range->freq[i].i = 36; + range->freq[i].m = channel_to_mhz(36, 1); + range->freq[i].e = 6; + range->freq[i+1].i = 40; + range->freq[i+1].m = channel_to_mhz(40, 1); + range->freq[i+1].e = 6; + range->freq[i+2].i = 44; + range->freq[i+2].m = channel_to_mhz(44, 1); + range->freq[i+2].e = 6; + range->freq[i+3].i = 48; + range->freq[i+3].m = channel_to_mhz(48, 1); + range->freq[i+3].e = 6; + } + +#if WIRELESS_EXT > 16 + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) | + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) | + IW_EVENT_CAPA_MASK(IWEVCUSTOM) | + IW_EVENT_CAPA_MASK(IWEVREGISTERED) | + IW_EVENT_CAPA_MASK(IWEVEXPIRED)); +#endif /* WIRELESS_EXT > 16 */ + +#if WIRELESS_EXT > 17 + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; +#endif /* WIRELESS_EXT > 17 */ + + + return 0; +} /* unifi_giwrange() */ + + +static int +unifi_siwap(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int err = 0; + const unsigned char zero_bssid[ETH_ALEN] = {0x00, 0x00, 0x00, + 0x00, 0x00, 0x00}; + + func_enter(); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwap: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) { + return -EINVAL; + } + + unifi_trace(priv, UDBG1, "unifi_siwap: asked for %02X:%02X:%02X:%02X:%02X:%02X\n", + (u8)wrqu->ap_addr.sa_data[0], + (u8)wrqu->ap_addr.sa_data[1], + (u8)wrqu->ap_addr.sa_data[2], + (u8)wrqu->ap_addr.sa_data[3], + (u8)wrqu->ap_addr.sa_data[4], + (u8)wrqu->ap_addr.sa_data[5]); + + if (!memcmp(wrqu->ap_addr.sa_data, zero_bssid, ETH_ALEN)) { + priv->ignore_bssid_join = FALSE; + err = sme_mgt_disconnect(priv); + if (err) { + unifi_trace(priv, UDBG4, "unifi_siwap: Disconnect failed, status %d\n", err); + } + return 0; + } + + if (priv->ignore_bssid_join) { + unifi_trace(priv, UDBG4, "unifi_siwap: ignoring second join\n"); + priv->ignore_bssid_join = FALSE; + } else { + memcpy(priv->connection_config.bssid.a, wrqu->ap_addr.sa_data, ETH_ALEN); + unifi_trace(priv, UDBG1, "unifi_siwap: Joining %X:%X:%X:%X:%X:%X\n", + priv->connection_config.bssid.a[0], + priv->connection_config.bssid.a[1], + priv->connection_config.bssid.a[2], + priv->connection_config.bssid.a[3], + priv->connection_config.bssid.a[4], + priv->connection_config.bssid.a[5]); + err = sme_mgt_connect(priv); + if (err) { + unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err); + func_exit(); + return convert_sme_error(err); + } + } + func_exit(); + + return 0; +} /* unifi_siwap() */ + + +static int +unifi_giwap(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + CsrWifiSmeConnectionInfo connectionInfo; + int r = 0; + CsrUint8 *bssid; + + func_enter(); + + CHECK_INITED(priv); + unifi_trace(priv, UDBG2, "unifi_giwap\n"); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + UF_RTNL_UNLOCK(); + r = sme_mgt_connection_info_get(priv, &connectionInfo); + UF_RTNL_LOCK(); + + if (r == 0) { + bssid = connectionInfo.bssid.a; + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + unifi_trace(priv, UDBG4, + "unifi_giwap: BSSID = %02X:%02X:%02X:%02X:%02X:%02X\n", + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5]); + + memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN); + } else { + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + } + + func_exit(); + return 0; +} /* unifi_giwap() */ + + +static int +unifi_siwscan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int scantype; + int r; + CsrWifiSsid scan_ssid; + unsigned char *channel_list = NULL; + int chans_good = 0; +#if WIRELESS_EXT > 17 + struct iw_point *data = &wrqu->data; + struct iw_scan_req *req = (struct iw_scan_req *) extra; +#endif + + func_enter(); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwscan: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + scantype = UNIFI_SCAN_ACTIVE; + +#if WIRELESS_EXT > 17 + /* Providing a valid channel list will force an active scan */ + if (req) { + if ((req->num_channels > 0) && (req->num_channels < IW_MAX_FREQUENCIES)) { + channel_list = kmalloc(req->num_channels, GFP_KERNEL); + if (channel_list) { + int i; + for (i = 0; i < req->num_channels; i++) { + /* Convert frequency to channel number */ + int ch = wext_freq_to_channel(req->channel_list[i].m, + req->channel_list[i].e); + if (ch) { + channel_list[chans_good++] = ch; + } + } + unifi_trace(priv, UDBG1, + "SIWSCAN: Scanning %d channels\n", chans_good); + } else { + /* Fall back to scanning all */ + unifi_error(priv, "SIWSCAN: Can't alloc channel_list (%d)\n", + req->num_channels); + } + } + } + + if (req && (data->flags & IW_SCAN_THIS_ESSID)) { + memcpy(scan_ssid.ssid, req->essid, req->essid_len); + scan_ssid.length = req->essid_len; + unifi_trace(priv, UDBG1, + "SIWSCAN: Scanning for %.*s\n", + scan_ssid.length, scan_ssid.ssid); + } else +#endif + { + unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for all APs\n"); + scan_ssid.length = 0; + } + + r = sme_mgt_scan_full(priv, &scan_ssid, chans_good, channel_list); + if (r) { + unifi_error(priv, "SIWSCAN: Scan returned error %d\n", r); + } else { + unifi_trace(priv, UDBG1, "SIWSCAN: Scan done\n"); + wext_send_scan_results_event(priv); + } + + if (channel_list) { + kfree(channel_list); + } + + func_exit(); + return r; + +} /* unifi_siwscan() */ + + +static const unsigned char * +unifi_find_info_element(int id, const unsigned char *info, int len) +{ + const unsigned char *ie = info; + + while (len > 1) + { + int e_id, e_len; + e_id = ie[0]; + e_len = ie[1]; + + /* Return if we find a match */ + if (e_id == id) + { + return ie; + } + + len -= (e_len + 2); + ie += (e_len + 2); + } + + return NULL; +} /* unifi_find_info_element() */ + + +/* + * Translate scan data returned from the card to a card independent + * format that the Wireless Tools will understand - Jean II + */ +int +unifi_translate_scan(struct net_device *dev, + struct iw_request_info *info, + char *current_ev, char *end_buf, + CsrWifiSmeScanResult *scan_data, + int scan_index) +{ + struct iw_event iwe; /* Temporary buffer */ + unsigned char *info_elems; + int info_elem_len; + const unsigned char *elem; + u16 capabilities; + int signal, noise, snr; + char *start_buf = current_ev; + char *current_val; /* For rates */ + int i, r; + + info_elems = scan_data->informationElements; + info_elem_len = scan_data->informationElementsLength; + + if (!scan_data->informationElementsLength || !scan_data->informationElements) { + unifi_error(NULL, "*** NULL SCAN IEs ***\n"); + return -EIO; + } + + /* get capinfo bits */ + capabilities = scan_data->capabilityInformation; + + unifi_trace(NULL, UDBG5, "Capabilities: 0x%x\n", capabilities); + + /* First entry *MUST* be the AP MAC address */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, scan_data->bssid.a, ETH_ALEN); + iwe.len = IW_EV_ADDR_LEN; + r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_ADDR_LEN); + if (r < 0) { + return r; + } + start_buf += r; + + /* Other entries will be displayed in the order we give them */ + + /* Add the ESSID */ + /* find SSID in Info Elems */ + elem = unifi_find_info_element(IE_SSID_ID, info_elems, info_elem_len); + if (elem) { + int e_len = elem[1]; + const unsigned char *e_ptr = elem + 2; + unsigned char buf[33]; + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWESSID; + iwe.u.essid.length = e_len; + if (iwe.u.essid.length > 32) { + iwe.u.essid.length = 32; + } + iwe.u.essid.flags = scan_index; + memcpy(buf, e_ptr, iwe.u.essid.length); + buf[iwe.u.essid.length] = '\0'; + r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, buf); + if (r < 0) { + return r; + } + start_buf += r; + + } + + /* Add mode */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWMODE; + if (scan_data->bssType == CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE) { + iwe.u.mode = IW_MODE_INFRA; + } else { + iwe.u.mode = IW_MODE_ADHOC; + } + iwe.len = IW_EV_UINT_LEN; + r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_UINT_LEN); + if (r < 0) { + return r; + } + start_buf += r; + + /* Add frequency. iwlist will convert to channel using table given in giwrange */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = scan_data->channelFrequency; + iwe.u.freq.e = 6; + r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_FREQ_LEN); + if (r < 0) { + return r; + } + start_buf += r; + + + /* Add quality statistics */ + iwe.cmd = IWEVQUAL; + /* + * level and noise below are mapped into an unsigned 8 bit number, + * ranging from [-192; 63]. The way this is achieved is simply to + * add 0x100 onto the number if it is negative, + * once clipped to the correct range. + */ + signal = scan_data->rssi; /* This value is in dBm */ + /* Clip range of snr */ + snr = (scan_data->snr > 0) ? scan_data->snr : 0; /* In dB relative, from 0 - 255 */ + snr = (snr < 255) ? snr : 255; + noise = signal - snr; + + /* Clip range of signal */ + signal = (signal < 63) ? signal : 63; + signal = (signal > -192) ? signal : -192; + + /* Clip range of noise */ + noise = (noise < 63) ? noise : 63; + noise = (noise > -192) ? noise : -192; + + /* Make u8 */ + signal = ( signal < 0 ) ? signal + 0x100 : signal; + noise = ( noise < 0 ) ? noise + 0x100 : noise; + + iwe.u.qual.level = (u8)signal; /* -192 : 63 */ + iwe.u.qual.noise = (u8)noise; /* -192 : 63 */ + iwe.u.qual.qual = snr; /* 0 : 255 */ + iwe.u.qual.updated = 0; +#if WIRELESS_EXT > 16 + iwe.u.qual.updated |= IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED | + IW_QUAL_QUAL_UPDATED; +#if WIRELESS_EXT > 18 + iwe.u.qual.updated |= IW_QUAL_DBM; +#endif +#endif + r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_QUAL_LEN); + if (r < 0) { + return r; + } + start_buf += r; + + /* Add encryption capability */ + iwe.cmd = SIOCGIWENCODE; + if (capabilities & SIG_CAP_PRIVACY) { + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + } else { + iwe.u.data.flags = IW_ENCODE_DISABLED; + } + iwe.u.data.length = 0; + iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; + r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, ""); + if (r < 0) { + return r; + } + start_buf += r; + + + /* + * Rate : stuffing multiple values in a single event require a bit + * more of magic - Jean II + */ + current_val = start_buf + IW_EV_LCP_LEN; + + iwe.cmd = SIOCGIWRATE; + /* Those two flags are ignored... */ + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + + elem = unifi_find_info_element(IE_SUPPORTED_RATES_ID, + info_elems, info_elem_len); + if (elem) { + int e_len = elem[1]; + const unsigned char *e_ptr = elem + 2; + + /* + * Count how many rates we have. + * Zero marks the end of the list, if the list is not truncated. + */ + /* Max 8 values */ + for (i = 0; i < e_len; i++) { + if (e_ptr[i] == 0) { + break; + } + /* Bit rate given in 500 kb/s units (+ 0x80) */ + iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000); + /* Add new value to event */ + r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + if (r < 0) { + return r; + } + current_val +=r; + + } + } + elem = unifi_find_info_element(IE_EXTENDED_SUPPORTED_RATES_ID, + info_elems, info_elem_len); + if (elem) { + int e_len = elem[1]; + const unsigned char *e_ptr = elem + 2; + + /* + * Count how many rates we have. + * Zero marks the end of the list, if the list is not truncated. + */ + /* Max 8 values */ + for (i = 0; i < e_len; i++) { + if (e_ptr[i] == 0) { + break; + } + /* Bit rate given in 500 kb/s units (+ 0x80) */ + iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000); + /* Add new value to event */ + r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + if (r < 0) { + return r; + } + current_val +=r; + } + } + /* Check if we added any rates event */ + if ((current_val - start_buf) > IW_EV_LCP_LEN) { + start_buf = current_val; + } + + +#if WIRELESS_EXT > 17 + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = info_elem_len; + + r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, info_elems); + if (r < 0) { + return r; + } + + start_buf += r; +#endif /* WE > 17 */ + + return (start_buf - current_ev); +} /* unifi_translate_scan() */ + + + +static int +unifi_giwscan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_point *dwrq = &wrqu->data; + int r; + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_giwscan: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + unifi_trace(priv, UDBG1, + "unifi_giwscan: buffer (%d bytes) \n", + dwrq->length); + UF_RTNL_UNLOCK(); + r = sme_mgt_scan_results_get_async(priv, info, extra, dwrq->length); + UF_RTNL_LOCK(); + if (r < 0) { + unifi_trace(priv, UDBG1, + "unifi_giwscan: buffer (%d bytes) not big enough.\n", + dwrq->length); + return r; + } + + dwrq->length = r; + dwrq->flags = 0; + + return 0; +} /* unifi_giwscan() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_siwessid + * + * Request to join a network or start and AdHoc. + * + * Arguments: + * dev Pointer to network device struct. + * info Pointer to broken-out ioctl request. + * data Pointer to argument data. + * essid Pointer to string giving name of network to join + * or start + * + * Returns: + * 0 on success and everything complete + * -EINPROGRESS to have the higher level call the commit method. + * --------------------------------------------------------------------------- + */ +static int +unifi_siwessid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int len; + int err = 0; + + func_enter(); + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwessid: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + len = 0; + if (data->flags & 1) { + /* Limit length */ + len = data->length; + if (len > UNIFI_MAX_SSID_LEN) { + len = UNIFI_MAX_SSID_LEN; + } + } + +#ifdef UNIFI_DEBUG + { + char essid_str[UNIFI_MAX_SSID_LEN+1]; + int i; + + for (i = 0; i < len; i++) { + essid_str[i] = (isprint(essid[i]) ? essid[i] : '?'); + } + essid_str[i] = '\0'; + + unifi_trace(priv, UDBG1, "unifi_siwessid: asked for '%*s' (%d)\n", len, essid_str, len); + unifi_trace(priv, UDBG2, " with authModeMask = %d", priv->connection_config.authModeMask); + } +#endif + + memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN); + if (len) { + if (essid[len - 1] == 0) { + len --; + } + + memcpy(priv->connection_config.ssid.ssid, essid, len); + priv->connection_config.ssid.length = len; + + } else { + priv->connection_config.ssid.length = 0; + } + + UF_RTNL_UNLOCK(); + err = sme_mgt_connect(priv); + UF_RTNL_LOCK(); + if (err) { + unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err); + func_exit(); + return convert_sme_error(err); + } + + func_exit(); + return 0; +} /* unifi_siwessid() */ + + +static int +unifi_giwessid(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *essid) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_point *data = &wrqu->essid; + CsrWifiSmeConnectionInfo connectionInfo; + int r = 0; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_giwessid\n"); + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_giwessid: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + UF_RTNL_UNLOCK(); + r = sme_mgt_connection_info_get(priv, &connectionInfo); + UF_RTNL_LOCK(); + + if (r == 0) { + data->length = connectionInfo.ssid.length; + strncpy(essid, + connectionInfo.ssid.ssid, + data->length); + data->flags = 1; /* active */ + + unifi_trace(priv, UDBG2, "unifi_giwessid: %.*s\n", + data->length, essid); + } + + func_exit(); + + return 0; +} /* unifi_giwessid() */ + + +static int +unifi_siwrate(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_param *args = &wrqu->bitrate; + CsrWifiSmeMibConfig mibConfig; + int r; + + func_enter(); + + CHECK_INITED(priv); + unifi_trace(priv, UDBG2, "unifi_siwrate\n"); + + /* + * If args->fixed == 0, value is max rate or -1 for best + * If args->fixed == 1, value is rate to set or -1 for best + * args->disabled and args->flags are not used in SIOCSIWRATE + */ + + /* Get, modify and set the MIB data */ + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_get(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwrate: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + /* Default to auto rate algorithm */ + /* in 500Kbit/s, 0 means auto */ + mibConfig.unifiFixTxDataRate = 0; + + if (args->value != -1) { + mibConfig.unifiFixTxDataRate = args->value / 500000; + } + + /* 1 means rate is a maximum, 2 means rate is a set value */ + if (args->fixed == 1) { + mibConfig.unifiFixMaxTxDataRate = 0; + } else { + mibConfig.unifiFixMaxTxDataRate = 1; + } + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_set(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwrate: Set CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + func_exit(); + + return 0; +} /* unifi_siwrate() */ + + + +static int +unifi_giwrate(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_param *args = &wrqu->bitrate; + int r; + int bitrate, flag; + CsrWifiSmeMibConfig mibConfig; + CsrWifiSmeConnectionStats connectionStats; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_giwrate\n"); + CHECK_INITED(priv); + + flag = 0; + bitrate = 0; + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_get(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_giwrate: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + bitrate = mibConfig.unifiFixTxDataRate; + flag = mibConfig.unifiFixMaxTxDataRate; + + /* Used the value returned by the SME if MIB returns 0 */ + if (bitrate == 0) { + UF_RTNL_UNLOCK(); + r = sme_mgt_connection_stats_get(priv, &connectionStats); + UF_RTNL_LOCK(); + /* Ignore errors, we may be disconnected */ + if (r == 0) { + bitrate = connectionStats.unifiTxDataRate; + } + } + + args->value = bitrate * 500000; + args->fixed = !flag; + + func_exit(); + + return 0; +} /* unifi_giwrate() */ + + +static int +unifi_siwrts(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int val = wrqu->rts.value; + int r = 0; + CsrWifiSmeMibConfig mibConfig; + + unifi_trace(priv, UDBG2, "unifi_siwrts\n"); + CHECK_INITED(priv); + + if (wrqu->rts.disabled) { + val = 2347; + } + + if ( (val < 0) || (val > 2347) ) + { + return -EINVAL; + } + + /* Get, modify and set the MIB data */ + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_get(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwrts: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + mibConfig.dot11RtsThreshold = val; + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_set(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwrts: Set CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + return 0; +} + + +static int +unifi_giwrts(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int r; + int rts_thresh; + CsrWifiSmeMibConfig mibConfig; + + unifi_trace(priv, UDBG2, "unifi_giwrts\n"); + CHECK_INITED(priv); + + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_get(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_giwrts: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + rts_thresh = mibConfig.dot11RtsThreshold; + if (rts_thresh > 2347) { + rts_thresh = 2347; + } + + wrqu->rts.value = rts_thresh; + wrqu->rts.disabled = (rts_thresh == 2347); + wrqu->rts.fixed = 1; + + return 0; +} + + +static int +unifi_siwfrag(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int val = wrqu->frag.value; + int r = 0; + CsrWifiSmeMibConfig mibConfig; + + unifi_trace(priv, UDBG2, "unifi_siwfrag\n"); + CHECK_INITED(priv); + + if (wrqu->frag.disabled) + val = 2346; + + if ( (val < 256) || (val > 2347) ) + return -EINVAL; + + /* Get, modify and set the MIB data */ + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_get(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwfrag: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + /* Fragmentation Threashold must be even */ + mibConfig.dot11FragmentationThreshold = (val & ~0x1); + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_set(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwfrag: Set CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + return 0; +} + + +static int +unifi_giwfrag(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int r; + int frag_thresh; + CsrWifiSmeMibConfig mibConfig; + + unifi_trace(priv, UDBG2, "unifi_giwfrag\n"); + CHECK_INITED(priv); + + UF_RTNL_UNLOCK(); + r = sme_mgt_mib_config_get(priv, &mibConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_giwfrag: Get CsrWifiSmeMibConfigValue failed.\n"); + return r; + } + + frag_thresh = mibConfig.dot11FragmentationThreshold; + + /* Build the return structure */ + wrqu->frag.value = frag_thresh; + wrqu->frag.disabled = (frag_thresh >= 2346); + wrqu->frag.fixed = 1; + + return 0; +} + + +static int +unifi_siwencode(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_point *erq = &wrqu->encoding; + int index; + int rc = 0; + int privacy = -1; + CsrWifiSmeKey sme_key; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_siwencode\n"); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwencode: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + /* + * Key index is encoded in the flags. + * 0 - use current default, + * 1-4 - if a key value is given set that key + * if not use that key + */ + index = (erq->flags & IW_ENCODE_INDEX); /* key number, 1-4 */ + if ((index < 0) || (index > 4)) { + unifi_error(priv, "unifi_siwencode: Request to set an invalid key (index:%d)", index); + return -EINVAL; + } + + /* + * Basic checking: do we have a key to set ? + * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags), + * but older versions rely on sending a key id 1-4. + */ + if (erq->length > 0) { + + /* Check the size of the key */ + if ((erq->length > LARGE_KEY_SIZE) || (erq->length < SMALL_KEY_SIZE)) { + unifi_error(priv, "unifi_siwencode: Request to set an invalid key (length:%d)", + erq->length); + return -EINVAL; + } + + /* Check the index (none (i.e. 0) means use current) */ + if ((index < 1) || (index > 4)) { + /* If we do not have a previous key, use 1 as default */ + if (!priv->wep_tx_key_index) { + priv->wep_tx_key_index = 1; + } + index = priv->wep_tx_key_index; + } + + /* If we didn't have a key and a valid index is set, we want to remember it*/ + if (!priv->wep_tx_key_index) { + priv->wep_tx_key_index = index; + } + + unifi_trace(priv, UDBG1, "Tx key Index is %d\n", priv->wep_tx_key_index); + + privacy = 1; + + /* Check if the key is not marked as invalid */ + if ((erq->flags & IW_ENCODE_NOKEY) == 0) { + + unifi_trace(priv, UDBG1, "New %s key (len=%d, index=%d)\n", + (priv->wep_tx_key_index == index) ? "tx" : "", + erq->length, index); + + sme_key.wepTxKey = (priv->wep_tx_key_index == index); + if (priv->wep_tx_key_index == index) { + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE; + } else { + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP; + } + /* Key index is zero based in SME but 1 based in wext */ + sme_key.keyIndex = (index - 1); + sme_key.keyLength = erq->length; + sme_key.authenticator = 0; + memset(sme_key.address.a, 0xFF, ETH_ALEN); + memcpy(sme_key.key, extra, erq->length); + + UF_RTNL_UNLOCK(); + rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD); + UF_RTNL_LOCK(); + if (rc) { + unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc); + return convert_sme_error(rc); + } + + /* Store the key to be reported by the SIOCGIWENCODE handler */ + priv->wep_keys[index - 1].len = erq->length; + memcpy(priv->wep_keys[index - 1].key, extra, erq->length); + } + } else { + /* + * No additional key data, so it must be a request to change the + * active key. + */ + if (index != 0) { + unifi_trace(priv, UDBG1, "Tx key Index is %d\n", index - 1); + + /* Store the index to be reported by the SIOCGIWENCODE handler */ + priv->wep_tx_key_index = index; + + sme_key.wepTxKey = 1; + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE; + + /* Key index is zero based in SME but 1 based in wext */ + sme_key.keyIndex = (index - 1); + sme_key.keyLength = 0; + sme_key.authenticator = 0; + UF_RTNL_UNLOCK(); + rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD); + UF_RTNL_LOCK(); + if (rc) { + unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc); + return convert_sme_error(rc); + } + + /* Turn on encryption */ + privacy = 1; + } + } + + /* Read the flags */ + if (erq->flags & IW_ENCODE_DISABLED) { + /* disable encryption */ + unifi_trace(priv, UDBG1, "disable WEP encryption\n"); + privacy = 0; + + priv->wep_tx_key_index = 0; + + unifi_trace(priv, UDBG1, "IW_ENCODE_DISABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n"); + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + } + + if (erq->flags & IW_ENCODE_RESTRICTED) { + /* Use shared key auth */ + unifi_trace(priv, UDBG1, "IW_ENCODE_RESTRICTED: CSR_WIFI_SME_AUTH_MODE_80211_SHARED\n"); + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_SHARED; + + /* Turn on encryption */ + privacy = 1; + } + if (erq->flags & IW_ENCODE_OPEN) { + unifi_trace(priv, UDBG1, "IW_ENCODE_OPEN: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n"); + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + } + + /* Commit the changes to flags if needed */ + if (privacy != -1) { + priv->connection_config.privacyMode = privacy ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED; + priv->connection_config.encryptionModeMask = privacy ? (CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 | + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 | + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 | + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104) : + CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE; + } + + func_exit_r(rc); + return convert_sme_error(rc); + +} /* unifi_siwencode() */ + + + +static int +unifi_giwencode(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_point *erq = &wrqu->encoding; + + unifi_trace(priv, UDBG2, "unifi_giwencode\n"); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_giwencode: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + if (priv->connection_config.authModeMask == CSR_WIFI_SME_AUTH_MODE_80211_SHARED) { + erq->flags = IW_ENCODE_RESTRICTED; + } + else { + if (priv->connection_config.privacyMode == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED) { + erq->flags = IW_ENCODE_DISABLED; + } else { + erq->flags = IW_ENCODE_OPEN; + } + } + + erq->length = 0; + + if (erq->flags != IW_ENCODE_DISABLED) { + int index = priv->wep_tx_key_index; + + if ((index > 0) && (index <= NUM_WEPKEYS)) { + erq->flags |= (index & IW_ENCODE_INDEX); + erq->length = priv->wep_keys[index - 1].len; + memcpy(extra, priv->wep_keys[index - 1].key, erq->length); + } else { + unifi_notice(priv, "unifi_giwencode: Surprise, do not have a valid key index (%d)\n", + index); + } + } + + return 0; +} /* unifi_giwencode() */ + + +static int +unifi_siwpower(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_param *args = &wrqu->power; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int listen_interval, wake_for_dtim; + int r = 0; + CsrWifiSmePowerConfig powerConfig; + + unifi_trace(priv, UDBG2, "unifi_siwpower\n"); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwpower: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + UF_RTNL_UNLOCK(); + r = sme_mgt_power_config_get(priv, &powerConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwpower: Get unifi_PowerConfigValue failed.\n"); + return r; + } + + listen_interval = -1; + wake_for_dtim = -1; + if (args->disabled) { + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW; + } + else + { + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH; + + switch (args->flags & IW_POWER_TYPE) { + case 0: + /* not specified */ + break; + case IW_POWER_PERIOD: + listen_interval = args->value / 1000; + break; + default: + return -EINVAL; + } + + switch (args->flags & IW_POWER_MODE) { + case 0: + /* not specified */ + break; + case IW_POWER_UNICAST_R: + /* not interested in broadcast packets */ + wake_for_dtim = 0; + break; + case IW_POWER_ALL_R: + /* yes, we are interested in broadcast packets */ + wake_for_dtim = 1; + break; + default: + return -EINVAL; + } + } + + if (listen_interval > 0) { + powerConfig.listenIntervalTu = listen_interval; + unifi_trace(priv, UDBG4, "unifi_siwpower: new Listen Interval = %d.\n", + powerConfig.listenIntervalTu); + } + + if (wake_for_dtim >= 0) { + powerConfig.rxDtims = wake_for_dtim; + } + UF_RTNL_UNLOCK(); + r = sme_mgt_power_config_set(priv, &powerConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_siwpower: Set unifi_PowerConfigValue failed.\n"); + return r; + } + + return 0; +} /* unifi_siwpower() */ + + +static int +unifi_giwpower(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_param *args = &wrqu->power; + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + CsrWifiSmePowerConfig powerConfig; + int r; + + unifi_trace(priv, UDBG2, "unifi_giwpower\n"); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_giwpower: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + args->flags = 0; + UF_RTNL_UNLOCK(); + r = sme_mgt_power_config_get(priv, &powerConfig); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "unifi_giwpower: Get unifi_PowerConfigValue failed.\n"); + return r; + } + + unifi_trace(priv, UDBG4, "unifi_giwpower: mode=%d\n", + powerConfig.powerSaveLevel); + + args->disabled = (powerConfig.powerSaveLevel == CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW); + if (args->disabled) { + args->flags = 0; + return 0; + } + + args->value = powerConfig.listenIntervalTu * 1000; + args->flags |= IW_POWER_PERIOD; + + if (powerConfig.rxDtims) { + args->flags |= IW_POWER_ALL_R; + } else { + args->flags |= IW_POWER_UNICAST_R; + } + + return 0; +} /* unifi_giwpower() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_siwcommit - handler for SIOCSIWCOMMIT + * + * Apply all the parameters that have been set. + * In practice this means: + * - do a scan + * - join a network or start an AdHoc + * - authenticate and associate. + * + * Arguments: + * None. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static int +unifi_siwcommit(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + return 0; +} /* unifi_siwcommit() */ + + + +static int +unifi_siwmlme(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_mlme *mlme = (struct iw_mlme *)extra; + func_enter(); + + unifi_trace(priv, UDBG2, "unifi_siwmlme\n"); + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwmlme: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + case IW_MLME_DISASSOC: + UF_RTNL_UNLOCK(); + sme_mgt_disconnect(priv); + UF_RTNL_LOCK(); + break; + default: + func_exit_r(-EOPNOTSUPP); + return -EOPNOTSUPP; + } + + func_exit(); + return 0; +} /* unifi_siwmlme() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_siwgenie + * unifi_giwgenie + * + * WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM). + * Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE + * + * The host program (e.g. wpa_supplicant) uses this call to set the + * additional IEs to accompany the next (Associate?) request. + * + * Arguments: + * None. + * + * Returns: + * None. + * Notes: + * From wireless.h: + * This ioctl uses struct iw_point and data buffer that includes IE id + * and len fields. More than one IE may be included in the + * request. Setting the generic IE to empty buffer (len=0) removes the + * generic IE from the driver. + * --------------------------------------------------------------------------- + */ +static int +unifi_siwgenie(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int len; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_siwgenie\n"); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwgenie: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + if ( priv->connection_config.mlmeAssociateReqInformationElements) { + kfree( priv->connection_config.mlmeAssociateReqInformationElements); + } + priv->connection_config.mlmeAssociateReqInformationElementsLength = 0; + priv->connection_config.mlmeAssociateReqInformationElements = NULL; + + len = wrqu->data.length; + if (len == 0) { + func_exit(); + return 0; + } + + priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL); + if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) { + func_exit(); + return -ENOMEM; + } + + priv->connection_config.mlmeAssociateReqInformationElementsLength = len; + memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len); + + func_exit(); + return 0; +} /* unifi_siwgenie() */ + + +static int +unifi_giwgenie(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + int len; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_giwgenie\n"); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_giwgenie: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + len = priv->connection_config.mlmeAssociateReqInformationElementsLength; + + if (len == 0) { + wrqu->data.length = 0; + return 0; + } + + if (wrqu->data.length < len) { + return -E2BIG; + } + + wrqu->data.length = len; + memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements, len); + + func_exit(); + return 0; +} /* unifi_giwgenie() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_siwauth + * unifi_giwauth + * + * Handlers for SIOCSIWAUTH, SIOCGIWAUTH + * Set/get various authentication parameters. + * + * Arguments: + * + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static int +_unifi_siwauth(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + CsrWifiSmeAuthModeMask new_auth; + + func_enter(); + unifi_trace(priv, UDBG2, "unifi_siwauth\n"); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwauth: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + /* + * This ioctl is safe to call even when UniFi is powered off. + * wpa_supplicant calls it to test whether we support WPA. + */ + + switch (wrqu->param.flags & IW_AUTH_INDEX) { + + case IW_AUTH_WPA_ENABLED: + unifi_trace(priv, UDBG1, "IW_AUTH_WPA_ENABLED: %d\n", wrqu->param.value); + + if (wrqu->param.value == 0) { + unifi_trace(priv, UDBG5, "IW_AUTH_WPA_ENABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n"); + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + } + break; + + case IW_AUTH_PRIVACY_INVOKED: + unifi_trace(priv, UDBG1, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu->param.value); + + priv->connection_config.privacyMode = wrqu->param.value ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED; + if (wrqu->param.value == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED) + { + priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE; + } + break; + + case IW_AUTH_80211_AUTH_ALG: + /* + IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 + IW_AUTH_ALG_SHARED_KEY 0x00000002 + IW_AUTH_ALG_LEAP 0x00000004 + */ + new_auth = 0; + if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM) { + unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu->param.value); + new_auth |= CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + } + if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY) { + unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu->param.value); + new_auth |= CSR_WIFI_SME_AUTH_MODE_80211_SHARED; + } + if (wrqu->param.value & IW_AUTH_ALG_LEAP) { + /* Initial exchanges using open-system to set EAP */ + unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu->param.value); + new_auth |= CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X; + } + if (new_auth == 0) { + unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n", + wrqu->param.value); + return -EINVAL; + } else { + priv->connection_config.authModeMask = new_auth; + } + break; + + case IW_AUTH_WPA_VERSION: + unifi_trace(priv, UDBG1, "IW_AUTH_WPA_VERSION: %d\n", wrqu->param.value); + priv->ignore_bssid_join = TRUE; + /* + IW_AUTH_WPA_VERSION_DISABLED 0x00000001 + IW_AUTH_WPA_VERSION_WPA 0x00000002 + IW_AUTH_WPA_VERSION_WPA2 0x00000004 + */ + + if (!(wrqu->param.value & IW_AUTH_WPA_VERSION_DISABLED)) { + + priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN; + + if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA) { + unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA, WPA-PSK\n"); + priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK); + } + if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA2) { + unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA2, WPA2-PSK\n"); + priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK); + } + } + break; + + case IW_AUTH_CIPHER_PAIRWISE: + unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu->param.value); + /* + * one of: + IW_AUTH_CIPHER_NONE 0x00000001 + IW_AUTH_CIPHER_WEP40 0x00000002 + IW_AUTH_CIPHER_TKIP 0x00000004 + IW_AUTH_CIPHER_CCMP 0x00000008 + IW_AUTH_CIPHER_WEP104 0x00000010 + */ + + priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE; + + if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) { + priv->connection_config.encryptionModeMask |= + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40; + } + if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) { + priv->connection_config.encryptionModeMask |= + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104; + } + if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) { + priv->connection_config.encryptionModeMask |= + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP; + } + if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) { + priv->connection_config.encryptionModeMask |= + CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP; + } + + break; + + case IW_AUTH_CIPHER_GROUP: + unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu->param.value); + /* + * Use the WPA version and the group cipher suite to set the permitted + * group key in the MIB. f/w uses this value to validate WPA and RSN IEs + * in the probe responses from the desired BSS(ID) + */ + + priv->connection_config.encryptionModeMask &= ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 | + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104 | + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP | + CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP); + if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) { + priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40; + } + if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) { + priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104; + } + if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) { + priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP; + } + if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) { + priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP; + } + + break; + + case IW_AUTH_KEY_MGMT: + unifi_trace(priv, UDBG1, "IW_AUTH_KEY_MGMT: %d\n", wrqu->param.value); + /* + IW_AUTH_KEY_MGMT_802_1X 1 + IW_AUTH_KEY_MGMT_PSK 2 + */ + if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK)) { + /* Check for explicitly set mode. */ + if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) { + priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK; + } + if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) { + priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA; + } + unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA: %d\n", + priv->connection_config.authModeMask); + } + if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK)) { + /* Check for explicitly set mode. */ + if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) { + priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK; + } + if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) { + priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2; + } + unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA2: %d\n", + priv->connection_config.authModeMask); + } + + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + /* + * Set to true at the start of the 60 second backup-off period + * following 2 MichaelMIC failures within 60s. + */ + unifi_trace(priv, UDBG1, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu->param.value); + break; + + case IW_AUTH_DROP_UNENCRYPTED: + /* + * Set to true on init. + * Set to false just before associate if encryption will not be + * required. + * + * Note this is not the same as the 802.1X controlled port + */ + unifi_trace(priv, UDBG1, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu->param.value); + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + /* + * This is set by wpa_supplicant to allow unencrypted EAPOL messages + * even if pairwise keys are set when not using WPA. IEEE 802.1X + * specifies that these frames are not encrypted, but WPA encrypts + * them when pairwise keys are in use. + * I think the UniFi f/w handles this decision for us. + */ + unifi_trace(priv, UDBG1, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu->param.value); + break; + + case IW_AUTH_ROAMING_CONTROL: + unifi_trace(priv, UDBG1, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu->param.value); + break; + + default: + unifi_trace(priv, UDBG1, "Unsupported auth param %d to 0x%X\n", + wrqu->param.flags & IW_AUTH_INDEX, + wrqu->param.value); + return -EOPNOTSUPP; + } + + unifi_trace(priv, UDBG2, "authModeMask = %d", priv->connection_config.authModeMask); + func_exit(); + + return 0; +} /* _unifi_siwauth() */ + + +static int +unifi_siwauth(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int err = 0; + + UF_RTNL_UNLOCK(); + err = _unifi_siwauth(dev, info, wrqu, extra); + UF_RTNL_LOCK(); + + return err; +} /* unifi_siwauth() */ + + +static int +unifi_giwauth(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + unifi_trace(NULL, UDBG2, "unifi_giwauth\n"); + return -EOPNOTSUPP; +} /* unifi_giwauth() */ + +/* + * --------------------------------------------------------------------------- + * unifi_siwencodeext + * unifi_giwencodeext + * + * Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get + * encoding token & mode + * + * Arguments: + * None. + * + * Returns: + * None. + * + * Notes: + * For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag. + * This flag means "use this key to encode transmissions"; we just + * assume only one key will be set and that is the one to use. + * --------------------------------------------------------------------------- + */ +static int +_unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int r = 0; + unsigned char *keydata; + unsigned char tkip_key[32]; + int keyid; + unsigned char *a = (unsigned char *)ext->addr.sa_data; + CsrWifiSmeKey sme_key; + CsrWifiSmeKeyType key_type; + + func_enter(); + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwencodeext: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + unifi_trace(priv, UDBG1, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, len=%d, index=%d,\n", + wrqu->encoding.flags, ext->alg, ext->ext_flags, + ext->key_len, (wrqu->encoding.flags & IW_ENCODE_INDEX)); + unifi_trace(priv, UDBG3, " addr=%02X:%02X:%02X:%02X:%02X:%02X\n", + a[0], a[1], a[2], a[3], a[4], a[5]); + + if ((ext->key_len == 0) && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { + /* This means use a different key (given by key_idx) for Tx. */ + /* NYI */ + unifi_trace(priv, UDBG1, KERN_ERR "unifi_siwencodeext: NYI should change tx key id here!!\n"); + return -ENOTSUPP; + } + + memset(&sme_key, 0, sizeof(sme_key)); + + keydata = (unsigned char *)(ext + 1); + keyid = (wrqu->encoding.flags & IW_ENCODE_INDEX); + + /* + * Check for request to delete keys for an address. + */ + /* Pick out request for no privacy. */ + if (ext->alg == IW_ENCODE_ALG_NONE) { + + unifi_trace(priv, UDBG1, "Deleting %s key %d\n", + (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? "GROUP" : "PAIRWISE", + keyid); + + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP; + } else { + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE; + } + sme_key.keyIndex = (keyid - 1); + sme_key.keyLength = 0; + sme_key.authenticator = 0; + memcpy(sme_key.address.a, a, ETH_ALEN); + UF_RTNL_UNLOCK(); + r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_REMOVE); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "Delete key request was rejected with result %d\n", r); + return convert_sme_error(r); + } + + return 0; + } + + /* + * Request is to set a key, not delete + */ + + /* Pick out WEP and use set_wep_key(). */ + if (ext->alg == IW_ENCODE_ALG_WEP) { + /* WEP-40, WEP-104 */ + + /* Check for valid key length */ + if (!((ext->key_len == 5) || (ext->key_len == 13))) { + unifi_trace(priv, UDBG1, KERN_ERR "Invalid length for WEP key: %d\n", ext->key_len); + return -EINVAL; + } + + unifi_trace(priv, UDBG1, "Setting WEP key %d tx:%d\n", + keyid, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY); + + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + sme_key.wepTxKey = TRUE; + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE; + } else { + sme_key.wepTxKey = FALSE; + sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP; + } + sme_key.keyIndex = (keyid - 1); + sme_key.keyLength = ext->key_len; + sme_key.authenticator = 0; + memset(sme_key.address.a, 0xFF, ETH_ALEN); + memcpy(sme_key.key, keydata, ext->key_len); + UF_RTNL_UNLOCK(); + r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "siwencodeext: Set key failed (%d)", r); + return convert_sme_error(r); + } + + return 0; + } + + /* + * + * If we reach here, we are dealing with a WPA/WPA2 key + * + */ + if (ext->key_len > 32) { + return -EINVAL; + } + + /* + * TKIP keys from wpa_supplicant need swapping. + * What about other supplicants (when they come along)? + */ + if ((ext->alg == IW_ENCODE_ALG_TKIP) && (ext->key_len == 32)) { + memcpy(tkip_key, keydata, 16); + memcpy(tkip_key + 16, keydata + 24, 8); + memcpy(tkip_key + 24, keydata + 16, 8); + keydata = tkip_key; + } + + key_type = (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? + CSR_WIFI_SME_KEY_TYPE_GROUP : /* Group Key */ + CSR_WIFI_SME_KEY_TYPE_PAIRWISE; /* Pairwise Key */ + + sme_key.keyType = key_type; + sme_key.keyIndex = (keyid - 1); + sme_key.keyLength = ext->key_len; + sme_key.authenticator = 0; + memcpy(sme_key.address.a, ext->addr.sa_data, ETH_ALEN); + if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + + unifi_trace(priv, UDBG5, "RSC first 6 bytes = %02X:%02X:%02X:%02X:%02X:%02X\n", + ext->rx_seq[0], ext->rx_seq[1], ext->rx_seq[2], ext->rx_seq[3], ext->rx_seq[4], ext->rx_seq[5]); + + /* memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8); */ + sme_key.keyRsc[0] = ext->rx_seq[1] << 8 | ext->rx_seq[0]; + sme_key.keyRsc[1] = ext->rx_seq[3] << 8 | ext->rx_seq[2]; + sme_key.keyRsc[2] = ext->rx_seq[5] << 8 | ext->rx_seq[4]; + sme_key.keyRsc[3] = ext->rx_seq[7] << 8 | ext->rx_seq[6]; + + } + + memcpy(sme_key.key, keydata, ext->key_len); + UF_RTNL_UNLOCK(); + r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "SETKEYS request was rejected with result %d\n", r); + return convert_sme_error(r); + } + + func_exit(); + return r; +} /* _unifi_siwencodeext() */ + + +static int +unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int err = 0; + + err = _unifi_siwencodeext(dev, info, wrqu, extra); + + return err; +} /* unifi_siwencodeext() */ + + +static int +unifi_giwencodeext(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + return -EOPNOTSUPP; +} /* unifi_giwencodeext() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_siwpmksa + * + * SIOCSIWPMKSA - PMKSA cache operation + * The caller passes a pmksa structure: + * - cmd one of ADD, REMOVE, FLUSH + * - bssid MAC address + * - pmkid ID string (16 bytes) + * + * Arguments: + * None. + * + * Returns: + * None. + * + * Notes: + * This is not needed since we provide a siwgenie method. + * --------------------------------------------------------------------------- + */ +#define UNIFI_PMKID_KEY_SIZE 16 +static int +unifi_siwpmksa(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; + CsrResult r = 0; + CsrWifiSmePmkidList pmkid_list; + CsrWifiSmePmkid pmkid; + CsrWifiSmeListAction action; + + CHECK_INITED(priv); + + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + unifi_error(priv, "unifi_siwpmksa: not permitted in Mode %d\n", + interfacePriv->interfaceMode); + return -EPERM; + } + + + unifi_trace(priv, UDBG1, "SIWPMKSA: cmd %d, %02x:%02x:%02x:%02x:%02x:%02x\n", + pmksa->cmd, + pmksa->bssid.sa_data[0], + pmksa->bssid.sa_data[1], + pmksa->bssid.sa_data[2], + pmksa->bssid.sa_data[3], + pmksa->bssid.sa_data[4], + pmksa->bssid.sa_data[5]); + + pmkid_list.pmkids = NULL; + switch (pmksa->cmd) { + case IW_PMKSA_ADD: + pmkid_list.pmkids = &pmkid; + action = CSR_WIFI_SME_LIST_ACTION_ADD; + pmkid_list.pmkidsCount = 1; + memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN); + memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE); + break; + case IW_PMKSA_REMOVE: + pmkid_list.pmkids = &pmkid; + action = CSR_WIFI_SME_LIST_ACTION_REMOVE; + pmkid_list.pmkidsCount = 1; + memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN); + memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE); + break; + case IW_PMKSA_FLUSH: + /* Replace current PMKID's with an empty list */ + pmkid_list.pmkidsCount = 0; + action = CSR_WIFI_SME_LIST_ACTION_FLUSH; + break; + default: + unifi_notice(priv, "SIWPMKSA: Unknown command (0x%x)\n", pmksa->cmd); + return -EINVAL; + } + + /* Set the Value the pmkid's will have 1 added OR 1 removed OR be cleared at this point */ + UF_RTNL_UNLOCK(); + r = sme_mgt_pmkid(priv, action, &pmkid_list); + UF_RTNL_LOCK(); + if (r) { + unifi_error(priv, "SIWPMKSA: Set PMKID's Failed.\n"); + } + + return r; + +} /* unifi_siwpmksa() */ + + +/* + * --------------------------------------------------------------------------- + * unifi_get_wireless_stats + * + * get_wireless_stats method for Linux wireless extensions. + * + * Arguments: + * dev Pointer to associated netdevice. + * + * Returns: + * Pointer to iw_statistics struct. + * --------------------------------------------------------------------------- + */ +struct iw_statistics * +unifi_get_wireless_stats(struct net_device *dev) +{ + netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); + unifi_priv_t *priv = interfacePriv->privPtr; + + if (priv->init_progress != UNIFI_INIT_COMPLETED) { + return NULL; + } + + return &priv->wext_wireless_stats; +} /* unifi_get_wireless_stats() */ + + +/* + * Structures to export the Wireless Handlers + */ + +static const struct iw_priv_args unifi_private_args[] = { + /*{ cmd, set_args, get_args, name } */ + { SIOCIWS80211POWERSAVEPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_NONE, "iwprivs80211ps" }, + { SIOCIWG80211POWERSAVEPRIV, IW_PRIV_TYPE_NONE, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IWPRIV_POWER_SAVE_MAX_STRING, "iwprivg80211ps" }, + { SIOCIWS80211RELOADDEFAULTSPRIV, IW_PRIV_TYPE_NONE, + IW_PRIV_TYPE_NONE, "iwprivsdefs" }, + { SIOCIWSSMEDEBUGPRIV, IW_PRIV_TYPE_CHAR | IWPRIV_SME_DEBUG_MAX_STRING, IW_PRIV_TYPE_NONE, "iwprivssmedebug" }, +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + { SIOCIWSCONFWAPIPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_NONE, "iwprivsconfwapi" }, + { SIOCIWSWAPIKEYPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(unifiio_wapi_key_t), + IW_PRIV_TYPE_NONE, "iwprivswpikey" }, +#endif +#ifdef CSR_SUPPORT_WEXT_AP + { SIOCIWSAPCFGPRIV, IW_PRIV_TYPE_CHAR | 256, IW_PRIV_TYPE_NONE, "AP_SET_CFG" }, + { SIOCIWSAPSTARTPRIV, 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING,"AP_BSS_START" }, + { SIOCIWSAPSTOPPRIV, IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, + IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "AP_BSS_STOP" }, +#ifdef ANDROID_BUILD + { SIOCIWSFWRELOADPRIV, IW_PRIV_TYPE_CHAR |256, + IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "WL_FW_RELOAD" }, + { SIOCIWSSTACKSTART, 0, + IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING, "START" }, + { SIOCIWSSTACKSTOP, 0, + IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING, "STOP" }, +#endif /* ANDROID_BUILD */ +#endif /* CSR_SUPPORT_WEXT_AP */ +}; + +static const iw_handler unifi_handler[] = +{ + (iw_handler) unifi_siwcommit, /* SIOCSIWCOMMIT */ + (iw_handler) unifi_giwname, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) unifi_siwfreq, /* SIOCSIWFREQ */ + (iw_handler) unifi_giwfreq, /* SIOCGIWFREQ */ + (iw_handler) unifi_siwmode, /* SIOCSIWMODE */ + (iw_handler) unifi_giwmode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) unifi_giwrange, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + (iw_handler) NULL, /* SIOCSIWSPY */ + (iw_handler) NULL, /* SIOCGIWSPY */ + (iw_handler) NULL, /* SIOCSIWTHRSPY */ + (iw_handler) NULL, /* SIOCGIWTHRSPY */ + (iw_handler) unifi_siwap, /* SIOCSIWAP */ + (iw_handler) unifi_giwap, /* SIOCGIWAP */ +#if WIRELESS_EXT > 17 + /* WPA : IEEE 802.11 MLME requests */ + unifi_siwmlme, /* SIOCSIWMLME, request MLME operation */ +#else + (iw_handler) NULL, /* -- hole -- */ +#endif + (iw_handler) NULL, /* SIOCGIWAPLIST */ + (iw_handler) unifi_siwscan, /* SIOCSIWSCAN */ + (iw_handler) unifi_giwscan, /* SIOCGIWSCAN */ + (iw_handler) unifi_siwessid, /* SIOCSIWESSID */ + (iw_handler) unifi_giwessid, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) NULL, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + unifi_siwrate, /* SIOCSIWRATE */ + unifi_giwrate, /* SIOCGIWRATE */ + unifi_siwrts, /* SIOCSIWRTS */ + unifi_giwrts, /* SIOCGIWRTS */ + unifi_siwfrag, /* SIOCSIWFRAG */ + unifi_giwfrag, /* SIOCGIWFRAG */ + (iw_handler) NULL, /* SIOCSIWTXPOW */ + (iw_handler) NULL, /* SIOCGIWTXPOW */ + (iw_handler) NULL, /* SIOCSIWRETRY */ + (iw_handler) NULL, /* SIOCGIWRETRY */ + unifi_siwencode, /* SIOCSIWENCODE */ + unifi_giwencode, /* SIOCGIWENCODE */ + unifi_siwpower, /* SIOCSIWPOWER */ + unifi_giwpower, /* SIOCGIWPOWER */ +#if WIRELESS_EXT > 17 + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + + /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */ + unifi_siwgenie, /* SIOCSIWGENIE */ /* set generic IE */ + unifi_giwgenie, /* SIOCGIWGENIE */ /* get generic IE */ + + /* WPA : Authentication mode parameters */ + unifi_siwauth, /* SIOCSIWAUTH */ /* set authentication mode params */ + unifi_giwauth, /* SIOCGIWAUTH */ /* get authentication mode params */ + + /* WPA : Extended version of encoding configuration */ + unifi_siwencodeext, /* SIOCSIWENCODEEXT */ /* set encoding token & mode */ + unifi_giwencodeext, /* SIOCGIWENCODEEXT */ /* get encoding token & mode */ + + /* WPA2 : PMKSA cache management */ + unifi_siwpmksa, /* SIOCSIWPMKSA */ /* PMKSA cache operation */ + (iw_handler) NULL, /* -- hole -- */ +#endif /* WIRELESS_EXT > 17 */ +}; + + +static const iw_handler unifi_private_handler[] = +{ + iwprivs80211ps, /* SIOCIWFIRSTPRIV */ + iwprivg80211ps, /* SIOCIWFIRSTPRIV + 1 */ + iwprivsdefs, /* SIOCIWFIRSTPRIV + 2 */ + (iw_handler) NULL, +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + iwprivsconfwapi, /* SIOCIWFIRSTPRIV + 4 */ + (iw_handler) NULL, /* SIOCIWFIRSTPRIV + 5 */ + iwprivswpikey, /* SIOCIWFIRSTPRIV + 6 */ +#else + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, +#endif + (iw_handler) NULL, + iwprivssmedebug, /* SIOCIWFIRSTPRIV + 8 */ +#ifdef CSR_SUPPORT_WEXT_AP + (iw_handler) NULL, + iwprivsapconfig, + (iw_handler) NULL, + iwprivsapstart, + (iw_handler) NULL, + iwprivsapstop, + (iw_handler) NULL, +#ifdef ANDROID_BUILD + iwprivsapfwreload, + (iw_handler) NULL, + iwprivsstackstart, + (iw_handler) NULL, + iwprivsstackstop, +#else + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, +#endif /* ANDROID_BUILD */ +#else + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, + (iw_handler) NULL, +#endif /* CSR_SUPPORT_WEXT_AP */ +}; + +struct iw_handler_def unifi_iw_handler_def = +{ + .num_standard = sizeof(unifi_handler) / sizeof(iw_handler), + .num_private = sizeof(unifi_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(unifi_private_args) / sizeof(struct iw_priv_args), + .standard = (iw_handler *) unifi_handler, + .private = (iw_handler *) unifi_private_handler, + .private_args = (struct iw_priv_args *) unifi_private_args, +#if IW_HANDLER_VERSION >= 6 + .get_wireless_stats = unifi_get_wireless_stats, +#endif +}; + + diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c new file mode 100644 index 000000000000..ae14f2354362 --- /dev/null +++ b/drivers/staging/csr/ul_int.c @@ -0,0 +1,552 @@ +/* + * *************************************************************************** + * FILE: ul_int.c + * + * PURPOSE: + * Manage list of client applications using UniFi. + * + * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "unifi_priv.h" +#include "unifiio.h" +#include "unifi_os.h" + +static void free_bulkdata_buffers(unifi_priv_t *priv, bulk_data_param_t *bulkdata); +static void reset_driver_status(unifi_priv_t *priv); + +/* + * --------------------------------------------------------------------------- + * ul_init_clients + * + * Initialise the clients array to empty. + * + * Arguments: + * priv Pointer to device private context struct + * + * Returns: + * None. + * + * Notes: + * This function needs to be called before priv is stored in + * Unifi_instances[]. + * --------------------------------------------------------------------------- + */ +void +ul_init_clients(unifi_priv_t *priv) +{ + int id; + ul_client_t *ul_clients; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) + sema_init(&priv->udi_logging_mutex, 1); +#else + init_MUTEX(&priv->udi_logging_mutex); +#endif + priv->logging_client = NULL; + + ul_clients = priv->ul_clients; + + for (id = 0; id < MAX_UDI_CLIENTS; id++) { + memset(&ul_clients[id], 0, sizeof(ul_client_t)); + + ul_clients[id].client_id = id; + ul_clients[id].sender_id = UDI_SENDER_ID_BASE + (id << UDI_SENDER_ID_SHIFT); + ul_clients[id].instance = -1; + ul_clients[id].event_hook = NULL; + + INIT_LIST_HEAD(&ul_clients[id].udi_log); + init_waitqueue_head(&ul_clients[id].udi_wq); + sema_init(&ul_clients[id].udi_sem, 1); + + ul_clients[id].wake_up_wq_id = 0; + ul_clients[id].seq_no = 0; + ul_clients[id].wake_seq_no = 0; + ul_clients[id].snap_filter.count = 0; + } +} /* ul_init_clients() */ + + +/* + * --------------------------------------------------------------------------- + * ul_register_client + * + * This function registers a new ul client. + * + * Arguments: + * priv Pointer to device private context struct + * configuration Special configuration for the client. + * udi_event_clbk Callback for receiving event from unifi. + * + * Returns: + * 0 if a new clients is registered, -1 otherwise. + * --------------------------------------------------------------------------- + */ +ul_client_t * +ul_register_client(unifi_priv_t *priv, unsigned int configuration, + udi_event_t udi_event_clbk) +{ + unsigned char id, ref; + ul_client_t *ul_clients; + + ul_clients = priv->ul_clients; + + /* check for an unused entry */ + for (id = 0; id < MAX_UDI_CLIENTS; id++) { + if (ul_clients[id].udi_enabled == 0) { + ul_clients[id].instance = priv->instance; + ul_clients[id].udi_enabled = 1; + ul_clients[id].configuration = configuration; + + /* Allocate memory for the reply signal.. */ + ul_clients[id].reply_signal = (CSR_SIGNAL*) CsrPmemAlloc(sizeof(CSR_SIGNAL)); + if (ul_clients[id].reply_signal == NULL) { + unifi_error(priv, "Failed to allocate reply signal for client.\n"); + return NULL; + } + /* .. and the bulk data of the reply signal. */ + for (ref = 0; ref < UNIFI_MAX_DATA_REFERENCES; ref ++) { + ul_clients[id].reply_bulkdata[ref] = + (bulk_data_t*) CsrPmemAlloc(sizeof(bulk_data_t)); + /* If allocation fails, free allocated memory. */ + if (ul_clients[id].reply_bulkdata[ref] == NULL) { + for (; ref > 0; ref --) { + CsrPmemFree(ul_clients[id].reply_bulkdata[ref - 1]); + } + CsrPmemFree(ul_clients[id].reply_signal); + unifi_error(priv, "Failed to allocate bulk data buffers for client.\n"); + return NULL; + } + } + + /* Set the event callback. */ + ul_clients[id].event_hook = udi_event_clbk; + + unifi_trace(priv, UDBG2, "UDI %d (0x%x) registered. configuration = 0x%x\n", + id, &ul_clients[id], configuration); + return &ul_clients[id]; + } + } + return NULL; +} /* ul_register_client() */ + + +/* + * --------------------------------------------------------------------------- + * ul_deregister_client + * + * This function deregisters a blocking UDI client. + * + * Arguments: + * client Pointer to the client we deregister. + * + * Returns: + * 0 if a new clients is deregistered. + * --------------------------------------------------------------------------- + */ +int +ul_deregister_client(ul_client_t *ul_client) +{ + struct list_head *pos, *n; + udi_log_t *logptr; + unifi_priv_t *priv = uf_find_instance(ul_client->instance); + int ref; + + ul_client->instance = -1; + ul_client->event_hook = NULL; + ul_client->udi_enabled = 0; + unifi_trace(priv, UDBG5, "UDI (0x%x) deregistered.\n", ul_client); + + /* Free memory allocated for the reply signal and its bulk data. */ + CsrPmemFree(ul_client->reply_signal); + for (ref = 0; ref < UNIFI_MAX_DATA_REFERENCES; ref ++) { + CsrPmemFree(ul_client->reply_bulkdata[ref]); + } + + if (ul_client->snap_filter.count) { + ul_client->snap_filter.count = 0; + CsrPmemFree(ul_client->snap_filter.protocols); + } + + /* Free anything pending on the udi_log list */ + down(&ul_client->udi_sem); + list_for_each_safe(pos, n, &ul_client->udi_log) + { + logptr = list_entry(pos, udi_log_t, q); + list_del(pos); + kfree(logptr); + } + up(&ul_client->udi_sem); + + return 0; +} /* ul_deregister_client() */ + + + +/* + * --------------------------------------------------------------------------- + * logging_handler + * + * This function is registered with the driver core. + * It is called every time a UniFi HIP Signal is sent. It iterates over + * the list of processes interested in receiving log events and + * delivers the events to them. + * + * Arguments: + * ospriv Pointer to driver's private data. + * sigdata Pointer to the packed signal buffer. + * signal_len Length of the packed signal. + * bulkdata Pointer to the signal's bulk data. + * dir Direction of the signal + * 0 = from-host + * 1 = to-host + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +logging_handler(void *ospriv, + CsrUint8 *sigdata, CsrUint32 signal_len, + const bulk_data_param_t *bulkdata, + enum udi_log_direction direction) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + ul_client_t *client; + int dir; + + dir = (direction == UDI_LOG_FROM_HOST) ? UDI_FROM_HOST : UDI_TO_HOST; + + down(&priv->udi_logging_mutex); + client = priv->logging_client; + if (client != NULL) { + client->event_hook(client, sigdata, signal_len, + bulkdata, dir); + } + up(&priv->udi_logging_mutex); + +} /* logging_handler() */ + + + +/* + * --------------------------------------------------------------------------- + * ul_log_config_ind + * + * This function uses the client's register callback + * to indicate configuration information e.g core errors. + * + * Arguments: + * priv Pointer to driver's private data. + * conf_param Pointer to the configuration data. + * len Length of the configuration data. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len) +{ +#ifdef CSR_SUPPORT_SME + if (priv->smepriv == NULL) + { + return; + } + if ((CONFIG_IND_ERROR == (*conf_param)) && (priv->wifi_on_state == wifi_on_in_progress)) { + unifi_notice(priv, "ul_log_config_ind: wifi on in progress, suppress error\n"); + } else { + /* wifi_off_ind (error or exit) */ + CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, (CsrWifiRouterCtrlControlIndication)(*conf_param)); + } + +#else + bulk_data_param_t bulkdata; + + /* + * If someone killed unifi_managed before the driver was unloaded + * the g_drvpriv pointer is going to be NULL. In this case it is + * safe to assume that there is no client to get the indication. + */ + if (!priv) { + unifi_notice(NULL, "uf_sme_event_ind: NULL priv\n"); + return; + } + + /* Create a null bulkdata structure. */ + bulkdata.d[0].data_length = 0; + bulkdata.d[1].data_length = 0; + + sme_native_log_event(priv->sme_cli, conf_param, sizeof(CsrUint8), + &bulkdata, UDI_CONFIG_IND); + +#endif /* CSR_SUPPORT_SME */ + +} /* ul_log_config_ind */ + + +/* + * --------------------------------------------------------------------------- + * free_bulkdata_buffers + * + * Free the bulkdata buffers e.g. after a failed unifi_send_signal(). + * + * Arguments: + * priv Pointer to device private struct + * bulkdata Pointer to bulkdata parameter table + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +free_bulkdata_buffers(unifi_priv_t *priv, bulk_data_param_t *bulkdata) +{ + int i; + + if (bulkdata) { + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (bulk_data_desc_t *)(&bulkdata->d[i])); + /* data_length is now 0 */ + } + } + } + +} /* free_bulkdata_buffers */ + +static int +_align_bulk_data_buffers(unifi_priv_t *priv, CsrUint8 *signal, + bulk_data_param_t *bulkdata) +{ + unsigned int i; + + if ((bulkdata == NULL) || (CSR_WIFI_ALIGN_BYTES == 0)) { + return 0; + } + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) + { + struct sk_buff *skb; + /* + * The following complex casting is in place in order to eliminate 64-bit compilation warning + * "cast to/from pointer from/to integer of different size" + */ + CsrUint32 align_offset = (CsrUint32)(long)(bulkdata->d[i].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1); + if (align_offset) + { + skb = (struct sk_buff*)bulkdata->d[i].os_net_buf_ptr; + if (skb == NULL) { + unifi_warning(priv, + "_align_bulk_data_buffers: Align offset found (%d) but skb is NULL!\n", + align_offset); + return -EINVAL; + } + if (bulkdata->d[i].data_length == 0) { + unifi_warning(priv, + "_align_bulk_data_buffers: Align offset found (%d) but length is zero\n", + align_offset); + return CSR_RESULT_SUCCESS; + } + unifi_trace(priv, UDBG5, + "Align f-h buffer (0x%p) by %d bytes (skb->data: 0x%p)\n", + bulkdata->d[i].os_data_ptr, align_offset, skb->data); + + + /* Check if there is enough headroom... */ + if (unlikely(skb_headroom(skb) < align_offset)) + { + struct sk_buff *tmp = skb; + + unifi_trace(priv, UDBG5, "Headroom not enough - realloc it\n"); + skb = skb_realloc_headroom(skb, align_offset); + if (skb == NULL) { + unifi_error(priv, + "_align_bulk_data_buffers: skb_realloc_headroom failed - signal is dropped\n"); + return -EFAULT; + } + /* Free the old bulk data only if allocation succeeds */ + kfree_skb(tmp); + /* Bulkdata needs to point to the new skb */ + bulkdata->d[i].os_net_buf_ptr = (const unsigned char*)skb; + bulkdata->d[i].os_data_ptr = (const void*)skb->data; + } + /* ... before pushing the data to the right alignment offset */ + skb_push(skb, align_offset); + + } + /* The direction bit is zero for the from-host */ + signal[SIZEOF_SIGNAL_HEADER + (i * SIZEOF_DATAREF) + 1] = align_offset; + + } + return 0; +} /* _align_bulk_data_buffers() */ + + +/* + * --------------------------------------------------------------------------- + * ul_send_signal_unpacked + * + * This function sends a host formatted signal to unifi. + * + * Arguments: + * priv Pointer to driver's private data. + * sigptr Pointer to the signal. + * bulkdata Pointer to the signal's bulk data. + * + * Returns: + * O on success, error code otherwise. + * + * Notes: + * The signals have to be sent in the format described in the host interface + * specification, i.e wire formatted. Certain clients use the host formatted + * structures. The write_pack() transforms the host formatted signal + * into the wired formatted signal. The code is in the core, since the signals + * are defined therefore binded to the host interface specification. + * --------------------------------------------------------------------------- + */ +int +ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr, + bulk_data_param_t *bulkdata) +{ + CsrUint8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE]; + CsrUint16 packed_siglen; + CsrResult csrResult; + unsigned long lock_flags; + int r; +#ifdef CSR_SUPPORT_SME + netInterface_priv_t *interfacePriv = priv->interfacePriv[0]; + CsrUint32 alignOffset = 0; +#endif + + + csrResult = write_pack(sigptr, sigbuf, &packed_siglen); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n"); + return CsrHipResultToStatus(csrResult); + } +#ifdef CSR_SUPPORT_SME + if (bulkdata != NULL){ + alignOffset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1); + + } +#endif + r = _align_bulk_data_buffers(priv, sigbuf, (bulk_data_param_t*)bulkdata); + if (r) { + return r; + } + + spin_lock_irqsave(&priv->send_signal_lock, lock_flags); + csrResult = unifi_send_signal(priv->card, sigbuf, packed_siglen, bulkdata); + if (csrResult != CSR_RESULT_SUCCESS) { + /* free_bulkdata_buffers(priv, (bulk_data_param_t *)bulkdata); */ + spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); + return CsrHipResultToStatus(csrResult); + } +#ifdef CSR_SUPPORT_SME + if (sigptr->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID) { + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + + uf_store_directed_ma_packet_referenece(priv, bulkdata, sigptr,alignOffset); + + } + } +#endif + + spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); + + return 0; +} /* ul_send_signal_unpacked() */ + + +/* + * --------------------------------------------------------------------------- + * reset_driver_status + * + * This function is called from ul_send_signal_raw() when it detects + * that the SME has sent a MLME-RESET request. + * + * Arguments: + * priv Pointer to device private struct + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +static void +reset_driver_status(unifi_priv_t *priv) +{ + priv->sta_wmm_capabilities = 0; +#ifdef CSR_NATIVE_LINUX +#ifdef CSR_SUPPORT_WEXT + priv->wext_conf.flag_associated = 0; + priv->wext_conf.block_controlled_port = CSR_WIFI_ROUTER_PORT_ACTION_8021X_PORT_OPEN; + priv->wext_conf.bss_wmm_capabilities = 0; + priv->wext_conf.disable_join_on_ssid_set = 0; +#endif +#endif +} /* reset_driver_status() */ + + +/* + * --------------------------------------------------------------------------- + * ul_send_signal_raw + * + * This function sends a wire formatted data signal to unifi. + * + * Arguments: + * priv Pointer to driver's private data. + * sigptr Pointer to the signal. + * siglen Length of the signal. + * bulkdata Pointer to the signal's bulk data. + * + * Returns: + * O on success, error code otherwise. + * --------------------------------------------------------------------------- + */ +int +ul_send_signal_raw(unifi_priv_t *priv, unsigned char *sigptr, int siglen, + bulk_data_param_t *bulkdata) +{ + CsrResult csrResult; + unsigned long lock_flags; + int r; + + /* + * Make sure that the signal is updated with the bulk data + * alignment for DMA. + */ + r = _align_bulk_data_buffers(priv, (CsrUint8*)sigptr, bulkdata); + if (r) { + return r; + } + + spin_lock_irqsave(&priv->send_signal_lock, lock_flags); + csrResult = unifi_send_signal(priv->card, sigptr, siglen, bulkdata); + if (csrResult != CSR_RESULT_SUCCESS) { + free_bulkdata_buffers(priv, bulkdata); + spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); + return CsrHipResultToStatus(csrResult); + } + spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); + + /* + * Since this is use by unicli, if we get an MLME reset request + * we need to initialize a few status parameters + * that the driver uses to make decisions. + */ + if (GET_SIGNAL_ID(sigptr) == CSR_MLME_RESET_REQUEST_ID) { + reset_driver_status(priv); + } + + return 0; +} /* ul_send_signal_raw() */ + + diff --git a/drivers/staging/csr/unifi_clients.h b/drivers/staging/csr/unifi_clients.h new file mode 100644 index 000000000000..206b8cffd5b7 --- /dev/null +++ b/drivers/staging/csr/unifi_clients.h @@ -0,0 +1,129 @@ +/* + ***************************************************************************** + * + * FILE : unifi_clients.h + * + * PURPOSE : Private header file for unifi clients. + * + * UDI = UniFi Debug Interface + * + * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + ***************************************************************************** + */ +#ifndef __LINUX_UNIFI_CLIENTS_H__ +#define __LINUX_UNIFI_CLIENTS_H__ 1 + +#include + +#define MAX_UDI_CLIENTS 8 + +/* The start of the range of process ids allocated for ul clients */ +#define UDI_SENDER_ID_BASE 0xC000 +#define UDI_SENDER_ID_SHIFT 8 + + +/* Structure to hold a UDI logged signal */ +typedef struct { + + /* List link structure */ + struct list_head q; + + /* The message that will be passed to the user app */ + udi_msg_t msg; + + /* Signal body and data follow */ + +} udi_log_t; + + + +typedef struct ul_client ul_client_t; + +typedef void (*udi_event_t)(ul_client_t *client, + const u8 *sigdata, int signal_len, + const bulk_data_param_t *bulkdata, + int dir); + +void logging_handler(void *ospriv, + CsrUint8 *sigdata, CsrUint32 signal_len, + const bulk_data_param_t *bulkdata, + enum udi_log_direction direction); + + +/* + * Structure describing a bulk data slot. + * The length field is used to indicate empty/occupied state. + */ +typedef struct _bulk_data +{ + unsigned char ptr[2000]; + unsigned int length; +} bulk_data_t; + + +struct ul_client { + /* Index of this client in the ul_clients array. */ + int client_id; + + /* Index of UniFi device to which this client is attached. */ + int instance; + + /* Flag to say whether this client has been enabled. */ + int udi_enabled; + + /* Value to use in signal->SenderProcessId */ + int sender_id; + + /* Configuration flags, e.g blocking, logging, etc. */ + unsigned int configuration; + + udi_event_t event_hook; + + /* A list to hold signals received from UniFi for reading by read() */ + struct list_head udi_log; + + /* Semaphore to protect the udi_log list */ + struct semaphore udi_sem; + + /* + * Linux waitqueue to support blocking read and poll. + * Logging clients should wait on udi_log. while + * blocking clients should wait on wake_up_wq. + */ + wait_queue_head_t udi_wq; + CSR_SIGNAL* reply_signal; + bulk_data_t* reply_bulkdata[UNIFI_MAX_DATA_REFERENCES]; + + CsrUint16 signal_filter[SIG_FILTER_SIZE]; + + + /* ------------------------------------------------------------------- */ + /* Code below here is used by the sme_native configuration only */ + + /* Flag to wake up blocking clients waiting on udi_wq. */ + int wake_up_wq_id; + + /* + * A 0x00 - 0x0F mask to apply in signal->SenderProcessId. + * Every time we do a blocking mlme request we increase this value. + * The mlme_wait_for_reply() will wait for this sequence number. + * Only the MLME blocking functions update this field. + */ + unsigned char seq_no; + + /* + * A 0x00 - 0x0F counter, containing the sequence number of + * the signal that this client has last received. + * Only the MLME blocking functions update this field. + */ + unsigned char wake_seq_no; + + unifiio_snap_filter_t snap_filter; +}; /* struct ul_client */ + + +#endif /* __LINUX_UNIFI_CLIENTS_H__ */ diff --git a/drivers/staging/csr/unifi_config.h b/drivers/staging/csr/unifi_config.h new file mode 100644 index 000000000000..fe119707844a --- /dev/null +++ b/drivers/staging/csr/unifi_config.h @@ -0,0 +1,34 @@ +/* + * --------------------------------------------------------------------------- + * + * FILE: unifi_config.h + * + * PURPOSE: + * This header file provides parameters that configure the operation + * of the driver. + * + * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#ifndef __UNIFI_CONFIG_H__ +#define __UNIFI_CONFIG_H__ 1 + +/* + * Override for the SDIO function block size on this host. When byte mode CMD53s + * are not used/supported by the SD host controller, transfers are padded up to + * the next block boundary. The 512-byte default on UF6xxx wastes too much space + * on the chip, so the block size is reduced to support this configuration. + */ +#define CSR_WIFI_HIP_SDIO_BLOCK_SIZE 64 + +/* Define the number of mini-coredump buffers to allocate at startup. These are + * used to record chip status for the last n unexpected resets. + */ +#define CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS 5 + + +#endif /* __UNIFI_CONFIG_H__ */ diff --git a/drivers/staging/csr/unifi_dbg.c b/drivers/staging/csr/unifi_dbg.c new file mode 100644 index 000000000000..38d57085a26a --- /dev/null +++ b/drivers/staging/csr/unifi_dbg.c @@ -0,0 +1,110 @@ +/* + * *************************************************************************** + * FILE: unifi_dbg.c + * + * PURPOSE: + * Handle debug signals received from UniFi. + * + * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ +#include "unifi_priv.h" + +/* + * --------------------------------------------------------------------------- + * debug_string_indication + * debug_word16_indication + * + * Handlers for debug indications. + * + * Arguments: + * priv Pointer to private context structure. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +debug_string_indication(unifi_priv_t *priv, const unsigned char *extra, unsigned int extralen) +{ + const unsigned int maxlen = sizeof(priv->last_debug_string) - 1; + + if (extralen > maxlen) { + extralen = maxlen; + } + + strncpy(priv->last_debug_string, extra, extralen); + + /* Make sure the string is terminated */ + priv->last_debug_string[extralen] = '\0'; + + unifi_info(priv, "unifi debug: %s\n", priv->last_debug_string); + +} /* debug_string_indication() */ + + + +void +debug_word16_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr) +{ + int i; + + if (priv == NULL) { + unifi_info(priv, "Priv is NULL\n"); + return; + } + + for (i = 0; i < 16; i++) { + priv->last_debug_word16[i] = + sigptr->u.DebugWord16Indication.DebugWords[i]; + } + + if (priv->last_debug_word16[0] == 0xFA11) { + unsigned long ts; + ts = (priv->last_debug_word16[6] << 16) | priv->last_debug_word16[5]; + unifi_info(priv, " %10lu: %s fault %04x, arg %04x (x%d)\n", + ts, + priv->last_debug_word16[3] == 0x8000 ? "MAC" : + priv->last_debug_word16[3] == 0x4000 ? "PHY" : + "???", + priv->last_debug_word16[1], + priv->last_debug_word16[2], + priv->last_debug_word16[4]); + } + else if (priv->last_debug_word16[0] != 0xDBAC) + /* suppress SDL Trace output (note: still available to unicli). */ + { + unifi_info(priv, "unifi debug: %04X %04X %04X %04X %04X %04X %04X %04X\n", + priv->last_debug_word16[0], priv->last_debug_word16[1], + priv->last_debug_word16[2], priv->last_debug_word16[3], + priv->last_debug_word16[4], priv->last_debug_word16[5], + priv->last_debug_word16[6], priv->last_debug_word16[7]); + unifi_info(priv, " %04X %04X %04X %04X %04X %04X %04X %04X\n", + priv->last_debug_word16[8], priv->last_debug_word16[9], + priv->last_debug_word16[10], priv->last_debug_word16[11], + priv->last_debug_word16[12], priv->last_debug_word16[13], + priv->last_debug_word16[14], priv->last_debug_word16[15]); + } + +} /* debug_word16_indication() */ + + +void +debug_generic_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr) +{ + unifi_info(priv, "debug: %04X %04X %04X %04X %04X %04X %04X %04X\n", + sigptr->u.DebugGenericIndication.DebugWords[0], + sigptr->u.DebugGenericIndication.DebugWords[1], + sigptr->u.DebugGenericIndication.DebugWords[2], + sigptr->u.DebugGenericIndication.DebugWords[3], + sigptr->u.DebugGenericIndication.DebugWords[4], + sigptr->u.DebugGenericIndication.DebugWords[5], + sigptr->u.DebugGenericIndication.DebugWords[6], + sigptr->u.DebugGenericIndication.DebugWords[7]); + +} /* debug_generic_indication() */ + diff --git a/drivers/staging/csr/unifi_event.c b/drivers/staging/csr/unifi_event.c new file mode 100644 index 000000000000..cfc5b32d4a66 --- /dev/null +++ b/drivers/staging/csr/unifi_event.c @@ -0,0 +1,794 @@ +/* + * *************************************************************************** + * FILE: unifi_event.c + * + * PURPOSE: + * Process the signals received by UniFi. + * It is part of the porting exercise. + * + * Copyright (C) 2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ + + +/* + * Porting notes: + * The implementation of unifi_receive_event() in Linux is fairly complicated. + * The linux driver support multiple userspace applications and several + * build configurations, so the received signals are processed by different + * processes and multiple times. + * In a simple implementation, this function needs to deliver: + * - The MLME-UNITDATA.ind signals to the Rx data plane and to the Traffic + * Analysis using unifi_ta_sample(). + * - The MLME-UNITDATA-STATUS.ind signals to the Tx data plane. + * - All the other signals to the SME using unifi_sys_hip_ind(). + */ + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "unifi_priv.h" + + +/* + * --------------------------------------------------------------------------- + * send_to_client + * + * Helper for unifi_receive_event. + * + * This function forwards a signal to one client. + * + * Arguments: + * priv Pointer to driver's private data. + * client Pointer to the client structure. + * receiver_id The reciever id of the signal. + * sigdata Pointer to the packed signal buffer. + * siglen Length of the packed signal. + * bulkdata Pointer to the signal's bulk data. + * + * Returns: + * None. + * + * --------------------------------------------------------------------------- + */ +static void send_to_client(unifi_priv_t *priv, ul_client_t *client, + int receiver_id, + unsigned char *sigdata, int siglen, + const bulk_data_param_t *bulkdata) +{ + if (client && client->event_hook) { + /*unifi_trace(priv, UDBG3, + "Receive: client %d, (s:0x%X, r:0x%X) - Signal 0x%.4X \n", + client->client_id, client->sender_id, receiver_id, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));*/ + + client->event_hook(client, sigdata, siglen, bulkdata, UDI_TO_HOST); + } +} + +/* + * --------------------------------------------------------------------------- + * process_pkt_data_ind + * + * Dispatcher for received signals. + * + * This function receives the 'to host' signals and forwards + * them to the unifi linux clients. + * + * Arguments: + * priv Context + * sigdata Pointer to the packed signal buffer(Its in form of MA-PACKET.ind). + * bulkdata Pointer to signal's bulkdata + * freeBulkData Pointer to a flag which gets set if the bulkdata needs to + * be freed after calling the logging handlers. If it is not + * set the bulkdata must be freed by the MLME handler or + * passed to the network stack. + * Returns: + * TRUE if the packet should be routed to the SME etc. + * FALSE if the packet is for the driver or network stack + * --------------------------------------------------------------------------- + */ +static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv, + CsrUint8 *sigdata, + const bulk_data_param_t* bulkdata, + CsrBool *freeBulkData, + netInterface_priv_t *interfacePriv) +{ + CsrUint16 frmCtrl, receptionStatus, frmCtrlSubType; + CsrUint8 *macHdrLocation; + CsrUint8 interfaceTag; + CsrBool isDataFrame; + CsrBool isProtocolVerInvalid = FALSE; + CsrBool isDataFrameSubTypeNoData = FALSE; + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + static const CsrUint8 wapiProtocolIdSNAPHeader[] = {0x88,0xb4}; + static const CsrUint8 wapiProtocolIdSNAPHeaderOffset = 6; + CsrUint8 *destAddr; + CsrUint8 *srcAddr; + CsrBool isUnicastPkt = FALSE; + + CsrUint8 llcSnapHeaderOffset = 0; + + destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; + srcAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; + + /*Individual/Group bit - Bit 0 of first byte*/ + isUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE; +#endif + +#define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22 + + *freeBulkData = FALSE; + + /* Fetch the MAC header location from MA_PKT_IND packet */ + macHdrLocation = (CsrUint8 *) bulkdata->d[0].os_data_ptr; + /* Fetch the Frame Control value from MAC header */ + frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation); + + /* Pull out interface tag from virtual interface identifier */ + interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff; + + /* check for MIC failure before processing the signal */ + receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET); + + /* To discard any spurious MIC failures that could be reported by the firmware */ + isDataFrame = ((frmCtrl & IEEE80211_FC_TYPE_MASK) == (IEEE802_11_FC_TYPE_DATA & IEEE80211_FC_TYPE_MASK)) ? TRUE : FALSE; + /* 0x00 is the only valid protocol version*/ + isProtocolVerInvalid = (frmCtrl & IEEE80211_FC_PROTO_VERSION_MASK) ? TRUE : FALSE; + frmCtrlSubType = (frmCtrl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET; + /*Exclude the no data & reserved sub-types from MIC failure processing*/ + isDataFrameSubTypeNoData = (((frmCtrlSubType>0x03)&&(frmCtrlSubType<0x08)) || (frmCtrlSubType>0x0B)) ? TRUE : FALSE; + if ((receptionStatus == CSR_MICHAEL_MIC_ERROR) && + ((!isDataFrame) || isProtocolVerInvalid || (isDataFrame && isDataFrameSubTypeNoData))) { + /* Currently MIC errors are discarded for frames other than data frames. This might need changing when we start + * supporting 802.11w (Protected Management frames) + */ + *freeBulkData = TRUE; + unifi_trace(priv, UDBG4, "Discarding this frame and ignoring the MIC failure as this is a garbage/non-data/no data frame\n"); + return FALSE; + } + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + + if (receptionStatus == CSR_MICHAEL_MIC_ERROR) { + + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) { + + /* If this MIC ERROR reported by the firmware is either for + * [1] a WAPI Multicast Packet and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying) OR + * [2] a WAPI Unicast Packet and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set + * then report a MIC FAILURE indication to the SME. + */ + if ((priv->wapi_multicast_filter == 0) || isUnicastPkt) { + + /*Discard the frame*/ + *freeBulkData = TRUE; + unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n"); + + if (isUnicastPkt && + ((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)|| + (priv->wapi_unicast_filter) || + (priv->wapi_unicast_queued_pkt_filter))) { + + /* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP + * while we are in the process of re-association induced by unsupported WAPI Unicast key index + * - Discard the packets with MIC failures "until" we have + * a. negotiated a key, + * b. opened the CONTROL PORT and + * c. the AP has started using the new key + */ + unifi_trace(priv, UDBG4, "Ignoring the MIC failure as either a. CONTROL PORT isn't OPEN or b. Unicast filter is set or c. WAPI AP using old key for buffered pkts\n"); + + /*Ignore this MIC failure*/ + return FALSE; + + }/*WAPI re-key specific workaround*/ + + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n", + interfaceTag, srcAddr[0], srcAddr[1], srcAddr[2], srcAddr[3], srcAddr[4], srcAddr[5]); + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : Dest Addr %x:%x:%x:%x:%x:%x\n", + destAddr[0], destAddr[1], destAddr[2], destAddr[3], destAddr[4], destAddr[5]); + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : Control Port State - 0x%.4X \n", + uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag)); + + unifi_error(priv, "MIC failure in %s\n", __FUNCTION__); + + /*Report the MIC failure to the SME*/ + return TRUE; + } + }/* STA mode */ + else { + /* Its AP Mode . Just Return */ + *freeBulkData = TRUE; + unifi_error(priv, "MIC failure in %s\n", __FUNCTION__); + return TRUE; + } /* AP mode */ + }/* MIC error */ +#else + if (receptionStatus == CSR_MICHAEL_MIC_ERROR) { + *freeBulkData = TRUE; + unifi_error(priv, "MIC failure in %s\n", __FUNCTION__); + return TRUE; + } +#endif /*CSR_WIFI_SECURITY_WAPI_ENABLE*/ + + unifi_trace(priv, UDBG4, "frmCtrl = 0x%04x %s\n", + frmCtrl, + (((frmCtrl & 0x000c)>>FRAME_CONTROL_TYPE_FIELD_OFFSET) == IEEE802_11_FRAMETYPE_MANAGEMENT) ? + "Mgt" : "Ctrl/Data"); + +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + /* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before + * starting to use the new key negotiated as part of unicast re-keying + */ + if (isUnicastPkt && + (receptionStatus == CSR_RX_SUCCESS) && + (priv->wapi_unicast_queued_pkt_filter==1)) { + + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): WAPI unicast pkt received when the (wapi_unicast_queued_pkt_filter) is set\n"); + + if (isDataFrame) { + switch(frmCtrl & IEEE80211_FC_SUBTYPE_MASK) { + case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK: + llcSnapHeaderOffset = MAC_HEADER_SIZE + 2; + break; + case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK: + case IEEE802_11_FC_TYPE_NULL & IEEE80211_FC_SUBTYPE_MASK: + break; + default: + llcSnapHeaderOffset = MAC_HEADER_SIZE; + } + } + + if (llcSnapHeaderOffset > 0) { + /* QoS data or Data */ + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): SNAP header found & its offset %d\n",llcSnapHeaderOffset); + if (memcmp((CsrUint8 *)(bulkdata->d[0].os_data_ptr+llcSnapHeaderOffset+wapiProtocolIdSNAPHeaderOffset), + wapiProtocolIdSNAPHeader,sizeof(wapiProtocolIdSNAPHeader))) { + + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): This is a data & NOT a WAI protocol packet\n"); + /* On the first unicast data pkt that is decrypted successfully after re-keying, reset the filter */ + priv->wapi_unicast_queued_pkt_filter = 0; + unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind(): WAPI AP has started using the new unicast key, no more MIC failures expected (reset filter)\n"); + } + else { + unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): WAPI - This is a WAI protocol packet\n"); + } + } + } +#endif + + + switch ((frmCtrl & 0x000c)>>FRAME_CONTROL_TYPE_FIELD_OFFSET) { + case IEEE802_11_FRAMETYPE_MANAGEMENT: + *freeBulkData = TRUE; /* Free (after SME handler copies it) */ + + /* In P2P device mode, filter the legacy AP beacons here */ + if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2P)&&\ + ((CSR_WIFI_80211_GET_FRAME_SUBTYPE(macHdrLocation)) == CSR_WIFI_80211_FRAME_SUBTYPE_BEACON)){ + + CsrUint8 *pSsid, *pSsidLen; + static CsrUint8 P2PWildCardSsid[CSR_WIFI_P2P_WILDCARD_SSID_LENGTH] = {'D', 'I', 'R', 'E', 'C', 'T', '-'}; + + pSsidLen = macHdrLocation + MAC_HEADER_SIZE + CSR_WIFI_BEACON_FIXED_LENGTH; + pSsid = pSsidLen + 2; + + if(*(pSsidLen + 1) >= CSR_WIFI_P2P_WILDCARD_SSID_LENGTH){ + if(memcmp(pSsid, P2PWildCardSsid, CSR_WIFI_P2P_WILDCARD_SSID_LENGTH) == 0){ + unifi_trace(priv, UDBG6, "Received a P2P Beacon, pass it to SME\n"); + return TRUE; + } + } + unifi_trace(priv, UDBG6, "Received a Legacy AP beacon in P2P mode, drop it\n"); + return FALSE; + } + return TRUE; /* Route to SME */ + case IEEE802_11_FRAMETYPE_DATA: + case IEEE802_11_FRAMETYPE_CONTROL: + *freeBulkData = FALSE; /* Network stack or MLME handler frees */ + return FALSE; + default: + unifi_error(priv, "Unhandled frame type %04x\n", frmCtrl); + *freeBulkData = TRUE; /* Not interested, but must free it */ + return FALSE; + } +} +#ifdef CSR_WIFI_RX_PATH_SPLIT +static CsrBool signal_buffer_is_full(unifi_priv_t* priv) +{ + return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer)); + +} +#endif +/* + * --------------------------------------------------------------------------- + * unifi_receive_event + * + * Dispatcher for received signals. + * + * This function receives the 'to host' signals and forwards + * them to the unifi linux clients. + * + * Arguments: + * ospriv Pointer to driver's private data. + * sigdata Pointer to the packed signal buffer. + * siglen Length of the packed signal. + * bulkdata Pointer to the signal's bulk data. + * + * Returns: + * None. + * + * Notes: + * The signals are received in the format described in the host interface + * specification, i.e wire formatted. Certain clients use the same format + * to interpret them and other clients use the host formatted structures. + * Each client has to call read_unpack_signal() to transform the wire + * formatted signal into the host formatted signal, if necessary. + * The code is in the core, since the signals are defined therefore + * binded to the host interface specification. + * --------------------------------------------------------------------------- + */ + + +void +unifi_receive_event(void *ospriv, + CsrUint8 *sigdata, CsrUint32 siglen, + const bulk_data_param_t *bulkdata) +{ +#ifdef CSR_WIFI_RX_PATH_SPLIT + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + CsrUint8 writePointer; + int i; + rx_buff_struct_t * rx_buff; + func_enter(); + + unifi_trace(priv, UDBG5, "unifi_receive_event: " + "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); + if(signal_buffer_is_full(priv)) { + unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n"); + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } + } + return; + } + writePointer = priv->rxSignalBuffer.writePointer; + rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer]; + memcpy(rx_buff->bufptr,sigdata,siglen); + rx_buff->sig_len = siglen; + rx_buff->data_ptrs = *bulkdata; + writePointer++; + if(writePointer >= priv->rxSignalBuffer.size) { + writePointer =0; + } + unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer); + priv->rxSignalBuffer.writePointer = writePointer; + +#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ + queue_work(priv->rx_workqueue, &priv->rx_work_struct); +#endif + +#else + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + int i, receiver_id; + int client_id; + CsrInt16 signal_id; + CsrBool pktIndToSme = FALSE, freeBulkData = FALSE; + + func_enter(); + + unifi_trace(priv, UDBG5, "unifi_receive_event: " + "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); + + receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00; + client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; + signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata); + + + + /* check for the type of frame received (checks for 802.11 management frames) */ + if (signal_id == CSR_MA_PACKET_INDICATION_ID) + { + CsrUint8 interfaceTag; + netInterface_priv_t *interfacePriv; + + /* Pull out interface tag from virtual interface identifier */ + interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff; + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* Update activity for this station in case of IBSS */ +#ifdef CSR_SUPPORT_SME + + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) { + + CsrUint8 *saddr; + /* Fetch the source address from mac header */ + saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; + unifi_trace(priv, UDBG5, + "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n", + interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]); + + uf_update_sta_activity(priv, interfaceTag, saddr); + } +#endif + + pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv); + + unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO"); + } + + if (pktIndToSme) + { + /* Management MA_PACKET_IND for SME */ + if(sigdata != NULL && bulkdata != NULL){ + send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); + } + else{ + unifi_error(priv, "unifi_receive_event: sigdata or Bulkdata is NULL \n"); + } +#ifdef CSR_NATIVE_LINUX + send_to_client(priv, priv->wext_client, + receiver_id, + sigdata, siglen, bulkdata); +#endif + } + else + { + /* Signals with ReceiverId==0 are also reported to SME / WEXT, + * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs + */ + if (!receiver_id) { + if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) + { + uf_process_ma_vif_availibility_ind(priv, sigdata, siglen); + } + else if (signal_id != CSR_MA_PACKET_INDICATION_ID) + { + send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); +#ifdef CSR_NATIVE_LINUX + send_to_client(priv, priv->wext_client, + receiver_id, + sigdata, siglen, bulkdata); +#endif + } + }/*if (receiver_id==0) */ + +#ifdef CSR_SUPPORT_SME +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + /* Send a WAPI Multicast Indication to SME if the filter has been set + * and this is a multicast data packet + */ + if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) { + CSR_SIGNAL signal; + CsrUint8 *destAddr; + CsrResult res; + CsrUint16 interfaceTag = 0; + + /* Check if it is a multicast packet from the destination address in the MAC header */ + res = read_unpack_signal(sigdata, &signal); + destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; + if (res) { + unifi_error(priv, "Received unknown or corrupted signal.\n"); + return; + } + /*Individual/Group bit - Bit 0 of first byte*/ + if (destAddr[0] & 0x01) { + unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n"); + + CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr); + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } + } + func_exit(); + return; + } + } +#endif +#endif + + /* calls the registered clients handler callback func. + * netdev_mlme_event_handler is one of the registered handler used to route + * data packet to network stack or AMP/EAPOL related data to SME + */ + /* The freeBulkData check ensures that, it has received a management frame and + * the frame needs to be freed here. So not to be passed to netdev handler + */ + if(!freeBulkData){ + if ((client_id < MAX_UDI_CLIENTS) && + (&priv->ul_clients[client_id] != priv->logging_client)) { + send_to_client(priv, &priv->ul_clients[client_id], + receiver_id, + sigdata, siglen, bulkdata); + } + } + } + + /* + * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION + */ + switch (signal_id) + { +#ifdef UNIFI_SNIFF_ARPHRD + case CSR_MA_SNIFFDATA_INDICATION_ID: +#endif + break; + + case CSR_MA_PACKET_INDICATION_ID: + if (!freeBulkData) + { + break; + } + /* FALLS THROUGH... */ + default: + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } + } + } +#endif + func_exit(); +} /* unifi_receive_event() */ + +#ifdef CSR_WIFI_RX_PATH_SPLIT +/* + * --------------------------------------------------------------------------- + * unifi_receive_event2 + * + * Dispatcher for received signals. + * + * This function receives the 'to host' signals and forwards + * them to the unifi linux clients. + * + * Arguments: + * ospriv Pointer to driver's private data. + * sigdata Pointer to the packed signal buffer. + * siglen Length of the packed signal. + * bulkdata Pointer to the signal's bulk data. + * + * Returns: + * None. + * + * Notes: + * The signals are received in the format described in the host interface + * specification, i.e wire formatted. Certain clients use the same format + * to interpret them and other clients use the host formatted structures. + * Each client has to call read_unpack_signal() to transform the wire + * formatted signal into the host formatted signal, if necessary. + * The code is in the core, since the signals are defined therefore + * binded to the host interface specification. + * --------------------------------------------------------------------------- + */ +static void +unifi_receive_event2(void *ospriv, + CsrUint8 *sigdata, CsrUint32 siglen, + const bulk_data_param_t *bulkdata) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + int i, receiver_id; + int client_id; + CsrInt16 signal_id; + CsrBool pktIndToSme = FALSE, freeBulkData = FALSE; + + func_enter(); + + unifi_trace(priv, UDBG5, "unifi_receive_event2: " + "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); + + receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00; + client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; + signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata); + + + + /* check for the type of frame received (checks for 802.11 management frames) */ + if (signal_id == CSR_MA_PACKET_INDICATION_ID) + { + CsrUint8 interfaceTag; + netInterface_priv_t *interfacePriv; + + /* Pull out interface tag from virtual interface identifier */ + interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff; + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* Update activity for this station in case of IBSS */ +#ifdef CSR_SUPPORT_SME + + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) { + + CsrUint8 *saddr; + /* Fetch the source address from mac header */ + saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; + unifi_trace(priv, UDBG5, + "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n", + interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]); + + uf_update_sta_activity(priv, interfaceTag, saddr); + } +#endif + + pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv); + + unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO"); + + } + + if (pktIndToSme) + { + /* Management MA_PACKET_IND for SME */ + if(sigdata != NULL && bulkdata != NULL){ + send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); + } + else{ + unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n"); + } +#ifdef CSR_NATIVE_LINUX + send_to_client(priv, priv->wext_client, + receiver_id, + sigdata, siglen, bulkdata); +#endif + } + else + { + /* Signals with ReceiverId==0 are also reported to SME / WEXT, + * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs + */ + if (!receiver_id) { + if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) + { + uf_process_ma_vif_availibility_ind(priv, sigdata, siglen); + } + else if (signal_id != CSR_MA_PACKET_INDICATION_ID) + { + send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); +#ifdef CSR_NATIVE_LINUX + send_to_client(priv, priv->wext_client, + receiver_id, + sigdata, siglen, bulkdata); +#endif + } + } + +#ifdef CSR_SUPPORT_SME +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + /* Send a WAPI Multicast Indication to SME if the filter has been set + * and this is a multicast data packet + */ + if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) { + CSR_SIGNAL signal; + CsrUint8 *destAddr; + CsrResult res; + CsrUint16 interfaceTag = 0; + + /* Check if it is a multicast packet from the destination address in the MAC header */ + res = read_unpack_signal(sigdata, &signal); + destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; + if (res) { + unifi_error(priv, "Received unknown or corrupted signal.\n"); + return; + } + /*Individual/Group bit - Bit 0 of first byte*/ + if (destAddr[0] & 0x01) { + unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n"); + + CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr); + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } + } + func_exit(); + return; + } + } +#endif +#endif + + /* calls the registered clients handler callback func. + * netdev_mlme_event_handler is one of the registered handler used to route + * data packet to network stack or AMP/EAPOL related data to SME + */ + /* The freeBulkData check ensures that, it has received a management frame and + * the frame needs to be freed here. So not to be passed to netdev handler + */ + if(!freeBulkData){ + if ((client_id < MAX_UDI_CLIENTS) && + (&priv->ul_clients[client_id] != priv->logging_client)) { + send_to_client(priv, &priv->ul_clients[client_id], + receiver_id, + sigdata, siglen, bulkdata); + } + } + } + + /* + * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION + */ + switch (signal_id) + { +#ifdef UNIFI_SNIFF_ARPHRD + case CSR_MA_SNIFFDATA_INDICATION_ID: +#endif + break; + + case CSR_MA_PACKET_INDICATION_ID: + if (!freeBulkData) + { + break; + } + /* FALLS THROUGH... */ + default: + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } + } + } + + func_exit(); +} /* unifi_receive_event2() */ + +void unifi_rx_queue_flush(void *ospriv) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + + func_enter(); + unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", + priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer); + if(priv != NULL) { + CsrUint8 readPointer = priv->rxSignalBuffer.readPointer; + while(readPointer != priv->rxSignalBuffer.writePointer) { + rx_buff_struct_t * buf = &priv->rxSignalBuffer.rx_buff[readPointer]; + unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", + readPointer,priv->rxSignalBuffer.writePointer); + unifi_receive_event2(priv,buf->bufptr,buf->sig_len,&buf->data_ptrs); + readPointer ++; + if(readPointer >= priv->rxSignalBuffer.size) { + readPointer = 0; + } + } + priv->rxSignalBuffer.readPointer = readPointer; + } + func_exit(); +} + +void rx_wq_handler(struct work_struct *work) +{ + unifi_priv_t *priv = container_of(work,unifi_priv_t,rx_work_struct); + unifi_rx_queue_flush(priv); +} + +#endif diff --git a/drivers/staging/csr/unifi_native.h b/drivers/staging/csr/unifi_native.h new file mode 100644 index 000000000000..0015ec2cdb00 --- /dev/null +++ b/drivers/staging/csr/unifi_native.h @@ -0,0 +1,276 @@ +/* + ***************************************************************************** + * + * FILE : unifi_native.h + * + * PURPOSE : Private header file for unifi driver support to wireless extensions. + * + * UDI = UniFi Debug Interface + * + * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + ***************************************************************************** + */ +#ifndef __LINUX_UNIFI_NATIVE_H__ +#define __LINUX_UNIFI_NATIVE_H__ 1 + +#include +#include + + +/* + * scan.c wext.c autojoin.c + */ +/* Structure to hold results of a scan */ +typedef struct scan_info { + +/* CSR_MLME_SCAN_INDICATION msi; */ + + unsigned char *info_elems; + int info_elem_length; + +} scan_info_t; + + +#define IE_VECTOR_MAXLEN 1024 + +#ifdef CSR_SUPPORT_WEXT +/* + * Structre to hold the wireless network configuration info. + */ +struct wext_config { + + /* Requested channel when setting up an adhoc network */ + int channel; + + /* wireless extns mode: IW_MODE_AUTO, ADHOC, INFRA, MASTER ... MONITOR */ + int mode; + + /* The capabilities of the currently joined network */ + int capability; + + /* The interval between beacons if we create an IBSS */ + int beacon_period; + + /* + * Power-save parameters + */ + /* The listen interval to ask for in Associate req. */ + int assoc_listen_interval; + /* Power-mode to put UniFi into */ + + unsigned char desired_ssid[UNIFI_MAX_SSID_LEN]; /* the last ESSID set by SIOCSIWESSID */ + int power_mode; + /* Whether to wake for broadcast packets (using DTIM interval) */ + int wakeup_for_dtims; + + /* Currently selected WEP Key ID (0..3) */ + int wep_key_id; + + wep_key_t wep_keys[NUM_WEPKEYS]; + +/* CSR_AUTHENTICATION_TYPE auth_type; */ + int privacy; + + u32 join_failure_timeout; + u32 auth_failure_timeout; + u32 assoc_failure_timeout; + + unsigned char generic_ie[IE_VECTOR_MAXLEN]; + int generic_ie_len; + + struct iw_statistics wireless_stats; + + + /* the ESSID we are currently associated to */ + unsigned char current_ssid[UNIFI_MAX_SSID_LEN]; + /* the BSSID we are currently associated to */ + unsigned char current_bssid[6]; + + /* + * IW_AUTH_WPA_VERSION_DISABLED 0x00000001 + * IW_AUTH_WPA_VERSION_WPA 0x00000002 + * IW_AUTH_WPA_VERSION_WPA2 0x00000004 + */ + unsigned char wpa_version; + + /* + * cipher selection: + * IW_AUTH_CIPHER_NONE 0x00000001 + * IW_AUTH_CIPHER_WEP40 0x00000002 + * IW_AUTH_CIPHER_TKIP 0x00000004 + * IW_AUTH_CIPHER_CCMP 0x00000008 + * IW_AUTH_CIPHER_WEP104 0x00000010 + */ + unsigned char pairwise_cipher_used; + unsigned char group_cipher_used; + + unsigned int frag_thresh; + unsigned int rts_thresh; + + /* U-APSD value, send with Association Request to WMM Enabled APs */ + unsigned char wmm_bss_uapsd_mask; + /* The WMM capabilities of the selected BSS */ + unsigned int bss_wmm_capabilities; + + /* Flag to prevent a join when the ssid is set */ + int disable_join_on_ssid_set; + + /* Scan info */ +#define UNIFI_MAX_SCANS 32 + scan_info_t scan_list[UNIFI_MAX_SCANS]; + int num_scan_info; + + /* Flag on whether non-802.1x packets are allowed out */ + CsrWifiRouterPortAction block_controlled_port; + + /* Flag on whether we have completed an authenticate/associate process */ + unsigned int flag_associated : 1; +}; /* struct wext_config */ + +#endif /* CSR_SUPPORT_WEXT */ + + +/* + * wext.c + */ +/*int mlme_set_protection(unifi_priv_t *priv, unsigned char *addr, + CSR_PROTECT_TYPE prot, CSR_KEY_TYPE key_type); +*/ + +/* + * scan.c + */ +/* +void unifi_scan_indication_handler(unifi_priv_t *priv, + const CSR_MLME_SCAN_INDICATION *msg, + const unsigned char *extra, + unsigned int len); +*/ +void unifi_clear_scan_table(unifi_priv_t *priv); +scan_info_t *unifi_get_scan_report(unifi_priv_t *priv, int index); + + +/* + * Utility functions + */ +const unsigned char *unifi_find_info_element(int id, + const unsigned char *info, + int len); +int unifi_add_info_element(unsigned char *info, + int ie_id, + const unsigned char *ie_data, + int ie_len); + +/* + * autojoin.c + */ +/* Higher level fns */ +int unifi_autojoin(unifi_priv_t *priv, const char *ssid); +/* +int unifi_do_scan(unifi_priv_t *priv, int scantype, CSR_BSS_TYPE bsstype, + const char *ssid, int ssid_len); +*/ +int unifi_set_powermode(unifi_priv_t *priv); +int unifi_join_ap(unifi_priv_t *priv, scan_info_t *si); +int unifi_join_bss(unifi_priv_t *priv, unsigned char *macaddr); +int unifi_leave(unifi_priv_t *priv); +unsigned int unifi_get_wmm_bss_capabilities(unifi_priv_t *priv, + unsigned char *ie_vector, + int ie_len, int *ap_capabilities); + +/* + * Status and management. + */ +int uf_init_wext_interface(unifi_priv_t *priv); +void uf_deinit_wext_interface(unifi_priv_t *priv); + +/* + * Function to reset UniFi's 802.11 state by sending MLME-RESET.req + */ +int unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr, unsigned char set_default_mib); + + +/* + * mlme.c + */ +/* Abort an MLME operation - useful in error recovery */ +int uf_abort_mlme(unifi_priv_t *priv); + +int unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli, + CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs, + int timeout); +void unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli, + CSR_SIGNAL *signal, int signal_len, + const bulk_data_param_t *bulkdata); + +/* + * Utility functions + */ +const char *lookup_reason_code(int reason); +const char *lookup_result_code(int result); + + +/* + * sme_native.c + */ +int uf_sme_init(unifi_priv_t *priv); +void uf_sme_deinit(unifi_priv_t *priv); +int sme_sys_suspend(unifi_priv_t *priv); +int sme_sys_resume(unifi_priv_t *priv); +int sme_mgt_wifi_on(unifi_priv_t *priv); + +/* Callback for event logging to SME clients (unifi_manager) */ +void sme_native_log_event(ul_client_t *client, + const u8 *sig_packed, int sig_len, + const bulk_data_param_t *bulkdata, + int dir); + +void sme_native_mlme_event_handler(ul_client_t *pcli, + const u8 *sig_packed, int sig_len, + const bulk_data_param_t *bulkdata, + int dir); + +/* Task to query statistics from the MIB */ +#define UF_SME_STATS_WQ_TIMEOUT 2000 /* in msecs */ +void uf_sme_stats_wq(struct work_struct *work); + +void uf_native_process_udi_signal(ul_client_t *pcli, + const u8 *packed_signal, + int packed_signal_len, + const bulk_data_param_t *bulkdata, int dir); +#if 0 +/* + * Choose one of these if available in linux/if_arp.h: + * #define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_RADIOTAP + * #define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_PRISM + * + * Radiotap is the newer standard for softmac WLAN devices, it works with + * Wireshark but not Ethereal (due to a bug in the Ethereal dissector). + * Prism is an older (less desirable) format but it does work with Ethereal. + */ +#ifdef ARPHRD_IEEE80211_RADIOTAP +#define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_RADIOTAP +#else +#ifdef ARPHRD_IEEE80211_PRISM +#define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_PRISM +#endif +#endif +#endif + +#ifdef UNIFI_SNIFF_ARPHRD +/* + * monitor.c + */ +int uf_start_sniff(unifi_priv_t *priv); +/* +void ma_sniffdata_ind(void *ospriv, + const CSR_MA_SNIFFDATA_INDICATION *ind, + const bulk_data_param_t *bulkdata); +*/ +#endif /* ARPHRD_IEEE80211_PRISM */ + +#endif /* __LINUX_UNIFI_NATIVE_H__ */ diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h new file mode 100644 index 000000000000..579c7e0544a3 --- /dev/null +++ b/drivers/staging/csr/unifi_os.h @@ -0,0 +1,137 @@ +/* + * --------------------------------------------------------------------------- + * + * FILE: os_linux/unifi_os.h + * + * PURPOSE: + * This header file provides the OS-dependent facilities for a linux + * environment. + * + * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#ifndef __UNIFI_OS_LINUX_H__ +#define __UNIFI_OS_LINUX_H__ 1 + +#include +#include +#include +#include +#include + +/* + * Needed for core/signals.c + */ +#include + + +/* Define INLINE directive*/ +#define INLINE inline + +/* Malloc and free */ +CsrResult unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size); +void unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot); +#define CSR_WIFI_ALIGN_BYTES 4 +CsrResult unifi_net_dma_align(void *ospriv, bulk_data_desc_t *bulk_data_slot); + +/* + * Byte Order + * Note that __le*_to_cpu and __cpu_to_le* return an unsigned value! + */ +#ifdef __KERNEL__ +#define unifi2host_16(n) (__le16_to_cpu((n))) +#define unifi2host_32(n) (__le32_to_cpu((n))) +#define host2unifi_16(n) (__cpu_to_le16((n))) +#define host2unifi_32(n) (__cpu_to_le32((n))) +#endif + +/* Module parameters */ +extern int unifi_debug; + +/* debugging */ +#ifdef UNIFI_DEBUG +/* + * unifi_debug is a verbosity level for debug messages + * UDBG0 msgs are always printed if UNIFI_DEBUG is defined + * UDBG1 msgs are printed if UNIFI_DEBUG is defined and unifi_debug > 0 + * etc. + */ + +#define func_enter() \ + do { \ + if (unifi_debug >= 5) { \ + printk("unifi: => %s\n", __FUNCTION__); \ + } \ + } while (0) +#define func_exit() \ + do { \ + if (unifi_debug >= 5) { \ + printk("unifi: <= %s\n", __FUNCTION__); \ + } \ + } while (0) +#define func_exit_r(_rc) \ + do { \ + if (unifi_debug >= 5) { \ + printk("unifi: <= %s %d\n", __FUNCTION__, (int)(_rc)); \ + } \ + } while (0) + + +#define ASSERT(cond) \ + do { \ + if (!(cond)) { \ + printk("Assertion failed in %s at %s:%d: %s\n", \ + __FUNCTION__, __FILE__, __LINE__, #cond); \ + } \ + } while (0) + + +void unifi_dump(void *ospriv, int lvl, const char *msg, void *mem, CsrUint16 len); +void dump(void *mem, CsrUint16 len); +void dump16(void *mem, CsrUint16 len); +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +void dump_str(void *mem, CsrUint16 len); +#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ + +#else + +/* Stubs */ +#define func_enter() +#define func_exit() +#define func_exit_r(_rc) + +#define ASSERT(cond) + +static inline void unifi_dump(void *ospriv, int lvl, const char *msg, void *mem, CsrUint16 len) {} +static inline void dump(void *mem, CsrUint16 len) {} +static inline void dump16(void *mem, CsrUint16 len) {} +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +static inline void dump_str(void *mem, CsrUint16 len) {} +#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ + +#endif /* UNIFI_DEBUG */ + + +void unifi_error(void* ospriv, const char *fmt, ...); +void unifi_warning(void* ospriv, const char *fmt, ...); +void unifi_notice(void* ospriv, const char *fmt, ...); +void unifi_info(void* ospriv, const char *fmt, ...); + +void unifi_trace(void* ospriv, int level, const char *fmt, ...); + +/* Different levels of diagnostic detail... */ +#define UDBG0 0 /* always prints in debug build */ +#define UDBG1 1 +#define UDBG2 2 +#define UDBG3 3 +#define UDBG4 4 +#define UDBG5 5 +#define UDBG6 6 +#define UDBG7 7 + + +#endif /* __UNIFI_OS_LINUX_H__ */ diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c new file mode 100644 index 000000000000..36b871e02c98 --- /dev/null +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -0,0 +1,3728 @@ +/* + * --------------------------------------------------------------------------- + * FILE: unifi_pdu_processing.c + * + * PURPOSE: + * This file provides the PDU handling functionality before it gets sent to unfi and after + * receiving a PDU from unifi + * + * Copyright (C) 2010 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ + + +#include +#include +#include + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" +#include "csr_time.h" +#include "unifi_priv.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) +#include +#endif +#include + +#ifdef CSR_SUPPORT_SME +static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata, + tx_buffered_packets_t* buffered_pkt) +{ + + struct sk_buff *skb ; + CsrUint32 align_offset; + + if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){ + return; + } + skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; + align_offset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1); + if(align_offset){ + skb_pull(skb,align_offset); + } + buffered_pkt->bulkdata.os_data_ptr = skb->data; + buffered_pkt->bulkdata.data_length = skb->len; + + +} +#endif + +void +unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority, + CSR_RATE TransmitRate, CSR_CLIENT_TAG hostTag, + CsrUint16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl, + CSR_PROCESS_ID leSenderProcessId, CsrUint8 *peerMacAddress, + CSR_SIGNAL *signal) +{ + + CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest; + netInterface_priv_t *interfacePriv; + CsrUint8 ba_session_idx = 0; + ba_session_tx_struct *ba_session = NULL; + CsrUint8 *ba_addr = NULL; + + interfacePriv = priv->interfacePriv[interfaceTag]; + + UF_TRACE_MAC(priv, UDBG5, "In unifi_frame_ma_packet_req, Frame for Peer:", peerMacAddress); + signal->SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID; + signal->SignalPrimitiveHeader.ReceiverProcessId = 0; + signal->SignalPrimitiveHeader.SenderProcessId = leSenderProcessId; + + /* Fill the MA-PACKET.req */ + req->Priority = priority; + unifi_trace(priv, UDBG3, "Tx Frame with Priority: 0x%x\n", req->Priority); + + /* A value of 0 is used for auto selection of rates. But for P2P GO case + * for action frames the rate is governed by SME. Hence instead of 0, + * the rate is filled in with the value passed here + */ + req->TransmitRate = TransmitRate; + + /* packets from netdev then no confirm required but packets from + * Nme/Sme eapol data frames requires the confirmation + */ + req->TransmissionControl = transmissionControl; + req->VirtualInterfaceIdentifier = + uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag); + memcpy(req->Ra.x, peerMacAddress, ETH_ALEN); + + if (hostTag == 0xffffffff) { + req->HostTag = interfacePriv->tag++; + req->HostTag |= 0x40000000; + unifi_trace(priv, UDBG3, "new host tag assigned = 0x%x\n", req->HostTag); + interfacePriv->tag &= 0x0fffffff; + } else { + req->HostTag = hostTag; + unifi_trace(priv, UDBG3, "host tag got from SME = 0x%x\n", req->HostTag); + } + /* check if BA session exists for the peer MAC address on same tID */ + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){ + ba_addr = peerMacAddress; + }else{ + ba_addr = interfacePriv->bssid.a; + } + for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){ + ba_session = interfacePriv->ba_session_tx[ba_session_idx]; + if (ba_session){ + if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == priority)){ + req->TransmissionControl |= CSR_ALLOW_BA; + break; + } + } + } + + unifi_trace(priv, UDBG5, "leaving unifi_frame_ma_packet_req\n"); +} + +#ifdef CSR_SUPPORT_SME + +#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001 +#define TRANSMISSION_CONTROL_ESOP_MASK 0x0002 + +static +int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt, + CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool moreData , CsrBool eosp) +{ + + CSR_SIGNAL signal; + bulk_data_param_t bulkdata; + int result; + CsrUint8 toDs, fromDs, macHeaderLengthInBytes = MAC_HEADER_SIZE; + CsrUint8 *qc; + CsrUint16 *fc = (CsrUint16*)(buffered_pkt->bulkdata.os_data_ptr); + unsigned long lock_flags; + unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu with moreData: %d , EOSP: %d\n",moreData,eosp); + unifi_frame_ma_packet_req(priv, buffered_pkt->priority, buffered_pkt->rate, buffered_pkt->hostTag, + buffered_pkt->interfaceTag, buffered_pkt->transmissionControl, + buffered_pkt->leSenderProcessId, buffered_pkt->peerMacAddress.a, &signal); + bulkdata.d[0].os_data_ptr = buffered_pkt->bulkdata.os_data_ptr; + bulkdata.d[0].data_length = buffered_pkt->bulkdata.data_length; + bulkdata.d[0].os_net_buf_ptr = buffered_pkt->bulkdata.os_net_buf_ptr; + bulkdata.d[0].net_buf_length = buffered_pkt->bulkdata.net_buf_length; + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].data_length = 0; + bulkdata.d[1].os_net_buf_ptr =0; + bulkdata.d[1].net_buf_length =0; + + if(moreData) { + *fc |= cpu_to_le16(IEEE802_11_FC_MOREDATA_MASK); + } else { + *fc &= cpu_to_le16(~IEEE802_11_FC_MOREDATA_MASK); + } + + if((staRecord != NULL)&& (staRecord->wmmOrQosEnabled == TRUE)) + { + unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu WMM Enabled: %d \n",staRecord->wmmOrQosEnabled); + + toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0; + fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0; + + switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK) + { + case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK: + case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK: + /* If both are set then the Address4 exists (only for AP) */ + if (fromDs && toDs) + { + /* 6 is the size of Address4 field */ + macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6); + } + else + { + macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE; + } + + /* If order bit set then HT control field is the part of MAC header */ + if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { + macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE; + } + break; + default: + if (fromDs && toDs) + macHeaderLengthInBytes += 6; + break; + } + + if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { + qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6)); + } else { + qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2)); + } + + *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4)); + } + result = ul_send_signal_unpacked(priv, &signal, &bulkdata); + if(result){ + _update_buffered_pkt_params_after_alignment(priv, &bulkdata,buffered_pkt); + } + + /* Decrement the packet counts queued in driver */ + if (result != -ENOSPC) { + /* protect entire counter updation by disabling preemption */ + if (!priv->noOfPktQueuedInDriver) { + unifi_error(priv, "packets queued in driver 0 still decrementing\n"); + } else { + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + priv->noOfPktQueuedInDriver--; + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + } + /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */ + if (staRecord) { + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + if (!staRecord->noOfPktQueued) { + unifi_error(priv, "packets queued in driver per station is 0 still decrementing\n"); + } else { + staRecord->noOfPktQueued--; + } + /* if the STA alive probe frame has failed then reset the saved host tag */ + if (result){ + if (staRecord->nullDataHostTag == buffered_pkt->hostTag){ + staRecord->nullDataHostTag = INVALID_HOST_TAG; + } + } + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } + + } + return result; +} +#ifdef CSR_SUPPORT_SME +static +void set_eosp_transmit_ctrl(unifi_priv_t *priv, struct list_head *txList) +{ + /* dequeue the tx data packets from the appropriate queue */ + tx_buffered_packets_t *tx_q_item = NULL; + struct list_head *listHead; + struct list_head *placeHolder; + unsigned long lock_flags; + + + unifi_trace(priv, UDBG5, "entering set_eosp_transmit_ctrl\n"); + /* check for list empty */ + if (list_empty(txList)) { + unifi_warning(priv, "In set_eosp_transmit_ctrl, the list is empty\n"); + return; + } + + /* return the last node , and modify it. */ + + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_prev_safe(listHead, placeHolder, txList) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; + tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); + unifi_trace(priv, UDBG1, + "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag); + unifi_trace(priv,UDBG3,"in set_eosp_transmit_ctrl no.of buffered frames %d\n",priv->noOfPktQueuedInDriver); + break; + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + unifi_trace(priv, UDBG1,"List Empty %d\n",list_empty(txList)); + unifi_trace(priv, UDBG5, "leaving set_eosp_transmit_ctrl\n"); + return; +} + +static +void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RESULT_CODE resultCode) +{ + CSR_SIGNAL signal; + CSR_MA_VIF_AVAILABILITY_RESPONSE *rsp; + bulk_data_param_t *bulkdata = NULL; + int r; + + memset(&signal,0,sizeof(CSR_SIGNAL)); + rsp = &signal.u.MaVifAvailabilityResponse; + rsp->VirtualInterfaceIdentifier = vif; + rsp->ResultCode = resultCode; + signal.SignalPrimitiveHeader.SignalId = CSR_MA_VIF_AVAILABILITY_RESPONSE_ID; + signal.SignalPrimitiveHeader.ReceiverProcessId = 0; + signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id; + + /* Send the signal to UniFi */ + r = ul_send_signal_unpacked(priv, &signal, bulkdata); + if(r) { + unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r); + } +} +#endif + +static +void verify_and_accomodate_tx_packet(unifi_priv_t *priv) +{ + tx_buffered_packets_t *tx_q_item; + unsigned long lock_flags; + struct list_head *listHead, *list; + struct list_head *placeHolder; + CsrUint8 i, j,eospFramedeleted=0; + CsrBool thresholdExcedeDueToBroadcast = TRUE; + /* it will be made it interface Specific in the future when multi interfaces are supported , + right now interface 0 is considered */ + netInterface_priv_t *interfacePriv = priv->interfacePriv[0]; + CsrWifiRouterCtrlStaInfo_t *staInfo = NULL; + + unifi_trace(priv, UDBG3, "entering verify_and_accomodate_tx_packet\n"); + + for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + staInfo = interfacePriv->staInfo[i]; + if (staInfo && (staInfo->noOfPktQueued >= CSR_WIFI_DRIVER_MAX_PKT_QUEUING_THRESHOLD_PER_PEER)) { + /* remove the first(oldest) packet from the all the access catogory, since data + * packets for station record crossed the threshold limit (64 for AP supporting + * 8 peers) + */ + unifi_trace(priv,UDBG3,"number of station pkts queued= %d for sta id = %d\n", staInfo->noOfPktQueued, staInfo->aid); + for(j = 0; j < MAX_ACCESS_CATOGORY; j++) { + list = &staInfo->dataPdu[j]; + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHead, placeHolder, list) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + list_del(listHead); + thresholdExcedeDueToBroadcast = FALSE; + unifi_net_data_free(priv, &tx_q_item->bulkdata); + kfree(tx_q_item); + tx_q_item = NULL; + if (!priv->noOfPktQueuedInDriver) { + unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__); + } else { + /* protection provided by spinlock */ + priv->noOfPktQueuedInDriver--; + + } + /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */ + if (!staInfo->noOfPktQueued) { + unifi_error(priv, "packets queued in driver per station is 0 still decrementing in %s\n", __FUNCTION__); + } else { + spin_lock(&priv->staRecord_lock); + staInfo->noOfPktQueued--; + spin_unlock(&priv->staRecord_lock); + } + break; + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + } + } + } + if (thresholdExcedeDueToBroadcast && interfacePriv->noOfbroadcastPktQueued > CSR_WIFI_DRIVER_MINIMUM_BROADCAST_PKT_THRESHOLD ) { + /* Remove the packets from genericMulticastOrBroadCastFrames queue + * (the max packets in driver is reached due to broadcast/multicast frames) + */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + if(eospFramedeleted){ + tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; + tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); + unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag); + eospFramedeleted =0; + break; + } + + if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK ){ + eospFramedeleted = 1; + } + unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag); + list_del(listHead); + unifi_net_data_free(priv, &tx_q_item->bulkdata); + kfree(tx_q_item); + priv->noOfPktQueuedInDriver--; + spin_lock(&priv->staRecord_lock); + interfacePriv->noOfbroadcastPktQueued--; + spin_unlock(&priv->staRecord_lock); + if(!eospFramedeleted){ + break; + } + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + } + unifi_trace(priv, UDBG3, "leaving verify_and_accomodate_tx_packet\n"); +} + +static +CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, + struct list_head *list, CSR_SIGNAL *signal, + CsrBool requeueOnSamePos) +{ + + /* queue the tx data packets on to appropriate queue */ + CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest; + tx_buffered_packets_t *tx_q_item; + unsigned long lock_flags; + + unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n"); + if(!list) { + unifi_error(priv,"List is not specified\n"); + return CSR_RESULT_FAILURE; + } + + /* Removes aged packets & adds the incoming packet */ + if (priv->noOfPktQueuedInDriver >= CSR_WIFI_DRIVER_SUPPORT_FOR_MAX_PKT_QUEUEING) { + unifi_trace(priv,UDBG3,"number of pkts queued= %d \n", priv->noOfPktQueuedInDriver); + verify_and_accomodate_tx_packet(priv); + } + + + + tx_q_item = (tx_buffered_packets_t *)kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); + if (tx_q_item == NULL) { + unifi_error(priv, + "Failed to allocate %d bytes for tx packet record\n", + sizeof(tx_buffered_packets_t)); + func_exit(); + return CSR_RESULT_FAILURE; + } + + /* disable the preemption */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + INIT_LIST_HEAD(&tx_q_item->q); + /* fill the tx_q structure members */ + tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr; + tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length; + tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr; + tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length; + tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff; + tx_q_item->hostTag = req->HostTag; + tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId; + tx_q_item->transmissionControl = req->TransmissionControl; + tx_q_item->priority = req->Priority; + tx_q_item->rate = req->TransmitRate; + memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN); + + + + if (requeueOnSamePos) { + list_add(&tx_q_item->q, list); + } else { + list_add_tail(&tx_q_item->q, list); + } + + /* Count of packet queued in driver */ + priv->noOfPktQueuedInDriver++; + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n"); + return CSR_RESULT_SUCCESS; +} +static +CsrResult enque_direceted_ma_pkt_cfm_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, + struct list_head *list, CSR_SIGNAL *signal, + CsrBool requeueOnSamePos) +{ + + /* queue the tx data packets on to appropriate queue */ + CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest; + tx_buffered_packets_t *tx_q_item; + + + unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n"); + if(!list ) { + unifi_error(priv,"List is not specified\n"); + return CSR_RESULT_FAILURE; + } + if(!requeueOnSamePos && !list->prev){ + unifi_error(priv,"List prev is NULL so don't requeu it\n"); + return CSR_RESULT_FAILURE; + + } + + + + tx_q_item = (tx_buffered_packets_t *)kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); + if (tx_q_item == NULL) { + unifi_error(priv, + "Failed to allocate %d bytes for tx packet record\n", + sizeof(tx_buffered_packets_t)); + func_exit(); + return CSR_RESULT_FAILURE; + } + /* disable the preemption */ + INIT_LIST_HEAD(&tx_q_item->q); + /* fill the tx_q structure members */ + tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr; + tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length; + tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr; + tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length; + tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff; + tx_q_item->hostTag = req->HostTag; + tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId; + tx_q_item->transmissionControl = req->TransmissionControl; + tx_q_item->priority = req->Priority; + tx_q_item->rate = req->TransmitRate; + memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN); + + + + if (requeueOnSamePos) { + list_add(&tx_q_item->q, list); + } else { + list_add_tail(&tx_q_item->q, list); + } + + /* Count of packet queued in driver */ + priv->noOfPktQueuedInDriver++; + unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n"); + return CSR_RESULT_SUCCESS; +} + +static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, CsrUint8 *allDeliveryEnabled, CsrUint8 *dataAvailable) +{ + CsrUint8 i; + *allDeliveryEnabled = TRUE; + for (i = 0 ;i < MAX_ACCESS_CATOGORY; i++) { + if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) { + /* One is is not Delivery Enabled */ + *allDeliveryEnabled = FALSE; + break; + } + } + if (*allDeliveryEnabled) { + *dataAvailable = (!list_empty(&staRecord->dataPdu[0]) || !list_empty(&staRecord->dataPdu[1]) + ||!list_empty(&staRecord->dataPdu[2]) ||!list_empty(&staRecord->dataPdu[3]) + ||!list_empty(&staRecord->mgtFrames)); + } +} + +/* + * --------------------------------------------------------------------------- + * uf_handle_tim_cfm + * + * + * This function updates tim status in host depending confirm status from firmware + * + * Arguments: + * priv Pointer to device private context struct + * cfm CSR_MLME_SET_TIM_CONFIRM + * receiverProcessId SenderProcessID to fetch handle & timSet status + * + * --------------------------------------------------------------------------- + */ +void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, CsrUint16 receiverProcessId) +{ + CsrUint8 handle = CSR_WIFI_GET_STATION_HANDLE_FROM_RECEIVER_ID(receiverProcessId); + CsrUint8 timSetStatus = CSR_WIFI_GET_TIMSET_STATE_FROM_RECEIVER_ID(receiverProcessId); + CsrUint16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff); + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; + /* This variable holds what TIM value we wanted to set in firmware */ + CsrUint16 timSetValue = 0; + /* Irrespective of interface the count maintained */ + static CsrUint8 retryCount = 0; + unsigned long lock_flags; + unifi_trace(priv, UDBG3, "entering %s, handle = %x, timSetStatus = %x\n", __FUNCTION__, handle, timSetStatus); + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_warning(priv, "bad interfaceTag = %x\n", interfaceTag); + return; + } + + if ((handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) && (handle >= UNIFI_MAX_CONNECTIONS)) { + unifi_warning(priv, "bad station Handle = %x\n", handle); + return; + } + + if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) { + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) { + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + unifi_warning(priv, "uf_handle_tim_cfm: station record is NULL handle = %x\n", handle); + return; + } + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } + switch(timSetStatus) + { + case CSR_WIFI_TIM_SETTING: + timSetValue = CSR_WIFI_TIM_SET; + break; + case CSR_WIFI_TIM_RESETTING: + timSetValue = CSR_WIFI_TIM_RESET; + break; + default: + unifi_warning(priv, "timSet state is %x: Debug\n", timSetStatus); + return; + } + + /* check TIM confirm for success/failures */ + switch(cfm->ResultCode) + { + case CSR_RC_SUCCESS: + if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) { + /* Unicast frame & station record available */ + if (timSetStatus == staRecord->timSet) { + staRecord->timSet = timSetValue; + /* fh_cmd_q can also be full at some point of time!, + * resetting count as queue is cleaned by firmware at this point + */ + retryCount = 0; + unifi_trace(priv, UDBG2, "tim (%s) successfully in firmware\n", (timSetValue)?"SET":"RESET"); + } else { + unifi_trace(priv, UDBG3, "receiver processID = %x, success: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x, handle = %x\n", + receiverProcessId, timSetStatus, staRecord->timSet, handle); + } + } else { + /* fh_cmd_q can also be full at some point of time!, + * resetting count as queue is cleaned by firmware at this point + */ + retryCount = 0; + unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET"); + } + break; + case CSR_RC_INVALID_PARAMETERS: + case CSR_RC_INSUFFICIENT_RESOURCE: + /* check for max retry limit & send again + * MAX_RETRY_LIMIT is not maintained for each set of transactions..Its generic + * If failure crosses this Limit, we have to take a call to FIX + */ + if (retryCount > UNIFI_MAX_RETRY_LIMIT) { + CsrBool moreData = FALSE; + retryCount = 0; + /* Because of continuos traffic in fh_cmd_q the tim set request is failing (exceeding retry limit) + * but if we didn't synchronize our timSet varible state with firmware then it can cause below issues + * cond 1. We want to SET tim in firmware if its fails & max retry limit reached + * -> If host set's the timSet to 1, we wont try to send(as max retry reached) update tim but + * firmware is not updated with queue(TIM) status so it wont set TIM in beacon finally host start piling + * up data & wont try to set tim in firmware (This can cause worser performance) + * cond 2. We want to reset tim in firmware it fails & reaches max retry limit + * -> If host sets the timSet to Zero, it wont try to set a TIM request unless we wont have any packets + * to be queued, so beacon unnecessarily advertizes the TIM + */ + + if(staRecord) { + if(!staRecord->wmmOrQosEnabled) { + moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) || + !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || + !list_empty(&staRecord->mgtFrames)); + } else { + /* Peer is QSTA */ + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); + /*check for more data in non-delivery enabled queues*/ + moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)); + + } + /* To avoid cond 1 & 2, check internal Queues status, if we have more Data then set RESET the timSet(0), + * so we are trying to be in sync with firmware & next packets before queuing atleast try to + * set TIM in firmware otherwise it SET timSet(1) + */ + if (moreData) { + staRecord->timSet = CSR_WIFI_TIM_RESET; + } else { + staRecord->timSet = CSR_WIFI_TIM_SET; + } + } else { + /* Its a broadcast frames */ + moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || + !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)); + if (moreData) { + update_tim(priv, 0, CSR_WIFI_TIM_SET, interfaceTag, 0xFFFFFFFF); + } else { + update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0xFFFFFFFF); + } + } + + unifi_error(priv, "no of error's for TIM setting crossed the Limit: verify\n"); + return; + } + retryCount++; + + if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) { + if (timSetStatus == staRecord->timSet) { + unifi_warning(priv, "tim request failed, retry for AID = %x\n", staRecord->aid); + update_tim(priv, staRecord->aid, timSetValue, interfaceTag, handle); + } else { + unifi_trace(priv, UDBG1, "failure: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x\n", + timSetStatus, staRecord->timSet); + } + } else { + unifi_warning(priv, "tim request failed, retry for broadcast frames\n"); + update_tim(priv, 0, timSetValue, interfaceTag, 0xFFFFFFFF); + } + break; + default: + unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode); + } + unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__); +} + +/* + * --------------------------------------------------------------------------- + * update_tim + * + * + * This function updates tim status in firmware for AID[1 to UNIFI_MAX_CONNECTIONS] or + * AID[0] for broadcast/multicast packets. + * + * NOTE: The LSB (least significant BYTE) of senderId while sending this MLME premitive + * has been modified(utilized) as below + * + * SenderID in signal's SignalPrimitiveHeader is 2 byte the lowe byte bitmap is below + * + * station handle(6 bits) timSet Status (2 bits) + * --------------------- ---------------------- + * 0 0 0 0 0 0 | 0 0 + * + * timSet Status can be one of below: + * + * CSR_WIFI_TIM_RESET + * CSR_WIFI_TIM_RESETTING + * CSR_WIFI_TIM_SET + * CSR_WIFI_TIM_SETTING + * + * Arguments: + * priv Pointer to device private context struct + * aid can be 1 t0 UNIFI_MAX_CONNECTIONS & 0 means multicast/broadcast + * setTim value SET(1) / RESET(0) + * interfaceTag the interfaceID on which activity going on + * handle from (0 <= handle < UNIFI_MAX_CONNECTIONS) + * + * --------------------------------------------------------------------------- + */ +void update_tim(unifi_priv_t * priv, CsrUint16 aid, CsrUint8 setTim, CsrUint16 interfaceTag, CsrUint32 handle) +{ + CSR_SIGNAL signal; + CsrInt32 r; + CSR_MLME_SET_TIM_REQUEST *req = &signal.u.MlmeSetTimRequest; + bulk_data_param_t *bulkdata = NULL; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrUint8 senderIdLsb = 0; + CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; + CsrUint32 oldTimSetStatus = 0, timSetStatus = 0; + + unifi_trace(priv, UDBG5, "entering the update_tim routine\n"); + + if (handle == 0xFFFFFFFF) { + handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE; + } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) { + unifi_warning(priv, "bad station Handle = %x\n", handle); + return; + } + + if (setTim) { + timSetStatus = CSR_WIFI_TIM_SETTING; + } else { + timSetStatus = CSR_WIFI_TIM_RESETTING; + } + + if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) { + if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) { + unifi_warning(priv, "station record is NULL in update_tim: handle = %x :debug\n", handle); + return; + } + /* In case of signal sending failed, revert back to old state */ + oldTimSetStatus = staRecord->timSet; + staRecord->timSet = timSetStatus; + } + + /* pack senderID LSB */ + senderIdLsb = CSR_WIFI_PACK_SENDER_ID_LSB_FOR_TIM_REQ(handle, timSetStatus); + + /* initialize signal to zero */ + memset(&signal, 0, sizeof(CSR_SIGNAL)); + + /* Frame the MLME-SET-TIM request */ + signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SET_TIM_REQUEST_ID; + signal.SignalPrimitiveHeader.ReceiverProcessId = 0; + CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->netdev_client->sender_id & 0xff00) | senderIdLsb), + (u8*)&signal.SignalPrimitiveHeader.SenderProcessId); + + /* set The virtual interfaceIdentifier, aid, tim value */ + req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag); + req->AssociationId = aid; + req->TimValue = setTim; + + + unifi_trace(priv, UDBG2, "update_tim:AID %x,senderIdLsb = 0x%x, handle = 0x%x, timSetStatus = %x, sender proceesID = %x \n", + aid,senderIdLsb, handle, timSetStatus, signal.SignalPrimitiveHeader.SenderProcessId); + + /* Send the signal to UniFi */ + r = ul_send_signal_unpacked(priv, &signal, bulkdata); + if (r) { + /* No need to free bulk data, as TIM request doesn't carries any data */ + unifi_error(priv, "Error queueing CSR_MLME_SET_TIM_REQUEST signal\n"); + if (staRecord) { + staRecord->timSet = oldTimSetStatus ; + } + } + unifi_trace(priv, UDBG5, "leaving the update_tim routine\n"); +} + +static +void process_peer_active_transition(unifi_priv_t * priv, + CsrWifiRouterCtrlStaInfo_t *staRecord, + CsrUint16 interfaceTag) +{ + int r,i; + CsrBool spaceAvail[4] = {TRUE,TRUE,TRUE,TRUE}; + tx_buffered_packets_t * buffered_pkt = NULL; + unsigned long lock_flags; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + unifi_trace(priv, UDBG5, "entering process_peer_active_transition\n"); + + if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) { + /* giving more priority to multicast packets so delaying unicast packets*/ + unifi_trace(priv,UDBG2," multicast transmission is going on so resume unicast transmission after DTIM over\n"); + return; + } + while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) { + unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n"); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->mgtFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[3]=(CsrUint8)(staRecord->assignedHandle); + spaceAvail[3] = FALSE; + break; + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + if (staRecord->txSuspend) { + if(staRecord->timSet == CSR_WIFI_TIM_SET) { + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + return; + } + for(i=3;i>=0;i--) { + if(!spaceAvail[i]) + continue; + unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i); + while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) { + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->dataPdu[i]); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[i]=(CsrUint8)(staRecord->assignedHandle); + break; + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + } + if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){ + unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n"); + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n"); +} + + + +void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,CsrUint16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm) +{ + netInterface_priv_t *interfacePriv; + CsrUint8 i; + CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; + struct list_head *listHeadMaPktreq,*listHeadStaQueue; + struct list_head *placeHolderMaPktreq,*placeHolderStaQueue; + unsigned long lock_flags; + unsigned long lock_flags1; + maPktReqList_t *maPktreq = NULL; + tx_buffered_packets_t *tx_q_item = NULL; + bulk_data_param_t bulkdata; + CsrBool entryFound = FALSE; + interfacePriv = priv->interfacePriv[interfaceTag]; + + + if(pkt_cfm->HostTag == interfacePriv->multicastPduHostTag) { + unifi_trace(priv,UDBG2,"CFM for marked Multicast Tag = %x\n",interfacePriv->multicastPduHostTag); + interfacePriv->multicastPduHostTag = 0xffffffff; + resume_suspended_uapsd(priv,interfaceTag); + resume_unicast_buffered_frames(priv,interfaceTag); + if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) && + list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { + unifi_trace(priv,UDBG1,"Resetting multicastTIM"); + update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF); + } + return; + } + + /* Check if a copy of the same frame (identified by host tag) is queued in driver */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) { + maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q); + if(maPktreq->hostTag == pkt_cfm->HostTag){ + entryFound = TRUE; + break; + } + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + + if(entryFound){ + + /* Monitor the time difference between the MA-PACKET.req and MA-PACKET.cfm */ + unsigned long timeout; + timeout = (long)jiffies - (long)maPktreq->jiffeTime; + + /* convert into milliseconds */ + timeout = jiffies_to_msecs(timeout); + unifi_trace(priv, UDBG3, "Jiffies Time: Host Tag(%x) --> Req(%u) Cfm(%u) Diff (in ms): %u\n",maPktreq->hostTag,maPktreq->jiffeTime, jiffies, timeout); + + if( (timeout/1000) > 1) + { + unifi_trace(priv, UDBG1, "Confirm time > 2 Seconds: time = %u Status = %x\n", (timeout/1000), pkt_cfm->TransmissionStatus); + } + + if( CSR_TX_LIFETIME == pkt_cfm->TransmissionStatus || + CSR_TX_BLOCK_ACK_TIMEOUT== pkt_cfm->TransmissionStatus || + CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED== pkt_cfm->TransmissionStatus || + CSR_TX_REJECTED_PEER_STATION_SLEEPING== pkt_cfm->TransmissionStatus || + CSR_TX_REJECTED_DTIM_STARTED== pkt_cfm->TransmissionStatus ){ + + CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler]; + unifi_TrafficQueue priority_q; + struct list_head *list; + CsrResult result; + CSR_MA_PACKET_REQUEST *req = &maPktreq->signal.u.MaPacketRequest; + CsrUint16 ii=0; + CsrBool locationFound = FALSE; + CsrUint8 *sigbuffer; + + sigbuffer = (CsrUint8*)&maPktreq->signal; + if(req->Priority == CSR_MANAGEMENT){ + list = &staRecord->mgtFrames; + unifi_trace(priv,UDBG5,"mgmt list priority %d\n",req->Priority); + } + else{ + priority_q= unifi_frame_priority_to_queue(req->Priority); + list = &staRecord->dataPdu[priority_q]; + unifi_trace(priv,UDBG5,"data list priority %d\n",req->Priority); + } + + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHeadStaQueue, placeHolderStaQueue, list){ + tx_q_item = list_entry(listHeadStaQueue, tx_buffered_packets_t, q); + COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item->hostTag ,maPktreq->hostTag) + + + } + if(sigbuffer[SIZEOF_SIGNAL_HEADER + 1]){ + skb_pull(maPktreq->skb,sigbuffer[SIZEOF_SIGNAL_HEADER + 1]); + } + + /* enqueue the failed packet sta queue*/ + bulkdata.d[0].os_net_buf_ptr= (unsigned char*)maPktreq->skb; + bulkdata.d[0].os_data_ptr = maPktreq->skb->data; + bulkdata.d[0].data_length = bulkdata.d[0].net_buf_length = maPktreq->skb->len; + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].os_net_buf_ptr = NULL; + bulkdata.d[1].data_length = bulkdata.d[0].net_buf_length = 0; + unifi_trace(priv,UDBG4,"Cfm Fail for HosTag = %x with status %d so requeue it\n",maPktreq->hostTag,pkt_cfm->TransmissionStatus ); + req->TransmissionControl = 0; + + if(!locationFound){ + + if(list_empty(list)){ + result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1); + } + else{ + unifi_trace(priv,UDBG4,"did not find location so add to end of list \n"); + result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,0); + } + + + } + + else { + if(ii > 1){ + unifi_trace(priv,UDBG4,"find the location in the middle of list \n"); + result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, listHeadStaQueue,&maPktreq->signal,0); + + } + else{ + unifi_trace(priv,UDBG4," add at begining of list \n"); + result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1); + } + } + + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + + /* Increment the counter */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags1); + staRecord->noOfPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags1); + + + + + /* after enqueuing update the TIM */ + if(CSR_RESULT_SUCCESS == result){ + if(CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE == staRecord->currentPeerState) { + if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) { + if(!staRecord->wmmOrQosEnabled) { + unifi_trace(priv, UDBG3, "uf_process_ma_pkt_cfm_for_ap :tim set due to unicast pkt & peer in powersave\n"); + update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle); + } + else { + /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */ + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); + if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) { + update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle); + } + } + } + } + } + else{ + dev_kfree_skb(maPktreq->skb); + } + } + else + { + CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler]; + if (CSR_TX_RETRY_LIMIT == pkt_cfm->TransmissionStatus || + CSR_TX_NO_BSS == pkt_cfm->TransmissionStatus) + { + if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) + { + unifi_trace(priv, UDBG2, "CFM failed with Retry Limit or No BSS --> update TIM\n"); + update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle); + } + } + else if (CSR_TX_SUCCESSFUL == pkt_cfm->TransmissionStatus) + { + staRecord->activity_flag = TRUE; + } + unifi_trace(priv, UDBG5, "CFM for HosTag = %x Status = %d, Free SKB reference\n", + maPktreq->hostTag, + pkt_cfm->TransmissionStatus ); + + dev_kfree_skb(maPktreq->skb); + + } + list_del(listHeadMaPktreq); + kfree(maPktreq); + + }else{ + /* Check if it is a Confirm for null data frame used + * for probing station activity + */ + for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) { + staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]); + if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) { + + unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n", + pkt_cfm->HostTag, + pkt_cfm->TransmissionStatus + ); + staRecord->nullDataHostTag = INVALID_HOST_TAG; + + if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){ + CsrTime now; + CsrTime inactive_time; + + unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n"); + /* Recheck if there is some activity after null data is sent. + * + * If still there is no activity then send a disconnected indication + * to SME to delete the station record. + */ + if (staRecord->activity_flag){ + return; + } + now = CsrTimeGet(NULL); + + if (staRecord->lastActivity > now) + { + /* simple timer wrap (for 1 wrap) */ + inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity), + now); + } + else + { + inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity); + } + + if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) + { + struct list_head send_cfm_list; + CsrUint8 j; + + /* The SME/NME may be waiting for confirmation for requested frames to this station. + * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a + * a defensive check, it loops through buffered frames for this station and if confirmation + * is requested, send auto confirmation with failure status. Also flush the frames so + * that these are not processed again in PEER_DEL_REQ handler. + */ + INIT_LIST_HEAD(&send_cfm_list); + + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staRecord->mgtFrames)); + + uf_flush_list(priv, &(staRecord->mgtFrames)); + + for(j = 0; j < MAX_ACCESS_CATOGORY; j++){ + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staRecord->dataPdu[j])); + + uf_flush_list(priv,&(staRecord->dataPdu[j])); + } + + send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list); + + + + unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n", + staRecord->peerMacAddress.a[0], + staRecord->peerMacAddress.a[1], + staRecord->peerMacAddress.a[2], + staRecord->peerMacAddress.a[3], + staRecord->peerMacAddress.a[4], + staRecord->peerMacAddress.a[5]); + + CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, + 0, + staRecord->interfacePriv->InterfaceTag, + staRecord->peerMacAddress, + CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED); + } + + } + else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL) + { + staRecord->activity_flag = TRUE; + } + } + } + } +} + +#endif +CsrUint16 uf_get_vif_identifier (CsrWifiRouterCtrlMode mode, CsrUint16 tag) +{ + switch(mode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + return (0x02<<8|tag); + + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + return (0x03<<8|tag); + + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + return (0x01<<8|tag); + + case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR: + return (0x04<<8|tag); + case CSR_WIFI_ROUTER_CTRL_MODE_AMP: + return (0x05<<8|tag); + default: + return tag; + } +} + +#ifdef CSR_SUPPORT_SME + +/* + * --------------------------------------------------------------------------- + * update_macheader + * + * + * These functions updates mac header for intra BSS packet + * routing. + * NOTE: This function always has to be called in rx context which + * is in bh thread context since GFP_KERNEL is used. In soft IRQ/ Interrupt + * context shouldn't be used + * + * Arguments: + * priv Pointer to device private context struct + * skb Socket buffer containing data packet to transmit + * newSkb Socket buffer containing data packet + Mac header if no sufficient headroom in skb + * priority to append QOS control header in Mac header + * bulkdata if newSkb allocated then bulkdata updated to send to unifi + * interfaceTag the interfaceID on which activity going on + * macHeaderLengthInBytes no. of bytes of mac header in received frame + * qosDestination used to append Qos control field + * + * Returns: + * Zero on success or -1 on error. + * --------------------------------------------------------------------------- + */ + +static int update_macheader(unifi_priv_t *priv, struct sk_buff *skb, + struct sk_buff *newSkb, CSR_PRIORITY *priority, + bulk_data_param_t *bulkdata, CsrUint16 interfaceTag, + CsrUint8 macHeaderLengthInBytes, + CsrUint8 qosDestination) +{ + + CsrUint16 *fc = NULL; + CsrUint8 direction = 0, toDs, fromDs; + CsrUint8 *bufPtr = NULL; + CsrUint8 sa[ETH_ALEN], da[ETH_ALEN]; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + int headroom; + CsrUint8 macHeaderBuf[IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE] = {0}; + + unifi_trace(priv, UDBG5, "entering the update_macheader function\n"); + + /* temporary buffer for the Mac header storage */ + memcpy(macHeaderBuf, skb->data, macHeaderLengthInBytes); + + /* remove the Macheader from the skb */ + skb_pull(skb, macHeaderLengthInBytes); + + /* get the skb headroom for skb_push check */ + headroom = skb_headroom(skb); + + /* pointer to frame control field */ + fc = (CsrUint16*) macHeaderBuf; + + toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0; + fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0; + unifi_trace(priv, UDBG5, "In update_macheader function, fromDs = %x, toDs = %x\n", fromDs, toDs); + direction = ((fromDs | (toDs << 1)) & 0x3); + + /* Address1 or 3 from the macheader */ + memcpy(da, macHeaderBuf+4+toDs*12, ETH_ALEN); + /* Address2, 3 or 4 from the mac header */ + memcpy(sa, macHeaderBuf+10+fromDs*(6+toDs*8), ETH_ALEN); + + unifi_trace(priv, UDBG3, "update_macheader:direction = %x\n", direction); + /* update the toDs, fromDs & address fields in Mac header */ + switch(direction) + { + case 2: + /* toDs = 1 & fromDs = 0 , toAp when frames received from peer + * while sending this packet to Destination the Mac header changed + * as fromDs = 1 & toDs = 0, fromAp + */ + *fc &= cpu_to_le16(~IEEE802_11_FC_TO_DS_MASK); + *fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK); + /* Address1: MAC address of the actual destination (4 = 2+2) */ + memcpy(macHeaderBuf + 4, da, ETH_ALEN); + /* Address2: The MAC address of the AP (10 = 2+2+6) */ + memcpy(macHeaderBuf + 10, &interfacePriv->bssid, ETH_ALEN); + /* Address3: MAC address of the actual source from mac header (16 = 2+2+6+6) */ + memcpy(macHeaderBuf + 16, sa, ETH_ALEN); + break; + case 3: + unifi_trace(priv, UDBG3, "when both the toDs & fromDS set, NOT SUPPORTED\n"); + break; + default: + unifi_trace(priv, UDBG3, "problem in decoding packet in update_macheader \n"); + return -1; + } + + /* frameType is Data always, Validation is done before calling this function */ + + /* check for the souce station type */ + switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK) + { + case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK: + /* No need to modify the qos control field */ + if (!qosDestination) { + + /* If source Sta is QOS enabled & if this bit set, then HTC is supported by + * peer station & htc field present in macHeader + */ + if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { + /* HT control field present in Mac header + * 6 = sizeof(qosControl) + sizeof(htc) + */ + macHeaderLengthInBytes -= 6; + } else { + macHeaderLengthInBytes -= 2; + } + /* Destination STA is non qos so change subtype to DATA */ + *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK); + *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA); + /* remove the qos control field & HTC(if present). new macHeaderLengthInBytes is less than old + * macHeaderLengthInBytes so no need to verify skb headroom + */ + if (headroom < macHeaderLengthInBytes) { + unifi_trace(priv, UDBG1, " sufficient headroom not there to push updated mac header \n"); + return -1; + } + bufPtr = (CsrUint8 *) skb_push(skb, macHeaderLengthInBytes); + + /* update bulk data os_data_ptr */ + bulkdata->d[0].os_data_ptr = skb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata->d[0].data_length = skb->len; + + } else { + /* pointing to QOS control field */ + CsrUint8 qc; + if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { + qc = *((CsrUint8*)(macHeaderBuf + (macHeaderLengthInBytes - 4 - 2))); + } else { + qc = *((CsrUint8*)(macHeaderBuf + (macHeaderLengthInBytes - 2))); + } + + if ((qc & IEEE802_11_QC_TID_MASK) > 7) { + *priority = 7; + } else { + *priority = qc & IEEE802_11_QC_TID_MASK; + } + + unifi_trace(priv, UDBG1, "Incoming packet priority from QSTA is %x\n", *priority); + + if (headroom < macHeaderLengthInBytes) { + unifi_trace(priv, UDBG3, " sufficient headroom not there to push updated mac header \n"); + return -1; + } + bufPtr = (CsrUint8 *) skb_push(skb, macHeaderLengthInBytes); + } + break; + default: + { + bulk_data_param_t data_ptrs; + CsrResult csrResult; + unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n"); + + *priority = CSR_CONTENTION; + if (qosDestination) { + CsrUint8 qc = 0; + unifi_trace(priv, UDBG3, "destination is QOS station \n"); + /* prepare the qos control field */ + + qc |= CSR_QOS_UP0; + + /* no Amsdu is in ap buffer so eosp is left 0 */ + + if (da[0] & 0x1) { + /* multicast/broadcast frames, no acknowledgement needed */ + qc |= 1 << 5; + } + + /* update new Mac header Length with 2 = sizeof(qos control) */ + macHeaderLengthInBytes += 2; + + /* received DATA frame but destiantion is QOS station so update subtype to QOS*/ + *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK); + *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA); + + /* appendQosControlOffset = macHeaderLengthInBytes - 2, since source sta is not QOS */ + macHeaderBuf[macHeaderLengthInBytes - 2] = qc; + /* txopLimit is 0 */ + macHeaderBuf[macHeaderLengthInBytes - 1] = 0; + if (headroom < macHeaderLengthInBytes) { + csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, " failed to allocate request_data. in update_macheader func\n"); + return -1; + } + newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr); + newSkb->len = skb->len + macHeaderLengthInBytes; + + memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes, + skb->data, skb->len); + + bulkdata->d[0].os_data_ptr = newSkb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb; + bulkdata->d[0].data_length = newSkb->len; + + bufPtr = (CsrUint8*)data_ptrs.d[0].os_data_ptr; + + /* The old skb will not be used again */ + kfree_skb(skb); + } else { + /* skb headroom is sufficient to append Macheader */ + bufPtr = (CsrUint8*)skb_push(skb, macHeaderLengthInBytes); + bulkdata->d[0].os_data_ptr = skb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata->d[0].data_length = skb->len; + } + } else { + unifi_trace(priv, UDBG3, "destination is not a QSTA\n"); + if (headroom < macHeaderLengthInBytes) { + csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, " failed to allocate request_data. in update_macheader func\n"); + return -1; + } + newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr); + newSkb->len = skb->len + macHeaderLengthInBytes; + + memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes, + skb->data, skb->len); + + bulkdata->d[0].os_data_ptr = newSkb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb; + bulkdata->d[0].data_length = newSkb->len; + + bufPtr = (CsrUint8*)data_ptrs.d[0].os_data_ptr; + + /* The old skb will not be used again */ + kfree_skb(skb); + } else { + /* skb headroom is sufficient to append Macheader */ + bufPtr = (CsrUint8*)skb_push(skb, macHeaderLengthInBytes); + bulkdata->d[0].os_data_ptr = skb->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata->d[0].data_length = skb->len; + } + } + } + } + + /* prepare the complete skb, by pushing the MAC header to the begining of the skb->data */ + unifi_trace(priv, UDBG5, "updated Mac Header: %d \n",macHeaderLengthInBytes); + memcpy(bufPtr, macHeaderBuf, macHeaderLengthInBytes); + + unifi_trace(priv, UDBG5, "leaving the update_macheader function\n"); + return 0; +} +/* + * --------------------------------------------------------------------------- + * uf_ap_process_data_pdu + * + * + * Takes care of intra BSS admission control & routing packets within BSS + * + * Arguments: + * priv Pointer to device private context struct + * skb Socket buffer containing data packet to transmit + * ehdr ethernet header to fetch priority of packet + * srcStaInfo source stations record for connection verification + * packed_signal + * signal_len + * signal MA-PACKET.indication signal + * bulkdata if newSkb allocated then bulkdata updated to send to unifi + * macHeaderLengthInBytes no. of bytes of mac header in received frame + * + * Returns: + * Zero on success(ap processing complete) or -1 if packet also have to be sent to NETDEV. + * --------------------------------------------------------------------------- + */ +int +uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb, + struct ethhdr *ehdr, CsrWifiRouterCtrlStaInfo_t * srcStaInfo, + const CSR_SIGNAL *signal, + bulk_data_param_t *bulkdata, + CsrUint8 macHeaderLengthInBytes) +{ + const CSR_MA_PACKET_INDICATION *ind = &(signal->u.MaPacketIndication); + CsrUint16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0x00ff); + struct sk_buff *newSkb = NULL; + /* pointer to skb or private skb created using skb_copy() */ + struct sk_buff *skbPtr = skb; + CsrBool sendToNetdev = FALSE; + CsrBool qosDestination = FALSE; + CSR_PRIORITY priority = CSR_CONTENTION; + CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL; + netInterface_priv_t *interfacePriv; + + unifi_trace(priv, UDBG5, "entering uf_ap_process_data_pdu %d\n",macHeaderLengthInBytes); + /* InterfaceTag validation from MA_PACKET.indication */ + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_trace(priv, UDBG1, "Interface Tag is Invalid in uf_ap_process_data_pdu\n"); + unifi_net_data_free(priv, &bulkdata->d[0]); + return 0; + } + interfacePriv = priv->interfacePriv[interfaceTag]; + + if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) && + (interfacePriv->intraBssEnabled == FALSE)) { + unifi_trace(priv, UDBG2, "uf_ap_process_data_pdu:P2P GO intrabssEnabled?= %d\n", interfacePriv->intraBssEnabled); + + /*In P2P GO case, if intraBSS distribution Disabled then don't do IntraBSS routing */ + /* If destination in our BSS then drop otherwise give packet to netdev */ + dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag); + if (dstStaInfo) { + unifi_net_data_free(priv, &bulkdata->d[0]); + return 0; + } + /* May be associated P2PCLI trying to send the packets on backbone (Netdev) */ + return -1; + } + + if(!memcmp(ehdr->h_dest, interfacePriv->bssid.a, ETH_ALEN)) { + /* This packet will be given to the TCP/IP stack since this packet is for us(AP) + * No routing needed */ + unifi_trace(priv, UDBG4, "destination address is csr_ap\n"); + return -1; + } + + /* fetch the destination record from staion record database */ + dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag); + + /* AP mode processing, & if packet is unicast */ + if(!dstStaInfo) { + if (!(ehdr->h_dest[0] & 0x1)) { + /* destination not in station record & its a unicast packet, so pass the packet to network stack */ + unifi_trace(priv, UDBG3, "unicast frame & destination record not exist, send to netdev proto = %x\n", htons(skb->protocol)); + return -1; + } else { + /* packet is multicast/broadcast */ + /* copy the skb to skbPtr, send skb to netdev & skbPtr to multicast/broad cast list */ + unifi_trace(priv, UDBG5, "skb_copy, in uf_ap_process_data_pdu, protocol = %x\n", htons(skb->protocol)); + skbPtr = skb_copy(skb, GFP_KERNEL); + if(skbPtr == NULL) { + /* We don't have memory to don't send the frame in BSS*/ + unifi_notice(priv, "broacast/multicast frame can't be sent in BSS No memeory: proto = %x\n", htons(skb->protocol)); + return -1; + } + sendToNetdev = TRUE; + } + } else { + + /* validate the Peer & Destination Station record */ + if (uf_process_station_records_for_sending_data(priv, interfaceTag, srcStaInfo, dstStaInfo)) { + unifi_notice(priv, "uf_ap_process_data_pdu: station record validation failed \n"); + interfacePriv->stats.rx_errors++; + unifi_net_data_free(priv, &bulkdata->d[0]); + return 0; + } + } + + /* BroadCast packet received and it's been sent as non QOS packets. + * Since WMM spec not mandates broadcast/multicast to be sent as QOS data only, + * if all Peers are QSTA + */ + if(sendToNetdev) { + /* BroadCast packet and it's been sent as non QOS packets */ + qosDestination = FALSE; + } else if(dstStaInfo && (dstStaInfo->wmmOrQosEnabled == TRUE)) { + qosDestination = TRUE; + } + + unifi_trace(priv, UDBG3, "uf_ap_process_data_pdu QoS destination = %s\n", (qosDestination)? "TRUE": "FALSE"); + + /* packet is allowed to send to unifi, update the Mac header */ + if (update_macheader(priv, skbPtr, newSkb, &priority, bulkdata, interfaceTag, macHeaderLengthInBytes, qosDestination)) { + interfacePriv->stats.rx_errors++; + unifi_notice(priv, "(Packet Drop) failed to update the Mac header in uf_ap_process_data_pdu\n"); + if (sendToNetdev) { + /* Free's the skb_copy(skbPtr) data since packet processing failed */ + bulkdata->d[0].os_data_ptr = skbPtr->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr; + bulkdata->d[0].data_length = skbPtr->len; + unifi_net_data_free(priv, &bulkdata->d[0]); + } + return -1; + } + + unifi_trace(priv, UDBG3, "Mac Header updated...calling uf_process_ma_packet_req \n"); + + /* Packet is ready to send to unifi ,transmissionControl = 0x0004, confirmation is not needed for data packets */ + if (uf_process_ma_packet_req(priv, ehdr->h_dest, 0xffffffff, interfaceTag, CSR_NO_CONFIRM_REQUIRED, (CSR_RATE)0,priority, priv->netdev_client->sender_id, bulkdata)) { + if (sendToNetdev) { + unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop) uf_process_ma_packet_req failed. freeing skb_copy data (original data sent to Netdev)\n"); + /* Free's the skb_copy(skbPtr) data since packet processing failed */ + bulkdata->d[0].os_data_ptr = skbPtr->data; + bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr; + bulkdata->d[0].data_length = skbPtr->len; + unifi_net_data_free(priv, &bulkdata->d[0]); + } else { + /* This free's the skb data */ + unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop). Unicast data so freeing original skb \n"); + unifi_net_data_free(priv, &bulkdata->d[0]); + } + } + unifi_trace(priv, UDBG5, "leaving uf_ap_process_data_pdu\n"); + + if (sendToNetdev) { + /* The packet is multicast/broadcast, so after AP processing packet has to + * be sent to netdev, if peer port state is open + */ + unifi_trace(priv, UDBG4, "Packet will be routed to NetDev\n"); + return -1; + } + /* Ap handled the packet & its a unicast packet, no need to send to netdev */ + return 0; +} + +#endif + +CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, + CsrUint8 *peerMacAddress, + CSR_CLIENT_TAG hostTag, + CsrUint16 interfaceTag, + CSR_TRANSMISSION_CONTROL transmissionControl, + CSR_RATE TransmitRate, + CSR_PRIORITY priority, + CSR_PROCESS_ID leSenderProcessId, + bulk_data_param_t *bulkdata) +{ + CsrResult status = CSR_RESULT_SUCCESS; + CSR_SIGNAL signal; + int result; +#ifdef CSR_SUPPORT_SME + CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; + const CsrUint8 *macHdrLocation = bulkdata->d[0].os_data_ptr; + CsrWifiPacketType pktType; + int frameType = 0; + CsrBool queuePacketDozing = FALSE; + CsrUint32 priority_q; + CsrUint16 frmCtrl; + struct list_head * list = NULL; /* List to which buffered PDUs are to be enqueued*/ + CsrBool setBcTim=FALSE; + netInterface_priv_t *interfacePriv; + CsrBool requeueOnSamePos = FALSE; + CsrUint32 handle = 0xFFFFFFFF; + unsigned long lock_flags; + + UF_TRACE_MAC(priv, UDBG5, "entering uf_process_ma_packet_req, peer: ", peerMacAddress); + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag); + return CSR_RESULT_FAILURE; + } + interfacePriv = priv->interfacePriv[interfaceTag]; + + + /* fetch the station record for corresponding peer mac address */ + if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag))) { + handle = staRecord->assignedHandle; + } + + /* Frame ma-packet.req, this is saved/transmitted depend on queue state */ + unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag, + interfaceTag, transmissionControl, leSenderProcessId, + peerMacAddress, &signal); + + /* Since it's common path between STA & AP mode, in case of STA packet + * need not to be queued but in AP case we have to queue PDU's in + * different scenarios + */ + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + /* For this mode processing done below */ + break; + default: + /* In case of STA/IBSS/P2PCLI/AMP, no checks needed send the packet down & return */ + unifi_trace(priv, UDBG5, "In %s, interface mode is %x \n", __FUNCTION__, interfacePriv->interfaceMode); + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) { + unifi_warning(priv, "In %s, interface mode NONE \n", __FUNCTION__); + } + if ((result = ul_send_signal_unpacked(priv, &signal, bulkdata))) { + status = CSR_RESULT_FAILURE; + } + return status; + } + + /* -----Only AP/P2pGO mode handling falls below----- */ + + /* convert priority to queue */ + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); + + /* check the powersave status of the peer */ + if (staRecord && (staRecord->currentPeerState == + CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)) { + /* Peer is dozing & packet have to be delivered, so buffer the packet & + * update the TIM + */ + queuePacketDozing = TRUE; + } + + /* find the type of frame unicast or mulicast/broadcast */ + if (*peerMacAddress & 0x1) { + /* Multicast/broadCast data are always triggered by vif_availability.ind + * at the DTIM + */ + pktType = CSR_WIFI_MULTICAST_PDU; + } else { + pktType = CSR_WIFI_UNICAST_PDU; + } + + /* Fetch the frame control field from mac header & check for frame type */ + frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation); + + /* Processing done according to Frame/Packet type */ + frameType = ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET); + switch(frameType) + { + case IEEE802_11_FRAMETYPE_MANAGEMENT: + + switch(pktType) + { + case CSR_WIFI_UNICAST_PDU: + unifi_trace(priv, UDBG5, "management unicast PDU in uf_process_ma_packet_req \n"); + /* push the packet in to the queue with appropriate mgt list */ + if (!staRecord) { + /* push the packet to the unifi if list is empty (if packet lost how to re-enque) */ + if (list_empty(&interfacePriv->genericMgtFrames)) { +#ifdef CSR_SUPPORT_SME + if(!(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) { +#endif + + unifi_trace(priv, UDBG3, "genericMgtFrames list is empty uf_process_ma_packet_req \n"); + result = ul_send_signal_unpacked(priv, &signal, bulkdata); + /* reque only on ENOSPC */ + if(result == -ENOSPC) { + /* requeue the failed packet to genericMgtFrame with same position */ + unifi_trace(priv, UDBG1, "(ENOSPC) Sending genericMgtFrames Failed so buffering\n"); + list = &interfacePriv->genericMgtFrames; + requeueOnSamePos = TRUE; + } +#ifdef CSR_SUPPORT_SME + }else{ + list = &interfacePriv->genericMgtFrames; + unifi_trace(priv, UDBG3, "genericMgtFrames queue empty and dtim started\n hosttag is 0x%x,\n",signal.u.MaPacketRequest.HostTag); + update_eosp_to_head_of_broadcast_list_head(priv,interfaceTag); + } +#endif + } else { + /* Queue the packet to genericMgtFrame of unifi_priv_t data structure */ + list = &interfacePriv->genericMgtFrames; + unifi_trace(priv, UDBG2, "genericMgtFrames queue not empty\n"); + } + } else { + /* check peer power state */ + if (queuePacketDozing || !list_empty(&staRecord->mgtFrames) || IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) { + /* peer is in dozing mode, so queue packet in mgt frame list of station record */ + /*if multicast traffic is going on, buffer the unicast packets*/ + list = &staRecord->mgtFrames; + + unifi_trace(priv, UDBG1, "staRecord->MgtFrames list empty? = %s, handle = %d, queuePacketDozing = %d\n", + (list_empty(&staRecord->mgtFrames))? "YES": "NO", staRecord->assignedHandle, queuePacketDozing); + if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)){ + update_eosp_to_head_of_broadcast_list_head(priv,interfaceTag); + } + + } else { + unifi_trace(priv, UDBG5, "staRecord->mgtFrames list is empty uf_process_ma_packet_req \n"); + result = ul_send_signal_unpacked(priv, &signal, bulkdata); + if(result == -ENOSPC) { + /* requeue the failed packet to staRecord->mgtFrames with same position */ + list = &staRecord->mgtFrames; + requeueOnSamePos = TRUE; + unifi_trace(priv, UDBG1, "(ENOSPC) Sending MgtFrames Failed handle = %d so buffering\n",staRecord->assignedHandle); + priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle); + } else if (result) { + status = CSR_RESULT_FAILURE; + } + } + } + break; + case CSR_WIFI_MULTICAST_PDU: + unifi_trace(priv, UDBG5, "management multicast/broadcast PDU in uf_process_ma_packet_req 'QUEUE it' \n"); + /* Queue the packet to genericMulticastOrBroadCastMgtFrames of unifi_priv_t data structure + * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM + */ + + list = &interfacePriv->genericMulticastOrBroadCastMgtFrames; + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + interfacePriv->noOfbroadcastPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) && + (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { + setBcTim=TRUE; + } + break; + default: + unifi_error(priv, "condition never meets: packet type unrecognized\n"); + } + break; + case IEEE802_11_FRAMETYPE_DATA: + switch(pktType) + { + case CSR_WIFI_UNICAST_PDU: + unifi_trace(priv, UDBG5, "data unicast PDU in uf_process_ma_packet_req \n"); + /* check peer power state, list status & peer port status */ + if(!staRecord) { + unifi_error(priv, "In %s unicast but staRecord = NULL\n", __FUNCTION__); + return CSR_RESULT_FAILURE; + } else if (queuePacketDozing || isRouterBufferEnabled(priv,priority_q)|| !list_empty(&staRecord->dataPdu[priority_q]) || IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) { + /* peer is in dozing mode, so queue packet in mgt frame list of station record */ + /* if multicast traffic is going on, buffet the unicast packets */ + unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\ + Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q)); + signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED); + list = &staRecord->dataPdu[priority_q]; + } else { + unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q); + signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED); + /* Pdu allowed to send to unifi */ + result = ul_send_signal_unpacked(priv, &signal, bulkdata); + if(result == -ENOSPC) { + /* requeue the failed packet to staRecord->dataPdu[priority_q] with same position */ + unifi_trace(priv, UDBG1, "(ENOSPC) Sending Unicast DataPDU to queue %d Failed so buffering\n",priority_q); + requeueOnSamePos = TRUE; + list = &staRecord->dataPdu[priority_q]; + priv->pausedStaHandle[priority_q]=(CsrUint8)(staRecord->assignedHandle); + if(!isRouterBufferEnabled(priv,priority_q)) { + unifi_error(priv,"Buffering Not enabled for queue %d \n",priority_q); + } + } else if (result) { + status = CSR_RESULT_FAILURE; + } + } + break; + case CSR_WIFI_MULTICAST_PDU: + unifi_trace(priv, UDBG5, "data multicast/broadcast PDU in uf_process_ma_packet_req \n"); + /* Queue the packet to genericMulticastOrBroadCastFrames list of unifi_priv_t data structure + * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM + */ + list = &interfacePriv->genericMulticastOrBroadCastFrames; + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + interfacePriv->noOfbroadcastPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { + setBcTim = TRUE; + } + break; + default: + unifi_error(priv, "condition never meets: packet type un recognized\n"); + } + break; + default: + unifi_error(priv, "unrecognized frame type\n"); + } + if(list) { + status = enque_tx_data_pdu(priv, bulkdata,list, &signal,requeueOnSamePos); + /* Record no. of packet queued for each peer */ + if (staRecord && (pktType == CSR_WIFI_UNICAST_PDU) && (!status)) { + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staRecord->noOfPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } + } + if(setBcTim) { + unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n"); + update_tim(priv,0,1,interfaceTag, handle); + } else if(staRecord && staRecord->currentPeerState == + CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) { + if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) { + if(!staRecord->wmmOrQosEnabled) { + if(!list_empty(&staRecord->mgtFrames) || + !list_empty(&staRecord->dataPdu[3]) || + !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) { + unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n"); + update_tim(priv,staRecord->aid,1,interfaceTag, handle); + } + } else { + /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */ + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); + if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) { + update_tim(priv,staRecord->aid,1,interfaceTag, handle); + } + } + } + } + + if((list) && (pktType == CSR_WIFI_UNICAST_PDU && !queuePacketDozing) && !(isRouterBufferEnabled(priv,priority_q)) && !(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) { + unifi_trace(priv, UDBG2, "buffering cleared for queue = %d So resending buffered frames\n",priority_q); + uf_send_buffered_frames(priv, priority_q); + } + unifi_trace(priv, UDBG5, "leaving uf_process_ma_packet_req \n"); + return status; +#else +#ifdef CSR_NATIVE_LINUX + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag); + return CSR_RESULT_FAILURE; + } + /* Frame ma-packet.req, this is saved/transmitted depend on queue state */ + unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag, interfaceTag, + transmissionControl, leSenderProcessId, + peerMacAddress, &signal); + result = ul_send_signal_unpacked(priv, &signal, bulkdata); + if (result) { + return CSR_RESULT_FAILURE; + } +#endif + return status; +#endif +} + +#ifdef CSR_SUPPORT_SME +CsrInt8 uf_get_protection_bit_from_interfacemode(unifi_priv_t *priv, CsrUint16 interfaceTag, const CsrUint8 *daddr) +{ + CsrInt8 protection = 0; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + switch(interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_STA: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI: + case CSR_WIFI_ROUTER_CTRL_MODE_AMP: + case CSR_WIFI_ROUTER_CTRL_MODE_IBSS: + protection = interfacePriv->protect; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + { + CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL; + if (daddr[0] & 0x1) { + unifi_trace(priv, UDBG3, "broadcast/multicast packet in send_ma_pkt_request\n"); + /* In this mode, the protect member of priv structure has an information of how + * AP/P2PGO has started, & the member updated in set mode request for AP/P2PGO + */ + protection = interfacePriv->protect; + } else { + /* fetch the destination record from staion record database */ + dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, daddr, interfaceTag); + if (!dstStaInfo) { + unifi_trace(priv, UDBG3, "peer not found in station record in send_ma_pkt_request\n"); + return -1; + } + protection = dstStaInfo->protection; + } + } + break; + default: + unifi_trace(priv, UDBG2, "mode unknown in send_ma_pkt_request\n"); + } + return protection; +} +#endif +#ifdef CSR_SUPPORT_SME +CsrUint8 send_multicast_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) +{ + int r; + tx_buffered_packets_t * buffered_pkt = NULL; + CsrBool moreData = FALSE; + CsrUint8 pduSent =0; + unsigned long lock_flags; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrUint32 hostTag = 0xffffffff; + + func_enter(); + if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) { + while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK); + moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE; + + + unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag); + + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) { + unifi_trace(priv,UDBG1,"frame_and_send_queued_pdu failed with ENOSPC for host tag = %x\n", buffered_pkt->hostTag); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastMgtFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + break; + } else { + unifi_trace(priv,UDBG1,"send_multicast_frames: Send genericMulticastOrBroadCastMgtFrames (%x, %x)\n", + buffered_pkt->hostTag, + r); + if(r) { + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + if(!moreData) { + + interfacePriv->dtimActive = FALSE; + if(!r) { + hostTag = buffered_pkt->hostTag; + pduSent++; + } else { + send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_UNSPECIFIED_FAILURE); + } + } + /* Buffered frame sent successfully */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + interfacePriv->noOfbroadcastPktQueued--; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + kfree(buffered_pkt); + } + + } + } + if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) { + while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) { + buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; + moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE; + + + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + break; + } else { + if(r) { + unifi_trace(priv,UDBG1,"send_multicast_frames: Send genericMulticastOrBroadCastFrame failed (%x, %x)\n", + buffered_pkt->hostTag, + r); + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + if(!moreData) { + interfacePriv->dtimActive = FALSE; + if(!r) { + pduSent ++; + hostTag = buffered_pkt->hostTag; + } else { + send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_UNSPECIFIED_FAILURE); + } + } + /* Buffered frame sent successfully */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + interfacePriv->noOfbroadcastPktQueued--; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + kfree(buffered_pkt); + } + } + } + if((interfacePriv->dtimActive == FALSE)) { + /* Record the host Tag*/ + unifi_trace(priv,UDBG2,"send_multicast_frames: Recorded hostTag of EOSP packet: = 0x%x\n",hostTag); + interfacePriv->multicastPduHostTag = hostTag; + } + return pduSent; +} +#endif +void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,CsrUint8 *sigdata, + CsrUint32 siglen) +{ +#ifdef CSR_SUPPORT_SME + CSR_SIGNAL signal; + CSR_MA_VIF_AVAILABILITY_INDICATION *ind; + int r; + CsrUint16 interfaceTag; + CsrUint8 pduSent =0; + CSR_RESULT_CODE resultCode = CSR_RC_SUCCESS; + netInterface_priv_t *interfacePriv; + + func_enter(); + unifi_trace(priv, UDBG3, + "uf_process_ma_vif_availibility_ind: Process signal 0x%.4X\n", + *((CsrUint16*)sigdata)); + + r = read_unpack_signal(sigdata, &signal); + if (r) { + unifi_error(priv, + "uf_process_ma_vif_availibility_ind: Received unknown signal 0x%.4X.\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata)); + func_exit(); + return; + } + ind = &signal.u.MaVifAvailabilityIndication; + interfaceTag=ind->VirtualInterfaceIdentifier & 0xff; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "in vif_availability_ind interfaceTag is wrong\n"); + return; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + if(ind->Multicast) { + if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames) && + list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames)) { + /* This condition can occur because of a potential race where the + TIM is not yet reset as host is waiting for confirm but it is sent + by firmware and DTIM occurs*/ + unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag); + send_vif_availibility_rsp(priv,ind->VirtualInterfaceIdentifier,CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES); + interfacePriv->dtimActive = FALSE; + if(interfacePriv->multicastPduHostTag == 0xffffffff) { + unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag); + /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */ + update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF); + } + return; + } + if(interfacePriv->dtimActive) { + unifi_trace(priv,UDBG2,"DTIM Occurred for already active DTIM interface %d\n",interfaceTag); + return; + } else { + unifi_trace(priv,UDBG2,"DTIM Occurred for interface %d\n",interfaceTag); + if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { + set_eosp_transmit_ctrl(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames); + } else { + set_eosp_transmit_ctrl(priv,&interfacePriv->genericMulticastOrBroadCastFrames); + } + } + interfacePriv->dtimActive = TRUE; + pduSent = send_multicast_frames(priv,interfaceTag); + } + else { + unifi_error(priv,"Interface switching is not supported %d\n",interfaceTag); + resultCode = CSR_RC_NOT_SUPPORTED; + send_vif_availibility_rsp(priv,ind->VirtualInterfaceIdentifier,CSR_RC_NOT_SUPPORTED); + } +#endif +} +#ifdef CSR_SUPPORT_SME + +#define GET_ACTIVE_INTERFACE_TAG(priv) 0 + + +void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo) +{ + + CsrInt8 i; + + func_enter(); + + if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| + (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) + &&(!list_empty(&staInfo->mgtFrames))){ + + unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n"); + uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); + + /*This may happen because U-APSD was completed + with previous AC transfer*/ + + if(staInfo->uapsdActive == FALSE) { + return; + } + } + + for(i=3;i>=0;i--) { + + if(((staInfo->powersaveMode[i]== CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) + ||(staInfo->powersaveMode[i] == CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) + &&(!list_empty(&staInfo->dataPdu[i]))) { + unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered data frames\n"); + uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]); + } + + /*This may happen because U-APSD was completed + with previous AC transfer*/ + if (staInfo->uapsdActive == FALSE) { + return; + } + } + + if (staInfo->uapsdActive && !uf_is_more_data_for_delivery_ac(priv, staInfo, TRUE)) { + /* If last packet not able to transfer due to ENOSPC & buffer management algorithm + * would have removed last packet. Then we wont update staInfo->UapsdActive = FALSE (suppose + * to update as we dont have packet to transfer at this USP) because above if loop fails as list is empty & + * update of UAPSD activity done in uf_send_buffered_data_from_delivery_ac(). + * In this situation we send QOS null & mean time update UapsdActive to FALSE here + */ + staInfo->uapsdActive = FALSE; + uf_send_qos_null(priv, GET_ACTIVE_INTERFACE_TAG(priv), staInfo->peerMacAddress.a, CSR_QOS_UP0 , staInfo); + } + func_exit(); +} + + +void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, + CsrWifiRouterCtrlStaInfo_t * staInfo, + CsrUint8 queue, + struct list_head *txList) +{ + + CsrUint16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv); + tx_buffered_packets_t * buffered_pkt = NULL; + unsigned long lock_flags; + CsrBool eosp=FALSE; + CsrInt8 r =0; + CsrBool moreData = FALSE; + + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + netInterface_priv_t *interfacePriv; + interfacePriv = priv->interfacePriv[interfaceTag]; + func_enter(); + + /*Check U-APSD conditions if not met return from here*/ + if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)&& + (staInfo->uapsdActive == TRUE)&& + (!IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){ + + unifi_trace(priv,UDBG4,"uf_send_buffered_data_from_queue : U-APSD active. %d :Queue NOT delivery enbaled.return %\n",queue); + + return; + } + + while(!isRouterBufferEnabled(priv,queue) && + ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){ + if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->uapsdSuspended = TRUE; + staInfo->uapsdActive = FALSE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + /* re-queueing the packet as DTIM started */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q,txList); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + unifi_trace(priv, UDBG3, "%s: DTIM Active while UAPSD in progress for staId: 0x%x\n",__FUNCTION__,staInfo->aid); + break; + } + + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + + + if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)){ + + moreData = uf_is_more_data_for_delivery_ac(priv,staInfo,TRUE); + + buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK; + + if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength-1)){ + moreData = FALSE; + } + + if(moreData == FALSE){ + eosp = TRUE; + staInfo->uapsdActive = FALSE; + staInfo->noOfSpFramesSent = FALSE; + buffered_pkt->transmissionControl = + (TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable); + if ((allDeliveryEnabled && !dataAvailable)) { + update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle); + } + /* check the moer data for non delivery ac and update accordingly */ + else if(uf_is_more_data_for_non_delivery_ac(staInfo) ) { + update_tim(priv,staInfo->aid,1,interfaceTag, staInfo->assignedHandle); + } + else if(!uf_is_more_data_for_non_delivery_ac(staInfo) ){ + unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_send_buffered_data_from_delivery_ac\n"); + update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle); + } + + } + } + else + { + /*Non QoS and non U-APSD.*/ + eosp = FALSE; + moreData = FALSE; + unifi_warning(priv,"uf_send_buffered_data_from_delivery_ac :non U-APSD !!! \n"); + } + + unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp); + + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) { + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q,txList); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle); + unifi_notice (priv," U-APSD: PDU sending failed .. no space for queue %d \n",queue); + /*Break the loop for this queue.Try for next available Delivery enabled + Queue*/ + break; + } else { + if(r){ + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + + kfree(buffered_pkt); + if(staInfo->uapsdActive == TRUE){ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->noOfSpFramesSent = staInfo->noOfSpFramesSent + 1; + if(staInfo->noOfSpFramesSent == staInfo->maxSpLength){ + staInfo->uapsdActive = FALSE; + staInfo->noOfSpFramesSent = FALSE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + break; + } + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } + } + } + + func_exit(); + +} + +void uf_send_buffered_data_from_ac(unifi_priv_t *priv, + CsrWifiRouterCtrlStaInfo_t * staInfo, + CsrUint8 queue, + struct list_head *txList) +{ + tx_buffered_packets_t * buffered_pkt = NULL; + unsigned long lock_flags; + CsrBool eosp=FALSE; + CsrBool moreData = FALSE; + CsrInt8 r =0; + + func_enter(); + + unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_ac :\n"); + + while(!isRouterBufferEnabled(priv,queue) && + ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){ + + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + + unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp); + + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) { + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q,txList); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + if(staInfo != NULL){ + priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle); + } + unifi_trace(priv,UDBG3," uf_send_buffered_data_from_ac: PDU sending failed .. no space for queue %d \n",queue); + } else { + if(r){ + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + + func_exit(); + +} + +void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) +{ + CsrUint16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv); + CsrUint32 startIndex=0,endIndex=0; + CsrWifiRouterCtrlStaInfo_t * staInfo = NULL; + CsrUint8 queue; + CsrBool moreData = FALSE; + + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) || + (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) + return; + func_enter(); + + queue = (q<=3)?q:0; + + if(interfacePriv->dtimActive) { + /* this function updates dtimActive*/ + send_multicast_frames(priv,interfaceTag); + if(!interfacePriv->dtimActive) { + moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || + !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)); + if(!moreData) { + update_tim(priv,0,0,interfaceTag, 0XFFFFFFFF); + } + } else { + moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || + !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)); + if(!moreData) { + /* This should never happen but if it happens, we need a way out */ + unifi_error(priv,"ERROR: No More Data but DTIM is active sending Response\n"); + send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES); + interfacePriv->dtimActive = FALSE; + } + } + func_exit(); + return; + } + if(priv->pausedStaHandle[queue] > 7) { + priv->pausedStaHandle[queue] = 0; + } + + if(queue == UNIFI_TRAFFIC_Q_VO) { + + + unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying mgt from queue=%d\n",queue); + for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { + staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); + if(!staInfo ) { + continue; + } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + &&(staInfo->uapsdActive == FALSE) ) { + continue; + } + + if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) + &&(staInfo->uapsdActive == FALSE)){ + /*Non-UAPSD case push the management frames out*/ + if(!list_empty(&staInfo->mgtFrames)){ + uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); + } + } + else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]))){ + + + if(!list_empty(&staInfo->mgtFrames)){ + /*UNIFI_TRAFFIC_Q_VO is delivery enabled push the managment frames out*/ + uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); + + } + } + + if(isRouterBufferEnabled(priv,queue)) { + unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue); + break; + } + } + + + /*push generic management frames out*/ + + if(!list_empty(&interfacePriv->genericMgtFrames)){ + + unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue); + uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames); + + } + + } + + + unifi_trace(priv,UDBG2,"uf_send_buffered_frames : Resume called for Queue=%d\n",queue); + unifi_trace(priv,UDBG2,"uf_send_buffered_frames : start=%d end=%d\n",startIndex,endIndex); + + startIndex = priv->pausedStaHandle[queue]; + endIndex = (startIndex + UNIFI_MAX_CONNECTIONS -1) % UNIFI_MAX_CONNECTIONS; + + while(startIndex != endIndex) { + staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); + if(!staInfo) { + startIndex ++; + if(startIndex >= UNIFI_MAX_CONNECTIONS){ + startIndex = 0; + } + continue; + } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + &&(staInfo->uapsdActive == FALSE)){ + startIndex ++; + if(startIndex >= UNIFI_MAX_CONNECTIONS){ + startIndex = 0; + } + continue; + } + /* Peer is active or U-APSD is active so send PDUs to the peer */ + unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying data from queue=%d\n",queue); + + + if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) + &&(staInfo->uapsdActive == FALSE)){ + + if(!list_empty(&staInfo->dataPdu[queue])){ + + /*Non-UAPSD case push the AC frames out*/ + uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue])); + } + } + else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){ + if(!list_empty(&staInfo->dataPdu[queue])){ + uf_send_buffered_data_from_delivery_ac(priv, staInfo, queue, &staInfo->dataPdu[queue]); + } + } + + startIndex ++; + if(startIndex >= UNIFI_MAX_CONNECTIONS){ + startIndex = 0; + } + } + if(isRouterBufferEnabled(priv,queue)) { + priv->pausedStaHandle[queue] = endIndex; + } else { + priv->pausedStaHandle[queue] = 0; + } + + /*U-APSD might have stopped because of pause.So restart it if U-APSD + was active with any of the station*/ + for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { + staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); + if(!staInfo ) { + continue; + } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + &&(staInfo->uapsdActive == TRUE)) { + + /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by + sending data from remaining delivery enabled queues*/ + uf_continue_uapsd(priv,staInfo); + } + } + func_exit(); +} + +CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck) +{ + CsrUint8 i; + + for(i=0;i<=3;i++) + { + if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) + ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) + &&(!list_empty(&staRecord->dataPdu[i]))){ + unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available \n"); + return TRUE; + } + } + if((mgtCheck == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO])) + &&(!list_empty(&staRecord->mgtFrames))){ + + unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Management Data Available \n"); + + return TRUE; + } + + unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n"); + return FALSE; +} + +CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord) +{ + CsrUint8 i; + + for(i=0;i<=3;i++) + { + if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) + ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_LEGACY_POWER_SAVE)) + &&(!list_empty(&staRecord->dataPdu[i]))){ + + return TRUE; + } + } + + if(((staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) + ||(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_LEGACY_POWER_SAVE)) + &&(!list_empty(&staRecord->mgtFrames))){ + + return TRUE; + } + + + + return FALSE; +} + + +int uf_process_station_records_for_sending_data(unifi_priv_t *priv,CsrUint16 interfaceTag, + CsrWifiRouterCtrlStaInfo_t *srcStaInfo, + CsrWifiRouterCtrlStaInfo_t *dstStaInfo) +{ + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + unifi_trace(priv, UDBG5, "entering uf_process_station_records_for_sending_data\n"); + + if (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED) { + unifi_error(priv, "Peer State not connected AID = %x, handle = %x, control port state = %x\n", + srcStaInfo->aid, srcStaInfo->assignedHandle, srcStaInfo->peerControlledPort->port_action); + return -1; + } + switch (interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + unifi_trace(priv, UDBG5, "mode is AP/P2PGO\n"); + break; + default: + unifi_warning(priv, "mode is nor AP neither P2PGO, packet cant be xmit\n"); + return -1; + } + + switch(dstStaInfo->peerControlledPort->port_action) + { + case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD: + case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK: + unifi_trace(priv, UDBG5, "destination port is closed/blocked, discarding the packet\n"); + return -1; + default: + unifi_trace(priv, UDBG5, "destination port state is open\n"); + } + + /* port state is open, destination station record is valid, Power save state is + * validated in uf_process_ma_packet_req function + */ + unifi_trace(priv, UDBG5, "leaving uf_process_station_records_for_sending_data\n"); + return 0; +} + +void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv, + CsrWifiRouterCtrlStaInfo_t * srcStaInfo, + CsrUint16 qosControl, + CsrUint16 interfaceTag) +{ + + CSR_PRIORITY priority; + CsrInt8 i; + unifi_TrafficQueue priority_q; + unsigned long lock_flags; + + func_enter(); + + /* start the U-APSD operation only if it not active*/ + if(srcStaInfo->uapsdActive == FALSE){ + /*if recceived Frames trigger Frame and Devlivery enabled AC has data + then transmit from High priorty delivery enabled AC*/ + + + priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK); + + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); + + if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) + ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){ + + unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd starting U-APSD operations\n"); + + /*Received Frame is trigger frame*/ + unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : Received Frame is trigger frame %d\n",priority_q); + + if(((srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| + (srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) + &&(!list_empty(&srcStaInfo->mgtFrames))){ + + /*Trigger frame received and Data available in Delivery enabled AC + or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->uapsdActive = TRUE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n"); + + /* uf_send_buffered_frames(priv, priority_q); */ + uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, UNIFI_TRAFFIC_Q_VO, &srcStaInfo->mgtFrames); + + + /*This may happen because U-APSD was completed + with previous AC transfer*/ + + if(srcStaInfo->uapsdActive == FALSE){ + return; + } + + } + + + for(i=3;i>=0;i--){ + + if(((srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) + ||(srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) + &&(!list_empty(&srcStaInfo->dataPdu[i]))){ + + + /*Trigger frame received and Data available in Delivery enabled AC + or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->uapsdActive = TRUE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered data frames\n"); + + uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, i, &srcStaInfo->dataPdu[i]); + + /*This may happen because U-APSD was completed + with previous AC transfer*/ + + if(srcStaInfo->uapsdActive == FALSE){ + return; + } + } + + } + if(srcStaInfo->uapsdActive == FALSE && !(uf_is_more_data_for_delivery_ac(priv,srcStaInfo,TRUE))){ + unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd : No buffer frames so sending QOS Null in response of trigger frame\n"); + uf_send_qos_null(priv,interfaceTag,srcStaInfo->peerMacAddress.a,priority,srcStaInfo); + } + + } + + } + + func_exit(); + +} +void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo) +{ + bulk_data_param_t bulkdata; + CsrResult csrResult; + struct sk_buff *skb, *newSkb = NULL; + CsrWifiMacAddress peerAddress; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_ESOP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK); + int r; + CSR_SIGNAL signal; + CsrUint32 priority_q; + CSR_RATE transmitRate = 0; + + + func_enter(); + /* Send a Null Frame to Peer, + * 32= size of mac header */ + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE + QOS_CONTROL_HEADER_SIZE); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, " failed to allocate request_data. in uf_send_qos_null func\n"); + return ; + } + skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr); + skb->len = 0; + bulkdata.d[0].os_data_ptr = skb->data; + bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len; + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].os_net_buf_ptr = NULL; + bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0; + + /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */ + + if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) { + unifi_error(priv, "failed to create MAC header\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + return; + } + memcpy(peerAddress.a, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN); + /* convert priority to queue */ + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); + + /* Frame ma-packet.req, this is saved/transmitted depend on queue state + * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO + */ + switch (interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + transmitRate = 2; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + transmitRate = 12; + break; + default: + transmitRate = 0; + } + unifi_frame_ma_packet_req(priv, priority, transmitRate, 0xffffffff, interfaceTag, + transmissionControl, priv->netdev_client->sender_id, + peerAddress.a, &signal); + + r = ul_send_signal_unpacked(priv, &signal, &bulkdata); + if(r) { + unifi_error(priv, "failed to send QOS data null packet result: %d\n",r); + unifi_net_data_free(priv, &bulkdata.d[0]); + } + + func_exit(); + return; + +} +void uf_send_nulldata(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo) +{ + bulk_data_param_t bulkdata; + CsrResult csrResult; + struct sk_buff *skb, *newSkb = NULL; + CsrWifiMacAddress peerAddress; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CSR_TRANSMISSION_CONTROL transmissionControl = 0; + int r; + CSR_SIGNAL signal; + CsrUint32 priority_q; + CSR_RATE transmitRate = 0; + CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest; + unsigned long lock_flags; + + func_enter(); + /* Send a Null Frame to Peer, size = 24 for MAC header */ + csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "uf_send_nulldata: Failed to allocate memory for NULL frame\n"); + return ; + } + skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr); + skb->len = 0; + bulkdata.d[0].os_data_ptr = skb->data; + bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb; + bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len; + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].os_net_buf_ptr = NULL; + bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0; + + /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */ + if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) { + unifi_error(priv, "uf_send_nulldata: Failed to create MAC header\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + return; + } + memcpy(peerAddress.a, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN); + /* convert priority to queue */ + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); + transmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED); + + /* Frame ma-packet.req, this is saved/transmitted depend on queue state + * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO + */ + switch (interfacePriv->interfaceMode) + { + case CSR_WIFI_ROUTER_CTRL_MODE_AP: + transmitRate = 2; + break; + case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO: + transmitRate = 12; + break; + default: + transmitRate = 0; + } + unifi_frame_ma_packet_req(priv, priority, transmitRate, INVALID_HOST_TAG, interfaceTag, + transmissionControl, priv->netdev_client->sender_id, + peerAddress.a, &signal); + + /* Save host tag to check the status on reception of MA packet confirm */ + srcStaInfo->nullDataHostTag = req->HostTag; + unifi_trace(priv, UDBG1, "uf_send_nulldata: STA AID = %d hostTag = %x\n", srcStaInfo->aid, req->HostTag); + + r = ul_send_signal_unpacked(priv, &signal, &bulkdata); + + if(r == -ENOSPC) { + unifi_trace(priv, UDBG1, "uf_send_nulldata: ENOSPC Requeue the Null frame\n"); + enque_tx_data_pdu(priv, &bulkdata, &srcStaInfo->dataPdu[priority_q], &signal, 1); + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->noOfPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + + } + if(r && r != -ENOSPC){ + unifi_error(priv, "uf_send_nulldata: Failed to send Null frame Error = %d\n",r); + unifi_net_data_free(priv, &bulkdata.d[0]); + srcStaInfo->nullDataHostTag = INVALID_HOST_TAG; + } + + func_exit(); + return; +} + +CsrBool uf_check_broadcast_bssid(unifi_priv_t *priv, const bulk_data_param_t *bulkdata) +{ + CsrUint8 *bssid = NULL; + static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + CsrUint8 toDs, fromDs; + + toDs = (((bulkdata->d[0].os_data_ptr)[1]) & 0x01) ? 1 : 0; + fromDs =(((bulkdata->d[0].os_data_ptr)[1]) & 0x02) ? 1 : 0; + + if (toDs && fromDs) + { + unifi_trace(priv, UDBG6, "Address 4 present, Don't try to find BSSID\n"); + bssid = NULL; + } + else if((toDs == 0) && (fromDs ==0)) + { + /* BSSID is Address 3 */ + bssid = (CsrUint8 *) (bulkdata->d[0].os_data_ptr + 4 + (2 * ETH_ALEN)); + } + else if(toDs) + { + /* BSSID is Address 1 */ + bssid = (CsrUint8 *) (bulkdata->d[0].os_data_ptr + 4); + } + else if(fromDs) + { + /* BSSID is Address 2 */ + bssid = (CsrUint8 *) (bulkdata->d[0].os_data_ptr + 4 + ETH_ALEN); + } + + if (memcmp(broadcast_address.a, bssid, ETH_ALEN)== 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +CsrBool uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo, + CsrUint8 pmBit,CsrUint16 interfaceTag) +{ + CsrBool moreData = FALSE; + CsrBool powerSaveChanged = FALSE; + unsigned long lock_flags; + + unifi_trace(priv, UDBG3, "entering uf_process_pm_bit_for_peer\n"); + if (pmBit) { + priv->allPeerDozing |= (0x01 << (srcStaInfo->assignedHandle)); + } else { + priv->allPeerDozing &= ~(0x01 << (srcStaInfo->assignedHandle)); + } + if(pmBit) { + if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) { + + /* disable the preemption */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->currentPeerState =CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE; + powerSaveChanged = TRUE; + /* enable the preemption */ + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } else { + return powerSaveChanged; + } + } else { + if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) { + /* disable the preemption */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE; + powerSaveChanged = TRUE; + /* enable the preemption */ + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + }else { + return powerSaveChanged; + } + } + + + if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) { + unifi_trace(priv,UDBG3, "Peer with AID = %d is active now\n",srcStaInfo->aid); + process_peer_active_transition(priv,srcStaInfo,interfaceTag); + } else { + unifi_trace(priv,UDBG3, "Peer with AID = %d is in PS Now\n",srcStaInfo->aid); + /* Set TIM if needed */ + if(!srcStaInfo->wmmOrQosEnabled) { + moreData = (!list_empty(&srcStaInfo->mgtFrames) || + !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_VO])|| + !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])); + if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) { + unifi_trace(priv, UDBG3, "This condition should not occur\n"); + update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); + } + } else { + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + unifi_trace(priv, UDBG5, "Qos in AP Mode\n"); + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(srcStaInfo, &allDeliveryEnabled, &dataAvailable); + /*check for more data in non-delivery enabled queues*/ + moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable)); + + if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) { + update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); + } + } + } + unifi_trace(priv, UDBG3, "leaving uf_process_pm_bit_for_peer\n"); + return powerSaveChanged; +} + + + +void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pmBit,CsrUint16 interfaceTag) +{ + CsrWifiRouterCtrlStaInfo_t *staRecord = + CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, sa, interfaceTag); + tx_buffered_packets_t * buffered_pkt = NULL; + CsrWifiMacAddress peerMacAddress; + unsigned long lock_flags; + CsrInt8 r =0; + CsrBool moreData = FALSE; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + unifi_trace(priv, UDBG3, "entering uf_process_ps_poll\n"); + if(!staRecord) { + memcpy(peerMacAddress.a,sa,ETH_ALEN); + unifi_trace(priv, UDBG3, "In uf_process_ps_poll, sta record not found:unexpected frame addr = %x:%x:%x:%x:%x:%x\n", + sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]); + CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress); + return; + } + + uf_process_pm_bit_for_peer(priv,staRecord,pmBit,interfaceTag); + + /* Update station last activity time */ + staRecord->activity_flag = TRUE; + + /* This should not change the PM bit as PS-POLL has PM bit always set */ + if(!pmBit) { + unifi_notice (priv," PM bit reset in PS-POLL\n"); + return; + } + + if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) { + /* giving more priority to multicast packets so dropping ps-poll*/ + unifi_notice (priv," multicast transmission is going on so don't take action on PS-POLL\n"); + return; + } + + if(!staRecord->wmmOrQosEnabled) { + if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { + buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; + moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) || + !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || + !list_empty(&staRecord->mgtFrames)); + + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->mgtFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); + priv->pausedStaHandle[3]=(CsrUint8)(staRecord->assignedHandle); + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } else if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) { + buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; + moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) || + !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO])); + + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[3]=(CsrUint8)(staRecord->assignedHandle); + unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } else if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]))) { + buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; + moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]); + + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle); + unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } else { + /* Actually since we have sent an ACK, there + * there is no need to send a NULL frame*/ + } + moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || + !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) || + !list_empty(&staRecord->mgtFrames)); + if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) { + unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n"); + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + } else { + + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + unifi_trace(priv, UDBG3,"Qos Support station.Processing PS-Poll\n"); + + /*Send Data From Management Frames*/ + /* Priority orders for delivering the buffered packets are + * 1. UNIFI_TRAFFIC_Q_VO, if its non delivery enabled + * 2. management frames + * 3. Other access catagory frames which are non deliver enable + */ + + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); + + if (allDeliveryEnabled) { + unifi_trace(priv, UDBG3, "uf_process_ps_poll: All ACs are delivery enable so Sending QOS Null in response of Ps-poll\n"); + uf_send_qos_null(priv,interfaceTag,sa,CSR_QOS_UP0,staRecord); + return; + } + + if ((!IS_DELIVERY_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO])) && + (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || !list_empty(&staRecord->mgtFrames))) { + /* UNIFI_TRAFFIC_Q_VO is non delivery enabled, & check for packets are there to send from this AC */ + if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) { + moreData = uf_is_more_data_for_non_delivery_ac(staRecord); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + + /* Last parameter is EOSP & its false always for PS-POLL processing */ + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle); + unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } else if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { + /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management + * queue of the station record + */ + moreData = uf_is_more_data_for_non_delivery_ac(staRecord); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + + /* Last parameter is EOSP & its false always for PS-POLL processing */ + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->mgtFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle); + unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + } else { + CsrInt8 i; + /* We dont have buffered packet in UNIFI_TRAFFIC_Q_VO & mangement frame queue (1 & 2 failed), So proceed with 3 condition + * UNIFI_TRAFFIC_Q_VO is taken care so start with i index = 2 + */ + for(i= 2; i>=0; i--) { + if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) { + /* Send One packet, if queue is NULL then continue */ + if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) { + moreData = uf_is_more_data_for_non_delivery_ac(staRecord); + + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + + /* Last parameter is EOSP & its false always for PS-POLL processing */ + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { + /* Clear the trigger bit transmission control*/ + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staRecord->dataPdu[i]); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle); + unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); + } else { + if(r) { + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + break; + } + } + } + } + /* Check if all AC's are Delivery Enabled */ + is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); + /*check for more data in non-delivery enabled queues*/ + moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)); + if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) { + unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n"); + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + } + + unifi_trace(priv, UDBG3, "leaving uf_process_ps_poll\n"); +} + + + +void add_to_send_cfm_list(unifi_priv_t * priv, + tx_buffered_packets_t *tx_q_item, + struct list_head *frames_need_cfm_list) +{ + tx_buffered_packets_t *send_cfm_list_item = NULL; + + send_cfm_list_item = (tx_buffered_packets_t *) kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); + + if(send_cfm_list_item == NULL){ + unifi_warning(priv, "%s: Failed to allocate memory for new list item \n"); + return; + } + + INIT_LIST_HEAD(&send_cfm_list_item->q); + + send_cfm_list_item->hostTag = tx_q_item->hostTag; + send_cfm_list_item->interfaceTag = tx_q_item->interfaceTag; + send_cfm_list_item->transmissionControl = tx_q_item->transmissionControl; + send_cfm_list_item->leSenderProcessId = tx_q_item->leSenderProcessId; + send_cfm_list_item->rate = tx_q_item->rate; + memcpy(send_cfm_list_item->peerMacAddress.a, tx_q_item->peerMacAddress.a, ETH_ALEN); + send_cfm_list_item->priority = tx_q_item->priority; + + list_add_tail(&send_cfm_list_item->q, frames_need_cfm_list); +} + +void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv, + struct list_head *frames_need_cfm_list, + struct list_head * list) +{ + tx_buffered_packets_t *tx_q_item = NULL; + struct list_head *listHead; + struct list_head *placeHolder; + unsigned long lock_flags; + + func_enter(); + + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + + /* Search through the list and if confirmation required for any frames, + add it to the send_cfm list */ + list_for_each_safe(listHead, placeHolder, list) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + + if(!tx_q_item) { + unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n"); + continue; + } + + /* check if confirmation is requested and if the sender ID + is not netdevice client then save the entry in the list for need cfms */ + if (!(tx_q_item->transmissionControl & CSR_NO_CONFIRM_REQUIRED) && + (tx_q_item->leSenderProcessId != priv->netdev_client->sender_id)){ + unifi_trace(priv, UDBG1, "%s: SenderProcessID=%x host tag=%x transmission control=%x\n", + __FUNCTION__, + tx_q_item->leSenderProcessId, + tx_q_item->hostTag, + tx_q_item->transmissionControl); + + add_to_send_cfm_list(priv, tx_q_item, frames_need_cfm_list); + } + } + + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + + func_exit(); +} + + + +void uf_flush_list(unifi_priv_t * priv, struct list_head * list) +{ + tx_buffered_packets_t *tx_q_item; + struct list_head *listHead; + struct list_head *placeHolder; + unsigned long lock_flags; + + unifi_trace(priv, UDBG5, "entering the uf_flush_list \n"); + + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + /* go through list, delete & free memory */ + list_for_each_safe(listHead, placeHolder, list) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + + if(!tx_q_item) { + unifi_error(priv, "entry should exists, otherwise crashes (bug)\n"); + } + unifi_trace(priv, UDBG5, + "proccess_tx: in uf_flush_list peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n", + tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1], + tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3], + tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5], + tx_q_item->leSenderProcessId); + + list_del(listHead); + /* free the allocated memory */ + unifi_net_data_free(priv, &tx_q_item->bulkdata); + kfree(tx_q_item); + tx_q_item = NULL; + if (!priv->noOfPktQueuedInDriver) { + unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__); + } else { + priv->noOfPktQueuedInDriver--; + } + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); +} +void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list) +{ + struct list_head *listHeadMaPktreq,*placeHolderMaPktreq; + maPktReqList_t *maPktreq; + unsigned long lock_flags; + + unifi_trace(priv, UDBG5, "entering the uf_flush_maPktlist \n"); + + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + /* go through list, delete & free memory */ + list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, list) { + maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q); + + if(!maPktreq) { + unifi_error(priv, "entry should exists, otherwise crashes (bug)\n"); + } + /* free the allocated memory */ + dev_kfree_skb(maPktreq->skb); + list_del(listHeadMaPktreq); + kfree(maPktreq); + maPktreq = NULL; + + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); +} +tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList) +{ + /* dequeue the tx data packets from the appropriate queue */ + tx_buffered_packets_t *tx_q_item = NULL; + struct list_head *listHead; + struct list_head *placeHolder; + unsigned long lock_flags; + + unifi_trace(priv, UDBG5, "entering dequeue_tx_data_pdu\n"); + /* check for list empty */ + if (list_empty(txList)) { + unifi_trace(priv, UDBG5, "In dequeue_tx_data_pdu, the list is empty\n"); + return NULL; + } + + /* Verification, if packet count is negetive */ + if (priv->noOfPktQueuedInDriver == 0xFFFF) { + unifi_warning(priv, "no packet available in queue: debug"); + return NULL; + } + + /* return first node after header, & delete from the list && atleast one item exist */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHead, placeHolder, txList) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + list_del(listHead); + break; + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + + if (tx_q_item) { + unifi_trace(priv, UDBG5, + "proccess_tx: In dequeue_tx_data_pdu peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n", + tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1], + tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3], + tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5], + tx_q_item->leSenderProcessId); + } + + unifi_trace(priv, UDBG5, "leaving dequeue_tx_data_pdu\n"); + return tx_q_item; +} +/* generic function to get the station record handler */ +CsrWifiRouterCtrlStaInfo_t *CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(unifi_priv_t *priv, + const CsrUint8 *peerMacAddress, + CsrUint16 interfaceTag) +{ + CsrUint8 i; + netInterface_priv_t *interfacePriv; + unsigned long lock_flags; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "interfaceTag is not proper, interfaceTag = %d\n", interfaceTag); + return NULL; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* disable the preemption untill station record is fetched */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + + for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + if (interfacePriv->staInfo[i]!= NULL) { + if (!memcmp(((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]))->peerMacAddress.a, peerMacAddress, ETH_ALEN)) { + /* enable the preemption as station record is fetched */ + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + unifi_trace(priv, UDBG5, "peer entry found in station record\n"); + return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i])); + } + } + } + /* enable the preemption as station record is fetched */ + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + unifi_trace(priv, UDBG5, "peer entry not found in station record\n"); + return NULL; +} +/* generic function to get the station record handler from the handle */ +CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_priv_t *priv, + CsrUint32 handle, + CsrUint16 interfaceTag) +{ + netInterface_priv_t *interfacePriv; + + if ((handle >= UNIFI_MAX_CONNECTIONS) || (interfaceTag >= CSR_WIFI_NUM_INTERFACES)) { + unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", handle, interfaceTag); + return NULL; + } + interfacePriv = priv->interfacePriv[interfaceTag]; + return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle])); +} + +/* Function to do inactivity */ +void uf_check_inactivity(unifi_priv_t *priv, CsrUint16 interfaceTag, CsrTime currentTime) +{ + CsrUint32 i; + CsrWifiRouterCtrlStaInfo_t *staInfo; + CsrTime elapsedTime; /* Time in microseconds */ + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrWifiMacAddress peerMacAddress; + unsigned long lock_flags; + + if (interfacePriv == NULL) { + unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n"); + return; + } + + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + /* Go through the list of stations to check for inactivity */ + for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv, i, interfaceTag); + if(!staInfo ) { + continue; + } + + unifi_trace(priv, UDBG3, "Running Inactivity handler Time %xus station's last activity %xus\n", + currentTime, staInfo->lastActivity); + + + elapsedTime = (currentTime >= staInfo->lastActivity)? + (currentTime - staInfo->lastActivity): + (~((CsrUint32)0) - staInfo->lastActivity + currentTime); + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + if (elapsedTime > MAX_INACTIVITY_INTERVAL) { + memcpy((CsrUint8*)&peerMacAddress, (CsrUint8*)&staInfo->peerMacAddress, sizeof(CsrWifiMacAddress)); + + /* Indicate inactivity for the station */ + unifi_trace(priv, UDBG3, "Station %x:%x:%x:%x:%x:%x inactive since %xus\n sending Inactive Ind\n", + peerMacAddress.a[0], peerMacAddress.a[1], + peerMacAddress.a[2], peerMacAddress.a[3], + peerMacAddress.a[4], peerMacAddress.a[5], + elapsedTime); + + CsrWifiRouterCtrlStaInactiveIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress); + } + } + + interfacePriv->last_inactivity_check = currentTime; +} + +/* Function to update activity of a station */ +void uf_update_sta_activity(unifi_priv_t *priv, CsrUint16 interfaceTag, const CsrUint8 *peerMacAddress) +{ + CsrTime elapsedTime, currentTime; /* Time in microseconds */ + CsrTime timeHi; /* Not used - Time in microseconds */ + CsrWifiRouterCtrlStaInfo_t *staInfo; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + unsigned long lock_flags; + + if (interfacePriv == NULL) { + unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n"); + return; + } + + currentTime = CsrTimeGet(&timeHi); + + + staInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag); + + if (staInfo == NULL) { + unifi_trace(priv, UDBG4, "Sta does not exist yet"); + return; + } + + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + /* Update activity */ + staInfo->lastActivity = currentTime; + + /* See if inactivity handler needs to be run + * Here it is theoretically possible that the counter may have wrapped around. But + * since we just want to know when to run the inactivity handler it does not really matter. + * Especially since this is data path it makes sense in keeping it simple and avoiding + * 64 bit handling */ + elapsedTime = (currentTime >= interfacePriv->last_inactivity_check)? + (currentTime - interfacePriv->last_inactivity_check): + (~((CsrUint32)0) - interfacePriv->last_inactivity_check + currentTime); + + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + /* Check if it is time to run the inactivity handler */ + if (elapsedTime > INACTIVITY_CHECK_INTERVAL) { + uf_check_inactivity(priv, interfaceTag, currentTime); + } +} +void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) +{ + + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrUint8 i; + int j; + tx_buffered_packets_t * buffered_pkt = NULL; + CsrBool hipslotFree[4] = {TRUE,TRUE,TRUE,TRUE}; + int r; + unsigned long lock_flags; + + func_enter(); + while(!isRouterBufferEnabled(priv,3) && + ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) { + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) { + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &interfacePriv->genericMgtFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + hipslotFree[3]=FALSE; + break; + }else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + CsrWifiRouterCtrlStaInfo_t *staInfo = interfacePriv->staInfo[i]; + if(!hipslotFree[0] && !hipslotFree[1] && !hipslotFree[2] && !hipslotFree[3]) { + unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full \n"); + break; + } + if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) { + while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) { + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) { + unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n"); + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staInfo->mgtFrames); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[3]=(CsrUint8)(staInfo->assignedHandle); + hipslotFree[3] = FALSE; + break; + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + + for(j=3;j>=0;j--) { + if(!hipslotFree[j]) + continue; + + while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) { + buffered_pkt->transmissionControl &= + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) { + /* Enqueue at the head of the queue */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q, &staInfo->dataPdu[j]); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[j]=(CsrUint8)(staInfo->assignedHandle); + hipslotFree[j]=FALSE; + break; + } else { + if(r){ + unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); + /* the PDU failed where we can't do any thing so free the storage */ + unifi_net_data_free(priv, &buffered_pkt->bulkdata); + } + kfree(buffered_pkt); + } + } + } + } + } + func_exit(); +} +void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 interfaceTag) +{ + + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + unsigned long lock_flags; + struct list_head *listHead; + struct list_head *placeHolder; + tx_buffered_packets_t *tx_q_item; + + func_enter(); + if (interfacePriv->noOfbroadcastPktQueued) { + + /* Update the EOSP to the HEAD of b/c list + * beacuse we have received any mgmt packet so it should not hold for long time + * peer may time out. + */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) { + tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); + tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; + tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); + unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag); + break; + } + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + } + func_exit(); +} +void resume_suspended_uapsd(unifi_priv_t* priv,CsrUint16 interfaceTag) +{ + + CsrUint8 startIndex; + CsrWifiRouterCtrlStaInfo_t * staInfo = NULL; + unsigned long lock_flags; + /*U-APSD might have stopped because of multicast. So restart it if U-APSD + was active with any of the station*/ + for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { + staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); + if(!staInfo ) { + continue; + } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) + &&(staInfo->uapsdSuspended == TRUE)) { + + /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by + sending data from remaining delivery enabled queues*/ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->uapsdActive = TRUE; + staInfo->uapsdSuspended = FALSE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + uf_continue_uapsd(priv,staInfo); + } + } + +} +void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata, + CSR_SIGNAL *sigptr, CsrUint32 alignOffset) +{ + + maPktReqList_t *maPktreq = NULL; + CSR_MA_PACKET_REQUEST *req = &sigptr->u.MaPacketRequest; + CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; + CsrUint16 frmCtrl,interfaceTag = 0; + const CsrUint8* macHdrLocation; + struct sk_buff *skb ; + unsigned long lock_flags; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + CsrUint8 *sigbuffer; + CsrUint8 frameType = 0; + func_enter(); + + if(bulkdata == NULL || (0 == bulkdata->d[0].data_length )){ + unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece:bulk data NULL \n"); + func_exit(); + return; + } + macHdrLocation = bulkdata->d[0].os_data_ptr; + skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; + /* fectch the frame control value from mac header */ + frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation); + + /* Processing done according to Frame/Packet type */ + frameType = ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET); + + if( (((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_QOS_NULL) || + ((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_NULL ) ) || + ( IEEE802_11_FRAMETYPE_MANAGEMENT== frameType)){ + + /* if packet is NULL or Qos Null no need of retransmit so dont queue it*/ + unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: NULL data Pkt or mgmt\n"); + func_exit(); + return; + } + + /* fetch the station record for corresponding peer mac address */ + if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, req->Ra.x, interfaceTag))) { + maPktreq = (maPktReqList_t*)kmalloc(sizeof(maPktReqList_t),GFP_ATOMIC); + if(maPktreq == NULL){ + unifi_error(priv, + "uf_store_directed_ma_packet_referenece :: Failed to allocate %d byter for maPktreq\n", + sizeof(maPktReqList_t)); + func_exit(); + return; + } + } + + /* staRecord not present that means packet is multicast or generic mgmt so no need to queue it */ + else{ + unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: multicast pkt \n"); + func_exit(); + return ; + } + + /* disbale preemption */ + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + INIT_LIST_HEAD(&maPktreq->q); + maPktreq->staHandler = staRecord->assignedHandle; + memcpy(&maPktreq->signal,sigptr,sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + sizeof(CSR_MA_PACKET_REQUEST)); + sigbuffer = (CsrUint8*)&maPktreq->signal; + sigbuffer[SIZEOF_SIGNAL_HEADER + 1] = alignOffset; + maPktreq->skb = skb_get(skb); + maPktreq->hostTag = req->HostTag; + maPktreq->jiffeTime = jiffies; + list_add_tail(&maPktreq->q,&interfacePriv->directedMaPktReq); + + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + func_exit(); + +} + +#endif diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h new file mode 100644 index 000000000000..f687f270a699 --- /dev/null +++ b/drivers/staging/csr/unifi_priv.h @@ -0,0 +1,1148 @@ +/* + ***************************************************************************** + * + * FILE : unifi_priv.h + * + * PURPOSE : Private header file for unifi driver. + * + * UDI = UniFi Debug Interface + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + ***************************************************************************** + */ +#ifndef __LINUX_UNIFI_PRIV_H__ +#define __LINUX_UNIFI_PRIV_H__ 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19) +#include +#endif + +#ifdef CSR_WIFI_SUPPORT_MMC_DRIVER +#include +#include +#include +#include +#include +#include +#endif /* CSR_WIFI_SUPPORT_MMC_DRIVER */ + +#include + +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_unifi_udi.h" +#include "csr_wifi_router_lib.h" +#include "unifiio.h" +#ifndef CSR_WIFI_HIP_TA_DISABLE +#include "csr_wifi_vif_utils.h" +#endif + +/* Define the unifi_priv_t before include the unifi_native.h */ +struct unifi_priv; +typedef struct unifi_priv unifi_priv_t; +#ifdef CSR_SUPPORT_WEXT_AP +struct CsrWifiSmeApConfig; +typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t; +#endif +#ifdef CSR_SUPPORT_WEXT +#include "unifi_wext.h" +#endif + +#include "unifi_clients.h" + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#include + +#undef INIT_WORK +#define INIT_WORK(_work, _func) \ + do { \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->pending = 0; \ + PREPARE_WORK((_work), (_func), (_work)); \ + init_timer(&(_work)->timer); \ + } while(0) + +#endif /* Linux kernel < 2.6.20 */ + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_tx_wake_all_queues(_netdev) +#define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_tx_start_all_queues(_netdev) +#define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_tx_stop_all_queues(_netdev) +#else +#define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_wake_queue(_netdev) +#define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_start_queue(_netdev) +#define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_stop_queue(_netdev) +#endif /* Linux kernel >= 2.6.27 */ + + +#ifdef CSR_NATIVE_LINUX +#include "sme_native/unifi_native.h" +#else +#include "unifi_sme.h" +#endif + +#undef COMPARE_HOST_TAG_TO_ENQUEUE +#define COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item_hosttag,maPktHostTag) \ + if(tx_q_item_hosttag > maPktHostTag){ \ + locationFound = TRUE; \ + ii++; \ + break; \ + } \ + ii++; \ + + +/* The device major number to use when registering the udi driver */ +#define UNIFI_NAME "unifi" +#define MAX_UNIFI_DEVS 2 + +/* 802.11 Mac header offsets */ +#define MAC_HEADER_SIZE 24 +#define QOS_CONTROL_HEADER_SIZE 2 +#define HT_CONTROL_HEADER_SIZE 4 +#define QOS_DATA 0x8 +#define QOS_DATA_NULL 0xc +#define DATA_NULL 0x04 +#define FRAME_CONTROL_ORDER_BIT 0x8000 +#define FRAME_CONTROL_TYPE_FIELD_OFFSET 2 +#define FRAME_CONTROL_SUBTYPE_FIELD_OFFSET 4 +#define IEEE802_11_FRAMETYPE_DATA 0x02 +#define IEEE802_11_FRAMETYPE_CONTROL 0x01 +#define IEEE802_11_FRAMETYPE_MANAGEMENT 0x00 +#define IEEE802_11_FRAMETYPE_RESERVED 0x03 + +/* octet offset from start of mac header for certain fields */ +#define IEEE802_11_ADDR3_OFFSET 16 +#define IEEE802_11_SEQUENCE_CONTROL_OFFSET 22 +#define IEEE802_11_MAX_DATA_LEN 2304 + +/* frame control (FC) masks, for frame control as 16 bit integer */ +#define IEEE802_11_FC_TO_DS_MASK 0x100 +#define IEEE802_11_FC_FROM_DS_MASK 0x200 +#define IEEE802_11_FC_MOREDATA_MASK 0x2000 +#define IEEE802_11_FC_PROTECTED_MASK 0x4000 +#define IEEE80211_FC_ORDER_MASK 0x8000 +#define IEEE80211_FC_SUBTYPE_MASK 0x00f0 +#define IEEE80211_FC_TYPE_MASK 0x000c +#define IEEE80211_FC_PROTO_VERSION_MASK 0x0003 + +/* selected type and subtype combinations as in 7.1.3.1 table 1 + For frame control as 16 bit integer, or for ls octet +*/ +#define IEEE802_11_FC_TYPE_DATA 0x08 +#define IEEE802_11_FC_TYPE_NULL 0x48 +#define IEEE802_11_FC_TYPE_QOS_NULL 0xc8 +#define IEEE802_11_FC_TYPE_QOS_DATA 0x88 + +#define IEEE802_11_FC_TYPE_DATA_SUBTYPE_RESERVED 0x0D + +/* qos control (QC) masks for qos control as 16 bit integer, or for ls octet */ +#define IEEE802_11_QC_TID_MASK 0x0f +#define IEEE802_11_QC_A_MSDU_PRESENT 0x80 + +#define CSR_WIFI_EAPOL_M4_HOST_TAG 0x50000000 +#define IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE 36 +#define MAX_ACCESS_CATOGORY 4 + +/* Time in us to check for inactivity of stations 5 mins */ +#define INACTIVITY_CHECK_INTERVAL 300000000 +/* Time in us before a station is flagged as inactive */ +#define MAX_INACTIVITY_INTERVAL 300000000 + + +/* Define for maximum BA session */ +#define MAX_SUPPORTED_BA_SESSIONS_TX 1 +#define MAX_SUPPORTED_BA_SESSIONS_RX 4 + +#define MAX_BA_WIND_SIZE 64 +#define MAC_HEADER_ADDR1_OFFSET 4 +#define MAC_HEADER_ADDR2_OFFSET 10 + +/* Define for age (in us) value for frames in MPDU reorder buffer */ +#define CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT 30000 /* 30 milli seconds */ + +/* This macro used in prepare_and_add_macheader*/ +#define ADDRESS_ONE_OFFSET 20 + +/* Defines for STA inactivity detection */ +#define STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD 1 /* in number of stations */ +#define STA_INACTIVE_DETECTION_TIMER_INTERVAL 30 /* in seconds */ +#define STA_INACTIVE_TIMEOUT_VAL 120*1000*1000 /* 120 seconds */ + + +/* Defines used in beacon filtering in case of P2P */ +#define CSR_WIFI_P2P_WILDCARD_SSID_LENGTH 0x7 +#define CSR_WIFI_80211_FRAME_SUBTYPE_BEACON 0x8 +#define CSR_WIFI_BEACON_FIXED_LENGTH 12 +#define CSR_WIFI_FRAME_SUBTYPE_BIT_OFFSET 4 +#define CSR_WIFI_80211_FRAME_SUBTYPE_BIT_MASK ((CsrUint8)(0xF << CSR_WIFI_FRAME_SUBTYPE_BIT_OFFSET)) + +#define CSR_WIFI_80211_GET_FRAME_SUBTYPE(frameBuffer) \ + ((CsrUint8)(((CsrUint8 *)frameBuffer)[0] & CSR_WIFI_80211_FRAME_SUBTYPE_BIT_MASK) >> CSR_WIFI_FRAME_SUBTYPE_BIT_OFFSET) + +/* For M4 request received via netdev*/ + +typedef CsrUint8 CsrWifiPacketType; +#define CSR_WIFI_UNICAST_PDU ((CsrWifiPacketType) 0x00) +#define CSR_WIFI_MULTICAST_PDU ((CsrWifiPacketType) 0x1) +#define CSR_WIFI_BROADCAST_PDU ((CsrWifiPacketType) 0x2) + +#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20) + +/* Module parameter variables */ +extern int buswidth; +extern int sdio_clock; +extern int use_5g; +extern int disable_hw_reset; +extern int disable_power_control; +extern int enable_wol; +extern int sme_debug; +extern int fw_init[MAX_UNIFI_DEVS]; +extern int tl_80211d; +extern int sdio_byte_mode; +extern int sdio_block_size; +extern int coredump_max; +extern int run_bh_once; +extern int bh_priority; + +struct dlpriv { + const unsigned char *dl_data; + int dl_len; + void *fw_desc; +}; + + +struct uf_thread { + + struct task_struct *thread_task; + + /* wait_queue for waking the unifi_thread kernel thread */ + wait_queue_head_t wakeup_q; + unsigned int wakeup_flag; + + /* + * Use it to block the I/O thread when + * an error occurs or UniFi is reinitialised. + */ + int block_thread; + + char name[16]; + int prio; +}; + +/* + * Link list to hold the received packets for the period the port + * remains closed. + */ +typedef struct rx_buffered_packets { + /* List link structure */ + struct list_head q; + /* Packet to indicate when the port reopens */ + struct sk_buff *skb; + /* Bulkdata to free in case the port closes and need to discard the packet */ + bulk_data_param_t bulkdata; + /* The source address of the packet */ + CsrWifiMacAddress sa; + /* The destination address of the packet */ + CsrWifiMacAddress da; + /* Corresponding signal */ + CSR_SIGNAL signal; +} rx_buffered_packets_t; + + +typedef CsrUint8 CsrWifiAcPowersaveMode; +#define CSR_WIFI_AC_TRIGGER_ONLY_ENABLED 0x00 +#define CSR_WIFI_AC_DELIVERY_ONLY_ENABLE 0X01 +#define CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED 0X03 +#define CSR_WIFI_AC_LEGACY_POWER_SAVE 0X02 + + +#define IS_DELIVERY_ENABLED(mode) (mode & CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)? 1: 0 +#define IS_DELIVERY_AND_TRIGGER_ENABLED(mode) ((mode & CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)||(mode & CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))? 1: 0 +#define IS_DTIM_ACTIVE(flag,hostTag) ((flag == TRUE || hostTag != INVALID_HOST_TAG)) +#define INVALID_HOST_TAG 0xFFFFFFFF +#define UNIFI_TRAFFIC_Q_CONTENTION UNIFI_TRAFFIC_Q_BE + + + + +/* Queue to be used for contention priority */ + +/* + * Link list to hold the tx packets for the period the peer + * powersave/free slots in unifi + */ +typedef struct tx_buffered_packets { + /* List link structure */ + struct list_head q; + CsrUint16 interfaceTag; + CSR_CLIENT_TAG hostTag; + CSR_PROCESS_ID leSenderProcessId; + CSR_TRANSMISSION_CONTROL transmissionControl; + CSR_RATE rate; + /* Bulkdata to free in case the port closes and need to discard the packet */ + bulk_data_desc_t bulkdata; + /* The source address of the packet */ + CsrWifiMacAddress peerMacAddress; + CSR_PRIORITY priority; +} tx_buffered_packets_t; + +/* station record has this data structure */ +typedef struct CsrWifiRouterCtrlStaInfo_t { + + /* Sme sends these parameters */ + CsrWifiMacAddress peerMacAddress; + CsrUint32 assignedHandle; + CsrBool wmmOrQosEnabled; + CsrWifiAcPowersaveMode powersaveMode[MAX_ACCESS_CATOGORY]; + CsrUint16 maxSpLength; + CsrBool uapsdActive; + CsrUint16 noOfSpFramesSent; + + /* Router/Driver database */ +#ifdef CSR_SUPPORT_SME + unifi_port_cfg_t *peerControlledPort; + unifi_port_cfg_t *peerUnControlledPort; + + /* Inactivity feature parameters */ + struct netInterface_priv *interfacePriv; + struct work_struct send_disconnected_ind_task; + CsrBool activity_flag; + CsrUint16 listenIntervalInTus; + CSR_CLIENT_TAG nullDataHostTag; + + /* Activity timestamps for the station */ + CsrTime lastActivity; + + /* during m/c transmission sp suspended */ + CsrBool uapsdSuspended; +#endif + CsrWifiRouterCtrlPeerStatus currentPeerState; + struct list_head dataPdu[MAX_ACCESS_CATOGORY]; + struct list_head mgtFrames; + CsrUint8 spStatus; + CsrUint8 prevFrmType; + CsrUint8 prevFrmAccessCatogory; + CsrBool protection; + CsrUint16 aid; + CsrBool txSuspend; + CsrUint8 timSet; + /* Dont change the value of below macro for SET & RESET */ +#define CSR_WIFI_TIM_RESET 0 +#define CSR_WIFI_TIM_SET 1 +#define CSR_WIFI_TIM_RESETTING 2 +#define CSR_WIFI_TIM_SETTING 3 + + CsrUint16 noOfPktQueued; +}CsrWifiRouterCtrlStaInfo_t; + +#ifdef CSR_SUPPORT_WEXT_AP +struct CsrWifiSmeApConfig { + CsrWifiSsid ssid; + CsrUint16 channel; + CsrWifiNmeApCredentials credentials; + CsrUint8 max_connections; + CsrUint8 if_index; +}; +#endif + +#ifdef CSR_WIFI_RX_PATH_SPLIT +/* This is a test code and may be removed later*/ +#define CSR_WIFI_RX_SIGNAL_BUFFER_SIZE (60+1) + +typedef struct +{ + CsrUint8 *bufptr; /* Signal Primitive */ + bulk_data_param_t data_ptrs; /* Bulk Data pointers */ + CsrUint16 sig_len; +}rx_buff_struct_t; + +typedef struct +{ + CsrUint8 writePointer; /**< write pointer */ + CsrUint8 readPointer; /**< read pointer */ + CsrUint8 size; /**< size of circular buffer */ + rx_buff_struct_t rx_buff[CSR_WIFI_RX_SIGNAL_BUFFER_SIZE]; /**< Element of ciruclar buffer */ +} rxCircularBuffer_t; + +void rx_wq_handler(struct work_struct *work); +#endif + +struct unifi_priv { + + card_t *card; + CsrSdioFunction *sdio; + + /* Index into Unifi_instances[] for this device. */ + int instance; + /* Reference count for this instance */ + int ref_count; + + /* Firmware images */ + struct dlpriv fw_sta; + struct dlpriv fw_conv; /* used for conversion of production test image */ + + /* Char device related structures */ + struct cdev unifi_cdev; + struct cdev unifiudi_cdev; + struct device *unifi_device; + + /* Which wireless interface to use (1 - 2.4GHz, 2 - 5GHz) */ + CSR_IFINTERFACE if_index; + + /* For multiple interface support */ + struct net_device *netdev[CSR_WIFI_NUM_INTERFACES]; + struct netInterface_priv *interfacePriv[CSR_WIFI_NUM_INTERFACES]; + + CsrUint8 totalInterfaceCount; + + int prev_queue; + + /* Name of node under /proc */ + char proc_entry_name[64]; + + /* + * Flags: + * drop_unencrypted + * - Not used? + * netdev_registered + * - whether the netdev has been registered. + */ + unsigned int drop_unencrypted : 1; + + /* Our list of unifi linux clients. */ + ul_client_t ul_clients[MAX_UDI_CLIENTS]; + + /* Mutex to protect using the logging hook after UDI client is gone */ + struct semaphore udi_logging_mutex; + /* Pointer to the ul_clients[] array */ + ul_client_t *logging_client; + + /* A ul_client_t* used to send the netdev related MIB requests. */ + ul_client_t *netdev_client; + + /* The SME ul_client_t pointer. */ + ul_client_t *sme_cli; + + /* The AMP ul_client_t pointer. */ + ul_client_t *amp_client; + + /* + * Semaphore for locking the top-half to one user process. + * This is necessary to prevent multiple processes calling driver + * operations. This can happen because the network driver entry points + * can be called from multiple processes. + */ +#ifdef USE_DRIVER_LOCK + struct semaphore lock; +#endif /* USE_DRIVER_LOCK */ + + /* Flag to say that an operation was aborted */ + int io_aborted; + + struct uf_thread bh_thread; + +#define UNIFI_INIT_NONE 0x00 +#define UNIFI_INIT_IN_PROGRESS 0x01 +#define UNIFI_INIT_FW_DOWNLOADED 0x02 +#define UNIFI_INIT_COMPLETED 0x04 + unsigned char init_progress; + + int sme_is_present; + + /* The WMM features that UniFi uses in the current BSS */ + unsigned int sta_wmm_capabilities; + + /* Debug only */ + char last_debug_string[256]; + unsigned short last_debug_word16[16]; + +#ifdef CSR_SUPPORT_SME + /* lock to protect the tx queues list */ + spinlock_t tx_q_lock; + CsrUint8 allPeerDozing; + CsrUint8 pausedStaHandle[MAX_ACCESS_CATOGORY]; + /* Max packet the driver can queue, irrespective of interface number */ + CsrUint16 noOfPktQueuedInDriver; +#define CSR_WIFI_DRIVER_SUPPORT_FOR_MAX_PKT_QUEUEING 512 +#define CSR_WIFI_DRIVER_MAX_PKT_QUEUING_THRESHOLD_PER_PEER 64 +#define CSR_WIFI_DRIVER_MINIMUM_BROADCAST_PKT_THRESHOLD 3 + + CsrBool routerBufferEnable[MAX_ACCESS_CATOGORY]; + /* lock to protect stainfo members and priv members*/ + spinlock_t staRecord_lock; +#endif +#ifdef CSR_NATIVE_LINUX +#ifdef CSR_SUPPORT_WEXT + /* wireless config */ + struct wext_config wext_conf; +#endif + + /* Mutex to protect the MLME blocking requests */ + struct semaphore mlme_blocking_mutex; + + /* The ul_client that provides the blocking API for WEXT calls */ + ul_client_t *wext_client; + +#endif /* CSR_NATIVE_LINUX */ + +#ifdef CSR_SUPPORT_SME + wait_queue_head_t sme_request_wq; + /* Semaphore to protect the SME blocking requests */ + struct semaphore sme_sem; + /* Structure to hold the SME blocking requests data*/ + sme_reply_t sme_reply; + + /* Structure to hold a traffic protocol indication */ + struct ta_ind { + struct work_struct task; + CsrWifiRouterCtrlTrafficPacketType packet_type; + CsrWifiRouterCtrlProtocolDirection direction; + CsrWifiMacAddress src_addr; + int in_use; + } ta_ind_work; + + struct ta_sample_ind { + struct work_struct task; + CsrWifiRouterCtrlTrafficStats stats; + int in_use; + } ta_sample_ind_work; + + __be32 sta_ip_address; + CsrWifiRouterCtrlSmeVersions sme_versions; + + /* + * Flag to reflect state of unifi_sys_wifi_on_*() progress. + * This indicates whether we are in an "wifi on" state when we are + * allowed to indication errors with unifi_mgt_wifi_off_ind() + */ + enum { + wifi_on_unspecified = -1, + wifi_on_in_progress = 0, + wifi_on_done = 1, + } wifi_on_state; + + /* Userspace TaskId for the SME Set when a wifi on req is received */ + CsrSchedQid CSR_WIFI_SME_IFACEQUEUE; + + struct work_struct multicast_list_task; + /* + * The SME installs filters to ask for specific MA-UNITDATA.req + * to be passed to different SME components. + */ +#define MAX_MA_UNIDATA_IND_FILTERS 8 + sme_ma_unidata_ind_filter_t sme_unidata_ind_filters[MAX_MA_UNIDATA_IND_FILTERS]; + +/* UNIFI_CFG related parameters */ + uf_cfg_bcast_packet_filter_t packet_filters; + unsigned char *filter_tclas_ies; + /* The structure that holds all the connection configuration. */ + CsrWifiSmeConnectionConfig connection_config; +#ifdef CSR_SUPPORT_WEXT + + int ignore_bssid_join; + struct iw_statistics wext_wireless_stats; + + /* The MIB and MAC address files contents, read from userspace */ + CsrWifiSmeDataBlock mib_data; + CsrWifiMacAddress sta_mac_address; + + int wep_tx_key_index; + wep_key_t wep_keys[NUM_WEPKEYS]; + + +#ifdef CSR_SUPPORT_WEXT_AP + CsrWifiSmeApMacConfig ap_mac_config; + CsrWifiNmeApConfig group_sec_config; + CsrWifiSmeApConfig_t ap_config; +#endif + struct work_struct sme_config_task; + +#endif /* CSR_SUPPORT_WEXT */ + +#endif /* CSR_SUPPORT_SME */ + +#ifdef CSR_SME_USERSPACE + void *smepriv; +#endif /* CSR_SME_USERSPACE */ + + card_info_t card_info; + + /* Mutex to protect unifi_send_signal() */ + spinlock_t send_signal_lock; + + + /* + * The workqueue to offload the TA run + * and the multicast addresses list set + */ + struct workqueue_struct *unifi_workqueue; + + unsigned char *mib_cfm_buffer; + unsigned int mib_cfm_buffer_length; + + int ptest_mode; /* Set when in production test mode */ + int coredump_mode; /* Set when SME has requested a coredump */ + CsrBool wol_suspend; /* Set when suspending with UniFi powered */ + +#define UF_UNCONTROLLED_PORT_Q 0 +#define UF_CONTROLLED_PORT_Q 1 + + /* Semaphore to protect the rx queues list */ + struct semaphore rx_q_sem; + + /* Spinlock to protect M4 data */ + spinlock_t m4_lock; + /* Spinlock to protect BA RX data */ + spinlock_t ba_lock; +#ifndef ALLOW_Q_PAUSE + /* Array to indicate if a particular Tx queue is paused, this may not be + * required in a multiqueue implementation since we can directly stop kernel + * queues */ + CsrUint8 tx_q_paused_flag[UNIFI_TRAFFIC_Q_MAX]; +#endif + +#ifdef CSR_WIFI_RX_PATH_SPLIT + struct workqueue_struct *rx_workqueue; + struct work_struct rx_work_struct; + rxCircularBuffer_t rxSignalBuffer; + +#endif + + CsrUint32 rxTcpThroughput; + CsrUint32 txTcpThroughput; + CsrUint32 rxUdpThroughput; + CsrUint32 txUdpThroughput; + + + CsrUint8 wapi_multicast_filter; + CsrUint8 wapi_unicast_filter; + CsrUint8 wapi_unicast_queued_pkt_filter; +}; + +typedef struct { + CsrUint16 queue_length[4]; + CsrUint8 os_queue_paused; +} unifi_OsQosInfo; + + +typedef struct { + CsrBool active; + bulk_data_param_t bulkdata; + CSR_SIGNAL signal; + CsrUint16 sn; + CsrTime recv_time; +} frame_desc_struct; + +typedef struct { + frame_desc_struct *buffer; + CsrUint16 wind_size; + CsrUint16 occupied_slots; + struct timer_list timer; + CsrUint16 timeout; + CsrUint16 expected_sn; + CsrUint16 start_sn; + CsrBool trigger_ba_after_ssn; + struct netInterface_priv *interfacePriv; + CsrUint16 tID; + CsrWifiMacAddress macAddress; + struct work_struct send_ba_err_task; +} ba_session_rx_struct; + + +typedef struct { + struct netInterface_priv *interfacePriv; + CsrUint16 tID; + CsrWifiMacAddress macAddress; +} ba_session_tx_struct; + +typedef struct netInterface_priv +{ + CsrUint16 InterfaceTag; + struct unifi_priv *privPtr; + ba_session_tx_struct *ba_session_tx[MAX_SUPPORTED_BA_SESSIONS_TX]; + ba_session_rx_struct *ba_session_rx[MAX_SUPPORTED_BA_SESSIONS_RX]; + frame_desc_struct ba_complete[MAX_BA_WIND_SIZE]; + CsrUint8 ba_complete_index; + CsrUint8 queueEnabled[UNIFI_NO_OF_TX_QS]; + struct work_struct send_m4_ready_task; + struct net_device_stats stats; + CsrUint8 interfaceMode; + CsrBool protect; + CsrWifiMacAddress bssid; + /* + * Flag to reflect state of CONNECTED indication signal. + * This indicates whether we are "joined" an Access Point (i.e. have + * nominated an AP and are receiving beacons) but give no indication + * of whether we are authenticated and/or associated. + */ + enum { + UnifiConnectedUnknown = -1, + UnifiNotConnected = 0, + UnifiConnected = 1, + } connected; +#ifdef CSR_SUPPORT_WEXT + /* Tracks when we are waiting for a netdevice state change callback */ + CsrBool wait_netdev_change; + /* True if we have successfully registered for netdev callbacks */ + CsrBool netdev_callback_registered; +#endif /* CSR_SUPPORT_WEXT */ + unsigned int netdev_registered; +#define UNIFI_MAX_MULTICAST_ADDRESSES 10 + /* The multicast addresses list that the thread needs to set. */ + u8 mc_list[UNIFI_MAX_MULTICAST_ADDRESSES*ETH_ALEN]; + /* The multicast addresses count that the thread needs to set. */ + int mc_list_count; + CsrUint32 tag; +#ifdef CSR_SUPPORT_SME + /* (un)controlled port configuration */ + unifi_port_config_t controlled_data_port; + unifi_port_config_t uncontrolled_data_port; + + /* station record maintenance related data structures */ + CsrUint8 num_stations_joined; + CsrWifiRouterCtrlStaInfo_t *(staInfo)[UNIFI_MAX_CONNECTIONS]; + struct list_head genericMgtFrames; + struct list_head genericMulticastOrBroadCastFrames; + struct list_head genericMulticastOrBroadCastMgtFrames; + struct list_head directedMaPktReq; + + /* Timer for detecting station inactivity */ + struct timer_list sta_activity_check_timer; + CsrBool sta_activity_check_enabled; + + /* Timestamp when the last inactivity check was done */ + CsrTime last_inactivity_check; + + /*number of multicast or borad cast packets queued*/ + CsrUint16 noOfbroadcastPktQueued; +#endif + /* A list to hold the buffered uncontrolled port packets */ + struct list_head rx_uncontrolled_list; + /* A list to hold the buffered controlled port packets */ + struct list_head rx_controlled_list; + /* Buffered M4 signal to take care of WPA race condition */ + CSR_SIGNAL m4_signal; + bulk_data_desc_t m4_bulk_data; + /* This should be removed and m4_hostTag should be used for checking*/ + CsrBool m4_sent; + CSR_CLIENT_TAG m4_hostTag; + CsrBool dtimActive; + CsrBool intraBssEnabled; + CsrUint32 multicastPduHostTag; /* Used to set the tim after getting + a confirm for it */ +} netInterface_priv_t; + +typedef struct maPktReqList{ + struct list_head q; + struct sk_buff *skb; + CSR_SIGNAL signal; + CSR_CLIENT_TAG hostTag; + CsrUint32 staHandler; + unsigned long jiffeTime; +}maPktReqList_t; + +#ifndef ALLOW_Q_PAUSE +#define net_is_tx_q_paused(priv, q) (priv->tx_q_paused_flag[q]) +#define net_tx_q_unpause(priv, q) (priv->tx_q_paused_flag[q] = 0) +#define net_tx_q_pause(priv, q) (priv->tx_q_paused_flag[q] = 1) +#endif + +#ifdef CSR_SUPPORT_SME +#define routerStartBuffering(priv,queue) priv->routerBufferEnable[(queue)] = TRUE; +#define routerStopBuffering(priv,queue) priv->routerBufferEnable[(queue)] = FALSE; +#define isRouterBufferEnabled(priv,queue) priv->routerBufferEnable[(queue)] +#endif + +#ifdef USE_DRIVER_LOCK +#define LOCK_DRIVER(_p) down_interruptible(&(_p)->lock) +#define UNLOCK_DRIVER(_p) up(&(_p)->lock) +#else +#define LOCK_DRIVER(_p) (void)(_p); /* as nothing */ +#define UNLOCK_DRIVER(_p) (void)(_p); /* as nothing */ +#endif /* USE_DRIVER_LOCK */ + +CsrInt32 CsrHipResultToStatus(CsrResult csrResult); + + +/* + * SDIO related functions and callbacks + */ +int uf_sdio_load(void); +void uf_sdio_unload(void); +unifi_priv_t *uf_find_instance(int inst); +int uf_find_priv(unifi_priv_t *priv); +int uf_find_netdev_priv(netInterface_priv_t *priv); +unifi_priv_t *uf_get_instance(int inst); +void uf_put_instance(int inst); +int csr_sdio_linux_install_irq(CsrSdioFunction *sdio); +int csr_sdio_linux_remove_irq(CsrSdioFunction *sdio); + +void uf_add_os_device(int bus_id, struct device *os_device); +void uf_remove_os_device(int bus_id); + + + +/* + * Claim/release SDIO + * + * For multifunction cards, we cannot grub the SDIO lock around the unifi_bh() + * as this prevents other functions using SDIO. + * Since some of CSR SDIO API is used regardless of trying to lock unifi_bh() + * we have followed this scheme: + * 1. If a function needs protection only when CSR_WIFI_SINGLE_FUNCTION is defined + * then we call CsrSdioClaim/CsrSdioRelease(). + * 2. If a function needs protection only when CSR_WIFI_SINGLE_FUNCTION is not defined + * then we call _sdio_claim_host/_sdio_claim_host(). Use of this should be restricted + * to the SDIO glue layer only (e.g. sdio_mmc.c). + * 3. If a function needs protection, regardless of the CSR_WIFI_SINGLE_FUNCTION + * then we call directly the sdio_claim_host/sdio_release_host(). + * Use of this must be restricted to the SDIO glue layer only (e.g. sdio_mmc.c). + * + * Note: The _func and function pointers are _not_ the same. + * The former is the (struct sdio_func*) context, which restricts the use to the SDIO glue layer. + * The latter is the (CsrSdioFunction*) context, which allows calls from all layers. + */ + +#ifdef CSR_WIFI_SUPPORT_MMC_DRIVER + +#ifdef CSR_WIFI_SINGLE_FUNCTION +#define CsrSdioClaim(function) sdio_claim_host((function)->priv); +#define CsrSdioRelease(function) sdio_release_host((function)->priv); + +#define _sdio_claim_host(_func) +#define _sdio_release_host(_func) + +#else +#define CsrSdioClaim(function) +#define CsrSdioRelease(function) + +#define _sdio_claim_host(_func) sdio_claim_host(_func) +#define _sdio_release_host(_func) sdio_release_host(_func) + +#endif /* CSR_WIFI_SINGLE_FUNCTION */ + +#else +#define _sdio_claim_host(_func) +#define _sdio_release_host(_func) + +#define CsrSdioClaim(function) +#define CsrSdioRelease(function) + +#endif /* CSR_WIFI_SUPPORT_MMC_DRIVER */ + + +/* + * Functions to allocate and free an ethernet device. + */ +unifi_priv_t *uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id); +int uf_free_netdevice(unifi_priv_t *priv); + +/* Allocating function for other interfaces */ +CsrBool uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, CsrUint16 interfaceTag); + +/* + * Firmware download related functions. + */ +int uf_run_unifihelper(unifi_priv_t *priv); +int uf_request_firmware_files(unifi_priv_t *priv, int is_fw); +int uf_release_firmware_files(unifi_priv_t *priv); +int uf_release_firmware(unifi_priv_t *priv, struct dlpriv *to_free); + +/* + * Functions to create and delete the device nodes. + */ +int uf_create_device_nodes(unifi_priv_t *priv, int bus_id); +void uf_destroy_device_nodes(unifi_priv_t *priv); + +/* + * Upper Edge Initialisation functions + */ +int uf_init_bh(unifi_priv_t *priv); +int uf_init_hw(unifi_priv_t *priv); + +/* Thread related helper functions */ +int uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void *)); +void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread); +void uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread); + + +/* + * Unifi Linux functions + */ +void ul_init_clients(unifi_priv_t *priv); + +/* Configuration flags */ +#define CLI_USING_WIRE_FORMAT 0x0002 +#define CLI_SME_USERSPACE 0x0020 +ul_client_t *ul_register_client(unifi_priv_t *priv, + unsigned int configuration, + udi_event_t udi_event_clbk); +int ul_deregister_client(ul_client_t *pcli); + +int ul_send_signal_unpacked(unifi_priv_t *priv, + CSR_SIGNAL *sigptr, + bulk_data_param_t *bulkdata); +int ul_send_signal_raw(unifi_priv_t *priv, + unsigned char *sigptr, int siglen, + bulk_data_param_t *bulkdata); + +void ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len); + + +/* + * Data plane operations + */ +/* + * data_tx.c + */ +int uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, + unsigned int length); + +#ifdef CSR_SUPPORT_SME +CsrBool uf_check_broadcast_bssid(unifi_priv_t *priv, const bulk_data_param_t *bulkdata); +CsrBool uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,CsrUint8 pmBit,CsrUint16 interfaceTag); +void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pmBit,CsrUint16 interfaceTag); +int uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb, + struct ethhdr *ehdr, CsrWifiRouterCtrlStaInfo_t * srcStaInfo, + const CSR_SIGNAL *signal, + bulk_data_param_t *bulkdata, + CsrUint8 macHeaderLengthInBytes); +CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord); +CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck); +void uf_process_wmm_deliver_ac_uapsd ( unifi_priv_t * priv, + CsrWifiRouterCtrlStaInfo_t * srcStaInfo, + CsrUint16 qosControl, + CsrUint16 interfaceTag); + +void uf_send_buffered_data_from_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo, CsrUint8 queue, struct list_head *txList); +void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo, CsrUint8 queue, struct list_head *txList); + +void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo); +void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo); +void uf_send_nulldata(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo); +void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata,CSR_SIGNAL *sigptr,CsrUint32 alignOffset); + + + +#endif +CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, CsrUint8 *peerMacAddress, CSR_CLIENT_TAG hostTag, CsrUint16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl, CSR_RATE TransmitRate, CSR_PRIORITY priority, CSR_PROCESS_ID senderId, bulk_data_param_t *bulkdata); +void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,CsrUint8 *sigdata, CsrUint32 siglen); +#ifdef CSR_SUPPORT_SME +void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue queue); +int uf_process_station_records_for_sending_data(unifi_priv_t *priv,CsrUint16 interfaceTag, + CsrWifiRouterCtrlStaInfo_t *srcStaInfo, + CsrWifiRouterCtrlStaInfo_t *dstStaInfo); +void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv, + struct list_head *frames_need_cfm_list, + struct list_head * list); +void send_auto_ma_packet_confirm(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + struct list_head *buffered_frames_list); +void uf_flush_list(unifi_priv_t * priv, struct list_head * list); +void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list); +tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList); +void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag); +void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 interfaceTag); +void resume_suspended_uapsd(unifi_priv_t* priv,CsrUint16 interfaceTag); +#endif +/* + * netdev.c + */ + +#ifndef P80211_OUI_LEN +#define P80211_OUI_LEN 3 +#endif +typedef struct { + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + u16 protocol; +} __attribute__ ((packed)) llc_snap_hdr_t; +int skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto); +int skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb, + const unsigned char *daddr, const unsigned char *saddr, + const CSR_SIGNAL *signal, + bulk_data_param_t *bulkdata); + +const char *result_code_str(int result); + + +/* prepares & appends the Mac header for the payload */ +int prepare_and_add_macheader(unifi_priv_t *priv, + struct sk_buff *skb, + struct sk_buff *newSkb, + CSR_PRIORITY priority, + bulk_data_param_t *bulkdata, + CsrUint16 interfaceTag, + const CsrUint8 *daddr, + const CsrUint8 *saddr, + CsrBool protection); +CSR_PRIORITY +get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv); + +void +unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority, + CSR_RATE TransmitRate, CSR_CLIENT_TAG hostTag, + CsrUint16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl, + CSR_PROCESS_ID leSenderProcessId, CsrUint8 *peerMacAddress, + CSR_SIGNAL *signal); + + +/* Pack the LSB to include station handle & status of tim set */ +#define CSR_WIFI_PACK_SENDER_ID_LSB_FOR_TIM_REQ(handle, timState) ((handle << 2) | timState) +/* get the station record handle from the sender ID */ +#define CSR_WIFI_GET_STATION_HANDLE_FROM_RECEIVER_ID(receiverProcessId) (CsrUint8) ((receiverProcessId & 0xff) >> 2) +/* get the timSet status from the sender ID */ +#define CSR_WIFI_GET_TIMSET_STATE_FROM_RECEIVER_ID(receiverProcessId) (CsrUint8) (receiverProcessId & 0x03) + +/* handle is 6 bits to accomodate in senderId LSB (only 64 station can be associated) */ +#define CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE 0x3F + +void update_tim(unifi_priv_t * priv, CsrUint16 aid, CsrUint8 setTim, CsrUint16 interfaceTag, CsrUint32 handle); +void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, CsrUint16 senderProcessId); + +/* Clear the Peer station Record, in case of wifioff/unexpected card removal */ +void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, CsrUint16 interfaceTag); + +void scroll_ba_window(unifi_priv_t *priv, + netInterface_priv_t *interfacePriv, + ba_session_rx_struct *ba_session, + CsrUint16 sn); + +CsrBool blockack_session_stop(unifi_priv_t *priv, + CsrUint16 interfaceTag, + CsrWifiRouterCtrlBlockAckRole role, + CsrUint16 tID, + CsrWifiMacAddress macAddress); +#ifdef CSR_SUPPORT_SME +/* Fetch the protection information from interface Mode */ +CsrInt8 uf_get_protection_bit_from_interfacemode(unifi_priv_t *priv, CsrUint16 interfaceTag, const CsrUint8 *daddr); +#endif + +/* Fetch the station record handler from data base for matching Mac address */ +#ifdef CSR_SUPPORT_SME +CsrWifiRouterCtrlStaInfo_t *CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(unifi_priv_t *priv, + const CsrUint8 *peerMacAddress, + CsrUint16 interfaceTag); + +/* Fetch the station record handler from data base for matching handle */ +CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_priv_t *priv, + CsrUint32 handle, + CsrUint16 interfaceTag); + +void uf_update_sta_activity(unifi_priv_t *priv, CsrUint16 interfaceTag, const CsrUint8 *peerMacAddress); +void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,CsrUint16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) +int uf_install_qdisc(struct net_device *dev); +#endif + +void uf_resume_data_plane(unifi_priv_t *priv, int queue, + CsrWifiMacAddress peer_address, + CsrUint16 interfaceTag); +void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, + CsrWifiMacAddress peer_address,CsrUint16 interfaceTag); + +int uf_register_netdev(unifi_priv_t *priv, int numOfInterface); +void uf_unregister_netdev(unifi_priv_t *priv); + +void uf_net_get_name(struct net_device *dev, char *name, int len); + +void uf_send_queue_info(unifi_priv_t *priv); +CsrUint16 uf_get_vif_identifier(CsrWifiRouterCtrlMode mode, CsrUint16 tag); + +void uf_process_rx_pending_queue(unifi_priv_t *priv, int queue, + CsrWifiMacAddress source_address, + int indicate, CsrUint16 interfaceTag); + +/* + * inet.c + */ +void uf_register_inet_notifier(void); +void uf_unregister_inet_notifier(void); + + +/* + * Suspend / Resume handlers + */ +void unifi_resume(void *ospriv); +void unifi_suspend(void *ospriv); + + +#define QOS_CAPABILITY_WMM_ENABLED 0x0001 +#define QOS_CAPABILITY_WMM_UAPSD 0x0002 +#define QOS_CAPABILITY_ACM_BE_ENABLED 0x0010 +#define QOS_CAPABILITY_ACM_BK_ENABLED 0x0020 +#define QOS_CAPABILITY_ACM_VI_ENABLED 0x0040 +#define QOS_CAPABILITY_ACM_VO_ENABLED 0x0080 +#define QOS_CAPABILITY_TS_BE_ENABLED 0x0100 +#define QOS_CAPABILITY_TS_BK_ENABLED 0x0200 +#define QOS_CAPABILITY_TS_VI_ENABLED 0x0400 +#define QOS_CAPABILITY_TS_VO_ENABLED 0x0800 + + +/* EAPOL PDUS */ +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888e +#endif +#ifndef ETH_P_WAI +#define ETH_P_WAI 0x88b4 +#endif +/* + * unifi_dbg.c + */ +void debug_string_indication(unifi_priv_t *priv, + const unsigned char *extra, + unsigned int extralen); +void debug_word16_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr); +void debug_generic_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr); + + +/* + * putest.c + */ +int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg); + +int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg); +int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg); + + +/* Macro for formatting a MAC address with a prefix string */ +#define UF_TRACE_MAC(priv, lvl, msg, addr) \ + unifi_trace(priv, lvl, \ + "%s %02x-%02x-%02x-%02x-%02x-%02x\n", \ + msg, \ + *(((CsrUint8 *)addr)+0), \ + *(((CsrUint8 *)addr)+1), \ + *(((CsrUint8 *)addr)+2), \ + *(((CsrUint8 *)addr)+3), \ + *(((CsrUint8 *)addr)+4), \ + *(((CsrUint8 *)addr)+5)) + +#endif /* __LINUX_UNIFI_PRIV_H__ */ diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c new file mode 100644 index 000000000000..4ee663fe4e4a --- /dev/null +++ b/drivers/staging/csr/unifi_sme.c @@ -0,0 +1,1164 @@ +/* + * *************************************************************************** + * FILE: unifi_sme.c + * + * PURPOSE: SME related functions. + * + * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ + +#include "unifi_priv.h" +#include "csr_wifi_hip_unifi.h" +#include "csr_wifi_hip_conversions.h" + + + + + int +convert_sme_error(CsrResult error) +{ + switch (error) { + case CSR_RESULT_SUCCESS: + return 0; + case CSR_RESULT_FAILURE: + case CSR_WIFI_RESULT_NOT_FOUND: + case CSR_WIFI_RESULT_TIMED_OUT: + case CSR_WIFI_RESULT_CANCELLED: + case CSR_WIFI_RESULT_UNAVAILABLE: + return -EIO; + case CSR_WIFI_RESULT_NO_ROOM: + return -EBUSY; + case CSR_WIFI_RESULT_INVALID_PARAMETER: + return -EINVAL; + case CSR_WIFI_RESULT_UNSUPPORTED: + return -EOPNOTSUPP; + default: + return -EIO; + } +} + + +/* + * --------------------------------------------------------------------------- + * sme_log_event + * + * Callback function to be registered as the SME event callback. + * Copies the signal content into a new udi_log_t struct and adds + * it to the read queue for the SME client. + * + * Arguments: + * arg This is the value given to unifi_add_udi_hook, in + * this case a pointer to the client instance. + * signal Pointer to the received signal. + * signal_len Size of the signal structure in bytes. + * bulkdata Pointers to any associated bulk data. + * dir Direction of the signal. Zero means from host, + * non-zero means to host. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ + void +sme_log_event(ul_client_t *pcli, + const u8 *signal, int signal_len, + const bulk_data_param_t *bulkdata, + int dir) +{ + unifi_priv_t *priv; + CSR_SIGNAL unpacked_signal; + CsrWifiSmeDataBlock mlmeCommand; + CsrWifiSmeDataBlock dataref1; + CsrWifiSmeDataBlock dataref2; + CsrResult result = CSR_RESULT_SUCCESS; + int r; + + /* Following bits are encoded in hostTag These are there to ensure that hostTags are unique*/ +#define CSR_SME_DATA 0x00000000 /* Frames Sent by SME */ +#define CSR_PAL_DATA 0X10000000 /* Frames Sent by PAL-D*/ +#define CSR_NME_DATA 0x20000000 /* Frames Sent by NME*/ +#define APPLICATION_DATA 0x30000000 /* Frames Sent by Application*/ + + func_enter(); + /* Just a sanity check */ + if ((signal == NULL) || (signal_len <= 0)) { + func_exit(); + return; + } + + priv = uf_find_instance(pcli->instance); + if (!priv) { + unifi_error(priv, "sme_log_event: invalid priv\n"); + func_exit(); + return; + } + + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_log_event: invalid smepriv\n"); + func_exit(); + return; + } + + unifi_trace(priv, UDBG3, + "sme_log_event: Process signal 0x%.4X\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(signal)); + + + /* If the signal is known, then do any filtering required, otherwise it pass it to the SME. */ + r = read_unpack_signal(signal, &unpacked_signal); + if (r == CSR_RESULT_SUCCESS) { + if ((unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_STRING_INDICATION_ID) || + (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_WORD16_INDICATION_ID)) + { + func_exit(); + return; + } + if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_INDICATION_ID) + { + CsrUint16 frmCtrl; + CsrBool unicastPdu = TRUE; + CsrUint8 *macHdrLocation; + CsrUint8 *raddr = NULL, *taddr = NULL; + CsrWifiMacAddress peerMacAddress; + /* Check if we need to send CsrWifiRouterCtrlMicFailureInd*/ + CSR_MA_PACKET_INDICATION *ind = &unpacked_signal.u.MaPacketIndication; + + macHdrLocation = (CsrUint8 *) bulkdata->d[0].os_data_ptr; + /* Fetch the frame control value from mac header */ + frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation); + + /* Point to the addresses */ + raddr = macHdrLocation + MAC_HEADER_ADDR1_OFFSET; + taddr = macHdrLocation + MAC_HEADER_ADDR2_OFFSET; + + CsrMemCpy(peerMacAddress.a, taddr, ETH_ALEN); + + if(ind->ReceptionStatus == CSR_MICHAEL_MIC_ERROR) + { + if (*raddr & 0x1) + unicastPdu = FALSE; + + CsrWifiRouterCtrlMicFailureIndSend (priv->CSR_WIFI_SME_IFACEQUEUE, 0, + (ind->VirtualInterfaceIdentifier & 0xff),peerMacAddress, + unicastPdu); + return; + } + else + { + if(ind->ReceptionStatus == CSR_RX_SUCCESS) + { + CsrUint8 pmBit = (frmCtrl & 0x1000)?0x01:0x00; + CsrUint16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0xff); + CsrWifiRouterCtrlStaInfo_t *srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,taddr,interfaceTag); + if((srcStaInfo != NULL) && (uf_check_broadcast_bssid(priv, bulkdata)== FALSE)) + { + uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag); + + /* Update station last activity flag */ + srcStaInfo->activity_flag = TRUE; + } + } + } + } + + if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_CONFIRM_ID) + { + CSR_MA_PACKET_CONFIRM *cfm = &unpacked_signal.u.MaPacketConfirm; + CsrUint16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff); + netInterface_priv_t *interfacePriv; + CSR_MA_PACKET_REQUEST *req; + CsrWifiMacAddress peerMacAddress; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) + { + unifi_error(priv, "Bad MA_PACKET_CONFIRM interfaceTag %d\n", interfaceTag); + func_exit(); + return; + } + + unifi_trace(priv,UDBG1,"MA-PACKET Confirm (%x, %x)\n", cfm->HostTag, cfm->TransmissionStatus); + + interfacePriv = priv->interfacePriv[interfaceTag]; +#ifdef CSR_SUPPORT_SME + if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || + interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { + + if(cfm->HostTag == interfacePriv->multicastPduHostTag){ + uf_process_ma_pkt_cfm_for_ap(priv ,interfaceTag, cfm); + } + } +#endif + + req = &interfacePriv->m4_signal.u.MaPacketRequest; + + if(cfm->HostTag & 0x80000000) + { + if (cfm->TransmissionStatus != CSR_TX_SUCCESSFUL) + { + result = CSR_RESULT_FAILURE; + } +#ifdef CSR_SUPPORT_SME + memcpy(peerMacAddress.a, req->Ra.x, ETH_ALEN); + /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/ + if (interfacePriv->m4_sent && (cfm->HostTag == interfacePriv->m4_hostTag)) + { + unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__); + CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, + interfaceTag, + peerMacAddress, + result); + interfacePriv->m4_sent = FALSE; + interfacePriv->m4_hostTag = 0xffffffff; + } +#endif + /* If EAPOL was requested via router APIs then send cfm else ignore*/ + if((cfm->HostTag & 0x80000000) != CSR_WIFI_EAPOL_M4_HOST_TAG) { + CsrWifiRouterMaPacketCfmSend((CsrUint16)signal[2], + cfm->VirtualInterfaceIdentifier, + result, + (cfm->HostTag & 0x3fffffff), cfm->Rate); + } else { + unifi_trace(priv, UDBG1, "%s: M4 received from netdevice\n", __FUNCTION__); + } + func_exit(); + return; + } + } + } + + mlmeCommand.length = signal_len; + mlmeCommand.data = (CsrUint8*)signal; + + dataref1.length = bulkdata->d[0].data_length; + if (dataref1.length > 0) { + dataref1.data = (CsrUint8 *) bulkdata->d[0].os_data_ptr; + } else + { + dataref1.data = NULL; + } + + dataref2.length = bulkdata->d[1].data_length; + if (dataref2.length > 0) { + dataref2.data = (CsrUint8 *) bulkdata->d[1].os_data_ptr; + } else + { + dataref2.data = NULL; + } + + CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, mlmeCommand.length, mlmeCommand.data, + dataref1.length, dataref1.data, + dataref2.length, dataref2.data); + + func_exit(); +} /* sme_log_event() */ + + +/* + * --------------------------------------------------------------------------- + * uf_sme_port_state + * + * Return the state of the controlled port. + * + * Arguments: + * priv Pointer to device private context struct + * address Pointer to the destination for tx or sender for rx address + * queue Controlled or uncontrolled queue + * + * Returns: + * An unifi_ControlledPortAction value. + * --------------------------------------------------------------------------- + */ +CsrWifiRouterCtrlPortAction +uf_sme_port_state(unifi_priv_t *priv, unsigned char *address, int queue, CsrUint16 interfaceTag) +{ + int i; + unifi_port_config_t *port; + netInterface_priv_t *interfacePriv; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_sme_port_state: bad interfaceTag\n"); + return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + } + + interfacePriv = priv->interfacePriv[interfaceTag]; + + if (queue == UF_CONTROLLED_PORT_Q) { + port = &interfacePriv->controlled_data_port; + } else { + port = &interfacePriv->uncontrolled_data_port; + } + + if (!port->entries_in_use) { + unifi_trace(priv, UDBG5, "No port configurations, return Discard.\n"); + return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD; + } + + /* If the port configuration is common for all destinations, return it. */ + if (port->overide_action == UF_DATA_PORT_OVERIDE) { + unifi_trace(priv, UDBG5, "Single port configuration (%d).\n", + port->port_cfg[0].port_action); + return port->port_cfg[0].port_action; + } + + unifi_trace(priv, UDBG5, "Multiple (%d) port configurations.\n", port->entries_in_use); + + /* If multiple configurations exist.. */ + for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + /* .. go through the list and match the destination address. */ + if (port->port_cfg[i].in_use && + memcmp(address, port->port_cfg[i].mac_address.a, ETH_ALEN) == 0) { + /* Return the desired action. */ + return port->port_cfg[i].port_action; + } + } + + /* Could not find any information, return Open. */ + unifi_trace(priv, UDBG5, "port configuration not found, return Open.\n"); + return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; +} /* uf_sme_port_state() */ + +/* + * --------------------------------------------------------------------------- + * uf_sme_port_config_handle + * + * Return the port config handle of the controlled/uncontrolled port. + * + * Arguments: + * priv Pointer to device private context struct + * address Pointer to the destination for tx or sender for rx address + * queue Controlled or uncontrolled queue + * + * Returns: + * An unifi_port_cfg_t* . + * --------------------------------------------------------------------------- + */ +unifi_port_cfg_t* +uf_sme_port_config_handle(unifi_priv_t *priv, unsigned char *address, int queue, CsrUint16 interfaceTag) +{ + int i; + unifi_port_config_t *port; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_sme_port_config_handle: bad interfaceTag\n"); + return NULL; + } + + if (queue == UF_CONTROLLED_PORT_Q) { + port = &interfacePriv->controlled_data_port; + } else { + port = &interfacePriv->uncontrolled_data_port; + } + + if (!port->entries_in_use) { + unifi_trace(priv, UDBG5, "No port configurations, return Discard.\n"); + return NULL; + } + + /* If the port configuration is common for all destinations, return it. */ + if (port->overide_action == UF_DATA_PORT_OVERIDE) { + unifi_trace(priv, UDBG5, "Single port configuration (%d).\n", + port->port_cfg[0].port_action); + if (address) { + unifi_trace(priv, UDBG5, "addr[0] = %x, addr[1] = %x, addr[2] = %x, addr[3] = %x\n", address[0], address[1], address[2], address[3]); + } + return &port->port_cfg[0]; + } + + unifi_trace(priv, UDBG5, "Multiple port configurations.\n"); + + /* If multiple configurations exist.. */ + for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) { + /* .. go through the list and match the destination address. */ + if (port->port_cfg[i].in_use && + memcmp(address, port->port_cfg[i].mac_address.a, ETH_ALEN) == 0) { + /* Return the desired action. */ + return &port->port_cfg[i]; + } + } + + /* Could not find any information, return Open. */ + unifi_trace(priv, UDBG5, "port configuration not found, returning NULL (debug).\n"); + return NULL; +} /* uf_sme_port_config_handle */ + +void +uf_multicast_list_wq(struct work_struct *work) +{ + unifi_priv_t *priv = container_of(work, unifi_priv_t, + multicast_list_task); + int i; + CsrUint16 interfaceTag = 0; + CsrWifiMacAddress* multicast_address_list = NULL; + int mc_count; + u8 *mc_list; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "uf_multicast_list_wq: bad interfaceTag\n"); + return; + } + + unifi_trace(priv, UDBG5, + "uf_multicast_list_wq: list count = %d\n", + interfacePriv->mc_list_count); + + /* Flush the current list */ + CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, interfaceTag, CSR_WIFI_SME_LIST_ACTION_FLUSH, 0, NULL); + + mc_count = interfacePriv->mc_list_count; + mc_list = interfacePriv->mc_list; + /* + * Allocate a new list, need to free it later + * in unifi_mgt_multicast_address_cfm(). + */ + multicast_address_list = CsrPmemAlloc(mc_count * sizeof(CsrWifiMacAddress)); + + if (multicast_address_list == NULL) { + return; + } + + for (i = 0; i < mc_count; i++) { + memcpy(multicast_address_list[i].a, mc_list, ETH_ALEN); + mc_list += ETH_ALEN; + } + + if (priv->smepriv == NULL) { + CsrPmemFree(multicast_address_list); + return; + } + + CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, + interfaceTag, + CSR_WIFI_SME_LIST_ACTION_ADD, + mc_count, multicast_address_list); + + /* The SME will take a copy of the addreses*/ + CsrPmemFree(multicast_address_list); +} + + +int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) +{ + unifi_cfg_power_t cfg_power; + int rc; + + if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); + return -EFAULT; + } + + switch (cfg_power) { + case UNIFI_CFG_POWER_OFF: + rc = sme_sys_suspend(priv); + if (rc) { + return rc; + } + break; + case UNIFI_CFG_POWER_ON: + rc = sme_sys_resume(priv); + if (rc) { + return rc; + } + break; + default: + unifi_error(priv, "WIFI POWER: Unknown value.\n"); + return -EINVAL; + } + + return 0; +} + + +int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg) +{ + unifi_cfg_powersave_t cfg_power_save; + CsrWifiSmePowerConfig powerConfig; + int rc; + + if (get_user(cfg_power_save, (unifi_cfg_powersave_t*)(((unifi_cfg_command_t*)arg) + 1))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); + return -EFAULT; + } + + /* Get the coex info from the SME */ + rc = sme_mgt_power_config_get(priv, &powerConfig); + if (rc) { + unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n"); + return rc; + } + + switch (cfg_power_save) { + case UNIFI_CFG_POWERSAVE_NONE: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW; + break; + case UNIFI_CFG_POWERSAVE_FAST: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED; + break; + case UNIFI_CFG_POWERSAVE_FULL: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH; + break; + case UNIFI_CFG_POWERSAVE_AUTO: + powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO; + break; + default: + unifi_error(priv, "POWERSAVE: Unknown value.\n"); + return -EINVAL; + } + + rc = sme_mgt_power_config_set(priv, &powerConfig); + + if (rc) { + unifi_error(priv, "UNIFI_CFG: Set unifi_PowerConfigValue failed.\n"); + } + + return rc; +} + + +int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg) +{ + unifi_cfg_powersupply_t cfg_power_supply; + CsrWifiSmeHostConfig hostConfig; + int rc; + + if (get_user(cfg_power_supply, (unifi_cfg_powersupply_t*)(((unifi_cfg_command_t*)arg) + 1))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); + return -EFAULT; + } + + /* Get the coex info from the SME */ + rc = sme_mgt_host_config_get(priv, &hostConfig); + if (rc) { + unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n"); + return rc; + } + + switch (cfg_power_supply) { + case UNIFI_CFG_POWERSUPPLY_MAINS: + hostConfig.powerMode = CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE; + break; + case UNIFI_CFG_POWERSUPPLY_BATTERIES: + hostConfig.powerMode = CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE; + break; + default: + unifi_error(priv, "POWERSUPPLY: Unknown value.\n"); + return -EINVAL; + } + + rc = sme_mgt_host_config_set(priv, &hostConfig); + if (rc) { + unifi_error(priv, "UNIFI_CFG: Set unifi_HostConfigValue failed.\n"); + } + + return rc; +} + + +int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg) +{ + unsigned char *tclas_buffer; + unsigned int tclas_buffer_length; + tclas_t *dhcp_tclas; + int rc; + + /* Free any TCLASs previously allocated */ + if (priv->packet_filters.tclas_ies_length) { + CsrPmemFree(priv->filter_tclas_ies); + priv->filter_tclas_ies = NULL; + } + + tclas_buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int); + if (copy_from_user(&priv->packet_filters, (void*)tclas_buffer, + sizeof(uf_cfg_bcast_packet_filter_t))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the filter struct\n"); + return -EFAULT; + } + + tclas_buffer_length = priv->packet_filters.tclas_ies_length; + + /* Allocate TCLASs if necessary */ + if (priv->packet_filters.dhcp_filter) { + priv->packet_filters.tclas_ies_length += sizeof(tclas_t); + } + if (priv->packet_filters.tclas_ies_length > 0) { + priv->filter_tclas_ies = CsrPmemAlloc(priv->packet_filters.tclas_ies_length); + if (priv->filter_tclas_ies == NULL) { + return -ENOMEM; + } + if (tclas_buffer_length) { + tclas_buffer += sizeof(uf_cfg_bcast_packet_filter_t) - sizeof(unsigned char*); + if (copy_from_user(priv->filter_tclas_ies, + tclas_buffer, + tclas_buffer_length)) { + unifi_error(priv, "UNIFI_CFG: Failed to get the TCLAS buffer\n"); + return -EFAULT; + } + } + } + + if(priv->packet_filters.dhcp_filter) + { + /* Append the DHCP tclas IE */ + dhcp_tclas = (tclas_t*)(priv->filter_tclas_ies + tclas_buffer_length); + memset(dhcp_tclas, 0, sizeof(tclas_t)); + dhcp_tclas->element_id = 14; + dhcp_tclas->length = sizeof(tcpip_clsfr_t) + 1; + dhcp_tclas->user_priority = 0; + dhcp_tclas->tcp_ip_cls_fr.cls_fr_type = 1; + dhcp_tclas->tcp_ip_cls_fr.version = 4; + ((CsrUint8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[0] = 0x00; + ((CsrUint8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[1] = 0x44; + ((CsrUint8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[0] = 0x00; + ((CsrUint8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[1] = 0x43; + dhcp_tclas->tcp_ip_cls_fr.protocol = 0x11; + dhcp_tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6 + } + + rc = sme_mgt_packet_filter_set(priv); + + return rc; +} + + +int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg) +{ + CsrUint8 wmm_qos_info; + int rc = 0; + + if (get_user(wmm_qos_info, (CsrUint8*)(((unifi_cfg_command_t*)arg) + 1))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); + return -EFAULT; + } + + /* Store the value in the connection info */ + priv->connection_config.wmmQosInfo = wmm_qos_info; + + return rc; +} + + +int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg) +{ + CsrUint32 addts_tid; + CsrUint8 addts_ie_length; + CsrUint8 *addts_ie; + CsrUint8 *addts_params; + CsrWifiSmeDataBlock tspec; + CsrWifiSmeDataBlock tclas; + int rc; + + addts_params = (CsrUint8*)(((unifi_cfg_command_t*)arg) + 1); + if (get_user(addts_tid, (CsrUint32*)addts_params)) { + unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n"); + return -EFAULT; + } + + addts_params += sizeof(CsrUint32); + if (get_user(addts_ie_length, (CsrUint8*)addts_params)) { + unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG4, "addts: tid = 0x%x ie_length = %d\n", + addts_tid, addts_ie_length); + + addts_ie = CsrPmemAlloc(addts_ie_length); + if (addts_ie == NULL) { + unifi_error(priv, + "unifi_cfg_wmm_addts: Failed to malloc %d bytes for addts_ie buffer\n", + addts_ie_length); + return -ENOMEM; + } + + addts_params += sizeof(CsrUint8); + rc = copy_from_user(addts_ie, addts_params, addts_ie_length); + if (rc) { + unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the addts buffer\n"); + CsrPmemFree(addts_ie); + return -EFAULT; + } + + tspec.data = addts_ie; + tspec.length = addts_ie_length; + tclas.data = NULL; + tclas.length = 0; + + rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_ADD, addts_tid, + &tspec, &tclas); + + CsrPmemFree(addts_ie); + return rc; +} + + +int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg) +{ + CsrUint32 delts_tid; + CsrUint8 *delts_params; + CsrWifiSmeDataBlock tspec; + CsrWifiSmeDataBlock tclas; + int rc; + + delts_params = (CsrUint8*)(((unifi_cfg_command_t*)arg) + 1); + if (get_user(delts_tid, (CsrUint32*)delts_params)) { + unifi_error(priv, "unifi_cfg_wmm_delts: Failed to get the argument\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG4, "delts: tid = 0x%x\n", delts_tid); + + tspec.data = tclas.data = NULL; + tspec.length = tclas.length = 0; + + rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_REMOVE, delts_tid, + &tspec, &tclas); + + return rc; +} + +int unifi_cfg_strict_draft_n(unifi_priv_t *priv, unsigned char *arg) +{ + CsrBool strict_draft_n; + CsrUint8 *strict_draft_n_params; + int rc; + + CsrWifiSmeStaConfig staConfig; + CsrWifiSmeDeviceConfig deviceConfig; + + strict_draft_n_params = (CsrUint8*)(((unifi_cfg_command_t*)arg) + 1); + if (get_user(strict_draft_n, (CsrBool*)strict_draft_n_params)) { + unifi_error(priv, "unifi_cfg_strict_draft_n: Failed to get the argument\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG4, "strict_draft_n: = %s\n", ((strict_draft_n) ? "yes":"no")); + + rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig); + + if (rc) { + unifi_warning(priv, "unifi_cfg_strict_draft_n: Get unifi_SMEConfigValue failed.\n"); + return -EFAULT; + } + + deviceConfig.enableStrictDraftN = strict_draft_n; + + rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig); + if (rc) { + unifi_warning(priv, "unifi_cfg_strict_draft_n: Set unifi_SMEConfigValue failed.\n"); + rc = -EFAULT; + } + + return rc; +} + + +int unifi_cfg_enable_okc(unifi_priv_t *priv, unsigned char *arg) +{ + CsrBool enable_okc; + CsrUint8 *enable_okc_params; + int rc; + + CsrWifiSmeStaConfig staConfig; + CsrWifiSmeDeviceConfig deviceConfig; + + enable_okc_params = (CsrUint8*)(((unifi_cfg_command_t*)arg) + 1); + if (get_user(enable_okc, (CsrBool*)enable_okc_params)) { + unifi_error(priv, "unifi_cfg_enable_okc: Failed to get the argument\n"); + return -EFAULT; + } + + unifi_trace(priv, UDBG4, "enable_okc: = %s\n", ((enable_okc) ? "yes":"no")); + + rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig); + if (rc) { + unifi_warning(priv, "unifi_cfg_enable_okc: Get unifi_SMEConfigValue failed.\n"); + return -EFAULT; + } + + staConfig.enableOpportunisticKeyCaching = enable_okc; + + rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig); + if (rc) { + unifi_warning(priv, "unifi_cfg_enable_okc: Set unifi_SMEConfigValue failed.\n"); + rc = -EFAULT; + } + + return rc; +} + + +int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg) +{ + unifi_cfg_get_t get_cmd; + char inst_name[IFNAMSIZ]; + int rc; + + if (get_user(get_cmd, (unifi_cfg_get_t*)(((unifi_cfg_command_t*)arg) + 1))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); + return -EFAULT; + } + + switch (get_cmd) { + case UNIFI_CFG_GET_COEX: + { + CsrWifiSmeCoexInfo coexInfo; + /* Get the coex info from the SME */ + rc = sme_mgt_coex_info_get(priv, &coexInfo); + if (rc) { + unifi_error(priv, "UNIFI_CFG: Get unifi_CoexInfoValue failed.\n"); + return rc; + } + + /* Copy the info to the out buffer */ + if (copy_to_user((void*)arg, + &coexInfo, + sizeof(CsrWifiSmeCoexInfo))) { + unifi_error(priv, "UNIFI_CFG: Failed to copy the coex info\n"); + return -EFAULT; + } + break; + } + case UNIFI_CFG_GET_POWER_MODE: + { + CsrWifiSmePowerConfig powerConfig; + rc = sme_mgt_power_config_get(priv, &powerConfig); + if (rc) { + unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n"); + return rc; + } + + /* Copy the info to the out buffer */ + if (copy_to_user((void*)arg, + &powerConfig.powerSaveLevel, + sizeof(CsrWifiSmePowerSaveLevel))) { + unifi_error(priv, "UNIFI_CFG: Failed to copy the power save info\n"); + return -EFAULT; + } + break; + } + case UNIFI_CFG_GET_POWER_SUPPLY: + { + CsrWifiSmeHostConfig hostConfig; + rc = sme_mgt_host_config_get(priv, &hostConfig); + if (rc) { + unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n"); + return rc; + } + + /* Copy the info to the out buffer */ + if (copy_to_user((void*)arg, + &hostConfig.powerMode, + sizeof(CsrWifiSmeHostPowerMode))) { + unifi_error(priv, "UNIFI_CFG: Failed to copy the host power mode\n"); + return -EFAULT; + } + break; + } + case UNIFI_CFG_GET_VERSIONS: + break; + case UNIFI_CFG_GET_INSTANCE: + { + CsrUint16 InterfaceId=0; + uf_net_get_name(priv->netdev[InterfaceId], &inst_name[0], sizeof(inst_name)); + + /* Copy the info to the out buffer */ + if (copy_to_user((void*)arg, + &inst_name[0], + sizeof(inst_name))) { + unifi_error(priv, "UNIFI_CFG: Failed to copy the instance name\n"); + return -EFAULT; + } + } + break; + + case UNIFI_CFG_GET_AP_CONFIG: + { +#ifdef CSR_SUPPORT_WEXT_AP + uf_cfg_ap_config_t cfg_ap_config; + cfg_ap_config.channel = priv->ap_config.channel; + cfg_ap_config.beaconInterval = priv->ap_mac_config.beaconInterval; + cfg_ap_config.wmmEnabled = priv->ap_mac_config.wmmEnabled; + cfg_ap_config.dtimPeriod = priv->ap_mac_config.dtimPeriod; + cfg_ap_config.phySupportedBitmap = priv->ap_mac_config.phySupportedBitmap; + if (copy_to_user((void*)arg, + &cfg_ap_config, + sizeof(uf_cfg_ap_config_t))) { + unifi_error(priv, "UNIFI_CFG: Failed to copy the AP configuration\n"); + return -EFAULT; + } +#else + return -EPERM; +#endif + } + break; + + + default: + unifi_error(priv, "unifi_cfg_get_info: Unknown value.\n"); + return -EINVAL; + } + + return 0; +} +#ifdef CSR_SUPPORT_WEXT_AP +int + uf_configure_supported_rates(CsrUint8 * supportedRates, CsrUint8 phySupportedBitmap) +{ + int i=0; + CsrBool b=FALSE, g = FALSE, n = FALSE; + b = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_B; + n = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_N; + g = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_G; + if(b || g) { + supportedRates[i++]=0x82; + supportedRates[i++]=0x84; + supportedRates[i++]=0x8b; + supportedRates[i++]=0x96; + } else if(n) { + supportedRates[i++]=0x02; + supportedRates[i++]=0x04; + supportedRates[i++]=0x0b; + supportedRates[i++]=0x16; + } + if(g) { + if(!b) { + supportedRates[i++]=0x8c; + supportedRates[i++]=0x98; + supportedRates[i++]=0xb0; + } else { + supportedRates[i++]=0x0c; + supportedRates[i++]=0x18; + supportedRates[i++]=0x30; + } + supportedRates[i++]=0x48; + supportedRates[i++]=0x12; + supportedRates[i++]=0x24; + supportedRates[i++]=0x60; + supportedRates[i++]=0x6c; + } + return i; +} +int unifi_cfg_set_ap_config(unifi_priv_t * priv,unsigned char* arg) +{ + uf_cfg_ap_config_t cfg_ap_config; + char *buffer; + + buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int); + if (copy_from_user(&cfg_ap_config, (void*)buffer, + sizeof(uf_cfg_ap_config_t))) { + unifi_error(priv, "UNIFI_CFG: Failed to get the ap config struct\n"); + return -EFAULT; + } + priv->ap_config.channel = cfg_ap_config.channel; + priv->ap_mac_config.dtimPeriod = cfg_ap_config.dtimPeriod; + priv->ap_mac_config.beaconInterval = cfg_ap_config.beaconInterval; + priv->group_sec_config.apGroupkeyTimeout = cfg_ap_config.groupkeyTimeout; + priv->group_sec_config.apStrictGtkRekey = cfg_ap_config.strictGtkRekeyEnabled; + priv->group_sec_config.apGmkTimeout = cfg_ap_config.gmkTimeout; + priv->group_sec_config.apResponseTimeout = cfg_ap_config.responseTimeout; + priv->group_sec_config.apRetransLimit = cfg_ap_config.retransLimit; + + priv->ap_mac_config.shortSlotTimeEnabled = cfg_ap_config.shortSlotTimeEnabled; + priv->ap_mac_config.ctsProtectionType=cfg_ap_config.ctsProtectionType; + + priv->ap_mac_config.wmmEnabled = cfg_ap_config.wmmEnabled; + + priv->ap_mac_config.apHtParams.rxStbc=cfg_ap_config.rxStbc; + priv->ap_mac_config.apHtParams.rifsModeAllowed=cfg_ap_config.rifsModeAllowed; + + priv->ap_mac_config.phySupportedBitmap = cfg_ap_config.phySupportedBitmap; + priv->ap_mac_config.maxListenInterval=cfg_ap_config.maxListenInterval; + + priv->ap_mac_config.supportedRatesCount= uf_configure_supported_rates(priv->ap_mac_config.supportedRates,priv->ap_mac_config.phySupportedBitmap); + + return 0; +} + +#endif +#ifdef CSR_SUPPORT_WEXT + + void +uf_sme_config_wq(struct work_struct *work) +{ + CsrWifiSmeStaConfig staConfig; + CsrWifiSmeDeviceConfig deviceConfig; + unifi_priv_t *priv = container_of(work, unifi_priv_t, sme_config_task); + + /* Register to receive indications from the SME */ + CsrWifiSmeEventMaskSetReqSend(0, + CSR_WIFI_SME_INDICATIONS_WIFIOFF | CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY | + CSR_WIFI_SME_INDICATIONS_MEDIASTATUS | CSR_WIFI_SME_INDICATIONS_MICFAILURE); + + if (sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig)) { + unifi_warning(priv, "uf_sme_config_wq: Get unifi_SMEConfigValue failed.\n"); + return; + } + + if (priv->if_index == CSR_INDEX_5G) { + staConfig.ifIndex = CSR_WIFI_SME_RADIO_IF_GHZ_5_0; + } else { + staConfig.ifIndex = CSR_WIFI_SME_RADIO_IF_GHZ_2_4; + } + + deviceConfig.trustLevel = (CsrWifiSme80211dTrustLevel)tl_80211d; + if (sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig)) { + unifi_warning(priv, + "SME config for 802.11d Trust Level and Radio Band failed.\n"); + return; + } + +} /* uf_sme_config_wq() */ + +#endif /* CSR_SUPPORT_WEXT */ + + +/* + * --------------------------------------------------------------------------- + * uf_ta_ind_wq + * + * Deferred work queue function to send Traffic Analysis protocols + * indications to the SME. + * These are done in a deferred work queue for two reasons: + * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context + * - we want to load the main driver data path as lightly as possible + * + * The TA classifications already come from a workqueue. + * + * Arguments: + * work Pointer to work queue item. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ + void +uf_ta_ind_wq(struct work_struct *work) +{ + struct ta_ind *ind = container_of(work, struct ta_ind, task); + unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_ind_work); + CsrUint16 interfaceTag = 0; + + + CsrWifiRouterCtrlTrafficProtocolIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, + interfaceTag, + ind->packet_type, + ind->direction, + ind->src_addr); + ind->in_use = 0; + +} /* uf_ta_ind_wq() */ + + +/* + * --------------------------------------------------------------------------- + * uf_ta_sample_ind_wq + * + * Deferred work queue function to send Traffic Analysis sample + * indications to the SME. + * These are done in a deferred work queue for two reasons: + * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context + * - we want to load the main driver data path as lightly as possible + * + * The TA classifications already come from a workqueue. + * + * Arguments: + * work Pointer to work queue item. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ + void +uf_ta_sample_ind_wq(struct work_struct *work) +{ + struct ta_sample_ind *ind = container_of(work, struct ta_sample_ind, task); + unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_sample_ind_work); + CsrUint16 interfaceTag = 0; + + unifi_trace(priv, UDBG5, "rxtcp %d txtcp %d rxudp %d txudp %d prio %d\n", + priv->rxTcpThroughput, + priv->txTcpThroughput, + priv->rxUdpThroughput, + priv->txUdpThroughput, + priv->bh_thread.prio); + + if(priv->rxTcpThroughput > 1000) + { + if (bh_priority == -1 && priv->bh_thread.prio != 1) + { + struct sched_param param; + priv->bh_thread.prio = 1; + unifi_trace(priv, UDBG1, "%s new thread (RT) priority = %d\n", + priv->bh_thread.name, priv->bh_thread.prio); + param.sched_priority = priv->bh_thread.prio; + sched_setscheduler(priv->bh_thread.thread_task, SCHED_FIFO, ¶m); + } + } else + { + if (bh_priority == -1 && priv->bh_thread.prio != DEFAULT_PRIO) + { + struct sched_param param; + param.sched_priority = 0; + sched_setscheduler(priv->bh_thread.thread_task, SCHED_NORMAL, ¶m); + priv->bh_thread.prio = DEFAULT_PRIO; + unifi_trace(priv, UDBG1, "%s new thread priority = %d\n", + priv->bh_thread.name, priv->bh_thread.prio); + set_user_nice(priv->bh_thread.thread_task, PRIO_TO_NICE(priv->bh_thread.prio)); + } + } + + CsrWifiRouterCtrlTrafficSampleIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, interfaceTag, ind->stats); + + ind->in_use = 0; + +} /* uf_ta_sample_ind_wq() */ + + +/* + * --------------------------------------------------------------------------- + * uf_send_m4_ready_wq + * + * Deferred work queue function to send M4 ReadyToSend inds to the SME. + * These are done in a deferred work queue for two reasons: + * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context + * - we want to load the main driver data path as lightly as possible + * + * Arguments: + * work Pointer to work queue item. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void +uf_send_m4_ready_wq(struct work_struct *work) +{ + netInterface_priv_t *InterfacePriv = container_of(work, netInterface_priv_t, send_m4_ready_task); + CsrUint16 iface = InterfacePriv->InterfaceTag; + unifi_priv_t *priv = InterfacePriv->privPtr; + CSR_MA_PACKET_REQUEST *req = &InterfacePriv->m4_signal.u.MaPacketRequest; + CsrWifiMacAddress peer; + unsigned long flags; + + func_enter(); + + /* The peer address was stored in the signal */ + spin_lock_irqsave(&priv->m4_lock, flags); + memcpy(peer.a, req->Ra.x, sizeof(peer.a)); + spin_unlock_irqrestore(&priv->m4_lock, flags); + + /* Send a signal to SME */ + CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, iface, peer); + + UF_TRACE_MAC(priv, UDBG1, "M4ReadyToSendInd sent for peer", peer.a); + + func_exit(); + +} /* uf_send_m4_ready_wq() */ + diff --git a/drivers/staging/csr/unifi_sme.h b/drivers/staging/csr/unifi_sme.h new file mode 100644 index 000000000000..51ca92e89055 --- /dev/null +++ b/drivers/staging/csr/unifi_sme.h @@ -0,0 +1,236 @@ +/* + * *************************************************************************** + * FILE: unifi_sme.h + * + * PURPOSE: SME related definitions. + * + * Copyright (C) 2007-2011 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * *************************************************************************** + */ +#ifndef __LINUX_UNIFI_SME_H__ +#define __LINUX_UNIFI_SME_H__ 1 + +#include + +#ifdef CSR_SME_USERSPACE +#include "sme_userspace.h" +#endif + +#include "csr_wifi_sme_lib.h" + +typedef int unifi_data_port_action; + +typedef struct unifi_port_cfg +{ + /* TRUE if this port entry is allocated */ + CsrBool in_use; + CsrWifiRouterCtrlPortAction port_action; + CsrWifiMacAddress mac_address; +} unifi_port_cfg_t; + +#define UNIFI_MAX_CONNECTIONS 8 +#define UNIFI_MAX_RETRY_LIMIT 5 +#define UF_DATA_PORT_NOT_OVERIDE 0 +#define UF_DATA_PORT_OVERIDE 1 + +typedef struct unifi_port_config +{ + int entries_in_use; + int overide_action; + unifi_port_cfg_t port_cfg[UNIFI_MAX_CONNECTIONS]; +} unifi_port_config_t; + + +enum sme_request_status { + SME_REQUEST_EMPTY, + SME_REQUEST_PENDING, + SME_REQUEST_RECEIVED, + SME_REQUEST_TIMEDOUT, +}; + +/* Structure to hold a UDI logged signal */ +typedef struct { + + /* The current status of the request */ + enum sme_request_status request_status; + + /* The status the SME has passed to us */ + CsrResult reply_status; + + /* SME's reply to a get request */ + CsrWifiSmeVersions versions; + CsrWifiSmePowerConfig powerConfig; + CsrWifiSmeHostConfig hostConfig; + CsrWifiSmeStaConfig staConfig; + CsrWifiSmeDeviceConfig deviceConfig; + CsrWifiSmeCoexInfo coexInfo; + CsrWifiSmeCoexConfig coexConfig; + CsrWifiSmeMibConfig mibConfig; + CsrWifiSmeConnectionInfo connectionInfo; + CsrWifiSmeConnectionConfig connectionConfig; + CsrWifiSmeConnectionStats connectionStats; + + + /* SME's reply to a scan request */ + CsrUint16 reply_scan_results_count; + CsrWifiSmeScanResult* reply_scan_results; + +} sme_reply_t; + + +typedef struct { + CsrUint16 appHandle; + CsrWifiRouterEncapsulation encapsulation; + CsrUint16 protocol; + CsrUint8 oui[3]; + CsrUint8 in_use; +} sme_ma_unidata_ind_filter_t; + + +CsrWifiRouterCtrlPortAction uf_sme_port_state(unifi_priv_t *priv, + unsigned char *address, + int queue, + CsrUint16 interfaceTag); +unifi_port_cfg_t *uf_sme_port_config_handle(unifi_priv_t *priv, + unsigned char *address, + int queue, + CsrUint16 interfaceTag); + + + +/* Callback for event logging to SME clients */ +void sme_log_event(ul_client_t *client, const u8 *signal, int signal_len, + const bulk_data_param_t *bulkdata, int dir); + +/* The workqueue task to the set the multicast addresses list */ +void uf_multicast_list_wq(struct work_struct *work); + +/* The workqueue task to execute the TA module */ +void uf_ta_wq(struct work_struct *work); + + +/* + * SME blocking helper functions + */ +#ifdef UNIFI_DEBUG +# define sme_complete_request(priv, status) uf_sme_complete_request(priv, status, __func__) +#else +# define sme_complete_request(priv, status) uf_sme_complete_request(priv, status, NULL) +#endif + +void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func); + + +/* + * Blocking functions using the SME SYS API. + */ +int sme_sys_suspend(unifi_priv_t *priv); +int sme_sys_resume(unifi_priv_t *priv); + + +/* + * Traffic Analysis workqueue jobs + */ +void uf_ta_ind_wq(struct work_struct *work); +void uf_ta_sample_ind_wq(struct work_struct *work); + +/* + * SME config workqueue job + */ +void uf_sme_config_wq(struct work_struct *work); + +/* + * To send M4 read to send IND + */ +void uf_send_m4_ready_wq(struct work_struct *work); + +int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig); +int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig); +int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig); +int sme_mgt_host_config_get(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig); +int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig); +int sme_mgt_sme_config_get(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig); +int sme_mgt_coex_info_get(unifi_priv_t *priv, CsrWifiSmeCoexInfo *coexInfo); +int sme_mgt_packet_filter_set(unifi_priv_t *priv); +int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action, + CsrUint32 tid, CsrWifiSmeDataBlock *tspec, CsrWifiSmeDataBlock *tclas); + +#ifdef CSR_SUPPORT_WEXT +/* + * Blocking functions using the SME MGT API. + */ +int sme_mgt_wifi_on(unifi_priv_t *priv); +int sme_mgt_wifi_off(unifi_priv_t *priv); +/*int sme_mgt_set_value_async(unifi_priv_t *priv, unifi_AppValue *app_value); +int sme_mgt_get_value_async(unifi_priv_t *priv, unifi_AppValue *app_value); +int sme_mgt_get_value(unifi_priv_t *priv, unifi_AppValue *app_value); +int sme_mgt_set_value(unifi_priv_t *priv, unifi_AppValue *app_value); +*/ +int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig); +int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig); +int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig); +int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig); + +int sme_mgt_connection_info_set(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo); +int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo); +int sme_mgt_connection_config_set(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig); +int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig); +int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *connectionStats); + +int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions); + + +int sme_mgt_scan_full(unifi_priv_t *priv, CsrWifiSsid *specific_ssid, + int num_channels, unsigned char *channel_list); +int sme_mgt_scan_results_get_async(unifi_priv_t *priv, + struct iw_request_info *info, + char *scan_results, + long scan_results_len); +int sme_mgt_disconnect(unifi_priv_t *priv); +int sme_mgt_connect(unifi_priv_t *priv); +int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key, + CsrWifiSmeListAction action); +int sme_mgt_pmkid(unifi_priv_t *priv, CsrWifiSmeListAction action, + CsrWifiSmePmkidList *pmkid_list); +int sme_mgt_mib_get(unifi_priv_t *priv, + unsigned char *varbind, int *length); +int sme_mgt_mib_set(unifi_priv_t *priv, + unsigned char *varbind, int length); +#ifdef CSR_SUPPORT_WEXT_AP +int sme_ap_start(unifi_priv_t *priv,CsrUint16 interface_tag,CsrWifiSmeApConfig_t *ap_config); +int sme_ap_stop(unifi_priv_t *priv,CsrUint16 interface_tag); +int sme_ap_config(unifi_priv_t *priv,CsrWifiSmeApMacConfig *ap_mac_config, CsrWifiNmeApConfig *group_security_config); +int uf_configure_supported_rates(CsrUint8 * supportedRates, CsrUint8 phySupportedBitmap); +#endif +int unifi_translate_scan(struct net_device *dev, + struct iw_request_info *info, + char *current_ev, char *end_buf, + CsrWifiSmeScanResult *scan_data, + int scan_index); + +#endif /* CSR_SUPPORT_WEXT */ + +int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_strict_draft_n(unifi_priv_t *priv, unsigned char *arg); +int unifi_cfg_enable_okc(unifi_priv_t *priv, unsigned char *arg); +#ifdef CSR_SUPPORT_WEXT_AP +int unifi_cfg_set_ap_config(unifi_priv_t * priv,unsigned char* arg); +#endif + + + +int convert_sme_error(CsrResult error); + + +#endif /* __LINUX_UNIFI_SME_H__ */ diff --git a/drivers/staging/csr/unifi_wext.h b/drivers/staging/csr/unifi_wext.h new file mode 100644 index 000000000000..ac86df92d955 --- /dev/null +++ b/drivers/staging/csr/unifi_wext.h @@ -0,0 +1,124 @@ +/* + ***************************************************************************** + * + * FILE : unifi_wext.h + * + * PURPOSE : Private header file for unifi driver support to wireless extensions. + * + * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * +***************************************************************************** + */ +#ifndef __LINUX_UNIFI_WEXT_H__ +#define __LINUX_UNIFI_WEXT_H__ 1 + +#include +#include +#include "csr_wifi_sme_prim.h" + +/* + * wext.c + */ +/* A few details needed for WEP (Wireless Equivalent Privacy) */ +#define UNIFI_MAX_KEY_SIZE 16 +#define NUM_WEPKEYS 4 +#define SMALL_KEY_SIZE 5 +#define LARGE_KEY_SIZE 13 +typedef struct wep_key_t { + int len; + unsigned char key[UNIFI_MAX_KEY_SIZE]; /* 40-bit and 104-bit keys */ +} wep_key_t; + +#define UNIFI_SCAN_ACTIVE 0 +#define UNIFI_SCAN_PASSIVE 1 +#define UNIFI_MAX_SSID_LEN 32 + +#define MAX_WPA_IE_LEN 64 +#define MAX_RSN_IE_LEN 255 + +/* + * Function to register in the netdev to report wireless stats. + */ +struct iw_statistics *unifi_get_wireless_stats(struct net_device *dev); + +void uf_sme_wext_set_defaults(unifi_priv_t *priv); + + +/* + * wext_events.c + */ +/* Functions to generate Wireless Extension events */ +void wext_send_scan_results_event(unifi_priv_t *priv); +void wext_send_assoc_event(unifi_priv_t *priv, unsigned char *bssid, + unsigned char *req_ie, int req_ie_len, + unsigned char *resp_ie, int resp_ie_len, + unsigned char *scan_ie, unsigned int scan_ie_len); +void wext_send_disassoc_event(unifi_priv_t *priv); +void wext_send_michaelmicfailure_event(unifi_priv_t *priv, + CsrUint16 count, CsrWifiMacAddress address, + CsrWifiSmeKeyType keyType, CsrUint16 interfaceTag); +void wext_send_pmkid_candidate_event(unifi_priv_t *priv, CsrWifiMacAddress bssid, CsrBool preauth_allowed, CsrUint16 interfaceTag); +void wext_send_started_event(unifi_priv_t *priv); + + +static inline int +uf_iwe_stream_add_point(struct iw_request_info *info, char *start, char *stop, + struct iw_event *piwe, char *extra) +{ + char *new_start; + + new_start = iwe_stream_add_point( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined (IW_REQUEST_FLAG_COMPAT) + info, +#endif + start, stop, piwe, extra); + if (unlikely(new_start == start)) + { + return -E2BIG; + } + + return (new_start - start); +} + + +static inline int +uf_iwe_stream_add_event(struct iw_request_info *info, char *start, char *stop, + struct iw_event *piwe, int len) +{ + char *new_start; + + new_start = iwe_stream_add_event( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined(IW_REQUEST_FLAG_COMPAT) + info, +#endif + start, stop, piwe, len); + if (unlikely(new_start == start)) { + return -E2BIG; + } + + return (new_start - start); +} + +static inline int +uf_iwe_stream_add_value(struct iw_request_info *info, char *stream, char *start, + char *stop, struct iw_event *piwe, int len) +{ + char *new_start; + + new_start = iwe_stream_add_value( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined(IW_REQUEST_FLAG_COMPAT) + info, +#endif + stream, start, stop, piwe, len); + if (unlikely(new_start == start)) { + return -E2BIG; + } + + return (new_start - start); +} + + +#endif /* __LINUX_UNIFI_WEXT_H__ */ diff --git a/drivers/staging/csr/unifiio.h b/drivers/staging/csr/unifiio.h new file mode 100644 index 000000000000..e707eedef29d --- /dev/null +++ b/drivers/staging/csr/unifiio.h @@ -0,0 +1,400 @@ +/* + * --------------------------------------------------------------------------- + * + * FILE: unifiio.h + * + * Public definitions for the UniFi linux driver. + * This is mostly ioctl command values and structs. + * + * Include or similar before this file + * + * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#ifndef __UNIFIIO_H__ +#define __UNIFIIO_H__ + +#include +#include "csr_types.h" + +#define UNIFI_GET_UDI_ENABLE _IOR('u', 1, int) +#define UNIFI_SET_UDI_ENABLE _IOW('u', 2, int) +/* Values for UDI_ENABLE */ +#define UDI_ENABLE_DATA 0x1 +#define UDI_ENABLE_CONTROL 0x2 + +/* MIB set/get. Arg is a pointer to a varbind */ +#define UNIFI_GET_MIB _IOWR('u', 3, unsigned char *) +#define UNIFI_SET_MIB _IOW ('u', 4, unsigned char *) +#define MAX_VARBIND_LENGTH 127 + +/* Private IOCTLs */ +#define SIOCIWS80211POWERSAVEPRIV SIOCIWFIRSTPRIV +#define SIOCIWG80211POWERSAVEPRIV SIOCIWFIRSTPRIV + 1 +#define SIOCIWS80211RELOADDEFAULTSPRIV SIOCIWFIRSTPRIV + 2 +#define SIOCIWSCONFWAPIPRIV SIOCIWFIRSTPRIV + 4 +#define SIOCIWSWAPIKEYPRIV SIOCIWFIRSTPRIV + 6 +#define SIOCIWSSMEDEBUGPRIV SIOCIWFIRSTPRIV + 8 +#define SIOCIWSAPCFGPRIV SIOCIWFIRSTPRIV + 10 +#define SIOCIWSAPSTARTPRIV SIOCIWFIRSTPRIV + 12 +#define SIOCIWSAPSTOPPRIV SIOCIWFIRSTPRIV + 14 +#define SIOCIWSFWRELOADPRIV SIOCIWFIRSTPRIV + 16 +#define SIOCIWSSTACKSTART SIOCIWFIRSTPRIV + 18 +#define SIOCIWSSTACKSTOP SIOCIWFIRSTPRIV + 20 + + + +#define IWPRIV_POWER_SAVE_MAX_STRING 32 +#define IWPRIV_SME_DEBUG_MAX_STRING 32 +#define IWPRIV_SME_MAX_STRING 120 + + +/* Private configuration commands */ +#define UNIFI_CFG _IOWR('u', 5, unsigned char *) +/* + * <------------------ Read/Write Buffer --------------------> + * _____________________________________________________________ + * | Cmd | Arg | ... Buffer (opt) ... | + * ------------------------------------------------------------- + * <-- uint --><-- uint --><----- unsigned char buffer ------> + * + * Cmd: A unifi_cfg_command_t command. + * Arg: Out:Length if Cmd==UNIFI_CFG_GET + * In:PowerOnOff if Cmd==UNIFI_CFG_POWER + * In:PowerMode if Cmd==UNIFI_CFG_POWERSAVE + * In:Length if Cmd==UNIFI_CFG_FILTER + * In:WMM Qos Info if Cmd==UNIFI_CFG_WMM_QOS_INFO + * Buffer: Out:Data if Cmd==UNIFI_CFG_GET + * NULL if Cmd==UNIFI_CFG_POWER + * NULL if Cmd==UNIFI_CFG_POWERSAVE + * In:Filters if Cmd==UNIFI_CFG_FILTER + * + * where Filters is a uf_cfg_bcast_packet_filter_t structure + * followed by 0 - n tclas_t structures. The length of the tclas_t + * structures is obtained by uf_cfg_bcast_packet_filter_t::tclas_ies_length. + */ + + +#define UNIFI_PUTEST _IOWR('u', 6, unsigned char *) +/* + * <------------------ Read/Write Buffer --------------------> + * _____________________________________________________________ + * | Cmd | Arg | ... Buffer (opt) ... | + * ------------------------------------------------------------- + * <-- uint --><-- uint --><----- unsigned char buffer ------> + * + * Cmd: A unifi_putest_command_t command. + * Arg: N/A if Cmd==UNIFI_PUTEST_START + * N/A if Cmd==UNIFI_PUTEST_STOP + * In:int (Clock Speed) if Cmd==UNIFI_PUTEST_SET_SDIO_CLOCK + * In/Out:sizeof(unifi_putest_cmd52) if Cmd==UNIFI_PUTEST_CMD52_READ + * In:sizeof(unifi_putest_cmd52) if Cmd==UNIFI_PUTEST_CMD52_WRITE + * In:uint (f/w file name length) if Cmd==UNIFI_PUTEST_DL_FW + * Buffer: NULL if Cmd==UNIFI_PUTEST_START + * NULL if Cmd==UNIFI_PUTEST_STOP + * NULL if Cmd==UNIFI_PUTEST_SET_SDIO_CLOCK + * In/Out:unifi_putest_cmd52 if Cmd==UNIFI_PUTEST_CMD52_READ + * In:unifi_putest_cmd52 if Cmd==UNIFI_PUTEST_CMD52_WRITE + * In:f/w file name if Cmd==UNIFI_PUTEST_DL_FW + */ + +#define UNIFI_BUILD_TYPE _IOWR('u', 7, unsigned char) +#define UNIFI_BUILD_NME 1 +#define UNIFI_BUILD_WEXT 2 +#define UNIFI_BUILD_AP 3 + +/* debugging */ +#define UNIFI_KICK _IO ('u', 0x10) +#define UNIFI_SET_DEBUG _IO ('u', 0x11) +#define UNIFI_SET_TRACE _IO ('u', 0x12) + +#define UNIFI_GET_INIT_STATUS _IOR ('u', 0x15, int) +#define UNIFI_SET_UDI_LOG_MASK _IOR('u', 0x18, unifiio_filter_t) +#define UNIFI_SET_UDI_SNAP_MASK _IOW('u', 0x1a, unifiio_snap_filter_t) +#define UNIFI_SET_AMP_ENABLE _IOWR('u', 0x1b, int) + +#define UNIFI_INIT_HW _IOR ('u', 0x13, unsigned char) +#define UNIFI_INIT_NETDEV _IOW ('u', 0x14, unsigned char[6]) +#define UNIFI_SME_PRESENT _IOW ('u', 0x19, int) + +#define UNIFI_CFG_PERIOD_TRAFFIC _IOW ('u', 0x21, unsigned char *) +#define UNIFI_CFG_UAPSD_TRAFFIC _IOW ('u', 0x22, unsigned char) + +#define UNIFI_COREDUMP_GET_REG _IOWR('u', 0x23, unifiio_coredump_req_t) + + +/* + * Following reset, f/w may only be downloaded using CMD52. + * This is slow, so there is a facility to download a secondary + * loader first which supports CMD53. + * If loader_len is > 0, then loader_data is assumed to point to + * a suitable secondary loader that can be used to download the + * main image. + * + * The driver will run the host protocol initialisation sequence + * after downloading the image. + * + * If both lengths are zero, then the f/w is assumed to have been + * booted from Flash and the host protocol initialisation sequence + * is run. + */ +typedef struct { + + /* Number of bytes in the image */ + int img_len; + + /* Pointer to image data. */ + unsigned char *img_data; + + + /* Number of bytes in the loader image */ + int loader_len; + + /* Pointer to loader image data. */ + unsigned char *loader_data; + +} unifiio_img_t; + + +/* Structure of data read from the unifi device. */ +typedef struct +{ + /* Length (in bytes) of entire structure including appended bulk data */ + int length; + + /* System time (in milliseconds) that signal was transferred */ + int timestamp; + + /* Direction in which signal was transferred. */ + int direction; +#define UDI_FROM_HOST 0 +#define UDI_TO_HOST 1 +#define UDI_CONFIG_IND 2 + + /* The length of the signal (in bytes) not including bulk data */ + int signal_length; + + /* Signal body follows, then any bulk data */ + +} udi_msg_t; + + +typedef enum +{ + UfSigFil_AllOn = 0, /* Log all signal IDs */ + UfSigFil_AllOff = 1, /* Don't log any signal IDs */ + UfSigFil_SelectOn = 2, /* Log these signal IDs */ + UfSigFil_SelectOff = 3 /* Don't log these signal IDs */ +} uf_sigfilter_action_t; + +typedef struct { + + /* Number of 16-bit ints in the sig_ids array */ + int num_sig_ids; + /* The action to perform */ + uf_sigfilter_action_t action; + /* List of signal IDs to pass or block */ + unsigned short *sig_ids; + +} unifiio_filter_t; + + +typedef struct { + /* Number of 16-bit ints in the protocols array */ + CsrUint16 count; + /* List of protocol ids to pass */ + CsrUint16 *protocols; +} unifiio_snap_filter_t; + + + +typedef enum unifi_putest_command { + UNIFI_PUTEST_START, + UNIFI_PUTEST_STOP, + UNIFI_PUTEST_SET_SDIO_CLOCK, + UNIFI_PUTEST_CMD52_READ, + UNIFI_PUTEST_CMD52_WRITE, + UNIFI_PUTEST_DL_FW, + UNIFI_PUTEST_DL_FW_BUFF, + UNIFI_PUTEST_CMD52_BLOCK_READ, + UNIFI_PUTEST_COREDUMP_PREPARE, + UNIFI_PUTEST_GP_READ16, + UNIFI_PUTEST_GP_WRITE16 + +} unifi_putest_command_t; + + +struct unifi_putest_cmd52 { + int funcnum; + unsigned long addr; + unsigned char data; +}; + + +struct unifi_putest_block_cmd52_r { + int funcnum; + unsigned long addr; + unsigned int length; + unsigned char *data; +}; + +struct unifi_putest_gp_rw16 { + unsigned long addr; /* generic address */ + unsigned short data; +}; + +typedef enum unifi_cfg_command { + UNIFI_CFG_GET, + UNIFI_CFG_POWER, + UNIFI_CFG_POWERSAVE, + UNIFI_CFG_FILTER, + UNIFI_CFG_POWERSUPPLY, + UNIFI_CFG_WMM_QOSINFO, + UNIFI_CFG_WMM_ADDTS, + UNIFI_CFG_WMM_DELTS, + UNIFI_CFG_STRICT_DRAFT_N, + UNIFI_CFG_ENABLE_OKC, + UNIFI_CFG_SET_AP_CONFIG, + UNIFI_CFG_CORE_DUMP /* request to take a fw core dump */ +} unifi_cfg_command_t; + +typedef enum unifi_cfg_power { + UNIFI_CFG_POWER_UNSPECIFIED, + UNIFI_CFG_POWER_OFF, + UNIFI_CFG_POWER_ON +} unifi_cfg_power_t; + +typedef enum unifi_cfg_powersupply { + UNIFI_CFG_POWERSUPPLY_UNSPECIFIED, + UNIFI_CFG_POWERSUPPLY_MAINS, + UNIFI_CFG_POWERSUPPLY_BATTERIES +} unifi_cfg_powersupply_t; + +typedef enum unifi_cfg_powersave { + UNIFI_CFG_POWERSAVE_UNSPECIFIED, + UNIFI_CFG_POWERSAVE_NONE, + UNIFI_CFG_POWERSAVE_FAST, + UNIFI_CFG_POWERSAVE_FULL, + UNIFI_CFG_POWERSAVE_AUTO +} unifi_cfg_powersave_t; + +typedef enum unifi_cfg_get { + UNIFI_CFG_GET_COEX, + UNIFI_CFG_GET_POWER_MODE, + UNIFI_CFG_GET_VERSIONS, + UNIFI_CFG_GET_POWER_SUPPLY, + UNIFI_CFG_GET_INSTANCE, + UNIFI_CFG_GET_AP_CONFIG +} unifi_cfg_get_t; + +#define UNIFI_CFG_FILTER_NONE 0x0000 +#define UNIFI_CFG_FILTER_DHCP 0x0001 +#define UNIFI_CFG_FILTER_ARP 0x0002 +#define UNIFI_CFG_FILTER_NBNS 0x0004 +#define UNIFI_CFG_FILTER_NBDS 0x0008 +#define UNIFI_CFG_FILTER_CUPS 0x0010 +#define UNIFI_CFG_FILTER_ALL 0xFFFF + + +typedef struct uf_cfg_bcast_packet_filter +{ + unsigned long filter_mode; //as defined by HIP protocol + unsigned char arp_filter; + unsigned char dhcp_filter; + unsigned long tclas_ies_length; // length of tclas_ies in bytes + unsigned char tclas_ies[1]; // variable length depending on above field +} uf_cfg_bcast_packet_filter_t; + +typedef struct uf_cfg_ap_config +{ + CsrUint8 phySupportedBitmap; + CsrUint8 channel; + CsrUint16 beaconInterval; + CsrUint8 dtimPeriod; + CsrBool wmmEnabled; + CsrUint8 shortSlotTimeEnabled; + CsrUint16 groupkeyTimeout; + CsrBool strictGtkRekeyEnabled; + CsrUint16 gmkTimeout; + CsrUint16 responseTimeout; + CsrUint8 retransLimit; + CsrUint8 rxStbc; + CsrBool rifsModeAllowed; + CsrUint8 dualCtsProtection; + CsrUint8 ctsProtectionType; + CsrUint16 maxListenInterval; +}uf_cfg_ap_config_t; + +typedef struct tcpic_clsfr +{ + __u8 cls_fr_type; + __u8 cls_fr_mask; + __u8 version; + __u8 source_ip_addr[4]; + __u8 dest_ip_addr[4]; + __u16 source_port; + __u16 dest_port; + __u8 dscp; + __u8 protocol; + __u8 reserved; +} __attribute__ ((packed)) tcpip_clsfr_t; + +typedef struct tclas { + __u8 element_id; + __u8 length; + __u8 user_priority; + tcpip_clsfr_t tcp_ip_cls_fr; +} __attribute__ ((packed)) tclas_t; + + +#define CONFIG_IND_ERROR 0x01 +#define CONFIG_IND_EXIT 0x02 +#define CONFIG_SME_NOT_PRESENT 0x10 +#define CONFIG_SME_PRESENT 0x20 + +/* WAPI Key */ +typedef struct +{ + CsrUint8 unicastKey; + /* If non zero, then unicast key otherwise group key */ + CsrUint8 keyIndex; + CsrUint8 keyRsc[16]; + CsrUint8 authenticator; + /* If non zero, then authenticator otherwise supplicant */ + CsrUint8 address[6]; + CsrUint8 key[32]; +} unifiio_wapi_key_t; + +/* Values describing XAP memory regions captured by the mini-coredump system */ +typedef enum unifiio_coredump_space { + UNIFIIO_COREDUMP_MAC_REG, + UNIFIIO_COREDUMP_PHY_REG, + UNIFIIO_COREDUMP_SH_DMEM, + UNIFIIO_COREDUMP_MAC_DMEM, + UNIFIIO_COREDUMP_PHY_DMEM, + UNIFIIO_COREDUMP_TRIGGER_MAGIC = 0xFEED +} unifiio_coredump_space_t; + +/* Userspace tool uses this structure to retrieve a register value from a + * mini-coredump buffer previously saved by the HIP + */ +typedef struct unifiio_coredump_req { + /* From user */ + int index; /* 0=newest, -1=oldest */ + unsigned int offset; /* register offset in space */ + unifiio_coredump_space_t space; /* memory space */ + /* Filled by driver */ + unsigned int drv_build; /* driver build id */ + unsigned int chip_ver; /* chip version */ + unsigned int fw_ver; /* firmware version */ + int requestor; /* requestor: 0=auto dump, 1=manual */ + unsigned int timestamp; /* time of capture by driver */ + unsigned int serial; /* capture serial number */ + int value; /* 16 bit register value, -ve for error */ +} unifiio_coredump_req_t; /* Core-dumped register value request */ + +#endif /* __UNIFIIO_H__ */ diff --git a/drivers/staging/csr/wext_events.c b/drivers/staging/csr/wext_events.c new file mode 100644 index 000000000000..5674782b19a7 --- /dev/null +++ b/drivers/staging/csr/wext_events.c @@ -0,0 +1,285 @@ +/* + * --------------------------------------------------------------------------- + * FILE: wext_events.c + * + * PURPOSE: + * Code to generate iwevents. + * + * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd. + * + * Refer to LICENSE.txt included with this source code for details on + * the license terms. + * + * --------------------------------------------------------------------------- + */ +#include +#include +#include +#include "csr_wifi_hip_unifi.h" +#include "unifi_priv.h" + + + +/* + * --------------------------------------------------------------------------- + * wext_send_assoc_event + * + * Send wireless-extension events up to userland to announce + * successful association with an AP. + * + * Arguments: + * priv Pointer to driver context. + * bssid MAC address of AP we associated with + * req_ie, req_ie_len IEs in the original request + * resp_ie, resp_ie_len IEs in the response + * + * Returns: + * None. + * + * Notes: + * This is sent on first successful association, and again if we + * roam to another AP. + * --------------------------------------------------------------------------- + */ +void +wext_send_assoc_event(unifi_priv_t *priv, unsigned char *bssid, + unsigned char *req_ie, int req_ie_len, + unsigned char *resp_ie, int resp_ie_len, + unsigned char *scan_ie, unsigned int scan_ie_len) +{ +#if WIRELESS_EXT > 17 + union iwreq_data wrqu; + + if (req_ie_len == 0) req_ie = NULL; + wrqu.data.length = req_ie_len; + wrqu.data.flags = 0; + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVASSOCREQIE, &wrqu, req_ie); + + if (resp_ie_len == 0) resp_ie = NULL; + wrqu.data.length = resp_ie_len; + wrqu.data.flags = 0; + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVASSOCRESPIE, &wrqu, resp_ie); + + if (scan_ie_len > 0) { + wrqu.data.length = scan_ie_len; + wrqu.data.flags = 0; + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVGENIE, &wrqu, scan_ie); + } + + memcpy(&wrqu.ap_addr.sa_data, bssid, ETH_ALEN); + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], SIOCGIWAP, &wrqu, NULL); +#endif +} /* wext_send_assoc_event() */ + + + +/* + * --------------------------------------------------------------------------- + * wext_send_disassoc_event + * + * Send a wireless-extension event up to userland to announce + * that we disassociated from an AP. + * + * Arguments: + * priv Pointer to driver context. + * + * Returns: + * None. + * + * Notes: + * The semantics of wpa_supplicant (the userland SME application) are + * that a SIOCGIWAP event with MAC address of all zero means + * disassociate. + * --------------------------------------------------------------------------- + */ +void +wext_send_disassoc_event(unifi_priv_t *priv) +{ +#if WIRELESS_EXT > 17 + union iwreq_data wrqu; + + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], SIOCGIWAP, &wrqu, NULL); +#endif +} /* wext_send_disassoc_event() */ + + + +/* + * --------------------------------------------------------------------------- + * wext_send_scan_results_event + * + * Send wireless-extension events up to userland to announce + * completion of a scan. + * + * Arguments: + * priv Pointer to driver context. + * + * Returns: + * None. + * + * Notes: + * This doesn't actually report the results, they are retrieved + * using the SIOCGIWSCAN ioctl command. + * --------------------------------------------------------------------------- + */ +void +wext_send_scan_results_event(unifi_priv_t *priv) +{ +#if WIRELESS_EXT > 17 + union iwreq_data wrqu; + + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], SIOCGIWSCAN, &wrqu, NULL); + +#endif +} /* wext_send_scan_results_event() */ + + + +/* + * --------------------------------------------------------------------------- + * wext_send_michaelmicfailure_event + * + * Send wireless-extension events up to userland to announce + * completion of a scan. + * + * Arguments: + * priv Pointer to driver context. + * count, macaddr, key_type, key_idx, tsc + * Parameters from report from UniFi. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +#if WIRELESS_EXT >= 18 +static inline void +_send_michaelmicfailure_event(struct net_device *dev, + int count, const unsigned char *macaddr, + int key_type, int key_idx, + unsigned char *tsc) +{ + union iwreq_data wrqu; + struct iw_michaelmicfailure mmf; + + memset(&mmf, 0, sizeof(mmf)); + + mmf.flags = key_idx & IW_MICFAILURE_KEY_ID; + if (key_type == CSR_GROUP) { + mmf.flags |= IW_MICFAILURE_GROUP; + } else { + mmf.flags |= IW_MICFAILURE_PAIRWISE; + } + mmf.flags |= ((count << 5) & IW_MICFAILURE_COUNT); + + mmf.src_addr.sa_family = ARPHRD_ETHER; + memcpy(mmf.src_addr.sa_data, macaddr, ETH_ALEN); + + memcpy(mmf.tsc, tsc, IW_ENCODE_SEQ_MAX_SIZE); + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(mmf); + + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&mmf); +} +#elif WIRELESS_EXT >= 15 +static inline void +_send_michaelmicfailure_event(struct net_device *dev, + int count, const unsigned char *macaddr, + int key_type, int key_idx, + unsigned char *tsc) +{ + union iwreq_data wrqu; + char buf[128]; + + sprintf(buf, + "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%02x:%02x:%02x:%02x:%02x:%02x)", + key_idx, (key_type == CSR_GROUP) ? "broad" : "uni", + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlen(buf); + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); +} +#else /* WIRELESS_EXT >= 15 */ +static inline void +_send_michaelmicfailure_event(struct net_device *dev, + int count, const unsigned char *macaddr, + int key_type, int key_idx, + unsigned char *tsc) +{ + /* Not supported before WEXT 15 */ +} +#endif /* WIRELESS_EXT >= 15 */ + + +void +wext_send_michaelmicfailure_event(unifi_priv_t *priv, + CsrUint16 count, + CsrWifiMacAddress address, + CsrWifiSmeKeyType keyType, + CsrUint16 interfaceTag) +{ + unsigned char tsc[8] = {0}; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "wext_send_michaelmicfailure_event bad interfaceTag\n"); + return; + } + + _send_michaelmicfailure_event(priv->netdev[interfaceTag], + count, + address.a, + keyType, + 0, + tsc); +} /* wext_send_michaelmicfailure_event() */ + +void +wext_send_pmkid_candidate_event(unifi_priv_t *priv, CsrWifiMacAddress bssid, CsrBool preauth_allowed, CsrUint16 interfaceTag) +{ +#if WIRELESS_EXT > 17 + union iwreq_data wrqu; + struct iw_pmkid_cand pmkid_cand; + + if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { + unifi_error(priv, "wext_send_pmkid_candidate_event bad interfaceTag\n"); + return; + } + + memset(&pmkid_cand, 0, sizeof(pmkid_cand)); + + if (preauth_allowed) { + pmkid_cand.flags |= IW_PMKID_CAND_PREAUTH; + } + pmkid_cand.bssid.sa_family = ARPHRD_ETHER; + memcpy(pmkid_cand.bssid.sa_data, bssid.a, ETH_ALEN); + /* Used as priority, smaller the number higher the priority, not really used in our case */ + pmkid_cand.index = 1; + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(pmkid_cand); + + wireless_send_event(priv->netdev[interfaceTag], IWEVPMKIDCAND, &wrqu, (char *)&pmkid_cand); +#endif +} /* wext_send_pmkid_candidate_event() */ + +/* + * Send a custom WEXT event to say we have completed initialisation + * and are now ready for WEXT ioctls. Used by Android wpa_supplicant. + */ +void +wext_send_started_event(unifi_priv_t *priv) +{ +#if WIRELESS_EXT > 17 + union iwreq_data wrqu; + char data[] = "STARTED"; + + wrqu.data.length = sizeof(data); + wrqu.data.flags = 0; + wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVCUSTOM, &wrqu, data); +#endif +} /* wext_send_started_event() */ + -- GitLab From 4efdc8a5731d6617f99486d9024041f712628a0c Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Jun 2012 09:13:40 +0900 Subject: [PATCH 2098/6849] ARM: S5P64X0: Remove unused variable in dma.c file Fixes the following warning: arch/arm/mach-s5p64x0/dma.c:39:12: warning: 'dma_dmamask' defined but not used [-Wunused-variable] Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index 2ee5dc069b37..9c4ce085f585 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -36,8 +36,6 @@ #include #include -static u64 dma_dmamask = DMA_BIT_MASK(32); - static u8 s5p6440_pdma_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, -- GitLab From f876c22a5cf4003b000718c2497fc6142fdff621 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Jun 2012 09:14:08 +0900 Subject: [PATCH 2099/6849] ARM: S5PC100: Remove unused variable in dma.c file Fixes the following warning: arch/arm/mach-s5pc100/dma.c:36:12: warning: 'dma_dmamask' defined but not used [-Wunused-variable] Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pc100/dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index afd8db2d5991..b1418409709e 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -33,8 +33,6 @@ #include #include -static u64 dma_dmamask = DMA_BIT_MASK(32); - static u8 pdma0_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, -- GitLab From 9d530786c4ed88720671ba83b669b7e7da5cdc91 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Jun 2012 09:18:39 +0900 Subject: [PATCH 2100/6849] ARM: SAMSUNG: Remove description corresponding to a deleted element Commit 3c582647a9f8 ("video: s3c-fb: remove 'default_win' element from platform data") removed the default_win element from the structure, but the description was not removed. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/fb.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h index 536002ff2ab8..b885322717a1 100644 --- a/arch/arm/plat-samsung/include/plat/fb.h +++ b/arch/arm/plat-samsung/include/plat/fb.h @@ -43,7 +43,6 @@ struct s3c_fb_pd_win { * @setup_gpio: Setup the external GPIO pins to the right state to transfer * the data from the display system to the connected display * device. - * @default_win: default window layer number to be used for UI layer. * @vidcon0: The base vidcon0 values to control the panel data format. * @vidcon1: The base vidcon1 values to control the panel data output. * @vtiming: Video timing when connected to a RGB type panel. -- GitLab From 334a511a811133182f8dbdc7b63f141bb1185fbb Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Jun 2012 09:19:17 +0900 Subject: [PATCH 2101/6849] ARM: S3C24XX: Remove duplicate header file inclusion regs-clock.h header file was included twice. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index 56cdd34cce41..0c9e9a785ef6 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -41,7 +41,6 @@ #include #include -#include #include #include -- GitLab From 3817575b4e0a58199ebe8f05faed4fc6469fda74 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 20 Jun 2012 09:25:07 +0900 Subject: [PATCH 2102/6849] ARM: S3C24XX: remove unused header Since (at least) v2.6.12-rc2 there has been a bast-pmu.h header in the tree. Currently it can be found at arch/arm/mach-s3c24xx/include/mach/bast-pmu.h. It seems that during that entire period nothing included that header and that none of the named constants it provided were ever used. That header can safely be removed. Signed-off-by: Paul Bolle Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/include/mach/bast-pmu.h | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 arch/arm/mach-s3c24xx/include/mach/bast-pmu.h diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h b/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h deleted file mode 100644 index 4c38b39b741d..000000000000 --- a/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h +++ /dev/null @@ -1,40 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/bast-pmu.h - * - * Copyright (c) 2003-2004 Simtec Electronics - * Ben Dooks - * Vincent Sanders - * - * Machine BAST - Power Management chip - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_BASTPMU_H -#define __ASM_ARCH_BASTPMU_H "08_OCT_2004" - -#define BASTPMU_REG_IDENT (0x00) -#define BASTPMU_REG_VERSION (0x01) -#define BASTPMU_REG_DDCCTRL (0x02) -#define BASTPMU_REG_POWER (0x03) -#define BASTPMU_REG_RESET (0x04) -#define BASTPMU_REG_GWO (0x05) -#define BASTPMU_REG_WOL (0x06) -#define BASTPMU_REG_WOR (0x07) -#define BASTPMU_REG_UID (0x09) - -#define BASTPMU_EEPROM (0xC0) - -#define BASTPMU_EEP_UID (BASTPMU_EEPROM + 0) -#define BASTPMU_EEP_WOL (BASTPMU_EEPROM + 8) -#define BASTPMU_EEP_WOR (BASTPMU_EEPROM + 9) - -#define BASTPMU_IDENT_0 0x53 -#define BASTPMU_IDENT_1 0x42 -#define BASTPMU_IDENT_2 0x50 -#define BASTPMU_IDENT_3 0x4d - -#define BASTPMU_RESET_GUARD (0x55) - -#endif /* __ASM_ARCH_BASTPMU_H */ -- GitLab From 95edd09ec3b15b165e2c7ba1e54cc508eafb2321 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 19 Jun 2012 17:33:16 -0700 Subject: [PATCH 2103/6849] Staging: csr: update to version 5.1.0 of the driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This brings the in-kernel driver up to the level of the csr-linux-wifi-5.1.0-oss.tar.gz tarball. Cc: Mikko Virkkilä Cc: Lauri Hintsala Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 35 + drivers/staging/csr/csr_types.h | 1 + drivers/staging/csr/csr_util.c | 4 + drivers/staging/csr/csr_util.h | 45 +- drivers/staging/csr/csr_wifi_common.h | 2 +- drivers/staging/csr/csr_wifi_hip_card.h | 11 +- drivers/staging/csr/csr_wifi_hip_card_sdio.c | 85 +- .../staging/csr/csr_wifi_hip_card_sdio_intr.c | 40 +- .../staging/csr/csr_wifi_hip_card_sdio_mem.c | 4 +- drivers/staging/csr/csr_wifi_hip_download.c | 6 +- drivers/staging/csr/csr_wifi_hip_dump.c | 6 +- .../staging/csr/csr_wifi_hip_ta_sampling.c | 30 +- drivers/staging/csr/csr_wifi_hip_unifi.h | 32 +- drivers/staging/csr/csr_wifi_hip_xbv.c | 12 +- drivers/staging/csr/csr_wifi_nme_ap_lib.h | 3 +- drivers/staging/csr/csr_wifi_nme_ap_prim.h | 3 +- .../csr/csr_wifi_router_converter_init.c | 10 +- .../csr/csr_wifi_router_ctrl_converter_init.c | 18 +- ...ifi_router_ctrl_free_downstream_contents.c | 20 +- ..._wifi_router_ctrl_free_upstream_contents.c | 13 +- .../staging/csr/csr_wifi_router_ctrl_lib.h | 226 ++- .../staging/csr/csr_wifi_router_ctrl_prim.h | 130 +- .../staging/csr/csr_wifi_router_ctrl_sef.c | 12 +- .../staging/csr/csr_wifi_router_ctrl_sef.h | 4 +- .../csr/csr_wifi_router_ctrl_serialize.c | 261 ++- .../csr/csr_wifi_router_ctrl_serialize.h | 58 +- drivers/staging/csr/csr_wifi_sme_ap_lib.h | 131 +- drivers/staging/csr/csr_wifi_sme_ap_prim.h | 141 +- .../staging/csr/csr_wifi_sme_converter_init.c | 11 +- .../staging/csr/csr_wifi_sme_converter_init.h | 2 +- .../csr_wifi_sme_free_downstream_contents.c | 9 +- drivers/staging/csr/csr_wifi_sme_lib.h | 35 +- drivers/staging/csr/csr_wifi_sme_prim.h | 99 +- drivers/staging/csr/csr_wifi_sme_serialize.c | 62 +- drivers/staging/csr/csr_wifi_sme_serialize.h | 7 +- drivers/staging/csr/drv.c | 131 +- drivers/staging/csr/firmware.c | 18 +- drivers/staging/csr/io.c | 20 + drivers/staging/csr/netdev.c | 168 +- drivers/staging/csr/os.c | 26 +- drivers/staging/csr/putest.c | 29 +- drivers/staging/csr/sdio_emb.c | 187 +- drivers/staging/csr/sdio_events.c | 49 +- drivers/staging/csr/sdio_mmc.c | 247 ++- drivers/staging/csr/sme_blocking.c | 123 +- drivers/staging/csr/sme_sys.c | 582 ++++-- drivers/staging/csr/sme_userspace.c | 5 +- drivers/staging/csr/sme_wext.c | 4 +- drivers/staging/csr/ul_int.c | 25 +- drivers/staging/csr/unifi_event.c | 540 +++--- drivers/staging/csr/unifi_os.h | 22 +- drivers/staging/csr/unifi_pdu_processing.c | 1559 +++++++++-------- drivers/staging/csr/unifi_priv.h | 96 +- drivers/staging/csr/unifi_sme.c | 80 + drivers/staging/csr/unifi_sme.h | 9 + drivers/staging/csr/unifiio.h | 27 +- 56 files changed, 3845 insertions(+), 1670 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index 0406a4b0f786..1586b235e296 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -211,3 +211,38 @@ void CsrMemFree(void *pointer) kfree(pointer); } EXPORT_SYMBOL_GPL(CsrMemFree); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemAllocDma + * + * DESCRIPTION + * Allocate DMA capable dynamic memory of a given size. + * + * RETURNS + * Pointer to allocated memory, or NULL in case of failure. + * Allocated memory is not initialised. + * + *----------------------------------------------------------------------------*/ +void *CsrMemAllocDma(CsrSize size) +{ + return kmalloc(size, GFP_KERNEL | GFP_DMA); +} +EXPORT_SYMBOL_GPL(CsrMemAllocDma); + +/*----------------------------------------------------------------------------* + * NAME + * CsrMemFreeDma + * + * DESCRIPTION + * Free DMA capable dynamic allocated memory. + * + * RETURNS + * void + * + *----------------------------------------------------------------------------*/ +void CsrMemFreeDma(void *pointer) +{ + kfree(pointer); +} +EXPORT_SYMBOL_GPL(CsrMemFreeDma); diff --git a/drivers/staging/csr/csr_types.h b/drivers/staging/csr/csr_types.h index d7d2c5d061fe..23193ea4429f 100644 --- a/drivers/staging/csr/csr_types.h +++ b/drivers/staging/csr/csr_types.h @@ -21,6 +21,7 @@ #include #include #include +#include #endif #ifdef __cplusplus diff --git a/drivers/staging/csr/csr_util.c b/drivers/staging/csr/csr_util.c index 0ae11531e26d..939c87c638a1 100644 --- a/drivers/staging/csr/csr_util.c +++ b/drivers/staging/csr/csr_util.c @@ -221,6 +221,7 @@ void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str) /*------------------------------------------------------------------*/ /* String */ /*------------------------------------------------------------------*/ +#ifndef CSR_USE_STDC_LIB void *CsrMemCpy(void *dest, const void *src, CsrSize count) { return memcpy(dest, src, count); @@ -257,7 +258,9 @@ void *CsrMemDup(const void *buf1, CsrSize count) return buf2; } +#endif +#ifndef CSR_USE_STDC_LIB CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src) { return strcpy(dest, src); @@ -303,6 +306,7 @@ CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c) { return strchr(string, c); } +#endif CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args) { diff --git a/drivers/staging/csr/csr_util.h b/drivers/staging/csr/csr_util.h index a19baddc0213..ce39c7e8dab7 100644 --- a/drivers/staging/csr/csr_util.h +++ b/drivers/staging/csr/csr_util.h @@ -35,26 +35,53 @@ void CsrUInt16ToHex(CsrUint16 number, CsrCharString *str); void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str); /*------------------------------------------------------------------*/ -/* String */ +/* Standard C Library functions */ /*------------------------------------------------------------------*/ +#ifdef CSR_USE_STDC_LIB +#define CsrMemCpy memcpy +#define CsrMemMove memmove +#define CsrStrCpy strcpy +#define CsrStrNCpy strncpy +#define CsrStrCat strcat +#define CsrStrNCat strncat +#define CsrMemCmp(s1, s2, n) ((CsrInt32) memcmp((s1), (s2), (n))) +#define CsrStrCmp(s1, s2) ((CsrInt32) strcmp((s1), (s2))) +#define CsrStrNCmp(s1, s2, n) ((CsrInt32) strncmp((s1), (s2), (n))) +/*#define CsrMemChr memchr*/ +#define CsrStrChr strchr +/*#define CsrStrCSpn strcspn*/ +/*#define CsrStrPBrk strpbrk*/ +/*#define CsrStrRChr strrchr*/ +/*#define CsrStrSpn strspn*/ +#define CsrStrStr strstr +/*#define CsrStrTok strtok*/ +#define CsrMemSet memset +#define CsrStrLen strlen +/*#define CsrVsnprintf(s, n, format, arg) ((CsrInt32) vsnprintf((s), (n), (format), (arg)))*/ +#else /* !CSR_USE_STDC_LIB */ void *CsrMemCpy(void *dest, const void *src, CsrSize count); -void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count); void *CsrMemMove(void *dest, const void *src, CsrSize count); -CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count); -void *CsrMemDup(const void *buf1, CsrSize count); CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src); CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count); -int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count); CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src); CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count); -CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2); -CsrSize CsrStrLen(const CsrCharString *string); +CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count); CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2); CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count); -CsrCharString *CsrStrDup(const CsrCharString *string); CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c); -CsrUint32 CsrStrToInt(const CsrCharString *string); +CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2); +void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count); +CsrSize CsrStrLen(const CsrCharString *string); +#endif /* !CSR_USE_STDC_LIB */ CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args); + +/*------------------------------------------------------------------*/ +/* Non-standard utility functions */ +/*------------------------------------------------------------------*/ +void *CsrMemDup(const void *buf1, CsrSize count); +int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count); +CsrCharString *CsrStrDup(const CsrCharString *string); +CsrUint32 CsrStrToInt(const CsrCharString *string); CsrCharString *CsrStrNCpyZero(CsrCharString *dest, const CsrCharString *src, CsrSize count); /*------------------------------------------------------------------*/ diff --git a/drivers/staging/csr/csr_wifi_common.h b/drivers/staging/csr/csr_wifi_common.h index 1cdde5c7bd8d..442dcc6e4e06 100644 --- a/drivers/staging/csr/csr_wifi_common.h +++ b/drivers/staging/csr/csr_wifi_common.h @@ -99,7 +99,7 @@ typedef struct #define CSR_WIFI_RESULT_INVALID_INTERFACE_TAG ((CsrResult) 0x000B) #define CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT ((CsrResult) 0x000C) -#define CSR_WIFI_VERSION "5.0.3.0" +#define CSR_WIFI_VERSION "5.1.0.0" #ifdef __cplusplus } diff --git a/drivers/staging/csr/csr_wifi_hip_card.h b/drivers/staging/csr/csr_wifi_hip_card.h index 8904211d3317..2ab47843bcc6 100644 --- a/drivers/staging/csr/csr_wifi_hip_card.h +++ b/drivers/staging/csr/csr_wifi_hip_card.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -81,6 +81,15 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue */ void CardClearFromHostDataSlot(card_t *card, const CsrInt16 aSlotNum); +#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL +/***************************************************************************** + * CardClearFromHostDataSlotWithoutFreeingBulkData - Clear the data stot + * without freeing the bulk data + */ + +void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const CsrInt16 aSlotNum); +#endif + /***************************************************************************** * CardGetFreeFromHostDataSlots - */ diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c index 719c608d18b4..91976b824a4e 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -323,7 +323,7 @@ CsrResult unifi_init(card_t *card) * have requested a mini-coredump which needs to be captured now the * SDIO interface is alive. */ - unifi_coredump_handle_request(card); + (void)unifi_coredump_handle_request(card); /* * Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do. @@ -1616,14 +1616,14 @@ static CsrResult card_allocate_memory_resources(card_t *card) /* Reset any state carried forward from a previous life */ card->fh_command_queue.q_rd_ptr = 0; card->fh_command_queue.q_wr_ptr = 0; - CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, - "fh_cmd_q"); + (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, + "fh_cmd_q"); for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) { card->fh_traffic_queue[i].q_rd_ptr = 0; card->fh_traffic_queue[i].q_wr_ptr = 0; - CsrSnprintf(card->fh_traffic_queue[i].name, - UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); + (void)CsrSnprintf(card->fh_traffic_queue[i].name, + UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); } #ifndef CSR_WIFI_HIP_TA_DISABLE unifi_ta_sampling_init(card); @@ -1634,7 +1634,7 @@ static CsrResult card_allocate_memory_resources(card_t *card) /* * Allocate memory for the from-host and to-host signal buffers. */ - card->fh_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE); + card->fh_buffer.buf = CsrMemAllocDma(UNIFI_FH_BUF_SIZE); if (card->fh_buffer.buf == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n"); @@ -1645,7 +1645,7 @@ static CsrResult card_allocate_memory_resources(card_t *card) card->fh_buffer.ptr = card->fh_buffer.buf; card->fh_buffer.count = 0; - card->th_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE); + card->th_buffer.buf = CsrMemAllocDma(UNIFI_FH_BUF_SIZE); if (card->th_buffer.buf == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n"); @@ -1693,6 +1693,12 @@ static CsrResult card_allocate_memory_resources(card_t *card) return CSR_WIFI_HIP_RESULT_NO_MEMORY; } + /* Initialise host tag entries for from-host bulk data slots */ + for (i = 0; i < n; i++) + { + card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG; + } + /* Allocate memory for the array of pointers */ n = cfg_data->num_tohost_data_slots; @@ -1811,7 +1817,7 @@ static void card_free_memory_resources(card_t *card) if (card->fh_buffer.buf) { - CsrMemFree(card->fh_buffer.buf); + CsrMemFreeDma(card->fh_buffer.buf); } card->fh_buffer.ptr = card->fh_buffer.buf = NULL; card->fh_buffer.bufsize = 0; @@ -1819,7 +1825,7 @@ static void card_free_memory_resources(card_t *card) if (card->th_buffer.buf) { - CsrMemFree(card->th_buffer.buf); + CsrMemFreeDma(card->th_buffer.buf); } card->th_buffer.ptr = card->th_buffer.buf = NULL; card->th_buffer.bufsize = 0; @@ -1842,14 +1848,14 @@ static void card_init_soft_queues(card_t *card) /* Reset any state carried forward from a previous life */ card->fh_command_queue.q_rd_ptr = 0; card->fh_command_queue.q_wr_ptr = 0; - CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, - "fh_cmd_q"); + (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, + "fh_cmd_q"); for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) { card->fh_traffic_queue[i].q_rd_ptr = 0; card->fh_traffic_queue[i].q_wr_ptr = 0; - CsrSnprintf(card->fh_traffic_queue[i].name, - UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); + (void)CsrSnprintf(card->fh_traffic_queue[i].name, + UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); } #ifndef CSR_WIFI_HIP_TA_DISABLE unifi_ta_sampling_init(card); @@ -2399,6 +2405,57 @@ void CardClearFromHostDataSlot(card_t *card, const CsrInt16 slot) } /* CardClearFromHostDataSlot() */ +#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL +/* + * --------------------------------------------------------------------------- + * CardClearFromHostDataSlotWithoutFreeingBulkData + * + * Clear the given data slot with out freeing the bulk data. + * + * Arguments: + * card Pointer to Card object + * slot Index of the signal slot to clear. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const CsrInt16 slot) +{ + CsrUint8 queue = card->from_host_data[slot].queue; + + /* Initialise the from_host data slot so it can be re-used, + * Set length field in from_host_data array to 0. + */ + UNIFI_INIT_BULK_DATA(&card->from_host_data[slot].bd); + + queue = card->from_host_data[slot].queue; + + if (queue < UNIFI_NO_OF_TX_QS) + { + if (card->dynamic_slot_data.from_host_used_slots[queue] == 0) + { + unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n", + queue, + card->dynamic_slot_data.from_host_used_slots[queue]); + } + else + { + card->dynamic_slot_data.from_host_used_slots[queue]--; + } + card->dynamic_slot_data.packets_txed[queue]++; + card->dynamic_slot_data.total_packets_txed++; + if (card->dynamic_slot_data.total_packets_txed >= + card->dynamic_slot_data.packets_interval) + { + CardReassignDynamicReservation(card); + } + } +} /* CardClearFromHostDataSlotWithoutFreeingBulkData() */ + + +#endif + CsrUint16 CardGetDataSlotSize(card_t *card) { return card->config_data.data_slot_size; diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c index 3d563c13ff5a..8fefbdfc7156 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -148,9 +148,9 @@ void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length) CsrCharString s[5]; CsrUint16 i; - for (i = 0; i < length; i++) + for (i = 0; i < length; i = i + 2) { - CsrUInt16ToHex(0xff & buff[i], s); + CsrUInt16ToHex(*((CsrUint16 *)(buff + i)), s); unifi_debug_string_to_buf(s); } } @@ -277,7 +277,7 @@ void unifi_sdio_interrupt_handler(card_t *card) * Then ask the OS layer to run the unifi_bh to give attention to the UniFi. */ card->bh_reason_unifi = 1; - unifi_run_bh(card->ospriv); + (void)unifi_run_bh(card->ospriv); } /* sdio_interrupt_handler() */ @@ -309,7 +309,7 @@ CsrResult unifi_configure_low_power_mode(card_t *card, (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled", (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE"); - unifi_run_bh(card->ospriv); + (void)unifi_run_bh(card->ospriv); return CSR_RESULT_SUCCESS; } /* unifi_configure_low_power_mode() */ @@ -614,10 +614,10 @@ exit: (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled"); /* Try to capture firmware panic codes */ - unifi_capture_panic(card); + (void)unifi_capture_panic(card); /* Ask for a mini-coredump when the driver has reset UniFi */ - unifi_coredump_request_at_next_reset(card, 1); + (void)unifi_coredump_request_at_next_reset(card, 1); } return r; @@ -932,9 +932,13 @@ static CsrResult handle_host_protocol(card_t *card, CsrBool *processed_something return r; } } + +#ifdef CSR_WIFI_RX_PATH_SPLIT #ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ unifi_rx_queue_flush(card->ospriv); #endif +#endif + /* See if we can re-enable transmission now */ restart_packet_flow(card); @@ -1324,7 +1328,6 @@ static CsrResult process_to_host_signals(card_t *card, CsrInt32 *processed) if (status && (card->fh_slot_host_tag_record)) { CsrUint16 num_fh_slots = card->config_data.num_fromhost_data_slots; - CsrUint16 i = 0; /* search through the list of slot records and match with host tag * If a slot is not yet cleared then clear the slot from here @@ -1333,12 +1336,27 @@ static CsrResult process_to_host_signals(card_t *card, CsrInt32 *processed) { if (card->fh_slot_host_tag_record[i] == host_tag) { +#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL + /* Invoke the HAL module function to requeue it back to HAL Queues */ + r = unifi_reque_ma_packet_request(card->ospriv, host_tag, status, &card->from_host_data[i].bd); + card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG; + if (CSR_RESULT_SUCCESS != r) + { + unifi_trace(card->ospriv, UDBG5, "process_to_host_signals: Failed to requeue Packet(hTag:%x) back to HAL \n", host_tag); + CardClearFromHostDataSlot(card, i); + } + else + { + CardClearFromHostDataSlotWithoutFreeingBulkData(card, i); + } + +#else unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag); card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG; /* Set length field in from_host_data array to 0 */ CardClearFromHostDataSlot(card, i); - +#endif break; } } @@ -1724,7 +1742,7 @@ static CsrResult process_bulk_data_command(card_t *card, const CsrUint8 *cmdptr, if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3)) { - host_bulk_data_slot = CsrMemAlloc(len); + host_bulk_data_slot = CsrMemAllocDma(len); if (!host_bulk_data_slot) { @@ -1783,7 +1801,7 @@ static CsrResult process_bulk_data_command(card_t *card, const CsrUint8 *cmdptr, /* moving this check before we clear host data slot */ if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3)) { - CsrMemFree(host_bulk_data_slot); + CsrMemFreeDma(host_bulk_data_slot); } #endif diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c index 403641d4df02..8bc2d74e8d5e 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -1565,7 +1565,7 @@ CsrResult unifi_bulk_rw(card_t *card, CsrUint32 handle, void *pdata, */ if (card->chip_id <= SDIO_CARD_ID_UNIFI_2) { - unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); + (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); } /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c index fb6f04e1bbf4..47178afe5865 100644 --- a/drivers/staging/csr/csr_wifi_hip_download.c +++ b/drivers/staging/csr/csr_wifi_hip_download.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -674,7 +674,7 @@ static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv, return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } - buf = CsrMemAlloc(buf_size); + buf = CsrMemAllocDma(buf_size); if (buf == NULL) { unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n"); @@ -720,7 +720,7 @@ static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv, } } - CsrMemFree(buf); + CsrMemFreeDma(buf); if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE) { diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c index c191ea135040..5297f103e9eb 100644 --- a/drivers/staging/csr/csr_wifi_hip_dump.c +++ b/drivers/staging/csr/csr_wifi_hip_dump.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -293,7 +293,7 @@ done: * Notes: * --------------------------------------------------------------------------- */ -static CsrInt32 get_value_from_coredump(const coredump_buffer *dump, +static CsrInt32 get_value_from_coredump(const coredump_buffer *coreDump, const unifi_coredump_space_t space, const CsrUint16 offset_in_space) { @@ -316,7 +316,7 @@ static CsrInt32 get_value_from_coredump(const coredump_buffer *dump, { /* Calculate the offset of data within the zone buffer */ offset_in_zone = offset_in_space - def->offset; - r = (CsrInt32) * (dump->zone[i] + offset_in_zone); + r = (CsrInt32) * (coreDump->zone[i] + offset_in_zone); unifi_trace(NULL, UDBG6, "sp %d, offs 0x%04x = 0x%04x (in z%d 0x%04x->0x%04x)\n", diff --git a/drivers/staging/csr/csr_wifi_hip_ta_sampling.c b/drivers/staging/csr/csr_wifi_hip_ta_sampling.c index 4fa8f607f15c..7afcd3c90fc6 100644 --- a/drivers/staging/csr/csr_wifi_hip_ta_sampling.c +++ b/drivers/staging/csr/csr_wifi_hip_ta_sampling.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -69,9 +69,9 @@ enum ta_frame_identity #define TA_EAPOL_TYPE_OFFSET 9 #define TA_EAPOL_TYPE_START 0x01 -static const CsrUint8 snap_802_2[3] = { 0xAA, 0xAA, 0x03 }; -static const CsrUint8 oui_rfc1042[3] = { 0x00, 0x00, 0x00 }; -static const CsrUint8 oui_8021h[3] = { 0x00, 0x00, 0xf8 }; +#define snap_802_2 0xAAAA0300 +#define oui_rfc1042 0x00000000 +#define oui_8021h 0x0000f800 static const CsrUint8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 }; @@ -100,13 +100,17 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl CsrUint16 proto; CsrUint16 source_port, dest_port; CsrWifiMacAddress srcAddress; + CsrUint32 snap_hdr, oui_hdr; if (data->data_length < TA_LLC_HEADER_SIZE) { return TA_FRAME_UNKNOWN; } - if (CsrMemCmp(data->os_data_ptr, snap_802_2, 3)) + snap_hdr = (((CsrUint32)data->os_data_ptr[0]) << 24) | + (((CsrUint32)data->os_data_ptr[1]) << 16) | + (((CsrUint32)data->os_data_ptr[2]) << 8); + if (snap_hdr != snap_802_2) { return TA_FRAME_UNKNOWN; } @@ -118,8 +122,10 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl */ } - if (!CsrMemCmp(data->os_data_ptr + 3, oui_rfc1042, 3) || - !CsrMemCmp(data->os_data_ptr + 3, oui_8021h, 3)) + oui_hdr = (((CsrUint32)data->os_data_ptr[3]) << 24) | + (((CsrUint32)data->os_data_ptr[4]) << 16) | + (((CsrUint32)data->os_data_ptr[5]) << 8); + if ((oui_hdr == oui_rfc1042) || (oui_hdr == oui_8021h)) { proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) + data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1]; @@ -177,7 +183,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl /* The DHCP should have at least a message type (request, ack, nack, etc) */ if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6) { - CsrMemCpy(srcAddress.a, saddr, 6); + UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) { @@ -189,7 +195,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl } /* DHCPACK is a special indication */ - if (!CsrMemCmp(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr, 6)) + if (UNIFI_MAC_ADDRESS_CMP(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr) == TRUE) { if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK) { @@ -224,7 +230,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) || (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START)) { - CsrMemCpy(srcAddress.a, saddr, 6); + UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL, direction, &srcAddress); @@ -238,7 +244,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl { if (proto == TA_PROTO_TYPE_ARP) { - CsrMemCpy(srcAddress.a, saddr, 6); + UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP, direction, &srcAddress); @@ -253,7 +259,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl /* detect Aironet frames */ if (!CsrMemCmp(data->os_data_ptr + 3, aironet_snap, 5)) { - CsrMemCpy(srcAddress.a, saddr, 6); + UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET, direction, &srcAddress); } diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h index feda2e051c21..5f1c67b7c6ea 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi.h +++ b/drivers/staging/csr/csr_wifi_hip_unifi.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -103,6 +103,17 @@ extern "C" { #include "csr_formatted_io.h" /* from the synergy gsp folder */ #include "csr_wifi_result.h" +/* Utility MACROS. Note that UNIFI_MAC_ADDRESS_CMP returns TRUE on success */ +#define UNIFI_MAC_ADDRESS_COPY(dst, src) \ + do { (dst)[0] = (src)[0]; (dst)[1] = (src)[1]; \ + (dst)[2] = (src)[2]; (dst)[3] = (src)[3]; \ + (dst)[4] = (src)[4]; (dst)[5] = (src)[5]; \ + } while (0) + +#define UNIFI_MAC_ADDRESS_CMP(addr1, addr2) \ + (((addr1)[0] == (addr2)[0]) && ((addr1)[1] == (addr2)[1]) && \ + ((addr1)[2] == (addr2)[2]) && ((addr1)[3] == (addr2)[3]) && \ + ((addr1)[4] == (addr2)[4]) && ((addr1)[5] == (addr2)[5])) /* Traffic queue ordered according to priority * EAPOL/Uncontrolled port Queue should be the last @@ -635,7 +646,24 @@ void unifi_receive_event(void *ospriv, CsrUint8 *sigdata, CsrUint32 siglen, const bulk_data_param_t *bulkdata); +#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL +/** + * + * Used to reque the failed ma packet request back to hal queues + * + * @param ospriv the OS layer context. + * + * @param host_tag host tag for the packet to requeue. + * + * @param bulkDataDesc pointer to the bulk data. + * + * @ingroup upperedge + */ +CsrResult unifi_reque_ma_packet_request(void *ospriv, CsrUint32 host_tag, + CsrUint16 status, + bulk_data_desc_t *bulkDataDesc); +#endif typedef struct { CsrUint16 free_fh_sig_queue_slots[UNIFI_NO_OF_TX_QS]; @@ -836,6 +864,8 @@ const CsrCharString* lookup_bulkcmd_name(CsrUint16 id); /* Function to log HIP's global debug buffer */ #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE void unifi_debug_buf_dump(void); +void unifi_debug_log_to_buf(const CsrCharString *fmt, ...); +void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length); #endif /* Mini-coredump utility functions */ diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.c b/drivers/staging/csr/csr_wifi_hip_xbv.c index 5d0fdcce1a97..5aaec4da441b 100644 --- a/drivers/staging/csr/csr_wifi_hip_xbv.c +++ b/drivers/staging/csr/csr_wifi_hip_xbv.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -579,8 +579,8 @@ static CsrUint32 write_uint16(void *buf, const CsrUint32 offset, const CsrUint16 static CsrUint32 write_uint32(void *buf, const CsrUint32 offset, const CsrUint32 val) { - write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff)); - write_uint16(buf, offset + 2, (CsrUint16)(val >> 16)); + (void)write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff)); + (void)write_uint16(buf, offset + 2, (CsrUint16)(val >> 16)); return sizeof(CsrUint32); } @@ -1055,11 +1055,11 @@ void* xbv_to_patch(card_t *card, fwreadfn_t readfn, patch_offs += write_reset_ptdl(patch_buf, patch_offs, fwinfo, fw_id); /* Now the length is known, update the LIST.length */ - write_uint32(patch_buf, list_len_offs, - (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE); + (void)write_uint32(patch_buf, list_len_offs, + (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE); /* Re write XBV headers just to fill in the correct file size */ - write_xbv_header(patch_buf, 0, (patch_offs - payload_offs)); + (void)write_xbv_header(patch_buf, 0, (patch_offs - payload_offs)); unifi_trace(card->ospriv, UDBG1, "XBV:PTCH size %u, fw_id %u\n", patch_offs, fw_id); diff --git a/drivers/staging/csr/csr_wifi_nme_ap_lib.h b/drivers/staging/csr/csr_wifi_nme_ap_lib.h index fc5692476ddc..aa632d5dd0d4 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_lib.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_lib.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -196,7 +196,6 @@ extern const CsrCharString *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM apCredentials - Security credential configuration. maxConnections - Maximum number of stations/P2P clients allowed p2pGoParam - P2P specific GO parameters. - NOT USED FOR CURRENT RELEASE wpsEnabled - Indicates whether WPS should be enabled or not *******************************************************************************/ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_prim.h b/drivers/staging/csr/csr_wifi_nme_ap_prim.h index e3b56b4b44e3..561c2fdc3799 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_prim.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_prim.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -248,7 +248,6 @@ typedef struct apCredentials - Security credential configuration. maxConnections - Maximum number of stations/P2P clients allowed p2pGoParam - P2P specific GO parameters. - NOT USED FOR CURRENT RELEASE wpsEnabled - Indicates whether WPS should be enabled or not *******************************************************************************/ diff --git a/drivers/staging/csr/csr_wifi_router_converter_init.c b/drivers/staging/csr/csr_wifi_router_converter_init.c index f7ee3f0ec37d..6ff59c01e149 100644 --- a/drivers/staging/csr/csr_wifi_router_converter_init.c +++ b/drivers/staging/csr/csr_wifi_router_converter_init.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -41,11 +41,11 @@ CsrMsgConvMsgEntry* CsrWifiRouterConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint { if (msgType & CSR_PRIM_UPSTREAM) { - CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT; - if (index < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) && - csrwifirouter_conv_lut[index].msgType == msgType) + CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT; + if (idx < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) && + csrwifirouter_conv_lut[idx].msgType == msgType) { - return &csrwifirouter_conv_lut[index]; + return &csrwifirouter_conv_lut[idx]; } } else diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c index 36403fcf97e8..32d0bb632d99 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -50,9 +50,11 @@ static CsrMsgConvMsgEntry csrwifirouterctrl_conv_lut[] = { { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, CsrWifiRouterCtrlCapabilitiesReqSizeof, CsrWifiRouterCtrlCapabilitiesReqSer, CsrWifiRouterCtrlCapabilitiesReqDes, CsrWifiRouterCtrlCapabilitiesReqSerFree }, { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, CsrWifiRouterCtrlBlockAckEnableReqSizeof, CsrWifiRouterCtrlBlockAckEnableReqSer, CsrWifiRouterCtrlBlockAckEnableReqDes, CsrWifiRouterCtrlBlockAckEnableReqSerFree }, { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, CsrWifiRouterCtrlBlockAckDisableReqSizeof, CsrWifiRouterCtrlBlockAckDisableReqSer, CsrWifiRouterCtrlBlockAckDisableReqDes, CsrWifiRouterCtrlBlockAckDisableReqSerFree }, - { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, CsrWifiRouterCtrlWapiMulticastReqSizeof, CsrWifiRouterCtrlWapiMulticastReqSer, CsrWifiRouterCtrlWapiMulticastReqDes, CsrWifiRouterCtrlWapiMulticastReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, CsrWifiRouterCtrlWapiRxPktReqSizeof, CsrWifiRouterCtrlWapiRxPktReqSer, CsrWifiRouterCtrlWapiRxPktReqDes, CsrWifiRouterCtrlWapiRxPktReqSerFree }, { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, CsrWifiRouterCtrlWapiMulticastFilterReqSizeof, CsrWifiRouterCtrlWapiMulticastFilterReqSer, CsrWifiRouterCtrlWapiMulticastFilterReqDes, CsrWifiRouterCtrlWapiMulticastFilterReqSerFree }, { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, CsrWifiRouterCtrlWapiUnicastFilterReqSizeof, CsrWifiRouterCtrlWapiUnicastFilterReqSer, CsrWifiRouterCtrlWapiUnicastFilterReqDes, CsrWifiRouterCtrlWapiUnicastFilterReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof, CsrWifiRouterCtrlWapiUnicastTxPktReqSer, CsrWifiRouterCtrlWapiUnicastTxPktReqDes, CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, CsrWifiRouterCtrlWapiFilterReqSizeof, CsrWifiRouterCtrlWapiFilterReqSer, CsrWifiRouterCtrlWapiFilterReqDes, CsrWifiRouterCtrlWapiFilterReqSerFree }, { CSR_WIFI_ROUTER_CTRL_HIP_IND, CsrWifiRouterCtrlHipIndSizeof, CsrWifiRouterCtrlHipIndSer, CsrWifiRouterCtrlHipIndDes, CsrWifiRouterCtrlHipIndSerFree }, { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, CsrWifiRouterCtrlMulticastAddressIndSizeof, CsrWifiRouterCtrlMulticastAddressIndSer, CsrWifiRouterCtrlMulticastAddressIndDes, CsrWifiRouterCtrlMulticastAddressIndSerFree }, { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, CsrWifiRouterCtrlPortConfigureCfmSizeof, CsrWifiRouterCtrlPortConfigureCfmSer, CsrWifiRouterCtrlPortConfigureCfmDes, CsrWifiRouterCtrlPortConfigureCfmSerFree }, @@ -81,7 +83,9 @@ static CsrMsgConvMsgEntry csrwifirouterctrl_conv_lut[] = { { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, CsrWifiRouterCtrlBlockAckDisableCfmSizeof, CsrWifiRouterCtrlBlockAckDisableCfmSer, CsrWifiRouterCtrlBlockAckDisableCfmDes, CsrWifiRouterCtrlBlockAckDisableCfmSerFree }, { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, CsrWifiRouterCtrlBlockAckErrorIndSizeof, CsrWifiRouterCtrlBlockAckErrorIndSer, CsrWifiRouterCtrlBlockAckErrorIndDes, CsrWifiRouterCtrlBlockAckErrorIndSerFree }, { CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, CsrWifiRouterCtrlStaInactiveIndSizeof, CsrWifiRouterCtrlStaInactiveIndSer, CsrWifiRouterCtrlStaInactiveIndDes, CsrWifiRouterCtrlStaInactiveIndSerFree }, - { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, CsrWifiRouterCtrlWapiMulticastIndSizeof, CsrWifiRouterCtrlWapiMulticastIndSer, CsrWifiRouterCtrlWapiMulticastIndDes, CsrWifiRouterCtrlWapiMulticastIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, CsrWifiRouterCtrlWapiRxMicCheckIndSizeof, CsrWifiRouterCtrlWapiRxMicCheckIndSer, CsrWifiRouterCtrlWapiRxMicCheckIndDes, CsrWifiRouterCtrlWapiRxMicCheckIndSerFree }, + { CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, CsrWifiRouterCtrlModeSetCfmSizeof, CsrWifiRouterCtrlModeSetCfmSer, CsrWifiRouterCtrlModeSetCfmDes, CsrWifiRouterCtrlModeSetCfmSerFree }, + { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer, CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree }, { 0, NULL, NULL, NULL, NULL }, }; @@ -90,11 +94,11 @@ CsrMsgConvMsgEntry* CsrWifiRouterCtrlConverterLookup(CsrMsgConvMsgEntry *ce, Csr { if (msgType & CSR_PRIM_UPSTREAM) { - CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT; - if (index < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) && - csrwifirouterctrl_conv_lut[index].msgType == msgType) + CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT; + if (idx < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) && + csrwifirouterctrl_conv_lut[idx].msgType == msgType) { - return &csrwifirouterctrl_conv_lut[index]; + return &csrwifirouterctrl_conv_lut[idx]; } } else diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c index 57aa36739590..d161fad84608 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -70,6 +70,13 @@ void CsrWifiRouterCtrlFreeDownstreamMessageContents(CsrUint16 eventClass, void * p->tclas = NULL; break; } + case CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ: + { + CsrWifiRouterCtrlWifiOnReq *p = (CsrWifiRouterCtrlWifiOnReq *)message; + CsrPmemFree(p->data); + p->data = NULL; + break; + } case CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES: { CsrWifiRouterCtrlWifiOnRes *p = (CsrWifiRouterCtrlWifiOnRes *)message; @@ -77,15 +84,22 @@ void CsrWifiRouterCtrlFreeDownstreamMessageContents(CsrUint16 eventClass, void * p->smeVersions.smeBuild = NULL; break; } - case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ: + case CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ: { - CsrWifiRouterCtrlWapiMulticastReq *p = (CsrWifiRouterCtrlWapiMulticastReq *)message; + CsrWifiRouterCtrlWapiRxPktReq *p = (CsrWifiRouterCtrlWapiRxPktReq *)message; CsrPmemFree(p->signal); p->signal = NULL; CsrPmemFree(p->data); p->data = NULL; break; } + case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ: + { + CsrWifiRouterCtrlWapiUnicastTxPktReq *p = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)message; + CsrPmemFree(p->data); + p->data = NULL; + break; + } default: break; diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c index 25e327357a32..b6bf11d566d7 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -63,15 +63,22 @@ void CsrWifiRouterCtrlFreeUpstreamMessageContents(CsrUint16 eventClass, void *me p->versions.routerBuild = NULL; break; } - case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND: + case CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND: { - CsrWifiRouterCtrlWapiMulticastInd *p = (CsrWifiRouterCtrlWapiMulticastInd *)message; + CsrWifiRouterCtrlWapiRxMicCheckInd *p = (CsrWifiRouterCtrlWapiRxMicCheckInd *)message; CsrPmemFree(p->signal); p->signal = NULL; CsrPmemFree(p->data); p->data = NULL; break; } + case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND: + { + CsrWifiRouterCtrlWapiUnicastTxEncryptInd *p = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)message; + CsrPmemFree(p->data); + p->data = NULL; + break; + } default: break; diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h index f0ad836b00c5..6c7e97437570 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -658,6 +658,39 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER #define CsrWifiRouterCtrlModeSetReqSend(src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \ CsrWifiRouterCtrlModeSetReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) +/******************************************************************************* + + NAME + CsrWifiRouterCtrlModeSetCfmSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + mode - + status - + +*******************************************************************************/ +#define CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__) \ + msg__ = (CsrWifiRouterCtrlModeSetCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->mode = (mode__); \ + msg__->status = (status__); + +#define CsrWifiRouterCtrlModeSetCfmSendTo(dst__, src__, clientData__, interfaceTag__, mode__, status__) \ + { \ + CsrWifiRouterCtrlModeSetCfm *msg__; \ + CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlModeSetCfmSend(dst__, clientData__, interfaceTag__, mode__, status__) \ + CsrWifiRouterCtrlModeSetCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, mode__, status__) + /******************************************************************************* NAME @@ -1594,6 +1627,35 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER #define CsrWifiRouterCtrlUnexpectedFrameIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__) \ CsrWifiRouterCtrlUnexpectedFrameIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__) +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiFilterReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + isWapiConnected - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__) \ + msg__ = (CsrWifiRouterCtrlWapiFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiFilterReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->isWapiConnected = (isWapiConnected__); + +#define CsrWifiRouterCtrlWapiFilterReqSendTo(dst__, src__, interfaceTag__, isWapiConnected__) \ + { \ + CsrWifiRouterCtrlWapiFilterReq *msg__; \ + CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiFilterReqSend(src__, interfaceTag__, isWapiConnected__) \ + CsrWifiRouterCtrlWapiFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, isWapiConnected__) + /******************************************************************************* NAME @@ -1602,68 +1664,73 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER DESCRIPTION PARAMETERS - queue - Message Source Task Queue (Cfm's will be sent to this Queue) - status - + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + status - *******************************************************************************/ -#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__) \ +#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \ msg__ = (CsrWifiRouterCtrlWapiMulticastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastFilterReq)); \ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ msg__->status = (status__); -#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, status__) \ +#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \ { \ CsrWifiRouterCtrlWapiMulticastFilterReq *msg__; \ - CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__); \ + CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \ CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ } -#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, status__) \ - CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__) +#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, interfaceTag__, status__) \ + CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__) /******************************************************************************* NAME - CsrWifiRouterCtrlWapiMulticastReqSend + CsrWifiRouterCtrlWapiRxMicCheckIndSend DESCRIPTION PARAMETERS - queue - Message Source Task Queue (Cfm's will be sent to this Queue) + queue - Destination Task Queue + clientData - + interfaceTag - signalLength - signal - dataLength - data - *******************************************************************************/ -#define CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__) \ - msg__ = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); \ - CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, dst__, src__); \ +#define CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + msg__ = (CsrWifiRouterCtrlWapiRxMicCheckInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ msg__->signalLength = (signalLength__); \ msg__->signal = (signal__); \ msg__->dataLength = (dataLength__); \ msg__->data = (data__); -#define CsrWifiRouterCtrlWapiMulticastReqSendTo(dst__, src__, signalLength__, signal__, dataLength__, data__) \ +#define CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ { \ - CsrWifiRouterCtrlWapiMulticastReq *msg__; \ - CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__); \ - CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + CsrWifiRouterCtrlWapiRxMicCheckInd *msg__; \ + CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ } -#define CsrWifiRouterCtrlWapiMulticastReqSend(src__, signalLength__, signal__, dataLength__, data__) \ - CsrWifiRouterCtrlWapiMulticastReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, signalLength__, signal__, dataLength__, data__) +#define CsrWifiRouterCtrlWapiRxMicCheckIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) /******************************************************************************* NAME - CsrWifiRouterCtrlWapiMulticastIndSend + CsrWifiRouterCtrlWapiRxPktReqSend DESCRIPTION PARAMETERS - queue - Destination Task Queue - clientData - + queue - Message Source Task Queue (Cfm's will be sent to this Queue) interfaceTag - signalLength - signal - @@ -1671,25 +1738,24 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER data - *******************************************************************************/ -#define CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ - msg__ = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); \ - CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, dst__, src__); \ - msg__->clientData = (clientData__); \ +#define CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + msg__ = (CsrWifiRouterCtrlWapiRxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, dst__, src__); \ msg__->interfaceTag = (interfaceTag__); \ msg__->signalLength = (signalLength__); \ msg__->signal = (signal__); \ msg__->dataLength = (dataLength__); \ msg__->data = (data__); -#define CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ +#define CsrWifiRouterCtrlWapiRxPktReqSendTo(dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ { \ - CsrWifiRouterCtrlWapiMulticastInd *msg__; \ - CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \ - CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + CsrWifiRouterCtrlWapiRxPktReq *msg__; \ + CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ } -#define CsrWifiRouterCtrlWapiMulticastIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ - CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) +#define CsrWifiRouterCtrlWapiRxPktReqSend(src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ + CsrWifiRouterCtrlWapiRxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) /******************************************************************************* @@ -1699,24 +1765,90 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER DESCRIPTION PARAMETERS - queue - Message Source Task Queue (Cfm's will be sent to this Queue) - status - + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + status - *******************************************************************************/ -#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__) \ +#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \ msg__ = (CsrWifiRouterCtrlWapiUnicastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastFilterReq)); \ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ msg__->status = (status__); -#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, status__) \ +#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \ { \ CsrWifiRouterCtrlWapiUnicastFilterReq *msg__; \ - CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__); \ + CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \ + CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, interfaceTag__, status__) \ + CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend + + DESCRIPTION + + PARAMETERS + queue - Destination Task Queue + clientData - + interfaceTag - + dataLength - + data - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \ + msg__ = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, dst__, src__); \ + msg__->clientData = (clientData__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); + +#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \ + { \ + CsrWifiRouterCtrlWapiUnicastTxEncryptInd *msg__; \ + CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ + } + +#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(dst__, clientData__, interfaceTag__, dataLength__, data__) \ + CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, dataLength__, data__) + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiUnicastTxPktReqSend + + DESCRIPTION + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + dataLength - + data - + +*******************************************************************************/ +#define CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__) \ + msg__ = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); + +#define CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(dst__, src__, interfaceTag__, dataLength__, data__) \ + { \ + CsrWifiRouterCtrlWapiUnicastTxPktReq *msg__; \ + CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__); \ CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ } -#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, status__) \ - CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__) +#define CsrWifiRouterCtrlWapiUnicastTxPktReqSend(src__, interfaceTag__, dataLength__, data__) \ + CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, dataLength__, data__) /******************************************************************************* @@ -1837,22 +1969,26 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER PARAMETERS queue - Message Source Task Queue (Cfm's will be sent to this Queue) clientData - + dataLength - Number of bytes in the buffer pointed to by 'data' + data - Pointer to the buffer containing 'dataLength' bytes *******************************************************************************/ -#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__) \ +#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__) \ msg__ = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq)); \ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, dst__, src__); \ - msg__->clientData = (clientData__); + msg__->clientData = (clientData__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); -#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__) \ +#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__, dataLength__, data__) \ { \ CsrWifiRouterCtrlWifiOnReq *msg__; \ - CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__); \ + CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__); \ CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ } -#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__) \ - CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) +#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__, dataLength__, data__) \ + CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, dataLength__, data__) /******************************************************************************* diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h index 954f600b4ff4..810482a8fbab 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -616,12 +616,14 @@ typedef struct #define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ ((CsrWifiRouterCtrlPrim) (0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) -#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ ((CsrWifiRouterCtrlPrim) (0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) -#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) /* Upstream */ #define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) @@ -654,9 +656,11 @@ typedef struct #define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM ((CsrWifiRouterCtrlPrim)(0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) #define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND ((CsrWifiRouterCtrlPrim)(0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) #define CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND ((CsrWifiRouterCtrlPrim)(0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) -#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM ((CsrWifiRouterCtrlPrim)(0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND ((CsrWifiRouterCtrlPrim)(0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) -#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) +#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) #define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) #define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) @@ -1032,12 +1036,16 @@ typedef struct MEMBERS common - Common header for use with the CsrWifiFsm Module clientData - + dataLength - Number of bytes in the buffer pointed to by 'data' + data - Pointer to the buffer containing 'dataLength' bytes *******************************************************************************/ typedef struct { CsrWifiFsmEvent common; CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint32 dataLength; + CsrUint8 *data; } CsrWifiRouterCtrlWifiOnReq; /******************************************************************************* @@ -1273,12 +1281,13 @@ typedef struct /******************************************************************************* NAME - CsrWifiRouterCtrlWapiMulticastReq + CsrWifiRouterCtrlWapiRxPktReq DESCRIPTION MEMBERS common - Common header for use with the CsrWifiFsm Module + interfaceTag - signalLength - signal - dataLength - @@ -1288,11 +1297,12 @@ typedef struct typedef struct { CsrWifiFsmEvent common; + CsrUint16 interfaceTag; CsrUint16 signalLength; CsrUint8 *signal; CsrUint16 dataLength; CsrUint8 *data; -} CsrWifiRouterCtrlWapiMulticastReq; +} CsrWifiRouterCtrlWapiRxPktReq; /******************************************************************************* @@ -1302,13 +1312,15 @@ typedef struct DESCRIPTION MEMBERS - common - Common header for use with the CsrWifiFsm Module - status - + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - *******************************************************************************/ typedef struct { CsrWifiFsmEvent common; + CsrUint16 interfaceTag; CsrUint8 status; } CsrWifiRouterCtrlWapiMulticastFilterReq; @@ -1320,16 +1332,60 @@ typedef struct DESCRIPTION MEMBERS - common - Common header for use with the CsrWifiFsm Module - status - + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - *******************************************************************************/ typedef struct { CsrWifiFsmEvent common; + CsrUint16 interfaceTag; CsrUint8 status; } CsrWifiRouterCtrlWapiUnicastFilterReq; +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiUnicastTxPktReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + dataLength - + data - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrUint16 dataLength; + CsrUint8 *data; +} CsrWifiRouterCtrlWapiUnicastTxPktReq; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiFilterReq + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + isWapiConnected - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrBool isWapiConnected; +} CsrWifiRouterCtrlWapiFilterReq; + /******************************************************************************* NAME @@ -1984,7 +2040,7 @@ typedef struct /******************************************************************************* NAME - CsrWifiRouterCtrlWapiMulticastInd + CsrWifiRouterCtrlWapiRxMicCheckInd DESCRIPTION @@ -2007,7 +2063,55 @@ typedef struct CsrUint8 *signal; CsrUint16 dataLength; CsrUint8 *data; -} CsrWifiRouterCtrlWapiMulticastInd; +} CsrWifiRouterCtrlWapiRxMicCheckInd; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlModeSetCfm + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + mode - + status - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrWifiRouterCtrlMode mode; + CsrResult status; +} CsrWifiRouterCtrlModeSetCfm; + +/******************************************************************************* + + NAME + CsrWifiRouterCtrlWapiUnicastTxEncryptInd + + DESCRIPTION + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + clientData - + interfaceTag - + dataLength - + data - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrWifiRouterCtrlRequestorInfo clientData; + CsrUint16 interfaceTag; + CsrUint16 dataLength; + CsrUint8 *data; +} CsrWifiRouterCtrlWapiUnicastTxEncryptInd; #ifdef __cplusplus diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c index b7fa6a1eb521..33d92b698c59 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c @@ -35,9 +35,11 @@ const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, - CsrWifiRouterCtrlBlockAckEnableReqHandler, /* 0x0018 */ - CsrWifiRouterCtrlBlockAckDisableReqHandler, /* 0x0019 */ - CsrWifiRouterCtrlWapiMulticastReqHandler, /* 0x001A */ - CsrWifiRouterCtrlWapiMulticastFilterReqHandler, /* 0x001B */ - CsrWifiRouterCtrlWapiUnicastFilterReqHandler, /* 0x001C */ + /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler, + /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler, + /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler, + /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler, + /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler, + /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler, + /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler, }; diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h index 07382ef8cce4..e0ee5cf45f9e 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h @@ -47,8 +47,10 @@ extern "C" { extern void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); - extern void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); + extern void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); #ifdef __cplusplus } #endif diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c index cb1f6dc29888..3239c9bad18d 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -656,6 +656,65 @@ void* CsrWifiRouterCtrlTrafficConfigReqDes(CsrUint8 *buffer, CsrSize length) } +CsrSize CsrWifiRouterCtrlWifiOnReqSizeof(void *msg) +{ + CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 4; /* CsrUint32 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlWifiOnReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlWifiOnReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) voidPrimitivePointer; + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + CsrSize CsrWifiRouterCtrlWifiOnResSizeof(void *msg) { CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) msg; @@ -1055,12 +1114,13 @@ void* CsrWifiRouterCtrlBlockAckDisableReqDes(CsrUint8 *buffer, CsrSize length) } -CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg) +CsrSize CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg) { - CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) msg; + CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) msg; CsrSize bufferSize = 2; - /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ bufferSize += 2; /* CsrUint16 primitive->signalLength */ bufferSize += primitive->signalLength; /* CsrUint8 primitive->signal */ bufferSize += 2; /* CsrUint16 primitive->dataLength */ @@ -1069,11 +1129,12 @@ CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg) } -CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +CsrUint8* CsrWifiRouterCtrlWapiRxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) { - CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *)msg; + CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *)msg; *len = 0; CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); CsrUint16Ser(ptr, len, (CsrUint16) primitive->signalLength); if (primitive->signalLength) { @@ -1088,13 +1149,14 @@ CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void } -void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize length) +void* CsrWifiRouterCtrlWapiRxPktReqDes(CsrUint8 *buffer, CsrSize length) { - CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); + CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq)); CsrSize offset; offset = 0; CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); CsrUint16Des((CsrUint16 *) &primitive->signalLength, buffer, &offset); if (primitive->signalLength) { @@ -1120,15 +1182,74 @@ void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize length) } -void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *voidPrimitivePointer) +void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *voidPrimitivePointer) { - CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) voidPrimitivePointer; + CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) voidPrimitivePointer; CsrPmemFree(primitive->signal); CsrPmemFree(primitive->data); CsrPmemFree(primitive); } +CsrSize CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg) +{ + CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrUint16 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) voidPrimitivePointer; + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg) { CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) msg; @@ -2287,9 +2408,9 @@ void* CsrWifiRouterCtrlStaInactiveIndDes(CsrUint8 *buffer, CsrSize length) } -CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg) +CsrSize CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg) { - CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) msg; + CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) msg; CsrSize bufferSize = 2; /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ @@ -2303,9 +2424,9 @@ CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg) } -CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +CsrUint8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) { - CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *)msg; + CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *)msg; *len = 0; CsrUint16Ser(ptr, len, primitive->common.type); CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); @@ -2324,9 +2445,9 @@ CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void } -void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize length) +void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(CsrUint8 *buffer, CsrSize length) { - CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); + CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd)); CsrSize offset; offset = 0; @@ -2358,12 +2479,116 @@ void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize length) } -void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *voidPrimitivePointer) +void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *voidPrimitivePointer) { - CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) voidPrimitivePointer; + CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) voidPrimitivePointer; CsrPmemFree(primitive->signal); CsrPmemFree(primitive->data); CsrPmemFree(primitive); } +CsrSize CsrWifiRouterCtrlModeSetCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiRouterCtrlMode primitive->mode */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlModeSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mode); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiRouterCtrlModeSetCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mode, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg) +{ + CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */ + bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrUint16 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *voidPrimitivePointer) +{ + CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) voidPrimitivePointer; + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h index 5d82f8d0daa6..3b7834dad524 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -105,10 +105,10 @@ extern CsrSize CsrWifiRouterCtrlTrafficConfigReqSizeof(void *msg); #define CsrWifiRouterCtrlWifiOffResSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiRouterCtrlWifiOffResSerFree CsrWifiRouterCtrlPfree -#define CsrWifiRouterCtrlWifiOnReqSer CsrWifiEventCsrUint16Ser -#define CsrWifiRouterCtrlWifiOnReqDes CsrWifiEventCsrUint16Des -#define CsrWifiRouterCtrlWifiOnReqSizeof CsrWifiEventCsrUint16Sizeof -#define CsrWifiRouterCtrlWifiOnReqSerFree CsrWifiRouterCtrlPfree +extern CsrUint8* CsrWifiRouterCtrlWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWifiOnReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWifiOnReqSizeof(void *msg); +extern void CsrWifiRouterCtrlWifiOnReqSerFree(void *msg); extern CsrUint8* CsrWifiRouterCtrlWifiOnResSer(CsrUint8 *ptr, CsrSize *len, void *msg); extern void* CsrWifiRouterCtrlWifiOnResDes(CsrUint8 *buffer, CsrSize len); @@ -155,21 +155,31 @@ extern void* CsrWifiRouterCtrlBlockAckDisableReqDes(CsrUint8 *buffer, CsrSize le extern CsrSize CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg); #define CsrWifiRouterCtrlBlockAckDisableReqSerFree CsrWifiRouterCtrlPfree -extern CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); -extern void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize len); -extern CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg); -extern void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *msg); +extern CsrUint8* CsrWifiRouterCtrlWapiRxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWapiRxPktReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg); +extern void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *msg); -#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint8Ser -#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint8Des -#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint8Sizeof +#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof #define CsrWifiRouterCtrlWapiMulticastFilterReqSerFree CsrWifiRouterCtrlPfree -#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint8Ser -#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint8Des -#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint8Sizeof +#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof #define CsrWifiRouterCtrlWapiUnicastFilterReqSerFree CsrWifiRouterCtrlPfree +extern CsrUint8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg); +extern void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *msg); + +#define CsrWifiRouterCtrlWapiFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser +#define CsrWifiRouterCtrlWapiFilterReqDes CsrWifiEventCsrUint16CsrUint8Des +#define CsrWifiRouterCtrlWapiFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof +#define CsrWifiRouterCtrlWapiFilterReqSerFree CsrWifiRouterCtrlPfree + extern CsrUint8* CsrWifiRouterCtrlHipIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); extern void* CsrWifiRouterCtrlHipIndDes(CsrUint8 *buffer, CsrSize len); extern CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg); @@ -310,10 +320,20 @@ extern void* CsrWifiRouterCtrlStaInactiveIndDes(CsrUint8 *buffer, CsrSize len); extern CsrSize CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg); #define CsrWifiRouterCtrlStaInactiveIndSerFree CsrWifiRouterCtrlPfree -extern CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); -extern void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize len); -extern CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg); -extern void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *msg); +extern CsrUint8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg); +extern void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *msg); + +extern CsrUint8* CsrWifiRouterCtrlModeSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlModeSetCfmDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlModeSetCfmSizeof(void *msg); +#define CsrWifiRouterCtrlModeSetCfmSerFree CsrWifiRouterCtrlPfree + +extern CsrUint8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg); +extern void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *msg); #ifdef __cplusplus diff --git a/drivers/staging/csr/csr_wifi_sme_ap_lib.h b/drivers/staging/csr/csr_wifi_sme_ap_lib.h index edef7c8de409..bb9e79f95ec2 100644 --- a/drivers/staging/csr/csr_wifi_sme_ap_lib.h +++ b/drivers/staging/csr/csr_wifi_sme_ap_lib.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -63,6 +63,7 @@ void CsrWifiSmeApFreeDownstreamMessageContents(CsrUint16 eventClass, void *messa const CsrCharString* CsrWifiSmeApAccessTypeToString(CsrWifiSmeApAccessType value); const CsrCharString* CsrWifiSmeApAuthSupportToString(CsrWifiSmeApAuthSupport value); const CsrCharString* CsrWifiSmeApAuthTypeToString(CsrWifiSmeApAuthType value); +const CsrCharString* CsrWifiSmeApDirectionToString(CsrWifiSmeApDirection value); const CsrCharString* CsrWifiSmeApPhySupportToString(CsrWifiSmeApPhySupport value); const CsrCharString* CsrWifiSmeApTypeToString(CsrWifiSmeApType value); @@ -79,6 +80,134 @@ const CsrCharString* CsrWifiSmeApPrimTypeToString(CsrPrim msgType); extern const CsrCharString *CsrWifiSmeApUpstreamPrimNames[CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT]; extern const CsrCharString *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT]; +/******************************************************************************* + + NAME + CsrWifiSmeApActiveBaGetReqSend + + DESCRIPTION + This primitive used to retrieve information related to the active block + ack sessions + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + +*******************************************************************************/ +#define CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__) \ + msg__ = (CsrWifiSmeApActiveBaGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApActiveBaGetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); + +#define CsrWifiSmeApActiveBaGetReqSendTo(dst__, src__, interfaceTag__) \ + { \ + CsrWifiSmeApActiveBaGetReq *msg__; \ + CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApActiveBaGetReqSend(src__, interfaceTag__) \ + CsrWifiSmeApActiveBaGetReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__) + +/******************************************************************************* + + NAME + CsrWifiSmeApActiveBaGetCfmSend + + DESCRIPTION + This primitive carries the information related to the active ba sessions + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - Reports the result of the request + activeBaCount - Number of active block ack session + activeBaSessions - Points to a buffer containing an array of + CsrWifiSmeApBaSession structures. + +*******************************************************************************/ +#define CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \ + msg__ = (CsrWifiSmeApActiveBaGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApActiveBaGetCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->activeBaCount = (activeBaCount__); \ + msg__->activeBaSessions = (activeBaSessions__); + +#define CsrWifiSmeApActiveBaGetCfmSendTo(dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \ + { \ + CsrWifiSmeApActiveBaGetCfm *msg__; \ + CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApActiveBaGetCfmSend(dst__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \ + CsrWifiSmeApActiveBaGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, activeBaCount__, activeBaSessions__) + +/******************************************************************************* + + NAME + CsrWifiSmeApBaDeleteReqSend + + DESCRIPTION + This primitive is used to delete an active block ack session + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + interfaceTag - + reason - + baSession - BA session to be deleted + +*******************************************************************************/ +#define CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__) \ + msg__ = (CsrWifiSmeApBaDeleteReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApBaDeleteReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_REQ, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->reason = (reason__); \ + msg__->baSession = (baSession__); + +#define CsrWifiSmeApBaDeleteReqSendTo(dst__, src__, interfaceTag__, reason__, baSession__) \ + { \ + CsrWifiSmeApBaDeleteReq *msg__; \ + CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApBaDeleteReqSend(src__, interfaceTag__, reason__, baSession__) \ + CsrWifiSmeApBaDeleteReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, reason__, baSession__) + +/******************************************************************************* + + NAME + CsrWifiSmeApBaDeleteCfmSend + + DESCRIPTION + This primitive confirms the BA is deleted + + PARAMETERS + queue - Destination Task Queue + interfaceTag - + status - Reports the result of the request + baSession - deleted BA session + +*******************************************************************************/ +#define CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__) \ + msg__ = (CsrWifiSmeApBaDeleteCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApBaDeleteCfm)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_CFM, dst__, src__); \ + msg__->interfaceTag = (interfaceTag__); \ + msg__->status = (status__); \ + msg__->baSession = (baSession__); + +#define CsrWifiSmeApBaDeleteCfmSendTo(dst__, src__, interfaceTag__, status__, baSession__) \ + { \ + CsrWifiSmeApBaDeleteCfm *msg__; \ + CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__); \ + CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \ + } + +#define CsrWifiSmeApBaDeleteCfmSend(dst__, interfaceTag__, status__, baSession__) \ + CsrWifiSmeApBaDeleteCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, baSession__) + /******************************************************************************* NAME diff --git a/drivers/staging/csr/csr_wifi_sme_ap_prim.h b/drivers/staging/csr/csr_wifi_sme_ap_prim.h index 3310cd287fdc..41594395c651 100644 --- a/drivers/staging/csr/csr_wifi_sme_ap_prim.h +++ b/drivers/staging/csr/csr_wifi_sme_ap_prim.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -95,6 +95,23 @@ typedef CsrUint8 CsrWifiSmeApAuthType; #define CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL ((CsrWifiSmeApAuthType) 0x01) #define CSR_WIFI_SME_AP_AUTH_TYPE_WEP ((CsrWifiSmeApAuthType) 0x02) +/******************************************************************************* + + NAME + CsrWifiSmeApDirection + + DESCRIPTION + Definition of Direction + + VALUES + CSR_WIFI_AP_DIRECTION_RECEIPIENT - Receipient + CSR_WIFI_AP_DIRECTION_ORIGINATOR - Originator + +*******************************************************************************/ +typedef CsrUint8 CsrWifiSmeApDirection; +#define CSR_WIFI_AP_DIRECTION_RECEIPIENT ((CsrWifiSmeApDirection) 0x00) +#define CSR_WIFI_AP_DIRECTION_ORIGINATOR ((CsrWifiSmeApDirection) 0x01) + /******************************************************************************* NAME @@ -302,6 +319,28 @@ typedef struct CsrWifiSmeApWapiCapabilitiesMask wapiCapabilities; } CsrWifiSmeApAuthPers; +/******************************************************************************* + + NAME + CsrWifiSmeApBaSession + + DESCRIPTION + + MEMBERS + peerMacAddress - Indicates MAC address of the peer station + tid - Specifies the TID of the MSDUs for which this Block Ack has + been set up. Range: 0-15 + direction - Specifies if the AP is the originator or the recipient of + the data stream that uses the Block Ack. + +*******************************************************************************/ +typedef struct +{ + CsrWifiMacAddress peerMacAddress; + CsrUint8 tid; + CsrWifiSmeApDirection direction; +} CsrWifiSmeApBaSession; + /******************************************************************************* NAME @@ -456,9 +495,11 @@ typedef struct #define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ ((CsrWifiSmeApPrim) (0x0004 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_SME_AP_STA_DISCONNECT_REQ ((CsrWifiSmeApPrim) (0x0005 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ ((CsrWifiSmeApPrim) (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ ((CsrWifiSmeApPrim) (0x0007 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_BA_DELETE_REQ ((CsrWifiSmeApPrim) (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) -#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) /* Upstream */ #define CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) @@ -473,8 +514,10 @@ typedef struct #define CSR_WIFI_SME_AP_STA_DISCONNECT_CFM ((CsrWifiSmeApPrim)(0x0007 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) #define CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM ((CsrWifiSmeApPrim)(0x0008 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) #define CSR_WIFI_SME_AP_ERROR_IND ((CsrWifiSmeApPrim)(0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM ((CsrWifiSmeApPrim)(0x000A + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) +#define CSR_WIFI_SME_AP_BA_DELETE_CFM ((CsrWifiSmeApPrim)(0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) -#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) +#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) #define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) #define CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) @@ -655,6 +698,49 @@ typedef struct CsrWifiSmeWpsConfig wpsConfig; } CsrWifiSmeApWpsConfigurationReq; +/******************************************************************************* + + NAME + CsrWifiSmeApActiveBaGetReq + + DESCRIPTION + This primitive used to retrieve information related to the active block + ack sessions + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; +} CsrWifiSmeApActiveBaGetReq; + +/******************************************************************************* + + NAME + CsrWifiSmeApBaDeleteReq + + DESCRIPTION + This primitive is used to delete an active block ack session + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + reason - + baSession - BA session to be deleted + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrWifiSmeIEEE80211Reason reason; + CsrWifiSmeApBaSession baSession; +} CsrWifiSmeApBaDeleteReq; + /******************************************************************************* NAME @@ -895,6 +981,55 @@ typedef struct CsrResult status; } CsrWifiSmeApErrorInd; +/******************************************************************************* + + NAME + CsrWifiSmeApActiveBaGetCfm + + DESCRIPTION + This primitive carries the information related to the active ba sessions + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - Reports the result of the request + activeBaCount - Number of active block ack session + activeBaSessions - Points to a buffer containing an array of + CsrWifiSmeApBaSession structures. + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrUint16 activeBaCount; + CsrWifiSmeApBaSession *activeBaSessions; +} CsrWifiSmeApActiveBaGetCfm; + +/******************************************************************************* + + NAME + CsrWifiSmeApBaDeleteCfm + + DESCRIPTION + This primitive confirms the BA is deleted + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + interfaceTag - + status - Reports the result of the request + baSession - deleted BA session + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint16 interfaceTag; + CsrResult status; + CsrWifiSmeApBaSession baSession; +} CsrWifiSmeApBaDeleteCfm; + #ifdef __cplusplus } diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.c b/drivers/staging/csr/csr_wifi_sme_converter_init.c index bafd1b411a90..6897a77faf27 100644 --- a/drivers/staging/csr/csr_wifi_sme_converter_init.c +++ b/drivers/staging/csr/csr_wifi_sme_converter_init.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -79,6 +79,7 @@ static CsrMsgConvMsgEntry csrwifisme_conv_lut[] = { { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, CsrWifiSmeSmeCommonConfigSetReqSizeof, CsrWifiSmeSmeCommonConfigSetReqSer, CsrWifiSmeSmeCommonConfigSetReqDes, CsrWifiSmeSmeCommonConfigSetReqSerFree }, { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, CsrWifiSmeInterfaceCapabilityGetReqSizeof, CsrWifiSmeInterfaceCapabilityGetReqSer, CsrWifiSmeInterfaceCapabilityGetReqDes, CsrWifiSmeInterfaceCapabilityGetReqSerFree }, { CSR_WIFI_SME_WPS_CONFIGURATION_REQ, CsrWifiSmeWpsConfigurationReqSizeof, CsrWifiSmeWpsConfigurationReqSer, CsrWifiSmeWpsConfigurationReqDes, CsrWifiSmeWpsConfigurationReqSerFree }, + { CSR_WIFI_SME_SET_REQ, CsrWifiSmeSetReqSizeof, CsrWifiSmeSetReqSer, CsrWifiSmeSetReqDes, CsrWifiSmeSetReqSerFree }, { CSR_WIFI_SME_ACTIVATE_CFM, CsrWifiSmeActivateCfmSizeof, CsrWifiSmeActivateCfmSer, CsrWifiSmeActivateCfmDes, CsrWifiSmeActivateCfmSerFree }, { CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, CsrWifiSmeAdhocConfigGetCfmSizeof, CsrWifiSmeAdhocConfigGetCfmSer, CsrWifiSmeAdhocConfigGetCfmDes, CsrWifiSmeAdhocConfigGetCfmSerFree }, { CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, CsrWifiSmeAdhocConfigSetCfmSizeof, CsrWifiSmeAdhocConfigSetCfmSer, CsrWifiSmeAdhocConfigSetCfmDes, CsrWifiSmeAdhocConfigSetCfmSerFree }, @@ -159,11 +160,11 @@ CsrMsgConvMsgEntry* CsrWifiSmeConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint16 { if (msgType & CSR_PRIM_UPSTREAM) { - CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT; - if (index < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) && - csrwifisme_conv_lut[index].msgType == msgType) + CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT; + if (idx < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) && + csrwifisme_conv_lut[idx].msgType == msgType) { - return &csrwifisme_conv_lut[index]; + return &csrwifisme_conv_lut[idx]; } } else diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.h b/drivers/staging/csr/csr_wifi_sme_converter_init.h index 8637eb7baafe..fb895dec7688 100644 --- a/drivers/staging/csr/csr_wifi_sme_converter_init.h +++ b/drivers/staging/csr/csr_wifi_sme_converter_init.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details diff --git a/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c index c8e66be899cd..93e75e5ace18 100644 --- a/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c +++ b/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -172,6 +172,13 @@ void CsrWifiSmeFreeDownstreamMessageContents(CsrUint16 eventClass, void *message p->wpsConfig.secondaryDeviceType = NULL; break; } + case CSR_WIFI_SME_SET_REQ: + { + CsrWifiSmeSetReq *p = (CsrWifiSmeSetReq *)message; + CsrPmemFree(p->data); + p->data = NULL; + break; + } default: break; diff --git a/drivers/staging/csr/csr_wifi_sme_lib.h b/drivers/staging/csr/csr_wifi_sme_lib.h index 16053fb6ed43..67dcb48448c3 100644 --- a/drivers/staging/csr/csr_wifi_sme_lib.h +++ b/drivers/staging/csr/csr_wifi_sme_lib.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -3442,6 +3442,39 @@ extern const CsrCharString *CsrWifiSmeDownstreamPrimNames[CSR_WIFI_SME_PRIM_DOWN #define CsrWifiSmeScanResultsGetCfmSend(dst__, status__, scanResultsCount__, scanResults__) \ CsrWifiSmeScanResultsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, scanResultsCount__, scanResults__) +/******************************************************************************* + + NAME + CsrWifiSmeSetReqSend + + DESCRIPTION + Used to pass custom data to the SME. Format is the same as 802.11 Info + Elements => | Id | Length | Data + 1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01 + (0x00|0x01)" + + PARAMETERS + queue - Message Source Task Queue (Cfm's will be sent to this Queue) + dataLength - Number of bytes in the buffer pointed to by 'data' + data - Pointer to the buffer containing 'dataLength' bytes + +*******************************************************************************/ +#define CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__) \ + msg__ = (CsrWifiSmeSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSetReq)); \ + CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SET_REQ, dst__, src__); \ + msg__->dataLength = (dataLength__); \ + msg__->data = (data__); + +#define CsrWifiSmeSetReqSendTo(dst__, src__, dataLength__, data__) \ + { \ + CsrWifiSmeSetReq *msg__; \ + CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__); \ + CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \ + } + +#define CsrWifiSmeSetReqSend(src__, dataLength__, data__) \ + CsrWifiSmeSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, dataLength__, data__) + /******************************************************************************* NAME diff --git a/drivers/staging/csr/csr_wifi_sme_prim.h b/drivers/staging/csr/csr_wifi_sme_prim.h index 4bc8520dbd0c..8ffa50a6c048 100644 --- a/drivers/staging/csr/csr_wifi_sme_prim.h +++ b/drivers/staging/csr/csr_wifi_sme_prim.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -1434,7 +1434,7 @@ typedef CsrUint8 CsrWifiSmeWepCredentialType; CsrWifiSmeWmmMode DESCRIPTION - Defines bits for wmmModeMask: enable/disable WMM features. + Defines bits for CsrWifiSmeWmmModeMask: enable/disable WMM features. VALUES CSR_WIFI_SME_WMM_MODE_DISABLED - Disables the WMM features. @@ -2410,40 +2410,6 @@ typedef struct CsrUint16 maxPassiveChannelTimeTu; } CsrWifiSmeScanConfigData; -/******************************************************************************* - - NAME - CsrWifiSmeStaConfig - - DESCRIPTION - Station configuration options in the SME - - MEMBERS - connectionQualityRssiChangeTrigger - Sets the difference of RSSI - measurements which triggers reports - from the Firmware - connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements - which triggers reports from the - Firmware - wmmModeMask - Mask containing one or more values from - CsrWifiSmeWmmMode - ifIndex - Indicates the band of frequencies used - allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise - keys if no pairwise key is specified - enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key - Caching feature - -*******************************************************************************/ -typedef struct -{ - CsrUint8 connectionQualityRssiChangeTrigger; - CsrUint8 connectionQualitySnrChangeTrigger; - CsrUint8 wmmModeMask; - CsrWifiSmeRadioIF ifIndex; - CsrBool allowUnicastUseGroupCipher; - CsrBool enableOpportunisticKeyCaching; -} CsrWifiSmeStaConfig; - /******************************************************************************* NAME @@ -3197,6 +3163,40 @@ typedef struct } deviceInfo; } CsrWifiSmeScanResult; +/******************************************************************************* + + NAME + CsrWifiSmeStaConfig + + DESCRIPTION + Station configuration options in the SME + + MEMBERS + connectionQualityRssiChangeTrigger - Sets the difference of RSSI + measurements which triggers reports + from the Firmware + connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements + which triggers reports from the + Firmware + wmmModeMask - Mask containing one or more values from + CsrWifiSmeWmmMode + ifIndex - Indicates the band of frequencies used + allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise + keys if no pairwise key is specified + enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key + Caching feature + +*******************************************************************************/ +typedef struct +{ + CsrUint8 connectionQualityRssiChangeTrigger; + CsrUint8 connectionQualitySnrChangeTrigger; + CsrWifiSmeWmmModeMask wmmModeMask; + CsrWifiSmeRadioIF ifIndex; + CsrBool allowUnicastUseGroupCipher; + CsrBool enableOpportunisticKeyCaching; +} CsrWifiSmeStaConfig; + /******************************************************************************* NAME @@ -3393,9 +3393,10 @@ typedef struct #define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0034 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ ((CsrWifiSmePrim) (0x0035 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) #define CSR_WIFI_SME_WPS_CONFIGURATION_REQ ((CsrWifiSmePrim) (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) +#define CSR_WIFI_SME_SET_REQ ((CsrWifiSmePrim) (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) -#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST) +#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST) /* Upstream */ #define CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) @@ -4809,6 +4810,30 @@ typedef struct CsrWifiSmeWpsConfig wpsConfig; } CsrWifiSmeWpsConfigurationReq; +/******************************************************************************* + + NAME + CsrWifiSmeSetReq + + DESCRIPTION + Used to pass custom data to the SME. Format is the same as 802.11 Info + Elements => | Id | Length | Data + 1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01 + (0x00|0x01)" + + MEMBERS + common - Common header for use with the CsrWifiFsm Module + dataLength - Number of bytes in the buffer pointed to by 'data' + data - Pointer to the buffer containing 'dataLength' bytes + +*******************************************************************************/ +typedef struct +{ + CsrWifiFsmEvent common; + CsrUint32 dataLength; + CsrUint8 *data; +} CsrWifiSmeSetReq; + /******************************************************************************* NAME diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.c b/drivers/staging/csr/csr_wifi_sme_serialize.c index 489c378186bd..5c1bc31f2dd6 100644 --- a/drivers/staging/csr/csr_wifi_sme_serialize.c +++ b/drivers/staging/csr/csr_wifi_sme_serialize.c @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -1356,7 +1356,7 @@ CsrSize CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg) bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */ bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */ - bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */ + bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */ bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */ bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */ bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */ @@ -1898,6 +1898,62 @@ void CsrWifiSmeWpsConfigurationReqSerFree(void *voidPrimitivePointer) } +CsrSize CsrWifiSmeSetReqSizeof(void *msg) +{ + CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 4; /* CsrUint32 primitive->dataLength */ + bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */ + return bufferSize; +} + + +CsrUint8* CsrWifiSmeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength); + if (primitive->dataLength) + { + CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength))); + } + return(ptr); +} + + +void* CsrWifiSmeSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset); + if (primitive->dataLength) + { + primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength); + CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength))); + } + else + { + primitive->data = NULL; + } + + return primitive; +} + + +void CsrWifiSmeSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->data); + CsrPmemFree(primitive); +} + + CsrSize CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg) { CsrSize bufferSize = 2; @@ -5085,7 +5141,7 @@ CsrSize CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg) bufferSize += 2; /* CsrResult primitive->status */ bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */ bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */ - bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */ + bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */ bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */ bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */ bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */ diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h index c2d7fd68c4ae..0080bf43a6c4 100644 --- a/drivers/staging/csr/csr_wifi_sme_serialize.h +++ b/drivers/staging/csr/csr_wifi_sme_serialize.h @@ -1,6 +1,6 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 + (c) Cambridge Silicon Radio Limited 2012 All rights reserved and confidential information of CSR Refer to LICENSE.txt included with this source for details @@ -300,6 +300,11 @@ extern void* CsrWifiSmeWpsConfigurationReqDes(CsrUint8 *buffer, CsrSize len); extern CsrSize CsrWifiSmeWpsConfigurationReqSizeof(void *msg); extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg); +extern CsrUint8* CsrWifiSmeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); +extern void* CsrWifiSmeSetReqDes(CsrUint8 *buffer, CsrSize len); +extern CsrSize CsrWifiSmeSetReqSizeof(void *msg); +extern void CsrWifiSmeSetReqSerFree(void *msg); + #define CsrWifiSmeActivateCfmSer CsrWifiEventCsrUint16Ser #define CsrWifiSmeActivateCfmDes CsrWifiEventCsrUint16Des #define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index 4545fb2b063b..fbe86301816c 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -47,12 +47,7 @@ int buswidth = 0; /* 0 means use default, values 1,4 */ int sdio_clock = 50000; /* kHz */ int unifi_debug = 0; -/* - * fw_init prevents f/w initialisation on error. - * Unless necessary, avoid usage in the CSR_SME_EMB build because it prevents - * UniFi initialisation after getting out of suspend and also leaves - * UniFi powered when the module unloads. - */ +/* fw_init prevents f/w initialisation on error. */ int fw_init[MAX_UNIFI_DEVS] = {-1, -1}; int use_5g = 0; int led_mask = 0; /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */ @@ -67,6 +62,12 @@ int sdio_byte_mode = 0; /* 0 for block mode + padding, 1 for byte mode */ int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS; int run_bh_once = -1; /* Set for scheduled interrupt mode, -1 = default */ int bh_priority = -1; +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +#define UNIFI_LOG_HIP_SIGNALS_FILTER_SIGNAL (1 << 0) +#define UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA (1 << 1) +#define UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP (1 << 2) +int log_hip_signals = 0; +#endif MODULE_DESCRIPTION("CSR UniFi (SDIO)"); @@ -87,6 +88,9 @@ module_param(sdio_byte_mode, int, S_IRUGO|S_IWUSR); module_param(coredump_max, int, S_IRUGO|S_IWUSR); module_param(run_bh_once, int, S_IRUGO|S_IWUSR); module_param(bh_priority, int, S_IRUGO|S_IWUSR); +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +module_param(log_hip_signals, int, S_IRUGO|S_IWUSR); +#endif MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode"); MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)"); @@ -105,6 +109,10 @@ MODULE_PARM_DESC(sdio_byte_mode, "Set to 1 for byte mode SDIO"); MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate"); MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts"); MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority"); +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +MODULE_PARM_DESC(log_hip_signals, "Set to 1 to enable HIP signal offline logging"); +#endif + /* Callback for event logging to UDI clients */ static void udi_log_event(ul_client_t *client, @@ -193,6 +201,54 @@ trace_putest_cmdid(unifi_putest_command_t putest_cmd) } } +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +int uf_register_hip_offline_debug(unifi_priv_t *priv) +{ + ul_client_t *udi_cli; + int i; + + udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event); + if (udi_cli == NULL) { + /* Too many clients already using this device */ + unifi_error(priv, "Too many UDI clients already open\n"); + return -ENOSPC; + } + unifi_trace(priv, UDBG1, "Offline HIP client is registered\n"); + + down(&priv->udi_logging_mutex); + udi_cli->event_hook = udi_log_event; + unifi_set_udi_hook(priv->card, logging_handler); + /* Log all signals by default */ + for (i = 0; i < SIG_FILTER_SIZE; i++) { + udi_cli->signal_filter[i] = 0xFFFF; + } + priv->logging_client = udi_cli; + up(&priv->udi_logging_mutex); + + return 0; +} + +int uf_unregister_hip_offline_debug(unifi_priv_t *priv) +{ + ul_client_t *udi_cli = priv->logging_client; + if (udi_cli == NULL) + { + unifi_error(priv, "Unknown HIP client unregister request\n"); + return -ERANGE; + } + + unifi_trace(priv, UDBG1, "Offline HIP client is unregistered\n"); + + down(&priv->udi_logging_mutex); + priv->logging_client = NULL; + udi_cli->event_hook = NULL; + up(&priv->udi_logging_mutex); + + ul_deregister_client(udi_cli); + + return 0; +} +#endif /* @@ -312,7 +368,6 @@ unifi_open(struct inode *inode, struct file *file) } /* unifi_open() */ - static int unifi_release(struct inode *inode, struct file *filp) { @@ -354,6 +409,15 @@ unifi_release(struct inode *inode, struct file *filp) } uf_sme_deinit(priv); + + /* It is possible that a blocking SME request was made from another process + * which did not get read by the SME before the WifiOffReq. + * So check for a pending request which will go unanswered and cancel + * the wait for event. As only one blocking request can be in progress at + * a time, up to one event should be completed. + */ + uf_sme_cancel_request(priv, 0); + #endif /* CSR_SME_USERSPACE */ } else { @@ -979,6 +1043,14 @@ unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto out; } +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE + if (log_hip_signals) { + unifi_error(priv, "omnicli cannot be used when log_hip_signals is used\n"); + r = -EFAULT; + goto out; + } +#endif + down(&priv->udi_logging_mutex); if (int_param) { pcli->event_hook = udi_log_event; @@ -1264,6 +1336,11 @@ unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) unifi_info(priv, "UniFi ready\n"); +#ifdef ANDROID_BUILD + /* Release the wakelock */ + unifi_trace(priv, UDBG1, "netdev_init: release wake lock\n"); + wake_unlock(&unifi_sdio_wake_lock); +#endif #ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */ { struct net_device *dev = priv->netdev[interfaceTag]; @@ -1720,6 +1797,40 @@ udi_log_event(ul_client_t *pcli, return; } +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE + /* When HIP offline signal logging is enabled, omnicli cannot run */ + if (log_hip_signals) + { + /* Add timestamp */ + if (log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP) + { + int timestamp = jiffies_to_msecs(jiffies); + unifi_debug_log_to_buf("T:"); + unifi_debug_log_to_buf("%04X%04X ", *(((CsrUint16*)×tamp) + 1), + *(CsrUint16*)×tamp); + } + + /* Add signal */ + unifi_debug_log_to_buf("S%s:%04X R:%04X D:%04X ", + dir ? "T" : "F", + *(CsrUint16*)signal, + *(CsrUint16*)(signal + 2), + *(CsrUint16*)(signal + 4)); + unifi_debug_hex_to_buf(signal + 6, signal_len - 6); + + /* Add bulk data (assume 1 bulk data per signal) */ + if ((log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA) && + (bulkdata->d[0].data_length > 0)) + { + unifi_debug_log_to_buf("\nD:"); + unifi_debug_hex_to_buf(bulkdata->d[0].os_data_ptr, bulkdata->d[0].data_length); + } + unifi_debug_log_to_buf("\n"); + + return; + } +#endif + #ifdef CSR_NATIVE_LINUX uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir); #endif @@ -1950,7 +2061,7 @@ int uf_create_device_nodes(unifi_priv_t *priv, int bus_id) priv->unifiudi_cdev.owner = THIS_MODULE; devno = MKDEV(MAJOR(unifi_first_devno), - MINOR(unifi_first_devno) + (bus_id * MAX_UNIFI_DEVS) + 1); + MINOR(unifi_first_devno) + (bus_id * 2) + 1); r = cdev_add(&priv->unifiudi_cdev, devno, 1); if (r) { device_destroy(unifi_class, priv->unifi_cdev.dev); @@ -2081,7 +2192,9 @@ unifi_load(void) #endif printk("CSR native no WEXT support\n"); #endif - +#ifdef CSR_WIFI_SPLIT_PATCH + printk("Split patch support\n"); +#endif printk("Kernel %d.%d.%d\n", ((LINUX_VERSION_CODE) >> 16) & 0xff, ((LINUX_VERSION_CODE) >> 8) & 0xff, diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c index 4ac3c89baa5d..03da0d5c247a 100644 --- a/drivers/staging/csr/firmware.c +++ b/drivers/staging/csr/firmware.c @@ -296,7 +296,18 @@ uf_run_unifihelper(unifi_priv_t *priv) #endif } /* uf_run_unifihelper() */ +#ifdef CSR_WIFI_SPLIT_PATCH +static CsrBool is_ap_mode(unifi_priv_t *priv) +{ + if (priv == NULL || priv->interfacePriv[0] == NULL) + { + return FALSE; + } + /* Test for mode requiring AP patch */ + return(CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode)); +} +#endif /* * --------------------------------------------------------------------------- @@ -334,8 +345,13 @@ int uf_request_firmware_files(unifi_priv_t *priv, int is_fw) if (is_fw == UNIFI_FW_STA) { /* Free kernel buffer and reload */ uf_release_firmware(priv, &priv->fw_sta); +#ifdef CSR_WIFI_SPLIT_PATCH scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s", - postfix, "sta.xbv"); + postfix, (is_ap_mode(priv) ? "ap.xbv" : "staonly.xbv") ); +#else + scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s", + postfix, "sta.xbv" ); +#endif r = request_firmware(&fw_entry, fw_name, priv->unifi_device); if (r == 0) { priv->fw_sta.dl_data = fw_entry->data; diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index fbf1b2099cc9..f489ade7f1ba 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -407,6 +407,13 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) INIT_WORK(&priv->rx_work_struct, rx_wq_handler); #endif +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE + if (log_hip_signals) + { + uf_register_hip_offline_debug(priv); + } +#endif + /* Initialise the SME related threads and parameters */ r = uf_sme_init(priv); if (r) { @@ -431,6 +438,12 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) return priv; failed4: +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +if (log_hip_signals) +{ + uf_unregister_hip_offline_debug(priv); +} +#endif #ifdef CSR_WIFI_RX_PATH_SPLIT flush_workqueue(priv->rx_workqueue); destroy_workqueue(priv->rx_workqueue); @@ -547,6 +560,13 @@ cleanup_unifi_sdio(unifi_priv_t *priv) priv->smepriv = NULL; #endif +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE + if (log_hip_signals) + { + uf_unregister_hip_offline_debug(priv); + } +#endif + /* Free any packets left in the Rx queues */ for(i=0;ista_wmm_capabilities = 0; +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME)) priv->wapi_multicast_filter = 0; priv->wapi_unicast_filter = 0; priv->wapi_unicast_queued_pkt_filter = 0; +#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND + priv->isWapiConnection = FALSE; +#endif +#endif /* Enable all queues by default */ interfacePriv->queueEnabled[0] = 1; @@ -450,7 +455,15 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) spin_lock_init(&priv->send_signal_lock); spin_lock_init(&priv->m4_lock); - spin_lock_init(&priv->ba_lock); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) + sema_init(&priv->ba_mutex, 1); +#else + init_MUTEX(&priv->ba_mutex); +#endif + +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + spin_lock_init(&priv->wapi_lock); +#endif #ifdef CSR_SUPPORT_SME spin_lock_init(&priv->staRecord_lock); @@ -472,6 +485,11 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) /* Create m4 buffering work structure */ INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq); + +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */ + INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt); +#endif #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) @@ -504,6 +522,11 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id) } #endif /* CSR_SUPPORT_WEXT */ +#ifdef CSR_WIFI_SPLIT_PATCH + /* set it to some invalid value */ + priv->pending_mode_set.common.destination = 0xaaaa; +#endif + return priv; } /* uf_alloc_netdevice() */ @@ -655,6 +678,19 @@ uf_free_netdevice(unifi_priv_t *priv) } spin_unlock_irqrestore(&priv->m4_lock, flags); +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + /* Free any bulkdata buffers allocated for M4 caching */ + spin_lock_irqsave(&priv->wapi_lock, flags); + for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { + netInterface_priv_t *interfacePriv = priv->interfacePriv[i]; + if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) { + unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i); + unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data); + } + } + spin_unlock_irqrestore(&priv->wapi_lock, flags); +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) #ifdef CONFIG_NET_SCHED /* Unregister the qdisc operations */ @@ -1556,7 +1592,7 @@ int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk /* IF Qos Data or Qos Null Data then set QosControl field */ if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) { - if (priority >= 7) { + if (priority > 7) { unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority); qc |= 7; } else { @@ -1628,6 +1664,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED; CsrInt8 protection; netInterface_priv_t *interfacePriv = NULL; + CSR_RATE TransmitRate = (CSR_RATE)0; unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n"); @@ -1780,6 +1817,63 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr return 0; } #endif + }/*EAPOL or WAI packet*/ + +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \ + (priv->wapi_unicast_filter) && \ + (proto != ETH_P_PAE) && \ + (proto != ETH_P_WAI) && \ + (skb->len > 0)) + { + CSR_SIGNAL signal; + CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest; + netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]); + + unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n"); + + /* initialize signal to zero */ + memset(&signal, 0, sizeof(CSR_SIGNAL)); + /* Frame MA_PACKET request */ + signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID; + signal.SignalPrimitiveHeader.ReceiverProcessId = 0; + signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id; + + /* Fill the MA-PACKET.req */ + req->TransmissionControl = 0; + req->Priority = priority; + unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority); + req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */ + req->HostTag = 0xffffffff; /* Ask for a new HostTag */ + /* RA address matching with address 1 of Mac header */ + memcpy(req->Ra.x, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN); + + /* Store the M4-PACKET.req for later */ + spin_lock(&priv->wapi_lock); + interfacePriv->wapi_unicast_ma_pkt_sig = signal; + interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length; + interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length; + interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr; + interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr; + spin_unlock(&priv->wapi_lock); + + /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(). + * It cannot be called directly from the tx path because it + * does a non-atomic kmalloc via the framework's CsrPmemAlloc(). + */ + queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt); + + return 0; + } +#endif + + if(priv->cmanrTestMode) + { + TransmitRate = priv->cmanrTestModeTransmitRate; + unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n", + priv->cmanrTestModeTransmitRate, + TransmitRate + ); } /* Send UniFi msg */ @@ -1789,7 +1883,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr 0xffffffff, /* Ask for a new HostTag */ interfaceTag, transmissionControl, - (CSR_RATE)0, + TransmitRate, priority, priv->netdev_client->sender_id, &bulkdata); @@ -1900,8 +1994,22 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) #endif /* CONFIG_NET_SCHED */ if (result == NETDEV_TX_OK) { +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + /* Don't update the tx stats when the pkt is to be sent for sw encryption*/ + if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && + (priv->wapi_unicast_filter == 1))) + { + dev->trans_start = jiffies; + /* Should really count tx stats in the UNITDATA.status signal but + * that doesn't have the length. + */ + interfacePriv->stats.tx_packets++; + /* count only the packet payload */ + interfacePriv->stats.tx_bytes += skb->len; - dev->trans_start = jiffies; + } +#else + dev->trans_start = jiffies; /* * Should really count tx stats in the UNITDATA.status signal but @@ -1910,7 +2018,7 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) interfacePriv->stats.tx_packets++; /* count only the packet payload */ interfacePriv->stats.tx_bytes += skb->len; - +#endif } else if (result < 0) { /* Failed to send: fh queue was full, and the skb was discarded. @@ -2118,6 +2226,13 @@ indicate_rx_skb(unifi_priv_t *priv, CsrUint16 ifTag, CsrUint8* dst_a, CsrUint8* } + if(priv->cmanrTestMode) + { + const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication; + priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate; + unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate); + } + /* Pass SKB up the stack */ #ifdef CSR_WIFI_USE_NETIF_RX netif_rx(skb); @@ -2780,36 +2895,17 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){ /* - QoS control field is offset from frame control by 2 (frame control) - + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN - */ + * QoS control field is offset from frame control by 2 (frame control) + * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN + */ if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){ qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30); } else{ qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24); } - - if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){ - CSR_PRIORITY priority; - unifi_TrafficQueue priority_q; - priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK); - priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); - if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) - ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){ - unsigned long lock_flags; - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - srcStaInfo->uapsdSuspended = TRUE; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); - unifi_trace(priv, UDBG3, "%s: qos Trigger Frame received while DTIM Active for staid: 0x%x\n",__FUNCTION__,srcStaInfo->aid); - } - } - else{ - - - unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl); - uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag); - } + unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl); + uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag); } } } @@ -2829,7 +2925,7 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d ba_addr = bssid; } - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ ba_session = interfacePriv->ba_session_rx[ba_session_idx]; if (ba_session){ @@ -2842,14 +2938,14 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d frame_desc.active = TRUE; unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx); process_ba_frame(priv, interfacePriv, ba_session, &frame_desc); - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); process_ba_complete(priv, interfacePriv); break; } } } if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){ - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__); process_amsdu(priv, signal, bulkdata); } @@ -2865,7 +2961,7 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d * And also this code here takes care that timeout check is made for all * the receive indications */ - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){ ba_session_rx_struct *ba_session; ba_session = interfacePriv->ba_session_rx[i]; @@ -2873,8 +2969,8 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d check_ba_frame_age_timeout(priv, interfacePriv, ba_session); } } + up(&priv->ba_mutex); process_ba_complete(priv, interfacePriv); - spin_unlock(&priv->ba_lock); func_exit(); } @@ -3879,7 +3975,7 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, } sn = pkt_err_ind->SequenceNumber; - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */ for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ ba_session = interfacePriv->ba_session_rx[ba_session_idx]; @@ -3894,7 +3990,7 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, } } - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); process_ba_complete(priv, interfacePriv); func_exit(); } diff --git a/drivers/staging/csr/os.c b/drivers/staging/csr/os.c index 6dfce4226750..f5a9352ce784 100644 --- a/drivers/staging/csr/os.c +++ b/drivers/staging/csr/os.c @@ -204,12 +204,10 @@ extern int unifi_debug; (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \ } \ } while (0) -#endif /* UNIFI_DEBUG */ void unifi_error(void* ospriv, const char *fmt, ...) { -#ifdef UNIFI_DEBUG unifi_priv_t *priv = (unifi_priv_t*) ospriv; char s[DEBUG_BUFFER_SIZE]; va_list args; @@ -230,13 +228,11 @@ unifi_error(void* ospriv, const char *fmt, ...) FORMAT_TRACE(s, len, args, fmt); printk("%s", s); -#endif /* UNIFI_DEBUG */ } void unifi_warning(void* ospriv, const char *fmt, ...) { -#ifdef UNIFI_DEBUG unifi_priv_t *priv = (unifi_priv_t*) ospriv; char s[DEBUG_BUFFER_SIZE]; va_list args; @@ -259,14 +255,12 @@ unifi_warning(void* ospriv, const char *fmt, ...) FORMAT_TRACE(s, len, args, fmt); printk("%s", s); -#endif /* UNIFI_DEBUG */ } void unifi_notice(void* ospriv, const char *fmt, ...) { -#ifdef UNIFI_DEBUG unifi_priv_t *priv = (unifi_priv_t*) ospriv; char s[DEBUG_BUFFER_SIZE]; va_list args; @@ -289,14 +283,12 @@ unifi_notice(void* ospriv, const char *fmt, ...) FORMAT_TRACE(s, len, args, fmt); printk("%s", s); -#endif /* UNIFI_DEBUG */ } void unifi_info(void* ospriv, const char *fmt, ...) { -#ifdef UNIFI_DEBUG unifi_priv_t *priv = (unifi_priv_t*) ospriv; char s[DEBUG_BUFFER_SIZE]; va_list args; @@ -319,14 +311,12 @@ unifi_info(void* ospriv, const char *fmt, ...) FORMAT_TRACE(s, len, args, fmt); printk("%s", s); -#endif /* UNIFI_DEBUG */ } /* debugging */ void unifi_trace(void* ospriv, int level, const char *fmt, ...) { -#ifdef UNIFI_DEBUG unifi_priv_t *priv = (unifi_priv_t*) ospriv; char s[DEBUG_BUFFER_SIZE]; va_list args; @@ -351,9 +341,23 @@ unifi_trace(void* ospriv, int level, const char *fmt, ...) printk("%s", s); } -#endif /* UNIFI_DEBUG */ } +#else + +void +unifi_error_nop(void* ospriv, const char *fmt, ...) +{ +} + +void +unifi_trace_nop(void* ospriv, int level, const char *fmt, ...) +{ +} + +#endif /* UNIFI_DEBUG */ + + /* * --------------------------------------------------------------------------- * diff --git a/drivers/staging/csr/putest.c b/drivers/staging/csr/putest.c index 1b2c7c299a6c..22614e7e8f7e 100644 --- a/drivers/staging/csr/putest.c +++ b/drivers/staging/csr/putest.c @@ -180,8 +180,9 @@ int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg) "unifi_putest_gp_read16: Failed to get the params\n"); return -EFAULT; } - + CsrSdioClaim(priv->sdio); csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult); @@ -240,8 +241,9 @@ int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg) } unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data); - + CsrSdioClaim(priv->sdio); csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult); @@ -265,7 +267,7 @@ int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg) unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed); CsrSdioClaim(priv->sdio); - csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed); + csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed * 1000); CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, @@ -304,7 +306,9 @@ int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg) /* Application may have stopped the XAPs, but they are needed for reset */ if (already_in_test) { + CsrSdioClaim(priv->sdio); csrResult = unifi_start_processors(priv->card); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } @@ -317,8 +321,9 @@ int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg) unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult); } } - + CsrSdioClaim(priv->sdio); csrResult = unifi_init(priv->card); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_putest_start: failed to init UniFi\n"); @@ -335,7 +340,9 @@ int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg) CsrResult csrResult; /* Application may have stopped the XAPs, but they are needed for reset */ + CsrSdioClaim(priv->sdio); csrResult = unifi_start_processors(priv->card); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } @@ -428,7 +435,9 @@ int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg) } /* Application may have stopped the XAPs, but they are needed for reset */ + CsrSdioClaim(priv->sdio); csrResult = unifi_start_processors(priv->card); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } @@ -436,7 +445,9 @@ int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg) /* Download the f/w. On UF6xxx this will cause the f/w file to convert * into patch format and download via the ROM boot loader */ + CsrSdioClaim(priv->sdio); csrResult = unifi_download(priv->card, 0x0c00); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_putest_dl_fw: failed to download the f/w\n"); @@ -504,7 +515,9 @@ int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg) priv->fw_sta.dl_len = fw_length; /* Application may have stopped the XAPs, but they are needed for reset */ + CsrSdioClaim(priv->sdio); csrResult = unifi_start_processors(priv->card); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } @@ -512,7 +525,9 @@ int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg) /* Download the f/w. On UF6xxx this will cause the f/w file to convert * into patch format and download via the ROM boot loader */ + CsrSdioClaim(priv->sdio); csrResult = unifi_download(priv->card, 0x0c00); + CsrSdioRelease(priv->sdio); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_putest_dl_fw_buff: failed to download the f/w\n"); @@ -581,7 +596,9 @@ int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg) } /* Card software reset */ + CsrSdioClaim(priv->sdio); r = unifi_card_hard_reset(priv->card); + CsrSdioRelease(priv->sdio); if (r != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r); } @@ -599,7 +616,9 @@ int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg) /* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at * Raw SDIO deinit, to resume them. */ + CsrSdioClaim(priv->sdio); r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH); + CsrSdioRelease(priv->sdio); if (r != CSR_RESULT_SUCCESS) { unifi_error(priv, "Failed to stop processors\n"); } @@ -646,7 +665,9 @@ int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg) return -ENOMEM; } + CsrSdioClaim(priv->sdio); r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length); + CsrSdioRelease(priv->sdio); if (r != CSR_RESULT_SUCCESS) { unifi_error(priv, "cmd52r_block: unifi_readn failed\n"); return -EIO; diff --git a/drivers/staging/csr/sdio_emb.c b/drivers/staging/csr/sdio_emb.c index f61fdb130e61..b6a7d6f513b0 100644 --- a/drivers/staging/csr/sdio_emb.c +++ b/drivers/staging/csr/sdio_emb.c @@ -17,6 +17,7 @@ */ #include #include +#include #include "csr_wifi_hip_unifi.h" #include "unifi_priv.h" @@ -25,7 +26,16 @@ /* The function driver context, i.e the UniFi Driver */ static CsrSdioFunctionDriver *sdio_func_drv; +#ifdef CONFIG_PM +static int uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr); +#endif +/* The Android wakelock is here for completeness. Typically the MMC driver is used + * instead of sdioemb, but sdioemb may be used for CSPI. + */ +#ifdef ANDROID_BUILD +struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */ +#endif /* sdioemb driver uses POSIX error codes */ static CsrResult @@ -501,6 +511,131 @@ uf_glue_sdio_int_handler(struct sdioemb_dev *fdev) } } +#ifdef CONFIG_PM + +/* + * Power Management notifier + */ +struct uf_sdio_emb_pm_notifier +{ + struct list_head list; + + CsrSdioFunction *sdio_ctx; + struct notifier_block pm_notifier; +}; + +/* PM notifier list head */ +static struct uf_sdio_emb_pm_notifier uf_sdio_emb_pm_notifiers = { + .sdio_ctx = NULL, +}; + +/* + * --------------------------------------------------------------------------- + * uf_sdio_emb_register_pm_notifier + * uf_sdio_emb_unregister_pm_notifier + * + * Register/unregister for power management events. A list is used to + * allow multiple card instances to be supported. + * + * Arguments: + * sdio_ctx - CSR SDIO context to associate PM notifier to + * + * Returns: + * Register function returns NULL on error + * --------------------------------------------------------------------------- + */ +static struct uf_sdio_emb_pm_notifier * +uf_sdio_emb_register_pm_notifier(CsrSdioFunction *sdio_ctx) +{ + /* Allocate notifier context for this card instance */ + struct uf_sdio_emb_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_emb_pm_notifier), GFP_KERNEL); + + if (notifier_ctx) + { + notifier_ctx->sdio_ctx = sdio_ctx; + notifier_ctx->pm_notifier.notifier_call = uf_sdio_emb_power_event; + + list_add(¬ifier_ctx->list, &uf_sdio_emb_pm_notifiers.list); + + if (register_pm_notifier(¬ifier_ctx->pm_notifier)) { + printk(KERN_ERR "unifi: register_pm_notifier failed\n"); + } + } + + return notifier_ctx; +} + +static void +uf_sdio_emb_unregister_pm_notifier(CsrSdioFunction *sdio_ctx) +{ + struct uf_sdio_emb_pm_notifier *notifier_ctx; + struct list_head *node, *q; + + list_for_each_safe(node, q, &uf_sdio_emb_pm_notifiers.list) { + notifier_ctx = list_entry(node, struct uf_sdio_emb_pm_notifier, list); + + /* If it matches, unregister and free the notifier context */ + if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx) + { + if (unregister_pm_notifier(¬ifier_ctx->pm_notifier)) { + printk(KERN_ERR "unifi: unregister_pm_notifier failed\n"); + } + + /* Remove from list */ + notifier_ctx->sdio_ctx = NULL; + list_del(node); + kfree(notifier_ctx); + } + } +} + +/* + * --------------------------------------------------------------------------- + * uf_sdio_emb_power_event + * + * Handler for power management events. + * + * We need to handle suspend/resume events while the userspace is unsuspended + * to allow the SME to run its suspend/resume state machines. + * + * Arguments: + * event event ID + * + * Returns: + * Status of the event handling + * --------------------------------------------------------------------------- + */ +static int +uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct uf_sdio_emb_pm_notifier *notifier_ctx = container_of(this, + struct uf_sdio_emb_pm_notifier, + pm_notifier); + + /* Call the CSR SDIO function driver's suspend/resume method + * while the userspace is unsuspended. + */ + switch (event) { + case PM_POST_HIBERNATION: + case PM_POST_SUSPEND: + printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ ); + if (sdio_func_drv && sdio_func_drv->resume) { + sdio_func_drv->resume(notifier_ctx->sdio_ctx); + } + break; + + case PM_HIBERNATION_PREPARE: + case PM_SUSPEND_PREPARE: + printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ ); + if (sdio_func_drv && sdio_func_drv->suspend) { + sdio_func_drv->suspend(notifier_ctx->sdio_ctx); + } + break; + } + return NOTIFY_DONE; +} + +#endif /* CONFIG_PM */ /* * --------------------------------------------------------------------------- @@ -550,16 +685,30 @@ uf_glue_sdio_probe(struct sdioemb_dev *fdev) unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock); sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock); +#ifdef CONFIG_PM + /* Register to get PM events */ + if (uf_sdio_emb_register_pm_notifier(sdio_ctx) == NULL) { + unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__); + } +#endif + /* Call the main UniFi driver inserted handler */ if (sdio_func_drv && sdio_func_drv->inserted) { uf_add_os_device(fdev->slot_id, fdev->os_device); sdio_func_drv->inserted(sdio_ctx); } +#ifdef ANDROID_BUILD + /* Take the wakelock */ + unifi_trace(NULL, UDBG1, "emb probe: take wake lock\n"); + wake_lock(&unifi_sdio_wake_lock); +#endif + return 0; } /* uf_glue_sdio_probe() */ + /* * --------------------------------------------------------------------------- * uf_sdio_remove @@ -585,6 +734,11 @@ uf_sdio_remove(struct sdioemb_dev *fdev) sdio_func_drv->removed(sdio_ctx); } +#ifdef CONFIG_PM + /* Unregister for PM events */ + uf_sdio_emb_unregister_pm_notifier(sdio_ctx); +#endif + kfree(sdio_ctx); } /* uf_sdio_remove */ @@ -606,14 +760,7 @@ uf_sdio_remove(struct sdioemb_dev *fdev) static void uf_glue_sdio_suspend(struct sdioemb_dev *fdev) { - CsrSdioFunction *sdio_ctx = fdev->drv_data; - - unifi_trace(NULL, UDBG3, "Suspending...\n"); - - /* Pass event to UniFi Driver. */ - if (sdio_func_drv && sdio_func_drv->suspend) { - sdio_func_drv->suspend(sdio_ctx); - } + unifi_info(NULL, "Suspending...\n"); } /* uf_glue_sdio_suspend() */ @@ -634,14 +781,13 @@ uf_glue_sdio_suspend(struct sdioemb_dev *fdev) static void uf_glue_sdio_resume(struct sdioemb_dev *fdev) { - CsrSdioFunction *sdio_ctx = fdev->drv_data; + unifi_info(NULL, "Resuming...\n"); - unifi_trace(NULL, UDBG3, "Resuming...\n"); +#ifdef ANDROID_BUILD + unifi_trace(NULL, UDBG1, "emb resume: take wakelock\n"); + wake_lock(&unifi_sdio_wake_lock); +#endif - /* Pass event to UniFi Driver. */ - if (sdio_func_drv && sdio_func_drv->resume) { - sdio_func_drv->resume(sdio_ctx); - } } /* uf_glue_sdio_resume() */ @@ -708,6 +854,15 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv) /* Save the registered driver description */ sdio_func_drv = sdio_drv; +#ifdef CONFIG_PM + /* Initialise PM notifier list */ + INIT_LIST_HEAD(&uf_sdio_emb_pm_notifiers.list); +#endif + +#ifdef ANDROID_BUILD + wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work"); +#endif + /* Register ourself with sdioemb */ r = sdioemb_driver_register(&unifi_sdioemb); if (r) { @@ -724,6 +879,10 @@ CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv) { sdioemb_driver_unregister(&unifi_sdioemb); +#ifdef ANDROID_BUILD + wake_lock_destroy(&unifi_sdio_wake_lock); +#endif + sdio_func_drv = NULL; CsrPmemFree(unifi_sdioemb.id_table); diff --git a/drivers/staging/csr/sdio_events.c b/drivers/staging/csr/sdio_events.c index e4f2d0d82fbf..6892c2e281bc 100644 --- a/drivers/staging/csr/sdio_events.c +++ b/drivers/staging/csr/sdio_events.c @@ -47,6 +47,12 @@ void unifi_suspend(void *ospriv) unifi_priv_t *priv = ospriv; int interfaceTag=0; + /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */ + priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; + + unifi_trace(priv, UDBG1, "unifi_suspend: wol_suspend %d, enable_wol %d", + priv->wol_suspend, enable_wol ); + /* Stop network traffic. */ /* need to stop all the netdevices*/ for( interfaceTag=0;interfaceTaginterfacePriv[interfaceTag]; if (interfacePriv->netdev_registered == 1) { - netif_carrier_off(priv->netdev[interfaceTag]); + if( priv->wol_suspend ) { + unifi_trace(priv, UDBG1, "unifi_suspend: Don't netif_carrier_off"); + } else { + unifi_trace(priv, UDBG1, "unifi_suspend: netif_carrier_off"); + netif_carrier_off(priv->netdev[interfaceTag]); + } UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); } } + + unifi_trace(priv, UDBG1, "unifi_suspend: suspend SME"); + sme_sys_suspend(priv); + } /* unifi_suspend() */ @@ -76,12 +91,44 @@ void unifi_suspend(void *ospriv) void unifi_resume(void *ospriv) { unifi_priv_t *priv = ospriv; + int interfaceTag=0; int r; + int wol = priv->wol_suspend; + + unifi_trace(priv, UDBG1, "unifi_resume: resume SME, enable_wol=%d", enable_wol); + /* The resume causes wifi-on which will re-enable the BH and reinstall the ISR */ r = sme_sys_resume(priv); if (r) { unifi_error(priv, "Failed to resume UniFi\n"); } + /* Resume the network interfaces. For the cold resume case, this will + * happen upon reconnection. + */ + if (wol) { + unifi_trace(priv, UDBG1, "unifi_resume: try to enable carrier"); + + /* need to start all the netdevices*/ + for( interfaceTag=0;interfaceTaginterfacePriv[interfaceTag]; + + unifi_trace(priv, UDBG1, "unifi_resume: interfaceTag %d netdev_registered %d mode %d\n", + interfaceTag, interfacePriv->netdev_registered, interfacePriv->interfaceMode); + + if (interfacePriv->netdev_registered == 1) + { + netif_carrier_on(priv->netdev[interfaceTag]); + UF_NETIF_TX_START_ALL_QUEUES(priv->netdev[interfaceTag]); + } + } + + /* Kick the BH thread (with reason=host) to poll for data that may have + * arrived during a powered suspend. This caters for the case where the SME + * doesn't interact with the chip (e.g install autonomous scans) during resume. + */ + unifi_send_signal(priv->card, NULL, 0, NULL); + } + } /* unifi_resume() */ diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index c8508341597a..24be0872b0aa 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -21,19 +21,28 @@ #include #include #include +#include #include "unifi_priv.h" +#ifdef ANDROID_BUILD +struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */ +#endif static CsrSdioFunctionDriver *sdio_func_drv; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#ifdef CONFIG_PM +static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr); +#endif + /* * We need to keep track of the power on/off because we can not call * mmc_power_restore_host() when the card is already powered. * Even then, we need to patch the MMC driver to add a power_restore handler - * in the mmc_sdio_ops structure. If the MMC driver is not patched, - * mmc_power_save_host() and mmc_power_restore_host() are no-ops. + * in the mmc_sdio_ops structure. If the MMC driver before 2.6.37 is not patched, + * mmc_power_save_host() and mmc_power_restore_host() are no-ops in the kernel, + * returning immediately (at least on x86). */ static int card_is_powered = 1; #endif /* 2.6.32 */ @@ -312,17 +321,28 @@ csr_sdio_enable_hs(struct mmc_card *card) int ret; u8 speed; - if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) + if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) { + /* We've asked for HS clock rates, but controller doesn't + * claim to support it. We should limit the clock + * to 25MHz via module parameter. + */ + printk(KERN_INFO "unifi: request HS but not MMC_CAP_SD_HIGHSPEED"); return 0; + } if (!card->cccr.high_speed) return 0; +#if 1 ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); if (ret) return ret; speed |= SDIO_SPEED_EHS; +#else + /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */ + speed = SDIO_SPEED_EHS | SDIO_SPEED_SHS; +#endif ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); if (ret) @@ -346,12 +366,16 @@ csr_sdio_disable_hs(struct mmc_card *card) if (!card->cccr.high_speed) return 0; - +#if 1 ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); if (ret) return ret; speed &= ~SDIO_SPEED_EHS; +#else + /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */ + speed = SDIO_SPEED_SHS; /* clear SDIO_SPEED_EHS */ +#endif ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); if (ret) @@ -460,6 +484,7 @@ CsrSdioInterruptEnable(CsrSdioFunction *function) func_exit(); if (err) { + printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err); return ConvertSdioToCsrSdioResult(err); } #endif @@ -486,6 +511,7 @@ CsrSdioInterruptDisable(CsrSdioFunction *function) func_exit(); if (err) { + printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err); return ConvertSdioToCsrSdioResult(err); } #endif @@ -772,6 +798,7 @@ uf_glue_sdio_int_handler(struct sdio_func *func) if (!sdio_ctx) { return; } + #ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD /* * Normally, we are not allowed to do any SDIO commands here. @@ -785,7 +812,7 @@ uf_glue_sdio_int_handler(struct sdio_func *func) r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL); #endif if (r) { - printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts\n"); + printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r); } #endif @@ -824,6 +851,8 @@ csr_sdio_linux_remove_irq(CsrSdioFunction *function) struct sdio_func *func = (struct sdio_func *)function->priv; int r; + unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n"); + sdio_claim_host(func); r = sdio_release_irq(func); sdio_release_host(func); @@ -853,6 +882,8 @@ csr_sdio_linux_install_irq(CsrSdioFunction *function) struct sdio_func *func = (struct sdio_func *)function->priv; int r; + unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n"); + /* Register our interrupt handle */ sdio_claim_host(func); r = sdio_claim_irq(func, uf_glue_sdio_int_handler); @@ -866,7 +897,133 @@ csr_sdio_linux_install_irq(CsrSdioFunction *function) return r; } /* csr_sdio_linux_install_irq() */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#ifdef CONFIG_PM + +/* + * Power Management notifier + */ +struct uf_sdio_mmc_pm_notifier +{ + struct list_head list; + + CsrSdioFunction *sdio_ctx; + struct notifier_block pm_notifier; +}; + +/* PM notifier list head */ +static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = { + .sdio_ctx = NULL, +}; + +/* + * --------------------------------------------------------------------------- + * uf_sdio_mmc_register_pm_notifier + * uf_sdio_mmc_unregister_pm_notifier + * + * Register/unregister for power management events. A list is used to + * allow multiple card instances to be supported. + * + * Arguments: + * sdio_ctx - CSR SDIO context to associate PM notifier to + * + * Returns: + * Register function returns NULL on error + * --------------------------------------------------------------------------- + */ +static struct uf_sdio_mmc_pm_notifier * +uf_sdio_mmc_register_pm_notifier(CsrSdioFunction *sdio_ctx) +{ + /* Allocate notifier context for this card instance */ + struct uf_sdio_mmc_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_mmc_pm_notifier), GFP_KERNEL); + + if (notifier_ctx) + { + notifier_ctx->sdio_ctx = sdio_ctx; + notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event; + + list_add(¬ifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list); + + if (register_pm_notifier(¬ifier_ctx->pm_notifier)) { + printk(KERN_ERR "unifi: register_pm_notifier failed\n"); + } + } + + return notifier_ctx; +} + +static void +uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction *sdio_ctx) +{ + struct uf_sdio_mmc_pm_notifier *notifier_ctx; + struct list_head *node, *q; + + list_for_each_safe(node, q, &uf_sdio_mmc_pm_notifiers.list) { + notifier_ctx = list_entry(node, struct uf_sdio_mmc_pm_notifier, list); + + /* If it matches, unregister and free the notifier context */ + if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx) + { + if (unregister_pm_notifier(¬ifier_ctx->pm_notifier)) { + printk(KERN_ERR "unifi: unregister_pm_notifier failed\n"); + } + + /* Remove from list */ + notifier_ctx->sdio_ctx = NULL; + list_del(node); + kfree(notifier_ctx); + } + } +} + +/* + * --------------------------------------------------------------------------- + * uf_sdio_mmc_power_event + * + * Handler for power management events. + * + * We need to handle suspend/resume events while the userspace is unsuspended + * to allow the SME to run its suspend/resume state machines. + * + * Arguments: + * event event ID + * + * Returns: + * Status of the event handling + * --------------------------------------------------------------------------- + */ +static int +uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct uf_sdio_mmc_pm_notifier *notifier_ctx = container_of(this, + struct uf_sdio_mmc_pm_notifier, + pm_notifier); + + /* Call the CSR SDIO function driver's suspend/resume method + * while the userspace is unsuspended. + */ + switch (event) { + case PM_POST_HIBERNATION: + case PM_POST_SUSPEND: + printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ ); + if (sdio_func_drv && sdio_func_drv->resume) { + sdio_func_drv->resume(notifier_ctx->sdio_ctx); + } + break; + + case PM_HIBERNATION_PREPARE: + case PM_SUSPEND_PREPARE: + printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ ); + if (sdio_func_drv && sdio_func_drv->suspend) { + sdio_func_drv->suspend(notifier_ctx->sdio_ctx); + } + break; + } + return NOTIFY_DONE; +} +#endif /* CONFIG_PM */ +#endif /* 2.6.32 */ /* * --------------------------------------------------------------------------- @@ -925,6 +1082,10 @@ uf_glue_sdio_probe(struct sdio_func *func, sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE; } + if (func->card->host->caps & MMC_CAP_SD_HIGHSPEED) { + unifi_trace(NULL, UDBG1, "MMC_CAP_SD_HIGHSPEED is available\n"); + } + #ifdef MMC_QUIRK_LENIENT_FN0 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; #endif @@ -932,6 +1093,15 @@ uf_glue_sdio_probe(struct sdio_func *func, /* Pass context to the SDIO driver */ sdio_set_drvdata(func, sdio_ctx); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#ifdef CONFIG_PM + /* Register to get PM events */ + if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) { + unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__); + } +#endif +#endif + /* Register this device with the SDIO function driver */ /* Call the main UniFi driver inserted handler */ if (sdio_func_drv && sdio_func_drv->inserted) { @@ -942,6 +1112,12 @@ uf_glue_sdio_probe(struct sdio_func *func, /* We have finished, so release the SDIO driver */ sdio_release_host(func); +#ifdef ANDROID_BUILD + /* Take the wakelock */ + unifi_trace(NULL, UDBG1, "probe: take wake lock\n"); + wake_lock(&unifi_sdio_wake_lock); +#endif + func_exit(); return 0; } /* uf_glue_sdio_probe() */ @@ -980,6 +1156,13 @@ uf_glue_sdio_remove(struct sdio_func *func) sdio_func_drv->removed(sdio_ctx); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#ifdef CONFIG_PM + /* Unregister for PM events */ + uf_sdio_mmc_unregister_pm_notifier(sdio_ctx); +#endif +#endif + kfree(sdio_ctx); func_exit(); @@ -1006,7 +1189,7 @@ MODULE_DEVICE_TABLE(sdio, unifi_ids); * --------------------------------------------------------------------------- * uf_glue_sdio_suspend * - * Card suspend callback. + * Card suspend callback. The userspace will already be suspended. * * Arguments: * dev The struct device owned by the MMC driver @@ -1018,23 +1201,9 @@ MODULE_DEVICE_TABLE(sdio, unifi_ids); static int uf_glue_sdio_suspend(struct device *dev) { - struct sdio_func *func; - CsrSdioFunction *sdio_ctx; - func_enter(); - func = dev_to_sdio_func(dev); - WARN_ON(!func); - - sdio_ctx = sdio_get_drvdata(func); - WARN_ON(!sdio_ctx); - - unifi_trace(NULL, UDBG1, "System Suspend...\n"); - - /* Clean up the SDIO function driver */ - if (sdio_func_drv && sdio_func_drv->suspend) { - sdio_func_drv->suspend(sdio_ctx); - } + unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend"); func_exit(); return 0; @@ -1045,7 +1214,7 @@ uf_glue_sdio_suspend(struct device *dev) * --------------------------------------------------------------------------- * uf_glue_sdio_resume * - * Card resume callback. + * Card resume callback. The userspace will still be suspended. * * Arguments: * dev The struct device owned by the MMC driver @@ -1057,23 +1226,14 @@ uf_glue_sdio_suspend(struct device *dev) static int uf_glue_sdio_resume(struct device *dev) { - struct sdio_func *func; - CsrSdioFunction *sdio_ctx; - func_enter(); - func = dev_to_sdio_func(dev); - WARN_ON(!func); - - sdio_ctx = sdio_get_drvdata(func); - WARN_ON(!sdio_ctx); + unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume"); - unifi_trace(NULL, UDBG1, "System Resume...\n"); - - /* Clean up the SDIO function driver */ - if (sdio_func_drv && sdio_func_drv->resume) { - sdio_func_drv->resume(sdio_ctx); - } +#ifdef ANDROID_BUILD + unifi_trace(NULL, UDBG1, "resume: take wakelock\n"); + wake_lock(&unifi_sdio_wake_lock); +#endif func_exit(); return 0; @@ -1133,6 +1293,10 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv) return CSR_SDIO_RESULT_INVALID_VALUE; } +#ifdef ANDROID_BUILD + wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work"); +#endif + /* Save the registered driver description */ /* * FIXME: @@ -1141,6 +1305,13 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv) */ sdio_func_drv = sdio_drv; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#ifdef CONFIG_PM + /* Initialise PM notifier list */ + INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list); +#endif +#endif + /* Register ourself with mmc_core */ r = sdio_register_driver(&unifi_driver); if (r) { @@ -1157,6 +1328,10 @@ void CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv) { printk(KERN_INFO "UniFi: unregister from MMC sdio\n"); + +#ifdef ANDROID_BUILD + wake_lock_destroy(&unifi_sdio_wake_lock); +#endif sdio_unregister_driver(&unifi_driver); sdio_func_drv = NULL; diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c index f30eda950ad6..8461baca2dea 100644 --- a/drivers/staging/csr/sme_blocking.c +++ b/drivers/staging/csr/sme_blocking.c @@ -92,11 +92,15 @@ sme_init_request(unifi_priv_t *priv) return -EIO; } + unifi_trace(priv, UDBG5, "sme_init_request: wait sem\n"); + /* Grab the SME semaphore until the reply comes, or timeout */ if (down_interruptible(&priv->sme_sem)) { unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n"); return -EIO; } + unifi_trace(priv, UDBG5, "sme_init_request: got sem: pending\n"); + priv->sme_reply.request_status = SME_REQUEST_PENDING; return 0; @@ -118,6 +122,10 @@ uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char * (func ? func : ""), priv->sme_reply.request_status); return; } + unifi_trace(priv, UDBG5, + "sme_complete_request: completed %s (s:%d)\n", + (func ? func : ""), priv->sme_reply.request_status); + priv->sme_reply.request_status = SME_REQUEST_RECEIVED; priv->sme_reply.reply_status = reply_status; @@ -127,23 +135,66 @@ uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char * } +void +uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status) +{ + /* Check for a blocking SME request in progress, and cancel the wait. + * This should be used when the character device is closed. + */ + + if (priv == NULL) { + unifi_error(priv, "sme_cancel_request: Invalid priv\n"); + return; + } + + /* If no request is pending, nothing to wake up */ + if (priv->sme_reply.request_status != SME_REQUEST_PENDING) { + unifi_trace(priv, UDBG5, + "sme_cancel_request: no request was pending (s:%d)\n", + priv->sme_reply.request_status); + /* Nothing to do */ + return; + } + unifi_trace(priv, UDBG5, + "sme_cancel_request: request cancelled (s:%d)\n", + priv->sme_reply.request_status); + + /* Wake up the wait with an error status */ + priv->sme_reply.request_status = SME_REQUEST_CANCELLED; + priv->sme_reply.reply_status = reply_status; /* unimportant since the CANCELLED state will fail the ioctl */ + + wake_up_interruptible(&priv->sme_request_wq); + + return; +} + + static int _sme_wait_for_reply(unifi_priv_t *priv, unsigned long timeout, const char *func) { long r; - unifi_trace(priv, UDBG5, "sme_wait_for_reply: sleep\n"); + unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s sleep\n", func ? func : ""); r = wait_event_interruptible_timeout(priv->sme_request_wq, (priv->sme_reply.request_status != SME_REQUEST_PENDING), msecs_to_jiffies(timeout)); - unifi_trace(priv, UDBG5, "sme_wait_for_reply: awake\n"); + unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s awake (%d)\n", func ? func : "", r); if (r == -ERESTARTSYS) { /* The thread was killed */ + unifi_info(priv, "ERESTARTSYS in _sme_wait_for_reply\n"); up(&priv->sme_sem); return r; } + if (priv->sme_reply.request_status == SME_REQUEST_CANCELLED) { + unifi_trace(priv, UDBG5, "Cancelled waiting for SME to reply (%s s:%d, t:%d, r:%d)\n", + (func ? func : ""), priv->sme_reply.request_status, timeout, r); + + /* Release the SME semaphore that was downed in sme_init_request() */ + up(&priv->sme_sem); + return -EIO; /* fail the ioctl */ + } if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) { unifi_notice(priv, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n", (func ? func : ""), priv->sme_reply.request_status, timeout); @@ -156,6 +207,9 @@ _sme_wait_for_reply(unifi_priv_t *priv, return -ETIMEDOUT; } + unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s received (%d)\n", + func ? func : "", r); + /* Release the SME semaphore that was downed in sme_init_request() */ up(&priv->sme_sem); @@ -1289,22 +1343,20 @@ int sme_sys_suspend(unifi_priv_t *priv) return -EIO; } - /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */ - priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; - - /* Suspend the SME, which will cause it to power down UniFi */ + /* Suspend the SME, which MAY cause it to power down UniFi */ CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend); r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); if (r) { /* No reply - forcibly power down in case the request wasn't processed */ unifi_notice(priv, "suspend: SME did not reply %s, ", - priv->ptest_mode ? "leave powered" : "power off UniFi anyway\n"); + (priv->ptest_mode | priv->wol_suspend) ? "leave powered" : "power off UniFi anyway\n"); /* Leave power on for production test, though */ if (!priv->ptest_mode) { /* Put UniFi to deep sleep, in case we can not power it off */ CsrSdioClaim(priv->sdio); + unifi_trace(priv, UDBG1, "Force deep sleep"); csrResult = unifi_force_low_power_mode(priv->card); /* For WOL, the UniFi must stay powered */ @@ -1319,13 +1371,40 @@ int sme_sys_suspend(unifi_priv_t *priv) if (priv->wol_suspend) { unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n"); - /* For PIO WOL, disable SDIO interrupt to enable PIO mode in the f/w */ - if (enable_wol == UNIFI_WOL_PIO) { - unifi_trace(priv, UDBG1, "Remove IRQ to enable PIO WOL\n"); - if (csr_sdio_linux_remove_irq(priv->sdio)) { - unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n"); + /* Remove the IRQ, which also disables the card SDIO interrupt. + * Disabling the card SDIO interrupt enables the PIO WOL source. + * Removal of the of the handler ensures that in both SDIO and PIO cases + * the card interrupt only wakes the host. The card will be polled + * after resume to handle any pending data. + */ + if (csr_sdio_linux_remove_irq(priv->sdio)) { + unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n"); + } + + if (enable_wol == UNIFI_WOL_SDIO) { + /* Because csr_sdio_linux_remove_irq() disabled the card SDIO interrupt, + * it must be left enabled to wake-on-SDIO. + */ + unifi_trace(priv, UDBG1, "Enable card SDIO interrupt for SDIO WOL\n"); + + CsrSdioClaim(priv->sdio); + csrResult = CsrSdioInterruptEnable(priv->sdio); + CsrSdioRelease(priv->sdio); + + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(priv, "WOL CsrSdioInterruptEnable failed %d\n", csrResult); } + } else { + unifi_trace(priv, UDBG1, "Disabled card SDIO interrupt for PIO WOL\n"); } + + /* Prevent the BH thread from running during the suspend. + * Upon resume, sme_sys_resume() will trigger a wifi-on, this will cause + * the BH thread to be re-enabled and reinstall the ISR. + */ + priv->bh_thread.block_thread = 1; + + unifi_trace(priv, UDBG1, "unifi_suspend: suspended BH"); } /* Consider UniFi to be uninitialised */ @@ -1354,22 +1433,10 @@ int sme_sys_resume(unifi_priv_t *priv) CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend); - if (priv->ptest_mode == 1) { - r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); - if (r) { - /* No reply - forcibly power down in case the request wasn't processed */ - unifi_notice(priv, - "resume: SME did not reply, return success anyway\n"); - } - } else { - - /* - * We are not going to wait for the reply because the SME might be in - * the userspace. In this case the event will reach it when the kernel - * resumes. So, release now the SME semaphore that was downed in - * sme_init_request(). - */ - up(&priv->sme_sem); + r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); + if (r) { + unifi_notice(priv, + "resume: SME did not reply, return success anyway\n"); } return 0; diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index f5760444bfea..da12807434b4 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -20,6 +20,8 @@ #ifdef CSR_SUPPORT_WEXT_AP #include "sme_csr/csr_wifi_sme_sef.h" #endif + + /* * This file implements the SME SYS API and contains the following functions: * CsrWifiRouterCtrlMediaStatusReqHandler() @@ -40,8 +42,10 @@ * CsrWifiRouterCtrlTclasDelReqHandler() * CsrWifiRouterCtrlSetModeReqHandler() * CsrWifiRouterCtrlWapiMulticastFilterReqHandler() - * CsrWifiRouterCtrlWapiMulticastReqHandler() * CsrWifiRouterCtrlWapiUnicastFilterReqHandler() + * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler() + * CsrWifiRouterCtrlWapiRxPktReqHandler() + * CsrWifiRouterCtrlWapiFilterReqHandler() */ #ifdef CSR_SUPPORT_SME @@ -731,10 +735,31 @@ void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) if (priv == NULL) { return; } - for (i=0; iinterfacePriv[i]->interfaceMode = 0; + if( priv->wol_suspend ) { + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n"); + } else { +#ifdef ANDROID_BUILD + /* Take the wakelock while Wi-Fi On is in progress */ + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n"); + wake_lock(&unifi_sdio_wake_lock); +#endif + for (i=0; iinterfacePriv[i]->interfaceMode = 0; + } + } + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data); + + if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1) + { + priv->cmanrTestMode = TRUE; + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode); + } + else + { + priv->cmanrTestMode = FALSE; } - unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X)\n", msg->source); /* * The request to initialise UniFi might come while UniFi is running. @@ -747,11 +772,16 @@ void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) /* Update the wifi_on state */ priv->wifi_on_state = wifi_on_in_progress; - r = uf_request_firmware_files(priv, UNIFI_FW_STA); - if (r) { - unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n"); - CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); - return; + /* If UniFi was unpowered, acquire the firmware for download to chip */ + if (!priv->wol_suspend) { + r = uf_request_firmware_files(priv, UNIFI_FW_STA); + if (r) { + unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n"); + CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); + return; + } + } else { + unifi_trace(priv, UDBG1, "Don't need firmware\n"); } /* Power on UniFi (which may not necessarily have been off) */ @@ -832,6 +862,13 @@ wifi_off(unifi_priv_t *priv) int i; CsrResult csrResult; + + /* Already off? */ + if (priv->wifi_on_state == wifi_on_unspecified) { + unifi_trace(priv, UDBG1, "wifi_off already\n"); + return; + } + unifi_trace(priv, UDBG1, "wifi_off\n"); /* Destroy the Traffic Analysis Module */ @@ -840,6 +877,7 @@ wifi_off(unifi_priv_t *priv) cancel_work_sync(&priv->ta_sample_ind_work.task); #ifdef CSR_SUPPORT_WEXT cancel_work_sync(&priv->sme_config_task); + wext_send_disassoc_event(priv); #endif /* Cancel pending M4 stuff */ @@ -908,9 +946,6 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) unifi_priv_t *priv = (unifi_priv_t*)drvpriv; CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg; int i = 0; -#ifdef CSR_SUPPORT_WEXT_AP - CsrWifiSmeWifiOffCfm cfm; -#endif if (priv == NULL) { return; @@ -924,6 +959,7 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) if (interfacePriv->netdev_registered == 1) { netif_carrier_off(priv->netdev[i]); UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]); + interfacePriv->connected = UnifiConnectedUnknown; } interfacePriv->interfaceMode = 0; @@ -936,15 +972,11 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) wifi_off(priv); CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData); -#ifdef CSR_SUPPORT_WEXT_AP - /* Router is turned off when WifiOffCfm is received - * hence for wext we don't see WifiOffCfm in the wext - * files. So just tell the waiting process that - * Wifi off is successful + + /* If this is called in response to closing the character device, the + * caller must use uf_sme_cancel_request() to terminate any pending SME + * blocking request or there will be a delay while the operation times out. */ - cfm.status = CSR_RESULT_SUCCESS; - CsrWifiSmeWifiOffCfmHandler(priv,(CsrWifiFsmEvent*)(&cfm)); -#endif } @@ -1065,7 +1097,9 @@ void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg) { int i; /* used as a loop counter */ CsrUint32 intmode = CSR_WIFI_INTMODE_DEFAULT; - +#ifdef CSR_WIFI_SPLIT_PATCH + CsrBool switching_ap_fw = FALSE; +#endif /* Register the UniFi device with the OS network manager */ unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n"); @@ -1099,6 +1133,16 @@ void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg) return; } } +#ifdef CSR_WIFI_SPLIT_PATCH + else + { + /* If a netdev is already registered, we have received this WifiOnRes + * in response to switching AP/STA firmware in a ModeSetReq. + * Rememeber this in order to send a ModeSetCfm once + */ + switching_ap_fw = TRUE; + } +#endif } priv->totalInterfaceCount = res->numInterfaceAddress; @@ -1117,8 +1161,27 @@ void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg) /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */ CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS); +#ifdef CSR_WIFI_SPLIT_PATCH + if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) { + unifi_info(priv, "Completed firmware reload with %s patch\n", + CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA"); + + /* Confirm the ModeSetReq that requested the AP/STA patch switch */ + CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source, + priv->pending_mode_set.clientData, + priv->pending_mode_set.interfaceTag, + priv->pending_mode_set.mode, + CSR_RESULT_SUCCESS); + priv->pending_mode_set.common.destination = 0xaaaa; + } +#endif unifi_info(priv, "UniFi ready\n"); +#ifdef ANDROID_BUILD + /* Release the wakelock */ + unifi_trace(priv, UDBG1, "ready: release wake lock\n"); + wake_unlock(&unifi_sdio_wake_lock); +#endif /* Firmware initialisation is complete, so let the SDIO bus * clock be raised when convienent to the core. */ @@ -1257,15 +1320,7 @@ void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg) return; } - /* - * Unless we are in ptest mode, nothing is waiting for the response. - * Do not call sme_complete_request(), otherwise the driver - * and the SME will be out of step. - */ - if (priv->ptest_mode == 1) { - sme_complete_request(priv, res->status); - } - + sme_complete_request(priv, res->status); } @@ -1709,7 +1764,6 @@ void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, CsrUint16 interfaceTag) &(interfacePriv->genericMulticastOrBroadCastFrames)); uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames)); - uf_flush_maPktlist(priv,&(interfacePriv->directedMaPktReq)); /* process the list of frames that requested cfm and send cfm to requestor one by one */ @@ -1747,21 +1801,93 @@ void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES) { netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; - +#ifdef CSR_WIFI_SPLIT_PATCH + CsrUint8 old_mode = interfacePriv->interfaceMode; +#endif unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n", interfacePriv->interfaceMode); - /* Cleanup the database first for current existing mode, Then take - * care of setting the new mode (Transition seq: AnyMode->NoneMode->newMode) - * So for Every mode changes, Database Initialization/cleanup needed + interfacePriv->interfaceMode = req->mode; + +#ifdef CSR_WIFI_SPLIT_PATCH + /* Detect a change in mode that requires a switch to/from the AP firmware patch. + * This should only happen when transitioning in/out of AP modes. */ - CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag); + if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode)) + { + CsrWifiRouterCtrlVersions versions; + int r; + +#ifdef ANDROID_BUILD + /* Take the wakelock while switching patch */ + unifi_trace(priv, UDBG1, "patch switch: take wake lock\n"); + wake_lock(&unifi_sdio_wake_lock); +#endif + unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA"); + + r = uf_request_firmware_files(priv, UNIFI_FW_STA); + if (r) { + unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n"); + CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag, + req->mode, CSR_RESULT_FAILURE); + return; + } + + /* Block the I/O thread */ + priv->bh_thread.block_thread = 1; + + /* Reset and download the new patch */ + r = uf_init_hw(priv); + if (r) { + unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r); + CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag, + req->mode, CSR_RESULT_FAILURE); + return; + } + + /* Re-enable the I/O thread */ + priv->bh_thread.block_thread = 0; + + /* Get the version information from the core */ + unifi_card_info(priv->card, &priv->card_info); + + /* Copy to the unifiio_card_info structure. */ + versions.chipId = priv->card_info.chip_id; + versions.chipVersion = priv->card_info.chip_version; + versions.firmwareBuild = priv->card_info.fw_build; + versions.firmwareHip = priv->card_info.fw_hip_version; + versions.routerBuild = (CsrCharString*)CSR_WIFI_VERSION; + versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION; + + /* Now that new firmware is running, send a WifiOnInd to the NME. This will + * cause it to retransfer the MIB. + */ + CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions); + + /* Store the request so we know where to send the ModeSetCfm */ + priv->pending_mode_set = *req; + } + else +#endif + { + /* No patch switch, confirm straightaway */ + CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag, + req->mode, CSR_RESULT_SUCCESS); + } - interfacePriv->interfaceMode = req->mode; interfacePriv->bssid = req->bssid; /* For modes other than AP/P2PGO, set below member FALSE */ interfacePriv->intraBssEnabled = FALSE; - + /* Initialise the variable bcTimSet with a value + * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value + */ + interfacePriv->bcTimSet = 0xFF; + interfacePriv->bcTimSetReqPendingFlag = FALSE; + /* Initialise the variable bcTimSetReqQueued with a value + * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value + */ + interfacePriv->bcTimSetReqQueued =0xFF; + CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag); if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP || req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { @@ -1797,8 +1923,6 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r unifi_port_config_t *controlledPort; unifi_port_config_t *unControlledPort; netInterface_priv_t *interfacePriv; - maPktReqList_t *maPktreq; - struct list_head *listHeadMaPktreq,*placeHolderMaPktreq; CsrUint8 ba_session_idx = 0; ba_session_rx_struct *ba_session_rx = NULL; @@ -1832,21 +1956,6 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r uf_flush_list(priv,&(staInfo->dataPdu[j])); } - /* There may be race condition - before getting the ma_packet_cfm from f/w, driver may receive peer del from SME - */ - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) { - maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q); - if(maPktreq->staHandler== staInfo->assignedHandle){ - dev_kfree_skb(maPktreq->skb); - list_del(listHeadMaPktreq); - kfree(maPktreq); - } - - } - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); /* clear the port configure array info, for the corresponding peer entry */ controlledPort = &interfacePriv->controlled_data_port; @@ -1885,7 +1994,7 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r /* Stop BA session if it is active, for this peer address all BA sessions (per tID per role) are closed */ - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx]; if(ba_session_rx) { @@ -1912,7 +2021,7 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r } } - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); #ifdef CSR_SUPPORT_SME unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid); @@ -2134,8 +2243,16 @@ static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *r newRecord->txSuspend = FALSE; /*U-APSD related data structure*/ + newRecord->timRequestPendingFlag = FALSE; + + /* Initialise the variable updateTimReqQueued with a value + * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value + */ + newRecord->updateTimReqQueued = 0xFF; + newRecord->timSet = CSR_WIFI_TIM_RESET; newRecord->uapsdActive = FALSE; newRecord->noOfSpFramesSent =0; + newRecord->triggerFramePriority = CSR_QOS_UP0; /* The protection bit is updated once the port opens for corresponding peer in * routerPortConfigure request */ @@ -2602,13 +2719,13 @@ void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__); - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); r = blockack_session_stop(priv, req->interfaceTag, req->role, req->trafficStreamID, req->macAddress); - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source, req->clientData, @@ -2746,6 +2863,16 @@ CsrBool blockack_session_start(unifi_priv_t *priv, init_timer(&ba_session_rx->timer); mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024))); } + /* + * The starting sequence number shall remain same if the BA + * enable request is issued to update BA parameters only. If + * it is not same, then we scroll our window to the new starting + * sequence number. This could happen if the DELBA frame from + * originator is lost and then we receive ADDBA frame with new SSN. + */ + if(ba_session_rx->start_sn != start_sn) { + scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn); + } return TRUE; } } @@ -2768,6 +2895,21 @@ CsrBool blockack_session_start(unifi_priv_t *priv, return FALSE; } + /* It is observed that with some devices there is a race between + * EAPOL exchanges and BA session establishment. This results in + * some EAPOL authentication packets getting stuck in BA reorder + * buffer and hence the conection cannot be established. To avoid + * this we check here if the EAPOL authentication is complete and + * if so then only allow the BA session to establish. + * + * It is verified that the peers normally re-establish + * the BA session after the initial rejection. + */ + if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag)) + { + unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n"); + return FALSE; + } ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL); if (!ba_session_rx) { @@ -2814,7 +2956,7 @@ void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* m unifi_priv_t *priv = (unifi_priv_t*)drvpriv; unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); r = blockack_session_start(priv, req->interfaceTag, req->trafficStreamID, @@ -2824,7 +2966,7 @@ void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* m req->ssn, req->macAddress ); - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source, req->clientData, @@ -2836,115 +2978,291 @@ void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* m void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) { +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; - unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); - unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status); + if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) { + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status); + + /* status 1 - Filter on + * status 0 - Filter off */ + priv->wapi_multicast_filter = req->status; + + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); + } else { - /* status 1 - Filter on - * status 0 - Filter off */ - priv->wapi_multicast_filter = req->status; + unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode); - unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); + } +#elif defined(UNIFI_DEBUG) + /*WAPI Disabled*/ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n"); +#endif } void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) { +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; - unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); - unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status); + if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) { - if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) { - /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */ - priv->wapi_unicast_queued_pkt_filter = 1; - } + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); - /* status 1 - Filter ON - * status 0 - Filter OFF */ - priv->wapi_unicast_filter = req->status; + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status); - unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); -} + if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) { + /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */ + priv->wapi_unicast_queued_pkt_filter = 1; + } + /* status 1 - Filter ON + * status 0 - Filter OFF */ + priv->wapi_unicast_filter = req->status; -void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) -{ + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); + } else { + + unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode); + + } +#elif defined(UNIFI_DEBUG) + /*WAPI Disabled*/ unifi_priv_t *priv = (unifi_priv_t*)drvpriv; - CsrWifiRouterCtrlWapiMulticastReq* req = (CsrWifiRouterCtrlWapiMulticastReq*)msg; + unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n"); +#endif +} + +void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWapiRxPktReq* req = (CsrWifiRouterCtrlWapiRxPktReq*)msg; int client_id, receiver_id; bulk_data_param_t bulkdata; CsrResult res; ul_client_t *client; - CSR_SIGNAL signal; CSR_MA_PACKET_INDICATION *pkt_ind; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; - unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); - unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlWapiMulticastReqHandler: \n"); + if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) { - if (priv == NULL) { - unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid priv\n",__FUNCTION__); - return; - } + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); - if (priv->smepriv == NULL) { - unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid sme priv\n",__FUNCTION__); - return; - } + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n",__FUNCTION__); + return; + } - if (req->dataLength == 0 || req->data == NULL) { - unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: invalid request\n",__FUNCTION__); - return; - } + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n",__FUNCTION__); + return; + } - res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength); - if (res != CSR_RESULT_SUCCESS) { - unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: Could not allocate net data\n",__FUNCTION__); - return; - } + if (req->dataLength == 0 || req->data == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__); + return; + } - /* This function is expected to be called only when the MIC has been verified by SME to be correct - * So reset the reception status to rx_success */ - res = read_unpack_signal(req->signal, &signal); - if (res) { - unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Received unknown or corrupted signal.\n"); - return; - } - pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication); - if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) { - unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus); - return; - } - else { - unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiMulticastReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__); - pkt_ind->ReceptionStatus = CSR_RX_SUCCESS; - write_pack(&signal, req->signal, &(req->signalLength)); + res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength); + if (res != CSR_RESULT_SUCCESS) { + unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__); + return; + } + + /* This function is expected to be called only when the MIC has been verified by SME to be correct + * So reset the reception status to rx_success */ + res = read_unpack_signal(req->signal, &signal); + if (res) { + unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n"); + return; + } + pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication); + if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) { + unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus); + return; + } else { + unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__); + pkt_ind->ReceptionStatus = CSR_RX_SUCCESS; + write_pack(&signal, req->signal, &(req->signalLength)); + } + + memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength); + + receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0; + client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; + + client = &priv->ul_clients[client_id]; + + if (client && client->event_hook) { + unifi_trace(priv, UDBG3, + "CsrWifiRouterCtrlWapiRxPktReq: " + "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n", + client->client_id, client->sender_id, receiver_id, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal)); + + client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST); + } else { + unifi_trace(priv, UDBG4, "No client to give the packet to\n"); + unifi_net_data_free(priv, &bulkdata.d[0]); + } + + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); + } else { + unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode); } +#elif defined(UNIFI_DEBUG) + /*WAPI Disabled*/ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n"); +#endif +} - memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength); +void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) - receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0; - client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; + unifi_priv_t *priv = (unifi_priv_t*) drvpriv; + CsrWifiRouterCtrlWapiUnicastTxPktReq *req = (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + bulk_data_param_t bulkdata; + CsrUint8 macHeaderLengthInBytes = MAC_HEADER_SIZE; + /*KeyID, Reserved, PN, MIC*/ + CsrUint8 appendedCryptoFields = 1 + 1 + 16 + 16; + CsrResult result; + /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */ + CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest; - client = &priv->ul_clients[client_id]; + if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) { + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + + if (priv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__); + return; + } + if (priv->smepriv == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__); + return; + } + if (req->data == NULL) { + unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__); + return; + } else { + /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */ + if ((req->data[0] & 0x88) == 0x88) { + macHeaderLengthInBytes = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE; + } + } + if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) { + unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__); + return; + } + + /* Encrypted DATA Packet contained in (req->data) + * ------------------------------------------------------------------- + * |MAC Header| KeyId | Reserved | PN | xxDataxx | xxMICxxx | + * ------------------------------------------------------------------- + * (<-----Encrypted----->) + * ------------------------------------------------------------------- + * |24/26(QoS)| 1 | 1 | 16 | x | 16 | + * ------------------------------------------------------------------- + */ + result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength); + if (result != CSR_RESULT_SUCCESS) { + unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__); + return; + } + memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength); + bulkdata.d[0].data_length = req->dataLength; + bulkdata.d[1].os_data_ptr = NULL; + bulkdata.d[1].data_length = 0; + + /* Send UniFi msg */ + /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */ + result = uf_process_ma_packet_req(priv, + storedSignalMAPktReq->Ra.x, + storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */ + req->interfaceTag, + storedSignalMAPktReq->TransmissionControl, + storedSignalMAPktReq->TransmitRate, + storedSignalMAPktReq->Priority, /* Retained value */ + interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/ + &bulkdata); + + if (result == NETDEV_TX_OK) { + (priv->netdev[req->interfaceTag])->trans_start = jiffies; + /* Should really count tx stats in the UNITDATA.status signal but + * that doesn't have the length. + */ + interfacePriv->stats.tx_packets++; + + /* count only the packet payload */ + interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields; + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets); + } else { + /* Failed to send: fh queue was full, and the skb was discarded*/ + unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result); + unifi_net_data_free(priv, &bulkdata.d[0]); + + interfacePriv->stats.tx_dropped++; + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped); + } - if (client && client->event_hook) { - unifi_trace(priv, UDBG3, - "CsrWifiRouterCtrlWapiMulticastReqHandler: " - "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n", - client->client_id, client->sender_id, receiver_id, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal)); + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); + + } else { + + unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode); - client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST); } - else { - unifi_trace(priv, UDBG4, "No client to give the packet to\n"); - unifi_net_data_free(priv, &bulkdata.d[0]); +#elif defined(UNIFI_DEBUG) + /*WAPI Disabled*/ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n"); +#endif +} + +void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) +{ +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + +#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg; + netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; + + if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) { + + unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); + + unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected); + + priv->isWapiConnection = req->isWapiConnected; + + unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); + } else { + + unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode); + } +#endif - unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); +#elif defined(UNIFI_DEBUG) + /*WAPI Disabled*/ + unifi_priv_t *priv = (unifi_priv_t*)drvpriv; + unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n"); +#endif } diff --git a/drivers/staging/csr/sme_userspace.c b/drivers/staging/csr/sme_userspace.c index 38df94b69e9f..d87a6e304ff2 100644 --- a/drivers/staging/csr/sme_userspace.c +++ b/drivers/staging/csr/sme_userspace.c @@ -101,7 +101,6 @@ uf_sme_init(unifi_priv_t *priv) INIT_LIST_HEAD(&interfacePriv->genericMgtFrames); INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastMgtFrames); INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastFrames); - INIT_LIST_HEAD(&interfacePriv->directedMaPktReq); for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) { interfacePriv->staInfo[j] = NULL; @@ -139,7 +138,7 @@ uf_sme_deinit(unifi_priv_t *priv) /* Remove all the Peer database, before going down */ for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { - spin_lock(&priv->ba_lock); + down(&priv->ba_mutex); for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ ba_session_rx = priv->interfacePriv[i]->ba_session_rx[ba_session_idx]; if(ba_session_rx) { @@ -161,7 +160,7 @@ uf_sme_deinit(unifi_priv_t *priv) } } - spin_unlock(&priv->ba_lock); + up(&priv->ba_mutex); interfacePriv = priv->interfacePriv[i]; if(interfacePriv){ for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) { diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index 384ccd46982e..3ba7b4cef2dd 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -29,8 +29,10 @@ } \ } while (0) -/* Workaround for the wpa_supplicant hanging issue */ +/* Workaround for the wpa_supplicant hanging issue - disabled on Android */ +#ifndef ANDROID_BUILD #define CSR_WIFI_WEXT_HANG_WORKAROUND +#endif #ifdef CSR_WIFI_WEXT_HANG_WORKAROUND # define UF_RTNL_LOCK() rtnl_lock() diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c index ae14f2354362..958b8a1a9eb3 100644 --- a/drivers/staging/csr/ul_int.c +++ b/drivers/staging/csr/ul_int.c @@ -265,7 +265,9 @@ ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len) /* wifi_off_ind (error or exit) */ CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, (CsrWifiRouterCtrlControlIndication)(*conf_param)); } - +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE + unifi_debug_buf_dump(); +#endif #else bulk_data_param_t bulkdata; @@ -420,10 +422,6 @@ ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr, CsrResult csrResult; unsigned long lock_flags; int r; -#ifdef CSR_SUPPORT_SME - netInterface_priv_t *interfacePriv = priv->interfacePriv[0]; - CsrUint32 alignOffset = 0; -#endif csrResult = write_pack(sigptr, sigbuf, &packed_siglen); @@ -431,12 +429,6 @@ ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr, unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n"); return CsrHipResultToStatus(csrResult); } -#ifdef CSR_SUPPORT_SME - if (bulkdata != NULL){ - alignOffset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1); - - } -#endif r = _align_bulk_data_buffers(priv, sigbuf, (bulk_data_param_t*)bulkdata); if (r) { return r; @@ -449,17 +441,6 @@ ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr, spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); return CsrHipResultToStatus(csrResult); } -#ifdef CSR_SUPPORT_SME - if (sigptr->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID) { - if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || - interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { - - uf_store_directed_ma_packet_referenece(priv, bulkdata, sigptr,alignOffset); - - } - } -#endif - spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); return 0; diff --git a/drivers/staging/csr/unifi_event.c b/drivers/staging/csr/unifi_event.c index cfc5b32d4a66..8b5d4669e127 100644 --- a/drivers/staging/csr/unifi_event.c +++ b/drivers/staging/csr/unifi_event.c @@ -109,7 +109,11 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv, static const CsrUint8 wapiProtocolIdSNAPHeaderOffset = 6; CsrUint8 *destAddr; CsrUint8 *srcAddr; - CsrBool isUnicastPkt = FALSE; + CsrBool isWapiUnicastPkt = FALSE; + +#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND + CsrUint16 qosControl; +#endif CsrUint8 llcSnapHeaderOffset = 0; @@ -117,7 +121,7 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv, srcAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; /*Individual/Group bit - Bit 0 of first byte*/ - isUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE; + isWapiUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE; #endif #define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22 @@ -158,20 +162,54 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv, if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) { +#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND + if ((isDataFrame) && + ((IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK) == (frmCtrl & IEEE80211_FC_SUBTYPE_MASK)) && + (priv->isWapiConnection)) + { + qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation + (((frmCtrl & IEEE802_11_FC_TO_DS_MASK) && (frmCtrl & IEEE802_11_FC_FROM_DS_MASK)) ? 30 : 24) ); + + unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind() :: Value of the QoS control field - 0x%04x \n", qosControl); + + if (qosControl & IEEE802_11_QC_NON_TID_BITS_MASK) + { + unifi_trace(priv, UDBG4, "Ignore the MIC failure and pass the MPDU to the stack when any of bits [4-15] is set in the QoS control field\n"); + + /*Exclude the MIC [16] and the PN [16] that are appended by the firmware*/ + ((bulk_data_param_t*)bulkdata)->d[0].data_length = bulkdata->d[0].data_length - 32; + + /*Clear the reception status of the signal (CSR_RX_SUCCESS)*/ + *(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET) = 0x00; + *(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET+1) = 0x00; + + *freeBulkData = FALSE; + + return FALSE; + } + } +#endif /* If this MIC ERROR reported by the firmware is either for - * [1] a WAPI Multicast Packet and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying) OR - * [2] a WAPI Unicast Packet and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set + * [1] a WAPI Multicast MPDU and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying) OR + * [2] a WAPI Unicast MPDU and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set * then report a MIC FAILURE indication to the SME. */ - if ((priv->wapi_multicast_filter == 0) || isUnicastPkt) { - +#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION + if ((priv->wapi_multicast_filter == 0) || isWapiUnicastPkt) { +#else + /*When SW encryption is enabled and USKID=1 (wapi_unicast_filter = 1), we are expected + *to receive MIC failure INDs for unicast MPDUs*/ + if ( ((priv->wapi_multicast_filter == 0) && !isWapiUnicastPkt) || + ((priv->wapi_unicast_filter == 0) && isWapiUnicastPkt) ) { +#endif /*Discard the frame*/ *freeBulkData = TRUE; unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n"); - if (isUnicastPkt && + if (isWapiUnicastPkt && ((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)|| +#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION (priv->wapi_unicast_filter) || +#endif (priv->wapi_unicast_queued_pkt_filter))) { /* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP @@ -225,7 +263,8 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv, /* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before * starting to use the new key negotiated as part of unicast re-keying */ - if (isUnicastPkt && + if ((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA)&& + isWapiUnicastPkt && (receptionStatus == CSR_RX_SUCCESS) && (priv->wapi_unicast_queued_pkt_filter==1)) { @@ -297,16 +336,10 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv, return FALSE; } } -#ifdef CSR_WIFI_RX_PATH_SPLIT -static CsrBool signal_buffer_is_full(unifi_priv_t* priv) -{ - return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer)); -} -#endif /* * --------------------------------------------------------------------------- - * unifi_receive_event + * unifi_process_receive_event * * Dispatcher for received signals. * @@ -332,56 +365,11 @@ static CsrBool signal_buffer_is_full(unifi_priv_t* priv) * binded to the host interface specification. * --------------------------------------------------------------------------- */ - - -void -unifi_receive_event(void *ospriv, - CsrUint8 *sigdata, CsrUint32 siglen, - const bulk_data_param_t *bulkdata) +static void +unifi_process_receive_event(void *ospriv, + CsrUint8 *sigdata, CsrUint32 siglen, + const bulk_data_param_t *bulkdata) { -#ifdef CSR_WIFI_RX_PATH_SPLIT - unifi_priv_t *priv = (unifi_priv_t*)ospriv; - CsrUint8 writePointer; - int i; - rx_buff_struct_t * rx_buff; - func_enter(); - - unifi_trace(priv, UDBG5, "unifi_receive_event: " - "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); - if(signal_buffer_is_full(priv)) { - unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n"); - for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { - if (bulkdata->d[i].data_length != 0) { - unifi_net_data_free(priv, (void *)&bulkdata->d[i]); - } - } - return; - } - writePointer = priv->rxSignalBuffer.writePointer; - rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer]; - memcpy(rx_buff->bufptr,sigdata,siglen); - rx_buff->sig_len = siglen; - rx_buff->data_ptrs = *bulkdata; - writePointer++; - if(writePointer >= priv->rxSignalBuffer.size) { - writePointer =0; - } - unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer); - priv->rxSignalBuffer.writePointer = writePointer; - -#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ - queue_work(priv->rx_workqueue, &priv->rx_work_struct); -#endif - -#else unifi_priv_t *priv = (unifi_priv_t*)ospriv; int i, receiver_id; int client_id; @@ -390,16 +378,17 @@ unifi_receive_event(void *ospriv, func_enter(); - unifi_trace(priv, UDBG5, "unifi_receive_event: " - "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, - CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); + unifi_trace(priv, UDBG5, "unifi_process_receive_event: " + "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, + CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, + siglen); receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00; client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; @@ -410,18 +399,18 @@ unifi_receive_event(void *ospriv, /* check for the type of frame received (checks for 802.11 management frames) */ if (signal_id == CSR_MA_PACKET_INDICATION_ID) { +#define CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET 14 CsrUint8 interfaceTag; netInterface_priv_t *interfacePriv; /* Pull out interface tag from virtual interface identifier */ - interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff; + interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff; interfacePriv = priv->interfacePriv[interfaceTag]; /* Update activity for this station in case of IBSS */ #ifdef CSR_SUPPORT_SME - - if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) { - + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) + { CsrUint8 *saddr; /* Fetch the source address from mac header */ saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; @@ -436,6 +425,7 @@ unifi_receive_event(void *ospriv, pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv); unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO"); + } if (pktIndToSme) @@ -445,7 +435,7 @@ unifi_receive_event(void *ospriv, send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); } else{ - unifi_error(priv, "unifi_receive_event: sigdata or Bulkdata is NULL \n"); + unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n"); } #ifdef CSR_NATIVE_LINUX send_to_client(priv, priv->wext_client, @@ -459,67 +449,99 @@ unifi_receive_event(void *ospriv, * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs */ if (!receiver_id) { - if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) - { - uf_process_ma_vif_availibility_ind(priv, sigdata, siglen); - } - else if (signal_id != CSR_MA_PACKET_INDICATION_ID) - { - send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); + if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) { + uf_process_ma_vif_availibility_ind(priv, sigdata, siglen); + } + else if (signal_id != CSR_MA_PACKET_INDICATION_ID) { + send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); #ifdef CSR_NATIVE_LINUX - send_to_client(priv, priv->wext_client, - receiver_id, - sigdata, siglen, bulkdata); + send_to_client(priv, priv->wext_client, + receiver_id, + sigdata, siglen, bulkdata); #endif - } - }/*if (receiver_id==0) */ - -#ifdef CSR_SUPPORT_SME -#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE - /* Send a WAPI Multicast Indication to SME if the filter has been set - * and this is a multicast data packet - */ - if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) { - CSR_SIGNAL signal; - CsrUint8 *destAddr; - CsrResult res; - CsrUint16 interfaceTag = 0; - - /* Check if it is a multicast packet from the destination address in the MAC header */ - res = read_unpack_signal(sigdata, &signal); - destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; - if (res) { - unifi_error(priv, "Received unknown or corrupted signal.\n"); - return; - } - /*Individual/Group bit - Bit 0 of first byte*/ - if (destAddr[0] & 0x01) { - unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n"); - - CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr); - - for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { - if (bulkdata->d[i].data_length != 0) { - unifi_net_data_free(priv, (void *)&bulkdata->d[i]); - } - } - func_exit(); - return; - } - } + } + else + { + +#if (defined(CSR_SUPPORT_SME) && defined(CSR_WIFI_SECURITY_WAPI_ENABLE)) + #define CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22 + netInterface_priv_t *interfacePriv; + CsrUint8 interfaceTag; + CsrUint16 receptionStatus = CSR_RX_SUCCESS; + + /* Pull out interface tag from virtual interface identifier */ + interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff; + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* check for MIC failure */ + receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET); + + /* Send a WAPI MPDU to SME for re-check MIC if the respective filter has been set*/ + if ((!freeBulkData) && + (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) && + (receptionStatus == CSR_MICHAEL_MIC_ERROR) && + ((priv->wapi_multicast_filter == 1) +#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION + || (priv->wapi_unicast_filter == 1) #endif + )) + { + CSR_SIGNAL signal; + CsrUint8 *destAddr; + CsrResult res; + CsrUint16 interfaceTag = 0; + CsrBool isMcastPkt = TRUE; + + unifi_trace(priv, UDBG6, "Received a WAPI data packet when the Unicast/Multicast filter is set\n"); + res = read_unpack_signal(sigdata, &signal); + if (res) { + unifi_error(priv, "Received unknown or corrupted signal (0x%x).\n", + CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata)); + return; + } + + /* Check if the type of MPDU and the respective filter status*/ + destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; + isMcastPkt = (destAddr[0] & 0x01) ? TRUE : FALSE; + unifi_trace(priv, UDBG6, + "1.MPDU type: (%s), 2.Multicast filter: (%s), 3. Unicast filter: (%s)\n", + ((isMcastPkt) ? "Multiast":"Unicast"), + ((priv->wapi_multicast_filter) ? "Enabled":"Disabled"), + ((priv->wapi_unicast_filter) ? "Enabled":"Disabled")); + + if (((isMcastPkt) && (priv->wapi_multicast_filter == 1)) +#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION + || ((!isMcastPkt) && (priv->wapi_unicast_filter == 1)) #endif + ) + { + unifi_trace(priv, UDBG4, "Sending the WAPI MPDU for MIC check\n"); + CsrWifiRouterCtrlWapiRxMicCheckIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr); + + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } + } + func_exit(); + return; + } + } /* CSR_MA_PACKET_INDICATION_ID */ +#endif /*CSR_SUPPORT_SME && CSR_WIFI_SECURITY_WAPI_ENABLE*/ + } + } /* calls the registered clients handler callback func. * netdev_mlme_event_handler is one of the registered handler used to route * data packet to network stack or AMP/EAPOL related data to SME - */ - /* The freeBulkData check ensures that, it has received a management frame and + * + * The freeBulkData check ensures that, it has received a management frame and * the frame needs to be freed here. So not to be passed to netdev handler */ if(!freeBulkData){ if ((client_id < MAX_UDI_CLIENTS) && (&priv->ul_clients[client_id] != priv->logging_client)) { + unifi_trace(priv, UDBG6, "Call the registered clients handler callback func\n"); send_to_client(priv, &priv->ul_clients[client_id], receiver_id, sigdata, siglen, bulkdata); @@ -550,14 +572,54 @@ unifi_receive_event(void *ospriv, } } } -#endif + func_exit(); -} /* unifi_receive_event() */ +} /* unifi_process_receive_event() */ + #ifdef CSR_WIFI_RX_PATH_SPLIT +static CsrBool signal_buffer_is_full(unifi_priv_t* priv) +{ + return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer)); +} + +void unifi_rx_queue_flush(void *ospriv) +{ + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + + func_enter(); + unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", + priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer); + if(priv != NULL) { + CsrUint8 readPointer = priv->rxSignalBuffer.readPointer; + while (readPointer != priv->rxSignalBuffer.writePointer) + { + rx_buff_struct_t *buf = &priv->rxSignalBuffer.rx_buff[readPointer]; + unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", + readPointer,priv->rxSignalBuffer.writePointer); + unifi_process_receive_event(priv, buf->bufptr, buf->sig_len, &buf->data_ptrs); + readPointer ++; + if(readPointer >= priv->rxSignalBuffer.size) { + readPointer = 0; + } + } + priv->rxSignalBuffer.readPointer = readPointer; + } + func_exit(); +} + +void rx_wq_handler(struct work_struct *work) +{ + unifi_priv_t *priv = container_of(work, unifi_priv_t, rx_work_struct); + unifi_rx_queue_flush(priv); +} +#endif + + + /* * --------------------------------------------------------------------------- - * unifi_receive_event2 + * unifi_receive_event * * Dispatcher for received signals. * @@ -583,20 +645,19 @@ unifi_receive_event(void *ospriv, * binded to the host interface specification. * --------------------------------------------------------------------------- */ -static void -unifi_receive_event2(void *ospriv, - CsrUint8 *sigdata, CsrUint32 siglen, - const bulk_data_param_t *bulkdata) +void +unifi_receive_event(void *ospriv, + CsrUint8 *sigdata, CsrUint32 siglen, + const bulk_data_param_t *bulkdata) { +#ifdef CSR_WIFI_RX_PATH_SPLIT unifi_priv_t *priv = (unifi_priv_t*)ospriv; - int i, receiver_id; - int client_id; - CsrInt16 signal_id; - CsrBool pktIndToSme = FALSE, freeBulkData = FALSE; - + CsrUint8 writePointer; + int i; + rx_buff_struct_t * rx_buff; func_enter(); - unifi_trace(priv, UDBG5, "unifi_receive_event2: " + unifi_trace(priv, UDBG5, "unifi_receive_event: " "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, @@ -606,189 +667,34 @@ unifi_receive_event2(void *ospriv, CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); - - receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00; - client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; - signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata); - - - - /* check for the type of frame received (checks for 802.11 management frames) */ - if (signal_id == CSR_MA_PACKET_INDICATION_ID) - { - CsrUint8 interfaceTag; - netInterface_priv_t *interfacePriv; - - /* Pull out interface tag from virtual interface identifier */ - interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff; - interfacePriv = priv->interfacePriv[interfaceTag]; - - /* Update activity for this station in case of IBSS */ -#ifdef CSR_SUPPORT_SME - - if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) { - - CsrUint8 *saddr; - /* Fetch the source address from mac header */ - saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; - unifi_trace(priv, UDBG5, - "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n", - interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]); - - uf_update_sta_activity(priv, interfaceTag, saddr); + if(signal_buffer_is_full(priv)) { + unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n"); + for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { + if (bulkdata->d[i].data_length != 0) { + unifi_net_data_free(priv, (void *)&bulkdata->d[i]); + } } -#endif - - pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv); - - unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO"); - + return; } - - if (pktIndToSme) - { - /* Management MA_PACKET_IND for SME */ - if(sigdata != NULL && bulkdata != NULL){ - send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); - } - else{ - unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n"); - } -#ifdef CSR_NATIVE_LINUX - send_to_client(priv, priv->wext_client, - receiver_id, - sigdata, siglen, bulkdata); -#endif + writePointer = priv->rxSignalBuffer.writePointer; + rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer]; + memcpy(rx_buff->bufptr,sigdata,siglen); + rx_buff->sig_len = siglen; + rx_buff->data_ptrs = *bulkdata; + writePointer++; + if(writePointer >= priv->rxSignalBuffer.size) { + writePointer =0; } - else - { - /* Signals with ReceiverId==0 are also reported to SME / WEXT, - * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs - */ - if (!receiver_id) { - if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) - { - uf_process_ma_vif_availibility_ind(priv, sigdata, siglen); - } - else if (signal_id != CSR_MA_PACKET_INDICATION_ID) - { - send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); -#ifdef CSR_NATIVE_LINUX - send_to_client(priv, priv->wext_client, - receiver_id, - sigdata, siglen, bulkdata); -#endif - } - } - -#ifdef CSR_SUPPORT_SME -#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE - /* Send a WAPI Multicast Indication to SME if the filter has been set - * and this is a multicast data packet - */ - if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) { - CSR_SIGNAL signal; - CsrUint8 *destAddr; - CsrResult res; - CsrUint16 interfaceTag = 0; - - /* Check if it is a multicast packet from the destination address in the MAC header */ - res = read_unpack_signal(sigdata, &signal); - destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; - if (res) { - unifi_error(priv, "Received unknown or corrupted signal.\n"); - return; - } - /*Individual/Group bit - Bit 0 of first byte*/ - if (destAddr[0] & 0x01) { - unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n"); - - CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr); + unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer); + priv->rxSignalBuffer.writePointer = writePointer; - for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { - if (bulkdata->d[i].data_length != 0) { - unifi_net_data_free(priv, (void *)&bulkdata->d[i]); - } - } - func_exit(); - return; - } - } -#endif +#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ + queue_work(priv->rx_workqueue, &priv->rx_work_struct); #endif - /* calls the registered clients handler callback func. - * netdev_mlme_event_handler is one of the registered handler used to route - * data packet to network stack or AMP/EAPOL related data to SME - */ - /* The freeBulkData check ensures that, it has received a management frame and - * the frame needs to be freed here. So not to be passed to netdev handler - */ - if(!freeBulkData){ - if ((client_id < MAX_UDI_CLIENTS) && - (&priv->ul_clients[client_id] != priv->logging_client)) { - send_to_client(priv, &priv->ul_clients[client_id], - receiver_id, - sigdata, siglen, bulkdata); - } - } - } - - /* - * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION - */ - switch (signal_id) - { -#ifdef UNIFI_SNIFF_ARPHRD - case CSR_MA_SNIFFDATA_INDICATION_ID: +#else + unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata); #endif - break; - - case CSR_MA_PACKET_INDICATION_ID: - if (!freeBulkData) - { - break; - } - /* FALLS THROUGH... */ - default: - for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { - if (bulkdata->d[i].data_length != 0) { - unifi_net_data_free(priv, (void *)&bulkdata->d[i]); - } - } - } - func_exit(); -} /* unifi_receive_event2() */ - -void unifi_rx_queue_flush(void *ospriv) -{ - unifi_priv_t *priv = (unifi_priv_t*)ospriv; - - func_enter(); - unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", - priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer); - if(priv != NULL) { - CsrUint8 readPointer = priv->rxSignalBuffer.readPointer; - while(readPointer != priv->rxSignalBuffer.writePointer) { - rx_buff_struct_t * buf = &priv->rxSignalBuffer.rx_buff[readPointer]; - unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", - readPointer,priv->rxSignalBuffer.writePointer); - unifi_receive_event2(priv,buf->bufptr,buf->sig_len,&buf->data_ptrs); - readPointer ++; - if(readPointer >= priv->rxSignalBuffer.size) { - readPointer = 0; - } - } - priv->rxSignalBuffer.readPointer = readPointer; - } - func_exit(); -} - -void rx_wq_handler(struct work_struct *work) -{ - unifi_priv_t *priv = container_of(work,unifi_priv_t,rx_work_struct); - unifi_rx_queue_flush(priv); -} +} /* unifi_receive_event() */ -#endif diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h index 579c7e0544a3..0a9749450688 100644 --- a/drivers/staging/csr/unifi_os.h +++ b/drivers/staging/csr/unifi_os.h @@ -97,6 +97,13 @@ void dump16(void *mem, CsrUint16 len); void dump_str(void *mem, CsrUint16 len); #endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ +void unifi_error(void* ospriv, const char *fmt, ...); +void unifi_warning(void* ospriv, const char *fmt, ...); +void unifi_notice(void* ospriv, const char *fmt, ...); +void unifi_info(void* ospriv, const char *fmt, ...); + +void unifi_trace(void* ospriv, int level, const char *fmt, ...); + #else /* Stubs */ @@ -113,15 +120,16 @@ static inline void dump16(void *mem, CsrUint16 len) {} static inline void dump_str(void *mem, CsrUint16 len) {} #endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ -#endif /* UNIFI_DEBUG */ +void unifi_error_nop(void* ospriv, const char *fmt, ...); +void unifi_trace_nop(void* ospriv, int level, const char *fmt, ...); +#define unifi_error if(1);else unifi_error_nop +#define unifi_warning if(1);else unifi_error_nop +#define unifi_notice if(1);else unifi_error_nop +#define unifi_info if(1);else unifi_error_nop +#define unifi_trace if(1);else unifi_trace_nop +#endif /* UNIFI_DEBUG */ -void unifi_error(void* ospriv, const char *fmt, ...); -void unifi_warning(void* ospriv, const char *fmt, ...); -void unifi_notice(void* ospriv, const char *fmt, ...); -void unifi_info(void* ospriv, const char *fmt, ...); - -void unifi_trace(void* ospriv, int level, const char *fmt, ...); /* Different levels of diagnostic detail... */ #define UDBG0 0 /* always prints in debug build */ diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index 36b871e02c98..e35747c08317 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -32,22 +32,23 @@ static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata, tx_buffered_packets_t* buffered_pkt) { - struct sk_buff *skb ; CsrUint32 align_offset; if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){ return; } + skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; align_offset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1); if(align_offset){ skb_pull(skb,align_offset); } - buffered_pkt->bulkdata.os_data_ptr = skb->data; - buffered_pkt->bulkdata.data_length = skb->len; - + buffered_pkt->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr; + buffered_pkt->bulkdata.data_length = bulkdata->d[0].data_length; + buffered_pkt->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr; + buffered_pkt->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length; } #endif @@ -122,7 +123,7 @@ unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority, #ifdef CSR_SUPPORT_SME #define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001 -#define TRANSMISSION_CONTROL_ESOP_MASK 0x0002 +#define TRANSMISSION_CONTROL_EOSP_MASK 0x0002 static int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt, @@ -167,34 +168,27 @@ int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK: case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK: /* If both are set then the Address4 exists (only for AP) */ - if (fromDs && toDs) - { + if (fromDs && toDs) { /* 6 is the size of Address4 field */ macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6); - } - else - { + } else { macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE; } /* If order bit set then HT control field is the part of MAC header */ if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE; + qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6)); + } else { + qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2)); } + *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4)); break; default: if (fromDs && toDs) macHeaderLengthInBytes += 6; - break; - } - - if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { - qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6)); - } else { - qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2)); } - *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4)); } result = ul_send_signal_unpacked(priv, &signal, &bulkdata); if(result){ @@ -254,7 +248,7 @@ void set_eosp_transmit_ctrl(unifi_priv_t *priv, struct list_head *txList) spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_for_each_prev_safe(listHead, placeHolder, txList) { tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); - tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; + tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK; tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); unifi_trace(priv, UDBG1, "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag); @@ -275,6 +269,8 @@ void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RES bulk_data_param_t *bulkdata = NULL; int r; + unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : invoked with resultCode = %d \n", resultCode); + memset(&signal,0,sizeof(CSR_SIGNAL)); rsp = &signal.u.MaVifAvailabilityResponse; rsp->VirtualInterfaceIdentifier = vif; @@ -288,6 +284,9 @@ void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RES if(r) { unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r); } + else { + unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : status = %d \n", r); + } } #endif @@ -354,14 +353,14 @@ void verify_and_accomodate_tx_packet(unifi_priv_t *priv) list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) { tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); if(eospFramedeleted){ - tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; + tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK; tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag); eospFramedeleted =0; break; } - if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK ){ + if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK ){ eospFramedeleted = 1; } unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag); @@ -445,66 +444,162 @@ CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n"); return CSR_RESULT_SUCCESS; } -static -CsrResult enque_direceted_ma_pkt_cfm_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, - struct list_head *list, CSR_SIGNAL *signal, - CsrBool requeueOnSamePos) + +#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL +CsrResult unifi_reque_ma_packet_request (void *ospriv, CsrUint32 host_tag, + CsrUint16 txStatus, bulk_data_desc_t *bulkDataDesc) { + CsrResult status = CSR_RESULT_SUCCESS; + unifi_priv_t *priv = (unifi_priv_t*)ospriv; + netInterface_priv_t *interfacePriv; + struct list_head *list = NULL; + CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; + bulk_data_param_t bulkData; + CSR_SIGNAL signal; + CSR_PRIORITY priority = 0; + CsrUint16 interfaceTag = 0; + unifi_TrafficQueue priority_q; + CsrUint16 frameControl = 0, frameType = 0; + unsigned long lock_flags; - /* queue the tx data packets on to appropriate queue */ - CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest; - tx_buffered_packets_t *tx_q_item; + interfacePriv = priv->interfacePriv[interfaceTag]; + + /* If the current mode is not AP or P2PGO then just return failure + * to clear the hip slot + */ + if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) || + (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) { + return CSR_RESULT_FAILURE; + } + unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: host_tag = 0x%x\n", host_tag); - unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n"); - if(!list ) { - unifi_error(priv,"List is not specified\n"); - return CSR_RESULT_FAILURE; + staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, + (((CsrUint8 *) bulkDataDesc->os_data_ptr) + 4), + interfaceTag); + if (NULL == staRecord) { + unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid STA record \n"); + return CSR_RESULT_FAILURE; } - if(!requeueOnSamePos && !list->prev){ - unifi_error(priv,"List prev is NULL so don't requeu it\n"); - return CSR_RESULT_FAILURE; + /* Update TIM if MA-PACKET.cfm fails with status as Tx-retry-limit or No-BSS and then just return failure + * to clear the hip slot associated with the Packet + */ + if (CSR_TX_RETRY_LIMIT == txStatus || CSR_TX_NO_BSS == txStatus) { + if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) + { + unifi_trace(priv, UDBG2, "unifi_reque_ma_packet_request: CFM failed with Retry Limit or No BSS-->update TIM\n"); + if (!staRecord->timRequestPendingFlag) { + update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle); + } + else { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 1; + unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: One more UpdateTim Request(:%d)Queued for AID %x\n", + staRecord->updateTimReqQueued, staRecord->aid); + } + } + return CSR_RESULT_FAILURE; } + else if ((CSR_TX_LIFETIME == txStatus) || (CSR_TX_BLOCK_ACK_TIMEOUT == txStatus) || + (CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED == txStatus) || + (CSR_TX_REJECTED_PEER_STATION_SLEEPING == txStatus) || + (CSR_TX_REJECTED_DTIM_STARTED == txStatus)) { + /* Extract the Frame control and the frame type */ + frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr); + frameType = ((frameControl & IEEE80211_FC_TYPE_MASK) >> FRAME_CONTROL_TYPE_FIELD_OFFSET); + /* Mgmt frames will not be re-queued for Tx + * so just return failure to clear the hip slot + */ + if (IEEE802_11_FRAMETYPE_MANAGEMENT == frameType) { + return CSR_RESULT_FAILURE; + } + else if (IEEE802_11_FRAMETYPE_DATA == frameType) { + /* QOS NULL and DATA NULL frames will not be re-queued for Tx + * so just return failure to clear the hip slot + */ + if ((((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET) == QOS_DATA_NULL) || + (((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET)== DATA_NULL )) { + return CSR_RESULT_FAILURE; + } + } + /* Extract the Packet priority */ + if (TRUE == staRecord->wmmOrQosEnabled) { + CsrUint16 qosControl = 0; + CsrUint8 dataFrameType = 0; - tx_q_item = (tx_buffered_packets_t *)kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); - if (tx_q_item == NULL) { - unifi_error(priv, - "Failed to allocate %d bytes for tx packet record\n", - sizeof(tx_buffered_packets_t)); - func_exit(); - return CSR_RESULT_FAILURE; - } - /* disable the preemption */ - INIT_LIST_HEAD(&tx_q_item->q); - /* fill the tx_q structure members */ - tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr; - tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length; - tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr; - tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length; - tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff; - tx_q_item->hostTag = req->HostTag; - tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId; - tx_q_item->transmissionControl = req->TransmissionControl; - tx_q_item->priority = req->Priority; - tx_q_item->rate = req->TransmitRate; - memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN); + dataFrameType =((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> 4); + if (dataFrameType == QOS_DATA) { + /* QoS control field is offset from frame control by 2 (frame control) + * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN + */ + if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)) { + qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 30); + } + else { + qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 24); + } + } + priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK); - if (requeueOnSamePos) { - list_add(&tx_q_item->q, list); - } else { - list_add_tail(&tx_q_item->q, list); + if (priority < CSR_QOS_UP0 || priority > CSR_QOS_UP7) { + unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid priority:%x \n", priority); + return CSR_RESULT_FAILURE; + } + } + else { + priority = CSR_CONTENTION; + } + + /* Frame Bulk data to requeue it back to HAL Queues */ + bulkData.d[0].os_data_ptr = bulkDataDesc->os_data_ptr; + bulkData.d[0].data_length = bulkDataDesc->data_length; + bulkData.d[0].os_net_buf_ptr = bulkDataDesc->os_net_buf_ptr; + bulkData.d[0].net_buf_length = bulkDataDesc->net_buf_length; + + bulkData.d[1].os_data_ptr = NULL; + bulkData.d[1].os_net_buf_ptr = NULL; + bulkData.d[1].data_length = bulkData.d[1].net_buf_length = 0; + + /* Initialize signal to zero */ + memset(&signal, 0, sizeof(CSR_SIGNAL)); + + /* Frame MA Packet Req */ + unifi_frame_ma_packet_req(priv, priority, 0, host_tag, + interfaceTag, CSR_NO_CONFIRM_REQUIRED, + priv->netdev_client->sender_id, + staRecord->peerMacAddress.a, &signal); + + /* Find the Q-Priority */ + priority_q = unifi_frame_priority_to_queue(priority); + list = &staRecord->dataPdu[priority_q]; + + /* Place the Packet on to HAL Queue */ + status = enque_tx_data_pdu(priv, &bulkData, list, &signal, TRUE); + + /* Update the Per-station queued packet counter */ + if (!status) { + spin_lock_irqsave(&priv->staRecord_lock, lock_flags); + staRecord->noOfPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags); + } + } + else { + /* Packet will not be re-queued for any of the other MA Packet Tx failure + * reasons so just return failure to clear the hip slot + */ + return CSR_RESULT_FAILURE; } - /* Count of packet queued in driver */ - priv->noOfPktQueuedInDriver++; - unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n"); - return CSR_RESULT_SUCCESS; + return status; } +#endif static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, CsrUint8 *allDeliveryEnabled, CsrUint8 *dataAvailable) { @@ -601,12 +696,53 @@ void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, CsrUin unifi_trace(priv, UDBG3, "receiver processID = %x, success: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x, handle = %x\n", receiverProcessId, timSetStatus, staRecord->timSet, handle); } + + /* Reset TIM pending flag to send next TIM request */ + staRecord->timRequestPendingFlag = FALSE; + + /* Make sure that one more UpdateTim request is queued, if Queued its value + * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET + */ + if (0xFF != staRecord->updateTimReqQueued) + { + /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */ + if (staRecord->timSet != staRecord->updateTimReqQueued) + { + unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateTimReq \n"); + + update_tim(priv, staRecord->aid, staRecord->updateTimReqQueued, interfaceTag, handle); + + staRecord->updateTimReqQueued = 0xFF; + } + } } else { + + interfacePriv->bcTimSet = timSetValue; /* fh_cmd_q can also be full at some point of time!, * resetting count as queue is cleaned by firmware at this point */ retryCount = 0; unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET"); + + /* Reset DTIM pending flag to send next DTIM request */ + interfacePriv->bcTimSetReqPendingFlag = FALSE; + + /* Make sure that one more UpdateDTim request is queued, if Queued its value + * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET + */ + if (0xFF != interfacePriv->bcTimSetReqQueued) + { + /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */ + if (interfacePriv->bcTimSet != interfacePriv->bcTimSetReqQueued) + { + unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateDTimReq \n"); + + update_tim(priv, 0, interfacePriv->bcTimSetReqQueued, interfaceTag, 0xFFFFFFFF); + + interfacePriv->bcTimSetReqQueued = 0xFF; + } + } + } break; case CSR_RC_INVALID_PARAMETERS: @@ -684,6 +820,7 @@ void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, CsrUin default: unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode); } + unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__); } @@ -733,8 +870,14 @@ void update_tim(unifi_priv_t * priv, CsrUint16 aid, CsrUint8 setTim, CsrUint16 i unifi_trace(priv, UDBG5, "entering the update_tim routine\n"); + if (handle == 0xFFFFFFFF) { handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE; + if (setTim == interfacePriv->bcTimSet) + { + unifi_trace(priv, UDBG3, "update_tim, Drop:Hdl=%x, timval=%d, globalTim=%d\n", handle, setTim, interfacePriv->bcTimSet); + return; + } } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) { unifi_warning(priv, "bad station Handle = %x\n", handle); return; @@ -785,6 +928,25 @@ void update_tim(unifi_priv_t * priv, CsrUint16 aid, CsrUint8 setTim, CsrUint16 i if (staRecord) { staRecord->timSet = oldTimSetStatus ; } + else + { + /* MLME_SET_TIM.req sending failed here for AID0, so revert back our bcTimSet status */ + interfacePriv->bcTimSet = !setTim; + } + } + else { + /* Update tim request pending flag and ensure no more TIM set requests are send + for the same station until TIM confirm is received */ + if (staRecord) { + staRecord->timRequestPendingFlag = TRUE; + } + else + { + /* Update tim request (for AID 0) pending flag and ensure no more DTIM set requests are send + * for the same station until TIM confirm is received + */ + interfacePriv->bcTimSetReqPendingFlag = TRUE; + } } unifi_trace(priv, UDBG5, "leaving the update_tim routine\n"); } @@ -804,12 +966,30 @@ void process_peer_active_transition(unifi_priv_t * priv, if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) { /* giving more priority to multicast packets so delaying unicast packets*/ - unifi_trace(priv,UDBG2," multicast transmission is going on so resume unicast transmission after DTIM over\n"); + unifi_trace(priv,UDBG2, "Multicast transmission is going on so resume unicast transmission after DTIM over\n"); + + /* As station is active now, even though AP is not able to send frames to it + * because of DTIM, it needs to reset the TIM here + */ + if (!staRecord->timRequestPendingFlag){ + if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){ + update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle); + } + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 0; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); + } return; } while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) { unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n"); /* Enqueue at the head of the queue */ @@ -828,11 +1008,22 @@ void process_peer_active_transition(unifi_priv_t * priv, kfree(buffered_pkt); } } - if (staRecord->txSuspend) { - if(staRecord->timSet == CSR_WIFI_TIM_SET) { - update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + if (!staRecord->timRequestPendingFlag) { + if (staRecord->txSuspend) { + if(staRecord->timSet == CSR_WIFI_TIM_SET) { + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + return; } - return; + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 0; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); } for(i=3;i>=0;i--) { if(!spaceAvail[i]) @@ -840,7 +1031,7 @@ void process_peer_active_transition(unifi_priv_t * priv, unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i); while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) { buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) { /* Clear the trigger bit transmission control*/ /* Enqueue at the head of the queue */ @@ -859,9 +1050,20 @@ void process_peer_active_transition(unifi_priv_t * priv, } } } - if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){ - unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n"); - update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + if (!staRecord->timRequestPendingFlag){ + if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)) { + unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n"); + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 0; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); } unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n"); } @@ -873,14 +1075,6 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,CsrUint16 interfaceTag, con netInterface_priv_t *interfacePriv; CsrUint8 i; CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; - struct list_head *listHeadMaPktreq,*listHeadStaQueue; - struct list_head *placeHolderMaPktreq,*placeHolderStaQueue; - unsigned long lock_flags; - unsigned long lock_flags1; - maPktReqList_t *maPktreq = NULL; - tx_buffered_packets_t *tx_q_item = NULL; - bulk_data_param_t bulkdata; - CsrBool entryFound = FALSE; interfacePriv = priv->interfacePriv[interfaceTag]; @@ -892,260 +1086,113 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,CsrUint16 interfaceTag, con if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) && list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { unifi_trace(priv,UDBG1,"Resetting multicastTIM"); - update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF); - } - return; - } - - /* Check if a copy of the same frame (identified by host tag) is queued in driver */ - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) { - maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q); - if(maPktreq->hostTag == pkt_cfm->HostTag){ - entryFound = TRUE; - break; - } - } - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - - if(entryFound){ - - /* Monitor the time difference between the MA-PACKET.req and MA-PACKET.cfm */ - unsigned long timeout; - timeout = (long)jiffies - (long)maPktreq->jiffeTime; - - /* convert into milliseconds */ - timeout = jiffies_to_msecs(timeout); - unifi_trace(priv, UDBG3, "Jiffies Time: Host Tag(%x) --> Req(%u) Cfm(%u) Diff (in ms): %u\n",maPktreq->hostTag,maPktreq->jiffeTime, jiffies, timeout); - - if( (timeout/1000) > 1) - { - unifi_trace(priv, UDBG1, "Confirm time > 2 Seconds: time = %u Status = %x\n", (timeout/1000), pkt_cfm->TransmissionStatus); - } - - if( CSR_TX_LIFETIME == pkt_cfm->TransmissionStatus || - CSR_TX_BLOCK_ACK_TIMEOUT== pkt_cfm->TransmissionStatus || - CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED== pkt_cfm->TransmissionStatus || - CSR_TX_REJECTED_PEER_STATION_SLEEPING== pkt_cfm->TransmissionStatus || - CSR_TX_REJECTED_DTIM_STARTED== pkt_cfm->TransmissionStatus ){ - - CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler]; - unifi_TrafficQueue priority_q; - struct list_head *list; - CsrResult result; - CSR_MA_PACKET_REQUEST *req = &maPktreq->signal.u.MaPacketRequest; - CsrUint16 ii=0; - CsrBool locationFound = FALSE; - CsrUint8 *sigbuffer; - - sigbuffer = (CsrUint8*)&maPktreq->signal; - if(req->Priority == CSR_MANAGEMENT){ - list = &staRecord->mgtFrames; - unifi_trace(priv,UDBG5,"mgmt list priority %d\n",req->Priority); - } - else{ - priority_q= unifi_frame_priority_to_queue(req->Priority); - list = &staRecord->dataPdu[priority_q]; - unifi_trace(priv,UDBG5,"data list priority %d\n",req->Priority); - } - - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - list_for_each_safe(listHeadStaQueue, placeHolderStaQueue, list){ - tx_q_item = list_entry(listHeadStaQueue, tx_buffered_packets_t, q); - COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item->hostTag ,maPktreq->hostTag) - - - } - if(sigbuffer[SIZEOF_SIGNAL_HEADER + 1]){ - skb_pull(maPktreq->skb,sigbuffer[SIZEOF_SIGNAL_HEADER + 1]); - } - - /* enqueue the failed packet sta queue*/ - bulkdata.d[0].os_net_buf_ptr= (unsigned char*)maPktreq->skb; - bulkdata.d[0].os_data_ptr = maPktreq->skb->data; - bulkdata.d[0].data_length = bulkdata.d[0].net_buf_length = maPktreq->skb->len; - bulkdata.d[1].os_data_ptr = NULL; - bulkdata.d[1].os_net_buf_ptr = NULL; - bulkdata.d[1].data_length = bulkdata.d[0].net_buf_length = 0; - unifi_trace(priv,UDBG4,"Cfm Fail for HosTag = %x with status %d so requeue it\n",maPktreq->hostTag,pkt_cfm->TransmissionStatus ); - req->TransmissionControl = 0; - - if(!locationFound){ - - if(list_empty(list)){ - result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1); - } - else{ - unifi_trace(priv,UDBG4,"did not find location so add to end of list \n"); - result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,0); - } - - - } - - else { - if(ii > 1){ - unifi_trace(priv,UDBG4,"find the location in the middle of list \n"); - result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, listHeadStaQueue,&maPktreq->signal,0); - - } - else{ - unifi_trace(priv,UDBG4," add at begining of list \n"); - result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1); + if (!interfacePriv->bcTimSetReqPendingFlag) + { + update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF); } - } - - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - - /* Increment the counter */ - spin_lock_irqsave(&priv->staRecord_lock,lock_flags1); - staRecord->noOfPktQueued++; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags1); - - - - - /* after enqueuing update the TIM */ - if(CSR_RESULT_SUCCESS == result){ - if(CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE == staRecord->currentPeerState) { - if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) { - if(!staRecord->wmmOrQosEnabled) { - unifi_trace(priv, UDBG3, "uf_process_ma_pkt_cfm_for_ap :tim set due to unicast pkt & peer in powersave\n"); - update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle); - } - else { - /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */ - CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; - /* Check if all AC's are Delivery Enabled */ - is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); - if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) { - update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle); - } - } - } - } - } - else{ - dev_kfree_skb(maPktreq->skb); - } - } - else - { - CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler]; - if (CSR_TX_RETRY_LIMIT == pkt_cfm->TransmissionStatus || - CSR_TX_NO_BSS == pkt_cfm->TransmissionStatus) - { - if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) + else { - unifi_trace(priv, UDBG2, "CFM failed with Retry Limit or No BSS --> update TIM\n"); - update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle); + /* Cache the DTimSet value so that it will processed immidiatly after + * completing the current setDTim Request + */ + interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET; + unifi_trace(priv, UDBG2, "uf_process_ma_pkt_cfm_for_ap : One more UpdateDTim Request(%d) Queued \n", + interfacePriv->bcTimSetReqQueued); } + } - else if (CSR_TX_SUCCESSFUL == pkt_cfm->TransmissionStatus) - { - staRecord->activity_flag = TRUE; - } - unifi_trace(priv, UDBG5, "CFM for HosTag = %x Status = %d, Free SKB reference\n", - maPktreq->hostTag, - pkt_cfm->TransmissionStatus ); + return; + } - dev_kfree_skb(maPktreq->skb); + /* Check if it is a Confirm for null data frame used + * for probing station activity + */ + for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) { + staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]); + if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) { + + unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n", + pkt_cfm->HostTag, + pkt_cfm->TransmissionStatus + ); + staRecord->nullDataHostTag = INVALID_HOST_TAG; + + if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){ + CsrTime now; + CsrTime inactive_time; + + unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n"); + /* Recheck if there is some activity after null data is sent. + * + * If still there is no activity then send a disconnected indication + * to SME to delete the station record. + */ + if (staRecord->activity_flag){ + return; + } + now = CsrTimeGet(NULL); - } - list_del(listHeadMaPktreq); - kfree(maPktreq); + if (staRecord->lastActivity > now) + { + /* simple timer wrap (for 1 wrap) */ + inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity), + now); + } + else + { + inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity); + } - }else{ - /* Check if it is a Confirm for null data frame used - * for probing station activity - */ - for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) { - staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]); - if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) { - - unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n", - pkt_cfm->HostTag, - pkt_cfm->TransmissionStatus - ); - staRecord->nullDataHostTag = INVALID_HOST_TAG; - - if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){ - CsrTime now; - CsrTime inactive_time; - - unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n"); - /* Recheck if there is some activity after null data is sent. - * - * If still there is no activity then send a disconnected indication - * to SME to delete the station record. - */ - if (staRecord->activity_flag){ - return; - } - now = CsrTimeGet(NULL); + if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) + { + struct list_head send_cfm_list; + CsrUint8 j; + + /* The SME/NME may be waiting for confirmation for requested frames to this station. + * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a + * a defensive check, it loops through buffered frames for this station and if confirmation + * is requested, send auto confirmation with failure status. Also flush the frames so + * that these are not processed again in PEER_DEL_REQ handler. + */ + INIT_LIST_HEAD(&send_cfm_list); - if (staRecord->lastActivity > now) - { - /* simple timer wrap (for 1 wrap) */ - inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity), - now); - } - else - { - inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity); - } + uf_prepare_send_cfm_list_for_queued_pkts(priv, + &send_cfm_list, + &(staRecord->mgtFrames)); - if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) - { - struct list_head send_cfm_list; - CsrUint8 j; - - /* The SME/NME may be waiting for confirmation for requested frames to this station. - * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a - * a defensive check, it loops through buffered frames for this station and if confirmation - * is requested, send auto confirmation with failure status. Also flush the frames so - * that these are not processed again in PEER_DEL_REQ handler. - */ - INIT_LIST_HEAD(&send_cfm_list); + uf_flush_list(priv, &(staRecord->mgtFrames)); + for(j = 0; j < MAX_ACCESS_CATOGORY; j++){ uf_prepare_send_cfm_list_for_queued_pkts(priv, &send_cfm_list, - &(staRecord->mgtFrames)); - - uf_flush_list(priv, &(staRecord->mgtFrames)); + &(staRecord->dataPdu[j])); - for(j = 0; j < MAX_ACCESS_CATOGORY; j++){ - uf_prepare_send_cfm_list_for_queued_pkts(priv, - &send_cfm_list, - &(staRecord->dataPdu[j])); - - uf_flush_list(priv,&(staRecord->dataPdu[j])); - } - - send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list); + uf_flush_list(priv,&(staRecord->dataPdu[j])); + } + send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list); - unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n", - staRecord->peerMacAddress.a[0], - staRecord->peerMacAddress.a[1], - staRecord->peerMacAddress.a[2], - staRecord->peerMacAddress.a[3], - staRecord->peerMacAddress.a[4], - staRecord->peerMacAddress.a[5]); - CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, - 0, - staRecord->interfacePriv->InterfaceTag, - staRecord->peerMacAddress, - CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED); - } + unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n", + staRecord->peerMacAddress.a[0], + staRecord->peerMacAddress.a[1], + staRecord->peerMacAddress.a[2], + staRecord->peerMacAddress.a[3], + staRecord->peerMacAddress.a[4], + staRecord->peerMacAddress.a[5]); + CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, + 0, + staRecord->interfacePriv->InterfaceTag, + staRecord->peerMacAddress, + CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED); } - else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL) - { - staRecord->activity_flag = TRUE; - } + + } + else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL) + { + staRecord->activity_flag = TRUE; } } } @@ -1336,16 +1383,16 @@ static int update_macheader(unifi_priv_t *priv, struct sk_buff *skb, CsrResult csrResult; unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n"); - *priority = CSR_CONTENTION; if (qosDestination) { CsrUint8 qc = 0; unifi_trace(priv, UDBG3, "destination is QOS station \n"); - /* prepare the qos control field */ - qc |= CSR_QOS_UP0; + /* Set Ma-Packet.req UP to UP0 */ + *priority = CSR_QOS_UP0; + /* prepare the qos control field */ + qc |= CSR_QOS_UP0; /* no Amsdu is in ap buffer so eosp is left 0 */ - if (da[0] & 0x1) { /* multicast/broadcast frames, no acknowledgement needed */ qc |= 1 << 5; @@ -1763,9 +1810,6 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, */ list = &interfacePriv->genericMulticastOrBroadCastMgtFrames; - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - interfacePriv->noOfbroadcastPktQueued++; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) && (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { setBcTim=TRUE; @@ -1789,11 +1833,9 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, /* if multicast traffic is going on, buffet the unicast packets */ unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\ Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q)); - signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED); list = &staRecord->dataPdu[priority_q]; } else { unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q); - signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED); /* Pdu allowed to send to unifi */ result = ul_send_signal_unpacked(priv, &signal, bulkdata); if(result == -ENOSPC) { @@ -1816,9 +1858,6 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM */ list = &interfacePriv->genericMulticastOrBroadCastFrames; - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - interfacePriv->noOfbroadcastPktQueued++; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { setBcTim = TRUE; } @@ -1838,10 +1877,30 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, staRecord->noOfPktQueued++; spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); } + else if ((pktType == CSR_WIFI_MULTICAST_PDU) && (!status)) + { + /* If broadcast Tim is set && queuing is successfull, then only update TIM */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + interfacePriv->noOfbroadcastPktQueued++; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } } - if(setBcTim) { + /* If broadcast Tim is set && queuing is successfull, then only update TIM */ + if(setBcTim && !status) { unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n"); - update_tim(priv,0,1,interfaceTag, handle); + if (!interfacePriv->bcTimSetReqPendingFlag) + { + update_tim(priv,0,CSR_WIFI_TIM_SET,interfaceTag, handle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_SET; + unifi_trace(priv, UDBG2, "uf_process_ma_packet_req : One more UpdateDTim Request(:%d) Queued \n", + interfacePriv->bcTimSetReqQueued); + } } else if(staRecord && staRecord->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) { if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) { @@ -1850,15 +1909,38 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv, !list_empty(&staRecord->dataPdu[3]) || !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) { unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n"); - update_tim(priv,staRecord->aid,1,interfaceTag, handle); - } - } else { - /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */ - CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + if (!staRecord->timRequestPendingFlag){ + update_tim(priv,staRecord->aid,1,interfaceTag, handle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 1; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); + } + } + } else { + /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */ + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; /* Check if all AC's are Delivery Enabled */ is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); - if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) { - update_tim(priv,staRecord->aid,1,interfaceTag, handle); + if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable) + || (!list_empty(&staRecord->mgtFrames))) { + if (!staRecord->timRequestPendingFlag) { + update_tim(priv,staRecord->aid,1,interfaceTag, handle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 1; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); + } } } } @@ -1945,7 +2027,7 @@ CsrUint8 send_multicast_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) { while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK); - moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE; + moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE; unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag); @@ -1986,7 +2068,7 @@ CsrUint8 send_multicast_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) { while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) { buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; - moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE; + moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE; if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) { @@ -2076,7 +2158,19 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,CsrUint8 *sigdata, if(interfacePriv->multicastPduHostTag == 0xffffffff) { unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag); /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */ - update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF); + if (!interfacePriv->bcTimSetReqPendingFlag) + { + update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET; + unifi_trace(priv, UDBG2, "uf_process_ma_vif_availibility_ind : One more UpdateDTim Request(%d) Queued \n", + interfacePriv->bcTimSetReqQueued); + } } return; } @@ -2105,59 +2199,62 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,CsrUint8 *sigdata, #define GET_ACTIVE_INTERFACE_TAG(priv) 0 - -void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo) +static CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord) { - CsrInt8 i; - func_enter(); - - if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| - (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) - &&(!list_empty(&staInfo->mgtFrames))){ - - unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n"); - uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); - - /*This may happen because U-APSD was completed - with previous AC transfer*/ - - if(staInfo->uapsdActive == FALSE) { - return; + for(i=UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) + { + if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) + ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) + &&(!list_empty(&staRecord->dataPdu[i]))) { + unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available AC = %d\n", i); + return TRUE; } } - for(i=3;i>=0;i--) { + unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n"); + return FALSE; +} - if(((staInfo->powersaveMode[i]== CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) - ||(staInfo->powersaveMode[i] == CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) - &&(!list_empty(&staInfo->dataPdu[i]))) { - unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered data frames\n"); - uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]); - } +static CsrBool uf_is_more_data_for_usp_delivery(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord, unifi_TrafficQueue queue) +{ + CsrInt8 i; - /*This may happen because U-APSD was completed - with previous AC transfer*/ - if (staInfo->uapsdActive == FALSE) { - return; + for(i = queue; i >= UNIFI_TRAFFIC_Q_BK; i--) + { + if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) + ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) + &&(!list_empty(&staRecord->dataPdu[i]))) { + unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data Available AC = %d\n", i); + return TRUE; } } - if (staInfo->uapsdActive && !uf_is_more_data_for_delivery_ac(priv, staInfo, TRUE)) { - /* If last packet not able to transfer due to ENOSPC & buffer management algorithm - * would have removed last packet. Then we wont update staInfo->UapsdActive = FALSE (suppose - * to update as we dont have packet to transfer at this USP) because above if loop fails as list is empty & - * update of UAPSD activity done in uf_send_buffered_data_from_delivery_ac(). - * In this situation we send QOS null & mean time update UapsdActive to FALSE here - */ - staInfo->uapsdActive = FALSE; - uf_send_qos_null(priv, GET_ACTIVE_INTERFACE_TAG(priv), staInfo->peerMacAddress.a, CSR_QOS_UP0 , staInfo); - } - func_exit(); + unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data NOT Available \n"); + return FALSE; } - +/* + * --------------------------------------------------------------------------- + * uf_send_buffered_data_from_delivery_ac + * + * This function takes care of + * -> Parsing the delivery enabled queue & sending frame down to HIP + * -> Setting EOSP=1 when USP to be terminated + * -> Depending on MAX SP length services the USP + * + * NOTE:This function always called from uf_handle_uspframes_delivery(), Dont + * call this function from any other location in code + * + * Arguments: + * priv Pointer to device private context struct + * vif interface specific HIP vif instance + * staInfo peer for which UAPSD to be scheduled + * queue AC from which Data to be sent in USP + * txList access category for processing list + * --------------------------------------------------------------------------- + */ void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo, CsrUint8 queue, @@ -2170,117 +2267,94 @@ void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, CsrBool eosp=FALSE; CsrInt8 r =0; CsrBool moreData = FALSE; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; - CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; - netInterface_priv_t *interfacePriv; - interfacePriv = priv->interfacePriv[interfaceTag]; - func_enter(); - - /*Check U-APSD conditions if not met return from here*/ - if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)&& - (staInfo->uapsdActive == TRUE)&& - (!IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){ - - unifi_trace(priv,UDBG4,"uf_send_buffered_data_from_queue : U-APSD active. %d :Queue NOT delivery enbaled.return %\n",queue); + unifi_trace(priv, UDBG2, "++uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive); + if (queue > UNIFI_TRAFFIC_Q_VO) + { return; - } + } + while((buffered_pkt=dequeue_tx_data_pdu(priv, txList))) { + if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) { + unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: DTIM Active, suspend UAPSD, staId: 0x%x\n", + staInfo->aid); - while(!isRouterBufferEnabled(priv,queue) && - ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){ - if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){ + /* Once resume called, the U-APSD delivery operation will resume */ spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - staInfo->uapsdSuspended = TRUE; - staInfo->uapsdActive = FALSE; + staInfo->uspSuspend = TRUE; spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); /* re-queueing the packet as DTIM started */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_add(&buffered_pkt->q,txList); spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - unifi_trace(priv, UDBG3, "%s: DTIM Active while UAPSD in progress for staId: 0x%x\n",__FUNCTION__,staInfo->aid); break; } buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); - + ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); - if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)){ - moreData = uf_is_more_data_for_delivery_ac(priv,staInfo,TRUE); + if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)) { buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK; - if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength-1)){ - moreData = FALSE; - } - - if(moreData == FALSE){ - eosp = TRUE; - staInfo->uapsdActive = FALSE; - staInfo->noOfSpFramesSent = FALSE; - buffered_pkt->transmissionControl = - (TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + /* Check All delivery enables Ac for more data, because caller of this + * function not aware about last packet + * (First check in moreData fetching helps in draining out Mgt frames Q) + */ + moreData = (!list_empty(txList) || uf_is_more_data_for_usp_delivery(priv, staInfo, queue)); - /* Check if all AC's are Delivery Enabled */ - is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable); - if ((allDeliveryEnabled && !dataAvailable)) { - update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle); - } - /* check the moer data for non delivery ac and update accordingly */ - else if(uf_is_more_data_for_non_delivery_ac(staInfo) ) { - update_tim(priv,staInfo->aid,1,interfaceTag, staInfo->assignedHandle); - } - else if(!uf_is_more_data_for_non_delivery_ac(staInfo) ){ - unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_send_buffered_data_from_delivery_ac\n"); - update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle); - } + if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength - 1)) { + moreData = FALSE; + } - } - } - else - { - /*Non QoS and non U-APSD.*/ - eosp = FALSE; - moreData = FALSE; - unifi_warning(priv,"uf_send_buffered_data_from_delivery_ac :non U-APSD !!! \n"); + if(moreData == FALSE) { + eosp = TRUE; + buffered_pkt->transmissionControl = + (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); + } + } else { + /* Non QoS and non U-APSD */ + unifi_warning(priv, "uf_send_buffered_data_from_delivery_ac: non U-APSD !!! \n"); } unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) { - /* Enqueue at the head of the queue */ - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - list_add(&buffered_pkt->q,txList); - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle); - unifi_notice (priv," U-APSD: PDU sending failed .. no space for queue %d \n",queue); - /*Break the loop for this queue.Try for next available Delivery enabled - Queue*/ - break; + + unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: UASPD suspended, ENOSPC in hipQ=%x\n", queue); + + /* Once resume called, the U-APSD delivery operation will resume */ + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->uspSuspend = TRUE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + + spin_lock_irqsave(&priv->tx_q_lock,lock_flags); + list_add(&buffered_pkt->q,txList); + spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); + priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle); + break; } else { if(r){ /* the PDU failed where we can't do any thing so free the storage */ unifi_net_data_free(priv, &buffered_pkt->bulkdata); } - kfree(buffered_pkt); - if(staInfo->uapsdActive == TRUE){ - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - staInfo->noOfSpFramesSent = staInfo->noOfSpFramesSent + 1; - if(staInfo->noOfSpFramesSent == staInfo->maxSpLength){ - staInfo->uapsdActive = FALSE; - staInfo->noOfSpFramesSent = FALSE; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); - break; - } + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->noOfSpFramesSent++; + if((!moreData) || (staInfo->noOfSpFramesSent == staInfo->maxSpLength)) { + unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: Terminating USP\n"); + staInfo->uapsdActive = FALSE; + staInfo->uspSuspend = FALSE; + staInfo->noOfSpFramesSent = 0; spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + break; } + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); } } - - func_exit(); - + unifi_trace(priv, UDBG2, "--uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive); } void uf_send_buffered_data_from_ac(unifi_priv_t *priv, @@ -2302,7 +2376,7 @@ void uf_send_buffered_data_from_ac(unifi_priv_t *priv, ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){ buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK); unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp); @@ -2352,7 +2426,19 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)); if(!moreData) { - update_tim(priv,0,0,interfaceTag, 0XFFFFFFFF); + if (!interfacePriv->bcTimSetReqPendingFlag) + { + update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0XFFFFFFFF); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET; + unifi_trace(priv, UDBG2, "uf_send_buffered_frames : One more UpdateDTim Request(%d) Queued \n", + interfacePriv->bcTimSetReqQueued); + } } } else { moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || @@ -2391,33 +2477,17 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); } } - else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) - &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]))){ - - - if(!list_empty(&staInfo->mgtFrames)){ - /*UNIFI_TRAFFIC_Q_VO is delivery enabled push the managment frames out*/ - uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); - - } - } if(isRouterBufferEnabled(priv,queue)) { unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue); break; } } - - /*push generic management frames out*/ - - if(!list_empty(&interfacePriv->genericMgtFrames)){ - - unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue); - uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames); - + if(!list_empty(&interfacePriv->genericMgtFrames)) { + unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue); + uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames); } - } @@ -2431,14 +2501,14 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); if(!staInfo) { startIndex ++; - if(startIndex >= UNIFI_MAX_CONNECTIONS){ + if(startIndex >= UNIFI_MAX_CONNECTIONS) { startIndex = 0; } continue; } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) - &&(staInfo->uapsdActive == FALSE)){ + &&(staInfo->uapsdActive == FALSE)) { startIndex ++; - if(startIndex >= UNIFI_MAX_CONNECTIONS){ + if(startIndex >= UNIFI_MAX_CONNECTIONS) { startIndex = 0; } continue; @@ -2448,23 +2518,15 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) - &&(staInfo->uapsdActive == FALSE)){ - - if(!list_empty(&staInfo->dataPdu[queue])){ + &&(staInfo->uapsdActive == FALSE)) { + if(!list_empty(&staInfo->dataPdu[queue])) { - /*Non-UAPSD case push the AC frames out*/ - uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue])); + /*Non-UAPSD case push the AC frames out*/ + uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue])); } } - else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) - &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){ - if(!list_empty(&staInfo->dataPdu[queue])){ - uf_send_buffered_data_from_delivery_ac(priv, staInfo, queue, &staInfo->dataPdu[queue]); - } - } - startIndex ++; - if(startIndex >= UNIFI_MAX_CONNECTIONS){ + if(startIndex >= UNIFI_MAX_CONNECTIONS) { startIndex = 0; } } @@ -2474,47 +2536,14 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) priv->pausedStaHandle[queue] = 0; } - /*U-APSD might have stopped because of pause.So restart it if U-APSD - was active with any of the station*/ - for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { - staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); - if(!staInfo ) { - continue; - } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) - &&(staInfo->uapsdActive == TRUE)) { - - /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by - sending data from remaining delivery enabled queues*/ - uf_continue_uapsd(priv,staInfo); - } - } + /* U-APSD might have stopped because of ENOSPC in lib_hip (pause activity). + * So restart it if U-APSD was active with any of the station + */ + unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue); + resume_suspended_uapsd(priv, interfaceTag); func_exit(); } -CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck) -{ - CsrUint8 i; - - for(i=0;i<=3;i++) - { - if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) - ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) - &&(!list_empty(&staRecord->dataPdu[i]))){ - unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available \n"); - return TRUE; - } - } - if((mgtCheck == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO])) - &&(!list_empty(&staRecord->mgtFrames))){ - - unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Management Data Available \n"); - - return TRUE; - } - - unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n"); - return FALSE; -} CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord) { @@ -2584,101 +2613,148 @@ int uf_process_station_records_for_sending_data(unifi_priv_t *priv,CsrUint16 int return 0; } -void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv, - CsrWifiRouterCtrlStaInfo_t * srcStaInfo, - CsrUint16 qosControl, - CsrUint16 interfaceTag) + +/* + * --------------------------------------------------------------------------- + * uf_handle_uspframes_delivery + * + * This function takes care of handling USP session for peer, when + * -> trigger frame from peer + * -> suspended USP to be processed (resumed) + * + * NOTE: uf_send_buffered_data_from_delivery_ac() always called from this function, Dont + * make a direct call to uf_send_buffered_data_from_delivery_ac() from any other part of + * code + * + * Arguments: + * priv Pointer to device private context struct + * staInfo peer for which UAPSD to be scheduled + * interfaceTag virtual interface tag + * --------------------------------------------------------------------------- + */ +static void uf_handle_uspframes_delivery(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t *staInfo, CsrUint16 interfaceTag) { - CSR_PRIORITY priority; CsrInt8 i; - unifi_TrafficQueue priority_q; + CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; + netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; unsigned long lock_flags; - func_enter(); - - /* start the U-APSD operation only if it not active*/ - if(srcStaInfo->uapsdActive == FALSE){ - /*if recceived Frames trigger Frame and Devlivery enabled AC has data - then transmit from High priorty delivery enabled AC*/ + unifi_trace(priv, UDBG2, " ++ uf_handle_uspframes_delivery, uapsd active=%x, suspended?=%x\n", + staInfo->uapsdActive, staInfo->uspSuspend); + /* Check for Buffered frames according to priority order & deliver it + * 1. AC_VO delivery enable & Mgt frames available + * 2. Process remaining Ac's from order AC_VO to AC_BK + */ - priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK); - - priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); - - if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) - ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){ + /* USP initiated by WMMPS enabled peer & SET the status flag to TRUE */ + if (!staInfo->uspSuspend && staInfo->uapsdActive) + { + unifi_notice(priv, "uf_handle_uspframes_delivery: U-APSD already active! STA=%x:%x:%x:%x:%x:%x\n", + staInfo->peerMacAddress.a[0], staInfo->peerMacAddress.a[1], + staInfo->peerMacAddress.a[2], staInfo->peerMacAddress.a[3], + staInfo->peerMacAddress.a[4], staInfo->peerMacAddress.a[5]); + return; + } - unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd starting U-APSD operations\n"); + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->uapsdActive = TRUE; + staInfo->uspSuspend = FALSE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); - /*Received Frame is trigger frame*/ - unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : Received Frame is trigger frame %d\n",priority_q); + if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| + (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) + && (!list_empty(&staInfo->mgtFrames))) { - if(((srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| - (srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) - &&(!list_empty(&srcStaInfo->mgtFrames))){ + /* Management queue has data && UNIFI_TRAFFIC_Q_VO is delivery enable */ + unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Sending buffered management frames\n"); + uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); + } - /*Trigger frame received and Data available in Delivery enabled AC - or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/ + if (!uf_is_more_data_for_delivery_ac(priv, staInfo)) { + /* All delivery enable AC's are empty, so QNULL to be sent to terminate the USP + * NOTE: If we have sent Mgt frame also, we must send QNULL followed to terminate USP + */ + if (!staInfo->uspSuspend) { spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - srcStaInfo->uapsdActive = TRUE; + staInfo->uapsdActive = FALSE; spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); - unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n"); - - /* uf_send_buffered_frames(priv, priority_q); */ - uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, UNIFI_TRAFFIC_Q_VO, &srcStaInfo->mgtFrames); - - - /*This may happen because U-APSD was completed - with previous AC transfer*/ - - if(srcStaInfo->uapsdActive == FALSE){ - return; - } - - } - - - for(i=3;i>=0;i--){ - - if(((srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) - ||(srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) - &&(!list_empty(&srcStaInfo->dataPdu[i]))){ - - - /*Trigger frame received and Data available in Delivery enabled AC - or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/ - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - srcStaInfo->uapsdActive = TRUE; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); - - unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered data frames\n"); - - uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, i, &srcStaInfo->dataPdu[i]); + unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: sending QNull for trigger\n"); + uf_send_qos_null(priv, interfaceTag, staInfo->peerMacAddress.a, (CSR_PRIORITY) staInfo->triggerFramePriority, staInfo); + staInfo->triggerFramePriority = CSR_QOS_UP0; + } else { + unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: MgtQ xfer suspended\n"); + } + } else { + for(i = UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) { + if(((staInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) + ||(staInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) + && (!list_empty(&staInfo->dataPdu[i]))) { + /* Deliver Data according to AC priority (from VO to BK) as part of USP */ + unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Buffered data frames from Queue (%d) for USP\n", i); + uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]); + } - /*This may happen because U-APSD was completed - with previous AC transfer*/ + if ((!staInfo->uapsdActive) || + (staInfo->uspSuspend && IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) { + /* If DTIM active found on one AC, No need to parse the remaining AC's + * as USP suspended. Break out of loop + */ + unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: suspend=%x, DTIM=%x, USP terminated=%s\n", + staInfo->uspSuspend, IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag), + staInfo->uapsdActive?"NO":"YES"); + break; + } + } + } - if(srcStaInfo->uapsdActive == FALSE){ - return; - } + /* Depending on the USP status, update the TIM accordingly for delivery enabled AC only + * (since we are not manipulating any Non-delivery list(AC)) + */ + is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable); + if ((allDeliveryEnabled && !dataAvailable)) { + if ((staInfo->timSet != CSR_WIFI_TIM_RESET) || (staInfo->timSet != CSR_WIFI_TIM_RESETTING)) { + staInfo->updateTimReqQueued = (CsrUint8) CSR_WIFI_TIM_RESET; + unifi_trace(priv, UDBG4, " --uf_handle_uspframes_delivery, UAPSD timset\n"); + if (!staInfo->timRequestPendingFlag) { + update_tim(priv, staInfo->aid, 0, interfaceTag, staInfo->assignedHandle); } + } + } + unifi_trace(priv, UDBG2, " --uf_handle_uspframes_delivery, uapsd active=%x, suspend?=%x\n", + staInfo->uapsdActive, staInfo->uspSuspend); +} - } - if(srcStaInfo->uapsdActive == FALSE && !(uf_is_more_data_for_delivery_ac(priv,srcStaInfo,TRUE))){ - unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd : No buffer frames so sending QOS Null in response of trigger frame\n"); - uf_send_qos_null(priv,interfaceTag,srcStaInfo->peerMacAddress.a,priority,srcStaInfo); - } +void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv, + CsrWifiRouterCtrlStaInfo_t * srcStaInfo, + CsrUint16 qosControl, + CsrUint16 interfaceTag) +{ + CSR_PRIORITY priority; + unifi_TrafficQueue priority_q; + unsigned long lock_flags; - } + unifi_trace(priv, UDBG2, "++uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive); + /* If recceived Frames trigger Frame and Devlivery enabled AC has data + * then transmit from High priorty delivery enabled AC + */ + priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK); + priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); - } + if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) + ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) { + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + srcStaInfo->triggerFramePriority = priority; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + unifi_trace(priv, UDBG2, "uf_process_wmm_deliver_ac_uapsd: trigger frame, Begin U-APSD, triggerQ=%x\n", priority_q); + uf_handle_uspframes_delivery(priv, srcStaInfo, interfaceTag); + } + unifi_trace(priv, UDBG2, "--uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive); +} - func_exit(); -} void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo) { bulk_data_param_t bulkdata; @@ -2686,7 +2762,7 @@ void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 struct sk_buff *skb, *newSkb = NULL; CsrWifiMacAddress peerAddress; netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; - CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_ESOP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK); + CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_EOSP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK); int r; CSR_SIGNAL signal; CsrUint32 priority_q; @@ -2928,7 +3004,19 @@ CsrBool uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])); if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) { unifi_trace(priv, UDBG3, "This condition should not occur\n"); - update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); + if (!srcStaInfo->timRequestPendingFlag){ + update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + srcStaInfo->updateTimReqQueued = 1; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued, + srcStaInfo->aid); + } + } } else { CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; @@ -2939,7 +3027,18 @@ CsrBool uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable)); if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) { - update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); + if (!srcStaInfo->timRequestPendingFlag){ + update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + srcStaInfo->updateTimReqQueued = 1; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued, + srcStaInfo->aid); + } } } } @@ -2993,10 +3092,10 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || !list_empty(&staRecord->mgtFrames)); - buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { /* Clear the trigger bit transmission control*/ - buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_add(&buffered_pkt->q, &staRecord->mgtFrames); @@ -3016,10 +3115,10 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) || !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO])); - buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { /* Clear the trigger bit transmission control*/ - buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]); @@ -3038,10 +3137,10 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]); - buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { /* Clear the trigger bit transmission control*/ - buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]); @@ -3065,7 +3164,18 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm !list_empty(&staRecord->mgtFrames)); if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) { unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n"); - update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + if (!staRecord->timRequestPendingFlag){ + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 0; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); + } } } else { @@ -3074,9 +3184,9 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm /*Send Data From Management Frames*/ /* Priority orders for delivering the buffered packets are - * 1. UNIFI_TRAFFIC_Q_VO, if its non delivery enabled - * 2. management frames - * 3. Other access catagory frames which are non deliver enable + * 1. Deliver the Management frames if there + * 2. Other access catagory frames which are non deliver enable including UNIFI_TRAFFIC_Q_VO + * priority is from VO->BK */ /* Check if all AC's are Delivery Enabled */ @@ -3088,42 +3198,18 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm return; } - if ((!IS_DELIVERY_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO])) && - (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || !list_empty(&staRecord->mgtFrames))) { - /* UNIFI_TRAFFIC_Q_VO is non delivery enabled, & check for packets are there to send from this AC */ - if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) { - moreData = uf_is_more_data_for_non_delivery_ac(staRecord); - buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); - - /* Last parameter is EOSP & its false always for PS-POLL processing */ - if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { - /* Clear the trigger bit transmission control*/ - buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); - /* Enqueue at the head of the queue */ - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]); - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle); - unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n"); - } else { - if(r){ - unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n"); - /* the PDU failed where we can't do any thing so free the storage */ - unifi_net_data_free(priv, &buffered_pkt->bulkdata); - } - kfree(buffered_pkt); - } - } else if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { + if (!list_empty(&staRecord->mgtFrames)) { + if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management * queue of the station record */ moreData = uf_is_more_data_for_non_delivery_ac(staRecord); - buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Last parameter is EOSP & its false always for PS-POLL processing */ if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { /* Clear the trigger bit transmission control*/ - buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_add(&buffered_pkt->q, &staRecord->mgtFrames); @@ -3138,24 +3224,27 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm } kfree(buffered_pkt); } + } else { + unifi_error(priv, "uf_process_ps_poll: Mgt frame list empty!! \n"); } + } else { CsrInt8 i; - /* We dont have buffered packet in UNIFI_TRAFFIC_Q_VO & mangement frame queue (1 & 2 failed), So proceed with 3 condition - * UNIFI_TRAFFIC_Q_VO is taken care so start with i index = 2 + /* We dont have buffered packet in mangement frame queue (1 failed), So proceed with condition 2 + * UNIFI_TRAFFIC_Q_VO -> VI -> BE -> BK */ - for(i= 2; i>=0; i--) { + for(i= 3; i>=0; i--) { if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) { /* Send One packet, if queue is NULL then continue */ if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) { moreData = uf_is_more_data_for_non_delivery_ac(staRecord); - buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Last parameter is EOSP & its false always for PS-POLL processing */ if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { /* Clear the trigger bit transmission control*/ - buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); + buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK); /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_add(&buffered_pkt->q, &staRecord->dataPdu[i]); @@ -3181,7 +3270,19 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)); if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) { unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n"); - update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + if (!staRecord->timRequestPendingFlag){ + update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); + } + else + { + /* Cache the TimSet value so that it will processed immidiatly after + * completing the current setTim Request + */ + staRecord->updateTimReqQueued = 0; + unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued, + staRecord->aid); + } + } } @@ -3297,31 +3398,7 @@ void uf_flush_list(unifi_priv_t * priv, struct list_head * list) } spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); } -void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list) -{ - struct list_head *listHeadMaPktreq,*placeHolderMaPktreq; - maPktReqList_t *maPktreq; - unsigned long lock_flags; - unifi_trace(priv, UDBG5, "entering the uf_flush_maPktlist \n"); - - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - /* go through list, delete & free memory */ - list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, list) { - maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q); - - if(!maPktreq) { - unifi_error(priv, "entry should exists, otherwise crashes (bug)\n"); - } - /* free the allocated memory */ - dev_kfree_skb(maPktreq->skb); - list_del(listHeadMaPktreq); - kfree(maPktreq); - maPktreq = NULL; - - } - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); -} tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList) { /* dequeue the tx data packets from the appropriate queue */ @@ -3521,7 +3598,7 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) while(!isRouterBufferEnabled(priv,3) && ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) { buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) { /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); @@ -3547,7 +3624,7 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) { while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) { buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) { unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n"); /* Enqueue at the head of the queue */ @@ -3573,7 +3650,7 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag) while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) { buffered_pkt->transmissionControl &= - ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); + ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK); if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) { /* Enqueue at the head of the queue */ spin_lock_irqsave(&priv->tx_q_lock,lock_flags); @@ -3615,7 +3692,7 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 int spin_lock_irqsave(&priv->tx_q_lock,lock_flags); list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) { tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); - tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; + tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK; tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag); break; @@ -3624,105 +3701,51 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 int } func_exit(); } + +/* + * --------------------------------------------------------------------------- + * resume_suspended_uapsd + * + * This function takes care processing packets of Unscheduled Service Period, + * which been suspended earlier due to DTIM/HIP ENOSPC scenarios + * + * Arguments: + * priv Pointer to device private context struct + * interfaceTag For which resume should happen + * --------------------------------------------------------------------------- + */ void resume_suspended_uapsd(unifi_priv_t* priv,CsrUint16 interfaceTag) { CsrUint8 startIndex; CsrWifiRouterCtrlStaInfo_t * staInfo = NULL; - unsigned long lock_flags; - /*U-APSD might have stopped because of multicast. So restart it if U-APSD - was active with any of the station*/ + unsigned long lock_flags; + + unifi_trace(priv, UDBG2, "++resume_suspended_uapsd: \n"); for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); - if(!staInfo ) { + + if(!staInfo || !staInfo->wmmOrQosEnabled) { continue; } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) - &&(staInfo->uapsdSuspended == TRUE)) { - - /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by - sending data from remaining delivery enabled queues*/ - spin_lock_irqsave(&priv->staRecord_lock,lock_flags); - staInfo->uapsdActive = TRUE; - staInfo->uapsdSuspended = FALSE; - spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); - uf_continue_uapsd(priv,staInfo); - } - } - -} -void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata, - CSR_SIGNAL *sigptr, CsrUint32 alignOffset) -{ - - maPktReqList_t *maPktreq = NULL; - CSR_MA_PACKET_REQUEST *req = &sigptr->u.MaPacketRequest; - CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; - CsrUint16 frmCtrl,interfaceTag = 0; - const CsrUint8* macHdrLocation; - struct sk_buff *skb ; - unsigned long lock_flags; - netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; - CsrUint8 *sigbuffer; - CsrUint8 frameType = 0; - func_enter(); - - if(bulkdata == NULL || (0 == bulkdata->d[0].data_length )){ - unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece:bulk data NULL \n"); - func_exit(); - return; - } - macHdrLocation = bulkdata->d[0].os_data_ptr; - skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; - /* fectch the frame control value from mac header */ - frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation); - - /* Processing done according to Frame/Packet type */ - frameType = ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET); - - if( (((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_QOS_NULL) || - ((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_NULL ) ) || - ( IEEE802_11_FRAMETYPE_MANAGEMENT== frameType)){ - - /* if packet is NULL or Qos Null no need of retransmit so dont queue it*/ - unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: NULL data Pkt or mgmt\n"); - func_exit(); - return; - } - - /* fetch the station record for corresponding peer mac address */ - if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, req->Ra.x, interfaceTag))) { - maPktreq = (maPktReqList_t*)kmalloc(sizeof(maPktReqList_t),GFP_ATOMIC); - if(maPktreq == NULL){ - unifi_error(priv, - "uf_store_directed_ma_packet_referenece :: Failed to allocate %d byter for maPktreq\n", - sizeof(maPktReqList_t)); - func_exit(); - return; + &&staInfo->uapsdActive && staInfo->uspSuspend) { + /* U-APSD Still active & previously suspended either ENOSPC of FH queues OR + * due to DTIM activity + */ + uf_handle_uspframes_delivery(priv, staInfo, interfaceTag); + } else { + unifi_trace(priv, UDBG2, "resume_suspended_uapsd: PS state=%x, uapsdActive?=%x, suspend?=%x\n", + staInfo->currentPeerState, staInfo->uapsdActive, staInfo->uspSuspend); + if (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) + { + spin_lock_irqsave(&priv->staRecord_lock,lock_flags); + staInfo->uapsdActive = FALSE; + staInfo->uspSuspend = FALSE; + spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); + } } } - - /* staRecord not present that means packet is multicast or generic mgmt so no need to queue it */ - else{ - unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: multicast pkt \n"); - func_exit(); - return ; - } - - /* disbale preemption */ - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); - INIT_LIST_HEAD(&maPktreq->q); - maPktreq->staHandler = staRecord->assignedHandle; - memcpy(&maPktreq->signal,sigptr,sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + sizeof(CSR_MA_PACKET_REQUEST)); - sigbuffer = (CsrUint8*)&maPktreq->signal; - sigbuffer[SIZEOF_SIGNAL_HEADER + 1] = alignOffset; - maPktreq->skb = skb_get(skb); - maPktreq->hostTag = req->HostTag; - maPktreq->jiffeTime = jiffies; - list_add_tail(&maPktreq->q,&interfacePriv->directedMaPktReq); - - spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - func_exit(); - + unifi_trace(priv, UDBG2, "--resume_suspended_uapsd:\n"); } #endif diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h index f687f270a699..b23c84456578 100644 --- a/drivers/staging/csr/unifi_priv.h +++ b/drivers/staging/csr/unifi_priv.h @@ -44,6 +44,10 @@ #include +#ifdef ANDROID_BUILD +#include +#endif + #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_unifi_udi.h" #include "csr_wifi_router_lib.h" @@ -63,6 +67,10 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t; #include "unifi_wext.h" #endif +#ifdef ANDROID_BUILD +extern struct wake_lock unifi_sdio_wake_lock; +#endif + #include "unifi_clients.h" @@ -98,18 +106,14 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t; #include "unifi_sme.h" #endif -#undef COMPARE_HOST_TAG_TO_ENQUEUE -#define COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item_hosttag,maPktHostTag) \ - if(tx_q_item_hosttag > maPktHostTag){ \ - locationFound = TRUE; \ - ii++; \ - break; \ - } \ - ii++; \ - - /* The device major number to use when registering the udi driver */ #define UNIFI_NAME "unifi" +/* + * MAX_UNIFI_DEVS defines the maximum number of UniFi devices that can be present. + * This number should be set to the number of SDIO slots supported by the SDIO + * host controller on the platform. + * Note: If MAX_UNIFI_DEVS value changes, fw_init[] needs to be corrected in drv.c + */ #define MAX_UNIFI_DEVS 2 /* 802.11 Mac header offsets */ @@ -156,6 +160,10 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t; #define IEEE802_11_QC_TID_MASK 0x0f #define IEEE802_11_QC_A_MSDU_PRESENT 0x80 +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND)) +#define IEEE802_11_QC_NON_TID_BITS_MASK 0xFFF0 +#endif + #define CSR_WIFI_EAPOL_M4_HOST_TAG 0x50000000 #define IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE 36 #define MAX_ACCESS_CATOGORY 4 @@ -185,6 +193,9 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t; #define STA_INACTIVE_DETECTION_TIMER_INTERVAL 30 /* in seconds */ #define STA_INACTIVE_TIMEOUT_VAL 120*1000*1000 /* 120 seconds */ +/* Test for modes requiring AP firmware patch */ +#define CSR_WIFI_HIP_IS_AP_FW(mode) ((((mode) == CSR_WIFI_ROUTER_CTRL_MODE_AP) || \ + ((mode) == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) ? TRUE : FALSE) /* Defines used in beacon filtering in case of P2P */ #define CSR_WIFI_P2P_WILDCARD_SSID_LENGTH 0x7 @@ -220,6 +231,9 @@ extern int sdio_block_size; extern int coredump_max; extern int run_bh_once; extern int bh_priority; +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +extern int log_hip_signals; +#endif struct dlpriv { const unsigned char *dl_data; @@ -331,7 +345,8 @@ typedef struct CsrWifiRouterCtrlStaInfo_t { CsrTime lastActivity; /* during m/c transmission sp suspended */ - CsrBool uapsdSuspended; + CsrBool uspSuspend; + CSR_PRIORITY triggerFramePriority; #endif CsrWifiRouterCtrlPeerStatus currentPeerState; struct list_head dataPdu[MAX_ACCESS_CATOGORY]; @@ -349,6 +364,8 @@ typedef struct CsrWifiRouterCtrlStaInfo_t { #define CSR_WIFI_TIM_RESETTING 2 #define CSR_WIFI_TIM_SETTING 3 + CsrBool timRequestPendingFlag; + CsrUint8 updateTimReqQueued; CsrUint16 noOfPktQueued; }CsrWifiRouterCtrlStaInfo_t; @@ -609,8 +626,14 @@ struct unifi_priv { /* Spinlock to protect M4 data */ spinlock_t m4_lock; - /* Spinlock to protect BA RX data */ - spinlock_t ba_lock; + /* Mutex to protect BA RX data */ + struct semaphore ba_mutex; + +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + /* Spinlock to protect the WAPI data */ + spinlock_t wapi_lock; +#endif + #ifndef ALLOW_Q_PAUSE /* Array to indicate if a particular Tx queue is paused, this may not be * required in a multiqueue implementation since we can directly stop kernel @@ -630,10 +653,24 @@ struct unifi_priv { CsrUint32 rxUdpThroughput; CsrUint32 txUdpThroughput; - +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + /*Set if multicast KeyID = 1*/ CsrUint8 wapi_multicast_filter; + /*Set if unicast KeyID = 1*/ CsrUint8 wapi_unicast_filter; CsrUint8 wapi_unicast_queued_pkt_filter; +#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND + CsrBool isWapiConnection; +#endif +#endif + +#ifdef CSR_WIFI_SPLIT_PATCH + CsrWifiRouterCtrlModeSetReq pending_mode_set; +#endif + + CsrBool cmanrTestMode; + CSR_RATE cmanrTestModeTransmitRate; + }; typedef struct { @@ -682,6 +719,9 @@ typedef struct netInterface_priv CsrUint8 ba_complete_index; CsrUint8 queueEnabled[UNIFI_NO_OF_TX_QS]; struct work_struct send_m4_ready_task; +#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE + struct work_struct send_pkt_to_encrypt; +#endif struct net_device_stats stats; CsrUint8 interfaceMode; CsrBool protect; @@ -721,7 +761,6 @@ typedef struct netInterface_priv struct list_head genericMgtFrames; struct list_head genericMulticastOrBroadCastFrames; struct list_head genericMulticastOrBroadCastMgtFrames; - struct list_head directedMaPktReq; /* Timer for detecting station inactivity */ struct timer_list sta_activity_check_timer; @@ -740,6 +779,13 @@ typedef struct netInterface_priv /* Buffered M4 signal to take care of WPA race condition */ CSR_SIGNAL m4_signal; bulk_data_desc_t m4_bulk_data; + +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) + /* Buffered WAPI Unicast MA Packet Request for encryption in Sme */ + CSR_SIGNAL wapi_unicast_ma_pkt_sig; + bulk_data_desc_t wapi_unicast_bulk_data; +#endif + /* This should be removed and m4_hostTag should be used for checking*/ CsrBool m4_sent; CSR_CLIENT_TAG m4_hostTag; @@ -747,17 +793,11 @@ typedef struct netInterface_priv CsrBool intraBssEnabled; CsrUint32 multicastPduHostTag; /* Used to set the tim after getting a confirm for it */ + CsrBool bcTimSet; + CsrBool bcTimSetReqPendingFlag; + CsrBool bcTimSetReqQueued; } netInterface_priv_t; -typedef struct maPktReqList{ - struct list_head q; - struct sk_buff *skb; - CSR_SIGNAL signal; - CSR_CLIENT_TAG hostTag; - CsrUint32 staHandler; - unsigned long jiffeTime; -}maPktReqList_t; - #ifndef ALLOW_Q_PAUSE #define net_is_tx_q_paused(priv, q) (priv->tx_q_paused_flag[q]) #define net_tx_q_unpause(priv, q) (priv->tx_q_paused_flag[q] = 0) @@ -925,7 +965,6 @@ int uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb, bulk_data_param_t *bulkdata, CsrUint8 macHeaderLengthInBytes); CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord); -CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck); void uf_process_wmm_deliver_ac_uapsd ( unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo, CsrUint16 qosControl, @@ -937,7 +976,6 @@ void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtr void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo); void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo); void uf_send_nulldata(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo); -void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata,CSR_SIGNAL *sigptr,CsrUint32 alignOffset); @@ -956,7 +994,6 @@ void send_auto_ma_packet_confirm(unifi_priv_t *priv, netInterface_priv_t *interfacePriv, struct list_head *buffered_frames_list); void uf_flush_list(unifi_priv_t * priv, struct list_head * list); -void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list); tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList); void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag); void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 interfaceTag); @@ -1073,6 +1110,11 @@ void uf_process_rx_pending_queue(unifi_priv_t *priv, int queue, CsrWifiMacAddress source_address, int indicate, CsrUint16 interfaceTag); +#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE +int uf_register_hip_offline_debug(unifi_priv_t *priv); +int uf_unregister_hip_offline_debug(unifi_priv_t *priv); +#endif + /* * inet.c */ diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c index 4ee663fe4e4a..54414ed2ed1c 100644 --- a/drivers/staging/csr/unifi_sme.c +++ b/drivers/staging/csr/unifi_sme.c @@ -447,6 +447,7 @@ int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_power_t cfg_power; int rc; + int wol; if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); @@ -455,16 +456,24 @@ int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) switch (cfg_power) { case UNIFI_CFG_POWER_OFF: + priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; rc = sme_sys_suspend(priv); if (rc) { return rc; } break; case UNIFI_CFG_POWER_ON: + wol = priv->wol_suspend; rc = sme_sys_resume(priv); if (rc) { return rc; } + if (wol) { + /* Kick the BH to ensure pending transfers are handled when + * a suspend happened with card powered. + */ + unifi_send_signal(priv->card, NULL, 0, NULL); + } break; default: unifi_error(priv, "WIFI POWER: Unknown value.\n"); @@ -921,10 +930,19 @@ int supportedRates[i++]=0x8b; supportedRates[i++]=0x96; } else if(n) { + /* For some strange reasons WiFi stack needs both b and g rates*/ supportedRates[i++]=0x02; supportedRates[i++]=0x04; supportedRates[i++]=0x0b; supportedRates[i++]=0x16; + supportedRates[i++]=0x0c; + supportedRates[i++]=0x12; + supportedRates[i++]=0x18; + supportedRates[i++]=0x24; + supportedRates[i++]=0x30; + supportedRates[i++]=0x48; + supportedRates[i++]=0x60; + supportedRates[i++]=0x6c; } if(g) { if(!b) { @@ -1162,3 +1180,65 @@ uf_send_m4_ready_wq(struct work_struct *work) } /* uf_send_m4_ready_wq() */ +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) +/* + * --------------------------------------------------------------------------- + * uf_send_pkt_to_encrypt + * + * Deferred work queue function to send the WAPI data pkts to SME when unicast KeyId = 1 + * These are done in a deferred work queue for two reasons: + * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context + * - we want to load the main driver data path as lightly as possible + * + * Arguments: + * work Pointer to work queue item. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void uf_send_pkt_to_encrypt(struct work_struct *work) +{ + netInterface_priv_t *interfacePriv = container_of(work, netInterface_priv_t, send_pkt_to_encrypt); + CsrUint16 interfaceTag = interfacePriv->InterfaceTag; + unifi_priv_t *priv = interfacePriv->privPtr; + + CsrUint32 pktBulkDataLength; + CsrUint8 *pktBulkData; + unsigned long flags; + + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) { + + func_enter(); + + pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length; + + if (pktBulkDataLength > 0) { + pktBulkData = (CsrUint8 *)CsrPmemAlloc(pktBulkDataLength); + CsrMemSet(pktBulkData, 0, pktBulkDataLength); + } else { + unifi_error(priv, "uf_send_pkt_to_encrypt() : invalid buffer\n"); + return; + } + + spin_lock_irqsave(&priv->wapi_lock, flags); + /* Copy over the MA PKT REQ bulk data */ + CsrMemCpy(pktBulkData, (CsrUint8*)interfacePriv->wapi_unicast_bulk_data.os_data_ptr, pktBulkDataLength); + /* Free any bulk data buffers allocated for the WAPI Data pkt */ + unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data); + interfacePriv->wapi_unicast_bulk_data.net_buf_length = 0; + interfacePriv->wapi_unicast_bulk_data.data_length = 0; + interfacePriv->wapi_unicast_bulk_data.os_data_ptr = interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = NULL; + spin_unlock_irqrestore(&priv->wapi_lock, flags); + + CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, pktBulkDataLength, pktBulkData); + unifi_trace(priv, UDBG1, "WapiUnicastTxEncryptInd sent to SME\n"); + + CsrPmemFree(pktBulkData); /* Would have been copied over by the SME Handler */ + + func_exit(); + } else { + unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode); + } +}/* uf_send_pkt_to_encrypt() */ +#endif diff --git a/drivers/staging/csr/unifi_sme.h b/drivers/staging/csr/unifi_sme.h index 51ca92e89055..3cbee81f1b0a 100644 --- a/drivers/staging/csr/unifi_sme.h +++ b/drivers/staging/csr/unifi_sme.h @@ -50,6 +50,7 @@ enum sme_request_status { SME_REQUEST_PENDING, SME_REQUEST_RECEIVED, SME_REQUEST_TIMEDOUT, + SME_REQUEST_CANCELLED, }; /* Structure to hold a UDI logged signal */ @@ -123,6 +124,7 @@ void uf_ta_wq(struct work_struct *work); #endif void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func); +void uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status); /* @@ -148,6 +150,13 @@ void uf_sme_config_wq(struct work_struct *work); */ void uf_send_m4_ready_wq(struct work_struct *work); +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) +/* + * To send data pkt to Sme for encryption + */ +void uf_send_pkt_to_encrypt(struct work_struct *work); +#endif + int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig); int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig); int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig); diff --git a/drivers/staging/csr/unifiio.h b/drivers/staging/csr/unifiio.h index e707eedef29d..4ab050bc71cb 100644 --- a/drivers/staging/csr/unifiio.h +++ b/drivers/staging/csr/unifiio.h @@ -212,20 +212,19 @@ typedef struct { -typedef enum unifi_putest_command { - UNIFI_PUTEST_START, - UNIFI_PUTEST_STOP, - UNIFI_PUTEST_SET_SDIO_CLOCK, - UNIFI_PUTEST_CMD52_READ, - UNIFI_PUTEST_CMD52_WRITE, - UNIFI_PUTEST_DL_FW, - UNIFI_PUTEST_DL_FW_BUFF, - UNIFI_PUTEST_CMD52_BLOCK_READ, - UNIFI_PUTEST_COREDUMP_PREPARE, - UNIFI_PUTEST_GP_READ16, - UNIFI_PUTEST_GP_WRITE16 - -} unifi_putest_command_t; +typedef CsrUint8 unifi_putest_command_t; + +#define UNIFI_PUTEST_START 0 +#define UNIFI_PUTEST_STOP 1 +#define UNIFI_PUTEST_SET_SDIO_CLOCK 2 +#define UNIFI_PUTEST_CMD52_READ 3 +#define UNIFI_PUTEST_CMD52_WRITE 4 +#define UNIFI_PUTEST_DL_FW 5 +#define UNIFI_PUTEST_DL_FW_BUFF 6 +#define UNIFI_PUTEST_CMD52_BLOCK_READ 7 +#define UNIFI_PUTEST_COREDUMP_PREPARE 8 +#define UNIFI_PUTEST_GP_READ16 9 +#define UNIFI_PUTEST_GP_WRITE16 10 struct unifi_putest_cmd52 { -- GitLab From f9242b6b28d61295f2bf7e8adfb1060b382e5381 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Jun 2012 18:56:21 -0700 Subject: [PATCH 2104/6849] inet: Sanitize inet{,6} protocol demux. Don't pretend that inet_protos[] and inet6_protos[] are hashes, thay are just a straight arrays. Remove all unnecessary hash masking. Document MAX_INET_PROTOS. Use RAW_HTABLE_SIZE when appropriate. Reported-by: Ben Hutchings Signed-off-by: David S. Miller --- include/net/protocol.h | 7 +++++-- net/ipv4/af_inet.c | 26 ++++++++++++-------------- net/ipv4/icmp.c | 9 ++++----- net/ipv4/ip_input.c | 5 ++--- net/ipv4/protocol.c | 8 +++----- net/ipv6/icmp.c | 7 ++----- net/ipv6/ip6_input.c | 9 +++------ net/ipv6/protocol.c | 8 +++----- net/ipv6/raw.c | 4 ++-- 9 files changed, 36 insertions(+), 47 deletions(-) diff --git a/include/net/protocol.h b/include/net/protocol.h index 875f4895b033..a1b1b530c338 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -29,8 +29,11 @@ #include #endif -#define MAX_INET_PROTOS 256 /* Must be a power of 2 */ - +/* This is one larger than the largest protocol value that can be + * found in an ipv4 or ipv6 header. Since in both cases the protocol + * value is presented in a __u8, this is defined to be 256. + */ +#define MAX_INET_PROTOS 256 /* This is used to register protocols. */ struct net_protocol { diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e4e8e00a2c91..85a3b1763136 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -242,20 +242,18 @@ void build_ehash_secret(void) } EXPORT_SYMBOL(build_ehash_secret); -static inline int inet_netns_ok(struct net *net, int protocol) +static inline int inet_netns_ok(struct net *net, __u8 protocol) { - int hash; const struct net_protocol *ipprot; if (net_eq(net, &init_net)) return 1; - hash = protocol & (MAX_INET_PROTOS - 1); - ipprot = rcu_dereference(inet_protos[hash]); - - if (ipprot == NULL) + ipprot = rcu_dereference(inet_protos[protocol]); + if (ipprot == NULL) { /* raw IP is OK */ return 1; + } return ipprot->netns_ok; } @@ -1216,8 +1214,8 @@ EXPORT_SYMBOL(inet_sk_rebuild_header); static int inet_gso_send_check(struct sk_buff *skb) { - const struct iphdr *iph; const struct net_protocol *ops; + const struct iphdr *iph; int proto; int ihl; int err = -EINVAL; @@ -1236,7 +1234,7 @@ static int inet_gso_send_check(struct sk_buff *skb) __skb_pull(skb, ihl); skb_reset_transport_header(skb); iph = ip_hdr(skb); - proto = iph->protocol & (MAX_INET_PROTOS - 1); + proto = iph->protocol; err = -EPROTONOSUPPORT; rcu_read_lock(); @@ -1253,8 +1251,8 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, netdev_features_t features) { struct sk_buff *segs = ERR_PTR(-EINVAL); - struct iphdr *iph; const struct net_protocol *ops; + struct iphdr *iph; int proto; int ihl; int id; @@ -1286,7 +1284,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, skb_reset_transport_header(skb); iph = ip_hdr(skb); id = ntohs(iph->id); - proto = iph->protocol & (MAX_INET_PROTOS - 1); + proto = iph->protocol; segs = ERR_PTR(-EPROTONOSUPPORT); rcu_read_lock(); @@ -1340,7 +1338,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, goto out; } - proto = iph->protocol & (MAX_INET_PROTOS - 1); + proto = iph->protocol; rcu_read_lock(); ops = rcu_dereference(inet_protos[proto]); @@ -1398,11 +1396,11 @@ out: static int inet_gro_complete(struct sk_buff *skb) { - const struct net_protocol *ops; + __be16 newlen = htons(skb->len - skb_network_offset(skb)); struct iphdr *iph = ip_hdr(skb); - int proto = iph->protocol & (MAX_INET_PROTOS - 1); + const struct net_protocol *ops; + int proto = iph->protocol; int err = -ENOSYS; - __be16 newlen = htons(skb->len - skb_network_offset(skb)); csum_replace2(&iph->check, iph->tot_len, newlen); iph->tot_len = newlen; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e1caa1abe5d1..49a74cc79dc8 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -637,12 +637,12 @@ EXPORT_SYMBOL(icmp_send); static void icmp_unreach(struct sk_buff *skb) { + const struct net_protocol *ipprot; const struct iphdr *iph; struct icmphdr *icmph; - int hash, protocol; - const struct net_protocol *ipprot; - u32 info = 0; struct net *net; + u32 info = 0; + int protocol; net = dev_net(skb_dst(skb)->dev); @@ -731,9 +731,8 @@ static void icmp_unreach(struct sk_buff *skb) */ raw_icmp_error(skb, protocol, info); - hash = protocol & (MAX_INET_PROTOS - 1); rcu_read_lock(); - ipprot = rcu_dereference(inet_protos[hash]); + ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot && ipprot->err_handler) ipprot->err_handler(skb, info); rcu_read_unlock(); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 8590144ca330..c4fe1d271131 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -198,14 +198,13 @@ static int ip_local_deliver_finish(struct sk_buff *skb) rcu_read_lock(); { int protocol = ip_hdr(skb)->protocol; - int hash, raw; const struct net_protocol *ipprot; + int raw; resubmit: raw = raw_local_deliver(skb, protocol); - hash = protocol & (MAX_INET_PROTOS - 1); - ipprot = rcu_dereference(inet_protos[hash]); + ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot != NULL) { int ret; diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index 9ae5c01cd0b2..8918eff1426d 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -36,9 +36,7 @@ const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly; int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) { - int hash = protocol & (MAX_INET_PROTOS - 1); - - return !cmpxchg((const struct net_protocol **)&inet_protos[hash], + return !cmpxchg((const struct net_protocol **)&inet_protos[protocol], NULL, prot) ? 0 : -1; } EXPORT_SYMBOL(inet_add_protocol); @@ -49,9 +47,9 @@ EXPORT_SYMBOL(inet_add_protocol); int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) { - int ret, hash = protocol & (MAX_INET_PROTOS - 1); + int ret; - ret = (cmpxchg((const struct net_protocol **)&inet_protos[hash], + ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol], prot, NULL) == prot) ? 0 : -1; synchronize_net(); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 5247d5c211f9..c7da1422cbde 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -600,9 +600,8 @@ static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) { const struct inet6_protocol *ipprot; int inner_offset; - int hash; - u8 nexthdr; __be16 frag_off; + u8 nexthdr; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) return; @@ -629,10 +628,8 @@ static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) --ANK (980726) */ - hash = nexthdr & (MAX_INET_PROTOS - 1); - rcu_read_lock(); - ipprot = rcu_dereference(inet6_protos[hash]); + ipprot = rcu_dereference(inet6_protos[nexthdr]); if (ipprot && ipprot->err_handler) ipprot->err_handler(skb, NULL, type, code, inner_offset, info); rcu_read_unlock(); diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 21a15dfe4a9e..5ab923e51af3 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -168,13 +168,12 @@ drop: static int ip6_input_finish(struct sk_buff *skb) { + struct net *net = dev_net(skb_dst(skb)->dev); const struct inet6_protocol *ipprot; + struct inet6_dev *idev; unsigned int nhoff; int nexthdr; bool raw; - u8 hash; - struct inet6_dev *idev; - struct net *net = dev_net(skb_dst(skb)->dev); /* * Parse extension headers @@ -189,9 +188,7 @@ resubmit: nexthdr = skb_network_header(skb)[nhoff]; raw = raw6_local_deliver(skb, nexthdr); - - hash = nexthdr & (MAX_INET_PROTOS - 1); - if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) { + if ((ipprot = rcu_dereference(inet6_protos[nexthdr])) != NULL) { int ret; if (ipprot->flags & INET6_PROTO_FINAL) { diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 9a7978fdc02a..053082dfc93e 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c @@ -29,9 +29,7 @@ const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly; int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) { - int hash = protocol & (MAX_INET_PROTOS - 1); - - return !cmpxchg((const struct inet6_protocol **)&inet6_protos[hash], + return !cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol], NULL, prot) ? 0 : -1; } EXPORT_SYMBOL(inet6_add_protocol); @@ -42,9 +40,9 @@ EXPORT_SYMBOL(inet6_add_protocol); int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) { - int ret, hash = protocol & (MAX_INET_PROTOS - 1); + int ret; - ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[hash], + ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol], prot, NULL) == prot) ? 0 : -1; synchronize_net(); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 43b0042f15f4..b5c1dcb27737 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -165,7 +165,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) saddr = &ipv6_hdr(skb)->saddr; daddr = saddr + 1; - hash = nexthdr & (MAX_INET_PROTOS - 1); + hash = nexthdr & (RAW_HTABLE_SIZE - 1); read_lock(&raw_v6_hashinfo.lock); sk = sk_head(&raw_v6_hashinfo.ht[hash]); @@ -229,7 +229,7 @@ bool raw6_local_deliver(struct sk_buff *skb, int nexthdr) { struct sock *raw_sk; - raw_sk = sk_head(&raw_v6_hashinfo.ht[nexthdr & (MAX_INET_PROTOS - 1)]); + raw_sk = sk_head(&raw_v6_hashinfo.ht[nexthdr & (RAW_HTABLE_SIZE - 1)]); if (raw_sk && !ipv6_raw_deliver(skb, nexthdr)) raw_sk = NULL; -- GitLab From 4dd81e895655c59bd19d7a8f03a5de1310f4aeb6 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 14 Jun 2012 20:49:09 +0000 Subject: [PATCH 2105/6849] RDMA/cma: QP type check on received REQs should be AND not OR Change || check to the intended && when checking the QP type in a received connection request against the listening endpoint. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/cma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 55d5642eb10a..2e826f9702c6 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) { - return (((ib_event->event == IB_CM_REQ_RECEIVED) || + return (((ib_event->event == IB_CM_REQ_RECEIVED) && (ib_event->param.req_rcvd.qp_type == id->qp_type)) || ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && (id->qp_type == IB_QPT_UD)) || -- GitLab From 4f6939f898c408e6ba9754a42405494f821f22cb Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 20 Jun 2012 13:11:38 +0900 Subject: [PATCH 2106/6849] ARM: SAMSUNG: remove unused SPI clock headers Commit 875a59374cd10200ac24f03877ccd8f73af590cc ("ARM: SAMSUNG: Consolidation of SPI platform devices to plat-samsung") deleted all (four) files that included one of the "spi-clocks.h" headers. It seems it was just an oversight to not remove those headers too. They can safely be removed now. Signed-off-by: Paul Bolle Signed-off-by: Kukjin Kim --- .../arm/mach-exynos/include/mach/spi-clocks.h | 16 --------------- .../mach-s3c64xx/include/mach/spi-clocks.h | 18 ----------------- .../mach-s5p64x0/include/mach/spi-clocks.h | 20 ------------------- .../mach-s5pc100/include/mach/spi-clocks.h | 18 ----------------- .../mach-s5pv210/include/mach/spi-clocks.h | 17 ---------------- 5 files changed, 89 deletions(-) delete mode 100644 arch/arm/mach-exynos/include/mach/spi-clocks.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/spi-clocks.h delete mode 100644 arch/arm/mach-s5p64x0/include/mach/spi-clocks.h delete mode 100644 arch/arm/mach-s5pc100/include/mach/spi-clocks.h delete mode 100644 arch/arm/mach-s5pv210/include/mach/spi-clocks.h diff --git a/arch/arm/mach-exynos/include/mach/spi-clocks.h b/arch/arm/mach-exynos/include/mach/spi-clocks.h deleted file mode 100644 index c71a5fba6a84..000000000000 --- a/arch/arm/mach-exynos/include/mach/spi-clocks.h +++ /dev/null @@ -1,16 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/spi-clocks.h - * - * Copyright (C) 2011 Samsung Electronics Co. Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_SPI_CLKS_H -#define __ASM_ARCH_SPI_CLKS_H __FILE__ - -/* Must source from SCLK_SPI */ -#define EXYNOS_SPI_SRCCLK_SCLK 0 - -#endif /* __ASM_ARCH_SPI_CLKS_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h b/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h deleted file mode 100644 index 9d0c43b4b687..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h +++ /dev/null @@ -1,18 +0,0 @@ -/* linux/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h - * - * Copyright (C) 2009 Samsung Electronics Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __S3C64XX_PLAT_SPI_CLKS_H -#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__ - -#define S3C64XX_SPI_SRCCLK_PCLK 0 -#define S3C64XX_SPI_SRCCLK_SPIBUS 1 -#define S3C64XX_SPI_SRCCLK_48M 2 - -#endif /* __S3C64XX_PLAT_SPI_CLKS_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h deleted file mode 100644 index 170a20a9643a..000000000000 --- a/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h +++ /dev/null @@ -1,20 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_SPI_CLKS_H -#define __ASM_ARCH_SPI_CLKS_H __FILE__ - -#define S5P64X0_SPI_SRCCLK_PCLK 0 -#define S5P64X0_SPI_SRCCLK_SCLK 1 - -#endif /* __ASM_ARCH_SPI_CLKS_H */ diff --git a/arch/arm/mach-s5pc100/include/mach/spi-clocks.h b/arch/arm/mach-s5pc100/include/mach/spi-clocks.h deleted file mode 100644 index 65e426370bb2..000000000000 --- a/arch/arm/mach-s5pc100/include/mach/spi-clocks.h +++ /dev/null @@ -1,18 +0,0 @@ -/* linux/arch/arm/mach-s5pc100/include/mach/spi-clocks.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __S5PC100_PLAT_SPI_CLKS_H -#define __S5PC100_PLAT_SPI_CLKS_H __FILE__ - -#define S5PC100_SPI_SRCCLK_PCLK 0 -#define S5PC100_SPI_SRCCLK_48M 1 -#define S5PC100_SPI_SRCCLK_SPIBUS 2 - -#endif /* __S5PC100_PLAT_SPI_CLKS_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/spi-clocks.h b/arch/arm/mach-s5pv210/include/mach/spi-clocks.h deleted file mode 100644 index 02acded5f73d..000000000000 --- a/arch/arm/mach-s5pv210/include/mach/spi-clocks.h +++ /dev/null @@ -1,17 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/include/mach/spi-clocks.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __S5PV210_PLAT_SPI_CLKS_H -#define __S5PV210_PLAT_SPI_CLKS_H __FILE__ - -#define S5PV210_SPI_SRCCLK_PCLK 0 -#define S5PV210_SPI_SRCCLK_SCLK 1 - -#endif /* __S5PV210_PLAT_SPI_CLKS_H */ -- GitLab From 41063e9dd11956f2d285e12e4342e1d232ba0ea2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Jun 2012 21:22:05 -0700 Subject: [PATCH 2107/6849] ipv4: Early TCP socket demux. Input packet processing for local sockets involves two major demuxes. One for the route and one for the socket. But we can optimize this down to one demux for certain kinds of local sockets. Currently we only do this for established TCP sockets, but it could at least in theory be expanded to other kinds of connections. If a TCP socket is established then it's identity is fully specified. This means that whatever input route was used during the three-way handshake must work equally well for the rest of the connection since the keys will not change. Once we move to established state, we cache the receive packet's input route to use later. Like the existing cached route in sk->sk_dst_cache used for output packets, we have to check for route invalidations using dst->obsolete and dst->ops->check(). Early demux occurs outside of a socket locked section, so when a route invalidation occurs we defer the fixup of sk->sk_rx_dst until we are actually inside of established state packet processing and thus have the socket locked. Signed-off-by: David S. Miller --- include/net/inet_hashtables.h | 4 +-- include/net/protocol.h | 1 + include/net/sock.h | 2 ++ include/net/tcp.h | 1 + net/core/sock.c | 5 ++++ net/ipv4/af_inet.c | 18 ++++++++------ net/ipv4/ip_input.c | 39 +++++++++++++++++++---------- net/ipv4/tcp_input.c | 16 +++++++++++- net/ipv4/tcp_ipv4.c | 46 +++++++++++++++++++++++++++++++++++ net/ipv4/tcp_minisocks.c | 2 ++ 10 files changed, 110 insertions(+), 24 deletions(-) diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 808fc5f76b03..54be0287eb98 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -379,10 +379,10 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, const __be16 sport, const __be16 dport) { - struct sock *sk; + struct sock *sk = skb_steal_sock(skb); const struct iphdr *iph = ip_hdr(skb); - if (unlikely(sk = skb_steal_sock(skb))) + if (sk) return sk; else return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, diff --git a/include/net/protocol.h b/include/net/protocol.h index a1b1b530c338..967b926cbfb1 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -37,6 +37,7 @@ /* This is used to register protocols. */ struct net_protocol { + int (*early_demux)(struct sk_buff *skb); int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); int (*gso_send_check)(struct sk_buff *skb); diff --git a/include/net/sock.h b/include/net/sock.h index 4a4521699563..87b424ae750a 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -319,6 +319,7 @@ struct sock { unsigned long sk_flags; struct dst_entry *sk_dst_cache; spinlock_t sk_dst_lock; + struct dst_entry *sk_rx_dst; atomic_t sk_wmem_alloc; atomic_t sk_omem_alloc; int sk_sndbuf; @@ -1426,6 +1427,7 @@ extern struct sk_buff *sock_rmalloc(struct sock *sk, gfp_t priority); extern void sock_wfree(struct sk_buff *skb); extern void sock_rfree(struct sk_buff *skb); +extern void sock_edemux(struct sk_buff *skb); extern int sock_setsockopt(struct socket *sock, int level, int op, char __user *optval, diff --git a/include/net/tcp.h b/include/net/tcp.h index 9332f342259a..6660ffc4963d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -325,6 +325,7 @@ extern void tcp_v4_err(struct sk_buff *skb, u32); extern void tcp_shutdown (struct sock *sk, int how); +extern int tcp_v4_early_demux(struct sk_buff *skb); extern int tcp_v4_rcv(struct sk_buff *skb); extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); diff --git a/net/core/sock.c b/net/core/sock.c index 9e5b71fda6ec..929bdcc2383b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1465,6 +1465,11 @@ void sock_rfree(struct sk_buff *skb) } EXPORT_SYMBOL(sock_rfree); +void sock_edemux(struct sk_buff *skb) +{ + sock_put(skb->sk); +} +EXPORT_SYMBOL(sock_edemux); int sock_i_uid(struct sock *sk) { diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 85a3b1763136..07a02f6e9696 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -157,6 +157,7 @@ void inet_sock_destruct(struct sock *sk) kfree(rcu_dereference_protected(inet->inet_opt, 1)); dst_release(rcu_dereference_check(sk->sk_dst_cache, 1)); + dst_release(sk->sk_rx_dst); sk_refcnt_debug_dec(sk); } EXPORT_SYMBOL(inet_sock_destruct); @@ -1518,14 +1519,15 @@ static const struct net_protocol igmp_protocol = { #endif static const struct net_protocol tcp_protocol = { - .handler = tcp_v4_rcv, - .err_handler = tcp_v4_err, - .gso_send_check = tcp_v4_gso_send_check, - .gso_segment = tcp_tso_segment, - .gro_receive = tcp4_gro_receive, - .gro_complete = tcp4_gro_complete, - .no_policy = 1, - .netns_ok = 1, + .early_demux = tcp_v4_early_demux, + .handler = tcp_v4_rcv, + .err_handler = tcp_v4_err, + .gso_send_check = tcp_v4_gso_send_check, + .gso_segment = tcp_tso_segment, + .gro_receive = tcp4_gro_receive, + .gro_complete = tcp4_gro_complete, + .no_policy = 1, + .netns_ok = 1, }; static const struct net_protocol udp_protocol = { diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index c4fe1d271131..93b092c9a394 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -323,19 +323,32 @@ static int ip_rcv_finish(struct sk_buff *skb) * how the packet travels inside Linux networking. */ if (skb_dst(skb) == NULL) { - int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb->dev); - if (unlikely(err)) { - if (err == -EHOSTUNREACH) - IP_INC_STATS_BH(dev_net(skb->dev), - IPSTATS_MIB_INADDRERRORS); - else if (err == -ENETUNREACH) - IP_INC_STATS_BH(dev_net(skb->dev), - IPSTATS_MIB_INNOROUTES); - else if (err == -EXDEV) - NET_INC_STATS_BH(dev_net(skb->dev), - LINUX_MIB_IPRPFILTER); - goto drop; + const struct net_protocol *ipprot; + int protocol = iph->protocol; + int err; + + rcu_read_lock(); + ipprot = rcu_dereference(inet_protos[protocol]); + err = -ENOENT; + if (ipprot && ipprot->early_demux) + err = ipprot->early_demux(skb); + rcu_read_unlock(); + + if (err) { + err = ip_route_input_noref(skb, iph->daddr, iph->saddr, + iph->tos, skb->dev); + if (unlikely(err)) { + if (err == -EHOSTUNREACH) + IP_INC_STATS_BH(dev_net(skb->dev), + IPSTATS_MIB_INADDRERRORS); + else if (err == -ENETUNREACH) + IP_INC_STATS_BH(dev_net(skb->dev), + IPSTATS_MIB_INNOROUTES); + else if (err == -EXDEV) + NET_INC_STATS_BH(dev_net(skb->dev), + LINUX_MIB_IPRPFILTER); + goto drop; + } } } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b224eb8bce8b..8416f8a68e65 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5518,6 +5518,18 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, struct tcp_sock *tp = tcp_sk(sk); int res; + if (sk->sk_rx_dst) { + struct dst_entry *dst = sk->sk_rx_dst; + if (unlikely(dst->obsolete)) { + if (dst->ops->check(dst, 0) == NULL) { + dst_release(dst); + sk->sk_rx_dst = NULL; + } + } + } + if (unlikely(sk->sk_rx_dst == NULL)) + sk->sk_rx_dst = dst_clone(skb_dst(skb)); + /* * Header prediction. * The code loosely follows the one in the famous @@ -5729,8 +5741,10 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) tcp_set_state(sk, TCP_ESTABLISHED); - if (skb != NULL) + if (skb != NULL) { + sk->sk_rx_dst = dst_clone(skb_dst(skb)); security_inet_conn_established(sk, skb); + } /* Make sure socket is routed, for correct metrics. */ icsk->icsk_af_ops->rebuild_header(sk); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index fda2ca17135e..13857df1dae1 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1671,6 +1671,52 @@ csum_err: } EXPORT_SYMBOL(tcp_v4_do_rcv); +int tcp_v4_early_demux(struct sk_buff *skb) +{ + struct net *net = dev_net(skb->dev); + const struct iphdr *iph; + const struct tcphdr *th; + struct sock *sk; + int err; + + err = -ENOENT; + if (skb->pkt_type != PACKET_HOST) + goto out_err; + + if (!pskb_may_pull(skb, ip_hdrlen(skb) + sizeof(struct tcphdr))) + goto out_err; + + iph = ip_hdr(skb); + th = (struct tcphdr *) ((char *)iph + ip_hdrlen(skb)); + + if (th->doff < sizeof(struct tcphdr) / 4) + goto out_err; + + if (!pskb_may_pull(skb, ip_hdrlen(skb) + th->doff * 4)) + goto out_err; + + sk = __inet_lookup_established(net, &tcp_hashinfo, + iph->saddr, th->source, + iph->daddr, th->dest, + skb->dev->ifindex); + if (sk) { + skb->sk = sk; + skb->destructor = sock_edemux; + if (sk->sk_state != TCP_TIME_WAIT) { + struct dst_entry *dst = sk->sk_rx_dst; + if (dst) + dst = dst_check(dst, 0); + if (dst) { + skb_dst_set_noref(skb, dst); + err = 0; + } + } + } + +out_err: + return err; +} + /* * From tcp_input.c */ diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index cb015317c9f7..72b7c63b1a39 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -445,6 +445,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct tcp_sock *oldtp = tcp_sk(sk); struct tcp_cookie_values *oldcvp = oldtp->cookie_values; + newsk->sk_rx_dst = dst_clone(skb_dst(skb)); + /* TCP Cookie Transactions require space for the cookie pair, * as it differs for each connection. There is no need to * copy any s_data_payload stored at the original socket. -- GitLab From 58f8c0543a9b0d84bca43526aec3774110201bc8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jun 2012 08:16:19 +0900 Subject: [PATCH 2108/6849] ARM: S3C64XX: Add module identification for Balblair Cragganmore module Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 7a27f5603c74..f51cc70064a4 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -209,6 +209,7 @@ static __devinitdata const struct { .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) }, { .id = 0x32, .name = "XXXX-EV1 Caol Illa" }, { .id = 0x33, .name = "XXXX-EV1 Oban" }, + { .id = 0x34, .name = "WM0010-6320-CS42 Balblair" }, { .id = 0x39, .name = "1254-EV1 Dallas Dhu", .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) }, { .id = 0x3a, .name = "1259-EV1 Tobermory", -- GitLab From 9b6e1b0e882a00d654a8313e22c189f13c321a20 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jun 2012 08:16:25 +0900 Subject: [PATCH 2109/6849] ARM: S3C64XX: Add WM5102 EVM to Cragganmore modules No platform data yet as driver is not yet merged. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index f51cc70064a4..497937222a29 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -182,6 +182,11 @@ static const struct i2c_board_info wm1277_devs[] = { }, }; +static const struct i2c_board_info wm5102_devs[] = { + { I2C_BOARD_INFO("wm5102", 0x1a), + .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, }, +}; + static const struct i2c_board_info wm6230_i2c_devs[] = { { I2C_BOARD_INFO("wm9081", 0x6c), .platform_data = &wm9081_pdata, }, @@ -219,6 +224,8 @@ static __devinitdata const struct { { .id = 0x3c, .name = "1273-EV1 Longmorn" }, { .id = 0x3d, .name = "1277-EV1 Littlemill", .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) }, + { .id = 0x3e, .name = "WM5102-6271-EV1-CS127", + .i2c_devs = wm5102_devs, .num_i2c_devs = ARRAY_SIZE(wm5102_devs) }, }; static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, -- GitLab From 7d1d8ce5b50f4593f6d4b9d8149f978c122f617b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jun 2012 08:18:04 +0900 Subject: [PATCH 2110/6849] ARM: S3C64XX: Dynamically allocate the IRQ range for WM8994 on Cragganmore Use the new irqdomain support in the WM8994 driver to dynamically allocate the interrupt range for the WM8994 rather than doing it explicitly. This is more idiomatic for modern interrupt usage. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/include/mach/crag6410.h | 1 - arch/arm/mach-s3c64xx/mach-crag6410-module.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h index 4cb2f951f1e9..ec97c15b109e 100644 --- a/arch/arm/mach-s3c64xx/include/mach/crag6410.h +++ b/arch/arm/mach-s3c64xx/include/mach/crag6410.h @@ -15,7 +15,6 @@ #define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START #define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) -#define CODEC_IRQ_BASE (IRQ_BOARD_START + 128) #define PCA935X_GPIO_BASE GPIO_BOARD_START #define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 497937222a29..4a83b4e7ab32 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -168,7 +168,6 @@ static struct wm8994_pdata wm8994_pdata = { .gpio_defaults = { 0x3, /* IRQ out, active high, CMOS */ }, - .irq_base = CODEC_IRQ_BASE, .ldo = { { .init_data = &wm8994_ldo1, }, { .init_data = &wm8994_ldo2, }, -- GitLab From 4f057aa0dcb2660bb09ead75d829a19ec71319f1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jun 2012 08:18:07 +0900 Subject: [PATCH 2111/6849] ARM: S3C64XX: Dynamically assign interrupts for CPU PMIC on Cragganmore Now that the WM831x driver uses irq_domain we can happily allow it to assign its own IRQs. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/include/mach/crag6410.h | 3 +-- arch/arm/mach-s3c64xx/mach-crag6410.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h index ec97c15b109e..4c3c9994fc2c 100644 --- a/arch/arm/mach-s3c64xx/include/mach/crag6410.h +++ b/arch/arm/mach-s3c64xx/include/mach/crag6410.h @@ -13,8 +13,7 @@ #include -#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START -#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) +#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START #define PCA935X_GPIO_BASE GPIO_BOARD_START #define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index d0c352d861f8..161c3b6218a2 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -525,7 +525,6 @@ static struct wm831x_touch_pdata touch_pdata __initdata = { static struct wm831x_pdata crag_pmic_pdata __initdata = { .wm831x_num = 1, - .irq_base = BANFF_PMIC_IRQ_BASE, .gpio_base = BANFF_PMIC_GPIO_BASE, .soft_shutdown = true, -- GitLab From 33fe1a49ad23a63a60a816c99bdf6640f2314aea Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Jun 2012 09:12:33 +0900 Subject: [PATCH 2112/6849] ARM: EXYNOS: Update keypad entries for SMDK4X12 Keypad entries are updated as per the latest revision of the board. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/mach-smdk4x12.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c index fb09c70e195a..e134c9562f15 100644 --- a/arch/arm/mach-exynos/mach-smdk4x12.c +++ b/arch/arm/mach-exynos/mach-smdk4x12.c @@ -219,8 +219,10 @@ static struct platform_pwm_backlight_data smdk4x12_bl_data = { static uint32_t smdk4x12_keymap[] __initdata = { /* KEY(row, col, keycode) */ - KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B), - KEY(1, 3, KEY_E), KEY(1, 4, KEY_C) + KEY(1, 3, KEY_1), KEY(1, 4, KEY_2), KEY(1, 5, KEY_3), + KEY(1, 6, KEY_4), KEY(1, 7, KEY_5), + KEY(2, 5, KEY_D), KEY(2, 6, KEY_A), KEY(2, 7, KEY_B), + KEY(0, 7, KEY_E), KEY(0, 5, KEY_C) }; static struct matrix_keymap_data smdk4x12_keymap_data __initdata = { @@ -230,8 +232,8 @@ static struct matrix_keymap_data smdk4x12_keymap_data __initdata = { static struct samsung_keypad_platdata smdk4x12_keypad_data __initdata = { .keymap_data = &smdk4x12_keymap_data, - .rows = 2, - .cols = 5, + .rows = 3, + .cols = 8, }; static struct platform_device *smdk4x12_devices[] __initdata = { -- GitLab From 05b9afd5b711b284c17f657495dc08f4a6f6e7e9 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 19 Jun 2012 22:21:18 +0200 Subject: [PATCH 2113/6849] ALSA: snd_usb_audio: ignore ctrl errors on QuickCam E3500 if this cam is pluged in, pulse audio can't initiate capture device. dmesg has lots of messages like: "cannot set freq 16000 to ep 0x86" Setting ignore_ctl_error=1 fixes this problem. Signed-off-by: Oleksij Rempel Signed-off-by: Takashi Iwai --- sound/usb/mixer_maps.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 41daaa24c25f..484603bbeb70 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -341,6 +341,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .map = audigy2nx_map, .selector_map = audigy2nx_selectors, }, + { /* Logitech, Inc. QuickCam E 3500 */ + .id = USB_ID(0x046d, 0x09a4), + .ignore_ctl_error = 1, + }, { /* Hercules DJ Console (Windows Edition) */ .id = USB_ID(0x06f8, 0xb000), -- GitLab From b64a1ba9d3111a7b3eb3bef96efb84dde15e6eac Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 19 Jun 2012 22:21:19 +0200 Subject: [PATCH 2114/6849] ALSA: snd_usb_audio: ignore ctrl errors on QuickCam Pro for Notebooks This webcam works mostly ok, exept with skype. Skype sends lots of ctrl messages to dynamically ajust record level. If for some reasons it pokes some error every thing goes broken: - first pulseaudio blocks sound for all apps - then video is reseted - then skype freez dmesg has lots of messages like: cannot set freq 16000 to ep 0x86" Setting ignore_ctl_error=1 fixes this problem. Signed-off-by: Oleksij Rempel Signed-off-by: Takashi Iwai --- sound/usb/mixer_maps.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 484603bbeb70..e71fe55cebef 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -341,6 +341,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .map = audigy2nx_map, .selector_map = audigy2nx_selectors, }, + { /* Logitech, Inc. QuickCam Pro for Notebooks */ + .id = USB_ID(0x046d, 0x0991), + .ignore_ctl_error = 1, + }, { /* Logitech, Inc. QuickCam E 3500 */ .id = USB_ID(0x046d, 0x09a4), .ignore_ctl_error = 1, -- GitLab From d7dc9e32ae64b5db777017344da61a285c2347f8 Mon Sep 17 00:00:00 2001 From: Markus Bollinger Date: Wed, 20 Jun 2012 08:32:48 +0200 Subject: [PATCH 2115/6849] ALSA: pcxhr: Fix a counter wrap fix a counter wrap to avoid resynchronization of stream positions every several minutes. The resynchronization may create stream position jitter Signed-off-by: Markus Bollinger Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr_core.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 304411c1fe4b..841703b5c52a 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -1133,13 +1133,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr, hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; hw_sample_count += (u_int64_t)rmh.stat[1]; - snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", + snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n", stream->pipe->is_capture ? 'C' : 'P', stream->substream->number, - (long unsigned int)hw_sample_count, - (long unsigned int)(stream->timer_abs_periods + - stream->timer_period_frag + - mgr->granularity)); + hw_sample_count, + stream->timer_abs_periods + stream->timer_period_frag + + mgr->granularity); return hw_sample_count; } @@ -1243,10 +1242,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) if ((dsp_time_diff < 0) && (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { - snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " - "resynchronize all streams\n", + /* handle dsp counter wraparound without resync */ + int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1; + snd_printdd("WARNING DSP timestamp old(%d) new(%d)", mgr->dsp_time_last, dsp_time_new); - mgr->dsp_time_err++; + if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) { + snd_printdd("-> timestamp wraparound OK: " + "diff=%d\n", tmp_diff); + dsp_time_diff = tmp_diff; + } else { + snd_printdd("-> resynchronize all streams\n"); + mgr->dsp_time_err++; + } } #ifdef CONFIG_SND_DEBUG_VERBOSE if (dsp_time_diff == 0) -- GitLab From fdfbaf69e0b9d6843c0da6501caf4ecacec0f775 Mon Sep 17 00:00:00 2001 From: Markus Bollinger Date: Wed, 20 Jun 2012 08:34:40 +0200 Subject: [PATCH 2116/6849] ALSA: pcxhr: Add LTC support add LTC (linear timecode) read function via proc interface to the pcxhr driver Signed-off-by: Markus Bollinger Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.c | 63 +++++++++++++++++++++++++++++++++++ sound/pci/pcxhr/pcxhr.h | 1 + sound/pci/pcxhr/pcxhr_core.c | 4 +++ sound/pci/pcxhr/pcxhr_core.h | 4 ++- sound/pci/pcxhr/pcxhr_mix22.c | 11 ++++++ sound/pci/pcxhr/pcxhr_mix22.h | 1 + 6 files changed, 83 insertions(+), 1 deletion(-) diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 0435f45e9513..e3ac1f768ff6 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -1368,6 +1368,67 @@ static void pcxhr_proc_gpo_write(struct snd_info_entry *entry, } } +/* Access to the results of the CMD_GET_TIME_CODE RMH */ +#define TIME_CODE_VALID_MASK 0x00800000 +#define TIME_CODE_NEW_MASK 0x00400000 +#define TIME_CODE_BACK_MASK 0x00200000 +#define TIME_CODE_WAIT_MASK 0x00100000 + +/* Values for the CMD_MANAGE_SIGNAL RMH */ +#define MANAGE_SIGNAL_TIME_CODE 0x01 +#define MANAGE_SIGNAL_MIDI 0x02 + +/* linear time code read proc*/ +static void pcxhr_proc_ltc(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_pcxhr *chip = entry->private_data; + struct pcxhr_mgr *mgr = chip->mgr; + struct pcxhr_rmh rmh; + unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm; + int err; + /* commands available when embedded DSP is running */ + if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) { + snd_iprintf(buffer, "no firmware loaded\n"); + return; + } + if (!mgr->capture_ltc) { + pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL); + rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE; + err = pcxhr_send_msg(mgr, &rmh); + if (err) { + snd_iprintf(buffer, "ltc not activated (%d)\n", err); + return; + } + if (mgr->is_hr_stereo) + hr222_manage_timecode(mgr, 1); + else + pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE, + REG_CONT_VALSMPTE, NULL); + mgr->capture_ltc = 1; + } + pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE); + err = pcxhr_send_msg(mgr, &rmh); + if (err) { + snd_iprintf(buffer, "ltc read error (err=%d)\n", err); + return ; + } + ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf); + ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf); + ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf); + ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf); + + snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n", + ltcHrs, ltcMin, ltcSec, ltcFrm); + snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff, + rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff); + /*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n", + rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/ + if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) { + snd_iprintf(buffer, "warning: linear timecode not valid\n"); + } +} + static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) { struct snd_info_entry *entry; @@ -1383,6 +1444,8 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) entry->c.text.write = pcxhr_proc_gpo_write; entry->mode |= S_IWUSR; } + if (!snd_card_proc_new(chip->card, "ltc", &entry)) + snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc); } /* end of proc interface */ diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index bda776c49884..a4c602c45173 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h @@ -103,6 +103,7 @@ struct pcxhr_mgr { unsigned int board_has_mic:1; /* if 1 the board has microphone input */ unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ unsigned int mono_capture:1; /* if 1 the board does mono capture */ + unsigned int capture_ltc:1; /* if 1 the board captures LTC input */ struct snd_dma_buffer hostport; diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 841703b5c52a..b33db1e006e7 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = { [CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, [CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, [CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, +[CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED }, +[CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED }, }; #ifdef CONFIG_SND_DEBUG_VERBOSE @@ -533,6 +535,8 @@ static char* cmd_names[] = { [CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", [CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", [CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", +[CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE", +[CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL", }; #endif diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h index be0173796cdb..a81ab6b811e7 100644 --- a/sound/pci/pcxhr/pcxhr_core.h +++ b/sound/pci/pcxhr/pcxhr_core.h @@ -79,6 +79,8 @@ enum { CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */ CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */ CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */ + CMD_GET_TIME_CODE, /* cmd_len = 1 stat_len = 5 */ + CMD_MANAGE_SIGNAL, /* cmd_len = 1 stat_len = 0 */ CMD_LAST_INDEX }; @@ -116,7 +118,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh); #define IO_NUM_REG_OUT_ANA_LEVEL 20 #define IO_NUM_REG_IN_ANA_LEVEL 21 - +#define REG_CONT_VALSMPTE 0x000800 #define REG_CONT_UNMUTE_INPUTS 0x020000 /* parameters used with register IO_NUM_REG_STATUS */ diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c index 1cb82c0a9cb3..84fe57626eba 100644 --- a/sound/pci/pcxhr/pcxhr_mix22.c +++ b/sound/pci/pcxhr/pcxhr_mix22.c @@ -53,6 +53,7 @@ #define PCXHR_DSP_RESET_DSP 0x01 #define PCXHR_DSP_RESET_MUTE 0x02 #define PCXHR_DSP_RESET_CODEC 0x08 +#define PCXHR_DSP_RESET_SMPTE 0x10 #define PCXHR_DSP_RESET_GPO_OFFSET 5 #define PCXHR_DSP_RESET_GPO_MASK 0x60 @@ -527,6 +528,16 @@ int hr222_write_gpo(struct pcxhr_mgr *mgr, int value) return 0; } +int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable) +{ + if (enable) + mgr->dsp_reset |= PCXHR_DSP_RESET_SMPTE; + else + mgr->dsp_reset &= ~PCXHR_DSP_RESET_SMPTE; + + PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset); + return 0; +} int hr222_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h index 5a37a0007e8f..5971b9933f41 100644 --- a/sound/pci/pcxhr/pcxhr_mix22.h +++ b/sound/pci/pcxhr/pcxhr_mix22.h @@ -34,6 +34,7 @@ int hr222_get_external_clock(struct pcxhr_mgr *mgr, int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value); int hr222_write_gpo(struct pcxhr_mgr *mgr, int value); +int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable); #define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */ #define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */ -- GitLab From 24fe5ddc5f189606bde68136ac808da37e4dfe04 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 19 Jun 2012 16:20:23 -0300 Subject: [PATCH 2117/6849] sound: swarm_cs4297: Provide definitions for AC97 registers This patch removes the last usage of linux/ac97_codec.h by re-defining used AC97 registers. We can't use sound/ac97_codec.h here, since it is an OSS driver. Cc: Ralf Baechle Cc: Jaroslav Kysela Cc: Clemens Ladisch Signed-off-by: Ezequiel Garcia Signed-off-by: Takashi Iwai --- sound/oss/swarm_cs4297a.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 09d46484bc1a..7d8803a00b79 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include #include @@ -199,6 +198,22 @@ static const char invalid_magic[] = } \ }) +/* AC97 registers */ +#define AC97_MASTER_VOL_STEREO 0x0002 /* Line Out */ +#define AC97_PCBEEP_VOL 0x000a /* none */ +#define AC97_PHONE_VOL 0x000c /* TAD Input (mono) */ +#define AC97_MIC_VOL 0x000e /* MIC Input (mono) */ +#define AC97_LINEIN_VOL 0x0010 /* Line Input (stereo) */ +#define AC97_CD_VOL 0x0012 /* CD Input (stereo) */ +#define AC97_AUX_VOL 0x0016 /* Aux Input (stereo) */ +#define AC97_PCMOUT_VOL 0x0018 /* Wave Output (stereo) */ +#define AC97_RECORD_SELECT 0x001a /* */ +#define AC97_RECORD_GAIN 0x001c +#define AC97_GENERAL_PURPOSE 0x0020 +#define AC97_3D_CONTROL 0x0022 +#define AC97_POWER_CONTROL 0x0026 +#define AC97_VENDOR_ID1 0x007c + struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs }; typedef struct serdma_descr_s { -- GitLab From 33eb3311f3ad4a14f2e55d36fdb0d3ec54712231 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 19 Jun 2012 16:20:24 -0300 Subject: [PATCH 2118/6849] sound: Remove unused include/linux/ac97_codec.h header This file has been superseded by include/sound/ac97_codec.h, and has currently no users. Cc: Ralf Baechle Cc: Jaroslav Kysela Cc: Clemens Ladisch Signed-off-by: Ezequiel Garcia Signed-off-by: Takashi Iwai --- include/linux/ac97_codec.h | 362 ------------------------------------- 1 file changed, 362 deletions(-) delete mode 100644 include/linux/ac97_codec.h diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h deleted file mode 100644 index 0260c3e79fdd..000000000000 --- a/include/linux/ac97_codec.h +++ /dev/null @@ -1,362 +0,0 @@ -#ifndef _AC97_CODEC_H_ -#define _AC97_CODEC_H_ - -#include -#include - -/* AC97 1.0 */ -#define AC97_RESET 0x0000 // -#define AC97_MASTER_VOL_STEREO 0x0002 // Line Out -#define AC97_HEADPHONE_VOL 0x0004 // -#define AC97_MASTER_VOL_MONO 0x0006 // TAD Output -#define AC97_MASTER_TONE 0x0008 // -#define AC97_PCBEEP_VOL 0x000a // none -#define AC97_PHONE_VOL 0x000c // TAD Input (mono) -#define AC97_MIC_VOL 0x000e // MIC Input (mono) -#define AC97_LINEIN_VOL 0x0010 // Line Input (stereo) -#define AC97_CD_VOL 0x0012 // CD Input (stereo) -#define AC97_VIDEO_VOL 0x0014 // none -#define AC97_AUX_VOL 0x0016 // Aux Input (stereo) -#define AC97_PCMOUT_VOL 0x0018 // Wave Output (stereo) -#define AC97_RECORD_SELECT 0x001a // -#define AC97_RECORD_GAIN 0x001c -#define AC97_RECORD_GAIN_MIC 0x001e -#define AC97_GENERAL_PURPOSE 0x0020 -#define AC97_3D_CONTROL 0x0022 -#define AC97_MODEM_RATE 0x0024 -#define AC97_POWER_CONTROL 0x0026 - -/* AC'97 2.0 */ -#define AC97_EXTENDED_ID 0x0028 /* Extended Audio ID */ -#define AC97_EXTENDED_STATUS 0x002A /* Extended Audio Status */ -#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */ -#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */ -#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */ -#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */ -#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */ -#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */ -#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */ -#define AC97_RESERVED_3A 0x003A /* Reserved in AC '97 < 2.2 */ - -/* AC'97 2.2 */ -#define AC97_SPDIF_CONTROL 0x003A /* S/PDIF Control */ - -/* range 0x3c-0x58 - MODEM */ -#define AC97_EXTENDED_MODEM_ID 0x003C -#define AC97_EXTEND_MODEM_STAT 0x003E -#define AC97_LINE1_RATE 0x0040 -#define AC97_LINE2_RATE 0x0042 -#define AC97_HANDSET_RATE 0x0044 -#define AC97_LINE1_LEVEL 0x0046 -#define AC97_LINE2_LEVEL 0x0048 -#define AC97_HANDSET_LEVEL 0x004A -#define AC97_GPIO_CONFIG 0x004C -#define AC97_GPIO_POLARITY 0x004E -#define AC97_GPIO_STICKY 0x0050 -#define AC97_GPIO_WAKE_UP 0x0052 -#define AC97_GPIO_STATUS 0x0054 -#define AC97_MISC_MODEM_STAT 0x0056 -#define AC97_RESERVED_58 0x0058 - -/* registers 0x005a - 0x007a are vendor reserved */ - -#define AC97_VENDOR_ID1 0x007c -#define AC97_VENDOR_ID2 0x007e - -/* volume control bit defines */ -#define AC97_MUTE 0x8000 -#define AC97_MICBOOST 0x0040 -#define AC97_LEFTVOL 0x3f00 -#define AC97_RIGHTVOL 0x003f - -/* record mux defines */ -#define AC97_RECMUX_MIC 0x0000 -#define AC97_RECMUX_CD 0x0101 -#define AC97_RECMUX_VIDEO 0x0202 -#define AC97_RECMUX_AUX 0x0303 -#define AC97_RECMUX_LINE 0x0404 -#define AC97_RECMUX_STEREO_MIX 0x0505 -#define AC97_RECMUX_MONO_MIX 0x0606 -#define AC97_RECMUX_PHONE 0x0707 - -/* general purpose register bit defines */ -#define AC97_GP_LPBK 0x0080 /* Loopback mode */ -#define AC97_GP_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 */ -#define AC97_GP_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic */ -#define AC97_GP_RLBK 0x0400 /* Remote Loopback - Modem line codec */ -#define AC97_GP_LLBK 0x0800 /* Local Loopback - Modem Line codec */ -#define AC97_GP_LD 0x1000 /* Loudness 1=on */ -#define AC97_GP_3D 0x2000 /* 3D Enhancement 1=on */ -#define AC97_GP_ST 0x4000 /* Stereo Enhancement 1=on */ -#define AC97_GP_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */ - -/* extended audio status and control bit defines */ -#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */ -#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */ -#define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */ -#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */ -#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */ -#define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */ -#define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */ -#define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */ -#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */ -#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */ -#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */ -#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */ -#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */ -#define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */ -#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */ -#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */ -#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */ -#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */ - -/* S/PDIF control bit defines */ -#define AC97_SC_PRO 0x0001 /* Professional status */ -#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */ -#define AC97_SC_COPY 0x0004 /* Copyright status */ -#define AC97_SC_PRE 0x0008 /* Preemphasis status */ -#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */ -#define AC97_SC_L 0x0800 /* Generation Level status */ -#define AC97_SC_SPSR_MASK 0xcfff /* S/PDIF Sample Rate bits */ -#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */ -#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */ -#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */ -#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */ -#define AC97_SC_V 0x8000 /* Validity status */ - -/* powerdown control and status bit defines */ - -/* status */ -#define AC97_PWR_MDM 0x0010 /* Modem section ready */ -#define AC97_PWR_REF 0x0008 /* Vref nominal */ -#define AC97_PWR_ANL 0x0004 /* Analog section ready */ -#define AC97_PWR_DAC 0x0002 /* DAC section ready */ -#define AC97_PWR_ADC 0x0001 /* ADC section ready */ - -/* control */ -#define AC97_PWR_PR0 0x0100 /* ADC and Mux powerdown */ -#define AC97_PWR_PR1 0x0200 /* DAC powerdown */ -#define AC97_PWR_PR2 0x0400 /* Output mixer powerdown (Vref on) */ -#define AC97_PWR_PR3 0x0800 /* Output mixer powerdown (Vref off) */ -#define AC97_PWR_PR4 0x1000 /* AC-link powerdown */ -#define AC97_PWR_PR5 0x2000 /* Internal Clk disable */ -#define AC97_PWR_PR6 0x4000 /* HP amp powerdown */ -#define AC97_PWR_PR7 0x8000 /* Modem off - if supported */ - -/* extended audio ID register bit defines */ -#define AC97_EXTID_VRA 0x0001 -#define AC97_EXTID_DRA 0x0002 -#define AC97_EXTID_SPDIF 0x0004 -#define AC97_EXTID_VRM 0x0008 -#define AC97_EXTID_DSA0 0x0010 -#define AC97_EXTID_DSA1 0x0020 -#define AC97_EXTID_CDAC 0x0040 -#define AC97_EXTID_SDAC 0x0080 -#define AC97_EXTID_LDAC 0x0100 -#define AC97_EXTID_AMAP 0x0200 -#define AC97_EXTID_REV0 0x0400 -#define AC97_EXTID_REV1 0x0800 -#define AC97_EXTID_ID0 0x4000 -#define AC97_EXTID_ID1 0x8000 - -/* extended status register bit defines */ -#define AC97_EXTSTAT_VRA 0x0001 -#define AC97_EXTSTAT_DRA 0x0002 -#define AC97_EXTSTAT_SPDIF 0x0004 -#define AC97_EXTSTAT_VRM 0x0008 -#define AC97_EXTSTAT_SPSA0 0x0010 -#define AC97_EXTSTAT_SPSA1 0x0020 -#define AC97_EXTSTAT_CDAC 0x0040 -#define AC97_EXTSTAT_SDAC 0x0080 -#define AC97_EXTSTAT_LDAC 0x0100 -#define AC97_EXTSTAT_MADC 0x0200 -#define AC97_EXTSTAT_SPCV 0x0400 -#define AC97_EXTSTAT_PRI 0x0800 -#define AC97_EXTSTAT_PRJ 0x1000 -#define AC97_EXTSTAT_PRK 0x2000 -#define AC97_EXTSTAT_PRL 0x4000 - -/* extended audio ID register bit defines */ -#define AC97_EXTID_VRA 0x0001 -#define AC97_EXTID_DRA 0x0002 -#define AC97_EXTID_SPDIF 0x0004 -#define AC97_EXTID_VRM 0x0008 -#define AC97_EXTID_DSA0 0x0010 -#define AC97_EXTID_DSA1 0x0020 -#define AC97_EXTID_CDAC 0x0040 -#define AC97_EXTID_SDAC 0x0080 -#define AC97_EXTID_LDAC 0x0100 -#define AC97_EXTID_AMAP 0x0200 -#define AC97_EXTID_REV0 0x0400 -#define AC97_EXTID_REV1 0x0800 -#define AC97_EXTID_ID0 0x4000 -#define AC97_EXTID_ID1 0x8000 - -/* extended status register bit defines */ -#define AC97_EXTSTAT_VRA 0x0001 -#define AC97_EXTSTAT_DRA 0x0002 -#define AC97_EXTSTAT_SPDIF 0x0004 -#define AC97_EXTSTAT_VRM 0x0008 -#define AC97_EXTSTAT_SPSA0 0x0010 -#define AC97_EXTSTAT_SPSA1 0x0020 -#define AC97_EXTSTAT_CDAC 0x0040 -#define AC97_EXTSTAT_SDAC 0x0080 -#define AC97_EXTSTAT_LDAC 0x0100 -#define AC97_EXTSTAT_MADC 0x0200 -#define AC97_EXTSTAT_SPCV 0x0400 -#define AC97_EXTSTAT_PRI 0x0800 -#define AC97_EXTSTAT_PRJ 0x1000 -#define AC97_EXTSTAT_PRK 0x2000 -#define AC97_EXTSTAT_PRL 0x4000 - -/* useful power states */ -#define AC97_PWR_D0 0x0000 /* everything on */ -#define AC97_PWR_D1 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4 -#define AC97_PWR_D2 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 -#define AC97_PWR_D3 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 -#define AC97_PWR_ANLOFF AC97_PWR_PR2|AC97_PWR_PR3 /* analog section off */ - -/* Total number of defined registers. */ -#define AC97_REG_CNT 64 - - -/* OSS interface to the ac97s.. */ -#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\ - SOUND_MASK_LINE|SOUND_MASK_CD|\ - SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\ - SOUND_MASK_LINE1|SOUND_MASK_VIDEO) - -#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \ - SOUND_MASK_BASS|SOUND_MASK_TREBLE|\ - SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\ - SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT) - -#define AC97_RECORD_MASK (SOUND_MASK_MIC|\ - SOUND_MASK_CD|SOUND_MASK_IGAIN|SOUND_MASK_VIDEO|\ - SOUND_MASK_LINE1| SOUND_MASK_LINE|\ - SOUND_MASK_PHONEIN) - -/* original check is not good enough in case FOO is greater than - * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly - * SOUND_MIXER_NRDEVICES elements. - * before matching the given mixer against the bitmask in supported_mixers we - * check if mixer number exceeds maximum allowed size which is as mentioned - * above SOUND_MIXER_NRDEVICES */ -#define supported_mixer(CODEC,FOO) ((FOO >= 0) && \ - (FOO < SOUND_MIXER_NRDEVICES) && \ - (CODEC)->supported_mixers & (1< Date: Tue, 19 Jun 2012 08:32:49 +0200 Subject: [PATCH 2119/6849] iwlwifi: fix 11n_disable EEPROM refactoring regression My commit 26a7ca9a71a ("iwlwifi: refactor EEPROM reading/parsing") broke the 11n_disable module parameter's BIT(0) to disable all HT operation (using the other bits to disable aggregation only was unaffected). Restore this by overriding the SKU when parsing the EEPROM if the module parameter is set. Reported-by: Matthijs Kooijman Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index c87a05cbec12..f10170fe8799 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -853,6 +853,9 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, EEPROM_RADIO_CONFIG); data->sku = iwl_eeprom_query16(eeprom, eeprom_size, EEPROM_SKU_CAP); + if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) + data->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; + data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size, EEPROM_VERSION); -- GitLab From 0d4e07726ea468c0f9bb7f84b02a9f1bfd16b69e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Jun 2012 10:17:12 +0200 Subject: [PATCH 2120/6849] iwlwifi: use minimal time for radio reset scan The effect of using a short single-channel scan to reset the radio is that scanning a channel that isn't in use needs to re-tune the radio. This means that the dwell time is irrelevant, so use a shorter time. While at it, clean up the code for this a bit. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/scan.c | 41 ++++++++++++------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 2f271c96ed39..f5b1452a60b3 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -51,6 +51,9 @@ #define IWL_CHANNEL_TUNE_TIME 5 #define MAX_SCAN_CHANNEL 50 +/* For reset radio, need minimal dwell time only */ +#define IWL_RADIO_RESET_DWELL_TIME 5 + static int iwl_send_scan_abort(struct iwl_priv *priv) { int ret; @@ -469,45 +472,39 @@ static u8 iwl_get_single_channel_number(struct iwl_priv *priv, return 0; } -static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - struct iwl_scan_channel *scan_ch) +static int iwl_get_channel_for_reset_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl_scan_channel *scan_ch) { const struct ieee80211_supported_band *sband; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added = 0; - u16 channel = 0; + u16 channel; sband = iwl_get_hw_mode(priv, band); if (!sband) { IWL_ERR(priv, "invalid band\n"); - return added; + return 0; } - active_dwell = iwl_get_active_dwell_time(priv, band, 0); - passive_dwell = iwl_get_passive_dwell_time(priv, band); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - channel = iwl_get_single_channel_number(priv, band); if (channel) { scan_ch->channel = cpu_to_le16(channel); scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + scan_ch->active_dwell = + cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME); + scan_ch->passive_dwell = + cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME); /* Set txpower levels to defaults */ scan_ch->dsp_atten = 110; if (band == IEEE80211_BAND_5GHZ) scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; else scan_ch->tx_gain = ((1 << 5) | (5 << 3)); - added++; - } else - IWL_ERR(priv, "no valid channel found\n"); - return added; + return 1; + } + + IWL_ERR(priv, "no valid channel found\n"); + return 0; } static int iwl_get_channels_for_scan(struct iwl_priv *priv, @@ -896,7 +893,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) switch (priv->scan_type) { case IWL_SCAN_RADIO_RESET: scan->channel_count = - iwl_get_single_channel_for_scan(priv, vif, band, + iwl_get_channel_for_reset_scan(priv, vif, band, (void *)&scan->data[cmd_len]); break; case IWL_SCAN_NORMAL: -- GitLab From 8d40f4eebf43bd73aa7c6e06665fd7a26012f9c9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 19 Jun 2012 08:42:08 +0200 Subject: [PATCH 2121/6849] iwlwifi: remove sku field from hw_params Now that the eeprom parsing code overrides the sku field directly with 11n_disable parameters, there's no longer a need to keep a copy of this field. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/dev.h | 2 -- drivers/net/wireless/iwlwifi/dvm/lib.c | 2 +- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 4 ++-- drivers/net/wireless/iwlwifi/dvm/main.c | 13 +++++-------- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 4620b657948a..54cf085ddc89 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -568,7 +568,6 @@ enum iwl_scan_type { * * @tx_chains_num: Number of TX chains * @rx_chains_num: Number of RX chains - * @sku: sku read from EEPROM * @ct_kill_threshold: temperature threshold - in hw dependent unit * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit * relevant for 1000, 6000 and up @@ -579,7 +578,6 @@ struct iwl_hw_params { u8 tx_chains_num; u8 rx_chains_num; bool use_rts_for_aggregation; - u16 sku; u32 ct_kill_threshold; u32 ct_kill_exit_threshold; diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 76f259283c3a..207ae91a83aa 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -160,7 +160,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | IWL_PAN_SCD_MULTICAST_MSK; - if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) + if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c57726348ffe..b581f035d4b0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -164,7 +164,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; */ - if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) + if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; @@ -649,7 +649,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); - if (!(priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)) + if (!(priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)) return -EACCES; IWL_DEBUG_MAC80211(priv, "enter\n"); diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index c642c217e29f..abfd7916bde6 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -1187,9 +1187,6 @@ static void iwl_set_hw_params(struct iwl_priv *priv) priv->hw_params.use_rts_for_aggregation = priv->cfg->ht_params->use_rts_for_aggregation; - if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) - priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE; - /* Device-specific setup */ priv->lib->set_hw_params(priv); } @@ -1234,20 +1231,20 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) { u16 radio_cfg; - priv->hw_params.sku = priv->eeprom_data->sku; + priv->eeprom_data->sku = priv->eeprom_data->sku; - if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && + if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && !priv->cfg->ht_params) { IWL_ERR(priv, "Invalid 11n configuration\n"); return -EINVAL; } - if (!priv->hw_params.sku) { + if (!priv->eeprom_data->sku) { IWL_ERR(priv, "Invalid device sku\n"); return -EINVAL; } - IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); + IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); radio_cfg = priv->eeprom_data->radio_cfg; @@ -1453,7 +1450,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ************************/ iwl_set_hw_params(priv); - if (!(priv->hw_params.sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { + if (!(priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; /* -- GitLab From 21cd683d318041c63876b4acbebb3f6d9d80597b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 20 Jun 2012 09:19:32 +0200 Subject: [PATCH 2122/6849] ALSA: hda - Fix the pin nid assignment in patch_hdmi.c This fixes the regression introduced by the commit d0b1252d for refactoring simple_hdmi*(). The pin NID wasn't assigned correctly. Reported-by: Annie Liu Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8891fa658382..72a3b26736ae 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1607,7 +1607,7 @@ static int patch_simple_hdmi(struct hda_codec *codec, spec->num_cvts = 1; spec->num_pins = 1; spec->cvts[0].cvt_nid = cvt_nid; - spec->cvts[0].cvt_nid = pin_nid; + spec->pins[0].pin_nid = pin_nid; spec->pcm_playback = simple_pcm_playback; codec->patch_ops = simple_hdmi_patch_ops; -- GitLab From 25bcde9fa805c2f723aa3a0ed559f5e5472a7afc Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Jun 2012 16:29:52 +0900 Subject: [PATCH 2123/6849] ARM: S5PV210: Add HSOTG support to SMDKV210 Adds S3C-HSOTG support to SMDKV210 board. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/Kconfig | 2 ++ arch/arm/mach-s5pv210/mach-smdkv210.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 88e983b0c82e..77185c38188b 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -152,6 +152,7 @@ config MACH_SMDKV210 select S3C_DEV_I2C1 select S3C_DEV_I2C2 select S3C_DEV_RTC + select S3C_DEV_USB_HSOTG select S3C_DEV_WDT select S5P_DEV_FIMC0 select S5P_DEV_FIMC1 @@ -170,6 +171,7 @@ config MACH_SMDKV210 select S5PV210_SETUP_IDE select S5PV210_SETUP_KEYPAD select S5PV210_SETUP_SDHCI + select S5PV210_SETUP_USB_PHY help Machine support for Samsung SMDKV210 diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 0d7ddec88eb7..c8997bce642d 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include #include "common.h" @@ -203,6 +205,9 @@ static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = { .setup_gpio = s5pv210_fb_gpio_setup_24bpp, }; +/* USB OTG */ +static struct s3c_hsotg_plat smdkv210_hsotg_pdata; + static struct platform_device *smdkv210_devices[] __initdata = { &s3c_device_adc, &s3c_device_cfcon, @@ -216,6 +221,7 @@ static struct platform_device *smdkv210_devices[] __initdata = { &s3c_device_i2c2, &s3c_device_rtc, &s3c_device_ts, + &s3c_device_usb_hsotg, &s3c_device_wdt, &s5p_device_fimc0, &s5p_device_fimc1, @@ -314,6 +320,9 @@ static void __init smdkv210_machine_init(void) samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data); + s3c_hsotg_set_platdata(&smdkv210_hsotg_pdata); + clk_xusbxti.rate = 24000000; + platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices)); } -- GitLab From ccfcf7d151c01969133b5555eed635537c41c944 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 20 Jun 2012 09:30:42 +0200 Subject: [PATCH 2124/6849] ALSA: hda - Add missing snd_hda_jack_detect_enable() for simple_hdmi*() Reported-by: Annie Liu Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 72a3b26736ae..db8f6928f839 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1415,13 +1415,15 @@ static int simple_playback_init(struct hda_codec *codec) int i; for (i = 0; i < spec->num_pins; i++) { - snd_hda_codec_write(codec, spec->pins[i].pin_nid, 0, + hda_nid_t pin = spec->pins[i].pin_nid; + snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); /* some codecs require to unmute the pin */ - if (get_wcaps(codec, spec->pins[i].pin_nid) & AC_WCAP_OUT_AMP) - snd_hda_codec_write(codec, spec->pins[i].pin_nid, 0, + if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_jack_detect_enable(codec, pin, pin); } snd_hda_jack_report_sync(codec); return 0; -- GitLab From adc0fa413917bd973469560388446c52ce43b995 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 18 May 2012 02:07:53 +0000 Subject: [PATCH 2125/6849] igb: Fix incorrect RAR address entries for i210/i211 device. i210/i211 device has only 16 RAR address filters like 82575, instead of 32 like i350. This patch removes the entries for i210/i211 in the get_invariants function which was setting them for 32. This ensures that they will get the default value which is the correct one. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/e1000_82575.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index e65083958421..5e84eaac48c1 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -206,8 +206,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; break; case e1000_i350: - case e1000_i210: - case e1000_i211: mac->rar_entry_count = E1000_RAR_ENTRIES_I350; break; default: -- GitLab From 0e808bcc483773b4bcb45f02792b24ccfa428b68 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 18 May 2012 05:40:46 +0000 Subject: [PATCH 2126/6849] Kconfig: Fix Kconfig for Intel ixgbe and igb PTP support. Fix Kconfig file to make sure that PTP and IGB/IXGBE are both either in-kernel or modules, not mixed. Having the build status mixed causes compile errors. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/Kconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 79b07ec6726f..0cafe4fe9406 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -122,8 +122,10 @@ config IGB_DCA config IGB_PTP bool "PTP Hardware Clock (PHC)" - default y - depends on IGB && PTP_1588_CLOCK + default n + depends on IGB && EXPERIMENTAL + select PPS + select PTP_1588_CLOCK ---help--- Say Y here if you want to use PTP Hardware Clock (PHC) in the driver. Only the basic clock operations have been implemented. @@ -223,7 +225,9 @@ config IXGBE_DCB config IXGBE_PTP bool "PTP Clock Support" default n - depends on IXGBE && PTP_1588_CLOCK + depends on IXGBE && EXPERIMENTAL + select PPS + select PTP_1588_CLOCK ---help--- Say Y here if you want support for 1588 Timestamping with a PHC device, using the PTP 1588 Clock support. This is -- GitLab From 8633c0846160af0b8cfb983bbccd94ae42922af8 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 16 Jun 2012 07:31:19 +0000 Subject: [PATCH 2127/6849] ixgbe: Fix memory leak in ixgbe when receiving traffic on DDP enabled rings This patch fixes a memory leak that was introduced in the 3.4 kernel. The leak occurred when FCoE was enabled and traffic was passed over the FCoE rings reserved for FCoE. The memory leak was due to us not populating the compound page information on the order 1 pages needed for FCoE. Signed-off-by: Alexander Duyck Tested-by: Phil Schmitt Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 17ad6a3c1be1..cbb05d65960f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1148,7 +1148,7 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, /* alloc new page for storage */ if (likely(!page)) { - page = alloc_pages(GFP_ATOMIC | __GFP_COLD, + page = alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; -- GitLab From a5d8f4765f0e92ef027492a8cb979c5b8d45f2c3 Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Wed, 20 Jun 2012 17:05:37 +0900 Subject: [PATCH 2128/6849] ARM: SAMSUNG: Should check for IS_ERR(clk) instead of NULL On the error condition clk_get() returns ERR_PTR(). Signed-off-by: Jonghwan Choi Cc: Stable Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/watchdog-reset.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h index f19aff19205c..bc4db9b04e36 100644 --- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h +++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h @@ -25,7 +25,7 @@ static inline void arch_wdt_reset(void) __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ - if (s3c2410_wdtclk) + if (!IS_ERR(s3c2410_wdtclk)) clk_enable(s3c2410_wdtclk); /* put initial values into count and data */ -- GitLab From 7500673be30f9467cd1a0e065c93e75c5213b44d Mon Sep 17 00:00:00 2001 From: Tushar Dave Date: Tue, 12 Jun 2012 13:03:29 +0000 Subject: [PATCH 2129/6849] e1000: Combining Bitwise OR in one expression. Signed-off-by: Tushar Dave Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 7483ca0a6282..183a4a3224ba 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1078,18 +1078,18 @@ static int __devinit e1000_probe(struct pci_dev *pdev, netdev->priv_flags |= IFF_SUPP_NOFCS; netdev->features |= netdev->hw_features; - netdev->hw_features |= NETIF_F_RXCSUM; - netdev->hw_features |= NETIF_F_RXALL; - netdev->hw_features |= NETIF_F_RXFCS; + netdev->hw_features |= (NETIF_F_RXCSUM | + NETIF_F_RXALL | + NETIF_F_RXFCS); if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; netdev->vlan_features |= NETIF_F_HIGHDMA; } - netdev->vlan_features |= NETIF_F_TSO; - netdev->vlan_features |= NETIF_F_HW_CSUM; - netdev->vlan_features |= NETIF_F_SG; + netdev->vlan_features |= (NETIF_F_TSO | + NETIF_F_HW_CSUM | + NETIF_F_SG); netdev->priv_flags |= IFF_UNICAST_FLT; -- GitLab From f00b0da776fda1abc481578e3932a668f603d72d Mon Sep 17 00:00:00 2001 From: Lior Levy Date: Sat, 4 Jun 2011 06:05:03 +0000 Subject: [PATCH 2130/6849] igb: A fix to VF TX rate limit There is a need to configure MMW_SIZE in register RTTBCNRM with a correct value. For 82576 device, the value should be 0x14. Signed-off-by: Lior Levy Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/e1000_regs.h | 1 + drivers/net/ethernet/intel/igb/igb_main.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h index 35d1e4f2c92c..10efcd88dca0 100644 --- a/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/drivers/net/ethernet/intel/igb/e1000_regs.h @@ -117,6 +117,7 @@ /* TX Rate Limit Registers */ #define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */ +#define E1000_RTTBCNRM 0x3690 /* Tx BCN Rate-scheduler MMW */ #define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */ /* Split and Replication RX Control - RW */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index dd3bfe8cd36c..64090549722d 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6997,6 +6997,11 @@ static void igb_set_vf_rate_limit(struct e1000_hw *hw, int vf, int tx_rate, } wr32(E1000_RTTDQSEL, vf); /* vf X uses queue X */ + /* + * Set global transmit compensation time to the MMW_SIZE in RTTBCNRM + * register. MMW_SIZE=0x014 if 9728-byte jumbo is supported. + */ + wr32(E1000_RTTBCNRM, 0x14); wr32(E1000_RTTBCNRC, bcnrc_val); } -- GitLab From d3eef8c8a033a5ee56ab5d923068eb8cd5d53887 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 16 May 2012 01:46:00 +0000 Subject: [PATCH 2131/6849] igb: Add switch case for supported hardware to igb_ptp_remove. PTP initialization is only done on supported parts, so remove needs same checks or it will cause crashes on systems with igb devices that don't support PTP. This patch adds those checks to the exit function. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_ptp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index d5ee7fa50723..c846ea9131a3 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -330,7 +330,17 @@ void igb_ptp_init(struct igb_adapter *adapter) void igb_ptp_remove(struct igb_adapter *adapter) { - cancel_delayed_work_sync(&adapter->overflow_work); + switch (adapter->hw.mac.type) { + case e1000_i211: + case e1000_i210: + case e1000_i350: + case e1000_82580: + case e1000_82576: + cancel_delayed_work_sync(&adapter->overflow_work); + break; + default: + return; + } if (adapter->ptp_clock) { ptp_clock_unregister(adapter->ptp_clock); -- GitLab From cb41145ee78585282af56a9203f391c0d84366b1 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 4 Apr 2012 17:43:59 +0000 Subject: [PATCH 2132/6849] igb: Support the get_ts_info ethtool method. Based on original patch from Richard Cochran Original patch caused build errors without CONFIG_IGB_1588_CLOCK and CONFIG_PPS enabled, since the added code was not properly wrapped. CC: Richard Cochran Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_ethtool.c | 35 ++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 812d4f963bd1..59d0f04d59af 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -2271,6 +2271,38 @@ static void igb_ethtool_complete(struct net_device *netdev) pm_runtime_put(&adapter->pdev->dev); } +#ifdef CONFIG_IGB_PTP +static int igb_ethtool_get_ts_info(struct net_device *dev, + struct ethtool_ts_info *info) +{ + struct igb_adapter *adapter = netdev_priv(dev); + + info->so_timestamping = + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + if (adapter->ptp_clock) + info->phc_index = ptp_clock_index(adapter->ptp_clock); + else + info->phc_index = -1; + + info->tx_types = + (1 << HWTSTAMP_TX_OFF) | + (1 << HWTSTAMP_TX_ON); + + info->rx_filters = + (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_ALL) | + (1 << HWTSTAMP_FILTER_SOME) | + (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | + (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | + (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); + + return 0; +} + +#endif static const struct ethtool_ops igb_ethtool_ops = { .get_settings = igb_get_settings, .set_settings = igb_set_settings, @@ -2299,6 +2331,9 @@ static const struct ethtool_ops igb_ethtool_ops = { .set_coalesce = igb_set_coalesce, .begin = igb_ethtool_begin, .complete = igb_ethtool_complete, +#ifdef CONFIG_IGB_PTP + .get_ts_info = igb_ethtool_get_ts_info, +#endif }; void igb_set_ethtool_ops(struct net_device *netdev) -- GitLab From b3c185a7614cd95ea9b68d89a8d1ee4227ee9018 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jun 2012 17:29:04 +0900 Subject: [PATCH 2133/6849] sh: pfc: Split out gpio chip support. This implements a bit of rework for the PFC code, making the core itself slightly more pluggable and moving out the gpio chip handling completely. The API is preserved in such a way that platforms that depend on it for early configuration are still able to do so, while making it possible to migrate to alternate interfaces going forward. This is the first step of chainsawing necessary to support the pinctrl API, with the eventual goal being able to decouple pin function state from the gpio API while retaining gpio chip tie-in for gpio pin functions only, relying on the pinctrl/pinmux API for non-gpio function demux. Signed-off-by: Paul Mundt --- drivers/sh/Makefile | 2 +- drivers/sh/pfc-gpio.c | 309 +++++++++++++++++++++++++++++++++ drivers/sh/pfc.c | 376 ++++++++++++----------------------------- include/linux/sh_pfc.h | 37 +++- 4 files changed, 447 insertions(+), 277 deletions(-) create mode 100644 drivers/sh/pfc-gpio.c diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 7139ad2f2086..be5b2934f067 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -6,5 +6,5 @@ obj-y := intc/ obj-$(CONFIG_HAVE_CLK) += clk/ obj-$(CONFIG_MAPLE) += maple/ obj-$(CONFIG_SUPERHYWAY) += superhyway/ -obj-$(CONFIG_GENERIC_GPIO) += pfc.o +obj-$(CONFIG_GENERIC_GPIO) += pfc.o pfc-gpio.o obj-y += pm_runtime.o diff --git a/drivers/sh/pfc-gpio.c b/drivers/sh/pfc-gpio.c new file mode 100644 index 000000000000..d74e5a96024b --- /dev/null +++ b/drivers/sh/pfc-gpio.c @@ -0,0 +1,309 @@ +/* + * SuperH Pin Function Controller GPIO driver. + * + * Copyright (C) 2008 Magnus Damm + * Copyright (C) 2009 - 2012 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +struct sh_pfc_chip { + struct sh_pfc *pfc; + struct gpio_chip gpio_chip; +}; + +static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc) +{ + return container_of(gc, struct sh_pfc_chip, gpio_chip); +} + +static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) +{ + return gpio_to_pfc_chip(gc)->pfc; +} + +static int sh_gpio_request(struct gpio_chip *gc, unsigned offset) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + struct pinmux_data_reg *dummy; + unsigned long flags; + int i, ret, pinmux_type; + + ret = -EINVAL; + + if (!pfc) + goto err_out; + + spin_lock_irqsave(&pfc->lock, flags); + + if ((pfc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) + goto err_unlock; + + /* setup pin function here if no data is associated with pin */ + + if (sh_pfc_get_data_reg(pfc, offset, &dummy, &i) != 0) + pinmux_type = PINMUX_TYPE_FUNCTION; + else + pinmux_type = PINMUX_TYPE_GPIO; + + if (pinmux_type == PINMUX_TYPE_FUNCTION) { + if (sh_pfc_config_gpio(pfc, offset, + pinmux_type, + GPIO_CFG_DRYRUN) != 0) + goto err_unlock; + + if (sh_pfc_config_gpio(pfc, offset, + pinmux_type, + GPIO_CFG_REQ) != 0) + BUG(); + } + + pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + pfc->gpios[offset].flags |= pinmux_type; + + ret = 0; + err_unlock: + spin_unlock_irqrestore(&pfc->lock, flags); + err_out: + return ret; +} + +static void sh_gpio_free(struct gpio_chip *gc, unsigned offset) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int pinmux_type; + + if (!pfc) + return; + + spin_lock_irqsave(&pfc->lock, flags); + + pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE; + sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + pfc->gpios[offset].flags |= PINMUX_TYPE_NONE; + + spin_unlock_irqrestore(&pfc->lock, flags); +} + +static int sh_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int ret; + + spin_lock_irqsave(&pfc->lock, flags); + ret = sh_pfc_set_direction(pfc, offset, PINMUX_TYPE_INPUT); + spin_unlock_irqrestore(&pfc->lock, flags); + + return ret; +} + +static void sh_gpio_set_value(struct sh_pfc *pfc, unsigned gpio, int value) +{ + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (!pfc || sh_pfc_get_data_reg(pfc, gpio, &dr, &bit) != 0) + BUG(); + else + sh_pfc_write_bit(dr, bit, value); +} + +static int sh_gpio_direction_output(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int ret; + + sh_gpio_set_value(pfc, offset, value); + + spin_lock_irqsave(&pfc->lock, flags); + ret = sh_pfc_set_direction(pfc, offset, PINMUX_TYPE_OUTPUT); + spin_unlock_irqrestore(&pfc->lock, flags); + + return ret; +} + +static int sh_gpio_get_value(struct sh_pfc *pfc, unsigned gpio) +{ + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (!pfc || sh_pfc_get_data_reg(pfc, gpio, &dr, &bit) != 0) + return -EINVAL; + + return sh_pfc_read_bit(dr, bit); +} + +static int sh_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + return sh_gpio_get_value(gpio_to_pfc(gc), offset); +} + +static void sh_gpio_set(struct gpio_chip *gc, unsigned offset, int value) +{ + sh_gpio_set_value(gpio_to_pfc(gc), offset, value); +} + +static int sh_gpio_to_irq(struct gpio_chip *gc, unsigned offset) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + pinmux_enum_t enum_id; + pinmux_enum_t *enum_ids; + int i, k, pos; + + pos = 0; + enum_id = 0; + while (1) { + pos = sh_pfc_gpio_to_enum(pfc, offset, pos, &enum_id); + if (pos <= 0 || !enum_id) + break; + + for (i = 0; i < pfc->gpio_irq_size; i++) { + enum_ids = pfc->gpio_irq[i].enum_ids; + for (k = 0; enum_ids[k]; k++) { + if (enum_ids[k] == enum_id) + return pfc->gpio_irq[i].irq; + } + } + } + + return -ENOSYS; +} + +static void sh_pfc_gpio_setup(struct sh_pfc_chip *chip) +{ + struct sh_pfc *pfc = chip->pfc; + struct gpio_chip *gc = &chip->gpio_chip; + + gc->request = sh_gpio_request; + gc->free = sh_gpio_free; + gc->direction_input = sh_gpio_direction_input; + gc->get = sh_gpio_get; + gc->direction_output = sh_gpio_direction_output; + gc->set = sh_gpio_set; + gc->to_irq = sh_gpio_to_irq; + + WARN_ON(pfc->first_gpio != 0); /* needs testing */ + + gc->label = pfc->name; + gc->owner = THIS_MODULE; + gc->base = pfc->first_gpio; + gc->ngpio = (pfc->last_gpio - pfc->first_gpio) + 1; +} + +int sh_pfc_register_gpiochip(struct sh_pfc *pfc) +{ + struct sh_pfc_chip *chip; + int ret; + + chip = kzalloc(sizeof(struct sh_pfc_chip), GFP_KERNEL); + if (unlikely(!chip)) + return -ENOMEM; + + chip->pfc = pfc; + + sh_pfc_gpio_setup(chip); + + ret = gpiochip_add(&chip->gpio_chip); + if (unlikely(ret < 0)) + kfree(chip); + + pr_info("%s handling gpio %d -> %d\n", + pfc->name, pfc->first_gpio, pfc->last_gpio); + + return ret; +} +EXPORT_SYMBOL_GPL(sh_pfc_register_gpiochip); + +static int sh_pfc_gpio_match(struct gpio_chip *gc, void *data) +{ + return !!strstr(gc->label, data); +} + +static int __devinit sh_pfc_gpio_probe(struct platform_device *pdev) +{ + struct sh_pfc_chip *chip; + struct gpio_chip *gc; + + gc = gpiochip_find("_pfc", sh_pfc_gpio_match); + if (unlikely(!gc)) { + pr_err("Cant find gpio chip\n"); + return -ENODEV; + } + + chip = gpio_to_pfc_chip(gc); + platform_set_drvdata(pdev, chip); + + pr_info("attaching to GPIO chip %s\n", chip->pfc->name); + + return 0; +} + +static int __devexit sh_pfc_gpio_remove(struct platform_device *pdev) +{ + struct sh_pfc_chip *chip = platform_get_drvdata(pdev); + int ret; + + ret = gpiochip_remove(&chip->gpio_chip); + if (unlikely(ret < 0)) + return ret; + + kfree(chip); + return 0; +} + +static struct platform_driver sh_pfc_gpio_driver = { + .probe = sh_pfc_gpio_probe, + .remove = __devexit_p(sh_pfc_gpio_remove), + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + }, +}; + +static struct platform_device sh_pfc_gpio_device = { + .name = KBUILD_MODNAME, + .id = -1, +}; + +static int __init sh_pfc_gpio_init(void) +{ + int rc; + + rc = platform_driver_register(&sh_pfc_gpio_driver); + if (likely(!rc)) { + rc = platform_device_register(&sh_pfc_gpio_device); + if (unlikely(rc)) + platform_driver_unregister(&sh_pfc_gpio_driver); + } + + return rc; +} + +static void __exit sh_pfc_gpio_exit(void) +{ + platform_device_unregister(&sh_pfc_gpio_device); + platform_driver_unregister(&sh_pfc_gpio_driver); +} + +module_init(sh_pfc_gpio_init); +module_exit(sh_pfc_gpio_exit); + +MODULE_AUTHOR("Magnus Damm, Paul Mundt"); +MODULE_DESCRIPTION("GPIO driver for SuperH pin function controller"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:pfc-gpio"); diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c index 522c6c46d1be..8a9ae09603d6 100644 --- a/drivers/sh/pfc.c +++ b/drivers/sh/pfc.c @@ -1,7 +1,8 @@ /* - * Pinmuxed GPIO support for SuperH. + * SuperH Pin Function Controller support. * * Copyright (C) 2008 Magnus Damm + * Copyright (C) 2009 - 2012 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -11,70 +12,74 @@ #include #include -#include +#include #include -#include #include #include -#include #include -#include #include #include -static void pfc_iounmap(struct pinmux_info *pip) +static struct sh_pfc *sh_pfc __read_mostly; + +static inline bool sh_pfc_initialized(void) +{ + return !!sh_pfc; +} + +static void pfc_iounmap(struct sh_pfc *pfc) { int k; - for (k = 0; k < pip->num_resources; k++) - if (pip->window[k].virt) - iounmap(pip->window[k].virt); + for (k = 0; k < pfc->num_resources; k++) + if (pfc->window[k].virt) + iounmap(pfc->window[k].virt); - kfree(pip->window); - pip->window = NULL; + kfree(pfc->window); + pfc->window = NULL; } -static int pfc_ioremap(struct pinmux_info *pip) +static int pfc_ioremap(struct sh_pfc *pfc) { struct resource *res; int k; - if (!pip->num_resources) + if (!pfc->num_resources) return 0; - pip->window = kzalloc(pip->num_resources * sizeof(*pip->window), + pfc->window = kzalloc(pfc->num_resources * sizeof(*pfc->window), GFP_NOWAIT); - if (!pip->window) + if (!pfc->window) goto err1; - for (k = 0; k < pip->num_resources; k++) { - res = pip->resource + k; + for (k = 0; k < pfc->num_resources; k++) { + res = pfc->resource + k; WARN_ON(resource_type(res) != IORESOURCE_MEM); - pip->window[k].phys = res->start; - pip->window[k].size = resource_size(res); - pip->window[k].virt = ioremap_nocache(res->start, + pfc->window[k].phys = res->start; + pfc->window[k].size = resource_size(res); + pfc->window[k].virt = ioremap_nocache(res->start, resource_size(res)); - if (!pip->window[k].virt) + if (!pfc->window[k].virt) goto err2; } return 0; err2: - pfc_iounmap(pip); + pfc_iounmap(pfc); err1: return -1; } -static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip, +static void __iomem *pfc_phys_to_virt(struct sh_pfc *pfc, unsigned long address) { struct pfc_window *window; int k; /* scan through physical windows and convert address */ - for (k = 0; k < pip->num_resources; k++) { - window = pip->window + k; + for (k = 0; k < pfc->num_resources; k++) { + window = pfc->window + k; if (address < window->phys) continue; @@ -135,8 +140,7 @@ static void gpio_write_raw_reg(void __iomem *mapped_reg, BUG(); } -static int gpio_read_bit(struct pinmux_data_reg *dr, - unsigned long in_pos) +int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos) { unsigned long pos; @@ -147,9 +151,10 @@ static int gpio_read_bit(struct pinmux_data_reg *dr, return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; } +EXPORT_SYMBOL_GPL(sh_pfc_read_bit); -static void gpio_write_bit(struct pinmux_data_reg *dr, - unsigned long in_pos, unsigned long value) +void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, + unsigned long value) { unsigned long pos; @@ -166,8 +171,9 @@ static void gpio_write_bit(struct pinmux_data_reg *dr, gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); } +EXPORT_SYMBOL_GPL(sh_pfc_write_bit); -static void config_reg_helper(struct pinmux_info *gpioc, +static void config_reg_helper(struct sh_pfc *pfc, struct pinmux_cfg_reg *crp, unsigned long in_pos, void __iomem **mapped_regp, @@ -176,7 +182,7 @@ static void config_reg_helper(struct pinmux_info *gpioc, { int k; - *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg); + *mapped_regp = pfc_phys_to_virt(pfc, crp->reg); if (crp->field_width) { *maskp = (1 << crp->field_width) - 1; @@ -189,14 +195,14 @@ static void config_reg_helper(struct pinmux_info *gpioc, } } -static int read_config_reg(struct pinmux_info *gpioc, +static int read_config_reg(struct sh_pfc *pfc, struct pinmux_cfg_reg *crp, unsigned long field) { void __iomem *mapped_reg; unsigned long mask, pos; - config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos); + config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos); pr_debug("read_reg: addr = %lx, field = %ld, " "r_width = %ld, f_width = %ld\n", @@ -205,14 +211,14 @@ static int read_config_reg(struct pinmux_info *gpioc, return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask; } -static void write_config_reg(struct pinmux_info *gpioc, +static void write_config_reg(struct sh_pfc *pfc, struct pinmux_cfg_reg *crp, unsigned long field, unsigned long value) { void __iomem *mapped_reg; unsigned long mask, pos, data; - config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos); + config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos); pr_debug("write_reg addr = %lx, value = %ld, field = %ld, " "r_width = %ld, f_width = %ld\n", @@ -225,30 +231,30 @@ static void write_config_reg(struct pinmux_info *gpioc, data &= mask; data |= value; - if (gpioc->unlock_reg) - gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg), + if (pfc->unlock_reg) + gpio_write_raw_reg(pfc_phys_to_virt(pfc, pfc->unlock_reg), 32, ~data); gpio_write_raw_reg(mapped_reg, crp->reg_width, data); } -static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) +static int setup_data_reg(struct sh_pfc *pfc, unsigned gpio) { - struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; + struct pinmux_gpio *gpiop = &pfc->gpios[gpio]; struct pinmux_data_reg *data_reg; int k, n; - if (!enum_in_range(gpiop->enum_id, &gpioc->data)) + if (!enum_in_range(gpiop->enum_id, &pfc->data)) return -1; k = 0; while (1) { - data_reg = gpioc->data_regs + k; + data_reg = pfc->data_regs + k; if (!data_reg->reg_width) break; - data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg); + data_reg->mapped_reg = pfc_phys_to_virt(pfc, data_reg->reg); for (n = 0; n < data_reg->reg_width; n++) { if (data_reg->enum_ids[n] == gpiop->enum_id) { @@ -267,17 +273,17 @@ static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) return -1; } -static void setup_data_regs(struct pinmux_info *gpioc) +static void setup_data_regs(struct sh_pfc *pfc) { struct pinmux_data_reg *drp; int k; - for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++) - setup_data_reg(gpioc, k); + for (k = pfc->first_gpio; k <= pfc->last_gpio; k++) + setup_data_reg(pfc, k); k = 0; while (1) { - drp = gpioc->data_regs + k; + drp = pfc->data_regs + k; if (!drp->reg_width) break; @@ -288,23 +294,24 @@ static void setup_data_regs(struct pinmux_info *gpioc) } } -static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio, +int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp) { - struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; + struct pinmux_gpio *gpiop = &pfc->gpios[gpio]; int k, n; - if (!enum_in_range(gpiop->enum_id, &gpioc->data)) + if (!enum_in_range(gpiop->enum_id, &pfc->data)) return -1; k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; - *drp = gpioc->data_regs + k; + *drp = pfc->data_regs + k; *bitp = n; return 0; } +EXPORT_SYMBOL_GPL(sh_pfc_get_data_reg); -static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, +static int get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, struct pinmux_cfg_reg **crp, int *fieldp, int *valuep, unsigned long **cntp) @@ -315,7 +322,7 @@ static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, k = 0; while (1) { - config_reg = gpioc->cfg_regs + k; + config_reg = pfc->cfg_regs + k; r_width = config_reg->reg_width; f_width = config_reg->field_width; @@ -350,15 +357,15 @@ static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, return -1; } -static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio, - int pos, pinmux_enum_t *enum_idp) +int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, + pinmux_enum_t *enum_idp) { - pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id; - pinmux_enum_t *data = gpioc->gpio_data; + pinmux_enum_t enum_id = pfc->gpios[gpio].enum_id; + pinmux_enum_t *data = pfc->gpio_data; int k; - if (!enum_in_range(enum_id, &gpioc->data)) { - if (!enum_in_range(enum_id, &gpioc->mark)) { + if (!enum_in_range(enum_id, &pfc->data)) { + if (!enum_in_range(enum_id, &pfc->mark)) { pr_err("non data/mark enum_id for gpio %d\n", gpio); return -1; } @@ -369,7 +376,7 @@ static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio, return pos + 1; } - for (k = 0; k < gpioc->gpio_data_size; k++) { + for (k = 0; k < pfc->gpio_data_size; k++) { if (data[k] == enum_id) { *enum_idp = data[k + 1]; return k + 1; @@ -379,11 +386,10 @@ static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio, pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio); return -1; } +EXPORT_SYMBOL_GPL(sh_pfc_gpio_to_enum); -enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; - -static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, - int pinmux_type, int cfg_mode) +int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, + int cfg_mode) { struct pinmux_cfg_reg *cr = NULL; pinmux_enum_t enum_id; @@ -398,19 +404,19 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, break; case PINMUX_TYPE_OUTPUT: - range = &gpioc->output; + range = &pfc->output; break; case PINMUX_TYPE_INPUT: - range = &gpioc->input; + range = &pfc->input; break; case PINMUX_TYPE_INPUT_PULLUP: - range = &gpioc->input_pu; + range = &pfc->input_pu; break; case PINMUX_TYPE_INPUT_PULLDOWN: - range = &gpioc->input_pd; + range = &pfc->input_pd; break; default: @@ -422,7 +428,7 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, field = 0; value = 0; while (1) { - pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id); + pos = sh_pfc_gpio_to_enum(pfc, gpio, pos, &enum_id); if (pos <= 0) goto out_err; @@ -430,7 +436,7 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, break; /* first check if this is a function enum */ - in_range = enum_in_range(enum_id, &gpioc->function); + in_range = enum_in_range(enum_id, &pfc->function); if (!in_range) { /* not a function enum */ if (range) { @@ -467,19 +473,19 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, if (!in_range) continue; - if (get_config_reg(gpioc, enum_id, &cr, + if (get_config_reg(pfc, enum_id, &cr, &field, &value, &cntp) != 0) goto out_err; switch (cfg_mode) { case GPIO_CFG_DRYRUN: if (!*cntp || - (read_config_reg(gpioc, cr, field) != value)) + (read_config_reg(pfc, cr, field) != value)) continue; break; case GPIO_CFG_REQ: - write_config_reg(gpioc, cr, field, value); + write_config_reg(pfc, cr, field, value); *cntp = *cntp + 1; break; @@ -493,89 +499,18 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, out_err: return -1; } +EXPORT_SYMBOL_GPL(sh_pfc_config_gpio); -static DEFINE_SPINLOCK(gpio_lock); - -static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip) -{ - return container_of(chip, struct pinmux_info, chip); -} - -static int sh_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - struct pinmux_info *gpioc = chip_to_pinmux(chip); - struct pinmux_data_reg *dummy; - unsigned long flags; - int i, ret, pinmux_type; - - ret = -EINVAL; - - if (!gpioc) - goto err_out; - - spin_lock_irqsave(&gpio_lock, flags); - - if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) - goto err_unlock; - - /* setup pin function here if no data is associated with pin */ - - if (get_data_reg(gpioc, offset, &dummy, &i) != 0) - pinmux_type = PINMUX_TYPE_FUNCTION; - else - pinmux_type = PINMUX_TYPE_GPIO; - - if (pinmux_type == PINMUX_TYPE_FUNCTION) { - if (pinmux_config_gpio(gpioc, offset, - pinmux_type, - GPIO_CFG_DRYRUN) != 0) - goto err_unlock; - - if (pinmux_config_gpio(gpioc, offset, - pinmux_type, - GPIO_CFG_REQ) != 0) - BUG(); - } - - gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; - gpioc->gpios[offset].flags |= pinmux_type; - - ret = 0; - err_unlock: - spin_unlock_irqrestore(&gpio_lock, flags); - err_out: - return ret; -} - -static void sh_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - struct pinmux_info *gpioc = chip_to_pinmux(chip); - unsigned long flags; - int pinmux_type; - - if (!gpioc) - return; - - spin_lock_irqsave(&gpio_lock, flags); - - pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE; - pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE); - gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; - gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE; - - spin_unlock_irqrestore(&gpio_lock, flags); -} - -static int pinmux_direction(struct pinmux_info *gpioc, - unsigned gpio, int new_pinmux_type) +int sh_pfc_set_direction(struct sh_pfc *pfc, unsigned gpio, + int new_pinmux_type) { int pinmux_type; int ret = -EINVAL; - if (!gpioc) + if (!pfc) goto err_out; - pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; + pinmux_type = pfc->gpios[gpio].flags & PINMUX_FLAG_TYPE; switch (pinmux_type) { case PINMUX_TYPE_GPIO: @@ -584,156 +519,55 @@ static int pinmux_direction(struct pinmux_info *gpioc, case PINMUX_TYPE_INPUT: case PINMUX_TYPE_INPUT_PULLUP: case PINMUX_TYPE_INPUT_PULLDOWN: - pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_gpio(pfc, gpio, pinmux_type, GPIO_CFG_FREE); break; default: goto err_out; } - if (pinmux_config_gpio(gpioc, gpio, + if (sh_pfc_config_gpio(pfc, gpio, new_pinmux_type, GPIO_CFG_DRYRUN) != 0) goto err_out; - if (pinmux_config_gpio(gpioc, gpio, + if (sh_pfc_config_gpio(pfc, gpio, new_pinmux_type, GPIO_CFG_REQ) != 0) BUG(); - gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; - gpioc->gpios[gpio].flags |= new_pinmux_type; + pfc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; + pfc->gpios[gpio].flags |= new_pinmux_type; ret = 0; err_out: return ret; } +EXPORT_SYMBOL_GPL(sh_pfc_set_direction); -static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +int register_sh_pfc(struct sh_pfc *pfc) { - struct pinmux_info *gpioc = chip_to_pinmux(chip); - unsigned long flags; + int (*initroutine)(struct sh_pfc *) = NULL; int ret; - spin_lock_irqsave(&gpio_lock, flags); - ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT); - spin_unlock_irqrestore(&gpio_lock, flags); - - return ret; -} - -static void sh_gpio_set_value(struct pinmux_info *gpioc, - unsigned gpio, int value) -{ - struct pinmux_data_reg *dr = NULL; - int bit = 0; - - if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) - BUG(); - else - gpio_write_bit(dr, bit, value); -} + if (sh_pfc) + return -EBUSY; -static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct pinmux_info *gpioc = chip_to_pinmux(chip); - unsigned long flags; - int ret; - - sh_gpio_set_value(gpioc, offset, value); - spin_lock_irqsave(&gpio_lock, flags); - ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT); - spin_unlock_irqrestore(&gpio_lock, flags); - - return ret; -} - -static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio) -{ - struct pinmux_data_reg *dr = NULL; - int bit = 0; - - if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) - return -EINVAL; - - return gpio_read_bit(dr, bit); -} - -static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - return sh_gpio_get_value(chip_to_pinmux(chip), offset); -} - -static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - sh_gpio_set_value(chip_to_pinmux(chip), offset, value); -} - -static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct pinmux_info *gpioc = chip_to_pinmux(chip); - pinmux_enum_t enum_id; - pinmux_enum_t *enum_ids; - int i, k, pos; - - pos = 0; - enum_id = 0; - while (1) { - pos = get_gpio_enum_id(gpioc, offset, pos, &enum_id); - if (pos <= 0 || !enum_id) - break; - - for (i = 0; i < gpioc->gpio_irq_size; i++) { - enum_ids = gpioc->gpio_irq[i].enum_ids; - for (k = 0; enum_ids[k]; k++) { - if (enum_ids[k] == enum_id) - return gpioc->gpio_irq[i].irq; - } - } - } - - return -ENOSYS; -} - -int register_pinmux(struct pinmux_info *pip) -{ - struct gpio_chip *chip = &pip->chip; - int ret; - - pr_info("%s handling gpio %d -> %d\n", - pip->name, pip->first_gpio, pip->last_gpio); - - ret = pfc_ioremap(pip); - if (ret < 0) + ret = pfc_ioremap(pfc); + if (unlikely(ret < 0)) return ret; - setup_data_regs(pip); - - chip->request = sh_gpio_request; - chip->free = sh_gpio_free; - chip->direction_input = sh_gpio_direction_input; - chip->get = sh_gpio_get; - chip->direction_output = sh_gpio_direction_output; - chip->set = sh_gpio_set; - chip->to_irq = sh_gpio_to_irq; - - WARN_ON(pip->first_gpio != 0); /* needs testing */ + spin_lock_init(&pfc->lock); - chip->label = pip->name; - chip->owner = THIS_MODULE; - chip->base = pip->first_gpio; - chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1; + setup_data_regs(pfc); - ret = gpiochip_add(chip); - if (ret < 0) - pfc_iounmap(pip); + sh_pfc = pfc; + pr_info("%s support registered\n", pfc->name); - return ret; -} + initroutine = symbol_request(sh_pfc_register_gpiochip); + if (initroutine) { + (*initroutine)(pfc); + symbol_put_addr(initroutine); + } -int unregister_pinmux(struct pinmux_info *pip) -{ - pr_info("%s deregistering\n", pip->name); - pfc_iounmap(pip); - return gpiochip_remove(&pip->chip); + return 0; } diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h index 5c15aed9c4b2..95dad340794a 100644 --- a/include/linux/sh_pfc.h +++ b/include/linux/sh_pfc.h @@ -89,7 +89,7 @@ struct pfc_window { unsigned long size; }; -struct pinmux_info { +struct sh_pfc { char *name; pinmux_enum_t reserved_id; struct pinmux_range data; @@ -112,17 +112,44 @@ struct pinmux_info { struct pinmux_irq *gpio_irq; unsigned int gpio_irq_size; + spinlock_t lock; + struct resource *resource; unsigned int num_resources; struct pfc_window *window; unsigned long unlock_reg; - - struct gpio_chip chip; }; -int register_pinmux(struct pinmux_info *pip); -int unregister_pinmux(struct pinmux_info *pip); +/* XXX compat for now */ +#define pinmux_info sh_pfc + +/* drivers/sh/pfc-gpio.c */ +int sh_pfc_register_gpiochip(struct sh_pfc *pfc); + +/* drivers/sh/pfc.c */ +int register_sh_pfc(struct sh_pfc *pfc); + +int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos); +void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, + unsigned long value); +int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, + struct pinmux_data_reg **drp, int *bitp); +int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, + pinmux_enum_t *enum_idp); +int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, + int cfg_mode); +int sh_pfc_set_direction(struct sh_pfc *pfc, unsigned gpio, + int new_pinmux_type); + +/* xxx */ +static inline int register_pinmux(struct pinmux_info *pip) +{ + struct sh_pfc *pfc = pip; + return register_sh_pfc(pfc); +} + +enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; /* helper macro for port */ #define PORT_1(fn, pfx, sfx) fn(pfx, sfx) -- GitLab From 374a542dee0a10c5f81edc2af17a97b06805ecd9 Mon Sep 17 00:00:00 2001 From: Matthew Vick Date: Fri, 18 May 2012 04:54:58 +0000 Subject: [PATCH 2134/6849] igb: Streamline RSS queue and queue pairing assignment logic. Rather than spread out the complexity of the RSS queue and queue pairing assignment logic, place it all in one location for simplicity and readability. Signed-off-by: Matthew Vick Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb.h | 9 +-- drivers/net/ethernet/intel/igb/igb_main.c | 79 +++++++++++++++-------- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index ae6d3f393a54..3ced7b546f7f 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -65,13 +65,10 @@ struct igb_adapter; #define MAX_Q_VECTORS 8 /* Transmit and receive queues */ -#define IGB_MAX_RX_QUEUES ((adapter->vfs_allocated_count ? 2 : \ - (hw->mac.type > e1000_82575 ? 8 : 4))) -#define IGB_MAX_RX_QUEUES_I210 4 +#define IGB_MAX_RX_QUEUES 8 +#define IGB_MAX_RX_QUEUES_82575 4 #define IGB_MAX_RX_QUEUES_I211 2 -#define IGB_MAX_TX_QUEUES 16 -#define IGB_MAX_TX_QUEUES_I210 4 -#define IGB_MAX_TX_QUEUES_I211 2 +#define IGB_MAX_TX_QUEUES 8 #define IGB_MAX_VF_MC_ENTRIES 30 #define IGB_MAX_VF_FUNCTIONS 8 #define IGB_MAX_VFTA_ENTRIES 128 diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 64090549722d..a7c9c5d77e0b 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1048,11 +1048,6 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter) if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) numvecs += adapter->num_tx_queues; - /* i210 and i211 can only have 4 MSIX vectors for rx/tx queues. */ - if ((adapter->hw.mac.type == e1000_i210) - || (adapter->hw.mac.type == e1000_i211)) - numvecs = 4; - /* store the number of vectors reserved for queues */ adapter->num_q_vectors = numvecs; @@ -2338,6 +2333,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; + u32 max_rss_queues; pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); @@ -2370,40 +2366,69 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) } else adapter->vfs_allocated_count = max_vfs; break; - case e1000_i210: - case e1000_i211: - adapter->vfs_allocated_count = 0; - break; default: break; } #endif /* CONFIG_PCI_IOV */ + + /* Determine the maximum number of RSS queues supported. */ switch (hw->mac.type) { + case e1000_i211: + max_rss_queues = IGB_MAX_RX_QUEUES_I211; + break; + case e1000_82575: case e1000_i210: - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I210, - num_online_cpus()); + max_rss_queues = IGB_MAX_RX_QUEUES_82575; + break; + case e1000_i350: + /* I350 cannot do RSS and SR-IOV at the same time */ + if (!!adapter->vfs_allocated_count) { + max_rss_queues = 1; + break; + } + /* fall through */ + case e1000_82576: + if (!!adapter->vfs_allocated_count) { + max_rss_queues = 2; + break; + } + /* fall through */ + case e1000_82580: + default: + max_rss_queues = IGB_MAX_RX_QUEUES; break; + } + + adapter->rss_queues = min_t(u32, max_rss_queues, num_online_cpus()); + + /* Determine if we need to pair queues. */ + switch (hw->mac.type) { + case e1000_82575: case e1000_i211: - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I211, - num_online_cpus()); + /* Device supports enough interrupts without queue pairing. */ break; + case e1000_82576: + /* + * If VFs are going to be allocated with RSS queues then we + * should pair the queues in order to conserve interrupts due + * to limited supply. + */ + if ((adapter->rss_queues > 1) && + (adapter->vfs_allocated_count > 6)) + adapter->flags |= IGB_FLAG_QUEUE_PAIRS; + /* fall through */ + case e1000_82580: + case e1000_i350: + case e1000_i210: default: - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, - num_online_cpus()); + /* + * If rss_queues > half of max_rss_queues, pair the queues in + * order to conserve interrupts due to limited supply. + */ + if (adapter->rss_queues > (max_rss_queues / 2)) + adapter->flags |= IGB_FLAG_QUEUE_PAIRS; break; } - /* i350 cannot do RSS and SR-IOV at the same time */ - if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count) - adapter->rss_queues = 1; - - /* - * if rss_queues > 4 or vfs are going to be allocated with rss_queues - * then we should combine the queues into a queue pair in order to - * conserve interrupts due to limited supply - */ - if ((adapter->rss_queues > 4) || - ((adapter->rss_queues > 1) && (adapter->vfs_allocated_count > 6))) - adapter->flags |= IGB_FLAG_QUEUE_PAIRS; /* Setup and initialize a copy of the hw vlan table array */ adapter->shadow_vfta = kzalloc(sizeof(u32) * -- GitLab From d67974f0deb1f309fc13821f45e52c63402bfb24 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Thu, 14 Jun 2012 16:04:19 +0000 Subject: [PATCH 2135/6849] igb: Update firmware info output Our NVM image creation tools have evolved over the years and there are multiple versions contained in them, depending on the tool used to create them. This patch outputs the NVM versions available in ethtool -i output. rc2: (not sure why others show in log but not in the message) Added additional call to igb_set_fw_version per Community feedback. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb.h | 16 +++++ drivers/net/ethernet/intel/igb/igb_ethtool.c | 17 +++-- drivers/net/ethernet/intel/igb/igb_main.c | 66 ++++++++++++++++++++ 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 3ced7b546f7f..9e572dd29ab2 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -75,6 +75,20 @@ struct igb_adapter; #define IGB_82576_VF_DEV_ID 0x10CA #define IGB_I350_VF_DEV_ID 0x1520 +/* NVM version defines */ +#define IGB_MAJOR_MASK 0xF000 +#define IGB_MINOR_MASK 0x0FF0 +#define IGB_BUILD_MASK 0x000F +#define IGB_COMB_VER_MASK 0x00FF +#define IGB_MAJOR_SHIFT 12 +#define IGB_MINOR_SHIFT 4 +#define IGB_COMB_VER_SHFT 8 +#define IGB_NVM_VER_INVALID 0xFFFF +#define IGB_ETRACK_SHIFT 16 +#define NVM_ETRACK_WORD 0x0042 +#define NVM_COMB_VER_OFF 0x0083 +#define NVM_COMB_VER_PTR 0x003d + struct vf_data_storage { unsigned char vf_mac_addresses[ETH_ALEN]; u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES]; @@ -368,6 +382,7 @@ struct igb_adapter { spinlock_t tmreg_lock; struct cyclecounter cc; struct timecounter tc; + char fw_version[32]; }; #define IGB_FLAG_HAS_MSI (1 << 0) @@ -417,6 +432,7 @@ extern void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *); extern bool igb_has_link(struct igb_adapter *adapter); extern void igb_set_ethtool_ops(struct net_device *); extern void igb_power_up_link(struct igb_adapter *); +extern void igb_set_fw_version(struct igb_adapter *); #ifdef CONFIG_IGB_PTP extern void igb_ptp_init(struct igb_adapter *adapter); extern void igb_ptp_remove(struct igb_adapter *adapter); diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 59d0f04d59af..a19c84cad0e9 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -710,6 +710,7 @@ static int igb_set_eeprom(struct net_device *netdev, if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG))) hw->nvm.ops.update(hw); + igb_set_fw_version(adapter); kfree(eeprom_buff); return ret_val; } @@ -718,20 +719,16 @@ static void igb_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) { struct igb_adapter *adapter = netdev_priv(netdev); - u16 eeprom_data; strlcpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver)); strlcpy(drvinfo->version, igb_driver_version, sizeof(drvinfo->version)); - /* EEPROM image version # is reported as firmware version # for - * 82575 controllers */ - adapter->hw.nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data); - snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d-%d", - (eeprom_data & 0xF000) >> 12, - (eeprom_data & 0x0FF0) >> 4, - eeprom_data & 0x000F); - + /* + * EEPROM image version # is reported as firmware version # for + * 82575 controllers + */ + strlcpy(drvinfo->fw_version, adapter->fw_version, + sizeof(drvinfo->fw_version)); strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), sizeof(drvinfo->bus_info)); drvinfo->n_stats = IGB_STATS_LEN; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index a7c9c5d77e0b..1e0b94ba2ef1 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1815,6 +1815,69 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_set_features = igb_set_features, }; +/** + * igb_set_fw_version - Configure version string for ethtool + * @adapter: adapter struct + * + **/ +void igb_set_fw_version(struct igb_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset; + u16 major, build, patch, fw_version; + u32 etrack_id; + + hw->nvm.ops.read(hw, 5, 1, &fw_version); + if (adapter->hw.mac.type != e1000_i211) { + hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh); + hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl); + etrack_id = (eeprom_verh << IGB_ETRACK_SHIFT) | eeprom_verl; + + /* combo image version needs to be found */ + hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset); + if ((comb_offset != 0x0) && + (comb_offset != IGB_NVM_VER_INVALID)) { + hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset + + 1), 1, &comb_verh); + hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset), + 1, &comb_verl); + + /* Only display Option Rom if it exists and is valid */ + if ((comb_verh && comb_verl) && + ((comb_verh != IGB_NVM_VER_INVALID) && + (comb_verl != IGB_NVM_VER_INVALID))) { + major = comb_verl >> IGB_COMB_VER_SHFT; + build = (comb_verl << IGB_COMB_VER_SHFT) | + (comb_verh >> IGB_COMB_VER_SHFT); + patch = comb_verh & IGB_COMB_VER_MASK; + snprintf(adapter->fw_version, + sizeof(adapter->fw_version), + "%d.%d%d, 0x%08x, %d.%d.%d", + (fw_version & IGB_MAJOR_MASK) >> + IGB_MAJOR_SHIFT, + (fw_version & IGB_MINOR_MASK) >> + IGB_MINOR_SHIFT, + (fw_version & IGB_BUILD_MASK), + etrack_id, major, build, patch); + goto out; + } + } + snprintf(adapter->fw_version, sizeof(adapter->fw_version), + "%d.%d%d, 0x%08x", + (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, + (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, + (fw_version & IGB_BUILD_MASK), etrack_id); + } else { + snprintf(adapter->fw_version, sizeof(adapter->fw_version), + "%d.%d%d", + (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, + (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, + (fw_version & IGB_BUILD_MASK)); + } +out: + return; +} + /** * igb_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -2025,6 +2088,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, goto err_eeprom; } + /* get firmware version for ethtool -i */ + igb_set_fw_version(adapter); + setup_timer(&adapter->watchdog_timer, igb_watchdog, (unsigned long) adapter); setup_timer(&adapter->phy_info_timer, igb_update_phy_info, -- GitLab From 200e5fd50ee80ec6ab3156bdbc46a41da0a82d10 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Thu, 31 May 2012 23:39:30 +0000 Subject: [PATCH 2136/6849] igb: Version bump This patch updates the igb version to 4.0.1. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 1e0b94ba2ef1..01ced68d3aac 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -59,9 +59,9 @@ #endif #include "igb.h" -#define MAJ 3 -#define MIN 4 -#define BUILD 7 +#define MAJ 4 +#define MIN 0 +#define BUILD 1 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ __stringify(BUILD) "-k" char igb_driver_name[] = "igb"; -- GitLab From a49fda3eaa4fe70fdd14681060a7c6c6246dc927 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Fri, 8 Jun 2012 06:59:09 +0000 Subject: [PATCH 2137/6849] ixgbe: add support for 1G SX modules This patch adds support for 1G Fiber PHY modules (SFP+ modules). This support comes along side support for 1G Copper PHY modules, but uses a different PHY type (ixgbe_sfp_type_1g_sx_core). Signed-off-by: Jacob Keller Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_82599.c | 4 +++- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 23 +++++++++++++++---- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 2 ++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index dee64d2703f0..e7dddfd97cb9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -241,7 +241,9 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, /* Determine 1G link capabilities off of SFP+ type */ if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || - hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) { + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { *speed = IXGBE_LINK_SPEED_1GB_FULL; *negotiation = true; goto out; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index 24117709d6a2..71659edf81aa 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -907,6 +907,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) * 8 SFP_act_lmt_DA_CORE1 - 82599-specific * 9 SFP_1g_cu_CORE0 - 82599-specific * 10 SFP_1g_cu_CORE1 - 82599-specific + * 11 SFP_1g_sx_CORE0 - 82599-specific + * 12 SFP_1g_sx_CORE1 - 82599-specific */ if (hw->mac.type == ixgbe_mac_82598EB) { if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) @@ -957,6 +959,13 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) else hw->phy.sfp_type = ixgbe_sfp_type_1g_cu_core1; + } else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_1g_sx_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_sx_core1; } else { hw->phy.sfp_type = ixgbe_sfp_type_unknown; } @@ -1049,7 +1058,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) /* Verify supported 1G SFP modules */ if (comp_codes_10g == 0 && !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || - hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0)) { + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { hw->phy.type = ixgbe_phy_sfp_unsupported; status = IXGBE_ERR_SFP_NOT_SUPPORTED; goto out; @@ -1064,7 +1075,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->mac.ops.get_device_caps(hw, &enforce_sfp); if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1))) { + (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) || + (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0) || + (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1))) { /* Make sure we're a supported PHY type */ if (hw->phy.type == ixgbe_phy_sfp_intel) { status = 0; @@ -1128,10 +1141,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, * SR modules */ if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || - sfp_type == ixgbe_sfp_type_1g_cu_core0) + sfp_type == ixgbe_sfp_type_1g_cu_core0 || + sfp_type == ixgbe_sfp_type_1g_sx_core0) sfp_type = ixgbe_sfp_type_srlr_core0; else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || - sfp_type == ixgbe_sfp_type_1g_cu_core1) + sfp_type == ixgbe_sfp_type_1g_cu_core1 || + sfp_type == ixgbe_sfp_type_1g_sx_core1) sfp_type = ixgbe_sfp_type_srlr_core1; /* Read offset to PHY init contents */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 1085c0739a3c..7416d22ec227 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -2604,6 +2604,8 @@ enum ixgbe_sfp_type { ixgbe_sfp_type_da_act_lmt_core1 = 8, ixgbe_sfp_type_1g_cu_core0 = 9, ixgbe_sfp_type_1g_cu_core1 = 10, + ixgbe_sfp_type_1g_sx_core0 = 11, + ixgbe_sfp_type_1g_sx_core1 = 12, ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; -- GitLab From db01896398ae6beba41fc14f1a90d55fd21e6738 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Fri, 8 Jun 2012 06:59:17 +0000 Subject: [PATCH 2138/6849] ixgbe: clean up ixgbe_get_settings ethtool function This patch cleans up the method used for determining the link speed of devices. The old method re-wrote some logic already existing in a mac.ops function which should be used instead. The result is much simpler to understand and removes a strange double-check of logic, as well as reducing code redundancy. Signed-off-by: Jacob Keller Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 147 ++++++++---------- 1 file changed, 62 insertions(+), 85 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 3178f1ec3711..bbc7da5cdb4d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -154,100 +154,60 @@ static int ixgbe_get_settings(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; + ixgbe_link_speed supported_link; u32 link_speed = 0; + bool autoneg; bool link_up; - ecmd->supported = SUPPORTED_10000baseT_Full; - ecmd->autoneg = AUTONEG_ENABLE; - ecmd->transceiver = XCVR_EXTERNAL; - if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.multispeed_fiber)) { - ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg); - - switch (hw->mac.type) { - case ixgbe_mac_X540: - ecmd->supported |= SUPPORTED_100baseT_Full; - break; - default: - break; - } - - ecmd->advertising = ADVERTISED_Autoneg; - if (hw->phy.autoneg_advertised) { - if (hw->phy.autoneg_advertised & - IXGBE_LINK_SPEED_100_FULL) - ecmd->advertising |= ADVERTISED_100baseT_Full; - if (hw->phy.autoneg_advertised & - IXGBE_LINK_SPEED_10GB_FULL) - ecmd->advertising |= ADVERTISED_10000baseT_Full; - if (hw->phy.autoneg_advertised & - IXGBE_LINK_SPEED_1GB_FULL) - ecmd->advertising |= ADVERTISED_1000baseT_Full; - } else { - /* - * Default advertised modes in case - * phy.autoneg_advertised isn't set. - */ - ecmd->advertising |= (ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full); - if (hw->mac.type == ixgbe_mac_X540) - ecmd->advertising |= ADVERTISED_100baseT_Full; - } - - if (hw->phy.media_type == ixgbe_media_type_copper) { - ecmd->supported |= SUPPORTED_TP; - ecmd->advertising |= ADVERTISED_TP; - ecmd->port = PORT_TP; - } else { - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising |= ADVERTISED_FIBRE; - ecmd->port = PORT_FIBRE; - } - } else if (hw->phy.media_type == ixgbe_media_type_backplane) { - /* Set as FIBRE until SERDES defined in kernel */ - if (hw->device_id == IXGBE_DEV_ID_82598_BX) { - ecmd->supported = (SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE); - ecmd->advertising = (ADVERTISED_1000baseT_Full | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; - ecmd->autoneg = AUTONEG_DISABLE; - } else if ((hw->device_id == IXGBE_DEV_ID_82599_COMBO_BACKPLANE) || - (hw->device_id == IXGBE_DEV_ID_82599_KX4_MEZZ)) { - ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE); - ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; - } else { - ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE); - ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; - } + hw->mac.ops.get_link_capabilities(hw, &supported_link, &autoneg); + + /* set the supported link speeds */ + if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) + ecmd->supported |= SUPPORTED_10000baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_1GB_FULL) + ecmd->supported |= SUPPORTED_1000baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_100_FULL) + ecmd->supported |= SUPPORTED_100baseT_Full; + + /* set the advertised speeds */ + if (hw->phy.autoneg_advertised) { + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + ecmd->advertising |= ADVERTISED_10000baseT_Full; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + ecmd->advertising |= ADVERTISED_1000baseT_Full; } else { - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; - ecmd->autoneg = AUTONEG_DISABLE; + /* default modes in case phy.autoneg_advertised isn't set */ + if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) + ecmd->advertising |= ADVERTISED_10000baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_1GB_FULL) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_100_FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; } - /* Get PHY type */ + if (autoneg) { + ecmd->supported |= SUPPORTED_Autoneg; + ecmd->advertising |= ADVERTISED_Autoneg; + ecmd->autoneg = AUTONEG_ENABLE; + } else + ecmd->autoneg = AUTONEG_DISABLE; + + ecmd->transceiver = XCVR_EXTERNAL; + + /* Determine the remaining settings based on the PHY type. */ switch (adapter->hw.phy.type) { case ixgbe_phy_tn: case ixgbe_phy_aq: case ixgbe_phy_cu_unknown: - /* Copper 10G-BASET */ + ecmd->supported |= SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; break; case ixgbe_phy_qt: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; break; case ixgbe_phy_nl: @@ -257,42 +217,59 @@ static int ixgbe_get_settings(struct net_device *netdev, case ixgbe_phy_sfp_avago: case ixgbe_phy_sfp_intel: case ixgbe_phy_sfp_unknown: - switch (adapter->hw.phy.sfp_type) { /* SFP+ devices, further checking needed */ + switch (adapter->hw.phy.sfp_type) { case ixgbe_sfp_type_da_cu: case ixgbe_sfp_type_da_cu_core0: case ixgbe_sfp_type_da_cu_core1: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_DA; break; case ixgbe_sfp_type_sr: case ixgbe_sfp_type_lr: case ixgbe_sfp_type_srlr_core0: case ixgbe_sfp_type_srlr_core1: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; break; case ixgbe_sfp_type_not_present: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_NONE; break; case ixgbe_sfp_type_1g_cu_core0: case ixgbe_sfp_type_1g_cu_core1: + ecmd->supported |= SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; - ecmd->supported = SUPPORTED_TP; - ecmd->advertising = (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); + break; + case ixgbe_sfp_type_1g_sx_core0: + case ixgbe_sfp_type_1g_sx_core1: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_FIBRE; break; case ixgbe_sfp_type_unknown: default: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_OTHER; break; } break; case ixgbe_phy_xaui: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_NONE; break; case ixgbe_phy_unknown: case ixgbe_phy_generic: case ixgbe_phy_sfp_unsupported: default: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_OTHER; break; } -- GitLab From 559cef996d2e4c9b652a53bb3a53e5787e247f57 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 18 Jun 2012 19:03:52 +0530 Subject: [PATCH 2139/6849] mac80211: cleanup offchannel_ps_enable argument The 'tell_ap' argument is always true. So that remove it and simplify the function. Signed-off-by: Rajkumar Manoharan Signed-off-by: Johannes Berg --- net/mac80211/offchannel.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index fcb01ee8ee7b..febce7fb7bb1 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -25,8 +25,7 @@ * because we *may* be doing work on-operating channel, and want our * hardware unconditionally awake, but still let the AP send us normal frames. */ -static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, - bool tell_ap) +static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; @@ -47,8 +46,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); } - if (tell_ap && (!local->offchannel_ps_enabled || - !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))) + if (!local->offchannel_ps_enabled || + !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) /* * If power save was enabled, no need to send a nullfunc * frame because AP knows that we are sleeping. But if the @@ -133,7 +132,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, if (offchannel_ps_enable && (sdata->vif.type == NL80211_IFTYPE_STATION) && sdata->u.mgd.associated) - ieee80211_offchannel_ps_enable(sdata, true); + ieee80211_offchannel_ps_enable(sdata); } } mutex_unlock(&local->iflist_mtx); -- GitLab From 6df653c71e8168e1df01118cc85cd84d0deeb583 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 18 Jun 2012 15:52:51 +0300 Subject: [PATCH 2140/6849] mac80211: initialize sta pointer to avoid false-positive warning Some compilers (eg. gcc 4.4.1 for ARM) report a false positive warning in mlme.c: net/mac80211/mlme.c: In function 'ieee80211_prep_connection': net/mac80211/mlme.c:3035: warning: 'sta' may be used uninitialized in this function This is a false positive because the place where 'sta' is used is inside an if with the same condition of where it is set: [...] if (!have_sta) { sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); if (!sta) return -ENOMEM; } [...] if (!have_sta) { [...] sta->sta.supp_rates[cbss->channel->band] = rates; [...] For some reason the compiler doesn't understand this and warns. While this is not a problem in the code itself, we can avoid polluting the build logs with false positives by setting sta to NULL on declaration and checking for sta instead of !have_sta in the second if. Reported-by: Tony Lindgren Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0f45d02e0ba7..fa927c6aa14b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3012,7 +3012,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_bss *bss = (void *)cbss->priv; - struct sta_info *sta; + struct sta_info *sta = NULL; bool have_sta = false; int err; int ht_cfreq; @@ -3102,7 +3102,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, local->oper_channel = cbss->channel; ieee80211_hw_config(local, 0); - if (!have_sta) { + if (sta) { u32 rates = 0, basic_rates = 0; bool have_higher_than_11mbit; int min_rate = INT_MAX, min_rate_index = -1; -- GitLab From a9455408b09395ecf4008bd998516ce2e9551bbc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jun 2012 13:32:49 +0200 Subject: [PATCH 2141/6849] cfg80211: make some functions static Some of the functions to retrieve a device can be static as they're used only in nl80211. Signed-off-by: Johannes Berg --- net/wireless/core.c | 63 -------------------------------- net/wireless/core.h | 26 -------------- net/wireless/nl80211.c | 82 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 89 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index a87d43552974..907f62c80e28 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -96,69 +96,6 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) return &rdev->wiphy; } -/* requires cfg80211_mutex to be held! */ -struct cfg80211_registered_device * -__cfg80211_rdev_from_info(struct genl_info *info) -{ - int ifindex; - struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL; - struct net_device *dev; - int err = -EINVAL; - - assert_cfg80211_lock(); - - if (info->attrs[NL80211_ATTR_WIPHY]) { - bywiphyidx = cfg80211_rdev_by_wiphy_idx( - nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); - err = -ENODEV; - } - - if (info->attrs[NL80211_ATTR_IFINDEX]) { - ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); - dev = dev_get_by_index(genl_info_net(info), ifindex); - if (dev) { - if (dev->ieee80211_ptr) - byifidx = - wiphy_to_dev(dev->ieee80211_ptr->wiphy); - dev_put(dev); - } - err = -ENODEV; - } - - if (bywiphyidx && byifidx) { - if (bywiphyidx != byifidx) - return ERR_PTR(-EINVAL); - else - return bywiphyidx; /* == byifidx */ - } - if (bywiphyidx) - return bywiphyidx; - - if (byifidx) - return byifidx; - - return ERR_PTR(err); -} - -struct cfg80211_registered_device * -cfg80211_get_dev_from_info(struct genl_info *info) -{ - struct cfg80211_registered_device *rdev; - - mutex_lock(&cfg80211_mutex); - rdev = __cfg80211_rdev_from_info(info); - - /* if it is not an error we grab the lock on - * it to assure it won't be going away while - * we operate on it */ - if (!IS_ERR(rdev)) - mutex_lock(&rdev->mtx); - - mutex_unlock(&cfg80211_mutex); - - return rdev; -} - struct cfg80211_registered_device * cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) { diff --git a/net/wireless/core.h b/net/wireless/core.h index 9348a47562a4..609a579255ac 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -159,32 +159,6 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); int get_wiphy_idx(struct wiphy *wiphy); -struct cfg80211_registered_device * -__cfg80211_rdev_from_info(struct genl_info *info); - -/* - * This function returns a pointer to the driver - * that the genl_info item that is passed refers to. - * If successful, it returns non-NULL and also locks - * the driver's mutex! - * - * This means that you need to call cfg80211_unlock_rdev() - * before being allowed to acquire &cfg80211_mutex! - * - * This is necessary because we need to lock the global - * mutex to get an item off the list safely, and then - * we lock the rdev mutex so it doesn't go away under us. - * - * We don't want to keep cfg80211_mutex locked - * for all the time in order to allow requests on - * other interfaces to go through at the same time. - * - * The result of this can be a PTR_ERR and hence must - * be checked with IS_ERR() for errors. - */ -extern struct cfg80211_registered_device * -cfg80211_get_dev_from_info(struct genl_info *info); - /* requires cfg80211_rdev_mutex to be held! */ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a363ca17bfc5..2d3541c5e058 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -70,6 +70,88 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, return 0; } +static struct cfg80211_registered_device * +__cfg80211_rdev_from_info(struct genl_info *info) +{ + int ifindex; + struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL; + struct net_device *dev; + int err = -EINVAL; + + assert_cfg80211_lock(); + + if (info->attrs[NL80211_ATTR_WIPHY]) { + bywiphyidx = cfg80211_rdev_by_wiphy_idx( + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); + err = -ENODEV; + } + + if (info->attrs[NL80211_ATTR_IFINDEX]) { + ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); + dev = dev_get_by_index(genl_info_net(info), ifindex); + if (dev) { + if (dev->ieee80211_ptr) + byifidx = + wiphy_to_dev(dev->ieee80211_ptr->wiphy); + dev_put(dev); + } + err = -ENODEV; + } + + if (bywiphyidx && byifidx) { + if (bywiphyidx != byifidx) + return ERR_PTR(-EINVAL); + else + return bywiphyidx; /* == byifidx */ + } + if (bywiphyidx) + return bywiphyidx; + + if (byifidx) + return byifidx; + + return ERR_PTR(err); +} + +/* + * This function returns a pointer to the driver + * that the genl_info item that is passed refers to. + * If successful, it returns non-NULL and also locks + * the driver's mutex! + * + * This means that you need to call cfg80211_unlock_rdev() + * before being allowed to acquire &cfg80211_mutex! + * + * This is necessary because we need to lock the global + * mutex to get an item off the list safely, and then + * we lock the rdev mutex so it doesn't go away under us. + * + * We don't want to keep cfg80211_mutex locked + * for all the time in order to allow requests on + * other interfaces to go through at the same time. + * + * The result of this can be a PTR_ERR and hence must + * be checked with IS_ERR() for errors. + */ +static struct cfg80211_registered_device * +cfg80211_get_dev_from_info(struct genl_info *info) +{ + struct cfg80211_registered_device *rdev; + + mutex_lock(&cfg80211_mutex); + rdev = __cfg80211_rdev_from_info(info); + + /* if it is not an error we grab the lock on + * it to assure it won't be going away while + * we operate on it */ + if (!IS_ERR(rdev)) + mutex_lock(&rdev->mtx); + + mutex_unlock(&cfg80211_mutex); + + return rdev; +} + /* policy for the attributes */ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, -- GitLab From 7fee4778bf56b0c5c86010d5b6f654177cc5da96 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jun 2012 14:09:58 +0200 Subject: [PATCH 2142/6849] nl80211: refactor __cfg80211_rdev_from_info Refactor the function to make it easier to extend. Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 59 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2d3541c5e058..0ec9779c2b56 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -73,44 +73,47 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, static struct cfg80211_registered_device * __cfg80211_rdev_from_info(struct genl_info *info) { - int ifindex; - struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL; - struct net_device *dev; - int err = -EINVAL; + struct cfg80211_registered_device *rdev = NULL, *tmp; + struct net_device *netdev; assert_cfg80211_lock(); - if (info->attrs[NL80211_ATTR_WIPHY]) { - bywiphyidx = cfg80211_rdev_by_wiphy_idx( + if (!info->attrs[NL80211_ATTR_WIPHY] && + !info->attrs[NL80211_ATTR_IFINDEX]) + return ERR_PTR(-EINVAL); + + if (info->attrs[NL80211_ATTR_WIPHY]) + rdev = cfg80211_rdev_by_wiphy_idx( nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); - err = -ENODEV; - } if (info->attrs[NL80211_ATTR_IFINDEX]) { - ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); - dev = dev_get_by_index(genl_info_net(info), ifindex); - if (dev) { - if (dev->ieee80211_ptr) - byifidx = - wiphy_to_dev(dev->ieee80211_ptr->wiphy); - dev_put(dev); - } - err = -ENODEV; - } + int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); + netdev = dev_get_by_index(genl_info_net(info), ifindex); + if (netdev) { + if (netdev->ieee80211_ptr) + tmp = wiphy_to_dev( + netdev->ieee80211_ptr->wiphy); + else + tmp = NULL; - if (bywiphyidx && byifidx) { - if (bywiphyidx != byifidx) - return ERR_PTR(-EINVAL); - else - return bywiphyidx; /* == byifidx */ + dev_put(netdev); + + /* not wireless device -- return error */ + if (!tmp) + return ERR_PTR(-EINVAL); + + /* mismatch -- return error */ + if (rdev && tmp != rdev) + return ERR_PTR(-EINVAL); + + rdev = tmp; + } } - if (bywiphyidx) - return bywiphyidx; - if (byifidx) - return byifidx; + if (rdev) + return rdev; - return ERR_PTR(err); + return ERR_PTR(-ENODEV); } /* -- GitLab From 4f7eff10b20fc86f71f2db83e6b16cb5fbde8dbc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jun 2012 14:14:22 +0200 Subject: [PATCH 2143/6849] nl80211: fix netns separation There are currently a few ways to "escape" the network namespace and access a wiphy that belongs to another namespace. Add a netns argument to the relevant functions to fix this. One remaining issue with testmode will be fixed in a follow-up patch. Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0ec9779c2b56..af232912fff8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -71,7 +71,7 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, } static struct cfg80211_registered_device * -__cfg80211_rdev_from_info(struct genl_info *info) +__cfg80211_rdev_from_info(struct net *netns, struct genl_info *info) { struct cfg80211_registered_device *rdev = NULL, *tmp; struct net_device *netdev; @@ -88,7 +88,7 @@ __cfg80211_rdev_from_info(struct genl_info *info) if (info->attrs[NL80211_ATTR_IFINDEX]) { int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); - netdev = dev_get_by_index(genl_info_net(info), ifindex); + netdev = dev_get_by_index(netns, ifindex); if (netdev) { if (netdev->ieee80211_ptr) tmp = wiphy_to_dev( @@ -110,10 +110,13 @@ __cfg80211_rdev_from_info(struct genl_info *info) } } - if (rdev) - return rdev; + if (!rdev) + return ERR_PTR(-ENODEV); - return ERR_PTR(-ENODEV); + if (netns != wiphy_net(&rdev->wiphy)) + return ERR_PTR(-ENODEV); + + return rdev; } /* @@ -137,12 +140,12 @@ __cfg80211_rdev_from_info(struct genl_info *info) * be checked with IS_ERR() for errors. */ static struct cfg80211_registered_device * -cfg80211_get_dev_from_info(struct genl_info *info) +cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) { struct cfg80211_registered_device *rdev; mutex_lock(&cfg80211_mutex); - rdev = __cfg80211_rdev_from_info(info); + rdev = __cfg80211_rdev_from_info(netns, info); /* if it is not an error we grab the lock on * it to assure it won't be going away while @@ -1419,7 +1422,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) } if (!netdev) { - rdev = __cfg80211_rdev_from_info(info); + rdev = __cfg80211_rdev_from_info(genl_info_net(info), info); if (IS_ERR(rdev)) { mutex_unlock(&cfg80211_mutex); return PTR_ERR(rdev); @@ -6623,7 +6626,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, rtnl_lock(); if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { - rdev = cfg80211_get_dev_from_info(info); + rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); if (IS_ERR(rdev)) { if (rtnl) rtnl_unlock(); -- GitLab From 878d9ec7367816dc336b0c24e6256596559692b7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jun 2012 14:18:32 +0200 Subject: [PATCH 2144/6849] nl80211: change __cfg80211_rdev_from_info Change the function to __cfg80211_rdev_from_attrs to take attributes instead of the info struct to make it usable from dump callbacks for testmode. Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index af232912fff8..7e94d4d960bf 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -71,23 +71,23 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, } static struct cfg80211_registered_device * -__cfg80211_rdev_from_info(struct net *netns, struct genl_info *info) +__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) { struct cfg80211_registered_device *rdev = NULL, *tmp; struct net_device *netdev; assert_cfg80211_lock(); - if (!info->attrs[NL80211_ATTR_WIPHY] && - !info->attrs[NL80211_ATTR_IFINDEX]) + if (!attrs[NL80211_ATTR_WIPHY] && + !attrs[NL80211_ATTR_IFINDEX]) return ERR_PTR(-EINVAL); - if (info->attrs[NL80211_ATTR_WIPHY]) + if (attrs[NL80211_ATTR_WIPHY]) rdev = cfg80211_rdev_by_wiphy_idx( - nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); + nla_get_u32(attrs[NL80211_ATTR_WIPHY])); - if (info->attrs[NL80211_ATTR_IFINDEX]) { - int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); + if (attrs[NL80211_ATTR_IFINDEX]) { + int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); netdev = dev_get_by_index(netns, ifindex); if (netdev) { if (netdev->ieee80211_ptr) @@ -145,7 +145,7 @@ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) struct cfg80211_registered_device *rdev; mutex_lock(&cfg80211_mutex); - rdev = __cfg80211_rdev_from_info(netns, info); + rdev = __cfg80211_rdev_from_attrs(netns, info->attrs); /* if it is not an error we grab the lock on * it to assure it won't be going away while @@ -1422,7 +1422,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) } if (!netdev) { - rdev = __cfg80211_rdev_from_info(genl_info_net(info), info); + rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), + info->attrs); if (IS_ERR(rdev)) { mutex_unlock(&cfg80211_mutex); return PTR_ERR(rdev); -- GitLab From 2bd7e35da011f51d4fdb3b71f888c3a50194bfcd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Jun 2012 14:23:16 +0200 Subject: [PATCH 2145/6849] nl80211: use __cfg80211_rdev_from_attrs for testmode To fix the testmode cross-namespace access problem, use __cfg80211_rdev_from_attrs() to get the device instead of open-coding similar functionality. Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7e94d4d960bf..06623d064606 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5230,21 +5230,18 @@ static int nl80211_testmode_dump(struct sk_buff *skb, nl80211_policy); if (err) return err; - if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) { - phy_idx = nla_get_u32( - nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]); - } else { - struct net_device *netdev; - err = get_rdev_dev_by_ifindex(sock_net(skb->sk), - nl80211_fam.attrbuf, - &rdev, &netdev); - if (err) - return err; - dev_put(netdev); - phy_idx = rdev->wiphy_idx; - cfg80211_unlock_rdev(rdev); + mutex_lock(&cfg80211_mutex); + rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); + if (IS_ERR(rdev)) { + mutex_unlock(&cfg80211_mutex); + return PTR_ERR(rdev); } + phy_idx = rdev->wiphy_idx; + rdev = NULL; + mutex_unlock(&cfg80211_mutex); + if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) cb->args[1] = (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; -- GitLab From 46c1dd0c7fac54d3739d62b6362024d9b568c6de Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 19 Jun 2012 02:50:57 +0200 Subject: [PATCH 2146/6849] cfg80211: fix regression in multi-vif AP start Commit "cfg80211: provide channel to start_ap function" assumes that the channel is always passed to the NL80211_CMD_START_AP command, however in case of multi-BSSID, hostapd only passes the channel for the first vif. This makes starting beaconing on secondary vifs fail with -EINVAL. Fix this by storing the channel provided to .start_ap in wdev->preset_chan and picking the first AP vif's channel for secondary vifs if not provided. Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 06623d064606..888fadc4d63e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2335,6 +2335,33 @@ static int nl80211_parse_beacon(struct genl_info *info, return 0; } +static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, + struct cfg80211_ap_settings *params) +{ + struct wireless_dev *wdev; + bool ret = false; + + mutex_lock(&rdev->devlist_mtx); + + list_for_each_entry(wdev, &rdev->netdev_list, list) { + if (wdev->iftype != NL80211_IFTYPE_AP && + wdev->iftype != NL80211_IFTYPE_P2P_GO) + continue; + + if (!wdev->preset_chan) + continue; + + params->channel = wdev->preset_chan; + params->channel_type = wdev->preset_chantype; + ret = true; + break; + } + + mutex_unlock(&rdev->devlist_mtx); + + return ret; +} + static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -2437,7 +2464,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) } else if (wdev->preset_chan) { params.channel = wdev->preset_chan; params.channel_type = wdev->preset_chantype; - } else + } else if (!nl80211_get_ap_channel(rdev, ¶ms)) return -EINVAL; if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, @@ -2445,8 +2472,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) return -EINVAL; err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); - if (!err) + if (!err) { + wdev->preset_chan = params.channel; + wdev->preset_chantype = params.channel_type; wdev->beacon_interval = params.beacon_interval; + } return err; } -- GitLab From b16b2a262c234d6abd8899d41769278337fff5b5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jun 2012 18:17:56 +0900 Subject: [PATCH 2147/6849] sh: pfc: Make gpio chip support optional where possible. This implements some Kconfig knobs for ensuring that the PFC gpio chip can be disabled or built as a module in the cases where it's optional, or forcibly enabled in cases where it's not. Signed-off-by: Paul Mundt --- drivers/sh/Kconfig | 15 +++++++++++++++ drivers/sh/Makefile | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig index f168a6159961..d7dbfee1bc70 100644 --- a/drivers/sh/Kconfig +++ b/drivers/sh/Kconfig @@ -2,4 +2,19 @@ menu "SuperH / SH-Mobile Driver Options" source "drivers/sh/intc/Kconfig" +comment "Pin function controller options" + +config SH_PFC + # XXX move off the gpio dependency + depends on GENERIC_GPIO + select GPIO_SH_PFC if ARCH_REQUIRE_GPIOLIB + def_bool y + +config GPIO_SH_PFC + tristate "SuperH PFC GPIO support" + depends on SH_PFC && GPIOLIB + help + This enables support for GPIOs within the SoC's pin function + controller. + endmenu diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index be5b2934f067..f5d93e8de090 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -6,5 +6,6 @@ obj-y := intc/ obj-$(CONFIG_HAVE_CLK) += clk/ obj-$(CONFIG_MAPLE) += maple/ obj-$(CONFIG_SUPERHYWAY) += superhyway/ -obj-$(CONFIG_GENERIC_GPIO) += pfc.o pfc-gpio.o +obj-$(CONFIG_SH_PFC) += pfc.o +obj-$(CONFIG_GPIO_SH_PFC) += pfc-gpio.o obj-y += pm_runtime.o -- GitLab From 32103c7ba7d274bcb3ace48bc3366e1df37ebb56 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 20 Jun 2012 11:30:25 +0200 Subject: [PATCH 2148/6849] ARM: shmobile: sh73a0: bugfix: SY-DMAC number 681e1b3eeb3606e06a7c4984e8058df84296f8bb (ARM: mach-shmobile: sh73a0 DMA Engine support for SY-DMAC) adds SY-DMAC, but it is 218, not 318 This patch is based on v2.0 manual Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/clock-sh73a0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 472d1f5361e5..3946c4ba2aa8 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -475,9 +475,9 @@ static struct clk *late_main_clks[] = { enum { MSTP001, MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, - MSTP219, + MSTP219, MSTP218, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, - MSTP331, MSTP329, MSTP325, MSTP323, MSTP318, + MSTP331, MSTP329, MSTP325, MSTP323, MSTP314, MSTP313, MSTP312, MSTP311, MSTP303, MSTP302, MSTP301, MSTP300, MSTP411, MSTP410, MSTP403, @@ -497,6 +497,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */ + [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ @@ -508,7 +509,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */ [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ - [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */ [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */ [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ @@ -552,6 +552,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ @@ -563,7 +564,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ - CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ -- GitLab From 4d6344f3c943a5ff1fd8dcbd7be61ebdef1d0285 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 20 Jun 2012 11:30:32 +0200 Subject: [PATCH 2149/6849] ARM: shmobile: sh7372: bugfix: chclr_offset base chclr_write() will use (chan_reg + chclr_offset). In sh7372 case, DMA1CHCLR is started from 0xfe008220, and chan_reg is started from 0xfe008020 (= sh7372_dmae0_resources). Thus, chclr_offset should be (0x220 - 0x20) instead of 0x220. Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/setup-sh7372.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 6a4bd582c028..fafce9ce8218 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -484,7 +484,7 @@ static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { }, }; -#define SH7372_CHCLR 0x220 +#define SH7372_CHCLR (0x220 - 0x20) static const struct sh_dmae_channel sh7372_dmae_channels[] = { { -- GitLab From 6ae42bb22b40254e6488bbfe47f970620ab6d433 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 20 Jun 2012 11:30:41 +0200 Subject: [PATCH 2150/6849] ARM: mach-shmobile: Fix build when SMP is enabled and EMEV2 is not enabled Build failed, when SMP is enabled and EMEV2 is not enabled. arch/arm/mach-shmobile/built-in.o: In function `shmobile_platform_cpu_kill': /home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:62: undefined reference to `emev2_platform_cpu_kill' arch/arm/mach-shmobile/built-in.o: In function `shmobile_smp_get_core_count': /home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:39: undefined reference to `emev2_get_core_count' arch/arm/mach-shmobile/built-in.o: In function `shmobile_smp_prepare_cpus': /home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:53: undefined reference to `emev2_smp_prepare_cpus' arch/arm/mach-shmobile/built-in.o: In function `platform_secondary_init': /home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:78: undefined reference to `emev2_secondary_init' arch/arm/mach-shmobile/built-in.o: In function `boot_secondary': /home/iwamatsu/work/kernel/sh-2.6-devel/arch/arm/mach-shmobile/platsmp.c:90: undefined reference to `emev2_boot_secondary This is the cause by when EMEV2 is disabled, that the check by OF of EMEV2 is performed in platsmp.c. This patch revise what the function about EMEV2 may not be used in this file, when EMEV2 is not enabled. Signed-off-by: Nobuhiro Iwamatsu Acked-by: Simon Horman Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/platsmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index bacdd667e3b1..e859fcdb3d58 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -25,7 +25,12 @@ #define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2() || \ of_machine_is_compatible("renesas,sh73a0")) #define is_r8a7779() machine_is_marzen() + +#ifdef CONFIG_ARCH_EMEV2 #define is_emev2() of_machine_is_compatible("renesas,emev2") +#else +#define is_emev2() (0) +#endif static unsigned int __init shmobile_smp_get_core_count(void) { -- GitLab From f3761c3950bd2ad813095a240d6a3dcb885d2431 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 19 Jun 2012 19:31:48 +0100 Subject: [PATCH 2151/6849] ALSA: Add missing include of pcm.h to pcm_params.h There's a dependency but no #include. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- include/sound/pcm_params.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h index f494f1e3c900..37ae12e0ab06 100644 --- a/include/sound/pcm_params.h +++ b/include/sound/pcm_params.h @@ -22,6 +22,8 @@ * */ +#include + int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var, int *dir); -- GitLab From 809d310c7e69289c94a4475d287ba1c512885478 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jun 2012 11:08:43 +0100 Subject: [PATCH 2152/6849] regulator: lp872x: Don't allow modular build Fixes link failure due to devm_gpio_request_one() Reported-by: Stephen Rothwell Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 870f7300b156..434462ada7c0 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -20,6 +20,7 @@ menuconfig REGULATOR If unsure, say no. + if REGULATOR config REGULATOR_DEBUG @@ -225,7 +226,7 @@ config REGULATOR_LP3972 on National Semiconductors LP3972 PMIC config REGULATOR_LP872X - tristate "TI/National Semiconductor LP8720/LP8725 voltage regulators" + bool "TI/National Semiconductor LP8720/LP8725 voltage regulators" depends on I2C select REGMAP_I2C help -- GitLab From c59d2a6b20aef4660a9ed89224bd17eec6a54751 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 20 Jun 2012 15:01:25 +0800 Subject: [PATCH 2153/6849] regulator: max77686: Initialize regulator_config Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index a29eee33dd7b..877d4bff1120 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -217,7 +217,7 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) struct max77686_data *max77686; int i, size; int ret = 0; - struct regulator_config config; + struct regulator_config config = { }; dev_dbg(&pdev->dev, "%s\n", __func__); -- GitLab From f503071b03dcac6908fb7e051cfc9c45bea084c0 Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Wed, 20 Jun 2012 10:50:51 +0530 Subject: [PATCH 2154/6849] regulator: max77686: Implement .set_ramp_delay() callback This patch implements the .set_ramp_delay callback to set the ramp_delay on hardware for BUCK2/3/4 if ramp_delay is set in regulator constraints. This patch also do some cleaning work for unrequired members of struct max77686_data. Signed-off-by: Yadwinder Singh Brar Acked-by: MyungJoo Ham Signed-off-by: Mark Brown --- drivers/regulator/max77686.c | 37 ++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 877d4bff1120..23f956a6c5f2 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -65,11 +65,34 @@ enum max77686_ramp_rate { }; struct max77686_data { - struct device *dev; - struct max77686_dev *iodev; struct regulator_dev **rdev; }; +static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) +{ + unsigned int ramp_value = RAMP_RATE_NO_CTRL; + + switch (ramp_delay) { + case 1 ... 13750: + ramp_value = RAMP_RATE_13P75MV; + break; + case 13751 ... 27500: + ramp_value = RAMP_RATE_27P5MV; + break; + case 27501 ... 55000: + ramp_value = RAMP_RATE_55MV; + break; + case 55001 ... 100000: + break; + default: + pr_warn("%s: ramp_delay: %d not supported, setting 100000\n", + rdev->desc->name, ramp_delay); + } + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + MAX77686_RAMP_RATE_MASK, ramp_value << 6); +} + static struct regulator_ops max77686_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, @@ -90,6 +113,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = max77686_set_ramp_delay, }; #define regulator_desc_ldo(num) { \ @@ -238,20 +262,17 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) return -ENOMEM; rdev = max77686->rdev; - max77686->dev = &pdev->dev; - max77686->iodev = iodev; + config.dev = &pdev->dev; + config.regmap = iodev->regmap; platform_set_drvdata(pdev, max77686); for (i = 0; i < MAX77686_REGULATORS; i++) { - config.dev = max77686->dev; - config.regmap = iodev->regmap; - config.driver_data = max77686; config.init_data = pdata->regulators[i].initdata; rdev[i] = regulator_register(®ulators[i], &config); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); - dev_err(max77686->dev, + dev_err(&pdev->dev, "regulator init failed for %d\n", i); rdev[i] = NULL; goto err; -- GitLab From 56fb523f12665974bd249a39524b75b4f5e57388 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 20 Jun 2012 12:15:59 +0200 Subject: [PATCH 2155/6849] ARM: mach-shmobile: add missing GPIO IRQ configuration on mackerel SDHI0 card-detect GPIO IRQ on mackarel currently works, because it is the default configuration of IRQ26. However, we should not rely on this and should configure the function explicitly. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/board-mackerel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index b577f7c44678..150122a44630 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1512,6 +1512,9 @@ static void __init mackerel_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); + /* SDHI0 PORT172 card-detect IRQ26 */ + gpio_request(GPIO_FN_IRQ26_172, NULL); + #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* enable SDHI1 */ gpio_request(GPIO_FN_SDHICMD1, NULL); -- GitLab From baf73e2c4e25aa57a7bd5df90a93e65be0542c74 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 20 Jun 2012 16:13:15 +0800 Subject: [PATCH 2156/6849] regulator: lp872x: Return -EINVAL if pdata is NULL Return -EINVAL if pdata is NULL, otherwise we have NULL dereference bug. This patch also moves the code checking pdata earlier in lp872x_probe. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/lp872x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index d51d09852041..e8f54efb1985 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -785,11 +785,6 @@ static int lp872x_config(struct lp872x *lp) struct lp872x_platform_data *pdata = lp->pdata; int ret; - if (!pdata) { - dev_warn(lp->dev, "no platform data\n"); - return 0; - } - if (!pdata->update_config) return 0; @@ -889,6 +884,11 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) [LP8725] = LP8725_NUM_REGULATORS, }; + if (!pdata) { + dev_warn(&cl->dev, "no platform data\n"); + return -EINVAL; + } + lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); if (!lp) goto err_mem; -- GitLab From 8386a00f1443f676e8b614f654e2e324fdc0b3b3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Jun 2012 16:00:53 +0800 Subject: [PATCH 2157/6849] regulator: tps6524x: Fix get_voltage_sel for fixed voltage get_voltage_sel() should return selector rather than voltage. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6524x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index b88b3df82381..1b299aacf22f 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -482,7 +482,7 @@ static int get_voltage_sel(struct regulator_dev *rdev) info = &supply_info[rdev_get_id(rdev)]; if (info->flags & FIXED_VOLTAGE) - return info->fixed_voltage; + return 0; ret = read_field(hw, &info->voltage); if (ret < 0) -- GitLab From d2aae47f804830da904d2454d73959eda4ebb0fd Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Wed, 20 Jun 2012 17:00:30 -0400 Subject: [PATCH 2158/6849] ASoC: add sport driver for bf6xx soc The SPORT(Serial Port) module on bf6xx soc has a totally different ip comparing to bf5xx soc. An individual SPORT module consists of two independently configurable SPORT halves with identical functionality. Each SPORT half can be configured for either transmitter or receiver. Signed-off-by: Scott Jiang Signed-off-by: Mark Brown --- sound/soc/blackfin/Kconfig | 10 +- sound/soc/blackfin/Makefile | 2 + sound/soc/blackfin/bf6xx-sport.c | 422 +++++++++++++++++++++++++++++++ sound/soc/blackfin/bf6xx-sport.h | 82 ++++++ 4 files changed, 513 insertions(+), 3 deletions(-) create mode 100644 sound/soc/blackfin/bf6xx-sport.c create mode 100644 sound/soc/blackfin/bf6xx-sport.h diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig index 9f6bc55fc399..0374a3965095 100644 --- a/sound/soc/blackfin/Kconfig +++ b/sound/soc/blackfin/Kconfig @@ -1,7 +1,8 @@ config SND_BF5XX_I2S - tristate "SoC I2S Audio for the ADI BF5xx chip" + tristate "SoC I2S Audio for the ADI Blackfin chip" depends on BLACKFIN - select SND_BF5XX_SOC_SPORT + select SND_BF5XX_SOC_SPORT if !BF60x + select SND_BF6XX_SOC_SPORT if BF60x help Say Y or M if you want to add support for codecs attached to the Blackfin SPORT (synchronous serial ports) interface in I2S @@ -162,6 +163,9 @@ config SND_BF5XX_SOC_AD1980 config SND_BF5XX_SOC_SPORT tristate +config SND_BF6XX_SOC_SPORT + tristate + config SND_BF5XX_SOC_I2S tristate @@ -173,7 +177,7 @@ config SND_BF5XX_SOC_AC97 config SND_BF5XX_SPORT_NUM int "Set a SPORT for Sound chip" - depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM) + depends on (SND_BF5XX_SOC_SPORT || SND_BF6XX_SOC_SPORT) range 0 3 if BF54x range 0 1 if !BF54x default 0 diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile index 1bf86ccaa8de..13b092239a82 100644 --- a/sound/soc/blackfin/Makefile +++ b/sound/soc/blackfin/Makefile @@ -3,6 +3,7 @@ snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o snd-soc-bf5xx-sport-objs := bf5xx-sport.o +snd-soc-bf6xx-sport-objs := bf6xx-sport.o snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o @@ -11,6 +12,7 @@ obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o +obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c new file mode 100644 index 000000000000..f19a72b8e0c2 --- /dev/null +++ b/sound/soc/blackfin/bf6xx-sport.c @@ -0,0 +1,422 @@ +/* + * bf6xx_sport.c Analog Devices BF6XX SPORT driver + * + * Copyright (c) 2012 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "bf6xx-sport.h" + +int sport_set_tx_params(struct sport_device *sport, + struct sport_params *params) +{ + if (sport->tx_regs->spctl & SPORT_CTL_SPENPRI) + return -EBUSY; + sport->tx_regs->spctl = params->spctl | SPORT_CTL_SPTRAN; + sport->tx_regs->div = params->div; + SSYNC(); + return 0; +} +EXPORT_SYMBOL(sport_set_tx_params); + +int sport_set_rx_params(struct sport_device *sport, + struct sport_params *params) +{ + if (sport->rx_regs->spctl & SPORT_CTL_SPENPRI) + return -EBUSY; + sport->rx_regs->spctl = params->spctl & ~SPORT_CTL_SPTRAN; + sport->rx_regs->div = params->div; + SSYNC(); + return 0; +} +EXPORT_SYMBOL(sport_set_rx_params); + +static int compute_wdsize(size_t wdsize) +{ + switch (wdsize) { + case 1: + return WDSIZE_8 | PSIZE_8; + case 2: + return WDSIZE_16 | PSIZE_16; + default: + return WDSIZE_32 | PSIZE_32; + } +} + +void sport_tx_start(struct sport_device *sport) +{ + set_dma_next_desc_addr(sport->tx_dma_chan, sport->tx_desc); + set_dma_config(sport->tx_dma_chan, DMAFLOW_LIST | DI_EN + | compute_wdsize(sport->wdsize) | NDSIZE_6); + enable_dma(sport->tx_dma_chan); + sport->tx_regs->spctl |= SPORT_CTL_SPENPRI; + SSYNC(); +} +EXPORT_SYMBOL(sport_tx_start); + +void sport_rx_start(struct sport_device *sport) +{ + set_dma_next_desc_addr(sport->rx_dma_chan, sport->rx_desc); + set_dma_config(sport->rx_dma_chan, DMAFLOW_LIST | DI_EN | WNR + | compute_wdsize(sport->wdsize) | NDSIZE_6); + enable_dma(sport->rx_dma_chan); + sport->rx_regs->spctl |= SPORT_CTL_SPENPRI; + SSYNC(); +} +EXPORT_SYMBOL(sport_rx_start); + +void sport_tx_stop(struct sport_device *sport) +{ + sport->tx_regs->spctl &= ~SPORT_CTL_SPENPRI; + SSYNC(); + disable_dma(sport->tx_dma_chan); +} +EXPORT_SYMBOL(sport_tx_stop); + +void sport_rx_stop(struct sport_device *sport) +{ + sport->rx_regs->spctl &= ~SPORT_CTL_SPENPRI; + SSYNC(); + disable_dma(sport->rx_dma_chan); +} +EXPORT_SYMBOL(sport_rx_stop); + +void sport_set_tx_callback(struct sport_device *sport, + void (*tx_callback)(void *), void *tx_data) +{ + sport->tx_callback = tx_callback; + sport->tx_data = tx_data; +} +EXPORT_SYMBOL(sport_set_tx_callback); + +void sport_set_rx_callback(struct sport_device *sport, + void (*rx_callback)(void *), void *rx_data) +{ + sport->rx_callback = rx_callback; + sport->rx_data = rx_data; +} +EXPORT_SYMBOL(sport_set_rx_callback); + +static void setup_desc(struct dmasg *desc, void *buf, int fragcount, + size_t fragsize, unsigned int cfg, + unsigned int count, size_t wdsize) +{ + + int i; + + for (i = 0; i < fragcount; ++i) { + desc[i].next_desc_addr = &(desc[i + 1]); + desc[i].start_addr = (unsigned long)buf + i*fragsize; + desc[i].cfg = cfg; + desc[i].x_count = count; + desc[i].x_modify = wdsize; + desc[i].y_count = 0; + desc[i].y_modify = 0; + } + + /* make circular */ + desc[fragcount-1].next_desc_addr = desc; +} + +int sport_config_tx_dma(struct sport_device *sport, void *buf, + int fragcount, size_t fragsize) +{ + unsigned int count; + unsigned int cfg; + dma_addr_t addr; + + count = fragsize/sport->wdsize; + + if (sport->tx_desc) + dma_free_coherent(NULL, sport->tx_desc_size, + sport->tx_desc, 0); + + sport->tx_desc = dma_alloc_coherent(NULL, + fragcount * sizeof(struct dmasg), &addr, 0); + sport->tx_desc_size = fragcount * sizeof(struct dmasg); + if (!sport->tx_desc) + return -ENOMEM; + + sport->tx_buf = buf; + sport->tx_fragsize = fragsize; + sport->tx_frags = fragcount; + cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6; + + setup_desc(sport->tx_desc, buf, fragcount, fragsize, + cfg|DMAEN, count, sport->wdsize); + + return 0; +} +EXPORT_SYMBOL(sport_config_tx_dma); + +int sport_config_rx_dma(struct sport_device *sport, void *buf, + int fragcount, size_t fragsize) +{ + unsigned int count; + unsigned int cfg; + dma_addr_t addr; + + count = fragsize/sport->wdsize; + + if (sport->rx_desc) + dma_free_coherent(NULL, sport->rx_desc_size, + sport->rx_desc, 0); + + sport->rx_desc = dma_alloc_coherent(NULL, + fragcount * sizeof(struct dmasg), &addr, 0); + sport->rx_desc_size = fragcount * sizeof(struct dmasg); + if (!sport->rx_desc) + return -ENOMEM; + + sport->rx_buf = buf; + sport->rx_fragsize = fragsize; + sport->rx_frags = fragcount; + cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) + | WNR | NDSIZE_6; + + setup_desc(sport->rx_desc, buf, fragcount, fragsize, + cfg|DMAEN, count, sport->wdsize); + + return 0; +} +EXPORT_SYMBOL(sport_config_rx_dma); + +unsigned long sport_curr_offset_tx(struct sport_device *sport) +{ + unsigned long curr = get_dma_curr_addr(sport->tx_dma_chan); + + return (unsigned char *)curr - sport->tx_buf; +} +EXPORT_SYMBOL(sport_curr_offset_tx); + +unsigned long sport_curr_offset_rx(struct sport_device *sport) +{ + unsigned long curr = get_dma_curr_addr(sport->rx_dma_chan); + + return (unsigned char *)curr - sport->rx_buf; +} +EXPORT_SYMBOL(sport_curr_offset_rx); + +static irqreturn_t sport_tx_irq(int irq, void *dev_id) +{ + struct sport_device *sport = dev_id; + static unsigned long status; + + status = get_dma_curr_irqstat(sport->tx_dma_chan); + if (status & (DMA_DONE|DMA_ERR)) { + clear_dma_irqstat(sport->tx_dma_chan); + SSYNC(); + } + if (sport->tx_callback) + sport->tx_callback(sport->tx_data); + return IRQ_HANDLED; +} + +static irqreturn_t sport_rx_irq(int irq, void *dev_id) +{ + struct sport_device *sport = dev_id; + unsigned long status; + + status = get_dma_curr_irqstat(sport->rx_dma_chan); + if (status & (DMA_DONE|DMA_ERR)) { + clear_dma_irqstat(sport->rx_dma_chan); + SSYNC(); + } + if (sport->rx_callback) + sport->rx_callback(sport->rx_data); + return IRQ_HANDLED; +} + +static irqreturn_t sport_err_irq(int irq, void *dev_id) +{ + struct sport_device *sport = dev_id; + struct device *dev = &sport->pdev->dev; + + if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI) + dev_dbg(dev, "sport error: TUVF\n"); + if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI) + dev_dbg(dev, "sport error: ROVF\n"); + + return IRQ_HANDLED; +} + +static int sport_get_resource(struct sport_device *sport) +{ + struct platform_device *pdev = sport->pdev; + struct device *dev = &pdev->dev; + struct bfin_snd_platform_data *pdata = dev->platform_data; + struct resource *res; + + if (!pdata) { + dev_err(dev, "No platform data\n"); + return -ENODEV; + } + sport->pin_req = pdata->pin_req; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "No tx MEM resource\n"); + return -ENODEV; + } + sport->tx_regs = (struct sport_register *)res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "No rx MEM resource\n"); + return -ENODEV; + } + sport->rx_regs = (struct sport_register *)res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(dev, "No tx DMA resource\n"); + return -ENODEV; + } + sport->tx_dma_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(dev, "No rx DMA resource\n"); + return -ENODEV; + } + sport->rx_dma_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "No tx error irq resource\n"); + return -ENODEV; + } + sport->tx_err_irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); + if (!res) { + dev_err(dev, "No rx error irq resource\n"); + return -ENODEV; + } + sport->rx_err_irq = res->start; + + return 0; +} + +static int sport_request_resource(struct sport_device *sport) +{ + struct device *dev = &sport->pdev->dev; + int ret; + + ret = peripheral_request_list(sport->pin_req, "soc-audio"); + if (ret) { + dev_err(dev, "Unable to request sport pin\n"); + return ret; + } + + ret = request_dma(sport->tx_dma_chan, "SPORT TX Data"); + if (ret) { + dev_err(dev, "Unable to allocate DMA channel for sport tx\n"); + goto err_tx_dma; + } + set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport); + + ret = request_dma(sport->rx_dma_chan, "SPORT RX Data"); + if (ret) { + dev_err(dev, "Unable to allocate DMA channel for sport rx\n"); + goto err_rx_dma; + } + set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport); + + ret = request_irq(sport->tx_err_irq, sport_err_irq, + 0, "SPORT TX ERROR", sport); + if (ret) { + dev_err(dev, "Unable to allocate tx error IRQ for sport\n"); + goto err_tx_irq; + } + + ret = request_irq(sport->rx_err_irq, sport_err_irq, + 0, "SPORT RX ERROR", sport); + if (ret) { + dev_err(dev, "Unable to allocate rx error IRQ for sport\n"); + goto err_rx_irq; + } + + return 0; +err_rx_irq: + free_irq(sport->tx_err_irq, sport); +err_tx_irq: + free_dma(sport->rx_dma_chan); +err_rx_dma: + free_dma(sport->tx_dma_chan); +err_tx_dma: + peripheral_free_list(sport->pin_req); + return ret; +} + +static void sport_free_resource(struct sport_device *sport) +{ + free_irq(sport->rx_err_irq, sport); + free_irq(sport->tx_err_irq, sport); + free_dma(sport->rx_dma_chan); + free_dma(sport->tx_dma_chan); + peripheral_free_list(sport->pin_req); +} + +struct sport_device *sport_create(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct sport_device *sport; + int ret; + + sport = kzalloc(sizeof(*sport), GFP_KERNEL); + if (!sport) { + dev_err(dev, "Unable to allocate memory for sport device\n"); + return NULL; + } + sport->pdev = pdev; + + ret = sport_get_resource(sport); + if (ret) { + kfree(sport); + return NULL; + } + + ret = sport_request_resource(sport); + if (ret) { + kfree(sport); + return NULL; + } + + dev_dbg(dev, "SPORT create success\n"); + return sport; +} +EXPORT_SYMBOL(sport_create); + +void sport_delete(struct sport_device *sport) +{ + sport_free_resource(sport); +} +EXPORT_SYMBOL(sport_delete); + +MODULE_DESCRIPTION("Analog Devices BF6XX SPORT driver"); +MODULE_AUTHOR("Scott Jiang "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/blackfin/bf6xx-sport.h b/sound/soc/blackfin/bf6xx-sport.h new file mode 100644 index 000000000000..307d193cfcef --- /dev/null +++ b/sound/soc/blackfin/bf6xx-sport.h @@ -0,0 +1,82 @@ +/* + * bf6xx_sport - Analog Devices BF6XX SPORT driver + * + * Copyright (c) 2012 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _BF6XX_SPORT_H_ +#define _BF6XX_SPORT_H_ + +#include +#include + +struct sport_device { + struct platform_device *pdev; + const unsigned short *pin_req; + struct sport_register *tx_regs; + struct sport_register *rx_regs; + int tx_dma_chan; + int rx_dma_chan; + int tx_err_irq; + int rx_err_irq; + + void (*tx_callback)(void *data); + void *tx_data; + void (*rx_callback)(void *data); + void *rx_data; + + struct dmasg *tx_desc; + struct dmasg *rx_desc; + unsigned int tx_desc_size; + unsigned int rx_desc_size; + unsigned char *tx_buf; + unsigned char *rx_buf; + unsigned int tx_fragsize; + unsigned int rx_fragsize; + unsigned int tx_frags; + unsigned int rx_frags; + unsigned int wdsize; +}; + +struct sport_params { + u32 spctl; + u32 div; +}; + +struct sport_device *sport_create(struct platform_device *pdev); +void sport_delete(struct sport_device *sport); +int sport_set_tx_params(struct sport_device *sport, + struct sport_params *params); +int sport_set_rx_params(struct sport_device *sport, + struct sport_params *params); +void sport_tx_start(struct sport_device *sport); +void sport_rx_start(struct sport_device *sport); +void sport_tx_stop(struct sport_device *sport); +void sport_rx_stop(struct sport_device *sport); +void sport_set_tx_callback(struct sport_device *sport, + void (*tx_callback)(void *), void *tx_data); +void sport_set_rx_callback(struct sport_device *sport, + void (*rx_callback)(void *), void *rx_data); +int sport_config_tx_dma(struct sport_device *sport, void *buf, + int fragcount, size_t fragsize); +int sport_config_rx_dma(struct sport_device *sport, void *buf, + int fragcount, size_t fragsize); +unsigned long sport_curr_offset_tx(struct sport_device *sport); +unsigned long sport_curr_offset_rx(struct sport_device *sport); + + + +#endif -- GitLab From f62ae7bda434ac5d2bcd6feb4f5bdb5885633177 Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Wed, 20 Jun 2012 17:00:31 -0400 Subject: [PATCH 2159/6849] ASoC: add i2s dai driver for bf6xx soc This driver enables i2s mode support on blackfin bf6xx platform. We reuse bf5xx-i2s-pcm.c as its i2s pcm driver because it's the same for both bf5xx and bf6xx soc. Signed-off-by: Scott Jiang Signed-off-by: Mark Brown --- sound/soc/blackfin/Kconfig | 11 +- sound/soc/blackfin/Makefile | 2 + sound/soc/blackfin/bf6xx-i2s.c | 234 +++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 sound/soc/blackfin/bf6xx-i2s.c diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig index 0374a3965095..16b88f5c26e2 100644 --- a/sound/soc/blackfin/Kconfig +++ b/sound/soc/blackfin/Kconfig @@ -10,12 +10,14 @@ config SND_BF5XX_I2S You will also need to select the audio interfaces to support below. config SND_BF5XX_SOC_SSM2602 - tristate "SoC SSM2602 Audio support for BF52x ezkit" + tristate "SoC SSM2602 Audio Codec Add-On Card support" depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) - select SND_BF5XX_SOC_I2S + select SND_BF5XX_SOC_I2S if !BF60x + select SND_BF6XX_SOC_I2S if BF60x select SND_SOC_SSM2602 help - Say Y if you want to add support for SoC audio on BF527-EZKIT. + Say Y if you want to add support for the Analog Devices + SSM2602 Audio Codec Add-On Card. config SND_SOC_BFIN_EVAL_ADAU1701 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" @@ -169,6 +171,9 @@ config SND_BF6XX_SOC_SPORT config SND_BF5XX_SOC_I2S tristate +config SND_BF6XX_SOC_I2S + tristate + config SND_BF5XX_SOC_TDM tristate diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile index 13b092239a82..6fea1f4cbee2 100644 --- a/sound/soc/blackfin/Makefile +++ b/sound/soc/blackfin/Makefile @@ -6,6 +6,7 @@ snd-soc-bf5xx-sport-objs := bf5xx-sport.o snd-soc-bf6xx-sport-objs := bf6xx-sport.o snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o +snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o @@ -15,6 +16,7 @@ obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o +obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o # Blackfin Machine Support diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c new file mode 100644 index 000000000000..c3c2466d3a42 --- /dev/null +++ b/sound/soc/blackfin/bf6xx-i2s.c @@ -0,0 +1,234 @@ +/* + * bf6xx-i2s.c - Analog Devices BF6XX i2s interface driver + * + * Copyright (c) 2012 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bf6xx-sport.h" + +struct sport_params param; + +static int bfin_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct sport_device *sport = snd_soc_dai_get_drvdata(cpu_dai); + struct device *dev = &sport->pdev->dev; + int ret = 0; + + param.spctl &= ~(SPORT_CTL_OPMODE | SPORT_CTL_CKRE | SPORT_CTL_FSR + | SPORT_CTL_LFS | SPORT_CTL_LAFS); + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_CKRE + | SPORT_CTL_LFS; + break; + case SND_SOC_DAIFMT_DSP_A: + param.spctl |= SPORT_CTL_FSR; + break; + case SND_SOC_DAIFMT_LEFT_J: + param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_LFS + | SPORT_CTL_LAFS; + break; + default: + dev_err(dev, "%s: Unknown DAI format type\n", __func__); + ret = -EINVAL; + break; + } + + param.spctl &= ~(SPORT_CTL_ICLK | SPORT_CTL_IFS); + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + break; + case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBS_CFM: + ret = -EINVAL; + break; + default: + dev_err(dev, "%s: Unknown DAI master type\n", __func__); + ret = -EINVAL; + break; + } + + return ret; +} + +static int bfin_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct sport_device *sport = snd_soc_dai_get_drvdata(dai); + struct device *dev = &sport->pdev->dev; + int ret = 0; + + param.spctl &= ~SPORT_CTL_SLEN; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + param.spctl |= 0x70; + sport->wdsize = 1; + case SNDRV_PCM_FORMAT_S16_LE: + param.spctl |= 0xf0; + sport->wdsize = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + param.spctl |= 0x170; + sport->wdsize = 3; + break; + case SNDRV_PCM_FORMAT_S32_LE: + param.spctl |= 0x1f0; + sport->wdsize = 4; + break; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = sport_set_tx_params(sport, ¶m); + if (ret) { + dev_err(dev, "SPORT tx is busy!\n"); + return ret; + } + } else { + ret = sport_set_rx_params(sport, ¶m); + if (ret) { + dev_err(dev, "SPORT rx is busy!\n"); + return ret; + } + } + return 0; +} + +#ifdef CONFIG_PM +static int bfin_i2s_suspend(struct snd_soc_dai *dai) +{ + struct sport_device *sport = snd_soc_dai_get_drvdata(dai); + + if (dai->capture_active) + sport_rx_stop(sport); + if (dai->playback_active) + sport_tx_stop(sport); + return 0; +} + +static int bfin_i2s_resume(struct snd_soc_dai *dai) +{ + struct sport_device *sport = snd_soc_dai_get_drvdata(dai); + struct device *dev = &sport->pdev->dev; + int ret; + + ret = sport_set_tx_params(sport, ¶m); + if (ret) { + dev_err(dev, "SPORT tx is busy!\n"); + return ret; + } + ret = sport_set_rx_params(sport, ¶m); + if (ret) { + dev_err(dev, "SPORT rx is busy!\n"); + return ret; + } + + return 0; +} + +#else +#define bfin_i2s_suspend NULL +#define bfin_i2s_resume NULL +#endif + +#define BFIN_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_96000) + +#define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops bfin_i2s_dai_ops = { + .hw_params = bfin_i2s_hw_params, + .set_fmt = bfin_i2s_set_dai_fmt, +}; + +static struct snd_soc_dai_driver bfin_i2s_dai = { + .suspend = bfin_i2s_suspend, + .resume = bfin_i2s_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = BFIN_I2S_RATES, + .formats = BFIN_I2S_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = BFIN_I2S_RATES, + .formats = BFIN_I2S_FORMATS, + }, + .ops = &bfin_i2s_dai_ops, +}; + +static int __devinit bfin_i2s_probe(struct platform_device *pdev) +{ + struct sport_device *sport; + struct device *dev = &pdev->dev; + int ret; + + sport = sport_create(pdev); + if (!sport) + return -ENODEV; + + /* register with the ASoC layers */ + ret = snd_soc_register_dai(dev, &bfin_i2s_dai); + if (ret) { + dev_err(dev, "Failed to register DAI: %d\n", ret); + sport_delete(sport); + return ret; + } + platform_set_drvdata(pdev, sport); + + return 0; +} + +static int __devexit bfin_i2s_remove(struct platform_device *pdev) +{ + struct sport_device *sport = platform_get_drvdata(pdev); + + snd_soc_unregister_dai(&pdev->dev); + sport_delete(sport); + + return 0; +} + +static struct platform_driver bfin_i2s_driver = { + .probe = bfin_i2s_probe, + .remove = __devexit_p(bfin_i2s_remove), + .driver = { + .name = "bfin-i2s", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(bfin_i2s_driver); + +MODULE_DESCRIPTION("Analog Devices BF6XX i2s interface driver"); +MODULE_AUTHOR("Scott Jiang "); +MODULE_LICENSE("GPL v2"); -- GitLab From b667a45d9f8ed98d4da2bbbd1c9083aade0f3237 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 14 Jun 2012 18:14:00 +0100 Subject: [PATCH 2160/6849] regulator: arizona: Add support for microphone supplies on Arizona devices The Wolfson Arizona platform is used for a range of low power audio hub CODECs. Many of these devices feature an integrated power supply for the microphone which is supported by this driver. Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 7 ++ drivers/regulator/Makefile | 1 + drivers/regulator/arizona-micsupp.c | 184 ++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 drivers/regulator/arizona-micsupp.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 434462ada7c0..e056c09661a2 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -89,6 +89,13 @@ config REGULATOR_AAT2870 If you have a AnalogicTech AAT2870 say Y to enable the regulator driver. +config REGULATOR_ARIZONA + tristate "Wolfson Arizona class devices" + depends on MFD_ARIZONA + help + Support for the regulators found on Wolfson Arizona class + devices. + config REGULATOR_DA903X tristate "Dialog Semiconductor DA9030/DA9034 regulators" depends on PMIC_DA903X diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e6f700748a3b..ec4a0cfb3ca7 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o +obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c new file mode 100644 index 000000000000..97d85b09a940 --- /dev/null +++ b/drivers/regulator/arizona-micsupp.c @@ -0,0 +1,184 @@ +/* + * arizona-micsupp.c -- Microphone supply for Arizona devices + * + * Copyright 2012 Wolfson Microelectronics PLC. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define ARIZONA_MICSUPP_MAX_SELECTOR 0x1f + +struct arizona_micsupp { + struct regulator_dev *regulator; + struct arizona *arizona; + + struct regulator_consumer_supply supply; + struct regulator_init_data init_data; +}; + +static int arizona_micsupp_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector > ARIZONA_MICSUPP_MAX_SELECTOR) + return -EINVAL; + + if (selector == ARIZONA_MICSUPP_MAX_SELECTOR) + return 3300000; + else + return (selector * 50000) + 1700000; +} + +static int arizona_micsupp_map_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + unsigned int voltage; + int selector; + + if (min_uV < 1700000) + min_uV = 1700000; + + if (min_uV >= 3300000) + selector = ARIZONA_MICSUPP_MAX_SELECTOR; + else + selector = DIV_ROUND_UP(min_uV - 1700000, 50000); + + if (selector < 0) + return -EINVAL; + + voltage = arizona_micsupp_list_voltage(rdev, selector); + if (voltage < min_uV || voltage > max_uV) + return -EINVAL; + + return selector; +} + +static struct regulator_ops arizona_micsupp_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + + .list_voltage = arizona_micsupp_list_voltage, + .map_voltage = arizona_micsupp_map_voltage, + + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, +}; + +static const struct regulator_desc arizona_micsupp = { + .name = "MICVDD", + .supply_name = "CPVDD", + .type = REGULATOR_VOLTAGE, + .n_voltages = ARIZONA_MICSUPP_MAX_SELECTOR + 1, + .ops = &arizona_micsupp_ops, + + .vsel_reg = ARIZONA_LDO2_CONTROL_1, + .vsel_mask = ARIZONA_LDO2_VSEL_MASK, + .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, + .enable_mask = ARIZONA_CPMIC_ENA, + + .owner = THIS_MODULE, +}; + +static const struct regulator_init_data arizona_micsupp_default = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_VOLTAGE, + .min_uV = 1700000, + .max_uV = 3300000, + }, + + .num_consumer_supplies = 1, +}; + +static __devinit int arizona_micsupp_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct arizona_micsupp *micsupp; + int ret; + + micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); + if (micsupp == NULL) { + dev_err(&pdev->dev, "Unable to allocate private data\n"); + return -ENOMEM; + } + + micsupp->arizona = arizona; + + /* + * Since the chip usually supplies itself we provide some + * default init_data for it. This will be overridden with + * platform data if provided. + */ + micsupp->init_data = arizona_micsupp_default; + micsupp->init_data.consumer_supplies = &micsupp->supply; + micsupp->supply.supply = "MICVDD"; + micsupp->supply.dev_name = dev_name(arizona->dev); + + config.dev = arizona->dev; + config.driver_data = micsupp; + config.regmap = arizona->regmap; + + if (arizona->pdata.micvdd) + config.init_data = arizona->pdata.micvdd; + else + config.init_data = &micsupp->init_data; + + micsupp->regulator = regulator_register(&arizona_micsupp, &config); + if (IS_ERR(micsupp->regulator)) { + ret = PTR_ERR(micsupp->regulator); + dev_err(arizona->dev, "Failed to register mic supply: %d\n", + ret); + return ret; + } + + platform_set_drvdata(pdev, micsupp); + + return 0; +} + +static __devexit int arizona_micsupp_remove(struct platform_device *pdev) +{ + struct arizona_micsupp *micsupp = platform_get_drvdata(pdev); + + regulator_unregister(micsupp->regulator); + + return 0; +} + +static struct platform_driver arizona_micsupp_driver = { + .probe = arizona_micsupp_probe, + .remove = __devexit_p(arizona_micsupp_remove), + .driver = { + .name = "arizona-micsupp", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(arizona_micsupp_driver); + +/* Module information */ +MODULE_AUTHOR("Mark Brown "); +MODULE_DESCRIPTION("Arizona microphone supply driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:arizona-micsupp"); -- GitLab From 3052cc2c92f11875d111d5b7b9b3ad535b3128b9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Jun 2012 20:11:40 +0200 Subject: [PATCH 2161/6849] dmaengine: Add wrapper for device_tx_status callback This patch adds a small inline wrapper for the devivce_tx_status callback of a dma device. This makes the source code of users of this function a bit more compact and a bit more legible. E.g.: -status = chan->device->device_tx_status(chan, cookie, &state) +status = dmaengine_tx_status(chan, cookie, &state) Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index ccec62f8e501..9c02a4508b25 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -674,6 +674,12 @@ static inline int dmaengine_resume(struct dma_chan *chan) return dmaengine_device_control(chan, DMA_RESUME, 0); } +static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *state) +{ + return chan->device->device_tx_status(chan, cookie, state); +} + static inline dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc) { return desc->tx_submit(desc); -- GitLab From c6da0ba8dfc826d476b75710abdf787ff17542b5 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Fri, 15 Jun 2012 11:04:08 +0800 Subject: [PATCH 2162/6849] dmaengine: mmp_tdma: add mmp tdma support Add support for two-channel dma under dmaengine support: mmp-adma and pxa910-squ Signed-off-by: Zhangfei Gao Signed-off-by: Leo Yan Signed-off-by: Qiao Zhou Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 10 + drivers/dma/Makefile | 1 + drivers/dma/mmp_tdma.c | 610 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 621 insertions(+) create mode 100644 drivers/dma/mmp_tdma.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index b3761153649d..90fec0e0e8f5 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -274,6 +274,16 @@ config DMA_SA11X0 SA-1110 SoCs. This DMA engine can only be used with on-chip devices. +config MMP_TDMA + bool "MMP Two-Channel DMA support" + default ARCH_MMP + select DMA_ENGINE + help + Support the MMP Two-Channel DMA engine. + This engine used for MMP Audio DMA and pxa910 SQU. + + Say Y here if you enabled MMP ADMA, otherwise say N. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index d679ea3f6ab0..370a65562242 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_PCH_DMA) += pch_dma.o obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o +obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c new file mode 100644 index 000000000000..8a15cf2163dc --- /dev/null +++ b/drivers/dma/mmp_tdma.c @@ -0,0 +1,610 @@ +/* + * Driver For Marvell Two-channel DMA Engine + * + * Copyright: Marvell International Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dmaengine.h" + +/* + * Two-Channel DMA registers + */ +#define TDBCR 0x00 /* Byte Count */ +#define TDSAR 0x10 /* Src Addr */ +#define TDDAR 0x20 /* Dst Addr */ +#define TDNDPR 0x30 /* Next Desc */ +#define TDCR 0x40 /* Control */ +#define TDCP 0x60 /* Priority*/ +#define TDCDPR 0x70 /* Current Desc */ +#define TDIMR 0x80 /* Int Mask */ +#define TDISR 0xa0 /* Int Status */ + +/* Two-Channel DMA Control Register */ +#define TDCR_SSZ_8_BITS (0x0 << 22) /* Sample Size */ +#define TDCR_SSZ_12_BITS (0x1 << 22) +#define TDCR_SSZ_16_BITS (0x2 << 22) +#define TDCR_SSZ_20_BITS (0x3 << 22) +#define TDCR_SSZ_24_BITS (0x4 << 22) +#define TDCR_SSZ_32_BITS (0x5 << 22) +#define TDCR_SSZ_SHIFT (0x1 << 22) +#define TDCR_SSZ_MASK (0x7 << 22) +#define TDCR_SSPMOD (0x1 << 21) /* SSP MOD */ +#define TDCR_ABR (0x1 << 20) /* Channel Abort */ +#define TDCR_CDE (0x1 << 17) /* Close Desc Enable */ +#define TDCR_PACKMOD (0x1 << 16) /* Pack Mode (ADMA Only) */ +#define TDCR_CHANACT (0x1 << 14) /* Channel Active */ +#define TDCR_FETCHND (0x1 << 13) /* Fetch Next Desc */ +#define TDCR_CHANEN (0x1 << 12) /* Channel Enable */ +#define TDCR_INTMODE (0x1 << 10) /* Interrupt Mode */ +#define TDCR_CHAINMOD (0x1 << 9) /* Chain Mode */ +#define TDCR_BURSTSZ_MSK (0x7 << 6) /* Burst Size */ +#define TDCR_BURSTSZ_4B (0x0 << 6) +#define TDCR_BURSTSZ_8B (0x1 << 6) +#define TDCR_BURSTSZ_16B (0x3 << 6) +#define TDCR_BURSTSZ_32B (0x6 << 6) +#define TDCR_BURSTSZ_64B (0x7 << 6) +#define TDCR_BURSTSZ_SQU_32B (0x7 << 6) +#define TDCR_BURSTSZ_128B (0x5 << 6) +#define TDCR_DSTDIR_MSK (0x3 << 4) /* Dst Direction */ +#define TDCR_DSTDIR_ADDR_HOLD (0x2 << 4) /* Dst Addr Hold */ +#define TDCR_DSTDIR_ADDR_INC (0x0 << 4) /* Dst Addr Increment */ +#define TDCR_SRCDIR_MSK (0x3 << 2) /* Src Direction */ +#define TDCR_SRCDIR_ADDR_HOLD (0x2 << 2) /* Src Addr Hold */ +#define TDCR_SRCDIR_ADDR_INC (0x0 << 2) /* Src Addr Increment */ +#define TDCR_DSTDESCCONT (0x1 << 1) +#define TDCR_SRCDESTCONT (0x1 << 0) + +/* Two-Channel DMA Int Mask Register */ +#define TDIMR_COMP (0x1 << 0) + +/* Two-Channel DMA Int Status Register */ +#define TDISR_COMP (0x1 << 0) + +/* + * Two-Channel DMA Descriptor Struct + * NOTE: desc's buf must be aligned to 16 bytes. + */ +struct mmp_tdma_desc { + u32 byte_cnt; + u32 src_addr; + u32 dst_addr; + u32 nxt_desc; +}; + +enum mmp_tdma_type { + MMP_AUD_TDMA = 0, + PXA910_SQU, +}; + +#define TDMA_ALIGNMENT 3 +#define TDMA_MAX_XFER_BYTES SZ_64K + +struct mmp_tdma_chan { + struct device *dev; + struct dma_chan chan; + struct dma_async_tx_descriptor desc; + struct tasklet_struct tasklet; + + struct mmp_tdma_desc *desc_arr; + phys_addr_t desc_arr_phys; + int desc_num; + enum dma_transfer_direction dir; + dma_addr_t dev_addr; + u32 burst_sz; + enum dma_slave_buswidth buswidth; + enum dma_status status; + + int idx; + enum mmp_tdma_type type; + int irq; + unsigned long reg_base; + + size_t buf_len; + size_t period_len; + size_t pos; +}; + +#define TDMA_CHANNEL_NUM 2 +struct mmp_tdma_device { + struct device *dev; + void __iomem *base; + struct dma_device device; + struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM]; + int irq; +}; + +#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan) + +static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys) +{ + writel(phys, tdmac->reg_base + TDNDPR); + writel(readl(tdmac->reg_base + TDCR) | TDCR_FETCHND, + tdmac->reg_base + TDCR); +} + +static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac) +{ + /* enable irq */ + writel(TDIMR_COMP, tdmac->reg_base + TDIMR); + /* enable dma chan */ + writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN, + tdmac->reg_base + TDCR); + tdmac->status = DMA_IN_PROGRESS; +} + +static void mmp_tdma_disable_chan(struct mmp_tdma_chan *tdmac) +{ + writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN, + tdmac->reg_base + TDCR); + tdmac->status = DMA_SUCCESS; +} + +static void mmp_tdma_resume_chan(struct mmp_tdma_chan *tdmac) +{ + writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN, + tdmac->reg_base + TDCR); + tdmac->status = DMA_IN_PROGRESS; +} + +static void mmp_tdma_pause_chan(struct mmp_tdma_chan *tdmac) +{ + writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN, + tdmac->reg_base + TDCR); + tdmac->status = DMA_PAUSED; +} + +static int mmp_tdma_config_chan(struct mmp_tdma_chan *tdmac) +{ + unsigned int tdcr; + + mmp_tdma_disable_chan(tdmac); + + if (tdmac->dir == DMA_MEM_TO_DEV) + tdcr = TDCR_DSTDIR_ADDR_HOLD | TDCR_SRCDIR_ADDR_INC; + else if (tdmac->dir == DMA_DEV_TO_MEM) + tdcr = TDCR_SRCDIR_ADDR_HOLD | TDCR_DSTDIR_ADDR_INC; + + if (tdmac->type == MMP_AUD_TDMA) { + tdcr |= TDCR_PACKMOD; + + switch (tdmac->burst_sz) { + case 4: + tdcr |= TDCR_BURSTSZ_4B; + break; + case 8: + tdcr |= TDCR_BURSTSZ_8B; + break; + case 16: + tdcr |= TDCR_BURSTSZ_16B; + break; + case 32: + tdcr |= TDCR_BURSTSZ_32B; + break; + case 64: + tdcr |= TDCR_BURSTSZ_64B; + break; + case 128: + tdcr |= TDCR_BURSTSZ_128B; + break; + default: + dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n"); + return -EINVAL; + } + + switch (tdmac->buswidth) { + case DMA_SLAVE_BUSWIDTH_1_BYTE: + tdcr |= TDCR_SSZ_8_BITS; + break; + case DMA_SLAVE_BUSWIDTH_2_BYTES: + tdcr |= TDCR_SSZ_16_BITS; + break; + case DMA_SLAVE_BUSWIDTH_4_BYTES: + tdcr |= TDCR_SSZ_32_BITS; + break; + default: + dev_err(tdmac->dev, "mmp_tdma: unknown bus size.\n"); + return -EINVAL; + } + } else if (tdmac->type == PXA910_SQU) { + tdcr |= TDCR_BURSTSZ_SQU_32B; + tdcr |= TDCR_SSPMOD; + } + + writel(tdcr, tdmac->reg_base + TDCR); + return 0; +} + +static int mmp_tdma_clear_chan_irq(struct mmp_tdma_chan *tdmac) +{ + u32 reg = readl(tdmac->reg_base + TDISR); + + if (reg & TDISR_COMP) { + /* clear irq */ + reg &= ~TDISR_COMP; + writel(reg, tdmac->reg_base + TDISR); + + return 0; + } + return -EAGAIN; +} + +static irqreturn_t mmp_tdma_chan_handler(int irq, void *dev_id) +{ + struct mmp_tdma_chan *tdmac = dev_id; + + if (mmp_tdma_clear_chan_irq(tdmac) == 0) { + tdmac->pos = (tdmac->pos + tdmac->period_len) % tdmac->buf_len; + tasklet_schedule(&tdmac->tasklet); + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + +static irqreturn_t mmp_tdma_int_handler(int irq, void *dev_id) +{ + struct mmp_tdma_device *tdev = dev_id; + int i, ret; + int irq_num = 0; + + for (i = 0; i < TDMA_CHANNEL_NUM; i++) { + struct mmp_tdma_chan *tdmac = tdev->tdmac[i]; + + ret = mmp_tdma_chan_handler(irq, tdmac); + if (ret == IRQ_HANDLED) + irq_num++; + } + + if (irq_num) + return IRQ_HANDLED; + else + return IRQ_NONE; +} + +static void dma_do_tasklet(unsigned long data) +{ + struct mmp_tdma_chan *tdmac = (struct mmp_tdma_chan *)data; + + if (tdmac->desc.callback) + tdmac->desc.callback(tdmac->desc.callback_param); + +} + +static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) +{ + struct gen_pool *gpool; + int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); + + gpool = sram_get_gpool("asram"); + if (tdmac->desc_arr) + gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, + size); + tdmac->desc_arr = NULL; + + return; +} + +static dma_cookie_t mmp_tdma_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(tx->chan); + + mmp_tdma_chan_set_desc(tdmac, tdmac->desc_arr_phys); + + return 0; +} + +static int mmp_tdma_alloc_chan_resources(struct dma_chan *chan) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + int ret; + + dma_async_tx_descriptor_init(&tdmac->desc, chan); + tdmac->desc.tx_submit = mmp_tdma_tx_submit; + + if (tdmac->irq) { + ret = devm_request_irq(tdmac->dev, tdmac->irq, + mmp_tdma_chan_handler, IRQF_DISABLED, "tdma", tdmac); + if (ret) + return ret; + } + return 1; +} + +static void mmp_tdma_free_chan_resources(struct dma_chan *chan) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + + if (tdmac->irq) + devm_free_irq(tdmac->dev, tdmac->irq, tdmac); + mmp_tdma_free_descriptor(tdmac); + return; +} + +struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac) +{ + struct gen_pool *gpool; + int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); + + gpool = sram_get_gpool("asram"); + if (!gpool) + return NULL; + + tdmac->desc_arr = (void *)gen_pool_alloc(gpool, size); + if (!tdmac->desc_arr) + return NULL; + + tdmac->desc_arr_phys = gen_pool_virt_to_phys(gpool, + (unsigned long)tdmac->desc_arr); + + return tdmac->desc_arr; +} + +static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( + struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, + size_t period_len, enum dma_transfer_direction direction, + void *context) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + struct mmp_tdma_desc *desc; + int num_periods = buf_len / period_len; + int i = 0, buf = 0; + + if (tdmac->status != DMA_SUCCESS) + return NULL; + + if (period_len > TDMA_MAX_XFER_BYTES) { + dev_err(tdmac->dev, + "maximum period size exceeded: %d > %d\n", + period_len, TDMA_MAX_XFER_BYTES); + goto err_out; + } + + tdmac->status = DMA_IN_PROGRESS; + tdmac->desc_num = num_periods; + desc = mmp_tdma_alloc_descriptor(tdmac); + if (!desc) + goto err_out; + + while (buf < buf_len) { + desc = &tdmac->desc_arr[i]; + + if (i + 1 == num_periods) + desc->nxt_desc = tdmac->desc_arr_phys; + else + desc->nxt_desc = tdmac->desc_arr_phys + + sizeof(*desc) * (i + 1); + + if (direction == DMA_MEM_TO_DEV) { + desc->src_addr = dma_addr; + desc->dst_addr = tdmac->dev_addr; + } else { + desc->src_addr = tdmac->dev_addr; + desc->dst_addr = dma_addr; + } + desc->byte_cnt = period_len; + dma_addr += period_len; + buf += period_len; + i++; + } + + tdmac->buf_len = buf_len; + tdmac->period_len = period_len; + tdmac->pos = 0; + + return &tdmac->desc; + +err_out: + tdmac->status = DMA_ERROR; + return NULL; +} + +static int mmp_tdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + struct dma_slave_config *dmaengine_cfg = (void *)arg; + int ret = 0; + + switch (cmd) { + case DMA_TERMINATE_ALL: + mmp_tdma_disable_chan(tdmac); + break; + case DMA_PAUSE: + mmp_tdma_pause_chan(tdmac); + break; + case DMA_RESUME: + mmp_tdma_resume_chan(tdmac); + break; + case DMA_SLAVE_CONFIG: + if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { + tdmac->dev_addr = dmaengine_cfg->src_addr; + tdmac->burst_sz = dmaengine_cfg->src_maxburst; + tdmac->buswidth = dmaengine_cfg->src_addr_width; + } else { + tdmac->dev_addr = dmaengine_cfg->dst_addr; + tdmac->burst_sz = dmaengine_cfg->dst_maxburst; + tdmac->buswidth = dmaengine_cfg->dst_addr_width; + } + tdmac->dir = dmaengine_cfg->direction; + return mmp_tdma_config_chan(tdmac); + default: + ret = -ENOSYS; + } + + return ret; +} + +static enum dma_status mmp_tdma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + + dma_set_residue(txstate, tdmac->buf_len - tdmac->pos); + + return tdmac->status; +} + +static void mmp_tdma_issue_pending(struct dma_chan *chan) +{ + struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + + mmp_tdma_enable_chan(tdmac); +} + +static int __devexit mmp_tdma_remove(struct platform_device *pdev) +{ + struct mmp_tdma_device *tdev = platform_get_drvdata(pdev); + + dma_async_device_unregister(&tdev->device); + return 0; +} + +static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev, + int idx, int irq, int type) +{ + struct mmp_tdma_chan *tdmac; + + if (idx >= TDMA_CHANNEL_NUM) { + dev_err(tdev->dev, "too many channels for device!\n"); + return -EINVAL; + } + + /* alloc channel */ + tdmac = devm_kzalloc(tdev->dev, sizeof(*tdmac), GFP_KERNEL); + if (!tdmac) { + dev_err(tdev->dev, "no free memory for DMA channels!\n"); + return -ENOMEM; + } + if (irq) + tdmac->irq = irq + idx; + tdmac->dev = tdev->dev; + tdmac->chan.device = &tdev->device; + tdmac->idx = idx; + tdmac->type = type; + tdmac->reg_base = (unsigned long)tdev->base + idx * 4; + tdmac->status = DMA_SUCCESS; + tdev->tdmac[tdmac->idx] = tdmac; + tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac); + + /* add the channel to tdma_chan list */ + list_add_tail(&tdmac->chan.device_node, + &tdev->device.channels); + + return 0; +} + +static int __devinit mmp_tdma_probe(struct platform_device *pdev) +{ + const struct platform_device_id *id = platform_get_device_id(pdev); + enum mmp_tdma_type type = id->driver_data; + struct mmp_tdma_device *tdev; + struct resource *iores; + int i, ret; + int irq = 0; + int chan_num = TDMA_CHANNEL_NUM; + + /* always have couple channels */ + tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL); + if (!tdev) + return -ENOMEM; + + tdev->dev = &pdev->dev; + iores = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!iores) + return -EINVAL; + + if (resource_size(iores) != chan_num) + tdev->irq = iores->start; + else + irq = iores->start; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iores) + return -EINVAL; + + tdev->base = devm_request_and_ioremap(&pdev->dev, iores); + if (!tdev->base) + return -EADDRNOTAVAIL; + + if (tdev->irq) { + ret = devm_request_irq(&pdev->dev, tdev->irq, + mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev); + if (ret) + return ret; + } + + dma_cap_set(DMA_SLAVE, tdev->device.cap_mask); + dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask); + + INIT_LIST_HEAD(&tdev->device.channels); + + /* initialize channel parameters */ + for (i = 0; i < chan_num; i++) { + ret = mmp_tdma_chan_init(tdev, i, irq, type); + if (ret) + return ret; + } + + tdev->device.dev = &pdev->dev; + tdev->device.device_alloc_chan_resources = + mmp_tdma_alloc_chan_resources; + tdev->device.device_free_chan_resources = + mmp_tdma_free_chan_resources; + tdev->device.device_prep_dma_cyclic = mmp_tdma_prep_dma_cyclic; + tdev->device.device_tx_status = mmp_tdma_tx_status; + tdev->device.device_issue_pending = mmp_tdma_issue_pending; + tdev->device.device_control = mmp_tdma_control; + tdev->device.copy_align = TDMA_ALIGNMENT; + + dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); + platform_set_drvdata(pdev, tdev); + + ret = dma_async_device_register(&tdev->device); + if (ret) { + dev_err(tdev->device.dev, "unable to register\n"); + return ret; + } + + dev_info(tdev->device.dev, "initialized\n"); + return 0; +} + +static const struct platform_device_id mmp_tdma_id_table[] = { + { "mmp-adma", MMP_AUD_TDMA }, + { "pxa910-squ", PXA910_SQU }, + { }, +}; + +static struct platform_driver mmp_tdma_driver = { + .driver = { + .name = "mmp-tdma", + .owner = THIS_MODULE, + }, + .id_table = mmp_tdma_id_table, + .probe = mmp_tdma_probe, + .remove = __devexit_p(mmp_tdma_remove), +}; + +module_platform_driver(mmp_tdma_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MMP Two-Channel DMA Driver"); +MODULE_ALIAS("platform:mmp-tdma"); +MODULE_AUTHOR("Leo Yan "); +MODULE_AUTHOR("Zhangfei Gao "); -- GitLab From 0718467c859f5571dc48d294596f841096f6a47a Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Mon, 18 Jun 2012 15:56:33 -0400 Subject: [PATCH 2163/6849] x86/nmi: Clean up register_nmi_handler() usage Implement a cleaner and easier to maintain version for the section warning fixes implemented in commit eeaaa96a3a21 ("x86/nmi: Fix section mismatch warnings on 32-bit"). Signed-off-by: Li Zhong Signed-off-by: Don Zickus Cc: Jan Beulich Link: http://lkml.kernel.org/r/1340049393-17771-1-git-send-email-dzickus@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/nmi.h | 20 +++----------------- arch/x86/kernel/nmi_selftest.c | 7 ++++--- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index dc580c42851c..c0fa356e90de 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h @@ -44,28 +44,14 @@ struct nmiaction { const char *name; }; -#define register_nmi_handler(t, fn, fg, n) \ +#define register_nmi_handler(t, fn, fg, n, init...) \ ({ \ - static struct nmiaction fn##_na = { \ + static struct nmiaction init fn##_na = { \ .handler = (fn), \ .name = (n), \ .flags = (fg), \ }; \ - __register_nmi_handler((t), &fn##_na); \ -}) - -/* - * For special handlers that register/unregister in the - * init section only. This should be considered rare. - */ -#define register_nmi_handler_initonly(t, fn, fg, n) \ -({ \ - static struct nmiaction fn##_na __initdata = { \ - .handler = (fn), \ - .name = (n), \ - .flags = (fg), \ - }; \ - __register_nmi_handler((t), &fn##_na); \ + __register_nmi_handler((t), &fn##_na); \ }) int __register_nmi_handler(unsigned int, struct nmiaction *); diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c index 149b8d9c6ad4..6d9582ec0324 100644 --- a/arch/x86/kernel/nmi_selftest.c +++ b/arch/x86/kernel/nmi_selftest.c @@ -42,7 +42,8 @@ static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs) static void __init init_nmi_testsuite(void) { /* trap all the unknown NMIs we may generate */ - register_nmi_handler_initonly(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk"); + register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk", + __initdata); } static void __init cleanup_nmi_testsuite(void) @@ -64,8 +65,8 @@ static void __init test_nmi_ipi(struct cpumask *mask) { unsigned long timeout; - if (register_nmi_handler_initonly(NMI_LOCAL, test_nmi_ipi_callback, - NMI_FLAG_FIRST, "nmi_selftest")) { + if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, + NMI_FLAG_FIRST, "nmi_selftest", __initdata)) { nmi_fail = FAILURE; return; } -- GitLab From e1b6fc55da40bc17e20795901cb786e3619f9be9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 18 Jun 2012 11:28:45 +0100 Subject: [PATCH 2164/6849] x86/microcode: Mark microcode_id[] as __initconst It's not being used for other than creating module aliases (i.e. no loadable section has any reference to it). Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/4FDF1EFD020000780008A65D@nat28.tlf.novell.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/microcode_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index fbdfc6917180..c383b3f8f397 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -504,7 +504,7 @@ static struct notifier_block __refdata mc_cpu_notifier = { #ifdef MODULE /* Autoload on Intel and AMD systems */ -static const struct x86_cpu_id microcode_id[] = { +static const struct x86_cpu_id __initconst microcode_id[] = { #ifdef CONFIG_MICROCODE_INTEL { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, #endif -- GitLab From 0d26d1d873a302828e064737746c53a2689e6c0f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 18 Jun 2012 11:30:20 +0100 Subject: [PATCH 2165/6849] x86/mm: Mark free_initrd_mem() as __init ... matching various other architectures. Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/4FDF1F5C020000780008A661@nat28.tlf.novell.com Signed-off-by: Ingo Molnar --- arch/x86/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index bc4e9d84157f..e0e6990723e9 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -385,7 +385,7 @@ void free_initmem(void) } #ifdef CONFIG_BLK_DEV_INITRD -void free_initrd_mem(unsigned long start, unsigned long end) +void __init free_initrd_mem(unsigned long start, unsigned long end) { /* * end could be not aligned, and We can not align that, -- GitLab From 0fa0e2f02e8edfbdb5f86d1cab0fa6dc0517489f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 18 Jun 2012 11:40:04 +0100 Subject: [PATCH 2166/6849] x86: Move call to print_modules() out of show_regs() Printing the list of loaded modules is really unrelated to what this function is about, and is particularly unnecessary in the context of the SysRQ key handling (gets printed so far over and over). It should really be the caller of the function to decide whether this piece of information is useful (and to avoid redundantly printing it). Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/4FDF21A4020000780008A67F@nat28.tlf.novell.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/dumpstack.c | 1 + arch/x86/kernel/dumpstack_32.c | 1 - arch/x86/kernel/dumpstack_64.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 87d3b5d663cd..ae42418bc50f 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -271,6 +271,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) return 1; + print_modules(); show_regs(regs); #ifdef CONFIG_X86_32 if (user_mode_vm(regs)) { diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 3a8aced11ae9..1038a417ea53 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -86,7 +86,6 @@ void show_regs(struct pt_regs *regs) { int i; - print_modules(); __show_regs(regs, !user_mode_vm(regs)); pr_emerg("Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index c582e9c5bd1a..b653675d5288 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -254,7 +254,6 @@ void show_regs(struct pt_regs *regs) sp = regs->sp; printk("CPU %d ", cpu); - print_modules(); __show_regs(regs, 1); printk(KERN_DEFAULT "Process %s (pid: %d, threadinfo %p, task %p)\n", cur->comm, cur->pid, task_thread_info(cur), cur); -- GitLab From 61600ef8483924039dcdec8b4717ca32bd3353c6 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 28 May 2012 14:44:30 +0800 Subject: [PATCH 2167/6849] ceph: check PG_Private flag before accessing page->private I got lots of NULL pointer dereference Oops when compiling kernel on ceph. The bug is because the kernel page migration routine replaces some pages in the page cache with new pages, these new pages' private can be non-zero. Signed-off-by: Zheng Yan Signed-off-by: Sage Weil (cherry picked from commit 28c0254ede13ab575d2df5c6585ed3d4817c3e6b) --- fs/ceph/addr.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 173b1d22e59b..8b67304e4b80 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -54,7 +54,12 @@ (CONGESTION_ON_THRESH(congestion_kb) - \ (CONGESTION_ON_THRESH(congestion_kb) >> 2)) - +static inline struct ceph_snap_context *page_snap_context(struct page *page) +{ + if (PagePrivate(page)) + return (void *)page->private; + return NULL; +} /* * Dirty a page. Optimistically adjust accounting, on the assumption @@ -142,10 +147,9 @@ static void ceph_invalidatepage(struct page *page, unsigned long offset) { struct inode *inode; struct ceph_inode_info *ci; - struct ceph_snap_context *snapc = (void *)page->private; + struct ceph_snap_context *snapc = page_snap_context(page); BUG_ON(!PageLocked(page)); - BUG_ON(!page->private); BUG_ON(!PagePrivate(page)); BUG_ON(!page->mapping); @@ -182,7 +186,6 @@ static int ceph_releasepage(struct page *page, gfp_t g) struct inode *inode = page->mapping ? page->mapping->host : NULL; dout("%p releasepage %p idx %lu\n", inode, page, page->index); WARN_ON(PageDirty(page)); - WARN_ON(page->private); WARN_ON(PagePrivate(page)); return 0; } @@ -443,7 +446,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) osdc = &fsc->client->osdc; /* verify this is a writeable snap context */ - snapc = (void *)page->private; + snapc = page_snap_context(page); if (snapc == NULL) { dout("writepage %p page %p not dirty?\n", inode, page); goto out; @@ -451,7 +454,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) oldest = get_oldest_context(inode, &snap_size); if (snapc->seq > oldest->seq) { dout("writepage %p page %p snapc %p not writeable - noop\n", - inode, page, (void *)page->private); + inode, page, snapc); /* we should only noop if called by kswapd */ WARN_ON((current->flags & PF_MEMALLOC) == 0); ceph_put_snap_context(oldest); @@ -591,7 +594,7 @@ static void writepages_finish(struct ceph_osd_request *req, clear_bdi_congested(&fsc->backing_dev_info, BLK_RW_ASYNC); - ceph_put_snap_context((void *)page->private); + ceph_put_snap_context(page_snap_context(page)); page->private = 0; ClearPagePrivate(page); dout("unlocking %d %p\n", i, page); @@ -795,7 +798,7 @@ get_more_pages: } /* only if matching snap context */ - pgsnapc = (void *)page->private; + pgsnapc = page_snap_context(page); if (pgsnapc->seq > snapc->seq) { dout("page snapc %p %lld > oldest %p %lld\n", pgsnapc, pgsnapc->seq, snapc, snapc->seq); @@ -984,7 +987,7 @@ retry_locked: BUG_ON(!ci->i_snap_realm); down_read(&mdsc->snap_rwsem); BUG_ON(!ci->i_snap_realm->cached_context); - snapc = (void *)page->private; + snapc = page_snap_context(page); if (snapc && snapc != ci->i_head_snapc) { /* * this page is already dirty in another (older) snap -- GitLab From 680584fab05efff732b5ae16ad601ba994d7b505 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 4 Jun 2012 14:43:32 -0500 Subject: [PATCH 2168/6849] libceph: osd_client: don't drop reply reference too early In ceph_osdc_release_request(), a reference to the r_reply message is dropped. But just after that, that same message is revoked if it was in use to receive an incoming reply. Reorder these so we are sure we hold a reference until we're actually done with the message. Signed-off-by: Alex Elder Reviewed-by: Sage Weil (cherry picked from commit ab8cb34a4b2f60281a4b18b1f1ad23bc2313d91b) --- net/ceph/osd_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 1ffebed5ce0f..13538da41dd6 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -139,8 +139,6 @@ void ceph_osdc_release_request(struct kref *kref) if (req->r_request) ceph_msg_put(req->r_request); - if (req->r_reply) - ceph_msg_put(req->r_reply); if (req->r_con_filling_msg) { dout("release_request revoking pages %p from con %p\n", req->r_pages, req->r_con_filling_msg); @@ -148,6 +146,8 @@ void ceph_osdc_release_request(struct kref *kref) req->r_reply); ceph_con_put(req->r_con_filling_msg); } + if (req->r_reply) + ceph_msg_put(req->r_reply); if (req->r_own_pages) ceph_release_page_vector(req->r_pages, req->r_num_pages); -- GitLab From 88ed6ea0b295f8e2383d599a04027ec596cdf97b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 31 May 2012 20:22:18 -0700 Subject: [PATCH 2169/6849] libceph: use con get/put ops from osd_client There were a few direct calls to ceph_con_{get,put}() instead of the con ops from osd_client.c. This is a bug since those ops aren't defined to be ceph_con_get/put. This breaks refcounting on the ceph_osd structs that contain the ceph_connections, and could lead to all manner of strangeness. The purpose of the ->get and ->put methods in a ceph connection are to allow the connection to indicate it has a reference to something external to the messaging system, *not* to indicate something external has a reference to the connection. [elder@inktank.com: added that last sentence] Signed-off-by: Sage Weil Reviewed-by: Alex Elder (cherry picked from commit 0d47766f14211a73eaf54cab234db134ece79f49) --- net/ceph/osd_client.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 13538da41dd6..ca59e66c9787 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -144,7 +144,7 @@ void ceph_osdc_release_request(struct kref *kref) req->r_pages, req->r_con_filling_msg); ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); - ceph_con_put(req->r_con_filling_msg); + req->r_con_filling_msg->ops->put(req->r_con_filling_msg); } if (req->r_reply) ceph_msg_put(req->r_reply); @@ -1216,7 +1216,7 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, if (req->r_con_filling_msg == con && req->r_reply == msg) { dout(" dropping con_filling_msg ref %p\n", con); req->r_con_filling_msg = NULL; - ceph_con_put(con); + con->ops->put(con); } if (!req->r_got_reply) { @@ -2028,7 +2028,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, dout("get_reply revoking msg %p from old con %p\n", req->r_reply, req->r_con_filling_msg); ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); - ceph_con_put(req->r_con_filling_msg); + req->r_con_filling_msg->ops->put(req->r_con_filling_msg); req->r_con_filling_msg = NULL; } @@ -2063,7 +2063,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, #endif } *skip = 0; - req->r_con_filling_msg = ceph_con_get(con); + req->r_con_filling_msg = con->ops->get(con); dout("get_reply tid %lld %p\n", tid, m); out: -- GitLab From b132cf4c733f91bb4dd2277ea049243cf16e8b66 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 6 Jun 2012 19:35:55 -0500 Subject: [PATCH 2170/6849] rbd: Clear ceph_msg->bio_iter for retransmitted message The bug can cause NULL pointer dereference in write_partial_msg_pages Signed-off-by: Zheng Yan Reviewed-by: Alex Elder (cherry picked from commit 43643528cce60ca184fe8197efa8e8da7c89a037) --- net/ceph/messenger.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 524f4e4f598b..b332c3d76059 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -563,6 +563,10 @@ static void prepare_write_message(struct ceph_connection *con) m->hdr.seq = cpu_to_le64(++con->out_seq); m->needs_out_seq = false; } +#ifdef CONFIG_BLOCK + else + m->bio_iter = NULL; +#endif dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", m, con->out_seq, le16_to_cpu(m->hdr.type), -- GitLab From 642c0dbde32f34baa7886e988a067089992adc8f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sun, 10 Jun 2012 20:43:56 -0700 Subject: [PATCH 2171/6849] libceph: flush msgr queue during mon_client shutdown We need to flush the msgr workqueue during mon_client shutdown to ensure that any work affecting our embedded ceph_connection is finished so that we can be safely destroyed. Previously, we were flushing the work queue after osd_client shutdown and before mon_client shutdown to ensure that any osd connection refs to authorizers are flushed. Remove the redundant flush, and document in the comment that the mon_client flush is needed to cover that case as well. Signed-off-by: Sage Weil Reviewed-by: Alex Elder (cherry picked from commit f3dea7edd3d449fe7a6d402c1ce56a294b985261) --- net/ceph/ceph_common.c | 7 ------- net/ceph/mon_client.c | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index a776f751edbf..ba4323bce0e9 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -504,13 +504,6 @@ void ceph_destroy_client(struct ceph_client *client) /* unmount */ ceph_osdc_stop(&client->osdc); - /* - * make sure osd connections close out before destroying the - * auth module, which is needed to free those connections' - * ceph_authorizers. - */ - ceph_msgr_flush(); - ceph_monc_stop(&client->monc); ceph_debugfs_client_cleanup(client); diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 10d6008d31f2..d0649a9655be 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -847,6 +847,14 @@ void ceph_monc_stop(struct ceph_mon_client *monc) mutex_unlock(&monc->mutex); + /* + * flush msgr queue before we destroy ourselves to ensure that: + * - any work that references our embedded con is finished. + * - any osd_client or other work that may reference an authorizer + * finishes before we shut down the auth subsystem. + */ + ceph_msgr_flush(); + ceph_auth_destroy(monc->auth); ceph_msg_put(monc->m_auth); -- GitLab From 9f65b2b60c42c1e2d885acede4443b53f141c987 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jun 2012 22:29:14 +0900 Subject: [PATCH 2172/6849] sh: pfc: Kill off unused pinmux bias flags. WANT_PULLUP/DOWN were never interfaced with anything, so just kill them off. Signed-off-by: Paul Mundt --- include/linux/sh_pfc.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h index 95dad340794a..c06a47313a25 100644 --- a/include/linux/sh_pfc.h +++ b/include/linux/sh_pfc.h @@ -25,8 +25,6 @@ typedef unsigned short pinmux_flag_t; #define PINMUX_TYPE_INPUT_PULLDOWN 6 #define PINMUX_FLAG_TYPE (0x7) -#define PINMUX_FLAG_WANT_PULLUP (1 << 3) -#define PINMUX_FLAG_WANT_PULLDOWN (1 << 4) #define PINMUX_FLAG_DBIT_SHIFT 5 #define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) -- GitLab From 310018d52ec06c19dc946c2807c07c8b70e2d1a6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 20 Jun 2012 07:18:15 -0700 Subject: [PATCH 2173/6849] ARM: OMAP2+: Fix MUSB ifdefs for platform init code Commit 62285963 (usb: musb: drop a gigantic amount of ifdeferry) got rid of a bunch of ifdefs in the MUSB code. Looks like the platform init code is still using these dropped defines though, which in many cases results the board defaulting always to host mode. Currently the situation is that USB_MUSB_HDRC is the main Kconfig option with additional USB_GADGET_MUSB_HDRC so only these two should be used to select between host and OTG mode. Fix the situation for omaps. The following users should fix the platform init code in a similar way: Dropped Kconfig option Current users USB_MUSB_OTG blackfin, davinci, not in Kconfigs USB_MUSB_PERIPHERAL davinci, not in Kconfigs USB_MUSB_HOST davinci, not in Kconfigs USB_MUSB_HDRC_HCD blackfin, not in Kconfigs USB_MUSB_OTG blackfin, not in Kconfigs Cc: Mike Frysinger Cc: Sekhar Nori Cc: linux-usb@vger.kernel.org Cc: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-n8x0.c | 6 ++---- arch/arm/mach-omap2/omap_phy_internal.c | 6 ------ arch/arm/mach-omap2/usb-musb.c | 6 ++---- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 8ca14e88a31a..2c5d0ed75285 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -83,11 +83,9 @@ static struct musb_hdrc_config musb_config = { }; static struct musb_hdrc_platform_data tusb_data = { -#if defined(CONFIG_USB_MUSB_OTG) +#ifdef CONFIG_USB_GADGET_MUSB_HDRC .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_PERIPHERAL) - .mode = MUSB_PERIPHERAL, -#else /* defined(CONFIG_USB_MUSB_HOST) */ +#else .mode = MUSB_HOST, #endif .set_power = tusb_set_power, diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 4c90477e6f82..d52651a05daa 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -239,21 +239,15 @@ void am35x_set_mode(u8 musb_mode) devconf2 &= ~CONF2_OTGMODE; switch (musb_mode) { -#ifdef CONFIG_USB_MUSB_HDRC_HCD case MUSB_HOST: /* Force VBUS valid, ID = 0 */ devconf2 |= CONF2_FORCE_HOST; break; -#endif -#ifdef CONFIG_USB_GADGET_MUSB_HDRC case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ devconf2 |= CONF2_FORCE_DEVICE; break; -#endif -#ifdef CONFIG_USB_MUSB_OTG case MUSB_OTG: /* Don't override the VBUS/ID comparators */ devconf2 |= CONF2_NO_OVERRIDE; break; -#endif default: pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); } diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index b19d1b43c12e..c4a576856661 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -41,12 +41,10 @@ static struct musb_hdrc_config musb_config = { }; static struct musb_hdrc_platform_data musb_plat = { -#ifdef CONFIG_USB_MUSB_OTG +#ifdef CONFIG_USB_GADGET_MUSB_HDRC .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_HDRC_HCD) +#else .mode = MUSB_HOST, -#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) - .mode = MUSB_PERIPHERAL, #endif /* .clock is set dynamically */ .config = &musb_config, -- GitLab From 3d09b33fecf204561e5c7126648ec05c756c631c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 20 Jun 2012 07:18:15 -0700 Subject: [PATCH 2174/6849] ARM: OMAP2: Fix tusb6010 GPIO interrupt for n8x0 Here's one more gpio_to_irq conversion that we missed earlier. Tested with n800 in gadget mode using USB_ETH. Cc: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/usb-tusb6010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index db84a46ce7fd..805bea6edf17 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -300,7 +300,7 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, printk(error, 3, status); return status; } - tusb_resources[2].start = irq + IH_GPIO_BASE; + tusb_resources[2].start = gpio_to_irq(irq); /* set up memory timings ... can speed them up later */ if (!ps_refclk) { -- GitLab From 95dca12d6bf2dd5e7720506b8f9786318899b8d6 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 12 Jun 2012 19:40:46 -0500 Subject: [PATCH 2175/6849] arm/dts: OMAP2: Fix interrupt controller binding When booting with device-tree on an OMAP2420H4, the kernel is hanging when initialising the interrupts and following kernel dumps is seen ... [ 0.000000] ------------[ cut here ]------------ [ 0.000000] WARNING: at arch/arm/mach-omap2/irq.c:271 omap_intc_of_init+0x50/0xb4() [ 0.000000] unable to get intc registers [ 0.000000] Modules linked in: [ 0.000000] [] (unwind_backtrace+0x0/0xf4) from [] (warn_slowpath_common+0x4c/0x64) [ 0.000000] [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x30/0x40) [ 0.000000] [] (warn_slowpath_fmt+0x30/0x40) from [] (omap_intc_of_init+0x50/0xb4) [ 0.000000] [] (omap_intc_of_init+0x50/0xb4) from [] (of_irq_init+0x144/0x288) [ 0.000000] [] (of_irq_init+0x144/0x288) from [] (init_IRQ+0x14/0x1c) [ 0.000000] [] (init_IRQ+0x14/0x1c) from [] (start_kernel+0x198/0x304) [ 0.000000] [] (start_kernel+0x198/0x304) from [<80008044>] (0x80008044) [ 0.000000] ---[ end trace 1b75b31a2719ed1c ]--- [ 0.000000] of_irq_init: children remain, but no parents The OMAP2 interrupt controller binding is missing the number of interrupts and interrupt controller register address. Adding these fixes the problem. Signed-off-by: Jon Hunter Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap2.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index f2ab4ea7cc0e..581cb081cb0f 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -44,6 +44,8 @@ compatible = "ti,omap2-intc"; interrupt-controller; #interrupt-cells = <1>; + ti,intc-size = <96>; + reg = <0x480FE000 0x1000>; }; uart1: serial@4806a000 { -- GitLab From aef2b89662b8a7506846d0dc0df672d196ddf8d0 Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Wed, 9 May 2012 15:15:03 -0700 Subject: [PATCH 2176/6849] ARM: OMAP: Fix Beagleboard DVI reset gpio Commit e813a55eb9c9bc6c8039fb16332cf43402125b30 ("OMAP: board-files: remove custom PD GPIO handling for DVI output") moved TFP410 chip's powerdown-gpio handling from the board files to the tfp410 driver. One gpio_request_one(powerdown-gpio, ...) was mistakenly left unremoved in the Beagle board file. This causes the tfp410 driver to fail to request the gpio on Beagle, causing the driver to fail and thus the DVI output doesn't work. This patch removes several boot errors from board-omap3beagle.c: - gpio_request: gpio--22 (DVI reset) status -22 - Unable to get DVI reset GPIO There is a combination of leftover code and revision confusion. Additionally, xM support is currently a hack. For original Beagleboard this removes the double initialization of GPIO 170, properly configures it as an output, and wraps the initialization in an if block so that xM does not attempt to request it. For Beagleboard xM it removes reference to GPIO 129 which was part of rev A1 and A2 designs, but never functioned. It then properly assigns beagle_dvi_device.reset_gpio in beagle_twl_gpio_setup and removes the hack of initializing it high. Additionally, it uses gpio_set_value_cansleep since this GPIO is connected through i2c. Unfortunately, there is no way to tell the difference between xM A2 and A3. However, GPIO 129 does not function on rev A1 and A2, and the TWL GPIO used on A3 and beyond is not used on rev A1 and A2, there are no problems created by this fix. Tested on Beagleboard-xM Rev C1 and Beagleboard Rev B4. Signed-off-by: Russ Dill Acked-by: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-omap3beagle.c | 28 +++++++++++-------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 79c6909eeb78..580fd17208da 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -81,13 +81,13 @@ static u8 omap3_beagle_version; static struct { int mmc1_gpio_wp; int usb_pwr_level; - int reset_gpio; + int dvi_pd_gpio; int usr_button_gpio; int mmc_caps; } beagle_config = { .mmc1_gpio_wp = -EINVAL, .usb_pwr_level = GPIOF_OUT_INIT_LOW, - .reset_gpio = 129, + .dvi_pd_gpio = -EINVAL, .usr_button_gpio = 4, .mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, }; @@ -126,21 +126,21 @@ static void __init omap3_beagle_init_rev(void) printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX; beagle_config.mmc1_gpio_wp = 29; - beagle_config.reset_gpio = 170; + beagle_config.dvi_pd_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 6: printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3; beagle_config.mmc1_gpio_wp = 23; - beagle_config.reset_gpio = 170; + beagle_config.dvi_pd_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 5: printk(KERN_INFO "OMAP3 Beagle Rev: C4\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; beagle_config.mmc1_gpio_wp = 23; - beagle_config.reset_gpio = 170; + beagle_config.dvi_pd_gpio = 170; beagle_config.usr_button_gpio = 7; break; case 0: @@ -274,11 +274,9 @@ static int beagle_twl_gpio_setup(struct device *dev, if (r) pr_err("%s: unable to configure nDVI_PWR_EN\n", __func__); - r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, - "DVI_LDO_EN"); - if (r) - pr_err("%s: unable to configure DVI_LDO_EN\n", - __func__); + + beagle_config.dvi_pd_gpio = gpio + 2; + } else { /* * REVISIT: need ehci-omap hooks for external VBUS @@ -287,7 +285,7 @@ static int beagle_twl_gpio_setup(struct device *dev, if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) pr_err("%s: unable to configure EHCI_nOC\n", __func__); } - dvi_panel.power_down_gpio = beagle_config.reset_gpio; + dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level, "nEN_USB_PWR"); @@ -499,7 +497,7 @@ static void __init omap3_beagle_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_beagle_init_rev(); - if (beagle_config.mmc1_gpio_wp != -EINVAL) + if (gpio_is_valid(beagle_config.mmc1_gpio_wp)) omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); mmc[0].caps = beagle_config.mmc_caps; omap_hsmmc_init(mmc); @@ -510,15 +508,13 @@ static void __init omap3_beagle_init(void) platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); + if (gpio_is_valid(beagle_config.dvi_pd_gpio)) + omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); omap_display_init(&beagle_dss_data); omap_serial_init(); omap_sdrc_init(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); - omap_mux_init_gpio(170, OMAP_PIN_INPUT); - /* REVISIT leave DVI powered down until it's needed ... */ - gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); - usb_musb_init(NULL); usbhs_init(&usbhs_bdata); omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, -- GitLab From 8b8d654b55648561287bd8baca0f75f964a17038 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 20 Jun 2012 16:32:22 +0200 Subject: [PATCH 2177/6849] ALSA: hda - Move one-time init codes from generic_hdmi_init() The codes to initialize work struct or create a proc interface should be called only once and never although it's called many times through the init callback. Move that stuff into patch_generic_hdmi() so that it's called only once. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index db8f6928f839..64f1fedfd535 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1277,23 +1277,34 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) return 0; } -static int generic_hdmi_init(struct hda_codec *codec) +static int generic_hdmi_init_per_pins(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; int pin_idx; for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; - hda_nid_t pin_nid = per_pin->pin_nid; struct hdmi_eld *eld = &per_pin->sink_eld; - hdmi_init_pin(codec, pin_nid); - snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); - per_pin->codec = codec; INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); snd_hda_eld_proc_new(codec, eld, pin_idx); } + return 0; +} + +static int generic_hdmi_init(struct hda_codec *codec) +{ + struct hdmi_spec *spec = codec->spec; + int pin_idx; + + for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { + struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; + hda_nid_t pin_nid = per_pin->pin_nid; + + hdmi_init_pin(codec, pin_nid); + snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); + } snd_hda_jack_report_sync(codec); return 0; } @@ -1338,6 +1349,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) return -EINVAL; } codec->patch_ops = generic_hdmi_patch_ops; + generic_hdmi_init_per_pins(codec); init_channel_allocations(); -- GitLab From c32c44cb58d212513243744878423abd207bc8a8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Jun 2012 20:11:40 +0200 Subject: [PATCH 2178/6849] dmaengine: Add wrapper for device_tx_status callback This patch adds a small inline wrapper for the devivce_tx_status callback of a dma device. This makes the source code of users of this function a bit more compact and a bit more legible. E.g.: -status = chan->device->device_tx_status(chan, cookie, &state) +status = dmaengine_tx_status(chan, cookie, &state) Signed-off-by: Lars-Peter Clausen Acked-by Vinod Koul Signed-off-by: Mark Brown --- include/linux/dmaengine.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 56377df39124..cc0756a35ae3 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -670,6 +670,12 @@ static inline int dmaengine_resume(struct dma_chan *chan) return dmaengine_device_control(chan, DMA_RESUME, 0); } +static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *state) +{ + return chan->device->device_tx_status(chan, cookie, state); +} + static inline dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc) { return desc->tx_submit(desc); -- GitLab From 9883ab229d61b884323f9186b1bd4a41373a491b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Jun 2012 20:11:41 +0200 Subject: [PATCH 2179/6849] ASoC: dmaengine-pcm: Rename and deprecate snd_dmaengine_pcm_pointer Currently the sound dmaengine pcm helper functions implement the pcm_pointer callback by trying to count the number of elapsed periods. This is done by advancing the stream position in the dmaengine callback by one period. Unfortunately there is no guarantee that the callback will be called for each elapsed period. It may be possible that under high system load it is only called once for multiple elapsed periods. This patch renames the current implementation and documents its shortcomings and that it should not be used anymore in new drivers. The next patch will introduce a new snd_dmaengine_pcm_pointer which will be implemented based on querying the current stream position from the dma device. Signed-off-by: Lars-Peter Clausen Acked-by Vinod Koul Acked-by: Dong Aisheng --- include/sound/dmaengine_pcm.h | 2 +- sound/soc/ep93xx/ep93xx-pcm.c | 2 +- sound/soc/fsl/imx-pcm-dma.c | 2 +- sound/soc/mxs/mxs-pcm.c | 2 +- sound/soc/soc-dmaengine-pcm.c | 10 +++++----- sound/soc/ux500/ux500_pcm.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index a8fcaa6d531f..ea5791583fed 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -38,7 +38,7 @@ void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream); int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd); -snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream); +snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data); diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index 162dbb74f4cc..4eea98b42bc8 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c @@ -136,7 +136,7 @@ static struct snd_pcm_ops ep93xx_pcm_ops = { .hw_params = ep93xx_pcm_hw_params, .hw_free = ep93xx_pcm_hw_free, .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer, + .pointer = snd_dmaengine_pcm_pointer_no_residue, .mmap = ep93xx_pcm_mmap, }; diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index f3c0a5ef35c8..48f9d886f020 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -141,7 +141,7 @@ static struct snd_pcm_ops imx_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer, + .pointer = snd_dmaengine_pcm_pointer_no_residue, .mmap = snd_imx_pcm_mmap, }; diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 373dec90579f..f82d766cbf9e 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -141,7 +141,7 @@ static struct snd_pcm_ops mxs_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_mxs_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer, + .pointer = snd_dmaengine_pcm_pointer_no_residue, .mmap = snd_mxs_pcm_mmap, }; diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 475695234b3d..7c0877e3731c 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -200,18 +200,18 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd) EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); /** - * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation + * snd_dmaengine_pcm_pointer_no_residue - dmaengine based PCM pointer implementation * @substream: PCM substream * - * This function can be used as the PCM pointer callback for dmaengine based PCM - * driver implementations. + * This function is deprecated and should not be used by new drivers, as its + * results may be unreliable. */ -snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) +snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); return bytes_to_frames(substream->runtime, prtd->pos); } -EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue); static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd, dma_filter_fn filter_fn, void *filter_data) diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 97d8e4de29c2..1a04e248453c 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -261,7 +261,7 @@ static struct snd_pcm_ops ux500_pcm_ops = { .hw_params = ux500_pcm_hw_params, .hw_free = ux500_pcm_hw_free, .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer, + .pointer = snd_dmaengine_pcm_pointer_no_residue, .mmap = ux500_pcm_mmap }; -- GitLab From 3528f27a5d4ac299e2d8cbe7297c1e9edd601ee6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Jun 2012 20:11:42 +0200 Subject: [PATCH 2180/6849] ASoC: dmaengine-pcm: Add support for querying stream position from DMA driver Currently the sound dmaengine pcm helper functions implement the pcm_pointer callback by trying to count the number of elapsed periods. This is done by advancing the stream position in the dmaengine callback by one period. Unfortunately there is no guarantee that the callback will be called for each elapsed period. It may be possible that under high system load it is only called once for multiple elapsed periods. This patch addresses the issue by implementing support for querying the current stream position directly from the dmaengine driver. Since not all dmaengine drivers support reporting the stream position yet the old period counting implementation is kept for now. Furthermore the new mechanism allows to report the stream position with a sub-period granularity, given that the dmaengine driver supports this. Signed-off-by: Lars-Peter Clausen Acked-by: Vinod Koul Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 1 + sound/soc/soc-dmaengine-pcm.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index ea5791583fed..b877334bbb0f 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -38,6 +38,7 @@ void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream); int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd); +snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream); snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 7c0877e3731c..2995334d8000 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -30,6 +30,7 @@ struct dmaengine_pcm_runtime_data { struct dma_chan *dma_chan; + dma_cookie_t cookie; unsigned int pos; @@ -153,7 +154,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream) desc->callback = dmaengine_pcm_dma_complete; desc->callback_param = substream; - dmaengine_submit(desc); + prtd->cookie = dmaengine_submit(desc); return 0; } @@ -213,6 +214,32 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue); +/** + * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation + * @substream: PCM substream + * + * This function can be used as the PCM pointer callback for dmaengine based PCM + * driver implementations. + */ +snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + struct dma_tx_state state; + enum dma_status status; + unsigned int buf_size; + unsigned int pos = 0; + + status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state); + if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) { + buf_size = snd_pcm_lib_buffer_bytes(substream); + if (state.residue > 0 && state.residue <= buf_size) + pos = buf_size - state.residue; + } + + return bytes_to_frames(substream->runtime, pos); +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); + static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd, dma_filter_fn filter_fn, void *filter_data) { -- GitLab From 06d5631f56460917af3d9417ef63811cf0cad9ce Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jun 2012 00:03:41 +0900 Subject: [PATCH 2181/6849] sh: pfc: Verify pin type encoding size at build time. The encoding is tightly packed, and future changes (such as pinconf-generic support) can easily lead to a situation where we violate the encoding constraints and trample data bit/reg bits. This plugs in some sanity checks by way of a BUILD_BUG_ON() to blow up if we fail to fit. Signed-off-by: Paul Mundt --- drivers/sh/pfc.c | 5 +++++ include/linux/sh_pfc.h | 23 ++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c index 8a9ae09603d6..ce4579ebd602 100644 --- a/drivers/sh/pfc.c +++ b/drivers/sh/pfc.c @@ -549,6 +549,11 @@ int register_sh_pfc(struct sh_pfc *pfc) int (*initroutine)(struct sh_pfc *) = NULL; int ret; + /* + * Ensure that the type encoding fits + */ + BUILD_BUG_ON(PINMUX_FLAG_TYPE > ((1 << PINMUX_FLAG_DBIT_SHIFT) - 1)); + if (sh_pfc) return -EBUSY; diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h index c06a47313a25..ed1d8234f6ae 100644 --- a/include/linux/sh_pfc.h +++ b/include/linux/sh_pfc.h @@ -16,15 +16,18 @@ typedef unsigned short pinmux_enum_t; typedef unsigned short pinmux_flag_t; -#define PINMUX_TYPE_NONE 0 -#define PINMUX_TYPE_FUNCTION 1 -#define PINMUX_TYPE_GPIO 2 -#define PINMUX_TYPE_OUTPUT 3 -#define PINMUX_TYPE_INPUT 4 -#define PINMUX_TYPE_INPUT_PULLUP 5 -#define PINMUX_TYPE_INPUT_PULLDOWN 6 +enum { + PINMUX_TYPE_NONE, -#define PINMUX_FLAG_TYPE (0x7) + PINMUX_TYPE_FUNCTION, + PINMUX_TYPE_GPIO, + PINMUX_TYPE_OUTPUT, + PINMUX_TYPE_INPUT, + PINMUX_TYPE_INPUT_PULLUP, + PINMUX_TYPE_INPUT_PULLDOWN, + + PINMUX_FLAG_TYPE, /* must be last */ +}; #define PINMUX_FLAG_DBIT_SHIFT 5 #define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) @@ -36,7 +39,9 @@ struct pinmux_gpio { pinmux_flag_t flags; }; -#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark } +#define PINMUX_GPIO(gpio, data_or_mark) \ + [gpio] = { .enum_id = data_or_mark, .flags = PINMUX_TYPE_NONE } + #define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 struct pinmux_cfg_reg { -- GitLab From 50ae34a254ca5192e46503884ed0edd60795fe87 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 20 Jun 2012 17:23:24 +0300 Subject: [PATCH 2182/6849] mac80211: use the correct capability info in ieee80211_set_associated() If an AP is beaconing with different capabilities than the one we get in the associate response, we were still using the capabilities received in the beacons. One example is when the AP is beaconing with the short slot bit set to zero and then we try to connect to it with long slot. In this case, we would keep using long slot until the next beacon was received. Fix this by using the correct capability value when calling ieee80211_handle_bss_capability(). We were using cbss->capability, but we should use the bss_conf->assoc_capability instead. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fa927c6aa14b..94d0183ce224 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1275,7 +1275,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_BEACON_INT; bss_info_changed |= ieee80211_handle_bss_capability(sdata, - cbss->capability, bss->has_erp_value, bss->erp_value); + bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); -- GitLab From 00e96decfd0b927f975c98340a5982c5039eeaae Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Wed, 20 Jun 2012 15:39:13 +0300 Subject: [PATCH 2183/6849] mac80211: save wmm_acm per sdata Save and configure the wmm_acm per sdata, rather than per hardware. If wmm_acm is saved per hardware when running two interfaces simultaneously on the same hardware one interface's wmm policy will be affected by the other interface. Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 4 +++- net/mac80211/iface.c | 2 +- net/mac80211/mlme.c | 10 +++++----- net/mac80211/rx.c | 2 +- net/mac80211/wme.c | 11 ++++++----- net/mac80211/wme.h | 2 +- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 34af2e5263c2..0024c32d7bc4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -680,6 +680,9 @@ struct ieee80211_sub_if_data { /* TID bitmap for NoAck policy */ u16 noack_map; + /* bit field of ACM bits (BIT(802.1D tag)) */ + u8 wmm_acm; + struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; struct ieee80211_key __rcu *default_unicast_key; struct ieee80211_key __rcu *default_multicast_key; @@ -1025,7 +1028,6 @@ struct ieee80211_local { int total_ps_buffered; /* total number of all buffered unicast and * multicast packets for power saving stations */ - unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ bool pspolling; bool offchannel_ps_enabled; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 87aeb4f21ffd..728d3eac1f59 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -808,7 +808,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev, hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); - return ieee80211_select_queue_80211(local, skb, hdr); + return ieee80211_select_queue_80211(sdata, skb, hdr); } static const struct net_device_ops ieee80211_monitorif_ops = { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 94d0183ce224..2b450f541993 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1141,7 +1141,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, memset(¶ms, 0, sizeof(params)); - local->wmm_acm = 0; + sdata->wmm_acm = 0; for (; left >= 4; left -= 4, pos += 4) { int aci = (pos[0] >> 5) & 0x03; int acm = (pos[0] >> 4) & 0x01; @@ -1152,21 +1152,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, case 1: /* AC_BK */ queue = 3; if (acm) - local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ + sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) uapsd = true; break; case 2: /* AC_VI */ queue = 1; if (acm) - local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ + sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) uapsd = true; break; case 3: /* AC_VO */ queue = 0; if (acm) - local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ + sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) uapsd = true; break; @@ -1174,7 +1174,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, default: queue = 2; if (acm) - local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ + sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) uapsd = true; break; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 072e8f3afa2b..446a327b3de0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1935,7 +1935,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ether_addr_equal(sdata->vif.addr, hdr->addr3)) return RX_CONTINUE; - q = ieee80211_select_queue_80211(local, skb, hdr); + q = ieee80211_select_queue_80211(sdata, skb, hdr); if (ieee80211_queue_stopped(&local->hw, q)) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); return RX_DROP_MONITOR; diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index c3d643a6536c..cea06e9f26f4 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -52,11 +52,11 @@ static int wme_downgrade_ac(struct sk_buff *skb) } } -static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, +static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { /* in case we are a client verify acm is not set for this ac */ - while (unlikely(local->wmm_acm & BIT(skb->priority))) { + while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { if (wme_downgrade_ac(skb)) { /* * This should not really happen. The AP has marked all @@ -73,10 +73,11 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, } /* Indicate which queue to use for this fully formed 802.11 frame */ -u16 ieee80211_select_queue_80211(struct ieee80211_local *local, +u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, struct ieee80211_hdr *hdr) { + struct ieee80211_local *local = sdata->local; u8 *p; if (local->hw.queues < IEEE80211_NUM_ACS) @@ -94,7 +95,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_local *local, p = ieee80211_get_qos_ctl(hdr); skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; - return ieee80211_downgrade_queue(local, skb); + return ieee80211_downgrade_queue(sdata, skb); } /* Indicate which queue to use. */ @@ -156,7 +157,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, * data frame has */ skb->priority = cfg80211_classify8021d(skb); - return ieee80211_downgrade_queue(local, skb); + return ieee80211_downgrade_queue(sdata, skb); } void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index ca80818b7b66..7fea4bb8acbc 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h @@ -15,7 +15,7 @@ extern const int ieee802_1d_to_ac[8]; -u16 ieee80211_select_queue_80211(struct ieee80211_local *local, +u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, struct ieee80211_hdr *hdr); u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -- GitLab From 9ea4fa158f3a038d5be82ccc7e142f198233f059 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 20 Jun 2012 13:10:14 +0300 Subject: [PATCH 2184/6849] mac80211: fix cleanup if driver suspend callback fails In case the driver suspend callback fails, mac80211 is left with stopped queues which prevents any further traffic as well as all STAs are left marked with WLAN_STA_BLOCK_BA which will cause any further ADDBA requests to be declined. Fix it by undoing both before returning from __iee80211_suspend. Reported-by: Vitaly Wool Signed-off-by: Eyal Shapira Signed-off-by: Johannes Berg --- net/mac80211/pm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 98c128be3827..5c572e7a1a71 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -78,6 +78,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (err < 0) { local->quiescing = false; local->wowlan = false; + if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { + mutex_lock(&local->sta_mtx); + list_for_each_entry(sta, + &local->sta_list, list) { + clear_sta_flag(sta, WLAN_STA_BLOCK_BA); + } + mutex_unlock(&local->sta_mtx); + } + ieee80211_wake_queues_by_reason(hw, + IEEE80211_QUEUE_STOP_REASON_SUSPEND); return err; } else if (err > 0) { WARN_ON(err != 1); -- GitLab From 8356aad43005ecb771a67efb4182dc038b4187e3 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Fri, 15 Jun 2012 21:15:49 +0800 Subject: [PATCH 2185/6849] PCI: cleanup assign_requested_resources_sorted() kernel-doc warning Warning(drivers/pci/setup-bus.c:277): No description found for parameter 'fail_head' Warning(drivers/pci/setup-bus.c:277): Excess function parameter 'failed_list' description in 'assign_requested_resources_sorted' Signed-off-by: Wanpeng Li Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8fa2d4be88de..9165d25cc792 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -265,7 +265,7 @@ out: * assign_requested_resources_sorted() - satisfy resource requests * * @head : head of the list tracking requests for resources - * @failed_list : head of the list tracking requests that could + * @fail_head : head of the list tracking requests that could * not be allocated * * Satisfy resource requests of each element in the list. Add -- GitLab From d6d88c832eaea6c6947ddf7b664601930a9f8a14 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 19 Jun 2012 06:54:49 -0600 Subject: [PATCH 2186/6849] PCI: use __weak consistently Use "__weak" instead of the gcc-specific "__attribute__ ((weak))" Signed-off-by: Bjorn Helgaas --- drivers/pci/pci-sysfs.c | 2 +- drivers/pci/pci.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 86c63fe45d11..a0b435f20bd6 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1112,7 +1112,7 @@ static struct bin_attribute pcie_config_attr = { .write = pci_write_config, }; -int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev) +int __weak pcibios_add_platform_entries(struct pci_dev *dev) { return 0; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..8f4a5ea543fc 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1349,7 +1349,7 @@ void pcim_pin_device(struct pci_dev *pdev) * is the default implementation. Architecture implementations can * override this. */ -void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {} +void __weak pcibios_disable_device (struct pci_dev *dev) {} static void do_pci_disable_device(struct pci_dev *dev) { @@ -1413,8 +1413,8 @@ pci_disable_device(struct pci_dev *dev) * Sets the PCIe reset state for the device. This is the default * implementation. Architecture implementations can override this. */ -int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, - enum pcie_reset_state state) +int __weak pcibios_set_pcie_reset_state(struct pci_dev *dev, + enum pcie_reset_state state) { return -EINVAL; } @@ -3851,7 +3851,7 @@ static void __devinit pci_no_domains(void) * greater than 0xff). This is the default implementation. Architecture * implementations can override this. */ -int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) +int __weak pci_ext_cfg_avail(struct pci_dev *dev) { return 1; } -- GitLab From 6abe0563224f8540c88e1d84d2bb394bd408c951 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 20 Jun 2012 11:51:14 -0400 Subject: [PATCH 2187/6849] mac80211: Track auth frame registrations on IBSS ifaces Track userspace registrations for authentication frames received on an IBSS interface. This field will be used to decide whether or not to send "open system" authentication frames when a new station joins an adhoc network. Signed-off-by: Will Hawkins [redesign the code flow a bit] Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 28 +++++++++++++++++++++------- net/mac80211/ieee80211_i.h | 1 + 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 17162fcc24bc..a6abcd473434 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2516,16 +2516,30 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, u16 frame_type, bool reg) { struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) - return; + switch (frame_type) { + case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: + if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - if (reg) - local->probe_req_reg++; - else - local->probe_req_reg--; + if (reg) + ifibss->auth_frame_registrations++; + else + ifibss->auth_frame_registrations--; + } + break; + case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: + if (reg) + local->probe_req_reg++; + else + local->probe_req_reg--; - ieee80211_queue_work(&local->hw, &local->reconfig_filter); + ieee80211_queue_work(&local->hw, &local->reconfig_filter); + break; + default: + break; + } } static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 0024c32d7bc4..36ce2bb066bf 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -511,6 +511,7 @@ struct ieee80211_if_ibss { bool privacy; bool control_port; + unsigned int auth_frame_registrations; u8 bssid[ETH_ALEN] __aligned(2); u8 ssid[IEEE80211_MAX_SSID_LEN]; -- GitLab From 452a6d22615bb8262a932b362f41fc5d89f03293 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 19 Jun 2012 17:59:13 -0400 Subject: [PATCH 2188/6849] mac80211: send auth in IBSS only if userspace isn't handling it Check the auth frame registration count before sending "open system" authentication messages when a new station registers on a particular IBSS network. This stops us from sending out multiple authentication messages with different authentication algorithms. Signed-off-by: Will Hawkins [reword commit message a bit] Signed-off-by: Johannes Berg --- net/mac80211/ibss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 725cb4be229d..ff46ff424941 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -279,7 +279,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, /* If it fails, maybe we raced another insertion? */ if (sta_info_insert_rcu(sta)) return sta_info_get(sdata, addr); - if (auth) { + if (auth && !sdata->u.ibss.auth_frame_registrations) { ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", sdata->vif.addr, sdata->u.ibss.bssid, addr); ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, -- GitLab From 3bfda62c50b0a4b118dcfce36686508ca2892292 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 19 Jun 2012 17:59:14 -0400 Subject: [PATCH 2189/6849] mac80211: Allow userspace to register for auth frames in IBSS Set the necessary flags to allow user space applications to register for authentication frames on IBSS interfaces. This is useful for situations where userspace applications want to control key negotiation between stations. Signed-off-by: Will Hawkins [reword commit message a bit] Signed-off-by: Johannes Berg --- net/mac80211/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 976e41365c25..0b040fb73673 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -462,7 +462,9 @@ static const struct ieee80211_txrx_stypes ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_ADHOC] = { .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4), + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4), }, [NL80211_IFTYPE_STATION] = { .tx = 0xffff, -- GitLab From cae6247db0b93673d170bc0e02aff85f53bc422c Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:26:46 +0300 Subject: [PATCH 2190/6849] wl1251: fix TSF calculation Cast MSB part of current TSF to u64 to prevent loss of most significant bits. MSB should also be shifted by 32. Patch based on old maemo patch by: Yuri Kululin Yuri Ershov Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/acx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c index ad87a1ac6462..db6430c1a084 100644 --- a/drivers/net/wireless/ti/wl1251/acx.c +++ b/drivers/net/wireless/ti/wl1251/acx.c @@ -869,7 +869,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) } *mactime = tsf_info->current_tsf_lsb | - (tsf_info->current_tsf_msb << 31); + ((u64)tsf_info->current_tsf_msb << 32); out: kfree(tsf_info); -- GitLab From 0d776fcdafed91403b1f453473771664ef7a66bd Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:26:47 +0300 Subject: [PATCH 2191/6849] wl1251: always report beacon loss to the stack Always report beacon loss to the stack, not only when in powersave state. This is because there's possibility that the driver disables PSM before it handles old BSS_LOSE_EVENT, so beacon loss has to be reported. Patch based on old maemo patch by: Janne Ylalehto Juuso Oikarinen Luciano Coelho Yuri Ershov Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/event.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index 9f15ccaf8f05..5ec50a476a69 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c @@ -76,8 +76,7 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) } } - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && - wl->station_mode != STATION_ACTIVE_MODE) { + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); /* indicate to the stack, that beacons have been lost */ -- GitLab From a859e4d6590b2429f518aa712b9e3edd367398d7 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:26:48 +0300 Subject: [PATCH 2192/6849] wl1251: Fix memory leaks in SPI initialization This patch fixes two memory leaks in the SPI initialization code. Patch based on old maemo patch by: Yuri Ershov Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/spi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 87f6305bda2c..567660cd2fcd 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -73,6 +73,8 @@ static void wl1251_spi_reset(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); + + kfree(cmd); } static void wl1251_spi_wake(struct wl1251 *wl) @@ -127,6 +129,8 @@ static void wl1251_spi_wake(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); + + kfree(cmd); } static void wl1251_spi_reset_wake(struct wl1251 *wl) -- GitLab From f18e3c6b67f448ec47b3a5b242789bd3d5644879 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 18 Jun 2012 13:13:30 +0530 Subject: [PATCH 2193/6849] ath9k_hw: avoid possible infinite loop in ar9003_get_pll_sqsum_dvc "ath9k: Fix softlockup in AR9485" with commit id 64bc1239c790e051ff677e023435d770d2ffa174 fixed the reported issue, yet its better to avoid the possible infinite loop in ar9003_get_pll_sqsum_dvc by having a timeout as suggested by ath9k maintainers. http://www.spinics.net/lists/linux-wireless/msg92126.html. Based on my testing PLL's locking measurement is done in ~200us (2 iterations). Cc: stable@vger.kernel.org Cc: Rolf Offermanns Cc: Sujith Manoharan Cc: Senthil Balasubramanian Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7db1890448f2..1c68e564f503 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -784,13 +784,25 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { + struct ath_common *common = ath9k_hw_common(ah); + int i = 0; + REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); udelay(100); REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) { + udelay(100); + if (WARN_ON_ONCE(i >= 100)) { + ath_err(common, "PLL4 meaurement not done\n"); + break; + } + + i++; + } + return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); -- GitLab From 882b7b7d11d65e8eccce738f1ce97cdfdb998f9f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jun 2012 08:46:25 +0200 Subject: [PATCH 2194/6849] iwlwifi: remove log_event debugfs file debugging is disabled When debugging is disabled, the event log functions aren't functional in the way that the debugfs file expects. This leads to the debugfs access crashing. Since the event log functions aren't functional then, remove the debugfs file when CONFIG_IWLWIFI_DEBUG is not set. Cc: stable@kernel.org Reported-by: Lekensteyn Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e7c157e5ebeb..7f97dec8534d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2239,6 +2239,7 @@ static ssize_t iwl_dbgfs_echo_test_write(struct file *file, return count; } +#ifdef CONFIG_IWLWIFI_DEBUG static ssize_t iwl_dbgfs_log_event_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2276,6 +2277,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, return count; } +#endif static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, char __user *user_buf, @@ -2345,7 +2347,9 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); +#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); +#endif DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); /* @@ -2405,7 +2409,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); +#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); +#endif if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); -- GitLab From 931cb03afed7b541392295f3afc4638da32f08a0 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 20 Jun 2012 16:29:20 +0530 Subject: [PATCH 2195/6849] ath9k_htc: configure bssid on ASSOC/IBSS change After the change "mac80211: remove spurious BSSID change flag", BSS_CHANGED_BSSID will not be passed on association or IBSS status changes. So it could be better to program bssid on ASSOC or IBSS change notification. Not doing so, is affecting the packet transmission. Cc: stable@vger.kernel.org [3.4+] Reported-by: Michael Leun Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2b8f61c210e1..abbd6effd60d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1496,6 +1496,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + ath9k_htc_choose_set_bssid(priv); if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) ath9k_htc_start_ani(priv); else if (priv->num_sta_assoc_vif == 0) @@ -1503,13 +1504,11 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_BSSID) { + if (changed & BSS_CHANGED_IBSS) { if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { common->curaid = bss_conf->aid; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); ath9k_htc_set_bssid(priv); - } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { - ath9k_htc_choose_set_bssid(priv); } } -- GitLab From 0f6b3f597daab2254614e2773e322e73fb1b6f4b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jun 2012 20:11:33 +0200 Subject: [PATCH 2196/6849] mac80211: fix double-start of remain-on-channel When a remain-on-channel item is deleted, we remove it from the list and then start the next item. However, if it wasn't actually the first item then calling ieee80211_start_next_roc() is wrong as it will start the first item -- even if that was already started. Fix the two places that do this and add a warning to prevent the problem from reoccurring. Reported-by: Eliad Peller Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 ++- net/mac80211/offchannel.c | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a6abcd473434..03aff23c70fd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2362,7 +2362,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, list_del(&found->list); - ieee80211_start_next_roc(local); + if (found->started) + ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); ieee80211_roc_notify_destroy(found); diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index febce7fb7bb1..7f93626ddc61 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -262,6 +262,9 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, list); + if (WARN_ON_ONCE(roc->started)) + return; + if (local->ops->remain_on_channel) { int ret, duration = roc->duration; @@ -377,7 +380,8 @@ void ieee80211_sw_roc_work(struct work_struct *work) ieee80211_recalc_idle(local); - ieee80211_start_next_roc(local); + if (roc->started) + ieee80211_start_next_roc(local); } out_unlock: -- GitLab From 702b0e4f2f2782962aab7d9a0a40ad68770bb1f6 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 11 Jun 2012 16:25:07 -0600 Subject: [PATCH 2197/6849] ARM: dt: tegra: rename board files to match SoC Most ARM ${board}.dts files are already named ${soc}-${board}.dts. This change modifies the Tegra board files to be named the same way for consistency. Once a related change is made in U-Boot, this will cause both U-Boot and the kernel to use the same names for the .dts files and SoC identifiers, thus allowing U-Boot's recently added "soc" and "board" environment variables to be used to construct the name of Tegra .dtb files, and hence allow board-generic U-Boot bootcmd scripts to be written. Signed-off-by: Stephen Warren --- .../dts/{tegra-harmony.dts => tegra20-harmony.dts} | 0 .../boot/dts/{tegra-paz00.dts => tegra20-paz00.dts} | 0 .../dts/{tegra-seaboard.dts => tegra20-seaboard.dts} | 0 .../{tegra-trimslice.dts => tegra20-trimslice.dts} | 0 .../dts/{tegra-ventana.dts => tegra20-ventana.dts} | 0 .../dts/{tegra-cardhu.dts => tegra30-cardhu.dts} | 0 arch/arm/mach-tegra/Makefile.boot | 12 ++++++------ 7 files changed, 6 insertions(+), 6 deletions(-) rename arch/arm/boot/dts/{tegra-harmony.dts => tegra20-harmony.dts} (100%) rename arch/arm/boot/dts/{tegra-paz00.dts => tegra20-paz00.dts} (100%) rename arch/arm/boot/dts/{tegra-seaboard.dts => tegra20-seaboard.dts} (100%) rename arch/arm/boot/dts/{tegra-trimslice.dts => tegra20-trimslice.dts} (100%) rename arch/arm/boot/dts/{tegra-ventana.dts => tegra20-ventana.dts} (100%) rename arch/arm/boot/dts/{tegra-cardhu.dts => tegra30-cardhu.dts} (100%) diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts similarity index 100% rename from arch/arm/boot/dts/tegra-harmony.dts rename to arch/arm/boot/dts/tegra20-harmony.dts diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts similarity index 100% rename from arch/arm/boot/dts/tegra-paz00.dts rename to arch/arm/boot/dts/tegra20-paz00.dts diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts similarity index 100% rename from arch/arm/boot/dts/tegra-seaboard.dts rename to arch/arm/boot/dts/tegra20-seaboard.dts diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts similarity index 100% rename from arch/arm/boot/dts/tegra-trimslice.dts rename to arch/arm/boot/dts/tegra20-trimslice.dts diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts similarity index 100% rename from arch/arm/boot/dts/tegra-ventana.dts rename to arch/arm/boot/dts/tegra20-ventana.dts diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra30-cardhu.dts similarity index 100% rename from arch/arm/boot/dts/tegra-cardhu.dts rename to arch/arm/boot/dts/tegra30-cardhu.dts diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index 9a82094092d7..8040345bd971 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot @@ -2,9 +2,9 @@ zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) += 0x00008000 params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 -dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb -dtb-$(CONFIG_MACH_PAZ00) += tegra-paz00.dtb -dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb -dtb-$(CONFIG_MACH_TRIMSLICE) += tegra-trimslice.dtb -dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb -dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra-cardhu.dtb +dtb-$(CONFIG_MACH_HARMONY) += tegra20-harmony.dtb +dtb-$(CONFIG_MACH_PAZ00) += tegra20-paz00.dtb +dtb-$(CONFIG_MACH_SEABOARD) += tegra20-seaboard.dtb +dtb-$(CONFIG_MACH_TRIMSLICE) += tegra20-trimslice.dtb +dtb-$(CONFIG_MACH_VENTANA) += tegra20-ventana.dtb +dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30-cardhu.dtb -- GitLab From 223ef78d04e1eea5490ee7c3dafdf6e259634fd1 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Mon, 11 Jun 2012 21:09:45 +0200 Subject: [PATCH 2198/6849] ARM: tegra: Fix dts files w/ status property: "disable" -> "disabled" This patches fixes some status = "disable" strings to "disabled", the correct way of disabling nodes in the devicetree. Just the tegra part here. Everything else goes via other patches and trees. Signed-off-by: Roland Stigge Acked-by: Rob Herring Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra20.dtsi | 36 ++++++++++++++++---------------- arch/arm/boot/dts/tegra30.dtsi | 38 +++++++++++++++++----------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 59116b852434..9f1921634eb7 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -72,7 +72,7 @@ reg = <0x70002800 0x200>; interrupts = <0 13 0x04>; nvidia,dma-request-selector = <&apbdma 2>; - status = "disable"; + status = "disabled"; }; tegra_i2s2: i2s@70002a00 { @@ -80,7 +80,7 @@ reg = <0x70002a00 0x200>; interrupts = <0 3 0x04>; nvidia,dma-request-selector = <&apbdma 1>; - status = "disable"; + status = "disabled"; }; serial@70006000 { @@ -88,7 +88,7 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <0 36 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006040 { @@ -96,7 +96,7 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = <0 37 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006200 { @@ -104,7 +104,7 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = <0 46 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006300 { @@ -112,7 +112,7 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = <0 90 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006400 { @@ -120,7 +120,7 @@ reg = <0x70006400 0x100>; reg-shift = <2>; interrupts = <0 91 0x04>; - status = "disable"; + status = "disabled"; }; i2c@7000c000 { @@ -129,7 +129,7 @@ interrupts = <0 38 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000c400 { @@ -138,7 +138,7 @@ interrupts = <0 84 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000c500 { @@ -147,7 +147,7 @@ interrupts = <0 92 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000d000 { @@ -156,7 +156,7 @@ interrupts = <0 53 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; pmc { @@ -190,7 +190,7 @@ interrupts = <0 20 0x04>; phy_type = "utmi"; nvidia,has-legacy-mode; - status = "disable"; + status = "disabled"; }; usb@c5004000 { @@ -198,7 +198,7 @@ reg = <0xc5004000 0x4000>; interrupts = <0 21 0x04>; phy_type = "ulpi"; - status = "disable"; + status = "disabled"; }; usb@c5008000 { @@ -206,35 +206,35 @@ reg = <0xc5008000 0x4000>; interrupts = <0 97 0x04>; phy_type = "utmi"; - status = "disable"; + status = "disabled"; }; sdhci@c8000000 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000000 0x200>; interrupts = <0 14 0x04>; - status = "disable"; + status = "disabled"; }; sdhci@c8000200 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000200 0x200>; interrupts = <0 15 0x04>; - status = "disable"; + status = "disabled"; }; sdhci@c8000400 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000400 0x200>; interrupts = <0 19 0x04>; - status = "disable"; + status = "disabled"; }; sdhci@c8000600 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000600 0x200>; interrupts = <0 31 0x04>; - status = "disable"; + status = "disabled"; }; pmu { diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 19479393842e..da740191771f 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -82,7 +82,7 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <0 36 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006040 { @@ -90,7 +90,7 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = <0 37 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006200 { @@ -98,7 +98,7 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = <0 46 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006300 { @@ -106,7 +106,7 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = <0 90 0x04>; - status = "disable"; + status = "disabled"; }; serial@70006400 { @@ -114,7 +114,7 @@ reg = <0x70006400 0x100>; reg-shift = <2>; interrupts = <0 91 0x04>; - status = "disable"; + status = "disabled"; }; i2c@7000c000 { @@ -123,7 +123,7 @@ interrupts = <0 38 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000c400 { @@ -132,7 +132,7 @@ interrupts = <0 84 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000c500 { @@ -141,7 +141,7 @@ interrupts = <0 92 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000c700 { @@ -150,7 +150,7 @@ interrupts = <0 120 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; i2c@7000d000 { @@ -159,7 +159,7 @@ interrupts = <0 53 0x04>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; pmc { @@ -201,35 +201,35 @@ compatible = "nvidia,tegra30-i2s"; reg = <0x70080300 0x100>; nvidia,ahub-cif-ids = <4 4>; - status = "disable"; + status = "disabled"; }; tegra_i2s1: i2s@70080400 { compatible = "nvidia,tegra30-i2s"; reg = <0x70080400 0x100>; nvidia,ahub-cif-ids = <5 5>; - status = "disable"; + status = "disabled"; }; tegra_i2s2: i2s@70080500 { compatible = "nvidia,tegra30-i2s"; reg = <0x70080500 0x100>; nvidia,ahub-cif-ids = <6 6>; - status = "disable"; + status = "disabled"; }; tegra_i2s3: i2s@70080600 { compatible = "nvidia,tegra30-i2s"; reg = <0x70080600 0x100>; nvidia,ahub-cif-ids = <7 7>; - status = "disable"; + status = "disabled"; }; tegra_i2s4: i2s@70080700 { compatible = "nvidia,tegra30-i2s"; reg = <0x70080700 0x100>; nvidia,ahub-cif-ids = <8 8>; - status = "disable"; + status = "disabled"; }; }; @@ -237,28 +237,28 @@ compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000000 0x200>; interrupts = <0 14 0x04>; - status = "disable"; + status = "disabled"; }; sdhci@78000200 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000200 0x200>; interrupts = <0 15 0x04>; - status = "disable"; + status = "disabled"; }; sdhci@78000400 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000400 0x200>; interrupts = <0 19 0x04>; - status = "disable"; + status = "disabled"; }; sdhci@78000600 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000600 0x200>; interrupts = <0 31 0x04>; - status = "disable"; + status = "disabled"; }; pmu { -- GitLab From 95ef9958849381931a79ecec53e677e52c406c5a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 13 Jun 2012 15:55:47 +0200 Subject: [PATCH 2199/6849] ARM: tegra: build powergate unconditionally powergate functions are needed for tegra30 as well (see common.c), so build it always. Fixes: arch/arm/mach-tegra/built-in.o: In function `tegra30_init_early': apbio.c:(.init.text+0x78): undefined reference to `tegra_powergate_init' (using "allnoconfig" with tegra30 enabled) Signed-off-by: Wolfram Sang Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 2eb4445ddb14..35253fdd1ba7 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -8,9 +8,9 @@ obj-y += timer.o obj-y += fuse.o obj-y += pmc.o obj-y += flowctrl.o +obj-y += powergate.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_CPU_IDLE) += sleep.o -obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o -- GitLab From 9132b0ed57320996b16eafbf651a04e02ad29092 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 14:44:26 -0600 Subject: [PATCH 2200/6849] ARM: tegra: make .dts compilation depend on Tegra2 support Update Makefile.boot to compile *.dts when the appropriate Tegra SoC support is enabled, rather than requiring Kconfig to list each board individually. Remove CONFIG_MACH_VENTANA now that it has no use. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/Kconfig | 7 ------- arch/arm/mach-tegra/Makefile.boot | 10 +++++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 7c407393cd07..5b9b1166003f 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -108,13 +108,6 @@ config MACH_WARIO help Support for the Wario version of Seaboard -config MACH_VENTANA - bool "Ventana board" - depends on ARCH_TEGRA_2x_SOC - select MACH_TEGRA_DT - help - Support for the nVidia Ventana development platform - choice prompt "Default low-level debug console UART" default TEGRA_DEBUG_UART_NONE diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index 8040345bd971..a369f96bd05e 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot @@ -2,9 +2,9 @@ zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) += 0x00008000 params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 -dtb-$(CONFIG_MACH_HARMONY) += tegra20-harmony.dtb -dtb-$(CONFIG_MACH_PAZ00) += tegra20-paz00.dtb -dtb-$(CONFIG_MACH_SEABOARD) += tegra20-seaboard.dtb -dtb-$(CONFIG_MACH_TRIMSLICE) += tegra20-trimslice.dtb -dtb-$(CONFIG_MACH_VENTANA) += tegra20-ventana.dtb +dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-harmony.dtb +dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-paz00.dtb +dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-seaboard.dtb +dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-trimslice.dtb +dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20-ventana.dtb dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30-cardhu.dtb -- GitLab From 2c95b7e06f63b264500fbcd5b4718c1a7258aa76 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 15:07:19 -0600 Subject: [PATCH 2201/6849] ARM: tegra: remove CONFIG_MACH_TEGRA_DT * Make ARCH_TEGRA select USE_OF; DT is the way forward. * Build board-dt-tegra*.c when the relevant Tegra SoC support is enabled, rather than requiring a specific config option for this. * The board-specific config options already build board-*-pinmux.o, and when booting from device tree these files are no longer needed, so we can remove some Makefile commands related to those files. Signed-off-by: Stephen Warren --- arch/arm/Kconfig | 1 + arch/arm/mach-tegra/Kconfig | 7 ------- arch/arm/mach-tegra/Makefile | 10 +++------- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 84449dd8f031..3b24b41458ae 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -645,6 +645,7 @@ config ARCH_TEGRA select MIGHT_HAVE_CACHE_L2X0 select NEED_MACH_IO_H if PCI select ARCH_HAS_CPUFREQ + select USE_OF help This enables support for NVIDIA Tegra based systems (Tegra APX, Tegra 6xx and Tegra 2 series). diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 5b9b1166003f..621466a717d1 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -87,13 +87,6 @@ config MACH_SEABOARD also be included for some of the derivative boards that have large similarities with the seaboard design. -config MACH_TEGRA_DT - bool "Generic Tegra20 board (FDT support)" - depends on ARCH_TEGRA_2x_SOC - select USE_OF - help - Support for generic NVIDIA Tegra20 boards using Flattened Device Tree - config MACH_TRIMSLICE bool "TrimSlice board" depends on ARCH_TEGRA_2x_SOC diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 2eb4445ddb14..60a02132d2da 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_CPU_IDLE) += sleep.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o -obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_SMP) += reset.o @@ -23,6 +22,9 @@ obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o obj-$(CONFIG_TEGRA_PCI) += pcie.o obj-$(CONFIG_USB_SUPPORT) += usb_phy.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o +obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o + obj-$(CONFIG_MACH_HARMONY) += board-harmony.o obj-$(CONFIG_MACH_HARMONY) += board-harmony-pinmux.o obj-$(CONFIG_MACH_HARMONY) += board-harmony-pcie.o @@ -34,11 +36,5 @@ obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o obj-$(CONFIG_MACH_SEABOARD) += board-seaboard.o obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o -obj-$(CONFIG_MACH_TEGRA_DT) += board-dt-tegra20.o -obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o -obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o -obj-$(CONFIG_MACH_TEGRA_DT) += board-paz00-pinmux.o -obj-$(CONFIG_MACH_TEGRA_DT) += board-trimslice-pinmux.o - obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o -- GitLab From 98a1405e20ecf261abbc091eabb229d8adfbf62c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 21 May 2012 14:40:14 -0600 Subject: [PATCH 2202/6849] ARM: tegra: remove Seaboard board files The Seaboard device tree supports all the features that the Seaboard board files support. Hence, there's no need to keep the board files around any more; all users should convert to device tree. MACH_KAEN and MACH_WARIO are also removed. While tegra-seaboard.dts doesn't support those explicitly, it would be trivial to create device trees for those boards if anyone cares. The Seaboard device tree is now compiled if Tegra2 support is enabled, rather than when Seaboard support is enabled. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/Kconfig | 22 -- arch/arm/mach-tegra/Makefile | 3 - arch/arm/mach-tegra/board-seaboard-pinmux.c | 197 ------------- arch/arm/mach-tegra/board-seaboard.c | 306 -------------------- arch/arm/mach-tegra/board-seaboard.h | 47 --- 5 files changed, 575 deletions(-) delete mode 100644 arch/arm/mach-tegra/board-seaboard-pinmux.c delete mode 100644 arch/arm/mach-tegra/board-seaboard.c delete mode 100644 arch/arm/mach-tegra/board-seaboard.h diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 621466a717d1..9077aaa398d9 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -66,27 +66,12 @@ config MACH_HARMONY help Support for nVidia Harmony development platform -config MACH_KAEN - bool "Kaen board" - depends on ARCH_TEGRA_2x_SOC - select MACH_SEABOARD - help - Support for the Kaen version of Seaboard - config MACH_PAZ00 bool "Paz00 board" depends on ARCH_TEGRA_2x_SOC help Support for the Toshiba AC100/Dynabook AZ netbook -config MACH_SEABOARD - bool "Seaboard board" - depends on ARCH_TEGRA_2x_SOC - help - Support for nVidia Seaboard development platform. It will - also be included for some of the derivative boards that - have large similarities with the seaboard design. - config MACH_TRIMSLICE bool "TrimSlice board" depends on ARCH_TEGRA_2x_SOC @@ -94,13 +79,6 @@ config MACH_TRIMSLICE help Support for CompuLab TrimSlice platform -config MACH_WARIO - bool "Wario board" - depends on ARCH_TEGRA_2x_SOC - select MACH_SEABOARD - help - Support for the Wario version of Seaboard - choice prompt "Default low-level debug console UART" default TEGRA_DEBUG_UART_NONE diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 60a02132d2da..1f6f237586e4 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -33,8 +33,5 @@ obj-$(CONFIG_MACH_HARMONY) += board-harmony-power.o obj-$(CONFIG_MACH_PAZ00) += board-paz00.o obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o -obj-$(CONFIG_MACH_SEABOARD) += board-seaboard.o -obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o - obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c deleted file mode 100644 index 11fc8a568c64..000000000000 --- a/arch/arm/mach-tegra/board-seaboard-pinmux.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2010-2012 NVIDIA Corporation - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include - -#include "board-seaboard.h" -#include "board-pinmux.h" - -static unsigned long seaboard_pincfg_drive_sdio1[] = { - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE, 0), - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_SCHMITT, 0), - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_LOW_POWER_MODE, 3), - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH, 31), - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH, 31), - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING, 3), - TEGRA_PINCONF_PACK(TEGRA_PINCONF_PARAM_SLEW_RATE_RISING, 3), -}; - -static struct pinctrl_map common_map[] = { - TEGRA_MAP_MUXCONF("ata", "ide", none, driven), - TEGRA_MAP_MUXCONF("atb", "sdio4", none, driven), - TEGRA_MAP_MUXCONF("atc", "nand", none, driven), - TEGRA_MAP_MUXCONF("atd", "gmi", none, driven), - TEGRA_MAP_MUXCONF("ate", "gmi", none, tristate), - TEGRA_MAP_MUXCONF("cdev1", "plla_out", none, driven), - TEGRA_MAP_MUXCONF("cdev2", "pllp_out4", none, driven), - TEGRA_MAP_MUXCONF("crtp", "crt", up, tristate), - TEGRA_MAP_MUXCONF("csus", "vi_sensor_clk", none, tristate), - TEGRA_MAP_MUXCONF("dap1", "dap1", none, driven), - TEGRA_MAP_MUXCONF("dap2", "dap2", none, driven), - TEGRA_MAP_MUXCONF("dap3", "dap3", none, tristate), - TEGRA_MAP_MUXCONF("dap4", "dap4", none, driven), - TEGRA_MAP_MUXCONF("dta", "vi", down, driven), - TEGRA_MAP_MUXCONF("dtb", "vi", down, driven), - TEGRA_MAP_MUXCONF("dtc", "vi", down, driven), - TEGRA_MAP_MUXCONF("dtd", "vi", down, driven), - TEGRA_MAP_MUXCONF("dte", "vi", down, tristate), - TEGRA_MAP_MUXCONF("dtf", "i2c3", none, driven), - TEGRA_MAP_MUXCONF("gma", "sdio4", none, driven), - TEGRA_MAP_MUXCONF("gmb", "gmi", up, tristate), - TEGRA_MAP_MUXCONF("gmc", "uartd", none, driven), - TEGRA_MAP_MUXCONF("gme", "sdio4", none, driven), - TEGRA_MAP_MUXCONF("gpu", "pwm", none, driven), - TEGRA_MAP_MUXCONF("gpu7", "rtck", none, driven), - TEGRA_MAP_MUXCONF("gpv", "pcie", none, tristate), - TEGRA_MAP_MUXCONF("hdint", "hdmi", na, tristate), - TEGRA_MAP_MUXCONF("i2cp", "i2cp", none, driven), - TEGRA_MAP_MUXCONF("irrx", "uartb", none, driven), - TEGRA_MAP_MUXCONF("irtx", "uartb", none, driven), - TEGRA_MAP_MUXCONF("kbca", "kbc", up, driven), - TEGRA_MAP_MUXCONF("kbcb", "kbc", up, driven), - TEGRA_MAP_MUXCONF("kbcc", "kbc", up, driven), - TEGRA_MAP_MUXCONF("kbcd", "kbc", up, driven), - TEGRA_MAP_MUXCONF("kbce", "kbc", up, driven), - TEGRA_MAP_MUXCONF("kbcf", "kbc", up, driven), - TEGRA_MAP_MUXCONF("lcsn", "rsvd4", na, tristate), - TEGRA_MAP_MUXCONF("ld0", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld1", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld10", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld11", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld12", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld13", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld14", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld15", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld16", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld17", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld2", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld3", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld4", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld5", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld6", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld7", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld8", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ld9", "displaya", na, driven), - TEGRA_MAP_MUXCONF("ldc", "rsvd4", na, tristate), - TEGRA_MAP_MUXCONF("ldi", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lhp0", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lhp1", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lhp2", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lhs", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lm0", "rsvd4", na, driven), - TEGRA_MAP_MUXCONF("lm1", "crt", na, tristate), - TEGRA_MAP_MUXCONF("lpp", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lpw1", "rsvd4", na, tristate), - TEGRA_MAP_MUXCONF("lsc0", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lsdi", "rsvd4", na, tristate), - TEGRA_MAP_MUXCONF("lspi", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lvp0", "rsvd4", na, tristate), - TEGRA_MAP_MUXCONF("lvp1", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lvs", "displaya", na, driven), - TEGRA_MAP_MUXCONF("owc", "rsvd2", none, tristate), - TEGRA_MAP_MUXCONF("pmc", "pwr_on", na, driven), - TEGRA_MAP_MUXCONF("pta", "hdmi", none, driven), - TEGRA_MAP_MUXCONF("rm", "i2c1", none, driven), - TEGRA_MAP_MUXCONF("sdb", "sdio3", na, driven), - TEGRA_MAP_MUXCONF("sdc", "sdio3", none, driven), - TEGRA_MAP_MUXCONF("sdd", "sdio3", none, driven), - TEGRA_MAP_MUXCONF("sdio1", "sdio1", up, driven), - TEGRA_MAP_MUXCONF("slxa", "pcie", up, tristate), - TEGRA_MAP_MUXCONF("slxd", "spdif", none, driven), - TEGRA_MAP_MUXCONF("slxk", "pcie", none, driven), - TEGRA_MAP_MUXCONF("spdi", "rsvd2", none, driven), - TEGRA_MAP_MUXCONF("spdo", "rsvd2", none, driven), - TEGRA_MAP_MUXCONF("spib", "gmi", none, tristate), - TEGRA_MAP_MUXCONF("spid", "spi1", none, tristate), - TEGRA_MAP_MUXCONF("spie", "spi1", none, tristate), - TEGRA_MAP_MUXCONF("spif", "spi1", down, tristate), - TEGRA_MAP_MUXCONF("spih", "spi2_alt", up, tristate), - TEGRA_MAP_MUXCONF("uaa", "ulpi", up, driven), - TEGRA_MAP_MUXCONF("uab", "ulpi", up, driven), - TEGRA_MAP_MUXCONF("uac", "rsvd2", none, driven), - TEGRA_MAP_MUXCONF("uad", "irda", none, driven), - TEGRA_MAP_MUXCONF("uca", "uartc", none, driven), - TEGRA_MAP_MUXCONF("ucb", "uartc", none, driven), - TEGRA_MAP_MUXCONF("uda", "ulpi", none, driven), - TEGRA_MAP_CONF("ck32", none, na), - TEGRA_MAP_CONF("ddrc", none, na), - TEGRA_MAP_CONF("pmca", none, na), - TEGRA_MAP_CONF("pmcb", none, na), - TEGRA_MAP_CONF("pmcc", none, na), - TEGRA_MAP_CONF("pmcd", none, na), - TEGRA_MAP_CONF("pmce", none, na), - TEGRA_MAP_CONF("xm2c", none, na), - TEGRA_MAP_CONF("xm2d", none, na), - TEGRA_MAP_CONF("ls", up, na), - TEGRA_MAP_CONF("lc", up, na), - TEGRA_MAP_CONF("ld17_0", down, na), - TEGRA_MAP_CONF("ld19_18", down, na), - TEGRA_MAP_CONF("ld21_20", down, na), - TEGRA_MAP_CONF("ld23_22", down, na), -}; - -static struct pinctrl_map seaboard_map[] = { - TEGRA_MAP_MUXCONF("ddc", "rsvd2", none, tristate), - TEGRA_MAP_MUXCONF("gmd", "sflash", none, driven), - TEGRA_MAP_MUXCONF("lpw0", "hdmi", na, driven), - TEGRA_MAP_MUXCONF("lpw2", "hdmi", na, driven), - TEGRA_MAP_MUXCONF("lsc1", "hdmi", na, tristate), - TEGRA_MAP_MUXCONF("lsck", "hdmi", na, tristate), - TEGRA_MAP_MUXCONF("lsda", "hdmi", na, tristate), - TEGRA_MAP_MUXCONF("slxc", "spdif", none, tristate), - TEGRA_MAP_MUXCONF("spia", "gmi", up, tristate), - TEGRA_MAP_MUXCONF("spic", "gmi", up, driven), - TEGRA_MAP_MUXCONF("spig", "spi2_alt", up, tristate), - PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(PINMUX_DEV, "drive_sdio1", seaboard_pincfg_drive_sdio1), -}; - -static struct pinctrl_map ventana_map[] = { - TEGRA_MAP_MUXCONF("ddc", "rsvd2", none, driven), - TEGRA_MAP_MUXCONF("gmd", "sflash", none, tristate), - TEGRA_MAP_MUXCONF("lpw0", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lpw2", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lsc1", "displaya", na, driven), - TEGRA_MAP_MUXCONF("lsck", "displaya", na, tristate), - TEGRA_MAP_MUXCONF("lsda", "displaya", na, tristate), - TEGRA_MAP_MUXCONF("slxc", "sdio3", none, driven), - TEGRA_MAP_MUXCONF("spia", "gmi", none, tristate), - TEGRA_MAP_MUXCONF("spic", "gmi", none, tristate), - TEGRA_MAP_MUXCONF("spig", "spi2_alt", none, tristate), -}; - -static struct tegra_board_pinmux_conf common_conf = { - .maps = common_map, - .map_count = ARRAY_SIZE(common_map), -}; - -static struct tegra_board_pinmux_conf seaboard_conf = { - .maps = seaboard_map, - .map_count = ARRAY_SIZE(seaboard_map), -}; - -static struct tegra_board_pinmux_conf ventana_conf = { - .maps = ventana_map, - .map_count = ARRAY_SIZE(ventana_map), -}; - -void seaboard_pinmux_init(void) -{ - tegra_board_pinmux_init(&common_conf, &seaboard_conf); -} - -void ventana_pinmux_init(void) -{ - tegra_board_pinmux_init(&common_conf, &ventana_conf); -} diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c deleted file mode 100644 index 71e9f3fc7fba..000000000000 --- a/arch/arm/mach-tegra/board-seaboard.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2010, 2011 NVIDIA Corporation. - * Copyright (C) 2010, 2011 Google, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "board.h" -#include "board-seaboard.h" -#include "clock.h" -#include "devices.h" -#include "gpio-names.h" - -static struct plat_serial8250_port debug_uart_platform_data[] = { - { - /* Memory and IRQ filled in before registration */ - .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, - .type = PORT_TEGRA, - .handle_break = tegra_serial_handle_break, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = 216000000, - }, { - .flags = 0, - } -}; - -static struct platform_device debug_uart = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = debug_uart_platform_data, - }, -}; - -static __initdata struct tegra_clk_init_table seaboard_clk_init_table[] = { - /* name parent rate enabled */ - { "uartb", "pll_p", 216000000, true}, - { "uartd", "pll_p", 216000000, true}, - { "pll_a", "pll_p_out1", 56448000, true }, - { "pll_a_out0", "pll_a", 11289600, true }, - { "cdev1", NULL, 0, true }, - { "i2s1", "pll_a_out0", 11289600, false}, - { "usbd", "clk_m", 12000000, true}, - { "usb3", "clk_m", 12000000, true}, - { NULL, NULL, 0, 0}, -}; - -static struct gpio_keys_button seaboard_gpio_keys_buttons[] = { - { - .code = SW_LID, - .gpio = TEGRA_GPIO_LIDSWITCH, - .active_low = 0, - .desc = "Lid", - .type = EV_SW, - .wakeup = 1, - .debounce_interval = 1, - }, - { - .code = KEY_POWER, - .gpio = TEGRA_GPIO_POWERKEY, - .active_low = 1, - .desc = "Power", - .type = EV_KEY, - .wakeup = 1, - }, -}; - -static struct gpio_keys_platform_data seaboard_gpio_keys = { - .buttons = seaboard_gpio_keys_buttons, - .nbuttons = ARRAY_SIZE(seaboard_gpio_keys_buttons), -}; - -static struct platform_device seaboard_gpio_keys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &seaboard_gpio_keys, - } -}; - -static struct tegra_sdhci_platform_data sdhci_pdata1 = { - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = -1, -}; - -static struct tegra_sdhci_platform_data sdhci_pdata3 = { - .cd_gpio = TEGRA_GPIO_SD2_CD, - .wp_gpio = TEGRA_GPIO_SD2_WP, - .power_gpio = TEGRA_GPIO_SD2_POWER, -}; - -static struct tegra_sdhci_platform_data sdhci_pdata4 = { - .cd_gpio = -1, - .wp_gpio = -1, - .power_gpio = -1, - .is_8bit = 1, -}; - -static struct tegra_wm8903_platform_data seaboard_audio_pdata = { - .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, - .gpio_hp_det = TEGRA_GPIO_HP_DET, - .gpio_hp_mute = -1, - .gpio_int_mic_en = -1, - .gpio_ext_mic_en = -1, -}; - -static struct platform_device seaboard_audio_device = { - .name = "tegra-snd-wm8903", - .id = 0, - .dev = { - .platform_data = &seaboard_audio_pdata, - }, -}; - -static struct platform_device *seaboard_devices[] __initdata = { - &debug_uart, - &tegra_pmu_device, - &tegra_sdhci_device4, - &tegra_sdhci_device3, - &tegra_sdhci_device1, - &seaboard_gpio_keys_device, - &tegra_i2s_device1, - &tegra_das_device, - &seaboard_audio_device, -}; - -static struct i2c_board_info __initdata isl29018_device = { - I2C_BOARD_INFO("isl29018", 0x44), -}; - -static struct i2c_board_info __initdata adt7461_device = { - I2C_BOARD_INFO("adt7461", 0x4c), -}; - -static struct wm8903_platform_data wm8903_pdata = { - .irq_active_low = 0, - .micdet_cfg = 0, - .micdet_delay = 100, - .gpio_base = SEABOARD_GPIO_WM8903(0), - .gpio_cfg = { - 0, - 0, - WM8903_GPIO_CONFIG_ZERO, - 0, - 0, - }, -}; - -static struct i2c_board_info __initdata wm8903_device = { - I2C_BOARD_INFO("wm8903", 0x1a), - .platform_data = &wm8903_pdata, -}; - -static int seaboard_ehci_init(void) -{ - struct tegra_ehci_platform_data *pdata; - - pdata = tegra_ehci1_device.dev.platform_data; - pdata->vbus_gpio = TEGRA_GPIO_USB1; - - platform_device_register(&tegra_ehci1_device); - platform_device_register(&tegra_ehci3_device); - - return 0; -} - -static void __init seaboard_i2c_init(void) -{ - isl29018_device.irq = gpio_to_irq(TEGRA_GPIO_ISL29018_IRQ); - i2c_register_board_info(0, &isl29018_device, 1); - - wm8903_device.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ); - i2c_register_board_info(0, &wm8903_device, 1); - - i2c_register_board_info(3, &adt7461_device, 1); - - platform_device_register(&tegra_i2c_device1); - platform_device_register(&tegra_i2c_device2); - platform_device_register(&tegra_i2c_device3); - platform_device_register(&tegra_i2c_device4); -} - -static void __init seaboard_common_init(void) -{ - seaboard_pinmux_init(); - - tegra_clk_init_from_table(seaboard_clk_init_table); - - tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; - tegra_sdhci_device3.dev.platform_data = &sdhci_pdata3; - tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; - - platform_add_devices(seaboard_devices, ARRAY_SIZE(seaboard_devices)); - - seaboard_ehci_init(); -} - -static void __init tegra_seaboard_init(void) -{ - /* Seaboard uses UARTD for the debug port. */ - debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTD_BASE); - debug_uart_platform_data[0].mapbase = TEGRA_UARTD_BASE; - debug_uart_platform_data[0].irq = INT_UARTD; - - seaboard_common_init(); - - seaboard_i2c_init(); -} - -static void __init tegra_kaen_init(void) -{ - /* Kaen uses UARTB for the debug port. */ - debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE); - debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE; - debug_uart_platform_data[0].irq = INT_UARTB; - - seaboard_audio_pdata.gpio_hp_mute = TEGRA_GPIO_KAEN_HP_MUTE; - - seaboard_common_init(); - - seaboard_i2c_init(); -} - -static void __init tegra_wario_init(void) -{ - /* Wario uses UARTB for the debug port. */ - debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE); - debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE; - debug_uart_platform_data[0].irq = INT_UARTB; - - seaboard_common_init(); - - seaboard_i2c_init(); -} - - -MACHINE_START(SEABOARD, "seaboard") - .atag_offset = 0x100, - .map_io = tegra_map_common_io, - .init_early = tegra20_init_early, - .init_irq = tegra_init_irq, - .handle_irq = gic_handle_irq, - .timer = &tegra_timer, - .init_machine = tegra_seaboard_init, - .init_late = tegra_init_late, - .restart = tegra_assert_system_reset, -MACHINE_END - -MACHINE_START(KAEN, "kaen") - .atag_offset = 0x100, - .map_io = tegra_map_common_io, - .init_early = tegra20_init_early, - .init_irq = tegra_init_irq, - .handle_irq = gic_handle_irq, - .timer = &tegra_timer, - .init_machine = tegra_kaen_init, - .init_late = tegra_init_late, - .restart = tegra_assert_system_reset, -MACHINE_END - -MACHINE_START(WARIO, "wario") - .atag_offset = 0x100, - .map_io = tegra_map_common_io, - .init_early = tegra20_init_early, - .init_irq = tegra_init_irq, - .handle_irq = gic_handle_irq, - .timer = &tegra_timer, - .init_machine = tegra_wario_init, - .init_late = tegra_init_late, - .restart = tegra_assert_system_reset, -MACHINE_END diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h deleted file mode 100644 index 4c45d4ca3c49..000000000000 --- a/arch/arm/mach-tegra/board-seaboard.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * arch/arm/mach-tegra/board-seaboard.h - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_TEGRA_BOARD_SEABOARD_H -#define _MACH_TEGRA_BOARD_SEABOARD_H - -#include - -#define SEABOARD_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_)) -#define SEABOARD_GPIO_WM8903(_x_) (SEABOARD_GPIO_TPS6586X(4) + (_x_)) - -#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5 -#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1 -#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PI6 -#define TEGRA_GPIO_LIDSWITCH TEGRA_GPIO_PC7 -#define TEGRA_GPIO_USB1 TEGRA_GPIO_PD0 -#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2 -#define TEGRA_GPIO_BACKLIGHT TEGRA_GPIO_PD4 -#define TEGRA_GPIO_LVDS_SHUTDOWN TEGRA_GPIO_PB2 -#define TEGRA_GPIO_BACKLIGHT_PWM TEGRA_GPIO_PU5 -#define TEGRA_GPIO_BACKLIGHT_VDD TEGRA_GPIO_PW0 -#define TEGRA_GPIO_EN_VDD_PNL TEGRA_GPIO_PC6 -#define TEGRA_GPIO_MAGNETOMETER TEGRA_GPIO_PN5 -#define TEGRA_GPIO_ISL29018_IRQ TEGRA_GPIO_PZ2 -#define TEGRA_GPIO_AC_ONLINE TEGRA_GPIO_PV3 -#define TEGRA_GPIO_WWAN_PWR SEABOARD_GPIO_TPS6586X(2) -#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3 -#define TEGRA_GPIO_SPKR_EN SEABOARD_GPIO_WM8903(2) -#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PX1 -#define TEGRA_GPIO_KAEN_HP_MUTE TEGRA_GPIO_PA5 - -void seaboard_pinmux_init(void); - -#endif -- GitLab From c554dee35c3e6b0c19db5fb75193d4cd99736c6b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 2 May 2012 13:43:26 -0600 Subject: [PATCH 2203/6849] ARM: tegra: trimslice: enable PCIe when booting from device tree There currently aren't bindings for the Tegra PCIe controller. Work on this is in progress, but not yet complete. Manually initialize PCIe when booting from device tree, in order to bring DT support to the same feature level as board files, which will in turn allow board files to be deprecated. PCIe hosts the wired Ethernet controller on TrimSlice. To support this, add infra-structure to board-dt-tegra20.c for board- specific initialization code. Once device tree support for the relevant features is in place, this code will be removed. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-dt-tegra20.c | 36 +++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index eb7249db50a5..9537f20384fc 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -98,6 +98,40 @@ static void __init tegra_dt_init(void) tegra20_auxdata_lookup, NULL); } +#ifdef CONFIG_MACH_TRIMSLICE +static void __init trimslice_init(void) +{ + int ret; + + ret = tegra_pcie_init(true, true); + if (ret) + pr_err("tegra_pci_init() failed: %d\n", ret); +} +#endif + +static struct { + char *machine; + void (*init)(void); +} board_init_funcs[] = { +#ifdef CONFIG_MACH_TRIMSLICE + { "compulab,trimslice", trimslice_init }, +#endif +}; + +static void __init tegra_dt_init_late(void) +{ + int i; + + tegra_init_late(); + + for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) { + if (of_machine_is_compatible(board_init_funcs[i].machine)) { + board_init_funcs[i].init(); + break; + } + } +} + static const char *tegra20_dt_board_compat[] = { "nvidia,tegra20", NULL @@ -110,7 +144,7 @@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") .handle_irq = gic_handle_irq, .timer = &tegra_timer, .init_machine = tegra_dt_init, - .init_late = tegra_init_late, + .init_late = tegra_dt_init_late, .restart = tegra_assert_system_reset, .dt_compat = tegra20_dt_board_compat, MACHINE_END -- GitLab From a12c0efc7a3f433377add0fa1fd0ed4836cc595e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 2 May 2012 15:47:12 -0600 Subject: [PATCH 2204/6849] ARM: tegra: harmony: init regulators, PCIe when booting from DT There currently aren't bindings for the Tegra PCIe controller. Work on this is in progress, but not yet complete. Manually initialize PCIe when booting from device tree, in order to bring DT support to the same feature level as board files, which will in turn allow board files to be deprecated. PCIe on Harmony requires various regulators to be registered and enabled before initializing the PCIe controller. Note that since the I2C controllers are instantiated from DT, we must use i2c_new_device() to register the PMU rather than i2c_register_board_info(). Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-dt-tegra20.c | 20 ++++++++++++++++++ arch/arm/mach-tegra/board-harmony-pcie.c | 15 +++++++++----- arch/arm/mach-tegra/board-harmony-power.c | 25 ++++++++++++++++++++++- arch/arm/mach-tegra/board.h | 7 +++++++ 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 9537f20384fc..777138611c77 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -109,6 +109,23 @@ static void __init trimslice_init(void) } #endif +#ifdef CONFIG_MACH_HARMONY +static void __init harmony_init(void) +{ + int ret; + + ret = harmony_regulator_init(); + if (ret) { + pr_err("harmony_regulator_init() failed: %d\n", ret); + return; + } + + ret = harmony_pcie_init(); + if (ret) + pr_err("harmony_pcie_init() failed: %d\n", ret); +} +#endif + static struct { char *machine; void (*init)(void); @@ -116,6 +133,9 @@ static struct { #ifdef CONFIG_MACH_TRIMSLICE { "compulab,trimslice", trimslice_init }, #endif +#ifdef CONFIG_MACH_HARMONY + { "nvidia,harmony", harmony_init }, +#endif }; static void __init tegra_dt_init_late(void) diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c index 33c4fedab840..e8c3fda9bec2 100644 --- a/arch/arm/mach-tegra/board-harmony-pcie.c +++ b/arch/arm/mach-tegra/board-harmony-pcie.c @@ -27,14 +27,11 @@ #ifdef CONFIG_TEGRA_PCI -static int __init harmony_pcie_init(void) +int __init harmony_pcie_init(void) { struct regulator *regulator = NULL; int err; - if (!machine_is_harmony()) - return 0; - err = gpio_request(TEGRA_GPIO_EN_VDD_1V05_GPIO, "EN_VDD_1V05"); if (err) return err; @@ -62,7 +59,15 @@ err_reg: return err; } +static int __init harmony_pcie_initcall(void) +{ + if (!machine_is_harmony()) + return 0; + + return harmony_pcie_init(); +} + /* PCI should be initialized after I2C, mfd and regulators */ -subsys_initcall_sync(harmony_pcie_init); +subsys_initcall_sync(harmony_pcie_initcall); #endif diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index 82f32300796c..44dcb2e869b5 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c @@ -20,6 +20,10 @@ #include #include #include +#include +#include + +#include #include @@ -110,7 +114,26 @@ static struct i2c_board_info __initdata harmony_regulators[] = { int __init harmony_regulator_init(void) { - i2c_register_board_info(3, harmony_regulators, 1); + if (machine_is_harmony()) { + i2c_register_board_info(3, harmony_regulators, 1); + } else { /* Harmony, booted using device tree */ + struct device_node *np; + struct i2c_adapter *adapter; + + np = of_find_node_by_path("/i2c@7000d000"); + if (np == NULL) { + pr_err("Could not find device_node for DVC I2C\n"); + return -ENODEV; + } + + adapter = of_find_i2c_adapter_by_node(np); + if (!adapter) { + pr_err("Could not find i2c_adapter for DVC I2C\n"); + return -ENODEV; + } + + i2c_new_device(adapter, harmony_regulators); + } return 0; } diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 65014968fc6c..097e0e16eacd 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h @@ -46,5 +46,12 @@ int __init tegra_powergate_debugfs_init(void); static inline int tegra_powergate_debugfs_init(void) { return 0; } #endif +int __init harmony_regulator_init(void); +#ifdef CONFIG_TEGRA_PCI +int __init harmony_pcie_init(void); +#else +static inline int harmony_pcie_init(void) { return 0; } +#endif + extern struct sys_timer tegra_timer; #endif -- GitLab From b64a02c6fa184405ac2de0ea048be2f342144a08 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 2 May 2012 16:05:44 -0600 Subject: [PATCH 2205/6849] ARM: tegra: paz00: enable WiFi rfkill when booting from device tree There currently aren't bindings for a WiFi rfkill button, and defining a good binding is non-trivial. Manually register this "device" when booting from device tree, in order to bring DT support to the same feature level as board files, which will in turn allow board files to be deprecated. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-dt-tegra20.c | 10 ++++++++++ arch/arm/mach-tegra/board-paz00.c | 7 ++++++- arch/arm/mach-tegra/board.h | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 777138611c77..8b4e6e1f0f7b 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -126,6 +126,13 @@ static void __init harmony_init(void) } #endif +#ifdef CONFIG_MACH_PAZ00 +static void __init paz00_init(void) +{ + tegra_paz00_wifikill_init(); +} +#endif + static struct { char *machine; void (*init)(void); @@ -136,6 +143,9 @@ static struct { #ifdef CONFIG_MACH_HARMONY { "nvidia,harmony", harmony_init }, #endif +#ifdef CONFIG_MACH_PAZ00 + { "compal,paz00", paz00_init }, +#endif }; static void __init tegra_dt_init_late(void) diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index bbc1907e98a6..4b64af5cab27 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -148,7 +148,6 @@ static struct platform_device *paz00_devices[] __initdata = { &debug_uart, &tegra_sdhci_device4, &tegra_sdhci_device1, - &wifi_rfkill_device, &leds_gpio, &gpio_keys_device, }; @@ -201,6 +200,11 @@ static struct tegra_sdhci_platform_data sdhci_pdata4 = { .is_8bit = 1, }; +void __init tegra_paz00_wifikill_init(void) +{ + platform_device_register(&wifi_rfkill_device); +} + static void __init tegra_paz00_init(void) { tegra_clk_init_from_table(paz00_clk_init_table); @@ -211,6 +215,7 @@ static void __init tegra_paz00_init(void) tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; platform_add_devices(paz00_devices, ARRAY_SIZE(paz00_devices)); + tegra_paz00_wifikill_init(); paz00_i2c_init(); paz00_usb_init(); diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 097e0e16eacd..f88e5143c767 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h @@ -53,5 +53,7 @@ int __init harmony_pcie_init(void); static inline int harmony_pcie_init(void) { return 0; } #endif +void __init tegra_paz00_wifikill_init(void); + extern struct sys_timer tegra_timer; #endif -- GitLab From b1027439dff844675f6c0df97a1b1d190791a699 Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Wed, 20 Jun 2012 14:35:28 -0400 Subject: [PATCH 2206/6849] NFS: Force the legacy idmapper to be single threaded It was initially coded under the assumption that there would only be one request at a time, so use a lock to enforce this requirement.. Signed-off-by: Bryan Schumaker CC: stable@vger.kernel.org [3.4+] Signed-off-by: Trond Myklebust --- fs/nfs/idmap.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index b5b86a05059c..864c51e4b400 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -57,6 +57,11 @@ unsigned int nfs_idmap_cache_timeout = 600; static const struct cred *id_resolver_cache; static struct key_type key_type_id_resolver_legacy; +struct idmap { + struct rpc_pipe *idmap_pipe; + struct key_construction *idmap_key_cons; + struct mutex idmap_mutex; +}; /** * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields @@ -310,9 +315,11 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, name, namelen, type, data, data_size, NULL); if (ret < 0) { + mutex_lock(&idmap->idmap_mutex); ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, name, namelen, type, data, data_size, idmap); + mutex_unlock(&idmap->idmap_mutex); } return ret; } @@ -354,11 +361,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ /* idmap classic begins here */ module_param(nfs_idmap_cache_timeout, int, 0644); -struct idmap { - struct rpc_pipe *idmap_pipe; - struct key_construction *idmap_key_cons; -}; - enum { Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err }; @@ -469,6 +471,7 @@ nfs_idmap_new(struct nfs_client *clp) return error; } idmap->idmap_pipe = pipe; + mutex_init(&idmap->idmap_mutex); clp->cl_idmap = idmap; return 0; -- GitLab From a89534edaaa7008992b878680490e9b02a665563 Mon Sep 17 00:00:00 2001 From: Woody Hung Date: Wed, 13 Jun 2012 15:01:16 +0800 Subject: [PATCH 2207/6849] rt2x00 : RT3290 chip support v4 This patch support the new chipset rt3290 wifi implementation in rt2x00. It initailize the related mac, bbp and rf register in startup phase. And this patch modify the efuse read/write method for the different efuse data offset of rt3290. Signed-off-by: Woody Hung Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 8 + drivers/net/wireless/rt2x00/rt2800.h | 173 +++++++++++- drivers/net/wireless/rt2x00/rt2800lib.c | 350 ++++++++++++++++++++---- drivers/net/wireless/rt2x00/rt2800pci.c | 82 +++++- drivers/net/wireless/rt2x00/rt2800pci.h | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00pci.c | 9 + 7 files changed, 567 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 299c3879582d..c7548da6573d 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -99,6 +99,14 @@ config RT2800PCI_RT53XX rt2800pci driver. Supported chips: RT5390 +config RT2800PCI_RT3290 + bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)" + depends on EXPERIMENTAL + default y + ---help--- + This adds support for rt3290 wireless chipset family to the + rt2800pci driver. + Supported chips: RT3290 endif config RT2500USB diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 1ca88cdc6ece..e252e9bafd0e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -68,6 +68,7 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3053 0x000d +#define RF3290 0x3290 #define RF5360 0x5360 #define RF5370 0x5370 #define RF5372 0x5372 @@ -117,6 +118,12 @@ * Registers. */ + +/* + * MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number. + */ +#define MAC_CSR0_3290 0x0000 + /* * E2PROM_CSR: PCI EEPROM control register. * RELOAD: Write 1 to reload eeprom content. @@ -132,6 +139,150 @@ #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) #define E2PROM_CSR_RELOAD FIELD32(0x00000080) +/* + * CMB_CTRL_CFG + */ +#define CMB_CTRL 0x0020 +#define AUX_OPT_BIT0 FIELD32(0x00000001) +#define AUX_OPT_BIT1 FIELD32(0x00000002) +#define AUX_OPT_BIT2 FIELD32(0x00000004) +#define AUX_OPT_BIT3 FIELD32(0x00000008) +#define AUX_OPT_BIT4 FIELD32(0x00000010) +#define AUX_OPT_BIT5 FIELD32(0x00000020) +#define AUX_OPT_BIT6 FIELD32(0x00000040) +#define AUX_OPT_BIT7 FIELD32(0x00000080) +#define AUX_OPT_BIT8 FIELD32(0x00000100) +#define AUX_OPT_BIT9 FIELD32(0x00000200) +#define AUX_OPT_BIT10 FIELD32(0x00000400) +#define AUX_OPT_BIT11 FIELD32(0x00000800) +#define AUX_OPT_BIT12 FIELD32(0x00001000) +#define AUX_OPT_BIT13 FIELD32(0x00002000) +#define AUX_OPT_BIT14 FIELD32(0x00004000) +#define AUX_OPT_BIT15 FIELD32(0x00008000) +#define LDO25_LEVEL FIELD32(0x00030000) +#define LDO25_LARGEA FIELD32(0x00040000) +#define LDO25_FRC_ON FIELD32(0x00080000) +#define CMB_RSV FIELD32(0x00300000) +#define XTAL_RDY FIELD32(0x00400000) +#define PLL_LD FIELD32(0x00800000) +#define LDO_CORE_LEVEL FIELD32(0x0F000000) +#define LDO_BGSEL FIELD32(0x30000000) +#define LDO3_EN FIELD32(0x40000000) +#define LDO0_EN FIELD32(0x80000000) + +/* + * EFUSE_CSR_3290: RT3290 EEPROM + */ +#define EFUSE_CTRL_3290 0x0024 + +/* + * EFUSE_DATA3 of 3290 + */ +#define EFUSE_DATA3_3290 0x0028 + +/* + * EFUSE_DATA2 of 3290 + */ +#define EFUSE_DATA2_3290 0x002c + +/* + * EFUSE_DATA1 of 3290 + */ +#define EFUSE_DATA1_3290 0x0030 + +/* + * EFUSE_DATA0 of 3290 + */ +#define EFUSE_DATA0_3290 0x0034 + +/* + * OSC_CTRL_CFG + * Ring oscillator configuration + */ +#define OSC_CTRL 0x0038 +#define OSC_REF_CYCLE FIELD32(0x00001fff) +#define OSC_RSV FIELD32(0x0000e000) +#define OSC_CAL_CNT FIELD32(0x0fff0000) +#define OSC_CAL_ACK FIELD32(0x10000000) +#define OSC_CLK_32K_VLD FIELD32(0x20000000) +#define OSC_CAL_REQ FIELD32(0x40000000) +#define OSC_ROSC_EN FIELD32(0x80000000) + +/* + * COEX_CFG_0 + */ +#define COEX_CFG0 0x0040 +#define COEX_CFG_ANT FIELD32(0xff000000) +/* + * COEX_CFG_1 + */ +#define COEX_CFG1 0x0044 + +/* + * COEX_CFG_2 + */ +#define COEX_CFG2 0x0048 +#define BT_COEX_CFG1 FIELD32(0xff000000) +#define BT_COEX_CFG0 FIELD32(0x00ff0000) +#define WL_COEX_CFG1 FIELD32(0x0000ff00) +#define WL_COEX_CFG0 FIELD32(0x000000ff) +/* + * PLL_CTRL_CFG + * PLL configuration register + */ +#define PLL_CTRL 0x0050 +#define PLL_RESERVED_INPUT1 FIELD32(0x000000ff) +#define PLL_RESERVED_INPUT2 FIELD32(0x0000ff00) +#define PLL_CONTROL FIELD32(0x00070000) +#define PLL_LPF_R1 FIELD32(0x00080000) +#define PLL_LPF_C1_CTRL FIELD32(0x00300000) +#define PLL_LPF_C2_CTRL FIELD32(0x00c00000) +#define PLL_CP_CURRENT_CTRL FIELD32(0x03000000) +#define PLL_PFD_DELAY_CTRL FIELD32(0x0c000000) +#define PLL_LOCK_CTRL FIELD32(0x70000000) +#define PLL_VBGBK_EN FIELD32(0x80000000) + + +/* + * WLAN_CTRL_CFG + * RT3290 wlan configuration + */ +#define WLAN_FUN_CTRL 0x0080 +#define WLAN_EN FIELD32(0x00000001) +#define WLAN_CLK_EN FIELD32(0x00000002) +#define WLAN_RSV1 FIELD32(0x00000004) +#define WLAN_RESET FIELD32(0x00000008) +#define PCIE_APP0_CLK_REQ FIELD32(0x00000010) +#define FRC_WL_ANT_SET FIELD32(0x00000020) +#define INV_TR_SW0 FIELD32(0x00000040) +#define WLAN_GPIO_IN_BIT0 FIELD32(0x00000100) +#define WLAN_GPIO_IN_BIT1 FIELD32(0x00000200) +#define WLAN_GPIO_IN_BIT2 FIELD32(0x00000400) +#define WLAN_GPIO_IN_BIT3 FIELD32(0x00000800) +#define WLAN_GPIO_IN_BIT4 FIELD32(0x00001000) +#define WLAN_GPIO_IN_BIT5 FIELD32(0x00002000) +#define WLAN_GPIO_IN_BIT6 FIELD32(0x00004000) +#define WLAN_GPIO_IN_BIT7 FIELD32(0x00008000) +#define WLAN_GPIO_IN_BIT_ALL FIELD32(0x0000ff00) +#define WLAN_GPIO_OUT_BIT0 FIELD32(0x00010000) +#define WLAN_GPIO_OUT_BIT1 FIELD32(0x00020000) +#define WLAN_GPIO_OUT_BIT2 FIELD32(0x00040000) +#define WLAN_GPIO_OUT_BIT3 FIELD32(0x00050000) +#define WLAN_GPIO_OUT_BIT4 FIELD32(0x00100000) +#define WLAN_GPIO_OUT_BIT5 FIELD32(0x00200000) +#define WLAN_GPIO_OUT_BIT6 FIELD32(0x00400000) +#define WLAN_GPIO_OUT_BIT7 FIELD32(0x00800000) +#define WLAN_GPIO_OUT_BIT_ALL FIELD32(0x00ff0000) +#define WLAN_GPIO_OUT_OE_BIT0 FIELD32(0x01000000) +#define WLAN_GPIO_OUT_OE_BIT1 FIELD32(0x02000000) +#define WLAN_GPIO_OUT_OE_BIT2 FIELD32(0x04000000) +#define WLAN_GPIO_OUT_OE_BIT3 FIELD32(0x08000000) +#define WLAN_GPIO_OUT_OE_BIT4 FIELD32(0x10000000) +#define WLAN_GPIO_OUT_OE_BIT5 FIELD32(0x20000000) +#define WLAN_GPIO_OUT_OE_BIT6 FIELD32(0x40000000) +#define WLAN_GPIO_OUT_OE_BIT7 FIELD32(0x80000000) +#define WLAN_GPIO_OUT_OE_BIT_ALL FIELD32(0xff000000) + /* * AUX_CTRL: Aux/PCI-E related configuration */ @@ -1763,9 +1914,11 @@ struct mac_iveiv_entry { /* * BBP 3: RX Antenna */ -#define BBP3_RX_ADC FIELD8(0x03) +#define BBP3_RX_ADC FIELD8(0x03) #define BBP3_RX_ANTENNA FIELD8(0x18) #define BBP3_HT40_MINUS FIELD8(0x20) +#define BBP3_ADC_MODE_SWITCH FIELD8(0x40) +#define BBP3_ADC_INIT_MODE FIELD8(0x80) /* * BBP 4: Bandwidth @@ -1774,6 +1927,14 @@ struct mac_iveiv_entry { #define BBP4_BANDWIDTH FIELD8(0x18) #define BBP4_MAC_IF_CTRL FIELD8(0x40) +/* + * BBP 47: Bandwidth + */ +#define BBP47_TSSI_REPORT_SEL FIELD8(0x03) +#define BBP47_TSSI_UPDATE_REQ FIELD8(0x04) +#define BBP47_TSSI_TSSI_MODE FIELD8(0x18) +#define BBP47_TSSI_ADC6 FIELD8(0x80) + /* * BBP 109 */ @@ -1916,6 +2077,16 @@ struct mac_iveiv_entry { #define RFCSR27_R3 FIELD8(0x30) #define RFCSR27_R4 FIELD8(0x40) +/* + * RFCSR 29: + */ +#define RFCSR29_ADC6_TEST FIELD8(0x01) +#define RFCSR29_ADC6_INT_TEST FIELD8(0x02) +#define RFCSR29_RSSI_RESET FIELD8(0x04) +#define RFCSR29_RSSI_ON FIELD8(0x08) +#define RFCSR29_RSSI_RIP_CTRL FIELD8(0x30) +#define RFCSR29_RSSI_GAIN FIELD8(0xc0) + /* * RFCSR 30: */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 4d3747c3010b..068276ee8aff 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -354,16 +354,15 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, * of 4kb. Certain USB chipsets however require different firmware, * which Ralink only provides attached to the original firmware * file. Thus for USB devices, firmware files have a length - * which is a multiple of 4kb. + * which is a multiple of 4kb. The firmware for rt3290 chip also + * have a length which is a multiple of 4kb. */ - if (rt2x00_is_usb(rt2x00dev)) { + if (rt2x00_is_usb(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290)) fw_len = 4096; - multiple = true; - } else { + else fw_len = 8192; - multiple = true; - } + multiple = true; /* * Validate the firmware length */ @@ -415,7 +414,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, return -EBUSY; if (rt2x00_is_pci(rt2x00dev)) { - if (rt2x00_rt(rt2x00dev, RT3572) || + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { rt2800_register_read(rt2x00dev, AUX_CTRL, ®); @@ -851,8 +851,13 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0); + } else { + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); + } } EXPORT_SYMBOL_GPL(rt2800_rfkill_poll); @@ -1935,9 +1940,54 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); } +#define RT3290_POWER_BOUND 0x27 +#define RT3290_FREQ_OFFSET_BOUND 0x5f #define RT5390_POWER_BOUND 0x27 #define RT5390_FREQ_OFFSET_BOUND 0x5f +static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, + struct channel_info *info) +{ + u8 rfcsr; + + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); + rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); + rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); + rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); + if (info->default_power1 > RT3290_POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT3290_POWER_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + if (rt2x00dev->freq_offset > RT3290_FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, + RT3290_FREQ_OFFSET_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + + if (rf->channel <= 14) { + if (rf->channel == 6) + rt2800_bbp_write(rt2x00dev, 68, 0x0c); + else + rt2800_bbp_write(rt2x00dev, 68, 0x0b); + + if (rf->channel >= 1 && rf->channel <= 6) + rt2800_bbp_write(rt2x00dev, 59, 0x0f); + else if (rf->channel >= 7 && rf->channel <= 11) + rt2800_bbp_write(rt2x00dev, 59, 0x0e); + else if (rf->channel >= 12 && rf->channel <= 14) + rt2800_bbp_write(rt2x00dev, 59, 0x0d); + } +} + static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, @@ -2036,15 +2086,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, } } } - - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); } static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, @@ -2054,7 +2095,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, { u32 reg; unsigned int tx_pin; - u8 bbp; + u8 bbp, rfcsr; if (rf->channel <= 14) { info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); @@ -2075,6 +2116,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF3052: rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); break; + case RF3290: + rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info); + break; case RF5360: case RF5370: case RF5372: @@ -2086,6 +2130,22 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); } + if (rt2x00_rf(rt2x00dev, RF3290) || + rt2x00_rf(rt2x00dev, RF5360) || + rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || + rt2x00_rf(rt2x00dev, RF5390) || + rt2x00_rf(rt2x00dev, RF5392)) { + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); + } + /* * Change BBP settings */ @@ -2566,6 +2626,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); break; + case RF3290: case RF5360: case RF5370: case RF5372: @@ -2701,6 +2762,7 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) @@ -2797,10 +2859,54 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2); rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + if (rt2x00_get_field32(reg, WLAN_EN) == 1) { + rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 1); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + } + + rt2800_register_read(rt2x00dev, CMB_CTRL, ®); + if (!(rt2x00_get_field32(reg, LDO0_EN) == 1)) { + rt2x00_set_field32(®, LDO0_EN, 1); + rt2x00_set_field32(®, LDO_BGSEL, 3); + rt2800_register_write(rt2x00dev, CMB_CTRL, reg); + } + + rt2800_register_read(rt2x00dev, OSC_CTRL, ®); + rt2x00_set_field32(®, OSC_ROSC_EN, 1); + rt2x00_set_field32(®, OSC_CAL_REQ, 1); + rt2x00_set_field32(®, OSC_REF_CYCLE, 0x27); + rt2800_register_write(rt2x00dev, OSC_CTRL, reg); + + rt2800_register_read(rt2x00dev, COEX_CFG0, ®); + rt2x00_set_field32(®, COEX_CFG_ANT, 0x5e); + rt2800_register_write(rt2x00dev, COEX_CFG0, reg); + + rt2800_register_read(rt2x00dev, COEX_CFG2, ®); + rt2x00_set_field32(®, BT_COEX_CFG1, 0x00); + rt2x00_set_field32(®, BT_COEX_CFG0, 0x17); + rt2x00_set_field32(®, WL_COEX_CFG1, 0x93); + rt2x00_set_field32(®, WL_COEX_CFG0, 0x7f); + rt2800_register_write(rt2x00dev, COEX_CFG2, reg); + + rt2800_register_read(rt2x00dev, PLL_CTRL, ®); + rt2x00_set_field32(®, PLL_CONTROL, 1); + rt2800_register_write(rt2x00dev, PLL_CTRL, reg); + } + if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); + + if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_register_write(rt2x00dev, TX_SW_CFG0, + 0x00000404); + else + rt2800_register_write(rt2x00dev, TX_SW_CFG0, + 0x00000400); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || @@ -3209,14 +3315,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_read(rt2x00dev, 4, &value); rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); rt2800_bbp_write(rt2x00dev, 4, value); } if (rt2800_is_305x_soc(rt2x00dev) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) @@ -3225,20 +3333,26 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 68, 0x0b); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { rt2800_bbp_write(rt2x00dev, 69, 0x16); rt2800_bbp_write(rt2x00dev, 73, 0x12); - } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + } else if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x13); rt2800_bbp_write(rt2x00dev, 75, 0x46); rt2800_bbp_write(rt2x00dev, 76, 0x28); - rt2800_bbp_write(rt2x00dev, 77, 0x59); + + if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_bbp_write(rt2x00dev, 77, 0x58); + else + rt2800_bbp_write(rt2x00dev, 77, 0x59); } else { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x10); @@ -3263,23 +3377,33 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 81, 0x37); } + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_bbp_write(rt2x00dev, 74, 0x0b); + rt2800_bbp_write(rt2x00dev, 79, 0x18); + rt2800_bbp_write(rt2x00dev, 80, 0x09); + rt2800_bbp_write(rt2x00dev, 81, 0x33); + } + rt2800_bbp_write(rt2x00dev, 82, 0x62); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 83, 0x7a); else rt2800_bbp_write(rt2x00dev, 83, 0x6a); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); - else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + else if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 86, 0x38); else rt2800_bbp_write(rt2x00dev, 86, 0x00); @@ -3289,8 +3413,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 91, 0x04); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 92, 0x02); else rt2800_bbp_write(rt2x00dev, 92, 0x00); @@ -3304,6 +3429,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || + rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392) || @@ -3312,27 +3438,32 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) else rt2800_bbp_write(rt2x00dev, 103, 0x00); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 104, 0x92); if (rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 105, 0x01); + else if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_bbp_write(rt2x00dev, 105, 0x1c); else if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 106, 0x03); else if (rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 106, 0x12); else rt2800_bbp_write(rt2x00dev, 106, 0x35); - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 128, 0x12); if (rt2x00_rt(rt2x00dev, RT5392)) { @@ -3357,6 +3488,29 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_bbp_write(rt2x00dev, 67, 0x24); + rt2800_bbp_write(rt2x00dev, 143, 0x04); + rt2800_bbp_write(rt2x00dev, 142, 0x99); + rt2800_bbp_write(rt2x00dev, 150, 0x30); + rt2800_bbp_write(rt2x00dev, 151, 0x2e); + rt2800_bbp_write(rt2x00dev, 152, 0x20); + rt2800_bbp_write(rt2x00dev, 153, 0x34); + rt2800_bbp_write(rt2x00dev, 154, 0x40); + rt2800_bbp_write(rt2x00dev, 155, 0x3b); + rt2800_bbp_write(rt2x00dev, 253, 0x04); + + rt2800_bbp_read(rt2x00dev, 47, &value); + rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1); + rt2800_bbp_write(rt2x00dev, 47, value); + + /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */ + rt2800_bbp_read(rt2x00dev, 3, &value); + rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1); + rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1); + rt2800_bbp_write(rt2x00dev, 3, value); + } + if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { int ant, div_mode; @@ -3489,6 +3643,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (!rt2x00_rt(rt2x00dev, RT3070) && !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && + !rt2x00_rt(rt2x00dev, RT3290) && !rt2x00_rt(rt2x00dev, RT3390) && !rt2x00_rt(rt2x00dev, RT3572) && !rt2x00_rt(rt2x00dev, RT5390) && @@ -3499,8 +3654,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) /* * Init RF calibration. */ - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); @@ -3538,6 +3694,53 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 24, 0x16); rt2800_rfcsr_write(rt2x00dev, 25, 0x01); rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); + } else if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 4, 0x00); + rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); + rt2800_rfcsr_write(rt2x00dev, 9, 0x02); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 18, 0x02); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 25, 0x83); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x05); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x98); + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + rt2800_rfcsr_write(rt2x00dev, 54, 0x78); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0x02); + rt2800_rfcsr_write(rt2x00dev, 57, 0x80); + rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x09); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); } else if (rt2x00_rt(rt2x00dev, RT3390)) { rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); @@ -3946,6 +4149,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); } + if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); + rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); + } + if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); @@ -4052,9 +4261,14 @@ EXPORT_SYMBOL_GPL(rt2800_disable_radio); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) { u32 reg; + u16 efuse_ctrl_reg; - rt2800_register_read(rt2x00dev, EFUSE_CTRL, ®); + if (rt2x00_rt(rt2x00dev, RT3290)) + efuse_ctrl_reg = EFUSE_CTRL_3290; + else + efuse_ctrl_reg = EFUSE_CTRL; + rt2800_register_read(rt2x00dev, efuse_ctrl_reg, ®); return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT); } EXPORT_SYMBOL_GPL(rt2800_efuse_detect); @@ -4062,27 +4276,44 @@ EXPORT_SYMBOL_GPL(rt2800_efuse_detect); static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) { u32 reg; - + u16 efuse_ctrl_reg; + u16 efuse_data0_reg; + u16 efuse_data1_reg; + u16 efuse_data2_reg; + u16 efuse_data3_reg; + + if (rt2x00_rt(rt2x00dev, RT3290)) { + efuse_ctrl_reg = EFUSE_CTRL_3290; + efuse_data0_reg = EFUSE_DATA0_3290; + efuse_data1_reg = EFUSE_DATA1_3290; + efuse_data2_reg = EFUSE_DATA2_3290; + efuse_data3_reg = EFUSE_DATA3_3290; + } else { + efuse_ctrl_reg = EFUSE_CTRL; + efuse_data0_reg = EFUSE_DATA0; + efuse_data1_reg = EFUSE_DATA1; + efuse_data2_reg = EFUSE_DATA2; + efuse_data3_reg = EFUSE_DATA3; + } mutex_lock(&rt2x00dev->csr_mutex); - rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, ®); + rt2800_register_read_lock(rt2x00dev, efuse_ctrl_reg, ®); rt2x00_set_field32(®, EFUSE_CTRL_ADDRESS_IN, i); rt2x00_set_field32(®, EFUSE_CTRL_MODE, 0); rt2x00_set_field32(®, EFUSE_CTRL_KICK, 1); - rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg); + rt2800_register_write_lock(rt2x00dev, efuse_ctrl_reg, reg); /* Wait until the EEPROM has been loaded */ - rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); - + rt2800_regbusy_read(rt2x00dev, efuse_ctrl_reg, EFUSE_CTRL_KICK, ®); /* Apparently the data is read from end to start */ - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data3_reg, ®); /* The returned value is in CPU order, but eeprom is le */ *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data2_reg, ®); *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data1_reg, ®); *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, ®); + rt2800_register_read_lock(rt2x00dev, efuse_data0_reg, ®); *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg); mutex_unlock(&rt2x00dev->csr_mutex); @@ -4244,9 +4475,14 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field * RT53xx: defined in "EEPROM_CHIP_ID" field */ - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || - rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) + if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_register_read(rt2x00dev, MAC_CSR0_3290, ®); + else + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + + if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 || + rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || + rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); else value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); @@ -4261,6 +4497,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RT3070: case RT3071: case RT3090: + case RT3290: case RT3390: case RT3572: case RT5390: @@ -4281,6 +4518,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3021: case RF3022: case RF3052: + case RF3290: case RF3320: case RF5360: case RF5370: @@ -4597,6 +4835,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3290) || rt2x00_rf(rt2x00dev, RF3320) || rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5370) || @@ -4685,6 +4924,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3022: case RF3320: case RF3052: + case RF3290: case RF5360: case RF5370: case RF5372: diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 206158b67426..dd436125fe3d 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -280,7 +280,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue) */ static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) { - return FIRMWARE_RT2860; + /* + * Chip rt3290 use specific 4KB firmware named rt3290.bin. + */ + if (rt2x00_rt(rt2x00dev, RT3290)) + return FIRMWARE_RT3290; + else + return FIRMWARE_RT2860; } static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, @@ -974,6 +980,66 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) return rt2800_validate_eeprom(rt2x00dev); } +static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + int i, count; + + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + if ((rt2x00_get_field32(reg, WLAN_EN) == 1)) + return 0; + + rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); + rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); + rt2x00_set_field32(®, WLAN_CLK_EN, 0); + rt2x00_set_field32(®, WLAN_EN, 1); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + + udelay(REGISTER_BUSY_DELAY); + + count = 0; + do { + /* + * Check PLL_LD & XTAL_RDY. + */ + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, CMB_CTRL, ®); + if ((rt2x00_get_field32(reg, PLL_LD) == 1) && + (rt2x00_get_field32(reg, XTAL_RDY) == 1)) + break; + udelay(REGISTER_BUSY_DELAY); + } + + if (i >= REGISTER_BUSY_COUNT) { + + if (count >= 10) + return -EIO; + + rt2800_register_write(rt2x00dev, 0x58, 0x018); + udelay(REGISTER_BUSY_DELAY); + rt2800_register_write(rt2x00dev, 0x58, 0x418); + udelay(REGISTER_BUSY_DELAY); + rt2800_register_write(rt2x00dev, 0x58, 0x618); + udelay(REGISTER_BUSY_DELAY); + count++; + } else { + count = 0; + } + + rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); + rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); + rt2x00_set_field32(®, WLAN_CLK_EN, 1); + rt2x00_set_field32(®, WLAN_RESET, 1); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + udelay(10); + rt2x00_set_field32(®, WLAN_RESET, 0); + rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); + udelay(10); + rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); + } while (count != 0); + + return 0; +} static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; @@ -996,6 +1062,17 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; + /* + * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan + * clk for rt3290. That avoid the MCU fail in start phase. + */ + if (rt2x00_rt(rt2x00dev, RT3290)) { + retval = rt2800_enable_wlan_rt3290(rt2x00dev); + + if (retval) + return retval; + } + /* * This device has multiple filters for control frames * and has a separate filter for PS Poll frames. @@ -1175,6 +1252,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1432, 0x7768) }, { PCI_DEVICE(0x1462, 0x891a) }, { PCI_DEVICE(0x1a3b, 0x1059) }, +#ifdef CONFIG_RT2800PCI_RT3290 + { PCI_DEVICE(0x1814, 0x3290) }, +#endif #ifdef CONFIG_RT2800PCI_RT33XX { PCI_DEVICE(0x1814, 0x3390) }, #endif diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index 70e050d904c8..ab22a087c50d 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h @@ -47,6 +47,7 @@ * 8051 firmware image. */ #define FIRMWARE_RT2860 "rt2860.bin" +#define FIRMWARE_RT3290 "rt3290.bin" #define FIRMWARE_IMAGE_BASE 0x2000 /* diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8f754025b06e..8afb546c2b2d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -187,6 +187,7 @@ struct rt2x00_chip { #define RT3070 0x3070 #define RT3071 0x3071 #define RT3090 0x3090 /* 2.4GHz PCIe */ +#define RT3290 0x3290 #define RT3390 0x3390 #define RT3572 0x3572 #define RT3593 0x3593 diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 0a4653a92cab..a0c8caef3b0a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -256,6 +256,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) struct ieee80211_hw *hw; struct rt2x00_dev *rt2x00dev; int retval; + u16 chip; retval = pci_enable_device(pci_dev); if (retval) { @@ -305,6 +306,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) if (retval) goto exit_free_device; + /* + * Because rt3290 chip use different efuse offset to read efuse data. + * So before read efuse it need to indicate it is the + * rt3290 or not. + */ + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip); + rt2x00dev->chip.rt = chip; + retval = rt2x00lib_probe_dev(rt2x00dev); if (retval) goto exit_free_reg; -- GitLab From 4fc0d0160d59689a90cebcdc9c269ac1d8c6d161 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 14 Jun 2012 12:16:57 +0200 Subject: [PATCH 2208/6849] brcmfmac: introduce checkdied debugfs functionality The checkdied functionality provides useful information for analyzing firmware crashes. By exposing this information to a debugfs file users can easily provide its content in bug reports. The functionality is available only when CONFIG_BRCMDBG is selected. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 332 +++++++++++++++++- 1 file changed, 331 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index a07fb01bc36b..9971e130476d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,9 @@ #define CBUF_LEN (128) +/* Device console log buffer state */ +#define CONSOLE_BUFFER_MAX 2024 + struct rte_log_le { __le32 buf; /* Can't be pointer on (64-bit) hosts */ __le32 buf_size; @@ -281,7 +285,7 @@ struct rte_console { * Shared structure between dongle and the host. * The structure contains pointers to trap or assert information. */ -#define SDPCM_SHARED_VERSION 0x0002 +#define SDPCM_SHARED_VERSION 0x0003 #define SDPCM_SHARED_VERSION_MASK 0x00FF #define SDPCM_SHARED_ASSERT_BUILT 0x0100 #define SDPCM_SHARED_ASSERT 0x0200 @@ -428,6 +432,29 @@ struct brcmf_console { u8 *buf; /* Log buffer (host copy) */ uint last; /* Last buffer read index */ }; + +struct brcmf_trap_info { + __le32 type; + __le32 epc; + __le32 cpsr; + __le32 spsr; + __le32 r0; /* a1 */ + __le32 r1; /* a2 */ + __le32 r2; /* a3 */ + __le32 r3; /* a4 */ + __le32 r4; /* v1 */ + __le32 r5; /* v2 */ + __le32 r6; /* v3 */ + __le32 r7; /* v4 */ + __le32 r8; /* v5 */ + __le32 r9; /* sb/v6 */ + __le32 r10; /* sl/v7 */ + __le32 r11; /* fp/v8 */ + __le32 r12; /* ip */ + __le32 r13; /* sp */ + __le32 r14; /* lr */ + __le32 pc; /* r15 */ +}; #endif /* DEBUG */ struct sdpcm_shared { @@ -439,6 +466,7 @@ struct sdpcm_shared { u32 console_addr; /* Address of struct rte_console */ u32 msgtrace_addr; u8 tag[32]; + u32 brpt_addr; }; struct sdpcm_shared_le { @@ -450,6 +478,7 @@ struct sdpcm_shared_le { __le32 console_addr; /* Address of struct rte_console */ __le32 msgtrace_addr; u8 tag[32]; + __le32 brpt_addr; }; @@ -2953,13 +2982,311 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } #ifdef DEBUG +static inline bool brcmf_sdio_valid_shared_address(u32 addr) +{ + return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)); +} + +static int brcmf_sdio_readshared(struct brcmf_sdio *bus, + struct sdpcm_shared *sh) +{ + u32 addr; + int rv; + u32 shaddr = 0; + struct sdpcm_shared_le sh_le; + __le32 addr_le; + + shaddr = bus->ramsize - 4; + + /* + * Read last word in socram to determine + * address of sdpcm_shared structure + */ + rv = brcmf_sdbrcm_membytes(bus, false, shaddr, + (u8 *)&addr_le, 4); + if (rv < 0) + return rv; + + addr = le32_to_cpu(addr_le); + + brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr); + + /* + * Check if addr is valid. + * NVRAM length at the end of memory should have been overwritten. + */ + if (!brcmf_sdio_valid_shared_address(addr)) { + brcmf_dbg(ERROR, "invalid sdpcm_shared address 0x%08X\n", + addr); + return -EINVAL; + } + + /* Read hndrte_shared structure */ + rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, + sizeof(struct sdpcm_shared_le)); + if (rv < 0) + return rv; + + /* Endianness */ + sh->flags = le32_to_cpu(sh_le.flags); + sh->trap_addr = le32_to_cpu(sh_le.trap_addr); + sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr); + sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr); + sh->assert_line = le32_to_cpu(sh_le.assert_line); + sh->console_addr = le32_to_cpu(sh_le.console_addr); + sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr); + + if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { + brcmf_dbg(ERROR, + "sdpcm_shared version mismatch: dhd %d dongle %d\n", + SDPCM_SHARED_VERSION, + sh->flags & SDPCM_SHARED_VERSION_MASK); + return -EPROTO; + } + + return 0; +} + +static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, + struct sdpcm_shared *sh, char __user *data, + size_t count) +{ + u32 addr, console_ptr, console_size, console_index; + char *conbuf = NULL; + __le32 sh_val; + int rv; + loff_t pos = 0; + int nbytes = 0; + + /* obtain console information from device memory */ + addr = sh->console_addr + offsetof(struct rte_console, log_le); + rv = brcmf_sdbrcm_membytes(bus, false, addr, + (u8 *)&sh_val, sizeof(u32)); + if (rv < 0) + return rv; + console_ptr = le32_to_cpu(sh_val); + + addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); + rv = brcmf_sdbrcm_membytes(bus, false, addr, + (u8 *)&sh_val, sizeof(u32)); + if (rv < 0) + return rv; + console_size = le32_to_cpu(sh_val); + + addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); + rv = brcmf_sdbrcm_membytes(bus, false, addr, + (u8 *)&sh_val, sizeof(u32)); + if (rv < 0) + return rv; + console_index = le32_to_cpu(sh_val); + + /* allocate buffer for console data */ + if (console_size <= CONSOLE_BUFFER_MAX) + conbuf = vzalloc(console_size+1); + + if (!conbuf) + return -ENOMEM; + + /* obtain the console data from device */ + conbuf[console_size] = '\0'; + rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf, + console_size); + if (rv < 0) + goto done; + + rv = simple_read_from_buffer(data, count, &pos, + conbuf + console_index, + console_size - console_index); + if (rv < 0) + goto done; + + nbytes = rv; + if (console_index > 0) { + pos = 0; + rv = simple_read_from_buffer(data+nbytes, count, &pos, + conbuf, console_index - 1); + if (rv < 0) + goto done; + rv += nbytes; + } +done: + vfree(conbuf); + return rv; +} + +static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, + char __user *data, size_t count) +{ + int error, res; + char buf[350]; + struct brcmf_trap_info tr; + int nbytes; + loff_t pos = 0; + + if ((sh->flags & SDPCM_SHARED_TRAP) == 0) + return 0; + + error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, + sizeof(struct brcmf_trap_info)); + if (error < 0) + return error; + + nbytes = brcmf_sdio_dump_console(bus, sh, data, count); + if (nbytes < 0) + return nbytes; + + res = scnprintf(buf, sizeof(buf), + "dongle trap info: type 0x%x @ epc 0x%08x\n" + " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" + " lr 0x%08x pc 0x%08x offset 0x%x\n" + " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" + " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", + le32_to_cpu(tr.type), le32_to_cpu(tr.epc), + le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), + le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), + le32_to_cpu(tr.pc), le32_to_cpu(sh->trap_addr), + le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), + le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), + le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), + le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); + + error = simple_read_from_buffer(data+nbytes, count, &pos, buf, res); + if (error < 0) + return error; + + nbytes += error; + return nbytes; +} + +static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, + struct sdpcm_shared *sh, char __user *data, + size_t count) +{ + int error = 0; + char buf[200]; + char file[80] = "?"; + char expr[80] = ""; + int res; + loff_t pos = 0; + + if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { + brcmf_dbg(INFO, "firmware not built with -assert\n"); + return 0; + } else if ((sh->flags & SDPCM_SHARED_ASSERT) == 0) { + brcmf_dbg(INFO, "no assert in dongle\n"); + return 0; + } + + if (sh->assert_file_addr != 0) { + error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, + (u8 *)file, 80); + if (error < 0) + return error; + } + if (sh->assert_exp_addr != 0) { + error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr, + (u8 *)expr, 80); + if (error < 0) + return error; + } + + res = scnprintf(buf, sizeof(buf), + "dongle assert: %s:%d: assert(%s)\n", + file, sh->assert_line, expr); + return simple_read_from_buffer(data, count, &pos, buf, res); +} + +static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) +{ + int error; + struct sdpcm_shared sh; + + down(&bus->sdsem); + error = brcmf_sdio_readshared(bus, &sh); + up(&bus->sdsem); + + if (error < 0) + return error; + + if ((sh.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) + brcmf_dbg(INFO, "firmware not built with -assert\n"); + else if (sh.flags & SDPCM_SHARED_ASSERT) + brcmf_dbg(ERROR, "assertion in dongle\n"); + + if (sh.flags & SDPCM_SHARED_TRAP) + brcmf_dbg(ERROR, "firmware trap in dongle\n"); + + return 0; +} + +static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, + size_t count, loff_t *ppos) +{ + int error = 0; + struct sdpcm_shared sh; + int nbytes = 0; + loff_t pos = *ppos; + + if (pos != 0) + return 0; + + down(&bus->sdsem); + error = brcmf_sdio_readshared(bus, &sh); + if (error < 0) + goto done; + + error = brcmf_sdio_assert_info(bus, &sh, data, count); + if (error < 0) + goto done; + + nbytes = error; + error = brcmf_sdio_trap_info(bus, &sh, data, count); + if (error < 0) + goto done; + + error += nbytes; + *ppos += error; +done: + up(&bus->sdsem); + return error; +} + +static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data, + size_t count, loff_t *ppos) +{ + struct brcmf_sdio *bus = f->private_data; + int res; + + res = brcmf_sdbrcm_died_dump(bus, data, count, ppos); + if (res > 0) + *ppos += res; + return (ssize_t)res; +} + +static const struct file_operations brcmf_sdio_forensic_ops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = brcmf_sdio_forensic_read +}; + static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) { struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr; + struct dentry *dentry = brcmf_debugfs_get_devdir(drvr); + if (IS_ERR_OR_NULL(dentry)) + return; + + debugfs_create_file("forensics", S_IRUGO, dentry, bus, + &brcmf_sdio_forensic_ops); brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); } #else +static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) +{ + return 0; +} + static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) { } @@ -2991,11 +3318,13 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) rxlen, msglen); } else if (timeleft == 0) { brcmf_dbg(ERROR, "resumed on timeout\n"); + brcmf_sdbrcm_checkdied(bus); } else if (pending) { brcmf_dbg(CTL, "cancelled\n"); return -ERESTARTSYS; } else { brcmf_dbg(CTL, "resumed for unknown reason?\n"); + brcmf_sdbrcm_checkdied(bus); } if (rxlen) @@ -3817,6 +4146,7 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); + if (bus) { /* De-register interrupt handler */ brcmf_sdio_intr_unregister(bus->sdiodev); -- GitLab From 5615171c935f41696b5ade3dd27bdf1a579239f2 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 14 Jun 2012 14:16:27 +0200 Subject: [PATCH 2209/6849] brcm80211: add mailing list address for brcm80211 drivers Added the mailing list address brcm80211-dev-list@broadcom.com which can be used to report issues and in bug reports. Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3075a2a29511..fe6dd3d7d2c4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1595,6 +1595,7 @@ M: Arend van Spriel M: Franky (Zhenhui) Lin M: Kan Yan L: linux-wireless@vger.kernel.org +L: brcm80211-dev-list@broadcom.com S: Supported F: drivers/net/wireless/brcm80211/ -- GitLab From a769f9577232afe2c754606a83aad85127e7052a Mon Sep 17 00:00:00 2001 From: Jeongdo Son Date: Fri, 15 Jun 2012 02:28:01 +0900 Subject: [PATCH 2210/6849] rt2x00: Add support for BUFFALO WLI-UC-GNM2 to rt2800usb. This is a RT3070 based device. Signed-off-by: Jeongdo Son Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 20a504072895..6cf336595e25 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -971,6 +971,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0411, 0x015d) }, { USB_DEVICE(0x0411, 0x016f) }, { USB_DEVICE(0x0411, 0x01a2) }, + { USB_DEVICE(0x0411, 0x01ee) }, /* Corega */ { USB_DEVICE(0x07aa, 0x002f) }, { USB_DEVICE(0x07aa, 0x003c) }, -- GitLab From 1521109318466c2e064dcbd732aa64f99a62852f Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 21 Jun 2012 03:43:57 +0900 Subject: [PATCH 2211/6849] ARM: S3C64XX: Add IRQ mapping for wm0010 on Cragganmore Signed-off-by: Dimitris Papastamos Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 4a83b4e7ab32..4645aa15c82a 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -39,6 +39,7 @@ static struct spi_board_info wm1253_devs[] = { .bus_num = 0, .chip_select = 0, .mode = SPI_MODE_0, + .irq = S3C_EINT(5), .controller_data = &wm0010_spi_csinfo, }, }; -- GitLab From 35e808b7e4e9ddac1086716867fe686f52fb78ff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:19 +0200 Subject: [PATCH 2212/6849] ath9k_hw: remove aniState->noiseFloor I don't know why somebody decided to keep a cached copy of beacon rssi in a variable called 'noiseFloor', but the caching is unnecessary and the variable name is confusing, so let's just get rid of it entirely. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 11 ++++------- drivers/net/wireless/ath/ath9k/ani.h | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index b4c77f9d7470..18ce69d7feac 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -266,11 +266,9 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; - aniState->noiseFloor = BEACON_RSSI(ah); - ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", aniState->ofdmNoiseImmunityLevel, - immunityLevel, aniState->noiseFloor, + immunityLevel, BEACON_RSSI(ah), aniState->rssiThrLow, aniState->rssiThrHigh); if (aniState->update_ani) @@ -292,7 +290,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) ATH9K_ANI_FIRSTEP_LEVEL, entry_ofdm->fir_step_level); - if ((aniState->noiseFloor >= aniState->rssiThrHigh) && + if (BEACON_RSSI(ah) >= aniState->rssiThrHigh && (!aniState->ofdmWeakSigDetectOff != entry_ofdm->ofdm_weak_signal_on)) { ath9k_hw_ani_control(ah, @@ -329,15 +327,14 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; - aniState->noiseFloor = BEACON_RSSI(ah); ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", aniState->cckNoiseImmunityLevel, immunityLevel, - aniState->noiseFloor, aniState->rssiThrLow, + BEACON_RSSI(ah), aniState->rssiThrLow, aniState->rssiThrHigh); if ((ah->opmode == NL80211_IFTYPE_STATION || ah->opmode == NL80211_IFTYPE_ADHOC) && - aniState->noiseFloor <= aniState->rssiThrLow && + BEACON_RSSI(ah) <= aniState->rssiThrLow && immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 72e2b874e179..c04d167725f5 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -128,7 +128,6 @@ struct ar5416AniState { u32 listenTime; int32_t rssiThrLow; int32_t rssiThrHigh; - u32 noiseFloor; u32 ofdmPhyErrCount; u32 cckPhyErrCount; int16_t pktRssi[2]; -- GitLab From 0b81cc3922bce79d0f21189648bf4f9992e9a533 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:20 +0200 Subject: [PATCH 2213/6849] ath9k_hw: fix OFDM weak signal detection handling Commit "ath9k_hw: improve ANI processing and rx desensitizing parameters" was unifying some code related to overriding OFDM weak signal detection, but seems to have gotten some of the original intent wrong, probably because of a misnamed variable. The beacon RSSI is only valid in station mode, and the main reason to check it in ath9k_hw_set_ofdm_nil is to make sure that OFDM weak signal detection stays enabled if the RSSI is low, even when the OFDM noise immunity entry is supposed to disable it. The above commit removed the mode checks and changed the code so that OFDM weak signal detection would only be changed if the rssi is high, which is wrong for everything but client mode. This patch restores the old behavior in a simplified form. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 18ce69d7feac..cf310508cac5 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -265,6 +265,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; + bool weak_sig; ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", aniState->ofdmNoiseImmunityLevel, @@ -290,13 +291,15 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) ATH9K_ANI_FIRSTEP_LEVEL, entry_ofdm->fir_step_level); - if (BEACON_RSSI(ah) >= aniState->rssiThrHigh && - (!aniState->ofdmWeakSigDetectOff != - entry_ofdm->ofdm_weak_signal_on)) { + weak_sig = entry_ofdm->ofdm_weak_signal_on; + if (ah->opmode == NL80211_IFTYPE_STATION && + BEACON_RSSI(ah) <= aniState->rssiThrHigh) + weak_sig = true; + + if (!aniState->ofdmWeakSigDetectOff != weak_sig) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, entry_ofdm->ofdm_weak_signal_on); - } } static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) -- GitLab From 7067e7014d7013645f7e866b74814f1e59e6a7cd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:21 +0200 Subject: [PATCH 2214/6849] ath9k_hw: remove confusing logic inversion in an ANI variable Code using this had already triggered smatch complaints, so remove it before it gets fixed the wrong way. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 17 ++++++++--------- drivers/net/wireless/ath/ath9k/ani.h | 2 +- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 18 +++++++++--------- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 +++++----- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index cf310508cac5..aef81707cf88 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -185,7 +185,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) } rssi = BEACON_RSSI(ah); if (rssi > aniState->rssiThrHigh) { - if (!aniState->ofdmWeakSigDetectOff) { + if (aniState->ofdmWeakSigDetect) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, false)) { @@ -200,7 +200,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) return; } } else if (rssi > aniState->rssiThrLow) { - if (aniState->ofdmWeakSigDetectOff) + if (!aniState->ofdmWeakSigDetect) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, true); @@ -211,7 +211,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) } else { if ((conf->channel->band == IEEE80211_BAND_2GHZ) && !conf_is_ht(conf)) { - if (!aniState->ofdmWeakSigDetectOff) + if (aniState->ofdmWeakSigDetect) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, false); @@ -296,7 +296,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) BEACON_RSSI(ah) <= aniState->rssiThrHigh) weak_sig = true; - if (!aniState->ofdmWeakSigDetectOff != weak_sig) + if (aniState->ofdmWeakSigDetect != weak_sig) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, entry_ofdm->ofdm_weak_signal_on); @@ -401,7 +401,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) if (rssi > aniState->rssiThrHigh) { /* XXX: Handle me */ } else if (rssi > aniState->rssiThrLow) { - if (aniState->ofdmWeakSigDetectOff) { + if (!aniState->ofdmWeakSigDetect) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, true)) @@ -509,9 +509,9 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) if (aniState->spurImmunityLevel != 0) ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel); - if (aniState->ofdmWeakSigDetectOff) + if (!aniState->ofdmWeakSigDetect) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - !aniState->ofdmWeakSigDetectOff); + aniState->ofdmWeakSigDetect); if (aniState->cckWeakSigThreshold) ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, aniState->cckWeakSigThreshold); @@ -887,8 +887,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; - ani->ofdmWeakSigDetectOff = - !ATH9K_ANI_USE_OFDM_WEAK_SIG; + ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; ani->update_ani = false; diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index c04d167725f5..2ed848fdf08b 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -122,7 +122,7 @@ struct ar5416AniState { u8 mrcCCKOff; u8 spurImmunityLevel; u8 firstepLevel; - u8 ofdmWeakSigDetectOff; + u8 ofdmWeakSigDetect; u8 cckWeakSigThreshold; bool update_ani; u32 listenTime; diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index c7492c6a2519..d2fb78b4318f 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1042,12 +1042,12 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - if (!on != aniState->ofdmWeakSigDetectOff) { + if (on != aniState->ofdmWeakSigDetect) { if (on) ah->stats.ast_ani_ofdmon++; else ah->stats.ast_ani_ofdmoff++; - aniState->ofdmWeakSigDetectOff = !on; + aniState->ofdmWeakSigDetect = on; } break; } @@ -1114,10 +1114,10 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, ath_dbg(common, ANI, "ANI parameters:\n"); ath_dbg(common, ANI, - "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n", + "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetect=%d\n", aniState->noiseImmunityLevel, aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff); + aniState->ofdmWeakSigDetect); ath_dbg(common, ANI, "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n", aniState->cckWeakSigThreshold, @@ -1206,18 +1206,18 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - if (!on != aniState->ofdmWeakSigDetectOff) { + if (on != aniState->ofdmWeakSigDetect) { ath_dbg(common, ANI, "** ch %d: ofdm weak signal: %s=>%s\n", chan->channel, - !aniState->ofdmWeakSigDetectOff ? + aniState->ofdmWeakSigDetect ? "on" : "off", on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else ah->stats.ast_ani_ofdmoff++; - aniState->ofdmWeakSigDetectOff = !on; + aniState->ofdmWeakSigDetect = on; } break; } @@ -1367,7 +1367,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, ath_dbg(common, ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff ? "on" : "off", + aniState->ofdmWeakSigDetect ? "on" : "off", aniState->firstepLevel, !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, @@ -1456,7 +1456,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) /* these levels just got reset to defaults by the INI */ aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; - aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; + aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = true; /* not available on pre AR9003 */ } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index d6baf69cdc14..bb186d084eb8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -825,18 +825,18 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - if (!on != aniState->ofdmWeakSigDetectOff) { + if (on != aniState->ofdmWeakSigDetect) { ath_dbg(common, ANI, "** ch %d: ofdm weak signal: %s=>%s\n", chan->channel, - !aniState->ofdmWeakSigDetectOff ? + aniState->ofdmWeakSigDetect ? "on" : "off", on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else ah->stats.ast_ani_ofdmoff++; - aniState->ofdmWeakSigDetectOff = !on; + aniState->ofdmWeakSigDetect = on; } break; } @@ -1002,7 +1002,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, ath_dbg(common, ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff ? "on" : "off", + aniState->ofdmWeakSigDetect ? "on" : "off", aniState->firstepLevel, !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, @@ -1113,7 +1113,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) /* these levels just got reset to defaults by the INI */ aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; - aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; + aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; } -- GitLab From 5330df7b178f4f050c67451413020bdd4ec75262 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:22 +0200 Subject: [PATCH 2215/6849] ath9k_hw: clean up / fix ANI mode checks related to beacon RSSI Beacon RSSI is only meaningful in station mode - in ad-hoc mode it fluctuates, depending on which peer last sent a beacon, and in other modes it is not set at all. Fix places in ANI where the beacon RSSI is used to limit their use to station mode only. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index aef81707cf88..4949d8b99d2e 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -176,7 +176,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) } } - if (ah->opmode == NL80211_IFTYPE_AP) { + if (ah->opmode != NL80211_IFTYPE_STATION) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); @@ -236,7 +236,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) return; } } - if (ah->opmode == NL80211_IFTYPE_AP) { + if (ah->opmode != NL80211_IFTYPE_STATION) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); @@ -335,8 +335,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) BEACON_RSSI(ah), aniState->rssiThrLow, aniState->rssiThrHigh); - if ((ah->opmode == NL80211_IFTYPE_STATION || - ah->opmode == NL80211_IFTYPE_ADHOC) && + if (ah->opmode == NL80211_IFTYPE_STATION && BEACON_RSSI(ah) <= aniState->rssiThrLow && immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; @@ -390,7 +389,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) aniState = &ah->curchan->ani; - if (ah->opmode == NL80211_IFTYPE_AP) { + if (ah->opmode != NL80211_IFTYPE_STATION) { if (aniState->firstepLevel > 0) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1)) @@ -474,8 +473,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) aniState = &ah->curchan->ani; - if (ah->opmode != NL80211_IFTYPE_STATION - && ah->opmode != NL80211_IFTYPE_ADHOC) { + if (ah->opmode != NL80211_IFTYPE_STATION) { ath_dbg(common, ANI, "Reset ANI state opmode %u\n", ah->opmode); ah->stats.ast_ani_reset++; -- GitLab From 6790ae7a1383db07842b3fd03208dd86f55da57e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:23 +0200 Subject: [PATCH 2216/6849] ath9k_hw: remove the old ANI implementation It was found to be buggy on a variety of chipsets from AR913x to AR928x. The new version (which was introduced along with AR93xx support) is more reliable in preventing connectivity dropouts and also fixes MIB interrupt storm issues. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 332 +------------------- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 142 +-------- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 - drivers/net/wireless/ath/ath9k/hw.h | 9 +- 4 files changed, 19 insertions(+), 468 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 4949d8b99d2e..175c3f5590e9 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -104,11 +104,6 @@ static const struct ani_cck_level_entry cck_level_table[] = { #define ATH9K_ANI_CCK_DEF_LEVEL \ 2 /* default level - matches the INI settings */ -static bool use_new_ani(struct ath_hw *ah) -{ - return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani; -} - static void ath9k_hw_update_mibstats(struct ath_hw *ah, struct ath9k_mib_stats *stats) { @@ -131,11 +126,6 @@ static void ath9k_ani_restart(struct ath_hw *ah) aniState = &ah->curchan->ani; aniState->listenTime = 0; - if (!use_new_ani(ah)) { - ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; - cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; - } - ath_dbg(common, ANI, "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base); @@ -154,110 +144,6 @@ static void ath9k_ani_restart(struct ath_hw *ah) aniState->cckPhyErrCount = 0; } -static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) -{ - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - struct ar5416AniState *aniState; - int32_t rssi; - - aniState = &ah->curchan->ani; - - if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, - aniState->noiseImmunityLevel + 1)) { - return; - } - } - - if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, - aniState->spurImmunityLevel + 1)) { - return; - } - } - - if (ah->opmode != NL80211_IFTYPE_STATION) { - if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel + 1); - } - return; - } - rssi = BEACON_RSSI(ah); - if (rssi > aniState->rssiThrHigh) { - if (aniState->ofdmWeakSigDetect) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - false)) { - ath9k_hw_ani_control(ah, - ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); - return; - } - } - if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel + 1); - return; - } - } else if (rssi > aniState->rssiThrLow) { - if (!aniState->ofdmWeakSigDetect) - ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - true); - if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel + 1); - return; - } else { - if ((conf->channel->band == IEEE80211_BAND_2GHZ) && - !conf_is_ht(conf)) { - if (aniState->ofdmWeakSigDetect) - ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - false); - if (aniState->firstepLevel > 0) - ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, 0); - return; - } - } -} - -static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) -{ - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - struct ar5416AniState *aniState; - int32_t rssi; - - aniState = &ah->curchan->ani; - if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, - aniState->noiseImmunityLevel + 1)) { - return; - } - } - if (ah->opmode != NL80211_IFTYPE_STATION) { - if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel + 1); - } - return; - } - rssi = BEACON_RSSI(ah); - if (rssi > aniState->rssiThrLow) { - if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel + 1); - } else { - if ((conf->channel->band == IEEE80211_BAND_2GHZ) && - !conf_is_ht(conf)) { - if (aniState->firstepLevel > 0) - ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, 0); - } - } -} - /* Adjust the OFDM Noise Immunity Level */ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) { @@ -309,11 +195,6 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) if (!DO_ANI(ah)) return; - if (!use_new_ani(ah)) { - ath9k_hw_ani_ofdm_err_trigger_old(ah); - return; - } - aniState = &ah->curchan->ani; if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) @@ -371,70 +252,12 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) if (!DO_ANI(ah)) return; - if (!use_new_ani(ah)) { - ath9k_hw_ani_cck_err_trigger_old(ah); - return; - } - aniState = &ah->curchan->ani; if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); } -static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) -{ - struct ar5416AniState *aniState; - int32_t rssi; - - aniState = &ah->curchan->ani; - - if (ah->opmode != NL80211_IFTYPE_STATION) { - if (aniState->firstepLevel > 0) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel - 1)) - return; - } - } else { - rssi = BEACON_RSSI(ah); - if (rssi > aniState->rssiThrHigh) { - /* XXX: Handle me */ - } else if (rssi > aniState->rssiThrLow) { - if (!aniState->ofdmWeakSigDetect) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - true)) - return; - } - if (aniState->firstepLevel > 0) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel - 1)) - return; - } - } else { - if (aniState->firstepLevel > 0) { - if (ath9k_hw_ani_control(ah, - ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel - 1)) - return; - } - } - } - - if (aniState->spurImmunityLevel > 0) { - if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, - aniState->spurImmunityLevel - 1)) - return; - } - - if (aniState->noiseImmunityLevel > 0) { - ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, - aniState->noiseImmunityLevel - 1); - return; - } -} - /* * only lower either OFDM or CCK errors per turn * we lower the other one next time @@ -445,11 +268,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) aniState = &ah->curchan->ani; - if (!use_new_ani(ah)) { - ath9k_hw_ani_lower_immunity_old(ah); - return; - } - /* lower OFDM noise immunity */ if (aniState->ofdmNoiseImmunityLevel > 0 && (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) { @@ -462,71 +280,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); } -static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) -{ - struct ar5416AniState *aniState; - struct ath9k_channel *chan = ah->curchan; - struct ath_common *common = ath9k_hw_common(ah); - - if (!DO_ANI(ah)) - return; - - aniState = &ah->curchan->ani; - - if (ah->opmode != NL80211_IFTYPE_STATION) { - ath_dbg(common, ANI, "Reset ANI state opmode %u\n", ah->opmode); - ah->stats.ast_ani_reset++; - - if (ah->opmode == NL80211_IFTYPE_AP) { - /* - * ath9k_hw_ani_control() will only process items set on - * ah->ani_function - */ - if (IS_CHAN_2GHZ(chan)) - ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | - ATH9K_ANI_FIRSTEP_LEVEL); - else - ah->ani_function = 0; - } - - ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); - ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); - ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - !ATH9K_ANI_USE_OFDM_WEAK_SIG); - ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, - ATH9K_ANI_CCK_WEAK_SIG_THR); - - ath9k_ani_restart(ah); - return; - } - - if (aniState->noiseImmunityLevel != 0) - ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, - aniState->noiseImmunityLevel); - if (aniState->spurImmunityLevel != 0) - ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, - aniState->spurImmunityLevel); - if (!aniState->ofdmWeakSigDetect) - ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - aniState->ofdmWeakSigDetect); - if (aniState->cckWeakSigThreshold) - ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, - aniState->cckWeakSigThreshold); - if (aniState->firstepLevel != 0) - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel); - - ath9k_ani_restart(ah); - - ENABLE_REGWRITE_BUFFER(ah); - - REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); - REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); - - REGWRITE_BUFFER_FLUSH(ah); -} - /* * Restore the ANI parameters in the HAL and reset the statistics. * This routine should be called for every hardware reset and for @@ -541,9 +294,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) if (!DO_ANI(ah)) return; - if (!use_new_ani(ah)) - return ath9k_ani_reset_old(ah, is_scanning); - BUG_ON(aniState == NULL); ah->stats.ast_ani_reset++; @@ -640,11 +390,6 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) return false; } - if (!use_new_ani(ah)) { - ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; - cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; - } - aniState->listenTime += listenTime; ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -652,26 +397,6 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { - if (phyCnt1 < ofdm_base) { - ath_dbg(common, ANI, - "phyCnt1 0x%x, resetting counter value to 0x%x\n", - phyCnt1, ofdm_base); - REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); - REG_WRITE(ah, AR_PHY_ERR_MASK_1, - AR_PHY_ERR_OFDM_TIMING); - } - if (phyCnt2 < cck_base) { - ath_dbg(common, ANI, - "phyCnt2 0x%x, resetting counter value to 0x%x\n", - phyCnt2, cck_base); - REG_WRITE(ah, AR_PHY_ERR_2, cck_base); - REG_WRITE(ah, AR_PHY_ERR_MASK_2, - AR_PHY_ERR_CCK_TIMING); - } - return false; - } - ofdmPhyErrCnt = phyCnt1 - ofdm_base; ah->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; @@ -810,9 +535,6 @@ void ath9k_hw_proc_mib_event(struct ath_hw *ah) if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { - if (!use_new_ani(ah)) - ath9k_hw_ani_read_counters(ah); - /* NB: always restart to insure the h/w counters are reset */ ath9k_ani_restart(ah); } @@ -843,45 +565,28 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath_dbg(common, ANI, "Initialize ANI\n"); - if (use_new_ani(ah)) { - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW; - - ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW; - ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW; - } else { - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD; + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW; - ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; - ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; - } + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW; for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { struct ath9k_channel *chan = &ah->channels[i]; struct ar5416AniState *ani = &chan->ani; - if (use_new_ani(ah)) { - ani->spurImmunityLevel = - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + ani->spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; - ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; - if (AR_SREV_9300_20_OR_LATER(ah)) - ani->mrcCCKOff = - !ATH9K_ANI_ENABLE_MRC_CCK; - else - ani->mrcCCKOff = true; - - ani->ofdmsTurn = true; - } else { - ani->spurImmunityLevel = - ATH9K_ANI_SPUR_IMMUNE_LVL_OLD; - ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; - - ani->cckWeakSigThreshold = - ATH9K_ANI_CCK_WEAK_SIG_THR; - } + if (AR_SREV_9300_20_OR_LATER(ah)) + ani->mrcCCKOff = + !ATH9K_ANI_ENABLE_MRC_CCK; + else + ani->mrcCCKOff = true; + + ani->ofdmsTurn = true; ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; @@ -895,13 +600,8 @@ void ath9k_hw_ani_init(struct ath_hw *ah) * since we expect some ongoing maintenance on the tables, let's sanity * check here default level should not modify INI setting. */ - if (use_new_ani(ah)) { - ah->aniperiod = ATH9K_ANI_PERIOD_NEW; - ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; - } else { - ah->aniperiod = ATH9K_ANI_PERIOD_OLD; - ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; - } + ah->aniperiod = ATH9K_ANI_PERIOD_NEW; + ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index d2fb78b4318f..736747cb38c0 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -995,141 +995,6 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah, return pll; } -static bool ar5008_hw_ani_control_old(struct ath_hw *ah, - enum ath9k_ani_cmd cmd, - int param) -{ - struct ar5416AniState *aniState = &ah->curchan->ani; - struct ath_common *common = ath9k_hw_common(ah); - - switch (cmd & ah->ani_function) { - case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ - u32 level = param; - - if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { - ath_dbg(common, ANI, "level out of range (%u > %zu)\n", - level, ARRAY_SIZE(ah->totalSizeDesired)); - return false; - } - - REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, - AR_PHY_DESIRED_SZ_TOT_DES, - ah->totalSizeDesired[level]); - REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, - AR_PHY_AGC_CTL1_COARSE_LOW, - ah->coarse_low[level]); - REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, - AR_PHY_AGC_CTL1_COARSE_HIGH, - ah->coarse_high[level]); - REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, - AR_PHY_FIND_SIG_FIRPWR, - ah->firpwr[level]); - - if (level > aniState->noiseImmunityLevel) - ah->stats.ast_ani_niup++; - else if (level < aniState->noiseImmunityLevel) - ah->stats.ast_ani_nidown++; - aniState->noiseImmunityLevel = level; - break; - } - case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ - u32 on = param ? 1 : 0; - - if (on) - REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, - AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - else - REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, - AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - - if (on != aniState->ofdmWeakSigDetect) { - if (on) - ah->stats.ast_ani_ofdmon++; - else - ah->stats.ast_ani_ofdmoff++; - aniState->ofdmWeakSigDetect = on; - } - break; - } - case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ - static const int weakSigThrCck[] = { 8, 6 }; - u32 high = param ? 1 : 0; - - REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, - AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, - weakSigThrCck[high]); - if (high != aniState->cckWeakSigThreshold) { - if (high) - ah->stats.ast_ani_cckhigh++; - else - ah->stats.ast_ani_ccklow++; - aniState->cckWeakSigThreshold = high; - } - break; - } - case ATH9K_ANI_FIRSTEP_LEVEL:{ - static const int firstep[] = { 0, 4, 8 }; - u32 level = param; - - if (level >= ARRAY_SIZE(firstep)) { - ath_dbg(common, ANI, "level out of range (%u > %zu)\n", - level, ARRAY_SIZE(firstep)); - return false; - } - REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, - AR_PHY_FIND_SIG_FIRSTEP, - firstep[level]); - if (level > aniState->firstepLevel) - ah->stats.ast_ani_stepup++; - else if (level < aniState->firstepLevel) - ah->stats.ast_ani_stepdown++; - aniState->firstepLevel = level; - break; - } - case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ - static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; - u32 level = param; - - if (level >= ARRAY_SIZE(cycpwrThr1)) { - ath_dbg(common, ANI, "level out of range (%u > %zu)\n", - level, ARRAY_SIZE(cycpwrThr1)); - return false; - } - REG_RMW_FIELD(ah, AR_PHY_TIMING5, - AR_PHY_TIMING5_CYCPWR_THR1, - cycpwrThr1[level]); - if (level > aniState->spurImmunityLevel) - ah->stats.ast_ani_spurup++; - else if (level < aniState->spurImmunityLevel) - ah->stats.ast_ani_spurdown++; - aniState->spurImmunityLevel = level; - break; - } - case ATH9K_ANI_PRESENT: - break; - default: - ath_dbg(common, ANI, "invalid cmd %u\n", cmd); - return false; - } - - ath_dbg(common, ANI, "ANI parameters:\n"); - ath_dbg(common, ANI, - "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetect=%d\n", - aniState->noiseImmunityLevel, - aniState->spurImmunityLevel, - aniState->ofdmWeakSigDetect); - ath_dbg(common, ANI, - "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n", - aniState->cckWeakSigThreshold, - aniState->firstepLevel, - aniState->listenTime); - ath_dbg(common, ANI, "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", - aniState->ofdmPhyErrCount, - aniState->cckPhyErrCount); - - return true; -} - static bool ar5008_hw_ani_control_new(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) @@ -1545,11 +1410,8 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->do_getnf = ar5008_hw_do_getnf; priv_ops->set_radar_params = ar5008_hw_set_radar_params; - if (modparam_force_new_ani) { - priv_ops->ani_control = ar5008_hw_ani_control_new; - priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs; - } else - priv_ops->ani_control = ar5008_hw_ani_control_old; + priv_ops->ani_control = ar5008_hw_ani_control_new; + priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs; if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index d9a69fc470cd..edf21ea4fe93 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -21,10 +21,6 @@ #include "ar9002_initvals.h" #include "ar9002_phy.h" -int modparam_force_new_ani; -module_param_named(force_new_ani, modparam_force_new_ani, int, 0444); -MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002"); - /* General hardware code for the A5008/AR9001/AR9002 hadware families */ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 03d590924c64..111a046b44c6 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1019,14 +1019,7 @@ void ar9002_hw_attach_ops(struct ath_hw *ah); void ar9003_hw_attach_ops(struct ath_hw *ah); void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); -/* - * ANI work can be shared between all families but a next - * generation implementation of ANI will be used only for AR9003 only - * for now as the other families still need to be tested with the same - * next generation ANI. Feel free to start testing it though for the - * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. - */ -extern int modparam_force_new_ani; + void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); -- GitLab From 465dce62cdb35f49bc0e859fb23787e1229b62a3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:24 +0200 Subject: [PATCH 2217/6849] ath9k_hw: clean up defines and variables from the ANI implementation split Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 42 ++++++++------------- drivers/net/wireless/ath/ath9k/ani.h | 24 ++++-------- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 20 +++++----- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 20 +++++----- 4 files changed, 43 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 175c3f5590e9..7d5367676d4e 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -117,8 +117,6 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah, static void ath9k_ani_restart(struct ath_hw *ah) { struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); - u32 ofdm_base = 0, cck_base = 0; if (!DO_ANI(ah)) return; @@ -126,13 +124,10 @@ static void ath9k_ani_restart(struct ath_hw *ah) aniState = &ah->curchan->ani; aniState->listenTime = 0; - ath_dbg(common, ANI, "Writing ofdmbase=%u cckbase=%u\n", - ofdm_base, cck_base); - ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); - REG_WRITE(ah, AR_PHY_ERR_2, cck_base); + REG_WRITE(ah, AR_PHY_ERR_1, 0); + REG_WRITE(ah, AR_PHY_ERR_2, 0); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); @@ -375,9 +370,6 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); struct ar5416AniState *aniState = &ah->curchan->ani; - u32 ofdm_base = 0; - u32 cck_base = 0; - u32 ofdmPhyErrCnt, cckPhyErrCnt; u32 phyCnt1, phyCnt2; int32_t listenTime; @@ -397,15 +389,12 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - ofdmPhyErrCnt = phyCnt1 - ofdm_base; - ah->stats.ast_ani_ofdmerrs += - ofdmPhyErrCnt - aniState->ofdmPhyErrCount; - aniState->ofdmPhyErrCount = ofdmPhyErrCnt; + ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount; + aniState->ofdmPhyErrCount = phyCnt1; + + ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount; + aniState->cckPhyErrCount = phyCnt2; - cckPhyErrCnt = phyCnt2 - cck_base; - ah->stats.ast_ani_cckerrs += - cckPhyErrCnt - aniState->cckPhyErrCount; - aniState->cckPhyErrCount = cckPhyErrCnt; return true; } @@ -565,20 +554,19 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath_dbg(common, ANI, "Initialize ANI\n"); - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW; + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; - ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW; - ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW; + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { struct ath9k_channel *chan = &ah->channels[i]; struct ar5416AniState *ani = &chan->ani; - ani->spurImmunityLevel = - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; if (AR_SREV_9300_20_OR_LATER(ah)) ani->mrcCCKOff = @@ -600,8 +588,8 @@ void ath9k_hw_ani_init(struct ath_hw *ah) * since we expect some ongoing maintenance on the tables, let's sanity * check here default level should not modify INI setting. */ - ah->aniperiod = ATH9K_ANI_PERIOD_NEW; - ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; + ah->aniperiod = ATH9K_ANI_PERIOD; + ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL; if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 2ed848fdf08b..79c85fc6c32c 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -24,42 +24,34 @@ #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) /* units are errors per second */ -#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500 -#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 3500 +#define ATH9K_ANI_OFDM_TRIG_HIGH 3500 #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000 /* units are errors per second */ -#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200 -#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400 +#define ATH9K_ANI_OFDM_TRIG_LOW 400 #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900 /* units are errors per second */ -#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200 -#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600 +#define ATH9K_ANI_CCK_TRIG_HIGH 600 /* units are errors per second */ -#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100 -#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300 +#define ATH9K_ANI_CCK_TRIG_LOW 300 #define ATH9K_ANI_NOISE_IMMUNE_LVL 4 #define ATH9K_ANI_USE_OFDM_WEAK_SIG true #define ATH9K_ANI_CCK_WEAK_SIG_THR false -#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD 7 -#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3 +#define ATH9K_ANI_SPUR_IMMUNE_LVL 3 -#define ATH9K_ANI_FIRSTEP_LVL_OLD 0 -#define ATH9K_ANI_FIRSTEP_LVL_NEW 2 +#define ATH9K_ANI_FIRSTEP_LVL 2 #define ATH9K_ANI_RSSI_THR_HIGH 40 #define ATH9K_ANI_RSSI_THR_LOW 7 -#define ATH9K_ANI_PERIOD_OLD 100 -#define ATH9K_ANI_PERIOD_NEW 300 +#define ATH9K_ANI_PERIOD 300 /* in ms */ -#define ATH9K_ANI_POLLINTERVAL_OLD 100 -#define ATH9K_ANI_POLLINTERVAL_NEW 1000 +#define ATH9K_ANI_POLLINTERVAL 1000 #define HAL_NOISE_IMMUNE_MAX 4 #define HAL_SPUR_IMMUNE_MAX 7 diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 736747cb38c0..b6efcd9b3129 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1101,7 +1101,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL] + aniState->iniDef.firstep; if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) value = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -1116,7 +1116,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value2 = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL] + aniState->iniDef.firstepLow; if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -1132,7 +1132,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL_NEW, + ATH9K_ANI_FIRSTEP_LVL, value, aniState->iniDef.firstep); ath_dbg(common, ANI, @@ -1140,7 +1140,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL_NEW, + ATH9K_ANI_FIRSTEP_LVL, value2, aniState->iniDef.firstepLow); if (level > aniState->firstepLevel) @@ -1165,7 +1165,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + aniState->iniDef.cycpwrThr1; if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -1181,7 +1181,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value2 = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + aniState->iniDef.cycpwrThr1Ext; if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -1196,7 +1196,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + ATH9K_ANI_SPUR_IMMUNE_LVL, value, aniState->iniDef.cycpwrThr1); ath_dbg(common, ANI, @@ -1204,7 +1204,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + ATH9K_ANI_SPUR_IMMUNE_LVL, value2, aniState->iniDef.cycpwrThr1Ext); if (level > aniState->spurImmunityLevel) @@ -1319,8 +1319,8 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) AR_PHY_EXT_TIMING5_CYCPWR_THR1); /* these levels just got reset to defaults by the INI */ - aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; - aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; + aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = true; /* not available on pre AR9003 */ } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index bb186d084eb8..ec8a8d5c6db5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -855,7 +855,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL] + aniState->iniDef.firstep; if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) value = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -870,7 +870,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value2 = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL] + aniState->iniDef.firstepLow; if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -886,7 +886,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL_NEW, + ATH9K_ANI_FIRSTEP_LVL, value, aniState->iniDef.firstep); ath_dbg(common, ANI, @@ -894,7 +894,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL_NEW, + ATH9K_ANI_FIRSTEP_LVL, value2, aniState->iniDef.firstepLow); if (level > aniState->firstepLevel) @@ -919,7 +919,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + aniState->iniDef.cycpwrThr1; if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -935,7 +935,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value2 = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + aniState->iniDef.cycpwrThr1Ext; if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -950,7 +950,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + ATH9K_ANI_SPUR_IMMUNE_LVL, value, aniState->iniDef.cycpwrThr1); ath_dbg(common, ANI, @@ -958,7 +958,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + ATH9K_ANI_SPUR_IMMUNE_LVL, value2, aniState->iniDef.cycpwrThr1Ext); if (level > aniState->spurImmunityLevel) @@ -1111,8 +1111,8 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) AR_PHY_EXT_CYCPWR_THR1); /* these levels just got reset to defaults by the INI */ - aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; - aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; + aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; } -- GitLab From 198823fd002a7f9784648c24c72b7e8c9e73fd14 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:25 +0200 Subject: [PATCH 2218/6849] ath9k: remove MIB interrupt support The new ANI implementation does not need it Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 40 -------------------------- drivers/net/wireless/ath/ath9k/debug.c | 2 -- drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 26 ++--------------- 4 files changed, 2 insertions(+), 67 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 7d5367676d4e..da73fa2a77d6 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -490,46 +490,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); -/* - * Process a MIB interrupt. We may potentially be invoked because - * any of the MIB counters overflow/trigger so don't assume we're - * here because a PHY error counter triggered. - */ -void ath9k_hw_proc_mib_event(struct ath_hw *ah) -{ - u32 phyCnt1, phyCnt2; - - /* Reset these counters regardless */ - REG_WRITE(ah, AR_FILT_OFDM, 0); - REG_WRITE(ah, AR_FILT_CCK, 0); - if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) - REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); - - /* Clear the mib counters and save them in the stats */ - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - if (!DO_ANI(ah)) { - /* - * We must always clear the interrupt cause by - * resetting the phy error regs. - */ - REG_WRITE(ah, AR_PHY_ERR_1, 0); - REG_WRITE(ah, AR_PHY_ERR_2, 0); - return; - } - - /* NB: these are not reset-on-read */ - phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); - phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || - ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { - - /* NB: always restart to insure the h/w counters are reset */ - ath9k_ani_restart(ah); - } -} -EXPORT_SYMBOL(ath9k_hw_proc_mib_event); - void ath9k_hw_ani_setup(struct ath_hw *ah) { int i; diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 2831258d9507..5c3192ffc196 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -348,8 +348,6 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) sc->debug.stats.istats.txok++; if (status & ATH9K_INT_TXURN) sc->debug.stats.istats.txurn++; - if (status & ATH9K_INT_MIB) - sc->debug.stats.istats.mib++; if (status & ATH9K_INT_RXPHY) sc->debug.stats.istats.rxphyerr++; if (status & ATH9K_INT_RXKCM) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 111a046b44c6..b49e4b48f459 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1021,7 +1021,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah); void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); -void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 52561b341d68..85f9ab4fa26e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -516,24 +516,6 @@ irqreturn_t ath_isr(int irq, void *dev) ath9k_hw_set_interrupts(ah); } - if (status & ATH9K_INT_MIB) { - /* - * Disable interrupts until we service the MIB - * interrupt; otherwise it will continue to - * fire. - */ - ath9k_hw_disable_interrupts(ah); - /* - * Let the hal handle the event. We assume - * it will clear whatever condition caused - * the interrupt. - */ - spin_lock(&common->cc_lock); - ath9k_hw_proc_mib_event(ah); - spin_unlock(&common->cc_lock); - ath9k_hw_enable_interrupts(ah); - } - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) if (status & ATH9K_INT_TIM_TIMER) { if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle)) @@ -959,14 +941,10 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, /* * Enable MIB interrupts when there are hardware phy counters. */ - if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) { - if (ah->config.enable_ani) - ah->imask |= ATH9K_INT_MIB; + if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) ah->imask |= ATH9K_INT_TSFOOR; - } else { - ah->imask &= ~ATH9K_INT_MIB; + else ah->imask &= ~ATH9K_INT_TSFOOR; - } ath9k_hw_set_interrupts(ah); -- GitLab From 1e8f0a317b5774b2856cd8824991324efb353963 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:26 +0200 Subject: [PATCH 2219/6849] ath9k_hw: fix setting lower noise immunity values Commit af1e8a6f "ath9k: reset noiseimmunity level to default" was supposed to ensure that the default noise immunity level is above the INI values, however it prevents setting lower noise immunity values altogether. Fix this by moving the checks to the right function. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index da73fa2a77d6..6ee0875df469 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -154,9 +154,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) aniState->rssiThrLow, aniState->rssiThrHigh); if (aniState->update_ani) - aniState->ofdmNoiseImmunityLevel = - (immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ? - immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL; + aniState->ofdmNoiseImmunityLevel = immunityLevel; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; @@ -217,9 +215,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; if (aniState->update_ani) - aniState->cckNoiseImmunityLevel = - (immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ? - immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL; + aniState->cckNoiseImmunityLevel = immunityLevel; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; @@ -285,6 +281,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) struct ar5416AniState *aniState = &ah->curchan->ani; struct ath9k_channel *chan = ah->curchan; struct ath_common *common = ath9k_hw_common(ah); + int ofdm_nil, cck_nil; if (!DO_ANI(ah)) return; @@ -306,6 +303,11 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) /* always allow mode (on/off) to be controlled */ ah->ani_function |= ATH9K_ANI_MODE; + ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL, + aniState->ofdmNoiseImmunityLevel); + cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL, + aniState->cckNoiseImmunityLevel); + if (is_scanning || (ah->opmode != NL80211_IFTYPE_STATION && ah->opmode != NL80211_IFTYPE_ADHOC)) { @@ -329,8 +331,8 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->cckNoiseImmunityLevel); aniState->update_ani = false; - ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL); - ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL); + ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL; + cck_nil = ATH9K_ANI_CCK_DEF_LEVEL; } } else { /* @@ -346,11 +348,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->cckNoiseImmunityLevel); aniState->update_ani = true; - ath9k_hw_set_ofdm_nil(ah, - aniState->ofdmNoiseImmunityLevel); - ath9k_hw_set_cck_nil(ah, - aniState->cckNoiseImmunityLevel); } + ath9k_hw_set_ofdm_nil(ah, ofdm_nil); + ath9k_hw_set_cck_nil(ah, cck_nil); /* * enable phy counters if hw supports or if not, enable phy -- GitLab From 058a6385cb876d4b1b97610ee4e73a845e7bea71 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 15:25:27 +0200 Subject: [PATCH 2220/6849] ath9k_hw: clean up ANI OFDM trigger handling Adjust ah->config.ofdm_trig_{high,low} when setting noise immunity values to simplify threshold checks in ath9k_hw_ani_monitor Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 6ee0875df469..a90aa0b4c8f1 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -179,6 +179,14 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, entry_ofdm->ofdm_weak_signal_on); + + if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI; + } else { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; + } } static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) @@ -428,21 +436,10 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) if (aniState->listenTime > ah->aniperiod) { if (cckPhyErrRate < ah->config.cck_trig_low && - ((ofdmPhyErrRate < ah->config.ofdm_trig_low && - aniState->ofdmNoiseImmunityLevel < - ATH9K_ANI_OFDM_DEF_LEVEL) || - (ofdmPhyErrRate < ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI && - aniState->ofdmNoiseImmunityLevel >= - ATH9K_ANI_OFDM_DEF_LEVEL))) { + ofdmPhyErrRate < ah->config.ofdm_trig_low) { ath9k_hw_ani_lower_immunity(ah); aniState->ofdmsTurn = !aniState->ofdmsTurn; - } else if ((ofdmPhyErrRate > ah->config.ofdm_trig_high && - aniState->ofdmNoiseImmunityLevel >= - ATH9K_ANI_OFDM_DEF_LEVEL) || - (ofdmPhyErrRate > - ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI && - aniState->ofdmNoiseImmunityLevel < - ATH9K_ANI_OFDM_DEF_LEVEL)) { + } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) { ath9k_hw_ani_ofdm_err_trigger(ah); aniState->ofdmsTurn = false; } else if (cckPhyErrRate > ah->config.cck_trig_high) { -- GitLab From 29a6b508569cc1d04884d3140ccb5973dd7d91fa Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Fri, 15 Jun 2012 17:27:05 +0200 Subject: [PATCH 2221/6849] wireless: rtl818x: rtl8180 add devices ids from windows driver: 0x1186, 0x3301 D-Link Air DWL-510 Wireless PCI Adapter 0x1432, 0x7106 LevelOne WPC-0101 11Mbps Wireless PCMCIA CardBus Adapter Signed-off-by: Xose Vazquez Perez Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180/dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 2bebcb71a1e9..3b505395d869 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -47,6 +47,8 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = { { PCI_DEVICE(0x1799, 0x6001) }, { PCI_DEVICE(0x1799, 0x6020) }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) }, + { PCI_DEVICE(0x1186, 0x3301) }, + { PCI_DEVICE(0x1432, 0x7106) }, { } }; -- GitLab From 0abd79e5a87319f0710c8db2ef2a2c5c6479c32b Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 12:21:51 -0700 Subject: [PATCH 2222/6849] mwifiex: set channel via start_ap handler for AP interface This patch adds functionality to set channel info received from cfg80211_ap_settings in start_ap handler. Since set_channel cfg80211 handler has been removed and we need not explicitely call mwifiex_uap_set_channel(); hence this function definition is also removed. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 23 ++++++++++++++----- drivers/net/wireless/mwifiex/main.h | 1 - drivers/net/wireless/mwifiex/uap_cmd.c | 30 ------------------------- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 015fec3371a0..7b4eaf41bfc0 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -384,13 +384,13 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, cfp.freq = chan->center_freq; cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); - if (mwifiex_bss_set_channel(priv, &cfp)) - return -EFAULT; - - if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) + if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { + if (mwifiex_bss_set_channel(priv, &cfp)) + return -EFAULT; return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); - else - return mwifiex_uap_set_channel(priv, cfp.channel); + } + + return 0; } /* @@ -961,6 +961,17 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, return -EINVAL; } + bss_cfg->channel = + (u8)ieee80211_frequency_to_channel(params->channel->center_freq); + bss_cfg->band_cfg = BAND_CONFIG_MANUAL; + + if (mwifiex_set_rf_channel(priv, params->channel, + params->channel_type)) { + kfree(bss_cfg); + wiphy_err(wiphy, "Failed to set band config information!\n"); + return -1; + } + if (mwifiex_set_secure_params(priv, bss_cfg, params)) { kfree(bss_cfg); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 5b32221077c4..512481ea664e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -990,7 +990,6 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, int mwifiex_main_process(struct mwifiex_adapter *); -int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel); int mwifiex_bss_set_channel(struct mwifiex_private *, struct mwifiex_chan_freq_power *cfp); int mwifiex_get_bss_info(struct mwifiex_private *, diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 89f9a2a45de3..fb0c6cbfc277 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -421,33 +421,3 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, return 0; } - -/* This function sets the RF channel for AP. - * - * This function populates channel information in AP config structure - * and sends command to configure channel information in AP. - */ -int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) -{ - struct mwifiex_uap_bss_param *bss_cfg; - struct wiphy *wiphy = priv->wdev->wiphy; - - bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); - if (!bss_cfg) - return -ENOMEM; - - mwifiex_set_sys_config_invalid_data(bss_cfg); - bss_cfg->band_cfg = BAND_CONFIG_MANUAL; - bss_cfg->channel = channel; - - if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, - HostCmd_ACT_GEN_SET, - UAP_BSS_PARAMS_I, bss_cfg)) { - wiphy_err(wiphy, "Failed to set the uAP channel\n"); - kfree(bss_cfg); - return -1; - } - - kfree(bss_cfg); - return 0; -} -- GitLab From 5a05fae5ca7cd5279567747fc34d60413b504cd6 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 20 Jun 2012 20:50:31 +0200 Subject: [PATCH 2223/6849] netfilter: nfq_ct_hook needs __rcu and __read_mostly This removes some sparse warnings. Reported-by: Fengguang Wu Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter.h | 2 +- net/netfilter/core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index dca19e61b30a..38b96a54f9a5 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -404,7 +404,7 @@ struct nfq_ct_hook { void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, u32 ctinfo, int off); }; -extern struct nfq_ct_hook *nfq_ct_hook; +extern struct nfq_ct_hook __rcu *nfq_ct_hook; #else static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} #endif diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 7eef8453b909..4cd10ed2d6e6 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -265,7 +265,7 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct) } EXPORT_SYMBOL(nf_conntrack_destroy); -struct nfq_ct_hook *nfq_ct_hook; +struct nfq_ct_hook __rcu *nfq_ct_hook __read_mostly; EXPORT_SYMBOL_GPL(nfq_ct_hook); #endif /* CONFIG_NF_CONNTRACK */ -- GitLab From 3dca938656c7b0ff6b0717a5dde0f5f45e592be5 Mon Sep 17 00:00:00 2001 From: Jose Miguel Goncalves Date: Sat, 12 May 2012 06:11:49 +0900 Subject: [PATCH 2224/6849] ARM: SAMSUNG: Fix for S3C2412 EBI memory mapping While upgrading the kernel on a S3C2412 based board I've noted that it was impossible to boot the board with a 2.6.32 or upper kernel. I've tracked down the problem to the EBI virtual memory mapping that is in conflict with the IO mapping definition in arch/arm/mach-s3c24xx/s3c2412.c. Signed-off-by: Jose Miguel Goncalves Cc: Stable Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/map-s3c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/plat-samsung/include/plat/map-s3c.h b/arch/arm/plat-samsung/include/plat/map-s3c.h index 7d048759b772..c0c70a895ca8 100644 --- a/arch/arm/plat-samsung/include/plat/map-s3c.h +++ b/arch/arm/plat-samsung/include/plat/map-s3c.h @@ -22,7 +22,7 @@ #define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG #define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) -#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000) +#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00100000) #define S3C2410_PA_UART (0x50000000) #define S3C24XX_PA_UART S3C2410_PA_UART -- GitLab From b7019b2f31fe7bec9f6f5dc1bf54cb0e0d73e047 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 15:58:25 -0400 Subject: [PATCH 2225/6849] drm/radeon: SI tiling fixes for display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use the correct union for getting the tiling info - Properly init the PIPE_CONFIG field for SI Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 10 +++- drivers/gpu/drm/radeon/si_reg.h | 72 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 01d77d1554f4..3904d7964a4b 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1149,7 +1149,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_CAYMAN) + if (rdev->family >= CHIP_TAHITI) + tmp = rdev->config.si.tile_config; + else if (rdev->family >= CHIP_CAYMAN) tmp = rdev->config.cayman.tile_config; else tmp = rdev->config.evergreen.tile_config; @@ -1177,6 +1179,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } else if (tiling_flags & RADEON_TILING_MICRO) fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + if ((rdev->family == CHIP_TAHITI) || + (rdev->family == CHIP_PITCAIRN)) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); + else if (rdev->family == CHIP_VERDE) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); + switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/si_reg.h b/drivers/gpu/drm/radeon/si_reg.h index eda938a7cb6e..501f9d431d57 100644 --- a/drivers/gpu/drm/radeon/si_reg.h +++ b/drivers/gpu/drm/radeon/si_reg.h @@ -30,4 +30,76 @@ #define SI_DC_GPIO_HPD_EN 0x65b8 #define SI_DC_GPIO_HPD_Y 0x65bc +#define SI_GRPH_CONTROL 0x6804 +# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0) +# define SI_GRPH_DEPTH_8BPP 0 +# define SI_GRPH_DEPTH_16BPP 1 +# define SI_GRPH_DEPTH_32BPP 2 +# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) +# define SI_ADDR_SURF_2_BANK 0 +# define SI_ADDR_SURF_4_BANK 1 +# define SI_ADDR_SURF_8_BANK 2 +# define SI_ADDR_SURF_16_BANK 3 +# define SI_GRPH_Z(x) (((x) & 0x3) << 4) +# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) +# define SI_ADDR_SURF_BANK_WIDTH_1 0 +# define SI_ADDR_SURF_BANK_WIDTH_2 1 +# define SI_ADDR_SURF_BANK_WIDTH_4 2 +# define SI_ADDR_SURF_BANK_WIDTH_8 3 +# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8) +/* 8 BPP */ +# define SI_GRPH_FORMAT_INDEXED 0 +/* 16 BPP */ +# define SI_GRPH_FORMAT_ARGB1555 0 +# define SI_GRPH_FORMAT_ARGB565 1 +# define SI_GRPH_FORMAT_ARGB4444 2 +# define SI_GRPH_FORMAT_AI88 3 +# define SI_GRPH_FORMAT_MONO16 4 +# define SI_GRPH_FORMAT_BGRA5551 5 +/* 32 BPP */ +# define SI_GRPH_FORMAT_ARGB8888 0 +# define SI_GRPH_FORMAT_ARGB2101010 1 +# define SI_GRPH_FORMAT_32BPP_DIG 2 +# define SI_GRPH_FORMAT_8B_ARGB2101010 3 +# define SI_GRPH_FORMAT_BGRA1010102 4 +# define SI_GRPH_FORMAT_8B_BGRA1010102 5 +# define SI_GRPH_FORMAT_RGB111110 6 +# define SI_GRPH_FORMAT_BGR101111 7 +# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) +# define SI_ADDR_SURF_BANK_HEIGHT_1 0 +# define SI_ADDR_SURF_BANK_HEIGHT_2 1 +# define SI_ADDR_SURF_BANK_HEIGHT_4 2 +# define SI_ADDR_SURF_BANK_HEIGHT_8 3 +# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) +# define SI_ADDR_SURF_TILE_SPLIT_64B 0 +# define SI_ADDR_SURF_TILE_SPLIT_128B 1 +# define SI_ADDR_SURF_TILE_SPLIT_256B 2 +# define SI_ADDR_SURF_TILE_SPLIT_512B 3 +# define SI_ADDR_SURF_TILE_SPLIT_1KB 4 +# define SI_ADDR_SURF_TILE_SPLIT_2KB 5 +# define SI_ADDR_SURF_TILE_SPLIT_4KB 6 +# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3 +# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) +# define SI_GRPH_ARRAY_LINEAR_GENERAL 0 +# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1 +# define SI_GRPH_ARRAY_1D_TILED_THIN1 2 +# define SI_GRPH_ARRAY_2D_TILED_THIN1 4 +# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24) +# define SI_ADDR_SURF_P2 0 +# define SI_ADDR_SURF_P4_8x16 4 +# define SI_ADDR_SURF_P4_16x16 5 +# define SI_ADDR_SURF_P4_16x32 6 +# define SI_ADDR_SURF_P4_32x32 7 +# define SI_ADDR_SURF_P8_16x16_8x16 8 +# define SI_ADDR_SURF_P8_16x32_8x16 9 +# define SI_ADDR_SURF_P8_32x32_8x16 10 +# define SI_ADDR_SURF_P8_16x32_16x16 11 +# define SI_ADDR_SURF_P8_32x32_16x16 12 +# define SI_ADDR_SURF_P8_32x32_16x32 13 +# define SI_ADDR_SURF_P8_32x64_32x32 14 + #endif -- GitLab From 2228125600b3031657b825502d1a1999e4c02566 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 12:21:53 -0700 Subject: [PATCH 2226/6849] mwifiex: set HT capability based on cfg80211_ap_settings Parse HT IE from cfg80211 and set HT capabilities accordingly to FW. If HT IE is missing, 11n would be disabled in FW. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 2 ++ drivers/net/wireless/mwifiex/fw.h | 6 ++++ drivers/net/wireless/mwifiex/ioctl.h | 1 + drivers/net/wireless/mwifiex/main.h | 3 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 47 +++++++++++++++++++++++++ 5 files changed, 59 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 7b4eaf41bfc0..5af3f97936e4 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -978,6 +978,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, return -1; } + mwifiex_set_ht_params(priv, bss_cfg, params); + if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "Failed to stop the BSS\n"); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 561452a5c818..9686f6fec19a 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -162,6 +162,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) +#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ + (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ + IEEE80211_HT_CAP_SM_PS) + +#define MWIFIEX_DEF_AMPDU IEEE80211_HT_AMPDU_PARM_FACTOR + /* dev_cap bitmap * BIT * 0-16 reserved diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index e6be6ee75951..8c8e47c792a0 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -90,6 +90,7 @@ struct mwifiex_uap_bss_param { u16 key_mgmt; u16 key_mgmt_operation; struct wpa_param wpa_cfg; + struct ieee80211_ht_cap ht_cap; }; enum { diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 512481ea664e..0b3b5aa9830d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -840,6 +840,9 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv, int mwifiex_set_secure_params(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_config, struct cfg80211_ap_settings *params); +void mwifiex_set_ht_params(struct mwifiex_private *priv, + struct mwifiex_uap_bss_param *bss_cfg, + struct cfg80211_ap_settings *params); /* * This function checks if the queuing is RA based or not. diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index fb0c6cbfc277..59e5ba4df02b 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -118,6 +118,33 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, return 0; } +/* This function updates 11n related parameters from IE and sets them into + * bss_config structure. + */ +void +mwifiex_set_ht_params(struct mwifiex_private *priv, + struct mwifiex_uap_bss_param *bss_cfg, + struct cfg80211_ap_settings *params) +{ + const u8 *ht_ie; + + if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info)) + return; + + ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail, + params->beacon.tail_len); + if (ht_ie) { + memcpy(&bss_cfg->ht_cap, ht_ie + 2, + sizeof(struct ieee80211_ht_cap)); + } else { + memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap)); + bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP); + bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU; + } + + return; +} + /* This function initializes some of mwifiex_uap_bss_param variables. * This helps FW in ignoring invalid values. These values may or may not * be get updated to valid ones at later stage. @@ -154,6 +181,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_auth_type *auth_type; struct host_cmd_tlv_passphrase *passphrase; struct host_cmd_tlv_akmp *tlv_akmp; + struct mwifiex_ie_types_htcap *htcap; struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; u16 cmd_size = *param_size; @@ -330,6 +358,25 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) tlv += sizeof(struct host_cmd_tlv_encrypt_protocol); } + if (bss_cfg->ht_cap.cap_info) { + htcap = (struct mwifiex_ie_types_htcap *)tlv; + htcap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); + htcap->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_cap)); + htcap->ht_cap.cap_info = bss_cfg->ht_cap.cap_info; + htcap->ht_cap.ampdu_params_info = + bss_cfg->ht_cap.ampdu_params_info; + memcpy(&htcap->ht_cap.mcs, &bss_cfg->ht_cap.mcs, + sizeof(struct ieee80211_mcs_info)); + htcap->ht_cap.extended_ht_cap_info = + bss_cfg->ht_cap.extended_ht_cap_info; + htcap->ht_cap.tx_BF_cap_info = bss_cfg->ht_cap.tx_BF_cap_info; + htcap->ht_cap.antenna_selection_info = + bss_cfg->ht_cap.antenna_selection_info; + cmd_size += sizeof(struct mwifiex_ie_types_htcap); + tlv += sizeof(struct mwifiex_ie_types_htcap); + } + *param_size = cmd_size; return 0; -- GitLab From 5d66cb62954106d4abfb67bbb5a14cec57903cbb Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 12:21:54 -0700 Subject: [PATCH 2227/6849] mwifiex: separate uAP WPA/WPA2 parsing from other BSS parameters To enhance readability, create a separate function for parsing WPA/WPA2 related parameters from cfg80211_ap_settings. There is no functional change in this patch. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/uap_cmd.c | 147 +++++++++++++------------ 1 file changed, 79 insertions(+), 68 deletions(-) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 59e5ba4df02b..86a4432df7a8 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -161,6 +161,82 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config) config->retry_limit = 0x7F; } +/* This function parses BSS related parameters from structure + * and prepares TLVs specific to WPA/WPA2 security. + * These TLVs are appended to command buffer. + */ +static void +mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) +{ + struct host_cmd_tlv_pwk_cipher *pwk_cipher; + struct host_cmd_tlv_gwk_cipher *gwk_cipher; + struct host_cmd_tlv_passphrase *passphrase; + struct host_cmd_tlv_akmp *tlv_akmp; + struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; + u16 cmd_size = *param_size; + u8 *tlv = *tlv_buf; + + tlv_akmp = (struct host_cmd_tlv_akmp *)tlv; + tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP); + tlv_akmp->tlv.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) - + sizeof(struct host_cmd_tlv)); + tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation); + tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt); + cmd_size += sizeof(struct host_cmd_tlv_akmp); + tlv += sizeof(struct host_cmd_tlv_akmp); + + if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) { + pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; + pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); + pwk_cipher->tlv.len = + cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) - + sizeof(struct host_cmd_tlv)); + pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA); + pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa; + cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); + tlv += sizeof(struct host_cmd_tlv_pwk_cipher); + } + + if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) { + pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; + pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); + pwk_cipher->tlv.len = + cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) - + sizeof(struct host_cmd_tlv)); + pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2); + pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2; + cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); + tlv += sizeof(struct host_cmd_tlv_pwk_cipher); + } + + if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) { + gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv; + gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER); + gwk_cipher->tlv.len = + cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) - + sizeof(struct host_cmd_tlv)); + gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher; + cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher); + tlv += sizeof(struct host_cmd_tlv_gwk_cipher); + } + + if (bss_cfg->wpa_cfg.length) { + passphrase = (struct host_cmd_tlv_passphrase *)tlv; + passphrase->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE); + passphrase->tlv.len = cpu_to_le16(bss_cfg->wpa_cfg.length); + memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase, + bss_cfg->wpa_cfg.length); + cmd_size += sizeof(struct host_cmd_tlv) + + bss_cfg->wpa_cfg.length; + tlv += sizeof(struct host_cmd_tlv) + bss_cfg->wpa_cfg.length; + } + + *param_size = cmd_size; + *tlv_buf = tlv; + + return; +} + /* This function parses BSS related parameters from structure * and prepares TLVs. These TLVs are appended to command buffer. */ @@ -175,12 +251,8 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_frag_threshold *frag_threshold; struct host_cmd_tlv_rts_threshold *rts_threshold; struct host_cmd_tlv_retry_limit *retry_limit; - struct host_cmd_tlv_pwk_cipher *pwk_cipher; - struct host_cmd_tlv_gwk_cipher *gwk_cipher; struct host_cmd_tlv_encrypt_protocol *encrypt_protocol; struct host_cmd_tlv_auth_type *auth_type; - struct host_cmd_tlv_passphrase *passphrase; - struct host_cmd_tlv_akmp *tlv_akmp; struct mwifiex_ie_types_htcap *htcap; struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; u16 cmd_size = *param_size; @@ -271,70 +343,9 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) } if ((bss_cfg->protocol & PROTOCOL_WPA) || (bss_cfg->protocol & PROTOCOL_WPA2) || - (bss_cfg->protocol & PROTOCOL_EAP)) { - tlv_akmp = (struct host_cmd_tlv_akmp *)tlv; - tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP); - tlv_akmp->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) - - sizeof(struct host_cmd_tlv)); - tlv_akmp->key_mgmt_operation = - cpu_to_le16(bss_cfg->key_mgmt_operation); - tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt); - cmd_size += sizeof(struct host_cmd_tlv_akmp); - tlv += sizeof(struct host_cmd_tlv_akmp); - - if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & - VALID_CIPHER_BITMAP) { - pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; - pwk_cipher->tlv.type = - cpu_to_le16(TLV_TYPE_PWK_CIPHER); - pwk_cipher->tlv.len = cpu_to_le16( - sizeof(struct host_cmd_tlv_pwk_cipher) - - sizeof(struct host_cmd_tlv)); - pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA); - pwk_cipher->cipher = - bss_cfg->wpa_cfg.pairwise_cipher_wpa; - cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); - tlv += sizeof(struct host_cmd_tlv_pwk_cipher); - } - if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & - VALID_CIPHER_BITMAP) { - pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; - pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); - pwk_cipher->tlv.len = cpu_to_le16( - sizeof(struct host_cmd_tlv_pwk_cipher) - - sizeof(struct host_cmd_tlv)); - pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2); - pwk_cipher->cipher = - bss_cfg->wpa_cfg.pairwise_cipher_wpa2; - cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); - tlv += sizeof(struct host_cmd_tlv_pwk_cipher); - } - if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) { - gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv; - gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER); - gwk_cipher->tlv.len = cpu_to_le16( - sizeof(struct host_cmd_tlv_gwk_cipher) - - sizeof(struct host_cmd_tlv)); - gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher; - cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher); - tlv += sizeof(struct host_cmd_tlv_gwk_cipher); - } - if (bss_cfg->wpa_cfg.length) { - passphrase = (struct host_cmd_tlv_passphrase *)tlv; - passphrase->tlv.type = - cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE); - passphrase->tlv.len = - cpu_to_le16(bss_cfg->wpa_cfg.length); - memcpy(passphrase->passphrase, - bss_cfg->wpa_cfg.passphrase, - bss_cfg->wpa_cfg.length); - cmd_size += sizeof(struct host_cmd_tlv) + - bss_cfg->wpa_cfg.length; - tlv += sizeof(struct host_cmd_tlv) + - bss_cfg->wpa_cfg.length; - } - } + (bss_cfg->protocol & PROTOCOL_EAP)) + mwifiex_uap_bss_wpa(&tlv, cmd_buf, &cmd_size); + if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) || (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) { auth_type = (struct host_cmd_tlv_auth_type *)tlv; -- GitLab From 96893538564c43276dffe5e294b56935197cf1c8 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 12:21:55 -0700 Subject: [PATCH 2228/6849] mwifiex: support for WEP in AP mode This patch adds support for WEP open/shared encryption in AP mode. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 30 +++++++++++- drivers/net/wireless/mwifiex/fw.h | 8 ++++ drivers/net/wireless/mwifiex/ioctl.h | 9 ++++ drivers/net/wireless/mwifiex/uap_cmd.c | 62 +++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 5af3f97936e4..9c2e08e4b093 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -170,7 +170,9 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, if (!priv->sec_info.wep_enabled) return 0; - if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { + if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) { + priv->wep_key_curr_index = key_index; + } else if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { wiphy_err(wiphy, "set default Tx key index\n"); return -EFAULT; } @@ -187,9 +189,25 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, struct key_params *params) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); + struct mwifiex_wep_key *wep_key; const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; const u8 *peer_mac = pairwise ? mac_addr : bc_mac; + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP && + (params->cipher == WLAN_CIPHER_SUITE_WEP40 || + params->cipher == WLAN_CIPHER_SUITE_WEP104)) { + if (params->key && params->key_len) { + wep_key = &priv->wep_key[key_index]; + memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); + memcpy(wep_key->key_material, params->key, + params->key_len); + wep_key->key_index = key_index; + wep_key->key_length = params->key_len; + priv->sec_info.wep_enabled = 1; + } + return 0; + } + if (mwifiex_set_encode(priv, params->key, params->key_len, key_index, peer_mac, 0)) { wiphy_err(wiphy, "crypto keys added\n"); @@ -1003,6 +1021,16 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, return -1; } + if (priv->sec_info.wep_enabled) + priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; + else + priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; + + if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter)) + return -1; + return 0; } diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 9686f6fec19a..1184141839ae 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -124,6 +124,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) +#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) #define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65) @@ -1201,6 +1202,13 @@ struct host_cmd_tlv_passphrase { u8 passphrase[0]; } __packed; +struct host_cmd_tlv_wep_key { + struct host_cmd_tlv tlv; + u8 key_index; + u8 is_default; + u8 key[1]; +}; + struct host_cmd_tlv_auth_type { struct host_cmd_tlv tlv; u8 auth_type; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 8c8e47c792a0..9f088fb88cb7 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -21,6 +21,7 @@ #define _MWIFIEX_IOCTL_H_ #include +#include enum { MWIFIEX_SCAN_TYPE_UNCHANGED = 0, @@ -71,6 +72,13 @@ struct wpa_param { u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN]; }; +struct wep_key { + u8 key_index; + u8 is_default; + u16 length; + u8 key[WLAN_KEY_LEN_WEP104]; +}; + #define KEY_MGMT_ON_HOST 0x03 #define MWIFIEX_AUTH_MODE_AUTO 0xFF #define BAND_CONFIG_MANUAL 0x00 @@ -90,6 +98,7 @@ struct mwifiex_uap_bss_param { u16 key_mgmt; u16 key_mgmt_operation; struct wpa_param wpa_cfg; + struct wep_key wep_cfg[NUM_WEP_KEYS]; struct ieee80211_ht_cap ht_cap; }; diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 86a4432df7a8..abb1322a8ceb 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -26,6 +26,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_config, struct cfg80211_ap_settings *params) { int i; + struct mwifiex_wep_key wep_key; if (!params->privacy) { bss_config->protocol = PROTOCOL_NO_SECURITY; @@ -104,6 +105,27 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, switch (params->crypto.cipher_group) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: + if (priv->sec_info.wep_enabled) { + bss_config->protocol = PROTOCOL_STATIC_WEP; + bss_config->key_mgmt = KEY_MGMT_NONE; + bss_config->wpa_cfg.length = 0; + + for (i = 0; i < NUM_WEP_KEYS; i++) { + wep_key = priv->wep_key[i]; + bss_config->wep_cfg[i].key_index = i; + + if (priv->wep_key_curr_index == i) + bss_config->wep_cfg[i].is_default = 1; + else + bss_config->wep_cfg[i].is_default = 0; + + bss_config->wep_cfg[i].length = + wep_key.key_length; + memcpy(&bss_config->wep_cfg[i].key, + &wep_key.key_material, + wep_key.key_length); + } + } break; case WLAN_CIPHER_SUITE_TKIP: bss_config->wpa_cfg.group_cipher = CIPHER_TKIP; @@ -237,6 +259,44 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) return; } +/* This function parses BSS related parameters from structure + * and prepares TLVs specific to WEP encryption. + * These TLVs are appended to command buffer. + */ +static void +mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size) +{ + struct host_cmd_tlv_wep_key *wep_key; + u16 cmd_size = *param_size; + int i; + u8 *tlv = *tlv_buf; + struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; + + for (i = 0; i < NUM_WEP_KEYS; i++) { + if (bss_cfg->wep_cfg[i].length && + (bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 || + bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) { + wep_key = (struct host_cmd_tlv_wep_key *)tlv; + wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY); + wep_key->tlv.len = + cpu_to_le16(bss_cfg->wep_cfg[i].length + 2); + wep_key->key_index = bss_cfg->wep_cfg[i].key_index; + wep_key->is_default = bss_cfg->wep_cfg[i].is_default; + memcpy(wep_key->key, bss_cfg->wep_cfg[i].key, + bss_cfg->wep_cfg[i].length); + cmd_size += sizeof(struct host_cmd_tlv) + 2 + + bss_cfg->wep_cfg[i].length; + tlv += sizeof(struct host_cmd_tlv) + 2 + + bss_cfg->wep_cfg[i].length; + } + } + + *param_size = cmd_size; + *tlv_buf = tlv; + + return; +} + /* This function parses BSS related parameters from structure * and prepares TLVs. These TLVs are appended to command buffer. */ @@ -345,6 +405,8 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) (bss_cfg->protocol & PROTOCOL_WPA2) || (bss_cfg->protocol & PROTOCOL_EAP)) mwifiex_uap_bss_wpa(&tlv, cmd_buf, &cmd_size); + else + mwifiex_uap_bss_wep(&tlv, cmd_buf, &cmd_size); if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) || (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) { -- GitLab From 0bd8b79fe928b88ebaf36f2621f921a2fc09ea9c Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:48 -0500 Subject: [PATCH 2229/6849] brcm80211: smac: don't set up tx power limits during initialization This code is unnecessary, and in fact it's never executed because the interface is never up when brcms_c_channels_commit() is called. Removing it helps simplify the implementation of proper regulatory support. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Brett Rudley Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/channel.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index eb77ac3cfb6b..049d78fce103 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -908,7 +908,6 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) { struct brcms_c_info *wlc = wlc_cm->wlc; uint chan; - struct txpwr_limits txpwr; /* search for the existence of any valid channel */ for (chan = 0; chan < MAXCHANNEL; chan++) { @@ -949,13 +948,6 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, brcms_c_japan(wlc) ? true : false); - - if (wlc->pub->up && chan != INVCHANNEL) { - brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, - &txpwr, BRCMS_TXPWR_MAX); - wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); - } } static int -- GitLab From 91691295527d3fd63f12079222df0fd8048acccb Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:49 -0500 Subject: [PATCH 2230/6849] brcm80211: smac: always set channel specified by mac80211 In some situations brcmsmac is choosing a channel internally. This makes it difficult at times to know what channel to use for enforcing regulatory constraints, so instead always use the channel from the mac80211 configuration. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/main.c | 30 ++++--------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 19db4052c44c..93c865db7729 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -3139,20 +3139,6 @@ void brcms_c_reset(struct brcms_c_info *wlc) brcms_b_reset(wlc->hw); } -/* Return the channel the driver should initialize during brcms_c_init. - * the channel may have to be changed from the currently configured channel - * if other configurations are in conflict (bandlocked, 11n mode disabled, - * invalid channel for current country, etc.) - */ -static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc) -{ - u16 chanspec = - 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | - WL_CHANSPEC_BAND_2G; - - return chanspec; -} - void brcms_c_init_scb(struct scb *scb) { int i; @@ -5129,6 +5115,8 @@ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) /* make interface operational */ int brcms_c_up(struct brcms_c_info *wlc) { + struct ieee80211_channel *ch; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* HW is turned off so don't try to access it */ @@ -5195,8 +5183,9 @@ int brcms_c_up(struct brcms_c_info *wlc) wlc->pub->up = true; if (wlc->bandinit_pending) { + ch = wlc->pub->ieee_hw->conf.channel; brcms_c_suspend_mac_and_wait(wlc); - brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec); + brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value)); wlc->bandinit_pending = false; brcms_c_enable_mac(wlc); } @@ -8201,19 +8190,12 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) { struct bcma_device *core = wlc->hw->d11core; + struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; u16 chanspec; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - /* - * This will happen if a big-hammer was executed. In - * that case, we want to go back to the channel that - * we were on and not new channel - */ - if (wlc->pub->associated) - chanspec = wlc->home_chanspec; - else - chanspec = brcms_c_init_chanspec(wlc); + chanspec = ch20mhz_chspec(ch->hw_value); brcms_b_init(wlc->hw, chanspec); -- GitLab From a3ce5cc1a60fd2e237599d4b9bc247422a7523c2 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:50 -0500 Subject: [PATCH 2231/6849] brcm80211: smac: remove unused code for 40MHz channels This code has been kept around in anticipation of adding support for 40MHz channels, but subsequent patches to better integrate with mac80211 regulatory support will render it completely broken. Therefore we should go ahead and remove it. Keep these changes separate from other cleanup patches in order to make it easier to resurrect 40MHz channel support at some point in the future. Reviewed-by: Arend Van Spriel Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 116 ------------------ 1 file changed, 116 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 049d78fce103..089cc873109a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -512,83 +512,6 @@ static const struct { "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ }; -#ifdef SUPPORT_40MHZ -/* 20MHz channel info for 40MHz pairing support */ -struct chan20_info { - u8 sb; - u8 adj_sbs; -}; - -/* indicates adjacent channels that are allowed for a 40 Mhz channel and - * those that permitted by the HT - */ -struct chan20_info chan20_info[] = { - /* 11b/11g */ -/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 11 */ {12, (CH_LOWER_SB)}, -/* 12 */ {13, (CH_LOWER_SB)}, -/* 13 */ {14, (CH_LOWER_SB)}, - -/* 11a japan high */ -/* 14 */ {34, (CH_UPPER_SB)}, -/* 15 */ {38, (CH_LOWER_SB)}, -/* 16 */ {42, (CH_LOWER_SB)}, -/* 17 */ {46, (CH_LOWER_SB)}, - -/* 11a usa low */ -/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, - -/* 11a Europe */ -/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 36 */ {140, (CH_LOWER_SB)}, - -/* 11a usa high, ref5 only */ -/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ -/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 41 */ {165, (CH_LOWER_SB)}, - -/* 11a japan */ -/* 42 */ {184, (CH_UPPER_SB)}, -/* 43 */ {188, (CH_LOWER_SB)}, -/* 44 */ {192, (CH_UPPER_SB)}, -/* 45 */ {196, (CH_LOWER_SB)}, -/* 46 */ {200, (CH_UPPER_SB)}, -/* 47 */ {204, (CH_LOWER_SB)}, -/* 48 */ {208, (CH_UPPER_SB)}, -/* 49 */ {212, (CH_LOWER_SB)}, -/* 50 */ {216, (CH_LOWER_SB)} -}; -#endif /* SUPPORT_40MHZ */ - static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) @@ -1449,45 +1372,6 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, return brcms_c_valid_channel20(wlc_cm->wlc->cmi, channel); } -#ifdef SUPPORT_40MHZ - /* - * We know we are now checking a 40MHZ channel, so we should - * only be here for NPHYS - */ - if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) { - u8 upper_sideband = 0, idx; - u8 num_ch20_entries = - sizeof(chan20_info) / sizeof(struct chan20_info); - - if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec))) - return false; - - if (dualband) { - if (!brcms_c_valid_channel20_db(wlc->cmi, - lower_20_sb(channel)) || - !brcms_c_valid_channel20_db(wlc->cmi, - upper_20_sb(channel))) - return false; - } else { - if (!brcms_c_valid_channel20(wlc->cmi, - lower_20_sb(channel)) || - !brcms_c_valid_channel20(wlc->cmi, - upper_20_sb(channel))) - return false; - } - - /* find the lower sideband info in the sideband array */ - for (idx = 0; idx < num_ch20_entries; idx++) { - if (chan20_info[idx].sb == lower_20_sb(channel)) - upper_sideband = chan20_info[idx].adj_sbs; - } - /* check that the lower sideband allows an upper sideband */ - if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == - (CH_UPPER_SB | CH_EWA_VALID)) - return true; - return false; - } -#endif /* 40 MHZ */ return false; } -- GitLab From 2810a619ca5716e315090119e5695e97814b1e60 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:51 -0500 Subject: [PATCH 2232/6849] brcm80211: smac: clean up channel.c Much of the code is either unsed or never put to any useful purpose. Remove this code in advance of reworking the driver's regulatory support. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Brett Rudley Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 138 +----------------- 1 file changed, 5 insertions(+), 133 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 089cc873109a..c311ef7e99a7 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -58,18 +58,8 @@ LOCALE_CHAN_12_13 | \ LOCALE_CHAN_14) -#define LOCALE_RADAR_SET_NONE 0 -#define LOCALE_RADAR_SET_1 1 - #define LOCALE_RESTRICTED_NONE 0 #define LOCALE_RESTRICTED_SET_2G_SHORT 1 -#define LOCALE_RESTRICTED_CHAN_165 2 -#define LOCALE_CHAN_ALL_5G 3 -#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 -#define LOCALE_RESTRICTED_11D_2G 5 -#define LOCALE_RESTRICTED_11D_5G 6 -#define LOCALE_RESTRICTED_LOW_HI 7 -#define LOCALE_RESTRICTED_12_13_14 8 #define LOCALE_2G_IDX_i 0 #define LOCALE_5G_IDX_11 0 @@ -118,8 +108,6 @@ (((c) < 100) ? 2 : \ (((c) < 149) ? 3 : 4)))) -#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU) - struct brcms_cm_band { /* struct locale_info flags */ u8 locale_flags; @@ -127,9 +115,6 @@ struct brcms_cm_band { struct brcms_chanvec valid_channels; /* List of restricted use channels */ const struct brcms_chanvec *restricted_channels; - /* List of radar sensitive channels */ - const struct brcms_chanvec *radar_channels; - u8 PAD[8]; }; /* locale per-channel tx power limits for MIMO frames @@ -158,7 +143,6 @@ struct brcms_cm_info { char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */ uint srom_regrev; /* Regulatory Rev for the SROM ccode */ const struct country_info *country; /* current country def */ - char ccode[BRCM_CNTRY_BUF_SZ]; /* current internal Country Code */ uint regrev; /* current Regulatory Revision */ char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */ /* per-band state (one per phy/radio) */ @@ -171,14 +155,10 @@ struct brcms_cm_info { /* locale channel and power info. */ struct locale_info { u32 valid_channels; - /* List of radar sensitive channels */ - u8 radar_channels; /* List of channels used only if APs are detected */ u8 restricted_channels; /* Max tx pwr in qdBm for each sub-band */ s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE]; - /* Country IE advertised max tx pwr in dBm per sub-band */ - s8 pub_maxpwr[BAND_5G_PWR_LVLS]; u8 flags; }; @@ -196,46 +176,10 @@ static const struct brcms_chanvec chanvec_none = { 0x00, 0x00, 0x00, 0x00} }; -/* All 2.4 GHz HW channels */ -static const struct brcms_chanvec chanvec_all_2G = { - {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* All 5 GHz HW channels */ -static const struct brcms_chanvec chanvec_all_5G = { - {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, - 0x11, 0x11, 0x11, 0x01} -}; - -/* - * Radar channel sets - */ - -/* Channels 52 - 64, 100 - 140 */ -static const struct brcms_chanvec radar_set1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ - 0x00, 0x00, 0x00, 0x00} -}; - /* * Restricted channel sets */ -/* Channels 34, 38, 42, 46 */ -static const struct brcms_chanvec restricted_set_japan_legacy = { - {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - /* Channels 12, 13 */ static const struct brcms_chanvec restricted_set_2g_short = { {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -244,47 +188,11 @@ static const struct brcms_chanvec restricted_set_2g_short = { 0x00, 0x00, 0x00, 0x00} }; -/* Channel 165 */ -static const struct brcms_chanvec restricted_chan_165 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 36 - 48 & 149 - 165 */ -static const struct brcms_chanvec restricted_low_hi = { - {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 12 - 14 */ -static const struct brcms_chanvec restricted_set_12_13_14 = { - {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - /* global memory to provide working buffer for expanded locale */ -static const struct brcms_chanvec *g_table_radar_set[] = { - &chanvec_none, - &radar_set1 -}; - static const struct brcms_chanvec *g_table_restricted_chan[] = { &chanvec_none, /* restricted_set_none */ &restricted_set_2g_short, - &restricted_chan_165, - &chanvec_all_5G, - &restricted_set_japan_legacy, - &chanvec_all_2G, /* restricted_set_11d_2G */ - &chanvec_all_5G, /* restricted_set_11d_5G */ - &restricted_low_hi, - &restricted_set_12_13_14 }; static const struct brcms_chanvec locale_2g_01_11 = { @@ -445,11 +353,9 @@ static void brcms_c_locale_get_channels(const struct locale_info *locale, */ static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, - LOCALE_RADAR_SET_NONE, LOCALE_RESTRICTED_SET_2G_SHORT, {QDB(19), QDB(19), QDB(19), QDB(19), QDB(19), QDB(19)}, - {20, 20, 20, 0}, BRCMS_EIRP }; @@ -459,10 +365,8 @@ static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ static const struct locale_info locale_11 = { /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, - LOCALE_RADAR_SET_1, LOCALE_RESTRICTED_NONE, {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, - {23, 23, 23, 30, 30}, BRCMS_EIRP | BRCMS_DFS_EU }; @@ -544,13 +448,6 @@ static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) return g_mimo_5g_table[locale_idx]; } -static int -brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev) -{ - return false; -} - /* * Indicates whether the country provided is valid to pass * to cfg80211 or not. @@ -620,7 +517,6 @@ brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, const struct country_info *country; uint srom_regrev = wlc_cm->srom_regrev; const char *srom_ccode = wlc_cm->srom_ccode; - int mapped; /* check for currently supported ccode size */ if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) { @@ -639,12 +535,7 @@ brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, */ if (!strcmp(srom_ccode, ccode)) { *mapped_regrev = srom_regrev; - mapped = 0; wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__); - } else { - mapped = - brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode, - mapped_regrev); } /* find the matching built-in country definition */ @@ -902,8 +793,6 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, wlc_cm->bandstate[band->bandunit].restricted_channels = g_table_restricted_chan[li->restricted_channels]; - wlc_cm->bandstate[band->bandunit].radar_channels = - g_table_radar_set[li->radar_channels]; /* * set the channel availability, masking out the channels @@ -938,17 +827,11 @@ brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, { const struct locale_info *locale; struct brcms_c_info *wlc = wlc_cm->wlc; - char prev_country_abbrev[BRCM_CNTRY_BUF_SZ]; /* save current country state */ wlc_cm->country = country; - memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ); - strncpy(prev_country_abbrev, wlc_cm->country_abbrev, - BRCM_CNTRY_BUF_SZ - 1); - strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); - strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); wlc_cm->regrev = regrev; if ((wlc->pub->_n_enab & SUPPORT_11N) != @@ -1014,16 +897,12 @@ brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, static int brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode) { - char country_abbrev[BRCM_CNTRY_BUF_SZ]; - strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ); - return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); + return brcms_c_set_countrycode_rev(wlc_cm, ccode, ccode, -1); } struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) { struct brcms_cm_info *wlc_cm; - char country_abbrev[BRCM_CNTRY_BUF_SZ]; - const struct country_info *country; struct brcms_pub *pub = wlc->pub; struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; @@ -1040,21 +919,14 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2)) strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2)); - /* - * internal country information which must match - * regulatory constraints in firmware - */ - memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ); - strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); - country = brcms_c_country_lookup(wlc, country_abbrev); - /* save default country for exiting 11d regulatory mode */ - strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); + strncpy(wlc->country_default, "X2", BRCM_CNTRY_BUF_SZ - 1); /* initialize autocountry_default to driver default */ - strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1); + strncpy(wlc->autocountry_default, wlc->country_default, + BRCM_CNTRY_BUF_SZ - 1); - brcms_c_set_countrycode(wlc_cm, country_abbrev); + brcms_c_set_countrycode(wlc_cm, wlc->country_default); return wlc_cm; } -- GitLab From cf03c5dac83609f09d9f0e9fa3c09d86daed614d Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:52 -0500 Subject: [PATCH 2233/6849] brcm80211: smac: inform mac80211 of the X2 regulatory domain brcmsmac implements enforcement of regulatory constraints internally, using a Broadcom-specific world roaming domain named X2. Besides being duplication of functionality this can also conflict with mac80211's regulatory implementation, as mac80211 is unaware of the X2 domain and thus might apply a more restrictive domain. This patch is the first step in making brcmsmac cooperate with mac80211's regulatory support. X2 is registered as a custom domain with mac80211, so that at least both implementations will be enforcing the same set of constraints. The internal enforcement of rules is kept for now; this will be converted over to relying on mac80211 regulatory enforcement in later patches. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 385 ++++++++++-------- .../net/wireless/brcm80211/brcmsmac/channel.h | 1 + .../wireless/brcm80211/brcmsmac/mac80211_if.c | 2 + 3 files changed, 210 insertions(+), 178 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index c311ef7e99a7..65ef60bf9c8f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -15,7 +15,9 @@ */ #include +#include #include +#include #include #include "pub.h" @@ -23,6 +25,7 @@ #include "main.h" #include "stf.h" #include "channel.h" +#include "mac80211_if.h" /* QDB() macro takes a dB value and converts to a quarter dB value */ #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) @@ -108,6 +111,39 @@ (((c) < 100) ? 2 : \ (((c) < 149) ? 3 : 4)))) +#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) +#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_IBSS) + +#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_IBSS) +#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_DFS | \ + NL80211_RRF_NO_IBSS) +#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_DFS | \ + NL80211_RRF_NO_IBSS) +#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_IBSS) + +static const struct ieee80211_regdomain brcms_regdom_x2 = { + .n_reg_rules = 7, + .alpha2 = "X2", + .reg_rules = { + BRCM_2GHZ_2412_2462, + BRCM_2GHZ_2467_2472, + BRCM_5GHZ_5180_5240, + BRCM_5GHZ_5260_5320, + BRCM_5GHZ_5500_5700, + BRCM_5GHZ_5745_5825, + } +}; + struct brcms_cm_band { /* struct locale_info flags */ u8 locale_flags; @@ -137,14 +173,15 @@ struct country_info { const u8 locale_mimo_5G; /* 5G mimo info */ }; +struct brcms_regd { + struct country_info country; + const struct ieee80211_regdomain *regdomain; +}; + struct brcms_cm_info { struct brcms_pub *pub; struct brcms_c_info *wlc; - char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */ - uint srom_regrev; /* Regulatory Rev for the SROM ccode */ - const struct country_info *country; /* current country def */ - uint regrev; /* current Regulatory Revision */ - char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */ + const struct brcms_regd *world_regd; /* per-band state (one per phy/radio) */ struct brcms_cm_band bandstate[MAXBANDS]; /* quiet channels currently for radar sensitivity or 11h support */ @@ -408,12 +445,12 @@ static const struct locale_mimo_info *g_mimo_5g_table[] = { &locale_11n }; -static const struct { - char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */ - struct country_info country; -} cntry_locales[] = { +static const struct brcms_regd cntry_locales[] = { + /* Worldwide RoW 2, must always be at index 0 */ { - "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ + .country = LOCALES(i, 11, bn, 11n), + .regdomain = &brcms_regdom_x2, + }, }; static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) @@ -482,93 +519,24 @@ static bool brcms_c_country_valid(const char *ccode) return true; } -/* Lookup a country info structure from a null terminated country - * abbreviation and regrev directly with no translation. - */ -static const struct country_info * -brcms_c_country_lookup_direct(const char *ccode, uint regrev) +static const struct brcms_regd *brcms_world_regd(const char *regdom, int len) { - uint size, i; + const struct brcms_regd *regd = NULL; + int i; - /* Should just return 0 for single locale driver. */ - /* Keep it this way in case we add more locales. (for now anyway) */ - - /* - * all other country def arrays are for regrev == 0, so if - * regrev is non-zero, fail - */ - if (regrev > 0) - return NULL; - - /* find matched table entry from country code */ - size = ARRAY_SIZE(cntry_locales); - for (i = 0; i < size; i++) { - if (strcmp(ccode, cntry_locales[i].abbrev) == 0) - return &cntry_locales[i].country; - } - return NULL; -} - -static const struct country_info * -brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev) -{ - struct brcms_c_info *wlc = wlc_cm->wlc; - const struct country_info *country; - uint srom_regrev = wlc_cm->srom_regrev; - const char *srom_ccode = wlc_cm->srom_ccode; - - /* check for currently supported ccode size */ - if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) { - wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for " - "match\n", wlc->pub->unit, __func__, ccode); - return NULL; - } - - /* default mapping is the given ccode and regrev 0 */ - strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); - *mapped_regrev = 0; - - /* If the desired country code matches the srom country code, - * then the mapped country is the srom regulatory rev. - * Otherwise look for an aggregate mapping. - */ - if (!strcmp(srom_ccode, ccode)) { - *mapped_regrev = srom_regrev; - wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__); - } - - /* find the matching built-in country definition */ - country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); - - /* if there is not an exact rev match, default to rev zero */ - if (country == NULL && *mapped_regrev != 0) { - *mapped_regrev = 0; - country = - brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); + for (i = 0; i < ARRAY_SIZE(cntry_locales); i++) { + if (!strncmp(regdom, cntry_locales[i].regdomain->alpha2, len)) { + regd = &cntry_locales[i]; + break; + } } - return country; + return regd; } -/* Lookup a country info structure from a null terminated country code - * The lookup is case sensitive. - */ -static const struct country_info * -brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode) +static const struct brcms_regd *brcms_default_world_regd(void) { - const struct country_info *country; - char mapped_ccode[BRCM_CNTRY_BUF_SZ]; - uint mapped_regrev; - - /* - * map the country code to a built-in country code, regrev, and - * country_info struct - */ - country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode, - &mapped_regrev); - - return country; + return &cntry_locales[0]; } /* @@ -634,12 +602,6 @@ static bool brcms_c_japan_ccode(const char *ccode) (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); } -/* Returns true if currently set country is Japan or variant */ -static bool brcms_c_japan(struct brcms_c_info *wlc) -{ - return brcms_c_japan_ccode(wlc->cmi->country_abbrev); -} - static void brcms_c_channel_min_txpower_limits_with_local_constraint( struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, @@ -743,8 +705,8 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " "nbands %d bandlocked %d\n", wlc->pub->unit, - __func__, wlc_cm->country_abbrev, wlc->pub->_nbands, - wlc->bandlocked); + __func__, wlc_cm->world_regd->regdomain->alpha2, + wlc->pub->_nbands, wlc->bandlocked); } else if (mboolisset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE)) { /* @@ -753,15 +715,6 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) */ mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); } - - /* - * Now that the country abbreviation is set, if the radio supports 2G, - * then set channel 14 restrictions based on the new locale. - */ - if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) - wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, - brcms_c_japan(wlc) ? true : - false); } static int @@ -820,20 +773,13 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, * information found with the country code. */ static void -brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, - const char *country_abbrev, - const char *ccode, uint regrev, - const struct country_info *country) +brcms_c_set_country(struct brcms_cm_info *wlc_cm, + const struct brcms_regd *regd) { + const struct country_info *country = ®d->country; const struct locale_info *locale; struct brcms_c_info *wlc = wlc_cm->wlc; - /* save current country state */ - wlc_cm->country = country; - - strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); - wlc_cm->regrev = regrev; - if ((wlc->pub->_n_enab & SUPPORT_11N) != wlc->protection->nmode_user) brcms_c_set_nmode(wlc); @@ -852,59 +798,13 @@ brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, return; } -static int -brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, - const char *country_abbrev, - const char *ccode, int regrev) -{ - const struct country_info *country; - char mapped_ccode[BRCM_CNTRY_BUF_SZ]; - uint mapped_regrev; - - /* if regrev is -1, lookup the mapped country code, - * otherwise use the ccode and regrev directly - */ - if (regrev == -1) { - /* - * map the country code to a built-in country - * code, regrev, and country_info - */ - country = - brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode, - &mapped_regrev); - } else { - /* find the matching built-in country definition */ - country = brcms_c_country_lookup_direct(ccode, regrev); - strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); - mapped_regrev = regrev; - } - - if (country == NULL) - return -EINVAL; - - /* set the driver state for the country */ - brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode, - mapped_regrev, country); - - return 0; -} - -/* - * set the driver's current country and regulatory information using - * a country code as the source. Lookup built in country information - * found with the country code. - */ -static int -brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode) -{ - return brcms_c_set_countrycode_rev(wlc_cm, ccode, ccode, -1); -} - struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) { struct brcms_cm_info *wlc_cm; struct brcms_pub *pub = wlc->pub; struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; + const char *ccode = sprom->alpha2; + int ccode_len = sizeof(sprom->alpha2); BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -916,17 +816,27 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) wlc->cmi = wlc_cm; /* store the country code for passing up as a regulatory hint */ - if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2)) - strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2)); + wlc_cm->world_regd = brcms_world_regd(ccode, ccode_len); + if (brcms_c_country_valid(ccode)) + strncpy(wlc->pub->srom_ccode, ccode, ccode_len); + + /* + * If no custom world domain is found in the SROM, use the + * default "X2" domain. + */ + if (!wlc_cm->world_regd) { + wlc_cm->world_regd = brcms_default_world_regd(); + ccode = wlc_cm->world_regd->regdomain->alpha2; + ccode_len = BRCM_CNTRY_BUF_SZ - 1; + } /* save default country for exiting 11d regulatory mode */ - strncpy(wlc->country_default, "X2", BRCM_CNTRY_BUF_SZ - 1); + strncpy(wlc->country_default, ccode, ccode_len); /* initialize autocountry_default to driver default */ - strncpy(wlc->autocountry_default, wlc->country_default, - BRCM_CNTRY_BUF_SZ - 1); + strncpy(wlc->autocountry_default, ccode, ccode_len); - brcms_c_set_countrycode(wlc_cm, wlc->country_default); + brcms_c_set_country(wlc_cm, wlc_cm->world_regd); return wlc_cm; } @@ -994,13 +904,7 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, memset(txpwr, 0, sizeof(struct txpwr_limits)); - if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) { - country = brcms_c_country_lookup(wlc, wlc->autocountry_default); - if (country == NULL) - return; - } else { - country = wlc_cm->country; - } + country = &wlc_cm->world_regd->country; chan = CHSPEC_CHANNEL(chanspec); band = wlc->bandstate[chspec_bandunit(chanspec)]; @@ -1252,3 +1156,128 @@ bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) { return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); } + +static bool brcms_is_radar_freq(u16 center_freq) +{ + return center_freq >= 5260 && center_freq <= 5700; +} + +static void brcms_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + int i; + + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + + if (!brcms_is_radar_freq(ch->center_freq)) + continue; + + /* + * All channels in this range should be passive and have + * DFS enabled. + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +static void +brcms_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *rule; + int band, i, ret; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + sband = wiphy->bands[band]; + if (!sband) + continue; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + + if (ch->flags & + (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_RADAR)) + continue; + + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ret = freq_reg_info(wiphy, ch->center_freq, + 0, &rule); + if (ret) + continue; + + if (!(rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else if (ch->beacon_found) { + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +static int brcms_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct brcms_info *wl = hw->priv; + struct brcms_c_info *wlc = wl->wlc; + + brcms_reg_apply_radar_flags(wiphy); + + if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) + brcms_reg_apply_beaconing_flags(wiphy, request->initiator); + + if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) + wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, + brcms_c_japan_ccode(request->alpha2)); + + return 0; +} + +void brcms_c_regd_init(struct brcms_c_info *wlc) +{ + struct wiphy *wiphy = wlc->wiphy; + const struct brcms_regd *regd = wlc->cmi->world_regd; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + struct brcms_chanvec sup_chan; + struct brcms_band *band; + int band_idx, i; + + /* Disable any channels not supported by the phy */ + for (band_idx = 0; band_idx < IEEE80211_NUM_BANDS; band_idx++) { + if (band_idx == IEEE80211_BAND_2GHZ) + band = wlc->bandstate[BAND_2G_INDEX]; + else + band = wlc->bandstate[BAND_5G_INDEX]; + wlc_phy_chanspec_band_validch(band->pi, band->bandtype, + &sup_chan); + + sband = wiphy->bands[band_idx]; + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!isset(sup_chan.vec, ch->hw_value)) + ch->flags |= IEEE80211_CHAN_DISABLED; + } + } + + wlc->wiphy->reg_notifier = brcms_reg_notifier; + wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | + WIPHY_FLAG_STRICT_REGULATORY; + wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain); + brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER); +} diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h index 808cb4fbfbe7..de9887d95f2f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h @@ -49,5 +49,6 @@ extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, u8 local_constraint_qdbm); +extern void brcms_c_regd_init(struct brcms_c_info *wlc); #endif /* _WLC_CHANNEL_H */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 341e06a0d6ec..2d5a40412690 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -1050,6 +1050,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) goto fail; } + brcms_c_regd_init(wl->wlc); + memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN); if (WARN_ON(!is_valid_ether_addr(perm))) goto fail; -- GitLab From 2ab631f48cac65864a61007215187cb7511b0846 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:53 -0500 Subject: [PATCH 2234/6849] brcm80211: smac: enable/disable radio on regulatory updates Currently the radio disable state is only updated during initialization, and it's only checked against the internal world domain. This is unnecessary, as there are always valid channels against this domain. Instead, check whether any channels are enabled in the regulatory notifier and update the radio state accordingly. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 67 +++++++------------ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 65ef60bf9c8f..3951ccf22c9b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -677,46 +677,6 @@ brcms_c_channel_min_txpower_limits_with_local_constraint( } -/* Update the radio state (enable/disable) and tx power targets - * based on a new set of channel/regulatory information - */ -static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) -{ - struct brcms_c_info *wlc = wlc_cm->wlc; - uint chan; - - /* search for the existence of any valid channel */ - for (chan = 0; chan < MAXCHANNEL; chan++) { - if (brcms_c_valid_channel20_db(wlc->cmi, chan)) - break; - } - if (chan == MAXCHANNEL) - chan = INVCHANNEL; - - /* - * based on the channel search above, set or - * clear WL_RADIO_COUNTRY_DISABLE. - */ - if (chan == INVCHANNEL) { - /* - * country/locale with no valid channels, set - * the radio disable bit - */ - mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " - "nbands %d bandlocked %d\n", wlc->pub->unit, - __func__, wlc_cm->world_regd->regdomain->alpha2, - wlc->pub->_nbands, wlc->bandlocked); - } else if (mboolisset(wlc->pub->radio_disabled, - WL_RADIO_COUNTRY_DISABLE)) { - /* - * country/locale with valid channel, clear - * the radio disable bit - */ - mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - } -} - static int brcms_c_channels_init(struct brcms_cm_info *wlc_cm, const struct country_info *country) @@ -762,7 +722,6 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, } brcms_c_quiet_channels_reset(wlc_cm); - brcms_c_channels_commit(wlc_cm); return 0; } @@ -1235,12 +1194,38 @@ static int brcms_reg_notifier(struct wiphy *wiphy, struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct brcms_info *wl = hw->priv; struct brcms_c_info *wlc = wl->wlc; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + int band, i; + bool ch_found = false; brcms_reg_apply_radar_flags(wiphy); if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) brcms_reg_apply_beaconing_flags(wiphy, request->initiator); + /* Disable radio if all channels disallowed by regulatory */ + for (band = 0; !ch_found && band < IEEE80211_NUM_BANDS; band++) { + sband = wiphy->bands[band]; + if (!sband) + continue; + + for (i = 0; !ch_found && i < sband->n_channels; i++) { + ch = &sband->channels[i]; + + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch_found = true; + } + } + + if (ch_found) { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + } else { + mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", + wlc->pub->unit, __func__, request->alpha2); + } + if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, brcms_c_japan_ccode(request->alpha2)); -- GitLab From 2cf5089ed5ae4a8f73427234cb83c42eaaf34d46 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:54 -0500 Subject: [PATCH 2235/6849] brcm80211: smac: use mac80211 channel data for tx power limits Currently the limits from the internal X2 domain are used, regardless of what regulatory rules are in effect. Instead use the power limits set by the higher-level regulatory support. The rules for the MIMO power limits are still always derived from the world domain, pending guidance from Broadcom as to how these need to be handled. This will be fixed later, but using the limits from the world domain works for now. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 73 ++++--------------- 1 file changed, 14 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 3951ccf22c9b..bdb11ffcc154 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -74,15 +74,6 @@ /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ #define BRCMS_MAXPWR_MIMO_TBL_SIZE 14 -/* power level in group of 2.4GHz band channels: - * maxpwr[0] - CCK channels [1] - * maxpwr[1] - CCK channels [2-10] - * maxpwr[2] - CCK channels [11-14] - * maxpwr[3] - OFDM channels [1] - * maxpwr[4] - OFDM channels [2-10] - * maxpwr[5] - OFDM channels [11-14] - */ - /* maxpwr mapping to 5GHz band channels: * maxpwr[0] - channels [34-48] * maxpwr[1] - channels [52-60] @@ -101,10 +92,6 @@ #define LOCALES(band2, band5, mimo2, mimo5) \ {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} -/* macro to get 2.4 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) -#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) - /* macro to get 5 GHz channel group index for tx power */ #define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \ (((c) < 62) ? 1 : \ @@ -194,8 +181,6 @@ struct locale_info { u32 valid_channels; /* List of channels used only if APs are detected */ u8 restricted_channels; - /* Max tx pwr in qdBm for each sub-band */ - s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE]; u8 flags; }; @@ -391,8 +376,6 @@ static void brcms_c_locale_get_channels(const struct locale_info *locale, static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, LOCALE_RESTRICTED_SET_2G_SHORT, - {QDB(19), QDB(19), QDB(19), - QDB(19), QDB(19), QDB(19)}, BRCMS_EIRP }; @@ -403,7 +386,6 @@ static const struct locale_info locale_11 = { /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, LOCALE_RESTRICTED_NONE, - {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, BRCMS_EIRP | BRCMS_DFS_EU }; @@ -847,6 +829,7 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, struct txpwr_limits *txpwr) { struct brcms_c_info *wlc = wlc_cm->wlc; + struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; uint i; uint chan; int maxpwr; @@ -855,7 +838,6 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, struct brcms_band *band; const struct locale_info *li; int conducted_max = BRCMS_TXPWR_MAX; - int conducted_ofdm_max = BRCMS_TXPWR_MAX; const struct locale_mimo_info *li_mimo; int maxpwr20, maxpwr40; int maxpwr_idx; @@ -863,6 +845,9 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, memset(txpwr, 0, sizeof(struct txpwr_limits)); + if (WARN_ON(!ch)) + return; + country = &wlc_cm->world_regd->country; chan = CHSPEC_CHANNEL(chanspec); @@ -875,49 +860,24 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, brcms_c_get_mimo_5g(country->locale_mimo_5G) : brcms_c_get_mimo_2g(country->locale_mimo_2G); - if (li->flags & BRCMS_EIRP) { - delta = band->antgain; - } else { - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ - } + delta = band->antgain; - if (li == &locale_i) { + if (li == &locale_i) conducted_max = QDB(22); - conducted_ofdm_max = QDB(22); - } + + maxpwr = QDB(ch->max_power) - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_max); /* CCK txpwr limits for 2.4G band */ if (band->bandtype == BRCM_BAND_2G) { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; - - maxpwr = maxpwr - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_max); - for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) txpwr->cck[i] = (u8) maxpwr; } - /* OFDM txpwr limits for 2.4G or 5G bands */ - if (band->bandtype == BRCM_BAND_2G) - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; - else - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; - - maxpwr = maxpwr - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_ofdm_max); - - /* Keep OFDM lmit below CCK limit */ - if (band->bandtype == BRCM_BAND_2G) - maxpwr = min_t(int, maxpwr, txpwr->cck[0]); - - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { txpwr->ofdm[i] = (u8) maxpwr; - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { /* * OFDM 40 MHz SISO has the same power as the corresponding * MCS0-7 rate unless overriden by the locale specific code. @@ -932,14 +892,9 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, txpwr->ofdm_40_cdd[i] = 0; } - /* MIMO/HT specific limits */ - if (li_mimo->flags & BRCMS_EIRP) { - delta = band->antgain; - } else { - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ - } + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ if (band->bandtype == BRCM_BAND_2G) maxpwr_idx = (chan - 1); -- GitLab From 853346d8b60738467581d1cd9ccb678aeb086121 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:55 -0500 Subject: [PATCH 2236/6849] brcm80211: smac: don't validate channels against internal regulatory data The core regulatory support will disable channels not allowed by regulatory rules, so brcmsmac doesn't need to check whether or not the requested channel is permitted by regulatory. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 344 +----------------- 1 file changed, 6 insertions(+), 338 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index bdb11ffcc154..04e6a6ec77ff 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -30,40 +30,6 @@ /* QDB() macro takes a dB value and converts to a quarter dB value */ #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) -#define LOCALE_CHAN_01_11 (1<<0) -#define LOCALE_CHAN_12_13 (1<<1) -#define LOCALE_CHAN_14 (1<<2) -#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ -#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ -#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ -#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ -#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ -#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ -#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ -#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ -#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ -#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ -#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ -#define LOCALE_CHAN_52_140_ALL (1<<14) -#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ - -#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \ - LOCALE_SET_5G_LOW2 | \ - LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) -#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \ - LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) -#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) -#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 - -#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \ - LOCALE_CHAN_12_13 | \ - LOCALE_CHAN_14) - -#define LOCALE_RESTRICTED_NONE 0 -#define LOCALE_RESTRICTED_SET_2G_SHORT 1 - #define LOCALE_2G_IDX_i 0 #define LOCALE_5G_IDX_11 0 #define LOCALE_MIMO_IDX_bn 0 @@ -134,10 +100,6 @@ static const struct ieee80211_regdomain brcms_regdom_x2 = { struct brcms_cm_band { /* struct locale_info flags */ u8 locale_flags; - /* List of valid channels in the country */ - struct brcms_chanvec valid_channels; - /* List of restricted use channels */ - const struct brcms_chanvec *restricted_channels; }; /* locale per-channel tx power limits for MIMO frames @@ -171,211 +133,17 @@ struct brcms_cm_info { const struct brcms_regd *world_regd; /* per-band state (one per phy/radio) */ struct brcms_cm_band bandstate[MAXBANDS]; - /* quiet channels currently for radar sensitivity or 11h support */ - /* channels on which we cannot transmit */ - struct brcms_chanvec quiet_channels; }; /* locale channel and power info. */ struct locale_info { - u32 valid_channels; - /* List of channels used only if APs are detected */ - u8 restricted_channels; u8 flags; }; -/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ - -/* - * Some common channel sets - */ - -/* No channels */ -static const struct brcms_chanvec chanvec_none = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* - * Restricted channel sets - */ - -/* Channels 12, 13 */ -static const struct brcms_chanvec restricted_set_2g_short = { - {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* global memory to provide working buffer for expanded locale */ - -static const struct brcms_chanvec *g_table_restricted_chan[] = { - &chanvec_none, /* restricted_set_none */ - &restricted_set_2g_short, -}; - -static const struct brcms_chanvec locale_2g_01_11 = { - {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_2g_12_13 = { - {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_2g_14 = { - {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_LOW_JP1 = { - {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_LOW_JP2 = { - {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_LOW1 = { - {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_LOW2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_LOW3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_MID1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_MID2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_MID3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_HIGH1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_HIGH2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_HIGH3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_52_140_ALL = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const struct brcms_chanvec locale_5g_HIGH4 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x11, 0x11, 0x11, 0x11} -}; - -static const struct brcms_chanvec *g_table_locale_base[] = { - &locale_2g_01_11, - &locale_2g_12_13, - &locale_2g_14, - &locale_5g_LOW_JP1, - &locale_5g_LOW_JP2, - &locale_5g_LOW1, - &locale_5g_LOW2, - &locale_5g_LOW3, - &locale_5g_MID1, - &locale_5g_MID2, - &locale_5g_MID3, - &locale_5g_HIGH1, - &locale_5g_HIGH2, - &locale_5g_HIGH3, - &locale_5g_52_140_ALL, - &locale_5g_HIGH4 -}; - -static void brcms_c_locale_add_channels(struct brcms_chanvec *target, - const struct brcms_chanvec *channels) -{ - u8 i; - for (i = 0; i < sizeof(struct brcms_chanvec); i++) - target->vec[i] |= channels->vec[i]; -} - -static void brcms_c_locale_get_channels(const struct locale_info *locale, - struct brcms_chanvec *channels) -{ - u8 i; - - memset(channels, 0, sizeof(struct brcms_chanvec)); - - for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { - if (locale->valid_channels & (1 << i)) - brcms_c_locale_add_channels(channels, - g_table_locale_base[i]); - } -} - /* * Locale Definitions - 2.4 GHz */ static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ - LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, - LOCALE_RESTRICTED_SET_2G_SHORT, BRCMS_EIRP }; @@ -383,9 +151,6 @@ static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ * Locale Definitions - 5 GHz */ static const struct locale_info locale_11 = { - /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ - LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, - LOCALE_RESTRICTED_NONE, BRCMS_EIRP | BRCMS_DFS_EU }; @@ -521,62 +286,6 @@ static const struct brcms_regd *brcms_default_world_regd(void) return &cntry_locales[0]; } -/* - * reset the quiet channels vector to the union - * of the restricted and radar channel sets - */ -static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) -{ - struct brcms_c_info *wlc = wlc_cm->wlc; - uint i, j; - struct brcms_band *band; - const struct brcms_chanvec *chanvec; - - memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec)); - - band = wlc->band; - for (i = 0; i < wlc->pub->_nbands; - i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { - - /* initialize quiet channels for restricted channels */ - chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; - for (j = 0; j < sizeof(struct brcms_chanvec); j++) - wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; - - } -} - -/* Is the channel valid for the current locale and current band? */ -static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val) -{ - struct brcms_c_info *wlc = wlc_cm->wlc; - - return ((val < MAXCHANNEL) && - isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, - val)); -} - -/* Is the channel valid for the current locale and specified band? */ -static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, - uint bandunit, uint val) -{ - return ((val < MAXCHANNEL) - && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); -} - -/* Is the channel valid for the current locale? (but don't consider channels not - * available due to bandlocking) - */ -static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val) -{ - struct brcms_c_info *wlc = wlc_cm->wlc; - - return brcms_c_valid_channel20(wlc->cmi, val) || - (!wlc->bandlocked - && brcms_c_valid_channel20_in_band(wlc->cmi, - OTHERBANDUNIT(wlc), val)); -} - /* JP, J1 - J10 are Japan ccodes */ static bool brcms_c_japan_ccode(const char *ccode) { @@ -664,10 +373,9 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, const struct country_info *country) { struct brcms_c_info *wlc = wlc_cm->wlc; - uint i, j; + uint i; struct brcms_band *band; const struct locale_info *li; - struct brcms_chanvec sup_chan; const struct locale_mimo_info *li_mimo; band = wlc->band; @@ -685,26 +393,8 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, /* merge the mimo non-mimo locale flags */ wlc_cm->bandstate[band->bandunit].locale_flags |= li_mimo->flags; - - wlc_cm->bandstate[band->bandunit].restricted_channels = - g_table_restricted_chan[li->restricted_channels]; - - /* - * set the channel availability, masking out the channels - * that may not be supported on this phy. - */ - wlc_phy_chanspec_band_validch(band->pi, band->bandtype, - &sup_chan); - brcms_c_locale_get_channels(li, - &wlc_cm->bandstate[band->bandunit]. - valid_channels); - for (j = 0; j < sizeof(struct brcms_chanvec); j++) - wlc_cm->bandstate[band->bandunit].valid_channels. - vec[j] &= sup_chan.vec[j]; } - brcms_c_quiet_channels_reset(wlc_cm); - return 0; } @@ -794,23 +484,12 @@ brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, return wlc_cm->bandstate[bandunit].locale_flags; } -static bool -brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec) -{ - return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) && - CHSPEC_IS40(chspec) ? - (isset(wlc_cm->quiet_channels.vec, - lower_20_sb(CHSPEC_CHANNEL(chspec))) || - isset(wlc_cm->quiet_channels.vec, - upper_20_sb(CHSPEC_CHANNEL(chspec)))) : - isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec)); -} - void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, u8 local_constraint_qdbm) { struct brcms_c_info *wlc = wlc_cm->wlc; + struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; struct txpwr_limits txpwr; brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); @@ -820,7 +499,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, ); brcms_b_set_chanspec(wlc->hw, chanspec, - (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0), + !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), &txpwr); } @@ -1036,8 +715,7 @@ static bool brcms_c_chspec_malformed(u16 chanspec) * and they are also a legal HT combination */ static bool -brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, - bool dualband) +brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) { struct brcms_c_info *wlc = wlc_cm->wlc; u8 channel = CHSPEC_CHANNEL(chspec); @@ -1053,22 +731,12 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, chspec_bandunit(chspec)) return false; - /* Check a 20Mhz channel */ - if (CHSPEC_IS20(chspec)) { - if (dualband) - return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi, - channel); - else - return brcms_c_valid_channel20(wlc_cm->wlc->cmi, - channel); - } - - return false; + return true; } bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) { - return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); + return brcms_c_valid_chanspec_ext(wlc_cm, chspec); } static bool brcms_is_radar_freq(u16 center_freq) -- GitLab From edc7651f3a4ffa7fca37d92401562694121512ad Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Sat, 16 Jun 2012 07:47:56 -0500 Subject: [PATCH 2237/6849] brcm80211: smac: use current regulatory domain when checking whether OFDM is allowed The brcmsmac internal regulatory data is being used to determine whether OFDM should be allowed, and this is only done once during initialization. To be effective this needs to be checked against mac80211's regulatory rules for the current channel. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/channel.c | 132 ++---------------- .../net/wireless/brcm80211/brcmsmac/channel.h | 3 - .../net/wireless/brcm80211/brcmsmac/main.c | 6 +- 3 files changed, 15 insertions(+), 126 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 04e6a6ec77ff..d3c726021c35 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -30,13 +30,9 @@ /* QDB() macro takes a dB value and converts to a quarter dB value */ #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) -#define LOCALE_2G_IDX_i 0 -#define LOCALE_5G_IDX_11 0 #define LOCALE_MIMO_IDX_bn 0 #define LOCALE_MIMO_IDX_11n 0 -/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ -#define BRCMS_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ #define BRCMS_MAXPWR_MIMO_TBL_SIZE 14 @@ -51,12 +47,8 @@ #define LC(id) LOCALE_MIMO_IDX_ ## id -#define LC_2G(id) LOCALE_2G_IDX_ ## id - -#define LC_5G(id) LOCALE_5G_IDX_ ## id - -#define LOCALES(band2, band5, mimo2, mimo5) \ - {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} +#define LOCALES(mimo2, mimo5) \ + {LC(mimo2), LC(mimo5)} /* macro to get 5 GHz channel group index for tx power */ #define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \ @@ -97,11 +89,6 @@ static const struct ieee80211_regdomain brcms_regdom_x2 = { } }; -struct brcms_cm_band { - /* struct locale_info flags */ - u8 locale_flags; -}; - /* locale per-channel tx power limits for MIMO frames * maxpwr arrays are index by channel for 2.4 GHz limits, and * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) @@ -111,13 +98,10 @@ struct locale_mimo_info { s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE]; - u8 flags; }; /* Country names and abbreviations with locale defined from ISO 3166 */ struct country_info { - const u8 locale_2G; /* 2.4G band locale */ - const u8 locale_5G; /* 5G band locale */ const u8 locale_mimo_2G; /* 2.4G mimo info */ const u8 locale_mimo_5G; /* 5G mimo info */ }; @@ -131,35 +115,6 @@ struct brcms_cm_info { struct brcms_pub *pub; struct brcms_c_info *wlc; const struct brcms_regd *world_regd; - /* per-band state (one per phy/radio) */ - struct brcms_cm_band bandstate[MAXBANDS]; -}; - -/* locale channel and power info. */ -struct locale_info { - u8 flags; -}; - -/* - * Locale Definitions - 2.4 GHz - */ -static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ - BRCMS_EIRP -}; - -/* - * Locale Definitions - 5 GHz - */ -static const struct locale_info locale_11 = { - BRCMS_EIRP | BRCMS_DFS_EU -}; - -static const struct locale_info *g_locale_2g_table[] = { - &locale_i -}; - -static const struct locale_info *g_locale_5g_table[] = { - &locale_11 }; /* @@ -172,7 +127,6 @@ static const struct locale_mimo_info locale_bn = { {0, 0, QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 0, 0}, - 0 }; static const struct locale_mimo_info *g_mimo_2g_table[] = { @@ -185,7 +139,6 @@ static const struct locale_mimo_info *g_mimo_2g_table[] = { static const struct locale_mimo_info locale_11n = { { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, - 0 }; static const struct locale_mimo_info *g_mimo_5g_table[] = { @@ -195,27 +148,11 @@ static const struct locale_mimo_info *g_mimo_5g_table[] = { static const struct brcms_regd cntry_locales[] = { /* Worldwide RoW 2, must always be at index 0 */ { - .country = LOCALES(i, 11, bn, 11n), + .country = LOCALES(bn, 11n), .regdomain = &brcms_regdom_x2, }, }; -static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) - return NULL; /* error condition */ - - return g_locale_2g_table[locale_idx]; -} - -static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) - return NULL; /* error condition */ - - return g_locale_5g_table[locale_idx]; -} - static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) @@ -368,36 +305,6 @@ brcms_c_channel_min_txpower_limits_with_local_constraint( } -static int -brcms_c_channels_init(struct brcms_cm_info *wlc_cm, - const struct country_info *country) -{ - struct brcms_c_info *wlc = wlc_cm->wlc; - uint i; - struct brcms_band *band; - const struct locale_info *li; - const struct locale_mimo_info *li_mimo; - - band = wlc->band; - for (i = 0; i < wlc->pub->_nbands; - i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { - - li = (band->bandtype == BRCM_BAND_5G) ? - brcms_c_get_locale_5g(country->locale_5G) : - brcms_c_get_locale_2g(country->locale_2G); - wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; - li_mimo = (band->bandtype == BRCM_BAND_5G) ? - brcms_c_get_mimo_5g(country->locale_mimo_5G) : - brcms_c_get_mimo_2g(country->locale_mimo_2G); - - /* merge the mimo non-mimo locale flags */ - wlc_cm->bandstate[band->bandunit].locale_flags |= - li_mimo->flags; - } - - return 0; -} - /* * set the driver's current country and regulatory information * using a country code as the source. Look up built in country @@ -407,8 +314,6 @@ static void brcms_c_set_country(struct brcms_cm_info *wlc_cm, const struct brcms_regd *regd) { - const struct country_info *country = ®d->country; - const struct locale_info *locale; struct brcms_c_info *wlc = wlc_cm->wlc; if ((wlc->pub->_n_enab & SUPPORT_11N) != @@ -417,14 +322,8 @@ brcms_c_set_country(struct brcms_cm_info *wlc_cm, brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - /* set or restore gmode as required by regulatory */ - locale = brcms_c_get_locale_2g(country->locale_2G); - if (locale && (locale->flags & BRCMS_NO_OFDM)) - brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); - else - brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); - brcms_c_channels_init(wlc_cm, country); + brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); return; } @@ -477,20 +376,15 @@ void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm) kfree(wlc_cm); } -u8 -brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, - uint bandunit) -{ - return wlc_cm->bandstate[bandunit].locale_flags; -} - void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, u8 local_constraint_qdbm) { struct brcms_c_info *wlc = wlc_cm->wlc; struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; + const struct ieee80211_reg_rule *reg_rule; struct txpwr_limits txpwr; + int ret; brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); @@ -498,6 +392,13 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, wlc_cm, &txpwr, local_constraint_qdbm ); + /* set or restore gmode as required by regulatory */ + ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, ®_rule); + if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM)) + brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); + else + brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); + brcms_b_set_chanspec(wlc->hw, chanspec, !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), &txpwr); @@ -515,7 +416,6 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, int delta; const struct country_info *country; struct brcms_band *band; - const struct locale_info *li; int conducted_max = BRCMS_TXPWR_MAX; const struct locale_mimo_info *li_mimo; int maxpwr20, maxpwr40; @@ -531,17 +431,13 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, chan = CHSPEC_CHANNEL(chanspec); band = wlc->bandstate[chspec_bandunit(chanspec)]; - li = (band->bandtype == BRCM_BAND_5G) ? - brcms_c_get_locale_5g(country->locale_5G) : - brcms_c_get_locale_2g(country->locale_2G); - li_mimo = (band->bandtype == BRCM_BAND_5G) ? brcms_c_get_mimo_5g(country->locale_mimo_5G) : brcms_c_get_mimo_2g(country->locale_mimo_2G); delta = band->antgain; - if (li == &locale_i) + if (band->bandtype == BRCM_BAND_2G) conducted_max = QDB(22); maxpwr = QDB(ch->max_power) - delta; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h index de9887d95f2f..006483a0abe6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h @@ -37,9 +37,6 @@ brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); -extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, - uint bandunit); - extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 93c865db7729..8776fbc8dcf1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -5386,11 +5387,6 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) else return -EINVAL; - /* Legacy or bust when no OFDM is supported by regulatory */ - if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & - BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B)) - return -EINVAL; - /* update configuration value */ if (config) brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); -- GitLab From 7e05bedca084faa073c2e64bbcd6407dbaff3151 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:31:48 +0300 Subject: [PATCH 2238/6849] wl1251: remove unused filter_work filter_work is never used, remove it. Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/main.c | 36 ------------------------- drivers/net/wireless/ti/wl1251/wl1251.h | 1 - 2 files changed, 37 deletions(-) diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index d1afb8e3b2ef..ff60a7a341be 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -348,33 +348,6 @@ out: return ret; } -static void wl1251_filter_work(struct work_struct *work) -{ - struct wl1251 *wl = - container_of(work, struct wl1251, filter_work); - int ret; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1251_STATE_OFF) - goto out; - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int, - wl->dtim_period); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - static void wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; @@ -478,7 +451,6 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); - cancel_work_sync(&wl->filter_work); cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); @@ -723,13 +695,6 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, wl->rx_filter |= CFG_RX_CTL_EN; if (*total & FIF_OTHER_BSS) wl->rx_filter &= ~CFG_BSSID_FILTER_EN; - - /* - * FIXME: workqueues need to be properly cancelled on stop(), for - * now let's just disable changing the filter settings. They will - * be updated any on config(). - */ - /* schedule_work(&wl->filter_work); */ } /* HW encryption */ @@ -1390,7 +1355,6 @@ struct ieee80211_hw *wl1251_alloc_hw(void) skb_queue_head_init(&wl->tx_queue); - INIT_WORK(&wl->filter_work, wl1251_filter_work); INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); wl->channel = WL1251_DEFAULT_CHANNEL; wl->scanning = false; diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h index 9d8f5816c6f9..fd02060038de 100644 --- a/drivers/net/wireless/ti/wl1251/wl1251.h +++ b/drivers/net/wireless/ti/wl1251/wl1251.h @@ -315,7 +315,6 @@ struct wl1251 { bool tx_queue_stopped; struct work_struct tx_work; - struct work_struct filter_work; /* Pending TX frames */ struct sk_buff *tx_frames[16]; -- GitLab From a2d2bb8675fe9dc127d802b6be6517a0932e65b7 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:31:49 +0300 Subject: [PATCH 2239/6849] wl1251: fix filtering support This driver has a hack in cmd.c which effectively disables all filtering. This seems to be triggering a firmware bug where it stops reporting any rx packets after random time on some routers, which is eliminated (or at least appears much more rarely) when filtering is on. I have found that only BSSID filter needs to be disabled for association to work, so disable only that instead of all filtering. Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/cmd.c | 9 --------- drivers/net/wireless/ti/wl1251/main.c | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c index d14d69d733a0..6822b845efc1 100644 --- a/drivers/net/wireless/ti/wl1251/cmd.c +++ b/drivers/net/wireless/ti/wl1251/cmd.c @@ -277,15 +277,6 @@ int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, join->rx_config_options = wl->rx_config; join->rx_filter_options = wl->rx_filter; - /* - * FIXME: disable temporarily all filters because after commit - * 9cef8737 "mac80211: fix managed mode BSSID handling" broke - * association. The filter logic needs to be implemented properly - * and once that is done, this hack can be removed. - */ - join->rx_config_options = 0; - join->rx_filter_options = WL1251_DEFAULT_RX_FILTER; - join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index ff60a7a341be..6094e3f9e2f8 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -334,6 +334,12 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, if (ret < 0) goto out; + /* + * Join command applies filters, and if we are not associated, + * BSSID filter must be disabled for association to work. + */ + if (is_zero_ether_addr(wl->bssid)) + wl->rx_config &= ~CFG_BSSID_FILTER_EN; ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval, dtim_period); -- GitLab From 84b60c144cd32db5ca5185405e9b3f84cac9df9a Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:31:50 +0300 Subject: [PATCH 2240/6849] wl1251: send filters to firmware as they are set Firmware supports changing filters using ACX_RX_CFG command, so use it in .configure_filter callback. Firmware also supports probe request filtering, so add it too along the way. This will also re-enable BSSID filter which is now removed by join command while associating. Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/main.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 6094e3f9e2f8..3118c425bcf1 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -659,13 +659,15 @@ out: FIF_FCSFAIL | \ FIF_BCN_PRBRESP_PROMISC | \ FIF_CONTROL | \ - FIF_OTHER_BSS) + FIF_OTHER_BSS | \ + FIF_PROBE_REQ) static void wl1251_op_configure_filter(struct ieee80211_hw *hw, unsigned int changed, unsigned int *total,u64 multicast) { struct wl1251 *wl = hw->priv; + int ret; wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter"); @@ -676,7 +678,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, /* no filters which we support changed */ return; - /* FIXME: wl->rx_config and wl->rx_filter are not protected */ + mutex_lock(&wl->mutex); wl->rx_config = WL1251_DEFAULT_RX_CONFIG; wl->rx_filter = WL1251_DEFAULT_RX_FILTER; @@ -699,8 +701,25 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, } if (*total & FIF_CONTROL) wl->rx_filter |= CFG_RX_CTL_EN; - if (*total & FIF_OTHER_BSS) - wl->rx_filter &= ~CFG_BSSID_FILTER_EN; + if (*total & FIF_OTHER_BSS || is_zero_ether_addr(wl->bssid)) + wl->rx_config &= ~CFG_BSSID_FILTER_EN; + if (*total & FIF_PROBE_REQ) + wl->rx_filter |= CFG_RX_PREQ_EN; + + if (wl->state == WL1251_STATE_OFF) + goto out; + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + /* send filters to firmware */ + wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); + + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); } /* HW encryption */ -- GitLab From 305dd09f8ce05cc8a8cce4e790a6d3d02e5c4f1d Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Date: Mon, 18 Jun 2012 11:36:58 +0530 Subject: [PATCH 2241/6849] ath9k: fix incorrect profile type manupulation Two MCI interrupts are generated while adding A2DP and headset profiles with different types and same connection handle. While disconnecting, only one MCI interrupt is generated with last added profile type value for both profiles. While adding second profile type decrement first one. Signed-off-by: Bala Shanmugam Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mci.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 7d34a504d617..c40e568b5c2b 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -233,8 +233,21 @@ static void ath_mci_process_profile(struct ath_softc *sc, struct ath_mci_profile_info *entry = NULL; entry = ath_mci_find_profile(mci, info); - if (entry) + if (entry) { + /* + * Two MCI interrupts are generated while connecting to + * headset and A2DP profile, but only one MCI interrupt + * is generated with last added profile type while disconnecting + * both profiles. + * So while adding second profile type decrement + * the first one. + */ + if (entry->type != info->type) { + DEC_PROF(mci, entry); + INC_PROF(mci, info); + } memcpy(entry, info, 10); + } if (info->start) { if (!entry && !ath_mci_add_profile(common, mci, info)) -- GitLab From a68807e9177a083dc09c24b141158539d71db21c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 18 Jun 2012 19:02:37 +0530 Subject: [PATCH 2242/6849] ath9k_hw: fix BT mute at hw init WLAN driver initialization is muting BT which is terminating the ongoing BT traffic. The reason to mute BT is to avoid any incoming MCI messages from BT when MCI reset is in progress that could corrupt WLAN MCI RX state machine. But we should not dedicate radio completely to WLAN in driver init itself. So this patch removes the wlan weightage changes from mute BT to retain BT connection. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 4 ---- drivers/net/wireless/ath/ath9k/reg.h | 4 ---- 2 files changed, 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index cc2853ade8f8..867238f9d139 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -767,10 +767,6 @@ static void ar9003_mci_mute_bt(struct ath_hw *ah) { /* disable all MCI messages */ REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff); REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); /* wait pending HW messages to flush out */ diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 75acefbd4937..5046b282a93c 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -2162,10 +2162,6 @@ enum { #define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000 #define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31 -#define AR_BTCOEX_WL_WEIGHTS0 0x18b0 -#define AR_BTCOEX_WL_WEIGHTS1 0x18b4 -#define AR_BTCOEX_WL_WEIGHTS2 0x18b8 -#define AR_BTCOEX_WL_WEIGHTS3 0x18bc #define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2)) #define AR_BTCOEX_WL_LNA 0x1940 #define AR_BTCOEX_RFGAIN_CTRL 0x1944 -- GitLab From e1ecad78e5c5c32f331925f340141a38aaa64cef Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 18 Jun 2012 19:02:38 +0530 Subject: [PATCH 2243/6849] ath9k: fix mci_is_enabled utility During driver stop, btcoex is disabled and also btcoex_hw.enabled is set to false. Afterwards mci_is_enabled returns false so that BT is not gaining SPDT control on WLAN sleep. Fix that. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b49e4b48f459..94096607cbdd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1030,7 +1030,8 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) } static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) { - return ah->btcoex_hw.enabled && (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); + return ah->common.btcoex_enabled && + (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); } void ath9k_hw_btcoex_enable(struct ath_hw *ah); -- GitLab From 0967d862315366e2ef2401301ff2b1756928b4c1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 18 Jun 2012 19:02:39 +0530 Subject: [PATCH 2244/6849] ath9k_hw: update ar9462 dac_async_fifo initval Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 8f406ff2c95e..bbf48918a56c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -61,7 +61,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x013187c0, 0x013187c4, 0x013187c4, 0x013187c0}, + {0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0}, {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, -- GitLab From 4ff6a9d200c66f192da61822c36ad14424e218d6 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 18 Jun 2012 19:02:40 +0530 Subject: [PATCH 2245/6849] ath9k_hw: fix LNA control on WLAN sleep When WLAN enter full sleep mode, WLAN HW should send out a LNA_TAKE message for BT to take control of the shared LNA. Otherwise BT traffic is completely stopped whenever the wlan interface is moved full sleep mode. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 867238f9d139..61558375bfbf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -1015,9 +1015,14 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) return; if (mci->is_2g) { - ar9003_mci_send_2g5g_status(ah, true); + if (!force) { + ar9003_mci_send_2g5g_status(ah, true); - REG_SET_BIT(ah, AR_MCI_TX_CTRL, + ar9003_mci_send_lna_transfer(ah, true); + udelay(5); + } + + REG_CLR_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); @@ -1025,6 +1030,11 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) ar9003_mci_osla_setup(ah, true); } else { + if (!force) { + ar9003_mci_send_lna_take(ah, true); + udelay(5); + } + REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, @@ -1251,6 +1261,9 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n"); + ar9003_mci_send_lna_take(ah, true); + udelay(50); + REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); mci->is_2g = false; mci->update_2g5g = true; -- GitLab From 5039f38e16695a0a5c72b08c6a6cc66844a657b1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 19 Jun 2012 14:50:28 +0530 Subject: [PATCH 2246/6849] ath9k: do not sampling on ani timer when chip is in sleep The baseband and cycle counters are being sampled during ani processing for debugging purpose. Whenever the ani is postponded due to sleep state, taking samples on that time is of no use and also unneccesarily waking up the chip might increase the power consumption on idle associated state. Hence moving debug function within powersave block. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index a105c9426251..91650fe50461 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -407,6 +407,7 @@ void ath_ani_calibrate(unsigned long data) longcal ? "long" : "", shortcal ? "short" : "", aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); + ath9k_debug_samp_bb_mac(sc); ath9k_ps_restore(sc); set_timer: @@ -415,7 +416,6 @@ set_timer: * The interval must be the shortest necessary to satisfy ANI, * short calibration and long calibration. */ - ath9k_debug_samp_bb_mac(sc); cal_interval = ATH_LONG_CALINTERVAL; if (sc->sc_ah->config.enable_ani) cal_interval = min(cal_interval, -- GitLab From f761b6947dde42890beea59b020e1be87491809e Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 20 Jun 2012 11:47:26 -0500 Subject: [PATCH 2247/6849] rtlwifi: rtl8192se: Fix gcc 4.7.x warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc 4.7.x, the following warning is issued as the routine that sets the array has the possibility of not initializing the values: CC [M] drivers/net/wireless/rtlwifi/rtl8192se/phy.o drivers/net/wireless/rtlwifi/rtl8192se/phy.c: In function ‘rtl92s_phy_set_txpower’: drivers/net/wireless/rtlwifi/rtl8192se/phy.c:1268:23: warning: ‘ofdmpowerLevel[0]’ may be used uninitialized in this function [-Wuninitialized] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 8d7099bc472c..b917a2a3caf7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1247,6 +1247,9 @@ static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel, /* Read HT 40 OFDM TX power */ ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index]; ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index]; + } else { + ofdmpowerLevel[0] = 0; + ofdmpowerLevel[1] = 0; } } -- GitLab From 005c3b13e543af4c9d0b5d18473f48184eae6f07 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Jun 2012 12:53:58 -0700 Subject: [PATCH 2248/6849] Staging: csr: provide a MODULE_LICENSE for csr_helper.ko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I forgot a license for the csr_helper module, so it would not properly load as it depends on other GPL-only symbols. Reported-by: Lauri Hintsala Cc: Mikko Virkkilä Cc: Riku Mettälä Cc: Veli-Pekka Peltola Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/csr/csr_util.c b/drivers/staging/csr/csr_util.c index 939c87c638a1..ee2d0475781b 100644 --- a/drivers/staging/csr/csr_util.c +++ b/drivers/staging/csr/csr_util.c @@ -437,3 +437,7 @@ CsrBool CsrIsSpace(CsrUint8 c) return FALSE; } } + +MODULE_DESCRIPTION("CSR Operating System Kernel Abstraction"); +MODULE_AUTHOR("Cambridge Silicon Radio Ltd."); +MODULE_LICENSE("GPL and additional rights"); -- GitLab From 8cb8aad7d34cdc82fe205905c8dff771efb9604d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 19 Jun 2012 10:17:43 +0100 Subject: [PATCH 2249/6849] staging: comedi: make class and file operations static A couple of global variables in "comedi_fops.c" are only referenced from that .c file and can be declared 'static'. Also remove them from "comedi_fops.h" where they are declared 'extern'. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 4 ++-- drivers/staging/comedi/comedi_fops.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index ad8634734194..3650753b62f7 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2182,7 +2182,7 @@ static int comedi_fasync(int fd, struct file *file, int on) return fasync_helper(fd, file, on, &dev->async_queue); } -const struct file_operations comedi_fops = { +static const struct file_operations comedi_fops = { .owner = THIS_MODULE, .unlocked_ioctl = comedi_unlocked_ioctl, .compat_ioctl = comedi_compat_ioctl, @@ -2196,7 +2196,7 @@ const struct file_operations comedi_fops = { .llseek = noop_llseek, }; -struct class *comedi_class; +static struct class *comedi_class; static struct cdev comedi_cdev; static void comedi_cleanup_legacy_minors(void) diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h index 006cf14c577a..d59a29300f31 100644 --- a/drivers/staging/comedi/comedi_fops.h +++ b/drivers/staging/comedi/comedi_fops.h @@ -3,8 +3,6 @@ #define _COMEDI_FOPS_H #include -extern struct class *comedi_class; -extern const struct file_operations comedi_fops; extern bool comedi_autoconfig; extern struct comedi_driver *comedi_drivers; -- GitLab From 3a5fa27516116352e810b2122afd82c3d5cbcc7e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 19 Jun 2012 10:17:44 +0100 Subject: [PATCH 2250/6849] staging: comedi: rename internal.h to comedi_internal.h Use a less generic name for this internal header file included by various parts of the comedi core. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 2 +- drivers/staging/comedi/{internal.h => comedi_internal.h} | 0 drivers/staging/comedi/drivers.c | 2 +- drivers/staging/comedi/range.c | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename drivers/staging/comedi/{internal.h => comedi_internal.h} (100%) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 3650753b62f7..1079b0e7a264 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -49,7 +49,7 @@ #include #include -#include "internal.h" +#include "comedi_internal.h" MODULE_AUTHOR("http://www.comedi.org"); MODULE_DESCRIPTION("Comedi core module"); diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/comedi_internal.h similarity index 100% rename from drivers/staging/comedi/internal.h rename to drivers/staging/comedi/comedi_internal.h diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index bac3bc11d519..fe455e786ee4 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -45,7 +45,7 @@ #include #include "comedidev.h" -#include "internal.h" +#include "comedi_internal.h" static int postconfig(struct comedi_device *dev); static int insn_rw_emulate_bits(struct comedi_device *dev, diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 148ec6fd6fdd..41f95237789d 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -23,7 +23,7 @@ #include #include "comedidev.h" -#include "internal.h" +#include "comedi_internal.h" const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} }; EXPORT_SYMBOL(range_bipolar10); -- GitLab From 97ce84de8c19823ab0377a7ffc7fa25a8caa6ab8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 19 Jun 2012 10:17:45 +0100 Subject: [PATCH 2251/6849] staging: comedi: comedi_internal.h inclusion guards Add a multiple inclusion guard macro to "comedi_internal.h". Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_internal.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index 7ed20a04eef5..b004963a3d63 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -1,3 +1,6 @@ +#ifndef _COMEDI_INTERNAL_H +#define _COMEDI_INTERNAL_H + /* * various internal comedi stuff */ @@ -14,3 +17,5 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, extern unsigned int comedi_default_buf_size_kb; extern unsigned int comedi_default_buf_maxsize_kb; + +#endif /* _COMEDI_INTERNAL_H */ -- GitLab From f286766e4ba899043714471a0a2c9f1474d2ab5c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 19 Jun 2012 10:17:46 +0100 Subject: [PATCH 2252/6849] staging: comedi: remove comedi_fops.h Move the contents of "comedi_fops.h" into "comedi_internal.h" and delete "comedi_fops.h". It only contains a couple of external variable declarations (and #include ) and one of those isn't even declared in "comedi_fops.c". The other one is an external declaration of a variable used to store a module parameter and some of those are already externally declared in "comedi_internal.h", so they can keep it company! Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 1 - drivers/staging/comedi/comedi_fops.h | 9 --------- drivers/staging/comedi/comedi_internal.h | 4 ++++ drivers/staging/comedi/drivers.c | 1 - drivers/staging/comedi/proc.c | 2 +- 5 files changed, 5 insertions(+), 12 deletions(-) delete mode 100644 drivers/staging/comedi/comedi_fops.h diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 1079b0e7a264..e82126407e95 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -24,7 +24,6 @@ #undef DEBUG #define __NO_VERSION__ -#include "comedi_fops.h" #include "comedi_compat32.h" #include diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h deleted file mode 100644 index d59a29300f31..000000000000 --- a/drivers/staging/comedi/comedi_fops.h +++ /dev/null @@ -1,9 +0,0 @@ - -#ifndef _COMEDI_FOPS_H -#define _COMEDI_FOPS_H -#include - -extern bool comedi_autoconfig; -extern struct comedi_driver *comedi_drivers; - -#endif /* _COMEDI_FOPS_H */ diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index b004963a3d63..e70ef0515d9a 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -1,6 +1,8 @@ #ifndef _COMEDI_INTERNAL_H #define _COMEDI_INTERNAL_H +#include + /* * various internal comedi stuff */ @@ -17,5 +19,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, extern unsigned int comedi_default_buf_size_kb; extern unsigned int comedi_default_buf_maxsize_kb; +extern bool comedi_autoconfig; +extern struct comedi_driver *comedi_drivers; #endif /* _COMEDI_INTERNAL_H */ diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index fe455e786ee4..c0fdb00783ed 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -24,7 +24,6 @@ #define _GNU_SOURCE #define __NO_VERSION__ -#include "comedi_fops.h" #include #include #include diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index 2aa487b60187..bb7e70e3e94a 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -30,7 +30,7 @@ #define __NO_VERSION__ #include "comedidev.h" -#include "comedi_fops.h" +#include "comedi_internal.h" #include #include -- GitLab From 66f9311381b4772003d595fb6c518f1647450db0 Mon Sep 17 00:00:00 2001 From: Alain Renaud Date: Fri, 8 Jun 2012 15:34:46 -0400 Subject: [PATCH 2253/6849] xfs: xfs_vm_writepage clear iomap_valid when !buffer_uptodate (REV2) On filesytems with a block size smaller than PAGE_SIZE we currently have a problem with unwritten extents. If a we have multi-block page for which an unwritten extent has been allocated, and only some of the buffers have been written to, and they are not contiguous, we can expose stale data from disk in the blocks between the writes after extent conversion. Example of a page with unwritten and real data. buffer content 0 empty b_state = 0 1 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten 2 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten 3 empty b_state = 0 4 empty b_state = 0 5 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten 6 DATA b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten 7 empty b_state = 0 Buffers 1, 2, 5, and 6 have been written to, leaving 0, 3, 4, and 7 empty. Currently buffers 1, 2, 5, and 6 are added to a single ioend, and when IO has completed, extent conversion creates a real extent from block 1 through block 6, leaving 0 and 7 unwritten. However buffers 3 and 4 were not written to disk, so stale data is exposed from those blocks on a subsequent read. Fix this by setting iomap_valid = 0 when we find a buffer that is not Uptodate. This ensures that buffers 5 and 6 are not added to the same ioend as buffers 1 and 2. Later these blocks will be converted into two separate real extents, leaving the blocks in between unwritten. Signed-off-by: Alain Renaud Reviewed-by: Dave Chinner Signed-off-by: Ben Myers --- fs/xfs/xfs_aops.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index ae31c313a79e..8dad722c0041 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -981,10 +981,15 @@ xfs_vm_writepage( imap_valid = 0; } } else { - if (PageUptodate(page)) { + if (PageUptodate(page)) ASSERT(buffer_mapped(bh)); - imap_valid = 0; - } + /* + * This buffer is not uptodate and will not be + * written to disk. Ensure that we will put any + * subsequent writeable buffers into a new + * ioend. + */ + imap_valid = 0; continue; } -- GitLab From 00d20c64a19bc57816d85e3e8f72ff0b8d325d5e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 19 Jun 2012 10:58:16 +0100 Subject: [PATCH 2254/6849] staging: comedi: shrink comedi_compat32.h "comedi_compat32.h" #include's , but that is only needed by "comedi_compat32.c" so move the #include to that file. Also, "comedi_compat.h" doesn't really need the '#include ' just to declare 'struct file' as it only uses it to construct a pointer to that type. Replace that #include with an incomplete declaration of 'struct file' and move that #include into "comedi_compat32.c". Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_compat32.c | 2 ++ drivers/staging/comedi/comedi_compat32.h | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index 41a7a62ba49a..0a5057f0919b 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -26,6 +26,8 @@ #define __NO_VERSION__ #include +#include +#include #include "comedi.h" #include "comedi_compat32.h" diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h index c99573be046a..60cf51c4a793 100644 --- a/drivers/staging/comedi/comedi_compat32.h +++ b/drivers/staging/comedi/comedi_compat32.h @@ -27,11 +27,9 @@ #ifndef _COMEDI_COMPAT32_H #define _COMEDI_COMPAT32_H -#include -#include - #ifdef CONFIG_COMPAT +struct file; extern long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -- GitLab From 3b876c8f2a361ceeed3fed894980c69066f903a0 Mon Sep 17 00:00:00 2001 From: Jeff Liu Date: Thu, 7 Jun 2012 15:44:32 +0800 Subject: [PATCH 2255/6849] xfs: fix debug_object WARN at xfs_alloc_vextent() Fengguang reports: [ 780.529603] XFS (vdd): Ending clean mount [ 781.454590] ODEBUG: object is on stack, but not annotated [ 781.455433] ------------[ cut here ]------------ [ 781.455433] WARNING: at /c/kernel-tests/sound/lib/debugobjects.c:301 __debug_object_init+0x173/0x1f1() [ 781.455433] Hardware name: Bochs [ 781.455433] Modules linked in: [ 781.455433] Pid: 26910, comm: kworker/0:2 Not tainted 3.4.0+ #51 [ 781.455433] Call Trace: [ 781.455433] [] warn_slowpath_common+0x83/0x9b [ 781.455433] [] warn_slowpath_null+0x1a/0x1c [ 781.455433] [] __debug_object_init+0x173/0x1f1 [ 781.455433] [] debug_object_init+0x14/0x16 [ 781.455433] [] __init_work+0x20/0x22 [ 781.455433] [] xfs_alloc_vextent+0x6c/0xd5 Use INIT_WORK_ONSTACK in xfs_alloc_vextent instead of INIT_WORK. Reported-by: Wu Fengguang Signed-off-by: Jie Liu Signed-off-by: Ben Myers --- fs/xfs/xfs_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 229641fb8e67..a996e398692b 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -2441,7 +2441,7 @@ xfs_alloc_vextent( DECLARE_COMPLETION_ONSTACK(done); args->done = &done; - INIT_WORK(&args->work, xfs_alloc_vextent_worker); + INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); queue_work(xfs_alloc_wq, &args->work); wait_for_completion(&done); return args->result; -- GitLab From a3b0eee21be14e1d2b6a7b97c70a94ee76aaf0b3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 19 Jun 2012 16:20:05 -0700 Subject: [PATCH 2256/6849] staging: comedi: Kconfig: fix drivers that require the 8255 driver Many of the comedi drivers require the 8255 driver for various subdevice support. The Makefile currently uses CONFIG_COMEDI_PCI_DRIVERS to make sure the 8255 driver is compiled. The Kconfig help for that option says that it does not directly affect the kernel. Fix this by adding 'select COMEDI_8255' to the drivers that actually need the support. Also, remove two cases where the drivers don't require the 8255 support. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 3 +-- drivers/staging/comedi/drivers/Makefile | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 2ca7f08bc5b9..03ee2d0e188b 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -672,7 +672,6 @@ config COMEDI_ADDI_APCI_3XXX config COMEDI_ADL_PCI6208 tristate "ADLink PCI-6208A support" - select COMEDI_8255 ---help--- Enable support for ADLink PCI-6208A cards @@ -689,6 +688,7 @@ config COMEDI_ADL_PCI7230 config COMEDI_ADL_PCI7296 tristate "ADLink PCI-7296 96 ch. digital io board support" + select COMEDI_8255 ---help--- Enable support for ADlink PCI-7296 96 ch. digital io board support @@ -1061,7 +1061,6 @@ config COMEDI_NI_PCIMIO config COMEDI_RTD520 tristate "Real Time Devices PCI4520/DM7520 support" - select COMEDI_8255 ---help--- Enable support for Real Time Devices PCI4520/DM7520 diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 170da6091959..513469d943bf 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -55,7 +55,6 @@ obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o obj-$(CONFIG_COMEDI_POC) += poc.o # Comedi PCI drivers -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o -- GitLab From d4d3c4e676769dbabb0289f1a893854907950b65 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 19 Jun 2012 16:20:17 -0700 Subject: [PATCH 2257/6849] staging: comedi: remove unused CONFIG_COMEDI_PCMCIA define CONFIG_COMEDI_PCMCIA is not actually a Kconfig option. It is defined in the comedidev.h header based on another Kconfig option being enbled. Just remove it since the define is not used by any of the comedi drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 7363fd81cc7f..3bc97ad48593 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -513,11 +513,5 @@ void comedi_usb_auto_unconfig(struct usb_interface *intf); #ifdef CONFIG_COMEDI_PCI_DRIVERS_MODULE #define CONFIG_COMEDI_PCI #endif -#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS -#define CONFIG_COMEDI_PCMCIA -#endif -#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS_MODULE -#define CONFIG_COMEDI_PCMCIA -#endif #endif /* _COMEDIDEV_H */ -- GitLab From 928ae0956d8a3b26c3908c4bc97973cba36030a3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 19 Jun 2012 16:20:23 -0700 Subject: [PATCH 2258/6849] staging: comedi: remove CONFIG_COMEDI_PCI define CONFIG_COMEDI_PCI is not actually a Kconfig option. It is defined in the comedidev.h header based on another Kconfig option being enabled. It is only referenced in the skel driver to conditionally compile in the PCI support code. Use the CONFIG_COMEDI_PCI_DRIVERS Kconfig option instead and remove the define. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 7 ------- drivers/staging/comedi/drivers/skel.c | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 3bc97ad48593..de8c99c34070 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -507,11 +507,4 @@ int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver); void comedi_usb_auto_unconfig(struct usb_interface *intf); -#ifdef CONFIG_COMEDI_PCI_DRIVERS -#define CONFIG_COMEDI_PCI -#endif -#ifdef CONFIG_COMEDI_PCI_DRIVERS_MODULE -#define CONFIG_COMEDI_PCI -#endif - #endif /* _COMEDIDEV_H */ diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 6baac525f434..9a68eebefca0 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -611,7 +611,7 @@ static int skel_dio_insn_config(struct comedi_device *dev, return insn->n; } -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS static int __devinit driver_skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { -- GitLab From 64be096d0f32e21b7e6824bb3c937bdf0b56f38c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 19 Jun 2012 16:20:28 -0700 Subject: [PATCH 2259/6849] staging: comedi: Kconfig: menuconfig options should be bool The menuconfig options to enable the various comedi driver types should be bool not tristate. They don't directly affect the building of the kernel, they just allow other options to be selected. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 03ee2d0e188b..974c668ff62b 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -33,7 +33,7 @@ config COMEDI_DEFAULT_BUF_MAXSIZE_KB channels running at 100 kHz has 2-4 seconds of buffer. menuconfig COMEDI_MISC_DRIVERS - tristate "Comedi misc drivers" + bool "Comedi misc drivers" ---help--- Enable comedi misc drivers to be built @@ -100,7 +100,7 @@ config COMEDI_SKEL endif # COMEDI_MISC_DRIVERS menuconfig COMEDI_ISA_DRIVERS - tristate "Comedi ISA and PC/104 drivers" + bool "Comedi ISA and PC/104 drivers" depends on ISA ---help--- Enable comedi ISA and PC/104 drivers to be built @@ -540,7 +540,7 @@ config COMEDI_POC endif # COMEDI_ISA_DRIVERS menuconfig COMEDI_PCI_DRIVERS - tristate "Comedi PCI drivers" + bool "Comedi PCI drivers" depends on PCI ---help--- Enable comedi PCI drivers to be built @@ -1095,7 +1095,7 @@ config COMEDI_SSV_DNP endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS - tristate "Comedi PCMCIA drivers" + bool "Comedi PCMCIA drivers" depends on PCMCIA ---help--- Enable comedi PCMCIA and PCCARD drivers to be built @@ -1178,7 +1178,7 @@ config COMEDI_QUATECH_DAQP_CS endif # COMEDI_PCMCIA_DRIVERS menuconfig COMEDI_USB_DRIVERS - tristate "Comedi USB drivers" + bool "Comedi USB drivers" depends on USB ---help--- Enable comedi USB drivers to be built -- GitLab From 9c3db14239a5d7d813ed12945581378b70271060 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 19 Jun 2012 16:20:31 -0700 Subject: [PATCH 2260/6849] staging: comedi: Kconfig: remove redundant depends on tests The 'depends on COMEDI_ISA_DRIVERS' for COMEDI_AMPLC_DIO200_ISA is not needed. This option is alread in an if/endif block that will satisy the check. The 'depends on COMEDI' for COMEDI_NI_COMMON was missed when all the comedi options were wrapped in an if/endif block. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 974c668ff62b..04155202991c 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -213,7 +213,6 @@ config COMEDI_PCM3730 config COMEDI_AMPLC_DIO200_ISA tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E" select COMEDI_AMPLC_DIO200 - depends on COMEDI_ISA_DRIVERS ---help--- Enable support for Amplicon PC212E, PC214E, PC215E, PC218E and PC272E ISA DIO boards @@ -1236,7 +1235,6 @@ endif # COMEDI_USB_DRIVERS menuconfig COMEDI_NI_COMMON tristate "Comedi National Instruments card support" - depends on COMEDI ---help--- Enable comedi support for National Instruments cards. Modules in this section are used by many comedi NI drivers. -- GitLab From 42318c32f8c968d602d151ad81e567832b72b767 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:00:57 -0700 Subject: [PATCH 2261/6849] staging: comedi: usbdux: use module_comedi_usb_driver() Use the module_comedi_usb_driver helper macro to initialize this module. Rename the driver structs to follow the pattern of the other comedi driver types and add some whitespace to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 50 +++++++------------------ 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 83ee66965427..586936bc420b 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -317,7 +317,7 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); -static struct comedi_driver driver_usbdux; /* see below for initializer */ +static struct comedi_driver usbdux_driver; /* see below for initializer */ /* * Stops the data acquision @@ -2323,7 +2323,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(uinterf, &driver_usbdux); + comedi_usb_auto_config(uinterf, &usbdux_driver); out: release_firmware(fw); } @@ -2832,12 +2832,12 @@ static void usbdux_detach(struct comedi_device *dev) } /* main driver struct */ -static struct comedi_driver driver_usbdux = { - .driver_name = "usbdux", - .module = THIS_MODULE, - .attach = usbdux_attach, - .detach = usbdux_detach, - .attach_usb = usbdux_attach_usb, +static struct comedi_driver usbdux_driver = { + .driver_name = "usbdux", + .module = THIS_MODULE, + .attach = usbdux_attach, + .detach = usbdux_detach, + .attach_usb = usbdux_attach_usb, }; /* Table with the USB-devices: just now only testing IDs */ @@ -2849,35 +2849,13 @@ static const struct usb_device_id usbduxsub_table[] = { MODULE_DEVICE_TABLE(usb, usbduxsub_table); -/* The usbduxsub-driver */ -static struct usb_driver usbduxsub_driver = { - .name = BOARDNAME, - .probe = usbduxsub_probe, - .disconnect = usbduxsub_disconnect, - .id_table = usbduxsub_table, +static struct usb_driver usbdux_usb_driver = { + .name = BOARDNAME, + .probe = usbduxsub_probe, + .disconnect = usbduxsub_disconnect, + .id_table = usbduxsub_table, }; - -/* Can't use the nice macro as I have also to initialise the USB */ -/* subsystem: */ -/* registering the usb-system _and_ the comedi-driver */ -static int __init init_usbdux(void) -{ - printk(KERN_INFO KBUILD_MODNAME ": " - DRIVER_VERSION ":" DRIVER_DESC "\n"); - usb_register(&usbduxsub_driver); - comedi_driver_register(&driver_usbdux); - return 0; -} - -/* deregistering the comedi driver and the usb-subsystem */ -static void __exit exit_usbdux(void) -{ - comedi_driver_unregister(&driver_usbdux); - usb_deregister(&usbduxsub_driver); -} - -module_init(init_usbdux); -module_exit(exit_usbdux); +module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -- GitLab From cb9513adb2054c7a769d938cb519a437ad4f2b10 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:01:14 -0700 Subject: [PATCH 2262/6849] staging: comedi: usbduxfast: use module_comedi_usb_driver() Use the module_comedi_usb_driver helper macro to initialize this module. Rename the driver structs to follow the pattern of the other comedi driver types and add some whitespace to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 57 ++++++--------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index c71362086cdf..8c8e4ec9f358 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -196,7 +196,7 @@ static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST]; static DEFINE_SEMAPHORE(start_stop_sem); -static struct comedi_driver driver_usbduxfast; /* see below for initializer */ +static struct comedi_driver usbduxfast_driver; /* see below for initializer */ /* * bulk transfers to usbduxfast @@ -1458,7 +1458,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware goto out; } - comedi_usb_auto_config(uinterf, &driver_usbduxfast); + comedi_usb_auto_config(uinterf, &usbduxfast_driver); out: release_firmware(fw); } @@ -1757,12 +1757,12 @@ static void usbduxfast_detach(struct comedi_device *dev) /* * main driver struct */ -static struct comedi_driver driver_usbduxfast = { - .driver_name = "usbduxfast", - .module = THIS_MODULE, - .attach = usbduxfast_attach, - .detach = usbduxfast_detach, - .attach_usb = usbduxfast_attach_usb, +static struct comedi_driver usbduxfast_driver = { + .driver_name = "usbduxfast", + .module = THIS_MODULE, + .attach = usbduxfast_attach, + .detach = usbduxfast_detach, + .attach_usb = usbduxfast_attach_usb, }; /* @@ -1777,43 +1777,16 @@ static const struct usb_device_id usbduxfastsub_table[] = { MODULE_DEVICE_TABLE(usb, usbduxfastsub_table); -/* - * The usbduxfastsub-driver - */ -static struct usb_driver usbduxfastsub_driver = { +static struct usb_driver usbduxfast_usb_driver = { #ifdef COMEDI_HAVE_USB_DRIVER_OWNER - .owner = THIS_MODULE, + .owner = THIS_MODULE, #endif - .name = BOARDNAME, - .probe = usbduxfastsub_probe, - .disconnect = usbduxfastsub_disconnect, - .id_table = usbduxfastsub_table + .name = BOARDNAME, + .probe = usbduxfastsub_probe, + .disconnect = usbduxfastsub_disconnect, + .id_table = usbduxfastsub_table, }; - -/* - * Can't use the nice macro as I have also to initialise the USB subsystem: - * registering the usb-system _and_ the comedi-driver - */ -static int __init init_usbduxfast(void) -{ - printk(KERN_INFO - KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n"); - usb_register(&usbduxfastsub_driver); - comedi_driver_register(&driver_usbduxfast); - return 0; -} - -/* - * deregistering the comedi driver and the usb-subsystem - */ -static void __exit exit_usbduxfast(void) -{ - comedi_driver_unregister(&driver_usbduxfast); - usb_deregister(&usbduxfastsub_driver); -} - -module_init(init_usbduxfast); -module_exit(exit_usbduxfast); +module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -- GitLab From b7418f4524a830747a16f41b728075dca6e2cca3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:01:27 -0700 Subject: [PATCH 2263/6849] staging: comedi: usbduxsigma: use module_comedi_usb_driver() Use the module_comedi_usb_driver helper macro to initialize this module. Rename the driver structs to follow the pattern of the other comedi driver types and add some whitespace to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 49 ++++++-------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 28f41e9cf682..e4308823cf68 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -267,7 +267,7 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); -static struct comedi_driver driver_usbduxsigma; /* see below for initializer */ +static struct comedi_driver usbduxsigma_driver; /* see below for initializer */ /* * Stops the data acquision @@ -2331,7 +2331,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(uinterf, &driver_usbduxsigma); + comedi_usb_auto_config(uinterf, &usbduxsigma_driver); out: release_firmware(fw); } @@ -2828,12 +2828,12 @@ static void usbduxsigma_detach(struct comedi_device *dev) } /* main driver struct */ -static struct comedi_driver driver_usbduxsigma = { - .driver_name = "usbduxsigma", - .module = THIS_MODULE, - .attach = usbduxsigma_attach, - .detach = usbduxsigma_detach, - .attach_usb = usbduxsigma_attach_usb, +static struct comedi_driver usbduxsigma_driver = { + .driver_name = "usbduxsigma", + .module = THIS_MODULE, + .attach = usbduxsigma_attach, + .detach = usbduxsigma_detach, + .attach_usb = usbduxsigma_attach_usb, }; /* Table with the USB-devices */ @@ -2847,34 +2847,13 @@ static const struct usb_device_id usbduxsigma_table[] = { MODULE_DEVICE_TABLE(usb, usbduxsigma_table); /* The usbduxsub-driver */ -static struct usb_driver usbduxsigma_driver = { - .name = BOARDNAME, - .probe = usbduxsigma_probe, - .disconnect = usbduxsigma_disconnect, - .id_table = usbduxsigma_table, +static struct usb_driver usbduxsigma_usb_driver = { + .name = BOARDNAME, + .probe = usbduxsigma_probe, + .disconnect = usbduxsigma_disconnect, + .id_table = usbduxsigma_table, }; - -/* Can't use the nice macro as I have also to initialise the USB */ -/* subsystem: */ -/* registering the usb-system _and_ the comedi-driver */ -static int __init init_usbduxsigma(void) -{ - printk(KERN_INFO KBUILD_MODNAME ": " - DRIVER_VERSION ":" DRIVER_DESC "\n"); - usb_register(&usbduxsigma_driver); - comedi_driver_register(&driver_usbduxsigma); - return 0; -} - -/* deregistering the comedi driver and the usb-subsystem */ -static void __exit exit_usbduxsigma(void) -{ - comedi_driver_unregister(&driver_usbduxsigma); - usb_deregister(&usbduxsigma_driver); -} - -module_init(init_usbduxsigma); -module_exit(exit_usbduxsigma); +module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -- GitLab From d6cc3ec8e727de15ac59e7a184f9d51bf476147b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:01:44 -0700 Subject: [PATCH 2264/6849] staging: comedi: vmk80xx: use module_comedi_usb_driver() Use the module_comedi_usb_driver helper macro to initialize this module. Rename the driver structs to follow the pattern of the other comedi driver types and add some whitespace to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 50 +++++++----------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 7d3cb3a035e6..14fb50a49d44 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -232,7 +232,7 @@ static struct vmk80xx_usb vmb[VMK80XX_MAX_BOARDS]; static DEFINE_MUTEX(glb_mutex); -static struct comedi_driver driver_vmk80xx; /* see below for initializer */ +static struct comedi_driver vmk80xx_driver; /* see below for initializer */ static void vmk80xx_tx_callback(struct urb *urb) { @@ -1410,7 +1410,7 @@ static int vmk80xx_probe(struct usb_interface *intf, mutex_unlock(&glb_mutex); - comedi_usb_auto_config(intf, &driver_vmk80xx); + comedi_usb_auto_config(intf, &vmk80xx_driver); return 0; error: @@ -1449,40 +1449,18 @@ static void vmk80xx_disconnect(struct usb_interface *intf) /* TODO: Add support for suspend, resume, pre_reset, * post_reset and flush */ -static struct usb_driver vmk80xx_driver = { - .name = "vmk80xx", - .probe = vmk80xx_probe, - .disconnect = vmk80xx_disconnect, - .id_table = vmk80xx_id_table +static struct usb_driver vmk80xx_usb_driver = { + .name = "vmk80xx", + .probe = vmk80xx_probe, + .disconnect = vmk80xx_disconnect, + .id_table = vmk80xx_id_table }; -static struct comedi_driver driver_vmk80xx = { - .module = THIS_MODULE, - .driver_name = "vmk80xx", - .attach = vmk80xx_attach, - .detach = vmk80xx_detach, - .attach_usb = vmk80xx_attach_usb, +static struct comedi_driver vmk80xx_driver = { + .module = THIS_MODULE, + .driver_name = "vmk80xx", + .attach = vmk80xx_attach, + .detach = vmk80xx_detach, + .attach_usb = vmk80xx_attach_usb, }; - -static int __init vmk80xx_init(void) -{ - int retval; - - printk(KERN_INFO "vmk80xx: version 0.8.01 " - "Manuel Gebele \n"); - - retval = comedi_driver_register(&driver_vmk80xx); - if (retval < 0) - return retval; - - return usb_register(&vmk80xx_driver); -} - -static void __exit vmk80xx_exit(void) -{ - comedi_driver_unregister(&driver_vmk80xx); - usb_deregister(&vmk80xx_driver); -} - -module_init(vmk80xx_init); -module_exit(vmk80xx_exit); +module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver); -- GitLab From 007ff2af216090b4c20ebd2b9d94c528102ec135 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:01:57 -0700 Subject: [PATCH 2265/6849] staging: comedi: vmk80xx: refactor init code Refactor the usb driver probe/disconnect and comedi driver attach/ detach to follow the style of the other comedi driver types to improve maintainability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 79 +++++++++++------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 14fb50a49d44..94010fc05905 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -64,37 +64,11 @@ Changelog: #include "../comedidev.h" -#define BOARDNAME "vmk80xx" - -MODULE_AUTHOR("Manuel Gebele "); -MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver"); -MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140"); -MODULE_VERSION("0.8.01"); -MODULE_LICENSE("GPL"); - enum { DEVICE_VMK8055, DEVICE_VMK8061 }; -static const struct usb_device_id vmk80xx_id_table[] = { - {USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061}, - {} /* terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, vmk80xx_id_table); - #define VMK8055_DI_REG 0x00 #define VMK8055_DO_REG 0x01 #define VMK8055_AO1_REG 0x02 @@ -232,8 +206,6 @@ static struct vmk80xx_usb vmb[VMK80XX_MAX_BOARDS]; static DEFINE_MUTEX(glb_mutex); -static struct comedi_driver vmk80xx_driver; /* see below for initializer */ - static void vmk80xx_tx_callback(struct urb *urb) { struct vmk80xx_usb *dev = urb->context; @@ -1267,8 +1239,16 @@ static void vmk80xx_detach(struct comedi_device *dev) } } -static int vmk80xx_probe(struct usb_interface *intf, - const struct usb_device_id *id) +static struct comedi_driver vmk80xx_driver = { + .module = THIS_MODULE, + .driver_name = "vmk80xx", + .attach = vmk80xx_attach, + .detach = vmk80xx_detach, + .attach_usb = vmk80xx_attach_usb, +}; + +static int vmk80xx_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) { int i; struct vmk80xx_usb *dev; @@ -1419,7 +1399,7 @@ error: return -ENODEV; } -static void vmk80xx_disconnect(struct usb_interface *intf) +static void vmk80xx_usb_disconnect(struct usb_interface *intf) { struct vmk80xx_usb *dev = usb_get_intfdata(intf); @@ -1447,20 +1427,35 @@ static void vmk80xx_disconnect(struct usb_interface *intf) mutex_unlock(&glb_mutex); } +static const struct usb_device_id vmk80xx_usb_id_table[] = { + { USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055 }, + { USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055 }, + { USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055 }, + { USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055 }, + { USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061 }, + { USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061 }, + { } +}; +MODULE_DEVICE_TABLE(usb, vmk80xx_usb_id_table); + /* TODO: Add support for suspend, resume, pre_reset, * post_reset and flush */ static struct usb_driver vmk80xx_usb_driver = { .name = "vmk80xx", - .probe = vmk80xx_probe, - .disconnect = vmk80xx_disconnect, - .id_table = vmk80xx_id_table -}; - -static struct comedi_driver vmk80xx_driver = { - .module = THIS_MODULE, - .driver_name = "vmk80xx", - .attach = vmk80xx_attach, - .detach = vmk80xx_detach, - .attach_usb = vmk80xx_attach_usb, + .probe = vmk80xx_usb_probe, + .disconnect = vmk80xx_usb_disconnect, + .id_table = vmk80xx_usb_id_table, }; module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver); + +MODULE_AUTHOR("Manuel Gebele "); +MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver"); +MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140"); +MODULE_VERSION("0.8.01"); +MODULE_LICENSE("GPL"); -- GitLab From ab5455ae2d920b227afbf2f870f3253fc699b132 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:02:15 -0700 Subject: [PATCH 2266/6849] staging: comedi: usbduxsigma: refactor init code Refactor the usb driver probe/disconnect and comedi driver attach/ detach to follow the style of the other comedi driver types to improve maintainability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 450 +++++++++---------- 1 file changed, 219 insertions(+), 231 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index e4308823cf68..8da8c1cbb60a 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1,6 +1,3 @@ -#define DRIVER_VERSION "v0.6" -#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" -#define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com" /* comedi/drivers/usbdux.c Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com @@ -62,8 +59,6 @@ Status: testing #include "comedi_fc.h" #include "../comedidev.h" -#define BOARDNAME "usbduxsigma" - /* timeout for the USB-transfer in ms*/ #define BULK_TIMEOUT 1000 @@ -267,8 +262,6 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); -static struct comedi_driver usbduxsigma_driver; /* see below for initializer */ - /* * Stops the data acquision * It should be safe to call this function from any context @@ -2307,6 +2300,210 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_tmp->pwm_cmd_running = 0; } +/* common part of attach and attach_usb */ +static int usbduxsigma_attach_common(struct comedi_device *dev, + struct usbduxsub *uds, + void *aux_data, int aux_len) +{ + int ret; + struct comedi_subdevice *s; + int n_subdevs; + int offset; + + down(&uds->sem); + /* pointer back to the corresponding comedi device */ + uds->comedidev = dev; + /* trying to upload the firmware into the FX2 */ + if (aux_data) + firmwareUpload(uds, aux_data, aux_len); + dev->board_name = "usbduxsigma"; + /* set number of subdevices */ + if (uds->high_speed) + n_subdevs = 4; /* with pwm */ + else + n_subdevs = 3; /* without pwm */ + ret = comedi_alloc_subdevices(dev, n_subdevs); + if (ret) { + up(&uds->sem); + return ret; + } + /* private structure is also simply the usb-structure */ + dev->private = uds; + /* the first subdevice is the A/D converter */ + s = dev->subdevices + SUBDEV_AD; + /* the URBs get the comedi subdevice */ + /* which is responsible for reading */ + /* this is the subdevice which reads data */ + dev->read_subdev = s; + /* the subdevice receives as private structure the */ + /* usb-structure */ + s->private = NULL; + /* analog input */ + s->type = COMEDI_SUBD_AI; + /* readable and ref is to ground, 32 bit wide data! */ + s->subdev_flags = SDF_READABLE | SDF_GROUND | + SDF_CMD_READ | SDF_LSAMPL; + /* 16 A/D channels */ + s->n_chan = NUMCHANNELS; + /* length of the channellist */ + s->len_chanlist = NUMCHANNELS; + /* callback functions */ + s->insn_read = usbdux_ai_insn_read; + s->do_cmdtest = usbdux_ai_cmdtest; + s->do_cmd = usbdux_ai_cmd; + s->cancel = usbdux_ai_cancel; + /* max value from the A/D converter (24bit) */ + s->maxdata = 0x00FFFFFF; + /* range table to convert to physical units */ + s->range_table = (&range_usbdux_ai_range); + /* analog output subdevice */ + s = dev->subdevices + SUBDEV_DA; + /* analog out */ + s->type = COMEDI_SUBD_AO; + /* backward pointer */ + dev->write_subdev = s; + /* the subdevice receives as private structure the */ + /* usb-structure */ + s->private = NULL; + /* are writable */ + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; + /* 4 channels */ + s->n_chan = 4; + /* length of the channellist */ + s->len_chanlist = 4; + /* 8 bit resolution */ + s->maxdata = 0x00ff; + /* unipolar range */ + s->range_table = (&range_usbdux_ao_range); + /* callback */ + s->do_cmdtest = usbdux_ao_cmdtest; + s->do_cmd = usbdux_ao_cmd; + s->cancel = usbdux_ao_cancel; + s->insn_read = usbdux_ao_insn_read; + s->insn_write = usbdux_ao_insn_write; + /* digital I/O subdevice */ + s = dev->subdevices + SUBDEV_DIO; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + /* 8 external and 16 internal channels */ + s->n_chan = 24; + s->maxdata = 1; + s->range_table = (&range_digital); + s->insn_bits = usbdux_dio_insn_bits; + s->insn_config = usbdux_dio_insn_config; + /* we don't use it */ + s->private = NULL; + if (uds->high_speed) { + /* timer / pwm subdevice */ + s = dev->subdevices + SUBDEV_PWM; + s->type = COMEDI_SUBD_PWM; + s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; + s->n_chan = 8; + /* this defines the max duty cycle resolution */ + s->maxdata = uds->sizePwmBuf; + s->insn_write = usbdux_pwm_write; + s->insn_read = usbdux_pwm_read; + s->insn_config = usbdux_pwm_config; + usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); + } + /* finally decide that it's attached */ + uds->attached = 1; + up(&uds->sem); + offset = usbdux_getstatusinfo(dev, 0); + if (offset < 0) + dev_err(&uds->interface->dev, + "Communication to USBDUXSIGMA failed! Check firmware and cabling."); + dev_info(&uds->interface->dev, + "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset); + return 0; +} + +/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ +static int usbduxsigma_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int ret; + int index; + int i; + void *aux_data; + int aux_len; + + dev->private = NULL; + + aux_data = comedi_aux_data(it->options, 0); + aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; + if (aux_data == NULL) + aux_len = 0; + else if (aux_len == 0) + aux_data = NULL; + + down(&start_stop_sem); + /* find a valid device which has been detected by the probe function of + * the usb */ + index = -1; + for (i = 0; i < NUMUSBDUX; i++) { + if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { + index = i; + break; + } + } + if (index < 0) { + dev_err(dev->class_dev, + "usbduxsigma: error: attach failed, dev not connected to the usb bus.\n"); + up(&start_stop_sem); + ret = -ENODEV; + } else + ret = usbduxsigma_attach_common(dev, &usbduxsub[index], + aux_data, aux_len); + up(&start_stop_sem); + return ret; +} + +/* is called from comedi_usb_auto_config() */ +static int usbduxsigma_attach_usb(struct comedi_device *dev, + struct usb_interface *uinterf) +{ + int ret; + struct usbduxsub *uds; + + dev->private = NULL; + down(&start_stop_sem); + uds = usb_get_intfdata(uinterf); + if (!uds || !uds->probed) { + dev_err(dev->class_dev, + "usbduxsigma: error: attach_usb failed, not connected\n"); + ret = -ENODEV; + } else if (uds->attached) { + dev_err(dev->class_dev, + "usbduxsigma: error: attach_usb failed, already attached\n"); + ret = -ENODEV; + } else + ret = usbduxsigma_attach_common(dev, uds, NULL, 0); + up(&start_stop_sem); + return ret; +} + +static void usbduxsigma_detach(struct comedi_device *dev) +{ + struct usbduxsub *usb = dev->private; + + if (usb) { + down(&usb->sem); + dev->private = NULL; + usb->attached = 0; + usb->comedidev = NULL; + up(&usb->sem); + } +} + +static struct comedi_driver usbduxsigma_driver = { + .driver_name = "usbduxsigma", + .module = THIS_MODULE, + .attach = usbduxsigma_attach, + .detach = usbduxsigma_detach, + .attach_usb = usbduxsigma_attach_usb, +}; + static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { @@ -2336,9 +2533,8 @@ out: release_firmware(fw); } -/* allocate memory for the urbs and initialise them */ -static int usbduxsigma_probe(struct usb_interface *uinterf, - const struct usb_device_id *id) +static int usbduxsigma_usb_probe(struct usb_interface *uinterf, + const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(uinterf); struct device *dev = &uinterf->dev; @@ -2602,7 +2798,7 @@ static int usbduxsigma_probe(struct usb_interface *uinterf, return 0; } -static void usbduxsigma_disconnect(struct usb_interface *intf) +static void usbduxsigma_usb_disconnect(struct usb_interface *intf) { struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); @@ -2631,230 +2827,22 @@ static void usbduxsigma_disconnect(struct usb_interface *intf) dev_info(&intf->dev, "comedi_: disconnected from the usb\n"); } -/* common part of attach and attach_usb */ -static int usbduxsigma_attach_common(struct comedi_device *dev, - struct usbduxsub *uds, - void *aux_data, int aux_len) -{ - int ret; - struct comedi_subdevice *s; - int n_subdevs; - int offset; - - down(&uds->sem); - /* pointer back to the corresponding comedi device */ - uds->comedidev = dev; - /* trying to upload the firmware into the FX2 */ - if (aux_data) - firmwareUpload(uds, aux_data, aux_len); - dev->board_name = BOARDNAME; - /* set number of subdevices */ - if (uds->high_speed) - n_subdevs = 4; /* with pwm */ - else - n_subdevs = 3; /* without pwm */ - ret = comedi_alloc_subdevices(dev, n_subdevs); - if (ret) { - up(&uds->sem); - return ret; - } - /* private structure is also simply the usb-structure */ - dev->private = uds; - /* the first subdevice is the A/D converter */ - s = dev->subdevices + SUBDEV_AD; - /* the URBs get the comedi subdevice */ - /* which is responsible for reading */ - /* this is the subdevice which reads data */ - dev->read_subdev = s; - /* the subdevice receives as private structure the */ - /* usb-structure */ - s->private = NULL; - /* analog input */ - s->type = COMEDI_SUBD_AI; - /* readable and ref is to ground, 32 bit wide data! */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | - SDF_CMD_READ | SDF_LSAMPL; - /* 16 A/D channels */ - s->n_chan = NUMCHANNELS; - /* length of the channellist */ - s->len_chanlist = NUMCHANNELS; - /* callback functions */ - s->insn_read = usbdux_ai_insn_read; - s->do_cmdtest = usbdux_ai_cmdtest; - s->do_cmd = usbdux_ai_cmd; - s->cancel = usbdux_ai_cancel; - /* max value from the A/D converter (24bit) */ - s->maxdata = 0x00FFFFFF; - /* range table to convert to physical units */ - s->range_table = (&range_usbdux_ai_range); - /* analog output subdevice */ - s = dev->subdevices + SUBDEV_DA; - /* analog out */ - s->type = COMEDI_SUBD_AO; - /* backward pointer */ - dev->write_subdev = s; - /* the subdevice receives as private structure the */ - /* usb-structure */ - s->private = NULL; - /* are writable */ - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; - /* 4 channels */ - s->n_chan = 4; - /* length of the channellist */ - s->len_chanlist = 4; - /* 8 bit resolution */ - s->maxdata = 0x00ff; - /* unipolar range */ - s->range_table = (&range_usbdux_ao_range); - /* callback */ - s->do_cmdtest = usbdux_ao_cmdtest; - s->do_cmd = usbdux_ao_cmd; - s->cancel = usbdux_ao_cancel; - s->insn_read = usbdux_ao_insn_read; - s->insn_write = usbdux_ao_insn_write; - /* digital I/O subdevice */ - s = dev->subdevices + SUBDEV_DIO; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - /* 8 external and 16 internal channels */ - s->n_chan = 24; - s->maxdata = 1; - s->range_table = (&range_digital); - s->insn_bits = usbdux_dio_insn_bits; - s->insn_config = usbdux_dio_insn_config; - /* we don't use it */ - s->private = NULL; - if (uds->high_speed) { - /* timer / pwm subdevice */ - s = dev->subdevices + SUBDEV_PWM; - s->type = COMEDI_SUBD_PWM; - s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; - s->n_chan = 8; - /* this defines the max duty cycle resolution */ - s->maxdata = uds->sizePwmBuf; - s->insn_write = usbdux_pwm_write; - s->insn_read = usbdux_pwm_read; - s->insn_config = usbdux_pwm_config; - usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); - } - /* finally decide that it's attached */ - uds->attached = 1; - up(&uds->sem); - offset = usbdux_getstatusinfo(dev, 0); - if (offset < 0) - dev_err(&uds->interface->dev, - "Communication to USBDUXSIGMA failed! Check firmware and cabling."); - dev_info(&uds->interface->dev, - "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset); - return 0; -} - -/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ -static int usbduxsigma_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - int ret; - int index; - int i; - void *aux_data; - int aux_len; - - dev->private = NULL; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - if (aux_data == NULL) - aux_len = 0; - else if (aux_len == 0) - aux_data = NULL; - - down(&start_stop_sem); - /* find a valid device which has been detected by the probe function of - * the usb */ - index = -1; - for (i = 0; i < NUMUSBDUX; i++) { - if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { - index = i; - break; - } - } - if (index < 0) { - dev_err(dev->class_dev, - "usbduxsigma: error: attach failed, dev not connected to the usb bus.\n"); - up(&start_stop_sem); - ret = -ENODEV; - } else - ret = usbduxsigma_attach_common(dev, &usbduxsub[index], - aux_data, aux_len); - up(&start_stop_sem); - return ret; -} - -/* is called from comedi_usb_auto_config() */ -static int usbduxsigma_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) -{ - int ret; - struct usbduxsub *uds; - - dev->private = NULL; - down(&start_stop_sem); - uds = usb_get_intfdata(uinterf); - if (!uds || !uds->probed) { - dev_err(dev->class_dev, - "usbduxsigma: error: attach_usb failed, not connected\n"); - ret = -ENODEV; - } else if (uds->attached) { - dev_err(dev->class_dev, - "usbduxsigma: error: attach_usb failed, already attached\n"); - ret = -ENODEV; - } else - ret = usbduxsigma_attach_common(dev, uds, NULL, 0); - up(&start_stop_sem); - return ret; -} - -static void usbduxsigma_detach(struct comedi_device *dev) -{ - struct usbduxsub *usb = dev->private; - - if (usb) { - down(&usb->sem); - dev->private = NULL; - usb->attached = 0; - usb->comedidev = NULL; - up(&usb->sem); - } -} - -/* main driver struct */ -static struct comedi_driver usbduxsigma_driver = { - .driver_name = "usbduxsigma", - .module = THIS_MODULE, - .attach = usbduxsigma_attach, - .detach = usbduxsigma_detach, - .attach_usb = usbduxsigma_attach_usb, +static const struct usb_device_id usbduxsigma_usb_table[] = { + { USB_DEVICE(0x13d8, 0x0020) }, + { USB_DEVICE(0x13d8, 0x0021) }, + { USB_DEVICE(0x13d8, 0x0022) }, + { } }; +MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table); -/* Table with the USB-devices */ -static const struct usb_device_id usbduxsigma_table[] = { - {USB_DEVICE(0x13d8, 0x0020)}, - {USB_DEVICE(0x13d8, 0x0021)}, - {USB_DEVICE(0x13d8, 0x0022)}, - {} /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, usbduxsigma_table); - -/* The usbduxsub-driver */ static struct usb_driver usbduxsigma_usb_driver = { - .name = BOARDNAME, - .probe = usbduxsigma_probe, - .disconnect = usbduxsigma_disconnect, - .id_table = usbduxsigma_table, + .name = "usbduxsigma", + .probe = usbduxsigma_usb_probe, + .disconnect = usbduxsigma_usb_disconnect, + .id_table = usbduxsigma_usb_table, }; module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); +MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); MODULE_LICENSE("GPL"); -- GitLab From 4c8ba916b268d25ad5e2cd7ccb1a886831cde659 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:02:28 -0700 Subject: [PATCH 2267/6849] staging: comedi: usbduxfast: refactor init code Refactor the usb driver probe/disconnect and comedi driver attach/ detach to follow the style of the other comedi driver types to improve maintainability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 331 ++++++++++---------- 1 file changed, 157 insertions(+), 174 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 8c8e4ec9f358..d9911588c10a 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -49,11 +49,6 @@ #include "comedi_fc.h" #include "../comedidev.h" -#define DRIVER_VERSION "v1.0" -#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" -#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com" -#define BOARDNAME "usbduxfast" - /* * timeout for the USB-transfer */ @@ -196,8 +191,6 @@ static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST]; static DEFINE_SEMAPHORE(start_stop_sem); -static struct comedi_driver usbduxfast_driver; /* see below for initializer */ - /* * bulk transfers to usbduxfast */ @@ -1436,6 +1429,149 @@ static void tidy_up(struct usbduxfastsub_s *udfs) udfs->ai_cmd_running = 0; } +/* common part of attach and attach_usb */ +static int usbduxfast_attach_common(struct comedi_device *dev, + struct usbduxfastsub_s *udfs, + void *aux_data, int aux_len) +{ + int ret; + struct comedi_subdevice *s; + + down(&udfs->sem); + /* pointer back to the corresponding comedi device */ + udfs->comedidev = dev; + /* trying to upload the firmware into the chip */ + if (aux_data) + firmwareUpload(udfs, aux_data, aux_len); + dev->board_name = "usbduxfast"; + ret = comedi_alloc_subdevices(dev, 1); + if (ret) { + up(&udfs->sem); + return ret; + } + /* private structure is also simply the usb-structure */ + dev->private = udfs; + /* the first subdevice is the A/D converter */ + s = dev->subdevices + SUBDEV_AD; + /* + * the URBs get the comedi subdevice which is responsible for reading + * this is the subdevice which reads data + */ + dev->read_subdev = s; + /* the subdevice receives as private structure the usb-structure */ + s->private = NULL; + /* analog input */ + s->type = COMEDI_SUBD_AI; + /* readable and ref is to ground */ + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + /* 16 channels */ + s->n_chan = 16; + /* length of the channellist */ + s->len_chanlist = 16; + /* callback functions */ + s->insn_read = usbduxfast_ai_insn_read; + s->do_cmdtest = usbduxfast_ai_cmdtest; + s->do_cmd = usbduxfast_ai_cmd; + s->cancel = usbduxfast_ai_cancel; + /* max value from the A/D converter (12bit+1 bit for overflow) */ + s->maxdata = 0x1000; + /* range table to convert to physical units */ + s->range_table = &range_usbduxfast_ai_range; + /* finally decide that it's attached */ + udfs->attached = 1; + up(&udfs->sem); + dev_info(dev->class_dev, "successfully attached to usbduxfast.\n"); + return 0; +} + +/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ +static int usbduxfast_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int ret; + int index; + int i; + void *aux_data; + int aux_len; + + dev->private = NULL; + + aux_data = comedi_aux_data(it->options, 0); + aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; + if (aux_data == NULL) + aux_len = 0; + else if (aux_len == 0) + aux_data = NULL; + down(&start_stop_sem); + /* + * find a valid device which has been detected by the + * probe function of the usb + */ + index = -1; + for (i = 0; i < NUMUSBDUXFAST; i++) { + if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) { + index = i; + break; + } + } + if (index < 0) { + dev_err(dev->class_dev, + "usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n"); + ret = -ENODEV; + } else + ret = usbduxfast_attach_common(dev, &usbduxfastsub[index], + aux_data, aux_len); + up(&start_stop_sem); + return ret; +} + +/* is called from comedi_usb_auto_config() */ +static int usbduxfast_attach_usb(struct comedi_device *dev, + struct usb_interface *uinterf) +{ + int ret; + struct usbduxfastsub_s *udfs; + + dev->private = NULL; + down(&start_stop_sem); + udfs = usb_get_intfdata(uinterf); + if (!udfs || !udfs->probed) { + dev_err(dev->class_dev, + "usbduxfast: error: attach_usb failed, not connected\n"); + ret = -ENODEV; + } else if (udfs->attached) { + dev_err(dev->class_dev, + "usbduxfast: error: attach_usb failed, already attached\n"); + ret = -ENODEV; + } else + ret = usbduxfast_attach_common(dev, udfs, NULL, 0); + up(&start_stop_sem); + return ret; +} + +static void usbduxfast_detach(struct comedi_device *dev) +{ + struct usbduxfastsub_s *usb = dev->private; + + if (usb) { + down(&usb->sem); + down(&start_stop_sem); + dev->private = NULL; + usb->attached = 0; + usb->comedidev = NULL; + up(&start_stop_sem); + up(&usb->sem); + } +} + +static struct comedi_driver usbduxfast_driver = { + .driver_name = "usbduxfast", + .module = THIS_MODULE, + .attach = usbduxfast_attach, + .detach = usbduxfast_detach, + .attach_usb = usbduxfast_attach_usb, +}; + static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw, void *context) { @@ -1463,11 +1599,8 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware release_firmware(fw); } -/* - * allocate memory for the urbs and initialise them - */ -static int usbduxfastsub_probe(struct usb_interface *uinterf, - const struct usb_device_id *id) +static int usbduxfast_usb_probe(struct usb_interface *uinterf, + const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(uinterf); int i; @@ -1590,7 +1723,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf, return 0; } -static void usbduxfastsub_disconnect(struct usb_interface *intf) +static void usbduxfast_usb_disconnect(struct usb_interface *intf) { struct usbduxfastsub_s *udfs = usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); @@ -1619,175 +1752,25 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) #endif } -/* common part of attach and attach_usb */ -static int usbduxfast_attach_common(struct comedi_device *dev, - struct usbduxfastsub_s *udfs, - void *aux_data, int aux_len) -{ - int ret; - struct comedi_subdevice *s; - - down(&udfs->sem); - /* pointer back to the corresponding comedi device */ - udfs->comedidev = dev; - /* trying to upload the firmware into the chip */ - if (aux_data) - firmwareUpload(udfs, aux_data, aux_len); - dev->board_name = BOARDNAME; - ret = comedi_alloc_subdevices(dev, 1); - if (ret) { - up(&udfs->sem); - return ret; - } - /* private structure is also simply the usb-structure */ - dev->private = udfs; - /* the first subdevice is the A/D converter */ - s = dev->subdevices + SUBDEV_AD; - /* - * the URBs get the comedi subdevice which is responsible for reading - * this is the subdevice which reads data - */ - dev->read_subdev = s; - /* the subdevice receives as private structure the usb-structure */ - s->private = NULL; - /* analog input */ - s->type = COMEDI_SUBD_AI; - /* readable and ref is to ground */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; - /* 16 channels */ - s->n_chan = 16; - /* length of the channellist */ - s->len_chanlist = 16; - /* callback functions */ - s->insn_read = usbduxfast_ai_insn_read; - s->do_cmdtest = usbduxfast_ai_cmdtest; - s->do_cmd = usbduxfast_ai_cmd; - s->cancel = usbduxfast_ai_cancel; - /* max value from the A/D converter (12bit+1 bit for overflow) */ - s->maxdata = 0x1000; - /* range table to convert to physical units */ - s->range_table = &range_usbduxfast_ai_range; - /* finally decide that it's attached */ - udfs->attached = 1; - up(&udfs->sem); - dev_info(dev->class_dev, "successfully attached to usbduxfast.\n"); - return 0; -} - -/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */ -static int usbduxfast_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - int ret; - int index; - int i; - void *aux_data; - int aux_len; - - dev->private = NULL; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - if (aux_data == NULL) - aux_len = 0; - else if (aux_len == 0) - aux_data = NULL; - down(&start_stop_sem); - /* - * find a valid device which has been detected by the - * probe function of the usb - */ - index = -1; - for (i = 0; i < NUMUSBDUXFAST; i++) { - if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) { - index = i; - break; - } - } - if (index < 0) { - dev_err(dev->class_dev, - "usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n"); - ret = -ENODEV; - } else - ret = usbduxfast_attach_common(dev, &usbduxfastsub[index], - aux_data, aux_len); - up(&start_stop_sem); - return ret; -} - -/* is called from comedi_usb_auto_config() */ -static int usbduxfast_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) -{ - int ret; - struct usbduxfastsub_s *udfs; - - dev->private = NULL; - down(&start_stop_sem); - udfs = usb_get_intfdata(uinterf); - if (!udfs || !udfs->probed) { - dev_err(dev->class_dev, - "usbduxfast: error: attach_usb failed, not connected\n"); - ret = -ENODEV; - } else if (udfs->attached) { - dev_err(dev->class_dev, - "usbduxfast: error: attach_usb failed, already attached\n"); - ret = -ENODEV; - } else - ret = usbduxfast_attach_common(dev, udfs, NULL, 0); - up(&start_stop_sem); - return ret; -} - -static void usbduxfast_detach(struct comedi_device *dev) -{ - struct usbduxfastsub_s *usb = dev->private; - - if (usb) { - down(&usb->sem); - down(&start_stop_sem); - dev->private = NULL; - usb->attached = 0; - usb->comedidev = NULL; - up(&start_stop_sem); - up(&usb->sem); - } -} - -/* - * main driver struct - */ -static struct comedi_driver usbduxfast_driver = { - .driver_name = "usbduxfast", - .module = THIS_MODULE, - .attach = usbduxfast_attach, - .detach = usbduxfast_detach, - .attach_usb = usbduxfast_attach_usb, -}; - -/* - * Table with the USB-devices: just now only testing IDs - */ -static const struct usb_device_id usbduxfastsub_table[] = { +static const struct usb_device_id usbduxfast_usb_table[] = { /* { USB_DEVICE(0x4b4, 0x8613) }, testing */ - {USB_DEVICE(0x13d8, 0x0010)}, /* real ID */ - {USB_DEVICE(0x13d8, 0x0011)}, /* real ID */ - {} /* Terminating entry */ + { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */ + { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */ + { } }; - -MODULE_DEVICE_TABLE(usb, usbduxfastsub_table); +MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table); static struct usb_driver usbduxfast_usb_driver = { #ifdef COMEDI_HAVE_USB_DRIVER_OWNER .owner = THIS_MODULE, #endif - .name = BOARDNAME, - .probe = usbduxfastsub_probe, - .disconnect = usbduxfastsub_disconnect, - .id_table = usbduxfastsub_table, + .name = "usbduxfast", + .probe = usbduxfast_usb_probe, + .disconnect = usbduxfast_usb_disconnect, + .id_table = usbduxfast_usb_table, }; module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); +MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); MODULE_LICENSE("GPL"); -- GitLab From 3403cc0f701db8a3f1082e5b1027265ee1343b20 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 12:02:49 -0700 Subject: [PATCH 2268/6849] staging: comedi: usbdux: refactor init code Refactor the usb driver probe/disconnect and comedi driver attach/ detach to follow the style of the other comedi driver types to improve maintainability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 488 ++++++++++++------------ 1 file changed, 239 insertions(+), 249 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 586936bc420b..848c7ec06976 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1,6 +1,3 @@ -#define DRIVER_VERSION "v2.4" -#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" -#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com" /* comedi/drivers/usbdux.c Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com @@ -101,8 +98,6 @@ sampling rate. If you sample two channels you get 4kHz and so on. #include "../comedidev.h" -#define BOARDNAME "usbdux" - /* timeout for the USB-transfer in ms*/ #define BULK_TIMEOUT 1000 @@ -317,8 +312,6 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); -static struct comedi_driver usbdux_driver; /* see below for initializer */ - /* * Stops the data acquision * It should be safe to call this function from any context @@ -2299,6 +2292,231 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_tmp->pwm_cmd_running = 0; } +/* common part of attach and attach_usb */ +static int usbdux_attach_common(struct comedi_device *dev, + struct usbduxsub *udev, + void *aux_data, int aux_len) +{ + int ret; + struct comedi_subdevice *s = NULL; + int n_subdevs; + + down(&udev->sem); + /* pointer back to the corresponding comedi device */ + udev->comedidev = dev; + + /* trying to upload the firmware into the chip */ + if (aux_data) + firmwareUpload(udev, aux_data, aux_len); + + dev->board_name = "usbdux"; + + /* set number of subdevices */ + if (udev->high_speed) { + /* with pwm */ + n_subdevs = 5; + } else { + /* without pwm */ + n_subdevs = 4; + } + + ret = comedi_alloc_subdevices(dev, n_subdevs); + if (ret) { + up(&udev->sem); + return ret; + } + + /* private structure is also simply the usb-structure */ + dev->private = udev; + + /* the first subdevice is the A/D converter */ + s = dev->subdevices + SUBDEV_AD; + /* the URBs get the comedi subdevice */ + /* which is responsible for reading */ + /* this is the subdevice which reads data */ + dev->read_subdev = s; + /* the subdevice receives as private structure the */ + /* usb-structure */ + s->private = NULL; + /* analog input */ + s->type = COMEDI_SUBD_AI; + /* readable and ref is to ground */ + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + /* 8 channels */ + s->n_chan = 8; + /* length of the channellist */ + s->len_chanlist = 8; + /* callback functions */ + s->insn_read = usbdux_ai_insn_read; + s->do_cmdtest = usbdux_ai_cmdtest; + s->do_cmd = usbdux_ai_cmd; + s->cancel = usbdux_ai_cancel; + /* max value from the A/D converter (12bit) */ + s->maxdata = 0xfff; + /* range table to convert to physical units */ + s->range_table = (&range_usbdux_ai_range); + + /* analog out */ + s = dev->subdevices + SUBDEV_DA; + /* analog out */ + s->type = COMEDI_SUBD_AO; + /* backward pointer */ + dev->write_subdev = s; + /* the subdevice receives as private structure the */ + /* usb-structure */ + s->private = NULL; + /* are writable */ + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; + /* 4 channels */ + s->n_chan = 4; + /* length of the channellist */ + s->len_chanlist = 4; + /* 12 bit resolution */ + s->maxdata = 0x0fff; + /* bipolar range */ + s->range_table = (&range_usbdux_ao_range); + /* callback */ + s->do_cmdtest = usbdux_ao_cmdtest; + s->do_cmd = usbdux_ao_cmd; + s->cancel = usbdux_ao_cancel; + s->insn_read = usbdux_ao_insn_read; + s->insn_write = usbdux_ao_insn_write; + + /* digital I/O */ + s = dev->subdevices + SUBDEV_DIO; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = (&range_digital); + s->insn_bits = usbdux_dio_insn_bits; + s->insn_config = usbdux_dio_insn_config; + /* we don't use it */ + s->private = NULL; + + /* counter */ + s = dev->subdevices + SUBDEV_COUNTER; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 4; + s->maxdata = 0xFFFF; + s->insn_read = usbdux_counter_read; + s->insn_write = usbdux_counter_write; + s->insn_config = usbdux_counter_config; + + if (udev->high_speed) { + /* timer / pwm */ + s = dev->subdevices + SUBDEV_PWM; + s->type = COMEDI_SUBD_PWM; + s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; + s->n_chan = 8; + /* this defines the max duty cycle resolution */ + s->maxdata = udev->sizePwmBuf; + s->insn_write = usbdux_pwm_write; + s->insn_read = usbdux_pwm_read; + s->insn_config = usbdux_pwm_config; + usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); + } + /* finally decide that it's attached */ + udev->attached = 1; + + up(&udev->sem); + + dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n", + dev->minor); + + return 0; +} + +/* is called when comedi-config is called */ +static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + int ret; + int index; + int i; + void *aux_data; + int aux_len; + + dev->private = NULL; + + aux_data = comedi_aux_data(it->options, 0); + aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; + if (aux_data == NULL) + aux_len = 0; + else if (aux_len == 0) + aux_data = NULL; + + down(&start_stop_sem); + /* find a valid device which has been detected by the probe function of + * the usb */ + index = -1; + for (i = 0; i < NUMUSBDUX; i++) { + if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { + index = i; + break; + } + } + + if (index < 0) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n", + dev->minor); + ret = -ENODEV; + } else + ret = usbdux_attach_common(dev, &usbduxsub[index], + aux_data, aux_len); + up(&start_stop_sem); + return ret; +} + +/* is called from comedi_usb_auto_config() */ +static int usbdux_attach_usb(struct comedi_device *dev, + struct usb_interface *uinterf) +{ + int ret; + struct usbduxsub *this_usbduxsub; + + dev->private = NULL; + + down(&start_stop_sem); + this_usbduxsub = usb_get_intfdata(uinterf); + if (!this_usbduxsub || !this_usbduxsub->probed) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach_usb failed, not connected\n", + dev->minor); + ret = -ENODEV; + } else if (this_usbduxsub->attached) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach_usb failed, already attached\n", + dev->minor); + ret = -ENODEV; + } else + ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0); + up(&start_stop_sem); + return ret; +} + +static void usbdux_detach(struct comedi_device *dev) +{ + struct usbduxsub *usb = dev->private; + + if (usb) { + down(&usb->sem); + dev->private = NULL; + usb->attached = 0; + usb->comedidev = NULL; + up(&usb->sem); + } +} + +static struct comedi_driver usbdux_driver = { + .driver_name = "usbdux", + .module = THIS_MODULE, + .attach = usbdux_attach, + .detach = usbdux_detach, + .attach_usb = usbdux_attach_usb, +}; + static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { @@ -2328,9 +2546,8 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, release_firmware(fw); } -/* allocate memory for the urbs and initialise them */ -static int usbduxsub_probe(struct usb_interface *uinterf, - const struct usb_device_id *id) +static int usbdux_usb_probe(struct usb_interface *uinterf, + const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(uinterf); struct device *dev = &uinterf->dev; @@ -2591,7 +2808,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, return 0; } -static void usbduxsub_disconnect(struct usb_interface *intf) +static void usbdux_usb_disconnect(struct usb_interface *intf) { struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); @@ -2614,249 +2831,22 @@ static void usbduxsub_disconnect(struct usb_interface *intf) dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n"); } -/* common part of attach and attach_usb */ -static int usbdux_attach_common(struct comedi_device *dev, - struct usbduxsub *udev, - void *aux_data, int aux_len) -{ - int ret; - struct comedi_subdevice *s = NULL; - int n_subdevs; - - down(&udev->sem); - /* pointer back to the corresponding comedi device */ - udev->comedidev = dev; - - /* trying to upload the firmware into the chip */ - if (aux_data) - firmwareUpload(udev, aux_data, aux_len); - - dev->board_name = BOARDNAME; - - /* set number of subdevices */ - if (udev->high_speed) { - /* with pwm */ - n_subdevs = 5; - } else { - /* without pwm */ - n_subdevs = 4; - } - - ret = comedi_alloc_subdevices(dev, n_subdevs); - if (ret) { - up(&udev->sem); - return ret; - } - - /* private structure is also simply the usb-structure */ - dev->private = udev; - - /* the first subdevice is the A/D converter */ - s = dev->subdevices + SUBDEV_AD; - /* the URBs get the comedi subdevice */ - /* which is responsible for reading */ - /* this is the subdevice which reads data */ - dev->read_subdev = s; - /* the subdevice receives as private structure the */ - /* usb-structure */ - s->private = NULL; - /* analog input */ - s->type = COMEDI_SUBD_AI; - /* readable and ref is to ground */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; - /* 8 channels */ - s->n_chan = 8; - /* length of the channellist */ - s->len_chanlist = 8; - /* callback functions */ - s->insn_read = usbdux_ai_insn_read; - s->do_cmdtest = usbdux_ai_cmdtest; - s->do_cmd = usbdux_ai_cmd; - s->cancel = usbdux_ai_cancel; - /* max value from the A/D converter (12bit) */ - s->maxdata = 0xfff; - /* range table to convert to physical units */ - s->range_table = (&range_usbdux_ai_range); - - /* analog out */ - s = dev->subdevices + SUBDEV_DA; - /* analog out */ - s->type = COMEDI_SUBD_AO; - /* backward pointer */ - dev->write_subdev = s; - /* the subdevice receives as private structure the */ - /* usb-structure */ - s->private = NULL; - /* are writable */ - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; - /* 4 channels */ - s->n_chan = 4; - /* length of the channellist */ - s->len_chanlist = 4; - /* 12 bit resolution */ - s->maxdata = 0x0fff; - /* bipolar range */ - s->range_table = (&range_usbdux_ao_range); - /* callback */ - s->do_cmdtest = usbdux_ao_cmdtest; - s->do_cmd = usbdux_ao_cmd; - s->cancel = usbdux_ao_cancel; - s->insn_read = usbdux_ao_insn_read; - s->insn_write = usbdux_ao_insn_write; - - /* digital I/O */ - s = dev->subdevices + SUBDEV_DIO; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = (&range_digital); - s->insn_bits = usbdux_dio_insn_bits; - s->insn_config = usbdux_dio_insn_config; - /* we don't use it */ - s->private = NULL; - - /* counter */ - s = dev->subdevices + SUBDEV_COUNTER; - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 4; - s->maxdata = 0xFFFF; - s->insn_read = usbdux_counter_read; - s->insn_write = usbdux_counter_write; - s->insn_config = usbdux_counter_config; - - if (udev->high_speed) { - /* timer / pwm */ - s = dev->subdevices + SUBDEV_PWM; - s->type = COMEDI_SUBD_PWM; - s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; - s->n_chan = 8; - /* this defines the max duty cycle resolution */ - s->maxdata = udev->sizePwmBuf; - s->insn_write = usbdux_pwm_write; - s->insn_read = usbdux_pwm_read; - s->insn_config = usbdux_pwm_config; - usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); - } - /* finally decide that it's attached */ - udev->attached = 1; - - up(&udev->sem); - - dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n", - dev->minor); - - return 0; -} - -/* is called when comedi-config is called */ -static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - int ret; - int index; - int i; - void *aux_data; - int aux_len; - - dev->private = NULL; - - aux_data = comedi_aux_data(it->options, 0); - aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; - if (aux_data == NULL) - aux_len = 0; - else if (aux_len == 0) - aux_data = NULL; - - down(&start_stop_sem); - /* find a valid device which has been detected by the probe function of - * the usb */ - index = -1; - for (i = 0; i < NUMUSBDUX; i++) { - if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { - index = i; - break; - } - } - - if (index < 0) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n", - dev->minor); - ret = -ENODEV; - } else - ret = usbdux_attach_common(dev, &usbduxsub[index], - aux_data, aux_len); - up(&start_stop_sem); - return ret; -} - -/* is called from comedi_usb_auto_config() */ -static int usbdux_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) -{ - int ret; - struct usbduxsub *this_usbduxsub; - - dev->private = NULL; - - down(&start_stop_sem); - this_usbduxsub = usb_get_intfdata(uinterf); - if (!this_usbduxsub || !this_usbduxsub->probed) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach_usb failed, not connected\n", - dev->minor); - ret = -ENODEV; - } else if (this_usbduxsub->attached) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach_usb failed, already attached\n", - dev->minor); - ret = -ENODEV; - } else - ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0); - up(&start_stop_sem); - return ret; -} - -static void usbdux_detach(struct comedi_device *dev) -{ - struct usbduxsub *usb = dev->private; - - if (usb) { - down(&usb->sem); - dev->private = NULL; - usb->attached = 0; - usb->comedidev = NULL; - up(&usb->sem); - } -} - -/* main driver struct */ -static struct comedi_driver usbdux_driver = { - .driver_name = "usbdux", - .module = THIS_MODULE, - .attach = usbdux_attach, - .detach = usbdux_detach, - .attach_usb = usbdux_attach_usb, -}; - -/* Table with the USB-devices: just now only testing IDs */ -static const struct usb_device_id usbduxsub_table[] = { - {USB_DEVICE(0x13d8, 0x0001)}, - {USB_DEVICE(0x13d8, 0x0002)}, - {} /* Terminating entry */ +static const struct usb_device_id usbdux_usb_table[] = { + { USB_DEVICE(0x13d8, 0x0001) }, + { USB_DEVICE(0x13d8, 0x0002) }, + { } }; -MODULE_DEVICE_TABLE(usb, usbduxsub_table); +MODULE_DEVICE_TABLE(usb, usbdux_usb_table); static struct usb_driver usbdux_usb_driver = { - .name = BOARDNAME, - .probe = usbduxsub_probe, - .disconnect = usbduxsub_disconnect, - .id_table = usbduxsub_table, + .name = "usbdux", + .probe = usbdux_usb_probe, + .disconnect = usbdux_usb_disconnect, + .id_table = usbdux_usb_table, }; module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); +MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); MODULE_LICENSE("GPL"); -- GitLab From 81c524f76a353a19097e004ec05e4d62fd0bd57e Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:22 +0200 Subject: [PATCH 2269/6849] batman-adv: Prefix bat_algo non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_algo.h | 2 +- net/batman-adv/bat_iv_ogm.c | 2 +- net/batman-adv/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h index 9852a688ba43..a14336a08fac 100644 --- a/net/batman-adv/bat_algo.h +++ b/net/batman-adv/bat_algo.h @@ -22,6 +22,6 @@ #ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ #define _NET_BATMAN_ADV_BAT_ALGO_H_ -int bat_iv_init(void); +int batadv_iv_init(void); #endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */ diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 6e0859f4a6a9..b44573903264 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1248,7 +1248,7 @@ static struct bat_algo_ops batman_iv __read_mostly = { .bat_ogm_emit = bat_iv_ogm_emit, }; -int __init bat_iv_init(void) +int __init batadv_iv_init(void) { int ret; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 46ba302d2d01..1f064d430a29 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -56,7 +56,7 @@ static int __init batman_init(void) recv_handler_init(); - bat_iv_init(); + batadv_iv_init(); /* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ -- GitLab From 40a072d777a4f417c0296e06f91297b0f3f2fa36 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:23 +0200 Subject: [PATCH 2270/6849] batman-adv: Prefix bat_debugfs non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 10 +++++----- net/batman-adv/bat_debugfs.h | 8 ++++---- net/batman-adv/main.c | 4 ++-- net/batman-adv/main.h | 5 +++-- net/batman-adv/soft-interface.c | 6 +++--- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index db8273c26989..444d10bc9552 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -76,7 +76,7 @@ static int fdebug_log(struct debug_log *debug_log, const char *fmt, ...) return 0; } -int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) +int batadv_debug_log(struct bat_priv *bat_priv, const char *fmt, ...) { va_list args; char tmp_log_buf[256]; @@ -304,7 +304,7 @@ static struct bat_debuginfo *mesh_debuginfos[] = { NULL, }; -void debugfs_init(void) +void batadv_debugfs_init(void) { struct bat_debuginfo *bat_debug; struct dentry *file; @@ -327,7 +327,7 @@ out: return; } -void debugfs_destroy(void) +void batadv_debugfs_destroy(void) { if (bat_debugfs) { debugfs_remove_recursive(bat_debugfs); @@ -335,7 +335,7 @@ void debugfs_destroy(void) } } -int debugfs_add_meshif(struct net_device *dev) +int batadv_debugfs_add_meshif(struct net_device *dev) { struct bat_priv *bat_priv = netdev_priv(dev); struct bat_debuginfo **bat_debug; @@ -378,7 +378,7 @@ out: #endif /* CONFIG_DEBUG_FS */ } -void debugfs_del_meshif(struct net_device *dev) +void batadv_debugfs_del_meshif(struct net_device *dev) { struct bat_priv *bat_priv = netdev_priv(dev); diff --git a/net/batman-adv/bat_debugfs.h b/net/batman-adv/bat_debugfs.h index d605c6746428..3b206c811263 100644 --- a/net/batman-adv/bat_debugfs.h +++ b/net/batman-adv/bat_debugfs.h @@ -25,9 +25,9 @@ #define DEBUGFS_BAT_SUBDIR "batman_adv" -void debugfs_init(void); -void debugfs_destroy(void); -int debugfs_add_meshif(struct net_device *dev); -void debugfs_del_meshif(struct net_device *dev); +void batadv_debugfs_init(void); +void batadv_debugfs_destroy(void); +int batadv_debugfs_add_meshif(struct net_device *dev); +void batadv_debugfs_del_meshif(struct net_device *dev); #endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */ diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 1f064d430a29..46a35e1c67ca 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -66,7 +66,7 @@ static int __init batman_init(void) return -ENOMEM; bat_socket_init(); - debugfs_init(); + batadv_debugfs_init(); register_netdevice_notifier(&hard_if_notifier); @@ -78,7 +78,7 @@ static int __init batman_init(void) static void __exit batman_exit(void) { - debugfs_destroy(); + batadv_debugfs_destroy(); unregister_netdevice_notifier(&hard_if_notifier); hardif_remove_interfaces(); diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 6e0cbdc48321..ea9d433ad46d 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -167,12 +167,13 @@ int bat_algo_select(struct bat_priv *bat_priv, char *name); int bat_algo_seq_print_text(struct seq_file *seq, void *offset); #ifdef CONFIG_BATMAN_ADV_DEBUG -int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3); +int batadv_debug_log(struct bat_priv *bat_priv, const char *fmt, ...) +__printf(2, 3); #define bat_dbg(type, bat_priv, fmt, arg...) \ do { \ if (atomic_read(&bat_priv->log_level) & type) \ - debug_log(bat_priv, fmt, ## arg); \ + batadv_debug_log(bat_priv, fmt, ## arg);\ } \ while (0) #else /* !CONFIG_BATMAN_ADV_DEBUG */ diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 304a7ba09e03..0f0003b00f8c 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -419,7 +419,7 @@ struct net_device *softif_create(const char *name) if (ret < 0) goto free_bat_counters; - ret = debugfs_add_meshif(soft_iface); + ret = batadv_debugfs_add_meshif(soft_iface); if (ret < 0) goto unreg_sysfs; @@ -430,7 +430,7 @@ struct net_device *softif_create(const char *name) return soft_iface; unreg_debugfs: - debugfs_del_meshif(soft_iface); + batadv_debugfs_del_meshif(soft_iface); unreg_sysfs: sysfs_del_meshif(soft_iface); free_bat_counters: @@ -447,7 +447,7 @@ out: void softif_destroy(struct net_device *soft_iface) { - debugfs_del_meshif(soft_iface); + batadv_debugfs_del_meshif(soft_iface); sysfs_del_meshif(soft_iface); mesh_free(soft_iface); unregister_netdevice(soft_iface); -- GitLab From 5853e22c58b318232fd6e15033ccb0852f865c0b Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:24 +0200 Subject: [PATCH 2271/6849] batman-adv: Prefix bat_sysfs non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 12 ++++++------ net/batman-adv/bat_sysfs.h | 13 +++++++------ net/batman-adv/gateway_client.c | 6 +++--- net/batman-adv/hard-interface.c | 4 ++-- net/batman-adv/soft-interface.c | 6 +++--- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index dc1edbee63df..5dce1abc35d4 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -469,7 +469,7 @@ static struct bat_attribute *mesh_attrs[] = { NULL, }; -int sysfs_add_meshif(struct net_device *dev) +int batadv_sysfs_add_meshif(struct net_device *dev) { struct kobject *batif_kobject = &dev->dev.kobj; struct bat_priv *bat_priv = netdev_priv(dev); @@ -507,7 +507,7 @@ out: return -ENOMEM; } -void sysfs_del_meshif(struct net_device *dev) +void batadv_sysfs_del_meshif(struct net_device *dev) { struct bat_priv *bat_priv = netdev_priv(dev); struct bat_attribute **bat_attr; @@ -637,7 +637,7 @@ static struct bat_attribute *batman_attrs[] = { NULL, }; -int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) +int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) { struct kobject *hardif_kobject = &dev->dev.kobj; struct bat_attribute **bat_attr; @@ -671,14 +671,14 @@ out: return -ENOMEM; } -void sysfs_del_hardif(struct kobject **hardif_obj) +void batadv_sysfs_del_hardif(struct kobject **hardif_obj) { kobject_put(*hardif_obj); *hardif_obj = NULL; } -int throw_uevent(struct bat_priv *bat_priv, enum uev_type type, - enum uev_action action, const char *data) +int batadv_throw_uevent(struct bat_priv *bat_priv, enum uev_type type, + enum uev_action action, const char *data) { int ret = -ENOMEM; struct hard_iface *primary_if = NULL; diff --git a/net/batman-adv/bat_sysfs.h b/net/batman-adv/bat_sysfs.h index fece77ae586e..f01aea836b98 100644 --- a/net/batman-adv/bat_sysfs.h +++ b/net/batman-adv/bat_sysfs.h @@ -34,11 +34,12 @@ struct bat_attribute { char *buf, size_t count); }; -int sysfs_add_meshif(struct net_device *dev); -void sysfs_del_meshif(struct net_device *dev); -int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); -void sysfs_del_hardif(struct kobject **hardif_obj); -int throw_uevent(struct bat_priv *bat_priv, enum uev_type type, - enum uev_action action, const char *data); +int batadv_sysfs_add_meshif(struct net_device *dev); +void batadv_sysfs_del_meshif(struct net_device *dev); +int batadv_sysfs_add_hardif(struct kobject **hardif_obj, + struct net_device *dev); +void batadv_sysfs_del_hardif(struct kobject **hardif_obj); +int batadv_throw_uevent(struct bat_priv *bat_priv, enum uev_type type, + enum uev_action action, const char *data); #endif /* _NET_BATMAN_ADV_SYSFS_H_ */ diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 47f7186dcefc..1d7f08e026f3 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -220,19 +220,19 @@ void gw_election(struct bat_priv *bat_priv) if ((curr_gw) && (!next_gw)) { bat_dbg(DBG_BATMAN, bat_priv, "Removing selected gateway - no gateway in range\n"); - throw_uevent(bat_priv, UEV_GW, UEV_DEL, NULL); + batadv_throw_uevent(bat_priv, UEV_GW, UEV_DEL, NULL); } else if ((!curr_gw) && (next_gw)) { bat_dbg(DBG_BATMAN, bat_priv, "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n", next_gw->orig_node->orig, next_gw->orig_node->gw_flags, router->tq_avg); - throw_uevent(bat_priv, UEV_GW, UEV_ADD, gw_addr); + batadv_throw_uevent(bat_priv, UEV_GW, UEV_ADD, gw_addr); } else { bat_dbg(DBG_BATMAN, bat_priv, "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n", next_gw->orig_node->orig, next_gw->orig_node->gw_flags, router->tq_avg); - throw_uevent(bat_priv, UEV_GW, UEV_CHANGE, gw_addr); + batadv_throw_uevent(bat_priv, UEV_GW, UEV_CHANGE, gw_addr); } gw_select(bat_priv, next_gw); diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index ce78c6d645c6..380572e721e6 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -423,7 +423,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev) if (!hard_iface) goto release_dev; - ret = sysfs_add_hardif(&hard_iface->hardif_obj, net_dev); + ret = batadv_sysfs_add_hardif(&hard_iface->hardif_obj, net_dev); if (ret) goto free_if; @@ -467,7 +467,7 @@ static void hardif_remove_interface(struct hard_iface *hard_iface) return; hard_iface->if_status = IF_TO_BE_REMOVED; - sysfs_del_hardif(&hard_iface->hardif_obj); + batadv_sysfs_del_hardif(&hard_iface->hardif_obj); hardif_free_ref(hard_iface); } diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 0f0003b00f8c..11bfe533e2a4 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -415,7 +415,7 @@ struct net_device *softif_create(const char *name) if (ret < 0) goto free_bat_counters; - ret = sysfs_add_meshif(soft_iface); + ret = batadv_sysfs_add_meshif(soft_iface); if (ret < 0) goto free_bat_counters; @@ -432,7 +432,7 @@ struct net_device *softif_create(const char *name) unreg_debugfs: batadv_debugfs_del_meshif(soft_iface); unreg_sysfs: - sysfs_del_meshif(soft_iface); + batadv_sysfs_del_meshif(soft_iface); free_bat_counters: free_percpu(bat_priv->bat_counters); unreg_soft_iface: @@ -448,7 +448,7 @@ out: void softif_destroy(struct net_device *soft_iface) { batadv_debugfs_del_meshif(soft_iface); - sysfs_del_meshif(soft_iface); + batadv_sysfs_del_meshif(soft_iface); mesh_free(soft_iface); unregister_netdevice(soft_iface); } -- GitLab From 0f5f9322681887ca221707afafe4216b6db5d22f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:25 +0200 Subject: [PATCH 2272/6849] batman-adv: Prefix bitarray non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 6 +++--- net/batman-adv/bitarray.c | 8 ++++---- net/batman-adv/bitarray.h | 4 ++-- net/batman-adv/routing.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index b44573903264..53bce95e5f33 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -903,9 +903,9 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, set_mark = 0; /* if the window moved, set the update flag. */ - need_update |= bit_get_packet(bat_priv, - tmp_neigh_node->real_bits, - seq_diff, set_mark); + need_update |= batadv_bit_get_packet(bat_priv, + tmp_neigh_node->real_bits, + seq_diff, set_mark); tmp_neigh_node->real_packet_count = bitmap_weight(tmp_neigh_node->real_bits, diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index 07ae6e1b8aca..99ed9917ff0d 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -25,7 +25,7 @@ #include /* shift the packet array by n places. */ -static void bat_bitmap_shift_left(unsigned long *seq_bits, int32_t n) +static void batadv_bitmap_shift_left(unsigned long *seq_bits, int32_t n) { if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) return; @@ -40,8 +40,8 @@ static void bat_bitmap_shift_left(unsigned long *seq_bits, int32_t n) * 1 if the window was moved (either new or very old) * 0 if the window was not moved/shifted. */ -int bit_get_packet(void *priv, unsigned long *seq_bits, - int32_t seq_num_diff, int set_mark) +int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, + int32_t seq_num_diff, int set_mark) { struct bat_priv *bat_priv = priv; @@ -58,7 +58,7 @@ int bit_get_packet(void *priv, unsigned long *seq_bits, * set the mark if required */ if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { - bat_bitmap_shift_left(seq_bits, seq_num_diff); + batadv_bitmap_shift_left(seq_bits, seq_num_diff); if (set_mark) bat_set_bit(seq_bits, 0); diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h index 1835c15cda41..e855ddd37430 100644 --- a/net/batman-adv/bitarray.h +++ b/net/batman-adv/bitarray.h @@ -48,7 +48,7 @@ static inline void bat_set_bit(unsigned long *seq_bits, int32_t n) /* receive and process one packet, returns 1 if received seq_num is considered * new, 0 if old */ -int bit_get_packet(void *priv, unsigned long *seq_bits, - int32_t seq_num_diff, int set_mark); +int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, + int32_t seq_num_diff, int set_mark); #endif /* _NET_BATMAN_ADV_BITARRAY_H_ */ diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 9cfd23c6d64a..e573c32a619d 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -54,7 +54,7 @@ void slide_own_bcast_window(struct hard_iface *hard_iface) word_index = hard_iface->if_num * NUM_WORDS; word = &(orig_node->bcast_own[word_index]); - bit_get_packet(bat_priv, word, 1, 0); + batadv_bit_get_packet(bat_priv, word, 1, 0); orig_node->bcast_own_sum[hard_iface->if_num] = bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE); spin_unlock_bh(&orig_node->ogm_cnt_lock); @@ -1083,7 +1083,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* mark broadcast in flood history, update window position * if required. */ - if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) + if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); spin_unlock_bh(&orig_node->bcast_seqno_lock); -- GitLab From 08adf1512298201a53b88bb0a3d67e0dbbe0ed9b Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:38:47 +0200 Subject: [PATCH 2273/6849] batman-adv: Prefix bridge_loop_avoidance non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 3 +- net/batman-adv/bridge_loop_avoidance.c | 28 +++++------ net/batman-adv/bridge_loop_avoidance.h | 67 ++++++++++++++------------ net/batman-adv/hard-interface.c | 2 +- net/batman-adv/main.c | 4 +- net/batman-adv/routing.c | 6 +-- net/batman-adv/soft-interface.c | 4 +- net/batman-adv/translation-table.c | 6 +-- 8 files changed, 62 insertions(+), 58 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 444d10bc9552..71b225c1b5ca 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -249,7 +249,8 @@ static int transtable_global_open(struct inode *inode, struct file *file) static int bla_claim_table_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, bla_claim_table_seq_print_text, net_dev); + return single_open(file, batadv_bla_claim_table_seq_print_text, + net_dev); } #endif diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 314e37b272a7..b0561e338ae5 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1019,9 +1019,9 @@ purge_now: * Update the backbone gateways when the own orig address changes. * */ -void bla_update_orig_address(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - struct hard_iface *oldif) +void batadv_bla_update_orig_address(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + struct hard_iface *oldif) { struct backbone_gw *backbone_gw; struct hlist_node *node; @@ -1136,7 +1136,7 @@ static struct lock_class_key claim_hash_lock_class_key; static struct lock_class_key backbone_hash_lock_class_key; /* initialize all bla structures */ -int bla_init(struct bat_priv *bat_priv) +int batadv_bla_init(struct bat_priv *bat_priv) { int i; uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; @@ -1199,9 +1199,9 @@ int bla_init(struct bat_priv *bat_priv) * **/ -int bla_check_bcast_duplist(struct bat_priv *bat_priv, - struct bcast_packet *bcast_packet, - int hdr_size) +int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, + struct bcast_packet *bcast_packet, + int hdr_size) { int i, length, curr; uint8_t *content; @@ -1260,7 +1260,7 @@ int bla_check_bcast_duplist(struct bat_priv *bat_priv, * */ -int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) +int batadv_bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) { struct hashtable_t *hash = bat_priv->backbone_hash; struct hlist_head *head; @@ -1301,8 +1301,8 @@ int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) * returns 0. * */ -int bla_is_backbone_gw(struct sk_buff *skb, - struct orig_node *orig_node, int hdr_size) +int batadv_bla_is_backbone_gw(struct sk_buff *skb, + struct orig_node *orig_node, int hdr_size) { struct ethhdr *ethhdr; struct vlan_ethhdr *vhdr; @@ -1339,7 +1339,7 @@ int bla_is_backbone_gw(struct sk_buff *skb, } /* free all bla structures (for softinterface free or module unload) */ -void bla_free(struct bat_priv *bat_priv) +void batadv_bla_free(struct bat_priv *bat_priv) { struct hard_iface *primary_if; @@ -1374,7 +1374,7 @@ void bla_free(struct bat_priv *bat_priv) * process the skb. * */ -int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) +int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) { struct ethhdr *ethhdr; struct claim search_claim, *claim = NULL; @@ -1463,7 +1463,7 @@ out: * process the skb. * */ -int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) +int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) { struct ethhdr *ethhdr; struct claim search_claim, *claim = NULL; @@ -1537,7 +1537,7 @@ out: return ret; } -int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) +int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index e39f93acc28f..546cd641012a 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h @@ -23,73 +23,76 @@ #define _NET_BATMAN_ADV_BLA_H_ #ifdef CONFIG_BATMAN_ADV_BLA -int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); -int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); -int bla_is_backbone_gw(struct sk_buff *skb, - struct orig_node *orig_node, int hdr_size); -int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); -int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig); -int bla_check_bcast_duplist(struct bat_priv *bat_priv, - struct bcast_packet *bcast_packet, int hdr_size); -void bla_update_orig_address(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - struct hard_iface *oldif); -int bla_init(struct bat_priv *bat_priv); -void bla_free(struct bat_priv *bat_priv); +int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); +int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); +int batadv_bla_is_backbone_gw(struct sk_buff *skb, + struct orig_node *orig_node, int hdr_size); +int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); +int batadv_bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig); +int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, + struct bcast_packet *bcast_packet, + int hdr_size); +void batadv_bla_update_orig_address(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + struct hard_iface *oldif); +int batadv_bla_init(struct bat_priv *bat_priv); +void batadv_bla_free(struct bat_priv *bat_priv); #define BLA_CRC_INIT 0 #else /* ifdef CONFIG_BATMAN_ADV_BLA */ -static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, - short vid) +static inline int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, + short vid) { return 0; } -static inline int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, - short vid) +static inline int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, + short vid) { return 0; } -static inline int bla_is_backbone_gw(struct sk_buff *skb, - struct orig_node *orig_node, - int hdr_size) +static inline int batadv_bla_is_backbone_gw(struct sk_buff *skb, + struct orig_node *orig_node, + int hdr_size) { return 0; } -static inline int bla_claim_table_seq_print_text(struct seq_file *seq, - void *offset) +static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, + void *offset) { return 0; } -static inline int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, - uint8_t *orig) +static inline int batadv_bla_is_backbone_gw_orig(struct bat_priv *bat_priv, + uint8_t *orig) { return 0; } -static inline int bla_check_bcast_duplist(struct bat_priv *bat_priv, - struct bcast_packet *bcast_packet, - int hdr_size) +static inline int +batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, + struct bcast_packet *bcast_packet, + int hdr_size) { return 0; } -static inline void bla_update_orig_address(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - struct hard_iface *oldif) +static inline void +batadv_bla_update_orig_address(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + struct hard_iface *oldif) { } -static inline int bla_init(struct bat_priv *bat_priv) +static inline int batadv_bla_init(struct bat_priv *bat_priv) { return 1; } -static inline void bla_free(struct bat_priv *bat_priv) +static inline void batadv_bla_free(struct bat_priv *bat_priv) { } diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 380572e721e6..1643e7fca6c6 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -118,7 +118,7 @@ static void primary_if_update_addr(struct bat_priv *bat_priv, memcpy(vis_packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN); - bla_update_orig_address(bat_priv, primary_if, oldif); + batadv_bla_update_orig_address(bat_priv, primary_if, oldif); out: if (primary_if) hardif_free_ref(primary_if); diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 46a35e1c67ca..3e1bb7a1f8b4 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -125,7 +125,7 @@ int mesh_init(struct net_device *soft_iface) if (ret < 0) goto err; - ret = bla_init(bat_priv); + ret = batadv_bla_init(bat_priv); if (ret < 0) goto err; @@ -154,7 +154,7 @@ void mesh_free(struct net_device *soft_iface) tt_free(bat_priv); - bla_free(bat_priv); + batadv_bla_free(bat_priv); free_percpu(bat_priv->bat_counters); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index e573c32a619d..5b5feb496d8d 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -676,7 +676,7 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) * roaming advertisement from it, as it has the same * entries as we have. */ - if (bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src)) + if (batadv_bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src)) goto out; orig_node = orig_hash_find(bat_priv, roam_adv_packet->src); @@ -1089,7 +1089,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) spin_unlock_bh(&orig_node->bcast_seqno_lock); /* check whether this has been sent by another originator before */ - if (bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) + if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) goto out; /* rebroadcast packet */ @@ -1098,7 +1098,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* don't hand the broadcast up if it is from an originator * from the same backbone. */ - if (bla_is_backbone_gw(skb, orig_node, hdr_size)) + if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) goto out; /* broadcast for me */ diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 11bfe533e2a4..16e866ad1759 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -162,7 +162,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) goto dropped; } - if (bla_tx(bat_priv, skb, vid)) + if (batadv_bla_tx(bat_priv, skb, vid)) goto dropped; /* Register the client MAC in the transtable */ @@ -309,7 +309,7 @@ void interface_rx(struct net_device *soft_iface, /* Let the bridge loop avoidance check the packet. If will * not handle it, we can safely push it up. */ - if (bla_rx(bat_priv, skb, vid)) + if (batadv_bla_rx(bat_priv, skb, vid)) goto out; netif_rx(skb); diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a1a51cc9d88e..bb8557ea30f1 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1674,7 +1674,7 @@ bool send_tt_response(struct bat_priv *bat_priv, { if (is_my_mac(tt_request->dst)) { /* don't answer backbone gws! */ - if (bla_is_backbone_gw_orig(bat_priv, tt_request->src)) + if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) return true; return send_my_tt_response(bat_priv, tt_request); @@ -1786,7 +1786,7 @@ void handle_tt_response(struct bat_priv *bat_priv, (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); /* we should have never asked a backbone gw */ - if (bla_is_backbone_gw_orig(bat_priv, tt_response->src)) + if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src)) goto out; orig_node = orig_hash_find(bat_priv, tt_response->src); @@ -2163,7 +2163,7 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, bool full_table = true; /* don't care about a backbone gateways updates. */ - if (bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) + if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) return; /* orig table not initialised AND first diff is in the OGM OR the ttvn -- GitLab From 7cf06bc6ff810178a7fb9f12aaa6b274fc520f6f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:29 +0200 Subject: [PATCH 2274/6849] batman-adv: Prefix gateway-client non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 2 +- net/batman-adv/bat_iv_ogm.c | 6 ++--- net/batman-adv/bat_sysfs.c | 4 ++-- net/batman-adv/gateway_client.c | 40 +++++++++++++++++---------------- net/batman-adv/gateway_client.h | 26 +++++++++++---------- net/batman-adv/gateway_common.c | 2 +- net/batman-adv/main.c | 2 +- net/batman-adv/originator.c | 7 +++--- net/batman-adv/soft-interface.c | 6 ++--- net/batman-adv/unicast.c | 2 +- 10 files changed, 51 insertions(+), 46 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 71b225c1b5ca..7b294b431f88 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -236,7 +236,7 @@ static int originators_open(struct inode *inode, struct file *file) static int gateways_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, gw_client_seq_print_text, net_dev); + return single_open(file, batadv_gw_client_seq_print_text, net_dev); } static int transtable_global_open(struct inode *inode, struct file *file) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 53bce95e5f33..defcac1184c4 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -729,8 +729,8 @@ update_tt: ntohs(batman_ogm_packet->tt_crc)); if (orig_node->gw_flags != batman_ogm_packet->gw_flags) - gw_node_update(bat_priv, orig_node, - batman_ogm_packet->gw_flags); + batadv_gw_node_update(bat_priv, orig_node, + batman_ogm_packet->gw_flags); orig_node->gw_flags = batman_ogm_packet->gw_flags; @@ -738,7 +738,7 @@ update_tt: if ((orig_node->gw_flags) && (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && (atomic_read(&bat_priv->gw_sel_class) > 2)) - gw_check_election(bat_priv, orig_node); + batadv_gw_check_election(bat_priv, orig_node); goto out; diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 5dce1abc35d4..31d23dbccc38 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -326,7 +326,7 @@ static ssize_t show_bat_algo(struct kobject *kobj, struct attribute *attr, static void post_gw_deselect(struct net_device *net_dev) { struct bat_priv *bat_priv = netdev_priv(net_dev); - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); } static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, @@ -397,7 +397,7 @@ static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, bat_info(net_dev, "Changing gw mode from: %s to: %s\n", curr_gw_mode_str, buff); - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); return count; } diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 1d7f08e026f3..a28d9ce86812 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -60,7 +60,7 @@ out: return gw_node; } -struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv) +struct orig_node *batadv_gw_get_selected_orig(struct bat_priv *bat_priv) { struct gw_node *gw_node; struct orig_node *orig_node = NULL; @@ -103,7 +103,7 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node) spin_unlock_bh(&bat_priv->gw_list_lock); } -void gw_deselect(struct bat_priv *bat_priv) +void batadv_gw_deselect(struct bat_priv *bat_priv) { atomic_set(&bat_priv->gw_reselect, 1); } @@ -182,7 +182,7 @@ next: return curr_gw; } -void gw_election(struct bat_priv *bat_priv) +void batadv_gw_election(struct bat_priv *bat_priv) { struct gw_node *curr_gw = NULL, *next_gw = NULL; struct neigh_node *router = NULL; @@ -212,7 +212,7 @@ void gw_election(struct bat_priv *bat_priv) router = orig_node_get_router(next_gw->orig_node); if (!router) { - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); goto out; } } @@ -246,13 +246,14 @@ out: neigh_node_free_ref(router); } -void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) +void batadv_gw_check_election(struct bat_priv *bat_priv, + struct orig_node *orig_node) { struct orig_node *curr_gw_orig; struct neigh_node *router_gw = NULL, *router_orig = NULL; uint8_t gw_tq_avg, orig_tq_avg; - curr_gw_orig = gw_get_selected_orig(bat_priv); + curr_gw_orig = batadv_gw_get_selected_orig(bat_priv); if (!curr_gw_orig) goto deselect; @@ -288,7 +289,7 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) gw_tq_avg, orig_tq_avg); deselect: - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); out: if (curr_gw_orig) orig_node_free_ref(curr_gw_orig); @@ -328,8 +329,8 @@ static void gw_node_add(struct bat_priv *bat_priv, (up > 2048 ? "MBit" : "KBit")); } -void gw_node_update(struct bat_priv *bat_priv, - struct orig_node *orig_node, uint8_t new_gwflags) +void batadv_gw_node_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags) { struct hlist_node *node; struct gw_node *gw_node, *curr_gw; @@ -374,7 +375,7 @@ void gw_node_update(struct bat_priv *bat_priv, goto unlock; deselect: - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); unlock: rcu_read_unlock(); @@ -382,12 +383,13 @@ unlock: gw_node_free_ref(curr_gw); } -void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) +void batadv_gw_node_delete(struct bat_priv *bat_priv, + struct orig_node *orig_node) { - gw_node_update(bat_priv, orig_node, 0); + batadv_gw_node_update(bat_priv, orig_node, 0); } -void gw_node_purge(struct bat_priv *bat_priv) +void batadv_gw_node_purge(struct bat_priv *bat_priv) { struct gw_node *gw_node, *curr_gw; struct hlist_node *node, *node_tmp; @@ -416,7 +418,7 @@ void gw_node_purge(struct bat_priv *bat_priv) /* gw_deselect() needs to acquire the gw_list_lock */ if (do_deselect) - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); if (curr_gw) gw_node_free_ref(curr_gw); @@ -458,7 +460,7 @@ out: return ret; } -int gw_client_seq_print_text(struct seq_file *seq, void *offset) +int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); @@ -568,7 +570,7 @@ out: return ret; } -bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) +bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) { struct ethhdr *ethhdr; struct iphdr *iphdr; @@ -634,8 +636,8 @@ bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) return true; } -bool gw_out_of_range(struct bat_priv *bat_priv, - struct sk_buff *skb, struct ethhdr *ethhdr) +bool batadv_gw_out_of_range(struct bat_priv *bat_priv, + struct sk_buff *skb, struct ethhdr *ethhdr) { struct neigh_node *neigh_curr = NULL, *neigh_old = NULL; struct orig_node *orig_dst_node = NULL; @@ -644,7 +646,7 @@ bool gw_out_of_range(struct bat_priv *bat_priv, unsigned int header_len = 0; uint8_t curr_tq_avg; - ret = gw_is_dhcp_target(skb, &header_len); + ret = batadv_gw_is_dhcp_target(skb, &header_len); if (!ret) goto out; diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h index bf56a5aea10b..2c2446f3f124 100644 --- a/net/batman-adv/gateway_client.h +++ b/net/batman-adv/gateway_client.h @@ -22,17 +22,19 @@ #ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ #define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ -void gw_deselect(struct bat_priv *bat_priv); -void gw_election(struct bat_priv *bat_priv); -struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv); -void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node); -void gw_node_update(struct bat_priv *bat_priv, - struct orig_node *orig_node, uint8_t new_gwflags); -void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); -void gw_node_purge(struct bat_priv *bat_priv); -int gw_client_seq_print_text(struct seq_file *seq, void *offset); -bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len); -bool gw_out_of_range(struct bat_priv *bat_priv, - struct sk_buff *skb, struct ethhdr *ethhdr); +void batadv_gw_deselect(struct bat_priv *bat_priv); +void batadv_gw_election(struct bat_priv *bat_priv); +struct orig_node *batadv_gw_get_selected_orig(struct bat_priv *bat_priv); +void batadv_gw_check_election(struct bat_priv *bat_priv, + struct orig_node *orig_node); +void batadv_gw_node_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags); +void batadv_gw_node_delete(struct bat_priv *bat_priv, + struct orig_node *orig_node); +void batadv_gw_node_purge(struct bat_priv *bat_priv); +int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset); +bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len); +bool batadv_gw_out_of_range(struct bat_priv *bat_priv, + struct sk_buff *skb, struct ethhdr *ethhdr); #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 6e3b052b935d..a0b0f52d961a 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -165,7 +165,7 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) return count; - gw_deselect(bat_priv); + batadv_gw_deselect(bat_priv); bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 3e1bb7a1f8b4..8fe70b487b49 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -149,7 +149,7 @@ void mesh_free(struct net_device *soft_iface) vis_quit(bat_priv); - gw_node_purge(bat_priv); + batadv_gw_node_purge(bat_priv); originator_free(bat_priv); tt_free(bat_priv); diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index cf83c5422e9a..2f921bff84a9 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -361,7 +361,8 @@ static void _purge_orig(struct bat_priv *bat_priv) head, hash_entry) { if (purge_orig_node(bat_priv, orig_node)) { if (orig_node->gw_flags) - gw_node_delete(bat_priv, orig_node); + batadv_gw_node_delete(bat_priv, + orig_node); hlist_del_rcu(node); orig_node_free_ref(orig_node); continue; @@ -374,8 +375,8 @@ static void _purge_orig(struct bat_priv *bat_priv) spin_unlock_bh(list_lock); } - gw_node_purge(bat_priv); - gw_election(bat_priv); + batadv_gw_node_purge(bat_priv); + batadv_gw_election(bat_priv); } static void purge_orig(struct work_struct *work) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 16e866ad1759..bfc4fe03cafa 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -181,14 +181,14 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) case GW_MODE_SERVER: /* gateway servers should not send dhcp * requests into the mesh */ - ret = gw_is_dhcp_target(skb, &header_len); + ret = batadv_gw_is_dhcp_target(skb, &header_len); if (ret) goto dropped; break; case GW_MODE_CLIENT: /* gateway clients should send dhcp requests * via unicast to their gateway */ - ret = gw_is_dhcp_target(skb, &header_len); + ret = batadv_gw_is_dhcp_target(skb, &header_len); if (ret) do_bcast = false; break; @@ -232,7 +232,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) /* unicast packet */ } else { if (atomic_read(&bat_priv->gw_mode) != GW_MODE_OFF) { - ret = gw_out_of_range(bat_priv, skb, ethhdr); + ret = batadv_gw_out_of_range(bat_priv, skb, ethhdr); if (ret) goto dropped; } diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 74175c210858..92d3ea3e6ce4 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -294,7 +294,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* get routing information */ if (is_multicast_ether_addr(ethhdr->h_dest)) { - orig_node = gw_get_selected_orig(bat_priv); + orig_node = batadv_gw_get_selected_orig(bat_priv); if (orig_node) goto find_router; } -- GitLab From 84d5e5e003752bc56b413f8d2c3fcfeeec066145 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:30 +0200 Subject: [PATCH 2275/6849] batman-adv: Prefix gateway-common non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 4 ++-- net/batman-adv/gateway_client.c | 12 +++++++----- net/batman-adv/gateway_common.c | 7 ++++--- net/batman-adv/gateway_common.h | 5 +++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 31d23dbccc38..a8fb66095d83 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -409,7 +409,7 @@ static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, int down, up; int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); - gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); + batadv_gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); return sprintf(buff, "%i%s/%i%s\n", (down > 2048 ? down / 1024 : down), (down > 2048 ? "MBit" : "KBit"), @@ -425,7 +425,7 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, if (buff[count - 1] == '\n') buff[count - 1] = '\0'; - return gw_bandwidth_set(net_dev, buff, count); + return batadv_gw_bandwidth_set(net_dev, buff, count); } BAT_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index a28d9ce86812..a3f944b6ac53 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -116,13 +116,15 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) uint32_t max_gw_factor = 0, tmp_gw_factor = 0; uint8_t max_tq = 0; int down, up; + struct orig_node *orig_node; rcu_read_lock(); hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { if (gw_node->deleted) continue; - router = orig_node_get_router(gw_node->orig_node); + orig_node = gw_node->orig_node; + router = orig_node_get_router(orig_node); if (!router) continue; @@ -131,8 +133,8 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) switch (atomic_read(&bat_priv->gw_sel_class)) { case 1: /* fast connection */ - gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, - &down, &up); + batadv_gw_bandwidth_to_kbit(orig_node->gw_flags, + &down, &up); tmp_gw_factor = (router->tq_avg * router->tq_avg * down * 100 * 100) / @@ -319,7 +321,7 @@ static void gw_node_add(struct bat_priv *bat_priv, hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); spin_unlock_bh(&bat_priv->gw_list_lock); - gw_bandwidth_to_kbit(new_gwflags, &down, &up); + batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up); bat_dbg(DBG_BATMAN, bat_priv, "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", orig_node->orig, new_gwflags, @@ -434,7 +436,7 @@ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, struct neigh_node *router; int down, up, ret = -1; - gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); + batadv_gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); router = orig_node_get_router(gw_node->orig_node); if (!router) diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index a0b0f52d961a..722c93282442 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -59,7 +59,7 @@ static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) } /* returns the up and downspeeds in kbit, calculated from the class */ -void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) +void batadv_gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) { int sbit = (gw_srv_class & 0x80) >> 7; int dpart = (gw_srv_class & 0x78) >> 3; @@ -136,7 +136,8 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, return true; } -ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) +ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, + size_t count) { struct bat_priv *bat_priv = netdev_priv(net_dev); long gw_bandwidth_tmp = 0; @@ -160,7 +161,7 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) * speeds, hence we need to calculate it back to show the number * that is going to be propagated **/ - gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up); + batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up); if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) return count; diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h index b8fb11c4f927..e256040760bf 100644 --- a/net/batman-adv/gateway_common.h +++ b/net/batman-adv/gateway_common.h @@ -32,7 +32,8 @@ enum gw_modes { #define GW_MODE_CLIENT_NAME "client" #define GW_MODE_SERVER_NAME "server" -void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); -ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count); +void batadv_gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); +ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, + size_t count); #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ -- GitLab From 9563877ea52ea18bb4f1ed724c5e3a39bbbcf60b Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:31 +0200 Subject: [PATCH 2276/6849] batman-adv: Prefix hard-interface non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 20 ++++++++++--------- net/batman-adv/hard-interface.c | 32 +++++++++++++++--------------- net/batman-adv/hard-interface.h | 22 ++++++++++---------- net/batman-adv/main.c | 6 +++--- net/batman-adv/soft-interface.c | 2 +- net/batman-adv/translation-table.c | 2 +- 6 files changed, 43 insertions(+), 41 deletions(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index a8fb66095d83..5a7b042873e1 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -122,9 +122,10 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff, size_t count) \ { \ struct net_device *net_dev = kobj_to_netdev(kobj); \ - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ + struct hard_iface *hard_iface; \ ssize_t length; \ \ + hard_iface = batadv_hardif_get_by_netdev(net_dev); \ if (!hard_iface) \ return 0; \ \ @@ -140,9 +141,10 @@ ssize_t show_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff) \ { \ struct net_device *net_dev = kobj_to_netdev(kobj); \ - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ + struct hard_iface *hard_iface; \ ssize_t length; \ \ + hard_iface = batadv_hardif_get_by_netdev(net_dev); \ if (!hard_iface) \ return 0; \ \ @@ -433,7 +435,7 @@ BAT_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); #ifdef CONFIG_BATMAN_ADV_BLA BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); #endif -BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); +BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL); @@ -523,7 +525,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, char *buff) { struct net_device *net_dev = kobj_to_netdev(kobj); - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); + struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); ssize_t length; if (!hard_iface) @@ -541,7 +543,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, char *buff, size_t count) { struct net_device *net_dev = kobj_to_netdev(kobj); - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); + struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); int status_tmp = -1; int ret = count; @@ -576,15 +578,15 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, } if (status_tmp == IF_NOT_IN_USE) { - hardif_disable_interface(hard_iface); + batadv_hardif_disable_interface(hard_iface); goto unlock; } /* if the interface already is in use */ if (hard_iface->if_status != IF_NOT_IN_USE) - hardif_disable_interface(hard_iface); + batadv_hardif_disable_interface(hard_iface); - ret = hardif_enable_interface(hard_iface, buff); + ret = batadv_hardif_enable_interface(hard_iface, buff); unlock: rtnl_unlock(); @@ -597,7 +599,7 @@ static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, char *buff) { struct net_device *net_dev = kobj_to_netdev(kobj); - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); + struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); ssize_t length; if (!hard_iface) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 1643e7fca6c6..4f44f049186f 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -32,7 +32,7 @@ #include -void hardif_free_rcu(struct rcu_head *rcu) +void batadv_hardif_free_rcu(struct rcu_head *rcu) { struct hard_iface *hard_iface; @@ -41,7 +41,7 @@ void hardif_free_rcu(struct rcu_head *rcu) kfree(hard_iface); } -struct hard_iface *hardif_get_by_netdev(const struct net_device *net_dev) +struct hard_iface *batadv_hardif_get_by_netdev(const struct net_device *net_dev) { struct hard_iface *hard_iface; @@ -180,7 +180,7 @@ static void check_known_mac_addr(const struct net_device *net_dev) rcu_read_unlock(); } -int hardif_min_mtu(struct net_device *soft_iface) +int batadv_hardif_min_mtu(struct net_device *soft_iface) { const struct bat_priv *bat_priv = netdev_priv(soft_iface); const struct hard_iface *hard_iface; @@ -209,11 +209,11 @@ out: } /* adjusts the MTU if a new interface with a smaller MTU appeared. */ -void update_min_mtu(struct net_device *soft_iface) +void batadv_update_min_mtu(struct net_device *soft_iface) { int min_mtu; - min_mtu = hardif_min_mtu(soft_iface); + min_mtu = batadv_hardif_min_mtu(soft_iface); if (soft_iface->mtu != min_mtu) soft_iface->mtu = min_mtu; } @@ -242,7 +242,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) bat_info(hard_iface->soft_iface, "Interface activated: %s\n", hard_iface->net_dev->name); - update_min_mtu(hard_iface->soft_iface); + batadv_update_min_mtu(hard_iface->soft_iface); out: if (primary_if) @@ -260,11 +260,11 @@ static void hardif_deactivate_interface(struct hard_iface *hard_iface) bat_info(hard_iface->soft_iface, "Interface deactivated: %s\n", hard_iface->net_dev->name); - update_min_mtu(hard_iface->soft_iface); + batadv_update_min_mtu(hard_iface->soft_iface); } -int hardif_enable_interface(struct hard_iface *hard_iface, - const char *iface_name) +int batadv_hardif_enable_interface(struct hard_iface *hard_iface, + const char *iface_name) { struct bat_priv *bat_priv; struct net_device *soft_iface; @@ -357,7 +357,7 @@ err: return ret; } -void hardif_disable_interface(struct hard_iface *hard_iface) +void batadv_hardif_disable_interface(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct hard_iface *primary_if = NULL; @@ -461,7 +461,7 @@ static void hardif_remove_interface(struct hard_iface *hard_iface) /* first deactivate interface */ if (hard_iface->if_status != IF_NOT_IN_USE) - hardif_disable_interface(hard_iface); + batadv_hardif_disable_interface(hard_iface); if (hard_iface->if_status != IF_NOT_IN_USE) return; @@ -471,7 +471,7 @@ static void hardif_remove_interface(struct hard_iface *hard_iface) hardif_free_ref(hard_iface); } -void hardif_remove_interfaces(void) +void batadv_hardif_remove_interfaces(void) { struct hard_iface *hard_iface, *hard_iface_tmp; @@ -488,7 +488,7 @@ static int hard_if_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *net_dev = ptr; - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); + struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); struct hard_iface *primary_if = NULL; struct bat_priv *bat_priv; @@ -513,7 +513,7 @@ static int hard_if_event(struct notifier_block *this, break; case NETDEV_CHANGEMTU: if (hard_iface->soft_iface) - update_min_mtu(hard_iface->soft_iface); + batadv_update_min_mtu(hard_iface->soft_iface); break; case NETDEV_CHANGEADDR: if (hard_iface->if_status == IF_NOT_IN_USE) @@ -545,7 +545,7 @@ out: /* This function returns true if the interface represented by ifindex is a * 802.11 wireless device */ -bool is_wifi_iface(int ifindex) +bool batadv_is_wifi_iface(int ifindex) { struct net_device *net_device = NULL; bool ret = false; @@ -573,6 +573,6 @@ out: return ret; } -struct notifier_block hard_if_notifier = { +struct notifier_block batadv_hard_if_notifier = { .notifier_call = hard_if_event, }; diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index e68c5655e616..20e09db29d15 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -31,23 +31,23 @@ enum hard_if_state { IF_I_WANT_YOU }; -extern struct notifier_block hard_if_notifier; +extern struct notifier_block batadv_hard_if_notifier; struct hard_iface* -hardif_get_by_netdev(const struct net_device *net_dev); -int hardif_enable_interface(struct hard_iface *hard_iface, - const char *iface_name); -void hardif_disable_interface(struct hard_iface *hard_iface); -void hardif_remove_interfaces(void); -int hardif_min_mtu(struct net_device *soft_iface); -void update_min_mtu(struct net_device *soft_iface); -void hardif_free_rcu(struct rcu_head *rcu); -bool is_wifi_iface(int ifindex); +batadv_hardif_get_by_netdev(const struct net_device *net_dev); +int batadv_hardif_enable_interface(struct hard_iface *hard_iface, + const char *iface_name); +void batadv_hardif_disable_interface(struct hard_iface *hard_iface); +void batadv_hardif_remove_interfaces(void); +int batadv_hardif_min_mtu(struct net_device *soft_iface); +void batadv_update_min_mtu(struct net_device *soft_iface); +void batadv_hardif_free_rcu(struct rcu_head *rcu); +bool batadv_is_wifi_iface(int ifindex); static inline void hardif_free_ref(struct hard_iface *hard_iface) { if (atomic_dec_and_test(&hard_iface->refcount)) - call_rcu(&hard_iface->rcu, hardif_free_rcu); + call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu); } static inline struct hard_iface *primary_if_get_selected( diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 8fe70b487b49..8e4083612523 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -68,7 +68,7 @@ static int __init batman_init(void) bat_socket_init(); batadv_debugfs_init(); - register_netdevice_notifier(&hard_if_notifier); + register_netdevice_notifier(&batadv_hard_if_notifier); pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", SOURCE_VERSION, COMPAT_VERSION); @@ -79,8 +79,8 @@ static int __init batman_init(void) static void __exit batman_exit(void) { batadv_debugfs_destroy(); - unregister_netdevice_notifier(&hard_if_notifier); - hardif_remove_interfaces(); + unregister_netdevice_notifier(&batadv_hard_if_notifier); + batadv_hardif_remove_interfaces(); flush_workqueue(bat_event_workqueue); destroy_workqueue(bat_event_workqueue); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index bfc4fe03cafa..5bf9a73ae799 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -122,7 +122,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p) static int interface_change_mtu(struct net_device *dev, int new_mtu) { /* check ranges */ - if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev))) + if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev))) return -EINVAL; dev->mtu = new_mtu; diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index bb8557ea30f1..7324b89bf731 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -221,7 +221,7 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); tt_local_entry->common.flags = NO_FLAGS; - if (is_wifi_iface(ifindex)) + if (batadv_is_wifi_iface(ifindex)) tt_local_entry->common.flags |= TT_CLIENT_WIFI; atomic_set(&tt_local_entry->common.refcount, 2); tt_local_entry->last_seen = jiffies; -- GitLab From 1a8eaf0733ca754533a03d6cfa4463def2b81ce3 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:32 +0200 Subject: [PATCH 2277/6849] batman-adv: Prefix hash non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 8 ++++---- net/batman-adv/hash.c | 4 ++-- net/batman-adv/hash.h | 6 +++--- net/batman-adv/originator.c | 4 ++-- net/batman-adv/translation-table.c | 8 ++++---- net/batman-adv/vis.c | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index b0561e338ae5..eb2178951c39 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1166,8 +1166,8 @@ int batadv_bla_init(struct bat_priv *bat_priv) if (bat_priv->claim_hash) return 0; - bat_priv->claim_hash = hash_new(128); - bat_priv->backbone_hash = hash_new(32); + bat_priv->claim_hash = batadv_hash_new(128); + bat_priv->backbone_hash = batadv_hash_new(32); if (!bat_priv->claim_hash || !bat_priv->backbone_hash) return -ENOMEM; @@ -1348,12 +1348,12 @@ void batadv_bla_free(struct bat_priv *bat_priv) if (bat_priv->claim_hash) { bla_purge_claims(bat_priv, primary_if, 1); - hash_destroy(bat_priv->claim_hash); + batadv_hash_destroy(bat_priv->claim_hash); bat_priv->claim_hash = NULL; } if (bat_priv->backbone_hash) { bla_purge_backbone_gw(bat_priv, 1); - hash_destroy(bat_priv->backbone_hash); + batadv_hash_destroy(bat_priv->backbone_hash); bat_priv->backbone_hash = NULL; } if (primary_if) diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index 5b2eabe7c4e0..65bbd15dd37c 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c @@ -34,7 +34,7 @@ static void hash_init(struct hashtable_t *hash) } /* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash) +void batadv_hash_destroy(struct hashtable_t *hash) { kfree(hash->list_locks); kfree(hash->table); @@ -42,7 +42,7 @@ void hash_destroy(struct hashtable_t *hash) } /* allocates and clears the hash */ -struct hashtable_t *hash_new(uint32_t size) +struct hashtable_t *batadv_hash_new(uint32_t size) { struct hashtable_t *hash; diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index 3d67ce49fc31..e75df6be4f22 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h @@ -43,14 +43,14 @@ struct hashtable_t { }; /* allocates and clears the hash */ -struct hashtable_t *hash_new(uint32_t size); +struct hashtable_t *batadv_hash_new(uint32_t size); /* set class key for all locks */ void batadv_hash_set_lock_class(struct hashtable_t *hash, struct lock_class_key *key); /* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash); +void batadv_hash_destroy(struct hashtable_t *hash); /* remove the hash structure. if hashdata_free_cb != NULL, this function will be * called to remove the elements inside of the hash. if you don't remove the @@ -77,7 +77,7 @@ static inline void hash_delete(struct hashtable_t *hash, spin_unlock_bh(list_lock); } - hash_destroy(hash); + batadv_hash_destroy(hash); } /** diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 2f921bff84a9..410a197854ed 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -52,7 +52,7 @@ int originator_init(struct bat_priv *bat_priv) if (bat_priv->orig_hash) return 0; - bat_priv->orig_hash = hash_new(1024); + bat_priv->orig_hash = batadv_hash_new(1024); if (!bat_priv->orig_hash) goto err; @@ -184,7 +184,7 @@ void originator_free(struct bat_priv *bat_priv) spin_unlock_bh(list_lock); } - hash_destroy(hash); + batadv_hash_destroy(hash); } /* this function finds or creates an originator entry for the given diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 7324b89bf731..a7cbc915afef 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -183,7 +183,7 @@ static int tt_local_init(struct bat_priv *bat_priv) if (bat_priv->tt_local_hash) return 0; - bat_priv->tt_local_hash = hash_new(1024); + bat_priv->tt_local_hash = batadv_hash_new(1024); if (!bat_priv->tt_local_hash) return -ENOMEM; @@ -531,7 +531,7 @@ static void tt_local_table_free(struct bat_priv *bat_priv) spin_unlock_bh(list_lock); } - hash_destroy(hash); + batadv_hash_destroy(hash); bat_priv->tt_local_hash = NULL; } @@ -541,7 +541,7 @@ static int tt_global_init(struct bat_priv *bat_priv) if (bat_priv->tt_global_hash) return 0; - bat_priv->tt_global_hash = hash_new(1024); + bat_priv->tt_global_hash = batadv_hash_new(1024); if (!bat_priv->tt_global_hash) return -ENOMEM; @@ -1031,7 +1031,7 @@ static void tt_global_table_free(struct bat_priv *bat_priv) spin_unlock_bh(list_lock); } - hash_destroy(hash); + batadv_hash_destroy(hash); bat_priv->tt_global_hash = NULL; } diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 01d5da54143e..99f1931472f3 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -889,7 +889,7 @@ int vis_init(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->vis_hash_lock); - bat_priv->vis_hash = hash_new(256); + bat_priv->vis_hash = batadv_hash_new(256); if (!bat_priv->vis_hash) { pr_err("Can't initialize vis_hash\n"); goto err; -- GitLab From 9039dc7e8a42864744665bf0905f48c2724f6e3e Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:33 +0200 Subject: [PATCH 2278/6849] batman-adv: Prefix icmp-socket non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 2 +- net/batman-adv/icmp_socket.c | 8 ++++---- net/batman-adv/icmp_socket.h | 8 ++++---- net/batman-adv/main.c | 2 +- net/batman-adv/routing.c | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 7b294b431f88..9177a0619906 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -349,7 +349,7 @@ int batadv_debugfs_add_meshif(struct net_device *dev) if (!bat_priv->debug_dir) goto out; - if (bat_socket_setup(bat_priv) < 0) + if (batadv_socket_setup(bat_priv) < 0) goto rem_attr; if (debug_log_setup(bat_priv) < 0) diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index d27db8192e93..38ca3a853a2b 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -34,7 +34,7 @@ static void bat_socket_add_packet(struct socket_client *socket_client, struct icmp_packet_rr *icmp_packet, size_t icmp_len); -void bat_socket_init(void) +void batadv_socket_init(void) { memset(socket_client_hash, 0, sizeof(socket_client_hash)); } @@ -276,7 +276,7 @@ static const struct file_operations fops = { .llseek = no_llseek, }; -int bat_socket_setup(struct bat_priv *bat_priv) +int batadv_socket_setup(struct bat_priv *bat_priv) { struct dentry *d; @@ -336,8 +336,8 @@ static void bat_socket_add_packet(struct socket_client *socket_client, wake_up(&socket_client->queue_wait); } -void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, - size_t icmp_len) +void batadv_socket_receive_packet(struct icmp_packet_rr *icmp_packet, + size_t icmp_len) { struct socket_client *hash = socket_client_hash[icmp_packet->uid]; diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h index 380ed4c2443a..7b8863668490 100644 --- a/net/batman-adv/icmp_socket.h +++ b/net/batman-adv/icmp_socket.h @@ -24,9 +24,9 @@ #define ICMP_SOCKET "socket" -void bat_socket_init(void); -int bat_socket_setup(struct bat_priv *bat_priv); -void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, - size_t icmp_len); +void batadv_socket_init(void); +int batadv_socket_setup(struct bat_priv *bat_priv); +void batadv_socket_receive_packet(struct icmp_packet_rr *icmp_packet, + size_t icmp_len); #endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */ diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 8e4083612523..84dbda50aa90 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -65,7 +65,7 @@ static int __init batman_init(void) if (!bat_event_workqueue) return -ENOMEM; - bat_socket_init(); + batadv_socket_init(); batadv_debugfs_init(); register_netdevice_notifier(&batadv_hard_if_notifier); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 5b5feb496d8d..7525e4fd2faf 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -289,7 +289,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, /* add data to device queue */ if (icmp_packet->msg_type != ECHO_REQUEST) { - bat_socket_receive_packet(icmp_packet, icmp_len); + batadv_socket_receive_packet(icmp_packet, icmp_len); goto out; } -- GitLab From 7d211efc5087bc8870fa3374da88b4bf8159e79b Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:34 +0200 Subject: [PATCH 2279/6849] batman-adv: Prefix originator non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 2 +- net/batman-adv/bat_iv_ogm.c | 43 +++++++++---------- net/batman-adv/bridge_loop_avoidance.c | 4 +- net/batman-adv/gateway_client.c | 28 ++++++------- net/batman-adv/hard-interface.c | 6 +-- net/batman-adv/icmp_socket.c | 6 +-- net/batman-adv/main.c | 4 +- net/batman-adv/originator.c | 35 ++++++++-------- net/batman-adv/originator.h | 21 +++++----- net/batman-adv/routing.c | 58 +++++++++++++------------- net/batman-adv/translation-table.c | 32 +++++++------- net/batman-adv/unicast.c | 6 +-- net/batman-adv/vis.c | 20 ++++----- 13 files changed, 134 insertions(+), 131 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 9177a0619906..51b67f4a064b 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -230,7 +230,7 @@ static int bat_algorithms_open(struct inode *inode, struct file *file) static int originators_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, orig_seq_print_text, net_dev); + return single_open(file, batadv_orig_seq_print_text, net_dev); } static int gateways_open(struct inode *inode, struct file *file) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index defcac1184c4..9c8c9d017d00 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -633,7 +633,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, (tmp_neigh_node->if_incoming == if_incoming) && atomic_inc_not_zero(&tmp_neigh_node->refcount)) { if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); neigh_node = tmp_neigh_node; continue; } @@ -652,7 +652,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, if (!neigh_node) { struct orig_node *orig_tmp; - orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); + orig_tmp = batadv_get_orig_node(bat_priv, ethhdr->h_source); if (!orig_tmp) goto unlock; @@ -660,7 +660,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, orig_node, orig_tmp, batman_ogm_packet->seqno); - orig_node_free_ref(orig_tmp); + batadv_orig_node_free_ref(orig_tmp); if (!neigh_node) goto unlock; } else @@ -688,7 +688,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, /* if this neighbor already is our next hop there is nothing * to change */ - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (router == neigh_node) goto update_tt; @@ -746,9 +746,9 @@ unlock: rcu_read_unlock(); out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, @@ -848,7 +848,7 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); return ret; } @@ -875,7 +875,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, int set_mark, ret = -1; uint32_t seqno = ntohl(batman_ogm_packet->seqno); - orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); + orig_node = batadv_get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) return 0; @@ -924,7 +924,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, out: spin_unlock_bh(&orig_node->ogm_cnt_lock); - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } @@ -1029,7 +1029,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, unsigned long *word; int offset; - orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); + orig_neigh_node = batadv_get_orig_node(bat_priv, + ethhdr->h_source); if (!orig_neigh_node) return; @@ -1053,7 +1054,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: originator packet from myself (via neighbor)\n"); - orig_node_free_ref(orig_neigh_node); + batadv_orig_node_free_ref(orig_neigh_node); return; } @@ -1071,7 +1072,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, return; } - orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); + orig_node = batadv_get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) return; @@ -1091,9 +1092,9 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, goto out; } - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (router) - router_router = orig_node_get_router(router->orig_node); + router_router = batadv_orig_node_get_router(router->orig_node); if ((router && router->tq_avg != 0) && (compare_eth(router->addr, ethhdr->h_source))) @@ -1115,11 +1116,11 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, * originator mac */ orig_neigh_node = (is_single_hop_neigh ? orig_node : - get_orig_node(bat_priv, ethhdr->h_source)); + batadv_get_orig_node(bat_priv, ethhdr->h_source)); if (!orig_neigh_node) goto out; - orig_neigh_router = orig_node_get_router(orig_neigh_node); + orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node); /* drop packet if sender is not a direct neighbor and if we * don't route towards it */ @@ -1178,16 +1179,16 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, out_neigh: if ((orig_neigh_node) && (!is_single_hop_neigh)) - orig_node_free_ref(orig_neigh_node); + batadv_orig_node_free_ref(orig_neigh_node); out: if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (router_router) - neigh_node_free_ref(router_router); + batadv_neigh_node_free_ref(router_router); if (orig_neigh_router) - neigh_node_free_ref(orig_neigh_router); + batadv_neigh_node_free_ref(orig_neigh_router); - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } static int bat_iv_ogm_receive(struct sk_buff *skb, diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index eb2178951c39..c4b28af69297 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -399,7 +399,7 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, if (orig_node) { tt_global_del_orig(bat_priv, orig_node, "became a backbone gateway"); - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } return entry; } @@ -804,7 +804,7 @@ static int check_claim_group(struct bat_priv *bat_priv, bla_dst_own->group = bla_dst->group; } - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return 2; } diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index a3f944b6ac53..e92055da5074 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -124,7 +124,7 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) continue; orig_node = gw_node->orig_node; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) continue; @@ -177,7 +177,7 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) gw_node_free_ref(gw_node); next: - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } rcu_read_unlock(); @@ -212,7 +212,7 @@ void batadv_gw_election(struct bat_priv *bat_priv) if (next_gw) { sprintf(gw_addr, "%pM", next_gw->orig_node->orig); - router = orig_node_get_router(next_gw->orig_node); + router = batadv_orig_node_get_router(next_gw->orig_node); if (!router) { batadv_gw_deselect(bat_priv); goto out; @@ -245,7 +245,7 @@ out: if (next_gw) gw_node_free_ref(next_gw); if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } void batadv_gw_check_election(struct bat_priv *bat_priv, @@ -259,7 +259,7 @@ void batadv_gw_check_election(struct bat_priv *bat_priv, if (!curr_gw_orig) goto deselect; - router_gw = orig_node_get_router(curr_gw_orig); + router_gw = batadv_orig_node_get_router(curr_gw_orig); if (!router_gw) goto deselect; @@ -267,7 +267,7 @@ void batadv_gw_check_election(struct bat_priv *bat_priv, if (curr_gw_orig == orig_node) goto out; - router_orig = orig_node_get_router(orig_node); + router_orig = batadv_orig_node_get_router(orig_node); if (!router_orig) goto out; @@ -294,11 +294,11 @@ deselect: batadv_gw_deselect(bat_priv); out: if (curr_gw_orig) - orig_node_free_ref(curr_gw_orig); + batadv_orig_node_free_ref(curr_gw_orig); if (router_gw) - neigh_node_free_ref(router_gw); + batadv_neigh_node_free_ref(router_gw); if (router_orig) - neigh_node_free_ref(router_orig); + batadv_neigh_node_free_ref(router_orig); return; } @@ -438,7 +438,7 @@ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, batadv_gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); - router = orig_node_get_router(gw_node->orig_node); + router = batadv_orig_node_get_router(gw_node->orig_node); if (!router) goto out; @@ -455,7 +455,7 @@ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, (up > 2048 ? up / 1024 : up), (up > 2048 ? "MBit" : "KBit")); - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (curr_gw) gw_node_free_ref(curr_gw); out: @@ -702,12 +702,12 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, out: if (orig_dst_node) - orig_node_free_ref(orig_dst_node); + batadv_orig_node_free_ref(orig_dst_node); if (curr_gw) gw_node_free_ref(curr_gw); if (neigh_old) - neigh_node_free_ref(neigh_old); + batadv_neigh_node_free_ref(neigh_old); if (neigh_curr) - neigh_node_free_ref(neigh_curr); + batadv_neigh_node_free_ref(neigh_curr); return out_of_range; } diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 4f44f049186f..1f126cbd2c79 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -312,7 +312,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, hard_iface->if_num = bat_priv->num_ifaces; bat_priv->num_ifaces++; hard_iface->if_status = IF_INACTIVE; - orig_hash_add_if(hard_iface, bat_priv->num_ifaces); + batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); hard_iface->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); hard_iface->batman_adv_ptype.func = batman_skb_recv; @@ -373,7 +373,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) dev_remove_pack(&hard_iface->batman_adv_ptype); bat_priv->num_ifaces--; - orig_hash_del_if(hard_iface, bat_priv->num_ifaces); + batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); primary_if = primary_if_get_selected(bat_priv); if (hard_iface == primary_if) { @@ -390,7 +390,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) hard_iface->if_status = IF_NOT_IN_USE; /* delete all references to this hard_iface */ - purge_orig_ref(bat_priv); + batadv_purge_orig_ref(bat_priv); purge_outstanding_packets(bat_priv, hard_iface); dev_put(hard_iface->soft_iface); diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 38ca3a853a2b..44cbee58720b 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -219,7 +219,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, if (!orig_node) goto dst_unreach; - neigh_node = orig_node_get_router(orig_node); + neigh_node = batadv_orig_node_get_router(orig_node); if (!neigh_node) goto dst_unreach; @@ -248,9 +248,9 @@ out: if (primary_if) hardif_free_ref(primary_if); if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return len; } diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 84dbda50aa90..eba5d2899b25 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -111,7 +111,7 @@ int mesh_init(struct net_device *soft_iface) INIT_LIST_HEAD(&bat_priv->tt_req_list); INIT_LIST_HEAD(&bat_priv->tt_roam_list); - ret = originator_init(bat_priv); + ret = batadv_originator_init(bat_priv); if (ret < 0) goto err; @@ -150,7 +150,7 @@ void mesh_free(struct net_device *soft_iface) vis_quit(bat_priv); batadv_gw_node_purge(bat_priv); - originator_free(bat_priv); + batadv_originator_free(bat_priv); tt_free(bat_priv); diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 410a197854ed..93585132049f 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -47,7 +47,7 @@ static int compare_orig(const struct hlist_node *node, const void *data2) return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } -int originator_init(struct bat_priv *bat_priv) +int batadv_originator_init(struct bat_priv *bat_priv) { if (bat_priv->orig_hash) return 0; @@ -64,14 +64,14 @@ err: return -ENOMEM; } -void neigh_node_free_ref(struct neigh_node *neigh_node) +void batadv_neigh_node_free_ref(struct neigh_node *neigh_node) { if (atomic_dec_and_test(&neigh_node->refcount)) kfree_rcu(neigh_node, rcu); } /* increases the refcounter of a found router */ -struct neigh_node *orig_node_get_router(struct orig_node *orig_node) +struct neigh_node *batadv_orig_node_get_router(struct orig_node *orig_node) { struct neigh_node *router; @@ -126,14 +126,14 @@ static void orig_node_free_rcu(struct rcu_head *rcu) list_for_each_entry_safe(neigh_node, tmp_neigh_node, &orig_node->bond_list, bonding_list) { list_del_rcu(&neigh_node->bonding_list); - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); } /* for all neighbors towards this originator ... */ hlist_for_each_entry_safe(neigh_node, node, node_tmp, &orig_node->neigh_list, list) { hlist_del_rcu(&neigh_node->list); - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); } spin_unlock_bh(&orig_node->neigh_list_lock); @@ -148,13 +148,13 @@ static void orig_node_free_rcu(struct rcu_head *rcu) kfree(orig_node); } -void orig_node_free_ref(struct orig_node *orig_node) +void batadv_orig_node_free_ref(struct orig_node *orig_node) { if (atomic_dec_and_test(&orig_node->refcount)) call_rcu(&orig_node->rcu, orig_node_free_rcu); } -void originator_free(struct bat_priv *bat_priv) +void batadv_originator_free(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *node, *node_tmp; @@ -179,7 +179,7 @@ void originator_free(struct bat_priv *bat_priv) head, hash_entry) { hlist_del_rcu(node); - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } spin_unlock_bh(list_lock); } @@ -189,7 +189,8 @@ void originator_free(struct bat_priv *bat_priv) /* this function finds or creates an originator entry for the given * address if it does not exits */ -struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr) +struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, + const uint8_t *addr) { struct orig_node *orig_node; int size; @@ -307,7 +308,7 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, hlist_del_rcu(&neigh_node->list); bonding_candidate_del(orig_node, neigh_node); - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); } else { if ((!*best_neigh_node) || (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) @@ -364,7 +365,7 @@ static void _purge_orig(struct bat_priv *bat_priv) batadv_gw_node_delete(bat_priv, orig_node); hlist_del_rcu(node); - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); continue; } @@ -390,12 +391,12 @@ static void purge_orig(struct work_struct *work) start_purge_timer(bat_priv); } -void purge_orig_ref(struct bat_priv *bat_priv) +void batadv_purge_orig_ref(struct bat_priv *bat_priv) { _purge_orig(bat_priv); } -int orig_seq_print_text(struct seq_file *seq, void *offset) +int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); @@ -439,7 +440,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - neigh_node = orig_node_get_router(orig_node); + neigh_node = batadv_orig_node_get_router(orig_node); if (!neigh_node) continue; @@ -468,7 +469,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) batman_count++; next: - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); } rcu_read_unlock(); } @@ -508,7 +509,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) return 0; } -int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) +int batadv_orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; @@ -590,7 +591,7 @@ free_own_sum: return 0; } -int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) +int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index f74d0d693359..97deeba787ea 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -24,19 +24,20 @@ #include "hash.h" -int originator_init(struct bat_priv *bat_priv); -void originator_free(struct bat_priv *bat_priv); -void purge_orig_ref(struct bat_priv *bat_priv); -void orig_node_free_ref(struct orig_node *orig_node); -struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr); +int batadv_originator_init(struct bat_priv *bat_priv); +void batadv_originator_free(struct bat_priv *bat_priv); +void batadv_purge_orig_ref(struct bat_priv *bat_priv); +void batadv_orig_node_free_ref(struct orig_node *orig_node); +struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, + const uint8_t *addr); struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, const uint8_t *neigh_addr, uint32_t seqno); -void neigh_node_free_ref(struct neigh_node *neigh_node); -struct neigh_node *orig_node_get_router(struct orig_node *orig_node); -int orig_seq_print_text(struct seq_file *seq, void *offset); -int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num); -int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); +void batadv_neigh_node_free_ref(struct neigh_node *neigh_node); +struct neigh_node *batadv_orig_node_get_router(struct orig_node *orig_node); +int batadv_orig_seq_print_text(struct seq_file *seq, void *offset); +int batadv_orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num); +int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); /* hashfunction to choose an entry in a hash table of given size */ diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 7525e4fd2faf..77fe46065db6 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -69,7 +69,7 @@ static void _update_route(struct bat_priv *bat_priv, { struct neigh_node *curr_router; - curr_router = orig_node_get_router(orig_node); + curr_router = batadv_orig_node_get_router(orig_node); /* route deleted */ if ((curr_router) && (!neigh_node)) { @@ -93,7 +93,7 @@ static void _update_route(struct bat_priv *bat_priv, } if (curr_router) - neigh_node_free_ref(curr_router); + batadv_neigh_node_free_ref(curr_router); /* increase refcount of new best neighbor */ if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount)) @@ -105,7 +105,7 @@ static void _update_route(struct bat_priv *bat_priv, /* decrease refcount of previous best neighbor */ if (curr_router) - neigh_node_free_ref(curr_router); + batadv_neigh_node_free_ref(curr_router); } void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, @@ -116,14 +116,14 @@ void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, if (!orig_node) goto out; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (router != neigh_node) _update_route(bat_priv, orig_node, neigh_node); out: if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } /* caller must hold the neigh_list_lock */ @@ -136,7 +136,7 @@ void bonding_candidate_del(struct orig_node *orig_node, list_del_rcu(&neigh_node->bonding_list); INIT_LIST_HEAD(&neigh_node->bonding_list); - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); atomic_dec(&orig_node->bond_candidates); out: @@ -157,7 +157,7 @@ void bonding_candidate_add(struct orig_node *orig_node, neigh_node->orig_node->primary_addr)) goto candidate_del; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) goto candidate_del; @@ -210,7 +210,7 @@ out: spin_unlock_bh(&orig_node->neigh_list_lock); if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } /* copy primary address for bonding */ @@ -303,7 +303,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, if (!orig_node) goto out; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) goto out; @@ -325,9 +325,9 @@ out: if (primary_if) hardif_free_ref(primary_if); if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } @@ -358,7 +358,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, if (!orig_node) goto out; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) goto out; @@ -380,9 +380,9 @@ out: if (primary_if) hardif_free_ref(primary_if); if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } @@ -444,7 +444,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) if (!orig_node) goto out; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) goto out; @@ -463,9 +463,9 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) out: if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } @@ -551,13 +551,13 @@ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, /* decrement refcount of * previously selected router */ if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); router = tmp_neigh_node; atomic_inc_not_zero(&router->refcount); } - neigh_node_free_ref(tmp_neigh_node); + batadv_neigh_node_free_ref(tmp_neigh_node); } /* use the first candidate if nothing was found. */ @@ -695,7 +695,7 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) * packets for the correct destination. */ bat_priv->tt_poss_change = true; - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); out: /* returning NET_RX_DROP will make the caller function kfree the skb */ return NET_RX_DROP; @@ -717,7 +717,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, if (!orig_node) return NULL; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) goto err; @@ -750,7 +750,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, if (!primary_orig_node) goto return_router; - orig_node_free_ref(primary_orig_node); + batadv_orig_node_free_ref(primary_orig_node); } /* with less than 2 candidates, we can't do any @@ -762,7 +762,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, * is is not on the interface where the packet came * in. */ - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (bonding_enabled) router = find_bond_router(primary_orig_node, recv_if); @@ -779,7 +779,7 @@ err_unlock: rcu_read_unlock(); err: if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); return NULL; } @@ -885,9 +885,9 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } @@ -917,7 +917,7 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); tt_poss_change = orig_node->tt_poss_change; - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } /* Check whether I have to reroute the packet */ @@ -952,7 +952,7 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, ETH_ALEN); curr_ttvn = (uint8_t) atomic_read(&orig_node->last_ttvn); - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } bat_dbg(DBG_ROUTES, bat_priv, @@ -1110,7 +1110,7 @@ spin_unlock: spin_unlock_bh(&orig_node->bcast_seqno_lock); out: if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a7cbc915afef..3d2c3b142cf1 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -142,7 +142,7 @@ static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu) orig_entry = container_of(rcu, struct tt_orig_list_entry, rcu); atomic_dec(&orig_entry->orig_node->tt_size); - orig_node_free_ref(orig_entry->orig_node); + batadv_orig_node_free_ref(orig_entry->orig_node); kfree(orig_entry); } @@ -1080,7 +1080,7 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv, rcu_read_lock(); head = &tt_global_entry->orig_list; hlist_for_each_entry_rcu(orig_entry, node, head, list) { - router = orig_node_get_router(orig_entry->orig_node); + router = batadv_orig_node_get_router(orig_entry->orig_node); if (!router) continue; @@ -1088,7 +1088,7 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv, orig_node = orig_entry->orig_node; best_tq = router->tq_avg; } - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } /* found anything? */ if (orig_node && !atomic_inc_not_zero(&orig_node->refcount)) @@ -1395,7 +1395,7 @@ static int send_tt_request(struct bat_priv *bat_priv, if (full_table) tt_request->flags |= TT_FULL_TABLE; - neigh_node = orig_node_get_router(dst_orig_node); + neigh_node = batadv_orig_node_get_router(dst_orig_node); if (!neigh_node) goto out; @@ -1411,7 +1411,7 @@ static int send_tt_request(struct bat_priv *bat_priv, out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (primary_if) hardif_free_ref(primary_if); if (ret) @@ -1453,7 +1453,7 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, if (!res_dst_orig_node) goto out; - neigh_node = orig_node_get_router(res_dst_orig_node); + neigh_node = batadv_orig_node_get_router(res_dst_orig_node); if (!neigh_node) goto out; @@ -1541,11 +1541,11 @@ unlock: out: if (res_dst_orig_node) - orig_node_free_ref(res_dst_orig_node); + batadv_orig_node_free_ref(res_dst_orig_node); if (req_dst_orig_node) - orig_node_free_ref(req_dst_orig_node); + batadv_orig_node_free_ref(req_dst_orig_node); if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (primary_if) hardif_free_ref(primary_if); if (!ret) @@ -1580,7 +1580,7 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, if (!orig_node) goto out; - neigh_node = orig_node_get_router(orig_node); + neigh_node = batadv_orig_node_get_router(orig_node); if (!neigh_node) goto out; @@ -1658,9 +1658,9 @@ unlock: spin_unlock_bh(&bat_priv->tt_buff_lock); out: if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (primary_if) hardif_free_ref(primary_if); if (!ret) @@ -1738,7 +1738,7 @@ static void tt_fill_gtable(struct bat_priv *bat_priv, out: if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } static void tt_update_changes(struct bat_priv *bat_priv, @@ -1818,7 +1818,7 @@ void handle_tt_response(struct bat_priv *bat_priv, orig_node->tt_poss_change = false; out: if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } int tt_init(struct bat_priv *bat_priv) @@ -1947,7 +1947,7 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN); memcpy(roam_adv_packet->client, client, ETH_ALEN); - neigh_node = orig_node_get_router(orig_node); + neigh_node = batadv_orig_node_get_router(orig_node); if (!neigh_node) goto out; @@ -1962,7 +1962,7 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (ret) kfree_skb(skb); return; diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 92d3ea3e6ce4..6117100c292c 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -212,7 +212,7 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, out: if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } @@ -355,9 +355,9 @@ find_router: out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); if (ret == 1) kfree_skb(skb); return ret; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 99f1931472f3..1972a11aace1 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -574,7 +574,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv, rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) continue; @@ -584,7 +584,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv, memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); } - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); } rcu_read_unlock(); } @@ -641,7 +641,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) continue; @@ -665,7 +665,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) packet->entries++; next: - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (vis_packet_full(info)) goto unlock; @@ -757,7 +757,7 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, if (!(orig_node->flags & VIS_SERVER)) continue; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) continue; @@ -765,7 +765,7 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, * this node. */ if (recv_list_is_in(bat_priv, &info->recv_list, orig_node->orig)) { - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); continue; } @@ -773,7 +773,7 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, hard_iface = router->if_incoming; memcpy(dstaddr, router->addr, ETH_ALEN); - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) @@ -798,7 +798,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, if (!orig_node) goto out; - router = orig_node_get_router(orig_node); + router = batadv_orig_node_get_router(orig_node); if (!router) goto out; @@ -808,9 +808,9 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, out: if (router) - neigh_node_free_ref(router); + batadv_neigh_node_free_ref(router); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); } /* only send one vis packet. called from send_vis_packets() */ -- GitLab From 925a6672fae532ba178b8d35686705b417aada3d Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:35 +0200 Subject: [PATCH 2280/6849] batman-adv: Prefix ring_buffer non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 14 +++++++------- net/batman-adv/ring_buffer.c | 5 +++-- net/batman-adv/ring_buffer.h | 5 +++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 9c8c9d017d00..cd57cf2022c5 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -642,10 +642,10 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, continue; spin_lock_bh(&tmp_neigh_node->lq_update_lock); - ring_buffer_set(tmp_neigh_node->tq_recv, - &tmp_neigh_node->tq_index, 0); + batadv_ring_buffer_set(tmp_neigh_node->tq_recv, + &tmp_neigh_node->tq_index, 0); tmp_neigh_node->tq_avg = - ring_buffer_avg(tmp_neigh_node->tq_recv); + batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); spin_unlock_bh(&tmp_neigh_node->lq_update_lock); } @@ -673,10 +673,10 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, neigh_node->last_seen = jiffies; spin_lock_bh(&neigh_node->lq_update_lock); - ring_buffer_set(neigh_node->tq_recv, - &neigh_node->tq_index, - batman_ogm_packet->tq); - neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); + batadv_ring_buffer_set(neigh_node->tq_recv, + &neigh_node->tq_index, + batman_ogm_packet->tq); + neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); spin_unlock_bh(&neigh_node->lq_update_lock); if (!is_duplicate) { diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c index fd63951d118d..db8f5ef83d3e 100644 --- a/net/batman-adv/ring_buffer.c +++ b/net/batman-adv/ring_buffer.c @@ -22,13 +22,14 @@ #include "main.h" #include "ring_buffer.h" -void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value) +void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, + uint8_t value) { lq_recv[*lq_index] = value; *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE; } -uint8_t ring_buffer_avg(const uint8_t lq_recv[]) +uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) { const uint8_t *ptr; uint16_t count = 0, i = 0, sum = 0; diff --git a/net/batman-adv/ring_buffer.h b/net/batman-adv/ring_buffer.h index 8b58bd82767d..fbaf9d29d1d7 100644 --- a/net/batman-adv/ring_buffer.h +++ b/net/batman-adv/ring_buffer.h @@ -22,7 +22,8 @@ #ifndef _NET_BATMAN_ADV_RING_BUFFER_H_ #define _NET_BATMAN_ADV_RING_BUFFER_H_ -void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value); -uint8_t ring_buffer_avg(const uint8_t lq_recv[]); +void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, + uint8_t value); +uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]); #endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */ -- GitLab From 30d3c5113f9a3f162d65d01b771b122afac0ce79 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:36 +0200 Subject: [PATCH 2281/6849] batman-adv: Prefix routing non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 15 +++++---- net/batman-adv/gateway_client.c | 5 +-- net/batman-adv/main.c | 14 ++++---- net/batman-adv/originator.c | 5 +-- net/batman-adv/routing.c | 60 +++++++++++++++++---------------- net/batman-adv/routing.h | 52 ++++++++++++++-------------- net/batman-adv/unicast.c | 3 +- 7 files changed, 80 insertions(+), 74 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index cd57cf2022c5..f48467ff6713 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -599,7 +599,7 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) else batman_ogm_packet->gw_flags = NO_FLAGS; - slide_own_bcast_window(hard_iface); + batadv_slide_own_bcast_window(hard_iface); bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, hard_iface->packet_len, hard_iface, 1, bat_iv_ogm_emit_send_time(bat_priv)); @@ -684,7 +684,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, neigh_node->last_ttl = batman_ogm_packet->header.ttl; } - bonding_candidate_add(orig_node, neigh_node); + batadv_bonding_candidate_add(orig_node, neigh_node); /* if this neighbor already is our next hop there is nothing * to change */ @@ -715,7 +715,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, goto update_tt; } - update_route(bat_priv, orig_node, neigh_node); + batadv_update_route(bat_priv, orig_node, neigh_node); update_tt: /* I have to check for transtable changes only if the OGM has been @@ -884,8 +884,8 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, /* signalize caller that the packet is to be dropped. */ if (!hlist_empty(&orig_node->neigh_list) && - window_protected(bat_priv, seq_diff, - &orig_node->batman_seqno_reset)) + batadv_window_protected(bat_priv, seq_diff, + &orig_node->batman_seqno_reset)) goto out; rcu_read_lock(); @@ -1133,7 +1133,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, is_bidirectional = bat_iv_ogm_calc_tq(orig_node, orig_neigh_node, batman_ogm_packet, if_incoming); - bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet); + batadv_bonding_save_primary(orig_node, orig_neigh_node, + batman_ogm_packet); /* update ranking if it is not a duplicate or has the same * seqno and similar ttl as the non-duplicate */ @@ -1201,7 +1202,7 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, unsigned char *tt_buff, *packet_buff; bool ret; - ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); + ret = batadv_check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); if (!ret) return NET_RX_DROP; diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index e92055da5074..2bf330d16485 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -682,7 +682,8 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, /* If the dhcp packet has been sent to a different gw, * we have to evaluate whether the old gw is still * reliable enough */ - neigh_curr = find_router(bat_priv, curr_gw->orig_node, NULL); + neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node, + NULL); if (!neigh_curr) goto out; @@ -693,7 +694,7 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, goto out; } - neigh_old = find_router(bat_priv, orig_dst_node, NULL); + neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL); if (!neigh_old) goto out; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index eba5d2899b25..92f39b50de6c 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -272,19 +272,19 @@ static void recv_handler_init(void) recv_packet_handler[i] = recv_unhandled_packet; /* batman icmp packet */ - recv_packet_handler[BAT_ICMP] = recv_icmp_packet; + recv_packet_handler[BAT_ICMP] = batadv_recv_icmp_packet; /* unicast packet */ - recv_packet_handler[BAT_UNICAST] = recv_unicast_packet; + recv_packet_handler[BAT_UNICAST] = batadv_recv_unicast_packet; /* fragmented unicast packet */ - recv_packet_handler[BAT_UNICAST_FRAG] = recv_ucast_frag_packet; + recv_packet_handler[BAT_UNICAST_FRAG] = batadv_recv_ucast_frag_packet; /* broadcast packet */ - recv_packet_handler[BAT_BCAST] = recv_bcast_packet; + recv_packet_handler[BAT_BCAST] = batadv_recv_bcast_packet; /* vis packet */ - recv_packet_handler[BAT_VIS] = recv_vis_packet; + recv_packet_handler[BAT_VIS] = batadv_recv_vis_packet; /* Translation table query (request or response) */ - recv_packet_handler[BAT_TT_QUERY] = recv_tt_query; + recv_packet_handler[BAT_TT_QUERY] = batadv_recv_tt_query; /* Roaming advertisement */ - recv_packet_handler[BAT_ROAM_ADV] = recv_roam_adv; + recv_packet_handler[BAT_ROAM_ADV] = batadv_recv_roam_adv; } int recv_handler_register(uint8_t packet_type, diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 93585132049f..12c2e1ed2560 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -307,7 +307,7 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, neigh_purged = true; hlist_del_rcu(&neigh_node->list); - bonding_candidate_del(orig_node, neigh_node); + batadv_bonding_candidate_del(orig_node, neigh_node); batadv_neigh_node_free_ref(neigh_node); } else { if ((!*best_neigh_node) || @@ -334,7 +334,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv, } else { if (purge_orig_neighbors(bat_priv, orig_node, &best_neigh_node)) - update_route(bat_priv, orig_node, best_neigh_node); + batadv_update_route(bat_priv, orig_node, + best_neigh_node); } return false; diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 77fe46065db6..631b40b65451 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -34,7 +34,7 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); -void slide_own_bcast_window(struct hard_iface *hard_iface) +void batadv_slide_own_bcast_window(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; @@ -108,8 +108,8 @@ static void _update_route(struct bat_priv *bat_priv, batadv_neigh_node_free_ref(curr_router); } -void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, - struct neigh_node *neigh_node) +void batadv_update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, + struct neigh_node *neigh_node) { struct neigh_node *router = NULL; @@ -127,8 +127,8 @@ out: } /* caller must hold the neigh_list_lock */ -void bonding_candidate_del(struct orig_node *orig_node, - struct neigh_node *neigh_node) +void batadv_bonding_candidate_del(struct orig_node *orig_node, + struct neigh_node *neigh_node) { /* this neighbor is not part of our candidate list */ if (list_empty(&neigh_node->bonding_list)) @@ -143,8 +143,8 @@ out: return; } -void bonding_candidate_add(struct orig_node *orig_node, - struct neigh_node *neigh_node) +void batadv_bonding_candidate_add(struct orig_node *orig_node, + struct neigh_node *neigh_node) { struct hlist_node *node; struct neigh_node *tmp_neigh_node, *router = NULL; @@ -204,7 +204,7 @@ void bonding_candidate_add(struct orig_node *orig_node, goto out; candidate_del: - bonding_candidate_del(orig_node, neigh_node); + batadv_bonding_candidate_del(orig_node, neigh_node); out: spin_unlock_bh(&orig_node->neigh_list_lock); @@ -214,9 +214,10 @@ out: } /* copy primary address for bonding */ -void bonding_save_primary(const struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - const struct batman_ogm_packet *batman_ogm_packet) +void +batadv_bonding_save_primary(const struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + const struct batman_ogm_packet *batman_ogm_packet) { if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) return; @@ -229,8 +230,8 @@ void bonding_save_primary(const struct orig_node *orig_node, * 0 if the packet is to be accepted * 1 if the packet is to be ignored. */ -int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, - unsigned long *last_reset) +int batadv_window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, + unsigned long *last_reset) { if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { @@ -245,9 +246,9 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, return 0; } -bool check_management_packet(struct sk_buff *skb, - struct hard_iface *hard_iface, - int header_len) +bool batadv_check_management_packet(struct sk_buff *skb, + struct hard_iface *hard_iface, + int header_len) { struct ethhdr *ethhdr; @@ -387,7 +388,7 @@ out: } -int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct icmp_packet_rr *icmp_packet; @@ -569,7 +570,7 @@ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, return router; } -int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct tt_query_packet *tt_query; @@ -644,7 +645,7 @@ out: return NET_RX_DROP; } -int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct roam_adv_packet *roam_adv_packet; @@ -704,9 +705,9 @@ out: /* find a suitable router for this originator, and use * bonding if possible. increases the found neighbors * refcount.*/ -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, - const struct hard_iface *recv_if) +struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const struct hard_iface *recv_if) { struct orig_node *primary_orig_node; struct orig_node *router_orig; @@ -834,7 +835,7 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) goto out; /* find_router() increases neigh_nodes refcount if found. */ - neigh_node = find_router(bat_priv, orig_node, recv_if); + neigh_node = batadv_find_router(bat_priv, orig_node, recv_if); if (!neigh_node) goto out; @@ -965,7 +966,7 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, return 1; } -int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct unicast_packet *unicast_packet; @@ -988,7 +989,8 @@ int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) return route_unicast_packet(skb, recv_if); } -int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_ucast_frag_packet(struct sk_buff *skb, + struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct unicast_frag_packet *unicast_packet; @@ -1025,7 +1027,7 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if) } -int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct orig_node *orig_node = NULL; @@ -1077,8 +1079,8 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; /* check whether the packet is old and the host just restarted. */ - if (window_protected(bat_priv, seq_diff, - &orig_node->bcast_seqno_reset)) + if (batadv_window_protected(bat_priv, seq_diff, + &orig_node->bcast_seqno_reset)) goto spin_unlock; /* mark broadcast in flood history, update window position @@ -1114,7 +1116,7 @@ out: return ret; } -int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if) +int batadv_recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if) { struct vis_packet *vis_packet; struct ethhdr *ethhdr; diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index d6bbbebb6567..4652f0c147f5 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h @@ -22,30 +22,32 @@ #ifndef _NET_BATMAN_ADV_ROUTING_H_ #define _NET_BATMAN_ADV_ROUTING_H_ -void slide_own_bcast_window(struct hard_iface *hard_iface); -bool check_management_packet(struct sk_buff *skb, - struct hard_iface *hard_iface, - int header_len); -void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, - struct neigh_node *neigh_node); -int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, - const struct hard_iface *recv_if); -void bonding_candidate_del(struct orig_node *orig_node, - struct neigh_node *neigh_node); -void bonding_candidate_add(struct orig_node *orig_node, - struct neigh_node *neigh_node); -void bonding_save_primary(const struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - const struct batman_ogm_packet *batman_ogm_packet); -int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, - unsigned long *last_reset); +void batadv_slide_own_bcast_window(struct hard_iface *hard_iface); +bool batadv_check_management_packet(struct sk_buff *skb, + struct hard_iface *hard_iface, + int header_len); +void batadv_update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, + struct neigh_node *neigh_node); +int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); +int batadv_recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); +int batadv_recv_ucast_frag_packet(struct sk_buff *skb, + struct hard_iface *recv_if); +int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); +int batadv_recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); +int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); +int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); +struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const struct hard_iface *recv_if); +void batadv_bonding_candidate_del(struct orig_node *orig_node, + struct neigh_node *neigh_node); +void batadv_bonding_candidate_add(struct orig_node *orig_node, + struct neigh_node *neigh_node); +void batadv_bonding_save_primary(const struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + const struct batman_ogm_packet + *batman_ogm_packet); +int batadv_window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, + unsigned long *last_reset); #endif /* _NET_BATMAN_ADV_ROUTING_H_ */ diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 6117100c292c..894c6a416dac 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -310,8 +310,7 @@ find_router: * - if orig_node is NULL it returns NULL * - increases neigh_nodes refcount if found. */ - neigh_node = find_router(bat_priv, orig_node, NULL); - + neigh_node = batadv_find_router(bat_priv, orig_node, NULL); if (!neigh_node) goto out; -- GitLab From 9455e34cb2ded22e01abb6daa65ba1caeed8d7fe Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:37 +0200 Subject: [PATCH 2282/6849] batman-adv: Prefix send non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 9 +++++---- net/batman-adv/hard-interface.c | 4 ++-- net/batman-adv/icmp_socket.c | 2 +- net/batman-adv/main.c | 2 +- net/batman-adv/routing.c | 10 +++++----- net/batman-adv/send.c | 22 ++++++++++++---------- net/batman-adv/send.h | 17 +++++++++-------- net/batman-adv/soft-interface.c | 2 +- net/batman-adv/translation-table.c | 8 ++++---- net/batman-adv/unicast.c | 6 +++--- net/batman-adv/vis.c | 5 +++-- 11 files changed, 46 insertions(+), 41 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index f48467ff6713..1566eac02d4c 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -201,7 +201,7 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX); batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES, skb->len + ETH_HLEN); - send_skb_packet(skb, hard_iface, broadcast_addr); + batadv_send_skb_packet(skb, hard_iface, broadcast_addr); } } @@ -250,8 +250,9 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) forw_packet->if_incoming->net_dev->dev_addr); /* skb is only used once and than forw_packet is free'd */ - send_skb_packet(forw_packet->skb, forw_packet->if_incoming, - broadcast_addr); + batadv_send_skb_packet(forw_packet->skb, + forw_packet->if_incoming, + broadcast_addr); forw_packet->skb = NULL; goto out; @@ -420,7 +421,7 @@ static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff, /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, - send_outstanding_bat_ogm_packet); + batadv_send_outstanding_bat_ogm_packet); queue_delayed_work(bat_event_workqueue, &forw_packet_aggr->delayed_work, send_time - jiffies); diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 1f126cbd2c79..7392ae28114d 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -345,7 +345,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, hard_iface->net_dev->name); /* begin scheduling originator messages on that interface */ - schedule_bat_ogm(hard_iface); + batadv_schedule_bat_ogm(hard_iface); out: return 0; @@ -391,7 +391,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) /* delete all references to this hard_iface */ batadv_purge_orig_ref(bat_priv); - purge_outstanding_packets(bat_priv, hard_iface); + batadv_purge_outstanding_packets(bat_priv, hard_iface); dev_put(hard_iface->soft_iface); /* nobody uses this interface anymore */ diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 44cbee58720b..21c001074ebe 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -236,7 +236,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, memcpy(icmp_packet->rr, neigh_node->if_incoming->net_dev->dev_addr, ETH_ALEN); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); goto out; dst_unreach: diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 92f39b50de6c..b9531a11b7bf 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -145,7 +145,7 @@ void mesh_free(struct net_device *soft_iface) atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING); - purge_outstanding_packets(bat_priv, NULL); + batadv_purge_outstanding_packets(bat_priv, NULL); vis_quit(bat_priv); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 631b40b65451..d7d05b22cc0d 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -319,7 +319,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, icmp_packet->msg_type = ECHO_REPLY; icmp_packet->header.ttl = TTL; - send_skb_packet(skb, router->if_incoming, router->addr); + batadv_send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; out: @@ -374,7 +374,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, icmp_packet->msg_type = TTL_EXCEEDED; icmp_packet->header.ttl = TTL; - send_skb_packet(skb, router->if_incoming, router->addr); + batadv_send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; out: @@ -459,7 +459,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) icmp_packet->header.ttl--; /* route it */ - send_skb_packet(skb, router->if_incoming, router->addr); + batadv_send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; out: @@ -881,7 +881,7 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) skb->len + ETH_HLEN); /* route it */ - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = NET_RX_SUCCESS; out: @@ -1095,7 +1095,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) goto out; /* rebroadcast packet */ - add_bcast_packet_to_list(bat_priv, skb, 1); + batadv_add_bcast_packet_to_list(bat_priv, skb, 1); /* don't hand the broadcast up if it is from an originator * from the same backbone. diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 79f8973810c0..bceb3d72e5c3 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -33,8 +33,8 @@ static void send_outstanding_bcast_packet(struct work_struct *work); /* send out an already prepared packet to the given address via the * specified batman interface */ -int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, - const uint8_t *dst_addr) +int batadv_send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, + const uint8_t *dst_addr) { struct ethhdr *ethhdr; @@ -77,7 +77,7 @@ send_skb_err: return NET_XMIT_DROP; } -void schedule_bat_ogm(struct hard_iface *hard_iface) +void batadv_schedule_bat_ogm(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); @@ -133,8 +133,9 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, * * The skb is not consumed, so the caller should make sure that the * skb is freed. */ -int add_bcast_packet_to_list(struct bat_priv *bat_priv, - const struct sk_buff *skb, unsigned long delay) +int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, + const struct sk_buff *skb, + unsigned long delay) { struct hard_iface *primary_if = NULL; struct forw_packet *forw_packet; @@ -211,7 +212,8 @@ static void send_outstanding_bcast_packet(struct work_struct *work) /* send a copy of the saved skb */ skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); if (skb1) - send_skb_packet(skb1, hard_iface, broadcast_addr); + batadv_send_skb_packet(skb1, hard_iface, + broadcast_addr); } rcu_read_unlock(); @@ -229,7 +231,7 @@ out: atomic_inc(&bat_priv->bcast_queue_left); } -void send_outstanding_bat_ogm_packet(struct work_struct *work) +void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work) { struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); @@ -253,7 +255,7 @@ void send_outstanding_bat_ogm_packet(struct work_struct *work) * shutting down */ if (forw_packet->own) - schedule_bat_ogm(forw_packet->if_incoming); + batadv_schedule_bat_ogm(forw_packet->if_incoming); out: /* don't count own packet */ @@ -263,8 +265,8 @@ out: forw_packet_free(forw_packet); } -void purge_outstanding_packets(struct bat_priv *bat_priv, - const struct hard_iface *hard_iface) +void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, + const struct hard_iface *hard_iface) { struct forw_packet *forw_packet; struct hlist_node *tmp_node, *safe_tmp_node; diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h index 824ef06f9b01..452e8df5abb8 100644 --- a/net/batman-adv/send.h +++ b/net/batman-adv/send.h @@ -22,13 +22,14 @@ #ifndef _NET_BATMAN_ADV_SEND_H_ #define _NET_BATMAN_ADV_SEND_H_ -int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, - const uint8_t *dst_addr); -void schedule_bat_ogm(struct hard_iface *hard_iface); -int add_bcast_packet_to_list(struct bat_priv *bat_priv, - const struct sk_buff *skb, unsigned long delay); -void send_outstanding_bat_ogm_packet(struct work_struct *work); -void purge_outstanding_packets(struct bat_priv *bat_priv, - const struct hard_iface *hard_iface); +int batadv_send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, + const uint8_t *dst_addr); +void batadv_schedule_bat_ogm(struct hard_iface *hard_iface); +int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, + const struct sk_buff *skb, + unsigned long delay); +void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work); +void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, + const struct hard_iface *hard_iface); #endif /* _NET_BATMAN_ADV_SEND_H_ */ diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 5bf9a73ae799..e15d474bd0b0 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -223,7 +223,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) bcast_packet->seqno = htonl(atomic_inc_return(&bat_priv->bcast_seqno)); - add_bcast_packet_to_list(bat_priv, skb, 1); + batadv_add_bcast_packet_to_list(bat_priv, skb, 1); /* a copy is stored in the bcast list, therefore removing * the original skb. */ diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 3d2c3b142cf1..445dc25ceba1 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1406,7 +1406,7 @@ static int send_tt_request(struct bat_priv *bat_priv, batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; out: @@ -1532,7 +1532,7 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = true; goto out; @@ -1650,7 +1650,7 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = true; goto out; @@ -1957,7 +1957,7 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_TX); - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; out: diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 894c6a416dac..6bb3bb9f843f 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -268,8 +268,8 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, frag1->seqno = htons(seqno - 1); frag2->seqno = htons(seqno); - send_skb_packet(skb, hard_iface, dstaddr); - send_skb_packet(frag_skb, hard_iface, dstaddr); + batadv_send_skb_packet(skb, hard_iface, dstaddr); + batadv_send_skb_packet(frag_skb, hard_iface, dstaddr); ret = NET_RX_SUCCESS; goto out; @@ -348,7 +348,7 @@ find_router: goto out; } - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; goto out; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 1972a11aace1..c56737cba0e2 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -777,7 +777,8 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) - send_skb_packet(skb, hard_iface, dstaddr); + batadv_send_skb_packet(skb, hard_iface, + dstaddr); } rcu_read_unlock(); @@ -804,7 +805,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) - send_skb_packet(skb, router->if_incoming, router->addr); + batadv_send_skb_packet(skb, router->if_incoming, router->addr); out: if (router) -- GitLab From 04b482a21aaf22cf5b327fb6a3fba6fdc8cb3de9 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:38 +0200 Subject: [PATCH 2283/6849] batman-adv: Prefix soft-interface non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/hard-interface.c | 8 ++++---- net/batman-adv/routing.c | 9 +++++---- net/batman-adv/send.c | 2 +- net/batman-adv/soft-interface.c | 16 ++++++++-------- net/batman-adv/soft-interface.h | 13 ++++++------- net/batman-adv/unicast.c | 6 +++--- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 7392ae28114d..93acf2be7759 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -71,7 +71,7 @@ static int is_valid_iface(const struct net_device *net_dev) return 0; /* no batman over batman */ - if (softif_is_valid(net_dev)) + if (batadv_softif_is_valid(net_dev)) return 0; /* Device is being bridged */ @@ -284,7 +284,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, soft_iface = dev_get_by_name(&init_net, iface_name); if (!soft_iface) { - soft_iface = softif_create(iface_name); + soft_iface = batadv_softif_create(iface_name); if (!soft_iface) { ret = -ENOMEM; @@ -295,7 +295,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, dev_hold(soft_iface); } - if (!softif_is_valid(soft_iface)) { + if (!batadv_softif_is_valid(soft_iface)) { pr_err("Can't create batman mesh interface %s: already exists as regular interface\n", soft_iface->name); ret = -EINVAL; @@ -396,7 +396,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) /* nobody uses this interface anymore */ if (!bat_priv->num_ifaces) - softif_destroy(hard_iface->soft_iface); + batadv_softif_destroy(hard_iface->soft_iface); hard_iface->soft_iface = NULL; hardif_free_ref(hard_iface); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index d7d05b22cc0d..0e982218e630 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -982,7 +982,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* packet for me */ if (is_my_mac(unicast_packet->dest)) { - interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); + batadv_interface_rx(recv_if->soft_iface, skb, recv_if, + hdr_size); return NET_RX_SUCCESS; } @@ -1018,8 +1019,8 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, if (!new_skb) return NET_RX_SUCCESS; - interface_rx(recv_if->soft_iface, new_skb, recv_if, - sizeof(struct unicast_packet)); + batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, + sizeof(struct unicast_packet)); return NET_RX_SUCCESS; } @@ -1104,7 +1105,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) goto out; /* broadcast for me */ - interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); + batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); ret = NET_RX_SUCCESS; goto out; diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index bceb3d72e5c3..8226b1cf05eb 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -51,7 +51,7 @@ int batadv_send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, } /* push to the ethernet header. */ - if (my_skb_head_push(skb, ETH_HLEN) < 0) + if (batadv_skb_head_push(skb, ETH_HLEN) < 0) goto send_skb_err; skb_reset_mac_header(skb); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index e15d474bd0b0..cbc36f0ec242 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -61,7 +61,7 @@ static const struct ethtool_ops bat_ethtool_ops = { .get_sset_count = batadv_get_sset_count, }; -int my_skb_head_push(struct sk_buff *skb, unsigned int len) +int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) { int result; @@ -204,7 +204,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) if (!primary_if) goto dropped; - if (my_skb_head_push(skb, sizeof(*bcast_packet)) < 0) + if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) goto dropped; bcast_packet = (struct bcast_packet *)skb->data; @@ -256,9 +256,9 @@ end: return NETDEV_TX_OK; } -void interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, struct hard_iface *recv_if, - int hdr_size) +void batadv_interface_rx(struct net_device *soft_iface, + struct sk_buff *skb, struct hard_iface *recv_if, + int hdr_size) { struct bat_priv *bat_priv = netdev_priv(soft_iface); struct ethhdr *ethhdr; @@ -357,7 +357,7 @@ static void interface_setup(struct net_device *dev) memset(priv, 0, sizeof(*priv)); } -struct net_device *softif_create(const char *name) +struct net_device *batadv_softif_create(const char *name) { struct net_device *soft_iface; struct bat_priv *bat_priv; @@ -445,7 +445,7 @@ out: return NULL; } -void softif_destroy(struct net_device *soft_iface) +void batadv_softif_destroy(struct net_device *soft_iface) { batadv_debugfs_del_meshif(soft_iface); batadv_sysfs_del_meshif(soft_iface); @@ -453,7 +453,7 @@ void softif_destroy(struct net_device *soft_iface) unregister_netdevice(soft_iface); } -int softif_is_valid(const struct net_device *net_dev) +int batadv_softif_is_valid(const struct net_device *net_dev) { if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) return 1; diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 020300673884..7e2bfafbcb79 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h @@ -22,12 +22,11 @@ #ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_ #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ -int my_skb_head_push(struct sk_buff *skb, unsigned int len); -void interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, struct hard_iface *recv_if, - int hdr_size); -struct net_device *softif_create(const char *name); -void softif_destroy(struct net_device *soft_iface); -int softif_is_valid(const struct net_device *net_dev); +int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); +void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, + struct hard_iface *recv_if, int hdr_size); +struct net_device *batadv_softif_create(const char *name); +void batadv_softif_destroy(struct net_device *soft_iface); +int batadv_softif_is_valid(const struct net_device *net_dev); #endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 6bb3bb9f843f..52179c8ae9bd 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -242,8 +242,8 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, memcpy(&tmp_uc, unicast_packet, uc_hdr_len); skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len); - if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || - my_skb_head_push(frag_skb, ucf_hdr_len) < 0) + if (batadv_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || + batadv_skb_head_push(frag_skb, ucf_hdr_len) < 0) goto drop_frag; frag1 = (struct unicast_frag_packet *)skb->data; @@ -314,7 +314,7 @@ find_router: if (!neigh_node) goto out; - if (my_skb_head_push(skb, sizeof(*unicast_packet)) < 0) + if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0) goto out; unicast_packet = (struct unicast_packet *)skb->data; -- GitLab From 08c36d3e8ad1f73d3b0322842363b23f6d203630 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:39 +0200 Subject: [PATCH 2284/6849] batman-adv: Prefix translation-table non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 4 +- net/batman-adv/bat_iv_ogm.c | 23 ++++--- net/batman-adv/bridge_loop_avoidance.c | 4 +- net/batman-adv/gateway_client.c | 4 +- net/batman-adv/main.c | 6 +- net/batman-adv/originator.c | 4 +- net/batman-adv/routing.c | 23 ++++--- net/batman-adv/soft-interface.c | 10 +-- net/batman-adv/translation-table.c | 84 ++++++++++++++------------ net/batman-adv/translation-table.h | 63 ++++++++++--------- net/batman-adv/unicast.c | 7 +-- 11 files changed, 125 insertions(+), 107 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 51b67f4a064b..93cc0d14c70a 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -242,7 +242,7 @@ static int gateways_open(struct inode *inode, struct file *file) static int transtable_global_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, tt_global_seq_print_text, net_dev); + return single_open(file, batadv_tt_global_seq_print_text, net_dev); } #ifdef CONFIG_BATMAN_ADV_BLA @@ -257,7 +257,7 @@ static int bla_claim_table_open(struct inode *inode, struct file *file) static int transtable_local_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, tt_local_seq_print_text, net_dev); + return single_open(file, batadv_tt_local_seq_print_text, net_dev); } static int vis_data_open(struct inode *inode, struct file *file) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 1566eac02d4c..62b52b663afb 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -138,7 +138,10 @@ static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len, int tt_num_changes) { - int next_buff_pos = buff_pos + BATMAN_OGM_HLEN + tt_len(tt_num_changes); + int next_buff_pos = 0; + + next_buff_pos += buff_pos + BATMAN_OGM_HLEN; + next_buff_pos += batadv_tt_len(tt_num_changes); return (next_buff_pos <= packet_len) && (next_buff_pos <= MAX_AGGREGATION_BYTES); @@ -188,8 +191,8 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, batman_ogm_packet->ttvn, hard_iface->net_dev->name, hard_iface->net_dev->dev_addr); - buff_pos += BATMAN_OGM_HLEN + - tt_len(batman_ogm_packet->tt_num_changes); + buff_pos += BATMAN_OGM_HLEN; + buff_pos += batadv_tt_len(batman_ogm_packet->tt_num_changes); packet_num++; batman_ogm_packet = (struct batman_ogm_packet *) (forw_packet->skb->data + buff_pos); @@ -556,7 +559,7 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, batman_ogm_packet->flags &= ~DIRECTLINK; bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, - BATMAN_OGM_HLEN + tt_len(tt_num_changes), + BATMAN_OGM_HLEN + batadv_tt_len(tt_num_changes), if_incoming, 0, bat_iv_ogm_fwd_send_time()); } @@ -724,10 +727,10 @@ update_tt: if (((batman_ogm_packet->orig != ethhdr->h_source) && (batman_ogm_packet->header.ttl > 2)) || (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) - tt_update_orig(bat_priv, orig_node, tt_buff, - batman_ogm_packet->tt_num_changes, - batman_ogm_packet->ttvn, - ntohs(batman_ogm_packet->tt_crc)); + batadv_tt_update_orig(bat_priv, orig_node, tt_buff, + batman_ogm_packet->tt_num_changes, + batman_ogm_packet->ttvn, + ntohs(batman_ogm_packet->tt_crc)); if (orig_node->gw_flags != batman_ogm_packet->gw_flags) batadv_gw_node_update(bat_priv, orig_node, @@ -1229,8 +1232,8 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, bat_iv_ogm_process(ethhdr, batman_ogm_packet, tt_buff, if_incoming); - buff_pos += BATMAN_OGM_HLEN + - tt_len(batman_ogm_packet->tt_num_changes); + buff_pos += BATMAN_OGM_HLEN; + buff_pos += batadv_tt_len(batman_ogm_packet->tt_num_changes); batman_ogm_packet = (struct batman_ogm_packet *) (packet_buff + buff_pos); diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index c4b28af69297..bd356a12882a 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -397,8 +397,8 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, /* this is a gateway now, remove any tt entries */ orig_node = orig_hash_find(bat_priv, orig); if (orig_node) { - tt_global_del_orig(bat_priv, orig_node, - "became a backbone gateway"); + batadv_tt_global_del_orig(bat_priv, orig_node, + "became a backbone gateway"); batadv_orig_node_free_ref(orig_node); } return entry; diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 2bf330d16485..e396029e578b 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -652,8 +652,8 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, if (!ret) goto out; - orig_dst_node = transtable_search(bat_priv, ethhdr->h_source, - ethhdr->h_dest); + orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, + ethhdr->h_dest); if (!orig_dst_node) goto out; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index b9531a11b7bf..8d2011b8ed35 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -115,11 +115,11 @@ int mesh_init(struct net_device *soft_iface) if (ret < 0) goto err; - ret = tt_init(bat_priv); + ret = batadv_tt_init(bat_priv); if (ret < 0) goto err; - tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); + batadv_tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); ret = vis_init(bat_priv); if (ret < 0) @@ -152,7 +152,7 @@ void mesh_free(struct net_device *soft_iface) batadv_gw_node_purge(bat_priv); batadv_originator_free(bat_priv); - tt_free(bat_priv); + batadv_tt_free(bat_priv); batadv_bla_free(bat_priv); diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 12c2e1ed2560..030666c12daf 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -139,8 +139,8 @@ static void orig_node_free_rcu(struct rcu_head *rcu) spin_unlock_bh(&orig_node->neigh_list_lock); frag_list_free(&orig_node->frag_list); - tt_global_del_orig(orig_node->bat_priv, orig_node, - "originator timed out"); + batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, + "originator timed out"); kfree(orig_node->tt_buff); kfree(orig_node->bcast_own); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 0e982218e630..8fb5ae3dee87 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -75,8 +75,8 @@ static void _update_route(struct bat_priv *bat_priv, if ((curr_router) && (!neigh_node)) { bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", orig_node->orig); - tt_global_del_orig(bat_priv, orig_node, - "Deleted route towards originator"); + batadv_tt_global_del_orig(bat_priv, orig_node, + "Deleted route towards originator"); /* route added */ } else if ((!curr_router) && (neigh_node)) { @@ -603,7 +603,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) /* If we cannot provide an answer the tt_request is * forwarded */ - if (!send_tt_response(bat_priv, tt_query)) { + if (!batadv_send_tt_response(bat_priv, tt_query)) { bat_dbg(DBG_TT, bat_priv, "Routing TT_REQUEST to %pM [%c]\n", tt_query->dst, @@ -622,14 +622,14 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) /* skb_linearize() possibly changed skb->data */ tt_query = (struct tt_query_packet *)skb->data; - tt_size = tt_len(ntohs(tt_query->tt_data)); + tt_size = batadv_tt_len(ntohs(tt_query->tt_data)); /* Ensure we have all the claimed data */ if (unlikely(skb_headlen(skb) < sizeof(struct tt_query_packet) + tt_size)) goto out; - handle_tt_response(bat_priv, tt_query); + batadv_handle_tt_response(bat_priv, tt_query); } else { bat_dbg(DBG_TT, bat_priv, "Routing TT_RESPONSE to %pM [%c]\n", @@ -688,8 +688,9 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) "Received ROAMING_ADV from %pM (client %pM)\n", roam_adv_packet->src, roam_adv_packet->client); - tt_global_add(bat_priv, orig_node, roam_adv_packet->client, - atomic_read(&orig_node->last_ttvn) + 1, true, false); + batadv_tt_global_add(bat_priv, orig_node, roam_adv_packet->client, + atomic_read(&orig_node->last_ttvn) + 1, true, + false); /* Roaming phase starts: I have new information but the ttvn has not * been incremented yet. This flag will make me check all the incoming @@ -934,13 +935,15 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, /* we don't have an updated route for this client, so we should * not try to reroute the packet!! */ - if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) + if (batadv_tt_global_client_is_roaming(bat_priv, + ethhdr->h_dest)) return 1; - orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest); + orig_node = batadv_transtable_search(bat_priv, NULL, + ethhdr->h_dest); if (!orig_node) { - if (!is_my_client(bat_priv, ethhdr->h_dest)) + if (!batadv_is_my_client(bat_priv, ethhdr->h_dest)) return 0; primary_if = primary_if_get_selected(bat_priv); if (!primary_if) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index cbc36f0ec242..a4b5e64bf0c7 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -109,9 +109,9 @@ static int interface_set_mac_addr(struct net_device *dev, void *p) /* only modify transtable if it has been initialized before */ if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { - tt_local_remove(bat_priv, dev->dev_addr, - "mac address changed", false); - tt_local_add(dev, addr->sa_data, NULL_IFINDEX); + batadv_tt_local_remove(bat_priv, dev->dev_addr, + "mac address changed", false); + batadv_tt_local_add(dev, addr->sa_data, NULL_IFINDEX); } memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); @@ -166,7 +166,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) goto dropped; /* Register the client MAC in the transtable */ - tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); + batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); /* don't accept stp packets. STP does not help in meshes. * better use the bridge loop avoidance ... @@ -303,7 +303,7 @@ void batadv_interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; - if (is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) + if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; /* Let the bridge loop avoidance check the packet. If will diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 445dc25ceba1..ecef827ae28f 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -173,7 +173,7 @@ static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr, atomic_set(&bat_priv->tt_ogm_append_cnt, 0); } -int tt_len(int changes_num) +int batadv_tt_len(int changes_num) { return changes_num * sizeof(struct tt_change); } @@ -191,8 +191,8 @@ static int tt_local_init(struct bat_priv *bat_priv) return 0; } -void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, - int ifindex) +void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, + int ifindex) { struct bat_priv *bat_priv = netdev_priv(soft_iface); struct tt_local_entry *tt_local_entry = NULL; @@ -302,7 +302,7 @@ static void tt_prepare_packet_buff(struct bat_priv *bat_priv, primary_if = primary_if_get_selected(bat_priv); req_len = min_packet_len; - req_len += tt_len(atomic_read(&bat_priv->tt_local_changes)); + req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes)); /* if we have too many changes for one packet don't send any * and wait for the tt table request which will be fragmented @@ -332,7 +332,7 @@ static int tt_changes_fill_buff(struct bat_priv *bat_priv, tt_buff = *packet_buff + min_packet_len; if (new_len > 0) - tot_changes = new_len / tt_len(1); + tot_changes = new_len / batadv_tt_len(1); spin_lock_bh(&bat_priv->tt_changes_list_lock); atomic_set(&bat_priv->tt_local_changes, 0); @@ -340,7 +340,7 @@ static int tt_changes_fill_buff(struct bat_priv *bat_priv, list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, list) { if (count < tot_changes) { - memcpy(tt_buff + tt_len(count), + memcpy(tt_buff + batadv_tt_len(count), &entry->change, sizeof(struct tt_change)); count++; } @@ -370,7 +370,7 @@ static int tt_changes_fill_buff(struct bat_priv *bat_priv, return count; } -int tt_local_seq_print_text(struct seq_file *seq, void *offset) +int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); @@ -445,8 +445,8 @@ static void tt_local_set_pending(struct bat_priv *bat_priv, tt_local_entry->common.addr, message); } -void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr, - const char *message, bool roaming) +void batadv_tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr, + const char *message, bool roaming) { struct tt_local_entry *tt_local_entry = NULL; @@ -611,9 +611,9 @@ static void tt_global_add_orig_entry(struct tt_global_entry *tt_global_entry, } /* caller must hold orig_node refcount */ -int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *tt_addr, uint8_t ttvn, bool roaming, - bool wifi) +int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, + const unsigned char *tt_addr, uint8_t ttvn, + bool roaming, bool wifi) { struct tt_global_entry *tt_global_entry = NULL; int ret = 0; @@ -677,8 +677,8 @@ int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, out_remove: /* remove address from local hash if present */ - tt_local_remove(bat_priv, tt_global_entry->common.addr, - "global tt received", roaming); + batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr, + "global tt received", roaming); ret = 1; out: if (tt_global_entry) @@ -714,7 +714,7 @@ static void tt_global_print_entry(struct tt_global_entry *tt_global_entry, } } -int tt_global_seq_print_text(struct seq_file *seq, void *offset) +int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); @@ -919,8 +919,8 @@ out: tt_local_entry_free_ref(tt_local_entry); } -void tt_global_del_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, const char *message) +void batadv_tt_global_del_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, const char *message) { struct tt_global_entry *tt_global_entry; struct tt_common_entry *tt_common_entry; @@ -1048,8 +1048,9 @@ static bool _is_ap_isolated(struct tt_local_entry *tt_local_entry, return ret; } -struct orig_node *transtable_search(struct bat_priv *bat_priv, - const uint8_t *src, const uint8_t *addr) +struct orig_node *batadv_transtable_search(struct bat_priv *bat_priv, + const uint8_t *src, + const uint8_t *addr) { struct tt_local_entry *tt_local_entry = NULL; struct tt_global_entry *tt_global_entry = NULL; @@ -1204,7 +1205,7 @@ static void tt_save_orig_buffer(struct bat_priv *bat_priv, const unsigned char *tt_buff, uint8_t tt_num_changes) { - uint16_t tt_buff_len = tt_len(tt_num_changes); + uint16_t tt_buff_len = batadv_tt_len(tt_num_changes); /* Replace the old buffer only if I received something in the * last OGM (the OGM could carry no changes) */ @@ -1669,8 +1670,8 @@ out: return true; } -bool send_tt_response(struct bat_priv *bat_priv, - struct tt_query_packet *tt_request) +bool batadv_send_tt_response(struct bat_priv *bat_priv, + struct tt_query_packet *tt_request) { if (is_my_mac(tt_request->dst)) { /* don't answer backbone gws! */ @@ -1689,18 +1690,19 @@ static void _tt_update_changes(struct bat_priv *bat_priv, uint16_t tt_num_changes, uint8_t ttvn) { int i; + int is_wifi; for (i = 0; i < tt_num_changes; i++) { - if ((tt_change + i)->flags & TT_CLIENT_DEL) + if ((tt_change + i)->flags & TT_CLIENT_DEL) { tt_global_del(bat_priv, orig_node, (tt_change + i)->addr, "tt removed by changes", (tt_change + i)->flags & TT_CLIENT_ROAM); - else - if (!tt_global_add(bat_priv, orig_node, - (tt_change + i)->addr, ttvn, false, - (tt_change + i)->flags & - TT_CLIENT_WIFI)) + } else { + is_wifi = (tt_change + i)->flags & TT_CLIENT_WIFI; + if (!batadv_tt_global_add(bat_priv, orig_node, + (tt_change + i)->addr, ttvn, + false, is_wifi)) /* In case of problem while storing a * global_entry, we stop the updating * procedure without committing the @@ -1708,6 +1710,7 @@ static void _tt_update_changes(struct bat_priv *bat_priv, * corrupted data on tt_request */ return; + } } orig_node->tt_initialised = true; } @@ -1722,7 +1725,7 @@ static void tt_fill_gtable(struct bat_priv *bat_priv, goto out; /* Purge the old table first.. */ - tt_global_del_orig(bat_priv, orig_node, "Received full table"); + batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table"); _tt_update_changes(bat_priv, orig_node, (struct tt_change *)(tt_response + 1), @@ -1754,7 +1757,7 @@ static void tt_update_changes(struct bat_priv *bat_priv, atomic_set(&orig_node->last_ttvn, ttvn); } -bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr) +bool batadv_is_my_client(struct bat_priv *bat_priv, const uint8_t *addr) { struct tt_local_entry *tt_local_entry = NULL; bool ret = false; @@ -1773,8 +1776,8 @@ out: return ret; } -void handle_tt_response(struct bat_priv *bat_priv, - struct tt_query_packet *tt_response) +void batadv_handle_tt_response(struct bat_priv *bat_priv, + struct tt_query_packet *tt_response) { struct tt_req_node *node, *safe; struct orig_node *orig_node = NULL; @@ -1821,7 +1824,7 @@ out: batadv_orig_node_free_ref(orig_node); } -int tt_init(struct bat_priv *bat_priv) +int batadv_tt_init(struct bat_priv *bat_priv) { int ret; @@ -1983,7 +1986,7 @@ static void tt_purge(struct work_struct *work) tt_start_timer(bat_priv); } -void tt_free(struct bat_priv *bat_priv) +void batadv_tt_free(struct bat_priv *bat_priv) { cancel_delayed_work_sync(&bat_priv->tt_work); @@ -2125,7 +2128,8 @@ int batadv_tt_append_diff(struct bat_priv *bat_priv, return tt_num_changes; } -bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) +bool batadv_is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, + uint8_t *dst) { struct tt_local_entry *tt_local_entry = NULL; struct tt_global_entry *tt_global_entry = NULL; @@ -2155,9 +2159,10 @@ out: return ret; } -void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *tt_buff, uint8_t tt_num_changes, - uint8_t ttvn, uint16_t tt_crc) +void batadv_tt_update_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const unsigned char *tt_buff, uint8_t tt_num_changes, + uint8_t ttvn, uint16_t tt_crc) { uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); bool full_table = true; @@ -2222,7 +2227,8 @@ request_table: * originator to another one. This entry is kept is still kept for consistency * purposes */ -bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr) +bool batadv_tt_global_client_is_roaming(struct bat_priv *bat_priv, + uint8_t *addr) { struct tt_global_entry *tt_global_entry; bool ret = false; diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index d6ea30f9b026..fe1281a71685 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -22,37 +22,44 @@ #ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ #define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ -int tt_len(int changes_num); -int tt_init(struct bat_priv *bat_priv); -void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, - int ifindex); -void tt_local_remove(struct bat_priv *bat_priv, - const uint8_t *addr, const char *message, bool roaming); -int tt_local_seq_print_text(struct seq_file *seq, void *offset); -void tt_global_add_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *tt_buff, int tt_buff_len); -int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *addr, uint8_t ttvn, bool roaming, - bool wifi); -int tt_global_seq_print_text(struct seq_file *seq, void *offset); -void tt_global_del_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, const char *message); -struct orig_node *transtable_search(struct bat_priv *bat_priv, - const uint8_t *src, const uint8_t *addr); -void tt_free(struct bat_priv *bat_priv); -bool send_tt_response(struct bat_priv *bat_priv, - struct tt_query_packet *tt_request); -bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); -void handle_tt_response(struct bat_priv *bat_priv, - struct tt_query_packet *tt_response); -bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); -void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *tt_buff, uint8_t tt_num_changes, - uint8_t ttvn, uint16_t tt_crc); +int batadv_tt_len(int changes_num); +int batadv_tt_init(struct bat_priv *bat_priv); +void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, + int ifindex); +void batadv_tt_local_remove(struct bat_priv *bat_priv, + const uint8_t *addr, const char *message, + bool roaming); +int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); +void batadv_tt_global_add_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const unsigned char *tt_buff, int tt_buff_len); +int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, + const unsigned char *addr, uint8_t ttvn, bool roaming, + bool wifi); +int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); +void batadv_tt_global_del_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const char *message); +struct orig_node *batadv_transtable_search(struct bat_priv *bat_priv, + const uint8_t *src, + const uint8_t *addr); +void batadv_tt_free(struct bat_priv *bat_priv); +bool batadv_send_tt_response(struct bat_priv *bat_priv, + struct tt_query_packet *tt_request); +bool batadv_is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); +void batadv_handle_tt_response(struct bat_priv *bat_priv, + struct tt_query_packet *tt_response); +bool batadv_is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, + uint8_t *dst); +void batadv_tt_update_orig(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const unsigned char *tt_buff, uint8_t tt_num_changes, + uint8_t ttvn, uint16_t tt_crc); int batadv_tt_append_diff(struct bat_priv *bat_priv, unsigned char **packet_buff, int *packet_buff_len, int packet_min_len); -bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr); +bool batadv_tt_global_client_is_roaming(struct bat_priv *bat_priv, + uint8_t *addr); #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 52179c8ae9bd..5e699db700b3 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -301,9 +301,8 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* check for tt host - increases orig_node refcount. * returns NULL in case of AP isolation */ - orig_node = transtable_search(bat_priv, ethhdr->h_source, - ethhdr->h_dest); - + orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source, + ethhdr->h_dest); find_router: /** * find_router(): @@ -335,7 +334,7 @@ find_router: * try to reroute it because the ttvn contained in the header is less * than the current one */ - if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) + if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) unicast_packet->ttvn = unicast_packet->ttvn - 1; if (atomic_read(&bat_priv->fragmentation) && -- GitLab From 88ed1e7772bbedfd0bb013c209f61619eca0a781 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:40 +0200 Subject: [PATCH 2285/6849] batman-adv: Prefix unicast non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/originator.c | 4 ++-- net/batman-adv/routing.c | 9 +++++---- net/batman-adv/soft-interface.c | 2 +- net/batman-adv/unicast.c | 19 ++++++++++--------- net/batman-adv/unicast.h | 13 +++++++------ 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 030666c12daf..9d77edeff589 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -138,7 +138,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu) spin_unlock_bh(&orig_node->neigh_list_lock); - frag_list_free(&orig_node->frag_list); + batadv_frag_list_free(&orig_node->frag_list); batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, "originator timed out"); @@ -372,7 +372,7 @@ static void _purge_orig(struct bat_priv *bat_priv) if (has_timed_out(orig_node->last_frag_packet, FRAG_TIMEOUT)) - frag_list_free(&orig_node->frag_list); + batadv_frag_list_free(&orig_node->frag_list); } spin_unlock_bh(list_lock); } diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 8fb5ae3dee87..4103f68ae9db 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -850,15 +850,16 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) if (unicast_packet->header.packet_type == BAT_UNICAST && atomic_read(&bat_priv->fragmentation) && skb->len > neigh_node->if_incoming->net_dev->mtu) { - ret = frag_send_skb(skb, bat_priv, - neigh_node->if_incoming, neigh_node->addr); + ret = batadv_frag_send_skb(skb, bat_priv, + neigh_node->if_incoming, + neigh_node->addr); goto out; } if (unicast_packet->header.packet_type == BAT_UNICAST_FRAG && frag_can_reassemble(skb, neigh_node->if_incoming->net_dev->mtu)) { - ret = frag_reassemble_skb(skb, bat_priv, &new_skb); + ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); if (ret == NET_RX_DROP) goto out; @@ -1013,7 +1014,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, /* packet for me */ if (is_my_mac(unicast_packet->dest)) { - ret = frag_reassemble_skb(skb, bat_priv, &new_skb); + ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); if (ret == NET_RX_DROP) return NET_RX_DROP; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index a4b5e64bf0c7..9fd1925775c7 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -237,7 +237,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) goto dropped; } - ret = unicast_send_skb(skb, bat_priv); + ret = batadv_unicast_send_skb(skb, bat_priv); if (ret != 0) goto dropped_freed; } diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 5e699db700b3..e9d3bdd4e3d6 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -101,7 +101,7 @@ static int frag_create_buffer(struct list_head *head) for (i = 0; i < FRAG_BUFFER_SIZE; i++) { tfp = kmalloc(sizeof(*tfp), GFP_ATOMIC); if (!tfp) { - frag_list_free(head); + batadv_frag_list_free(head); return -ENOMEM; } tfp->skb = NULL; @@ -151,7 +151,7 @@ mov_tail: return NULL; } -void frag_list_free(struct list_head *head) +void batadv_frag_list_free(struct list_head *head) { struct frag_packet_list_entry *pf, *tmp_pf; @@ -172,8 +172,8 @@ void frag_list_free(struct list_head *head) * or the skb could be reassembled (skb_new will point to the new packet and * skb was freed) */ -int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct sk_buff **new_skb) +int batadv_frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct sk_buff **new_skb) { struct orig_node *orig_node; struct frag_packet_list_entry *tmp_frag_entry; @@ -216,8 +216,8 @@ out: return ret; } -int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct hard_iface *hard_iface, const uint8_t dstaddr[]) +int batadv_frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct hard_iface *hard_iface, const uint8_t dstaddr[]) { struct unicast_packet tmp_uc, *unicast_packet; struct hard_iface *primary_if; @@ -283,7 +283,7 @@ out: return ret; } -int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) +int batadv_unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) { struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct unicast_packet *unicast_packet; @@ -342,8 +342,9 @@ find_router: neigh_node->if_incoming->net_dev->mtu) { /* send frag skb decreases ttl */ unicast_packet->header.ttl++; - ret = frag_send_skb(skb, bat_priv, - neigh_node->if_incoming, neigh_node->addr); + ret = batadv_frag_send_skb(skb, bat_priv, + neigh_node->if_incoming, + neigh_node->addr); goto out; } diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h index a9faf6b1db19..657fe7392b14 100644 --- a/net/batman-adv/unicast.h +++ b/net/batman-adv/unicast.h @@ -27,12 +27,13 @@ #define FRAG_TIMEOUT 10000 /* purge frag list entries after time in ms */ #define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ -int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct sk_buff **new_skb); -void frag_list_free(struct list_head *head); -int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); -int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct hard_iface *hard_iface, const uint8_t dstaddr[]); +int batadv_frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct sk_buff **new_skb); +void batadv_frag_list_free(struct list_head *head); +int batadv_unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); +int batadv_frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct hard_iface *hard_iface, + const uint8_t dstaddr[]); static inline int frag_can_reassemble(const struct sk_buff *skb, int mtu) { -- GitLab From d0f714f472967577067853acc8dabe0abc75ae8f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:41 +0200 Subject: [PATCH 2286/6849] batman-adv: Prefix vis non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 2 +- net/batman-adv/main.c | 4 ++-- net/batman-adv/routing.c | 8 ++++---- net/batman-adv/vis.c | 20 ++++++++++---------- net/batman-adv/vis.h | 18 +++++++++--------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 93cc0d14c70a..ad377aba0661 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -263,7 +263,7 @@ static int transtable_local_open(struct inode *inode, struct file *file) static int vis_data_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, vis_seq_print_text, net_dev); + return single_open(file, batadv_vis_seq_print_text, net_dev); } struct bat_debuginfo { diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 8d2011b8ed35..ffea3609ea41 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -121,7 +121,7 @@ int mesh_init(struct net_device *soft_iface) batadv_tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); - ret = vis_init(bat_priv); + ret = batadv_vis_init(bat_priv); if (ret < 0) goto err; @@ -147,7 +147,7 @@ void mesh_free(struct net_device *soft_iface) batadv_purge_outstanding_packets(bat_priv, NULL); - vis_quit(bat_priv); + batadv_vis_quit(bat_priv); batadv_gw_node_purge(bat_priv); batadv_originator_free(bat_priv); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 4103f68ae9db..d492634dd040 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1151,13 +1151,13 @@ int batadv_recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if) switch (vis_packet->vis_type) { case VIS_TYPE_SERVER_SYNC: - receive_server_sync_packet(bat_priv, vis_packet, - skb_headlen(skb)); + batadv_receive_server_sync_packet(bat_priv, vis_packet, + skb_headlen(skb)); break; case VIS_TYPE_CLIENT_UPDATE: - receive_client_update_packet(bat_priv, vis_packet, - skb_headlen(skb)); + batadv_receive_client_update_packet(bat_priv, vis_packet, + skb_headlen(skb)); break; default: /* ignore unknown packet */ diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index c56737cba0e2..24040c300636 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -188,7 +188,7 @@ static ssize_t vis_data_read_entry(char *buff, return 0; } -int vis_seq_print_text(struct seq_file *seq, void *offset) +int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) { struct hard_iface *primary_if; struct hlist_node *node; @@ -483,9 +483,9 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, } /* handle the server sync packet, forward if needed. */ -void receive_server_sync_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len) +void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len) { struct vis_info *info; int is_new, make_broadcast; @@ -508,9 +508,9 @@ end: } /* handle an incoming client update packet and schedule forward if needed. */ -void receive_client_update_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len) +void batadv_receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len) { struct vis_info *info; struct vis_packet *packet; @@ -880,7 +880,7 @@ static void send_vis_packets(struct work_struct *work) /* init the vis server. this may only be called when if_list is already * initialized (e.g. bat0 is initialized, interfaces have been added) */ -int vis_init(struct bat_priv *bat_priv) +int batadv_vis_init(struct bat_priv *bat_priv) { struct vis_packet *packet; int hash_added; @@ -944,7 +944,7 @@ free_info: bat_priv->my_vis_info = NULL; err: spin_unlock_bh(&bat_priv->vis_hash_lock); - vis_quit(bat_priv); + batadv_vis_quit(bat_priv); return -ENOMEM; } @@ -959,7 +959,7 @@ static void free_info_ref(struct hlist_node *node, void *arg) } /* shutdown vis-server */ -void vis_quit(struct bat_priv *bat_priv) +void batadv_vis_quit(struct bat_priv *bat_priv) { if (!bat_priv->vis_hash) return; diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h index ee2e46e5347b..932514e4b7d7 100644 --- a/net/batman-adv/vis.h +++ b/net/batman-adv/vis.h @@ -25,14 +25,14 @@ #define VIS_TIMEOUT 200000 /* timeout of vis packets * in miliseconds */ -int vis_seq_print_text(struct seq_file *seq, void *offset); -void receive_server_sync_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len); -void receive_client_update_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len); -int vis_init(struct bat_priv *bat_priv); -void vis_quit(struct bat_priv *bat_priv); +int batadv_vis_seq_print_text(struct seq_file *seq, void *offset); +void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len); +void batadv_receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len); +int batadv_vis_init(struct bat_priv *bat_priv); +void batadv_vis_quit(struct bat_priv *bat_priv); #endif /* _NET_BATMAN_ADV_VIS_H_ */ -- GitLab From 3193e8fdfa355289892661d206d1954114a7be95 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:42 +0200 Subject: [PATCH 2287/6849] batman-adv: Prefix main non-static functions with batadv_ batman-adv can be compiled as part of the kernel instead of an module. In that case the linker will see all non-static symbols of batman-adv and all other non-static symbols of the kernel. This could lead to symbol collisions. A prefix for the batman-adv symbols that defines their private namespace avoids such a problem. Reported-by: David Miller Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 6 +-- net/batman-adv/bat_iv_ogm.c | 16 ++++---- net/batman-adv/bridge_loop_avoidance.c | 2 +- net/batman-adv/hard-interface.c | 14 +++---- net/batman-adv/icmp_socket.c | 4 +- net/batman-adv/main.c | 57 +++++++++++++------------- net/batman-adv/main.h | 41 +++++++++--------- net/batman-adv/originator.c | 4 +- net/batman-adv/routing.c | 26 ++++++------ net/batman-adv/send.c | 6 +-- net/batman-adv/soft-interface.c | 6 +-- net/batman-adv/translation-table.c | 4 +- net/batman-adv/vis.c | 10 ++--- 13 files changed, 99 insertions(+), 97 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index ad377aba0661..3900624d333d 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -94,13 +94,13 @@ static int log_open(struct inode *inode, struct file *file) { nonseekable_open(inode, file); file->private_data = inode->i_private; - inc_module_count(); + batadv_inc_module_count(); return 0; } static int log_release(struct inode *inode, struct file *file) { - dec_module_count(); + batadv_dec_module_count(); return 0; } @@ -224,7 +224,7 @@ static void debug_log_cleanup(struct bat_priv *bat_priv) static int bat_algorithms_open(struct inode *inode, struct file *file) { - return single_open(file, bat_algo_seq_print_text, NULL); + return single_open(file, batadv_algo_seq_print_text, NULL); } static int originators_open(struct inode *inode, struct file *file) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 62b52b663afb..0430063d3a7d 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -204,7 +204,7 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX); batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES, skb->len + ETH_HLEN); - batadv_send_skb_packet(skb, hard_iface, broadcast_addr); + batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr); } } @@ -255,7 +255,7 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) /* skb is only used once and than forw_packet is free'd */ batadv_send_skb_packet(forw_packet->skb, forw_packet->if_incoming, - broadcast_addr); + batadv_broadcast_addr); forw_packet->skb = NULL; goto out; @@ -263,7 +263,7 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) /* broadcast on every interface */ rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->soft_iface != soft_iface) continue; @@ -425,7 +425,7 @@ static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff, /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, batadv_send_outstanding_bat_ogm_packet); - queue_delayed_work(bat_event_workqueue, + queue_delayed_work(batadv_event_workqueue, &forw_packet_aggr->delayed_work, send_time - jiffies); @@ -984,7 +984,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, batman_ogm_packet->header.version, has_directlink_flag); rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->if_status != IF_ACTIVE) continue; @@ -1259,18 +1259,18 @@ int __init batadv_iv_init(void) int ret; /* batman originator packet */ - ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); + ret = batadv_recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); if (ret < 0) goto out; - ret = bat_algo_register(&batman_iv); + ret = batadv_algo_register(&batman_iv); if (ret < 0) goto handler_unregister; goto out; handler_unregister: - recv_handler_unregister(BAT_IV_OGM); + batadv_recv_handler_unregister(BAT_IV_OGM); out: return ret; } diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index bd356a12882a..27f451a64ad0 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1070,7 +1070,7 @@ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, static void bla_start_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->bla_work, bla_periodic_work); - queue_delayed_work(bat_event_workqueue, &bat_priv->bla_work, + queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work, msecs_to_jiffies(BLA_PERIOD_LENGTH)); } diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 93acf2be7759..ab2fcfaf297e 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -46,7 +46,7 @@ struct hard_iface *batadv_hardif_get_by_netdev(const struct net_device *net_dev) struct hard_iface *hard_iface; rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->net_dev == net_dev && atomic_inc_not_zero(&hard_iface->refcount)) goto out; @@ -86,7 +86,7 @@ static struct hard_iface *hardif_get_active(const struct net_device *soft_iface) struct hard_iface *hard_iface; rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->soft_iface != soft_iface) continue; @@ -161,7 +161,7 @@ static void check_known_mac_addr(const struct net_device *net_dev) const struct hard_iface *hard_iface; rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if ((hard_iface->if_status != IF_ACTIVE) && (hard_iface->if_status != IF_TO_BE_ACTIVATED)) continue; @@ -192,7 +192,7 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface) goto out; rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if ((hard_iface->if_status != IF_ACTIVE) && (hard_iface->if_status != IF_TO_BE_ACTIVATED)) continue; @@ -315,7 +315,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); hard_iface->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); - hard_iface->batman_adv_ptype.func = batman_skb_recv; + hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; dev_add_pack(&hard_iface->batman_adv_ptype); @@ -436,7 +436,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev) atomic_set(&hard_iface->refcount, 2); check_known_mac_addr(hard_iface->net_dev); - list_add_tail_rcu(&hard_iface->list, &hardif_list); + list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); /** * This can't be called via a bat_priv callback because @@ -477,7 +477,7 @@ void batadv_hardif_remove_interfaces(void) rtnl_lock(); list_for_each_entry_safe(hard_iface, hard_iface_tmp, - &hardif_list, list) { + &batadv_hardif_list, list) { list_del_rcu(&hard_iface->list); hardif_remove_interface(hard_iface); } diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 21c001074ebe..230056139445 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -73,7 +73,7 @@ static int bat_socket_open(struct inode *inode, struct file *file) file->private_data = socket_client; - inc_module_count(); + batadv_inc_module_count(); return 0; } @@ -98,7 +98,7 @@ static int bat_socket_release(struct inode *inode, struct file *file) spin_unlock_bh(&socket_client->lock); kfree(socket_client); - dec_module_count(); + batadv_dec_module_count(); return 0; } diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index ffea3609ea41..5e1d906628f5 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -38,20 +38,20 @@ /* List manipulations on hardif_list have to be rtnl_lock()'ed, * list traversals just rcu-locked */ -struct list_head hardif_list; +struct list_head batadv_hardif_list; static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); -char bat_routing_algo[20] = "BATMAN_IV"; +char batadv_routing_algo[20] = "BATMAN_IV"; static struct hlist_head bat_algo_list; -unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +unsigned char batadv_broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -struct workqueue_struct *bat_event_workqueue; +struct workqueue_struct *batadv_event_workqueue; static void recv_handler_init(void); static int __init batman_init(void) { - INIT_LIST_HEAD(&hardif_list); + INIT_LIST_HEAD(&batadv_hardif_list); INIT_HLIST_HEAD(&bat_algo_list); recv_handler_init(); @@ -60,9 +60,9 @@ static int __init batman_init(void) /* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ - bat_event_workqueue = create_singlethread_workqueue("bat_events"); + batadv_event_workqueue = create_singlethread_workqueue("bat_events"); - if (!bat_event_workqueue) + if (!batadv_event_workqueue) return -ENOMEM; batadv_socket_init(); @@ -82,14 +82,14 @@ static void __exit batman_exit(void) unregister_netdevice_notifier(&batadv_hard_if_notifier); batadv_hardif_remove_interfaces(); - flush_workqueue(bat_event_workqueue); - destroy_workqueue(bat_event_workqueue); - bat_event_workqueue = NULL; + flush_workqueue(batadv_event_workqueue); + destroy_workqueue(batadv_event_workqueue); + batadv_event_workqueue = NULL; rcu_barrier(); } -int mesh_init(struct net_device *soft_iface) +int batadv_mesh_init(struct net_device *soft_iface) { struct bat_priv *bat_priv = netdev_priv(soft_iface); int ret; @@ -135,11 +135,11 @@ int mesh_init(struct net_device *soft_iface) return 0; err: - mesh_free(soft_iface); + batadv_mesh_free(soft_iface); return ret; } -void mesh_free(struct net_device *soft_iface) +void batadv_mesh_free(struct net_device *soft_iface) { struct bat_priv *bat_priv = netdev_priv(soft_iface); @@ -161,22 +161,22 @@ void mesh_free(struct net_device *soft_iface) atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); } -void inc_module_count(void) +void batadv_inc_module_count(void) { try_module_get(THIS_MODULE); } -void dec_module_count(void) +void batadv_dec_module_count(void) { module_put(THIS_MODULE); } -int is_my_mac(const uint8_t *addr) +int batadv_is_my_mac(const uint8_t *addr) { const struct hard_iface *hard_iface; rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->if_status != IF_ACTIVE) continue; @@ -198,8 +198,9 @@ static int recv_unhandled_packet(struct sk_buff *skb, /* incoming packets with the batman ethertype received on any active hard * interface */ -int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev) +int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, + struct net_device *orig_dev) { struct bat_priv *bat_priv; struct batman_ogm_packet *batman_ogm_packet; @@ -287,9 +288,9 @@ static void recv_handler_init(void) recv_packet_handler[BAT_ROAM_ADV] = batadv_recv_roam_adv; } -int recv_handler_register(uint8_t packet_type, - int (*recv_handler)(struct sk_buff *, - struct hard_iface *)) +int batadv_recv_handler_register(uint8_t packet_type, + int (*recv_handler)(struct sk_buff *, + struct hard_iface *)) { if (recv_packet_handler[packet_type] != &recv_unhandled_packet) return -EBUSY; @@ -298,7 +299,7 @@ int recv_handler_register(uint8_t packet_type, return 0; } -void recv_handler_unregister(uint8_t packet_type) +void batadv_recv_handler_unregister(uint8_t packet_type) { recv_packet_handler[packet_type] = recv_unhandled_packet; } @@ -319,7 +320,7 @@ static struct bat_algo_ops *bat_algo_get(char *name) return bat_algo_ops; } -int bat_algo_register(struct bat_algo_ops *bat_algo_ops) +int batadv_algo_register(struct bat_algo_ops *bat_algo_ops) { struct bat_algo_ops *bat_algo_ops_tmp; int ret; @@ -353,7 +354,7 @@ out: return ret; } -int bat_algo_select(struct bat_priv *bat_priv, char *name) +int batadv_algo_select(struct bat_priv *bat_priv, char *name) { struct bat_algo_ops *bat_algo_ops; int ret = -EINVAL; @@ -369,7 +370,7 @@ out: return ret; } -int bat_algo_seq_print_text(struct seq_file *seq, void *offset) +int batadv_algo_seq_print_text(struct seq_file *seq, void *offset) { struct bat_algo_ops *bat_algo_ops; struct hlist_node *node; @@ -407,8 +408,8 @@ static const struct kernel_param_ops param_ops_ra = { }; static struct kparam_string __param_string_ra = { - .maxlen = sizeof(bat_routing_algo), - .string = bat_routing_algo, + .maxlen = sizeof(batadv_routing_algo), + .string = batadv_routing_algo, }; module_param_cb(routing_algo, ¶m_ops_ra, &__param_string_ra, 0644); diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index ea9d433ad46d..12386421a55b 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -145,26 +145,27 @@ enum dbg_level { #include #include "types.h" -extern char bat_routing_algo[]; -extern struct list_head hardif_list; - -extern unsigned char broadcast_addr[]; -extern struct workqueue_struct *bat_event_workqueue; - -int mesh_init(struct net_device *soft_iface); -void mesh_free(struct net_device *soft_iface); -void inc_module_count(void); -void dec_module_count(void); -int is_my_mac(const uint8_t *addr); -int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev); -int recv_handler_register(uint8_t packet_type, - int (*recv_handler)(struct sk_buff *, - struct hard_iface *)); -void recv_handler_unregister(uint8_t packet_type); -int bat_algo_register(struct bat_algo_ops *bat_algo_ops); -int bat_algo_select(struct bat_priv *bat_priv, char *name); -int bat_algo_seq_print_text(struct seq_file *seq, void *offset); +extern char batadv_routing_algo[]; +extern struct list_head batadv_hardif_list; + +extern unsigned char batadv_broadcast_addr[]; +extern struct workqueue_struct *batadv_event_workqueue; + +int batadv_mesh_init(struct net_device *soft_iface); +void batadv_mesh_free(struct net_device *soft_iface); +void batadv_inc_module_count(void); +void batadv_dec_module_count(void); +int batadv_is_my_mac(const uint8_t *addr); +int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, + struct net_device *orig_dev); +int batadv_recv_handler_register(uint8_t packet_type, + int (*recv_handler)(struct sk_buff *, + struct hard_iface *)); +void batadv_recv_handler_unregister(uint8_t packet_type); +int batadv_algo_register(struct bat_algo_ops *bat_algo_ops); +int batadv_algo_select(struct bat_priv *bat_priv, char *name); +int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); #ifdef CONFIG_BATMAN_ADV_DEBUG int batadv_debug_log(struct bat_priv *bat_priv, const char *fmt, ...) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 9d77edeff589..3e902042af8f 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -35,7 +35,7 @@ static void purge_orig(struct work_struct *work); static void start_purge_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); - queue_delayed_work(bat_event_workqueue, + queue_delayed_work(batadv_event_workqueue, &bat_priv->orig_work, msecs_to_jiffies(1000)); } @@ -623,7 +623,7 @@ int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ rcu_read_lock(); - list_for_each_entry_rcu(hard_iface_tmp, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface_tmp, &batadv_hardif_list, list) { if (hard_iface_tmp->if_status == IF_NOT_IN_USE) continue; diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index d492634dd040..1b1dd41f5fe6 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -419,7 +419,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) goto out; /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) + if (!batadv_is_my_mac(ethhdr->h_dest)) goto out; icmp_packet = (struct icmp_packet_rr *)skb->data; @@ -433,7 +433,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) } /* packet for me */ - if (is_my_mac(icmp_packet->dst)) + if (batadv_is_my_mac(icmp_packet->dst)) return recv_my_icmp_packet(bat_priv, skb, hdr_size); /* TTL exceeded */ @@ -614,7 +614,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) case TT_RESPONSE: batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_RX); - if (is_my_mac(tt_query->dst)) { + if (batadv_is_my_mac(tt_query->dst)) { /* packet needs to be linearized to access the TT * changes */ if (skb_linearize(skb) < 0) @@ -670,7 +670,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) roam_adv_packet = (struct roam_adv_packet *)skb->data; - if (!is_my_mac(roam_adv_packet->dst)) + if (!batadv_is_my_mac(roam_adv_packet->dst)) return route_unicast_packet(skb, recv_if); /* check if it is a backbone gateway. we don't accept @@ -804,7 +804,7 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) return -1; /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) + if (!batadv_is_my_mac(ethhdr->h_dest)) return -1; return 0; @@ -909,7 +909,7 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, unicast_packet = (struct unicast_packet *)skb->data; - if (is_my_mac(unicast_packet->dest)) { + if (batadv_is_my_mac(unicast_packet->dest)) { tt_poss_change = bat_priv->tt_poss_change; curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); } else { @@ -985,7 +985,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) unicast_packet = (struct unicast_packet *)skb->data; /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { + if (batadv_is_my_mac(unicast_packet->dest)) { batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); return NET_RX_SUCCESS; @@ -1012,7 +1012,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, unicast_packet = (struct unicast_frag_packet *)skb->data; /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { + if (batadv_is_my_mac(unicast_packet->dest)) { ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); @@ -1057,13 +1057,13 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) goto out; /* ignore broadcasts sent by myself */ - if (is_my_mac(ethhdr->h_source)) + if (batadv_is_my_mac(ethhdr->h_source)) goto out; bcast_packet = (struct bcast_packet *)skb->data; /* ignore broadcasts originated by myself */ - if (is_my_mac(bcast_packet->orig)) + if (batadv_is_my_mac(bcast_packet->orig)) goto out; if (bcast_packet->header.ttl < 2) @@ -1139,14 +1139,14 @@ int batadv_recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) + if (!batadv_is_my_mac(ethhdr->h_dest)) return NET_RX_DROP; /* ignore own packets */ - if (is_my_mac(vis_packet->vis_orig)) + if (batadv_is_my_mac(vis_packet->vis_orig)) return NET_RX_DROP; - if (is_my_mac(vis_packet->sender_orig)) + if (batadv_is_my_mac(vis_packet->sender_orig)) return NET_RX_DROP; switch (vis_packet->vis_type) { diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 8226b1cf05eb..1a0f7c364ea0 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -121,7 +121,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet->delayed_work, send_outstanding_bcast_packet); - queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work, + queue_delayed_work(batadv_event_workqueue, &forw_packet->delayed_work, send_time); } @@ -205,7 +205,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work) /* rebroadcast packet */ rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &hardif_list, list) { + list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->soft_iface != soft_iface) continue; @@ -213,7 +213,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work) skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); if (skb1) batadv_send_skb_packet(skb1, hard_iface, - broadcast_addr); + batadv_broadcast_addr); } rcu_read_unlock(); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 9fd1925775c7..994b2b8d7e10 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -411,7 +411,7 @@ struct net_device *batadv_softif_create(const char *name) if (!bat_priv->bat_counters) goto unreg_soft_iface; - ret = bat_algo_select(bat_priv, bat_routing_algo); + ret = batadv_algo_select(bat_priv, batadv_routing_algo); if (ret < 0) goto free_bat_counters; @@ -423,7 +423,7 @@ struct net_device *batadv_softif_create(const char *name) if (ret < 0) goto unreg_sysfs; - ret = mesh_init(soft_iface); + ret = batadv_mesh_init(soft_iface); if (ret < 0) goto unreg_debugfs; @@ -449,7 +449,7 @@ void batadv_softif_destroy(struct net_device *soft_iface) { batadv_debugfs_del_meshif(soft_iface); batadv_sysfs_del_meshif(soft_iface); - mesh_free(soft_iface); + batadv_mesh_free(soft_iface); unregister_netdevice(soft_iface); } diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index ecef827ae28f..66e11b58312e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -48,7 +48,7 @@ static int compare_tt(const struct hlist_node *node, const void *data2) static void tt_start_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->tt_work, tt_purge); - queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work, + queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work, msecs_to_jiffies(5000)); } @@ -1673,7 +1673,7 @@ out: bool batadv_send_tt_response(struct bat_priv *bat_priv, struct tt_query_packet *tt_request) { - if (is_my_mac(tt_request->dst)) { + if (batadv_is_my_mac(tt_request->dst)) { /* don't answer backbone gws! */ if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) return true; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 24040c300636..83c931fa5c21 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -462,7 +462,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, /* Make it a broadcast packet, if required */ if (make_broadcast) - memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); + memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN); /* repair if entries is longer than packet. */ if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len) @@ -524,7 +524,7 @@ void batadv_receive_client_update_packet(struct bat_priv *bat_priv, /* Are we the target for this VIS packet? */ if (vis_server == VIS_TYPE_SERVER_SYNC && - is_my_mac(vis_packet->target_orig)) + batadv_is_my_mac(vis_packet->target_orig)) are_target = 1; spin_lock_bh(&bat_priv->vis_hash_lock); @@ -543,7 +543,7 @@ void batadv_receive_client_update_packet(struct bat_priv *bat_priv, send_list_add(bat_priv, info); /* ... we're not the recipient (and thus need to forward). */ - } else if (!is_my_mac(packet->target_orig)) { + } else if (!batadv_is_my_mac(packet->target_orig)) { send_list_add(bat_priv, info); } @@ -623,7 +623,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) info->first_seen = jiffies; packet->vis_type = atomic_read(&bat_priv->vis_mode); - memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); + memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN); packet->header.ttl = TTL; packet->seqno = htonl(ntohl(packet->seqno) + 1); packet->entries = 0; @@ -978,6 +978,6 @@ void batadv_vis_quit(struct bat_priv *bat_priv) static void start_vis_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets); - queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work, + queue_delayed_work(batadv_event_workqueue, &bat_priv->vis_work, msecs_to_jiffies(VIS_INTERVAL)); } -- GitLab From 9cfc7bd608b97463993b4f3e4775d99022253f8d Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 02:09:43 +0200 Subject: [PATCH 2288/6849] batman-adv: Reformat multiline comments to consistent style batman-adv doesn't follow the style for multiline comments that David S. Miller prefers. All comments should be reformatted to follow this consistent style to make the code slightly more readable. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_algo.h | 4 +- net/batman-adv/bat_debugfs.c | 4 +- net/batman-adv/bat_debugfs.h | 5 +- net/batman-adv/bat_iv_ogm.c | 75 ++++++++++++++----------- net/batman-adv/bat_sysfs.c | 13 +++-- net/batman-adv/bat_sysfs.h | 5 +- net/batman-adv/bitarray.c | 17 +++--- net/batman-adv/bitarray.h | 10 ++-- net/batman-adv/bridge_loop_avoidance.c | 67 +++++++--------------- net/batman-adv/bridge_loop_avoidance.h | 4 +- net/batman-adv/gateway_client.c | 41 +++++++------- net/batman-adv/gateway_client.h | 4 +- net/batman-adv/gateway_common.c | 9 +-- net/batman-adv/gateway_common.h | 4 +- net/batman-adv/hard-interface.c | 23 +++----- net/batman-adv/hard-interface.h | 4 +- net/batman-adv/hash.c | 4 +- net/batman-adv/hash.h | 24 ++++---- net/batman-adv/icmp_socket.c | 7 +-- net/batman-adv/icmp_socket.h | 4 +- net/batman-adv/main.c | 10 ++-- net/batman-adv/main.h | 38 +++++++------ net/batman-adv/originator.c | 13 +++-- net/batman-adv/originator.h | 9 ++- net/batman-adv/packet.h | 21 ++++--- net/batman-adv/ring_buffer.c | 4 +- net/batman-adv/ring_buffer.h | 4 +- net/batman-adv/routing.c | 67 +++++++++++++--------- net/batman-adv/routing.h | 4 +- net/batman-adv/send.c | 32 +++++------ net/batman-adv/send.h | 4 +- net/batman-adv/soft-interface.c | 27 ++++----- net/batman-adv/soft-interface.h | 4 +- net/batman-adv/translation-table.c | 78 ++++++++++++++++---------- net/batman-adv/translation-table.h | 4 +- net/batman-adv/types.h | 29 +++++----- net/batman-adv/unicast.c | 10 ++-- net/batman-adv/unicast.h | 4 +- net/batman-adv/vis.c | 39 ++++++++----- net/batman-adv/vis.h | 8 +-- 40 files changed, 349 insertions(+), 388 deletions(-) diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h index a14336a08fac..a0ba3bff9b36 100644 --- a/net/batman-adv/bat_algo.h +++ b/net/batman-adv/bat_algo.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 3900624d333d..4001c57a25e4 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" diff --git a/net/batman-adv/bat_debugfs.h b/net/batman-adv/bat_debugfs.h index 3b206c811263..eb0d576b4f9d 100644 --- a/net/batman-adv/bat_debugfs.h +++ b/net/batman-adv/bat_debugfs.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,10 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ - #ifndef _NET_BATMAN_ADV_DEBUGFS_H_ #define _NET_BATMAN_ADV_DEBUGFS_H_ diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 0430063d3a7d..94859d45ed6e 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -170,7 +168,8 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, batman_ogm_packet->tt_num_changes)) { /* we might have aggregated direct link packets with an - * ordinary base packet */ + * ordinary base packet + */ if ((forw_packet->direct_link_flags & (1 << packet_num)) && (forw_packet->if_incoming == hard_iface)) batman_ogm_packet->flags |= DIRECTLINK; @@ -237,8 +236,9 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) if (!primary_if) goto out; - /* multihomed peer assumed */ - /* non-primary OGMs are only broadcasted on their interface */ + /* multihomed peer assumed + * non-primary OGMs are only broadcasted on their interface + */ if ((directlink && (batman_ogm_packet->header.ttl == 1)) || (forw_packet->own && (forw_packet->if_incoming != primary_if))) { @@ -292,41 +292,39 @@ static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data; - /** - * we can aggregate the current packet to this aggregated packet + /* we can aggregate the current packet to this aggregated packet * if: * * - the send time is within our MAX_AGGREGATION_MS time * - the resulting packet wont be bigger than * MAX_AGGREGATION_BYTES */ - if (time_before(send_time, forw_packet->send_time) && time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), forw_packet->send_time) && (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { - /** - * check aggregation compatibility + /* check aggregation compatibility * -> direct link packets are broadcasted on * their interface only * -> aggregate packet if the current packet is * a "global" packet as well as the base * packet */ - primary_if = primary_if_get_selected(bat_priv); if (!primary_if) goto out; /* packets without direct link flag and high TTL - * are flooded through the net */ + * are flooded through the net + */ if ((!directlink) && (!(batman_ogm_packet->flags & DIRECTLINK)) && (batman_ogm_packet->header.ttl != 1) && /* own packets originating non-primary - * interfaces leave only that interface */ + * interfaces leave only that interface + */ ((!forw_packet->own) || (forw_packet->if_incoming == primary_if))) { res = true; @@ -334,14 +332,16 @@ static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet } /* if the incoming packet is sent via this one - * interface only - we still can aggregate */ + * interface only - we still can aggregate + */ if ((directlink) && (new_batman_ogm_packet->header.ttl == 1) && (forw_packet->if_incoming == if_incoming) && /* packets from direct neighbors or * own secondary interface packets - * (= secondary interface packets in general) */ + * (= secondary interface packets in general) + */ (batman_ogm_packet->flags & DIRECTLINK || (forw_packet->own && forw_packet->if_incoming != primary_if))) { @@ -457,8 +457,7 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, int packet_len, struct hard_iface *if_incoming, int own_packet, unsigned long send_time) { - /** - * _aggr -> pointer to the packet we want to aggregate with + /* _aggr -> pointer to the packet we want to aggregate with * _pos -> pointer to the position in the queue */ struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL; @@ -487,13 +486,13 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, } /* nothing to aggregate with - either aggregation disabled or no - * suitable aggregation packet found */ + * suitable aggregation packet found + */ if (!forw_packet_aggr) { /* the following section can run without the lock */ spin_unlock_bh(&bat_priv->forw_bat_list_lock); - /** - * if we could not aggregate this packet with one of the others + /* if we could not aggregate this packet with one of the others * we hold it back for a while, so that it might be aggregated * later on */ @@ -691,7 +690,8 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, batadv_bonding_candidate_add(orig_node, neigh_node); /* if this neighbor already is our next hop there is nothing - * to change */ + * to change + */ router = batadv_orig_node_get_router(orig_node); if (router == neigh_node) goto update_tt; @@ -701,7 +701,8 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, goto update_tt; /* if the TQ is the same and the link not more symmetric we - * won't consider it either */ + * won't consider it either + */ if (router && (neigh_node->tq_avg == router->tq_avg)) { orig_node_tmp = router->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); @@ -723,7 +724,8 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, update_tt: /* I have to check for transtable changes only if the OGM has been - * sent through a primary interface */ + * sent through a primary interface + */ if (((batman_ogm_packet->orig != ethhdr->h_source) && (batman_ogm_packet->header.ttl > 2)) || (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) @@ -812,15 +814,17 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, total_count = (orig_eq_count > neigh_rq_count ? neigh_rq_count : orig_eq_count); - /* if we have too few packets (too less data) we set tq_own to zero */ - /* if we receive too few packets it is not considered bidirectional */ + /* if we have too few packets (too less data) we set tq_own to zero + * if we receive too few packets it is not considered bidirectional + */ if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) tq_own = 0; else /* neigh_node->real_packet_count is never zero as we * only purge old information when getting new - * information */ + * information + */ tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count; /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does @@ -846,7 +850,8 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, neigh_rq_count, tq_own, tq_asym_penalty, batman_ogm_packet->tq); /* if link has the minimum required transmission quality - * consider it bidirectional */ + * consider it bidirectional + */ if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) ret = 1; @@ -1039,8 +1044,9 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, return; /* neighbor has to indicate direct link and it has to - * come via the corresponding interface */ - /* save packet seqno for bidirectional check */ + * come via the corresponding interface + * save packet seqno for bidirectional check + */ if (has_directlink_flag && compare_eth(if_incoming->net_dev->dev_addr, batman_ogm_packet->orig)) { @@ -1117,7 +1123,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, } /* if sender is a direct neighbor the sender mac equals - * originator mac */ + * originator mac + */ orig_neigh_node = (is_single_hop_neigh ? orig_node : batadv_get_orig_node(bat_priv, ethhdr->h_source)); @@ -1127,7 +1134,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node); /* drop packet if sender is not a direct neighbor and if we - * don't route towards it */ + * don't route towards it + */ if (!is_single_hop_neigh && (!orig_neigh_router)) { bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: OGM via unknown neighbor!\n"); @@ -1141,7 +1149,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, batman_ogm_packet); /* update ranking if it is not a duplicate or has the same - * seqno and similar ttl as the non-duplicate */ + * seqno and similar ttl as the non-duplicate + */ if (is_bidirectional && (!is_duplicate || ((orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno)) && diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 5a7b042873e1..8196fa6ff22e 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -84,7 +82,8 @@ ssize_t show_##_name(struct kobject *kobj, \ } \ /* Use this, if you are going to turn a [name] in the soft-interface - * (bat_priv) on or off */ + * (bat_priv) on or off + */ #define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \ static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ static BAT_ATTR_SIF_SHOW_BOOL(_name) \ @@ -110,7 +109,8 @@ ssize_t show_##_name(struct kobject *kobj, \ } \ /* Use this, if you are going to set [name] in the soft-interface - * (bat_priv) to an unsigned integer value */ + * (bat_priv) to an unsigned integer value + */ #define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ static BAT_ATTR_SIF_SHOW_UINT(_name) \ @@ -155,7 +155,8 @@ ssize_t show_##_name(struct kobject *kobj, \ } /* Use this, if you are going to set [name] in hard_iface to an - * unsigned integer value*/ + * unsigned integer value + */ #define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ static BAT_ATTR_HIF_SHOW_UINT(_name) \ diff --git a/net/batman-adv/bat_sysfs.h b/net/batman-adv/bat_sysfs.h index f01aea836b98..367227707d52 100644 --- a/net/batman-adv/bat_sysfs.h +++ b/net/batman-adv/bat_sysfs.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,10 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ - #ifndef _NET_BATMAN_ADV_SYSFS_H_ #define _NET_BATMAN_ADV_SYSFS_H_ diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index 99ed9917ff0d..838abbc73c6c 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -46,8 +44,8 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, struct bat_priv *bat_priv = priv; /* sequence number is slightly older. We already got a sequence number - * higher than this one, so we just mark it. */ - + * higher than this one, so we just mark it. + */ if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { if (set_mark) bat_set_bit(seq_bits, -seq_num_diff); @@ -55,8 +53,8 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, } /* sequence number is slightly newer, so we shift the window and - * set the mark if required */ - + * set the mark if required + */ if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { batadv_bitmap_shift_left(seq_bits, seq_num_diff); @@ -66,7 +64,6 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, } /* sequence number is much newer, probably missed a lot of packets */ - if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) && (seq_num_diff < EXPECTED_SEQNO_RANGE)) { bat_dbg(DBG_BATMAN, bat_priv, @@ -81,8 +78,8 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, /* received a much older packet. The other host either restarted * or the old packet got delayed somewhere in the network. The * packet should be dropped without calling this function if the - * seqno window is protected. */ - + * seqno window is protected. + */ if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h index e855ddd37430..8ab542632343 100644 --- a/net/batman-adv/bitarray.h +++ b/net/batman-adv/bitarray.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * @@ -16,14 +15,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_BITARRAY_H_ #define _NET_BATMAN_ADV_BITARRAY_H_ /* returns true if the corresponding bit in the given seq_bits indicates true - * and curr_seqno is within range of last_seqno */ + * and curr_seqno is within range of last_seqno + */ static inline int bat_test_bit(const unsigned long *seq_bits, uint32_t last_seqno, uint32_t curr_seqno) { @@ -47,7 +46,8 @@ static inline void bat_set_bit(unsigned long *seq_bits, int32_t n) } /* receive and process one packet, returns 1 if received seq_num is considered - * new, 0 if old */ + * new, 0 if old + */ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, int32_t seq_num_diff, int set_mark); diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 27f451a64ad0..52c0d637d581 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -123,8 +121,7 @@ static void claim_free_ref(struct claim *claim) call_rcu(&claim->rcu, claim_free_rcu); } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @data: search data (may be local/static data) * * looks for a claim in the hash, and returns it if found @@ -162,8 +159,7 @@ static struct claim *claim_hash_find(struct bat_priv *bat_priv, return claim_tmp; } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @addr: the address of the originator * @vid: the VLAN ID * @@ -241,8 +237,7 @@ static void bla_del_backbone_claims(struct backbone_gw *backbone_gw) backbone_gw->crc = BLA_CRC_INIT; } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @orig: the mac address to be announced within the claim * @vid: the VLAN ID * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...) @@ -347,8 +342,7 @@ out: hardif_free_ref(primary_if); } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @orig: the mac address of the originator * @vid: the VLAN ID * @@ -422,8 +416,7 @@ static void bla_update_own_backbone_gw(struct bat_priv *bat_priv, backbone_gw_free_ref(backbone_gw); } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @vid: the vid where the request came on * * Repeat all of our own claims, and finally send an ANNOUNCE frame @@ -468,8 +461,7 @@ static void bla_answer_request(struct bat_priv *bat_priv, backbone_gw_free_ref(backbone_gw); } -/** - * @backbone_gw: the backbone gateway from whom we are out of sync +/* @backbone_gw: the backbone gateway from whom we are out of sync * * When the crc is wrong, ask the backbone gateway for a full table update. * After the request, it will repeat all of his own claims and finally @@ -495,8 +487,7 @@ static void bla_send_request(struct backbone_gw *backbone_gw) } } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @backbone_gw: our backbone gateway which should be announced * * This function sends an announcement. It is called from multiple @@ -516,8 +507,7 @@ static void bla_send_announce(struct bat_priv *bat_priv, } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @mac: the mac address of the claim * @vid: the VLAN ID of the frame * @backbone_gw: the backbone gateway which claims it @@ -731,8 +721,7 @@ static int handle_claim(struct bat_priv *bat_priv, return 1; } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @hw_src: the Hardware source in the ARP Header * @hw_dst: the Hardware destination in the ARP Header * @ethhdr: pointer to the Ethernet header of the claim frame @@ -810,8 +799,7 @@ static int check_claim_group(struct bat_priv *bat_priv, } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @skb: the frame to be checked * * Check if this is a claim frame, and process it accordingly. @@ -860,7 +848,6 @@ static int bla_process_claim(struct bat_priv *bat_priv, /* Check whether the ARP frame carries a valid * IP information */ - if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) return 0; if (arphdr->ar_pro != htons(ETH_P_IP)) @@ -963,8 +950,7 @@ purge_now: } } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @primary_if: the selected primary interface, may be NULL if now is set * @now: whether the whole hash shall be wiped now * @@ -1011,13 +997,11 @@ purge_now: } } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @primary_if: the new selected primary_if * @oldif: the old primary interface, may be NULL * * Update the backbone gateways when the own orig address changes. - * */ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, struct hard_iface *primary_if, @@ -1183,8 +1167,7 @@ int batadv_bla_init(struct bat_priv *bat_priv) return 0; } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @bcast_packet: originator mac address * @hdr_size: maximum length of the frame * @@ -1196,9 +1179,7 @@ int batadv_bla_init(struct bat_priv *bat_priv) * with a good chance that it is the same packet. If it is furthermore * sent by another host, drop it. We allow equal packets from * the same host however as this might be intended. - * - **/ - + */ int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, struct bcast_packet *bcast_packet, int hdr_size) @@ -1250,16 +1231,13 @@ int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @orig: originator mac address * * check if the originator is a gateway for any VLAN ID. * * returns 1 if it is found, 0 otherwise - * */ - int batadv_bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) { struct hashtable_t *hash = bat_priv->backbone_hash; @@ -1291,15 +1269,13 @@ int batadv_bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) } -/** - * @skb: the frame to be checked +/* @skb: the frame to be checked * @orig_node: the orig_node of the frame * @hdr_size: maximum length of the frame * * bla_is_backbone_gw inspects the skb for the VLAN ID and returns 1 * if the orig_node is also a gateway on the soft interface, otherwise it * returns 0. - * */ int batadv_bla_is_backbone_gw(struct sk_buff *skb, struct orig_node *orig_node, int hdr_size) @@ -1328,7 +1304,6 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb, } /* see if this originator is a backbone gw for this VLAN */ - backbone_gw = backbone_hash_find(orig_node->bat_priv, orig_node->orig, vid); if (!backbone_gw) @@ -1360,8 +1335,7 @@ void batadv_bla_free(struct bat_priv *bat_priv) hardif_free_ref(primary_if); } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @skb: the frame to be checked * @vid: the VLAN ID of the frame * @@ -1372,7 +1346,6 @@ void batadv_bla_free(struct bat_priv *bat_priv) * in these cases, the skb is further handled by this function and * returns 1, otherwise it returns 0 and the caller shall further * process the skb. - * */ int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) { @@ -1449,8 +1422,7 @@ out: return ret; } -/** - * @bat_priv: the bat priv with all the soft interface information +/* @bat_priv: the bat priv with all the soft interface information * @skb: the frame to be checked * @vid: the VLAN ID of the frame * @@ -1461,7 +1433,6 @@ out: * in these cases, the skb is further handled by this function and * returns 1, otherwise it returns 0 and the caller shall further * process the skb. - * */ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) { diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 546cd641012a..9818b1e4c59e 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_BLA_H_ diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index e396029e578b..0d90fffd9efb 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -33,7 +31,8 @@ #include /* This is the offset of the options field in a dhcp packet starting at - * the beginning of the dhcp header */ + * the beginning of the dhcp header + */ #define DHCP_OPTIONS_OFFSET 240 #define DHCP_REQUEST 3 @@ -151,14 +150,13 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) } break; - default: /** - * 2: stable connection (use best statistic) + default: /* 2: stable connection (use best statistic) * 3: fast-switch (use best statistic but change as * soon as a better gateway appears) * XX: late-switch (use best statistic but change as * soon as a better gateway appears which has * $routing_class more tq points) - **/ + */ if (router->tq_avg > max_tq) { if (curr_gw) gw_node_free_ref(curr_gw); @@ -190,12 +188,11 @@ void batadv_gw_election(struct bat_priv *bat_priv) struct neigh_node *router = NULL; char gw_addr[18] = { '\0' }; - /** - * The batman daemon checks here if we already passed a full originator + /* The batman daemon checks here if we already passed a full originator * cycle in order to make sure we don't choose the first gateway we * hear about. This check is based on the daemon's uptime which we * don't have. - **/ + */ if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) goto out; @@ -278,10 +275,9 @@ void batadv_gw_check_election(struct bat_priv *bat_priv, if (orig_tq_avg < gw_tq_avg) goto out; - /** - * if the routing class is greater than 3 the value tells us how much + /* if the routing class is greater than 3 the value tells us how much * greater the TQ value of the new gateway must be - **/ + */ if ((atomic_read(&bat_priv->gw_sel_class) > 3) && (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) goto out; @@ -337,8 +333,7 @@ void batadv_gw_node_update(struct bat_priv *bat_priv, struct hlist_node *node; struct gw_node *gw_node, *curr_gw; - /** - * Note: We don't need a NULL check here, since curr_gw never gets + /* Note: We don't need a NULL check here, since curr_gw never gets * dereferenced. If curr_gw is NULL we also should not exit as we may * have this gateway in our list (duplication check!) even though we * have no currently selected gateway. @@ -426,9 +421,7 @@ void batadv_gw_node_purge(struct bat_priv *bat_priv) gw_node_free_ref(curr_gw); } -/** - * fails if orig_node has no router - */ +/* fails if orig_node has no router */ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, const struct gw_node *gw_node) { @@ -534,12 +527,14 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len) /* Access the dhcp option lists. Each entry is made up by: * - octet 1: option type * - octet 2: option data len (only if type != 255 and 0) - * - octet 3: option data */ + * - octet 3: option data + */ while (*p != 255 && !ret) { /* p now points to the first octet: option type */ if (*p == 53) { /* type 53 is the message type option. - * Jump the len octet and go to the data octet */ + * Jump the len octet and go to the data octet + */ if (pkt_len < 2) goto out; p += 2; @@ -667,7 +662,8 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, switch (atomic_read(&bat_priv->gw_mode)) { case GW_MODE_SERVER: /* If we are a GW then we are our best GW. We can artificially - * set the tq towards ourself as the maximum value */ + * set the tq towards ourself as the maximum value + */ curr_tq_avg = TQ_MAX_VALUE; break; case GW_MODE_CLIENT: @@ -681,7 +677,8 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, /* If the dhcp packet has been sent to a different gw, * we have to evaluate whether the old gw is still - * reliable enough */ + * reliable enough + */ neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node, NULL); if (!neigh_curr) diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h index 2c2446f3f124..4529d42894ef 100644 --- a/net/batman-adv/gateway_client.h +++ b/net/batman-adv/gateway_client.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 722c93282442..3700562cf276 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -156,11 +154,10 @@ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); - /** - * the gw bandwidth we guessed above might not match the given + /* the gw bandwidth we guessed above might not match the given * speeds, hence we need to calculate it back to show the number * that is going to be propagated - **/ + */ batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up); if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h index e256040760bf..6f8a4d0cbbb6 100644 --- a/net/batman-adv/gateway_common.h +++ b/net/batman-adv/gateway_common.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_ diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index ab2fcfaf297e..2a4d394771b8 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -74,10 +72,6 @@ static int is_valid_iface(const struct net_device *net_dev) if (batadv_softif_is_valid(net_dev)) return 0; - /* Device is being bridged */ - /* if (net_dev->priv_flags & IFF_BRIDGE_PORT) - return 0; */ - return 1; } @@ -185,7 +179,8 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface) const struct bat_priv *bat_priv = netdev_priv(soft_iface); const struct hard_iface *hard_iface; /* allow big frames if all devices are capable to do so - * (have MTU > 1500 + BAT_HEADER_LEN) */ + * (have MTU > 1500 + BAT_HEADER_LEN) + */ int min_mtu = ETH_DATA_LEN; if (atomic_read(&bat_priv->fragmentation)) @@ -231,8 +226,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); hard_iface->if_status = IF_TO_BE_ACTIVATED; - /** - * the first active interface becomes our primary interface or + /* the first active interface becomes our primary interface or * the next active interface after the old primary interface was removed */ primary_if = primary_if_get_selected(bat_priv); @@ -438,8 +432,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev) check_known_mac_addr(hard_iface->net_dev); list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); - /** - * This can't be called via a bat_priv callback because + /* This can't be called via a bat_priv callback because * we have no bat_priv yet. */ atomic_set(&hard_iface->seqno, 1); @@ -544,7 +537,8 @@ out: } /* This function returns true if the interface represented by ifindex is a - * 802.11 wireless device */ + * 802.11 wireless device + */ bool batadv_is_wifi_iface(int ifindex) { struct net_device *net_device = NULL; @@ -559,7 +553,8 @@ bool batadv_is_wifi_iface(int ifindex) #ifdef CONFIG_WIRELESS_EXT /* pre-cfg80211 drivers have to implement WEXT, so it is possible to - * check for wireless_handlers != NULL */ + * check for wireless_handlers != NULL + */ if (net_device->wireless_handlers) ret = true; else diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 20e09db29d15..6bc12c0eb2f0 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_ diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index 65bbd15dd37c..e39f8f4bb165 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index e75df6be4f22..eba8f2a55ccc 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2006-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_HASH_H_ @@ -24,15 +22,15 @@ #include -/* callback to a compare function. should - * compare 2 element datas for their keys, - * return 0 if same and not 0 if not - * same */ +/* callback to a compare function. should compare 2 element datas for their + * keys, return 0 if same and not 0 if not same + */ typedef int (*hashdata_compare_cb)(const struct hlist_node *, const void *); /* the hashfunction, should return an index * based on the key in the data of the first - * argument and the size the second */ + * argument and the size the second + */ typedef uint32_t (*hashdata_choose_cb)(const void *, uint32_t); typedef void (*hashdata_free_cb)(struct hlist_node *, void *); @@ -54,7 +52,8 @@ void batadv_hash_destroy(struct hashtable_t *hash); /* remove the hash structure. if hashdata_free_cb != NULL, this function will be * called to remove the elements inside of the hash. if you don't remove the - * elements, memory might be leaked. */ + * elements, memory might be leaked. + */ static inline void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg) { @@ -80,8 +79,7 @@ static inline void hash_delete(struct hashtable_t *hash, batadv_hash_destroy(hash); } -/** - * hash_add - adds data to the hashtable +/* hash_add - adds data to the hashtable * @hash: storage hash table * @compare: callback to determine if 2 hash elements are identical * @choose: callback calculating the hash index @@ -91,7 +89,6 @@ static inline void hash_delete(struct hashtable_t *hash, * Returns 0 on success, 1 if the element already is in the hash * and -1 on error. */ - static inline int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, hashdata_choose_cb choose, @@ -134,7 +131,8 @@ out: /* removes data from hash, if found. returns pointer do data on success, so you * can remove the used structure yourself, or NULL on error . data could be the * structure you use with just the key filled, we just need the key for - * comparing. */ + * comparing. + */ static inline void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, hashdata_choose_cb choose, void *data) diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 230056139445..40c5e189e6fd 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -312,7 +310,8 @@ static void bat_socket_add_packet(struct socket_client *socket_client, spin_lock_bh(&socket_client->lock); /* while waiting for the lock the socket_client could have been - * deleted */ + * deleted + */ if (!socket_client_hash[icmp_packet->uid]) { spin_unlock_bh(&socket_client->lock); kfree(socket_packet); diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h index 7b8863668490..a62ab80df9bd 100644 --- a/net/batman-adv/icmp_socket.h +++ b/net/batman-adv/icmp_socket.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_ diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 5e1d906628f5..d56d6b2e1924 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -37,7 +35,8 @@ /* List manipulations on hardif_list have to be rtnl_lock()'ed, - * list traversals just rcu-locked */ + * list traversals just rcu-locked + */ struct list_head batadv_hardif_list; static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); char batadv_routing_algo[20] = "BATMAN_IV"; @@ -59,7 +58,8 @@ static int __init batman_init(void) batadv_iv_init(); /* the name should not be longer than 10 chars - see - * http://lwn.net/Articles/23634/ */ + * http://lwn.net/Articles/23634/ + */ batadv_event_workqueue = create_singlethread_workqueue("bat_events"); if (!batadv_event_workqueue) diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 12386421a55b..4b06b7621e7a 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_MAIN_H_ @@ -36,19 +34,21 @@ #define TQ_MAX_VALUE 255 #define JITTER 20 - /* Time To Live of broadcast messages */ +/* Time To Live of broadcast messages */ #define TTL 50 /* purge originators after time in seconds if no valid packet comes in - * -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */ + * -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE + */ #define PURGE_TIMEOUT 200000 /* 200 seconds */ #define TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */ #define TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */ /* sliding packet range of received originator messages in sequence numbers - * (should be a multiple of our word size) */ + * (should be a multiple of our word size) + */ #define TQ_LOCAL_WINDOW_SIZE 64 -#define TT_REQUEST_TIMEOUT 3000 /* miliseconds we have to keep - * pending tt_req */ +/* miliseconds we have to keep pending tt_req */ +#define TT_REQUEST_TIMEOUT 3000 #define TQ_GLOBAL_WINDOW_SIZE 5 #define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 @@ -57,8 +57,10 @@ #define TT_OGM_APPEND_MAX 3 /* number of OGMs sent with the last tt diff */ -#define ROAMING_MAX_TIME 20000 /* Time in which a client can roam at most - * ROAMING_MAX_COUNT times in miliseconds*/ +/* Time in which a client can roam at most ROAMING_MAX_COUNT times in + * miliseconds + */ +#define ROAMING_MAX_TIME 20000 #define ROAMING_MAX_COUNT 5 #define NO_FLAGS 0 @@ -72,11 +74,13 @@ #define VIS_INTERVAL 5000 /* 5 seconds */ /* how much worse secondary interfaces may be to be considered as bonding - * candidates */ + * candidates + */ #define BONDING_TQ_THRESHOLD 50 /* should not be bigger than 512 bytes or change the size of - * forw_packet->direct_link_flags */ + * forw_packet->direct_link_flags + */ #define MAX_AGGREGATION_BYTES 512 #define MAX_AGGREGATION_MS 100 @@ -201,19 +205,16 @@ static inline void bat_dbg(int type __always_unused, pr_err("%s: " fmt, _netdev->name, ## arg); \ } while (0) -/** - * returns 1 if they are the same ethernet addr +/* returns 1 if they are the same ethernet addr * * note: can't use compare_ether_addr() as it requires aligned memory */ - static inline int compare_eth(const void *data1, const void *data2) { return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } -/** - * has_timed_out - compares current time (jiffies) and timestamp + timeout +/* has_timed_out - compares current time (jiffies) and timestamp + timeout * @timestamp: base value to compare with (in jiffies) * @timeout: added to base value before comparing (in milliseconds) * @@ -237,7 +238,8 @@ static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout) * - when adding nothing - it is neither a predecessor nor a successor * - before adding more than 127 to the starting value - it is a predecessor, * - when adding 128 - it is neither a predecessor nor a successor, - * - after adding more than 127 to the starting value - it is a successor */ + * - after adding more than 127 to the starting value - it is a successor + */ #define seq_before(x, y) ({typeof(x) _d1 = (x); \ typeof(y) _d2 = (y); \ typeof(x) _dummy = (_d1 - _d2); \ diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 3e902042af8f..86e7e082c2bc 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2009-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -188,7 +186,8 @@ void batadv_originator_free(struct bat_priv *bat_priv) } /* this function finds or creates an originator entry for the given - * address if it does not exits */ + * address if it does not exits + */ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr) { @@ -521,7 +520,8 @@ int batadv_orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) int ret; /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ + * if_num + */ for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -604,7 +604,8 @@ int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) int ret; /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ + * if_num + */ for (i = 0; i < hash->size; i++) { head = &hash->table[i]; diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 97deeba787ea..a72171997056 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_ORIGINATOR_H_ @@ -40,8 +38,9 @@ int batadv_orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num); int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); -/* hashfunction to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ +/* hashfunction to choose an entry in a hash table of given size + * hash algorithm from http://en.wikipedia.org/wiki/Hash_table + */ static inline uint32_t choose_orig(const void *data, uint32_t size) { const unsigned char *key = data; diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 033d99490e82..c90219cd648e 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_PACKET_H_ @@ -81,7 +79,8 @@ enum tt_query_flags { /* TT_CLIENT flags. * Flags from 1 to 1 << 7 are sent on the wire, while flags from 1 << 8 to - * 1 << 15 are used for local computation only */ + * 1 << 15 are used for local computation only + */ enum tt_client_flags { TT_CLIENT_DEL = 1 << 0, TT_CLIENT_ROAM = 1 << 1, @@ -142,7 +141,8 @@ struct icmp_packet { #define BAT_RR_LEN 16 /* icmp_packet_rr must start with all fields from imcp_packet - * as this is assumed by code that handles ICMP packets */ + * as this is assumed by code that handles ICMP packets + */ struct icmp_packet_rr { struct batman_header header; uint8_t msg_type; /* see ICMP message types above */ @@ -192,7 +192,8 @@ struct tt_query_packet { struct batman_header header; /* the flag field is a combination of: * - TT_REQUEST or TT_RESPONSE - * - TT_FULL_TABLE */ + * - TT_FULL_TABLE + */ uint8_t flags; uint8_t dst[ETH_ALEN]; uint8_t src[ETH_ALEN]; @@ -200,13 +201,15 @@ struct tt_query_packet { * if TT_REQUEST: ttvn that triggered the * request * if TT_RESPONSE: new ttvn for the src - * orig_node */ + * orig_node + */ uint8_t ttvn; /* tt_data field is: * if TT_REQUEST: crc associated with the * ttvn - * if TT_RESPONSE: table_size */ - __be16 tt_data; + * if TT_RESPONSE: table_size + */ + __be16 tt_data; } __packed; struct roam_adv_packet { diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c index db8f5ef83d3e..aff1ca2990f1 100644 --- a/net/batman-adv/ring_buffer.c +++ b/net/batman-adv/ring_buffer.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" diff --git a/net/batman-adv/ring_buffer.h b/net/batman-adv/ring_buffer.h index fbaf9d29d1d7..fda8c17df273 100644 --- a/net/batman-adv/ring_buffer.h +++ b/net/batman-adv/ring_buffer.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_RING_BUFFER_H_ diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 1b1dd41f5fe6..79f63cf11be4 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -165,8 +163,7 @@ void batadv_bonding_candidate_add(struct orig_node *orig_node, if (neigh_node->tq_avg < router->tq_avg - BONDING_TQ_THRESHOLD) goto candidate_del; - /** - * check if we have another candidate with the same mac address or + /* check if we have another candidate with the same mac address or * interface. If we do, we won't select this candidate because of * possible interference. */ @@ -177,7 +174,8 @@ void batadv_bonding_candidate_add(struct orig_node *orig_node, continue; /* we only care if the other candidate is even - * considered as candidate. */ + * considered as candidate. + */ if (list_empty(&tmp_neigh_node->bonding_list)) continue; @@ -398,9 +396,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) int hdr_size = sizeof(struct icmp_packet); int ret = NET_RX_DROP; - /** - * we truncate all incoming icmp packets if they don't match our size - */ + /* we truncate all incoming icmp packets if they don't match our size */ if (skb->len >= sizeof(struct icmp_packet_rr)) hdr_size = sizeof(struct icmp_packet_rr); @@ -474,7 +470,8 @@ out: * robin fashion over the remaining interfaces. * * This method rotates the bonding list and increases the - * returned router's refcount. */ + * returned router's refcount. + */ static struct neigh_node *find_bond_router(struct orig_node *primary_orig, const struct hard_iface *recv_if) { @@ -507,10 +504,12 @@ static struct neigh_node *find_bond_router(struct orig_node *primary_orig, goto out; /* selected should point to the next element - * after the current router */ + * after the current router + */ spin_lock_bh(&primary_orig->neigh_list_lock); /* this is a list_move(), which unfortunately - * does not exist as rcu version */ + * does not exist as rcu version + */ list_del_rcu(&primary_orig->bond_list); list_add_rcu(&primary_orig->bond_list, &router->bonding_list); @@ -525,7 +524,8 @@ out: * remaining candidates which are not using * this interface. * - * Increases the returned router's refcount */ + * Increases the returned router's refcount + */ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, const struct hard_iface *recv_if) { @@ -546,11 +546,13 @@ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, continue; /* if we don't have a router yet - * or this one is better, choose it. */ + * or this one is better, choose it. + */ if ((!router) || (tmp_neigh_node->tq_avg > router->tq_avg)) { /* decrement refcount of - * previously selected router */ + * previously selected router + */ if (router) batadv_neigh_node_free_ref(router); @@ -602,7 +604,8 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX); /* If we cannot provide an answer the tt_request is - * forwarded */ + * forwarded + */ if (!batadv_send_tt_response(bat_priv, tt_query)) { bat_dbg(DBG_TT, bat_priv, "Routing TT_REQUEST to %pM [%c]\n", @@ -616,7 +619,8 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) if (batadv_is_my_mac(tt_query->dst)) { /* packet needs to be linearized to access the TT - * changes */ + * changes + */ if (skb_linearize(skb) < 0) goto out; /* skb_linearize() possibly changed skb->data */ @@ -694,7 +698,8 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) /* Roaming phase starts: I have new information but the ttvn has not * been incremented yet. This flag will make me check all the incoming - * packets for the correct destination. */ + * packets for the correct destination. + */ bat_priv->tt_poss_change = true; batadv_orig_node_free_ref(orig_node); @@ -705,7 +710,8 @@ out: /* find a suitable router for this originator, and use * bonding if possible. increases the found neighbors - * refcount.*/ + * refcount. + */ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, struct orig_node *orig_node, const struct hard_iface *recv_if) @@ -724,7 +730,8 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, goto err; /* without bonding, the first node should - * always choose the default router. */ + * always choose the default router. + */ bonding_enabled = atomic_read(&bat_priv->bonding); rcu_read_lock(); @@ -737,13 +744,14 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, goto return_router; /* if we have something in the primary_addr, we can search - * for a potential bonding candidate. */ + * for a potential bonding candidate. + */ if (compare_eth(router_orig->primary_addr, zero_mac)) goto return_router; /* find the orig_node which has the primary interface. might - * even be the same as our router_orig in many cases */ - + * even be the same as our router_orig in many cases + */ if (compare_eth(router_orig->primary_addr, router_orig->orig)) { primary_orig_node = router_orig; } else { @@ -756,14 +764,15 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, } /* with less than 2 candidates, we can't do any - * bonding and prefer the original router. */ + * bonding and prefer the original router. + */ if (atomic_read(&primary_orig_node->bond_candidates) < 2) goto return_router; /* all nodes between should choose a candidate which * is is not on the interface where the packet came - * in. */ - + * in. + */ batadv_neigh_node_free_ref(router); if (bonding_enabled) @@ -1089,7 +1098,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) goto spin_unlock; /* mark broadcast in flood history, update window position - * if required. */ + * if required. + */ if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); @@ -1165,6 +1175,7 @@ int batadv_recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if) } /* We take a copy of the data in the packet, so we should - always free the skbuf. */ + * always free the skbuf. + */ return NET_RX_DROP; } diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 4652f0c147f5..c3fd219e8e53 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_ROUTING_H_ diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 1a0f7c364ea0..2c92a32ec6c6 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -32,7 +30,8 @@ static void send_outstanding_bcast_packet(struct work_struct *work); /* send out an already prepared packet to the given address via the - * specified batman interface */ + * specified batman interface + */ int batadv_send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, const uint8_t *dst_addr) { @@ -69,8 +68,8 @@ int batadv_send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, /* dev_queue_xmit() returns a negative result on error. However on * congestion and traffic shaping, it drops and returns NET_XMIT_DROP - * (which is > 0). This will not be treated as an error. */ - + * (which is > 0). This will not be treated as an error. + */ return dev_queue_xmit(skb); send_skb_err: kfree_skb(skb); @@ -85,8 +84,7 @@ void batadv_schedule_bat_ogm(struct hard_iface *hard_iface) (hard_iface->if_status == IF_TO_BE_REMOVED)) return; - /** - * the interface gets activated here to avoid race conditions between + /* the interface gets activated here to avoid race conditions between * the moment of activating the interface in * hardif_activate_interface() where the originator mac is set and * outdated packets (especially uninitialized mac addresses) in the @@ -132,7 +130,8 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, * errors. * * The skb is not consumed, so the caller should make sure that the - * skb is freed. */ + * skb is freed. + */ int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, const struct sk_buff *skb, unsigned long delay) @@ -249,8 +248,7 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work) bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet); - /** - * we have to have at least one packet in the queue + /* we have to have at least one packet in the queue * to determine the queues wake up time unless we are * shutting down */ @@ -285,8 +283,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &bat_priv->forw_bcast_list, list) { - /** - * if purge_outstanding_packets() was called with an argument + /* if purge_outstanding_packets() was called with an argument * we delete only packets belonging to the given interface */ if ((hard_iface) && @@ -295,8 +292,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, spin_unlock_bh(&bat_priv->forw_bcast_list_lock); - /** - * send_outstanding_bcast_packet() will lock the list to + /* send_outstanding_bcast_packet() will lock the list to * delete the item from the list */ pending = cancel_delayed_work_sync(&forw_packet->delayed_work); @@ -314,8 +310,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &bat_priv->forw_bat_list, list) { - /** - * if purge_outstanding_packets() was called with an argument + /* if purge_outstanding_packets() was called with an argument * we delete only packets belonging to the given interface */ if ((hard_iface) && @@ -324,8 +319,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, spin_unlock_bh(&bat_priv->forw_bat_list_lock); - /** - * send_outstanding_bat_packet() will lock the list to + /* send_outstanding_bat_packet() will lock the list to * delete the item from the list */ pending = cancel_delayed_work_sync(&forw_packet->delayed_work); diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h index 452e8df5abb8..e3ac75ba432b 100644 --- a/net/batman-adv/send.h +++ b/net/batman-adv/send.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_SEND_H_ diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 994b2b8d7e10..0658781febde 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -65,8 +63,7 @@ int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) { int result; - /** - * TODO: We must check if we can release all references to non-payload + /* TODO: We must check if we can release all references to non-payload * data using skb_header_release in our skbs to allow skb_cow_header to * work optimally. This means that those skbs are not allowed to read * or write any data which is before the current position of skb->data @@ -180,14 +177,16 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) switch (atomic_read(&bat_priv->gw_mode)) { case GW_MODE_SERVER: /* gateway servers should not send dhcp - * requests into the mesh */ + * requests into the mesh + */ ret = batadv_gw_is_dhcp_target(skb, &header_len); if (ret) goto dropped; break; case GW_MODE_CLIENT: /* gateway clients should send dhcp requests - * via unicast to their gateway */ + * via unicast to their gateway + */ ret = batadv_gw_is_dhcp_target(skb, &header_len); if (ret) do_bcast = false; @@ -215,7 +214,8 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) bcast_packet->header.packet_type = BAT_BCAST; /* hw address of first interface is the orig mac because only - * this mac is known throughout the mesh */ + * this mac is known throughout the mesh + */ memcpy(bcast_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); @@ -226,7 +226,8 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) batadv_add_bcast_packet_to_list(bat_priv, skb, 1); /* a copy is stored in the bcast list, therefore removing - * the original skb. */ + * the original skb. + */ kfree_skb(skb); /* unicast packet */ @@ -294,9 +295,10 @@ void batadv_interface_rx(struct net_device *soft_iface, /* should not be necessary anymore as we use skb_pull_rcsum() * TODO: please verify this and remove this TODO - * -- Dec 21st 2009, Simon Wunderlich */ + * -- Dec 21st 2009, Simon Wunderlich + */ -/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ + /* skb->ip_summed = CHECKSUM_UNNECESSARY; */ bat_priv->stats.rx_packets++; bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; @@ -341,8 +343,7 @@ static void interface_setup(struct net_device *dev) dev->destructor = free_netdev; dev->tx_queue_len = 0; - /** - * can't call min_mtu, because the needed variables + /* can't call min_mtu, because the needed variables * have not been initialized yet */ dev->mtu = ETH_DATA_LEN; diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 7e2bfafbcb79..2711ba5b1233 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_ diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 66e11b58312e..5180d50e909d 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich, Antonio Quartulli * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -232,7 +230,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, /* The local entry has to be marked as NEW to avoid to send it in * a full table response going out before the next ttvn increment - * (consistency check) */ + * (consistency check) + */ tt_local_entry->common.flags |= TT_CLIENT_NEW; hash_added = hash_add(bat_priv->tt_local_hash, compare_tt, choose_orig, @@ -437,7 +436,8 @@ static void tt_local_set_pending(struct bat_priv *bat_priv, /* The local client has to be marked as "pending to be removed" but has * to be kept in the table in order to send it in a full table - * response issued before the net ttvn increment (consistency check) */ + * response issued before the net ttvn increment (consistency check) + */ tt_local_entry->common.flags |= TT_CLIENT_PENDING; bat_dbg(DBG_TT, bat_priv, @@ -898,8 +898,8 @@ static void tt_global_del(struct bat_priv *bat_priv, * If there are other originators left, we directly delete * the originator. * 2) the client roamed to us => we can directly delete - * the global entry, since it is useless now. */ - + * the global entry, since it is useless now. + */ tt_local_entry = tt_local_hash_find(bat_priv, tt_global_entry->common.addr); if (tt_local_entry) { @@ -1072,7 +1072,8 @@ struct orig_node *batadv_transtable_search(struct bat_priv *bat_priv, goto out; /* check whether the clients should not communicate due to AP - * isolation */ + * isolation + */ if (tt_local_entry && _is_ap_isolated(tt_local_entry, tt_global_entry)) goto out; @@ -1171,7 +1172,8 @@ static uint16_t batadv_tt_local_crc(struct bat_priv *bat_priv) hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) { /* not yet committed clients have not to be taken into - * account while computing the CRC */ + * account while computing the CRC + */ if (tt_common_entry->flags & TT_CLIENT_NEW) continue; total_one = 0; @@ -1208,7 +1210,8 @@ static void tt_save_orig_buffer(struct bat_priv *bat_priv, uint16_t tt_buff_len = batadv_tt_len(tt_num_changes); /* Replace the old buffer only if I received something in the - * last OGM (the OGM could carry no changes) */ + * last OGM (the OGM could carry no changes) + */ spin_lock_bh(&orig_node->tt_buff_lock); if (tt_buff_len > 0) { kfree(orig_node->tt_buff); @@ -1237,7 +1240,8 @@ static void tt_req_purge(struct bat_priv *bat_priv) } /* returns the pointer to the new tt_req_node struct if no request - * has already been issued for this orig_node, NULL otherwise */ + * has already been issued for this orig_node, NULL otherwise + */ static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv, struct orig_node *orig_node) { @@ -1347,7 +1351,8 @@ static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, rcu_read_unlock(); /* store in the message the number of entries we have successfully - * copied */ + * copied + */ tt_response->tt_data = htons(tt_count); out: @@ -1370,7 +1375,8 @@ static int send_tt_request(struct bat_priv *bat_priv, goto out; /* The new tt_req will be issued only if I'm not waiting for a - * reply from the same orig_node yet */ + * reply from the same orig_node yet + */ tt_req_node = new_tt_req_node(bat_priv, dst_orig_node); if (!tt_req_node) goto out; @@ -1478,7 +1484,8 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, full_table = false; /* In this version, fragmentation is not implemented, then - * I'll send only one packet with as much TT entries as I can */ + * I'll send only one packet with as much TT entries as I can + */ if (!full_table) { spin_lock_bh(&req_dst_orig_node->tt_buff_lock); tt_len = req_dst_orig_node->tt_buff_len; @@ -1590,7 +1597,8 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, goto out; /* If the full table has been explicitly requested or the gap - * is too big send the whole local translation table */ + * is too big send the whole local translation table + */ if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn || !bat_priv->tt_buff) full_table = true; @@ -1598,7 +1606,8 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, full_table = false; /* In this version, fragmentation is not implemented, then - * I'll send only one packet with as much TT entries as I can */ + * I'll send only one packet with as much TT entries as I can + */ if (!full_table) { spin_lock_bh(&bat_priv->tt_buff_lock); tt_len = bat_priv->tt_buff_len; @@ -1766,7 +1775,8 @@ bool batadv_is_my_client(struct bat_priv *bat_priv, const uint8_t *addr) if (!tt_local_entry) goto out; /* Check if the client has been logically deleted (but is kept for - * consistency purpose) */ + * consistency purpose) + */ if (tt_local_entry->common.flags & TT_CLIENT_PENDING) goto out; ret = true; @@ -1817,7 +1827,8 @@ void batadv_handle_tt_response(struct bat_priv *bat_priv, /* Recalculate the CRC for this orig_node and store it */ orig_node->tt_crc = tt_global_crc(bat_priv, orig_node); /* Roaming phase is over: tables are in sync again. I can - * unset the flag */ + * unset the flag + */ orig_node->tt_poss_change = false; out: if (orig_node) @@ -1874,7 +1885,8 @@ static void tt_roam_purge(struct bat_priv *bat_priv) * maximum number of possible roaming phases. In this case the ROAMING_ADV * will not be sent. * - * returns true if the ROAMING_ADV can be sent, false otherwise */ + * returns true if the ROAMING_ADV can be sent, false otherwise + */ static bool tt_check_roam_count(struct bat_priv *bat_priv, uint8_t *client) { @@ -1883,7 +1895,8 @@ static bool tt_check_roam_count(struct bat_priv *bat_priv, spin_lock_bh(&bat_priv->tt_roam_list_lock); /* The new tt_req will be issued only if I'm not waiting for a - * reply from the same orig_node yet */ + * reply from the same orig_node yet + */ list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { if (!compare_eth(tt_roam_node->addr, client)) continue; @@ -1926,7 +1939,8 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, struct hard_iface *primary_if; /* before going on we have to check whether the client has - * already roamed to us too many times */ + * already roamed to us too many times + */ if (!tt_check_roam_count(bat_priv, client)) goto out; @@ -2000,7 +2014,8 @@ void batadv_tt_free(struct bat_priv *bat_priv) } /* This function will enable or disable the specified flags for all the entries - * in the given hash table and returns the number of modified entries */ + * in the given hash table and returns the number of modified entries + */ static uint16_t tt_set_flags(struct hashtable_t *hash, uint16_t flags, bool enable) { @@ -2172,12 +2187,14 @@ void batadv_tt_update_orig(struct bat_priv *bat_priv, return; /* orig table not initialised AND first diff is in the OGM OR the ttvn - * increased by one -> we can apply the attached changes */ + * increased by one -> we can apply the attached changes + */ if ((!orig_node->tt_initialised && ttvn == 1) || ttvn - orig_ttvn == 1) { /* the OGM could not contain the changes due to their size or * because they have already been sent TT_OGM_APPEND_MAX times. - * In this case send a tt request */ + * In this case send a tt request + */ if (!tt_num_changes) { full_table = false; goto request_table; @@ -2188,7 +2205,8 @@ void batadv_tt_update_orig(struct bat_priv *bat_priv, /* Even if we received the precomputed crc with the OGM, we * prefer to recompute it to spot any possible inconsistency - * in the global table */ + * in the global table + */ orig_node->tt_crc = tt_global_crc(bat_priv, orig_node); /* The ttvn alone is not enough to guarantee consistency @@ -2198,17 +2216,19 @@ void batadv_tt_update_orig(struct bat_priv *bat_priv, * consistent or not. E.g. a node could disconnect while its * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case * checking the CRC value is mandatory to detect the - * inconsistency */ + * inconsistency + */ if (orig_node->tt_crc != tt_crc) goto request_table; /* Roaming phase is over: tables are in sync again. I can - * unset the flag */ + * unset the flag + */ orig_node->tt_poss_change = false; } else { /* if we missed more than one change or our tables are not - * in sync anymore -> request fresh tt data */ - + * in sync anymore -> request fresh tt data + */ if (!orig_node->tt_initialised || ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) { request_table: diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index fe1281a71685..7edc9dff8ba1 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich, Antonio Quartulli * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index bf71d525445a..053c5d4776ce 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * @@ -16,11 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ - - #ifndef _NET_BATMAN_ADV_TYPES_H_ #define _NET_BATMAN_ADV_TYPES_H_ @@ -49,8 +45,7 @@ struct hard_iface { struct rcu_head rcu; }; -/** - * orig_node - structure for orig_list maintaining nodes of mesh +/* orig_node - structure for orig_list maintaining nodes of mesh * @primary_addr: hosts primary interface address * @last_seen: when last packet from this node was received * @bcast_seqno_reset: time when the broadcast seqno window was reset @@ -86,7 +81,8 @@ struct orig_node { * If true, then I sent a Roaming_adv to this orig_node and I have to * inspect every packet directed to it to check whether it is still * the true destination or not. This flag will be reset to false as - * soon as I receive a new TTVN from this orig_node */ + * soon as I receive a new TTVN from this orig_node + */ bool tt_poss_change; uint32_t last_real_seqno; uint8_t last_ttl; @@ -101,7 +97,8 @@ struct orig_node { struct bat_priv *bat_priv; unsigned long last_frag_packet; /* ogm_cnt_lock protects: bcast_own, bcast_own_sum, - * neigh_node->real_bits, neigh_node->real_packet_count */ + * neigh_node->real_bits, neigh_node->real_packet_count + */ spinlock_t ogm_cnt_lock; /* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */ spinlock_t bcast_seqno_lock; @@ -118,8 +115,7 @@ struct gw_node { struct rcu_head rcu; }; -/** - * neigh_node +/* neigh_node * @last_seen: when last packet via this neighbor was received */ struct neigh_node { @@ -191,7 +187,8 @@ struct bat_priv { * If true, then I received a Roaming_adv and I have to inspect every * packet directed to me to check whether I am still the true * destination or not. This flag will be reset to false as soon as I - * increase my TTVN */ + * increase my TTVN + */ bool tt_poss_change; char num_ifaces; struct debug_log *debug_log; @@ -326,8 +323,7 @@ struct tt_roam_node { struct list_head list; }; -/** - * forw_packet - structure for forw_list maintaining packets to be +/* forw_packet - structure for forw_list maintaining packets to be * send/forwarded */ struct forw_packet { @@ -369,7 +365,8 @@ struct frag_packet_list_entry { struct vis_info { unsigned long first_seen; /* list of server-neighbors we received a vis-packet - * from. we should not reply to them. */ + * from. we should not reply to them. + */ struct list_head recv_list; struct list_head send_list; struct kref refcount; @@ -377,7 +374,7 @@ struct vis_info { struct bat_priv *bat_priv; /* this packet might be part of the vis send queue. */ struct sk_buff *skb_packet; - /* vis_info may follow here*/ + /* vis_info may follow here */ } __packed; struct vis_info_entry { diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index e9d3bdd4e3d6..b2b76df69607 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Andreas Langer * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -300,12 +298,12 @@ int batadv_unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) } /* check for tt host - increases orig_node refcount. - * returns NULL in case of AP isolation */ + * returns NULL in case of AP isolation + */ orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source, ethhdr->h_dest); find_router: - /** - * find_router(): + /* find_router(): * - if orig_node is NULL it returns NULL * - increases neigh_nodes refcount if found. */ diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h index 657fe7392b14..87f8f89d1440 100644 --- a/net/batman-adv/unicast.h +++ b/net/batman-adv/unicast.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Andreas Langer * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_UNICAST_H_ diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 83c931fa5c21..20eef04645bd 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2008-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -64,8 +62,9 @@ static int vis_info_cmp(const struct hlist_node *node, const void *data2) return compare_eth(p1->vis_orig, p2->vis_orig); } -/* hash function to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ +/* hash function to choose an entry in a hash table of given size + * hash algorithm from http://en.wikipedia.org/wiki/Hash_table + */ static uint32_t vis_info_choose(const void *data, uint32_t size) { const struct vis_info *vis_info = data; @@ -118,7 +117,8 @@ static struct vis_info *vis_hash_find(struct bat_priv *bat_priv, } /* insert interface to the list of interfaces of one originator, if it - * does not already exist in the list */ + * does not already exist in the list + */ static void vis_data_insert_interface(const uint8_t *interface, struct hlist_head *if_list, bool primary) @@ -334,7 +334,8 @@ out: } /* add the info packet to the send list, if it was not - * already linked in. */ + * already linked in. + */ static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) { if (list_empty(&info->send_list)) { @@ -344,7 +345,8 @@ static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) } /* delete the info packet from the send list, if it was - * linked in. */ + * linked in. + */ static void send_list_del(struct vis_info *info) { if (!list_empty(&info->send_list)) { @@ -388,7 +390,8 @@ static int recv_list_is_in(struct bat_priv *bat_priv, /* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old, * broken.. ). vis hash must be locked outside. is_new is set when the packet - * is newer than old entries in the hash. */ + * is newer than old entries in the hash. + */ static struct vis_info *add_packet(struct bat_priv *bat_priv, struct vis_packet *vis_packet, int vis_info_len, int *is_new, @@ -500,7 +503,8 @@ void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, goto end; /* only if we are server ourselves and packet is newer than the one in - * hash.*/ + * hash. + */ if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) send_list_add(bat_priv, info); end: @@ -554,7 +558,8 @@ end: /* Walk the originators and find the VIS server with the best tq. Set the packet * address to its address and return the best_tq. * - * Must be called with the originator hash locked */ + * Must be called with the originator hash locked + */ static int find_best_vis_server(struct bat_priv *bat_priv, struct vis_info *info) { @@ -605,7 +610,8 @@ static bool vis_packet_full(const struct vis_info *info) } /* generates a packet of own vis data, - * returns 0 on success, -1 if no packet could be generated */ + * returns 0 on success, -1 if no packet could be generated + */ static int generate_vis_packet(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; @@ -703,7 +709,8 @@ unlock: } /* free old vis packets. Must be called with this vis_hash_lock - * held */ + * held + */ static void purge_vis_packets(struct bat_priv *bat_priv) { uint32_t i; @@ -762,7 +769,8 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, continue; /* don't send it if we already received the packet from - * this node. */ + * this node. + */ if (recv_list_is_in(bat_priv, &info->recv_list, orig_node->orig)) { batadv_neigh_node_free_ref(router); @@ -879,7 +887,8 @@ static void send_vis_packets(struct work_struct *work) } /* init the vis server. this may only be called when if_list is already - * initialized (e.g. bat0 is initialized, interfaces have been added) */ + * initialized (e.g. bat0 is initialized, interfaces have been added) + */ int batadv_vis_init(struct bat_priv *bat_priv) { struct vis_packet *packet; diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h index 932514e4b7d7..dad595870f8f 100644 --- a/net/batman-adv/vis.h +++ b/net/batman-adv/vis.h @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2008-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * @@ -16,14 +15,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #ifndef _NET_BATMAN_ADV_VIS_H_ #define _NET_BATMAN_ADV_VIS_H_ -#define VIS_TIMEOUT 200000 /* timeout of vis packets - * in miliseconds */ +/* timeout of vis packets in miliseconds */ +#define VIS_TIMEOUT 200000 int batadv_vis_seq_print_text(struct seq_file *seq, void *offset); void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, -- GitLab From 1aa2d1daf067c8c9e625449e2e6f54caa3e34023 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 20 Jun 2012 06:04:26 +0000 Subject: [PATCH 2289/6849] can: c_can_pci: fix compilation on non HAVE_CLK archs In commit: 5b92da0 c_can_pci: generic module for C_CAN/D_CAN on PCI the c_can_pci driver has been added. It uses clk_*() functions resulting in a link error on archs without clock support. This patch removed these clk_() functions as these parts of the driver are not tested. Cc: Federico Vaga Signed-off-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/c_can/c_can_pci.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index 914aecfa09a9..1011146ea513 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -30,7 +29,7 @@ struct c_can_pci_data { enum c_can_dev_id type; /* Set the register alignment in the memory */ enum c_can_pci_reg_align reg_align; - /* Set the frequency if clk is not usable */ + /* Set the frequency */ unsigned int freq; }; @@ -71,7 +70,6 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, struct c_can_priv *priv; struct net_device *dev; void __iomem *addr; - struct clk *clk; int ret; ret = pci_enable_device(pdev); @@ -113,18 +111,11 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, priv->base = addr; if (!c_can_pci_data->freq) { - /* get the appropriate clk */ - clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "no clock defined\n"); - ret = -ENODEV; - goto out_free_c_can; - } - priv->can.clock.freq = clk_get_rate(clk); - priv->priv = clk; + dev_err(&pdev->dev, "no clock frequency defined\n"); + ret = -ENODEV; + goto out_free_c_can; } else { priv->can.clock.freq = c_can_pci_data->freq; - priv->priv = NULL; } /* Configure CAN type */ @@ -138,7 +129,7 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, break; default: ret = -EINVAL; - goto out_free_clock; + goto out_free_c_can; } /* Configure access to registers */ @@ -153,14 +144,14 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, break; default: ret = -EINVAL; - goto out_free_clock; + goto out_free_c_can; } ret = register_c_can_dev(dev); if (ret) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", KBUILD_MODNAME, ret); - goto out_free_clock; + goto out_free_c_can; } dev_dbg(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", @@ -168,9 +159,6 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, return 0; -out_free_clock: - if (priv->priv) - clk_put(priv->priv); out_free_c_can: pci_set_drvdata(pdev, NULL); free_c_can_dev(dev); @@ -193,9 +181,6 @@ static void __devexit c_can_pci_remove(struct pci_dev *pdev) unregister_c_can_dev(dev); - if (priv->priv) - clk_put(priv->priv); - pci_set_drvdata(pdev, NULL); free_c_can_dev(dev); -- GitLab From b443a2307d3ade1520daa15d79ef97ad00641504 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jun 2012 05:32:00 +0000 Subject: [PATCH 2290/6849] team: use rcu_access_pointer to access RCU pointer by writer Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_activebackup.c | 7 +++++-- drivers/net/team/team_mode_loadbalance.c | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c index 2fe02a8713ea..c9e7621b4480 100644 --- a/drivers/net/team/team_mode_activebackup.c +++ b/drivers/net/team/team_mode_activebackup.c @@ -61,8 +61,11 @@ static void ab_port_leave(struct team *team, struct team_port *port) static int ab_active_port_get(struct team *team, struct team_gsetter_ctx *ctx) { - if (ab_priv(team)->active_port) - ctx->data.u32_val = ab_priv(team)->active_port->dev->ifindex; + struct team_port *active_port; + + active_port = rcu_access_pointer(ab_priv(team)->active_port); + if (active_port) + ctx->data.u32_val = active_port->dev->ifindex; else ctx->data.u32_val = 0; return 0; diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index 45cc0951aa48..b4475a5d2d4b 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -96,7 +96,7 @@ static void lb_tx_hash_to_port_mapping_null_port(struct team *team, struct lb_port_mapping *pm; pm = &lb_priv->ex->tx_hash_to_port_mapping[i]; - if (pm->port == port) { + if (rcu_access_pointer(pm->port) == port) { rcu_assign_pointer(pm->port, NULL); team_option_inst_set_change(pm->opt_inst_info); changed = true; @@ -292,7 +292,7 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) if (lb_priv->ex->orig_fprog) { /* Clear old filter data */ __fprog_destroy(lb_priv->ex->orig_fprog); - sk_unattached_filter_destroy(lb_priv->fp); + sk_unattached_filter_destroy(rcu_access_pointer(lb_priv->fp)); } rcu_assign_pointer(lb_priv->fp, fp); @@ -303,9 +303,11 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) static int lb_tx_method_get(struct team *team, struct team_gsetter_ctx *ctx) { struct lb_priv *lb_priv = get_lb_priv(team); + lb_select_tx_port_func_t *func; char *name; - name = lb_select_tx_port_get_name(lb_priv->select_tx_port_func); + func = rcu_access_pointer(lb_priv->select_tx_port_func); + name = lb_select_tx_port_get_name(func); BUG_ON(!name); ctx->data.str_val = name; return 0; -- GitLab From d8dbd96e507e1f1133d346be123e7be4b16b72c3 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jun 2012 05:32:01 +0000 Subject: [PATCH 2291/6849] team: use RCU_INIT_POINTER for NULL assignment of RCU pointer Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_loadbalance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index b4475a5d2d4b..c385b45cad18 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -97,7 +97,7 @@ static void lb_tx_hash_to_port_mapping_null_port(struct team *team, pm = &lb_priv->ex->tx_hash_to_port_mapping[i]; if (rcu_access_pointer(pm->port) == port) { - rcu_assign_pointer(pm->port, NULL); + RCU_INIT_POINTER(pm->port, NULL); team_option_inst_set_change(pm->opt_inst_info); changed = true; } -- GitLab From f643776e4d1906ceff59f18315d6aba8e85db343 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 20 Jun 2012 14:28:58 -0700 Subject: [PATCH 2292/6849] team: Revert previous two changes. I didn't notice that these were superceded by a more uptodate version of the changes. Signed-off-by: David S. Miller --- drivers/net/team/team_mode_activebackup.c | 7 ++----- drivers/net/team/team_mode_loadbalance.c | 10 ++++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c index c9e7621b4480..2fe02a8713ea 100644 --- a/drivers/net/team/team_mode_activebackup.c +++ b/drivers/net/team/team_mode_activebackup.c @@ -61,11 +61,8 @@ static void ab_port_leave(struct team *team, struct team_port *port) static int ab_active_port_get(struct team *team, struct team_gsetter_ctx *ctx) { - struct team_port *active_port; - - active_port = rcu_access_pointer(ab_priv(team)->active_port); - if (active_port) - ctx->data.u32_val = active_port->dev->ifindex; + if (ab_priv(team)->active_port) + ctx->data.u32_val = ab_priv(team)->active_port->dev->ifindex; else ctx->data.u32_val = 0; return 0; diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index c385b45cad18..45cc0951aa48 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -96,8 +96,8 @@ static void lb_tx_hash_to_port_mapping_null_port(struct team *team, struct lb_port_mapping *pm; pm = &lb_priv->ex->tx_hash_to_port_mapping[i]; - if (rcu_access_pointer(pm->port) == port) { - RCU_INIT_POINTER(pm->port, NULL); + if (pm->port == port) { + rcu_assign_pointer(pm->port, NULL); team_option_inst_set_change(pm->opt_inst_info); changed = true; } @@ -292,7 +292,7 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) if (lb_priv->ex->orig_fprog) { /* Clear old filter data */ __fprog_destroy(lb_priv->ex->orig_fprog); - sk_unattached_filter_destroy(rcu_access_pointer(lb_priv->fp)); + sk_unattached_filter_destroy(lb_priv->fp); } rcu_assign_pointer(lb_priv->fp, fp); @@ -303,11 +303,9 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) static int lb_tx_method_get(struct team *team, struct team_gsetter_ctx *ctx) { struct lb_priv *lb_priv = get_lb_priv(team); - lb_select_tx_port_func_t *func; char *name; - func = rcu_access_pointer(lb_priv->select_tx_port_func); - name = lb_select_tx_port_get_name(func); + name = lb_select_tx_port_get_name(lb_priv->select_tx_port_func); BUG_ON(!name); ctx->data.str_val = name; return 0; -- GitLab From 6dab015cf8c9d2fabb13d0332998bc440e9c6555 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jun 2012 08:39:39 +0000 Subject: [PATCH 2293/6849] team: do RCU update path fixups Use rcu_access_pointer and rcu_dereference_protected to access RCU pointer by updater. Use RCU_INIT_POINTER for NULL assignment of RCU pointer. Signed-off-by: Jiri Pirko Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/team/team_mode_activebackup.c | 8 ++++++-- drivers/net/team/team_mode_loadbalance.c | 14 ++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c index 2fe02a8713ea..253b8a5f3427 100644 --- a/drivers/net/team/team_mode_activebackup.c +++ b/drivers/net/team/team_mode_activebackup.c @@ -61,8 +61,12 @@ static void ab_port_leave(struct team *team, struct team_port *port) static int ab_active_port_get(struct team *team, struct team_gsetter_ctx *ctx) { - if (ab_priv(team)->active_port) - ctx->data.u32_val = ab_priv(team)->active_port->dev->ifindex; + struct team_port *active_port; + + active_port = rcu_dereference_protected(ab_priv(team)->active_port, + lockdep_is_held(&team->lock)); + if (active_port) + ctx->data.u32_val = active_port->dev->ifindex; else ctx->data.u32_val = 0; return 0; diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index 45cc0951aa48..c92fa02d6a63 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -96,8 +96,8 @@ static void lb_tx_hash_to_port_mapping_null_port(struct team *team, struct lb_port_mapping *pm; pm = &lb_priv->ex->tx_hash_to_port_mapping[i]; - if (pm->port == port) { - rcu_assign_pointer(pm->port, NULL); + if (rcu_access_pointer(pm->port) == port) { + RCU_INIT_POINTER(pm->port, NULL); team_option_inst_set_change(pm->opt_inst_info); changed = true; } @@ -274,6 +274,7 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) { struct lb_priv *lb_priv = get_lb_priv(team); struct sk_filter *fp = NULL; + struct sk_filter *orig_fp; struct sock_fprog *fprog = NULL; int err; @@ -292,7 +293,9 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) if (lb_priv->ex->orig_fprog) { /* Clear old filter data */ __fprog_destroy(lb_priv->ex->orig_fprog); - sk_unattached_filter_destroy(lb_priv->fp); + orig_fp = rcu_dereference_protected(lb_priv->fp, + lockdep_is_held(&team->lock)); + sk_unattached_filter_destroy(orig_fp); } rcu_assign_pointer(lb_priv->fp, fp); @@ -303,9 +306,12 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx) static int lb_tx_method_get(struct team *team, struct team_gsetter_ctx *ctx) { struct lb_priv *lb_priv = get_lb_priv(team); + lb_select_tx_port_func_t *func; char *name; - name = lb_select_tx_port_get_name(lb_priv->select_tx_port_func); + func = rcu_dereference_protected(lb_priv->select_tx_port_func, + lockdep_is_held(&team->lock)); + name = lb_select_tx_port_get_name(func); BUG_ON(!name); ctx->data.str_val = name; return 0; -- GitLab From da55737467c1c3bc02271039c088171d82e0796f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Jun 2012 04:02:10 +0000 Subject: [PATCH 2294/6849] inetpeer: inetpeer_invalidate_tree() cleanup No need to use cmpxchg() in inetpeer_invalidate_tree() since we hold base lock. Also use correct rcu annotations to remove sparse errors (CONFIG_SPARSE_RCU_POINTER=y) net/ipv4/inetpeer.c:144:19: error: incompatible types in comparison expression (different address spaces) net/ipv4/inetpeer.c:149:20: error: incompatible types in comparison expression (different address spaces) net/ipv4/inetpeer.c:595:10: error: incompatible types in comparison expression (different address spaces) Signed-off-by: Eric Dumazet Cc: Steffen Klassert Signed-off-by: David S. Miller --- net/ipv4/inetpeer.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index cac02ad1425d..da90a8cab614 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -126,7 +126,7 @@ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min static void inetpeer_gc_worker(struct work_struct *work) { - struct inet_peer *p, *n; + struct inet_peer *p, *n, *c; LIST_HEAD(list); spin_lock_bh(&gc_lock); @@ -138,17 +138,19 @@ static void inetpeer_gc_worker(struct work_struct *work) list_for_each_entry_safe(p, n, &list, gc_list) { - if(need_resched()) + if (need_resched()) cond_resched(); - if (p->avl_left != peer_avl_empty) { - list_add_tail(&p->avl_left->gc_list, &list); - p->avl_left = peer_avl_empty; + c = rcu_dereference_protected(p->avl_left, 1); + if (c != peer_avl_empty) { + list_add_tail(&c->gc_list, &list); + p->avl_left = peer_avl_empty_rcu; } - if (p->avl_right != peer_avl_empty) { - list_add_tail(&p->avl_right->gc_list, &list); - p->avl_right = peer_avl_empty; + c = rcu_dereference_protected(p->avl_right, 1); + if (c != peer_avl_empty) { + list_add_tail(&c->gc_list, &list); + p->avl_right = peer_avl_empty_rcu; } n = list_entry(p->gc_list.next, struct inet_peer, gc_list); @@ -587,23 +589,17 @@ static void inetpeer_inval_rcu(struct rcu_head *head) void inetpeer_invalidate_tree(struct inet_peer_base *base) { - struct inet_peer *old, *new, *prev; + struct inet_peer *root; write_seqlock_bh(&base->lock); - old = base->root; - if (old == peer_avl_empty_rcu) - goto out; - - new = peer_avl_empty_rcu; - - prev = cmpxchg(&base->root, old, new); - if (prev == old) { + root = rcu_deref_locked(base->root, base); + if (root != peer_avl_empty) { + base->root = peer_avl_empty_rcu; base->total = 0; - call_rcu(&prev->gc_rcu, inetpeer_inval_rcu); + call_rcu(&root->gc_rcu, inetpeer_inval_rcu); } -out: write_sequnlock_bh(&base->lock); } EXPORT_SYMBOL(inetpeer_invalidate_tree); -- GitLab From abca7c4965845924f65d40e0aa1092bdd895e314 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Wed, 20 Jun 2012 12:52:56 -0700 Subject: [PATCH 2295/6849] mm: fix slab->page _count corruption when using slub On arches that do not support this_cpu_cmpxchg_double() slab_lock is used to do atomic cmpxchg() on double word which contains page->_count. The page count can be changed from get_page() or put_page() without taking slab_lock. That corrupts page counter. Fix it by moving page->_count out of cmpxchg_double data. So that slub does no change it while updating slub meta-data in struct page. [akpm@linux-foundation.org: use standard comment layout, tweak comment text] Reported-by: Amey Bhide Signed-off-by: Pravin B Shelar Acked-by: Christoph Lameter Cc: Pekka Enberg Cc: Andrea Arcangeli Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_types.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index dad95bdd06d7..704a626d94a0 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -57,8 +57,18 @@ struct page { }; union { +#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) && \ + defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE) /* Used for cmpxchg_double in slub */ unsigned long counters; +#else + /* + * Keep _count separate from slub cmpxchg_double data. + * As the rest of the double word is protected by + * slab_lock but _count is not. + */ + unsigned counters; +#endif struct { -- GitLab From e4eed03fd06578571c01d4f1478c874bb432c815 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Wed, 20 Jun 2012 12:52:57 -0700 Subject: [PATCH 2296/6849] thp: avoid atomic64_read in pmd_read_atomic for 32bit PAE In the x86 32bit PAE CONFIG_TRANSPARENT_HUGEPAGE=y case while holding the mmap_sem for reading, cmpxchg8b cannot be used to read pmd contents under Xen. So instead of dealing only with "consistent" pmdvals in pmd_none_or_trans_huge_or_clear_bad() (which would be conceptually simpler) we let pmd_none_or_trans_huge_or_clear_bad() deal with pmdvals where the low 32bit and high 32bit could be inconsistent (to avoid having to use cmpxchg8b). The only guarantee we get from pmd_read_atomic is that if the low part of the pmd was found null, the high part will be null too (so the pmd will be considered unstable). And if the low part of the pmd is found "stable" later, then it means the whole pmd was read atomically (because after a pmd is stable, neither MADV_DONTNEED nor page faults can alter it anymore, and we read the high part after the low part). In the 32bit PAE x86 case, it is enough to read the low part of the pmdval atomically to declare the pmd as "stable" and that's true for THP and no THP, furthermore in the THP case we also have a barrier() that will prevent any inconsistent pmdvals to be cached by a later re-read of the *pmd. Signed-off-by: Andrea Arcangeli Cc: Jonathan Nieder Cc: Ulrich Obergfell Cc: Mel Gorman Cc: Hugh Dickins Cc: Larry Woodman Cc: Petr Matousek Cc: Rik van Riel Cc: Jan Beulich Cc: KOSAKI Motohiro Tested-by: Andrew Jones Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/include/asm/pgtable-3level.h | 30 +++++++++++++++------------ include/asm-generic/pgtable.h | 10 +++++++++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 43876f16caf1..cb00ccc7d571 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h @@ -47,16 +47,26 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd * operations. * - * Without THP if the mmap_sem is hold for reading, the - * pmd can only transition from null to not null while pmd_read_atomic runs. - * So there's no need of literally reading it atomically. + * Without THP if the mmap_sem is hold for reading, the pmd can only + * transition from null to not null while pmd_read_atomic runs. So + * we can always return atomic pmd values with this function. * * With THP if the mmap_sem is hold for reading, the pmd can become - * THP or null or point to a pte (and in turn become "stable") at any - * time under pmd_read_atomic, so it's mandatory to read it atomically - * with cmpxchg8b. + * trans_huge or none or point to a pte (and in turn become "stable") + * at any time under pmd_read_atomic. We could read it really + * atomically here with a atomic64_read for the THP enabled case (and + * it would be a whole lot simpler), but to avoid using cmpxchg8b we + * only return an atomic pmdval if the low part of the pmdval is later + * found stable (i.e. pointing to a pte). And we're returning a none + * pmdval if the low part of the pmd is none. In some cases the high + * and low part of the pmdval returned may not be consistent if THP is + * enabled (the low part may point to previously mapped hugepage, + * while the high part may point to a more recently mapped hugepage), + * but pmd_none_or_trans_huge_or_clear_bad() only needs the low part + * of the pmd to be read atomically to decide if the pmd is unstable + * or not, with the only exception of when the low part of the pmd is + * zero in which case we return a none pmd. */ -#ifndef CONFIG_TRANSPARENT_HUGEPAGE static inline pmd_t pmd_read_atomic(pmd_t *pmdp) { pmdval_t ret; @@ -74,12 +84,6 @@ static inline pmd_t pmd_read_atomic(pmd_t *pmdp) return (pmd_t) { ret }; } -#else /* CONFIG_TRANSPARENT_HUGEPAGE */ -static inline pmd_t pmd_read_atomic(pmd_t *pmdp) -{ - return (pmd_t) { atomic64_read((atomic64_t *)pmdp) }; -} -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) { diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 6f2b45a9b6bc..ff4947b7a976 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -484,6 +484,16 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd) /* * The barrier will stabilize the pmdval in a register or on * the stack so that it will stop changing under the code. + * + * When CONFIG_TRANSPARENT_HUGEPAGE=y on x86 32bit PAE, + * pmd_read_atomic is allowed to return a not atomic pmdval + * (for example pointing to an hugepage that has never been + * mapped in the pmd). The below checks will only care about + * the low part of the pmd with 32bit PAE x86 anyway, with the + * exception of pmd_none(). So the important thing is that if + * the low part of the pmd is found null, the high part will + * be also null or the pmd_none() check below would be + * confused. */ #ifdef CONFIG_TRANSPARENT_HUGEPAGE barrier(); -- GitLab From fbb24a3a915f105016f1c828476be11aceac8504 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Wed, 20 Jun 2012 12:52:57 -0700 Subject: [PATCH 2297/6849] nilfs2: ensure proper cache clearing for gc-inodes A gc-inode is a pseudo inode used to buffer the blocks to be moved by garbage collection. Block caches of gc-inodes must be cleared every time a garbage collection function (nilfs_clean_segments) completes. Otherwise, stale blocks buffered in the caches may be wrongly reused in successive calls of the GC function. For user files, this is not a problem because their gc-inodes are distinguished by a checkpoint number as well as an inode number. They never buffer different blocks if either an inode number, a checkpoint number, or a block offset differs. However, gc-inodes of sufile, cpfile and DAT file can store different data for the same block offset. Thus, the nilfs_clean_segments function can move incorrect block for these meta-data files if an old block is cached. I found this is really causing meta-data corruption in nilfs. This fixes the issue by ensuring cache clear of gc-inodes and resolves reported GC problems including checkpoint file corruption, b-tree corruption, and the following warning during GC. nilfs_palloc_freev: entry number 307234 already freed. ... Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi Cc: [2.6.37+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/nilfs2/gcinode.c | 2 ++ fs/nilfs2/segment.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index 08a07a218d26..57ceaf33d177 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c @@ -191,6 +191,8 @@ void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs) while (!list_empty(head)) { ii = list_first_entry(head, struct nilfs_inode_info, i_dirty); list_del_init(&ii->i_dirty); + truncate_inode_pages(&ii->vfs_inode.i_data, 0); + nilfs_btnode_cache_clear(&ii->i_btnode_cache); iput(&ii->vfs_inode); } } diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 0e72ad6f22aa..88e11fb346b6 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2309,6 +2309,8 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head) if (!test_bit(NILFS_I_UPDATED, &ii->i_state)) continue; list_del_init(&ii->i_dirty); + truncate_inode_pages(&ii->vfs_inode.i_data, 0); + nilfs_btnode_cache_clear(&ii->i_btnode_cache); iput(&ii->vfs_inode); } } -- GitLab From 61eafb00d55dfbccdfce543c6b60e369ff4f8f18 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 20 Jun 2012 12:52:58 -0700 Subject: [PATCH 2298/6849] mm, oom: fix and cleanup oom score calculations The divide in p->signal->oom_score_adj * totalpages / 1000 within oom_badness() was causing an overflow of the signed long data type. This adds both the root bias and p->signal->oom_score_adj before doing the normalization which fixes the issue and also cleans up the calculation. Tested-by: Dave Jones Signed-off-by: David Rientjes Cc: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/oom_kill.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 416637f0e924..77775138e930 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -184,6 +184,7 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, const nodemask_t *nodemask, unsigned long totalpages) { long points; + long adj; if (oom_unkillable_task(p, memcg, nodemask)) return 0; @@ -192,7 +193,8 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, if (!p) return 0; - if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) { + adj = p->signal->oom_score_adj; + if (adj == OOM_SCORE_ADJ_MIN) { task_unlock(p); return 0; } @@ -210,14 +212,11 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, * implementation used by LSMs. */ if (has_capability_noaudit(p, CAP_SYS_ADMIN)) - points -= 30 * totalpages / 1000; + adj -= 30; - /* - * /proc/pid/oom_score_adj ranges from -1000 to +1000 such that it may - * either completely disable oom killing or always prefer a certain - * task. - */ - points += p->signal->oom_score_adj * totalpages / 1000; + /* Normalize to oom_score_adj units */ + adj *= totalpages / 1000; + points += adj; /* * Never return 0 for an eligible task regardless of the root bonus and -- GitLab From 3a981f482cc29f7d0aeab509e51ea15519a6e961 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 20 Jun 2012 12:52:58 -0700 Subject: [PATCH 2299/6849] memcg: fix use_hierarchy css_is_ancestor oops regression If use_hierarchy is set, reclaim testing soon oopses in css_is_ancestor() called from __mem_cgroup_same_or_subtree() called from page_referenced(): when processes are exiting, it's easy for mm_match_cgroup() to pass along a NULL memcg coming from a NULL mm->owner. Check for that in __mem_cgroup_same_or_subtree(). Return true or false? False because we cannot know if it was in the hierarchy, but also false because it's better not to count a reference from an exiting process. Signed-off-by: Hugh Dickins Acked-by: Johannes Weiner Acked-by: Konstantin Khlebnikov Acked-by: KAMEZAWA Hiroyuki Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index ac35bccadb7b..f8517cd28feb 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1148,7 +1148,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg, { if (root_memcg == memcg) return true; - if (!root_memcg->use_hierarchy) + if (!root_memcg->use_hierarchy || !memcg) return false; return css_is_ancestor(&memcg->css, &root_memcg->css); } -- GitLab From 5e7b6ed8e9bf3c8e3bb579fd0aec64f6526f8c81 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Jun 2012 12:52:58 -0700 Subject: [PATCH 2300/6849] xtensa: replace xtensa-specific _f{data,text} by _s{data,text} commit a2d063ac216c161 ("extable, core_kernel_data(): Make sure all archs define _sdata") missed xtensa. Xtensa does have a start of data marker, but calls it _fdata, causing kernel/built-in.o:(.text+0x964): undefined reference to `_sdata' _stext was already defined, but it was duplicated by _fdata. Signed-off-by: Geert Uytterhoeven Cc: Steven Rostedt Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/kernel/vmlinux.lds.S | 3 +-- arch/xtensa/mm/init.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 88ecea3facb4..ee2e2089483d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -83,7 +83,6 @@ SECTIONS _text = .; _stext = .; - _ftext = .; .text : { @@ -112,7 +111,7 @@ SECTIONS EXCEPTION_TABLE(16) /* Data section */ - _fdata = .; + _sdata = .; RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) _edata = .; diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index ba150e5de2eb..c82af58f60bc 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -29,7 +29,7 @@ /* References to section boundaries */ -extern char _ftext, _etext, _fdata, _edata, _rodata_end; +extern char _stext, _etext, _sdata, _edata, _rodata_end; extern char __init_begin, __init_end; /* @@ -197,8 +197,8 @@ void __init mem_init(void) reservedpages++; } - codesize = (unsigned long) &_etext - (unsigned long) &_ftext; - datasize = (unsigned long) &_edata - (unsigned long) &_fdata; + codesize = (unsigned long) &_etext - (unsigned long) &_stext; + datasize = (unsigned long) &_edata - (unsigned long) &_sdata; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " -- GitLab From 0eff08b5d1bf4b30f1a549a58c85806748256b18 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Jun 2012 12:52:59 -0700 Subject: [PATCH 2301/6849] xtensa: use "test -e" instead of bashism "test -a" On Ubuntu, /bin/sh is a symlink to dash, which does not support "test -a". This causes messages like test: 1: -a: unexpected operator test: 1: -a: unexpected operator and link failures like (.init.text+0x132): undefined reference to `platform_init' due to the appropriate platform code not being compiled. Signed-off-by: Geert Uytterhoeven Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 7608559de93a..f973754ddf90 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -68,8 +68,8 @@ endif # Only build variant and/or platform if it includes a Makefile -buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) -buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) +buildvar := $(shell test -e $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) +buildplf := $(shell test -e $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) # Find libgcc.a -- GitLab From f022d0fa183c4def30ddd74f2baebd72c4254fcf Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Jun 2012 12:52:59 -0700 Subject: [PATCH 2302/6849] xtensa: use the declarations provided by Cleanups: - Include , - Remove the (different) extern declarations, - Remove the no longer needed address-of ('&') operators, - Use %p to format pointer differences. Signed-off-by: Geert Uytterhoeven Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/mm/init.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index c82af58f60bc..db955179da2d 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -26,11 +26,7 @@ #include #include - -/* References to section boundaries */ - -extern char _stext, _etext, _sdata, _edata, _rodata_end; -extern char __init_begin, __init_end; +#include /* * mem_reserve(start, end, must_exist) @@ -197,9 +193,9 @@ void __init mem_init(void) reservedpages++; } - codesize = (unsigned long) &_etext - (unsigned long) &_stext; - datasize = (unsigned long) &_edata - (unsigned long) &_sdata; - initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + codesize = (unsigned long) _etext - (unsigned long) _stext; + datasize = (unsigned long) _edata - (unsigned long) _sdata; + initsize = (unsigned long) __init_end - (unsigned long) __init_begin; printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " "%ldk data, %ldk init %ldk highmem)\n", @@ -237,7 +233,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) void free_initmem(void) { - free_reserved_mem(&__init_begin, &__init_end); - printk("Freeing unused kernel memory: %dk freed\n", - (&__init_end - &__init_begin) >> 10); + free_reserved_mem(__init_begin, __init_end); + printk("Freeing unused kernel memory: %zuk freed\n", + (__init_end - __init_begin) >> 10); } -- GitLab From ffb20313c01addc04212577af5f9b1399156a5bd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Jun 2012 12:53:00 -0700 Subject: [PATCH 2303/6849] h8300: fix use of extinct _sbss and _ebss Nowadays it should use __bss_start and __bss_stop Signed-off-by: Geert Uytterhoeven Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/kernel/setup.c | 6 +++--- arch/h8300/mm/init.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 68d651081bd3..050f13665b8e 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -54,7 +54,7 @@ unsigned long memory_end; char __initdata command_line[COMMAND_LINE_SIZE]; -extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; +extern int _stext, _etext, _sdata, _edata, __bss_start, __bss_stop, _end; extern int _ramstart, _ramend; extern char _target_name[]; extern void h8300_gpio_init(void); @@ -137,10 +137,10 @@ void __init setup_arch(char **cmdline_p) printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, (int) &_sdata, (int) &_edata, - (int) &_sbss, (int) &_ebss); + (int) &__bss_start, (int) &__bss_stop); printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " "STACK=0x%06x-0x%06x\n", - (int) &_ebss, (int) memory_start, + (int) &__bss_stop, (int) memory_start, (int) memory_start, (int) memory_end, (int) memory_end, (int) &_ramend); #endif diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index 973369c32a95..ee4c9dbf58cc 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -123,7 +123,7 @@ void __init mem_init(void) int codek = 0, datak = 0, initk = 0; /* DAVIDM look at setup memory map generically with reserved area */ unsigned long tmp; - extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end; + extern char _etext, _stext, _sdata, __bss_stop, __init_begin, __init_end; extern unsigned long _ramend, _ramstart; unsigned long len = &_ramend - &_ramstart; unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */ @@ -143,7 +143,7 @@ void __init mem_init(void) totalram_pages = free_all_bootmem(); codek = (&_etext - &_stext) >> 10; - datak = (&_ebss - &_sdata) >> 10; + datak = (&__bss_stop - &_sdata) >> 10; initk = (&__init_begin - &__init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; -- GitLab From 436814e61f5c526ed123853a9bf63fb2ff4ff94b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Jun 2012 12:53:00 -0700 Subject: [PATCH 2304/6849] h8300: use the declarations provided by Cleanups: - Include , - Remove the (different) extern declarations, - Remove the no longer needed address-of ('&') operators, - Remove the superfluous casts, use proper printk formatting instead. Signed-off-by: Geert Uytterhoeven Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/kernel/setup.c | 23 ++++++++++------------- arch/h8300/mm/init.c | 17 ++++++++--------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 050f13665b8e..d0b1607f2711 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -35,6 +35,7 @@ #include #include #include +#include #if defined(__H8300H__) #define CPU "H8/300H" @@ -54,7 +55,6 @@ unsigned long memory_end; char __initdata command_line[COMMAND_LINE_SIZE]; -extern int _stext, _etext, _sdata, _edata, __bss_start, __bss_stop, _end; extern int _ramstart, _ramend; extern char _target_name[]; extern void h8300_gpio_init(void); @@ -119,9 +119,9 @@ void __init setup_arch(char **cmdline_p) memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS; #endif - init_mm.start_code = (unsigned long) &_stext; - init_mm.end_code = (unsigned long) &_etext; - init_mm.end_data = (unsigned long) &_edata; + init_mm.start_code = (unsigned long) _stext; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; init_mm.brk = (unsigned long) 0; #if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT) @@ -134,15 +134,12 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "H8/300 series support by Yoshinori Sato \n"); #ifdef DEBUG - printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " - "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, - (int) &_sdata, (int) &_edata, - (int) &__bss_start, (int) &__bss_stop); - printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " - "STACK=0x%06x-0x%06x\n", - (int) &__bss_stop, (int) memory_start, - (int) memory_start, (int) memory_end, - (int) memory_end, (int) &_ramend); + printk(KERN_DEBUG "KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p " + "BSS=0x%p-0x%p\n", _stext, _etext, _sdata, _edata, __bss_start, + __bss_stop); + printk(KERN_DEBUG "KERNEL -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx " + "STACK=0x%06lx-0x%p\n", __bss_stop, memory_start, memory_start, + memory_end, memory_end, &_ramend); #endif #ifdef CONFIG_DEFAULT_CMDLINE diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index ee4c9dbf58cc..981e25094b1a 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -36,6 +36,7 @@ #include #include #include +#include #undef DEBUG @@ -123,7 +124,6 @@ void __init mem_init(void) int codek = 0, datak = 0, initk = 0; /* DAVIDM look at setup memory map generically with reserved area */ unsigned long tmp; - extern char _etext, _stext, _sdata, __bss_stop, __init_begin, __init_end; extern unsigned long _ramend, _ramstart; unsigned long len = &_ramend - &_ramstart; unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */ @@ -142,9 +142,9 @@ void __init mem_init(void) /* this will put all memory onto the freelists */ totalram_pages = free_all_bootmem(); - codek = (&_etext - &_stext) >> 10; - datak = (&__bss_stop - &_sdata) >> 10; - initk = (&__init_begin - &__init_end) >> 10; + codek = (_etext - _stext) >> 10; + datak = (__bss_stop - _sdata) >> 10; + initk = (__init_begin - __init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n", @@ -178,22 +178,21 @@ free_initmem(void) { #ifdef CONFIG_RAMKERNEL unsigned long addr; - extern char __init_begin, __init_end; /* * the following code should be cool even if these sections * are not page aligned. */ - addr = PAGE_ALIGN((unsigned long)(&__init_begin)); + addr = PAGE_ALIGN((unsigned long)(__init_begin)); /* next to check that the page we free is not a partial page */ - for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { + for (; addr + PAGE_SIZE < (unsigned long)__init_end; addr +=PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); totalram_pages++; } printk(KERN_INFO "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", - (addr - PAGE_ALIGN((long) &__init_begin)) >> 10, - (int)(PAGE_ALIGN((unsigned long)(&__init_begin))), + (addr - PAGE_ALIGN((long) __init_begin)) >> 10, + (int)(PAGE_ALIGN((unsigned long)__init_begin)), (int)(addr - PAGE_SIZE)); #endif } -- GitLab From e0897d75f0b22e8c3a7287a48548c5686ef73447 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 20 Jun 2012 12:53:00 -0700 Subject: [PATCH 2305/6849] mm, thp: print useful information when mmap_sem is unlocked in zap_pmd_range Andrea asked for addr, end, vma->vm_start, and vma->vm_end to be emitted when !rwsem_is_locked(&tlb->mm->mmap_sem). Otherwise, debugging the underlying issue is more difficult. Suggested-by: Andrea Arcangeli Signed-off-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index 1b7dc662bf9f..8762c4f915fc 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1225,7 +1225,15 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, next = pmd_addr_end(addr, end); if (pmd_trans_huge(*pmd)) { if (next - addr != HPAGE_PMD_SIZE) { - VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem)); +#ifdef CONFIG_DEBUG_VM + if (!rwsem_is_locked(&tlb->mm->mmap_sem)) { + pr_err("%s: mmap_sem is unlocked! addr=0x%lx end=0x%lx vma->vm_start=0x%lx vma->vm_end=0x%lx\n", + __func__, addr, end, + vma->vm_start, + vma->vm_end); + BUG(); + } +#endif split_huge_page_pmd(vma->vm_mm, pmd); } else if (zap_huge_pmd(tlb, vma, pmd, addr)) goto next; -- GitLab From 4fe7efdbdfb1c7e7a7f31decfd831c0f31d37091 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Wed, 20 Jun 2012 12:53:01 -0700 Subject: [PATCH 2306/6849] mm: correctly synchronize rss-counters at exit/exec do_exit() and exec_mmap() call sync_mm_rss() before mm_release() does put_user(clear_child_tid) which can update task->rss_stat and thus make mm->rss_stat inconsistent. This triggers the "BUG:" printk in check_mm(). Let's fix this bug in the safest way, and optimize/cleanup this later. Reported-by: Markus Trippelsdorf Signed-off-by: Konstantin Khlebnikov Cc: Oleg Nesterov Cc: KAMEZAWA Hiroyuki Cc: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 2 +- kernel/exit.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/exec.c b/fs/exec.c index a79786a8d2c8..da27b91ff1e8 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -819,10 +819,10 @@ static int exec_mmap(struct mm_struct *mm) /* Notify parent that we're no longer interested in the old VM */ tsk = current; old_mm = current->mm; - sync_mm_rss(old_mm); mm_release(tsk, old_mm); if (old_mm) { + sync_mm_rss(old_mm); /* * Make sure that if there is a core dump in progress * for the old mm, we get out and die instead of going diff --git a/kernel/exit.c b/kernel/exit.c index 34867cc5b42a..c0277d3f1aaa 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -643,6 +643,7 @@ static void exit_mm(struct task_struct * tsk) mm_release(tsk, mm); if (!mm) return; + sync_mm_rss(mm); /* * Serialize with any possible pending coredump. * We must hold mmap_sem around checking core_state -- GitLab From dad7557eb705688040aac134efa5418b66d5ed92 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Wed, 20 Jun 2012 12:53:01 -0700 Subject: [PATCH 2307/6849] mm: fix kernel-doc warnings Fix kernel-doc warnings such as Warning(../mm/page_cgroup.c:432): No description found for parameter 'id' Warning(../mm/page_cgroup.c:432): Excess function parameter 'mem' description in 'swap_cgroup_record' Signed-off-by: Wanpeng Li Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memblock.c | 12 ++++++------ mm/memcontrol.c | 4 ++-- mm/oom_kill.c | 2 +- mm/page_cgroup.c | 4 ++-- mm/pagewalk.c | 1 - mm/percpu-vm.c | 1 - 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index 32a0a5e4d79d..b65b687e2362 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -540,9 +540,9 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) * __next_free_mem_range - next function for for_each_free_mem_range() * @idx: pointer to u64 loop variable * @nid: nid: node selector, %MAX_NUMNODES for all nodes - * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL - * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL - * @p_nid: ptr to int for nid of the range, can be %NULL + * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL + * @out_end: ptr to phys_addr_t for end address of the range, can be %NULL + * @out_nid: ptr to int for nid of the range, can be %NULL * * Find the first free area from *@idx which matches @nid, fill the out * parameters, and update *@idx for the next iteration. The lower 32bit of @@ -616,9 +616,9 @@ void __init_memblock __next_free_mem_range(u64 *idx, int nid, * __next_free_mem_range_rev - next function for for_each_free_mem_range_reverse() * @idx: pointer to u64 loop variable * @nid: nid: node selector, %MAX_NUMNODES for all nodes - * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL - * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL - * @p_nid: ptr to int for nid of the range, can be %NULL + * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL + * @out_end: ptr to phys_addr_t for end address of the range, can be %NULL + * @out_nid: ptr to int for nid of the range, can be %NULL * * Reverse of __next_free_mem_range(). */ diff --git a/mm/memcontrol.c b/mm/memcontrol.c index f8517cd28feb..f72b5e52451a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1234,7 +1234,7 @@ int mem_cgroup_inactive_file_is_low(struct lruvec *lruvec) /** * mem_cgroup_margin - calculate chargeable space of a memory cgroup - * @mem: the memory cgroup + * @memcg: the memory cgroup * * Returns the maximum amount of memory @mem can be charged with, in * pages. @@ -1508,7 +1508,7 @@ static unsigned long mem_cgroup_reclaim(struct mem_cgroup *memcg, /** * test_mem_cgroup_node_reclaimable - * @mem: the target memcg + * @memcg: the target memcg * @nid: the node ID to be checked. * @noswap : specify true here if the user wants flle only information. * diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 77775138e930..ac300c99baf6 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -365,7 +365,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, /** * dump_tasks - dump current memory state of all system tasks - * @mem: current's memory controller, if constrained + * @memcg: current's memory controller, if constrained * @nodemask: nodemask passed to page allocator for mempolicy ooms * * Dumps the current memory state of all eligible tasks. Tasks not in the same diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index 1ccbd714059c..eb750f851395 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c @@ -392,7 +392,7 @@ static struct swap_cgroup *lookup_swap_cgroup(swp_entry_t ent, /** * swap_cgroup_cmpxchg - cmpxchg mem_cgroup's id for this swp_entry. - * @end: swap entry to be cmpxchged + * @ent: swap entry to be cmpxchged * @old: old id * @new: new id * @@ -422,7 +422,7 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, /** * swap_cgroup_record - record mem_cgroup for this swp_entry. * @ent: swap entry to be recorded into - * @mem: mem_cgroup to be recorded + * @id: mem_cgroup to be recorded * * Returns old value at success, 0 at failure. * (Of course, old value can be 0.) diff --git a/mm/pagewalk.c b/mm/pagewalk.c index aa9701e12714..6c118d012bb5 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -162,7 +162,6 @@ static int walk_hugetlb_range(struct vm_area_struct *vma, /** * walk_page_range - walk a memory map's page tables with a callback - * @mm: memory map to walk * @addr: starting address * @end: ending address * @walk: set of callbacks to invoke for each level of the tree diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c index 405d331804c3..3707c71ae4cd 100644 --- a/mm/percpu-vm.c +++ b/mm/percpu-vm.c @@ -360,7 +360,6 @@ err_free: * @chunk: chunk to depopulate * @off: offset to the area to depopulate * @size: size of the area to depopulate in bytes - * @flush: whether to flush cache and tlb or not * * For each cpu, depopulate and unmap pages [@page_start,@page_end) * from @chunk. If @flush is true, vcache is flushed before unmapping -- GitLab From eb4546bbbdb160aff084d50511165f385756af18 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 20 Jun 2012 12:53:02 -0700 Subject: [PATCH 2308/6849] mm/memory.c: fix kernel-doc warnings Fix kernel-doc warnings in mm/memory.c: Warning(mm/memory.c:1377): No description found for parameter 'start' Warning(mm/memory.c:1377): Excess function parameter 'address' description in 'zap_page_range' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index 8762c4f915fc..2466d1250231 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1374,7 +1374,7 @@ void unmap_vmas(struct mmu_gather *tlb, /** * zap_page_range - remove user pages in a given range * @vma: vm_area_struct holding the applicable pages - * @address: starting address of pages to zap + * @start: starting address of pages to zap * @size: number of bytes to zap * @details: details of nonlinear truncation or shared cache invalidation * -- GitLab From 7dea26813507bfa3d261a81f70494336c3b28293 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 20 Jun 2012 12:53:02 -0700 Subject: [PATCH 2309/6849] get_maintainer: Fix --help warning Using --help emits a concatenation error. Fix it. Signed-off-by: Joe Perches Reported-by: Paul Bolle Tested-by: Paul Bolle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 0948c6b5a321..8b673dd4627f 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -83,6 +83,8 @@ push(@signature_tags, "Signed-off-by:"); push(@signature_tags, "Reviewed-by:"); push(@signature_tags, "Acked-by:"); +my $signature_pattern = "\(" . join("|", @signature_tags) . "\)"; + # rfc822 email address - preloaded methods go here. my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; my $rfc822_char = '[\\000-\\377]'; @@ -473,7 +475,6 @@ my @subsystem = (); my @status = (); my %deduplicate_name_hash = (); my %deduplicate_address_hash = (); -my $signature_pattern; my @maintainers = get_maintainers(); -- GitLab From 10d8935f46e5028847b179757ecbf9238b13d129 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 20 Jun 2012 12:53:02 -0700 Subject: [PATCH 2310/6849] Viresh has moved viresh.kumar@st.com email-id doesn't exist anymore as I have left the company. Replace ST's id with viresh.linux@gmail.com. It also updates .mailmap file to fix address for 'git shortlog' Signed-off-by: Viresh Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 1 + Documentation/arm/SPEAr/overview.txt | 2 +- MAINTAINERS | 18 +++++++++--------- arch/arm/boot/dts/spear1310-evb.dts | 2 +- arch/arm/boot/dts/spear1310.dtsi | 2 +- arch/arm/boot/dts/spear1340-evb.dts | 2 +- arch/arm/boot/dts/spear1340.dtsi | 2 +- arch/arm/boot/dts/spear13xx.dtsi | 2 +- arch/arm/boot/dts/spear300-evb.dts | 2 +- arch/arm/boot/dts/spear300.dtsi | 2 +- arch/arm/boot/dts/spear310-evb.dts | 2 +- arch/arm/boot/dts/spear310.dtsi | 2 +- arch/arm/boot/dts/spear320-evb.dts | 2 +- arch/arm/boot/dts/spear320.dtsi | 2 +- arch/arm/boot/dts/spear3xx.dtsi | 2 +- arch/arm/include/asm/hardware/sp810.h | 2 +- .../mach-spear13xx/include/mach/debug-macro.S | 2 +- arch/arm/mach-spear13xx/include/mach/dma.h | 2 +- arch/arm/mach-spear13xx/include/mach/generic.h | 2 +- arch/arm/mach-spear13xx/include/mach/gpio.h | 2 +- arch/arm/mach-spear13xx/include/mach/irqs.h | 2 +- arch/arm/mach-spear13xx/include/mach/spear.h | 2 +- arch/arm/mach-spear13xx/include/mach/timex.h | 2 +- .../mach-spear13xx/include/mach/uncompress.h | 2 +- arch/arm/mach-spear13xx/spear1310.c | 2 +- arch/arm/mach-spear13xx/spear1340.c | 2 +- arch/arm/mach-spear13xx/spear13xx.c | 2 +- .../mach-spear3xx/include/mach/debug-macro.S | 2 +- arch/arm/mach-spear3xx/include/mach/generic.h | 2 +- arch/arm/mach-spear3xx/include/mach/gpio.h | 2 +- arch/arm/mach-spear3xx/include/mach/irqs.h | 2 +- .../arm/mach-spear3xx/include/mach/misc_regs.h | 2 +- arch/arm/mach-spear3xx/include/mach/spear.h | 2 +- arch/arm/mach-spear3xx/include/mach/timex.h | 2 +- .../mach-spear3xx/include/mach/uncompress.h | 2 +- arch/arm/mach-spear3xx/spear300.c | 2 +- arch/arm/mach-spear3xx/spear310.c | 2 +- arch/arm/mach-spear3xx/spear320.c | 2 +- arch/arm/mach-spear3xx/spear3xx.c | 2 +- arch/arm/mach-spear6xx/include/mach/gpio.h | 2 +- .../arm/mach-spear6xx/include/mach/misc_regs.h | 2 +- arch/arm/plat-spear/include/plat/debug-macro.S | 2 +- arch/arm/plat-spear/include/plat/pl080.h | 2 +- arch/arm/plat-spear/include/plat/shirq.h | 2 +- arch/arm/plat-spear/include/plat/timex.h | 2 +- arch/arm/plat-spear/include/plat/uncompress.h | 2 +- arch/arm/plat-spear/pl080.c | 2 +- arch/arm/plat-spear/restart.c | 2 +- arch/arm/plat-spear/shirq.c | 2 +- drivers/ata/pata_arasan_cf.c | 4 ++-- drivers/clk/spear/clk-aux-synth.c | 2 +- drivers/clk/spear/clk-frac-synth.c | 2 +- drivers/clk/spear/clk-gpt-synth.c | 2 +- drivers/clk/spear/clk-vco-pll.c | 2 +- drivers/clk/spear/clk.c | 2 +- drivers/clk/spear/clk.h | 2 +- drivers/clk/spear/spear1310_clock.c | 2 +- drivers/clk/spear/spear1340_clock.c | 2 +- drivers/clk/spear/spear3xx_clock.c | 2 +- drivers/clk/spear/spear6xx_clock.c | 2 +- drivers/dma/dw_dmac.c | 2 +- drivers/mfd/stmpe-i2c.c | 2 +- drivers/mfd/stmpe-spi.c | 4 ++-- drivers/mmc/host/sdhci-spear.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear.c | 2 +- drivers/pinctrl/spear/pinctrl-spear.h | 2 +- drivers/pinctrl/spear/pinctrl-spear1310.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear1340.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear300.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear310.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear320.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear3xx.c | 2 +- drivers/pinctrl/spear/pinctrl-spear3xx.h | 2 +- drivers/watchdog/sp805_wdt.c | 4 ++-- include/linux/mmc/sdhci-spear.h | 2 +- include/linux/pata_arasan_cf_data.h | 2 +- 76 files changed, 93 insertions(+), 92 deletions(-) diff --git a/.mailmap b/.mailmap index 2909c33bc54e..658003aa9446 100644 --- a/.mailmap +++ b/.mailmap @@ -111,6 +111,7 @@ Uwe Kleine-König Uwe Kleine-König Uwe Kleine-König Valdis Kletnieks +Viresh Kumar Takashi YOSHII Yusuke Goda Gustavo Padovan diff --git a/Documentation/arm/SPEAr/overview.txt b/Documentation/arm/SPEAr/overview.txt index 57aae7765c74..65610bf52ebf 100644 --- a/Documentation/arm/SPEAr/overview.txt +++ b/Documentation/arm/SPEAr/overview.txt @@ -60,4 +60,4 @@ Introduction Document Author --------------- - Viresh Kumar , (c) 2010-2012 ST Microelectronics + Viresh Kumar , (c) 2010-2012 ST Microelectronics diff --git a/MAINTAINERS b/MAINTAINERS index 3e30a3afe2a4..a81b298d9c75 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -579,7 +579,7 @@ F: drivers/net/appletalk/ F: net/appletalk/ ARASAN COMPACT FLASH PATA CONTROLLER -M: Viresh Kumar +M: Viresh Kumar L: linux-ide@vger.kernel.org S: Maintained F: include/linux/pata_arasan_cf_data.h @@ -5296,7 +5296,7 @@ S: Maintained F: drivers/pinctrl/ PIN CONTROLLER - ST SPEAR -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -5873,7 +5873,7 @@ S: Maintained F: drivers/tty/serial SYNOPSYS DESIGNWARE DMAC DRIVER -M: Viresh Kumar +M: Viresh Kumar S: Maintained F: include/linux/dw_dmac.h F: drivers/dma/dw_dmac_regs.h @@ -6021,7 +6021,7 @@ S: Maintained F: drivers/mmc/host/sdhci-s3c.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-mmc@vger.kernel.org S: Maintained @@ -6377,7 +6377,7 @@ S: Maintained F: include/linux/compiler.h SPEAR PLATFORM SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6386,7 +6386,7 @@ S: Maintained F: arch/arm/plat-spear/ SPEAR13XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6395,7 +6395,7 @@ S: Maintained F: arch/arm/mach-spear13xx/ SPEAR3XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -6406,7 +6406,7 @@ F: arch/arm/mach-spear3xx/ SPEAR6XX MACHINE SUPPORT M: Rajeev Kumar M: Shiraz Hashim -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -6414,7 +6414,7 @@ S: Maintained F: arch/arm/mach-spear6xx/ SPEAR CLOCK FRAMEWORK SUPPORT -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts index 8314e4171884..dd4358bc26e2 100644 --- a/arch/arm/boot/dts/spear1310-evb.dts +++ b/arch/arm/boot/dts/spear1310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr1310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 9e61da404d57..419ea7413d23 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr1310 SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts index 0d8472e5ab9f..c9a54e06fb68 100644 --- a/arch/arm/boot/dts/spear1340-evb.dts +++ b/arch/arm/boot/dts/spear1340-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr1340 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index a26fc47a55e8..d71fe2a68f09 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr1340 SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index 1f8e1e1481df..10dcec7e7321 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr13xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts index fc82b1a26458..d71b8d581e3d 100644 --- a/arch/arm/boot/dts/spear300-evb.dts +++ b/arch/arm/boot/dts/spear300-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi index 01c5e358fdb2..ed3627c116cc 100644 --- a/arch/arm/boot/dts/spear300.dtsi +++ b/arch/arm/boot/dts/spear300.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts index dc5e2d445a93..b00544e0cd5d 100644 --- a/arch/arm/boot/dts/spear310-evb.dts +++ b/arch/arm/boot/dts/spear310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index e47081c494d9..62fc4fb3e5f9 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts index 6308fa3bec1e..c13fd1f3b09f 100644 --- a/arch/arm/boot/dts/spear320-evb.dts +++ b/arch/arm/boot/dts/spear320-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index 5372ca399b1f..1f49d69595a0 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi index 91072553963f..3a8bb5736928 100644 --- a/arch/arm/boot/dts/spear3xx.dtsi +++ b/arch/arm/boot/dts/spear3xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr3xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h index e0d1c0cfa548..6b9b077d86b3 100644 --- a/arch/arm/include/asm/hardware/sp810.h +++ b/arch/arm/include/asm/hardware/sp810.h @@ -4,7 +4,7 @@ * ARM PrimeXsys System Controller SP810 header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/debug-macro.S b/arch/arm/mach-spear13xx/include/mach/debug-macro.S index ea1564609bd4..9e3ae6bfe50d 100644 --- a/arch/arm/mach-spear13xx/include/mach/debug-macro.S +++ b/arch/arm/mach-spear13xx/include/mach/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header spear13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/dma.h b/arch/arm/mach-spear13xx/include/mach/dma.h index 383ab04dc6c9..d50bdb605925 100644 --- a/arch/arm/mach-spear13xx/include/mach/dma.h +++ b/arch/arm/mach-spear13xx/include/mach/dma.h @@ -4,7 +4,7 @@ * DMA information for SPEAr13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h index 6d8c45b9f298..dac57fd0cdfd 100644 --- a/arch/arm/mach-spear13xx/include/mach/generic.h +++ b/arch/arm/mach-spear13xx/include/mach/generic.h @@ -4,7 +4,7 @@ * spear13xx machine family generic header file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/gpio.h b/arch/arm/mach-spear13xx/include/mach/gpio.h index cd6f4f86a56b..85f176311f63 100644 --- a/arch/arm/mach-spear13xx/include/mach/gpio.h +++ b/arch/arm/mach-spear13xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h index f542a24aa5f2..271a62b4cd31 100644 --- a/arch/arm/mach-spear13xx/include/mach/irqs.h +++ b/arch/arm/mach-spear13xx/include/mach/irqs.h @@ -4,7 +4,7 @@ * IRQ helper macros for spear13xx machine family * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h index 30c57ef72686..65f27def239b 100644 --- a/arch/arm/mach-spear13xx/include/mach/spear.h +++ b/arch/arm/mach-spear13xx/include/mach/spear.h @@ -4,7 +4,7 @@ * spear13xx Machine family specific definition * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/timex.h b/arch/arm/mach-spear13xx/include/mach/timex.h index 31af3e8d976e..3a58b8284a6a 100644 --- a/arch/arm/mach-spear13xx/include/mach/timex.h +++ b/arch/arm/mach-spear13xx/include/mach/timex.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family specific timex definitions * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/include/mach/uncompress.h b/arch/arm/mach-spear13xx/include/mach/uncompress.h index c7840896ae6e..70fe72f05dea 100644 --- a/arch/arm/mach-spear13xx/include/mach/uncompress.h +++ b/arch/arm/mach-spear13xx/include/mach/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c index fefd15b2f380..732d29bc7330 100644 --- a/arch/arm/mach-spear13xx/spear1310.c +++ b/arch/arm/mach-spear13xx/spear1310.c @@ -4,7 +4,7 @@ * SPEAr1310 machine source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c index ee38cbc56869..81e4ed76ad06 100644 --- a/arch/arm/mach-spear13xx/spear1340.c +++ b/arch/arm/mach-spear13xx/spear1340.c @@ -4,7 +4,7 @@ * SPEAr1340 machine source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index 50b349ae863d..cf936b106e27 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c @@ -4,7 +4,7 @@ * SPEAr13XX machines common source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/arch/arm/mach-spear3xx/include/mach/debug-macro.S index 590519f10d6e..0a6381fad5d9 100644 --- a/arch/arm/mach-spear3xx/include/mach/debug-macro.S +++ b/arch/arm/mach-spear3xx/include/mach/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header spear3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h index 4a95b9453c2a..ce19113ca791 100644 --- a/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/arch/arm/mach-spear3xx/include/mach/generic.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family generic header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h index 451b2081bfc9..2ac74c6db7f1 100644 --- a/arch/arm/mach-spear3xx/include/mach/gpio.h +++ b/arch/arm/mach-spear3xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h index 51bd62a0254c..803de76f5f36 100644 --- a/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -4,7 +4,7 @@ * IRQ helper macros for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h index 18e2ac576f25..6309bf68d6f8 100644 --- a/arch/arm/mach-spear3xx/include/mach/misc_regs.h +++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h @@ -4,7 +4,7 @@ * Miscellaneous registers definitions for SPEAr3xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h index 51eb953148a9..8cca95193d4d 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear.h +++ b/arch/arm/mach-spear3xx/include/mach/spear.h @@ -4,7 +4,7 @@ * SPEAr3xx Machine family specific definition * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/timex.h b/arch/arm/mach-spear3xx/include/mach/timex.h index a38cc9de876f..9f5d08bd0c44 100644 --- a/arch/arm/mach-spear3xx/include/mach/timex.h +++ b/arch/arm/mach-spear3xx/include/mach/timex.h @@ -4,7 +4,7 @@ * SPEAr3XX machine family specific timex definitions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/include/mach/uncompress.h b/arch/arm/mach-spear3xx/include/mach/uncompress.h index 53ba8bbc0dfa..b909b011f7c8 100644 --- a/arch/arm/mach-spear3xx/include/mach/uncompress.h +++ b/arch/arm/mach-spear3xx/include/mach/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index f74a05bdb829..0f882ecb7d81 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -4,7 +4,7 @@ * SPEAr300 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 84dfb0900747..bbcf4571d361 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -4,7 +4,7 @@ * SPEAr310 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index a88fa841d29d..88d483bcd66a 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -4,7 +4,7 @@ * SPEAr320 machine source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index f22419ed74a8..0f41bd1c47c3 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -4,7 +4,7 @@ * SPEAr3XX machines common source file * * Copyright (C) 2009-2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h index 3a789dbb69f7..d42cefc0356d 100644 --- a/arch/arm/mach-spear6xx/include/mach/gpio.h +++ b/arch/arm/mach-spear6xx/include/mach/gpio.h @@ -4,7 +4,7 @@ * GPIO macros for SPEAr6xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h index 179e45774b3a..c34acc201d34 100644 --- a/arch/arm/mach-spear6xx/include/mach/misc_regs.h +++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h @@ -4,7 +4,7 @@ * Miscellaneous registers definitions for SPEAr6xx machine family * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S index ab3de721c5db..75b05ad0fbad 100644 --- a/arch/arm/plat-spear/include/plat/debug-macro.S +++ b/arch/arm/plat-spear/include/plat/debug-macro.S @@ -4,7 +4,7 @@ * Debugging macro include header for spear platform * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h index e14a3e4932f9..2bc6b54460a8 100644 --- a/arch/arm/plat-spear/include/plat/pl080.h +++ b/arch/arm/plat-spear/include/plat/pl080.h @@ -4,7 +4,7 @@ * DMAC pl080 definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h index 03ed8b585dcf..88a7fbd24793 100644 --- a/arch/arm/plat-spear/include/plat/shirq.h +++ b/arch/arm/plat-spear/include/plat/shirq.h @@ -4,7 +4,7 @@ * SPEAr platform shared irq layer header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/timex.h b/arch/arm/plat-spear/include/plat/timex.h index 914d09dd50fd..ef95e5b780bd 100644 --- a/arch/arm/plat-spear/include/plat/timex.h +++ b/arch/arm/plat-spear/include/plat/timex.h @@ -4,7 +4,7 @@ * SPEAr platform specific timex definitions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/include/plat/uncompress.h b/arch/arm/plat-spear/include/plat/uncompress.h index 6dd455bafdfd..2ce6cb17a98b 100644 --- a/arch/arm/plat-spear/include/plat/uncompress.h +++ b/arch/arm/plat-spear/include/plat/uncompress.h @@ -4,7 +4,7 @@ * Serial port stubs for kernel decompress status messages * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/pl080.c b/arch/arm/plat-spear/pl080.c index a56a067717c1..12cf27f935f9 100644 --- a/arch/arm/plat-spear/pl080.c +++ b/arch/arm/plat-spear/pl080.c @@ -4,7 +4,7 @@ * DMAC pl080 definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/restart.c b/arch/arm/plat-spear/restart.c index ea0a61302b7e..4f990115b1bd 100644 --- a/arch/arm/plat-spear/restart.c +++ b/arch/arm/plat-spear/restart.c @@ -4,7 +4,7 @@ * SPEAr platform specific restart functions * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c index 961fb7261243..853e891e1184 100644 --- a/arch/arm/plat-spear/shirq.c +++ b/arch/arm/plat-spear/shirq.c @@ -4,7 +4,7 @@ * SPEAr platform shared irq layer source file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 3239517f4d90..ac6a5beb28f3 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller source file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -959,7 +959,7 @@ static struct platform_driver arasan_cf_driver = { module_platform_driver(arasan_cf_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index af34074e702b..6756e7c3bc07 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 4dbdb3fe18e0..958aa3ad1d60 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index b471c9762a97..1afc18c4effc 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index dcd4bdf4b0d9..5f1b6badeb15 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c index 376d4e5ff326..7cd63788d546 100644 --- a/drivers/clk/spear/clk.c +++ b/drivers/clk/spear/clk.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h index 3321c46a071c..931737677dfa 100644 --- a/drivers/clk/spear/clk.h +++ b/drivers/clk/spear/clk.h @@ -2,7 +2,7 @@ * Clock framework definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 42b68df9aeef..8f05652d53e6 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -4,7 +4,7 @@ * SPEAr1310 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index f130919d5bf8..e3ea72162236 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -4,7 +4,7 @@ * SPEAr1340 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 440bb3e4c971..01dd6daff2a1 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -2,7 +2,7 @@ * SPEAr3xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index f9a20b382304..554d64b062a1 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -2,7 +2,7 @@ * SPEAr6xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index e23dc82d43ac..721296157577 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1626,4 +1626,4 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 373f423b1181..947a06a1845f 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -6,7 +6,7 @@ * * License Terms: GNU General Public License, version 2 * Author: Rabin Vincent for ST-Ericsson - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index afd459013ecb..9edfe864cc05 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -4,7 +4,7 @@ * Copyright (C) ST Microelectronics SA 2011 * * License Terms: GNU General Public License, version 2 - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include @@ -146,4 +146,4 @@ module_exit(stmpe_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 1fe32dfa7cd4..423da8194cd8 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c @@ -4,7 +4,7 @@ * Support of SDHCI platform devices for spear soc family * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired by sdhci-pltfm.c * @@ -289,5 +289,5 @@ static struct platform_driver sdhci_driver = { module_platform_driver(sdhci_driver); MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 5ae50aadf885..b3f6b2873fdd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired from: * - U300 Pinctl drivers diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index 9155783bb47f..d950eb78d939 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h @@ -2,7 +2,7 @@ * Driver header file for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index fff168be7f00..d6cca8c81b92 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -2192,7 +2192,7 @@ static void __exit spear1310_pinctrl_exit(void) } module_exit(spear1310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index a8ab2a6f51bf..a0eb057e55bd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1340 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -1983,7 +1983,7 @@ static void __exit spear1340_pinctrl_exit(void) } module_exit(spear1340_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 9c82a35e4e78..4dfc2849b172 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr300 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -702,7 +702,7 @@ static void __exit spear300_pinctrl_exit(void) } module_exit(spear300_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 1a9707605125..96883693fb7e 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -425,7 +425,7 @@ static void __exit spear310_pinctrl_exit(void) } module_exit(spear310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index de726e6c283a..020b1e0bdb3e 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr320 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -3462,7 +3462,7 @@ static void __exit spear320_pinctrl_exit(void) } module_exit(spear320_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 91c883bc46a6..0242378f7cb8 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 5d5fdd8df7b8..31f44347f17c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -2,7 +2,7 @@ * Header file for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index afcd13676542..e4841c36798b 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -4,7 +4,7 @@ * Watchdog driver for ARM SP805 watchdog module * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2 or later. This program is licensed "as is" without any @@ -331,6 +331,6 @@ static struct amba_driver sp805_wdt_driver = { module_amba_driver(sp805_wdt_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); MODULE_LICENSE("GPL"); diff --git a/include/linux/mmc/sdhci-spear.h b/include/linux/mmc/sdhci-spear.h index 5cdc96da9dd5..e78c0e236e9d 100644 --- a/include/linux/mmc/sdhci-spear.h +++ b/include/linux/mmc/sdhci-spear.h @@ -4,7 +4,7 @@ * SDHCI declarations specific to ST SPEAr platform * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/include/linux/pata_arasan_cf_data.h b/include/linux/pata_arasan_cf_data.h index a6ee9aa898bb..a7b4fc386e63 100644 --- a/include/linux/pata_arasan_cf_data.h +++ b/include/linux/pata_arasan_cf_data.h @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller platform data header file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any -- GitLab From f39cdaebb89dc3e6dd4f3e75b6d4e87ef12190af Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 20 Jun 2012 12:53:03 -0700 Subject: [PATCH 2311/6849] fault-inject: avoid call to random32() if fault injection is disabled After enabling CONFIG_FAILSLAB I noticed random32 in profiles even if slub fault injection wasn't enabled at runtime. should_fail forces a comparison against random32() even if probability is 0: if (attr->probability <= random32() % 100) return false; Add a check up front for probability == 0 and avoid all of the more complicated checks. Signed-off-by: Anton Blanchard Acked-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/fault-inject.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 6805453c18e7..f7210ad6cffd 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -101,6 +101,10 @@ static inline bool fail_stacktrace(struct fault_attr *attr) bool should_fail(struct fault_attr *attr, ssize_t size) { + /* No need to check any other properties if the probability is 0 */ + if (attr->probability == 0) + return false; + if (attr->task_filter && !fail_task(attr, current)) return false; -- GitLab From 6347e90091041e34bea625370794c92f4ce71228 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 20 Jun 2012 12:53:03 -0700 Subject: [PATCH 2312/6849] pidns: guarantee that the pidns init will be the last pidns process reaped Today we have a twofold bug. Sometimes release_task on pid == 1 in a pid namespace can run before other processes in a pid namespace have had release task called. With the result that pid_ns_release_proc can be called before the last proc_flus_task() is done using upid->ns->proc_mnt, resulting in the use of a stale pointer. This same set of circumstances can lead to waitpid(...) returning for a processes started with clone(CLONE_NEWPID) before the every process in the pid namespace has actually exited. To fix this modify zap_pid_ns_processess wait until all other processes in the pid namespace have exited, even EXIT_DEAD zombies. The delay_group_leader and related tests ensure that the thread gruop leader will be the last thread of a process group to be reaped, or to become EXIT_DEAD and self reap. With the change to zap_pid_ns_processes we get the guarantee that pid == 1 in a pid namespace will be the last task that release_task is called on. With pid == 1 being the last task to pass through release_task pid_ns_release_proc can no longer be called too early nor can wait return before all of the EXIT_DEAD tasks in a pid namespace have exited. Signed-off-by: Eric W. Biederman Signed-off-by: Oleg Nesterov Cc: Louis Rilling Cc: Mike Galbraith Acked-by: Pavel Emelyanov Tested-by: Andrew Wagin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/exit.c | 14 +++++++++++++- kernel/pid_namespace.c | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/kernel/exit.c b/kernel/exit.c index c0277d3f1aaa..a85efd2348bd 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -64,7 +64,6 @@ static void exit_mm(struct task_struct * tsk); static void __unhash_process(struct task_struct *p, bool group_dead) { nr_threads--; - detach_pid(p, PIDTYPE_PID); if (group_dead) { detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_SID); @@ -72,7 +71,20 @@ static void __unhash_process(struct task_struct *p, bool group_dead) list_del_rcu(&p->tasks); list_del_init(&p->sibling); __this_cpu_dec(process_counts); + /* + * If we are the last child process in a pid namespace to be + * reaped, notify the reaper sleeping zap_pid_ns_processes(). + */ + if (IS_ENABLED(CONFIG_PID_NS)) { + struct task_struct *parent = p->real_parent; + + if ((task_active_pid_ns(p)->child_reaper == parent) && + list_empty(&parent->children) && + (parent->flags & PF_EXITING)) + wake_up_process(parent); + } } + detach_pid(p, PIDTYPE_PID); list_del_rcu(&p->thread_group); } diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 16b20e38c4a1..b3c7fd554250 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -184,11 +184,31 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) } read_unlock(&tasklist_lock); + /* Firstly reap the EXIT_ZOMBIE children we may have. */ do { clear_thread_flag(TIF_SIGPENDING); rc = sys_wait4(-1, NULL, __WALL, NULL); } while (rc != -ECHILD); + /* + * sys_wait4() above can't reap the TASK_DEAD children. + * Make sure they all go away, see __unhash_process(). + */ + for (;;) { + bool need_wait = false; + + read_lock(&tasklist_lock); + if (!list_empty(¤t->children)) { + __set_current_state(TASK_UNINTERRUPTIBLE); + need_wait = true; + } + read_unlock(&tasklist_lock); + + if (!need_wait) + break; + schedule(); + } + if (pid_ns->reboot) current->signal->group_exit_code = pid_ns->reboot; -- GitLab From 50d75f8daead8a1f850c40a3b6c6575ab19b48cf Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 20 Jun 2012 12:53:04 -0700 Subject: [PATCH 2313/6849] pidns: find_new_reaper() can no longer switch to init_pid_ns.child_reaper find_new_reaper() changes pid_ns->child_reaper, see add0d4df ("pid_ns: zap_pid_ns_processes: fix the ->child_reaper changing"). The original reason has gone away after the previous patch, ->children list must be empty after zap_pid_ns_processes(). However now we can not switch to init_pid_ns.child_reaper. __unhash_process() relies on the "->child_reaper == parent" check, but this check does not work if the last exiting task is also the child reaper. As Eric sugested, we can change __unhash_process() to use the parent's pid_ns and remove this code. Also, with this change we can move detach_pid(PIDTYPE_PID) back, where it was before the previous fix. Signed-off-by: Oleg Nesterov Acked-by: "Eric W. Biederman" Cc: Louis Rilling Cc: Mike Galbraith Acked-by: Pavel Emelyanov Tested-by: Andrew Wagin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/exit.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index a85efd2348bd..2f59cc334516 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -64,6 +64,7 @@ static void exit_mm(struct task_struct * tsk); static void __unhash_process(struct task_struct *p, bool group_dead) { nr_threads--; + detach_pid(p, PIDTYPE_PID); if (group_dead) { detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_SID); @@ -78,13 +79,12 @@ static void __unhash_process(struct task_struct *p, bool group_dead) if (IS_ENABLED(CONFIG_PID_NS)) { struct task_struct *parent = p->real_parent; - if ((task_active_pid_ns(p)->child_reaper == parent) && + if ((task_active_pid_ns(parent)->child_reaper == parent) && list_empty(&parent->children) && (parent->flags & PF_EXITING)) wake_up_process(parent); } } - detach_pid(p, PIDTYPE_PID); list_del_rcu(&p->thread_group); } @@ -732,12 +732,6 @@ static struct task_struct *find_new_reaper(struct task_struct *father) zap_pid_ns_processes(pid_ns); write_lock_irq(&tasklist_lock); - /* - * We can not clear ->child_reaper or leave it alone. - * There may by stealth EXIT_DEAD tasks on ->children, - * forget_original_parent() must move them somewhere. - */ - pid_ns->child_reaper = init_pid_ns.child_reaper; } else if (father->signal->has_child_subreaper) { struct task_struct *reaper; -- GitLab From 5702c5eeab959e86ee2d9b4fe7f2d87e65b25d46 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 20 Jun 2012 12:53:04 -0700 Subject: [PATCH 2314/6849] c/r: prctl: Move PR_GET_TID_ADDRESS to a proper place During merging of PR_GET_TID_ADDRESS patch the code has been misplaced (it happened to appear under PR_MCE_KILL) in result noone can use this option. Fix it by moving code snippet to a proper place. Signed-off-by: Cyrill Gorcunov Acked-by: Kees Cook Cc: Oleg Nesterov Cc: Pavel Emelyanov Cc: Andrey Vagin Cc: Serge Hallyn Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/sys.c b/kernel/sys.c index f0ec44dcd415..e0c8ffc50d7f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2127,9 +2127,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, else return -EINVAL; break; - case PR_GET_TID_ADDRESS: - error = prctl_get_tid_address(me, (int __user **)arg2); - break; default: return -EINVAL; } @@ -2147,6 +2144,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, case PR_SET_MM: error = prctl_set_mm(arg2, arg3, arg4, arg5); break; + case PR_GET_TID_ADDRESS: + error = prctl_get_tid_address(me, (int __user **)arg2); + break; case PR_SET_CHILD_SUBREAPER: me->signal->is_child_subreaper = !!arg2; error = 0; -- GitLab From 48c3b583bbddad2220ca4c22319ca5d1f78b2090 Mon Sep 17 00:00:00 2001 From: Greg Pearson Date: Wed, 20 Jun 2012 12:53:05 -0700 Subject: [PATCH 2315/6849] mm/memblock: fix overlapping allocation when doubling reserved array __alloc_memory_core_early() asks memblock for a range of memory then try to reserve it. If the reserved region array lacks space for the new range, memblock_double_array() is called to allocate more space for the array. If memblock is used to allocate memory for the new array it can end up using a range that overlaps with the range originally allocated in __alloc_memory_core_early(), leading to possible data corruption. With this patch memblock_double_array() now calls memblock_find_in_range() with a narrowed candidate range (in cases where the reserved.regions array is being doubled) so any memory allocated will not overlap with the original range that was being reserved. The range is narrowed by passing in the starting address and size of the previously allocated range. Then the range above the ending address is searched and if a candidate is not found, the range below the starting address is searched. Signed-off-by: Greg Pearson Signed-off-by: Yinghai Lu Acked-by: Tejun Heo Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memblock.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index b65b687e2362..d4382095f8bd 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -184,7 +184,24 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u } } -static int __init_memblock memblock_double_array(struct memblock_type *type) +/** + * memblock_double_array - double the size of the memblock regions array + * @type: memblock type of the regions array being doubled + * @new_area_start: starting address of memory range to avoid overlap with + * @new_area_size: size of memory range to avoid overlap with + * + * Double the size of the @type regions array. If memblock is being used to + * allocate memory for a new reserved regions array and there is a previously + * allocated memory range [@new_area_start,@new_area_start+@new_area_size] + * waiting to be reserved, ensure the memory used by the new array does + * not overlap. + * + * RETURNS: + * 0 on success, -1 on failure. + */ +static int __init_memblock memblock_double_array(struct memblock_type *type, + phys_addr_t new_area_start, + phys_addr_t new_area_size) { struct memblock_region *new_array, *old_array; phys_addr_t old_size, new_size, addr; @@ -222,7 +239,18 @@ static int __init_memblock memblock_double_array(struct memblock_type *type) new_array = kmalloc(new_size, GFP_KERNEL); addr = new_array ? __pa(new_array) : 0; } else { - addr = memblock_find_in_range(0, MEMBLOCK_ALLOC_ACCESSIBLE, new_size, sizeof(phys_addr_t)); + /* only exclude range when trying to double reserved.regions */ + if (type != &memblock.reserved) + new_area_start = new_area_size = 0; + + addr = memblock_find_in_range(new_area_start + new_area_size, + memblock.current_limit, + new_size, sizeof(phys_addr_t)); + if (!addr && new_area_size) + addr = memblock_find_in_range(0, + min(new_area_start, memblock.current_limit), + new_size, sizeof(phys_addr_t)); + new_array = addr ? __va(addr) : 0; } if (!addr) { @@ -399,7 +427,7 @@ repeat: */ if (!insert) { while (type->cnt + nr_new > type->max) - if (memblock_double_array(type) < 0) + if (memblock_double_array(type, obase, size) < 0) return -ENOMEM; insert = true; goto repeat; @@ -450,7 +478,7 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, /* we'll create at most two more regions */ while (type->cnt + 2 > type->max) - if (memblock_double_array(type) < 0) + if (memblock_double_array(type, base, size) < 0) return -ENOMEM; for (i = 0; i < type->cnt; i++) { -- GitLab From 33e6ada17fffc54c24607d5acb279363b30ac401 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 20 Jun 2012 13:36:06 +0100 Subject: [PATCH 2316/6849] staging: ozwpan: ISOC transfer in triggered mode This patch implements ISOC frame transfer while PD is in triggered mode. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozmain.c | 2 +- drivers/staging/ozwpan/ozpd.c | 171 +++++++++++++++++++++++----- drivers/staging/ozwpan/ozpd.h | 3 +- drivers/staging/ozwpan/ozproto.c | 4 +- drivers/staging/ozwpan/ozprotocol.h | 1 + 5 files changed, 146 insertions(+), 35 deletions(-) diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c index 7579645d642a..c1ed6b2522ec 100644 --- a/drivers/staging/ozwpan/ozmain.c +++ b/drivers/staging/ozwpan/ozmain.c @@ -59,6 +59,6 @@ module_exit(ozwpan_exit); MODULE_AUTHOR("Chris Kelly"); MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver"); -MODULE_VERSION("1.0.9"); +MODULE_VERSION("1.0.10"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 04cd57f2a6da..6c566f585024 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -24,18 +24,22 @@ /*------------------------------------------------------------------------------ */ #define OZ_MAX_TX_POOL_SIZE 6 -/* Maximum number of uncompleted isoc frames that can be pending. +/* Maximum number of uncompleted isoc frames that can be pending in network. */ #define OZ_MAX_SUBMITTED_ISOC 16 +/* Maximum number of uncompleted isoc frames that can be pending in Tx Queue. + */ +#define OZ_MAX_TX_QUEUE_ISOC 32 /*------------------------------------------------------------------------------ */ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd); static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f); +static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f); static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f); static int oz_send_isoc_frame(struct oz_pd *pd); static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f); static void oz_isoc_stream_free(struct oz_isoc_stream *st); -static int oz_send_next_queued_frame(struct oz_pd *pd, int *more_data); +static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data); static void oz_isoc_destructor(struct sk_buff *skb); static int oz_def_app_init(void); static void oz_def_app_term(void); @@ -208,6 +212,8 @@ void oz_pd_destroy(struct oz_pd *pd) while (e != &pd->tx_queue) { f = container_of(e, struct oz_tx_frame, link); e = e->next; + if (f->skb != NULL) + kfree_skb(f->skb); oz_retire_frame(pd, f); } oz_elt_buf_term(&pd->elt_buff); @@ -372,6 +378,23 @@ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd) } return f; } +/*------------------------------------------------------------------------------ + * Context: softirq or process + */ +static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f) +{ + pd->nb_queued_isoc_frames--; + list_del_init(&f->link); + if (pd->tx_pool_count < OZ_MAX_TX_POOL_SIZE) { + f->link.next = pd->tx_pool; + pd->tx_pool = &f->link; + pd->tx_pool_count++; + } else { + kfree(f); + } + oz_trace2(OZ_TRACE_TX_FRAMES, "Releasing ISOC Frame isoc_nb= %d\n", + pd->nb_queued_isoc_frames); +} /*------------------------------------------------------------------------------ * Context: softirq or process */ @@ -388,6 +411,14 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f) if (f) kfree(f); } +/*------------------------------------------------------------------------------ + * Context: softirq-serialized + */ +void oz_set_more_bit(struct sk_buff *skb) +{ + struct oz_hdr *oz_hdr = (struct oz_hdr *)skb_network_header(skb); + oz_hdr->control |= OZ_F_MORE_DATA; +} /*------------------------------------------------------------------------------ * Context: softirq */ @@ -403,6 +434,7 @@ int oz_prepare_frame(struct oz_pd *pd, int empty) f = oz_tx_frame_alloc(pd); if (f == 0) return -1; + f->skb = NULL; f->hdr.control = (OZ_PROTOCOL_VERSION<last_tx_pkt_num; @@ -486,24 +518,51 @@ static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f) /*------------------------------------------------------------------------------ * Context: softirq-serialized */ -static int oz_send_next_queued_frame(struct oz_pd *pd, int *more_data) +static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data) { struct sk_buff *skb; struct oz_tx_frame *f; struct list_head *e; - *more_data = 0; spin_lock(&pd->tx_frame_lock); e = pd->last_sent_frame->next; if (e == &pd->tx_queue) { spin_unlock(&pd->tx_frame_lock); return -1; } - pd->last_sent_frame = e; - if (e->next != &pd->tx_queue) - *more_data = 1; f = container_of(e, struct oz_tx_frame, link); + + if (f->skb != NULL) { + skb = f->skb; + oz_tx_isoc_free(pd, f); + spin_unlock(&pd->tx_frame_lock); + if (more_data) + oz_set_more_bit(skb); + if ((int)atomic_read(&g_submitted_isoc) < + OZ_MAX_SUBMITTED_ISOC) { + if (dev_queue_xmit(skb) < 0) { + oz_trace2(OZ_TRACE_TX_FRAMES, + "Dropping ISOC Frame\n"); + oz_event_log(OZ_EVT_TX_ISOC_DROP, 0, 0, 0, 0); + return -1; + } + atomic_inc(&g_submitted_isoc); + oz_trace2(OZ_TRACE_TX_FRAMES, + "Sending ISOC Frame, nb_isoc= %d\n", + pd->nb_queued_isoc_frames); + return 0; + } else { + kfree_skb(skb); + oz_trace2(OZ_TRACE_TX_FRAMES, "Dropping ISOC Frame>\n"); + oz_event_log(OZ_EVT_TX_ISOC_DROP, 0, 0, 0, 0); + return -1; + } + } + + pd->last_sent_frame = e; skb = oz_build_frame(pd, f); spin_unlock(&pd->tx_frame_lock); + if (more_data) + oz_set_more_bit(skb); oz_trace2(OZ_TRACE_TX_FRAMES, "TX frame PN=0x%x\n", f->hdr.pkt_num); if (skb) { oz_event_log(OZ_EVT_TX_FRAME, @@ -512,6 +571,7 @@ static int oz_send_next_queued_frame(struct oz_pd *pd, int *more_data) 0, f->hdr.pkt_num); if (dev_queue_xmit(skb) < 0) return -1; + } return 0; } @@ -520,21 +580,38 @@ static int oz_send_next_queued_frame(struct oz_pd *pd, int *more_data) */ void oz_send_queued_frames(struct oz_pd *pd, int backlog) { - int more; - if (backlog < OZ_MAX_QUEUED_FRAMES) { - if (oz_send_next_queued_frame(pd, &more) >= 0) { - while (more && oz_send_next_queued_frame(pd, &more)) - ; - } else { - if (((pd->mode & OZ_F_ISOC_ANYTIME) == 0) - || (pd->isoc_sent == 0)) { - if (oz_prepare_frame(pd, 1) >= 0) - oz_send_next_queued_frame(pd, &more); - } + while (oz_prepare_frame(pd, 0) >= 0) + backlog++; + + switch (pd->mode & (OZ_F_ISOC_NO_ELTS | OZ_F_ISOC_ANYTIME)) { + + case OZ_F_ISOC_NO_ELTS: { + backlog += pd->nb_queued_isoc_frames; + if (backlog <= 0) + goto out; + if (backlog > OZ_MAX_SUBMITTED_ISOC) + backlog = OZ_MAX_SUBMITTED_ISOC; + break; } - } else { - oz_send_next_queued_frame(pd, &more); + case OZ_NO_ELTS_ANYTIME: { + if ((backlog <= 0) && (pd->isoc_sent == 0)) + goto out; + break; + } + default: { + if (backlog <= 0) + goto out; + break; + } + } + while (backlog--) { + if (oz_send_next_queued_frame(pd, backlog) < 0) + break; } + return; + +out: oz_prepare_frame(pd, 1); + oz_send_next_queued_frame(pd, 0); } /*------------------------------------------------------------------------------ * Context: softirq @@ -603,8 +680,10 @@ void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn) f = container_of(e, struct oz_tx_frame, link); pkt_num = le32_to_cpu(get_unaligned(&f->hdr.pkt_num)); diff = (lpn - (pkt_num & OZ_LAST_PN_MASK)) & OZ_LAST_PN_MASK; - if (diff > OZ_LAST_PN_HALF_CYCLE) + if ((diff > OZ_LAST_PN_HALF_CYCLE) || (pkt_num == 0)) break; + oz_trace2(OZ_TRACE_TX_FRAMES, "Releasing pkt_num= %u, nb= %d\n", + pkt_num, pd->nb_queued_frames); if (first == 0) first = e; last = e; @@ -756,21 +835,53 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, u8 *data, int len) memcpy(oz_hdr, &oz, sizeof(oz)); memcpy(oz_hdr+1, &iso, sizeof(iso)); if (dev_hard_header(skb, dev, OZ_ETHERTYPE, pd->mac_addr, - dev->dev_addr, skb->len) < 0) { - kfree_skb(skb); - return -1; + dev->dev_addr, skb->len) < 0) + goto out; + + skb->destructor = oz_isoc_destructor; + /*Queue for Xmit if mode is not ANYTIME*/ + if (!(pd->mode & OZ_F_ISOC_ANYTIME)) { + struct oz_tx_frame *isoc_unit = NULL; + int nb = pd->nb_queued_isoc_frames; + if (nb >= OZ_MAX_TX_QUEUE_ISOC) { + oz_trace2(OZ_TRACE_TX_FRAMES, + "Dropping ISOC Unit nb= %d\n", + nb); + goto out; + } + isoc_unit = oz_tx_frame_alloc(pd); + if (isoc_unit == NULL) + goto out; + isoc_unit->hdr = oz; + isoc_unit->skb = skb; + spin_lock_bh(&pd->tx_frame_lock); + list_add_tail(&isoc_unit->link, &pd->tx_queue); + pd->nb_queued_isoc_frames++; + spin_unlock_bh(&pd->tx_frame_lock); + oz_trace2(OZ_TRACE_TX_FRAMES, + "Added ISOC Frame to Tx Queue isoc_nb= %d, nb= %d\n", + pd->nb_queued_isoc_frames, pd->nb_queued_frames); + oz_event_log(OZ_EVT_TX_ISOC, nb_units, iso.frame_number, + skb, atomic_read(&g_submitted_isoc)); + return 0; } + + /*In ANYTIME mode Xmit unit immediately*/ if (atomic_read(&g_submitted_isoc) < OZ_MAX_SUBMITTED_ISOC) { - skb->destructor = oz_isoc_destructor; atomic_inc(&g_submitted_isoc); oz_event_log(OZ_EVT_TX_ISOC, nb_units, iso.frame_number, - skb, atomic_read(&g_submitted_isoc)); - if (dev_queue_xmit(skb) < 0) + skb, atomic_read(&g_submitted_isoc)); + if (dev_queue_xmit(skb) < 0) { + oz_event_log(OZ_EVT_TX_ISOC_DROP, 0, 0, 0, 0); return -1; - } else { - oz_event_log(OZ_EVT_TX_ISOC_DROP, 0, 0, 0, 0); - kfree_skb(skb); + } else + return 0; } + +out: oz_event_log(OZ_EVT_TX_ISOC_DROP, 0, 0, 0, 0); + kfree_skb(skb); + return -1; + } return 0; } diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index afc77f0260f0..ddf1341b4e67 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -29,6 +29,7 @@ struct oz_tx_frame { struct list_head link; struct list_head elt_list; struct oz_hdr hdr; + struct sk_buff *skb; int total_size; }; @@ -83,6 +84,7 @@ struct oz_pd { u8 ms_per_isoc; unsigned max_stream_buffering; int nb_queued_frames; + int nb_queued_isoc_frames; struct list_head *tx_pool; int tx_pool_count; spinlock_t tx_frame_lock; @@ -118,4 +120,3 @@ void oz_apps_init(void); void oz_apps_term(void); #endif /* Sentry */ - diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index ad857eeabbb7..502e18a66758 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -217,7 +217,6 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt, pd->mode = body->mode; pd->pd_info = body->pd_info; if (pd->mode & OZ_F_ISOC_NO_ELTS) { - pd->mode |= OZ_F_ISOC_ANYTIME; pd->ms_per_isoc = body->ms_per_isoc; if (!pd->ms_per_isoc) pd->ms_per_isoc = 4; @@ -366,6 +365,7 @@ static void oz_rx_frame(struct sk_buff *skb) } if (pd && !dup && ((pd->mode & OZ_MODE_MASK) == OZ_MODE_TRIGGERED)) { + oz_trace2(OZ_TRACE_RX_FRAMES, "Received TRIGGER Frame\n"); pd->last_sent_frame = &pd->tx_queue; if (oz_hdr->control & OZ_F_ACK) { /* Retire completed frames */ @@ -376,8 +376,6 @@ static void oz_rx_frame(struct sk_buff *skb) int backlog = pd->nb_queued_frames; pd->trigger_pkt_num = pkt_num; /* Send queued frames */ - while (oz_prepare_frame(pd, 0) >= 0) - ; oz_send_queued_frames(pd, backlog); } } diff --git a/drivers/staging/ozwpan/ozprotocol.h b/drivers/staging/ozwpan/ozprotocol.h index b3e7d77f3fff..1e4edbeb61cd 100644 --- a/drivers/staging/ozwpan/ozprotocol.h +++ b/drivers/staging/ozwpan/ozprotocol.h @@ -89,6 +89,7 @@ struct oz_elt_connect_req { #define OZ_MODE_MASK 0xf #define OZ_F_ISOC_NO_ELTS 0x40 #define OZ_F_ISOC_ANYTIME 0x80 +#define OZ_NO_ELTS_ANYTIME 0xc0 /* Keep alive field. */ -- GitLab From df49093ae499882cb9cfb29f80f6abb10ae51d74 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 20 Jun 2012 13:36:07 +0100 Subject: [PATCH 2317/6849] staging: ozwpan: Correct ioctl numbers. ioctl numbers were not in order, rearranging them in ascending order. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozappif.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/ozwpan/ozappif.h b/drivers/staging/ozwpan/ozappif.h index 1b59b0748c6b..449a6ba82337 100644 --- a/drivers/staging/ozwpan/ozappif.h +++ b/drivers/staging/ozwpan/ozappif.h @@ -30,9 +30,9 @@ struct oz_binding_info { #define OZ_IOCTL_GET_PD_LIST _IOR(OZ_IOCTL_MAGIC, 0, struct oz_pd_list) #define OZ_IOCTL_SET_ACTIVE_PD _IOW(OZ_IOCTL_MAGIC, 1, struct oz_mac_addr) #define OZ_IOCTL_GET_ACTIVE_PD _IOR(OZ_IOCTL_MAGIC, 2, struct oz_mac_addr) -#define OZ_IOCTL_ADD_BINDING _IOW(OZ_IOCTL_MAGIC, 5, struct oz_binding_info) -#define OZ_IOCTL_REMOVE_BINDING _IOW(OZ_IOCTL_MAGIC, 8, struct oz_binding_info) -#define OZ_IOCTL_MAX 9 +#define OZ_IOCTL_ADD_BINDING _IOW(OZ_IOCTL_MAGIC, 3, struct oz_binding_info) +#define OZ_IOCTL_REMOVE_BINDING _IOW(OZ_IOCTL_MAGIC, 4, struct oz_binding_info) +#define OZ_IOCTL_MAX 5 #endif /* _OZAPPIF_H */ -- GitLab From fec9f24b6269dc5fb4b1212a970c089461ec7ff2 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 20 Jun 2012 13:36:08 +0100 Subject: [PATCH 2318/6849] staging: ozwpan: kmalloc flag Pass right flag as memory is assigned in process context. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozproto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 502e18a66758..a50ab18a5987 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -794,7 +794,7 @@ void oz_binding_add(char *net_dev) { struct oz_binding *binding; - binding = kmalloc(sizeof(struct oz_binding), GFP_ATOMIC); + binding = kmalloc(sizeof(struct oz_binding), GFP_KERNEL); if (binding) { binding->ptype.type = __constant_htons(OZ_ETHERTYPE); binding->ptype.func = oz_pkt_recv; -- GitLab From 00ec12b827d2f99202e0c9d804514aef2febf8d6 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 20 Jun 2012 13:36:09 +0100 Subject: [PATCH 2319/6849] staging: ozwpan: set last_pkt_nb In case of trigeered ISOC mode set last_pkt_nb only when we are ready to send data. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozpd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 6c566f585024..25a8a08586d6 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -419,6 +419,14 @@ void oz_set_more_bit(struct sk_buff *skb) struct oz_hdr *oz_hdr = (struct oz_hdr *)skb_network_header(skb); oz_hdr->control |= OZ_F_MORE_DATA; } +/*------------------------------------------------------------------------------ + * Context: softirq-serialized + */ +void oz_set_last_pkt_nb(struct oz_pd *pd, struct sk_buff *skb) +{ + struct oz_hdr *oz_hdr = (struct oz_hdr *)skb_network_header(skb); + oz_hdr->last_pkt_num = pd->trigger_pkt_num & OZ_LAST_PN_MASK; +} /*------------------------------------------------------------------------------ * Context: softirq */ @@ -537,6 +545,7 @@ static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data) spin_unlock(&pd->tx_frame_lock); if (more_data) oz_set_more_bit(skb); + oz_set_last_pkt_nb(pd, skb); if ((int)atomic_read(&g_submitted_isoc) < OZ_MAX_SUBMITTED_ISOC) { if (dev_queue_xmit(skb) < 0) { -- GitLab From 6261c1ee6c84290ff89cc2271b9ec634006e53b7 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 20 Jun 2012 13:36:10 +0100 Subject: [PATCH 2320/6849] staging: ozwpan: udev support Register ozmo_wpan class with sysfs & support for udev to create device node. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozcdev.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 27325f74ecdc..929756abf02c 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -330,10 +330,12 @@ const struct file_operations oz_fops = { int oz_cdev_register(void) { int err; + struct class *cl; + struct device *dev; memset(&g_cdev, 0, sizeof(g_cdev)); err = alloc_chrdev_region(&g_cdev.devnum, 0, 1, "ozwpan"); if (err < 0) - return err; + goto out3; oz_trace("Alloc dev number %d:%d\n", MAJOR(g_cdev.devnum), MINOR(g_cdev.devnum)); cdev_init(&g_cdev.cdev, &oz_fops); @@ -342,7 +344,27 @@ int oz_cdev_register(void) spin_lock_init(&g_cdev.lock); init_waitqueue_head(&g_cdev.rdq); err = cdev_add(&g_cdev.cdev, g_cdev.devnum, 1); + if (err < 0) { + oz_trace("Failed to add cdev\n"); + goto out2; + } + cl = class_create(THIS_MODULE, "ozmo_wpan"); + if (IS_ERR(cl)) { + oz_trace("Failed to register ozmo_wpan class\n"); + goto out1; + } + dev = device_create(cl, NULL, g_cdev.devnum, NULL, "ozwpan"); + if (IS_ERR(dev)) { + oz_trace("Failed to create sysfs entry for cdev\n"); + goto out1; + } return 0; +out1: + cdev_del(&g_cdev.cdev); +out2: + unregister_chrdev_region(g_cdev.devnum, 1); +out3: + return err; } /*------------------------------------------------------------------------------ * Context: process -- GitLab From 86c948b4416b4c2c064d6c7e15476afbc04e2bf5 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Wed, 20 Jun 2012 13:36:11 +0100 Subject: [PATCH 2321/6849] staging: ozwpan: Set AC_VO priority Set packet priority to AC_VO for audio data. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozpd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 25a8a08586d6..6c287ac6eaea 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -815,6 +815,8 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, u8 *data, int len) skb_reset_network_header(skb); skb->dev = dev; skb->protocol = htons(OZ_ETHERTYPE); + /* For audio packet set priority to AC_VO */ + skb->priority = 0x7; size = sizeof(struct oz_hdr) + sizeof(struct oz_isoc_large); oz_hdr = (struct oz_hdr *)skb_put(skb, size); } -- GitLab From b10c0b92caf97e0d7f1d76996f73bf07a719aa3e Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 19 Jun 2012 18:15:25 +0530 Subject: [PATCH 2322/6849] staging/ft1000: Return -ENOMEM if kmalloc fails at ft1000_probe If the kmalloc fails return -ENOMEM , returning 0 is not the proper way if any function fails Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 84c38d5c9397..a07c504eb029 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -71,7 +71,7 @@ static int ft1000_probe(struct usb_interface *interface, if (!ft1000dev) { printk(KERN_ERR "out of memory allocating device structure\n"); - return 0; + return -ENOMEM; } memset(ft1000dev, 0, sizeof(*ft1000dev)); -- GitLab From 42ad4a8da587792df050748cadfb433cd67a1cad Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 19 Jun 2012 21:52:38 +0530 Subject: [PATCH 2323/6849] staging/ft1000: use kzalloc to allocate the ft1000_device structure with kzalloc the allocate memory is set to zero, so no need of calling memset again on the allocated memory Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index a07c504eb029..bfead67436fe 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -67,15 +67,13 @@ static int ft1000_probe(struct usb_interface *interface, struct ft1000_info *pft1000info = NULL; const struct firmware *dsp_fw; - ft1000dev = kmalloc(sizeof(struct ft1000_device), GFP_KERNEL); + ft1000dev = kzalloc(sizeof(struct ft1000_device), GFP_KERNEL); if (!ft1000dev) { printk(KERN_ERR "out of memory allocating device structure\n"); return -ENOMEM; } - memset(ft1000dev, 0, sizeof(*ft1000dev)); - dev = interface_to_usbdev(interface); DEBUG("ft1000_probe: usb device descriptor info:\n"); DEBUG("ft1000_probe: number of configuration is %d\n", -- GitLab From 06e34dfb8567585eed11ab39fc2a39192b66500d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 19 Jun 2012 21:53:32 +0530 Subject: [PATCH 2324/6849] staging/ft1000: remove usage of ret in ft1000_open remove the ret and do a simple "return ft1000_submit_rx_urb" Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 43b1d363107e..c1f4f13bf485 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1178,7 +1178,6 @@ static int ft1000_open(struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); struct timeval tv; - int ret; DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber); @@ -1194,9 +1193,7 @@ static int ft1000_open(struct net_device *dev) netif_carrier_on(dev); - ret = ft1000_submit_rx_urb(pInfo); - - return ret; + return ft1000_submit_rx_urb(pInfo); } //--------------------------------------------------------------------------- -- GitLab From 3a658a47f434aae566fd679c33267e733442ba29 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 19 Jun 2012 20:14:52 -0400 Subject: [PATCH 2325/6849] Staging: bcm: Replace INT with int in nvm.c This patch replaces all uppercase INT with lowercase int. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 222 +++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index ed2316570d30..b5b9e93ee79b 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -2,54 +2,54 @@ #define DWORD unsigned int -static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset); -static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); -static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter); +static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset); +static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); +static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter); static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); -static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); +static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize); static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); -static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter); +static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter); static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter); static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter); -static INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset); -static INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section); -static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section); - -static INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd); -static INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd); -static INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso); -static INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso); - -static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); -static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); -static INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); -static INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, +static int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section); +static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section); + +static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd); +static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd); +static int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso); +static int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso); + +static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); +static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, FLASH2X_SECTION_VAL eFlash2xSectionVal, UINT uiOffset, UINT uiNumBytes); static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter); static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter); -static INT BeceemFlashBulkRead( +static int BeceemFlashBulkRead( struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes); -static INT BeceemFlashBulkWrite( +static int BeceemFlashBulkWrite( struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, BOOLEAN bVerify); -static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); +static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); -static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData, UINT dwNumData); +static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData, UINT dwNumData); /* Procedure: ReadEEPROMStatusRegister * @@ -122,7 +122,7 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) * OSAL_STATUS_CODE: */ -INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, +int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, DWORD dwAddress, DWORD *pdwData, DWORD dwNumWords) @@ -241,7 +241,7 @@ INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, * OSAL_STATUS_CODE: */ -INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, +int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, DWORD uiOffset, DWORD *pBuffer) { @@ -267,9 +267,9 @@ INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } /* ReadBeceemEEPROM() */ -INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) +int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) { - INT Status; + int Status; unsigned char puMacAddr[6]; Status = BeceemNVMRead(Adapter, @@ -299,7 +299,7 @@ INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) * - if failed. */ -INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, +int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) @@ -391,14 +391,14 @@ INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, * - if failed. */ -static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, +static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) { UINT uiIndex = 0; UINT uiBytesToRead = uiNumBytes; - INT Status = 0; + int Status = 0; UINT uiPartOffset = 0; int bytes; @@ -542,7 +542,7 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) * */ -static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, +static int FlashSectorErase(struct bcm_mini_adapter *Adapter, UINT addr, UINT numOfSectors) { @@ -603,12 +603,12 @@ static INT FlashSectorErase(struct bcm_mini_adapter *Adapter, * */ -static INT flashByteWrite(struct bcm_mini_adapter *Adapter, +static int flashByteWrite(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ + int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ UINT value; ULONG ulData = *(PUCHAR)pData; int bytes; @@ -680,16 +680,16 @@ static INT flashByteWrite(struct bcm_mini_adapter *Adapter, * */ -static INT flashWrite(struct bcm_mini_adapter *Adapter, +static int flashWrite(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { /* UINT uiStatus = 0; - * INT iRetries = 0; + * int iRetries = 0; * UINT uiReadBack = 0; */ UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ + int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ UINT value; UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; @@ -758,12 +758,12 @@ static INT flashWrite(struct bcm_mini_adapter *Adapter, * OSAL_STATUS_CODE * */ -static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, +static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ + int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ ULONG ulData = *(PUCHAR)pData; UINT value; int bytes; @@ -836,12 +836,12 @@ static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter, * */ -static INT flashWriteStatus(struct bcm_mini_adapter *Adapter, +static int flashWriteStatus(struct bcm_mini_adapter *Adapter, UINT uiOffset, PVOID pData) { UINT uiStatus = 0; - INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ + int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ /* UINT uiReadBack = 0; */ UINT value; UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; @@ -1030,7 +1030,7 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOff * */ -static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, +static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -1046,7 +1046,7 @@ static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, UINT uiNumSectTobeRead = 0; UCHAR ucReadBk[16] = {0}; ULONG ulStatus = 0; - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; UINT uiTemp = 0; UINT index = 0; UINT uiPartOffset = 0; @@ -1218,7 +1218,7 @@ BeceemFlashBulkWrite_EXIT: * */ -static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, +static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -1366,7 +1366,7 @@ BeceemFlashBulkWriteStatus_EXIT: * */ -INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) +int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); UINT uiEepromSize = 0; @@ -1375,7 +1375,7 @@ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) UINT uiCalStartAddr = EEPROM_CALPARAM_START; UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT value; - INT Status = 0; + int Status = 0; if (pBuff == NULL) return -ENOMEM; @@ -1427,7 +1427,7 @@ INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) * */ -INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) +int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff, pPtr; UINT uiEepromSize = 0; @@ -1436,7 +1436,7 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) UINT uiCalStartAddr = EEPROM_CALPARAM_START; UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT value; - INT Status = 0; + int Status = 0; /* * Write the signature first. This will ensure firmware does not access EEPROM. @@ -1505,7 +1505,7 @@ INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) * */ -static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, +static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) @@ -1590,7 +1590,7 @@ static VOID BcmSwapWord(UINT *ptr1) * */ -static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset) +static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset) { UINT uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; UINT uiStatus = 0; @@ -1720,7 +1720,7 @@ static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] * */ -INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, +int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, PUCHAR pBuffer, UINT uiOffset, UINT uiNumBytes, @@ -1733,7 +1733,7 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, UINT uiTempOffset = 0; UINT uiExtraBytes = 0; /* PUINT puiBuffer = (PUINT)pBuffer; - * INT value; + * int value; */ if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { @@ -1807,12 +1807,12 @@ INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, * - if failed. */ -INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, +int BeceemNVMRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes) { - INT Status = 0; + int Status = 0; #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) UINT uiTemp = 0, value; @@ -1866,13 +1866,13 @@ INT BeceemNVMRead(struct bcm_mini_adapter *Adapter, * - if failed. */ -INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, +int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, UINT uiOffset, UINT uiNumBytes, BOOLEAN bVerify) { - INT Status = 0; + int Status = 0; UINT uiTemp = 0; UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; UINT uiIndex = 0; @@ -1975,9 +1975,9 @@ INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter, * - if failed. */ -INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) +int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) { - INT Status = -1; + int Status = -1; FLASH_CS_INFO sFlashCsInfo = {0}; UINT uiTemp = 0; UINT uiSectorSig = 0; @@ -2089,7 +2089,7 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe * */ -static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) +static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) { UINT value = 0; /* CHIP Bug : Clear the Avail bits on the Read queue. The default @@ -2126,7 +2126,7 @@ static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) * */ -INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) +int BcmInitNVM(struct bcm_mini_adapter *ps_adapter) { BcmValidateNvmType(ps_adapter); BcmInitEEPROMQueues(ps_adapter); @@ -2152,7 +2152,7 @@ INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter) * 0. means success; */ -static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter) +static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter) { if (Adapter->eNVMType == NVM_EEPROM) Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); @@ -2222,7 +2222,7 @@ static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) return ulRDID >> 8; } -INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) +int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { if (psAdapter == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); @@ -2252,7 +2252,7 @@ INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) return STATUS_SUCCESS; } -INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) +int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { if (psAdapter == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); @@ -2264,7 +2264,7 @@ INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) return STATUS_SUCCESS; } -static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) +static int BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) { UINT Index = 0; @@ -2324,7 +2324,7 @@ static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bc return STATUS_SUCCESS; } -static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) +static int ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) { UINT Index = 0; @@ -2381,7 +2381,7 @@ static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) return STATUS_SUCCESS; } -static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) +static int ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) { /* UINT Index = 0; */ psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); @@ -2413,7 +2413,7 @@ static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) return STATUS_SUCCESS; } -static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section) +static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section) { return (Adapter->uiVendorExtnFlag && (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && @@ -2507,7 +2507,7 @@ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) * */ -static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) +static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) { /* FLASH_CS_INFO sFlashCsInfo = {0}; */ @@ -2667,7 +2667,7 @@ static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) * On Failure -returns STATUS_FAILURE */ -INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) +int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { /* * Considering all the section for which end offset can be calculated or directly given @@ -2675,7 +2675,7 @@ INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO * endoffset can't be calculated or given in CS Structure. */ - INT SectStartOffset = 0; + int SectStartOffset = 0; SectStartOffset = INVALID_OFFSET; @@ -2759,9 +2759,9 @@ INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTIO * On Failure -returns STATUS_FAILURE */ -INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { - INT SectEndOffset = 0; + int SectEndOffset = 0; SectEndOffset = INVALID_OFFSET; if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) @@ -2845,14 +2845,14 @@ INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ * return true on success and STATUS_FAILURE on fail. */ -INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, +int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, FLASH2X_SECTION_VAL eFlash2xSectionVal, UINT uiOffsetWithinSectionVal, UINT uiNumBytes) { - INT Status = STATUS_SUCCESS; - INT SectionStartOffset = 0; + int Status = STATUS_SUCCESS; + int SectionStartOffset = 0; UINT uiAbsoluteOffset = 0; UINT uiTemp = 0, value = 0; @@ -2907,14 +2907,14 @@ INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, * */ -INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, +int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, FLASH2X_SECTION_VAL eFlash2xSectVal, UINT uiOffset, UINT uiNumBytes, UINT bVerify) { - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; UINT FlashSectValStartOffset = 0; UINT uiTemp = 0, value = 0; @@ -2969,7 +2969,7 @@ INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, * */ -static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) +static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) { FLASH2X_SECTION_VAL uiHighestPriDSD = 0; @@ -3011,9 +3011,9 @@ static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) * */ -static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter) +static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter) { - INT HighestPriISO = 0; + int HighestPriISO = 0; HighestPriISO = getHighestPriISO(Adapter); @@ -3064,7 +3064,7 @@ B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) return FALSE; } -static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) +static int BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -3099,7 +3099,7 @@ static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) * Failure:- negative error code */ -INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap) +int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap) { PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo; FLASH2X_SECTION_VAL uiHighestPriDSD = 0; @@ -3349,16 +3349,16 @@ INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITM * */ -INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) +int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal) { unsigned int SectImagePriority = 0; - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; /* DSD_HEADER sDSD = {0}; * ISO_HEADER sISO = {0}; */ - INT HighestPriDSD = 0 ; - INT HighestPriISO = 0; + int HighestPriDSD = 0 ; + int HighestPriISO = 0; Status = IsSectionWritable(Adapter, eFlash2xSectVal); if (Status != TRUE) { @@ -3529,7 +3529,7 @@ INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eF * */ -INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut) +int BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut) { PCHAR Buff = NULL; FLASH2X_SECTION_VAL eISOReadPart = 0, eISOWritePart = 0; @@ -3813,9 +3813,9 @@ out: * Failure :-Return negative error code */ -INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal); @@ -3841,7 +3841,7 @@ INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e * Failure :-Return negative error code */ -INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) +int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { UINT uiSignature = 0; UINT uiOffset = 0; @@ -3901,7 +3901,7 @@ INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl * Return values:-Return TRUE is request is valid else FALSE. */ -INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) +int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) { UINT uiNumOfBytes = 0; UINT uiSectStartOffset = 0; @@ -3960,7 +3960,7 @@ INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRIT * return TRUE if flah2.x of hgher version else return false. */ -INT IsFlash2x(struct bcm_mini_adapter *Adapter) +int IsFlash2x(struct bcm_mini_adapter *Adapter) { if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) return TRUE; @@ -3976,7 +3976,7 @@ INT IsFlash2x(struct bcm_mini_adapter *Adapter) * Success :- Base Address of the Flash */ -static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) +static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) { UINT uiBaseAddr = 0; @@ -4020,7 +4020,7 @@ static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) * Faillure :- return negative error code */ -INT BcmCopySection(struct bcm_mini_adapter *Adapter, +int BcmCopySection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL SrcSection, FLASH2X_SECTION_VAL DstSection, UINT offset, @@ -4029,7 +4029,7 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, UINT BuffSize = 0; UINT BytesToBeCopied = 0; PUCHAR pBuff = NULL; - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; if (SrcSection == DstSection) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again"); @@ -4125,7 +4125,7 @@ INT BcmCopySection(struct bcm_mini_adapter *Adapter, * Faillure :- Return negative error code */ -INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset) +int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset) { UINT offsetToProtect = 0, HeaderSizeToProtect = 0; BOOLEAN bHasHeader = FALSE; @@ -4190,10 +4190,10 @@ INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO * OutPut:- * Select the Appropriate chip and retrn status Success */ -static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) +static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) { UINT FlashConfig = 0; - INT ChipNum = 0; + int ChipNum = 0; UINT GPIOConfig = 0; UINT PartNum = 0; @@ -4264,7 +4264,7 @@ static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) return STATUS_SUCCESS; } -INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) +int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { UINT uiDSDsig = 0; /* UINT sigoffsetInMap = 0; @@ -4289,7 +4289,7 @@ INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) return uiDSDsig; } -INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) +int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { /* UINT priOffsetInMap = 0 ; */ unsigned int uiDSDPri = STATUS_FAILURE; @@ -4314,8 +4314,8 @@ INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter) { - INT DSDHighestPri = STATUS_FAILURE; - INT DsdPri = 0; + int DSDHighestPri = STATUS_FAILURE; + int DsdPri = 0; FLASH2X_SECTION_VAL HighestPriDSD = 0; if (IsSectionWritable(Adapter, DSD2)) { @@ -4344,7 +4344,7 @@ FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter) return HighestPriDSD; } -INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) +int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { UINT uiISOsig = 0; /* UINT sigoffsetInMap = 0; @@ -4367,7 +4367,7 @@ INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) return uiISOsig; } -INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) +int ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { unsigned int ISOPri = STATUS_FAILURE; if (IsSectionWritable(Adapter, iso)) { @@ -4388,8 +4388,8 @@ INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter) { - INT ISOHighestPri = STATUS_FAILURE; - INT ISOPri = 0; + int ISOHighestPri = STATUS_FAILURE; + int ISOPri = 0; FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL; if (IsSectionWritable(Adapter, ISO_IMAGE2)) { @@ -4410,7 +4410,7 @@ FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter) return HighestPriISO; } -INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, +int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, FLASH2X_SECTION_VAL eFlash2xSectionVal, UINT uiOffset, @@ -4423,7 +4423,7 @@ INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, #endif UINT uiStartOffset = 0; /* Adding section start address */ - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; PUCHAR pcBuff = (PUCHAR)pBuff; if (uiNumBytes % Adapter->ulFlashWriteSize) { @@ -4523,10 +4523,10 @@ BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ return SectionPresent; } -INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section) +int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section) { - INT offset = STATUS_FAILURE; - INT Status = FALSE; + int offset = STATUS_FAILURE; + int Status = FALSE; if (IsSectionExistInFlash(Adapter, Section) == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section); @@ -4546,7 +4546,7 @@ INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Sect return Status; } -static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; UINT sig = 0; @@ -4608,7 +4608,7 @@ static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e return STATUS_SUCCESS; } -static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; UINT sig = 0; -- GitLab From 0f20146536ecf6ed901afa2f9a88b8f968175480 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 19 Jun 2012 20:14:53 -0400 Subject: [PATCH 2326/6849] Staging: bcm: Replace UINT with "unsigned int" in nvm.c This patch replaces all uppercase UINT with "unsigned int". Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 412 +++++++++++++++++++------------------- 1 file changed, 206 insertions(+), 206 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index b5b9e93ee79b..14fce106db2c 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -2,21 +2,21 @@ #define DWORD unsigned int -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset); +static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset); static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter); -static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); +static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); -static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize); +static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize); static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter); -static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter); +static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter); static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter); static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); -static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset); +static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset); static int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section); static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section); @@ -27,29 +27,29 @@ static int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VA static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); -static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); +static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr); static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, FLASH2X_SECTION_VAL eFlash2xSectionVal, - UINT uiOffset, UINT uiNumBytes); + unsigned int uiOffset, unsigned int uiNumBytes); static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter); static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter); static int BeceemFlashBulkRead( struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes); + unsigned int uiOffset, + unsigned int uiNumBytes); static int BeceemFlashBulkWrite( struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, + unsigned int uiOffset, + unsigned int uiNumBytes, BOOLEAN bVerify); static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); -static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData, UINT dwNumData); +static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData); /* Procedure: ReadEEPROMStatusRegister * @@ -64,9 +64,9 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) { UCHAR uiData = 0; DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - UINT uiStatus = 0; - UINT value = 0; - UINT value1 = 0; + unsigned int uiStatus = 0; + unsigned int value = 0; + unsigned int value1 = 0; /* Read the EEPROM status register */ value = EEPROM_READ_STATUS_REGISTER; @@ -129,9 +129,9 @@ int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, { DWORD dwIndex = 0; DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - UINT uiStatus = 0; - UINT value = 0; - UINT value1 = 0; + unsigned int uiStatus = 0; + unsigned int value = 0; + unsigned int value1 = 0; UCHAR *pvalue; /* Flush the read and cmd queue. */ @@ -245,9 +245,9 @@ int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, DWORD uiOffset, DWORD *pBuffer) { - UINT uiData[8] = {0}; - UINT uiByteOffset = 0; - UINT uiTempOffset = 0; + unsigned int uiData[8] = {0}; + unsigned int uiByteOffset = 0; + unsigned int uiTempOffset = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> "); @@ -301,16 +301,16 @@ int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) + unsigned int uiOffset, + unsigned int uiNumBytes) { - UINT uiData[4] = {0}; - /* UINT uiAddress = 0; */ - UINT uiBytesRemaining = uiNumBytes; - UINT uiIndex = 0; - UINT uiTempOffset = 0; - UINT uiExtraBytes = 0; - UINT uiFailureRetries = 0; + unsigned int uiData[4] = {0}; + /* unsigned int uiAddress = 0; */ + unsigned int uiBytesRemaining = uiNumBytes; + unsigned int uiIndex = 0; + unsigned int uiTempOffset = 0; + unsigned int uiExtraBytes = 0; + unsigned int uiFailureRetries = 0; PUCHAR pcBuff = (PUCHAR)pBuffer; if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) { @@ -393,13 +393,13 @@ int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) + unsigned int uiOffset, + unsigned int uiNumBytes) { - UINT uiIndex = 0; - UINT uiBytesToRead = uiNumBytes; + unsigned int uiIndex = 0; + unsigned int uiBytesToRead = uiNumBytes; int Status = 0; - UINT uiPartOffset = 0; + unsigned int uiPartOffset = 0; int bytes; if (Adapter->device_removed) { @@ -465,11 +465,11 @@ static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, * Adapter - ptr to Adapter object instance * * Returns: - * UINT - size of the FLASH Storage. + * unsigned int - size of the FLASH Storage. * */ -static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) +static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter) { if (IsFlash2x(Adapter)) return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER); @@ -486,14 +486,14 @@ static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter) * Adapter - ptr to Adapter object instance * * Returns: - * UINT - size of the EEPROM Storage. + * unsigned int - size of the EEPROM Storage. * */ -static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) +static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) { - UINT uiData = 0; - UINT uiIndex = 0; + unsigned int uiData = 0; + unsigned int uiIndex = 0; /* * if EEPROM is present and already Calibrated,it will have @@ -543,12 +543,12 @@ static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) */ static int FlashSectorErase(struct bcm_mini_adapter *Adapter, - UINT addr, - UINT numOfSectors) + unsigned int addr, + unsigned int numOfSectors) { - UINT iIndex = 0, iRetries = 0; - UINT uiStatus = 0; - UINT value; + unsigned int iIndex = 0, iRetries = 0; + unsigned int uiStatus = 0; + unsigned int value; int bytes; for (iIndex = 0; iIndex < numOfSectors; iIndex++) { @@ -604,12 +604,12 @@ static int FlashSectorErase(struct bcm_mini_adapter *Adapter, */ static int flashByteWrite(struct bcm_mini_adapter *Adapter, - UINT uiOffset, + unsigned int uiOffset, PVOID pData) { - UINT uiStatus = 0; + unsigned int uiStatus = 0; int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - UINT value; + unsigned int value; ULONG ulData = *(PUCHAR)pData; int bytes; /* @@ -681,17 +681,17 @@ static int flashByteWrite(struct bcm_mini_adapter *Adapter, */ static int flashWrite(struct bcm_mini_adapter *Adapter, - UINT uiOffset, + unsigned int uiOffset, PVOID pData) { - /* UINT uiStatus = 0; + /* unsigned int uiStatus = 0; * int iRetries = 0; - * UINT uiReadBack = 0; + * unsigned int uiReadBack = 0; */ - UINT uiStatus = 0; + unsigned int uiStatus = 0; int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - UINT value; - UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + unsigned int value; + unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; /* * need not write 0xFFFFFFFF because write requires an erase and erase will @@ -759,13 +759,13 @@ static int flashWrite(struct bcm_mini_adapter *Adapter, * */ static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter, - UINT uiOffset, + unsigned int uiOffset, PVOID pData) { - UINT uiStatus = 0; + unsigned int uiStatus = 0; int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ ULONG ulData = *(PUCHAR)pData; - UINT value; + unsigned int value; int bytes; /* @@ -837,14 +837,14 @@ static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter, */ static int flashWriteStatus(struct bcm_mini_adapter *Adapter, - UINT uiOffset, + unsigned int uiOffset, PVOID pData) { - UINT uiStatus = 0; + unsigned int uiStatus = 0; int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - /* UINT uiReadBack = 0; */ - UINT value; - UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + /* unsigned int uiReadBack = 0; */ + unsigned int value; + unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; int bytes; /* @@ -913,7 +913,7 @@ static int flashWriteStatus(struct bcm_mini_adapter *Adapter, static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) { - UINT value; + unsigned int value; value = (FLASH_CMD_WRITE_ENABLE << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); @@ -936,11 +936,11 @@ static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG * */ -static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOffset, UINT uiLength) +static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength) { ULONG ulStatus = 0; ULONG ulWriteStatus = 0; - UINT value; + unsigned int value; uiOffset = uiOffset&0x000FFFFF; /* @@ -1032,24 +1032,24 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOff static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, + unsigned int uiOffset, + unsigned int uiNumBytes, BOOLEAN bVerify) { PCHAR pTempBuff = NULL; PUCHAR pcBuffer = (PUCHAR)pBuffer; - UINT uiIndex = 0; - UINT uiOffsetFromSectStart = 0; - UINT uiSectAlignAddr = 0; - UINT uiCurrSectOffsetAddr = 0; - UINT uiSectBoundary = 0; - UINT uiNumSectTobeRead = 0; + unsigned int uiIndex = 0; + unsigned int uiOffsetFromSectStart = 0; + unsigned int uiSectAlignAddr = 0; + unsigned int uiCurrSectOffsetAddr = 0; + unsigned int uiSectBoundary = 0; + unsigned int uiNumSectTobeRead = 0; UCHAR ucReadBk[16] = {0}; ULONG ulStatus = 0; int Status = STATUS_SUCCESS; - UINT uiTemp = 0; - UINT index = 0; - UINT uiPartOffset = 0; + unsigned int uiTemp = 0; + unsigned int index = 0; + unsigned int uiPartOffset = 0; #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); @@ -1153,7 +1153,7 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { if (Adapter->ulFlashWriteSize == 1) { - UINT uiReadIndex = 0; + unsigned int uiReadIndex = 0; for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) { if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) { if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) { @@ -1220,24 +1220,24 @@ BeceemFlashBulkWrite_EXIT: static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, + unsigned int uiOffset, + unsigned int uiNumBytes, BOOLEAN bVerify) { PCHAR pTempBuff = NULL; PUCHAR pcBuffer = (PUCHAR)pBuffer; - UINT uiIndex = 0; - UINT uiOffsetFromSectStart = 0; - UINT uiSectAlignAddr = 0; - UINT uiCurrSectOffsetAddr = 0; - UINT uiSectBoundary = 0; - UINT uiNumSectTobeRead = 0; + unsigned int uiIndex = 0; + unsigned int uiOffsetFromSectStart = 0; + unsigned int uiSectAlignAddr = 0; + unsigned int uiCurrSectOffsetAddr = 0; + unsigned int uiSectBoundary = 0; + unsigned int uiNumSectTobeRead = 0; UCHAR ucReadBk[16] = {0}; ULONG ulStatus = 0; - UINT Status = STATUS_SUCCESS; - UINT uiTemp = 0; - UINT index = 0; - UINT uiPartOffset = 0; + unsigned int Status = STATUS_SUCCESS; + unsigned int uiTemp = 0; + unsigned int index = 0; + unsigned int uiPartOffset = 0; uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); @@ -1369,12 +1369,12 @@ BeceemFlashBulkWriteStatus_EXIT: int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); - UINT uiEepromSize = 0; - UINT uiIndex = 0; - UINT uiBytesToCopy = 0; - UINT uiCalStartAddr = EEPROM_CALPARAM_START; - UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - UINT value; + unsigned int uiEepromSize = 0; + unsigned int uiIndex = 0; + unsigned int uiBytesToCopy = 0; + unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; + unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; + unsigned int value; int Status = 0; if (pBuff == NULL) @@ -1430,12 +1430,12 @@ int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) { PCHAR pBuff, pPtr; - UINT uiEepromSize = 0; - UINT uiBytesToCopy = 0; - /* UINT uiIndex = 0; */ - UINT uiCalStartAddr = EEPROM_CALPARAM_START; - UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - UINT value; + unsigned int uiEepromSize = 0; + unsigned int uiBytesToCopy = 0; + /* unsigned int uiIndex = 0; */ + unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; + unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; + unsigned int value; int Status = 0; /* @@ -1507,13 +1507,13 @@ int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) + unsigned int uiOffset, + unsigned int uiNumBytes) { - UINT uiRdbk = 0; - UINT uiIndex = 0; - UINT uiData = 0; - UINT auiData[4] = {0}; + unsigned int uiRdbk = 0; + unsigned int uiIndex = 0; + unsigned int uiData = 0; + unsigned int auiData[4] = {0}; while (uiNumBytes) { if (Adapter->device_removed) @@ -1551,7 +1551,7 @@ static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, } else { /* Handle the reads less than 4 bytes... */ uiData = 0; - memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(UINT)), uiNumBytes); + memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes); BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); if (memcmp(&uiData, &uiRdbk, uiNumBytes)) @@ -1564,9 +1564,9 @@ static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, return 0; } -static VOID BcmSwapWord(UINT *ptr1) +static VOID BcmSwapWord(unsigned int *ptr1) { - UINT tempval = (UINT)*ptr1; + unsigned int tempval = (unsigned int)*ptr1; char *ptr2 = (char *)&tempval; char *ptr = (char *)ptr1; @@ -1590,12 +1590,12 @@ static VOID BcmSwapWord(UINT *ptr1) * */ -static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset) +static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset) { - UINT uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - UINT uiStatus = 0; + unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; + unsigned int uiStatus = 0; UCHAR uiEpromStatus = 0; - UINT value = 0; + unsigned int value = 0; /* Flush the Write/Read/Cmd queues. */ value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH); @@ -1722,16 +1722,16 @@ static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[] int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, PUCHAR pBuffer, - UINT uiOffset, - UINT uiNumBytes, + unsigned int uiOffset, + unsigned int uiNumBytes, BOOLEAN bVerify) { - UINT uiBytesToCopy = uiNumBytes; - /* UINT uiRdbk = 0; */ - UINT uiData[4] = {0}; - UINT uiIndex = 0; - UINT uiTempOffset = 0; - UINT uiExtraBytes = 0; + unsigned int uiBytesToCopy = uiNumBytes; + /* unsigned int uiRdbk = 0; */ + unsigned int uiData[4] = {0}; + unsigned int uiIndex = 0; + unsigned int uiTempOffset = 0; + unsigned int uiExtraBytes = 0; /* PUINT puiBuffer = (PUINT)pBuffer; * int value; */ @@ -1809,13 +1809,13 @@ int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, int BeceemNVMRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes) + unsigned int uiOffset, + unsigned int uiNumBytes) { int Status = 0; #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT uiTemp = 0, value; + unsigned int uiTemp = 0, value; #endif if (Adapter->eNVMType == NVM_FLASH) { @@ -1868,20 +1868,20 @@ int BeceemNVMRead(struct bcm_mini_adapter *Adapter, int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, + unsigned int uiOffset, + unsigned int uiNumBytes, BOOLEAN bVerify) { int Status = 0; - UINT uiTemp = 0; - UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - UINT uiIndex = 0; + unsigned int uiTemp = 0; + unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; + unsigned int uiIndex = 0; #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT value; + unsigned int value; #endif - UINT uiFlashOffset = 0; + unsigned int uiFlashOffset = 0; if (Adapter->eNVMType == NVM_FLASH) { if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) @@ -1975,14 +1975,14 @@ int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, * - if failed. */ -int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize) +int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize) { int Status = -1; FLASH_CS_INFO sFlashCsInfo = {0}; - UINT uiTemp = 0; - UINT uiSectorSig = 0; - UINT uiCurrentSectorSize = 0; - UINT value; + unsigned int uiTemp = 0; + unsigned int uiSectorSig = 0; + unsigned int uiCurrentSectorSize = 0; + unsigned int value; rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); value = 0; @@ -2032,14 +2032,14 @@ Restore: * Adapter - ptr to Adapter object instance * * Returns: - * UINT - sector size. + * unsigned int - sector size. * */ -static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) +static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize) { - UINT uiSectorSize = 0; - UINT uiSectorSig = 0; + unsigned int uiSectorSize = 0; + unsigned int uiSectorSig = 0; if (Adapter->bSectorSizeOverride && (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && @@ -2091,7 +2091,7 @@ static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSe static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) { - UINT value = 0; + unsigned int value = 0; /* CHIP Bug : Clear the Avail bits on the Read queue. The default * value on this register is supposed to be 0x00001102. * But we get 0x00001122. @@ -2202,7 +2202,7 @@ static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) { ULONG ulRDID = 0; - UINT value; + unsigned int value; /* * Read ID Instruction. @@ -2266,7 +2266,7 @@ int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) static int BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) { - UINT Index = 0; + unsigned int Index = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); @@ -2326,7 +2326,7 @@ static int BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bc static int ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) { - UINT Index = 0; + unsigned int Index = 0; psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion); @@ -2383,7 +2383,7 @@ static int ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo) static int ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) { - /* UINT Index = 0; */ + /* unsigned int Index = 0; */ psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion); psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); @@ -2423,7 +2423,7 @@ static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_ static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) { B_UINT32 i = 0; - UINT uiSizeSection = 0; + unsigned int uiSizeSection = 0; Adapter->uiVendorExtnFlag = FALSE; @@ -2512,10 +2512,10 @@ static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) /* FLASH_CS_INFO sFlashCsInfo = {0}; */ #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT value; + unsigned int value; #endif - UINT uiFlashLayoutMajorVersion; + unsigned int uiFlashLayoutMajorVersion; Adapter->uiFlashLayoutMinorVersion = 0; Adapter->uiFlashLayoutMajorVersion = 0; Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; @@ -2631,7 +2631,7 @@ static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter) { - UINT uiData = 0; + unsigned int uiData = 0; BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); if (uiData == BECM) @@ -2848,13 +2848,13 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, PUINT pBuffer, FLASH2X_SECTION_VAL eFlash2xSectionVal, - UINT uiOffsetWithinSectionVal, - UINT uiNumBytes) + unsigned int uiOffsetWithinSectionVal, + unsigned int uiNumBytes) { int Status = STATUS_SUCCESS; int SectionStartOffset = 0; - UINT uiAbsoluteOffset = 0; - UINT uiTemp = 0, value = 0; + unsigned int uiAbsoluteOffset = 0; + unsigned int uiTemp = 0, value = 0; if (Adapter == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); @@ -2910,13 +2910,13 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, PUINT pBuffer, FLASH2X_SECTION_VAL eFlash2xSectVal, - UINT uiOffset, - UINT uiNumBytes, - UINT bVerify) + unsigned int uiOffset, + unsigned int uiNumBytes, + unsigned int bVerify) { int Status = STATUS_SUCCESS; - UINT FlashSectValStartOffset = 0; - UINT uiTemp = 0, value = 0; + unsigned int FlashSectValStartOffset = 0; + unsigned int uiTemp = 0, value = 0; if (Adapter == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); @@ -3040,11 +3040,11 @@ static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter) * */ -B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset) +B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset) { - UINT uiSectorNum = 0; - UINT uiWordOfSectorPermission = 0; - UINT uiBitofSectorePermission = 0; + unsigned int uiSectorNum = 0; + unsigned int uiWordOfSectorPermission = 0; + unsigned int uiBitofSectorePermission = 0; B_UINT32 permissionBits = 0; uiSectorNum = uiOffset/Adapter->uiSectorSize; @@ -3533,14 +3533,14 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS { PCHAR Buff = NULL; FLASH2X_SECTION_VAL eISOReadPart = 0, eISOWritePart = 0; - UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; - UINT uiTotalDataToCopy = 0; + unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; + unsigned int uiTotalDataToCopy = 0; BOOLEAN IsThisHeaderSector = FALSE; - UINT sigOffset = 0; - UINT ISOLength = 0; - UINT Status = STATUS_SUCCESS; - UINT SigBuff[MAX_RW_SIZE]; - UINT i = 0; + unsigned int sigOffset = 0; + unsigned int ISOLength = 0; + unsigned int Status = STATUS_SUCCESS; + unsigned int SigBuff[MAX_RW_SIZE]; + unsigned int i = 0; if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); @@ -3843,8 +3843,8 @@ int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal) { - UINT uiSignature = 0; - UINT uiOffset = 0; + unsigned int uiSignature = 0; + unsigned int uiOffset = 0; /* DSD_HEADER dsdHeader = {0}; */ if (Adapter->bSigCorrupted == FALSE) { @@ -3903,9 +3903,9 @@ int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFl int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite) { - UINT uiNumOfBytes = 0; - UINT uiSectStartOffset = 0; - UINT uiSectEndOffset = 0; + unsigned int uiNumOfBytes = 0; + unsigned int uiSectStartOffset = 0; + unsigned int uiSectEndOffset = 0; uiNumOfBytes = psFlash2xReadWrite->numOfBytes; @@ -3978,7 +3978,7 @@ int IsFlash2x(struct bcm_mini_adapter *Adapter) static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) { - UINT uiBaseAddr = 0; + unsigned int uiBaseAddr = 0; if (Adapter->bDDRInitDone) { /* @@ -4023,11 +4023,11 @@ static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) int BcmCopySection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL SrcSection, FLASH2X_SECTION_VAL DstSection, - UINT offset, - UINT numOfBytes) + unsigned int offset, + unsigned int numOfBytes) { - UINT BuffSize = 0; - UINT BytesToBeCopied = 0; + unsigned int BuffSize = 0; + unsigned int BytesToBeCopied = 0; PUCHAR pBuff = NULL; int Status = STATUS_SUCCESS; @@ -4125,13 +4125,13 @@ int BcmCopySection(struct bcm_mini_adapter *Adapter, * Faillure :- Return negative error code */ -int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset) +int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset) { - UINT offsetToProtect = 0, HeaderSizeToProtect = 0; + unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0; BOOLEAN bHasHeader = FALSE; PUCHAR pTempBuff = NULL; - UINT uiSectAlignAddr = 0; - UINT sig = 0; + unsigned int uiSectAlignAddr = 0; + unsigned int sig = 0; /* making the offset sector aligned */ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); @@ -4190,12 +4190,12 @@ int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiO * OutPut:- * Select the Appropriate chip and retrn status Success */ -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) +static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset) { - UINT FlashConfig = 0; + unsigned int FlashConfig = 0; int ChipNum = 0; - UINT GPIOConfig = 0; - UINT PartNum = 0; + unsigned int GPIOConfig = 0; + unsigned int PartNum = 0; ChipNum = offset / FLASH_PART_SIZE; @@ -4266,8 +4266,8 @@ static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset) int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { - UINT uiDSDsig = 0; - /* UINT sigoffsetInMap = 0; + unsigned int uiDSDsig = 0; + /* unsigned int sigoffsetInMap = 0; * DSD_HEADER dsdHeader = {0}; */ @@ -4291,7 +4291,7 @@ int ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) int ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd) { - /* UINT priOffsetInMap = 0 ; */ + /* unsigned int priOffsetInMap = 0 ; */ unsigned int uiDSDPri = STATUS_FAILURE; /* DSD_HEADER dsdHeader = {0}; * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; @@ -4346,8 +4346,8 @@ FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter) int ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso) { - UINT uiISOsig = 0; - /* UINT sigoffsetInMap = 0; + unsigned int uiISOsig = 0; + /* unsigned int sigoffsetInMap = 0; * ISO_HEADER ISOHeader = {0}; * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; */ @@ -4413,15 +4413,15 @@ FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter) int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, FLASH2X_SECTION_VAL eFlash2xSectionVal, - UINT uiOffset, - UINT uiNumBytes) + unsigned int uiOffset, + unsigned int uiNumBytes) { #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - UINT uiTemp = 0, value = 0; - UINT i = 0; - UINT uiPartOffset = 0; + unsigned int uiTemp = 0, value = 0; + unsigned int i = 0; + unsigned int uiPartOffset = 0; #endif - UINT uiStartOffset = 0; + unsigned int uiStartOffset = 0; /* Adding section start address */ int Status = STATUS_SUCCESS; PUCHAR pcBuff = (PUCHAR)pBuff; @@ -4549,10 +4549,10 @@ int IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Sect static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; - UINT sig = 0; - UINT uiOffset = 0; - UINT BlockStatus = 0; - UINT uiSectAlignAddr = 0; + unsigned int sig = 0; + unsigned int uiOffset = 0; + unsigned int BlockStatus = 0; + unsigned int uiSectAlignAddr = 0; Adapter->bSigCorrupted = FALSE; if (Adapter->bAllDSDWriteAllow == FALSE) { @@ -4611,8 +4611,8 @@ static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; - UINT sig = 0; - UINT uiOffset = 0; + unsigned int sig = 0; + unsigned int uiOffset = 0; Adapter->bSigCorrupted = FALSE; -- GitLab From a2a7ef06de037761dab79e1ed8e62758ddac3201 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 19 Jun 2012 20:14:54 -0400 Subject: [PATCH 2327/6849] Staging: bcm: Change conditions that check for NULL in nvm.c This patch changes all conditions that check for NULL from "if (variable == NULL)" or "if (NULL == variable)" to "if (variable)" to make code more readable. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 14fce106db2c..a85258f901a2 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -1067,7 +1067,7 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (NULL == pTempBuff) + if (!pTempBuff) goto BeceemFlashBulkWrite_EXIT; /* * check if the data to be written is overlapped across sectors @@ -1250,7 +1250,7 @@ static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (NULL == pTempBuff) + if (!pTempBuff) goto BeceemFlashBulkWriteStatus_EXIT; /* @@ -1377,7 +1377,7 @@ int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) unsigned int value; int Status = 0; - if (pBuff == NULL) + if (!pBuff) return -ENOMEM; if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { @@ -2224,7 +2224,7 @@ static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { - if (psAdapter == NULL) { + if (!psAdapter) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } @@ -2235,14 +2235,14 @@ int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) } psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL); - if (psAdapter->psFlash2xCSInfo == NULL) { + if (!psAdapter->psFlash2xCSInfo) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); return -ENOMEM; } psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL); - if (psAdapter->psFlash2xVendorInfo == NULL) { + if (!psAdapter->psFlash2xVendorInfo) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); kfree(psAdapter->psFlash2xCSInfo); @@ -2254,7 +2254,7 @@ int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) { - if (psAdapter == NULL) { + if (!psAdapter) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } @@ -2856,7 +2856,7 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, unsigned int uiAbsoluteOffset = 0; unsigned int uiTemp = 0, value = 0; - if (Adapter == NULL) { + if (!Adapter) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); return -EINVAL; } @@ -2918,7 +2918,7 @@ int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, unsigned int FlashSectValStartOffset = 0; unsigned int uiTemp = 0, value = 0; - if (Adapter == NULL) { + if (!Adapter) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); return -EINVAL; } @@ -3565,7 +3565,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectS Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (Buff == NULL) { + if (!Buff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size"); return -ENOMEM; } @@ -4074,7 +4074,7 @@ int BcmCopySection(struct bcm_mini_adapter *Adapter, BuffSize = numOfBytes; pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL); - if (pBuff == NULL) { + if (!pBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); return -ENOMEM; } @@ -4154,7 +4154,7 @@ int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned /* If Header is present overwrite passed buffer with this */ if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) { pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL); - if (pTempBuff == NULL) { + if (!pTempBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); return -ENOMEM; } @@ -4563,7 +4563,7 @@ static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e } pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (pBuff == NULL) { + if (!pBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); return -ENOMEM; } @@ -4622,7 +4622,7 @@ static int CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL e } pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (pBuff == NULL) { + if (!pBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); return -ENOMEM; } -- GitLab From 85ba24d395620d8a0769bdaa619b32c458603180 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 19 Jun 2012 20:14:55 -0400 Subject: [PATCH 2328/6849] Staging: bcm: Change order in if conditions to make more readable in nvm.c This patch changes the order of several if conditions to make the code more readable. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index a85258f901a2..b179dbab93b5 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -339,7 +339,7 @@ int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, * read function to make the access faster. * We read 4 Dwords of data */ - if (0 == ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4)) { + if (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) { memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE); uiOffset += MAX_RW_SIZE; uiBytesRemaining -= MAX_RW_SIZE; @@ -349,7 +349,7 @@ int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, mdelay(3); /* sleep for a while before retry... */ } } else if (uiBytesRemaining >= 4) { - if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { + if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { memcpy(pcBuff + uiIndex, &uiData[0], 4); uiOffset += 4; uiBytesRemaining -= 4; @@ -362,7 +362,7 @@ int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, /* Handle the reads less than 4 bytes... */ PUCHAR pCharBuff = (PUCHAR)pBuffer; pCharBuff += uiIndex; - if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) { + if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */ uiBytesRemaining = 0; } else { @@ -515,7 +515,7 @@ static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) * EEPROM may not be present or not programmed */ uiData = 0xBABEFACE; - if (0 == BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE)) { + if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) { uiData = 0; for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); -- GitLab From 2f0f8e6a219022e4926afeb9d80a52f156c51918 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 13:50:03 -0700 Subject: [PATCH 2329/6849] staging: comedi: ssv_dnp: remove empty private data The private data struct 'dnp_private_data' contains no information. Remove it and the alloc_private() call. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ssv_dnp.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 72dbccc4427e..84b9f2a4280b 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -59,14 +59,6 @@ struct dnp_board { int have_dio; }; -/* This structure is for data unique to the DNP driver --------------------- */ -struct dnp_private_data { - -}; - -/* Shorthand macro for faster access to the private data ------------------- */ -#define devpriv ((dnp_private *)dev->private) - /* ------------------------------------------------------------------------- */ /* The insn_bits interface allows packed reading/writing of DIO channels. */ /* The comedi core can convert between insn_bits and insn_read/write, so you */ @@ -189,11 +181,6 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - /* Allocate the private structure area. alloc_private() is a */ - /* convenient macro defined in comedidev.h. */ - if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) - return -ENOMEM; - ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; -- GitLab From 069f101fa463351f528773d73b74e9b606b3f66a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 20 Jun 2012 02:31:11 +0100 Subject: [PATCH 2330/6849] staging: zsmalloc: Finish conversion to a separate module ZSMALLOC is tristate, but the code has no MODULE_LICENSE and since it depends on GPL-only symbols it cannot be loaded as a module. This in turn breaks zram which now depends on it. I assume it's meant to be Dual BSD/GPL like the other z-stuff. There is also no module_exit, which will make it impossible to unload. Add the appropriate module_init and module_exit declarations suggested by comments. Reported-by: Christian Ohm References: http://bugs.debian.org/677273 Cc: stable@vger.kernel.org # v3.4 Signed-off-by: Ben Hutchings Reviewed-by: Jonathan Nieder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zsmalloc/zsmalloc-main.c | 33 +++++------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 4af3dd6641c9..10b0d6000260 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -471,12 +471,6 @@ static struct page *find_get_zspage(struct size_class *class) } -/* - * If this becomes a separate module, register zs_init() with - * module_init(), zs_exit with module_exit(), and remove zs_initialized -*/ -static int zs_initialized; - static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action, void *pcpu) { @@ -535,7 +529,7 @@ fail: struct zs_pool *zs_create_pool(const char *name, gfp_t flags) { - int i, error, ovhd_size; + int i, ovhd_size; struct zs_pool *pool; if (!name) @@ -562,28 +556,9 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags) } - /* - * If this becomes a separate module, register zs_init with - * module_init, and remove this block - */ - if (!zs_initialized) { - error = zs_init(); - if (error) - goto cleanup; - zs_initialized = 1; - } - pool->flags = flags; pool->name = name; - error = 0; /* Success */ - -cleanup: - if (error) { - zs_destroy_pool(pool); - pool = NULL; - } - return pool; } EXPORT_SYMBOL_GPL(zs_create_pool); @@ -799,3 +774,9 @@ u64 zs_get_total_size_bytes(struct zs_pool *pool) return npages << PAGE_SHIFT; } EXPORT_SYMBOL_GPL(zs_get_total_size_bytes); + +module_init(zs_init); +module_exit(zs_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Nitin Gupta "); -- GitLab From 62a1efb9f868690d68b11ffb22dc598e547aa184 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Tue, 19 Jun 2012 09:58:54 +0200 Subject: [PATCH 2331/6849] iio: add vcnl4000 combined ALS and proximity sensor minimal driver, no IR current control and proximity/event handling yet v5: * checkpatch warnings * increase msleep() to 20 ms when waiting for data ready as measurement/conversion can take up to 100 ms, 1 ms is too short v4 (address comments by Jonathan Cameron) * remove SENSORS_ prefix in Kconfig * change from IIO_INTENSITY to IIO_LIGHT * move from staging v3 (address comments by Shubhrajyoti Datta) * cleanup Kconfig entry * call I2C read/write functions directly v2 (address comments by Lars-Peter Clausen and Jonathan Cameron) * unify code for reading PS and AL data into parameterized _measure() function * limit wait for data to become ready within 20 tries * drop IIO_LIGHT channel, add SCALE to IIO_INTENSITY * drop extra string arguments used for logging purpose only Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/light/Kconfig | 11 ++ drivers/iio/light/Makefile | 1 + drivers/iio/light/vcnl4000.c | 217 +++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 drivers/iio/light/vcnl4000.c diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index db5618e7d90b..f3ea90d735b8 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -19,4 +19,15 @@ config SENSORS_LM3533 light zone through sysfs. A threshold event can be generated on zone changes. The ALS-control output values can be set per zone for the three current output channels. + +config VCNL4000 + tristate "VCNL4000 combined ALS and proximity sensor" + depends on I2C + help + Say Y here if you want to build a driver for the Vishay VCNL4000 + combined ambient light and proximity sensor. + + To compile this driver as a module, choose M here: the + module will be called vcnl4000. + endmenu diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index c1c23a024cd2..06fa4d3f33ec 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o +obj-$(CONFIG_VCNL4000) += vcnl4000.o diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c new file mode 100644 index 000000000000..e49cb9784a6f --- /dev/null +++ b/drivers/iio/light/vcnl4000.c @@ -0,0 +1,217 @@ +/* + * vcnl4000.c - Support for Vishay VCNL4000 combined ambient light and + * proximity sensor + * + * Copyright 2012 Peter Meerwald + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * IIO driver for VCNL4000 (7-bit I2C slave address 0x13) + * + * TODO: + * allow to adjust IR current + * proximity threshold and event handling + */ + +#include +#include +#include +#include + +#include +#include + +#define VCNL4000_DRV_NAME "vcnl4000" + +#define VCNL4000_COMMAND 0x80 /* Command register */ +#define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */ +#define VCNL4000_LED_CURRENT 0x83 /* IR LED current for proximity mode */ +#define VCNL4000_AL_PARAM 0x84 /* Ambient light parameter register */ +#define VCNL4000_AL_RESULT_HI 0x85 /* Ambient light result register, MSB */ +#define VCNL4000_AL_RESULT_LO 0x86 /* Ambient light result register, LSB */ +#define VCNL4000_PS_RESULT_HI 0x87 /* Proximity result register, MSB */ +#define VCNL4000_PS_RESULT_LO 0x88 /* Proximity result register, LSB */ +#define VCNL4000_PS_MEAS_FREQ 0x89 /* Proximity test signal frequency */ +#define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */ + +/* Bit masks for COMMAND register */ +#define VCNL4000_AL_RDY 0x40 /* ALS data ready? */ +#define VCNL4000_PS_RDY 0x20 /* proximity data ready? */ +#define VCNL4000_AL_OD 0x10 /* start on-demand ALS measurement */ +#define VCNL4000_PS_OD 0x08 /* start on-demand proximity measurement */ + +struct vcnl4000_data { + struct i2c_client *client; +}; + +static const struct i2c_device_id vcnl4000_id[] = { + { "vcnl4000", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, vcnl4000_id); + +static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, + u8 rdy_mask, u8 data_reg, int *val) +{ + int tries = 20; + u16 buf; + int ret; + + ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, + req_mask); + if (ret < 0) + return ret; + + /* wait for data to become ready */ + while (tries--) { + ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND); + if (ret < 0) + return ret; + if (ret & rdy_mask) + break; + msleep(20); /* measurement takes up to 100 ms */ + } + + if (tries < 0) { + dev_err(&data->client->dev, + "vcnl4000_measure() failed, data not ready\n"); + return -EIO; + } + + ret = i2c_smbus_read_i2c_block_data(data->client, + data_reg, sizeof(buf), (u8 *) &buf); + if (ret < 0) + return ret; + + *val = be16_to_cpu(buf); + + return 0; +} + +static const struct iio_chan_spec vcnl4000_channels[] = { + { + .type = IIO_LIGHT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + }, { + .type = IIO_PROXIMITY, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + } +}; + +static int vcnl4000_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret = -EINVAL; + struct vcnl4000_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_LIGHT: + ret = vcnl4000_measure(data, + VCNL4000_AL_OD, VCNL4000_AL_RDY, + VCNL4000_AL_RESULT_HI, val); + if (ret < 0) + return ret; + ret = IIO_VAL_INT; + break; + case IIO_PROXIMITY: + ret = vcnl4000_measure(data, + VCNL4000_PS_OD, VCNL4000_PS_RDY, + VCNL4000_PS_RESULT_HI, val); + if (ret < 0) + return ret; + ret = IIO_VAL_INT; + break; + default: + break; + } + break; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_LIGHT) { + *val = 0; + *val2 = 250000; + ret = IIO_VAL_INT_PLUS_MICRO; + } + break; + default: + break; + } + + return ret; +} + +static const struct iio_info vcnl4000_info = { + .read_raw = vcnl4000_read_raw, + .driver_module = THIS_MODULE, +}; + +static int __devinit vcnl4000_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct vcnl4000_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = iio_device_alloc(sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV); + if (ret < 0) + goto error_free_dev; + + dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n", + ret >> 4, ret & 0xf); + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &vcnl4000_info; + indio_dev->channels = vcnl4000_channels; + indio_dev->num_channels = ARRAY_SIZE(vcnl4000_channels); + indio_dev->name = VCNL4000_DRV_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(indio_dev); + if (ret < 0) + goto error_free_dev; + + return 0; + +error_free_dev: + iio_device_free(indio_dev); + return ret; +} + +static int __devexit vcnl4000_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + iio_device_free(indio_dev); + + return 0; +} + +static struct i2c_driver vcnl4000_driver = { + .driver = { + .name = VCNL4000_DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = vcnl4000_probe, + .remove = __devexit_p(vcnl4000_remove), + .id_table = vcnl4000_id, +}; + +module_i2c_driver(vcnl4000_driver); + +MODULE_AUTHOR("Peter Meerwald "); +MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver"); +MODULE_LICENSE("GPL"); -- GitLab From 924d37118f9e18825294b2012a10c6245d6c25e1 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 18 Jun 2012 19:15:50 -0700 Subject: [PATCH 2332/6849] pstore/ram: Probe as early as possible Registering the platform driver before module_init allows us to log oopses that happen during device probing. This requires changing module_init to postcore_initcall, and switching from platform_driver_probe to platform_driver_register because the platform device is not registered when the platform driver is registered; and because we use driver_register, now can't use create_bundle() (since it will try to register the same driver once again), so we have to switch to platform_device_register_data(). Also, some __init -> __devinit changes were needed. Overall, the registration logic is now much clearer, since we have only one driver registration point, and just an optional dummy device, which is created from the module parameters. Suggested-by: Colin Cross Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 63 +++++++++++++++++++------------------- fs/pstore/ram_core.c | 9 +++--- include/linux/pstore_ram.h | 6 ++-- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index c7acf94ff475..0b36e91978e6 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -330,7 +330,7 @@ static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt, return 0; } -static int __init ramoops_probe(struct platform_device *pdev) +static int __devinit ramoops_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ramoops_platform_data *pdata = pdev->dev.platform_data; @@ -452,6 +452,7 @@ static int __exit ramoops_remove(struct platform_device *pdev) } static struct platform_driver ramoops_driver = { + .probe = ramoops_probe, .remove = __exit_p(ramoops_remove), .driver = { .name = "ramoops", @@ -459,46 +460,46 @@ static struct platform_driver ramoops_driver = { }, }; -static int __init ramoops_init(void) +static void ramoops_register_dummy(void) { - int ret; - ret = platform_driver_probe(&ramoops_driver, ramoops_probe); - if (ret == -ENODEV) { - /* - * If we didn't find a platform device, we use module parameters - * building platform data on the fly. - */ - pr_info("platform device not found, using module parameters\n"); - dummy_data = kzalloc(sizeof(struct ramoops_platform_data), - GFP_KERNEL); - if (!dummy_data) - return -ENOMEM; - dummy_data->mem_size = mem_size; - dummy_data->mem_address = mem_address; - dummy_data->record_size = record_size; - dummy_data->console_size = ramoops_console_size; - dummy_data->dump_oops = dump_oops; - dummy_data->ecc = ramoops_ecc; - dummy = platform_create_bundle(&ramoops_driver, ramoops_probe, - NULL, 0, dummy_data, - sizeof(struct ramoops_platform_data)); - - if (IS_ERR(dummy)) - ret = PTR_ERR(dummy); - else - ret = 0; + if (!mem_size) + return; + + pr_info("using module parameters\n"); + + dummy_data = kzalloc(sizeof(*dummy_data), GFP_KERNEL); + if (!dummy_data) { + pr_info("could not allocate pdata\n"); + return; } - return ret; + dummy_data->mem_size = mem_size; + dummy_data->mem_address = mem_address; + dummy_data->record_size = record_size; + dummy_data->console_size = ramoops_console_size; + dummy_data->dump_oops = dump_oops; + dummy_data->ecc = ramoops_ecc; + + dummy = platform_device_register_data(NULL, "ramoops", -1, + dummy_data, sizeof(struct ramoops_platform_data)); + if (IS_ERR(dummy)) { + pr_info("could not create platform device: %ld\n", + PTR_ERR(dummy)); + } +} + +static int __init ramoops_init(void) +{ + ramoops_register_dummy(); + return platform_driver_register(&ramoops_driver); } +postcore_initcall(ramoops_init); static void __exit ramoops_exit(void) { platform_driver_unregister(&ramoops_driver); kfree(dummy_data); } - -module_init(ramoops_init); module_exit(ramoops_exit); MODULE_LICENSE("GPL"); diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 0fd81611525c..26531856daf8 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -390,7 +390,8 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, return 0; } -static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool ecc) +static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, + bool ecc) { int ret; @@ -436,9 +437,9 @@ void persistent_ram_free(struct persistent_ram_zone *prz) kfree(prz); } -struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, - size_t size, - bool ecc) +struct persistent_ram_zone * __devinit persistent_ram_new(phys_addr_t start, + size_t size, + bool ecc) { struct persistent_ram_zone *prz; int ret = -ENOMEM; diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 2470bb591434..e681af92c04b 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -48,9 +48,9 @@ struct persistent_ram_zone { size_t old_log_size; }; -struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, - size_t size, - bool ecc); +struct persistent_ram_zone * __devinit persistent_ram_new(phys_addr_t start, + size_t size, + bool ecc); void persistent_ram_free(struct persistent_ram_zone *prz); void persistent_ram_zap(struct persistent_ram_zone *prz); -- GitLab From 90b58d96907e0a45555429c0d3a79c85cea4b9fc Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 18 Jun 2012 19:15:51 -0700 Subject: [PATCH 2333/6849] pstore/ram: Fix error handling during przs allocation persistent_ram_new() returns ERR_PTR() value on errors, so during freeing of the przs we should check for both NULL and IS_ERR() entries, otherwise bad things will happen. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 0b36e91978e6..58b93fbd117e 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -260,7 +260,7 @@ static void ramoops_free_przs(struct ramoops_context *cxt) if (!cxt->przs) return; - for (i = 0; cxt->przs[i]; i++) + for (i = 0; !IS_ERR_OR_NULL(cxt->przs[i]); i++) persistent_ram_free(cxt->przs[i]); kfree(cxt->przs); } -- GitLab From beeb94321a7a6d493b4a06ff0cd771f09f41c35e Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 18 Jun 2012 19:15:52 -0700 Subject: [PATCH 2334/6849] pstore/ram_core: Proper checking for post_init errors (e.g. improper ECC size) We will implement variable-sized ECC buffers soon, so post_init routine might fail much more likely, so we'd better check for its errors. To make error handling simple, modify persistent_ram_free() to it be safe at all times. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram_core.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 26531856daf8..f62ebf2dfed7 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -427,11 +427,17 @@ static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, void persistent_ram_free(struct persistent_ram_zone *prz) { - if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { - vunmap(prz->vaddr); - } else { - iounmap(prz->vaddr); - release_mem_region(prz->paddr, prz->size); + if (!prz) + return; + + if (prz->vaddr) { + if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { + vunmap(prz->vaddr); + } else { + iounmap(prz->vaddr); + release_mem_region(prz->paddr, prz->size); + } + prz->vaddr = NULL; } persistent_ram_free_old(prz); kfree(prz); @@ -454,10 +460,12 @@ struct persistent_ram_zone * __devinit persistent_ram_new(phys_addr_t start, if (ret) goto err; - persistent_ram_post_init(prz, ecc); + ret = persistent_ram_post_init(prz, ecc); + if (ret) + goto err; return prz; err: - kfree(prz); + persistent_ram_free(prz); return ERR_PTR(ret); } -- GitLab From 1e6a9e56252399ae8c143f2327b4bb8cd289c3d5 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 18 Jun 2012 19:15:53 -0700 Subject: [PATCH 2335/6849] pstore/ram_core: Better ECC size checking - Instead of exploiting unsigned overflows (which doesn't work for all sizes), use straightforward checking for ECC total size not exceeding initial buffer size; - Printing overflowed buffer_size is not informative. Instead, print ecc_size and buffer_size; - No need for buffer_size argument in persistent_ram_init_ecc(), we can address prz->buffer_size directly. Signed-off-by: Anton Vorontsov Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram_core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f62ebf2dfed7..a5a7b13d358c 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -171,12 +171,12 @@ static void persistent_ram_ecc_old(struct persistent_ram_zone *prz) } } -static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, - size_t buffer_size) +static int persistent_ram_init_ecc(struct persistent_ram_zone *prz) { int numerr; struct persistent_ram_buffer *buffer = prz->buffer; int ecc_blocks; + size_t ecc_total; if (!prz->ecc) return 0; @@ -187,14 +187,14 @@ static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, prz->ecc_poly = 0x11d; ecc_blocks = DIV_ROUND_UP(prz->buffer_size, prz->ecc_block_size); - prz->buffer_size -= (ecc_blocks + 1) * prz->ecc_size; - - if (prz->buffer_size > buffer_size) { - pr_err("persistent_ram: invalid size %zu, non-ecc datasize %zu\n", - buffer_size, prz->buffer_size); + ecc_total = (ecc_blocks + 1) * prz->ecc_size; + if (ecc_total >= prz->buffer_size) { + pr_err("%s: invalid ecc_size %u (total %zu, buffer size %zu)\n", + __func__, prz->ecc_size, ecc_total, prz->buffer_size); return -EINVAL; } + prz->buffer_size -= ecc_total; prz->par_buffer = buffer->data + prz->buffer_size; prz->par_header = prz->par_buffer + ecc_blocks * prz->ecc_size; @@ -397,7 +397,7 @@ static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, prz->ecc = ecc; - ret = persistent_ram_init_ecc(prz, prz->buffer_size); + ret = persistent_ram_init_ecc(prz); if (ret) return ret; -- GitLab From 996a776544cc8a71653ffa95a89c317f33d2cb4a Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Tue, 19 Jun 2012 10:34:06 -0400 Subject: [PATCH 2336/6849] USB: serial: Remove unused s_priv variable s_priv was set but never used in keyspan_open() and keyspan_close(), remove it. This also makes the serial variable in keyspan_open() unused since it's only use was to set s_priv, so it is also removed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index a1b99243dac9..9a0ca8355905 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -1036,15 +1036,12 @@ static int keyspan_write_room(struct tty_struct *tty) static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port) { struct keyspan_port_private *p_priv; - struct keyspan_serial_private *s_priv; - struct usb_serial *serial = port->serial; const struct keyspan_device_details *d_details; int i, err; int baud_rate, device_port; struct urb *urb; unsigned int cflag = 0; - s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; @@ -1130,10 +1127,8 @@ static void keyspan_close(struct usb_serial_port *port) { int i; struct usb_serial *serial = port->serial; - struct keyspan_serial_private *s_priv; struct keyspan_port_private *p_priv; - s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); p_priv->rts_state = 0; -- GitLab From c50f2af8e1a33e95e4d3b7af9db05ed9096c6072 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Tue, 19 Jun 2012 10:34:07 -0400 Subject: [PATCH 2337/6849] USB: serial: Remove unused serial_priv variable qt2_open() and qt2_close() both set a serial_priv variable but never used it. Remove the variable from the functions. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/quatech2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 8dd88ebe9863..151670b6b72a 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -345,7 +345,6 @@ static void qt2_set_termios(struct tty_struct *tty, static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) { struct usb_serial *serial; - struct qt2_serial_private *serial_priv; struct qt2_port_private *port_priv; u8 *data; u16 device_port; @@ -357,7 +356,6 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) serial = port->serial; port_priv = usb_get_serial_port_data(port); - serial_priv = usb_get_serial_data(serial); /* set the port to RS232 mode */ status = qt2_control_msg(serial->dev, QT2_GET_SET_QMCR, @@ -417,13 +415,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) static void qt2_close(struct usb_serial_port *port) { struct usb_serial *serial; - struct qt2_serial_private *serial_priv; struct qt2_port_private *port_priv; unsigned long flags; int i; serial = port->serial; - serial_priv = usb_get_serial_data(serial); port_priv = usb_get_serial_port_data(port); port_priv->is_open = false; -- GitLab From 1a86e156e249e5d5c7b8dd4bf93701bb6ccb3cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jun 2012 11:53:23 +0200 Subject: [PATCH 2338/6849] USB: cdc-wdm: QMI devices are now handled by qmi_wwan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qmi_wwan has been changed to drive both the control and data interface for all QMI/wwan devices, using cdc-wdm as a subdriver. Remove the stale device ID entries from cdc-wdm. >From now on new QMI/wwan devices will only need to be added to the qmi_wwan driver, regardless of the USB descriptor layout Note that this is not appropriate for stable/longterm kernels despite being a device ID patch. Cc: Oliver Neukum Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8fd398dffced..25e7d72f339e 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -32,8 +32,6 @@ #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" -#define HUAWEI_VENDOR_ID 0x12D1 - static const struct usb_device_id wdm_ids[] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | @@ -41,29 +39,6 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM }, - { - /* - * Huawei E392, E398 and possibly other Qualcomm based modems - * embed the Qualcomm QMI protocol inside CDC on CDC ECM like - * control interfaces. Userspace access to this is required - * to configure the accompanying data interface - */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | - USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = HUAWEI_VENDOR_ID, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ - }, - { - /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | - USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = HUAWEI_VENDOR_ID, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 57, /* NOTE: CDC ECM control interface! */ - }, { } }; -- GitLab From 78091dc2f6f04b03131218df590c877cadcd9379 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 20 Jun 2012 09:02:23 -0300 Subject: [PATCH 2339/6849] USB: ohci-nxp: add usbd and otg clock initialization The ohci-nxp was assuming the clock was enabled by the board init or bootloader and just enabling the pll. This enables the usbd and otg clocks this periferal also needs. Signed-off-by: Alexandre Pereira da Silva Acked-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-nxp.c | 88 +++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 1e364ec962fb..a446386bf779 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -43,16 +43,6 @@ #define USB_HOST_NEED_CLK_EN (1 << 21) #define PAD_CONTROL_LAST_DRIVEN (1 << 19) -#define USB_OTG_CLK_CTRL IO_ADDRESS(USB_CONFIG_BASE + 0xFF4) -#define USB_OTG_CLK_STAT IO_ADDRESS(USB_CONFIG_BASE + 0xFF8) - -/* USB_OTG_CLK_CTRL bit defines */ -#define AHB_M_CLOCK_ON (1 << 4) -#define OTG_CLOCK_ON (1 << 3) -#define I2C_CLOCK_ON (1 << 2) -#define DEV_CLOCK_ON (1 << 1) -#define HOST_CLOCK_ON (1 << 0) - #define USB_OTG_STAT_CONTROL IO_ADDRESS(USB_CONFIG_BASE + 0x110) /* USB_OTG_STAT_CONTROL bit defines */ @@ -72,7 +62,9 @@ static struct i2c_client *isp1301_i2c_client; extern int usb_disabled(void); -static struct clk *usb_clk; +static struct clk *usb_pll_clk; +static struct clk *usb_dev_clk; +static struct clk *usb_otg_clk; static void isp1301_configure_pnx4008(void) { @@ -249,8 +241,6 @@ static const struct hc_driver ohci_nxp_hc_driver = { .start_port_reset = ohci_start_port_reset, }; -#define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON) - static void nxp_set_usb_bits(void) { if (machine_is_pnx4008()) { @@ -327,41 +317,63 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) /* Enable AHB slave USB clock, needed for further USB clock control */ __raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL); - isp1301_configure(); - /* Enable USB PLL */ - usb_clk = clk_get(&pdev->dev, "ck_pll5"); - if (IS_ERR(usb_clk)) { + usb_pll_clk = clk_get(&pdev->dev, "ck_pll5"); + if (IS_ERR(usb_pll_clk)) { dev_err(&pdev->dev, "failed to acquire USB PLL\n"); - ret = PTR_ERR(usb_clk); + ret = PTR_ERR(usb_pll_clk); goto out1; } - ret = clk_enable(usb_clk); + ret = clk_enable(usb_pll_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB PLL\n"); goto out2; } - ret = clk_set_rate(usb_clk, 48000); + ret = clk_set_rate(usb_pll_clk, 48000); if (ret < 0) { dev_err(&pdev->dev, "failed to set USB clock rate\n"); goto out3; } + /* Enable USB device clock */ + usb_dev_clk = clk_get(&pdev->dev, "ck_usbd"); + if (IS_ERR(usb_dev_clk)) { + dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); + ret = PTR_ERR(usb_dev_clk); + goto out4; + } + + ret = clk_enable(usb_dev_clk); + if (ret < 0) { + dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); + goto out5; + } + + /* Enable USB otg clocks */ + usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); + if (IS_ERR(usb_otg_clk)) { + dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); + ret = PTR_ERR(usb_dev_clk); + goto out6; + } + __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); - /* Set to enable all needed USB clocks */ - __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); + ret = clk_enable(usb_otg_clk); + if (ret < 0) { + dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); + goto out7; + } - while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != - USB_CLOCK_MASK) ; + isp1301_configure(); hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); ret = -ENOMEM; - goto out3; + goto out8; } /* Set all USB bits in the Start Enable register */ @@ -371,14 +383,14 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "Failed to get MEM resource\n"); ret = -ENOMEM; - goto out4; + goto out8; } hcd->regs = devm_request_and_ioremap(&pdev->dev, res); if (!hcd->regs) { dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n"); ret = -ENOMEM; - goto out4; + goto out8; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); @@ -386,7 +398,7 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENXIO; - goto out4; + goto out8; } nxp_start_hc(); @@ -400,13 +412,21 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) return ret; nxp_stop_hc(); -out4: +out8: nxp_unset_usb_bits(); usb_put_hcd(hcd); +out7: + clk_disable(usb_otg_clk); +out6: + clk_put(usb_otg_clk); +out5: + clk_disable(usb_dev_clk); +out4: + clk_put(usb_dev_clk); out3: - clk_disable(usb_clk); + clk_disable(usb_pll_clk); out2: - clk_put(usb_clk); + clk_put(usb_pll_clk); out1: isp1301_i2c_client = NULL; out: @@ -422,8 +442,10 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev) release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); nxp_unset_usb_bits(); - clk_disable(usb_clk); - clk_put(usb_clk); + clk_disable(usb_pll_clk); + clk_put(usb_pll_clk); + clk_disable(usb_dev_clk); + clk_put(usb_dev_clk); i2c_unregister_device(isp1301_i2c_client); isp1301_i2c_client = NULL; -- GitLab From 8291550f8479fde2cee571d1b367e6918819f189 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 19 Jun 2012 07:35:34 -0600 Subject: [PATCH 2340/6849] PCI: fix upstream P2P bridge checks when enabling OBFF and LTR pci_enable_obff() and pci_enable_ltr() incorrectly check "dev->bus" instead of "dev->bus->self" to determine whether the upstream device is a P2P bridge or a host bridge. For devices on the root bus, the upstream device is a host bridge, "dev->bus != NULL" and "dev->bus->self == NULL", and we panic with a null pointer dereference. These functions should previously have panicked when called on devices supporting OBFF or LTR, so they should be regarded as untested. Found by Coverity (CID 143038 and CID 143039). Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8f4a5ea543fc..b9e93cf1eb40 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2108,7 +2108,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) return -ENOTSUPP; /* no OBFF support at all */ /* Make sure the topology supports OBFF as well */ - if (dev->bus) { + if (dev->bus->self) { ret = pci_enable_obff(dev->bus->self, type); if (ret) return ret; @@ -2215,7 +2215,7 @@ int pci_enable_ltr(struct pci_dev *dev) return -EINVAL; /* Enable upstream ports first */ - if (dev->bus) { + if (dev->bus->self) { ret = pci_enable_ltr(dev->bus->self); if (ret) return ret; -- GitLab From 8f38eaca55d0fab7499b33adb1dec33e16de5abb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 19 Jun 2012 07:45:44 -0600 Subject: [PATCH 2341/6849] PCI: fix P2P bridge I/O port window sign extension On P2P bridges with 32-bit I/O decoding, we incorrectly sign-extended windows starting at 0x80000000 or above. In "base |= (io_base_hi << 16)", "io_base_hi" is promoted to a signed int before being extended to an unsigned long. This would cause a window starting at I/O address 0x80000000 to be treated as though it started at 0xffffffff80008000 instead, which should cause "no compatible bridge window" errors when we enumerate devices using that I/O space. The mmio and mmio_pref casts are not strictly necessary, but without them, correctness depends on the types of the PCI_MEMORY_RANGE_MASK and PCI_PREF_RANGE_MASK constants, which are not obvious from reading the local code. Found by Coverity (CID 138747 and CID 138748). Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 658ac977cb56..a7a504fc82b9 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -281,10 +281,11 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { u16 io_base_hi, io_limit_hi; + pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); - base |= (io_base_hi << 16); - limit |= (io_limit_hi << 16); + base |= ((unsigned long) io_base_hi << 16); + limit |= ((unsigned long) io_limit_hi << 16); } if (base && base <= limit) { @@ -312,8 +313,8 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) res = child->resource[1]; pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); - base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; - limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; + base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; + limit = ((unsigned long) mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; if (base && base <= limit) { res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; region.start = base; @@ -334,11 +335,12 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) res = child->resource[2]; pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); - base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; - limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; + base = ((unsigned long) mem_base_lo & PCI_PREF_RANGE_MASK) << 16; + limit = ((unsigned long) mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { u32 mem_base_hi, mem_limit_hi; + pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); @@ -349,8 +351,8 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) */ if (mem_base_hi <= mem_limit_hi) { #if BITS_PER_LONG == 64 - base |= ((long) mem_base_hi) << 32; - limit |= ((long) mem_limit_hi) << 32; + base |= ((unsigned long) mem_base_hi) << 32; + limit |= ((unsigned long) mem_limit_hi) << 32; #else if (mem_base_hi || mem_limit_hi) { dev_err(&dev->dev, "can't handle 64-bit " -- GitLab From 67454b6602c3519d15193630e6765a5f02f39160 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 20 Jun 2012 16:11:45 -0600 Subject: [PATCH 2342/6849] PCI: shpchp: remove dead code "slots_not_empty" is initialized to zero and can't be set again before reaching this point, so this return statement is dead. Remove it. Found by Coverity (CID 114324). Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/shpchp_ctrl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b00b09bdd38a..f9b5a52e4115 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -262,9 +262,6 @@ static int board_added(struct slot *p_slot) } if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { - if (slots_not_empty) - return WRONG_BUS_FREQUENCY; - if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { ctrl_err(ctrl, "%s: Issue of set bus speed mode command" " failed\n", __func__); -- GitLab From dfb117b3e50c52c7b3416db4a4569224b8db80bb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 20 Jun 2012 16:18:29 -0600 Subject: [PATCH 2343/6849] PCI: acpiphp: check whether _ADR evaluation succeeded Check whether we evaluated _ADR successfully. Previously we ignored failure, so we would have used garbage data from the stack as the device and function number. We return AE_OK so that we ignore only this slot and continue looking for other slots. Found by Coverity (CID 113981). Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 806c44fa645a..09bf37721842 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -132,6 +132,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; + status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); + if (ACPI_FAILURE(status)) { + warn("can't evaluate _ADR (%#x)\n", status); + return AE_OK; + } + + device = (adr >> 16) & 0xffff; + function = adr & 0xffff; + pdev = pbus->self; if (pdev && pci_is_pcie(pdev)) { tmp = acpi_find_root_bridge_handle(pdev); @@ -144,10 +153,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } } - acpi_evaluate_integer(handle, "_ADR", NULL, &adr); - device = (adr >> 16) & 0xffff; - function = adr & 0xffff; - newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); if (!newfunc) return AE_NO_MEMORY; -- GitLab From 809a3bf9f34cb6d0c0383b31b3495fa1ed3508a6 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 20 Jun 2012 16:41:16 -0600 Subject: [PATCH 2344/6849] PCI: remove useless pcix_set_mmrbc() dev->bus check For a valid pci_dev, dev->bus != NULL always, so remove this unnecessary test. Found by Coverity (CID 101680). Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b9e93cf1eb40..7f1310e58534 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3395,8 +3395,7 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) o = (cmd & PCI_X_CMD_MAX_READ) >> 2; if (o != v) { - if (v > o && dev->bus && - (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC)) + if (v > o && (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC)) return -EIO; cmd &= ~PCI_X_CMD_MAX_READ; -- GitLab From d20411588d2f47ded7b0a02ed1005c7e3ce0df40 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:34 +0300 Subject: [PATCH 2345/6849] mei: check for error codes that mei_flow_ctrl_creds retuns we cannot use if(!mei_flow_ctrl_creds()) logic as mei_flow_ctrl_creds also negative error codes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 93936f1b75eb..83e80bc08d77 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1326,7 +1326,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, continue; if (cl != &dev->iamthif_cl) { - if (!mei_flow_ctrl_creds(dev, cl)) { + if (mei_flow_ctrl_creds(dev, cl) <= 0) { dev_dbg(&dev->pdev->dev, "No flow control" " credentials for client" @@ -1343,7 +1343,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, } else if (cl == &dev->iamthif_cl) { /* IAMTHIF IOCTL */ dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); - if (!mei_flow_ctrl_creds(dev, cl)) { + if (mei_flow_ctrl_creds(dev, cl) <= 0) { dev_dbg(&dev->pdev->dev, "No flow control" " credentials for amthi" -- GitLab From 169d1338ed4ed91412761a77095a13b9992993ba Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:35 +0300 Subject: [PATCH 2346/6849] mei: make mei_write_message more readable 1. reduce hairy casting 2. replace open code with mei_count_empty_write_slots 4. include header size in check for overflow 3. use concise for loop instead of a while loop Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interface.c | 49 +++++++++++++----------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 428d21e36416..6c0569177646 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -127,52 +127,39 @@ int mei_count_empty_write_slots(struct mei_device *dev) * * This function returns -EIO if write has failed */ -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length) +int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, + unsigned char *buf, unsigned long length) { - u32 temp_msg = 0; - unsigned long bytes_written = 0; - unsigned char buffer_depth, filled_slots, empty_slots; - unsigned long dw_to_write; - - dev->host_hw_state = mei_hcsr_read(dev); + unsigned long rem, dw_cnt; + u32 *reg_buf = (u32 *)buf; + int i; + int empty_slots; - dev_dbg(&dev->pdev->dev, - "host_hw_state = 0x%08x.\n", - dev->host_hw_state); dev_dbg(&dev->pdev->dev, "mei_write_message header=%08x.\n", *((u32 *) header)); - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - dev_dbg(&dev->pdev->dev, - "filled = %hu, empty = %hu.\n", - filled_slots, empty_slots); - - dw_to_write = ((write_length + 3) / 4); + empty_slots = mei_count_empty_write_slots(dev); + dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); - if (dw_to_write > empty_slots) + dw_cnt = (length + sizeof(*header) + 3) / 4; + if (empty_slots < 0 || dw_cnt > empty_slots) return -EIO; mei_reg_write(dev, H_CB_WW, *((u32 *) header)); - while (write_length >= 4) { - mei_reg_write(dev, H_CB_WW, - *(u32 *) (write_buffer + bytes_written)); - bytes_written += 4; - write_length -= 4; - } + for (i = 0; i < length / 4; i++) + mei_reg_write(dev, H_CB_WW, reg_buf[i]); - if (write_length > 0) { - memcpy(&temp_msg, &write_buffer[bytes_written], write_length); - mei_reg_write(dev, H_CB_WW, temp_msg); + rem = length & 0x3; + if (rem > 0) { + u32 reg = 0; + memcpy(®, &buf[length - rem], rem); + mei_reg_write(dev, H_CB_WW, reg); } + dev->host_hw_state = mei_hcsr_read(dev); dev->host_hw_state |= H_IG; mei_hcsr_set(dev); dev->me_hw_state = mei_mecsr_read(dev); -- GitLab From 7d5e0e59542ac452585e3a33abcad6e26b4dec4a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:36 +0300 Subject: [PATCH 2347/6849] mei: mei_irq_thread_write_handler check for overflow check for overflow when retrieving empty write slots Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 83e80bc08d77..8e4dd74b96e5 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1204,6 +1204,9 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, return 0; } *slots = mei_count_empty_write_slots(dev); + if (*slots <= 0) + return -EMSGSIZE; + /* complete all waiting for write CB */ dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); -- GitLab From 21c66d1be7c586b56c2902ada4ba030a12b00063 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:37 +0300 Subject: [PATCH 2348/6849] mei: group wd_interface_reg with watchdog variables within struct mei_device Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/mei_dev.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 63d7ee97c5fb..4fe653392a49 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -237,6 +237,7 @@ struct mei_device { bool mei_host_buffer_is_empty; struct mei_cl wd_cl; + bool wd_interface_reg; bool wd_pending; bool wd_stopped; bool wd_bypass; /* if false, don't refresh watchdog ME client */ @@ -245,7 +246,6 @@ struct mei_device { unsigned char wd_data[MEI_START_WD_DATA_SIZE]; - struct file *iamthif_file_object; struct mei_cl iamthif_cl; struct mei_cl_cb *iamthif_current_cb; @@ -259,8 +259,6 @@ struct mei_device { bool iamthif_flow_control_pending; bool iamthif_ioctl; bool iamthif_canceled; - - bool wd_interface_reg; }; -- GitLab From 1e2c4e59d2b8797973471b4a287a43eac12a0f40 Mon Sep 17 00:00:00 2001 From: Dmitry Shmygov Date: Wed, 20 Jun 2012 15:51:40 +0400 Subject: [PATCH 2349/6849] USB: option: add id for Cellient MEN-200 Add vendor and product ID to option.c driver for Cellient MEN-200 EVDO Rev.B 450MHz data module. http://cellient.com Signed-off-by: Dmitry Shmygov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e668a2460bd4..396d968dddd9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -497,6 +497,10 @@ static void option_instat_callback(struct urb *urb); /* MediaTek products */ #define MEDIATEK_VENDOR_ID 0x0e8d +/* Cellient products */ +#define CELLIENT_VENDOR_ID 0x2692 +#define CELLIENT_PRODUCT_MEN200 0x9005 + /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -1233,6 +1237,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- GitLab From 8f748e20b8060317bf56f7a8afa6e24047a38cdb Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Wed, 20 Jun 2012 17:02:30 +0900 Subject: [PATCH 2350/6849] ARM: SAMSUNG: Remove unused variable 'running' on PWM This variable is indeed no longer in use. Signed-off-by: Jonghwan Choi Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/pwm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c index c559d8438c70..d3583050fb05 100644 --- a/arch/arm/plat-samsung/pwm.c +++ b/arch/arm/plat-samsung/pwm.c @@ -36,7 +36,6 @@ struct pwm_device { unsigned int duty_ns; unsigned char tcon_base; - unsigned char running; unsigned char use_count; unsigned char pwm_id; }; @@ -116,7 +115,6 @@ int pwm_enable(struct pwm_device *pwm) local_irq_restore(flags); - pwm->running = 1; return 0; } @@ -134,8 +132,6 @@ void pwm_disable(struct pwm_device *pwm) __raw_writel(tcon, S3C2410_TCON); local_irq_restore(flags); - - pwm->running = 0; } EXPORT_SYMBOL(pwm_disable); -- GitLab From e5a7286b5f1b0b5beb97275f2152bf10c4aa4204 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 21 Jun 2012 00:16:29 +0200 Subject: [PATCH 2351/6849] x86, boot: Remove ancient, unconditionally #ifdef'd out dead code Release v1.3.82 wrapped a few lines of code in an "#ifdef SAFE_RESET_DISK_CONTROLLER" and "#endif" pair. Since SAFE_RESET_DISK_CONTROLLER was never defined anywhere that was basically a verbose "#ifdef 0" and "#endif" pair. These dead lines have been in the tree for sixteen years but now the time has come to remove them. I guess the main lesson here is that if you want your dead code in the tree for a very long time you'd better be creative. A plain old "#ifdef 0" and "#endif" pair just doesn't cut it! See: http://lkml.kernel.org/r/199603301718.LAA00178@craie.inetnebr.com Signed-off-by: Paul Bolle Link: http://lkml.kernel.org/r/1340230589.1773.7.camel@x61.thuisdomein Acked-by: Jeff Epler Acked-by: Jesper Juhl Signed-off-by: H. Peter Anvin --- arch/x86/boot/header.S | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 8bbea6aa40d9..fde5bde3b605 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -386,13 +386,6 @@ init_size: .long INIT_SIZE # kernel initialization size .section ".entrytext", "ax" start_of_setup: -#ifdef SAFE_RESET_DISK_CONTROLLER -# Reset the disk controller. - movw $0x0000, %ax # Reset disk controller - movb $0x80, %dl # All disks - int $0x13 -#endif - # Force %es = %ds movw %ds, %ax movw %ax, %es -- GitLab From 745664ebe0a97237fb026d2c0aa1c689f9395f0c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:01 +0300 Subject: [PATCH 2352/6849] dw_dmac: fix constant in the comment Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index f298f69ecbf9..e248481ad5f1 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h @@ -82,7 +82,7 @@ struct dw_dma_regs { DW_REG(ID); DW_REG(TEST); - /* optional encoded params, 0x3c8..0x3 */ + /* optional encoded params, 0x3c8..0x3f7 */ }; /* Bitfields in CTL_LO */ -- GitLab From 2f45d613ffae00d3355de7871d9cbfd0f2292971 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:02 +0300 Subject: [PATCH 2353/6849] dw_dmac: use proper casting to print dma_addr_t values dma_addr_t is sometimes 32 bit and sometimes 64. We normally cast them to unsigned long long for printk(). Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index e23dc82d43ac..9794f00810f6 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -337,7 +337,8 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) return; } - dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); + dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%llx\n", + (unsigned long long)llp); list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { /* check first descriptors addr */ @@ -387,8 +388,10 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli) { dev_printk(KERN_CRIT, chan2dev(&dwc->chan), - " desc: s0x%x d0x%x l0x%x c0x%x:%x\n", - lli->sar, lli->dar, lli->llp, + " desc: s0x%llx d0x%llx l0x%llx c0x%x:%x\n", + (unsigned long long)lli->sar, + (unsigned long long)lli->dar, + (unsigned long long)lli->llp, lli->ctlhi, lli->ctllo); } @@ -627,8 +630,10 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, unsigned int dst_width; u32 ctllo; - dev_vdbg(chan2dev(chan), "prep_dma_memcpy d0x%x s0x%x l0x%zx f0x%lx\n", - dest, src, len, flags); + dev_vdbg(chan2dev(chan), + "prep_dma_memcpy d0x%llx s0x%llx l0x%zx f0x%lx\n", + (unsigned long long)dest, (unsigned long long)src, + len, flags); if (unlikely(!len)) { dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n"); @@ -1308,9 +1313,9 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, dma_sync_single_for_device(chan2parent(chan), last->txd.phys, sizeof(last->lli), DMA_TO_DEVICE); - dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu " - "period %zu periods %d\n", buf_addr, buf_len, - period_len, periods); + dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu " + "period %zu periods %d\n", (unsigned long long)buf_addr, + buf_len, period_len, periods); cdesc->periods = periods; dwc->cdesc = cdesc; -- GitLab From 1d4554376549d50e8555e6617a4005623ea91788 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:03 +0300 Subject: [PATCH 2354/6849] dw_dmac: introduce dwc_dump_chan_regs to dump registers There is three places where values of the most significant registers were printed. Make such piece of code as separate function. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 9794f00810f6..467599a4b9b6 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -191,6 +191,19 @@ static void dwc_initialize(struct dw_dma_chan *dwc) /*----------------------------------------------------------------------*/ +static void dwc_dump_chan_regs(struct dw_dma_chan *dwc) +{ + dev_err(chan2dev(&dwc->chan), + " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", + channel_readl(dwc, SAR), + channel_readl(dwc, DAR), + channel_readl(dwc, LLP), + channel_readl(dwc, CTL_HI), + channel_readl(dwc, CTL_LO)); +} + +/*----------------------------------------------------------------------*/ + /* Called with dwc->lock held and bh disabled */ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) { @@ -200,13 +213,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) if (dma_readl(dw, CH_EN) & dwc->mask) { dev_err(chan2dev(&dwc->chan), "BUG: Attempted to start non-idle channel\n"); - dev_err(chan2dev(&dwc->chan), - " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", - channel_readl(dwc, SAR), - channel_readl(dwc, DAR), - channel_readl(dwc, LLP), - channel_readl(dwc, CTL_HI), - channel_readl(dwc, CTL_LO)); + dwc_dump_chan_regs(dwc); /* The tasklet will hopefully advance the queue... */ return; @@ -490,13 +497,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, spin_lock_irqsave(&dwc->lock, flags); - dev_err(chan2dev(&dwc->chan), - " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", - channel_readl(dwc, SAR), - channel_readl(dwc, DAR), - channel_readl(dwc, LLP), - channel_readl(dwc, CTL_HI), - channel_readl(dwc, CTL_LO)); + dwc_dump_chan_regs(dwc); channel_clear_bit(dw, CH_EN, dwc->mask); while (dma_readl(dw, CH_EN) & dwc->mask) @@ -1131,13 +1132,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) if (dma_readl(dw, CH_EN) & dwc->mask) { dev_err(chan2dev(&dwc->chan), "BUG: Attempted to start non-idle channel\n"); - dev_err(chan2dev(&dwc->chan), - " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", - channel_readl(dwc, SAR), - channel_readl(dwc, DAR), - channel_readl(dwc, LLP), - channel_readl(dwc, CTL_HI), - channel_readl(dwc, CTL_LO)); + dwc_dump_chan_regs(dwc); spin_unlock_irqrestore(&dwc->lock, flags); return -EBUSY; } -- GitLab From 2ab3727634bf88583b40541ea32df6dadfb8cc6c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:04 +0300 Subject: [PATCH 2355/6849] dw_dmac: print correct number of scanned descriptors In case the first descriptor we found is available, the counter still remains 0 value which is wrong. This patch fixes the counter behaviour. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 467599a4b9b6..a37608d02a2c 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -105,13 +105,13 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc) spin_lock_irqsave(&dwc->lock, flags); list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) { + i++; if (async_tx_test_ack(&desc->txd)) { list_del(&desc->desc_node); ret = desc; break; } dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc); - i++; } spin_unlock_irqrestore(&dwc->lock, flags); -- GitLab From 2e4c364e151ba9085c77836733af36d3bd0e8ffd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:05 +0300 Subject: [PATCH 2356/6849] dw_dmac: use __func__ constant in the debug prints Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index a37608d02a2c..41f03f37df2a 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -344,7 +344,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) return; } - dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%llx\n", + dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__, (unsigned long long)llp); list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { @@ -531,7 +531,7 @@ static void dw_dma_tasklet(unsigned long data) status_xfer = dma_readl(dw, RAW.XFER); status_err = dma_readl(dw, RAW.ERROR); - dev_vdbg(dw->dma.dev, "tasklet: status_err=%x\n", status_err); + dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err); for (i = 0; i < dw->dma.chancnt; i++) { dwc = &dw->chan[i]; @@ -555,7 +555,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id) struct dw_dma *dw = dev_id; u32 status; - dev_vdbg(dw->dma.dev, "interrupt: status=0x%x\n", + dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__, dma_readl(dw, STATUS_INT)); /* @@ -601,12 +601,12 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx) * for DMA. But this is hard to do in a race-free manner. */ if (list_empty(&dwc->active_list)) { - dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n", + dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__, desc->txd.cookie); list_add_tail(&desc->desc_node, &dwc->active_list); dwc_dostart(dwc, dwc_first_active(dwc)); } else { - dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", + dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__, desc->txd.cookie); list_add_tail(&desc->desc_node, &dwc->queue); @@ -632,12 +632,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, u32 ctllo; dev_vdbg(chan2dev(chan), - "prep_dma_memcpy d0x%llx s0x%llx l0x%zx f0x%lx\n", + "%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__, (unsigned long long)dest, (unsigned long long)src, len, flags); if (unlikely(!len)) { - dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n"); + dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__); return NULL; } @@ -726,7 +726,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, struct scatterlist *sg; size_t total_len = 0; - dev_vdbg(chan2dev(chan), "prep_dma_slave\n"); + dev_vdbg(chan2dev(chan), "%s\n", __func__); if (unlikely(!dws || !sg_len)) return NULL; @@ -1020,7 +1020,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) int i; unsigned long flags; - dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); + dev_vdbg(chan2dev(chan), "%s\n", __func__); /* ASSERT: channel is idle */ if (dma_readl(dw, CH_EN) & dwc->mask) { @@ -1063,8 +1063,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&dwc->lock, flags); - dev_dbg(chan2dev(chan), - "alloc_chan_resources allocated %d descriptors\n", i); + dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i); return i; } @@ -1077,7 +1076,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) unsigned long flags; LIST_HEAD(list); - dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n", + dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__, dwc->descs_allocated); /* ASSERT: channel is idle */ @@ -1103,7 +1102,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) kfree(desc); } - dev_vdbg(chan2dev(chan), "free_chan_resources done\n"); + dev_vdbg(chan2dev(chan), "%s: done\n", __func__); } /* --------------------- Cyclic DMA API extensions -------------------- */ @@ -1340,7 +1339,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan) int i; unsigned long flags; - dev_dbg(chan2dev(&dwc->chan), "cyclic free\n"); + dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__); if (!cdesc) return; -- GitLab From 11f932ec221ee07c3a9d49e83df7d44b13f8885f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:06 +0300 Subject: [PATCH 2357/6849] dw_dmac: disable dma in optimal way in probe The dw_dma_off call needs to have the all_chan_mask calculated. So, done this calculations before the call. Moreover, remove duplicate code that masks the DMA interrupts. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 41f03f37df2a..8a37f6d17b47 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1431,6 +1431,9 @@ static int __init dw_probe(struct platform_device *pdev) } clk_prepare_enable(dw->clk); + /* Calculate all channel mask before DMA setup */ + dw->all_chan_mask = (1 << pdata->nr_channels) - 1; + /* force dma off, just in case */ dw_dma_off(dw); @@ -1442,8 +1445,6 @@ static int __init dw_probe(struct platform_device *pdev) tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw); - dw->all_chan_mask = (1 << pdata->nr_channels) - 1; - INIT_LIST_HEAD(&dw->dma.channels); for (i = 0; i < pdata->nr_channels; i++) { struct dw_dma_chan *dwc = &dw->chan[i]; @@ -1473,17 +1474,12 @@ static int __init dw_probe(struct platform_device *pdev) channel_clear_bit(dw, CH_EN, dwc->mask); } - /* Clear/disable all interrupts on all channels. */ + /* Clear all interrupts on all channels. */ dma_writel(dw, CLEAR.XFER, dw->all_chan_mask); dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask); dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask); dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask); - channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); - channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask); - channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask); - channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask); - dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); if (pdata->is_private) -- GitLab From 236b106f1a66a272708e4960cde8cbcdd1611435 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:07 +0300 Subject: [PATCH 2358/6849] dw_dmac: disable BLOCK interrupts Just to be sure we are in known state we disable the BLOCK interupts. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 8a37f6d17b47..d3038a03503d 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1437,6 +1437,9 @@ static int __init dw_probe(struct platform_device *pdev) /* force dma off, just in case */ dw_dma_off(dw); + /* disable BLOCK interrupts as well */ + channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); + err = request_irq(irq, dw_dma_interrupt, 0, "dw_dmac", dw); if (err) goto err_irq; @@ -1476,6 +1479,7 @@ static int __init dw_probe(struct platform_device *pdev) /* Clear all interrupts on all channels. */ dma_writel(dw, CLEAR.XFER, dw->all_chan_mask); + dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask); dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask); dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask); dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask); -- GitLab From 4c2d56c574db84ef6e0101f28a37c044e89b0302 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:08 +0300 Subject: [PATCH 2359/6849] dw_dmac: introduce dwc_fast_fls() There were three places where such function is used. We still avoid to use native fls() because in one case it requires to use 64bit version which is suboptimal in our case. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 46 +++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index d3038a03503d..6b456f042557 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -191,6 +191,21 @@ static void dwc_initialize(struct dw_dma_chan *dwc) /*----------------------------------------------------------------------*/ +static inline unsigned int dwc_fast_fls(unsigned long long v) +{ + /* + * We can be a lot more clever here, but this should take care + * of the most common optimization. + */ + if (!(v & 7)) + return 3; + else if (!(v & 3)) + return 2; + else if (!(v & 1)) + return 1; + return 0; +} + static void dwc_dump_chan_regs(struct dw_dma_chan *dwc) { dev_err(chan2dev(&dwc->chan), @@ -641,18 +656,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, return NULL; } - /* - * We can be a lot more clever here, but this should take care - * of the most common optimization. - */ - if (!((src | dest | len) & 7)) - src_width = dst_width = 3; - else if (!((src | dest | len) & 3)) - src_width = dst_width = 2; - else if (!((src | dest | len) & 1)) - src_width = dst_width = 1; - else - src_width = dst_width = 0; + src_width = dst_width = dwc_fast_fls(src | dest | len); ctllo = DWC_DEFAULT_CTLLO(chan) | DWC_CTLL_DST_WIDTH(dst_width) @@ -752,14 +756,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, mem = sg_dma_address(sg); len = sg_dma_len(sg); - if (!((mem | len) & 7)) - mem_width = 3; - else if (!((mem | len) & 3)) - mem_width = 2; - else if (!((mem | len) & 1)) - mem_width = 1; - else - mem_width = 0; + mem_width = dwc_fast_fls(mem | len); slave_sg_todev_fill_desc: desc = dwc_desc_get(dwc); @@ -819,14 +816,7 @@ slave_sg_todev_fill_desc: mem = sg_dma_address(sg); len = sg_dma_len(sg); - if (!((mem | len) & 7)) - mem_width = 3; - else if (!((mem | len) & 3)) - mem_width = 2; - else if (!((mem | len) & 1)) - mem_width = 1; - else - mem_width = 0; + mem_width = dwc_fast_fls(mem | len); slave_sg_fromdev_fill_desc: desc = dwc_desc_get(dwc); -- GitLab From 0272e93f364eac1a30f2831adcaca3dd633d5f14 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:34:09 +0300 Subject: [PATCH 2360/6849] dw_dmac: move from __init to __devinit We usually have more than one DMA device. Thus, the probe function should serve for all of them in case when the driver is built as a module. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 6b456f042557..83f63b38dcc0 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1375,7 +1375,7 @@ static void dw_dma_off(struct dw_dma *dw) dw->chan[i].initialized = false; } -static int __init dw_probe(struct platform_device *pdev) +static int __devinit dw_probe(struct platform_device *pdev) { struct dw_dma_platform_data *pdata; struct resource *io; @@ -1512,7 +1512,7 @@ err_kfree: return err; } -static int __exit dw_remove(struct platform_device *pdev) +static int __devexit dw_remove(struct platform_device *pdev) { struct dw_dma *dw = platform_get_drvdata(pdev); struct dw_dma_chan *dwc, *_dwc; @@ -1591,7 +1591,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table); #endif static struct platform_driver dw_driver = { - .remove = __exit_p(dw_remove), + .remove = __devexit_p(dw_remove), .shutdown = dw_shutdown, .driver = { .name = "dw_dmac", -- GitLab From 3f9362078b101bd57bfed635e49c8ecb8b6d465d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Jun 2012 13:46:32 +0300 Subject: [PATCH 2361/6849] dw_dmac: introduce dwc_chan_disable This piece of code is used often. Make it as a separate function. Signed-off-by: Andy Shevchenko Acked-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dw_dmac.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 83f63b38dcc0..85ed5f20e027 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -217,6 +217,14 @@ static void dwc_dump_chan_regs(struct dw_dma_chan *dwc) channel_readl(dwc, CTL_LO)); } + +static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc) +{ + channel_clear_bit(dw, CH_EN, dwc->mask); + while (dma_readl(dw, CH_EN) & dwc->mask) + cpu_relax(); +} + /*----------------------------------------------------------------------*/ /* Called with dwc->lock held and bh disabled */ @@ -312,9 +320,7 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc) "BUG: XFER bit set, but channel not idle!\n"); /* Try to continue after resetting the channel... */ - channel_clear_bit(dw, CH_EN, dwc->mask); - while (dma_readl(dw, CH_EN) & dwc->mask) - cpu_relax(); + dwc_chan_disable(dw, dwc); } /* @@ -396,9 +402,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) "BUG: All descriptors done, but channel not idle!\n"); /* Try to continue after resetting the channel... */ - channel_clear_bit(dw, CH_EN, dwc->mask); - while (dma_readl(dw, CH_EN) & dwc->mask) - cpu_relax(); + dwc_chan_disable(dw, dwc); if (!list_empty(&dwc->queue)) { list_move(dwc->queue.next, &dwc->active_list); @@ -514,9 +518,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, dwc_dump_chan_regs(dwc); - channel_clear_bit(dw, CH_EN, dwc->mask); - while (dma_readl(dw, CH_EN) & dwc->mask) - cpu_relax(); + dwc_chan_disable(dw, dwc); /* make sure DMA does not restart by loading a new list */ channel_writel(dwc, LLP, 0); @@ -946,9 +948,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, } else if (cmd == DMA_TERMINATE_ALL) { spin_lock_irqsave(&dwc->lock, flags); - channel_clear_bit(dw, CH_EN, dwc->mask); - while (dma_readl(dw, CH_EN) & dwc->mask) - cpu_relax(); + dwc_chan_disable(dw, dwc); dwc->paused = false; @@ -1156,9 +1156,7 @@ void dw_dma_cyclic_stop(struct dma_chan *chan) spin_lock_irqsave(&dwc->lock, flags); - channel_clear_bit(dw, CH_EN, dwc->mask); - while (dma_readl(dw, CH_EN) & dwc->mask) - cpu_relax(); + dwc_chan_disable(dw, dwc); spin_unlock_irqrestore(&dwc->lock, flags); } @@ -1336,9 +1334,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan) spin_lock_irqsave(&dwc->lock, flags); - channel_clear_bit(dw, CH_EN, dwc->mask); - while (dma_readl(dw, CH_EN) & dwc->mask) - cpu_relax(); + dwc_chan_disable(dw, dwc); dma_writel(dw, CLEAR.ERROR, dwc->mask); dma_writel(dw, CLEAR.XFER, dwc->mask); -- GitLab From 2b1b712f050eaf0ac576591281446dc960c0afc5 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 20 Jun 2012 21:18:14 -0700 Subject: [PATCH 2362/6849] x86, reboot: Drop redundant write of reboot_mode We write reboot_mode to BIOS location 0x472 in native_machine_emergency_restart() (reboot.c:542) already, there is no need to then write it again in machine_real_restart(). This means nothing gets written there for MRR_APM, but the APM call is a poweroff call and doesn't use this memory location. Link: http://lkml.kernel.org/n/tip-3i0pfh44c1e3jv5lab0cf7sc@git.kernel.org Signed-off-by: H. Peter Anvin --- arch/x86/kernel/reboot.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 6ddb9cd0ced0..6ef559f09acd 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -179,14 +179,6 @@ void __noreturn machine_real_restart(unsigned int type) write_cr3(real_mode_header->trampoline_pgd); #endif - /* - * Write 0x1234 to absolute memory location 0x472. The BIOS reads - * this on booting to tell it to "Bypass memory test (also warm - * boot)". This seems like a fairly standard thing that gets set by - * REBOOT.COM programs, and the previous reset routine did this - * too. */ - *((unsigned short *)0x472) = reboot_mode; - /* Jump to the identity-mapped low memory code */ #ifdef CONFIG_X86_32 asm volatile("jmpl *%0" : : -- GitLab From 0e3534c0417fef6e6535db8867a04798f2024e3f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 20 Jun 2012 18:30:30 -0700 Subject: [PATCH 2363/6849] media: pms.c needs linux/slab.h drivers/media/video/pms.c uses kzalloc() and kfree() so it should include to fix build errors and a warning. drivers/media/video/pms.c:1047:2: error: implicit declaration of function 'kzalloc' drivers/media/video/pms.c:1047:6: warning: assignment makes pointer from integer without a cast drivers/media/video/pms.c:1116:2: error: implicit declaration of function 'kfree' Found in mmotm but applies to mainline. Signed-off-by: Randy Dunlap Cc: Hans Verkuil Signed-off-by: Linus Torvalds --- drivers/media/video/pms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index af2d9086d7e8..c370c2d87c17 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include -- GitLab From c4c0e9e544a0eb640798cc66e68f394fa4a561bf Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 20 Jun 2012 18:00:12 -0700 Subject: [PATCH 2364/6849] mm, mempolicy: fix mbind() to do synchronous migration If the range passed to mbind() is not allocated on nodes set in the nodemask, it migrates the pages to respect the constraint. The final formal of migrate_pages() is a mode of type enum migrate_mode, not a boolean. do_mbind() is currently passing "true" which is the equivalent of MIGRATE_SYNC_LIGHT. This should instead be MIGRATE_SYNC for synchronous page migration. Signed-off-by: David Rientjes Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index f15c1b24ca18..1d771e4200d2 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1177,7 +1177,7 @@ static long do_mbind(unsigned long start, unsigned long len, if (!list_empty(&pagelist)) { nr_failed = migrate_pages(&pagelist, new_vma_page, (unsigned long)vma, - false, true); + false, MIGRATE_SYNC); if (nr_failed) putback_lru_pages(&pagelist); } -- GitLab From 8ceb332df46863ac8f74114a2b1805719cf49dcc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Jun 2012 08:23:27 +0200 Subject: [PATCH 2365/6849] ALSA: hda - Remove loop from simple_hdmi*() The simple_hdmi stuff is designed only for a single pin and a single converter (thus a single PCM stream), and no need for loops. Let's flatten the code. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 69 +++++++++++++++----------------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 64f1fedfd535..0a87a1f2988e 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1364,26 +1364,22 @@ static int simple_playback_build_pcms(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; struct hda_pcm *info = spec->pcm_rec; - int i; + unsigned int chans; + struct hda_pcm_stream *pstr; - codec->num_pcms = spec->num_cvts; + codec->num_pcms = 1; codec->pcm_info = info; - for (i = 0; i < codec->num_pcms; i++, info++) { - unsigned int chans; - struct hda_pcm_stream *pstr; + chans = get_wcaps(codec, spec->cvts[0].cvt_nid); + chans = get_wcaps_channels(chans); - chans = get_wcaps(codec, spec->cvts[i].cvt_nid); - chans = get_wcaps_channels(chans); - - info->name = get_hdmi_pcm_name(i); - info->pcm_type = HDA_PCM_TYPE_HDMI; - pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; - *pstr = spec->pcm_playback; - pstr->nid = spec->cvts[i].cvt_nid; - if (pstr->channels_max <= 2 && chans && chans <= 16) - pstr->channels_max = chans; - } + info->name = get_hdmi_pcm_name(0); + info->pcm_type = HDA_PCM_TYPE_HDMI; + pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; + *pstr = spec->pcm_playback; + pstr->nid = spec->cvts[0].cvt_nid; + if (pstr->channels_max <= 2 && chans && chans <= 16) + pstr->channels_max = chans; return 0; } @@ -1405,38 +1401,27 @@ static int simple_playback_build_controls(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; int err; - int i; - - for (i = 0; i < codec->num_pcms; i++) { - err = snd_hda_create_spdif_out_ctls(codec, - spec->cvts[i].cvt_nid, - spec->cvts[i].cvt_nid); - if (err < 0) - return err; - err = simple_hdmi_build_jack(codec, i); - if (err < 0) - return err; - } - return 0; + err = snd_hda_create_spdif_out_ctls(codec, + spec->cvts[0].cvt_nid, + spec->cvts[0].cvt_nid); + if (err < 0) + return err; + return simple_hdmi_build_jack(codec, 0); } static int simple_playback_init(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; - int i; - - for (i = 0; i < spec->num_pins; i++) { - hda_nid_t pin = spec->pins[i].pin_nid; - snd_hda_codec_write(codec, pin, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - /* some codecs require to unmute the pin */ - if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) - snd_hda_codec_write(codec, pin, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_UNMUTE); - snd_hda_jack_detect_enable(codec, pin, pin); - } + hda_nid_t pin = spec->pins[0].pin_nid; + + snd_hda_codec_write(codec, pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + /* some codecs require to unmute the pin */ + if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); + snd_hda_jack_detect_enable(codec, pin, pin); snd_hda_jack_report_sync(codec); return 0; } -- GitLab From 3f8a9e76672202bfb55cc83b5fdc66306d3d170a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jun 2012 21:25:15 +0200 Subject: [PATCH 2366/6849] iwlwifi: fix radio reset scan dwell vs. quiet time My previous commit to shorten the radio reset time caused issues as the firmware checks the active dwell time against the quiet time, asserting that the dwell is >= quiet time. This isn't really needed in case of passive scanning like here, but of course we need to pass that check. To fix this, override the quiet time to be the same as the radio reset dwell time. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/scan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index f5b1452a60b3..6633074258c7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -720,6 +720,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) switch (priv->scan_type) { case IWL_SCAN_RADIO_RESET: IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + /* + * Override quiet time as firmware checks that active + * dwell is >= quiet; since we use passive scan it'll + * not actually be used. + */ + scan->quiet_time = cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME); break; case IWL_SCAN_NORMAL: if (priv->scan_request->n_ssids) { -- GitLab From e9c03d18c4291c4351d6b9f74bd1278a761015a2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jun 2012 16:24:59 +0200 Subject: [PATCH 2367/6849] iwlwifi: increase scan timeout When the first interface is active, then scanning on it or the second interface can take a little longer than 7s (I observed around 8s.) Bump the timeout to 15s to avoid aborting a scan that is still running, just taking more time. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/agn.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 6d102413dd94..9bb16bdf6d26 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -269,7 +269,7 @@ void iwl_scan_offchannel_skb_status(struct iwl_priv *priv); #define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */ #define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */ -#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) +#define IWL_SCAN_CHECK_WATCHDOG (HZ * 15) /* bt coex */ -- GitLab From e75dac921d88ac1fa1ad08686ab242556f8b888b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jun 2012 11:47:42 +0200 Subject: [PATCH 2368/6849] iwlwifi: limit mac_change_interface to BSS context Currently when mac80211 asks to change the interface type, we will accept it for both the BSS and PAN contexts. This is not terribly complicated today, but with the addition of the P2P Device abstraction the PAN context handling will get more complex, so restrict mac_change_interface to the BSS context. Also fix a small locking issue and use is_active instead of the vif pointer to check if the other context is activated, guarding exclusive interface types on the BSS context (IBSS) against the PAN context being used for something else. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 37 ++++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index b581f035d4b0..b83ca358eb18 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1411,13 +1411,11 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, } static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum nl80211_iftype newtype, bool newp2p) + struct ieee80211_vif *vif, + enum nl80211_iftype newtype, bool newp2p) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl_rxon_context *tmp; + struct iwl_rxon_context *ctx, *tmp; enum nl80211_iftype newviftype = newtype; u32 interface_modes; int err; @@ -1428,6 +1426,18 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + ctx = iwl_rxon_ctx_from_vif(vif); + + /* + * To simplify this code, only support changes on the + * BSS context. The PAN context is usually reassigned + * by creating/removing P2P interfaces anyway. + */ + if (ctx->ctxid != IWL_RXON_CTX_BSS) { + err = -EBUSY; + goto out; + } + if (!ctx->vif || !iwl_is_ready_rf(priv)) { /* * Huh? But wait ... this can maybe happen when @@ -1437,32 +1447,19 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, goto out; } + /* Check if the switch is supported in the same context */ interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; - if (!(interface_modes & BIT(newtype))) { err = -EBUSY; goto out; } - /* - * Refuse a change that should be done by moving from the PAN - * context to the BSS context instead, if the BSS context is - * available and can support the new interface type. - */ - if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && - (bss_ctx->interface_modes & BIT(newtype) || - bss_ctx->exclusive_interface_modes & BIT(newtype))) { - BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); - err = -EBUSY; - goto out; - } - if (ctx->exclusive_interface_modes & BIT(newtype)) { for_each_context(priv, tmp) { if (ctx == tmp) continue; - if (!tmp->vif) + if (!tmp->is_active) continue; /* -- GitLab From d3decf3a0c1d28c80c76be170373f4c7a7217f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ozan=20=C3=87a=C4=9Flayan?= Date: Thu, 14 Jun 2012 15:02:35 +0300 Subject: [PATCH 2369/6849] vga_switcheroo: Add include guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guard vga_switcheroo.h against multiple inclusion. Signed-off-by: Ozan Çağlayan Signed-off-by: Dave Airlie --- include/linux/vga_switcheroo.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index d844b7790ea6..ddb419cf4530 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -7,6 +7,9 @@ * vga_switcheroo.h - Support for laptop with dual GPU using one set of outputs */ +#ifndef _LINUX_VGA_SWITCHEROO_H_ +#define _LINUX_VGA_SWITCHEROO_H_ + #include struct pci_dev; @@ -73,3 +76,4 @@ static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return #endif +#endif /* _LINUX_VGA_SWITCHEROO_H_ */ -- GitLab From b196a4980ff7bb54db478e2a408dc8b12be15304 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 19 Jun 2012 11:33:06 +0200 Subject: [PATCH 2370/6849] drm/edid: don't return stack garbage from supports_rb We need to initialize this to false, because the is_rb callback only ever sets it to true. Noticed while reading through the code. Cc: stable@vger.kernel.org Signed-Off-by: Daniel Vetter Reviewed-by: Adam Jackson Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index eb92fe257a39..5873e481e5d2 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -610,7 +610,7 @@ static bool drm_monitor_supports_rb(struct edid *edid) { if (edid->revision >= 4) { - bool ret; + bool ret = false; drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); return ret; } -- GitLab From 97ee9f01d6f26a69847d7a0ea07be756fe9f8eb6 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Thu, 21 Jun 2012 01:36:02 -0700 Subject: [PATCH 2371/6849] ARM: OMAP: fix the ads7846 init code In case a board provides the gpio_pendown and not board_pdata, the GPIO debounce is not taken care of. Fix this by taking care of GPIO debounce in any case. Signed-off-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/common-board-devices.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 1706ebcec08d..c1875862679f 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -63,28 +63,30 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, struct spi_board_info *spi_bi = &ads7846_spi_board_info; int err; - if (board_pdata && board_pdata->get_pendown_state) { - err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); - if (err) { - pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); - return; - } - gpio_export(gpio_pendown, 0); - - if (gpio_debounce) - gpio_set_debounce(gpio_pendown, gpio_debounce); + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); + if (err) { + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); + return; } + if (gpio_debounce) + gpio_set_debounce(gpio_pendown, gpio_debounce); + spi_bi->bus_num = bus_num; spi_bi->irq = gpio_to_irq(gpio_pendown); if (board_pdata) { board_pdata->gpio_pendown = gpio_pendown; spi_bi->platform_data = board_pdata; + if (board_pdata->get_pendown_state) + gpio_export(gpio_pendown, 0); } else { ads7846_config.gpio_pendown = gpio_pendown; } + if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) + gpio_free(gpio_pendown); + spi_register_board_info(&ads7846_spi_board_info, 1); } #else -- GitLab From da0085ff9b2ca9ad21fd9fb380247e6639cccacd Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 21 Jun 2012 01:36:02 -0700 Subject: [PATCH 2372/6849] ARM: OMAP2: twl-common: Fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the kernel is built only for OMAP2 the following warning will show up: arch/arm/mach-omap2/twl-common.c:52: warning: ‘twl_set_voltage’ defined but not used arch/arm/mach-omap2/twl-common.c:58: warning: ‘twl_get_voltage’ defined but not used The twl_set/get_voltage callbacks only used when OMAP3/4 is selected. Signed-off-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/twl-common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 119d5a910f3a..5447c135633f 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -48,6 +48,7 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { }, }; +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) static int twl_set_voltage(void *data, int target_uV) { struct voltagedomain *voltdm = (struct voltagedomain *)data; @@ -59,6 +60,7 @@ static int twl_get_voltage(void *data) struct voltagedomain *voltdm = (struct voltagedomain *)data; return voltdm_get_voltage(voltdm); } +#endif void __init omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, -- GitLab From f6f6c9a5be996f266ff6fbe7850d76c3b0bdab95 Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Thu, 21 Jun 2012 01:36:02 -0700 Subject: [PATCH 2373/6849] ARM: OMAP: beagle: Set USB Host Port 1 to OMAP_USBHS_PORT_MODE_UNUSED The beagleboard USB Host Port that is used is Port 2. The platform driver sets MODE_PHY for port 1 causing pin muxing to override the pins on the expansion connector P17 when using board_mux[]. Since USBHS Port 1 is not connected remove the case for muxing the USB Port1 pins by default. Tested with BeagleBoard xM revC and checked the userguides for Beagle xM and revC to be sure USB Port2 is what is used. Signed-off-by: Brian Austin Acked-by: Russ Dill Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-omap3beagle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 79c6909eeb78..75eb88a738c4 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -435,7 +435,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = { static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, -- GitLab From fd5c3fd7c4d06414453d7b72ab6d59ab1a0d2356 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 21 Jun 2012 01:36:03 -0700 Subject: [PATCH 2374/6849] ARM: OMAP: Fix dts files w/ status property: "disable" -> "disabled" This patches fixes some status = "disable" strings to "disabled", the correct way of disabling nodes in the devicetree. Just the OMAP part here, the rest goes via other patches and trees. Signed-off-by: Roland Stigge Acked-by: Rob Herring Acked-by: Benoit Cousson Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-beagle.dts | 4 ++-- arch/arm/boot/dts/omap4-panda.dts | 6 +++--- arch/arm/boot/dts/omap4-sdp.dts | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 5b4506c0a8c4..cdcb98c7e075 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -61,9 +61,9 @@ }; &mmc2 { - status = "disable"; + status = "disabled"; }; &mmc3 { - status = "disable"; + status = "disabled"; }; diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts index 1efe0c587985..9d8abf0938e0 100644 --- a/arch/arm/boot/dts/omap4-panda.dts +++ b/arch/arm/boot/dts/omap4-panda.dts @@ -74,15 +74,15 @@ }; &mmc2 { - status = "disable"; + status = "disabled"; }; &mmc3 { - status = "disable"; + status = "disabled"; }; &mmc4 { - status = "disable"; + status = "disabled"; }; &mmc5 { diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index d08c4d137280..9b1c13a16c2c 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -147,11 +147,11 @@ }; &mmc3 { - status = "disable"; + status = "disabled"; }; &mmc4 { - status = "disable"; + status = "disabled"; }; &mmc5 { -- GitLab From 37f971b68009b8fadd322130787d693137302925 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 20 Jun 2012 12:53:25 +0200 Subject: [PATCH 2375/6849] ARM: mach-shmobile: armadillo800eva: Use late init machine hook Since commit 21cc1b7ede3cf456cf1d51f8a906093261f7c111 ("ARM: shmobile: use machine specific hook for late init") suspend and CPU idle are not initialized automatically anymore. Set shmobile_init_late() as the machine late init hook to initialize them. Signed-off-by: Laurent Pinchart Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/board-armadillo800eva.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 9e37026ef9dd..9bd135531d76 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -779,6 +779,7 @@ DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva") .init_irq = r8a7740_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = eva_init, + .init_late = shmobile_init_late, .timer = &shmobile_timer, .dt_compat = eva_boards_compat_dt, MACHINE_END -- GitLab From 14dd52f4389e206537488aeb2b85d6b21fc27196 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 20 Jun 2012 22:40:08 -0700 Subject: [PATCH 2376/6849] ARM: shmobile: kzm9g: use late init machine hook Since commit 21cc1b7ede3cf456cf1d51f8a906093261f7c111 ("ARM: shmobile: use machine specific hook for late init") suspend and CPU idle are not initialized automatically anymore. Set shmobile_init_late() as the machine late init hook to initialize them. Signed-off-by: Kuninori Morimoto Acked-by: Laurent Pinchart Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/board-kzm9g.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index d8e33b682832..c0ae815e7beb 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -455,6 +455,7 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g") .init_irq = sh73a0_init_irq, .handle_irq = gic_handle_irq, .init_machine = kzm_init, + .init_late = shmobile_init_late, .timer = &shmobile_timer, .dt_compat = kzm9g_boards_compat_dt, MACHINE_END -- GitLab From c207d2df1c1b2a160b7d52229e5a43feea6a7d26 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 20 Jun 2012 22:41:34 -0700 Subject: [PATCH 2377/6849] ARM: shmobile: kzm9d: use late init machine hook Since commit 21cc1b7ede3cf456cf1d51f8a906093261f7c111 ("ARM: shmobile: use machine specific hook for late init") suspend and CPU idle are not initialized automatically anymore. Set shmobile_init_late() as the machine late init hook to initialize them. Signed-off-by: Kuninori Morimoto Acked-by: Laurent Pinchart Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/board-kzm9d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c index 7bc5e7d39f9b..6a33cf393428 100644 --- a/arch/arm/mach-shmobile/board-kzm9d.c +++ b/arch/arm/mach-shmobile/board-kzm9d.c @@ -80,6 +80,7 @@ DT_MACHINE_START(KZM9D_DT, "kzm9d") .init_irq = emev2_init_irq, .handle_irq = gic_handle_irq, .init_machine = kzm9d_add_standard_devices, + .init_late = shmobile_init_late, .timer = &shmobile_timer, .dt_compat = kzm9d_boards_compat_dt, MACHINE_END -- GitLab From 01bc3a1400373a0f6bd79f2328eb822ca099c784 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 20 Jun 2012 22:40:10 +0800 Subject: [PATCH 2378/6849] regulator: tps65910: Convert to regulator_set_voltage_time_sel() Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 34 +++++--------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index e1b01ec82301..373c529b379d 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -824,31 +824,6 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) return (LDO_MIN_VOLT + selector * step_mv) * 1000; } -static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev, - unsigned int old_selector, unsigned int new_selector) -{ - int id = rdev_get_id(dev); - int old_volt, new_volt; - - old_volt = tps65910_list_voltage_dcdc(dev, old_selector); - if (old_volt < 0) - return old_volt; - - new_volt = tps65910_list_voltage_dcdc(dev, new_selector); - if (new_volt < 0) - return new_volt; - - /* VDD1 and VDD2 are 12.5mV/us, VDDCTRL is 100mV/20us */ - switch (id) { - case TPS65910_REG_VDD1: - case TPS65910_REG_VDD2: - return DIV_ROUND_UP(abs(old_volt - new_volt), 12500); - case TPS65911_REG_VDDCTRL: - return DIV_ROUND_UP(abs(old_volt - new_volt), 5000); - } - return -EINVAL; -} - /* Regulator ops (except VRTC) */ static struct regulator_ops tps65910_ops_dcdc = { .is_enabled = regulator_is_enabled_regmap, @@ -859,7 +834,7 @@ static struct regulator_ops tps65910_ops_dcdc = { .get_mode = tps65910_get_mode, .get_voltage_sel = tps65910_get_voltage_dcdc_sel, .set_voltage_sel = tps65910_set_voltage_dcdc_sel, - .set_voltage_time_sel = tps65910_set_voltage_dcdc_time_sel, + .set_voltage_time_sel = regulator_set_voltage_time_sel, .list_voltage = tps65910_list_voltage_dcdc, }; @@ -1236,11 +1211,14 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].ops = &tps65910_ops_dcdc; pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE * VDD1_2_NUM_VOLT_COARSE; + pmic->desc[i].ramp_delay = 12500; } else if (i == TPS65910_REG_VDD3) { - if (tps65910_chip_id(tps65910) == TPS65910) + if (tps65910_chip_id(tps65910) == TPS65910) { pmic->desc[i].ops = &tps65910_ops_vdd3; - else + } else { pmic->desc[i].ops = &tps65910_ops_dcdc; + pmic->desc[i].ramp_delay = 5000; + } } else { if (tps65910_chip_id(tps65910) == TPS65910) pmic->desc[i].ops = &tps65910_ops; -- GitLab From dc2060cfe2aa2b62ba2f4a19fce0c20eceefe7ca Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Jun 2012 10:35:58 +0100 Subject: [PATCH 2379/6849] regulator: lp872x: Depend on I2C=y Kconfig doesn't do the right thing for us here. Reported-by: Stephen Rothwell Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index e056c09661a2..27fe52f592d9 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -234,7 +234,7 @@ config REGULATOR_LP3972 config REGULATOR_LP872X bool "TI/National Semiconductor LP8720/LP8725 voltage regulators" - depends on I2C + depends on I2C=y select REGMAP_I2C help This driver supports LP8720/LP8725 PMIC -- GitLab From 9dd8cf125d27742a25219bfdf82026e7efed27d9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Jun 2012 10:43:15 +0200 Subject: [PATCH 2380/6849] ALSA: hda - Don't rely on event tag for simple_hdmi VIA codecs seem not returning the event tag in the unsolicited events, thus the current code relying on the tag value doesn't work. Since simple_hdmi stuff has only a single pin, we can use simply snd_hda_jack_set_dirty_all() to activate the pin-detection independently from the tag value. Tested-by: Annie Liu Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0a87a1f2988e..75ad1a10646b 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1388,7 +1388,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) static void simple_hdmi_unsol_event(struct hda_codec *codec, unsigned int res) { - snd_hda_jack_get_action(codec, res >> AC_UNSOL_RES_TAG_SHIFT); + snd_hda_jack_set_dirty_all(codec); snd_hda_jack_report_sync(codec); } -- GitLab From e9ea8e8f229f4963bf01658e79c1c01780de25dd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Jun 2012 11:41:05 +0200 Subject: [PATCH 2381/6849] ALSA: hda - Correct info print in HDMI non-intrinsic unsol event In the recent code, the value shown there is a tag number, and it's no longer same as the pin nid. Correct the message to avoid confusion. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 75ad1a10646b..d6a8260a6f74 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -787,7 +787,7 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); printk(KERN_INFO - "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", + "HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", codec->addr, tag, subtag, -- GitLab From c954910bc4501447cc647d5fca5bd0d9439e177d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 6 Jun 2012 10:48:56 +0300 Subject: [PATCH 2382/6849] wlcore: suppress error message on Rx BA session removal The ampdu_action() function is called on the reconfig() path to remove existing Rx BA sessions. Since these don't exist for the low level driver, we output an error message. Turn the message into a debug message for now, until the mac80211 reconfig flow is changed. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 8eefcd7505e2..22b342f64b7b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4366,9 +4366,14 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: if (!(*ba_bitmap & BIT(tid))) { - ret = -EINVAL; - wl1271_error("no active RX BA session on tid: %d", + /* + * this happens on reconfig - so only output a debug + * message for now, and don't fail the function. + */ + wl1271_debug(DEBUG_MAC80211, + "no active RX BA session on tid: %d", tid); + ret = 0; break; } -- GitLab From 26b5858a67e4316ecd8159e2c0dc5591ef68226a Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 28 Feb 2012 19:13:28 +0200 Subject: [PATCH 2383/6849] wlcore: add a debugfs entry to allow changing the sleep mode by hand For FW debugging purposes, we may need to change the sleep mode (aka. sleep_auth) by hand, and set it to the mode we want. To allow this, a debugfs entry is added. Now we store the sleep_auth value that has been set and use that instead of the quirk to decide whether we should enter ELP or not. Signed-off-by: Luciano Coelho Signed-off-by: Arik Nemtsov --- drivers/net/wireless/ti/wlcore/acx.c | 3 ++ drivers/net/wireless/ti/wlcore/acx.h | 2 + drivers/net/wireless/ti/wlcore/debugfs.c | 58 ++++++++++++++++++++++++ drivers/net/wireless/ti/wlcore/main.c | 3 ++ drivers/net/wireless/ti/wlcore/ps.c | 2 +- drivers/net/wireless/ti/wlcore/wlcore.h | 3 ++ 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index b9ec42c83757..b56217f9bfd4 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -81,7 +81,10 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) auth->sleep_auth = sleep_auth; ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); + if (ret < 0) + goto out; + wl->sleep_auth = sleep_auth; out: kfree(auth); return ret; diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index c0181258b722..168e0464411d 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -118,6 +118,8 @@ enum wl1271_psm_mode { /* Extreme low power */ WL1271_PSM_ELP = 2, + + WL1271_PSM_MAX = WL1271_PSM_ELP, }; struct acx_sleep_auth { diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 689a847005c9..91e43def013d 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -963,6 +963,63 @@ static const struct file_operations fw_stats_raw_ops = { .llseek = default_llseek, }; +static ssize_t sleep_auth_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + + return wl1271_format_buffer(user_buf, count, + ppos, "%d\n", + wl->sleep_auth); +} + +static ssize_t sleep_auth_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + unsigned long value; + int ret; + + ret = kstrtoul_from_user(user_buf, count, 0, &value); + if (ret < 0) { + wl1271_warning("illegal value in sleep_auth"); + return -EINVAL; + } + + if (value < 0 || value > WL1271_PSM_MAX) { + wl1271_warning("sleep_auth must be between 0 and %d", + WL1271_PSM_MAX); + return -ERANGE; + } + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1271_acx_sleep_auth(wl, value); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations sleep_auth_ops = { + .read = sleep_auth_read, + .write = sleep_auth_write, + .open = simple_open, + .llseek = default_llseek, +}; + static int wl1271_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -988,6 +1045,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(irq_blk_threshold, rootdir); DEBUGFS_ADD(irq_timeout, rootdir); DEBUGFS_ADD(fw_stats_raw, rootdir); + DEBUGFS_ADD(sleep_auth, rootdir); streaming = debugfs_create_dir("rx_streaming", rootdir); if (!streaming || IS_ERR(streaming)) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 22b342f64b7b..7677cd55f83e 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1082,6 +1082,7 @@ int wl1271_plt_stop(struct wl1271 *wl) mutex_lock(&wl->mutex); wl1271_power_off(wl); wl->flags = 0; + wl->sleep_auth = WL1271_PSM_CAM; wl->state = WL1271_STATE_OFF; wl->plt = false; wl->rx_counter = 0; @@ -1740,6 +1741,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl->ap_fw_ps_map = 0; wl->ap_ps_map = 0; wl->sched_scanning = false; + wl->sleep_auth = WL1271_PSM_CAM; memset(wl->roles_map, 0, sizeof(wl->roles_map)); memset(wl->links_map, 0, sizeof(wl->links_map)); memset(wl->roc_map, 0, sizeof(wl->roc_map)); @@ -5174,6 +5176,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) wl->channel_type = NL80211_CHAN_NO_HT; wl->flags = 0; wl->sg_enabled = true; + wl->sleep_auth = WL1271_PSM_CAM; wl->hw_pg_ver = -1; wl->ap_ps_map = 0; wl->ap_fw_ps_map = 0; diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c index 47e81b32f7da..95d8797cfa28 100644 --- a/drivers/net/wireless/ti/wlcore/ps.c +++ b/drivers/net/wireless/ti/wlcore/ps.c @@ -76,7 +76,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) struct wl12xx_vif *wlvif; u32 timeout; - if (wl->quirks & WLCORE_QUIRK_NO_ELP) + if (wl->sleep_auth != WL1271_PSM_ELP) return; /* we shouldn't get consecutive sleep requests */ diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 761a72f4b8d1..eae8edcc5fc7 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -387,6 +387,9 @@ struct wl1271 { /* mutex for protecting the tx_flush function */ struct mutex flush_mutex; + + /* sleep auth value currently configured to FW */ + int sleep_auth; }; int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); -- GitLab From 66340e5b259bd7ca67cf0ca079dd3997fa198d4b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 10 Jun 2012 17:09:22 +0300 Subject: [PATCH 2384/6849] wlcore: allow setting sleep_auth before interface init Hold a value for sta_sleep_auth that is amenable to change by debugfs. When detecting a legal value in this variable on interface init, use it as an override value for sleep_auth. This makes debugging more intuitive using the debugfs value. Increment the conf version since we added an element to the conf structure. Note: An AP going up will always set sleep_auth to PSM_CAM. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 1 + drivers/net/wireless/ti/wl18xx/main.c | 1 + drivers/net/wireless/ti/wlcore/acx.c | 2 +- drivers/net/wireless/ti/wlcore/acx.h | 3 +++ drivers/net/wireless/ti/wlcore/conf.h | 8 +++++++- drivers/net/wireless/ti/wlcore/debugfs.c | 7 ++++++- drivers/net/wireless/ti/wlcore/init.c | 8 +++++++- drivers/net/wireless/ti/wlcore/main.c | 2 +- 8 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 85d1600ee340..7974ed55dd5b 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -246,6 +246,7 @@ static struct wlcore_conf wl12xx_conf = { .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, + .sta_sleep_auth = WL1271_PSM_ILLEGAL, }, .itrim = { .enable = false, diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b2ccff7d6188..d3f171ddebae 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -372,6 +372,7 @@ static struct wlcore_conf wl18xx_conf = { .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, + .sta_sleep_auth = WL1271_PSM_ILLEGAL, }, .itrim = { .enable = false, diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index b56217f9bfd4..3384bc14c824 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -70,7 +70,7 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) struct acx_sleep_auth *auth; int ret; - wl1271_debug(DEBUG_ACX, "acx sleep auth"); + wl1271_debug(DEBUG_ACX, "acx sleep auth %d", sleep_auth); auth = kzalloc(sizeof(*auth), GFP_KERNEL); if (!auth) { diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 168e0464411d..d03215d6b3bd 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -120,6 +120,9 @@ enum wl1271_psm_mode { WL1271_PSM_ELP = 2, WL1271_PSM_MAX = WL1271_PSM_ELP, + + /* illegal out of band value of PSM mode */ + WL1271_PSM_ILLEGAL = 0xff }; struct acx_sleep_auth { diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 03c635872335..d77224f2ac6b 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -951,6 +951,12 @@ struct conf_conn_settings { * Range: u16 */ u8 max_listen_interval; + + /* + * Default sleep authorization for a new STA interface. This determines + * whether we can go to ELP. + */ + u8 sta_sleep_auth; } __packed; enum { @@ -1276,7 +1282,7 @@ struct conf_hangover_settings { * version, the two LSB are the lower driver's private conf * version. */ -#define WLCORE_CONF_VERSION (0x0001 << 16) +#define WLCORE_CONF_VERSION (0x0002 << 16) #define WLCORE_CONF_MASK 0xffff0000 #define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \ sizeof(struct wlcore_conf)) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 91e43def013d..1768f37049bd 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -995,8 +995,13 @@ static ssize_t sleep_auth_write(struct file *file, mutex_lock(&wl->mutex); - if (wl->state == WL1271_STATE_OFF) + wl->conf.conn.sta_sleep_auth = value; + + if (wl->state == WL1271_STATE_OFF) { + /* this will show up on "read" in case we are off */ + wl->sleep_auth = value; goto out; + } ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 645abd4b660d..3fb9352bf504 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -565,7 +565,13 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) if (ret < 0) return ret; } else if (!wl->sta_count) { - if (wl->quirks & WLCORE_QUIRK_NO_ELP) { + u8 sta_auth = wl->conf.conn.sta_sleep_auth; + if (sta_auth != WL1271_PSM_ILLEGAL) { + /* Configure for power according to debugfs */ + ret = wl1271_acx_sleep_auth(wl, sta_auth); + if (ret < 0) + return ret; + } else if (wl->quirks & WLCORE_QUIRK_NO_ELP) { /* Configure for power always on */ ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); if (ret < 0) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 7677cd55f83e..69643d194301 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5176,7 +5176,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) wl->channel_type = NL80211_CHAN_NO_HT; wl->flags = 0; wl->sg_enabled = true; - wl->sleep_auth = WL1271_PSM_CAM; + wl->sleep_auth = WL1271_PSM_ILLEGAL; wl->hw_pg_ver = -1; wl->ap_ps_map = 0; wl->ap_fw_ps_map = 0; -- GitLab From 2f18cf7c3b99779465def78318b4243d1f66cce8 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 10 Jun 2012 19:10:45 +0300 Subject: [PATCH 2385/6849] wlcore: reconfigure sleep_auth when removing interfaces The sleep_auth value of the last interface to be set up prevailed when an interface was removed. Take care of this by correctly configuring the value according to the remaining STA/AP interfaces. Take this opportunity to refactor the sleep_auth setting code for better readability. [Small style fix. -- Luca] Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/acx.c | 5 ++- drivers/net/wireless/ti/wlcore/init.c | 49 ++++++++++++--------------- drivers/net/wireless/ti/wlcore/main.c | 21 ++++++++++-- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index 3384bc14c824..ce108a736bd0 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -81,8 +81,11 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) auth->sleep_auth = sleep_auth; ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) + if (ret < 0) { + wl1271_error("could not configure sleep_auth to %d: %d", + sleep_auth, ret); goto out; + } wl->sleep_auth = sleep_auth; out: diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 3fb9352bf504..8a8a8971befa 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -554,35 +554,28 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); int ret, i; - /* - * consider all existing roles before configuring psm. - * TODO: reconfigure on interface removal. - */ - if (!wl->ap_count) { - if (is_ap) { - /* Configure for power always on */ + /* consider all existing roles before configuring psm. */ + + if (wl->ap_count == 0 && is_ap) { /* first AP */ + /* Configure for power always on */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + if (ret < 0) + return ret; + /* first STA, no APs */ + } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { + u8 sta_auth = wl->conf.conn.sta_sleep_auth; + /* Configure for power according to debugfs */ + if (sta_auth != WL1271_PSM_ILLEGAL) + ret = wl1271_acx_sleep_auth(wl, sta_auth); + /* Configure for power always on */ + else if (wl->quirks & WLCORE_QUIRK_NO_ELP) ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - return ret; - } else if (!wl->sta_count) { - u8 sta_auth = wl->conf.conn.sta_sleep_auth; - if (sta_auth != WL1271_PSM_ILLEGAL) { - /* Configure for power according to debugfs */ - ret = wl1271_acx_sleep_auth(wl, sta_auth); - if (ret < 0) - return ret; - } else if (wl->quirks & WLCORE_QUIRK_NO_ELP) { - /* Configure for power always on */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - return ret; - } else { - /* Configure for ELP power saving */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - if (ret < 0) - return ret; - } - } + /* Configure for ELP power saving */ + else + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); + + if (ret < 0) + return ret; } /* Mode specific init */ diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 69643d194301..3279a94163f3 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1082,7 +1082,7 @@ int wl1271_plt_stop(struct wl1271 *wl) mutex_lock(&wl->mutex); wl1271_power_off(wl); wl->flags = 0; - wl->sleep_auth = WL1271_PSM_CAM; + wl->sleep_auth = WL1271_PSM_ILLEGAL; wl->state = WL1271_STATE_OFF; wl->plt = false; wl->rx_counter = 0; @@ -1741,7 +1741,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl->ap_fw_ps_map = 0; wl->ap_ps_map = 0; wl->sched_scanning = false; - wl->sleep_auth = WL1271_PSM_CAM; + wl->sleep_auth = WL1271_PSM_ILLEGAL; memset(wl->roles_map, 0, sizeof(wl->roles_map)); memset(wl->links_map, 0, sizeof(wl->links_map)); memset(wl->roc_map, 0, sizeof(wl->roc_map)); @@ -2148,6 +2148,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); int i, ret; + bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); @@ -2228,11 +2229,25 @@ deinit: wlvif->role_id = WL12XX_INVALID_ROLE_ID; wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID; - if (wlvif->bss_type == BSS_TYPE_AP_BSS) + if (is_ap) wl->ap_count--; else wl->sta_count--; + /* Last AP, have more stations. Configure according to STA. */ + if (wl->ap_count == 0 && is_ap && wl->sta_count) { + u8 sta_auth = wl->conf.conn.sta_sleep_auth; + /* Configure for power according to debugfs */ + if (sta_auth != WL1271_PSM_ILLEGAL) + wl1271_acx_sleep_auth(wl, sta_auth); + /* Configure for power always on */ + else if (wl->quirks & WLCORE_QUIRK_NO_ELP) + wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + /* Configure for ELP power saving */ + else + wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); + } + mutex_unlock(&wl->mutex); del_timer_sync(&wlvif->rx_streaming_timer); -- GitLab From b222a817b45c27f3411dbe9eb6b4041076351bc2 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Thu, 21 Jun 2012 08:03:56 +0000 Subject: [PATCH 2386/6849] regulator: change message level on probing lp872x driver Use err log rather than warning message when the platform data is NULL Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Mark Brown --- drivers/regulator/lp872x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index e8f54efb1985..471f8e82be41 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -885,7 +885,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) }; if (!pdata) { - dev_warn(&cl->dev, "no platform data\n"); + dev_err(&cl->dev, "no platform data\n"); return -EINVAL; } -- GitLab From f4a6348391fa029c0e230230adfafb7f33d4683e Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Thu, 21 Jun 2012 13:51:58 -0400 Subject: [PATCH 2387/6849] ASoC: bfin: use dev_err to print error log instead of dev_dbg Signed-off-by: Scott Jiang Signed-off-by: Mark Brown --- sound/soc/blackfin/bf6xx-sport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c index f19a72b8e0c2..318c5ba5360f 100644 --- a/sound/soc/blackfin/bf6xx-sport.c +++ b/sound/soc/blackfin/bf6xx-sport.c @@ -256,9 +256,9 @@ static irqreturn_t sport_err_irq(int irq, void *dev_id) struct device *dev = &sport->pdev->dev; if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI) - dev_dbg(dev, "sport error: TUVF\n"); + dev_err(dev, "sport error: TUVF\n"); if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI) - dev_dbg(dev, "sport error: ROVF\n"); + dev_err(dev, "sport error: ROVF\n"); return IRQ_HANDLED; } -- GitLab From 1c8f52a5e9539600543347bcdefafa1854e07986 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 19 Jun 2012 07:42:25 -0600 Subject: [PATCH 2388/6849] Btrfs: introduce btrfs_next_old_item We introduce btrfs_next_old_item that uses btrfs_next_old_leaf instead of btrfs_next_leaf. btrfs_next_item is also changed to simply call btrfs_next_old_item with time_seq being 0. Signed-off-by: Alexander Block Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index db15e9e7b91c..84ac723f58f8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2755,13 +2755,18 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, u64 time_seq); -static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) +static inline int btrfs_next_old_item(struct btrfs_root *root, + struct btrfs_path *p, u64 time_seq) { ++p->slots[0]; if (p->slots[0] >= btrfs_header_nritems(p->nodes[0])) - return btrfs_next_leaf(root, p); + return btrfs_next_old_leaf(root, p, time_seq); return 0; } +static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) +{ + return btrfs_next_old_item(root, p, 0); +} int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); int __must_check btrfs_drop_snapshot(struct btrfs_root *root, -- GitLab From 69bca40d41c613927b150c5392505f1894fe3010 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 19 Jun 2012 07:42:26 -0600 Subject: [PATCH 2389/6849] Btrfs: don't assume to be on the correct extent in add_all_parents add_all_parents did assume that path is already at a correct extent data item, which may not be true in case of data extents that were partly rewritten and splitted. We need to check if we're on a matching extent for every item and only for the ones after the first. The loop is changed to do this now. This patch also fixes a bug introduced with commit 3b127fd8 "Btrfs: remove obsolete btrfs_next_leaf call from __resolve_indirect_ref". The removal of next_leaf did sometimes result in slot==nritems when the above described case happens, and thus resulting in invalid values (e.g. wanted_obejctid) in add_all_parents (leading to missed backrefs or even crashes). Signed-off-by: Alexander Block Signed-off-by: Jan Schmidt Signed-off-by: Chris Mason --- fs/btrfs/backref.c | 94 +++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 8f7d1237b7a0..7301cdb4b2cb 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -179,61 +179,74 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id, static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, struct ulist *parents, int level, - struct btrfs_key *key, u64 time_seq, + struct btrfs_key *key_for_search, u64 time_seq, u64 wanted_disk_byte, const u64 *extent_item_pos) { - int ret; - int slot = path->slots[level]; - struct extent_buffer *eb = path->nodes[level]; + int ret = 0; + int slot; + struct extent_buffer *eb; + struct btrfs_key key; struct btrfs_file_extent_item *fi; struct extent_inode_elem *eie = NULL; u64 disk_byte; - u64 wanted_objectid = key->objectid; -add_parent: - if (level == 0 && extent_item_pos) { - fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); - ret = check_extent_in_eb(key, eb, fi, *extent_item_pos, &eie); + if (level != 0) { + eb = path->nodes[level]; + ret = ulist_add(parents, eb->start, 0, GFP_NOFS); if (ret < 0) return ret; - } - ret = ulist_add(parents, eb->start, (unsigned long)eie, GFP_NOFS); - if (ret < 0) - return ret; - - if (level != 0) return 0; + } /* - * if the current leaf is full with EXTENT_DATA items, we must - * check the next one if that holds a reference as well. - * ref->count cannot be used to skip this check. - * repeat this until we don't find any additional EXTENT_DATA items. + * We normally enter this function with the path already pointing to + * the first item to check. But sometimes, we may enter it with + * slot==nritems. In that case, go to the next leaf before we continue. */ - while (1) { - eie = NULL; + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) ret = btrfs_next_old_leaf(root, path, time_seq); - if (ret < 0) - return ret; - if (ret) - return 0; + while (!ret) { eb = path->nodes[0]; - for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) { - btrfs_item_key_to_cpu(eb, key, slot); - if (key->objectid != wanted_objectid || - key->type != BTRFS_EXTENT_DATA_KEY) - return 0; - fi = btrfs_item_ptr(eb, slot, - struct btrfs_file_extent_item); - disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); - if (disk_byte == wanted_disk_byte) - goto add_parent; + slot = path->slots[0]; + + btrfs_item_key_to_cpu(eb, &key, slot); + + if (key.objectid != key_for_search->objectid || + key.type != BTRFS_EXTENT_DATA_KEY) + break; + + fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); + disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); + + if (disk_byte == wanted_disk_byte) { + eie = NULL; + if (extent_item_pos) { + ret = check_extent_in_eb(&key, eb, fi, + *extent_item_pos, + &eie); + if (ret < 0) + break; + } + if (!ret) { + ret = ulist_add(parents, eb->start, + (unsigned long)eie, GFP_NOFS); + if (ret < 0) + break; + if (!extent_item_pos) { + ret = btrfs_next_old_leaf(root, path, + time_seq); + continue; + } + } } + ret = btrfs_next_old_item(root, path, time_seq); } - return 0; + if (ret > 0) + ret = 0; + return ret; } /* @@ -250,7 +263,6 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, struct btrfs_path *path; struct btrfs_root *root; struct btrfs_key root_key; - struct btrfs_key key = {0}; struct extent_buffer *eb; int ret = 0; int root_level; @@ -295,11 +307,9 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, goto out; } - if (level == 0) - btrfs_item_key_to_cpu(eb, &key, path->slots[0]); - - ret = add_all_parents(root, path, parents, level, &key, time_seq, - ref->wanted_disk_byte, extent_item_pos); + ret = add_all_parents(root, path, parents, level, &ref->key_for_search, + time_seq, ref->wanted_disk_byte, + extent_item_pos); out: btrfs_free_path(path); return ret; -- GitLab From e18fca734278784bd6591de63ca148cc27344ca9 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 18 Jun 2012 07:23:18 -0600 Subject: [PATCH 2390/6849] Btrfs: add a missing spin_lock When fixing up the locking in the delayed ref destruction work I accidently broke the locking myself ;(. Add back a spin_lock that should be there and we are now all set. Thanks, Btrfs: add a missing spin_lock When fixing up the locking in the delayed ref destruction work I accidently broke the locking myself ;(. Add back a spin_lock that should be there and we are now all set. Thanks, Reported-by: Dan Carpenter Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/disk-io.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e22c5bbf0223..7d7bc8eace86 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3426,6 +3426,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, mutex_unlock(&head->mutex); btrfs_put_delayed_ref(ref); + spin_lock(&delayed_refs->lock); continue; } -- GitLab From cb77fcd88569cd2b7b25ecd4086ea932a53be9b3 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 15 Jun 2012 12:19:48 -0600 Subject: [PATCH 2391/6849] Btrfs: delay iput with async extents There is some concern that these iput()'s could be the final iputs and could induce lockups on people waiting on writeback. This would happen in the rare case that we don't create ordered extents because of an error, but it is theoretically possible and we already have a mechanism to deal with this so just make them delayed iputs to negate any worry. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3f2c8cbe5ba6..4a4f2d59a64b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -987,7 +987,7 @@ static noinline void async_cow_start(struct btrfs_work *work) async_cow->start, async_cow->end, async_cow, &num_added); if (num_added == 0) { - iput(async_cow->inode); + btrfs_add_delayed_iput(async_cow->inode); async_cow->inode = NULL; } } @@ -1023,7 +1023,7 @@ static noinline void async_cow_free(struct btrfs_work *work) struct async_cow *async_cow; async_cow = container_of(work, struct async_cow, work); if (async_cow->inode) - iput(async_cow->inode); + btrfs_add_delayed_iput(async_cow->inode); kfree(async_cow); } -- GitLab From ce7d16a1752accbff1ff7c813594aad0b7168563 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jun 2012 10:05:56 -0300 Subject: [PATCH 2392/6849] [media] smiapp-core: fix compilation build error smiapp-core.c:2472:3: error: implicit declaration of function 'kzalloc' [-Werror=implicit-function-declaration] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/smiapp/smiapp-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c index e8c93c89265a..9cf5bda35fbe 100644 --- a/drivers/media/video/smiapp/smiapp-core.c +++ b/drivers/media/video/smiapp/smiapp-core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include -- GitLab From b6a509df59c6abd0a2177e3be29642207711145d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 20 Jun 2012 21:30:30 -0300 Subject: [PATCH 2393/6849] [media] media: pms.c needs linux/slab.h drivers/media/video/pms.c uses kzalloc() and kfree() so it should include to fix build errors and a warning. drivers/media/video/pms.c:1047:2: error: implicit declaration of function 'kzalloc' drivers/media/video/pms.c:1047:6: warning: assignment makes pointer from integer without a cast drivers/media/video/pms.c:1116:2: error: implicit declaration of function 'kfree' Found in mmotm but applies to mainline. Signed-off-by: Randy Dunlap Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 77f9c92186f4..b4c679b3fb0f 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include -- GitLab From 09aad14f6533d0db47b8077792fcb7c8fc881cf1 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 10 Jun 2012 22:57:30 +0300 Subject: [PATCH 2394/6849] wl18xx: increase Rx descriptors for PG2 New PG2 firmwares have additional Rx descriptors. Add a module parameter to manually set the number of Rx descriptors for older versions (PG1). We cannot discriminate based on chip-id, since this value must be set on probe. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index d3f171ddebae..18cf19c12941 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -47,6 +47,7 @@ static char *ht_mode_param = "wide"; static char *board_type_param = "hdk"; static bool checksum_param = false; static bool enable_11a_param = true; +static int num_rx_desc_param = -1; /* phy paramters */ static int dc2dc_param = -1; @@ -1286,7 +1287,7 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) wl->ptable = wl18xx_ptable; wl->rtable = wl18xx_rtable; wl->num_tx_desc = 32; - wl->num_rx_desc = 16; + wl->num_rx_desc = 32; wl->band_rate_to_idx = wl18xx_band_rate_to_idx; wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; @@ -1294,6 +1295,9 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); + if (num_rx_desc_param != -1) + wl->num_rx_desc = num_rx_desc_param; + if (!strcmp(ht_mode_param, "wide")) { memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl18xx_siso40_ht_cap, @@ -1458,6 +1462,11 @@ module_param_named(pwr_limit_reference_11_abg, MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " "(default is 0xc8)"); +module_param_named(num_rx_desc, + num_rx_desc_param, int, S_IRUSR); +MODULE_PARM_DESC(num_rx_desc_param, + "Number of Rx descriptors: u8 (default is 32)"); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); -- GitLab From bf7c46a7672830eb13898b2871de7780448f0674 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 11 Jun 2012 10:41:08 +0300 Subject: [PATCH 2395/6849] wl18xx: set Tx align quirk for PG2 Before patch b5d6d9b (wlcore/wl12xx/wl18xx: don't use TX align quirk for wl127x), this was automatically set for all platforms. As this should now be set explicitly, set it for PG2 as well. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 18cf19c12941..066e8e5cbb66 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -608,8 +608,8 @@ static int wl18xx_identify_chip(struct wl1271 *wl) wl->plt_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | + WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | WLCORE_QUIRK_TX_PAD_LAST_FRAME; - break; case CHIP_ID_185x_PG10: wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", -- GitLab From add779a0738a6bd199b3c5b9f0f8090036e53ff0 Mon Sep 17 00:00:00 2001 From: Yoni Divinsky Date: Wed, 13 Jun 2012 18:56:54 +0300 Subject: [PATCH 2396/6849] wlcore: do not report noise level in get survey op The get survey op expects the low level driver to report the noise level for a a given channel. The noise calculated in wlcore is (rssi-snr/2), but since the snr reported by the FW is a derivative from the rssi this calculation is useless, and should not be reported to the user space. Reporting incorrect noise, results in the wpa_supplicant miscalculating the roaming candidate priority, thus causing a situation where an AP with a lower rssi level would be chosen over a better AP. Signed-off-by: Yoni Divinsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 3279a94163f3..a7c5e32e90db 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4108,16 +4108,13 @@ out: static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) { - struct wl1271 *wl = hw->priv; struct ieee80211_conf *conf = &hw->conf; if (idx != 0) return -ENOENT; survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = wl->noise; - + survey->filled = 0; return 0; } -- GitLab From 1e41213fe738e8f8e3fd69dd490ac7e4faaa184f Mon Sep 17 00:00:00 2001 From: Igal Chernobelsky Date: Mon, 18 Jun 2012 11:05:39 +0300 Subject: [PATCH 2397/6849] wlcore: read FW logs from FW memory on watchdog recovery FW uses a few memory blocks as a buffer to accumulate FW logs before transmitting them to the host over SDIO. When FW WatchDog recovery occurs, the last FW traces are still pending in the buffer. Driver is to read these FW traces whether log mode is continuous or on demand. FW memory blocks allocated for the log buffer are handled as a link list: the first 4 bytes in each memory block contain FW address to the next block. The end of list condition depends on FW log mode: - on demand: the list is cyclic, the next address is equal to the first address - continuous: the address is equal to 0x2000000 Log data resides inside FW memory block with offset depending on logger mode: - on demand: 4 bytes (address of the next memory block) - continuous: 4 bytes and Rx Descriptor structure size Described FW logger API is backward compatible with previous FW versions. Signed-off-by: Igal Chernobelsky Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 34 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index a7c5e32e90db..78edc58da210 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -770,14 +770,16 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) return len; } +#define WLCORE_FW_LOG_END 0x2000000 + static void wl12xx_read_fwlog_panic(struct wl1271 *wl) { u32 addr; - u32 first_addr; + u32 offset; + u32 end_of_log; u8 *block; if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) || - (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) || (wl->conf.fwlog.mem_blocks == 0)) return; @@ -791,19 +793,26 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) * Make sure the chip is awake and the logger isn't active. * Do not send a stop fwlog command if the fw is hanged. */ - if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery) - wl12xx_cmd_stop_fwlog(wl); - else + if (wl1271_ps_elp_wakeup(wl)) goto out; + if (!wl->watchdog_recovery) + wl12xx_cmd_stop_fwlog(wl); /* Read the first memory block address */ wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); - first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr); - if (!first_addr) + addr = le32_to_cpu(wl->fw_status_2->log_start_addr); + if (!addr) goto out; + if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) { + offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor); + end_of_log = WLCORE_FW_LOG_END; + } else { + offset = sizeof(addr); + end_of_log = addr; + } + /* Traverse the memory blocks linked list */ - addr = first_addr; do { memset(block, 0, WL12XX_HW_BLOCK_SIZE); wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, @@ -812,13 +821,14 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) /* * Memory blocks are linked to one another. The first 4 bytes * of each memory block hold the hardware address of the next - * one. The last memory block points to the first one. + * one. The last memory block points to the first one in + * on demand mode and is equal to 0x2000000 in continuous mode. */ addr = le32_to_cpup((__le32 *)block); - if (!wl12xx_copy_fwlog(wl, block + sizeof(addr), - WL12XX_HW_BLOCK_SIZE - sizeof(addr))) + if (!wl12xx_copy_fwlog(wl, block + offset, + WL12XX_HW_BLOCK_SIZE - offset)) break; - } while (addr && (addr != first_addr)); + } while (addr && (addr != end_of_log)); wake_up_interruptible(&wl->fwlog_waitq); -- GitLab From 68a847f2c1ea2b974a28c5b537fe846522d7a9c0 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 13 Jun 2012 19:09:24 +0300 Subject: [PATCH 2398/6849] wl18xx: explicitly remove the 5Ghz MIMO HT cap The 18xx chip does not support MIMO in 5Ghz. Use the siso20 HT cap as fallback in 5Ghz when "mimo" is requested. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 066e8e5cbb66..365063b6f7c3 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1255,18 +1255,6 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { }, }; -static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_5ghz = { - .cap = IEEE80211_HT_CAP_SGI_20, - .ht_supported = true, - .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .mcs = { - .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(72), - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, - }, -}; - static int __devinit wl18xx_probe(struct platform_device *pdev) { struct wl1271 *wl; @@ -1309,9 +1297,10 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl18xx_mimo_ht_cap_2ghz, sizeof(wl18xx_mimo_ht_cap_2ghz)); + /* we don't support MIMO in 5Ghz */ memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], - &wl18xx_mimo_ht_cap_5ghz, - sizeof(wl18xx_mimo_ht_cap_5ghz)); + &wl18xx_siso20_ht_cap, + sizeof(wl18xx_siso20_ht_cap)); } else if (!strcmp(ht_mode_param, "siso20")) { memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl18xx_siso20_ht_cap, -- GitLab From fa2adfcdbd88124e8b7cc46c6363b1343dabc09d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 13 Jun 2012 19:09:25 +0300 Subject: [PATCH 2399/6849] wl18xx: sane defaults for HT capabilities Introduce a default set of HT capabilities that are set according to the number of antennas on the board. Move the HT setting code down to allow the number of antennas to be set (and optionally overridden) before it. Remove the "mimo" HT option, since the default mode now enables MIMO is possible. Use this opportunity to add a helper function for setting HT capabilities and reduce the volume of the code a bit. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 6 +-- drivers/net/wireless/ti/wl18xx/main.c | 63 +++++++++++++------------ drivers/net/wireless/ti/wlcore/wlcore.h | 7 +++ 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 7974ed55dd5b..0d2fdca2aa32 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1449,10 +1449,8 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = 0; wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); - memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl12xx_ht_cap, - sizeof(wl12xx_ht_cap)); - memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], &wl12xx_ht_cap, - sizeof(wl12xx_ht_cap)); + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap); + wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap); wl12xx_conf_init(wl); if (!fref_param) { diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 365063b6f7c3..485aeae2f777 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -43,7 +43,7 @@ #define WL18XX_RX_CHECKSUM_MASK 0x40 -static char *ht_mode_param = "wide"; +static char *ht_mode_param = "default"; static char *board_type_param = "hdk"; static bool checksum_param = false; static bool enable_11a_param = true; @@ -1286,34 +1286,6 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) if (num_rx_desc_param != -1) wl->num_rx_desc = num_rx_desc_param; - if (!strcmp(ht_mode_param, "wide")) { - memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], - &wl18xx_siso40_ht_cap, - sizeof(wl18xx_siso40_ht_cap)); - memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], - &wl18xx_siso40_ht_cap, - sizeof(wl18xx_siso40_ht_cap)); - } else if (!strcmp(ht_mode_param, "mimo")) { - memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], - &wl18xx_mimo_ht_cap_2ghz, - sizeof(wl18xx_mimo_ht_cap_2ghz)); - /* we don't support MIMO in 5Ghz */ - memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], - &wl18xx_siso20_ht_cap, - sizeof(wl18xx_siso20_ht_cap)); - } else if (!strcmp(ht_mode_param, "siso20")) { - memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], - &wl18xx_siso20_ht_cap, - sizeof(wl18xx_siso20_ht_cap)); - memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], - &wl18xx_siso20_ht_cap, - sizeof(wl18xx_siso20_ht_cap)); - } else { - wl1271_error("invalid ht_mode '%s'", ht_mode_param); - ret = -EINVAL; - goto out_free; - } - ret = wl18xx_conf_init(wl, &pdev->dev); if (ret < 0) goto out_free; @@ -1359,6 +1331,37 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) if (dc2dc_param != -1) priv->conf.phy.external_pa_dc2dc = dc2dc_param; + if (!strcmp(ht_mode_param, "default")) { + /* + * Only support mimo with multiple antennas. Fall back to + * siso20. + */ + if (priv->conf.phy.number_of_assembled_ant2_4 >= 2) + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, + &wl18xx_mimo_ht_cap_2ghz); + else + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, + &wl18xx_siso20_ht_cap); + + /* 5Ghz is always wide */ + wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, + &wl18xx_siso40_ht_cap); + } else if (!strcmp(ht_mode_param, "wide")) { + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, + &wl18xx_siso40_ht_cap); + wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, + &wl18xx_siso40_ht_cap); + } else if (!strcmp(ht_mode_param, "siso20")) { + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, + &wl18xx_siso20_ht_cap); + wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, + &wl18xx_siso20_ht_cap); + } else { + wl1271_error("invalid ht_mode '%s'", ht_mode_param); + ret = -EINVAL; + goto out_free; + } + if (!checksum_param) { wl18xx_ops.set_rx_csum = NULL; wl18xx_ops.init_vif = NULL; @@ -1403,7 +1406,7 @@ static void __exit wl18xx_exit(void) module_exit(wl18xx_exit); module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); -MODULE_PARM_DESC(ht_mode, "Force HT mode: wide (default), mimo or siso20"); +MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); module_param_named(board_type, board_type_param, charp, S_IRUSR); MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index eae8edcc5fc7..205d8ad2b761 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -401,6 +401,13 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, struct ieee80211_sta *sta, struct ieee80211_key_conf *key_conf); +static inline void +wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, + struct ieee80211_sta_ht_cap *ht_cap) +{ + memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); +} + /* Firmware image load chunk size */ #define CHUNK_SIZE 16384 -- GitLab From 93fb19bbb37c734ec0c662aa600d1d6a12c1be70 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 13 Jun 2012 19:09:26 +0300 Subject: [PATCH 2400/6849] wl18xx: split siso40 HT cap between 2Ghz and 5Ghz Remove the cap IEEE80211_HT_CAP_DSSSCCK40 from the 5Ghz variant of the siso40 HT capabilities. It is meaningless in 5Ghz. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 485aeae2f777..2c0f51b449c4 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1215,8 +1215,8 @@ static struct wlcore_ops wl18xx_ops = { .pre_pkt_send = wl18xx_pre_pkt_send, }; -/* HT cap appropriate for wide channels */ -static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = { +/* HT cap appropriate for wide channels in 2Ghz */ +static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, .ht_supported = true, @@ -1229,6 +1229,20 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = { }, }; +/* HT cap appropriate for wide channels in 5Ghz */ +static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = { + .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SUP_WIDTH_20_40, + .ht_supported = true, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .mcs = { + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(150), + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, +}; + /* HT cap appropriate for SISO 20 */ static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { .cap = IEEE80211_HT_CAP_SGI_20, @@ -1345,12 +1359,12 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) /* 5Ghz is always wide */ wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, - &wl18xx_siso40_ht_cap); + &wl18xx_siso40_ht_cap_5ghz); } else if (!strcmp(ht_mode_param, "wide")) { wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, - &wl18xx_siso40_ht_cap); + &wl18xx_siso40_ht_cap_2ghz); wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, - &wl18xx_siso40_ht_cap); + &wl18xx_siso40_ht_cap_5ghz); } else if (!strcmp(ht_mode_param, "siso20")) { wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl18xx_siso20_ht_cap); -- GitLab From 41844076c5c3a33636b5c26d19b16c6141c5d6cd Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 21 Jun 2012 15:33:10 +0300 Subject: [PATCH 2401/6849] wl18xx: use %zu for size_t arguments in printk calls After 934b9d1e (wl18xx: avoid some -Wformat warnings) there was still a warning with (at least) ARM gcc version 4.4.1: drivers/net/wireless/ti/wl18xx/main.c: In function 'wl18xx_conf_init': drivers/net/wireless/ti/wl18xx/main.c:1026: warning: format '%ld' expects type 'long int', but argument 2 has type 'unsigned int' Fix this by using %zu for the both formats, since the fw->size and the macro (derived from sizeof()) are size_t. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 2c0f51b449c4..271ff81da922 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1023,8 +1023,8 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) } if (fw->size != WL18XX_CONF_SIZE) { - wl1271_error("configuration binary file size is wrong, " - "expected %d got %d", WL18XX_CONF_SIZE, fw->size); + wl1271_error("configuration binary file size is wrong, expected %zu got %zu", + WL18XX_CONF_SIZE, fw->size); ret = -EINVAL; goto out; } -- GitLab From 8e5a050901a16a62a7d2d4d4ef285eec8ae7203e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Jun 2012 15:49:33 +0200 Subject: [PATCH 2402/6849] ALSA: hda - Fix ALC272X codec detection The codec ALC272X is a special codec for some Dell machines, and its detection got broken in the recent kernel because SSID check (required by ALC272X check) was moved to the later point. Now we need to move this codec check to the right place, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f8f4906e498d..41475ae0e769 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6705,6 +6705,12 @@ static int patch_alc662(struct hda_codec *codec) alc_fix_pll_init(codec, 0x20, 0x04, 15); + alc_pick_fixup(codec, alc662_fixup_models, + alc662_fixup_tbl, alc662_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + + alc_auto_parse_customize_define(codec); + if ((alc_get_coef0(codec) & (1 << 14)) && codec->bus->pci->subsystem_vendor == 0x1025 && spec->cdefine.platform_type == 1) { @@ -6712,12 +6718,6 @@ static int patch_alc662(struct hda_codec *codec) goto error; } - alc_pick_fixup(codec, alc662_fixup_models, - alc662_fixup_tbl, alc662_fixups); - alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - - alc_auto_parse_customize_define(codec); - /* automatic parse from the BIOS config */ err = alc662_parse_auto_config(codec); if (err < 0) -- GitLab From e734568b675c985db2026848fefaac01c22977a5 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 8 Jun 2012 16:16:04 +0100 Subject: [PATCH 2403/6849] oprofile: perf: use NR_CPUS instead or nr_cpumask_bits for static array The OProfile perf backend uses a static array to keep track of the perf events on the system. When compiling with CONFIG_CPUMASK_OFFSTACK=y && SMP, nr_cpumask_bits is not a compile-time constant and the build will fail with: oprofile_perf.c:28: error: variably modified 'perf_events' at file scope This patch uses NR_CPUs instead of nr_cpumask_bits for the array initialisation. If this causes space problems in the future, we can always move to dynamic allocation for the events array. Cc: Matt Fleming Reported-by: Russell King - ARM Linux Signed-off-by: Will Deacon Cc: # v2.6.37+ Signed-off-by: Robert Richter --- drivers/oprofile/oprofile_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index da14432806c6..efc4b7f308cf 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c @@ -25,7 +25,7 @@ static int oprofile_perf_enabled; static DEFINE_MUTEX(oprofile_perf_mutex); static struct op_counter_config *counter_config; -static struct perf_event **perf_events[nr_cpumask_bits]; +static struct perf_event **perf_events[NR_CPUS]; static int num_counters; /* -- GitLab From 66572cfc30a4b764150c83ee5d842a3ce17991c9 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Thu, 21 Jun 2012 10:56:46 +0300 Subject: [PATCH 2404/6849] mac80211: add command to get current rssi Get current rssi (in dBm) from the driver/FW. Instead of reporting the signal received in the last rx packet, which might be inaccurate if rx traffic is low and beacon filtering is enabled, get the signal from the driver/FW. Signed-off-by: Victor Goldenshtein Signed-off-by: Johannes Berg --- include/net/mac80211.h | 5 +++++ net/mac80211/cfg.c | 21 +++++++++++++-------- net/mac80211/driver-ops.h | 15 +++++++++++++++ net/mac80211/driver-trace.h | 26 ++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d152f54064fd..f11c2f8b00c9 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2249,6 +2249,9 @@ enum ieee80211_rate_control_changed { * @get_et_strings: Ethtool API to get a set of strings to describe stats * and perhaps other supported types of ethtool data-sets. * + * @get_rssi: Get current signal strength in dBm, the function is optional + * and can sleep. + * */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -2388,6 +2391,8 @@ struct ieee80211_ops { void (*get_et_strings)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 sset, u8 *data); + int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, s8 *rssi_dbm); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 03aff23c70fd..d0c8f78115cb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -353,6 +353,7 @@ void sta_set_rate_info_tx(struct sta_info *sta, static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_local *local = sdata->local; struct timespec uptime; sinfo->generation = sdata->local->sta_generation; @@ -388,7 +389,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; - sinfo->signal = (s8)sta->last_signal; + if (!local->ops->get_rssi || + drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) + sinfo->signal = (s8)sta->last_signal; sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } @@ -517,7 +520,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, * network device. */ - rcu_read_lock(); + mutex_lock(&local->sta_mtx); if (sdata->vif.type == NL80211_IFTYPE_STATION) { sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); @@ -546,7 +549,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, data[i] = (u8)sinfo.signal_avg; i++; } else { - list_for_each_entry_rcu(sta, &local->sta_list, list) { + list_for_each_entry(sta, &local->sta_list, list) { /* Make sure this station belongs to the proper dev */ if (sta->sdata->dev != dev) continue; @@ -603,7 +606,7 @@ do_survey: else data[i++] = -1LL; - rcu_read_unlock(); + mutex_unlock(&local->sta_mtx); if (WARN_ON(i != STA_STATS_LEN)) return; @@ -629,10 +632,11 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; struct sta_info *sta; int ret = -ENOENT; - rcu_read_lock(); + mutex_lock(&local->sta_mtx); sta = sta_info_get_by_idx(sdata, idx); if (sta) { @@ -641,7 +645,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, sta_set_sinfo(sta, sinfo); } - rcu_read_unlock(); + mutex_unlock(&local->sta_mtx); return ret; } @@ -658,10 +662,11 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; struct sta_info *sta; int ret = -ENOENT; - rcu_read_lock(); + mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, mac); if (sta) { @@ -669,7 +674,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, sta_set_sinfo(sta, sinfo); } - rcu_read_unlock(); + mutex_unlock(&local->sta_mtx); return ret; } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 6d33a0c743ab..933026949df9 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -845,4 +845,19 @@ drv_allow_buffered_frames(struct ieee80211_local *local, more_data); trace_drv_return_void(local); } + +static inline int drv_get_rssi(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, + s8 *rssi_dbm) +{ + int ret; + + might_sleep(); + + ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm); + trace_drv_get_rssi(local, sta, *rssi_dbm, ret); + + return ret; +} #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 6de00b2c268c..a0f7d357884d 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -1218,6 +1218,32 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames, TP_ARGS(local, sta, tids, num_frames, reason, more_data) ); +TRACE_EVENT(drv_get_rssi, + TP_PROTO(struct ieee80211_local *local, struct ieee80211_sta *sta, + s8 rssi, int ret), + + TP_ARGS(local, sta, rssi, ret), + + TP_STRUCT__entry( + LOCAL_ENTRY + STA_ENTRY + __field(s8, rssi) + __field(int, ret) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + STA_ASSIGN; + __entry->rssi = rssi; + __entry->ret = ret; + ), + + TP_printk( + LOCAL_PR_FMT STA_PR_FMT " rssi:%d ret:%d", + LOCAL_PR_ARG, STA_PR_ARG, __entry->rssi, __entry->ret + ) +); + /* * Tracing for API calls that drivers call. */ -- GitLab From c2ebea2097f84f0973c58b8467c1a2236bbb307a Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 20 Jun 2012 17:59:01 -0700 Subject: [PATCH 2405/6849] ieee80211: more OUI type definitions for WLAN_OUI_MICROSOFT WMM and WPS Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 6e0601189db9..318fc1f705b1 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1633,6 +1633,8 @@ enum ieee80211_sa_query_action { #define WLAN_OUI_TYPE_WFA_P2P 9 #define WLAN_OUI_MICROSOFT 0x0050f2 #define WLAN_OUI_TYPE_MICROSOFT_WPA 1 +#define WLAN_OUI_TYPE_MICROSOFT_WMM 2 +#define WLAN_OUI_TYPE_MICROSOFT_WPS 4 /* * WMM/802.11e Tspec Element -- GitLab From b3c5dce81584391af8b6dedb0647e65c17aab3a2 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 21 Jun 2012 16:03:01 +0200 Subject: [PATCH 2406/6849] ALSA: HDA: Add inverted internal mic quirk for Lenovo S205 The Lenovo Ideapad S205 has an internal mic where the right channel is phase inverted. BugLink: https://bugs.launchpad.net/bugs/884652 Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 172370b3793b..2af0868f78ad 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -4466,6 +4466,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), {} }; -- GitLab From 9751d7627582fc1cc64625d63bde9528c14f1544 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 21 Jun 2012 10:25:03 -0700 Subject: [PATCH 2407/6849] x86-64, reboot: Be more paranoid in 64-bit reboot=bios Be a bit more paranoid in the transition back to 16-bit mode. In particular, in case the kernel is residing above the 4 GiB mark, switch to the trampoline GDT, and make the jump after turning off paging a far jump. In theory, none of this should matter, but it is exactly the kind of things that broken SMM or virtualization software could trip up on. Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/r/tip-jopx7y6g6dbcx4tpal8q0jlr@git.kernel.org --- arch/x86/realmode/rm/reboot.S | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/realmode/rm/reboot.S b/arch/x86/realmode/rm/reboot.S index 6bf8feac5557..f932ea61d1c8 100644 --- a/arch/x86/realmode/rm/reboot.S +++ b/arch/x86/realmode/rm/reboot.S @@ -22,14 +22,18 @@ ENTRY(machine_real_restart_asm) #ifdef CONFIG_X86_64 + /* Switch to trampoline GDT as it is guaranteed < 4 GiB */ + movl $__KERNEL_DS, %eax + movl %eax, %ds + lgdtl pa_tr_gdt /* Disable paging to drop us out of long mode */ movl %cr0, %eax andl $~X86_CR0_PG, %eax movl %eax, %cr0 - jmp 1f /* "A branch" may be needed here, assume near is OK */ + ljmpl $__KERNEL32_CS, $pa_machine_real_restart_paging_off -1: +GLOBAL(machine_real_restart_paging_off) xorl %eax, %eax xorl %edx, %edx movl $MSR_EFER, %ecx -- GitLab From 9a3a5dab63461b84213052888bf38a962b22d035 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 11 Jun 2012 10:39:43 -0400 Subject: [PATCH 2408/6849] xfs: check for stale inode before acquiring iflock on push An inode in the AIL can be flush locked and marked stale if a cluster free transaction occurs at the right time. The inode item is then marked as flushing, which causes xfsaild to spin and leaves the filesystem stalled. This is reproduced by running xfstests 273 in a loop for an extended period of time. Check for stale inodes before the flush lock. This marks the inode as pinned, leads to a log flush and allows the filesystem to proceed. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_inode_item.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 6cdbf90c6f7b..d041d47d9d86 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -504,6 +504,14 @@ xfs_inode_item_push( goto out_unlock; } + /* + * Stale inode items should force out the iclog. + */ + if (ip->i_flags & XFS_ISTALE) { + rval = XFS_ITEM_PINNED; + goto out_unlock; + } + /* * Someone else is already flushing the inode. Nothing we can do * here but wait for the flush to finish and remove the item from @@ -514,15 +522,6 @@ xfs_inode_item_push( goto out_unlock; } - /* - * Stale inode items should force out the iclog. - */ - if (ip->i_flags & XFS_ISTALE) { - xfs_ifunlock(ip); - xfs_iunlock(ip, XFS_ILOCK_SHARED); - return XFS_ITEM_PINNED; - } - ASSERT(iip->ili_fields != 0 || XFS_FORCED_SHUTDOWN(ip->i_mount)); ASSERT(iip->ili_logged == 0 || XFS_FORCED_SHUTDOWN(ip->i_mount)); -- GitLab From 76d095388b040229ea1aad7dea45be0cfa20f589 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 12 Jun 2012 14:20:26 +1000 Subject: [PATCH 2409/6849] xfs: fix allocbt cursor leak in xfs_alloc_ag_vextent_near When we fail to find an matching extent near the requested extent specification during a left-right distance search in xfs_alloc_ag_vextent_near, we fail to free the original cursor that we used to look up the XFS_BTNUM_CNT tree and hence leak it. Reported-by: Chris J Arges Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Ben Myers --- fs/xfs/xfs_alloc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index a996e398692b..9d1aeb7e2734 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -1080,6 +1080,7 @@ restart: goto restart; } + xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); trace_xfs_alloc_size_neither(args); args->agbno = NULLAGBLOCK; return 0; -- GitLab From 59c84ed0ddc11f1823b4a33ace4fbcc948261bb2 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 6 Jun 2012 00:32:26 +0200 Subject: [PATCH 2410/6849] xfs: Fix overallocation in xfs_buf_allocate_memory() Commit de1cbee which removed b_file_offset in favor of b_bn introduced a bug causing xfs_buf_allocate_memory() to overestimate the number of necessary pages. The problem is that xfs_buf_alloc() sets b_bn to -1 and thus effectively every buffer is straddling a page boundary which causes xfs_buf_allocate_memory() to allocate two pages and use vmalloc() for access which is unnecessary. Dave says xfs_buf_alloc() doesn't need to set b_bn to -1 anymore since the buffer is inserted into the cache only after being fully initialized now. So just make xfs_buf_alloc() fill in proper block number from the beginning. CC: David Chinner Signed-off-by: Jan Kara Reviewed-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Ben Myers --- fs/xfs/xfs_buf.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 172d3cc8f8cb..a4beb421018a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -201,14 +201,7 @@ xfs_buf_alloc( bp->b_length = numblks; bp->b_io_length = numblks; bp->b_flags = flags; - - /* - * We do not set the block number here in the buffer because we have not - * finished initialising the buffer. We insert the buffer into the cache - * in this state, so this ensures that we are unable to do IO on a - * buffer that hasn't been fully initialised. - */ - bp->b_bn = XFS_BUF_DADDR_NULL; + bp->b_bn = blkno; atomic_set(&bp->b_pin_count, 0); init_waitqueue_head(&bp->b_waiters); @@ -567,11 +560,6 @@ xfs_buf_get( if (bp != new_bp) xfs_buf_free(new_bp); - /* - * Now we have a workable buffer, fill in the block number so - * that we can do IO on it. - */ - bp->b_bn = blkno; bp->b_io_length = bp->b_length; found: @@ -772,7 +760,7 @@ xfs_buf_get_uncached( int error, i; xfs_buf_t *bp; - bp = xfs_buf_alloc(target, 0, numblks, 0); + bp = xfs_buf_alloc(target, XFS_BUF_DADDR_NULL, numblks, 0); if (unlikely(bp == NULL)) goto fail; -- GitLab From 8866fc6fa55e31b2bce931b7963ff16641b39dc7 Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Fri, 25 May 2012 15:45:36 -0500 Subject: [PATCH 2411/6849] xfs: shutdown xfs_sync_worker before the log Revert commit 1307bbd, which uses the s_umount semaphore to provide exclusion between xfs_sync_worker and unmount, in favor of shutting down the sync worker before freeing the log in xfs_log_unmount. This is a cleaner way of resolving the race between xfs_sync_worker and unmount than using s_umount. Signed-off-by: Ben Myers Reviewed-by: Mark Tinguely Reviewed-by: Dave Chinner --- fs/xfs/xfs_log.c | 1 + fs/xfs/xfs_sync.c | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index f30d9807dc48..0e1a64f0439c 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -810,6 +810,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) void xfs_log_unmount(xfs_mount_t *mp) { + cancel_delayed_work_sync(&mp->m_sync_work); xfs_trans_ail_destroy(mp); xlog_dealloc_log(mp->m_log); } diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index c9d3409c5ca3..1e9ee064dbb2 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c @@ -386,23 +386,23 @@ xfs_sync_worker( * We shouldn't write/force the log if we are in the mount/unmount * process or on a read only filesystem. The workqueue still needs to be * active in both cases, however, because it is used for inode reclaim - * during these times. Use the s_umount semaphore to provide exclusion - * with unmount. + * during these times. Use the MS_ACTIVE flag to avoid doing anything + * during mount. Doing work during unmount is avoided by calling + * cancel_delayed_work_sync on this work queue before tearing down + * the ail and the log in xfs_log_unmount. */ - if (down_read_trylock(&mp->m_super->s_umount)) { - if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { - /* dgc: errors ignored here */ - if (mp->m_super->s_frozen == SB_UNFROZEN && - xfs_log_need_covered(mp)) - error = xfs_fs_log_dummy(mp); - else - xfs_log_force(mp, 0); - - /* start pushing all the metadata that is currently - * dirty */ - xfs_ail_push_all(mp->m_ail); - } - up_read(&mp->m_super->s_umount); + if (!(mp->m_super->s_flags & MS_ACTIVE) && + !(mp->m_flags & XFS_MOUNT_RDONLY)) { + /* dgc: errors ignored here */ + if (mp->m_super->s_frozen == SB_UNFROZEN && + xfs_log_need_covered(mp)) + error = xfs_fs_log_dummy(mp); + else + xfs_log_force(mp, 0); + + /* start pushing all the metadata that is currently + * dirty */ + xfs_ail_push_all(mp->m_ail); } /* queue us up again */ -- GitLab From f7bdf03a99efc083608cd9c0c3e03abff311c79e Mon Sep 17 00:00:00 2001 From: Mark Tinguely Date: Thu, 14 Jun 2012 09:22:15 -0500 Subject: [PATCH 2412/6849] xfs: rename log structure to xlog Rename the XFS log structure to xlog to help crash distinquish it from the other logs in Linux. Signed-off-by: Mark Tinguely Reviewed-by: Christoph Hellwig Signed-off-by: Ben Myers --- fs/xfs/xfs_log.c | 76 +++++++++++++++++++++++----------------- fs/xfs/xfs_log_cil.c | 22 ++++++------ fs/xfs/xfs_log_priv.h | 46 ++++++++++++++++-------- fs/xfs/xfs_log_recover.c | 38 ++++++++++---------- fs/xfs/xfs_mount.h | 4 +-- fs/xfs/xfs_trace.h | 18 +++++----- 6 files changed, 116 insertions(+), 88 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 0e1a64f0439c..d90d4a388609 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -38,13 +38,21 @@ kmem_zone_t *xfs_log_ticket_zone; /* Local miscellaneous function prototypes */ -STATIC int xlog_commit_record(struct log *log, struct xlog_ticket *ticket, - xlog_in_core_t **, xfs_lsn_t *); +STATIC int +xlog_commit_record( + struct xlog *log, + struct xlog_ticket *ticket, + struct xlog_in_core **iclog, + xfs_lsn_t *commitlsnp); + STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, xfs_buftarg_t *log_target, xfs_daddr_t blk_offset, int num_bblks); -STATIC int xlog_space_left(struct log *log, atomic64_t *head); +STATIC int +xlog_space_left( + struct xlog *log, + atomic64_t *head); STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); STATIC void xlog_dealloc_log(xlog_t *log); @@ -64,8 +72,10 @@ STATIC void xlog_state_switch_iclogs(xlog_t *log, int eventual_size); STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); -STATIC void xlog_grant_push_ail(struct log *log, - int need_bytes); +STATIC void +xlog_grant_push_ail( + struct xlog *log, + int need_bytes); STATIC void xlog_regrant_reserve_log_space(xlog_t *log, xlog_ticket_t *ticket); STATIC void xlog_ungrant_log_space(xlog_t *log, @@ -73,7 +83,9 @@ STATIC void xlog_ungrant_log_space(xlog_t *log, #if defined(DEBUG) STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); -STATIC void xlog_verify_grant_tail(struct log *log); +STATIC void +xlog_verify_grant_tail( + struct xlog *log); STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, int count, boolean_t syncing); STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, @@ -89,9 +101,9 @@ STATIC int xlog_iclogs_empty(xlog_t *log); static void xlog_grant_sub_space( - struct log *log, - atomic64_t *head, - int bytes) + struct xlog *log, + atomic64_t *head, + int bytes) { int64_t head_val = atomic64_read(head); int64_t new, old; @@ -115,9 +127,9 @@ xlog_grant_sub_space( static void xlog_grant_add_space( - struct log *log, - atomic64_t *head, - int bytes) + struct xlog *log, + atomic64_t *head, + int bytes) { int64_t head_val = atomic64_read(head); int64_t new, old; @@ -165,7 +177,7 @@ xlog_grant_head_wake_all( static inline int xlog_ticket_reservation( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, struct xlog_ticket *tic) { @@ -182,7 +194,7 @@ xlog_ticket_reservation( STATIC bool xlog_grant_head_wake( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, int *free_bytes) { @@ -204,7 +216,7 @@ xlog_grant_head_wake( STATIC int xlog_grant_head_wait( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, struct xlog_ticket *tic, int need_bytes) @@ -256,7 +268,7 @@ shutdown: */ STATIC int xlog_grant_head_check( - struct log *log, + struct xlog *log, struct xlog_grant_head *head, struct xlog_ticket *tic, int *need_bytes) @@ -323,7 +335,7 @@ xfs_log_regrant( struct xfs_mount *mp, struct xlog_ticket *tic) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; int need_bytes; int error = 0; @@ -389,7 +401,7 @@ xfs_log_reserve( bool permanent, uint t_type) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xlog_ticket *tic; int need_bytes; int error = 0; @@ -465,7 +477,7 @@ xfs_log_done( struct xlog_in_core **iclog, uint flags) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; xfs_lsn_t lsn = 0; if (XLOG_FORCED_SHUTDOWN(log) || @@ -839,7 +851,7 @@ void xfs_log_space_wake( struct xfs_mount *mp) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; int free_bytes; if (XLOG_FORCED_SHUTDOWN(log)) @@ -917,7 +929,7 @@ xfs_lsn_t xlog_assign_tail_lsn_locked( struct xfs_mount *mp) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xfs_log_item *lip; xfs_lsn_t tail_lsn; @@ -966,7 +978,7 @@ xlog_assign_tail_lsn( */ STATIC int xlog_space_left( - struct log *log, + struct xlog *log, atomic64_t *head) { int free_bytes; @@ -1278,7 +1290,7 @@ out: */ STATIC int xlog_commit_record( - struct log *log, + struct xlog *log, struct xlog_ticket *ticket, struct xlog_in_core **iclog, xfs_lsn_t *commitlsnp) @@ -1312,7 +1324,7 @@ xlog_commit_record( */ STATIC void xlog_grant_push_ail( - struct log *log, + struct xlog *log, int need_bytes) { xfs_lsn_t threshold_lsn = 0; @@ -1791,7 +1803,7 @@ xlog_write_start_rec( static xlog_op_header_t * xlog_write_setup_ophdr( - struct log *log, + struct xlog *log, struct xlog_op_header *ophdr, struct xlog_ticket *ticket, uint flags) @@ -1874,7 +1886,7 @@ xlog_write_setup_copy( static int xlog_write_copy_finish( - struct log *log, + struct xlog *log, struct xlog_in_core *iclog, uint flags, int *record_cnt, @@ -1959,7 +1971,7 @@ xlog_write_copy_finish( */ int xlog_write( - struct log *log, + struct xlog *log, struct xfs_log_vec *log_vector, struct xlog_ticket *ticket, xfs_lsn_t *start_lsn, @@ -2822,7 +2834,7 @@ _xfs_log_force( uint flags, int *log_flushed) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xlog_in_core *iclog; xfs_lsn_t lsn; @@ -2970,7 +2982,7 @@ _xfs_log_force_lsn( uint flags, int *log_flushed) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; struct xlog_in_core *iclog; int already_slept = 0; @@ -3148,7 +3160,7 @@ xfs_log_ticket_get( */ xlog_ticket_t * xlog_ticket_alloc( - struct log *log, + struct xlog *log, int unit_bytes, int cnt, char client, @@ -3279,7 +3291,7 @@ xlog_ticket_alloc( */ void xlog_verify_dest_ptr( - struct log *log, + struct xlog *log, char *ptr) { int i; @@ -3308,7 +3320,7 @@ xlog_verify_dest_ptr( */ STATIC void xlog_verify_grant_tail( - struct log *log) + struct xlog *log) { int tail_cycle, tail_blocks; int cycle, space; diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 7d6197c58493..ddc4529d07d3 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -44,7 +44,7 @@ */ static struct xlog_ticket * xlog_cil_ticket_alloc( - struct log *log) + struct xlog *log) { struct xlog_ticket *tic; @@ -72,7 +72,7 @@ xlog_cil_ticket_alloc( */ void xlog_cil_init_post_recovery( - struct log *log) + struct xlog *log) { log->l_cilp->xc_ctx->ticket = xlog_cil_ticket_alloc(log); log->l_cilp->xc_ctx->sequence = 1; @@ -182,7 +182,7 @@ xlog_cil_prepare_log_vecs( */ STATIC void xfs_cil_prepare_item( - struct log *log, + struct xlog *log, struct xfs_log_vec *lv, int *len, int *diff_iovecs) @@ -231,7 +231,7 @@ xfs_cil_prepare_item( */ static void xlog_cil_insert_items( - struct log *log, + struct xlog *log, struct xfs_log_vec *log_vector, struct xlog_ticket *ticket) { @@ -373,7 +373,7 @@ xlog_cil_committed( */ STATIC int xlog_cil_push( - struct log *log) + struct xlog *log) { struct xfs_cil *cil = log->l_cilp; struct xfs_log_vec *lv; @@ -601,7 +601,7 @@ xlog_cil_push_work( */ static void xlog_cil_push_background( - struct log *log) + struct xlog *log) { struct xfs_cil *cil = log->l_cilp; @@ -629,7 +629,7 @@ xlog_cil_push_background( static void xlog_cil_push_foreground( - struct log *log, + struct xlog *log, xfs_lsn_t push_seq) { struct xfs_cil *cil = log->l_cilp; @@ -683,7 +683,7 @@ xfs_log_commit_cil( xfs_lsn_t *commit_lsn, int flags) { - struct log *log = mp->m_log; + struct xlog *log = mp->m_log; int log_flags = 0; struct xfs_log_vec *log_vector; @@ -754,7 +754,7 @@ xfs_log_commit_cil( */ xfs_lsn_t xlog_cil_force_lsn( - struct log *log, + struct xlog *log, xfs_lsn_t sequence) { struct xfs_cil *cil = log->l_cilp; @@ -833,7 +833,7 @@ xfs_log_item_in_current_chkpt( */ int xlog_cil_init( - struct log *log) + struct xlog *log) { struct xfs_cil *cil; struct xfs_cil_ctx *ctx; @@ -869,7 +869,7 @@ xlog_cil_init( void xlog_cil_destroy( - struct log *log) + struct xlog *log) { if (log->l_cilp->xc_ctx) { if (log->l_cilp->xc_ctx->ticket) diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 5bc33261f5be..72eba2201b14 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -19,7 +19,7 @@ #define __XFS_LOG_PRIV_H__ struct xfs_buf; -struct log; +struct xlog; struct xlog_ticket; struct xfs_mount; @@ -352,7 +352,7 @@ typedef struct xlog_in_core { struct xlog_in_core *ic_next; struct xlog_in_core *ic_prev; struct xfs_buf *ic_bp; - struct log *ic_log; + struct xlog *ic_log; int ic_size; int ic_offset; int ic_bwritecnt; @@ -409,7 +409,7 @@ struct xfs_cil_ctx { * operations almost as efficient as the old logging methods. */ struct xfs_cil { - struct log *xc_log; + struct xlog *xc_log; struct list_head xc_cil; spinlock_t xc_cil_lock; struct xfs_cil_ctx *xc_ctx; @@ -487,7 +487,7 @@ struct xlog_grant_head { * overflow 31 bits worth of byte offset, so using a byte number will mean * that round off problems won't occur when releasing partial reservations. */ -typedef struct log { +typedef struct xlog { /* The following fields don't need locking */ struct xfs_mount *l_mp; /* mount point */ struct xfs_ail *l_ailp; /* AIL log is working with */ @@ -553,9 +553,14 @@ extern int xlog_recover_finish(xlog_t *log); extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); extern kmem_zone_t *xfs_log_ticket_zone; -struct xlog_ticket *xlog_ticket_alloc(struct log *log, int unit_bytes, - int count, char client, bool permanent, - xfs_km_flags_t alloc_flags); +struct xlog_ticket * +xlog_ticket_alloc( + struct xlog *log, + int unit_bytes, + int count, + char client, + bool permanent, + xfs_km_flags_t alloc_flags); static inline void @@ -567,9 +572,14 @@ xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes) } void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket); -int xlog_write(struct log *log, struct xfs_log_vec *log_vector, - struct xlog_ticket *tic, xfs_lsn_t *start_lsn, - xlog_in_core_t **commit_iclog, uint flags); +int +xlog_write( + struct xlog *log, + struct xfs_log_vec *log_vector, + struct xlog_ticket *tic, + xfs_lsn_t *start_lsn, + struct xlog_in_core **commit_iclog, + uint flags); /* * When we crack an atomic LSN, we sample it first so that the value will not @@ -629,17 +639,23 @@ xlog_assign_grant_head(atomic64_t *head, int cycle, int space) /* * Committed Item List interfaces */ -int xlog_cil_init(struct log *log); -void xlog_cil_init_post_recovery(struct log *log); -void xlog_cil_destroy(struct log *log); +int +xlog_cil_init(struct xlog *log); +void +xlog_cil_init_post_recovery(struct xlog *log); +void +xlog_cil_destroy(struct xlog *log); /* * CIL force routines */ -xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence); +xfs_lsn_t +xlog_cil_force_lsn( + struct xlog *log, + xfs_lsn_t sequence); static inline void -xlog_cil_force(struct log *log) +xlog_cil_force(struct xlog *log) { xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence); } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index ca386909131a..a7be98abd6a9 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1471,8 +1471,8 @@ xlog_recover_add_item( STATIC int xlog_recover_add_to_cont_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1517,8 +1517,8 @@ xlog_recover_add_to_cont_trans( */ STATIC int xlog_recover_add_to_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1588,8 +1588,8 @@ xlog_recover_add_to_trans( */ STATIC int xlog_recover_reorder_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, int pass) { xlog_recover_item_t *item, *n; @@ -1642,8 +1642,8 @@ xlog_recover_reorder_trans( */ STATIC int xlog_recover_buffer_pass1( - struct log *log, - xlog_recover_item_t *item) + struct xlog *log, + struct xlog_recover_item *item) { xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; struct list_head *bucket; @@ -1696,7 +1696,7 @@ xlog_recover_buffer_pass1( */ STATIC int xlog_check_buffer_cancelled( - struct log *log, + struct xlog *log, xfs_daddr_t blkno, uint len, ushort flags) @@ -2689,9 +2689,9 @@ xlog_recover_free_trans( STATIC int xlog_recover_commit_pass1( - struct log *log, - struct xlog_recover *trans, - xlog_recover_item_t *item) + struct xlog *log, + struct xlog_recover *trans, + struct xlog_recover_item *item) { trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1); @@ -2716,10 +2716,10 @@ xlog_recover_commit_pass1( STATIC int xlog_recover_commit_pass2( - struct log *log, - struct xlog_recover *trans, - struct list_head *buffer_list, - xlog_recover_item_t *item) + struct xlog *log, + struct xlog_recover *trans, + struct list_head *buffer_list, + struct xlog_recover_item *item) { trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS2); @@ -2753,7 +2753,7 @@ xlog_recover_commit_pass2( */ STATIC int xlog_recover_commit_trans( - struct log *log, + struct xlog *log, struct xlog_recover *trans, int pass) { @@ -2793,8 +2793,8 @@ out: STATIC int xlog_recover_unmount_trans( - struct log *log, - xlog_recover_t *trans) + struct xlog *log, + struct xlog_recover *trans) { /* Do nothing now */ xfs_warn(log->l_mp, "%s: Unmount LR", __func__); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8b89c5ac72d9..90c1fc9eaea4 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -53,7 +53,7 @@ typedef struct xfs_trans_reservations { #include "xfs_sync.h" -struct log; +struct xlog; struct xfs_mount_args; struct xfs_inode; struct xfs_bmbt_irec; @@ -133,7 +133,7 @@ typedef struct xfs_mount { uint m_readio_blocks; /* min read size blocks */ uint m_writeio_log; /* min write size log bytes */ uint m_writeio_blocks; /* min write size blocks */ - struct log *m_log; /* log specific stuff */ + struct xlog *m_log; /* log specific stuff */ int m_logbufs; /* number of log buffers */ int m_logbsize; /* size of each log buffer */ uint m_rsumlevels; /* rt summary levels */ diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7cf9d3529e51..caf5dabfd553 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -32,7 +32,7 @@ struct xfs_da_node_entry; struct xfs_dquot; struct xfs_log_item; struct xlog_ticket; -struct log; +struct xlog; struct xlog_recover; struct xlog_recover_item; struct xfs_buf_log_format; @@ -762,7 +762,7 @@ DEFINE_DQUOT_EVENT(xfs_dqflush_force); DEFINE_DQUOT_EVENT(xfs_dqflush_done); DECLARE_EVENT_CLASS(xfs_loggrant_class, - TP_PROTO(struct log *log, struct xlog_ticket *tic), + TP_PROTO(struct xlog *log, struct xlog_ticket *tic), TP_ARGS(log, tic), TP_STRUCT__entry( __field(dev_t, dev) @@ -830,7 +830,7 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, #define DEFINE_LOGGRANT_EVENT(name) \ DEFINE_EVENT(xfs_loggrant_class, name, \ - TP_PROTO(struct log *log, struct xlog_ticket *tic), \ + TP_PROTO(struct xlog *log, struct xlog_ticket *tic), \ TP_ARGS(log, tic)) DEFINE_LOGGRANT_EVENT(xfs_log_done_nonperm); DEFINE_LOGGRANT_EVENT(xfs_log_done_perm); @@ -1664,7 +1664,7 @@ DEFINE_SWAPEXT_EVENT(xfs_swap_extent_before); DEFINE_SWAPEXT_EVENT(xfs_swap_extent_after); DECLARE_EVENT_CLASS(xfs_log_recover_item_class, - TP_PROTO(struct log *log, struct xlog_recover *trans, + TP_PROTO(struct xlog *log, struct xlog_recover *trans, struct xlog_recover_item *item, int pass), TP_ARGS(log, trans, item, pass), TP_STRUCT__entry( @@ -1698,7 +1698,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_item_class, #define DEFINE_LOG_RECOVER_ITEM(name) \ DEFINE_EVENT(xfs_log_recover_item_class, name, \ - TP_PROTO(struct log *log, struct xlog_recover *trans, \ + TP_PROTO(struct xlog *log, struct xlog_recover *trans, \ struct xlog_recover_item *item, int pass), \ TP_ARGS(log, trans, item, pass)) @@ -1709,7 +1709,7 @@ DEFINE_LOG_RECOVER_ITEM(xfs_log_recover_item_reorder_tail); DEFINE_LOG_RECOVER_ITEM(xfs_log_recover_item_recover); DECLARE_EVENT_CLASS(xfs_log_recover_buf_item_class, - TP_PROTO(struct log *log, struct xfs_buf_log_format *buf_f), + TP_PROTO(struct xlog *log, struct xfs_buf_log_format *buf_f), TP_ARGS(log, buf_f), TP_STRUCT__entry( __field(dev_t, dev) @@ -1739,7 +1739,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_buf_item_class, #define DEFINE_LOG_RECOVER_BUF_ITEM(name) \ DEFINE_EVENT(xfs_log_recover_buf_item_class, name, \ - TP_PROTO(struct log *log, struct xfs_buf_log_format *buf_f), \ + TP_PROTO(struct xlog *log, struct xfs_buf_log_format *buf_f), \ TP_ARGS(log, buf_f)) DEFINE_LOG_RECOVER_BUF_ITEM(xfs_log_recover_buf_not_cancel); @@ -1752,7 +1752,7 @@ DEFINE_LOG_RECOVER_BUF_ITEM(xfs_log_recover_buf_reg_buf); DEFINE_LOG_RECOVER_BUF_ITEM(xfs_log_recover_buf_dquot_buf); DECLARE_EVENT_CLASS(xfs_log_recover_ino_item_class, - TP_PROTO(struct log *log, struct xfs_inode_log_format *in_f), + TP_PROTO(struct xlog *log, struct xfs_inode_log_format *in_f), TP_ARGS(log, in_f), TP_STRUCT__entry( __field(dev_t, dev) @@ -1790,7 +1790,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_ino_item_class, ) #define DEFINE_LOG_RECOVER_INO_ITEM(name) \ DEFINE_EVENT(xfs_log_recover_ino_item_class, name, \ - TP_PROTO(struct log *log, struct xfs_inode_log_format *in_f), \ + TP_PROTO(struct xlog *log, struct xfs_inode_log_format *in_f), \ TP_ARGS(log, in_f)) DEFINE_LOG_RECOVER_INO_ITEM(xfs_log_recover_inode_recover); -- GitLab From 88a9e31c506c00c8b7a2f1611406d0e38dcb33b3 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Fri, 1 Jun 2012 11:14:03 +0300 Subject: [PATCH 2413/6849] mac80211: clear ifmgd->bssid only after building DELBA ieee80211_set_disassoc() clears ifmgd->bssid before building DELBA frames, resulting in frames with invalid bssid ("00:00:00:00:00:00"). Fix it by clearing ifmgd->bssid only after building all the needed frames. After this change, we no longer need to save the bssid (before clearing it), so remove the local array. Reported-by: Ido Yariv Cc: stable@vger.kernel.org Signed-off-by: Eliad Peller Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 66e4fcdd1c6b..a4bb856de08f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1342,7 +1342,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct sta_info *sta; u32 changed = 0; - u8 bssid[ETH_ALEN]; ASSERT_MGD_MTX(ifmgd); @@ -1354,10 +1353,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ieee80211_stop_poll(sdata); - memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); - ifmgd->associated = NULL; - memset(ifmgd->bssid, 0, ETH_ALEN); /* * we need to commit the associated = NULL change because the @@ -1377,7 +1373,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, netif_carrier_off(sdata->dev); mutex_lock(&local->sta_mtx); - sta = sta_info_get(sdata, bssid); + sta = sta_info_get(sdata, ifmgd->bssid); if (sta) { set_sta_flag(sta, WLAN_STA_BLOCK_BA); ieee80211_sta_tear_down_BA_sessions(sta, tx); @@ -1386,13 +1382,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, /* deauthenticate/disassociate now */ if (tx || frame_buf) - ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason, - tx, frame_buf); + ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, + reason, tx, frame_buf); /* flush out frame */ if (tx) drv_flush(local, false); + /* clear bssid only after building the needed mgmt frames */ + memset(ifmgd->bssid, 0, ETH_ALEN); + /* remove AP and TDLS peers */ sta_info_flush(local, sdata); -- GitLab From fd62e09b946522ec3578412826a81bead06fadf7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 21 Jun 2012 14:58:10 -0700 Subject: [PATCH 2414/6849] tcp: Validate route interface in early demux. Otherwise we might violate reverse path filtering. Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 13857df1dae1..21e22a00481a 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1676,6 +1676,7 @@ int tcp_v4_early_demux(struct sk_buff *skb) struct net *net = dev_net(skb->dev); const struct iphdr *iph; const struct tcphdr *th; + struct net_device *dev; struct sock *sk; int err; @@ -1695,10 +1696,11 @@ int tcp_v4_early_demux(struct sk_buff *skb) if (!pskb_may_pull(skb, ip_hdrlen(skb) + th->doff * 4)) goto out_err; + dev = skb->dev; sk = __inet_lookup_established(net, &tcp_hashinfo, iph->saddr, th->source, iph->daddr, th->dest, - skb->dev->ifindex); + dev->ifindex); if (sk) { skb->sk = sk; skb->destructor = sock_edemux; @@ -1707,8 +1709,12 @@ int tcp_v4_early_demux(struct sk_buff *skb) if (dst) dst = dst_check(dst, 0); if (dst) { - skb_dst_set_noref(skb, dst); - err = 0; + struct rtable *rt = (struct rtable *) dst; + + if (rt->rt_iif == dev->ifindex) { + skb_dst_set_noref(skb, dst); + err = 0; + } } } } -- GitLab From f73332fc39e35a6ac14f892390adcd34a63b00d3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 21 Jun 2012 02:15:10 +0000 Subject: [PATCH 2415/6849] ixgbe: simplify padding and length checks The check for length <= 0 is bogus because length is unsigned, and network stack never sends zero length packets (unless it is totally broken). The check for really small packets can be optimized (using unlikely) and calling skb_pad directly. Signed-off-by: Stephen Hemminger Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index b0ddfd47e473..69a660b5621a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6380,17 +6380,12 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_ring *tx_ring; - if (skb->len <= 0) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - /* * The minimum packet size for olinfo paylen is 17 so pad the skb * in order to meet this minimum size requirement. */ - if (skb->len < 17) { - if (skb_padto(skb, 17)) + if (unlikely(skb->len < 17)) { + if (skb_pad(skb, 17 - skb->len)) return NETDEV_TX_OK; skb->len = 17; } -- GitLab From bb1dfefdc62fa68107c4c9f1374cb856743a9434 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 20 Jun 2012 19:56:21 +0000 Subject: [PATCH 2416/6849] net: dcb: fix small regression in __dcbnl_pg_setcfg() A small regression was introduced in the reply command of dcbnl_pg_setcfg(). User space apps may be expecting the DCB_ATTR_PG_CFG attribute to be returned with the patch below TX or RX variants are returned. commit 7be994138b188387691322921c08e19bddf6d3c5 Author: Thomas Graf Date: Wed Jun 13 02:54:55 2012 +0000 dcbnl: Shorten all command handling functions This patch reverts this behavior and returns DCB_ATTR_PG_CFG Signed-off-by: John Fastabend Acked-by: Thomas Graf Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 0a360072cfec..013da86575e8 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -852,8 +852,7 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, } } - return nla_put_u8(skb, - (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 0); + return nla_put_u8(skb, DCB_ATTR_PG_CFG, 0); } static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, -- GitLab From 561038f0a8aa1de272a2ac5dad24cc8246d9f496 Mon Sep 17 00:00:00 2001 From: Djamil Elaidi Date: Sun, 17 Jun 2012 11:57:51 -0600 Subject: [PATCH 2417/6849] ARM: OMAP4+: hwmod: fix issue causing IPs not going back to Smart-Standby If an IP is configured in Smart-Standby-Wakeup, when disabling wakeup feature the IP will not go back to Smart-Standby, but will remain in Smart-Standby-Wakeup. Signed-off-by: Djamil Elaidi Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index bf86f7e8f91f..773193670ea2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -530,7 +530,7 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v); if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) - _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); + _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v); /* XXX test pwrdm_get_wken for this hwmod's subsystem */ -- GitLab From 252a4c5443ec4d0bd310ae5b0d1b7f9c5b1e7f46 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 17 Jun 2012 11:57:51 -0600 Subject: [PATCH 2418/6849] ARM: OMAP4: hwmod data: fix 32k sync timer idle modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 32k sync timer IP block target idle modes in the hwmod data are incorrect. The IP block does not support any smart-idle modes. Update the data to reflect the correct modes. This problem was initially identified and a diff fragment posted to the lists by Benoît Cousson . A patch description bug in the first version was also identified by Benoît. Signed-off-by: Paul Walmsley Cc: Benoît Cousson Cc: Tero Kristo --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 950454a3fa31..c4c9cdd4c0cf 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -393,8 +393,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0004, .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO), .sysc_fields = &omap_hwmod_sysc_type1, }; -- GitLab From 9a47d32d5c4b91a4ce4c459f3b7b0290185e7578 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 17 Jun 2012 11:57:52 -0600 Subject: [PATCH 2419/6849] ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until the OMAP4 code is converted to disable the use of the clock framework-based clockdomain enable/disable sequence, any clock used as a hwmod main_clk must have a clockdomain associated with it. This patch populates some clock structure clockdomain names to resolve the following warnings during kernel init: omap_hwmod: dpll_mpu_m2_ck: missing clockdomain for dpll_mpu_m2_ck. omap_hwmod: trace_clk_div_ck: missing clockdomain for trace_clk_div_ck. omap_hwmod: l3_div_ck: missing clockdomain for l3_div_ck. omap_hwmod: ddrphy_ck: missing clockdomain for ddrphy_ck. Signed-off-by: Paul Walmsley Cc: Rajendra Nayak Cc: Benoît Cousson --- arch/arm/mach-omap2/clock44xx_data.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 2172f6603848..e2b701e164f6 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -84,6 +84,7 @@ static struct clk slimbus_clk = { static struct clk sys_32k_ck = { .name = "sys_32k_ck", + .clkdm_name = "prm_clkdm", .rate = 32768, .ops = &clkops_null, }; @@ -512,6 +513,7 @@ static struct clk ddrphy_ck = { .name = "ddrphy_ck", .parent = &dpll_core_m2_ck, .ops = &clkops_null, + .clkdm_name = "l3_emif_clkdm", .fixed_div = 2, .recalc = &omap_fixed_divisor_recalc, }; @@ -769,6 +771,7 @@ static const struct clksel dpll_mpu_m2_div[] = { static struct clk dpll_mpu_m2_ck = { .name = "dpll_mpu_m2_ck", .parent = &dpll_mpu_ck, + .clkdm_name = "cm_clkdm", .clksel = dpll_mpu_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, @@ -1149,6 +1152,7 @@ static const struct clksel l3_div_div[] = { static struct clk l3_div_ck = { .name = "l3_div_ck", .parent = &div_core_ck, + .clkdm_name = "cm_clkdm", .clksel = l3_div_div, .clksel_reg = OMAP4430_CM_CLKSEL_CORE, .clksel_mask = OMAP4430_CLKSEL_L3_MASK, @@ -2824,6 +2828,7 @@ static const struct clksel trace_clk_div_div[] = { static struct clk trace_clk_div_ck = { .name = "trace_clk_div_ck", .parent = &pmd_trace_clk_mux_ck, + .clkdm_name = "emu_sys_clkdm", .clksel = trace_clk_div_div, .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL, .clksel_mask = OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK, -- GitLab From b8f15b7e1dd3638d35cfff85571df1d7ea96e35e Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 17 Jun 2012 11:57:53 -0600 Subject: [PATCH 2420/6849] ARM: OMAP2+: CM: increase the module disable timeout Increase the timeout for disabling an IP block to five milliseconds. This is to handle the usb_host_fs idle latency, which takes almost four milliseconds after a host controller reset. This is the second of two patches needed to resolve the following boot warning: omap_hwmod: usb_host_fs: _wait_target_disable failed Thanks to Sergei Shtylyov for finding an unrelated hunk in a previous version of this patch. Signed-off-by: Paul Walmsley Cc: Sergei Shtylyov Cc: Tero Kristo --- arch/arm/mach-omap2/cm.h | 11 +++++++++++ arch/arm/mach-omap2/cminst44xx.c | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index a7bc096bd407..f24e3f7a2bbc 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -22,4 +22,15 @@ */ #define MAX_MODULE_READY_TIME 2000 +/* + * MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for + * the PRCM to request that a module enter the inactive state in the + * case of OMAP2 & 3. In the case of OMAP4 this is the max duration + * in microseconds for the module to reach the inactive state from + * a functional state. + * XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during + * kernel init. + */ +#define MAX_MODULE_DISABLE_TIME 5000 + #endif diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 8c86d294b1a3..1a39945d9ff8 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -313,9 +313,9 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_off omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == CLKCTRL_IDLEST_DISABLED), - MAX_MODULE_READY_TIME, i); + MAX_MODULE_DISABLE_TIME, i); - return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; + return (i < MAX_MODULE_DISABLE_TIME) ? 0 : -EBUSY; } /** -- GitLab From 65e25976b75c4996c5650afadc4180db09ec7475 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 17 Jun 2012 12:00:58 -0600 Subject: [PATCH 2421/6849] ARM: OMAP2+: mux: fix sparse warning Commit bbd707acee279a61177a604822db92e8164d00db ("ARM: omap2: use machine specific hook for late init") resulted in the addition of this sparse warning: arch/arm/mach-omap2/mux.c:791:12: warning: symbol 'omap_mux_late_init' was not declared. Should it be static? Fix by including the header file containing the prototype. Signed-off-by: Paul Walmsley Cc: Shawn Guo Cc: Tony Lindgren --- arch/arm/mach-omap2/mux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 80e55c5c9998..d3ef99c5cad8 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -41,6 +41,7 @@ #include "control.h" #include "mux.h" #include "prm.h" +#include "common.h" #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ #define OMAP_MUX_BASE_SZ 0x5ca -- GitLab From dc57aef503859dbf724f6126c58b2e1672e215f3 Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Thu, 21 Jun 2012 10:08:53 +0200 Subject: [PATCH 2422/6849] ARM: OMAP4: hwmod data: Force HDMI in no-idle while enabled As per the OMAP4 documentation, audio over HDMI must be transmitted in no-idle mode. This patch adds the HWMOD_SWSUP_SIDLE so that omap_hwmod uses no-idle/force-idle settings instead of smart-idle mode. This is required as the DSS interface clock is used as functional clock for the HDMI wrapper audio FIFO. If no-idle mode is not used, audio could be choppy, have bad quality or not be audible at all. Signed-off-by: Ricardo Neri [b-cousson@ti.com: Update the subject and align the .flags location with the script template] Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c4c9cdd4c0cf..f30e861ce6d9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -853,6 +853,11 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .name = "dss_hdmi", .class = &omap44xx_hdmi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + /* + * HDMI audio requires to use no-idle mode. Hence, + * set idle mode by software. + */ + .flags = HWMOD_SWSUP_SIDLE, .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", -- GitLab From d584a61a931e6cbfef0dd811c4ae0250ec5987f4 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 20 Jun 2012 20:52:31 +0200 Subject: [PATCH 2423/6849] netfilter: nfnetlink_queue: fix compilation with CONFIG_NF_NAT=m and CONFIG_NF_CT_NETLINK=y LD init/built-in.o net/built-in.o:(.data+0x4408): undefined reference to `nf_nat_tcp_seq_adjust' make: *** [vmlinux] Error 1 This patch adds a new pointer hook (nfq_ct_nat_hook) similar to other existing in Netfilter to solve our complicated configuration dependencies. Reported-by: Valdis Kletnieks Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter.h | 6 +++++- net/ipv4/netfilter/nf_nat_core.c | 6 ++++++ net/netfilter/core.c | 3 +++ net/netfilter/nf_conntrack_netlink.c | 3 --- net/netfilter/nfnetlink_queue_ct.c | 8 ++++---- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 38b96a54f9a5..c613cf0d7884 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -401,10 +401,14 @@ struct nfq_ct_hook { size_t (*build_size)(const struct nf_conn *ct); int (*build)(struct sk_buff *skb, struct nf_conn *ct); int (*parse)(const struct nlattr *attr, struct nf_conn *ct); +}; +extern struct nfq_ct_hook __rcu *nfq_ct_hook; + +struct nfq_ct_nat_hook { void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, u32 ctinfo, int off); }; -extern struct nfq_ct_hook __rcu *nfq_ct_hook; +extern struct nfq_ct_nat_hook __rcu *nfq_ct_nat_hook; #else static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} #endif diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index abb52adf5acd..44b082fd48ab 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -691,6 +691,10 @@ static struct nf_ct_helper_expectfn follow_master_nat = { .expectfn = nf_nat_follow_master, }; +static struct nfq_ct_nat_hook nfq_ct_nat = { + .seq_adjust = nf_nat_tcp_seq_adjust, +}; + static int __init nf_nat_init(void) { size_t i; @@ -731,6 +735,7 @@ static int __init nf_nat_init(void) nfnetlink_parse_nat_setup); BUG_ON(nf_ct_nat_offset != NULL); RCU_INIT_POINTER(nf_ct_nat_offset, nf_nat_get_offset); + RCU_INIT_POINTER(nfq_ct_nat_hook, &nfq_ct_nat); return 0; cleanup_extend: @@ -747,6 +752,7 @@ static void __exit nf_nat_cleanup(void) RCU_INIT_POINTER(nf_nat_seq_adjust_hook, NULL); RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL); RCU_INIT_POINTER(nf_ct_nat_offset, NULL); + RCU_INIT_POINTER(nfq_ct_nat_hook, NULL); synchronize_net(); } diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 4cd10ed2d6e6..0bc6b60db4df 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -268,6 +268,9 @@ EXPORT_SYMBOL(nf_conntrack_destroy); struct nfq_ct_hook __rcu *nfq_ct_hook __read_mostly; EXPORT_SYMBOL_GPL(nfq_ct_hook); +struct nfq_ct_nat_hook __rcu *nfq_ct_nat_hook __read_mostly; +EXPORT_SYMBOL_GPL(nfq_ct_nat_hook); + #endif /* CONFIG_NF_CONNTRACK */ #ifdef CONFIG_PROC_FS diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 31d1d8f3a6ce..8bb47339b770 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1757,9 +1757,6 @@ static struct nfq_ct_hook ctnetlink_nfqueue_hook = { .build_size = ctnetlink_nfqueue_build_size, .build = ctnetlink_nfqueue_build, .parse = ctnetlink_nfqueue_parse, -#ifdef CONFIG_NF_NAT_NEEDED - .seq_adjust = nf_nat_tcp_seq_adjust, -#endif }; #endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */ diff --git a/net/netfilter/nfnetlink_queue_ct.c b/net/netfilter/nfnetlink_queue_ct.c index 68ef550066f5..01247b730e66 100644 --- a/net/netfilter/nfnetlink_queue_ct.c +++ b/net/netfilter/nfnetlink_queue_ct.c @@ -86,12 +86,12 @@ nla_put_failure: void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, int diff) { - struct nfq_ct_hook *nfq_ct; + struct nfq_ct_nat_hook *nfq_nat_ct; - nfq_ct = rcu_dereference(nfq_ct_hook); - if (nfq_ct == NULL) + nfq_nat_ct = rcu_dereference(nfq_ct_nat_hook); + if (nfq_nat_ct == NULL) return; if ((ct->status & IPS_NAT_MASK) && diff) - nfq_ct->seq_adjust(skb, ct, ctinfo, diff); + nfq_nat_ct->seq_adjust(skb, ct, ctinfo, diff); } -- GitLab From d660030061dd7e20ad18557368188d9c1002ec71 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 21 Jun 2012 21:40:37 -0600 Subject: [PATCH 2424/6849] W1: OMAP HDQ1W: allow driver to be built on all OMAP2+ Allow the OMAP HDQ1W driver to be built for all OMAP2+ SoCs by adjusting KConfig dependencies. The previous dependency required either SOC_OMAP2430 or ARCH_OMAP3 to be set, but the HDQ IP block is present on OMAP2420 and OMAP44xx SoCs. The driver was still selectable on multi-OMAP kernel configurations, however; so the previous prohibition was rather pointless. Signed-off-by: Paul Walmsley Cc: Evgeniy Polyakov Acked-by: Evgeniy Polyakov --- drivers/w1/masters/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index 979d6eed9a0f..5ceb1cd50195 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig @@ -60,7 +60,7 @@ config W1_MASTER_GPIO config HDQ_MASTER_OMAP tristate "OMAP HDQ driver" - depends on SOC_OMAP2430 || ARCH_OMAP3 + depends on ARCH_OMAP2PLUS help Say Y here if you want support for the 1-wire or HDQ Interface on an OMAP processor. -- GitLab From 2acd089471d93373e051c6b1f9f9e0d9e51a76bc Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 21 Jun 2012 21:40:37 -0600 Subject: [PATCH 2425/6849] W1: OMAP HDQ1W: use 32-bit register accesses HDQ/1-wire registers are 32 bits long, even if the register contents fit into 8 bits, so accesses must be 32-bit aligned. Evidently the OMAP2/3 interconnects allowed the driver to get away with 8 bit accesses, but the OMAP4 puts a stop to that: [ 1.488800] Driver for 1-wire Dallas network protocol. [ 1.495025] Bad mode in data abort handler detected [ 1.500122] Internal error: Oops - bad mode: 0 [#1] SMP [ 1.505615] Modules linked in: [ 1.508819] CPU: 0 Not tainted (3.3.0-rc1-00008-g45030e9 #992) [ 1.515289] PC is at 0xffff0018 [ 1.518615] LR is at omap_hdq_probe+0xd4/0x2cc The OMAP4430 ES2 Rev X TRM does warn about this restriction in section 23.2.6.2 "HDQ/1-Wire Registers". Fixes the crash on OMAP4430 ES2 Pandaboard. Tested also on OMAP34xx and OMAP2420; it seems to work fine on those chips, although due to the lack of boards with HDQ/1-wire devices here, a more indepth test was not possible. Signed-off-by: Paul Walmsley Cc: NeilBrown Cc: Evgeniy Polyakov Acked-by: Evgeniy Polyakov --- drivers/w1/masters/omap_hdq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 5ef385bfed18..344db9c5ab88 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -102,20 +102,20 @@ static struct w1_bus_master omap_w1_master = { /* HDQ register I/O routines */ static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset) { - return __raw_readb(hdq_data->hdq_base + offset); + return __raw_readl(hdq_data->hdq_base + offset); } static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val) { - __raw_writeb(val, hdq_data->hdq_base + offset); + __raw_writel(val, hdq_data->hdq_base + offset); } static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset, u8 val, u8 mask) { - u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask) + u8 new_val = (__raw_readl(hdq_data->hdq_base + offset) & ~mask) | (val & mask); - __raw_writeb(new_val, hdq_data->hdq_base + offset); + __raw_writel(new_val, hdq_data->hdq_base + offset); return new_val; } -- GitLab From 96b1b29d37b0ca3ecd424a1fe301406cf525fc04 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 21 Jun 2012 21:40:38 -0600 Subject: [PATCH 2426/6849] ARM: OMAP2+: HDQ1W: use omap_device Convert the old-style device registration code for HDQ1W to use omap_device. This will allow the driver to be converted to use PM runtime and to take advantage of the OMAP IP block management infrastructure (hwmod, PM, etc.). A side benefit of this conversion is that it also makes the HDQ device available on OMAP2420. The previous code only enabled it on 2430 and 3430. Signed-off-by: Paul Walmsley Cc: NeilBrown Tested-by: NeilBrown --- arch/arm/mach-omap2/devices.c | 38 ----------------------------------- arch/arm/mach-omap2/hdq1w.c | 26 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 7b4b9327e543..8cab358603ac 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -672,43 +672,6 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) #endif -/*-------------------------------------------------------------------------*/ - -#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#define OMAP_HDQ_BASE 0x480B2000 -static struct resource omap_hdq_resources[] = { - { - .start = OMAP_HDQ_BASE, - .end = OMAP_HDQ_BASE + 0x1C, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_24XX_HDQ_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; -static struct platform_device omap_hdq_dev = { - .name = "omap_hdq", - .id = 0, - .dev = { - .platform_data = NULL, - }, - .num_resources = ARRAY_SIZE(omap_hdq_resources), - .resource = omap_hdq_resources, -}; -static inline void omap_hdq_init(void) -{ - if (cpu_is_omap2420()) - return; - - platform_device_register(&omap_hdq_dev); -} -#else -static inline void omap_hdq_init(void) {} -#endif - -/*---------------------------------------------------------------------------*/ - #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) @@ -753,7 +716,6 @@ static int __init omap2_init_devices(void) omap_init_mcspi(); } omap_init_pmu(); - omap_hdq_init(); omap_init_sti(); omap_init_sham(); omap_init_aes(); diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c index 297ebe03f09c..cdd6dda03828 100644 --- a/arch/arm/mach-omap2/hdq1w.c +++ b/arch/arm/mach-omap2/hdq1w.c @@ -22,7 +22,13 @@ * 02110-1301 USA */ +#include +#include +#include +#include + #include +#include #include #include "common.h" @@ -70,3 +76,23 @@ int omap_hdq1w_reset(struct omap_hwmod *oh) return 0; } + +static int __init omap_init_hdq(void) +{ + int id = -1; + struct platform_device *pdev; + struct omap_hwmod *oh; + char *oh_name = "hdq1w"; + char *devname = "omap_hdq"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) + return 0; + + pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", + devname, oh->name); + + return 0; +} +arch_initcall(omap_init_hdq); -- GitLab From c354a86484b61e32100eb94c1f3f0aa512958cee Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 21 Jun 2012 21:40:40 -0600 Subject: [PATCH 2427/6849] W1: OMAP HDQ1W: use runtime PM Convert the OMAP HDQ driver to use runtime PM. Compile- and boot-tested, but not tested in actual use. Signed-off-by: Paul Walmsley Cc: NeilBrown Cc: Evgeniy Polyakov Acked-by: Evgeniy Polyakov Tested-by: NeilBrown --- drivers/w1/masters/omap_hdq.c | 78 ++++++----------------------------- 1 file changed, 13 insertions(+), 65 deletions(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 344db9c5ab88..291897c881be 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -1,7 +1,7 @@ /* * drivers/w1/masters/omap_hdq.c * - * Copyright (C) 2007 Texas Instruments, Inc. + * Copyright (C) 2007,2012 Texas Instruments, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -14,9 +14,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -61,8 +61,6 @@ struct hdq_data { /* lock status update */ struct mutex hdq_mutex; int hdq_usecount; - struct clk *hdq_ick; - struct clk *hdq_fck; u8 hdq_irqstatus; /* device lock */ spinlock_t hdq_spinlock; @@ -419,17 +417,8 @@ static int omap_hdq_get(struct hdq_data *hdq_data) hdq_data->hdq_usecount++; try_module_get(THIS_MODULE); if (1 == hdq_data->hdq_usecount) { - if (clk_enable(hdq_data->hdq_ick)) { - dev_dbg(hdq_data->dev, "Can not enable ick\n"); - ret = -ENODEV; - goto clk_err; - } - if (clk_enable(hdq_data->hdq_fck)) { - dev_dbg(hdq_data->dev, "Can not enable fck\n"); - clk_disable(hdq_data->hdq_ick); - ret = -ENODEV; - goto clk_err; - } + + pm_runtime_get_sync(hdq_data->dev); /* make sure HDQ is out of reset */ if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) & @@ -450,9 +439,6 @@ static int omap_hdq_get(struct hdq_data *hdq_data) } } -clk_err: - clk_put(hdq_data->hdq_ick); - clk_put(hdq_data->hdq_fck); out: mutex_unlock(&hdq_data->hdq_mutex); rtn: @@ -475,10 +461,8 @@ static int omap_hdq_put(struct hdq_data *hdq_data) } else { hdq_data->hdq_usecount--; module_put(THIS_MODULE); - if (0 == hdq_data->hdq_usecount) { - clk_disable(hdq_data->hdq_ick); - clk_disable(hdq_data->hdq_fck); - } + if (0 == hdq_data->hdq_usecount) + pm_runtime_put_sync(hdq_data->dev); } mutex_unlock(&hdq_data->hdq_mutex); @@ -591,35 +575,11 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev) goto err_ioremap; } - /* get interface & functional clock objects */ - hdq_data->hdq_ick = clk_get(&pdev->dev, "ick"); - if (IS_ERR(hdq_data->hdq_ick)) { - dev_dbg(&pdev->dev, "Can't get HDQ ick clock object\n"); - ret = PTR_ERR(hdq_data->hdq_ick); - goto err_ick; - } - - hdq_data->hdq_fck = clk_get(&pdev->dev, "fck"); - if (IS_ERR(hdq_data->hdq_fck)) { - dev_dbg(&pdev->dev, "Can't get HDQ fck clock object\n"); - ret = PTR_ERR(hdq_data->hdq_fck); - goto err_fck; - } - hdq_data->hdq_usecount = 0; mutex_init(&hdq_data->hdq_mutex); - if (clk_enable(hdq_data->hdq_ick)) { - dev_dbg(&pdev->dev, "Can not enable ick\n"); - ret = -ENODEV; - goto err_intfclk; - } - - if (clk_enable(hdq_data->hdq_fck)) { - dev_dbg(&pdev->dev, "Can not enable fck\n"); - ret = -ENODEV; - goto err_fnclk; - } + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION); dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n", @@ -641,9 +601,7 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev) omap_hdq_break(hdq_data); - /* don't clock the HDQ until it is needed */ - clk_disable(hdq_data->hdq_ick); - clk_disable(hdq_data->hdq_fck); + pm_runtime_put_sync(&pdev->dev); omap_w1_master.data = hdq_data; @@ -655,20 +613,11 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev) return 0; -err_w1: err_irq: - clk_disable(hdq_data->hdq_fck); - -err_fnclk: - clk_disable(hdq_data->hdq_ick); - -err_intfclk: - clk_put(hdq_data->hdq_fck); - -err_fck: - clk_put(hdq_data->hdq_ick); + pm_runtime_put_sync(&pdev->dev); +err_w1: + pm_runtime_disable(&pdev->dev); -err_ick: iounmap(hdq_data->hdq_base); err_ioremap: @@ -696,8 +645,7 @@ static int omap_hdq_remove(struct platform_device *pdev) mutex_unlock(&hdq_data->hdq_mutex); /* remove module dependency */ - clk_put(hdq_data->hdq_ick); - clk_put(hdq_data->hdq_fck); + pm_runtime_disable(&pdev->dev); free_irq(INT_24XX_HDQ_IRQ, hdq_data); platform_set_drvdata(pdev, NULL); iounmap(hdq_data->hdq_base); -- GitLab From b43d224767e426cf1a8b6622d1d172f2b2b0e857 Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Thu, 21 Jun 2012 21:51:22 -0700 Subject: [PATCH 2428/6849] ALSA: hda - Don't power up when not powered down. After cancel_delayed_work_sync returns, the power down work either never started (power_on == 1) or finished (power_on == 0). In the former case there is no need to power up again. Signed-off-by: Dylan Reid Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 604699cf85f5..045b5e7b8245 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4444,6 +4444,13 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) cancel_delayed_work_sync(&codec->power_work); spin_lock(&codec->power_lock); + /* If the power down delayed work was cancelled above before starting, + * then there is no need to go through power up here. + */ + if (codec->power_on) { + spin_unlock(&codec->power_lock); + return; + } trace_hda_power_up(codec); snd_hda_update_power_acct(codec); codec->power_on = 1; -- GitLab From 645865fc377c9ac73df590abf8e6af65824390a3 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Sun, 20 May 2012 10:38:16 +0300 Subject: [PATCH 2429/6849] wlcore: Fix sdio out-of-sync power state wl12xx_sdio_power_off() manually powers down the card regardless of the runtime pm state. If wl12xx_sdio_power_on() is called before the card was suspended by runtime PM, it will not power up the card. As part of the HW detection, the chip's power is toggled. Since this happens in the context of probing sdio, the power reference counter will be higher than zero. As a result, when wl12xx_sdio_power_off() is called, the chip will be powered down while still having a positive power reference counter. If the interface is quickly activated, the driver might try to transfer data to a powered off chip. Fix this by ensuring that wl12xx_sdio_power_on() explicitly powers on the chip in case runtime pm claims the chip is already powered on. To avoid cases in which it is not possible to determine if the chip was really powered on (card's power reference counter is positive), operate on the mmc_card instead of the function. Also verify that the chip is indeed powered on before powering off, to avoid wrong reference counter values in error cases. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/io.h | 10 ++++++-- drivers/net/wireless/ti/wlcore/sdio.c | 34 +++++++++++++++------------ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 8942954b56a0..404cb14458eb 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -160,8 +160,14 @@ static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) static inline void wl1271_power_off(struct wl1271 *wl) { - wl->if_ops->power(wl->dev, false); - clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + int ret; + + if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags)) + return; + + ret = wl->if_ops->power(wl->dev, false); + if (!ret) + clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); } static inline int wl1271_power_on(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index c67ec482e445..4edaa20acfb1 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -147,17 +147,20 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); + struct mmc_card *card = func->card; - /* If enabled, tell runtime PM not to power off the card */ - if (pm_runtime_enabled(&func->dev)) { - ret = pm_runtime_get_sync(&func->dev); - if (ret < 0) - goto out; - } else { - /* Runtime PM is disabled: power up the card manually */ - ret = mmc_power_restore_host(func->card->host); - if (ret < 0) + ret = pm_runtime_get_sync(&card->dev); + if (ret) { + /* + * Runtime PM might be temporarily disabled, or the device + * might have a positive reference counter. Make sure it is + * really powered on. + */ + ret = mmc_power_restore_host(card->host); + if (ret < 0) { + pm_runtime_put_sync(&card->dev); goto out; + } } sdio_claim_host(func); @@ -172,20 +175,21 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); + struct mmc_card *card = func->card; sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); - /* Power off the card manually, even if runtime PM is enabled. */ - ret = mmc_power_save_host(func->card->host); + /* Power off the card manually in case it wasn't powered off above */ + ret = mmc_power_save_host(card->host); if (ret < 0) - return ret; + goto out; - /* If enabled, let runtime PM know the card is powered off */ - if (pm_runtime_enabled(&func->dev)) - ret = pm_runtime_put_sync(&func->dev); + /* Let runtime PM know the card is powered off */ + pm_runtime_put_sync(&card->dev); +out: return ret; } -- GitLab From b666bb7f2fe2bdc0309b0d58afb48eae85d92221 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 21 May 2012 01:10:11 +0300 Subject: [PATCH 2430/6849] wlcore: Disable interrupts while recovering In case a recovery is initiated, the FW can no longer be trusted, and the driver should not handle any new FW events. Disable the interrupt handler when a recovery is scheduled and balance it back in the op_stop callback. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/io.c | 6 ++++++ drivers/net/wireless/ti/wlcore/io.h | 1 + drivers/net/wireless/ti/wlcore/main.c | 21 +++++++++++++++------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/io.c b/drivers/net/wireless/ti/wlcore/io.c index 7cd0081aede5..62d657389996 100644 --- a/drivers/net/wireless/ti/wlcore/io.c +++ b/drivers/net/wireless/ti/wlcore/io.c @@ -48,6 +48,12 @@ void wlcore_disable_interrupts(struct wl1271 *wl) } EXPORT_SYMBOL_GPL(wlcore_disable_interrupts); +void wlcore_disable_interrupts_nosync(struct wl1271 *wl) +{ + disable_irq_nosync(wl->irq); +} +EXPORT_SYMBOL_GPL(wlcore_disable_interrupts_nosync); + void wlcore_enable_interrupts(struct wl1271 *wl) { enable_irq(wl->irq); diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 404cb14458eb..bbaf7117204e 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -45,6 +45,7 @@ struct wl1271; void wlcore_disable_interrupts(struct wl1271 *wl); +void wlcore_disable_interrupts_nosync(struct wl1271 *wl); void wlcore_enable_interrupts(struct wl1271 *wl); void wl1271_io_reset(struct wl1271 *wl); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 78edc58da210..c94351a92419 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -743,8 +743,11 @@ out: void wl12xx_queue_recovery_work(struct wl1271 *wl) { - if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) + /* Avoid a recursive recovery */ + if (!test_and_set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { + wlcore_disable_interrupts_nosync(wl); ieee80211_queue_work(wl->hw, &wl->recovery_work); + } } size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) @@ -848,9 +851,6 @@ static void wl1271_recovery_work(struct work_struct *work) if (wl->state != WL1271_STATE_ON || wl->plt) goto out_unlock; - /* Avoid a recursive recovery */ - set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); - wl12xx_read_fwlog_panic(wl); /* change partitions momentarily so we can read the FW pc */ @@ -902,8 +902,6 @@ static void wl1271_recovery_work(struct work_struct *work) mutex_unlock(&wl->mutex); wl1271_op_stop(wl->hw); - clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); - ieee80211_restart_hw(wl->hw); /* @@ -1706,6 +1704,10 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wlcore_disable_interrupts(wl); mutex_lock(&wl->mutex); if (wl->state == WL1271_STATE_OFF) { + if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, + &wl->flags)) + wlcore_enable_interrupts(wl); + mutex_unlock(&wl->mutex); /* @@ -1737,6 +1739,13 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) mutex_lock(&wl->mutex); wl1271_power_off(wl); + /* + * In case a recovery was scheduled, interrupts were disabled to avoid + * an interrupt storm. Now that the power is down, it is safe to + * re-enable interrupts to balance the disable depth + */ + if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) + wlcore_enable_interrupts(wl); wl->band = IEEE80211_BAND_2GHZ; -- GitLab From 02eb1d9d3bc307e2b540b8c095fa19342789f86d Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Sun, 17 Jun 2012 20:30:05 +0300 Subject: [PATCH 2431/6849] wlcore: Change read/write ops to return errors While bus operations may fail, either due to HW or FW issues, these are never propagated to higher layers. As a result, the core driver has no way of knowing that the operations failed, and will only recover if high level logic requires it (e.g. no command completion). Change read/write bus operations to return errors to let higher layer functionality handle these. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/sdio.c | 16 ++++++++++------ drivers/net/wireless/ti/wlcore/spi.c | 14 +++++++++----- drivers/net/wireless/ti/wlcore/wlcore_i.h | 6 +++--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 4edaa20acfb1..9069dc93b1bc 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -71,8 +71,8 @@ static void wl1271_sdio_set_block_size(struct device *child, sdio_release_host(func); } -static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, + size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); @@ -103,12 +103,14 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, sdio_release_host(func); - if (ret) + if (WARN_ON(ret)) dev_err(child->parent, "sdio read failed (%d)\n", ret); + + return ret; } -static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, + size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); @@ -139,8 +141,10 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, sdio_release_host(func); - if (ret) + if (WARN_ON(ret)) dev_err(child->parent, "sdio write failed (%d)\n", ret); + + return ret; } static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index 553cd3cbb98c..d6768e9d7dab 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c @@ -193,8 +193,8 @@ static int wl12xx_spi_read_busy(struct device *child) return -ETIMEDOUT; } -static void wl12xx_spi_raw_read(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int wl12xx_spi_raw_read(struct device *child, int addr, void *buf, + size_t len, bool fixed) { struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); struct wl1271 *wl = dev_get_drvdata(child); @@ -238,7 +238,7 @@ static void wl12xx_spi_raw_read(struct device *child, int addr, void *buf, if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && wl12xx_spi_read_busy(child)) { memset(buf, 0, chunk_len); - return; + return 0; } spi_message_init(&m); @@ -256,10 +256,12 @@ static void wl12xx_spi_raw_read(struct device *child, int addr, void *buf, buf += chunk_len; len -= chunk_len; } + + return 0; } -static void wl12xx_spi_raw_write(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int wl12xx_spi_raw_write(struct device *child, int addr, void *buf, + size_t len, bool fixed) { struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; @@ -304,6 +306,8 @@ static void wl12xx_spi_raw_write(struct device *child, int addr, void *buf, } spi_sync(to_spi_device(glue->dev), &m); + + return 0; } static struct wl1271_if_operations spi_ops = { diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 8260b1e9288a..5ab31ff4080e 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -209,9 +209,9 @@ struct wl1271_scan { }; struct wl1271_if_operations { - void (*read)(struct device *child, int addr, void *buf, size_t len, - bool fixed); - void (*write)(struct device *child, int addr, void *buf, size_t len, + int (*read)(struct device *child, int addr, void *buf, size_t len, + bool fixed); + int (*write)(struct device *child, int addr, void *buf, size_t len, bool fixed); void (*reset)(struct device *child); void (*init)(struct device *child); -- GitLab From 0c2a6ce04eb4d742170a4ddfeb57263fb7964698 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Sun, 17 Jun 2012 21:29:51 +0300 Subject: [PATCH 2432/6849] wlcore: Change raw io functions to return errors Make wl1271_raw_write and wl1271_raw_read return errors so the driver could handle these appropriately. Since the prototype has changed, also rename the prefix of these functions to wlcore. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/io.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index bbaf7117204e..60b95033cdde 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -53,33 +53,33 @@ void wl1271_io_init(struct wl1271 *wl); int wlcore_translate_addr(struct wl1271 *wl, int addr); /* Raw target IO, address is not translated */ -static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int wlcore_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { - wl->if_ops->write(wl->dev, addr, buf, len, fixed); + return wl->if_ops->write(wl->dev, addr, buf, len, fixed); } -static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int wlcore_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { - wl->if_ops->read(wl->dev, addr, buf, len, fixed); + return wl->if_ops->read(wl->dev, addr, buf, len, fixed); } static inline void wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf, size_t len, bool fixed) { - wl1271_raw_read(wl, wl->rtable[reg], buf, len, fixed); + wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed); } static inline void wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf, size_t len, bool fixed) { - wl1271_raw_write(wl, wl->rtable[reg], buf, len, fixed); + wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); } static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) { - wl1271_raw_read(wl, addr, &wl->buffer_32, + wlcore_raw_read(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32), false); return le32_to_cpu(wl->buffer_32); @@ -88,7 +88,7 @@ static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) { wl->buffer_32 = cpu_to_le32(val); - wl1271_raw_write(wl, addr, &wl->buffer_32, + wlcore_raw_write(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32), false); } @@ -99,7 +99,7 @@ static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, physical = wlcore_translate_addr(wl, addr); - wl1271_raw_read(wl, physical, buf, len, fixed); + wlcore_raw_read(wl, physical, buf, len, fixed); } static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, @@ -109,7 +109,7 @@ static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, physical = wlcore_translate_addr(wl, addr); - wl1271_raw_write(wl, physical, buf, len, fixed); + wlcore_raw_write(wl, physical, buf, len, fixed); } static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf, @@ -135,7 +135,7 @@ static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, physical = wlcore_translate_addr(wl, addr); - wl1271_raw_read(wl, physical, buf, len, fixed); + wlcore_raw_read(wl, physical, buf, len, fixed); } static inline u32 wl1271_read32(struct wl1271 *wl, int addr) -- GitLab From 8b7c0fc3569693c3a68103b7d5a7dad5b84109bc Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Sun, 17 Jun 2012 21:59:42 +0300 Subject: [PATCH 2433/6849] wlcore: Propagate errors from wlcore_raw_*_data functions wlcore_raw_read_data is called when the FW status is read which happens while handling interrupts and when the FW log is read following a recovery. Request a recovery in the former case, and don't read the FW log in case the FW status read failed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/io.h | 12 ++++++------ drivers/net/wireless/ti/wlcore/main.c | 27 ++++++++++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 60b95033cdde..2713ce11e21b 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -65,16 +65,16 @@ static inline int wlcore_raw_read(struct wl1271 *wl, int addr, void *buf, return wl->if_ops->read(wl->dev, addr, buf, len, fixed); } -static inline void wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed); + return wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed); } -static inline void wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); + return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); } static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index c94351a92419..085cd17fa074 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -378,9 +378,9 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, } } -static void wl12xx_fw_status(struct wl1271 *wl, - struct wl_fw_status_1 *status_1, - struct wl_fw_status_2 *status_2) +static int wlcore_fw_status(struct wl1271 *wl, + struct wl_fw_status_1 *status_1, + struct wl_fw_status_2 *status_2) { struct wl12xx_vif *wlvif; struct timespec ts; @@ -388,12 +388,15 @@ static void wl12xx_fw_status(struct wl1271 *wl, int avail, freed_blocks; int i; size_t status_len; + int ret; status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + sizeof(*status_2) + wl->fw_status_priv_len; - wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, - status_len, false); + ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, + status_len, false); + if (ret < 0) + return ret; wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " "drv_rx_counter = %d, tx_results_counter = %d)", @@ -462,6 +465,8 @@ static void wl12xx_fw_status(struct wl1271 *wl, getnstimeofday(&ts); wl->time_offset = (timespec_to_ns(&ts) >> 10) - (s64)le32_to_cpu(status_2->fw_localtime); + + return 0; } static void wl1271_flush_deferred_work(struct wl1271 *wl) @@ -530,7 +535,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); smp_mb__after_clear_bit(); - wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); + ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } wlcore_hw_tx_immediate_compl(wl); @@ -781,6 +790,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) u32 offset; u32 end_of_log; u8 *block; + int ret; if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) || (wl->conf.fwlog.mem_blocks == 0)) @@ -802,7 +812,10 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) wl12xx_cmd_stop_fwlog(wl); /* Read the first memory block address */ - wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); + ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); + if (ret < 0) + goto out; + addr = le32_to_cpu(wl->fw_status_2->log_start_addr); if (!addr) goto out; -- GitLab From 045b9b5f4172b2b21af0b9bf5e6dda51146d51a4 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 18 Jun 2012 12:31:16 +0300 Subject: [PATCH 2434/6849] wlcore: Propagate errors from wl1271_read Propagate errors from wl1271_read and request for recovery when appropriate. Also rename prefixes of wlcore functions which their prototypes had to be changed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 6 +++--- drivers/net/wireless/ti/wlcore/boot.c | 4 +++- drivers/net/wireless/ti/wlcore/cmd.c | 20 +++++++++++++++----- drivers/net/wireless/ti/wlcore/event.c | 6 ++++-- drivers/net/wireless/ti/wlcore/hw_ops.h | 6 ++++-- drivers/net/wireless/ti/wlcore/io.h | 10 +++++----- drivers/net/wireless/ti/wlcore/main.c | 24 ++++++++++++++++++++---- drivers/net/wireless/ti/wlcore/rx.c | 13 ++++++++++--- drivers/net/wireless/ti/wlcore/rx.h | 2 +- drivers/net/wireless/ti/wlcore/tx.c | 15 +++++++++++---- drivers/net/wireless/ti/wlcore/tx.h | 2 +- drivers/net/wireless/ti/wlcore/wlcore.h | 2 +- 12 files changed, 78 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 0d2fdca2aa32..916cee76b37f 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1162,13 +1162,13 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, return data_len - sizeof(*desc) - desc->pad_len; } -static void wl12xx_tx_delayed_compl(struct wl1271 *wl) +static int wl12xx_tx_delayed_compl(struct wl1271 *wl) { if (wl->fw_status_1->tx_results_counter == (wl->tx_results_count & 0xff)) - return; + return 0; - wl1271_tx_complete(wl); + return wlcore_tx_complete(wl); } static int wl12xx_hw_init(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 0fda500c01c9..d7abc505f2a3 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -87,7 +87,9 @@ static int wlcore_boot_static_data(struct wl1271 *wl) goto out; } - wl1271_read(wl, wl->cmd_box_addr, static_data, len, false); + ret = wlcore_read(wl, wl->cmd_box_addr, static_data, len, false); + if (ret < 0) + goto out_free; ret = wlcore_boot_parse_fw_ver(wl, static_data); if (ret < 0) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 885364ca4344..69f27d1fdcdf 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -95,7 +95,10 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, /* read back the status code of the command */ if (res_len == 0) res_len = sizeof(struct wl1271_cmd_header); - wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false); + + ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false); + if (ret < 0) + goto fail; status = le16_to_cpu(cmd->status); if (status != CMD_STATUS_SUCCESS) { @@ -141,11 +144,18 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) msleep(1); /* read from both event fields */ - wl1271_read(wl, wl->mbox_ptr[0], events_vector, - sizeof(*events_vector), false); + ret = wlcore_read(wl, wl->mbox_ptr[0], events_vector, + sizeof(*events_vector), false); + if (ret < 0) + goto out; + event = *events_vector & mask; - wl1271_read(wl, wl->mbox_ptr[1], events_vector, - sizeof(*events_vector), false); + + ret = wlcore_read(wl, wl->mbox_ptr[1], events_vector, + sizeof(*events_vector), false); + if (ret < 0) + goto out; + event |= *events_vector & mask; } while (!event); diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index c976f0409865..858ac33f5980 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -301,8 +301,10 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) return -EINVAL; /* first we read the mbox descriptor */ - wl1271_read(wl, wl->mbox_ptr[mbox_num], wl->mbox, - sizeof(*wl->mbox), false); + ret = wlcore_read(wl, wl->mbox_ptr[mbox_num], wl->mbox, + sizeof(*wl->mbox), false); + if (ret < 0) + return ret; /* process the descriptor */ ret = wl1271_event_process(wl); diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 9e7787ba9610..f44d586048ab 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -81,10 +81,12 @@ wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len) return wl->ops->get_rx_packet_len(wl, rx_data, data_len); } -static inline void wlcore_hw_tx_delayed_compl(struct wl1271 *wl) +static inline int wlcore_hw_tx_delayed_compl(struct wl1271 *wl) { if (wl->ops->tx_delayed_compl) - wl->ops->tx_delayed_compl(wl); + return wl->ops->tx_delayed_compl(wl); + + return 0; } static inline void wlcore_hw_tx_immediate_compl(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 2713ce11e21b..d114bb42a924 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -92,14 +92,14 @@ static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) sizeof(wl->buffer_32), false); } -static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int wlcore_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { int physical; physical = wlcore_translate_addr(wl, addr); - wlcore_raw_read(wl, physical, buf, len, fixed); + return wlcore_raw_read(wl, physical, buf, len, fixed); } static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, @@ -118,10 +118,10 @@ static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf, wl1271_write(wl, wl->rtable[reg], buf, len, fixed); } -static inline void wlcore_read_data(struct wl1271 *wl, int reg, void *buf, +static inline int wlcore_read_data(struct wl1271 *wl, int reg, void *buf, size_t len, bool fixed) { - wl1271_read(wl, wl->rtable[reg], buf, len, fixed); + return wlcore_read(wl, wl->rtable[reg], buf, len, fixed); } static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 085cd17fa074..deb22f8e193d 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -572,7 +572,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (likely(intr & WL1271_ACX_INTR_DATA)) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); - wl12xx_rx(wl, wl->fw_status_1); + ret = wlcore_rx(wl, wl->fw_status_1); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } /* Check if any tx blocks were freed */ spin_lock_irqsave(&wl->wl_lock, flags); @@ -589,7 +593,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) } /* check for tx results */ - wlcore_hw_tx_delayed_compl(wl); + ret = wlcore_hw_tx_delayed_compl(wl); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } /* Make sure the deferred queues don't get too long */ defer_count = skb_queue_len(&wl->deferred_tx_queue) + @@ -600,12 +608,20 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (intr & WL1271_ACX_INTR_EVENT_A) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); - wl1271_event_handle(wl, 0); + ret = wl1271_event_handle(wl, 0); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } } if (intr & WL1271_ACX_INTR_EVENT_B) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); - wl1271_event_handle(wl, 1); + ret = wl1271_event_handle(wl, 1); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } } if (intr & WL1271_ACX_INTR_INIT_COMPLETE) diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index a1db4e032409..59d0956c5d09 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -200,7 +200,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, return is_data; } -void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) +int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) { unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; u32 buf_size; @@ -211,6 +211,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) u32 pkt_offset, des; u8 hlid; enum wl_rx_buf_align rx_align; + int ret = 0; while (drv_rx_counter != fw_rx_counter) { buf_size = 0; @@ -235,8 +236,11 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) /* Read all available packets at once */ des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]); wlcore_hw_prepare_read(wl, des, buf_size); - wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, - buf_size, true); + + ret = wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, + buf_size, true); + if (ret < 0) + goto out; /* Split data into separate packets */ pkt_offset = 0; @@ -278,6 +282,9 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) wl->rx_counter); wl12xx_rearm_rx_streaming(wl, active_hlids); + +out: + return ret; } #ifdef CONFIG_PM diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h index 4324a427e835..79f7839a06e2 100644 --- a/drivers/net/wireless/ti/wlcore/rx.h +++ b/drivers/net/wireless/ti/wlcore/rx.h @@ -143,7 +143,7 @@ struct wl1271_rx_descriptor { u8 reserved; } __packed; -void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); +int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 8ee82b9f93f4..fc890cba8d39 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -881,16 +881,20 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, } /* Called upon reception of a TX complete interrupt */ -void wl1271_tx_complete(struct wl1271 *wl) +int wlcore_tx_complete(struct wl1271 *wl) { struct wl1271_acx_mem_map *memmap = (struct wl1271_acx_mem_map *)wl->target_mem_map; u32 count, fw_counter; u32 i; + int ret; /* read the tx results from the chipset */ - wl1271_read(wl, le32_to_cpu(memmap->tx_result), - wl->tx_res_if, sizeof(*wl->tx_res_if), false); + ret = wlcore_read(wl, le32_to_cpu(memmap->tx_result), + wl->tx_res_if, sizeof(*wl->tx_res_if), false); + if (ret < 0) + goto out; + fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); /* write host counter to chipset (to ack) */ @@ -916,8 +920,11 @@ void wl1271_tx_complete(struct wl1271 *wl) wl->tx_results_count++; } + +out: + return ret; } -EXPORT_SYMBOL(wl1271_tx_complete); +EXPORT_SYMBOL(wlcore_tx_complete); void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) { diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index fa4be1b91135..10540944a80c 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -235,7 +235,7 @@ static inline int wl1271_tx_total_queue_count(struct wl1271 *wl) void wl1271_tx_work(struct work_struct *work); void wl1271_tx_work_locked(struct wl1271 *wl); -void wl1271_tx_complete(struct wl1271 *wl); +int wlcore_tx_complete(struct wl1271 *wl); void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); void wl12xx_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 205d8ad2b761..fd37307ebb93 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -56,7 +56,7 @@ struct wlcore_ops { void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data, u32 data_len); - void (*tx_delayed_compl)(struct wl1271 *wl); + int (*tx_delayed_compl)(struct wl1271 *wl); void (*tx_immediate_compl)(struct wl1271 *wl); int (*hw_init)(struct wl1271 *wl); int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif); -- GitLab From eb96f841b9563ba34969be25615548635728faf5 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 18 Jun 2012 13:21:55 +0300 Subject: [PATCH 2435/6849] wlcore: Propagate errors from wl1271_write Propagate errors from wl1271_write and request for recovery when appropriate. Also rename prefixes of wlcore functions which their prototypes had to be changed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 23 +++++++++++++++----- drivers/net/wireless/ti/wl18xx/main.c | 19 ++++++++++------ drivers/net/wireless/ti/wlcore/boot.c | 17 ++++++++++----- drivers/net/wireless/ti/wlcore/cmd.c | 12 +++++++--- drivers/net/wireless/ti/wlcore/event.c | 5 ++++- drivers/net/wireless/ti/wlcore/hw_ops.h | 6 +++-- drivers/net/wireless/ti/wlcore/io.h | 12 +++++----- drivers/net/wireless/ti/wlcore/main.c | 13 ++++++++--- drivers/net/wireless/ti/wlcore/rx.c | 4 +++- drivers/net/wireless/ti/wlcore/tx.c | 29 ++++++++++++++++++------- drivers/net/wireless/ti/wlcore/tx.h | 2 +- drivers/net/wireless/ti/wlcore/wlcore.h | 6 ++--- 12 files changed, 102 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 916cee76b37f..257745fbdff9 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -598,8 +598,10 @@ static const int wl12xx_rtable[REG_TABLE_LEN] = { #define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin" #define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin" -static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) +static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) { + int ret; + if (wl->chip.id != CHIP_ID_1283_PG20) { struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; struct wl127x_rx_mem_pool_addr rx_mem_addr; @@ -616,9 +618,13 @@ static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) rx_mem_addr.addr_extra = rx_mem_addr.addr + 4; - wl1271_write(wl, WL1271_SLV_REG_DATA, - &rx_mem_addr, sizeof(rx_mem_addr), false); + ret = wlcore_write(wl, WL1271_SLV_REG_DATA, &rx_mem_addr, + sizeof(rx_mem_addr), false); + if (ret < 0) + return ret; } + + return 0; } static int wl12xx_identify_chip(struct wl1271 *wl) @@ -1073,11 +1079,18 @@ out: return ret; } -static void wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, +static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, void *buf, size_t len) { - wl1271_write(wl, cmd_box_addr, buf, len, false); + int ret; + + ret = wlcore_write(wl, cmd_box_addr, buf, len, false); + if (ret < 0) + return ret; + wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD); + + return ret; } static void wl12xx_ack_event(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 271ff81da922..974a6ff11f6d 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -720,10 +720,11 @@ static void wl18xx_pre_upload(struct wl1271 *wl) tmp = wl1271_read32(wl, WL18XX_SCR_PAD2); } -static void wl18xx_set_mac_and_phy(struct wl1271 *wl) +static int wl18xx_set_mac_and_phy(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; size_t len; + int ret; /* the parameters struct is smaller for PG1 */ if (wl->chip.id == CHIP_ID_185x_PG10) @@ -732,8 +733,10 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl) len = sizeof(struct wl18xx_mac_and_phy_params); wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); - wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, len, - false); + ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, + len, false); + + return ret; } static void wl18xx_enable_interrupts(struct wl1271 *wl) @@ -769,7 +772,9 @@ static int wl18xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - wl18xx_set_mac_and_phy(wl); + ret = wl18xx_set_mac_and_phy(wl); + if (ret < 0) + goto out; ret = wlcore_boot_run_firmware(wl); if (ret < 0) @@ -781,7 +786,7 @@ out: return ret; } -static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, +static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, void *buf, size_t len) { struct wl18xx_priv *priv = wl->priv; @@ -789,8 +794,8 @@ static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, memcpy(priv->cmd_buf, buf, len); memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len); - wl1271_write(wl, cmd_box_addr, priv->cmd_buf, WL18XX_CMD_MAX_SIZE, - false); + return wlcore_write(wl, cmd_box_addr, priv->cmd_buf, + WL18XX_CMD_MAX_SIZE, false); } static void wl18xx_ack_event(struct wl1271 *wl) diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index d7abc505f2a3..ee7a401478a9 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -111,6 +111,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, struct wlcore_partition_set partition; int addr, chunk_num, partition_limit; u8 *p, *chunk; + int ret; /* whal_FwCtrl_LoadFwImageSm() */ @@ -155,7 +156,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, memcpy(chunk, p, CHUNK_SIZE); wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", p, addr); - wl1271_write(wl, addr, chunk, CHUNK_SIZE, false); + ret = wlcore_write(wl, addr, chunk, CHUNK_SIZE, false); + if (ret < 0) + goto out; chunk_num++; } @@ -166,10 +169,11 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, memcpy(chunk, p, fw_data_len % CHUNK_SIZE); wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x", fw_data_len % CHUNK_SIZE, p, addr); - wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); + ret = wlcore_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); +out: kfree(chunk); - return 0; + return ret; } int wlcore_boot_upload_firmware(struct wl1271 *wl) @@ -212,6 +216,7 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) int i; u32 dest_addr, val; u8 *nvs_ptr, *nvs_aligned; + int ret; if (wl->nvs == NULL) { wl1271_error("NVS file is needed during boot"); @@ -343,11 +348,11 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) return -ENOMEM; /* And finally we upload the NVS tables */ - wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS, - nvs_aligned, nvs_len, false); + ret = wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, + false); kfree(nvs_aligned); - return 0; + return ret; out_badnvs: wl1271_error("nvs data is malformed"); diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 69f27d1fdcdf..658dccbfd7ed 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -65,13 +65,17 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, WARN_ON(len % 4 != 0); WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags)); - wl1271_write(wl, wl->cmd_box_addr, buf, len, false); + ret = wlcore_write(wl, wl->cmd_box_addr, buf, len, false); + if (ret < 0) + goto fail; /* * TODO: we just need this because one bit is in a different * place. Is there any better way? */ - wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len); + ret = wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len); + if (ret < 0) + goto fail; timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); @@ -1764,7 +1768,9 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) return -EINVAL; /* flush all pending packets */ - wl1271_tx_work_locked(wl); + ret = wlcore_tx_work_locked(wl); + if (ret < 0) + goto out; if (test_bit(wlvif->dev_role_id, wl->roc_map)) { ret = wl12xx_croc(wl, wlvif->dev_role_id); diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 858ac33f5980..123d26d17ba4 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -105,6 +105,7 @@ static int wl1271_event_process(struct wl1271 *wl) u32 vector; bool disconnect_sta = false; unsigned long sta_bitmap = 0; + int ret; wl1271_event_mbox_dump(mbox); @@ -228,7 +229,9 @@ static int wl1271_event_process(struct wl1271 *wl) if ((vector & DUMMY_PACKET_EVENT_ID)) { wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); - wl1271_tx_dummy_packet(wl); + ret = wl1271_tx_dummy_packet(wl); + if (ret < 0) + return ret; } /* diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index f44d586048ab..2673d783ec1e 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -65,11 +65,13 @@ wlcore_hw_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc) return wl->ops->get_rx_buf_align(wl, rx_desc); } -static inline void +static inline int wlcore_hw_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) { if (wl->ops->prepare_read) - wl->ops->prepare_read(wl, rx_desc, len); + return wl->ops->prepare_read(wl, rx_desc, len); + + return 0; } static inline u32 diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index d114bb42a924..2cbf7623ddbb 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -102,20 +102,20 @@ static inline int wlcore_read(struct wl1271 *wl, int addr, void *buf, return wlcore_raw_read(wl, physical, buf, len, fixed); } -static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int wlcore_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { int physical; physical = wlcore_translate_addr(wl, addr); - wlcore_raw_write(wl, physical, buf, len, fixed); + return wlcore_raw_write(wl, physical, buf, len, fixed); } -static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int wlcore_write_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - wl1271_write(wl, wl->rtable[reg], buf, len, fixed); + return wlcore_write(wl, wl->rtable[reg], buf, len, fixed); } static inline int wlcore_read_data(struct wl1271 *wl, int reg, void *buf, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index deb22f8e193d..0461d4eecfd2 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -587,7 +587,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) * In order to avoid starvation of the TX path, * call the work function directly. */ - wl1271_tx_work_locked(wl); + ret = wlcore_tx_work_locked(wl); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } } else { spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -1211,7 +1215,7 @@ int wl1271_tx_dummy_packet(struct wl1271 *wl) /* The FW is low on RX memory blocks, so send the dummy packet asap */ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) - wl1271_tx_work_locked(wl); + return wlcore_tx_work_locked(wl); /* * If the FW TX is busy, TX work will be scheduled by the threaded @@ -2513,7 +2517,10 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, (wlvif->channel != channel) || (wlvif->channel_type != conf->channel_type))) { /* send all pending packets */ - wl1271_tx_work_locked(wl); + ret = wlcore_tx_work_locked(wl); + if (ret < 0) + return ret; + wlvif->band = conf->channel->band; wlvif->channel = channel; wlvif->channel_type = conf->channel_type; diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index 59d0956c5d09..be24b3030f92 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -235,7 +235,9 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) /* Read all available packets at once */ des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]); - wlcore_hw_prepare_read(wl, des, buf_size); + ret = wlcore_hw_prepare_read(wl, des, buf_size); + if (ret < 0) + goto out; ret = wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, buf_size, true); diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index fc890cba8d39..90bddf56f8ed 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -662,7 +662,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids) } } -void wl1271_tx_work_locked(struct wl1271 *wl) +int wlcore_tx_work_locked(struct wl1271 *wl) { struct wl12xx_vif *wlvif; struct sk_buff *skb; @@ -670,10 +670,10 @@ void wl1271_tx_work_locked(struct wl1271 *wl) u32 buf_offset = 0, last_len = 0; bool sent_packets = false; unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; - int ret; + int ret = 0; if (unlikely(wl->state == WL1271_STATE_OFF)) - return; + return -EIO; while ((skb = wl1271_skb_dequeue(wl))) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -694,8 +694,11 @@ void wl1271_tx_work_locked(struct wl1271 *wl) buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); - wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); + ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, + wl->aggr_buf, buf_offset, true); + if (ret < 0) + goto out; + sent_packets = true; buf_offset = 0; continue; @@ -731,8 +734,11 @@ void wl1271_tx_work_locked(struct wl1271 *wl) out_ack: if (buf_offset) { buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); - wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); + ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + if (ret < 0) + goto out; + sent_packets = true; } if (sent_packets) { @@ -747,6 +753,9 @@ out_ack: wl1271_handle_tx_low_watermark(wl); } wl12xx_rearm_rx_streaming(wl, active_hlids); + +out: + return ret; } void wl1271_tx_work(struct work_struct *work) @@ -759,7 +768,11 @@ void wl1271_tx_work(struct work_struct *work) if (ret < 0) goto out; - wl1271_tx_work_locked(wl); + ret = wlcore_tx_work_locked(wl); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } wl1271_ps_elp_sleep(wl); out: diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 10540944a80c..1e939b016155 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -234,7 +234,7 @@ static inline int wl1271_tx_total_queue_count(struct wl1271 *wl) } void wl1271_tx_work(struct work_struct *work); -void wl1271_tx_work_locked(struct wl1271 *wl); +int wlcore_tx_work_locked(struct wl1271 *wl); int wlcore_tx_complete(struct wl1271 *wl); void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); void wl12xx_tx_reset(struct wl1271 *wl); diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index fd37307ebb93..5d51647e6154 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -41,8 +41,8 @@ struct wlcore_ops { int (*identify_fw)(struct wl1271 *wl); int (*boot)(struct wl1271 *wl); int (*plt_init)(struct wl1271 *wl); - void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, - void *buf, size_t len); + int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, + void *buf, size_t len); void (*ack_event)(struct wl1271 *wl); u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks); void (*set_tx_desc_blocks)(struct wl1271 *wl, @@ -53,7 +53,7 @@ struct wlcore_ops { struct sk_buff *skb); enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl, u32 rx_desc); - void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); + int (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data, u32 data_len); int (*tx_delayed_compl)(struct wl1271 *wl); -- GitLab From 6134323f42b0dbae8e8206414d26cb167b9bedfc Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 18 Jun 2012 15:50:21 +0300 Subject: [PATCH 2436/6849] wlcore: Propagate errors from wl1271_raw_read32 Propagate errors from wl1271_raw_read32. Since the read functions had no way of returning errors in-band, change their prototypes. Also rename prefixes of wlcore functions which their prototypes had to be changed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 152 ++++++++++++++++++------ drivers/net/wireless/ti/wl18xx/io.c | 35 ++++-- drivers/net/wireless/ti/wl18xx/io.h | 4 +- drivers/net/wireless/ti/wl18xx/main.c | 114 +++++++++++++----- drivers/net/wireless/ti/wlcore/boot.c | 31 +++-- drivers/net/wireless/ti/wlcore/cmd.c | 9 +- drivers/net/wireless/ti/wlcore/io.h | 26 ++-- drivers/net/wireless/ti/wlcore/main.c | 47 ++++++-- drivers/net/wireless/ti/wlcore/wlcore.h | 4 +- 9 files changed, 309 insertions(+), 113 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 257745fbdff9..ab486f71eee4 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -701,10 +701,11 @@ static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE); } -static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr) +static int wl12xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) { u32 val; int timeout = OCP_CMD_LOOP; + int ret; /* write address >> 1 + 0x30000 to OCP_POR_CTR */ addr = (addr >> 1) + 0x30000; @@ -715,29 +716,38 @@ static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr) /* poll for data ready */ do { - val = wl1271_read32(wl, WL12XX_OCP_DATA_READ); + ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val); + if (ret < 0) + return ret; } while (!(val & OCP_READY_MASK) && --timeout); if (!timeout) { wl1271_warning("Top register access timed out."); - return 0xffff; + return -ETIMEDOUT; } /* check data status and return if OK */ - if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) - return val & 0xffff; - else { + if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) { wl1271_warning("Top register access returned error."); - return 0xffff; + return -EIO; } + + if (out) + *out = val & 0xffff; + + return 0; } static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) { u16 spare_reg; + int ret; /* Mask bits [2] & [8:4] in the sys_clk_cfg register */ - spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); + ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg); + if (ret < 0) + return ret; + if (spare_reg == 0xFFFF) return -EFAULT; spare_reg |= (BIT(3) | BIT(5) | BIT(6)); @@ -756,8 +766,12 @@ static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) static bool wl128x_is_tcxo_valid(struct wl1271 *wl) { u16 tcxo_detection; + int ret; + + ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection); + if (ret < 0) + return false; - tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG); if (tcxo_detection & TCXO_DET_FAILED) return false; @@ -767,8 +781,12 @@ static bool wl128x_is_tcxo_valid(struct wl1271 *wl) static bool wl128x_is_fref_valid(struct wl1271 *wl) { u16 fref_detection; + int ret; + + ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection); + if (ret < 0) + return false; - fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG); if (fref_detection & FREF_CLK_DETECT_FAIL) return false; @@ -790,9 +808,13 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) u16 pll_config; u8 input_freq; struct wl12xx_priv *priv = wl->priv; + int ret; /* Mask bits [3:1] in the sys_clk_cfg register */ - spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); + ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg); + if (ret < 0) + return ret; + if (spare_reg == 0xFFFF) return -EFAULT; spare_reg |= BIT(2); @@ -806,7 +828,10 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) /* Set the input frequency according to the selected clock source */ input_freq = (clk & 1) + 1; - pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG); + ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config); + if (ret < 0) + return ret; + if (pll_config == 0xFFFF) return -EFAULT; pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT); @@ -827,6 +852,7 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) { struct wl12xx_priv *priv = wl->priv; u16 sys_clk_cfg; + int ret; /* For XTAL-only modes, FREF will be used after switching from TCXO */ if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL || @@ -837,7 +863,10 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) } /* Query the HW, to determine which clock source we should use */ - sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG); + ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg); + if (ret < 0) + return ret; + if (sys_clk_cfg == 0xFFFF) return -EINVAL; if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF) @@ -872,6 +901,7 @@ static int wl127x_boot_clk(struct wl1271 *wl) struct wl12xx_priv *priv = wl->priv; u32 pause; u32 clk; + int ret; if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION; @@ -892,18 +922,27 @@ static int wl127x_boot_clk(struct wl1271 *wl) if (priv->ref_clock != CONF_REF_CLK_19_2_E) { u16 val; /* Set clock type (open drain) */ - val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE); + ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val); + if (ret < 0) + goto out; + val &= FREF_CLK_TYPE_BITS; wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val); /* Set clock pull mode (no pull) */ - val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL); + ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val); + if (ret < 0) + goto out; + val |= NO_PULL; wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val); } else { u16 val; /* Set clock polarity */ - val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY); + ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val); + if (ret < 0) + goto out; + val &= FREF_CLK_POLARITY_BITS; val |= CLK_REQ_OUTN_SEL; wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); @@ -911,7 +950,9 @@ static int wl127x_boot_clk(struct wl1271 *wl) wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk); - pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS); + ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause); + if (ret < 0) + goto out; wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); @@ -919,13 +960,15 @@ static int wl127x_boot_clk(struct wl1271 *wl) pause |= WU_COUNTER_PAUSE_VAL; wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause); - return 0; +out: + return ret; } static int wl1271_boot_soft_reset(struct wl1271 *wl) { unsigned long timeout; u32 boot_data; + int ret = 0; /* perform soft reset */ wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); @@ -933,7 +976,10 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) /* SOFT_RESET is self clearing */ timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); while (1) { - boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET); + ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data); + if (ret < 0) + goto out; + wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) break; @@ -954,7 +1000,8 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) /* disable auto calibration on start*/ wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff); - return 0; +out: + return ret; } static int wl12xx_pre_boot(struct wl1271 *wl) @@ -984,7 +1031,9 @@ static int wl12xx_pre_boot(struct wl1271 *wl) to be used by DRPw FW. The RTRIM value will be added by the FW before taking DRPw out of reset */ - clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START); + ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk); + if (ret < 0) + goto out; wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); @@ -1008,9 +1057,11 @@ out: return ret; } -static void wl12xx_pre_upload(struct wl1271 *wl) +static int wl12xx_pre_upload(struct wl1271 *wl) { - u32 tmp, polarity; + u32 tmp; + u16 polarity; + int ret; /* write firmware's last address (ie. it's length) to * ACX_EEPROMLESS_IND_REG */ @@ -1018,12 +1069,16 @@ static void wl12xx_pre_upload(struct wl1271 *wl) wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND); - tmp = wlcore_read_reg(wl, REG_CHIP_ID_B); + ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); + if (ret < 0) + goto out; wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); /* 6. read the EEPROM parameters */ - tmp = wl1271_read32(wl, WL12XX_SCR_PAD2); + ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp); + if (ret < 0) + goto out; /* WL1271: The reference driver skips steps 7 to 10 (jumps directly * to upload_fw) */ @@ -1032,12 +1087,16 @@ static void wl12xx_pre_upload(struct wl1271 *wl) wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); /* polarity must be set before the firmware is loaded */ - polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY); + ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity); + if (ret < 0) + goto out; /* We use HIGH polarity, so unset the LOW bit */ polarity &= ~POLARITY_LOW; wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); +out: + return ret; } static void wl12xx_enable_interrupts(struct wl1271 *wl) @@ -1063,7 +1122,9 @@ static int wl12xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - wl12xx_pre_upload(wl); + ret = wl12xx_pre_upload(wl); + if (ret < 0) + goto out; ret = wlcore_boot_upload_firmware(wl); if (ret < 0) @@ -1282,14 +1343,20 @@ static bool wl12xx_mac_in_fuse(struct wl1271 *wl) return supported; } -static void wl12xx_get_fuse_mac(struct wl1271 *wl) +static int wl12xx_get_fuse_mac(struct wl1271 *wl) { u32 mac1, mac2; + int ret; wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); - mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1); - mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2); + ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1); + if (ret < 0) + goto out; + + ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2); + if (ret < 0) + goto out; /* these are the two parts of the BD_ADDR */ wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + @@ -1297,24 +1364,35 @@ static void wl12xx_get_fuse_mac(struct wl1271 *wl) wl->fuse_nic_addr = mac1 & 0xffffff; wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); + +out: + return ret; } -static s8 wl12xx_get_pg_ver(struct wl1271 *wl) +static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver) { - u32 die_info; + u16 die_info; + int ret; if (wl->chip.id == CHIP_ID_1283_PG20) - die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1); + ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1, + &die_info); else - die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1); + ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1, + &die_info); - return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET; + if (ret >= 0 && ver) + *ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET); + + return ret; } -static void wl12xx_get_mac(struct wl1271 *wl) +static int wl12xx_get_mac(struct wl1271 *wl) { if (wl12xx_mac_in_fuse(wl)) - wl12xx_get_fuse_mac(wl); + return wl12xx_get_fuse_mac(wl); + + return 0; } static void wl12xx_set_tx_desc_csum(struct wl1271 *wl, diff --git a/drivers/net/wireless/ti/wl18xx/io.c b/drivers/net/wireless/ti/wl18xx/io.c index 598c057e722b..92c2c03e4cd8 100644 --- a/drivers/net/wireless/ti/wl18xx/io.c +++ b/drivers/net/wireless/ti/wl18xx/io.c @@ -24,37 +24,52 @@ #include "io.h" -void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) +int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) { u32 tmp; + int ret; if (WARN_ON(addr % 2)) - return; + return -EINVAL; if ((addr % 4) == 0) { - tmp = wl1271_read32(wl, addr); + ret = wlcore_read32(wl, addr, &tmp); + if (ret < 0) + goto out; + tmp = (tmp & 0xffff0000) | val; wl1271_write32(wl, addr, tmp); } else { - tmp = wl1271_read32(wl, addr - 2); + ret = wlcore_read32(wl, addr - 2, &tmp); + if (ret < 0) + goto out; + tmp = (tmp & 0xffff) | (val << 16); wl1271_write32(wl, addr - 2, tmp); } + +out: + return ret; } -u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr) +int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) { u32 val; + int ret; if (WARN_ON(addr % 2)) - return 0; + return -EINVAL; if ((addr % 4) == 0) { /* address is 4-bytes aligned */ - val = wl1271_read32(wl, addr); - return val & 0xffff; + ret = wlcore_read32(wl, addr, &val); + if (ret >= 0 && out) + *out = val & 0xffff; } else { - val = wl1271_read32(wl, addr - 2); - return (val & 0xffff0000) >> 16; + ret = wlcore_read32(wl, addr - 2, &val); + if (ret >= 0 && out) + *out = (val & 0xffff0000) >> 16; } + + return ret; } diff --git a/drivers/net/wireless/ti/wl18xx/io.h b/drivers/net/wireless/ti/wl18xx/io.h index be4e126ff617..0e1b8d28edb2 100644 --- a/drivers/net/wireless/ti/wl18xx/io.h +++ b/drivers/net/wireless/ti/wl18xx/io.h @@ -22,7 +22,7 @@ #ifndef __WL18XX_IO_H__ #define __WL18XX_IO_H__ -void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); -u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr); +int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); +int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out); #endif /* __WL18XX_IO_H__ */ diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 974a6ff11f6d..f99f003ab182 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -636,45 +636,67 @@ out: return ret; } -static void wl18xx_set_clk(struct wl1271 *wl) +static int wl18xx_set_clk(struct wl1271 *wl) { - u32 clk_freq; + u16 clk_freq; + int ret; wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); /* TODO: PG2: apparently we need to read the clk type */ - clk_freq = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT); + ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq); + if (ret < 0) + goto out; + wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq, wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m, wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q, wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit"); - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, wl18xx_clk_table[clk_freq].n); - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, wl18xx_clk_table[clk_freq].m); + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, + wl18xx_clk_table[clk_freq].n); + if (ret < 0) + goto out; + + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, + wl18xx_clk_table[clk_freq].m); + if (ret < 0) + goto out; if (wl18xx_clk_table[clk_freq].swallow) { /* first the 16 lower bits */ - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, - wl18xx_clk_table[clk_freq].q & - PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, + wl18xx_clk_table[clk_freq].q & + PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); + if (ret < 0) + goto out; + /* then the 16 higher bits, masked out */ - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, - (wl18xx_clk_table[clk_freq].q >> 16) & - PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, + (wl18xx_clk_table[clk_freq].q >> 16) & + PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); + if (ret < 0) + goto out; /* first the 16 lower bits */ - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, - wl18xx_clk_table[clk_freq].p & - PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, + wl18xx_clk_table[clk_freq].p & + PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); + if (ret < 0) + goto out; + /* then the 16 higher bits, masked out */ - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, - (wl18xx_clk_table[clk_freq].p >> 16) & - PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, + (wl18xx_clk_table[clk_freq].p >> 16) & + PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); } else { - wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, - PLLSH_WCS_PLL_SWALLOW_EN_VAL2); + ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, + PLLSH_WCS_PLL_SWALLOW_EN_VAL2); } + +out: + return ret; } static void wl18xx_boot_soft_reset(struct wl1271 *wl) @@ -688,7 +710,11 @@ static void wl18xx_boot_soft_reset(struct wl1271 *wl) static int wl18xx_pre_boot(struct wl1271 *wl) { - wl18xx_set_clk(wl); + int ret; + + ret = wl18xx_set_clk(wl); + if (ret < 0) + goto out; /* Continue the ELP wake up sequence */ wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); @@ -701,23 +727,30 @@ static int wl18xx_pre_boot(struct wl1271 *wl) wl18xx_boot_soft_reset(wl); - return 0; +out: + return ret; } -static void wl18xx_pre_upload(struct wl1271 *wl) +static int wl18xx_pre_upload(struct wl1271 *wl) { u32 tmp; + int ret; wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); /* TODO: check if this is all needed */ wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); - tmp = wlcore_read_reg(wl, REG_CHIP_ID_B); + ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); + if (ret < 0) + goto out; wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); - tmp = wl1271_read32(wl, WL18XX_SCR_PAD2); + ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp); + +out: + return ret; } static int wl18xx_set_mac_and_phy(struct wl1271 *wl) @@ -766,7 +799,9 @@ static int wl18xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - wl18xx_pre_upload(wl); + ret = wl18xx_pre_upload(wl); + if (ret < 0) + goto out; ret = wlcore_boot_upload_firmware(wl); if (ret < 0) @@ -998,18 +1033,24 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, } } -static s8 wl18xx_get_pg_ver(struct wl1271 *wl) +static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) { u32 fuse; + int ret; wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - fuse = wl1271_read32(wl, WL18XX_REG_FUSE_DATA_1_3); - fuse = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; + ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse); + if (ret < 0) + goto out; + + if (ver) + *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - return (s8)fuse; +out: + return ret; } #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin" @@ -1080,14 +1121,20 @@ static int wl18xx_plt_init(struct wl1271 *wl) return wl->ops->boot(wl); } -static void wl18xx_get_mac(struct wl1271 *wl) +static int wl18xx_get_mac(struct wl1271 *wl) { u32 mac1, mac2; + int ret; wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - mac1 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1); - mac2 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2); + ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1); + if (ret < 0) + goto out; + + ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2); + if (ret < 0) + goto out; /* these are the two parts of the BD_ADDR */ wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + @@ -1095,6 +1142,9 @@ static void wl18xx_get_mac(struct wl1271 *wl) wl->fuse_nic_addr = (mac1 & 0xffffff); wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); + +out: + return ret; } static int wl18xx_handle_static_data(struct wl1271 *wl, diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index ee7a401478a9..0aa0e29b8d98 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -33,16 +33,22 @@ #include "rx.h" #include "hw_ops.h" -static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) +static int wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) { u32 cpu_ctrl; + int ret; /* 10.5.0 run the firmware (I) */ - cpu_ctrl = wlcore_read_reg(wl, REG_ECPU_CONTROL); + ret = wlcore_read_reg(wl, REG_ECPU_CONTROL, &cpu_ctrl); + if (ret < 0) + goto out; /* 10.5.1 run the firmware (II) */ cpu_ctrl |= flag; wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); + +out: + return ret; } static int wlcore_boot_parse_fw_ver(struct wl1271 *wl, @@ -368,9 +374,13 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) /* Make sure we have the boot partition */ wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); + ret = wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); + if (ret < 0) + return ret; - chip_id = wlcore_read_reg(wl, REG_CHIP_ID_B); + ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &chip_id); + if (ret < 0) + return ret; wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); @@ -383,7 +393,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) loop = 0; while (loop++ < INIT_LOOP) { udelay(INIT_LOOP_DELAY); - intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR); + ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); + if (ret < 0) + return ret; if (intr == 0xffffffff) { wl1271_error("error reading hardware complete " @@ -405,12 +417,17 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) } /* get hardware config command mail box */ - wl->cmd_box_addr = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR); + ret = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR, &wl->cmd_box_addr); + if (ret < 0) + return ret; wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x", wl->cmd_box_addr); /* get hardware config event mail box */ - wl->mbox_ptr[0] = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR); + ret = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR, &wl->mbox_ptr[0]); + if (ret < 0) + return ret; + wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 658dccbfd7ed..f2ac982a5cf5 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -79,7 +79,10 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); - intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR); + ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); + if (ret < 0) + goto fail; + while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { if (time_after(jiffies, timeout)) { wl1271_error("command complete timeout"); @@ -93,7 +96,9 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, else msleep(1); - intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR); + ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); + if (ret < 0) + goto fail; } /* read back the status code of the command */ diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 2cbf7623ddbb..0395b030a4d6 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -77,12 +77,19 @@ static inline int wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf, return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); } -static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) +static inline int wlcore_raw_read32(struct wl1271 *wl, int addr, u32 *val) { - wlcore_raw_read(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); + int ret; + + ret = wlcore_raw_read(wl, addr, &wl->buffer_32, + sizeof(wl->buffer_32), false); + if (ret < 0) + return ret; + + if (val) + *val = le32_to_cpu(wl->buffer_32); - return le32_to_cpu(wl->buffer_32); + return 0; } static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) @@ -138,9 +145,9 @@ static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, wlcore_raw_read(wl, physical, buf, len, fixed); } -static inline u32 wl1271_read32(struct wl1271 *wl, int addr) +static inline int wlcore_read32(struct wl1271 *wl, int addr, u32 *val) { - return wl1271_raw_read32(wl, wlcore_translate_addr(wl, addr)); + return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val); } static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) @@ -148,10 +155,11 @@ static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) wl1271_raw_write32(wl, wlcore_translate_addr(wl, addr), val); } -static inline u32 wlcore_read_reg(struct wl1271 *wl, int reg) +static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val) { - return wl1271_raw_read32(wl, - wlcore_translate_addr(wl, wl->rtable[reg])); + return wlcore_raw_read32(wl, + wlcore_translate_addr(wl, wl->rtable[reg]), + val); } static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0461d4eecfd2..c16d266ea6a2 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -872,6 +872,32 @@ out: kfree(block); } +static void wlcore_print_recovery(struct wl1271 *wl) +{ + u32 pc = 0; + u32 hint_sts = 0; + int ret; + + wl1271_info("Hardware recovery in progress. FW ver: %s", + wl->chip.fw_ver_str); + + /* change partitions momentarily so we can read the FW pc */ + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + + ret = wlcore_read_reg(wl, REG_PC_ON_RECOVERY, &pc); + if (ret < 0) + return; + + ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &hint_sts); + if (ret < 0) + return; + + wl1271_info("pc: 0x%x, hint_sts: 0x%08x", pc, hint_sts); + + wlcore_set_partition(wl, &wl->ptable[PART_WORK]); +} + + static void wl1271_recovery_work(struct work_struct *work) { struct wl1271 *wl = @@ -886,14 +912,7 @@ static void wl1271_recovery_work(struct work_struct *work) wl12xx_read_fwlog_panic(wl); - /* change partitions momentarily so we can read the FW pc */ - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x " - "hint_sts: 0x%08x", - wl->chip.fw_ver_str, - wlcore_read_reg(wl, REG_PC_ON_RECOVERY), - wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR)); - wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + wlcore_print_recovery(wl); BUG_ON(bug_on_recovery && !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); @@ -4979,18 +4998,22 @@ static int wl12xx_get_hw_info(struct wl1271 *wl) if (ret < 0) goto out; - wl->chip.id = wlcore_read_reg(wl, REG_CHIP_ID_B); + ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id); + if (ret < 0) + goto out; wl->fuse_oui_addr = 0; wl->fuse_nic_addr = 0; - wl->hw_pg_ver = wl->ops->get_pg_ver(wl); + ret = wl->ops->get_pg_ver(wl, &wl->hw_pg_ver); + if (ret < 0) + goto out; if (wl->ops->get_mac) - wl->ops->get_mac(wl); + ret = wl->ops->get_mac(wl); - wl1271_power_off(wl); out: + wl1271_power_off(wl); return ret; } diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 5d51647e6154..2fb537478ba4 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -62,8 +62,8 @@ struct wlcore_ops { int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif); u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl, struct wl12xx_vif *wlvif); - s8 (*get_pg_ver)(struct wl1271 *wl); - void (*get_mac)(struct wl1271 *wl); + int (*get_pg_ver)(struct wl1271 *wl, s8 *ver); + int (*get_mac)(struct wl1271 *wl); void (*set_tx_desc_csum)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, struct sk_buff *skb); -- GitLab From b0f0ad39e3d2716fe9ca6e50ce4cda87eb409ee0 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Wed, 20 Jun 2012 00:48:23 +0300 Subject: [PATCH 2437/6849] wlcore: Propagate errors from wl1271_raw_write32 Propagate errors from wl1271_raw_write32 and request for recovery when appropriate. Also rename prefixes of wlcore functions which their prototypes had to be changed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 160 +++++++++++++++++------- drivers/net/wireless/ti/wl18xx/io.c | 4 +- drivers/net/wireless/ti/wl18xx/main.c | 86 +++++++++---- drivers/net/wireless/ti/wlcore/boot.c | 32 +++-- drivers/net/wireless/ti/wlcore/cmd.c | 6 +- drivers/net/wireless/ti/wlcore/event.c | 4 +- drivers/net/wireless/ti/wlcore/io.c | 49 +++++--- drivers/net/wireless/ti/wlcore/io.h | 22 ++-- drivers/net/wireless/ti/wlcore/main.c | 20 ++- drivers/net/wireless/ti/wlcore/ps.c | 14 ++- drivers/net/wireless/ti/wlcore/rx.c | 9 +- drivers/net/wireless/ti/wlcore/tx.c | 17 ++- drivers/net/wireless/ti/wlcore/wlcore.h | 2 +- 13 files changed, 298 insertions(+), 127 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index ab486f71eee4..3a4ab65db0ec 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -688,17 +688,28 @@ out: return ret; } -static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) +static int wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) { + int ret; + /* write address >> 1 + 0x30000 to OCP_POR_CTR */ addr = (addr >> 1) + 0x30000; - wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr); + ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr); + if (ret < 0) + goto out; /* write value to OCP_POR_WDATA */ - wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val); + ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val); + if (ret < 0) + goto out; /* write 1 to OCP_CMD */ - wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE); + ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE); + if (ret < 0) + goto out; + +out: + return ret; } static int wl12xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) @@ -709,10 +720,14 @@ static int wl12xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) /* write address >> 1 + 0x30000 to OCP_POR_CTR */ addr = (addr >> 1) + 0x30000; - wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr); + ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr); + if (ret < 0) + return ret; /* write 2 to OCP_CMD */ - wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ); + ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ); + if (ret < 0) + return ret; /* poll for data ready */ do { @@ -751,11 +766,15 @@ static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) if (spare_reg == 0xFFFF) return -EFAULT; spare_reg |= (BIT(3) | BIT(5) | BIT(6)); - wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); + ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); + if (ret < 0) + return ret; /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */ - wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG, - WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); + ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG, + WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); + if (ret < 0) + return ret; /* Delay execution for 15msec, to let the HW settle */ mdelay(15); @@ -795,11 +814,21 @@ static bool wl128x_is_fref_valid(struct wl1271 *wl) static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl) { - wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); - wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); - wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL); + int ret; - return 0; + ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); + if (ret < 0) + goto out; + + ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); + if (ret < 0) + goto out; + + ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, + MCS_PLL_CONFIG_REG_VAL); + +out: + return ret; } static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) @@ -818,7 +847,9 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) if (spare_reg == 0xFFFF) return -EFAULT; spare_reg |= BIT(2); - wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); + ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); + if (ret < 0) + return ret; /* Handle special cases of the TCXO clock */ if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || @@ -836,9 +867,9 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) return -EFAULT; pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT); pll_config |= MCS_PLL_ENABLE_HP; - wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config); + ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config); - return 0; + return ret; } /* @@ -927,7 +958,9 @@ static int wl127x_boot_clk(struct wl1271 *wl) goto out; val &= FREF_CLK_TYPE_BITS; - wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val); + ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val); + if (ret < 0) + goto out; /* Set clock pull mode (no pull) */ ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val); @@ -935,7 +968,9 @@ static int wl127x_boot_clk(struct wl1271 *wl) goto out; val |= NO_PULL; - wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val); + ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val); + if (ret < 0) + goto out; } else { u16 val; /* Set clock polarity */ @@ -945,10 +980,14 @@ static int wl127x_boot_clk(struct wl1271 *wl) val &= FREF_CLK_POLARITY_BITS; val |= CLK_REQ_OUTN_SEL; - wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); + ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); + if (ret < 0) + goto out; } - wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk); + ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk); + if (ret < 0) + goto out; ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause); if (ret < 0) @@ -958,7 +997,7 @@ static int wl127x_boot_clk(struct wl1271 *wl) pause &= ~(WU_COUNTER_PAUSE_VAL); pause |= WU_COUNTER_PAUSE_VAL; - wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause); + ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause); out: return ret; @@ -971,7 +1010,9 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) int ret = 0; /* perform soft reset */ - wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); + ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); + if (ret < 0) + goto out; /* SOFT_RESET is self clearing */ timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); @@ -995,10 +1036,12 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) } /* disable Rx/Tx */ - wl1271_write32(wl, WL12XX_ENABLE, 0x0); + ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0); + if (ret < 0) + goto out; /* disable auto calibration on start*/ - wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff); + ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff); out: return ret; @@ -1022,10 +1065,15 @@ static int wl12xx_pre_boot(struct wl1271 *wl) } /* Continue the ELP wake up sequence */ - wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + if (ret < 0) + goto out; + udelay(500); - wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); + if (ret < 0) + goto out; /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW. The RTRIM value will be added by the FW @@ -1042,12 +1090,18 @@ static int wl12xx_pre_boot(struct wl1271 *wl) else clk |= (priv->ref_clock << 1) << 4; - wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); + ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); + if (ret < 0) + goto out; - wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + if (ret < 0) + goto out; /* Disable interrupts */ - wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); + ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); + if (ret < 0) + goto out; ret = wl1271_boot_soft_reset(wl); if (ret < 0) @@ -1067,7 +1121,9 @@ static int wl12xx_pre_upload(struct wl1271 *wl) * ACX_EEPROMLESS_IND_REG */ wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); - wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND); + ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND); + if (ret < 0) + goto out; ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); if (ret < 0) @@ -1083,8 +1139,11 @@ static int wl12xx_pre_upload(struct wl1271 *wl) /* WL1271: The reference driver skips steps 7 to 10 (jumps directly * to upload_fw) */ - if (wl->chip.id == CHIP_ID_1283_PG20) - wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); + if (wl->chip.id == CHIP_ID_1283_PG20) { + ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); + if (ret < 0) + goto out; + } /* polarity must be set before the firmware is loaded */ ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity); @@ -1093,21 +1152,31 @@ static int wl12xx_pre_upload(struct wl1271 *wl) /* We use HIGH polarity, so unset the LOW bit */ polarity &= ~POLARITY_LOW; - wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); + ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); out: return ret; } -static void wl12xx_enable_interrupts(struct wl1271 *wl) +static int wl12xx_enable_interrupts(struct wl1271 *wl) { - wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL12XX_ACX_ALL_EVENTS_VECTOR); + int ret; + + ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, + WL12XX_ACX_ALL_EVENTS_VECTOR); + if (ret < 0) + goto out; wlcore_enable_interrupts(wl); - wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); + ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, + WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); + if (ret < 0) + goto out; + + ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); - wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); +out: + return ret; } static int wl12xx_boot(struct wl1271 *wl) @@ -1134,7 +1203,7 @@ static int wl12xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - wl12xx_enable_interrupts(wl); + ret = wl12xx_enable_interrupts(wl); out: return ret; @@ -1149,14 +1218,15 @@ static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, if (ret < 0) return ret; - wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD); + ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD); return ret; } -static void wl12xx_ack_event(struct wl1271 *wl) +static int wl12xx_ack_event(struct wl1271 *wl) { - wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK); + return wlcore_write_reg(wl, REG_INTERRUPT_TRIG, + WL12XX_INTR_TRIG_EVENT_ACK); } static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) @@ -1348,7 +1418,9 @@ static int wl12xx_get_fuse_mac(struct wl1271 *wl) u32 mac1, mac2; int ret; - wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); + if (ret < 0) + goto out; ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1); if (ret < 0) @@ -1363,7 +1435,7 @@ static int wl12xx_get_fuse_mac(struct wl1271 *wl) ((mac1 & 0xff000000) >> 24); wl->fuse_nic_addr = mac1 & 0xffffff; - wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); out: return ret; diff --git a/drivers/net/wireless/ti/wl18xx/io.c b/drivers/net/wireless/ti/wl18xx/io.c index 92c2c03e4cd8..0c06ccfd1b8c 100644 --- a/drivers/net/wireless/ti/wl18xx/io.c +++ b/drivers/net/wireless/ti/wl18xx/io.c @@ -38,14 +38,14 @@ int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) goto out; tmp = (tmp & 0xffff0000) | val; - wl1271_write32(wl, addr, tmp); + ret = wlcore_write32(wl, addr, tmp); } else { ret = wlcore_read32(wl, addr - 2, &tmp); if (ret < 0) goto out; tmp = (tmp & 0xffff) | (val << 16); - wl1271_write32(wl, addr - 2, tmp); + ret = wlcore_write32(wl, addr - 2, tmp); } out: diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index f99f003ab182..c25b960faa29 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -641,7 +641,9 @@ static int wl18xx_set_clk(struct wl1271 *wl) u16 clk_freq; int ret; - wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + if (ret < 0) + goto out; /* TODO: PG2: apparently we need to read the clk type */ @@ -699,13 +701,20 @@ out: return ret; } -static void wl18xx_boot_soft_reset(struct wl1271 *wl) +static int wl18xx_boot_soft_reset(struct wl1271 *wl) { + int ret; + /* disable Rx/Tx */ - wl1271_write32(wl, WL18XX_ENABLE, 0x0); + ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0); + if (ret < 0) + goto out; /* disable auto calibration on start*/ - wl1271_write32(wl, WL18XX_SPARE_A2, 0xffff); + ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff); + +out: + return ret; } static int wl18xx_pre_boot(struct wl1271 *wl) @@ -717,15 +726,22 @@ static int wl18xx_pre_boot(struct wl1271 *wl) goto out; /* Continue the ELP wake up sequence */ - wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + if (ret < 0) + goto out; + udelay(500); - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + if (ret < 0) + goto out; /* Disable interrupts */ - wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); + ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); + if (ret < 0) + goto out; - wl18xx_boot_soft_reset(wl); + ret = wl18xx_boot_soft_reset(wl); out: return ret; @@ -736,10 +752,14 @@ static int wl18xx_pre_upload(struct wl1271 *wl) u32 tmp; int ret; - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + if (ret < 0) + goto out; /* TODO: check if this is all needed */ - wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); + ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); + if (ret < 0) + goto out; ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); if (ret < 0) @@ -765,16 +785,21 @@ static int wl18xx_set_mac_and_phy(struct wl1271 *wl) else len = sizeof(struct wl18xx_mac_and_phy_params); - wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); + if (ret < 0) + goto out; + ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, len, false); +out: return ret; } -static void wl18xx_enable_interrupts(struct wl1271 *wl) +static int wl18xx_enable_interrupts(struct wl1271 *wl) { u32 event_mask, intr_mask; + int ret; if (wl->chip.id == CHIP_ID_185x_PG10) { event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1; @@ -784,11 +809,17 @@ static void wl18xx_enable_interrupts(struct wl1271 *wl) intr_mask = WL18XX_INTR_MASK_PG2; } - wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); + ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); + if (ret < 0) + goto out; wlcore_enable_interrupts(wl); - wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~intr_mask); + + ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, + WL1271_ACX_INTR_ALL & ~intr_mask); + +out: + return ret; } static int wl18xx_boot(struct wl1271 *wl) @@ -815,7 +846,7 @@ static int wl18xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - wl18xx_enable_interrupts(wl); + ret = wl18xx_enable_interrupts(wl); out: return ret; @@ -833,9 +864,10 @@ static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, WL18XX_CMD_MAX_SIZE, false); } -static void wl18xx_ack_event(struct wl1271 *wl) +static int wl18xx_ack_event(struct wl1271 *wl) { - wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK); + return wlcore_write_reg(wl, REG_INTERRUPT_TRIG, + WL18XX_INTR_TRIG_EVENT_ACK); } static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) @@ -1038,7 +1070,9 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) u32 fuse; int ret; - wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + if (ret < 0) + goto out; ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse); if (ret < 0) @@ -1047,7 +1081,7 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) if (ver) *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); out: return ret; @@ -1116,7 +1150,11 @@ out: static int wl18xx_plt_init(struct wl1271 *wl) { - wl1271_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); + int ret; + + ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); + if (ret < 0) + return ret; return wl->ops->boot(wl); } @@ -1126,7 +1164,9 @@ static int wl18xx_get_mac(struct wl1271 *wl) u32 mac1, mac2; int ret; - wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + if (ret < 0) + goto out; ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1); if (ret < 0) @@ -1141,7 +1181,7 @@ static int wl18xx_get_mac(struct wl1271 *wl) ((mac1 & 0xff000000) >> 24); wl->fuse_nic_addr = (mac1 & 0xffffff); - wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); out: return ret; diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 0aa0e29b8d98..8965960b841a 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c @@ -45,7 +45,7 @@ static int wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) /* 10.5.1 run the firmware (II) */ cpu_ctrl |= flag; - wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); + ret = wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); out: return ret; @@ -139,7 +139,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition)); partition.mem.start = dest; - wlcore_set_partition(wl, &partition); + ret = wlcore_set_partition(wl, &partition); + if (ret < 0) + return ret; /* 10.1 set partition limit and chunk num */ chunk_num = 0; @@ -153,7 +155,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, partition_limit = chunk_num * CHUNK_SIZE + wl->ptable[PART_DOWN].mem.size; partition.mem.start = addr; - wlcore_set_partition(wl, &partition); + ret = wlcore_set_partition(wl, &partition); + if (ret < 0) + return ret; } /* 10.3 upload the chunk */ @@ -320,7 +324,9 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "nvs burst write 0x%x: 0x%x", dest_addr, val); - wl1271_write32(wl, dest_addr, val); + ret = wlcore_write32(wl, dest_addr, val); + if (ret < 0) + return ret; nvs_ptr += 4; dest_addr += 4; @@ -346,7 +352,9 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) nvs_len -= nvs_ptr - (u8 *)wl->nvs; /* Now we must set the partition correctly */ - wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + if (ret < 0) + return ret; /* Copy the NVS tables to a new block to ensure alignment */ nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); @@ -372,7 +380,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) u32 chip_id, intr; /* Make sure we have the boot partition */ - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + if (ret < 0) + return ret; ret = wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); if (ret < 0) @@ -404,8 +414,10 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) } /* check that ACX_INTR_INIT_COMPLETE is enabled */ else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { - wlcore_write_reg(wl, REG_INTERRUPT_ACK, - WL1271_ACX_INTR_INIT_COMPLETE); + ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK, + WL1271_ACX_INTR_INIT_COMPLETE); + if (ret < 0) + return ret; break; } } @@ -469,9 +481,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) } /* set the working partition to its "running" mode offset */ - wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]); /* firmware startup completed */ - return 0; + return ret; } EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware); diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index f2ac982a5cf5..84dd808f65fa 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -116,7 +116,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, goto fail; } - wlcore_write_reg(wl, REG_INTERRUPT_ACK, WL1271_ACX_INTR_CMD_COMPLETE); + ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK, + WL1271_ACX_INTR_CMD_COMPLETE); + if (ret < 0) + goto fail; + return 0; fail: diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 123d26d17ba4..48907054d493 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -318,7 +318,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) * TODO: we just need this because one bit is in a different * place. Is there any better way? */ - wl->ops->ack_event(wl); + ret = wl->ops->ack_event(wl); - return 0; + return ret; } diff --git a/drivers/net/wireless/ti/wlcore/io.c b/drivers/net/wireless/ti/wlcore/io.c index 62d657389996..9976219c4e49 100644 --- a/drivers/net/wireless/ti/wlcore/io.c +++ b/drivers/net/wireless/ti/wlcore/io.c @@ -128,9 +128,11 @@ EXPORT_SYMBOL_GPL(wlcore_translate_addr); * | | * */ -void wlcore_set_partition(struct wl1271 *wl, - const struct wlcore_partition_set *p) +int wlcore_set_partition(struct wl1271 *wl, + const struct wlcore_partition_set *p) { + int ret; + /* copy partition info */ memcpy(&wl->curr_part, p, sizeof(*p)); @@ -143,28 +145,41 @@ void wlcore_set_partition(struct wl1271 *wl, wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X", p->mem3.start, p->mem3.size); - wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); - wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); - wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); - wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); - wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); - wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); + ret = wlcore_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); + if (ret < 0) + goto out; + + ret = wlcore_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); + if (ret < 0) + goto out; + + ret = wlcore_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); + if (ret < 0) + goto out; + + ret = wlcore_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); + if (ret < 0) + goto out; + + ret = wlcore_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); + if (ret < 0) + goto out; + + ret = wlcore_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); + if (ret < 0) + goto out; + /* * We don't need the size of the last partition, as it is * automatically calculated based on the total memory size and * the sizes of the previous partitions. */ - wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); -} -EXPORT_SYMBOL_GPL(wlcore_set_partition); + ret = wlcore_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); -void wlcore_select_partition(struct wl1271 *wl, u8 part) -{ - wl1271_debug(DEBUG_IO, "setting partition %d", part); - - wlcore_set_partition(wl, &wl->ptable[part]); +out: + return ret; } -EXPORT_SYMBOL_GPL(wlcore_select_partition); +EXPORT_SYMBOL_GPL(wlcore_set_partition); void wl1271_io_reset(struct wl1271 *wl) { diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 0395b030a4d6..5e4a3d174004 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -92,11 +92,11 @@ static inline int wlcore_raw_read32(struct wl1271 *wl, int addr, u32 *val) return 0; } -static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) +static inline int wlcore_raw_write32(struct wl1271 *wl, int addr, u32 val) { wl->buffer_32 = cpu_to_le32(val); - wlcore_raw_write(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); + return wlcore_raw_write(wl, addr, &wl->buffer_32, + sizeof(wl->buffer_32), false); } static inline int wlcore_read(struct wl1271 *wl, int addr, void *buf, @@ -150,9 +150,9 @@ static inline int wlcore_read32(struct wl1271 *wl, int addr, u32 *val) return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val); } -static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) +static inline int wlcore_write32(struct wl1271 *wl, int addr, u32 val) { - wl1271_raw_write32(wl, wlcore_translate_addr(wl, addr), val); + return wlcore_raw_write32(wl, wlcore_translate_addr(wl, addr), val); } static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val) @@ -162,9 +162,11 @@ static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val) val); } -static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) +static inline int wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) { - wl1271_raw_write32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), val); + return wlcore_raw_write32(wl, + wlcore_translate_addr(wl, wl->rtable[reg]), + val); } static inline void wl1271_power_off(struct wl1271 *wl) @@ -188,8 +190,8 @@ static inline int wl1271_power_on(struct wl1271 *wl) return ret; } -void wlcore_set_partition(struct wl1271 *wl, - const struct wlcore_partition_set *p); +int wlcore_set_partition(struct wl1271 *wl, + const struct wlcore_partition_set *p); bool wl1271_set_block_size(struct wl1271 *wl); @@ -197,6 +199,4 @@ bool wl1271_set_block_size(struct wl1271 *wl); int wl1271_tx_dummy_packet(struct wl1271 *wl); -void wlcore_select_partition(struct wl1271 *wl, u8 part); - #endif diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index c16d266ea6a2..546fcb074c6e 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -882,7 +882,9 @@ static void wlcore_print_recovery(struct wl1271 *wl) wl->chip.fw_ver_str); /* change partitions momentarily so we can read the FW pc */ - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + if (ret < 0) + return; ret = wlcore_read_reg(wl, REG_PC_ON_RECOVERY, &pc); if (ret < 0) @@ -967,9 +969,9 @@ out_unlock: mutex_unlock(&wl->mutex); } -static void wl1271_fw_wakeup(struct wl1271 *wl) +static int wlcore_fw_wakeup(struct wl1271 *wl) { - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); + return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); } static int wl1271_setup(struct wl1271 *wl) @@ -1005,13 +1007,21 @@ static int wl12xx_set_power_on(struct wl1271 *wl) wl1271_io_reset(wl); wl1271_io_init(wl); - wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + if (ret < 0) + goto fail; /* ELP module wake up */ - wl1271_fw_wakeup(wl); + ret = wlcore_fw_wakeup(wl); + if (ret < 0) + goto fail; out: return ret; + +fail: + wl1271_power_off(wl); + return ret; } static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c index 95d8797cfa28..46d36fd30eba 100644 --- a/drivers/net/wireless/ti/wlcore/ps.c +++ b/drivers/net/wireless/ti/wlcore/ps.c @@ -35,6 +35,7 @@ void wl1271_elp_work(struct work_struct *work) struct delayed_work *dwork; struct wl1271 *wl; struct wl12xx_vif *wlvif; + int ret; dwork = container_of(work, struct delayed_work, work); wl = container_of(dwork, struct wl1271, elp_work); @@ -63,7 +64,12 @@ void wl1271_elp_work(struct work_struct *work) } wl1271_debug(DEBUG_PSM, "chip to elp"); - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP); + ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto out; + } + set_bit(WL1271_FLAG_IN_ELP, &wl->flags); out: @@ -135,7 +141,11 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl) wl->elp_compl = &compl; spin_unlock_irqrestore(&wl->wl_lock, flags); - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); + ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); + if (ret < 0) { + wl12xx_queue_recovery_work(wl); + goto err; + } if (!pending) { ret = wait_for_completion_timeout( diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index be24b3030f92..f42b969c1de9 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -279,9 +279,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) * Write the driver's packet counter to the FW. This is only required * for older hardware revisions */ - if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) - wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER, - wl->rx_counter); + if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) { + ret = wlcore_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER, + wl->rx_counter); + if (ret < 0) + goto out; + } wl12xx_rearm_rx_streaming(wl, active_hlids); diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 90bddf56f8ed..b5211be229d9 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -746,9 +746,12 @@ out_ack: * Interrupt the firmware with the new packets. This is only * required for older hardware revisions */ - if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) - wl1271_write32(wl, WL12XX_HOST_WR_ACCESS, - wl->tx_packets_count); + if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) { + ret = wlcore_write32(wl, WL12XX_HOST_WR_ACCESS, + wl->tx_packets_count); + if (ret < 0) + goto out; + } wl1271_handle_tx_low_watermark(wl); } @@ -911,9 +914,11 @@ int wlcore_tx_complete(struct wl1271 *wl) fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); /* write host counter to chipset (to ack) */ - wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + - offsetof(struct wl1271_tx_hw_res_if, - tx_result_host_counter), fw_counter); + ret = wlcore_write32(wl, le32_to_cpu(memmap->tx_result) + + offsetof(struct wl1271_tx_hw_res_if, + tx_result_host_counter), fw_counter); + if (ret < 0) + goto out; count = fw_counter - wl->tx_results_count; wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 2fb537478ba4..e796974df59b 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -43,7 +43,7 @@ struct wlcore_ops { int (*plt_init)(struct wl1271 *wl); int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, void *buf, size_t len); - void (*ack_event)(struct wl1271 *wl); + int (*ack_event)(struct wl1271 *wl); u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks); void (*set_tx_desc_blocks)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, -- GitLab From 2b80040782af56e1b13ad451f593dd4e1875b2b8 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 18 Jun 2012 18:15:50 +0300 Subject: [PATCH 2438/6849] wlcore: Propagate errors from wl1271_read_hwaddr Propagate errors from wl1271_read_hwaddr. This function is only used when reading the FW log (following a recovery), so don't read the FW log in case of a bus error. Also rename prefixes of wlcore functions which their prototypes had to be changed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/io.h | 4 ++-- drivers/net/wireless/ti/wlcore/main.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 5e4a3d174004..4a6688b03aea 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -131,7 +131,7 @@ static inline int wlcore_read_data(struct wl1271 *wl, int reg, void *buf, return wlcore_read(wl, wl->rtable[reg], buf, len, fixed); } -static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, +static inline int wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, void *buf, size_t len, bool fixed) { int physical; @@ -142,7 +142,7 @@ static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, physical = wlcore_translate_addr(wl, addr); - wlcore_raw_read(wl, physical, buf, len, fixed); + return wlcore_raw_read(wl, physical, buf, len, fixed); } static inline int wlcore_read32(struct wl1271 *wl, int addr, u32 *val) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 546fcb074c6e..b0795aac4bac 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -851,8 +851,10 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) /* Traverse the memory blocks linked list */ do { memset(block, 0, WL12XX_HW_BLOCK_SIZE); - wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, - false); + ret = wlcore_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, + false); + if (ret < 0) + goto out; /* * Memory blocks are linked to one another. The first 4 bytes -- GitLab From f1a26e638e646d971f77c5a5186ee254b3f4e818 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Wed, 20 Jun 2012 00:03:46 +0300 Subject: [PATCH 2439/6849] wlcore: Force checking of io functions' return values All io functions' return values should be propagated and handled. Add a __must_check annotation to verify that the return values are checked and to avoid future mistakes. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl12xx/main.c | 6 ++- drivers/net/wireless/ti/wl18xx/io.h | 4 +- drivers/net/wireless/ti/wlcore/io.h | 61 ++++++++++++++--------- drivers/net/wireless/ti/wlcore/sdio.c | 8 +-- drivers/net/wireless/ti/wlcore/spi.c | 8 +-- drivers/net/wireless/ti/wlcore/wlcore_i.h | 8 +-- 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 3a4ab65db0ec..47ba2e0017f4 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -688,7 +688,8 @@ out: return ret; } -static int wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) +static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr, + u16 val) { int ret; @@ -712,7 +713,8 @@ out: return ret; } -static int wl12xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) +static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr, + u16 *out) { u32 val; int timeout = OCP_CMD_LOOP; diff --git a/drivers/net/wireless/ti/wl18xx/io.h b/drivers/net/wireless/ti/wl18xx/io.h index 0e1b8d28edb2..c32ae30277df 100644 --- a/drivers/net/wireless/ti/wl18xx/io.h +++ b/drivers/net/wireless/ti/wl18xx/io.h @@ -22,7 +22,7 @@ #ifndef __WL18XX_IO_H__ #define __WL18XX_IO_H__ -int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); -int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out); +int __must_check wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); +int __must_check wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out); #endif /* __WL18XX_IO_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 4a6688b03aea..1cd545b0ed1e 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -53,31 +53,36 @@ void wl1271_io_init(struct wl1271 *wl); int wlcore_translate_addr(struct wl1271 *wl, int addr); /* Raw target IO, address is not translated */ -static inline int wlcore_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr, + void *buf, size_t len, + bool fixed) { return wl->if_ops->write(wl->dev, addr, buf, len, fixed); } -static inline int wlcore_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr, + void *buf, size_t len, + bool fixed) { return wl->if_ops->read(wl->dev, addr, buf, len, fixed); } -static inline int wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_raw_read_data(struct wl1271 *wl, int reg, + void *buf, size_t len, + bool fixed) { return wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed); } -static inline int wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_raw_write_data(struct wl1271 *wl, int reg, + void *buf, size_t len, + bool fixed) { return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); } -static inline int wlcore_raw_read32(struct wl1271 *wl, int addr, u32 *val) +static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr, + u32 *val) { int ret; @@ -92,15 +97,16 @@ static inline int wlcore_raw_read32(struct wl1271 *wl, int addr, u32 *val) return 0; } -static inline int wlcore_raw_write32(struct wl1271 *wl, int addr, u32 val) +static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr, + u32 val) { wl->buffer_32 = cpu_to_le32(val); return wlcore_raw_write(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32), false); } -static inline int wlcore_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_read(struct wl1271 *wl, int addr, + void *buf, size_t len, bool fixed) { int physical; @@ -109,8 +115,8 @@ static inline int wlcore_read(struct wl1271 *wl, int addr, void *buf, return wlcore_raw_read(wl, physical, buf, len, fixed); } -static inline int wlcore_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_write(struct wl1271 *wl, int addr, + void *buf, size_t len, bool fixed) { int physical; @@ -119,20 +125,23 @@ static inline int wlcore_write(struct wl1271 *wl, int addr, void *buf, return wlcore_raw_write(wl, physical, buf, len, fixed); } -static inline int wlcore_write_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_write_data(struct wl1271 *wl, int reg, + void *buf, size_t len, + bool fixed) { return wlcore_write(wl, wl->rtable[reg], buf, len, fixed); } -static inline int wlcore_read_data(struct wl1271 *wl, int reg, void *buf, - size_t len, bool fixed) +static inline int __must_check wlcore_read_data(struct wl1271 *wl, int reg, + void *buf, size_t len, + bool fixed) { return wlcore_read(wl, wl->rtable[reg], buf, len, fixed); } -static inline int wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, - void *buf, size_t len, bool fixed) +static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, + void *buf, size_t len, + bool fixed) { int physical; int addr; @@ -145,24 +154,28 @@ static inline int wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, return wlcore_raw_read(wl, physical, buf, len, fixed); } -static inline int wlcore_read32(struct wl1271 *wl, int addr, u32 *val) +static inline int __must_check wlcore_read32(struct wl1271 *wl, int addr, + u32 *val) { return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val); } -static inline int wlcore_write32(struct wl1271 *wl, int addr, u32 val) +static inline int __must_check wlcore_write32(struct wl1271 *wl, int addr, + u32 val) { return wlcore_raw_write32(wl, wlcore_translate_addr(wl, addr), val); } -static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val) +static inline int __must_check wlcore_read_reg(struct wl1271 *wl, int reg, + u32 *val) { return wlcore_raw_read32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), val); } -static inline int wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) +static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg, + u32 val) { return wlcore_raw_write32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 9069dc93b1bc..204e69fa9327 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -71,8 +71,8 @@ static void wl1271_sdio_set_block_size(struct device *child, sdio_release_host(func); } -static int wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, + void *buf, size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); @@ -109,8 +109,8 @@ static int wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, return ret; } -static int wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr, + void *buf, size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index d6768e9d7dab..6420abae40ee 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c @@ -193,8 +193,8 @@ static int wl12xx_spi_read_busy(struct device *child) return -ETIMEDOUT; } -static int wl12xx_spi_raw_read(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int __must_check wl12xx_spi_raw_read(struct device *child, int addr, + void *buf, size_t len, bool fixed) { struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); struct wl1271 *wl = dev_get_drvdata(child); @@ -260,8 +260,8 @@ static int wl12xx_spi_raw_read(struct device *child, int addr, void *buf, return 0; } -static int wl12xx_spi_raw_write(struct device *child, int addr, void *buf, - size_t len, bool fixed) +static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, + void *buf, size_t len, bool fixed) { struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 5ab31ff4080e..e5a34dd34baf 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -209,10 +209,10 @@ struct wl1271_scan { }; struct wl1271_if_operations { - int (*read)(struct device *child, int addr, void *buf, size_t len, - bool fixed); - int (*write)(struct device *child, int addr, void *buf, size_t len, - bool fixed); + int __must_check (*read)(struct device *child, int addr, void *buf, + size_t len, bool fixed); + int __must_check (*write)(struct device *child, int addr, void *buf, + size_t len, bool fixed); void (*reset)(struct device *child); void (*init)(struct device *child); int (*power)(struct device *child, bool enable); -- GitLab From f6442aa0b503f944907b869659dd27756c809488 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 21 Jun 2012 18:45:46 +0800 Subject: [PATCH 2440/6849] regulator: tps65910: Remove unused min_uV and max_uV from struct tps_info The min_uV and max_uV fields of struct tps_info are not used in the code. For the case voltage_table is provided, the min_uV and max_uV are the same values as volt_table[0] and volt_table[n_voltages -1]. For the case voltage_table is not available, having the min_uV and max_uV seems misleading. Current code uses equations to get the voltage value in this case, but these equations do not use the min_uV and max_uV fields of struct tps_info. Thus this patch removes the min_uV and max_uV fields from struct tps_info. Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 50 -------------------------- 1 file changed, 50 deletions(-) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 373c529b379d..edeaa2c770b9 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -85,8 +85,6 @@ static const u16 VMMC_VSEL_table[] = { struct tps_info { const char *name; - unsigned min_uV; - unsigned max_uV; u8 n_voltages; const u16 *voltage_table; int enable_time_us; @@ -99,92 +97,68 @@ static struct tps_info tps65910_regs[] = { }, { .name = "vio", - .min_uV = 1500000, - .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, .enable_time_us = 350, }, { .name = "vdd1", - .min_uV = 600000, - .max_uV = 4500000, .enable_time_us = 350, }, { .name = "vdd2", - .min_uV = 600000, - .max_uV = 4500000, .enable_time_us = 350, }, { .name = "vdd3", - .min_uV = 5000000, - .max_uV = 5000000, .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), .voltage_table = VDD3_VSEL_table, .enable_time_us = 200, }, { .name = "vdig1", - .min_uV = 1200000, - .max_uV = 2700000, .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), .voltage_table = VDIG1_VSEL_table, .enable_time_us = 100, }, { .name = "vdig2", - .min_uV = 1000000, - .max_uV = 1800000, .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), .voltage_table = VDIG2_VSEL_table, .enable_time_us = 100, }, { .name = "vpll", - .min_uV = 1000000, - .max_uV = 2500000, .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), .voltage_table = VPLL_VSEL_table, .enable_time_us = 100, }, { .name = "vdac", - .min_uV = 1800000, - .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), .voltage_table = VDAC_VSEL_table, .enable_time_us = 100, }, { .name = "vaux1", - .min_uV = 1800000, - .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), .voltage_table = VAUX1_VSEL_table, .enable_time_us = 100, }, { .name = "vaux2", - .min_uV = 1800000, - .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), .voltage_table = VAUX2_VSEL_table, .enable_time_us = 100, }, { .name = "vaux33", - .min_uV = 1800000, - .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), .voltage_table = VAUX33_VSEL_table, .enable_time_us = 100, }, { .name = "vmmc", - .min_uV = 1800000, - .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), .voltage_table = VMMC_VSEL_table, .enable_time_us = 100, @@ -198,86 +172,62 @@ static struct tps_info tps65911_regs[] = { }, { .name = "vio", - .min_uV = 1500000, - .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, .enable_time_us = 350, }, { .name = "vdd1", - .min_uV = 600000, - .max_uV = 4500000, .n_voltages = 73, .enable_time_us = 350, }, { .name = "vdd2", - .min_uV = 600000, - .max_uV = 4500000, .n_voltages = 73, .enable_time_us = 350, }, { .name = "vddctrl", - .min_uV = 600000, - .max_uV = 1400000, .n_voltages = 65, .enable_time_us = 900, }, { .name = "ldo1", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 47, .enable_time_us = 420, }, { .name = "ldo2", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 47, .enable_time_us = 420, }, { .name = "ldo3", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo4", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 47, .enable_time_us = 230, }, { .name = "ldo5", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo6", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo7", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { .name = "ldo8", - .min_uV = 1000000, - .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, -- GitLab From d9fe28f9621be70514aeacd2b4b3640e986d4cb1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 21 Jun 2012 18:48:00 +0800 Subject: [PATCH 2441/6849] regulator: tps65910: Convert to regulator_list_voltage_table Convert tps65910_ops and tps65910_ops_vdd3 to regulator_list_voltage_table. Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 94 +++++++++++--------------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index edeaa2c770b9..66da87cc0879 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -31,62 +31,62 @@ TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \ TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) -/* supported VIO voltages in millivolts */ -static const u16 VIO_VSEL_table[] = { - 1500, 1800, 2500, 3300, +/* supported VIO voltages in microvolts */ +static const unsigned int VIO_VSEL_table[] = { + 1500000, 1800000, 2500000, 3300000, }; /* VSEL tables for TPS65910 specific LDOs and dcdc's */ -/* supported VDD3 voltages in millivolts */ -static const u16 VDD3_VSEL_table[] = { - 5000, +/* supported VDD3 voltages in microvolts */ +static const unsigned int VDD3_VSEL_table[] = { + 5000000, }; -/* supported VDIG1 voltages in millivolts */ -static const u16 VDIG1_VSEL_table[] = { - 1200, 1500, 1800, 2700, +/* supported VDIG1 voltages in microvolts */ +static const unsigned int VDIG1_VSEL_table[] = { + 1200000, 1500000, 1800000, 2700000, }; -/* supported VDIG2 voltages in millivolts */ -static const u16 VDIG2_VSEL_table[] = { - 1000, 1100, 1200, 1800, +/* supported VDIG2 voltages in microvolts */ +static const unsigned int VDIG2_VSEL_table[] = { + 1000000, 1100000, 1200000, 1800000, }; -/* supported VPLL voltages in millivolts */ -static const u16 VPLL_VSEL_table[] = { - 1000, 1100, 1800, 2500, +/* supported VPLL voltages in microvolts */ +static const unsigned int VPLL_VSEL_table[] = { + 1000000, 1100000, 1800000, 2500000, }; -/* supported VDAC voltages in millivolts */ -static const u16 VDAC_VSEL_table[] = { - 1800, 2600, 2800, 2850, +/* supported VDAC voltages in microvolts */ +static const unsigned int VDAC_VSEL_table[] = { + 1800000, 2600000, 2800000, 2850000, }; -/* supported VAUX1 voltages in millivolts */ -static const u16 VAUX1_VSEL_table[] = { - 1800, 2500, 2800, 2850, +/* supported VAUX1 voltages in microvolts */ +static const unsigned int VAUX1_VSEL_table[] = { + 1800000, 2500000, 2800000, 2850000, }; -/* supported VAUX2 voltages in millivolts */ -static const u16 VAUX2_VSEL_table[] = { - 1800, 2800, 2900, 3300, +/* supported VAUX2 voltages in microvolts */ +static const unsigned int VAUX2_VSEL_table[] = { + 1800000, 2800000, 2900000, 3300000, }; -/* supported VAUX33 voltages in millivolts */ -static const u16 VAUX33_VSEL_table[] = { - 1800, 2000, 2800, 3300, +/* supported VAUX33 voltages in microvolts */ +static const unsigned int VAUX33_VSEL_table[] = { + 1800000, 2000000, 2800000, 3300000, }; -/* supported VMMC voltages in millivolts */ -static const u16 VMMC_VSEL_table[] = { - 1800, 2800, 3000, 3300, +/* supported VMMC voltages in microvolts */ +static const unsigned int VMMC_VSEL_table[] = { + 1800000, 2800000, 3000000, 3300000, }; struct tps_info { const char *name; u8 n_voltages; - const u16 *voltage_table; + const unsigned int *voltage_table; int enable_time_us; }; @@ -559,7 +559,7 @@ static int tps65910_get_voltage_sel(struct regulator_dev *dev) static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) { - return 5 * 1000 * 1000; + return dev->desc->volt_table[0]; } static int tps65911_get_voltage_sel(struct regulator_dev *dev) @@ -718,23 +718,6 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, return volt * 100 * mult; } -static int tps65910_list_voltage(struct regulator_dev *dev, - unsigned selector) -{ - struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev), voltage; - - if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) - return -EINVAL; - - if (selector >= pmic->info[id]->n_voltages) - return -EINVAL; - else - voltage = pmic->info[id]->voltage_table[selector] * 1000; - - return voltage; -} - static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); @@ -766,7 +749,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->voltage_table[selector] * 1000; + return pmic->info[id]->voltage_table[selector]; default: return -EINVAL; } @@ -796,7 +779,7 @@ static struct regulator_ops tps65910_ops_vdd3 = { .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage_vdd3, - .list_voltage = tps65910_list_voltage, + .list_voltage = regulator_list_voltage_table, }; static struct regulator_ops tps65910_ops = { @@ -808,7 +791,7 @@ static struct regulator_ops tps65910_ops = { .get_mode = tps65910_get_mode, .get_voltage_sel = tps65910_get_voltage_sel, .set_voltage_sel = tps65910_set_voltage_sel, - .list_voltage = tps65910_list_voltage, + .list_voltage = regulator_list_voltage_table, }; static struct regulator_ops tps65911_ops = { @@ -1165,15 +1148,18 @@ static __devinit int tps65910_probe(struct platform_device *pdev) } else if (i == TPS65910_REG_VDD3) { if (tps65910_chip_id(tps65910) == TPS65910) { pmic->desc[i].ops = &tps65910_ops_vdd3; + pmic->desc[i].volt_table = info->voltage_table; } else { pmic->desc[i].ops = &tps65910_ops_dcdc; pmic->desc[i].ramp_delay = 5000; } } else { - if (tps65910_chip_id(tps65910) == TPS65910) + if (tps65910_chip_id(tps65910) == TPS65910) { pmic->desc[i].ops = &tps65910_ops; - else + pmic->desc[i].volt_table = info->voltage_table; + } else { pmic->desc[i].ops = &tps65911_ops; + } } err = tps65910_set_ext_sleep_config(pmic, i, -- GitLab From 3a9cf8efd7b64f26f1e0f02afb70382f90cc11ca Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Thu, 21 Jun 2012 15:54:51 +0530 Subject: [PATCH 2442/6849] ASoC: Add support for synopsys i2s controller as per ASoC framework. This patch add support for synopsys I2S controller as per the ASoC framework. Signed-off-by: Rajeev Kumar Signed-off-by: Mark Brown --- include/sound/designware_i2s.h | 69 +++++ sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/dwc/Kconfig | 8 + sound/soc/dwc/Makefile | 3 + sound/soc/dwc/designware_i2s.c | 454 +++++++++++++++++++++++++++++++++ 6 files changed, 536 insertions(+) create mode 100644 include/sound/designware_i2s.h create mode 100644 sound/soc/dwc/Kconfig create mode 100644 sound/soc/dwc/Makefile create mode 100644 sound/soc/dwc/designware_i2s.c diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h new file mode 100644 index 000000000000..26f406e0f673 --- /dev/null +++ b/include/sound/designware_i2s.h @@ -0,0 +1,69 @@ +/* + * Copyright (ST) 2012 Rajeev Kumar (rajeev-dlh.kumar@st.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __SOUND_DESIGNWARE_I2S_H +#define __SOUND_DESIGNWARE_I2S_H + +#include +#include + +/* + * struct i2s_clk_config_data - represent i2s clk configuration data + * @chan_nr: number of channel + * @data_width: number of bits per sample (8/16/24/32 bit) + * @sample_rate: sampling frequency (8Khz, 16Khz, 32Khz, 44Khz, 48Khz) + */ +struct i2s_clk_config_data { + int chan_nr; + u32 data_width; + u32 sample_rate; +}; + +struct i2s_platform_data { + #define DWC_I2S_PLAY (1 << 0) + #define DWC_I2S_RECORD (1 << 1) + unsigned int cap; + int channel; + u32 snd_fmts; + u32 snd_rates; + + void *play_dma_data; + void *capture_dma_data; + bool (*filter)(struct dma_chan *chan, void *slave); + int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); +}; + +struct i2s_dma_data { + void *data; + dma_addr_t addr; + u32 max_burst; + enum dma_slave_buswidth addr_width; + bool (*filter)(struct dma_chan *chan, void *slave); +}; + +/* I2S DMA registers */ +#define I2S_RXDMA 0x01C0 +#define I2S_TXDMA 0x01C8 + +#define TWO_CHANNEL_SUPPORT 2 /* up to 2.0 */ +#define FOUR_CHANNEL_SUPPORT 4 /* up to 3.1 */ +#define SIX_CHANNEL_SUPPORT 6 /* up to 5.1 */ +#define EIGHT_CHANNEL_SUPPORT 8 /* up to 7.1 */ + +#endif /* __SOUND_DESIGNWARE_I2S_H */ diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 40b2ad1bb1cd..c5de0a84566f 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -33,6 +33,7 @@ source "sound/soc/atmel/Kconfig" source "sound/soc/au1x/Kconfig" source "sound/soc/blackfin/Kconfig" source "sound/soc/davinci/Kconfig" +source "sound/soc/dwc/Kconfig" source "sound/soc/ep93xx/Kconfig" source "sound/soc/fsl/Kconfig" source "sound/soc/jz4740/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 70990f4017f4..00a555a743b6 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_SND_SOC) += atmel/ obj-$(CONFIG_SND_SOC) += au1x/ obj-$(CONFIG_SND_SOC) += blackfin/ obj-$(CONFIG_SND_SOC) += davinci/ +obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += ep93xx/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += jz4740/ diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig new file mode 100644 index 000000000000..93e9fc33560c --- /dev/null +++ b/sound/soc/dwc/Kconfig @@ -0,0 +1,8 @@ +config SND_DESIGNWARE_I2S + tristate "Synopsys I2S Device Driver" + help + Say Y or M if you want to add support for I2S driver for + Synopsys desigwnware I2S device. The device supports upto + maximum of 8 channels each for play and record. + + diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile new file mode 100644 index 000000000000..319371f690f4 --- /dev/null +++ b/sound/soc/dwc/Makefile @@ -0,0 +1,3 @@ +# SYNOPSYS Platform Support +obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o + diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c new file mode 100644 index 000000000000..e667e2b45e67 --- /dev/null +++ b/sound/soc/dwc/designware_i2s.c @@ -0,0 +1,454 @@ +/* + * ALSA SoC Synopsys I2S Audio Layer + * + * sound/soc/spear/designware_i2s.c + * + * Copyright (C) 2010 ST Microelectronics + * Rajeev Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* common register for all channel */ +#define IER 0x000 +#define IRER 0x004 +#define ITER 0x008 +#define CER 0x00C +#define CCR 0x010 +#define RXFFR 0x014 +#define TXFFR 0x018 + +/* I2STxRxRegisters for all channels */ +#define LRBR_LTHR(x) (0x40 * x + 0x020) +#define RRBR_RTHR(x) (0x40 * x + 0x024) +#define RER(x) (0x40 * x + 0x028) +#define TER(x) (0x40 * x + 0x02C) +#define RCR(x) (0x40 * x + 0x030) +#define TCR(x) (0x40 * x + 0x034) +#define ISR(x) (0x40 * x + 0x038) +#define IMR(x) (0x40 * x + 0x03C) +#define ROR(x) (0x40 * x + 0x040) +#define TOR(x) (0x40 * x + 0x044) +#define RFCR(x) (0x40 * x + 0x048) +#define TFCR(x) (0x40 * x + 0x04C) +#define RFF(x) (0x40 * x + 0x050) +#define TFF(x) (0x40 * x + 0x054) + +/* I2SCOMPRegisters */ +#define I2S_COMP_PARAM_2 0x01F0 +#define I2S_COMP_PARAM_1 0x01F4 +#define I2S_COMP_VERSION 0x01F8 +#define I2S_COMP_TYPE 0x01FC + +#define MAX_CHANNEL_NUM 8 +#define MIN_CHANNEL_NUM 2 + +struct dw_i2s_dev { + void __iomem *i2s_base; + struct clk *clk; + int active; + unsigned int capability; + struct device *dev; + + /* data related to DMA transfers b/w i2s and DMAC */ + struct i2s_dma_data play_dma_data; + struct i2s_dma_data capture_dma_data; + struct i2s_clk_config_data config; + int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); +}; + +static inline void i2s_write_reg(void *io_base, int reg, u32 val) +{ + writel(val, io_base + reg); +} + +static inline u32 i2s_read_reg(void *io_base, int reg) +{ + return readl(io_base + reg); +} + +static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream) +{ + u32 i = 0; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + for (i = 0; i < 4; i++) + i2s_write_reg(dev->i2s_base, TER(i), 0); + } else { + for (i = 0; i < 4; i++) + i2s_write_reg(dev->i2s_base, RER(i), 0); + } +} + +static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream) +{ + u32 i = 0; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + for (i = 0; i < 4; i++) + i2s_write_reg(dev->i2s_base, TOR(i), 0); + } else { + for (i = 0; i < 4; i++) + i2s_write_reg(dev->i2s_base, ROR(i), 0); + } +} + +void i2s_start(struct dw_i2s_dev *dev, struct snd_pcm_substream *substream) +{ + + i2s_write_reg(dev->i2s_base, IER, 1); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + i2s_write_reg(dev->i2s_base, ITER, 1); + else + i2s_write_reg(dev->i2s_base, IRER, 1); + + i2s_write_reg(dev->i2s_base, CER, 1); +} + +static void i2s_stop(struct dw_i2s_dev *dev, + struct snd_pcm_substream *substream) +{ + u32 i = 0, irq; + + i2s_clear_irqs(dev, substream->stream); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + i2s_write_reg(dev->i2s_base, ITER, 0); + + for (i = 0; i < 4; i++) { + irq = i2s_read_reg(dev->i2s_base, IMR(i)); + i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30); + } + } else { + i2s_write_reg(dev->i2s_base, IRER, 0); + + for (i = 0; i < 4; i++) { + irq = i2s_read_reg(dev->i2s_base, IMR(i)); + i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03); + } + } + + if (!dev->active) { + i2s_write_reg(dev->i2s_base, CER, 0); + i2s_write_reg(dev->i2s_base, IER, 0); + } +} + +static int dw_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); + struct i2s_dma_data *dma_data = NULL; + + if (!(dev->capability & DWC_I2S_RECORD) && + (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) + return -EINVAL; + + if (!(dev->capability & DWC_I2S_PLAY) && + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) + return -EINVAL; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = &dev->play_dma_data; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + dma_data = &dev->capture_dma_data; + + snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data); + + return 0; +} + +static int dw_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + struct i2s_clk_config_data *config = &dev->config; + u32 ccr, xfer_resolution, ch_reg, irq; + int ret; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + config->data_width = 16; + ccr = 0x00; + xfer_resolution = 0x02; + break; + + case SNDRV_PCM_FORMAT_S24_LE: + config->data_width = 24; + ccr = 0x08; + xfer_resolution = 0x04; + break; + + case SNDRV_PCM_FORMAT_S32_LE: + config->data_width = 32; + ccr = 0x10; + xfer_resolution = 0x05; + break; + + default: + dev_err(dev->dev, "designware-i2s: unsuppted PCM fmt"); + return -EINVAL; + } + + config->chan_nr = params_channels(params); + + switch (config->chan_nr) { + case EIGHT_CHANNEL_SUPPORT: + ch_reg = 3; + case SIX_CHANNEL_SUPPORT: + ch_reg = 2; + case FOUR_CHANNEL_SUPPORT: + ch_reg = 1; + case TWO_CHANNEL_SUPPORT: + ch_reg = 0; + break; + default: + dev_err(dev->dev, "channel not supported\n"); + } + + i2s_disable_channels(dev, substream->stream); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution); + i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); + irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); + i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); + i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); + } else { + i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution); + i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); + irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); + i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); + i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); + } + + i2s_write_reg(dev->i2s_base, CCR, ccr); + + config->sample_rate = params_rate(params); + + if (!dev->i2s_clk_cfg) + return -EINVAL; + + ret = dev->i2s_clk_cfg(config); + if (ret < 0) { + dev_err(dev->dev, "runtime audio clk config fail\n"); + return ret; + } + + return 0; +} + +static void dw_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + snd_soc_dai_set_dma_data(dai, substream, NULL); +} + +static int dw_i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + dev->active++; + i2s_start(dev, substream); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + dev->active--; + i2s_stop(dev, substream); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static struct snd_soc_dai_ops dw_i2s_dai_ops = { + .startup = dw_i2s_startup, + .shutdown = dw_i2s_shutdown, + .hw_params = dw_i2s_hw_params, + .trigger = dw_i2s_trigger, +}; + +#ifdef CONFIG_PM + +static int dw_i2s_suspend(struct snd_soc_dai *dai) +{ + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + + clk_disable(dev->clk); + return 0; +} + +static int dw_i2s_resume(struct snd_soc_dai *dai) +{ + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + + clk_enable(dev->clk); + return 0; +} + +#else +#define dw_i2s_suspend NULL +#define dw_i2s_resume NULL +#endif + +static int dw_i2s_probe(struct platform_device *pdev) +{ + const struct i2s_platform_data *pdata = pdev->dev.platform_data; + struct dw_i2s_dev *dev; + struct resource *res; + int ret; + unsigned int cap; + struct snd_soc_dai_driver *dw_i2s_dai; + + if (!pdata) { + dev_err(&pdev->dev, "Invalid platform data\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no i2s resource defined\n"); + return -ENODEV; + } + + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), pdev->name)) { + dev_err(&pdev->dev, "i2s region already claimed\n"); + return -EBUSY; + } + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) { + dev_warn(&pdev->dev, "kzalloc fail\n"); + return -ENOMEM; + } + + dev->i2s_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!dev->i2s_base) { + dev_err(&pdev->dev, "ioremap fail for i2s_region\n"); + return -ENOMEM; + } + + cap = pdata->cap; + dev->capability = cap; + dev->i2s_clk_cfg = pdata->i2s_clk_cfg; + + /* Set DMA slaves info */ + + dev->play_dma_data.data = pdata->play_dma_data; + dev->capture_dma_data.data = pdata->capture_dma_data; + dev->play_dma_data.addr = res->start + I2S_TXDMA; + dev->capture_dma_data.addr = res->start + I2S_RXDMA; + dev->play_dma_data.max_burst = 16; + dev->capture_dma_data.max_burst = 16; + dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + dev->play_dma_data.filter = pdata->filter; + dev->capture_dma_data.filter = pdata->filter; + + dev->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(dev->clk)) + return PTR_ERR(dev->clk); + + ret = clk_enable(dev->clk); + if (ret < 0) + goto err_clk_put; + + dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); + if (!dw_i2s_dai) { + dev_err(&pdev->dev, "mem allocation failed for dai driver\n"); + ret = -ENOMEM; + goto err_clk_disable; + } + + if (cap & DWC_I2S_PLAY) { + dev_dbg(&pdev->dev, " SPEAr: play supported\n"); + dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; + dw_i2s_dai->playback.channels_max = pdata->channel; + dw_i2s_dai->playback.formats = pdata->snd_fmts; + dw_i2s_dai->playback.rates = pdata->snd_rates; + } + + if (cap & DWC_I2S_RECORD) { + dev_dbg(&pdev->dev, "SPEAr: record supported\n"); + dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; + dw_i2s_dai->capture.channels_max = pdata->channel; + dw_i2s_dai->capture.formats = pdata->snd_fmts; + dw_i2s_dai->capture.rates = pdata->snd_rates; + } + + dw_i2s_dai->ops = &dw_i2s_dai_ops; + dw_i2s_dai->suspend = dw_i2s_suspend; + dw_i2s_dai->resume = dw_i2s_resume; + + dev->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, dev); + ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai); + if (ret != 0) { + dev_err(&pdev->dev, "not able to register dai\n"); + goto err_set_drvdata; + } + + return 0; + +err_set_drvdata: + dev_set_drvdata(&pdev->dev, NULL); +err_clk_disable: + clk_disable(dev->clk); +err_clk_put: + clk_put(dev->clk); + return ret; +} + +static int dw_i2s_remove(struct platform_device *pdev) +{ + struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); + + snd_soc_unregister_dai(&pdev->dev); + dev_set_drvdata(&pdev->dev, NULL); + + clk_put(dev->clk); + + return 0; +} + +static struct platform_driver dw_i2s_driver = { + .probe = dw_i2s_probe, + .remove = dw_i2s_remove, + .driver = { + .name = "designware-i2s", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(dw_i2s_driver); + +MODULE_AUTHOR("Rajeev Kumar "); +MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:designware_i2s"); -- GitLab From 17efdc4ab8cc2ac959ca1a16c9ab04d8830c4bff Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 11:26:47 +0200 Subject: [PATCH 2443/6849] mac80211: remove TKIP debug The TKIP code hasn't been changed in a very long time, so it seems unlikely that anyone really has a need for the TKIP debug code. Remove it. Signed-off-by: Johannes Berg --- net/mac80211/Kconfig | 11 ----------- net/mac80211/tkip.c | 43 +------------------------------------------ 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 8d249d705980..323aa19a39d5 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -152,17 +152,6 @@ config MAC80211_HT_DEBUG Do not select this option. -config MAC80211_TKIP_DEBUG - bool "Verbose TKIP debugging" - depends on MAC80211_DEBUG_MENU - ---help--- - Selecting this option causes mac80211 to print out - very verbose TKIP debugging messages. It should not - be selected on production systems as those messages - are remotely triggerable. - - Do not select this option. - config MAC80211_IBSS_DEBUG bool "Verbose IBSS debugging" depends on MAC80211_DEBUG_MENU diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 68be47ca208f..57e14d59e12f 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -260,16 +260,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, keyid = pos[3]; iv32 = get_unaligned_le32(pos + 4); pos += 8; -#ifdef CONFIG_MAC80211_TKIP_DEBUG - { - int i; - pr_debug("TKIP decrypt: data(len=%zd)", payload_len); - for (i = 0; i < payload_len; i++) - printk(" %02x", payload[i]); - printk("\n"); - pr_debug("TKIP decrypt: iv16=%04x iv32=%08x\n", iv16, iv32); - } -#endif if (!(keyid & (1 << 5))) return TKIP_DECRYPT_NO_EXT_IV; @@ -280,15 +270,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT && (iv32 < key->u.tkip.rx[queue].iv32 || (iv32 == key->u.tkip.rx[queue].iv32 && - iv16 <= key->u.tkip.rx[queue].iv16))) { -#ifdef CONFIG_MAC80211_TKIP_DEBUG - pr_debug("TKIP replay detected for RX frame from %pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", - ta, iv32, iv16, - key->u.tkip.rx[queue].iv32, - key->u.tkip.rx[queue].iv16); -#endif + iv16 <= key->u.tkip.rx[queue].iv16))) return TKIP_DECRYPT_REPLAY; - } if (only_iv) { res = TKIP_DECRYPT_OK; @@ -300,21 +283,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, key->u.tkip.rx[queue].iv32 != iv32) { /* IV16 wrapped around - perform TKIP phase 1 */ tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); -#ifdef CONFIG_MAC80211_TKIP_DEBUG - { - int i; - u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; - pr_debug("TKIP decrypt: Phase1 TA=%pM TK=", ta); - for (i = 0; i < 16; i++) - printk("%02x ", - key->conf.key[key_offset + i]); - printk("\n"); - pr_debug("TKIP decrypt: P1K="); - for (i = 0; i < 5; i++) - printk("%04x ", key->u.tkip.rx[queue].p1k[i]); - printk("\n"); - } -#endif } if (key->local->ops->update_tkip_key && key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && @@ -330,15 +298,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, } tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); -#ifdef CONFIG_MAC80211_TKIP_DEBUG - { - int i; - pr_debug("TKIP decrypt: Phase2 rc4key="); - for (i = 0; i < 16; i++) - printk("%02x ", rc4key[i]); - printk("\n"); - } -#endif res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); done: -- GitLab From 241b446f30de171b627524c107ce03e5ecee0124 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Thu, 21 Jun 2012 15:54:52 +0530 Subject: [PATCH 2444/6849] ASoC: Add support for SPEAr ASoC pcm layer. This patch add support for the SPEAr ASoC pcm layer in ASoC framework. The pcm layer uses common snd_dmaengine framework. Signed-off-by: Rajeev Kumar Signed-off-by: Mark Brown --- include/sound/spear_dma.h | 35 ++++++ sound/soc/spear/spear_pcm.c | 214 ++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 include/sound/spear_dma.h create mode 100644 sound/soc/spear/spear_pcm.c diff --git a/include/sound/spear_dma.h b/include/sound/spear_dma.h new file mode 100644 index 000000000000..1b365bfdfb37 --- /dev/null +++ b/include/sound/spear_dma.h @@ -0,0 +1,35 @@ +/* +* linux/spear_dma.h +* +* Copyright (ST) 2012 Rajeev Kumar (rajeev-dlh.kumar@st.com) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*/ + +#ifndef SPEAR_DMA_H +#define SPEAR_DMA_H + +#include + +struct spear_dma_data { + void *data; + dma_addr_t addr; + u32 max_burst; + enum dma_slave_buswidth addr_width; + bool (*filter)(struct dma_chan *chan, void *slave); +}; + +#endif /* SPEAR_DMA_H */ diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c new file mode 100644 index 000000000000..97c2cac8e92c --- /dev/null +++ b/sound/soc/spear/spear_pcm.c @@ -0,0 +1,214 @@ +/* + * ALSA PCM interface for ST SPEAr Processors + * + * sound/soc/spear/spear_pcm.c + * + * Copyright (C) 2012 ST Microelectronics + * Rajeev Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct snd_pcm_hardware spear_pcm_hardware = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .buffer_bytes_max = 16 * 1024, /* max buffer size */ + .period_bytes_min = 2 * 1024, /* 1 msec data minimum period size */ + .period_bytes_max = 2 * 1024, /* maximum period size */ + .periods_min = 1, /* min # periods */ + .periods_max = 8, /* max # of periods */ + .fifo_size = 0, /* fifo size in bytes */ +}; + +static int spear_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static int spear_pcm_hw_free(struct snd_pcm_substream *substream) +{ + snd_pcm_set_runtime_buffer(substream, NULL); + + return 0; +} + +static int spear_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + struct spear_dma_data *dma_data = (struct spear_dma_data *) + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + int ret; + + ret = snd_soc_set_runtime_hwparams(substream, &spear_pcm_hardware); + if (ret) + return ret; + + ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data); + if (ret) + return ret; + + snd_dmaengine_pcm_set_data(substream, dma_data); + + return 0; +} + +static int spear_pcm_close(struct snd_pcm_substream *substream) +{ + + snd_dmaengine_pcm_close(substream); + + return 0; +} + +static int spear_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops spear_pcm_ops = { + .open = spear_pcm_open, + .close = spear_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = spear_pcm_hw_params, + .hw_free = spear_pcm_hw_free, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, + .mmap = spear_pcm_mmap, +}; + +static int +spear_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream, + size_t size) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + if (!buf->area) + return -ENOMEM; + + dev_info(buf->dev.dev, + " preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", + (void *)buf->area, (void *)buf->addr, size); + + buf->bytes = size; + return 0; +} + +static void spear_pcm_free(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf && !buf->area) + continue; + + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + buf->area = NULL; + } +} + +static u64 spear_pcm_dmamask = DMA_BIT_MASK(32); + +static int spear_pcm_new(struct snd_card *card, + struct snd_soc_dai *dai, struct snd_pcm *pcm) +{ + int ret; + + if (!card->dev->dma_mask) + card->dev->dma_mask = &spear_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + if (dai->driver->playback.channels_min) { + ret = spear_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK, + spear_pcm_hardware.buffer_bytes_max); + if (ret) + return ret; + } + + if (dai->driver->capture.channels_min) { + ret = spear_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE, + spear_pcm_hardware.buffer_bytes_max); + if (ret) + return ret; + } + + return 0; +} + +struct snd_soc_platform_driver spear_soc_platform = { + .ops = &spear_pcm_ops, + .pcm_new = spear_pcm_new, + .pcm_free = spear_pcm_free, +}; + +static int __devinit spear_soc_platform_probe(struct platform_device *pdev) +{ + return snd_soc_register_platform(&pdev->dev, &spear_soc_platform); +} + +static int __devexit spear_soc_platform_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + + return 0; +} + +static struct platform_driver spear_pcm_driver = { + .driver = { + .name = "spear-pcm-audio", + .owner = THIS_MODULE, + }, + + .probe = spear_soc_platform_probe, + .remove = __devexit_p(spear_soc_platform_remove), +}; + +module_platform_driver(spear_pcm_driver); + +MODULE_AUTHOR("Rajeev Kumar "); +MODULE_DESCRIPTION("SPEAr PCM DMA module"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spear-pcm-audio"); -- GitLab From 59bbe27ba0f6bae1d85f1521e43181d98ee9c5ab Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 22 Jun 2012 11:04:55 +0100 Subject: [PATCH 2445/6849] drm: drop comment about this header being autogenerated. This comment is well out of date. Signed-off-by: Dave Airlie --- include/drm/drm_pciids.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 81368ab6c611..a7aec391b7b7 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -1,7 +1,3 @@ -/* - This file is auto-generated from the drm_pciids.txt in the DRM CVS - Please contact dri-devel@lists.sf.net to add new cards to this list -*/ #define radeon_PCI_IDS \ {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x3151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ -- GitLab From 3d4eb9dfa3e89a09cdaaf3d0465479475e4afb0c Mon Sep 17 00:00:00 2001 From: Yu Xu Date: Fri, 15 Jun 2012 21:45:08 +0800 Subject: [PATCH 2446/6849] usb: gadget: mv: Add USB 3.0 device driver for Marvell PXA2128 chip. It supports Marvell USB 3.0 device controller for PXA2128 chip. Signed-off-by: Yu Xu Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 9 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/mv_u3d.h | 320 +++++ drivers/usb/gadget/mv_u3d_core.c | 2098 ++++++++++++++++++++++++++++++ 4 files changed, 2428 insertions(+) create mode 100644 drivers/usb/gadget/mv_u3d.h create mode 100644 drivers/usb/gadget/mv_u3d_core.c diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bddc8fd9a7be..5e242c34088d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -321,6 +321,15 @@ config USB_MV_UDC USB2.0 OTG controller, which can be configured as high speed or full speed USB peripheral. +config USB_MV_U3D + tristate "MARVELL PXA2128 USB 3.0 controller" + depends on CPU_MMP3 + select USB_GADGET_DUALSPEED + select USB_GADGET_SUPERSPEED + help + MARVELL PXA2128 Processor series include a super speed USB3.0 device + controller, which support super speed USB peripheral. + # # Controllers available in both integrated and discrete versions # diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 1811513f1c27..3fd8cd09d2c1 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_USB_EG20T) += pch_udc.o obj-$(CONFIG_USB_MV_UDC) += mv_udc.o mv_udc-y := mv_udc_core.o obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o +obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o # # USB gadget drivers diff --git a/drivers/usb/gadget/mv_u3d.h b/drivers/usb/gadget/mv_u3d.h new file mode 100644 index 000000000000..e32a787ac373 --- /dev/null +++ b/drivers/usb/gadget/mv_u3d.h @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#ifndef __MV_U3D_H +#define __MV_U3D_H + +#define MV_U3D_EP_CONTEXT_ALIGNMENT 32 +#define MV_U3D_TRB_ALIGNMENT 16 +#define MV_U3D_DMA_BOUNDARY 4096 +#define MV_U3D_EP0_MAX_PKT_SIZE 512 + +/* ep0 transfer state */ +#define MV_U3D_WAIT_FOR_SETUP 0 +#define MV_U3D_DATA_STATE_XMIT 1 +#define MV_U3D_DATA_STATE_NEED_ZLP 2 +#define MV_U3D_WAIT_FOR_OUT_STATUS 3 +#define MV_U3D_DATA_STATE_RECV 4 +#define MV_U3D_STATUS_STAGE 5 + +#define MV_U3D_EP_MAX_LENGTH_TRANSFER 0x10000 + +/* USB3 Interrupt Status */ +#define MV_U3D_USBINT_SETUP 0x00000001 +#define MV_U3D_USBINT_RX_COMPLETE 0x00000002 +#define MV_U3D_USBINT_TX_COMPLETE 0x00000004 +#define MV_U3D_USBINT_UNDER_RUN 0x00000008 +#define MV_U3D_USBINT_RXDESC_ERR 0x00000010 +#define MV_U3D_USBINT_TXDESC_ERR 0x00000020 +#define MV_U3D_USBINT_RX_TRB_COMPLETE 0x00000040 +#define MV_U3D_USBINT_TX_TRB_COMPLETE 0x00000080 +#define MV_U3D_USBINT_VBUS_VALID 0x00010000 +#define MV_U3D_USBINT_STORAGE_CMD_FULL 0x00020000 +#define MV_U3D_USBINT_LINK_CHG 0x01000000 + +/* USB3 Interrupt Enable */ +#define MV_U3D_INTR_ENABLE_SETUP 0x00000001 +#define MV_U3D_INTR_ENABLE_RX_COMPLETE 0x00000002 +#define MV_U3D_INTR_ENABLE_TX_COMPLETE 0x00000004 +#define MV_U3D_INTR_ENABLE_UNDER_RUN 0x00000008 +#define MV_U3D_INTR_ENABLE_RXDESC_ERR 0x00000010 +#define MV_U3D_INTR_ENABLE_TXDESC_ERR 0x00000020 +#define MV_U3D_INTR_ENABLE_RX_TRB_COMPLETE 0x00000040 +#define MV_U3D_INTR_ENABLE_TX_TRB_COMPLETE 0x00000080 +#define MV_U3D_INTR_ENABLE_RX_BUFFER_ERR 0x00000100 +#define MV_U3D_INTR_ENABLE_VBUS_VALID 0x00010000 +#define MV_U3D_INTR_ENABLE_STORAGE_CMD_FULL 0x00020000 +#define MV_U3D_INTR_ENABLE_LINK_CHG 0x01000000 +#define MV_U3D_INTR_ENABLE_PRIME_STATUS 0x02000000 + +/* USB3 Link Change */ +#define MV_U3D_LINK_CHANGE_LINK_UP 0x00000001 +#define MV_U3D_LINK_CHANGE_SUSPEND 0x00000002 +#define MV_U3D_LINK_CHANGE_RESUME 0x00000004 +#define MV_U3D_LINK_CHANGE_WRESET 0x00000008 +#define MV_U3D_LINK_CHANGE_HRESET 0x00000010 +#define MV_U3D_LINK_CHANGE_VBUS_INVALID 0x00000020 +#define MV_U3D_LINK_CHANGE_INACT 0x00000040 +#define MV_U3D_LINK_CHANGE_DISABLE_AFTER_U0 0x00000080 +#define MV_U3D_LINK_CHANGE_U1 0x00000100 +#define MV_U3D_LINK_CHANGE_U2 0x00000200 +#define MV_U3D_LINK_CHANGE_U3 0x00000400 + +/* bridge setting */ +#define MV_U3D_BRIDGE_SETTING_VBUS_VALID (1 << 16) + +/* Command Register Bit Masks */ +#define MV_U3D_CMD_RUN_STOP 0x00000001 +#define MV_U3D_CMD_CTRL_RESET 0x00000002 + +/* ep control register */ +#define MV_U3D_EPXCR_EP_TYPE_CONTROL 0 +#define MV_U3D_EPXCR_EP_TYPE_ISOC 1 +#define MV_U3D_EPXCR_EP_TYPE_BULK 2 +#define MV_U3D_EPXCR_EP_TYPE_INT 3 +#define MV_U3D_EPXCR_EP_ENABLE_SHIFT 4 +#define MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT 12 +#define MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT 16 +#define MV_U3D_USB_BULK_BURST_OUT 6 +#define MV_U3D_USB_BULK_BURST_IN 14 + +#define MV_U3D_EPXCR_EP_FLUSH (1 << 7) +#define MV_U3D_EPXCR_EP_HALT (1 << 1) +#define MV_U3D_EPXCR_EP_INIT (1) + +/* TX/RX Status Register */ +#define MV_U3D_XFERSTATUS_COMPLETE_SHIFT 24 +#define MV_U3D_COMPLETE_INVALID 0 +#define MV_U3D_COMPLETE_SUCCESS 1 +#define MV_U3D_COMPLETE_BUFF_ERR 2 +#define MV_U3D_COMPLETE_SHORT_PACKET 3 +#define MV_U3D_COMPLETE_TRB_ERR 5 +#define MV_U3D_XFERSTATUS_TRB_LENGTH_MASK (0xFFFFFF) + +#define MV_U3D_USB_LINK_BYPASS_VBUS 0x8 + +#define MV_U3D_LTSSM_PHY_INIT_DONE 0x80000000 +#define MV_U3D_LTSSM_NEVER_GO_COMPLIANCE 0x40000000 + +#define MV_U3D_USB3_OP_REGS_OFFSET 0x100 +#define MV_U3D_USB3_PHY_OFFSET 0xB800 + +#define DCS_ENABLE 0x1 + +/* timeout */ +#define MV_U3D_RESET_TIMEOUT 10000 +#define MV_U3D_FLUSH_TIMEOUT 100000 +#define MV_U3D_OWN_TIMEOUT 10000 +#define LOOPS_USEC_SHIFT 4 +#define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) +#define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) + +/* ep direction */ +#define MV_U3D_EP_DIR_IN 1 +#define MV_U3D_EP_DIR_OUT 0 +#define mv_u3d_ep_dir(ep) (((ep)->ep_num == 0) ? \ + ((ep)->u3d->ep0_dir) : ((ep)->direction)) + +/* usb capability registers */ +struct mv_u3d_cap_regs { + u32 rsvd[5]; + u32 dboff; /* doorbell register offset */ + u32 rtsoff; /* runtime register offset */ + u32 vuoff; /* vendor unique register offset */ +}; + +/* operation registers */ +struct mv_u3d_op_regs { + u32 usbcmd; /* Command register */ + u32 rsvd1[11]; + u32 dcbaapl; /* Device Context Base Address low register */ + u32 dcbaaph; /* Device Context Base Address high register */ + u32 rsvd2[243]; + u32 portsc; /* port status and control register*/ + u32 portlinkinfo; /* port link info register*/ + u32 rsvd3[9917]; + u32 doorbell; /* doorbell register */ +}; + +/* control enpoint enable registers */ +struct epxcr { + u32 epxoutcr0; /* ep out control 0 register */ + u32 epxoutcr1; /* ep out control 1 register */ + u32 epxincr0; /* ep in control 0 register */ + u32 epxincr1; /* ep in control 1 register */ +}; + +/* transfer status registers */ +struct xferstatus { + u32 curdeqlo; /* current TRB pointer low */ + u32 curdeqhi; /* current TRB pointer high */ + u32 statuslo; /* transfer status low */ + u32 statushi; /* transfer status high */ +}; + +/* vendor unique control registers */ +struct mv_u3d_vuc_regs { + u32 ctrlepenable; /* control endpoint enable register */ + u32 setuplock; /* setup lock register */ + u32 endcomplete; /* endpoint transfer complete register */ + u32 intrcause; /* interrupt cause register */ + u32 intrenable; /* interrupt enable register */ + u32 trbcomplete; /* TRB complete register */ + u32 linkchange; /* link change register */ + u32 rsvd1[5]; + u32 trbunderrun; /* TRB underrun register */ + u32 rsvd2[43]; + u32 bridgesetting; /* bridge setting register */ + u32 rsvd3[7]; + struct xferstatus txst[16]; /* TX status register */ + struct xferstatus rxst[16]; /* RX status register */ + u32 ltssm; /* LTSSM control register */ + u32 pipe; /* PIPE control register */ + u32 linkcr0; /* link control 0 register */ + u32 linkcr1; /* link control 1 register */ + u32 rsvd6[60]; + u32 mib0; /* MIB0 counter register */ + u32 usblink; /* usb link control register */ + u32 ltssmstate; /* LTSSM state register */ + u32 linkerrorcause; /* link error cause register */ + u32 rsvd7[60]; + u32 devaddrtiebrkr; /* device address and tie breaker */ + u32 itpinfo0; /* ITP info 0 register */ + u32 itpinfo1; /* ITP info 1 register */ + u32 rsvd8[61]; + struct epxcr epcr[16]; /* ep control register */ + u32 rsvd9[64]; + u32 phyaddr; /* PHY address register */ + u32 phydata; /* PHY data register */ +}; + +/* Endpoint context structure */ +struct mv_u3d_ep_context { + u32 rsvd0; + u32 rsvd1; + u32 trb_addr_lo; /* TRB address low 32 bit */ + u32 trb_addr_hi; /* TRB address high 32 bit */ + u32 rsvd2; + u32 rsvd3; + struct usb_ctrlrequest setup_buffer; /* setup data buffer */ +}; + +/* TRB control data structure */ +struct mv_u3d_trb_ctrl { + u32 own:1; /* owner of TRB */ + u32 rsvd1:3; + u32 chain:1; /* associate this TRB with the + next TRB on the Ring */ + u32 ioc:1; /* interrupt on complete */ + u32 rsvd2:4; + u32 type:6; /* TRB type */ +#define TYPE_NORMAL 1 +#define TYPE_DATA 3 +#define TYPE_LINK 6 + u32 dir:1; /* Working at data stage of control endpoint + operation. 0 is OUT and 1 is IN. */ + u32 rsvd3:15; +}; + +/* TRB data structure + * For multiple TRB, all the TRBs' physical address should be continuous. + */ +struct mv_u3d_trb_hw { + u32 buf_addr_lo; /* data buffer address low 32 bit */ + u32 buf_addr_hi; /* data buffer address high 32 bit */ + u32 trb_len; /* transfer length */ + struct mv_u3d_trb_ctrl ctrl; /* TRB control data */ +}; + +/* TRB structure */ +struct mv_u3d_trb { + struct mv_u3d_trb_hw *trb_hw; /* point to the trb_hw structure */ + dma_addr_t trb_dma; /* dma address for this trb_hw */ + struct list_head trb_list; /* trb list */ +}; + +/* device data structure */ +struct mv_u3d { + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + spinlock_t lock; /* device lock */ + struct completion *done; + struct device *dev; + int irq; + + /* usb controller registers */ + struct mv_u3d_cap_regs __iomem *cap_regs; + struct mv_u3d_op_regs __iomem *op_regs; + struct mv_u3d_vuc_regs __iomem *vuc_regs; + void __iomem *phy_regs; + + unsigned int max_eps; + struct mv_u3d_ep_context *ep_context; + size_t ep_context_size; + dma_addr_t ep_context_dma; + + struct dma_pool *trb_pool; /* for TRB data structure */ + struct mv_u3d_ep *eps; + + struct mv_u3d_req *status_req; /* ep0 status request */ + struct usb_ctrlrequest local_setup_buff; /* store setup data*/ + + unsigned int resume_state; /* USB state to resume */ + unsigned int usb_state; /* USB current state */ + unsigned int ep0_state; /* Endpoint zero state */ + unsigned int ep0_dir; + + unsigned int dev_addr; /* device address */ + + unsigned int errors; + + unsigned softconnect:1; + unsigned vbus_active:1; /* vbus is active or not */ + unsigned remote_wakeup:1; /* support remote wakeup */ + unsigned clock_gating:1; /* clock gating or not */ + unsigned active:1; /* udc is active or not */ + unsigned vbus_valid_detect:1; /* udc vbus detection */ + + struct mv_usb_addon_irq *vbus; + unsigned int power; + + struct clk *clk; +}; + +/* endpoint data structure */ +struct mv_u3d_ep { + struct usb_ep ep; + struct mv_u3d *u3d; + struct list_head queue; /* ep request queued hardware */ + struct list_head req_list; /* list of ep request */ + struct mv_u3d_ep_context *ep_context; /* ep context */ + u32 direction; + char name[14]; + u32 processing; /* there is ep request + queued on haredware */ + spinlock_t req_lock; /* ep lock */ + unsigned wedge:1; + unsigned enabled:1; + unsigned ep_type:2; + unsigned ep_num:8; +}; + +/* request data structure */ +struct mv_u3d_req { + struct usb_request req; + struct mv_u3d_ep *ep; + struct list_head queue; /* ep requst queued on hardware */ + struct list_head list; /* ep request list */ + struct list_head trb_list; /* trb list of a request */ + + struct mv_u3d_trb *trb_head; /* point to first trb of a request */ + unsigned trb_count; /* TRB number in the chain */ + unsigned chain; /* TRB chain or not */ +}; + +#endif diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c new file mode 100644 index 000000000000..8cfd5b028dbd --- /dev/null +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -0,0 +1,2098 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mv_u3d.h" + +#define DRIVER_DESC "Marvell PXA USB3.0 Device Controller driver" + +static const char driver_name[] = "mv_u3d"; +static const char driver_desc[] = DRIVER_DESC; + +static void mv_u3d_nuke(struct mv_u3d_ep *ep, int status); +static void mv_u3d_stop_activity(struct mv_u3d *u3d, + struct usb_gadget_driver *driver); + +/* for endpoint 0 operations */ +static const struct usb_endpoint_descriptor mv_u3d_ep0_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0, + .bmAttributes = USB_ENDPOINT_XFER_CONTROL, + .wMaxPacketSize = MV_U3D_EP0_MAX_PKT_SIZE, +}; + +static void mv_u3d_ep0_reset(struct mv_u3d *u3d) +{ + struct mv_u3d_ep *ep; + u32 epxcr; + int i; + + for (i = 0; i < 2; i++) { + ep = &u3d->eps[i]; + ep->u3d = u3d; + + /* ep0 ep context, ep0 in and out share the same ep context */ + ep->ep_context = &u3d->ep_context[1]; + } + + /* reset ep state machine */ + /* reset ep0 out */ + epxcr = ioread32(&u3d->vuc_regs->epcr[0].epxoutcr0); + epxcr |= MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxoutcr0); + udelay(5); + epxcr &= ~MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxoutcr0); + + epxcr = ((MV_U3D_EP0_MAX_PKT_SIZE + << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) + | (1 << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) + | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) + | MV_U3D_EPXCR_EP_TYPE_CONTROL); + iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxoutcr1); + + /* reset ep0 in */ + epxcr = ioread32(&u3d->vuc_regs->epcr[0].epxincr0); + epxcr |= MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxincr0); + udelay(5); + epxcr &= ~MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxincr0); + + epxcr = ((MV_U3D_EP0_MAX_PKT_SIZE + << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) + | (1 << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) + | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) + | MV_U3D_EPXCR_EP_TYPE_CONTROL); + iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxincr1); +} + +static void mv_u3d_ep0_stall(struct mv_u3d *u3d) +{ + u32 tmp; + dev_dbg(u3d->dev, "%s\n", __func__); + + /* set TX and RX to stall */ + tmp = ioread32(&u3d->vuc_regs->epcr[0].epxoutcr0); + tmp |= MV_U3D_EPXCR_EP_HALT; + iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxoutcr0); + + tmp = ioread32(&u3d->vuc_regs->epcr[0].epxincr0); + tmp |= MV_U3D_EPXCR_EP_HALT; + iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxincr0); + + /* update ep0 state */ + u3d->ep0_state = MV_U3D_WAIT_FOR_SETUP; + u3d->ep0_dir = MV_U3D_EP_DIR_OUT; +} + +static int mv_u3d_process_ep_req(struct mv_u3d *u3d, int index, + struct mv_u3d_req *curr_req) +{ + struct mv_u3d_trb *curr_trb; + dma_addr_t cur_deq_lo; + struct mv_u3d_ep_context *curr_ep_context; + int trb_complete, actual, remaining_length; + int direction, ep_num; + int retval = 0; + u32 tmp, status, length; + + curr_ep_context = &u3d->ep_context[index]; + direction = index % 2; + ep_num = index / 2; + + trb_complete = 0; + actual = curr_req->req.length; + + while (!list_empty(&curr_req->trb_list)) { + curr_trb = list_entry(curr_req->trb_list.next, + struct mv_u3d_trb, trb_list); + if (!curr_trb->trb_hw->ctrl.own) { + dev_err(u3d->dev, "%s, TRB own error!\n", + u3d->eps[index].name); + return 1; + } + + curr_trb->trb_hw->ctrl.own = 0; + if (direction == MV_U3D_EP_DIR_OUT) { + tmp = ioread32(&u3d->vuc_regs->rxst[ep_num].statuslo); + cur_deq_lo = + ioread32(&u3d->vuc_regs->rxst[ep_num].curdeqlo); + } else { + tmp = ioread32(&u3d->vuc_regs->txst[ep_num].statuslo); + cur_deq_lo = + ioread32(&u3d->vuc_regs->txst[ep_num].curdeqlo); + } + + status = tmp >> MV_U3D_XFERSTATUS_COMPLETE_SHIFT; + length = tmp & MV_U3D_XFERSTATUS_TRB_LENGTH_MASK; + + if (status == MV_U3D_COMPLETE_SUCCESS || + (status == MV_U3D_COMPLETE_SHORT_PACKET && + direction == MV_U3D_EP_DIR_OUT)) { + remaining_length += length; + actual -= remaining_length; + } else { + dev_err(u3d->dev, + "complete_tr error: ep=%d %s: error = 0x%x\n", + index >> 1, direction ? "SEND" : "RECV", + status); + retval = -EPROTO; + } + + list_del_init(&curr_trb->trb_list); + } + if (retval) + return retval; + + curr_req->req.actual = actual; + return 0; +} + +/* + * mv_u3d_done() - retire a request; caller blocked irqs + * @status : request status to be set, only works when + * request is still in progress. + */ +static +void mv_u3d_done(struct mv_u3d_ep *ep, struct mv_u3d_req *req, int status) +{ + struct mv_u3d *u3d = (struct mv_u3d *)ep->u3d; + + dev_dbg(u3d->dev, "mv_u3d_done: remove req->queue\n"); + /* Removed the req from ep queue */ + list_del_init(&req->queue); + + /* req.status should be set as -EINPROGRESS in ep_queue() */ + if (req->req.status == -EINPROGRESS) + req->req.status = status; + else + status = req->req.status; + + /* Free trb for the request */ + if (!req->chain) + dma_pool_free(u3d->trb_pool, + req->trb_head->trb_hw, req->trb_head->trb_dma); + else { + dma_unmap_single(ep->u3d->gadget.dev.parent, + (dma_addr_t)req->trb_head->trb_dma, + req->trb_count * sizeof(struct mv_u3d_trb_hw), + DMA_BIDIRECTIONAL); + kfree(req->trb_head->trb_hw); + } + kfree(req->trb_head); + + usb_gadget_unmap_request(&u3d->gadget, &req->req, mv_u3d_ep_dir(ep)); + + if (status && (status != -ESHUTDOWN)) { + dev_dbg(u3d->dev, "complete %s req %p stat %d len %u/%u", + ep->ep.name, &req->req, status, + req->req.actual, req->req.length); + } + + spin_unlock(&ep->u3d->lock); + /* + * complete() is from gadget layer, + * eg fsg->bulk_in_complete() + */ + if (req->req.complete) + req->req.complete(&ep->ep, &req->req); + + spin_lock(&ep->u3d->lock); +} + +static int mv_u3d_queue_trb(struct mv_u3d_ep *ep, struct mv_u3d_req *req) +{ + u32 tmp, direction; + struct mv_u3d *u3d; + struct mv_u3d_ep_context *ep_context; + int retval = 0; + + u3d = ep->u3d; + direction = mv_u3d_ep_dir(ep); + + /* ep0 in and out share the same ep context slot 1*/ + if (ep->ep_num == 0) + ep_context = &(u3d->ep_context[1]); + else + ep_context = &(u3d->ep_context[ep->ep_num * 2 + direction]); + + /* check if the pipe is empty or not */ + if (!list_empty(&ep->queue)) { + dev_err(u3d->dev, "add trb to non-empty queue!\n"); + retval = -ENOMEM; + WARN_ON(1); + } else { + ep_context->rsvd0 = cpu_to_le32(1); + ep_context->rsvd1 = 0; + + /* Configure the trb address and set the DCS bit. + * Both DCS bit and own bit in trb should be set. + */ + ep_context->trb_addr_lo = + cpu_to_le32(req->trb_head->trb_dma | DCS_ENABLE); + ep_context->trb_addr_hi = 0; + + /* Ensure that updates to the EP Context will + * occure before Ring Bell. + */ + wmb(); + + /* ring bell the ep */ + if (ep->ep_num == 0) + tmp = 0x1; + else + tmp = ep->ep_num * 2 + + ((direction == MV_U3D_EP_DIR_OUT) ? 0 : 1); + + iowrite32(tmp, &u3d->op_regs->doorbell); + } + return retval; +} + +static struct mv_u3d_trb *mv_u3d_build_trb_one(struct mv_u3d_req *req, + unsigned *length, dma_addr_t *dma) +{ + u32 temp; + unsigned int direction; + struct mv_u3d_trb *trb; + struct mv_u3d_trb_hw *trb_hw; + struct mv_u3d *u3d; + + /* how big will this transfer be? */ + *length = req->req.length - req->req.actual; + BUG_ON(*length > (unsigned)MV_U3D_EP_MAX_LENGTH_TRANSFER); + + u3d = req->ep->u3d; + + trb = kzalloc(sizeof(*trb), GFP_ATOMIC); + if (!trb) { + dev_err(u3d->dev, "%s, trb alloc fail\n", __func__); + return NULL; + } + + /* + * Be careful that no _GFP_HIGHMEM is set, + * or we can not use dma_to_virt + * cannot use GFP_KERNEL in spin lock + */ + trb_hw = dma_pool_alloc(u3d->trb_pool, GFP_ATOMIC, dma); + if (!trb_hw) { + dev_err(u3d->dev, + "%s, dma_pool_alloc fail\n", __func__); + return NULL; + } + trb->trb_dma = *dma; + trb->trb_hw = trb_hw; + + /* initialize buffer page pointers */ + temp = (u32)(req->req.dma + req->req.actual); + + trb_hw->buf_addr_lo = cpu_to_le32(temp); + trb_hw->buf_addr_hi = 0; + trb_hw->trb_len = cpu_to_le32(*length); + trb_hw->ctrl.own = 1; + + if (req->ep->ep_num == 0) + trb_hw->ctrl.type = TYPE_DATA; + else + trb_hw->ctrl.type = TYPE_NORMAL; + + req->req.actual += *length; + + direction = mv_u3d_ep_dir(req->ep); + if (direction == MV_U3D_EP_DIR_IN) + trb_hw->ctrl.dir = 1; + else + trb_hw->ctrl.dir = 0; + + /* Enable interrupt for the last trb of a request */ + if (!req->req.no_interrupt) + trb_hw->ctrl.ioc = 1; + + trb_hw->ctrl.chain = 0; + + wmb(); + return trb; +} + +static int mv_u3d_build_trb_chain(struct mv_u3d_req *req, unsigned *length, + struct mv_u3d_trb *trb, int *is_last) +{ + u32 temp; + unsigned int direction; + struct mv_u3d *u3d; + + /* how big will this transfer be? */ + *length = min(req->req.length - req->req.actual, + (unsigned)MV_U3D_EP_MAX_LENGTH_TRANSFER); + + u3d = req->ep->u3d; + + trb->trb_dma = 0; + + /* initialize buffer page pointers */ + temp = (u32)(req->req.dma + req->req.actual); + + trb->trb_hw->buf_addr_lo = cpu_to_le32(temp); + trb->trb_hw->buf_addr_hi = 0; + trb->trb_hw->trb_len = cpu_to_le32(*length); + trb->trb_hw->ctrl.own = 1; + + if (req->ep->ep_num == 0) + trb->trb_hw->ctrl.type = TYPE_DATA; + else + trb->trb_hw->ctrl.type = TYPE_NORMAL; + + req->req.actual += *length; + + direction = mv_u3d_ep_dir(req->ep); + if (direction == MV_U3D_EP_DIR_IN) + trb->trb_hw->ctrl.dir = 1; + else + trb->trb_hw->ctrl.dir = 0; + + /* zlp is needed if req->req.zero is set */ + if (req->req.zero) { + if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0) + *is_last = 1; + else + *is_last = 0; + } else if (req->req.length == req->req.actual) + *is_last = 1; + else + *is_last = 0; + + /* Enable interrupt for the last trb of a request */ + if (*is_last && !req->req.no_interrupt) + trb->trb_hw->ctrl.ioc = 1; + + if (*is_last) + trb->trb_hw->ctrl.chain = 0; + else { + trb->trb_hw->ctrl.chain = 1; + dev_dbg(u3d->dev, "chain trb\n"); + } + + wmb(); + + return 0; +} + +/* generate TRB linked list for a request + * usb controller only supports continous trb chain, + * that trb structure physical address should be continous. + */ +static int mv_u3d_req_to_trb(struct mv_u3d_req *req) +{ + unsigned count; + int is_last; + struct mv_u3d_trb *trb; + struct mv_u3d_trb_hw *trb_hw; + struct mv_u3d *u3d; + dma_addr_t dma; + unsigned length; + unsigned trb_num; + + u3d = req->ep->u3d; + + INIT_LIST_HEAD(&req->trb_list); + + length = req->req.length - req->req.actual; + /* normally the request transfer length is less than 16KB. + * we use buil_trb_one() to optimize it. + */ + if (length <= (unsigned)MV_U3D_EP_MAX_LENGTH_TRANSFER) { + trb = mv_u3d_build_trb_one(req, &count, &dma); + list_add_tail(&trb->trb_list, &req->trb_list); + req->trb_head = trb; + req->trb_count = 1; + req->chain = 0; + } else { + trb_num = length / MV_U3D_EP_MAX_LENGTH_TRANSFER; + if (length % MV_U3D_EP_MAX_LENGTH_TRANSFER) + trb_num++; + + trb = kcalloc(trb_num, sizeof(*trb), GFP_ATOMIC); + if (!trb) { + dev_err(u3d->dev, + "%s, trb alloc fail\n", __func__); + return -ENOMEM; + } + + trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC); + if (!trb_hw) { + dev_err(u3d->dev, + "%s, trb_hw alloc fail\n", __func__); + return -ENOMEM; + } + + do { + trb->trb_hw = trb_hw; + if (mv_u3d_build_trb_chain(req, &count, + trb, &is_last)) { + dev_err(u3d->dev, + "%s, mv_u3d_build_trb_chain fail\n", + __func__); + return -EIO; + } + + list_add_tail(&trb->trb_list, &req->trb_list); + req->trb_count++; + trb++; + trb_hw++; + } while (!is_last); + + req->trb_head = list_entry(req->trb_list.next, + struct mv_u3d_trb, trb_list); + req->trb_head->trb_dma = dma_map_single(u3d->gadget.dev.parent, + req->trb_head->trb_hw, + trb_num * sizeof(*trb_hw), + DMA_BIDIRECTIONAL); + + req->chain = 1; + } + + return 0; +} + +static int +mv_u3d_start_queue(struct mv_u3d_ep *ep) +{ + struct mv_u3d *u3d = ep->u3d; + struct mv_u3d_req *req; + int ret; + + if (!list_empty(&ep->req_list) && !ep->processing) + req = list_entry(ep->req_list.next, struct mv_u3d_req, list); + else + return 0; + + ep->processing = 1; + + /* set up dma mapping */ + ret = usb_gadget_map_request(&u3d->gadget, &req->req, + mv_u3d_ep_dir(ep)); + if (ret) + return ret; + + req->req.status = -EINPROGRESS; + req->req.actual = 0; + req->trb_count = 0; + + /* build trbs and push them to device queue */ + if (!mv_u3d_req_to_trb(req)) { + ret = mv_u3d_queue_trb(ep, req); + if (ret) { + ep->processing = 0; + return ret; + } + } else { + ep->processing = 0; + dev_err(u3d->dev, "%s, mv_u3d_req_to_trb fail\n", __func__); + return -ENOMEM; + } + + /* irq handler advances the queue */ + if (req) + list_add_tail(&req->queue, &ep->queue); + + return 0; +} + +static int mv_u3d_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct mv_u3d *u3d; + struct mv_u3d_ep *ep; + struct mv_u3d_ep_context *ep_context; + u16 max = 0; + unsigned maxburst = 0; + u32 epxcr, direction; + + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) + return -EINVAL; + + ep = container_of(_ep, struct mv_u3d_ep, ep); + u3d = ep->u3d; + + if (!u3d->driver || u3d->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + + direction = mv_u3d_ep_dir(ep); + max = le16_to_cpu(desc->wMaxPacketSize); + + if (!_ep->maxburst) + _ep->maxburst = 1; + maxburst = _ep->maxburst; + + /* Get the endpoint context address */ + ep_context = (struct mv_u3d_ep_context *)ep->ep_context; + + /* Set the max burst size */ + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_BULK: + if (maxburst > 16) { + dev_dbg(u3d->dev, + "max burst should not be greater " + "than 16 on bulk ep\n"); + maxburst = 1; + _ep->maxburst = maxburst; + } + dev_dbg(u3d->dev, + "maxburst: %d on bulk %s\n", maxburst, ep->name); + break; + case USB_ENDPOINT_XFER_CONTROL: + /* control transfer only supports maxburst as one */ + maxburst = 1; + _ep->maxburst = maxburst; + break; + case USB_ENDPOINT_XFER_INT: + if (maxburst != 1) { + dev_dbg(u3d->dev, + "max burst should be 1 on int ep " + "if transfer size is not 1024\n"); + maxburst = 1; + _ep->maxburst = maxburst; + } + break; + case USB_ENDPOINT_XFER_ISOC: + if (maxburst != 1) { + dev_dbg(u3d->dev, + "max burst should be 1 on isoc ep " + "if transfer size is not 1024\n"); + maxburst = 1; + _ep->maxburst = maxburst; + } + break; + default: + goto en_done; + } + + ep->ep.maxpacket = max; + ep->ep.desc = desc; + ep->enabled = 1; + + /* Enable the endpoint for Rx or Tx and set the endpoint type */ + if (direction == MV_U3D_EP_DIR_OUT) { + epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + epxcr |= MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + udelay(5); + epxcr &= ~MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + + epxcr = ((max << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) + | ((maxburst - 1) << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) + | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) + | (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr1); + } else { + epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + epxcr |= MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + udelay(5); + epxcr &= ~MV_U3D_EPXCR_EP_INIT; + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + + epxcr = ((max << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) + | ((maxburst - 1) << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) + | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) + | (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr1); + } + + return 0; +en_done: + return -EINVAL; +} + +static int mv_u3d_ep_disable(struct usb_ep *_ep) +{ + struct mv_u3d *u3d; + struct mv_u3d_ep *ep; + struct mv_u3d_ep_context *ep_context; + u32 epxcr, direction; + + if (!_ep) + return -EINVAL; + + ep = container_of(_ep, struct mv_u3d_ep, ep); + if (!ep->ep.desc) + return -EINVAL; + + u3d = ep->u3d; + + /* Get the endpoint context address */ + ep_context = ep->ep_context; + + direction = mv_u3d_ep_dir(ep); + + /* nuke all pending requests (does flush) */ + mv_u3d_nuke(ep, -ESHUTDOWN); + + /* Disable the endpoint for Rx or Tx and reset the endpoint type */ + if (direction == MV_U3D_EP_DIR_OUT) { + epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr1); + epxcr &= ~((1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) + | USB_ENDPOINT_XFERTYPE_MASK); + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr1); + } else { + epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr1); + epxcr &= ~((1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) + | USB_ENDPOINT_XFERTYPE_MASK); + iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr1); + } + + ep->enabled = 0; + + ep->ep.desc = NULL; + return 0; +} + +static struct usb_request * +mv_u3d_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) +{ + struct mv_u3d_req *req = NULL; + + req = kzalloc(sizeof *req, gfp_flags); + if (!req) + return NULL; + + INIT_LIST_HEAD(&req->queue); + + return &req->req; +} + +static void mv_u3d_free_request(struct usb_ep *_ep, struct usb_request *_req) +{ + struct mv_u3d_req *req = container_of(_req, struct mv_u3d_req, req); + + kfree(req); +} + +static void mv_u3d_ep_fifo_flush(struct usb_ep *_ep) +{ + struct mv_u3d *u3d; + u32 direction; + struct mv_u3d_ep *ep = container_of(_ep, struct mv_u3d_ep, ep); + unsigned int loops; + u32 tmp; + + /* if endpoint is not enabled, cannot flush endpoint */ + if (!ep->enabled) + return; + + u3d = ep->u3d; + direction = mv_u3d_ep_dir(ep); + + /* ep0 need clear bit after flushing fifo. */ + if (!ep->ep_num) { + if (direction == MV_U3D_EP_DIR_OUT) { + tmp = ioread32(&u3d->vuc_regs->epcr[0].epxoutcr0); + tmp |= MV_U3D_EPXCR_EP_FLUSH; + iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxoutcr0); + udelay(10); + tmp &= ~MV_U3D_EPXCR_EP_FLUSH; + iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxoutcr0); + } else { + tmp = ioread32(&u3d->vuc_regs->epcr[0].epxincr0); + tmp |= MV_U3D_EPXCR_EP_FLUSH; + iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxincr0); + udelay(10); + tmp &= ~MV_U3D_EPXCR_EP_FLUSH; + iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxincr0); + } + return; + } + + if (direction == MV_U3D_EP_DIR_OUT) { + tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + tmp |= MV_U3D_EPXCR_EP_FLUSH; + iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + + /* Wait until flushing completed */ + loops = LOOPS(MV_U3D_FLUSH_TIMEOUT); + while (ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0) & + MV_U3D_EPXCR_EP_FLUSH) { + /* + * EP_FLUSH bit should be cleared to indicate this + * operation is complete + */ + if (loops == 0) { + dev_dbg(u3d->dev, + "EP FLUSH TIMEOUT for ep%d%s\n", ep->ep_num, + direction ? "in" : "out"); + return; + } + loops--; + udelay(LOOPS_USEC); + } + } else { /* EP_DIR_IN */ + tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + tmp |= MV_U3D_EPXCR_EP_FLUSH; + iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + + /* Wait until flushing completed */ + loops = LOOPS(MV_U3D_FLUSH_TIMEOUT); + while (ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0) & + MV_U3D_EPXCR_EP_FLUSH) { + /* + * EP_FLUSH bit should be cleared to indicate this + * operation is complete + */ + if (loops == 0) { + dev_dbg(u3d->dev, + "EP FLUSH TIMEOUT for ep%d%s\n", ep->ep_num, + direction ? "in" : "out"); + return; + } + loops--; + udelay(LOOPS_USEC); + } + } +} + +/* queues (submits) an I/O request to an endpoint */ +static int +mv_u3d_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) +{ + struct mv_u3d_ep *ep; + struct mv_u3d_req *req; + struct mv_u3d *u3d; + unsigned long flags; + int is_first_req = 0; + + if (unlikely(!_ep || !_req)) + return -EINVAL; + + ep = container_of(_ep, struct mv_u3d_ep, ep); + u3d = ep->u3d; + + req = container_of(_req, struct mv_u3d_req, req); + + if (!ep->ep_num + && u3d->ep0_state == MV_U3D_STATUS_STAGE + && !_req->length) { + dev_dbg(u3d->dev, "ep0 status stage\n"); + u3d->ep0_state = MV_U3D_WAIT_FOR_SETUP; + return 0; + } + + dev_dbg(u3d->dev, "%s: %s, req: 0x%x\n", + __func__, _ep->name, (u32)req); + + /* catch various bogus parameters */ + if (!req->req.complete || !req->req.buf + || !list_empty(&req->queue)) { + dev_err(u3d->dev, + "%s, bad params, _req: 0x%x," + "req->req.complete: 0x%x, req->req.buf: 0x%x," + "list_empty: 0x%x\n", + __func__, (u32)_req, + (u32)req->req.complete, (u32)req->req.buf, + (u32)list_empty(&req->queue)); + return -EINVAL; + } + if (unlikely(!ep->ep.desc)) { + dev_err(u3d->dev, "%s, bad ep\n", __func__); + return -EINVAL; + } + if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + if (req->req.length > ep->ep.maxpacket) + return -EMSGSIZE; + } + + if (!u3d->driver || u3d->gadget.speed == USB_SPEED_UNKNOWN) { + dev_err(u3d->dev, + "bad params of driver/speed\n"); + return -ESHUTDOWN; + } + + req->ep = ep; + + /* Software list handles usb request. */ + spin_lock_irqsave(&ep->req_lock, flags); + is_first_req = list_empty(&ep->req_list); + list_add_tail(&req->list, &ep->req_list); + spin_unlock_irqrestore(&ep->req_lock, flags); + if (!is_first_req) { + dev_dbg(u3d->dev, "list is not empty\n"); + return 0; + } + + dev_dbg(u3d->dev, "call mv_u3d_start_queue from usb_ep_queue\n"); + spin_lock_irqsave(&u3d->lock, flags); + mv_u3d_start_queue(ep); + spin_unlock_irqrestore(&u3d->lock, flags); + return 0; +} + +/* dequeues (cancels, unlinks) an I/O request from an endpoint */ +static int mv_u3d_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct mv_u3d_ep *ep; + struct mv_u3d_req *req; + struct mv_u3d *u3d; + struct mv_u3d_ep_context *ep_context; + struct mv_u3d_req *next_req; + + unsigned long flags; + int ret = 0; + + if (!_ep || !_req) + return -EINVAL; + + ep = container_of(_ep, struct mv_u3d_ep, ep); + u3d = ep->u3d; + + spin_lock_irqsave(&ep->u3d->lock, flags); + + /* make sure it's actually queued on this endpoint */ + list_for_each_entry(req, &ep->queue, queue) { + if (&req->req == _req) + break; + } + if (&req->req != _req) { + ret = -EINVAL; + goto out; + } + + /* The request is in progress, or completed but not dequeued */ + if (ep->queue.next == &req->queue) { + _req->status = -ECONNRESET; + mv_u3d_ep_fifo_flush(_ep); + + /* The request isn't the last request in this ep queue */ + if (req->queue.next != &ep->queue) { + dev_dbg(u3d->dev, + "it is the last request in this ep queue\n"); + ep_context = ep->ep_context; + next_req = list_entry(req->queue.next, + struct mv_u3d_req, queue); + + /* Point first TRB of next request to the EP context. */ + iowrite32((u32) next_req->trb_head, + &ep_context->trb_addr_lo); + } else { + struct mv_u3d_ep_context *ep_context; + ep_context = ep->ep_context; + ep_context->trb_addr_lo = 0; + ep_context->trb_addr_hi = 0; + } + + } else + WARN_ON(1); + + mv_u3d_done(ep, req, -ECONNRESET); + + /* remove the req from the ep req list */ + if (!list_empty(&ep->req_list)) { + struct mv_u3d_req *curr_req; + curr_req = list_entry(ep->req_list.next, + struct mv_u3d_req, list); + if (curr_req == req) { + list_del_init(&req->list); + ep->processing = 0; + } + } + +out: + spin_unlock_irqrestore(&ep->u3d->lock, flags); + return ret; +} + +static void +mv_u3d_ep_set_stall(struct mv_u3d *u3d, u8 ep_num, u8 direction, int stall) +{ + u32 tmp; + struct mv_u3d_ep *ep = u3d->eps; + + dev_dbg(u3d->dev, "%s\n", __func__); + if (direction == MV_U3D_EP_DIR_OUT) { + tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + if (stall) + tmp |= MV_U3D_EPXCR_EP_HALT; + else + tmp &= ~MV_U3D_EPXCR_EP_HALT; + iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); + } else { + tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + if (stall) + tmp |= MV_U3D_EPXCR_EP_HALT; + else + tmp &= ~MV_U3D_EPXCR_EP_HALT; + iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); + } +} + +static int mv_u3d_ep_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge) +{ + struct mv_u3d_ep *ep; + unsigned long flags = 0; + int status = 0; + struct mv_u3d *u3d; + + ep = container_of(_ep, struct mv_u3d_ep, ep); + u3d = ep->u3d; + if (!ep->ep.desc) { + status = -EINVAL; + goto out; + } + + if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + status = -EOPNOTSUPP; + goto out; + } + + /* + * Attempt to halt IN ep will fail if any transfer requests + * are still queue + */ + if (halt && (mv_u3d_ep_dir(ep) == MV_U3D_EP_DIR_IN) + && !list_empty(&ep->queue)) { + status = -EAGAIN; + goto out; + } + + spin_lock_irqsave(&ep->u3d->lock, flags); + mv_u3d_ep_set_stall(u3d, ep->ep_num, mv_u3d_ep_dir(ep), halt); + if (halt && wedge) + ep->wedge = 1; + else if (!halt) + ep->wedge = 0; + spin_unlock_irqrestore(&ep->u3d->lock, flags); + + if (ep->ep_num == 0) + u3d->ep0_dir = MV_U3D_EP_DIR_OUT; +out: + return status; +} + +static int mv_u3d_ep_set_halt(struct usb_ep *_ep, int halt) +{ + return mv_u3d_ep_set_halt_wedge(_ep, halt, 0); +} + +static int mv_u3d_ep_set_wedge(struct usb_ep *_ep) +{ + return mv_u3d_ep_set_halt_wedge(_ep, 1, 1); +} + +static struct usb_ep_ops mv_u3d_ep_ops = { + .enable = mv_u3d_ep_enable, + .disable = mv_u3d_ep_disable, + + .alloc_request = mv_u3d_alloc_request, + .free_request = mv_u3d_free_request, + + .queue = mv_u3d_ep_queue, + .dequeue = mv_u3d_ep_dequeue, + + .set_wedge = mv_u3d_ep_set_wedge, + .set_halt = mv_u3d_ep_set_halt, + .fifo_flush = mv_u3d_ep_fifo_flush, +}; + +static void mv_u3d_controller_stop(struct mv_u3d *u3d) +{ + u32 tmp; + + if (!u3d->clock_gating && u3d->vbus_valid_detect) + iowrite32(MV_U3D_INTR_ENABLE_VBUS_VALID, + &u3d->vuc_regs->intrenable); + else + iowrite32(0, &u3d->vuc_regs->intrenable); + iowrite32(~0x0, &u3d->vuc_regs->endcomplete); + iowrite32(~0x0, &u3d->vuc_regs->trbunderrun); + iowrite32(~0x0, &u3d->vuc_regs->trbcomplete); + iowrite32(~0x0, &u3d->vuc_regs->linkchange); + iowrite32(0x1, &u3d->vuc_regs->setuplock); + + /* Reset the RUN bit in the command register to stop USB */ + tmp = ioread32(&u3d->op_regs->usbcmd); + tmp &= ~MV_U3D_CMD_RUN_STOP; + iowrite32(tmp, &u3d->op_regs->usbcmd); + dev_dbg(u3d->dev, "after u3d_stop, USBCMD 0x%x\n", + ioread32(&u3d->op_regs->usbcmd)); +} + +static void mv_u3d_controller_start(struct mv_u3d *u3d) +{ + u32 usbintr; + u32 temp; + + /* enable link LTSSM state machine */ + temp = ioread32(&u3d->vuc_regs->ltssm); + temp |= MV_U3D_LTSSM_PHY_INIT_DONE; + iowrite32(temp, &u3d->vuc_regs->ltssm); + + /* Enable interrupts */ + usbintr = MV_U3D_INTR_ENABLE_LINK_CHG | MV_U3D_INTR_ENABLE_TXDESC_ERR | + MV_U3D_INTR_ENABLE_RXDESC_ERR | MV_U3D_INTR_ENABLE_TX_COMPLETE | + MV_U3D_INTR_ENABLE_RX_COMPLETE | MV_U3D_INTR_ENABLE_SETUP | + (u3d->vbus_valid_detect ? MV_U3D_INTR_ENABLE_VBUS_VALID : 0); + iowrite32(usbintr, &u3d->vuc_regs->intrenable); + + /* Enable ctrl ep */ + iowrite32(0x1, &u3d->vuc_regs->ctrlepenable); + + /* Set the Run bit in the command register */ + iowrite32(MV_U3D_CMD_RUN_STOP, &u3d->op_regs->usbcmd); + dev_dbg(u3d->dev, "after u3d_start, USBCMD 0x%x\n", + ioread32(&u3d->op_regs->usbcmd)); +} + +static int mv_u3d_controller_reset(struct mv_u3d *u3d) +{ + unsigned int loops; + u32 tmp; + + /* Stop the controller */ + tmp = ioread32(&u3d->op_regs->usbcmd); + tmp &= ~MV_U3D_CMD_RUN_STOP; + iowrite32(tmp, &u3d->op_regs->usbcmd); + + /* Reset the controller to get default values */ + iowrite32(MV_U3D_CMD_CTRL_RESET, &u3d->op_regs->usbcmd); + + /* wait for reset to complete */ + loops = LOOPS(MV_U3D_RESET_TIMEOUT); + while (ioread32(&u3d->op_regs->usbcmd) & MV_U3D_CMD_CTRL_RESET) { + if (loops == 0) { + dev_err(u3d->dev, + "Wait for RESET completed TIMEOUT\n"); + return -ETIMEDOUT; + } + loops--; + udelay(LOOPS_USEC); + } + + /* Configure the Endpoint Context Address */ + iowrite32(u3d->ep_context_dma, &u3d->op_regs->dcbaapl); + iowrite32(0, &u3d->op_regs->dcbaaph); + + return 0; +} + +static int mv_u3d_enable(struct mv_u3d *u3d) +{ + struct mv_usb_platform_data *pdata = u3d->dev->platform_data; + int retval; + + if (u3d->active) + return 0; + + if (!u3d->clock_gating) { + u3d->active = 1; + return 0; + } + + dev_dbg(u3d->dev, "enable u3d\n"); + clk_enable(u3d->clk); + if (pdata->phy_init) { + retval = pdata->phy_init(u3d->phy_regs); + if (retval) { + dev_err(u3d->dev, + "init phy error %d\n", retval); + clk_disable(u3d->clk); + return retval; + } + } + u3d->active = 1; + + return 0; +} + +static void mv_u3d_disable(struct mv_u3d *u3d) +{ + struct mv_usb_platform_data *pdata = u3d->dev->platform_data; + if (u3d->clock_gating && u3d->active) { + dev_dbg(u3d->dev, "disable u3d\n"); + if (pdata->phy_deinit) + pdata->phy_deinit(u3d->phy_regs); + clk_disable(u3d->clk); + u3d->active = 0; + } +} + +static int mv_u3d_vbus_session(struct usb_gadget *gadget, int is_active) +{ + struct mv_u3d *u3d; + unsigned long flags; + int retval = 0; + + u3d = container_of(gadget, struct mv_u3d, gadget); + + spin_lock_irqsave(&u3d->lock, flags); + + u3d->vbus_active = (is_active != 0); + dev_dbg(u3d->dev, "%s: softconnect %d, vbus_active %d\n", + __func__, u3d->softconnect, u3d->vbus_active); + /* + * 1. external VBUS detect: we can disable/enable clock on demand. + * 2. UDC VBUS detect: we have to enable clock all the time. + * 3. No VBUS detect: we have to enable clock all the time. + */ + if (u3d->driver && u3d->softconnect && u3d->vbus_active) { + retval = mv_u3d_enable(u3d); + if (retval == 0) { + /* + * after clock is disabled, we lost all the register + * context. We have to re-init registers + */ + mv_u3d_controller_reset(u3d); + mv_u3d_ep0_reset(u3d); + mv_u3d_controller_start(u3d); + } + } else if (u3d->driver && u3d->softconnect) { + if (!u3d->active) + goto out; + + /* stop all the transfer in queue*/ + mv_u3d_stop_activity(u3d, u3d->driver); + mv_u3d_controller_stop(u3d); + mv_u3d_disable(u3d); + } + +out: + spin_unlock_irqrestore(&u3d->lock, flags); + return retval; +} + +/* constrain controller's VBUS power usage + * This call is used by gadget drivers during SET_CONFIGURATION calls, + * reporting how much power the device may consume. For example, this + * could affect how quickly batteries are recharged. + * + * Returns zero on success, else negative errno. + */ +static int mv_u3d_vbus_draw(struct usb_gadget *gadget, unsigned mA) +{ + struct mv_u3d *u3d = container_of(gadget, struct mv_u3d, gadget); + + u3d->power = mA; + + return 0; +} + +static int mv_u3d_pullup(struct usb_gadget *gadget, int is_on) +{ + struct mv_u3d *u3d = container_of(gadget, struct mv_u3d, gadget); + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&u3d->lock, flags); + + dev_dbg(u3d->dev, "%s: softconnect %d, vbus_active %d\n", + __func__, u3d->softconnect, u3d->vbus_active); + u3d->softconnect = (is_on != 0); + if (u3d->driver && u3d->softconnect && u3d->vbus_active) { + retval = mv_u3d_enable(u3d); + if (retval == 0) { + /* + * after clock is disabled, we lost all the register + * context. We have to re-init registers + */ + mv_u3d_controller_reset(u3d); + mv_u3d_ep0_reset(u3d); + mv_u3d_controller_start(u3d); + } + } else if (u3d->driver && u3d->vbus_active) { + /* stop all the transfer in queue*/ + mv_u3d_stop_activity(u3d, u3d->driver); + mv_u3d_controller_stop(u3d); + mv_u3d_disable(u3d); + } + + spin_unlock_irqrestore(&u3d->lock, flags); + + return retval; +} + +static int mv_u3d_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) +{ + struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); + struct mv_usb_platform_data *pdata = u3d->dev->platform_data; + unsigned long flags; + + if (u3d->driver) + return -EBUSY; + + spin_lock_irqsave(&u3d->lock, flags); + + if (!u3d->clock_gating) { + clk_enable(u3d->clk); + if (pdata->phy_init) + pdata->phy_init(u3d->phy_regs); + } + + /* hook up the driver ... */ + driver->driver.bus = NULL; + u3d->driver = driver; + u3d->gadget.dev.driver = &driver->driver; + + u3d->ep0_dir = USB_DIR_OUT; + + spin_unlock_irqrestore(&u3d->lock, flags); + + u3d->vbus_valid_detect = 1; + + return 0; +} + +static int mv_u3d_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) +{ + struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); + struct mv_usb_platform_data *pdata = u3d->dev->platform_data; + unsigned long flags; + + u3d->vbus_valid_detect = 0; + spin_lock_irqsave(&u3d->lock, flags); + + /* enable clock to access controller register */ + clk_enable(u3d->clk); + if (pdata->phy_init) + pdata->phy_init(u3d->phy_regs); + + mv_u3d_controller_stop(u3d); + /* stop all usb activities */ + u3d->gadget.speed = USB_SPEED_UNKNOWN; + mv_u3d_stop_activity(u3d, driver); + mv_u3d_disable(u3d); + + if (pdata->phy_deinit) + pdata->phy_deinit(u3d->phy_regs); + clk_disable(u3d->clk); + + spin_unlock_irqrestore(&u3d->lock, flags); + + u3d->gadget.dev.driver = NULL; + u3d->driver = NULL; + + return 0; +} + +/* device controller usb_gadget_ops structure */ +static const struct usb_gadget_ops mv_u3d_ops = { + /* notify controller that VBUS is powered or not */ + .vbus_session = mv_u3d_vbus_session, + + /* constrain controller's VBUS power usage */ + .vbus_draw = mv_u3d_vbus_draw, + + .pullup = mv_u3d_pullup, + .udc_start = mv_u3d_start, + .udc_stop = mv_u3d_stop, +}; + +static int mv_u3d_eps_init(struct mv_u3d *u3d) +{ + struct mv_u3d_ep *ep; + char name[14]; + int i; + + /* initialize ep0, ep0 in/out use eps[1] */ + ep = &u3d->eps[1]; + ep->u3d = u3d; + strncpy(ep->name, "ep0", sizeof(ep->name)); + ep->ep.name = ep->name; + ep->ep.ops = &mv_u3d_ep_ops; + ep->wedge = 0; + ep->ep.maxpacket = MV_U3D_EP0_MAX_PKT_SIZE; + ep->ep_num = 0; + ep->ep.desc = &mv_u3d_ep0_desc; + INIT_LIST_HEAD(&ep->queue); + INIT_LIST_HEAD(&ep->req_list); + ep->ep_type = USB_ENDPOINT_XFER_CONTROL; + + /* add ep0 ep_context */ + ep->ep_context = &u3d->ep_context[1]; + + /* initialize other endpoints */ + for (i = 2; i < u3d->max_eps * 2; i++) { + ep = &u3d->eps[i]; + if (i & 1) { + snprintf(name, sizeof(name), "ep%din", i >> 1); + ep->direction = MV_U3D_EP_DIR_IN; + } else { + snprintf(name, sizeof(name), "ep%dout", i >> 1); + ep->direction = MV_U3D_EP_DIR_OUT; + } + ep->u3d = u3d; + strncpy(ep->name, name, sizeof(ep->name)); + ep->ep.name = ep->name; + + ep->ep.ops = &mv_u3d_ep_ops; + ep->ep.maxpacket = (unsigned short) ~0; + ep->ep_num = i / 2; + + INIT_LIST_HEAD(&ep->queue); + list_add_tail(&ep->ep.ep_list, &u3d->gadget.ep_list); + + INIT_LIST_HEAD(&ep->req_list); + spin_lock_init(&ep->req_lock); + ep->ep_context = &u3d->ep_context[i]; + } + + return 0; +} + +/* delete all endpoint requests, called with spinlock held */ +static void mv_u3d_nuke(struct mv_u3d_ep *ep, int status) +{ + /* endpoint fifo flush */ + mv_u3d_ep_fifo_flush(&ep->ep); + + while (!list_empty(&ep->queue)) { + struct mv_u3d_req *req = NULL; + req = list_entry(ep->queue.next, struct mv_u3d_req, queue); + mv_u3d_done(ep, req, status); + } +} + +/* stop all USB activities */ +static +void mv_u3d_stop_activity(struct mv_u3d *u3d, struct usb_gadget_driver *driver) +{ + struct mv_u3d_ep *ep; + + mv_u3d_nuke(&u3d->eps[1], -ESHUTDOWN); + + list_for_each_entry(ep, &u3d->gadget.ep_list, ep.ep_list) { + mv_u3d_nuke(ep, -ESHUTDOWN); + } + + /* report disconnect; the driver is already quiesced */ + if (driver) { + spin_unlock(&u3d->lock); + driver->disconnect(&u3d->gadget); + spin_lock(&u3d->lock); + } +} + +static void mv_u3d_irq_process_error(struct mv_u3d *u3d) +{ + /* Increment the error count */ + u3d->errors++; + dev_err(u3d->dev, "%s\n", __func__); +} + +static void mv_u3d_irq_process_link_change(struct mv_u3d *u3d) +{ + u32 linkchange; + + linkchange = ioread32(&u3d->vuc_regs->linkchange); + iowrite32(linkchange, &u3d->vuc_regs->linkchange); + + dev_dbg(u3d->dev, "linkchange: 0x%x\n", linkchange); + + if (linkchange & MV_U3D_LINK_CHANGE_LINK_UP) { + dev_dbg(u3d->dev, "link up: ltssm state: 0x%x\n", + ioread32(&u3d->vuc_regs->ltssmstate)); + + u3d->usb_state = USB_STATE_DEFAULT; + u3d->ep0_dir = MV_U3D_EP_DIR_OUT; + u3d->ep0_state = MV_U3D_WAIT_FOR_SETUP; + + /* set speed */ + u3d->gadget.speed = USB_SPEED_SUPER; + } + + if (linkchange & MV_U3D_LINK_CHANGE_SUSPEND) { + dev_dbg(u3d->dev, "link suspend\n"); + u3d->resume_state = u3d->usb_state; + u3d->usb_state = USB_STATE_SUSPENDED; + } + + if (linkchange & MV_U3D_LINK_CHANGE_RESUME) { + dev_dbg(u3d->dev, "link resume\n"); + u3d->usb_state = u3d->resume_state; + u3d->resume_state = 0; + } + + if (linkchange & MV_U3D_LINK_CHANGE_WRESET) { + dev_dbg(u3d->dev, "warm reset\n"); + u3d->usb_state = USB_STATE_POWERED; + } + + if (linkchange & MV_U3D_LINK_CHANGE_HRESET) { + dev_dbg(u3d->dev, "hot reset\n"); + u3d->usb_state = USB_STATE_DEFAULT; + } + + if (linkchange & MV_U3D_LINK_CHANGE_INACT) + dev_dbg(u3d->dev, "inactive\n"); + + if (linkchange & MV_U3D_LINK_CHANGE_DISABLE_AFTER_U0) + dev_dbg(u3d->dev, "ss.disabled\n"); + + if (linkchange & MV_U3D_LINK_CHANGE_VBUS_INVALID) { + dev_dbg(u3d->dev, "vbus invalid\n"); + u3d->usb_state = USB_STATE_ATTACHED; + u3d->vbus_valid_detect = 1; + /* if external vbus detect is not supported, + * we handle it here. + */ + if (!u3d->vbus) { + spin_unlock(&u3d->lock); + mv_u3d_vbus_session(&u3d->gadget, 0); + spin_lock(&u3d->lock); + } + } +} + +static void mv_u3d_ch9setaddress(struct mv_u3d *u3d, + struct usb_ctrlrequest *setup) +{ + u32 tmp; + + if (u3d->usb_state != USB_STATE_DEFAULT) { + dev_err(u3d->dev, + "%s, cannot setaddr in this state (%d)\n", + __func__, u3d->usb_state); + goto err; + } + + u3d->dev_addr = (u8)setup->wValue; + + dev_dbg(u3d->dev, "%s: 0x%x\n", __func__, u3d->dev_addr); + + if (u3d->dev_addr > 127) { + dev_err(u3d->dev, + "%s, u3d address is wrong (out of range)\n", __func__); + u3d->dev_addr = 0; + goto err; + } + + /* update usb state */ + u3d->usb_state = USB_STATE_ADDRESS; + + /* set the new address */ + tmp = ioread32(&u3d->vuc_regs->devaddrtiebrkr); + tmp &= ~0x7F; + tmp |= (u32)u3d->dev_addr; + iowrite32(tmp, &u3d->vuc_regs->devaddrtiebrkr); + + return; +err: + mv_u3d_ep0_stall(u3d); +} + +static int mv_u3d_is_set_configuration(struct usb_ctrlrequest *setup) +{ + if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) + if (setup->bRequest == USB_REQ_SET_CONFIGURATION) + return 1; + + return 0; +} + +static void mv_u3d_handle_setup_packet(struct mv_u3d *u3d, u8 ep_num, + struct usb_ctrlrequest *setup) +{ + bool delegate = false; + + mv_u3d_nuke(&u3d->eps[ep_num * 2 + MV_U3D_EP_DIR_IN], -ESHUTDOWN); + + dev_dbg(u3d->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", + setup->bRequestType, setup->bRequest, + setup->wValue, setup->wIndex, setup->wLength); + + /* We process some stardard setup requests here */ + if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { + switch (setup->bRequest) { + case USB_REQ_GET_STATUS: + delegate = true; + break; + + case USB_REQ_SET_ADDRESS: + mv_u3d_ch9setaddress(u3d, setup); + break; + + case USB_REQ_CLEAR_FEATURE: + delegate = true; + break; + + case USB_REQ_SET_FEATURE: + delegate = true; + break; + + default: + delegate = true; + } + } else + delegate = true; + + /* delegate USB standard requests to the gadget driver */ + if (delegate == true) { + /* USB requests handled by gadget */ + if (setup->wLength) { + /* DATA phase from gadget, STATUS phase from u3d */ + u3d->ep0_dir = (setup->bRequestType & USB_DIR_IN) + ? MV_U3D_EP_DIR_IN : MV_U3D_EP_DIR_OUT; + spin_unlock(&u3d->lock); + if (u3d->driver->setup(&u3d->gadget, + &u3d->local_setup_buff) < 0) { + dev_err(u3d->dev, "setup error!\n"); + mv_u3d_ep0_stall(u3d); + } + spin_lock(&u3d->lock); + } else { + /* no DATA phase, STATUS phase from gadget */ + u3d->ep0_dir = MV_U3D_EP_DIR_IN; + u3d->ep0_state = MV_U3D_STATUS_STAGE; + spin_unlock(&u3d->lock); + if (u3d->driver->setup(&u3d->gadget, + &u3d->local_setup_buff) < 0) + mv_u3d_ep0_stall(u3d); + spin_lock(&u3d->lock); + } + + if (mv_u3d_is_set_configuration(setup)) { + dev_dbg(u3d->dev, "u3d configured\n"); + u3d->usb_state = USB_STATE_CONFIGURED; + } + } +} + +static void mv_u3d_get_setup_data(struct mv_u3d *u3d, u8 ep_num, u8 *buffer_ptr) +{ + struct mv_u3d_ep_context *epcontext; + + epcontext = &u3d->ep_context[ep_num * 2 + MV_U3D_EP_DIR_IN]; + + /* Copy the setup packet to local buffer */ + memcpy(buffer_ptr, (u8 *) &epcontext->setup_buffer, 8); +} + +static void mv_u3d_irq_process_setup(struct mv_u3d *u3d) +{ + u32 tmp, i; + /* Process all Setup packet received interrupts */ + tmp = ioread32(&u3d->vuc_regs->setuplock); + if (tmp) { + for (i = 0; i < u3d->max_eps; i++) { + if (tmp & (1 << i)) { + mv_u3d_get_setup_data(u3d, i, + (u8 *)(&u3d->local_setup_buff)); + mv_u3d_handle_setup_packet(u3d, i, + &u3d->local_setup_buff); + } + } + } + + iowrite32(tmp, &u3d->vuc_regs->setuplock); +} + +static void mv_u3d_irq_process_tr_complete(struct mv_u3d *u3d) +{ + u32 tmp, bit_pos; + int i, ep_num = 0, direction = 0; + struct mv_u3d_ep *curr_ep; + struct mv_u3d_req *curr_req, *temp_req; + int status; + + tmp = ioread32(&u3d->vuc_regs->endcomplete); + + dev_dbg(u3d->dev, "tr_complete: ep: 0x%x\n", tmp); + if (!tmp) + return; + iowrite32(tmp, &u3d->vuc_regs->endcomplete); + + for (i = 0; i < u3d->max_eps * 2; i++) { + ep_num = i >> 1; + direction = i % 2; + + bit_pos = 1 << (ep_num + 16 * direction); + + if (!(bit_pos & tmp)) + continue; + + if (i == 0) + curr_ep = &u3d->eps[1]; + else + curr_ep = &u3d->eps[i]; + + /* remove req out of ep request list after completion */ + dev_dbg(u3d->dev, "tr comp: check req_list\n"); + spin_lock(&curr_ep->req_lock); + if (!list_empty(&curr_ep->req_list)) { + struct mv_u3d_req *req; + req = list_entry(curr_ep->req_list.next, + struct mv_u3d_req, list); + list_del_init(&req->list); + curr_ep->processing = 0; + } + spin_unlock(&curr_ep->req_lock); + + /* process the req queue until an uncomplete request */ + list_for_each_entry_safe(curr_req, temp_req, + &curr_ep->queue, queue) { + status = mv_u3d_process_ep_req(u3d, i, curr_req); + if (status) + break; + /* write back status to req */ + curr_req->req.status = status; + + /* ep0 request completion */ + if (ep_num == 0) { + mv_u3d_done(curr_ep, curr_req, 0); + break; + } else { + mv_u3d_done(curr_ep, curr_req, status); + } + } + + dev_dbg(u3d->dev, "call mv_u3d_start_queue from ep complete\n"); + mv_u3d_start_queue(curr_ep); + } +} + +static irqreturn_t mv_u3d_irq(int irq, void *dev) +{ + struct mv_u3d *u3d = (struct mv_u3d *)dev; + u32 status, intr; + u32 bridgesetting; + u32 trbunderrun; + + spin_lock(&u3d->lock); + + status = ioread32(&u3d->vuc_regs->intrcause); + intr = ioread32(&u3d->vuc_regs->intrenable); + status &= intr; + + if (status == 0) { + spin_unlock(&u3d->lock); + dev_err(u3d->dev, "irq error!\n"); + return IRQ_NONE; + } + + if (status & MV_U3D_USBINT_VBUS_VALID) { + bridgesetting = ioread32(&u3d->vuc_regs->bridgesetting); + if (bridgesetting & MV_U3D_BRIDGE_SETTING_VBUS_VALID) { + /* write vbus valid bit of bridge setting to clear */ + bridgesetting = MV_U3D_BRIDGE_SETTING_VBUS_VALID; + iowrite32(bridgesetting, &u3d->vuc_regs->bridgesetting); + dev_dbg(u3d->dev, "vbus valid\n"); + + u3d->usb_state = USB_STATE_POWERED; + u3d->vbus_valid_detect = 0; + /* if external vbus detect is not supported, + * we handle it here. + */ + if (!u3d->vbus) { + spin_unlock(&u3d->lock); + mv_u3d_vbus_session(&u3d->gadget, 1); + spin_lock(&u3d->lock); + } + } else + dev_err(u3d->dev, "vbus bit is not set\n"); + } + + /* RX data is already in the 16KB FIFO.*/ + if (status & MV_U3D_USBINT_UNDER_RUN) { + trbunderrun = ioread32(&u3d->vuc_regs->trbunderrun); + dev_err(u3d->dev, "under run, ep%d\n", trbunderrun); + iowrite32(trbunderrun, &u3d->vuc_regs->trbunderrun); + mv_u3d_irq_process_error(u3d); + } + + if (status & (MV_U3D_USBINT_RXDESC_ERR | MV_U3D_USBINT_TXDESC_ERR)) { + /* write one to clear */ + iowrite32(status & (MV_U3D_USBINT_RXDESC_ERR + | MV_U3D_USBINT_TXDESC_ERR), + &u3d->vuc_regs->intrcause); + dev_err(u3d->dev, "desc err 0x%x\n", status); + mv_u3d_irq_process_error(u3d); + } + + if (status & MV_U3D_USBINT_LINK_CHG) + mv_u3d_irq_process_link_change(u3d); + + if (status & MV_U3D_USBINT_TX_COMPLETE) + mv_u3d_irq_process_tr_complete(u3d); + + if (status & MV_U3D_USBINT_RX_COMPLETE) + mv_u3d_irq_process_tr_complete(u3d); + + if (status & MV_U3D_USBINT_SETUP) + mv_u3d_irq_process_setup(u3d); + + spin_unlock(&u3d->lock); + return IRQ_HANDLED; +} + +static void mv_u3d_gadget_release(struct device *dev) +{ + dev_dbg(dev, "%s\n", __func__); +} + +static __devexit int mv_u3d_remove(struct platform_device *dev) +{ + struct mv_u3d *u3d = platform_get_drvdata(dev); + + BUG_ON(u3d == NULL); + + usb_del_gadget_udc(&u3d->gadget); + + /* free memory allocated in probe */ + if (u3d->trb_pool) + dma_pool_destroy(u3d->trb_pool); + + if (u3d->ep_context) + dma_free_coherent(&dev->dev, u3d->ep_context_size, + u3d->ep_context, u3d->ep_context_dma); + + kfree(u3d->eps); + + if (u3d->irq) + free_irq(u3d->irq, &dev->dev); + + if (u3d->cap_regs) + iounmap(u3d->cap_regs); + u3d->cap_regs = NULL; + + kfree(u3d->status_req); + + clk_put(u3d->clk); + + device_unregister(&u3d->gadget.dev); + + platform_set_drvdata(dev, NULL); + + kfree(u3d); + + return 0; +} + +static int mv_u3d_probe(struct platform_device *dev) +{ + struct mv_u3d *u3d = NULL; + struct mv_usb_platform_data *pdata = dev->dev.platform_data; + int retval = 0; + struct resource *r; + size_t size; + + if (!dev->dev.platform_data) { + dev_err(&dev->dev, "missing platform_data\n"); + retval = -ENODEV; + goto err_pdata; + } + + u3d = kzalloc(sizeof(*u3d), GFP_KERNEL); + if (!u3d) { + dev_err(&dev->dev, "failed to allocate memory for u3d\n"); + retval = -ENOMEM; + goto err_alloc_private; + } + + spin_lock_init(&u3d->lock); + + platform_set_drvdata(dev, u3d); + + u3d->dev = &dev->dev; + u3d->vbus = pdata->vbus; + + u3d->clk = clk_get(&dev->dev, pdata->clkname[0]); + if (IS_ERR(u3d->clk)) { + retval = PTR_ERR(u3d->clk); + goto err_get_clk; + } + + r = platform_get_resource_byname(dev, IORESOURCE_MEM, "capregs"); + if (!r) { + dev_err(&dev->dev, "no I/O memory resource defined\n"); + retval = -ENODEV; + goto err_get_cap_regs; + } + + u3d->cap_regs = (struct mv_u3d_cap_regs __iomem *) + ioremap(r->start, resource_size(r)); + if (!u3d->cap_regs) { + dev_err(&dev->dev, "failed to map I/O memory\n"); + retval = -EBUSY; + goto err_map_cap_regs; + } else { + dev_dbg(&dev->dev, "cap_regs address: 0x%x/0x%x\n", + (unsigned int)r->start, (unsigned int)u3d->cap_regs); + } + + /* we will access controller register, so enable the u3d controller */ + clk_enable(u3d->clk); + + if (pdata->phy_init) { + retval = pdata->phy_init(u3d->phy_regs); + if (retval) { + dev_err(&dev->dev, "init phy error %d\n", retval); + goto err_u3d_enable; + } + } + + u3d->op_regs = (struct mv_u3d_op_regs __iomem *)((u32)u3d->cap_regs + + MV_U3D_USB3_OP_REGS_OFFSET); + + u3d->vuc_regs = (struct mv_u3d_vuc_regs __iomem *)((u32)u3d->cap_regs + + ioread32(&u3d->cap_regs->vuoff)); + + u3d->max_eps = 16; + + /* + * some platform will use usb to download image, it may not disconnect + * usb gadget before loading kernel. So first stop u3d here. + */ + mv_u3d_controller_stop(u3d); + iowrite32(0xFFFFFFFF, &u3d->vuc_regs->intrcause); + + if (pdata->phy_deinit) + pdata->phy_deinit(u3d->phy_regs); + clk_disable(u3d->clk); + + size = u3d->max_eps * sizeof(struct mv_u3d_ep_context) * 2; + size = (size + MV_U3D_EP_CONTEXT_ALIGNMENT - 1) + & ~(MV_U3D_EP_CONTEXT_ALIGNMENT - 1); + u3d->ep_context = dma_alloc_coherent(&dev->dev, size, + &u3d->ep_context_dma, GFP_KERNEL); + if (!u3d->ep_context) { + dev_err(&dev->dev, "allocate ep context memory failed\n"); + retval = -ENOMEM; + goto err_alloc_ep_context; + } + u3d->ep_context_size = size; + + /* create TRB dma_pool resource */ + u3d->trb_pool = dma_pool_create("u3d_trb", + &dev->dev, + sizeof(struct mv_u3d_trb_hw), + MV_U3D_TRB_ALIGNMENT, + MV_U3D_DMA_BOUNDARY); + + if (!u3d->trb_pool) { + retval = -ENOMEM; + goto err_alloc_trb_pool; + } + + size = u3d->max_eps * sizeof(struct mv_u3d_ep) * 2; + u3d->eps = kzalloc(size, GFP_KERNEL); + if (!u3d->eps) { + dev_err(&dev->dev, "allocate ep memory failed\n"); + retval = -ENOMEM; + goto err_alloc_eps; + } + + /* initialize ep0 status request structure */ + u3d->status_req = kzalloc(sizeof(struct mv_u3d_req) + 8, GFP_KERNEL); + if (!u3d->status_req) { + dev_err(&dev->dev, "allocate status_req memory failed\n"); + retval = -ENOMEM; + goto err_alloc_status_req; + } + INIT_LIST_HEAD(&u3d->status_req->queue); + + /* allocate a small amount of memory to get valid address */ + u3d->status_req->req.buf = (char *)u3d->status_req + + sizeof(struct mv_u3d_req); + u3d->status_req->req.dma = virt_to_phys(u3d->status_req->req.buf); + + u3d->resume_state = USB_STATE_NOTATTACHED; + u3d->usb_state = USB_STATE_ATTACHED; + u3d->ep0_dir = MV_U3D_EP_DIR_OUT; + u3d->remote_wakeup = 0; + + r = platform_get_resource(dev, IORESOURCE_IRQ, 0); + if (!r) { + dev_err(&dev->dev, "no IRQ resource defined\n"); + retval = -ENODEV; + goto err_get_irq; + } + u3d->irq = r->start; + if (request_irq(u3d->irq, mv_u3d_irq, + IRQF_DISABLED | IRQF_SHARED, driver_name, u3d)) { + u3d->irq = 0; + dev_err(&dev->dev, "Request irq %d for u3d failed\n", + u3d->irq); + retval = -ENODEV; + goto err_request_irq; + } + + /* initialize gadget structure */ + u3d->gadget.ops = &mv_u3d_ops; /* usb_gadget_ops */ + u3d->gadget.ep0 = &u3d->eps[1].ep; /* gadget ep0 */ + INIT_LIST_HEAD(&u3d->gadget.ep_list); /* ep_list */ + u3d->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ + + /* the "gadget" abstracts/virtualizes the controller */ + dev_set_name(&u3d->gadget.dev, "gadget"); + u3d->gadget.dev.parent = &dev->dev; + u3d->gadget.dev.dma_mask = dev->dev.dma_mask; + u3d->gadget.dev.release = mv_u3d_gadget_release; + u3d->gadget.name = driver_name; /* gadget name */ + + retval = device_register(&u3d->gadget.dev); + if (retval) + goto err_register_gadget_device; + + mv_u3d_eps_init(u3d); + + /* external vbus detection */ + if (u3d->vbus) { + u3d->clock_gating = 1; + dev_err(&dev->dev, "external vbus detection\n"); + } + + if (!u3d->clock_gating) + u3d->vbus_active = 1; + + /* enable usb3 controller vbus detection */ + u3d->vbus_valid_detect = 1; + + retval = usb_add_gadget_udc(&dev->dev, &u3d->gadget); + if (retval) + goto err_unregister; + + dev_dbg(&dev->dev, "successful probe usb3 device %s clock gating.\n", + u3d->clock_gating ? "with" : "without"); + + return 0; + +err_unregister: + device_unregister(&u3d->gadget.dev); +err_register_gadget_device: + free_irq(u3d->irq, &dev->dev); +err_request_irq: +err_get_irq: + kfree(u3d->status_req); +err_alloc_status_req: + kfree(u3d->eps); +err_alloc_eps: + dma_pool_destroy(u3d->trb_pool); +err_alloc_trb_pool: + dma_free_coherent(&dev->dev, u3d->ep_context_size, + u3d->ep_context, u3d->ep_context_dma); +err_alloc_ep_context: + if (pdata->phy_deinit) + pdata->phy_deinit(u3d->phy_regs); + clk_disable(u3d->clk); +err_u3d_enable: + iounmap(u3d->cap_regs); +err_map_cap_regs: +err_get_cap_regs: +err_get_clk: + clk_put(u3d->clk); + platform_set_drvdata(dev, NULL); + kfree(u3d); +err_alloc_private: +err_pdata: + return retval; +} + +#ifdef CONFIG_PM +static int mv_u3d_suspend(struct device *dev) +{ + struct mv_u3d *u3d = dev_get_drvdata(dev); + + /* + * only cable is unplugged, usb can suspend. + * So do not care about clock_gating == 1, it is handled by + * vbus session. + */ + if (!u3d->clock_gating) { + mv_u3d_controller_stop(u3d); + + spin_lock_irq(&u3d->lock); + /* stop all usb activities */ + mv_u3d_stop_activity(u3d, u3d->driver); + spin_unlock_irq(&u3d->lock); + + mv_u3d_disable(u3d); + } + + return 0; +} + +static int mv_u3d_resume(struct device *dev) +{ + struct mv_u3d *u3d = dev_get_drvdata(dev); + int retval; + + if (!u3d->clock_gating) { + retval = mv_u3d_enable(u3d); + if (retval) + return retval; + + if (u3d->driver && u3d->softconnect) { + mv_u3d_controller_reset(u3d); + mv_u3d_ep0_reset(u3d); + mv_u3d_controller_start(u3d); + } + } + + return 0; +} + +SIMPLE_DEV_PM_OPS(mv_u3d_pm_ops, mv_u3d_suspend, mv_u3d_resume); +#endif + +static void mv_u3d_shutdown(struct platform_device *dev) +{ + struct mv_u3d *u3d = dev_get_drvdata(&dev->dev); + u32 tmp; + + tmp = ioread32(&u3d->op_regs->usbcmd); + tmp &= ~MV_U3D_CMD_RUN_STOP; + iowrite32(tmp, &u3d->op_regs->usbcmd); +} + +static struct platform_driver mv_u3d_driver = { + .probe = mv_u3d_probe, + .remove = __exit_p(mv_u3d_remove), + .shutdown = mv_u3d_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = "mv-u3d", +#ifdef CONFIG_PM + .pm = &mv_u3d_pm_ops, +#endif + }, +}; + +module_platform_driver(mv_u3d_driver); +MODULE_ALIAS("platform:mv-u3d"); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Yu Xu "); +MODULE_LICENSE("GPL"); -- GitLab From ba789170d251a3c47854cee8a492d8ba7345f468 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 15 Jun 2012 18:39:02 -0300 Subject: [PATCH 2447/6849] usb: gadget: fsl_mxc_udc: do not depend on grouped clocks With the new common clock infrastructure, the following clocks should be used on i.MX drivers: ipg, per and ahb. Adapt fsl_mxc_udc to follow this new behaviour to fix the following probe error: Freescale High-Speed USB SOC Device Controller driver (Apr 20, 2007) fsl-usb2-udc fsl-usb2-udc: clk_get("usb") failed fsl-usb2-udc: probe of fsl-usb2-udc failed with error -2 Reported-by: Christoph Fritz Signed-off-by: Fabio Estevam Acked-by: Sascha Hauer Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_mxc_udc.c | 74 +++++++++++++------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index f4b5109feb3d..1b0f086426bd 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c @@ -21,7 +21,8 @@ #include static struct clk *mxc_ahb_clk; -static struct clk *mxc_usb_clk; +static struct clk *mxc_per_clk; +static struct clk *mxc_ipg_clk; /* workaround ENGcm09152 for i.MX35 */ #define USBPHYCTRL_OTGBASE_OFFSET 0x608 @@ -35,28 +36,31 @@ int fsl_udc_clk_init(struct platform_device *pdev) pdata = pdev->dev.platform_data; - if (!cpu_is_mx35() && !cpu_is_mx25()) { - mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb"); - if (IS_ERR(mxc_ahb_clk)) - return PTR_ERR(mxc_ahb_clk); + mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(mxc_ipg_clk)) { + dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n"); + return PTR_ERR(mxc_ipg_clk); + } - ret = clk_prepare_enable(mxc_ahb_clk); - if (ret < 0) { - dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); - goto eenahb; - } + mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb"); + if (IS_ERR(mxc_ahb_clk)) { + dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n"); + return PTR_ERR(mxc_ahb_clk); } - /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ - mxc_usb_clk = clk_get(&pdev->dev, "usb"); - if (IS_ERR(mxc_usb_clk)) { - dev_err(&pdev->dev, "clk_get(\"usb\") failed\n"); - ret = PTR_ERR(mxc_usb_clk); - goto egusb; + mxc_per_clk = devm_clk_get(&pdev->dev, "per"); + if (IS_ERR(mxc_per_clk)) { + dev_err(&pdev->dev, "clk_get(\"per\") failed\n"); + return PTR_ERR(mxc_per_clk); } + clk_prepare_enable(mxc_ipg_clk); + clk_prepare_enable(mxc_ahb_clk); + clk_prepare_enable(mxc_per_clk); + + /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ if (!cpu_is_mx51()) { - freq = clk_get_rate(mxc_usb_clk); + freq = clk_get_rate(mxc_per_clk); if (pdata->phy_mode != FSL_USB2_PHY_ULPI && (freq < 59999000 || freq > 60001000)) { dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); @@ -65,24 +69,13 @@ int fsl_udc_clk_init(struct platform_device *pdev) } } - ret = clk_prepare_enable(mxc_usb_clk); - if (ret < 0) { - dev_err(&pdev->dev, "clk_enable(\"usb_clk\") failed\n"); - goto eenusb; - } - return 0; -eenusb: eclkrate: - clk_put(mxc_usb_clk); - mxc_usb_clk = NULL; -egusb: - if (!cpu_is_mx35()) - clk_disable_unprepare(mxc_ahb_clk); -eenahb: - if (!cpu_is_mx35()) - clk_put(mxc_ahb_clk); + clk_disable_unprepare(mxc_ipg_clk); + clk_disable_unprepare(mxc_ahb_clk); + clk_disable_unprepare(mxc_per_clk); + mxc_per_clk = NULL; return ret; } @@ -104,20 +97,15 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) /* ULPI transceivers don't need usbpll */ if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { - clk_disable_unprepare(mxc_usb_clk); - clk_put(mxc_usb_clk); - mxc_usb_clk = NULL; + clk_disable_unprepare(mxc_per_clk); + mxc_per_clk = NULL; } } void fsl_udc_clk_release(void) { - if (mxc_usb_clk) { - clk_disable_unprepare(mxc_usb_clk); - clk_put(mxc_usb_clk); - } - if (!cpu_is_mx35()) { - clk_disable_unprepare(mxc_ahb_clk); - clk_put(mxc_ahb_clk); - } + if (mxc_per_clk) + clk_disable_unprepare(mxc_per_clk); + clk_disable_unprepare(mxc_ahb_clk); + clk_disable_unprepare(mxc_ipg_clk); } -- GitLab From 508566998b8de0a95e39da9d35893df9e212328d Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 20 Jun 2012 09:03:15 -0300 Subject: [PATCH 2448/6849] usb: gadget: lpc32xx_udc: move clock init to clock framework Moves clock initialization to the clock framework. Signed-off-by: Alexandre Pereira da Silva Acked-by: Roland Stigge Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 84 +++++++++----------------------- 1 file changed, 24 insertions(+), 60 deletions(-) diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 262acfd53e32..d227d93ce899 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -164,6 +164,7 @@ struct lpc32xx_udc { int udp_irq[4]; struct clk *usb_pll_clk; struct clk *usb_slv_clk; + struct clk *usb_otg_clk; /* DMA support */ u32 *udca_v_base; @@ -226,33 +227,15 @@ static inline struct lpc32xx_udc *to_udc(struct usb_gadget *g) #define UDCA_BUFF_SIZE (128) /* TODO: When the clock framework is introduced in LPC32xx, IO_ADDRESS will - * be replaced with an inremap()ed pointer, see USB_OTG_CLK_CTRL() + * be replaced with an inremap()ed pointer * */ #define USB_CTRL IO_ADDRESS(LPC32XX_CLK_PM_BASE + 0x64) -#define USB_CLOCK_MASK (AHB_M_CLOCK_ON | OTG_CLOCK_ON | \ - DEV_CLOCK_ON | I2C_CLOCK_ON) /* USB_CTRL bit defines */ #define USB_SLAVE_HCLK_EN (1 << 24) #define USB_HOST_NEED_CLK_EN (1 << 21) #define USB_DEV_NEED_CLK_EN (1 << 22) -#define USB_OTG_CLK_CTRL(udc) ((udc)->udp_baseaddr + 0xFF4) -#define USB_OTG_CLK_STAT(udc) ((udc)->udp_baseaddr + 0xFF8) - -/* USB_OTG_CLK_CTRL bit defines */ -#define AHB_M_CLOCK_ON (1 << 4) -#define OTG_CLOCK_ON (1 << 3) -#define I2C_CLOCK_ON (1 << 2) -#define DEV_CLOCK_ON (1 << 1) -#define HOST_CLOCK_ON (1 << 0) - -#define USB_OTG_STAT_CONTROL(udc) (udc->udp_baseaddr + 0x110) - -/* USB_OTG_STAT_CONTROL bit defines */ -#define TRANSPARENT_I2C_EN (1 << 7) -#define HOST_EN (1 << 0) - /********************************************************************** * USB device controller register offsets **********************************************************************/ @@ -676,7 +659,7 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc) ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD); /* Enable usb_need_clk clock after transceiver is initialized */ - writel((readl(USB_CTRL) | (1 << 22)), USB_CTRL); + writel((readl(USB_CTRL) | USB_DEV_NEED_CLK_EN), USB_CTRL); dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00)); @@ -1009,11 +992,8 @@ static void udc_dd_free(struct lpc32xx_udc *udc, struct lpc32xx_usbd_dd_gad *dd) /* Enables or disables most of the USB system clocks when low power mode is * needed. Clocks are typically started on a connection event, and disabled * when a cable is disconnected */ -#define OTGOFF_CLK_MASK (AHB_M_CLOCK_ON | I2C_CLOCK_ON) static void udc_clk_set(struct lpc32xx_udc *udc, int enable) { - int to = 1000; - if (enable != 0) { if (udc->clocked) return; @@ -1027,14 +1007,7 @@ static void udc_clk_set(struct lpc32xx_udc *udc, int enable) writel(readl(USB_CTRL) | USB_DEV_NEED_CLK_EN, USB_CTRL); - /* Set to enable all needed USB OTG clocks */ - writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc)); - - while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) != - USB_CLOCK_MASK) && (to > 0)) - to--; - if (!to) - dev_dbg(udc->dev, "Cannot enable USB OTG clocking\n"); + clk_enable(udc->usb_otg_clk); } else { if (!udc->clocked) return; @@ -1046,19 +1019,11 @@ static void udc_clk_set(struct lpc32xx_udc *udc, int enable) /* 48MHz PLL dpwn */ clk_disable(udc->usb_pll_clk); - /* Enable the USB device clock */ + /* Disable the USB device clock */ writel(readl(USB_CTRL) & ~USB_DEV_NEED_CLK_EN, USB_CTRL); - /* Set to enable all needed USB OTG clocks */ - writel(OTGOFF_CLK_MASK, USB_OTG_CLK_CTRL(udc)); - - while (((readl(USB_OTG_CLK_STAT(udc)) & - OTGOFF_CLK_MASK) != - OTGOFF_CLK_MASK) && (to > 0)) - to--; - if (!to) - dev_dbg(udc->dev, "Cannot disable USB OTG clocking\n"); + clk_disable(udc->usb_otg_clk); } } @@ -3238,6 +3203,12 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) retval = PTR_ERR(udc->usb_slv_clk); goto usb_clk_get_fail; } + udc->usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); + if (IS_ERR(udc->usb_otg_clk)) { + dev_err(udc->dev, "failed to acquire USB otg clock\n"); + retval = PTR_ERR(udc->usb_slv_clk); + goto usb_otg_clk_get_fail; + } /* Setup PLL clock to 48MHz */ retval = clk_enable(udc->usb_pll_clk); @@ -3261,15 +3232,12 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) goto usb_clk_enable_fail; } - /* Set to enable all needed USB OTG clocks */ - writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc)); - - i = 1000; - while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) != - USB_CLOCK_MASK) && (i > 0)) - i--; - if (!i) - dev_dbg(udc->dev, "USB OTG clocks not correctly enabled\n"); + /* Enable USB OTG clock */ + retval = clk_enable(udc->usb_otg_clk); + if (retval < 0) { + dev_err(udc->dev, "failed to start USB otg clock\n"); + goto usb_otg_clk_enable_fail; + } /* Setup deferred workqueue data */ udc->poweron = udc->pullup = 0; @@ -3389,12 +3357,16 @@ dma_alloc_fail: dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); i2c_fail: + clk_disable(udc->usb_otg_clk); +usb_otg_clk_enable_fail: clk_disable(udc->usb_slv_clk); usb_clk_enable_fail: pll_set_fail: clk_disable(udc->usb_pll_clk); pll_enable_fail: clk_put(udc->usb_slv_clk); +usb_otg_clk_get_fail: + clk_put(udc->usb_otg_clk); usb_clk_get_fail: clk_put(udc->usb_pll_clk); pll_get_fail: @@ -3432,6 +3404,8 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev) device_unregister(&udc->gadget.dev); + clk_disable(udc->usb_otg_clk); + clk_put(udc->usb_otg_clk); clk_disable(udc->usb_slv_clk); clk_put(udc->usb_slv_clk); clk_disable(udc->usb_pll_clk); @@ -3445,7 +3419,6 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg) { - int to = 1000; struct lpc32xx_udc *udc = platform_get_drvdata(pdev); if (udc->clocked) { @@ -3460,15 +3433,6 @@ static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg) on resume */ udc->clocked = 1; - /* Kill OTG and I2C clocks */ - writel(0, USB_OTG_CLK_CTRL(udc)); - while (((readl(USB_OTG_CLK_STAT(udc)) & OTGOFF_CLK_MASK) != - OTGOFF_CLK_MASK) && (to > 0)) - to--; - if (!to) - dev_dbg(udc->dev, - "USB OTG clocks not correctly enabled\n"); - /* Kill global USB clock */ clk_disable(udc->usb_slv_clk); } -- GitLab From 6f47209b271661ecd5929397cbe646ff247f01b6 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Fri, 22 Jun 2012 14:16:19 +1000 Subject: [PATCH 2449/6849] usb: gadget: acm_ms: need to set max_speed Failing to set max_speed prevents g_acm_ms working with many drivers which check for driver->max_speed < USB_SPEED_FULL, including pxa25x_udc Signed-off-by: Steve Bennett Signed-off-by: Felipe Balbi --- drivers/usb/gadget/acm_ms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index fdb7aec3bd0c..75b8a691fd00 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -235,6 +235,7 @@ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) static struct usb_composite_driver acm_ms_driver = { .name = "g_acm_ms", .dev = &device_desc, + .max_speed = USB_SPEED_SUPER, .strings = dev_strings, .unbind = __exit_p(acm_ms_unbind), }; -- GitLab From dc8738d95bb45d20b2141f1fe3e1cafb05be09f9 Mon Sep 17 00:00:00 2001 From: Moiz Sonasath Date: Tue, 12 Jun 2012 20:17:12 +0300 Subject: [PATCH 2450/6849] usb: otg: twl6030-usb: Fix twl writes There were mistakes in writing to few twl registers. There was interchange in the parameters being passed to twl6030_writeb(). Signed-off-by: Moiz Sonasath Signed-off-by: Ruslan Bilovol Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl6030-usb.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index d2a9a8e691b9..0eabb049b6a9 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -305,9 +305,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) regulator_enable(twl->usb3v3); twl->asleep = 1; - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, - 0x10); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); status = USB_EVENT_ID; otg->default_a = true; twl->phy.state = OTG_STATE_A_IDLE; @@ -316,12 +315,10 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) atomic_notifier_call_chain(&twl->phy.notifier, status, otg->gadget); } else { - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, - 0x10); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, - 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); } - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); + twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); return IRQ_HANDLED; } @@ -343,7 +340,7 @@ static int twl6030_enable_irq(struct usb_phy *x) { struct twl6030_usb *twl = phy_to_twl(x); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); -- GitLab From d7dbdb5e5fe809aa3d4c33b33943c94321dfdd06 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 20 Jun 2012 09:37:57 -0300 Subject: [PATCH 2451/6849] usb: gadget: lpc32xx_udc: fix build error with debugfs enabled If CONFIG_USB_GADGET_DEBUG_FILES is enabled, lpc32xx_udc breaks compilation because of a missing include file. Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 262acfd53e32..2ab0388d93eb 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -61,6 +61,7 @@ #include #include #ifdef CONFIG_USB_GADGET_DEBUG_FILES +#include #include #endif -- GitLab From 8c778db9f01a1b6c785890b5fd83c7addfd3eb3a Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Thu, 21 Jun 2012 17:18:12 +0530 Subject: [PATCH 2452/6849] usb: musb: host: release dma channels if no active io Currently DMA channels are allocated and they remain allocated even if there is no active data transfer. Added channel_release() whenever there is no pending request. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_host.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ef8d744800ac..e090c799d87b 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -375,11 +375,21 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, */ if (list_empty(&qh->hep->urb_list)) { struct list_head *head; + struct dma_controller *dma = musb->dma_controller; - if (is_in) + if (is_in) { ep->rx_reinit = 1; - else + if (ep->rx_channel) { + dma->channel_release(ep->rx_channel); + ep->rx_channel = NULL; + } + } else { ep->tx_reinit = 1; + if (ep->tx_channel) { + dma->channel_release(ep->tx_channel); + ep->tx_channel = NULL; + } + } /* Clobber old pointers to this qh */ musb_ep_set_qh(ep, is_in, NULL); -- GitLab From f87cabf4d56e1fc5d08434df9d54ef3450a756f0 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 18 Jun 2012 14:37:19 +0200 Subject: [PATCH 2453/6849] usb: gadget: storage_common: remove FSG_BUFFHD_STATIC_BUFFER support Since f_mass_storage stopped using FSG_BUFFHD_STATIC_BUFFER (because it caused buffers not to be page aligned which did not work well with at least some UDCs), no code was using it. Removing not to bloat the code too much. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/storage_common.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 8081ca3a70a2..8a8157f96a2d 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -37,12 +37,6 @@ * When FSG_NO_OTG is defined fsg_otg_desc won't be defined. */ -/* - * When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included - * the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN - * characters rather then a pointer to void. - */ - /* * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers * sets the number of pipeline buffers (length of the fsg_buffhd array). @@ -260,11 +254,7 @@ enum fsg_buffer_state { }; struct fsg_buffhd { -#ifdef FSG_BUFFHD_STATIC_BUFFER - char buf[FSG_BUFLEN]; -#else void *buf; -#endif enum fsg_buffer_state state; struct fsg_buffhd *next; -- GitLab From d6e16a89578fcc8834be634c85c5c5ddc2d13229 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 18 Jun 2012 14:37:20 +0200 Subject: [PATCH 2454/6849] usb: gadget: mass_storage: fail fsg_store_file() early if colud not open file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, when a new value is stored to the “file” sysfs entry, fsg_store_file() will release existing backing file and only then attempt to open a new one. If that fails, no new backing file is open. This commit changes the fsg_lun_open() so that it closes existing backing file only after the new backing file has been successfully opened. With that change, fsg_store_file() may use it to perform an atomic open operation with guarantee that logical unit will either point to the new backing file or still to the old one. Signed-off-by: Michal Nazarewicz Acked-by: Alan Stern --- drivers/usb/gadget/storage_common.c | 52 ++++++++++++++++------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 8a8157f96a2d..e576678fb621 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -617,6 +617,16 @@ static struct usb_gadget_strings fsg_stringtab = { * the caller must own fsg->filesem for writing. */ +static void fsg_lun_close(struct fsg_lun *curlun) +{ + if (curlun->filp) { + LDBG(curlun, "close backing file\n"); + fput(curlun->filp); + curlun->filp = NULL; + } +} + + static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) { int ro; @@ -626,6 +636,8 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) loff_t size; loff_t num_sectors; loff_t min_sectors; + unsigned int blkbits; + unsigned int blksize; /* R/W if we can, R/O if we must */ ro = curlun->initially_ro; @@ -670,17 +682,17 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) } if (curlun->cdrom) { - curlun->blksize = 2048; - curlun->blkbits = 11; + blksize = 2048; + blkbits = 11; } else if (inode->i_bdev) { - curlun->blksize = bdev_logical_block_size(inode->i_bdev); - curlun->blkbits = blksize_bits(curlun->blksize); + blksize = bdev_logical_block_size(inode->i_bdev); + blkbits = blksize_bits(blksize); } else { - curlun->blksize = 512; - curlun->blkbits = 9; + blksize = 512; + blkbits = 9; } - num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */ + num_sectors = size >> blkbits; /* File size in logic-block-size blocks */ min_sectors = 1; if (curlun->cdrom) { min_sectors = 300; /* Smallest track is 300 frames */ @@ -697,7 +709,12 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) goto out; } + if (fsg_lun_is_open(curlun)) + fsg_lun_close(curlun); + get_file(filp); + curlun->blksize = blksize; + curlun->blkbits = blkbits; curlun->ro = ro; curlun->filp = filp; curlun->file_length = size; @@ -711,16 +728,6 @@ out: } -static void fsg_lun_close(struct fsg_lun *curlun) -{ - if (curlun->filp) { - LDBG(curlun, "close backing file\n"); - fput(curlun->filp); - curlun->filp = NULL; - } -} - - /*-------------------------------------------------------------------------*/ /* @@ -871,19 +878,18 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, if (count > 0 && buf[count-1] == '\n') ((char *) buf)[count-1] = 0; /* Ugh! */ - /* Eject current medium */ - down_write(filesem); - if (fsg_lun_is_open(curlun)) { - fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } /* Load new medium */ + down_write(filesem); if (count > 0 && buf[0]) { + /* fsg_lun_open() will close existing file if any. */ rc = fsg_lun_open(curlun, buf); if (rc == 0) curlun->unit_attention_data = SS_NOT_READY_TO_READY_TRANSITION; + } else if (fsg_lun_is_open(curlun)) { + fsg_lun_close(curlun); + curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; } up_write(filesem); return (rc < 0 ? rc : count); -- GitLab From 45c396ce6bdad60ee94e6eed8cc7f09678651102 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Jun 2012 11:32:37 +0530 Subject: [PATCH 2455/6849] usb: dwc3: Remove duplicate header file inclusion module.h header file was included twice. Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index d19030198086..b8f00389fa34 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "core.h" -- GitLab From 45627ac6a4f063d19b0bd9863d20ac1dabda99a7 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Thu, 21 Jun 2012 17:44:28 +0530 Subject: [PATCH 2456/6849] USB: DWC3: Put 100 ms delay for phy to be stable Before taking core out of reset phy must be stable. So wait for 100ms after clear phy reset. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 49c060205c9a..ac151e9acf20 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -148,6 +148,8 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc) reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + mdelay(100); + /* After PHYs are stable we can take Core out of reset state */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; -- GitLab From 58a0f23fddd0a71d8fa22e6ef7627298a8ed29a6 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Thu, 21 Jun 2012 17:44:29 +0530 Subject: [PATCH 2457/6849] USB: DWC3: Issue device soft reset before core soft reset Synopsys specification clearly states under section "Device Power-On or Soft Reset" that DCTL.CSftRst=1 should be first step. So, just follow what specification says. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ac151e9acf20..c34452a7304f 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -335,8 +335,6 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc) } dwc->revision = reg; - dwc3_core_soft_reset(dwc); - /* issue device SoftReset too */ timeout = jiffies + msecs_to_jiffies(500); dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); @@ -354,6 +352,8 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc) cpu_relax(); } while (true); + dwc3_core_soft_reset(dwc); + dwc3_cache_hwparams(dwc); reg = dwc3_readl(dwc->regs, DWC3_GCTL); -- GitLab From a188b6897e3dca82dd6f5beceabf1fc62b9786d9 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 22 Jun 2012 09:29:56 +0200 Subject: [PATCH 2458/6849] usb: gadget: hsotg: pullup method implementation for s3c-hsotg UDC driver This commit adds pullup method implementation for UDC s3c-hsotg driver. It is needed for e.g. CCG - Configurable Composite Gadget, when user space configuration change request device disconnection from USB bus (done via calling usb_gadget_connect/disconnect, which calls UDC's pullup method). Implementation of pullup method has caused removal of phy_enable and core_init methods from udc_start to pullup. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index d208c46341d7..75a28e6d3761 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2963,9 +2963,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, goto err; } - s3c_hsotg_phy_enable(hsotg); - - s3c_hsotg_core_init(hsotg); hsotg->last_rst = jiffies; dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); return 0; @@ -3028,10 +3025,40 @@ static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) return s3c_hsotg_read_frameno(to_hsotg(gadget)); } +/** + * s3c_hsotg_pullup - connect/disconnect the USB PHY + * @gadget: The usb gadget state + * @is_on: Current state of the USB PHY + * + * Connect/Disconnect the USB PHY pullup + */ +static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) +{ + struct s3c_hsotg *hsotg = to_hsotg(gadget); + unsigned long flags = 0; + + dev_dbg(hsotg->dev, "%s: is_in: %d\n", __func__, is_on); + + spin_lock_irqsave(&hsotg->lock, flags); + if (is_on) { + s3c_hsotg_phy_enable(hsotg); + s3c_hsotg_core_init(hsotg); + } else { + s3c_hsotg_disconnect(hsotg); + s3c_hsotg_phy_disable(hsotg); + } + + hsotg->gadget.speed = USB_SPEED_UNKNOWN; + spin_unlock_irqrestore(&hsotg->lock, flags); + + return 0; +} + static struct usb_gadget_ops s3c_hsotg_gadget_ops = { .get_frame = s3c_hsotg_gadget_getframe, .udc_start = s3c_hsotg_udc_start, .udc_stop = s3c_hsotg_udc_stop, + .pullup = s3c_hsotg_pullup, }; /** -- GitLab From 08ce5abe3d0e29a7c8b46c4bec891862941116d7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 11:37:03 +0200 Subject: [PATCH 2459/6849] mac80211: two small verbose debug cleanups Two instances of CONFIG_MAC80211_VERBOSE_DEBUG should be different, fix them. Signed-off-by: Johannes Berg --- net/mac80211/ibss.c | 2 +- net/mac80211/status.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index ff46ff424941..8931110b8433 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -261,7 +261,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, memcpy(addr, sta->sta.addr, ETH_ALEN); -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG +#ifdef CONFIG_MAC80211_IBSS_DEBUG wiphy_debug(sdata->local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n", addr, sdata->name); diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 6b4f42527887..51a6d1e6e250 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -155,7 +155,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, return; } -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG if (net_ratelimit()) wiphy_debug(local->hw.wiphy, "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", -- GitLab From d3b2fb53c7f82903880769d406c11c7e619b11a4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 12:48:38 +0200 Subject: [PATCH 2460/6849] mac80211: pass sdata to some RX functions For better debugging, we would like to have the sdata pointer available later, so pass it into these functions. Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 446a327b3de0..9f1bd692589b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -554,11 +554,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) } -static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, +static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, int index) { - struct ieee80211_local *local = hw_to_local(hw); + struct ieee80211_local *local = sdata->local; struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; struct ieee80211_rx_status *status; @@ -578,7 +578,7 @@ no_frame: tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); } -static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, +static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, u16 head_seq_num) { @@ -589,7 +589,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; - ieee80211_release_reorder_frame(hw, tid_agg_rx, index); + ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); } } @@ -604,7 +604,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, */ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) -static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, +static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx) { int index, j; @@ -634,10 +634,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, #ifdef CONFIG_MAC80211_HT_DEBUG if (net_ratelimit()) - wiphy_debug(hw->wiphy, + wiphy_debug(sdata->local->hw.wiphy, "release an RX reorder frame due to timeout on earlier frames\n"); #endif - ieee80211_release_reorder_frame(hw, tid_agg_rx, j); + ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); /* * Increment the head seq# also for the skipped slots. @@ -647,7 +647,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, skipped = 0; } } else while (tid_agg_rx->reorder_buf[index]) { - ieee80211_release_reorder_frame(hw, tid_agg_rx, index); + ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; } @@ -677,7 +677,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, * rcu_read_lock protection. It returns false if the frame * can be processed immediately, true if it was consumed. */ -static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, +static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, struct sk_buff *skb) { @@ -706,7 +706,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); /* release stored frames up to new head to stack */ - ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); + ieee80211_release_reorder_frames(sdata, tid_agg_rx, + head_seq_num); } /* Now the new frame is always in the range of the reordering buffer */ @@ -736,7 +737,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, tid_agg_rx->reorder_buf[index] = skb; tid_agg_rx->reorder_time[index] = jiffies; tid_agg_rx->stored_mpdu_num++; - ieee80211_sta_reorder_release(hw, tid_agg_rx); + ieee80211_sta_reorder_release(sdata, tid_agg_rx); out: spin_unlock(&tid_agg_rx->reorder_lock); @@ -751,7 +752,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) { struct sk_buff *skb = rx->skb; struct ieee80211_local *local = rx->local; - struct ieee80211_hw *hw = &local->hw; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct sta_info *sta = rx->sta; @@ -813,7 +813,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) * sure that we cannot get to it any more before doing * anything with it. */ - if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) + if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) return; dont_reorder: @@ -2058,8 +2058,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) static ieee80211_rx_result debug_noinline ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) { - struct ieee80211_local *local = rx->local; - struct ieee80211_hw *hw = &local->hw; struct sk_buff *skb = rx->skb; struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; struct tid_ampdu_rx *tid_agg_rx; @@ -2096,7 +2094,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) spin_lock(&tid_agg_rx->reorder_lock); /* release stored frames up to start of BAR */ - ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); + ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, + start_seq_num); spin_unlock(&tid_agg_rx->reorder_lock); kfree_skb(skb); @@ -2747,7 +2746,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) return; spin_lock(&tid_agg_rx->reorder_lock); - ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); + ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); spin_unlock(&tid_agg_rx->reorder_lock); ieee80211_rx_handlers(&rx); -- GitLab From 398710379f516012c52d2ae396a9ba919bd6a7ab Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 22 Jun 2012 20:08:29 +0800 Subject: [PATCH 2461/6849] crypto: algapi - Move larval completion into algboss It has been observed that sometimes the crypto allocation code will get stuck for 60 seconds or multiples thereof. This is usually caused by an algorithm failing to pass the self-test. If an algorithm fails to be constructed, we will immediately notify all larval waiters. However, if it succeeds in construction, but then fails the self-test, we won't notify anyone at all. This patch fixes this by merging the notification in the case where the algorithm fails to be constructed with that of the the case where it pases the self-test. This way regardless of what happens, we'll give the larval waiters an answer. Signed-off-by: Herbert Xu --- crypto/algapi.c | 17 ----------------- crypto/algboss.c | 17 +++++++++-------- crypto/internal.h | 1 - 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/crypto/algapi.c b/crypto/algapi.c index 056571b85445..c3b9bfeeb7ff 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -24,22 +24,6 @@ static LIST_HEAD(crypto_template_list); -void crypto_larval_error(const char *name, u32 type, u32 mask) -{ - struct crypto_alg *alg; - - alg = crypto_alg_lookup(name, type, mask); - - if (alg) { - if (crypto_is_larval(alg)) { - struct crypto_larval *larval = (void *)alg; - complete_all(&larval->completion); - } - crypto_mod_put(alg); - } -} -EXPORT_SYMBOL_GPL(crypto_larval_error); - static inline int crypto_set_driver_name(struct crypto_alg *alg) { static const char suffix[] = "-generic"; @@ -295,7 +279,6 @@ found: continue; larval->adult = alg; - complete_all(&larval->completion); continue; } diff --git a/crypto/algboss.c b/crypto/algboss.c index 791d194958fa..f97027e7d996 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -47,6 +48,8 @@ struct cryptomgr_param { char larval[CRYPTO_MAX_ALG_NAME]; char template[CRYPTO_MAX_ALG_NAME]; + struct completion *completion; + u32 otype; u32 omask; }; @@ -66,7 +69,7 @@ static int cryptomgr_probe(void *data) tmpl = crypto_lookup_template(param->template); if (!tmpl) - goto err; + goto out; do { if (tmpl->create) { @@ -83,16 +86,10 @@ static int cryptomgr_probe(void *data) crypto_tmpl_put(tmpl); - if (err) - goto err; - out: + complete(param->completion); kfree(param); module_put_and_exit(0); - -err: - crypto_larval_error(param->larval, param->otype, param->omask); - goto out; } static int cryptomgr_schedule_probe(struct crypto_larval *larval) @@ -192,10 +189,14 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); + param->completion = &larval->completion; + thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe"); if (IS_ERR(thread)) goto err_free_param; + wait_for_completion_interruptible(&larval->completion); + return NOTIFY_STOP; err_free_param: diff --git a/crypto/internal.h b/crypto/internal.h index b865ca1a8613..9ebedae3fb54 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -83,7 +83,6 @@ void crypto_exit_compress_ops(struct crypto_tfm *tfm); struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask); void crypto_larval_kill(struct crypto_alg *alg); struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask); -void crypto_larval_error(const char *name, u32 type, u32 mask); void crypto_alg_tested(const char *name, int err); void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, -- GitLab From f8bbfd7d28303967ca4e8597de9bdc9bf8b197e7 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 23 Feb 2012 17:07:06 +0100 Subject: [PATCH 2462/6849] oprofile, perf: Use per-cpu framework This changes oprofile_perf.c to use the per-cpu framework. Using the per-cpu framework should avoid error like the following: arch/arm/oprofile/../../../drivers/oprofile/oprofile_perf.c:28:28: error: variably modified 'perf_events' at file scope Reported-by: William Cohen Cc: Will Deacon Signed-off-by: Robert Richter --- drivers/oprofile/oprofile_perf.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index efc4b7f308cf..f3cfa0b9adfa 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c @@ -1,5 +1,6 @@ /* * Copyright 2010 ARM Ltd. + * Copyright 2012 Advanced Micro Devices, Inc., Robert Richter * * Perf-events backend for OProfile. */ @@ -25,7 +26,7 @@ static int oprofile_perf_enabled; static DEFINE_MUTEX(oprofile_perf_mutex); static struct op_counter_config *counter_config; -static struct perf_event **perf_events[NR_CPUS]; +static DEFINE_PER_CPU(struct perf_event **, perf_events); static int num_counters; /* @@ -38,7 +39,7 @@ static void op_overflow_handler(struct perf_event *event, u32 cpu = smp_processor_id(); for (id = 0; id < num_counters; ++id) - if (perf_events[cpu][id] == event) + if (per_cpu(perf_events, cpu)[id] == event) break; if (id != num_counters) @@ -74,7 +75,7 @@ static int op_create_counter(int cpu, int event) { struct perf_event *pevent; - if (!counter_config[event].enabled || perf_events[cpu][event]) + if (!counter_config[event].enabled || per_cpu(perf_events, cpu)[event]) return 0; pevent = perf_event_create_kernel_counter(&counter_config[event].attr, @@ -91,18 +92,18 @@ static int op_create_counter(int cpu, int event) return -EBUSY; } - perf_events[cpu][event] = pevent; + per_cpu(perf_events, cpu)[event] = pevent; return 0; } static void op_destroy_counter(int cpu, int event) { - struct perf_event *pevent = perf_events[cpu][event]; + struct perf_event *pevent = per_cpu(perf_events, cpu)[event]; if (pevent) { perf_event_release_kernel(pevent); - perf_events[cpu][event] = NULL; + per_cpu(perf_events, cpu)[event] = NULL; } } @@ -257,12 +258,12 @@ void oprofile_perf_exit(void) for_each_possible_cpu(cpu) { for (id = 0; id < num_counters; ++id) { - event = perf_events[cpu][id]; + event = per_cpu(perf_events, cpu)[id]; if (event) perf_event_release_kernel(event); } - kfree(perf_events[cpu]); + kfree(per_cpu(perf_events, cpu)); } kfree(counter_config); @@ -277,8 +278,6 @@ int __init oprofile_perf_init(struct oprofile_operations *ops) if (ret) return ret; - memset(&perf_events, 0, sizeof(perf_events)); - num_counters = perf_num_counters(); if (num_counters <= 0) { pr_info("oprofile: no performance counters\n"); @@ -298,9 +297,9 @@ int __init oprofile_perf_init(struct oprofile_operations *ops) } for_each_possible_cpu(cpu) { - perf_events[cpu] = kcalloc(num_counters, + per_cpu(perf_events, cpu) = kcalloc(num_counters, sizeof(struct perf_event *), GFP_KERNEL); - if (!perf_events[cpu]) { + if (!per_cpu(perf_events, cpu)) { pr_info("oprofile: failed to allocate %d perf events " "for cpu %d\n", num_counters, cpu); ret = -ENOMEM; -- GitLab From 75a4433e409b2d22cbe443b623d92047b59cbb9a Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 22 Jun 2012 08:40:02 -0600 Subject: [PATCH 2463/6849] ARM: OMAP2+: PRM: fix compile for OMAP4-only build For OMAP4 only builds, the omap2_prm_* functions have dummy wrappers to detect incorrect usage. However, several unrelated omap3 PRM functions have made it inside the #else clause of the #ifdef wrapping the omap2_prm stubs, causing them to disappear on OMAP4-only builds. This was unnoticed until the IO chain support was added and introduced a new function in this section which is referenced by omap_hwmod.c: arch/arm/mach-omap2/omap_hwmod.c: In function '_reconfigure_io_chain': arch/arm/mach-omap2/omap_hwmod.c:1665:3: error: implicit declaration of function 'omap3xxx_prm_reconfigure_io_chain' [-Werror=implicit-function-declaration] Fix by using the #ifdef to only wrap the omap2_prm functions that need stubs on OMAP4-only builds. Cc: Paul Walmsley Signed-off-by: Kevin Hilman [paul@pwsan.com: fixed checkpatch warnings for patch description] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/prm2xxx_3xxx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 70ac2a19dc5f..491c72dd20a0 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -303,6 +303,8 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); +#endif /* CONFIG_ARCH_OMAP4 */ + /* OMAP3-specific VP functions */ u32 omap3_prm_vp_check_txdone(u8 vp_id); void omap3_prm_vp_clear_txdone(u8 vp_id); @@ -321,8 +323,6 @@ extern void omap3xxx_prm_ocp_barrier(void); extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); -#endif /* CONFIG_ARCH_OMAP4 */ - #endif /* -- GitLab From fe7ea0062f2f846bb68447c7b813b9230285dbeb Mon Sep 17 00:00:00 2001 From: Mohan V Date: Fri, 22 Jun 2012 08:40:02 -0600 Subject: [PATCH 2464/6849] ARM: OMAP3: PM: correct enable/disable of daisy io chain Currently the enabling and disabling of IO Daisy chain is not according to the TRM. The below steps are followed to enable/ disable the IO chain, based loosely on the "Sec 3.5.7.2.2 I/O Wake-Up Mechanism" section in OMAP3630 Public TRM[1]. Steps to enable IO chain: [a] Set PM_WKEN_WKUP.EN_IO bit [b] Set the PM_WKEN_WKUP.EN_IO_CHAIN bit [c] Poll for PM_WKST_WKUP.ST_IO_CHAIN. [d] When ST_IO_CHAIN bit set to 1, clear PM_WKEN_WKUP.EN_IO_CHAIN [e] Clear ST_IO_CHAIN bit. Steps to disable IO chain: [a] Clear PM_WKEN_WKUP.EN_IO_CHAIN bit [b] Clear PM_WKEN_WKUP.EN_IO bit [c] Clear PM_WKST_WKUP.ST_IO bit by writing 1 to it. Step [e] & [c] in each case can be skipped, as these are handled by the PRCM interrupt handler later. [1] http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vV.zip Signed-off-by: Mohan V Signed-off-by: Vishwanath BS [paul@pwsan.com: modified commit message to clarify that these steps are based loosely on the TRM section, rather than documented exactly] Reviewed-by: Rajendra Nayak [paul@pwsan.com: resolved new warnings from checkpatch] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/pm34xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a34023d0ca7c..6d7f0d8a3103 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -81,16 +81,17 @@ static void omap3_enable_io_chain(void) /* Do a readback to assure write has been done */ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & OMAP3430_ST_IO_CHAIN_MASK)) { timeout++; if (timeout > 1000) { pr_err("Wake up daisy chain activation failed.\n"); return; } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); } + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + } static void omap3_disable_io_chain(void) -- GitLab From 09659fa72bf638ae986b8b80cf99309768dd0b32 Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Fri, 22 Jun 2012 08:40:02 -0600 Subject: [PATCH 2465/6849] ARM: OMAP3: PM: Move IO Daisychain function to omap3 prm file Since IO Daisychain modifies only PRM registers, it makes sense to move it to PRM File. Also changed the timeout value for IO chain enable to 100us and added a wait for status disable at the end. Thanks to Nishanth Menon for contributing a fix to the timeout code waiting for WUCLKOUT to go high. Signed-off-by: Vishwanath BS Signed-off-by: Tero Kristo Cc: Nishanth Menon Reviewed-by: Rajendra Nayak [paul@pwsan.com: renamed omap3_trigger_io_chain() to better describe the end result and to match other PRM functions; removed omap3_disable_io_chain(); moved MAX_IOPAD_LATCH_TIME to prcm-common as it will also be used by the OMAP4 code; removed unnecessary barrier; added kerneldoc; added credit for fix from Nishanth] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/pm34xx.c | 35 ++---------------------------- arch/arm/mach-omap2/prcm-common.h | 8 +++++++ arch/arm/mach-omap2/prm2xxx_3xxx.c | 31 ++++++++++++++++++++++++++ arch/arm/mach-omap2/prm2xxx_3xxx.h | 2 ++ 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 6d7f0d8a3103..9d6cb7cc94ab 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -72,34 +72,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm; static struct powerdomain *cam_pwrdm; -static void omap3_enable_io_chain(void) -{ - int timeout = 0; - - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - pr_err("Wake up daisy chain activation failed.\n"); - return; - } - } - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - -} - -static void omap3_disable_io_chain(void) -{ - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); -} - static void omap3_core_save_context(void) { omap3_ctrl_save_padconf(); @@ -305,7 +277,7 @@ void omap_sram_idle(void) core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); if (omap3_has_io_chain_ctrl()) - omap3_enable_io_chain(); + omap3xxx_prm_reconfigure_io_chain(); } pwrdm_pre_transition(); @@ -382,12 +354,9 @@ void omap_sram_idle(void) /* Disable IO-PAD and IO-CHAIN wakeup */ if (omap3_has_io_wakeup() && (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) { + core_next_state < PWRDM_POWER_ON)) omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - if (omap3_has_io_chain_ctrl()) - omap3_disable_io_chain(); - } clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 6da3ba483ad1..fca23cbea708 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -410,6 +410,14 @@ */ #define MAX_MODULE_HARDRESET_WAIT 10000 +/* + * Maximum time(us) it takes to output the signal WUCLKOUT of the last + * pad of the I/O ring after asserting WUCLKIN high. Tero measured + * the actual time at 7 to 8 microseconds on OMAP3 and 2 to 4 + * microseconds on OMAP4, so this timeout may be too high. + */ +#define MAX_IOPAD_LATCH_TIME 100 + # ifndef __ASSEMBLER__ extern void __iomem *prm_base; extern void __iomem *cm_base; diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 9ce765407ad5..7d62bd654dbe 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -301,6 +301,37 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask) OMAP3_PRM_IRQENABLE_MPU_OFFSET); } +/** + * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain + * + * Clear any previously-latched I/O wakeup events and ensure that the + * I/O wakeup gates are aligned with the current mux settings. Works + * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then + * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No + * return value. + */ +void omap3xxx_prm_reconfigure_io_chain(void) +{ + int i = 0; + + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + + omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & + OMAP3430_ST_IO_CHAIN_MASK, + MAX_IOPAD_LATCH_TIME, i); + if (i == MAX_IOPAD_LATCH_TIME) + pr_warn("PRM: I/O chain clock line assertion timed out\n"); + + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD, + PM_WKST); + + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST); +} + static int __init omap3xxx_prcm_init(void) { if (cpu_is_omap34xx()) diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 491c72dd20a0..a8c946f318ab 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -317,6 +317,8 @@ extern u32 omap3_prm_vcvp_read(u8 offset); extern void omap3_prm_vcvp_write(u32 val, u8 offset); extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); +extern void omap3xxx_prm_reconfigure_io_chain(void); + /* PRM interrupt-related functions */ extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); extern void omap3xxx_prm_ocp_barrier(void); -- GitLab From dea6200ba0a43afb90a277802c3edf0124848eed Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 22 Jun 2012 08:40:03 -0600 Subject: [PATCH 2466/6849] ARM: OMAP4: PRM: Add IO Daisychain support IO daisychain is a mechanism that allows individual IO pads to generate wakeup events on their own based on a switch of an input signal level. This allows the hardware module behind the pad to be powered down, but still have device level capability to detect IO events, and once this happens the module can be powered back up to resume IO. See section 3.9.4 in OMAP4430 Public TRM for details. Signed-off-by: Rajendra Nayak Signed-off-by: Vishwanath BS Signed-off-by: Tero Kristo [paul@pwsan.com: use the shared MAX_IOPAD_LATCH_TIME declaration; renamed omap4_trigger_io_chain() to conform to other PRM function names; added kerneldoc; resolved checkpatch warnings] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/prm44xx.c | 54 +++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm44xx.h | 2 ++ 2 files changed, 56 insertions(+) diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index f106d21ff581..28ffbc55f8d6 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -233,6 +233,60 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask) OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); } +/** + * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain + * + * Clear any previously-latched I/O wakeup events and ensure that the + * I/O wakeup gates are aligned with the current mux settings. Works + * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then + * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. + * No return value. XXX Are the final two steps necessary? + */ +void omap44xx_prm_reconfigure_io_chain(void) +{ + int i = 0; + u32 v; + + v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); + + /* Enable GLOBAL_WUEN */ + if (!(v & OMAP4430_GLOBAL_WUEN_MASK)) + omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); + + /* Trigger WUCLKIN enable */ + omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, + OMAP4430_WUCLK_CTRL_MASK, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); + omap_test_timeout( + (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET) & + OMAP4430_WUCLK_STATUS_MASK) >> + OMAP4430_WUCLK_STATUS_SHIFT) == 1), + MAX_IOPAD_LATCH_TIME, i); + if (i == MAX_IOPAD_LATCH_TIME) + pr_warn("PRM: I/O chain clock line assertion timed out\n"); + + /* Trigger WUCLKIN disable */ + omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); + omap_test_timeout( + (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET) & + OMAP4430_WUCLK_STATUS_MASK) >> + OMAP4430_WUCLK_STATUS_SHIFT) == 0), + MAX_IOPAD_LATCH_TIME, i); + if (i == MAX_IOPAD_LATCH_TIME) + pr_warn("PRM: I/O chain clock line deassertion timed out\n"); + + return; +} + static int __init omap4xxx_prcm_init(void) { if (cpu_is_omap44xx()) diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index 7978092946db..ee72ae6bd8c9 100644 --- a/arch/arm/mach-omap2/prm44xx.h +++ b/arch/arm/mach-omap2/prm44xx.h @@ -763,6 +763,8 @@ extern u32 omap4_prm_vcvp_read(u8 offset); extern void omap4_prm_vcvp_write(u32 val, u8 offset); extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); +extern void omap44xx_prm_reconfigure_io_chain(void); + /* PRM interrupt-related functions */ extern void omap44xx_prm_read_pending_irqs(unsigned long *events); extern void omap44xx_prm_ocp_barrier(void); -- GitLab From 8a680ea2eb2e9ad602e290396add29e9eaed0911 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 22 Jun 2012 08:40:03 -0600 Subject: [PATCH 2467/6849] ARM: OMAP3+: PRM: Enable IO wake up Enable IO Wake up for OMAP3/4 as part of PRM Init. Currently this has been managed in cpuidle path which is not the right place. Subsequent patch will remove IO Daisy chain handling in cpuidle path once daisy chain is handled as part of hwmod mux. This patch also moves the OMAP4 IO wakeup enable code from the trigger function to init time setup. Signed-off-by: Tero Kristo Reviewed-by: Rajendra Nayak [paul@pwsan.com: harmonize function names with other PRM functions; add kerneldoc; resolve checkpatch warnings] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/prm2xxx_3xxx.c | 20 ++++++++++++++++++- arch/arm/mach-omap2/prm44xx.c | 31 ++++++++++++++++++------------ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 7d62bd654dbe..1471a33738f3 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -332,10 +332,28 @@ void omap3xxx_prm_reconfigure_io_chain(void) omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST); } +/** + * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches + * + * Activates the I/O wakeup event latches and allows events logged by + * those latches to signal a wakeup event to the PRCM. For I/O + * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux + * registers, and omap3xxx_prm_reconfigure_io_chain() must be called. + * No return value. + */ +static void __init omap3xxx_prm_enable_io_wakeup(void) +{ + if (omap3_has_io_wakeup()) + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, + PM_WKEN); +} + static int __init omap3xxx_prcm_init(void) { - if (cpu_is_omap34xx()) + if (cpu_is_omap34xx()) { + omap3xxx_prm_enable_io_wakeup(); return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + } return 0; } subsys_initcall(omap3xxx_prcm_init); diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 28ffbc55f8d6..bb727c2d9337 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -245,17 +245,6 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask) void omap44xx_prm_reconfigure_io_chain(void) { int i = 0; - u32 v; - - v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, - OMAP4_PRM_IO_PMCTRL_OFFSET); - - /* Enable GLOBAL_WUEN */ - if (!(v & OMAP4430_GLOBAL_WUEN_MASK)) - omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, - OMAP4430_GLOBAL_WUEN_MASK, - OMAP4430_PRM_DEVICE_INST, - OMAP4_PRM_IO_PMCTRL_OFFSET); /* Trigger WUCLKIN enable */ omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, @@ -287,10 +276,28 @@ void omap44xx_prm_reconfigure_io_chain(void) return; } +/** + * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches + * + * Activates the I/O wakeup event latches and allows events logged by + * those latches to signal a wakeup event to the PRCM. For I/O wakeups + * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and + * omap44xx_prm_reconfigure_io_chain() must be called. No return value. + */ +static void __init omap44xx_prm_enable_io_wakeup(void) +{ + omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); +} + static int __init omap4xxx_prcm_init(void) { - if (cpu_is_omap44xx()) + if (cpu_is_omap44xx()) { + omap44xx_prm_enable_io_wakeup(); return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); + } return 0; } subsys_initcall(omap4xxx_prcm_init); -- GitLab From 5165882a387325ac0df2f30c62ea710cfa328b54 Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Fri, 22 Jun 2012 08:40:04 -0600 Subject: [PATCH 2468/6849] ARM: OMAP3PLUS: hwmod: reconfigure IO Daisychain during hwmod mux IO Daisychain feature has to be triggered whenever there is a change in device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP). Now devices can idle independent of the powerdomain, there can be a window where device is idled and corresponding powerdomain can be ON/INACTIVE state. In such situations, since both module wake up is enabled at padlevel as well as io daisychain sequence is triggered, there will be 2 PRCM interrupts (Module async wake up via swakeup and IO Pad interrupt). But as PRCM Interrupt handler clears the Module Padlevel WKST bit in the first interrupt, module specific interrupt handler will not triggered for the second time Also look at detailed explanation given by Rajendra at http://www.spinics.net/lists/linux-serial/msg04480.html Signed-off-by: Vishwanath BS Signed-off-by: Tero Kristo Reviewed-by: Rajendra Nayak [paul@pwsan.com: remove dependency on pm.c & pm.h; add kerneldoc] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index bf86f7e8f91f..6d6c31a10a1b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -153,6 +153,7 @@ #include "prm44xx.h" #include "prminst44xx.h" #include "mux.h" +#include "pm.h" /* Maximum microseconds to wait for OMAP module to softreset */ #define MAX_MODULE_SOFTRESET_WAIT 10000 @@ -172,6 +173,9 @@ static LIST_HEAD(omap_hwmod_list); /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ static struct omap_hwmod *mpu_oh; +/* io_chain_lock: used to serialize reconfigurations of the I/O chain */ +static DEFINE_SPINLOCK(io_chain_lock); + /* * linkspace: ptr to a buffer that struct omap_hwmod_link records are * allocated from - used to reduce the number of small memory @@ -1737,6 +1741,32 @@ static int _reset(struct omap_hwmod *oh) return r; } +/** + * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain + * + * Call the appropriate PRM function to clear any logged I/O chain + * wakeups and to reconfigure the chain. This apparently needs to be + * done upon every mux change. Since hwmods can be concurrently + * enabled and idled, hold a spinlock around the I/O chain + * reconfiguration sequence. No return value. + * + * XXX When the PRM code is moved to drivers, this function can be removed, + * as the PRM infrastructure should abstract this. + */ +static void _reconfigure_io_chain(void) +{ + unsigned long flags; + + spin_lock_irqsave(&io_chain_lock, flags); + + if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl()) + omap3xxx_prm_reconfigure_io_chain(); + else if (cpu_is_omap44xx()) + omap44xx_prm_reconfigure_io_chain(); + + spin_unlock_irqrestore(&io_chain_lock, flags); +} + /** * _enable - enable an omap_hwmod * @oh: struct omap_hwmod * @@ -1793,8 +1823,10 @@ static int _enable(struct omap_hwmod *oh) /* Mux pins for device runtime if populated */ if (oh->mux && (!oh->mux->enabled || ((oh->_state == _HWMOD_STATE_IDLE) && - oh->mux->pads_dynamic))) + oh->mux->pads_dynamic))) { omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); + _reconfigure_io_chain(); + } _add_initiator_dep(oh, mpu_oh); @@ -1883,8 +1915,10 @@ static int _idle(struct omap_hwmod *oh) clkdm_hwmod_disable(oh->clkdm, oh); /* Mux pins for device idle if populated */ - if (oh->mux && oh->mux->pads_dynamic) + if (oh->mux && oh->mux->pads_dynamic) { omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); + _reconfigure_io_chain(); + } oh->_state = _HWMOD_STATE_IDLE; -- GitLab From fafcdd53220f44d7ae2f06a9ce20c8d550df2d9b Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Wed, 2 May 2012 02:44:40 -0600 Subject: [PATCH 2469/6849] ARM: OMAP3: PM: Remove IO Daisychain control from cpuidle As IO Daisy chain sequence is triggered via hwmod mux, there is no need to control it from cpuidle path for OMAP3. Also as omap3_disable_io_chain is no longer being used, just remove the function. Signed-off-by: Vishwanath BS Signed-off-by: Tero Kristo Reviewed-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/pm34xx.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 9d6cb7cc94ab..9d8258f16666 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -272,13 +272,6 @@ void omap_sram_idle(void) /* Enable IO-PAD and IO-CHAIN wakeups */ per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - if (omap3_has_io_wakeup() && - (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - if (omap3_has_io_chain_ctrl()) - omap3xxx_prm_reconfigure_io_chain(); - } pwrdm_pre_transition(); @@ -351,13 +344,6 @@ void omap_sram_idle(void) if (per_next_state < PWRDM_POWER_ON) omap2_gpio_resume_after_idle(); - /* Disable IO-PAD and IO-CHAIN wakeup */ - if (omap3_has_io_wakeup() && - (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, - PM_WKEN); - clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -- GitLab From 925839243dc9aa4ef25305f5afd10ed18258a4ac Mon Sep 17 00:00:00 2001 From: Stone Piao Date: Wed, 20 Jun 2012 20:21:10 -0700 Subject: [PATCH 2470/6849] mwifiex: fix 11n rx packet drop issue Currently we check the sequence number of last packet received against start_win. If a sequence hole is detected, start_win is updated to next sequence number. Since the rx sequence number is initialized to 0, a corner case exists when BA setup happens immediately after association. As 0 is a valid sequence number, start_win gets increased to 1 incorrectly. This causes the first packet with sequence number 0 being dropped. Initialize rx sequence number as 0xffff and skip adjusting start_win if the sequence number remains 0xffff. The sequence number will be updated once the first packet is received. Cc: "3.0.y, 3.1.y, 3.2.y, 3.3.y, 3.4.y" Signed-off-by: Stone Piao Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 +++-- drivers/net/wireless/mwifiex/11n_rxreorder.h | 7 +++++++ drivers/net/wireless/mwifiex/wmm.c | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 9c44088054dd..900ee129e825 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -256,7 +256,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, else last_seq = priv->rx_seq[tid]; - if (last_seq >= new_node->start_win) + if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && + last_seq >= new_node->start_win) new_node->start_win = last_seq + 1; new_node->win_size = win_size; @@ -596,5 +597,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); - memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); + mwifiex_reset_11n_rx_seq_num(priv); } diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index f1bffebabc60..6c9815a0f5d8 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -37,6 +37,13 @@ #define ADDBA_RSP_STATUS_ACCEPT 0 +#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff + +static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) +{ + memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); +} + int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index f3fc65515857..8c2b5c0aa754 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -404,6 +404,8 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; + mwifiex_reset_11n_rx_seq_num(priv); + atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } -- GitLab From f03ba7e9a24e5e9efaad56bd1713b994ea556b16 Mon Sep 17 00:00:00 2001 From: Stone Piao Date: Wed, 20 Jun 2012 20:21:11 -0700 Subject: [PATCH 2471/6849] mwifiex: fix WPS eapol handshake failure After association, STA will go through eapol handshake with WPS enabled AP. It's observed that WPS handshake fails with some 11n AP. The reason for the failure is that the eapol packet is sent via 11n frame aggregation. The eapol packet should be sent directly without 11n aggregation. This patch fixes the problem by adding WPS session control while dequeuing Tx packets for transmission. Cc: "3.4.y" Signed-off-by: Stone Piao Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/wmm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 8c2b5c0aa754..3fa4d4176993 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1223,6 +1223,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) || + priv->wps.session_enable || ((priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)) { -- GitLab From e80c81dc1416e326482c601af3a19d0f9989638e Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 20 Jun 2012 20:21:12 -0700 Subject: [PATCH 2472/6849] mwifiex: fix bugs in event handling code This patch ensures uniformity in event skb sent by interface code (USB/PCIe/SDIO) which automatically fixes following bugs. 1) For USB interface, same buffer is reused for receiving cmd and events from firmware. While handling events, we perform skb_pull(skb, 4) to remove event header. Corresponding skb_push() call is missing while submitting the buffer. 2) For PCIe interface, event skb is passed with event header. Recently added uAP events EVENT_UAP_STA_ASSOC, EVENT_UAP_STA_DEAUTH will not work for PCIe, as they assume event skb points to event body. Signed-off-by: Amitkumar Karwar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sdio.c | 6 +++--- drivers/net/wireless/mwifiex/sta_event.c | 9 ++++----- drivers/net/wireless/mwifiex/usb.c | 6 +++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index e0377473282f..fc8a9bfa1248 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -978,10 +978,10 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "info: --- Rx: Event ---\n"); adapter->event_cause = *(u32 *) skb->data; - skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN); - if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) - memcpy(adapter->event_body, skb->data, skb->len); + memcpy(adapter->event_body, + skb->data + MWIFIEX_EVENT_HEADER_LEN, + skb->len); /* event cause has been saved to adapter->event_cause */ adapter->event_received = true; diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 4ace5a3dcd23..11e731f3581c 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -406,9 +406,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_UAP_STA_ASSOC: - skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); memset(&sinfo, 0, sizeof(sinfo)); - event = (struct mwifiex_assoc_event *)adapter->event_skb->data; + event = (struct mwifiex_assoc_event *) + (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER); if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) { len = -1; @@ -433,9 +433,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) GFP_KERNEL); break; case EVENT_UAP_STA_DEAUTH: - skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); - cfg80211_del_sta(priv->netdev, adapter->event_skb->data, - GFP_KERNEL); + cfg80211_del_sta(priv->netdev, adapter->event_body + + MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL); break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 49ebf20c56eb..e6d796fabab5 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -91,7 +91,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, } skb_copy_from_linear_data(skb, &tmp, sizeof(u32)); adapter->event_cause = le32_to_cpu(tmp); - skb_pull(skb, sizeof(u32)); dev_dbg(dev, "event_cause %#x\n", adapter->event_cause); if (skb->len > MAX_EVENT_SIZE) { @@ -99,8 +98,9 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, return -1; } - skb_copy_from_linear_data(skb, adapter->event_body, - skb->len); + memcpy(adapter->event_body, skb->data + + MWIFIEX_EVENT_HEADER_LEN, skb->len); + adapter->event_received = true; adapter->event_skb = skb; break; -- GitLab From 8311f0da95d483ceb76bafae6e0a8c90531fb577 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 20 Jun 2012 20:21:13 -0700 Subject: [PATCH 2473/6849] mwifiex: improve error path handling in usb.c skb allocated during initialisation is reused for receiving commands/events by USB interface. We miss to reset skb->data in failure cases. This patch takes care of it. Signed-off-by: Amitkumar Karwar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/usb.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index e6d796fabab5..22a5916564b8 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -49,6 +49,7 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, struct device *dev = adapter->dev; u32 recv_type; __le32 tmp; + int ret; if (adapter->hs_activated) mwifiex_process_hs_config(adapter); @@ -69,16 +70,19 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_CMD: if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) { dev_err(dev, "CMD: skb->len too large\n"); - return -1; + ret = -1; + goto exit_restore_skb; } else if (!adapter->curr_cmd) { dev_dbg(dev, "CMD: no curr_cmd\n"); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp( adapter, skb->data, skb->len); - return 0; + ret = 0; + goto exit_restore_skb; } - return -1; + ret = -1; + goto exit_restore_skb; } adapter->curr_cmd->resp_skb = skb; @@ -87,7 +91,8 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_EVENT: if (skb->len < sizeof(u32)) { dev_err(dev, "EVENT: skb->len too small\n"); - return -1; + ret = -1; + goto exit_restore_skb; } skb_copy_from_linear_data(skb, &tmp, sizeof(u32)); adapter->event_cause = le32_to_cpu(tmp); @@ -95,7 +100,8 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, if (skb->len > MAX_EVENT_SIZE) { dev_err(dev, "EVENT: event body too large\n"); - return -1; + ret = -1; + goto exit_restore_skb; } memcpy(adapter->event_body, skb->data + @@ -124,6 +130,12 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, } return -EINPROGRESS; + +exit_restore_skb: + /* The buffer will be reused for further cmds/events */ + skb_push(skb, INTF_HEADER_LEN); + + return ret; } static void mwifiex_usb_rx_complete(struct urb *urb) -- GitLab From 0fd66be4a369e4a93bfd559c931e689539cc8e5f Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 12:21:52 -0700 Subject: [PATCH 2474/6849] mwifiex: parse WPA IE and support WPA/WPA2 mixed mode for uAP Add support for parsing WPA IE from beacon parameter of cfg80211_ap_settings and set it to FW. WPA/WPA2 mixed mode is supported with this patch. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/ie.c | 55 +++++++++++++++++--------- drivers/net/wireless/mwifiex/uap_cmd.c | 17 ++++++-- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index ceb82cd749cc..328fb14d9e14 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c @@ -224,29 +224,46 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL; - struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL; - struct ieee_types_header *ie = NULL; + struct mwifiex_ie *ar_ie = NULL, *gen_ie = NULL; + struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL; u16 beacon_idx = MWIFIEX_AUTO_IDX_MASK, pr_idx = MWIFIEX_AUTO_IDX_MASK; u16 ar_idx = MWIFIEX_AUTO_IDX_MASK, rsn_idx = MWIFIEX_AUTO_IDX_MASK; - u16 mask; + u16 mask, ie_len = 0; + const u8 *vendor_ie; int ret = 0; if (params->beacon.tail && params->beacon.tail_len) { - ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, params->beacon.tail, - params->beacon.tail_len); - if (ie) { - rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!rsn_ie) - return -ENOMEM; - - rsn_ie->ie_index = cpu_to_le16(rsn_idx); - mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | - MGMT_MASK_ASSOC_RESP; - rsn_ie->mgmt_subtype_mask = cpu_to_le16(mask); - rsn_ie->ie_length = cpu_to_le16(ie->len + 2); - memcpy(rsn_ie->ie_buffer, ie, ie->len + 2); - - if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &rsn_idx, + gen_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); + if (!gen_ie) + return -ENOMEM; + gen_ie->ie_index = cpu_to_le16(rsn_idx); + mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | + MGMT_MASK_ASSOC_RESP; + gen_ie->mgmt_subtype_mask = cpu_to_le16(mask); + + rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, + params->beacon.tail, + params->beacon.tail_len); + if (rsn_ie) { + memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2); + ie_len = rsn_ie->len + 2; + gen_ie->ie_length = cpu_to_le16(ie_len); + } + + vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WPA, + params->beacon.tail, + params->beacon.tail_len); + if (vendor_ie) { + wpa_ie = (struct ieee_types_header *)vendor_ie; + memcpy(gen_ie->ie_buffer + ie_len, + wpa_ie, wpa_ie->len + 2); + ie_len += wpa_ie->len + 2; + gen_ie->ie_length = cpu_to_le16(ie_len); + } + + if (rsn_ie || wpa_ie) { + if (mwifiex_update_uap_custom_ie(priv, gen_ie, &rsn_idx, NULL, NULL, NULL, NULL)) { ret = -1; @@ -319,7 +336,7 @@ done: kfree(beacon_ie); kfree(pr_ie); kfree(ar_ie); - kfree(rsn_ie); + kfree(gen_ie); return ret; } diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index abb1322a8ceb..f40e93fe894a 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -66,7 +66,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, } if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) { - bss_config->protocol = PROTOCOL_WPA2; + bss_config->protocol |= PROTOCOL_WPA2; bss_config->key_mgmt = KEY_MGMT_EAP; } break; @@ -78,7 +78,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, } if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) { - bss_config->protocol = PROTOCOL_WPA2; + bss_config->protocol |= PROTOCOL_WPA2; bss_config->key_mgmt = KEY_MGMT_PSK; } break; @@ -92,10 +92,19 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, case WLAN_CIPHER_SUITE_WEP104: break; case WLAN_CIPHER_SUITE_TKIP: - bss_config->wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP; + if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1) + bss_config->wpa_cfg.pairwise_cipher_wpa |= + CIPHER_TKIP; + if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) + bss_config->wpa_cfg.pairwise_cipher_wpa2 |= + CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP: - bss_config->wpa_cfg.pairwise_cipher_wpa2 = + if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1) + bss_config->wpa_cfg.pairwise_cipher_wpa |= + CIPHER_AES_CCMP; + if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) + bss_config->wpa_cfg.pairwise_cipher_wpa2 |= CIPHER_AES_CCMP; default: break; -- GitLab From f931c7705bb3e21edd345a0fa748462fd3df4122 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 20 Jun 2012 19:58:36 -0700 Subject: [PATCH 2475/6849] mwifiex: wake up main thread to handle Tx traffic if scan is delayed/aborted This is a flaw in recently implemented logic to handle Tx traffic and scan operation simultaneously. We missed to wakeup main thread to handle Tx traffic if scan is delayed/aborted. For some cards (SD8797, for example), firmware will send SLEEP event if there is no activity for 50msec. While handling the SLEEP event, main thread will be woken up and Tx packet gets sent hence. In worst case Tx traffic will be delayed for 50msec. For other cards, such as USB8797, firmware won't send SLEEP event. So, Tx traffic gets stuck if no other event triggers the wakeup of main thread. This patch fixes above issues. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 1 + drivers/net/wireless/mwifiex/main.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 0f18ef6a30c8..b543a4d82ff3 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -103,6 +103,7 @@ static void scan_delay_timer_fn(unsigned long data) msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); adapter->scan_delay_cnt++; } + queue_work(priv->adapter->workqueue, &priv->adapter->main_work); } else { /* * Tx data queue is empty. Get scan command from scan_pending_q diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 0f06f07a70e6..f0219efc8953 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -190,7 +190,8 @@ process_start: adapter->tx_lock_flag) break; - if (adapter->scan_processing || adapter->data_sent || + if ((adapter->scan_processing && + !adapter->scan_delay_cnt) || adapter->data_sent || mwifiex_wmm_lists_empty(adapter)) { if (adapter->cmd_sent || adapter->curr_cmd || (!is_command_pending(adapter))) -- GitLab From a4186ea6ec6c903e29294141d4861e8327fd113c Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 20 Jun 2012 19:58:37 -0700 Subject: [PATCH 2476/6849] mwifiex: enhance power save for USB and PCIe chipsets FW will not explicitly notify about host sleep activation to the host for USB and PCIe chipsets. Hence host should generate Host Sleep Activated event as soon as Host Sleep parameters are configured to FW successfully. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 51e023ec1de4..ea37b887a874 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1102,7 +1102,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, &resp->params.opt_hs_cfg; uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); - if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) { + if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && + adapter->iface_type == MWIFIEX_SDIO) { mwifiex_hs_activated_event(priv, true); return 0; } else { @@ -1114,6 +1115,9 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, } if (conditions != HOST_SLEEP_CFG_CANCEL) { adapter->is_hs_configured = true; + if (adapter->iface_type == MWIFIEX_USB || + adapter->iface_type == MWIFIEX_PCIE) + mwifiex_hs_activated_event(priv, true); } else { adapter->is_hs_configured = false; if (adapter->hs_activated) -- GitLab From 8dc01811da1119d6a5e595b5200b788c6603d3b2 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 21 Jun 2012 11:33:32 +0200 Subject: [PATCH 2477/6849] brcmfmac: make inclusion of vmalloc.h explicit fixing linux-next build This patch fixes problem detected in linux-next build for powerpc allyesconfig. The error message below is no longer observed: CC drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.o drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c: In function 'brcmf_sdio_dump_console': drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c:3085: error: implicit declaration of function 'vzalloc' drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c:3085: warning: assignment makes pointer from integer without a cast drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c:3113: error: implicit declaration of function 'vfree' make[2]: *** [drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.o] Error 1 Reported-by: Stephen Rothwell Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 9971e130476d..076b7720ded9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include -- GitLab From c49aa4aa2bc89e88672dc419a293d7b8c1f094d2 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 21 Jun 2012 15:49:13 +0200 Subject: [PATCH 2478/6849] brcmsmac: fix NULL pointer crash in brcms_c_regd_init() In the function brcms_c_regd_init() the channels are validated against the device capabilities. This is done for both 2.4G and 5G band, but there are devices that are 2.4G only, ie. BCM4313. For that device this leads to a NULL dereference. This patch adds a check in brcms_c_regd_init() to fix this. Issue introduced in wireless-next tree by following commit: cf03c5d brcm80211: smac: inform mac80211 of the X2 regulatory domain Cc: Seth Forshee Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/channel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index d3c726021c35..2d365d3486df 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -768,6 +768,11 @@ void brcms_c_regd_init(struct brcms_c_info *wlc) band = wlc->bandstate[BAND_2G_INDEX]; else band = wlc->bandstate[BAND_5G_INDEX]; + + /* skip if band not initialized */ + if (band->pi == NULL) + continue; + wlc_phy_chanspec_band_validch(band->pi, band->bandtype, &sup_chan); -- GitLab From 81b67fd60a75cac36092aa37cd0728aab3a7a938 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 21 Jun 2012 20:33:59 +0530 Subject: [PATCH 2479/6849] ath9k_hw: rename mrcCCKOff to fix smatch warning Rename mrcCCKOff for better code readability and also fixes the smatch warning. drivers/net/wireless/ath/ath9k/ar9003_phy.c:982 ar9003_hw_ani_control() Error invalid range 1 to 0. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 8 ++------ drivers/net/wireless/ath/ath9k/ani.h | 4 +--- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 4 ++-- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 +++++----- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index a90aa0b4c8f1..7ebc3465f22d 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -238,7 +238,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah)) return; - if (aniState->mrcCCKOff == entry_cck->mrc_cck_on) + if (aniState->mrcCCK != entry_cck->mrc_cck_on) ath9k_hw_ani_control(ah, ATH9K_ANI_MRC_CCK, entry_cck->mrc_cck_on); @@ -525,11 +525,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; - if (AR_SREV_9300_20_OR_LATER(ah)) - ani->mrcCCKOff = - !ATH9K_ANI_ENABLE_MRC_CCK; - else - ani->mrcCCKOff = true; + ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false; ani->ofdmsTurn = true; diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 79c85fc6c32c..e9d841bbe86f 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -62,8 +62,6 @@ #define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0 #define ATH9K_SIG_SPUR_IMM_SETTING_MAX 22 -#define ATH9K_ANI_ENABLE_MRC_CCK true - /* values here are relative to the INI */ enum ath9k_ani_cmd { @@ -111,7 +109,7 @@ struct ar5416AniState { u8 ofdmNoiseImmunityLevel; u8 cckNoiseImmunityLevel; bool ofdmsTurn; - u8 mrcCCKOff; + u8 mrcCCK; u8 spurImmunityLevel; u8 firstepLevel; u8 ofdmWeakSigDetect; diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index b6efcd9b3129..874186bfda41 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1234,7 +1234,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, aniState->spurImmunityLevel, aniState->ofdmWeakSigDetect ? "on" : "off", aniState->firstepLevel, - !aniState->mrcCCKOff ? "on" : "off", + aniState->mrcCCK ? "on" : "off", aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1322,7 +1322,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; - aniState->mrcCCKOff = true; /* not available on pre AR9003 */ + aniState->mrcCCK = false; /* not available on pre AR9003 */ } static void ar5008_hw_set_nf_limits(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ec8a8d5c6db5..f1975b9e5393 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -979,16 +979,16 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, AR_PHY_MRC_CCK_ENABLE, is_on); REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, AR_PHY_MRC_CCK_MUX_REG, is_on); - if (!is_on != aniState->mrcCCKOff) { + if (is_on != aniState->mrcCCK) { ath_dbg(common, ANI, "** ch %d: MRC CCK: %s=>%s\n", chan->channel, - !aniState->mrcCCKOff ? "on" : "off", + aniState->mrcCCK ? "on" : "off", is_on ? "on" : "off"); if (is_on) ah->stats.ast_ani_ccklow++; else ah->stats.ast_ani_cckhigh++; - aniState->mrcCCKOff = !is_on; + aniState->mrcCCK = is_on; } break; } @@ -1004,7 +1004,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, aniState->spurImmunityLevel, aniState->ofdmWeakSigDetect ? "on" : "off", aniState->firstepLevel, - !aniState->mrcCCKOff ? "on" : "off", + aniState->mrcCCK ? "on" : "off", aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1114,7 +1114,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; - aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; + aniState->mrcCCK = true; } static void ar9003_hw_set_radar_params(struct ath_hw *ah, -- GitLab From 4b5237cc86872319a321ca1a694dee8866f7d9a3 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 21 Jun 2012 20:34:00 +0530 Subject: [PATCH 2480/6849] ath9k_hw: fix smatch warning in ar9003_hw_spur_mitigate_mrc_cck drivers/net/wireless/ath/ath9k/ar9003_phy.c:211 ar9003_hw_spur_mitigate_mrc_cck() error: potential NULL dereference 'spur_fbin_ptr'. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index f1975b9e5393..6b91ebb158fe 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -173,7 +173,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, int cur_bb_spur, negative = 0, cck_spur_freq; int i; int range, max_spur_cnts, synth_freq; - u8 *spur_fbin_ptr = NULL; + u8 *spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, IS_CHAN_2GHZ(chan)); /* * Need to verify range +/- 10 MHz in control channel, otherwise spur @@ -181,8 +181,6 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, */ if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) { - spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, - IS_CHAN_2GHZ(chan)); if (spur_fbin_ptr[0] == 0) /* No spur */ return; max_spur_cnts = 5; -- GitLab From 5ea276963eacbef742fe4854883c0f69c903fcfd Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 21 Jun 2012 13:08:04 -0500 Subject: [PATCH 2481/6849] rtlwifi: Change debug level for deletion of an entry in CAM When running in AP mode, the driver reports all deletions from CAM in a cryptic manner that makes users think it is an error. change so that the condition is only reported at higher-levels of debugging. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/cam.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 3d8cc4a0c86d..6a2d72beb00d 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -128,7 +128,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, u32 us_config; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", ul_entry_idx, ul_key_id, ul_enc_alg, ul_default_key, mac_addr); @@ -342,7 +342,8 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) /* Remove from HW Security CAM */ memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); - pr_info("&&&&&&&&&del entry %d\n", i); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + "del CAM entry %d\n", i); } } return; -- GitLab From e1262efb9bf9864532c0dfca2b2e222aee7bd0a5 Mon Sep 17 00:00:00 2001 From: Arkady Miasnikov Date: Mon, 18 Jun 2012 16:21:12 +0300 Subject: [PATCH 2482/6849] wlcore: access the firmware memory via debugfs Applications running in the user space needs access to the memory of the chip. Examples of such access - read/write global variables - access to firmware log - dump memory after firmware panic event Arbitrary 4-bytes aligned location can be accessed by read/write file wlcore/mem [Check return value of wlcore_raw_read/write and wlcore_set_partition calls as required by the recent IO changes. -- Luca] Signed-off-by: Arkady Miasnikov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/debugfs.c | 192 +++++++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 1768f37049bd..80dbc5304fac 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -38,6 +38,8 @@ /* ms */ #define WL1271_DEBUGFS_STATS_LIFETIME 1000 +#define WLCORE_MAX_BLOCK_SIZE ((size_t)(4*PAGE_SIZE)) + /* debugfs macros idea from mac80211 */ int wl1271_format_buffer(char __user *userbuf, size_t count, loff_t *ppos, char *fmt, ...) @@ -1025,6 +1027,195 @@ static const struct file_operations sleep_auth_ops = { .llseek = default_llseek, }; +static ssize_t dev_mem_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + struct wlcore_partition_set part, old_part; + size_t bytes = count; + int ret; + char *buf; + + /* only requests of dword-aligned size and offset are supported */ + if (bytes % 4) + return -EINVAL; + + if (*ppos % 4) + return -EINVAL; + + /* function should return in reasonable time */ + bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE); + + if (bytes == 0) + return -EINVAL; + + memset(&part, 0, sizeof(part)); + part.mem.start = file->f_pos; + part.mem.size = bytes; + + buf = kmalloc(bytes, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) { + ret = -EFAULT; + goto skip_read; + } + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto skip_read; + + /* store current partition and switch partition */ + memcpy(&old_part, &wl->curr_part, sizeof(old_part)); + ret = wlcore_set_partition(wl, &part); + if (ret < 0) + goto part_err; + + ret = wlcore_raw_read(wl, 0, buf, bytes, false); + if (ret < 0) + goto read_err; + +read_err: + /* recover partition */ + ret = wlcore_set_partition(wl, &old_part); + if (ret < 0) + goto part_err; + +part_err: + wl1271_ps_elp_sleep(wl); + +skip_read: + mutex_unlock(&wl->mutex); + + if (ret == 0) { + ret = copy_to_user(user_buf, buf, bytes); + if (ret < bytes) { + bytes -= ret; + *ppos += bytes; + ret = 0; + } else { + ret = -EFAULT; + } + } + + kfree(buf); + + return ((ret == 0) ? bytes : ret); +} + +static ssize_t dev_mem_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + struct wlcore_partition_set part, old_part; + size_t bytes = count; + int ret; + char *buf; + + /* only requests of dword-aligned size and offset are supported */ + if (bytes % 4) + return -EINVAL; + + if (*ppos % 4) + return -EINVAL; + + /* function should return in reasonable time */ + bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE); + + if (bytes == 0) + return -EINVAL; + + memset(&part, 0, sizeof(part)); + part.mem.start = file->f_pos; + part.mem.size = bytes; + + buf = kmalloc(bytes, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = copy_from_user(buf, user_buf, bytes); + if (ret) { + ret = -EFAULT; + goto err_out; + } + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) { + ret = -EFAULT; + goto skip_write; + } + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto skip_write; + + /* store current partition and switch partition */ + memcpy(&old_part, &wl->curr_part, sizeof(old_part)); + ret = wlcore_set_partition(wl, &part); + if (ret < 0) + goto part_err; + + ret = wlcore_raw_write(wl, 0, buf, bytes, false); + if (ret < 0) + goto write_err; + +write_err: + /* recover partition */ + ret = wlcore_set_partition(wl, &old_part); + if (ret < 0) + goto part_err; + +part_err: + wl1271_ps_elp_sleep(wl); + +skip_write: + mutex_unlock(&wl->mutex); + + if (ret == 0) + *ppos += bytes; + +err_out: + kfree(buf); + + return ((ret == 0) ? bytes : ret); +} + +static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig) +{ + loff_t ret; + + /* only requests of dword-aligned size and offset are supported */ + if (offset % 4) + return -EINVAL; + + switch (orig) { + case SEEK_SET: + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + file->f_pos += offset; + ret = file->f_pos; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct file_operations dev_mem_ops = { + .open = simple_open, + .read = dev_mem_read, + .write = dev_mem_write, + .llseek = dev_mem_seek, +}; + static int wl1271_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -1059,6 +1250,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming); DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming); + DEBUGFS_ADD_PREFIX(dev, mem, rootdir); return 0; -- GitLab From 96caded8d275f67c6000fa219b0c11e7d6bf8e0b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 21 Jun 2012 18:10:47 +0300 Subject: [PATCH 2483/6849] wlcore: cancel suspend when recovery is pending We wish to postpone suspend if recovery is pending. This will make sure the FW is in a good state and perform wowlan wakeup. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index b0795aac4bac..0df28d5cb331 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1661,6 +1661,12 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); WARN_ON(!wow); + /* we want to perform the recovery before suspending */ + if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { + wl1271_warning("postponing suspend to perform recovery"); + return -EBUSY; + } + wl1271_tx_flush(wl); mutex_lock(&wl->mutex); -- GitLab From 2a76c450bd0377f715caf313ded530290d7dc7d7 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:10 +0800 Subject: [PATCH 2484/6849] x86/PCI: split out pci_mmcfg_check_reserved() for code reuse Split out pci_mmcfg_check_reserved() for code reuse, which will be used when supporting PCI host bridge hotplug. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 51 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 301e325992f6..f799949a08a5 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -474,39 +474,38 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, return valid; } +static int __devinit pci_mmcfg_check_reserved(struct pci_mmcfg_region *cfg, + int early) +{ + if (!early && !acpi_disabled) { + if (is_mmconf_reserved(is_acpi_reserved, cfg, 0)) + return 1; + else + printk(KERN_ERR FW_BUG PREFIX + "MMCONFIG at %pR not reserved in " + "ACPI motherboard resources\n", + &cfg->res); + } + + /* Don't try to do this check unless configuration + type 1 is available. how about type 2 ?*/ + if (raw_pci_ops) + return is_mmconf_reserved(e820_all_mapped, cfg, 1); + + return 0; +} + static void __init pci_mmcfg_reject_broken(int early) { struct pci_mmcfg_region *cfg; list_for_each_entry(cfg, &pci_mmcfg_list, list) { - int valid = 0; - - if (!early && !acpi_disabled) { - valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0); - - if (valid) - continue; - else - printk(KERN_ERR FW_BUG PREFIX - "MMCONFIG at %pR not reserved in " - "ACPI motherboard resources\n", - &cfg->res); + if (pci_mmcfg_check_reserved(cfg, early) == 0) { + printk(KERN_INFO PREFIX "not using MMCONFIG\n"); + free_all_mmcfg(); + return; } - - /* Don't try to do this check unless configuration - type 1 is available. how about type 2 ?*/ - if (raw_pci_ops) - valid = is_mmconf_reserved(e820_all_mapped, cfg, 1); - - if (!valid) - goto reject; } - - return; - -reject: - printk(KERN_INFO PREFIX "not using MMCONFIG\n"); - free_all_mmcfg(); } static int __initdata known_bridge; -- GitLab From 846e402300ffa2131239dcf82265b5366cd755f4 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:11 +0800 Subject: [PATCH 2485/6849] x86/PCI: split out pci_mmconfig_alloc() for code reuse Split out pci_mmconfig_alloc() for code reuse, which will be used when supporting PCI root bridge hotplug. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index f799949a08a5..5e2cd2aa2889 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -61,8 +61,9 @@ static __init void list_add_sorted(struct pci_mmcfg_region *new) list_add_tail(&new->list, &pci_mmcfg_list); } -static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, - int end, u64 addr) +static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, + int start, + int end, u64 addr) { struct pci_mmcfg_region *new; struct resource *res; @@ -79,8 +80,6 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, new->start_bus = start; new->end_bus = end; - list_add_sorted(new); - res = &new->res; res->start = addr + PCI_MMCFG_BUS_OFFSET(start); res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1; @@ -96,6 +95,18 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, return new; } +static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, + int end, u64 addr) +{ + struct pci_mmcfg_region *new; + + new = pci_mmconfig_alloc(segment, start, end, addr); + if (new) + list_add_sorted(new); + + return new; +} + struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) { struct pci_mmcfg_region *cfg; -- GitLab From 376f70acfe4bd97493299cdfc00a8d235279d267 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:12 +0800 Subject: [PATCH 2486/6849] x86/PCI: use RCU list to protect mmconfig list Use RCU list to protect mmconfig list from dynamic change when supporting PCI host bridge hotplug. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 18 ++++++++++++------ arch/x86/pci/mmconfig_32.c | 13 +++++++++++-- arch/x86/pci/mmconfig_64.c | 13 +++++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 5e2cd2aa2889..0ac97d54bcac 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -25,6 +27,7 @@ /* Indicate if the mmcfg resources have been placed into the resource table. */ static int __initdata pci_mmcfg_resources_inserted; +static DEFINE_MUTEX(pci_mmcfg_lock); LIST_HEAD(pci_mmcfg_list); @@ -45,20 +48,20 @@ static __init void free_all_mmcfg(void) pci_mmconfig_remove(cfg); } -static __init void list_add_sorted(struct pci_mmcfg_region *new) +static __devinit void list_add_sorted(struct pci_mmcfg_region *new) { struct pci_mmcfg_region *cfg; /* keep list sorted by segment and starting bus number */ - list_for_each_entry(cfg, &pci_mmcfg_list, list) { + list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) { if (cfg->segment > new->segment || (cfg->segment == new->segment && cfg->start_bus >= new->start_bus)) { - list_add_tail(&new->list, &cfg->list); + list_add_tail_rcu(&new->list, &cfg->list); return; } } - list_add_tail(&new->list, &pci_mmcfg_list); + list_add_tail_rcu(&new->list, &pci_mmcfg_list); } static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, @@ -101,8 +104,11 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, struct pci_mmcfg_region *new; new = pci_mmconfig_alloc(segment, start, end, addr); - if (new) + if (new) { + mutex_lock(&pci_mmcfg_lock); list_add_sorted(new); + mutex_unlock(&pci_mmcfg_lock); + } return new; } @@ -111,7 +117,7 @@ struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) { struct pci_mmcfg_region *cfg; - list_for_each_entry(cfg, &pci_mmcfg_list, list) + list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) if (cfg->segment == segment && cfg->start_bus <= bus && bus <= cfg->end_bus) return cfg; diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 5372e86834c0..5dad04aa6b37 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -60,9 +61,12 @@ err: *value = -1; return -EINVAL; } + rcu_read_lock(); base = get_base_addr(seg, bus, devfn); - if (!base) + if (!base) { + rcu_read_unlock(); goto err; + } raw_spin_lock_irqsave(&pci_config_lock, flags); @@ -80,6 +84,7 @@ err: *value = -1; break; } raw_spin_unlock_irqrestore(&pci_config_lock, flags); + rcu_read_unlock(); return 0; } @@ -93,9 +98,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; + rcu_read_lock(); base = get_base_addr(seg, bus, devfn); - if (!base) + if (!base) { + rcu_read_unlock(); return -EINVAL; + } raw_spin_lock_irqsave(&pci_config_lock, flags); @@ -113,6 +121,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, break; } raw_spin_unlock_irqrestore(&pci_config_lock, flags); + rcu_read_unlock(); return 0; } diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 915a493502cb..acc48c5b6863 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -34,9 +35,12 @@ err: *value = -1; return -EINVAL; } + rcu_read_lock(); addr = pci_dev_base(seg, bus, devfn); - if (!addr) + if (!addr) { + rcu_read_unlock(); goto err; + } switch (len) { case 1: @@ -49,6 +53,7 @@ err: *value = -1; *value = mmio_config_readl(addr + reg); break; } + rcu_read_unlock(); return 0; } @@ -62,9 +67,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; + rcu_read_lock(); addr = pci_dev_base(seg, bus, devfn); - if (!addr) + if (!addr) { + rcu_read_unlock(); return -EINVAL; + } switch (len) { case 1: @@ -77,6 +85,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, mmio_config_writel(addr + reg, value); break; } + rcu_read_unlock(); return 0; } -- GitLab From 9cf0105da5a315677d8f91043fb87fdade0d8b39 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:13 +0800 Subject: [PATCH 2487/6849] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap() Introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap(), which will be used when supporting PCI root bridge hotplug. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/include/asm/pci_x86.h | 2 ++ arch/x86/pci/mmconfig_32.c | 15 ++++++++++++++ arch/x86/pci/mmconfig_64.c | 38 +++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b3a531746026..df898ceab4d4 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -135,6 +135,8 @@ struct pci_mmcfg_region { extern int __init pci_mmcfg_arch_init(void); extern void __init pci_mmcfg_arch_free(void); +extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg); +extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg); extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); extern struct list_head pci_mmcfg_list; diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 5dad04aa6b37..a22785deb50e 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c @@ -141,3 +141,18 @@ int __init pci_mmcfg_arch_init(void) void __init pci_mmcfg_arch_free(void) { } + +int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) +{ + return 0; +} + +void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) +{ + unsigned long flags; + + /* Invalidate the cached mmcfg map entry. */ + raw_spin_lock_irqsave(&pci_config_lock, flags); + mmcfg_last_accessed_device = 0; + raw_spin_unlock_irqrestore(&pci_config_lock, flags); +} diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index acc48c5b6863..ebefea5107a7 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -95,7 +95,7 @@ static const struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; -static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) +static void __iomem * __devinit mcfg_ioremap(struct pci_mmcfg_region *cfg) { void __iomem *addr; u64 start, size; @@ -114,16 +114,14 @@ int __init pci_mmcfg_arch_init(void) { struct pci_mmcfg_region *cfg; - list_for_each_entry(cfg, &pci_mmcfg_list, list) { - cfg->virt = mcfg_ioremap(cfg); - if (!cfg->virt) { - printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", - &cfg->res); + list_for_each_entry(cfg, &pci_mmcfg_list, list) + if (pci_mmcfg_arch_map(cfg)) { pci_mmcfg_arch_free(); return 0; } - } + raw_pci_ext_ops = &pci_mmcfg; + return 1; } @@ -131,10 +129,26 @@ void __init pci_mmcfg_arch_free(void) { struct pci_mmcfg_region *cfg; - list_for_each_entry(cfg, &pci_mmcfg_list, list) { - if (cfg->virt) { - iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); - cfg->virt = NULL; - } + list_for_each_entry(cfg, &pci_mmcfg_list, list) + pci_mmcfg_arch_unmap(cfg); +} + +int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) +{ + cfg->virt = mcfg_ioremap(cfg); + if (!cfg->virt) { + printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", + &cfg->res); + return -ENOMEM; + } + + return 0; +} + +void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) +{ + if (cfg && cfg->virt) { + iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); + cfg->virt = NULL; } } -- GitLab From 95c5e92f4f691bbaba40bbf3decfc8e13b6ea897 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:14 +0800 Subject: [PATCH 2488/6849] x86/PCI: prepare pci_mmcfg_check_reserved() to be called at runtime Prepare function pci_mmcfg_check_reserved() to be called at runtime for PCI host bridge hot-plugging Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 104 +++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 0ac97d54bcac..15a7abf5139c 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -27,6 +27,7 @@ /* Indicate if the mmcfg resources have been placed into the resource table. */ static int __initdata pci_mmcfg_resources_inserted; +static bool pci_mmcfg_running_state; static DEFINE_MUTEX(pci_mmcfg_lock); LIST_HEAD(pci_mmcfg_list); @@ -375,14 +376,15 @@ static void __init pci_mmcfg_insert_resources(void) struct pci_mmcfg_region *cfg; list_for_each_entry(cfg, &pci_mmcfg_list, list) - insert_resource(&iomem_resource, &cfg->res); + if (!cfg->res.parent) + insert_resource(&iomem_resource, &cfg->res); /* Mark that the resources have been inserted. */ pci_mmcfg_resources_inserted = 1; } -static acpi_status __init check_mcfg_resource(struct acpi_resource *res, - void *data) +static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res, + void *data) { struct resource *mcfg_res = data; struct acpi_resource_address64 address; @@ -418,8 +420,8 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res, return AE_OK; } -static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, - void *context, void **rv) +static acpi_status __devinit find_mboard_resource(acpi_handle handle, u32 lvl, + void *context, void **rv) { struct resource *mcfg_res = context; @@ -432,7 +434,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, return AE_OK; } -static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) +static int __devinit is_acpi_reserved(u64 start, u64 end, unsigned not_used) { struct resource mcfg_res; @@ -451,13 +453,15 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); -static int __init is_mmconf_reserved(check_reserved_t is_reserved, - struct pci_mmcfg_region *cfg, int with_e820) +static int __ref is_mmconf_reserved(check_reserved_t is_reserved, + struct pci_mmcfg_region *cfg, + struct device *dev, int with_e820) { u64 addr = cfg->res.start; u64 size = resource_size(&cfg->res); u64 old_size = size; - int valid = 0, num_buses; + int num_buses; + char *method = with_e820 ? "E820" : "ACPI motherboard resources"; while (!is_reserved(addr, addr + size, E820_RESERVED)) { size >>= 1; @@ -465,49 +469,75 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, break; } - if (size >= (16UL<<20) || size == old_size) { - printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n", - &cfg->res, - with_e820 ? "E820" : "ACPI motherboard resources"); - valid = 1; - - if (old_size != size) { - /* update end_bus */ - cfg->end_bus = cfg->start_bus + ((size>>20) - 1); - num_buses = cfg->end_bus - cfg->start_bus + 1; - cfg->res.end = cfg->res.start + - PCI_MMCFG_BUS_OFFSET(num_buses) - 1; - snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN, - "PCI MMCONFIG %04x [bus %02x-%02x]", - cfg->segment, cfg->start_bus, cfg->end_bus); + if (size < (16UL<<20) && size != old_size) + return 0; + + if (dev) + dev_info(dev, "MMCONFIG at %pR reserved in %s\n", + &cfg->res, method); + else + printk(KERN_INFO PREFIX + "MMCONFIG at %pR reserved in %s\n", + &cfg->res, method); + + if (old_size != size) { + /* update end_bus */ + cfg->end_bus = cfg->start_bus + ((size>>20) - 1); + num_buses = cfg->end_bus - cfg->start_bus + 1; + cfg->res.end = cfg->res.start + + PCI_MMCFG_BUS_OFFSET(num_buses) - 1; + snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN, + "PCI MMCONFIG %04x [bus %02x-%02x]", + cfg->segment, cfg->start_bus, cfg->end_bus); + + if (dev) + dev_info(dev, + "MMCONFIG " + "at %pR (base %#lx) (size reduced!)\n", + &cfg->res, (unsigned long) cfg->address); + else printk(KERN_INFO PREFIX - "MMCONFIG for %04x [bus%02x-%02x] " - "at %pR (base %#lx) (size reduced!)\n", - cfg->segment, cfg->start_bus, cfg->end_bus, - &cfg->res, (unsigned long) cfg->address); - } + "MMCONFIG for %04x [bus%02x-%02x] " + "at %pR (base %#lx) (size reduced!)\n", + cfg->segment, cfg->start_bus, cfg->end_bus, + &cfg->res, (unsigned long) cfg->address); } - return valid; + return 1; } -static int __devinit pci_mmcfg_check_reserved(struct pci_mmcfg_region *cfg, - int early) +static int __ref pci_mmcfg_check_reserved(struct device *dev, + struct pci_mmcfg_region *cfg, int early) { if (!early && !acpi_disabled) { - if (is_mmconf_reserved(is_acpi_reserved, cfg, 0)) + if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0)) return 1; + + if (dev) + dev_info(dev, FW_INFO + "MMCONFIG at %pR not reserved in " + "ACPI motherboard resources\n", + &cfg->res); else - printk(KERN_ERR FW_BUG PREFIX + printk(KERN_INFO FW_INFO PREFIX "MMCONFIG at %pR not reserved in " "ACPI motherboard resources\n", &cfg->res); } + /* + * e820_all_mapped() is marked as __init. + * All entries from ACPI MCFG table have been checked at boot time. + * For MCFG information constructed from hotpluggable host bridge's + * _CBA method, just assume it's reserved. + */ + if (pci_mmcfg_running_state) + return 1; + /* Don't try to do this check unless configuration type 1 is available. how about type 2 ?*/ if (raw_pci_ops) - return is_mmconf_reserved(e820_all_mapped, cfg, 1); + return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1); return 0; } @@ -517,7 +547,7 @@ static void __init pci_mmcfg_reject_broken(int early) struct pci_mmcfg_region *cfg; list_for_each_entry(cfg, &pci_mmcfg_list, list) { - if (pci_mmcfg_check_reserved(cfg, early) == 0) { + if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) { printk(KERN_INFO PREFIX "not using MMCONFIG\n"); free_all_mmcfg(); return; @@ -656,6 +686,8 @@ void __init pci_mmcfg_late_init(void) static int __init pci_mmcfg_late_insert_resources(void) { + pci_mmcfg_running_state = true; + /* * If resources are already inserted or we are not using MMCONFIG, * don't insert the resources. -- GitLab From 9c95111b330d2ddf851444528a7608f267cbb50c Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:15 +0800 Subject: [PATCH 2489/6849] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug Introduce pci_mmconfig_insert()/pci_mmconfig_delete(), which will be used to update MMCONFIG information when supporting PCI root bridge hotplug. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/include/asm/pci_x86.h | 4 ++ arch/x86/pci/mmconfig-shared.c | 109 +++++++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index df898ceab4d4..af5018f3d7c3 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -137,6 +137,10 @@ extern int __init pci_mmcfg_arch_init(void); extern void __init pci_mmcfg_arch_free(void); extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg); extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg); +extern int __devinit pci_mmconfig_insert(struct device *dev, + u16 seg, u8 start, + u8 end, phys_addr_t addr); +extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end); extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); extern struct list_head pci_mmcfg_list; diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 15a7abf5139c..19fc42b9f823 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -28,6 +28,7 @@ /* Indicate if the mmcfg resources have been placed into the resource table. */ static int __initdata pci_mmcfg_resources_inserted; static bool pci_mmcfg_running_state; +static bool pci_mmcfg_arch_init_failed; static DEFINE_MUTEX(pci_mmcfg_lock); LIST_HEAD(pci_mmcfg_list); @@ -92,10 +93,6 @@ static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end); res->name = new->name; - printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at " - "%pR (base %#lx)\n", segment, start, end, &new->res, - (unsigned long) addr); - return new; } @@ -109,6 +106,11 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, mutex_lock(&pci_mmcfg_lock); list_add_sorted(new); mutex_unlock(&pci_mmcfg_lock); + + printk(KERN_INFO PREFIX + "MMCONFIG for domain %04x [bus %02x-%02x] at %pR " + "(base %#lx)\n", + segment, start, end, &new->res, (unsigned long)addr); } return new; @@ -671,6 +673,7 @@ static void __init __pci_mmcfg_init(int early) * the architecture mmcfg setup could not initialize. */ pci_mmcfg_resources_inserted = 1; + pci_mmcfg_arch_init_failed = true; } } @@ -713,3 +716,101 @@ static int __init pci_mmcfg_late_insert_resources(void) * with other system resources. */ late_initcall(pci_mmcfg_late_insert_resources); + +/* Add MMCFG information for host bridges */ +int __devinit pci_mmconfig_insert(struct device *dev, + u16 seg, u8 start, u8 end, + phys_addr_t addr) +{ + int rc; + struct resource *tmp = NULL; + struct pci_mmcfg_region *cfg; + + if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) + return -ENODEV; + + if (start > end) + return -EINVAL; + + mutex_lock(&pci_mmcfg_lock); + cfg = pci_mmconfig_lookup(seg, start); + if (cfg) { + if (cfg->end_bus < end) + dev_info(dev, FW_INFO + "MMCONFIG for " + "domain %04x [bus %02x-%02x] " + "only partially covers this bridge\n", + cfg->segment, cfg->start_bus, cfg->end_bus); + mutex_unlock(&pci_mmcfg_lock); + return -EEXIST; + } + + if (!addr) { + mutex_unlock(&pci_mmcfg_lock); + return -EINVAL; + } + + rc = -EBUSY; + cfg = pci_mmconfig_alloc(seg, start, end, addr); + if (cfg == NULL) { + dev_warn(dev, "fail to add MMCONFIG (out of memory)\n"); + rc = -ENOMEM; + } else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) { + dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n", + &cfg->res); + } else { + /* Insert resource if it's not in boot stage */ + if (pci_mmcfg_running_state) + tmp = insert_resource_conflict(&iomem_resource, + &cfg->res); + + if (tmp) { + dev_warn(dev, + "MMCONFIG %pR conflicts with " + "%s %pR\n", + &cfg->res, tmp->name, tmp); + } else if (pci_mmcfg_arch_map(cfg)) { + dev_warn(dev, "fail to map MMCONFIG %pR.\n", + &cfg->res); + } else { + list_add_sorted(cfg); + dev_info(dev, "MMCONFIG at %pR (base %#lx)\n", + &cfg->res, (unsigned long)addr); + cfg = NULL; + rc = 0; + } + } + + if (cfg) { + if (cfg->res.parent) + release_resource(&cfg->res); + kfree(cfg); + } + + mutex_unlock(&pci_mmcfg_lock); + + return rc; +} + +/* Delete MMCFG information for host bridges */ +int pci_mmconfig_delete(u16 seg, u8 start, u8 end) +{ + struct pci_mmcfg_region *cfg; + + mutex_lock(&pci_mmcfg_lock); + list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) + if (cfg->segment == seg && cfg->start_bus == start && + cfg->end_bus == end) { + list_del_rcu(&cfg->list); + synchronize_rcu(); + pci_mmcfg_arch_unmap(cfg); + if (cfg->res.parent) + release_resource(&cfg->res); + mutex_unlock(&pci_mmcfg_lock); + kfree(cfg); + return 0; + } + mutex_unlock(&pci_mmcfg_lock); + + return -ENOENT; +} -- GitLab From f4b57a3b4352f72e461e362cb25917e28bdba80f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:16 +0800 Subject: [PATCH 2490/6849] PCI/ACPI: provide MMCONFIG address for PCI host bridges This patch provide MMCONFIG address for PCI host bridges, which will be used to support host bridge hotplug. It gets MMCONFIG address by evaluating _CBA method if available. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- drivers/acpi/pci_root.c | 2 ++ drivers/pci/pci-acpi.c | 14 ++++++++++++++ include/acpi/acnames.h | 1 + include/acpi/acpi_bus.h | 1 + include/linux/pci-acpi.h | 1 + 5 files changed, 19 insertions(+) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7aff6312ce7c..ec54014c321c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -505,6 +505,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); device->driver_data = root; + root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); + /* * All supported architectures that use ACPI have support for * PCI domains, so we indicate this in _OSC support capabilities. diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 61e2fefeedab..87f4c504eafb 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -162,6 +162,20 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) return remove_pm_notifier(dev, pci_acpi_wake_dev); } +phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) +{ + acpi_status status = AE_NOT_EXIST; + unsigned long long mcfg_addr; + + if (handle) + status = acpi_evaluate_integer(handle, METHOD_NAME__CBA, + NULL, &mcfg_addr); + if (ACPI_FAILURE(status)) + return 0; + + return (phys_addr_t)mcfg_addr; +} + /* * _SxD returns the D-state with the highest power * (lowest D-state number) supported in the S-state "x". diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 38f508816e4a..b177f97f53b6 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -62,6 +62,7 @@ #define METHOD_NAME__AEI "_AEI" #define METHOD_NAME__PRW "_PRW" #define METHOD_NAME__SRS "_SRS" +#define METHOD_NAME__CBA "_CBA" /* Method names - these methods must appear at the namespace root */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 9e6e1c6eb60a..457974073994 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -401,6 +401,7 @@ struct acpi_pci_root { u32 osc_support_set; /* _OSC state of support bits */ u32 osc_control_set; /* _OSC state of control bits */ + phys_addr_t mcfg_addr; }; /* helper */ diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 44623500f419..248fba2af98a 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -17,6 +17,7 @@ extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev); extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, struct pci_dev *pci_dev); extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev); +extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) { -- GitLab From c0fa40784cce9cc66b54499a3762cfe07e35353f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:17 +0800 Subject: [PATCH 2491/6849] x86/PCI: update MMCONFIG information when hot-plugging PCI host bridges This patch enhances x86 arch-specific code to update MMCONFIG information when PCI host bridge hotplug event happens. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/include/asm/pci_x86.h | 1 + arch/x86/pci/acpi.c | 93 ++++++++++++++++++++++++++++++++-- arch/x86/pci/mmconfig_32.c | 2 +- arch/x86/pci/mmconfig_64.c | 2 +- 4 files changed, 93 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index af5018f3d7c3..b2652e95b3d7 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -100,6 +100,7 @@ struct pci_raw_ops { extern const struct pci_raw_ops *raw_pci_ops; extern const struct pci_raw_ops *raw_pci_ext_ops; +extern const struct pci_raw_ops pci_mmcfg; extern const struct pci_raw_ops pci_direct_conf1; extern bool port_cf9_safe; diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 2bb885afe103..912b54b26d6a 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -13,6 +13,12 @@ struct pci_root_info { unsigned int res_num; struct resource *res; struct pci_sysdata sd; +#ifdef CONFIG_PCI_MMCONFIG + bool mcfg_added; + u16 segment; + u8 start_bus; + u8 end_bus; +#endif }; static bool pci_use_crs = true; @@ -119,6 +125,81 @@ void __init pci_acpi_crs_quirks(void) pci_use_crs ? "nocrs" : "use_crs"); } +#ifdef CONFIG_PCI_MMCONFIG +static int __devinit check_segment(u16 seg, struct device *dev, char *estr) +{ + if (seg) { + dev_err(dev, + "%s can't access PCI configuration " + "space under this host bridge.\n", + estr); + return -EIO; + } + + /* + * Failure in adding MMCFG information is not fatal, + * just can't access extended configuration space of + * devices under this host bridge. + */ + dev_warn(dev, + "%s can't access extended PCI configuration " + "space under this bridge.\n", + estr); + + return 0; +} + +static int __devinit setup_mcfg_map(struct pci_root_info *info, + u16 seg, u8 start, u8 end, + phys_addr_t addr) +{ + int result; + struct device *dev = &info->bridge->dev; + + info->start_bus = start; + info->end_bus = end; + info->mcfg_added = false; + + /* return success if MMCFG is not in use */ + if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg) + return 0; + + if (!(pci_probe & PCI_PROBE_MMCONF)) + return check_segment(seg, dev, "MMCONFIG is disabled,"); + + result = pci_mmconfig_insert(dev, seg, start, end, addr); + if (result == 0) { + /* enable MMCFG if it hasn't been enabled yet */ + if (raw_pci_ext_ops == NULL) + raw_pci_ext_ops = &pci_mmcfg; + info->mcfg_added = true; + } else if (result != -EEXIST) + return check_segment(seg, dev, + "fail to add MMCONFIG information,"); + + return 0; +} + +static void teardown_mcfg_map(struct pci_root_info *info) +{ + if (info->mcfg_added) { + pci_mmconfig_delete(info->segment, info->start_bus, + info->end_bus); + info->mcfg_added = false; + } +} +#else +static int __devinit setup_mcfg_map(struct pci_root_info *info, + u16 seg, u8 start, u8 end, + phys_addr_t addr) +{ + return 0; +} +static void teardown_mcfg_map(struct pci_root_info *info) +{ +} +#endif + static acpi_status resource_to_addr(struct acpi_resource *resource, struct acpi_resource_address64 *addr) @@ -331,8 +412,11 @@ static void __release_pci_root_info(struct pci_root_info *info) free_pci_root_info_res(info); + teardown_mcfg_map(info); + kfree(info); } + static void release_pci_root_info(struct pci_host_bridge *bridge) { struct pci_root_info *info = bridge->release_data; @@ -372,7 +456,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) int domain = root->segment; int busnum = root->secondary.start; LIST_HEAD(resources); - struct pci_bus *bus; + struct pci_bus *bus = NULL; struct pci_sysdata *sd; int node; #ifdef CONFIG_ACPI_NUMA @@ -438,8 +522,11 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) x86_pci_root_bus_resources(busnum, &resources); } - bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, - &resources); + if (!setup_mcfg_map(info, domain, (u8)root->secondary.start, + (u8)root->secondary.end, root->mcfg_addr)) + bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, + sd, &resources); + if (bus) { pci_scan_child_bus(bus); pci_set_host_bridge_release( diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index a22785deb50e..db63ac23e3d9 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c @@ -126,7 +126,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, return 0; } -static const struct pci_raw_ops pci_mmcfg = { +const struct pci_raw_ops pci_mmcfg = { .read = pci_mmcfg_read, .write = pci_mmcfg_write, }; diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index ebefea5107a7..c206521fe98e 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -90,7 +90,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, return 0; } -static const struct pci_raw_ops pci_mmcfg = { +const struct pci_raw_ops pci_mmcfg = { .read = pci_mmcfg_read, .write = pci_mmcfg_write, }; -- GitLab From 66e8850a2a34e6c52105d92a0f0054b304cb7140 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:18 +0800 Subject: [PATCH 2492/6849] x86/PCI: simplify pci_mmcfg_late_insert_resources() Reduce redundant code to simplify pci_mmcfg_late_insert_resources(). Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 19fc42b9f823..332fabdeff43 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -26,7 +26,6 @@ #define PREFIX "PCI: " /* Indicate if the mmcfg resources have been placed into the resource table. */ -static int __initdata pci_mmcfg_resources_inserted; static bool pci_mmcfg_running_state; static bool pci_mmcfg_arch_init_failed; static DEFINE_MUTEX(pci_mmcfg_lock); @@ -373,18 +372,6 @@ static int __init pci_mmcfg_check_hostbridge(void) return !list_empty(&pci_mmcfg_list); } -static void __init pci_mmcfg_insert_resources(void) -{ - struct pci_mmcfg_region *cfg; - - list_for_each_entry(cfg, &pci_mmcfg_list, list) - if (!cfg->res.parent) - insert_resource(&iomem_resource, &cfg->res); - - /* Mark that the resources have been inserted. */ - pci_mmcfg_resources_inserted = 1; -} - static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res, void *data) { @@ -668,11 +655,7 @@ static void __init __pci_mmcfg_init(int early) if (pci_mmcfg_arch_init()) pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; else { - /* - * Signal not to attempt to insert mmcfg resources because - * the architecture mmcfg setup could not initialize. - */ - pci_mmcfg_resources_inserted = 1; + free_all_mmcfg(); pci_mmcfg_arch_init_failed = true; } } @@ -689,15 +672,12 @@ void __init pci_mmcfg_late_init(void) static int __init pci_mmcfg_late_insert_resources(void) { + struct pci_mmcfg_region *cfg; + pci_mmcfg_running_state = true; - /* - * If resources are already inserted or we are not using MMCONFIG, - * don't insert the resources. - */ - if ((pci_mmcfg_resources_inserted == 1) || - (pci_probe & PCI_PROBE_MMCONF) == 0 || - list_empty(&pci_mmcfg_list)) + /* If we are not using MMCONFIG, don't insert the resources. */ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 1; /* @@ -705,7 +685,9 @@ static int __init pci_mmcfg_late_insert_resources(void) * marked so it won't cause request errors when __request_region is * called. */ - pci_mmcfg_insert_resources(); + list_for_each_entry(cfg, &pci_mmcfg_list, list) + if (!cfg->res.parent) + insert_resource(&iomem_resource, &cfg->res); return 0; } -- GitLab From 8503562fd4e8e261bd7ca442705c6e8f0fd88228 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:19 +0800 Subject: [PATCH 2493/6849] x86/PCI: get rid of redundant log messages For each resource of a PCI host bridge, the arch code and PCI code log following messages. We don't need both, so drop the arch-specific printing. pci_root PNP0A08:00: host bridge window [io 0x0000-0x03af] pci_bus 0000:00: root bus resource [io 0x0000-0x03af] Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/acpi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 912b54b26d6a..505acdd6d600 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -314,13 +314,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data) } info->res_num++; - if (addr.translation_offset) - dev_info(&info->bridge->dev, "host bridge window %pR " - "(PCI address [%#llx-%#llx])\n", - res, res->start - addr.translation_offset, - res->end - addr.translation_offset); - else - dev_info(&info->bridge->dev, "host bridge window %pR\n", res); return AE_OK; } -- GitLab From 574a59414083df3911e5a1514742959b412b6947 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:20 +0800 Subject: [PATCH 2494/6849] x86/PCI: refine __pci_mmcfg_init() for better code readability Refine __pci_mmcfg_init() for better code readability. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 46 ++++++++++++++++------------------ 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 332fabdeff43..ffe72b9d6869 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -544,8 +544,6 @@ static void __init pci_mmcfg_reject_broken(int early) } } -static int __initdata known_bridge; - static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, struct acpi_mcfg_allocation *cfg) { @@ -617,28 +615,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) static void __init __pci_mmcfg_init(int early) { - /* MMCONFIG disabled */ - if ((pci_probe & PCI_PROBE_MMCONF) == 0) - return; - - /* MMCONFIG already enabled */ - if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF)) - return; - - /* for late to exit */ - if (known_bridge) - return; - - if (early) { - if (pci_mmcfg_check_hostbridge()) - known_bridge = 1; - } - - if (!known_bridge) - acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); - pci_mmcfg_reject_broken(early); - if (list_empty(&pci_mmcfg_list)) return; @@ -660,14 +637,33 @@ static void __init __pci_mmcfg_init(int early) } } +static int __initdata known_bridge; + void __init pci_mmcfg_early_init(void) { - __pci_mmcfg_init(1); + if (pci_probe & PCI_PROBE_MMCONF) { + if (pci_mmcfg_check_hostbridge()) + known_bridge = 1; + else + acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); + __pci_mmcfg_init(1); + } } void __init pci_mmcfg_late_init(void) { - __pci_mmcfg_init(0); + /* MMCONFIG disabled */ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) + return; + + if (known_bridge) + return; + + /* MMCONFIG hasn't been enabled yet, try again */ + if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) { + acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); + __pci_mmcfg_init(0); + } } static int __init pci_mmcfg_late_insert_resources(void) -- GitLab From 24c97f04c4570e02c5cf4b97c73ab9dc27bacdbe Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:22 +0800 Subject: [PATCH 2495/6849] x86/PCI: use pr_level() to replace printk(KERN_LEVEL) Script checkpatch.pl recommends to replace printk(KERN_LVL) with pr_lvl(), so do it. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 21 +++++++++------------ arch/x86/pci/mmconfig_64.c | 3 +-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index ffe72b9d6869..937bcece7006 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -106,7 +106,7 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, list_add_sorted(new); mutex_unlock(&pci_mmcfg_lock); - printk(KERN_INFO PREFIX + pr_info(PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at %pR " "(base %#lx)\n", segment, start, end, &new->res, (unsigned long)addr); @@ -362,8 +362,7 @@ static int __init pci_mmcfg_check_hostbridge(void) name = pci_mmcfg_probes[i].probe(); if (name) - printk(KERN_INFO PREFIX "%s with MMCONFIG support\n", - name); + pr_info(PREFIX "%s with MMCONFIG support\n", name); } /* some end_bus_number is crazy, fix it */ @@ -465,8 +464,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved, dev_info(dev, "MMCONFIG at %pR reserved in %s\n", &cfg->res, method); else - printk(KERN_INFO PREFIX - "MMCONFIG at %pR reserved in %s\n", + pr_info(PREFIX "MMCONFIG at %pR reserved in %s\n", &cfg->res, method); if (old_size != size) { @@ -485,7 +483,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved, "at %pR (base %#lx) (size reduced!)\n", &cfg->res, (unsigned long) cfg->address); else - printk(KERN_INFO PREFIX + pr_info(PREFIX "MMCONFIG for %04x [bus%02x-%02x] " "at %pR (base %#lx) (size reduced!)\n", cfg->segment, cfg->start_bus, cfg->end_bus, @@ -508,7 +506,7 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev, "ACPI motherboard resources\n", &cfg->res); else - printk(KERN_INFO FW_INFO PREFIX + pr_info(FW_INFO PREFIX "MMCONFIG at %pR not reserved in " "ACPI motherboard resources\n", &cfg->res); @@ -537,7 +535,7 @@ static void __init pci_mmcfg_reject_broken(int early) list_for_each_entry(cfg, &pci_mmcfg_list, list) { if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) { - printk(KERN_INFO PREFIX "not using MMCONFIG\n"); + pr_info(PREFIX "not using MMCONFIG\n"); free_all_mmcfg(); return; } @@ -562,7 +560,7 @@ static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, return 0; } - printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " + pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " "is above 4GB, ignored\n", cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number, cfg->address); return -EINVAL; @@ -589,7 +587,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) i -= sizeof(struct acpi_mcfg_allocation); }; if (entries == 0) { - printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); + pr_err(PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } @@ -603,8 +601,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number, cfg->address) == NULL) { - printk(KERN_WARNING PREFIX - "no memory for MCFG entries\n"); + pr_warn(PREFIX "no memory for MCFG entries\n"); free_all_mmcfg(); return -ENOMEM; } diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index c206521fe98e..d4ebd07c306d 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -137,8 +137,7 @@ int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) { cfg->virt = mcfg_ioremap(cfg); if (!cfg->virt) { - printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", - &cfg->res); + pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res); return -ENOMEM; } -- GitLab From c0233ed4b3f74cf4c129d73c27af8ee057ced1ca Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 24 May 2012 14:18:14 -0600 Subject: [PATCH 2496/6849] MAINTAINERS: correct PCI git tree address Signed-off-by: Bjorn Helgaas --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 14bc7071f9df..28b4679d8c75 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5195,7 +5195,7 @@ PCI SUBSYSTEM M: Bjorn Helgaas L: linux-pci@vger.kernel.org Q: http://patchwork.ozlabs.org/project/linux-pci/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/linux.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git S: Supported F: Documentation/PCI/ F: drivers/pci/ -- GitLab From 397038519f2c2ac68c125c0cd766e91041c52b30 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 22 Jun 2012 14:55:21 +0800 Subject: [PATCH 2497/6849] ACPI: mark acpi_sfi_table_parse() as __init Mark function acpi_sfi_table_parse() as __init to avoid warning messages: WARNING: vmlinux.o(.text+0x4cd2d2): Section mismatch in reference from the function acpi_sfi_table_parse.clone.0() to the function Function acpi_sfi_table_parse() calls acpi_table_parse() and pci_parse_mcfg(), which are both marked as __init. Currently acpi_sfi_table_parse() is only used by MMCONFIG to scan MCFG table at boot time only, so it's safe to mark acpi_sfi_table_parse() as __init. Reviewed-by: Yinghai Lu Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- include/linux/sfi_acpi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/sfi_acpi.h b/include/linux/sfi_acpi.h index c4a5a8cd4469..631af63af42d 100644 --- a/include/linux/sfi_acpi.h +++ b/include/linux/sfi_acpi.h @@ -66,7 +66,7 @@ extern int sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id, int (*handler)(struct acpi_table_header *)); -static inline int acpi_sfi_table_parse(char *signature, +static inline int __init acpi_sfi_table_parse(char *signature, int (*handler)(struct acpi_table_header *)) { if (!acpi_table_parse(signature, handler)) @@ -83,7 +83,7 @@ static inline int sfi_acpi_table_parse(char *signature, char *oem_id, return -1; } -static inline int acpi_sfi_table_parse(char *signature, +static inline int __init acpi_sfi_table_parse(char *signature, int (*handler)(struct acpi_table_header *)) { return acpi_table_parse(signature, handler); -- GitLab From 9973290ce20ace7cac8ad06f753468c0b826fd0f Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 20 Jun 2012 22:52:24 +0100 Subject: [PATCH 2498/6849] ARM: 7428/1: Prevent KALLSYM size mismatch on ARM. ARM builds seem to be plagued by an occasional build error: Inconsistent kallsyms data This is a bug - please report about it Try "make KALLSYMS_EXTRA_PASS=1" as a workaround The problem has to do with alignment of some sections by the linker. The kallsyms data is built in two passes by first linking the kernel without it, and then linking the kernel again with the symbols included. Normally, this just shifts the symbols, without changing their order, and the compression used by the kallsyms gives the same result. On non SMP, the per CPU data is empty. Depending on the where the alignment ends up, it can come out as either: +-------------------+ | last text segment | +-------------------+ /* padding */ +-------------------+ <- L1_CACHE_BYTES alignemnt | per cpu (empty) | +-------------------+ __per_cpu_end: /* padding */ __data_loc: +-------------------+ <- THREAD_SIZE alignment | data | +-------------------+ or +-------------------+ | last text segment | +-------------------+ /* padding */ +-------------------+ <- L1_CACHE_BYTES alignemnt | per cpu (empty) | +-------------------+ __per_cpu_end: /* no padding */ __data_loc: +-------------------+ <- THREAD_SIZE alignment | data | +-------------------+ if the alignment satisfies both. Because symbols that have the same address are sorted by 'nm -n', the second case will be in a different order than the first case. This changes the compression, changing the size of the kallsym data, causing the build failure. The KALLSYMS_EXTRA_PASS=1 workaround usually works, but it is still possible to have the alignment change between the second and third pass. It's probably even possible for it to never reach a fixedpoint. The problem only occurs on non-SMP, when the per-cpu data is empty, and when the data segment has alignment (and immediately follows the text segments). Fix this by only including the per_cpu section on SMP, when it is not empty. Signed-off-by: David Brown Signed-off-by: Russell King --- arch/arm/kernel/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 43a31fb06318..36ff15bbfdd4 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -183,7 +183,9 @@ SECTIONS } #endif +#ifdef CONFIG_SMP PERCPU_SECTION(L1_CACHE_BYTES) +#endif #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ -- GitLab From 58bf8062d0b293b8e1028e5b0342082002886bd4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 21 Jun 2012 14:55:22 +0200 Subject: [PATCH 2499/6849] drm/i915: rip out the PM_IIR WARN After banging my head against this for the past few months, I still don't see how this could possible race under the premise that once an irq bit is masked in PM_IMR and reset in PM_IIR it won't show up again until we unmask it in PM_IMR. Still, we have reports of this being seen in the wild. Now Bspec has this little bit of lovely language in the PMIIR register: Public SNB Docs, Vol3Part2, 2.5.14 "PMIIR": "For each bit, the IIR can store a second pending interrupt if two or more of the same interrupt conditions occur before the first condition is cleared. Upon clearing the interrupt, the IIR bit will momentarily go low, then return high to indicate there is another interrupt pending." Now if we presume that PMIMR only prevent new interrupts from being queued, we could easily end up masking an interrupt and clearing it, but the 2nd pending interrupt setting the bit in PMIIR right away again. Which leads, the next time the irq handler runs, to hitting the WARN. Also, no bad side effects of this have ever been reported. And we've tracked down our issues with the gpu turbo getting stuck to bogus interrupt generation limits in th RPLIMIT register. So let's just rip out this WARN as bogus and call it a day. The only shallow thing here is that this 2-deep irq queue in the hw makes you wonder how racy the windows irq handler is ... Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42907 Cc: stable@vger.kernel.org Acked-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1fe0edda955..ed3224c37423 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -412,7 +412,6 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, */ spin_lock_irqsave(&dev_priv->rps_lock, flags); - WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); dev_priv->pm_iir |= pm_iir; I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); POSTING_READ(GEN6_PMIMR); -- GitLab From 6db65cbb941f9d433659bdad02b307f6d94465df Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Jun 2012 15:30:41 +0200 Subject: [PATCH 2500/6849] drm/i915: Fix eDP blank screen after S3 resume on HP desktops This patch fixes the problem on some HP desktop machines with eDP which give blank screens after S3 resume. It turned out that BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2. Otherwise it doesn't take effect on these SNB machines. Tested with 3.5-rc3 kernel. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49233 Cc: Signed-off-by: Takashi Iwai Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_suspend.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 0ede02a99d91..a748e5cabe14 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -740,8 +740,11 @@ static void i915_restore_display(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); + /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; + * otherwise we get blank eDP screen after S3 on some machines + */ I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); + I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); -- GitLab From 86f887c105b909a2cea7b06f2136d66b3438b038 Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Sat, 23 Jun 2012 01:12:09 +0200 Subject: [PATCH 2501/6849] ARM: shmobile: r8a7779: Route all interrupts to ARM Without this, the interrupts for I2C, VIN, GPIO, SDHC, HSCIF and HPB-DMAC are sent to the SH processor. Signed-off-by: Phil Edworthy Acked-by: Magnus Damm Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/intc-r8a7779.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c index 550b23df4fd4..f04fad4ec4fb 100644 --- a/arch/arm/mach-shmobile/intc-r8a7779.c +++ b/arch/arm/mach-shmobile/intc-r8a7779.c @@ -35,6 +35,9 @@ #define INT2SMSKCR3 0xfe7822ac #define INT2SMSKCR4 0xfe7822b0 +#define INT2NTSR0 0xfe700060 +#define INT2NTSR1 0xfe700064 + static int r8a7779_set_wake(struct irq_data *data, unsigned int on) { return 0; /* always allow wakeup */ @@ -49,6 +52,10 @@ void __init r8a7779_init_irq(void) gic_init(0, 29, gic_dist_base, gic_cpu_base); gic_arch_extn.irq_set_wake = r8a7779_set_wake; + /* route all interrupts to ARM */ + __raw_writel(0xffffffff, INT2NTSR0); + __raw_writel(0x3fffffff, INT2NTSR1); + /* unmask all known interrupts in INTCS2 */ __raw_writel(0xfffffff0, INT2SMSKCR0); __raw_writel(0xfff7ffff, INT2SMSKCR1); -- GitLab From 8e27628ecf883b9e5825103e40e6f86bf8225f1a Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Fri, 22 Jun 2012 01:10:15 +0000 Subject: [PATCH 2502/6849] smsc911x.c: encapsulate enable irq calls We encapsulate enbale irq functionality in a function call. As on probe the interrupts will be disabled twice, we delete one. Signed-off-by: Matthias Brugger Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 1466e5d2af44..54ca99dbb406 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1442,6 +1442,14 @@ smsc911x_set_hw_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6]) smsc911x_mac_write(pdata, ADDRL, mac_low32); } +static void smsc911x_disable_irq_chip(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + + smsc911x_reg_write(pdata, INT_EN, 0); + smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF); +} + static int smsc911x_open(struct net_device *dev) { struct smsc911x_data *pdata = netdev_priv(dev); @@ -1494,8 +1502,7 @@ static int smsc911x_open(struct net_device *dev) spin_unlock_irq(&pdata->mac_lock); /* Initialise irqs, but leave all sources disabled */ - smsc911x_reg_write(pdata, INT_EN, 0); - smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF); + smsc911x_disable_irq_chip(dev); /* Set interrupt deassertion to 100uS */ intcfg = ((10 << 24) | INT_CFG_IRQ_EN_); @@ -2215,9 +2222,6 @@ static int __devinit smsc911x_init(struct net_device *dev) if (smsc911x_soft_reset(pdata)) return -ENODEV; - /* Disable all interrupt sources until we bring the device up */ - smsc911x_reg_write(pdata, INT_EN, 0); - ether_setup(dev); dev->flags |= IFF_MULTICAST; netif_napi_add(dev, &pdata->napi, smsc911x_poll, SMSC_NAPI_WEIGHT); @@ -2434,8 +2438,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) smsc911x_reg_write(pdata, INT_CFG, intcfg); /* Ensure interrupts are globally disabled before connecting ISR */ - smsc911x_reg_write(pdata, INT_EN, 0); - smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF); + smsc911x_disable_irq_chip(dev); retval = request_irq(dev->irq, smsc911x_irqhandler, irq_flags | IRQF_SHARED, dev->name, dev); -- GitLab From 6648bd7e0e62c0c8c03b15e00c9e7015e232feff Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 21 Jun 2012 13:58:31 +0000 Subject: [PATCH 2503/6849] ipv4: Add sysctl knob to control early socket demux This change is meant to add a control for disabling early socket demux. The main motivation behind this patch is to provide an option to disable the feature as it adds an additional cost to routing that reduces overall throughput by up to 5%. For example one of my systems went from 12.1Mpps to 11.6 after the early socket demux was added. It looks like the reason for the regression is that we are now having to perform two lookups, first the one for an established socket, and then the one for the routing table. By adding this patch and toggling the value for ip_early_demux to 0 I am able to get back to the 12.1Mpps I was previously seeing. [ Move local variables in ip_rcv_finish() down into the basic block in which they are actually used. -DaveM ] Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- include/linux/sysctl.h | 1 + include/net/ip.h | 3 +++ kernel/sysctl_binary.c | 2 ++ net/ipv4/ip_input.c | 22 +++++++++++++--------- net/ipv4/sysctl_net_ipv4.c | 7 +++++++ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index c34b4c82b0dc..20825e5f433f 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -425,6 +425,7 @@ enum NET_TCP_ALLOWED_CONG_CONTROL=123, NET_TCP_MAX_SSTHRESH=124, NET_TCP_FRTO_RESPONSE=125, + NET_IPV4_EARLY_DEMUX=126, }; enum { diff --git a/include/net/ip.h b/include/net/ip.h index 83e0619f59d0..50841bd6f10e 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -210,6 +210,9 @@ extern int inet_peer_threshold; extern int inet_peer_minttl; extern int inet_peer_maxttl; +/* From ip_input.c */ +extern int sysctl_ip_early_demux; + /* From ip_output.c */ extern int sysctl_ip_dynaddr; diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index a650694883a1..6a3cf8253aae 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -415,6 +415,8 @@ static const struct bin_table bin_net_ipv4_table[] = { { CTL_INT, NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, /* NET_IPV4_IPFRAG_MAX_DIST "ipfrag_max_dist" no longer used */ + { CTL_INT, NET_IPV4_EARLY_DEMUX, "ip_early_demux" }, + { CTL_INT, 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, /* NET_TCP_DEFAULT_WIN_SCALE unused */ diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 93b092c9a394..bca25179cdb9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -313,6 +313,8 @@ drop: return true; } +int sysctl_ip_early_demux __read_mostly = 1; + static int ip_rcv_finish(struct sk_buff *skb) { const struct iphdr *iph = ip_hdr(skb); @@ -323,16 +325,18 @@ static int ip_rcv_finish(struct sk_buff *skb) * how the packet travels inside Linux networking. */ if (skb_dst(skb) == NULL) { - const struct net_protocol *ipprot; - int protocol = iph->protocol; - int err; + int err = -ENOENT; - rcu_read_lock(); - ipprot = rcu_dereference(inet_protos[protocol]); - err = -ENOENT; - if (ipprot && ipprot->early_demux) - err = ipprot->early_demux(skb); - rcu_read_unlock(); + if (sysctl_ip_early_demux) { + const struct net_protocol *ipprot; + int protocol = iph->protocol; + + rcu_read_lock(); + ipprot = rcu_dereference(inet_protos[protocol]); + if (ipprot && ipprot->early_demux) + err = ipprot->early_demux(skb); + rcu_read_unlock(); + } if (err) { err = ip_route_input_noref(skb, iph->daddr, iph->saddr, diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index ef32956ed655..12aa0c5867c4 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -300,6 +300,13 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "ip_early_demux", + .data = &sysctl_ip_early_demux, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, { .procname = "ip_dynaddr", .data = &sysctl_ip_dynaddr, -- GitLab From ab5e8b77d53ac8d4c7d9beafc73815da00cf19a5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 22 Jun 2012 11:25:33 +0200 Subject: [PATCH 2504/6849] netfilter: nfnetlink_queue: fix sparse warning due to missing include This patch fixes a sparse warning due to missing include header file. Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_queue_ct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nfnetlink_queue_ct.c b/net/netfilter/nfnetlink_queue_ct.c index 01247b730e66..ab61d66bc0b9 100644 --- a/net/netfilter/nfnetlink_queue_ct.c +++ b/net/netfilter/nfnetlink_queue_ct.c @@ -12,6 +12,7 @@ #include #include #include +#include struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo) -- GitLab From 8e36c4b5b673edc6081599b8bd461e062e4910f4 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 23 Jun 2012 01:43:51 +0200 Subject: [PATCH 2505/6849] netfilter: ctnetlink: fix compilation with NF_CONNTRACK_EVENTS=n This patch fixes compilation with NF_CONNTRACK_EVENTS=n and NETFILTER_NETLINK_QUEUE_CT=y. I'm leaving all those static inline functions that calculate the size of the event message out of the ifdef area of NF_CONNTRACK_EVENTS since they will not be included by gcc in case they are unused. Reported-by: Randy Dunlap Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 8bb47339b770..b9b8f4ac7a36 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -478,7 +478,6 @@ nla_put_failure: return -1; } -#ifdef CONFIG_NF_CONNTRACK_EVENTS static inline size_t ctnetlink_proto_size(const struct nf_conn *ct) { @@ -565,6 +564,7 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct) ; } +#ifdef CONFIG_NF_CONNTRACK_EVENTS static int ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) { -- GitLab From b9f90eb2740203ff2592efe640409ad48335d1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 21 Jun 2012 02:45:58 +0000 Subject: [PATCH 2506/6849] net: qmi_wwan: fix Gobi device probing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ignoring interfaces with additional descriptors is not a reliable method for locating the correct interface on Gobi devices. There is at least one device where this method fails: https://bbs.archlinux.org/viewtopic.php?id=143506 The result is that the AT command port (interface #2) is hidden from qcserial, preventing traditional serial modem usage: [ 15.562552] qmi_wwan 4-1.6:1.0: cdc-wdm0: USB WDM device [ 15.562691] qmi_wwan 4-1.6:1.0: wwan0: register 'qmi_wwan' at usb-0000:00:1d.0-1.6, Qualcomm Gobi wwan/QMI device, 1e:df:3c:3a:4e:3b [ 15.563383] qmi_wwan: probe of 4-1.6:1.1 failed with error -22 [ 15.564189] qmi_wwan 4-1.6:1.2: cdc-wdm1: USB WDM device [ 15.564302] qmi_wwan 4-1.6:1.2: wwan1: register 'qmi_wwan' at usb-0000:00:1d.0-1.6, Qualcomm Gobi wwan/QMI device, 1e:df:3c:3a:4e:3b [ 15.564328] qmi_wwan: probe of 4-1.6:1.3 failed with error -22 [ 15.569376] qcserial 4-1.6:1.1: Qualcomm USB modem converter detected [ 15.569440] usb 4-1.6: Qualcomm USB modem converter now attached to ttyUSB0 [ 15.570372] qcserial 4-1.6:1.3: Qualcomm USB modem converter detected [ 15.570430] usb 4-1.6: Qualcomm USB modem converter now attached to ttyUSB1 Use static interface numbers taken from the interface map in qcserial for all Gobi devices instead: Gobi 1K USB layout: 0: serial port (doesn't respond) 1: serial port (doesn't respond) 2: AT-capable modem port 3: QMI/net Gobi 2K+ USB layout: 0: QMI/net 1: DM/DIAG (use libqcdm from ModemManager for communication) 2: AT-capable modem port 3: NMEA This should be more reliable over all, and will also prevent the noisy "probe failed" messages. The whitelisting logic is expected to be replaced by direct interface number matching in 3.6. Reported-by: Heinrich Siebmanns (Harvey) Cc: # v3.4: 0000188 USB: qmi_wwan: Make forced int 4 whitelist generic Cc: # v3.4: f7142e6 USB: qmi_wwan: Add ZTE (Vodafone) K3520-Z Cc: # v3.4 Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 83 ++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..3767a1225860 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -257,29 +257,6 @@ err: return rv; } -/* Gobi devices uses identical class/protocol codes for all interfaces regardless - * of function. Some of these are CDC ACM like and have the exact same endpoints - * we are looking for. This leaves two possible strategies for identifying the - * correct interface: - * a) hardcoding interface number, or - * b) use the fact that the wwan interface is the only one lacking additional - * (CDC functional) descriptors - * - * Let's see if we can get away with the generic b) solution. - */ -static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf) -{ - int rv = -EINVAL; - - /* ignore any interface with additional descriptors */ - if (intf->cur_altsetting->extralen) - goto err; - - rv = qmi_wwan_bind_shared(dev, intf); -err: - return rv; -} - static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) { struct usb_driver *subdriver = (void *)dev->data[0]; @@ -347,15 +324,15 @@ static const struct driver_info qmi_wwan_shared = { .manage_power = qmi_wwan_manage_power, }; -static const struct driver_info qmi_wwan_gobi = { - .description = "Qualcomm Gobi wwan/QMI device", +static const struct driver_info qmi_wwan_force_int0 = { + .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, + .data = BIT(0), /* interface whitelist bitmap */ }; -/* ZTE suck at making USB descriptors */ static const struct driver_info qmi_wwan_force_int1 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -365,6 +342,15 @@ static const struct driver_info qmi_wwan_force_int1 = { .data = BIT(1), /* interface whitelist bitmap */ }; +static const struct driver_info qmi_wwan_force_int3 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, + .data = BIT(3), /* interface whitelist bitmap */ +}; + static const struct driver_info qmi_wwan_force_int4 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -390,16 +376,23 @@ static const struct driver_info qmi_wwan_force_int4 = { static const struct driver_info qmi_wwan_sierra = { .description = "Sierra Wireless wwan/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ }; #define HUAWEI_VENDOR_ID 0x12D1 + +/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ +#define QMI_GOBI1K_DEVICE(vend, prod) \ + USB_DEVICE(vend, prod), \ + .driver_info = (unsigned long)&qmi_wwan_force_int3 + +/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ #define QMI_GOBI_DEVICE(vend, prod) \ USB_DEVICE(vend, prod), \ - .driver_info = (unsigned long)&qmi_wwan_gobi + .driver_info = (unsigned long)&qmi_wwan_force_int0 static const struct usb_device_id products[] = { { /* Huawei E392, E398 and possibly others sharing both device id and more... */ @@ -510,20 +503,24 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_sierra, }, - {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ - {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ - {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ - {QMI_GOBI_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ - {QMI_GOBI_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ - {QMI_GOBI_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ - {QMI_GOBI_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ + + /* Gobi 1000 devices */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ + {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ + {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ + {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ + + /* Gobi 2000 and 3000 devices */ {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ -- GitLab From d0b8a6f926be5109d711937a74b8d327b29470ba Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Jun 2012 19:05:18 +0000 Subject: [PATCH 2507/6849] bnx2x: sfp+ Tx fault detection added Adds the ability to identify sfp+ modules' Tx fault, and when such occur shut down the link. Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 2 + .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 112 +++++++++++++++--- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 1 + 3 files changed, 99 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 6b776309e0a1..e7c390c66b2a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -1150,6 +1150,7 @@ struct drv_port_mb { u32 link_status; /* Driver should update this field on any link change event */ + #define LINK_STATUS_NONE (0<<0) #define LINK_STATUS_LINK_FLAG_MASK 0x00000001 #define LINK_STATUS_LINK_UP 0x00000001 #define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E @@ -1207,6 +1208,7 @@ struct drv_port_mb { #define LINK_STATUS_PFC_ENABLED 0x20000000 #define LINK_STATUS_PHYSICAL_LINK_FLAG 0x40000000 + #define LINK_STATUS_SFP_TX_FAULT 0x80000000 u32 port_stx; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 91aa565d4374..9e008e4534d4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -4746,6 +4746,8 @@ void bnx2x_sync_link(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; + if (vars->link_status & LINK_STATUS_SFP_TX_FAULT) + vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG; } } @@ -12925,30 +12927,41 @@ static void bnx2x_check_over_curr(struct link_params *params, vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG; } -static void bnx2x_analyze_link_error(struct link_params *params, - struct link_vars *vars, u32 lss_status, - u8 notify) +/* Returns 0 if no change occured since last check; 1 otherwise. */ +static u8 bnx2x_analyze_link_error(struct link_params *params, + struct link_vars *vars, u32 status, + u32 phy_flag, u32 link_flag, u8 notify) { struct bnx2x *bp = params->bp; /* Compare new value with previous value */ u8 led_mode; - u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0; + u32 old_status = (vars->phy_flags & phy_flag) ? 1 : 0; - if ((lss_status ^ half_open_conn) == 0) - return; + if ((status ^ old_status) == 0) + return 0; /* If values differ */ - DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up, - half_open_conn, lss_status); + switch (phy_flag) { + case PHY_HALF_OPEN_CONN_FLAG: + DP(NETIF_MSG_LINK, "Analyze Remote Fault\n"); + break; + case PHY_SFP_TX_FAULT_FLAG: + DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); + break; + default: + DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); + } + DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, + old_status, status); /* a. Update shmem->link_status accordingly * b. Update link_vars->link_up */ - if (lss_status) { - DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n"); + if (status) { vars->link_status &= ~LINK_STATUS_LINK_UP; + vars->link_status |= link_flag; vars->link_up = 0; - vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; + vars->phy_flags |= phy_flag; /* activate nig drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1); @@ -12957,10 +12970,10 @@ static void bnx2x_analyze_link_error(struct link_params *params, */ led_mode = LED_MODE_OFF; } else { - DP(NETIF_MSG_LINK, "Remote Fault cleared\n"); vars->link_status |= LINK_STATUS_LINK_UP; + vars->link_status &= ~link_flag; vars->link_up = 1; - vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; + vars->phy_flags &= ~phy_flag; led_mode = LED_MODE_OPER; /* Clear nig drain */ @@ -12977,6 +12990,8 @@ static void bnx2x_analyze_link_error(struct link_params *params, vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT; if (notify) bnx2x_notify_link_changed(bp); + + return 1; } /****************************************************************************** @@ -13018,7 +13033,9 @@ int bnx2x_check_half_open_conn(struct link_params *params, if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS)) lss_status = 1; - bnx2x_analyze_link_error(params, vars, lss_status, notify); + bnx2x_analyze_link_error(params, vars, lss_status, + PHY_HALF_OPEN_CONN_FLAG, + LINK_STATUS_NONE, notify); } else if (REG_RD(bp, MISC_REG_RESET_REG_2) & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) { /* Check E1X / E2 BMAC */ @@ -13035,11 +13052,55 @@ int bnx2x_check_half_open_conn(struct link_params *params, REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2); lss_status = (wb_data[0] > 0); - bnx2x_analyze_link_error(params, vars, lss_status, notify); + bnx2x_analyze_link_error(params, vars, lss_status, + PHY_HALF_OPEN_CONN_FLAG, + LINK_STATUS_NONE, notify); } return 0; } +static void bnx2x_sfp_tx_fault_detection(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 cfg_pin, value = 0; + u8 led_change, port = params->port; + /* Get The SFP+ TX_Fault controlling pin ([eg]pio) */ + cfg_pin = (REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & + PORT_HW_CFG_E3_TX_FAULT_MASK) >> + PORT_HW_CFG_E3_TX_FAULT_SHIFT; + + if (bnx2x_get_cfg_pin(bp, cfg_pin, &value)) { + DP(NETIF_MSG_LINK, "Failed to read pin 0x%02x\n", cfg_pin); + return; + } + + led_change = bnx2x_analyze_link_error(params, vars, value, + PHY_SFP_TX_FAULT_FLAG, + LINK_STATUS_SFP_TX_FAULT, 1); + + if (led_change) { + /* Change TX_Fault led, set link status for further syncs */ + u8 led_mode; + + if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) { + led_mode = MISC_REGISTERS_GPIO_HIGH; + vars->link_status |= LINK_STATUS_SFP_TX_FAULT; + } else { + led_mode = MISC_REGISTERS_GPIO_LOW; + vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT; + } + + /* If module is unapproved, led should be on regardless */ + if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) { + DP(NETIF_MSG_LINK, "Change TX_Fault LED: ->%x\n", + led_mode); + bnx2x_set_e3_module_fault_led(params, led_mode); + } + } +} void bnx2x_period_func(struct link_params *params, struct link_vars *vars) { u16 phy_idx; @@ -13058,7 +13119,26 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars) struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; bnx2x_set_aer_mmd(params, phy); bnx2x_check_over_curr(params, vars); - bnx2x_warpcore_config_runtime(phy, params, vars); + if (vars->rx_tx_asic_rst) + bnx2x_warpcore_config_runtime(phy, params, vars); + + if ((REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].default_cfg)) + & PORT_HW_CFG_NET_SERDES_IF_MASK) == + PORT_HW_CFG_NET_SERDES_IF_SFI) { + if (bnx2x_is_sfp_module_plugged(phy, params)) { + bnx2x_sfp_tx_fault_detection(phy, params, vars); + } else if (vars->link_status & + LINK_STATUS_SFP_TX_FAULT) { + /* Clean trail, interrupt corrects the leds */ + vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT; + vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG; + /* Update link status in the shared memory */ + bnx2x_update_mng(params, vars->link_status); + } + } + } } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index e920800a7bc5..cd1f2719b62d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -307,6 +307,7 @@ struct link_vars { #define PHY_PHYSICAL_LINK_FLAG (1<<2) #define PHY_HALF_OPEN_CONN_FLAG (1<<3) #define PHY_OVER_CURRENT_FLAG (1<<4) +#define PHY_SFP_TX_FAULT_FLAG (1<<5) u8 mac_type; #define MAC_TYPE_NONE 0 -- GitLab From d231023eb17134e43bf1dcea631dd156d9904b70 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Jun 2012 19:05:19 +0000 Subject: [PATCH 2508/6849] bnx2x: link cleanup This patch does several things: 1. Add static to function when possible. 2. Correct comments. 3. Change msleep(small) --> usleep_range(small, small*2). Also correct existing calls to usleep_range. 4. Remove dead code. 5. Change 'if(rc != 0)' --> if(rc) Most of these changes are purely semantic. Signed-off-by: Yuval Mintz Signed-off-by: Yaniv Rosner Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 340 +++++++++--------- 1 file changed, 167 insertions(+), 173 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 9e008e4534d4..b3c33ed2bc96 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -284,7 +284,6 @@ #define ETS_E3B0_PBF_MIN_W_VAL (10000) #define MAX_PACKET_SIZE (9700) -#define WC_UC_TIMEOUT 100 #define MAX_KR_LINK_RETRY 4 /**********************************************************/ @@ -1627,7 +1626,7 @@ static void bnx2x_umac_enable(struct link_params *params, /* Reset UMAC */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)); - usleep_range(1000, 1000); + usleep_range(1000, 2000); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)); @@ -1729,7 +1728,7 @@ static void bnx2x_xmac_init(struct link_params *params, u32 max_speed) /* Hard reset */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, MISC_REGISTERS_RESET_REG_2_XMAC); - usleep_range(1000, 1000); + usleep_range(1000, 2000); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, MISC_REGISTERS_RESET_REG_2_XMAC); @@ -1759,7 +1758,7 @@ static void bnx2x_xmac_init(struct link_params *params, u32 max_speed) /* Soft reset */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, MISC_REGISTERS_RESET_REG_2_XMAC_SOFT); - usleep_range(1000, 1000); + usleep_range(1000, 2000); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, MISC_REGISTERS_RESET_REG_2_XMAC_SOFT); @@ -1880,11 +1879,6 @@ static int bnx2x_emac_enable(struct link_params *params, bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, EMAC_TX_MODE_RESET); - if (CHIP_REV_IS_SLOW(bp)) { - /* config GMII mode */ - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); - EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII)); - } else { /* ASIC */ /* pause enable/disable */ bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, EMAC_RX_MODE_FLOW_EN); @@ -1907,7 +1901,6 @@ static int bnx2x_emac_enable(struct link_params *params, } else bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, EMAC_TX_MODE_FLOW_EN); - } /* KEEP_VLAN_TAG, promiscuous */ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); @@ -1946,23 +1939,23 @@ static int bnx2x_emac_enable(struct link_params *params, val &= ~0x810; EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); - /* enable emac */ + /* Enable emac */ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1); - /* enable emac for jumbo packets */ + /* Enable emac for jumbo packets */ EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, (EMAC_RX_MTU_SIZE_JUMBO_ENA | (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); - /* strip CRC */ + /* Strip CRC */ REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1); - /* disable the NIG in/out to the bmac */ + /* Disable the NIG in/out to the bmac */ REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0); REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0); REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0); - /* enable the NIG in/out to the emac */ + /* Enable the NIG in/out to the emac */ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1); val = 0; if ((params->feature_config_flags & @@ -1997,7 +1990,7 @@ static void bnx2x_update_pfc_bmac1(struct link_params *params, wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2); - /* tx control */ + /* TX control */ val = 0xc0; if (!(params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) && @@ -2057,7 +2050,7 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params, wb_data[0] &= ~(1<<2); } else { DP(NETIF_MSG_LINK, "PFC is disabled\n"); - /* disable PFC RX & TX & STATS and set 8 COS */ + /* Disable PFC RX & TX & STATS and set 8 COS */ wb_data[0] = 0x8; wb_data[1] = 0; } @@ -2151,7 +2144,7 @@ static int bnx2x_pfc_brb_get_config_params( PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE; config_val->pauseable_th.full_xon = PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE; - /* non pause able*/ + /* Non pause able*/ config_val->non_pauseable_th.pause_xoff = PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; config_val->non_pauseable_th.pause_xon = @@ -2179,7 +2172,7 @@ static int bnx2x_pfc_brb_get_config_params( PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE; config_val->pauseable_th.full_xon = PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE; - /* non pause able*/ + /* Non pause able*/ config_val->non_pauseable_th.pause_xoff = PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; config_val->non_pauseable_th.pause_xon = @@ -2209,7 +2202,7 @@ static int bnx2x_pfc_brb_get_config_params( PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE; config_val->pauseable_th.full_xon = PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE; - /* non pause able*/ + /* Non pause able*/ config_val->non_pauseable_th.pause_xoff = PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; config_val->non_pauseable_th.pause_xon = @@ -2227,7 +2220,7 @@ static int bnx2x_pfc_brb_get_config_params( PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE; config_val->pauseable_th.full_xon = PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE; - /* non pause able*/ + /* Non pause able*/ config_val->non_pauseable_th.pause_xoff = PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; config_val->non_pauseable_th.pause_xon = @@ -2284,7 +2277,7 @@ static void bnx2x_pfc_brb_get_e3b0_config_params( if (pfc_params->cos0_pauseable != pfc_params->cos1_pauseable) { - /* nonpauseable= Lossy + pauseable = Lossless*/ + /* Nonpauseable= Lossy + pauseable = Lossless*/ e3b0_val->lb_guarantied = PFC_E3B0_2P_MIX_PAUSE_LB_GUART; e3b0_val->mac_0_class_t_guarantied = @@ -2483,9 +2476,9 @@ static int bnx2x_update_pfc_brb(struct link_params *params, * This function is needed because NIG ARB_CREDIT_WEIGHT_X are * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable. ******************************************************************************/ -int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp, - u8 cos_entry, - u32 priority_mask, u8 port) +static int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp, + u8 cos_entry, + u32 priority_mask, u8 port) { u32 nig_reg_rx_priority_mask_add = 0; @@ -2612,7 +2605,7 @@ static void bnx2x_update_pfc_nig(struct link_params *params, REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 : NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7); - /* output enable for RX_XCM # IF */ + /* Output enable for RX_XCM # IF */ REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN : NIG_REG_XCM0_OUT_EN, xcm_out_en); @@ -2661,10 +2654,10 @@ int bnx2x_update_pfc(struct link_params *params, bnx2x_update_mng(params, vars->link_status); - /* update NIG params */ + /* Update NIG params */ bnx2x_update_pfc_nig(params, vars, pfc_params); - /* update BRB params */ + /* Update BRB params */ bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params); if (bnx2x_status) return bnx2x_status; @@ -2719,7 +2712,7 @@ static int bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL, wb_data, 2); - /* tx MAC SA */ + /* TX MAC SA */ wb_data[0] = ((params->mac_addr[2] << 24) | (params->mac_addr[3] << 16) | (params->mac_addr[4] << 8) | @@ -2728,7 +2721,7 @@ static int bnx2x_bmac1_enable(struct link_params *params, params->mac_addr[1]); REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2); - /* mac control */ + /* MAC control */ val = 0x3; if (is_lb) { val |= 0x4; @@ -2738,24 +2731,24 @@ static int bnx2x_bmac1_enable(struct link_params *params, wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2); - /* set rx mtu */ + /* Set rx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2); bnx2x_update_pfc_bmac1(params, vars); - /* set tx mtu */ + /* Set tx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2); - /* set cnt max size */ + /* Set cnt max size */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2); - /* configure safc */ + /* Configure SAFC */ wb_data[0] = 0x1000200; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, @@ -2789,7 +2782,7 @@ static int bnx2x_bmac2_enable(struct link_params *params, udelay(30); - /* tx MAC SA */ + /* TX MAC SA */ wb_data[0] = ((params->mac_addr[2] << 24) | (params->mac_addr[3] << 16) | (params->mac_addr[4] << 8) | @@ -2808,18 +2801,18 @@ static int bnx2x_bmac2_enable(struct link_params *params, wb_data, 2); udelay(30); - /* set rx mtu */ + /* Set RX MTU */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2); udelay(30); - /* set tx mtu */ + /* Set TX MTU */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2); udelay(30); - /* set cnt max size */ + /* Set cnt max size */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2); @@ -2837,15 +2830,15 @@ static int bnx2x_bmac_enable(struct link_params *params, u8 port = params->port; struct bnx2x *bp = params->bp; u32 val; - /* reset and unreset the BigMac */ + /* Reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - msleep(1); + usleep_range(1000, 2000); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - /* enable access for bmac registers */ + /* Enable access for bmac registers */ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); /* Enable BMAC according to BMAC type*/ @@ -2903,7 +2896,7 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2); } - msleep(1); + usleep_range(1000, 2000); } } @@ -2915,17 +2908,16 @@ static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, u32 init_crd, crd; u32 count = 1000; - /* disable port */ + /* Disable port */ REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); - /* wait for init credit */ + /* Wait for init credit */ init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4); crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd); while ((init_crd != crd) && count) { - msleep(5); - + usleep_range(5000, 10000); crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); count--; } @@ -2942,18 +2934,18 @@ static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, line_speed == SPEED_1000 || line_speed == SPEED_2500) { REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1); - /* update threshold */ + /* Update threshold */ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); - /* update init credit */ + /* Update init credit */ init_crd = 778; /* (800-18-4) */ } else { u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)/16; REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); - /* update threshold */ + /* Update threshold */ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh); - /* update init credit */ + /* Update init credit */ switch (line_speed) { case SPEED_10000: init_crd = thresh + 553 - 22; @@ -2968,12 +2960,12 @@ static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n", line_speed, init_crd); - /* probe the credit changes */ + /* Probe the credit changes */ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1); - msleep(5); + usleep_range(5000, 10000); REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0); - /* enable port */ + /* Enable port */ REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0); return 0; } @@ -3040,7 +3032,7 @@ static int bnx2x_cl22_write(struct bnx2x *bp, REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode & ~EMAC_MDIO_MODE_CLAUSE_45); - /* address */ + /* Address */ tmp = ((phy->addr << 21) | (reg << 16) | val | EMAC_MDIO_COMM_COMMAND_WRITE_22 | EMAC_MDIO_COMM_START_BUSY); @@ -3076,7 +3068,7 @@ static int bnx2x_cl22_read(struct bnx2x *bp, REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode & ~EMAC_MDIO_MODE_CLAUSE_45); - /* address */ + /* Address */ val = ((phy->addr << 21) | (reg << 16) | EMAC_MDIO_COMM_COMMAND_READ_22 | EMAC_MDIO_COMM_START_BUSY); @@ -3114,7 +3106,7 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, if (phy->flags & FLAGS_MDC_MDIO_WA_B0) bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, EMAC_MDIO_STATUS_10MB); - /* address */ + /* Address */ val = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); @@ -3135,7 +3127,7 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, *ret_val = 0; rc = -EFAULT; } else { - /* data */ + /* Data */ val = ((phy->addr << 21) | (devad << 16) | EMAC_MDIO_COMM_COMMAND_READ_45 | EMAC_MDIO_COMM_START_BUSY); @@ -3183,7 +3175,7 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, EMAC_MDIO_STATUS_10MB); - /* address */ + /* Address */ tmp = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); @@ -3203,7 +3195,7 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, netdev_err(bp->dev, "MDC/MDIO access timeout\n"); rc = -EFAULT; } else { - /* data */ + /* Data */ tmp = ((phy->addr << 21) | (devad << 16) | val | EMAC_MDIO_COMM_COMMAND_WRITE_45 | EMAC_MDIO_COMM_START_BUSY); @@ -3293,23 +3285,23 @@ static int bnx2x_bsc_read(struct link_params *params, xfer_cnt = 16 - lc_addr; - /* enable the engine */ + /* Enable the engine */ val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); val |= MCPR_IMC_COMMAND_ENABLE; REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); - /* program slave device ID */ + /* Program slave device ID */ val = (sl_devid << 16) | sl_addr; REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val); - /* start xfer with 0 byte to update the address pointer ???*/ + /* Start xfer with 0 byte to update the address pointer ???*/ val = (MCPR_IMC_COMMAND_ENABLE) | (MCPR_IMC_COMMAND_WRITE_OP << MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0); REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); - /* poll for completion */ + /* Poll for completion */ i = 0; val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { @@ -3325,7 +3317,7 @@ static int bnx2x_bsc_read(struct link_params *params, if (rc == -EFAULT) return rc; - /* start xfer with read op */ + /* Start xfer with read op */ val = (MCPR_IMC_COMMAND_ENABLE) | (MCPR_IMC_COMMAND_READ_OP << MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | @@ -3333,7 +3325,7 @@ static int bnx2x_bsc_read(struct link_params *params, (xfer_cnt); REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); - /* poll for completion */ + /* Poll for completion */ i = 0; val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { @@ -3436,7 +3428,7 @@ static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy, port = port ^ 1; lane = (port<<1) + path; - } else { /* two port mode - no port swap */ + } else { /* Two port mode - no port swap */ /* Figure out path swap value */ path_swap_ovr = @@ -3514,7 +3506,7 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) val = SERDES_RESET_BITS << (port*16); - /* reset and unreset the SerDes/XGXS */ + /* Reset and unreset the SerDes/XGXS */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); udelay(500); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); @@ -3535,7 +3527,7 @@ static void bnx2x_xgxs_deassert(struct link_params *params) val = XGXS_RESET_BITS << (port*16); - /* reset and unreset the SerDes/XGXS */ + /* Reset and unreset the SerDes/XGXS */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); udelay(500); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); @@ -3627,7 +3619,7 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, { u16 val; struct bnx2x *bp = params->bp; - /* read modify write pause advertizing */ + /* Read modify write pause advertizing */ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; @@ -3945,7 +3937,7 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0xF9); - /* set and clear loopback to cause a reset to 64/66 decoder */ + /* Set and clear loopback to cause a reset to 64/66 decoder */ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, @@ -4373,7 +4365,7 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, if (!vars->turn_to_run_wc_rt) return; - /* return if there is no link partner */ + /* Return if there is no link partner */ if (!(bnx2x_warpcore_get_sigdet(phy, params))) { DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n"); return; @@ -4407,7 +4399,7 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, bnx2x_warpcore_reset_lane(bp, phy, 1); bnx2x_warpcore_reset_lane(bp, phy, 0); - /* restart Autoneg */ + /* Restart Autoneg */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200); @@ -4645,8 +4637,9 @@ static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, } -void bnx2x_sync_link(struct link_params *params, - struct link_vars *vars) + +static void bnx2x_sync_link(struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 link_10g_plus; @@ -4719,7 +4712,7 @@ void bnx2x_sync_link(struct link_params *params, USES_WARPCORE(bp) && (vars->line_speed == SPEED_1000)) vars->phy_flags |= PHY_SGMII_FLAG; - /* anything 10 and over uses the bmac */ + /* Anything 10 and over uses the bmac */ link_10g_plus = (vars->line_speed >= SPEED_10000); if (link_10g_plus) { @@ -4733,7 +4726,7 @@ void bnx2x_sync_link(struct link_params *params, else vars->mac_type = MAC_TYPE_EMAC; } - } else { /* link down */ + } else { /* Link down */ DP(NETIF_MSG_LINK, "phy link down\n"); vars->phy_link_up = 0; @@ -4742,7 +4735,7 @@ void bnx2x_sync_link(struct link_params *params, vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - /* indicate no mac active */ + /* Indicate no mac active */ vars->mac_type = MAC_TYPE_NONE; if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; @@ -4813,7 +4806,7 @@ static void bnx2x_set_master_ln(struct link_params *params, PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - /* set the master_ln for AN */ + /* Set the master_ln for AN */ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TEST_MODE_LANE, @@ -4836,7 +4829,7 @@ static int bnx2x_reset_unicore(struct link_params *params, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); - /* reset the unicore */ + /* Reset the unicore */ CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, @@ -4845,11 +4838,11 @@ static int bnx2x_reset_unicore(struct link_params *params, if (set_serdes) bnx2x_set_serdes_access(bp, params->port); - /* wait for the reset to self clear */ + /* Wait for the reset to self clear */ for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { udelay(5); - /* the reset erased the previous bank value */ + /* The reset erased the previous bank value */ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, @@ -5067,7 +5060,7 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); } -/* program SerDes, forced speed */ +/* Program SerDes, forced speed */ static void bnx2x_program_serdes(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -5075,7 +5068,7 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 reg_val; - /* program duplex, disable autoneg and sgmii*/ + /* Program duplex, disable autoneg and sgmii*/ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); @@ -5094,7 +5087,7 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, ®_val); - /* clearing the speed value before setting the right speed */ + /* Clearing the speed value before setting the right speed */ DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val); reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK | @@ -5123,7 +5116,7 @@ static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 val = 0; - /* set extended capabilities */ + /* Set extended capabilities */ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) val |= MDIO_OVER_1G_UP1_2_5G; if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) @@ -5143,7 +5136,7 @@ static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 val; - /* for AN, we are always publishing full duplex */ + /* For AN, we are always publishing full duplex */ CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, @@ -5205,14 +5198,14 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 control1; - /* in SGMII mode, the unicore is always slave */ + /* In SGMII mode, the unicore is always slave */ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &control1); control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT; - /* set sgmii mode (and not fiber) */ + /* Set sgmii mode (and not fiber) */ control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); @@ -5221,9 +5214,9 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, control1); - /* if forced speed */ + /* If forced speed */ if (!(vars->line_speed == SPEED_AUTO_NEG)) { - /* set speed, disable autoneg */ + /* Set speed, disable autoneg */ u16 mii_control; CL22_RD_OVER_CL45(bp, phy, @@ -5244,16 +5237,16 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000; break; case SPEED_10: - /* there is nothing to set for 10M */ + /* There is nothing to set for 10M */ break; default: - /* invalid speed for SGMII */ + /* Invalid speed for SGMII */ DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", vars->line_speed); break; } - /* setting the full duplex */ + /* Setting the full duplex */ if (phy->req_duplex == DUPLEX_FULL) mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; @@ -5263,7 +5256,7 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, mii_control); } else { /* AN mode */ - /* enable and restart AN */ + /* Enable and restart AN */ bnx2x_restart_autoneg(phy, params, 0); } } @@ -5359,7 +5352,7 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - /* resolve from gp_status in case of AN complete and not sgmii */ + /* Resolve from gp_status in case of AN complete and not sgmii */ if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) { /* Update the advertised flow-controled of LD/LP in AN */ if (phy->req_line_speed == SPEED_AUTO_NEG) @@ -5583,7 +5576,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, bnx2x_xgxs_an_resolve(phy, params, vars, gp_status); } - } else { /* link_down */ + } else { /* Link_down */ if ((phy->req_line_speed == SPEED_AUTO_NEG) && SINGLE_MEDIA_DIRECT(params)) { /* Check signal is detected */ @@ -5732,12 +5725,12 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) u16 tx_driver; u16 bank; - /* read precomp */ + /* Read precomp */ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_LP_UP2, &lp_up2); - /* bits [10:7] at lp_up2, positioned at [15:12] */ + /* Bits [10:7] at lp_up2, positioned at [15:12] */ lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >> MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) << MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT); @@ -5751,7 +5744,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) bank, MDIO_TX0_TX_DRIVER, &tx_driver); - /* replace tx_driver bits [15:12] */ + /* Replace tx_driver bits [15:12] */ if (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) { tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; @@ -5847,16 +5840,16 @@ static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy, FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) bnx2x_set_preemphasis(phy, params); - /* forced speed requested? */ + /* Forced speed requested? */ if (vars->line_speed != SPEED_AUTO_NEG || (SINGLE_MEDIA_DIRECT(params) && params->loopback_mode == LOOPBACK_EXT)) { DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); - /* disable autoneg */ + /* Disable autoneg */ bnx2x_set_autoneg(phy, params, vars, 0); - /* program speed and duplex */ + /* Program speed and duplex */ bnx2x_program_serdes(phy, params, vars); } else { /* AN_mode */ @@ -5865,14 +5858,14 @@ static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy, /* AN enabled */ bnx2x_set_brcm_cl37_advertisement(phy, params); - /* program duplex & pause advertisement (for aneg) */ + /* Program duplex & pause advertisement (for aneg) */ bnx2x_set_ieee_aneg_advertisement(phy, params, vars->ieee_fc); - /* enable autoneg */ + /* Enable autoneg */ bnx2x_set_autoneg(phy, params, vars, enable_cl73); - /* enable and restart AN */ + /* Enable and restart AN */ bnx2x_restart_autoneg(phy, params, enable_cl73); } @@ -5908,12 +5901,12 @@ static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy, bnx2x_set_master_ln(params, phy); rc = bnx2x_reset_unicore(params, phy, 0); - /* reset the SerDes and wait for reset bit return low */ - if (rc != 0) + /* Reset the SerDes and wait for reset bit return low */ + if (rc) return rc; bnx2x_set_aer_mmd(params, phy); - /* setting the masterLn_def again after the reset */ + /* Setting the masterLn_def again after the reset */ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { bnx2x_set_master_ln(params, phy); bnx2x_set_swap_lanes(params, phy); @@ -5938,7 +5931,7 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, MDIO_PMA_REG_CTRL, &ctrl); if (!(ctrl & (1<<15))) break; - msleep(1); + usleep_range(1000, 2000); } if (cnt == 1000) @@ -6169,7 +6162,7 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); if (!CHIP_IS_E3(bp)) { - /* change the uni_phy_addr in the nig */ + /* Change the uni_phy_addr in the nig */ md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18)); @@ -6189,11 +6182,11 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), 0x6041); msleep(200); - /* set aer mmd back */ + /* Set aer mmd back */ bnx2x_set_aer_mmd(params, phy); if (!CHIP_IS_E3(bp)) { - /* and md_devad */ + /* And md_devad */ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); } @@ -6390,7 +6383,7 @@ int bnx2x_test_link(struct link_params *params, struct link_vars *vars, MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); - /* link is up only if both local phy and external phy are up */ + /* Link is up only if both local phy and external phy are up */ if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) return -ESRCH; } @@ -6512,7 +6505,7 @@ static int bnx2x_link_initialize(struct link_params *params, static void bnx2x_int_link_reset(struct bnx2x_phy *phy, struct link_params *params) { - /* reset the SerDes/XGXS */ + /* Reset the SerDes/XGXS */ REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, (0x1ff << (params->port*16))); } @@ -6545,10 +6538,10 @@ static int bnx2x_update_link_down(struct link_params *params, DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); bnx2x_set_led(params, vars, LED_MODE_OFF, 0); vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG; - /* indicate no mac active */ + /* Indicate no mac active */ vars->mac_type = MAC_TYPE_NONE; - /* update shared memory */ + /* Update shared memory */ vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | LINK_STATUS_LINK_UP | LINK_STATUS_PHYSICAL_LINK_FLAG | @@ -6561,15 +6554,15 @@ static int bnx2x_update_link_down(struct link_params *params, vars->line_speed = 0; bnx2x_update_mng(params, vars->link_status); - /* activate nig drain */ + /* Activate nig drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - /* disable emac */ + /* Disable emac */ if (!CHIP_IS_E3(bp)) REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - msleep(10); - /* reset BigMac/Xmac */ + usleep_range(10000, 20000); + /* Reset BigMac/Xmac */ if (CHIP_IS_E1x(bp) || CHIP_IS_E2(bp)) { bnx2x_bmac_rx_disable(bp, params->port); @@ -6578,6 +6571,7 @@ static int bnx2x_update_link_down(struct link_params *params, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); } if (CHIP_IS_E3(bp)) { + /* Prevent LPI Generation by chip */ REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0); REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0); @@ -6668,10 +6662,10 @@ static int bnx2x_update_link_up(struct link_params *params, rc |= bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); - /* disable drain */ + /* Disable drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); - /* update shared memory */ + /* Update shared memory */ bnx2x_update_mng(params, vars->link_status); bnx2x_update_mng_eee(params, vars->eee_status); /* Check remote fault */ @@ -6739,7 +6733,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); - /* disable emac */ + /* Disable emac */ if (!CHIP_IS_E3(bp)) REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); @@ -6884,11 +6878,11 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) } else if (prev_line_speed != vars->line_speed) { REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); - msleep(1); + usleep_range(1000, 2000); } } - /* anything 10 and over uses the bmac */ + /* Anything 10 and over uses the bmac */ link_10g_plus = (vars->line_speed >= SPEED_10000); bnx2x_link_int_ack(params, vars, link_10g_plus); @@ -6954,7 +6948,7 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) { bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - msleep(1); + usleep_range(1000, 2000); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); } @@ -7051,7 +7045,7 @@ static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, MDIO_PMA_REG_GEN_CTRL, 0x0001); - /* ucode reboot and rst */ + /* Ucode reboot and rst */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, @@ -7095,7 +7089,7 @@ static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout); - msleep(1); + usleep_range(1000, 2000); } while (fw_ver1 == 0 || fw_ver1 == 0x4321 || ((fw_msgout & 0xff) != 0x03 && (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))); @@ -7189,11 +7183,11 @@ static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) "XAUI workaround has completed\n"); return 0; } - msleep(3); + usleep_range(3000, 6000); } break; } - msleep(3); + usleep_range(3000, 6000); } DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n"); return -EINVAL; @@ -7267,7 +7261,7 @@ static int bnx2x_8073_config_init(struct bnx2x_phy *phy, bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - /* enable LASI */ + /* Enable LASI */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2)); bnx2x_cl45_write(bp, phy, @@ -7415,7 +7409,7 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); - /* clear the interrupt LASI status register */ + /* Clear the interrupt LASI status register */ bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); bnx2x_cl45_read(bp, phy, @@ -7794,7 +7788,7 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) return 0; - msleep(1); + usleep_range(1000, 2000); } return -EINVAL; } @@ -7876,7 +7870,7 @@ static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* Wait appropriate time for two-wire command to finish before * polling the status register */ - msleep(1); + usleep_range(1000, 2000); /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { @@ -7912,7 +7906,7 @@ static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) return 0; - msleep(1); + usleep_range(1000, 2000); } return -EINVAL; @@ -8091,7 +8085,7 @@ static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy, return 0; } - /* format the warning message */ + /* Format the warning message */ if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_VENDOR_NAME_ADDR, @@ -8137,7 +8131,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, timeout * 5); return 0; } - msleep(5); + usleep_range(5000, 10000); } return -EINVAL; } @@ -8472,7 +8466,7 @@ int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); return -EINVAL; } else if (bnx2x_verify_sfp_module(phy, params) != 0) { - /* check SFP+ module compatibility */ + /* Check SFP+ module compatibility */ DP(NETIF_MSG_LINK, "Module verification failed!!\n"); rc = -EINVAL; /* Turn on fault module-detected led */ @@ -8603,7 +8597,7 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT, MDIO_PMA_LASI_TXCTRL); - /* clear LASI indication*/ + /* Clear LASI indication*/ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); bnx2x_cl45_read(bp, phy, @@ -8671,7 +8665,7 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); if (val) break; - msleep(10); + usleep_range(10000, 20000); } DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt); if ((params->feature_config_flags & @@ -8800,7 +8794,7 @@ static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); - /* wait for 150ms for microcode load */ + /* Wait for 150ms for microcode load */ msleep(150); /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ @@ -9011,7 +9005,7 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, lasi_ctrl_val = 0x0006; DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); - /* enable LASI */ + /* Enable LASI */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, rx_alarm_ctrl_val); @@ -9733,7 +9727,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, MDIO_84833_CMD_HDLR_STATUS, &val); if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS) break; - msleep(1); + usleep_range(1000, 2000); } if (idx >= PHY84833_CMDHDLR_WAIT) { DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n"); @@ -9754,7 +9748,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) || (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) break; - msleep(1); + usleep_range(1000, 2000); } if ((idx >= PHY84833_CMDHDLR_WAIT) || (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) { @@ -9924,7 +9918,7 @@ static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy, /* Prevent Phy from working in EEE and advertising it */ rc = bnx2x_84833_cmd_hdlr(phy, params, PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1); - if (rc != 0) { + if (rc) { DP(NETIF_MSG_LINK, "EEE disable failed.\n"); return rc; } @@ -9947,7 +9941,7 @@ static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy, rc = bnx2x_84833_cmd_hdlr(phy, params, PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1); - if (rc != 0) { + if (rc) { DP(NETIF_MSG_LINK, "EEE enable failed.\n"); return rc; } @@ -9975,7 +9969,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, u16 cmd_args[PHY84833_CMDHDLR_MAX_ARGS]; int rc = 0; - msleep(1); + usleep_range(1000, 2000); if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); @@ -10064,7 +10058,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, rc = bnx2x_84833_cmd_hdlr(phy, params, PHY84833_CMD_SET_EEE_MODE, cmd_args, PHY84833_CMDHDLR_MAX_ARGS); - if (rc != 0) + if (rc) DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); } if (initialize) @@ -10108,7 +10102,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT; rc = bnx2x_8483x_eee_timers(params, vars); - if (rc != 0) { + if (rc) { DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n"); bnx2x_8483x_disable_eee(phy, params, vars); return rc; @@ -10121,7 +10115,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, rc = bnx2x_8483x_enable_eee(phy, params, vars); else rc = bnx2x_8483x_disable_eee(phy, params, vars); - if (rc != 0) { + if (rc) { DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); return rc; } @@ -10222,7 +10216,7 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, } } if (link_up) { - DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n", + DP(NETIF_MSG_LINK, "BCM848x3: link speed is %d\n", vars->line_speed); bnx2x_ext_phy_resolve_fc(phy, params, vars); @@ -10564,7 +10558,7 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, u32 cfg_pin; DP(NETIF_MSG_LINK, "54618SE cfg init\n"); - usleep_range(1000, 1000); + usleep_range(1000, 2000); /* This works with E3 only, no need to check the chip * before determining the port. @@ -10633,7 +10627,7 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; - /* read all advertisement */ + /* Read all advertisement */ bnx2x_cl22_read(bp, phy, 0x09, &an_1000_val); @@ -10670,7 +10664,7 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, 0x09, &an_1000_val); - /* set 100 speed advertisement */ + /* Set 100 speed advertisement */ if (((phy->req_line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | @@ -10684,7 +10678,7 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Advertising 100M\n"); } - /* set 10 speed advertisement */ + /* Set 10 speed advertisement */ if (((phy->req_line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | @@ -11050,7 +11044,7 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", val2, val1); link_up = ((val1 & 4) == 4); - /* if link is up print the AN outcome of the SFX7101 PHY */ + /* If link is up print the AN outcome of the SFX7101 PHY */ if (link_up) { bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, @@ -11062,7 +11056,7 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); bnx2x_ext_phy_resolve_fc(phy, params, vars); - /* read LP advertised speeds */ + /* Read LP advertised speeds */ if (val2 & (1<<11)) vars->link_status |= LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE; @@ -12260,7 +12254,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->mac_type = MAC_TYPE_NONE; vars->phy_flags = 0; - /* disable attentions */ + /* Disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, (NIG_MASK_XGXS0_LINK_STATUS | NIG_MASK_XGXS0_LINK10G | @@ -12320,7 +12314,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, struct bnx2x *bp = params->bp; u8 phy_index, port = params->port, clear_latch_ind = 0; DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); - /* disable attentions */ + /* Disable attentions */ vars->link_status = 0; bnx2x_update_mng(params, vars->link_status); vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | @@ -12332,10 +12326,10 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - /* activate nig drain */ + /* Activate nig drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - /* disable nig egress interface */ + /* Disable nig egress interface */ if (!CHIP_IS_E3(bp)) { REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); @@ -12348,15 +12342,15 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, bnx2x_xmac_disable(params); bnx2x_umac_disable(params); } - /* disable emac */ + /* Disable emac */ if (!CHIP_IS_E3(bp)) REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - msleep(10); + usleep_range(10000, 20000); /* The PHY reset is controlled by GPIO 1 * Hold it as vars low */ - /* clear link led */ + /* Clear link led */ bnx2x_set_mdio_clk(bp, params->chip_id, port); bnx2x_set_led(params, vars, LED_MODE_OFF, 0); @@ -12386,9 +12380,9 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, params->phy[INT_PHY].link_reset( ¶ms->phy[INT_PHY], params); - /* disable nig ingress interface */ + /* Disable nig ingress interface */ if (!CHIP_IS_E3(bp)) { - /* reset BigMac */ + /* Reset BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); @@ -12445,7 +12439,7 @@ static int bnx2x_8073_common_init_phy(struct bnx2x *bp, DP(NETIF_MSG_LINK, "populate_phy failed\n"); return -EINVAL; } - /* disable attentions */ + /* Disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port_of_path*4, (NIG_MASK_XGXS0_LINK_STATUS | @@ -12519,7 +12513,7 @@ static int bnx2x_8073_common_init_phy(struct bnx2x *bp, bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); - msleep(15); + usleep_range(15000, 30000); /* Read modify write the SPI-ROM version select register */ bnx2x_cl45_read(bp, phy_blk[port], @@ -12551,7 +12545,7 @@ static int bnx2x_8726_common_init_phy(struct bnx2x *bp, REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); bnx2x_ext_phy_hw_reset(bp, 0); - msleep(5); + usleep_range(5000, 10000); for (port = 0; port < PORT_MAX; port++) { u32 shmem_base, shmem2_base; @@ -12658,11 +12652,11 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp, /* Initiate PHY reset*/ bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - msleep(1); + usleep_range(1000, 2000); bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); - msleep(5); + usleep_range(5000, 10000); /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { @@ -12756,7 +12750,7 @@ static int bnx2x_84833_pre_init_phy(struct bnx2x *bp, MDIO_PMA_REG_CTRL, &val); if (!(val & (1<<15))) break; - msleep(1); + usleep_range(1000, 2000); } if (cnt >= 1500) { DP(NETIF_MSG_LINK, "84833 reset timeout\n"); @@ -12846,7 +12840,7 @@ static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], break; } - if (rc != 0) + if (rc) netdev_err(bp->dev, "Warning: PHY was not initialized," " Port %d\n", 0); -- GitLab From 1440090111ad626c8ab3d3c10076254ab7d98777 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Jun 2012 19:05:20 +0000 Subject: [PATCH 2509/6849] bnx2x: treat 0 speed as link down (copper) Signed-off-by: Yuval Mintz Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index b3c33ed2bc96..d38d269824fc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -10178,17 +10178,19 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n", legacy_status); link_up = ((legacy_status & (1<<11)) == (1<<11)); - if (link_up) { - legacy_speed = (legacy_status & (3<<9)); - if (legacy_speed == (0<<9)) - vars->line_speed = SPEED_10; - else if (legacy_speed == (1<<9)) - vars->line_speed = SPEED_100; - else if (legacy_speed == (2<<9)) - vars->line_speed = SPEED_1000; - else /* Should not happen */ - vars->line_speed = 0; + legacy_speed = (legacy_status & (3<<9)); + if (legacy_speed == (0<<9)) + vars->line_speed = SPEED_10; + else if (legacy_speed == (1<<9)) + vars->line_speed = SPEED_100; + else if (legacy_speed == (2<<9)) + vars->line_speed = SPEED_1000; + else { /* Should not happen: Treat as link down */ + vars->line_speed = 0; + link_up = 0; + } + if (link_up) { if (legacy_status & (1<<8)) vars->duplex = DUPLEX_FULL; else -- GitLab From a351d497f3367461fc96bf4cb9749bdb163c897e Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Jun 2012 19:05:21 +0000 Subject: [PATCH 2510/6849] bnx2x: revised link register access This is a semantic change, cleaning some sections in which the bnx2x handles the phy's registers. Signed-off-by: Yuval Mintz Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 238 +++++++----------- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 5 + .../net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 1 + 3 files changed, 100 insertions(+), 144 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index d38d269824fc..23ca0b642a8e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -3754,44 +3754,35 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 val16 = 0, lane, bam37 = 0; - struct bnx2x *bp = params->bp; + u16 val16 = 0, lane, i; + struct bnx2x *bp = params->bp; + static struct bnx2x_reg_set reg_set[] = { + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555}, + {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, + /* Disable Autoneg: re-enable it after adv is done. */ + {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0} + }; DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); /* Set to default registers that may be overriden by 10G force */ - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_PAR_DET_10G_CTRL, 0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_RX66_CONTROL, 0x7415); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190); - /* Disable Autoneg: re-enable it after adv is done. */ - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_IEEE0BLK_MIICNTL, 0); + for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++) + bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, + reg_set[i].val); /* Check adding advertisement for 1G KX */ if (((vars->line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || (vars->line_speed == SPEED_1000)) { - u16 sd_digital; + u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; val16 |= (1<<5); /* Enable CL37 1G Parallel Detect */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, - (sd_digital | 0x1)); - + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); DP(NETIF_MSG_LINK, "Advertize 1G\n"); } if (((vars->line_speed == SPEED_AUTO_NEG) && @@ -3801,7 +3792,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, val16 |= (1<<7); /* Enable 10G Parallel Detect */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_PAR_DET_10G_CTRL, 1); + MDIO_WC_REG_PAR_DET_10G_CTRL, 1); DP(NETIF_MSG_LINK, "Advertize 10G\n"); } @@ -3835,10 +3826,9 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, offsetof(struct shmem_region, dev_info. port_hw_config[params->port].default_cfg)) & PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, + 1); DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); } @@ -3852,11 +3842,8 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Enable AN KR work-around\n"); vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; } - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL5_MISC7, &val16); - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC7, 0x100); /* Over 1G - AN local device user page 1 */ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, @@ -3873,50 +3860,35 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val; - - /* Disable Autoneg */ - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7); - - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_PAR_DET_10G_CTRL, 0); - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00); - - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0); - - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL3_UP1, 0x1); - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL5_MISC7, 0xa); - - /* Disable CL36 PCS Tx */ - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0); - - /* Double Wide Single Data Rate @ pll rate */ - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF); - - /* Leave cl72 training enable, needed for KR */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, + u16 i; + static struct bnx2x_reg_set reg_set[] = { + /* Disable Autoneg */ + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + 0x3f00}, + {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, + {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, + {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, + /* Disable CL36 PCS Tx */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0}, + /* Double Wide Single Data Rate @ pll rate */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF}, + /* Leave cl72 training enable, needed for KR */ + {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, - 0x2); + 0x2} + }; + + for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++) + bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, + reg_set[i].val); /* Leave CL72 enabled */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, - &val); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, - val | 0x3800); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + 0x3800); /* Set speed via PMA/PMD register */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, @@ -3952,16 +3924,12 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 misc1_val, tap_val, tx_driver_val, lane, val; /* Hold rxSeqStart */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000)); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000); /* Hold tx_fifo_reset */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1)); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1); /* Disable CL73 AN */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); @@ -3973,10 +3941,8 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA)); /* Disable 100FX Idle detect */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_FX100_CTRL3, &val); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_FX100_CTRL3, (val | 0x0080)); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL3, 0x0080); /* Set Block address to Remote PHY & Clear forced_speed[5] */ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, @@ -4037,16 +4003,12 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, tx_driver_val); /* Enable fiber mode, enable and invert sig_det */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd); /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL4_MISC3, &val); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, 0x8080); /* Enable LPI pass through */ DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n"); @@ -4244,40 +4206,35 @@ static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy, u16 lane) { struct bnx2x *bp = params->bp; - u16 val16; - + u16 i; + static struct bnx2x_reg_set wc_regs[] = { + {MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a}, + {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800}, + {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008}, + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, + 0x0195}, + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, + 0x0007}, + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, + 0x0002}, + {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000}, + {MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000}, + {MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040}, + {MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140} + }; /* Set XFI clock comp as default. */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_RX66_CONTROL, &val16); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13)); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_CONTROL, (3<<13)); + + for (i = 0; i < sizeof(wc_regs)/sizeof(struct bnx2x_reg_set); i++) + bnx2x_cl45_write(bp, phy, wc_regs[i].devad, wc_regs[i].reg, + wc_regs[i].val); - bnx2x_warpcore_reset_lane(bp, phy, 1); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_FX100_CTRL1, 0x014a); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_FX100_CTRL3, 0x0800); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL4_MISC3, 0x8008); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000); lane = bnx2x_get_warpcore_lane(phy, params); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_TX_FIR_TAP, 0x0000); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140); - bnx2x_warpcore_reset_lane(bp, phy, 0); + } static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp, @@ -4605,12 +4562,9 @@ static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, 0); /* Enable 1G MDIO (1-copy) */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, - &val16); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, - val16 | 0x10); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, + 0x10); /* Set 1G loopback based on lane (1-copy) */ lane = bnx2x_get_warpcore_lane(phy, params); bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, @@ -4623,16 +4577,12 @@ static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, bnx2x_set_aer_mmd(params, phy); } else { /* 10G & 20G */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 | - 0x4000); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, + 0x4000); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1); + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1); } } @@ -10819,7 +10769,7 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy, /* Get speed operation status */ bnx2x_cl22_read(bp, phy, - 0x19, + MDIO_REG_GPHY_AUX_STATUS, &legacy_status); DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index cd1f2719b62d..7b6051bc4551 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -125,6 +125,11 @@ typedef void (*set_link_led_t)(struct bnx2x_phy *phy, struct link_params *params, u8 mode); typedef void (*phy_specific_func_t)(struct bnx2x_phy *phy, struct link_params *params, u32 action); +struct bnx2x_reg_set { + u8 devad; + u16 reg; + u16 val; +}; struct bnx2x_phy { u32 type; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index a78e35683b03..f371e3c06094 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -7160,6 +7160,7 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_REG_GPHY_EEE_1G (0x1 << 2) #define MDIO_REG_GPHY_EEE_100 (0x1 << 1) #define MDIO_REG_GPHY_EEE_RESOLVED 0x803e +#define MDIO_REG_GPHY_AUX_STATUS 0x19 #define MDIO_REG_INTR_STATUS 0x1a #define MDIO_REG_INTR_MASK 0x1b #define MDIO_REG_INTR_MASK_LINK_STATUS (0x1 << 1) -- GitLab From dbef807ee890b45f9c9125b665c0dddc993c3d15 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Jun 2012 19:05:22 +0000 Subject: [PATCH 2511/6849] bnx2x: 1G sfp+ module handling Automatically lower requested link speed to 1G in case 1G SFP+ module is detected. Signed-off-by: Yuval Mintz Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 16 +- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 202 +++++++++++------- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 17 +- 3 files changed, 151 insertions(+), 84 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 70c0881ce5a0..819170ee152a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -187,7 +187,8 @@ static int bnx2x_get_port_type(struct bnx2x *bp) int port_type; u32 phy_idx = bnx2x_get_cur_phy_idx(bp); switch (bp->link_params.phy[phy_idx].media_type) { - case ETH_PHY_SFP_FIBER: + case ETH_PHY_SFPP_10G_FIBER: + case ETH_PHY_SFP_1G_FIBER: case ETH_PHY_XFP_FIBER: case ETH_PHY_KR: case ETH_PHY_CX4: @@ -220,6 +221,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) (bp->port.supported[cfg_idx ^ 1] & (SUPPORTED_TP | SUPPORTED_FIBRE)); cmd->advertising = bp->port.advertising[cfg_idx]; + if (bp->link_params.phy[bnx2x_get_cur_phy_idx(bp)].media_type == + ETH_PHY_SFP_1G_FIBER) { + cmd->supported &= ~(SUPPORTED_10000baseT_Full); + cmd->advertising &= ~(ADVERTISED_10000baseT_Full); + } if ((bp->state == BNX2X_STATE_OPEN) && (bp->link_vars.link_up)) { if (!(bp->flags & MF_FUNC_DIS)) { @@ -295,7 +301,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; - u32 speed; + u32 speed, phy_idx; if (IS_MF_SD(bp)) return 0; @@ -550,9 +556,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) "10G half not supported\n"); return -EINVAL; } - + phy_idx = bnx2x_get_cur_phy_idx(bp); if (!(bp->port.supported[cfg_idx] - & SUPPORTED_10000baseT_Full)) { + & SUPPORTED_10000baseT_Full) || + (bp->link_params.phy[phy_idx].media_type == + ETH_PHY_SFP_1G_FIBER)) { DP(BNX2X_MSG_ETHTOOL, "10G full not supported\n"); return -EINVAL; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 23ca0b642a8e..b21a6be81032 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -4373,6 +4373,23 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, } /*params->rx_tx_asic_rst*/ } +static void bnx2x_warpcore_config_sfi(struct bnx2x_phy *phy, + struct link_params *params) +{ + u16 lane = bnx2x_get_warpcore_lane(phy, params); + struct bnx2x *bp = params->bp; + bnx2x_warpcore_clear_regs(phy, params, lane); + if ((params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)] == + SPEED_10000) && + (phy->media_type != ETH_PHY_SFP_1G_FIBER)) { + DP(NETIF_MSG_LINK, "Setting 10G SFI\n"); + bnx2x_warpcore_set_10G_XFI(phy, params, 0); + } else { + DP(NETIF_MSG_LINK, "Setting 1G Fiber\n"); + bnx2x_warpcore_set_sgmii_speed(phy, params, 1, 0); + } +} + static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -4433,19 +4450,11 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, break; case PORT_HW_CFG_NET_SERDES_IF_SFI: - - bnx2x_warpcore_clear_regs(phy, params, lane); - if (vars->line_speed == SPEED_10000) { - DP(NETIF_MSG_LINK, "Setting 10G SFI\n"); - bnx2x_warpcore_set_10G_XFI(phy, params, 0); - } else if (vars->line_speed == SPEED_1000) { - DP(NETIF_MSG_LINK, "Setting 1G Fiber\n"); - bnx2x_warpcore_set_sgmii_speed( - phy, params, 1, 0); - } /* Issue Module detection */ if (bnx2x_is_sfp_module_plugged(phy, params)) bnx2x_sfp_module_detection(phy, params); + + bnx2x_warpcore_config_sfi(phy, params); break; case PORT_HW_CFG_NET_SERDES_IF_DXGXS: @@ -6354,7 +6363,9 @@ int bnx2x_test_link(struct link_params *params, struct link_vars *vars, for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { serdes_phy_type = ((params->phy[phy_index].media_type == - ETH_PHY_SFP_FIBER) || + ETH_PHY_SFPP_10G_FIBER) || + (params->phy[phy_index].media_type == + ETH_PHY_SFP_1G_FIBER) || (params->phy[phy_index].media_type == ETH_PHY_XFP_FIBER) || (params->phy[phy_index].media_type == @@ -7891,7 +7902,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u32 sync_offset = 0, phy_idx, media_types; - u8 val, check_limiting_mode = 0; + u8 val[2], check_limiting_mode = 0; *edc_mode = EDC_MODE_LIMITING; phy->media_type = ETH_PHY_UNSPECIFIED; @@ -7899,13 +7910,13 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_CON_TYPE_ADDR, - 1, - &val) != 0) { + 2, + (u8 *)val) != 0) { DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); return -EINVAL; } - switch (val) { + switch (val[0]) { case SFP_EEPROM_CON_TYPE_VAL_COPPER: { u8 copper_module_type; @@ -7943,13 +7954,29 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, break; } case SFP_EEPROM_CON_TYPE_VAL_LC: - phy->media_type = ETH_PHY_SFP_FIBER; - DP(NETIF_MSG_LINK, "Optic module detected\n"); check_limiting_mode = 1; + if ((val[1] & (SFP_EEPROM_COMP_CODE_SR_MASK | + SFP_EEPROM_COMP_CODE_LR_MASK | + SFP_EEPROM_COMP_CODE_LRM_MASK)) == 0) { + DP(NETIF_MSG_LINK, "1G Optic module detected\n"); + phy->media_type = ETH_PHY_SFP_1G_FIBER; + phy->req_line_speed = SPEED_1000; + } else { + int idx, cfg_idx = 0; + DP(NETIF_MSG_LINK, "10G Optic module detected\n"); + for (idx = INT_PHY; idx < MAX_PHYS; idx++) { + if (params->phy[idx].type == phy->type) { + cfg_idx = LINK_CONFIG_IDX(idx); + break; + } + } + phy->media_type = ETH_PHY_SFPP_10G_FIBER; + phy->req_line_speed = params->req_line_speed[cfg_idx]; + } break; default: DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n", - val); + val[0]); return -EINVAL; } sync_offset = params->shmem_base + @@ -8479,14 +8506,34 @@ void bnx2x_handle_module_detect_int(struct link_params *params) /* Call the handling function in case module is detected */ if (gpio_val == 0) { + bnx2x_set_mdio_clk(bp, params->chip_id, params->port); + bnx2x_set_aer_mmd(params, phy); + bnx2x_power_sfp_module(params, phy, 1); bnx2x_set_gpio_int(bp, gpio_num, MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, gpio_port); - if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) { bnx2x_sfp_module_detection(phy, params); - else + if (CHIP_IS_E3(bp)) { + u16 rx_tx_in_reset; + /* In case WC is out of reset, reconfigure the + * link speed while taking into account 1G + * module limitation. + */ + bnx2x_cl45_read(bp, phy, + MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC6, + &rx_tx_in_reset); + if (!rx_tx_in_reset) { + bnx2x_warpcore_reset_lane(bp, phy, 1); + bnx2x_warpcore_config_sfi(phy, params); + bnx2x_warpcore_reset_lane(bp, phy, 0); + } + } + } else { DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); + } } else { u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. @@ -8938,6 +8985,63 @@ static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } +static void bnx2x_8727_config_speed(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u16 tmp1, val; + /* Set option 1G speed */ + if ((phy->req_line_speed == SPEED_1000) || + (phy->media_type == ETH_PHY_SFP_1G_FIBER)) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); + DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); + /* Power down the XAUI until link is up in case of dual-media + * and 1G + */ + if (DUAL_MEDIA(params)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val); + val |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val); + } + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); + } else { + /* Since the 8727 has only single reset pin, need to set the 10G + * registers although it is default + */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, + 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, + 0x0008); + } +} + static int bnx2x_8727_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -9007,56 +9111,7 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1); - /* Set option 1G speed */ - if (phy->req_line_speed == SPEED_1000) { - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); - DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); - /* Power down the XAUI until link is up in case of dual-media - * and 1G - */ - if (DUAL_MEDIA(params)) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_GP, &val); - val |= (3<<10); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_GP, val); - } - } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && - ((phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && - ((phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { - - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); - } else { - /* Since the 8727 has only single reset pin, need to set the 10G - * registers although it is default - */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, - 0x0020); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, - 0x0008); - } - + bnx2x_8727_config_speed(phy, params); /* Set 2-wire transfer rate of SFP+ module EEPROM * to 100Khz since some DACs(direct attached cables) do * not work at 400Khz. @@ -9183,6 +9238,9 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, bnx2x_sfp_module_detection(phy, params); else DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); + + /* Reconfigure link speed based on module type limitations */ + bnx2x_8727_config_speed(phy, params); } DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", @@ -11327,7 +11385,7 @@ static struct bnx2x_phy phy_8706 = { SUPPORTED_FIBRE | SUPPORTED_Pause | SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_SFP_FIBER, + .media_type = ETH_PHY_SFPP_10G_FIBER, .ver_addr = 0, .req_flow_ctrl = 0, .req_line_speed = 0, @@ -11666,7 +11724,7 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, SUPPORTED_FIBRE | SUPPORTED_Pause | SUPPORTED_Asym_Pause); - phy->media_type = ETH_PHY_SFP_FIBER; + phy->media_type = ETH_PHY_SFPP_10G_FIBER; break; case PORT_HW_CFG_NET_SERDES_IF_KR: phy->media_type = ETH_PHY_KR; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 7b6051bc4551..017236bee323 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -168,14 +168,15 @@ struct bnx2x_phy { u32 supported; u32 media_type; -#define ETH_PHY_UNSPECIFIED 0x0 -#define ETH_PHY_SFP_FIBER 0x1 -#define ETH_PHY_XFP_FIBER 0x2 -#define ETH_PHY_DA_TWINAX 0x3 -#define ETH_PHY_BASE_T 0x4 -#define ETH_PHY_KR 0xf0 -#define ETH_PHY_CX4 0xf1 -#define ETH_PHY_NOT_PRESENT 0xff +#define ETH_PHY_UNSPECIFIED 0x0 +#define ETH_PHY_SFPP_10G_FIBER 0x1 +#define ETH_PHY_XFP_FIBER 0x2 +#define ETH_PHY_DA_TWINAX 0x3 +#define ETH_PHY_BASE_T 0x4 +#define ETH_PHY_SFP_1G_FIBER 0x5 +#define ETH_PHY_KR 0xf0 +#define ETH_PHY_CX4 0xf1 +#define ETH_PHY_NOT_PRESENT 0xff /* The address in which version is located*/ u32 ver_addr; -- GitLab From 24ea818e305b92ad1fadcca015ae3b0c1222c497 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Jun 2012 19:05:23 +0000 Subject: [PATCH 2512/6849] bnx2x: link module eeprom Add the ethtool functionality of accessing optic modules' information and eeprom to the bnx2x driver. Signed-off-by: Yuval Mintz Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 61 +++++++++++++++++++ .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 9 +-- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 1 + 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 819170ee152a..1f8c1561cdec 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1160,6 +1160,65 @@ static int bnx2x_get_eeprom(struct net_device *dev, return rc; } +static int bnx2x_get_module_eeprom(struct net_device *dev, + struct ethtool_eeprom *ee, + u8 *data) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc = 0, phy_idx; + u8 *user_data = data; + int remaining_len = ee->len, xfer_size; + unsigned int page_off = ee->offset; + + if (!netif_running(dev)) { + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, + "cannot access eeprom when the interface is down\n"); + return -EAGAIN; + } + + phy_idx = bnx2x_get_cur_phy_idx(bp); + bnx2x_acquire_phy_lock(bp); + while (!rc && remaining_len > 0) { + xfer_size = (remaining_len > SFP_EEPROM_PAGE_SIZE) ? + SFP_EEPROM_PAGE_SIZE : remaining_len; + rc = bnx2x_read_sfp_module_eeprom(&bp->link_params.phy[phy_idx], + &bp->link_params, + page_off, + xfer_size, + user_data); + remaining_len -= xfer_size; + user_data += xfer_size; + page_off += xfer_size; + } + + bnx2x_release_phy_lock(bp); + return rc; +} + +static int bnx2x_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) +{ + struct bnx2x *bp = netdev_priv(dev); + int phy_idx; + if (!netif_running(dev)) { + DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, + "cannot access eeprom when the interface is down\n"); + return -EAGAIN; + } + + phy_idx = bnx2x_get_cur_phy_idx(bp); + switch (bp->link_params.phy[phy_idx].media_type) { + case ETH_PHY_SFPP_10G_FIBER: + case ETH_PHY_SFP_1G_FIBER: + case ETH_PHY_DA_TWINAX: + modinfo->type = ETH_MODULE_SFF_8079; + modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; + return 0; + default: + return -EOPNOTSUPP; + } +} + static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, u32 cmd_flags) { @@ -2915,6 +2974,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .set_rxfh_indir = bnx2x_set_rxfh_indir, .get_channels = bnx2x_get_channels, .set_channels = bnx2x_set_channels, + .get_module_info = bnx2x_get_module_info, + .get_module_eeprom = bnx2x_get_module_eeprom, .get_eee = bnx2x_get_eee, .set_eee = bnx2x_set_eee, }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index b21a6be81032..3e662bf7e5d8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -7695,7 +7695,7 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 val = 0; u16 i; - if (byte_cnt > 16) { + if (byte_cnt > SFP_EEPROM_PAGE_SIZE) { DP(NETIF_MSG_LINK, "Reading from eeprom is limited to 0xf\n"); return -EINVAL; @@ -7764,7 +7764,8 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, u32 data_array[4]; u16 addr32; struct bnx2x *bp = params->bp; - if (byte_cnt > 16) { + + if (byte_cnt > SFP_EEPROM_PAGE_SIZE) { DP(NETIF_MSG_LINK, "Reading from eeprom is limited to 16 bytes\n"); return -EINVAL; @@ -7794,7 +7795,7 @@ static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 val, i; - if (byte_cnt > 16) { + if (byte_cnt > SFP_EEPROM_PAGE_SIZE) { DP(NETIF_MSG_LINK, "Reading from eeprom is limited to 0xf\n"); return -EINVAL; @@ -7877,7 +7878,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { - int rc = -EINVAL; + int rc = -EOPNOTSUPP; switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 017236bee323..c05f9d94938f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -41,6 +41,7 @@ #define SPEED_AUTO_NEG 0 #define SPEED_20000 20000 +#define SFP_EEPROM_PAGE_SIZE 16 #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14 #define SFP_EEPROM_VENDOR_NAME_SIZE 16 #define SFP_EEPROM_VENDOR_OUI_ADDR 0x25 -- GitLab From fb13c47b8e5ce707268bd38cfd082da377eac4b7 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 19 Jun 2012 21:15:51 +0000 Subject: [PATCH 2513/6849] usbnet: clear OPEN flag in failure path Without clearing OPEN flag in failure path, runtime or system resume may submit interrupt/rx URB and start tx queue mistakenly on a interface in DOWN state. Signed-off-by: Ming Lei Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index d4f7256a607d..815493caea7f 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -796,11 +796,13 @@ int usbnet_open (struct net_device *net) if (info->manage_power) { retval = info->manage_power(dev, 1); if (retval < 0) - goto done; + goto done_manage_power_error; usb_autopm_put_interface(dev->intf); } return retval; +done_manage_power_error: + clear_bit(EVENT_DEV_OPEN, &dev->flags); done: usb_autopm_put_interface(dev->intf); done_nopm: -- GitLab From 5eeb3132eb4c5e9ca92e5247fe4575fe9f8c3efe Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 19 Jun 2012 21:15:52 +0000 Subject: [PATCH 2514/6849] usbnet: decrease suspend count if returning -EBUSY for runtime suspend This patch decreases dev->suspend_count in the -EBUSY failure path of usbnet_suspend. Without the change, the later runtime suspend will do nothing except for increasing dev->suspend_count. Signed-off-by: Ming Lei Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 815493caea7f..1e46f693eb47 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1515,6 +1515,7 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) spin_lock_irq(&dev->txq.lock); /* don't autosuspend while transmitting */ if (dev->txq.qlen && PMSG_IS_AUTO(message)) { + dev->suspend_count--; spin_unlock_irq(&dev->txq.lock); return -EBUSY; } else { -- GitLab From 65841fd5132c3941cdf5df09e70df3ed28323212 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 19 Jun 2012 21:15:53 +0000 Subject: [PATCH 2515/6849] usbnet: handle remote wakeup asap If usbnet is resumed by remote wakeup, generally there are some packets comming to be handled, so allocate and submit rx URBs in usbnet_resume to avoid delays introduced by tasklet. Otherwise, usbnet may have been runtime suspended before the usbnet_bh is executed to schedule Rx URBs. Without the patch, usbnet can't recieve any packets from peer in runtime suspend state if runtime PM is enabled and autosuspend_delay is set as zero. Signed-off-by: Ming Lei Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 42 +++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 1e46f693eb47..aba769d77459 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1204,6 +1204,21 @@ deferred: } EXPORT_SYMBOL_GPL(usbnet_start_xmit); +static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) +{ + struct urb *urb; + int i; + + /* don't refill the queue all at once */ + for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { + urb = usb_alloc_urb(0, flags); + if (urb != NULL) { + if (rx_submit(dev, urb, flags) == -ENOLINK) + return; + } + } +} + /*-------------------------------------------------------------------------*/ // tasklet (work deferred from completions, in_irq) or timer @@ -1243,26 +1258,14 @@ static void usbnet_bh (unsigned long param) !timer_pending (&dev->delay) && !test_bit (EVENT_RX_HALT, &dev->flags)) { int temp = dev->rxq.qlen; - int qlen = RX_QLEN (dev); - - if (temp < qlen) { - struct urb *urb; - int i; - - // don't refill the queue all at once - for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { - urb = usb_alloc_urb (0, GFP_ATOMIC); - if (urb != NULL) { - if (rx_submit (dev, urb, GFP_ATOMIC) == - -ENOLINK) - return; - } - } + + if (temp < RX_QLEN(dev)) { + rx_alloc_submit(dev, GFP_ATOMIC); if (temp != dev->rxq.qlen) netif_dbg(dev, link, dev->net, "rxqlen %d --> %d\n", temp, dev->rxq.qlen); - if (dev->rxq.qlen < qlen) + if (dev->rxq.qlen < RX_QLEN(dev)) tasklet_schedule (&dev->bh); } if (dev->txq.qlen < TX_QLEN (dev)) @@ -1572,6 +1575,13 @@ int usbnet_resume (struct usb_interface *intf) spin_unlock_irq(&dev->txq.lock); if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { + /* handle remote wakeup ASAP */ + if (!dev->wait && + netif_device_present(dev->net) && + !timer_pending(&dev->delay) && + !test_bit(EVENT_RX_HALT, &dev->flags)) + rx_alloc_submit(dev, GFP_KERNEL); + if (!(dev->txq.qlen >= TX_QLEN(dev))) netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); -- GitLab From cc4fce7f1f3e3aa9fb6b3b242ba268ba3c6272d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:23:54 -0700 Subject: [PATCH 2516/6849] staging: comedi: s626: local functions should not be exposed globally The 'ResetADC' function is prototyped as a static but is missing the static tag in it's definition. The function is only referenced in this file so add the static tag to the definition. This quiets a sparse warning about: warning: symbol 'ResetADC' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index d5edd9c091e6..440060b6f629 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1348,7 +1348,7 @@ static void s626_detach(struct comedi_device *dev) /* * this functions build the RPS program for hardware driven acquistion */ -void ResetADC(struct comedi_device *dev, uint8_t * ppl) +static void ResetADC(struct comedi_device *dev, uint8_t *ppl) { register uint32_t *pRPS; uint32_t JmpAdrs; -- GitLab From 0588ea3467e8773ddc98dfccb67b646ead2abd31 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:24:19 -0700 Subject: [PATCH 2517/6849] staging: comedi: s626: pointers should be cleared with NULL not 0 pdma->LogicalBase is a void *, NULL should be used to clear it not 0. This quiets a sparse warning about: warning: Using plain integer as NULL pointer Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 440060b6f629..58c9e40f6126 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2779,7 +2779,7 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, vpptr = pdma->PhysicalBase; if (vbptr) { pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr); - pdma->LogicalBase = 0; + pdma->LogicalBase = NULL; pdma->PhysicalBase = 0; DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n", -- GitLab From 020c44f3ad91b334f907a66eedba68f46dd39d25 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:24:47 -0700 Subject: [PATCH 2518/6849] staging: comedi: s626: remove forward declarations 1 Move the s626_attach and s626_detach functions down to match the coding style of the other comedi drivers. Then remove the forward declarations that are no longer needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 4572 ++++++++++++------------- 1 file changed, 2256 insertions(+), 2316 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 58c9e40f6126..08868066a4d9 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -207,70 +207,22 @@ static struct dio_private *dio_private_word[]={ #define devpriv ((struct s626_private *)dev->private) #define diopriv ((struct dio_private *)s->private) -/* ioctl routines */ -static int s626_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */ -static int s626_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int s626_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd); -static int s626_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); -static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s626_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s626_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan); static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop, unsigned int mask); static int s626_dio_clear_irq(struct comedi_device *dev); -static int s626_enc_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s626_enc_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s626_enc_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); static int s626_ns_to_timer(int *nanosec, int round_mode); -static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd); -static int s626_ai_inttrig(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int trignum); -static irqreturn_t s626_irq_handler(int irq, void *d); -static unsigned int s626_ai_reg_to_uint(int data); -/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data); */ - -/* end ioctl routines */ /* internal routines */ -static void s626_dio_init(struct comedi_device *dev); -static void ResetADC(struct comedi_device *dev, uint8_t * ppl); -static void LoadTrimDACs(struct comedi_device *dev); static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, uint8_t DacData); static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr); static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val); static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata); static void SendDAC(struct comedi_device *dev, uint32_t val); -static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage); static void DEBItransfer(struct comedi_device *dev); static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr); static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata); -static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, - uint16_t wdata); -static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, - size_t bsize); /* COUNTER OBJECT ------------------------------------------------ */ struct enc_private { @@ -295,7 +247,6 @@ struct enc_private { #define encpriv ((struct enc_private *)(dev->subdevices+5)->private) -/* counters routines */ static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick); static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k); @@ -315,7 +266,6 @@ static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k); static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k); static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value); -/* static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ); */ static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig); static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, @@ -328,20 +278,10 @@ static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, uint16_t IntSource); static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k); static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k); -/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) ; */ -/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) ; */ -/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ); */ -/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) ; */ -/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ); */ -/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ); */ -/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ); */ -/* static uint16_t GetIndexSrc( struct comedi_device *dev,struct enc_private *k ); */ static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k); static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k); static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value); -static void CountersInit(struct comedi_device *dev); -/* end internal routines */ /* Counter objects constructor. */ @@ -486,2814 +426,2814 @@ static const struct comedi_lrange s626_range_table = { 2, { } }; -static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static unsigned int s626_ai_reg_to_uint(int data) { -/* uint8_t PollList; */ -/* uint16_t AdcData; */ -/* uint16_t StartVal; */ -/* uint16_t index; */ -/* unsigned int data[16]; */ - int result; - int i; - int ret; - resource_size_t resourceStart; - dma_addr_t appdma; - struct comedi_subdevice *s; - struct pci_dev *pdev = NULL; + unsigned int tempdata; - if (alloc_private(dev, sizeof(struct s626_private)) < 0) - return -ENOMEM; + tempdata = (data >> 18); + if (tempdata & 0x2000) + tempdata &= 0x1fff; + else + tempdata += (1 << 13); - for (i = 0; i < ARRAY_SIZE(s626_boards) && !pdev; i++) { - do { - pdev = pci_get_subsys(s626_boards[i].vendor_id, - s626_boards[i].device_id, - s626_boards[i].subvendor_id, - s626_boards[i].subdevice_id, - pdev); + return tempdata; +} - if ((it->options[0] || it->options[1]) && pdev) { - /* matches requested bus/slot */ - if (pdev->bus->number == it->options[0] && - PCI_SLOT(pdev->devfn) == it->options[1]) - break; - } else - break; - } while (1); - } - devpriv->pdev = pdev; +/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */ +/* return 0; */ +/* } */ - if (pdev == NULL) { - printk(KERN_ERR "s626_attach: Board not present!!!\n"); - return -ENODEV; - } +static irqreturn_t s626_irq_handler(int irq, void *d) +{ + struct comedi_device *dev = d; + struct comedi_subdevice *s; + struct comedi_cmd *cmd; + struct enc_private *k; + unsigned long flags; + int32_t *readaddr; + uint32_t irqtype, irqstatus; + int i = 0; + short tempdata; + uint8_t group; + uint16_t irqbit; - result = comedi_pci_enable(pdev, "s626"); - if (result < 0) { - printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n"); - return -ENODEV; - } - devpriv->got_regions = 1; + DEBUG("s626_irq_handler: interrupt request received!!!\n"); - resourceStart = pci_resource_start(devpriv->pdev, 0); + if (dev->attached == 0) + return IRQ_NONE; + /* lock to avoid race with comedi_poll */ + spin_lock_irqsave(&dev->spinlock, flags); - devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE); - if (devpriv->base_addr == NULL) { - printk(KERN_ERR "s626_attach: IOREMAP failed\n"); - return -ENODEV; - } + /* save interrupt enable register state */ + irqstatus = readl(devpriv->base_addr + P_IER); - if (devpriv->base_addr) { - /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); + /* read interrupt type */ + irqtype = readl(devpriv->base_addr + P_ISR); - /* soft reset */ - writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); + /* disable master interrupt */ + writel(0, devpriv->base_addr + P_IER); - /* DMA FIXME DMA// */ - DEBUG("s626_attach: DMA ALLOCATION\n"); + /* clear interrupt */ + writel(irqtype, devpriv->base_addr + P_ISR); - /* adc buffer allocation */ - devpriv->allocatedBuf = 0; + /* do somethings */ + DEBUG("s626_irq_handler: interrupt type %d\n", irqtype); - devpriv->ANABuf.LogicalBase = - pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma); + switch (irqtype) { + case IRQ_RPS1: /* end_of_scan occurs */ - if (devpriv->ANABuf.LogicalBase == NULL) { - printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); - return -ENOMEM; - } + DEBUG("s626_irq_handler: RPS1 irq detected\n"); - devpriv->ANABuf.PhysicalBase = appdma; + /* manage ai subdevice */ + s = dev->subdevices; + cmd = &(s->async->cmd); - DEBUG - ("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n", - devpriv->ANABuf.LogicalBase, DMABUF_SIZE, - (uint32_t) devpriv->ANABuf.PhysicalBase); + /* Init ptr to DMA buffer that holds new ADC data. We skip the + * first uint16_t in the buffer because it contains junk data from + * the final ADC of the previous poll list scan. + */ + readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1; - devpriv->allocatedBuf++; + /* get the data and hand it over to comedi */ + for (i = 0; i < (s->async->cmd.chanlist_len); i++) { + /* Convert ADC data to 16-bit integer values and copy to application */ + /* buffer. */ + tempdata = s626_ai_reg_to_uint((int)*readaddr); + readaddr++; - devpriv->RPSBuf.LogicalBase = - pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma); + /* put data into read buffer */ + /* comedi_buf_put(s->async, tempdata); */ + if (cfc_write_to_buffer(s, tempdata) == 0) + printk + ("s626_irq_handler: cfc_write_to_buffer error!\n"); - if (devpriv->RPSBuf.LogicalBase == NULL) { - printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); - return -ENOMEM; + DEBUG("s626_irq_handler: ai channel %d acquired: %d\n", + i, tempdata); } - devpriv->RPSBuf.PhysicalBase = appdma; - - DEBUG - ("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n", - devpriv->RPSBuf.LogicalBase, DMABUF_SIZE, - (uint32_t) devpriv->RPSBuf.PhysicalBase); + /* end of scan occurs */ + s->async->events |= COMEDI_CB_EOS; - devpriv->allocatedBuf++; + if (!(devpriv->ai_continous)) + devpriv->ai_sample_count--; + if (devpriv->ai_sample_count <= 0) { + devpriv->ai_cmd_running = 0; - } + /* Stop RPS program. */ + MC_DISABLE(P_MC1, MC1_ERPS1); - dev->board_ptr = s626_boards; - dev->board_name = thisboard->name; + /* send end of acquisition */ + s->async->events |= COMEDI_CB_EOA; - ret = comedi_alloc_subdevices(dev, 6); - if (ret) - return ret; + /* disable master interrupt */ + irqstatus = 0; + } - dev->iobase = (unsigned long)devpriv->base_addr; - dev->irq = devpriv->pdev->irq; + if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) { + DEBUG + ("s626_irq_handler: enable interrupt on dio channel %d\n", + cmd->scan_begin_arg); - /* set up interrupt handler */ - if (dev->irq == 0) { - printk(KERN_ERR " unknown irq (bad)\n"); - } else { - ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED, - "s626", dev); + s626_dio_set_irq(dev, cmd->scan_begin_arg); - if (ret < 0) { - printk(KERN_ERR " irq not available\n"); - dev->irq = 0; + DEBUG("s626_irq_handler: External trigger is set!!!\n"); } - } - - DEBUG("s626_attach: -- it opts %d,%d --\n", - it->options[0], it->options[1]); + /* tell comedi that data is there */ + DEBUG("s626_irq_handler: events %d\n", s->async->events); + comedi_event(dev, s); + break; + case IRQ_GPIO3: /* check dio and conter interrupt */ - s = dev->subdevices + 0; - /* analog input subdevice */ - dev->read_subdev = s; - /* we support single-ended (ground) and differential */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; - s->n_chan = thisboard->ai_chans; - s->maxdata = (0xffff >> 2); - s->range_table = &s626_range_table; - s->len_chanlist = thisboard->ai_chans; /* This is the maximum chanlist - length that the board can - handle */ - s->insn_config = s626_ai_insn_config; - s->insn_read = s626_ai_insn_read; - s->do_cmd = s626_ai_cmd; - s->do_cmdtest = s626_ai_cmdtest; - s->cancel = s626_ai_cancel; + DEBUG("s626_irq_handler: GPIO3 irq detected\n"); - s = dev->subdevices + 1; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = thisboard->ao_chans; - s->maxdata = (0x3fff); - s->range_table = &range_bipolar10; - s->insn_write = s626_ao_winsn; - s->insn_read = s626_ao_rinsn; + /* manage ai subdevice */ + s = dev->subdevices; + cmd = &(s->async->cmd); - s = dev->subdevices + 2; - /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = S626_DIO_CHANNELS; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_A; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; + /* s626_dio_clear_irq(dev); */ - s = dev->subdevices + 3; - /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_B; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; + for (group = 0; group < S626_DIO_BANKS; group++) { + irqbit = 0; + /* read interrupt type */ + irqbit = DEBIread(dev, + ((struct dio_private *)(dev-> + subdevices + + 2 + + group)-> + private)->RDCapFlg); - s = dev->subdevices + 4; - /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_C; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; + /* check if interrupt is generated from dio channels */ + if (irqbit) { + s626_dio_reset_irq(dev, group, irqbit); + DEBUG + ("s626_irq_handler: check interrupt on dio group %d %d\n", + group, i); + if (devpriv->ai_cmd_running) { + /* check if interrupt is an ai acquisition start trigger */ + if ((irqbit >> (cmd->start_arg - + (16 * group))) + == 1 && cmd->start_src == TRIG_EXT) { + DEBUG + ("s626_irq_handler: Edge capture interrupt received from channel %d\n", + cmd->start_arg); - s = dev->subdevices + 5; - /* encoder (counter) subdevice */ - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; - s->n_chan = thisboard->enc_chans; - s->private = enc_private_data; - s->insn_config = s626_enc_insn_config; - s->insn_read = s626_enc_insn_read; - s->insn_write = s626_enc_insn_write; - s->maxdata = 0xffffff; - s->range_table = &range_unknown; + /* Start executing the RPS program. */ + MC_ENABLE(P_MC1, MC1_ERPS1); - /* stop ai_command */ - devpriv->ai_cmd_running = 0; + DEBUG + ("s626_irq_handler: acquisition start triggered!!!\n"); - if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) { - dma_addr_t pPhysBuf; - uint16_t chan; + if (cmd->scan_begin_src == + TRIG_EXT) { + DEBUG + ("s626_ai_cmd: enable interrupt on dio channel %d\n", + cmd-> + scan_begin_arg); - /* enab DEBI and audio pins, enable I2C interface. */ - MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); - /* Configure DEBI operating mode. */ - WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */ - /* bits wide. */ - | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) + s626_dio_set_irq(dev, + cmd->scan_begin_arg); - /* Declare DEBI */ - /* transfer timeout */ - /* interval. */ - |DEBI_SWAP /* Set up byte lane */ - /* steering. */ - | DEBI_CFG_INTEL); /* Intel-compatible */ - /* local bus (DEBI */ - /* never times out). */ - DEBUG("s626_attach: %d debi init -- %d\n", - DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | - DEBI_SWAP | DEBI_CFG_INTEL, - DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ | - DEBI_CFG_16Q); + DEBUG + ("s626_irq_handler: External scan trigger is set!!!\n"); + } + } + if ((irqbit >> (cmd->scan_begin_arg - + (16 * group))) + == 1 + && cmd->scan_begin_src == + TRIG_EXT) { + DEBUG + ("s626_irq_handler: Edge capture interrupt received from channel %d\n", + cmd->scan_begin_arg); - /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ - /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ + /* Trigger ADC scan loop start by setting RPS Signal 0. */ + MC_ENABLE(P_MC2, MC2_ADC_RPS); - /* Paging is disabled. */ - WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */ + DEBUG + ("s626_irq_handler: scan triggered!!! %d\n", + devpriv->ai_sample_count); + if (cmd->convert_src == + TRIG_EXT) { - /* Init GPIO so that ADC Start* is negated. */ - WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); + DEBUG + ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", + cmd->convert_arg - + (16 * group), + group); - /* IsBoardRevA is a boolean that indicates whether the board is RevA. - * - * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC - * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which - * is used to access the onboard serial EEPROM. The EEPROM's I2C - * DeviceAddress is hardwired to a value that is dependent on the - * 626 board revision. On all board revisions, the EEPROM stores - * TrimDAC calibration constants for analog I/O. On RevB and - * higher boards, the DeviceAddress is hardwired to 0 to enable - * the EEPROM to also store the PCI SubVendorID and SubDeviceID; - * this is the address at which the SAA7146 expects a - * configuration EEPROM to reside. On RevA boards, the EEPROM - * device address, which is hardwired to 4, prevents the SAA7146 - * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in - * default values, instead. - */ + devpriv->ai_convert_count + = cmd->chanlist_len; - /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */ - /* DeviceType (0xA0) */ - /* and DeviceAddress<<1. */ + s626_dio_set_irq(dev, + cmd->convert_arg); - devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */ - /* eeprom(revb) */ + DEBUG + ("s626_irq_handler: External convert trigger is set!!!\n"); + } - /* Issue an I2C ABORT command to halt any I2C operation in */ - /* progress and reset BUSY flag. */ - WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); - /* Write I2C control: abort any I2C activity. */ - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - /* Invoke command upload */ - while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) - ; - /* and wait for upload to complete. */ + if (cmd->convert_src == + TRIG_TIMER) { + k = &encpriv[5]; + devpriv->ai_convert_count + = cmd->chanlist_len; + k->SetEnable(dev, k, + CLKENAB_ALWAYS); + } + } + if ((irqbit >> (cmd->convert_arg - + (16 * group))) + == 1 + && cmd->convert_src == TRIG_EXT) { + DEBUG + ("s626_irq_handler: Edge capture interrupt received from channel %d\n", + cmd->convert_arg); - /* Per SAA7146 data sheet, write to STATUS reg twice to - * reset all I2C error flags. */ - for (i = 0; i < 2; i++) { - WR7146(P_I2CSTAT, I2C_CLKSEL); - /* Write I2C control: reset error flags. */ - MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */ - while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) - ; - /* and wait for upload to complete. */ - } + /* Trigger ADC scan loop start by setting RPS Signal 0. */ + MC_ENABLE(P_MC2, MC2_ADC_RPS); - /* Init audio interface functional attributes: set DAC/ADC - * serial clock rates, invert DAC serial clock so that - * DAC data setup times are satisfied, enable DAC serial - * clock out. - */ + DEBUG + ("s626_irq_handler: adc convert triggered!!!\n"); - WR7146(P_ACON2, ACON2_INIT); + devpriv->ai_convert_count--; - /* Set up TSL1 slot list, which is used to control the - * accumulation of ADC data: RSD1 = shift data in on SD1. - * SIB_A1 = store data uint8_t at next available location in - * FB BUFFER1 register. */ - WR7146(P_TSL1, RSD1 | SIB_A1); - /* Fetch ADC high data uint8_t. */ - WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); - /* Fetch ADC low data uint8_t; end of TSL1. */ + if (devpriv->ai_convert_count > + 0) { - /* enab TSL1 slot list so that it executes all the time. */ - WR7146(P_ACON1, ACON1_ADCSTART); + DEBUG + ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", + cmd->convert_arg - + (16 * group), + group); - /* Initialize RPS registers used for ADC. */ + s626_dio_set_irq(dev, + cmd->convert_arg); - /* Physical start of RPS program. */ - WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); + DEBUG + ("s626_irq_handler: External trigger is set!!!\n"); + } + } + } + break; + } + } - WR7146(P_RPSPAGE1, 0); - /* RPS program performs no explicit mem writes. */ - WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ + /* read interrupt type */ + irqbit = DEBIread(dev, LP_RDMISC2); - /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface - * to a known state by invoking ADCs until FB BUFFER 1 - * register shows that it is correctly receiving ADC data. - * This is necessary because the SAA7146 ADC interface does - * not start up in a defined state after a PCI reset. - */ + /* check interrupt on counters */ + DEBUG("s626_irq_handler: check counters interrupt %d\n", + irqbit); -/* PollList = EOPL; // Create a simple polling */ -/* // list for analog input */ -/* // channel 0. */ -/* ResetADC( dev, &PollList ); */ + if (irqbit & IRQ_COINT1A) { + DEBUG + ("s626_irq_handler: interrupt on counter 1A overflow\n"); + k = &encpriv[0]; -/* s626_ai_rinsn(dev,dev->subdevices,NULL,data); //( &AdcData ); // */ -/* //Get initial ADC */ -/* //value. */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT2A) { + DEBUG + ("s626_irq_handler: interrupt on counter 2A overflow\n"); + k = &encpriv[1]; -/* StartVal = data[0]; */ - -/* // VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION. */ -/* // Invoke ADCs until the new ADC value differs from the initial */ -/* // value or a timeout occurs. The timeout protects against the */ -/* // possibility that the driver is restarting and the ADC data is a */ -/* // fixed value resulting from the applied ADC analog input being */ -/* // unusually quiet or at the rail. */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT3A) { + DEBUG + ("s626_irq_handler: interrupt on counter 3A overflow\n"); + k = &encpriv[2]; -/* for ( index = 0; index < 500; index++ ) */ -/* { */ -/* s626_ai_rinsn(dev,dev->subdevices,NULL,data); */ -/* AdcData = data[0]; //ReadADC( &AdcData ); */ -/* if ( AdcData != StartVal ) */ -/* break; */ -/* } */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT1B) { + DEBUG + ("s626_irq_handler: interrupt on counter 1B overflow\n"); + k = &encpriv[3]; - /* end initADC */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT2B) { + DEBUG + ("s626_irq_handler: interrupt on counter 2B overflow\n"); + k = &encpriv[4]; - /* init the DAC interface */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); - /* Init Audio2's output DMAC attributes: burst length = 1 - * DWORD, threshold = 1 DWORD. - */ - WR7146(P_PCI_BT_A, 0); + if (devpriv->ai_convert_count > 0) { + devpriv->ai_convert_count--; + if (devpriv->ai_convert_count == 0) + k->SetEnable(dev, k, CLKENAB_INDEX); - /* Init Audio2's output DMA physical addresses. The protection - * address is set to 1 DWORD past the base address so that a - * single DWORD will be transferred each time a DMA transfer is - * enabled. */ + if (cmd->convert_src == TRIG_TIMER) { + DEBUG + ("s626_irq_handler: conver timer trigger!!! %d\n", + devpriv->ai_convert_count); - pPhysBuf = - devpriv->ANABuf.PhysicalBase + - (DAC_WDMABUF_OS * sizeof(uint32_t)); + /* Trigger ADC scan loop start by setting RPS Signal 0. */ + MC_ENABLE(P_MC2, MC2_ADC_RPS); + } + } + } + if (irqbit & IRQ_COINT3B) { + DEBUG + ("s626_irq_handler: interrupt on counter 3B overflow\n"); + k = &encpriv[5]; - WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */ - WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); - /* Cache Audio2's output DMA buffer logical address. This is - * where DAC data is buffered for A2 output DMA transfers. */ - devpriv->pDacWBuf = - (uint32_t *) devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS; + if (cmd->scan_begin_src == TRIG_TIMER) { + DEBUG + ("s626_irq_handler: scan timer trigger!!!\n"); - /* Audio2's output channels does not use paging. The protection - * violation handling bit is set so that the DMAC will - * automatically halt and its PCI address pointer will be reset - * when the protection address is reached. */ + /* Trigger ADC scan loop start by setting RPS Signal 0. */ + MC_ENABLE(P_MC2, MC2_ADC_RPS); + } - WR7146(P_PAGEA2_OUT, 8); + if (cmd->convert_src == TRIG_TIMER) { + DEBUG + ("s626_irq_handler: convert timer trigger is set\n"); + k = &encpriv[4]; + devpriv->ai_convert_count = cmd->chanlist_len; + k->SetEnable(dev, k, CLKENAB_ALWAYS); + } + } + } - /* Initialize time slot list 2 (TSL2), which is used to control - * the clock generation for and serialization of data to be sent - * to the DAC devices. Slot 0 is a NOP that is used to trap TSL - * execution; this permits other slots to be safely modified - * without first turning off the TSL sequencer (which is - * apparently impossible to do). Also, SD3 (which is driven by a - * pull-up resistor) is shifted in and stored to the MSB of - * FB_BUFFER2 to be used as evidence that the slot sequence has - * not yet finished executing. - */ + /* enable interrupt */ + writel(irqstatus, devpriv->base_addr + P_IER); - SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); - /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */ + DEBUG("s626_irq_handler: exit interrupt service routine.\n"); - /* Initialize slot 1, which is constant. Slot 1 causes a - * DWORD to be transferred from audio channel 2's output FIFO - * to the FIFO's output buffer so that it can be serialized - * and sent to the DAC during subsequent slots. All remaining - * slots are dynamically populated as required by the target - * DAC device. - */ - SETVECT(1, LF_A2); - /* Slot 1: Fetch DWORD from Audio2's output FIFO. */ + spin_unlock_irqrestore(&dev->spinlock, flags); + return IRQ_HANDLED; +} - /* Start DAC's audio interface (TSL2) running. */ - WR7146(P_ACON1, ACON1_DACSTART); +/* + * this functions build the RPS program for hardware driven acquistion + */ +static void ResetADC(struct comedi_device *dev, uint8_t *ppl) +{ + register uint32_t *pRPS; + uint32_t JmpAdrs; + uint16_t i; + uint16_t n; + uint32_t LocalPPL; + struct comedi_cmd *cmd = &(dev->subdevices->async->cmd); - /* end init DAC interface */ + /* Stop RPS program in case it is currently running. */ + MC_DISABLE(P_MC1, MC1_ERPS1); - /* Init Trim DACs to calibrated values. Do it twice because the - * SAA7146 audio channel does not always reset properly and - * sometimes causes the first few TrimDAC writes to malfunction. - */ + /* Set starting logical address to write RPS commands. */ + pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase; - LoadTrimDACs(dev); - LoadTrimDACs(dev); /* Insurance. */ + /* Initialize RPS instruction pointer. */ + WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); - /* Manually init all gate array hardware in case this is a soft - * reset (we have no way of determining whether this is a warm - * or cold start). This is necessary because the gate array will - * reset only in response to a PCI hard reset; there is no soft - * reset function. */ + /* Construct RPS program in RPSBuf DMA buffer */ - /* Init all DAC outputs to 0V and init all DAC setpoint and - * polarity images. - */ - for (chan = 0; chan < S626_DAC_CHANNELS; chan++) - SetDAC(dev, chan, 0); + if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) { + DEBUG("ResetADC: scan_begin pause inserted\n"); + /* Wait for Start trigger. */ + *pRPS++ = RPS_PAUSE | RPS_SIGADC; + *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC; + } - /* Init image of WRMISC2 Battery Charger Enabled control bit. - * This image is used when the state of the charger control bit, - * which has no direct hardware readback mechanism, is queried. - */ - devpriv->ChargeEnabled = 0; + /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary + * because the first RPS DEBI Write following a non-RPS DEBI write + * seems to always fail. If we don't do this dummy write, the ADC + * gain might not be set to the value required for the first slot in + * the poll list; the ADC gain would instead remain unchanged from + * the previously programmed value. + */ + *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); + /* Write DEBI Write command and address to shadow RAM. */ - /* Init image of watchdog timer interval in WRMISC2. This image - * maintains the value of the control bits of MISC2 are - * continuously reset to zero as long as the WD timer is disabled. - */ - devpriv->WDInterval = 0; + *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL; + *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); + /* Write DEBI immediate data to shadow RAM: */ - /* Init Counter Interrupt enab mask for RDMISC2. This mask is - * applied against MISC2 when testing to determine which timer - * events are requesting interrupt service. - */ - devpriv->CounterIntEnabs = 0; + *pRPS++ = GSEL_BIPOLAR5V; + /* arbitrary immediate data value. */ - /* Init counters. */ - CountersInit(dev); + *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; + /* Reset "shadow RAM uploaded" flag. */ + *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */ + *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to finish. */ - /* Without modifying the state of the Battery Backup enab, disable - * the watchdog timer, set DIO channels 0-5 to operate in the - * standard DIO (vs. counter overflow) mode, disable the battery - * charger, and reset the watchdog interval selector to zero. + /* Digitize all slots in the poll list. This is implemented as a + * for loop to limit the slot count to 16 in case the application + * forgot to set the EOPL flag in the final slot. + */ + for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) { + /* Convert application's poll list item to private board class + * format. Each app poll list item is an uint8_t with form + * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 = + * +-10V, 1 = +-5V, and EOPL = End of Poll List marker. */ - WriteMISC2(dev, (uint16_t) (DEBIread(dev, - LP_RDMISC2) & - MISC2_BATT_ENABLE)); + LocalPPL = + (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V : + GSEL_BIPOLAR10V); - /* Initialize the digital I/O subsystem. */ - s626_dio_init(dev); + /* Switch ADC analog gain. */ + *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /* Write DEBI command */ + /* and address to */ + /* shadow RAM. */ + *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL; + *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); /* Write DEBI */ + /* immediate data to */ + /* shadow RAM. */ + *pRPS++ = LocalPPL; + *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; /* Reset "shadow RAM uploaded" */ + /* flag. */ + *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */ + *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to */ + /* finish. */ - /* enable interrupt test */ - /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ - } + /* Select ADC analog input channel. */ + *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); + /* Write DEBI command and address to shadow RAM. */ + *pRPS++ = DEBI_CMD_WRWORD | LP_ISEL; + *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); + /* Write DEBI immediate data to shadow RAM. */ + *pRPS++ = LocalPPL; + *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; + /* Reset "shadow RAM uploaded" flag. */ - DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor, - (uint32_t) devpriv->base_addr); + *pRPS++ = RPS_UPLOAD | RPS_DEBI; + /* Invoke shadow RAM upload. */ - return 1; -} + *pRPS++ = RPS_PAUSE | RPS_DEBI; + /* Wait for shadow upload to finish. */ -static unsigned int s626_ai_reg_to_uint(int data) -{ - unsigned int tempdata; + /* Delay at least 10 microseconds for analog input settling. + * Instead of padding with NOPs, we use RPS_JUMP instructions + * here; this allows us to produce a longer delay than is + * possible with NOPs because each RPS_JUMP flushes the RPS' + * instruction prefetch pipeline. + */ + JmpAdrs = + (uint32_t) devpriv->RPSBuf.PhysicalBase + + (uint32_t) ((unsigned long)pRPS - + (unsigned long)devpriv->RPSBuf.LogicalBase); + for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) { + JmpAdrs += 8; /* Repeat to implement time delay: */ + *pRPS++ = RPS_JUMP; /* Jump to next RPS instruction. */ + *pRPS++ = JmpAdrs; + } - tempdata = (data >> 18); - if (tempdata & 0x2000) - tempdata &= 0x1fff; - else - tempdata += (1 << 13); + if (cmd != NULL && cmd->convert_src != TRIG_NOW) { + DEBUG("ResetADC: convert pause inserted\n"); + /* Wait for Start trigger. */ + *pRPS++ = RPS_PAUSE | RPS_SIGADC; + *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC; + } + /* Start ADC by pulsing GPIO1. */ + *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */ + *pRPS++ = GPIO_BASE | GPIO1_LO; + *pRPS++ = RPS_NOP; + /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */ + *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */ + *pRPS++ = GPIO_BASE | GPIO1_HI; - return tempdata; -} + /* Wait for ADC to complete (GPIO2 is asserted high when ADC not + * busy) and for data from previous conversion to shift into FB + * BUFFER 1 register. + */ + *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */ -/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */ -/* return 0; */ -/* } */ + /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */ + *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); + *pRPS++ = + (uint32_t) devpriv->ANABuf.PhysicalBase + + (devpriv->AdcItems << 2); -static irqreturn_t s626_irq_handler(int irq, void *d) -{ - struct comedi_device *dev = d; - struct comedi_subdevice *s; - struct comedi_cmd *cmd; - struct enc_private *k; - unsigned long flags; - int32_t *readaddr; - uint32_t irqtype, irqstatus; - int i = 0; - short tempdata; - uint8_t group; - uint16_t irqbit; + /* If this slot's EndOfPollList flag is set, all channels have */ + /* now been processed. */ + if (*ppl++ & EOPL) { + devpriv->AdcItems++; /* Adjust poll list item count. */ + break; /* Exit poll list processing loop. */ + } + } + DEBUG("ResetADC: ADC items %d\n", devpriv->AdcItems); - DEBUG("s626_irq_handler: interrupt request received!!!\n"); + /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the + * ADC to stabilize for 2 microseconds before starting the final + * (dummy) conversion. This delay is necessary to allow sufficient + * time between last conversion finished and the start of the dummy + * conversion. Without this delay, the last conversion's data value + * is sometimes set to the previous conversion's data value. + */ + for (n = 0; n < (2 * RPSCLK_PER_US); n++) + *pRPS++ = RPS_NOP; - if (dev->attached == 0) - return IRQ_NONE; - /* lock to avoid race with comedi_poll */ - spin_lock_irqsave(&dev->spinlock, flags); + /* Start a dummy conversion to cause the data from the last + * conversion of interest to be shifted in. + */ + *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */ + *pRPS++ = GPIO_BASE | GPIO1_LO; + *pRPS++ = RPS_NOP; + /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */ + *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */ + *pRPS++ = GPIO_BASE | GPIO1_HI; - /* save interrupt enable register state */ - irqstatus = readl(devpriv->base_addr + P_IER); + /* Wait for the data from the last conversion of interest to arrive + * in FB BUFFER 1 register. + */ + *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */ - /* read interrupt type */ - irqtype = readl(devpriv->base_addr + P_ISR); + /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */ + *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); /* */ + *pRPS++ = + (uint32_t) devpriv->ANABuf.PhysicalBase + (devpriv->AdcItems << 2); - /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); + /* Indicate ADC scan loop is finished. */ + /* *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; // Signal ReadADC() that scan is done. */ - /* clear interrupt */ - writel(irqtype, devpriv->base_addr + P_ISR); + /* invoke interrupt */ + if (devpriv->ai_cmd_running == 1) { + DEBUG("ResetADC: insert irq in ADC RPS task\n"); + *pRPS++ = RPS_IRQ; + } + /* Restart RPS program at its beginning. */ + *pRPS++ = RPS_JUMP; /* Branch to start of RPS program. */ + *pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase; - /* do somethings */ - DEBUG("s626_irq_handler: interrupt type %d\n", irqtype); + /* End of RPS program build */ +} - switch (irqtype) { - case IRQ_RPS1: /* end_of_scan occurs */ +/* TO COMPLETE, IF NECESSARY */ +static int s626_ai_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ - DEBUG("s626_irq_handler: RPS1 irq detected\n"); + return -EINVAL; +} - /* manage ai subdevice */ - s = dev->subdevices; - cmd = &(s->async->cmd); +/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */ +/* { */ +/* register uint8_t i; */ +/* register int32_t *readaddr; */ - /* Init ptr to DMA buffer that holds new ADC data. We skip the - * first uint16_t in the buffer because it contains junk data from - * the final ADC of the previous poll list scan. - */ - readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1; +/* DEBUG("as626_ai_rinsn: ai_rinsn enter\n"); */ - /* get the data and hand it over to comedi */ - for (i = 0; i < (s->async->cmd.chanlist_len); i++) { - /* Convert ADC data to 16-bit integer values and copy to application */ - /* buffer. */ - tempdata = s626_ai_reg_to_uint((int)*readaddr); - readaddr++; +/* Trigger ADC scan loop start by setting RPS Signal 0. */ +/* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ - /* put data into read buffer */ - /* comedi_buf_put(s->async, tempdata); */ - if (cfc_write_to_buffer(s, tempdata) == 0) - printk - ("s626_irq_handler: cfc_write_to_buffer error!\n"); +/* Wait until ADC scan loop is finished (RPS Signal 0 reset). */ +/* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */ - DEBUG("s626_irq_handler: ai channel %d acquired: %d\n", - i, tempdata); - } +/* Init ptr to DMA buffer that holds new ADC data. We skip the + * first uint16_t in the buffer because it contains junk data from + * the final ADC of the previous poll list scan. + */ +/* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */ - /* end of scan occurs */ - s->async->events |= COMEDI_CB_EOS; +/* Convert ADC data to 16-bit integer values and copy to application buffer. */ +/* for ( i = 0; i < devpriv->AdcItems; i++ ) { */ +/* *data = s626_ai_reg_to_uint( *readaddr++ ); */ +/* DEBUG("s626_ai_rinsn: data %d\n",*data); */ +/* data++; */ +/* } */ - if (!(devpriv->ai_continous)) - devpriv->ai_sample_count--; - if (devpriv->ai_sample_count <= 0) { - devpriv->ai_cmd_running = 0; +/* DEBUG("s626_ai_rinsn: ai_rinsn escape\n"); */ +/* return i; */ +/* } */ - /* Stop RPS program. */ - MC_DISABLE(P_MC1, MC1_ERPS1); +static int s626_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + uint16_t chan = CR_CHAN(insn->chanspec); + uint16_t range = CR_RANGE(insn->chanspec); + uint16_t AdcSpec = 0; + uint32_t GpioImage; + int n; - /* send end of acquisition */ - s->async->events |= COMEDI_CB_EOA; + /* interrupt call test */ +/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */ + /* Writing a logical 1 into any of the RPS_PSR bits causes the + * corresponding interrupt to be generated if enabled + */ - /* disable master interrupt */ - irqstatus = 0; - } + DEBUG("s626_ai_insn_read: entering\n"); - if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: enable interrupt on dio channel %d\n", - cmd->scan_begin_arg); + /* Convert application's ADC specification into form + * appropriate for register programming. + */ + if (range == 0) + AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V); + else + AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V); - s626_dio_set_irq(dev, cmd->scan_begin_arg); + /* Switch ADC analog gain. */ + DEBIwrite(dev, LP_GSEL, AdcSpec); /* Set gain. */ - DEBUG("s626_irq_handler: External trigger is set!!!\n"); - } - /* tell comedi that data is there */ - DEBUG("s626_irq_handler: events %d\n", s->async->events); - comedi_event(dev, s); - break; - case IRQ_GPIO3: /* check dio and conter interrupt */ + /* Select ADC analog input channel. */ + DEBIwrite(dev, LP_ISEL, AdcSpec); /* Select channel. */ - DEBUG("s626_irq_handler: GPIO3 irq detected\n"); + for (n = 0; n < insn->n; n++) { - /* manage ai subdevice */ - s = dev->subdevices; - cmd = &(s->async->cmd); + /* Delay 10 microseconds for analog input settling. */ + udelay(10); - /* s626_dio_clear_irq(dev); */ + /* Start ADC by pulsing GPIO1 low. */ + GpioImage = RR7146(P_GPIO); + /* Assert ADC Start command */ + WR7146(P_GPIO, GpioImage & ~GPIO1_HI); + /* and stretch it out. */ + WR7146(P_GPIO, GpioImage & ~GPIO1_HI); + WR7146(P_GPIO, GpioImage & ~GPIO1_HI); + /* Negate ADC Start command. */ + WR7146(P_GPIO, GpioImage | GPIO1_HI); - for (group = 0; group < S626_DIO_BANKS; group++) { - irqbit = 0; - /* read interrupt type */ - irqbit = DEBIread(dev, - ((struct dio_private *)(dev-> - subdevices + - 2 + - group)-> - private)->RDCapFlg); - - /* check if interrupt is generated from dio channels */ - if (irqbit) { - s626_dio_reset_irq(dev, group, irqbit); - DEBUG - ("s626_irq_handler: check interrupt on dio group %d %d\n", - group, i); - if (devpriv->ai_cmd_running) { - /* check if interrupt is an ai acquisition start trigger */ - if ((irqbit >> (cmd->start_arg - - (16 * group))) - == 1 && cmd->start_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: Edge capture interrupt received from channel %d\n", - cmd->start_arg); + /* Wait for ADC to complete (GPIO2 is asserted high when */ + /* ADC not busy) and for data from previous conversion to */ + /* shift into FB BUFFER 1 register. */ - /* Start executing the RPS program. */ - MC_ENABLE(P_MC1, MC1_ERPS1); + /* Wait for ADC done. */ + while (!(RR7146(P_PSR) & PSR_GPIO2)) + ; - DEBUG - ("s626_irq_handler: acquisition start triggered!!!\n"); + /* Fetch ADC data. */ + if (n != 0) + data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); - if (cmd->scan_begin_src == - TRIG_EXT) { - DEBUG - ("s626_ai_cmd: enable interrupt on dio channel %d\n", - cmd-> - scan_begin_arg); + /* Allow the ADC to stabilize for 4 microseconds before + * starting the next (final) conversion. This delay is + * necessary to allow sufficient time between last + * conversion finished and the start of the next + * conversion. Without this delay, the last conversion's + * data value is sometimes set to the previous + * conversion's data value. + */ + udelay(4); + } - s626_dio_set_irq(dev, - cmd->scan_begin_arg); + /* Start a dummy conversion to cause the data from the + * previous conversion to be shifted in. */ + GpioImage = RR7146(P_GPIO); - DEBUG - ("s626_irq_handler: External scan trigger is set!!!\n"); - } - } - if ((irqbit >> (cmd->scan_begin_arg - - (16 * group))) - == 1 - && cmd->scan_begin_src == - TRIG_EXT) { - DEBUG - ("s626_irq_handler: Edge capture interrupt received from channel %d\n", - cmd->scan_begin_arg); + /* Assert ADC Start command */ + WR7146(P_GPIO, GpioImage & ~GPIO1_HI); + /* and stretch it out. */ + WR7146(P_GPIO, GpioImage & ~GPIO1_HI); + WR7146(P_GPIO, GpioImage & ~GPIO1_HI); + /* Negate ADC Start command. */ + WR7146(P_GPIO, GpioImage | GPIO1_HI); - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); + /* Wait for the data to arrive in FB BUFFER 1 register. */ - DEBUG - ("s626_irq_handler: scan triggered!!! %d\n", - devpriv->ai_sample_count); - if (cmd->convert_src == - TRIG_EXT) { + /* Wait for ADC done. */ + while (!(RR7146(P_PSR) & PSR_GPIO2)) + ; - DEBUG - ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", - cmd->convert_arg - - (16 * group), - group); + /* Fetch ADC data from audio interface's input shift register. */ - devpriv->ai_convert_count - = cmd->chanlist_len; + /* Fetch ADC data. */ + if (n != 0) + data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); - s626_dio_set_irq(dev, - cmd->convert_arg); + DEBUG("s626_ai_insn_read: samples %d, data %d\n", n, data[n - 1]); - DEBUG - ("s626_irq_handler: External convert trigger is set!!!\n"); - } + return n; +} - if (cmd->convert_src == - TRIG_TIMER) { - k = &encpriv[5]; - devpriv->ai_convert_count - = cmd->chanlist_len; - k->SetEnable(dev, k, - CLKENAB_ALWAYS); - } - } - if ((irqbit >> (cmd->convert_arg - - (16 * group))) - == 1 - && cmd->convert_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: Edge capture interrupt received from channel %d\n", - cmd->convert_arg); +static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd) +{ - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); + int n; - DEBUG - ("s626_irq_handler: adc convert triggered!!!\n"); + for (n = 0; n < cmd->chanlist_len; n++) { + if (CR_RANGE((cmd->chanlist)[n]) == 0) + ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V); + else + ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V); + } + if (n != 0) + ppl[n - 1] |= EOPL; - devpriv->ai_convert_count--; + return n; +} - if (devpriv->ai_convert_count > - 0) { +static int s626_ai_inttrig(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int trignum) +{ + if (trignum != 0) + return -EINVAL; - DEBUG - ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", - cmd->convert_arg - - (16 * group), - group); + DEBUG("s626_ai_inttrig: trigger adc start..."); - s626_dio_set_irq(dev, - cmd->convert_arg); + /* Start executing the RPS program. */ + MC_ENABLE(P_MC1, MC1_ERPS1); - DEBUG - ("s626_irq_handler: External trigger is set!!!\n"); - } - } - } - break; - } - } + s->async->inttrig = NULL; - /* read interrupt type */ - irqbit = DEBIread(dev, LP_RDMISC2); + DEBUG(" done\n"); - /* check interrupt on counters */ - DEBUG("s626_irq_handler: check counters interrupt %d\n", - irqbit); + return 1; +} - if (irqbit & IRQ_COINT1A) { - DEBUG - ("s626_irq_handler: interrupt on counter 1A overflow\n"); - k = &encpriv[0]; +/* TO COMPLETE */ +static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +{ - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); - } - if (irqbit & IRQ_COINT2A) { - DEBUG - ("s626_irq_handler: interrupt on counter 2A overflow\n"); - k = &encpriv[1]; + uint8_t ppl[16]; + struct comedi_cmd *cmd = &s->async->cmd; + struct enc_private *k; + int tick; - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); - } - if (irqbit & IRQ_COINT3A) { - DEBUG - ("s626_irq_handler: interrupt on counter 3A overflow\n"); - k = &encpriv[2]; + DEBUG("s626_ai_cmd: entering command function\n"); - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); - } - if (irqbit & IRQ_COINT1B) { - DEBUG - ("s626_irq_handler: interrupt on counter 1B overflow\n"); - k = &encpriv[3]; + if (devpriv->ai_cmd_running) { + printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n", + dev->minor); + return -EBUSY; + } + /* disable interrupt */ + writel(0, devpriv->base_addr + P_IER); - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); - } - if (irqbit & IRQ_COINT2B) { - DEBUG - ("s626_irq_handler: interrupt on counter 2B overflow\n"); - k = &encpriv[4]; + /* clear interrupt request */ + writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR); - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); + /* clear any pending interrupt */ + s626_dio_clear_irq(dev); + /* s626_enc_clear_irq(dev); */ - if (devpriv->ai_convert_count > 0) { - devpriv->ai_convert_count--; - if (devpriv->ai_convert_count == 0) - k->SetEnable(dev, k, CLKENAB_INDEX); + /* reset ai_cmd_running flag */ + devpriv->ai_cmd_running = 0; - if (cmd->convert_src == TRIG_TIMER) { - DEBUG - ("s626_irq_handler: conver timer trigger!!! %d\n", - devpriv->ai_convert_count); + /* test if cmd is valid */ + if (cmd == NULL) { + DEBUG("s626_ai_cmd: NULL command\n"); + return -EINVAL; + } else { + DEBUG("s626_ai_cmd: command received!!!\n"); + } - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); - } - } - } - if (irqbit & IRQ_COINT3B) { - DEBUG - ("s626_irq_handler: interrupt on counter 3B overflow\n"); - k = &encpriv[5]; + if (dev->irq == 0) { + comedi_error(dev, + "s626_ai_cmd: cannot run command without an irq"); + return -EIO; + } - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); + s626_ai_load_polllist(ppl, cmd); + devpriv->ai_cmd_running = 1; + devpriv->ai_convert_count = 0; - if (cmd->scan_begin_src == TRIG_TIMER) { - DEBUG - ("s626_irq_handler: scan timer trigger!!!\n"); + switch (cmd->scan_begin_src) { + case TRIG_FOLLOW: + break; + case TRIG_TIMER: + /* set a conter to generate adc trigger at scan_begin_arg interval */ + k = &encpriv[5]; + tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg, + cmd->flags & TRIG_ROUND_MASK); - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); - } + /* load timer value and enable interrupt */ + s626_timer_load(dev, k, tick); + k->SetEnable(dev, k, CLKENAB_ALWAYS); - if (cmd->convert_src == TRIG_TIMER) { - DEBUG - ("s626_irq_handler: convert timer trigger is set\n"); - k = &encpriv[4]; - devpriv->ai_convert_count = cmd->chanlist_len; - k->SetEnable(dev, k, CLKENAB_ALWAYS); - } - } - } + DEBUG("s626_ai_cmd: scan trigger timer is set with value %d\n", + tick); - /* enable interrupt */ - writel(irqstatus, devpriv->base_addr + P_IER); + break; + case TRIG_EXT: + /* set the digital line and interrupt for scan trigger */ + if (cmd->start_src != TRIG_EXT) + s626_dio_set_irq(dev, cmd->scan_begin_arg); - DEBUG("s626_irq_handler: exit interrupt service routine.\n"); + DEBUG("s626_ai_cmd: External scan trigger is set!!!\n"); - spin_unlock_irqrestore(&dev->spinlock, flags); - return IRQ_HANDLED; -} + break; + } -static void s626_detach(struct comedi_device *dev) -{ - if (devpriv) { - /* stop ai_command */ - devpriv->ai_cmd_running = 0; + switch (cmd->convert_src) { + case TRIG_NOW: + break; + case TRIG_TIMER: + /* set a conter to generate adc trigger at convert_arg interval */ + k = &encpriv[4]; + tick = s626_ns_to_timer((int *)&cmd->convert_arg, + cmd->flags & TRIG_ROUND_MASK); - if (devpriv->base_addr) { - /* interrupt mask */ - WR7146(P_IER, 0); /* Disable master interrupt. */ - WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); /* Clear board's IRQ status flag. */ + /* load timer value and enable interrupt */ + s626_timer_load(dev, k, tick); + k->SetEnable(dev, k, CLKENAB_INDEX); - /* Disable the watchdog timer and battery charger. */ - WriteMISC2(dev, 0); + DEBUG + ("s626_ai_cmd: convert trigger timer is set with value %d\n", + tick); + break; + case TRIG_EXT: + /* set the digital line and interrupt for convert trigger */ + if (cmd->scan_begin_src != TRIG_EXT + && cmd->start_src == TRIG_EXT) + s626_dio_set_irq(dev, cmd->convert_arg); - /* Close all interfaces on 7146 device. */ - WR7146(P_MC1, MC1_SHUTDOWN); - WR7146(P_ACON1, ACON1_BASE); + DEBUG("s626_ai_cmd: External convert trigger is set!!!\n"); - CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE); - CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE); - } + break; + } - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv->base_addr) - iounmap(devpriv->base_addr); - if (devpriv->pdev) { - if (devpriv->got_regions) - comedi_pci_disable(devpriv->pdev); - pci_dev_put(devpriv->pdev); - } + switch (cmd->stop_src) { + case TRIG_COUNT: + /* data arrives as one packet */ + devpriv->ai_sample_count = cmd->stop_arg; + devpriv->ai_continous = 0; + break; + case TRIG_NONE: + /* continous acquisition */ + devpriv->ai_continous = 1; + devpriv->ai_sample_count = 0; + break; } -} -/* - * this functions build the RPS program for hardware driven acquistion - */ -static void ResetADC(struct comedi_device *dev, uint8_t *ppl) -{ - register uint32_t *pRPS; - uint32_t JmpAdrs; - uint16_t i; - uint16_t n; - uint32_t LocalPPL; - struct comedi_cmd *cmd = &(dev->subdevices->async->cmd); + ResetADC(dev, ppl); - /* Stop RPS program in case it is currently running. */ - MC_DISABLE(P_MC1, MC1_ERPS1); + switch (cmd->start_src) { + case TRIG_NOW: + /* Trigger ADC scan loop start by setting RPS Signal 0. */ + /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ - /* Set starting logical address to write RPS commands. */ - pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase; + /* Start executing the RPS program. */ + MC_ENABLE(P_MC1, MC1_ERPS1); - /* Initialize RPS instruction pointer. */ - WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); + DEBUG("s626_ai_cmd: ADC triggered\n"); + s->async->inttrig = NULL; + break; + case TRIG_EXT: + /* configure DIO channel for acquisition trigger */ + s626_dio_set_irq(dev, cmd->start_arg); - /* Construct RPS program in RPSBuf DMA buffer */ + DEBUG("s626_ai_cmd: External start trigger is set!!!\n"); - if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) { - DEBUG("ResetADC: scan_begin pause inserted\n"); - /* Wait for Start trigger. */ - *pRPS++ = RPS_PAUSE | RPS_SIGADC; - *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC; + s->async->inttrig = NULL; + break; + case TRIG_INT: + s->async->inttrig = s626_ai_inttrig; + break; } - /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary - * because the first RPS DEBI Write following a non-RPS DEBI write - * seems to always fail. If we don't do this dummy write, the ADC - * gain might not be set to the value required for the first slot in - * the poll list; the ADC gain would instead remain unchanged from - * the previously programmed value. - */ - *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); - /* Write DEBI Write command and address to shadow RAM. */ + /* enable interrupt */ + writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); - *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL; - *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); - /* Write DEBI immediate data to shadow RAM: */ + DEBUG("s626_ai_cmd: command function terminated\n"); - *pRPS++ = GSEL_BIPOLAR5V; - /* arbitrary immediate data value. */ + return 0; +} - *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; - /* Reset "shadow RAM uploaded" flag. */ - *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */ - *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to finish. */ +static int s626_ai_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_cmd *cmd) +{ + int err = 0; + int tmp; - /* Digitize all slots in the poll list. This is implemented as a - * for loop to limit the slot count to 16 in case the application - * forgot to set the EOPL flag in the final slot. - */ - for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) { - /* Convert application's poll list item to private board class - * format. Each app poll list item is an uint8_t with form - * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 = - * +-10V, 1 = +-5V, and EOPL = End of Poll List marker. - */ - LocalPPL = - (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V : - GSEL_BIPOLAR10V); + /* cmdtest tests a particular command to see if it is valid. Using + * the cmdtest ioctl, a user can create a valid cmd and then have it + * executes by the cmd ioctl. + * + * cmdtest returns 1,2,3,4 or 0, depending on which tests the + * command passes. */ - /* Switch ADC analog gain. */ - *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /* Write DEBI command */ - /* and address to */ - /* shadow RAM. */ - *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL; - *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); /* Write DEBI */ - /* immediate data to */ - /* shadow RAM. */ - *pRPS++ = LocalPPL; - *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; /* Reset "shadow RAM uploaded" */ - /* flag. */ - *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */ - *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to */ - /* finish. */ + /* step 1: make sure trigger sources are trivially valid */ - /* Select ADC analog input channel. */ - *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); - /* Write DEBI command and address to shadow RAM. */ - *pRPS++ = DEBI_CMD_WRWORD | LP_ISEL; - *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); - /* Write DEBI immediate data to shadow RAM. */ - *pRPS++ = LocalPPL; - *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; - /* Reset "shadow RAM uploaded" flag. */ + tmp = cmd->start_src; + cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT; + if (!cmd->start_src || tmp != cmd->start_src) + err++; - *pRPS++ = RPS_UPLOAD | RPS_DEBI; - /* Invoke shadow RAM upload. */ + tmp = cmd->scan_begin_src; + cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; + if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) + err++; - *pRPS++ = RPS_PAUSE | RPS_DEBI; - /* Wait for shadow upload to finish. */ + tmp = cmd->convert_src; + cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; + if (!cmd->convert_src || tmp != cmd->convert_src) + err++; - /* Delay at least 10 microseconds for analog input settling. - * Instead of padding with NOPs, we use RPS_JUMP instructions - * here; this allows us to produce a longer delay than is - * possible with NOPs because each RPS_JUMP flushes the RPS' - * instruction prefetch pipeline. - */ - JmpAdrs = - (uint32_t) devpriv->RPSBuf.PhysicalBase + - (uint32_t) ((unsigned long)pRPS - - (unsigned long)devpriv->RPSBuf.LogicalBase); - for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) { - JmpAdrs += 8; /* Repeat to implement time delay: */ - *pRPS++ = RPS_JUMP; /* Jump to next RPS instruction. */ - *pRPS++ = JmpAdrs; - } + tmp = cmd->scan_end_src; + cmd->scan_end_src &= TRIG_COUNT; + if (!cmd->scan_end_src || tmp != cmd->scan_end_src) + err++; - if (cmd != NULL && cmd->convert_src != TRIG_NOW) { - DEBUG("ResetADC: convert pause inserted\n"); - /* Wait for Start trigger. */ - *pRPS++ = RPS_PAUSE | RPS_SIGADC; - *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC; - } - /* Start ADC by pulsing GPIO1. */ - *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */ - *pRPS++ = GPIO_BASE | GPIO1_LO; - *pRPS++ = RPS_NOP; - /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */ - *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */ - *pRPS++ = GPIO_BASE | GPIO1_HI; + tmp = cmd->stop_src; + cmd->stop_src &= TRIG_COUNT | TRIG_NONE; + if (!cmd->stop_src || tmp != cmd->stop_src) + err++; - /* Wait for ADC to complete (GPIO2 is asserted high when ADC not - * busy) and for data from previous conversion to shift into FB - * BUFFER 1 register. - */ - *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */ + if (err) + return 1; - /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */ - *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); - *pRPS++ = - (uint32_t) devpriv->ANABuf.PhysicalBase + - (devpriv->AdcItems << 2); + /* step 2: make sure trigger sources are unique and mutually + compatible */ - /* If this slot's EndOfPollList flag is set, all channels have */ - /* now been processed. */ - if (*ppl++ & EOPL) { - devpriv->AdcItems++; /* Adjust poll list item count. */ - break; /* Exit poll list processing loop. */ - } + /* note that mutual compatibility is not an issue here */ + if (cmd->scan_begin_src != TRIG_TIMER && + cmd->scan_begin_src != TRIG_EXT + && cmd->scan_begin_src != TRIG_FOLLOW) + err++; + if (cmd->convert_src != TRIG_TIMER && + cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) + err++; + if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) + err++; + + if (err) + return 2; + + /* step 3: make sure arguments are trivially compatible */ + + if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) { + cmd->start_arg = 0; + err++; } - DEBUG("ResetADC: ADC items %d\n", devpriv->AdcItems); - /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the - * ADC to stabilize for 2 microseconds before starting the final - * (dummy) conversion. This delay is necessary to allow sufficient - * time between last conversion finished and the start of the dummy - * conversion. Without this delay, the last conversion's data value - * is sometimes set to the previous conversion's data value. - */ - for (n = 0; n < (2 * RPSCLK_PER_US); n++) - *pRPS++ = RPS_NOP; + if (cmd->start_src == TRIG_EXT && cmd->start_arg > 39) { + cmd->start_arg = 39; + err++; + } - /* Start a dummy conversion to cause the data from the last - * conversion of interest to be shifted in. - */ - *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */ - *pRPS++ = GPIO_BASE | GPIO1_LO; - *pRPS++ = RPS_NOP; - /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */ - *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */ - *pRPS++ = GPIO_BASE | GPIO1_HI; + if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) { + cmd->scan_begin_arg = 39; + err++; + } - /* Wait for the data from the last conversion of interest to arrive - * in FB BUFFER 1 register. - */ - *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */ + if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) { + cmd->convert_arg = 39; + err++; + } +#define MAX_SPEED 200000 /* in nanoseconds */ +#define MIN_SPEED 2000000000 /* in nanoseconds */ - /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */ - *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); /* */ - *pRPS++ = - (uint32_t) devpriv->ANABuf.PhysicalBase + (devpriv->AdcItems << 2); + if (cmd->scan_begin_src == TRIG_TIMER) { + if (cmd->scan_begin_arg < MAX_SPEED) { + cmd->scan_begin_arg = MAX_SPEED; + err++; + } + if (cmd->scan_begin_arg > MIN_SPEED) { + cmd->scan_begin_arg = MIN_SPEED; + err++; + } + } else { + /* external trigger */ + /* should be level/edge, hi/lo specification here */ + /* should specify multiple external triggers */ +/* if(cmd->scan_begin_arg>9){ */ +/* cmd->scan_begin_arg=9; */ +/* err++; */ +/* } */ + } + if (cmd->convert_src == TRIG_TIMER) { + if (cmd->convert_arg < MAX_SPEED) { + cmd->convert_arg = MAX_SPEED; + err++; + } + if (cmd->convert_arg > MIN_SPEED) { + cmd->convert_arg = MIN_SPEED; + err++; + } + } else { + /* external trigger */ + /* see above */ +/* if(cmd->convert_arg>9){ */ +/* cmd->convert_arg=9; */ +/* err++; */ +/* } */ + } - /* Indicate ADC scan loop is finished. */ - /* *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; // Signal ReadADC() that scan is done. */ + if (cmd->scan_end_arg != cmd->chanlist_len) { + cmd->scan_end_arg = cmd->chanlist_len; + err++; + } + if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_arg > 0x00ffffff) { + cmd->stop_arg = 0x00ffffff; + err++; + } + } else { + /* TRIG_NONE */ + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + err++; + } + } - /* invoke interrupt */ - if (devpriv->ai_cmd_running == 1) { - DEBUG("ResetADC: insert irq in ADC RPS task\n"); - *pRPS++ = RPS_IRQ; + if (err) + return 3; + + /* step 4: fix up any arguments */ + + if (cmd->scan_begin_src == TRIG_TIMER) { + tmp = cmd->scan_begin_arg; + s626_ns_to_timer((int *)&cmd->scan_begin_arg, + cmd->flags & TRIG_ROUND_MASK); + if (tmp != cmd->scan_begin_arg) + err++; + } + if (cmd->convert_src == TRIG_TIMER) { + tmp = cmd->convert_arg; + s626_ns_to_timer((int *)&cmd->convert_arg, + cmd->flags & TRIG_ROUND_MASK); + if (tmp != cmd->convert_arg) + err++; + if (cmd->scan_begin_src == TRIG_TIMER && + cmd->scan_begin_arg < + cmd->convert_arg * cmd->scan_end_arg) { + cmd->scan_begin_arg = + cmd->convert_arg * cmd->scan_end_arg; + err++; + } } - /* Restart RPS program at its beginning. */ - *pRPS++ = RPS_JUMP; /* Branch to start of RPS program. */ - *pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase; - /* End of RPS program build */ + if (err) + return 4; + + return 0; } -/* TO COMPLETE, IF NECESSARY */ -static int s626_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + /* Stop RPS program in case it is currently running. */ + MC_DISABLE(P_MC1, MC1_ERPS1); - return -EINVAL; -} - -/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */ -/* { */ -/* register uint8_t i; */ -/* register int32_t *readaddr; */ + /* disable master interrupt */ + writel(0, devpriv->base_addr + P_IER); -/* DEBUG("as626_ai_rinsn: ai_rinsn enter\n"); */ + devpriv->ai_cmd_running = 0; -/* Trigger ADC scan loop start by setting RPS Signal 0. */ -/* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ + return 0; +} -/* Wait until ADC scan loop is finished (RPS Signal 0 reset). */ -/* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */ +/* This function doesn't require a particular form, this is just what + * happens to be used in some of the drivers. It should convert ns + * nanoseconds to a counter value suitable for programming the device. + * Also, it should adjust ns so that it cooresponds to the actual time + * that the device will use. */ +static int s626_ns_to_timer(int *nanosec, int round_mode) +{ + int divider, base; -/* Init ptr to DMA buffer that holds new ADC data. We skip the - * first uint16_t in the buffer because it contains junk data from - * the final ADC of the previous poll list scan. - */ -/* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */ + base = 500; /* 2MHz internal clock */ -/* Convert ADC data to 16-bit integer values and copy to application buffer. */ -/* for ( i = 0; i < devpriv->AdcItems; i++ ) { */ -/* *data = s626_ai_reg_to_uint( *readaddr++ ); */ -/* DEBUG("s626_ai_rinsn: data %d\n",*data); */ -/* data++; */ -/* } */ + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + divider = (*nanosec + base / 2) / base; + break; + case TRIG_ROUND_DOWN: + divider = (*nanosec) / base; + break; + case TRIG_ROUND_UP: + divider = (*nanosec + base - 1) / base; + break; + } -/* DEBUG("s626_ai_rinsn: ai_rinsn escape\n"); */ -/* return i; */ -/* } */ + *nanosec = base * divider; + return divider - 1; +} -static int s626_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { + + int i; uint16_t chan = CR_CHAN(insn->chanspec); - uint16_t range = CR_RANGE(insn->chanspec); - uint16_t AdcSpec = 0; - uint32_t GpioImage; - int n; + int16_t dacdata; - /* interrupt call test */ -/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */ - /* Writing a logical 1 into any of the RPS_PSR bits causes the - * corresponding interrupt to be generated if enabled - */ - - DEBUG("s626_ai_insn_read: entering\n"); - - /* Convert application's ADC specification into form - * appropriate for register programming. - */ - if (range == 0) - AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V); - else - AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V); + for (i = 0; i < insn->n; i++) { + dacdata = (int16_t) data[i]; + devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[i]; + dacdata -= (0x1fff); - /* Switch ADC analog gain. */ - DEBIwrite(dev, LP_GSEL, AdcSpec); /* Set gain. */ + SetDAC(dev, chan, dacdata); + } - /* Select ADC analog input channel. */ - DEBIwrite(dev, LP_ISEL, AdcSpec); /* Select channel. */ + return i; +} - for (n = 0; n < insn->n; n++) { +static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int i; - /* Delay 10 microseconds for analog input settling. */ - udelay(10); + for (i = 0; i < insn->n; i++) + data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; - /* Start ADC by pulsing GPIO1 low. */ - GpioImage = RR7146(P_GPIO); - /* Assert ADC Start command */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* and stretch it out. */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* Negate ADC Start command. */ - WR7146(P_GPIO, GpioImage | GPIO1_HI); + return i; +} - /* Wait for ADC to complete (GPIO2 is asserted high when */ - /* ADC not busy) and for data from previous conversion to */ - /* shift into FB BUFFER 1 register. */ +/* *************** DIGITAL I/O FUNCTIONS *************** + * All DIO functions address a group of DIO channels by means of + * "group" argument. group may be 0, 1 or 2, which correspond to DIO + * ports A, B and C, respectively. + */ - /* Wait for ADC done. */ - while (!(RR7146(P_PSR) & PSR_GPIO2)) - ; +static void s626_dio_init(struct comedi_device *dev) +{ + uint16_t group; + struct comedi_subdevice *s; - /* Fetch ADC data. */ - if (n != 0) - data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); + /* Prepare to treat writes to WRCapSel as capture disables. */ + DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - /* Allow the ADC to stabilize for 4 microseconds before - * starting the next (final) conversion. This delay is - * necessary to allow sufficient time between last - * conversion finished and the start of the next - * conversion. Without this delay, the last conversion's - * data value is sometimes set to the previous - * conversion's data value. - */ - udelay(4); + /* For each group of sixteen channels ... */ + for (group = 0; group < S626_DIO_BANKS; group++) { + s = dev->subdevices + 2 + group; + DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */ + DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */ + /* captures. */ + DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */ + /* default edge */ + /* polarity. */ + DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */ + /* to inactive state. */ } + DEBUG("s626_dio_init: DIO initialized\n"); +} - /* Start a dummy conversion to cause the data from the - * previous conversion to be shifted in. */ - GpioImage = RR7146(P_GPIO); - - /* Assert ADC Start command */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* and stretch it out. */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* Negate ADC Start command. */ - WR7146(P_GPIO, GpioImage | GPIO1_HI); - - /* Wait for the data to arrive in FB BUFFER 1 register. */ +/* DIO devices are slightly special. Although it is possible to + * implement the insn_read/insn_write interface, it is much more + * useful to applications if you implement the insn_bits interface. + * This allows packed reading/writing of the DIO channels. The comedi + * core can convert between insn_bits and insn_read/write */ - /* Wait for ADC done. */ - while (!(RR7146(P_PSR) & PSR_GPIO2)) - ; +static int s626_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + /* + * The insn data consists of a mask in data[0] and the new data in + * data[1]. The mask defines which bits we are concerning about. + * The new data must be anded with the mask. Each channel + * corresponds to a bit. + */ + if (data[0]) { + /* Check if requested ports are configured for output */ + if ((s->io_bits & data[0]) != data[0]) + return -EIO; - /* Fetch ADC data from audio interface's input shift register. */ + s->state &= ~data[0]; + s->state |= data[0] & data[1]; - /* Fetch ADC data. */ - if (n != 0) - data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); + /* Write out the new digital output lines */ - DEBUG("s626_ai_insn_read: samples %d, data %d\n", n, data[n - 1]); + DEBIwrite(dev, diopriv->WRDOut, s->state); + } + data[1] = DEBIread(dev, diopriv->RDDIn); - return n; + return insn->n; } -static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd) +static int s626_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { - int n; - - for (n = 0; n < cmd->chanlist_len; n++) { - if (CR_RANGE((cmd->chanlist)[n]) == 0) - ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V); - else - ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V); + switch (data[0]) { + case INSN_CONFIG_DIO_QUERY: + data[1] = + (s-> + io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : + COMEDI_INPUT; + return insn->n; + break; + case COMEDI_INPUT: + s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); + break; + case COMEDI_OUTPUT: + s->io_bits |= 1 << CR_CHAN(insn->chanspec); + break; + default: + return -EINVAL; + break; } - if (n != 0) - ppl[n - 1] |= EOPL; + DEBIwrite(dev, diopriv->WRDOut, s->io_bits); - return n; + return 1; } -static int s626_ai_inttrig(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int trignum) +static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) { - if (trignum != 0) - return -EINVAL; + unsigned int group; + unsigned int bitmask; + unsigned int status; - DEBUG("s626_ai_inttrig: trigger adc start..."); + /* select dio bank */ + group = chan / 16; + bitmask = 1 << (chan - (16 * group)); + DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n", + chan - (16 * group), group); - /* Start executing the RPS program. */ - MC_ENABLE(P_MC1, MC1_ERPS1); + /* set channel to capture positive edge */ + status = DEBIread(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->RDEdgSel); + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WREdgSel, + bitmask | status); - s->async->inttrig = NULL; + /* enable interrupt on selected channel */ + status = DEBIread(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->RDIntSel); + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRIntSel, + bitmask | status); - DEBUG(" done\n"); + /* enable edge capture write command */ + DEBIwrite(dev, LP_MISC1, MISC1_EDCAP); - return 1; + /* enable edge capture on selected channel */ + status = DEBIread(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->RDCapSel); + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRCapSel, + bitmask | status); + + return 0; } -/* TO COMPLETE */ -static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, + unsigned int mask) { + DEBUG + ("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", + mask, group); - uint8_t ppl[16]; - struct comedi_cmd *cmd = &s->async->cmd; - struct enc_private *k; - int tick; + /* disable edge capture write command */ + DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - DEBUG("s626_ai_cmd: entering command function\n"); + /* enable edge capture on selected channel */ + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRCapSel, mask); - if (devpriv->ai_cmd_running) { - printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n", - dev->minor); - return -EBUSY; - } - /* disable interrupt */ - writel(0, devpriv->base_addr + P_IER); + return 0; +} - /* clear interrupt request */ - writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR); +static int s626_dio_clear_irq(struct comedi_device *dev) +{ + unsigned int group; - /* clear any pending interrupt */ - s626_dio_clear_irq(dev); - /* s626_enc_clear_irq(dev); */ + /* disable edge capture write command */ + DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - /* reset ai_cmd_running flag */ - devpriv->ai_cmd_running = 0; - - /* test if cmd is valid */ - if (cmd == NULL) { - DEBUG("s626_ai_cmd: NULL command\n"); - return -EINVAL; - } else { - DEBUG("s626_ai_cmd: command received!!!\n"); - } - - if (dev->irq == 0) { - comedi_error(dev, - "s626_ai_cmd: cannot run command without an irq"); - return -EIO; + for (group = 0; group < S626_DIO_BANKS; group++) { + /* clear pending events and interrupt */ + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRCapSel, + 0xffff); } - s626_ai_load_polllist(ppl, cmd); - devpriv->ai_cmd_running = 1; - devpriv->ai_convert_count = 0; - - switch (cmd->scan_begin_src) { - case TRIG_FOLLOW: - break; - case TRIG_TIMER: - /* set a conter to generate adc trigger at scan_begin_arg interval */ - k = &encpriv[5]; - tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg, - cmd->flags & TRIG_ROUND_MASK); - - /* load timer value and enable interrupt */ - s626_timer_load(dev, k, tick); - k->SetEnable(dev, k, CLKENAB_ALWAYS); - - DEBUG("s626_ai_cmd: scan trigger timer is set with value %d\n", - tick); + return 0; +} - break; - case TRIG_EXT: - /* set the digital line and interrupt for scan trigger */ - if (cmd->start_src != TRIG_EXT) - s626_dio_set_irq(dev, cmd->scan_begin_arg); +/* Now this function initializes the value of the counter (data[0]) + and set the subdevice. To complete with trigger and interrupt + configuration */ +static int s626_enc_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ + /* index. */ + (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ + (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is Counter. */ + (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ + /* ( CNTDIR_UP << BF_CLKPOL ) | // Count direction is Down. */ + (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ + (CLKENAB_INDEX << BF_CLKENAB); + /* uint16_t DisableIntSrc=TRUE; */ + /* uint32_t Preloadvalue; //Counter initial value */ + uint16_t valueSrclatch = LATCHSRC_AB_READ; + uint16_t enab = CLKENAB_ALWAYS; + struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; - DEBUG("s626_ai_cmd: External scan trigger is set!!!\n"); + DEBUG("s626_enc_insn_config: encoder config\n"); - break; - } + /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */ - switch (cmd->convert_src) { - case TRIG_NOW: - break; - case TRIG_TIMER: - /* set a conter to generate adc trigger at convert_arg interval */ - k = &encpriv[4]; - tick = s626_ns_to_timer((int *)&cmd->convert_arg, - cmd->flags & TRIG_ROUND_MASK); + k->SetMode(dev, k, Setup, TRUE); + Preload(dev, k, *(insn->data)); + k->PulseIndex(dev, k); + SetLatchSource(dev, k, valueSrclatch); + k->SetEnable(dev, k, (uint16_t) (enab != 0)); - /* load timer value and enable interrupt */ - s626_timer_load(dev, k, tick); - k->SetEnable(dev, k, CLKENAB_INDEX); + return insn->n; +} - DEBUG - ("s626_ai_cmd: convert trigger timer is set with value %d\n", - tick); - break; - case TRIG_EXT: - /* set the digital line and interrupt for convert trigger */ - if (cmd->scan_begin_src != TRIG_EXT - && cmd->start_src == TRIG_EXT) - s626_dio_set_irq(dev, cmd->convert_arg); +static int s626_enc_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ - DEBUG("s626_ai_cmd: External convert trigger is set!!!\n"); + int n; + struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; - break; - } + DEBUG("s626_enc_insn_read: encoder read channel %d\n", + CR_CHAN(insn->chanspec)); - switch (cmd->stop_src) { - case TRIG_COUNT: - /* data arrives as one packet */ - devpriv->ai_sample_count = cmd->stop_arg; - devpriv->ai_continous = 0; - break; - case TRIG_NONE: - /* continous acquisition */ - devpriv->ai_continous = 1; - devpriv->ai_sample_count = 0; - break; - } + for (n = 0; n < insn->n; n++) + data[n] = ReadLatch(dev, k); - ResetADC(dev, ppl); + DEBUG("s626_enc_insn_read: encoder sample %d\n", data[n]); - switch (cmd->start_src) { - case TRIG_NOW: - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ + return n; +} - /* Start executing the RPS program. */ - MC_ENABLE(P_MC1, MC1_ERPS1); +static int s626_enc_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ - DEBUG("s626_ai_cmd: ADC triggered\n"); - s->async->inttrig = NULL; - break; - case TRIG_EXT: - /* configure DIO channel for acquisition trigger */ - s626_dio_set_irq(dev, cmd->start_arg); + struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; - DEBUG("s626_ai_cmd: External start trigger is set!!!\n"); + DEBUG("s626_enc_insn_write: encoder write channel %d\n", + CR_CHAN(insn->chanspec)); - s->async->inttrig = NULL; - break; - case TRIG_INT: - s->async->inttrig = s626_ai_inttrig; - break; - } + /* Set the preload register */ + Preload(dev, k, data[0]); - /* enable interrupt */ - writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); + /* Software index pulse forces the preload register to load */ + /* into the counter */ + k->SetLoadTrig(dev, k, 0); + k->PulseIndex(dev, k); + k->SetLoadTrig(dev, k, 2); - DEBUG("s626_ai_cmd: command function terminated\n"); + DEBUG("s626_enc_insn_write: End encoder write\n"); - return 0; + return 1; } -static int s626_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) +static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, + int tick) { - int err = 0; - int tmp; + uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ + /* index. */ + (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ + (CLKSRC_TIMER << BF_CLKSRC) | /* Operating mode is Timer. */ + (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ + (CNTDIR_DOWN << BF_CLKPOL) | /* Count direction is Down. */ + (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ + (CLKENAB_INDEX << BF_CLKENAB); + uint16_t valueSrclatch = LATCHSRC_A_INDXA; + /* uint16_t enab=CLKENAB_ALWAYS; */ - /* cmdtest tests a particular command to see if it is valid. Using - * the cmdtest ioctl, a user can create a valid cmd and then have it - * executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4 or 0, depending on which tests the - * command passes. */ + k->SetMode(dev, k, Setup, FALSE); - /* step 1: make sure trigger sources are trivially valid */ + /* Set the preload register */ + Preload(dev, k, tick); - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; + /* Software index pulse forces the preload register to load */ + /* into the counter */ + k->SetLoadTrig(dev, k, 0); + k->PulseIndex(dev, k); - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + /* set reload on counter overflow */ + k->SetLoadTrig(dev, k, 1); - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; + /* set interrupt on overflow */ + k->SetIntSrc(dev, k, INTSRC_OVER); - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; + SetLatchSource(dev, k, valueSrclatch); + /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */ +} - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; +/* *********** DAC FUNCTIONS *********** */ - if (err) - return 1; +/* Slot 0 base settings. */ +#define VECT0 (XSD2 | RSD3 | SIB_A2) +/* Slot 0 always shifts in 0xFF and store it to FB_BUFFER2. */ - /* step 2: make sure trigger sources are unique and mutually - compatible */ +/* TrimDac LogicalChan-to-PhysicalChan mapping table. */ +static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 }; - /* note that mutual compatibility is not an issue here */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT - && cmd->scan_begin_src != TRIG_FOLLOW) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; +/* TrimDac LogicalChan-to-EepromAdrs mapping table. */ +static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 }; - if (err) - return 2; +static void LoadTrimDACs(struct comedi_device *dev) +{ + register uint8_t i; - /* step 3: make sure arguments are trivially compatible */ + /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */ + for (i = 0; i < ARRAY_SIZE(trimchan); i++) + WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i])); +} - if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - - if (cmd->start_src == TRIG_EXT && cmd->start_arg > 39) { - cmd->start_arg = 39; - err++; - } - - if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) { - cmd->scan_begin_arg = 39; - err++; - } - - if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) { - cmd->convert_arg = 39; - err++; - } -#define MAX_SPEED 200000 /* in nanoseconds */ -#define MIN_SPEED 2000000000 /* in nanoseconds */ - - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } - } else { - /* external trigger */ - /* should be level/edge, hi/lo specification here */ - /* should specify multiple external triggers */ -/* if(cmd->scan_begin_arg>9){ */ -/* cmd->scan_begin_arg=9; */ -/* err++; */ -/* } */ - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } - } else { - /* external trigger */ - /* see above */ -/* if(cmd->convert_arg>9){ */ -/* cmd->convert_arg=9; */ -/* err++; */ -/* } */ - } +static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, + uint8_t DacData) +{ + uint32_t chan; - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + /* Save the new setpoint in case the application needs to read it back later. */ + devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData; - if (err) - return 3; + /* Map logical channel number to physical channel number. */ + chan = (uint32_t) trimchan[LogicalChan]; - /* step 4: fix up any arguments */ + /* Set up TSL2 records for TrimDac write operation. All slots shift + * 0xFF in from pulled-up SD3 so that the end of the slot sequence + * can be detected. + */ - if (cmd->scan_begin_src == TRIG_TIMER) { - tmp = cmd->scan_begin_arg; - s626_ns_to_timer((int *)&cmd->scan_begin_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->scan_begin_arg) - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - tmp = cmd->convert_arg; - s626_ns_to_timer((int *)&cmd->convert_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->convert_arg) - err++; - if (cmd->scan_begin_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->scan_end_arg) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->scan_end_arg; - err++; - } - } + SETVECT(2, XSD2 | XFIFO_1 | WS3); + /* Slot 2: Send high uint8_t to target TrimDac. */ + SETVECT(3, XSD2 | XFIFO_0 | WS3); + /* Slot 3: Send low uint8_t to target TrimDac. */ + SETVECT(4, XSD2 | XFIFO_3 | WS1); + /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */ + SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); + /* Slot 5: Send NOP low uint8_t to DAC0. */ - if (err) - return 4; + /* Construct and transmit target DAC's serial packet: + * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the + * DAC channel's address, and D<7:0> is the DAC setpoint. Append a + * WORD value (that writes a channel 0 NOP command to a non-existent + * main DAC channel) that serves to keep the clock running after the + * packet has been sent to the target DAC. + */ - return 0; + /* Address the DAC channel within the trimdac device. */ + SendDAC(dev, ((uint32_t) chan << 8) + | (uint32_t) DacData); /* Include DAC setpoint data. */ } -static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - /* Stop RPS program in case it is currently running. */ - MC_DISABLE(P_MC1, MC1_ERPS1); - - /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); +/* ************** EEPROM ACCESS FUNCTIONS ************** */ +/* Read uint8_t from EEPROM. */ - devpriv->ai_cmd_running = 0; +static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) +{ + uint8_t rtnval; - return 0; -} + /* Send EEPROM target address. */ + if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) + /* Byte2 = I2C command: write to I2C EEPROM device. */ + | I2C_B1(I2C_ATTRSTOP, addr) + /* Byte1 = EEPROM internal target address. */ + | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ + /* Abort function and declare error if handshake failed. */ + DEBUG("I2Cread: error handshake I2Cread a\n"); + return 0; + } + /* Execute EEPROM read. */ + if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) -/* This function doesn't require a particular form, this is just what - * happens to be used in some of the drivers. It should convert ns - * nanoseconds to a counter value suitable for programming the device. - * Also, it should adjust ns so that it cooresponds to the actual time - * that the device will use. */ -static int s626_ns_to_timer(int *nanosec, int round_mode) -{ - int divider, base; + /* Byte2 = I2C */ + /* command: read */ + /* from I2C EEPROM */ + /* device. */ + |I2C_B1(I2C_ATTRSTOP, 0) - base = 500; /* 2MHz internal clock */ + /* Byte1 receives */ + /* uint8_t from */ + /* EEPROM. */ + |I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ - switch (round_mode) { - case TRIG_ROUND_NEAREST: - default: - divider = (*nanosec + base / 2) / base; - break; - case TRIG_ROUND_DOWN: - divider = (*nanosec) / base; - break; - case TRIG_ROUND_UP: - divider = (*nanosec + base - 1) / base; - break; + /* Abort function and declare error if handshake failed. */ + DEBUG("I2Cread: error handshake I2Cread b\n"); + return 0; } - - *nanosec = base * divider; - return divider - 1; + /* Return copy of EEPROM value. */ + rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16); + return rtnval; } -static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) { + /* Write I2C command to I2C Transfer Control shadow register. */ + WR7146(P_I2CCTRL, val); - int i; - uint16_t chan = CR_CHAN(insn->chanspec); - int16_t dacdata; - - for (i = 0; i < insn->n; i++) { - dacdata = (int16_t) data[i]; - devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[i]; - dacdata -= (0x1fff); - - SetDAC(dev, chan, dacdata); - } + /* Upload I2C shadow registers into working registers and wait for */ + /* upload confirmation. */ - return i; -} + MC_ENABLE(P_MC2, MC2_UPLD_IIC); + while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) + ; -static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int i; + /* Wait until I2C bus transfer is finished or an error occurs. */ + while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) + ; - for (i = 0; i < insn->n; i++) - data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; + /* Return non-zero if I2C error occurred. */ + return RR7146(P_I2CCTRL) & I2C_ERR; - return i; } -/* *************** DIGITAL I/O FUNCTIONS *************** - * All DIO functions address a group of DIO channels by means of - * "group" argument. group may be 0, 1 or 2, which correspond to DIO - * ports A, B and C, respectively. - */ +/* Private helper function: Write setpoint to an application DAC channel. */ -static void s626_dio_init(struct comedi_device *dev) +static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) { - uint16_t group; - struct comedi_subdevice *s; + register uint16_t signmask; + register uint32_t WSImage; - /* Prepare to treat writes to WRCapSel as capture disables. */ - DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); + /* Adjust DAC data polarity and set up Polarity Control Register */ + /* image. */ + signmask = 1 << chan; + if (dacdata < 0) { + dacdata = -dacdata; + devpriv->Dacpol |= signmask; + } else + devpriv->Dacpol &= ~signmask; - /* For each group of sixteen channels ... */ - for (group = 0; group < S626_DIO_BANKS; group++) { - s = dev->subdevices + 2 + group; - DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */ - DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */ - /* captures. */ - DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */ - /* default edge */ - /* polarity. */ - DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */ - /* to inactive state. */ - } - DEBUG("s626_dio_init: DIO initialized\n"); -} - -/* DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The comedi - * core can convert between insn_bits and insn_read/write */ + /* Limit DAC setpoint value to valid range. */ + if ((uint16_t) dacdata > 0x1FFF) + dacdata = 0x1FFF; -static int s626_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - /* - * The insn data consists of a mask in data[0] and the new data in - * data[1]. The mask defines which bits we are concerning about. - * The new data must be anded with the mask. Each channel - * corresponds to a bit. + /* Set up TSL2 records (aka "vectors") for DAC update. Vectors V2 + * and V3 transmit the setpoint to the target DAC. V4 and V5 send + * data to a non-existent TrimDac channel just to keep the clock + * running after sending data to the target DAC. This is necessary + * to eliminate the clock glitch that would otherwise occur at the + * end of the target DAC's serial data stream. When the sequence + * restarts at V0 (after executing V5), the gate array automatically + * disables gating for the DAC clock and all DAC chip selects. */ - if (data[0]) { - /* Check if requested ports are configured for output */ - if ((s->io_bits & data[0]) != data[0]) - return -EIO; - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - - /* Write out the new digital output lines */ + WSImage = (chan & 2) ? WS1 : WS2; + /* Choose DAC chip select to be asserted. */ + SETVECT(2, XSD2 | XFIFO_1 | WSImage); + /* Slot 2: Transmit high data byte to target DAC. */ + SETVECT(3, XSD2 | XFIFO_0 | WSImage); + /* Slot 3: Transmit low data byte to target DAC. */ + SETVECT(4, XSD2 | XFIFO_3 | WS3); + /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */ + SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); + /* Slot 5: running after writing target DAC's low data byte. */ - DEBIwrite(dev, diopriv->WRDOut, s->state); - } - data[1] = DEBIread(dev, diopriv->RDDIn); + /* Construct and transmit target DAC's serial packet: + * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, + * and D<12:0> is the DAC setpoint. Append a WORD value (that writes + * to a non-existent TrimDac channel) that serves to keep the clock + * running after the packet has been sent to the target DAC. + */ + SendDAC(dev, 0x0F000000 + /* Continue clock after target DAC data (write to non-existent trimdac). */ + | 0x00004000 + /* Address the two main dual-DAC devices (TSL's chip select enables + * target device). */ + | ((uint32_t) (chan & 1) << 15) + /* Address the DAC channel within the device. */ + | (uint32_t) dacdata); /* Include DAC setpoint data. */ - return insn->n; } -static int s626_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ +/* Private helper function: Transmit serial data to DAC via Audio + * channel 2. Assumes: (1) TSL2 slot records initialized, and (2) + * Dacpol contains valid target image. + */ - switch (data[0]) { - case INSN_CONFIG_DIO_QUERY: - data[1] = - (s-> - io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : - COMEDI_INPUT; - return insn->n; - break; - case COMEDI_INPUT: - s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); - break; - case COMEDI_OUTPUT: - s->io_bits |= 1 << CR_CHAN(insn->chanspec); - break; - default: - return -EINVAL; - break; - } - DEBIwrite(dev, diopriv->WRDOut, s->io_bits); +static void SendDAC(struct comedi_device *dev, uint32_t val) +{ - return 1; -} + /* START THE SERIAL CLOCK RUNNING ------------- */ -static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) -{ - unsigned int group; - unsigned int bitmask; - unsigned int status; + /* Assert DAC polarity control and enable gating of DAC serial clock + * and audio bit stream signals. At this point in time we must be + * assured of being in time slot 0. If we are not in slot 0, the + * serial clock and audio stream signals will be disabled; this is + * because the following DEBIwrite statement (which enables signals + * to be passed through the gate array) would execute before the + * trailing edge of WS1/WS3 (which turns off the signals), thus + * causing the signals to be inactive during the DAC write. + */ + DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol); - /* select dio bank */ - group = chan / 16; - bitmask = 1 << (chan - (16 * group)); - DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n", - chan - (16 * group), group); + /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */ - /* set channel to capture positive edge */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDEdgSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WREdgSel, - bitmask | status); + /* Copy DAC setpoint value to DAC's output DMA buffer. */ - /* enable interrupt on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDIntSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRIntSel, - bitmask | status); + /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */ + *devpriv->pDacWBuf = val; - /* enable edge capture write command */ - DEBIwrite(dev, LP_MISC1, MISC1_EDCAP); + /* enab the output DMA transfer. This will cause the DMAC to copy + * the DAC's data value to A2's output FIFO. The DMA transfer will + * then immediately terminate because the protection address is + * reached upon transfer of the first DWORD value. + */ + MC_ENABLE(P_MC1, MC1_A2OUT); - /* enable edge capture on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDCapSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - bitmask | status); + /* While the DMA transfer is executing ... */ - return 0; -} + /* Reset Audio2 output FIFO's underflow flag (along with any other + * FIFO underflow/overflow flags). When set, this flag will + * indicate that we have emerged from slot 0. + */ + WR7146(P_ISR, ISR_AFOU); -static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, - unsigned int mask) -{ - DEBUG - ("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", - mask, group); + /* Wait for the DMA transfer to finish so that there will be data + * available in the FIFO when time slot 1 tries to transfer a DWORD + * from the FIFO to the output buffer register. We test for DMA + * Done by polling the DMAC enable flag; this flag is automatically + * cleared when the transfer has finished. + */ + while ((RR7146(P_MC1) & MC1_A2OUT) != 0) + ; - /* disable edge capture write command */ - DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); + /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */ - /* enable edge capture on selected channel */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, mask); + /* FIFO data is now available, so we enable execution of time slots + * 1 and higher by clearing the EOS flag in slot 0. Note that SD3 + * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list + * detection. + */ + SETVECT(0, XSD2 | RSD3 | SIB_A2); - return 0; -} + /* Wait for slot 1 to execute to ensure that the Packet will be + * transmitted. This is detected by polling the Audio2 output FIFO + * underflow flag, which will be set when slot 1 execution has + * finished transferring the DAC's data DWORD from the output FIFO + * to the output buffer register. + */ + while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) + ; -static int s626_dio_clear_irq(struct comedi_device *dev) -{ - unsigned int group; + /* Set up to trap execution at slot 0 when the TSL sequencer cycles + * back to slot 0 after executing the EOS in slot 5. Also, + * simultaneously shift out and in the 0x00 that is ALWAYS the value + * stored in the last byte to be shifted out of the FIFO's DWORD + * buffer register. + */ + SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS); - /* disable edge capture write command */ - DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); + /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */ - for (group = 0; group < S626_DIO_BANKS; group++) { - /* clear pending events and interrupt */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - 0xffff); + /* Wait for the TSL to finish executing all time slots before + * exiting this function. We must do this so that the next DAC + * write doesn't start, thereby enabling clock/chip select signals: + * + * 1. Before the TSL sequence cycles back to slot 0, which disables + * the clock/cs signal gating and traps slot // list execution. + * we have not yet finished slot 5 then the clock/cs signals are + * still gated and we have not finished transmitting the stream. + * + * 2. While slots 2-5 are executing due to a late slot 0 trap. In + * this case, the slot sequence is currently repeating, but with + * clock/cs signals disabled. We must wait for slot 0 to trap + * execution before setting up the next DAC setpoint DMA transfer + * and enabling the clock/cs signals. To detect the end of slot 5, + * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If + * the TSL has not yet finished executing slot 5 ... + */ + if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) { + /* The trap was set on time and we are still executing somewhere + * in slots 2-5, so we now wait for slot 0 to execute and trap + * TSL execution. This is detected when FB_BUFFER2 MSB changes + * from 0xFF to 0x00, which slot 0 causes to happen by shifting + * out/in on SD2 the 0x00 that is always referenced by slot 5. + */ + while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) + ; } + /* Either (1) we were too late setting the slot 0 trap; the TSL + * sequencer restarted slot 0 before we could set the EOS trap flag, + * or (2) we were not late and execution is now trapped at slot 0. + * In either case, we must now change slot 0 so that it will store + * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes. + * In order to do this, we reprogram slot 0 so that it will shift in + * SD3, which is driven only by a pull-up resistor. + */ + SETVECT(0, RSD3 | SIB_A2 | EOS); - return 0; + /* Wait for slot 0 to execute, at which time the TSL is setup for + * the next DAC write. This is detected when FB_BUFFER2 MSB changes + * from 0x00 to 0xFF. + */ + while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) + ; } -/* Now this function initializes the value of the counter (data[0]) - and set the subdevice. To complete with trigger and interrupt - configuration */ -static int s626_enc_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage) { - uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ - /* index. */ - (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ - (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is Counter. */ - (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ - /* ( CNTDIR_UP << BF_CLKPOL ) | // Count direction is Down. */ - (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ - (CLKENAB_INDEX << BF_CLKENAB); - /* uint16_t DisableIntSrc=TRUE; */ - /* uint32_t Preloadvalue; //Counter initial value */ - uint16_t valueSrclatch = LATCHSRC_AB_READ; - uint16_t enab = CLKENAB_ALWAYS; - struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; + DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); /* enab writes to */ + /* MISC2 register. */ + DEBIwrite(dev, LP_WRMISC2, NewImage); /* Write new image to MISC2. */ + DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); /* Disable writes to MISC2. */ +} - DEBUG("s626_enc_insn_config: encoder config\n"); +/* Initialize the DEBI interface for all transfers. */ - /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */ +static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) +{ + uint16_t retval; - k->SetMode(dev, k, Setup, TRUE); - Preload(dev, k, *(insn->data)); - k->PulseIndex(dev, k); - SetLatchSource(dev, k, valueSrclatch); - k->SetEnable(dev, k, (uint16_t) (enab != 0)); + /* Set up DEBI control register value in shadow RAM. */ + WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); - return insn->n; + /* Execute the DEBI transfer. */ + DEBItransfer(dev); + + /* Fetch target register value. */ + retval = (uint16_t) RR7146(P_DEBIAD); + + /* Return register value. */ + return retval; } -static int s626_enc_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +/* Execute a DEBI transfer. This must be called from within a */ +/* critical section. */ +static void DEBItransfer(struct comedi_device *dev) { + /* Initiate upload of shadow RAM to DEBI control register. */ + MC_ENABLE(P_MC2, MC2_UPLD_DEBI); - int n; - struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; + /* Wait for completion of upload from shadow RAM to DEBI control */ + /* register. */ + while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) + ; - DEBUG("s626_enc_insn_read: encoder read channel %d\n", - CR_CHAN(insn->chanspec)); + /* Wait until DEBI transfer is done. */ + while (RR7146(P_PSR) & PSR_DEBI_S) + ; +} - for (n = 0; n < insn->n; n++) - data[n] = ReadLatch(dev, k); +/* Write a value to a gate array register. */ +static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) +{ - DEBUG("s626_enc_insn_read: encoder sample %d\n", data[n]); + /* Set up DEBI control register value in shadow RAM. */ + WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); + WR7146(P_DEBIAD, wdata); - return n; + /* Execute the DEBI transfer. */ + DEBItransfer(dev); } -static int s626_enc_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +/* Replace the specified bits in a gate array register. Imports: mask + * specifies bits that are to be preserved, wdata is new value to be + * or'd with the masked original. + */ +static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, + uint16_t wdata) { - struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; + /* Copy target gate array register into P_DEBIAD register. */ + WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); + /* Set up DEBI control reg value in shadow RAM. */ + DEBItransfer(dev); /* Execute the DEBI Read transfer. */ - DEBUG("s626_enc_insn_write: encoder write channel %d\n", - CR_CHAN(insn->chanspec)); + /* Write back the modified image. */ + WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); + /* Set up DEBI control reg value in shadow RAM. */ - /* Set the preload register */ - Preload(dev, k, data[0]); + WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); + /* Modify the register image. */ + DEBItransfer(dev); /* Execute the DEBI Write transfer. */ +} - /* Software index pulse forces the preload register to load */ - /* into the counter */ - k->SetLoadTrig(dev, k, 0); - k->PulseIndex(dev, k); - k->SetLoadTrig(dev, k, 2); +static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, + size_t bsize) +{ + void *vbptr; + dma_addr_t vpptr; - DEBUG("s626_enc_insn_write: End encoder write\n"); + DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n"); + if (pdma == NULL) + return; + /* find the matching allocation from the board struct */ - return 1; + vbptr = pdma->LogicalBase; + vpptr = pdma->PhysicalBase; + if (vbptr) { + pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr); + pdma->LogicalBase = NULL; + pdma->PhysicalBase = 0; + + DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n", + vbptr, bsize, (uint32_t) vpptr); + } } -static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, - int tick) +/* ****** COUNTER FUNCTIONS ******* */ +/* All counter functions address a specific counter by means of the + * "Counter" argument, which is a logical counter number. The Counter + * argument may have any of the following legal values: 0=0A, 1=1A, + * 2=2A, 3=0B, 4=1B, 5=2B. + */ + +/* Forward declarations for functions that are common to both A and B counters: */ + +/* ****** PRIVATE COUNTER FUNCTIONS ****** */ + +/* Read a counter's output latch. */ + +static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) { - uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ - /* index. */ - (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ - (CLKSRC_TIMER << BF_CLKSRC) | /* Operating mode is Timer. */ - (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ - (CNTDIR_DOWN << BF_CLKPOL) | /* Count direction is Down. */ - (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ - (CLKENAB_INDEX << BF_CLKENAB); - uint16_t valueSrclatch = LATCHSRC_A_INDXA; - /* uint16_t enab=CLKENAB_ALWAYS; */ + register uint32_t value; + /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */ - k->SetMode(dev, k, Setup, FALSE); + /* Latch counts and fetch LSW of latched counts value. */ + value = (uint32_t) DEBIread(dev, k->MyLatchLsw); - /* Set the preload register */ - Preload(dev, k, tick); + /* Fetch MSW of latched counts and combine with LSW. */ + value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16); - /* Software index pulse forces the preload register to load */ - /* into the counter */ - k->SetLoadTrig(dev, k, 0); - k->PulseIndex(dev, k); + /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */ + + /* Return latched counts. */ + return value; +} - /* set reload on counter overflow */ - k->SetLoadTrig(dev, k, 1); +/* Reset a counter's index and overflow event capture flags. */ - /* set interrupt on overflow */ - k->SetIntSrc(dev, k, INTSRC_OVER); +static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k) +{ + DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), + CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); +} - SetLatchSource(dev, k, valueSrclatch); - /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */ +static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k) +{ + DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), + CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B); } -/* *********** DAC FUNCTIONS *********** */ +/* Return counter setup in a format (COUNTER_SETUP) that is consistent */ +/* for both A and B counters. */ -/* Slot 0 base settings. */ -#define VECT0 (XSD2 | RSD3 | SIB_A2) -/* Slot 0 always shifts in 0xFF and store it to FB_BUFFER2. */ +static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k) +{ + register uint16_t cra; + register uint16_t crb; + register uint16_t setup; -/* TrimDac LogicalChan-to-PhysicalChan mapping table. */ -static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 }; + /* Fetch CRA and CRB register images. */ + cra = DEBIread(dev, k->MyCRA); + crb = DEBIread(dev, k->MyCRB); -/* TrimDac LogicalChan-to-EepromAdrs mapping table. */ -static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 }; + /* Populate the standardized counter setup bit fields. Note: */ + /* IndexSrc is restricted to ENC_X or IndxPol. */ + setup = ((cra & STDMSK_LOADSRC) /* LoadSrc = LoadSrcA. */ + |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcA. */ + |((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC) /* IntSrc = IntSrcA. */ + |((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /* IndxSrc = IndxSrcA<1>. */ + |((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL) /* IndxPol = IndxPolA. */ + |((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB)); /* ClkEnab = ClkEnabA. */ -static void LoadTrimDACs(struct comedi_device *dev) -{ - register uint8_t i; + /* Adjust mode-dependent parameters. */ + if (cra & (2 << CRABIT_CLKSRC_A)) /* If Timer mode (ClkSrcA<1> == 1): */ + setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */ + |((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /* Set ClkPol to indicate count direction (ClkSrcA<0>). */ + |(MULT_X1 << STDBIT_CLKMULT)); /* ClkMult must be 1x in Timer mode. */ - /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */ - for (i = 0; i < ARRAY_SIZE(trimchan); i++) - WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i])); + else /* If Counter mode (ClkSrcA<1> == 0): */ + setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Counter mode. */ + |((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /* Pass through ClkPol. */ + |(((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ? /* Force ClkMult to 1x if not legal, else pass through. */ + (MULT_X1 << STDBIT_CLKMULT) : + ((cra >> (CRABIT_CLKMULT_A - + STDBIT_CLKMULT)) & STDMSK_CLKMULT))); + + /* Return adjusted counter setup. */ + return setup; } -static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, - uint8_t DacData) +static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k) { - uint32_t chan; + register uint16_t cra; + register uint16_t crb; + register uint16_t setup; - /* Save the new setpoint in case the application needs to read it back later. */ - devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData; + /* Fetch CRA and CRB register images. */ + cra = DEBIread(dev, k->MyCRA); + crb = DEBIread(dev, k->MyCRB); - /* Map logical channel number to physical channel number. */ - chan = (uint32_t) trimchan[LogicalChan]; + /* Populate the standardized counter setup bit fields. Note: */ + /* IndexSrc is restricted to ENC_X or IndxPol. */ + setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC) /* IntSrc = IntSrcB. */ + |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcB. */ + |((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC) /* LoadSrc = LoadSrcB. */ + |((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL) /* IndxPol = IndxPolB. */ + |((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB) /* ClkEnab = ClkEnabB. */ + |((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC)); /* IndxSrc = IndxSrcB<1>. */ - /* Set up TSL2 records for TrimDac write operation. All slots shift - * 0xFF in from pulled-up SD3 so that the end of the slot sequence - * can be detected. - */ + /* Adjust mode-dependent parameters. */ + if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B)) /* If Extender mode (ClkMultB == MULT_X0): */ + setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC) /* Indicate Extender mode. */ + |(MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */ + |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */ - SETVECT(2, XSD2 | XFIFO_1 | WS3); - /* Slot 2: Send high uint8_t to target TrimDac. */ - SETVECT(3, XSD2 | XFIFO_0 | WS3); - /* Slot 3: Send low uint8_t to target TrimDac. */ - SETVECT(4, XSD2 | XFIFO_3 | WS1); - /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */ - SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); - /* Slot 5: Send NOP low uint8_t to DAC0. */ + else if (cra & (2 << CRABIT_CLKSRC_B)) /* If Timer mode (ClkSrcB<1> == 1): */ + setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */ + |(MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */ + |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */ - /* Construct and transmit target DAC's serial packet: - * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the - * DAC channel's address, and D<7:0> is the DAC setpoint. Append a - * WORD value (that writes a channel 0 NOP command to a non-existent - * main DAC channel) that serves to keep the clock running after the - * packet has been sent to the target DAC. - */ + else /* If Counter mode (ClkSrcB<1> == 0): */ + setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Timer mode. */ + |((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT) /* Clock multiplier is passed through. */ + |((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL)); /* Clock polarity is passed through. */ - /* Address the DAC channel within the trimdac device. */ - SendDAC(dev, ((uint32_t) chan << 8) - | (uint32_t) DacData); /* Include DAC setpoint data. */ + /* Return adjusted counter setup. */ + return setup; } -/* ************** EEPROM ACCESS FUNCTIONS ************** */ -/* Read uint8_t from EEPROM. */ +/* + * Set the operating mode for the specified counter. The setup + * parameter is treated as a COUNTER_SETUP data type. The following + * parameters are programmable (all other parms are ignored): ClkMult, + * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc. + */ -static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) +static void SetMode_A(struct comedi_device *dev, struct enc_private *k, + uint16_t Setup, uint16_t DisableIntSrc) { - uint8_t rtnval; - - /* Send EEPROM target address. */ - if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) - /* Byte2 = I2C command: write to I2C EEPROM device. */ - | I2C_B1(I2C_ATTRSTOP, addr) - /* Byte1 = EEPROM internal target address. */ - | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ - /* Abort function and declare error if handshake failed. */ - DEBUG("I2Cread: error handshake I2Cread a\n"); - return 0; - } - /* Execute EEPROM read. */ - if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) + register uint16_t cra; + register uint16_t crb; + register uint16_t setup = Setup; /* Cache the Standard Setup. */ - /* Byte2 = I2C */ - /* command: read */ - /* from I2C EEPROM */ - /* device. */ - |I2C_B1(I2C_ATTRSTOP, 0) + /* Initialize CRA and CRB images. */ + cra = ((setup & CRAMSK_LOADSRC_A) /* Preload trigger is passed through. */ + |((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1)))); /* IndexSrc is restricted to ENC_X or IndxPol. */ - /* Byte1 receives */ - /* uint8_t from */ - /* EEPROM. */ - |I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ + crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A /* Reset any pending CounterA event captures. */ + | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB))); /* Clock enable is passed through. */ - /* Abort function and declare error if handshake failed. */ - DEBUG("I2Cread: error handshake I2Cread b\n"); - return 0; - } - /* Return copy of EEPROM value. */ - rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16); - return rtnval; -} + /* Force IntSrc to Disabled if DisableIntSrc is asserted. */ + if (!DisableIntSrc) + cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC - + CRABIT_INTSRC_A)); -static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) -{ - /* Write I2C command to I2C Transfer Control shadow register. */ - WR7146(P_I2CCTRL, val); + /* Populate all mode-dependent attributes of CRA & CRB images. */ + switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) { + case CLKSRC_EXTENDER: /* Extender Mode: Force to Timer mode */ + /* (Extender valid only for B counters). */ - /* Upload I2C shadow registers into working registers and wait for */ - /* upload confirmation. */ + case CLKSRC_TIMER: /* Timer Mode: */ + cra |= ((2 << CRABIT_CLKSRC_A) /* ClkSrcA<1> selects system clock */ + |((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /* with count direction (ClkSrcA<0>) obtained from ClkPol. */ + |(1 << CRABIT_CLKPOL_A) /* ClkPolA behaves as always-on clock enable. */ + |(MULT_X1 << CRABIT_CLKMULT_A)); /* ClkMult must be 1x. */ + break; - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) - ; + default: /* Counter Mode: */ + cra |= (CLKSRC_COUNTER /* Select ENC_C and ENC_D as clock/direction inputs. */ + | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) /* Clock polarity is passed through. */ + |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force multiplier to x1 if not legal, otherwise pass through. */ + (MULT_X1 << CRABIT_CLKMULT_A) : + ((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A - + STDBIT_CLKMULT)))); + } - /* Wait until I2C bus transfer is finished or an error occurs. */ - while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) - ; + /* Force positive index polarity if IndxSrc is software-driven only, */ + /* otherwise pass it through. */ + if (~setup & STDMSK_INDXSRC) + cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A - + STDBIT_INDXPOL)); - /* Return non-zero if I2C error occurred. */ - return RR7146(P_I2CCTRL) & I2C_ERR; + /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */ + /* enable mask to indicate the counter interrupt is disabled. */ + if (DisableIntSrc) + devpriv->CounterIntEnabs &= ~k->MyEventBits[3]; + /* While retaining CounterB and LatchSrc configurations, program the */ + /* new counter operating mode. */ + DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra); + DEBIreplace(dev, k->MyCRB, + (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb); } -/* Private helper function: Write setpoint to an application DAC channel. */ - -static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) +static void SetMode_B(struct comedi_device *dev, struct enc_private *k, + uint16_t Setup, uint16_t DisableIntSrc) { - register uint16_t signmask; - register uint32_t WSImage; + register uint16_t cra; + register uint16_t crb; + register uint16_t setup = Setup; /* Cache the Standard Setup. */ - /* Adjust DAC data polarity and set up Polarity Control Register */ - /* image. */ - signmask = 1 << chan; - if (dacdata < 0) { - dacdata = -dacdata; - devpriv->Dacpol |= signmask; - } else - devpriv->Dacpol &= ~signmask; + /* Initialize CRA and CRB images. */ + cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)); /* IndexSrc field is restricted to ENC_X or IndxPol. */ + + crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B /* Reset event captures and disable interrupts. */ + | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) /* Clock enable is passed through. */ + |((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B))); /* Preload trigger source is passed through. */ + + /* Force IntSrc to Disabled if DisableIntSrc is asserted. */ + if (!DisableIntSrc) + crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC - + CRBBIT_INTSRC_B)); + + /* Populate all mode-dependent attributes of CRA & CRB images. */ + switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) { + case CLKSRC_TIMER: /* Timer Mode: */ + cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB<1> selects system clock */ + |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction (ClkSrcB<0>) obtained from ClkPol. */ + crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB behaves as always-on clock enable. */ + |(MULT_X1 << CRBBIT_CLKMULT_B)); /* ClkMultB must be 1x. */ + break; - /* Limit DAC setpoint value to valid range. */ - if ((uint16_t) dacdata > 0x1FFF) - dacdata = 0x1FFF; + case CLKSRC_EXTENDER: /* Extender Mode: */ + cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB source is OverflowA (same as "timer") */ + |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction obtained from ClkPol. */ + crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB controls IndexB -- always set to active. */ + |(MULT_X0 << CRBBIT_CLKMULT_B)); /* ClkMultB selects OverflowA as the clock source. */ + break; - /* Set up TSL2 records (aka "vectors") for DAC update. Vectors V2 - * and V3 transmit the setpoint to the target DAC. V4 and V5 send - * data to a non-existent TrimDac channel just to keep the clock - * running after sending data to the target DAC. This is necessary - * to eliminate the clock glitch that would otherwise occur at the - * end of the target DAC's serial data stream. When the sequence - * restarts at V0 (after executing V5), the gate array automatically - * disables gating for the DAC clock and all DAC chip selects. - */ + default: /* Counter Mode: */ + cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B); /* Select ENC_C and ENC_D as clock/direction inputs. */ + crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) /* ClkPol is passed through. */ + |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force ClkMult to x1 if not legal, otherwise pass through. */ + (MULT_X1 << CRBBIT_CLKMULT_B) : + ((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B - + STDBIT_CLKMULT)))); + } - WSImage = (chan & 2) ? WS1 : WS2; - /* Choose DAC chip select to be asserted. */ - SETVECT(2, XSD2 | XFIFO_1 | WSImage); - /* Slot 2: Transmit high data byte to target DAC. */ - SETVECT(3, XSD2 | XFIFO_0 | WSImage); - /* Slot 3: Transmit low data byte to target DAC. */ - SETVECT(4, XSD2 | XFIFO_3 | WS3); - /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */ - SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); - /* Slot 5: running after writing target DAC's low data byte. */ + /* Force positive index polarity if IndxSrc is software-driven only, */ + /* otherwise pass it through. */ + if (~setup & STDMSK_INDXSRC) + crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL - + CRBBIT_INDXPOL_B)); - /* Construct and transmit target DAC's serial packet: - * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, - * and D<12:0> is the DAC setpoint. Append a WORD value (that writes - * to a non-existent TrimDac channel) that serves to keep the clock - * running after the packet has been sent to the target DAC. - */ - SendDAC(dev, 0x0F000000 - /* Continue clock after target DAC data (write to non-existent trimdac). */ - | 0x00004000 - /* Address the two main dual-DAC devices (TSL's chip select enables - * target device). */ - | ((uint32_t) (chan & 1) << 15) - /* Address the DAC channel within the device. */ - | (uint32_t) dacdata); /* Include DAC setpoint data. */ + /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */ + /* enable mask to indicate the counter interrupt is disabled. */ + if (DisableIntSrc) + devpriv->CounterIntEnabs &= ~k->MyEventBits[3]; + /* While retaining CounterA and LatchSrc configurations, program the */ + /* new counter operating mode. */ + DEBIreplace(dev, k->MyCRA, + (uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra); + DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb); } -/* Private helper function: Transmit serial data to DAC via Audio - * channel 2. Assumes: (1) TSL2 slot records initialized, and (2) - * Dacpol contains valid target image. - */ +/* Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index. */ -static void SendDAC(struct comedi_device *dev, uint32_t val) +static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, + uint16_t enab) { + DEBUG("SetEnable_A: SetEnable_A enter 3541\n"); + DEBIreplace(dev, k->MyCRB, + (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), + (uint16_t) (enab << CRBBIT_CLKENAB_A)); +} - /* START THE SERIAL CLOCK RUNNING ------------- */ - - /* Assert DAC polarity control and enable gating of DAC serial clock - * and audio bit stream signals. At this point in time we must be - * assured of being in time slot 0. If we are not in slot 0, the - * serial clock and audio stream signals will be disabled; this is - * because the following DEBIwrite statement (which enables signals - * to be passed through the gate array) would execute before the - * trailing edge of WS1/WS3 (which turns off the signals), thus - * causing the signals to be inactive during the DAC write. - */ - DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol); +static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, + uint16_t enab) +{ + DEBIreplace(dev, k->MyCRB, + (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)), + (uint16_t) (enab << CRBBIT_CLKENAB_B)); +} - /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */ +static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k) +{ + return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1; +} - /* Copy DAC setpoint value to DAC's output DMA buffer. */ +static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k) +{ + return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1; +} - /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */ - *devpriv->pDacWBuf = val; +/* Return/set a counter pair's latch trigger source. 0: On read + * access, 1: A index latches A, 2: B index latches B, 3: A overflow + * latches B. + */ - /* enab the output DMA transfer. This will cause the DMAC to copy - * the DAC's data value to A2's output FIFO. The DMA transfer will - * then immediately terminate because the protection address is - * reached upon transfer of the first DWORD value. - */ - MC_ENABLE(P_MC1, MC1_A2OUT); +static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, + uint16_t value) +{ + DEBUG("SetLatchSource: SetLatchSource enter 3550\n"); + DEBIreplace(dev, k->MyCRB, + (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)), + (uint16_t) (value << CRBBIT_LATCHSRC)); - /* While the DMA transfer is executing ... */ + DEBUG("SetLatchSource: SetLatchSource exit\n"); +} - /* Reset Audio2 output FIFO's underflow flag (along with any other - * FIFO underflow/overflow flags). When set, this flag will - * indicate that we have emerged from slot 0. - */ - WR7146(P_ISR, ISR_AFOU); +/* + * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ) + * { + * return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3; + * } + */ - /* Wait for the DMA transfer to finish so that there will be data - * available in the FIFO when time slot 1 tries to transfer a DWORD - * from the FIFO to the output buffer register. We test for DMA - * Done by polling the DMAC enable flag; this flag is automatically - * cleared when the transfer has finished. - */ - while ((RR7146(P_MC1) & MC1_A2OUT) != 0) - ; +/* + * Return/set the event that will trigger transfer of the preload + * register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow, + * 2=OverflowA (B counters only), 3=disabled. + */ - /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */ +static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, + uint16_t Trig) +{ + DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A), + (uint16_t) (Trig << CRABIT_LOADSRC_A)); +} - /* FIFO data is now available, so we enable execution of time slots - * 1 and higher by clearing the EOS flag in slot 0. Note that SD3 - * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list - * detection. - */ - SETVECT(0, XSD2 | RSD3 | SIB_A2); +static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, + uint16_t Trig) +{ + DEBIreplace(dev, k->MyCRB, + (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)), + (uint16_t) (Trig << CRBBIT_LOADSRC_B)); +} - /* Wait for slot 1 to execute to ensure that the Packet will be - * transmitted. This is detected by polling the Audio2 output FIFO - * underflow flag, which will be set when slot 1 execution has - * finished transferring the DAC's data DWORD from the output FIFO - * to the output buffer register. - */ - while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) - ; +static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k) +{ + return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3; +} - /* Set up to trap execution at slot 0 when the TSL sequencer cycles - * back to slot 0 after executing the EOS in slot 5. Also, - * simultaneously shift out and in the 0x00 that is ALWAYS the value - * stored in the last byte to be shifted out of the FIFO's DWORD - * buffer register. - */ - SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS); +static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k) +{ + return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3; +} - /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */ +/* Return/set counter interrupt source and clear any captured + * index/overflow events. IntSource: 0=Disabled, 1=OverflowOnly, + * 2=IndexOnly, 3=IndexAndOverflow. + */ - /* Wait for the TSL to finish executing all time slots before - * exiting this function. We must do this so that the next DAC - * write doesn't start, thereby enabling clock/chip select signals: - * - * 1. Before the TSL sequence cycles back to slot 0, which disables - * the clock/cs signal gating and traps slot // list execution. - * we have not yet finished slot 5 then the clock/cs signals are - * still gated and we have not finished transmitting the stream. - * - * 2. While slots 2-5 are executing due to a late slot 0 trap. In - * this case, the slot sequence is currently repeating, but with - * clock/cs signals disabled. We must wait for slot 0 to trap - * execution before setting up the next DAC setpoint DMA transfer - * and enabling the clock/cs signals. To detect the end of slot 5, - * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If - * the TSL has not yet finished executing slot 5 ... - */ - if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) { - /* The trap was set on time and we are still executing somewhere - * in slots 2-5, so we now wait for slot 0 to execute and trap - * TSL execution. This is detected when FB_BUFFER2 MSB changes - * from 0xFF to 0x00, which slot 0 causes to happen by shifting - * out/in on SD2 the 0x00 that is always referenced by slot 5. - */ - while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) - ; - } - /* Either (1) we were too late setting the slot 0 trap; the TSL - * sequencer restarted slot 0 before we could set the EOS trap flag, - * or (2) we were not late and execution is now trapped at slot 0. - * In either case, we must now change slot 0 so that it will store - * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes. - * In order to do this, we reprogram slot 0 so that it will shift in - * SD3, which is driven only by a pull-up resistor. - */ - SETVECT(0, RSD3 | SIB_A2 | EOS); +static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, + uint16_t IntSource) +{ + /* Reset any pending counter overflow or index captures. */ + DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), + CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); - /* Wait for slot 0 to execute, at which time the TSL is setup for - * the next DAC write. This is detected when FB_BUFFER2 MSB changes - * from 0x00 to 0xFF. - */ - while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) - ; + /* Program counter interrupt source. */ + DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A, + (uint16_t) (IntSource << CRABIT_INTSRC_A)); + + /* Update MISC2 interrupt enable mask. */ + devpriv->CounterIntEnabs = + (devpriv->CounterIntEnabs & ~k-> + MyEventBits[3]) | k->MyEventBits[IntSource]; } -static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage) +static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k, + uint16_t IntSource) { - DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); /* enab writes to */ - /* MISC2 register. */ - DEBIwrite(dev, LP_WRMISC2, NewImage); /* Write new image to MISC2. */ - DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); /* Disable writes to MISC2. */ + uint16_t crb; + + /* Cache writeable CRB register image. */ + crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; + + /* Reset any pending counter overflow or index captures. */ + DEBIwrite(dev, k->MyCRB, + (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B)); + + /* Program counter interrupt source. */ + DEBIwrite(dev, k->MyCRB, + (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource << + CRBBIT_INTSRC_B))); + + /* Update MISC2 interrupt enable mask. */ + devpriv->CounterIntEnabs = + (devpriv->CounterIntEnabs & ~k-> + MyEventBits[3]) | k->MyEventBits[IntSource]; } -/* Initialize the DEBI interface for all transfers. */ +static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k) +{ + return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3; +} -static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) +static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k) { - uint16_t retval; + return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3; +} - /* Set up DEBI control register value in shadow RAM. */ - WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); +/* Return/set the clock multiplier. */ - /* Execute the DEBI transfer. */ - DEBItransfer(dev); +/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ +/* { */ +/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */ +/* } */ - /* Fetch target register value. */ - retval = (uint16_t) RR7146(P_DEBIAD); +/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) */ +/* { */ +/* return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */ +/* } */ - /* Return register value. */ - return retval; -} +/* Return/set the clock polarity. */ -/* Execute a DEBI transfer. This must be called from within a */ -/* critical section. */ -static void DEBItransfer(struct comedi_device *dev) -{ - /* Initiate upload of shadow RAM to DEBI control register. */ - MC_ENABLE(P_MC2, MC2_UPLD_DEBI); +/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */ +/* { */ +/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */ +/* } */ - /* Wait for completion of upload from shadow RAM to DEBI control */ - /* register. */ - while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) - ; +/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) */ +/* { */ +/* return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */ +/* } */ - /* Wait until DEBI transfer is done. */ - while (RR7146(P_PSR) & PSR_DEBI_S) - ; -} +/* Return/set the clock source. */ -/* Write a value to a gate array register. */ -static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) -{ +/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */ +/* { */ +/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */ +/* } */ - /* Set up DEBI control register value in shadow RAM. */ - WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); - WR7146(P_DEBIAD, wdata); +/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ) */ +/* { */ +/* return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */ +/* } */ - /* Execute the DEBI transfer. */ - DEBItransfer(dev); -} +/* Return/set the index polarity. */ -/* Replace the specified bits in a gate array register. Imports: mask - * specifies bits that are to be preserved, wdata is new value to be - * or'd with the masked original. - */ -static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, - uint16_t wdata) -{ +/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ +/* { */ +/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */ +/* } */ - /* Copy target gate array register into P_DEBIAD register. */ - WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); - /* Set up DEBI control reg value in shadow RAM. */ - DEBItransfer(dev); /* Execute the DEBI Read transfer. */ +/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k ) */ +/* { */ +/* return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */ +/* } */ - /* Write back the modified image. */ - WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); - /* Set up DEBI control reg value in shadow RAM. */ +/* Return/set the index source. */ - WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); - /* Modify the register image. */ - DEBItransfer(dev); /* Execute the DEBI Write transfer. */ -} +/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ +/* { */ +/* DEBUG("SetIndexSrc: set index src enter 3700\n"); */ +/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */ +/* } */ -static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, - size_t bsize) -{ - void *vbptr; - dma_addr_t vpptr; +/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k ) */ +/* { */ +/* return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */ +/* } */ - DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n"); - if (pdma == NULL) - return; - /* find the matching allocation from the board struct */ +/* Generate an index pulse. */ - vbptr = pdma->LogicalBase; - vpptr = pdma->PhysicalBase; - if (vbptr) { - pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr); - pdma->LogicalBase = NULL; - pdma->PhysicalBase = 0; +static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k) +{ + register uint16_t cra; - DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n", - vbptr, bsize, (uint32_t) vpptr); - } + DEBUG("PulseIndex_A: pulse index enter\n"); + + cra = DEBIread(dev, k->MyCRA); /* Pulse index. */ + DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A)); + DEBUG("PulseIndex_A: pulse index step1\n"); + DEBIwrite(dev, k->MyCRA, cra); } -/* ****** COUNTER FUNCTIONS ******* */ -/* All counter functions address a specific counter by means of the - * "Counter" argument, which is a logical counter number. The Counter - * argument may have any of the following legal values: 0=0A, 1=1A, - * 2=2A, 3=0B, 4=1B, 5=2B. - */ +static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k) +{ + register uint16_t crb; -/* Forward declarations for functions that are common to both A and B counters: */ + crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; /* Pulse index. */ + DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B)); + DEBIwrite(dev, k->MyCRB, crb); +} -/* ****** PRIVATE COUNTER FUNCTIONS ****** */ +/* Write value into counter preload register. */ -/* Read a counter's output latch. */ +static void Preload(struct comedi_device *dev, struct enc_private *k, + uint32_t value) +{ + DEBUG("Preload: preload enter\n"); + DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */ + DEBUG("Preload: preload step 1\n"); + DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2), + (uint16_t) (value >> 16)); +} -static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) +static void CountersInit(struct comedi_device *dev) { - register uint32_t value; - /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */ + int chan; + struct enc_private *k; + uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ + /* index. */ + (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ + (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is counter. */ + (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ + (CNTDIR_UP << BF_CLKPOL) | /* Count direction is up. */ + (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ + (CLKENAB_INDEX << BF_CLKENAB); /* Enabled by index */ - /* Latch counts and fetch LSW of latched counts value. */ - value = (uint32_t) DEBIread(dev, k->MyLatchLsw); + /* Disable all counter interrupts and clear any captured counter events. */ + for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) { + k = &encpriv[chan]; + k->SetMode(dev, k, Setup, TRUE); + k->SetIntSrc(dev, k, 0); + k->ResetCapFlags(dev, k); + k->SetEnable(dev, k, CLKENAB_ALWAYS); + } + DEBUG("CountersInit: counters initialized\n"); - /* Fetch MSW of latched counts and combine with LSW. */ - value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16); +} - /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */ +static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ +/* uint8_t PollList; */ +/* uint16_t AdcData; */ +/* uint16_t StartVal; */ +/* uint16_t index; */ +/* unsigned int data[16]; */ + int result; + int i; + int ret; + resource_size_t resourceStart; + dma_addr_t appdma; + struct comedi_subdevice *s; + struct pci_dev *pdev = NULL; - /* Return latched counts. */ - return value; -} + if (alloc_private(dev, sizeof(struct s626_private)) < 0) + return -ENOMEM; -/* Reset a counter's index and overflow event capture flags. */ + for (i = 0; i < ARRAY_SIZE(s626_boards) && !pdev; i++) { + do { + pdev = pci_get_subsys(s626_boards[i].vendor_id, + s626_boards[i].device_id, + s626_boards[i].subvendor_id, + s626_boards[i].subdevice_id, + pdev); + + if ((it->options[0] || it->options[1]) && pdev) { + /* matches requested bus/slot */ + if (pdev->bus->number == it->options[0] && + PCI_SLOT(pdev->devfn) == it->options[1]) + break; + } else + break; + } while (1); + } + devpriv->pdev = pdev; -static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k) -{ - DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), - CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); -} + if (pdev == NULL) { + printk(KERN_ERR "s626_attach: Board not present!!!\n"); + return -ENODEV; + } -static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k) -{ - DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), - CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B); -} + result = comedi_pci_enable(pdev, "s626"); + if (result < 0) { + printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n"); + return -ENODEV; + } + devpriv->got_regions = 1; -/* Return counter setup in a format (COUNTER_SETUP) that is consistent */ -/* for both A and B counters. */ + resourceStart = pci_resource_start(devpriv->pdev, 0); -static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k) -{ - register uint16_t cra; - register uint16_t crb; - register uint16_t setup; + devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE); + if (devpriv->base_addr == NULL) { + printk(KERN_ERR "s626_attach: IOREMAP failed\n"); + return -ENODEV; + } - /* Fetch CRA and CRB register images. */ - cra = DEBIread(dev, k->MyCRA); - crb = DEBIread(dev, k->MyCRB); + if (devpriv->base_addr) { + /* disable master interrupt */ + writel(0, devpriv->base_addr + P_IER); - /* Populate the standardized counter setup bit fields. Note: */ - /* IndexSrc is restricted to ENC_X or IndxPol. */ - setup = ((cra & STDMSK_LOADSRC) /* LoadSrc = LoadSrcA. */ - |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcA. */ - |((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC) /* IntSrc = IntSrcA. */ - |((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /* IndxSrc = IndxSrcA<1>. */ - |((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL) /* IndxPol = IndxPolA. */ - |((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB)); /* ClkEnab = ClkEnabA. */ + /* soft reset */ + writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); - /* Adjust mode-dependent parameters. */ - if (cra & (2 << CRABIT_CLKSRC_A)) /* If Timer mode (ClkSrcA<1> == 1): */ - setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */ - |((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /* Set ClkPol to indicate count direction (ClkSrcA<0>). */ - |(MULT_X1 << STDBIT_CLKMULT)); /* ClkMult must be 1x in Timer mode. */ + /* DMA FIXME DMA// */ + DEBUG("s626_attach: DMA ALLOCATION\n"); - else /* If Counter mode (ClkSrcA<1> == 0): */ - setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Counter mode. */ - |((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /* Pass through ClkPol. */ - |(((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ? /* Force ClkMult to 1x if not legal, else pass through. */ - (MULT_X1 << STDBIT_CLKMULT) : - ((cra >> (CRABIT_CLKMULT_A - - STDBIT_CLKMULT)) & STDMSK_CLKMULT))); + /* adc buffer allocation */ + devpriv->allocatedBuf = 0; - /* Return adjusted counter setup. */ - return setup; -} + devpriv->ANABuf.LogicalBase = + pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma); -static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k) -{ - register uint16_t cra; - register uint16_t crb; - register uint16_t setup; + if (devpriv->ANABuf.LogicalBase == NULL) { + printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); + return -ENOMEM; + } - /* Fetch CRA and CRB register images. */ - cra = DEBIread(dev, k->MyCRA); - crb = DEBIread(dev, k->MyCRB); + devpriv->ANABuf.PhysicalBase = appdma; - /* Populate the standardized counter setup bit fields. Note: */ - /* IndexSrc is restricted to ENC_X or IndxPol. */ - setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC) /* IntSrc = IntSrcB. */ - |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcB. */ - |((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC) /* LoadSrc = LoadSrcB. */ - |((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL) /* IndxPol = IndxPolB. */ - |((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB) /* ClkEnab = ClkEnabB. */ - |((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC)); /* IndxSrc = IndxSrcB<1>. */ + DEBUG + ("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n", + devpriv->ANABuf.LogicalBase, DMABUF_SIZE, + (uint32_t) devpriv->ANABuf.PhysicalBase); - /* Adjust mode-dependent parameters. */ - if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B)) /* If Extender mode (ClkMultB == MULT_X0): */ - setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC) /* Indicate Extender mode. */ - |(MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */ - |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */ + devpriv->allocatedBuf++; - else if (cra & (2 << CRABIT_CLKSRC_B)) /* If Timer mode (ClkSrcB<1> == 1): */ - setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */ - |(MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */ - |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */ + devpriv->RPSBuf.LogicalBase = + pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma); - else /* If Counter mode (ClkSrcB<1> == 0): */ - setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Timer mode. */ - |((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT) /* Clock multiplier is passed through. */ - |((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL)); /* Clock polarity is passed through. */ + if (devpriv->RPSBuf.LogicalBase == NULL) { + printk(KERN_ERR "s626_attach: DMA Memory mapping error\n"); + return -ENOMEM; + } - /* Return adjusted counter setup. */ - return setup; -} + devpriv->RPSBuf.PhysicalBase = appdma; -/* - * Set the operating mode for the specified counter. The setup - * parameter is treated as a COUNTER_SETUP data type. The following - * parameters are programmable (all other parms are ignored): ClkMult, - * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc. - */ + DEBUG + ("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n", + devpriv->RPSBuf.LogicalBase, DMABUF_SIZE, + (uint32_t) devpriv->RPSBuf.PhysicalBase); -static void SetMode_A(struct comedi_device *dev, struct enc_private *k, - uint16_t Setup, uint16_t DisableIntSrc) -{ - register uint16_t cra; - register uint16_t crb; - register uint16_t setup = Setup; /* Cache the Standard Setup. */ + devpriv->allocatedBuf++; - /* Initialize CRA and CRB images. */ - cra = ((setup & CRAMSK_LOADSRC_A) /* Preload trigger is passed through. */ - |((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1)))); /* IndexSrc is restricted to ENC_X or IndxPol. */ + } - crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A /* Reset any pending CounterA event captures. */ - | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB))); /* Clock enable is passed through. */ + dev->board_ptr = s626_boards; + dev->board_name = thisboard->name; - /* Force IntSrc to Disabled if DisableIntSrc is asserted. */ - if (!DisableIntSrc) - cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC - - CRABIT_INTSRC_A)); + ret = comedi_alloc_subdevices(dev, 6); + if (ret) + return ret; - /* Populate all mode-dependent attributes of CRA & CRB images. */ - switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) { - case CLKSRC_EXTENDER: /* Extender Mode: Force to Timer mode */ - /* (Extender valid only for B counters). */ + dev->iobase = (unsigned long)devpriv->base_addr; + dev->irq = devpriv->pdev->irq; - case CLKSRC_TIMER: /* Timer Mode: */ - cra |= ((2 << CRABIT_CLKSRC_A) /* ClkSrcA<1> selects system clock */ - |((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /* with count direction (ClkSrcA<0>) obtained from ClkPol. */ - |(1 << CRABIT_CLKPOL_A) /* ClkPolA behaves as always-on clock enable. */ - |(MULT_X1 << CRABIT_CLKMULT_A)); /* ClkMult must be 1x. */ - break; + /* set up interrupt handler */ + if (dev->irq == 0) { + printk(KERN_ERR " unknown irq (bad)\n"); + } else { + ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED, + "s626", dev); - default: /* Counter Mode: */ - cra |= (CLKSRC_COUNTER /* Select ENC_C and ENC_D as clock/direction inputs. */ - | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) /* Clock polarity is passed through. */ - |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force multiplier to x1 if not legal, otherwise pass through. */ - (MULT_X1 << CRABIT_CLKMULT_A) : - ((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A - - STDBIT_CLKMULT)))); + if (ret < 0) { + printk(KERN_ERR " irq not available\n"); + dev->irq = 0; + } } - /* Force positive index polarity if IndxSrc is software-driven only, */ - /* otherwise pass it through. */ - if (~setup & STDMSK_INDXSRC) - cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A - - STDBIT_INDXPOL)); + DEBUG("s626_attach: -- it opts %d,%d --\n", + it->options[0], it->options[1]); - /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */ - /* enable mask to indicate the counter interrupt is disabled. */ - if (DisableIntSrc) - devpriv->CounterIntEnabs &= ~k->MyEventBits[3]; + s = dev->subdevices + 0; + /* analog input subdevice */ + dev->read_subdev = s; + /* we support single-ended (ground) and differential */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; + s->n_chan = thisboard->ai_chans; + s->maxdata = (0xffff >> 2); + s->range_table = &s626_range_table; + s->len_chanlist = thisboard->ai_chans; /* This is the maximum chanlist + length that the board can + handle */ + s->insn_config = s626_ai_insn_config; + s->insn_read = s626_ai_insn_read; + s->do_cmd = s626_ai_cmd; + s->do_cmdtest = s626_ai_cmdtest; + s->cancel = s626_ai_cancel; - /* While retaining CounterB and LatchSrc configurations, program the */ - /* new counter operating mode. */ - DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra); - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb); -} + s = dev->subdevices + 1; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = thisboard->ao_chans; + s->maxdata = (0x3fff); + s->range_table = &range_bipolar10; + s->insn_write = s626_ao_winsn; + s->insn_read = s626_ao_rinsn; -static void SetMode_B(struct comedi_device *dev, struct enc_private *k, - uint16_t Setup, uint16_t DisableIntSrc) -{ - register uint16_t cra; - register uint16_t crb; - register uint16_t setup = Setup; /* Cache the Standard Setup. */ + s = dev->subdevices + 2; + /* digital I/O subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = S626_DIO_CHANNELS; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = &dio_private_A; + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = dev->subdevices + 3; + /* digital I/O subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = &dio_private_B; + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = dev->subdevices + 4; + /* digital I/O subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = &dio_private_C; + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; - /* Initialize CRA and CRB images. */ - cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)); /* IndexSrc field is restricted to ENC_X or IndxPol. */ + s = dev->subdevices + 5; + /* encoder (counter) subdevice */ + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; + s->n_chan = thisboard->enc_chans; + s->private = enc_private_data; + s->insn_config = s626_enc_insn_config; + s->insn_read = s626_enc_insn_read; + s->insn_write = s626_enc_insn_write; + s->maxdata = 0xffffff; + s->range_table = &range_unknown; - crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B /* Reset event captures and disable interrupts. */ - | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) /* Clock enable is passed through. */ - |((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B))); /* Preload trigger source is passed through. */ + /* stop ai_command */ + devpriv->ai_cmd_running = 0; - /* Force IntSrc to Disabled if DisableIntSrc is asserted. */ - if (!DisableIntSrc) - crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC - - CRBBIT_INTSRC_B)); + if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) { + dma_addr_t pPhysBuf; + uint16_t chan; - /* Populate all mode-dependent attributes of CRA & CRB images. */ - switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) { - case CLKSRC_TIMER: /* Timer Mode: */ - cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB<1> selects system clock */ - |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction (ClkSrcB<0>) obtained from ClkPol. */ - crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB behaves as always-on clock enable. */ - |(MULT_X1 << CRBBIT_CLKMULT_B)); /* ClkMultB must be 1x. */ - break; + /* enab DEBI and audio pins, enable I2C interface. */ + MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); + /* Configure DEBI operating mode. */ + WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */ + /* bits wide. */ + | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) - case CLKSRC_EXTENDER: /* Extender Mode: */ - cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB source is OverflowA (same as "timer") */ - |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction obtained from ClkPol. */ - crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB controls IndexB -- always set to active. */ - |(MULT_X0 << CRBBIT_CLKMULT_B)); /* ClkMultB selects OverflowA as the clock source. */ - break; + /* Declare DEBI */ + /* transfer timeout */ + /* interval. */ + |DEBI_SWAP /* Set up byte lane */ + /* steering. */ + | DEBI_CFG_INTEL); /* Intel-compatible */ + /* local bus (DEBI */ + /* never times out). */ + DEBUG("s626_attach: %d debi init -- %d\n", + DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | + DEBI_SWAP | DEBI_CFG_INTEL, + DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ | + DEBI_CFG_16Q); - default: /* Counter Mode: */ - cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B); /* Select ENC_C and ENC_D as clock/direction inputs. */ - crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) /* ClkPol is passed through. */ - |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force ClkMult to x1 if not legal, otherwise pass through. */ - (MULT_X1 << CRBBIT_CLKMULT_B) : - ((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B - - STDBIT_CLKMULT)))); - } + /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ + /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ - /* Force positive index polarity if IndxSrc is software-driven only, */ - /* otherwise pass it through. */ - if (~setup & STDMSK_INDXSRC) - crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL - - CRBBIT_INDXPOL_B)); + /* Paging is disabled. */ + WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */ - /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */ - /* enable mask to indicate the counter interrupt is disabled. */ - if (DisableIntSrc) - devpriv->CounterIntEnabs &= ~k->MyEventBits[3]; + /* Init GPIO so that ADC Start* is negated. */ + WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); - /* While retaining CounterA and LatchSrc configurations, program the */ - /* new counter operating mode. */ - DEBIreplace(dev, k->MyCRA, - (uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra); - DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb); -} + /* IsBoardRevA is a boolean that indicates whether the board is RevA. + * + * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC + * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which + * is used to access the onboard serial EEPROM. The EEPROM's I2C + * DeviceAddress is hardwired to a value that is dependent on the + * 626 board revision. On all board revisions, the EEPROM stores + * TrimDAC calibration constants for analog I/O. On RevB and + * higher boards, the DeviceAddress is hardwired to 0 to enable + * the EEPROM to also store the PCI SubVendorID and SubDeviceID; + * this is the address at which the SAA7146 expects a + * configuration EEPROM to reside. On RevA boards, the EEPROM + * device address, which is hardwired to 4, prevents the SAA7146 + * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in + * default values, instead. + */ -/* Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index. */ + /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */ + /* DeviceType (0xA0) */ + /* and DeviceAddress<<1. */ -static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, - uint16_t enab) -{ - DEBUG("SetEnable_A: SetEnable_A enter 3541\n"); - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), - (uint16_t) (enab << CRBBIT_CLKENAB_A)); -} + devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */ + /* eeprom(revb) */ -static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, - uint16_t enab) -{ - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)), - (uint16_t) (enab << CRBBIT_CLKENAB_B)); -} + /* Issue an I2C ABORT command to halt any I2C operation in */ + /* progress and reset BUSY flag. */ + WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); + /* Write I2C control: abort any I2C activity. */ + MC_ENABLE(P_MC2, MC2_UPLD_IIC); + /* Invoke command upload */ + while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) + ; + /* and wait for upload to complete. */ -static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k) -{ - return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1; -} + /* Per SAA7146 data sheet, write to STATUS reg twice to + * reset all I2C error flags. */ + for (i = 0; i < 2; i++) { + WR7146(P_I2CSTAT, I2C_CLKSEL); + /* Write I2C control: reset error flags. */ + MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */ + while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) + ; + /* and wait for upload to complete. */ + } -static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k) -{ - return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1; -} + /* Init audio interface functional attributes: set DAC/ADC + * serial clock rates, invert DAC serial clock so that + * DAC data setup times are satisfied, enable DAC serial + * clock out. + */ -/* Return/set a counter pair's latch trigger source. 0: On read - * access, 1: A index latches A, 2: B index latches B, 3: A overflow - * latches B. - */ + WR7146(P_ACON2, ACON2_INIT); -static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, - uint16_t value) -{ - DEBUG("SetLatchSource: SetLatchSource enter 3550\n"); - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)), - (uint16_t) (value << CRBBIT_LATCHSRC)); + /* Set up TSL1 slot list, which is used to control the + * accumulation of ADC data: RSD1 = shift data in on SD1. + * SIB_A1 = store data uint8_t at next available location in + * FB BUFFER1 register. */ + WR7146(P_TSL1, RSD1 | SIB_A1); + /* Fetch ADC high data uint8_t. */ + WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); + /* Fetch ADC low data uint8_t; end of TSL1. */ - DEBUG("SetLatchSource: SetLatchSource exit\n"); -} + /* enab TSL1 slot list so that it executes all the time. */ + WR7146(P_ACON1, ACON1_ADCSTART); -/* - * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ) - * { - * return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3; - * } - */ + /* Initialize RPS registers used for ADC. */ -/* - * Return/set the event that will trigger transfer of the preload - * register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow, - * 2=OverflowA (B counters only), 3=disabled. - */ + /* Physical start of RPS program. */ + WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); -static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, - uint16_t Trig) -{ - DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A), - (uint16_t) (Trig << CRABIT_LOADSRC_A)); -} + WR7146(P_RPSPAGE1, 0); + /* RPS program performs no explicit mem writes. */ + WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */ -static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, - uint16_t Trig) -{ - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)), - (uint16_t) (Trig << CRBBIT_LOADSRC_B)); -} + /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface + * to a known state by invoking ADCs until FB BUFFER 1 + * register shows that it is correctly receiving ADC data. + * This is necessary because the SAA7146 ADC interface does + * not start up in a defined state after a PCI reset. + */ -static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k) -{ - return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3; -} +/* PollList = EOPL; // Create a simple polling */ +/* // list for analog input */ +/* // channel 0. */ +/* ResetADC( dev, &PollList ); */ -static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k) -{ - return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3; -} +/* s626_ai_rinsn(dev,dev->subdevices,NULL,data); //( &AdcData ); // */ +/* //Get initial ADC */ +/* //value. */ -/* Return/set counter interrupt source and clear any captured - * index/overflow events. IntSource: 0=Disabled, 1=OverflowOnly, - * 2=IndexOnly, 3=IndexAndOverflow. - */ +/* StartVal = data[0]; */ -static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, - uint16_t IntSource) -{ - /* Reset any pending counter overflow or index captures. */ - DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), - CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); +/* // VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION. */ +/* // Invoke ADCs until the new ADC value differs from the initial */ +/* // value or a timeout occurs. The timeout protects against the */ +/* // possibility that the driver is restarting and the ADC data is a */ +/* // fixed value resulting from the applied ADC analog input being */ +/* // unusually quiet or at the rail. */ - /* Program counter interrupt source. */ - DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A, - (uint16_t) (IntSource << CRABIT_INTSRC_A)); +/* for ( index = 0; index < 500; index++ ) */ +/* { */ +/* s626_ai_rinsn(dev,dev->subdevices,NULL,data); */ +/* AdcData = data[0]; //ReadADC( &AdcData ); */ +/* if ( AdcData != StartVal ) */ +/* break; */ +/* } */ - /* Update MISC2 interrupt enable mask. */ - devpriv->CounterIntEnabs = - (devpriv->CounterIntEnabs & ~k-> - MyEventBits[3]) | k->MyEventBits[IntSource]; -} + /* end initADC */ -static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k, - uint16_t IntSource) -{ - uint16_t crb; + /* init the DAC interface */ - /* Cache writeable CRB register image. */ - crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; + /* Init Audio2's output DMAC attributes: burst length = 1 + * DWORD, threshold = 1 DWORD. + */ + WR7146(P_PCI_BT_A, 0); - /* Reset any pending counter overflow or index captures. */ - DEBIwrite(dev, k->MyCRB, - (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B)); + /* Init Audio2's output DMA physical addresses. The protection + * address is set to 1 DWORD past the base address so that a + * single DWORD will be transferred each time a DMA transfer is + * enabled. */ - /* Program counter interrupt source. */ - DEBIwrite(dev, k->MyCRB, - (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource << - CRBBIT_INTSRC_B))); + pPhysBuf = + devpriv->ANABuf.PhysicalBase + + (DAC_WDMABUF_OS * sizeof(uint32_t)); - /* Update MISC2 interrupt enable mask. */ - devpriv->CounterIntEnabs = - (devpriv->CounterIntEnabs & ~k-> - MyEventBits[3]) | k->MyEventBits[IntSource]; -} + WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */ + WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */ -static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k) -{ - return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3; -} + /* Cache Audio2's output DMA buffer logical address. This is + * where DAC data is buffered for A2 output DMA transfers. */ + devpriv->pDacWBuf = + (uint32_t *) devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS; -static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k) -{ - return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3; -} + /* Audio2's output channels does not use paging. The protection + * violation handling bit is set so that the DMAC will + * automatically halt and its PCI address pointer will be reset + * when the protection address is reached. */ -/* Return/set the clock multiplier. */ + WR7146(P_PAGEA2_OUT, 8); -/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ -/* { */ -/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */ -/* } */ + /* Initialize time slot list 2 (TSL2), which is used to control + * the clock generation for and serialization of data to be sent + * to the DAC devices. Slot 0 is a NOP that is used to trap TSL + * execution; this permits other slots to be safely modified + * without first turning off the TSL sequencer (which is + * apparently impossible to do). Also, SD3 (which is driven by a + * pull-up resistor) is shifted in and stored to the MSB of + * FB_BUFFER2 to be used as evidence that the slot sequence has + * not yet finished executing. + */ -/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) */ -/* { */ -/* return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */ -/* } */ + SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); + /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */ -/* Return/set the clock polarity. */ + /* Initialize slot 1, which is constant. Slot 1 causes a + * DWORD to be transferred from audio channel 2's output FIFO + * to the FIFO's output buffer so that it can be serialized + * and sent to the DAC during subsequent slots. All remaining + * slots are dynamically populated as required by the target + * DAC device. + */ + SETVECT(1, LF_A2); + /* Slot 1: Fetch DWORD from Audio2's output FIFO. */ -/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */ -/* { */ -/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */ -/* } */ + /* Start DAC's audio interface (TSL2) running. */ + WR7146(P_ACON1, ACON1_DACSTART); -/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) */ -/* { */ -/* return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */ -/* } */ + /* end init DAC interface */ -/* Return/set the clock source. */ + /* Init Trim DACs to calibrated values. Do it twice because the + * SAA7146 audio channel does not always reset properly and + * sometimes causes the first few TrimDAC writes to malfunction. + */ -/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */ -/* { */ -/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */ -/* } */ + LoadTrimDACs(dev); + LoadTrimDACs(dev); /* Insurance. */ -/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ) */ -/* { */ -/* return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */ -/* } */ + /* Manually init all gate array hardware in case this is a soft + * reset (we have no way of determining whether this is a warm + * or cold start). This is necessary because the gate array will + * reset only in response to a PCI hard reset; there is no soft + * reset function. */ -/* Return/set the index polarity. */ + /* Init all DAC outputs to 0V and init all DAC setpoint and + * polarity images. + */ + for (chan = 0; chan < S626_DAC_CHANNELS; chan++) + SetDAC(dev, chan, 0); -/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ -/* { */ -/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */ -/* } */ + /* Init image of WRMISC2 Battery Charger Enabled control bit. + * This image is used when the state of the charger control bit, + * which has no direct hardware readback mechanism, is queried. + */ + devpriv->ChargeEnabled = 0; -/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k ) */ -/* { */ -/* return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */ -/* } */ + /* Init image of watchdog timer interval in WRMISC2. This image + * maintains the value of the control bits of MISC2 are + * continuously reset to zero as long as the WD timer is disabled. + */ + devpriv->WDInterval = 0; -/* Return/set the index source. */ + /* Init Counter Interrupt enab mask for RDMISC2. This mask is + * applied against MISC2 when testing to determine which timer + * events are requesting interrupt service. + */ + devpriv->CounterIntEnabs = 0; -/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ -/* { */ -/* DEBUG("SetIndexSrc: set index src enter 3700\n"); */ -/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */ -/* } */ + /* Init counters. */ + CountersInit(dev); -/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k ) */ -/* { */ -/* return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */ -/* } */ + /* Without modifying the state of the Battery Backup enab, disable + * the watchdog timer, set DIO channels 0-5 to operate in the + * standard DIO (vs. counter overflow) mode, disable the battery + * charger, and reset the watchdog interval selector to zero. + */ + WriteMISC2(dev, (uint16_t) (DEBIread(dev, + LP_RDMISC2) & + MISC2_BATT_ENABLE)); -/* Generate an index pulse. */ + /* Initialize the digital I/O subsystem. */ + s626_dio_init(dev); -static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k) -{ - register uint16_t cra; + /* enable interrupt test */ + /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ + } - DEBUG("PulseIndex_A: pulse index enter\n"); + DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor, + (uint32_t) devpriv->base_addr); - cra = DEBIread(dev, k->MyCRA); /* Pulse index. */ - DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A)); - DEBUG("PulseIndex_A: pulse index step1\n"); - DEBIwrite(dev, k->MyCRA, cra); + return 1; } -static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k) +static void s626_detach(struct comedi_device *dev) { - register uint16_t crb; + if (devpriv) { + /* stop ai_command */ + devpriv->ai_cmd_running = 0; - crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; /* Pulse index. */ - DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B)); - DEBIwrite(dev, k->MyCRB, crb); -} + if (devpriv->base_addr) { + /* interrupt mask */ + WR7146(P_IER, 0); /* Disable master interrupt. */ + WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); /* Clear board's IRQ status flag. */ -/* Write value into counter preload register. */ + /* Disable the watchdog timer and battery charger. */ + WriteMISC2(dev, 0); -static void Preload(struct comedi_device *dev, struct enc_private *k, - uint32_t value) -{ - DEBUG("Preload: preload enter\n"); - DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */ - DEBUG("Preload: preload step 1\n"); - DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2), - (uint16_t) (value >> 16)); -} + /* Close all interfaces on 7146 device. */ + WR7146(P_MC1, MC1_SHUTDOWN); + WR7146(P_ACON1, ACON1_BASE); -static void CountersInit(struct comedi_device *dev) -{ - int chan; - struct enc_private *k; - uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ - /* index. */ - (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ - (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is counter. */ - (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ - (CNTDIR_UP << BF_CLKPOL) | /* Count direction is up. */ - (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ - (CLKENAB_INDEX << BF_CLKENAB); /* Enabled by index */ + CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE); + CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE); + } - /* Disable all counter interrupts and clear any captured counter events. */ - for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) { - k = &encpriv[chan]; - k->SetMode(dev, k, Setup, TRUE); - k->SetIntSrc(dev, k, 0); - k->ResetCapFlags(dev, k); - k->SetEnable(dev, k, CLKENAB_ALWAYS); + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv->base_addr) + iounmap(devpriv->base_addr); + if (devpriv->pdev) { + if (devpriv->got_regions) + comedi_pci_disable(devpriv->pdev); + pci_dev_put(devpriv->pdev); + } } - DEBUG("CountersInit: counters initialized\n"); - } static struct comedi_driver s626_driver = { -- GitLab From 6b387b7095cabbb8bd31c936ed3d47ef758cc595 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:25:16 -0700 Subject: [PATCH 2519/6849] staging: comedi: s626: remove forward declarations 2 Move the DEBI* i/o functions up to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 143 +++++++++++++------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 08868066a4d9..1efa2f021647 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -220,9 +220,6 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr); static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val); static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata); static void SendDAC(struct comedi_device *dev, uint32_t val); -static void DEBItransfer(struct comedi_device *dev); -static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr); -static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata); /* COUNTER OBJECT ------------------------------------------------ */ struct enc_private { @@ -426,6 +423,76 @@ static const struct comedi_lrange s626_range_table = { 2, { } }; +/* Execute a DEBI transfer. This must be called from within a */ +/* critical section. */ +static void DEBItransfer(struct comedi_device *dev) +{ + /* Initiate upload of shadow RAM to DEBI control register. */ + MC_ENABLE(P_MC2, MC2_UPLD_DEBI); + + /* Wait for completion of upload from shadow RAM to DEBI control */ + /* register. */ + while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) + ; + + /* Wait until DEBI transfer is done. */ + while (RR7146(P_PSR) & PSR_DEBI_S) + ; +} + +/* Initialize the DEBI interface for all transfers. */ + +static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) +{ + uint16_t retval; + + /* Set up DEBI control register value in shadow RAM. */ + WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); + + /* Execute the DEBI transfer. */ + DEBItransfer(dev); + + /* Fetch target register value. */ + retval = (uint16_t) RR7146(P_DEBIAD); + + /* Return register value. */ + return retval; +} + +/* Write a value to a gate array register. */ +static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) +{ + + /* Set up DEBI control register value in shadow RAM. */ + WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); + WR7146(P_DEBIAD, wdata); + + /* Execute the DEBI transfer. */ + DEBItransfer(dev); +} + +/* Replace the specified bits in a gate array register. Imports: mask + * specifies bits that are to be preserved, wdata is new value to be + * or'd with the masked original. + */ +static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, + uint16_t wdata) +{ + + /* Copy target gate array register into P_DEBIAD register. */ + WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); + /* Set up DEBI control reg value in shadow RAM. */ + DEBItransfer(dev); /* Execute the DEBI Read transfer. */ + + /* Write back the modified image. */ + WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); + /* Set up DEBI control reg value in shadow RAM. */ + + WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); + /* Modify the register image. */ + DEBItransfer(dev); /* Execute the DEBI Write transfer. */ +} + static unsigned int s626_ai_reg_to_uint(int data) { unsigned int tempdata; @@ -2123,76 +2190,6 @@ static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage) DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); /* Disable writes to MISC2. */ } -/* Initialize the DEBI interface for all transfers. */ - -static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) -{ - uint16_t retval; - - /* Set up DEBI control register value in shadow RAM. */ - WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); - - /* Execute the DEBI transfer. */ - DEBItransfer(dev); - - /* Fetch target register value. */ - retval = (uint16_t) RR7146(P_DEBIAD); - - /* Return register value. */ - return retval; -} - -/* Execute a DEBI transfer. This must be called from within a */ -/* critical section. */ -static void DEBItransfer(struct comedi_device *dev) -{ - /* Initiate upload of shadow RAM to DEBI control register. */ - MC_ENABLE(P_MC2, MC2_UPLD_DEBI); - - /* Wait for completion of upload from shadow RAM to DEBI control */ - /* register. */ - while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) - ; - - /* Wait until DEBI transfer is done. */ - while (RR7146(P_PSR) & PSR_DEBI_S) - ; -} - -/* Write a value to a gate array register. */ -static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) -{ - - /* Set up DEBI control register value in shadow RAM. */ - WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); - WR7146(P_DEBIAD, wdata); - - /* Execute the DEBI transfer. */ - DEBItransfer(dev); -} - -/* Replace the specified bits in a gate array register. Imports: mask - * specifies bits that are to be preserved, wdata is new value to be - * or'd with the masked original. - */ -static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, - uint16_t wdata) -{ - - /* Copy target gate array register into P_DEBIAD register. */ - WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); - /* Set up DEBI control reg value in shadow RAM. */ - DEBItransfer(dev); /* Execute the DEBI Read transfer. */ - - /* Write back the modified image. */ - WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); - /* Set up DEBI control reg value in shadow RAM. */ - - WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); - /* Modify the register image. */ - DEBItransfer(dev); /* Execute the DEBI Write transfer. */ -} - static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize) { -- GitLab From 982e3d11ed2b7a96ee93ef62ab37826da1e75a32 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:25:32 -0700 Subject: [PATCH 2520/6849] staging: comedi: s626: remove forward declarations 3 Move the I2C functions up to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 124 +++++++++++++------------- 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 1efa2f021647..5fcb43ae5471 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -216,8 +216,6 @@ static int s626_ns_to_timer(int *nanosec, int round_mode); /* internal routines */ static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, uint8_t DacData); -static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr); -static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val); static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata); static void SendDAC(struct comedi_device *dev, uint32_t val); @@ -493,6 +491,67 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, DEBItransfer(dev); /* Execute the DEBI Write transfer. */ } +/* ************** EEPROM ACCESS FUNCTIONS ************** */ + +static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) +{ + /* Write I2C command to I2C Transfer Control shadow register. */ + WR7146(P_I2CCTRL, val); + + /* Upload I2C shadow registers into working registers and wait for */ + /* upload confirmation. */ + + MC_ENABLE(P_MC2, MC2_UPLD_IIC); + while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) + ; + + /* Wait until I2C bus transfer is finished or an error occurs. */ + while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) + ; + + /* Return non-zero if I2C error occurred. */ + return RR7146(P_I2CCTRL) & I2C_ERR; + +} + +/* Read uint8_t from EEPROM. */ +static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) +{ + uint8_t rtnval; + + /* Send EEPROM target address. */ + if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) + /* Byte2 = I2C command: write to I2C EEPROM device. */ + | I2C_B1(I2C_ATTRSTOP, addr) + /* Byte1 = EEPROM internal target address. */ + | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ + /* Abort function and declare error if handshake failed. */ + DEBUG("I2Cread: error handshake I2Cread a\n"); + return 0; + } + /* Execute EEPROM read. */ + if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) + + /* Byte2 = I2C */ + /* command: read */ + /* from I2C EEPROM */ + /* device. */ + |I2C_B1(I2C_ATTRSTOP, 0) + + /* Byte1 receives */ + /* uint8_t from */ + /* EEPROM. */ + |I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ + + /* Abort function and declare error if handshake failed. */ + DEBUG("I2Cread: error handshake I2Cread b\n"); + return 0; + } + /* Return copy of EEPROM value. */ + rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16); + return rtnval; +} + static unsigned int s626_ai_reg_to_uint(int data) { unsigned int tempdata; @@ -1938,67 +1997,6 @@ static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, | (uint32_t) DacData); /* Include DAC setpoint data. */ } -/* ************** EEPROM ACCESS FUNCTIONS ************** */ -/* Read uint8_t from EEPROM. */ - -static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) -{ - uint8_t rtnval; - - /* Send EEPROM target address. */ - if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) - /* Byte2 = I2C command: write to I2C EEPROM device. */ - | I2C_B1(I2C_ATTRSTOP, addr) - /* Byte1 = EEPROM internal target address. */ - | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ - /* Abort function and declare error if handshake failed. */ - DEBUG("I2Cread: error handshake I2Cread a\n"); - return 0; - } - /* Execute EEPROM read. */ - if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) - - /* Byte2 = I2C */ - /* command: read */ - /* from I2C EEPROM */ - /* device. */ - |I2C_B1(I2C_ATTRSTOP, 0) - - /* Byte1 receives */ - /* uint8_t from */ - /* EEPROM. */ - |I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ - - /* Abort function and declare error if handshake failed. */ - DEBUG("I2Cread: error handshake I2Cread b\n"); - return 0; - } - /* Return copy of EEPROM value. */ - rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16); - return rtnval; -} - -static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) -{ - /* Write I2C command to I2C Transfer Control shadow register. */ - WR7146(P_I2CCTRL, val); - - /* Upload I2C shadow registers into working registers and wait for */ - /* upload confirmation. */ - - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) - ; - - /* Wait until I2C bus transfer is finished or an error occurs. */ - while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) - ; - - /* Return non-zero if I2C error occurred. */ - return RR7146(P_I2CCTRL) & I2C_ERR; - -} - /* Private helper function: Write setpoint to an application DAC channel. */ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) -- GitLab From 954147296993e1c369f8e1d68d488724e7040dea Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:25:49 -0700 Subject: [PATCH 2521/6849] staging: comedi: s626: remove forward declarations 4 Move the DAC functions up to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 488 +++++++++++++------------- 1 file changed, 240 insertions(+), 248 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 5fcb43ae5471..3cdb29323ca3 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -213,12 +213,6 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop, static int s626_dio_clear_irq(struct comedi_device *dev); static int s626_ns_to_timer(int *nanosec, int round_mode); -/* internal routines */ -static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, - uint8_t DacData); -static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata); -static void SendDAC(struct comedi_device *dev, uint32_t val); - /* COUNTER OBJECT ------------------------------------------------ */ struct enc_private { /* Pointers to functions that differ for A and B counters: */ @@ -552,6 +546,246 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) return rtnval; } +/* *********** DAC FUNCTIONS *********** */ + +/* Slot 0 base settings. */ +#define VECT0 (XSD2 | RSD3 | SIB_A2) +/* Slot 0 always shifts in 0xFF and store it to FB_BUFFER2. */ + +/* TrimDac LogicalChan-to-PhysicalChan mapping table. */ +static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 }; + +/* TrimDac LogicalChan-to-EepromAdrs mapping table. */ +static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 }; + +/* Private helper function: Transmit serial data to DAC via Audio + * channel 2. Assumes: (1) TSL2 slot records initialized, and (2) + * Dacpol contains valid target image. + */ +static void SendDAC(struct comedi_device *dev, uint32_t val) +{ + + /* START THE SERIAL CLOCK RUNNING ------------- */ + + /* Assert DAC polarity control and enable gating of DAC serial clock + * and audio bit stream signals. At this point in time we must be + * assured of being in time slot 0. If we are not in slot 0, the + * serial clock and audio stream signals will be disabled; this is + * because the following DEBIwrite statement (which enables signals + * to be passed through the gate array) would execute before the + * trailing edge of WS1/WS3 (which turns off the signals), thus + * causing the signals to be inactive during the DAC write. + */ + DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol); + + /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */ + + /* Copy DAC setpoint value to DAC's output DMA buffer. */ + + /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */ + *devpriv->pDacWBuf = val; + + /* enab the output DMA transfer. This will cause the DMAC to copy + * the DAC's data value to A2's output FIFO. The DMA transfer will + * then immediately terminate because the protection address is + * reached upon transfer of the first DWORD value. + */ + MC_ENABLE(P_MC1, MC1_A2OUT); + + /* While the DMA transfer is executing ... */ + + /* Reset Audio2 output FIFO's underflow flag (along with any other + * FIFO underflow/overflow flags). When set, this flag will + * indicate that we have emerged from slot 0. + */ + WR7146(P_ISR, ISR_AFOU); + + /* Wait for the DMA transfer to finish so that there will be data + * available in the FIFO when time slot 1 tries to transfer a DWORD + * from the FIFO to the output buffer register. We test for DMA + * Done by polling the DMAC enable flag; this flag is automatically + * cleared when the transfer has finished. + */ + while ((RR7146(P_MC1) & MC1_A2OUT) != 0) + ; + + /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */ + + /* FIFO data is now available, so we enable execution of time slots + * 1 and higher by clearing the EOS flag in slot 0. Note that SD3 + * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list + * detection. + */ + SETVECT(0, XSD2 | RSD3 | SIB_A2); + + /* Wait for slot 1 to execute to ensure that the Packet will be + * transmitted. This is detected by polling the Audio2 output FIFO + * underflow flag, which will be set when slot 1 execution has + * finished transferring the DAC's data DWORD from the output FIFO + * to the output buffer register. + */ + while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) + ; + + /* Set up to trap execution at slot 0 when the TSL sequencer cycles + * back to slot 0 after executing the EOS in slot 5. Also, + * simultaneously shift out and in the 0x00 that is ALWAYS the value + * stored in the last byte to be shifted out of the FIFO's DWORD + * buffer register. + */ + SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS); + + /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */ + + /* Wait for the TSL to finish executing all time slots before + * exiting this function. We must do this so that the next DAC + * write doesn't start, thereby enabling clock/chip select signals: + * + * 1. Before the TSL sequence cycles back to slot 0, which disables + * the clock/cs signal gating and traps slot // list execution. + * we have not yet finished slot 5 then the clock/cs signals are + * still gated and we have not finished transmitting the stream. + * + * 2. While slots 2-5 are executing due to a late slot 0 trap. In + * this case, the slot sequence is currently repeating, but with + * clock/cs signals disabled. We must wait for slot 0 to trap + * execution before setting up the next DAC setpoint DMA transfer + * and enabling the clock/cs signals. To detect the end of slot 5, + * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If + * the TSL has not yet finished executing slot 5 ... + */ + if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) { + /* The trap was set on time and we are still executing somewhere + * in slots 2-5, so we now wait for slot 0 to execute and trap + * TSL execution. This is detected when FB_BUFFER2 MSB changes + * from 0xFF to 0x00, which slot 0 causes to happen by shifting + * out/in on SD2 the 0x00 that is always referenced by slot 5. + */ + while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) + ; + } + /* Either (1) we were too late setting the slot 0 trap; the TSL + * sequencer restarted slot 0 before we could set the EOS trap flag, + * or (2) we were not late and execution is now trapped at slot 0. + * In either case, we must now change slot 0 so that it will store + * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes. + * In order to do this, we reprogram slot 0 so that it will shift in + * SD3, which is driven only by a pull-up resistor. + */ + SETVECT(0, RSD3 | SIB_A2 | EOS); + + /* Wait for slot 0 to execute, at which time the TSL is setup for + * the next DAC write. This is detected when FB_BUFFER2 MSB changes + * from 0x00 to 0xFF. + */ + while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) + ; +} + +/* Private helper function: Write setpoint to an application DAC channel. */ +static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) +{ + register uint16_t signmask; + register uint32_t WSImage; + + /* Adjust DAC data polarity and set up Polarity Control Register */ + /* image. */ + signmask = 1 << chan; + if (dacdata < 0) { + dacdata = -dacdata; + devpriv->Dacpol |= signmask; + } else + devpriv->Dacpol &= ~signmask; + + /* Limit DAC setpoint value to valid range. */ + if ((uint16_t) dacdata > 0x1FFF) + dacdata = 0x1FFF; + + /* Set up TSL2 records (aka "vectors") for DAC update. Vectors V2 + * and V3 transmit the setpoint to the target DAC. V4 and V5 send + * data to a non-existent TrimDac channel just to keep the clock + * running after sending data to the target DAC. This is necessary + * to eliminate the clock glitch that would otherwise occur at the + * end of the target DAC's serial data stream. When the sequence + * restarts at V0 (after executing V5), the gate array automatically + * disables gating for the DAC clock and all DAC chip selects. + */ + + WSImage = (chan & 2) ? WS1 : WS2; + /* Choose DAC chip select to be asserted. */ + SETVECT(2, XSD2 | XFIFO_1 | WSImage); + /* Slot 2: Transmit high data byte to target DAC. */ + SETVECT(3, XSD2 | XFIFO_0 | WSImage); + /* Slot 3: Transmit low data byte to target DAC. */ + SETVECT(4, XSD2 | XFIFO_3 | WS3); + /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */ + SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); + /* Slot 5: running after writing target DAC's low data byte. */ + + /* Construct and transmit target DAC's serial packet: + * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, + * and D<12:0> is the DAC setpoint. Append a WORD value (that writes + * to a non-existent TrimDac channel) that serves to keep the clock + * running after the packet has been sent to the target DAC. + */ + SendDAC(dev, 0x0F000000 + /* Continue clock after target DAC data (write to non-existent trimdac). */ + | 0x00004000 + /* Address the two main dual-DAC devices (TSL's chip select enables + * target device). */ + | ((uint32_t) (chan & 1) << 15) + /* Address the DAC channel within the device. */ + | (uint32_t) dacdata); /* Include DAC setpoint data. */ + +} + +static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, + uint8_t DacData) +{ + uint32_t chan; + + /* Save the new setpoint in case the application needs to read it back later. */ + devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData; + + /* Map logical channel number to physical channel number. */ + chan = (uint32_t) trimchan[LogicalChan]; + + /* Set up TSL2 records for TrimDac write operation. All slots shift + * 0xFF in from pulled-up SD3 so that the end of the slot sequence + * can be detected. + */ + + SETVECT(2, XSD2 | XFIFO_1 | WS3); + /* Slot 2: Send high uint8_t to target TrimDac. */ + SETVECT(3, XSD2 | XFIFO_0 | WS3); + /* Slot 3: Send low uint8_t to target TrimDac. */ + SETVECT(4, XSD2 | XFIFO_3 | WS1); + /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */ + SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); + /* Slot 5: Send NOP low uint8_t to DAC0. */ + + /* Construct and transmit target DAC's serial packet: + * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the + * DAC channel's address, and D<7:0> is the DAC setpoint. Append a + * WORD value (that writes a channel 0 NOP command to a non-existent + * main DAC channel) that serves to keep the clock running after the + * packet has been sent to the target DAC. + */ + + /* Address the DAC channel within the trimdac device. */ + SendDAC(dev, ((uint32_t) chan << 8) + | (uint32_t) DacData); /* Include DAC setpoint data. */ +} + +static void LoadTrimDACs(struct comedi_device *dev) +{ + register uint8_t i; + + /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */ + for (i = 0; i < ARRAY_SIZE(trimchan); i++) + WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i])); +} + static unsigned int s626_ai_reg_to_uint(int data) { unsigned int tempdata; @@ -1938,248 +2172,6 @@ static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */ } -/* *********** DAC FUNCTIONS *********** */ - -/* Slot 0 base settings. */ -#define VECT0 (XSD2 | RSD3 | SIB_A2) -/* Slot 0 always shifts in 0xFF and store it to FB_BUFFER2. */ - -/* TrimDac LogicalChan-to-PhysicalChan mapping table. */ -static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 }; - -/* TrimDac LogicalChan-to-EepromAdrs mapping table. */ -static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 }; - -static void LoadTrimDACs(struct comedi_device *dev) -{ - register uint8_t i; - - /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */ - for (i = 0; i < ARRAY_SIZE(trimchan); i++) - WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i])); -} - -static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, - uint8_t DacData) -{ - uint32_t chan; - - /* Save the new setpoint in case the application needs to read it back later. */ - devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData; - - /* Map logical channel number to physical channel number. */ - chan = (uint32_t) trimchan[LogicalChan]; - - /* Set up TSL2 records for TrimDac write operation. All slots shift - * 0xFF in from pulled-up SD3 so that the end of the slot sequence - * can be detected. - */ - - SETVECT(2, XSD2 | XFIFO_1 | WS3); - /* Slot 2: Send high uint8_t to target TrimDac. */ - SETVECT(3, XSD2 | XFIFO_0 | WS3); - /* Slot 3: Send low uint8_t to target TrimDac. */ - SETVECT(4, XSD2 | XFIFO_3 | WS1); - /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */ - SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); - /* Slot 5: Send NOP low uint8_t to DAC0. */ - - /* Construct and transmit target DAC's serial packet: - * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the - * DAC channel's address, and D<7:0> is the DAC setpoint. Append a - * WORD value (that writes a channel 0 NOP command to a non-existent - * main DAC channel) that serves to keep the clock running after the - * packet has been sent to the target DAC. - */ - - /* Address the DAC channel within the trimdac device. */ - SendDAC(dev, ((uint32_t) chan << 8) - | (uint32_t) DacData); /* Include DAC setpoint data. */ -} - -/* Private helper function: Write setpoint to an application DAC channel. */ - -static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) -{ - register uint16_t signmask; - register uint32_t WSImage; - - /* Adjust DAC data polarity and set up Polarity Control Register */ - /* image. */ - signmask = 1 << chan; - if (dacdata < 0) { - dacdata = -dacdata; - devpriv->Dacpol |= signmask; - } else - devpriv->Dacpol &= ~signmask; - - /* Limit DAC setpoint value to valid range. */ - if ((uint16_t) dacdata > 0x1FFF) - dacdata = 0x1FFF; - - /* Set up TSL2 records (aka "vectors") for DAC update. Vectors V2 - * and V3 transmit the setpoint to the target DAC. V4 and V5 send - * data to a non-existent TrimDac channel just to keep the clock - * running after sending data to the target DAC. This is necessary - * to eliminate the clock glitch that would otherwise occur at the - * end of the target DAC's serial data stream. When the sequence - * restarts at V0 (after executing V5), the gate array automatically - * disables gating for the DAC clock and all DAC chip selects. - */ - - WSImage = (chan & 2) ? WS1 : WS2; - /* Choose DAC chip select to be asserted. */ - SETVECT(2, XSD2 | XFIFO_1 | WSImage); - /* Slot 2: Transmit high data byte to target DAC. */ - SETVECT(3, XSD2 | XFIFO_0 | WSImage); - /* Slot 3: Transmit low data byte to target DAC. */ - SETVECT(4, XSD2 | XFIFO_3 | WS3); - /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */ - SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); - /* Slot 5: running after writing target DAC's low data byte. */ - - /* Construct and transmit target DAC's serial packet: - * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, - * and D<12:0> is the DAC setpoint. Append a WORD value (that writes - * to a non-existent TrimDac channel) that serves to keep the clock - * running after the packet has been sent to the target DAC. - */ - SendDAC(dev, 0x0F000000 - /* Continue clock after target DAC data (write to non-existent trimdac). */ - | 0x00004000 - /* Address the two main dual-DAC devices (TSL's chip select enables - * target device). */ - | ((uint32_t) (chan & 1) << 15) - /* Address the DAC channel within the device. */ - | (uint32_t) dacdata); /* Include DAC setpoint data. */ - -} - -/* Private helper function: Transmit serial data to DAC via Audio - * channel 2. Assumes: (1) TSL2 slot records initialized, and (2) - * Dacpol contains valid target image. - */ - -static void SendDAC(struct comedi_device *dev, uint32_t val) -{ - - /* START THE SERIAL CLOCK RUNNING ------------- */ - - /* Assert DAC polarity control and enable gating of DAC serial clock - * and audio bit stream signals. At this point in time we must be - * assured of being in time slot 0. If we are not in slot 0, the - * serial clock and audio stream signals will be disabled; this is - * because the following DEBIwrite statement (which enables signals - * to be passed through the gate array) would execute before the - * trailing edge of WS1/WS3 (which turns off the signals), thus - * causing the signals to be inactive during the DAC write. - */ - DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol); - - /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */ - - /* Copy DAC setpoint value to DAC's output DMA buffer. */ - - /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */ - *devpriv->pDacWBuf = val; - - /* enab the output DMA transfer. This will cause the DMAC to copy - * the DAC's data value to A2's output FIFO. The DMA transfer will - * then immediately terminate because the protection address is - * reached upon transfer of the first DWORD value. - */ - MC_ENABLE(P_MC1, MC1_A2OUT); - - /* While the DMA transfer is executing ... */ - - /* Reset Audio2 output FIFO's underflow flag (along with any other - * FIFO underflow/overflow flags). When set, this flag will - * indicate that we have emerged from slot 0. - */ - WR7146(P_ISR, ISR_AFOU); - - /* Wait for the DMA transfer to finish so that there will be data - * available in the FIFO when time slot 1 tries to transfer a DWORD - * from the FIFO to the output buffer register. We test for DMA - * Done by polling the DMAC enable flag; this flag is automatically - * cleared when the transfer has finished. - */ - while ((RR7146(P_MC1) & MC1_A2OUT) != 0) - ; - - /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */ - - /* FIFO data is now available, so we enable execution of time slots - * 1 and higher by clearing the EOS flag in slot 0. Note that SD3 - * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list - * detection. - */ - SETVECT(0, XSD2 | RSD3 | SIB_A2); - - /* Wait for slot 1 to execute to ensure that the Packet will be - * transmitted. This is detected by polling the Audio2 output FIFO - * underflow flag, which will be set when slot 1 execution has - * finished transferring the DAC's data DWORD from the output FIFO - * to the output buffer register. - */ - while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) - ; - - /* Set up to trap execution at slot 0 when the TSL sequencer cycles - * back to slot 0 after executing the EOS in slot 5. Also, - * simultaneously shift out and in the 0x00 that is ALWAYS the value - * stored in the last byte to be shifted out of the FIFO's DWORD - * buffer register. - */ - SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS); - - /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */ - - /* Wait for the TSL to finish executing all time slots before - * exiting this function. We must do this so that the next DAC - * write doesn't start, thereby enabling clock/chip select signals: - * - * 1. Before the TSL sequence cycles back to slot 0, which disables - * the clock/cs signal gating and traps slot // list execution. - * we have not yet finished slot 5 then the clock/cs signals are - * still gated and we have not finished transmitting the stream. - * - * 2. While slots 2-5 are executing due to a late slot 0 trap. In - * this case, the slot sequence is currently repeating, but with - * clock/cs signals disabled. We must wait for slot 0 to trap - * execution before setting up the next DAC setpoint DMA transfer - * and enabling the clock/cs signals. To detect the end of slot 5, - * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If - * the TSL has not yet finished executing slot 5 ... - */ - if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) { - /* The trap was set on time and we are still executing somewhere - * in slots 2-5, so we now wait for slot 0 to execute and trap - * TSL execution. This is detected when FB_BUFFER2 MSB changes - * from 0xFF to 0x00, which slot 0 causes to happen by shifting - * out/in on SD2 the 0x00 that is always referenced by slot 5. - */ - while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) - ; - } - /* Either (1) we were too late setting the slot 0 trap; the TSL - * sequencer restarted slot 0 before we could set the EOS trap flag, - * or (2) we were not late and execution is now trapped at slot 0. - * In either case, we must now change slot 0 so that it will store - * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes. - * In order to do this, we reprogram slot 0 so that it will shift in - * SD3, which is driven only by a pull-up resistor. - */ - SETVECT(0, RSD3 | SIB_A2 | EOS); - - /* Wait for slot 0 to execute, at which time the TSL is setup for - * the next DAC write. This is detected when FB_BUFFER2 MSB changes - * from 0x00 to 0xFF. - */ - while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) - ; -} - static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage) { DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); /* enab writes to */ -- GitLab From 6baffbc2a4a11d78325f338a5e4731207ab9ca7d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:26:11 -0700 Subject: [PATCH 2522/6849] staging: comedi: s626: remove forward declarations 5 Move the irq set/reset/clear and ns_to_timer helper functions up to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 224 +++++++++++++------------- 1 file changed, 109 insertions(+), 115 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 3cdb29323ca3..cc18bf06a243 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -207,12 +207,6 @@ static struct dio_private *dio_private_word[]={ #define devpriv ((struct s626_private *)dev->private) #define diopriv ((struct dio_private *)s->private) -static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan); -static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop, - unsigned int mask); -static int s626_dio_clear_irq(struct comedi_device *dev); -static int s626_ns_to_timer(int *nanosec, int round_mode); - /* COUNTER OBJECT ------------------------------------------------ */ struct enc_private { /* Pointers to functions that differ for A and B counters: */ @@ -803,6 +797,87 @@ static unsigned int s626_ai_reg_to_uint(int data) /* return 0; */ /* } */ +static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) +{ + unsigned int group; + unsigned int bitmask; + unsigned int status; + + /* select dio bank */ + group = chan / 16; + bitmask = 1 << (chan - (16 * group)); + DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n", + chan - (16 * group), group); + + /* set channel to capture positive edge */ + status = DEBIread(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->RDEdgSel); + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WREdgSel, + bitmask | status); + + /* enable interrupt on selected channel */ + status = DEBIread(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->RDIntSel); + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRIntSel, + bitmask | status); + + /* enable edge capture write command */ + DEBIwrite(dev, LP_MISC1, MISC1_EDCAP); + + /* enable edge capture on selected channel */ + status = DEBIread(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->RDCapSel); + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRCapSel, + bitmask | status); + + return 0; +} + +static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, + unsigned int mask) +{ + DEBUG + ("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", + mask, group); + + /* disable edge capture write command */ + DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); + + /* enable edge capture on selected channel */ + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRCapSel, mask); + + return 0; +} + +static int s626_dio_clear_irq(struct comedi_device *dev) +{ + unsigned int group; + + /* disable edge capture write command */ + DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); + + for (group = 0; group < S626_DIO_BANKS; group++) { + /* clear pending events and interrupt */ + DEBIwrite(dev, + ((struct dio_private *)(dev->subdevices + 2 + + group)->private)->WRCapSel, + 0xffff); + } + + return 0; +} + static irqreturn_t s626_irq_handler(int irq, void *d) { struct comedi_device *dev = d; @@ -1500,6 +1575,34 @@ static int s626_ai_inttrig(struct comedi_device *dev, return 1; } +/* This function doesn't require a particular form, this is just what + * happens to be used in some of the drivers. It should convert ns + * nanoseconds to a counter value suitable for programming the device. + * Also, it should adjust ns so that it cooresponds to the actual time + * that the device will use. */ +static int s626_ns_to_timer(int *nanosec, int round_mode) +{ + int divider, base; + + base = 500; /* 2MHz internal clock */ + + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + divider = (*nanosec + base / 2) / base; + break; + case TRIG_ROUND_DOWN: + divider = (*nanosec) / base; + break; + case TRIG_ROUND_UP: + divider = (*nanosec + base - 1) / base; + break; + } + + *nanosec = base * divider; + return divider - 1; +} + /* TO COMPLETE */ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1832,34 +1935,6 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -/* This function doesn't require a particular form, this is just what - * happens to be used in some of the drivers. It should convert ns - * nanoseconds to a counter value suitable for programming the device. - * Also, it should adjust ns so that it cooresponds to the actual time - * that the device will use. */ -static int s626_ns_to_timer(int *nanosec, int round_mode) -{ - int divider, base; - - base = 500; /* 2MHz internal clock */ - - switch (round_mode) { - case TRIG_ROUND_NEAREST: - default: - divider = (*nanosec + base / 2) / base; - break; - case TRIG_ROUND_DOWN: - divider = (*nanosec) / base; - break; - case TRIG_ROUND_UP: - divider = (*nanosec + base - 1) / base; - break; - } - - *nanosec = base * divider; - return divider - 1; -} - static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -1980,87 +2055,6 @@ static int s626_dio_insn_config(struct comedi_device *dev, return 1; } -static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) -{ - unsigned int group; - unsigned int bitmask; - unsigned int status; - - /* select dio bank */ - group = chan / 16; - bitmask = 1 << (chan - (16 * group)); - DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n", - chan - (16 * group), group); - - /* set channel to capture positive edge */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDEdgSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WREdgSel, - bitmask | status); - - /* enable interrupt on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDIntSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRIntSel, - bitmask | status); - - /* enable edge capture write command */ - DEBIwrite(dev, LP_MISC1, MISC1_EDCAP); - - /* enable edge capture on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDCapSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - bitmask | status); - - return 0; -} - -static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, - unsigned int mask) -{ - DEBUG - ("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", - mask, group); - - /* disable edge capture write command */ - DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - - /* enable edge capture on selected channel */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, mask); - - return 0; -} - -static int s626_dio_clear_irq(struct comedi_device *dev) -{ - unsigned int group; - - /* disable edge capture write command */ - DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - - for (group = 0; group < S626_DIO_BANKS; group++) { - /* clear pending events and interrupt */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - 0xffff); - } - - return 0; -} - /* Now this function initializes the value of the counter (data[0]) and set the subdevice. To complete with trigger and interrupt configuration */ -- GitLab From 878cf9547f7985dd260dec4a4247840ecb4ba225 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:26:31 -0700 Subject: [PATCH 2523/6849] staging: comedi: s626: remove forward declarations 6 Move the enc_private_data definition down to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 222 +++++++++++--------------- 1 file changed, 94 insertions(+), 128 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index cc18bf06a243..d7d72ac16457 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -233,36 +233,8 @@ struct enc_private { static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick); static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k); -static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k); -static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k); -static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k); -static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k); -static void SetMode_A(struct comedi_device *dev, struct enc_private *k, - uint16_t Setup, uint16_t DisableIntSrc); -static void SetMode_B(struct comedi_device *dev, struct enc_private *k, - uint16_t Setup, uint16_t DisableIntSrc); -static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, - uint16_t enab); -static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, - uint16_t enab); -static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k); -static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k); static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value); -static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, - uint16_t Trig); -static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, - uint16_t Trig); -static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k); -static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k); -static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k, - uint16_t IntSource); -static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, - uint16_t IntSource); -static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k); -static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k); -static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k); -static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k); static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value); @@ -276,106 +248,6 @@ static void Preload(struct comedi_device *dev, struct enc_private *k, /* Translation table to map IntSrc into equivalent RDMISC2 event flag bits. */ /* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */ -/* struct enc_private; */ -static struct enc_private enc_private_data[] = { - { - .GetEnable = GetEnable_A, - .GetIntSrc = GetIntSrc_A, - .GetLoadTrig = GetLoadTrig_A, - .GetMode = GetMode_A, - .PulseIndex = PulseIndex_A, - .SetEnable = SetEnable_A, - .SetIntSrc = SetIntSrc_A, - .SetLoadTrig = SetLoadTrig_A, - .SetMode = SetMode_A, - .ResetCapFlags = ResetCapFlags_A, - .MyCRA = LP_CR0A, - .MyCRB = LP_CR0B, - .MyLatchLsw = LP_CNTR0ALSW, - .MyEventBits = EVBITS(0), - }, - { - .GetEnable = GetEnable_A, - .GetIntSrc = GetIntSrc_A, - .GetLoadTrig = GetLoadTrig_A, - .GetMode = GetMode_A, - .PulseIndex = PulseIndex_A, - .SetEnable = SetEnable_A, - .SetIntSrc = SetIntSrc_A, - .SetLoadTrig = SetLoadTrig_A, - .SetMode = SetMode_A, - .ResetCapFlags = ResetCapFlags_A, - .MyCRA = LP_CR1A, - .MyCRB = LP_CR1B, - .MyLatchLsw = LP_CNTR1ALSW, - .MyEventBits = EVBITS(1), - }, - { - .GetEnable = GetEnable_A, - .GetIntSrc = GetIntSrc_A, - .GetLoadTrig = GetLoadTrig_A, - .GetMode = GetMode_A, - .PulseIndex = PulseIndex_A, - .SetEnable = SetEnable_A, - .SetIntSrc = SetIntSrc_A, - .SetLoadTrig = SetLoadTrig_A, - .SetMode = SetMode_A, - .ResetCapFlags = ResetCapFlags_A, - .MyCRA = LP_CR2A, - .MyCRB = LP_CR2B, - .MyLatchLsw = LP_CNTR2ALSW, - .MyEventBits = EVBITS(2), - }, - { - .GetEnable = GetEnable_B, - .GetIntSrc = GetIntSrc_B, - .GetLoadTrig = GetLoadTrig_B, - .GetMode = GetMode_B, - .PulseIndex = PulseIndex_B, - .SetEnable = SetEnable_B, - .SetIntSrc = SetIntSrc_B, - .SetLoadTrig = SetLoadTrig_B, - .SetMode = SetMode_B, - .ResetCapFlags = ResetCapFlags_B, - .MyCRA = LP_CR0A, - .MyCRB = LP_CR0B, - .MyLatchLsw = LP_CNTR0BLSW, - .MyEventBits = EVBITS(3), - }, - { - .GetEnable = GetEnable_B, - .GetIntSrc = GetIntSrc_B, - .GetLoadTrig = GetLoadTrig_B, - .GetMode = GetMode_B, - .PulseIndex = PulseIndex_B, - .SetEnable = SetEnable_B, - .SetIntSrc = SetIntSrc_B, - .SetLoadTrig = SetLoadTrig_B, - .SetMode = SetMode_B, - .ResetCapFlags = ResetCapFlags_B, - .MyCRA = LP_CR1A, - .MyCRB = LP_CR1B, - .MyLatchLsw = LP_CNTR1BLSW, - .MyEventBits = EVBITS(4), - }, - { - .GetEnable = GetEnable_B, - .GetIntSrc = GetIntSrc_B, - .GetLoadTrig = GetLoadTrig_B, - .GetMode = GetMode_B, - .PulseIndex = PulseIndex_B, - .SetEnable = SetEnable_B, - .SetIntSrc = SetIntSrc_B, - .SetLoadTrig = SetLoadTrig_B, - .SetMode = SetMode_B, - .ResetCapFlags = ResetCapFlags_B, - .MyCRA = LP_CR2A, - .MyCRB = LP_CR2B, - .MyLatchLsw = LP_CNTR2BLSW, - .MyEventBits = EVBITS(5), - }, -}; - /* enab/disable a function or test status bit(s) that are accessed */ /* through Main Control Registers 1 or 2. */ #define MC_ENABLE(REGADRS, CTRLWORD) writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS)) @@ -2681,6 +2553,100 @@ static void Preload(struct comedi_device *dev, struct enc_private *k, (uint16_t) (value >> 16)); } +static struct enc_private enc_private_data[] = { + { + .GetEnable = GetEnable_A, + .GetIntSrc = GetIntSrc_A, + .GetLoadTrig = GetLoadTrig_A, + .GetMode = GetMode_A, + .PulseIndex = PulseIndex_A, + .SetEnable = SetEnable_A, + .SetIntSrc = SetIntSrc_A, + .SetLoadTrig = SetLoadTrig_A, + .SetMode = SetMode_A, + .ResetCapFlags = ResetCapFlags_A, + .MyCRA = LP_CR0A, + .MyCRB = LP_CR0B, + .MyLatchLsw = LP_CNTR0ALSW, + .MyEventBits = EVBITS(0), + }, { + .GetEnable = GetEnable_A, + .GetIntSrc = GetIntSrc_A, + .GetLoadTrig = GetLoadTrig_A, + .GetMode = GetMode_A, + .PulseIndex = PulseIndex_A, + .SetEnable = SetEnable_A, + .SetIntSrc = SetIntSrc_A, + .SetLoadTrig = SetLoadTrig_A, + .SetMode = SetMode_A, + .ResetCapFlags = ResetCapFlags_A, + .MyCRA = LP_CR1A, + .MyCRB = LP_CR1B, + .MyLatchLsw = LP_CNTR1ALSW, + .MyEventBits = EVBITS(1), + }, { + .GetEnable = GetEnable_A, + .GetIntSrc = GetIntSrc_A, + .GetLoadTrig = GetLoadTrig_A, + .GetMode = GetMode_A, + .PulseIndex = PulseIndex_A, + .SetEnable = SetEnable_A, + .SetIntSrc = SetIntSrc_A, + .SetLoadTrig = SetLoadTrig_A, + .SetMode = SetMode_A, + .ResetCapFlags = ResetCapFlags_A, + .MyCRA = LP_CR2A, + .MyCRB = LP_CR2B, + .MyLatchLsw = LP_CNTR2ALSW, + .MyEventBits = EVBITS(2), + }, { + .GetEnable = GetEnable_B, + .GetIntSrc = GetIntSrc_B, + .GetLoadTrig = GetLoadTrig_B, + .GetMode = GetMode_B, + .PulseIndex = PulseIndex_B, + .SetEnable = SetEnable_B, + .SetIntSrc = SetIntSrc_B, + .SetLoadTrig = SetLoadTrig_B, + .SetMode = SetMode_B, + .ResetCapFlags = ResetCapFlags_B, + .MyCRA = LP_CR0A, + .MyCRB = LP_CR0B, + .MyLatchLsw = LP_CNTR0BLSW, + .MyEventBits = EVBITS(3), + }, { + .GetEnable = GetEnable_B, + .GetIntSrc = GetIntSrc_B, + .GetLoadTrig = GetLoadTrig_B, + .GetMode = GetMode_B, + .PulseIndex = PulseIndex_B, + .SetEnable = SetEnable_B, + .SetIntSrc = SetIntSrc_B, + .SetLoadTrig = SetLoadTrig_B, + .SetMode = SetMode_B, + .ResetCapFlags = ResetCapFlags_B, + .MyCRA = LP_CR1A, + .MyCRB = LP_CR1B, + .MyLatchLsw = LP_CNTR1BLSW, + .MyEventBits = EVBITS(4), + }, { + .GetEnable = GetEnable_B, + .GetIntSrc = GetIntSrc_B, + .GetLoadTrig = GetLoadTrig_B, + .GetMode = GetMode_B, + .PulseIndex = PulseIndex_B, + .SetEnable = SetEnable_B, + .SetIntSrc = SetIntSrc_B, + .SetLoadTrig = SetLoadTrig_B, + .SetMode = SetMode_B, + .ResetCapFlags = ResetCapFlags_B, + .MyCRA = LP_CR2A, + .MyCRB = LP_CR2B, + .MyLatchLsw = LP_CNTR2BLSW, + .MyEventBits = EVBITS(5), + }, +}; + static void CountersInit(struct comedi_device *dev) { int chan; -- GitLab From e3eb08d0f91ff6afab323fa5e3342f3c4a3e4a73 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:26:56 -0700 Subject: [PATCH 2524/6849] staging: comedi: s626: remove forward declarations 7 Move up the remaining functions needed to remove the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 185 ++++++++++++-------------- 1 file changed, 85 insertions(+), 100 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index d7d72ac16457..50656a78b263 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -230,16 +230,6 @@ struct enc_private { #define encpriv ((struct enc_private *)(dev->subdevices+5)->private) -static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, - int tick); -static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k); -static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, - uint16_t value); -static void Preload(struct comedi_device *dev, struct enc_private *k, - uint32_t value); - -/* Counter objects constructor. */ - /* Counter overflow/index event flag masks for RDMISC2. */ #define INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4))) #define OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10))) @@ -652,6 +642,57 @@ static void LoadTrimDACs(struct comedi_device *dev) WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i])); } +/* ****** COUNTER FUNCTIONS ******* */ +/* All counter functions address a specific counter by means of the + * "Counter" argument, which is a logical counter number. The Counter + * argument may have any of the following legal values: 0=0A, 1=1A, + * 2=2A, 3=0B, 4=1B, 5=2B. + */ + +/* Read a counter's output latch. */ +static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) +{ + register uint32_t value; + /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */ + + /* Latch counts and fetch LSW of latched counts value. */ + value = (uint32_t) DEBIread(dev, k->MyLatchLsw); + + /* Fetch MSW of latched counts and combine with LSW. */ + value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16); + + /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */ + + /* Return latched counts. */ + return value; +} + +/* Return/set a counter pair's latch trigger source. 0: On read + * access, 1: A index latches A, 2: B index latches B, 3: A overflow + * latches B. + */ +static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, + uint16_t value) +{ + DEBUG("SetLatchSource: SetLatchSource enter 3550\n"); + DEBIreplace(dev, k->MyCRB, + (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)), + (uint16_t) (value << CRBBIT_LATCHSRC)); + + DEBUG("SetLatchSource: SetLatchSource exit\n"); +} + +/* Write value into counter preload register. */ +static void Preload(struct comedi_device *dev, struct enc_private *k, + uint32_t value) +{ + DEBUG("Preload: preload enter\n"); + DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */ + DEBUG("Preload: preload step 1\n"); + DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2), + (uint16_t) (value >> 16)); +} + static unsigned int s626_ai_reg_to_uint(int data) { unsigned int tempdata; @@ -1475,6 +1516,40 @@ static int s626_ns_to_timer(int *nanosec, int round_mode) return divider - 1; } +static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, + int tick) +{ + uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ + /* index. */ + (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ + (CLKSRC_TIMER << BF_CLKSRC) | /* Operating mode is Timer. */ + (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ + (CNTDIR_DOWN << BF_CLKPOL) | /* Count direction is Down. */ + (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ + (CLKENAB_INDEX << BF_CLKENAB); + uint16_t valueSrclatch = LATCHSRC_A_INDXA; + /* uint16_t enab=CLKENAB_ALWAYS; */ + + k->SetMode(dev, k, Setup, FALSE); + + /* Set the preload register */ + Preload(dev, k, tick); + + /* Software index pulse forces the preload register to load */ + /* into the counter */ + k->SetLoadTrig(dev, k, 0); + k->PulseIndex(dev, k); + + /* set reload on counter overflow */ + k->SetLoadTrig(dev, k, 1); + + /* set interrupt on overflow */ + k->SetIntSrc(dev, k, INTSRC_OVER); + + SetLatchSource(dev, k, valueSrclatch); + /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */ +} + /* TO COMPLETE */ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -2004,40 +2079,6 @@ static int s626_enc_insn_write(struct comedi_device *dev, return 1; } -static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, - int tick) -{ - uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */ - /* index. */ - (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */ - (CLKSRC_TIMER << BF_CLKSRC) | /* Operating mode is Timer. */ - (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */ - (CNTDIR_DOWN << BF_CLKPOL) | /* Count direction is Down. */ - (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */ - (CLKENAB_INDEX << BF_CLKENAB); - uint16_t valueSrclatch = LATCHSRC_A_INDXA; - /* uint16_t enab=CLKENAB_ALWAYS; */ - - k->SetMode(dev, k, Setup, FALSE); - - /* Set the preload register */ - Preload(dev, k, tick); - - /* Software index pulse forces the preload register to load */ - /* into the counter */ - k->SetLoadTrig(dev, k, 0); - k->PulseIndex(dev, k); - - /* set reload on counter overflow */ - k->SetLoadTrig(dev, k, 1); - - /* set interrupt on overflow */ - k->SetIntSrc(dev, k, INTSRC_OVER); - - SetLatchSource(dev, k, valueSrclatch); - /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */ -} - static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage) { DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); /* enab writes to */ @@ -2069,36 +2110,8 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, } } -/* ****** COUNTER FUNCTIONS ******* */ -/* All counter functions address a specific counter by means of the - * "Counter" argument, which is a logical counter number. The Counter - * argument may have any of the following legal values: 0=0A, 1=1A, - * 2=2A, 3=0B, 4=1B, 5=2B. - */ - -/* Forward declarations for functions that are common to both A and B counters: */ - /* ****** PRIVATE COUNTER FUNCTIONS ****** */ -/* Read a counter's output latch. */ - -static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) -{ - register uint32_t value; - /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */ - - /* Latch counts and fetch LSW of latched counts value. */ - value = (uint32_t) DEBIread(dev, k->MyLatchLsw); - - /* Fetch MSW of latched counts and combine with LSW. */ - value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16); - - /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */ - - /* Return latched counts. */ - return value; -} - /* Reset a counter's index and overflow event capture flags. */ static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k) @@ -2348,22 +2361,6 @@ static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k) return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1; } -/* Return/set a counter pair's latch trigger source. 0: On read - * access, 1: A index latches A, 2: B index latches B, 3: A overflow - * latches B. - */ - -static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, - uint16_t value) -{ - DEBUG("SetLatchSource: SetLatchSource enter 3550\n"); - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)), - (uint16_t) (value << CRBBIT_LATCHSRC)); - - DEBUG("SetLatchSource: SetLatchSource exit\n"); -} - /* * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ) * { @@ -2541,18 +2538,6 @@ static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k) DEBIwrite(dev, k->MyCRB, crb); } -/* Write value into counter preload register. */ - -static void Preload(struct comedi_device *dev, struct enc_private *k, - uint32_t value) -{ - DEBUG("Preload: preload enter\n"); - DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */ - DEBUG("Preload: preload step 1\n"); - DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2), - (uint16_t) (value >> 16)); -} - static struct enc_private enc_private_data[] = { { .GetEnable = GetEnable_A, -- GitLab From bdf5aa39f7a42fc49903d456baaba11efc4d4243 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:27:25 -0700 Subject: [PATCH 2525/6849] staging: comedi: s626: remove private DEBUG macro The private DEBUG macro defined in this driver outputs a lot of function tracing noise. This information might be useful when first developing the driver but should not be in the mainlined code. If any of this is needed in the future it should be added back using the proper dev_printk interface. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 209 +------------------------- drivers/staging/comedi/drivers/s626.h | 6 - 2 files changed, 3 insertions(+), 212 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 50656a78b263..779ae7a104f6 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -376,7 +376,6 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) /* Byte1 = EEPROM internal target address. */ | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ /* Abort function and declare error if handshake failed. */ - DEBUG("I2Cread: error handshake I2Cread a\n"); return 0; } /* Execute EEPROM read. */ @@ -394,7 +393,6 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) |I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */ /* Abort function and declare error if handshake failed. */ - DEBUG("I2Cread: error handshake I2Cread b\n"); return 0; } /* Return copy of EEPROM value. */ @@ -653,7 +651,6 @@ static void LoadTrimDACs(struct comedi_device *dev) static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) { register uint32_t value; - /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */ /* Latch counts and fetch LSW of latched counts value. */ value = (uint32_t) DEBIread(dev, k->MyLatchLsw); @@ -661,8 +658,6 @@ static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) /* Fetch MSW of latched counts and combine with LSW. */ value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16); - /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */ - /* Return latched counts. */ return value; } @@ -674,21 +669,16 @@ static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k) static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value) { - DEBUG("SetLatchSource: SetLatchSource enter 3550\n"); DEBIreplace(dev, k->MyCRB, (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)), (uint16_t) (value << CRBBIT_LATCHSRC)); - - DEBUG("SetLatchSource: SetLatchSource exit\n"); } /* Write value into counter preload register. */ static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value) { - DEBUG("Preload: preload enter\n"); - DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */ - DEBUG("Preload: preload step 1\n"); + DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2), (uint16_t) (value >> 16)); } @@ -719,8 +709,6 @@ static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) /* select dio bank */ group = chan / 16; bitmask = 1 << (chan - (16 * group)); - DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n", - chan - (16 * group), group); /* set channel to capture positive edge */ status = DEBIread(dev, @@ -758,10 +746,6 @@ static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, unsigned int mask) { - DEBUG - ("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", - mask, group); - /* disable edge capture write command */ DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); @@ -805,8 +789,6 @@ static irqreturn_t s626_irq_handler(int irq, void *d) uint8_t group; uint16_t irqbit; - DEBUG("s626_irq_handler: interrupt request received!!!\n"); - if (dev->attached == 0) return IRQ_NONE; /* lock to avoid race with comedi_poll */ @@ -824,14 +806,8 @@ static irqreturn_t s626_irq_handler(int irq, void *d) /* clear interrupt */ writel(irqtype, devpriv->base_addr + P_ISR); - /* do somethings */ - DEBUG("s626_irq_handler: interrupt type %d\n", irqtype); - switch (irqtype) { case IRQ_RPS1: /* end_of_scan occurs */ - - DEBUG("s626_irq_handler: RPS1 irq detected\n"); - /* manage ai subdevice */ s = dev->subdevices; cmd = &(s->async->cmd); @@ -854,9 +830,6 @@ static irqreturn_t s626_irq_handler(int irq, void *d) if (cfc_write_to_buffer(s, tempdata) == 0) printk ("s626_irq_handler: cfc_write_to_buffer error!\n"); - - DEBUG("s626_irq_handler: ai channel %d acquired: %d\n", - i, tempdata); } /* end of scan occurs */ @@ -877,23 +850,12 @@ static irqreturn_t s626_irq_handler(int irq, void *d) irqstatus = 0; } - if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: enable interrupt on dio channel %d\n", - cmd->scan_begin_arg); - + if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) s626_dio_set_irq(dev, cmd->scan_begin_arg); - - DEBUG("s626_irq_handler: External trigger is set!!!\n"); - } /* tell comedi that data is there */ - DEBUG("s626_irq_handler: events %d\n", s->async->events); comedi_event(dev, s); break; case IRQ_GPIO3: /* check dio and conter interrupt */ - - DEBUG("s626_irq_handler: GPIO3 irq detected\n"); - /* manage ai subdevice */ s = dev->subdevices; cmd = &(s->async->cmd); @@ -913,36 +875,18 @@ static irqreturn_t s626_irq_handler(int irq, void *d) /* check if interrupt is generated from dio channels */ if (irqbit) { s626_dio_reset_irq(dev, group, irqbit); - DEBUG - ("s626_irq_handler: check interrupt on dio group %d %d\n", - group, i); if (devpriv->ai_cmd_running) { /* check if interrupt is an ai acquisition start trigger */ if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 && cmd->start_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: Edge capture interrupt received from channel %d\n", - cmd->start_arg); - /* Start executing the RPS program. */ MC_ENABLE(P_MC1, MC1_ERPS1); - DEBUG - ("s626_irq_handler: acquisition start triggered!!!\n"); - if (cmd->scan_begin_src == TRIG_EXT) { - DEBUG - ("s626_ai_cmd: enable interrupt on dio channel %d\n", - cmd-> - scan_begin_arg); - s626_dio_set_irq(dev, cmd->scan_begin_arg); - - DEBUG - ("s626_irq_handler: External scan trigger is set!!!\n"); } } if ((irqbit >> (cmd->scan_begin_arg - @@ -950,33 +894,16 @@ static irqreturn_t s626_irq_handler(int irq, void *d) == 1 && cmd->scan_begin_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: Edge capture interrupt received from channel %d\n", - cmd->scan_begin_arg); - /* Trigger ADC scan loop start by setting RPS Signal 0. */ MC_ENABLE(P_MC2, MC2_ADC_RPS); - DEBUG - ("s626_irq_handler: scan triggered!!! %d\n", - devpriv->ai_sample_count); if (cmd->convert_src == TRIG_EXT) { - - DEBUG - ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", - cmd->convert_arg - - (16 * group), - group); - devpriv->ai_convert_count = cmd->chanlist_len; s626_dio_set_irq(dev, cmd->convert_arg); - - DEBUG - ("s626_irq_handler: External convert trigger is set!!!\n"); } if (cmd->convert_src == @@ -992,32 +919,15 @@ static irqreturn_t s626_irq_handler(int irq, void *d) (16 * group))) == 1 && cmd->convert_src == TRIG_EXT) { - DEBUG - ("s626_irq_handler: Edge capture interrupt received from channel %d\n", - cmd->convert_arg); - /* Trigger ADC scan loop start by setting RPS Signal 0. */ MC_ENABLE(P_MC2, MC2_ADC_RPS); - DEBUG - ("s626_irq_handler: adc convert triggered!!!\n"); - devpriv->ai_convert_count--; if (devpriv->ai_convert_count > 0) { - - DEBUG - ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", - cmd->convert_arg - - (16 * group), - group); - s626_dio_set_irq(dev, cmd->convert_arg); - - DEBUG - ("s626_irq_handler: External trigger is set!!!\n"); } } } @@ -1029,44 +939,31 @@ static irqreturn_t s626_irq_handler(int irq, void *d) irqbit = DEBIread(dev, LP_RDMISC2); /* check interrupt on counters */ - DEBUG("s626_irq_handler: check counters interrupt %d\n", - irqbit); - if (irqbit & IRQ_COINT1A) { - DEBUG - ("s626_irq_handler: interrupt on counter 1A overflow\n"); k = &encpriv[0]; /* clear interrupt capture flag */ k->ResetCapFlags(dev, k); } if (irqbit & IRQ_COINT2A) { - DEBUG - ("s626_irq_handler: interrupt on counter 2A overflow\n"); k = &encpriv[1]; /* clear interrupt capture flag */ k->ResetCapFlags(dev, k); } if (irqbit & IRQ_COINT3A) { - DEBUG - ("s626_irq_handler: interrupt on counter 3A overflow\n"); k = &encpriv[2]; /* clear interrupt capture flag */ k->ResetCapFlags(dev, k); } if (irqbit & IRQ_COINT1B) { - DEBUG - ("s626_irq_handler: interrupt on counter 1B overflow\n"); k = &encpriv[3]; /* clear interrupt capture flag */ k->ResetCapFlags(dev, k); } if (irqbit & IRQ_COINT2B) { - DEBUG - ("s626_irq_handler: interrupt on counter 2B overflow\n"); k = &encpriv[4]; /* clear interrupt capture flag */ @@ -1078,34 +975,23 @@ static irqreturn_t s626_irq_handler(int irq, void *d) k->SetEnable(dev, k, CLKENAB_INDEX); if (cmd->convert_src == TRIG_TIMER) { - DEBUG - ("s626_irq_handler: conver timer trigger!!! %d\n", - devpriv->ai_convert_count); - /* Trigger ADC scan loop start by setting RPS Signal 0. */ MC_ENABLE(P_MC2, MC2_ADC_RPS); } } } if (irqbit & IRQ_COINT3B) { - DEBUG - ("s626_irq_handler: interrupt on counter 3B overflow\n"); k = &encpriv[5]; /* clear interrupt capture flag */ k->ResetCapFlags(dev, k); if (cmd->scan_begin_src == TRIG_TIMER) { - DEBUG - ("s626_irq_handler: scan timer trigger!!!\n"); - /* Trigger ADC scan loop start by setting RPS Signal 0. */ MC_ENABLE(P_MC2, MC2_ADC_RPS); } if (cmd->convert_src == TRIG_TIMER) { - DEBUG - ("s626_irq_handler: convert timer trigger is set\n"); k = &encpriv[4]; devpriv->ai_convert_count = cmd->chanlist_len; k->SetEnable(dev, k, CLKENAB_ALWAYS); @@ -1116,8 +1002,6 @@ static irqreturn_t s626_irq_handler(int irq, void *d) /* enable interrupt */ writel(irqstatus, devpriv->base_addr + P_IER); - DEBUG("s626_irq_handler: exit interrupt service routine.\n"); - spin_unlock_irqrestore(&dev->spinlock, flags); return IRQ_HANDLED; } @@ -1146,7 +1030,6 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) /* Construct RPS program in RPSBuf DMA buffer */ if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) { - DEBUG("ResetADC: scan_begin pause inserted\n"); /* Wait for Start trigger. */ *pRPS++ = RPS_PAUSE | RPS_SIGADC; *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC; @@ -1236,7 +1119,6 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) } if (cmd != NULL && cmd->convert_src != TRIG_NOW) { - DEBUG("ResetADC: convert pause inserted\n"); /* Wait for Start trigger. */ *pRPS++ = RPS_PAUSE | RPS_SIGADC; *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC; @@ -1268,7 +1150,6 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) break; /* Exit poll list processing loop. */ } } - DEBUG("ResetADC: ADC items %d\n", devpriv->AdcItems); /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the * ADC to stabilize for 2 microseconds before starting the final @@ -1305,7 +1186,6 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) /* invoke interrupt */ if (devpriv->ai_cmd_running == 1) { - DEBUG("ResetADC: insert irq in ADC RPS task\n"); *pRPS++ = RPS_IRQ; } /* Restart RPS program at its beginning. */ @@ -1329,8 +1209,6 @@ static int s626_ai_insn_config(struct comedi_device *dev, /* register uint8_t i; */ /* register int32_t *readaddr; */ -/* DEBUG("as626_ai_rinsn: ai_rinsn enter\n"); */ - /* Trigger ADC scan loop start by setting RPS Signal 0. */ /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ @@ -1346,11 +1224,9 @@ static int s626_ai_insn_config(struct comedi_device *dev, /* Convert ADC data to 16-bit integer values and copy to application buffer. */ /* for ( i = 0; i < devpriv->AdcItems; i++ ) { */ /* *data = s626_ai_reg_to_uint( *readaddr++ ); */ -/* DEBUG("s626_ai_rinsn: data %d\n",*data); */ /* data++; */ /* } */ -/* DEBUG("s626_ai_rinsn: ai_rinsn escape\n"); */ /* return i; */ /* } */ @@ -1370,8 +1246,6 @@ static int s626_ai_insn_read(struct comedi_device *dev, * corresponding interrupt to be generated if enabled */ - DEBUG("s626_ai_insn_read: entering\n"); - /* Convert application's ADC specification into form * appropriate for register programming. */ @@ -1448,8 +1322,6 @@ static int s626_ai_insn_read(struct comedi_device *dev, if (n != 0) data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); - DEBUG("s626_ai_insn_read: samples %d, data %d\n", n, data[n - 1]); - return n; } @@ -1476,15 +1348,11 @@ static int s626_ai_inttrig(struct comedi_device *dev, if (trignum != 0) return -EINVAL; - DEBUG("s626_ai_inttrig: trigger adc start..."); - /* Start executing the RPS program. */ MC_ENABLE(P_MC1, MC1_ERPS1); s->async->inttrig = NULL; - DEBUG(" done\n"); - return 1; } @@ -1559,8 +1427,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct enc_private *k; int tick; - DEBUG("s626_ai_cmd: entering command function\n"); - if (devpriv->ai_cmd_running) { printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n", dev->minor); @@ -1580,12 +1446,8 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_cmd_running = 0; /* test if cmd is valid */ - if (cmd == NULL) { - DEBUG("s626_ai_cmd: NULL command\n"); + if (cmd == NULL) return -EINVAL; - } else { - DEBUG("s626_ai_cmd: command received!!!\n"); - } if (dev->irq == 0) { comedi_error(dev, @@ -1609,18 +1471,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* load timer value and enable interrupt */ s626_timer_load(dev, k, tick); k->SetEnable(dev, k, CLKENAB_ALWAYS); - - DEBUG("s626_ai_cmd: scan trigger timer is set with value %d\n", - tick); - break; case TRIG_EXT: /* set the digital line and interrupt for scan trigger */ if (cmd->start_src != TRIG_EXT) s626_dio_set_irq(dev, cmd->scan_begin_arg); - - DEBUG("s626_ai_cmd: External scan trigger is set!!!\n"); - break; } @@ -1636,19 +1491,12 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* load timer value and enable interrupt */ s626_timer_load(dev, k, tick); k->SetEnable(dev, k, CLKENAB_INDEX); - - DEBUG - ("s626_ai_cmd: convert trigger timer is set with value %d\n", - tick); break; case TRIG_EXT: /* set the digital line and interrupt for convert trigger */ if (cmd->scan_begin_src != TRIG_EXT && cmd->start_src == TRIG_EXT) s626_dio_set_irq(dev, cmd->convert_arg); - - DEBUG("s626_ai_cmd: External convert trigger is set!!!\n"); - break; } @@ -1675,15 +1523,12 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* Start executing the RPS program. */ MC_ENABLE(P_MC1, MC1_ERPS1); - DEBUG("s626_ai_cmd: ADC triggered\n"); s->async->inttrig = NULL; break; case TRIG_EXT: /* configure DIO channel for acquisition trigger */ s626_dio_set_irq(dev, cmd->start_arg); - DEBUG("s626_ai_cmd: External start trigger is set!!!\n"); - s->async->inttrig = NULL; break; case TRIG_INT: @@ -1694,8 +1539,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* enable interrupt */ writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); - DEBUG("s626_ai_cmd: command function terminated\n"); - return 0; } @@ -1938,7 +1781,6 @@ static void s626_dio_init(struct comedi_device *dev) DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */ /* to inactive state. */ } - DEBUG("s626_dio_init: DIO initialized\n"); } /* DIO devices are slightly special. Although it is possible to @@ -2023,8 +1865,6 @@ static int s626_enc_insn_config(struct comedi_device *dev, uint16_t enab = CLKENAB_ALWAYS; struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; - DEBUG("s626_enc_insn_config: encoder config\n"); - /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */ k->SetMode(dev, k, Setup, TRUE); @@ -2044,14 +1884,9 @@ static int s626_enc_insn_read(struct comedi_device *dev, int n; struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; - DEBUG("s626_enc_insn_read: encoder read channel %d\n", - CR_CHAN(insn->chanspec)); - for (n = 0; n < insn->n; n++) data[n] = ReadLatch(dev, k); - DEBUG("s626_enc_insn_read: encoder sample %d\n", data[n]); - return n; } @@ -2062,9 +1897,6 @@ static int s626_enc_insn_write(struct comedi_device *dev, struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)]; - DEBUG("s626_enc_insn_write: encoder write channel %d\n", - CR_CHAN(insn->chanspec)); - /* Set the preload register */ Preload(dev, k, data[0]); @@ -2074,8 +1906,6 @@ static int s626_enc_insn_write(struct comedi_device *dev, k->PulseIndex(dev, k); k->SetLoadTrig(dev, k, 2); - DEBUG("s626_enc_insn_write: End encoder write\n"); - return 1; } @@ -2093,7 +1923,6 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, void *vbptr; dma_addr_t vpptr; - DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n"); if (pdma == NULL) return; /* find the matching allocation from the board struct */ @@ -2104,9 +1933,6 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr); pdma->LogicalBase = NULL; pdma->PhysicalBase = 0; - - DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n", - vbptr, bsize, (uint32_t) vpptr); } } @@ -2337,7 +2163,6 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k, static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab) { - DEBUG("SetEnable_A: SetEnable_A enter 3541\n"); DEBIreplace(dev, k->MyCRB, (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), (uint16_t) (enab << CRBBIT_CLKENAB_A)); @@ -2506,7 +2331,6 @@ static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k) /* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */ /* { */ -/* DEBUG("SetIndexSrc: set index src enter 3700\n"); */ /* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */ /* } */ @@ -2521,11 +2345,8 @@ static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k) { register uint16_t cra; - DEBUG("PulseIndex_A: pulse index enter\n"); - cra = DEBIread(dev, k->MyCRA); /* Pulse index. */ DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A)); - DEBUG("PulseIndex_A: pulse index step1\n"); DEBIwrite(dev, k->MyCRA, cra); } @@ -2653,8 +2474,6 @@ static void CountersInit(struct comedi_device *dev) k->ResetCapFlags(dev, k); k->SetEnable(dev, k, CLKENAB_ALWAYS); } - DEBUG("CountersInit: counters initialized\n"); - } static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -2722,7 +2541,6 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); /* DMA FIXME DMA// */ - DEBUG("s626_attach: DMA ALLOCATION\n"); /* adc buffer allocation */ devpriv->allocatedBuf = 0; @@ -2737,11 +2555,6 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->ANABuf.PhysicalBase = appdma; - DEBUG - ("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n", - devpriv->ANABuf.LogicalBase, DMABUF_SIZE, - (uint32_t) devpriv->ANABuf.PhysicalBase); - devpriv->allocatedBuf++; devpriv->RPSBuf.LogicalBase = @@ -2754,11 +2567,6 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->RPSBuf.PhysicalBase = appdma; - DEBUG - ("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n", - devpriv->RPSBuf.LogicalBase, DMABUF_SIZE, - (uint32_t) devpriv->RPSBuf.PhysicalBase); - devpriv->allocatedBuf++; } @@ -2786,9 +2594,6 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - DEBUG("s626_attach: -- it opts %d,%d --\n", - it->options[0], it->options[1]); - s = dev->subdevices + 0; /* analog input subdevice */ dev->read_subdev = s; @@ -2887,11 +2692,6 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) | DEBI_CFG_INTEL); /* Intel-compatible */ /* local bus (DEBI */ /* never times out). */ - DEBUG("s626_attach: %d debi init -- %d\n", - DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | - DEBI_SWAP | DEBI_CFG_INTEL, - DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ | - DEBI_CFG_16Q); /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */ /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */ @@ -3128,9 +2928,6 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */ } - DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor, - (uint32_t) devpriv->base_addr); - return 1; } diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h index 2d1afecbbb60..82de03fb9c4c 100644 --- a/drivers/staging/comedi/drivers/s626.h +++ b/drivers/staging/comedi/drivers/s626.h @@ -62,12 +62,6 @@ comedi_do_insn(cf,&insn); // executing configuration */ -#ifdef _DEBUG_ -#define DEBUG(...); printk(__VA_ARGS__); -#else -#define DEBUG(...) -#endif - #if !defined(TRUE) #define TRUE (1) #endif -- GitLab From 90fd56af25b7835118657833a52bb4c85a911de7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:27:43 -0700 Subject: [PATCH 2526/6849] staging: comedi: s626: remove private INLINE macro The INLINE macro is not used in the code. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h index 82de03fb9c4c..179623634732 100644 --- a/drivers/staging/comedi/drivers/s626.h +++ b/drivers/staging/comedi/drivers/s626.h @@ -70,10 +70,6 @@ #define FALSE (0) #endif -#if !defined(INLINE) -#define INLINE static __inline -#endif - #include #define S626_SIZE 0x0200 -- GitLab From 9c1f1f12472c5b9808e4465cdf882892b19f2f10 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jun 2012 19:28:01 -0700 Subject: [PATCH 2527/6849] staging: comedi: s626: factor out the find PCI device code Factor out the code that finds a matching PCI device from attach function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 54 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 779ae7a104f6..bef9649960b8 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2476,6 +2476,35 @@ static void CountersInit(struct comedi_device *dev) } } +static struct pci_dev *s626_find_pci(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + int i; + + for (i = 0; i < ARRAY_SIZE(s626_boards) && !pcidev; i++) { + do { + pcidev = pci_get_subsys(s626_boards[i].vendor_id, + s626_boards[i].device_id, + s626_boards[i].subvendor_id, + s626_boards[i].subdevice_id, + pcidev); + + if ((bus || slot) && pcidev) { + /* matches requested bus/slot */ + if (pcidev->bus->number == bus && + PCI_SLOT(pcidev->devfn) == slot) + break; + } else { + break; + } + } while (1); + } + return pcidev; +} + static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) { /* uint8_t PollList; */ @@ -2489,36 +2518,17 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) resource_size_t resourceStart; dma_addr_t appdma; struct comedi_subdevice *s; - struct pci_dev *pdev = NULL; if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(s626_boards) && !pdev; i++) { - do { - pdev = pci_get_subsys(s626_boards[i].vendor_id, - s626_boards[i].device_id, - s626_boards[i].subvendor_id, - s626_boards[i].subdevice_id, - pdev); - - if ((it->options[0] || it->options[1]) && pdev) { - /* matches requested bus/slot */ - if (pdev->bus->number == it->options[0] && - PCI_SLOT(pdev->devfn) == it->options[1]) - break; - } else - break; - } while (1); - } - devpriv->pdev = pdev; - - if (pdev == NULL) { + devpriv->pdev = s626_find_pci(dev, it); + if (!devpriv->pdev) { printk(KERN_ERR "s626_attach: Board not present!!!\n"); return -ENODEV; } - result = comedi_pci_enable(pdev, "s626"); + result = comedi_pci_enable(devpriv->pdev, "s626"); if (result < 0) { printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n"); return -ENODEV; -- GitLab From 933045a221acab3b17f4e6e5c1c12d6bf87d68ec Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 22 Jun 2012 10:14:59 +0300 Subject: [PATCH 2528/6849] staging: comedi: double unlock in usbduxsigma_attach() There was a double unlock introduced in 60ff461067 ("staging: comedi: usbduxsigma: use attach_usb() hook"). Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 8da8c1cbb60a..543e604791e2 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2450,7 +2450,6 @@ static int usbduxsigma_attach(struct comedi_device *dev, if (index < 0) { dev_err(dev->class_dev, "usbduxsigma: error: attach failed, dev not connected to the usb bus.\n"); - up(&start_stop_sem); ret = -ENODEV; } else ret = usbduxsigma_attach_common(dev, &usbduxsub[index], -- GitLab From 088dc173a1ca029b1ec239bb4b3dec0da03242c5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:12:42 -0700 Subject: [PATCH 2529/6849] staging: comedi: ni_daq_700: remove exported symbols This driver exports a number of functions with EXPORT_SYMBOL() but nothing actually uses them. They also are not declared in any header for use outside this module. As stated in the comments, this driver was based on the 8255 driver so these exports are most likely the result of cut-and- paste from the 8255 driver. Remove all the EXPORT_SYMBOL() lines. If the exported function is not used in the driver, remove the entire function as well. If the function is used, make it static. Also, make the dio700_cs_driver variable static since it's only referenced in this file. This quiets the following sparse warnings: warning: symbol 'subdev_700_interrupt' was not declared. Should it be static? warning: symbol 'subdev_700_init' was not declared. Should it be static? warning: symbol 'subdev_700_init_irq' was not declared. Should it be static? warning: symbol 'subdev_700_cleanup' was not declared. Should it be static? warning: symbol 'dio700_cs_driver' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 137 +------------------- 1 file changed, 7 insertions(+), 130 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 4b42809d87a7..fd1acf0c0e60 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -132,19 +132,6 @@ struct subdev_700_struct { static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); -void subdev_700_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) -{ - short d; - - d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG); - - comedi_buf_put(s->async, d); - s->async->events |= COMEDI_CB_EOS; - - comedi_event(dev, s); -} -EXPORT_SYMBOL(subdev_700_interrupt); - static int subdev_700_cb(int dir, int port, int data, unsigned long arg) { /* port is always A for output and B for input (8255 emu) */ @@ -206,99 +193,10 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) return; } -static int subdev_700_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - unsigned int tmp; - - /* step 1 */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_FOLLOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; - - if (err) - return 1; - - /* step 2 */ - - if (err) - return 2; - - /* step 3 */ - - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - - if (err) - return 3; - - /* step 4 */ - - if (err) - return 4; - - return 0; -} - -static int subdev_700_cmd(struct comedi_device *dev, struct comedi_subdevice *s) -{ - /* FIXME */ - - return 0; -} - -static int subdev_700_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - /* FIXME */ - - return 0; -} - -int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), unsigned long arg) +static int subdev_700_init(struct comedi_device *dev, + struct comedi_subdevice *s, + int (*cb) (int, int, int, unsigned long), + unsigned long arg) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -325,36 +223,15 @@ int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } -EXPORT_SYMBOL(subdev_700_init); - -int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) -{ - int ret; - - ret = subdev_700_init(dev, s, cb, arg); - if (ret < 0) - return ret; - - s->do_cmdtest = subdev_700_cmdtest; - s->do_cmd = subdev_700_cmd; - s->cancel = subdev_700_cancel; - - subdevpriv->have_irq = 1; - - return 0; -} -EXPORT_SYMBOL(subdev_700_init_irq); -void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) +static void subdev_700_cleanup(struct comedi_device *dev, + struct comedi_subdevice *s) { if (s->private) if (subdevpriv->have_irq) kfree(s->private); } -EXPORT_SYMBOL(subdev_700_cleanup); static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -556,7 +433,7 @@ MODULE_DESCRIPTION("Comedi driver for National Instruments " "PCMCIA DAQCard-700 DIO"); MODULE_LICENSE("GPL"); -struct pcmcia_driver dio700_cs_driver = { +static struct pcmcia_driver dio700_cs_driver = { .probe = dio700_cs_attach, .remove = dio700_cs_detach, .suspend = dio700_cs_suspend, -- GitLab From c0a97efc59c675e10390f61ba62ca2f0474c5206 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:13:00 -0700 Subject: [PATCH 2530/6849] staging: comedi: ni_daq_700: move the MODULE_* stuff to the EOF Move the MODULE_* declarations to the end of the file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index fd1acf0c0e60..e75bdd0850ac 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -428,10 +428,6 @@ static const struct pcmcia_device_id dio700_cs_ids[] = { MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); -MODULE_AUTHOR("Fred Brooks "); -MODULE_DESCRIPTION("Comedi driver for National Instruments " - "PCMCIA DAQCard-700 DIO"); -MODULE_LICENSE("GPL"); static struct pcmcia_driver dio700_cs_driver = { .probe = dio700_cs_attach, @@ -471,3 +467,8 @@ void __exit cleanup_module(void) exit_dio700_cs(); comedi_driver_unregister(&driver_dio700); } + +MODULE_AUTHOR("Fred Brooks "); +MODULE_DESCRIPTION( + "Comedi driver for National Instruments PCMCIA DAQCard-700 DIO"); +MODULE_LICENSE("GPL"); -- GitLab From 113f7021497e5203dec3fba05294a6f184852db9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:13:26 -0700 Subject: [PATCH 2531/6849] staging: comedi: ni_daq_700: add the module_{init, exit} declarations The init and exit functions for this module were being declared as global symbols. Add the module_{init,exit} declarations and make the functions static. Also, rename the functions so they have namespace associated with the module. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index e75bdd0850ac..052a05173447 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -451,7 +451,7 @@ static void __exit exit_dio700_cs(void) pcmcia_unregister_driver(&dio700_cs_driver); } -int __init init_module(void) +static int __init dio700_cs_init(void) { int ret; @@ -461,12 +461,14 @@ int __init init_module(void) return comedi_driver_register(&driver_dio700); } +module_init(dio700_cs_init); -void __exit cleanup_module(void) +static void __exit dio700_cs_exit(void) { exit_dio700_cs(); comedi_driver_unregister(&driver_dio700); } +module_exit(dio700_cs_exit); MODULE_AUTHOR("Fred Brooks "); MODULE_DESCRIPTION( -- GitLab From 5fe9b247cc5dd6d39d9252fc0b51700e438a65fd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:14:30 -0700 Subject: [PATCH 2532/6849] staging: comedi: ni_daq_700: consolidate the init and exit functions The register/unregister of the pcmcia driver is done is separate functions that are called by the module_{init,exit} routines. Simplify the code a bit by moving the register/unregister into the module_{init,exit} routines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 052a05173447..b06792b3a70c 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -439,23 +439,11 @@ static struct pcmcia_driver dio700_cs_driver = { .name = "ni_daq_700", }; -static int __init init_dio700_cs(void) -{ - pcmcia_register_driver(&dio700_cs_driver); - return 0; -} - -static void __exit exit_dio700_cs(void) -{ - pr_debug("ni_daq_700: unloading\n"); - pcmcia_unregister_driver(&dio700_cs_driver); -} - static int __init dio700_cs_init(void) { int ret; - ret = init_dio700_cs(); + ret = pcmcia_register_driver(&dio700_cs_driver); if (ret < 0) return ret; @@ -465,7 +453,7 @@ module_init(dio700_cs_init); static void __exit dio700_cs_exit(void) { - exit_dio700_cs(); + pcmcia_unregister_driver(&dio700_cs_driver); comedi_driver_unregister(&driver_dio700); } module_exit(dio700_cs_exit); -- GitLab From f90398294753b3f88570af1c2a68032f6ae6bfbe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:15:16 -0700 Subject: [PATCH 2533/6849] staging: comedi: ni_daq_700: change driver registration order As done with the other comedi driver types, register the comedi_driver first then the pcmcia_driver. Also, make sure the pcmcia_driver registration succeeds and unregister the comedi_driver it it fails. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index b06792b3a70c..af4f10fd15df 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -443,11 +443,17 @@ static int __init dio700_cs_init(void) { int ret; - ret = pcmcia_register_driver(&dio700_cs_driver); + ret = comedi_driver_register(&driver_dio700); if (ret < 0) return ret; - return comedi_driver_register(&driver_dio700); + ret = pcmcia_register_driver(&dio700_cs_driver); + if (ret < 0) { + comedi_driver_unregister(&driver_dio700); + return ret; + } + + return 0; } module_init(dio700_cs_init); -- GitLab From 2f485d93cb6f870f2f19fb9a18656a372583eab1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:16:00 -0700 Subject: [PATCH 2534/6849] staging: comedi: ni_daq_700: cleanup to the pcmcia_driver declaration For aesthetic reasons, add some whitespace to the declaration of the pcmcia_driver and reorder it a bit. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index af4f10fd15df..30eeb9d1c842 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -430,13 +430,13 @@ static const struct pcmcia_device_id dio700_cs_ids[] = { MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); static struct pcmcia_driver dio700_cs_driver = { - .probe = dio700_cs_attach, - .remove = dio700_cs_detach, - .suspend = dio700_cs_suspend, - .resume = dio700_cs_resume, - .id_table = dio700_cs_ids, - .owner = THIS_MODULE, - .name = "ni_daq_700", + .name = "ni_daq_700", + .owner = THIS_MODULE, + .probe = dio700_cs_attach, + .remove = dio700_cs_detach, + .suspend = dio700_cs_suspend, + .resume = dio700_cs_resume, + .id_table = dio700_cs_ids, }; static int __init dio700_cs_init(void) -- GitLab From 59c9c00234fbadc8c479c89ec517e2e4f964029c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:16:41 -0700 Subject: [PATCH 2535/6849] staging: comedi: ni_daq_700: remove some useless comments Remove some useless comments and whitespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 30eeb9d1c842..1059297fd9fb 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -111,8 +111,6 @@ static struct comedi_driver driver_dio700 = { .offset = sizeof(struct dio700_board), }; -/* the real driver routines */ - #define _700_SIZE 8 #define _700_DATA 0 @@ -342,7 +340,7 @@ static int dio700_cs_attach(struct pcmcia_device *link) dio700_config(link); return 0; -} /* dio700_cs_attach */ +} static void dio700_cs_detach(struct pcmcia_device *link) { @@ -392,14 +390,14 @@ failed: printk(KERN_INFO "ni_daq_700 cs failed"); dio700_release(link); -} /* dio700_config */ +} static void dio700_release(struct pcmcia_device *link) { dev_dbg(&link->dev, "dio700_release\n"); pcmcia_disable_device(link); -} /* dio700_release */ +} static int dio700_cs_suspend(struct pcmcia_device *link) { @@ -408,7 +406,7 @@ static int dio700_cs_suspend(struct pcmcia_device *link) /* Mark the device as stopped, to block IO until later */ local->stop = 1; return 0; -} /* dio700_cs_suspend */ +} static int dio700_cs_resume(struct pcmcia_device *link) { @@ -416,17 +414,12 @@ static int dio700_cs_resume(struct pcmcia_device *link) local->stop = 0; return 0; -} /* dio700_cs_resume */ - -/*====================================================================*/ +} static const struct pcmcia_device_id dio700_cs_ids[] = { - /* N.B. These IDs should match those in dio700_boards */ - PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), /* daqcard-700 */ + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), PCMCIA_DEVICE_NULL }; - - MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); static struct pcmcia_driver dio700_cs_driver = { -- GitLab From 1a4d5b17c331b7a086a49720b1d7911caa075e3b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:17:20 -0700 Subject: [PATCH 2536/6849] staging: comedi: ni_daq_700: refactor the pcmcia support code Refactor the pcmcia support code to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 80 ++++++++++----------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 1059297fd9fb..f9b0d67024fc 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -306,49 +306,11 @@ static void dio700_detach(struct comedi_device *dev) free_irq(dev->irq, dev); }; -static void dio700_config(struct pcmcia_device *link); -static void dio700_release(struct pcmcia_device *link); -static int dio700_cs_suspend(struct pcmcia_device *p_dev); -static int dio700_cs_resume(struct pcmcia_device *p_dev); - -static int dio700_cs_attach(struct pcmcia_device *); -static void dio700_cs_detach(struct pcmcia_device *); - -struct local_info_t { - struct pcmcia_device *link; - int stop; - struct bus_operations *bus; -}; - -static int dio700_cs_attach(struct pcmcia_device *link) -{ - struct local_info_t *local; - - printk(KERN_INFO "ni_daq_700: cs-attach\n"); - - dev_dbg(&link->dev, "dio700_cs_attach()\n"); - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); - if (!local) - return -ENOMEM; - local->link = link; - link->priv = local; - - pcmcia_cur_dev = link; - - dio700_config(link); - - return 0; -} - -static void dio700_cs_detach(struct pcmcia_device *link) +static void dio700_release(struct pcmcia_device *link) { - ((struct local_info_t *)link->priv)->stop = 1; - dio700_release(link); + dev_dbg(&link->dev, "dio700_release\n"); - /* This points to the parent struct local_info_t struct */ - kfree(link->priv); + pcmcia_disable_device(link); } static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, @@ -392,11 +354,41 @@ failed: } -static void dio700_release(struct pcmcia_device *link) +struct local_info_t { + struct pcmcia_device *link; + int stop; + struct bus_operations *bus; +}; + +static int dio700_cs_attach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "dio700_release\n"); + struct local_info_t *local; - pcmcia_disable_device(link); + printk(KERN_INFO "ni_daq_700: cs-attach\n"); + + dev_dbg(&link->dev, "dio700_cs_attach()\n"); + + /* Allocate space for private device-specific data */ + local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); + if (!local) + return -ENOMEM; + local->link = link; + link->priv = local; + + pcmcia_cur_dev = link; + + dio700_config(link); + + return 0; +} + +static void dio700_cs_detach(struct pcmcia_device *link) +{ + ((struct local_info_t *)link->priv)->stop = 1; + dio700_release(link); + + /* This points to the parent struct local_info_t struct */ + kfree(link->priv); } static int dio700_cs_suspend(struct pcmcia_device *link) -- GitLab From 1ac53c027bb6be5a82b080a1320bfd6f7fba641b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:17:52 -0700 Subject: [PATCH 2537/6849] staging: comedi: ni_daq_700: Move the comedi_driver variable Move the comedi_driver variable to remove the need for the forward declarations. Add some whitespace to the declaration for aesthetic reasons. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 24 +++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index f9b0d67024fc..b851e2e7db42 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -55,10 +55,6 @@ static struct pcmcia_device *pcmcia_cur_dev; #define DIO700_SIZE 8 /* size of io region used by board */ -static int dio700_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static void dio700_detach(struct comedi_device *dev); - enum dio700_bustype { pcmcia_bustype }; struct dio700_board { @@ -101,16 +97,6 @@ struct dio700_private { #define devpriv ((struct dio700_private *)dev->private) -static struct comedi_driver driver_dio700 = { - .driver_name = "ni_daq_700", - .module = THIS_MODULE, - .attach = dio700_attach, - .detach = dio700_detach, - .num_names = ARRAY_SIZE(dio700_boards), - .board_name = &dio700_boards[0].name, - .offset = sizeof(struct dio700_board), -}; - #define _700_SIZE 8 #define _700_DATA 0 @@ -306,6 +292,16 @@ static void dio700_detach(struct comedi_device *dev) free_irq(dev->irq, dev); }; +static struct comedi_driver driver_dio700 = { + .driver_name = "ni_daq_700", + .module = THIS_MODULE, + .attach = dio700_attach, + .detach = dio700_detach, + .board_name = &dio700_boards[0].name, + .num_names = ARRAY_SIZE(dio700_boards), + .offset = sizeof(struct dio700_board), +}; + static void dio700_release(struct pcmcia_device *link) { dev_dbg(&link->dev, "dio700_release\n"); -- GitLab From c7949bbbfcf3e6b76384b191cd472ccc31742002 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:18:51 -0700 Subject: [PATCH 2538/6849] staging: comedi: ni_daq_700: Remove the unused private data struct The private data struct in this driver is not used for anything. Remove the struct definition and the alloc_private() call. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index b851e2e7db42..7ad54652b41f 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -90,13 +90,6 @@ static const struct dio700_board dio700_boards[] = { */ #define thisboard ((const struct dio700_board *)dev->board_ptr) -struct dio700_private { - - int data; /* number of data points left to be taken */ -}; - -#define devpriv ((struct dio700_private *)dev->private) - #define _700_SIZE 8 #define _700_DATA 0 @@ -227,10 +220,6 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pcmcia_device *link; int ret; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct dio700_private)) < 0) - return -ENOMEM; - /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { case pcmcia_bustype: -- GitLab From c0c33f69c08721d775fb0cf2d935ce5436314c68 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:19:47 -0700 Subject: [PATCH 2539/6849] staging: comedi: ni_daq_700: Remove a "do nothing" function stub The function do_config() doesn't do anything. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7ad54652b41f..99ce234ddfa9 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -107,8 +107,6 @@ struct subdev_700_struct { #define CALLBACK_FUNC (((struct subdev_700_struct *)s->private)->cb_func) #define subdevpriv ((struct subdev_700_struct *)s->private) -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); - static int subdev_700_cb(int dir, int port, int data, unsigned long arg) { /* port is always A for output and B for input (8255 emu) */ @@ -165,11 +163,6 @@ static int subdev_700_insn_config(struct comedi_device *dev, return 1; } -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) -{ /* use powerup defaults */ - return; -} - static int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, int, int, unsigned long), @@ -196,7 +189,6 @@ static int subdev_700_init(struct comedi_device *dev, s->state = 0; s->io_bits = 0x00ff; - do_config(dev, s); return 0; } -- GitLab From 5956703960aceff6340ca569d4dcc80f2045bf20 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:20:56 -0700 Subject: [PATCH 2540/6849] staging: comedi: ni_daq_700: Remove unused variables from the boardinfo The 'read_byte' and 'write_byte' function pointers in the boardinfo struct are not referenced in the driver. Just remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 99ce234ddfa9..749bc5a8e447 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -62,10 +62,6 @@ struct dio700_board { int device_id; /* device id for pcmcia board */ enum dio700_bustype bustype; /* PCMCIA */ int have_dio; /* have daqcard-700 dio */ - /* function pointers so we can use inb/outb or readb/writeb */ - /* as appropriate */ - unsigned int (*read_byte) (unsigned int address); - void (*write_byte) (unsigned int byte, unsigned int address); }; static const struct dio700_board dio700_boards[] = { -- GitLab From ba0333ead10246535134cb4a552c79b56e6a4894 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:21:55 -0700 Subject: [PATCH 2541/6849] staging: comedi: ni_daq_700: Remove unneeded variables from the boardinfo The 'device_id' and 'have_dio' variables in the boardinfo struct are initialized but not referenced in the driver. Just remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 749bc5a8e447..47e8cf4bf4a8 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -59,25 +59,17 @@ enum dio700_bustype { pcmcia_bustype }; struct dio700_board { const char *name; - int device_id; /* device id for pcmcia board */ enum dio700_bustype bustype; /* PCMCIA */ - int have_dio; /* have daqcard-700 dio */ }; static const struct dio700_board dio700_boards[] = { { .name = "daqcard-700", - /* 0x10b is manufacturer id, 0x4743 is device id */ - .device_id = 0x4743, .bustype = pcmcia_bustype, - .have_dio = 1, }, { .name = "ni_daq_700", - /* 0x10b is manufacturer id, 0x4743 is device id */ - .device_id = 0x4743, .bustype = pcmcia_bustype, - .have_dio = 1, }, }; -- GitLab From 726288e4aadbe53ed8f43483eb3b02c4a5385bd4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:23:04 -0700 Subject: [PATCH 2542/6849] staging: comedi: ni_daq_700: Remove bustype variable from the boardinfo This driver is only used for pcmcia type devices. There is no need for the 'bustype' check. Remove the variable from the boardinfo and refactor the code based on it's removal. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 27 +++++---------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 47e8cf4bf4a8..106da08433ba 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -55,21 +55,16 @@ static struct pcmcia_device *pcmcia_cur_dev; #define DIO700_SIZE 8 /* size of io region used by board */ -enum dio700_bustype { pcmcia_bustype }; - struct dio700_board { const char *name; - enum dio700_bustype bustype; /* PCMCIA */ }; static const struct dio700_board dio700_boards[] = { { .name = "daqcard-700", - .bustype = pcmcia_bustype, }, { .name = "ni_daq_700", - .bustype = pcmcia_bustype, }, }; @@ -200,22 +195,14 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pcmcia_device *link; int ret; - /* get base address, irq etc. based on bustype */ - switch (thisboard->bustype) { - case pcmcia_bustype: - link = pcmcia_cur_dev; /* XXX hack */ - if (!link) - return -EIO; - iobase = link->resource[0]->start; + link = pcmcia_cur_dev; /* XXX hack */ + if (!link) + return -EIO; + iobase = link->resource[0]->start; #ifdef incomplete - irq = link->irq; + irq = link->irq; #endif - break; - default: - printk(KERN_ERR "bug! couldn't determine board type\n"); - return -EINVAL; - break; - } + printk(KERN_ERR "comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, thisboard->name, iobase); #ifdef incomplete @@ -255,8 +242,6 @@ static void dio700_detach(struct comedi_device *dev) { if (dev->subdevices) subdev_700_cleanup(dev, dev->subdevices + 0); - if (thisboard->bustype != pcmcia_bustype && dev->iobase) - release_region(dev->iobase, DIO700_SIZE); if (dev->irq) free_irq(dev->irq, dev); }; -- GitLab From 79820c9cec076bd839a076fcb06fb6bfb79b1614 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:24:06 -0700 Subject: [PATCH 2543/6849] staging: comedi: ni_daq_700: move the boardinfo variable For aesthetic reasons, move the boardinfo declaration down so it's next to the comedi_driver. That's the only place in the driver where it's referenced directly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 106da08433ba..864bef7badd0 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -59,15 +59,6 @@ struct dio700_board { const char *name; }; -static const struct dio700_board dio700_boards[] = { - { - .name = "daqcard-700", - }, - { - .name = "ni_daq_700", - }, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -246,6 +237,14 @@ static void dio700_detach(struct comedi_device *dev) free_irq(dev->irq, dev); }; +static const struct dio700_board dio700_boards[] = { + { + .name = "daqcard-700", + }, { + .name = "ni_daq_700", + }, +}; + static struct comedi_driver driver_dio700 = { .driver_name = "ni_daq_700", .module = THIS_MODULE, -- GitLab From 109d5d54e0e5d93d1fcc4acb186981459d152977 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:25:26 -0700 Subject: [PATCH 2544/6849] staging: comedi: ni_daq_700: remove thisboard macro The 'thisboard' macro relies on a local variable having a specific name and yields a pointer derived from that local variable. Replace the macro with local variables and use the comedi_board() helper to get the pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 864bef7badd0..2f849342d748 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -59,11 +59,6 @@ struct dio700_board { const char *name; }; -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct dio700_board *)dev->board_ptr) - #define _700_SIZE 8 #define _700_DATA 0 @@ -178,6 +173,7 @@ static void subdev_700_cleanup(struct comedi_device *dev, static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dio700_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase = 0; #ifdef incomplete -- GitLab From 54be9353682914693074078d203407806f8f3f34 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:26:46 -0700 Subject: [PATCH 2545/6849] staging: comedi: ni_daq_700: remove unused private data variable The 'have_irq' variable is not needed since this driver doesn't use interrupts. Remove it. The kfree(s->private) needs to remain to free the memory allocated in subdev_700_init(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 2f849342d748..525f076c9a6d 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -69,7 +69,6 @@ struct dio700_board { struct subdev_700_struct { unsigned long cb_arg; int (*cb_func) (int, int, int, unsigned long); - int have_irq; }; #define CALLBACK_ARG (((struct subdev_700_struct *)s->private)->cb_arg) @@ -166,9 +165,7 @@ static void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { if (s->private) - if (subdevpriv->have_irq) - - kfree(s->private); + kfree(s->private); } static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) -- GitLab From 1de02225358988e8fd48d1dc3fd12336bbae258a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:28:33 -0700 Subject: [PATCH 2546/6849] staging: comedi: ni_daq_700: remove the CALLBACK_* code This driver was originally copied from the 8255 driver. The 8255 uses a callback function to handle the io operations to the device. In this driver, the callback adds unneeded complexity. The CALLBACK_ARG for this driver is always 'dev->iobase' and the CALLBACK_FUNC is always 'subdev_700_cb'. The callback function is also overly complex for this driver. It takes a 'dir' parameter to determine if the io is a write or read, a 'port' parameter that is not used, a 'data' parameter that is only used for writes, and an 'arg' which is the iobase of the device. Unwind all of it and just put the outb()/inb() call in the code where needed. This allows getting rid of the private data completely. Refactor the code based on it's removal. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 46 +-------------------- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 525f076c9a6d..59f7632351e0 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -66,28 +66,6 @@ struct dio700_board { #define DIO_W 0x04 #define DIO_R 0x05 -struct subdev_700_struct { - unsigned long cb_arg; - int (*cb_func) (int, int, int, unsigned long); -}; - -#define CALLBACK_ARG (((struct subdev_700_struct *)s->private)->cb_arg) -#define CALLBACK_FUNC (((struct subdev_700_struct *)s->private)->cb_func) -#define subdevpriv ((struct subdev_700_struct *)s->private) - -static int subdev_700_cb(int dir, int port, int data, unsigned long arg) -{ - /* port is always A for output and B for input (8255 emu) */ - unsigned long iobase = arg; - - if (dir) { - outb(data, iobase + DIO_W); - return 0; - } else { - return inb(iobase + DIO_R); - } -} - static int subdev_700_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -97,12 +75,11 @@ static int subdev_700_insn(struct comedi_device *dev, s->state |= (data[0] & data[1]); if (data[0] & 0xff) - CALLBACK_FUNC(1, _700_DATA, s->state & 0xff, - CALLBACK_ARG); + outb(s->state & 0xff, dev->iobase + DIO_W); } data[1] = s->state & 0xff; - data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8; + data[1] |= inb(dev->iobase + DIO_R); return insn->n; } @@ -142,16 +119,6 @@ static int subdev_700_init(struct comedi_device *dev, s->range_table = &range_digital; s->maxdata = 1; - s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL); - if (!s->private) - return -ENOMEM; - - CALLBACK_ARG = arg; - if (cb == NULL) - CALLBACK_FUNC = subdev_700_cb; - else - CALLBACK_FUNC = cb; - s->insn_bits = subdev_700_insn; s->insn_config = subdev_700_insn_config; @@ -161,13 +128,6 @@ static int subdev_700_init(struct comedi_device *dev, return 0; } -static void subdev_700_cleanup(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - if (s->private) - kfree(s->private); -} - static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dio700_board *thisboard = comedi_board(dev); @@ -224,8 +184,6 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dio700_detach(struct comedi_device *dev) { - if (dev->subdevices) - subdev_700_cleanup(dev, dev->subdevices + 0); if (dev->irq) free_irq(dev->irq, dev); }; -- GitLab From 797a9e782ae2922451cf9aa6d66dd5eaa0987626 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:29:19 -0700 Subject: [PATCH 2547/6849] staging: comedi: ni_daq_700: remove a couple unused defines These defines are not referenced in the driver. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 59f7632351e0..dbc5fc64e438 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -53,16 +53,10 @@ IRQ is assigned but not used. static struct pcmcia_device *pcmcia_cur_dev; -#define DIO700_SIZE 8 /* size of io region used by board */ - struct dio700_board { const char *name; }; -#define _700_SIZE 8 - -#define _700_DATA 0 - #define DIO_W 0x04 #define DIO_R 0x05 -- GitLab From be7085ae31fa062b82a4f0614998cbc9066debfc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:30:13 -0700 Subject: [PATCH 2548/6849] staging: comedi: ni_daq_700: remove the subdev_700_init function Move the contents of subdev_700_init into the attach function. For aesthetic reasone, add some whitespace to the initialization of the subdevice. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 31 +++++++-------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index dbc5fc64e438..206a0c458347 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -102,26 +102,6 @@ static int subdev_700_insn_config(struct comedi_device *dev, return 1; } -static int subdev_700_init(struct comedi_device *dev, - struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) -{ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 16; - s->range_table = &range_digital; - s->maxdata = 1; - - s->insn_bits = subdev_700_insn; - s->insn_config = subdev_700_insn_config; - - s->state = 0; - s->io_bits = 0x00ff; - - return 0; -} - static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dio700_board *thisboard = comedi_board(dev); @@ -171,7 +151,16 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* DAQCard-700 dio */ s = dev->subdevices + 0; - subdev_700_init(dev, s, NULL, dev->iobase); + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 16; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_bits = subdev_700_insn; + s->insn_config = subdev_700_insn_config; + + s->state = 0; + s->io_bits = 0x00ff; return 0; }; -- GitLab From 40cfdb9505c253c0dac4a1a8a8d9bdf551a38649 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:31:15 -0700 Subject: [PATCH 2549/6849] staging: comedi: ni_daq_700: remove the #ifdef'ed out irq code The irq code is not compiled in due to the '#ifdef incomplete'. And, as stated, it's not even complete. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 25 ++------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 206a0c458347..94cb3461cfbe 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -37,8 +37,6 @@ port, bit 0; channel 8 corresponds to the input port, bit 0. Direction configuration: channels 0-7 output, 8-15 input (8225 device emu as port A output, port B input, port C N/A). - -IRQ is assigned but not used. */ #include @@ -107,9 +105,6 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct dio700_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase = 0; -#ifdef incomplete - unsigned int irq = 0; -#endif struct pcmcia_device *link; int ret; @@ -117,19 +112,9 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!link) return -EIO; iobase = link->resource[0]->start; -#ifdef incomplete - irq = link->irq; -#endif - printk(KERN_ERR "comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, + printk(KERN_ERR "comedi%d: ni_daq_700: %s, io 0x%lx\n", dev->minor, thisboard->name, iobase); -#ifdef incomplete - if (irq) - printk(", irq %u", irq); - -#endif - - printk("\n"); if (iobase == 0) { printk(KERN_ERR "io base address is zero!\n"); @@ -138,11 +123,6 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; -#ifdef incomplete - /* grab our IRQ */ - dev->irq = irq; -#endif - dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, 1); @@ -167,8 +147,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dio700_detach(struct comedi_device *dev) { - if (dev->irq) - free_irq(dev->irq, dev); + /* nothing to cleanup */ }; static const struct dio700_board dio700_boards[] = { -- GitLab From b88c59972db3117996913d8e74fdfe9df3ac601b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:32:19 -0700 Subject: [PATCH 2550/6849] staging: comedi: ni_daq_700: change the 'attach' printk's to dev_printk's Use the dev_printk() routines to output the kernel messages in the attach routine. The main 'attach' message had a level of KERN_ERR, I believe it should have been KERN_INFO. Also, move that message to the end of the attach so it only gets displayed if the attach is successful. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 94cb3461cfbe..50fad12f7eb1 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -113,11 +113,8 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; iobase = link->resource[0]->start; - printk(KERN_ERR "comedi%d: ni_daq_700: %s, io 0x%lx\n", dev->minor, - thisboard->name, iobase); - if (iobase == 0) { - printk(KERN_ERR "io base address is zero!\n"); + dev_err(dev->class_dev, "io base address is zero!\n"); return -EINVAL; } @@ -142,6 +139,11 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->state = 0; s->io_bits = 0x00ff; + dev_info(dev->class_dev, "%s: %s, io 0x%lx\n", + dev->driver->driver_name, + dev->board_name, + dev->iobase); + return 0; }; -- GitLab From 7448fcd3b8caee05c6e5a7dc965b5845affbb2e8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:33:10 -0700 Subject: [PATCH 2551/6849] staging: comedi: ni_daq_700: remove local variable in the 'attach' function There is no need for the local variable 'iobase' in the attach function. If it's '0' the attach fails otherwise the value is just stored in dev->iobase. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 50fad12f7eb1..5c60df832467 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -104,22 +104,19 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dio700_board *thisboard = comedi_board(dev); struct comedi_subdevice *s; - unsigned long iobase = 0; struct pcmcia_device *link; int ret; link = pcmcia_cur_dev; /* XXX hack */ if (!link) return -EIO; - iobase = link->resource[0]->start; - if (iobase == 0) { + dev->iobase = link->resource[0]->start; + if (!dev->iobase) { dev_err(dev->class_dev, "io base address is zero!\n"); return -EINVAL; } - dev->iobase = iobase; - dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, 1); -- GitLab From 4fb209a56960bad241b41b0e0e451b6346b6aee4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:33:52 -0700 Subject: [PATCH 2552/6849] staging: comedi: ni_daq_700: remove some dangling ';' Functions don't need the ';' at the end. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 5c60df832467..4978cd374a53 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -142,12 +142,12 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase); return 0; -}; +} static void dio700_detach(struct comedi_device *dev) { /* nothing to cleanup */ -}; +} static const struct dio700_board dio700_boards[] = { { -- GitLab From c11a1ea71bf2ce9a75a7071c785220a42f4c922a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:34:57 -0700 Subject: [PATCH 2553/6849] staging: comedi: ni_daq_700: use a local var to fix a > 80 char line issue The 'data[1] = ...' line is currently kept < 80 chars by breaking a pointer access after the '->'. This makes the code a bit confusing to follow. Use a local variable to shorten the line and make it clearer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 4978cd374a53..2ea3c8d5194c 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -80,6 +80,7 @@ static int subdev_700_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + unsigned int chan = 1 << CR_CHAN(insn->chanspec); switch (data[0]) { case INSN_CONFIG_DIO_INPUT: @@ -87,10 +88,7 @@ static int subdev_700_insn_config(struct comedi_device *dev, case INSN_CONFIG_DIO_OUTPUT: break; case INSN_CONFIG_DIO_QUERY: - data[1] = - (s-> - io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : - COMEDI_INPUT; + data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; break; default: -- GitLab From 740b48be40761c0345a3c5e7ad077b7e4616bd13 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:35:57 -0700 Subject: [PATCH 2554/6849] staging: comedi: ni_daq_700: fix return for insn_config function The comedi insn_config functions should return < 0 for errors or the number of data elements used to perform the command, this value is available as 'insn->n'. Return that instead of the open coded number to better indicate what the return means. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 2ea3c8d5194c..cc469480ff4f 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -89,13 +89,12 @@ static int subdev_700_insn_config(struct comedi_device *dev, break; case INSN_CONFIG_DIO_QUERY: data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; break; default: return -EINVAL; } - return 1; + return insn->n; } static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) -- GitLab From 9c1eb8e1a04acb27da21d461db2b015ac33a0d25 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:36:58 -0700 Subject: [PATCH 2555/6849] staging: comedi: ni_daq_700: cleanup pcmcia debug output messages These messages should probably just be removed. For now just clean then up. Remove a couple redundant KERN_INFO messages in the pcmcia support code and leave the dev_dbg() ones. Change the dev_dgb() messages to use __func__ instead of the open coded string. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index cc469480ff4f..bb857ac4e2c5 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -166,7 +166,7 @@ static struct comedi_driver driver_dio700 = { static void dio700_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "dio700_release\n"); + dev_dbg(&link->dev, "%s\n", __func__); pcmcia_disable_device(link); } @@ -184,9 +184,7 @@ static void dio700_config(struct pcmcia_device *link) { int ret; - printk(KERN_INFO "ni_daq_700: cs-config\n"); - - dev_dbg(&link->dev, "dio700_config\n"); + dev_dbg(&link->dev, "%s\n", __func__); link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; @@ -207,7 +205,7 @@ static void dio700_config(struct pcmcia_device *link) return; failed: - printk(KERN_INFO "ni_daq_700 cs failed"); + dev_dbg(&link->dev, "%s failed\n", __func__); dio700_release(link); } @@ -222,9 +220,7 @@ static int dio700_cs_attach(struct pcmcia_device *link) { struct local_info_t *local; - printk(KERN_INFO "ni_daq_700: cs-attach\n"); - - dev_dbg(&link->dev, "dio700_cs_attach()\n"); + dev_dbg(&link->dev, "%s\n", __func__); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); -- GitLab From 919f6077f26937455d8ce2a2987063c6111e1609 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:37:56 -0700 Subject: [PATCH 2556/6849] staging: comedi: ni_daq_700: remove unused pcmcia 'stop' logic The pcmcia support code in this driver appears to be cut-and- paste from some other driver. It has code in it to stop the device during suspend but nothing in the main comedi_driver uses it. Remove the 'stop' variable from the pcmcia private data and all the logic that deals with it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index bb857ac4e2c5..b02ed37b55b4 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -212,7 +212,6 @@ failed: struct local_info_t { struct pcmcia_device *link; - int stop; struct bus_operations *bus; }; @@ -238,7 +237,6 @@ static int dio700_cs_attach(struct pcmcia_device *link) static void dio700_cs_detach(struct pcmcia_device *link) { - ((struct local_info_t *)link->priv)->stop = 1; dio700_release(link); /* This points to the parent struct local_info_t struct */ @@ -247,18 +245,11 @@ static void dio700_cs_detach(struct pcmcia_device *link) static int dio700_cs_suspend(struct pcmcia_device *link) { - struct local_info_t *local = link->priv; - - /* Mark the device as stopped, to block IO until later */ - local->stop = 1; return 0; } static int dio700_cs_resume(struct pcmcia_device *link) { - struct local_info_t *local = link->priv; - - local->stop = 0; return 0; } -- GitLab From d2d2a6f27564d101192610abaae94177471c755b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:38:45 -0700 Subject: [PATCH 2557/6849] staging: comedi: ni_daq_700: remove unneeded pcmcia private data The pcmcia device-specific data is not longer needed by this driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index b02ed37b55b4..f8465a2bfc87 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -210,24 +210,10 @@ failed: } -struct local_info_t { - struct pcmcia_device *link; - struct bus_operations *bus; -}; - static int dio700_cs_attach(struct pcmcia_device *link) { - struct local_info_t *local; - dev_dbg(&link->dev, "%s\n", __func__); - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); - if (!local) - return -ENOMEM; - local->link = link; - link->priv = local; - pcmcia_cur_dev = link; dio700_config(link); @@ -238,9 +224,6 @@ static int dio700_cs_attach(struct pcmcia_device *link) static void dio700_cs_detach(struct pcmcia_device *link) { dio700_release(link); - - /* This points to the parent struct local_info_t struct */ - kfree(link->priv); } static int dio700_cs_suspend(struct pcmcia_device *link) -- GitLab From cc04ac0fee72d55e59c2d9db19969bc2d74a9097 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:39:42 -0700 Subject: [PATCH 2558/6849] staging: comedi: ni_daq_700: remove the pcmcia suspend/resume The pcmcia suspend/resume callbacks don't do anything. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index f8465a2bfc87..c57300f89cfd 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -226,16 +226,6 @@ static void dio700_cs_detach(struct pcmcia_device *link) dio700_release(link); } -static int dio700_cs_suspend(struct pcmcia_device *link) -{ - return 0; -} - -static int dio700_cs_resume(struct pcmcia_device *link) -{ - return 0; -} - static const struct pcmcia_device_id dio700_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), PCMCIA_DEVICE_NULL @@ -247,8 +237,6 @@ static struct pcmcia_driver dio700_cs_driver = { .owner = THIS_MODULE, .probe = dio700_cs_attach, .remove = dio700_cs_detach, - .suspend = dio700_cs_suspend, - .resume = dio700_cs_resume, .id_table = dio700_cs_ids, }; -- GitLab From 6e891af85b4b697679f72c77ddbe19f853379f02 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 22 Jun 2012 16:40:40 -0700 Subject: [PATCH 2559/6849] staging: comedi: ni_daq_700: refactor the pcmcia attach/detach Move the pcmcia_disable_device() call where needed in the pcmcia attach/detach and delete the dio700_release() function. Move the logic of dio700_config() directly into the attach function and properly return an error code when the config fails. Only set the pcmcia_cur_dev, used by the comedi_driver, if the pcmcia attach is successful. Also, make sure to NULL it in the detach. Remove all the kernel messages in the pcmcia support code. They are just added noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 39 +++++---------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index c57300f89cfd..83016b411851 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -164,13 +164,6 @@ static struct comedi_driver driver_dio700 = { .offset = sizeof(struct dio700_board), }; -static void dio700_release(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "%s\n", __func__); - - pcmcia_disable_device(link); -} - static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { @@ -180,50 +173,36 @@ static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, return pcmcia_request_io(p_dev); } -static void dio700_config(struct pcmcia_device *link) +static int dio700_cs_attach(struct pcmcia_device *link) { int ret; - dev_dbg(&link->dev, "%s\n", __func__); - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); + if (ret) goto failed; - } if (!link->irq) goto failed; ret = pcmcia_enable_device(link); - if (ret != 0) + if (ret) goto failed; - return; - -failed: - dev_dbg(&link->dev, "%s failed\n", __func__); - dio700_release(link); - -} - -static int dio700_cs_attach(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "%s\n", __func__); - pcmcia_cur_dev = link; - - dio700_config(link); - return 0; + +failed: + pcmcia_disable_device(link); + return ret; } static void dio700_cs_detach(struct pcmcia_device *link) { - dio700_release(link); + pcmcia_disable_device(link); + pcmcia_cur_dev = NULL; } static const struct pcmcia_device_id dio700_cs_ids[] = { -- GitLab From 3852587ac62d249f26f89e3fef28c0474cc25729 Mon Sep 17 00:00:00 2001 From: Erik Jones Date: Wed, 20 Jun 2012 23:17:03 -0400 Subject: [PATCH 2560/6849] staging: rts5139: rts51x_chip: fixed brace coding style issue Fixed a coding style issue. Signed-off-by: Erik Jones Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5139/rts51x_chip.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index db88d7a194b8..08dcae8db63e 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -363,11 +363,10 @@ void rts51x_polling_func(struct rts51x_chip *chip) break; } - if (chip->option.auto_delink_en && !chip->card_ready) { + if (chip->option.auto_delink_en && !chip->card_ready) rts51x_auto_delink(chip); - } else { + else chip->auto_delink_counter = 0; - } } void rts51x_add_cmd(struct rts51x_chip *chip, -- GitLab From b15297e912afb6a2a5bf592bb006fd705c12ab1c Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 22 Jun 2012 01:00:41 +0200 Subject: [PATCH 2561/6849] staging: rts5139: Remove duplicate include of rts51x.h The header "rts51x.h" is included unconditionally at the start of the file and then again once more under "#ifdef SUPPORT_FILE_OP". Once is enough, so remove the conditional include and just keep the unconditional one. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5139/rts51x_fop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c index ef893c8cdec6..e1200fe89579 100644 --- a/drivers/staging/rts5139/rts51x_fop.c +++ b/drivers/staging/rts5139/rts51x_fop.c @@ -36,7 +36,6 @@ #include "rts51x_card.h" #include "rts51x_fop.h" #include "sd_cprm.h" -#include "rts51x.h" #define RTS5139_IOC_MAGIC 0x39 -- GitLab From 70b3fd34a9b2e06b2702d691d406ef2ec1d2f0df Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 22 Jun 2012 02:28:12 +0200 Subject: [PATCH 2562/6849] staging: vt6656: Correct a few assignments to be compares in iwctl_siwencodeext() The result of "foo = bar" is true, so in statements such as ... if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) ... an assignment is most likely not what was intended - a comparison was. As in: ... if ((pDevice->bwextstep0 == TRUE) && (param->u.wpa_key.key_index == 1)) ... There are a 3 such mistakes in the iwctl_siwencodeext() function. This patch fixes them all. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index b24e5314a6af..57404388eba9 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -1708,15 +1708,15 @@ if(param->u.wpa_key.alg_name == WPA_ALG_NONE) { if(param->u.wpa_key.key_index ==0) { pDevice->bwextstep0 = TRUE; } - if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) { + if ((pDevice->bwextstep0 == TRUE) && (param->u.wpa_key.key_index == 1)) { pDevice->bwextstep0 = FALSE; pDevice->bwextstep1 = TRUE; } - if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) { + if ((pDevice->bwextstep1 == TRUE) && (param->u.wpa_key.key_index == 2)) { pDevice->bwextstep1 = FALSE; pDevice->bwextstep2 = TRUE; } - if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) { + if ((pDevice->bwextstep2 == TRUE)&&(param->u.wpa_key.key_index == 3)) { pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = TRUE; } -- GitLab From 4bf8172772254a38741de139a355e36eabbb5cb8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 21 Jun 2012 19:10:59 +0200 Subject: [PATCH 2563/6849] staging:iio:trigger: Use to_iio_trigger() instead of dev_get_drvdata() Use to_iio_trigger(dev) instead of dev_get_drvdata(dev). Both will return the trigger which belongs to the device, but the the first on is a bit more lightweight. Also this will eventually free up the drvdata pointer of the device for driver specific data. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 4 ++-- drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | 4 ++-- drivers/staging/iio/trigger/iio-trig-sysfs.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index f85734d212bb..ce6a7b1b8860 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -60,7 +60,7 @@ struct bfin_tmr_state { static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_trigger *trig = dev_get_drvdata(dev); + struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = trig->private_data; long val; int ret; @@ -97,7 +97,7 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_trigger *trig = dev_get_drvdata(dev); + struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = trig->private_data; return sprintf(buf, "%lu\n", diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 9f2d055524a3..4ceaa18ef9f4 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -41,7 +41,7 @@ static ssize_t iio_trig_periodic_read_freq(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_trigger *trig = dev_get_drvdata(dev); + struct iio_trigger *trig = to_iio_trigger(dev); struct iio_prtc_trigger_info *trig_info = trig->private_data; return sprintf(buf, "%u\n", trig_info->frequency); } @@ -51,7 +51,7 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev, const char *buf, size_t len) { - struct iio_trigger *trig = dev_get_drvdata(dev); + struct iio_trigger *trig = to_iio_trigger(dev); struct iio_prtc_trigger_info *trig_info = trig->private_data; unsigned long val; int ret; diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index 552763bb3d4c..fee474648108 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -92,7 +92,7 @@ static struct device iio_sysfs_trig_dev = { static ssize_t iio_sysfs_trigger_poll(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_trigger *trig = dev_get_drvdata(dev); + struct iio_trigger *trig = to_iio_trigger(dev); iio_trigger_poll_chained(trig, 0); return count; -- GitLab From 971ff1db41b0f16f34cfdeb9e0460d7dc598e68e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 21 Jun 2012 19:11:00 +0200 Subject: [PATCH 2564/6849] iio:trigger: Use to_iio_trigger() instead of dev_get_drvdata() Use to_iio_trigger(dev) instead of dev_get_drvdata(dev). Both will return the trigger which belongs to the device, but the the first on is a bit more lightweight. Since this is the last location where we used dev_get_drvdata() for retrieving the trigger there is no need anymore to assign the the trigger to the devices drvdata, so we can remove that as well. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-trigger.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 0f582df75a19..ec653fb51d0b 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -45,7 +45,7 @@ static ssize_t iio_trigger_read_name(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_trigger *trig = dev_get_drvdata(dev); + struct iio_trigger *trig = to_iio_trigger(dev); return sprintf(buf, "%s\n", trig->name); } @@ -436,7 +436,6 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) trig->dev.type = &iio_trig_type; trig->dev.bus = &iio_bus_type; device_initialize(&trig->dev); - dev_set_drvdata(&trig->dev, (void *)trig); mutex_init(&trig->pool_lock); trig->subirq_base -- GitLab From 708706ff290545decbb7f43b533cb247e8ff64fd Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 22 Jun 2012 09:47:41 +0200 Subject: [PATCH 2565/6849] staging: iio: fix trigger handler of iio_simple_dummy driver accessing first and last channel fails: fakedata[0] is never accessed, out-of-bound access for last channel Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio_simple_dummy_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index fa4939caee6a..d91196021c0d 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -75,9 +75,9 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) for (i = 0, j = 0; i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); - i++) { + i++, j++) { j = find_next_bit(buffer->scan_mask, - indio_dev->masklength, j + 1); + indio_dev->masklength, j); /* random access read from the 'device' */ data[i] = fakedata[j]; len += 2; -- GitLab From 970689f10e7447225eef39ceabd1898daec99553 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 22 Jun 2012 09:47:42 +0200 Subject: [PATCH 2566/6849] staging: iio: simplify timestamp alignment in iio_simple_dummy Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio_simple_dummy_buffer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index d91196021c0d..f4415da528a7 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -85,8 +85,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) } /* Store a timestampe at an 8 byte boundary */ if (indio_dev->scan_timestamp) - *(s64 *)(((phys_addr_t)data + len - + sizeof(s64) - 1) & ~(sizeof(s64) - 1)) + *(s64 *)((phys_addr_t)data + ALIGN(len, sizeof(s64))) = iio_get_time_ns(); buffer->access->store_to(buffer, (u8 *)data, pf->timestamp); -- GitLab From 8b32b11c2eb800c636975dbc37e4e11f36790493 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Fri, 22 Jun 2012 09:47:43 +0200 Subject: [PATCH 2567/6849] staging: iio: fix typo, improve timestamp alignment comment Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio_simple_dummy_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index f4415da528a7..b9e6093f6543 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -83,7 +83,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) len += 2; } } - /* Store a timestampe at an 8 byte boundary */ + /* Store the timestamp at an 8 byte aligned offset */ if (indio_dev->scan_timestamp) *(s64 *)((phys_addr_t)data + ALIGN(len, sizeof(s64))) = iio_get_time_ns(); -- GitLab From 1c1b86215730ef07d8851c2247b9ecf73038d05d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 22 Jun 2012 11:26:04 -0500 Subject: [PATCH 2568/6849] staging: r8712u: Remove useless driver version info This driver contains version information that is outdated, has no real value in terms of the Linux update process, and tends to confuse users. Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/usb_intf.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 9bd18e2d0513..f9c32cae64e7 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -41,8 +41,6 @@ #include "usb_ops.h" #include "usb_osintf.h" -#define DRVER "v7_0.20100831" - static struct usb_interface *pintf; static int r871xu_drv_init(struct usb_interface *pusb_intf, @@ -372,7 +370,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, struct net_device *pnetdev; struct usb_device *udev; - printk(KERN_INFO "r8712u: DriverVersion: %s\n", DRVER); + printk(KERN_INFO "r8712u: Staging version\n"); /* In this probe function, O.S. will provide the usb interface pointer * to driver. We have to increase the reference count of the usb device * structure by using the usb_get_dev function. -- GitLab From 7586eceb0abc0ea1c2b023e3e5d4dfd4ff40930a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Jun 2012 05:02:19 +0000 Subject: [PATCH 2569/6849] ipv4: tcp: dont cache output dst for syncookies Don't cache output dst for syncookies, as this adds pressure on IP route cache and rcu subsystem for no gain. Signed-off-by: Eric Dumazet Cc: Hans Schillstrom Signed-off-by: Jesper Dangaard Brouer Signed-off-by: David S. Miller --- include/net/flow.h | 1 + include/net/inet_connection_sock.h | 3 ++- net/dccp/ipv4.c | 2 +- net/ipv4/inet_connection_sock.c | 8 ++++++-- net/ipv4/route.c | 5 ++++- net/ipv4/tcp_ipv4.c | 12 +++++++----- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/net/flow.h b/include/net/flow.h index 6c469dbdb917..bd524f598561 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -22,6 +22,7 @@ struct flowi_common { #define FLOWI_FLAG_ANYSRC 0x01 #define FLOWI_FLAG_PRECOW_METRICS 0x02 #define FLOWI_FLAG_CAN_SLEEP 0x04 +#define FLOWI_FLAG_RT_NOCACHE 0x08 __u32 flowic_secid; }; diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index e1b7734c456f..af3c743a40e4 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -251,7 +251,8 @@ extern int inet_csk_get_port(struct sock *sk, unsigned short snum); extern struct dst_entry* inet_csk_route_req(struct sock *sk, struct flowi4 *fl4, - const struct request_sock *req); + const struct request_sock *req, + bool nocache); extern struct dst_entry* inet_csk_route_child_sock(struct sock *sk, struct sock *newsk, const struct request_sock *req); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 07f5579ca756..3eb76b5f221a 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -504,7 +504,7 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, struct dst_entry *dst; struct flowi4 fl4; - dst = inet_csk_route_req(sk, &fl4, req); + dst = inet_csk_route_req(sk, &fl4, req, false); if (dst == NULL) goto out; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index f9ee7417f6a0..034ddbe42adf 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -368,17 +368,21 @@ EXPORT_SYMBOL(inet_csk_reset_keepalive_timer); struct dst_entry *inet_csk_route_req(struct sock *sk, struct flowi4 *fl4, - const struct request_sock *req) + const struct request_sock *req, + bool nocache) { struct rtable *rt; const struct inet_request_sock *ireq = inet_rsk(req); struct ip_options_rcu *opt = inet_rsk(req)->opt; struct net *net = sock_net(sk); + int flags = inet_sk_flowi_flags(sk) & ~FLOWI_FLAG_PRECOW_METRICS; + if (nocache) + flags |= FLOWI_FLAG_RT_NOCACHE; flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, - inet_sk_flowi_flags(sk) & ~FLOWI_FLAG_PRECOW_METRICS, + flags, (opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr, ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport); security_req_classify_flow(req, flowi4_to_flowi(fl4)); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a91f6d33804c..8d62d85e68dc 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1156,7 +1156,7 @@ restart: candp = NULL; now = jiffies; - if (!rt_caching(dev_net(rt->dst.dev))) { + if (!rt_caching(dev_net(rt->dst.dev)) || (rt->dst.flags & DST_NOCACHE)) { /* * If we're not caching, just tell the caller we * were successful and don't touch the route. The @@ -2582,6 +2582,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rt_set_nexthop(rth, fl4, res, fi, type, 0); + if (fl4->flowi4_flags & FLOWI_FLAG_RT_NOCACHE) + rth->dst.flags |= DST_NOCACHE; + return rth; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 21e22a00481a..b52934f5334e 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -825,7 +825,8 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, struct request_values *rvp, - u16 queue_mapping) + u16 queue_mapping, + bool nocache) { const struct inet_request_sock *ireq = inet_rsk(req); struct flowi4 fl4; @@ -833,7 +834,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, struct sk_buff * skb; /* First, grab a route. */ - if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) + if (!dst && (dst = inet_csk_route_req(sk, &fl4, req, nocache)) == NULL) return -1; skb = tcp_make_synack(sk, dst, req, rvp); @@ -855,7 +856,7 @@ static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req, struct request_values *rvp) { TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); - return tcp_v4_send_synack(sk, NULL, req, rvp, 0); + return tcp_v4_send_synack(sk, NULL, req, rvp, 0, false); } /* @@ -1388,7 +1389,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) */ if (tmp_opt.saw_tstamp && tcp_death_row.sysctl_tw_recycle && - (dst = inet_csk_route_req(sk, &fl4, req)) != NULL && + (dst = inet_csk_route_req(sk, &fl4, req, want_cookie)) != NULL && fl4.daddr == saddr && (peer = rt_get_peer((struct rtable *)dst, fl4.daddr)) != NULL) { inet_peer_refcheck(peer); @@ -1424,7 +1425,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) if (tcp_v4_send_synack(sk, dst, req, (struct request_values *)&tmp_ext, - skb_get_queue_mapping(skb)) || + skb_get_queue_mapping(skb), + want_cookie) || want_cookie) goto drop_and_free; -- GitLab From eb2dc35d99028b698cdedba4f5522bc43e576bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Wed, 20 Jun 2012 12:09:18 +0000 Subject: [PATCH 2570/6849] r8169: RxConfig hack for the 8168evl. The 8168evl (RTL_GIGA_MAC_VER_34) based Gigabyte GA-990FXA motherboards are very prone to NETDEV watchdog problems without this change. See https://bugzilla.kernel.org/show_bug.cgi?id=42899 for instance. I don't know why it *works*. It's depressingly effective though. For the record: - the problem may go along IOMMU (AMD-Vi) errors but it really looks like a red herring. - the patch sets the RX_MULTI_EN bit. If the 8168c doc is any guide, the chipset now fetches several Rx descriptors at a time. - long ago the driver ignored the RX_MULTI_EN bit. e542a2269f232d61270ceddd42b73a4348dee2bb changed the RxConfig settings. Whatever the problem it's now labeled a regression. - Realtek's own driver can identify two different 8168evl devices (CFG_METHOD_16 and CFG_METHOD_17) where the r8169 driver only sees one. It sucks. Signed-off-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7260aa79466a..d7a04e091101 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3894,6 +3894,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_22: case RTL_GIGA_MAC_VER_23: case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; default: -- GitLab From a18e08bdcf845efb7344cea146e683df746bbfb4 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 20 Jun 2012 15:26:34 +0000 Subject: [PATCH 2571/6849] net: sh_eth: fix the condition to fix the cur_tx/dirty_rx The following commit couldn't work if the RMCR is not set to 1. "net: sh_eth: fix the rxdesc pointer when rx descriptor empty happens" commit id 79fba9f51755c704c0a7d7b7f0df10874dc0a744 If RMCR is not set, the controller will clear the EDRRR after it received a frame. In this case, the driver doesn't need to fix the value of cur_rx/dirty_rx. The driver only needs it when the controll detects receive descriptors are empty. Signed-off-by: Yoshihiro Shimoda Tested-by: Guennadi Liakhovetski Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 667169b82526..79bf09b41971 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1011,7 +1011,7 @@ static int sh_eth_txfree(struct net_device *ndev) } /* Packet receive function */ -static int sh_eth_rx(struct net_device *ndev) +static int sh_eth_rx(struct net_device *ndev, u32 intr_status) { struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_rxdesc *rxdesc; @@ -1102,9 +1102,11 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { - /* fix the values for the next receiving */ - mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - - sh_eth_read(ndev, RDLAR)) >> 4; + /* fix the values for the next receiving if RDE is set */ + if (intr_status & EESR_RDE) + mdp->cur_rx = mdp->dirty_rx = + (sh_eth_read(ndev, RDFAR) - + sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_write(ndev, EDRRR_R, EDRRR); } @@ -1273,7 +1275,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) EESR_RTSF | /* short frame recv */ EESR_PRE | /* PHY-LSI recv error */ EESR_CERF)){ /* recv frame CRC error */ - sh_eth_rx(ndev); + sh_eth_rx(ndev, intr_status); } /* Tx Check */ -- GitLab From 6a0bdffa0073857870a4ed1b4489762146359eb4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Jun 2012 16:04:19 -0400 Subject: [PATCH 2572/6849] SCSI & usb-storage: add try_rc_10_first flag Several bug reports have been received recently for USB mass-storage devices that don't handle READ CAPACITY(16) commands properly. They report bogus sizes, in some cases becoming unusable as a result. The bugs were triggered by commit 09b6b51b0b6c1b9bb61815baf205e4d74c89ff04 (SCSI & usb-storage: add flags for VPD pages and REPORT LUNS), which caused usb-storage to stop overriding the SCSI level reported by devices. By default, the sd driver will try READ CAPACITY(16) first for any device whose level is above SCSI_SPC_2. It seems likely that any device large enough to require the use of READ CAPACITY(16) (i.e., 2 TB or more) would be able to handle READ CAPACITY(10) commands properly. Indeed, I don't know of any devices that don't handle READ CAPACITY(10) properly. Therefore this patch (as1559) adds a new flag telling the sd driver to try READ CAPACITY(10) before READ CAPACITY(16), and sets this flag for every USB mass-storage device. If a device really is larger than 2 TB, sd will fall back to READ CAPACITY(16) just as it used to. This fixes Bugzilla #43391. Signed-off-by: Alan Stern Acked-by: Hans de Goede CC: "James E.J. Bottomley" CC: Matthew Dharm Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 2 ++ drivers/usb/storage/scsiglue.c | 6 ++++++ include/scsi/scsi_device.h | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 6f0a4c612b3b..6f72b80121a0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1899,6 +1899,8 @@ static int sd_try_rc16_first(struct scsi_device *sdp) { if (sdp->host->max_cmd_len < 16) return 0; + if (sdp->try_rc_10_first) + return 0; if (sdp->scsi_level > SCSI_SPC_2) return 1; if (scsi_device_protection(sdp)) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a324a5d21e99..11418da9bc09 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -202,6 +202,12 @@ static int slave_configure(struct scsi_device *sdev) if (us->fflags & US_FL_NO_READ_CAPACITY_16) sdev->no_read_capacity_16 = 1; + /* + * Many devices do not respond properly to READ_CAPACITY_16. + * Tell the SCSI layer to try READ_CAPACITY_10 first. + */ + sdev->try_rc_10_first = 1; + /* assume SPC3 or latter devices support sense size > 18 */ if (sdev->scsi_level > SCSI_SPC_2) us->fflags |= US_FL_SANE_SENSE; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 6efb2e1416e0..ba9698852321 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -151,6 +151,7 @@ struct scsi_device { SD_LAST_BUGGY_SECTORS */ unsigned no_read_disc_info:1; /* Avoid READ_DISC_INFO cmds */ unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */ + unsigned try_rc_10_first:1; /* Try READ_CAPACACITY_10 first */ unsigned is_visible:1; /* is the device visible in sysfs */ DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ -- GitLab From 0070513b5e005161a7a7fd9a3f48f982b41eb094 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Jun 2012 16:04:30 -0400 Subject: [PATCH 2573/6849] usb-storage: revert commit afff07e61a52 (Add 090c:1000 to unusal-devs) This patch (as1560) reverts commit afff07e61a5243e14ee3f0a272a0380cd744a8a3 (usb-storage: Add 090c:1000 to unusal-devs). It is no longer needed, because usb-storage now tells the sd driver to try READ CAPACITY(10) before READ CAPACITY(16) for every USB mass-storage device. Signed-off-by: Alan Stern Acked-by: Hans de Goede CC: Matthew Dharm Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index caf22bf5f822..1719886bb9be 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1107,13 +1107,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, USB_SC_RBC, USB_PR_BULK, NULL, 0 ), -/* Feiya QDI U2 DISK, reported by Hans de Goede */ -UNUSUAL_DEV( 0x090c, 0x1000, 0x0000, 0xffff, - "Feiya", - "QDI U2 DISK", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_NO_READ_CAPACITY_16 ), - /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", -- GitLab From dfbce08c19cba2ba4faaf8c0dd6d7678f46c78dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 22 Jun 2012 23:02:22 -0700 Subject: [PATCH 2574/6849] ipv4: Don't add deprecated new binary sysctl value. Reported-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/sysctl.h | 1 - kernel/sysctl_binary.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 20825e5f433f..c34b4c82b0dc 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -425,7 +425,6 @@ enum NET_TCP_ALLOWED_CONG_CONTROL=123, NET_TCP_MAX_SSTHRESH=124, NET_TCP_FRTO_RESPONSE=125, - NET_IPV4_EARLY_DEMUX=126, }; enum { diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 6a3cf8253aae..a650694883a1 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -415,8 +415,6 @@ static const struct bin_table bin_net_ipv4_table[] = { { CTL_INT, NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, /* NET_IPV4_IPFRAG_MAX_DIST "ipfrag_max_dist" no longer used */ - { CTL_INT, NET_IPV4_EARLY_DEMUX, "ip_early_demux" }, - { CTL_INT, 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, /* NET_TCP_DEFAULT_WIN_SCALE unused */ -- GitLab From 1d23396d9df0a9543b2ba5c288f4914ad1f19e46 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 21 Jun 2012 18:10:48 +0300 Subject: [PATCH 2575/6849] wlcore: don't allow SDIO read/writes after failure Set a flag and after the first read/write failure is encountered. This flag will disallow further SDIO read/writes until op_stop() is executed, which will clear all flags. This prevents further errors from occurring, since one error usually indicates that IO operations won't work anymore until the chip is rebooted. By blocking more calls, we avoid extra timeouts and having to wait for them to occur. [Added second paragraph explaining why the change is needed. -- Luca] Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/io.h | 22 ++++++++++++++++++++-- drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 1cd545b0ed1e..fef80adc8bf5 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -57,14 +57,32 @@ static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { - return wl->if_ops->write(wl->dev, addr, buf, len, fixed); + int ret; + + if (test_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags)) + return -EIO; + + ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed); + if (ret) + set_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags); + + return ret; } static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { - return wl->if_ops->read(wl->dev, addr, buf, len, fixed); + int ret; + + if (test_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags)) + return -EIO; + + ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed); + if (ret) + set_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags); + + return ret; } static inline int __must_check wlcore_raw_read_data(struct wl1271 *wl, int reg, diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index e5a34dd34baf..4273a21cdde1 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -247,6 +247,7 @@ enum wl12xx_flags { WL1271_FLAG_RECOVERY_IN_PROGRESS, WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, WL1271_FLAG_INTENDED_FW_RECOVERY, + WL1271_FLAG_SDIO_FAILED, }; enum wl12xx_vif_flags { -- GitLab From ea0a3cf95ed8839ce6f11bf9a050e6333bfc27d6 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 21 Jun 2012 18:10:49 +0300 Subject: [PATCH 2576/6849] wlcore: force recovery on resume if suspended without recovering If an error is detected after mac80211 is already suspended, the recovery work will not be queued. This will leave the driver in a bad state on resume. Detect this in the resume op and re-queue a recovery. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0df28d5cb331..0b51522d8eae 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1707,7 +1707,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif; unsigned long flags; - bool run_irq_work = false; + bool run_irq_work = false, pending_recovery; wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d", wl->wow_enabled); @@ -1723,17 +1723,33 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) run_irq_work = true; spin_unlock_irqrestore(&wl->wl_lock, flags); + /* test the recovery flag before calling any SDIO functions */ + pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, + &wl->flags); + if (run_irq_work) { wl1271_debug(DEBUG_MAC80211, "run postponed irq_work directly"); - wl1271_irq(0, wl); + + /* don't talk to the HW if recovery is pending */ + if (!pending_recovery) + wl1271_irq(0, wl); + wlcore_enable_interrupts(wl); } mutex_lock(&wl->mutex); + if (pending_recovery) { + wl1271_warning("queuing forgotten recovery on resume"); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + goto out; + } + wl12xx_for_each_wlvif(wl, wlvif) { wl1271_configure_resume(wl, wlvif); } + +out: wl->wow_enabled = false; mutex_unlock(&wl->mutex); -- GitLab From c439a1ca3bdc58febf51a388a9930eeba361b410 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 21 Jun 2012 18:10:50 +0300 Subject: [PATCH 2577/6849] wlcore: check Rx-filter functions in the suspend path Propagate some missing return values for Rx-filter related functions. This and makes sure we always fail the suspend in case of SDIO errors. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 27 +++++++++++++++++++++------ drivers/net/wireless/ti/wlcore/rx.c | 11 ++++++++--- drivers/net/wireless/ti/wlcore/rx.h | 2 +- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0b51522d8eae..e6e665440f81 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1513,8 +1513,15 @@ static int wl1271_configure_wowlan(struct wl1271 *wl, int i, ret; if (!wow || wow->any || !wow->n_patterns) { - wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); - wl1271_rx_filter_clear_all(wl); + ret = wl1271_acx_default_rx_filter_enable(wl, 0, + FILTER_SIGNAL); + if (ret) + goto out; + + ret = wl1271_rx_filter_clear_all(wl); + if (ret) + goto out; + return 0; } @@ -1530,8 +1537,13 @@ static int wl1271_configure_wowlan(struct wl1271 *wl, } } - wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); - wl1271_rx_filter_clear_all(wl); + ret = wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); + if (ret) + goto out; + + ret = wl1271_rx_filter_clear_all(wl); + if (ret) + goto out; /* Translate WoWLAN patterns into filters */ for (i = 0; i < wow->n_patterns; i++) { @@ -1573,7 +1585,10 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, if (ret < 0) goto out; - wl1271_configure_wowlan(wl, wow); + ret = wl1271_configure_wowlan(wl, wow); + if (ret < 0) + goto out_sleep; + ret = wl1271_acx_wake_up_conditions(wl, wlvif, wl->conf.conn.suspend_wake_up_event, wl->conf.conn.suspend_listen_interval); @@ -1581,8 +1596,8 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, if (ret < 0) wl1271_error("suspend: set wake up conditions failed: %d", ret); +out_sleep: wl1271_ps_elp_sleep(wl); - out: return ret; diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index f42b969c1de9..f55e2f9e7ac5 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -318,14 +318,19 @@ int wl1271_rx_filter_enable(struct wl1271 *wl, return 0; } -void wl1271_rx_filter_clear_all(struct wl1271 *wl) +int wl1271_rx_filter_clear_all(struct wl1271 *wl) { - int i; + int i, ret = 0; for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) { if (!wl->rx_filter_enabled[i]) continue; - wl1271_rx_filter_enable(wl, i, 0, NULL); + ret = wl1271_rx_filter_enable(wl, i, 0, NULL); + if (ret) + goto out; } + +out: + return ret; } #endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h index 79f7839a06e2..71eba1899915 100644 --- a/drivers/net/wireless/ti/wlcore/rx.h +++ b/drivers/net/wireless/ti/wlcore/rx.h @@ -148,6 +148,6 @@ u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, struct wl12xx_rx_filter *filter); -void wl1271_rx_filter_clear_all(struct wl1271 *wl); +int wl1271_rx_filter_clear_all(struct wl1271 *wl); #endif -- GitLab From b5b45b3cbd56162d9612dd76529d7ad9f6be9a56 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 21 Jun 2012 18:10:51 +0300 Subject: [PATCH 2578/6849] wlcore: refactor threaded IRQ routine Separate the threaded IRQ handling routine into two functions. The outer function takes the mutex and calls recovery on errors. It also performs a Tx-path optimization to avoid redundant works. The inner function is simplified - all calls to recovery are removed and it assumes the lock is taken. The locked variant will be reused elsewhere. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 62 +++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index e6e665440f81..0c1e0751ecaa 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -494,20 +494,15 @@ static void wl1271_netstack_work(struct work_struct *work) #define WL1271_IRQ_MAX_LOOPS 256 -static irqreturn_t wl1271_irq(int irq, void *cookie) +static int wlcore_irq_locked(struct wl1271 *wl) { - int ret; + int ret = 0; u32 intr; int loopcount = WL1271_IRQ_MAX_LOOPS; - struct wl1271 *wl = (struct wl1271 *)cookie; bool done = false; unsigned int defer_count; unsigned long flags; - /* TX might be handled here, avoid redundant work */ - set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); - cancel_work_sync(&wl->tx_work); - /* * In case edge triggered interrupt must be used, we cannot iterate * more than once without introducing race conditions with the hardirq. @@ -515,8 +510,6 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) loopcount = 1; - mutex_lock(&wl->mutex); - wl1271_debug(DEBUG_IRQ, "IRQ work"); if (unlikely(wl->state == WL1271_STATE_OFF)) @@ -536,10 +529,8 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) smp_mb__after_clear_bit(); ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); + if (ret < 0) goto out; - } wlcore_hw_tx_immediate_compl(wl); @@ -553,7 +544,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { wl1271_error("HW watchdog interrupt received! starting recovery."); wl->watchdog_recovery = true; - wl12xx_queue_recovery_work(wl); + ret = -EIO; /* restarting the chip. ignore any other interrupt. */ goto out; @@ -563,7 +554,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_error("SW watchdog interrupt received! " "starting recovery."); wl->watchdog_recovery = true; - wl12xx_queue_recovery_work(wl); + ret = -EIO; /* restarting the chip. ignore any other interrupt. */ goto out; @@ -573,10 +564,8 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); ret = wlcore_rx(wl, wl->fw_status_1); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); + if (ret < 0) goto out; - } /* Check if any tx blocks were freed */ spin_lock_irqsave(&wl->wl_lock, flags); @@ -588,20 +577,16 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) * call the work function directly. */ ret = wlcore_tx_work_locked(wl); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); + if (ret < 0) goto out; - } } else { spin_unlock_irqrestore(&wl->wl_lock, flags); } /* check for tx results */ ret = wlcore_hw_tx_delayed_compl(wl); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); + if (ret < 0) goto out; - } /* Make sure the deferred queues don't get too long */ defer_count = skb_queue_len(&wl->deferred_tx_queue) + @@ -613,19 +598,15 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) if (intr & WL1271_ACX_INTR_EVENT_A) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); ret = wl1271_event_handle(wl, 0); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); + if (ret < 0) goto out; - } } if (intr & WL1271_ACX_INTR_EVENT_B) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); ret = wl1271_event_handle(wl, 1); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); + if (ret < 0) goto out; - } } if (intr & WL1271_ACX_INTR_INIT_COMPLETE) @@ -639,6 +620,25 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_ps_elp_sleep(wl); out: + return ret; +} + +static irqreturn_t wlcore_irq(int irq, void *cookie) +{ + int ret; + unsigned long flags; + struct wl1271 *wl = cookie; + + /* TX might be handled here, avoid redundant work */ + set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); + cancel_work_sync(&wl->tx_work); + + mutex_lock(&wl->mutex); + + ret = wlcore_irq_locked(wl); + if (ret) + wl12xx_queue_recovery_work(wl); + spin_lock_irqsave(&wl->wl_lock, flags); /* In case TX was not handled here, queue TX work */ clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); @@ -1748,7 +1748,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) /* don't talk to the HW if recovery is pending */ if (!pending_recovery) - wl1271_irq(0, wl); + wlcore_irq(0, wl); wlcore_enable_interrupts(wl); } @@ -5489,7 +5489,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) else irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; - ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wl1271_irq, + ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wlcore_irq, irqflags, pdev->name, wl); if (ret < 0) { -- GitLab From 725b82775e7901dc92afaddfa45683934e75c33e Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 21 Jun 2012 18:10:52 +0300 Subject: [PATCH 2579/6849] wlcore: prevent recovery in the middle of resume Take the mutex early in the resume handler and use the locked version of the IRQ routine. This ensures any recoveries queued will only take place after resume has fully completed. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0c1e0751ecaa..372ccf277b1e 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1723,6 +1723,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) struct wl12xx_vif *wlvif; unsigned long flags; bool run_irq_work = false, pending_recovery; + int ret; wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d", wl->wow_enabled); @@ -1738,6 +1739,8 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) run_irq_work = true; spin_unlock_irqrestore(&wl->wl_lock, flags); + mutex_lock(&wl->mutex); + /* test the recovery flag before calling any SDIO functions */ pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); @@ -1747,13 +1750,15 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) "run postponed irq_work directly"); /* don't talk to the HW if recovery is pending */ - if (!pending_recovery) - wlcore_irq(0, wl); + if (!pending_recovery) { + ret = wlcore_irq_locked(wl); + if (ret) + wl12xx_queue_recovery_work(wl); + } wlcore_enable_interrupts(wl); } - mutex_lock(&wl->mutex); if (pending_recovery) { wl1271_warning("queuing forgotten recovery on resume"); ieee80211_queue_work(wl->hw, &wl->recovery_work); -- GitLab From 49d57b5e588ce511bd826f5759aa2aebf322626b Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 22 Jun 2012 10:29:53 +0530 Subject: [PATCH 2580/6849] dmaengine: mmp_tdma: fix the arch dependency Reported-by: Stephen Rothwell Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 90fec0e0e8f5..d45cf1bcbde5 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -276,7 +276,7 @@ config DMA_SA11X0 config MMP_TDMA bool "MMP Two-Channel DMA support" - default ARCH_MMP + depends on ARCH_MMP select DMA_ENGINE help Support the MMP Two-Channel DMA engine. -- GitLab From b19dbf711e8dae026f8d014eae90d766d02f4acb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 23 Jun 2012 11:34:20 +0100 Subject: [PATCH 2581/6849] regulator: core: Add export of regulator_set_voltage_time_sel() Signed-off-by: Mark Brown --- drivers/regulator/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ce0a3462e0de..26b71048709b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2330,6 +2330,7 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, return 0; } +EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); /** * regulator_sync_voltage - re-apply last regulator output voltage -- GitLab From a68de074613abd028b2ce63366d18db9c29e15d2 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 22 Jun 2012 13:36:20 +0100 Subject: [PATCH 2582/6849] regulator: palmas: fix regmap offsets for enable/disable I forgot to apply the offsets for the regmap helper functions for enable/disable on SMPS10 and the LDO regulators. This means regulators will not enable/disable correctly. Signed-off-by: Graeme Gregory Tested-by: Sebastien Guiriec Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 9b7ca90057d5..795f75a6ac33 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -673,7 +673,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].ops = &palmas_ops_smps10; pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; pmic->desc[id].vsel_mask = SMPS10_VSEL; - pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + PALMAS_SMPS10_STATUS); pmic->desc[id].enable_mask = SMPS10_BOOST_EN; } @@ -739,7 +741,8 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; - pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr; + pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + palmas_regs_info[id].ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; if (pdata && pdata->reg_data) -- GitLab From ace36d85809f6005b559802f194d44c6aa61af88 Mon Sep 17 00:00:00 2001 From: Vipin Kumar Date: Thu, 21 Jun 2012 15:54:53 +0530 Subject: [PATCH 2583/6849] ASoC: SPEAr spdif_in: Add spdif IN support This patch implements the spdif IN driver for ST peripheral Signed-off-by: Vipin Kumar Signed-off-by: Rajeev Kumar Signed-off-by: Mark Brown --- include/sound/spear_spdif.h | 29 ++++ sound/soc/spear/spdif_in.c | 297 ++++++++++++++++++++++++++++++++ sound/soc/spear/spdif_in_regs.h | 60 +++++++ 3 files changed, 386 insertions(+) create mode 100644 include/sound/spear_spdif.h create mode 100644 sound/soc/spear/spdif_in.c create mode 100644 sound/soc/spear/spdif_in_regs.h diff --git a/include/sound/spear_spdif.h b/include/sound/spear_spdif.h new file mode 100644 index 000000000000..a12f39695610 --- /dev/null +++ b/include/sound/spear_spdif.h @@ -0,0 +1,29 @@ +/* + * Copyright (ST) 2012 Vipin Kumar (vipin.kumar@st.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SOUND_SPDIF_H +#define __SOUND_SPDIF_H + +struct spear_spdif_platform_data { + /* DMA params */ + void *dma_params; + bool (*filter)(struct dma_chan *chan, void *slave); + void (*reset_perip)(void); +}; + +#endif /* SOUND_SPDIF_H */ diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c new file mode 100644 index 000000000000..c7c4b20395bb --- /dev/null +++ b/sound/soc/spear/spdif_in.c @@ -0,0 +1,297 @@ +/* + * ALSA SoC SPDIF In Audio Layer for spear processors + * + * Copyright (C) 2012 ST Microelectronics + * Vipin Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "spdif_in_regs.h" + +struct spdif_in_params { + u32 format; +}; + +struct spdif_in_dev { + struct clk *clk; + struct spear_dma_data dma_params; + struct spdif_in_params saved_params; + void *io_base; + struct device *dev; + void (*reset_perip)(void); + int irq; +}; + +static void spdif_in_configure(struct spdif_in_dev *host) +{ + u32 ctrl = SPDIF_IN_PRTYEN | SPDIF_IN_STATEN | SPDIF_IN_USREN | + SPDIF_IN_VALEN | SPDIF_IN_BLKEN; + ctrl |= SPDIF_MODE_16BIT | SPDIF_FIFO_THRES_16; + + writel(ctrl, host->io_base + SPDIF_IN_CTRL); + writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK); +} + +static int spdif_in_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct spdif_in_dev *host = snd_soc_dai_get_drvdata(cpu_dai); + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) + return -EINVAL; + + snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params); + return 0; +} + +static void spdif_in_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai); + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) + return; + + writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK); + snd_soc_dai_set_dma_data(dai, substream, NULL); +} + +static void spdif_in_format(struct spdif_in_dev *host, u32 format) +{ + u32 ctrl = readl(host->io_base + SPDIF_IN_CTRL); + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + ctrl |= SPDIF_XTRACT_16BIT; + break; + + case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: + ctrl &= ~SPDIF_XTRACT_16BIT; + break; + } + + writel(ctrl, host->io_base + SPDIF_IN_CTRL); +} + +static int spdif_in_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai); + u32 format; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) + return -EINVAL; + + format = params_format(params); + host->saved_params.format = format; + + return 0; +} + +static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai); + u32 ctrl; + int ret = 0; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) + return -EINVAL; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + clk_enable(host->clk); + spdif_in_configure(host); + spdif_in_format(host, host->saved_params.format); + + ctrl = readl(host->io_base + SPDIF_IN_CTRL); + ctrl |= SPDIF_IN_SAMPLE | SPDIF_IN_ENB; + writel(ctrl, host->io_base + SPDIF_IN_CTRL); + writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ctrl = readl(host->io_base + SPDIF_IN_CTRL); + ctrl &= ~(SPDIF_IN_SAMPLE | SPDIF_IN_ENB); + writel(ctrl, host->io_base + SPDIF_IN_CTRL); + writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK); + + if (host->reset_perip) + host->reset_perip(); + clk_disable(host->clk); + break; + + default: + ret = -EINVAL; + break; + } + return ret; +} + +static struct snd_soc_dai_ops spdif_in_dai_ops = { + .startup = spdif_in_startup, + .shutdown = spdif_in_shutdown, + .trigger = spdif_in_trigger, + .hw_params = spdif_in_hw_params, +}; + +struct snd_soc_dai_driver spdif_in_dai = { + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000), + .formats = SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE, + }, + .ops = &spdif_in_dai_ops, +}; + +static irqreturn_t spdif_in_irq(int irq, void *arg) +{ + struct spdif_in_dev *host = (struct spdif_in_dev *)arg; + + u32 irq_status = readl(host->io_base + SPDIF_IN_IRQ); + + if (!irq_status) + return IRQ_NONE; + + if (irq_status & SPDIF_IRQ_FIFOWRITE) + dev_err(host->dev, "spdif in: fifo write error"); + if (irq_status & SPDIF_IRQ_EMPTYFIFOREAD) + dev_err(host->dev, "spdif in: empty fifo read error"); + if (irq_status & SPDIF_IRQ_FIFOFULL) + dev_err(host->dev, "spdif in: fifo full error"); + if (irq_status & SPDIF_IRQ_OUTOFRANGE) + dev_err(host->dev, "spdif in: out of range error"); + + writel(0, host->io_base + SPDIF_IN_IRQ); + + return IRQ_HANDLED; +} + +static int spdif_in_probe(struct platform_device *pdev) +{ + struct spdif_in_dev *host; + struct spear_spdif_platform_data *pdata; + struct resource *res, *res_fifo; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + res_fifo = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res_fifo) + return -EINVAL; + + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), pdev->name)) { + dev_warn(&pdev->dev, "Failed to get memory resourse\n"); + return -ENOENT; + } + + host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); + if (!host) { + dev_warn(&pdev->dev, "kzalloc fail\n"); + return -ENOMEM; + } + + host->io_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!host->io_base) { + dev_warn(&pdev->dev, "ioremap failed\n"); + return -ENOMEM; + } + + host->irq = platform_get_irq(pdev, 0); + if (host->irq < 0) + return -EINVAL; + + host->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(host->clk)) + return PTR_ERR(host->clk); + + pdata = dev_get_platdata(&pdev->dev); + + if (!pdata) + return -EINVAL; + + host->dma_params.data = pdata->dma_params; + host->dma_params.addr = res_fifo->start; + host->dma_params.max_burst = 16; + host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + host->dma_params.filter = pdata->filter; + host->reset_perip = pdata->reset_perip; + + host->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, host); + + ret = devm_request_irq(&pdev->dev, host->irq, spdif_in_irq, 0, + "spdif-in", host); + if (ret) { + clk_put(host->clk); + dev_warn(&pdev->dev, "request_irq failed\n"); + return ret; + } + + ret = snd_soc_register_dai(&pdev->dev, &spdif_in_dai); + if (ret != 0) { + clk_put(host->clk); + return ret; + } + + return 0; +} + +static int spdif_in_remove(struct platform_device *pdev) +{ + struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev); + + snd_soc_unregister_dai(&pdev->dev); + dev_set_drvdata(&pdev->dev, NULL); + + clk_put(host->clk); + + return 0; +} + + +static struct platform_driver spdif_in_driver = { + .probe = spdif_in_probe, + .remove = spdif_in_remove, + .driver = { + .name = "spdif-in", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(spdif_in_driver); + +MODULE_AUTHOR("Vipin Kumar "); +MODULE_DESCRIPTION("SPEAr SPDIF IN SoC Interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spdif_in"); diff --git a/sound/soc/spear/spdif_in_regs.h b/sound/soc/spear/spdif_in_regs.h new file mode 100644 index 000000000000..37af7bc66b7f --- /dev/null +++ b/sound/soc/spear/spdif_in_regs.h @@ -0,0 +1,60 @@ +/* + * SPEAr SPDIF IN controller header file + * + * Copyright (ST) 2011 Vipin Kumar (vipin.kumar@st.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SPDIF_IN_REGS_H +#define SPDIF_IN_REGS_H + +#define SPDIF_IN_CTRL 0x00 + #define SPDIF_IN_PRTYEN (1 << 20) + #define SPDIF_IN_STATEN (1 << 19) + #define SPDIF_IN_USREN (1 << 18) + #define SPDIF_IN_VALEN (1 << 17) + #define SPDIF_IN_BLKEN (1 << 16) + + #define SPDIF_MODE_24BIT (8 << 12) + #define SPDIF_MODE_23BIT (7 << 12) + #define SPDIF_MODE_22BIT (6 << 12) + #define SPDIF_MODE_21BIT (5 << 12) + #define SPDIF_MODE_20BIT (4 << 12) + #define SPDIF_MODE_19BIT (3 << 12) + #define SPDIF_MODE_18BIT (2 << 12) + #define SPDIF_MODE_17BIT (1 << 12) + #define SPDIF_MODE_16BIT (0 << 12) + #define SPDIF_MODE_MASK (0x0F << 12) + + #define SPDIF_IN_VALID (1 << 11) + #define SPDIF_IN_SAMPLE (1 << 10) + #define SPDIF_DATA_SWAP (1 << 9) + #define SPDIF_IN_ENB (1 << 8) + #define SPDIF_DATA_REVERT (1 << 7) + #define SPDIF_XTRACT_16BIT (1 << 6) + #define SPDIF_FIFO_THRES_16 (16 << 0) + +#define SPDIF_IN_IRQ_MASK 0x04 +#define SPDIF_IN_IRQ 0x08 + #define SPDIF_IRQ_FIFOWRITE (1 << 0) + #define SPDIF_IRQ_EMPTYFIFOREAD (1 << 1) + #define SPDIF_IRQ_FIFOFULL (1 << 2) + #define SPDIF_IRQ_OUTOFRANGE (1 << 3) + +#define SPDIF_IN_STA 0x0C + #define SPDIF_IN_LOCK (0x1 << 0) + +#endif /* SPDIF_IN_REGS_H */ -- GitLab From b2a4ec3d48fb53c99cb2e332f6e58eef770f1ed9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jun 2012 11:34:49 +0100 Subject: [PATCH 2584/6849] ASoC: da732x: Staticise non-exported symbol soc_codec_dev_da732x Signed-off-by: Mark Brown --- sound/soc/codecs/da732x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 04af369f228c..01be2a320e21 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1543,7 +1543,7 @@ static int da732x_remove(struct snd_soc_codec *codec) return 0; } -struct snd_soc_codec_driver soc_codec_dev_da732x = { +static struct snd_soc_codec_driver soc_codec_dev_da732x = { .probe = da732x_probe, .remove = da732x_remove, .set_bias_level = da732x_set_bias_level, -- GitLab From bb1591b3de7c9c6b28f337e214100a394a126ab2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jun 2012 11:33:38 +0100 Subject: [PATCH 2585/6849] ASoC: isabelle: Staticise non-exported isabelle_dai Signed-off-by: Mark Brown --- sound/soc/codecs/isabelle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 0d62f3b0f474..5d8f39e32978 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1036,7 +1036,7 @@ static struct snd_soc_dai_ops isabelle_ul_dai_ops = { }; /* ISABELLE dai structure */ -struct snd_soc_dai_driver isabelle_dai[] = { +static struct snd_soc_dai_driver isabelle_dai[] = { { .name = "isabelle-dl1", .playback = { -- GitLab From 229e3fdc1ba49b747e9434b55b3f6bd68a4db251 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jun 2012 11:40:55 +0100 Subject: [PATCH 2586/6849] ASoC: core: Add DOUBLE_R variants of the _RANGE controls The code handles this fine already, we just need new macros in the header for drivers to create the controls. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index e4348d25fca3..e063380f63a2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -42,6 +42,10 @@ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ .max = xmax, .platform_max = xmax, .invert = xinvert}) +#define SOC_DOUBLE_R_RANGE_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \ + ((unsigned long)&(struct soc_mixer_control) \ + {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ + .min = xmin, .max = xmax, .platform_max = xmax, .invert = xinvert}) #define SOC_SINGLE(xname, reg, shift, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ @@ -96,6 +100,13 @@ .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ xmax, xinvert) } +#define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \ + xmax, xinvert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .info = snd_soc_info_volsw_range, \ + .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ + .private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \ + xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -114,6 +125,16 @@ .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ xmax, xinvert) } +#define SOC_DOUBLE_R_RANGE_TLV(xname, reg_left, reg_right, xshift, xmin, \ + xmax, xinvert, tlv_array) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ + SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .tlv.p = (tlv_array), \ + .info = snd_soc_info_volsw_range, \ + .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ + .private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \ + xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ -- GitLab From 62d4a4b99dfd647ef88b8434334eaa7497602857 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jun 2012 12:21:49 +0100 Subject: [PATCH 2587/6849] ASoC: dapm: Try to add all routes even if one fails We may as well print as many errors as we can in one go rather than requiring developers to iterate through all their typos. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7365fed1ba74..32fbf10127f1 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2276,15 +2276,15 @@ err: int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route, int num) { - int i, ret = 0; + int i, r, ret = 0; mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); for (i = 0; i < num; i++) { - ret = snd_soc_dapm_add_route(dapm, route); - if (ret < 0) { + r = snd_soc_dapm_add_route(dapm, route); + if (r < 0) { dev_err(dapm->dev, "Failed to add route %s->%s\n", route->source, route->sink); - break; + ret = r; } route++; } -- GitLab From 9dfdd5abcf2b350d4fdb207c0dff3194e2fd73db Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jun 2012 12:40:52 +0100 Subject: [PATCH 2588/6849] ASoC: io: Don't dereference regmap if we failed to get one Avoids a crash in invalid configurations. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-io.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 44d0174b4d97..29183ef2b93d 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -145,10 +145,13 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, if (!codec->control_data) codec->control_data = dev_get_regmap(codec->dev, NULL); - ret = regmap_get_val_bytes(codec->control_data); - /* Errors are legitimate for non-integer byte multiples */ - if (ret > 0) - codec->val_bytes = ret; + if (codec->control_data) { + ret = regmap_get_val_bytes(codec->control_data); + /* Errors are legitimate for non-integer byte + * multiples */ + if (ret > 0) + codec->val_bytes = ret; + } break; default: -- GitLab From 07ed873e4c975a26c327a6bd306693678ef63351 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 18 Jun 2012 21:08:44 +0100 Subject: [PATCH 2589/6849] ASoC: Add shared code for Wolfson Arizona class devices The Wolfson Arizona series of audio hub CODECs can share a large amount of their driver code as the result of a common register map. This patch adds some of this core support, providing a basis for the initial WM5102 audio driver. Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/arizona.c | 781 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/arizona.h | 149 +++++++ 4 files changed, 937 insertions(+) create mode 100644 sound/soc/codecs/arizona.c create mode 100644 sound/soc/codecs/arizona.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 43f5240e6942..2ae8082f23b5 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -129,6 +129,11 @@ config SND_SOC_ALL_CODECS config SND_SOC_88PM860X tristate +config SND_SOC_ARIZONA + tristate + default y if SND_SOC_WM5102=y + default m if SND_SOC_WM5102=m + config SND_SOC_WM_HUBS tristate default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3d30654f6fcc..3005ea6c1fd8 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -14,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o snd-soc-ak4641-objs := ak4641.o snd-soc-ak4642-objs := ak4642.o snd-soc-ak4671-objs := ak4671.o +snd-soc-arizona-objs := arizona.o snd-soc-cq93vc-objs := cq93vc.o snd-soc-cs42l51-objs := cs42l51.o snd-soc-cs42l52-objs := cs42l52.o @@ -128,6 +129,7 @@ obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o +obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c new file mode 100644 index 000000000000..3b5730b90686 --- /dev/null +++ b/sound/soc/codecs/arizona.c @@ -0,0 +1,781 @@ +/* + * arizona.c - Wolfson Arizona class device shared support + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "arizona.h" + +#define ARIZONA_AIF_BCLK_CTRL 0x00 +#define ARIZONA_AIF_TX_PIN_CTRL 0x01 +#define ARIZONA_AIF_RX_PIN_CTRL 0x02 +#define ARIZONA_AIF_RATE_CTRL 0x03 +#define ARIZONA_AIF_FORMAT 0x04 +#define ARIZONA_AIF_TX_BCLK_RATE 0x05 +#define ARIZONA_AIF_RX_BCLK_RATE 0x06 +#define ARIZONA_AIF_FRAME_CTRL_1 0x07 +#define ARIZONA_AIF_FRAME_CTRL_2 0x08 +#define ARIZONA_AIF_FRAME_CTRL_3 0x09 +#define ARIZONA_AIF_FRAME_CTRL_4 0x0A +#define ARIZONA_AIF_FRAME_CTRL_5 0x0B +#define ARIZONA_AIF_FRAME_CTRL_6 0x0C +#define ARIZONA_AIF_FRAME_CTRL_7 0x0D +#define ARIZONA_AIF_FRAME_CTRL_8 0x0E +#define ARIZONA_AIF_FRAME_CTRL_9 0x0F +#define ARIZONA_AIF_FRAME_CTRL_10 0x10 +#define ARIZONA_AIF_FRAME_CTRL_11 0x11 +#define ARIZONA_AIF_FRAME_CTRL_12 0x12 +#define ARIZONA_AIF_FRAME_CTRL_13 0x13 +#define ARIZONA_AIF_FRAME_CTRL_14 0x14 +#define ARIZONA_AIF_FRAME_CTRL_15 0x15 +#define ARIZONA_AIF_FRAME_CTRL_16 0x16 +#define ARIZONA_AIF_FRAME_CTRL_17 0x17 +#define ARIZONA_AIF_FRAME_CTRL_18 0x18 +#define ARIZONA_AIF_TX_ENABLES 0x19 +#define ARIZONA_AIF_RX_ENABLES 0x1A +#define ARIZONA_AIF_FORCE_WRITE 0x1B + +#define arizona_fll_err(_fll, fmt, ...) \ + dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) +#define arizona_fll_warn(_fll, fmt, ...) \ + dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) +#define arizona_fll_dbg(_fll, fmt, ...) \ + dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) + +#define arizona_aif_err(_dai, fmt, ...) \ + dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) +#define arizona_aif_warn(_dai, fmt, ...) \ + dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) +#define arizona_aif_dbg(_dai, fmt, ...) \ + dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) + +const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { + "None", + "Tone Generator 1", + "Tone Generator 2", + "Haptics", + "AEC", + "Mic Mute Mixer", + "Noise Generator", + "IN1L", + "IN1R", + "IN2L", + "IN2R", + "IN3L", + "IN3R", + "AIF1RX1", + "AIF1RX2", + "AIF1RX3", + "AIF1RX4", + "AIF1RX5", + "AIF1RX6", + "AIF1RX7", + "AIF1RX8", + "AIF2RX1", + "AIF2RX2", + "AIF3RX1", + "AIF3RX2", + "SLIMRX1", + "SLIMRX2", + "SLIMRX3", + "SLIMRX4", + "SLIMRX5", + "SLIMRX6", + "SLIMRX7", + "SLIMRX8", + "EQ1", + "EQ2", + "EQ3", + "EQ4", + "DRC1L", + "DRC1R", + "DRC2L", + "DRC2R", + "LHPF1", + "LHPF2", + "LHPF3", + "LHPF4", + "DSP1.1", + "DSP1.2", + "DSP1.3", + "DSP1.4", + "DSP1.5", + "DSP1.6", + "ASRC1L", + "ASRC1R", + "ASRC2L", + "ASRC2R", +}; +EXPORT_SYMBOL_GPL(arizona_mixer_texts); + +int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { + 0x00, /* None */ + 0x04, /* Tone */ + 0x05, + 0x06, /* Haptics */ + 0x08, /* AEC */ + 0x0c, /* Noise mixer */ + 0x0d, /* Comfort noise */ + 0x10, /* IN1L */ + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x20, /* AIF1RX1 */ + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, /* AIF2RX1 */ + 0x29, + 0x30, /* AIF3RX1 */ + 0x31, + 0x38, /* SLIMRX1 */ + 0x39, + 0x3a, + 0x3b, + 0x3c, + 0x3d, + 0x3e, + 0x3f, + 0x50, /* EQ1 */ + 0x51, + 0x52, + 0x53, + 0x58, /* DRC1L */ + 0x59, + 0x5a, + 0x5b, + 0x60, /* LHPF1 */ + 0x61, + 0x62, + 0x63, + 0x68, /* DSP1.1 */ + 0x69, + 0x6a, + 0x6b, + 0x6c, + 0x6d, + 0x90, /* ASRC1L */ + 0x91, + 0x92, + 0x93, +}; +EXPORT_SYMBOL_GPL(arizona_mixer_values); + +const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); +EXPORT_SYMBOL_GPL(arizona_mixer_tlv); + +static const char *arizona_lhpf_mode_text[] = { + "Low-pass", "High-pass" +}; + +const struct soc_enum arizona_lhpf1_mode = + SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2, + arizona_lhpf_mode_text); +EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); + +const struct soc_enum arizona_lhpf2_mode = + SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2, + arizona_lhpf_mode_text); +EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); + +const struct soc_enum arizona_lhpf3_mode = + SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2, + arizona_lhpf_mode_text); +EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); + +const struct soc_enum arizona_lhpf4_mode = + SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, + arizona_lhpf_mode_text); +EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); + +int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + return 0; +} +EXPORT_SYMBOL_GPL(arizona_in_ev); + +int arizona_out_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return 0; +} +EXPORT_SYMBOL_GPL(arizona_out_ev); + +int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, + int source, unsigned int freq, int dir) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + char *name; + unsigned int reg; + unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK; + unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT; + unsigned int *clk; + + switch (clk_id) { + case ARIZONA_CLK_SYSCLK: + name = "SYSCLK"; + reg = ARIZONA_SYSTEM_CLOCK_1; + clk = &priv->sysclk; + mask |= ARIZONA_SYSCLK_FRAC; + break; + case ARIZONA_CLK_ASYNCCLK: + name = "ASYNCCLK"; + reg = ARIZONA_ASYNC_CLOCK_1; + clk = &priv->asyncclk; + break; + default: + return -EINVAL; + } + + switch (freq) { + case 5644800: + case 6144000: + break; + case 11289600: + case 12288000: + val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + case 22579200: + case 24576000: + val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + case 45158400: + case 49152000: + val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; + break; + default: + return -EINVAL; + } + + *clk = freq; + + if (freq % 6144000) + val |= ARIZONA_SYSCLK_FRAC; + + dev_dbg(arizona->dev, "%s set to %uHz", name, freq); + + return regmap_update_bits(arizona->regmap, reg, mask, val); +} +EXPORT_SYMBOL_GPL(arizona_set_sysclk); + +static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + int lrclk, bclk, mode, base; + + base = dai->driver->base; + + lrclk = 0; + bclk = 0; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + mode = 0; + break; + case SND_SOC_DAIFMT_DSP_B: + mode = 1; + break; + case SND_SOC_DAIFMT_I2S: + mode = 2; + break; + case SND_SOC_DAIFMT_LEFT_J: + mode = 3; + break; + default: + arizona_aif_err(dai, "Unsupported DAI format %d\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBS_CFM: + lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + bclk |= ARIZONA_AIF1_BCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + bclk |= ARIZONA_AIF1_BCLK_MSTR; + lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; + break; + default: + arizona_aif_err(dai, "Unsupported master mode %d\n", + fmt & SND_SOC_DAIFMT_MASTER_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + bclk |= ARIZONA_AIF1_BCLK_INV; + lrclk |= ARIZONA_AIF1TX_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + bclk |= ARIZONA_AIF1_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + lrclk |= ARIZONA_AIF1TX_LRCLK_INV; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, + ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR, + bclk); + snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL, + ARIZONA_AIF1TX_LRCLK_INV | + ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); + snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL, + ARIZONA_AIF1RX_LRCLK_INV | + ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); + snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT, + ARIZONA_AIF1_FMT_MASK, mode); + + return 0; +} + +static const int arizona_48k_rates[] = { + -1, + 48000, + 64000, + 96000, + 128000, + 192000, + 256000, + 384000, + 512000, + 768000, + 1024000, + 1536000, + 2048000, + 3072000, + 4096000, + 6144000, + 8192000, + 12288000, + 24576000, +}; + +static const int arizona_44k1_rates[] = { + -1, + 44100, + 58800, + 88200, + 117600, + 177640, + 235200, + 352800, + 470400, + 705600, + 940800, + 1411200, + 1881600, + 2882400, + 3763200, + 5644800, + 7526400, + 11289600, + 22579200, +}; + +static int arizona_sr_vals[] = { + 0, + 12000, + 24000, + 48000, + 96000, + 192000, + 384000, + 768000, + 0, + 11025, + 22050, + 44100, + 88200, + 176400, + 352800, + 705600, + 4000, + 8000, + 16000, + 32000, + 64000, + 128000, + 256000, + 512000, +}; + +static int arizona_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + int base = dai->driver->base; + const int *rates; + int i; + int bclk, lrclk, wl, frame, sr_val; + + if (params_rate(params) % 8000) + rates = &arizona_44k1_rates[0]; + else + rates = &arizona_48k_rates[0]; + + for (i = 0; i < ARRAY_SIZE(arizona_44k1_rates); i++) { + if (rates[i] == snd_soc_params_to_bclk(params)) { + bclk = i; + break; + } + } + if (i == ARRAY_SIZE(arizona_44k1_rates)) { + arizona_aif_err(dai, "Unsupported sample rate %dHz\n", + params_rate(params)); + return -EINVAL; + } + + /* + * We will need to be more flexible than this in future, + * currently we use a single sample rate for the chip. + */ + for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++) + if (arizona_sr_vals[i] == params_rate(params)) + break; + if (i == ARRAY_SIZE(arizona_sr_vals)) { + arizona_aif_err(dai, "Unsupported sample rate %dHz\n", + params_rate(params)); + return -EINVAL; + } + sr_val = i; + + lrclk = snd_soc_params_to_bclk(params) / params_rate(params); + + arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", + rates[bclk], rates[bclk] / lrclk); + + wl = snd_pcm_format_width(params_format(params)); + frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; + + snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1, + ARIZONA_SAMPLE_RATE_1_MASK, sr_val); + snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, + ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); + snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE, + ARIZONA_AIF1TX_BCPF_MASK, lrclk); + snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE, + ARIZONA_AIF1RX_BCPF_MASK, lrclk); + snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1, + ARIZONA_AIF1TX_WL_MASK | + ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); + snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2, + ARIZONA_AIF1RX_WL_MASK | + ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); + + return 0; +} + +const struct snd_soc_dai_ops arizona_dai_ops = { + .set_fmt = arizona_set_fmt, + .hw_params = arizona_hw_params, +}; + +static irqreturn_t arizona_fll_lock(int irq, void *data) +{ + struct arizona_fll *fll = data; + + arizona_fll_dbg(fll, "Locked\n"); + + complete(&fll->lock); + + return IRQ_HANDLED; +} + +static irqreturn_t arizona_fll_clock_ok(int irq, void *data) +{ + struct arizona_fll *fll = data; + + arizona_fll_dbg(fll, "clock OK\n"); + + complete(&fll->ok); + + return IRQ_HANDLED; +} + +static struct { + unsigned int min; + unsigned int max; + u16 fratio; + int ratio; +} fll_fratios[] = { + { 0, 64000, 4, 16 }, + { 64000, 128000, 3, 8 }, + { 128000, 256000, 2, 4 }, + { 256000, 1000000, 1, 2 }, + { 1000000, 13500000, 0, 1 }, +}; + +struct arizona_fll_cfg { + int n; + int theta; + int lambda; + int refdiv; + int outdiv; + int fratio; +}; + +static int arizona_calc_fll(struct arizona_fll *fll, + struct arizona_fll_cfg *cfg, + unsigned int Fref, + unsigned int Fout) +{ + unsigned int target, div, gcd_fll; + int i, ratio; + + arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout); + + /* Fref must be <=13.5MHz */ + div = 1; + cfg->refdiv = 0; + while ((Fref / div) > 13500000) { + div *= 2; + cfg->refdiv++; + + if (div > 8) { + arizona_fll_err(fll, + "Can't scale %dMHz in to <=13.5MHz\n", + Fref); + return -EINVAL; + } + } + + /* Apply the division for our remaining calculations */ + Fref /= div; + + /* Fvco should be 90-100MHz; don't check the upper bound */ + div = 1; + while (Fout * div < 90000000) { + div++; + if (div > 7) { + arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", + Fout); + return -EINVAL; + } + } + target = Fout * div; + cfg->outdiv = div; + + arizona_fll_dbg(fll, "Fvco=%dHz\n", target); + + /* Find an appropraite FLL_FRATIO and factor it out of the target */ + for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { + if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { + cfg->fratio = fll_fratios[i].fratio; + ratio = fll_fratios[i].ratio; + break; + } + } + if (i == ARRAY_SIZE(fll_fratios)) { + arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", + Fref); + return -EINVAL; + } + + cfg->n = target / (ratio * Fref); + + if (target % Fref) { + gcd_fll = gcd(target, ratio * Fref); + arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll); + + cfg->theta = (target - (cfg->n * ratio * Fref)) + / gcd_fll; + cfg->lambda = (ratio * Fref) / gcd_fll; + } else { + cfg->theta = 0; + cfg->lambda = 0; + } + + arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", + cfg->n, cfg->theta, cfg->lambda); + arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", + cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); + + return 0; + +} + +static void arizona_apply_fll(struct arizona *arizona, unsigned int base, + struct arizona_fll_cfg *cfg, int source) +{ + regmap_update_bits(arizona->regmap, base + 3, + ARIZONA_FLL1_THETA_MASK, cfg->theta); + regmap_update_bits(arizona->regmap, base + 4, + ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); + regmap_update_bits(arizona->regmap, base + 5, + ARIZONA_FLL1_FRATIO_MASK, + cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); + regmap_update_bits(arizona->regmap, base + 6, + ARIZONA_FLL1_CLK_REF_DIV_MASK | + ARIZONA_FLL1_CLK_REF_SRC_MASK, + cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | + source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); + + regmap_update_bits(arizona->regmap, base + 2, + ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, + ARIZONA_FLL1_CTRL_UPD | cfg->n); +} + +int arizona_set_fll(struct arizona_fll *fll, int source, + unsigned int Fref, unsigned int Fout) +{ + struct arizona *arizona = fll->arizona; + struct arizona_fll_cfg cfg, sync; + unsigned int reg, val; + int syncsrc; + bool ena; + int ret; + + ret = regmap_read(arizona->regmap, fll->base + 1, ®); + if (ret != 0) { + arizona_fll_err(fll, "Failed to read current state: %d\n", + ret); + return ret; + } + ena = reg & ARIZONA_FLL1_ENA; + + if (Fout) { + /* Do we have a 32kHz reference? */ + regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); + switch (val & ARIZONA_CLK_32K_SRC_MASK) { + case ARIZONA_CLK_SRC_MCLK1: + case ARIZONA_CLK_SRC_MCLK2: + syncsrc = val & ARIZONA_CLK_32K_SRC_MASK; + break; + default: + syncsrc = -1; + } + + if (source == syncsrc) + syncsrc = -1; + + if (syncsrc >= 0) { + ret = arizona_calc_fll(fll, &sync, Fref, Fout); + if (ret != 0) + return ret; + + ret = arizona_calc_fll(fll, &cfg, 32768, Fout); + if (ret != 0) + return ret; + } else { + ret = arizona_calc_fll(fll, &cfg, Fref, Fout); + if (ret != 0) + return ret; + } + } else { + regmap_update_bits(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_ENA, 0); + regmap_update_bits(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, 0); + + if (ena) + pm_runtime_put_autosuspend(arizona->dev); + + return 0; + } + + regmap_update_bits(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); + + if (syncsrc >= 0) { + arizona_apply_fll(arizona, fll->base, &cfg, syncsrc); + arizona_apply_fll(arizona, fll->base + 0x10, &sync, source); + } else { + arizona_apply_fll(arizona, fll->base, &cfg, source); + } + + if (!ena) + pm_runtime_get(arizona->dev); + + /* Clear any pending completions */ + try_wait_for_completion(&fll->ok); + + regmap_update_bits(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); + if (syncsrc >= 0) + regmap_update_bits(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, + ARIZONA_FLL1_SYNC_ENA); + + ret = wait_for_completion_timeout(&fll->ok, + msecs_to_jiffies(25)); + if (ret == 0) + arizona_fll_warn(fll, "Timed out waiting for lock\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_set_fll); + +int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, + int ok_irq, struct arizona_fll *fll) +{ + int ret; + + init_completion(&fll->lock); + init_completion(&fll->ok); + + fll->id = id; + fll->base = base; + fll->arizona = arizona; + + snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); + snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), + "FLL%d clock OK", id); + + ret = arizona_request_irq(arizona, lock_irq, fll->lock_name, + arizona_fll_lock, fll); + if (ret != 0) { + dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n", + id, ret); + } + + ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name, + arizona_fll_clock_ok, fll); + if (ret != 0) { + dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n", + id, ret); + } + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_init_fll); + +MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h new file mode 100644 index 000000000000..8c2ca1d9dbae --- /dev/null +++ b/sound/soc/codecs/arizona.h @@ -0,0 +1,149 @@ +/* + * arizona.h - Wolfson Arizona class device shared support + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _ASOC_ARIZONA_H +#define _ASOC_ARIZONA_H + +#include + +#include + +#define ARIZONA_CLK_SYSCLK 1 +#define ARIZONA_CLK_ASYNCCLK 2 + +#define ARIZONA_CLK_SRC_MCLK1 0x0 +#define ARIZONA_CLK_SRC_MCLK2 0x1 +#define ARIZONA_CLK_SRC_FLL1 0x4 +#define ARIZONA_CLK_SRC_FLL2 0x5 +#define ARIZONA_CLK_SRC_AIF1BCLK 0x8 +#define ARIZONA_CLK_SRC_AIF2BCLK 0x9 +#define ARIZONA_CLK_SRC_AIF3BCLK 0xa + +#define ARIZONA_FLL_SRC_MCLK1 0 +#define ARIZONA_FLL_SRC_MCLK2 1 +#define ARIZONA_FLL_SRC_SLIMCLK 2 +#define ARIZONA_FLL_SRC_FLL1 3 +#define ARIZONA_FLL_SRC_FLL2 4 +#define ARIZONA_FLL_SRC_AIF1BCLK 5 +#define ARIZONA_FLL_SRC_AIF2BCLK 6 +#define ARIZONA_FLL_SRC_AIF3BCLK 7 +#define ARIZONA_FLL_SRC_AIF1LRCLK 8 +#define ARIZONA_FLL_SRC_AIF2LRCLK 9 +#define ARIZONA_FLL_SRC_AIF3LRCLK 10 + +#define ARIZONA_MIXER_VOL_MASK 0x00FE +#define ARIZONA_MIXER_VOL_SHIFT 1 +#define ARIZONA_MIXER_VOL_WIDTH 7 + +struct arizona; + +struct arizona_priv { + struct arizona *arizona; + int sysclk; + int asyncclk; +}; + +#define ARIZONA_NUM_MIXER_INPUTS 55 + +extern const unsigned int arizona_mixer_tlv[]; +extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; +extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; + +#define ARIZONA_MIXER_CONTROLS(name, base) \ + SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \ + ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ + arizona_mixer_tlv), \ + SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \ + ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ + arizona_mixer_tlv), \ + SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \ + ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ + arizona_mixer_tlv), \ + SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \ + ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ + arizona_mixer_tlv) + +#define ARIZONA_MUX_ENUM_DECL(name, reg) \ + SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ + arizona_mixer_texts, arizona_mixer_values) + +#define ARIZONA_MUX_CTL_DECL(name) \ + const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_VALUE_ENUM("Route", name##_enum) + +#define ARIZONA_MIXER_ENUMS(name, base_reg) \ + static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ + static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ + static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ + static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ + static ARIZONA_MUX_CTL_DECL(name##_in1); \ + static ARIZONA_MUX_CTL_DECL(name##_in2); \ + static ARIZONA_MUX_CTL_DECL(name##_in3); \ + static ARIZONA_MUX_CTL_DECL(name##_in4) + +#define ARIZONA_MUX(name, ctrl) \ + SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + +#define ARIZONA_MIXER_WIDGETS(name, name_str) \ + ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \ + ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \ + ARIZONA_MUX(name_str " Input 3", &name##_in3_mux), \ + ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \ + SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) + +#define ARIZONA_MIXER_ROUTES(widget, name) \ + { widget, NULL, name " Mixer" }, \ + { name " Mixer", NULL, name " Input 1" }, \ + { name " Mixer", NULL, name " Input 2" }, \ + { name " Mixer", NULL, name " Input 3" }, \ + { name " Mixer", NULL, name " Input 4" }, \ + ARIZONA_MIXER_INPUT_ROUTES(name " Input 1"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Input 2"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \ + ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") + +extern const struct soc_enum arizona_lhpf1_mode; +extern const struct soc_enum arizona_lhpf2_mode; +extern const struct soc_enum arizona_lhpf3_mode; +extern const struct soc_enum arizona_lhpf4_mode; + +extern int arizona_in_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event); +extern int arizona_out_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event); + +extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, + int source, unsigned int freq, int dir); + +extern const struct snd_soc_dai_ops arizona_dai_ops; + +#define ARIZONA_FLL_NAME_LEN 20 + +struct arizona_fll { + struct arizona *arizona; + int id; + unsigned int base; + struct completion lock; + struct completion ok; + + char lock_name[ARIZONA_FLL_NAME_LEN]; + char clock_ok_name[ARIZONA_FLL_NAME_LEN]; +}; + +extern int arizona_init_fll(struct arizona *arizona, int id, int base, + int lock_irq, int ok_irq, struct arizona_fll *fll); +extern int arizona_set_fll(struct arizona_fll *fll, int source, + unsigned int Fref, unsigned int Fout); + +#endif -- GitLab From 93e8791dd34ca0c3371d65c4488249d41de02776 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 19 Jun 2012 16:38:15 +0100 Subject: [PATCH 2590/6849] ASoC: wm5102: Initial driver The WM5102 is a highly-integrated low-power audio system for smartphones, tablets and other portable audio devices based on the Arizona platform. Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm5102.c | 870 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm5102.h | 21 + 4 files changed, 897 insertions(+) create mode 100644 sound/soc/codecs/wm5102.c create mode 100644 sound/soc/codecs/wm5102.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 2ae8082f23b5..1de24ccfe1c3 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -73,6 +73,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM2000 if I2C select SND_SOC_WM2200 if I2C select SND_SOC_WM5100 if I2C + select SND_SOC_WM5102 if MFD_WM5102 select SND_SOC_WM8350 if MFD_WM8350 select SND_SOC_WM8400 if MFD_WM8400 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI @@ -330,6 +331,9 @@ config SND_SOC_WM2200 config SND_SOC_WM5100 tristate +config SND_SOC_WM5102 + tristate + config SND_SOC_WM8350 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3005ea6c1fd8..d35ba7f06fcf 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -63,6 +63,7 @@ snd-soc-wm1250-ev1-objs := wm1250-ev1.o snd-soc-wm2000-objs := wm2000.o snd-soc-wm2200-objs := wm2200.o snd-soc-wm5100-objs := wm5100.o wm5100-tables.o +snd-soc-wm5102-objs := wm5102.o snd-soc-wm8350-objs := wm8350.o snd-soc-wm8400-objs := wm8400.o snd-soc-wm8510-objs := wm8510.o @@ -176,6 +177,7 @@ obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o +obj-$(CONFIG_SND_SOC_WM5102) += snd-soc-wm5102.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c new file mode 100644 index 000000000000..9b9ea7fd0d7d --- /dev/null +++ b/sound/soc/codecs/wm5102.c @@ -0,0 +1,870 @@ +/* + * wm5102.c -- WM5102 ALSA SoC Audio driver + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "arizona.h" +#include "wm5102.h" + +struct wm5102_priv { + struct arizona_priv core; + struct arizona_fll fll[2]; +}; + +static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); +static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); +static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); +static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); + +static const struct snd_kcontrol_new wm5102_snd_controls[] = { +SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, + ARIZONA_IN1_OSR_SHIFT, 1, 0), +SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL, + ARIZONA_IN2_OSR_SHIFT, 1, 0), +SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL, + ARIZONA_IN3_OSR_SHIFT, 1, 0), + +SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL, + ARIZONA_IN1R_CONTROL, + ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), +SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL, + ARIZONA_IN2R_CONTROL, + ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), +SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL, + ARIZONA_IN3R_CONTROL, + ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), + +SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L, + ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L, + ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L, + ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1), + +SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L, + ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_PGA_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L, + ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_PGA_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L, + ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_PGA_VOL_SHIFT, + 0xbf, 0, digital_tlv), + +ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE), + +SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT, + 24, 0, eq_tlv), + +SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT, + 24, 0, eq_tlv), + +SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT, + 24, 0, eq_tlv), + +SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT, + 24, 0, eq_tlv), +SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT, + 24, 0, eq_tlv), + +ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE), + +SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5, + ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA), +SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5, + ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA), + +ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE), + +SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode), +SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), +SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), +SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), + +ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), + +SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR, + ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv), + +ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), + +SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L, + ARIZONA_OUT1_OSR_SHIFT, 1, 0), +SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, + ARIZONA_OUT2_OSR_SHIFT, 1, 0), +SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, + ARIZONA_OUT3_OSR_SHIFT, 1, 0), +SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, + ARIZONA_OUT4_OSR_SHIFT, 1, 0), +SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, + ARIZONA_OUT5_OSR_SHIFT, 1, 0), + +SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, + ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, + ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1), +SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L, + ARIZONA_OUT3L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L, + ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L, + ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1), + +SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L, + ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L, + ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L, + ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L, + ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, + ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, + 0xbf, 0, digital_tlv), + +SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L, + ARIZONA_OUTPUT_PATH_CONFIG_1R, + ARIZONA_OUT1L_PGA_VOL_SHIFT, + 0x34, 0x40, 0, ana_tlv), +SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L, + ARIZONA_OUTPUT_PATH_CONFIG_2R, + ARIZONA_OUT2L_PGA_VOL_SHIFT, + 0x34, 0x40, 0, ana_tlv), +SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, + ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), + +SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, + ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), + +ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE), + +ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE), + +ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), +}; + +ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(SPKDAT1R, ARIZONA_OUT5RMIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); + +static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { +SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, + 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, + ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), +SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0), + +SND_SOC_DAPM_SIGGEN("TONE"), +SND_SOC_DAPM_SIGGEN("NOISE"), + +SND_SOC_DAPM_INPUT("IN1L"), +SND_SOC_DAPM_INPUT("IN1R"), +SND_SOC_DAPM_INPUT("IN2L"), +SND_SOC_DAPM_INPUT("IN2R"), +SND_SOC_DAPM_INPUT("IN3L"), +SND_SOC_DAPM_INPUT("IN3R"), + +SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, + 0, NULL, 0, arizona_in_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, + 0, NULL, 0, arizona_in_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, + 0, NULL, 0, arizona_in_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, + 0, NULL, 0, arizona_in_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, + 0, NULL, 0, arizona_in_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, + 0, NULL, 0, arizona_in_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + +SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, + ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2, + ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3, + ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR, + ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1, + ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1, + ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("Mic Mute Mixer", ARIZONA_MIC_NOISE_MIX_CONTROL_1, + ARIZONA_MICMUTE_MIX_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0, + NULL, 0), + +SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0, + NULL, 0), + +SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT, + 0, NULL, 0), +SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT, + 0, NULL, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0, + ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0), + +SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0, + ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0), + +SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, + ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0, + ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0), + +SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, + ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0, + ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0), + +SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0, + ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0, + ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0), + +SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, + ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, + ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), + +SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + +ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"), +ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"), +ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"), +ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"), + +ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"), +ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"), +ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"), +ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"), + +ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"), +ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"), +ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"), +ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"), + +ARIZONA_MIXER_WIDGETS(Mic, "Mic"), +ARIZONA_MIXER_WIDGETS(Noise, "Noise"), + +ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"), +ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"), + +ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"), +ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"), +ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"), +ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"), +ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"), +ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"), +ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"), +ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"), +ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"), + +ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), +ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), +ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), +ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), +ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), +ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), +ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"), +ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"), + +ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"), +ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), + +ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), +ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), + +SND_SOC_DAPM_OUTPUT("HPOUT1L"), +SND_SOC_DAPM_OUTPUT("HPOUT1R"), +SND_SOC_DAPM_OUTPUT("HPOUT2L"), +SND_SOC_DAPM_OUTPUT("HPOUT2R"), +SND_SOC_DAPM_OUTPUT("EPOUTN"), +SND_SOC_DAPM_OUTPUT("EPOUTP"), +SND_SOC_DAPM_OUTPUT("SPKOUTLN"), +SND_SOC_DAPM_OUTPUT("SPKOUTLP"), +SND_SOC_DAPM_OUTPUT("SPKOUTRN"), +SND_SOC_DAPM_OUTPUT("SPKOUTRP"), +SND_SOC_DAPM_OUTPUT("SPKDAT1L"), +SND_SOC_DAPM_OUTPUT("SPKDAT1R"), +}; + +#define ARIZONA_MIXER_INPUT_ROUTES(name) \ + { name, "Noise Generator", "Noise Generator" }, \ + { name, "Tone Generator 1", "Tone Generator 1" }, \ + { name, "Tone Generator 2", "Tone Generator 2" }, \ + { name, "IN1L", "IN1L PGA" }, \ + { name, "IN1R", "IN1R PGA" }, \ + { name, "IN2L", "IN2L PGA" }, \ + { name, "IN2R", "IN2R PGA" }, \ + { name, "IN3L", "IN3L PGA" }, \ + { name, "IN3R", "IN3R PGA" }, \ + { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \ + { name, "AIF1RX1", "AIF1RX1" }, \ + { name, "AIF1RX2", "AIF1RX2" }, \ + { name, "AIF1RX3", "AIF1RX3" }, \ + { name, "AIF1RX4", "AIF1RX4" }, \ + { name, "AIF1RX5", "AIF1RX5" }, \ + { name, "AIF1RX6", "AIF1RX6" }, \ + { name, "AIF1RX7", "AIF1RX7" }, \ + { name, "AIF1RX8", "AIF1RX8" }, \ + { name, "AIF2RX1", "AIF2RX1" }, \ + { name, "AIF2RX2", "AIF2RX2" }, \ + { name, "AIF3RX1", "AIF3RX1" }, \ + { name, "AIF3RX2", "AIF3RX2" }, \ + { name, "EQ1", "EQ1" }, \ + { name, "EQ2", "EQ2" }, \ + { name, "EQ3", "EQ3" }, \ + { name, "EQ4", "EQ4" }, \ + { name, "DRC1L", "DRC1L" }, \ + { name, "DRC1R", "DRC1R" }, \ + { name, "DRC2L", "DRC2L" }, \ + { name, "DRC2R", "DRC2R" }, \ + { name, "LHPF1", "LHPF1" }, \ + { name, "LHPF2", "LHPF2" }, \ + { name, "LHPF3", "LHPF3" }, \ + { name, "LHPF4", "LHPF4" } + +static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { + { "AIF2 Capture", NULL, "DBVDD2" }, + { "AIF2 Playback", NULL, "DBVDD2" }, + + { "AIF3 Capture", NULL, "DBVDD3" }, + { "AIF3 Playback", NULL, "DBVDD3" }, + + { "OUT1L", NULL, "CPVDD" }, + { "OUT1R", NULL, "CPVDD" }, + { "OUT2L", NULL, "CPVDD" }, + { "OUT2R", NULL, "CPVDD" }, + { "OUT3L", NULL, "CPVDD" }, + + { "OUT4L", NULL, "SPKVDDL" }, + { "OUT4R", NULL, "SPKVDDR" }, + + { "OUT1L", NULL, "SYSCLK" }, + { "OUT1R", NULL, "SYSCLK" }, + { "OUT2L", NULL, "SYSCLK" }, + { "OUT2R", NULL, "SYSCLK" }, + { "OUT3L", NULL, "SYSCLK" }, + { "OUT4L", NULL, "SYSCLK" }, + { "OUT4R", NULL, "SYSCLK" }, + { "OUT5L", NULL, "SYSCLK" }, + { "OUT5R", NULL, "SYSCLK" }, + + { "MICBIAS1", NULL, "MICVDD" }, + { "MICBIAS2", NULL, "MICVDD" }, + { "MICBIAS3", NULL, "MICVDD" }, + + { "Noise Generator", NULL, "NOISE" }, + { "Tone Generator 1", NULL, "TONE" }, + { "Tone Generator 2", NULL, "TONE" }, + + { "Mic Mute Mixer", NULL, "Noise Mixer" }, + { "Mic Mute Mixer", NULL, "Mic Mixer" }, + + { "AIF1 Capture", NULL, "AIF1TX1" }, + { "AIF1 Capture", NULL, "AIF1TX2" }, + { "AIF1 Capture", NULL, "AIF1TX3" }, + { "AIF1 Capture", NULL, "AIF1TX4" }, + { "AIF1 Capture", NULL, "AIF1TX5" }, + { "AIF1 Capture", NULL, "AIF1TX6" }, + { "AIF1 Capture", NULL, "AIF1TX7" }, + { "AIF1 Capture", NULL, "AIF1TX8" }, + + { "AIF1RX1", NULL, "AIF1 Playback" }, + { "AIF1RX2", NULL, "AIF1 Playback" }, + { "AIF1RX3", NULL, "AIF1 Playback" }, + { "AIF1RX4", NULL, "AIF1 Playback" }, + { "AIF1RX5", NULL, "AIF1 Playback" }, + { "AIF1RX6", NULL, "AIF1 Playback" }, + { "AIF1RX7", NULL, "AIF1 Playback" }, + { "AIF1RX8", NULL, "AIF1 Playback" }, + + { "AIF2 Capture", NULL, "AIF2TX1" }, + { "AIF2 Capture", NULL, "AIF2TX2" }, + + { "AIF2RX1", NULL, "AIF2 Playback" }, + { "AIF2RX2", NULL, "AIF2 Playback" }, + + { "AIF3 Capture", NULL, "AIF3TX1" }, + { "AIF3 Capture", NULL, "AIF3TX2" }, + + { "AIF3RX1", NULL, "AIF3 Playback" }, + { "AIF3RX2", NULL, "AIF3 Playback" }, + + { "AIF1 Playback", NULL, "SYSCLK" }, + { "AIF2 Playback", NULL, "SYSCLK" }, + { "AIF3 Playback", NULL, "SYSCLK" }, + + { "AIF1 Capture", NULL, "SYSCLK" }, + { "AIF2 Capture", NULL, "SYSCLK" }, + { "AIF3 Capture", NULL, "SYSCLK" }, + + ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), + ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), + ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), + ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"), + ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"), + + ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"), + ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"), + ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"), + ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"), + + ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"), + ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"), + + ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), + ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), + ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), + ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), + ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), + ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), + ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"), + ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"), + + ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"), + ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"), + + ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), + ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), + + ARIZONA_MIXER_ROUTES("EQ1", "EQ1"), + ARIZONA_MIXER_ROUTES("EQ2", "EQ2"), + ARIZONA_MIXER_ROUTES("EQ3", "EQ3"), + ARIZONA_MIXER_ROUTES("EQ4", "EQ4"), + + ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"), + ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"), + ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"), + ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"), + + ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"), + ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"), + ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), + ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), + + { "HPOUT1L", NULL, "OUT1L" }, + { "HPOUT1R", NULL, "OUT1R" }, + + { "HPOUT2L", NULL, "OUT2L" }, + { "HPOUT2R", NULL, "OUT2R" }, + + { "EPOUTN", NULL, "OUT3L" }, + { "EPOUTP", NULL, "OUT3L" }, + + { "SPKOUTLN", NULL, "OUT4L" }, + { "SPKOUTLP", NULL, "OUT4L" }, + + { "SPKOUTRN", NULL, "OUT4R" }, + { "SPKOUTRP", NULL, "OUT4R" }, + + { "SPKDAT1L", NULL, "OUT5L" }, + { "SPKDAT1R", NULL, "OUT5R" }, +}; + +static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, + unsigned int Fref, unsigned int Fout) +{ + struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec); + + switch (fll_id) { + case WM5102_FLL1: + return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); + case WM5102_FLL2: + return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); + default: + return -EINVAL; + } +} + +#define WM5102_RATES SNDRV_PCM_RATE_8000_192000 + +#define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver wm5102_dai[] = { + { + .name = "wm5102-aif1", + .id = 1, + .base = ARIZONA_AIF1_BCLK_CTRL, + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 8, + .rates = WM5102_RATES, + .formats = WM5102_FORMATS, + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 8, + .rates = WM5102_RATES, + .formats = WM5102_FORMATS, + }, + .ops = &arizona_dai_ops, + .symmetric_rates = 1, + }, + { + .name = "wm5102-aif2", + .id = 2, + .base = ARIZONA_AIF2_BCLK_CTRL, + .playback = { + .stream_name = "AIF2 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM5102_RATES, + .formats = WM5102_FORMATS, + }, + .capture = { + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM5102_RATES, + .formats = WM5102_FORMATS, + }, + .ops = &arizona_dai_ops, + .symmetric_rates = 1, + }, + { + .name = "wm5102-aif3", + .id = 3, + .base = ARIZONA_AIF3_BCLK_CTRL, + .playback = { + .stream_name = "AIF3 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM5102_RATES, + .formats = WM5102_FORMATS, + }, + .capture = { + .stream_name = "AIF3 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM5102_RATES, + .formats = WM5102_FORMATS, + }, + .ops = &arizona_dai_ops, + .symmetric_rates = 1, + }, +}; + +static int wm5102_codec_probe(struct snd_soc_codec *codec) +{ + struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); + + codec->control_data = priv->core.arizona->regmap; + return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP); +} + +#define WM5102_DIG_VU 0x0200 + +static unsigned int wm5102_digital_vu[] = { + ARIZONA_ADC_DIGITAL_VOLUME_1L, + ARIZONA_ADC_DIGITAL_VOLUME_1R, + ARIZONA_ADC_DIGITAL_VOLUME_2L, + ARIZONA_ADC_DIGITAL_VOLUME_2R, + ARIZONA_ADC_DIGITAL_VOLUME_3L, + ARIZONA_ADC_DIGITAL_VOLUME_3R, + + ARIZONA_DAC_DIGITAL_VOLUME_1L, + ARIZONA_DAC_DIGITAL_VOLUME_1R, + ARIZONA_DAC_DIGITAL_VOLUME_2L, + ARIZONA_DAC_DIGITAL_VOLUME_2R, + ARIZONA_DAC_DIGITAL_VOLUME_3L, + ARIZONA_DAC_DIGITAL_VOLUME_3R, + ARIZONA_DAC_DIGITAL_VOLUME_4L, + ARIZONA_DAC_DIGITAL_VOLUME_4R, + ARIZONA_DAC_DIGITAL_VOLUME_5L, + ARIZONA_DAC_DIGITAL_VOLUME_5R, +}; + +static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { + .probe = wm5102_codec_probe, + + .idle_bias_off = true, + + .set_sysclk = arizona_set_sysclk, + .set_pll = wm5102_set_fll, + + .controls = wm5102_snd_controls, + .num_controls = ARRAY_SIZE(wm5102_snd_controls), + .dapm_widgets = wm5102_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets), + .dapm_routes = wm5102_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), +}; + +static int __devinit wm5102_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct wm5102_priv *wm5102; + int i; + + wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv), + GFP_KERNEL); + if (wm5102 == NULL) + return -ENOMEM; + platform_set_drvdata(pdev, wm5102); + + wm5102->core.arizona = arizona; + + arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1, + ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK, + &wm5102->fll[0]); + arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1, + ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, + &wm5102->fll[1]); + + /* Latch volume update bits */ + for (i = 0; i < ARRAY_SIZE(wm5102_digital_vu); i++) + regmap_update_bits(arizona->regmap, wm5102_digital_vu[i], + WM5102_DIG_VU, WM5102_DIG_VU); + + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102, + wm5102_dai, ARRAY_SIZE(wm5102_dai)); +} + +static int __devexit wm5102_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static struct platform_driver wm5102_codec_driver = { + .driver = { + .name = "wm5102-codec", + .owner = THIS_MODULE, + }, + .probe = wm5102_probe, + .remove = __devexit_p(wm5102_remove), +}; + +module_platform_driver(wm5102_codec_driver); + +MODULE_DESCRIPTION("ASoC WM5102 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wm5102-codec"); diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h new file mode 100644 index 000000000000..d30477f3070c --- /dev/null +++ b/sound/soc/codecs/wm5102.h @@ -0,0 +1,21 @@ +/* + * wm5102.h -- WM5102 ALSA SoC Audio driver + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _WM5102_H +#define _WM5102_H + +#include "arizona.h" + +#define WM5102_FLL1 1 +#define WM5102_FLL2 2 + +#endif -- GitLab From b5152415225ba0d489939778f3b85217b25036db Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Jun 2012 09:38:26 +0800 Subject: [PATCH 2591/6849] regulator: tps62360: Remove chip_id and voltage_base from struct tps62360_chip The chip_id is not used. The voltage_base is not necessary, set base voltage to tps->desc.min_uV instead. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps62360-regulator.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index d044a58640e7..bcea4e1eea1e 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -65,10 +65,8 @@ struct tps62360_chip { struct regulator_desc desc; struct regulator_dev *rdev; struct regmap *regmap; - int chip_id; int vsel0_gpio; int vsel1_gpio; - int voltage_base; u8 voltage_reg_mask; bool en_internal_pulldn; bool en_discharge; @@ -401,13 +399,13 @@ static int __devinit tps62360_probe(struct i2c_client *client, switch (chip_id) { case TPS62360: case TPS62362: - tps->voltage_base = TPS62360_BASE_VOLTAGE; + tps->desc.min_uV = TPS62360_BASE_VOLTAGE; tps->voltage_reg_mask = 0x3F; tps->desc.n_voltages = TPS62360_N_VOLTAGES; break; case TPS62361: case TPS62363: - tps->voltage_base = TPS62361_BASE_VOLTAGE; + tps->desc.min_uV = TPS62361_BASE_VOLTAGE; tps->voltage_reg_mask = 0x7F; tps->desc.n_voltages = TPS62361_N_VOLTAGES; break; @@ -420,7 +418,6 @@ static int __devinit tps62360_probe(struct i2c_client *client, tps->desc.ops = &tps62360_dcdc_ops; tps->desc.type = REGULATOR_VOLTAGE; tps->desc.owner = THIS_MODULE; - tps->desc.min_uV = tps->voltage_base; tps->desc.uV_step = 10000; tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); -- GitLab From 9a0fbb627cfa86303b8eb57377f536c64812cc85 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 17 Jun 2012 09:33:07 +0800 Subject: [PATCH 2592/6849] regulator: max8998: Convert to regulator_list_voltage_linear() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max8998.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 18bb58b9b96e..105dafca3369 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -111,27 +111,6 @@ static const struct voltage_map_desc *ldo_voltage_map[] = { &buck4_voltage_map_desc, /* BUCK4 */ }; -static int max8998_list_voltage(struct regulator_dev *rdev, - unsigned int selector) -{ - const struct voltage_map_desc *desc; - int ldo = rdev_get_id(rdev); - int val; - - if (ldo >= ARRAY_SIZE(ldo_voltage_map)) - return -EINVAL; - - desc = ldo_voltage_map[ldo]; - if (desc == NULL) - return -EINVAL; - - val = desc->min + desc->step * selector; - if (val > desc->max) - return -EINVAL; - - return val * 1000; -} - static int max8998_get_enable_register(struct regulator_dev *rdev, int *reg, int *shift) { @@ -392,8 +371,8 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, /* if previous_voltage equal new voltage, return */ if (previous_sel == i) { dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n", - max8998_list_voltage(rdev, previous_sel), - max8998_list_voltage(rdev, i)); + regulator_list_voltage_linear(rdev, previous_sel), + regulator_list_voltage_linear(rdev, i)); return ret; } @@ -519,7 +498,7 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, } static struct regulator_ops max8998_ldo_ops = { - .list_voltage = max8998_list_voltage, + .list_voltage = regulator_list_voltage_linear, .is_enabled = max8998_ldo_is_enabled, .enable = max8998_ldo_enable, .disable = max8998_ldo_disable, @@ -530,7 +509,7 @@ static struct regulator_ops max8998_ldo_ops = { }; static struct regulator_ops max8998_buck_ops = { - .list_voltage = max8998_list_voltage, + .list_voltage = regulator_list_voltage_linear, .is_enabled = max8998_ldo_is_enabled, .enable = max8998_ldo_enable, .disable = max8998_ldo_disable, @@ -860,7 +839,10 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) desc = ldo_voltage_map[id]; if (desc && regulators[index].ops != &max8998_others_ops) { int count = (desc->max - desc->min) / desc->step + 1; + regulators[index].n_voltages = count; + regulators[index].min_uV = desc->min * 1000; + regulators[index].uV_step = desc->step * 1000; } config.dev = max8998->dev; -- GitLab From baae019efe84b6d2c6d5e7e7e1c9cfa130ad6b2a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 17 Jun 2012 09:34:29 +0800 Subject: [PATCH 2593/6849] regulator: max8998: Convert to set_voltage_sel and regulator_map_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max8998.c | 97 +++++++++++-------------------------- 1 file changed, 27 insertions(+), 70 deletions(-) diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 105dafca3369..a1fa26613494 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -276,41 +276,18 @@ static int max8998_get_voltage_sel(struct regulator_dev *rdev) return val; } -static int max8998_set_voltage_ldo(struct regulator_dev *rdev, - int min_uV, int max_uV, unsigned *selector) +static int max8998_set_voltage_ldo_sel(struct regulator_dev *rdev, + unsigned selector) { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c; - int min_vol = min_uV / 1000, max_vol = max_uV / 1000; - const struct voltage_map_desc *desc; - int ldo = rdev_get_id(rdev); - int reg, shift = 0, mask, ret, i; - - if (ldo >= ARRAY_SIZE(ldo_voltage_map)) - return -EINVAL; - - desc = ldo_voltage_map[ldo]; - if (desc == NULL) - return -EINVAL; - - if (max_vol < desc->min || min_vol > desc->max) - return -EINVAL; - - if (min_vol < desc->min) - min_vol = desc->min; - - i = DIV_ROUND_UP(min_vol - desc->min, desc->step); - - if (desc->min + desc->step*i > max_vol) - return -EINVAL; - - *selector = i; + int reg, shift = 0, mask, ret; ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); if (ret) return ret; - ret = max8998_update_reg(i2c, reg, i<iodev->dev); struct i2c_client *i2c = max8998->iodev->i2c; - int min_vol = min_uV / 1000, max_vol = max_uV / 1000; - const struct voltage_map_desc *desc; int buck = rdev_get_id(rdev); int reg, shift = 0, mask, ret; - int i, j, previous_sel; + int j, previous_sel; static u8 buck1_last_val; - if (buck >= ARRAY_SIZE(ldo_voltage_map)) - return -EINVAL; - - desc = ldo_voltage_map[buck]; - - if (desc == NULL) - return -EINVAL; - - if (max_vol < desc->min || min_vol > desc->max) - return -EINVAL; - - if (min_vol < desc->min) - min_vol = desc->min; - - i = DIV_ROUND_UP(min_vol - desc->min, desc->step); - - if (desc->min + desc->step*i > max_vol) - return -EINVAL; - - *selector = i; - ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); if (ret) return ret; @@ -369,19 +323,19 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, /* Check if voltage needs to be changed */ /* if previous_voltage equal new voltage, return */ - if (previous_sel == i) { + if (previous_sel == selector) { dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n", regulator_list_voltage_linear(rdev, previous_sel), - regulator_list_voltage_linear(rdev, i)); + regulator_list_voltage_linear(rdev, selector)); return ret; } switch (buck) { case MAX8998_BUCK1: dev_dbg(max8998->dev, - "BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n" + "BUCK1, selector:%d, buck1_vol1:%d, buck1_vol2:%d\n" "buck1_vol3:%d, buck1_vol4:%d\n", - i, max8998->buck1_vol[0], max8998->buck1_vol[1], + selector, max8998->buck1_vol[0], max8998->buck1_vol[1], max8998->buck1_vol[2], max8998->buck1_vol[3]); if (gpio_is_valid(pdata->buck1_set1) && @@ -390,7 +344,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, /* check if requested voltage */ /* value is already defined */ for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) { - if (max8998->buck1_vol[j] == i) { + if (max8998->buck1_vol[j] == selector) { max8998->buck1_idx = j; buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, j); @@ -405,11 +359,11 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, max8998->buck1_idx = (buck1_last_val % 2) + 2; dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", max8998->buck1_idx); - max8998->buck1_vol[max8998->buck1_idx] = i; + max8998->buck1_vol[max8998->buck1_idx] = selector; ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); - ret = max8998_write_reg(i2c, reg, i); + ret = max8998_write_reg(i2c, reg, selector); buck1_gpio_set(pdata->buck1_set1, pdata->buck1_set2, max8998->buck1_idx); buck1_last_val++; @@ -419,20 +373,20 @@ buck1_exit: gpio_get_value(pdata->buck1_set2)); break; } else { - ret = max8998_write_reg(i2c, reg, i); + ret = max8998_write_reg(i2c, reg, selector); } break; case MAX8998_BUCK2: dev_dbg(max8998->dev, - "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" - , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); + "BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n", + selector, max8998->buck2_vol[0], max8998->buck2_vol[1]); if (gpio_is_valid(pdata->buck2_set3)) { /* check if requested voltage */ /* value is already defined */ for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) { - if (max8998->buck2_vol[j] == i) { + if (max8998->buck2_vol[j] == selector) { max8998->buck2_idx = j; buck2_gpio_set(pdata->buck2_set3, j); goto buck2_exit; @@ -444,20 +398,21 @@ buck1_exit: max8998_get_voltage_register(rdev, ®, &shift, &mask); - ret = max8998_write_reg(i2c, reg, i); - max8998->buck2_vol[max8998->buck2_idx] = i; + ret = max8998_write_reg(i2c, reg, selector); + max8998->buck2_vol[max8998->buck2_idx] = selector; buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx); buck2_exit: dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, gpio_get_value(pdata->buck2_set3)); } else { - ret = max8998_write_reg(i2c, reg, i); + ret = max8998_write_reg(i2c, reg, selector); } break; case MAX8998_BUCK3: case MAX8998_BUCK4: - ret = max8998_update_reg(i2c, reg, i< Date: Tue, 19 Jun 2012 09:38:45 +0800 Subject: [PATCH 2594/6849] regulator: Use list_voltage() to get voltage in regulator_set_voltage_time_sel With this change, regulator_set_voltage_time_sel() can be more generic and not limited to linear and table based mapping now. One side-effect of this change is that list_voltage() must be implemented. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 26b71048709b..e3597ab09be3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2296,8 +2296,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time); * Provided with the starting and target voltage selectors, this function * returns time in microseconds required to rise or fall to this new voltage * - * Drivers providing uV_step or volt_table in their regulator_desc and - * ramp_delay in regulation_constraints can use this as their + * Drivers providing ramp_delay in regulation_constraints can use this as their * set_voltage_time_sel() operation. */ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, @@ -2305,6 +2304,7 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int new_selector) { unsigned int ramp_delay = 0; + int old_volt, new_volt; if (rdev->constraints->ramp_delay) ramp_delay = rdev->constraints->ramp_delay; @@ -2316,19 +2316,14 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, return 0; } - if (rdev->desc->uV_step) { - return DIV_ROUND_UP(rdev->desc->uV_step * - abs(new_selector - old_selector), - ramp_delay); - } else if (rdev->desc->volt_table) { - return DIV_ROUND_UP(abs(rdev->desc->volt_table[new_selector] - - rdev->desc->volt_table[old_selector]), - ramp_delay); - } else { - rdev_warn(rdev, "Unsupported voltage mapping settings\n"); - } + /* sanity check */ + if (!rdev->desc->ops->list_voltage) + return -EINVAL; - return 0; + old_volt = rdev->desc->ops->list_voltage(rdev, old_selector); + new_volt = rdev->desc->ops->list_voltage(rdev, new_selector); + + return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); } EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); -- GitLab From 5870adc68fc39d81089f1e80efdf64b97e5c37a1 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Wed, 20 Jun 2012 17:16:05 +0200 Subject: [PATCH 2595/6849] batman-adv: only drop packets of known wifi clients bug introduced with 59b699cdee039d75915c354da06937102d1f9a84 If the source or destination mac address of an ethernet packet could not be found in the translation table the packet was dropped if AP isolation was turned on. This behavior would make it impossible to send broadcast packets over the mesh as the broadcast address will never enter the translation table. Signed-off-by: Marek Lindner Acked-by: Antonio Quartulli --- net/batman-adv/translation-table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a66c2dcd1088..660c40fe13ea 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -2031,10 +2031,10 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) { struct tt_local_entry *tt_local_entry = NULL; struct tt_global_entry *tt_global_entry = NULL; - bool ret = true; + bool ret = false; if (!atomic_read(&bat_priv->ap_isolation)) - return false; + goto out; tt_local_entry = tt_local_hash_find(bat_priv, dst); if (!tt_local_entry) @@ -2044,10 +2044,10 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) if (!tt_global_entry) goto out; - if (_is_ap_isolated(tt_local_entry, tt_global_entry)) + if (!_is_ap_isolated(tt_local_entry, tt_global_entry)) goto out; - ret = false; + ret = true; out: if (tt_global_entry) -- GitLab From 8b8e4bc0391f8abbcdb9e1c54415bcc0f4f5a2a0 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 20 Jun 2012 14:12:56 +0200 Subject: [PATCH 2596/6849] batman-adv: fix race condition in TT full-table replacement bug introduced with cea194d90b11aff7fc289149e4c7f305fad3535a In the current TT code, when a TT_Response containing a full table is received from an originator, first the node purges all the clients for that originator in the global translation-table and then merges the newly received table. During the purging phase each client deletion is done by means of a call_rcu() invocation and at the end of this phase the global entry counter for that originator is set to 0. However the invoked rcu function decreases the global entry counter for that originator by one too and since the rcu invocation is likely to be postponed, the node will end up in first setting the counter to 0 and then decreasing it one by one for each deleted client. This bug leads to having a wrong global entry counter for the related node, say X. Then when the node with the broken counter will answer to a TT_REQUEST on behalf of node X, it will create faulty TT_RESPONSE that will generate an unrecoverable situation on the node that asked for the full table recover. The non-recoverability is given by the fact that the node with the broken counter will keep answering on behalf of X because its knowledge about X's state (ttvn + tt_crc) is correct. To solve this problem the counter is not explicitly set to 0 anymore and the counter decrement is performed right before the invocation of call_rcu(). Signed-off-by: Antonio Quartulli --- net/batman-adv/translation-table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 660c40fe13ea..2ab83d7fb1f8 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -141,13 +141,14 @@ static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu) struct tt_orig_list_entry *orig_entry; orig_entry = container_of(rcu, struct tt_orig_list_entry, rcu); - atomic_dec(&orig_entry->orig_node->tt_size); orig_node_free_ref(orig_entry->orig_node); kfree(orig_entry); } static void tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) { + /* to avoid race conditions, immediately decrease the tt counter */ + atomic_dec(&orig_entry->orig_node->tt_size); call_rcu(&orig_entry->rcu, tt_orig_list_entry_free_rcu); } @@ -910,7 +911,6 @@ void tt_global_del_orig(struct bat_priv *bat_priv, } spin_unlock_bh(list_lock); } - atomic_set(&orig_node->tt_size, 0); orig_node->tt_initialised = false; } -- GitLab From ee85f543710dd56ce526cb44e39191f32972e5ad Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Sat, 23 Jun 2012 10:23:48 +0800 Subject: [PATCH 2597/6849] ACPI/PM: specify lowest allowed state for device sleep state Lower device sleep state can save more power, but has more exit latency too. Sometimes, to satisfy some power QoS and other requirement, we need to constrain the lowest device sleep state. In this patch, a parameter to specify lowest allowed state for acpi_pm_device_sleep_state is added. So that the caller can enforce the constraint via the parameter. This is needed by PCIe D3cold support, where the lowest power state allowed may be D3_HOT instead of default D3_COLD. CC: Len Brown CC: linux-acpi@vger.kernel.org Reviewed-by: Rafael J. Wysocki Signed-off-by: Huang Ying Signed-off-by: Bjorn Helgaas --- drivers/acpi/sleep.c | 24 +++++++++++++++++++----- drivers/pci/pci-acpi.c | 3 ++- drivers/pnp/pnpacpi/core.c | 4 ++-- include/acpi/acpi_bus.h | 6 +++--- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 88561029cca8..1cc02ca2af2a 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -716,8 +716,9 @@ int acpi_suspend(u32 acpi_state) * @dev: device to examine; its driver model wakeup flags control * whether it should be able to wake up the system * @d_min_p: used to store the upper limit of allowed states range - * Return value: preferred power state of the device on success, -ENODEV on - * failure (ie. if there's no 'struct acpi_device' for @dev) + * @d_max_in: specify the lowest allowed states + * Return value: preferred power state of the device on success, -ENODEV + * (ie. if there's no 'struct acpi_device' for @dev) or -EINVAL on failure * * Find the lowest power (highest number) ACPI device power state that * device @dev can be in while the system is in the sleep state represented @@ -732,13 +733,15 @@ int acpi_suspend(u32 acpi_state) * via @wake. */ -int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) +int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) { acpi_handle handle = DEVICE_ACPI_HANDLE(dev); struct acpi_device *adev; char acpi_method[] = "_SxD"; unsigned long long d_min, d_max; + if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3) + return -EINVAL; if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { printk(KERN_DEBUG "ACPI handle has no context!\n"); return -ENODEV; @@ -746,8 +749,10 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) acpi_method[2] = '0' + acpi_target_sleep_state; /* - * If the sleep state is S0, we will return D3, but if the device has - * _S0W, we will use the value from _S0W + * If the sleep state is S0, the lowest limit from ACPI is D3, + * but if the device has _S0W, we will use the value from _S0W + * as the lowest limit from ACPI. Finally, we will constrain + * the lowest limit with the specified one. */ d_min = ACPI_STATE_D0; d_max = ACPI_STATE_D3; @@ -791,8 +796,17 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) } } + if (d_max_in < d_min) + return -EINVAL; if (d_min_p) *d_min_p = d_min; + /* constrain d_max with specified lowest limit (max number) */ + if (d_max > d_max_in) { + for (d_max = d_max_in; d_max > d_min; d_max--) { + if (adev->power.states[d_max].flags.valid) + break; + } + } return d_max; } #endif /* CONFIG_PM */ diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 61e2fefeedab..a9efebc586b4 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -189,7 +189,8 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) { int acpi_state; - acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL); + acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, + ACPI_STATE_D3); if (acpi_state < 0) return PCI_POWER_ERROR; diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index d21e8f59c84e..507a8e2b9a4c 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -170,8 +170,8 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) } if (acpi_bus_power_manageable(handle)) { - int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); - + int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL, + ACPI_STATE_D3); if (power_state < 0) power_state = (state.event == PM_EVENT_ON) ? ACPI_STATE_D0 : ACPI_STATE_D3; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 9e6e1c6eb60a..16bd68504ff7 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -414,13 +414,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); #ifdef CONFIG_PM -int acpi_pm_device_sleep_state(struct device *, int *); +int acpi_pm_device_sleep_state(struct device *, int *, int); #else -static inline int acpi_pm_device_sleep_state(struct device *d, int *p) +static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) { if (p) *p = ACPI_STATE_D0; - return ACPI_STATE_D3; + return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0; } #endif -- GitLab From 71a83bd727cc31c5fe960c3758cb396267ff710e Mon Sep 17 00:00:00 2001 From: Zheng Yan Date: Sat, 23 Jun 2012 10:23:49 +0800 Subject: [PATCH 2598/6849] PCI/PM: add runtime PM support to PCIe port This patch adds runtime PM support to PCIe port. This is needed by PCIe D3cold support, where PCIe device without ACPI node may be powered on/off by PCIe port. Because runtime suspend is broken for some chipsets, a black list is used to disable runtime PM support for these chipsets. Reviewed-by: Rafael J. Wysocki Signed-off-by: Zheng Yan Signed-off-by: Huang Ying Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 10 ++++++++++ drivers/pci/pcie/portdrv_pci.c | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..9eae64b17954 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1518,6 +1518,16 @@ static void pci_pme_list_scan(struct work_struct *work) if (!list_empty(&pci_pme_list)) { list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) { if (pme_dev->dev->pme_poll) { + struct pci_dev *bridge; + + bridge = pme_dev->dev->bus->self; + /* + * If bridge is in low power state, the + * configuration space of subordinate devices + * may be not accessible + */ + if (bridge && bridge->current_state != PCI_D0) + continue; pci_pme_wakeup(pme_dev->dev, NULL); } else { list_del(&pme_dev->list); diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index e0610bda1dea..7c576b9aa01d 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -99,6 +100,15 @@ static int pcie_port_resume_noirq(struct device *dev) return 0; } +#ifdef CONFIG_PM_RUNTIME +static int pcie_port_runtime_pm(struct device *dev) +{ + return 0; +} +#else +#define pcie_port_runtime_pm NULL +#endif + static const struct dev_pm_ops pcie_portdrv_pm_ops = { .suspend = pcie_port_device_suspend, .resume = pcie_port_device_resume, @@ -107,6 +117,8 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { .poweroff = pcie_port_device_suspend, .restore = pcie_port_device_resume, .resume_noirq = pcie_port_resume_noirq, + .runtime_suspend = pcie_port_runtime_pm, + .runtime_resume = pcie_port_runtime_pm, }; #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) @@ -116,6 +128,14 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { #define PCIE_PORTDRV_PM_OPS NULL #endif /* !PM */ +/* + * PCIe port runtime suspend is broken for some chipsets, so use a + * black list to disable runtime PM for these chipsets. + */ +static const struct pci_device_id port_runtime_pm_black_list[] = { + { /* end: all zeroes */ } +}; + /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -144,12 +164,16 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, return status; pci_save_state(dev); + if (!pci_match_id(port_runtime_pm_black_list, dev)) + pm_runtime_put_noidle(&dev->dev); return 0; } static void pcie_portdrv_remove(struct pci_dev *dev) { + if (!pci_match_id(port_runtime_pm_black_list, dev)) + pm_runtime_get_noresume(&dev->dev); pcie_port_device_remove(dev); pci_disable_device(dev); } -- GitLab From 8497f696686ae1ab3f01e5956046d59844b9f500 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Sat, 23 Jun 2012 10:23:50 +0800 Subject: [PATCH 2599/6849] PCI: do not call pci_set_power_state with PCI_D3cold PCI subsystem has not been ready for D3cold support yet. So PCI_D3cold should not be used as parameter for pci_set_power_state. This patch is needed for upcoming PCI_D3cold support. This patch has no functionality change, because pci_set_power_state will bound the parameter to PCI_D3hot too. CC: Michal Miroslaw CC: Jesse Barnes Reviewed-by: Rafael J. Wysocki Signed-off-by: Huang Ying Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mrst.c | 2 +- drivers/misc/cb710/core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index 140942f66b31..e14a2ff708b5 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c @@ -264,7 +264,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup); static void __devinit mrst_power_off_unused_dev(struct pci_dev *dev) { - pci_set_power_state(dev, PCI_D3cold); + pci_set_power_state(dev, PCI_D3hot); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev); diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index 85cc7710193c..9d5eed754666 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -180,7 +180,7 @@ static int cb710_suspend(struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); pci_disable_device(pdev); if (state.event & PM_EVENT_SLEEP) - pci_set_power_state(pdev, PCI_D3cold); + pci_set_power_state(pdev, PCI_D3hot); return 0; } -- GitLab From 448bd857d48e69b33ef323739dc6d8ca20d4cda7 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Sat, 23 Jun 2012 10:23:51 +0800 Subject: [PATCH 2600/6849] PCI/PM: add PCIe runtime D3cold support This patch adds runtime D3cold support and corresponding ACPI platform support. This patch only enables runtime D3cold support; it does not enable D3cold support during system suspend/hibernate. D3cold is the deepest power saving state for a PCIe device, where its main power is removed. While it is in D3cold, you can't access the device at all, not even its configuration space (which is still accessible in D3hot). Therefore the PCI PM registers can not be used to transition into/out of the D3cold state; that must be done by platform logic such as ACPI _PR3. To support wakeup from D3cold, a system may provide auxiliary power, which allows a device to request wakeup using a Beacon or the sideband WAKE# signal. WAKE# is usually connected to platform logic such as ACPI GPE. This is quite different from other power saving states, where devices request wakeup via a PME message on the PCIe link. Some devices, such as those in plug-in slots, have no direct platform logic. For example, there is usually no ACPI _PR3 for them. D3cold support for these devices can be done via the PCIe Downstream Port leading to the device. When the PCIe port is powered on/off, the device is powered on/off too. Wakeup events from the device will be notified to the corresponding PCIe port. For more information about PCIe D3cold and corresponding ACPI support, please refer to: - PCI Express Base Specification Revision 2.0 - Advanced Configuration and Power Interface Specification Revision 5.0 [bhelgaas: changelog] Reviewed-by: Rafael J. Wysocki Originally-by: Zheng Yan Signed-off-by: Huang Ying Signed-off-by: Bjorn Helgaas --- drivers/pci/pci-acpi.c | 23 +++++-- drivers/pci/pci-driver.c | 10 ++- drivers/pci/pci-sysfs.c | 29 +++++++++ drivers/pci/pci.c | 114 ++++++++++++++++++++++++++++++--- drivers/pci/pci.h | 1 + drivers/pci/pcie/portdrv_pci.c | 44 +++++++++++-- include/linux/pci.h | 16 +++-- 7 files changed, 215 insertions(+), 22 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index a9efebc586b4..e1658afef873 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -48,6 +48,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) return; + if (pci_dev->current_state == PCI_D3cold) { + pci_wakeup_event(pci_dev); + pm_runtime_resume(&pci_dev->dev); + return; + } + if (!pci_dev->pm_cap || !pci_dev->pme_support || pci_check_pme_status(pci_dev)) { if (pci_dev->pme_poll) @@ -187,10 +193,13 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) { - int acpi_state; + int acpi_state, d_max; - acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, - ACPI_STATE_D3); + if (pdev->no_d3cold) + d_max = ACPI_STATE_D3_HOT; + else + d_max = ACPI_STATE_D3_COLD; + acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, d_max); if (acpi_state < 0) return PCI_POWER_ERROR; @@ -297,7 +306,13 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) { - if (dev->pme_interrupt) + /* + * Per PCI Express Base Specification Revision 2.0 section + * 5.3.3.2 Link Wakeup, platform support is needed for D3cold + * waking up to power on the main link even if there is PME + * support for D3cold + */ + if (dev->pme_interrupt && !dev->runtime_d3cold) return 0; if (!acpi_pm_device_run_wake(&dev->dev, enable)) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index bf0cee629b60..ca2e4c79a588 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1019,10 +1019,13 @@ static int pci_pm_runtime_suspend(struct device *dev) if (!pm || !pm->runtime_suspend) return -ENOSYS; + pci_dev->no_d3cold = false; error = pm->runtime_suspend(dev); suspend_report_result(pm->runtime_suspend, error); if (error) return error; + if (!pci_dev->d3cold_allowed) + pci_dev->no_d3cold = true; pci_fixup_device(pci_fixup_suspend, pci_dev); @@ -1044,6 +1047,7 @@ static int pci_pm_runtime_suspend(struct device *dev) static int pci_pm_runtime_resume(struct device *dev) { + int rc; struct pci_dev *pci_dev = to_pci_dev(dev); const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; @@ -1054,7 +1058,11 @@ static int pci_pm_runtime_resume(struct device *dev) __pci_enable_wake(pci_dev, PCI_D0, true, false); pci_fixup_device(pci_fixup_resume, pci_dev); - return pm->runtime_resume(dev); + rc = pm->runtime_resume(dev); + + pci_dev->runtime_d3cold = false; + + return rc; } static int pci_pm_runtime_idle(struct device *dev) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 86c63fe45d11..1426db0c0607 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "pci.h" static int sysfs_initialized; /* = 0 */ @@ -378,6 +379,31 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, #endif +#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) +static ssize_t d3cold_allowed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pci_dev *pdev = to_pci_dev(dev); + unsigned long val; + + if (strict_strtoul(buf, 0, &val) < 0) + return -EINVAL; + + pdev->d3cold_allowed = !!val; + pm_runtime_resume(dev); + + return count; +} + +static ssize_t d3cold_allowed_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + return sprintf (buf, "%u\n", pdev->d3cold_allowed); +} +#endif + struct device_attribute pci_dev_attrs[] = { __ATTR_RO(resource), __ATTR_RO(vendor), @@ -401,6 +427,9 @@ struct device_attribute pci_dev_attrs[] = { #ifdef CONFIG_HOTPLUG __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store), __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store), +#endif +#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) + __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store), #endif __ATTR_NULL, }; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9eae64b17954..8effb9b23eec 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -622,7 +622,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) dev_info(&dev->dev, "Refused to change power state, " "currently in D%d\n", dev->current_state); - /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT + /* + * According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning * from D3hot to D0 _may_ perform an internal reset, thereby * going to "D0 Uninitialized" rather than "D0 Initialized". @@ -654,6 +655,16 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state) if (dev->pm_cap) { u16 pmcsr; + /* + * Configuration space is not accessible for device in + * D3cold, so just keep or set D3cold for safety + */ + if (dev->current_state == PCI_D3cold) + return; + if (state == PCI_D3cold) { + dev->current_state = PCI_D3cold; + return; + } pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } else { @@ -694,8 +705,50 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) */ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) { - if (state == PCI_D0) + if (state == PCI_D0) { pci_platform_power_transition(dev, PCI_D0); + /* + * Mandatory power management transition delays, see + * PCI Express Base Specification Revision 2.0 Section + * 6.6.1: Conventional Reset. Do not delay for + * devices powered on/off by corresponding bridge, + * because have already delayed for the bridge. + */ + if (dev->runtime_d3cold) { + msleep(dev->d3cold_delay); + /* + * When powering on a bridge from D3cold, the + * whole hierarchy may be powered on into + * D0uninitialized state, resume them to give + * them a chance to suspend again + */ + pci_wakeup_bus(dev->subordinate); + } + } +} + +/** + * __pci_dev_set_current_state - Set current state of a PCI device + * @dev: Device to handle + * @data: pointer to state to be set + */ +static int __pci_dev_set_current_state(struct pci_dev *dev, void *data) +{ + pci_power_t state = *(pci_power_t *)data; + + dev->current_state = state; + return 0; +} + +/** + * __pci_bus_set_current_state - Walk given bus and set current state of devices + * @bus: Top bus of the subtree to walk. + * @state: state to be set + */ +static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) +{ + if (bus) + pci_walk_bus(bus, __pci_dev_set_current_state, &state); } /** @@ -707,8 +760,15 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) */ int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) { - return state >= PCI_D0 ? - pci_platform_power_transition(dev, state) : -EINVAL; + int ret; + + if (state < PCI_D0) + return -EINVAL; + ret = pci_platform_power_transition(dev, state); + /* Power off the bridge may power off the whole hierarchy */ + if (!ret && state == PCI_D3cold) + __pci_bus_set_current_state(dev->subordinate, PCI_D3cold); + return ret; } EXPORT_SYMBOL_GPL(__pci_complete_power_transition); @@ -732,8 +792,8 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) int error; /* bound the state we're entering */ - if (state > PCI_D3hot) - state = PCI_D3hot; + if (state > PCI_D3cold) + state = PCI_D3cold; else if (state < PCI_D0) state = PCI_D0; else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) @@ -748,10 +808,15 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) /* This device is quirked not to be put into D3, so don't put it in D3 */ - if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) + if (state >= PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) return 0; - error = pci_raw_set_power_state(dev, state); + /* + * To put device in D3cold, we put device into D3hot in native + * way, then put device into D3cold with platform ops + */ + error = pci_raw_set_power_state(dev, state > PCI_D3hot ? + PCI_D3hot : state); if (!__pci_complete_power_transition(dev, state)) error = 0; @@ -1497,6 +1562,28 @@ void pci_pme_wakeup_bus(struct pci_bus *bus) pci_walk_bus(bus, pci_pme_wakeup, (void *)true); } +/** + * pci_wakeup - Wake up a PCI device + * @dev: Device to handle. + * @ign: ignored parameter + */ +static int pci_wakeup(struct pci_dev *pci_dev, void *ign) +{ + pci_wakeup_event(pci_dev); + pm_request_resume(&pci_dev->dev); + return 0; +} + +/** + * pci_wakeup_bus - Walk given bus and wake up devices on it + * @bus: Top bus of the subtree to walk. + */ +void pci_wakeup_bus(struct pci_bus *bus) +{ + if (bus) + pci_walk_bus(bus, pci_wakeup, NULL); +} + /** * pci_pme_capable - check the capability of PCI device to generate PME# * @dev: PCI device to handle. @@ -1754,6 +1841,10 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; + /* D3cold during system suspend/hibernate is not supported */ + if (target_state > PCI_D3hot) + target_state = PCI_D3hot; + pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); error = pci_set_power_state(dev, target_state); @@ -1791,12 +1882,16 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; + dev->runtime_d3cold = target_state == PCI_D3cold; + __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); error = pci_set_power_state(dev, target_state); - if (error) + if (error) { __pci_enable_wake(dev, target_state, true, false); + dev->runtime_d3cold = false; + } return error; } @@ -1866,6 +1961,7 @@ void pci_pm_init(struct pci_dev *dev) dev->pm_cap = pm; dev->d3_delay = PCI_PM_D3_WAIT; + dev->d3cold_delay = PCI_PM_D3COLD_WAIT; dev->d1_support = false; dev->d2_support = false; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e4943479b234..5cd3dce7a245 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -70,6 +70,7 @@ extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); extern void pci_disable_enabled_device(struct pci_dev *dev); extern int pci_finish_runtime_suspend(struct pci_dev *dev); extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); +extern void pci_wakeup_bus(struct pci_bus *bus); extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 7c576b9aa01d..3a7eefcb270a 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -101,12 +101,48 @@ static int pcie_port_resume_noirq(struct device *dev) } #ifdef CONFIG_PM_RUNTIME -static int pcie_port_runtime_pm(struct device *dev) +struct d3cold_info { + bool no_d3cold; + unsigned int d3cold_delay; +}; + +static int pci_dev_d3cold_info(struct pci_dev *pdev, void *data) +{ + struct d3cold_info *info = data; + + info->d3cold_delay = max_t(unsigned int, pdev->d3cold_delay, + info->d3cold_delay); + if (pdev->no_d3cold) + info->no_d3cold = true; + return 0; +} + +static int pcie_port_runtime_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct d3cold_info d3cold_info = { + .no_d3cold = false, + .d3cold_delay = PCI_PM_D3_WAIT, + }; + + /* + * If any subordinate device disable D3cold, we should not put + * the port into D3cold. The D3cold delay of port should be + * the max of that of all subordinate devices. + */ + pci_walk_bus(pdev->subordinate, pci_dev_d3cold_info, &d3cold_info); + pdev->no_d3cold = d3cold_info.no_d3cold; + pdev->d3cold_delay = d3cold_info.d3cold_delay; + return 0; +} + +static int pcie_port_runtime_resume(struct device *dev) { return 0; } #else -#define pcie_port_runtime_pm NULL +#define pcie_port_runtime_suspend NULL +#define pcie_port_runtime_resume NULL #endif static const struct dev_pm_ops pcie_portdrv_pm_ops = { @@ -117,8 +153,8 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { .poweroff = pcie_port_device_suspend, .restore = pcie_port_device_resume, .resume_noirq = pcie_port_resume_noirq, - .runtime_suspend = pcie_port_runtime_pm, - .runtime_resume = pcie_port_runtime_pm, + .runtime_suspend = pcie_port_runtime_suspend, + .runtime_resume = pcie_port_runtime_resume, }; #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..002cfd3e33ca 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -132,9 +132,10 @@ static inline const char *pci_power_name(pci_power_t state) return pci_power_names[1 + (int) state]; } -#define PCI_PM_D2_DELAY 200 -#define PCI_PM_D3_WAIT 10 -#define PCI_PM_BUS_WAIT 50 +#define PCI_PM_D2_DELAY 200 +#define PCI_PM_D3_WAIT 10 +#define PCI_PM_D3COLD_WAIT 100 +#define PCI_PM_BUS_WAIT 50 /** The pci_channel state describes connectivity between the CPU and * the pci device. If some PCI bus between here and the pci device @@ -278,11 +279,18 @@ struct pci_dev { unsigned int pme_poll:1; /* Poll device's PME status bit */ unsigned int d1_support:1; /* Low power state D1 is supported */ unsigned int d2_support:1; /* Low power state D2 is supported */ - unsigned int no_d1d2:1; /* Only allow D0 and D3 */ + unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ + unsigned int no_d3cold:1; /* D3cold is forbidden */ + unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ unsigned int mmio_always_on:1; /* disallow turning off io/mem decoding during bar sizing */ unsigned int wakeup_prepared:1; + unsigned int runtime_d3cold:1; /* whether go through runtime + D3cold, not set for devices + powered on/off by the + corresponding bridge */ unsigned int d3_delay; /* D3->D0 transition time in ms */ + unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */ #ifdef CONFIG_PCIEASPM struct pcie_link_state *link_state; /* ASPM link state. */ -- GitLab From b5e12229a4850ae9b19ee5252508749da8844b3c Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 22 Jun 2012 20:57:57 +0200 Subject: [PATCH 2601/6849] ARM: Orion5x - Restore parts of io.h, with rework Commit 4d5fc58dbe34b78157c05b319669bb3e064ba8bd (ARM: remove bunch of now unused mach/io.h files) removed the orion5x io.h. Unfortunately, this is still needed for the definition of IO_SPACE_LIMIT which overrides the default 64K. All Orion based systems have 1Mbyte of IO space per PCI[e] bus, and try to request_resource() this size. Orion5x has two such PCI buses. It is likely that the original, removed version, was broken. This version might be less broken. However, it has not been tested on hardware with a PCI card, let alone hardware with a PCI card with IO capabilities. Signed-off-by: Andrew Lunn Acked-by: Rob Herring Signed-off-by: Olof Johansson --- arch/arm/Kconfig | 1 + arch/arm/mach-orion5x/include/mach/io.h | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 arch/arm/mach-orion5x/include/mach/io.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b1b27525b24d..a91009c61870 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -589,6 +589,7 @@ config ARCH_ORION5X select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select NEED_MACH_IO_H select PLAT_ORION help Support for the following Marvell Orion 5x series SoCs: diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h new file mode 100644 index 000000000000..1aa5d0a50a0b --- /dev/null +++ b/arch/arm/mach-orion5x/include/mach/io.h @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-orion5x/include/mach/io.h + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARCH_IO_H +#define __ASM_ARCH_IO_H + +#include +#include + +#define IO_SPACE_LIMIT SZ_2M +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)(addr + ORION5X_PCIE_IO_VIRT_BASE); +} + +#define __io(a) __io(a) +#endif -- GitLab From 5fb2ce119c113e5c987fa81ed89e73b2653e28e4 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 22 Jun 2012 08:54:01 +0200 Subject: [PATCH 2602/6849] ARM: Kirkwood: clk_register_gate_fn: add fn assignment In commit: 98d9986 ARM: Kirkwood: Replace clock gating the kirkwood clock gating has been reworked. A custom variant of clock gating, that calls a custom function before gating the clock off, has been introduced. However in clk_register_gate_fn() this custom function "fn" is never assigned. This patch adds the missing fn assignment. Cc: stable Signed-off-by: Marc Kleine-Budde Tested-by: Andrew Lunn Acked-by: Andrew Lunn Signed-off-by: Olof Johansson --- arch/arm/mach-kirkwood/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index e1d2c6def5e6..f261cd242643 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -159,6 +159,7 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, gate_fn->gate.flags = clk_gate_flags; gate_fn->gate.lock = lock; gate_fn->gate.hw.init = &init; + gate_fn->fn = fn; /* ops is the gate ops, but with our disable function */ if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { -- GitLab From 0fa1f0609a0c1fe8b2be3c0089a2cb48f7fda521 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 22 Jun 2012 08:54:02 +0200 Subject: [PATCH 2603/6849] ARM: Orion: Fix Virtual/Physical mixup with watchdog The orion watchdog is expecting to be passed the physcial address of the hardware, and will ioremap() it to give a virtual address it will use as the base address for the hardware. However, when creating the platform resource record, a virtual address was being used. Add the necassary #define's so we can pass the physical address as expected. Tested on Kirkwood and Orion5x. Cc: stable Signed-off-by: Andrew Lunn Signed-off-by: Olof Johansson --- arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 + arch/arm/mach-kirkwood/include/mach/kirkwood.h | 1 + arch/arm/mach-orion5x/include/mach/bridge-regs.h | 2 +- arch/arm/mach-orion5x/include/mach/orion5x.h | 1 + arch/arm/plat-orion/common.c | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 3eee37a3b501..a115142f8690 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -38,6 +38,7 @@ #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) +#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300) #define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) #define L2_WRITETHROUGH 0x00000010 diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index fede3d503efa..c5b68510776b 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -80,6 +80,7 @@ #define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) #define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) +#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x20000) #define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000) diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h index 96484bcd34ca..11a3c1e9801f 100644 --- a/arch/arm/mach-orion5x/include/mach/bridge-regs.h +++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h @@ -35,5 +35,5 @@ #define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x204) #define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE | 0x300) - +#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE | 0x300) #endif diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h index 2745f5d95b3f..683e085ce162 100644 --- a/arch/arm/mach-orion5x/include/mach/orion5x.h +++ b/arch/arm/mach-orion5x/include/mach/orion5x.h @@ -82,6 +82,7 @@ #define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2100) #define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x20000) +#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x20000) #define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x30000) diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 61fd837624a8..c1793786aea9 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -582,7 +582,7 @@ void __init orion_spi_1_init(unsigned long mapbase) * Watchdog ****************************************************************************/ static struct resource orion_wdt_resource = - DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28); + DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x28); static struct platform_device orion_wdt_device = { .name = "orion_wdt", -- GitLab From d9b0cde91c60da0ed5f92cdc3ac878142e6b5f27 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 29 May 2012 14:31:23 -0700 Subject: [PATCH 2604/6849] x86-64, gcc: Use -mpreferred-stack-boundary=3 if supported On x86-64, the standard ABI requires alignment to 16 bytes. However, this is not actually necessary in the kernel (we don't do SSE except in very controlled ways); and furthermore, the standard kernel entry on x86-64 actually leaves the stack on an odd 8-byte boundary, which means that gcc will generate extra instructions to keep the stack *mis*aligned! gcc 4.8 adds an -mpreferred-stack-boundary=3 option to override this and lets us save some stack space and a handful of instructions. Note that this causes us to pass -mno-sse twice; this is redundant, but necessary since the cc-option test will fail unless -mno-sse is passed on the same command line. [ hpa: rewrote the patch description ] Signed-off-by: H.J. Lu Link: http://lkml.kernel.org/r/CAMe9rOqPfy3JcZRLaUeCjBe9BVY-P6e0uaSbMi5hvS-6WwQueg@mail.gmail.com Signed-off-by: H. Peter Anvin --- arch/x86/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 1f2521434554..b0c5276861ec 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -49,6 +49,9 @@ else KBUILD_AFLAGS += -m64 KBUILD_CFLAGS += -m64 + # Use -mpreferred-stack-boundary=3 if supported. + KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3) + # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) -- GitLab From 7011d0851b80a1a229acfda37ce08aad903b12d1 Mon Sep 17 00:00:00 2001 From: Vijay Subramanian Date: Sat, 23 Jun 2012 17:38:10 +0000 Subject: [PATCH 2605/6849] tcp: Fix bug in tcp socket early demux The dest port for the call to __inet_lookup_established() in TCP early demux code is passed with the wrong endian-ness. This causes the lookup to fail leading to early demux not being used. Signed-off-by: Vijay Subramanian Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b52934f5334e..1781dc650b9d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1701,7 +1701,7 @@ int tcp_v4_early_demux(struct sk_buff *skb) dev = skb->dev; sk = __inet_lookup_established(net, &tcp_hashinfo, iph->saddr, th->source, - iph->daddr, th->dest, + iph->daddr, ntohs(th->dest), dev->ifindex); if (sk) { skb->sk = sk; -- GitLab From bdcbd8e0e3ffdad32b14b6373e67bfcf5fd3f002 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 11:29:50 +0200 Subject: [PATCH 2606/6849] mac80211: clean up debugging There are a few things that make the logging and debugging in mac80211 less useful than it should be right now: * a lot of messages should be pr_info, not pr_debug * wholesale use of pr_debug makes it require *both* Kconfig and dynamic configuration * there are still a lot of ifdefs * the style is very inconsistent, sometimes the sdata->name is printed in front Clean up everything, introducing new macros and separating out the station MLME debugging into a new Kconfig symbol. Signed-off-by: Johannes Berg --- include/net/mac80211.h | 24 ---- net/mac80211/Kconfig | 32 +++++- net/mac80211/Makefile | 2 +- net/mac80211/agg-rx.c | 34 +++--- net/mac80211/agg-tx.c | 72 ++++++------ net/mac80211/cfg.c | 9 +- net/mac80211/debug.h | 152 +++++++++++++++++++++++++ net/mac80211/debugfs_netdev.c | 5 +- net/mac80211/ht.c | 10 +- net/mac80211/ibss.c | 89 +++++++-------- net/mac80211/ieee80211_i.h | 1 + net/mac80211/iface.c | 13 +-- net/mac80211/key.c | 4 +- net/mac80211/mesh.c | 4 - net/mac80211/mesh_hwmp.c | 42 ++++--- net/mac80211/mesh_pathtbl.c | 30 ++--- net/mac80211/mesh_plink.c | 61 +++++----- net/mac80211/mesh_sync.c | 47 ++++---- net/mac80211/mlme.c | 203 ++++++++++++++++------------------ net/mac80211/rx.c | 40 ++----- net/mac80211/sta_info.c | 44 +++----- net/mac80211/status.c | 11 +- net/mac80211/tx.c | 43 +++---- 23 files changed, 519 insertions(+), 453 deletions(-) create mode 100644 net/mac80211/debug.h diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f11c2f8b00c9..510d852d5222 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3842,28 +3842,4 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, */ int ieee80211_ave_rssi(struct ieee80211_vif *vif); -/* Extra debugging macros */ - -#ifdef CONFIG_MAC80211_HT_DEBUG -#define ht_vdbg(fmt, ...) \ - pr_debug(fmt, ##__VA_ARGS__) -#else -#define ht_vdbg(fmt, ...) \ -do { \ - if (0) \ - pr_debug(fmt, ##__VA_ARGS__); \ -} while (0) -#endif - -#ifdef CONFIG_MAC80211_IBSS_DEBUG -#define ibss_vdbg(fmt, ...) \ - pr_debug(fmt, ##__VA_ARGS__) -#else -#define ibss_vdbg(fmt, ...) \ -do { \ - if (0) \ - pr_debug(fmt, ##__VA_ARGS__); \ -} while (0) -#endif - #endif /* MAC80211_H */ diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 323aa19a39d5..7475e266eb4e 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -140,6 +140,26 @@ config MAC80211_VERBOSE_DEBUG Do not select this option. +config MAC80211_MLME_DEBUG + bool "Verbose managed MLME output" + depends on MAC80211_DEBUG_MENU + ---help--- + Selecting this option causes mac80211 to print out + debugging messages for the managed-mode MLME. It + should not be selected on production systems as some + of the messages are remotely triggerable. + + Do not select this option. + +config MAC80211_STA_DEBUG + bool "Verbose station debugging" + depends on MAC80211_DEBUG_MENU + ---help--- + Selecting this option causes mac80211 to print out + debugging messages for station addition/removal. + + Do not select this option. + config MAC80211_HT_DEBUG bool "Verbose HT debugging" depends on MAC80211_DEBUG_MENU @@ -163,7 +183,7 @@ config MAC80211_IBSS_DEBUG Do not select this option. -config MAC80211_VERBOSE_PS_DEBUG +config MAC80211_PS_DEBUG bool "Verbose powersave mode debugging" depends on MAC80211_DEBUG_MENU ---help--- @@ -175,7 +195,7 @@ config MAC80211_VERBOSE_PS_DEBUG Do not select this option. -config MAC80211_VERBOSE_MPL_DEBUG +config MAC80211_MPL_DEBUG bool "Verbose mesh peer link debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -188,7 +208,7 @@ config MAC80211_VERBOSE_MPL_DEBUG Do not select this option. -config MAC80211_VERBOSE_MPATH_DEBUG +config MAC80211_MPATH_DEBUG bool "Verbose mesh path debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -201,7 +221,7 @@ config MAC80211_VERBOSE_MPATH_DEBUG Do not select this option. -config MAC80211_VERBOSE_MHWMP_DEBUG +config MAC80211_MHWMP_DEBUG bool "Verbose mesh HWMP routing debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -214,7 +234,7 @@ config MAC80211_VERBOSE_MHWMP_DEBUG Do not select this option. -config MAC80211_VERBOSE_MESH_SYNC_DEBUG +config MAC80211_MESH_SYNC_DEBUG bool "Verbose mesh mesh synchronization debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -225,7 +245,7 @@ config MAC80211_VERBOSE_MESH_SYNC_DEBUG Do not select this option. -config MAC80211_VERBOSE_TDLS_DEBUG +config MAC80211_TDLS_DEBUG bool "Verbose TDLS debugging" depends on MAC80211_DEBUG_MENU ---help--- diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 2b1470bac178..231ffa02e496 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -58,4 +58,4 @@ mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) -ccflags-y += -D__CHECK_ENDIAN__ +ccflags-y += -D__CHECK_ENDIAN__ -DDEBUG diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 32ef11d69798..186d9919b043 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -74,15 +74,17 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); - ht_vdbg("Rx BA session stop requested for %pM tid %u %s reason: %d\n", - sta->sta.addr, tid, - initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", - (int)reason); + ht_dbg(sta->sdata, + "Rx BA session stop requested for %pM tid %u %s reason: %d\n", + sta->sta.addr, tid, + initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", + (int)reason); if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, &sta->sta, tid, NULL, 0)) - pr_debug("HW problem - can not stop rx aggregation for tid %d\n", - tid); + sdata_info(sta->sdata, + "HW problem - can not stop rx aggregation for tid %d\n", + tid); /* check if this is a self generated aggregation halt */ if (initiator == WLAN_BACK_RECIPIENT && tx) @@ -157,7 +159,7 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) } rcu_read_unlock(); - ht_vdbg("rx session timer expired on tid %d\n", (u16)*ptid); + ht_dbg(sta->sdata, "rx session timer expired on tid %d\n", (u16)*ptid); set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); @@ -245,7 +247,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, status = WLAN_STATUS_REQUEST_DECLINED; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { - ht_vdbg("Suspend in progress - Denying ADDBA request\n"); + ht_dbg(sta->sdata, "Suspend in progress - Denying ADDBA request\n"); goto end_no_lock; } @@ -257,10 +259,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { status = WLAN_STATUS_INVALID_QOS_PARAM; -#ifdef CONFIG_MAC80211_HT_DEBUG - net_dbg_ratelimited("AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", - mgmt->sa, tid, ba_policy, buf_size); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_dbg_ratelimited(sta->sdata, + "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", + mgmt->sa, tid, ba_policy, buf_size); goto end_no_lock; } /* determine default buffer size */ @@ -275,10 +276,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, mutex_lock(&sta->ampdu_mlme.mtx); if (sta->ampdu_mlme.tid_rx[tid]) { -#ifdef CONFIG_MAC80211_HT_DEBUG - net_dbg_ratelimited("unexpected AddBA Req from %pM on tid %u\n", - mgmt->sa, tid); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_dbg_ratelimited(sta->sdata, + "unexpected AddBA Req from %pM on tid %u\n", + mgmt->sa, tid); /* delete existing Rx BA session on the same tid */ ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, @@ -317,7 +317,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, &sta->sta, tid, &start_seq_num, 0); - ht_vdbg("Rx A-MPDU request on tid %d result %d\n", tid, ret); + ht_dbg(sta->sdata, "Rx A-MPDU request on tid %d result %d\n", tid, ret); if (ret) { kfree(tid_agg_rx->reorder_buf); kfree(tid_agg_rx->reorder_time); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index da07f01cfe4d..5cc1bf7d8033 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -184,8 +184,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, spin_unlock_bh(&sta->lock); - ht_vdbg("Tx BA session stop requested for %pM tid %u\n", - sta->sta.addr, tid); + ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n", + sta->sta.addr, tid); del_timer_sync(&tid_tx->addba_resp_timer); del_timer_sync(&tid_tx->session_timer); @@ -251,12 +251,13 @@ static void sta_addba_resp_timer_expired(unsigned long data) if (!tid_tx || test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { rcu_read_unlock(); - ht_vdbg("timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", - tid); + ht_dbg(sta->sdata, + "timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", + tid); return; } - ht_vdbg("addBA response timer expired on tid %d\n", tid); + ht_dbg(sta->sdata, "addBA response timer expired on tid %d\n", tid); ieee80211_stop_tx_ba_session(&sta->sta, tid); rcu_read_unlock(); @@ -316,8 +317,9 @@ ieee80211_agg_splice_packets(struct ieee80211_sub_if_data *sdata, ieee80211_stop_queue_agg(sdata, tid); - if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" - " from the pending queue\n", tid)) + if (WARN(!tid_tx, + "TID %d gone but expected when splicing aggregates from the pending queue\n", + tid)) return; if (!skb_queue_empty(&tid_tx->pending)) { @@ -365,7 +367,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, &sta->sta, tid, &start_seq_num, 0); if (ret) { - ht_vdbg("BA request denied - HW unavailable for tid %d\n", tid); + ht_dbg(sdata, + "BA request denied - HW unavailable for tid %d\n", tid); spin_lock_bh(&sta->lock); ieee80211_agg_splice_packets(sdata, tid_tx, tid); ieee80211_assign_tid_tx(sta, tid, NULL); @@ -378,7 +381,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) /* activate the timer for the recipient's addBA response */ mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); - ht_vdbg("activated addBA response timer on tid %d\n", tid); + ht_dbg(sdata, "activated addBA response timer on tid %d\n", tid); spin_lock_bh(&sta->lock); sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; @@ -425,7 +428,7 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) rcu_read_unlock(); - ht_vdbg("tx session timer expired on tid %d\n", (u16)*ptid); + ht_dbg(sta->sdata, "tx session timer expired on tid %d\n", (u16)*ptid); ieee80211_stop_tx_ba_session(&sta->sta, *ptid); } @@ -449,8 +452,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) return -EINVAL; - ht_vdbg("Open BA session requested for %pM tid %u\n", - pubsta->addr, tid); + ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", + pubsta->addr, tid); if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_MESH_POINT && @@ -460,7 +463,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, return -EINVAL; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { - ht_vdbg("BA sessions blocked - Denying BA session request\n"); + ht_dbg(sdata, + "BA sessions blocked - Denying BA session request\n"); return -EINVAL; } @@ -478,8 +482,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, */ if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && !sta->sta.ht_cap.ht_supported) { - ht_vdbg("BA request denied - IBSS STA %pM does not advertise HT support\n", - pubsta->addr); + ht_dbg(sdata, + "BA request denied - IBSS STA %pM does not advertise HT support\n", + pubsta->addr); return -EINVAL; } @@ -499,8 +504,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + HT_AGG_RETRIES_PERIOD)) { - ht_vdbg("BA request denied - waiting a grace period after %d failed requests on tid %u\n", - sta->ampdu_mlme.addba_req_num[tid], tid); + ht_dbg(sdata, + "BA request denied - waiting a grace period after %d failed requests on tid %u\n", + sta->ampdu_mlme.addba_req_num[tid], tid); ret = -EBUSY; goto err_unlock_sta; } @@ -508,8 +514,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); /* check if the TID is not in aggregation flow already */ if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { - ht_vdbg("BA request denied - session is not idle on tid %u\n", - tid); + ht_dbg(sdata, + "BA request denied - session is not idle on tid %u\n", + tid); ret = -EAGAIN; goto err_unlock_sta; } @@ -564,7 +571,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - ht_vdbg("Aggregation is on for tid %d\n", tid); + ht_dbg(sta->sdata, "Aggregation is on for tid %d\n", tid); drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_OPERATIONAL, @@ -598,7 +605,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) trace_api_start_tx_ba_cb(sdata, ra, tid); if (tid >= STA_TID_NUM) { - ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); + ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", + tid, STA_TID_NUM); return; } @@ -606,7 +614,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) sta = sta_info_get_bss(sdata, ra); if (!sta) { mutex_unlock(&local->sta_mtx); - ht_vdbg("Could not find station: %pM\n", ra); + ht_dbg(sdata, "Could not find station: %pM\n", ra); return; } @@ -614,7 +622,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (WARN_ON(!tid_tx)) { - ht_vdbg("addBA was not requested!\n"); + ht_dbg(sdata, "addBA was not requested!\n"); goto unlock; } @@ -714,17 +722,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) trace_api_stop_tx_ba_cb(sdata, ra, tid); if (tid >= STA_TID_NUM) { - ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); + ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", + tid, STA_TID_NUM); return; } - ht_vdbg("Stopping Tx BA session for %pM tid %d\n", ra, tid); + ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid); mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, ra); if (!sta) { - ht_vdbg("Could not find station: %pM\n", ra); + ht_dbg(sdata, "Could not find station: %pM\n", ra); goto unlock; } @@ -733,7 +742,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { - ht_vdbg("unexpected callback to A-MPDU stop\n"); + ht_dbg(sdata, "unexpected callback to A-MPDU stop\n"); goto unlock_sta; } @@ -809,13 +818,13 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, goto out; if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { - ht_vdbg("wrong addBA response token, tid %d\n", tid); + ht_dbg(sta->sdata, "wrong addBA response token, tid %d\n", tid); goto out; } del_timer_sync(&tid_tx->addba_resp_timer); - ht_vdbg("switched off addBA timer for tid %d\n", tid); + ht_dbg(sta->sdata, "switched off addBA timer for tid %d\n", tid); /* * addba_resp_timer may have fired before we got here, and @@ -824,8 +833,9 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, */ if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { - ht_vdbg("got addBA resp for tid %d but we already gave up\n", - tid); + ht_dbg(sta->sdata, + "got addBA resp for tid %d but we already gave up\n", + tid); goto out; } diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d0c8f78115cb..7722a7336a58 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2771,9 +2771,8 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, !sdata->u.mgd.associated) return -EINVAL; -#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG - pr_debug("TDLS mgmt action %d peer %pM\n", action_code, peer); -#endif + tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", + action_code, peer); skb = dev_alloc_skb(local->hw.extra_tx_headroom + max(sizeof(struct ieee80211_mgmt), @@ -2882,9 +2881,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, if (sdata->vif.type != NL80211_IFTYPE_STATION) return -EINVAL; -#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG - pr_debug("TDLS oper %d peer %pM\n", oper, peer); -#endif + tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); switch (oper) { case NL80211_TDLS_ENABLE_LINK: diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h new file mode 100644 index 000000000000..6e6bbb9a9d41 --- /dev/null +++ b/net/mac80211/debug.h @@ -0,0 +1,152 @@ +#ifndef __MAC80211_DEBUG_H +#define __MAC80211_DEBUG_H + +#ifdef CONFIG_MAC80211_IBSS_DEBUG +#define MAC80211_IBSS_DEBUG 1 +#else +#define MAC80211_IBSS_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_PS_DEBUG +#define MAC80211_PS_DEBUG 1 +#else +#define MAC80211_PS_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_HT_DEBUG +#define MAC80211_HT_DEBUG 1 +#else +#define MAC80211_HT_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_MPL_DEBUG +#define MAC80211_MPL_DEBUG 1 +#else +#define MAC80211_MPL_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_MPATH_DEBUG +#define MAC80211_MPATH_DEBUG 1 +#else +#define MAC80211_MPATH_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_MHWMP_DEBUG +#define MAC80211_MHWMP_DEBUG 1 +#else +#define MAC80211_MHWMP_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_MESH_SYNC_DEBUG +#define MAC80211_MESH_SYNC_DEBUG 1 +#else +#define MAC80211_MESH_SYNC_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_TDLS_DEBUG +#define MAC80211_TDLS_DEBUG 1 +#else +#define MAC80211_TDLS_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_STA_DEBUG +#define MAC80211_STA_DEBUG 1 +#else +#define MAC80211_STA_DEBUG 0 +#endif + +#ifdef CONFIG_MAC80211_MLME_DEBUG +#define MAC80211_MLME_DEBUG 1 +#else +#define MAC80211_MLME_DEBUG 0 +#endif + +#define _sdata_info(sdata, fmt, ...) \ +do { \ + pr_info("%s: " fmt, \ + (sdata)->name, ##__VA_ARGS__); \ +} while (0) + +#define _sdata_dbg(print, sdata, fmt, ...) \ +do { \ + if (print) \ + pr_debug("%s: " fmt, \ + (sdata)->name, ##__VA_ARGS__); \ +} while (0) + +#define _sdata_err(sdata, fmt, ...) \ +do { \ + pr_err("%s: " fmt, \ + (sdata)->name, ##__VA_ARGS__); \ +} while (0) + +#define _wiphy_dbg(print, wiphy, fmt, ...) \ +do { \ + if (print) \ + wiphy_dbg((wiphy), fmt, ##__VA_ARGS__); \ +} while (0) + +#define sdata_info(sdata, fmt, ...) \ + _sdata_info(sdata, fmt, ##__VA_ARGS__) +#define sdata_err(sdata, fmt, ...) \ + _sdata_err(sdata, fmt, ##__VA_ARGS__) +#define sdata_dbg(sdata, fmt, ...) \ + _sdata_dbg(1, sdata, fmt, ##__VA_ARGS__) + +#define ht_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_HT_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define ht_dbg_ratelimited(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ + sdata, fmt, ##__VA_ARGS__) + +#define ibss_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_IBSS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define ps_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_PS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define ps_dbg_hw(hw, fmt, ...) \ + _wiphy_dbg(MAC80211_PS_DEBUG, \ + (hw)->wiphy, fmt, ##__VA_ARGS__) + +#define ps_dbg_ratelimited(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_PS_DEBUG && net_ratelimit(), \ + sdata, fmt, ##__VA_ARGS__) + +#define mpl_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_MPL_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define mpath_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_MPATH_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define mhwmp_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_MHWMP_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define msync_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_MESH_SYNC_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define tdls_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_TDLS_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define sta_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_STA_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define mlme_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_MLME_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + +#define mlme_dbg_ratelimited(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_MLME_DEBUG && net_ratelimit(), \ + sdata, fmt, ##__VA_ARGS__) + +#endif /* __MAC80211_DEBUG_H */ diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 512c894893d6..6d5aec9418ee 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -695,6 +695,7 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) sprintf(buf, "netdev:%s", sdata->name); if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) - pr_err("mac80211: debugfs: failed to rename debugfs " - "dir to %s\n", buf); + sdata_err(sdata, + "debugfs: failed to rename debugfs dir to %s\n", + buf); } diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 6f8615c54b22..4b4538d63925 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -305,12 +305,10 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; -#ifdef CONFIG_MAC80211_HT_DEBUG - net_dbg_ratelimited("delba from %pM (%s) tid %d reason code %d\n", - mgmt->sa, initiator ? "initiator" : "recipient", - tid, - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); -#endif /* CONFIG_MAC80211_HT_DEBUG */ + ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n", + mgmt->sa, initiator ? "initiator" : "recipient", + tid, + le16_to_cpu(mgmt->u.action.u.delba.reason_code)); if (initiator == WLAN_BACK_INITIATOR) __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 8931110b8433..5746d62faba1 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -261,11 +261,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, memcpy(addr, sta->sta.addr, ETH_ALEN); -#ifdef CONFIG_MAC80211_IBSS_DEBUG - wiphy_debug(sdata->local->hw.wiphy, - "Adding new IBSS station %pM (dev=%s)\n", - addr, sdata->name); -#endif + ibss_dbg(sdata, "Adding new IBSS station %pM\n", addr); sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); @@ -280,8 +276,9 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, if (sta_info_insert_rcu(sta)) return sta_info_get(sdata, addr); if (auth && !sdata->u.ibss.auth_frame_registrations) { - ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", - sdata->vif.addr, sdata->u.ibss.bssid, addr); + ibss_dbg(sdata, + "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", + sdata->vif.addr, sdata->u.ibss.bssid, addr); ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, addr, sdata->u.ibss.bssid, NULL, 0, 0); } @@ -304,7 +301,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", + net_info_ratelimited("%s: No room for a new IBSS STA entry %pM\n", sdata->name, addr); rcu_read_lock(); return NULL; @@ -351,9 +348,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) return; - ibss_vdbg("%s: RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", - sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, - auth_transaction); + ibss_dbg(sdata, + "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", + mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); sta_info_destroy_addr(sdata, mgmt->sa); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); rcu_read_unlock(); @@ -416,10 +413,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, ieee80211_mandatory_rates(local, band); if (sta->sta.supp_rates[band] != prev_rates) { - ibss_vdbg("%s: updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", - sdata->name, sta->sta.addr, - prev_rates, - sta->sta.supp_rates[band]); + ibss_dbg(sdata, + "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", + sta->sta.addr, prev_rates, + sta->sta.supp_rates[band]); rates_updated = true; } } else { @@ -534,16 +531,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, rx_timestamp = drv_get_tsf(local, sdata); } - ibss_vdbg("RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", - mgmt->sa, mgmt->bssid, - (unsigned long long)rx_timestamp, - (unsigned long long)beacon_timestamp, - (unsigned long long)(rx_timestamp - beacon_timestamp), - jiffies); + ibss_dbg(sdata, + "RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", + mgmt->sa, mgmt->bssid, + (unsigned long long)rx_timestamp, + (unsigned long long)beacon_timestamp, + (unsigned long long)(rx_timestamp - beacon_timestamp), + jiffies); if (beacon_timestamp > rx_timestamp) { - ibss_vdbg("%s: beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", - sdata->name, mgmt->bssid); + ibss_dbg(sdata, + "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", + mgmt->bssid); ieee80211_sta_join_ibss(sdata, bss); supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, @@ -569,7 +568,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", + net_info_ratelimited("%s: No room for a new IBSS STA entry %pM\n", sdata->name, addr); return; } @@ -645,8 +644,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) if (ifibss->fixed_channel) return; - pr_debug("%s: No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n", - sdata->name); + sdata_info(sdata, + "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len, NULL); @@ -674,8 +673,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) bssid[0] |= 0x02; } - pr_debug("%s: Creating new IBSS network, BSSID %pM\n", - sdata->name, bssid); + sdata_info(sdata, "Creating new IBSS network, BSSID %pM\n", bssid); capability = WLAN_CAPABILITY_IBSS; @@ -706,8 +704,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&ifibss->mtx); active_ibss = ieee80211_sta_active_ibss(sdata); - ibss_vdbg("%s: sta_find_ibss (active_ibss=%d)\n", - sdata->name, active_ibss); + ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); if (active_ibss) return; @@ -730,23 +727,24 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) struct ieee80211_bss *bss; bss = (void *)cbss->priv; - ibss_vdbg(" sta_find_ibss: selected %pM current %pM\n", - cbss->bssid, ifibss->bssid); - pr_debug("%s: Selected IBSS BSSID %pM based on configured SSID\n", - sdata->name, cbss->bssid); + ibss_dbg(sdata, + "sta_find_ibss: selected %pM current %pM\n", + cbss->bssid, ifibss->bssid); + sdata_info(sdata, + "Selected IBSS BSSID %pM based on configured SSID\n", + cbss->bssid); ieee80211_sta_join_ibss(sdata, bss); ieee80211_rx_bss_put(local, bss); return; } - ibss_vdbg(" did not try to join ibss\n"); + ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); /* Selected IBSS not found in current scan results - try to scan */ if (time_after(jiffies, ifibss->last_scan_completed + IEEE80211_SCAN_INTERVAL)) { - pr_debug("%s: Trigger new scan to find an IBSS to join\n", - sdata->name); + sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len, @@ -760,9 +758,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) ieee80211_sta_create_ibss(sdata); return; } - pr_debug("%s: IBSS not allowed on %d MHz\n", - sdata->name, - local->hw.conf.channel->center_freq); + sdata_info(sdata, "IBSS not allowed on %d MHz\n", + local->hw.conf.channel->center_freq); /* No IBSS found - decrease scan interval and continue * scanning. */ @@ -797,9 +794,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, tx_last_beacon = drv_tx_last_beacon(local); - ibss_vdbg("%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", - sdata->name, mgmt->sa, mgmt->da, - mgmt->bssid, tx_last_beacon); + ibss_dbg(sdata, + "RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", + mgmt->sa, mgmt->da, mgmt->bssid, tx_last_beacon); if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; @@ -812,8 +809,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, pos = mgmt->u.probe_req.variable; if (pos[0] != WLAN_EID_SSID || pos + 2 + pos[1] > end) { - ibss_vdbg("%s: Invalid SSID IE in ProbeReq from %pM\n", - sdata->name, mgmt->sa); + ibss_dbg(sdata, "Invalid SSID IE in ProbeReq from %pM\n", + mgmt->sa); return; } if (pos[1] != 0 && @@ -830,7 +827,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, resp = (struct ieee80211_mgmt *) skb->data; memcpy(resp->da, mgmt->sa, ETH_ALEN); - ibss_vdbg("%s: Sending ProbeResp to %pM\n", sdata->name, resp->da); + ibss_dbg(sdata, "Sending ProbeResp to %pM\n", resp->da); IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; ieee80211_tx_skb(sdata, skb); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 36ce2bb066bf..f834a005e1c5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -30,6 +30,7 @@ #include #include "key.h" #include "sta_info.h" +#include "debug.h" struct ieee80211_local; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 728d3eac1f59..576880317d0e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -57,9 +57,6 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - pr_debug("%s: setting MTU %d\n", dev->name, new_mtu); -#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ dev->mtu = new_mtu; return 0; } @@ -1223,7 +1220,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { /* not a contiguous mask ... not handled now! */ - pr_debug("not contiguous\n"); + pr_info("not contiguous\n"); break; } @@ -1414,10 +1411,6 @@ static u32 ieee80211_idle_off(struct ieee80211_local *local, if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) return 0; -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason); -#endif - local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; return IEEE80211_CONF_CHANGE_IDLE; } @@ -1427,10 +1420,6 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) if (local->hw.conf.flags & IEEE80211_CONF_IDLE) return 0; -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, "device now idle\n"); -#endif - drv_flush(local, false); local->hw.conf.flags |= IEEE80211_CONF_IDLE; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 5bb600d93d77..b3b7e526e245 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -139,7 +139,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) } if (ret != -ENOSPC && ret != -EOPNOTSUPP) - wiphy_err(key->local->hw.wiphy, + sdata_err(sdata, "failed to set key (%d, %pM) to hardware (%d)\n", key->conf.keyidx, sta ? sta->sta.addr : bcast_addr, ret); @@ -186,7 +186,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) sta ? &sta->sta : NULL, &key->conf); if (ret) - wiphy_err(key->local->hw.wiphy, + sdata_err(sdata, "failed to remove key (%d, %pM) from hardware (%d)\n", key->conf.keyidx, sta ? sta->sta.addr : bcast_addr, ret); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index ae40a83675e9..764593d65fc3 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -523,10 +523,6 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, { bool free_plinks; -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - pr_debug("%s: running mesh housekeeping\n", sdata->name); -#endif - ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); mesh_path_expire(sdata); diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index aed1821bd6f1..fb7b6a11d0ba 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -13,13 +13,6 @@ #include "wme.h" #include "mesh.h" -#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG -#define mhwmp_dbg(fmt, args...) \ - pr_debug("Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) -#else -#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) -#endif - #define TEST_FRAME_LEN 8192 #define MAX_METRIC 0xffffffff #define ARITH_SHIFT 8 @@ -144,19 +137,19 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, switch (action) { case MPATH_PREQ: - mhwmp_dbg("sending PREQ to %pM", target); + mhwmp_dbg(sdata, "sending PREQ to %pM\n", target); ie_len = 37; pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_PREQ; break; case MPATH_PREP: - mhwmp_dbg("sending PREP to %pM", target); + mhwmp_dbg(sdata, "sending PREP to %pM\n", target); ie_len = 31; pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_PREP; break; case MPATH_RANN: - mhwmp_dbg("sending RANN from %pM", orig_addr); + mhwmp_dbg(sdata, "sending RANN from %pM\n", orig_addr); ie_len = sizeof(struct ieee80211_rann_ie); pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_RANN; @@ -535,10 +528,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, flags = PREQ_IE_FLAGS(preq_elem); root_is_gate = !!(flags & RANN_FLAG_IS_GATE); - mhwmp_dbg("received PREQ from %pM", orig_addr); + mhwmp_dbg(sdata, "received PREQ from %pM\n", orig_addr); if (ether_addr_equal(target_addr, sdata->vif.addr)) { - mhwmp_dbg("PREQ is for us"); + mhwmp_dbg(sdata, "PREQ is for us\n"); forward = false; reply = true; metric = 0; @@ -590,7 +583,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, lifetime = PREQ_IE_LIFETIME(preq_elem); ttl = ifmsh->mshcfg.element_ttl; if (ttl != 0) { - mhwmp_dbg("replying to the PREQ"); + mhwmp_dbg(sdata, "replying to the PREQ\n"); mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, cpu_to_le32(orig_sn), 0, target_addr, cpu_to_le32(target_sn), mgmt->sa, 0, ttl, @@ -611,7 +604,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, ifmsh->mshstats.dropped_frames_ttl++; return; } - mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); + mhwmp_dbg(sdata, "forwarding the PREQ from %pM\n", orig_addr); --ttl; preq_id = PREQ_IE_PREQ_ID(preq_elem); hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; @@ -658,7 +651,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, u8 next_hop[ETH_ALEN]; u32 target_sn, orig_sn, lifetime; - mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); + mhwmp_dbg(sdata, "received PREP from %pM\n", + PREP_IE_ORIG_ADDR(prep_elem)); orig_addr = PREP_IE_ORIG_ADDR(prep_elem); if (ether_addr_equal(orig_addr, sdata->vif.addr)) @@ -784,8 +778,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, if (ether_addr_equal(orig_addr, sdata->vif.addr)) return; - mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", - orig_addr, mgmt->sa, root_is_gate); + mhwmp_dbg(sdata, + "received RANN from %pM via neighbour %pM (is_gate=%d)\n", + orig_addr, mgmt->sa, root_is_gate); rcu_read_lock(); sta = sta_info_get(sdata, mgmt->sa); @@ -818,8 +813,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, root_path_confirmation_jiffies(sdata)) || time_before(jiffies, mpath->last_preq_to_root))) && !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) { - mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, - orig_addr); + mhwmp_dbg(sdata, + "time to refresh root mpath %pM\n", + orig_addr); mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); mpath->last_preq_to_root = jiffies; } @@ -926,7 +922,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); if (!preq_node) { - mhwmp_dbg("could not allocate PREQ node"); + mhwmp_dbg(sdata, "could not allocate PREQ node\n"); return; } @@ -935,7 +931,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); kfree(preq_node); if (printk_ratelimit()) - mhwmp_dbg("PREQ node queue full"); + mhwmp_dbg(sdata, "PREQ node queue full\n"); return; } @@ -1183,7 +1179,7 @@ void mesh_path_timer(unsigned long data) if (!mpath->is_gate && mesh_gate_num(sdata) > 0) { ret = mesh_path_send_to_gates(mpath); if (ret) - mhwmp_dbg("no gate was reachable"); + mhwmp_dbg(sdata, "no gate was reachable\n"); } else mesh_path_flush_pending(mpath); } @@ -1221,7 +1217,7 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) 0, cpu_to_le32(ifmsh->preq_id++), sdata); break; default: - mhwmp_dbg("Proactive mechanism not supported"); + mhwmp_dbg(sdata, "Proactive mechanism not supported\n"); return; } } diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 572f706fd65b..c9ae931dd693 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -18,12 +18,6 @@ #include "ieee80211_i.h" #include "mesh.h" -#ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG -#define mpath_dbg(fmt, args...) pr_debug(fmt, ##args) -#else -#define mpath_dbg(fmt, args...) do { (void)(0); } while (0) -#endif - /* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */ #define INIT_PATHS_SIZE_ORDER 2 @@ -322,9 +316,8 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags); skb_queue_splice(&gateq, &gate_mpath->frame_queue); - mpath_dbg("Mpath queue for gate %pM has %d frames\n", - gate_mpath->dst, - skb_queue_len(&gate_mpath->frame_queue)); + mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n", + gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue)); spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags); if (!copy) @@ -446,9 +439,9 @@ int mesh_path_add_gate(struct mesh_path *mpath) hlist_add_head_rcu(&new_gate->list, tbl->known_gates); spin_unlock_bh(&tbl->gates_lock); rcu_read_unlock(); - mpath_dbg("Mesh path (%s): Recorded new gate: %pM. %d known gates\n", - mpath->sdata->name, mpath->dst, - mpath->sdata->u.mesh.num_gates); + mpath_dbg(mpath->sdata, + "Mesh path: Recorded new gate: %pM. %d known gates\n", + mpath->dst, mpath->sdata->u.mesh.num_gates); return 0; err_rcu: rcu_read_unlock(); @@ -477,8 +470,8 @@ static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) spin_unlock_bh(&tbl->gates_lock); mpath->sdata->u.mesh.num_gates--; mpath->is_gate = false; - mpath_dbg("Mesh path (%s): Deleted gate: %pM. " - "%d known gates\n", mpath->sdata->name, + mpath_dbg(mpath->sdata, + "Mesh path: Deleted gate: %pM. %d known gates\n", mpath->dst, mpath->sdata->u.mesh.num_gates); break; } @@ -946,19 +939,20 @@ int mesh_path_send_to_gates(struct mesh_path *mpath) continue; if (gate->mpath->flags & MESH_PATH_ACTIVE) { - mpath_dbg("Forwarding to %pM\n", gate->mpath->dst); + mpath_dbg(sdata, "Forwarding to %pM\n", gate->mpath->dst); mesh_path_move_to_queue(gate->mpath, from_mpath, copy); from_mpath = gate->mpath; copy = true; } else { - mpath_dbg("Not forwarding %p\n", gate->mpath); - mpath_dbg("flags %x\n", gate->mpath->flags); + mpath_dbg(sdata, + "Not forwarding %p (flags %#x)\n", + gate->mpath, gate->mpath->flags); } } hlist_for_each_entry_rcu(gate, n, known_gates, list) if (gate->mpath->sdata == sdata) { - mpath_dbg("Sending to %pM\n", gate->mpath->dst); + mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst); mesh_path_tx_pending(gate->mpath); } diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index be4fad128c34..a1dbd1540276 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -13,12 +13,6 @@ #include "rate.h" #include "mesh.h" -#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG -#define mpl_dbg(fmt, args...) pr_debug(fmt, ##args) -#else -#define mpl_dbg(fmt, args...) do { (void)(0); } while (0) -#endif - #define PLINK_GET_LLID(p) (p + 2) #define PLINK_GET_PLID(p) (p + 4) @@ -134,12 +128,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) switch (sta->ch_type) { case NL80211_CHAN_NO_HT: - mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present", + mpl_dbg(sdata, + "mesh_plink %pM: nonHT sta (%pM) is present\n", sdata->vif.addr, sta->sta.addr); non_ht_sta = true; goto out; case NL80211_CHAN_HT20: - mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present", + mpl_dbg(sdata, + "mesh_plink %pM: HT20 sta (%pM) is present\n", sdata->vif.addr, sta->sta.addr); ht20_sta = true; default: @@ -160,7 +156,8 @@ out: sdata->vif.bss_conf.ht_operation_mode = ht_opmode; sdata->u.mesh.mshcfg.ht_opmode = ht_opmode; changed = BSS_CHANGED_HT; - mpl_dbg("mesh_plink %pM: protection mode changed to %d", + mpl_dbg(sdata, + "mesh_plink %pM: protection mode changed to %d\n", sdata->vif.addr, ht_opmode); } @@ -437,7 +434,8 @@ static void mesh_plink_timer(unsigned long data) spin_unlock_bh(&sta->lock); return; } - mpl_dbg("Mesh plink timer for %pM fired on state %d\n", + mpl_dbg(sta->sdata, + "Mesh plink timer for %pM fired on state %d\n", sta->sta.addr, sta->plink_state); reason = 0; llid = sta->llid; @@ -450,7 +448,8 @@ static void mesh_plink_timer(unsigned long data) /* retry timer */ if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { u32 rand; - mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n", + mpl_dbg(sta->sdata, + "Mesh plink for %pM (retry, timeout): %d %d\n", sta->sta.addr, sta->plink_retries, sta->plink_timeout); get_random_bytes(&rand, sizeof(u32)); @@ -530,7 +529,8 @@ int mesh_plink_open(struct sta_info *sta) sta->plink_state = NL80211_PLINK_OPN_SNT; mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); spin_unlock_bh(&sta->lock); - mpl_dbg("Mesh plink: starting establishment with %pM\n", + mpl_dbg(sdata, + "Mesh plink: starting establishment with %pM\n", sta->sta.addr); return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, @@ -565,7 +565,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m u8 *baseaddr; u32 changed = 0; __le16 plid, llid, reason; -#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG static const char *mplstates[] = { [NL80211_PLINK_LISTEN] = "LISTEN", [NL80211_PLINK_OPN_SNT] = "OPN-SNT", @@ -575,14 +574,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m [NL80211_PLINK_HOLDING] = "HOLDING", [NL80211_PLINK_BLOCKED] = "BLOCKED" }; -#endif /* need action_code, aux */ if (len < IEEE80211_MIN_ACTION_SIZE + 3) return; if (is_multicast_ether_addr(mgmt->da)) { - mpl_dbg("Mesh plink: ignore frame from multicast address"); + mpl_dbg(sdata, + "Mesh plink: ignore frame from multicast address\n"); return; } @@ -595,12 +594,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } ieee802_11_parse_elems(baseaddr, len - baselen, &elems); if (!elems.peering) { - mpl_dbg("Mesh plink: missing necessary peer link ie\n"); + mpl_dbg(sdata, + "Mesh plink: missing necessary peer link ie\n"); return; } if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { - mpl_dbg("Mesh plink: can't establish link with secure peer\n"); + mpl_dbg(sdata, + "Mesh plink: can't establish link with secure peer\n"); return; } @@ -610,14 +611,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 && ie_len != 8)) { - mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", - ftype, ie_len); + mpl_dbg(sdata, + "Mesh plink: incorrect plink ie length %d %d\n", + ftype, ie_len); return; } if (ftype != WLAN_SP_MESH_PEERING_CLOSE && (!elems.mesh_id || !elems.mesh_config)) { - mpl_dbg("Mesh plink: missing necessary ie\n"); + mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); return; } /* Note the lines below are correct, the llid in the frame is the plid @@ -632,21 +634,21 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m sta = sta_info_get(sdata, mgmt->sa); if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { - mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); + mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); rcu_read_unlock(); return; } if (ftype == WLAN_SP_MESH_PEERING_OPEN && !rssi_threshold_check(sta, sdata)) { - mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", + mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", mgmt->sa); rcu_read_unlock(); return; } if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { - mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); + mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); rcu_read_unlock(); return; } @@ -683,7 +685,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } else if (!sta) { /* ftype == WLAN_SP_MESH_PEERING_OPEN */ if (!mesh_plink_free_count(sdata)) { - mpl_dbg("Mesh plink error: no more free plinks\n"); + mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); rcu_read_unlock(); return; } @@ -724,7 +726,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m event = CLS_ACPT; break; default: - mpl_dbg("Mesh plink: unknown frame subtype\n"); + mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); rcu_read_unlock(); return; } @@ -734,13 +736,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m /* allocate sta entry if necessary and update info */ sta = mesh_peer_init(sdata, mgmt->sa, &elems); if (!sta) { - mpl_dbg("Mesh plink: failed to init peer!\n"); + mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); rcu_read_unlock(); return; } } - mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", + mpl_dbg(sdata, + "Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", mgmt->sa, mplstates[sta->plink_state], le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), event); @@ -851,7 +854,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m mesh_plink_inc_estab_count(sdata); changed |= mesh_set_ht_prot_mode(sdata); changed |= BSS_CHANGED_BEACON; - mpl_dbg("Mesh plink with %pM ESTABLISHED\n", + mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); break; default: @@ -887,7 +890,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m mesh_plink_inc_estab_count(sdata); changed |= mesh_set_ht_prot_mode(sdata); changed |= BSS_CHANGED_BEACON; - mpl_dbg("Mesh plink with %pM ESTABLISHED\n", + mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 0ccdad49f987..accfa00ffcdf 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c @@ -12,13 +12,6 @@ #include "mesh.h" #include "driver-ops.h" -#ifdef CONFIG_MAC80211_VERBOSE_MESH_SYNC_DEBUG -#define msync_dbg(fmt, args...) \ - pr_debug("Mesh sync (%s): " fmt "\n", sdata->name, ##args) -#else -#define msync_dbg(fmt, args...) do { (void)(0); } while (0) -#endif - /* This is not in the standard. It represents a tolerable tbtt drift below * which we do no TSF adjustment. */ @@ -65,14 +58,14 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) spin_lock_bh(&ifmsh->sync_offset_lock); if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { - msync_dbg("TBTT : max clockdrift=%lld; adjusting", - (long long) ifmsh->sync_offset_clockdrift_max); + msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n", + (long long) ifmsh->sync_offset_clockdrift_max); tsfdelta = -ifmsh->sync_offset_clockdrift_max; ifmsh->sync_offset_clockdrift_max = 0; } else { - msync_dbg("TBTT : max clockdrift=%lld; adjusting by %llu", - (long long) ifmsh->sync_offset_clockdrift_max, - (unsigned long long) beacon_int_fraction); + msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting by %llu\n", + (long long) ifmsh->sync_offset_clockdrift_max, + (unsigned long long) beacon_int_fraction); tsfdelta = -beacon_int_fraction; ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction; } @@ -120,7 +113,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); - msync_dbg("STA %pM : is adjusting TBTT", sta->sta.addr); + msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", sta->sta.addr); goto no_sync; } @@ -169,7 +162,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { s64 t_clockdrift = sta->t_offset_setpoint - sta->t_offset; - msync_dbg("STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld", + msync_dbg(sdata, + "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n", sta->sta.addr, (long long) sta->t_offset, (long long) @@ -178,7 +172,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT || t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) { - msync_dbg("STA %pM : t_clockdrift=%lld too large, setpoint reset", + msync_dbg(sdata, + "STA %pM : t_clockdrift=%lld too large, setpoint reset\n", sta->sta.addr, (long long) t_clockdrift); clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); @@ -197,8 +192,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, } else { sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN; set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); - msync_dbg("STA %pM : offset was invalid, " - " sta->t_offset=%lld", + msync_dbg(sdata, + "STA %pM : offset was invalid, sta->t_offset=%lld\n", sta->sta.addr, (long long) sta->t_offset); rcu_read_unlock(); @@ -226,17 +221,15 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) * to the driver tsf setter, we punt * the tsf adjustment to the mesh tasklet */ - msync_dbg("TBTT : kicking off TBTT " - "adjustment with " - "clockdrift_max=%lld", - ifmsh->sync_offset_clockdrift_max); + msync_dbg(sdata, + "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n", + ifmsh->sync_offset_clockdrift_max); set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags); } else { - msync_dbg("TBTT : max clockdrift=%lld; " - "too small to adjust", - (long long) - ifmsh->sync_offset_clockdrift_max); + msync_dbg(sdata, + "TBTT : max clockdrift=%lld; too small to adjust\n", + (long long)ifmsh->sync_offset_clockdrift_max); ifmsh->sync_offset_clockdrift_max = 0; } spin_unlock_bh(&ifmsh->sync_offset_lock); @@ -268,7 +261,7 @@ static void mesh_sync_vendor_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, const u8 *oui; WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); - msync_dbg("called mesh_sync_vendor_rx_bcn_presp"); + msync_dbg(sdata, "called mesh_sync_vendor_rx_bcn_presp\n"); oui = mesh_get_vendor_oui(sdata); /* here you would implement the vendor offset tracking for this oui */ } @@ -278,7 +271,7 @@ static void mesh_sync_vendor_adjust_tbtt(struct ieee80211_sub_if_data *sdata) const u8 *oui; WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); - msync_dbg("called mesh_sync_vendor_adjust_tbtt"); + msync_dbg(sdata, "called mesh_sync_vendor_adjust_tbtt\n"); oui = mesh_get_vendor_oui(sdata); /* here you would implement the vendor tsf adjustment for this oui */ } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2b450f541993..e11cd0e033ef 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1186,19 +1186,16 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, params.txop = get_unaligned_le16(pos + 2); params.uapsd = uapsd; -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, - "WMM queue=%d aci=%d acm=%d aifs=%d " - "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", - queue, aci, acm, - params.aifs, params.cw_min, params.cw_max, - params.txop, params.uapsd); -#endif + mlme_dbg(sdata, + "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", + queue, aci, acm, + params.aifs, params.cw_min, params.cw_max, + params.txop, params.uapsd); sdata->tx_conf[queue] = params; if (drv_conf_tx(local, sdata, queue, ¶ms)) - wiphy_debug(local->hw.wiphy, - "failed to set TX queue parameters for queue %d\n", - queue); + sdata_err(sdata, + "failed to set TX queue parameters for queue %d\n", + queue); } /* enable WMM or activate new settings */ @@ -1565,11 +1562,10 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, goto out; } -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG if (beacon) - net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", - sdata->name); -#endif + mlme_dbg_ratelimited(sdata, + "detected beacon loss from AP - sending probe request\n"); + ieee80211_cqm_rssi_notify(&sdata->vif, NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); @@ -1654,7 +1650,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); - pr_debug("%s: Connection to AP %pM lost\n", sdata->name, bssid); + sdata_info(sdata, "Connection to AP %pM lost\n", bssid); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, @@ -1788,8 +1784,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (status_code != WLAN_STATUS_SUCCESS) { - pr_debug("%s: %pM denied authentication (status %d)\n", - sdata->name, mgmt->sa, status_code); + sdata_info(sdata, "%pM denied authentication (status %d)\n", + mgmt->sa, status_code); ieee80211_destroy_auth_data(sdata, false); return RX_MGMT_CFG80211_RX_AUTH; } @@ -1812,7 +1808,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; } - pr_debug("%s: authenticated\n", sdata->name); + sdata_info(sdata, "authenticated\n"); ifmgd->auth_data->done = true; ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -1825,7 +1821,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, goto out_err; } if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { - pr_debug("%s: failed moving %pM to auth\n", sdata->name, bssid); + sdata_info(sdata, "failed moving %pM to auth\n", bssid); goto out_err; } mutex_unlock(&sdata->local->sta_mtx); @@ -1859,8 +1855,8 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - pr_debug("%s: deauthenticated from %pM (Reason: %u)\n", - sdata->name, bssid, reason_code); + sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", + bssid, reason_code); ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -1890,8 +1886,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - pr_debug("%s: disassociated from %pM (Reason: %u)\n", - sdata->name, mgmt->sa, reason_code); + sdata_info(sdata, "disassociated from %pM (Reason: %u)\n", + mgmt->sa, reason_code); ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -1983,15 +1979,15 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - pr_debug("%s: invalid AID value 0x%x; bits 15:14 not set\n", - sdata->name, aid); + sdata_info(sdata, "invalid AID value 0x%x; bits 15:14 not set\n", + aid); aid &= ~(BIT(15) | BIT(14)); ifmgd->broken_ap = false; if (aid == 0 || aid > IEEE80211_MAX_AID) { - pr_debug("%s: invalid AID value %d (out of range), turn off PS\n", - sdata->name, aid); + sdata_info(sdata, "invalid AID value %d (out of range), turn off PS\n", + aid); aid = 0; ifmgd->broken_ap = true; } @@ -2000,8 +1996,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.supp_rates) { - pr_debug("%s: no SuppRates element in AssocResp\n", - sdata->name); + sdata_info(sdata, "no SuppRates element in AssocResp\n"); return false; } @@ -2041,8 +2036,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); if (err) { - pr_debug("%s: failed to move station %pM to desired state\n", - sdata->name, sta->sta.addr); + sdata_info(sdata, + "failed to move station %pM to desired state\n", + sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); mutex_unlock(&sdata->local->sta_mtx); return false; @@ -2125,9 +2121,10 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); aid = le16_to_cpu(mgmt->u.assoc_resp.aid); - pr_debug("%s: RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", - sdata->name, reassoc ? "Rea" : "A", mgmt->sa, - capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); + sdata_info(sdata, + "RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", + reassoc ? "Rea" : "A", mgmt->sa, + capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); pos = mgmt->u.assoc_resp.variable; ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); @@ -2138,8 +2135,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, u32 tu, ms; tu = get_unaligned_le32(elems.timeout_int + 1); ms = tu * 1024 / 1000; - pr_debug("%s: %pM rejected association temporarily; comeback duration %u TU (%u ms)\n", - sdata->name, mgmt->sa, tu, ms); + sdata_info(sdata, + "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", + mgmt->sa, tu, ms); assoc_data->timeout = jiffies + msecs_to_jiffies(ms); if (ms > IEEE80211_ASSOC_TIMEOUT) run_again(ifmgd, assoc_data->timeout); @@ -2149,11 +2147,11 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, *bss = assoc_data->bss; if (status_code != WLAN_STATUS_SUCCESS) { - pr_debug("%s: %pM denied association (code=%d)\n", - sdata->name, mgmt->sa, status_code); + sdata_info(sdata, "%pM denied association (code=%d)\n", + mgmt->sa, status_code); ieee80211_destroy_assoc_data(sdata, false); } else { - pr_debug("%s: associated\n", sdata->name); + sdata_info(sdata, "associated\n"); if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { /* oops -- internal error -- send timeout for now */ @@ -2261,7 +2259,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { /* got probe response, continue with auth */ - pr_debug("%s: direct probe responded\n", sdata->name); + sdata_info(sdata, "direct probe responded\n"); ifmgd->auth_data->tries = 0; ifmgd->auth_data->timeout = jiffies; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -2397,10 +2395,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", - sdata->name); -#endif + mlme_dbg_ratelimited(sdata, + "cancelling probereq poll due to a received beacon\n"); mutex_lock(&local->mtx); ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; ieee80211_run_deferred_scan(local); @@ -2625,8 +2621,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) auth_data->tries++; if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { - pr_debug("%s: authentication with %pM timed out\n", - sdata->name, auth_data->bss->bssid); + sdata_info(sdata, "authentication with %pM timed out\n", + auth_data->bss->bssid); /* * Most likely AP is not in the range so remove the @@ -2638,9 +2634,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) } if (auth_data->bss->proberesp_ies) { - pr_debug("%s: send auth to %pM (try %d/%d)\n", - sdata->name, auth_data->bss->bssid, auth_data->tries, - IEEE80211_AUTH_MAX_TRIES); + sdata_info(sdata, "send auth to %pM (try %d/%d)\n", + auth_data->bss->bssid, auth_data->tries, + IEEE80211_AUTH_MAX_TRIES); auth_data->expected_transaction = 2; ieee80211_send_auth(sdata, 1, auth_data->algorithm, @@ -2650,9 +2646,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) } else { const u8 *ssidie; - pr_debug("%s: direct probe to %pM (try %d/%i)\n", - sdata->name, auth_data->bss->bssid, auth_data->tries, - IEEE80211_AUTH_MAX_TRIES); + sdata_info(sdata, "direct probe to %pM (try %d/%i)\n", + auth_data->bss->bssid, auth_data->tries, + IEEE80211_AUTH_MAX_TRIES); ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); if (!ssidie) @@ -2680,8 +2676,8 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) assoc_data->tries++; if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { - pr_debug("%s: association with %pM timed out\n", - sdata->name, assoc_data->bss->bssid); + sdata_info(sdata, "association with %pM timed out\n", + assoc_data->bss->bssid); /* * Most likely AP is not in the range so remove the @@ -2692,9 +2688,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) return -ETIMEDOUT; } - pr_debug("%s: associate with %pM (try %d/%d)\n", - sdata->name, assoc_data->bss->bssid, assoc_data->tries, - IEEE80211_ASSOC_MAX_TRIES); + sdata_info(sdata, "associate with %pM (try %d/%d)\n", + assoc_data->bss->bssid, assoc_data->tries, + IEEE80211_ASSOC_MAX_TRIES); ieee80211_send_assoc(sdata); assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; @@ -2767,45 +2763,31 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) ieee80211_reset_ap_probe(sdata); else if (ifmgd->nullfunc_failed) { if (ifmgd->probe_send_count < max_tries) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, - "%s: No ack for nullfunc frame to" - " AP %pM, try %d/%i\n", - sdata->name, bssid, - ifmgd->probe_send_count, max_tries); -#endif + mlme_dbg(sdata, + "No ack for nullfunc frame to AP %pM, try %d/%i\n", + bssid, ifmgd->probe_send_count, + max_tries); ieee80211_mgd_probe_ap_send(sdata); } else { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, - "%s: No ack for nullfunc frame to" - " AP %pM, disconnecting.\n", - sdata->name, bssid); -#endif + mlme_dbg(sdata, + "No ack for nullfunc frame to AP %pM, disconnecting.\n", + bssid); ieee80211_sta_connection_lost(sdata, bssid, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } else if (time_is_after_jiffies(ifmgd->probe_timeout)) run_again(ifmgd, ifmgd->probe_timeout); else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, - "%s: Failed to send nullfunc to AP %pM" - " after %dms, disconnecting.\n", - sdata->name, - bssid, probe_wait_ms); -#endif + mlme_dbg(sdata, + "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", + bssid, probe_wait_ms); ieee80211_sta_connection_lost(sdata, bssid, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } else if (ifmgd->probe_send_count < max_tries) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, - "%s: No probe response from AP %pM" - " after %dms, try %d/%i\n", - sdata->name, - bssid, probe_wait_ms, - ifmgd->probe_send_count, max_tries); -#endif + mlme_dbg(sdata, + "No probe response from AP %pM after %dms, try %d/%i\n", + bssid, probe_wait_ms, + ifmgd->probe_send_count, max_tries); ieee80211_mgd_probe_ap_send(sdata); } else { /* @@ -2920,11 +2902,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; mutex_lock(&ifmgd->mtx); if (ifmgd->associated) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(sdata->local->hw.wiphy, - "%s: driver requested disconnect after resume.\n", - sdata->name); -#endif + mlme_dbg(sdata, + "driver requested disconnect after resume\n"); ieee80211_sta_connection_lost(sdata, ifmgd->associated->bssid, WLAN_REASON_UNSPECIFIED); @@ -3065,10 +3044,11 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, * since we look at probe response/beacon data here * it should be OK. */ - pr_debug("%s: Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", - sdata->name, cbss->channel->center_freq, - ht_cfreq, ht_oper->primary_chan, - cbss->channel->band); + sdata_info(sdata, + "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", + cbss->channel->center_freq, + ht_cfreq, ht_oper->primary_chan, + cbss->channel->band); ht_oper = NULL; } } @@ -3092,8 +3072,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, if (!ieee80211_set_channel_type(local, sdata, channel_type)) { /* can only fail due to HT40+/- mismatch */ channel_type = NL80211_CHAN_HT20; - pr_debug("%s: disabling 40 MHz due to multi-vif mismatch\n", - sdata->name); + sdata_info(sdata, + "disabling 40 MHz due to multi-vif mismatch\n"); ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); @@ -3122,8 +3102,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, * we can connect -- with a warning. */ if (!basic_rates && min_rate_index >= 0) { - pr_debug("%s: No basic rates, using min rate instead\n", - sdata->name); + sdata_info(sdata, + "No basic rates, using min rate instead\n"); basic_rates = BIT(min_rate_index); } @@ -3149,8 +3129,9 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, err = sta_info_insert(sta); sta = NULL; if (err) { - pr_debug("%s: failed to insert STA entry for the AP (error %d)\n", - sdata->name, err); + sdata_info(sdata, + "failed to insert STA entry for the AP (error %d)\n", + err); return err; } } else @@ -3228,7 +3209,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, if (ifmgd->associated) ieee80211_set_disassoc(sdata, 0, 0, false, NULL); - pr_debug("%s: authenticate with %pM\n", sdata->name, req->bss->bssid); + sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); err = ieee80211_prep_connection(sdata, req->bss, false); if (err) @@ -3410,8 +3391,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, * Wait up to one beacon interval ... * should this be more if we miss one? */ - pr_debug("%s: waiting for beacon from %pM\n", - sdata->name, ifmgd->bssid); + sdata_info(sdata, "waiting for beacon from %pM\n", + ifmgd->bssid); assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); } else { assoc_data->have_beacon = true; @@ -3430,8 +3411,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, corrupt_type = "beacon"; } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) corrupt_type = "probe response"; - pr_debug("%s: associating with AP with corrupt %s\n", - sdata->name, corrupt_type); + sdata_info(sdata, "associating with AP with corrupt %s\n", + corrupt_type); } err = 0; @@ -3460,8 +3441,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, return 0; } - pr_debug("%s: deauthenticating from %pM by local choice (reason=%d)\n", - sdata->name, req->bssid, req->reason_code); + sdata_info(sdata, + "deauthenticating from %pM by local choice (reason=%d)\n", + req->bssid, req->reason_code); if (ifmgd->associated && ether_addr_equal(ifmgd->associated->bssid, req->bssid)) @@ -3503,8 +3485,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, return -ENOLINK; } - pr_debug("%s: disassociating from %pM by local choice (reason=%d)\n", - sdata->name, req->bss->bssid, req->reason_code); + sdata_info(sdata, + "disassociating from %pM by local choice (reason=%d)\n", + req->bss->bssid, req->reason_code); memcpy(bssid, req->bss->bssid, ETH_ALEN); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9f1bd692589b..ab5185054e6c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -632,11 +632,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, HT_RX_REORDER_BUF_TIMEOUT)) goto set_release_timer; -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - wiphy_debug(sdata->local->hw.wiphy, - "release an RX reorder frame due to timeout on earlier frames\n"); -#endif + ht_dbg_ratelimited(sdata, + "release an RX reorder frame due to timeout on earlier frames\n"); ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); /* @@ -1136,24 +1133,18 @@ static void ap_sta_ps_start(struct sta_info *sta) set_sta_flag(sta, WLAN_STA_PS_STA); if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - pr_debug("%s: STA %pM aid %d enters power save mode\n", - sdata->name, sta->sta.addr, sta->sta.aid); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", + sta->sta.addr, sta->sta.aid); } static void ap_sta_ps_end(struct sta_info *sta) { -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - pr_debug("%s: STA %pM aid %d exits power save mode\n", - sta->sdata->name, sta->sta.addr, sta->sta.aid); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", + sta->sta.addr, sta->sta.aid); if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - pr_debug("%s: STA %pM aid %d driver-ps-blocked\n", - sta->sdata->name, sta->sta.addr, sta->sta.aid); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", + sta->sta.addr, sta->sta.aid); return; } @@ -1383,17 +1374,8 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) sdata->fragment_next = 0; - if (!skb_queue_empty(&entry->skb_list)) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) entry->skb_list.next->data; - pr_debug("%s: RX reassembly removed oldest fragment entry (idx=%d age=%lu seq=%d last_frag=%d addr1=%pM addr2=%pM\n", - sdata->name, idx, - jiffies - entry->first_frag_time, entry->seq, - entry->last_frag, hdr->addr1, hdr->addr2); -#endif + if (!skb_queue_empty(&entry->skb_list)) __skb_queue_purge(&entry->skb_list); - } __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ *skb = NULL; @@ -1751,7 +1733,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) */ xmit_skb = skb_copy(skb, GFP_ATOMIC); if (!xmit_skb) - net_dbg_ratelimited("%s: failed to clone multicast frame\n", + net_info_ratelimited("%s: failed to clone multicast frame\n", dev->name); } else { dsta = sta_info_get(sdata, skb->data); @@ -1955,7 +1937,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { - net_dbg_ratelimited("%s: failed to clone mesh frame\n", + net_info_ratelimited("%s: failed to clone mesh frame\n", sdata->name); goto out; } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 77dcf2f89d42..06fa75ceb025 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -169,9 +169,7 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) if (sta->rate_ctrl) rate_control_free_sta(sta); -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr); -#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ + sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); kfree(sta); } @@ -278,9 +276,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, for (i = 0; i < NUM_RX_DATA_QUEUES; i++) sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr); -#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ + sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); #ifdef CONFIG_MAC80211_MESH sta->plink_state = NL80211_PLINK_LISTEN; @@ -333,8 +329,9 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, } if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - pr_debug("%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", - sdata->name, sta->sta.addr, state + 1, err); + sdata_info(sdata, + "failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", + sta->sta.addr, state + 1, err); err = 0; } @@ -389,9 +386,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) sinfo.generation = local->sta_generation; cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); -#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ + sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr); /* move reference to rcu-protected */ rcu_read_lock(); @@ -617,9 +612,8 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, break; local->total_ps_buffered--; -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - pr_debug("Buffered frame expired (STA %pM)\n", sta->sta.addr); -#endif + ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", + sta->sta.addr); dev_kfree_skb(skb); } @@ -745,9 +739,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta) mesh_accept_plinks_update(sdata); #endif -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr); -#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ + sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); + cancel_work_sync(&sta->drv_unblock_wk); cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL); @@ -887,8 +880,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, continue; if (time_after(jiffies, sta->last_rx + exp_time)) { - ibss_vdbg("%s: expiring inactive STA %pM\n", - sdata->name, sta->sta.addr); + ibss_dbg(sdata, "expiring inactive STA %pM\n", + sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); } } @@ -986,10 +979,9 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) sta_info_recalc_tim(sta); -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - pr_debug("%s: STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", - sdata->name, sta->sta.addr, sta->sta.aid, filtered, buffered); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sdata, + "STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", + sta->sta.addr, sta->sta.aid, filtered, buffered); } static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, @@ -1379,10 +1371,8 @@ int sta_info_move_state(struct sta_info *sta, return -EINVAL; } -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - pr_debug("%s: moving STA %pM to state %d\n", - sta->sdata->name, sta->sta.addr, new_state); -#endif + sta_dbg(sta->sdata, "moving STA %pM to state %d\n", + sta->sta.addr, new_state); /* * notify the driver before the actual changes so it can diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 51a6d1e6e250..2ed2f27fe8a7 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -155,13 +155,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, return; } -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - if (net_ratelimit()) - wiphy_debug(local->hw.wiphy, - "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", - skb_queue_len(&sta->tx_filtered[ac]), - !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); -#endif + ps_dbg_ratelimited(sta->sdata, + "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", + skb_queue_len(&sta->tx_filtered[ac]), + !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); dev_kfree_skb(skb); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index af25c4e7ec5c..37eda7e00e03 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -297,9 +297,10 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) if (unlikely(!assoc && ieee80211_is_data(hdr->frame_control))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - pr_debug("%s: dropped data frame to not associated station %pM\n", - tx->sdata->name, hdr->addr1); -#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ + sdata_info(tx->sdata, + "dropped data frame to not associated station %pM\n", + hdr->addr1); +#endif I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); return TX_DROP; } @@ -366,10 +367,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) rcu_read_unlock(); local->total_ps_buffered = total; -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", - purged); -#endif + ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged); } static ieee80211_tx_result @@ -411,10 +409,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) purge_old_ps_buffers(tx->local); if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - net_dbg_ratelimited("%s: BC TX buffer full - dropping the oldest frame\n", - tx->sdata->name); -#endif + ps_dbg(tx->sdata, + "BC TX buffer full - dropping the oldest frame\n"); dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); } else tx->local->total_ps_buffered++; @@ -465,18 +461,15 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) return TX_CONTINUE; } -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - pr_debug("STA %pM aid %d: PS buffer for AC %d\n", - sta->sta.addr, sta->sta.aid, ac); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", + sta->sta.addr, sta->sta.aid, ac); if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) purge_old_ps_buffers(tx->local); if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - net_dbg_ratelimited("%s: STA %pM TX buffer for AC %d full - dropping oldest frame\n", - tx->sdata->name, sta->sta.addr, ac); -#endif + ps_dbg(tx->sdata, + "STA %pM TX buffer for AC %d full - dropping oldest frame\n", + sta->sta.addr, ac); dev_kfree_skb(old); } else tx->local->total_ps_buffered++; @@ -498,13 +491,11 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) sta_info_recalc_tim(sta); return TX_QUEUED; + } else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { + ps_dbg(tx->sdata, + "STA %pM in PS mode, but polling/in SP -> send frame\n", + sta->sta.addr); } -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { - pr_debug("%s: STA %pM in PS mode, but polling/in SP -> send frame\n", - tx->sdata->name, sta->sta.addr); - } -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ return TX_CONTINUE; } @@ -1963,7 +1954,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, (cpu_to_be16(ethertype) != sdata->control_port_protocol || !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - net_dbg_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", + net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", dev->name, hdr.addr1); #endif -- GitLab From 011ad0e9f8533cd003fb760663713df2655a2114 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 12:55:52 +0200 Subject: [PATCH 2607/6849] mac80211: rename driver-trace file This file will contain more soon, so rename it to just trace. Signed-off-by: Johannes Berg --- net/mac80211/Makefile | 4 ++-- net/mac80211/driver-ops.h | 2 +- net/mac80211/offchannel.c | 1 - net/mac80211/{driver-trace.c => trace.c} | 2 +- net/mac80211/{driver-trace.h => trace.h} | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) rename net/mac80211/{driver-trace.c => trace.c} (88%) rename net/mac80211/{driver-trace.h => trace.h} (99%) diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 231ffa02e496..a7dd110faafa 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -24,7 +24,7 @@ mac80211-y := \ wme.o \ event.o \ chan.o \ - driver-trace.o mlme.o + trace.o mlme.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ @@ -42,7 +42,7 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ mac80211-$(CONFIG_PM) += pm.o -CFLAGS_driver-trace.o := -I$(src) +CFLAGS_trace.o := -I$(src) # objects for PID algorithm rc80211_pid-y := rc80211_pid_algo.o diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 933026949df9..44e8c1242781 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -3,7 +3,7 @@ #include #include "ieee80211_i.h" -#include "driver-trace.h" +#include "trace.h" static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 7f93626ddc61..b0fb6a2b89ad 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -15,7 +15,6 @@ #include #include #include "ieee80211_i.h" -#include "driver-trace.h" #include "driver-ops.h" /* diff --git a/net/mac80211/driver-trace.c b/net/mac80211/trace.c similarity index 88% rename from net/mac80211/driver-trace.c rename to net/mac80211/trace.c index 8ed8711b1a6d..943da6e7076c 100644 --- a/net/mac80211/driver-trace.c +++ b/net/mac80211/trace.c @@ -5,5 +5,5 @@ #ifndef __CHECKER__ #include "driver-ops.h" #define CREATE_TRACE_POINTS -#include "driver-trace.h" +#include "trace.h" #endif diff --git a/net/mac80211/driver-trace.h b/net/mac80211/trace.h similarity index 99% rename from net/mac80211/driver-trace.h rename to net/mac80211/trace.h index a0f7d357884d..392bcc9f6a12 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/trace.h @@ -1637,5 +1637,5 @@ TRACE_EVENT(stop_queue, #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . #undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE driver-trace +#define TRACE_INCLUDE_FILE trace #include -- GitLab From 3fae0273168026ed7b6065674f1410f531d58164 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 13:36:25 +0200 Subject: [PATCH 2608/6849] mac80211: trace debug messages It can be very useful to have all debug messages available when debugging, but hard to correlate between different sources, so add a trace event for all mac80211 debug messages. Signed-off-by: Johannes Berg --- net/mac80211/Kconfig | 13 +++++++++ net/mac80211/debug.h | 18 ++++++++++++ net/mac80211/trace.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/trace.h | 39 ++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 7475e266eb4e..63af25458fda 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -107,6 +107,19 @@ config MAC80211_DEBUGFS Say N unless you know you need this. +config MAC80211_MESSAGE_TRACING + bool "Trace all mac80211 debug messages" + depends on MAC80211 + ---help--- + Select this option to have mac80211 register the + mac80211_msg trace subsystem with tracepoints to + collect all debugging messages, independent of + printing them into the kernel log. + + The overhead in this option is that all the messages + need to be present in the binary and formatted at + runtime for tracing. + menuconfig MAC80211_DEBUG_MENU bool "Select mac80211 debugging features" depends on MAC80211 diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h index 6e6bbb9a9d41..8f383a576016 100644 --- a/net/mac80211/debug.h +++ b/net/mac80211/debug.h @@ -1,5 +1,6 @@ #ifndef __MAC80211_DEBUG_H #define __MAC80211_DEBUG_H +#include #ifdef CONFIG_MAC80211_IBSS_DEBUG #define MAC80211_IBSS_DEBUG 1 @@ -61,6 +62,22 @@ #define MAC80211_MLME_DEBUG 0 #endif +#ifdef CONFIG_MAC80211_MESSAGE_TRACING +void __sdata_info(const char *fmt, ...) __printf(1, 2); +void __sdata_dbg(bool print, const char *fmt, ...) __printf(2, 3); +void __sdata_err(const char *fmt, ...) __printf(1, 2); +void __wiphy_dbg(struct wiphy *wiphy, bool print, const char *fmt, ...) + __printf(3, 4); + +#define _sdata_info(sdata, fmt, ...) \ + __sdata_info("%s: " fmt, (sdata)->name, ##__VA_ARGS__) +#define _sdata_dbg(print, sdata, fmt, ...) \ + __sdata_dbg(print, "%s: " fmt, (sdata)->name, ##__VA_ARGS__) +#define _sdata_err(sdata, fmt, ...) \ + __sdata_err("%s: " fmt, (sdata)->name, ##__VA_ARGS__) +#define _wiphy_dbg(print, wiphy, fmt, ...) \ + __wiphy_dbg(wiphy, print, fmt, ##__VA_ARGS__) +#else #define _sdata_info(sdata, fmt, ...) \ do { \ pr_info("%s: " fmt, \ @@ -85,6 +102,7 @@ do { \ if (print) \ wiphy_dbg((wiphy), fmt, ##__VA_ARGS__); \ } while (0) +#endif #define sdata_info(sdata, fmt, ...) \ _sdata_info(sdata, fmt, ##__VA_ARGS__) diff --git a/net/mac80211/trace.c b/net/mac80211/trace.c index 943da6e7076c..386e45d8a958 100644 --- a/net/mac80211/trace.c +++ b/net/mac80211/trace.c @@ -3,7 +3,73 @@ /* sparse isn't too happy with all macros... */ #ifndef __CHECKER__ +#include #include "driver-ops.h" +#include "debug.h" #define CREATE_TRACE_POINTS #include "trace.h" + +#ifdef CONFIG_MAC80211_MESSAGE_TRACING +void __sdata_info(const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + + pr_info("%pV", &vaf); + trace_mac80211_info(&vaf); + va_end(args); +} + +void __sdata_dbg(bool print, const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + + if (print) + pr_debug("%pV", &vaf); + trace_mac80211_dbg(&vaf); + va_end(args); +} + +void __sdata_err(const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + + pr_err("%pV", &vaf); + trace_mac80211_err(&vaf); + va_end(args); +} + +void __wiphy_dbg(struct wiphy *wiphy, bool print, const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + + if (print) + wiphy_dbg(wiphy, "%pV", &vaf); + trace_mac80211_dbg(&vaf); + va_end(args); +} +#endif #endif diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 392bcc9f6a12..2e60f4acd027 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -1632,6 +1632,45 @@ TRACE_EVENT(stop_queue, LOCAL_PR_ARG, __entry->queue, __entry->reason ) ); + +#ifdef CONFIG_MAC80211_MESSAGE_TRACING +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mac80211_msg + +#define MAX_MSG_LEN 100 + +DECLARE_EVENT_CLASS(mac80211_msg_event, + TP_PROTO(struct va_format *vaf), + + TP_ARGS(vaf), + + TP_STRUCT__entry( + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + + TP_fast_assign( + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + + TP_printk("%s", __get_str(msg)) +); + +DEFINE_EVENT(mac80211_msg_event, mac80211_info, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); +DEFINE_EVENT(mac80211_msg_event, mac80211_dbg, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); +DEFINE_EVENT(mac80211_msg_event, mac80211_err, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); +#endif + #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH -- GitLab From 2f6ae6ef631cd16b0725958ee805a24b9e38d7ad Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 19 Jun 2012 09:26:52 +0800 Subject: [PATCH 2609/6849] regulator: rc5t583: Use regulator_set_voltage_time_sel() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/rc5t583-regulator.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 332eae897dab..8bf4e8c9de9a 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -42,7 +42,6 @@ struct rc5t583_regulator_info { /* Regulator specific turn-on delay and voltage settling time*/ int enable_uv_per_us; - int change_uv_per_us; /* Used by regulator core */ struct regulator_desc desc; @@ -66,17 +65,6 @@ static int rc5t583_regulator_enable_time(struct regulator_dev *rdev) return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us); } -static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, unsigned int new_selector) -{ - struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); - - return DIV_ROUND_UP(abs(new_selector - old_selector) * - rdev->desc->uV_step, - reg->reg_info->change_uv_per_us); -} - - static struct regulator_ops rc5t583_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, @@ -86,7 +74,7 @@ static struct regulator_ops rc5t583_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, - .set_voltage_time_sel = rc5t583_set_voltage_time_sel, + .set_voltage_time_sel = regulator_set_voltage_time_sel, }; #define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \ @@ -96,7 +84,6 @@ static struct regulator_ops rc5t583_ops = { .disc_bit = _disc_bit, \ .deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \ .enable_uv_per_us = _enable_mv * 1000, \ - .change_uv_per_us = 40 * 1000, \ .deepsleep_id = RC5T583_DS_##_id, \ .desc = { \ .name = "rc5t583-regulator-"#_id, \ @@ -111,6 +98,7 @@ static struct regulator_ops rc5t583_ops = { .enable_mask = BIT(_en_bit), \ .min_uV = _min_mv * 1000, \ .uV_step = _step_uV, \ + .ramp_delay = 40 * 1000, \ }, \ } -- GitLab From 9e466250ede375482a9a65ca60765d24303099e9 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:50 +0200 Subject: [PATCH 2610/6849] batman-adv: Prefix bat_debugfs local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 143 ++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 4001c57a25e4..03f09f0f6d98 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -32,25 +32,25 @@ #include "icmp_socket.h" #include "bridge_loop_avoidance.h" -static struct dentry *bat_debugfs; +static struct dentry *batadv_debugfs; #ifdef CONFIG_BATMAN_ADV_DEBUG -#define LOG_BUFF_MASK (log_buff_len-1) +#define LOG_BUFF_MASK (batadv_log_buff_len - 1) #define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK]) -static int log_buff_len = LOG_BUF_LEN; +static int batadv_log_buff_len = LOG_BUF_LEN; -static void emit_log_char(struct debug_log *debug_log, char c) +static void batadv_emit_log_char(struct debug_log *debug_log, char c) { LOG_BUFF(debug_log->log_end) = c; debug_log->log_end++; - if (debug_log->log_end - debug_log->log_start > log_buff_len) - debug_log->log_start = debug_log->log_end - log_buff_len; + if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len) + debug_log->log_start = debug_log->log_end - batadv_log_buff_len; } __printf(2, 3) -static int fdebug_log(struct debug_log *debug_log, const char *fmt, ...) +static int batadv_fdebug_log(struct debug_log *debug_log, const char *fmt, ...) { va_list args; static char debug_log_buf[256]; @@ -65,7 +65,7 @@ static int fdebug_log(struct debug_log *debug_log, const char *fmt, ...) va_end(args); for (p = debug_log_buf; *p != 0; p++) - emit_log_char(debug_log, *p); + batadv_emit_log_char(debug_log, *p); spin_unlock_bh(&debug_log->lock); @@ -81,14 +81,14 @@ int batadv_debug_log(struct bat_priv *bat_priv, const char *fmt, ...) va_start(args, fmt); vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); - fdebug_log(bat_priv->debug_log, "[%10u] %s", - jiffies_to_msecs(jiffies), tmp_log_buf); + batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s", + jiffies_to_msecs(jiffies), tmp_log_buf); va_end(args); return 0; } -static int log_open(struct inode *inode, struct file *file) +static int batadv_log_open(struct inode *inode, struct file *file) { nonseekable_open(inode, file); file->private_data = inode->i_private; @@ -96,14 +96,14 @@ static int log_open(struct inode *inode, struct file *file) return 0; } -static int log_release(struct inode *inode, struct file *file) +static int batadv_log_release(struct inode *inode, struct file *file) { batadv_dec_module_count(); return 0; } -static ssize_t log_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +static ssize_t batadv_log_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { struct bat_priv *bat_priv = file->private_data; struct debug_log *debug_log = bat_priv->debug_log; @@ -156,7 +156,7 @@ static ssize_t log_read(struct file *file, char __user *buf, return error; } -static unsigned int log_poll(struct file *file, poll_table *wait) +static unsigned int batadv_log_poll(struct file *file, poll_table *wait) { struct bat_priv *bat_priv = file->private_data; struct debug_log *debug_log = bat_priv->debug_log; @@ -169,15 +169,15 @@ static unsigned int log_poll(struct file *file, poll_table *wait) return 0; } -static const struct file_operations log_fops = { - .open = log_open, - .release = log_release, - .read = log_read, - .poll = log_poll, +static const struct file_operations batadv_log_fops = { + .open = batadv_log_open, + .release = batadv_log_release, + .read = batadv_log_read, + .poll = batadv_log_poll, .llseek = no_llseek, }; -static int debug_log_setup(struct bat_priv *bat_priv) +static int batadv_debug_log_setup(struct bat_priv *bat_priv) { struct dentry *d; @@ -192,7 +192,8 @@ static int debug_log_setup(struct bat_priv *bat_priv) init_waitqueue_head(&bat_priv->debug_log->queue_wait); d = debugfs_create_file("log", S_IFREG | S_IRUSR, - bat_priv->debug_dir, bat_priv, &log_fops); + bat_priv->debug_dir, bat_priv, + &batadv_log_fops); if (!d) goto err; @@ -202,49 +203,49 @@ err: return -ENOMEM; } -static void debug_log_cleanup(struct bat_priv *bat_priv) +static void batadv_debug_log_cleanup(struct bat_priv *bat_priv) { kfree(bat_priv->debug_log); bat_priv->debug_log = NULL; } #else /* CONFIG_BATMAN_ADV_DEBUG */ -static int debug_log_setup(struct bat_priv *bat_priv) +static int batadv_debug_log_setup(struct bat_priv *bat_priv) { bat_priv->debug_log = NULL; return 0; } -static void debug_log_cleanup(struct bat_priv *bat_priv) +static void batadv_debug_log_cleanup(struct bat_priv *bat_priv) { return; } #endif -static int bat_algorithms_open(struct inode *inode, struct file *file) +static int batadv_algorithms_open(struct inode *inode, struct file *file) { return single_open(file, batadv_algo_seq_print_text, NULL); } -static int originators_open(struct inode *inode, struct file *file) +static int batadv_originators_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; return single_open(file, batadv_orig_seq_print_text, net_dev); } -static int gateways_open(struct inode *inode, struct file *file) +static int batadv_gateways_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; return single_open(file, batadv_gw_client_seq_print_text, net_dev); } -static int transtable_global_open(struct inode *inode, struct file *file) +static int batadv_transtable_global_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; return single_open(file, batadv_tt_global_seq_print_text, net_dev); } #ifdef CONFIG_BATMAN_ADV_BLA -static int bla_claim_table_open(struct inode *inode, struct file *file) +static int batadv_bla_claim_table_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; return single_open(file, batadv_bla_claim_table_seq_print_text, @@ -252,13 +253,13 @@ static int bla_claim_table_open(struct inode *inode, struct file *file) } #endif -static int transtable_local_open(struct inode *inode, struct file *file) +static int batadv_transtable_local_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; return single_open(file, batadv_tt_local_seq_print_text, net_dev); } -static int vis_data_open(struct inode *inode, struct file *file) +static int batadv_vis_data_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; return single_open(file, batadv_vis_seq_print_text, net_dev); @@ -269,37 +270,37 @@ struct bat_debuginfo { const struct file_operations fops; }; -#define BAT_DEBUGINFO(_name, _mode, _open) \ -struct bat_debuginfo bat_debuginfo_##_name = { \ - .attr = { .name = __stringify(_name), \ - .mode = _mode, }, \ - .fops = { .owner = THIS_MODULE, \ - .open = _open, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release, \ - } \ +#define BAT_DEBUGINFO(_name, _mode, _open) \ +struct bat_debuginfo batadv_debuginfo_##_name = { \ + .attr = { .name = __stringify(_name), \ + .mode = _mode, }, \ + .fops = { .owner = THIS_MODULE, \ + .open = _open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + } \ }; -static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open); -static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); -static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); -static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); +static BAT_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open); +static BAT_DEBUGINFO(originators, S_IRUGO, batadv_originators_open); +static BAT_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open); +static BAT_DEBUGINFO(transtable_global, S_IRUGO, batadv_transtable_global_open); #ifdef CONFIG_BATMAN_ADV_BLA -static BAT_DEBUGINFO(bla_claim_table, S_IRUGO, bla_claim_table_open); +static BAT_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); #endif -static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); -static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); +static BAT_DEBUGINFO(transtable_local, S_IRUGO, batadv_transtable_local_open); +static BAT_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); -static struct bat_debuginfo *mesh_debuginfos[] = { - &bat_debuginfo_originators, - &bat_debuginfo_gateways, - &bat_debuginfo_transtable_global, +static struct bat_debuginfo *batadv_mesh_debuginfos[] = { + &batadv_debuginfo_originators, + &batadv_debuginfo_gateways, + &batadv_debuginfo_transtable_global, #ifdef CONFIG_BATMAN_ADV_BLA - &bat_debuginfo_bla_claim_table, + &batadv_debuginfo_bla_claim_table, #endif - &bat_debuginfo_transtable_local, - &bat_debuginfo_vis_data, + &batadv_debuginfo_transtable_local, + &batadv_debuginfo_vis_data, NULL, }; @@ -308,17 +309,17 @@ void batadv_debugfs_init(void) struct bat_debuginfo *bat_debug; struct dentry *file; - bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); - if (bat_debugfs == ERR_PTR(-ENODEV)) - bat_debugfs = NULL; + batadv_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); + if (batadv_debugfs == ERR_PTR(-ENODEV)) + batadv_debugfs = NULL; - if (!bat_debugfs) + if (!batadv_debugfs) goto out; - bat_debug = &bat_debuginfo_routing_algos; + bat_debug = &batadv_debuginfo_routing_algos; file = debugfs_create_file(bat_debug->attr.name, S_IFREG | bat_debug->attr.mode, - bat_debugfs, NULL, &bat_debug->fops); + batadv_debugfs, NULL, &bat_debug->fops); if (!file) pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name); @@ -328,9 +329,9 @@ out: void batadv_debugfs_destroy(void) { - if (bat_debugfs) { - debugfs_remove_recursive(bat_debugfs); - bat_debugfs = NULL; + if (batadv_debugfs) { + debugfs_remove_recursive(batadv_debugfs); + batadv_debugfs = NULL; } } @@ -340,20 +341,20 @@ int batadv_debugfs_add_meshif(struct net_device *dev) struct bat_debuginfo **bat_debug; struct dentry *file; - if (!bat_debugfs) + if (!batadv_debugfs) goto out; - bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs); + bat_priv->debug_dir = debugfs_create_dir(dev->name, batadv_debugfs); if (!bat_priv->debug_dir) goto out; if (batadv_socket_setup(bat_priv) < 0) goto rem_attr; - if (debug_log_setup(bat_priv) < 0) + if (batadv_debug_log_setup(bat_priv) < 0) goto rem_attr; - for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) { + for (bat_debug = batadv_mesh_debuginfos; *bat_debug; ++bat_debug) { file = debugfs_create_file(((*bat_debug)->attr).name, S_IFREG | ((*bat_debug)->attr).mode, bat_priv->debug_dir, @@ -381,9 +382,9 @@ void batadv_debugfs_del_meshif(struct net_device *dev) { struct bat_priv *bat_priv = netdev_priv(dev); - debug_log_cleanup(bat_priv); + batadv_debug_log_cleanup(bat_priv); - if (bat_debugfs) { + if (batadv_debugfs) { debugfs_remove_recursive(bat_priv->debug_dir); bat_priv->debug_dir = NULL; } -- GitLab From 9b4a1159dff76f938aa64f7000621552e4d9ad18 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:48:53 +0200 Subject: [PATCH 2611/6849] batman-adv: Prefix bitarray static inline functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 13 +++++++------ net/batman-adv/bitarray.c | 8 ++++---- net/batman-adv/bitarray.h | 6 +++--- net/batman-adv/routing.c | 4 ++-- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 94859d45ed6e..ad641e8d3c0f 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -901,9 +901,9 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, hlist_for_each_entry_rcu(tmp_neigh_node, node, &orig_node->neigh_list, list) { - is_duplicate |= bat_test_bit(tmp_neigh_node->real_bits, - orig_node->last_real_seqno, - seqno); + is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits, + orig_node->last_real_seqno, + seqno); if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) @@ -1037,6 +1037,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, if (is_my_orig) { unsigned long *word; int offset; + int32_t bit_pos; orig_neigh_node = batadv_get_orig_node(bat_priv, ethhdr->h_source); @@ -1054,9 +1055,9 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); word = &(orig_neigh_node->bcast_own[offset]); - bat_set_bit(word, - if_incoming_seqno - - ntohl(batman_ogm_packet->seqno) - 2); + bit_pos = if_incoming_seqno - 2; + bit_pos -= ntohl(batman_ogm_packet->seqno); + batadv_set_bit(word, bit_pos); orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE); spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index 838abbc73c6c..7a7065cc88cd 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -48,7 +48,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, */ if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { if (set_mark) - bat_set_bit(seq_bits, -seq_num_diff); + batadv_set_bit(seq_bits, -seq_num_diff); return 0; } @@ -59,7 +59,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, batadv_bitmap_shift_left(seq_bits, seq_num_diff); if (set_mark) - bat_set_bit(seq_bits, 0); + batadv_set_bit(seq_bits, 0); return 1; } @@ -71,7 +71,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, seq_num_diff - 1); bitmap_zero(seq_bits, TQ_LOCAL_WINDOW_SIZE); if (set_mark) - bat_set_bit(seq_bits, 0); + batadv_set_bit(seq_bits, 0); return 1; } @@ -88,7 +88,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, bitmap_zero(seq_bits, TQ_LOCAL_WINDOW_SIZE); if (set_mark) - bat_set_bit(seq_bits, 0); + batadv_set_bit(seq_bits, 0); return 1; } diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h index 8ab542632343..7954ba81cece 100644 --- a/net/batman-adv/bitarray.h +++ b/net/batman-adv/bitarray.h @@ -23,8 +23,8 @@ /* returns true if the corresponding bit in the given seq_bits indicates true * and curr_seqno is within range of last_seqno */ -static inline int bat_test_bit(const unsigned long *seq_bits, - uint32_t last_seqno, uint32_t curr_seqno) +static inline int batadv_test_bit(const unsigned long *seq_bits, + uint32_t last_seqno, uint32_t curr_seqno) { int32_t diff; @@ -36,7 +36,7 @@ static inline int bat_test_bit(const unsigned long *seq_bits, } /* turn corresponding bit on, so we can remember that we got the packet */ -static inline void bat_set_bit(unsigned long *seq_bits, int32_t n) +static inline void batadv_set_bit(unsigned long *seq_bits, int32_t n) { /* if too old, just drop it */ if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 79f63cf11be4..9c90cceda17d 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1086,8 +1086,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) spin_lock_bh(&orig_node->bcast_seqno_lock); /* check whether the packet is a duplicate */ - if (bat_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno, - ntohl(bcast_packet->seqno))) + if (batadv_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno, + ntohl(bcast_packet->seqno))) goto spin_unlock; seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; -- GitLab From e5d89254bf763da35b42a3c65289c9962f7240c2 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:48:54 +0200 Subject: [PATCH 2612/6849] batman-adv: Prefix hard-interface static inline functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 14 ++++++------- net/batman-adv/bat_sysfs.c | 16 +++++++-------- net/batman-adv/bridge_loop_avoidance.c | 28 +++++++++++++------------- net/batman-adv/gateway_client.c | 4 ++-- net/batman-adv/hard-interface.c | 28 +++++++++++++------------- net/batman-adv/hard-interface.h | 7 ++++--- net/batman-adv/icmp_socket.c | 4 ++-- net/batman-adv/originator.c | 4 ++-- net/batman-adv/routing.c | 12 +++++------ net/batman-adv/send.c | 6 +++--- net/batman-adv/soft-interface.c | 4 ++-- net/batman-adv/translation-table.c | 28 +++++++++++++------------- net/batman-adv/unicast.c | 4 ++-- net/batman-adv/vis.c | 8 ++++---- 14 files changed, 84 insertions(+), 83 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index ad641e8d3c0f..94e6fdbdd13d 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -232,7 +232,7 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) if (forw_packet->if_incoming->if_status != IF_ACTIVE) goto out; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -273,7 +273,7 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } /* return true if new_packet can be aggregated with forw_packet */ @@ -311,7 +311,7 @@ static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet * a "global" packet as well as the base * packet */ - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -352,7 +352,7 @@ static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return res; } @@ -431,7 +431,7 @@ static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff, return; out: - hardif_free_ref(if_incoming); + batadv_hardif_free_ref(if_incoming); } /* aggregate a new packet into the existing ogm packet */ @@ -570,7 +570,7 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) int vis_server, tt_num_changes = 0; vis_server = atomic_read(&bat_priv->vis_mode); - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (hard_iface == primary_if) tt_num_changes = batadv_tt_append_diff(bat_priv, @@ -608,7 +608,7 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) bat_iv_ogm_emit_send_time(bat_priv)); if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 8196fa6ff22e..0c7e22e4d5f3 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -132,7 +132,7 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ length = __store_uint_attr(buff, count, _min, _max, _post_func, \ attr, &hard_iface->_name, net_dev); \ \ - hardif_free_ref(hard_iface); \ + batadv_hardif_free_ref(hard_iface); \ return length; \ } @@ -150,7 +150,7 @@ ssize_t show_##_name(struct kobject *kobj, \ \ length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\ \ - hardif_free_ref(hard_iface); \ + batadv_hardif_free_ref(hard_iface); \ return length; \ } @@ -535,7 +535,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, length = sprintf(buff, "%s\n", hard_iface->if_status == IF_NOT_IN_USE ? "none" : hard_iface->soft_iface->name); - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); return length; } @@ -557,7 +557,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, if (strlen(buff) >= IFNAMSIZ) { pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n", buff); - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); return -EINVAL; } @@ -592,7 +592,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, unlock: rtnl_unlock(); out: - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); return ret; } @@ -625,7 +625,7 @@ static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, break; } - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); return length; } @@ -688,7 +688,7 @@ int batadv_throw_uevent(struct bat_priv *bat_priv, enum uev_type type, struct kobject *bat_kobj; char *uevent_env[4] = { NULL, NULL, NULL, NULL }; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -727,7 +727,7 @@ out: kfree(uevent_env[2]); if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (ret) bat_dbg(DBG_BATMAN, bat_priv, diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 52c0d637d581..72ff8b90e222 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -255,7 +255,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, struct bla_claim_dst local_claim_dest; __be32 zeroip = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) return; @@ -339,7 +339,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, netif_rx(skb); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } /* @bat_priv: the bat priv with all the soft interface information @@ -1075,7 +1075,7 @@ static void bla_periodic_work(struct work_struct *work) struct hard_iface *primary_if; int i; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1106,7 +1106,7 @@ static void bla_periodic_work(struct work_struct *work) } out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); bla_start_timer(bat_priv); } @@ -1131,12 +1131,12 @@ int batadv_bla_init(struct bat_priv *bat_priv) /* setting claim destination address */ memcpy(&bat_priv->claim_dest.magic, claim_dest, 3); bat_priv->claim_dest.type = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (primary_if) { bat_priv->claim_dest.group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } else { bat_priv->claim_dest.group = 0; /* will be set later */ } @@ -1319,7 +1319,7 @@ void batadv_bla_free(struct bat_priv *bat_priv) struct hard_iface *primary_if; cancel_delayed_work_sync(&bat_priv->bla_work); - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (bat_priv->claim_hash) { bla_purge_claims(bat_priv, primary_if, 1); @@ -1332,7 +1332,7 @@ void batadv_bla_free(struct bat_priv *bat_priv) bat_priv->backbone_hash = NULL; } if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } /* @bat_priv: the bat priv with all the soft interface information @@ -1356,7 +1356,7 @@ int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) ethhdr = (struct ethhdr *)skb_mac_header(skb); - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto handled; @@ -1416,7 +1416,7 @@ handled: out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (claim) claim_free_ref(claim); return ret; @@ -1441,7 +1441,7 @@ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) struct hard_iface *primary_if; int ret = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1502,7 +1502,7 @@ handled: ret = 1; out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (claim) claim_free_ref(claim); return ret; @@ -1521,7 +1521,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) bool is_own; int ret = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { ret = seq_printf(seq, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -1559,6 +1559,6 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) } out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 0d90fffd9efb..c917a2ee1f39 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -464,7 +464,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) struct hlist_node *node; int gw_count = 0, ret = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { ret = seq_printf(seq, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -503,7 +503,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 2a4d394771b8..06f8d63d741d 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -102,7 +102,7 @@ static void primary_if_update_addr(struct bat_priv *bat_priv, struct vis_packet *vis_packet; struct hard_iface *primary_if; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -115,7 +115,7 @@ static void primary_if_update_addr(struct bat_priv *bat_priv, batadv_bla_update_orig_address(bat_priv, primary_if, oldif); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } static void primary_if_select(struct bat_priv *bat_priv, @@ -139,7 +139,7 @@ static void primary_if_select(struct bat_priv *bat_priv, out: if (curr_hard_iface) - hardif_free_ref(curr_hard_iface); + batadv_hardif_free_ref(curr_hard_iface); } static bool hardif_is_iface_up(const struct hard_iface *hard_iface) @@ -229,7 +229,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) /* the first active interface becomes our primary interface or * the next active interface after the old primary interface was removed */ - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) primary_if_select(bat_priv, hard_iface); @@ -240,7 +240,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } static void hardif_deactivate_interface(struct hard_iface *hard_iface) @@ -347,7 +347,7 @@ out: err_dev: dev_put(soft_iface); err: - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); return ret; } @@ -369,7 +369,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) bat_priv->num_ifaces--; batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces); - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (hard_iface == primary_if) { struct hard_iface *new_if; @@ -377,7 +377,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) primary_if_select(bat_priv, new_if); if (new_if) - hardif_free_ref(new_if); + batadv_hardif_free_ref(new_if); } bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); @@ -393,11 +393,11 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) batadv_softif_destroy(hard_iface->soft_iface); hard_iface->soft_iface = NULL; - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } static struct hard_iface *hardif_add_interface(struct net_device *net_dev) @@ -461,7 +461,7 @@ static void hardif_remove_interface(struct hard_iface *hard_iface) hard_iface->if_status = IF_TO_BE_REMOVED; batadv_sysfs_del_hardif(&hard_iface->hardif_obj); - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); } void batadv_hardif_remove_interfaces(void) @@ -517,7 +517,7 @@ static int hard_if_event(struct notifier_block *this, bat_priv = netdev_priv(hard_iface->soft_iface); bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto hardif_put; @@ -529,10 +529,10 @@ static int hard_if_event(struct notifier_block *this, } hardif_put: - hardif_free_ref(hard_iface); + batadv_hardif_free_ref(hard_iface); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return NOTIFY_DONE; } diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 6bc12c0eb2f0..d66dabd620b7 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -42,14 +42,15 @@ void batadv_update_min_mtu(struct net_device *soft_iface); void batadv_hardif_free_rcu(struct rcu_head *rcu); bool batadv_is_wifi_iface(int ifindex); -static inline void hardif_free_ref(struct hard_iface *hard_iface) +static inline void +batadv_hardif_free_ref(struct hard_iface *hard_iface) { if (atomic_dec_and_test(&hard_iface->refcount)) call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu); } -static inline struct hard_iface *primary_if_get_selected( - struct bat_priv *bat_priv) +static inline struct hard_iface * +batadv_primary_if_get_selected(struct bat_priv *bat_priv) { struct hard_iface *hard_iface; diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 40c5e189e6fd..2523436907e6 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -163,7 +163,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, return -EINVAL; } - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { len = -EFAULT; @@ -244,7 +244,7 @@ free_skb: kfree_skb(skb); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (neigh_node) batadv_neigh_node_free_ref(neigh_node); if (orig_node) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 86e7e082c2bc..90d24fccb9cf 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -412,7 +412,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) uint32_t i; int ret = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { ret = seq_printf(seq, @@ -479,7 +479,7 @@ next: out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 9c90cceda17d..9c6edc23bfc4 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -292,7 +292,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, goto out; } - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -322,7 +322,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (router) batadv_neigh_node_free_ref(router); if (orig_node) @@ -348,7 +348,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, goto out; } - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -377,7 +377,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (router) batadv_neigh_node_free_ref(router); if (orig_node) @@ -955,12 +955,12 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, if (!orig_node) { if (!batadv_is_my_client(bat_priv, ethhdr->h_dest)) return 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) return 0; memcpy(unicast_packet->dest, primary_if->net_dev->dev_addr, ETH_ALEN); - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } else { memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 2c92a32ec6c6..54091db9d5ff 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -101,7 +101,7 @@ static void forw_packet_free(struct forw_packet *forw_packet) if (forw_packet->skb) kfree_skb(forw_packet->skb); if (forw_packet->if_incoming) - hardif_free_ref(forw_packet->if_incoming); + batadv_hardif_free_ref(forw_packet->if_incoming); kfree(forw_packet); } @@ -146,7 +146,7 @@ int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, goto out; } - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out_and_inc; @@ -180,7 +180,7 @@ out_and_inc: atomic_inc(&bat_priv->bcast_queue_left); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return NETDEV_TX_BUSY; } diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 0658781febde..85fe9c1ce5bc 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -199,7 +199,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) /* ethernet packet should be broadcasted */ if (do_bcast) { - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto dropped; @@ -253,7 +253,7 @@ dropped_freed: bat_priv->stats.tx_dropped++; end: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return NETDEV_TX_OK; } diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 5180d50e909d..bc06af4781b3 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -298,7 +298,7 @@ static void tt_prepare_packet_buff(struct bat_priv *bat_priv, struct hard_iface *primary_if; int req_len; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); req_len = min_packet_len; req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes)); @@ -313,7 +313,7 @@ static void tt_prepare_packet_buff(struct bat_priv *bat_priv, min_packet_len, req_len); if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } static int tt_changes_fill_buff(struct bat_priv *bat_priv, @@ -381,7 +381,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) uint32_t i; int ret = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { ret = seq_printf(seq, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -423,7 +423,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) } out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } @@ -727,7 +727,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) uint32_t i; int ret = 0; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { ret = seq_printf(seq, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -763,7 +763,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) } out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } @@ -1370,7 +1370,7 @@ static int send_tt_request(struct bat_priv *bat_priv, struct tt_req_node *tt_req_node = NULL; int ret = 1; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1420,7 +1420,7 @@ out: if (neigh_node) batadv_neigh_node_free_ref(neigh_node); if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (ret) kfree_skb(skb); if (ret && tt_req_node) { @@ -1464,7 +1464,7 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, if (!neigh_node) goto out; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1555,7 +1555,7 @@ out: if (neigh_node) batadv_neigh_node_free_ref(neigh_node); if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (!ret) kfree_skb(skb); return ret; @@ -1592,7 +1592,7 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, if (!neigh_node) goto out; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1672,7 +1672,7 @@ out: if (neigh_node) batadv_neigh_node_free_ref(neigh_node); if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); if (!ret) kfree_skb(skb); /* This packet was for me, so it doesn't need to be re-routed */ @@ -1956,11 +1956,11 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, roam_adv_packet->header.packet_type = BAT_ROAM_ADV; roam_adv_packet->header.version = COMPAT_VERSION; roam_adv_packet->header.ttl = TTL; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN); memcpy(roam_adv_packet->client, client, ETH_ALEN); diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index b2b76df69607..fff34e05a5d9 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -227,7 +227,7 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, int large_tail = 0, ret = NET_RX_DROP; uint16_t seqno; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto dropped; @@ -277,7 +277,7 @@ dropped: kfree_skb(skb); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 20eef04645bd..619f0a5a8484 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -208,7 +208,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) size_t buff_pos, buf_size; char *buff; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -329,7 +329,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } @@ -828,7 +828,7 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) struct hard_iface *primary_if; struct vis_packet *packet; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -849,7 +849,7 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); } /* called from timer; send (and maybe generate) vis packet. */ -- GitLab From c0a559295eb2601602f7dc88f4240afcd666f73a Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:48:55 +0200 Subject: [PATCH 2613/6849] batman-adv: Prefix hash static inline functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 13 ++++++++----- net/batman-adv/hash.h | 19 ++++++++++--------- net/batman-adv/originator.c | 5 +++-- net/batman-adv/translation-table.c | 24 +++++++++++++----------- net/batman-adv/vis.c | 16 ++++++++-------- 5 files changed, 42 insertions(+), 35 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 72ff8b90e222..7a2dfd41d5c8 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -379,8 +379,9 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, /* one for the hash, one for returning */ atomic_set(&entry->refcount, 2); - hash_added = hash_add(bat_priv->backbone_hash, compare_backbone_gw, - choose_backbone_gw, entry, &entry->hash_entry); + hash_added = batadv_hash_add(bat_priv->backbone_hash, + compare_backbone_gw, choose_backbone_gw, + entry, &entry->hash_entry); if (unlikely(hash_added != 0)) { /* hash failed, free the structure */ @@ -540,8 +541,9 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, bat_dbg(DBG_BLA, bat_priv, "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", mac, vid); - hash_added = hash_add(bat_priv->claim_hash, compare_claim, - choose_claim, claim, &claim->hash_entry); + hash_added = batadv_hash_add(bat_priv->claim_hash, + compare_claim, choose_claim, + claim, &claim->hash_entry); if (unlikely(hash_added != 0)) { /* only local changes happened. */ @@ -590,7 +592,8 @@ static void bla_del_claim(struct bat_priv *bat_priv, const uint8_t *mac, bat_dbg(DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid); - hash_remove(bat_priv->claim_hash, compare_claim, choose_claim, claim); + batadv_hash_remove(bat_priv->claim_hash, compare_claim, choose_claim, + claim); claim_free_ref(claim); /* reference from the hash is gone */ claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index eba8f2a55ccc..7ec4e5b0bd41 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h @@ -54,8 +54,8 @@ void batadv_hash_destroy(struct hashtable_t *hash); * called to remove the elements inside of the hash. if you don't remove the * elements, memory might be leaked. */ -static inline void hash_delete(struct hashtable_t *hash, - hashdata_free_cb free_cb, void *arg) +static inline void batadv_hash_delete(struct hashtable_t *hash, + hashdata_free_cb free_cb, void *arg) { struct hlist_head *head; struct hlist_node *node, *node_tmp; @@ -89,10 +89,11 @@ static inline void hash_delete(struct hashtable_t *hash, * Returns 0 on success, 1 if the element already is in the hash * and -1 on error. */ -static inline int hash_add(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, - const void *data, struct hlist_node *data_node) +static inline int batadv_hash_add(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, + const void *data, + struct hlist_node *data_node) { uint32_t index; int ret = -1; @@ -133,9 +134,9 @@ out: * structure you use with just the key filled, we just need the key for * comparing. */ -static inline void *hash_remove(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data) +static inline void *batadv_hash_remove(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data) { uint32_t index; struct hlist_node *node; diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 90d24fccb9cf..623c23c6ec36 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -248,8 +248,9 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, if (!orig_node->bcast_own_sum) goto free_bcast_own; - hash_added = hash_add(bat_priv->orig_hash, compare_orig, - choose_orig, orig_node, &orig_node->hash_entry); + hash_added = batadv_hash_add(bat_priv->orig_hash, compare_orig, + choose_orig, orig_node, + &orig_node->hash_entry); if (hash_added != 0) goto free_bcast_own_sum; diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index bc06af4781b3..72a8548515ae 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -234,9 +234,9 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, */ tt_local_entry->common.flags |= TT_CLIENT_NEW; - hash_added = hash_add(bat_priv->tt_local_hash, compare_tt, choose_orig, - &tt_local_entry->common, - &tt_local_entry->common.hash_entry); + hash_added = batadv_hash_add(bat_priv->tt_local_hash, compare_tt, + choose_orig, &tt_local_entry->common, + &tt_local_entry->common.hash_entry); if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ @@ -618,6 +618,7 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, struct tt_global_entry *tt_global_entry = NULL; int ret = 0; int hash_added; + struct tt_common_entry *common; tt_global_entry = tt_global_hash_find(bat_priv, tt_addr); @@ -627,18 +628,19 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, if (!tt_global_entry) goto out; - memcpy(tt_global_entry->common.addr, tt_addr, ETH_ALEN); + common = &tt_global_entry->common; + memcpy(common->addr, tt_addr, ETH_ALEN); - tt_global_entry->common.flags = NO_FLAGS; + common->flags = NO_FLAGS; tt_global_entry->roam_at = 0; - atomic_set(&tt_global_entry->common.refcount, 2); + atomic_set(&common->refcount, 2); INIT_HLIST_HEAD(&tt_global_entry->orig_list); spin_lock_init(&tt_global_entry->list_lock); - hash_added = hash_add(bat_priv->tt_global_hash, compare_tt, - choose_orig, &tt_global_entry->common, - &tt_global_entry->common.hash_entry); + hash_added = batadv_hash_add(bat_priv->tt_global_hash, + compare_tt, choose_orig, + common, &common->hash_entry); if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ @@ -816,8 +818,8 @@ static void tt_global_del_struct(struct bat_priv *bat_priv, "Deleting global tt entry %pM: %s\n", tt_global_entry->common.addr, message); - hash_remove(bat_priv->tt_global_hash, compare_tt, choose_orig, - tt_global_entry->common.addr); + batadv_hash_remove(bat_priv->tt_global_hash, compare_tt, choose_orig, + tt_global_entry->common.addr); tt_global_entry_free_ref(tt_global_entry); } diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 619f0a5a8484..e0a90570d667 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -433,8 +433,8 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, } } /* remove old entry */ - hash_remove(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - old_info); + batadv_hash_remove(bat_priv->vis_hash, vis_info_cmp, + vis_info_choose, old_info); send_list_del(old_info); kref_put(&old_info->refcount, free_info); } @@ -474,8 +474,8 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); /* try to add it */ - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - info, &info->hash_entry); + hash_added = batadv_hash_add(bat_priv->vis_hash, vis_info_cmp, + vis_info_choose, info, &info->hash_entry); if (hash_added != 0) { /* did not work (for some reason) */ kref_put(&info->refcount, free_info); @@ -934,9 +934,9 @@ int batadv_vis_init(struct bat_priv *bat_priv) INIT_LIST_HEAD(&bat_priv->vis_send_list); - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - bat_priv->my_vis_info, - &bat_priv->my_vis_info->hash_entry); + hash_added = batadv_hash_add(bat_priv->vis_hash, vis_info_cmp, + vis_info_choose, bat_priv->my_vis_info, + &bat_priv->my_vis_info->hash_entry); if (hash_added != 0) { pr_err("Can't add own vis packet into hash\n"); /* not in hash, need to remove it manually. */ @@ -977,7 +977,7 @@ void batadv_vis_quit(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->vis_hash_lock); /* properly remove, kill timers ... */ - hash_delete(bat_priv->vis_hash, free_info_ref, NULL); + batadv_hash_delete(bat_priv->vis_hash, free_info_ref, NULL); bat_priv->vis_hash = NULL; bat_priv->my_vis_info = NULL; spin_unlock_bh(&bat_priv->vis_hash_lock); -- GitLab From da641193dd3117ccd408dc589a131f16286b0da0 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:48:56 +0200 Subject: [PATCH 2614/6849] batman-adv: Prefix originator static inline functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 4 ++-- net/batman-adv/icmp_socket.c | 2 +- net/batman-adv/originator.c | 4 ++-- net/batman-adv/originator.h | 8 ++++---- net/batman-adv/routing.c | 26 +++++++++++++++----------- net/batman-adv/translation-table.c | 21 +++++++++++---------- net/batman-adv/unicast.c | 2 +- net/batman-adv/vis.c | 2 +- 8 files changed, 37 insertions(+), 32 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 7a2dfd41d5c8..1d143d5bb53e 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -390,7 +390,7 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, } /* this is a gateway now, remove any tt entries */ - orig_node = orig_hash_find(bat_priv, orig); + orig_node = batadv_orig_hash_find(bat_priv, orig); if (orig_node) { batadv_tt_global_del_orig(bat_priv, orig_node, "became a backbone gateway"); @@ -780,7 +780,7 @@ static int check_claim_group(struct bat_priv *bat_priv, return 2; /* lets see if this originator is in our mesh */ - orig_node = orig_hash_find(bat_priv, backbone_addr); + orig_node = batadv_orig_hash_find(bat_priv, backbone_addr); /* dont accept claims from gateways which are not in * the same mesh or group. diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 2523436907e6..50a74dadb4d6 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -213,7 +213,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) goto dst_unreach; - orig_node = orig_hash_find(bat_priv, icmp_packet->dst); + orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); if (!orig_node) goto dst_unreach; diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 623c23c6ec36..36f5ee5cd195 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -195,7 +195,7 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, int size; int hash_added; - orig_node = orig_hash_find(bat_priv, addr); + orig_node = batadv_orig_hash_find(bat_priv, addr); if (orig_node) return orig_node; @@ -249,7 +249,7 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, goto free_bcast_own; hash_added = batadv_hash_add(bat_priv->orig_hash, compare_orig, - choose_orig, orig_node, + batadv_choose_orig, orig_node, &orig_node->hash_entry); if (hash_added != 0) goto free_bcast_own_sum; diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index a72171997056..c4f63b4d54a7 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -41,7 +41,7 @@ int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); /* hashfunction to choose an entry in a hash table of given size * hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -static inline uint32_t choose_orig(const void *data, uint32_t size) +static inline uint32_t batadv_choose_orig(const void *data, uint32_t size) { const unsigned char *key = data; uint32_t hash = 0; @@ -60,8 +60,8 @@ static inline uint32_t choose_orig(const void *data, uint32_t size) return hash % size; } -static inline struct orig_node *orig_hash_find(struct bat_priv *bat_priv, - const void *data) +static inline struct orig_node *batadv_orig_hash_find(struct bat_priv *bat_priv, + const void *data) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_head *head; @@ -72,7 +72,7 @@ static inline struct orig_node *orig_hash_find(struct bat_priv *bat_priv, if (!hash) return NULL; - index = choose_orig(data, hash->size); + index = batadv_choose_orig(data, hash->size); head = &hash->table[index]; rcu_read_lock(); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 9c6edc23bfc4..0888f1e39fdc 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -298,7 +298,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, /* answer echo request (ping) */ /* get routing information */ - orig_node = orig_hash_find(bat_priv, icmp_packet->orig); + orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); if (!orig_node) goto out; @@ -353,7 +353,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, goto out; /* get routing information */ - orig_node = orig_hash_find(bat_priv, icmp_packet->orig); + orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); if (!orig_node) goto out; @@ -437,7 +437,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) return recv_icmp_ttl_exceeded(bat_priv, skb); /* get routing information */ - orig_node = orig_hash_find(bat_priv, icmp_packet->dst); + orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); if (!orig_node) goto out; @@ -684,7 +684,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) if (batadv_bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src)) goto out; - orig_node = orig_hash_find(bat_priv, roam_adv_packet->src); + orig_node = batadv_orig_hash_find(bat_priv, roam_adv_packet->src); if (!orig_node) goto out; @@ -721,6 +721,7 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, struct neigh_node *router; static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; int bonding_enabled; + uint8_t *primary_addr; if (!orig_node) return NULL; @@ -743,20 +744,22 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, if ((!recv_if) && (!bonding_enabled)) goto return_router; + primary_addr = router_orig->primary_addr; + /* if we have something in the primary_addr, we can search * for a potential bonding candidate. */ - if (compare_eth(router_orig->primary_addr, zero_mac)) + if (compare_eth(primary_addr, zero_mac)) goto return_router; /* find the orig_node which has the primary interface. might * even be the same as our router_orig in many cases */ - if (compare_eth(router_orig->primary_addr, router_orig->orig)) { + if (compare_eth(primary_addr, router_orig->orig)) { primary_orig_node = router_orig; } else { - primary_orig_node = orig_hash_find(bat_priv, - router_orig->primary_addr); + primary_orig_node = batadv_orig_hash_find(bat_priv, + primary_addr); if (!primary_orig_node) goto return_router; @@ -839,7 +842,7 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) } /* get routing information */ - orig_node = orig_hash_find(bat_priv, unicast_packet->dest); + orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest); if (!orig_node) goto out; @@ -922,7 +925,8 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, tt_poss_change = bat_priv->tt_poss_change; curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); } else { - orig_node = orig_hash_find(bat_priv, unicast_packet->dest); + orig_node = batadv_orig_hash_find(bat_priv, + unicast_packet->dest); if (!orig_node) return 0; @@ -1078,7 +1082,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if) if (bcast_packet->header.ttl < 2) goto out; - orig_node = orig_hash_find(bat_priv, bcast_packet->orig); + orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig); if (!orig_node) goto out; diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 72a8548515ae..1dfa2311bb1b 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -61,7 +61,7 @@ static struct tt_common_entry *tt_hash_find(struct hashtable_t *hash, if (!hash) return NULL; - index = choose_orig(data, hash->size); + index = batadv_choose_orig(data, hash->size); head = &hash->table[index]; rcu_read_lock(); @@ -235,7 +235,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, tt_local_entry->common.flags |= TT_CLIENT_NEW; hash_added = batadv_hash_add(bat_priv->tt_local_hash, compare_tt, - choose_orig, &tt_local_entry->common, + batadv_choose_orig, + &tt_local_entry->common, &tt_local_entry->common.hash_entry); if (unlikely(hash_added != 0)) { @@ -639,7 +640,7 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, spin_lock_init(&tt_global_entry->list_lock); hash_added = batadv_hash_add(bat_priv->tt_global_hash, - compare_tt, choose_orig, + compare_tt, batadv_choose_orig, common, &common->hash_entry); if (unlikely(hash_added != 0)) { @@ -818,8 +819,8 @@ static void tt_global_del_struct(struct bat_priv *bat_priv, "Deleting global tt entry %pM: %s\n", tt_global_entry->common.addr, message); - batadv_hash_remove(bat_priv->tt_global_hash, compare_tt, choose_orig, - tt_global_entry->common.addr); + batadv_hash_remove(bat_priv->tt_global_hash, compare_tt, + batadv_choose_orig, tt_global_entry->common.addr); tt_global_entry_free_ref(tt_global_entry); } @@ -1454,11 +1455,11 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); /* Let's get the orig node of the REAL destination */ - req_dst_orig_node = orig_hash_find(bat_priv, tt_request->dst); + req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst); if (!req_dst_orig_node) goto out; - res_dst_orig_node = orig_hash_find(bat_priv, tt_request->src); + res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); if (!res_dst_orig_node) goto out; @@ -1586,7 +1587,7 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); req_ttvn = tt_request->ttvn; - orig_node = orig_hash_find(bat_priv, tt_request->src); + orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); if (!orig_node) goto out; @@ -1731,7 +1732,7 @@ static void tt_fill_gtable(struct bat_priv *bat_priv, { struct orig_node *orig_node = NULL; - orig_node = orig_hash_find(bat_priv, tt_response->src); + orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); if (!orig_node) goto out; @@ -1804,7 +1805,7 @@ void batadv_handle_tt_response(struct bat_priv *bat_priv, if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src)) goto out; - orig_node = orig_hash_find(bat_priv, tt_response->src); + orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); if (!orig_node) goto out; diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index fff34e05a5d9..d021055ad262 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -181,7 +181,7 @@ int batadv_frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, *new_skb = NULL; - orig_node = orig_hash_find(bat_priv, unicast_packet->orig); + orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->orig); if (!orig_node) goto out; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index e0a90570d667..bf72c5248662 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -803,7 +803,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, packet = (struct vis_packet *)info->skb_packet->data; - orig_node = orig_hash_find(bat_priv, packet->target_orig); + orig_node = batadv_orig_hash_find(bat_priv, packet->target_orig); if (!orig_node) goto out; -- GitLab From f0530ee5fb9e73465ac844ada2c96a2bea85a18f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:48:57 +0200 Subject: [PATCH 2615/6849] batman-adv: Prefix unicast static inline functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/routing.c | 3 ++- net/batman-adv/unicast.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 0888f1e39fdc..3eb4a2e121a6 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -869,7 +869,8 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) } if (unicast_packet->header.packet_type == BAT_UNICAST_FRAG && - frag_can_reassemble(skb, neigh_node->if_incoming->net_dev->mtu)) { + batadv_frag_can_reassemble(skb, + neigh_node->if_incoming->net_dev->mtu)) { ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h index 87f8f89d1440..9257b83534fd 100644 --- a/net/batman-adv/unicast.h +++ b/net/batman-adv/unicast.h @@ -33,7 +33,7 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, struct hard_iface *hard_iface, const uint8_t dstaddr[]); -static inline int frag_can_reassemble(const struct sk_buff *skb, int mtu) +static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu) { const struct unicast_frag_packet *unicast_packet; int uneven_correction = 0; -- GitLab From 02b7d83436ae4b1d86a5df03e72c1c69af7e239d Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Sat, 23 Jun 2012 15:54:34 -0700 Subject: [PATCH 2616/6849] Fix typo in printed messages Coult -> Could Signed-off-by: Linus Torvalds --- arch/sparc/kernel/vio.c | 2 +- drivers/net/wireless/b43/main.c | 2 +- drivers/net/wireless/b43legacy/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 5cffdc55f075..3e244f31e56b 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -443,7 +443,7 @@ static int __init vio_init(void) root_vdev = vio_create_one(hp, root, NULL); err = -ENODEV; if (!root_vdev) { - printk(KERN_ERR "VIO: Coult not create root device.\n"); + printk(KERN_ERR "VIO: Could not create root device.\n"); goto out_release; } diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index acd03a4f9730..1b988f26bdf1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3767,7 +3767,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) if (prev_status >= B43_STAT_STARTED) { err = b43_wireless_core_start(up_dev); if (err) { - b43err(wl, "Fatal: Coult not start device for " + b43err(wl, "Fatal: Could not start device for " "selected %s-GHz band\n", band_to_string(chan->band)); b43_wireless_core_exit(up_dev); diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index cd9c9bc186d9..eae691e2f7dd 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2633,7 +2633,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, if (prev_status >= B43legacy_STAT_STARTED) { err = b43legacy_wireless_core_start(up_dev); if (err) { - b43legacyerr(wl, "Fatal: Coult not start device for " + b43legacyerr(wl, "Fatal: Could not start device for " "newly selected %s-PHY mode\n", phymode_to_string(new_mode)); b43legacy_wireless_core_exit(up_dev); -- GitLab From 6b16351acbd415e66ba16bf7d473ece1574cf0bc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 24 Jun 2012 12:53:04 -0700 Subject: [PATCH 2617/6849] Linux 3.5-rc4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 462a0b4794b6..3fdfde2c1b7d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Saber-toothed Squirrel # *DOCUMENTATION* -- GitLab From 1f758b23177d588a71b96ad02990e715949bb82f Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Sun, 24 Jun 2012 23:31:09 +0200 Subject: [PATCH 2618/6849] PM / Sleep: Prevent waiting forever on asynchronous suspend after abort __device_suspend() must always send a completion. Otherwise, parent devices will wait forever. Commit 1e2ef05b, "PM: Limit race conditions between runtime PM and system sleep (v2)", introduced a regression by short-circuiting the complete_all() for certain error cases. This patch fixes the bug by always signalling a completion. Addresses http://crosbug.com/31972 Tested by injecting an abort. Signed-off-by: Mandeep Singh Baines Cc: stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e0fb5b0435a3..9cb845e49334 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1031,7 +1031,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dpm_wait_for_children(dev, async); if (async_error) - return 0; + goto Complete; pm_runtime_get_noresume(dev); if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) @@ -1040,7 +1040,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (pm_wakeup_pending()) { pm_runtime_put_sync(dev); async_error = -EBUSY; - return 0; + goto Complete; } device_lock(dev); @@ -1097,6 +1097,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } device_unlock(dev); + + Complete: complete_all(&dev->power.completion); if (error) { -- GitLab From 19a1d332cc8ca599578111b9ff8cd6963f75c387 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 12 Jun 2012 13:27:31 +1000 Subject: [PATCH 2619/6849] m68knommu: define a local devm_clk_get() function Commit f4d40de39a23f0c39cca55ac63e1175c69c3d2f7 ("net fec: do not depend on grouped clocks") breaks compilation of the FEC driver for non iMX platforms in linux-3.5-rc1. For example when compiling for ColdFire I get: LD vmlinux drivers/built-in.o: In function `fec_probe': fec.c:(.devinit.text+0x1e0): undefined reference to `devm_clk_get' Define a simple devm_clk_get() function for the m68knommu architecture. Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/clk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/m68k/platform/coldfire/clk.c b/arch/m68k/platform/coldfire/clk.c index 9f1260c5e2ad..44da406897e5 100644 --- a/arch/m68k/platform/coldfire/clk.c +++ b/arch/m68k/platform/coldfire/clk.c @@ -42,4 +42,11 @@ unsigned long clk_get_rate(struct clk *clk) return MCF_CLK; } EXPORT_SYMBOL(clk_get_rate); + +struct clk *devm_clk_get(struct device *dev, const char *id) +{ + return NULL; +} +EXPORT_SYMBOL(devm_clk_get); + /***************************************************************************/ -- GitLab From 1eda58bfc56c43e73a0cf2bfb6e4d620ab866109 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 13:48:58 +0200 Subject: [PATCH 2620/6849] batman-adv: Prefix main static inline functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 206 +++++++++++++------------ net/batman-adv/bat_sysfs.c | 8 +- net/batman-adv/bitarray.c | 10 +- net/batman-adv/bridge_loop_avoidance.c | 165 ++++++++++---------- net/batman-adv/gateway_client.c | 54 +++---- net/batman-adv/hard-interface.c | 4 +- net/batman-adv/icmp_socket.c | 12 +- net/batman-adv/main.c | 8 +- net/batman-adv/main.h | 17 +- net/batman-adv/originator.c | 65 ++++---- net/batman-adv/originator.h | 2 +- net/batman-adv/routing.c | 68 ++++---- net/batman-adv/send.c | 12 +- net/batman-adv/soft-interface.c | 2 +- net/batman-adv/translation-table.c | 149 +++++++++--------- net/batman-adv/vis.c | 27 ++-- 16 files changed, 414 insertions(+), 395 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 94e6fdbdd13d..025df7c9a2d9 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -179,16 +179,16 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? "Sending own" : "Forwarding")); - bat_dbg(DBG_BATMAN, bat_priv, - "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", - fwd_str, (packet_num > 0 ? "aggregated " : ""), - batman_ogm_packet->orig, - ntohl(batman_ogm_packet->seqno), - batman_ogm_packet->tq, batman_ogm_packet->header.ttl, - (batman_ogm_packet->flags & DIRECTLINK ? - "on" : "off"), - batman_ogm_packet->ttvn, hard_iface->net_dev->name, - hard_iface->net_dev->dev_addr); + batadv_dbg(DBG_BATMAN, bat_priv, + "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", + fwd_str, (packet_num > 0 ? "aggregated " : ""), + batman_ogm_packet->orig, + ntohl(batman_ogm_packet->seqno), + batman_ogm_packet->tq, batman_ogm_packet->header.ttl, + (batman_ogm_packet->flags & DIRECTLINK ? + "on" : "off"), + batman_ogm_packet->ttvn, hard_iface->net_dev->name, + hard_iface->net_dev->dev_addr); buff_pos += BATMAN_OGM_HLEN; buff_pos += batadv_tt_len(batman_ogm_packet->tt_num_changes); @@ -243,14 +243,14 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) (forw_packet->own && (forw_packet->if_incoming != primary_if))) { /* FIXME: what about aggregated packets ? */ - bat_dbg(DBG_BATMAN, bat_priv, - "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n", - (forw_packet->own ? "Sending own" : "Forwarding"), - batman_ogm_packet->orig, - ntohl(batman_ogm_packet->seqno), - batman_ogm_packet->header.ttl, - forw_packet->if_incoming->net_dev->name, - forw_packet->if_incoming->net_dev->dev_addr); + batadv_dbg(DBG_BATMAN, bat_priv, + "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n", + (forw_packet->own ? "Sending own" : "Forwarding"), + batman_ogm_packet->orig, + ntohl(batman_ogm_packet->seqno), + batman_ogm_packet->header.ttl, + forw_packet->if_incoming->net_dev->name, + forw_packet->if_incoming->net_dev->dev_addr); /* skb is only used once and than forw_packet is free'd */ batadv_send_skb_packet(forw_packet->skb, @@ -373,8 +373,8 @@ static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff, /* own packet should always be scheduled */ if (!own_packet) { if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { - bat_dbg(DBG_BATMAN, bat_priv, - "batman packet queue full\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "batman packet queue full\n"); goto out; } } @@ -521,7 +521,7 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, uint8_t tt_num_changes; if (batman_ogm_packet->header.ttl <= 1) { - bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); + batadv_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); return; } @@ -546,9 +546,9 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, /* apply hop penalty */ batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); - bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: tq: %i, ttl: %i\n", - batman_ogm_packet->tq, batman_ogm_packet->header.ttl); + batadv_dbg(DBG_BATMAN, bat_priv, + "Forwarding packet: tq: %i, ttl: %i\n", + batman_ogm_packet->tq, batman_ogm_packet->header.ttl); /* switch of primaries first hop flag when forwarding */ batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; @@ -625,16 +625,18 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, struct orig_node *orig_node_tmp; struct hlist_node *node; uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; + uint8_t *neigh_addr; - bat_dbg(DBG_BATMAN, bat_priv, - "update_originator(): Searching and updating originator entry of received packet\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "update_originator(): Searching and updating originator entry of received packet\n"); rcu_read_lock(); hlist_for_each_entry_rcu(tmp_neigh_node, node, &orig_node->neigh_list, list) { - if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && - (tmp_neigh_node->if_incoming == if_incoming) && - atomic_inc_not_zero(&tmp_neigh_node->refcount)) { + neigh_addr = tmp_neigh_node->addr; + if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && + tmp_neigh_node->if_incoming == if_incoming && + atomic_inc_not_zero(&tmp_neigh_node->refcount)) { if (neigh_node) batadv_neigh_node_free_ref(neigh_node); neigh_node = tmp_neigh_node; @@ -667,8 +669,8 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, if (!neigh_node) goto unlock; } else - bat_dbg(DBG_BATMAN, bat_priv, - "Updating existing last-hop neighbor of originator\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Updating existing last-hop neighbor of originator\n"); rcu_read_unlock(); @@ -774,7 +776,8 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, hlist_for_each_entry_rcu(tmp_neigh_node, node, &orig_neigh_node->neigh_list, list) { - if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig)) + if (!batadv_compare_eth(tmp_neigh_node->addr, + orig_neigh_node->orig)) continue; if (tmp_neigh_node->if_incoming != if_incoming) @@ -844,10 +847,11 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, * tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE)); - bat_dbg(DBG_BATMAN, bat_priv, - "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", - orig_node->orig, orig_neigh_node->orig, total_count, - neigh_rq_count, tq_own, tq_asym_penalty, batman_ogm_packet->tq); + batadv_dbg(DBG_BATMAN, bat_priv, + "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", + orig_node->orig, orig_neigh_node->orig, total_count, + neigh_rq_count, tq_own, + tq_asym_penalty, batman_ogm_packet->tq); /* if link has the minimum required transmission quality * consider it bidirectional @@ -883,6 +887,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, int need_update = 0; int set_mark, ret = -1; uint32_t seqno = ntohl(batman_ogm_packet->seqno); + uint8_t *neigh_addr; orig_node = batadv_get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) @@ -905,8 +910,9 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, orig_node->last_real_seqno, seqno); - if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) && - (tmp_neigh_node->if_incoming == if_incoming)) + neigh_addr = tmp_neigh_node->addr; + if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && + tmp_neigh_node->if_incoming == if_incoming) set_mark = 1; else set_mark = 0; @@ -923,9 +929,9 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, rcu_read_unlock(); if (need_update) { - bat_dbg(DBG_BATMAN, bat_priv, - "updating last_seqno: old %u, new %u\n", - orig_node->last_real_seqno, seqno); + batadv_dbg(DBG_BATMAN, bat_priv, + "updating last_seqno: old %u, new %u\n", + orig_node->last_real_seqno, seqno); orig_node->last_real_seqno = seqno; } @@ -954,6 +960,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, bool is_from_best_next_hop = false; int is_duplicate; uint32_t if_incoming_seqno; + uint8_t *prev_sender; /* Silently drop when the batman packet is actually not a * correct packet. @@ -975,18 +982,19 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); - if (compare_eth(ethhdr->h_source, batman_ogm_packet->orig)) + if (batadv_compare_eth(ethhdr->h_source, batman_ogm_packet->orig)) is_single_hop_neigh = true; - bat_dbg(DBG_BATMAN, bat_priv, - "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", - ethhdr->h_source, if_incoming->net_dev->name, - if_incoming->net_dev->dev_addr, batman_ogm_packet->orig, - batman_ogm_packet->prev_sender, ntohl(batman_ogm_packet->seqno), - batman_ogm_packet->ttvn, ntohs(batman_ogm_packet->tt_crc), - batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq, - batman_ogm_packet->header.ttl, - batman_ogm_packet->header.version, has_directlink_flag); + batadv_dbg(DBG_BATMAN, bat_priv, + "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", + ethhdr->h_source, if_incoming->net_dev->name, + if_incoming->net_dev->dev_addr, batman_ogm_packet->orig, + batman_ogm_packet->prev_sender, + ntohl(batman_ogm_packet->seqno), batman_ogm_packet->ttvn, + ntohs(batman_ogm_packet->tt_crc), + batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq, + batman_ogm_packet->header.ttl, + batman_ogm_packet->header.version, has_directlink_flag); rcu_read_lock(); list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { @@ -996,16 +1004,16 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, if (hard_iface->soft_iface != if_incoming->soft_iface) continue; - if (compare_eth(ethhdr->h_source, - hard_iface->net_dev->dev_addr)) + if (batadv_compare_eth(ethhdr->h_source, + hard_iface->net_dev->dev_addr)) is_my_addr = 1; - if (compare_eth(batman_ogm_packet->orig, - hard_iface->net_dev->dev_addr)) + if (batadv_compare_eth(batman_ogm_packet->orig, + hard_iface->net_dev->dev_addr)) is_my_orig = 1; - if (compare_eth(batman_ogm_packet->prev_sender, - hard_iface->net_dev->dev_addr)) + if (batadv_compare_eth(batman_ogm_packet->prev_sender, + hard_iface->net_dev->dev_addr)) is_my_oldorig = 1; if (is_broadcast_ether_addr(ethhdr->h_source)) @@ -1014,23 +1022,23 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, rcu_read_unlock(); if (batman_ogm_packet->header.version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_ogm_packet->header.version); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: incompatible batman version (%i)\n", + batman_ogm_packet->header.version); return; } if (is_my_addr) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: received my own broadcast (sender: %pM)\n", - ethhdr->h_source); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: received my own broadcast (sender: %pM)\n", + ethhdr->h_source); return; } if (is_broadcast) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n", - ethhdr->h_source); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n", + ethhdr->h_source); return; } @@ -1049,8 +1057,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, * save packet seqno for bidirectional check */ if (has_directlink_flag && - compare_eth(if_incoming->net_dev->dev_addr, - batman_ogm_packet->orig)) { + batadv_compare_eth(if_incoming->net_dev->dev_addr, + batman_ogm_packet->orig)) { offset = if_incoming->if_num * NUM_WORDS; spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); @@ -1063,23 +1071,23 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); } - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: originator packet from myself (via neighbor)\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: originator packet from myself (via neighbor)\n"); batadv_orig_node_free_ref(orig_neigh_node); return; } if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", - ethhdr->h_source); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", + ethhdr->h_source); return; } if (batman_ogm_packet->flags & NOT_BEST_NEXT_HOP) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n", - ethhdr->h_source); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n", + ethhdr->h_source); return; } @@ -1091,15 +1099,15 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, if_incoming); if (is_duplicate == -1) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: packet within seqno protection time (sender: %pM)\n", - ethhdr->h_source); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: packet within seqno protection time (sender: %pM)\n", + ethhdr->h_source); goto out; } if (batman_ogm_packet->tq == 0) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: originator packet with tq equal 0\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: originator packet with tq equal 0\n"); goto out; } @@ -1108,18 +1116,18 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, router_router = batadv_orig_node_get_router(router->orig_node); if ((router && router->tq_avg != 0) && - (compare_eth(router->addr, ethhdr->h_source))) + (batadv_compare_eth(router->addr, ethhdr->h_source))) is_from_best_next_hop = true; + prev_sender = batman_ogm_packet->prev_sender; /* avoid temporary routing loops */ if (router && router_router && - (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && - !(compare_eth(batman_ogm_packet->orig, - batman_ogm_packet->prev_sender)) && - (compare_eth(router->addr, router_router->addr))) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", - ethhdr->h_source); + (batadv_compare_eth(router->addr, prev_sender)) && + !(batadv_compare_eth(batman_ogm_packet->orig, prev_sender)) && + (batadv_compare_eth(router->addr, router_router->addr))) { + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", + ethhdr->h_source); goto out; } @@ -1138,8 +1146,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, * don't route towards it */ if (!is_single_hop_neigh && (!orig_neigh_router)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: OGM via unknown neighbor!\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: OGM via unknown neighbor!\n"); goto out_neigh; } @@ -1168,26 +1176,26 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, is_single_hop_neigh, is_from_best_next_hop, if_incoming); - bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); goto out_neigh; } /* multihop originator */ if (!is_bidirectional) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: not received via bidirectional link\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: not received via bidirectional link\n"); goto out_neigh; } if (is_duplicate) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: duplicate packet received\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: duplicate packet received\n"); goto out_neigh; } - bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: rebroadcast originator packet\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Forwarding packet: rebroadcast originator packet\n"); bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, is_single_hop_neigh, is_from_best_next_hop, if_incoming); diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 0c7e22e4d5f3..7f464a9e9672 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -730,9 +730,9 @@ out: batadv_hardif_free_ref(primary_if); if (ret) - bat_dbg(DBG_BATMAN, bat_priv, - "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n", - uev_type_str[type], uev_action_str[action], - (action == UEV_DEL ? "NULL" : data), ret); + batadv_dbg(DBG_BATMAN, bat_priv, + "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n", + uev_type_str[type], uev_action_str[action], + (action == UEV_DEL ? "NULL" : data), ret); return ret; } diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index 7a7065cc88cd..e195b9eed7ee 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -66,9 +66,9 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, /* sequence number is much newer, probably missed a lot of packets */ if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) && (seq_num_diff < EXPECTED_SEQNO_RANGE)) { - bat_dbg(DBG_BATMAN, bat_priv, - "We missed a lot of packets (%i) !\n", - seq_num_diff - 1); + batadv_dbg(DBG_BATMAN, bat_priv, + "We missed a lot of packets (%i) !\n", + seq_num_diff - 1); bitmap_zero(seq_bits, TQ_LOCAL_WINDOW_SIZE); if (set_mark) batadv_set_bit(seq_bits, 0); @@ -83,8 +83,8 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Other host probably restarted!\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Other host probably restarted!\n"); bitmap_zero(seq_bits, TQ_LOCAL_WINDOW_SIZE); if (set_mark) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 1d143d5bb53e..b7d70845aa4a 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -294,25 +294,26 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, * set Ethernet SRC to the clients mac */ memcpy(ethhdr->h_source, mac, ETH_ALEN); - bat_dbg(DBG_BLA, bat_priv, - "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid); break; case CLAIM_TYPE_DEL: /* unclaim frame * set HW SRC to the clients mac */ memcpy(hw_src, mac, ETH_ALEN); - bat_dbg(DBG_BLA, bat_priv, - "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac, + vid); break; case CLAIM_TYPE_ANNOUNCE: /* announcement frame * set HW SRC to the special mac containg the crc */ memcpy(hw_src, mac, ETH_ALEN); - bat_dbg(DBG_BLA, bat_priv, - "bla_send_claim(): ANNOUNCE of %pM on vid %d\n", - ethhdr->h_source, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_send_claim(): ANNOUNCE of %pM on vid %d\n", + ethhdr->h_source, vid); break; case CLAIM_TYPE_REQUEST: /* request frame @@ -320,9 +321,9 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, */ memcpy(hw_src, mac, ETH_ALEN); memcpy(ethhdr->h_dest, mac, ETH_ALEN); - bat_dbg(DBG_BLA, bat_priv, - "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n", - ethhdr->h_source, ethhdr->h_dest, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n", + ethhdr->h_source, ethhdr->h_dest, vid); break; } @@ -361,9 +362,9 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, if (entry) return entry; - bat_dbg(DBG_BLA, bat_priv, - "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n", - orig, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n", + orig, vid); entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) @@ -433,8 +434,8 @@ static void bla_answer_request(struct bat_priv *bat_priv, struct backbone_gw *backbone_gw; int i; - bat_dbg(DBG_BLA, bat_priv, - "bla_answer_request(): received a claim request, send all of our own claims again\n"); + batadv_dbg(DBG_BLA, bat_priv, + "bla_answer_request(): received a claim request, send all of our own claims again\n"); backbone_gw = backbone_hash_find(bat_priv, primary_if->net_dev->dev_addr, vid); @@ -473,9 +474,8 @@ static void bla_send_request(struct backbone_gw *backbone_gw) /* first, remove all old entries */ bla_del_backbone_claims(backbone_gw); - bat_dbg(DBG_BLA, backbone_gw->bat_priv, - "Sending REQUEST to %pM\n", - backbone_gw->orig); + batadv_dbg(DBG_BLA, backbone_gw->bat_priv, "Sending REQUEST to %pM\n", + backbone_gw->orig); /* send request */ bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig, @@ -538,9 +538,9 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, claim->backbone_gw = backbone_gw; atomic_set(&claim->refcount, 2); - bat_dbg(DBG_BLA, bat_priv, - "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", - mac, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", + mac, vid); hash_added = batadv_hash_add(bat_priv->claim_hash, compare_claim, choose_claim, claim, &claim->hash_entry); @@ -556,9 +556,9 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, /* no need to register a new backbone */ goto claim_free_ref; - bat_dbg(DBG_BLA, bat_priv, - "bla_add_claim(): changing ownership for %pM, vid %d\n", - mac, vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_add_claim(): changing ownership for %pM, vid %d\n", + mac, vid); claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); @@ -590,7 +590,8 @@ static void bla_del_claim(struct bat_priv *bat_priv, const uint8_t *mac, if (!claim) return; - bat_dbg(DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid); + batadv_dbg(DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, + vid); batadv_hash_remove(bat_priv->claim_hash, compare_claim, choose_claim, claim); @@ -622,15 +623,15 @@ static int handle_announce(struct bat_priv *bat_priv, backbone_gw->lasttime = jiffies; crc = ntohs(*((__be16 *)(&an_addr[4]))); - bat_dbg(DBG_BLA, bat_priv, - "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n", - vid, backbone_gw->orig, crc); + batadv_dbg(DBG_BLA, bat_priv, + "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n", + vid, backbone_gw->orig, crc); if (backbone_gw->crc != crc) { - bat_dbg(DBG_BLA, backbone_gw->bat_priv, - "handle_announce(): CRC FAILED for %pM/%d (my = %04x, sent = %04x)\n", - backbone_gw->orig, backbone_gw->vid, backbone_gw->crc, - crc); + batadv_dbg(DBG_BLA, backbone_gw->bat_priv, + "handle_announce(): CRC FAILED for %pM/%d (my = %04x, sent = %04x)\n", + backbone_gw->orig, backbone_gw->vid, + backbone_gw->crc, crc); bla_send_request(backbone_gw); } else { @@ -654,18 +655,18 @@ static int handle_request(struct bat_priv *bat_priv, struct ethhdr *ethhdr, short vid) { /* check for REQUEST frame */ - if (!compare_eth(backbone_addr, ethhdr->h_dest)) + if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest)) return 0; /* sanity check, this should not happen on a normal switch, * we ignore it in this case. */ - if (!compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr)) + if (!batadv_compare_eth(ethhdr->h_dest, primary_if->net_dev->dev_addr)) return 1; - bat_dbg(DBG_BLA, bat_priv, - "handle_request(): REQUEST vid %d (sent by %pM)...\n", - vid, ethhdr->h_source); + batadv_dbg(DBG_BLA, bat_priv, + "handle_request(): REQUEST vid %d (sent by %pM)...\n", + vid, ethhdr->h_source); bla_answer_request(bat_priv, primary_if, vid); return 1; @@ -680,8 +681,8 @@ static int handle_unclaim(struct bat_priv *bat_priv, struct backbone_gw *backbone_gw; /* unclaim in any case if it is our own */ - if (primary_if && compare_eth(backbone_addr, - primary_if->net_dev->dev_addr)) + if (primary_if && batadv_compare_eth(backbone_addr, + primary_if->net_dev->dev_addr)) bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_DEL); backbone_gw = backbone_hash_find(bat_priv, backbone_addr, vid); @@ -690,9 +691,9 @@ static int handle_unclaim(struct bat_priv *bat_priv, return 1; /* this must be an UNCLAIM frame */ - bat_dbg(DBG_BLA, bat_priv, - "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n", - claim_addr, vid, backbone_gw->orig); + batadv_dbg(DBG_BLA, bat_priv, + "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n", + claim_addr, vid, backbone_gw->orig); bla_del_claim(bat_priv, claim_addr, vid); backbone_gw_free_ref(backbone_gw); @@ -715,7 +716,7 @@ static int handle_claim(struct bat_priv *bat_priv, /* this must be a CLAIM frame */ bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); - if (compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) + if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_ADD); /* TODO: we could call something like tt_local_del() here. */ @@ -772,7 +773,7 @@ static int check_claim_group(struct bat_priv *bat_priv, } /* don't accept claim frames from ourselves */ - if (compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) + if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) return 0; /* if its already the same group, it is fine. */ @@ -790,9 +791,9 @@ static int check_claim_group(struct bat_priv *bat_priv, /* if our mesh friends mac is bigger, use it for ourselves. */ if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) { - bat_dbg(DBG_BLA, bat_priv, - "taking other backbones claim group: %04x\n", - ntohs(bla_dst->group)); + batadv_dbg(DBG_BLA, bat_priv, + "taking other backbones claim group: %04x\n", + ntohs(bla_dst->group)); bla_dst_own->group = bla_dst->group; } @@ -867,9 +868,9 @@ static int bla_process_claim(struct bat_priv *bat_priv, /* check if it is a claim frame. */ ret = check_claim_group(bat_priv, primary_if, hw_src, hw_dst, ethhdr); if (ret == 1) - bat_dbg(DBG_BLA, bat_priv, - "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", - ethhdr->h_source, vid, hw_src, hw_dst); + batadv_dbg(DBG_BLA, bat_priv, + "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", + ethhdr->h_source, vid, hw_src, hw_dst); if (ret < 2) return ret; @@ -900,9 +901,9 @@ static int bla_process_claim(struct bat_priv *bat_priv, break; } - bat_dbg(DBG_BLA, bat_priv, - "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", - ethhdr->h_source, vid, hw_src, hw_dst); + batadv_dbg(DBG_BLA, bat_priv, + "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", + ethhdr->h_source, vid, hw_src, hw_dst); return 1; } @@ -931,13 +932,13 @@ static void bla_purge_backbone_gw(struct bat_priv *bat_priv, int now) head, hash_entry) { if (now) goto purge_now; - if (!has_timed_out(backbone_gw->lasttime, - BLA_BACKBONE_TIMEOUT)) + if (!batadv_has_timed_out(backbone_gw->lasttime, + BLA_BACKBONE_TIMEOUT)) continue; - bat_dbg(DBG_BLA, backbone_gw->bat_priv, - "bla_purge_backbone_gw(): backbone gw %pM timed out\n", - backbone_gw->orig); + batadv_dbg(DBG_BLA, backbone_gw->bat_priv, + "bla_purge_backbone_gw(): backbone gw %pM timed out\n", + backbone_gw->orig); purge_now: /* don't wait for the pending request anymore */ @@ -980,16 +981,16 @@ static void bla_purge_claims(struct bat_priv *bat_priv, hlist_for_each_entry_rcu(claim, node, head, hash_entry) { if (now) goto purge_now; - if (!compare_eth(claim->backbone_gw->orig, - primary_if->net_dev->dev_addr)) + if (!batadv_compare_eth(claim->backbone_gw->orig, + primary_if->net_dev->dev_addr)) continue; - if (!has_timed_out(claim->lasttime, - BLA_CLAIM_TIMEOUT)) + if (!batadv_has_timed_out(claim->lasttime, + BLA_CLAIM_TIMEOUT)) continue; - bat_dbg(DBG_BLA, bat_priv, - "bla_purge_claims(): %pM, vid %d, time out\n", - claim->addr, claim->vid); + batadv_dbg(DBG_BLA, bat_priv, + "bla_purge_claims(): %pM, vid %d, time out\n", + claim->addr, claim->vid); purge_now: handle_unclaim(bat_priv, primary_if, @@ -1036,8 +1037,8 @@ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, rcu_read_lock(); hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { /* own orig still holds the old value. */ - if (!compare_eth(backbone_gw->orig, - oldif->net_dev->dev_addr)) + if (!batadv_compare_eth(backbone_gw->orig, + oldif->net_dev->dev_addr)) continue; memcpy(backbone_gw->orig, @@ -1097,8 +1098,8 @@ static void bla_periodic_work(struct work_struct *work) rcu_read_lock(); hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { - if (!compare_eth(backbone_gw->orig, - primary_if->net_dev->dev_addr)) + if (!batadv_compare_eth(backbone_gw->orig, + primary_if->net_dev->dev_addr)) continue; backbone_gw->lasttime = jiffies; @@ -1129,7 +1130,7 @@ int batadv_bla_init(struct bat_priv *bat_priv) uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; struct hard_iface *primary_if; - bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n"); + batadv_dbg(DBG_BLA, bat_priv, "bla hash registering\n"); /* setting claim destination address */ memcpy(&bat_priv->claim_dest.magic, claim_dest, 3); @@ -1164,7 +1165,7 @@ int batadv_bla_init(struct bat_priv *bat_priv) batadv_hash_set_lock_class(bat_priv->backbone_hash, &backbone_hash_lock_class_key); - bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); + batadv_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); bla_start_timer(bat_priv); return 0; @@ -1206,13 +1207,13 @@ int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, /* we can stop searching if the entry is too old ; * later entries will be even older */ - if (has_timed_out(entry->entrytime, DUPLIST_TIMEOUT)) + if (batadv_has_timed_out(entry->entrytime, DUPLIST_TIMEOUT)) break; if (entry->crc != crc) continue; - if (compare_eth(entry->orig, bcast_packet->orig)) + if (batadv_compare_eth(entry->orig, bcast_packet->orig)) continue; /* this entry seems to match: same crc, not too old, @@ -1260,7 +1261,7 @@ int batadv_bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig) rcu_read_lock(); hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { - if (compare_eth(backbone_gw->orig, orig)) { + if (batadv_compare_eth(backbone_gw->orig, orig)) { rcu_read_unlock(); return 1; } @@ -1387,8 +1388,8 @@ int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) } /* if it is our own claim ... */ - if (compare_eth(claim->backbone_gw->orig, - primary_if->net_dev->dev_addr)) { + if (batadv_compare_eth(claim->backbone_gw->orig, + primary_if->net_dev->dev_addr)) { /* ... allow it in any case */ claim->lasttime = jiffies; goto allow; @@ -1474,8 +1475,8 @@ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) goto allow; /* check if we are responsible. */ - if (compare_eth(claim->backbone_gw->orig, - primary_if->net_dev->dev_addr)) { + if (batadv_compare_eth(claim->backbone_gw->orig, + primary_if->net_dev->dev_addr)) { /* if yes, the client has roamed and we have * to unclaim it. */ @@ -1523,6 +1524,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) uint32_t i; bool is_own; int ret = 0; + uint8_t *primary_addr; primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) { @@ -1539,9 +1541,10 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) goto out; } + primary_addr = primary_if->net_dev->dev_addr; seq_printf(seq, "Claims announced for the mesh %s (orig %pM, group id %04x)\n", - net_dev->name, primary_if->net_dev->dev_addr, + net_dev->name, primary_addr, ntohs(bat_priv->claim_dest.group)); seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", "Client", "VID", "Originator", "CRC"); @@ -1550,8 +1553,8 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) rcu_read_lock(); hlist_for_each_entry_rcu(claim, node, head, hash_entry) { - is_own = compare_eth(claim->backbone_gw->orig, - primary_if->net_dev->dev_addr); + is_own = batadv_compare_eth(claim->backbone_gw->orig, + primary_addr); seq_printf(seq, " * %pM on % 5d by %pM [%c] (%04x)\n", claim->addr, claim->vid, claim->backbone_gw->orig, diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index c917a2ee1f39..318c112aa98c 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -217,20 +217,20 @@ void batadv_gw_election(struct bat_priv *bat_priv) } if ((curr_gw) && (!next_gw)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Removing selected gateway - no gateway in range\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Removing selected gateway - no gateway in range\n"); batadv_throw_uevent(bat_priv, UEV_GW, UEV_DEL, NULL); } else if ((!curr_gw) && (next_gw)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n", - next_gw->orig_node->orig, next_gw->orig_node->gw_flags, - router->tq_avg); + batadv_dbg(DBG_BATMAN, bat_priv, + "Adding route to gateway %pM (gw_flags: %i, tq: %i)\n", + next_gw->orig_node->orig, + next_gw->orig_node->gw_flags, router->tq_avg); batadv_throw_uevent(bat_priv, UEV_GW, UEV_ADD, gw_addr); } else { - bat_dbg(DBG_BATMAN, bat_priv, - "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n", - next_gw->orig_node->orig, next_gw->orig_node->gw_flags, - router->tq_avg); + batadv_dbg(DBG_BATMAN, bat_priv, + "Changing route to gateway %pM (gw_flags: %i, tq: %i)\n", + next_gw->orig_node->orig, + next_gw->orig_node->gw_flags, router->tq_avg); batadv_throw_uevent(bat_priv, UEV_GW, UEV_CHANGE, gw_addr); } @@ -282,9 +282,9 @@ void batadv_gw_check_election(struct bat_priv *bat_priv, (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) goto out; - bat_dbg(DBG_BATMAN, bat_priv, - "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n", - gw_tq_avg, orig_tq_avg); + batadv_dbg(DBG_BATMAN, bat_priv, + "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n", + gw_tq_avg, orig_tq_avg); deselect: batadv_gw_deselect(bat_priv); @@ -318,13 +318,13 @@ static void gw_node_add(struct bat_priv *bat_priv, spin_unlock_bh(&bat_priv->gw_list_lock); batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up); - bat_dbg(DBG_BATMAN, bat_priv, - "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", - orig_node->orig, new_gwflags, - (down > 2048 ? down / 1024 : down), - (down > 2048 ? "MBit" : "KBit"), - (up > 2048 ? up / 1024 : up), - (up > 2048 ? "MBit" : "KBit")); + batadv_dbg(DBG_BATMAN, bat_priv, + "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", + orig_node->orig, new_gwflags, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); } void batadv_gw_node_update(struct bat_priv *bat_priv, @@ -345,18 +345,18 @@ void batadv_gw_node_update(struct bat_priv *bat_priv, if (gw_node->orig_node != orig_node) continue; - bat_dbg(DBG_BATMAN, bat_priv, - "Gateway class of originator %pM changed from %i to %i\n", - orig_node->orig, gw_node->orig_node->gw_flags, - new_gwflags); + batadv_dbg(DBG_BATMAN, bat_priv, + "Gateway class of originator %pM changed from %i to %i\n", + orig_node->orig, gw_node->orig_node->gw_flags, + new_gwflags); gw_node->deleted = 0; if (new_gwflags == NO_FLAGS) { gw_node->deleted = jiffies; - bat_dbg(DBG_BATMAN, bat_priv, - "Gateway %pM removed from gateway list\n", - orig_node->orig); + batadv_dbg(DBG_BATMAN, bat_priv, + "Gateway %pM removed from gateway list\n", + orig_node->orig); if (gw_node == curr_gw) goto deselect; diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 06f8d63d741d..6131d932b638 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -163,8 +163,8 @@ static void check_known_mac_addr(const struct net_device *net_dev) if (hard_iface->net_dev == net_dev) continue; - if (!compare_eth(hard_iface->net_dev->dev_addr, - net_dev->dev_addr)) + if (!batadv_compare_eth(hard_iface->net_dev->dev_addr, + net_dev->dev_addr)) continue; pr_warn("The newly added mac address (%pM) already exists on: %s\n", diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 50a74dadb4d6..a3e80b6782af 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -158,8 +158,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, size_t packet_len = sizeof(struct icmp_packet); if (len < sizeof(struct icmp_packet)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Error - can't send packet from char device: invalid packet size\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Error - can't send packet from char device: invalid packet size\n"); return -EINVAL; } @@ -188,15 +188,15 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, } if (icmp_packet->header.packet_type != BAT_ICMP) { - bat_dbg(DBG_BATMAN, bat_priv, - "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); len = -EINVAL; goto free_skb; } if (icmp_packet->msg_type != ECHO_REQUEST) { - bat_dbg(DBG_BATMAN, bat_priv, - "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); len = -EINVAL; goto free_skb; } diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index d56d6b2e1924..e4564306453c 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -180,7 +180,7 @@ int batadv_is_my_mac(const uint8_t *addr) if (hard_iface->if_status != IF_ACTIVE) continue; - if (compare_eth(hard_iface->net_dev->dev_addr, addr)) { + if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) { rcu_read_unlock(); return 1; } @@ -238,9 +238,9 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, batman_ogm_packet = (struct batman_ogm_packet *)skb->data; if (batman_ogm_packet->header.version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_ogm_packet->header.version); + batadv_dbg(DBG_BATMAN, bat_priv, + "Drop packet: incompatible batman version (%i)\n", + batman_ogm_packet->header.version); goto err_free; } diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 4b06b7621e7a..28242642c3f1 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -175,7 +175,7 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); int batadv_debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3); -#define bat_dbg(type, bat_priv, fmt, arg...) \ +#define batadv_dbg(type, bat_priv, fmt, arg...) \ do { \ if (atomic_read(&bat_priv->log_level) & type) \ batadv_debug_log(bat_priv, fmt, ## arg);\ @@ -183,9 +183,9 @@ __printf(2, 3); while (0) #else /* !CONFIG_BATMAN_ADV_DEBUG */ __printf(3, 4) -static inline void bat_dbg(int type __always_unused, - struct bat_priv *bat_priv __always_unused, - const char *fmt __always_unused, ...) +static inline void batadv_dbg(int type __always_unused, + struct bat_priv *bat_priv __always_unused, + const char *fmt __always_unused, ...) { } #endif @@ -194,14 +194,14 @@ static inline void bat_dbg(int type __always_unused, do { \ struct net_device *_netdev = (net_dev); \ struct bat_priv *_batpriv = netdev_priv(_netdev); \ - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ + batadv_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ pr_info("%s: " fmt, _netdev->name, ## arg); \ } while (0) #define bat_err(net_dev, fmt, arg...) \ do { \ struct net_device *_netdev = (net_dev); \ struct bat_priv *_batpriv = netdev_priv(_netdev); \ - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ + batadv_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ pr_err("%s: " fmt, _netdev->name, ## arg); \ } while (0) @@ -209,7 +209,7 @@ static inline void bat_dbg(int type __always_unused, * * note: can't use compare_ether_addr() as it requires aligned memory */ -static inline int compare_eth(const void *data1, const void *data2) +static inline int batadv_compare_eth(const void *data1, const void *data2) { return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } @@ -220,7 +220,8 @@ static inline int compare_eth(const void *data1, const void *data2) * * Returns true if current time is after timestamp + timeout */ -static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout) +static inline bool batadv_has_timed_out(unsigned long timestamp, + unsigned int timeout) { return time_is_before_jiffies(timestamp + msecs_to_jiffies(timeout)); } diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 36f5ee5cd195..1cd640e8dab9 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -102,9 +102,9 @@ struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, /* extra reference for return */ atomic_set(&neigh_node->refcount, 2); - bat_dbg(DBG_BATMAN, bat_priv, - "Creating new neighbor %pM, initial seqno %d\n", - neigh_addr, seqno); + batadv_dbg(DBG_BATMAN, bat_priv, + "Creating new neighbor %pM, initial seqno %d\n", + neigh_addr, seqno); out: return neigh_node; @@ -199,8 +199,8 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, if (orig_node) return orig_node; - bat_dbg(DBG_BATMAN, bat_priv, - "Creating new originator: %pM\n", addr); + batadv_dbg(DBG_BATMAN, bat_priv, "Creating new originator: %pM\n", + addr); orig_node = kzalloc(sizeof(*orig_node), GFP_ATOMIC); if (!orig_node) @@ -272,6 +272,7 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, struct neigh_node *neigh_node; bool neigh_purged = false; unsigned long last_seen; + struct hard_iface *if_incoming; *best_neigh_node = NULL; @@ -281,28 +282,26 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, hlist_for_each_entry_safe(neigh_node, node, node_tmp, &orig_node->neigh_list, list) { - if ((has_timed_out(neigh_node->last_seen, PURGE_TIMEOUT)) || - (neigh_node->if_incoming->if_status == IF_INACTIVE) || - (neigh_node->if_incoming->if_status == IF_NOT_IN_USE) || - (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { - - last_seen = neigh_node->last_seen; - - if ((neigh_node->if_incoming->if_status == - IF_INACTIVE) || - (neigh_node->if_incoming->if_status == - IF_NOT_IN_USE) || - (neigh_node->if_incoming->if_status == - IF_TO_BE_REMOVED)) - bat_dbg(DBG_BATMAN, bat_priv, - "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", - orig_node->orig, neigh_node->addr, - neigh_node->if_incoming->net_dev->name); + last_seen = neigh_node->last_seen; + if_incoming = neigh_node->if_incoming; + + if ((batadv_has_timed_out(last_seen, PURGE_TIMEOUT)) || + (if_incoming->if_status == IF_INACTIVE) || + (if_incoming->if_status == IF_NOT_IN_USE) || + (if_incoming->if_status == IF_TO_BE_REMOVED)) { + + if ((if_incoming->if_status == IF_INACTIVE) || + (if_incoming->if_status == IF_NOT_IN_USE) || + (if_incoming->if_status == IF_TO_BE_REMOVED)) + batadv_dbg(DBG_BATMAN, bat_priv, + "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", + orig_node->orig, neigh_node->addr, + if_incoming->net_dev->name); else - bat_dbg(DBG_BATMAN, bat_priv, - "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n", - orig_node->orig, neigh_node->addr, - jiffies_to_msecs(last_seen)); + batadv_dbg(DBG_BATMAN, bat_priv, + "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n", + orig_node->orig, neigh_node->addr, + jiffies_to_msecs(last_seen)); neigh_purged = true; @@ -325,11 +324,11 @@ static bool purge_orig_node(struct bat_priv *bat_priv, { struct neigh_node *best_neigh_node; - if (has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Originator timeout: originator %pM, last_seen %u\n", - orig_node->orig, - jiffies_to_msecs(orig_node->last_seen)); + if (batadv_has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { + batadv_dbg(DBG_BATMAN, bat_priv, + "Originator timeout: originator %pM, last_seen %u\n", + orig_node->orig, + jiffies_to_msecs(orig_node->last_seen)); return true; } else { if (purge_orig_neighbors(bat_priv, orig_node, @@ -370,8 +369,8 @@ static void _purge_orig(struct bat_priv *bat_priv) continue; } - if (has_timed_out(orig_node->last_frag_packet, - FRAG_TIMEOUT)) + if (batadv_has_timed_out(orig_node->last_frag_packet, + FRAG_TIMEOUT)) batadv_frag_list_free(&orig_node->frag_list); } spin_unlock_bh(list_lock); diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index c4f63b4d54a7..35f67eb4073f 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -77,7 +77,7 @@ static inline struct orig_node *batadv_orig_hash_find(struct bat_priv *bat_priv, rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - if (!compare_eth(orig_node, data)) + if (!batadv_compare_eth(orig_node, data)) continue; if (!atomic_inc_not_zero(&orig_node->refcount)) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 3eb4a2e121a6..57ff85178216 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -71,23 +71,23 @@ static void _update_route(struct bat_priv *bat_priv, /* route deleted */ if ((curr_router) && (!neigh_node)) { - bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", - orig_node->orig); + batadv_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", + orig_node->orig); batadv_tt_global_del_orig(bat_priv, orig_node, "Deleted route towards originator"); /* route added */ } else if ((!curr_router) && (neigh_node)) { - bat_dbg(DBG_ROUTES, bat_priv, - "Adding route towards: %pM (via %pM)\n", - orig_node->orig, neigh_node->addr); + batadv_dbg(DBG_ROUTES, bat_priv, + "Adding route towards: %pM (via %pM)\n", + orig_node->orig, neigh_node->addr); /* route changed */ } else if (neigh_node && curr_router) { - bat_dbg(DBG_ROUTES, bat_priv, - "Changing route towards: %pM (now via %pM - was via %pM)\n", - orig_node->orig, neigh_node->addr, - curr_router->addr); + batadv_dbg(DBG_ROUTES, bat_priv, + "Changing route towards: %pM (now via %pM - was via %pM)\n", + orig_node->orig, neigh_node->addr, + curr_router->addr); } if (curr_router) @@ -151,8 +151,8 @@ void batadv_bonding_candidate_add(struct orig_node *orig_node, spin_lock_bh(&orig_node->neigh_list_lock); /* only consider if it has the same primary address ... */ - if (!compare_eth(orig_node->orig, - neigh_node->orig_node->primary_addr)) + if (!batadv_compare_eth(orig_node->orig, + neigh_node->orig_node->primary_addr)) goto candidate_del; router = batadv_orig_node_get_router(orig_node); @@ -180,7 +180,8 @@ void batadv_bonding_candidate_add(struct orig_node *orig_node, continue; if ((neigh_node->if_incoming == tmp_neigh_node->if_incoming) || - (compare_eth(neigh_node->addr, tmp_neigh_node->addr))) { + (batadv_compare_eth(neigh_node->addr, + tmp_neigh_node->addr))) { interference_candidate = 1; break; } @@ -233,12 +234,12 @@ int batadv_window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, { if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - if (!has_timed_out(*last_reset, RESET_PROTECTION_MS)) + if (!batadv_has_timed_out(*last_reset, RESET_PROTECTION_MS)) return 1; *last_reset = jiffies; - bat_dbg(DBG_BATMAN, bat_priv, - "old packet received, start protection\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "old packet received, start protection\n"); } return 0; @@ -578,6 +579,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) struct tt_query_packet *tt_query; uint16_t tt_size; struct ethhdr *ethhdr; + char tt_flag; /* drop packet if it has not necessary minimum size */ if (unlikely(!pskb_may_pull(skb, sizeof(struct tt_query_packet)))) @@ -607,10 +609,11 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) * forwarded */ if (!batadv_send_tt_response(bat_priv, tt_query)) { - bat_dbg(DBG_TT, bat_priv, - "Routing TT_REQUEST to %pM [%c]\n", - tt_query->dst, - (tt_query->flags & TT_FULL_TABLE ? 'F' : '.')); + tt_flag = tt_query->flags & TT_FULL_TABLE ? 'F' : '.'; + batadv_dbg(DBG_TT, bat_priv, + "Routing TT_REQUEST to %pM [%c]\n", + tt_query->dst, + tt_flag); return route_unicast_packet(skb, recv_if); } break; @@ -635,10 +638,11 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) batadv_handle_tt_response(bat_priv, tt_query); } else { - bat_dbg(DBG_TT, bat_priv, - "Routing TT_RESPONSE to %pM [%c]\n", - tt_query->dst, - (tt_query->flags & TT_FULL_TABLE ? 'F' : '.')); + tt_flag = tt_query->flags & TT_FULL_TABLE ? 'F' : '.'; + batadv_dbg(DBG_TT, bat_priv, + "Routing TT_RESPONSE to %pM [%c]\n", + tt_query->dst, + tt_flag); return route_unicast_packet(skb, recv_if); } break; @@ -688,9 +692,9 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) if (!orig_node) goto out; - bat_dbg(DBG_TT, bat_priv, - "Received ROAMING_ADV from %pM (client %pM)\n", - roam_adv_packet->src, roam_adv_packet->client); + batadv_dbg(DBG_TT, bat_priv, + "Received ROAMING_ADV from %pM (client %pM)\n", + roam_adv_packet->src, roam_adv_packet->client); batadv_tt_global_add(bat_priv, orig_node, roam_adv_packet->client, atomic_read(&orig_node->last_ttvn) + 1, true, @@ -749,13 +753,13 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, /* if we have something in the primary_addr, we can search * for a potential bonding candidate. */ - if (compare_eth(primary_addr, zero_mac)) + if (batadv_compare_eth(primary_addr, zero_mac)) goto return_router; /* find the orig_node which has the primary interface. might * even be the same as our router_orig in many cases */ - if (compare_eth(primary_addr, router_orig->orig)) { + if (batadv_compare_eth(primary_addr, router_orig->orig)) { primary_orig_node = router_orig; } else { primary_orig_node = batadv_orig_hash_find(bat_priv, @@ -974,10 +978,10 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, batadv_orig_node_free_ref(orig_node); } - bat_dbg(DBG_ROUTES, bat_priv, - "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", - unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest, - unicast_packet->dest); + batadv_dbg(DBG_ROUTES, bat_priv, + "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", + unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest, + unicast_packet->dest); unicast_packet->ttvn = curr_ttvn; } diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 54091db9d5ff..47c3a41cd854 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -142,7 +142,7 @@ int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *newskb; if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) { - bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n"); + batadv_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n"); goto out; } @@ -271,12 +271,12 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, bool pending; if (hard_iface) - bat_dbg(DBG_BATMAN, bat_priv, - "purge_outstanding_packets(): %s\n", - hard_iface->net_dev->name); + batadv_dbg(DBG_BATMAN, bat_priv, + "purge_outstanding_packets(): %s\n", + hard_iface->net_dev->name); else - bat_dbg(DBG_BATMAN, bat_priv, - "purge_outstanding_packets()\n"); + batadv_dbg(DBG_BATMAN, bat_priv, + "purge_outstanding_packets()\n"); /* free bcast list */ spin_lock_bh(&bat_priv->forw_bcast_list_lock); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 85fe9c1ce5bc..af676b818637 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -168,7 +168,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) /* don't accept stp packets. STP does not help in meshes. * better use the bridge loop avoidance ... */ - if (compare_eth(ethhdr->h_dest, stp_addr)) + if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) goto dropped; if (is_multicast_ether_addr(ethhdr->h_dest)) { diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 1dfa2311bb1b..2eff22f9fdaa 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -66,7 +66,7 @@ static struct tt_common_entry *tt_hash_find(struct hashtable_t *hash, rcu_read_lock(); hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) { - if (!compare_eth(tt_common_entry, data)) + if (!batadv_compare_eth(tt_common_entry, data)) continue; if (!atomic_inc_not_zero(&tt_common_entry->refcount)) @@ -213,9 +213,9 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, if (!tt_local_entry) goto out; - bat_dbg(DBG_TT, bat_priv, - "Creating new local tt entry: %pM (ttvn: %d)\n", addr, - (uint8_t)atomic_read(&bat_priv->ttvn)); + batadv_dbg(DBG_TT, bat_priv, + "Creating new local tt entry: %pM (ttvn: %d)\n", addr, + (uint8_t)atomic_read(&bat_priv->ttvn)); memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); tt_local_entry->common.flags = NO_FLAGS; @@ -225,7 +225,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, tt_local_entry->last_seen = jiffies; /* the batman interface mac address should never be purged */ - if (compare_eth(addr, soft_iface->dev_addr)) + if (batadv_compare_eth(addr, soft_iface->dev_addr)) tt_local_entry->common.flags |= TT_CLIENT_NOPURGE; /* The local entry has to be marked as NEW to avoid to send it in @@ -441,9 +441,9 @@ static void tt_local_set_pending(struct bat_priv *bat_priv, */ tt_local_entry->common.flags |= TT_CLIENT_PENDING; - bat_dbg(DBG_TT, bat_priv, - "Local tt entry (%pM) pending to be removed: %s\n", - tt_local_entry->common.addr, message); + batadv_dbg(DBG_TT, bat_priv, + "Local tt entry (%pM) pending to be removed: %s\n", + tt_local_entry->common.addr, message); } void batadv_tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr, @@ -489,8 +489,8 @@ static void tt_local_purge(struct bat_priv *bat_priv) if (tt_local_entry->common.flags & TT_CLIENT_PENDING) continue; - if (!has_timed_out(tt_local_entry->last_seen, - TT_LOCAL_TIMEOUT)) + if (!batadv_has_timed_out(tt_local_entry->last_seen, + TT_LOCAL_TIMEOUT)) continue; tt_local_set_pending(bat_priv, tt_local_entry, @@ -674,9 +674,9 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, if (wifi) tt_global_entry->common.flags |= TT_CLIENT_WIFI; - bat_dbg(DBG_TT, bat_priv, - "Creating new global tt entry: %pM (via %pM)\n", - tt_global_entry->common.addr, orig_node->orig); + batadv_dbg(DBG_TT, bat_priv, + "Creating new global tt entry: %pM (via %pM)\n", + tt_global_entry->common.addr, orig_node->orig); out_remove: /* remove address from local hash if present */ @@ -800,10 +800,10 @@ static void tt_global_del_orig_entry(struct bat_priv *bat_priv, head = &tt_global_entry->orig_list; hlist_for_each_entry_safe(orig_entry, node, safe, head, list) { if (orig_entry->orig_node == orig_node) { - bat_dbg(DBG_TT, bat_priv, - "Deleting %pM from global tt entry %pM: %s\n", - orig_node->orig, tt_global_entry->common.addr, - message); + batadv_dbg(DBG_TT, bat_priv, + "Deleting %pM from global tt entry %pM: %s\n", + orig_node->orig, + tt_global_entry->common.addr, message); hlist_del_rcu(node); tt_orig_list_entry_free_ref(orig_entry); } @@ -815,9 +815,8 @@ static void tt_global_del_struct(struct bat_priv *bat_priv, struct tt_global_entry *tt_global_entry, const char *message) { - bat_dbg(DBG_TT, bat_priv, - "Deleting global tt entry %pM: %s\n", - tt_global_entry->common.addr, message); + batadv_dbg(DBG_TT, bat_priv, "Deleting global tt entry %pM: %s\n", + tt_global_entry->common.addr, message); batadv_hash_remove(bat_priv->tt_global_hash, compare_tt, batadv_choose_orig, tt_global_entry->common.addr); @@ -951,10 +950,10 @@ void batadv_tt_global_del_orig(struct bat_priv *bat_priv, orig_node, message); if (hlist_empty(&tt_global_entry->orig_list)) { - bat_dbg(DBG_TT, bat_priv, - "Deleting global tt entry %pM: %s\n", - tt_global_entry->common.addr, - message); + batadv_dbg(DBG_TT, bat_priv, + "Deleting global tt entry %pM: %s\n", + tt_global_entry->common.addr, + message); hlist_del_rcu(node); tt_global_entry_free_ref(tt_global_entry); } @@ -987,13 +986,13 @@ static void tt_global_roam_purge(struct bat_priv *bat_priv) common); if (!(tt_global_entry->common.flags & TT_CLIENT_ROAM)) continue; - if (!has_timed_out(tt_global_entry->roam_at, - TT_CLIENT_ROAM_TIMEOUT)) + if (!batadv_has_timed_out(tt_global_entry->roam_at, + TT_CLIENT_ROAM_TIMEOUT)) continue; - bat_dbg(DBG_TT, bat_priv, - "Deleting global tt entry (%pM): Roaming timeout\n", - tt_global_entry->common.addr); + batadv_dbg(DBG_TT, bat_priv, + "Deleting global tt entry (%pM): Roaming timeout\n", + tt_global_entry->common.addr); hlist_del_rcu(node); tt_global_entry_free_ref(tt_global_entry); @@ -1234,7 +1233,7 @@ static void tt_req_purge(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->tt_req_list_lock); list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { - if (has_timed_out(node->issued_at, TT_REQUEST_TIMEOUT)) { + if (batadv_has_timed_out(node->issued_at, TT_REQUEST_TIMEOUT)) { list_del(&node->list); kfree(node); } @@ -1252,9 +1251,9 @@ static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv, spin_lock_bh(&bat_priv->tt_req_list_lock); list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { - if (compare_eth(tt_req_node_tmp, orig_node) && - !has_timed_out(tt_req_node_tmp->issued_at, - TT_REQUEST_TIMEOUT)) + if (batadv_compare_eth(tt_req_node_tmp, orig_node) && + !batadv_has_timed_out(tt_req_node_tmp->issued_at, + TT_REQUEST_TIMEOUT)) goto unlock; } @@ -1409,10 +1408,10 @@ static int send_tt_request(struct bat_priv *bat_priv, if (!neigh_node) goto out; - bat_dbg(DBG_TT, bat_priv, - "Sending TT_REQUEST to %pM via %pM [%c]\n", - dst_orig_node->orig, neigh_node->addr, - (full_table ? 'F' : '.')); + batadv_dbg(DBG_TT, bat_priv, + "Sending TT_REQUEST to %pM via %pM [%c]\n", + dst_orig_node->orig, neigh_node->addr, + (full_table ? 'F' : '.')); batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_TX); @@ -1449,10 +1448,10 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, struct sk_buff *skb = NULL; struct tt_query_packet *tt_response; - bat_dbg(DBG_TT, bat_priv, - "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n", - tt_request->src, tt_request->ttvn, tt_request->dst, - (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); + batadv_dbg(DBG_TT, bat_priv, + "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n", + tt_request->src, tt_request->ttvn, tt_request->dst, + (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); /* Let's get the orig node of the REAL destination */ req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst); @@ -1536,10 +1535,10 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, if (full_table) tt_response->flags |= TT_FULL_TABLE; - bat_dbg(DBG_TT, bat_priv, - "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n", - res_dst_orig_node->orig, neigh_node->addr, - req_dst_orig_node->orig, req_ttvn); + batadv_dbg(DBG_TT, bat_priv, + "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n", + res_dst_orig_node->orig, neigh_node->addr, + req_dst_orig_node->orig, req_ttvn); batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); @@ -1578,10 +1577,10 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, struct sk_buff *skb = NULL; struct tt_query_packet *tt_response; - bat_dbg(DBG_TT, bat_priv, - "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n", - tt_request->src, tt_request->ttvn, - (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); + batadv_dbg(DBG_TT, bat_priv, + "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n", + tt_request->src, tt_request->ttvn, + (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); @@ -1656,10 +1655,10 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, if (full_table) tt_response->flags |= TT_FULL_TABLE; - bat_dbg(DBG_TT, bat_priv, - "Sending TT_RESPONSE to %pM via %pM [%c]\n", - orig_node->orig, neigh_node->addr, - (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); + batadv_dbg(DBG_TT, bat_priv, + "Sending TT_RESPONSE to %pM via %pM [%c]\n", + orig_node->orig, neigh_node->addr, + (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX); @@ -1795,11 +1794,11 @@ void batadv_handle_tt_response(struct bat_priv *bat_priv, struct tt_req_node *node, *safe; struct orig_node *orig_node = NULL; - bat_dbg(DBG_TT, bat_priv, - "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", - tt_response->src, tt_response->ttvn, - ntohs(tt_response->tt_data), - (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); + batadv_dbg(DBG_TT, bat_priv, + "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", + tt_response->src, tt_response->ttvn, + ntohs(tt_response->tt_data), + (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); /* we should have never asked a backbone gw */ if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src)) @@ -1820,7 +1819,7 @@ void batadv_handle_tt_response(struct bat_priv *bat_priv, /* Delete the tt_req_node from pending tt_requests list */ spin_lock_bh(&bat_priv->tt_req_list_lock); list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { - if (!compare_eth(node->addr, tt_response->src)) + if (!batadv_compare_eth(node->addr, tt_response->src)) continue; list_del(&node->list); kfree(node); @@ -1875,7 +1874,7 @@ static void tt_roam_purge(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->tt_roam_list_lock); list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { - if (!has_timed_out(node->first_time, ROAMING_MAX_TIME)) + if (!batadv_has_timed_out(node->first_time, ROAMING_MAX_TIME)) continue; list_del(&node->list); @@ -1901,10 +1900,11 @@ static bool tt_check_roam_count(struct bat_priv *bat_priv, * reply from the same orig_node yet */ list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { - if (!compare_eth(tt_roam_node->addr, client)) + if (!batadv_compare_eth(tt_roam_node->addr, client)) continue; - if (has_timed_out(tt_roam_node->first_time, ROAMING_MAX_TIME)) + if (batadv_has_timed_out(tt_roam_node->first_time, + ROAMING_MAX_TIME)) continue; if (!atomic_dec_not_zero(&tt_roam_node->counter)) @@ -1971,9 +1971,9 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, if (!neigh_node) goto out; - bat_dbg(DBG_TT, bat_priv, - "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", - orig_node->orig, client, neigh_node->addr); + batadv_dbg(DBG_TT, bat_priv, + "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", + orig_node->orig, client, neigh_node->addr); batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_TX); @@ -2078,9 +2078,9 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) if (!(tt_common_entry->flags & TT_CLIENT_PENDING)) continue; - bat_dbg(DBG_TT, bat_priv, - "Deleting local tt entry (%pM): pending\n", - tt_common_entry->addr); + batadv_dbg(DBG_TT, bat_priv, + "Deleting local tt entry (%pM): pending\n", + tt_common_entry->addr); atomic_dec(&bat_priv->num_local_tt); hlist_del_rcu(node); @@ -2113,8 +2113,9 @@ static int tt_commit_changes(struct bat_priv *bat_priv, /* Increment the TTVN only once per OGM interval */ atomic_inc(&bat_priv->ttvn); - bat_dbg(DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", - (uint8_t)atomic_read(&bat_priv->ttvn)); + batadv_dbg(DBG_TT, bat_priv, + "Local changes committed, updating to ttvn %u\n", + (uint8_t)atomic_read(&bat_priv->ttvn)); bat_priv->tt_poss_change = false; /* reset the sending counter */ @@ -2235,10 +2236,10 @@ void batadv_tt_update_orig(struct bat_priv *bat_priv, if (!orig_node->tt_initialised || ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) { request_table: - bat_dbg(DBG_TT, bat_priv, - "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n", - orig_node->orig, ttvn, orig_ttvn, tt_crc, - orig_node->tt_crc, tt_num_changes); + batadv_dbg(DBG_TT, bat_priv, + "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n", + orig_node->orig, ttvn, orig_ttvn, tt_crc, + orig_node->tt_crc, tt_num_changes); send_tt_request(bat_priv, orig_node, ttvn, tt_crc, full_table); return; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index bf72c5248662..d45989e0bbd7 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -59,7 +59,7 @@ static int vis_info_cmp(const struct hlist_node *node, const void *data2) d2 = data2; p1 = (struct vis_packet *)d1->skb_packet->data; p2 = (struct vis_packet *)d2->skb_packet->data; - return compare_eth(p1->vis_orig, p2->vis_orig); + return batadv_compare_eth(p1->vis_orig, p2->vis_orig); } /* hash function to choose an entry in a hash table of given size @@ -127,7 +127,7 @@ static void vis_data_insert_interface(const uint8_t *interface, struct hlist_node *pos; hlist_for_each_entry(entry, pos, if_list, list) { - if (compare_eth(entry->addr, interface)) + if (batadv_compare_eth(entry->addr, interface)) return; } @@ -181,7 +181,7 @@ static ssize_t vis_data_read_entry(char *buff, /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ if (primary && entry->quality == 0) return sprintf(buff, "TT %pM, ", entry->dest); - else if (compare_eth(entry->src, src)) + else if (batadv_compare_eth(entry->src, src)) return sprintf(buff, "TQ %pM %d, ", entry->dest, entry->quality); @@ -233,8 +233,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) continue; - if (compare_eth(entries[j].src, - packet->vis_orig)) + if (batadv_compare_eth(entries[j].src, + packet->vis_orig)) continue; vis_data_insert_interface(entries[j].src, &vis_if_list, @@ -245,7 +245,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) buf_size += 18 + 26 * packet->entries; /* add primary/secondary records */ - if (compare_eth(entry->addr, packet->vis_orig)) + if (batadv_compare_eth(entry->addr, + packet->vis_orig)) buf_size += vis_data_count_prim_sec(&vis_if_list); @@ -285,8 +286,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) continue; - if (compare_eth(entries[j].src, - packet->vis_orig)) + if (batadv_compare_eth(entries[j].src, + packet->vis_orig)) continue; vis_data_insert_interface(entries[j].src, &vis_if_list, @@ -305,7 +306,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) entry->primary); /* add primary/secondary records */ - if (compare_eth(entry->addr, packet->vis_orig)) + if (batadv_compare_eth(entry->addr, + packet->vis_orig)) buff_pos += vis_data_read_prim_sec(buff + buff_pos, &vis_if_list); @@ -379,7 +381,7 @@ static int recv_list_is_in(struct bat_priv *bat_priv, spin_lock_bh(&bat_priv->vis_list_lock); list_for_each_entry(entry, recv_list, list) { - if (compare_eth(entry->mac, mac)) { + if (batadv_compare_eth(entry->mac, mac)) { spin_unlock_bh(&bat_priv->vis_list_lock); return 1; } @@ -651,7 +653,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) if (!router) continue; - if (!compare_eth(router->addr, orig_node->orig)) + if (!batadv_compare_eth(router->addr, orig_node->orig)) goto next; if (router->if_incoming->if_status != IF_ACTIVE) @@ -728,7 +730,8 @@ static void purge_vis_packets(struct bat_priv *bat_priv) if (info == bat_priv->my_vis_info) continue; - if (has_timed_out(info->first_seen, VIS_TIMEOUT)) { + if (batadv_has_timed_out(info->first_seen, + VIS_TIMEOUT)) { hlist_del(node); send_list_del(info); kref_put(&info->refcount, free_info); -- GitLab From fe8bc39699cf887a9c3758aa7b3cbbf771e1e847 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:51 +0200 Subject: [PATCH 2621/6849] batman-adv: Prefix bat_iv_ogm local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 257 ++++++++++++++++++------------------ 1 file changed, 130 insertions(+), 127 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 025df7c9a2d9..ca6466574c46 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -28,11 +28,11 @@ #include "send.h" #include "bat_algo.h" -static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, - const uint8_t *neigh_addr, - struct orig_node *orig_node, - struct orig_node *orig_neigh, - __be32 seqno) +static struct neigh_node *batadv_iv_ogm_neigh_new(struct hard_iface *hard_iface, + const uint8_t *neigh_addr, + struct orig_node *orig_node, + struct orig_node *orig_neigh, + __be32 seqno) { struct neigh_node *neigh_node; @@ -54,7 +54,7 @@ out: return neigh_node; } -static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) +static int batadv_iv_ogm_iface_enable(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; uint32_t random_seqno; @@ -85,13 +85,13 @@ out: return res; } -static void bat_iv_ogm_iface_disable(struct hard_iface *hard_iface) +static void batadv_iv_ogm_iface_disable(struct hard_iface *hard_iface) { kfree(hard_iface->packet_buff); hard_iface->packet_buff = NULL; } -static void bat_iv_ogm_iface_update_mac(struct hard_iface *hard_iface) +static void batadv_iv_ogm_iface_update_mac(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; @@ -102,7 +102,7 @@ static void bat_iv_ogm_iface_update_mac(struct hard_iface *hard_iface) hard_iface->net_dev->dev_addr, ETH_ALEN); } -static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) +static void batadv_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; @@ -112,7 +112,8 @@ static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) } /* when do we schedule our own ogm to be sent */ -static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) +static unsigned long +batadv_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) { return jiffies + msecs_to_jiffies( atomic_read(&bat_priv->orig_interval) - @@ -120,21 +121,21 @@ static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) } /* when do we schedule a ogm packet to be sent */ -static unsigned long bat_iv_ogm_fwd_send_time(void) +static unsigned long batadv_iv_ogm_fwd_send_time(void) { return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); } /* apply hop penalty for a normal link */ -static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) +static uint8_t batadv_hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) { int hop_penalty = atomic_read(&bat_priv->hop_penalty); return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); } /* is there another aggregated packet here? */ -static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len, - int tt_num_changes) +static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, + int tt_num_changes) { int next_buff_pos = 0; @@ -146,7 +147,7 @@ static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len, } /* send a batman ogm to a given interface */ -static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, +static void batadv_iv_ogm_send_to_if(struct forw_packet *forw_packet, struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); @@ -164,8 +165,8 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data; /* adjust all flags and log packets */ - while (bat_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, - batman_ogm_packet->tt_num_changes)) { + while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, + batman_ogm_packet->tt_num_changes)) { /* we might have aggregated direct link packets with an * ordinary base packet @@ -208,7 +209,7 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, } /* send a batman ogm packet */ -static void bat_iv_ogm_emit(struct forw_packet *forw_packet) +static void batadv_iv_ogm_emit(struct forw_packet *forw_packet) { struct hard_iface *hard_iface; struct net_device *soft_iface; @@ -267,7 +268,7 @@ static void bat_iv_ogm_emit(struct forw_packet *forw_packet) if (hard_iface->soft_iface != soft_iface) continue; - bat_iv_ogm_send_to_if(forw_packet, hard_iface); + batadv_iv_ogm_send_to_if(forw_packet, hard_iface); } rcu_read_unlock(); @@ -277,13 +278,13 @@ out: } /* return true if new_packet can be aggregated with forw_packet */ -static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet - *new_batman_ogm_packet, - struct bat_priv *bat_priv, - int packet_len, unsigned long send_time, - bool directlink, - const struct hard_iface *if_incoming, - const struct forw_packet *forw_packet) +static bool +batadv_iv_ogm_can_aggregate(const struct batman_ogm_packet *new_bat_ogm_packet, + struct bat_priv *bat_priv, + int packet_len, unsigned long send_time, + bool directlink, + const struct hard_iface *if_incoming, + const struct forw_packet *forw_packet) { struct batman_ogm_packet *batman_ogm_packet; int aggregated_bytes = forw_packet->packet_len + packet_len; @@ -335,7 +336,7 @@ static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet * interface only - we still can aggregate */ if ((directlink) && - (new_batman_ogm_packet->header.ttl == 1) && + (new_bat_ogm_packet->header.ttl == 1) && (forw_packet->if_incoming == if_incoming) && /* packets from direct neighbors or @@ -357,11 +358,11 @@ out: } /* create a new aggregated packet and add this packet to it */ -static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff, - int packet_len, unsigned long send_time, - bool direct_link, - struct hard_iface *if_incoming, - int own_packet) +static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, + int packet_len, unsigned long send_time, + bool direct_link, + struct hard_iface *if_incoming, + int own_packet) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct forw_packet *forw_packet_aggr; @@ -435,9 +436,9 @@ out: } /* aggregate a new packet into the existing ogm packet */ -static void bat_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr, - const unsigned char *packet_buff, - int packet_len, bool direct_link) +static void batadv_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr, + const unsigned char *packet_buff, + int packet_len, bool direct_link) { unsigned char *skb_buff; @@ -452,10 +453,11 @@ static void bat_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr, (1 << forw_packet_aggr->num_packets); } -static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, - unsigned char *packet_buff, - int packet_len, struct hard_iface *if_incoming, - int own_packet, unsigned long send_time) +static void batadv_iv_ogm_queue_add(struct bat_priv *bat_priv, + unsigned char *packet_buff, + int packet_len, + struct hard_iface *if_incoming, + int own_packet, unsigned long send_time) { /* _aggr -> pointer to the packet we want to aggregate with * _pos -> pointer to the position in the queue @@ -474,11 +476,11 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, &bat_priv->forw_bat_list, list) { - if (bat_iv_ogm_can_aggregate(batman_ogm_packet, - bat_priv, packet_len, - send_time, direct_link, - if_incoming, - forw_packet_pos)) { + if (batadv_iv_ogm_can_aggregate(batman_ogm_packet, + bat_priv, packet_len, + send_time, direct_link, + if_incoming, + forw_packet_pos)) { forw_packet_aggr = forw_packet_pos; break; } @@ -500,22 +502,22 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, (atomic_read(&bat_priv->aggregated_ogms))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); - bat_iv_ogm_aggregate_new(packet_buff, packet_len, - send_time, direct_link, - if_incoming, own_packet); + batadv_iv_ogm_aggregate_new(packet_buff, packet_len, + send_time, direct_link, + if_incoming, own_packet); } else { - bat_iv_ogm_aggregate(forw_packet_aggr, packet_buff, - packet_len, direct_link); + batadv_iv_ogm_aggregate(forw_packet_aggr, packet_buff, + packet_len, direct_link); spin_unlock_bh(&bat_priv->forw_bat_list_lock); } } -static void bat_iv_ogm_forward(struct orig_node *orig_node, - const struct ethhdr *ethhdr, - struct batman_ogm_packet *batman_ogm_packet, - bool is_single_hop_neigh, - bool is_from_best_next_hop, - struct hard_iface *if_incoming) +static void batadv_iv_ogm_forward(struct orig_node *orig_node, + const struct ethhdr *ethhdr, + struct batman_ogm_packet *batman_ogm_packet, + bool is_single_hop_neigh, + bool is_from_best_next_hop, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); uint8_t tt_num_changes; @@ -544,7 +546,8 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); /* apply hop penalty */ - batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); + batman_ogm_packet->tq = batadv_hop_penalty(batman_ogm_packet->tq, + bat_priv); batadv_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: tq: %i, ttl: %i\n", @@ -557,12 +560,12 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, else batman_ogm_packet->flags &= ~DIRECTLINK; - bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, - BATMAN_OGM_HLEN + batadv_tt_len(tt_num_changes), - if_incoming, 0, bat_iv_ogm_fwd_send_time()); + batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, + BATMAN_OGM_HLEN + batadv_tt_len(tt_num_changes), + if_incoming, 0, batadv_iv_ogm_fwd_send_time()); } -static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) +static void batadv_iv_ogm_schedule(struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batman_ogm_packet *batman_ogm_packet; @@ -603,22 +606,22 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface) batman_ogm_packet->gw_flags = NO_FLAGS; batadv_slide_own_bcast_window(hard_iface); - bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, - hard_iface->packet_len, hard_iface, 1, - bat_iv_ogm_emit_send_time(bat_priv)); + batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, + hard_iface->packet_len, hard_iface, 1, + batadv_iv_ogm_emit_send_time(bat_priv)); if (primary_if) batadv_hardif_free_ref(primary_if); } -static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, - struct orig_node *orig_node, - const struct ethhdr *ethhdr, - const struct batman_ogm_packet - *batman_ogm_packet, - struct hard_iface *if_incoming, - const unsigned char *tt_buff, - int is_duplicate) +static void +batadv_iv_ogm_orig_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const struct ethhdr *ethhdr, + const struct batman_ogm_packet *batman_ogm_packet, + struct hard_iface *if_incoming, + const unsigned char *tt_buff, + int is_duplicate) { struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; struct neigh_node *router = NULL; @@ -661,9 +664,10 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, if (!orig_tmp) goto unlock; - neigh_node = bat_iv_ogm_neigh_new(if_incoming, ethhdr->h_source, - orig_node, orig_tmp, - batman_ogm_packet->seqno); + neigh_node = batadv_iv_ogm_neigh_new(if_incoming, + ethhdr->h_source, + orig_node, orig_tmp, + batman_ogm_packet->seqno); batadv_orig_node_free_ref(orig_tmp); if (!neigh_node) @@ -759,10 +763,10 @@ out: batadv_neigh_node_free_ref(router); } -static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - struct batman_ogm_packet *batman_ogm_packet, - struct hard_iface *if_incoming) +static int batadv_iv_ogm_calc_tq(struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + struct batman_ogm_packet *batman_ogm_packet, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct neigh_node *neigh_node = NULL, *tmp_neigh_node; @@ -792,11 +796,11 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, rcu_read_unlock(); if (!neigh_node) - neigh_node = bat_iv_ogm_neigh_new(if_incoming, - orig_neigh_node->orig, - orig_neigh_node, - orig_neigh_node, - batman_ogm_packet->seqno); + neigh_node = batadv_iv_ogm_neigh_new(if_incoming, + orig_neigh_node->orig, + orig_neigh_node, + orig_neigh_node, + batman_ogm_packet->seqno); if (!neigh_node) goto out; @@ -873,10 +877,10 @@ out: * -1 the packet is old and has been received while the seqno window * was protected. Caller should drop it. */ -static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, - const struct batman_ogm_packet - *batman_ogm_packet, - const struct hard_iface *if_incoming) +static int +batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, + const struct batman_ogm_packet *batman_ogm_packet, + const struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct orig_node *orig_node; @@ -943,10 +947,10 @@ out: return ret; } -static void bat_iv_ogm_process(const struct ethhdr *ethhdr, - struct batman_ogm_packet *batman_ogm_packet, - const unsigned char *tt_buff, - struct hard_iface *if_incoming) +static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, + struct batman_ogm_packet *batman_ogm_packet, + const unsigned char *tt_buff, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct hard_iface *hard_iface; @@ -955,10 +959,10 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, struct neigh_node *orig_neigh_router = NULL; int has_directlink_flag; int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; - int is_broadcast = 0, is_bidirectional; + int is_broadcast = 0, is_bidirect; bool is_single_hop_neigh = false; bool is_from_best_next_hop = false; - int is_duplicate; + int is_duplicate, sameseq, simlar_ttl; uint32_t if_incoming_seqno; uint8_t *prev_sender; @@ -1095,8 +1099,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, if (!orig_node) return; - is_duplicate = bat_iv_ogm_update_seqnos(ethhdr, batman_ogm_packet, - if_incoming); + is_duplicate = batadv_iv_ogm_update_seqnos(ethhdr, batman_ogm_packet, + if_incoming); if (is_duplicate == -1) { batadv_dbg(DBG_BATMAN, bat_priv, @@ -1151,8 +1155,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, goto out_neigh; } - is_bidirectional = bat_iv_ogm_calc_tq(orig_node, orig_neigh_node, - batman_ogm_packet, if_incoming); + is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node, + batman_ogm_packet, if_incoming); batadv_bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet); @@ -1160,21 +1164,20 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, /* update ranking if it is not a duplicate or has the same * seqno and similar ttl as the non-duplicate */ - if (is_bidirectional && - (!is_duplicate || - ((orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno)) && - (orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl)))) - bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, - batman_ogm_packet, if_incoming, - tt_buff, is_duplicate); + sameseq = orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno); + simlar_ttl = orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl; + if (is_bidirect && (!is_duplicate || (sameseq && simlar_ttl))) + batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, + batman_ogm_packet, if_incoming, + tt_buff, is_duplicate); /* is single hop (direct) neighbor */ if (is_single_hop_neigh) { /* mark direct link on incoming interface */ - bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - is_single_hop_neigh, is_from_best_next_hop, - if_incoming); + batadv_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, + is_single_hop_neigh, + is_from_best_next_hop, if_incoming); batadv_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); @@ -1182,7 +1185,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, } /* multihop originator */ - if (!is_bidirectional) { + if (!is_bidirect) { batadv_dbg(DBG_BATMAN, bat_priv, "Drop packet: not received via bidirectional link\n"); goto out_neigh; @@ -1196,9 +1199,9 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, batadv_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast originator packet\n"); - bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - is_single_hop_neigh, is_from_best_next_hop, - if_incoming); + batadv_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, + is_single_hop_neigh, is_from_best_next_hop, + if_incoming); out_neigh: if ((orig_neigh_node) && (!is_single_hop_neigh)) @@ -1214,8 +1217,8 @@ out: batadv_orig_node_free_ref(orig_node); } -static int bat_iv_ogm_receive(struct sk_buff *skb, - struct hard_iface *if_incoming) +static int batadv_iv_ogm_receive(struct sk_buff *skb, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batman_ogm_packet *batman_ogm_packet; @@ -1231,7 +1234,7 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface * that does not have B.A.T.M.A.N. IV enabled ? */ - if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) + if (bat_priv->bat_algo_ops->bat_ogm_emit != batadv_iv_ogm_emit) return NET_RX_DROP; batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX); @@ -1247,29 +1250,29 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, do { tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN; - bat_iv_ogm_process(ethhdr, batman_ogm_packet, - tt_buff, if_incoming); + batadv_iv_ogm_process(ethhdr, batman_ogm_packet, tt_buff, + if_incoming); buff_pos += BATMAN_OGM_HLEN; buff_pos += batadv_tt_len(batman_ogm_packet->tt_num_changes); batman_ogm_packet = (struct batman_ogm_packet *) (packet_buff + buff_pos); - } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, - batman_ogm_packet->tt_num_changes)); + } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len, + batman_ogm_packet->tt_num_changes)); kfree_skb(skb); return NET_RX_SUCCESS; } -static struct bat_algo_ops batman_iv __read_mostly = { +static struct bat_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", - .bat_iface_enable = bat_iv_ogm_iface_enable, - .bat_iface_disable = bat_iv_ogm_iface_disable, - .bat_iface_update_mac = bat_iv_ogm_iface_update_mac, - .bat_primary_iface_set = bat_iv_ogm_primary_iface_set, - .bat_ogm_schedule = bat_iv_ogm_schedule, - .bat_ogm_emit = bat_iv_ogm_emit, + .bat_iface_enable = batadv_iv_ogm_iface_enable, + .bat_iface_disable = batadv_iv_ogm_iface_disable, + .bat_iface_update_mac = batadv_iv_ogm_iface_update_mac, + .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set, + .bat_ogm_schedule = batadv_iv_ogm_schedule, + .bat_ogm_emit = batadv_iv_ogm_emit, }; int __init batadv_iv_init(void) @@ -1277,11 +1280,11 @@ int __init batadv_iv_init(void) int ret; /* batman originator packet */ - ret = batadv_recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); + ret = batadv_recv_handler_register(BAT_IV_OGM, batadv_iv_ogm_receive); if (ret < 0) goto out; - ret = batadv_algo_register(&batman_iv); + ret = batadv_algo_register(&batadv_batman_iv); if (ret < 0) goto handler_unregister; -- GitLab From 0ff9b86feb6ee50171dcf5635520c91757b3d5e9 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:52 +0200 Subject: [PATCH 2622/6849] batman-adv: Prefix bat_sysfs local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 255 ++++++++++++++++++++----------------- 1 file changed, 138 insertions(+), 117 deletions(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 7f464a9e9672..03b76a41ac4e 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -26,15 +26,15 @@ #include "gateway_client.h" #include "vis.h" -static struct net_device *kobj_to_netdev(struct kobject *obj) +static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) { struct device *dev = container_of(obj->parent, struct device, kobj); return to_net_dev(dev); } -static struct bat_priv *kobj_to_batpriv(struct kobject *obj) +static struct bat_priv *batadv_kobj_to_batpriv(struct kobject *obj) { - struct net_device *net_dev = kobj_to_netdev(obj); + struct net_device *net_dev = batadv_kobj_to_netdev(obj); return netdev_priv(net_dev); } @@ -42,19 +42,19 @@ static struct bat_priv *kobj_to_batpriv(struct kobject *obj) #define UEV_ACTION_VAR "BATACTION=" #define UEV_DATA_VAR "BATDATA=" -static char *uev_action_str[] = { +static char *batadv_uev_action_str[] = { "add", "del", "change" }; -static char *uev_type_str[] = { +static char *batadv_uev_type_str[] = { "gw" }; /* Use this, if you have customized show and store functions */ #define BAT_ATTR(_name, _mode, _show, _store) \ -struct bat_attribute bat_attr_##_name = { \ +struct bat_attribute batadv_attr_##_name = { \ .attr = {.name = __stringify(_name), \ .mode = _mode }, \ .show = _show, \ @@ -62,20 +62,21 @@ struct bat_attribute bat_attr_##_name = { \ }; #define BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ -ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ +ssize_t batadv_store_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff, \ + size_t count) \ { \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ struct bat_priv *bat_priv = netdev_priv(net_dev); \ - return __store_bool_attr(buff, count, _post_func, attr, \ - &bat_priv->_name, net_dev); \ + return __batadv_store_bool_attr(buff, count, _post_func, attr, \ + &bat_priv->_name, net_dev); \ } #define BAT_ATTR_SIF_SHOW_BOOL(_name) \ -ssize_t show_##_name(struct kobject *kobj, \ - struct attribute *attr, char *buff) \ +ssize_t batadv_show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ { \ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ + struct bat_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \ return sprintf(buff, "%s\n", \ atomic_read(&bat_priv->_name) == 0 ? \ "disabled" : "enabled"); \ @@ -87,24 +88,27 @@ ssize_t show_##_name(struct kobject *kobj, \ #define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \ static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ static BAT_ATTR_SIF_SHOW_BOOL(_name) \ - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + static BAT_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) #define BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ -ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ +ssize_t batadv_store_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff, \ + size_t count) \ { \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ struct bat_priv *bat_priv = netdev_priv(net_dev); \ - return __store_uint_attr(buff, count, _min, _max, _post_func, \ - attr, &bat_priv->_name, net_dev); \ + return __batadv_store_uint_attr(buff, count, _min, _max, \ + _post_func, attr, \ + &bat_priv->_name, net_dev); \ } #define BAT_ATTR_SIF_SHOW_UINT(_name) \ -ssize_t show_##_name(struct kobject *kobj, \ - struct attribute *attr, char *buff) \ +ssize_t batadv_show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ { \ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ + struct bat_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \ return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ } \ @@ -114,14 +118,16 @@ ssize_t show_##_name(struct kobject *kobj, \ #define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ static BAT_ATTR_SIF_SHOW_UINT(_name) \ - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + static BAT_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) #define BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ -ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ +ssize_t batadv_store_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff, \ + size_t count) \ { \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ struct hard_iface *hard_iface; \ ssize_t length; \ \ @@ -129,18 +135,19 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ if (!hard_iface) \ return 0; \ \ - length = __store_uint_attr(buff, count, _min, _max, _post_func, \ - attr, &hard_iface->_name, net_dev); \ + length = __batadv_store_uint_attr(buff, count, _min, _max, \ + _post_func, attr, \ + &hard_iface->_name, net_dev); \ \ batadv_hardif_free_ref(hard_iface); \ return length; \ } #define BAT_ATTR_HIF_SHOW_UINT(_name) \ -ssize_t show_##_name(struct kobject *kobj, \ - struct attribute *attr, char *buff) \ +ssize_t batadv_show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ { \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ struct hard_iface *hard_iface; \ ssize_t length; \ \ @@ -160,12 +167,13 @@ ssize_t show_##_name(struct kobject *kobj, \ #define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ static BAT_ATTR_HIF_SHOW_UINT(_name) \ - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + static BAT_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) -static int store_bool_attr(char *buff, size_t count, - struct net_device *net_dev, - const char *attr_name, atomic_t *attr) +static int batadv_store_bool_attr(char *buff, size_t count, + struct net_device *net_dev, + const char *attr_name, atomic_t *attr) { int enabled = -1; @@ -200,23 +208,27 @@ static int store_bool_attr(char *buff, size_t count, return count; } -static inline ssize_t __store_bool_attr(char *buff, size_t count, - void (*post_func)(struct net_device *), - struct attribute *attr, - atomic_t *attr_store, struct net_device *net_dev) +static inline ssize_t +__batadv_store_bool_attr(char *buff, size_t count, + void (*post_func)(struct net_device *), + struct attribute *attr, + atomic_t *attr_store, struct net_device *net_dev) { int ret; - ret = store_bool_attr(buff, count, net_dev, attr->name, attr_store); + ret = batadv_store_bool_attr(buff, count, net_dev, attr->name, + attr_store); if (post_func && ret) post_func(net_dev); return ret; } -static int store_uint_attr(const char *buff, size_t count, - struct net_device *net_dev, const char *attr_name, - unsigned int min, unsigned int max, atomic_t *attr) +static int batadv_store_uint_attr(const char *buff, size_t count, + struct net_device *net_dev, + const char *attr_name, + unsigned int min, unsigned int max, + atomic_t *attr) { unsigned long uint_val; int ret; @@ -251,26 +263,27 @@ static int store_uint_attr(const char *buff, size_t count, return count; } -static inline ssize_t __store_uint_attr(const char *buff, size_t count, - int min, int max, - void (*post_func)(struct net_device *), - const struct attribute *attr, - atomic_t *attr_store, struct net_device *net_dev) +static inline ssize_t +__batadv_store_uint_attr(const char *buff, size_t count, + int min, int max, + void (*post_func)(struct net_device *), + const struct attribute *attr, + atomic_t *attr_store, struct net_device *net_dev) { int ret; - ret = store_uint_attr(buff, count, net_dev, attr->name, - min, max, attr_store); + ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max, + attr_store); if (post_func && ret) post_func(net_dev); return ret; } -static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, - char *buff) +static ssize_t batadv_show_vis_mode(struct kobject *kobj, + struct attribute *attr, char *buff) { - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + struct bat_priv *bat_priv = batadv_kobj_to_batpriv(kobj); int vis_mode = atomic_read(&bat_priv->vis_mode); return sprintf(buff, "%s\n", @@ -278,10 +291,11 @@ static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, "client" : "server"); } -static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +static ssize_t batadv_store_vis_mode(struct kobject *kobj, + struct attribute *attr, char *buff, + size_t count) { - struct net_device *net_dev = kobj_to_netdev(kobj); + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct bat_priv *bat_priv = netdev_priv(net_dev); unsigned long val; int ret, vis_mode_tmp = -1; @@ -319,23 +333,23 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, return count; } -static ssize_t show_bat_algo(struct kobject *kobj, struct attribute *attr, - char *buff) +static ssize_t batadv_show_bat_algo(struct kobject *kobj, + struct attribute *attr, char *buff) { - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + struct bat_priv *bat_priv = batadv_kobj_to_batpriv(kobj); return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name); } -static void post_gw_deselect(struct net_device *net_dev) +static void batadv_post_gw_deselect(struct net_device *net_dev) { struct bat_priv *bat_priv = netdev_priv(net_dev); batadv_gw_deselect(bat_priv); } -static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, - char *buff) +static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr, + char *buff) { - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + struct bat_priv *bat_priv = batadv_kobj_to_batpriv(kobj); int bytes_written; switch (atomic_read(&bat_priv->gw_mode)) { @@ -353,10 +367,11 @@ static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, return bytes_written; } -static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +static ssize_t batadv_store_gw_mode(struct kobject *kobj, + struct attribute *attr, char *buff, + size_t count) { - struct net_device *net_dev = kobj_to_netdev(kobj); + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct bat_priv *bat_priv = netdev_priv(net_dev); char *curr_gw_mode_str; int gw_mode_tmp = -1; @@ -405,10 +420,10 @@ static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, return count; } -static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, - char *buff) +static ssize_t batadv_show_gw_bwidth(struct kobject *kobj, + struct attribute *attr, char *buff) { - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + struct bat_priv *bat_priv = batadv_kobj_to_batpriv(kobj); int down, up; int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); @@ -420,10 +435,11 @@ static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, (up > 2048 ? "MBit" : "KBit")); } -static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +static ssize_t batadv_store_gw_bwidth(struct kobject *kobj, + struct attribute *attr, char *buff, + size_t count) { - struct net_device *net_dev = kobj_to_netdev(kobj); + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); if (buff[count - 1] == '\n') buff[count - 1] = '\0'; @@ -438,36 +454,38 @@ BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); #endif BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); -static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); -static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL); -static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); +static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, + batadv_store_vis_mode); +static BAT_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); +static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, + batadv_store_gw_mode); BAT_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); BAT_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, - post_gw_deselect); -static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, - store_gw_bwidth); + batadv_post_gw_deselect); +static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, + batadv_store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, DBG_ALL, NULL); #endif -static struct bat_attribute *mesh_attrs[] = { - &bat_attr_aggregated_ogms, - &bat_attr_bonding, +static struct bat_attribute *batadv_mesh_attrs[] = { + &batadv_attr_aggregated_ogms, + &batadv_attr_bonding, #ifdef CONFIG_BATMAN_ADV_BLA - &bat_attr_bridge_loop_avoidance, + &batadv_attr_bridge_loop_avoidance, #endif - &bat_attr_fragmentation, - &bat_attr_ap_isolation, - &bat_attr_vis_mode, - &bat_attr_routing_algo, - &bat_attr_gw_mode, - &bat_attr_orig_interval, - &bat_attr_hop_penalty, - &bat_attr_gw_sel_class, - &bat_attr_gw_bandwidth, + &batadv_attr_fragmentation, + &batadv_attr_ap_isolation, + &batadv_attr_vis_mode, + &batadv_attr_routing_algo, + &batadv_attr_gw_mode, + &batadv_attr_orig_interval, + &batadv_attr_hop_penalty, + &batadv_attr_gw_sel_class, + &batadv_attr_gw_bandwidth, #ifdef CONFIG_BATMAN_ADV_DEBUG - &bat_attr_log_level, + &batadv_attr_log_level, #endif NULL, }; @@ -487,7 +505,7 @@ int batadv_sysfs_add_meshif(struct net_device *dev) goto out; } - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { + for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) { err = sysfs_create_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); if (err) { @@ -501,7 +519,7 @@ int batadv_sysfs_add_meshif(struct net_device *dev) return 0; rem_attr: - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); kobject_put(bat_priv->mesh_obj); @@ -515,17 +533,17 @@ void batadv_sysfs_del_meshif(struct net_device *dev) struct bat_priv *bat_priv = netdev_priv(dev); struct bat_attribute **bat_attr; - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); kobject_put(bat_priv->mesh_obj); bat_priv->mesh_obj = NULL; } -static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, - char *buff) +static ssize_t batadv_show_mesh_iface(struct kobject *kobj, + struct attribute *attr, char *buff) { - struct net_device *net_dev = kobj_to_netdev(kobj); + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); ssize_t length; @@ -540,10 +558,11 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, return length; } -static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +static ssize_t batadv_store_mesh_iface(struct kobject *kobj, + struct attribute *attr, char *buff, + size_t count) { - struct net_device *net_dev = kobj_to_netdev(kobj); + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); int status_tmp = -1; int ret = count; @@ -596,10 +615,10 @@ out: return ret; } -static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, - char *buff) +static ssize_t batadv_show_iface_status(struct kobject *kobj, + struct attribute *attr, char *buff) { - struct net_device *net_dev = kobj_to_netdev(kobj); + struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); ssize_t length; @@ -631,12 +650,12 @@ static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, } static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR, - show_mesh_iface, store_mesh_iface); -static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); + batadv_show_mesh_iface, batadv_store_mesh_iface); +static BAT_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL); -static struct bat_attribute *batman_attrs[] = { - &bat_attr_mesh_iface, - &bat_attr_iface_status, +static struct bat_attribute *batadv_batman_attrs[] = { + &batadv_attr_mesh_iface, + &batadv_attr_iface_status, NULL, }; @@ -655,7 +674,7 @@ int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) goto out; } - for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) { + for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) { err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); if (err) { bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", @@ -668,7 +687,7 @@ int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) return 0; rem_attr: - for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) + for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); out: return -ENOMEM; @@ -695,20 +714,21 @@ int batadv_throw_uevent(struct bat_priv *bat_priv, enum uev_type type, bat_kobj = &primary_if->soft_iface->dev.kobj; uevent_env[0] = kmalloc(strlen(UEV_TYPE_VAR) + - strlen(uev_type_str[type]) + 1, + strlen(batadv_uev_type_str[type]) + 1, GFP_ATOMIC); if (!uevent_env[0]) goto out; - sprintf(uevent_env[0], "%s%s", UEV_TYPE_VAR, uev_type_str[type]); + sprintf(uevent_env[0], "%s%s", UEV_TYPE_VAR, batadv_uev_type_str[type]); uevent_env[1] = kmalloc(strlen(UEV_ACTION_VAR) + - strlen(uev_action_str[action]) + 1, + strlen(batadv_uev_action_str[action]) + 1, GFP_ATOMIC); if (!uevent_env[1]) goto out; - sprintf(uevent_env[1], "%s%s", UEV_ACTION_VAR, uev_action_str[action]); + sprintf(uevent_env[1], "%s%s", UEV_ACTION_VAR, + batadv_uev_action_str[action]); /* If the event is DEL, ignore the data field */ if (action != UEV_DEL) { @@ -732,7 +752,8 @@ out: if (ret) batadv_dbg(DBG_BATMAN, bat_priv, "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n", - uev_type_str[type], uev_action_str[action], + batadv_uev_type_str[type], + batadv_uev_action_str[action], (action == UEV_DEL ? "NULL" : data), ret); return ret; } -- GitLab From 3b300de322014f529b2e0a72a92c414686b85671 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:53 +0200 Subject: [PATCH 2623/6849] batman-adv: Prefix bridge_loop_avoidance local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 320 +++++++++++++------------ 1 file changed, 168 insertions(+), 152 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index b7d70845aa4a..0592d2bcb9b5 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -31,14 +31,14 @@ #include #include -static const uint8_t announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; +static const uint8_t batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; -static void bla_periodic_work(struct work_struct *work); -static void bla_send_announce(struct bat_priv *bat_priv, - struct backbone_gw *backbone_gw); +static void batadv_bla_periodic_work(struct work_struct *work); +static void batadv_bla_send_announce(struct bat_priv *bat_priv, + struct backbone_gw *backbone_gw); /* return the index of the claim */ -static inline uint32_t choose_claim(const void *data, uint32_t size) +static inline uint32_t batadv_choose_claim(const void *data, uint32_t size) { const unsigned char *key = data; uint32_t hash = 0; @@ -58,7 +58,8 @@ static inline uint32_t choose_claim(const void *data, uint32_t size) } /* return the index of the backbone gateway */ -static inline uint32_t choose_backbone_gw(const void *data, uint32_t size) +static inline uint32_t batadv_choose_backbone_gw(const void *data, + uint32_t size) { const unsigned char *key = data; uint32_t hash = 0; @@ -79,7 +80,8 @@ static inline uint32_t choose_backbone_gw(const void *data, uint32_t size) /* compares address and vid of two backbone gws */ -static int compare_backbone_gw(const struct hlist_node *node, const void *data2) +static int batadv_compare_backbone_gw(const struct hlist_node *node, + const void *data2) { const void *data1 = container_of(node, struct backbone_gw, hash_entry); @@ -88,7 +90,8 @@ static int compare_backbone_gw(const struct hlist_node *node, const void *data2) } /* compares address and vid of two claims */ -static int compare_claim(const struct hlist_node *node, const void *data2) +static int batadv_compare_claim(const struct hlist_node *node, + const void *data2) { const void *data1 = container_of(node, struct claim, hash_entry); @@ -97,28 +100,28 @@ static int compare_claim(const struct hlist_node *node, const void *data2) } /* free a backbone gw */ -static void backbone_gw_free_ref(struct backbone_gw *backbone_gw) +static void batadv_backbone_gw_free_ref(struct backbone_gw *backbone_gw) { if (atomic_dec_and_test(&backbone_gw->refcount)) kfree_rcu(backbone_gw, rcu); } /* finally deinitialize the claim */ -static void claim_free_rcu(struct rcu_head *rcu) +static void batadv_claim_free_rcu(struct rcu_head *rcu) { struct claim *claim; claim = container_of(rcu, struct claim, rcu); - backbone_gw_free_ref(claim->backbone_gw); + batadv_backbone_gw_free_ref(claim->backbone_gw); kfree(claim); } /* free a claim, call claim_free_rcu if its the last reference */ -static void claim_free_ref(struct claim *claim) +static void batadv_claim_free_ref(struct claim *claim) { if (atomic_dec_and_test(&claim->refcount)) - call_rcu(&claim->rcu, claim_free_rcu); + call_rcu(&claim->rcu, batadv_claim_free_rcu); } /* @bat_priv: the bat priv with all the soft interface information @@ -127,8 +130,8 @@ static void claim_free_ref(struct claim *claim) * looks for a claim in the hash, and returns it if found * or NULL otherwise. */ -static struct claim *claim_hash_find(struct bat_priv *bat_priv, - struct claim *data) +static struct claim *batadv_claim_hash_find(struct bat_priv *bat_priv, + struct claim *data) { struct hashtable_t *hash = bat_priv->claim_hash; struct hlist_head *head; @@ -140,12 +143,12 @@ static struct claim *claim_hash_find(struct bat_priv *bat_priv, if (!hash) return NULL; - index = choose_claim(data, hash->size); + index = batadv_choose_claim(data, hash->size); head = &hash->table[index]; rcu_read_lock(); hlist_for_each_entry_rcu(claim, node, head, hash_entry) { - if (!compare_claim(&claim->hash_entry, data)) + if (!batadv_compare_claim(&claim->hash_entry, data)) continue; if (!atomic_inc_not_zero(&claim->refcount)) @@ -166,8 +169,8 @@ static struct claim *claim_hash_find(struct bat_priv *bat_priv, * looks for a claim in the hash, and returns it if found * or NULL otherwise. */ -static struct backbone_gw *backbone_hash_find(struct bat_priv *bat_priv, - uint8_t *addr, short vid) +static struct backbone_gw *batadv_backbone_hash_find(struct bat_priv *bat_priv, + uint8_t *addr, short vid) { struct hashtable_t *hash = bat_priv->backbone_hash; struct hlist_head *head; @@ -182,13 +185,13 @@ static struct backbone_gw *backbone_hash_find(struct bat_priv *bat_priv, memcpy(search_entry.orig, addr, ETH_ALEN); search_entry.vid = vid; - index = choose_backbone_gw(&search_entry, hash->size); + index = batadv_choose_backbone_gw(&search_entry, hash->size); head = &hash->table[index]; rcu_read_lock(); hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { - if (!compare_backbone_gw(&backbone_gw->hash_entry, - &search_entry)) + if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry, + &search_entry)) continue; if (!atomic_inc_not_zero(&backbone_gw->refcount)) @@ -203,7 +206,7 @@ static struct backbone_gw *backbone_hash_find(struct bat_priv *bat_priv, } /* delete all claims for a backbone */ -static void bla_del_backbone_claims(struct backbone_gw *backbone_gw) +static void batadv_bla_del_backbone_claims(struct backbone_gw *backbone_gw) { struct hashtable_t *hash; struct hlist_node *node, *node_tmp; @@ -227,7 +230,7 @@ static void bla_del_backbone_claims(struct backbone_gw *backbone_gw) if (claim->backbone_gw != backbone_gw) continue; - claim_free_ref(claim); + batadv_claim_free_ref(claim); hlist_del_rcu(node); } spin_unlock_bh(list_lock); @@ -244,8 +247,8 @@ static void bla_del_backbone_claims(struct backbone_gw *backbone_gw) * * sends a claim frame according to the provided info. */ -static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, - short vid, int claimtype) +static void batadv_bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac, + short vid, int claimtype) { struct sk_buff *skb; struct ethhdr *ethhdr; @@ -350,14 +353,14 @@ out: * searches for the backbone gw or creates a new one if it could not * be found. */ -static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, - uint8_t *orig, short vid) +static struct backbone_gw *batadv_bla_get_backbone_gw(struct bat_priv *bat_priv, + uint8_t *orig, short vid) { struct backbone_gw *entry; struct orig_node *orig_node; int hash_added; - entry = backbone_hash_find(bat_priv, orig, vid); + entry = batadv_backbone_hash_find(bat_priv, orig, vid); if (entry) return entry; @@ -381,8 +384,9 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, atomic_set(&entry->refcount, 2); hash_added = batadv_hash_add(bat_priv->backbone_hash, - compare_backbone_gw, choose_backbone_gw, - entry, &entry->hash_entry); + batadv_compare_backbone_gw, + batadv_choose_backbone_gw, entry, + &entry->hash_entry); if (unlikely(hash_added != 0)) { /* hash failed, free the structure */ @@ -403,19 +407,20 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv, /* update or add the own backbone gw to make sure we announce * where we receive other backbone gws */ -static void bla_update_own_backbone_gw(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - short vid) +static void batadv_bla_update_own_backbone_gw(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + short vid) { struct backbone_gw *backbone_gw; - backbone_gw = bla_get_backbone_gw(bat_priv, - primary_if->net_dev->dev_addr, vid); + backbone_gw = batadv_bla_get_backbone_gw(bat_priv, + primary_if->net_dev->dev_addr, + vid); if (unlikely(!backbone_gw)) return; backbone_gw->lasttime = jiffies; - backbone_gw_free_ref(backbone_gw); + batadv_backbone_gw_free_ref(backbone_gw); } /* @bat_priv: the bat priv with all the soft interface information @@ -424,8 +429,8 @@ static void bla_update_own_backbone_gw(struct bat_priv *bat_priv, * Repeat all of our own claims, and finally send an ANNOUNCE frame * to allow the requester another check if the CRC is correct now. */ -static void bla_answer_request(struct bat_priv *bat_priv, - struct hard_iface *primary_if, short vid) +static void batadv_bla_answer_request(struct bat_priv *bat_priv, + struct hard_iface *primary_if, short vid) { struct hlist_node *node; struct hlist_head *head; @@ -437,8 +442,9 @@ static void bla_answer_request(struct bat_priv *bat_priv, batadv_dbg(DBG_BLA, bat_priv, "bla_answer_request(): received a claim request, send all of our own claims again\n"); - backbone_gw = backbone_hash_find(bat_priv, - primary_if->net_dev->dev_addr, vid); + backbone_gw = batadv_backbone_hash_find(bat_priv, + primary_if->net_dev->dev_addr, + vid); if (!backbone_gw) return; @@ -452,15 +458,15 @@ static void bla_answer_request(struct bat_priv *bat_priv, if (claim->backbone_gw != backbone_gw) continue; - bla_send_claim(bat_priv, claim->addr, claim->vid, - CLAIM_TYPE_ADD); + batadv_bla_send_claim(bat_priv, claim->addr, claim->vid, + CLAIM_TYPE_ADD); } rcu_read_unlock(); } /* finally, send an announcement frame */ - bla_send_announce(bat_priv, backbone_gw); - backbone_gw_free_ref(backbone_gw); + batadv_bla_send_announce(bat_priv, backbone_gw); + batadv_backbone_gw_free_ref(backbone_gw); } /* @backbone_gw: the backbone gateway from whom we are out of sync @@ -469,17 +475,17 @@ static void bla_answer_request(struct bat_priv *bat_priv, * After the request, it will repeat all of his own claims and finally * send an announcement claim with which we can check again. */ -static void bla_send_request(struct backbone_gw *backbone_gw) +static void batadv_bla_send_request(struct backbone_gw *backbone_gw) { /* first, remove all old entries */ - bla_del_backbone_claims(backbone_gw); + batadv_bla_del_backbone_claims(backbone_gw); batadv_dbg(DBG_BLA, backbone_gw->bat_priv, "Sending REQUEST to %pM\n", backbone_gw->orig); /* send request */ - bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig, - backbone_gw->vid, CLAIM_TYPE_REQUEST); + batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig, + backbone_gw->vid, CLAIM_TYPE_REQUEST); /* no local broadcasts should be sent or received, for now. */ if (!atomic_read(&backbone_gw->request_sent)) { @@ -494,17 +500,18 @@ static void bla_send_request(struct backbone_gw *backbone_gw) * This function sends an announcement. It is called from multiple * places. */ -static void bla_send_announce(struct bat_priv *bat_priv, - struct backbone_gw *backbone_gw) +static void batadv_bla_send_announce(struct bat_priv *bat_priv, + struct backbone_gw *backbone_gw) { uint8_t mac[ETH_ALEN]; __be16 crc; - memcpy(mac, announce_mac, 4); + memcpy(mac, batadv_announce_mac, 4); crc = htons(backbone_gw->crc); memcpy(&mac[4], &crc, 2); - bla_send_claim(bat_priv, mac, backbone_gw->vid, CLAIM_TYPE_ANNOUNCE); + batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid, + CLAIM_TYPE_ANNOUNCE); } @@ -515,8 +522,9 @@ static void bla_send_announce(struct bat_priv *bat_priv, * * Adds a claim in the claim hash. */ -static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, - const short vid, struct backbone_gw *backbone_gw) +static void batadv_bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, + const short vid, + struct backbone_gw *backbone_gw) { struct claim *claim; struct claim search_claim; @@ -524,7 +532,7 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, memcpy(search_claim.addr, mac, ETH_ALEN); search_claim.vid = vid; - claim = claim_hash_find(bat_priv, &search_claim); + claim = batadv_claim_hash_find(bat_priv, &search_claim); /* create a new claim entry if it does not exist yet. */ if (!claim) { @@ -542,8 +550,9 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", mac, vid); hash_added = batadv_hash_add(bat_priv->claim_hash, - compare_claim, choose_claim, - claim, &claim->hash_entry); + batadv_compare_claim, + batadv_choose_claim, claim, + &claim->hash_entry); if (unlikely(hash_added != 0)) { /* only local changes happened. */ @@ -562,7 +571,7 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); - backbone_gw_free_ref(claim->backbone_gw); + batadv_backbone_gw_free_ref(claim->backbone_gw); } /* set (new) backbone gw */ @@ -573,47 +582,48 @@ static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac, backbone_gw->lasttime = jiffies; claim_free_ref: - claim_free_ref(claim); + batadv_claim_free_ref(claim); } /* Delete a claim from the claim hash which has the * given mac address and vid. */ -static void bla_del_claim(struct bat_priv *bat_priv, const uint8_t *mac, - const short vid) +static void batadv_bla_del_claim(struct bat_priv *bat_priv, const uint8_t *mac, + const short vid) { struct claim search_claim, *claim; memcpy(search_claim.addr, mac, ETH_ALEN); search_claim.vid = vid; - claim = claim_hash_find(bat_priv, &search_claim); + claim = batadv_claim_hash_find(bat_priv, &search_claim); if (!claim) return; batadv_dbg(DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid); - batadv_hash_remove(bat_priv->claim_hash, compare_claim, choose_claim, - claim); - claim_free_ref(claim); /* reference from the hash is gone */ + batadv_hash_remove(bat_priv->claim_hash, batadv_compare_claim, + batadv_choose_claim, claim); + batadv_claim_free_ref(claim); /* reference from the hash is gone */ claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); /* don't need the reference from hash_find() anymore */ - claim_free_ref(claim); + batadv_claim_free_ref(claim); } /* check for ANNOUNCE frame, return 1 if handled */ -static int handle_announce(struct bat_priv *bat_priv, - uint8_t *an_addr, uint8_t *backbone_addr, short vid) +static int batadv_handle_announce(struct bat_priv *bat_priv, + uint8_t *an_addr, uint8_t *backbone_addr, + short vid) { struct backbone_gw *backbone_gw; uint16_t crc; - if (memcmp(an_addr, announce_mac, 4) != 0) + if (memcmp(an_addr, batadv_announce_mac, 4) != 0) return 0; - backbone_gw = bla_get_backbone_gw(bat_priv, backbone_addr, vid); + backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid); if (unlikely(!backbone_gw)) return 1; @@ -633,7 +643,7 @@ static int handle_announce(struct bat_priv *bat_priv, backbone_gw->orig, backbone_gw->vid, backbone_gw->crc, crc); - bla_send_request(backbone_gw); + batadv_bla_send_request(backbone_gw); } else { /* if we have sent a request and the crc was OK, * we can allow traffic again. @@ -644,15 +654,15 @@ static int handle_announce(struct bat_priv *bat_priv, } } - backbone_gw_free_ref(backbone_gw); + batadv_backbone_gw_free_ref(backbone_gw); return 1; } /* check for REQUEST frame, return 1 if handled */ -static int handle_request(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - uint8_t *backbone_addr, - struct ethhdr *ethhdr, short vid) +static int batadv_handle_request(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + uint8_t *backbone_addr, + struct ethhdr *ethhdr, short vid) { /* check for REQUEST frame */ if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest)) @@ -668,24 +678,25 @@ static int handle_request(struct bat_priv *bat_priv, "handle_request(): REQUEST vid %d (sent by %pM)...\n", vid, ethhdr->h_source); - bla_answer_request(bat_priv, primary_if, vid); + batadv_bla_answer_request(bat_priv, primary_if, vid); return 1; } /* check for UNCLAIM frame, return 1 if handled */ -static int handle_unclaim(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - uint8_t *backbone_addr, - uint8_t *claim_addr, short vid) +static int batadv_handle_unclaim(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + uint8_t *backbone_addr, + uint8_t *claim_addr, short vid) { struct backbone_gw *backbone_gw; /* unclaim in any case if it is our own */ if (primary_if && batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) - bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_DEL); + batadv_bla_send_claim(bat_priv, claim_addr, vid, + CLAIM_TYPE_DEL); - backbone_gw = backbone_hash_find(bat_priv, backbone_addr, vid); + backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid); if (!backbone_gw) return 1; @@ -695,33 +706,35 @@ static int handle_unclaim(struct bat_priv *bat_priv, "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n", claim_addr, vid, backbone_gw->orig); - bla_del_claim(bat_priv, claim_addr, vid); - backbone_gw_free_ref(backbone_gw); + batadv_bla_del_claim(bat_priv, claim_addr, vid); + batadv_backbone_gw_free_ref(backbone_gw); return 1; } /* check for CLAIM frame, return 1 if handled */ -static int handle_claim(struct bat_priv *bat_priv, - struct hard_iface *primary_if, uint8_t *backbone_addr, - uint8_t *claim_addr, short vid) +static int batadv_handle_claim(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + uint8_t *backbone_addr, uint8_t *claim_addr, + short vid) { struct backbone_gw *backbone_gw; /* register the gateway if not yet available, and add the claim. */ - backbone_gw = bla_get_backbone_gw(bat_priv, backbone_addr, vid); + backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid); if (unlikely(!backbone_gw)) return 1; /* this must be a CLAIM frame */ - bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); + batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) - bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_ADD); + batadv_bla_send_claim(bat_priv, claim_addr, vid, + CLAIM_TYPE_ADD); /* TODO: we could call something like tt_local_del() here. */ - backbone_gw_free_ref(backbone_gw); + batadv_backbone_gw_free_ref(backbone_gw); return 1; } @@ -739,10 +752,10 @@ static int handle_claim(struct bat_priv *bat_priv, * 1 - if is a claim packet from another group * 0 - if it is not a claim packet */ -static int check_claim_group(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - uint8_t *hw_src, uint8_t *hw_dst, - struct ethhdr *ethhdr) +static int batadv_check_claim_group(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + uint8_t *hw_src, uint8_t *hw_dst, + struct ethhdr *ethhdr) { uint8_t *backbone_addr; struct orig_node *orig_node; @@ -811,9 +824,9 @@ static int check_claim_group(struct bat_priv *bat_priv, * returns 1 if it was a claim frame, otherwise return 0 to * tell the callee that it can use the frame on its own. */ -static int bla_process_claim(struct bat_priv *bat_priv, - struct hard_iface *primary_if, - struct sk_buff *skb) +static int batadv_bla_process_claim(struct bat_priv *bat_priv, + struct hard_iface *primary_if, + struct sk_buff *skb) { struct ethhdr *ethhdr; struct vlan_ethhdr *vhdr; @@ -866,7 +879,8 @@ static int bla_process_claim(struct bat_priv *bat_priv, bla_dst = (struct bla_claim_dst *)hw_dst; /* check if it is a claim frame. */ - ret = check_claim_group(bat_priv, primary_if, hw_src, hw_dst, ethhdr); + ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, + ethhdr); if (ret == 1) batadv_dbg(DBG_BLA, bat_priv, "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n", @@ -876,27 +890,29 @@ static int bla_process_claim(struct bat_priv *bat_priv, return ret; /* become a backbone gw ourselves on this vlan if not happened yet */ - bla_update_own_backbone_gw(bat_priv, primary_if, vid); + batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); /* check for the different types of claim frames ... */ switch (bla_dst->type) { case CLAIM_TYPE_ADD: - if (handle_claim(bat_priv, primary_if, hw_src, - ethhdr->h_source, vid)) + if (batadv_handle_claim(bat_priv, primary_if, hw_src, + ethhdr->h_source, vid)) return 1; break; case CLAIM_TYPE_DEL: - if (handle_unclaim(bat_priv, primary_if, - ethhdr->h_source, hw_src, vid)) + if (batadv_handle_unclaim(bat_priv, primary_if, + ethhdr->h_source, hw_src, vid)) return 1; break; case CLAIM_TYPE_ANNOUNCE: - if (handle_announce(bat_priv, hw_src, ethhdr->h_source, vid)) + if (batadv_handle_announce(bat_priv, hw_src, ethhdr->h_source, + vid)) return 1; break; case CLAIM_TYPE_REQUEST: - if (handle_request(bat_priv, primary_if, hw_src, ethhdr, vid)) + if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr, + vid)) return 1; break; } @@ -910,7 +926,7 @@ static int bla_process_claim(struct bat_priv *bat_priv, /* Check when we last heard from other nodes, and remove them in case of * a time out, or clean all backbone gws if now is set. */ -static void bla_purge_backbone_gw(struct bat_priv *bat_priv, int now) +static void batadv_bla_purge_backbone_gw(struct bat_priv *bat_priv, int now) { struct backbone_gw *backbone_gw; struct hlist_node *node, *node_tmp; @@ -945,10 +961,10 @@ purge_now: if (atomic_read(&backbone_gw->request_sent)) atomic_dec(&bat_priv->bla_num_requests); - bla_del_backbone_claims(backbone_gw); + batadv_bla_del_backbone_claims(backbone_gw); hlist_del_rcu(node); - backbone_gw_free_ref(backbone_gw); + batadv_backbone_gw_free_ref(backbone_gw); } spin_unlock_bh(list_lock); } @@ -961,8 +977,8 @@ purge_now: * Check when we heard last time from our own claims, and remove them in case of * a time out, or clean all claims if now is set */ -static void bla_purge_claims(struct bat_priv *bat_priv, - struct hard_iface *primary_if, int now) +static void batadv_bla_purge_claims(struct bat_priv *bat_priv, + struct hard_iface *primary_if, int now) { struct claim *claim; struct hlist_node *node; @@ -993,9 +1009,9 @@ static void bla_purge_claims(struct bat_priv *bat_priv, claim->addr, claim->vid); purge_now: - handle_unclaim(bat_priv, primary_if, - claim->backbone_gw->orig, - claim->addr, claim->vid); + batadv_handle_unclaim(bat_priv, primary_if, + claim->backbone_gw->orig, + claim->addr, claim->vid); } rcu_read_unlock(); } @@ -1022,8 +1038,8 @@ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); if (!oldif) { - bla_purge_claims(bat_priv, NULL, 1); - bla_purge_backbone_gw(bat_priv, 1); + batadv_bla_purge_claims(bat_priv, NULL, 1); + batadv_bla_purge_backbone_gw(bat_priv, 1); return; } @@ -1046,7 +1062,7 @@ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, /* send an announce frame so others will ask for our * claims and update their tables. */ - bla_send_announce(bat_priv, backbone_gw); + batadv_bla_send_announce(bat_priv, backbone_gw); } rcu_read_unlock(); } @@ -1055,9 +1071,9 @@ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, /* (re)start the timer */ -static void bla_start_timer(struct bat_priv *bat_priv) +static void batadv_bla_start_timer(struct bat_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->bla_work, bla_periodic_work); + INIT_DELAYED_WORK(&bat_priv->bla_work, batadv_bla_periodic_work); queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work, msecs_to_jiffies(BLA_PERIOD_LENGTH)); } @@ -1066,7 +1082,7 @@ static void bla_start_timer(struct bat_priv *bat_priv) * * purge structures when they are too old * * send announcements */ -static void bla_periodic_work(struct work_struct *work) +static void batadv_bla_periodic_work(struct work_struct *work) { struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); @@ -1083,8 +1099,8 @@ static void bla_periodic_work(struct work_struct *work) if (!primary_if) goto out; - bla_purge_claims(bat_priv, primary_if, 0); - bla_purge_backbone_gw(bat_priv, 0); + batadv_bla_purge_claims(bat_priv, primary_if, 0); + batadv_bla_purge_backbone_gw(bat_priv, 0); if (!atomic_read(&bat_priv->bridge_loop_avoidance)) goto out; @@ -1104,7 +1120,7 @@ static void bla_periodic_work(struct work_struct *work) backbone_gw->lasttime = jiffies; - bla_send_announce(bat_priv, backbone_gw); + batadv_bla_send_announce(bat_priv, backbone_gw); } rcu_read_unlock(); } @@ -1112,7 +1128,7 @@ out: if (primary_if) batadv_hardif_free_ref(primary_if); - bla_start_timer(bat_priv); + batadv_bla_start_timer(bat_priv); } /* The hash for claim and backbone hash receive the same key because they @@ -1120,8 +1136,8 @@ out: * them with to different keys to allow nested locking without generating * lockdep warnings */ -static struct lock_class_key claim_hash_lock_class_key; -static struct lock_class_key backbone_hash_lock_class_key; +static struct lock_class_key batadv_claim_hash_lock_class_key; +static struct lock_class_key batadv_backbone_hash_lock_class_key; /* initialize all bla structures */ int batadv_bla_init(struct bat_priv *bat_priv) @@ -1161,13 +1177,13 @@ int batadv_bla_init(struct bat_priv *bat_priv) return -ENOMEM; batadv_hash_set_lock_class(bat_priv->claim_hash, - &claim_hash_lock_class_key); + &batadv_claim_hash_lock_class_key); batadv_hash_set_lock_class(bat_priv->backbone_hash, - &backbone_hash_lock_class_key); + &batadv_backbone_hash_lock_class_key); batadv_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n"); - bla_start_timer(bat_priv); + batadv_bla_start_timer(bat_priv); return 0; } @@ -1308,12 +1324,12 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb, } /* see if this originator is a backbone gw for this VLAN */ - backbone_gw = backbone_hash_find(orig_node->bat_priv, - orig_node->orig, vid); + backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, + orig_node->orig, vid); if (!backbone_gw) return 0; - backbone_gw_free_ref(backbone_gw); + batadv_backbone_gw_free_ref(backbone_gw); return 1; } @@ -1326,12 +1342,12 @@ void batadv_bla_free(struct bat_priv *bat_priv) primary_if = batadv_primary_if_get_selected(bat_priv); if (bat_priv->claim_hash) { - bla_purge_claims(bat_priv, primary_if, 1); + batadv_bla_purge_claims(bat_priv, primary_if, 1); batadv_hash_destroy(bat_priv->claim_hash); bat_priv->claim_hash = NULL; } if (bat_priv->backbone_hash) { - bla_purge_backbone_gw(bat_priv, 1); + batadv_bla_purge_backbone_gw(bat_priv, 1); batadv_hash_destroy(bat_priv->backbone_hash); bat_priv->backbone_hash = NULL; } @@ -1375,15 +1391,15 @@ int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); search_claim.vid = vid; - claim = claim_hash_find(bat_priv, &search_claim); + claim = batadv_claim_hash_find(bat_priv, &search_claim); if (!claim) { /* possible optimization: race for a claim */ /* No claim exists yet, claim it for us! */ - handle_claim(bat_priv, primary_if, - primary_if->net_dev->dev_addr, - ethhdr->h_source, vid); + batadv_handle_claim(bat_priv, primary_if, + primary_if->net_dev->dev_addr, + ethhdr->h_source, vid); goto allow; } @@ -1404,13 +1420,13 @@ int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) * send a claim and update the claim table * immediately. */ - handle_claim(bat_priv, primary_if, - primary_if->net_dev->dev_addr, - ethhdr->h_source, vid); + batadv_handle_claim(bat_priv, primary_if, + primary_if->net_dev->dev_addr, + ethhdr->h_source, vid); goto allow; } allow: - bla_update_own_backbone_gw(bat_priv, primary_if, vid); + batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); ret = 0; goto out; @@ -1422,7 +1438,7 @@ out: if (primary_if) batadv_hardif_free_ref(primary_if); if (claim) - claim_free_ref(claim); + batadv_claim_free_ref(claim); return ret; } @@ -1455,7 +1471,7 @@ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) /* in VLAN case, the mac header might not be set. */ skb_reset_mac_header(skb); - if (bla_process_claim(bat_priv, primary_if, skb)) + if (batadv_bla_process_claim(bat_priv, primary_if, skb)) goto handled; ethhdr = (struct ethhdr *)skb_mac_header(skb); @@ -1468,7 +1484,7 @@ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); search_claim.vid = vid; - claim = claim_hash_find(bat_priv, &search_claim); + claim = batadv_claim_hash_find(bat_priv, &search_claim); /* if no claim exists, allow it. */ if (!claim) @@ -1480,9 +1496,9 @@ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) /* if yes, the client has roamed and we have * to unclaim it. */ - handle_unclaim(bat_priv, primary_if, - primary_if->net_dev->dev_addr, - ethhdr->h_source, vid); + batadv_handle_unclaim(bat_priv, primary_if, + primary_if->net_dev->dev_addr, + ethhdr->h_source, vid); goto allow; } @@ -1499,7 +1515,7 @@ int batadv_bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) goto allow; } allow: - bla_update_own_backbone_gw(bat_priv, primary_if, vid); + batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid); ret = 0; goto out; handled: @@ -1508,7 +1524,7 @@ out: if (primary_if) batadv_hardif_free_ref(primary_if); if (claim) - claim_free_ref(claim); + batadv_claim_free_ref(claim); return ret; } -- GitLab From 1409a8349f978abec556748bcac00541a46a56b5 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:55 +0200 Subject: [PATCH 2624/6849] batman-adv: Prefix gateway_client local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_client.c | 67 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 318c112aa98c..efe7519f1491 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -36,13 +36,13 @@ #define DHCP_OPTIONS_OFFSET 240 #define DHCP_REQUEST 3 -static void gw_node_free_ref(struct gw_node *gw_node) +static void batadv_gw_node_free_ref(struct gw_node *gw_node) { if (atomic_dec_and_test(&gw_node->refcount)) kfree_rcu(gw_node, rcu); } -static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv) +static struct gw_node *batadv_gw_get_selected_gw_node(struct bat_priv *bat_priv) { struct gw_node *gw_node; @@ -64,7 +64,7 @@ struct orig_node *batadv_gw_get_selected_orig(struct bat_priv *bat_priv) struct gw_node *gw_node; struct orig_node *orig_node = NULL; - gw_node = gw_get_selected_gw_node(bat_priv); + gw_node = batadv_gw_get_selected_gw_node(bat_priv); if (!gw_node) goto out; @@ -80,11 +80,12 @@ unlock: rcu_read_unlock(); out: if (gw_node) - gw_node_free_ref(gw_node); + batadv_gw_node_free_ref(gw_node); return orig_node; } -static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node) +static void batadv_gw_select(struct bat_priv *bat_priv, + struct gw_node *new_gw_node) { struct gw_node *curr_gw_node; @@ -97,7 +98,7 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node) rcu_assign_pointer(bat_priv->curr_gw, new_gw_node); if (curr_gw_node) - gw_node_free_ref(curr_gw_node); + batadv_gw_node_free_ref(curr_gw_node); spin_unlock_bh(&bat_priv->gw_list_lock); } @@ -107,7 +108,7 @@ void batadv_gw_deselect(struct bat_priv *bat_priv) atomic_set(&bat_priv->gw_reselect, 1); } -static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) +static struct gw_node *batadv_gw_get_best_gw_node(struct bat_priv *bat_priv) { struct neigh_node *router; struct hlist_node *node; @@ -144,7 +145,7 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) ((tmp_gw_factor == max_gw_factor) && (router->tq_avg > max_tq))) { if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); curr_gw = gw_node; atomic_inc(&curr_gw->refcount); } @@ -159,7 +160,7 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) */ if (router->tq_avg > max_tq) { if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); curr_gw = gw_node; atomic_inc(&curr_gw->refcount); } @@ -172,7 +173,7 @@ static struct gw_node *gw_get_best_gw_node(struct bat_priv *bat_priv) if (tmp_gw_factor > max_gw_factor) max_gw_factor = tmp_gw_factor; - gw_node_free_ref(gw_node); + batadv_gw_node_free_ref(gw_node); next: batadv_neigh_node_free_ref(router); @@ -199,9 +200,9 @@ void batadv_gw_election(struct bat_priv *bat_priv) if (!atomic_dec_not_zero(&bat_priv->gw_reselect)) goto out; - curr_gw = gw_get_selected_gw_node(bat_priv); + curr_gw = batadv_gw_get_selected_gw_node(bat_priv); - next_gw = gw_get_best_gw_node(bat_priv); + next_gw = batadv_gw_get_best_gw_node(bat_priv); if (curr_gw == next_gw) goto out; @@ -234,13 +235,13 @@ void batadv_gw_election(struct bat_priv *bat_priv) batadv_throw_uevent(bat_priv, UEV_GW, UEV_CHANGE, gw_addr); } - gw_select(bat_priv, next_gw); + batadv_gw_select(bat_priv, next_gw); out: if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); if (next_gw) - gw_node_free_ref(next_gw); + batadv_gw_node_free_ref(next_gw); if (router) batadv_neigh_node_free_ref(router); } @@ -299,8 +300,9 @@ out: return; } -static void gw_node_add(struct bat_priv *bat_priv, - struct orig_node *orig_node, uint8_t new_gwflags) +static void batadv_gw_node_add(struct bat_priv *bat_priv, + struct orig_node *orig_node, + uint8_t new_gwflags) { struct gw_node *gw_node; int down, up; @@ -338,7 +340,7 @@ void batadv_gw_node_update(struct bat_priv *bat_priv, * have this gateway in our list (duplication check!) even though we * have no currently selected gateway. */ - curr_gw = gw_get_selected_gw_node(bat_priv); + curr_gw = batadv_gw_get_selected_gw_node(bat_priv); rcu_read_lock(); hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { @@ -368,7 +370,7 @@ void batadv_gw_node_update(struct bat_priv *bat_priv, if (new_gwflags == NO_FLAGS) goto unlock; - gw_node_add(bat_priv, orig_node, new_gwflags); + batadv_gw_node_add(bat_priv, orig_node, new_gwflags); goto unlock; deselect: @@ -377,7 +379,7 @@ unlock: rcu_read_unlock(); if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); } void batadv_gw_node_delete(struct bat_priv *bat_priv, @@ -393,7 +395,7 @@ void batadv_gw_node_purge(struct bat_priv *bat_priv) unsigned long timeout = msecs_to_jiffies(2 * PURGE_TIMEOUT); int do_deselect = 0; - curr_gw = gw_get_selected_gw_node(bat_priv); + curr_gw = batadv_gw_get_selected_gw_node(bat_priv); spin_lock_bh(&bat_priv->gw_list_lock); @@ -408,7 +410,7 @@ void batadv_gw_node_purge(struct bat_priv *bat_priv) do_deselect = 1; hlist_del_rcu(&gw_node->list); - gw_node_free_ref(gw_node); + batadv_gw_node_free_ref(gw_node); } spin_unlock_bh(&bat_priv->gw_list_lock); @@ -418,12 +420,13 @@ void batadv_gw_node_purge(struct bat_priv *bat_priv) batadv_gw_deselect(bat_priv); if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); } /* fails if orig_node has no router */ -static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, - const struct gw_node *gw_node) +static int batadv_write_buffer_text(struct bat_priv *bat_priv, + struct seq_file *seq, + const struct gw_node *gw_node) { struct gw_node *curr_gw; struct neigh_node *router; @@ -435,7 +438,7 @@ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, if (!router) goto out; - curr_gw = gw_get_selected_gw_node(bat_priv); + curr_gw = batadv_gw_get_selected_gw_node(bat_priv); ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", (curr_gw == gw_node ? "=>" : " "), @@ -450,7 +453,7 @@ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, batadv_neigh_node_free_ref(router); if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); out: return ret; } @@ -491,7 +494,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) continue; /* fails if orig_node has no router */ - if (_write_buffer_text(bat_priv, seq, gw_node) < 0) + if (batadv_write_buffer_text(bat_priv, seq, gw_node) < 0) continue; gw_count++; @@ -507,7 +510,7 @@ out: return ret; } -static bool is_type_dhcprequest(struct sk_buff *skb, int header_len) +static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) { int ret = false; unsigned char *p; @@ -655,7 +658,7 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, if (!orig_dst_node->gw_flags) goto out; - ret = is_type_dhcprequest(skb, header_len); + ret = batadv_is_type_dhcprequest(skb, header_len); if (!ret) goto out; @@ -667,7 +670,7 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, curr_tq_avg = TQ_MAX_VALUE; break; case GW_MODE_CLIENT: - curr_gw = gw_get_selected_gw_node(bat_priv); + curr_gw = batadv_gw_get_selected_gw_node(bat_priv); if (!curr_gw) goto out; @@ -702,7 +705,7 @@ out: if (orig_dst_node) batadv_orig_node_free_ref(orig_dst_node); if (curr_gw) - gw_node_free_ref(curr_gw); + batadv_gw_node_free_ref(curr_gw); if (neigh_old) batadv_neigh_node_free_ref(neigh_old); if (neigh_curr) -- GitLab From 8e714a5ded231abb853941b67845d25a022daa89 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:56 +0200 Subject: [PATCH 2625/6849] batman-adv: Prefix gateway_common local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 3700562cf276..6edf37f9a15c 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -22,7 +22,7 @@ #include "gateway_client.h" /* calculates the gateway class from kbit */ -static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) +static void batadv_kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) { int mdown = 0, tdown, tup, difference; uint8_t sbit, part; @@ -73,8 +73,8 @@ void batadv_gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) *up = ((upart + 1) * (*down)) / 8; } -static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, - int *up, int *down) +static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, + int *up, int *down) { int ret, multi = 1; char *slash_ptr, *tmp_ptr; @@ -142,7 +142,7 @@ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, int up = 0, down = 0; bool ret; - ret = parse_gw_bandwidth(net_dev, buff, &up, &down); + ret = batadv_parse_gw_bandwidth(net_dev, buff, &up, &down); if (!ret) goto end; @@ -152,7 +152,7 @@ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, if (!up) up = down / 5; - kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); + batadv_kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); /* the gw bandwidth we guessed above might not match the given * speeds, hence we need to calculate it back to show the number -- GitLab From 18a1cb6ee08e6ea62e0f3c2643435cd444fc0790 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:57 +0200 Subject: [PATCH 2626/6849] batman-adv: Prefix hard-interface local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/hard-interface.c | 64 +++++++++++++++++---------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 6131d932b638..c22c145d8224 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -57,7 +57,7 @@ out: return hard_iface; } -static int is_valid_iface(const struct net_device *net_dev) +static int batadv_is_valid_iface(const struct net_device *net_dev) { if (net_dev->flags & IFF_LOOPBACK) return 0; @@ -75,7 +75,8 @@ static int is_valid_iface(const struct net_device *net_dev) return 1; } -static struct hard_iface *hardif_get_active(const struct net_device *soft_iface) +static struct hard_iface * +batadv_hardif_get_active(const struct net_device *soft_iface) { struct hard_iface *hard_iface; @@ -96,8 +97,8 @@ out: return hard_iface; } -static void primary_if_update_addr(struct bat_priv *bat_priv, - struct hard_iface *oldif) +static void batadv_primary_if_update_addr(struct bat_priv *bat_priv, + struct hard_iface *oldif) { struct vis_packet *vis_packet; struct hard_iface *primary_if; @@ -118,8 +119,8 @@ out: batadv_hardif_free_ref(primary_if); } -static void primary_if_select(struct bat_priv *bat_priv, - struct hard_iface *new_hard_iface) +static void batadv_primary_if_select(struct bat_priv *bat_priv, + struct hard_iface *new_hard_iface) { struct hard_iface *curr_hard_iface; @@ -135,14 +136,14 @@ static void primary_if_select(struct bat_priv *bat_priv, goto out; bat_priv->bat_algo_ops->bat_primary_iface_set(new_hard_iface); - primary_if_update_addr(bat_priv, curr_hard_iface); + batadv_primary_if_update_addr(bat_priv, curr_hard_iface); out: if (curr_hard_iface) batadv_hardif_free_ref(curr_hard_iface); } -static bool hardif_is_iface_up(const struct hard_iface *hard_iface) +static bool batadv_hardif_is_iface_up(const struct hard_iface *hard_iface) { if (hard_iface->net_dev->flags & IFF_UP) return true; @@ -150,7 +151,7 @@ static bool hardif_is_iface_up(const struct hard_iface *hard_iface) return false; } -static void check_known_mac_addr(const struct net_device *net_dev) +static void batadv_check_known_mac_addr(const struct net_device *net_dev) { const struct hard_iface *hard_iface; @@ -213,7 +214,7 @@ void batadv_update_min_mtu(struct net_device *soft_iface) soft_iface->mtu = min_mtu; } -static void hardif_activate_interface(struct hard_iface *hard_iface) +static void batadv_hardif_activate_interface(struct hard_iface *hard_iface) { struct bat_priv *bat_priv; struct hard_iface *primary_if = NULL; @@ -231,7 +232,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) */ primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) - primary_if_select(bat_priv, hard_iface); + batadv_primary_if_select(bat_priv, hard_iface); bat_info(hard_iface->soft_iface, "Interface activated: %s\n", hard_iface->net_dev->name); @@ -243,7 +244,7 @@ out: batadv_hardif_free_ref(primary_if); } -static void hardif_deactivate_interface(struct hard_iface *hard_iface) +static void batadv_hardif_deactivate_interface(struct hard_iface *hard_iface) { if ((hard_iface->if_status != IF_ACTIVE) && (hard_iface->if_status != IF_TO_BE_ACTIVATED)) @@ -331,8 +332,8 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, hard_iface->net_dev->name, hard_iface->net_dev->mtu, ETH_DATA_LEN + BAT_HEADER_LEN); - if (hardif_is_iface_up(hard_iface)) - hardif_activate_interface(hard_iface); + if (batadv_hardif_is_iface_up(hard_iface)) + batadv_hardif_activate_interface(hard_iface); else bat_err(hard_iface->soft_iface, "Not using interface %s (retrying later): interface not active\n", @@ -357,7 +358,7 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) struct hard_iface *primary_if = NULL; if (hard_iface->if_status == IF_ACTIVE) - hardif_deactivate_interface(hard_iface); + batadv_hardif_deactivate_interface(hard_iface); if (hard_iface->if_status != IF_INACTIVE) goto out; @@ -373,8 +374,8 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) if (hard_iface == primary_if) { struct hard_iface *new_if; - new_if = hardif_get_active(hard_iface->soft_iface); - primary_if_select(bat_priv, new_if); + new_if = batadv_hardif_get_active(hard_iface->soft_iface); + batadv_primary_if_select(bat_priv, new_if); if (new_if) batadv_hardif_free_ref(new_if); @@ -400,14 +401,15 @@ out: batadv_hardif_free_ref(primary_if); } -static struct hard_iface *hardif_add_interface(struct net_device *net_dev) +static struct hard_iface * +batadv_hardif_add_interface(struct net_device *net_dev) { struct hard_iface *hard_iface; int ret; ASSERT_RTNL(); - ret = is_valid_iface(net_dev); + ret = batadv_is_valid_iface(net_dev); if (ret != 1) goto out; @@ -429,7 +431,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev) /* extra reference for return */ atomic_set(&hard_iface->refcount, 2); - check_known_mac_addr(hard_iface->net_dev); + batadv_check_known_mac_addr(hard_iface->net_dev); list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); /* This can't be called via a bat_priv callback because @@ -448,7 +450,7 @@ out: return NULL; } -static void hardif_remove_interface(struct hard_iface *hard_iface) +static void batadv_hardif_remove_interface(struct hard_iface *hard_iface) { ASSERT_RTNL(); @@ -472,13 +474,13 @@ void batadv_hardif_remove_interfaces(void) list_for_each_entry_safe(hard_iface, hard_iface_tmp, &batadv_hardif_list, list) { list_del_rcu(&hard_iface->list); - hardif_remove_interface(hard_iface); + batadv_hardif_remove_interface(hard_iface); } rtnl_unlock(); } -static int hard_if_event(struct notifier_block *this, - unsigned long event, void *ptr) +static int batadv_hard_if_event(struct notifier_block *this, + unsigned long event, void *ptr) { struct net_device *net_dev = ptr; struct hard_iface *hard_iface = batadv_hardif_get_by_netdev(net_dev); @@ -486,23 +488,23 @@ static int hard_if_event(struct notifier_block *this, struct bat_priv *bat_priv; if (!hard_iface && event == NETDEV_REGISTER) - hard_iface = hardif_add_interface(net_dev); + hard_iface = batadv_hardif_add_interface(net_dev); if (!hard_iface) goto out; switch (event) { case NETDEV_UP: - hardif_activate_interface(hard_iface); + batadv_hardif_activate_interface(hard_iface); break; case NETDEV_GOING_DOWN: case NETDEV_DOWN: - hardif_deactivate_interface(hard_iface); + batadv_hardif_deactivate_interface(hard_iface); break; case NETDEV_UNREGISTER: list_del_rcu(&hard_iface->list); - hardif_remove_interface(hard_iface); + batadv_hardif_remove_interface(hard_iface); break; case NETDEV_CHANGEMTU: if (hard_iface->soft_iface) @@ -512,7 +514,7 @@ static int hard_if_event(struct notifier_block *this, if (hard_iface->if_status == IF_NOT_IN_USE) goto hardif_put; - check_known_mac_addr(hard_iface->net_dev); + batadv_check_known_mac_addr(hard_iface->net_dev); bat_priv = netdev_priv(hard_iface->soft_iface); bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); @@ -522,7 +524,7 @@ static int hard_if_event(struct notifier_block *this, goto hardif_put; if (hard_iface == primary_if) - primary_if_update_addr(bat_priv, NULL); + batadv_primary_if_update_addr(bat_priv, NULL); break; default: break; @@ -569,5 +571,5 @@ out: } struct notifier_block batadv_hard_if_notifier = { - .notifier_call = hard_if_event, + .notifier_call = batadv_hard_if_event, }; -- GitLab From 7f9f02cb83a6a85fea1482191405a9ce37558479 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:58 +0200 Subject: [PATCH 2627/6849] batman-adv: Prefix hash local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index e39f8f4bb165..1fb961c8d9a0 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c @@ -21,7 +21,7 @@ #include "hash.h" /* clears the hash */ -static void hash_init(struct hashtable_t *hash) +static void batadv_hash_init(struct hashtable_t *hash) { uint32_t i; @@ -58,7 +58,7 @@ struct hashtable_t *batadv_hash_new(uint32_t size) goto free_table; hash->size = size; - hash_init(hash); + batadv_hash_init(hash); return hash; free_table: -- GitLab From af4447f62927accb68d5a074fabc539ef57b2729 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:33:59 +0200 Subject: [PATCH 2628/6849] batman-adv: Prefix icmp_socket local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/icmp_socket.c | 66 +++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index a3e80b6782af..b285c31bfa9e 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -26,18 +26,18 @@ #include "originator.h" #include "hard-interface.h" -static struct socket_client *socket_client_hash[256]; +static struct socket_client *batadv_socket_client_hash[256]; -static void bat_socket_add_packet(struct socket_client *socket_client, - struct icmp_packet_rr *icmp_packet, - size_t icmp_len); +static void batadv_socket_add_packet(struct socket_client *socket_client, + struct icmp_packet_rr *icmp_packet, + size_t icmp_len); void batadv_socket_init(void) { - memset(socket_client_hash, 0, sizeof(socket_client_hash)); + memset(batadv_socket_client_hash, 0, sizeof(batadv_socket_client_hash)); } -static int bat_socket_open(struct inode *inode, struct file *file) +static int batadv_socket_open(struct inode *inode, struct file *file) { unsigned int i; struct socket_client *socket_client; @@ -49,14 +49,14 @@ static int bat_socket_open(struct inode *inode, struct file *file) if (!socket_client) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) { - if (!socket_client_hash[i]) { - socket_client_hash[i] = socket_client; + for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) { + if (!batadv_socket_client_hash[i]) { + batadv_socket_client_hash[i] = socket_client; break; } } - if (i == ARRAY_SIZE(socket_client_hash)) { + if (i == ARRAY_SIZE(batadv_socket_client_hash)) { pr_err("Error - can't add another packet client: maximum number of clients reached\n"); kfree(socket_client); return -EXFULL; @@ -75,7 +75,7 @@ static int bat_socket_open(struct inode *inode, struct file *file) return 0; } -static int bat_socket_release(struct inode *inode, struct file *file) +static int batadv_socket_release(struct inode *inode, struct file *file) { struct socket_client *socket_client = file->private_data; struct socket_packet *socket_packet; @@ -92,7 +92,7 @@ static int bat_socket_release(struct inode *inode, struct file *file) kfree(socket_packet); } - socket_client_hash[socket_client->index] = NULL; + batadv_socket_client_hash[socket_client->index] = NULL; spin_unlock_bh(&socket_client->lock); kfree(socket_client); @@ -101,8 +101,8 @@ static int bat_socket_release(struct inode *inode, struct file *file) return 0; } -static ssize_t bat_socket_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +static ssize_t batadv_socket_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { struct socket_client *socket_client = file->private_data; struct socket_packet *socket_packet; @@ -144,8 +144,8 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf, return packet_len; } -static ssize_t bat_socket_write(struct file *file, const char __user *buff, - size_t len, loff_t *off) +static ssize_t batadv_socket_write(struct file *file, const char __user *buff, + size_t len, loff_t *off) { struct socket_client *socket_client = file->private_data; struct bat_priv *bat_priv = socket_client->bat_priv; @@ -206,7 +206,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, if (icmp_packet->header.version != COMPAT_VERSION) { icmp_packet->msg_type = PARAMETER_PROBLEM; icmp_packet->header.version = COMPAT_VERSION; - bat_socket_add_packet(socket_client, icmp_packet, packet_len); + batadv_socket_add_packet(socket_client, icmp_packet, + packet_len); goto free_skb; } @@ -239,7 +240,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, dst_unreach: icmp_packet->msg_type = DESTINATION_UNREACHABLE; - bat_socket_add_packet(socket_client, icmp_packet, packet_len); + batadv_socket_add_packet(socket_client, icmp_packet, packet_len); free_skb: kfree_skb(skb); out: @@ -252,7 +253,7 @@ out: return len; } -static unsigned int bat_socket_poll(struct file *file, poll_table *wait) +static unsigned int batadv_socket_poll(struct file *file, poll_table *wait) { struct socket_client *socket_client = file->private_data; @@ -264,13 +265,13 @@ static unsigned int bat_socket_poll(struct file *file, poll_table *wait) return 0; } -static const struct file_operations fops = { +static const struct file_operations batadv_fops = { .owner = THIS_MODULE, - .open = bat_socket_open, - .release = bat_socket_release, - .read = bat_socket_read, - .write = bat_socket_write, - .poll = bat_socket_poll, + .open = batadv_socket_open, + .release = batadv_socket_release, + .read = batadv_socket_read, + .write = batadv_socket_write, + .poll = batadv_socket_poll, .llseek = no_llseek, }; @@ -282,7 +283,7 @@ int batadv_socket_setup(struct bat_priv *bat_priv) goto err; d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, - bat_priv->debug_dir, bat_priv, &fops); + bat_priv->debug_dir, bat_priv, &batadv_fops); if (!d) goto err; @@ -292,9 +293,9 @@ err: return -ENOMEM; } -static void bat_socket_add_packet(struct socket_client *socket_client, - struct icmp_packet_rr *icmp_packet, - size_t icmp_len) +static void batadv_socket_add_packet(struct socket_client *socket_client, + struct icmp_packet_rr *icmp_packet, + size_t icmp_len) { struct socket_packet *socket_packet; @@ -312,7 +313,7 @@ static void bat_socket_add_packet(struct socket_client *socket_client, /* while waiting for the lock the socket_client could have been * deleted */ - if (!socket_client_hash[icmp_packet->uid]) { + if (!batadv_socket_client_hash[icmp_packet->uid]) { spin_unlock_bh(&socket_client->lock); kfree(socket_packet); return; @@ -338,8 +339,9 @@ static void bat_socket_add_packet(struct socket_client *socket_client, void batadv_socket_receive_packet(struct icmp_packet_rr *icmp_packet, size_t icmp_len) { - struct socket_client *hash = socket_client_hash[icmp_packet->uid]; + struct socket_client *hash; + hash = batadv_socket_client_hash[icmp_packet->uid]; if (hash) - bat_socket_add_packet(hash, icmp_packet, icmp_len); + batadv_socket_add_packet(hash, icmp_packet, icmp_len); } -- GitLab From 03fc7f863dc53516ca9764b324f54d10c4a137f6 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 12 May 2012 18:34:00 +0200 Subject: [PATCH 2629/6849] batman-adv: Prefix originator local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/originator.c | 54 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 1cd640e8dab9..bf9ec39a8349 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -28,17 +28,17 @@ #include "soft-interface.h" #include "bridge_loop_avoidance.h" -static void purge_orig(struct work_struct *work); +static void batadv_purge_orig(struct work_struct *work); -static void start_purge_timer(struct bat_priv *bat_priv) +static void batadv_start_purge_timer(struct bat_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); + INIT_DELAYED_WORK(&bat_priv->orig_work, batadv_purge_orig); queue_delayed_work(batadv_event_workqueue, &bat_priv->orig_work, msecs_to_jiffies(1000)); } /* returns 1 if they are the same originator */ -static int compare_orig(const struct hlist_node *node, const void *data2) +static int batadv_compare_orig(const struct hlist_node *node, const void *data2) { const void *data1 = container_of(node, struct orig_node, hash_entry); @@ -55,7 +55,7 @@ int batadv_originator_init(struct bat_priv *bat_priv) if (!bat_priv->orig_hash) goto err; - start_purge_timer(bat_priv); + batadv_start_purge_timer(bat_priv); return 0; err: @@ -110,7 +110,7 @@ out: return neigh_node; } -static void orig_node_free_rcu(struct rcu_head *rcu) +static void batadv_orig_node_free_rcu(struct rcu_head *rcu) { struct hlist_node *node, *node_tmp; struct neigh_node *neigh_node, *tmp_neigh_node; @@ -149,7 +149,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu) void batadv_orig_node_free_ref(struct orig_node *orig_node) { if (atomic_dec_and_test(&orig_node->refcount)) - call_rcu(&orig_node->rcu, orig_node_free_rcu); + call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu); } void batadv_originator_free(struct bat_priv *bat_priv) @@ -248,7 +248,7 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, if (!orig_node->bcast_own_sum) goto free_bcast_own; - hash_added = batadv_hash_add(bat_priv->orig_hash, compare_orig, + hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, batadv_choose_orig, orig_node, &orig_node->hash_entry); if (hash_added != 0) @@ -264,9 +264,9 @@ free_orig_node: return NULL; } -static bool purge_orig_neighbors(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct neigh_node **best_neigh_node) +static bool batadv_purge_orig_neighbors(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct neigh_node **best_neigh_node) { struct hlist_node *node, *node_tmp; struct neigh_node *neigh_node; @@ -319,8 +319,8 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, return neigh_purged; } -static bool purge_orig_node(struct bat_priv *bat_priv, - struct orig_node *orig_node) +static bool batadv_purge_orig_node(struct bat_priv *bat_priv, + struct orig_node *orig_node) { struct neigh_node *best_neigh_node; @@ -331,8 +331,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv, jiffies_to_msecs(orig_node->last_seen)); return true; } else { - if (purge_orig_neighbors(bat_priv, orig_node, - &best_neigh_node)) + if (batadv_purge_orig_neighbors(bat_priv, orig_node, + &best_neigh_node)) batadv_update_route(bat_priv, orig_node, best_neigh_node); } @@ -340,7 +340,7 @@ static bool purge_orig_node(struct bat_priv *bat_priv, return false; } -static void _purge_orig(struct bat_priv *bat_priv) +static void _batadv_purge_orig(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *node, *node_tmp; @@ -360,7 +360,7 @@ static void _purge_orig(struct bat_priv *bat_priv) spin_lock_bh(list_lock); hlist_for_each_entry_safe(orig_node, node, node_tmp, head, hash_entry) { - if (purge_orig_node(bat_priv, orig_node)) { + if (batadv_purge_orig_node(bat_priv, orig_node)) { if (orig_node->gw_flags) batadv_gw_node_delete(bat_priv, orig_node); @@ -380,20 +380,20 @@ static void _purge_orig(struct bat_priv *bat_priv) batadv_gw_election(bat_priv); } -static void purge_orig(struct work_struct *work) +static void batadv_purge_orig(struct work_struct *work) { struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); struct bat_priv *bat_priv = container_of(delayed_work, struct bat_priv, orig_work); - _purge_orig(bat_priv); - start_purge_timer(bat_priv); + _batadv_purge_orig(bat_priv); + batadv_start_purge_timer(bat_priv); } void batadv_purge_orig_ref(struct bat_priv *bat_priv) { - _purge_orig(bat_priv); + _batadv_purge_orig(bat_priv); } int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) @@ -483,7 +483,7 @@ out: return ret; } -static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) +static int batadv_orig_node_add_if(struct orig_node *orig_node, int max_if_num) { void *data_ptr; @@ -528,7 +528,7 @@ int batadv_orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); - ret = orig_node_add_if(orig_node, max_if_num); + ret = batadv_orig_node_add_if(orig_node, max_if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); if (ret == -ENOMEM) @@ -544,8 +544,8 @@ err: return -ENOMEM; } -static int orig_node_del_if(struct orig_node *orig_node, - int max_if_num, int del_if_num) +static int batadv_orig_node_del_if(struct orig_node *orig_node, + int max_if_num, int del_if_num) { void *data_ptr = NULL; int chunk_size; @@ -612,8 +612,8 @@ int batadv_orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); - ret = orig_node_del_if(orig_node, max_if_num, - hard_iface->if_num); + ret = batadv_orig_node_del_if(orig_node, max_if_num, + hard_iface->if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); if (ret == -ENOMEM) -- GitLab From 63b010371efebe6342b7f2bfad2f7881d03cf5f7 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:13 +0200 Subject: [PATCH 2630/6849] batman-adv: Prefix routing local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/routing.c | 65 +++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 57ff85178216..e7ee40d6d609 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -29,8 +29,8 @@ #include "unicast.h" #include "bridge_loop_avoidance.h" -static int route_unicast_packet(struct sk_buff *skb, - struct hard_iface *recv_if); +static int batadv_route_unicast_packet(struct sk_buff *skb, + struct hard_iface *recv_if); void batadv_slide_own_bcast_window(struct hard_iface *hard_iface) { @@ -61,9 +61,9 @@ void batadv_slide_own_bcast_window(struct hard_iface *hard_iface) } } -static void _update_route(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct neigh_node *neigh_node) +static void _batadv_update_route(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct neigh_node *neigh_node) { struct neigh_node *curr_router; @@ -117,7 +117,7 @@ void batadv_update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, router = batadv_orig_node_get_router(orig_node); if (router != neigh_node) - _update_route(bat_priv, orig_node, neigh_node); + _batadv_update_route(bat_priv, orig_node, neigh_node); out: if (router) @@ -276,8 +276,8 @@ bool batadv_check_management_packet(struct sk_buff *skb, return true; } -static int recv_my_icmp_packet(struct bat_priv *bat_priv, - struct sk_buff *skb, size_t icmp_len) +static int batadv_recv_my_icmp_packet(struct bat_priv *bat_priv, + struct sk_buff *skb, size_t icmp_len) { struct hard_iface *primary_if = NULL; struct orig_node *orig_node = NULL; @@ -331,8 +331,8 @@ out: return ret; } -static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, - struct sk_buff *skb) +static int batadv_recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, + struct sk_buff *skb) { struct hard_iface *primary_if = NULL; struct orig_node *orig_node = NULL; @@ -431,11 +431,11 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* packet for me */ if (batadv_is_my_mac(icmp_packet->dst)) - return recv_my_icmp_packet(bat_priv, skb, hdr_size); + return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); /* TTL exceeded */ if (icmp_packet->header.ttl < 2) - return recv_icmp_ttl_exceeded(bat_priv, skb); + return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); /* get routing information */ orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); @@ -473,8 +473,9 @@ out: * This method rotates the bonding list and increases the * returned router's refcount. */ -static struct neigh_node *find_bond_router(struct orig_node *primary_orig, - const struct hard_iface *recv_if) +static struct neigh_node * +batadv_find_bond_router(struct orig_node *primary_orig, + const struct hard_iface *recv_if) { struct neigh_node *tmp_neigh_node; struct neigh_node *router = NULL, *first_candidate = NULL; @@ -527,8 +528,9 @@ out: * * Increases the returned router's refcount */ -static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, - const struct hard_iface *recv_if) +static struct neigh_node * +batadv_find_ifalter_router(struct orig_node *primary_orig, + const struct hard_iface *recv_if) { struct neigh_node *tmp_neigh_node; struct neigh_node *router = NULL, *first_candidate = NULL; @@ -614,7 +616,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) "Routing TT_REQUEST to %pM [%c]\n", tt_query->dst, tt_flag); - return route_unicast_packet(skb, recv_if); + return batadv_route_unicast_packet(skb, recv_if); } break; case TT_RESPONSE: @@ -643,7 +645,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) "Routing TT_RESPONSE to %pM [%c]\n", tt_query->dst, tt_flag); - return route_unicast_packet(skb, recv_if); + return batadv_route_unicast_packet(skb, recv_if); } break; } @@ -679,7 +681,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) roam_adv_packet = (struct roam_adv_packet *)skb->data; if (!batadv_is_my_mac(roam_adv_packet->dst)) - return route_unicast_packet(skb, recv_if); + return batadv_route_unicast_packet(skb, recv_if); /* check if it is a backbone gateway. we don't accept * roaming advertisement from it, as it has the same @@ -783,9 +785,9 @@ struct neigh_node *batadv_find_router(struct bat_priv *bat_priv, batadv_neigh_node_free_ref(router); if (bonding_enabled) - router = find_bond_router(primary_orig_node, recv_if); + router = batadv_find_bond_router(primary_orig_node, recv_if); else - router = find_ifalter_router(primary_orig_node, recv_if); + router = batadv_find_ifalter_router(primary_orig_node, recv_if); return_router: if (router && router->if_incoming->if_status != IF_ACTIVE) @@ -801,7 +803,7 @@ err: return NULL; } -static int check_unicast_packet(struct sk_buff *skb, int hdr_size) +static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) { struct ethhdr *ethhdr; @@ -826,7 +828,8 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) return 0; } -static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) +static int batadv_route_unicast_packet(struct sk_buff *skb, + struct hard_iface *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct orig_node *orig_node = NULL; @@ -911,8 +914,8 @@ out: return ret; } -static int check_unicast_ttvn(struct bat_priv *bat_priv, - struct sk_buff *skb) { +static int batadv_check_unicast_ttvn(struct bat_priv *bat_priv, + struct sk_buff *skb) { uint8_t curr_ttvn; struct orig_node *orig_node; struct ethhdr *ethhdr; @@ -994,10 +997,10 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) struct unicast_packet *unicast_packet; int hdr_size = sizeof(*unicast_packet); - if (check_unicast_packet(skb, hdr_size) < 0) + if (batadv_check_unicast_packet(skb, hdr_size) < 0) return NET_RX_DROP; - if (!check_unicast_ttvn(bat_priv, skb)) + if (!batadv_check_unicast_ttvn(bat_priv, skb)) return NET_RX_DROP; unicast_packet = (struct unicast_packet *)skb->data; @@ -1009,7 +1012,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) return NET_RX_SUCCESS; } - return route_unicast_packet(skb, recv_if); + return batadv_route_unicast_packet(skb, recv_if); } int batadv_recv_ucast_frag_packet(struct sk_buff *skb, @@ -1021,10 +1024,10 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, struct sk_buff *new_skb = NULL; int ret; - if (check_unicast_packet(skb, hdr_size) < 0) + if (batadv_check_unicast_packet(skb, hdr_size) < 0) return NET_RX_DROP; - if (!check_unicast_ttvn(bat_priv, skb)) + if (!batadv_check_unicast_ttvn(bat_priv, skb)) return NET_RX_DROP; unicast_packet = (struct unicast_frag_packet *)skb->data; @@ -1046,7 +1049,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, return NET_RX_SUCCESS; } - return route_unicast_packet(skb, recv_if); + return batadv_route_unicast_packet(skb, recv_if); } -- GitLab From bb079c82e4274e32ae7592096d7e70bf4fa571ab Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:14 +0200 Subject: [PATCH 2631/6849] batman-adv: Prefix send local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/send.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 47c3a41cd854..1842cbc280c7 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -27,7 +27,7 @@ #include "gateway_common.h" #include "originator.h" -static void send_outstanding_bcast_packet(struct work_struct *work); +static void batadv_send_outstanding_bcast_packet(struct work_struct *work); /* send out an already prepared packet to the given address via the * specified batman interface @@ -96,7 +96,7 @@ void batadv_schedule_bat_ogm(struct hard_iface *hard_iface) bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface); } -static void forw_packet_free(struct forw_packet *forw_packet) +static void batadv_forw_packet_free(struct forw_packet *forw_packet) { if (forw_packet->skb) kfree_skb(forw_packet->skb); @@ -105,9 +105,9 @@ static void forw_packet_free(struct forw_packet *forw_packet) kfree(forw_packet); } -static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, - struct forw_packet *forw_packet, - unsigned long send_time) +static void _batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, + struct forw_packet *forw_packet, + unsigned long send_time) { INIT_HLIST_NODE(&forw_packet->list); @@ -118,7 +118,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet->delayed_work, - send_outstanding_bcast_packet); + batadv_send_outstanding_bcast_packet); queue_delayed_work(batadv_event_workqueue, &forw_packet->delayed_work, send_time); } @@ -171,7 +171,7 @@ int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, /* how often did we send the bcast packet ? */ forw_packet->num_packets = 0; - _add_bcast_packet_to_list(bat_priv, forw_packet, delay); + _batadv_add_bcast_packet_to_list(bat_priv, forw_packet, delay); return NETDEV_TX_OK; packet_free: @@ -184,7 +184,7 @@ out: return NETDEV_TX_BUSY; } -static void send_outstanding_bcast_packet(struct work_struct *work) +static void batadv_send_outstanding_bcast_packet(struct work_struct *work) { struct hard_iface *hard_iface; struct delayed_work *delayed_work = @@ -220,13 +220,13 @@ static void send_outstanding_bcast_packet(struct work_struct *work) /* if we still have some more bcasts to send */ if (forw_packet->num_packets < 3) { - _add_bcast_packet_to_list(bat_priv, forw_packet, - msecs_to_jiffies(5)); + _batadv_add_bcast_packet_to_list(bat_priv, forw_packet, + msecs_to_jiffies(5)); return; } out: - forw_packet_free(forw_packet); + batadv_forw_packet_free(forw_packet); atomic_inc(&bat_priv->bcast_queue_left); } @@ -260,7 +260,7 @@ out: if (!forw_packet->own) atomic_inc(&bat_priv->batman_queue_left); - forw_packet_free(forw_packet); + batadv_forw_packet_free(forw_packet); } void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, @@ -292,7 +292,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, spin_unlock_bh(&bat_priv->forw_bcast_list_lock); - /* send_outstanding_bcast_packet() will lock the list to + /* batadv_send_outstanding_bcast_packet() will lock the list to * delete the item from the list */ pending = cancel_delayed_work_sync(&forw_packet->delayed_work); @@ -300,7 +300,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, if (pending) { hlist_del(&forw_packet->list); - forw_packet_free(forw_packet); + batadv_forw_packet_free(forw_packet); } } spin_unlock_bh(&bat_priv->forw_bcast_list_lock); @@ -327,7 +327,7 @@ void batadv_purge_outstanding_packets(struct bat_priv *bat_priv, if (pending) { hlist_del(&forw_packet->list); - forw_packet_free(forw_packet); + batadv_forw_packet_free(forw_packet); } } spin_unlock_bh(&bat_priv->forw_bat_list_lock); -- GitLab From 0294ca0d92c6539ec6e37edf65a0a5b033dd6d78 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:15 +0200 Subject: [PATCH 2632/6849] batman-adv: Prefix soft-interface local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/soft-interface.c | 80 +++++++++++++++++---------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index af676b818637..2de1d742119f 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -37,23 +37,23 @@ #include "bridge_loop_avoidance.h" -static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); -static void bat_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info); -static u32 bat_get_msglevel(struct net_device *dev); -static void bat_set_msglevel(struct net_device *dev, u32 value); -static u32 bat_get_link(struct net_device *dev); +static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); +static void batadv_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info); +static u32 batadv_get_msglevel(struct net_device *dev); +static void batadv_set_msglevel(struct net_device *dev, u32 value); +static u32 batadv_get_link(struct net_device *dev); static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data); static void batadv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data); static int batadv_get_sset_count(struct net_device *dev, int stringset); -static const struct ethtool_ops bat_ethtool_ops = { - .get_settings = bat_get_settings, - .get_drvinfo = bat_get_drvinfo, - .get_msglevel = bat_get_msglevel, - .set_msglevel = bat_set_msglevel, - .get_link = bat_get_link, +static const struct ethtool_ops batadv_ethtool_ops = { + .get_settings = batadv_get_settings, + .get_drvinfo = batadv_get_drvinfo, + .get_msglevel = batadv_get_msglevel, + .set_msglevel = batadv_set_msglevel, + .get_link = batadv_get_link, .get_strings = batadv_get_strings, .get_ethtool_stats = batadv_get_ethtool_stats, .get_sset_count = batadv_get_sset_count, @@ -78,25 +78,25 @@ int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) return 0; } -static int interface_open(struct net_device *dev) +static int batadv_interface_open(struct net_device *dev) { netif_start_queue(dev); return 0; } -static int interface_release(struct net_device *dev) +static int batadv_interface_release(struct net_device *dev) { netif_stop_queue(dev); return 0; } -static struct net_device_stats *interface_stats(struct net_device *dev) +static struct net_device_stats *batadv_interface_stats(struct net_device *dev) { struct bat_priv *bat_priv = netdev_priv(dev); return &bat_priv->stats; } -static int interface_set_mac_addr(struct net_device *dev, void *p) +static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) { struct bat_priv *bat_priv = netdev_priv(dev); struct sockaddr *addr = p; @@ -116,7 +116,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p) return 0; } -static int interface_change_mtu(struct net_device *dev, int new_mtu) +static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) { /* check ranges */ if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev))) @@ -127,7 +127,8 @@ static int interface_change_mtu(struct net_device *dev, int new_mtu) return 0; } -static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) +static int batadv_interface_tx(struct sk_buff *skb, + struct net_device *soft_iface) { struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct bat_priv *bat_priv = netdev_priv(soft_iface); @@ -323,23 +324,23 @@ out: return; } -static const struct net_device_ops bat_netdev_ops = { - .ndo_open = interface_open, - .ndo_stop = interface_release, - .ndo_get_stats = interface_stats, - .ndo_set_mac_address = interface_set_mac_addr, - .ndo_change_mtu = interface_change_mtu, - .ndo_start_xmit = interface_tx, +static const struct net_device_ops batadv_netdev_ops = { + .ndo_open = batadv_interface_open, + .ndo_stop = batadv_interface_release, + .ndo_get_stats = batadv_interface_stats, + .ndo_set_mac_address = batadv_interface_set_mac_addr, + .ndo_change_mtu = batadv_interface_change_mtu, + .ndo_start_xmit = batadv_interface_tx, .ndo_validate_addr = eth_validate_addr }; -static void interface_setup(struct net_device *dev) +static void batadv_interface_setup(struct net_device *dev) { struct bat_priv *priv = netdev_priv(dev); ether_setup(dev); - dev->netdev_ops = &bat_netdev_ops; + dev->netdev_ops = &batadv_netdev_ops; dev->destructor = free_netdev; dev->tx_queue_len = 0; @@ -353,7 +354,7 @@ static void interface_setup(struct net_device *dev) /* generate random address */ eth_hw_addr_random(dev); - SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); + SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops); memset(priv, 0, sizeof(*priv)); } @@ -364,7 +365,8 @@ struct net_device *batadv_softif_create(const char *name) struct bat_priv *bat_priv; int ret; - soft_iface = alloc_netdev(sizeof(*bat_priv), name, interface_setup); + soft_iface = alloc_netdev(sizeof(*bat_priv), name, + batadv_interface_setup); if (!soft_iface) goto out; @@ -456,14 +458,14 @@ void batadv_softif_destroy(struct net_device *soft_iface) int batadv_softif_is_valid(const struct net_device *net_dev) { - if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) + if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) return 1; return 0; } /* ethtool */ -static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { cmd->supported = 0; cmd->advertising = 0; @@ -479,8 +481,8 @@ static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) return 0; } -static void bat_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) +static void batadv_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { strcpy(info->driver, "B.A.T.M.A.N. advanced"); strcpy(info->version, SOURCE_VERSION); @@ -488,16 +490,16 @@ static void bat_get_drvinfo(struct net_device *dev, strcpy(info->bus_info, "batman"); } -static u32 bat_get_msglevel(struct net_device *dev) +static u32 batadv_get_msglevel(struct net_device *dev) { return -EOPNOTSUPP; } -static void bat_set_msglevel(struct net_device *dev, u32 value) +static void batadv_set_msglevel(struct net_device *dev, u32 value) { } -static u32 bat_get_link(struct net_device *dev) +static u32 batadv_get_link(struct net_device *dev) { return 1; } @@ -508,7 +510,7 @@ static u32 bat_get_link(struct net_device *dev) */ static const struct { const char name[ETH_GSTRING_LEN]; -} bat_counters_strings[] = { +} batadv_counters_strings[] = { { "forward" }, { "forward_bytes" }, { "mgmt_tx" }, @@ -527,8 +529,8 @@ static void batadv_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *data) { if (stringset == ETH_SS_STATS) - memcpy(data, bat_counters_strings, - sizeof(bat_counters_strings)); + memcpy(data, batadv_counters_strings, + sizeof(batadv_counters_strings)); } static void batadv_get_ethtool_stats(struct net_device *dev, -- GitLab From a513088d022c8f59cebe17c567797c220563b517 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:16 +0200 Subject: [PATCH 2633/6849] batman-adv: Prefix translation-table local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/translation-table.c | 540 +++++++++++++++-------------- 1 file changed, 282 insertions(+), 258 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 2eff22f9fdaa..f7a615261f4e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -29,13 +29,14 @@ #include -static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, - struct orig_node *orig_node); -static void tt_purge(struct work_struct *work); -static void tt_global_del_orig_list(struct tt_global_entry *tt_global_entry); +static void batadv_send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, + struct orig_node *orig_node); +static void batadv_tt_purge(struct work_struct *work); +static void +batadv_tt_global_del_orig_list(struct tt_global_entry *tt_global_entry); /* returns 1 if they are the same mac addr */ -static int compare_tt(const struct hlist_node *node, const void *data2) +static int batadv_compare_tt(const struct hlist_node *node, const void *data2) { const void *data1 = container_of(node, struct tt_common_entry, hash_entry); @@ -43,15 +44,15 @@ static int compare_tt(const struct hlist_node *node, const void *data2) return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } -static void tt_start_timer(struct bat_priv *bat_priv) +static void batadv_tt_start_timer(struct bat_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->tt_work, tt_purge); + INIT_DELAYED_WORK(&bat_priv->tt_work, batadv_tt_purge); queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work, msecs_to_jiffies(5000)); } -static struct tt_common_entry *tt_hash_find(struct hashtable_t *hash, - const void *data) +static struct tt_common_entry *batadv_tt_hash_find(struct hashtable_t *hash, + const void *data) { struct hlist_head *head; struct hlist_node *node; @@ -80,26 +81,26 @@ static struct tt_common_entry *tt_hash_find(struct hashtable_t *hash, return tt_common_entry_tmp; } -static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv, - const void *data) +static struct tt_local_entry * +batadv_tt_local_hash_find(struct bat_priv *bat_priv, const void *data) { struct tt_common_entry *tt_common_entry; struct tt_local_entry *tt_local_entry = NULL; - tt_common_entry = tt_hash_find(bat_priv->tt_local_hash, data); + tt_common_entry = batadv_tt_hash_find(bat_priv->tt_local_hash, data); if (tt_common_entry) tt_local_entry = container_of(tt_common_entry, struct tt_local_entry, common); return tt_local_entry; } -static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv, - const void *data) +static struct tt_global_entry * +batadv_tt_global_hash_find(struct bat_priv *bat_priv, const void *data) { struct tt_common_entry *tt_common_entry; struct tt_global_entry *tt_global_entry = NULL; - tt_common_entry = tt_hash_find(bat_priv->tt_global_hash, data); + tt_common_entry = batadv_tt_hash_find(bat_priv->tt_global_hash, data); if (tt_common_entry) tt_global_entry = container_of(tt_common_entry, struct tt_global_entry, common); @@ -107,13 +108,14 @@ static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv, } -static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry) +static void +batadv_tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry) { if (atomic_dec_and_test(&tt_local_entry->common.refcount)) kfree_rcu(tt_local_entry, common.rcu); } -static void tt_global_entry_free_rcu(struct rcu_head *rcu) +static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu) { struct tt_common_entry *tt_common_entry; struct tt_global_entry *tt_global_entry; @@ -125,16 +127,17 @@ static void tt_global_entry_free_rcu(struct rcu_head *rcu) kfree(tt_global_entry); } -static void tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry) +static void +batadv_tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry) { if (atomic_dec_and_test(&tt_global_entry->common.refcount)) { - tt_global_del_orig_list(tt_global_entry); + batadv_tt_global_del_orig_list(tt_global_entry); call_rcu(&tt_global_entry->common.rcu, - tt_global_entry_free_rcu); + batadv_tt_global_entry_free_rcu); } } -static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu) +static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) { struct tt_orig_list_entry *orig_entry; @@ -144,13 +147,14 @@ static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu) kfree(orig_entry); } -static void tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) +static void +batadv_tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) { - call_rcu(&orig_entry->rcu, tt_orig_list_entry_free_rcu); + call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); } -static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr, - uint8_t flags) +static void batadv_tt_local_event(struct bat_priv *bat_priv, + const uint8_t *addr, uint8_t flags) { struct tt_change_node *tt_change_node; @@ -176,7 +180,7 @@ int batadv_tt_len(int changes_num) return changes_num * sizeof(struct tt_change); } -static int tt_local_init(struct bat_priv *bat_priv) +static int batadv_tt_local_init(struct bat_priv *bat_priv) { if (bat_priv->tt_local_hash) return 0; @@ -200,7 +204,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, struct tt_orig_list_entry *orig_entry; int hash_added; - tt_local_entry = tt_local_hash_find(bat_priv, addr); + tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); if (tt_local_entry) { tt_local_entry->last_seen = jiffies; @@ -234,21 +238,21 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, */ tt_local_entry->common.flags |= TT_CLIENT_NEW; - hash_added = batadv_hash_add(bat_priv->tt_local_hash, compare_tt, + hash_added = batadv_hash_add(bat_priv->tt_local_hash, batadv_compare_tt, batadv_choose_orig, &tt_local_entry->common, &tt_local_entry->common.hash_entry); if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); goto out; } - tt_local_event(bat_priv, addr, tt_local_entry->common.flags); + batadv_tt_local_event(bat_priv, addr, tt_local_entry->common.flags); /* remove address from global hash if present */ - tt_global_entry = tt_global_hash_find(bat_priv, addr); + tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); /* Check whether it is a roaming! */ if (tt_global_entry) { @@ -258,8 +262,9 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, hlist_for_each_entry_rcu(orig_entry, node, head, list) { orig_entry->orig_node->tt_poss_change = true; - send_roam_adv(bat_priv, tt_global_entry->common.addr, - orig_entry->orig_node); + batadv_send_roam_adv(bat_priv, + tt_global_entry->common.addr, + orig_entry->orig_node); } rcu_read_unlock(); /* The global entry has to be marked as ROAMING and @@ -270,14 +275,15 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, } out: if (tt_local_entry) - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); if (tt_global_entry) - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); } -static void tt_realloc_packet_buff(unsigned char **packet_buff, - int *packet_buff_len, int min_packet_len, - int new_packet_len) +static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff, + int *packet_buff_len, + int min_packet_len, + int new_packet_len) { unsigned char *new_buff; @@ -292,9 +298,10 @@ static void tt_realloc_packet_buff(unsigned char **packet_buff, } } -static void tt_prepare_packet_buff(struct bat_priv *bat_priv, - unsigned char **packet_buff, - int *packet_buff_len, int min_packet_len) +static void batadv_tt_prepare_packet_buff(struct bat_priv *bat_priv, + unsigned char **packet_buff, + int *packet_buff_len, + int min_packet_len) { struct hard_iface *primary_if; int req_len; @@ -310,23 +317,24 @@ static void tt_prepare_packet_buff(struct bat_priv *bat_priv, if ((!primary_if) || (req_len > primary_if->soft_iface->mtu)) req_len = min_packet_len; - tt_realloc_packet_buff(packet_buff, packet_buff_len, - min_packet_len, req_len); + batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, + min_packet_len, req_len); if (primary_if) batadv_hardif_free_ref(primary_if); } -static int tt_changes_fill_buff(struct bat_priv *bat_priv, - unsigned char **packet_buff, - int *packet_buff_len, int min_packet_len) +static int batadv_tt_changes_fill_buff(struct bat_priv *bat_priv, + unsigned char **packet_buff, + int *packet_buff_len, + int min_packet_len) { struct tt_change_node *entry, *safe; int count = 0, tot_changes = 0, new_len; unsigned char *tt_buff; - tt_prepare_packet_buff(bat_priv, packet_buff, - packet_buff_len, min_packet_len); + batadv_tt_prepare_packet_buff(bat_priv, packet_buff, + packet_buff_len, min_packet_len); new_len = *packet_buff_len - min_packet_len; tt_buff = *packet_buff + min_packet_len; @@ -428,12 +436,12 @@ out: return ret; } -static void tt_local_set_pending(struct bat_priv *bat_priv, - struct tt_local_entry *tt_local_entry, - uint16_t flags, const char *message) +static void batadv_tt_local_set_pending(struct bat_priv *bat_priv, + struct tt_local_entry *tt_local_entry, + uint16_t flags, const char *message) { - tt_local_event(bat_priv, tt_local_entry->common.addr, - tt_local_entry->common.flags | flags); + batadv_tt_local_event(bat_priv, tt_local_entry->common.addr, + tt_local_entry->common.flags | flags); /* The local client has to be marked as "pending to be removed" but has * to be kept in the table in order to send it in a full table @@ -451,18 +459,19 @@ void batadv_tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr, { struct tt_local_entry *tt_local_entry = NULL; - tt_local_entry = tt_local_hash_find(bat_priv, addr); + tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); if (!tt_local_entry) goto out; - tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL | - (roaming ? TT_CLIENT_ROAM : NO_FLAGS), message); + batadv_tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL | + (roaming ? TT_CLIENT_ROAM : NO_FLAGS), + message); out: if (tt_local_entry) - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); } -static void tt_local_purge(struct bat_priv *bat_priv) +static void batadv_tt_local_purge(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->tt_local_hash; struct tt_local_entry *tt_local_entry; @@ -493,15 +502,15 @@ static void tt_local_purge(struct bat_priv *bat_priv) TT_LOCAL_TIMEOUT)) continue; - tt_local_set_pending(bat_priv, tt_local_entry, - TT_CLIENT_DEL, "timed out"); + batadv_tt_local_set_pending(bat_priv, tt_local_entry, + TT_CLIENT_DEL, "timed out"); } spin_unlock_bh(list_lock); } } -static void tt_local_table_free(struct bat_priv *bat_priv) +static void batadv_tt_local_table_free(struct bat_priv *bat_priv) { struct hashtable_t *hash; spinlock_t *list_lock; /* protects write access to the hash lists */ @@ -527,7 +536,7 @@ static void tt_local_table_free(struct bat_priv *bat_priv) tt_local_entry = container_of(tt_common_entry, struct tt_local_entry, common); - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); } spin_unlock_bh(list_lock); } @@ -537,7 +546,7 @@ static void tt_local_table_free(struct bat_priv *bat_priv) bat_priv->tt_local_hash = NULL; } -static int tt_global_init(struct bat_priv *bat_priv) +static int batadv_tt_global_init(struct bat_priv *bat_priv) { if (bat_priv->tt_global_hash) return 0; @@ -550,7 +559,7 @@ static int tt_global_init(struct bat_priv *bat_priv) return 0; } -static void tt_changes_list_free(struct bat_priv *bat_priv) +static void batadv_tt_changes_list_free(struct bat_priv *bat_priv) { struct tt_change_node *entry, *safe; @@ -569,8 +578,8 @@ static void tt_changes_list_free(struct bat_priv *bat_priv) /* find out if an orig_node is already in the list of a tt_global_entry. * returns 1 if found, 0 otherwise */ -static bool tt_global_entry_has_orig(const struct tt_global_entry *entry, - const struct orig_node *orig_node) +static bool batadv_tt_global_entry_has_orig(const struct tt_global_entry *entry, + const struct orig_node *orig_node) { struct tt_orig_list_entry *tmp_orig_entry; const struct hlist_head *head; @@ -589,9 +598,9 @@ static bool tt_global_entry_has_orig(const struct tt_global_entry *entry, return found; } -static void tt_global_add_orig_entry(struct tt_global_entry *tt_global_entry, - struct orig_node *orig_node, - int ttvn) +static void +batadv_tt_global_add_orig_entry(struct tt_global_entry *tt_global_entry, + struct orig_node *orig_node, int ttvn) { struct tt_orig_list_entry *orig_entry; @@ -621,7 +630,7 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, int hash_added; struct tt_common_entry *common; - tt_global_entry = tt_global_hash_find(bat_priv, tt_addr); + tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); if (!tt_global_entry) { tt_global_entry = kzalloc(sizeof(*tt_global_entry), @@ -640,16 +649,18 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, spin_lock_init(&tt_global_entry->list_lock); hash_added = batadv_hash_add(bat_priv->tt_global_hash, - compare_tt, batadv_choose_orig, - common, &common->hash_entry); + batadv_compare_tt, + batadv_choose_orig, common, + &common->hash_entry); if (unlikely(hash_added != 0)) { /* remove the reference for the hash */ - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); goto out_remove; } - tt_global_add_orig_entry(tt_global_entry, orig_node, ttvn); + batadv_tt_global_add_orig_entry(tt_global_entry, orig_node, + ttvn); } else { /* there is already a global entry, use this one. */ @@ -661,14 +672,15 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, * new one. */ if (tt_global_entry->common.flags & TT_CLIENT_ROAM) { - tt_global_del_orig_list(tt_global_entry); + batadv_tt_global_del_orig_list(tt_global_entry); tt_global_entry->common.flags &= ~TT_CLIENT_ROAM; tt_global_entry->roam_at = 0; } - if (!tt_global_entry_has_orig(tt_global_entry, orig_node)) - tt_global_add_orig_entry(tt_global_entry, orig_node, - ttvn); + if (!batadv_tt_global_entry_has_orig(tt_global_entry, + orig_node)) + batadv_tt_global_add_orig_entry(tt_global_entry, + orig_node, ttvn); } if (wifi) @@ -685,15 +697,16 @@ out_remove: ret = 1; out: if (tt_global_entry) - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); return ret; } /* print all orig nodes who announce the address for this global entry. * it is assumed that the caller holds rcu_read_lock(); */ -static void tt_global_print_entry(struct tt_global_entry *tt_global_entry, - struct seq_file *seq) +static void +batadv_tt_global_print_entry(struct tt_global_entry *tt_global_entry, + struct seq_file *seq) { struct hlist_head *head; struct hlist_node *node; @@ -760,7 +773,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) tt_global_entry = container_of(tt_common_entry, struct tt_global_entry, common); - tt_global_print_entry(tt_global_entry, seq); + batadv_tt_global_print_entry(tt_global_entry, seq); } rcu_read_unlock(); } @@ -771,7 +784,8 @@ out: } /* deletes the orig list of a tt_global_entry */ -static void tt_global_del_orig_list(struct tt_global_entry *tt_global_entry) +static void +batadv_tt_global_del_orig_list(struct tt_global_entry *tt_global_entry) { struct hlist_head *head; struct hlist_node *node, *safe; @@ -781,16 +795,17 @@ static void tt_global_del_orig_list(struct tt_global_entry *tt_global_entry) head = &tt_global_entry->orig_list; hlist_for_each_entry_safe(orig_entry, node, safe, head, list) { hlist_del_rcu(node); - tt_orig_list_entry_free_ref(orig_entry); + batadv_tt_orig_list_entry_free_ref(orig_entry); } spin_unlock_bh(&tt_global_entry->list_lock); } -static void tt_global_del_orig_entry(struct bat_priv *bat_priv, - struct tt_global_entry *tt_global_entry, - struct orig_node *orig_node, - const char *message) +static void +batadv_tt_global_del_orig_entry(struct bat_priv *bat_priv, + struct tt_global_entry *tt_global_entry, + struct orig_node *orig_node, + const char *message) { struct hlist_head *head; struct hlist_node *node, *safe; @@ -805,22 +820,22 @@ static void tt_global_del_orig_entry(struct bat_priv *bat_priv, orig_node->orig, tt_global_entry->common.addr, message); hlist_del_rcu(node); - tt_orig_list_entry_free_ref(orig_entry); + batadv_tt_orig_list_entry_free_ref(orig_entry); } } spin_unlock_bh(&tt_global_entry->list_lock); } -static void tt_global_del_struct(struct bat_priv *bat_priv, - struct tt_global_entry *tt_global_entry, - const char *message) +static void batadv_tt_global_del_struct(struct bat_priv *bat_priv, + struct tt_global_entry *tt_global_entry, + const char *message) { batadv_dbg(DBG_TT, bat_priv, "Deleting global tt entry %pM: %s\n", tt_global_entry->common.addr, message); - batadv_hash_remove(bat_priv->tt_global_hash, compare_tt, + batadv_hash_remove(bat_priv->tt_global_hash, batadv_compare_tt, batadv_choose_orig, tt_global_entry->common.addr); - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); } @@ -828,10 +843,10 @@ static void tt_global_del_struct(struct bat_priv *bat_priv, * within tt_global entry. If yes, we set the TT_CLIENT_ROAM flag and the timer, * otherwise we simply remove the originator scheduled for deletion. */ -static void tt_global_del_roaming(struct bat_priv *bat_priv, - struct tt_global_entry *tt_global_entry, - struct orig_node *orig_node, - const char *message) +static void +batadv_tt_global_del_roaming(struct bat_priv *bat_priv, + struct tt_global_entry *tt_global_entry, + struct orig_node *orig_node, const char *message) { bool last_entry = true; struct hlist_head *head; @@ -860,31 +875,31 @@ static void tt_global_del_roaming(struct bat_priv *bat_priv, /* there is another entry, we can simply delete this * one and can still use the other one. */ - tt_global_del_orig_entry(bat_priv, tt_global_entry, - orig_node, message); + batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry, + orig_node, message); } -static void tt_global_del(struct bat_priv *bat_priv, - struct orig_node *orig_node, - const unsigned char *addr, - const char *message, bool roaming) +static void batadv_tt_global_del(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const unsigned char *addr, + const char *message, bool roaming) { struct tt_global_entry *tt_global_entry = NULL; - struct tt_local_entry *tt_local_entry = NULL; + struct tt_local_entry *local_entry = NULL; - tt_global_entry = tt_global_hash_find(bat_priv, addr); + tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); if (!tt_global_entry) goto out; if (!roaming) { - tt_global_del_orig_entry(bat_priv, tt_global_entry, orig_node, - message); + batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry, + orig_node, message); if (hlist_empty(&tt_global_entry->orig_list)) - tt_global_del_struct(bat_priv, tt_global_entry, - message); + batadv_tt_global_del_struct(bat_priv, tt_global_entry, + message); goto out; } @@ -902,29 +917,29 @@ static void tt_global_del(struct bat_priv *bat_priv, * 2) the client roamed to us => we can directly delete * the global entry, since it is useless now. */ - tt_local_entry = tt_local_hash_find(bat_priv, - tt_global_entry->common.addr); - if (tt_local_entry) { + local_entry = batadv_tt_local_hash_find(bat_priv, + tt_global_entry->common.addr); + if (local_entry) { /* local entry exists, case 2: client roamed to us. */ - tt_global_del_orig_list(tt_global_entry); - tt_global_del_struct(bat_priv, tt_global_entry, message); + batadv_tt_global_del_orig_list(tt_global_entry); + batadv_tt_global_del_struct(bat_priv, tt_global_entry, message); } else /* no local entry exists, case 1: check for roaming */ - tt_global_del_roaming(bat_priv, tt_global_entry, orig_node, - message); + batadv_tt_global_del_roaming(bat_priv, tt_global_entry, + orig_node, message); out: if (tt_global_entry) - tt_global_entry_free_ref(tt_global_entry); - if (tt_local_entry) - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); + if (local_entry) + batadv_tt_local_entry_free_ref(local_entry); } void batadv_tt_global_del_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const char *message) { - struct tt_global_entry *tt_global_entry; + struct tt_global_entry *global_entry; struct tt_common_entry *tt_common_entry; uint32_t i; struct hashtable_t *hash = bat_priv->tt_global_hash; @@ -942,20 +957,19 @@ void batadv_tt_global_del_orig(struct bat_priv *bat_priv, spin_lock_bh(list_lock); hlist_for_each_entry_safe(tt_common_entry, node, safe, head, hash_entry) { - tt_global_entry = container_of(tt_common_entry, - struct tt_global_entry, - common); + global_entry = container_of(tt_common_entry, + struct tt_global_entry, + common); - tt_global_del_orig_entry(bat_priv, tt_global_entry, - orig_node, message); + batadv_tt_global_del_orig_entry(bat_priv, global_entry, + orig_node, message); - if (hlist_empty(&tt_global_entry->orig_list)) { + if (hlist_empty(&global_entry->orig_list)) { batadv_dbg(DBG_TT, bat_priv, "Deleting global tt entry %pM: %s\n", - tt_global_entry->common.addr, - message); + global_entry->common.addr, message); hlist_del_rcu(node); - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(global_entry); } } spin_unlock_bh(list_lock); @@ -964,7 +978,7 @@ void batadv_tt_global_del_orig(struct bat_priv *bat_priv, orig_node->tt_initialised = false; } -static void tt_global_roam_purge(struct bat_priv *bat_priv) +static void batadv_tt_global_roam_purge(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->tt_global_hash; struct tt_common_entry *tt_common_entry; @@ -995,14 +1009,14 @@ static void tt_global_roam_purge(struct bat_priv *bat_priv) tt_global_entry->common.addr); hlist_del_rcu(node); - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); } spin_unlock_bh(list_lock); } } -static void tt_global_table_free(struct bat_priv *bat_priv) +static void batadv_tt_global_table_free(struct bat_priv *bat_priv) { struct hashtable_t *hash; spinlock_t *list_lock; /* protects write access to the hash lists */ @@ -1028,7 +1042,7 @@ static void tt_global_table_free(struct bat_priv *bat_priv) tt_global_entry = container_of(tt_common_entry, struct tt_global_entry, common); - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); } spin_unlock_bh(list_lock); } @@ -1038,8 +1052,8 @@ static void tt_global_table_free(struct bat_priv *bat_priv) bat_priv->tt_global_hash = NULL; } -static bool _is_ap_isolated(struct tt_local_entry *tt_local_entry, - struct tt_global_entry *tt_global_entry) +static bool _batadv_is_ap_isolated(struct tt_local_entry *tt_local_entry, + struct tt_global_entry *tt_global_entry) { bool ret = false; @@ -1064,19 +1078,20 @@ struct orig_node *batadv_transtable_search(struct bat_priv *bat_priv, int best_tq; if (src && atomic_read(&bat_priv->ap_isolation)) { - tt_local_entry = tt_local_hash_find(bat_priv, src); + tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); if (!tt_local_entry) goto out; } - tt_global_entry = tt_global_hash_find(bat_priv, addr); + tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); if (!tt_global_entry) goto out; /* check whether the clients should not communicate due to AP * isolation */ - if (tt_local_entry && _is_ap_isolated(tt_local_entry, tt_global_entry)) + if (tt_local_entry && + _batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) goto out; best_tq = 0; @@ -1100,16 +1115,16 @@ struct orig_node *batadv_transtable_search(struct bat_priv *bat_priv, rcu_read_unlock(); out: if (tt_global_entry) - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); if (tt_local_entry) - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); return orig_node; } /* Calculates the checksum of the local table of a given orig_node */ -static uint16_t tt_global_crc(struct bat_priv *bat_priv, - struct orig_node *orig_node) +static uint16_t batadv_tt_global_crc(struct bat_priv *bat_priv, + struct orig_node *orig_node) { uint16_t total = 0, total_one; struct hashtable_t *hash = bat_priv->tt_global_hash; @@ -1140,8 +1155,8 @@ static uint16_t tt_global_crc(struct bat_priv *bat_priv, /* find out if this global entry is announced by this * originator */ - if (!tt_global_entry_has_orig(tt_global_entry, - orig_node)) + if (!batadv_tt_global_entry_has_orig(tt_global_entry, + orig_node)) continue; total_one = 0; @@ -1190,7 +1205,7 @@ static uint16_t batadv_tt_local_crc(struct bat_priv *bat_priv) return total; } -static void tt_req_list_free(struct bat_priv *bat_priv) +static void batadv_tt_req_list_free(struct bat_priv *bat_priv) { struct tt_req_node *node, *safe; @@ -1204,10 +1219,10 @@ static void tt_req_list_free(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->tt_req_list_lock); } -static void tt_save_orig_buffer(struct bat_priv *bat_priv, - struct orig_node *orig_node, - const unsigned char *tt_buff, - uint8_t tt_num_changes) +static void batadv_tt_save_orig_buffer(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const unsigned char *tt_buff, + uint8_t tt_num_changes) { uint16_t tt_buff_len = batadv_tt_len(tt_num_changes); @@ -1227,7 +1242,7 @@ static void tt_save_orig_buffer(struct bat_priv *bat_priv, spin_unlock_bh(&orig_node->tt_buff_lock); } -static void tt_req_purge(struct bat_priv *bat_priv) +static void batadv_tt_req_purge(struct bat_priv *bat_priv) { struct tt_req_node *node, *safe; @@ -1244,8 +1259,8 @@ static void tt_req_purge(struct bat_priv *bat_priv) /* returns the pointer to the new tt_req_node struct if no request * has already been issued for this orig_node, NULL otherwise */ -static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv, - struct orig_node *orig_node) +static struct tt_req_node *batadv_new_tt_req_node(struct bat_priv *bat_priv, + struct orig_node *orig_node) { struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; @@ -1271,7 +1286,8 @@ unlock: } /* data_ptr is useless here, but has to be kept to respect the prototype */ -static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr) +static int batadv_tt_local_valid_entry(const void *entry_ptr, + const void *data_ptr) { const struct tt_common_entry *tt_common_entry = entry_ptr; @@ -1280,7 +1296,8 @@ static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr) return 1; } -static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr) +static int batadv_tt_global_valid(const void *entry_ptr, + const void *data_ptr) { const struct tt_common_entry *tt_common_entry = entry_ptr; const struct tt_global_entry *tt_global_entry; @@ -1292,15 +1309,15 @@ static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr) tt_global_entry = container_of(tt_common_entry, struct tt_global_entry, common); - return tt_global_entry_has_orig(tt_global_entry, orig_node); + return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node); } -static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, - struct hashtable_t *hash, - struct hard_iface *primary_if, - int (*valid_cb)(const void *, - const void *), - void *cb_data) +static struct sk_buff * +batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, + struct hashtable_t *hash, + struct hard_iface *primary_if, + int (*valid_cb)(const void *, const void *), + void *cb_data) { struct tt_common_entry *tt_common_entry; struct tt_query_packet *tt_response; @@ -1361,9 +1378,10 @@ out: return skb; } -static int send_tt_request(struct bat_priv *bat_priv, - struct orig_node *dst_orig_node, - uint8_t ttvn, uint16_t tt_crc, bool full_table) +static int batadv_send_tt_request(struct bat_priv *bat_priv, + struct orig_node *dst_orig_node, + uint8_t ttvn, uint16_t tt_crc, + bool full_table) { struct sk_buff *skb = NULL; struct tt_query_packet *tt_request; @@ -1379,7 +1397,7 @@ static int send_tt_request(struct bat_priv *bat_priv, /* The new tt_req will be issued only if I'm not waiting for a * reply from the same orig_node yet */ - tt_req_node = new_tt_req_node(bat_priv, dst_orig_node); + tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node); if (!tt_req_node) goto out; @@ -1434,8 +1452,8 @@ out: return ret; } -static bool send_other_tt_response(struct bat_priv *bat_priv, - struct tt_query_packet *tt_request) +static bool batadv_send_other_tt_response(struct bat_priv *bat_priv, + struct tt_query_packet *tt_request) { struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL; struct neigh_node *neigh_node = NULL; @@ -1515,10 +1533,11 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, sizeof(struct tt_change); ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); - skb = tt_response_fill_table(tt_len, ttvn, - bat_priv->tt_global_hash, - primary_if, tt_global_valid_entry, - req_dst_orig_node); + skb = batadv_tt_response_fill_table(tt_len, ttvn, + bat_priv->tt_global_hash, + primary_if, + batadv_tt_global_valid, + req_dst_orig_node); if (!skb) goto out; @@ -1563,8 +1582,8 @@ out: return ret; } -static bool send_my_tt_response(struct bat_priv *bat_priv, - struct tt_query_packet *tt_request) +static bool batadv_send_my_tt_response(struct bat_priv *bat_priv, + struct tt_query_packet *tt_request) { struct orig_node *orig_node = NULL; struct neigh_node *neigh_node = NULL; @@ -1635,10 +1654,11 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, sizeof(struct tt_change); ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); - skb = tt_response_fill_table(tt_len, ttvn, - bat_priv->tt_local_hash, - primary_if, tt_local_valid_entry, - NULL); + skb = batadv_tt_response_fill_table(tt_len, ttvn, + bat_priv->tt_local_hash, + primary_if, + batadv_tt_local_valid_entry, + NULL); if (!skb) goto out; @@ -1689,26 +1709,28 @@ bool batadv_send_tt_response(struct bat_priv *bat_priv, if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) return true; - return send_my_tt_response(bat_priv, tt_request); + return batadv_send_my_tt_response(bat_priv, tt_request); } else { - return send_other_tt_response(bat_priv, tt_request); + return batadv_send_other_tt_response(bat_priv, tt_request); } } -static void _tt_update_changes(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct tt_change *tt_change, - uint16_t tt_num_changes, uint8_t ttvn) +static void _batadv_tt_update_changes(struct bat_priv *bat_priv, + struct orig_node *orig_node, + struct tt_change *tt_change, + uint16_t tt_num_changes, uint8_t ttvn) { int i; int is_wifi; + int roams; for (i = 0; i < tt_num_changes; i++) { if ((tt_change + i)->flags & TT_CLIENT_DEL) { - tt_global_del(bat_priv, orig_node, - (tt_change + i)->addr, - "tt removed by changes", - (tt_change + i)->flags & TT_CLIENT_ROAM); + roams = (tt_change + i)->flags & TT_CLIENT_ROAM; + batadv_tt_global_del(bat_priv, orig_node, + (tt_change + i)->addr, + "tt removed by changes", + roams); } else { is_wifi = (tt_change + i)->flags & TT_CLIENT_WIFI; if (!batadv_tt_global_add(bat_priv, orig_node, @@ -1726,8 +1748,8 @@ static void _tt_update_changes(struct bat_priv *bat_priv, orig_node->tt_initialised = true; } -static void tt_fill_gtable(struct bat_priv *bat_priv, - struct tt_query_packet *tt_response) +static void batadv_tt_fill_gtable(struct bat_priv *bat_priv, + struct tt_query_packet *tt_response) { struct orig_node *orig_node = NULL; @@ -1738,9 +1760,10 @@ static void tt_fill_gtable(struct bat_priv *bat_priv, /* Purge the old table first.. */ batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table"); - _tt_update_changes(bat_priv, orig_node, - (struct tt_change *)(tt_response + 1), - ntohs(tt_response->tt_data), tt_response->ttvn); + _batadv_tt_update_changes(bat_priv, orig_node, + (struct tt_change *)(tt_response + 1), + ntohs(tt_response->tt_data), + tt_response->ttvn); spin_lock_bh(&orig_node->tt_buff_lock); kfree(orig_node->tt_buff); @@ -1755,16 +1778,16 @@ out: batadv_orig_node_free_ref(orig_node); } -static void tt_update_changes(struct bat_priv *bat_priv, - struct orig_node *orig_node, - uint16_t tt_num_changes, uint8_t ttvn, - struct tt_change *tt_change) +static void batadv_tt_update_changes(struct bat_priv *bat_priv, + struct orig_node *orig_node, + uint16_t tt_num_changes, uint8_t ttvn, + struct tt_change *tt_change) { - _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes, - ttvn); + _batadv_tt_update_changes(bat_priv, orig_node, tt_change, + tt_num_changes, ttvn); - tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change, - tt_num_changes); + batadv_tt_save_orig_buffer(bat_priv, orig_node, + (unsigned char *)tt_change, tt_num_changes); atomic_set(&orig_node->last_ttvn, ttvn); } @@ -1773,7 +1796,7 @@ bool batadv_is_my_client(struct bat_priv *bat_priv, const uint8_t *addr) struct tt_local_entry *tt_local_entry = NULL; bool ret = false; - tt_local_entry = tt_local_hash_find(bat_priv, addr); + tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); if (!tt_local_entry) goto out; /* Check if the client has been logically deleted (but is kept for @@ -1784,7 +1807,7 @@ bool batadv_is_my_client(struct bat_priv *bat_priv, const uint8_t *addr) ret = true; out: if (tt_local_entry) - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); return ret; } @@ -1809,12 +1832,12 @@ void batadv_handle_tt_response(struct bat_priv *bat_priv, goto out; if (tt_response->flags & TT_FULL_TABLE) - tt_fill_gtable(bat_priv, tt_response); + batadv_tt_fill_gtable(bat_priv, tt_response); else - tt_update_changes(bat_priv, orig_node, - ntohs(tt_response->tt_data), - tt_response->ttvn, - (struct tt_change *)(tt_response + 1)); + batadv_tt_update_changes(bat_priv, orig_node, + ntohs(tt_response->tt_data), + tt_response->ttvn, + (struct tt_change *)(tt_response + 1)); /* Delete the tt_req_node from pending tt_requests list */ spin_lock_bh(&bat_priv->tt_req_list_lock); @@ -1827,7 +1850,7 @@ void batadv_handle_tt_response(struct bat_priv *bat_priv, spin_unlock_bh(&bat_priv->tt_req_list_lock); /* Recalculate the CRC for this orig_node and store it */ - orig_node->tt_crc = tt_global_crc(bat_priv, orig_node); + orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); /* Roaming phase is over: tables are in sync again. I can * unset the flag */ @@ -1841,20 +1864,20 @@ int batadv_tt_init(struct bat_priv *bat_priv) { int ret; - ret = tt_local_init(bat_priv); + ret = batadv_tt_local_init(bat_priv); if (ret < 0) return ret; - ret = tt_global_init(bat_priv); + ret = batadv_tt_global_init(bat_priv); if (ret < 0) return ret; - tt_start_timer(bat_priv); + batadv_tt_start_timer(bat_priv); return 1; } -static void tt_roam_list_free(struct bat_priv *bat_priv) +static void batadv_tt_roam_list_free(struct bat_priv *bat_priv) { struct tt_roam_node *node, *safe; @@ -1868,7 +1891,7 @@ static void tt_roam_list_free(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->tt_roam_list_lock); } -static void tt_roam_purge(struct bat_priv *bat_priv) +static void batadv_tt_roam_purge(struct bat_priv *bat_priv) { struct tt_roam_node *node, *safe; @@ -1889,8 +1912,8 @@ static void tt_roam_purge(struct bat_priv *bat_priv) * * returns true if the ROAMING_ADV can be sent, false otherwise */ -static bool tt_check_roam_count(struct bat_priv *bat_priv, - uint8_t *client) +static bool batadv_tt_check_roam_count(struct bat_priv *bat_priv, + uint8_t *client) { struct tt_roam_node *tt_roam_node; bool ret = false; @@ -1932,8 +1955,8 @@ unlock: return ret; } -static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, - struct orig_node *orig_node) +static void batadv_send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, + struct orig_node *orig_node) { struct neigh_node *neigh_node = NULL; struct sk_buff *skb = NULL; @@ -1944,7 +1967,7 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, /* before going on we have to check whether the client has * already roamed to us too many times */ - if (!tt_check_roam_count(bat_priv, client)) + if (!batadv_tt_check_roam_count(bat_priv, client)) goto out; skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN); @@ -1988,30 +2011,30 @@ out: return; } -static void tt_purge(struct work_struct *work) +static void batadv_tt_purge(struct work_struct *work) { struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); struct bat_priv *bat_priv = container_of(delayed_work, struct bat_priv, tt_work); - tt_local_purge(bat_priv); - tt_global_roam_purge(bat_priv); - tt_req_purge(bat_priv); - tt_roam_purge(bat_priv); + batadv_tt_local_purge(bat_priv); + batadv_tt_global_roam_purge(bat_priv); + batadv_tt_req_purge(bat_priv); + batadv_tt_roam_purge(bat_priv); - tt_start_timer(bat_priv); + batadv_tt_start_timer(bat_priv); } void batadv_tt_free(struct bat_priv *bat_priv) { cancel_delayed_work_sync(&bat_priv->tt_work); - tt_local_table_free(bat_priv); - tt_global_table_free(bat_priv); - tt_req_list_free(bat_priv); - tt_changes_list_free(bat_priv); - tt_roam_list_free(bat_priv); + batadv_tt_local_table_free(bat_priv); + batadv_tt_global_table_free(bat_priv); + batadv_tt_req_list_free(bat_priv); + batadv_tt_changes_list_free(bat_priv); + batadv_tt_roam_list_free(bat_priv); kfree(bat_priv->tt_buff); } @@ -2019,8 +2042,8 @@ void batadv_tt_free(struct bat_priv *bat_priv) /* This function will enable or disable the specified flags for all the entries * in the given hash table and returns the number of modified entries */ -static uint16_t tt_set_flags(struct hashtable_t *hash, uint16_t flags, - bool enable) +static uint16_t batadv_tt_set_flags(struct hashtable_t *hash, uint16_t flags, + bool enable) { uint32_t i; uint16_t changed_num = 0; @@ -2055,7 +2078,7 @@ out: } /* Purge out all the tt local entries marked with TT_CLIENT_PENDING */ -static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) +static void batadv_tt_local_purge_pending_clients(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->tt_local_hash; struct tt_common_entry *tt_common_entry; @@ -2087,28 +2110,28 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) tt_local_entry = container_of(tt_common_entry, struct tt_local_entry, common); - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); } spin_unlock_bh(list_lock); } } -static int tt_commit_changes(struct bat_priv *bat_priv, - unsigned char **packet_buff, int *packet_buff_len, - int packet_min_len) +static int batadv_tt_commit_changes(struct bat_priv *bat_priv, + unsigned char **packet_buff, + int *packet_buff_len, int packet_min_len) { uint16_t changed_num = 0; if (atomic_read(&bat_priv->tt_local_changes) < 1) return -ENOENT; - changed_num = tt_set_flags(bat_priv->tt_local_hash, - TT_CLIENT_NEW, false); + changed_num = batadv_tt_set_flags(bat_priv->tt_local_hash, + TT_CLIENT_NEW, false); /* all reset entries have to be counted as local entries */ atomic_add(changed_num, &bat_priv->num_local_tt); - tt_local_purge_pending_clients(bat_priv); + batadv_tt_local_purge_pending_clients(bat_priv); bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); /* Increment the TTVN only once per OGM interval */ @@ -2121,8 +2144,8 @@ static int tt_commit_changes(struct bat_priv *bat_priv, /* reset the sending counter */ atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); - return tt_changes_fill_buff(bat_priv, packet_buff, - packet_buff_len, packet_min_len); + return batadv_tt_changes_fill_buff(bat_priv, packet_buff, + packet_buff_len, packet_min_len); } /* when calling this function (hard_iface == primary_if) has to be true */ @@ -2133,14 +2156,15 @@ int batadv_tt_append_diff(struct bat_priv *bat_priv, int tt_num_changes; /* if at least one change happened */ - tt_num_changes = tt_commit_changes(bat_priv, packet_buff, - packet_buff_len, packet_min_len); + tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff, + packet_buff_len, + packet_min_len); /* if the changes have been sent often enough */ if ((tt_num_changes < 0) && (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { - tt_realloc_packet_buff(packet_buff, packet_buff_len, - packet_min_len, packet_min_len); + batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, + packet_min_len, packet_min_len); tt_num_changes = 0; } @@ -2157,24 +2181,24 @@ bool batadv_is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, if (!atomic_read(&bat_priv->ap_isolation)) return false; - tt_local_entry = tt_local_hash_find(bat_priv, dst); + tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst); if (!tt_local_entry) goto out; - tt_global_entry = tt_global_hash_find(bat_priv, src); + tt_global_entry = batadv_tt_global_hash_find(bat_priv, src); if (!tt_global_entry) goto out; - if (_is_ap_isolated(tt_local_entry, tt_global_entry)) + if (_batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) goto out; ret = false; out: if (tt_global_entry) - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); if (tt_local_entry) - tt_local_entry_free_ref(tt_local_entry); + batadv_tt_local_entry_free_ref(tt_local_entry); return ret; } @@ -2204,14 +2228,14 @@ void batadv_tt_update_orig(struct bat_priv *bat_priv, goto request_table; } - tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn, - (struct tt_change *)tt_buff); + batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, + ttvn, (struct tt_change *)tt_buff); /* Even if we received the precomputed crc with the OGM, we * prefer to recompute it to spot any possible inconsistency * in the global table */ - orig_node->tt_crc = tt_global_crc(bat_priv, orig_node); + orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); /* The ttvn alone is not enough to guarantee consistency * because a single value could represent different states @@ -2240,8 +2264,8 @@ request_table: "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n", orig_node->orig, ttvn, orig_ttvn, tt_crc, orig_node->tt_crc, tt_num_changes); - send_tt_request(bat_priv, orig_node, ttvn, tt_crc, - full_table); + batadv_send_tt_request(bat_priv, orig_node, ttvn, + tt_crc, full_table); return; } } @@ -2257,12 +2281,12 @@ bool batadv_tt_global_client_is_roaming(struct bat_priv *bat_priv, struct tt_global_entry *tt_global_entry; bool ret = false; - tt_global_entry = tt_global_hash_find(bat_priv, addr); + tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); if (!tt_global_entry) goto out; ret = tt_global_entry->common.flags & TT_CLIENT_ROAM; - tt_global_entry_free_ref(tt_global_entry); + batadv_tt_global_entry_free_ref(tt_global_entry); out: return ret; } -- GitLab From aa8521ec2889d5d1f2f0ed00c3295b8229135f98 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 20 Jun 2012 21:18:48 +0200 Subject: [PATCH 2634/6849] hwmon: (applesmc) correct email address for Jesper Juhl I've not had a gmail address for years. This commit updates the address to my actual working one. Signed-off-by: Jesper Juhl Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 70d62f5bc909..2cde9ecf7731 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -8,7 +8,7 @@ * * Based on hdaps.c driver: * Copyright (C) 2005 Robert Love - * Copyright (C) 2005 Jesper Juhl + * Copyright (C) 2005 Jesper Juhl * * Fan control based on smcFanControl: * Copyright (C) 2006 Hendrik Holtmann -- GitLab From d42f0349f3fed647c61c2d432e974bbdafcfb3fb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 25 Jun 2012 07:32:14 +0100 Subject: [PATCH 2635/6849] drm/udl: Make sure to get correct endian keys from vendor descriptor This is a port of commit b49f184b640dcfab7ede394cf2a1ff4fe3d154f5 Author: Ben Collins from udlfb to udl kms driver. The driver was not using le16_to_cpu when reading keys from the vendor descriptor, causing incorrect parsing. Mainly, sku_pixel_limit was not being parsed on big-endian systems. This would result in a blank screen on big-endian CPUs where the DL chips's max mode was smaller than the monitor's native mode. Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index a8d5f09428c7..4c2d836a0893 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -61,7 +61,7 @@ static int udl_parse_vendor_descriptor(struct drm_device *dev, u8 length; u16 key; - key = *((u16 *) desc); + key = le16_to_cpu(*((u16 *) desc)); desc += sizeof(u16); length = *desc; desc++; -- GitLab From b04db9ac4f7641332e0133b2fd8f82e6e4553947 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 21 Jun 2012 11:53:44 +0300 Subject: [PATCH 2636/6849] iwlwifi: configure the queues from the op_mode Since the op_mode defines the queue mapping, let it do it completely through the API functions. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/commands.h | 40 +++++++++++++- drivers/net/wireless/iwlwifi/dvm/dev.h | 16 ------ drivers/net/wireless/iwlwifi/dvm/main.c | 56 +------------------- drivers/net/wireless/iwlwifi/dvm/ucode.c | 37 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-trans.h | 27 ++++++---- drivers/net/wireless/iwlwifi/pcie/internal.h | 3 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 22 ++------ 7 files changed, 98 insertions(+), 103 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 64811cd91635..97bea16f3592 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -190,6 +190,44 @@ enum { REPLY_MAX = 0xff }; +/* + * Minimum number of queues. MAX_NUM is defined in hw specific files. + * Set the minimum to accommodate + * - 4 standard TX queues + * - the command queue + * - 4 PAN TX queues + * - the PAN multicast queue, and + * - the AUX (TX during scan dwell) queue. + */ +#define IWL_MIN_NUM_QUEUES 11 + +/* + * Command queue depends on iPAN support. + */ +#define IWL_DEFAULT_CMD_QUEUE_NUM 4 +#define IWL_IPAN_CMD_QUEUE_NUM 9 + +#define IWL_TX_FIFO_BK 0 /* shared */ +#define IWL_TX_FIFO_BE 1 +#define IWL_TX_FIFO_VI 2 /* shared */ +#define IWL_TX_FIFO_VO 3 +#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK +#define IWL_TX_FIFO_BE_IPAN 4 +#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI +#define IWL_TX_FIFO_VO_IPAN 5 +/* re-uses the VO FIFO, uCode will properly flush/schedule */ +#define IWL_TX_FIFO_AUX 5 +#define IWL_TX_FIFO_UNUSED 255 + +#define IWLAGN_CMD_FIFO_NUM 7 + +/* + * This queue number is required for proper operation + * because the ucode will stop/start the scheduler as + * required. + */ +#define IWL_IPAN_MCAST_QUEUE 8 + /****************************************************************************** * (0) * Commonly used structures and definitions: @@ -755,8 +793,6 @@ struct iwl_qosparam_cmd { #define IWLAGN_BROADCAST_ID 15 #define IWLAGN_STATION_COUNT 16 -#define IWL_INVALID_STATION 255 -#define IWL_MAX_TID_COUNT 8 #define IWL_TID_NON_QOS IWL_MAX_TID_COUNT #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 54cf085ddc89..054f728f6266 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -90,22 +90,6 @@ #define IWL_NUM_SCAN_RATES (2) -/* - * Minimum number of queues. MAX_NUM is defined in hw specific files. - * Set the minimum to accommodate - * - 4 standard TX queues - * - the command queue - * - 4 PAN TX queues - * - the PAN multicast queue, and - * - the AUX (TX during scan dwell) queue. - */ -#define IWL_MIN_NUM_QUEUES 11 - -/* - * Command queue depends on iPAN support. - */ -#define IWL_DEFAULT_CMD_QUEUE_NUM 4 -#define IWL_IPAN_CMD_QUEUE_NUM 9 #define IEEE80211_DATA_LEN 2304 #define IEEE80211_4ADDR_LEN 30 diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index abfd7916bde6..612f05d757db 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -518,49 +518,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) * queue/FIFO/AC mapping definitions */ -#define IWL_TX_FIFO_BK 0 /* shared */ -#define IWL_TX_FIFO_BE 1 -#define IWL_TX_FIFO_VI 2 /* shared */ -#define IWL_TX_FIFO_VO 3 -#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK -#define IWL_TX_FIFO_BE_IPAN 4 -#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI -#define IWL_TX_FIFO_VO_IPAN 5 -/* re-uses the VO FIFO, uCode will properly flush/schedule */ -#define IWL_TX_FIFO_AUX 5 -#define IWL_TX_FIFO_UNUSED -1 - -#define IWLAGN_CMD_FIFO_NUM 7 - -/* - * This queue number is required for proper operation - * because the ucode will stop/start the scheduler as - * required. - */ -#define IWL_IPAN_MCAST_QUEUE 8 - -static const u8 iwlagn_default_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWLAGN_CMD_FIFO_NUM, -}; - -static const u8 iwlagn_ipan_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWL_TX_FIFO_BK_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWL_TX_FIFO_VI_IPAN, - IWL_TX_FIFO_VO_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWLAGN_CMD_FIFO_NUM, - IWL_TX_FIFO_AUX, -}; - static const u8 iwlagn_bss_ac_to_fifo[] = { IWL_TX_FIFO_VO, IWL_TX_FIFO_VI, @@ -1350,6 +1307,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, else trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; trans_cfg.command_names = iwl_dvm_cmd_strings; + trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE < priv->cfg->base_params->num_of_queues); @@ -1363,15 +1321,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - trans_cfg.queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; - trans_cfg.n_queue_to_fifo = - ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo); } else { priv->sta_key_max_num = STA_KEY_MAX_NUM; trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo; - trans_cfg.n_queue_to_fifo = - ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); } /* Configure transport layer */ @@ -1460,9 +1412,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; priv->sta_key_max_num = STA_KEY_MAX_NUM; trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo; - trans_cfg.n_queue_to_fifo = - ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); /* Configure transport layer again*/ iwl_trans_configure(priv->trans, &trans_cfg); @@ -1480,9 +1429,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, atomic_set(&priv->queue_stop_count[i], 0); } - WARN_ON(trans_cfg.queue_to_fifo[trans_cfg.cmd_queue] != - IWLAGN_CMD_FIFO_NUM); - if (iwl_init_drv(priv)) goto out_free_eeprom; diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index b3a314ba48c7..6d8d6dd7943f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -226,13 +226,50 @@ int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) return ret; } +static const u8 iwlagn_default_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, +}; + +static const u8 iwlagn_ipan_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, + IWL_TX_FIFO_BK_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_VI_IPAN, + IWL_TX_FIFO_VO_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_UNUSED, + IWL_TX_FIFO_AUX, +}; static int iwl_alive_notify(struct iwl_priv *priv) { + const u8 *queue_to_txf; + u8 n_queues; int ret; + int i; iwl_trans_fw_alive(priv->trans); + if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && + priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) { + n_queues = ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo); + queue_to_txf = iwlagn_ipan_queue_to_tx_fifo; + } else { + n_queues = ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); + queue_to_txf = iwlagn_default_queue_to_tx_fifo; + } + + for (i = 0; i < n_queues; i++) + if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED) + iwl_trans_ac_txq_enable(priv->trans, i, + queue_to_txf[i]); + priv->passive_no_rx = false; priv->transport_queue_stop = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 00efde8e5536..867d8e194da4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -290,16 +290,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * currently supports */ #define IWL_MAX_HW_QUEUES 32 +#define IWL_INVALID_STATION 255 +#define IWL_MAX_TID_COUNT 8 +#define IWL_FRAME_LIMIT 64 /** * struct iwl_trans_config - transport configuration * * @op_mode: pointer to the upper layer. - * @queue_to_fifo: queue to FIFO mapping to set up by - * default - * @n_queue_to_fifo: number of queues to set up * @cmd_queue: the index of the command queue. * Must be set before start_fw. + * @cmd_fifo: the fifo for host commands * @no_reclaim_cmds: Some devices erroneously don't set the * SEQ_RX_FRAME bit on some notifications, this is the * list of such notifications to filter. Max length is @@ -314,10 +315,9 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) */ struct iwl_trans_config { struct iwl_op_mode *op_mode; - const u8 *queue_to_fifo; - u8 n_queue_to_fifo; u8 cmd_queue; + u8 cmd_fifo; const u8 *no_reclaim_cmds; int n_no_reclaim_cmds; @@ -355,9 +355,9 @@ struct iwl_trans; * Must be atomic * @reclaim: free packet until ssn. Returns a list of freed packets. * Must be atomic - * @txq_enable: setup a tx queue for AMPDU - will be called once the HW is - * ready and a successful ADDBA response has been received. - * May sleep + * @txq_enable: setup a queue. To setup an AC queue, use the + * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before + * this one. The op_mode must not configure the HCMD queue. May sleep. * @txq_disable: de-configure a Tx queue to send AMPDUs * Must be atomic * @wait_tx_queue_empty: wait until all tx queues are empty @@ -497,9 +497,9 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) { might_sleep(); - trans->ops->fw_alive(trans); - trans->state = IWL_TRANS_FW_ALIVE; + + trans->ops->fw_alive(trans); } static inline int iwl_trans_start_fw(struct iwl_trans *trans, @@ -593,6 +593,13 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, frame_limit, ssn); } +static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, + int fifo) +{ + iwl_trans_txq_enable(trans, queue, fifo, IWL_INVALID_STATION, + IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); +} + static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 5024fb662bf6..d9694c58208c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -269,10 +269,9 @@ struct iwl_trans_pcie { wait_queue_head_t ucode_write_waitq; unsigned long status; u8 cmd_queue; + u8 cmd_fifo; u8 n_no_reclaim_cmds; u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; - u8 setup_q_to_fifo[IWL_MAX_HW_QUEUES]; - u8 n_q_to_fifo; bool rx_buf_size_8k; u32 rx_page_order; diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 42f369d15f48..bac0eb0d046d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1059,7 +1059,7 @@ static void iwl_tx_start(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 a; - int i, chan; + int chan; u32 reg_val; /* make sure all queue are not stopped/used */ @@ -1091,12 +1091,8 @@ static void iwl_tx_start(struct iwl_trans *trans) */ iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); - for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { - int fifo = trans_pcie->setup_q_to_fifo[i]; - - iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, - IWL_TID_NON_QOS, SCD_FRAME_LIMIT, 0); - } + iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, + trans_pcie->cmd_fifo); /* Activate all Tx DMA/FIFO channels */ iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); @@ -1528,6 +1524,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->cmd_queue = trans_cfg->cmd_queue; + trans_pcie->cmd_fifo = trans_cfg->cmd_fifo; if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) trans_pcie->n_no_reclaim_cmds = 0; else @@ -1536,17 +1533,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, trans_pcie->n_no_reclaim_cmds * sizeof(u8)); - trans_pcie->n_q_to_fifo = trans_cfg->n_queue_to_fifo; - - if (WARN_ON(trans_pcie->n_q_to_fifo > IWL_MAX_HW_QUEUES)) - trans_pcie->n_q_to_fifo = IWL_MAX_HW_QUEUES; - - /* at least the command queue must be mapped */ - WARN_ON(!trans_pcie->n_q_to_fifo); - - memcpy(trans_pcie->setup_q_to_fifo, trans_cfg->queue_to_fifo, - trans_pcie->n_q_to_fifo * sizeof(u8)); - trans_pcie->rx_buf_size_8k = trans_cfg->rx_buf_size_8k; if (trans_pcie->rx_buf_size_8k) trans_pcie->rx_page_order = get_order(8 * 1024); -- GitLab From eecf21a126dd23030c66949796561a9b0dde8b6e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 15:21:02 +0200 Subject: [PATCH 2637/6849] iwlwifi: bump trace message limit There's one message that goes just over the limit of 100 characters, so bump the limit to 110 to get rid of the warning from that. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 65364793021f..ad2dba8fc450 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -176,7 +176,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_msg -#define MAX_MSG_LEN 100 +#define MAX_MSG_LEN 110 DECLARE_EVENT_CLASS(iwlwifi_msg_event, TP_PROTO(struct va_format *vaf), -- GitLab From 94bfa4a255b3436e9a258585be6687d1f5c02a71 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 19:39:23 +0200 Subject: [PATCH 2638/6849] iwlwifi: use __get_str in tracing __get_str() is identical to (char *)__get_dynamic_array() that is in the code now, substitute __get_str to make the code more readable. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index ad2dba8fc450..06ca505bb2cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -189,7 +189,7 @@ DECLARE_EVENT_CLASS(iwlwifi_msg_event, MAX_MSG_LEN, vaf->fmt, *vaf->va) >= MAX_MSG_LEN); ), - TP_printk("%s", (char *)__get_dynamic_array(msg)) + TP_printk("%s", __get_str(msg)) ); DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err, -- GitLab From af77c88b8971232f23b4cba7a46fc7a43914bf22 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Gaddipati Date: Mon, 25 Jun 2012 00:25:41 -0700 Subject: [PATCH 2639/6849] Input: nomadik-ske-keypad - add multi key press support Added the multi key press support for SKE keypad by modifying the irq function for handling the two different keys on the same column and also pressing the two different keys of different columns on the same ASR register. Signed-off-by: Naveen Kumar Gaddipati Reviewed-by: Srinidhi Kasagar Signed-off-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 65 +++++++++++++-------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 4ea4341a68c5..6857454bb13c 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -135,12 +135,37 @@ static int __init ske_keypad_chip_init(struct ske_keypad *keypad) return 0; } -static void ske_keypad_read_data(struct ske_keypad *keypad) +static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col) { + int row = 0, code, pos; struct input_dev *input = keypad->input; - u16 status; - int col = 0, row = 0, code; - int ske_asr, ske_ris, key_pressed, i; + u32 ske_ris; + int key_pressed; + int num_of_rows; + + /* find out the row */ + num_of_rows = hweight8(status); + do { + pos = __ffs(status); + row = pos; + status &= ~(1 << pos); + + code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); + ske_ris = readl(keypad->reg_base + SKE_RIS); + key_pressed = ske_ris & SKE_KPRISA; + + input_event(input, EV_MSC, MSC_SCAN, code); + input_report_key(input, keypad->keymap[code], key_pressed); + input_sync(input); + num_of_rows--; + } while (num_of_rows); +} + +static void ske_keypad_read_data(struct ske_keypad *keypad) +{ + u8 status; + int col = 0; + int ske_asr, i; /* * Read the auto scan registers @@ -154,25 +179,17 @@ static void ske_keypad_read_data(struct ske_keypad *keypad) if (!ske_asr) continue; - /* now that ASRx is zero, find out the column x and row y*/ - if (ske_asr & 0xff) { + /* now that ASRx is zero, find out the coloumn x and row y */ + status = ske_asr & 0xff; + if (status) { col = i * 2; - status = ske_asr & 0xff; - } else { + ske_keypad_report(keypad, status, col); + } + status = (ske_asr & 0xff00) >> 8; + if (status) { col = (i * 2) + 1; - status = (ske_asr & 0xff00) >> 8; + ske_keypad_report(keypad, status, col); } - - /* find out the row */ - row = __ffs(status); - - code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); - ske_ris = readl(keypad->reg_base + SKE_RIS); - key_pressed = ske_ris & SKE_KPRISA; - - input_event(input, EV_MSC, MSC_SCAN, code); - input_report_key(input, keypad->keymap[code], key_pressed); - input_sync(input); } } @@ -186,12 +203,10 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id) ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) - msleep(5); + cpu_relax(); - if (retries) { - /* SKEx registers are stable and can be read */ - ske_keypad_read_data(keypad); - } + /* SKEx registers are stable and can be read */ + ske_keypad_read_data(keypad); /* enable auto scan interrupts */ ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); -- GitLab From 84b63ad8477c822edbeb1e310b201609f33522ec Mon Sep 17 00:00:00 2001 From: Naveen Kumar Gaddipati Date: Mon, 25 Jun 2012 00:34:36 -0700 Subject: [PATCH 2640/6849] Input: nomadik-ske-keypad - get rid of multiple interrupts The keypad could cause multiple interrupts to be fired in succession since we weren't waiting for the IRQs to clear properly in the interrupt handler. We wait for a number of bus iterations (the readl():s from the peripheral bus will stall, so these are quite long) before giving up on getting keys ready to read, then we sleep until the IRQ is deasserted (this is OK since the interrupt is threaded). Also use the debounce platform data for another hardcoded wait loop. Signed-off-by: Naveen Kumar Gaddipati Reviewed-by: Rikard Olsson Reviewed-by: Srinidhi Kasagar Signed-off-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 6857454bb13c..a880e7414202 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -49,6 +49,7 @@ #define SKE_ASR3 0x2C #define SKE_NUM_ASRX_REGISTERS (4) +#define KEY_PRESSED_DELAY 10 /** * struct ske_keypad - data structure used by keypad driver @@ -92,7 +93,7 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, static int __init ske_keypad_chip_init(struct ske_keypad *keypad) { u32 value; - int timeout = 50; + int timeout = keypad->board->debounce_ms; /* check SKE_RIS to be 0 */ while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) @@ -196,18 +197,22 @@ static void ske_keypad_read_data(struct ske_keypad *keypad) static irqreturn_t ske_keypad_irq(int irq, void *dev_id) { struct ske_keypad *keypad = dev_id; - int retries = 20; + int timeout = keypad->board->debounce_ms; /* disable auto scan interrupt; mask the interrupt generated */ ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); - while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) + while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --timeout) cpu_relax(); /* SKEx registers are stable and can be read */ ske_keypad_read_data(keypad); + /* wait until raw interrupt is clear */ + while ((readl(keypad->reg_base + SKE_RIS)) && --timeout) + msleep(KEY_PRESSED_DELAY); + /* enable auto scan interrupts */ ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); -- GitLab From 125821ae539ab60f432b5e10dadfd7bbf069ca7a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Jun 2012 14:30:29 +0200 Subject: [PATCH 2641/6849] ALSA: hda - Add the inverted digital mic workaround to Realtek codecs Some laptops are equipped with ForteMedia digital mics that give the differential input. With such devices, summing stereo streams into a mono (like PulseAudio does) results in almost silence. This patch provides a workaround for this bug by adding a new mixer switch to turn on/off the right channel of digital mic, just like a similar fix for Conexant codecs. When the new switch "Inverted Internal Mic Capture Switch" is off and the current input source is the digital mic, the right channel of the recording stream is muted. When another input source is selected, the right channel is restored. Tested-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 127 +++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f8f4906e498d..a0a3cf956503 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -170,6 +170,7 @@ struct alc_spec { hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ + hda_nid_t inv_dmic_pin; /* hooks */ void (*init_hook)(struct hda_codec *codec); @@ -201,6 +202,8 @@ struct alc_spec { unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ + unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ + unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ /* auto-mute control */ int automute_mode; @@ -298,6 +301,7 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) } static void call_update_outputs(struct hda_codec *codec); +static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); /* select the given imux item; either unmute exclusively or select the route */ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, @@ -368,6 +372,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, AC_VERB_SET_CONNECT_SEL, imux->items[idx].index); } + alc_inv_dmic_sync(codec, true); return 1; } @@ -1556,14 +1561,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol, - getput_call_t func, bool check_adc_switch) + getput_call_t func, bool is_put) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; int i, err = 0; mutex_lock(&codec->control_mutex); - if (check_adc_switch && spec->dyn_adc_switch) { + if (is_put && spec->dyn_adc_switch) { for (i = 0; i < spec->num_adc_nids; i++) { kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], @@ -1584,6 +1589,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 3, 0, HDA_INPUT); err = func(kcontrol, ucontrol); } + if (err >= 0 && is_put) + alc_inv_dmic_sync(codec, false); error: mutex_unlock(&codec->control_mutex); return err; @@ -1675,6 +1682,108 @@ DEFINE_CAPMIX_NOSRC(1); DEFINE_CAPMIX_NOSRC(2); DEFINE_CAPMIX_NOSRC(3); +/* + * Inverted digital-mic handling + * + * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" + * gives the additional mute only to the right channel of the digital mic + * capture stream. This is a workaround for avoiding the almost silence + * by summing the stereo stream from some (known to be ForteMedia) + * digital mic unit. + * + * The logic is to call alc_inv_dmic_sync() after each action (possibly) + * modifying ADC amp. When the mute flag is set, it mutes the R-channel + * without caching so that the cache can still keep the original value. + * The cached value is then restored when the flag is set off or any other + * than d-mic is used as the current input source. + */ +static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) +{ + struct alc_spec *spec = codec->spec; + int i; + + if (!spec->inv_dmic_fixup) + return; + if (!spec->inv_dmic_muted && !force) + return; + for (i = 0; i < spec->num_adc_nids; i++) { + int src = spec->dyn_adc_switch ? 0 : i; + bool dmic_fixup = false; + hda_nid_t nid; + int parm, dir, v; + + if (spec->inv_dmic_muted && + spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin) + dmic_fixup = true; + if (!dmic_fixup && !force) + continue; + if (spec->vol_in_capsrc) { + nid = spec->capsrc_nids[i]; + parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT; + dir = HDA_OUTPUT; + } else { + nid = spec->adc_nids[i]; + parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT; + dir = HDA_INPUT; + } + /* we care only right channel */ + v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); + if (v & 0x80) /* if already muted, we don't need to touch */ + continue; + if (dmic_fixup) /* add mute for d-mic */ + v |= 0x80; + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + parm | v); + } +} + +static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + + ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; + return 0; +} + +static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + unsigned int val = !ucontrol->value.integer.value[0]; + + if (val == spec->inv_dmic_muted) + return 0; + spec->inv_dmic_muted = val; + alc_inv_dmic_sync(codec, true); + return 0; +} + +static const struct snd_kcontrol_new alc_inv_dmic_sw = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_ctl_boolean_mono_info, + .get = alc_inv_dmic_sw_get, + .put = alc_inv_dmic_sw_put, +}; + +static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) +{ + struct alc_spec *spec = codec->spec; + struct snd_kcontrol_new *knew = alc_kcontrol_new(spec); + if (!knew) + return -ENOMEM; + *knew = alc_inv_dmic_sw; + knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL); + if (!knew->name) + return -ENOMEM; + spec->inv_dmic_fixup = 1; + spec->inv_dmic_muted = 0; + spec->inv_dmic_pin = nid; + return 0; +} + /* * virtual master controls */ @@ -2316,6 +2425,7 @@ static int alc_resume(struct hda_codec *codec) codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); + alc_inv_dmic_sync(codec, true); hda_call_check_power_status(codec, 0x01); return 0; } @@ -6424,6 +6534,13 @@ static void alc272_fixup_mario(struct hda_codec *codec, "hda_codec: failed to override amp caps for NID 0x2\n"); } +static void alc662_fixup_inv_dmic(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + if (action == ALC_FIXUP_ACT_PROBE) + alc_add_inv_dmic_mixer(codec, 0x12); +} + enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, @@ -6441,6 +6558,7 @@ enum { ALC662_FIXUP_ASUS_MODE8, ALC662_FIXUP_NO_JACK_DETECT, ALC662_FIXUP_ZOTAC_Z68, + ALC662_FIXUP_INV_DMIC, }; static const struct alc_fixup alc662_fixups[] = { @@ -6597,12 +6715,17 @@ static const struct alc_fixup alc662_fixups[] = { { } } }, + [ALC662_FIXUP_INV_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc662_fixup_inv_dmic, + }, }; static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), -- GitLab From 593f47355467b9ef44293698817e2bdb347e2d11 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 21 Jun 2012 11:48:11 +0200 Subject: [PATCH 2642/6849] ARM: dma-mapping: fix buffer chunk allocation order IOMMU-aware dma_alloc_attrs() implementation allocates buffers in power-of-two chunks to improve performance and take advantage of large page mappings provided by some IOMMU hardware. However current code, due to a subtle bug, allocated those chunks in the smallest-to-largest order, what completely killed all the advantages of using larger than page chunks. If a 4KiB chunk has been mapped as a first chunk, the consecutive chunks are not aligned correctly to the power-of-two which match their size and IOMMU drivers were not able to use internal mappings of size other than the 4KiB (largest common denominator of alignment and chunk size). This patch fixes this issue by changing to the correct largest-to-smallest chunk size allocation sequence. Signed-off-by: Marek Szyprowski --- arch/arm/mm/dma-mapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index d766e4256b74..4044abcf6f9d 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1067,7 +1067,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t return NULL; while (count) { - int j, order = __ffs(count); + int j, order = __fls(count); pages[i] = alloc_pages(gfp | __GFP_NOWARN, order); while (!pages[i] && order) -- GitLab From 693b613dc4657e3f9af2625e0097b1870c78bf8c Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Fri, 22 Jun 2012 19:12:10 +0200 Subject: [PATCH 2643/6849] ALSA: hda - Add inverted mic quirks for Asus U41SV, Acer 1810TZ and AOD260 These machines have inverted phase on right channel for their internal mics. BugLink: https://bugs.launchpad.net/bugs/997227 BugLink: https://bugs.launchpad.net/bugs/996611 BugLink: https://bugs.launchpad.net/bugs/1006089 Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a0a3cf956503..d11fd0160748 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5918,6 +5918,14 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec, } } +static void alc269_fixup_inv_dmic(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + if (action == ALC_FIXUP_ACT_PROBE) + alc_add_inv_dmic_mixer(codec, 0x12); +} + + enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -5936,6 +5944,7 @@ enum { ALC269VB_FIXUP_AMIC, ALC269VB_FIXUP_DMIC, ALC269_FIXUP_MIC2_MUTE_LED, + ALC269_FIXUP_INV_DMIC, }; static const struct alc_fixup alc269_fixups[] = { @@ -6060,12 +6069,19 @@ static const struct alc_fixup alc269_fixups[] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_mic2_mute, }, + [ALC269_FIXUP_INV_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc269_fixup_inv_dmic, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), + SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), + SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), @@ -6534,12 +6550,7 @@ static void alc272_fixup_mario(struct hda_codec *codec, "hda_codec: failed to override amp caps for NID 0x2\n"); } -static void alc662_fixup_inv_dmic(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - if (action == ALC_FIXUP_ACT_PROBE) - alc_add_inv_dmic_mixer(codec, 0x12); -} +#define alc662_fixup_inv_dmic alc269_fixup_inv_dmic enum { ALC662_FIXUP_ASPIRE, -- GitLab From 357398e96d8c883b010379a7669df43ed0e2e32b Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 20 Jun 2012 18:39:27 +0200 Subject: [PATCH 2644/6849] perf/x86: Fix section mismatch in uncore_pci_init() Fix section mismatch in uncore_pci_init(): WARNING: vmlinux.o(.init.text+0x9246): Section mismatch in reference from the function uncore_pci_init() to the function .devexit.text:uncore_pci_remove() The function __init uncore_pci_init() references a function __devexit uncore_pci_remove(). [...] Signed-off-by: Robert Richter Cc: Cc: Link: http://lkml.kernel.org/r/20120620163927.GI5046@erda.amd.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 28a8413ca199..6f43f9584e3d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -1313,7 +1313,7 @@ static int __devinit uncore_pci_add(struct intel_uncore_type *type, return 0; } -static void __devexit uncore_pci_remove(struct pci_dev *pdev) +static void uncore_pci_remove(struct pci_dev *pdev) { struct intel_uncore_box *box = pci_get_drvdata(pdev); struct intel_uncore_pmu *pmu = box->pmu; -- GitLab From 6e72aa5f511daa2ffbd333ea99635c551b86013b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Jun 2012 10:52:25 +0200 Subject: [PATCH 2645/6849] ALSA: hda - Add inv-dmic model to possible Realtek codecs For convenience, add "inv-dmic" model string for enabling the inverted internal mic workaround to possible Realtek codecs, so far, ALC882-variants, ALC262, ALC268, ALC269-variants, and ALC662-variants. Also, the model strings for hardware inv-dmic workarounds, "alc269-dmic" and "alc271-dmic", are added for ALC269(VA) and ALC271 codecs as well. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 64 ++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d11fd0160748..3e698e239dd8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1784,6 +1784,14 @@ static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) return 0; } +/* typically the digital mic is put at node 0x12 */ +static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + if (action == ALC_FIXUP_ACT_PROBE) + alc_add_inv_dmic_mixer(codec, 0x12); +} + /* * virtual master controls */ @@ -5017,6 +5025,7 @@ enum { ALC889_FIXUP_DAC_ROUTE, ALC889_FIXUP_MBP_VREF, ALC889_FIXUP_IMAC91_VREF, + ALC882_FIXUP_INV_DMIC, }; static void alc889_fixup_coef(struct hda_codec *codec, @@ -5320,6 +5329,10 @@ static const struct alc_fixup alc882_fixups[] = { .chained = true, .chain_id = ALC882_FIXUP_GPIO1, }, + [ALC882_FIXUP_INV_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic_0x12, + }, }; static const struct snd_pci_quirk alc882_fixup_tbl[] = { @@ -5394,6 +5407,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = { {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, + {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, {} }; @@ -5481,6 +5495,7 @@ enum { ALC262_FIXUP_LENOVO_3000, ALC262_FIXUP_BENQ, ALC262_FIXUP_BENQ_T31, + ALC262_FIXUP_INV_DMIC, }; static const struct alc_fixup alc262_fixups[] = { @@ -5532,6 +5547,10 @@ static const struct alc_fixup alc262_fixups[] = { {} } }, + [ALC262_FIXUP_INV_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic_0x12, + }, }; static const struct snd_pci_quirk alc262_fixup_tbl[] = { @@ -5546,6 +5565,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { {} }; +static const struct alc_model_fixup alc262_fixup_models[] = { + {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {} +}; /* */ @@ -5574,7 +5597,8 @@ static int patch_alc262(struct hda_codec *codec) #endif alc_fix_pll_init(codec, 0x20, 0x0a, 10); - alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); + alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, + alc262_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); @@ -5630,6 +5654,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = { { } }; +enum { + ALC268_FIXUP_INV_DMIC, +}; + +static const struct alc_fixup alc268_fixups[] = { + [ALC268_FIXUP_INV_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic_0x12, + }, +}; + +static const struct alc_model_fixup alc268_fixup_models[] = { + {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {} +}; + /* * BIOS auto configuration */ @@ -5661,6 +5701,9 @@ static int patch_alc268(struct hda_codec *codec) spec = codec->spec; + alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + /* automatic parse from the BIOS config */ err = alc268_parse_auto_config(codec); if (err < 0) @@ -5690,6 +5733,8 @@ static int patch_alc268(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; spec->shutup = alc_eapd_shutup; + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + return 0; error: @@ -5918,13 +5963,6 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec, } } -static void alc269_fixup_inv_dmic(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - if (action == ALC_FIXUP_ACT_PROBE) - alc_add_inv_dmic_mixer(codec, 0x12); -} - enum { ALC269_FIXUP_SONY_VAIO, @@ -6071,7 +6109,7 @@ static const struct alc_fixup alc269_fixups[] = { }, [ALC269_FIXUP_INV_DMIC] = { .type = ALC_FIXUP_FUNC, - .v.func = alc269_fixup_inv_dmic, + .v.func = alc_fixup_inv_dmic_0x12, }, }; @@ -6157,6 +6195,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct alc_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, + {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, + {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, + {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, {} }; @@ -6550,8 +6591,6 @@ static void alc272_fixup_mario(struct hda_codec *codec, "hda_codec: failed to override amp caps for NID 0x2\n"); } -#define alc662_fixup_inv_dmic alc269_fixup_inv_dmic - enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, @@ -6728,7 +6767,7 @@ static const struct alc_fixup alc662_fixups[] = { }, [ALC662_FIXUP_INV_DMIC] = { .type = ALC_FIXUP_FUNC, - .v.func = alc662_fixup_inv_dmic, + .v.func = alc_fixup_inv_dmic_0x12, }, }; @@ -6817,6 +6856,7 @@ static const struct alc_model_fixup alc662_fixup_models[] = { {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, + {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, {} }; -- GitLab From 1573ee81cb9ef24fa5acee6b7442e215e63ede2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 25 Jun 2012 09:28:46 +0200 Subject: [PATCH 2646/6849] ASoC: dmaengine_pcm: fix typo in comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Mark Brown --- sound/soc/soc-dmaengine-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 2995334d8000..5df529eda251 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -270,7 +270,7 @@ static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd * Note that this function will use private_data field of the substream's * runtime. So it is not availabe to your pcm driver implementation. If you need * to keep additional data attached to a substream use - * snd_dmaeinge_pcm_{set,get}_data. + * snd_dmaengine_pcm_{set,get}_data. */ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data) -- GitLab From fd88759a42dc10f8230b3933a1ceb40bd88fccea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:30:43 +0800 Subject: [PATCH 2647/6849] ASoC: wm8904: Rely entirely on the core for bias level management Even though the WM8904 is able to use idle_bias_off during both probe and resume we were needlessly leaving the device in standby mode. Instead power the device down as soon as we've confirmed that we can talk to it and don't manage the bias level at all over suspend and resume, the core will take us down to our minimum power level. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 5417b1183acb..ecab871573b1 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1945,25 +1945,6 @@ static struct snd_soc_dai_driver wm8904_dai = { .symmetric_rates = 1, }; -#ifdef CONFIG_PM -static int wm8904_suspend(struct snd_soc_codec *codec) -{ - wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm8904_resume(struct snd_soc_codec *codec) -{ - wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define wm8904_suspend NULL -#define wm8904_resume NULL -#endif - static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); @@ -2143,7 +2124,10 @@ static int wm8904_probe(struct snd_soc_codec *codec) goto err_enable; } + /* Can leave the device powered off until we need it */ regcache_cache_only(wm8904->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); + /* Change some default settings - latch VU and enable ZC */ snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, WM8904_ADC_VU, WM8904_ADC_VU); @@ -2198,11 +2182,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, WM8904_POBCTRL, 0); - wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - /* Bias level configuration will have done an extra enable */ - regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); - wm8904_handle_pdata(codec); wm8904_add_widgets(codec); @@ -2220,7 +2199,6 @@ static int wm8904_remove(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); - wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); kfree(wm8904->retune_mobile_texts); kfree(wm8904->drc_texts); @@ -2231,8 +2209,6 @@ static int wm8904_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { .probe = wm8904_probe, .remove = wm8904_remove, - .suspend = wm8904_suspend, - .resume = wm8904_resume, .set_bias_level = wm8904_set_bias_level, .idle_bias_off = true, }; -- GitLab From 03862cf62ea36d6cf3d94eee84b89578cbcf0213 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:41:58 +0800 Subject: [PATCH 2648/6849] ASoC: wm8904: Move regulator acquisition and device identification to I2C It's more idiomatic to have the resource allocation at this level. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 112 +++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 61 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index ecab871573b1..b178232c990c 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -314,11 +314,6 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg) } } -static int wm8904_reset(struct snd_soc_codec *codec) -{ - return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0); -} - static int wm8904_configure_clocking(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); @@ -2082,52 +2077,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) return ret; } - for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) - wm8904->supplies[i].supply = wm8904_supply_names[i]; - - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies), - wm8904->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - return ret; - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), - wm8904->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; - } - - ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID); - if (ret < 0) { - dev_err(codec->dev, "Failed to read ID register\n"); - goto err_enable; - } - if (ret != 0x8904) { - dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); - ret = -EINVAL; - goto err_enable; - } - - ret = snd_soc_read(codec, WM8904_REVISION); - if (ret < 0) { - dev_err(codec->dev, "Failed to read device revision: %d\n", - ret); - goto err_enable; - } - dev_info(codec->dev, "revision %c\n", ret + 'A'); - - ret = wm8904_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err_enable; - } - - /* Can leave the device powered off until we need it */ - regcache_cache_only(wm8904->regmap, true); - regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); - /* Change some default settings - latch VU and enable ZC */ snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, WM8904_ADC_VU, WM8904_ADC_VU); @@ -2187,19 +2136,12 @@ static int wm8904_probe(struct snd_soc_codec *codec) wm8904_add_widgets(codec); return 0; - -err_enable: - regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); - return ret; } static int wm8904_remove(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); - regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); kfree(wm8904->retune_mobile_texts); kfree(wm8904->drc_texts); @@ -2230,7 +2172,8 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8904_priv *wm8904; - int ret; + unsigned int val; + int ret, i; wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), GFP_KERNEL); @@ -2249,14 +2192,61 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8904); wm8904->pdata = i2c->dev.platform_data; + for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) + wm8904->supplies[i].supply = wm8904_supply_names[i]; + + ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8904->supplies), + wm8904->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), + wm8904->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + ret = regmap_read(wm8904->regmap, WM8904_SW_RESET_AND_ID, &val); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); + goto err_enable; + } + if (val != 0x8904) { + dev_err(&i2c->dev, "Device is not a WM8904, ID is %x\n", val); + ret = -EINVAL; + goto err_enable; + } + + ret = regmap_read(wm8904->regmap, WM8904_REVISION, &val); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read device revision: %d\n", + ret); + goto err_enable; + } + dev_info(&i2c->dev, "revision %c\n", val + 'A'); + + ret = regmap_write(wm8904->regmap, WM8904_SW_RESET_AND_ID, 0); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); + goto err_enable; + } + + /* Can leave the device powered off until we need it */ + regcache_cache_only(wm8904->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8904, &wm8904_dai, 1); if (ret != 0) - goto err; + return ret; return 0; -err: +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); return ret; } -- GitLab From 725e7a7b58fb27d8f97a1c4eae47cb5d37564725 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 9 Jun 2012 11:57:37 +0800 Subject: [PATCH 2649/6849] ASoC: wm8904: Move register default setup into I2C probe() Get it done as early as possible, it's neater and minimises the time the pins aren't configured as requested. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 111 +++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 56 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index b178232c990c..0013afe48e66 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2054,8 +2054,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) static int wm8904_probe(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); - struct wm8904_pdata *pdata = wm8904->pdata; - int ret, i; + int ret; codec->control_data = wm8904->regmap; @@ -2077,60 +2076,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) return ret; } - /* Change some default settings - latch VU and enable ZC */ - snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, - WM8904_ADC_VU, WM8904_ADC_VU); - snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT, - WM8904_ADC_VU, WM8904_ADC_VU); - snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT, - WM8904_DAC_VU, WM8904_DAC_VU); - snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT, - WM8904_DAC_VU, WM8904_DAC_VU); - snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT, - WM8904_HPOUT_VU | WM8904_HPOUTLZC, - WM8904_HPOUT_VU | WM8904_HPOUTLZC); - snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT, - WM8904_HPOUT_VU | WM8904_HPOUTRZC, - WM8904_HPOUT_VU | WM8904_HPOUTRZC); - snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT, - WM8904_LINEOUT_VU | WM8904_LINEOUTLZC, - WM8904_LINEOUT_VU | WM8904_LINEOUTLZC); - snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT, - WM8904_LINEOUT_VU | WM8904_LINEOUTRZC, - WM8904_LINEOUT_VU | WM8904_LINEOUTRZC); - snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, - WM8904_SR_MODE, 0); - - /* Apply configuration from the platform data. */ - if (wm8904->pdata) { - for (i = 0; i < WM8904_GPIO_REGS; i++) { - if (!pdata->gpio_cfg[i]) - continue; - - regmap_update_bits(wm8904->regmap, - WM8904_GPIO_CONTROL_1 + i, - 0xffff, - pdata->gpio_cfg[i]); - } - - /* Zero is the default value for these anyway */ - for (i = 0; i < WM8904_MIC_REGS; i++) - regmap_update_bits(wm8904->regmap, - WM8904_MIC_BIAS_CONTROL_0 + i, - 0xffff, - pdata->mic_cfg[i]); - } - - /* Set Class W by default - this will be managed by the Class - * G widget at runtime where bypass paths are available. - */ - snd_soc_update_bits(codec, WM8904_CLASS_W_0, - WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR); - - /* Use normal bias source */ - snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, - WM8904_POBCTRL, 0); - wm8904_handle_pdata(codec); wm8904_add_widgets(codec); @@ -2234,6 +2179,60 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, goto err_enable; } + /* Change some default settings - latch VU and enable ZC */ + regmap_update_bits(wm8904->regmap, WM8904_ADC_DIGITAL_VOLUME_LEFT, + WM8904_ADC_VU, WM8904_ADC_VU); + regmap_update_bits(wm8904->regmap, WM8904_ADC_DIGITAL_VOLUME_RIGHT, + WM8904_ADC_VU, WM8904_ADC_VU); + regmap_update_bits(wm8904->regmap, WM8904_DAC_DIGITAL_VOLUME_LEFT, + WM8904_DAC_VU, WM8904_DAC_VU); + regmap_update_bits(wm8904->regmap, WM8904_DAC_DIGITAL_VOLUME_RIGHT, + WM8904_DAC_VU, WM8904_DAC_VU); + regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT1_LEFT, + WM8904_HPOUT_VU | WM8904_HPOUTLZC, + WM8904_HPOUT_VU | WM8904_HPOUTLZC); + regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT1_RIGHT, + WM8904_HPOUT_VU | WM8904_HPOUTRZC, + WM8904_HPOUT_VU | WM8904_HPOUTRZC); + regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT2_LEFT, + WM8904_LINEOUT_VU | WM8904_LINEOUTLZC, + WM8904_LINEOUT_VU | WM8904_LINEOUTLZC); + regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT2_RIGHT, + WM8904_LINEOUT_VU | WM8904_LINEOUTRZC, + WM8904_LINEOUT_VU | WM8904_LINEOUTRZC); + regmap_update_bits(wm8904->regmap, WM8904_CLOCK_RATES_0, + WM8904_SR_MODE, 0); + + /* Apply configuration from the platform data. */ + if (wm8904->pdata) { + for (i = 0; i < WM8904_GPIO_REGS; i++) { + if (!wm8904->pdata->gpio_cfg[i]) + continue; + + regmap_update_bits(wm8904->regmap, + WM8904_GPIO_CONTROL_1 + i, + 0xffff, + wm8904->pdata->gpio_cfg[i]); + } + + /* Zero is the default value for these anyway */ + for (i = 0; i < WM8904_MIC_REGS; i++) + regmap_update_bits(wm8904->regmap, + WM8904_MIC_BIAS_CONTROL_0 + i, + 0xffff, + wm8904->pdata->mic_cfg[i]); + } + + /* Set Class W by default - this will be managed by the Class + * G widget at runtime where bypass paths are available. + */ + regmap_update_bits(wm8904->regmap, WM8904_CLASS_W_0, + WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR); + + /* Use normal bias source */ + regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0, + WM8904_POBCTRL, 0); + /* Can leave the device powered off until we need it */ regcache_cache_only(wm8904->regmap, true); regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); -- GitLab From 625c4888fff33c300779ed38963e1ee7ad878a12 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:42:06 +0800 Subject: [PATCH 2650/6849] ASoC: wm8996: Move regulator notifier callbacks into I2C level Now that we're using regmap the cache is available here. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 41 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 49e0e8d6663e..e0cf5b0b5203 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2644,21 +2644,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) goto err; } - wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; - wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; - wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; - - /* This should really be moved into the regulator core */ - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { - ret = regulator_register_notifier(wm8996->supplies[i].consumer, - &wm8996->disable_nb[i]); - if (ret != 0) { - dev_err(codec->dev, - "Failed to register regulator notifier: %d\n", - ret); - } - } - /* Apply platform data settings */ snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, @@ -2858,9 +2843,7 @@ err: static int wm8996_remove(struct snd_soc_codec *codec) { - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); struct i2c_client *i2c = to_i2c_client(codec->dev); - int i; snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL, WM8996_IM_IRQ, WM8996_IM_IRQ); @@ -2868,10 +2851,6 @@ static int wm8996_remove(struct snd_soc_codec *codec) if (i2c->irq) free_irq(i2c->irq, codec); - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) - regulator_unregister_notifier(wm8996->supplies[i].consumer, - &wm8996->disable_nb[i]); - return 0; } @@ -2985,6 +2964,21 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, goto err_gpio; } + wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; + wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; + wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { + ret = regulator_register_notifier(wm8996->supplies[i].consumer, + &wm8996->disable_nb[i]); + if (ret != 0) { + dev_err(&i2c->dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); if (ret != 0) { @@ -3062,6 +3056,7 @@ err: static __devexit int wm8996_i2c_remove(struct i2c_client *client) { struct wm8996_priv *wm8996 = i2c_get_clientdata(client); + int i; snd_soc_unregister_codec(&client->dev); wm8996_free_gpio(wm8996); @@ -3069,6 +3064,10 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); gpio_free(wm8996->pdata.ldo_ena); } + for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) + regulator_unregister_notifier(wm8996->supplies[i].consumer, + &wm8996->disable_nb[i]); + return 0; } -- GitLab From d4b3d0fbb7617a65cb919ac86110b0790ae568c5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 18:41:16 +0800 Subject: [PATCH 2651/6849] ASoC: wm8996: Inline wm8996_reset() and optimise cache-only usage There is only one caller and this allows us to cleanly leave the CODEC with the internal LDO powered down which is the default state we're looking for and means that we can robustly disable the register cache only when we either disable the LDO or power down the external regulators. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index e0cf5b0b5203..1579880ac05d 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -1528,18 +1528,6 @@ static bool wm8996_volatile_register(struct device *dev, unsigned int reg) } } -static int wm8996_reset(struct wm8996_priv *wm8996) -{ - if (wm8996->pdata.ldo_ena > 0) { - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); - return 0; - } else { - return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, - 0x8915); - } -} - static const int bclk_divs[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 }; @@ -1631,8 +1619,10 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_OFF: regcache_cache_only(codec->control_data, true); - if (wm8996->pdata.ldo_ena >= 0) + if (wm8996->pdata.ldo_ena >= 0) { gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); + regcache_cache_only(codec->control_data, true); + } regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); break; @@ -3019,13 +3009,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, dev_info(&i2c->dev, "revision %c\n", (reg & WM8996_CHIP_REV_MASK) + 'A'); - ret = wm8996_reset(wm8996); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to issue reset\n"); - goto err_regmap; + if (wm8996->pdata.ldo_ena > 0) { + gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); + regcache_cache_only(wm8996->regmap, true); + } else { + ret = regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, + 0x8915); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); + goto err_regmap; + } } - regcache_cache_only(wm8996->regmap, true); regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); wm8996_init_gpio(wm8996); -- GitLab From ec8ffe1868f45a72eb243f1c9797806be58276fd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Jun 2012 19:10:50 +0800 Subject: [PATCH 2652/6849] ASoC: wm8996: Move register default configuration to I2C probe This gets the registers set up as early as possible, mainly useful for the GPIOs to ensure that they're in the correct mode. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 331 +++++++++++++++++++++----------------- 1 file changed, 180 insertions(+), 151 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 1579880ac05d..00f183dfa454 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2619,7 +2619,7 @@ static int wm8996_probe(struct snd_soc_codec *codec) int ret; struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); struct i2c_client *i2c = to_i2c_client(codec->dev); - int i, irq_flags; + int irq_flags; wm8996->codec = codec; @@ -2634,162 +2634,12 @@ static int wm8996_probe(struct snd_soc_codec *codec) goto err; } - /* Apply platform data settings */ - snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, - WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, - wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT | - wm8996->pdata.inr_mode); - - for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) { - if (!wm8996->pdata.gpio_default[i]) - continue; - - snd_soc_write(codec, WM8996_GPIO_1 + i, - wm8996->pdata.gpio_default[i] & 0xffff); - } - - if (wm8996->pdata.spkmute_seq) - snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE, - WM8996_SPK_MUTE_ENDIAN | - WM8996_SPK_MUTE_SEQ1_MASK, - wm8996->pdata.spkmute_seq); - - snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2, - WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC | - WM8996_MICD_SRC, wm8996->pdata.micdet_def); - - /* Latch volume update bits */ - snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME, - WM8996_IN1_VU, WM8996_IN1_VU); - snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME, - WM8996_IN1_VU, WM8996_IN1_VU); - - snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - - snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - - snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME, - WM8996_DSP1TX_VU, WM8996_DSP1TX_VU); - snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME, - WM8996_DSP1TX_VU, WM8996_DSP1TX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME, - WM8996_DSP2TX_VU, WM8996_DSP2TX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME, - WM8996_DSP2TX_VU, WM8996_DSP2TX_VU); - - snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME, - WM8996_DSP1RX_VU, WM8996_DSP1RX_VU); - snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME, - WM8996_DSP1RX_VU, WM8996_DSP1RX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME, - WM8996_DSP2RX_VU, WM8996_DSP2RX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME, - WM8996_DSP2RX_VU, WM8996_DSP2RX_VU); - - /* No support currently for the underclocked TDM modes and - * pick a default TDM layout with each channel pair working with - * slots 0 and 1. */ - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, - WM8996_AIF1RX_CHAN0_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, - WM8996_AIF1RX_CHAN1_SLOTS_MASK | - WM8996_AIF1RX_CHAN1_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, - WM8996_AIF1RX_CHAN2_SLOTS_MASK | - WM8996_AIF1RX_CHAN2_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, - WM8996_AIF1RX_CHAN3_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, - WM8996_AIF1RX_CHAN4_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, - WM8996_AIF1RX_CHAN5_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1); - - snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, - WM8996_AIF2RX_CHAN0_SLOTS_MASK | - WM8996_AIF2RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, - WM8996_AIF2RX_CHAN1_SLOTS_MASK | - WM8996_AIF2RX_CHAN1_START_SLOT_MASK, - 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1); - - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, - WM8996_AIF1TX_CHAN0_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, - WM8996_AIF1TX_CHAN1_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, - WM8996_AIF1TX_CHAN2_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, - WM8996_AIF1TX_CHAN3_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, - WM8996_AIF1TX_CHAN4_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, - WM8996_AIF1TX_CHAN5_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1); - - snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, - WM8996_AIF2TX_CHAN0_SLOTS_MASK | - WM8996_AIF2TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, - WM8996_AIF2TX_CHAN1_SLOTS_MASK | - WM8996_AIF2TX_CHAN1_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1); - if (wm8996->pdata.num_retune_mobile_cfgs) wm8996_retune_mobile_pdata(codec); else snd_soc_add_codec_controls(codec, wm8996_eq_controls, ARRAY_SIZE(wm8996_eq_controls)); - /* If the TX LRCLK pins are not in LRCLK mode configure the - * AIFs to source their clocks from the RX LRCLKs. - */ - if ((snd_soc_read(codec, WM8996_GPIO_1))) - snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2, - WM8996_AIF1TX_LRCLK_MODE, - WM8996_AIF1TX_LRCLK_MODE); - - if ((snd_soc_read(codec, WM8996_GPIO_2))) - snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2, - WM8996_AIF2TX_LRCLK_MODE, - WM8996_AIF2TX_LRCLK_MODE); - if (i2c->irq) { if (wm8996->pdata.irq_flags) irq_flags = wm8996->pdata.irq_flags; @@ -3023,6 +2873,185 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); + /* Apply platform data settings */ + regmap_update_bits(wm8996->regmap, WM8996_LINE_INPUT_CONTROL, + WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, + wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT | + wm8996->pdata.inr_mode); + + for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) { + if (!wm8996->pdata.gpio_default[i]) + continue; + + regmap_write(wm8996->regmap, WM8996_GPIO_1 + i, + wm8996->pdata.gpio_default[i] & 0xffff); + } + + if (wm8996->pdata.spkmute_seq) + regmap_update_bits(wm8996->regmap, + WM8996_PDM_SPEAKER_MUTE_SEQUENCE, + WM8996_SPK_MUTE_ENDIAN | + WM8996_SPK_MUTE_SEQ1_MASK, + wm8996->pdata.spkmute_seq); + + regmap_update_bits(wm8996->regmap, WM8996_ACCESSORY_DETECT_MODE_2, + WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC | + WM8996_MICD_SRC, wm8996->pdata.micdet_def); + + /* Latch volume update bits */ + regmap_update_bits(wm8996->regmap, WM8996_LEFT_LINE_INPUT_VOLUME, + WM8996_IN1_VU, WM8996_IN1_VU); + regmap_update_bits(wm8996->regmap, WM8996_RIGHT_LINE_INPUT_VOLUME, + WM8996_IN1_VU, WM8996_IN1_VU); + + regmap_update_bits(wm8996->regmap, WM8996_DAC1_LEFT_VOLUME, + WM8996_DAC1_VU, WM8996_DAC1_VU); + regmap_update_bits(wm8996->regmap, WM8996_DAC1_RIGHT_VOLUME, + WM8996_DAC1_VU, WM8996_DAC1_VU); + regmap_update_bits(wm8996->regmap, WM8996_DAC2_LEFT_VOLUME, + WM8996_DAC2_VU, WM8996_DAC2_VU); + regmap_update_bits(wm8996->regmap, WM8996_DAC2_RIGHT_VOLUME, + WM8996_DAC2_VU, WM8996_DAC2_VU); + + regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_LEFT_VOLUME, + WM8996_DAC1_VU, WM8996_DAC1_VU); + regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_RIGHT_VOLUME, + WM8996_DAC1_VU, WM8996_DAC1_VU); + regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_LEFT_VOLUME, + WM8996_DAC2_VU, WM8996_DAC2_VU); + regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_RIGHT_VOLUME, + WM8996_DAC2_VU, WM8996_DAC2_VU); + + regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_LEFT_VOLUME, + WM8996_DSP1TX_VU, WM8996_DSP1TX_VU); + regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_RIGHT_VOLUME, + WM8996_DSP1TX_VU, WM8996_DSP1TX_VU); + regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_LEFT_VOLUME, + WM8996_DSP2TX_VU, WM8996_DSP2TX_VU); + regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_RIGHT_VOLUME, + WM8996_DSP2TX_VU, WM8996_DSP2TX_VU); + + regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_LEFT_VOLUME, + WM8996_DSP1RX_VU, WM8996_DSP1RX_VU); + regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_RIGHT_VOLUME, + WM8996_DSP1RX_VU, WM8996_DSP1RX_VU); + regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_LEFT_VOLUME, + WM8996_DSP2RX_VU, WM8996_DSP2RX_VU); + regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_RIGHT_VOLUME, + WM8996_DSP2RX_VU, WM8996_DSP2RX_VU); + + /* No support currently for the underclocked TDM modes and + * pick a default TDM layout with each channel pair working with + * slots 0 and 1. */ + regmap_update_bits(wm8996->regmap, + WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, + WM8996_AIF1RX_CHAN0_SLOTS_MASK | + WM8996_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, + WM8996_AIF1RX_CHAN1_SLOTS_MASK | + WM8996_AIF1RX_CHAN1_START_SLOT_MASK, + 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, + WM8996_AIF1RX_CHAN2_SLOTS_MASK | + WM8996_AIF1RX_CHAN2_START_SLOT_MASK, + 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, + WM8996_AIF1RX_CHAN3_SLOTS_MASK | + WM8996_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, + WM8996_AIF1RX_CHAN4_SLOTS_MASK | + WM8996_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, + WM8996_AIF1RX_CHAN5_SLOTS_MASK | + WM8996_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1); + + regmap_update_bits(wm8996->regmap, + WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, + WM8996_AIF2RX_CHAN0_SLOTS_MASK | + WM8996_AIF2RX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, + WM8996_AIF2RX_CHAN1_SLOTS_MASK | + WM8996_AIF2RX_CHAN1_START_SLOT_MASK, + 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1); + + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, + WM8996_AIF1TX_CHAN0_SLOTS_MASK | + WM8996_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, + WM8996_AIF1TX_CHAN1_SLOTS_MASK | + WM8996_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, + WM8996_AIF1TX_CHAN2_SLOTS_MASK | + WM8996_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, + WM8996_AIF1TX_CHAN3_SLOTS_MASK | + WM8996_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, + WM8996_AIF1TX_CHAN4_SLOTS_MASK | + WM8996_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, + WM8996_AIF1TX_CHAN5_SLOTS_MASK | + WM8996_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1); + + regmap_update_bits(wm8996->regmap, + WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, + WM8996_AIF2TX_CHAN0_SLOTS_MASK | + WM8996_AIF2TX_CHAN0_START_SLOT_MASK, + 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0); + regmap_update_bits(wm8996->regmap, + WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, + WM8996_AIF2TX_CHAN1_SLOTS_MASK | + WM8996_AIF2TX_CHAN1_START_SLOT_MASK, + 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1); + + /* If the TX LRCLK pins are not in LRCLK mode configure the + * AIFs to source their clocks from the RX LRCLKs. + */ + ret = regmap_read(wm8996->regmap, WM8996_GPIO_1, ®); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read GPIO1: %d\n", ret); + goto err_regmap; + } + + if (reg & WM8996_GP1_FN_MASK) + regmap_update_bits(wm8996->regmap, WM8996_AIF1_TX_LRCLK_2, + WM8996_AIF1TX_LRCLK_MODE, + WM8996_AIF1TX_LRCLK_MODE); + + ret = regmap_read(wm8996->regmap, WM8996_GPIO_2, ®); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read GPIO2: %d\n", ret); + goto err_regmap; + } + + if (reg & WM8996_GP2_FN_MASK) + regmap_update_bits(wm8996->regmap, WM8996_AIF2_TX_LRCLK_2, + WM8996_AIF2TX_LRCLK_MODE, + WM8996_AIF2TX_LRCLK_MODE); + wm8996_init_gpio(wm8996); ret = snd_soc_register_codec(&i2c->dev, -- GitLab From d69d65226a7910d1cfd9f3841180a0f250eeb2e9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 25 Jun 2012 10:01:27 +0100 Subject: [PATCH 2653/6849] ASoC: dwc: Bodge around continuing absence of clock API stubs The patches for stubbing out the generic clock API still haven't been applied so we need to either add ifdefs here or add a dependency until someone decides to actually apply them. Reported-by: Stephen Rothwell Signed-off-by: Mark Brown --- sound/soc/dwc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig index 93e9fc33560c..e334900cf0b8 100644 --- a/sound/soc/dwc/Kconfig +++ b/sound/soc/dwc/Kconfig @@ -1,5 +1,6 @@ config SND_DESIGNWARE_I2S tristate "Synopsys I2S Device Driver" + depends on CLKDEV_LOOKUP help Say Y or M if you want to add support for I2S driver for Synopsys desigwnware I2S device. The device supports upto -- GitLab From e6656369da73f8a4206a72ea6fb0e35247f42364 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Jun 2012 11:03:12 +0200 Subject: [PATCH 2654/6849] ALSA: hda - Remove suprefluous EAPD init verbs for ALC660vd The EAPD on nodes 0x14 and 0x15 are initialized in alc_auto_setup_eapd(). Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3e698e239dd8..4377a9539735 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6494,12 +6494,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { {} }; -static const struct hda_verb alc660vd_eapd_verbs[] = { - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; - /* */ static int patch_alc861vd(struct hda_codec *codec) @@ -6521,11 +6515,6 @@ static int patch_alc861vd(struct hda_codec *codec) if (err < 0) goto error; - if (codec->vendor_id == 0x10ec0660) { - /* always turn on EAPD */ - snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs); - } - if (!spec->no_analog) { err = snd_hda_attach_beep_device(codec, 0x23); if (err < 0) -- GitLab From a75e92442a9b17b24876ca85701a722af32d31a5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Jun 2012 11:06:55 +0200 Subject: [PATCH 2655/6849] ALSA: hda - Update documentation for Realtek codecs model strings Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 03f7897c6414..2ea8cf2819cf 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -15,19 +15,23 @@ ALC260 ALC262 ====== - N/A + inv-dmic Inverted internal mic workaround ALC267/268 ========== - N/A + inv-dmic Inverted internal mic workaround ALC269 ====== laptop-amic Laptops with analog-mic input laptop-dmic Laptops with digital-mic input + alc269-dmic Enable ALC269(VA) digital mic workaround + alc271-dmic Enable ALC271X digital mic workaround + inv-dmic Inverted internal mic workaround ALC662/663/272 ============== + mario Chromebook mario model fixup asus-mode1 ASUS asus-mode2 ASUS asus-mode3 ASUS @@ -36,6 +40,7 @@ ALC662/663/272 asus-mode6 ASUS asus-mode7 ASUS asus-mode8 ASUS + inv-dmic Inverted internal mic workaround ALC680 ====== @@ -46,6 +51,7 @@ ALC882/883/885/888/889 acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G acer-aspire-8930g Acer Aspire 8330G/6935G acer-aspire Acer Aspire others + inv-dmic Inverted internal mic workaround ALC861/660 ========== -- GitLab From 74953e201001b9582bf3125858cf6955650edb48 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sat, 23 Jun 2012 17:30:47 +0200 Subject: [PATCH 2656/6849] ALSA: usb-audio: add BOSS GT-100 support Reported-by: John McFarland Tested-by: John McFarland Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/quirks-table.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index d89ab4c7d44b..79780fa57a43 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -1831,6 +1831,36 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, +{ + USB_DEVICE(0x0582, 0x014d), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + /* .vendor_name = "BOSS", */ + /* .product_name = "GT-100", */ + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 3, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } + } + } +}, /* Guillemot devices */ { -- GitLab From 1af142c6f9843952d8eaff1c3de40d0b5d16f3ed Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 13 Jun 2012 17:27:54 +0900 Subject: [PATCH 2657/6849] regulator: Modify ramp_delay value for s5m8767a As s5m8767a is revisioned, ramp_delay register is changed. 5mV/uS, 10mV/uS, 25mV/uS, 50mV/uS, 100mV/uS ramp delay can be selected. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 22642c3ccf76..533bde68e4b7 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -720,9 +720,13 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) if (s5m8767->buck2_ramp || s5m8767->buck3_ramp || s5m8767->buck4_ramp) { switch (s5m8767->ramp_delay) { - case 15: + case 5: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, - 0xc0, 0xf0); + 0x40, 0xf0); + break; + case 10: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0x90, 0xf0); break; case 25: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, -- GitLab From 6cab3e1e65bfe070f09bb091eeda182b171d5929 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 28 May 2012 11:14:33 +0200 Subject: [PATCH 2658/6849] ASoC: wm8994: remove duplicate code It seems that the code duplication was added at a merge operation. Signed-off-by: Jaroslav Kysela Signed-off-by: Takashi Iwai --- sound/soc/codecs/wm8994.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index aa8c98b628da..1436b6ce74d1 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -724,9 +724,6 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - if (!wm8994->jackdet || !wm8994->jack_cb) - return; - if (!wm8994->jackdet || !wm8994->jack_cb) return; -- GitLab From 1910efa1d0fdf8109b285d4486f6a0de810b5574 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 23 Jun 2012 13:07:57 +0100 Subject: [PATCH 2659/6849] regulator: Add driver for Arizona LDO1 Arizona class devices feature an integrated LDO which is intended to supply the digital core for the device. Provide a driver offering minimal control of this regulator. Signed-off-by: Mark Brown --- drivers/regulator/Makefile | 2 +- drivers/regulator/arizona-ldo1.c | 134 +++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 drivers/regulator/arizona-ldo1.c diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ec4a0cfb3ca7..c7460888edcb 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o -obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o +obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c new file mode 100644 index 000000000000..51f02cac443f --- /dev/null +++ b/drivers/regulator/arizona-ldo1.c @@ -0,0 +1,134 @@ +/* + * arizona-ldo1.c -- LDO1 supply for Arizona devices + * + * Copyright 2012 Wolfson Microelectronics PLC. + * + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct arizona_ldo1 { + struct regulator_dev *regulator; + struct arizona *arizona; + + struct regulator_consumer_supply supply; + struct regulator_init_data init_data; +}; + +static struct regulator_ops arizona_ldo1_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, +}; + +static const struct regulator_desc arizona_ldo1 = { + .name = "LDO1", + .supply_name = "LDOVDD", + .type = REGULATOR_VOLTAGE, + .ops = &arizona_ldo1_ops, + + .vsel_reg = ARIZONA_LDO1_CONTROL_1, + .vsel_mask = ARIZONA_LDO1_VSEL_MASK, + .min_uV = 900000, + .uV_step = 50000, + .n_voltages = 7, + + .owner = THIS_MODULE, +}; + +static const struct regulator_init_data arizona_ldo1_default = { + .num_consumer_supplies = 1, +}; + +static __devinit int arizona_ldo1_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct arizona_ldo1 *ldo1; + int ret; + + ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); + if (ldo1 == NULL) { + dev_err(&pdev->dev, "Unable to allocate private data\n"); + return -ENOMEM; + } + + ldo1->arizona = arizona; + + /* + * Since the chip usually supplies itself we provide some + * default init_data for it. This will be overridden with + * platform data if provided. + */ + ldo1->init_data = arizona_ldo1_default; + ldo1->init_data.consumer_supplies = &ldo1->supply; + ldo1->supply.supply = "DCVDD"; + ldo1->supply.dev_name = dev_name(arizona->dev); + + config.dev = arizona->dev; + config.driver_data = ldo1; + config.regmap = arizona->regmap; + + if (arizona->pdata.ldo1) + config.init_data = arizona->pdata.ldo1; + else + config.init_data = &ldo1->init_data; + + ldo1->regulator = regulator_register(&arizona_ldo1, &config); + if (IS_ERR(ldo1->regulator)) { + ret = PTR_ERR(ldo1->regulator); + dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", + ret); + return ret; + } + + platform_set_drvdata(pdev, ldo1); + + return 0; +} + +static __devexit int arizona_ldo1_remove(struct platform_device *pdev) +{ + struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev); + + regulator_unregister(ldo1->regulator); + + return 0; +} + +static struct platform_driver arizona_ldo1_driver = { + .probe = arizona_ldo1_probe, + .remove = __devexit_p(arizona_ldo1_remove), + .driver = { + .name = "arizona-ldo1", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(arizona_ldo1_driver); + +/* Module information */ +MODULE_AUTHOR("Mark Brown "); +MODULE_DESCRIPTION("Arizona LDO1 driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:arizona-ldo1"); -- GitLab From 5eadf916dfa04c3c51397dbcb803ce8735bf191a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:24:19 +0300 Subject: [PATCH 2660/6849] KVM: document lapic regs field Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/kvm/lapic.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 6f4ce2575d09..d29da25ea525 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -13,6 +13,11 @@ struct kvm_lapic { u32 divide_count; struct kvm_vcpu *vcpu; bool irr_pending; + /** + * APIC register page. The layout matches the register layout seen by + * the guest 1:1, because it is accessed by the vmx microcode. + * Note: Only one register, the TPR, is used by the microcode. + */ void *regs; gpa_t vapic_addr; struct page *vapic_page; -- GitLab From 8680b94b0e6046af2644c17313287ec0cb5843dc Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:24:26 +0300 Subject: [PATCH 2661/6849] KVM: optimize ISR lookups We perform ISR lookups twice: during interrupt injection and on EOI. Typical workloads only have a single bit set there. So we can avoid ISR scans by 1. counting bits as we set/clear them in ISR 2. on set, caching the injected vector number 3. on clear, invalidating the cache The real purpose of this is enabling PV EOI which needs to quickly validate the vector. But non PV guests also benefit: with this patch, and without interrupt nesting, apic_find_highest_isr will always return immediately without scanning ISR. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/kvm/lapic.c | 53 ++++++++++++++++++++++++++++++++++++++++++-- arch/x86/kvm/lapic.h | 4 ++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 93c15743f1ee..805d887784f6 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -107,6 +107,16 @@ static inline void apic_clear_vector(int vec, void *bitmap) clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); } +static inline int __apic_test_and_set_vector(int vec, void *bitmap) +{ + return __test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); +} + +static inline int __apic_test_and_clear_vector(int vec, void *bitmap) +{ + return __test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); +} + static inline int apic_hw_enabled(struct kvm_lapic *apic) { return (apic)->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE; @@ -210,6 +220,16 @@ static int find_highest_vector(void *bitmap) return fls(word[word_offset << 2]) - 1 + (word_offset << 5); } +static u8 count_vectors(void *bitmap) +{ + u32 *word = bitmap; + int word_offset; + u8 count = 0; + for (word_offset = 0; word_offset < MAX_APIC_VECTOR >> 5; ++word_offset) + count += hweight32(word[word_offset << 2]); + return count; +} + static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) { apic->irr_pending = true; @@ -242,6 +262,27 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) apic->irr_pending = true; } +static inline void apic_set_isr(int vec, struct kvm_lapic *apic) +{ + if (!__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) + ++apic->isr_count; + BUG_ON(apic->isr_count > MAX_APIC_VECTOR); + /* + * ISR (in service register) bit is set when injecting an interrupt. + * The highest vector is injected. Thus the latest bit set matches + * the highest bit in ISR. + */ + apic->highest_isr_cache = vec; +} + +static inline void apic_clear_isr(int vec, struct kvm_lapic *apic) +{ + if (__apic_test_and_clear_vector(vec, apic->regs + APIC_ISR)) + --apic->isr_count; + BUG_ON(apic->isr_count < 0); + apic->highest_isr_cache = -1; +} + int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; @@ -273,6 +314,10 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) static inline int apic_find_highest_isr(struct kvm_lapic *apic) { int result; + if (!apic->isr_count) + return -1; + if (likely(apic->highest_isr_cache != -1)) + return apic->highest_isr_cache; result = find_highest_vector(apic->regs + APIC_ISR); ASSERT(result == -1 || result >= 16); @@ -492,7 +537,7 @@ static void apic_set_eoi(struct kvm_lapic *apic) if (vector == -1) return; - apic_clear_vector(vector, apic->regs + APIC_ISR); + apic_clear_isr(vector, apic); apic_update_ppr(apic); if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) && @@ -1081,6 +1126,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); } apic->irr_pending = false; + apic->isr_count = 0; + apic->highest_isr_cache = -1; update_divide_count(apic); atomic_set(&apic->lapic_timer.pending, 0); if (kvm_vcpu_is_bsp(vcpu)) @@ -1248,7 +1295,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) if (vector == -1) return -1; - apic_set_vector(vector, apic->regs + APIC_ISR); + apic_set_isr(vector, apic); apic_update_ppr(apic); apic_clear_irr(vector, apic); return vector; @@ -1267,6 +1314,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) update_divide_count(apic); start_apic_timer(apic); apic->irr_pending = true; + apic->isr_count = count_vectors(apic->regs + APIC_ISR); + apic->highest_isr_cache = -1; kvm_make_request(KVM_REQ_EVENT, vcpu); } diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index d29da25ea525..5ac9e5e2fedd 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -13,6 +13,10 @@ struct kvm_lapic { u32 divide_count; struct kvm_vcpu *vcpu; bool irr_pending; + /* Number of bits set in ISR. */ + s16 isr_count; + /* The highest vector set in ISR; if -1 - invalid, must scan ISR. */ + int highest_isr_cache; /** * APIC register page. The layout matches the register layout seen by * the guest 1:1, because it is accessed by the vmx microcode. -- GitLab From ab9cf4996bb989983e73da894b8dd0239aa2c3c2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:24:34 +0300 Subject: [PATCH 2662/6849] KVM guest: guest side for eoi avoidance The idea is simple: there's a bit, per APIC, in guest memory, that tells the guest that it does not need EOI. Guest tests it using a single est and clear operation - this is necessary so that host can detect interrupt nesting - and if set, it can skip the EOI MSR. I run a simple microbenchmark to show exit reduction (note: for testing, need to apply follow-up patch 'kvm: host side for eoi optimization' + a qemu patch I posted separately, on host): Before: Performance counter stats for 'sleep 1s': 47,357 kvm:kvm_entry [99.98%] 0 kvm:kvm_hypercall [99.98%] 0 kvm:kvm_hv_hypercall [99.98%] 5,001 kvm:kvm_pio [99.98%] 0 kvm:kvm_cpuid [99.98%] 22,124 kvm:kvm_apic [99.98%] 49,849 kvm:kvm_exit [99.98%] 21,115 kvm:kvm_inj_virq [99.98%] 0 kvm:kvm_inj_exception [99.98%] 0 kvm:kvm_page_fault [99.98%] 22,937 kvm:kvm_msr [99.98%] 0 kvm:kvm_cr [99.98%] 0 kvm:kvm_pic_set_irq [99.98%] 0 kvm:kvm_apic_ipi [99.98%] 22,207 kvm:kvm_apic_accept_irq [99.98%] 22,421 kvm:kvm_eoi [99.98%] 0 kvm:kvm_pv_eoi [99.99%] 0 kvm:kvm_nested_vmrun [99.99%] 0 kvm:kvm_nested_intercepts [99.99%] 0 kvm:kvm_nested_vmexit [99.99%] 0 kvm:kvm_nested_vmexit_inject [99.99%] 0 kvm:kvm_nested_intr_vmexit [99.99%] 0 kvm:kvm_invlpga [99.99%] 0 kvm:kvm_skinit [99.99%] 57 kvm:kvm_emulate_insn [99.99%] 0 kvm:vcpu_match_mmio [99.99%] 0 kvm:kvm_userspace_exit [99.99%] 2 kvm:kvm_set_irq [99.99%] 2 kvm:kvm_ioapic_set_irq [99.99%] 23,609 kvm:kvm_msi_set_irq [99.99%] 1 kvm:kvm_ack_irq [99.99%] 131 kvm:kvm_mmio [99.99%] 226 kvm:kvm_fpu [100.00%] 0 kvm:kvm_age_page [100.00%] 0 kvm:kvm_try_async_get_page [100.00%] 0 kvm:kvm_async_pf_doublefault [100.00%] 0 kvm:kvm_async_pf_not_present [100.00%] 0 kvm:kvm_async_pf_ready [100.00%] 0 kvm:kvm_async_pf_completed 1.002100578 seconds time elapsed After: Performance counter stats for 'sleep 1s': 28,354 kvm:kvm_entry [99.98%] 0 kvm:kvm_hypercall [99.98%] 0 kvm:kvm_hv_hypercall [99.98%] 1,347 kvm:kvm_pio [99.98%] 0 kvm:kvm_cpuid [99.98%] 1,931 kvm:kvm_apic [99.98%] 29,595 kvm:kvm_exit [99.98%] 24,884 kvm:kvm_inj_virq [99.98%] 0 kvm:kvm_inj_exception [99.98%] 0 kvm:kvm_page_fault [99.98%] 1,986 kvm:kvm_msr [99.98%] 0 kvm:kvm_cr [99.98%] 0 kvm:kvm_pic_set_irq [99.98%] 0 kvm:kvm_apic_ipi [99.99%] 25,953 kvm:kvm_apic_accept_irq [99.99%] 26,132 kvm:kvm_eoi [99.99%] 26,593 kvm:kvm_pv_eoi [99.99%] 0 kvm:kvm_nested_vmrun [99.99%] 0 kvm:kvm_nested_intercepts [99.99%] 0 kvm:kvm_nested_vmexit [99.99%] 0 kvm:kvm_nested_vmexit_inject [99.99%] 0 kvm:kvm_nested_intr_vmexit [99.99%] 0 kvm:kvm_invlpga [99.99%] 0 kvm:kvm_skinit [99.99%] 284 kvm:kvm_emulate_insn [99.99%] 68 kvm:vcpu_match_mmio [99.99%] 68 kvm:kvm_userspace_exit [99.99%] 2 kvm:kvm_set_irq [99.99%] 2 kvm:kvm_ioapic_set_irq [99.99%] 28,288 kvm:kvm_msi_set_irq [99.99%] 1 kvm:kvm_ack_irq [99.99%] 131 kvm:kvm_mmio [100.00%] 588 kvm:kvm_fpu [100.00%] 0 kvm:kvm_age_page [100.00%] 0 kvm:kvm_try_async_get_page [100.00%] 0 kvm:kvm_async_pf_doublefault [100.00%] 0 kvm:kvm_async_pf_not_present [100.00%] 0 kvm:kvm_async_pf_ready [100.00%] 0 kvm:kvm_async_pf_completed 1.002039622 seconds time elapsed We see that # of exits is almost halved. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_para.h | 7 ++++ arch/x86/kernel/kvm.c | 57 +++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 63ab1661d00e..2f7712e08b1e 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -22,6 +22,7 @@ #define KVM_FEATURE_CLOCKSOURCE2 3 #define KVM_FEATURE_ASYNC_PF 4 #define KVM_FEATURE_STEAL_TIME 5 +#define KVM_FEATURE_PV_EOI 6 /* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored. @@ -37,6 +38,7 @@ #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 #define MSR_KVM_ASYNC_PF_EN 0x4b564d02 #define MSR_KVM_STEAL_TIME 0x4b564d03 +#define MSR_KVM_PV_EOI_EN 0x4b564d04 struct kvm_steal_time { __u64 steal; @@ -89,6 +91,11 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_EOI_BIT 0 +#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT) +#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK +#define KVM_PV_EOI_DISABLED 0x0 + #ifdef __KERNEL__ #include diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index e554e5ad2fe8..75ab94c75c7a 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include static int kvmapf = 1; @@ -283,6 +285,22 @@ static void kvm_register_steal_time(void) cpu, __pa(st)); } +static DEFINE_PER_CPU(unsigned long, kvm_apic_eoi) = KVM_PV_EOI_DISABLED; + +static void kvm_guest_apic_eoi_write(u32 reg, u32 val) +{ + /** + * This relies on __test_and_clear_bit to modify the memory + * in a way that is atomic with respect to the local CPU. + * The hypervisor only accesses this memory from the local CPU so + * there's no need for lock or memory barriers. + * An optimization barrier is implied in apic write. + */ + if (__test_and_clear_bit(KVM_PV_EOI_BIT, &__get_cpu_var(kvm_apic_eoi))) + return; + apic->write(APIC_EOI, APIC_EOI_ACK); +} + void __cpuinit kvm_guest_cpu_init(void) { if (!kvm_para_available()) @@ -300,11 +318,20 @@ void __cpuinit kvm_guest_cpu_init(void) smp_processor_id()); } + if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) { + unsigned long pa; + /* Size alignment is implied but just to make it explicit. */ + BUILD_BUG_ON(__alignof__(kvm_apic_eoi) < 4); + __get_cpu_var(kvm_apic_eoi) = 0; + pa = __pa(&__get_cpu_var(kvm_apic_eoi)) | KVM_MSR_ENABLED; + wrmsrl(MSR_KVM_PV_EOI_EN, pa); + } + if (has_steal_clock) kvm_register_steal_time(); } -static void kvm_pv_disable_apf(void *unused) +static void kvm_pv_disable_apf(void) { if (!__get_cpu_var(apf_reason).enabled) return; @@ -316,11 +343,23 @@ static void kvm_pv_disable_apf(void *unused) smp_processor_id()); } +static void kvm_pv_guest_cpu_reboot(void *unused) +{ + /* + * We disable PV EOI before we load a new kernel by kexec, + * since MSR_KVM_PV_EOI_EN stores a pointer into old kernel's memory. + * New kernel can re-enable when it boots. + */ + if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) + wrmsrl(MSR_KVM_PV_EOI_EN, 0); + kvm_pv_disable_apf(); +} + static int kvm_pv_reboot_notify(struct notifier_block *nb, unsigned long code, void *unused) { if (code == SYS_RESTART) - on_each_cpu(kvm_pv_disable_apf, NULL, 1); + on_each_cpu(kvm_pv_guest_cpu_reboot, NULL, 1); return NOTIFY_DONE; } @@ -371,7 +410,9 @@ static void __cpuinit kvm_guest_cpu_online(void *dummy) static void kvm_guest_cpu_offline(void *dummy) { kvm_disable_steal_time(); - kvm_pv_disable_apf(NULL); + if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) + wrmsrl(MSR_KVM_PV_EOI_EN, 0); + kvm_pv_disable_apf(); apf_task_wake_all(); } @@ -424,6 +465,16 @@ void __init kvm_guest_init(void) pv_time_ops.steal_clock = kvm_steal_clock; } + if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) { + struct apic **drv; + + for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) { + /* Should happen once for each apic */ + WARN_ON((*drv)->eoi_write == kvm_guest_apic_eoi_write); + (*drv)->eoi_write = kvm_guest_apic_eoi_write; + } + } + #ifdef CONFIG_SMP smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; register_cpu_notifier(&kvm_cpu_notifier); -- GitLab From d0a69d6321ca759bb8d47803d06ba8571ab42d07 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:24:42 +0300 Subject: [PATCH 2663/6849] x86, bitops: note on __test_and_clear_bit atomicity __test_and_clear_bit is actually atomic with respect to the local CPU. Add a note saying that KVM on x86 relies on this behaviour so people don't accidentaly break it. Also warn not to rely on this in portable code. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/include/asm/bitops.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index a6983b277220..72f5009deb5a 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -264,6 +264,13 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. + * + * Note: the operation is performed atomically with respect to + * the local CPU, but not other CPUs. Portable code should not + * rely on this behaviour. + * KVM relies on this behaviour on x86 for modifying memory that is also + * accessed from a hypervisor on the same CPU if running in a VM: don't change + * this without also updating arch/x86/kernel/kvm.c */ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) { -- GitLab From c1af87dc96cd0f8f17694d0cd9be01b80b2c7a6a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:24:49 +0300 Subject: [PATCH 2664/6849] KVM: eoi msi documentation Document the new EOI MSR. Couldn't decide whether this change belongs conceptually on guest or host side, so a separate patch. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- Documentation/virtual/kvm/msr.txt | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Documentation/virtual/kvm/msr.txt b/Documentation/virtual/kvm/msr.txt index 96b41bd97523..730471048583 100644 --- a/Documentation/virtual/kvm/msr.txt +++ b/Documentation/virtual/kvm/msr.txt @@ -223,3 +223,36 @@ MSR_KVM_STEAL_TIME: 0x4b564d03 steal: the amount of time in which this vCPU did not run, in nanoseconds. Time during which the vcpu is idle, will not be reported as steal time. + +MSR_KVM_EOI_EN: 0x4b564d04 + data: Bit 0 is 1 when PV end of interrupt is enabled on the vcpu; 0 + when disabled. Bit 1 is reserved and must be zero. When PV end of + interrupt is enabled (bit 0 set), bits 63-2 hold a 4-byte aligned + physical address of a 4 byte memory area which must be in guest RAM and + must be zeroed. + + The first, least significant bit of 4 byte memory location will be + written to by the hypervisor, typically at the time of interrupt + injection. Value of 1 means that guest can skip writing EOI to the apic + (using MSR or MMIO write); instead, it is sufficient to signal + EOI by clearing the bit in guest memory - this location will + later be polled by the hypervisor. + Value of 0 means that the EOI write is required. + + It is always safe for the guest to ignore the optimization and perform + the APIC EOI write anyway. + + Hypervisor is guaranteed to only modify this least + significant bit while in the current VCPU context, this means that + guest does not need to use either lock prefix or memory ordering + primitives to synchronise with the hypervisor. + + However, hypervisor can set and clear this memory bit at any time: + therefore to make sure hypervisor does not interrupt the + guest and clear the least significant bit in the memory area + in the window between guest testing it to detect + whether it can skip EOI apic write and between guest + clearing it to signal EOI to the hypervisor, + guest must both read the least significant bit in the memory area and + clear it using a single CPU instruction, such as test and clear, or + compare and exchange. -- GitLab From 5cfb1d5a65dd96d2d3a0751a1e4e81dc84c1f08f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:24:54 +0300 Subject: [PATCH 2665/6849] KVM: only sync when attention bits set Commit eb0dc6d0368072236dcd086d7fdc17fd3c4574d4 introduced apic attention bitmask but kvm still syncs lapic unconditionally. As that commit suggested and in anticipation of adding more attention bits, only sync lapic if(apic_attention). Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6ed5983f78ff..c1f870690a64 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5388,7 +5388,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) if (unlikely(vcpu->arch.tsc_always_catchup)) kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); - kvm_lapic_sync_from_vapic(vcpu); + if (vcpu->arch.apic_attention) + kvm_lapic_sync_from_vapic(vcpu); r = kvm_x86_ops->handle_exit(vcpu); out: -- GitLab From d905c0693514e6f713b207377b67c9972c5d7d49 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:25:00 +0300 Subject: [PATCH 2666/6849] KVM: rearrange injection cancelling code Each time we need to cancel injection we invoke same code (cancel_injection callback). Move it towards the end of function using the familiar goto on error pattern. Will make it easier to do more cleanups for PV EOI. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c1f870690a64..7ea0f611bc89 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5296,8 +5296,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) r = kvm_mmu_reload(vcpu); if (unlikely(r)) { - kvm_x86_ops->cancel_injection(vcpu); - goto out; + goto cancel_injection; } preempt_disable(); @@ -5322,9 +5321,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) smp_wmb(); local_irq_enable(); preempt_enable(); - kvm_x86_ops->cancel_injection(vcpu); r = 1; - goto out; + goto cancel_injection; } srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); @@ -5392,6 +5390,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) kvm_lapic_sync_from_vapic(vcpu); r = kvm_x86_ops->handle_exit(vcpu); + return r; + +cancel_injection: + kvm_x86_ops->cancel_injection(vcpu); out: return r; } -- GitLab From ae7a2a3fb6f8b784c2752863f4f1f20c656f76fb Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 24 Jun 2012 19:25:07 +0300 Subject: [PATCH 2667/6849] KVM: host side for eoi optimization Implementation of PV EOI using shared memory. This reduces the number of exits an interrupt causes as much as by half. The idea is simple: there's a bit, per APIC, in guest memory, that tells the guest that it does not need EOI. We set it before injecting an interrupt and clear before injecting a nested one. Guest tests it using a test and clear operation - this is necessary so that host can detect interrupt nesting - and if set, it can skip the EOI MSR. There's a new MSR to set the address of said register in guest memory. Otherwise not much changed: - Guest EOI is not required - Register is tested & ISR is automatically cleared on exit For testing results see description of previous patch 'kvm_para: guest side for eoi avoidance'. Signed-off-by: Michael S. Tsirkin Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 12 +++ arch/x86/kvm/cpuid.c | 1 + arch/x86/kvm/lapic.c | 141 +++++++++++++++++++++++++++++++- arch/x86/kvm/lapic.h | 2 + arch/x86/kvm/trace.h | 34 ++++++++ arch/x86/kvm/x86.c | 7 ++ 6 files changed, 193 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index db7c1f2709a2..24b76474d9de 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -175,6 +175,13 @@ enum { /* apic attention bits */ #define KVM_APIC_CHECK_VAPIC 0 +/* + * The following bit is set with PV-EOI, unset on EOI. + * We detect PV-EOI changes by guest by comparing + * this bit with PV-EOI in guest memory. + * See the implementation in apic_update_pv_eoi. + */ +#define KVM_APIC_PV_EOI_PENDING 1 /* * We don't want allocation failures within the mmu code, so we preallocate @@ -484,6 +491,11 @@ struct kvm_vcpu_arch { u64 length; u64 status; } osvw; + + struct { + u64 msr_val; + struct gfn_to_hva_cache data; + } pv_eoi; }; struct kvm_lpage_info { diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 7df1c6d839fb..61ccbdf3d0ac 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -409,6 +409,7 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, (1 << KVM_FEATURE_NOP_IO_DELAY) | (1 << KVM_FEATURE_CLOCKSOURCE2) | (1 << KVM_FEATURE_ASYNC_PF) | + (1 << KVM_FEATURE_PV_EOI) | (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT); if (sched_info_on()) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 805d887784f6..ce878788a39f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -311,6 +311,54 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) irq->level, irq->trig_mode); } +static int pv_eoi_put_user(struct kvm_vcpu *vcpu, u8 val) +{ + + return kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.pv_eoi.data, &val, + sizeof(val)); +} + +static int pv_eoi_get_user(struct kvm_vcpu *vcpu, u8 *val) +{ + + return kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.pv_eoi.data, val, + sizeof(*val)); +} + +static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.pv_eoi.msr_val & KVM_MSR_ENABLED; +} + +static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) +{ + u8 val; + if (pv_eoi_get_user(vcpu, &val) < 0) + apic_debug("Can't read EOI MSR value: 0x%llx\n", + (unsigned long long)vcpi->arch.pv_eoi.msr_val); + return val & 0x1; +} + +static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) +{ + if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) { + apic_debug("Can't set EOI MSR value: 0x%llx\n", + (unsigned long long)vcpi->arch.pv_eoi.msr_val); + return; + } + __set_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); +} + +static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) +{ + if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) { + apic_debug("Can't clear EOI MSR value: 0x%llx\n", + (unsigned long long)vcpi->arch.pv_eoi.msr_val); + return; + } + __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); +} + static inline int apic_find_highest_isr(struct kvm_lapic *apic) { int result; @@ -527,15 +575,18 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio; } -static void apic_set_eoi(struct kvm_lapic *apic) +static int apic_set_eoi(struct kvm_lapic *apic) { int vector = apic_find_highest_isr(apic); + + trace_kvm_eoi(apic, vector); + /* * Not every write EOI will has corresponding ISR, * one example is when Kernel check timer on setup_IO_APIC */ if (vector == -1) - return; + return vector; apic_clear_isr(vector, apic); apic_update_ppr(apic); @@ -550,6 +601,7 @@ static void apic_set_eoi(struct kvm_lapic *apic) kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); } kvm_make_request(KVM_REQ_EVENT, apic->vcpu); + return vector; } static void apic_send_ipi(struct kvm_lapic *apic) @@ -1132,6 +1184,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) atomic_set(&apic->lapic_timer.pending, 0); if (kvm_vcpu_is_bsp(vcpu)) vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; + vcpu->arch.pv_eoi.msr_val = 0; apic_update_ppr(apic); vcpu->arch.apic_arb_prio = 0; @@ -1332,11 +1385,51 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) hrtimer_start_expires(timer, HRTIMER_MODE_ABS); } +/* + * apic_sync_pv_eoi_from_guest - called on vmexit or cancel interrupt + * + * Detect whether guest triggered PV EOI since the + * last entry. If yes, set EOI on guests's behalf. + * Clear PV EOI in guest memory in any case. + */ +static void apic_sync_pv_eoi_from_guest(struct kvm_vcpu *vcpu, + struct kvm_lapic *apic) +{ + bool pending; + int vector; + /* + * PV EOI state is derived from KVM_APIC_PV_EOI_PENDING in host + * and KVM_PV_EOI_ENABLED in guest memory as follows: + * + * KVM_APIC_PV_EOI_PENDING is unset: + * -> host disabled PV EOI. + * KVM_APIC_PV_EOI_PENDING is set, KVM_PV_EOI_ENABLED is set: + * -> host enabled PV EOI, guest did not execute EOI yet. + * KVM_APIC_PV_EOI_PENDING is set, KVM_PV_EOI_ENABLED is unset: + * -> host enabled PV EOI, guest executed EOI. + */ + BUG_ON(!pv_eoi_enabled(vcpu)); + pending = pv_eoi_get_pending(vcpu); + /* + * Clear pending bit in any case: it will be set again on vmentry. + * While this might not be ideal from performance point of view, + * this makes sure pv eoi is only enabled when we know it's safe. + */ + pv_eoi_clr_pending(vcpu); + if (pending) + return; + vector = apic_set_eoi(apic); + trace_kvm_pv_eoi(apic, vector); +} + void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) { u32 data; void *vapic; + if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention)) + apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic); + if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) return; @@ -1347,17 +1440,44 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) apic_set_tpr(vcpu->arch.apic, data & 0xff); } +/* + * apic_sync_pv_eoi_to_guest - called before vmentry + * + * Detect whether it's safe to enable PV EOI and + * if yes do so. + */ +static void apic_sync_pv_eoi_to_guest(struct kvm_vcpu *vcpu, + struct kvm_lapic *apic) +{ + if (!pv_eoi_enabled(vcpu) || + /* IRR set or many bits in ISR: could be nested. */ + apic->irr_pending || + /* Cache not set: could be safe but we don't bother. */ + apic->highest_isr_cache == -1 || + /* Need EOI to update ioapic. */ + kvm_ioapic_handles_vector(vcpu->kvm, apic->highest_isr_cache)) { + /* + * PV EOI was disabled by apic_sync_pv_eoi_from_guest + * so we need not do anything here. + */ + return; + } + + pv_eoi_set_pending(apic->vcpu); +} + void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) { u32 data, tpr; int max_irr, max_isr; - struct kvm_lapic *apic; + struct kvm_lapic *apic = vcpu->arch.apic; void *vapic; + apic_sync_pv_eoi_to_guest(vcpu, apic); + if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) return; - apic = vcpu->arch.apic; tpr = apic_get_reg(apic, APIC_TASKPRI) & 0xff; max_irr = apic_find_highest_irr(apic); if (max_irr < 0) @@ -1443,3 +1563,16 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data) return 0; } + +int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) +{ + u64 addr = data & ~KVM_MSR_ENABLED; + if (!IS_ALIGNED(addr, 4)) + return 1; + + vcpu->arch.pv_eoi.msr_val = data; + if (!pv_eoi_enabled(vcpu)) + return 0; + return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data, + addr); +} diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 5ac9e5e2fedd..4af5405ae1e2 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -69,4 +69,6 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu) { return vcpu->arch.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE; } + +int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); #endif diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 911d2641f14c..851914e207fc 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -517,6 +517,40 @@ TRACE_EVENT(kvm_apic_accept_irq, __entry->coalesced ? " (coalesced)" : "") ); +TRACE_EVENT(kvm_eoi, + TP_PROTO(struct kvm_lapic *apic, int vector), + TP_ARGS(apic, vector), + + TP_STRUCT__entry( + __field( __u32, apicid ) + __field( int, vector ) + ), + + TP_fast_assign( + __entry->apicid = apic->vcpu->vcpu_id; + __entry->vector = vector; + ), + + TP_printk("apicid %x vector %d", __entry->apicid, __entry->vector) +); + +TRACE_EVENT(kvm_pv_eoi, + TP_PROTO(struct kvm_lapic *apic, int vector), + TP_ARGS(apic, vector), + + TP_STRUCT__entry( + __field( __u32, apicid ) + __field( int, vector ) + ), + + TP_fast_assign( + __entry->apicid = apic->vcpu->vcpu_id; + __entry->vector = vector; + ), + + TP_printk("apicid %x vector %d", __entry->apicid, __entry->vector) +); + /* * Tracepoint for nested VMRUN */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7ea0f611bc89..8eacb2e64560 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -795,6 +795,7 @@ static u32 msrs_to_save[] = { MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME, + MSR_KVM_PV_EOI_EN, MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, MSR_STAR, #ifdef CONFIG_X86_64 @@ -1653,6 +1654,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); break; + case MSR_KVM_PV_EOI_EN: + if (kvm_lapic_enable_pv_eoi(vcpu, data)) + return 1; + break; case MSR_IA32_MCG_CTL: case MSR_IA32_MCG_STATUS: @@ -5394,6 +5399,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) cancel_injection: kvm_x86_ops->cancel_injection(vcpu); + if (unlikely(vcpu->arch.apic_attention)) + kvm_lapic_sync_from_vapic(vcpu); out: return r; } -- GitLab From ef5b6e127761667f78d99b7510a3876077fe9abe Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Sun, 17 Jun 2012 09:56:46 +0000 Subject: [PATCH 2668/6849] netfilter: ipset: fix interface comparision in hash-netiface sets ifname_compare() assumes that skb->dev is zero-padded, e.g 'eth1\0\0\0\0\0...'. This isn't always the case. e1000 driver does strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); in e1000_probe(), so once device is registered dev->name memory contains 'eth1\0:0:3\0\0\0' (or something like that), which makes eth1 compare fail. Use plain strcmp() instead. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipset/ip_set_hash_netiface.c | 32 +++------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index ee863943c826..d5d3607ae7bc 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c @@ -38,30 +38,6 @@ struct iface_node { #define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) -static inline long -ifname_compare(const char *_a, const char *_b) -{ - const long *a = (const long *)_a; - const long *b = (const long *)_b; - - BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); - if (a[0] != b[0]) - return a[0] - b[0]; - if (IFNAMSIZ > sizeof(long)) { - if (a[1] != b[1]) - return a[1] - b[1]; - } - if (IFNAMSIZ > 2 * sizeof(long)) { - if (a[2] != b[2]) - return a[2] - b[2]; - } - if (IFNAMSIZ > 3 * sizeof(long)) { - if (a[3] != b[3]) - return a[3] - b[3]; - } - return 0; -} - static void rbtree_destroy(struct rb_root *root) { @@ -99,7 +75,7 @@ iface_test(struct rb_root *root, const char **iface) while (n) { const char *d = iface_data(n); - long res = ifname_compare(*iface, d); + int res = strcmp(*iface, d); if (res < 0) n = n->rb_left; @@ -121,7 +97,7 @@ iface_add(struct rb_root *root, const char **iface) while (*n) { char *ifname = iface_data(*n); - long res = ifname_compare(*iface, ifname); + int res = strcmp(*iface, ifname); p = *n; if (res < 0) @@ -366,7 +342,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], struct hash_netiface4_elem data = { .cidr = HOST_MASK }; u32 ip = 0, ip_to, last; u32 timeout = h->timeout; - char iface[IFNAMSIZ] = {}; + char iface[IFNAMSIZ]; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || @@ -663,7 +639,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_netiface6_elem data = { .cidr = HOST_MASK }; u32 timeout = h->timeout; - char iface[IFNAMSIZ] = {}; + char iface[IFNAMSIZ]; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || -- GitLab From c24584c028a62900ea6b541b312030f0feac93b8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 24 Jun 2012 21:58:23 +0000 Subject: [PATCH 2669/6849] netfilter: ipvs: fix dst leak in __ip_vs_addr_is_local_v6 After call to ip6_route_output() we must release dst or we leak it. Also should test dst->error, as ip6_route_output() never returns NULL. Use boolean while we are at it. Signed-off-by: Eric Dumazet Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipvs/ip_vs_ctl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index dd811b8dd97c..d43e3c122f7b 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -76,19 +76,19 @@ static void __ip_vs_del_service(struct ip_vs_service *svc); #ifdef CONFIG_IP_VS_IPV6 /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ -static int __ip_vs_addr_is_local_v6(struct net *net, - const struct in6_addr *addr) +static bool __ip_vs_addr_is_local_v6(struct net *net, + const struct in6_addr *addr) { - struct rt6_info *rt; struct flowi6 fl6 = { .daddr = *addr, }; + struct dst_entry *dst = ip6_route_output(net, NULL, &fl6); + bool is_local; - rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); - if (rt && rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) - return 1; + is_local = !dst->error && dst->dev && (dst->dev->flags & IFF_LOOPBACK); - return 0; + dst_release(dst); + return is_local; } #endif -- GitLab From a2da399823ccb0f4ddf83700bf297803e5320f7e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 25 Jun 2012 12:07:18 +0200 Subject: [PATCH 2670/6849] netfilter: update location of my trees Signed-off-by: Pablo Neira Ayuso --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f6e62def61cd..302aa00e8309 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4654,8 +4654,8 @@ L: netfilter@vger.kernel.org L: coreteam@netfilter.org W: http://www.netfilter.org/ W: http://www.iptables.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git +T: git git://1984.lsi.us.es/nf +T: git git://1984.lsi.us.es/nf-next S: Supported F: include/linux/netfilter* F: include/linux/netfilter/ -- GitLab From 3daf74d78dfcd552445c35f1b82a271ca305ceb9 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Sat, 23 Jun 2012 02:23:08 +0530 Subject: [PATCH 2671/6849] usb: dwc3: remove WARN_ON from dwc_stop_active_transfer Now we are sure that, if res_trans_idx is zero, then endpoint has been stopped. So it's safe to just return if endpoint is already stopped. No need to generate warning anymore. While doing so, it's better to return when res_trans_idx is zero and decrease one level of indentation. Signed-off-by: Pratyush Anand [ balbi@ti.com: slightly changed commit log ] Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f6fb42da2e64..9ac4835d7b6b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1870,16 +1870,16 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) dep = dwc->eps[epnum]; - WARN_ON(!dep->res_trans_idx); - if (dep->res_trans_idx) { - cmd = DWC3_DEPCMD_ENDTRANSFER; - cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; - cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); - memset(¶ms, 0, sizeof(params)); - ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); - WARN_ON_ONCE(ret); - dep->res_trans_idx = 0; - } + if (!dep->res_trans_idx) + return; + + cmd = DWC3_DEPCMD_ENDTRANSFER; + cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; + cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); + memset(¶ms, 0, sizeof(params)); + ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); + WARN_ON_ONCE(ret); + dep->res_trans_idx = 0; } static void dwc3_stop_active_transfers(struct dwc3 *dwc) -- GitLab From b511e5e76bf488cd3eec1048483a3898393a4dca Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Jun 2012 12:00:50 +0300 Subject: [PATCH 2672/6849] usb: dwc3: gadget: split special cases of ep_queue() It makes it easier to read and also avoids setting DWC3_EP_PENDING_REQUEST just so the next branch evaluates true. No functional changes otherwise. Cc: Pratyush Anand Cc: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 50 ++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9ac4835d7b6b..1c98aee051a5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1075,17 +1075,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) list_add_tail(&req->list, &dep->request_list); - if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { - if (dep->flags & DWC3_EP_BUSY) { - dep->flags |= DWC3_EP_PENDING_REQUEST; - } else if (dep->flags & DWC3_EP_MISSED_ISOC) { - __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf); - dep->flags &= ~DWC3_EP_MISSED_ISOC; - } - } - /* - * There are two special cases: + * There are a few special cases: * * 1. XferNotReady with empty list of requests. We need to kick the * transfer here in that situation, otherwise we will be NAKing @@ -1094,24 +1085,29 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) * able to receive the data until the next request is queued. * The following code is handling exactly that. * - * 2. XferInProgress on Isoc EP with an active transfer. We need to - * kick the transfer here after queuing a request, otherwise the - * core may not see the modified TRB(s). */ if (dep->flags & DWC3_EP_PENDING_REQUEST) { int ret; - int start_trans = 1; - u8 trans_idx = dep->res_trans_idx; - if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && - (dep->flags & DWC3_EP_BUSY)) { - start_trans = 0; - WARN_ON_ONCE(!trans_idx); - } else { - trans_idx = 0; + ret = __dwc3_gadget_kick_transfer(dep, 0, true); + if (ret && ret != -EBUSY) { + struct dwc3 *dwc = dep->dwc; + + dev_dbg(dwc->dev, "%s: failed to kick transfers\n", + dep->name); } + } - ret = __dwc3_gadget_kick_transfer(dep, trans_idx, start_trans); + /* + * 2. XferInProgress on Isoc EP with an active transfer. We need to + * kick the transfer here after queuing a request, otherwise the + * core may not see the modified TRB(s). + */ + if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && + (dep->flags & DWC3_EP_BUSY)) { + WARN_ON_ONCE(!dep->res_trans_idx); + ret = __dwc3_gadget_kick_transfer(dep, dep->res_trans_idx, + false); if (ret && ret != -EBUSY) { struct dwc3 *dwc = dep->dwc; @@ -1120,6 +1116,16 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) } } + /* + * 3. Missed ISOC Handling. We need to start isoc transfer on the saved + * uframe number. + */ + if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && + (dep->flags & DWC3_EP_MISSED_ISOC)) { + __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf); + dep->flags &= ~DWC3_EP_MISSED_ISOC; + } + return 0; } -- GitLab From b4996a8631e80a2aaddb5c487ff6b9ad37315f70 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Jun 2012 12:04:13 +0300 Subject: [PATCH 2673/6849] usb: dwc3: rename res_trans_idx to resource_index resource_index is more human readable. No functional changes. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 4 ++-- drivers/usb/dwc3/ep0.c | 4 ++-- drivers/usb/dwc3/gadget.c | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index d3e56cfb29c3..151eca876dfd 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -404,7 +404,7 @@ struct dwc3_event_buffer { * @current_trb: index of current used trb * @number: endpoint number (1 - 15) * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK - * @res_trans_idx: Resource transfer index + * @resource_index: Resource transfer index * @current_uf: Current uf received through last event parameter * @interval: the intervall on which the ISOC transfer is started * @name: a human readable name e.g. ep1out-bulk @@ -438,7 +438,7 @@ struct dwc3_ep { u8 number; u8 type; - u8 res_trans_idx; + u8 resource_index; u16 current_uf; u32 interval; diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 90eb1ba65454..9a8f26cef0a1 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -113,7 +113,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, } dep->flags |= DWC3_EP_BUSY; - dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, + dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc, dep->number); dwc->ep0_next_event = DWC3_EP0_COMPLETE; @@ -757,7 +757,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; dep->flags &= ~DWC3_EP_BUSY; - dep->res_trans_idx = 0; + dep->resource_index = 0; dwc->setup_packet_pending = false; switch (dwc->ep0state) { diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1c98aee051a5..1b5fbdd859c2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1010,9 +1010,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, dep->flags |= DWC3_EP_BUSY; if (start_new) { - dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, + dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc, dep->number); - WARN_ON_ONCE(!dep->res_trans_idx); + WARN_ON_ONCE(!dep->resource_index); } return 0; @@ -1105,8 +1105,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) */ if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && (dep->flags & DWC3_EP_BUSY)) { - WARN_ON_ONCE(!dep->res_trans_idx); - ret = __dwc3_gadget_kick_transfer(dep, dep->res_trans_idx, + WARN_ON_ONCE(!dep->resource_index); + ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index, false); if (ret && ret != -EBUSY) { struct dwc3 *dwc = dep->dwc; @@ -1790,7 +1790,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: - dep->res_trans_idx = 0; + dep->resource_index = 0; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", @@ -1876,16 +1876,16 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) dep = dwc->eps[epnum]; - if (!dep->res_trans_idx) + if (!dep->resource_index) return; cmd = DWC3_DEPCMD_ENDTRANSFER; cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; - cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); + cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); memset(¶ms, 0, sizeof(params)); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); WARN_ON_ONCE(ret); - dep->res_trans_idx = 0; + dep->resource_index = 0; } static void dwc3_stop_active_transfers(struct dwc3 *dwc) -- GitLab From 721002ec1dd55a52425455826af49cf8853b2d4f Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:02:45 +0530 Subject: [PATCH 2674/6849] usb: otg: utils: rename function name in OTG utils _transceiver() in otg.c is replaced with _phy. usb_set_transceiver is replaced with usb_add_phy to make it similar to other usb standard function names like usb_add_hcd. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/power/ab8500_charger.c | 6 +++--- drivers/power/isp1704_charger.c | 6 +++--- drivers/power/pda_power.c | 6 +++--- drivers/power/twl4030_charger.c | 6 +++--- drivers/usb/chipidea/udc.c | 8 ++++---- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/mv_udc_core.c | 2 +- drivers/usb/gadget/omap_udc.c | 6 +++--- drivers/usb/gadget/pxa25x_udc.c | 6 +++--- drivers/usb/gadget/pxa27x_udc.c | 4 ++-- drivers/usb/gadget/s3c-hsudc.c | 4 ++-- drivers/usb/host/ehci-fsl.c | 6 +++--- drivers/usb/host/ehci-msm.c | 6 +++--- drivers/usb/host/ehci-mv.c | 6 +++--- drivers/usb/host/ehci-tegra.c | 6 +++--- drivers/usb/host/ohci-omap.c | 6 +++--- drivers/usb/musb/am35x.c | 4 ++-- drivers/usb/musb/blackfin.c | 4 ++-- drivers/usb/musb/da8xx.c | 4 ++-- drivers/usb/musb/davinci.c | 6 +++--- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_dsps.c | 6 +++--- drivers/usb/musb/omap2430.c | 4 ++-- drivers/usb/musb/tusb6010.c | 6 +++--- drivers/usb/musb/ux500.c | 4 ++-- drivers/usb/otg/ab8500-usb.c | 4 ++-- drivers/usb/otg/fsl_otg.c | 6 +++--- drivers/usb/otg/gpio_vbus.c | 4 ++-- drivers/usb/otg/isp1301_omap.c | 4 ++-- drivers/usb/otg/msm_otg.c | 6 +++--- drivers/usb/otg/mv_otg.c | 6 +++--- drivers/usb/otg/nop-usb-xceiv.c | 4 ++-- drivers/usb/otg/otg.c | 32 +++++++++++++++---------------- drivers/usb/otg/twl4030-usb.c | 2 +- drivers/usb/otg/twl6030-usb.c | 2 +- include/linux/usb/otg.h | 10 +++++----- 36 files changed, 103 insertions(+), 103 deletions(-) diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index d2303d0b7c75..cf5ffc4d1048 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -2517,7 +2517,7 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev) dev_err(di->dev, "%s mask and set failed\n", __func__); usb_unregister_notifier(di->usb_phy, &di->nb); - usb_put_transceiver(di->usb_phy); + usb_put_phy(di->usb_phy); /* Delete the work queue */ destroy_workqueue(di->charger_wq); @@ -2688,7 +2688,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev) goto free_ac; } - di->usb_phy = usb_get_transceiver(); + di->usb_phy = usb_get_phy(); if (!di->usb_phy) { dev_err(di->dev, "failed to get usb transceiver\n"); ret = -EINVAL; @@ -2747,7 +2747,7 @@ free_irq: free_irq(irq, di); } put_usb_phy: - usb_put_transceiver(di->usb_phy); + usb_put_phy(di->usb_phy); free_usb: power_supply_unregister(&di->usb_chg.psy); free_ac: diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index e5ccd2979773..50773ae6f72e 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -415,7 +415,7 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) if (!isp) return -ENOMEM; - isp->phy = usb_get_transceiver(); + isp->phy = usb_get_phy(); if (!isp->phy) goto fail0; @@ -475,7 +475,7 @@ fail2: power_supply_unregister(&isp->psy); fail1: isp1704_charger_set_power(isp, 0); - usb_put_transceiver(isp->phy); + usb_put_phy(isp->phy); fail0: kfree(isp); @@ -490,7 +490,7 @@ static int __devexit isp1704_charger_remove(struct platform_device *pdev) usb_unregister_notifier(isp->phy, &isp->nb); power_supply_unregister(&isp->psy); - usb_put_transceiver(isp->phy); + usb_put_phy(isp->phy); isp1704_charger_set_power(isp, 0); kfree(isp); diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index 214468f4444a..e0f206b0775b 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -321,7 +321,7 @@ static int pda_power_probe(struct platform_device *pdev) } #ifdef CONFIG_USB_OTG_UTILS - transceiver = usb_get_transceiver(); + transceiver = usb_get_phy(); if (transceiver && !pdata->is_usb_online) { pdata->is_usb_online = otg_is_usb_online; } @@ -409,7 +409,7 @@ usb_supply_failed: free_irq(ac_irq->start, &pda_psy_ac); #ifdef CONFIG_USB_OTG_UTILS if (transceiver) - usb_put_transceiver(transceiver); + usb_put_phy(transceiver); #endif ac_irq_failed: if (pdata->is_ac_online) @@ -444,7 +444,7 @@ static int pda_power_remove(struct platform_device *pdev) power_supply_unregister(&pda_psy_ac); #ifdef CONFIG_USB_OTG_UTILS if (transceiver) - usb_put_transceiver(transceiver); + usb_put_phy(transceiver); #endif if (ac_draw) { regulator_put(ac_draw); diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index fdad850c77d3..fcddd115cc08 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -479,7 +479,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) INIT_WORK(&bci->work, twl4030_bci_usb_work); - bci->transceiver = usb_get_transceiver(); + bci->transceiver = usb_get_phy(); if (bci->transceiver != NULL) { bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; usb_register_notifier(bci->transceiver, &bci->usb_nb); @@ -509,7 +509,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) fail_unmask_interrupts: if (bci->transceiver != NULL) { usb_unregister_notifier(bci->transceiver, &bci->usb_nb); - usb_put_transceiver(bci->transceiver); + usb_put_phy(bci->transceiver); } free_irq(bci->irq_bci, bci); fail_bci_irq: @@ -540,7 +540,7 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev) if (bci->transceiver != NULL) { usb_unregister_notifier(bci->transceiver, &bci->usb_nb); - usb_put_transceiver(bci->transceiver); + usb_put_phy(bci->transceiver); } free_irq(bci->irq_bci, bci); free_irq(bci->irq_chg, bci); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 51f96942dc5e..4468f2c2dddd 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1687,7 +1687,7 @@ static int udc_start(struct ci13xxx *udc) udc->gadget.ep0 = &udc->ep0in->ep; - udc->transceiver = usb_get_transceiver(); + udc->transceiver = usb_get_phy(); if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) { if (udc->transceiver == NULL) { @@ -1731,7 +1731,7 @@ static int udc_start(struct ci13xxx *udc) remove_trans: if (udc->transceiver) { otg_set_peripheral(udc->transceiver->otg, &udc->gadget); - usb_put_transceiver(udc->transceiver); + usb_put_phy(udc->transceiver); } dev_err(dev, "error = %i\n", retval); @@ -1741,7 +1741,7 @@ unreg_device: device_unregister(&udc->gadget.dev); put_transceiver: if (udc->transceiver) - usb_put_transceiver(udc->transceiver); + usb_put_phy(udc->transceiver); free_pools: dma_pool_destroy(udc->td_pool); free_qh_pool: @@ -1774,7 +1774,7 @@ static void udc_stop(struct ci13xxx *udc) if (udc->transceiver) { otg_set_peripheral(udc->transceiver->otg, NULL); - usb_put_transceiver(udc->transceiver); + usb_put_phy(udc->transceiver); } dbg_remove_files(&udc->gadget.dev); device_unregister(&udc->gadget.dev); diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 28316858208b..d7038509b956 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2455,7 +2455,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) #ifdef CONFIG_USB_OTG if (pdata->operating_mode == FSL_USB2_DR_OTG) { - udc_controller->transceiver = usb_get_transceiver(); + udc_controller->transceiver = usb_get_phy(); if (!udc_controller->transceiver) { ERR("Can't find OTG driver!\n"); ret = -ENODEV; diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index dbcd1329495e..5d779955d5a6 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2180,7 +2180,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev) #ifdef CONFIG_USB_OTG_UTILS if (pdata->mode == MV_USB_MODE_OTG) - udc->transceiver = usb_get_transceiver(); + udc->transceiver = usb_get_phy(); #endif udc->clknum = pdata->clknum; diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 7ba32469c5bd..74b9bb8099e7 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2865,7 +2865,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) * use it. Except for OTG, we don't _need_ to talk to one; * but not having one probably means no VBUS detection. */ - xceiv = usb_get_transceiver(); + xceiv = usb_get_phy(); if (xceiv) type = xceiv->label; else if (config->otg) { @@ -3011,7 +3011,7 @@ cleanup1: cleanup0: if (xceiv) - usb_put_transceiver(xceiv); + usb_put_phy(xceiv); if (cpu_is_omap16xx() || cpu_is_omap24xx() || cpu_is_omap7xx()) { clk_disable(hhc_clk); @@ -3041,7 +3041,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev) pullup_disable(udc); if (udc->transceiver) { - usb_put_transceiver(udc->transceiver); + usb_put_phy(udc->transceiver); udc->transceiver = NULL; } omap_writew(0, UDC_SYSCON1); diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index d7c8cb3bf759..a658e446caba 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2159,7 +2159,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev->mach = pdev->dev.platform_data; - dev->transceiver = usb_get_transceiver(); + dev->transceiver = usb_get_phy(); if (gpio_is_valid(dev->mach->gpio_pullup)) { if ((retval = gpio_request(dev->mach->gpio_pullup, @@ -2238,7 +2238,7 @@ lubbock_fail0: gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: if (dev->transceiver) { - usb_put_transceiver(dev->transceiver); + usb_put_phy(dev->transceiver); dev->transceiver = NULL; } clk_put(dev->clk); @@ -2280,7 +2280,7 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) clk_put(dev->clk); if (dev->transceiver) { - usb_put_transceiver(dev->transceiver); + usb_put_phy(dev->transceiver); dev->transceiver = NULL; } diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 98acb3ab9e17..b982304a49c1 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2464,7 +2464,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) udc->dev = &pdev->dev; udc->mach = pdev->dev.platform_data; - udc->transceiver = usb_get_transceiver(); + udc->transceiver = usb_get_phy(); gpio = udc->mach->gpio_pullup; if (gpio_is_valid(gpio)) { @@ -2543,7 +2543,7 @@ static int __exit pxa_udc_remove(struct platform_device *_dev) if (gpio_is_valid(gpio)) gpio_free(gpio); - usb_put_transceiver(udc->transceiver); + usb_put_phy(udc->transceiver); udc->transceiver = NULL; platform_set_drvdata(_dev, NULL); diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 36c6836eeb0f..9ad33395f564 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1282,7 +1282,7 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) hsudc->dev = dev; hsudc->pd = pdev->dev.platform_data; - hsudc->transceiver = usb_get_transceiver(); + hsudc->transceiver = usb_get_phy(); for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; @@ -1386,7 +1386,7 @@ err_remap: release_mem_region(res->start, resource_size(res)); err_res: if (hsudc->transceiver) - usb_put_transceiver(hsudc->transceiver); + usb_put_phy(hsudc->transceiver); regulator_bulk_free(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); err_supplies: diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 43362577b54a..0e8976a0ed51 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -142,7 +142,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, if (pdata->operating_mode == FSL_USB2_DR_OTG) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - ehci->transceiver = usb_get_transceiver(); + ehci->transceiver = usb_get_phy(); dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, transceiver=0x%p\n", hcd, ehci, ehci->transceiver); @@ -150,7 +150,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, retval = otg_set_host(ehci->transceiver->otg, &ehci_to_hcd(ehci)->self); if (retval) { - usb_put_transceiver(ehci->transceiver); + usb_put_phy(ehci->transceiver); goto err4; } } else { @@ -194,7 +194,7 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, if (ehci->transceiver) { otg_set_host(ehci->transceiver->otg, NULL); - usb_put_transceiver(ehci->transceiver); + usb_put_phy(ehci->transceiver); } usb_remove_hcd(hcd); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 9803a55fd5f4..7badd5db398c 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -145,7 +145,7 @@ static int ehci_msm_probe(struct platform_device *pdev) * powering up VBUS, mapping of registers address space and power * management. */ - phy = usb_get_transceiver(); + phy = usb_get_phy(); if (!phy) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -ENODEV; @@ -169,7 +169,7 @@ static int ehci_msm_probe(struct platform_device *pdev) return 0; put_transceiver: - usb_put_transceiver(phy); + usb_put_phy(phy); unmap: iounmap(hcd->regs); put_hcd: @@ -187,7 +187,7 @@ static int __devexit ehci_msm_remove(struct platform_device *pdev) pm_runtime_set_suspended(&pdev->dev); otg_set_host(phy->otg, NULL); - usb_put_transceiver(phy); + usb_put_phy(phy); usb_put_hcd(hcd); diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index a936bbcff8f4..24f838fe25ac 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -253,7 +253,7 @@ static int mv_ehci_probe(struct platform_device *pdev) ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { #ifdef CONFIG_USB_OTG_UTILS - ehci_mv->otg = usb_get_transceiver(); + ehci_mv->otg = usb_get_phy(); if (!ehci_mv->otg) { dev_err(&pdev->dev, "unable to find transceiver\n"); @@ -303,7 +303,7 @@ err_set_vbus: #ifdef CONFIG_USB_OTG_UTILS err_put_transceiver: if (ehci_mv->otg) - usb_put_transceiver(ehci_mv->otg); + usb_put_phy(ehci_mv->otg); #endif err_disable_clk: mv_ehci_disable(ehci_mv); @@ -333,7 +333,7 @@ static int mv_ehci_remove(struct platform_device *pdev) if (ehci_mv->otg) { otg_set_host(ehci_mv->otg->otg, NULL); - usb_put_transceiver(ehci_mv->otg); + usb_put_phy(ehci_mv->otg); } if (ehci_mv->mode == MV_USB_MODE_HOST) { diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 68548236ec42..ee17d19b1b82 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -749,7 +749,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { - tegra->transceiver = usb_get_transceiver(); + tegra->transceiver = usb_get_phy(); if (tegra->transceiver) otg_set_host(tegra->transceiver->otg, &hcd->self); } @@ -775,7 +775,7 @@ fail: #ifdef CONFIG_USB_OTG_UTILS if (tegra->transceiver) { otg_set_host(tegra->transceiver->otg, NULL); - usb_put_transceiver(tegra->transceiver); + usb_put_phy(tegra->transceiver); } #endif tegra_usb_phy_close(tegra->phy); @@ -810,7 +810,7 @@ static int tegra_ehci_remove(struct platform_device *pdev) #ifdef CONFIG_USB_OTG_UTILS if (tegra->transceiver) { otg_set_host(tegra->transceiver->otg, NULL); - usb_put_transceiver(tegra->transceiver); + usb_put_phy(tegra->transceiver); } #endif diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 9ce35d0d9d5d..c2c1f55889a4 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -211,14 +211,14 @@ static int ohci_omap_init(struct usb_hcd *hcd) #ifdef CONFIG_USB_OTG if (need_transceiver) { - ohci->transceiver = usb_get_transceiver(); + ohci->transceiver = usb_get_phy(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver->otg, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { - usb_put_transceiver(ohci->transceiver); + usb_put_phy(ohci->transceiver); return status; } } else { @@ -405,7 +405,7 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) usb_remove_hcd(hcd); if (ohci->transceiver) { (void) otg_set_host(ohci->transceiver->otg, 0); - usb_put_transceiver(ohci->transceiver); + usb_put_phy(ohci->transceiver); } if (machine_is_omap_osk()) gpio_free(9); diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 9f3eda91ea4d..a75989bbb3d4 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -364,7 +364,7 @@ static int am35x_musb_init(struct musb *musb) return -ENODEV; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) return -ENODEV; @@ -406,7 +406,7 @@ static int am35x_musb_exit(struct musb *musb) if (data->set_phy_power) data->set_phy_power(0); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index a087ed6c3be9..522a4a263df8 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -415,7 +415,7 @@ static int bfin_musb_init(struct musb *musb) gpio_direction_output(musb->config->gpio_vrsel, 0); usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) { gpio_free(musb->config->gpio_vrsel); return -ENODEV; @@ -440,7 +440,7 @@ static int bfin_musb_exit(struct musb *musb) { gpio_free(musb->config->gpio_vrsel); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; } diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 8bd9566f3fbb..61868d604b28 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -425,7 +425,7 @@ static int da8xx_musb_init(struct musb *musb) goto fail; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) goto fail; @@ -458,7 +458,7 @@ static int da8xx_musb_exit(struct musb *musb) phy_off(); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 768b4b55c816..441f776366f3 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -384,7 +384,7 @@ static int davinci_musb_init(struct musb *musb) u32 revision; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) goto unregister; @@ -443,7 +443,7 @@ static int davinci_musb_init(struct musb *musb) return 0; fail: - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); unregister: usb_nop_xceiv_unregister(); return -ENODEV; @@ -493,7 +493,7 @@ static int davinci_musb_exit(struct musb *musb) phy_off(); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index db3dff854b71..26f1befb4896 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1909,7 +1909,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) /* The musb_platform_init() call: * - adjusts musb->mregs and musb->isr if needed, * - may initialize an integrated tranceiver - * - initializes musb->xceiv, usually by otg_get_transceiver() + * - initializes musb->xceiv, usually by otg_get_phy() * - stops powering VBUS * * There are various transceiver configurations. Blackfin, diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 23db42db761a..716c113608f4 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -376,7 +376,7 @@ static int dsps_musb_init(struct musb *musb) /* NOP driver needs change if supporting dual instance */ usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) return -ENODEV; @@ -409,7 +409,7 @@ static int dsps_musb_init(struct musb *musb) return 0; err0: - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return status; } @@ -430,7 +430,7 @@ static int dsps_musb_exit(struct musb *musb) data->set_phy_power(0); /* NOP driver needs change if supporting dual instance */ - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c7785e81254c..e16dbbf7f305 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -292,7 +292,7 @@ static int omap2430_musb_init(struct musb *musb) * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; @@ -391,7 +391,7 @@ static int omap2430_musb_exit(struct musb *musb) cancel_work_sync(&musb->otg_notifier_work); omap2430_low_level_exit(musb); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); return 0; } diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index de1355946a83..a004736186f1 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1078,7 +1078,7 @@ static int tusb_musb_init(struct musb *musb) int ret; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) return -ENODEV; @@ -1130,7 +1130,7 @@ done: if (sync) iounmap(sync); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); } return ret; @@ -1146,7 +1146,7 @@ static int tusb_musb_exit(struct musb *musb) iounmap(musb->sync_va); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; } diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index aa09dd417b94..53006b113b12 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -37,7 +37,7 @@ struct ux500_glue { static int ux500_musb_init(struct musb *musb) { - musb->xceiv = usb_get_transceiver(); + musb->xceiv = usb_get_phy(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; @@ -48,7 +48,7 @@ static int ux500_musb_init(struct musb *musb) static int ux500_musb_exit(struct musb *musb) { - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); return 0; } diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index a84af677dc59..672e28c81437 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -529,7 +529,7 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev) if (err < 0) goto fail0; - err = usb_set_transceiver(&ab->phy); + err = usb_add_phy(&ab->phy); if (err) { dev_err(&pdev->dev, "Can't register transceiver\n"); goto fail1; @@ -556,7 +556,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev) cancel_work_sync(&ab->phy_dis_work); - usb_set_transceiver(NULL); + usb_add_phy(NULL); ab8500_usb_host_phy_dis(ab); ab8500_usb_peri_phy_dis(ab); diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index be4a63e8302f..73561edd81de 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -806,7 +806,7 @@ static int fsl_otg_conf(struct platform_device *pdev) fsl_otg_dev = fsl_otg_tc; /* Store the otg transceiver */ - status = usb_set_transceiver(&fsl_otg_tc->phy); + status = usb_add_phy(&fsl_otg_tc->phy); if (status) { pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); goto err; @@ -824,7 +824,7 @@ err: int usb_otg_start(struct platform_device *pdev) { struct fsl_otg *p_otg; - struct usb_phy *otg_trans = usb_get_transceiver(); + struct usb_phy *otg_trans = usb_get_phy(); struct otg_fsm *fsm; int status; struct resource *res; @@ -1134,7 +1134,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - usb_set_transceiver(NULL); + usb_add_phy(NULL); free_irq(fsl_otg_dev->irq, fsl_otg_dev); iounmap((void *)usb_dr_regs); diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index bde6298a9693..9b3c264cdb56 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -320,7 +320,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) } /* only active when a gadget is registered */ - err = usb_set_transceiver(&gpio_vbus->phy); + err = usb_add_phy(&gpio_vbus->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); @@ -354,7 +354,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) cancel_delayed_work_sync(&gpio_vbus->work); regulator_put(gpio_vbus->vbus_draw); - usb_set_transceiver(NULL); + usb_add_phy(NULL); free_irq(gpio_vbus->irq, pdev); if (gpio_is_valid(pdata->gpio_pullup)) diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 33cd709b084e..b74df3fec56f 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1611,7 +1611,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); #endif - status = usb_set_transceiver(&isp->phy); + status = usb_add_phy(&isp->phy); if (status < 0) dev_err(&i2c->dev, "can't register transceiver, %d\n", status); @@ -1650,7 +1650,7 @@ subsys_initcall(isp_init); static void __exit isp_exit(void) { if (the_transceiver) - usb_set_transceiver(NULL); + usb_add_phy(NULL); i2c_del_driver(&isp1301_driver); } module_exit(isp_exit); diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index 1d0347c247d1..dd606c010035 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -1555,9 +1555,9 @@ static int __init msm_otg_probe(struct platform_device *pdev) phy->otg->set_host = msm_otg_set_host; phy->otg->set_peripheral = msm_otg_set_peripheral; - ret = usb_set_transceiver(&motg->phy); + ret = usb_add_phy(&motg->phy); if (ret) { - dev_err(&pdev->dev, "usb_set_transceiver failed\n"); + dev_err(&pdev->dev, "usb_add_phy failed\n"); goto free_irq; } @@ -1624,7 +1624,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); pm_runtime_disable(&pdev->dev); - usb_set_transceiver(NULL); + usb_add_phy(NULL); free_irq(motg->irq, motg); /* diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c index 6cc6c3ffbb83..18e90fe1fbd1 100644 --- a/drivers/usb/otg/mv_otg.c +++ b/drivers/usb/otg/mv_otg.c @@ -690,7 +690,7 @@ int mv_otg_remove(struct platform_device *pdev) for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++) clk_put(mvotg->clk[clk_i]); - usb_set_transceiver(NULL); + usb_add_phy(NULL); platform_set_drvdata(pdev, NULL); kfree(mvotg->phy.otg); @@ -853,7 +853,7 @@ static int mv_otg_probe(struct platform_device *pdev) goto err_disable_clk; } - retval = usb_set_transceiver(&mvotg->phy); + retval = usb_add_phy(&mvotg->phy); if (retval < 0) { dev_err(&pdev->dev, "can't register transceiver, %d\n", retval); @@ -880,7 +880,7 @@ static int mv_otg_probe(struct platform_device *pdev) return 0; err_set_transceiver: - usb_set_transceiver(NULL); + usb_add_phy(NULL); err_free_irq: free_irq(mvotg->irq, mvotg); err_disable_clk: diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 58b26df6afd1..33000dae7200 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -117,7 +117,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; - err = usb_set_transceiver(&nop->phy); + err = usb_add_phy(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); @@ -139,7 +139,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) { struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); - usb_set_transceiver(NULL); + usb_add_phy(NULL); platform_set_drvdata(pdev, NULL); kfree(nop->phy.otg); diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 801e597a1541..300a995cfdbe 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -18,53 +18,53 @@ static struct usb_phy *phy; /** - * usb_get_transceiver - find the (single) USB transceiver + * usb_get_phy - find the (single) USB PHY * - * Returns the transceiver driver, after getting a refcount to it; or - * null if there is no such transceiver. The caller is responsible for - * calling usb_put_transceiver() to release that count. + * Returns the phy driver, after getting a refcount to it; or + * null if there is no such phy. The caller is responsible for + * calling usb_put_phy() to release that count. * * For use by USB host and peripheral drivers. */ -struct usb_phy *usb_get_transceiver(void) +struct usb_phy *usb_get_phy(void) { if (phy) get_device(phy->dev); return phy; } -EXPORT_SYMBOL(usb_get_transceiver); +EXPORT_SYMBOL(usb_get_phy); /** - * usb_put_transceiver - release the (single) USB transceiver - * @x: the transceiver returned by usb_get_transceiver() + * usb_put_phy - release the (single) USB PHY + * @x: the phy returned by usb_get_phy() * - * Releases a refcount the caller received from usb_get_transceiver(). + * Releases a refcount the caller received from usb_get_phy(). * * For use by USB host and peripheral drivers. */ -void usb_put_transceiver(struct usb_phy *x) +void usb_put_phy(struct usb_phy *x) { if (x) put_device(x->dev); } -EXPORT_SYMBOL(usb_put_transceiver); +EXPORT_SYMBOL(usb_put_phy); /** - * usb_set_transceiver - declare the (single) USB transceiver - * @x: the USB transceiver to be used; or NULL + * usb_add_phy - declare the (single) USB PHY + * @x: the USB phy to be used; or NULL * - * This call is exclusively for use by transceiver drivers, which + * This call is exclusively for use by phy drivers, which * coordinate the activities of drivers for host and peripheral * controllers, and in some cases for VBUS current regulation. */ -int usb_set_transceiver(struct usb_phy *x) +int usb_add_phy(struct usb_phy *x) { if (phy && x) return -EBUSY; phy = x; return 0; } -EXPORT_SYMBOL(usb_set_transceiver); +EXPORT_SYMBOL(usb_add_phy); const char *otg_state_string(enum usb_otg_state state) { diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 02979306bf83..01022c891e26 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -633,7 +633,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) kfree(twl); return err; } - usb_set_transceiver(&twl->phy); + usb_add_phy(&twl->phy); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index d2a9a8e691b9..a8be20878eb9 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -443,7 +443,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) kfree(twl); return err; } - usb_set_transceiver(&twl->phy); + usb_add_phy(&twl->phy); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 38ab3f46346f..0e739c810525 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -121,7 +121,7 @@ struct usb_phy { /* for board-specific init logic */ -extern int usb_set_transceiver(struct usb_phy *); +extern int usb_add_phy(struct usb_phy *); #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE)) /* sometimes transceivers are accessed only through e.g. ULPI */ @@ -172,16 +172,16 @@ usb_phy_shutdown(struct usb_phy *x) /* for usb host and peripheral controller drivers */ #ifdef CONFIG_USB_OTG_UTILS -extern struct usb_phy *usb_get_transceiver(void); -extern void usb_put_transceiver(struct usb_phy *); +extern struct usb_phy *usb_get_phy(void); +extern void usb_put_phy(struct usb_phy *); extern const char *otg_state_string(enum usb_otg_state state); #else -static inline struct usb_phy *usb_get_transceiver(void) +static inline struct usb_phy *usb_get_phy(void) { return NULL; } -static inline void usb_put_transceiver(struct usb_phy *x) +static inline void usb_put_phy(struct usb_phy *x) { } -- GitLab From 662dca54ca67c92b7aa14b9a2ec54acacf33ce45 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:02:46 +0530 Subject: [PATCH 2675/6849] usb: otg: support for multiple transceivers by a single controller Add a linked list for keeping multiple PHY instances with different types so that we can have separate USB2 and USB3 PHYs on one single board. _get_phy_ has been changed so that the controller gets the transceiver by type. _remove_phy_ has been added to let the phy be removed from the phy list. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/power/ab8500_charger.c | 2 +- drivers/power/isp1704_charger.c | 2 +- drivers/power/pda_power.c | 2 +- drivers/power/twl4030_charger.c | 2 +- drivers/usb/chipidea/udc.c | 2 +- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/mv_udc_core.c | 2 +- drivers/usb/gadget/omap_udc.c | 2 +- drivers/usb/gadget/pxa25x_udc.c | 2 +- drivers/usb/gadget/pxa27x_udc.c | 2 +- drivers/usb/gadget/s3c-hsudc.c | 2 +- drivers/usb/host/ehci-fsl.c | 2 +- drivers/usb/host/ehci-msm.c | 2 +- drivers/usb/host/ehci-mv.c | 2 +- drivers/usb/host/ehci-tegra.c | 2 +- drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/musb/am35x.c | 2 +- drivers/usb/musb/blackfin.c | 2 +- drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/davinci.c | 2 +- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/musb/omap2430.c | 2 +- drivers/usb/musb/tusb6010.c | 2 +- drivers/usb/musb/ux500.c | 2 +- drivers/usb/otg/ab8500-usb.c | 4 +- drivers/usb/otg/fsl_otg.c | 6 +- drivers/usb/otg/gpio_vbus.c | 4 +- drivers/usb/otg/isp1301_omap.c | 4 +- drivers/usb/otg/msm_otg.c | 4 +- drivers/usb/otg/mv_otg.c | 6 +- drivers/usb/otg/nop-usb-xceiv.c | 4 +- drivers/usb/otg/otg.c | 96 +++++++++++++++++++++++++++---- drivers/usb/otg/twl4030-usb.c | 2 +- drivers/usb/otg/twl6030-usb.c | 2 +- include/linux/usb/otg.h | 29 +++++++++- 35 files changed, 152 insertions(+), 57 deletions(-) diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index cf5ffc4d1048..6bd6f1c41967 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -2688,7 +2688,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev) goto free_ac; } - di->usb_phy = usb_get_phy(); + di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!di->usb_phy) { dev_err(di->dev, "failed to get usb transceiver\n"); ret = -EINVAL; diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 50773ae6f72e..090e5f9e72c9 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -415,7 +415,7 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) if (!isp) return -ENOMEM; - isp->phy = usb_get_phy(); + isp->phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!isp->phy) goto fail0; diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index e0f206b0775b..7602d49e4d81 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -321,7 +321,7 @@ static int pda_power_probe(struct platform_device *pdev) } #ifdef CONFIG_USB_OTG_UTILS - transceiver = usb_get_phy(); + transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (transceiver && !pdata->is_usb_online) { pdata->is_usb_online = otg_is_usb_online; } diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index fcddd115cc08..13f9db2e8538 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -479,7 +479,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) INIT_WORK(&bci->work, twl4030_bci_usb_work); - bci->transceiver = usb_get_phy(); + bci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (bci->transceiver != NULL) { bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; usb_register_notifier(bci->transceiver, &bci->usb_nb); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 4468f2c2dddd..a06d28b119f5 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1687,7 +1687,7 @@ static int udc_start(struct ci13xxx *udc) udc->gadget.ep0 = &udc->ep0in->ep; - udc->transceiver = usb_get_phy(); + udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) { if (udc->transceiver == NULL) { diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index d7038509b956..0808820ba495 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2455,7 +2455,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) #ifdef CONFIG_USB_OTG if (pdata->operating_mode == FSL_USB2_DR_OTG) { - udc_controller->transceiver = usb_get_phy(); + udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (!udc_controller->transceiver) { ERR("Can't find OTG driver!\n"); ret = -ENODEV; diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 5d779955d5a6..75ff41a5c959 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2180,7 +2180,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev) #ifdef CONFIG_USB_OTG_UTILS if (pdata->mode == MV_USB_MODE_OTG) - udc->transceiver = usb_get_phy(); + udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); #endif udc->clknum = pdata->clknum; diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 74b9bb8099e7..cf8bf26f12ed 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2865,7 +2865,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) * use it. Except for OTG, we don't _need_ to talk to one; * but not having one probably means no VBUS detection. */ - xceiv = usb_get_phy(); + xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (xceiv) type = xceiv->label; else if (config->otg) { diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index a658e446caba..cc0b1e63dcab 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2159,7 +2159,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev->mach = pdev->dev.platform_data; - dev->transceiver = usb_get_phy(); + dev->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (gpio_is_valid(dev->mach->gpio_pullup)) { if ((retval = gpio_request(dev->mach->gpio_pullup, diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index b982304a49c1..8f744aab9628 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2464,7 +2464,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) udc->dev = &pdev->dev; udc->mach = pdev->dev.platform_data; - udc->transceiver = usb_get_phy(); + udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); gpio = udc->mach->gpio_pullup; if (gpio_is_valid(gpio)) { diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 9ad33395f564..22326f274466 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1282,7 +1282,7 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) hsudc->dev = dev; hsudc->pd = pdev->dev.platform_data; - hsudc->transceiver = usb_get_phy(); + hsudc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 0e8976a0ed51..ba290589d858 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -142,7 +142,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, if (pdata->operating_mode == FSL_USB2_DR_OTG) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - ehci->transceiver = usb_get_phy(); + ehci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, transceiver=0x%p\n", hcd, ehci, ehci->transceiver); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 7badd5db398c..c7615fb93dbb 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -145,7 +145,7 @@ static int ehci_msm_probe(struct platform_device *pdev) * powering up VBUS, mapping of registers address space and power * management. */ - phy = usb_get_phy(); + phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!phy) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -ENODEV; diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 24f838fe25ac..ef7aa0df40a6 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -253,7 +253,7 @@ static int mv_ehci_probe(struct platform_device *pdev) ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { #ifdef CONFIG_USB_OTG_UTILS - ehci_mv->otg = usb_get_phy(); + ehci_mv->otg = usb_get_phy(USB_PHY_TYPE_USB2); if (!ehci_mv->otg) { dev_err(&pdev->dev, "unable to find transceiver\n"); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index ee17d19b1b82..14df2f5cf6ae 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -749,7 +749,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { - tegra->transceiver = usb_get_phy(); + tegra->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (tegra->transceiver) otg_set_host(tegra->transceiver->otg, &hcd->self); } diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index c2c1f55889a4..92a77dfd1930 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -211,7 +211,7 @@ static int ohci_omap_init(struct usb_hcd *hcd) #ifdef CONFIG_USB_OTG if (need_transceiver) { - ohci->transceiver = usb_get_phy(); + ohci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver->otg, &ohci_to_hcd(ohci)->self); diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index a75989bbb3d4..4a8cbf0e8d51 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -364,7 +364,7 @@ static int am35x_musb_init(struct musb *musb) return -ENODEV; usb_nop_xceiv_register(); - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) return -ENODEV; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 522a4a263df8..452940986d6d 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -415,7 +415,7 @@ static int bfin_musb_init(struct musb *musb) gpio_direction_output(musb->config->gpio_vrsel, 0); usb_nop_xceiv_register(); - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) { gpio_free(musb->config->gpio_vrsel); return -ENODEV; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 61868d604b28..d731c80c4fef 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -425,7 +425,7 @@ static int da8xx_musb_init(struct musb *musb) goto fail; usb_nop_xceiv_register(); - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) goto fail; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 441f776366f3..582268de3fa2 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -384,7 +384,7 @@ static int davinci_musb_init(struct musb *musb) u32 revision; usb_nop_xceiv_register(); - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) goto unregister; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 716c113608f4..92603e498e61 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -376,7 +376,7 @@ static int dsps_musb_init(struct musb *musb) /* NOP driver needs change if supporting dual instance */ usb_nop_xceiv_register(); - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) return -ENODEV; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index e16dbbf7f305..e279cf32772e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -292,7 +292,7 @@ static int omap2430_musb_init(struct musb *musb) * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index a004736186f1..8ddf3d5f7cdc 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1078,7 +1078,7 @@ static int tusb_musb_init(struct musb *musb) int ret; usb_nop_xceiv_register(); - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) return -ENODEV; diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 53006b113b12..46cf80a8cacd 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -37,7 +37,7 @@ struct ux500_glue { static int ux500_musb_init(struct musb *musb) { - musb->xceiv = usb_get_phy(); + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index 672e28c81437..ae8ad561f083 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -529,7 +529,7 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev) if (err < 0) goto fail0; - err = usb_add_phy(&ab->phy); + err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "Can't register transceiver\n"); goto fail1; @@ -556,7 +556,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev) cancel_work_sync(&ab->phy_dis_work); - usb_add_phy(NULL); + usb_remove_phy(&ab->phy); ab8500_usb_host_phy_dis(ab); ab8500_usb_peri_phy_dis(ab); diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 73561edd81de..23c798cb2d7f 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -806,7 +806,7 @@ static int fsl_otg_conf(struct platform_device *pdev) fsl_otg_dev = fsl_otg_tc; /* Store the otg transceiver */ - status = usb_add_phy(&fsl_otg_tc->phy); + status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); if (status) { pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); goto err; @@ -824,7 +824,7 @@ err: int usb_otg_start(struct platform_device *pdev) { struct fsl_otg *p_otg; - struct usb_phy *otg_trans = usb_get_phy(); + struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); struct otg_fsm *fsm; int status; struct resource *res; @@ -1134,7 +1134,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - usb_add_phy(NULL); + usb_remove_phy(&fsl_otg_dev->phy); free_irq(fsl_otg_dev->irq, fsl_otg_dev); iounmap((void *)usb_dr_regs); diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 9b3c264cdb56..a67ffe22179a 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -320,7 +320,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) } /* only active when a gadget is registered */ - err = usb_add_phy(&gpio_vbus->phy); + err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); @@ -354,7 +354,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) cancel_delayed_work_sync(&gpio_vbus->work); regulator_put(gpio_vbus->vbus_draw); - usb_add_phy(NULL); + usb_remove_phy(&gpio_vbus->phy); free_irq(gpio_vbus->irq, pdev); if (gpio_is_valid(pdata->gpio_pullup)) diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index b74df3fec56f..75cea4ab0985 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1611,7 +1611,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); #endif - status = usb_add_phy(&isp->phy); + status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); if (status < 0) dev_err(&i2c->dev, "can't register transceiver, %d\n", status); @@ -1650,7 +1650,7 @@ subsys_initcall(isp_init); static void __exit isp_exit(void) { if (the_transceiver) - usb_add_phy(NULL); + usb_remove_phy(&the_transceiver->phy); i2c_del_driver(&isp1301_driver); } module_exit(isp_exit); diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index dd606c010035..9f5fc906041a 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -1555,7 +1555,7 @@ static int __init msm_otg_probe(struct platform_device *pdev) phy->otg->set_host = msm_otg_set_host; phy->otg->set_peripheral = msm_otg_set_peripheral; - ret = usb_add_phy(&motg->phy); + ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); if (ret) { dev_err(&pdev->dev, "usb_add_phy failed\n"); goto free_irq; @@ -1624,7 +1624,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); pm_runtime_disable(&pdev->dev); - usb_add_phy(NULL); + usb_remove_phy(phy); free_irq(motg->irq, motg); /* diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c index 18e90fe1fbd1..3f124e8f5792 100644 --- a/drivers/usb/otg/mv_otg.c +++ b/drivers/usb/otg/mv_otg.c @@ -690,7 +690,7 @@ int mv_otg_remove(struct platform_device *pdev) for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++) clk_put(mvotg->clk[clk_i]); - usb_add_phy(NULL); + usb_remove_phy(&mvotg->phy); platform_set_drvdata(pdev, NULL); kfree(mvotg->phy.otg); @@ -853,7 +853,7 @@ static int mv_otg_probe(struct platform_device *pdev) goto err_disable_clk; } - retval = usb_add_phy(&mvotg->phy); + retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2); if (retval < 0) { dev_err(&pdev->dev, "can't register transceiver, %d\n", retval); @@ -880,7 +880,7 @@ static int mv_otg_probe(struct platform_device *pdev) return 0; err_set_transceiver: - usb_add_phy(NULL); + usb_remove_phy(&mvotg->phy); err_free_irq: free_irq(mvotg->irq, mvotg); err_disable_clk: diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 33000dae7200..803f958f4133 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -117,7 +117,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; - err = usb_add_phy(&nop->phy); + err = usb_add_phy(&nop->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); @@ -139,7 +139,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) { struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); - usb_add_phy(NULL); + usb_remove_phy(&nop->phy); platform_set_drvdata(pdev, NULL); kfree(nop->phy.otg); diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 300a995cfdbe..a23065820ead 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -11,14 +11,32 @@ #include #include +#include #include #include -static struct usb_phy *phy; +static LIST_HEAD(phy_list); +static DEFINE_SPINLOCK(phy_lock); + +static struct usb_phy *__usb_find_phy(struct list_head *list, + enum usb_phy_type type) +{ + struct usb_phy *phy = NULL; + + list_for_each_entry(phy, list, head) { + if (phy->type != type) + continue; + + return phy; + } + + return ERR_PTR(-ENODEV); +} /** - * usb_get_phy - find the (single) USB PHY + * usb_get_phy - find the USB PHY + * @type - the type of the phy the controller requires * * Returns the phy driver, after getting a refcount to it; or * null if there is no such phy. The caller is responsible for @@ -26,16 +44,30 @@ static struct usb_phy *phy; * * For use by USB host and peripheral drivers. */ -struct usb_phy *usb_get_phy(void) +struct usb_phy *usb_get_phy(enum usb_phy_type type) { - if (phy) - get_device(phy->dev); + struct usb_phy *phy = NULL; + unsigned long flags; + + spin_lock_irqsave(&phy_lock, flags); + + phy = __usb_find_phy(&phy_list, type); + if (IS_ERR(phy)) { + pr_err("unable to find transceiver of type %s\n", + usb_phy_type_string(type)); + return phy; + } + + get_device(phy->dev); + + spin_unlock_irqrestore(&phy_lock, flags); + return phy; } EXPORT_SYMBOL(usb_get_phy); /** - * usb_put_phy - release the (single) USB PHY + * usb_put_phy - release the USB PHY * @x: the phy returned by usb_get_phy() * * Releases a refcount the caller received from usb_get_phy(). @@ -50,22 +82,62 @@ void usb_put_phy(struct usb_phy *x) EXPORT_SYMBOL(usb_put_phy); /** - * usb_add_phy - declare the (single) USB PHY + * usb_add_phy - declare the USB PHY * @x: the USB phy to be used; or NULL + * @type - the type of this PHY * * This call is exclusively for use by phy drivers, which * coordinate the activities of drivers for host and peripheral * controllers, and in some cases for VBUS current regulation. */ -int usb_add_phy(struct usb_phy *x) +int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) { - if (phy && x) - return -EBUSY; - phy = x; - return 0; + int ret = 0; + unsigned long flags; + struct usb_phy *phy; + + if (x && x->type != USB_PHY_TYPE_UNDEFINED) { + dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); + return -EINVAL; + } + + spin_lock_irqsave(&phy_lock, flags); + + list_for_each_entry(phy, &phy_list, head) { + if (phy->type == type) { + ret = -EBUSY; + dev_err(x->dev, "transceiver type %s already exists\n", + usb_phy_type_string(type)); + goto out; + } + } + + x->type = type; + list_add_tail(&x->head, &phy_list); + +out: + spin_unlock_irqrestore(&phy_lock, flags); + return ret; } EXPORT_SYMBOL(usb_add_phy); +/** + * usb_remove_phy - remove the OTG PHY + * @x: the USB OTG PHY to be removed; + * + * This reverts the effects of usb_add_phy + */ +void usb_remove_phy(struct usb_phy *x) +{ + unsigned long flags; + + spin_lock_irqsave(&phy_lock, flags); + if (x) + list_del(&x->head); + spin_unlock_irqrestore(&phy_lock, flags); +} +EXPORT_SYMBOL(usb_remove_phy); + const char *otg_state_string(enum usb_otg_state state) { switch (state) { diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 01022c891e26..25a09fabbe35 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -633,7 +633,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) kfree(twl); return err; } - usb_add_phy(&twl->phy); + usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index a8be20878eb9..dbee00aea755 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -443,7 +443,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) kfree(twl); return err; } - usb_add_phy(&twl->phy); + usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 0e739c810525..1def65fb57d0 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -43,6 +43,13 @@ enum usb_phy_events { USB_EVENT_ENUMERATED, /* gadget driver enumerated */ }; +/* associate a type with PHY */ +enum usb_phy_type { + USB_PHY_TYPE_UNDEFINED, + USB_PHY_TYPE_USB2, + USB_PHY_TYPE_USB3, +}; + struct usb_phy; /* for transceivers connected thru an ULPI interface, the user must @@ -89,6 +96,7 @@ struct usb_phy { const char *label; unsigned int flags; + enum usb_phy_type type; enum usb_otg_state state; enum usb_phy_events last_event; @@ -105,6 +113,9 @@ struct usb_phy { u16 port_status; u16 port_change; + /* to support controllers that have multiple transceivers */ + struct list_head head; + /* initialize/shutdown the OTG controller */ int (*init)(struct usb_phy *x); void (*shutdown)(struct usb_phy *x); @@ -121,7 +132,8 @@ struct usb_phy { /* for board-specific init logic */ -extern int usb_add_phy(struct usb_phy *); +extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type); +extern void usb_remove_phy(struct usb_phy *); #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE)) /* sometimes transceivers are accessed only through e.g. ULPI */ @@ -172,11 +184,11 @@ usb_phy_shutdown(struct usb_phy *x) /* for usb host and peripheral controller drivers */ #ifdef CONFIG_USB_OTG_UTILS -extern struct usb_phy *usb_get_phy(void); +extern struct usb_phy *usb_get_phy(enum usb_phy_type type); extern void usb_put_phy(struct usb_phy *); extern const char *otg_state_string(enum usb_otg_state state); #else -static inline struct usb_phy *usb_get_phy(void) +static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) { return NULL; } @@ -276,4 +288,15 @@ usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb) /* for OTG controller drivers (and maybe other stuff) */ extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); +static inline const char *usb_phy_type_string(enum usb_phy_type type) +{ + switch (type) { + case USB_PHY_TYPE_USB2: + return "USB2 PHY"; + case USB_PHY_TYPE_USB3: + return "USB3 PHY"; + default: + return "UNKNOWN PHY TYPE"; + } +} #endif /* __LINUX_USB_OTG_H */ -- GitLab From 410219dcd2ba8d8b4bcfa9c232f35bf505bc021a Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:02:47 +0530 Subject: [PATCH 2676/6849] usb: otg: utils: devres: Add API's to associate a device with the phy Used devres API's to associate the phy with a device so that on driver detach, release function is invoked on the devres data(usb_phy) and devres data(usb_phy) is released. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/otg/otg.c | 62 +++++++++++++++++++++++++++++++++++++++++ include/linux/usb/otg.h | 13 +++++++++ 2 files changed, 75 insertions(+) diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index a23065820ead..0fa4d8c1b1e8 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -34,6 +35,48 @@ static struct usb_phy *__usb_find_phy(struct list_head *list, return ERR_PTR(-ENODEV); } +static void devm_usb_phy_release(struct device *dev, void *res) +{ + struct usb_phy *phy = *(struct usb_phy **)res; + + usb_put_phy(phy); +} + +static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) +{ + return res == match_data; +} + +/** + * devm_usb_get_phy - find the USB PHY + * @dev - device that requests this phy + * @type - the type of the phy the controller requires + * + * Gets the phy using usb_get_phy(), and associates a device with it using + * devres. On driver detach, release function is invoked on the devres data, + * then, devres data is freed. + * + * For use by USB host and peripheral drivers. + */ +struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) +{ + struct usb_phy **ptr, *phy; + + ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + phy = usb_get_phy(type); + if (phy) { + *ptr = phy; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return phy; +} +EXPORT_SYMBOL(devm_usb_get_phy); + /** * usb_get_phy - find the USB PHY * @type - the type of the phy the controller requires @@ -66,6 +109,25 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type) } EXPORT_SYMBOL(usb_get_phy); +/** + * devm_usb_put_phy - release the USB PHY + * @dev - device that wants to release this phy + * @phy - the phy returned by devm_usb_get_phy() + * + * destroys the devres associated with this phy and invokes usb_put_phy + * to release the phy. + * + * For use by USB host and peripheral drivers. + */ +void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) +{ + int r; + + r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); + dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); +} +EXPORT_SYMBOL(devm_usb_put_phy); + /** * usb_put_phy - release the USB PHY * @x: the phy returned by usb_get_phy() diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 1def65fb57d0..0cb2ec2e50c0 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -185,7 +185,10 @@ usb_phy_shutdown(struct usb_phy *x) /* for usb host and peripheral controller drivers */ #ifdef CONFIG_USB_OTG_UTILS extern struct usb_phy *usb_get_phy(enum usb_phy_type type); +extern struct usb_phy *devm_usb_get_phy(struct device *dev, + enum usb_phy_type type); extern void usb_put_phy(struct usb_phy *); +extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); extern const char *otg_state_string(enum usb_otg_state state); #else static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) @@ -193,10 +196,20 @@ static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) return NULL; } +static inline struct usb_phy *devm_usb_get_phy(struct device *dev, + enum usb_phy_type type) +{ + return NULL; +} + static inline void usb_put_phy(struct usb_phy *x) { } +static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x) +{ +} + static inline const char *otg_state_string(enum usb_otg_state state) { return NULL; -- GitLab From 1e5acb8d6113a0f159257845e153d5b870ca618a Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:40:51 +0530 Subject: [PATCH 2677/6849] usb: musb: move work_struct(otg_notifier_work) from core to omap glue Commit 712d8e(fixes pm_runtime calls while atomic by using a work queue. musb pm_runtime_get_sync call happens in interrupt context on cable attach case. That can result in re-enabling the interrupts and cause side affect. To avoid this deferred processing is used) While the issue and the work queue implementation is specific to omap (omap2430.c), the work_struct is defined as a member of struct musb (musb_core.h). Hence moved the work_struct from musb_core to omap glue. Cc: Vikram Pandita Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 2 -- drivers/usb/musb/omap2430.c | 24 +++++++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index f4a40f001c88..dbcdeea30f09 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -327,7 +327,6 @@ struct musb { irqreturn_t (*isr)(int, void *); struct work_struct irq_work; - struct work_struct otg_notifier_work; u16 hwvers; /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ @@ -373,7 +372,6 @@ struct musb { u16 int_tx; struct usb_phy *xceiv; - u8 xceiv_event; int nIrq; unsigned irq_wake:1; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index e279cf32772e..f40c8053a291 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -41,6 +41,8 @@ struct omap2430_glue { struct device *dev; struct platform_device *musb; + u8 xceiv_event; + struct work_struct omap_musb_mailbox_work; }; #define glue_to_musb(g) platform_get_drvdata(g->musb) @@ -226,22 +228,26 @@ static inline void omap2430_low_level_init(struct musb *musb) static int musb_otg_notifications(struct notifier_block *nb, unsigned long event, void *unused) { - struct musb *musb = container_of(nb, struct musb, nb); + struct musb *musb = container_of(nb, struct musb, nb); + struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); - musb->xceiv_event = event; - schedule_work(&musb->otg_notifier_work); + glue->xceiv_event = event; + schedule_work(&glue->omap_musb_mailbox_work); return NOTIFY_OK; } -static void musb_otg_notifier_work(struct work_struct *data_notifier_work) +static void omap_musb_mailbox_work(struct work_struct *data_notifier_work) { - struct musb *musb = container_of(data_notifier_work, struct musb, otg_notifier_work); + struct omap2430_glue *glue = container_of(data_notifier_work, + struct omap2430_glue, omap_musb_mailbox_work); + struct musb *musb = glue_to_musb(glue); struct device *dev = musb->controller; struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; - switch (musb->xceiv_event) { + switch (glue->xceiv_event) { case USB_EVENT_ID: dev_dbg(musb->controller, "ID GND\n"); @@ -298,8 +304,6 @@ static int omap2430_musb_init(struct musb *musb) return -ENODEV; } - INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work); - status = pm_runtime_get_sync(dev); if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); @@ -388,7 +392,6 @@ static void omap2430_musb_disable(struct musb *musb) static int omap2430_musb_exit(struct musb *musb) { del_timer_sync(&musb_idle_timer); - cancel_work_sync(&musb->otg_notifier_work); omap2430_low_level_exit(musb); usb_put_phy(musb->xceiv); @@ -441,6 +444,8 @@ static int __devinit omap2430_probe(struct platform_device *pdev) platform_set_drvdata(pdev, glue); + INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work); + ret = platform_device_add_resources(musb, pdev->resource, pdev->num_resources); if (ret) { @@ -478,6 +483,7 @@ static int __devexit omap2430_remove(struct platform_device *pdev) { struct omap2430_glue *glue = platform_get_drvdata(pdev); + cancel_work_sync(&glue->omap_musb_mailbox_work); platform_device_del(glue->musb); platform_device_put(glue->musb); kfree(glue); -- GitLab From c9721438c009adf8e81d376839ed037c53b9b8d9 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:40:52 +0530 Subject: [PATCH 2678/6849] usb: musb: twl: use mailbox API to send VBUS or ID events The atomic notifier from twl4030/twl6030 to notifiy VBUS and ID events, is replaced by a direct call to omap musb blue. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 94 ++++++++++++++++++++++------------- drivers/usb/otg/twl4030-usb.c | 46 ++++++++--------- drivers/usb/otg/twl6030-usb.c | 47 ++++++++---------- include/linux/usb/musb-omap.h | 30 +++++++++++ 4 files changed, 133 insertions(+), 84 deletions(-) create mode 100644 include/linux/usb/musb-omap.h diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index f40c8053a291..063687085d1e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "musb_core.h" #include "omap2430.h" @@ -41,11 +42,13 @@ struct omap2430_glue { struct device *dev; struct platform_device *musb; - u8 xceiv_event; + enum omap_musb_vbus_id_status status; struct work_struct omap_musb_mailbox_work; }; #define glue_to_musb(g) platform_get_drvdata(g->musb) +struct omap2430_glue *_glue; + static struct timer_list musb_idle_timer; static void musb_do_idle(unsigned long _musb) @@ -225,54 +228,58 @@ static inline void omap2430_low_level_init(struct musb *musb) musb_writel(musb->mregs, OTG_FORCESTDBY, l); } -static int musb_otg_notifications(struct notifier_block *nb, - unsigned long event, void *unused) +void omap_musb_mailbox(enum omap_musb_vbus_id_status status) { - struct musb *musb = container_of(nb, struct musb, nb); - struct device *dev = musb->controller; - struct omap2430_glue *glue = dev_get_drvdata(dev->parent); + struct omap2430_glue *glue = _glue; + struct musb *musb = glue_to_musb(glue); - glue->xceiv_event = event; - schedule_work(&glue->omap_musb_mailbox_work); + glue->status = status; + if (!musb) { + dev_err(glue->dev, "musb core is not yet ready\n"); + return; + } - return NOTIFY_OK; + schedule_work(&glue->omap_musb_mailbox_work); } +EXPORT_SYMBOL_GPL(omap_musb_mailbox); -static void omap_musb_mailbox_work(struct work_struct *data_notifier_work) +static void omap_musb_set_mailbox(struct omap2430_glue *glue) { - struct omap2430_glue *glue = container_of(data_notifier_work, - struct omap2430_glue, omap_musb_mailbox_work); struct musb *musb = glue_to_musb(glue); struct device *dev = musb->controller; struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; - switch (glue->xceiv_event) { - case USB_EVENT_ID: - dev_dbg(musb->controller, "ID GND\n"); + switch (glue->status) { + case OMAP_MUSB_ID_GROUND: + dev_dbg(dev, "ID GND\n"); + musb->xceiv->last_event = USB_EVENT_ID; if (!is_otg_enabled(musb) || musb->gadget_driver) { - pm_runtime_get_sync(musb->controller); + pm_runtime_get_sync(dev); usb_phy_init(musb->xceiv); omap2430_musb_set_vbus(musb, 1); } break; - case USB_EVENT_VBUS: - dev_dbg(musb->controller, "VBUS Connect\n"); + case OMAP_MUSB_VBUS_VALID: + dev_dbg(dev, "VBUS Connect\n"); + musb->xceiv->last_event = USB_EVENT_VBUS; if (musb->gadget_driver) - pm_runtime_get_sync(musb->controller); + pm_runtime_get_sync(dev); usb_phy_init(musb->xceiv); break; - case USB_EVENT_NONE: - dev_dbg(musb->controller, "VBUS Disconnect\n"); + case OMAP_MUSB_ID_FLOAT: + case OMAP_MUSB_VBUS_OFF: + dev_dbg(dev, "VBUS Disconnect\n"); + musb->xceiv->last_event = USB_EVENT_NONE; if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) if (musb->gadget_driver) { - pm_runtime_mark_last_busy(musb->controller); - pm_runtime_put_autosuspend(musb->controller); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } if (data->interface_type == MUSB_INTERFACE_UTMI) { @@ -282,15 +289,24 @@ static void omap_musb_mailbox_work(struct work_struct *data_notifier_work) usb_phy_shutdown(musb->xceiv); break; default: - dev_dbg(musb->controller, "ID float\n"); + dev_dbg(dev, "ID float\n"); } } + +static void omap_musb_mailbox_work(struct work_struct *mailbox_work) +{ + struct omap2430_glue *glue = container_of(mailbox_work, + struct omap2430_glue, omap_musb_mailbox_work); + omap_musb_set_mailbox(glue); +} + static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -330,14 +346,11 @@ static int omap2430_musb_init(struct musb *musb) musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); - musb->nb.notifier_call = musb_otg_notifications; - status = usb_register_notifier(musb->xceiv, &musb->nb); - - if (status) - dev_dbg(musb->controller, "notification register failed\n"); - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); + if (glue->status != OMAP_MUSB_UNKNOWN) + omap_musb_set_mailbox(glue); + pm_runtime_put_noidle(musb->controller); return 0; @@ -350,12 +363,13 @@ static void omap2430_musb_enable(struct musb *musb) u8 devctl; unsigned long timeout = jiffies + msecs_to_jiffies(1000); struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; - switch (musb->xceiv->last_event) { + switch (glue->status) { - case USB_EVENT_ID: + case OMAP_MUSB_ID_GROUND: usb_phy_init(musb->xceiv); if (data->interface_type != MUSB_INTERFACE_UTMI) break; @@ -374,7 +388,7 @@ static void omap2430_musb_enable(struct musb *musb) } break; - case USB_EVENT_VBUS: + case OMAP_MUSB_VBUS_VALID: usb_phy_init(musb->xceiv); break; @@ -385,7 +399,10 @@ static void omap2430_musb_enable(struct musb *musb) static void omap2430_musb_disable(struct musb *musb) { - if (musb->xceiv->last_event) + struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); + + if (glue->status != OMAP_MUSB_UNKNOWN) usb_phy_shutdown(musb->xceiv); } @@ -439,11 +456,18 @@ static int __devinit omap2430_probe(struct platform_device *pdev) glue->dev = &pdev->dev; glue->musb = musb; + glue->status = OMAP_MUSB_UNKNOWN; pdata->platform_ops = &omap2430_ops; platform_set_drvdata(pdev, glue); + /* + * REVISIT if we ever have two instances of the wrapper, we will be + * in big trouble + */ + _glue = glue; + INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work); ret = platform_device_add_resources(musb, pdev->resource, @@ -552,7 +576,7 @@ static int __init omap2430_init(void) { return platform_driver_register(&omap2430_driver); } -module_init(omap2430_init); +subsys_initcall(omap2430_init); static void __exit omap2430_exit(void) { diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 25a09fabbe35..a7b809e217ea 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -33,11 +33,11 @@ #include #include #include +#include #include #include #include #include -#include #include /* Register defines */ @@ -159,7 +159,7 @@ struct twl4030_usb { enum twl4030_usb_mode usb_mode; int irq; - u8 linkstat; + enum omap_musb_vbus_id_status linkstat; bool vbus_supplied; u8 asleep; bool irq_enabled; @@ -246,10 +246,11 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) /*-------------------------------------------------------------------------*/ -static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl) +static enum omap_musb_vbus_id_status + twl4030_usb_linkstat(struct twl4030_usb *twl) { int status; - int linkstat = USB_EVENT_NONE; + enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; struct usb_otg *otg = twl->phy.otg; twl->vbus_supplied = false; @@ -273,24 +274,24 @@ static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl) twl->vbus_supplied = true; if (status & BIT(2)) - linkstat = USB_EVENT_ID; + linkstat = OMAP_MUSB_ID_GROUND; else - linkstat = USB_EVENT_VBUS; - } else - linkstat = USB_EVENT_NONE; + linkstat = OMAP_MUSB_VBUS_VALID; + } else { + if (twl->linkstat != OMAP_MUSB_UNKNOWN) + linkstat = OMAP_MUSB_VBUS_OFF; + } dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", status, status, linkstat); - twl->phy.last_event = linkstat; - /* REVISIT this assumes host and peripheral controllers * are registered, and that both are active... */ spin_lock_irq(&twl->lock); twl->linkstat = linkstat; - if (linkstat == USB_EVENT_ID) { + if (linkstat == OMAP_MUSB_ID_GROUND) { otg->default_a = true; twl->phy.state = OTG_STATE_A_IDLE; } else { @@ -501,10 +502,10 @@ static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; - int status; + enum omap_musb_vbus_id_status status; status = twl4030_usb_linkstat(twl); - if (status >= 0) { + if (status > 0) { /* FIXME add a set_power() method so that B-devices can * configure the charger appropriately. It's not always * correct to consume VBUS power, and how much current to @@ -516,13 +517,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) * USB_LINK_VBUS state. musb_hdrc won't care until it * starts to handle softconnect right. */ - if (status == USB_EVENT_NONE) + if (status == OMAP_MUSB_VBUS_OFF || + status == OMAP_MUSB_ID_FLOAT) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); - atomic_notifier_call_chain(&twl->phy.notifier, status, - twl->phy.otg->gadget); + omap_musb_mailbox(twl->linkstat); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); @@ -531,11 +532,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) static void twl4030_usb_phy_init(struct twl4030_usb *twl) { - int status; + enum omap_musb_vbus_id_status status; status = twl4030_usb_linkstat(twl); - if (status >= 0) { - if (status == USB_EVENT_NONE) { + if (status > 0) { + if (status == OMAP_MUSB_VBUS_OFF || + status == OMAP_MUSB_ID_FLOAT) { __twl4030_phy_power(twl, 0); twl->asleep = 1; } else { @@ -543,8 +545,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl) twl->asleep = 0; } - atomic_notifier_call_chain(&twl->phy.notifier, status, - twl->phy.otg->gadget); + omap_musb_mailbox(twl->linkstat); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); } @@ -613,6 +614,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) twl->usb_mode = pdata->usb_mode; twl->vbus_supplied = false; twl->asleep = 1; + twl->linkstat = OMAP_MUSB_UNKNOWN; twl->phy.dev = twl->dev; twl->phy.label = "twl4030"; @@ -639,8 +641,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); - ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); - /* Our job is to use irqs and status from the power module * to keep the transceiver disabled when nothing's connected. * diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index dbee00aea755..6c758836cfb1 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -26,10 +26,10 @@ #include #include #include +#include #include #include #include -#include #include #include @@ -100,7 +100,7 @@ struct twl6030_usb { int irq1; int irq2; - u8 linkstat; + enum omap_musb_vbus_id_status linkstat; u8 asleep; bool irq_enabled; bool vbus_enable; @@ -147,7 +147,7 @@ static int twl6030_phy_init(struct usb_phy *x) dev = twl->dev; pdata = dev->platform_data; - if (twl->linkstat == USB_EVENT_ID) + if (twl->linkstat == OMAP_MUSB_ID_GROUND) pdata->phy_power(twl->dev, 1, 1); else pdata->phy_power(twl->dev, 0, 1); @@ -235,13 +235,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev, spin_lock_irqsave(&twl->lock, flags); switch (twl->linkstat) { - case USB_EVENT_VBUS: + case OMAP_MUSB_VBUS_VALID: ret = snprintf(buf, PAGE_SIZE, "vbus\n"); break; - case USB_EVENT_ID: + case OMAP_MUSB_ID_GROUND: ret = snprintf(buf, PAGE_SIZE, "id\n"); break; - case USB_EVENT_NONE: + case OMAP_MUSB_VBUS_OFF: ret = snprintf(buf, PAGE_SIZE, "none\n"); break; default: @@ -257,7 +257,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; struct usb_otg *otg = twl->phy.otg; - int status; + enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; u8 vbus_state, hw_state; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); @@ -268,22 +268,20 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) if (vbus_state & VBUS_DET) { regulator_enable(twl->usb3v3); twl->asleep = 1; - status = USB_EVENT_VBUS; + status = OMAP_MUSB_VBUS_VALID; otg->default_a = false; twl->phy.state = OTG_STATE_B_IDLE; twl->linkstat = status; - twl->phy.last_event = status; - atomic_notifier_call_chain(&twl->phy.notifier, - status, otg->gadget); + omap_musb_mailbox(status); } else { - status = USB_EVENT_NONE; - twl->linkstat = status; - twl->phy.last_event = status; - atomic_notifier_call_chain(&twl->phy.notifier, - status, otg->gadget); - if (twl->asleep) { - regulator_disable(twl->usb3v3); - twl->asleep = 0; + if (twl->linkstat != OMAP_MUSB_UNKNOWN) { + status = OMAP_MUSB_VBUS_OFF; + twl->linkstat = status; + omap_musb_mailbox(status); + if (twl->asleep) { + regulator_disable(twl->usb3v3); + twl->asleep = 0; + } } } } @@ -296,7 +294,7 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; struct usb_otg *otg = twl->phy.otg; - int status = USB_EVENT_NONE; + enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; u8 hw_state; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); @@ -308,13 +306,11 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x10); - status = USB_EVENT_ID; + status = OMAP_MUSB_ID_GROUND; otg->default_a = true; twl->phy.state = OTG_STATE_A_IDLE; twl->linkstat = status; - twl->phy.last_event = status; - atomic_notifier_call_chain(&twl->phy.notifier, status, - otg->gadget); + omap_musb_mailbox(status); } else { twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x10); @@ -419,6 +415,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); twl->features = pdata->features; + twl->linkstat = OMAP_MUSB_UNKNOWN; twl->phy.dev = twl->dev; twl->phy.label = "twl6030"; @@ -449,8 +446,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); - ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); - INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); twl->irq_enabled = true; diff --git a/include/linux/usb/musb-omap.h b/include/linux/usb/musb-omap.h new file mode 100644 index 000000000000..7774c5986f07 --- /dev/null +++ b/include/linux/usb/musb-omap.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011-2012 by Texas Instruments + * + * The Inventra Controller Driver for Linux is free software; you + * can redistribute it and/or modify it under the terms of the GNU + * General Public License version 2 as published by the Free Software + * Foundation. + */ + +#ifndef __MUSB_OMAP_H__ +#define __MUSB_OMAP_H__ + +enum omap_musb_vbus_id_status { + OMAP_MUSB_UNKNOWN = 0, + OMAP_MUSB_ID_GROUND, + OMAP_MUSB_ID_FLOAT, + OMAP_MUSB_VBUS_VALID, + OMAP_MUSB_VBUS_OFF, +}; + +#if (defined(CONFIG_USB_MUSB_OMAP2PLUS) || \ + defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE)) +void omap_musb_mailbox(enum omap_musb_vbus_id_status status); +#else +static inline void omap_musb_mailbox(enum omap_musb_vbus_id_status status) +{ +} +#endif + +#endif /* __MUSB_OMAP_H__ */ -- GitLab From c83a8542b5e3c5b30825955a68b1cc8bd24b122a Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:40:53 +0530 Subject: [PATCH 2679/6849] usb: musb: move otg specific initializations from twl to glue Moved otg specific state(OTG_STATE_B_IDLE, OTG_STATE_A_IDLE) initializations from twl to glue. These initializations are removed from twl4030 and twl6030 and moved to the mailbox API defined in glue. This is part of the cleanup in preparation to make use of usb2 phy driver. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 5 +++++ drivers/usb/otg/twl4030-usb.c | 8 -------- drivers/usb/otg/twl6030-usb.c | 6 ------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 063687085d1e..c4dc92bd7e85 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -249,11 +249,14 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) struct device *dev = musb->controller; struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; + struct usb_otg *otg = musb->xceiv->otg; switch (glue->status) { case OMAP_MUSB_ID_GROUND: dev_dbg(dev, "ID GND\n"); + otg->default_a = true; + musb->xceiv->state = OTG_STATE_A_IDLE; musb->xceiv->last_event = USB_EVENT_ID; if (!is_otg_enabled(musb) || musb->gadget_driver) { pm_runtime_get_sync(dev); @@ -265,6 +268,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) case OMAP_MUSB_VBUS_VALID: dev_dbg(dev, "VBUS Connect\n"); + otg->default_a = false; + musb->xceiv->state = OTG_STATE_B_IDLE; musb->xceiv->last_event = USB_EVENT_VBUS; if (musb->gadget_driver) pm_runtime_get_sync(dev); diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index a7b809e217ea..4d0d98bc40cd 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -251,7 +251,6 @@ static enum omap_musb_vbus_id_status { int status; enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; - struct usb_otg *otg = twl->phy.otg; twl->vbus_supplied = false; @@ -291,13 +290,6 @@ static enum omap_musb_vbus_id_status spin_lock_irq(&twl->lock); twl->linkstat = linkstat; - if (linkstat == OMAP_MUSB_ID_GROUND) { - otg->default_a = true; - twl->phy.state = OTG_STATE_A_IDLE; - } else { - otg->default_a = false; - twl->phy.state = OTG_STATE_B_IDLE; - } spin_unlock_irq(&twl->lock); return linkstat; diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 6c758836cfb1..66cfea735557 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -256,7 +256,6 @@ static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); static irqreturn_t twl6030_usb_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; - struct usb_otg *otg = twl->phy.otg; enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; u8 vbus_state, hw_state; @@ -269,8 +268,6 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) regulator_enable(twl->usb3v3); twl->asleep = 1; status = OMAP_MUSB_VBUS_VALID; - otg->default_a = false; - twl->phy.state = OTG_STATE_B_IDLE; twl->linkstat = status; omap_musb_mailbox(status); } else { @@ -293,7 +290,6 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; - struct usb_otg *otg = twl->phy.otg; enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; u8 hw_state; @@ -307,8 +303,6 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x10); status = OMAP_MUSB_ID_GROUND; - otg->default_a = true; - twl->phy.state = OTG_STATE_A_IDLE; twl->linkstat = status; omap_musb_mailbox(status); } else { -- GitLab From b1183c242a60764afbdfaf39396405b7afa1106c Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:40:54 +0530 Subject: [PATCH 2680/6849] usb: musb: omap: use devres API to allocate resources used devres API while allocating memory resource and while getting usb phy so that these resources are released automatically on driver detach. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c4dc92bd7e85..2813490ba631 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -319,7 +319,7 @@ static int omap2430_musb_init(struct musb *musb) * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ - musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; @@ -416,7 +416,6 @@ static int omap2430_musb_exit(struct musb *musb) del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); - usb_put_phy(musb->xceiv); return 0; } @@ -443,7 +442,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev) struct omap2430_glue *glue; int ret = -ENOMEM; - glue = kzalloc(sizeof(*glue), GFP_KERNEL); + glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(&pdev->dev, "failed to allocate glue context\n"); goto err0; @@ -452,7 +451,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev) musb = platform_device_alloc("musb-hdrc", -1); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err1; + goto err0; } musb->dev.parent = &pdev->dev; @@ -479,13 +478,13 @@ static int __devinit omap2430_probe(struct platform_device *pdev) pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err1; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err1; } pm_runtime_enable(&pdev->dev); @@ -493,16 +492,13 @@ static int __devinit omap2430_probe(struct platform_device *pdev) ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err2; + goto err1; } return 0; -err2: - platform_device_put(musb); - err1: - kfree(glue); + platform_device_put(musb); err0: return ret; @@ -515,7 +511,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev) cancel_work_sync(&glue->omap_musb_mailbox_work); platform_device_del(glue->musb); platform_device_put(glue->musb); - kfree(glue); return 0; } -- GitLab From b8a3efa3a363720687d21228d6b23b988a223bbb Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 22 Jun 2012 17:40:55 +0530 Subject: [PATCH 2681/6849] usb: otg: twl: use devres API to allocate resources used devres API while allocating memory resource in twl4030 and twl6030 so that these resources are released automatically on driver detach. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl4030-usb.c | 15 +++------------ drivers/usb/otg/twl6030-usb.c | 16 +++------------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 4d0d98bc40cd..523cad5bfea9 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -591,15 +591,13 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) return -EINVAL; } - twl = kzalloc(sizeof *twl, GFP_KERNEL); + twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; - otg = kzalloc(sizeof *otg, GFP_KERNEL); - if (!otg) { - kfree(twl); + otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); + if (!otg) return -ENOMEM; - } twl->dev = &pdev->dev; twl->irq = platform_get_irq(pdev, 0); @@ -623,8 +621,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) err = twl4030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); - kfree(otg); - kfree(twl); return err; } usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); @@ -648,8 +644,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); - kfree(otg); - kfree(twl); return status; } @@ -693,9 +687,6 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) regulator_put(twl->usb1v8); regulator_put(twl->usb3v1); - kfree(twl->phy.otg); - kfree(twl); - return 0; } diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 66cfea735557..600c27a42ff1 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -395,15 +395,13 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; pdata = dev->platform_data; - twl = kzalloc(sizeof *twl, GFP_KERNEL); + twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; - otg = kzalloc(sizeof *otg, GFP_KERNEL); - if (!otg) { - kfree(twl); + otg = devm_kzalloc(dev, sizeof *otg, GFP_KERNEL); + if (!otg) return -ENOMEM; - } twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); @@ -430,8 +428,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) err = twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); - kfree(otg); - kfree(twl); return err; } usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); @@ -450,8 +446,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq1, status); device_remove_file(twl->dev, &dev_attr_vbus); - kfree(otg); - kfree(twl); return status; } @@ -463,8 +457,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) twl->irq2, status); free_irq(twl->irq1, twl); device_remove_file(twl->dev, &dev_attr_vbus); - kfree(otg); - kfree(twl); return status; } @@ -495,8 +487,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev) pdata->phy_exit(twl->dev); device_remove_file(twl->dev, &dev_attr_vbus); cancel_work_sync(&twl->set_vbus_work); - kfree(twl->phy.otg); - kfree(twl); return 0; } -- GitLab From 31bde1ceaa873bcaecd49e829bfabceacc4c512d Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sun, 24 Jun 2012 21:11:22 -0700 Subject: [PATCH 2682/6849] usb: gadget: Fix g_ether interface link status A "usb0" interface that has never been connected to a host has an unknown operstate, and therefore the IFF_RUNNING flag is (incorrectly) asserted when queried by ifconfig, ifplugd, etc. This is a result of calling netif_carrier_off() too early in the probe function; it should be called after register_netdev(). Similar problems have been fixed in many other drivers, e.g.: e826eafa6 (bonding: Call netif_carrier_off after register_netdevice) 0d672e9f8 (drivers/net: Call netif_carrier_off at the end of the probe) 6a3c869a6 (cxgb4: fix reported state of interfaces without link) Fix is to move netif_carrier_off() to the end of the function. Cc: stable@vger.kernel.org Signed-off-by: Kevin Cernekee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/u_ether.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 47cf48b51c9d..5b46f022d0f0 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -798,12 +798,6 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], SET_ETHTOOL_OPS(net, &ops); - /* two kinds of host-initiated state changes: - * - iff DATA transfer is active, carrier is "on" - * - tx queueing enabled if open *and* carrier is "on" - */ - netif_carrier_off(net); - dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); @@ -817,6 +811,12 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; + + /* two kinds of host-initiated state changes: + * - iff DATA transfer is active, carrier is "on" + * - tx queueing enabled if open *and* carrier is "on" + */ + netif_carrier_off(net); } return status; -- GitLab From ac1534a55d1e87d59a21c09c570605933b551480 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 21 Jun 2012 14:52:40 +0200 Subject: [PATCH 2683/6849] iommu/amd: Initialize dma_ops for hotplug and sriov devices When a device is added to the system at runtime the AMD IOMMU driver initializes the necessary data structures to handle translation for it. But it forgets to change the per-device dma_ops to point to the AMD IOMMU driver. So mapping actually never happens and all DMA accesses end in an IO_PAGE_FAULT. Fix this. Reported-by: Stefan Assmann Cc: stable@vger.kernel.org Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a2e418cba0ff..dfe7d37c82c5 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -83,6 +83,8 @@ static struct iommu_ops amd_iommu_ops; static ATOMIC_NOTIFIER_HEAD(ppr_notifier); int amd_iommu_max_glx_val = -1; +static struct dma_map_ops amd_iommu_dma_ops; + /* * general struct to manage commands send to an IOMMU */ @@ -2267,6 +2269,13 @@ static int device_change_notifier(struct notifier_block *nb, list_add_tail(&dma_domain->list, &iommu_pd_list); spin_unlock_irqrestore(&iommu_pd_list_lock, flags); + dev_data = get_dev_data(dev); + + if (!dev_data->passthrough) + dev->archdata.dma_ops = &amd_iommu_dma_ops; + else + dev->archdata.dma_ops = &nommu_dma_ops; + break; case BUS_NOTIFY_DEL_DEVICE: -- GitLab From 74416e1e07660798379ce10a210bf4fd35b84f9f Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:18:41 -0600 Subject: [PATCH 2684/6849] driver core: Add iommu_group tracking to struct device IOMMU groups allow IOMMU drivers to represent DMA visibility and isolation of devices. Multiple devices may be grouped together for the purposes of DMA. Placing a pointer on struct device enable easy access for things like streaming DMA programming and drivers like VFIO. Signed-off-by: Alex Williamson Acked-by: Greg Kroah-Hartman Acked-by: Benjamin Herrenschmidt Signed-off-by: Joerg Roedel --- include/linux/device.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 161d96241b1b..d0e4d99405ae 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -36,6 +36,7 @@ struct subsys_private; struct bus_type; struct device_node; struct iommu_ops; +struct iommu_group; struct bus_attribute { struct attribute attr; @@ -687,6 +688,7 @@ struct device { const struct attribute_group **groups; /* optional groups */ void (*release)(struct device *dev); + struct iommu_group *iommu_group; }; /* Get the wakeup routines, which depend on struct device */ -- GitLab From d72e31c9374627068df29da8085ca18c92ae35d3 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:18:53 -0600 Subject: [PATCH 2685/6849] iommu: IOMMU Groups IOMMU device groups are currently a rather vague associative notion with assembly required by the user or user level driver provider to do anything useful. This patch intends to grow the IOMMU group concept into something a bit more consumable. To do this, we first create an object representing the group, struct iommu_group. This structure is allocated (iommu_group_alloc) and filled (iommu_group_add_device) by the iommu driver. The iommu driver is free to add devices to the group using it's own set of policies. This allows inclusion of devices based on physical hardware or topology limitations of the platform, as well as soft requirements, such as multi-function trust levels or peer-to-peer protection of the interconnects. Each device may only belong to a single iommu group, which is linked from struct device.iommu_group. IOMMU groups are maintained using kobject reference counting, allowing for automatic removal of empty, unreferenced groups. It is the responsibility of the iommu driver to remove devices from the group (iommu_group_remove_device). IOMMU groups also include a userspace representation in sysfs under /sys/kernel/iommu_groups. When allocated, each group is given a dynamically assign ID (int). The ID is managed by the core IOMMU group code to support multiple heterogeneous iommu drivers, which could potentially collide in group naming/numbering. This also keeps group IDs to small, easily managed values. A directory is created under /sys/kernel/iommu_groups for each group. A further subdirectory named "devices" contains links to each device within the group. The iommu_group file in the device's sysfs directory, which formerly contained a group number when read, is now a link to the iommu group. Example: $ ls -l /sys/kernel/iommu_groups/26/devices/ total 0 lrwxrwxrwx. 1 root root 0 Apr 17 12:57 0000:00:1e.0 -> ../../../../devices/pci0000:00/0000:00:1e.0 lrwxrwxrwx. 1 root root 0 Apr 17 12:57 0000:06:0d.0 -> ../../../../devices/pci0000:00/0000:00:1e.0/0000:06:0d.0 lrwxrwxrwx. 1 root root 0 Apr 17 12:57 0000:06:0d.1 -> ../../../../devices/pci0000:00/0000:00:1e.0/0000:06:0d.1 $ ls -l /sys/kernel/iommu_groups/26/devices/*/iommu_group [truncating perms/owner/timestamp] /sys/kernel/iommu_groups/26/devices/0000:00:1e.0/iommu_group -> ../../../kernel/iommu_groups/26 /sys/kernel/iommu_groups/26/devices/0000:06:0d.0/iommu_group -> ../../../../kernel/iommu_groups/26 /sys/kernel/iommu_groups/26/devices/0000:06:0d.1/iommu_group -> ../../../../kernel/iommu_groups/26 Groups also include several exported functions for use by user level driver providers, for example VFIO. These include: iommu_group_get(): Acquires a reference to a group from a device iommu_group_put(): Releases reference iommu_group_for_each_dev(): Iterates over group devices using callback iommu_group_[un]register_notifier(): Allows notification of device add and remove operations relevant to the group iommu_group_id(): Return the group number This patch also extends the IOMMU API to allow attaching groups to domains. This is currently a simple wrapper for iterating through devices within a group, but it's expected that the IOMMU API may eventually make groups a more integral part of domains. Groups intentionally do not try to manage group ownership. A user level driver provider must independently acquire ownership for each device within a group before making use of the group as a whole. This may change in the future if group usage becomes more pervasive across both DMA and IOMMU ops. Groups intentionally do not provide a mechanism for driver locking or otherwise manipulating driver matching/probing of devices within the group. Such interfaces are generic to devices and beyond the scope of IOMMU groups. If implemented, user level providers have ready access via iommu_group_for_each_dev and group notifiers. iommu_device_group() is removed here as it has no users. The replacement is: group = iommu_group_get(dev); id = iommu_group_id(group); iommu_group_put(group); AMD-Vi & Intel VT-d support re-added in following patches. Signed-off-by: Alex Williamson Acked-by: Benjamin Herrenschmidt Signed-off-by: Joerg Roedel --- .../ABI/testing/sysfs-kernel-iommu_groups | 14 + drivers/iommu/amd_iommu.c | 21 - drivers/iommu/intel-iommu.c | 49 -- drivers/iommu/iommu.c | 578 +++++++++++++++++- include/linux/iommu.h | 104 +++- 5 files changed, 663 insertions(+), 103 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-kernel-iommu_groups diff --git a/Documentation/ABI/testing/sysfs-kernel-iommu_groups b/Documentation/ABI/testing/sysfs-kernel-iommu_groups new file mode 100644 index 000000000000..9b31556cfdda --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-iommu_groups @@ -0,0 +1,14 @@ +What: /sys/kernel/iommu_groups/ +Date: May 2012 +KernelVersion: v3.5 +Contact: Alex Williamson +Description: /sys/kernel/iommu_groups/ contains a number of sub- + directories, each representing an IOMMU group. The + name of the sub-directory matches the iommu_group_id() + for the group, which is an integer value. Within each + subdirectory is another directory named "devices" with + links to the sysfs devices contained in this group. + The group directory also optionally contains a "name" + file if the IOMMU driver has chosen to register a more + common name for the group. +Users: diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a2e418cba0ff..55283d6291c8 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -3227,26 +3227,6 @@ static int amd_iommu_domain_has_cap(struct iommu_domain *domain, return 0; } -static int amd_iommu_device_group(struct device *dev, unsigned int *groupid) -{ - struct iommu_dev_data *dev_data = dev->archdata.iommu; - struct pci_dev *pdev = to_pci_dev(dev); - u16 devid; - - if (!dev_data) - return -ENODEV; - - if (pdev->is_virtfn || !iommu_group_mf) - devid = dev_data->devid; - else - devid = calc_devid(pdev->bus->number, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); - - *groupid = amd_iommu_alias_table[devid]; - - return 0; -} - static struct iommu_ops amd_iommu_ops = { .domain_init = amd_iommu_domain_init, .domain_destroy = amd_iommu_domain_destroy, @@ -3256,7 +3236,6 @@ static struct iommu_ops amd_iommu_ops = { .unmap = amd_iommu_unmap, .iova_to_phys = amd_iommu_iova_to_phys, .domain_has_cap = amd_iommu_domain_has_cap, - .device_group = amd_iommu_device_group, .pgsize_bitmap = AMD_IOMMU_PGSIZES, }; diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index b12af2ff8c54..c62f2df25221 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4090,54 +4090,6 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain, return 0; } -/* - * Group numbers are arbitrary. Device with the same group number - * indicate the iommu cannot differentiate between them. To avoid - * tracking used groups we just use the seg|bus|devfn of the lowest - * level we're able to differentiate devices - */ -static int intel_iommu_device_group(struct device *dev, unsigned int *groupid) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct pci_dev *bridge; - union { - struct { - u8 devfn; - u8 bus; - u16 segment; - } pci; - u32 group; - } id; - - if (iommu_no_mapping(dev)) - return -ENODEV; - - id.pci.segment = pci_domain_nr(pdev->bus); - id.pci.bus = pdev->bus->number; - id.pci.devfn = pdev->devfn; - - if (!device_to_iommu(id.pci.segment, id.pci.bus, id.pci.devfn)) - return -ENODEV; - - bridge = pci_find_upstream_pcie_bridge(pdev); - if (bridge) { - if (pci_is_pcie(bridge)) { - id.pci.bus = bridge->subordinate->number; - id.pci.devfn = 0; - } else { - id.pci.bus = bridge->bus->number; - id.pci.devfn = bridge->devfn; - } - } - - if (!pdev->is_virtfn && iommu_group_mf) - id.pci.devfn = PCI_DEVFN(PCI_SLOT(id.pci.devfn), 0); - - *groupid = id.group; - - return 0; -} - static struct iommu_ops intel_iommu_ops = { .domain_init = intel_iommu_domain_init, .domain_destroy = intel_iommu_domain_destroy, @@ -4147,7 +4099,6 @@ static struct iommu_ops intel_iommu_ops = { .unmap = intel_iommu_unmap, .iova_to_phys = intel_iommu_iova_to_phys, .domain_has_cap = intel_iommu_domain_has_cap, - .device_group = intel_iommu_device_group, .pgsize_bitmap = INTEL_IOMMU_PGSIZES, }; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 8b9ded88e6f5..0e928acd7dcf 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -26,60 +26,535 @@ #include #include #include +#include +#include +#include + +static struct kset *iommu_group_kset; +static struct ida iommu_group_ida; +static struct mutex iommu_group_mutex; + +struct iommu_group { + struct kobject kobj; + struct kobject *devices_kobj; + struct list_head devices; + struct mutex mutex; + struct blocking_notifier_head notifier; + void *iommu_data; + void (*iommu_data_release)(void *iommu_data); + char *name; + int id; +}; + +struct iommu_device { + struct list_head list; + struct device *dev; + char *name; +}; + +struct iommu_group_attribute { + struct attribute attr; + ssize_t (*show)(struct iommu_group *group, char *buf); + ssize_t (*store)(struct iommu_group *group, + const char *buf, size_t count); +}; + +#define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \ +struct iommu_group_attribute iommu_group_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) -static ssize_t show_iommu_group(struct device *dev, - struct device_attribute *attr, char *buf) +#define to_iommu_group_attr(_attr) \ + container_of(_attr, struct iommu_group_attribute, attr) +#define to_iommu_group(_kobj) \ + container_of(_kobj, struct iommu_group, kobj) + +static ssize_t iommu_group_attr_show(struct kobject *kobj, + struct attribute *__attr, char *buf) { - unsigned int groupid; + struct iommu_group_attribute *attr = to_iommu_group_attr(__attr); + struct iommu_group *group = to_iommu_group(kobj); + ssize_t ret = -EIO; - if (iommu_device_group(dev, &groupid)) - return 0; + if (attr->show) + ret = attr->show(group, buf); + return ret; +} + +static ssize_t iommu_group_attr_store(struct kobject *kobj, + struct attribute *__attr, + const char *buf, size_t count) +{ + struct iommu_group_attribute *attr = to_iommu_group_attr(__attr); + struct iommu_group *group = to_iommu_group(kobj); + ssize_t ret = -EIO; - return sprintf(buf, "%u", groupid); + if (attr->store) + ret = attr->store(group, buf, count); + return ret; } -static DEVICE_ATTR(iommu_group, S_IRUGO, show_iommu_group, NULL); -static int add_iommu_group(struct device *dev, void *data) +static const struct sysfs_ops iommu_group_sysfs_ops = { + .show = iommu_group_attr_show, + .store = iommu_group_attr_store, +}; + +static int iommu_group_create_file(struct iommu_group *group, + struct iommu_group_attribute *attr) +{ + return sysfs_create_file(&group->kobj, &attr->attr); +} + +static void iommu_group_remove_file(struct iommu_group *group, + struct iommu_group_attribute *attr) +{ + sysfs_remove_file(&group->kobj, &attr->attr); +} + +static ssize_t iommu_group_show_name(struct iommu_group *group, char *buf) +{ + return sprintf(buf, "%s\n", group->name); +} + +static IOMMU_GROUP_ATTR(name, S_IRUGO, iommu_group_show_name, NULL); + +static void iommu_group_release(struct kobject *kobj) +{ + struct iommu_group *group = to_iommu_group(kobj); + + if (group->iommu_data_release) + group->iommu_data_release(group->iommu_data); + + mutex_lock(&iommu_group_mutex); + ida_remove(&iommu_group_ida, group->id); + mutex_unlock(&iommu_group_mutex); + + kfree(group->name); + kfree(group); +} + +static struct kobj_type iommu_group_ktype = { + .sysfs_ops = &iommu_group_sysfs_ops, + .release = iommu_group_release, +}; + +/** + * iommu_group_alloc - Allocate a new group + * @name: Optional name to associate with group, visible in sysfs + * + * This function is called by an iommu driver to allocate a new iommu + * group. The iommu group represents the minimum granularity of the iommu. + * Upon successful return, the caller holds a reference to the supplied + * group in order to hold the group until devices are added. Use + * iommu_group_put() to release this extra reference count, allowing the + * group to be automatically reclaimed once it has no devices or external + * references. + */ +struct iommu_group *iommu_group_alloc(void) { - unsigned int groupid; + struct iommu_group *group; + int ret; + + group = kzalloc(sizeof(*group), GFP_KERNEL); + if (!group) + return ERR_PTR(-ENOMEM); + + group->kobj.kset = iommu_group_kset; + mutex_init(&group->mutex); + INIT_LIST_HEAD(&group->devices); + BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier); + + mutex_lock(&iommu_group_mutex); + +again: + if (unlikely(0 == ida_pre_get(&iommu_group_ida, GFP_KERNEL))) { + kfree(group); + mutex_unlock(&iommu_group_mutex); + return ERR_PTR(-ENOMEM); + } + + if (-EAGAIN == ida_get_new(&iommu_group_ida, &group->id)) + goto again; + + mutex_unlock(&iommu_group_mutex); - if (iommu_device_group(dev, &groupid) == 0) - return device_create_file(dev, &dev_attr_iommu_group); + ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype, + NULL, "%d", group->id); + if (ret) { + mutex_lock(&iommu_group_mutex); + ida_remove(&iommu_group_ida, group->id); + mutex_unlock(&iommu_group_mutex); + kfree(group); + return ERR_PTR(ret); + } + + group->devices_kobj = kobject_create_and_add("devices", &group->kobj); + if (!group->devices_kobj) { + kobject_put(&group->kobj); /* triggers .release & free */ + return ERR_PTR(-ENOMEM); + } + + /* + * The devices_kobj holds a reference on the group kobject, so + * as long as that exists so will the group. We can therefore + * use the devices_kobj for reference counting. + */ + kobject_put(&group->kobj); + + return group; +} +EXPORT_SYMBOL_GPL(iommu_group_alloc); + +/** + * iommu_group_get_iommudata - retrieve iommu_data registered for a group + * @group: the group + * + * iommu drivers can store data in the group for use when doing iommu + * operations. This function provides a way to retrieve it. Caller + * should hold a group reference. + */ +void *iommu_group_get_iommudata(struct iommu_group *group) +{ + return group->iommu_data; +} +EXPORT_SYMBOL_GPL(iommu_group_get_iommudata); + +/** + * iommu_group_set_iommudata - set iommu_data for a group + * @group: the group + * @iommu_data: new data + * @release: release function for iommu_data + * + * iommu drivers can store data in the group for use when doing iommu + * operations. This function provides a way to set the data after + * the group has been allocated. Caller should hold a group reference. + */ +void iommu_group_set_iommudata(struct iommu_group *group, void *iommu_data, + void (*release)(void *iommu_data)) +{ + group->iommu_data = iommu_data; + group->iommu_data_release = release; +} +EXPORT_SYMBOL_GPL(iommu_group_set_iommudata); + +/** + * iommu_group_set_name - set name for a group + * @group: the group + * @name: name + * + * Allow iommu driver to set a name for a group. When set it will + * appear in a name attribute file under the group in sysfs. + */ +int iommu_group_set_name(struct iommu_group *group, const char *name) +{ + int ret; + + if (group->name) { + iommu_group_remove_file(group, &iommu_group_attr_name); + kfree(group->name); + group->name = NULL; + if (!name) + return 0; + } + + group->name = kstrdup(name, GFP_KERNEL); + if (!group->name) + return -ENOMEM; + + ret = iommu_group_create_file(group, &iommu_group_attr_name); + if (ret) { + kfree(group->name); + group->name = NULL; + return ret; + } return 0; } +EXPORT_SYMBOL_GPL(iommu_group_set_name); -static int remove_iommu_group(struct device *dev) +/** + * iommu_group_add_device - add a device to an iommu group + * @group: the group into which to add the device (reference should be held) + * @dev: the device + * + * This function is called by an iommu driver to add a device into a + * group. Adding a device increments the group reference count. + */ +int iommu_group_add_device(struct iommu_group *group, struct device *dev) { - unsigned int groupid; + int ret, i = 0; + struct iommu_device *device; + + device = kzalloc(sizeof(*device), GFP_KERNEL); + if (!device) + return -ENOMEM; + + device->dev = dev; - if (iommu_device_group(dev, &groupid) == 0) - device_remove_file(dev, &dev_attr_iommu_group); + ret = sysfs_create_link(&dev->kobj, &group->kobj, "iommu_group"); + if (ret) { + kfree(device); + return ret; + } + + device->name = kasprintf(GFP_KERNEL, "%s", kobject_name(&dev->kobj)); +rename: + if (!device->name) { + sysfs_remove_link(&dev->kobj, "iommu_group"); + kfree(device); + return -ENOMEM; + } + ret = sysfs_create_link_nowarn(group->devices_kobj, + &dev->kobj, device->name); + if (ret) { + kfree(device->name); + if (ret == -EEXIST && i >= 0) { + /* + * Account for the slim chance of collision + * and append an instance to the name. + */ + device->name = kasprintf(GFP_KERNEL, "%s.%d", + kobject_name(&dev->kobj), i++); + goto rename; + } + + sysfs_remove_link(&dev->kobj, "iommu_group"); + kfree(device); + return ret; + } + + kobject_get(group->devices_kobj); + + dev->iommu_group = group; + + mutex_lock(&group->mutex); + list_add_tail(&device->list, &group->devices); + mutex_unlock(&group->mutex); + + /* Notify any listeners about change to group. */ + blocking_notifier_call_chain(&group->notifier, + IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev); return 0; } +EXPORT_SYMBOL_GPL(iommu_group_add_device); -static int iommu_device_notifier(struct notifier_block *nb, - unsigned long action, void *data) +/** + * iommu_group_remove_device - remove a device from it's current group + * @dev: device to be removed + * + * This function is called by an iommu driver to remove the device from + * it's current group. This decrements the iommu group reference count. + */ +void iommu_group_remove_device(struct device *dev) +{ + struct iommu_group *group = dev->iommu_group; + struct iommu_device *tmp_device, *device = NULL; + + /* Pre-notify listeners that a device is being removed. */ + blocking_notifier_call_chain(&group->notifier, + IOMMU_GROUP_NOTIFY_DEL_DEVICE, dev); + + mutex_lock(&group->mutex); + list_for_each_entry(tmp_device, &group->devices, list) { + if (tmp_device->dev == dev) { + device = tmp_device; + list_del(&device->list); + break; + } + } + mutex_unlock(&group->mutex); + + if (!device) + return; + + sysfs_remove_link(group->devices_kobj, device->name); + sysfs_remove_link(&dev->kobj, "iommu_group"); + + kfree(device->name); + kfree(device); + dev->iommu_group = NULL; + kobject_put(group->devices_kobj); +} +EXPORT_SYMBOL_GPL(iommu_group_remove_device); + +/** + * iommu_group_for_each_dev - iterate over each device in the group + * @group: the group + * @data: caller opaque data to be passed to callback function + * @fn: caller supplied callback function + * + * This function is called by group users to iterate over group devices. + * Callers should hold a reference count to the group during callback. + * The group->mutex is held across callbacks, which will block calls to + * iommu_group_add/remove_device. + */ +int iommu_group_for_each_dev(struct iommu_group *group, void *data, + int (*fn)(struct device *, void *)) +{ + struct iommu_device *device; + int ret = 0; + + mutex_lock(&group->mutex); + list_for_each_entry(device, &group->devices, list) { + ret = fn(device->dev, data); + if (ret) + break; + } + mutex_unlock(&group->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(iommu_group_for_each_dev); + +/** + * iommu_group_get - Return the group for a device and increment reference + * @dev: get the group that this device belongs to + * + * This function is called by iommu drivers and users to get the group + * for the specified device. If found, the group is returned and the group + * reference in incremented, else NULL. + */ +struct iommu_group *iommu_group_get(struct device *dev) +{ + struct iommu_group *group = dev->iommu_group; + + if (group) + kobject_get(group->devices_kobj); + + return group; +} +EXPORT_SYMBOL_GPL(iommu_group_get); + +/** + * iommu_group_put - Decrement group reference + * @group: the group to use + * + * This function is called by iommu drivers and users to release the + * iommu group. Once the reference count is zero, the group is released. + */ +void iommu_group_put(struct iommu_group *group) +{ + if (group) + kobject_put(group->devices_kobj); +} +EXPORT_SYMBOL_GPL(iommu_group_put); + +/** + * iommu_group_register_notifier - Register a notifier for group changes + * @group: the group to watch + * @nb: notifier block to signal + * + * This function allows iommu group users to track changes in a group. + * See include/linux/iommu.h for actions sent via this notifier. Caller + * should hold a reference to the group throughout notifier registration. + */ +int iommu_group_register_notifier(struct iommu_group *group, + struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&group->notifier, nb); +} +EXPORT_SYMBOL_GPL(iommu_group_register_notifier); + +/** + * iommu_group_unregister_notifier - Unregister a notifier + * @group: the group to watch + * @nb: notifier block to signal + * + * Unregister a previously registered group notifier block. + */ +int iommu_group_unregister_notifier(struct iommu_group *group, + struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&group->notifier, nb); +} +EXPORT_SYMBOL_GPL(iommu_group_unregister_notifier); + +/** + * iommu_group_id - Return ID for a group + * @group: the group to ID + * + * Return the unique ID for the group matching the sysfs group number. + */ +int iommu_group_id(struct iommu_group *group) +{ + return group->id; +} +EXPORT_SYMBOL_GPL(iommu_group_id); + +static int add_iommu_group(struct device *dev, void *data) +{ + struct iommu_ops *ops = data; + + if (!ops->add_device) + return -ENODEV; + + WARN_ON(dev->iommu_group); + + ops->add_device(dev); + + return 0; +} + +static int iommu_bus_notifier(struct notifier_block *nb, + unsigned long action, void *data) { struct device *dev = data; + struct iommu_ops *ops = dev->bus->iommu_ops; + struct iommu_group *group; + unsigned long group_action = 0; + + /* + * ADD/DEL call into iommu driver ops if provided, which may + * result in ADD/DEL notifiers to group->notifier + */ + if (action == BUS_NOTIFY_ADD_DEVICE) { + if (ops->add_device) + return ops->add_device(dev); + } else if (action == BUS_NOTIFY_DEL_DEVICE) { + if (ops->remove_device && dev->iommu_group) { + ops->remove_device(dev); + return 0; + } + } - if (action == BUS_NOTIFY_ADD_DEVICE) - return add_iommu_group(dev, NULL); - else if (action == BUS_NOTIFY_DEL_DEVICE) - return remove_iommu_group(dev); + /* + * Remaining BUS_NOTIFYs get filtered and republished to the + * group, if anyone is listening + */ + group = iommu_group_get(dev); + if (!group) + return 0; + switch (action) { + case BUS_NOTIFY_BIND_DRIVER: + group_action = IOMMU_GROUP_NOTIFY_BIND_DRIVER; + break; + case BUS_NOTIFY_BOUND_DRIVER: + group_action = IOMMU_GROUP_NOTIFY_BOUND_DRIVER; + break; + case BUS_NOTIFY_UNBIND_DRIVER: + group_action = IOMMU_GROUP_NOTIFY_UNBIND_DRIVER; + break; + case BUS_NOTIFY_UNBOUND_DRIVER: + group_action = IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER; + break; + } + + if (group_action) + blocking_notifier_call_chain(&group->notifier, + group_action, dev); + + iommu_group_put(group); return 0; } -static struct notifier_block iommu_device_nb = { - .notifier_call = iommu_device_notifier, +static struct notifier_block iommu_bus_nb = { + .notifier_call = iommu_bus_notifier, }; static void iommu_bus_init(struct bus_type *bus, struct iommu_ops *ops) { - bus_register_notifier(bus, &iommu_device_nb); - bus_for_each_dev(bus, NULL, NULL, add_iommu_group); + bus_register_notifier(bus, &iommu_bus_nb); + bus_for_each_dev(bus, NULL, ops, add_iommu_group); } /** @@ -192,6 +667,45 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev) } EXPORT_SYMBOL_GPL(iommu_detach_device); +/* + * IOMMU groups are really the natrual working unit of the IOMMU, but + * the IOMMU API works on domains and devices. Bridge that gap by + * iterating over the devices in a group. Ideally we'd have a single + * device which represents the requestor ID of the group, but we also + * allow IOMMU drivers to create policy defined minimum sets, where + * the physical hardware may be able to distiguish members, but we + * wish to group them at a higher level (ex. untrusted multi-function + * PCI devices). Thus we attach each device. + */ +static int iommu_group_do_attach_device(struct device *dev, void *data) +{ + struct iommu_domain *domain = data; + + return iommu_attach_device(domain, dev); +} + +int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) +{ + return iommu_group_for_each_dev(group, domain, + iommu_group_do_attach_device); +} +EXPORT_SYMBOL_GPL(iommu_attach_group); + +static int iommu_group_do_detach_device(struct device *dev, void *data) +{ + struct iommu_domain *domain = data; + + iommu_detach_device(domain, dev); + + return 0; +} + +void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group) +{ + iommu_group_for_each_dev(group, domain, iommu_group_do_detach_device); +} +EXPORT_SYMBOL_GPL(iommu_detach_group); + phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, unsigned long iova) { @@ -336,11 +850,15 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) } EXPORT_SYMBOL_GPL(iommu_unmap); -int iommu_device_group(struct device *dev, unsigned int *groupid) +static int __init iommu_init(void) { - if (iommu_present(dev->bus) && dev->bus->iommu_ops->device_group) - return dev->bus->iommu_ops->device_group(dev, groupid); + iommu_group_kset = kset_create_and_add("iommu_groups", + NULL, kernel_kobj); + ida_init(&iommu_group_ida); + mutex_init(&iommu_group_mutex); - return -ENODEV; + BUG_ON(!iommu_group_kset); + + return 0; } -EXPORT_SYMBOL_GPL(iommu_device_group); +subsys_initcall(iommu_init); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 450293f6d68b..a71df92be992 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -26,6 +26,7 @@ #define IOMMU_CACHE (4) /* DMA cache coherency */ struct iommu_ops; +struct iommu_group; struct bus_type; struct device; struct iommu_domain; @@ -60,6 +61,8 @@ struct iommu_domain { * @iova_to_phys: translate iova to physical address * @domain_has_cap: domain capabilities query * @commit: commit iommu domain + * @add_device: add device to iommu grouping + * @remove_device: remove device from iommu grouping * @pgsize_bitmap: bitmap of supported page sizes */ struct iommu_ops { @@ -75,10 +78,18 @@ struct iommu_ops { unsigned long iova); int (*domain_has_cap)(struct iommu_domain *domain, unsigned long cap); - int (*device_group)(struct device *dev, unsigned int *groupid); + int (*add_device)(struct device *dev); + void (*remove_device)(struct device *dev); unsigned long pgsize_bitmap; }; +#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */ +#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */ +#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3 /* Pre Driver bind */ +#define IOMMU_GROUP_NOTIFY_BOUND_DRIVER 4 /* Post Driver bind */ +#define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER 5 /* Pre Driver unbind */ +#define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */ + extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); extern bool iommu_present(struct bus_type *bus); extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); @@ -97,7 +108,29 @@ extern int iommu_domain_has_cap(struct iommu_domain *domain, unsigned long cap); extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); -extern int iommu_device_group(struct device *dev, unsigned int *groupid); + +extern int iommu_attach_group(struct iommu_domain *domain, + struct iommu_group *group); +extern void iommu_detach_group(struct iommu_domain *domain, + struct iommu_group *group); +extern struct iommu_group *iommu_group_alloc(void); +extern void *iommu_group_get_iommudata(struct iommu_group *group); +extern void iommu_group_set_iommudata(struct iommu_group *group, + void *iommu_data, + void (*release)(void *iommu_data)); +extern int iommu_group_set_name(struct iommu_group *group, const char *name); +extern int iommu_group_add_device(struct iommu_group *group, + struct device *dev); +extern void iommu_group_remove_device(struct device *dev); +extern int iommu_group_for_each_dev(struct iommu_group *group, void *data, + int (*fn)(struct device *, void *)); +extern struct iommu_group *iommu_group_get(struct device *dev); +extern void iommu_group_put(struct iommu_group *group); +extern int iommu_group_register_notifier(struct iommu_group *group, + struct notifier_block *nb); +extern int iommu_group_unregister_notifier(struct iommu_group *group, + struct notifier_block *nb); +extern int iommu_group_id(struct iommu_group *group); /** * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework @@ -142,6 +175,7 @@ static inline int report_iommu_fault(struct iommu_domain *domain, #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; +struct iommu_group {}; static inline bool iommu_present(struct bus_type *bus) { @@ -197,11 +231,75 @@ static inline void iommu_set_fault_handler(struct iommu_domain *domain, { } -static inline int iommu_device_group(struct device *dev, unsigned int *groupid) +int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) +{ + return -ENODEV; +} + +void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group) +{ +} + +struct iommu_group *iommu_group_alloc(void) +{ + return ERR_PTR(-ENODEV); +} + +void *iommu_group_get_iommudata(struct iommu_group *group) +{ + return NULL; +} + +void iommu_group_set_iommudata(struct iommu_group *group, void *iommu_data, + void (*release)(void *iommu_data)) +{ +} + +int iommu_group_set_name(struct iommu_group *group, const char *name) +{ + return -ENODEV; +} + +int iommu_group_add_device(struct iommu_group *group, struct device *dev) +{ + return -ENODEV; +} + +void iommu_group_remove_device(struct device *dev) +{ +} + +int iommu_group_for_each_dev(struct iommu_group *group, void *data, + int (*fn)(struct device *, void *)) +{ + return -ENODEV; +} + +struct iommu_group *iommu_group_get(struct device *dev) +{ + return NULL; +} + +void iommu_group_put(struct iommu_group *group) +{ +} + +int iommu_group_register_notifier(struct iommu_group *group, + struct notifier_block *nb) { return -ENODEV; } +int iommu_group_unregister_notifier(struct iommu_group *group, + struct notifier_block *nb) +{ + return 0; +} + +int iommu_group_id(struct iommu_group *group) +{ + return -ENODEV; +} #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */ -- GitLab From 9dcd61303af862c279df86aa97fde7ce371be774 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:19:07 -0600 Subject: [PATCH 2686/6849] amd_iommu: Support IOMMU groups Add IOMMU group support to AMD-Vi device init and uninit code. Existing notifiers make sure this gets called for each device. Signed-off-by: Alex Williamson Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 55283d6291c8..60ea92065d31 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -256,9 +256,11 @@ static bool check_device(struct device *dev) static int iommu_init_device(struct device *dev) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev); struct iommu_dev_data *dev_data; + struct iommu_group *group; u16 alias; + int ret; if (dev->archdata.iommu) return 0; @@ -279,8 +281,26 @@ static int iommu_init_device(struct device *dev) return -ENOTSUPP; } dev_data->alias_data = alias_data; + + dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff); + } else + dma_pdev = pci_dev_get(pdev); + + group = iommu_group_get(&dma_pdev->dev); + pci_dev_put(dma_pdev); + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return PTR_ERR(group); } + ret = iommu_group_add_device(group, dev); + + iommu_group_put(group); + + if (ret) + return ret; + if (pci_iommuv2_capable(pdev)) { struct amd_iommu *iommu; @@ -309,6 +329,8 @@ static void iommu_ignore_device(struct device *dev) static void iommu_uninit_device(struct device *dev) { + iommu_group_remove_device(dev); + /* * Nothing to do here - we keep dev_data around for unplugged devices * and reuse it when the device is re-plugged - not doing so would -- GitLab From abdfdde2534c48d7a761fc437ad3d840a5947dbc Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:19:19 -0600 Subject: [PATCH 2687/6849] intel-iommu: Support IOMMU groups Add IOMMU group support to Intel VT-d code. This driver sets up devices ondemand, so make use of the add_device/remove_device callbacks in IOMMU API to manage setting up the groups. Signed-off-by: Alex Williamson Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c62f2df25221..4a434528cd1c 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4090,6 +4090,47 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain, return 0; } +static int intel_iommu_add_device(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *bridge, *dma_pdev; + struct iommu_group *group; + int ret; + + if (!device_to_iommu(pci_domain_nr(pdev->bus), + pdev->bus->number, pdev->devfn)) + return -ENODEV; + + bridge = pci_find_upstream_pcie_bridge(pdev); + if (bridge) { + if (pci_is_pcie(bridge)) + dma_pdev = pci_get_domain_bus_and_slot( + pci_domain_nr(pdev->bus), + bridge->subordinate->number, 0); + else + dma_pdev = pci_dev_get(bridge); + } else + dma_pdev = pci_dev_get(pdev); + + group = iommu_group_get(&dma_pdev->dev); + pci_dev_put(dma_pdev); + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return PTR_ERR(group); + } + + ret = iommu_group_add_device(group, dev); + + iommu_group_put(group); + return ret; +} + +static void intel_iommu_remove_device(struct device *dev) +{ + iommu_group_remove_device(dev); +} + static struct iommu_ops intel_iommu_ops = { .domain_init = intel_iommu_domain_init, .domain_destroy = intel_iommu_domain_destroy, @@ -4099,6 +4140,8 @@ static struct iommu_ops intel_iommu_ops = { .unmap = intel_iommu_unmap, .iova_to_phys = intel_iommu_iova_to_phys, .domain_has_cap = intel_iommu_domain_has_cap, + .add_device = intel_iommu_add_device, + .remove_device = intel_iommu_remove_device, .pgsize_bitmap = INTEL_IOMMU_PGSIZES, }; -- GitLab From 664b600331128146d8ddd3e004defe23ba5c47dc Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:19:31 -0600 Subject: [PATCH 2688/6849] amd_iommu: Make use of DMA quirks and ACS checks in IOMMU groups Work around broken devices and adhere to ACS support when determining IOMMU grouping. Signed-off-by: Alex Williamson Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 60ea92065d31..49172393d6ec 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -254,6 +254,14 @@ static bool check_device(struct device *dev) return true; } +static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) +{ + pci_dev_put(*from); + *from = to; +} + +#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) + static int iommu_init_device(struct device *dev) { struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev); @@ -286,6 +294,23 @@ static int iommu_init_device(struct device *dev) } else dma_pdev = pci_dev_get(pdev); + swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); + + if (dma_pdev->multifunction && + !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) + swap_pci_ref(&dma_pdev, + pci_get_slot(dma_pdev->bus, + PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), + 0))); + + while (!pci_is_root_bus(dma_pdev->bus)) { + if (pci_acs_path_enabled(dma_pdev->bus->self, + NULL, REQ_ACS_FLAGS)) + break; + + swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); + } + group = iommu_group_get(&dma_pdev->dev); pci_dev_put(dma_pdev); if (!group) { -- GitLab From 783f157bc5a7fa30ee17b4099b27146bd1b68af4 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:19:43 -0600 Subject: [PATCH 2689/6849] intel-iommu: Make use of DMA quirks and ACS checks in IOMMU groups Work around broken devices and adhere to ACS support when determining IOMMU grouping. Signed-off-by: Alex Williamson Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 4a434528cd1c..ebf2b310cdde 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4090,6 +4090,14 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain, return 0; } +static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) +{ + pci_dev_put(*from); + *from = to; +} + +#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) + static int intel_iommu_add_device(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); @@ -4112,6 +4120,23 @@ static int intel_iommu_add_device(struct device *dev) } else dma_pdev = pci_dev_get(pdev); + swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); + + if (dma_pdev->multifunction && + !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) + swap_pci_ref(&dma_pdev, + pci_get_slot(dma_pdev->bus, + PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), + 0))); + + while (!pci_is_root_bus(dma_pdev->bus)) { + if (pci_acs_path_enabled(dma_pdev->bus->self, + NULL, REQ_ACS_FLAGS)) + break; + + swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); + } + group = iommu_group_get(&dma_pdev->dev); pci_dev_put(dma_pdev); if (!group) { -- GitLab From 7d43c2e42cb1e436f97c1763150e4e1122ae0d57 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 30 May 2012 14:19:55 -0600 Subject: [PATCH 2690/6849] iommu: Remove group_mf The iommu=group_mf is really no longer needed with the addition of ACS support in IOMMU drivers creating groups. Most multifunction devices will now be grouped already. If a device has gone to the trouble of exposing ACS, trust that it works. We can use the device specific ACS function for fixing devices we trust individually. This largely reverts bcb71abe. Signed-off-by: Alex Williamson Signed-off-by: Joerg Roedel --- Documentation/kernel-parameters.txt | 1 - arch/ia64/include/asm/iommu.h | 2 -- arch/ia64/kernel/pci-dma.c | 1 - arch/x86/include/asm/iommu.h | 1 - arch/x86/kernel/pci-dma.c | 11 ----------- 5 files changed, 16 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a92c5ebf373e..d2f4f7acc435 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1134,7 +1134,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. forcesac soft pt [x86, IA-64] - group_mf [x86, IA-64] io7= [HW] IO7 for Marvel based alpha systems diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h index b6a809fa2995..105c93b00b1b 100644 --- a/arch/ia64/include/asm/iommu.h +++ b/arch/ia64/include/asm/iommu.h @@ -11,12 +11,10 @@ extern void no_iommu_init(void); extern int force_iommu, no_iommu; extern int iommu_pass_through; extern int iommu_detected; -extern int iommu_group_mf; #else #define iommu_pass_through (0) #define no_iommu (1) #define iommu_detected (0) -#define iommu_group_mf (0) #endif extern void iommu_dma_init(void); extern void machvec_init(const char *name); diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index 7cdc89b2483c..1ddcfe5ef353 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -32,7 +32,6 @@ int force_iommu __read_mostly; #endif int iommu_pass_through; -int iommu_group_mf; /* Dummy device used for NULL arguments (normally ISA). Better would be probably a smaller DMA mask, but this is bug-to-bug compatible diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index dffc38ee6255..345c99cef152 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -5,7 +5,6 @@ extern struct dma_map_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; extern int iommu_pass_through; -extern int iommu_group_mf; /* 10 seconds */ #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index c0f420f76cd3..de2b7ad70273 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -45,15 +45,6 @@ int iommu_detected __read_mostly = 0; */ int iommu_pass_through __read_mostly; -/* - * Group multi-function PCI devices into a single device-group for the - * iommu_device_group interface. This tells the iommu driver to pretend - * it cannot distinguish between functions of a device, exposing only one - * group for the device. Useful for disallowing use of individual PCI - * functions from userspace drivers. - */ -int iommu_group_mf __read_mostly; - extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; /* Dummy device used for NULL arguments (normally ISA). */ @@ -194,8 +185,6 @@ static __init int iommu_setup(char *p) #endif if (!strncmp(p, "pt", 2)) iommu_pass_through = 1; - if (!strncmp(p, "group_mf", 8)) - iommu_group_mf = 1; gart_parse_options(p); -- GitLab From 4e0ee78f2af96676c9dca898c13250f62c513058 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Mon, 25 Jun 2012 14:23:54 +0300 Subject: [PATCH 2691/6849] iommu: Add DMA window parser, of_get_dma_window() This code was based on: "arch/microblaze/kernel/prom_parse.c" "arch/powerpc/kernel/prom_parse.c" Can replace "of_parse_dma_window()" in the above. This supports different formats flexibly. "prefix" can be configured if any. "busno" and "index" are optionally specified. Set NULL and 0 if not used. Signed-off-by: Hiroshi DOYU Acked-by: Stephen Warren Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 4 ++ drivers/iommu/Makefile | 1 + drivers/iommu/of_iommu.c | 90 ++++++++++++++++++++++++++++++++++++++++ include/linux/of_iommu.h | 21 ++++++++++ 4 files changed, 116 insertions(+) create mode 100644 drivers/iommu/of_iommu.c create mode 100644 include/linux/of_iommu.h diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 340893727538..4826af62a9de 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -13,6 +13,10 @@ menuconfig IOMMU_SUPPORT if IOMMU_SUPPORT +config OF_IOMMU + def_bool y + depends on OF + # MSM IOMMU support config MSM_IOMMU bool "MSM IOMMU Support" diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 76e54ef796de..14a4d5fc94fa 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_IOMMU_API) += iommu.o +obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c new file mode 100644 index 000000000000..ee249bc959f8 --- /dev/null +++ b/drivers/iommu/of_iommu.c @@ -0,0 +1,90 @@ +/* + * OF helpers for IOMMU + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +/** + * of_get_dma_window - Parse *dma-window property and returns 0 if found. + * + * @dn: device node + * @prefix: prefix for property name if any + * @index: index to start to parse + * @busno: Returns busno if supported. Otherwise pass NULL + * @addr: Returns address that DMA starts + * @size: Returns the range that DMA can handle + * + * This supports different formats flexibly. "prefix" can be + * configured if any. "busno" and "index" are optionally + * specified. Set 0(or NULL) if not used. + */ +int of_get_dma_window(struct device_node *dn, const char *prefix, int index, + unsigned long *busno, dma_addr_t *addr, size_t *size) +{ + const __be32 *dma_window, *end; + int bytes, cur_index = 0; + char propname[NAME_MAX], addrname[NAME_MAX], sizename[NAME_MAX]; + + if (!dn || !addr || !size) + return -EINVAL; + + if (!prefix) + prefix = ""; + + snprintf(propname, sizeof(propname), "%sdma-window", prefix); + snprintf(addrname, sizeof(addrname), "%s#dma-address-cells", prefix); + snprintf(sizename, sizeof(sizename), "%s#dma-size-cells", prefix); + + dma_window = of_get_property(dn, propname, &bytes); + if (!dma_window) + return -ENODEV; + end = dma_window + bytes / sizeof(*dma_window); + + while (dma_window < end) { + u32 cells; + const void *prop; + + /* busno is one cell if supported */ + if (busno) + *busno = be32_to_cpup(dma_window++); + + prop = of_get_property(dn, addrname, NULL); + if (!prop) + prop = of_get_property(dn, "#address-cells", NULL); + + cells = prop ? be32_to_cpup(prop) : of_n_addr_cells(dn); + if (!cells) + return -EINVAL; + *addr = of_read_number(dma_window, cells); + dma_window += cells; + + prop = of_get_property(dn, sizename, NULL); + cells = prop ? be32_to_cpup(prop) : of_n_size_cells(dn); + if (!cells) + return -EINVAL; + *size = of_read_number(dma_window, cells); + dma_window += cells; + + if (cur_index++ == index) + break; + } + return 0; +} +EXPORT_SYMBOL_GPL(of_get_dma_window); diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h new file mode 100644 index 000000000000..51a560f34bca --- /dev/null +++ b/include/linux/of_iommu.h @@ -0,0 +1,21 @@ +#ifndef __OF_IOMMU_H +#define __OF_IOMMU_H + +#ifdef CONFIG_OF_IOMMU + +extern int of_get_dma_window(struct device_node *dn, const char *prefix, + int index, unsigned long *busno, dma_addr_t *addr, + size_t *size); + +#else + +static inline int of_get_dma_window(struct device_node *dn, const char *prefix, + int index, unsigned long *busno, dma_addr_t *addr, + size_t *size) +{ + return -EINVAL; +} + +#endif /* CONFIG_OF_IOMMU */ + +#endif /* __OF_IOMMU_H */ -- GitLab From 0760e8faa960f8ee991fa4acb802db4e20661281 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Mon, 25 Jun 2012 14:23:55 +0300 Subject: [PATCH 2692/6849] iommu/tegra: smmu: Add device tree support for SMMU The necessary info is expected to pass from DT. For more precise resource reservation, there shouldn't be any overlapping of register range between SMMU and MC. SMMU register offset needs to be calculated correctly, based on its register bank. Signed-off-by: Hiroshi DOYU Acked-by: Stephen Warren Acked-by: Grant Likely Signed-off-by: Joerg Roedel --- .../bindings/iommu/nvidia,tegra30-smmu.txt | 21 +++ drivers/iommu/Kconfig | 2 +- drivers/iommu/tegra-smmu.c | 149 +++++++++++------- 3 files changed, 117 insertions(+), 55 deletions(-) create mode 100644 Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt new file mode 100644 index 000000000000..89fb5434b730 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt @@ -0,0 +1,21 @@ +NVIDIA Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit) + +Required properties: +- compatible : "nvidia,tegra30-smmu" +- reg : Should contain 3 register banks(address and length) for each + of the SMMU register blocks. +- interrupts : Should contain MC General interrupt. +- nvidia,#asids : # of ASIDs +- dma-window : IOVA start address and length. +- nvidia,ahb : phandle to the ahb bus connected to SMMU. + +Example: + smmu { + compatible = "nvidia,tegra30-smmu"; + reg = <0x7000f010 0x02c + 0x7000f1f0 0x010 + 0x7000f228 0x05c>; + nvidia,#asids = <4>; /* # of ASIDs */ + dma-window = <0 0x40000000>; /* IOVA start & length */ + nvidia,ahb = <&ahb>; + }; diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 4826af62a9de..9f69b561f5db 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -158,7 +158,7 @@ config TEGRA_IOMMU_GART config TEGRA_IOMMU_SMMU bool "Tegra SMMU IOMMU Support" - depends on ARCH_TEGRA_3x_SOC + depends on ARCH_TEGRA_3x_SOC && TEGRA_AHB select IOMMU_API help Enables support for remapping discontiguous physical memory diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index ecd679043d77..2c92b8c3514e 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -30,12 +30,15 @@ #include #include #include +#include +#include #include #include #include #include +#include /* bitmap of the page sizes currently supported */ #define SMMU_IOMMU_PGSIZES (SZ_4K) @@ -111,12 +114,6 @@ #define SMMU_PDE_NEXT_SHIFT 28 -/* AHB Arbiter Registers */ -#define AHB_XBAR_CTRL 0xe0 -#define AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE 1 -#define AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT 17 - -#define SMMU_NUM_ASIDS 4 #define SMMU_TLB_FLUSH_VA_SECTION__MASK 0xffc00000 #define SMMU_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */ #define SMMU_TLB_FLUSH_VA_GROUP__MASK 0xffffc000 @@ -136,6 +133,7 @@ #define SMMU_PAGE_SHIFT 12 #define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) +#define SMMU_PAGE_MASK ((1 << SMMU_PAGE_SHIFT) - 1) #define SMMU_PDIR_COUNT 1024 #define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT) @@ -177,6 +175,8 @@ #define SMMU_ASID_DISABLE 0 #define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0)) +#define NUM_SMMU_REG_BANKS 3 + #define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1) #define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0) #define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1) @@ -235,7 +235,7 @@ struct smmu_as { * Per SMMU device - IOMMU device */ struct smmu_device { - void __iomem *regs, *regs_ahbarb; + void __iomem *regs[NUM_SMMU_REG_BANKS]; unsigned long iovmm_base; /* remappable base address */ unsigned long page_count; /* total remappable size */ spinlock_t lock; @@ -252,29 +252,47 @@ struct smmu_device { unsigned long translation_enable_1; unsigned long translation_enable_2; unsigned long asid_security; + + struct device_node *ahb; }; static struct smmu_device *smmu_handle; /* unique for a system */ /* - * SMMU/AHB register accessors + * SMMU register accessors */ static inline u32 smmu_read(struct smmu_device *smmu, size_t offs) { - return readl(smmu->regs + offs); -} -static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs) -{ - writel(val, smmu->regs + offs); + BUG_ON(offs < 0x10); + if (offs < 0x3c) + return readl(smmu->regs[0] + offs - 0x10); + BUG_ON(offs < 0x1f0); + if (offs < 0x200) + return readl(smmu->regs[1] + offs - 0x1f0); + BUG_ON(offs < 0x228); + if (offs < 0x284) + return readl(smmu->regs[2] + offs - 0x228); + BUG(); } -static inline u32 ahb_read(struct smmu_device *smmu, size_t offs) -{ - return readl(smmu->regs_ahbarb + offs); -} -static inline void ahb_write(struct smmu_device *smmu, u32 val, size_t offs) +static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs) { - writel(val, smmu->regs_ahbarb + offs); + BUG_ON(offs < 0x10); + if (offs < 0x3c) { + writel(val, smmu->regs[0] + offs - 0x10); + return; + } + BUG_ON(offs < 0x1f0); + if (offs < 0x200) { + writel(val, smmu->regs[1] + offs - 0x1f0); + return; + } + BUG_ON(offs < 0x228); + if (offs < 0x284) { + writel(val, smmu->regs[2] + offs - 0x228); + return; + } + BUG(); } #define VA_PAGE_TO_PA(va, page) \ @@ -370,7 +388,7 @@ static void smmu_flush_regs(struct smmu_device *smmu, int enable) FLUSH_SMMU_REGS(smmu); } -static void smmu_setup_regs(struct smmu_device *smmu) +static int smmu_setup_regs(struct smmu_device *smmu) { int i; u32 val; @@ -398,10 +416,7 @@ static void smmu_setup_regs(struct smmu_device *smmu) smmu_flush_regs(smmu, 1); - val = ahb_read(smmu, AHB_XBAR_CTRL); - val |= AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE << - AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT; - ahb_write(smmu, val, AHB_XBAR_CTRL); + return tegra_ahb_enable_smmu(smmu->ahb); } static void flush_ptc_and_tlb(struct smmu_device *smmu, @@ -873,52 +888,72 @@ static int tegra_smmu_resume(struct device *dev) { struct smmu_device *smmu = dev_get_drvdata(dev); unsigned long flags; + int err; spin_lock_irqsave(&smmu->lock, flags); - smmu_setup_regs(smmu); + err = smmu_setup_regs(smmu); spin_unlock_irqrestore(&smmu->lock, flags); - return 0; + return err; } static int tegra_smmu_probe(struct platform_device *pdev) { struct smmu_device *smmu; - struct resource *regs, *regs2, *window; struct device *dev = &pdev->dev; - int i, err = 0; + int i, asids, err = 0; + dma_addr_t base; + size_t size; + const void *prop; if (smmu_handle) return -EIO; BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT); - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - window = platform_get_resource(pdev, IORESOURCE_MEM, 2); - if (!regs || !regs2 || !window) { - dev_err(dev, "No SMMU resources\n"); - return -ENODEV; - } - smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); if (!smmu) { dev_err(dev, "failed to allocate smmu_device\n"); return -ENOMEM; } - smmu->dev = dev; - smmu->num_as = SMMU_NUM_ASIDS; - smmu->iovmm_base = (unsigned long)window->start; - smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT; - smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs)); - smmu->regs_ahbarb = devm_ioremap(dev, regs2->start, - resource_size(regs2)); - if (!smmu->regs || !smmu->regs_ahbarb) { - dev_err(dev, "failed to remap SMMU registers\n"); - err = -ENXIO; - goto fail; + for (i = 0; i < ARRAY_SIZE(smmu->regs); i++) { + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (!res) + return -ENODEV; + smmu->regs[i] = devm_request_and_ioremap(&pdev->dev, res); + if (!smmu->regs[i]) + return -EBUSY; } + err = of_get_dma_window(dev->of_node, NULL, 0, NULL, &base, &size); + if (err) + return -ENODEV; + + if (size & SMMU_PAGE_MASK) + return -EINVAL; + + size >>= SMMU_PAGE_SHIFT; + if (!size) + return -EINVAL; + + prop = of_get_property(dev->of_node, "nvidia,#asids", NULL); + if (!prop) + return -ENODEV; + asids = be32_to_cpup(prop); + if (!asids) + return -ENODEV; + + smmu->ahb = of_parse_phandle(dev->of_node, "nvidia,ahb", 0); + if (!smmu->ahb) + return -ENODEV; + + smmu->dev = dev; + smmu->num_as = asids; + smmu->iovmm_base = base; + smmu->page_count = size; + smmu->translation_enable_0 = ~0; smmu->translation_enable_1 = ~0; smmu->translation_enable_2 = ~0; @@ -945,7 +980,9 @@ static int tegra_smmu_probe(struct platform_device *pdev) INIT_LIST_HEAD(&as->client); } spin_lock_init(&smmu->lock); - smmu_setup_regs(smmu); + err = smmu_setup_regs(smmu); + if (err) + goto fail; platform_set_drvdata(pdev, smmu); smmu->avp_vector_page = alloc_page(GFP_KERNEL); @@ -958,10 +995,6 @@ static int tegra_smmu_probe(struct platform_device *pdev) fail: if (smmu->avp_vector_page) __free_page(smmu->avp_vector_page); - if (smmu->regs) - devm_iounmap(dev, smmu->regs); - if (smmu->regs_ahbarb) - devm_iounmap(dev, smmu->regs_ahbarb); if (smmu && smmu->as) { for (i = 0; i < smmu->num_as; i++) { if (smmu->as[i].pdir_page) { @@ -993,8 +1026,6 @@ static int tegra_smmu_remove(struct platform_device *pdev) __free_page(smmu->avp_vector_page); if (smmu->regs) devm_iounmap(dev, smmu->regs); - if (smmu->regs_ahbarb) - devm_iounmap(dev, smmu->regs_ahbarb); devm_kfree(dev, smmu); smmu_handle = NULL; return 0; @@ -1005,6 +1036,14 @@ const struct dev_pm_ops tegra_smmu_pm_ops = { .resume = tegra_smmu_resume, }; +#ifdef CONFIG_OF +static struct of_device_id tegra_smmu_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra30-smmu", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tegra_smmu_of_match); +#endif + static struct platform_driver tegra_smmu_driver = { .probe = tegra_smmu_probe, .remove = tegra_smmu_remove, @@ -1012,6 +1051,7 @@ static struct platform_driver tegra_smmu_driver = { .owner = THIS_MODULE, .name = "tegra-smmu", .pm = &tegra_smmu_pm_ops, + .of_match_table = of_match_ptr(tegra_smmu_of_match), }, }; @@ -1031,4 +1071,5 @@ module_exit(tegra_smmu_exit); MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30"); MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_ALIAS("platform:tegra-smmu"); MODULE_LICENSE("GPL v2"); -- GitLab From a3b24915456b63c9002e94152e122b07de5566f2 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Mon, 25 Jun 2012 14:23:56 +0300 Subject: [PATCH 2693/6849] iommu/tegra: smmu: Simplify allocation at once To simplify the code, alloc necessary data at once. Signed-off-by: Hiroshi DOYU Acked-by: Stephen Warren Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 2c92b8c3514e..98fcc7268eaf 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -241,8 +241,6 @@ struct smmu_device { spinlock_t lock; char *name; struct device *dev; - int num_as; - struct smmu_as *as; /* Run-time allocated array */ struct page *avp_vector_page; /* dummy page shared by all AS's */ /* @@ -254,6 +252,9 @@ struct smmu_device { unsigned long asid_security; struct device_node *ahb; + + int num_as; + struct smmu_as as[0]; /* Run-time allocated array */ }; static struct smmu_device *smmu_handle; /* unique for a system */ @@ -902,15 +903,18 @@ static int tegra_smmu_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int i, asids, err = 0; dma_addr_t base; - size_t size; - const void *prop; + size_t bytes, size; if (smmu_handle) return -EIO; BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT); - smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); + if (of_property_read_u32(dev->of_node, "nvidia,#asids", &asids)) + return -ENODEV; + + bytes = sizeof(*smmu) + asids * sizeof(*smmu->as); + smmu = devm_kzalloc(dev, bytes, GFP_KERNEL); if (!smmu) { dev_err(dev, "failed to allocate smmu_device\n"); return -ENOMEM; @@ -938,13 +942,6 @@ static int tegra_smmu_probe(struct platform_device *pdev) if (!size) return -EINVAL; - prop = of_get_property(dev->of_node, "nvidia,#asids", NULL); - if (!prop) - return -ENODEV; - asids = be32_to_cpup(prop); - if (!asids) - return -ENODEV; - smmu->ahb = of_parse_phandle(dev->of_node, "nvidia,ahb", 0); if (!smmu->ahb) return -ENODEV; @@ -959,14 +956,6 @@ static int tegra_smmu_probe(struct platform_device *pdev) smmu->translation_enable_2 = ~0; smmu->asid_security = 0; - smmu->as = devm_kzalloc(dev, - sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL); - if (!smmu->as) { - dev_err(dev, "failed to allocate smmu_as\n"); - err = -ENOMEM; - goto fail; - } - for (i = 0; i < smmu->num_as; i++) { struct smmu_as *as = &smmu->as[i]; -- GitLab From 0547c2f56e6e4795d5366ba3b8483b668920a947 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Mon, 25 Jun 2012 14:23:57 +0300 Subject: [PATCH 2694/6849] iommu/tegra: smmu: Remove unnecessary cleanups with devm_*() Remove unnecessary cleanup procedures with devm_*() functions. Signed-off-by: Hiroshi DOYU Acked-by: Stephen Warren Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 98fcc7268eaf..cc6aba45e49a 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -971,51 +971,26 @@ static int tegra_smmu_probe(struct platform_device *pdev) spin_lock_init(&smmu->lock); err = smmu_setup_regs(smmu); if (err) - goto fail; + return err; platform_set_drvdata(pdev, smmu); smmu->avp_vector_page = alloc_page(GFP_KERNEL); if (!smmu->avp_vector_page) - goto fail; + return -ENOMEM; smmu_handle = smmu; return 0; - -fail: - if (smmu->avp_vector_page) - __free_page(smmu->avp_vector_page); - if (smmu && smmu->as) { - for (i = 0; i < smmu->num_as; i++) { - if (smmu->as[i].pdir_page) { - ClearPageReserved(smmu->as[i].pdir_page); - __free_page(smmu->as[i].pdir_page); - } - } - devm_kfree(dev, smmu->as); - } - devm_kfree(dev, smmu); - return err; } static int tegra_smmu_remove(struct platform_device *pdev) { struct smmu_device *smmu = platform_get_drvdata(pdev); - struct device *dev = smmu->dev; + int i; smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG); - platform_set_drvdata(pdev, NULL); - if (smmu->as) { - int i; - - for (i = 0; i < smmu->num_as; i++) - free_pdir(&smmu->as[i]); - devm_kfree(dev, smmu->as); - } - if (smmu->avp_vector_page) - __free_page(smmu->avp_vector_page); - if (smmu->regs) - devm_iounmap(dev, smmu->regs); - devm_kfree(dev, smmu); + for (i = 0; i < smmu->num_as; i++) + free_pdir(&smmu->as[i]); + __free_page(smmu->avp_vector_page); smmu_handle = NULL; return 0; } -- GitLab From ff7636292aac6cae2ee3a553d5424ea49c8a8263 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Mon, 25 Jun 2012 14:23:58 +0300 Subject: [PATCH 2695/6849] iommu/tegra: smmu: Fix uninitialized var warning For the compiler warning, uninitizlized var when getting value by a pointer. Signed-off-by: Hiroshi DOYU Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index cc6aba45e49a..becfc614cf94 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -902,8 +902,8 @@ static int tegra_smmu_probe(struct platform_device *pdev) struct smmu_device *smmu; struct device *dev = &pdev->dev; int i, asids, err = 0; - dma_addr_t base; - size_t bytes, size; + dma_addr_t uninitialized_var(base); + size_t bytes, uninitialized_var(size); if (smmu_handle) return -EIO; -- GitLab From 90e614bb4c581eb588ec26f130fcdd65aa047fa8 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 16 May 2012 11:35:04 -0300 Subject: [PATCH 2696/6849] [media] s5p-fimc: Fix bug in capture node open() When video pipeline initialization fails, the ST_CAPT_BUSY flag needs to be cleared before pm_runtime_put_sync is called. Otherwise the runtime suspend routine tries to suspend device, rather than just turning it off. Also fix potential null pointer dereference in fimc_pipeline_shutdown(). Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-capture.c | 2 +- drivers/media/video/s5p-fimc/fimc-mdevice.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 354574591908..7083107c2b37 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -499,10 +499,10 @@ static int fimc_capture_open(struct file *file) if (ret < 0) { dev_err(&fimc->pdev->dev, "Video pipeline initialization failed\n"); + clear_bit(ST_CAPT_BUSY, &fimc->state); pm_runtime_put_sync(&fimc->pdev->dev); fimc->vid_cap.refcnt--; v4l2_fh_release(file); - clear_bit(ST_CAPT_BUSY, &fimc->state); return ret; } ret = fimc_capture_ctrls_create(fimc); diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 6753c45631b8..7450dcdafc87 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -193,9 +193,13 @@ int __fimc_pipeline_shutdown(struct fimc_pipeline *p) int fimc_pipeline_shutdown(struct fimc_pipeline *p) { - struct media_entity *me = &p->subdevs[IDX_SENSOR]->entity; + struct media_entity *me; int ret; + if (!p || !p->subdevs[IDX_SENSOR]) + return -EINVAL; + + me = &p->subdevs[IDX_SENSOR]->entity; mutex_lock(&me->parent->graph_mutex); ret = __fimc_pipeline_shutdown(p); mutex_unlock(&me->parent->graph_mutex); -- GitLab From d0da3c3565a1dd3cdfa374038d6ccae4b90fe142 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 16 May 2012 13:08:30 -0300 Subject: [PATCH 2697/6849] [media] s5p-fimc: Don't create multiple active links to same sink entity The driver is supposed to create active media link from sensor N (or its corresponding s5p-mipi-csis entity) to FIMC.N by default. Instead s5p-mipi-csis.N entity gets always connected by a default active link to FIMC.N, regardless of there are parallel bus sensor entities already connected to FIMC.N. Correct this. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-mdevice.c | 23 ++++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 7450dcdafc87..dffe4da5eaa0 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -502,12 +502,12 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) * @source: the source entity to create links to all fimc entities from * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null * @pad: the source entity pad index - * @fimc_id: index of the fimc device for which link should be enabled + * @link_mask: bitmask of the fimc devices for which link should be enabled */ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, struct media_entity *source, struct v4l2_subdev *sensor, - int pad, int fimc_id) + int pad, int link_mask) { struct fimc_sensor_info *s_info; struct media_entity *sink; @@ -524,7 +524,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc[i]->variant->has_cam_if) continue; - flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; + flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0; sink = &fmd->fimc[i]->vid_cap.subdev.entity; ret = media_entity_create_link(source, pad, sink, @@ -556,7 +556,10 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc_lite[i]) continue; - flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; + if (link_mask & (1 << (i + FIMC_MAX_DEVS))) + flags = MEDIA_LNK_FL_ENABLED; + else + flags = 0; sink = &fmd->fimc_lite[i]->subdev.entity; ret = media_entity_create_link(source, pad, sink, @@ -618,9 +621,8 @@ static int fimc_md_create_links(struct fimc_md *fmd) struct s5p_fimc_isp_info *pdata; struct fimc_sensor_info *s_info; struct media_entity *source, *sink; - int i, pad, fimc_id = 0; - int ret = 0; - u32 flags; + int i, pad, fimc_id = 0, ret = 0; + u32 flags, link_mask = 0; for (i = 0; i < fmd->num_sensors; i++) { if (fmd->sensor[i].subdev == NULL) @@ -672,19 +674,20 @@ static int fimc_md_create_links(struct fimc_md *fmd) if (source == NULL) continue; + link_mask = 1 << fimc_id++; ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor, - pad, fimc_id++); + pad, link_mask); } - fimc_id = 0; for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) { if (fmd->csis[i].sd == NULL) continue; source = &fmd->csis[i].sd->entity; pad = CSIS_PAD_SOURCE; + link_mask = 1 << fimc_id++; ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL, - pad, fimc_id++); + pad, link_mask); } /* Create immutable links between each FIMC's subdev and video node */ -- GitLab From d547ab66e275e2f6bf703572e943018ef7c391c5 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 16 May 2012 15:00:26 -0300 Subject: [PATCH 2698/6849] [media] s5p-fimc: Honour sizeimage in VIDIOC_S_FMT Allow memory buffer size to be increased by means of struct v4l2_pix_plane_format::sizeimage at VIDIOC_S_FMT ioctl. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-capture.c | 7 ++++--- drivers/media/video/s5p-fimc/fimc-core.c | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 7083107c2b37..13df7230c8d8 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -350,7 +350,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, if (pixm) sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); else - sizes[i] = size; + sizes[i] = max_t(u32, size, frame->payload[i]); + allocators[i] = ctx->fimc_dev->alloc_ctx; } @@ -924,10 +925,10 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) pix->width = mf->width; pix->height = mf->height; } + fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); for (i = 0; i < ff->fmt->colplanes; i++) - ff->payload[i] = - (pix->width * pix->height * ff->fmt->depth[i]) / 8; + ff->payload[i] = pix->plane_fmt[i].sizeimage; set_frame_bounds(ff, pix->width, pix->height); /* Reset the composition rectangle if not yet configured */ diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 92fc5a20fb76..65124a24c30f 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -741,8 +741,8 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, pix->width = width; for (i = 0; i < pix->num_planes; ++i) { - u32 bpl = pix->plane_fmt[i].bytesperline; - u32 *sizeimage = &pix->plane_fmt[i].sizeimage; + struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i]; + u32 bpl = plane_fmt->bytesperline; if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) bpl = pix->width; /* Planar */ @@ -754,8 +754,9 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, if (i == 0) /* Same bytesperline for each plane. */ bytesperline = bpl; - pix->plane_fmt[i].bytesperline = bytesperline; - *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8; + plane_fmt->bytesperline = bytesperline; + plane_fmt->sizeimage = max((pix->width * pix->height * + fmt->depth[i]) / 8, plane_fmt->sizeimage); } } -- GitLab From 0b4b1f199d367762ddb68cb3303431fa6c84a7d6 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 16 May 2012 15:03:50 -0300 Subject: [PATCH 2699/6849] [media] s5p-fimc: Remove superfluous checks for buffer type The checks are already done at the v4l2 framework. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-capture.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 13df7230c8d8..0fd12dfbd3db 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -819,9 +819,6 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh, struct fimc_dev *fimc = video_drvdata(file); struct fimc_ctx *ctx = fimc->vid_cap.ctx; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; - return fimc_fill_format(&ctx->d_frame, f); } @@ -834,9 +831,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, struct v4l2_mbus_framefmt mf; struct fimc_fmt *ffmt = NULL; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; - if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { fimc_capture_try_format(ctx, &pix->width, &pix->height, NULL, &pix->pixelformat, @@ -888,8 +882,6 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) struct fimc_fmt *s_fmt = NULL; int ret, i; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; if (vb2_is_busy(&fimc->vid_cap.vbq)) return -EBUSY; -- GitLab From e3fc82e8b9f550d28f05600b98bcc8c26beef2ef Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 17 May 2012 14:22:10 -0300 Subject: [PATCH 2700/6849] [media] s5p-fimc: Prevent lock-up in multiple sensor systems The camera clocks managed by the driver were improperly reference counted and remained disabled when multiple video nodes were opened simultaneously. It manifested itself with following warning: [12.920000] WARNING: at drivers/media/video/s5p-fimc/fimc-mdevice.c:787 __fimc_md_set_camclk+0x1c0/0x1dc() [13.005000] Modules linked in: [13.005000] Backtrace: [13.040000] [] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c) [13.070000] r7:00000009 r6:00000313 r5:c02d576c r4:00000000 [13.155000] [] (dump_stack+0x0/0x1c) from [] (warn_slowpath_common+0x54/0x6c) [13.285000] [] (warn_slowpath_common+0x0/0x6c) from [] (warn_slowpath_null+0x24/0x2c) [13.360000] r9:e1981010 r8:00000000 r7:c061d3fc r6:e1981010 r5:e1981030 [13.430000] r4:00000000 [13.430000] [] (warn_slowpath_null+0x0/0x2c) from [] (__fimc_md_set_camclk+0x1c0/0x1dc) [13.550000] [] (__fimc_md_set_camclk+0x0/0x1dc) from [] (fimc_md_set_camclk+0x28/0x2c) [13.630000] [] (fimc_md_set_camclk+0x0/0x2c) from [] (__fimc_pipeline_shutdown+0x34/0x50) [13.705000] [] (__fimc_pipeline_shutdown+0x0/0x50) from [] (fimc_pipeline_shutdown+0x40/0x58) [13.765000] r5:e2391200 r4:e2357704 [13.805000] [] (fimc_pipeline_shutdown+0x0/0x58) from [] (fimc_capture_close+0xcc/0xe4) [13.915000] r5:e1b396c0 r4:e2357410 [13.915000] [] (fimc_capture_close+0x0/0xe4) from [] (v4l2_release+0x5c/0x80) [13.970000] r7:00000010 r6:e1d2d990 r5:e1b396c0 r4:e2394800 [14.000000] [] (v4l2_release+0x0/0x80) from [] (fput+0xc0/0x22c) [14.015000] r5:c157ef30 r4:e1b396c0 [14.015000] [] (fput+0x0/0x22c) from [] (filp_close+0x60/0x80) [14.080000] [] (filp_close+0x0/0x80) from [] (sys_close+0xb8/0xf4) [14.125000] r7:00000001 r6:e1b396c0 r5:c1400340 r4:c1400300 [14.125000] [] (sys_close+0x0/0xf4) from [] (ret_fast_syscall+0x0/0x30) [14.205000] r7:00000006 r6:beee5b94 r5:00000003 r4:b6f64fac Fix this, as well as potential memory leaks due to not calling v4l2_fh_release() on some error paths. Also remove some error logs printed for events that aren't critical and are normal conditions for some system configurations. Also check if the device have been properly run-time enabled during video node open. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-capture.c | 46 +++++++++++---------- drivers/media/video/s5p-fimc/fimc-lite.c | 14 ++++--- drivers/media/video/s5p-fimc/fimc-mdevice.c | 19 +++------ drivers/media/video/s5p-fimc/fimc-mdevice.h | 2 - 4 files changed, 38 insertions(+), 43 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 0fd12dfbd3db..71e483847a17 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -480,37 +480,39 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc); static int fimc_capture_open(struct file *file) { struct fimc_dev *fimc = video_drvdata(file); - int ret = v4l2_fh_open(file); - - if (ret) - return ret; + int ret; dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); - /* Return if the corresponding video mem2mem node is already opened. */ if (fimc_m2m_active(fimc)) return -EBUSY; set_bit(ST_CAPT_BUSY, &fimc->state); - pm_runtime_get_sync(&fimc->pdev->dev); - - if (++fimc->vid_cap.refcnt == 1) { - ret = fimc_pipeline_initialize(&fimc->pipeline, - &fimc->vid_cap.vfd->entity, true); - if (ret < 0) { - dev_err(&fimc->pdev->dev, - "Video pipeline initialization failed\n"); - clear_bit(ST_CAPT_BUSY, &fimc->state); - pm_runtime_put_sync(&fimc->pdev->dev); - fimc->vid_cap.refcnt--; - v4l2_fh_release(file); - return ret; - } - ret = fimc_capture_ctrls_create(fimc); + ret = pm_runtime_get_sync(&fimc->pdev->dev); + if (ret < 0) + return ret; + + ret = v4l2_fh_open(file); + if (ret) + return ret; + + if (++fimc->vid_cap.refcnt != 1) + return 0; - if (!ret && !fimc->vid_cap.user_subdev_api) - ret = fimc_capture_set_default_format(fimc); + ret = fimc_pipeline_initialize(&fimc->pipeline, + &fimc->vid_cap.vfd->entity, true); + if (ret < 0) { + clear_bit(ST_CAPT_BUSY, &fimc->state); + pm_runtime_put_sync(&fimc->pdev->dev); + fimc->vid_cap.refcnt--; + v4l2_fh_release(file); + return ret; } + ret = fimc_capture_ctrls_create(fimc); + + if (!ret && !fimc->vid_cap.user_subdev_api) + ret = fimc_capture_set_default_format(fimc); + return ret; } diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c index 400d701aef04..bbe93e4a8731 100644 --- a/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/drivers/media/video/s5p-fimc/fimc-lite.c @@ -451,21 +451,23 @@ static void fimc_lite_clear_event_counters(struct fimc_lite *fimc) static int fimc_lite_open(struct file *file) { struct fimc_lite *fimc = video_drvdata(file); - int ret = v4l2_fh_open(file); - - if (ret) - return ret; + int ret; set_bit(ST_FLITE_IN_USE, &fimc->state); - pm_runtime_get_sync(&fimc->pdev->dev); + ret = pm_runtime_get_sync(&fimc->pdev->dev); + if (ret < 0) + return ret; if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA) + return 0; + + ret = v4l2_fh_open(file); + if (ret < 0) return ret; ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, true); if (ret < 0) { - v4l2_err(fimc->vfd, "Video pipeline initialization failed\n"); pm_runtime_put_sync(&fimc->pdev->dev); fimc->ref_count--; v4l2_fh_release(file); diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index dffe4da5eaa0..52cef4865423 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -741,8 +741,8 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) } static int __fimc_md_set_camclk(struct fimc_md *fmd, - struct fimc_sensor_info *s_info, - bool on) + struct fimc_sensor_info *s_info, + bool on) { struct s5p_fimc_isp_info *pdata = s_info->pdata; struct fimc_camclk_info *camclk; @@ -751,12 +751,10 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL) return -EINVAL; - if (s_info->clk_on == on) - return 0; camclk = &fmd->camclk[pdata->clk_id]; - dbg("camclk %d, f: %lu, clk: %p, on: %d", - pdata->clk_id, pdata->clk_frequency, camclk, on); + dbg("camclk %d, f: %lu, use_count: %d, on: %d", + pdata->clk_id, pdata->clk_frequency, camclk->use_count, on); if (on) { if (camclk->use_count > 0 && @@ -767,11 +765,9 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, clk_set_rate(camclk->clock, pdata->clk_frequency); camclk->frequency = pdata->clk_frequency; ret = clk_enable(camclk->clock); + dbg("Enabled camclk %d: f: %lu", pdata->clk_id, + clk_get_rate(camclk->clock)); } - s_info->clk_on = 1; - dbg("Enabled camclk %d: f: %lu", pdata->clk_id, - clk_get_rate(camclk->clock)); - return ret; } @@ -780,7 +776,6 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (--camclk->use_count == 0) { clk_disable(camclk->clock); - s_info->clk_on = 0; dbg("Disabled camclk %d", pdata->clk_id); } return ret; @@ -796,8 +791,6 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, * devices to which sensors can be attached, either directly or through * the MIPI CSI receiver. The clock is allowed here to be used by * multiple sensors concurrently if they use same frequency. - * The per sensor subdev clk_on attribute helps to synchronize accesses - * to the sclk_cam clocks from the video and media device nodes. * This function should only be called when the graph mutex is held. */ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h index 3b8a3492a176..1f5dbaff5442 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.h @@ -47,7 +47,6 @@ struct fimc_camclk_info { * @pdata: sensor's atrributes passed as media device's platform data * @subdev: image sensor v4l2 subdev * @host: fimc device the sensor is currently linked to - * @clk_on: sclk_cam clock's state associated with this subdev * * This data structure applies to image sensor and the writeback subdevs. */ @@ -55,7 +54,6 @@ struct fimc_sensor_info { struct s5p_fimc_isp_info *pdata; struct v4l2_subdev *subdev; struct fimc_dev *host; - bool clk_on; }; /** -- GitLab From 316efab3e949e4fbdacb0975bf33adbad89115db Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 18 May 2012 13:31:28 -0300 Subject: [PATCH 2701/6849] [media] s5p-fimc: Fix fimc-lite system wide suspend procedure Only suspend the video pipeline devices if they were active before the pm.suspend() helper is called. This patch prevents following error: /# echo mem > /sys/power/state [ 34.965000] PM: Syncing filesystems ... done. [ 35.035000] Freezing user space processes ... (elapsed 0.01 seconds) done. ... [ 35.105000] dpm_run_callback(): platform_pm_suspend+0x0/0x5c returns -22 [ 35.105000] PM: Device exynos-fimc-lite.1 failed to suspend: error -22 [ 35.105000] PM: Some devices failed to suspend Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-lite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c index bbe93e4a8731..b0a8ce61ebf2 100644 --- a/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/drivers/media/video/s5p-fimc/fimc-lite.c @@ -1510,7 +1510,7 @@ static int fimc_lite_suspend(struct device *dev) return 0; ret = fimc_lite_stop_capture(fimc, suspend); - if (ret) + if (ret < 0 || !fimc_lite_active(fimc)) return ret; return fimc_pipeline_shutdown(&fimc->pipeline); -- GitLab From 0a198bcd511fcc60dc5daa203d221aafc95e0471 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 22 May 2012 13:50:14 -0300 Subject: [PATCH 2702/6849] [media] s5p-fimc: Shorten pixel formats description Shorten pixel format descriptions that exceed 32 characters so they're not being truncated when queried from user space. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 65124a24c30f..987bff20cc34 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -153,7 +153,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr", + .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -161,7 +161,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr", + .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 2, 2 }, @@ -169,7 +169,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 3, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled", + .name = "YUV 4:2:0 non-contig. 2p, tiled", .fourcc = V4L2_PIX_FMT_NV12MT, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, -- GitLab From 8183e7a7e2a4b542bd3044c5e3b0e116b0a7d2a1 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 25 May 2012 07:04:01 -0300 Subject: [PATCH 2703/6849] [media] s5p-fimc: Update to the control handler lock changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 77e7c4e624404c6edb5686b3d5f873c6008ed6b0 "v4l: Allow changing control handler lock" changed the lock field of struct v4l2_ctrl_handler to a pointer and this driver wasn't updated properly. This patch fixes following warning: drivers/media/video/s5p-fimc/fimc-core.c: In function ‘fimc_ctrls_activate’: drivers/media/video/s5p-fimc/fimc-core.c:644: warning: passing argument 1 of ‘mutex_lock’ from incompatible pointer type include/linux/mutex.h:152: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’ drivers/media/video/s5p-fimc/fimc-core.c:663: warning: passing argument 1 of ‘mutex_unlock’ from incompatible pointer type include/linux/mutex.h:169: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’ Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 987bff20cc34..a4646ca1d56f 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -641,7 +641,7 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) if (!ctrls->ready) return; - mutex_lock(&ctrls->handler.lock); + mutex_lock(ctrls->handler.lock); v4l2_ctrl_activate(ctrls->rotate, active); v4l2_ctrl_activate(ctrls->hflip, active); v4l2_ctrl_activate(ctrls->vflip, active); @@ -660,7 +660,7 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) ctx->hflip = 0; ctx->vflip = 0; } - mutex_unlock(&ctrls->handler.lock); + mutex_unlock(ctrls->handler.lock); } /* Update maximum value of the alpha color control */ -- GitLab From a60a295986edcbca6603cd42b4e38d7c83d87fb6 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 25 May 2012 07:08:05 -0300 Subject: [PATCH 2704/6849] [media] s5p-fimc: media_entity_pipeline_start() may fail Take into account media_entity_pipeline_start() may fail. [s.nawrocki: rebased onto latest tree] Signed-off-by: Sakari Ailus Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-capture.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 71e483847a17..7ace324d30cd 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -1045,8 +1045,10 @@ static int fimc_cap_streamon(struct file *file, void *priv, if (fimc_capture_active(fimc)) return -EBUSY; - media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, + ret = media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, p->m_pipeline); + if (ret < 0) + return ret; if (fimc->vid_cap.user_subdev_api) { ret = fimc_pipeline_validate(fimc); -- GitLab From a1a5861bd9ca3a6cb7ab89dd836da8cd158986b0 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 25 May 2012 03:29:38 -0300 Subject: [PATCH 2705/6849] [media] s5p-fimc: Fix compiler warning in fimc-lite.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is an update to changed media_entity_pipeline_start() signature in commit af88be3887c1a0b20d0792c3c237a67c73ef3286, "media: Add link_validate() op to check links to the sink pad" It fixes the following warning: drivers/media/video/s5p-fimc/fimc-lite.c: In function ‘fimc_lite_streamon’: drivers/media/video/s5p-fimc/fimc-lite.c:765:29: warning: ignoring return value of ‘media_entity_pipeline_start’, declared with attribute warn_unused_result [-Wunused-result] Signed-off-by: Sachin Kamat Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-lite.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c index b0a8ce61ebf2..4d269b8fa1ef 100644 --- a/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/drivers/media/video/s5p-fimc/fimc-lite.c @@ -764,7 +764,9 @@ static int fimc_lite_streamon(struct file *file, void *priv, if (fimc_lite_active(fimc)) return -EBUSY; - media_entity_pipeline_start(&sensor->entity, p->m_pipeline); + ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline); + if (ret < 0) + return ret; ret = fimc_pipeline_validate(fimc); if (ret) { -- GitLab From f676fa068819357f716953920b764554fe116b3c Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 25 May 2012 03:29:40 -0300 Subject: [PATCH 2706/6849] [media] s5p-fimc: Stop media entity pipeline if fimc_pipeline_validate fails Stops the media entity pipeline which was started earlier if fimc_pipeline_validate fails. [s.nawrocki: reworked to not exceed 80 characters line length] Signed-off-by: Sachin Kamat Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-capture.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 7ace324d30cd..725812aa0c30 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -1040,20 +1040,22 @@ static int fimc_cap_streamon(struct file *file, void *priv, { struct fimc_dev *fimc = video_drvdata(file); struct fimc_pipeline *p = &fimc->pipeline; + struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR]; int ret; if (fimc_capture_active(fimc)) return -EBUSY; - ret = media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, - p->m_pipeline); + ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline); if (ret < 0) return ret; if (fimc->vid_cap.user_subdev_api) { ret = fimc_pipeline_validate(fimc); - if (ret) + if (ret < 0) { + media_entity_pipeline_stop(&sd->entity); return ret; + } } return vb2_streamon(&fimc->vid_cap.vbq, type); } -- GitLab From 55d52ea86898f7b8fed437d400e6e28f4ef47665 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Jun 2012 14:36:43 +0200 Subject: [PATCH 2707/6849] ALSA: hda - Remove obsoleted CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS I simply forgot to remove this entry although all Realtek quirks have been dropped. Signed-off-by: Takashi Iwai --- sound/pci/hda/Kconfig | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 163b6b5de3eb..d03079764189 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -97,19 +97,6 @@ config SND_HDA_CODEC_REALTEK snd-hda-codec-realtek. This module is automatically loaded at probing. -config SND_HDA_ENABLE_REALTEK_QUIRKS - bool "Build static quirks for Realtek codecs" - depends on SND_HDA_CODEC_REALTEK - default y - help - Say Y here to build the static quirks codes for Realtek codecs. - If you need the "model" preset that the default BIOS auto-parser - can't handle, turn this option on. - - If your device works with model=auto option, basically you don't - need the quirk code. By turning this off, you can reduce the - module size quite a lot. - config SND_HDA_CODEC_ANALOG bool "Build Analog Device HD-audio codec support" default y -- GitLab From 11cab711f686893f2696a061dfca30454a624784 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Fri, 22 Jun 2012 08:12:12 -0500 Subject: [PATCH 2708/6849] x86/uv: Fix the UV BAU destination timeout period Correct the calculation of a destination timeout period, which is used to distinguish between a destination timeout and the situation where all the target software ack resources are full and a request is returned immediately. The problem is that integer arithmetic was overflowing, yielding a very large result. Without this fix destination timeouts are identified as resource 'plugged' events and an ipi method of resource releasing is unnecessarily employed. Signed-off-by: Cliff Wickman Link: http://lkml.kernel.org/r/20120622131212.GA31884@sgi.com Signed-off-by: Ingo Molnar --- arch/x86/platform/uv/tlb_uv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 59880afa851f..0c48d438cbba 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -1811,8 +1811,8 @@ static int calculate_destination_timeout(void) index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; - base = timeout_base_ns[index]; - ts_ns = base * mult1 * mult2; + ts_ns = timeout_base_ns[index]; + ts_ns *= (mult1 * mult2); ret = ts_ns / 1000; } else { /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */ -- GitLab From 26ef85770c765bb8b6b6922f8a413872dd8e3979 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Fri, 22 Jun 2012 08:13:30 -0500 Subject: [PATCH 2709/6849] x86/uv: Implement UV BAU runtime enable and disable control via /proc/sgi_uv/ This patch enables the BAU to be turned on or off dynamically. echo "on" > /proc/sgi_uv/ptc_statistics echo "off" > /proc/sgi_uv/ptc_statistics The system may be booted with or without the nobau option. Whether the system currently has the BAU off can be seen in the /proc file -- normally with the baustats script. Each cpu will have a 1 in the bauoff field if the BAU was turned off, so baustats will give a count of cpus that have it off. Signed-off-by: Cliff Wickman Link: http://lkml.kernel.org/r/20120622131330.GB31884@sgi.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uv/uv_bau.h | 2 + arch/x86/platform/uv/tlb_uv.c | 76 +++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 6149b476d9df..847c00b721b2 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -520,6 +520,7 @@ struct ptc_stats { unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */ unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */ unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */ + unsigned long s_enters; /* entries to the driver */ /* destination statistics */ unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ @@ -586,6 +587,7 @@ struct bau_control { int timeout_tries; int ipi_attempts; int conseccompletes; + short nobau; int baudisabled; int set_bau_off; short cpu; diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 0c48d438cbba..1492170cbb5a 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -38,6 +38,7 @@ static int timeout_base_ns[] = { static int timeout_us; static int nobau; +static int nobau_perm; static int baudisabled; static spinlock_t disable_lock; static cycles_t congested_cycles; @@ -120,6 +121,40 @@ static DEFINE_PER_CPU(struct ptc_stats, ptcstats); static DEFINE_PER_CPU(struct bau_control, bau_control); static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); +static void +set_bau_on(void) +{ + int cpu; + struct bau_control *bcp; + + if (nobau_perm) { + pr_info("BAU not initialized; cannot be turned on\n"); + return; + } + nobau = 0; + for_each_present_cpu(cpu) { + bcp = &per_cpu(bau_control, cpu); + bcp->nobau = 0; + } + pr_info("BAU turned on\n"); + return; +} + +static void +set_bau_off(void) +{ + int cpu; + struct bau_control *bcp; + + nobau = 1; + for_each_present_cpu(cpu) { + bcp = &per_cpu(bau_control, cpu); + bcp->nobau = 1; + } + pr_info("BAU turned off\n"); + return; +} + /* * Determine the first node on a uvhub. 'Nodes' are used for kernel * memory allocation. @@ -1079,12 +1114,12 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct ptc_stats *stat; struct bau_control *bcp; - /* kernel was booted 'nobau' */ - if (nobau) - return cpumask; - bcp = &per_cpu(bau_control, cpu); stat = bcp->statp; + stat->s_enters++; + + if (bcp->nobau) + return cpumask; /* bau was disabled due to slow response */ if (bcp->baudisabled) { @@ -1338,29 +1373,32 @@ static inline unsigned long long usec_2_cycles(unsigned long microsec) static int ptc_seq_show(struct seq_file *file, void *data) { struct ptc_stats *stat; + struct bau_control *bcp; int cpu; cpu = *(loff_t *)data; if (!cpu) { seq_printf(file, - "# cpu sent stime self locals remotes ncpus localhub "); + "# cpu bauoff sent stime self locals remotes ncpus localhub "); seq_printf(file, "remotehub numuvhubs numuvhubs16 numuvhubs8 "); seq_printf(file, "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries rok "); seq_printf(file, - "resetp resett giveup sto bz throt swack recv rtime "); + "resetp resett giveup sto bz throt enters swack recv rtime "); seq_printf(file, "all one mult none retry canc nocan reset rcan "); seq_printf(file, "disable enable wars warshw warwaits\n"); } if (cpu < num_possible_cpus() && cpu_online(cpu)) { - stat = &per_cpu(ptcstats, cpu); + bcp = &per_cpu(bau_control, cpu); + stat = bcp->statp; /* source side statistics */ seq_printf(file, - "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", - cpu, stat->s_requestor, cycles_2_us(stat->s_time), + "cpu %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", + cpu, bcp->nobau, stat->s_requestor, + cycles_2_us(stat->s_time), stat->s_ntargself, stat->s_ntarglocals, stat->s_ntargremotes, stat->s_ntargcpu, stat->s_ntarglocaluvhub, stat->s_ntargremoteuvhub, @@ -1369,11 +1407,11 @@ static int ptc_seq_show(struct seq_file *file, void *data) stat->s_ntarguvhub8, stat->s_ntarguvhub4, stat->s_ntarguvhub2, stat->s_ntarguvhub1, stat->s_dtimeout, stat->s_strongnacks); - seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ", + seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld %ld ", stat->s_retry_messages, stat->s_retriesok, stat->s_resets_plug, stat->s_resets_timeout, stat->s_giveup, stat->s_stimeout, - stat->s_busy, stat->s_throttles); + stat->s_busy, stat->s_throttles, stat->s_enters); /* destination side statistics */ seq_printf(file, @@ -1438,6 +1476,14 @@ static ssize_t ptc_proc_write(struct file *file, const char __user *user, return -EFAULT; optstr[count - 1] = '\0'; + if (!strcmp(optstr, "on")) { + set_bau_on(); + return count; + } else if (!strcmp(optstr, "off")) { + set_bau_off(); + return count; + } + if (strict_strtol(optstr, 10, &input_arg) < 0) { printk(KERN_DEBUG "%s is invalid\n", optstr); return -EINVAL; @@ -1836,6 +1882,8 @@ static void __init init_per_cpu_tunables(void) for_each_present_cpu(cpu) { bcp = &per_cpu(bau_control, cpu); bcp->baudisabled = 0; + if (nobau) + bcp->nobau = 1; bcp->statp = &per_cpu(ptcstats, cpu); /* time interval to catch a hardware stay-busy bug */ bcp->timeout_interval = usec_2_cycles(2*timeout_us); @@ -2069,9 +2117,6 @@ static int __init uv_bau_init(void) if (!is_uv_system()) return 0; - if (nobau) - return 0; - for_each_possible_cpu(cur_cpu) { mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); @@ -2091,7 +2136,8 @@ static int __init uv_bau_init(void) enable_timeouts(); if (init_per_cpu(nuvhubs, uv_base_pnode)) { - nobau = 1; + set_bau_off(); + nobau_perm = 1; return 0; } -- GitLab From 8b6e511e51f7e540c8e71022318ee4cc9a4567a7 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Fri, 22 Jun 2012 08:14:59 -0500 Subject: [PATCH 2710/6849] x86/uv: Work around UV2 BAU hangs On SGI's UV2 the BAU (Broadcast Assist Unit) driver can hang under a heavy load. To cure this: - Disable the UV2 extended status mode (see UV2_EXT_SHFT), as this mode changes BAU behavior in more ways then just delivering an extra bit of status. Revert status to just two meaningful bits, like UV1. - Use no IPI-style resets on UV2. Just give up the request for whatever the reason it failed and let it be accomplished with the legacy IPI method. - Use no alternate sending descriptor (the former UV2 workaround bcp->using_desc and handle_uv2_busy() stuff). Just disable the use of the BAU for a period of time in favor of the legacy IPI method when the h/w bug leaves a descriptor busy. -- new tunable: giveup_limit determines the threshold at which a hub is so plugged that it should do all requests with the legacy IPI method for a period of time -- generalize disable_for_congestion() (renamed disable_for_period()) for use whenever a hub should avoid using the BAU for a period of time Also: - Fix find_another_by_swack(), which is part of the UV2 bug workaround - Correct and clarify the statistics (new stats s_overipilimit, s_giveuplimit, s_enters, s_ipifordisabled, s_plugged, s_congested) Signed-off-by: Cliff Wickman Link: http://lkml.kernel.org/r/20120622131459.GC31884@sgi.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uv/uv_bau.h | 28 ++- arch/x86/platform/uv/tlb_uv.c | 387 +++++++++++++++---------------- 2 files changed, 200 insertions(+), 215 deletions(-) diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 847c00b721b2..a06983cdc125 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -140,6 +140,9 @@ #define IPI_RESET_LIMIT 1 /* after this # consecutive successes, bump up the throttle if it was lowered */ #define COMPLETE_THRESHOLD 5 +/* after this # of giveups (fall back to kernel IPI's) disable the use of + the BAU for a period of time */ +#define GIVEUP_LIMIT 100 #define UV_LB_SUBNODEID 0x10 @@ -166,7 +169,6 @@ #define FLUSH_RETRY_TIMEOUT 2 #define FLUSH_GIVEUP 3 #define FLUSH_COMPLETE 4 -#define FLUSH_RETRY_BUSYBUG 5 /* * tuning the action when the numalink network is extremely delayed @@ -175,7 +177,7 @@ microseconds */ #define CONGESTED_REPS 10 /* long delays averaged over this many broadcasts */ -#define CONGESTED_PERIOD 30 /* time for the bau to be +#define DISABLED_PERIOD 10 /* time for the bau to be disabled, in seconds */ /* see msg_type: */ #define MSG_NOOP 0 @@ -520,7 +522,12 @@ struct ptc_stats { unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */ unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */ unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */ - unsigned long s_enters; /* entries to the driver */ + unsigned long s_overipilimit; /* over the ipi reset limit */ + unsigned long s_giveuplimit; /* disables, over giveup limit*/ + unsigned long s_enters; /* entries to the driver */ + unsigned long s_ipifordisabled; /* fall back to IPI; disabled */ + unsigned long s_plugged; /* plugged by h/w bug*/ + unsigned long s_congested; /* giveup on long wait */ /* destination statistics */ unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ @@ -588,8 +595,7 @@ struct bau_control { int ipi_attempts; int conseccompletes; short nobau; - int baudisabled; - int set_bau_off; + short baudisabled; short cpu; short osnode; short uvhub_cpu; @@ -598,14 +604,16 @@ struct bau_control { short cpus_in_socket; short cpus_in_uvhub; short partition_base_pnode; - short using_desc; /* an index, like uvhub_cpu */ - unsigned int inuse_map; + short busy; /* all were busy (war) */ unsigned short message_number; unsigned short uvhub_quiesce; short socket_acknowledge_count[DEST_Q_SIZE]; cycles_t send_message; + cycles_t period_end; + cycles_t period_time; spinlock_t uvhub_lock; spinlock_t queue_lock; + spinlock_t disable_lock; /* tunables */ int max_concurr; int max_concurr_const; @@ -616,9 +624,9 @@ struct bau_control { int complete_threshold; int cong_response_us; int cong_reps; - int cong_period; - unsigned long clocks_per_100_usec; - cycles_t period_time; + cycles_t disabled_period; + int period_giveups; + int giveup_limit; long period_requests; struct hub_and_pnode *thp; }; diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 1492170cbb5a..71b5d5a07d7b 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -1,7 +1,7 @@ /* * SGI UltraViolet TLB flush routines. * - * (c) 2008-2011 Cliff Wickman , SGI. + * (c) 2008-2012 Cliff Wickman , SGI. * * This code is released under the GNU General Public License version 2 or * later. @@ -39,8 +39,6 @@ static int timeout_base_ns[] = { static int timeout_us; static int nobau; static int nobau_perm; -static int baudisabled; -static spinlock_t disable_lock; static cycles_t congested_cycles; /* tunables: */ @@ -48,12 +46,13 @@ static int max_concurr = MAX_BAU_CONCURRENT; static int max_concurr_const = MAX_BAU_CONCURRENT; static int plugged_delay = PLUGGED_DELAY; static int plugsb4reset = PLUGSB4RESET; +static int giveup_limit = GIVEUP_LIMIT; static int timeoutsb4reset = TIMEOUTSB4RESET; static int ipi_reset_limit = IPI_RESET_LIMIT; static int complete_threshold = COMPLETE_THRESHOLD; static int congested_respns_us = CONGESTED_RESPONSE_US; static int congested_reps = CONGESTED_REPS; -static int congested_period = CONGESTED_PERIOD; +static int disabled_period = DISABLED_PERIOD; static struct tunables tunables[] = { {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ @@ -64,7 +63,8 @@ static struct tunables tunables[] = { {&complete_threshold, COMPLETE_THRESHOLD}, {&congested_respns_us, CONGESTED_RESPONSE_US}, {&congested_reps, CONGESTED_REPS}, - {&congested_period, CONGESTED_PERIOD} + {&disabled_period, DISABLED_PERIOD}, + {&giveup_limit, GIVEUP_LIMIT} }; static struct dentry *tunables_dir; @@ -313,7 +313,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, * Both sockets dump their completed count total into * the message's count. */ - smaster->socket_acknowledge_count[mdp->msg_slot] = 0; + *sp = 0; asp = (struct atomic_short *)&msg->acknowledge_count; msg_ack_count = atom_asr(socket_ack_count, asp); @@ -526,16 +526,15 @@ static int uv1_wait_completion(struct bau_desc *bau_desc, } /* - * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register. + * UV2 could have an extra bit of status in the ACTIVATION_STATUS_2 register. + * But not currently used. */ static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc) { unsigned long descriptor_status; - unsigned long descriptor_status2; - descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK); - descriptor_status2 = (read_mmr_uv2_status() >> desc) & 0x1UL; - descriptor_status = (descriptor_status << 1) | descriptor_status2; + descriptor_status = + ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK) << 1; return descriptor_status; } @@ -566,87 +565,11 @@ int normal_busy(struct bau_control *bcp) */ int handle_uv2_busy(struct bau_control *bcp) { - int busy_one = bcp->using_desc; - int normal = bcp->uvhub_cpu; - int selected = -1; - int i; - unsigned long descriptor_status; - unsigned long status; - int mmr_offset; - struct bau_desc *bau_desc_old; - struct bau_desc *bau_desc_new; - struct bau_control *hmaster = bcp->uvhub_master; struct ptc_stats *stat = bcp->statp; - cycles_t ttm; stat->s_uv2_wars++; - spin_lock(&hmaster->uvhub_lock); - /* try for the original first */ - if (busy_one != normal) { - if (!normal_busy(bcp)) - selected = normal; - } - if (selected < 0) { - /* can't use the normal, select an alternate */ - mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; - descriptor_status = read_lmmr(mmr_offset); - - /* scan available descriptors 32-63 */ - for (i = 0; i < UV_CPUS_PER_AS; i++) { - if ((hmaster->inuse_map & (1 << i)) == 0) { - status = ((descriptor_status >> - (i * UV_ACT_STATUS_SIZE)) & - UV_ACT_STATUS_MASK) << 1; - if (status != UV2H_DESC_BUSY) { - selected = i + UV_CPUS_PER_AS; - break; - } - } - } - } - - if (busy_one != normal) - /* mark the busy alternate as not in-use */ - hmaster->inuse_map &= ~(1 << (busy_one - UV_CPUS_PER_AS)); - - if (selected >= 0) { - /* switch to the selected descriptor */ - if (selected != normal) { - /* set the selected alternate as in-use */ - hmaster->inuse_map |= - (1 << (selected - UV_CPUS_PER_AS)); - if (selected > stat->s_uv2_wars_hw) - stat->s_uv2_wars_hw = selected; - } - bau_desc_old = bcp->descriptor_base; - bau_desc_old += (ITEMS_PER_DESC * busy_one); - bcp->using_desc = selected; - bau_desc_new = bcp->descriptor_base; - bau_desc_new += (ITEMS_PER_DESC * selected); - *bau_desc_new = *bau_desc_old; - } else { - /* - * All are busy. Wait for the normal one for this cpu to - * free up. - */ - stat->s_uv2_war_waits++; - spin_unlock(&hmaster->uvhub_lock); - ttm = get_cycles(); - do { - cpu_relax(); - } while (normal_busy(bcp)); - spin_lock(&hmaster->uvhub_lock); - /* switch to the original descriptor */ - bcp->using_desc = normal; - bau_desc_old = bcp->descriptor_base; - bau_desc_old += (ITEMS_PER_DESC * bcp->using_desc); - bcp->using_desc = (ITEMS_PER_DESC * normal); - bau_desc_new = bcp->descriptor_base; - bau_desc_new += (ITEMS_PER_DESC * normal); - *bau_desc_new = *bau_desc_old; /* copy the entire descriptor */ - } - spin_unlock(&hmaster->uvhub_lock); - return FLUSH_RETRY_BUSYBUG; + bcp->busy = 1; + return FLUSH_GIVEUP; } static int uv2_wait_completion(struct bau_desc *bau_desc, @@ -655,7 +578,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, { unsigned long descriptor_stat; cycles_t ttm; - int desc = bcp->using_desc; + int desc = bcp->uvhub_cpu; long busy_reps = 0; struct ptc_stats *stat = bcp->statp; @@ -663,24 +586,38 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, /* spin on the status MMR, waiting for it to go idle */ while (descriptor_stat != UV2H_DESC_IDLE) { - /* - * Our software ack messages may be blocked because - * there are no swack resources available. As long - * as none of them has timed out hardware will NACK - * our message and its state will stay IDLE. - */ - if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) || - (descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) { + if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT)) { + /* + * A h/w bug on the destination side may + * have prevented the message being marked + * pending, thus it doesn't get replied to + * and gets continually nacked until it times + * out with a SOURCE_TIMEOUT. + */ stat->s_stimeout++; return FLUSH_GIVEUP; - } else if (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) { - stat->s_strongnacks++; - bcp->conseccompletes = 0; - return FLUSH_GIVEUP; } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { + ttm = get_cycles(); + + /* + * Our retries may be blocked by all destination + * swack resources being consumed, and a timeout + * pending. In that case hardware returns the + * ERROR that looks like a destination timeout. + * Without using the extended status we have to + * deduce from the short time that this was a + * strong nack. + */ + if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { + bcp->conseccompletes = 0; + stat->s_plugged++; + /* FLUSH_RETRY_PLUGGED causes hang on boot */ + return FLUSH_GIVEUP; + } stat->s_dtimeout++; bcp->conseccompletes = 0; - return FLUSH_RETRY_TIMEOUT; + /* FLUSH_RETRY_TIMEOUT causes hang on boot */ + return FLUSH_GIVEUP; } else { busy_reps++; if (busy_reps > 1000000) { @@ -688,9 +625,8 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, busy_reps = 0; ttm = get_cycles(); if ((ttm - bcp->send_message) > - (bcp->clocks_per_100_usec)) { + bcp->timeout_interval) return handle_uv2_busy(bcp); - } } /* * descriptor_stat is still BUSY @@ -714,7 +650,7 @@ static int wait_completion(struct bau_desc *bau_desc, { int right_shift; unsigned long mmr_offset; - int desc = bcp->using_desc; + int desc = bcp->uvhub_cpu; if (desc < UV_CPUS_PER_AS) { mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; @@ -793,33 +729,31 @@ static void destination_timeout(struct bau_desc *bau_desc, } /* - * Completions are taking a very long time due to a congested numalink - * network. + * Stop all cpus on a uvhub from using the BAU for a period of time. + * This is reversed by check_enable. */ -static void disable_for_congestion(struct bau_control *bcp, - struct ptc_stats *stat) +static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) { - /* let only one cpu do this disabling */ - spin_lock(&disable_lock); - - if (!baudisabled && bcp->period_requests && - ((bcp->period_time / bcp->period_requests) > congested_cycles)) { - int tcpu; - struct bau_control *tbcp; - /* it becomes this cpu's job to turn on the use of the - BAU again */ - baudisabled = 1; - bcp->set_bau_off = 1; - bcp->set_bau_on_time = get_cycles(); - bcp->set_bau_on_time += sec_2_cycles(bcp->cong_period); + int tcpu; + struct bau_control *tbcp; + struct bau_control *hmaster; + cycles_t tm1; + + hmaster = bcp->uvhub_master; + spin_lock(&hmaster->disable_lock); + if (!bcp->baudisabled) { stat->s_bau_disabled++; + tm1 = get_cycles(); for_each_present_cpu(tcpu) { tbcp = &per_cpu(bau_control, tcpu); - tbcp->baudisabled = 1; + if (tbcp->uvhub_master == hmaster) { + tbcp->baudisabled = 1; + tbcp->set_bau_on_time = + tm1 + bcp->disabled_period; + } } } - - spin_unlock(&disable_lock); + spin_unlock(&hmaster->disable_lock); } static void count_max_concurr(int stat, struct bau_control *bcp, @@ -850,16 +784,30 @@ static void record_send_stats(cycles_t time1, cycles_t time2, bcp->period_requests++; bcp->period_time += elapsed; if ((elapsed > congested_cycles) && - (bcp->period_requests > bcp->cong_reps)) - disable_for_congestion(bcp, stat); + (bcp->period_requests > bcp->cong_reps) && + ((bcp->period_time / bcp->period_requests) > + congested_cycles)) { + stat->s_congested++; + disable_for_period(bcp, stat); + } } } else stat->s_requestor--; if (completion_status == FLUSH_COMPLETE && try > 1) stat->s_retriesok++; - else if (completion_status == FLUSH_GIVEUP) + else if (completion_status == FLUSH_GIVEUP) { stat->s_giveup++; + if (get_cycles() > bcp->period_end) + bcp->period_giveups = 0; + bcp->period_giveups++; + if (bcp->period_giveups == 1) + bcp->period_end = get_cycles() + bcp->disabled_period; + if (bcp->period_giveups > bcp->giveup_limit) { + disable_for_period(bcp, stat); + stat->s_giveuplimit++; + } + } } /* @@ -903,7 +851,8 @@ static void handle_cmplt(int completion_status, struct bau_desc *bau_desc, * Returns 1 if it gives up entirely and the original cpu mask is to be * returned to the kernel. */ -int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) +int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp, + struct bau_desc *bau_desc) { int seq_number = 0; int completion_stat = 0; @@ -916,24 +865,23 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) struct bau_control *hmaster = bcp->uvhub_master; struct uv1_bau_msg_header *uv1_hdr = NULL; struct uv2_bau_msg_header *uv2_hdr = NULL; - struct bau_desc *bau_desc; - if (bcp->uvhub_version == 1) + if (bcp->uvhub_version == 1) { + uv1 = 1; uv1_throttle(hmaster, stat); + } while (hmaster->uvhub_quiesce) cpu_relax(); time1 = get_cycles(); + if (uv1) + uv1_hdr = &bau_desc->header.uv1_hdr; + else + uv2_hdr = &bau_desc->header.uv2_hdr; + do { - bau_desc = bcp->descriptor_base; - bau_desc += (ITEMS_PER_DESC * bcp->using_desc); - if (bcp->uvhub_version == 1) { - uv1 = 1; - uv1_hdr = &bau_desc->header.uv1_hdr; - } else - uv2_hdr = &bau_desc->header.uv2_hdr; - if ((try == 0) || (completion_stat == FLUSH_RETRY_BUSYBUG)) { + if (try == 0) { if (uv1) uv1_hdr->msg_type = MSG_REGULAR; else @@ -951,25 +899,24 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) uv1_hdr->sequence = seq_number; else uv2_hdr->sequence = seq_number; - index = (1UL << AS_PUSH_SHIFT) | bcp->using_desc; + index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; bcp->send_message = get_cycles(); write_mmr_activation(index); try++; completion_stat = wait_completion(bau_desc, bcp, try); - /* UV2: wait_completion() may change the bcp->using_desc */ handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { bcp->ipi_attempts = 0; + stat->s_overipilimit++; completion_stat = FLUSH_GIVEUP; break; } cpu_relax(); } while ((completion_stat == FLUSH_RETRY_PLUGGED) || - (completion_stat == FLUSH_RETRY_BUSYBUG) || (completion_stat == FLUSH_RETRY_TIMEOUT)); time2 = get_cycles(); @@ -990,28 +937,33 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) } /* - * The BAU is disabled. When the disabled time period has expired, the cpu - * that disabled it must re-enable it. - * Return 0 if it is re-enabled for all cpus. + * The BAU is disabled for this uvhub. When the disabled time period has + * expired re-enable it. + * Return 0 if it is re-enabled for all cpus on this uvhub. */ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) { int tcpu; struct bau_control *tbcp; + struct bau_control *hmaster; - if (bcp->set_bau_off) { - if (get_cycles() >= bcp->set_bau_on_time) { - stat->s_bau_reenabled++; - baudisabled = 0; - for_each_present_cpu(tcpu) { - tbcp = &per_cpu(bau_control, tcpu); + hmaster = bcp->uvhub_master; + spin_lock(&hmaster->disable_lock); + if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { + stat->s_bau_reenabled++; + for_each_present_cpu(tcpu) { + tbcp = &per_cpu(bau_control, tcpu); + if (tbcp->uvhub_master == hmaster) { tbcp->baudisabled = 0; tbcp->period_requests = 0; tbcp->period_time = 0; + tbcp->period_giveups = 0; } - return 0; } + spin_unlock(&hmaster->disable_lock); + return 0; } + spin_unlock(&hmaster->disable_lock); return -1; } @@ -1113,6 +1065,8 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct cpumask *flush_mask; struct ptc_stats *stat; struct bau_control *bcp; + unsigned long descriptor_status; + unsigned long status; bcp = &per_cpu(bau_control, cpu); stat = bcp->statp; @@ -1121,10 +1075,22 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, if (bcp->nobau) return cpumask; + if (bcp->busy) { + descriptor_status = + read_lmmr(UVH_LB_BAU_SB_ACTIVATION_STATUS_0); + status = ((descriptor_status >> (bcp->uvhub_cpu * + UV_ACT_STATUS_SIZE)) & UV_ACT_STATUS_MASK) << 1; + if (status == UV2H_DESC_BUSY) + return cpumask; + bcp->busy = 0; + } + /* bau was disabled due to slow response */ if (bcp->baudisabled) { - if (check_enable(bcp, stat)) + if (check_enable(bcp, stat)) { + stat->s_ipifordisabled++; return cpumask; + } } /* @@ -1140,7 +1106,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, stat->s_ntargself++; bau_desc = bcp->descriptor_base; - bau_desc += (ITEMS_PER_DESC * bcp->using_desc); + bau_desc += (ITEMS_PER_DESC * bcp->uvhub_cpu); bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) return NULL; @@ -1153,25 +1119,27 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, * uv_flush_send_and_wait returns 0 if all cpu's were messaged, * or 1 if it gave up and the original cpumask should be returned. */ - if (!uv_flush_send_and_wait(flush_mask, bcp)) + if (!uv_flush_send_and_wait(flush_mask, bcp, bau_desc)) return NULL; else return cpumask; } /* - * Search the message queue for any 'other' message with the same software - * acknowledge resource bit vector. + * Search the message queue for any 'other' unprocessed message with the + * same software acknowledge resource bit vector as the 'msg' message. */ struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg, - struct bau_control *bcp, unsigned char swack_vec) + struct bau_control *bcp) { struct bau_pq_entry *msg_next = msg + 1; + unsigned char swack_vec = msg->swack_vec; if (msg_next > bcp->queue_last) msg_next = bcp->queue_first; - while ((msg_next->swack_vec != 0) && (msg_next != msg)) { - if (msg_next->swack_vec == swack_vec) + while (msg_next != msg) { + if ((msg_next->canceled == 0) && (msg_next->replied_to == 0) && + (msg_next->swack_vec == swack_vec)) return msg_next; msg_next++; if (msg_next > bcp->queue_last) @@ -1200,32 +1168,30 @@ void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp) * This message was assigned a swack resource, but no * reserved acknowlegment is pending. * The bug has prevented this message from setting the MMR. - * And no other message has used the same sw_ack resource. - * Do the requested shootdown but do not reply to the msg. - * (the 0 means make no acknowledge) */ - bau_process_message(mdp, bcp, 0); - return; - } - - /* - * Some message has set the MMR 'pending' bit; it might have been - * another message. Look for that message. - */ - other_msg = find_another_by_swack(msg, bcp, msg->swack_vec); - if (other_msg) { - /* There is another. Do not ack the current one. */ - bau_process_message(mdp, bcp, 0); /* - * Let the natural processing of that message acknowledge - * it. Don't get the processing of sw_ack's out of order. + * Some message has set the MMR 'pending' bit; it might have + * been another message. Look for that message. */ - return; + other_msg = find_another_by_swack(msg, bcp); + if (other_msg) { + /* + * There is another. Process this one but do not + * ack it. + */ + bau_process_message(mdp, bcp, 0); + /* + * Let the natural processing of that other message + * acknowledge it. Don't get the processing of sw_ack's + * out of order. + */ + return; + } } /* - * There is no other message using this sw_ack, so it is safe to - * acknowledge it. + * Either the MMR shows this one pending a reply or there is no + * other message using this sw_ack, so it is safe to acknowledge it. */ bau_process_message(mdp, bcp, 1); @@ -1330,7 +1296,8 @@ static void __init enable_timeouts(void) */ mmr_image |= (1L << SOFTACK_MSHIFT); if (is_uv2_hub()) { - mmr_image |= (1L << UV2_EXT_SHFT); + /* hw bug workaround; do not use extended status */ + mmr_image &= ~(1L << UV2_EXT_SHFT); } write_mmr_misc_control(pnode, mmr_image); } @@ -1379,24 +1346,26 @@ static int ptc_seq_show(struct seq_file *file, void *data) cpu = *(loff_t *)data; if (!cpu) { seq_printf(file, - "# cpu bauoff sent stime self locals remotes ncpus localhub "); + "# cpu bauoff sent stime self locals remotes ncpus localhub "); seq_printf(file, "remotehub numuvhubs numuvhubs16 numuvhubs8 "); seq_printf(file, - "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries rok "); + "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries "); + seq_printf(file, + "rok resetp resett giveup sto bz throt disable "); seq_printf(file, - "resetp resett giveup sto bz throt enters swack recv rtime "); + "enable wars warshw warwaits enters ipidis plugged "); seq_printf(file, - "all one mult none retry canc nocan reset rcan "); + "ipiover glim cong swack recv rtime all one mult "); seq_printf(file, - "disable enable wars warshw warwaits\n"); + "none retry canc nocan reset rcan\n"); } if (cpu < num_possible_cpus() && cpu_online(cpu)) { bcp = &per_cpu(bau_control, cpu); stat = bcp->statp; /* source side statistics */ seq_printf(file, - "cpu %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", + "cpu %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", cpu, bcp->nobau, stat->s_requestor, cycles_2_us(stat->s_time), stat->s_ntargself, stat->s_ntarglocals, @@ -1407,25 +1376,28 @@ static int ptc_seq_show(struct seq_file *file, void *data) stat->s_ntarguvhub8, stat->s_ntarguvhub4, stat->s_ntarguvhub2, stat->s_ntarguvhub1, stat->s_dtimeout, stat->s_strongnacks); - seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld %ld ", + seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ", stat->s_retry_messages, stat->s_retriesok, stat->s_resets_plug, stat->s_resets_timeout, stat->s_giveup, stat->s_stimeout, - stat->s_busy, stat->s_throttles, stat->s_enters); + stat->s_busy, stat->s_throttles); + seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", + stat->s_bau_disabled, stat->s_bau_reenabled, + stat->s_uv2_wars, stat->s_uv2_wars_hw, + stat->s_uv2_war_waits, stat->s_enters, + stat->s_ipifordisabled, stat->s_plugged, + stat->s_overipilimit, stat->s_giveuplimit, + stat->s_congested); /* destination side statistics */ seq_printf(file, - "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", + "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)), stat->d_requestee, cycles_2_us(stat->d_time), stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, stat->d_nomsg, stat->d_retries, stat->d_canceled, stat->d_nocanceled, stat->d_resets, stat->d_rcanceled); - seq_printf(file, "%ld %ld %ld %ld %ld\n", - stat->s_bau_disabled, stat->s_bau_reenabled, - stat->s_uv2_wars, stat->s_uv2_wars_hw, - stat->s_uv2_war_waits); } return 0; } @@ -1439,13 +1411,14 @@ static ssize_t tunables_read(struct file *file, char __user *userbuf, char *buf; int ret; - buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", - "max_concur plugged_delay plugsb4reset", - "timeoutsb4reset ipi_reset_limit complete_threshold", - "congested_response_us congested_reps congested_period", + buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d %d\n", + "max_concur plugged_delay plugsb4reset timeoutsb4reset", + "ipi_reset_limit complete_threshold congested_response_us", + "congested_reps disabled_period giveup_limit", max_concurr, plugged_delay, plugsb4reset, timeoutsb4reset, ipi_reset_limit, complete_threshold, - congested_respns_us, congested_reps, congested_period); + congested_respns_us, congested_reps, disabled_period, + giveup_limit); if (!buf) return -ENOMEM; @@ -1616,7 +1589,8 @@ static ssize_t tunables_write(struct file *file, const char __user *user, bcp->complete_threshold = complete_threshold; bcp->cong_response_us = congested_respns_us; bcp->cong_reps = congested_reps; - bcp->cong_period = congested_period; + bcp->disabled_period = sec_2_cycles(disabled_period); + bcp->giveup_limit = giveup_limit; } return count; } @@ -1745,6 +1719,10 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) * fairness chaining multilevel count replied_to */ } else { + /* + * BIOS uses legacy mode, but UV2 hardware always + * uses native mode for selective broadcasts. + */ uv2_hdr = &bd2->header.uv2_hdr; uv2_hdr->swack_flag = 1; uv2_hdr->base_dest_nasid = @@ -1896,10 +1874,11 @@ static void __init init_per_cpu_tunables(void) bcp->complete_threshold = complete_threshold; bcp->cong_response_us = congested_respns_us; bcp->cong_reps = congested_reps; - bcp->cong_period = congested_period; - bcp->clocks_per_100_usec = usec_2_cycles(100); + bcp->disabled_period = sec_2_cycles(disabled_period); + bcp->giveup_limit = giveup_limit; spin_lock_init(&bcp->queue_lock); spin_lock_init(&bcp->uvhub_lock); + spin_lock_init(&bcp->disable_lock); } } @@ -2020,7 +1999,6 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp, } bcp->uvhub_master = *hmasterp; bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; - bcp->using_desc = bcp->uvhub_cpu; if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { printk(KERN_EMERG "%d cpus per uvhub invalid\n", bcp->uvhub_cpu); @@ -2123,7 +2101,6 @@ static int __init uv_bau_init(void) } nuvhubs = uv_num_possible_blades(); - spin_lock_init(&disable_lock); congested_cycles = usec_2_cycles(congested_respns_us); uv_base_pnode = 0x7fffffff; -- GitLab From b3a6d2e0e727c3b126093c9b5fcdf41dd12bc4fd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jun 2012 15:57:55 +0200 Subject: [PATCH 2711/6849] iwlwifi: limit dwell time more strictly The dwell time for scanning is currently limited so that it fits into the timings inside the ucode when that is tracking DTIM/beacon periods for the AP(s) it's connected to. However, when it's connected to two APs, those may be in lockstep, for example if they both have a DTIM interval of 100 TU, then one could be 50 TU after the other, leaving only 50 TU free to be used by scanning. Since we can't know how far apart they are the only option is to restrict to 1/2 of the minium of the two APs. In theory, it would be possible to not use 1/2 of the minimum but take into account that if they have different intervals then there will be a bit more time since they can't be in lockstep, but as they will have 100 TU intervals in practice that complex calculation will probably just result in hard-to-find bugs. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/scan.c | 37 ++++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 6633074258c7..e3467fa86899 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -396,15 +396,21 @@ static u16 iwl_get_active_dwell_time(struct iwl_priv *priv, static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) { struct iwl_rxon_context *ctx; + int limits[NUM_IWL_RXON_CTX] = {}; + int n_active = 0; + u16 limit; + + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); /* * If we're associated, we clamp the dwell time 98% - * of the smallest beacon interval (minus 2 * channel - * tune time) + * of the beacon interval (minus 2 * channel tune time) + * If both contexts are active, we have to restrict to + * 1/2 of the minimum of them, because they might be in + * lock-step with the time inbetween only half of what + * time we'd have in each of them. */ for_each_context(priv, ctx) { - u16 value; - switch (ctx->staging.dev_type) { case RXON_DEV_TYPE_P2P: /* no timing constraints */ @@ -424,14 +430,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) break; } - value = ctx->beacon_int; - if (!value) - value = IWL_PASSIVE_DWELL_BASE; - value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; - dwell_time = min(value, dwell_time); + limits[n_active++] = ctx->beacon_int ?: IWL_PASSIVE_DWELL_BASE; } - return dwell_time; + switch (n_active) { + case 0: + return dwell_time; + case 2: + limit = (limits[1] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + limit /= 2; + dwell_time = min(limit, dwell_time); + /* fall through to limit further */ + case 1: + limit = (limits[0] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + limit /= n_active; + return min(limit, dwell_time); + default: + WARN_ON_ONCE(1); + return dwell_time; + } } static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, -- GitLab From 020c876738bf6ea55687543bfd2c0227ddbd3126 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 24 Jun 2012 15:51:59 +0300 Subject: [PATCH 2712/6849] iwlwifi: disable the watchdog for queues by default I saw that when the watchdog triggers, the packets do go through if we wait enough time. So we still have an issue where packets are blocked in the Tx queue for a short while and this needs to be debugged separately. For now, don't restart the driver when it is not needed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 095547b37a27..6322e2a692cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1011,6 +1011,7 @@ struct iwl_mod_params iwlwifi_mod_params = { .power_level = IWL_POWER_INDEX_1, .bt_ch_announce = true, .auto_agg = true, + .wd_disable = true, /* the rest are 0 by default */ }; EXPORT_SYMBOL_GPL(iwlwifi_mod_params); -- GitLab From e75561b3d2a4eb15080ed73f59f7dc2965c01423 Mon Sep 17 00:00:00 2001 From: Yufeng Shen Date: Fri, 22 Jun 2012 12:31:53 -0400 Subject: [PATCH 2713/6849] HID: magicmouse: Correct report range of major / minor axes In patch "HID: magicmouse: Adjust major / minor axes to scale", touch_major and touch_minor axes are scaled by a factor of four when reported but the max touch_major/minor is not scaled accordingly. This patch scales the max touch_major/minor to be consistent with the reported value. Signed-off-by: Yufeng Shen Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 7cf3ffe4b7bc..40ac6654f1d1 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -426,8 +426,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_ABS, input->evbit); input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, + 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, + 4, 0); input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); /* Note: Touch Y position from the device is inverted relative -- GitLab From bb9a80e5719abae235c7e9c7391a3a17b64a217b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 22 Jun 2012 12:07:25 -0700 Subject: [PATCH 2714/6849] hwmon: Update my e-mail address My old e-mail address won't be valid for much longer. Time to update it. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/jc42.c | 2 +- drivers/hwmon/lineage-pem.c | 2 +- drivers/hwmon/ltc4261.c | 2 +- drivers/hwmon/max16065.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index a9bfd6736d9a..e72ba5d2a824 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -590,6 +590,6 @@ abort: module_i2c_driver(jc42_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("JC42 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c index d264937c7f5e..bd75d2415432 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -567,6 +567,6 @@ static struct i2c_driver pem_driver = { module_i2c_driver(pem_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 069b7d34d8f9..77476a575c4e 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -292,6 +292,6 @@ static struct i2c_driver ltc4261_driver = { module_i2c_driver(ltc4261_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("LTC4261 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index 822261be84dd..019427d7a5fd 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -692,6 +692,6 @@ static struct i2c_driver max16065_driver = { module_i2c_driver(max16065_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("MAX16065 driver"); MODULE_LICENSE("GPL"); -- GitLab From 9be2395186b3504aa5e337bd3284afb4966caae7 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Jun 2012 17:09:28 +0300 Subject: [PATCH 2715/6849] usb: dwc3: gadget: remove duplicated code from __dwc3_gadget_ep_set_halt whenever we want to stall ep0, we always call dwc3_ep0_stall_and_restart() which makes sure to send ep0state properly rendering the code in __dwc3_gadget_ep_set_halt() duplicated. Reported-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1b5fbdd859c2..d98549a7b8b0 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1209,15 +1209,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) memset(¶ms, 0x00, sizeof(params)); if (value) { - if (dep->number == 0 || dep->number == 1) { - /* - * Whenever EP0 is stalled, we will restart - * the state machine, thus moving back to - * Setup Phase - */ - dwc->ep0state = EP0_SETUP_PHASE; - } - ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_SETSTALL, ¶ms); if (ret) -- GitLab From d0f718c1c0dfcb67f3af47a1fc4de7784974d1f7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Jun 2012 14:46:44 +0200 Subject: [PATCH 2716/6849] mac80211_hwsim: fix smatch/sparse complaints The code is fine in both cases as-is, but we can write it slightly differently to fix smatch/sparse complaints: * compare the skb pointer (which we use as a cookie) by casting the skb to unsigned long rather than the cookie to a pointer (fixes "different address spaces") * when transmitting, data->channel must be assigned, don't check it (fixes "dereferenced before check") Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4c9336cee817..eacfe020d0b7 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -678,8 +678,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, continue; if (data2->idle || !data2->started || - !hwsim_ps_rx_ok(data2, skb) || - !data->channel || !data2->channel || + !hwsim_ps_rx_ok(data2, skb) || !data2->channel || data->channel->center_freq != data2->channel->center_freq || !(data->group & data2->group)) continue; @@ -1486,7 +1485,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, struct mac80211_hwsim_data *data2; struct ieee80211_tx_info *txi; struct hwsim_tx_rate *tx_attempts; - struct sk_buff __user *ret_skb; + unsigned long ret_skb_ptr; struct sk_buff *skb, *tmp; struct mac_address *src; unsigned int hwsim_flags; @@ -1504,8 +1503,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]); - ret_skb = (struct sk_buff __user *) - (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); + ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); data2 = get_hwsim_data_ref_from_addr(src); @@ -1514,7 +1512,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, /* look for the skb matching the cookie passed back from user */ skb_queue_walk_safe(&data2->pending, skb, tmp) { - if (skb == ret_skb) { + if ((unsigned long)skb == ret_skb_ptr) { skb_unlink(skb, &data2->pending); found = true; break; -- GitLab From 67de956ff5dc1d4f321e16cfbd63f5be3b691b43 Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Mon, 25 Jun 2012 16:05:27 +0200 Subject: [PATCH 2717/6849] NFC: Prevent multiple buffer overflows in NCI Fix multiple remotely-exploitable stack-based buffer overflows due to the NCI code pulling length fields directly from incoming frames and copying too much data into statically-sized arrays. Signed-off-by: Dan Rosenberg Cc: stable@kernel.org Cc: security@kernel.org Cc: Lauro Ramos Venancio Cc: Aloisio Almeida Jr Cc: Samuel Ortiz Cc: David S. Miller Acked-by: Ilan Elias Signed-off-by: Samuel Ortiz --- net/nfc/nci/ntf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index cb2646179e5f..2ab196a9f228 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -106,7 +106,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); data += 2; - nfca_poll->nfcid1_len = *data++; + nfca_poll->nfcid1_len = min_t(__u8, *data++, NFC_NFCID1_MAXSIZE); pr_debug("sens_res 0x%x, nfcid1_len %d\n", nfca_poll->sens_res, nfca_poll->nfcid1_len); @@ -130,7 +130,7 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcb_poll *nfcb_poll, __u8 *data) { - nfcb_poll->sensb_res_len = *data++; + nfcb_poll->sensb_res_len = min_t(__u8, *data++, NFC_SENSB_RES_MAXSIZE); pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); @@ -145,7 +145,7 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, __u8 *data) { nfcf_poll->bit_rate = *data++; - nfcf_poll->sensf_res_len = *data++; + nfcf_poll->sensf_res_len = min_t(__u8, *data++, NFC_SENSF_RES_MAXSIZE); pr_debug("bit_rate %d, sensf_res_len %d\n", nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); @@ -331,7 +331,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, switch (ntf->activation_rf_tech_and_mode) { case NCI_NFC_A_PASSIVE_POLL_MODE: nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; - nfca_poll->rats_res_len = *data++; + nfca_poll->rats_res_len = min_t(__u8, *data++, 20); pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); if (nfca_poll->rats_res_len > 0) { memcpy(nfca_poll->rats_res, @@ -341,7 +341,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, case NCI_NFC_B_PASSIVE_POLL_MODE: nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; - nfcb_poll->attrib_res_len = *data++; + nfcb_poll->attrib_res_len = min_t(__u8, *data++, 50); pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); if (nfcb_poll->attrib_res_len > 0) { memcpy(nfcb_poll->attrib_res, -- GitLab From 1f41a6a9947615dca37d80b044ab81616e956a67 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 25 Jun 2012 16:55:41 +0200 Subject: [PATCH 2718/6849] HID: Fix the generic Kconfig options The generic HID driver is obviously not a special driver, so move it outside of the special drivers menu. Explain the usage and make the default follow the HID setting. This should simplify migration from older kernels. While at it, remove the redundant HID_SUPPORT option and modify the HID and USB_HID entries to better explain the bus structure. Reported-by: Jan Beulich Signed-off-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 43 ++++++++++++++++++-------------------- drivers/hid/usbhid/Kconfig | 8 +++---- net/bluetooth/hidp/Kconfig | 2 +- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e9c68fedfcff..3089cd6c5755 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1,20 +1,11 @@ # # HID driver configuration # -menuconfig HID_SUPPORT - bool "HID Devices" - depends on INPUT - default y - ---help--- - Say Y here to get to see options for various computer-human interface - device drivers. This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if HID_SUPPORT +menu "HID support" + depends on INPUT config HID - tristate "Generic HID support" + tristate "HID bus support" depends on INPUT default y ---help--- @@ -23,14 +14,17 @@ config HID most commonly used to refer to the USB-HID specification, but other devices (such as, but not strictly limited to, Bluetooth) are designed using HID specification (this involves certain keyboards, - mice, tablets, etc). This option compiles into kernel the generic - HID layer code (parser, usages, etc.), which can then be used by - transport-specific HID implementation (like USB or Bluetooth). + mice, tablets, etc). This option adds the HID bus to the kernel, + together with generic HID layer code. The HID devices are added and + removed from the HID bus by the transport-layer drivers, such as + usbhid (USB_HID) and hidp (BT_HIDP). For docs and specs, see http://www.usb.org/developers/hidpage/ If unsure, say Y. +if HID + config HID_BATTERY_STRENGTH bool "Battery level reporting for HID devices" depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY @@ -59,23 +53,22 @@ config HIDRAW If unsure, say Y. -source "drivers/hid/usbhid/Kconfig" - -menu "Special HID drivers" - depends on HID - config HID_GENERIC tristate "Generic HID driver" depends on HID - default y + default HID ---help--- - Support for generic HID devices. + Support for generic devices on the HID bus. This includes most + keyboards and mice, joysticks, tablets and digitizers. To compile this driver as a module, choose M here: the module will be called hid-generic. If unsure, say Y. +menu "Special HID drivers" + depends on HID + config HID_A4TECH tristate "A4 tech mice" if EXPERT depends on USB_HID @@ -662,4 +655,8 @@ config HID_ZYDACRON endmenu -endif # HID_SUPPORT +endif # HID + +source "drivers/hid/usbhid/Kconfig" + +endmenu diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index 0f20fd17cf06..0108c5991a04 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig @@ -1,13 +1,13 @@ -comment "USB Input Devices" +menu "USB HID support" depends on USB config USB_HID - tristate "USB Human Interface Device (full HID) support" + tristate "USB HID transport layer" default y depends on USB && INPUT select HID ---help--- - Say Y here if you want full HID support to connect USB keyboards, + Say Y here if you want to connect USB keyboards, mice, joysticks, graphic tablets, or any other HID based devices to your computer via USB, as well as Uninterruptible Power Supply (UPS) and monitor control devices. @@ -81,4 +81,4 @@ config USB_MOUSE endmenu - +endmenu diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 4deaca78e91e..9332bc7aa851 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig @@ -1,6 +1,6 @@ config BT_HIDP tristate "HIDP protocol support" - depends on BT && INPUT && HID_SUPPORT + depends on BT && INPUT select HID help HIDP (Human Interface Device Protocol) is a transport layer -- GitLab From 4ad33411308596f2f918603509729922a1ec4411 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 22 Jun 2012 10:58:06 -0700 Subject: [PATCH 2719/6849] x86, cpufeature: Rename X86_FEATURE_DTS to X86_FEATURE_DTHERM It makes sense to label "Digital Thermal Sensor" as "DTS", but unfortunately the string "dts" was already used for "Debug Store", and /proc/cpuinfo is a user space ABI. Therefore, rename this to "dtherm". This conflict went into mainline via the hwmon tree without any x86 maintainer ack, and without any kind of hint in the subject. a4659053 x86/hwmon: fix initialization of coretemp Reported-by: Jean Delvare Link: http://lkml.kernel.org/r/4FE34BCB.5050305@linux.intel.com Cc: Jan Beulich Cc: v2.6.36..v3.4 Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cpufeature.h | 2 +- arch/x86/kernel/cpu/scattered.c | 2 +- drivers/hwmon/coretemp.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 340ee49961a6..f91e80f4f180 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -176,7 +176,7 @@ #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ -#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ +#define X86_FEATURE_DTHERM (7*32+ 7) /* Digital Thermal Sensor */ #define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */ /* Virtualization flags: Linux defined, word 8 */ diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index addf9e82a7f2..ee8e9abc859f 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -31,7 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { - { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, + { X86_FEATURE_DTHERM, CR_EAX, 0, 0x00000006, 0 }, { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index b9d512331ed4..0f52799973d4 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -664,7 +664,7 @@ static void __cpuinit get_core_online(unsigned int cpu) * sensors. We check this bit only, all the early CPUs * without thermal sensors will be filtered out. */ - if (!cpu_has(c, X86_FEATURE_DTS)) + if (!cpu_has(c, X86_FEATURE_DTHERM)) return; if (!pdev) { @@ -765,7 +765,7 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { }; static const struct x86_cpu_id coretemp_ids[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, {} }; MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); -- GitLab From 55f6cb9d0b364e7e8cb65b51193f5e4743c44fde Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 22 Jun 2012 11:47:15 -0700 Subject: [PATCH 2720/6849] x86, cpufeature: Catch duplicate CPU feature strings We had a case of duplicate CPU feature strings, a user space ABI violation, for almost two years. Make it a build error so that doesn't happen again. Link: http://lkml.kernel.org/r/4FE34BCB.5050305@linux.intel.com Cc: Jan Beulich Cc: Jean Delvare --- arch/x86/kernel/cpu/mkcapflags.pl | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/mkcapflags.pl b/arch/x86/kernel/cpu/mkcapflags.pl index dfea390e1608..0c5b54919c7b 100644 --- a/arch/x86/kernel/cpu/mkcapflags.pl +++ b/arch/x86/kernel/cpu/mkcapflags.pl @@ -11,22 +11,35 @@ open(OUT, "> $out\0") or die "$0: cannot create: $out: $!\n"; print OUT "#include \n\n"; print OUT "const char * const x86_cap_flags[NCAPINTS*32] = {\n"; +%features = (); +$err = 0; + while (defined($line = )) { if ($line =~ /^\s*\#\s*define\s+(X86_FEATURE_(\S+))\s+(.*)$/) { $macro = $1; - $feature = $2; + $feature = "\L$2"; $tail = $3; if ($tail =~ /\/\*\s*\"([^"]*)\".*\*\//) { - $feature = $1; + $feature = "\L$1"; } - if ($feature ne '') { - printf OUT "\t%-32s = \"%s\",\n", - "[$macro]", "\L$feature"; + next if ($feature eq ''); + + if ($features{$feature}++) { + print STDERR "$in: duplicate feature name: $feature\n"; + $err++; } + printf OUT "\t%-32s = \"%s\",%s\n", "[$macro]", $feature; } } print OUT "};\n"; close(IN); close(OUT); + +if ($err) { + unlink($out); + exit(1); +} + +exit(0); -- GitLab From 5c81ababecd7ddae08ca944a65d8030cd393013c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Jun 2012 19:30:49 +0300 Subject: [PATCH 2721/6849] usb: dwc3: ep0: prevent starting transfers twice on ep0 In case we try to start an invalid test mode, we will call dwc3_ep0_stall_and_restart() but we will also call dwc3_ep0_out_start() which will start a second transfer on ep0. Let's prevent any problems by returning early in the error case. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9a8f26cef0a1..8244eb53082e 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -744,6 +744,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc, dev_dbg(dwc->dev, "Invalid Test #%d\n", dwc->test_mode_nr); dwc3_ep0_stall_and_restart(dwc); + return; } } -- GitLab From c90e3e80b9751335cc98934ae32188fa7de6bccd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 24 Jun 2012 21:35:29 -0700 Subject: [PATCH 2722/6849] staging: reduce stack usage in prism2fw.c Fix frame size (stack usage) warning by allocating and freeing pointers to the data. drivers/staging/wlan-ng/prism2fw.c:1115:1: warning: the frame size of 4288 bytes is larger than 2048 bytes Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2fw.c | 124 ++++++++++++++++------------- 1 file changed, 69 insertions(+), 55 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index f13cdc9ab412..66c9aa972310 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -982,9 +982,8 @@ int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, unsigned int nfchunks) { int result = 0; - struct p80211msg_p2req_ramdl_state rstatemsg; - struct p80211msg_p2req_ramdl_write rwritemsg; - struct p80211msg *msgp; + struct p80211msg_p2req_ramdl_state *rstmsg; + struct p80211msg_p2req_ramdl_write *rwrmsg; u32 resultcode; int i; int j; @@ -993,57 +992,68 @@ int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, u32 currlen; u32 currdaddr; + rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL); + rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL); + if (!rstmsg || !rwrmsg) { + kfree(rstmsg); + kfree(rwrmsg); + printk(KERN_ERR + "writeimage: no memory for firmware download, " + "aborting download\n"); + return -ENOMEM; + } + /* Initialize the messages */ - memset(&rstatemsg, 0, sizeof(rstatemsg)); - strcpy(rstatemsg.devname, wlandev->name); - rstatemsg.msgcode = DIDmsg_p2req_ramdl_state; - rstatemsg.msglen = sizeof(rstatemsg); - rstatemsg.enable.did = DIDmsg_p2req_ramdl_state_enable; - rstatemsg.exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr; - rstatemsg.resultcode.did = DIDmsg_p2req_ramdl_state_resultcode; - rstatemsg.enable.status = P80211ENUM_msgitem_status_data_ok; - rstatemsg.exeaddr.status = P80211ENUM_msgitem_status_data_ok; - rstatemsg.resultcode.status = P80211ENUM_msgitem_status_no_value; - rstatemsg.enable.len = sizeof(u32); - rstatemsg.exeaddr.len = sizeof(u32); - rstatemsg.resultcode.len = sizeof(u32); - - memset(&rwritemsg, 0, sizeof(rwritemsg)); - strcpy(rwritemsg.devname, wlandev->name); - rwritemsg.msgcode = DIDmsg_p2req_ramdl_write; - rwritemsg.msglen = sizeof(rwritemsg); - rwritemsg.addr.did = DIDmsg_p2req_ramdl_write_addr; - rwritemsg.len.did = DIDmsg_p2req_ramdl_write_len; - rwritemsg.data.did = DIDmsg_p2req_ramdl_write_data; - rwritemsg.resultcode.did = DIDmsg_p2req_ramdl_write_resultcode; - rwritemsg.addr.status = P80211ENUM_msgitem_status_data_ok; - rwritemsg.len.status = P80211ENUM_msgitem_status_data_ok; - rwritemsg.data.status = P80211ENUM_msgitem_status_data_ok; - rwritemsg.resultcode.status = P80211ENUM_msgitem_status_no_value; - rwritemsg.addr.len = sizeof(u32); - rwritemsg.len.len = sizeof(u32); - rwritemsg.data.len = WRITESIZE_MAX; - rwritemsg.resultcode.len = sizeof(u32); + memset(rstmsg, 0, sizeof(*rstmsg)); + strcpy(rstmsg->devname, wlandev->name); + rstmsg->msgcode = DIDmsg_p2req_ramdl_state; + rstmsg->msglen = sizeof(*rstmsg); + rstmsg->enable.did = DIDmsg_p2req_ramdl_state_enable; + rstmsg->exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr; + rstmsg->resultcode.did = DIDmsg_p2req_ramdl_state_resultcode; + rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok; + rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok; + rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value; + rstmsg->enable.len = sizeof(u32); + rstmsg->exeaddr.len = sizeof(u32); + rstmsg->resultcode.len = sizeof(u32); + + memset(rwrmsg, 0, sizeof(*rwrmsg)); + strcpy(rwrmsg->devname, wlandev->name); + rwrmsg->msgcode = DIDmsg_p2req_ramdl_write; + rwrmsg->msglen = sizeof(*rwrmsg); + rwrmsg->addr.did = DIDmsg_p2req_ramdl_write_addr; + rwrmsg->len.did = DIDmsg_p2req_ramdl_write_len; + rwrmsg->data.did = DIDmsg_p2req_ramdl_write_data; + rwrmsg->resultcode.did = DIDmsg_p2req_ramdl_write_resultcode; + rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok; + rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok; + rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok; + rwrmsg->resultcode.status = P80211ENUM_msgitem_status_no_value; + rwrmsg->addr.len = sizeof(u32); + rwrmsg->len.len = sizeof(u32); + rwrmsg->data.len = WRITESIZE_MAX; + rwrmsg->resultcode.len = sizeof(u32); /* Send xxx_state(enable) */ pr_debug("Sending dl_state(enable) message.\n"); - rstatemsg.enable.data = P80211ENUM_truth_true; - rstatemsg.exeaddr.data = startaddr; + rstmsg->enable.data = P80211ENUM_truth_true; + rstmsg->exeaddr.data = startaddr; - msgp = (struct p80211msg *) &rstatemsg; - result = prism2mgmt_ramdl_state(wlandev, msgp); + result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { printk(KERN_ERR "writeimage state enable failed w/ result=%d, " "aborting download\n", result); - return result; + goto free_result; } - resultcode = rstatemsg.resultcode.data; + resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { printk(KERN_ERR "writeimage()->xxxdl_state msg indicates failure, " "w/ resultcode=%d, aborting download.\n", resultcode); - return 1; + result = 1; + goto free_result; } /* Now, loop through the data chunks and send WRITESIZE_MAX data */ @@ -1061,9 +1071,9 @@ int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, curroff = j * WRITESIZE_MAX; currdaddr = fchunk[i].addr + curroff; /* Setup the message */ - rwritemsg.addr.data = currdaddr; - rwritemsg.len.data = currlen; - memcpy(rwritemsg.data.data, + rwrmsg->addr.data = currdaddr; + rwrmsg->len.data = currlen; + memcpy(rwrmsg->data.data, fchunk[i].data + curroff, currlen); /* Send flashdl_write(pda) */ @@ -1071,23 +1081,23 @@ int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, ("Sending xxxdl_write message addr=%06x len=%d.\n", currdaddr, currlen); - msgp = (struct p80211msg *) &rwritemsg; - result = prism2mgmt_ramdl_write(wlandev, msgp); + result = prism2mgmt_ramdl_write(wlandev, rwrmsg); /* Check the results */ if (result) { printk(KERN_ERR "writeimage chunk write failed w/ result=%d, " "aborting download\n", result); - return result; + goto free_result; } - resultcode = rstatemsg.resultcode.data; + resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { printk(KERN_ERR "writeimage()->xxxdl_write msg indicates failure, " "w/ resultcode=%d, aborting download.\n", resultcode); - return 1; + result = 1; + goto free_result; } } @@ -1095,24 +1105,28 @@ int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, /* Send xxx_state(disable) */ pr_debug("Sending dl_state(disable) message.\n"); - rstatemsg.enable.data = P80211ENUM_truth_false; - rstatemsg.exeaddr.data = 0; + rstmsg->enable.data = P80211ENUM_truth_false; + rstmsg->exeaddr.data = 0; - msgp = (struct p80211msg *) &rstatemsg; - result = prism2mgmt_ramdl_state(wlandev, msgp); + result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { printk(KERN_ERR "writeimage state disable failed w/ result=%d, " "aborting download\n", result); - return result; + goto free_result; } - resultcode = rstatemsg.resultcode.data; + resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { printk(KERN_ERR "writeimage()->xxxdl_state msg indicates failure, " "w/ resultcode=%d, aborting download.\n", resultcode); - return 1; + result = 1; + goto free_result; } + +free_result: + kfree(rstmsg); + kfree(rwrmsg); return result; } -- GitLab From 6e2361720b9da9ec830d407da058ca1827e62b12 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Mon, 25 Jun 2012 11:14:36 -0500 Subject: [PATCH 2723/6849] staging: zram/zcache: swtich Kconfig dependency from X86 to ZSMALLOC This patch switches zcache and zram dependency to ZSMALLOC rather than X86. There is no net change since ZSMALLOC depends on X86, however, this prevent further changes to these files as zsmalloc dependencies change. Signed-off-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 5 +---- drivers/staging/zram/Kconfig | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 7048e01f0817..4881839be625 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -1,9 +1,6 @@ config ZCACHE bool "Dynamic compression of swap pages and clean pagecache pages" - # X86 dependency is because zsmalloc uses non-portable pte/tlb - # functions - depends on (CLEANCACHE || FRONTSWAP) && CRYPTO=y && X86 - select ZSMALLOC + depends on (CLEANCACHE || FRONTSWAP) && CRYPTO=y && ZSMALLOC=y select CRYPTO_LZO default n help diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index 9d11a4cb99b7..be5abe8e7943 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -1,9 +1,6 @@ config ZRAM tristate "Compressed RAM block device support" - # X86 dependency is because zsmalloc uses non-portable pte/tlb - # functions - depends on BLOCK && SYSFS && X86 - select ZSMALLOC + depends on BLOCK && SYSFS && ZSMALLOC select LZO_COMPRESS select LZO_DECOMPRESS default n -- GitLab From 09682c1dd3820445a27d32dcbeee6a6eafff3dc9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 25 Jun 2012 17:15:31 +0900 Subject: [PATCH 2724/6849] bug.h: Fix up CONFIG_BUG=n implicit function declarations. Commit 2603efa31a03 ("bug.h: Fix up powerpc build regression") corrected the powerpc build case and extended the __ASSEMBLY__ guards, but it also got caught in pre-processor hell accidentally matching the else case of CONFIG_BUG resulting in the BUG disabled case tripping up on -Werror=implicit-function-declaration. It's not possible to __ASSEMBLY__ guard the entire file as architecture code needs to get at the BUGFLAG_WARNING definition in the GENERIC_BUG case, but the rest of the CONFIG_BUG=y/n case needs to be guarded. Rather than littering endless __ASSEMBLY__ checks in each of the if/else cases we just move the BUGFLAG definitions up under their own GENERIC_BUG test and then shove everything else under one big __ASSEMBLY__ guard. Build tested on all of x86 CONFIG_BUG=y, CONFIG_BUG=n, powerpc (due to it's dependence on BUGFLAG definitions in assembly code), and sh (due to not bringing in linux/kernel.h to satisfy the taint flag definitions used by the generic bug code). Hopefully that's the end of the corner cases and I can abstain from ever having to touch this infernal header ever again. Reported-by: Fengguang Wu Tested-by: Fengguang Wu Acked-by: Randy Dunlap Cc: Arnd Bergmann Signed-off-by: Paul Mundt Signed-off-by: Linus Torvalds --- include/asm-generic/bug.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 506ec19a3736..7d10f962aa13 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -3,10 +3,18 @@ #include +#ifdef CONFIG_GENERIC_BUG +#define BUGFLAG_WARNING (1 << 0) +#define BUGFLAG_TAINT(taint) (BUGFLAG_WARNING | ((taint) << 8)) +#define BUG_GET_TAINT(bug) ((bug)->flags >> 8) +#endif + +#ifndef __ASSEMBLY__ +#include + #ifdef CONFIG_BUG #ifdef CONFIG_GENERIC_BUG -#ifndef __ASSEMBLY__ struct bug_entry { #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS unsigned long bug_addr; @@ -23,17 +31,8 @@ struct bug_entry { #endif unsigned short flags; }; -#endif /* __ASSEMBLY__ */ - -#define BUGFLAG_WARNING (1 << 0) -#define BUGFLAG_TAINT(taint) (BUGFLAG_WARNING | ((taint) << 8)) -#define BUG_GET_TAINT(bug) ((bug)->flags >> 8) - #endif /* CONFIG_GENERIC_BUG */ -#ifndef __ASSEMBLY__ -#include - /* * Don't use BUG() or BUG_ON() unless there's really no way out; one * example might be detecting data structure corruption in the middle -- GitLab From 7756d3e8b0acff580aab1f60c30e066e20a9900e Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 25 Jun 2012 07:28:25 -0700 Subject: [PATCH 2725/6849] staging: sm7xxfb: Fix typos in sm7xxfb The below patch fixes some typos found in staging "sm7xxfb" while reading through. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xxfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 21dab346253a..32111a011f66 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -351,7 +351,7 @@ static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, case FB_VISUAL_DIRECTCOLOR: case FB_VISUAL_TRUECOLOR: /* - * 16/32 bit true-colour, use pseuo-palette for 16 base color + * 16/32 bit true-colour, use pseudo-palette for 16 base color */ if (regno < 16) { if (sfb->fb.var.bits_per_pixel == 16) { @@ -996,7 +996,7 @@ static int smtcfb_pci_suspend(struct device *device) sfb = pci_get_drvdata(pdev); - /* set the hw in sleep mode use externel clock and self memory refresh + /* set the hw in sleep mode use external clock and self memory refresh * so that we can turn off internal PLLs later on */ smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0)); -- GitLab From db1db294d9366e95a76f4ca7e6442240eba67a0a Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Mon, 25 Jun 2012 17:15:44 +0200 Subject: [PATCH 2726/6849] Staging: ipack/devices/ipoctal: fix oops when accessing "buffer" The buffer[][] field was replaced by tty_port->xmit_buf field but there was some places that "buffer" was still accessed, giving a kernel oops because it was uninitialized. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 29214677ea0c..7fe1c932276b 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -46,7 +46,6 @@ struct ipoctal { struct scc2698_channel *chan_regs; struct scc2698_block *block_regs; struct ipoctal_stats chan_stats[NR_CHANNELS]; - char *buffer[NR_CHANNELS]; unsigned int nb_bytes[NR_CHANNELS]; unsigned int count_wr[NR_CHANNELS]; wait_queue_head_t queue[NR_CHANNELS]; @@ -305,7 +304,7 @@ static int ipoctal_irq_handler(void *arg) continue; } spin_lock(&ipoctal->lock[channel]); - value = ipoctal->buffer[channel][*pointer_write]; + value = ipoctal->tty_port[channel].xmit_buf[*pointer_write]; ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.thr, value); -- GitLab From 55c0a6f470517918a996a525325db6a88435c298 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Mon, 25 Jun 2012 17:15:45 +0200 Subject: [PATCH 2727/6849] Staging: ipack/devices/ipoctal: remove unneeded includes Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 7fe1c932276b..b11126dfc006 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -13,16 +13,12 @@ #include #include -#include #include -#include -#include #include #include #include #include #include -#include #include #include "../ipack.h" #include "ipoctal.h" -- GitLab From bae8bd165ae3fee0573eb7eb377a479cf26e4277 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Mon, 25 Jun 2012 17:15:46 +0200 Subject: [PATCH 2728/6849] Staging: ipack/bridges/tpci200: remove unneeded lock in irq handler Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 5 ----- drivers/staging/ipack/bridges/tpci200.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index ae9f803db292..2b83fa8e550a 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -302,13 +302,10 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) { struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; int i; - unsigned long flags; unsigned short status_reg, reg_value; unsigned short unhandled_ints = 0; irqreturn_t ret = IRQ_NONE; - spin_lock_irqsave(&tpci200->info->access_lock, flags); - /* Read status register */ status_reg = readw(tpci200->info->interface_regs + TPCI200_STATUS_REG); @@ -351,7 +348,6 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) } } - spin_unlock_irqrestore(&tpci200->info->access_lock, flags); return ret; } @@ -414,7 +410,6 @@ static int tpci200_register(struct tpci200_board *tpci200) TPCI200_MEM8_SPACE_BAR), TPCI200_MEM8_SIZE); - spin_lock_init(&tpci200->info->access_lock); ioidint_base = pci_resource_start(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); mem_base = pci_resource_start(tpci200->info->pdev, diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 97ff0d6636b6..d04510a89be4 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -136,7 +136,6 @@ struct tpci200_slot { * @interface_regs Pointer to IP interface space (Bar 2) * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) * @mem8_space Pointer to MEM space (Bar 4) - * @access_lock Mutex lock for simultaneous access * */ struct tpci200_infos { @@ -145,7 +144,6 @@ struct tpci200_infos { void __iomem *interface_regs; void __iomem *ioidint_space; void __iomem *mem8_space; - spinlock_t access_lock; struct ipack_bus_device *ipack_bus; }; struct tpci200_board { -- GitLab From 59d6a29e554d891a513476c13a6657825f8be270 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Mon, 25 Jun 2012 17:15:47 +0200 Subject: [PATCH 2729/6849] Staging: ipack/devices/ipoctal: remove unneeded lock in IRQ handler In the rest of the code, the data is protected with spin_lock_irqsave(). Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index b11126dfc006..ec7b2f9c89ad 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -299,7 +299,7 @@ static int ipoctal_irq_handler(void *arg) ipoctal->nb_bytes[channel] = 0; continue; } - spin_lock(&ipoctal->lock[channel]); + value = ipoctal->tty_port[channel].xmit_buf[*pointer_write]; ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.thr, @@ -309,7 +309,6 @@ static int ipoctal_irq_handler(void *arg) (*pointer_write)++; *pointer_write = *pointer_write % PAGE_SIZE; ipoctal->nb_bytes[channel]--; - spin_unlock(&ipoctal->lock[channel]); if ((ipoctal->nb_bytes[channel] == 0) && (waitqueue_active(&ipoctal->queue[channel]))) { -- GitLab From 07caba966dee241cd6599618a243be721195de38 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 30 May 2012 12:18:57 +0200 Subject: [PATCH 2730/6849] ARM: davinci: cp_intc: Add irq domain support Add irq domain support for DaVinci cp_intc. Boot tested on AM18x EVM. Also tested with GPIO IRQ support on AM18x EVM. Signed-off-by: Heiko Schocher Cc: davinci-linux-open-source@linux.davincidsp.com Cc: linux-arm-kernel@lists.infradead.org Cc: devicetree-discuss@lists.ozlabs.org Cc: Grant Likely Cc: Sekhar Nori Cc: Wolfgang Denk Cc: Sergei Shtylyov [nsekhar@ti.com: add commit description, select IRQ_DOMAIN for CP_INTC in Kconfig] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/Kconfig | 1 + arch/arm/mach-davinci/cp_intc.c | 63 +++++++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 32d837d8eab9..2ce1ef07c13d 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -4,6 +4,7 @@ config AINTC bool config CP_INTC + select IRQ_DOMAIN bool config ARCH_DAVINCI_DMx diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index f83152d643c5..45d52567ced7 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -9,8 +9,10 @@ * kind, whether express or implied. */ +#include #include #include +#include #include #include @@ -28,7 +30,7 @@ static inline void cp_intc_write(unsigned long value, unsigned offset) static void cp_intc_ack_irq(struct irq_data *d) { - cp_intc_write(d->irq, CP_INTC_SYS_STAT_IDX_CLR); + cp_intc_write(d->hwirq, CP_INTC_SYS_STAT_IDX_CLR); } /* Disable interrupt */ @@ -36,20 +38,20 @@ static void cp_intc_mask_irq(struct irq_data *d) { /* XXX don't know why we need to disable nIRQ here... */ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR); - cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_CLR); + cp_intc_write(d->hwirq, CP_INTC_SYS_ENABLE_IDX_CLR); cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET); } /* Enable interrupt */ static void cp_intc_unmask_irq(struct irq_data *d) { - cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_SET); + cp_intc_write(d->hwirq, CP_INTC_SYS_ENABLE_IDX_SET); } static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type) { - unsigned reg = BIT_WORD(d->irq); - unsigned mask = BIT_MASK(d->irq); + unsigned reg = BIT_WORD(d->hwirq); + unsigned mask = BIT_MASK(d->hwirq); unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg)); unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg)); @@ -99,18 +101,36 @@ static struct irq_chip cp_intc_irq_chip = { .irq_set_wake = cp_intc_set_wake, }; -void __init cp_intc_init(void) +static struct irq_domain *cp_intc_domain; + +static int cp_intc_host_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + pr_debug("cp_intc_host_map(%d, 0x%lx)\n", virq, hw); + + irq_set_chip(virq, &cp_intc_irq_chip); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + irq_set_handler(virq, handle_edge_irq); + return 0; +} + +static const struct irq_domain_ops cp_intc_host_ops = { + .map = cp_intc_host_map, + .xlate = irq_domain_xlate_onetwocell, +}; + +int __init __cp_intc_init(struct device_node *node) { - unsigned long num_irq = davinci_soc_info.intc_irq_num; + u32 num_irq = davinci_soc_info.intc_irq_num; u8 *irq_prio = davinci_soc_info.intc_irq_prios; u32 *host_map = davinci_soc_info.intc_host_map; unsigned num_reg = BITS_TO_LONGS(num_irq); - int i; + int i, irq_base; davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC; davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K); if (WARN_ON(!davinci_intc_base)) - return; + return -EINVAL; cp_intc_write(0, CP_INTC_GLOBAL_ENABLE); @@ -165,13 +185,28 @@ void __init cp_intc_init(void) for (i = 0; host_map[i] != -1; i++) cp_intc_write(host_map[i], CP_INTC_HOST_MAP(i)); - /* Set up genirq dispatching for cp_intc */ - for (i = 0; i < num_irq; i++) { - irq_set_chip(i, &cp_intc_irq_chip); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - irq_set_handler(i, handle_edge_irq); + irq_base = irq_alloc_descs(-1, 0, num_irq, 0); + if (irq_base < 0) { + pr_warn("Couldn't allocate IRQ numbers\n"); + irq_base = 0; + } + + /* create a legacy host */ + cp_intc_domain = irq_domain_add_legacy(node, num_irq, + irq_base, 0, &cp_intc_host_ops, NULL); + + if (!cp_intc_domain) { + pr_err("cp_intc: failed to allocate irq host!\n"); + return -EINVAL; } /* Enable global interrupt */ cp_intc_write(1, CP_INTC_GLOBAL_ENABLE); + + return 0; +} + +void __init cp_intc_init(void) +{ + __cp_intc_init(NULL); } -- GitLab From 35a468732289372aab506d7cf73f98f0379888ae Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 21 Jun 2012 17:52:52 +0900 Subject: [PATCH 2731/6849] perf evsel: Fix a build failure on cross compilation The commit c410431cefefd ("perf tools: Reconstruct event with modifiers from perf_event_attr") added the line, but it's broken since it needs to go up 3 directories to get to the kernel root directory, not 2. However host gcc contains /usr/local/include in its search path, so that it can find the perf_event.h in /usr/include. This why we didn't notice the problem yet. But when I tried to cross compile it appears like: CC util/evsel.o util/evsel.c:18:44: error: ../../include/linux/perf_event.h: No such file or directory make: *** [util/evsel.o] Error 1 Looking at the source, it isn't needed at all as evsel.h already included the perf_event.h. So simply remove it would solve the problem. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1340268772-5737-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 876f639d69ed..3d1f6968f175 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -15,7 +15,6 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" -#include "../../include/linux/perf_event.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) -- GitLab From 7a25b2d32b9cb0b813d56ee6109acf90f3c9f1e5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 21 Jun 2012 12:25:16 +0200 Subject: [PATCH 2732/6849] perf test: Fix parse events test to follow proper raw event name Following commit changed raw event names to carry event modificator. perf evsel: Reconstruct raw event with modifiers from perf_event_attr commit 6eef3d9c2bcf52b7a3c18e609f5838c007b989a4 Author: Arnaldo Carvalho de Melo The perf_evsel__name function now returns ':mod' suffix for raw events, so we need to follow that in current tests. All tests pass now for 'perf test parse' suite. Signed-off-by: Jiri Olsa Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1340274316-5161-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events-test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 229af6da33a2..a0f61a2a6835 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -413,19 +413,20 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) { struct perf_evsel *evsel; - /* cpu/config=1,name=krava1/u */ + /* cpu/config=1,name=krava/u */ evsel = list_entry(evlist->entries.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); - /* cpu/config=2/" */ + /* cpu/config=2/u" */ evsel = list_entry(evsel->node.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "raw 0x2")); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "raw 0x2:u")); return 0; } -- GitLab From f5e3352e5185ef37700da9a51c333559381fe8fd Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 24 Jun 2012 23:25:16 +0200 Subject: [PATCH 2733/6849] staging: nvec: convert to devm_ functions This patch cleanups the nvec and its childs by replacing calls to resource allocations by their devm_* equivalents. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 44 +++++++++++-------------------- drivers/staging/nvec/nvec_leds.c | 10 +++---- drivers/staging/nvec/nvec_power.c | 8 +++--- drivers/staging/nvec/nvec_ps2.c | 6 ++++- 4 files changed, 28 insertions(+), 40 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 3c60088871e0..47ffdb834203 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -719,10 +719,9 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) struct nvec_chip *nvec; struct nvec_msg *msg; struct resource *res; - struct resource *iomem; void __iomem *base; - nvec = kzalloc(sizeof(struct nvec_chip), GFP_KERNEL); + nvec = devm_kzalloc(&pdev->dev, sizeof(struct nvec_chip), GFP_KERNEL); if (nvec == NULL) { dev_err(&pdev->dev, "failed to reserve memory\n"); return -ENOMEM; @@ -737,15 +736,15 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) nvec->gpio = of_get_named_gpio(nvec->dev->of_node, "request-gpios", 0); if (nvec->gpio < 0) { dev_err(&pdev->dev, "no gpio specified"); - goto failed; + return -ENODEV; } if (of_property_read_u32(nvec->dev->of_node, "slave-addr", &nvec->i2c_addr)) { dev_err(&pdev->dev, "no i2c address specified"); - goto failed; + return -ENODEV; } } else { dev_err(&pdev->dev, "no platform data\n"); - goto failed; + return -ENODEV; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -754,13 +753,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) return -ENODEV; } - iomem = request_mem_region(res->start, resource_size(res), pdev->name); - if (!iomem) { - dev_err(&pdev->dev, "I2C region already claimed\n"); - return -EBUSY; - } - - base = ioremap(iomem->start, resource_size(iomem)); + base = devm_request_and_ioremap(&pdev->dev, res); if (!base) { dev_err(&pdev->dev, "Can't ioremap I2C region\n"); return -ENOMEM; @@ -769,14 +762,13 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "no irq resource?\n"); - ret = -ENODEV; - goto err_iounmap; + return -ENODEV; } i2c_clk = clk_get_sys("tegra-i2c.2", NULL); if (IS_ERR(i2c_clk)) { dev_err(nvec->dev, "failed to get controller clock\n"); - goto err_iounmap; + return -ENODEV; } nvec->base = base; @@ -797,16 +789,20 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) INIT_WORK(&nvec->tx_work, nvec_request_master); nvec->wq = alloc_workqueue("nvec", WQ_NON_REENTRANT, 2); - err = gpio_request_one(nvec->gpio, GPIOF_OUT_INIT_HIGH, "nvec gpio"); + err = devm_gpio_request_one(&pdev->dev, nvec->gpio, GPIOF_OUT_INIT_HIGH, + "nvec gpio"); if (err < 0) { dev_err(nvec->dev, "couldn't request gpio\n"); - goto failed; + destroy_workqueue(nvec->wq); + return -ENODEV; } - err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec); + err = devm_request_irq(&pdev->dev, nvec->irq, nvec_interrupt, 0, + "nvec", nvec); if (err) { dev_err(nvec->dev, "couldn't request irq\n"); - goto failed; + destroy_workqueue(nvec->wq); + return -ENODEV; } disable_irq(nvec->irq); @@ -851,12 +847,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x80\x00", 7); return 0; - -err_iounmap: - iounmap(base); -failed: - kfree(nvec); - return -ENOMEM; } static int __devexit tegra_nvec_remove(struct platform_device *pdev) @@ -865,11 +855,7 @@ static int __devexit tegra_nvec_remove(struct platform_device *pdev) nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3); mfd_remove_devices(nvec->dev); - free_irq(nvec->irq, &nvec_interrupt); - iounmap(nvec->base); - gpio_free(nvec->gpio); destroy_workqueue(nvec->wq); - kfree(nvec); return 0; } diff --git a/drivers/staging/nvec/nvec_leds.c b/drivers/staging/nvec/nvec_leds.c index f4cbcd625001..91947fb86067 100644 --- a/drivers/staging/nvec/nvec_leds.c +++ b/drivers/staging/nvec/nvec_leds.c @@ -49,7 +49,7 @@ static int __devinit nvec_led_probe(struct platform_device *pdev) struct nvec_led *led; int ret = 0; - led = kzalloc(sizeof(*led), GFP_KERNEL); + led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); if (led == NULL) return -ENOMEM; @@ -64,16 +64,12 @@ static int __devinit nvec_led_probe(struct platform_device *pdev) ret = led_classdev_register(&pdev->dev, &led->cdev); if (ret < 0) - goto err_led; + return ret; /* to expose the default value to userspace */ led->cdev.brightness = 0; return 0; - -err_led: - kfree(led); - return ret; } static int __devexit nvec_led_remove(struct platform_device *pdev) @@ -81,7 +77,7 @@ static int __devexit nvec_led_remove(struct platform_device *pdev) struct nvec_led *led = platform_get_drvdata(pdev); led_classdev_unregister(&led->cdev); - kfree(led); + return 0; } diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index dfa966f6189d..a23e5485c279 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -371,10 +371,13 @@ static void nvec_power_poll(struct work_struct *work) static int __devinit nvec_power_probe(struct platform_device *pdev) { struct power_supply *psy; - struct nvec_power *power = - kzalloc(sizeof(struct nvec_power), GFP_NOWAIT); + struct nvec_power *power; struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + power = devm_kzalloc(&pdev->dev, sizeof(struct nvec_power), GFP_NOWAIT); + if (power == NULL) + return -ENOMEM; + dev_set_drvdata(&pdev->dev, power); power->nvec = nvec; @@ -393,7 +396,6 @@ static int __devinit nvec_power_probe(struct platform_device *pdev) power->notifier.notifier_call = nvec_power_bat_notifier; break; default: - kfree(power); return -ENODEV; } diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 14a6f687cf75..d6ceff93d8b6 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -96,7 +96,11 @@ static int nvec_ps2_notifier(struct notifier_block *nb, static int __devinit nvec_mouse_probe(struct platform_device *pdev) { struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); - struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); + struct serio *ser_dev; + + ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL); + if (ser_dev == NULL) + return -ENOMEM; ser_dev->id.type = SERIO_PS_PSTHRU; ser_dev->write = ps2_sendcommand; -- GitLab From 50d4656a2304e48917a8e2b9df99f69d50b8a0aa Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 24 Jun 2012 23:25:17 +0200 Subject: [PATCH 2734/6849] staging: nvec: use dev_warn instead of printk Replace a printk in nvec core driver with dev_warn. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 47ffdb834203..39dbaa0ac6a0 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -127,12 +127,14 @@ EXPORT_SYMBOL_GPL(nvec_register_notifier); static int nvec_status_notifier(struct notifier_block *nb, unsigned long event_type, void *data) { + struct nvec_chip *nvec = container_of(nb, struct nvec_chip, + nvec_status_notifier); unsigned char *msg = (unsigned char *)data; if (event_type != NVEC_CNTL) return NOTIFY_DONE; - printk(KERN_WARNING "unhandled msg type %ld\n", event_type); + dev_warn(nvec->dev, "unhandled msg type %ld\n", event_type); print_hex_dump(KERN_WARNING, "payload: ", DUMP_PREFIX_NONE, 16, 1, msg, msg[1] + 2, true); -- GitLab From 9891b1ce6276912c54f66b7b0c8c1bcc42ca75eb Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 24 Jun 2012 23:25:18 +0200 Subject: [PATCH 2735/6849] staging: nvec: cleanup driver registration This patch simplifies code by using the module_platform_driver macro. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 7 +------ drivers/staging/nvec/nvec_kbd.c | 7 +------ drivers/staging/nvec/nvec_leds.c | 14 +------------- drivers/staging/nvec/nvec_power.c | 7 +------ drivers/staging/nvec/nvec_ps2.c | 7 +------ 5 files changed, 5 insertions(+), 37 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 39dbaa0ac6a0..09b7e129fc27 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -917,12 +917,7 @@ static struct platform_driver nvec_device_driver = { } }; -static int __init tegra_nvec_init(void) -{ - return platform_driver_register(&nvec_device_driver); -} - -module_init(tegra_nvec_init); +module_platform_driver(nvec_device_driver); MODULE_ALIAS("platform:nvec"); MODULE_DESCRIPTION("NVIDIA compliant embedded controller interface"); diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index a4ce5a740e2b..36ef6a6b01af 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -167,12 +167,7 @@ static struct platform_driver nvec_kbd_driver = { }, }; -static int __init nvec_kbd_init(void) -{ - return platform_driver_register(&nvec_kbd_driver); -} - -module_init(nvec_kbd_init); +module_platform_driver(nvec_kbd_driver); MODULE_AUTHOR("Marc Dietrich "); MODULE_DESCRIPTION("NVEC keyboard driver"); diff --git a/drivers/staging/nvec/nvec_leds.c b/drivers/staging/nvec/nvec_leds.c index 91947fb86067..53cb5711afa6 100644 --- a/drivers/staging/nvec/nvec_leds.c +++ b/drivers/staging/nvec/nvec_leds.c @@ -90,19 +90,7 @@ static struct platform_driver nvec_led_driver = { }, }; -static int __init nvec_led_init(void) -{ - return platform_driver_register(&nvec_led_driver); -} - -module_init(nvec_led_init); - -static void __exit nvec_led_exit(void) -{ - platform_driver_unregister(&nvec_led_driver); -} - -module_exit(nvec_led_exit); +module_platform_driver(nvec_led_driver); MODULE_AUTHOR("Ilya Petrov "); MODULE_DESCRIPTION("Tegra NVEC LED driver"); diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index a23e5485c279..063f6d5e8ab1 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -415,12 +415,7 @@ static struct platform_driver nvec_power_driver = { } }; -static int __init nvec_power_init(void) -{ - return platform_driver_register(&nvec_power_driver); -} - -module_init(nvec_power_init); +module_platform_driver(nvec_power_driver); MODULE_AUTHOR("Ilya Petrov "); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index d6ceff93d8b6..441dd76f10a1 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -158,12 +158,7 @@ static struct platform_driver nvec_mouse_driver = { }, }; -static int __init nvec_mouse_init(void) -{ - return platform_driver_register(&nvec_mouse_driver); -} - -module_init(nvec_mouse_init); +module_platform_driver(nvec_mouse_driver); MODULE_DESCRIPTION("NVEC mouse driver"); MODULE_AUTHOR("Marc Dietrich "); -- GitLab From ebefae28cea729cb1fa9c944179f62d7dd65b10f Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 24 Jun 2012 23:25:19 +0200 Subject: [PATCH 2736/6849] staging: nvec: cleanup powermanagement callbacks Simplify powermanagement initialization by using pm_ops macro. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 20 ++++++++++---------- drivers/staging/nvec/nvec_ps2.c | 14 ++++++++++---- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 09b7e129fc27..221bc055ef98 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -700,12 +700,14 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) clk_disable(nvec->i2c_clk); } +#ifdef CONFIG_PM_SLEEP static void nvec_disable_i2c_slave(struct nvec_chip *nvec) { disable_irq(nvec->irq); writel(I2C_SL_NEWSL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG); clk_disable(nvec->i2c_clk); } +#endif static void nvec_power_off(void) { @@ -862,10 +864,10 @@ static int __devexit tegra_nvec_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM - -static int tegra_nvec_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int nvec_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct nvec_chip *nvec = platform_get_drvdata(pdev); struct nvec_msg *msg; @@ -882,8 +884,9 @@ static int tegra_nvec_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int tegra_nvec_resume(struct platform_device *pdev) +static int nvec_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct nvec_chip *nvec = platform_get_drvdata(pdev); dev_dbg(nvec->dev, "resuming\n"); @@ -892,12 +895,10 @@ static int tegra_nvec_resume(struct platform_device *pdev) return 0; } - -#else -#define tegra_nvec_suspend NULL -#define tegra_nvec_resume NULL #endif +static const SIMPLE_DEV_PM_OPS(nvec_pm_ops, nvec_suspend, nvec_resume); + /* Match table for of_platform binding */ static const struct of_device_id nvidia_nvec_of_match[] __devinitconst = { { .compatible = "nvidia,nvec", }, @@ -908,11 +909,10 @@ MODULE_DEVICE_TABLE(of, nvidia_nvec_of_match); static struct platform_driver nvec_device_driver = { .probe = tegra_nvec_probe, .remove = __devexit_p(tegra_nvec_remove), - .suspend = tegra_nvec_suspend, - .resume = tegra_nvec_resume, .driver = { .name = "nvec", .owner = THIS_MODULE, + .pm = &nvec_pm_ops, .of_match_table = nvidia_nvec_of_match, } }; diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 441dd76f10a1..2481df2d3bfc 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -123,8 +123,10 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) return 0; } -static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int nvec_mouse_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); /* disable mouse */ @@ -136,8 +138,9 @@ static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int nvec_mouse_resume(struct platform_device *pdev) +static int nvec_mouse_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); ps2_startstreaming(ps2_dev.ser_dev); @@ -147,14 +150,17 @@ static int nvec_mouse_resume(struct platform_device *pdev) return 0; } +#endif + +static const SIMPLE_DEV_PM_OPS(nvec_mouse_pm_ops, nvec_mouse_suspend, + nvec_mouse_resume); static struct platform_driver nvec_mouse_driver = { .probe = nvec_mouse_probe, - .suspend = nvec_mouse_suspend, - .resume = nvec_mouse_resume, .driver = { .name = "nvec-mouse", .owner = THIS_MODULE, + .pm = &nvec_mouse_pm_ops, }, }; -- GitLab From ac562680577a28fa98ebecebff5e5097ccf9a9d2 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 24 Jun 2012 23:25:20 +0200 Subject: [PATCH 2737/6849] staging: nvec: rename led driver to board specific paz00 driver The led driver used OEM commands which are not part of the nvec protocol definition. Therefore it is renamed to nvec_paz00 to reflect that it only applies to PAZ00 board based devices. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/Kconfig | 9 +++---- drivers/staging/nvec/Makefile | 2 +- drivers/staging/nvec/nvec.c | 2 +- .../nvec/{nvec_leds.c => nvec_paz00.c} | 24 +++++++++---------- 4 files changed, 19 insertions(+), 18 deletions(-) rename drivers/staging/nvec/{nvec_leds.c => nvec_paz00.c} (76%) diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig index 731301f524a6..43048e9ba0d4 100644 --- a/drivers/staging/nvec/Kconfig +++ b/drivers/staging/nvec/Kconfig @@ -26,8 +26,9 @@ config NVEC_POWER Say Y to enable support for battery and charger interface for nVidia compliant embedded controllers. -config NVEC_LEDS - bool "NVEC leds" - depends on MFD_NVEC && LEDS_CLASS +config NVEC_PAZ00 + bool "Support for OEM specific functions on Compal PAZ00 based devices" + depends on MFD_NVEC && LEDS_CLASS && MACH_PAZ00 help - Say Y to enable yellow side leds on AC100 or other nVidia tegra nvec leds + Say Y to enable control of the yellow side leds on Compal PAZ00 based + devices, e.g. Toshbia AC100 and Dynabooks AZ netbooks. diff --git a/drivers/staging/nvec/Makefile b/drivers/staging/nvec/Makefile index b844d604e3ac..0db0e1f43337 100644 --- a/drivers/staging/nvec/Makefile +++ b/drivers/staging/nvec/Makefile @@ -2,4 +2,4 @@ obj-$(CONFIG_SERIO_NVEC_PS2) += nvec_ps2.o obj-$(CONFIG_MFD_NVEC) += nvec.o obj-$(CONFIG_NVEC_POWER) += nvec_power.o obj-$(CONFIG_KEYBOARD_NVEC) += nvec_kbd.o -obj-$(CONFIG_NVEC_LEDS) += nvec_leds.o +obj-$(CONFIG_NVEC_PAZ00) += nvec_paz00.o diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 221bc055ef98..0f2b541add18 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -97,7 +97,7 @@ static struct mfd_cell nvec_devices[] = { .id = 2, }, { - .name = "nvec-leds", + .name = "nvec-paz00", .id = 1, }, }; diff --git a/drivers/staging/nvec/nvec_leds.c b/drivers/staging/nvec/nvec_paz00.c similarity index 76% rename from drivers/staging/nvec/nvec_leds.c rename to drivers/staging/nvec/nvec_paz00.c index 53cb5711afa6..b747e39ff94d 100644 --- a/drivers/staging/nvec/nvec_leds.c +++ b/drivers/staging/nvec/nvec_paz00.c @@ -1,5 +1,5 @@ /* - * nvec_leds: LED driver for a NVIDIA compliant embedded controller + * nvec_paz00: OEM specific driver for Compal PAZ00 based devices * * Copyright (C) 2011 The AC100 Kernel Team * @@ -43,7 +43,7 @@ static void nvec_led_brightness_set(struct led_classdev *led_cdev, } -static int __devinit nvec_led_probe(struct platform_device *pdev) +static int __devinit nvec_paz00_probe(struct platform_device *pdev) { struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct nvec_led *led; @@ -56,7 +56,7 @@ static int __devinit nvec_led_probe(struct platform_device *pdev) led->cdev.max_brightness = NVEC_LED_MAX; led->cdev.brightness_set = nvec_led_brightness_set; - led->cdev.name = "nvec-led"; + led->cdev.name = "paz00-led"; led->cdev.flags |= LED_CORE_SUSPENDRESUME; led->nvec = nvec; @@ -72,7 +72,7 @@ static int __devinit nvec_led_probe(struct platform_device *pdev) return 0; } -static int __devexit nvec_led_remove(struct platform_device *pdev) +static int __devexit nvec_paz00_remove(struct platform_device *pdev) { struct nvec_led *led = platform_get_drvdata(pdev); @@ -81,18 +81,18 @@ static int __devexit nvec_led_remove(struct platform_device *pdev) return 0; } -static struct platform_driver nvec_led_driver = { - .probe = nvec_led_probe, - .remove = __devexit_p(nvec_led_remove), +static struct platform_driver nvec_paz00_driver = { + .probe = nvec_paz00_probe, + .remove = __devexit_p(nvec_paz00_remove), .driver = { - .name = "nvec-leds", - .owner = THIS_MODULE, + .name = "nvec-paz00", + .owner = THIS_MODULE, }, }; -module_platform_driver(nvec_led_driver); +module_platform_driver(nvec_paz00_driver); MODULE_AUTHOR("Ilya Petrov "); -MODULE_DESCRIPTION("Tegra NVEC LED driver"); +MODULE_DESCRIPTION("Tegra NVEC PAZ00 driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:nvec-leds"); +MODULE_ALIAS("platform:nvec-paz00"); -- GitLab From 3cdde3a3d55e64e6d1ae3465701c8d9f226775f3 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sun, 24 Jun 2012 23:25:21 +0200 Subject: [PATCH 2738/6849] staging: nvec: add remove function to nvec childs This patch cleanups registered devices on remove. Signed-off-by: Marc Dietrich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_kbd.c | 9 +++++++++ drivers/staging/nvec/nvec_power.c | 17 +++++++++++++++++ drivers/staging/nvec/nvec_ps2.c | 8 ++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index 36ef6a6b01af..6cc30dcd8306 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -159,8 +159,17 @@ fail: return err; } +static int __devexit nvec_kbd_remove(struct platform_device *pdev) +{ + input_unregister_device(keys_dev.input); + input_free_device(keys_dev.input); + + return 0; +} + static struct platform_driver nvec_kbd_driver = { .probe = nvec_kbd_probe, + .remove = __devexit_p(nvec_kbd_remove), .driver = { .name = "nvec-kbd", .owner = THIS_MODULE, diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index 063f6d5e8ab1..cc8ccd75e7f4 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -407,8 +407,25 @@ static int __devinit nvec_power_probe(struct platform_device *pdev) return power_supply_register(&pdev->dev, psy); } +static int __devexit nvec_power_remove(struct platform_device *pdev) +{ + struct nvec_power *power = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&power->poller); + switch (pdev->id) { + case AC: + power_supply_unregister(&nvec_psy); + break; + case BAT: + power_supply_unregister(&nvec_bat_psy); + } + + return 0; +} + static struct platform_driver nvec_power_driver = { .probe = nvec_power_probe, + .remove = __devexit_p(nvec_power_remove), .driver = { .name = "nvec-power", .owner = THIS_MODULE, diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 2481df2d3bfc..d7c651102131 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -123,6 +123,13 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) return 0; } +static int __devexit nvec_mouse_remove(struct platform_device *pdev) +{ + serio_unregister_port(ps2_dev.ser_dev); + + return 0; +} + #ifdef CONFIG_PM_SLEEP static int nvec_mouse_suspend(struct device *dev) { @@ -157,6 +164,7 @@ static const SIMPLE_DEV_PM_OPS(nvec_mouse_pm_ops, nvec_mouse_suspend, static struct platform_driver nvec_mouse_driver = { .probe = nvec_mouse_probe, + .remove = __devexit_p(nvec_mouse_remove), .driver = { .name = "nvec-mouse", .owner = THIS_MODULE, -- GitLab From 4c0ad72f01e358a8fa9ece655e9918d7c864e1a6 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:55:54 +0200 Subject: [PATCH 2739/6849] staging: vt6656: iwctl: Remove redundant blank lines There are a number of excessive blank lines in iwctl.c - this patch gets rid of most of those that I personally considered the most obvious ones. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 76 ---------------------------------- 1 file changed, 76 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 57404388eba9..9a49fa9dbf3f 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -81,14 +81,12 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr; pDevice->wstats.discard.misc = 0; pDevice->wstats.miss.beacon = 0; - return &pDevice->wstats; } /* * Wireless Handler : get protocol name */ - int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, char *wrq, @@ -101,7 +99,6 @@ int iwctl_giwname(struct net_device *dev, /* * Wireless Handler : set scan */ - int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -176,7 +173,6 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! /* * Wireless Handler : get scan results */ - int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -320,17 +316,13 @@ int iwctl_giwscan(struct net_device *dev, } }// for - wrq->length = current_ev - extra; return 0; - } - /* * Wireless Handler : set frequence or channel */ - int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, @@ -373,7 +365,6 @@ int iwctl_siwfreq(struct net_device *dev, /* * Wireless Handler : get frequence or channel */ - int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, @@ -396,14 +387,12 @@ int iwctl_giwfreq(struct net_device *dev, wrq->e = 1; } #endif - return 0; } /* * Wireless Handler : set operation mode */ - int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, @@ -470,7 +459,6 @@ int iwctl_siwmode(struct net_device *dev, /* * Wireless Handler : get operation mode */ - void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, @@ -500,11 +488,9 @@ void iwctl_giwmode(struct net_device *dev, } } - /* * Wireless Handler : get capability range */ - void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -556,7 +542,6 @@ void iwctl_giwrange(struct net_device *dev, range->min_frag = 256; range->max_frag = 2312; - // the encoding capabilities range->num_encoding_sizes = 3; // 64(40) bits WEP @@ -580,7 +565,6 @@ void iwctl_giwrange(struct net_device *dev, range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; // Transmit Power - values are in mW - range->txpower[0] = 100; range->num_txpower = 1; range->txpower_capa = IW_TXPOW_MWATT; @@ -602,11 +586,9 @@ void iwctl_giwrange(struct net_device *dev, } } - /* * Wireless Handler : set ap mac address */ - int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, @@ -623,7 +605,6 @@ int iwctl_siwap(struct net_device *dev, rc = -EINVAL; else { memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - //mike :add if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ @@ -657,7 +638,6 @@ int iwctl_siwap(struct net_device *dev, /* * Wireless Handler : get ap mac address */ - int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, @@ -666,7 +646,6 @@ int iwctl_giwap(struct net_device *dev, PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); @@ -679,16 +658,12 @@ int iwctl_giwap(struct net_device *dev, } wrq->sa_family = ARPHRD_ETHER; - return 0; - } - /* * Wireless Handler : get ap list */ - int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -700,7 +675,6 @@ int iwctl_giwaplist(struct net_device *dev, PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); // Only super-user can see AP list @@ -710,7 +684,6 @@ int iwctl_giwaplist(struct net_device *dev, } if (wrq->pointer) { - PKnownBSS pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) { @@ -732,11 +705,9 @@ int iwctl_giwaplist(struct net_device *dev, memcpy(extra, sock, sizeof(struct sockaddr)*jj); memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj); } - return rc; } - /* * Wireless Handler : set essid */ @@ -847,12 +818,9 @@ int iwctl_siwessid(struct net_device *dev, if (pDevice->flags & DEVICE_FLAGS_OPENED) { pDevice->bCommit = TRUE; } - - return 0; } - /* * Wireless Handler : get essid */ @@ -861,7 +829,6 @@ void iwctl_giwessid(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; @@ -883,7 +850,6 @@ void iwctl_giwessid(struct net_device *dev, /* * Wireless Handler : set data rate */ - int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1005,8 +971,6 @@ void iwctl_giwrate(struct net_device *dev, } } - - /* * Wireless Handler : set rts threshold */ @@ -1020,7 +984,6 @@ int iwctl_siwrts(struct net_device *dev, else if (wrq->disabled) pDevice->wRTSThreshold = 2312; - else pDevice->wRTSThreshold = wrq->value; @@ -1030,7 +993,6 @@ int iwctl_siwrts(struct net_device *dev, /* * Wireless Handler : get rts */ - int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1049,7 +1011,6 @@ int iwctl_giwrts(struct net_device *dev, /* * Wireless Handler : set fragment threshold */ - int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1059,10 +1020,8 @@ int iwctl_siwfrag(struct net_device *dev, int rc = 0; int fthr = wrq->value; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n"); - if (wrq->disabled) fthr = 2312; if((fthr < 256) || (fthr > 2312)) { @@ -1071,7 +1030,6 @@ int iwctl_siwfrag(struct net_device *dev, fthr &= ~0x1; // Get an even value pDevice->wFragmentationThreshold = (u16)fthr; } - return rc; } @@ -1094,8 +1052,6 @@ int iwctl_giwfrag(struct net_device *dev, return 0; } - - /* * Wireless Handler : set retry threshold */ @@ -1107,7 +1063,6 @@ int iwctl_siwretry(struct net_device *dev, PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); if (wrq->disabled) { @@ -1129,8 +1084,6 @@ int iwctl_siwretry(struct net_device *dev, if (wrq->flags & IW_RETRY_LIFETIME) { pDevice->wMaxTransmitMSDULifetime = wrq->value; } - - return rc; } @@ -1160,11 +1113,9 @@ int iwctl_giwretry(struct net_device *dev, wrq->flags |= IW_RETRY_MIN; } - return 0; } - /* * Wireless Handler : set encode mode */ @@ -1179,7 +1130,6 @@ int iwctl_siwencode(struct net_device *dev, int ii,uu, rc = 0; int index = (wrq->flags & IW_ENCODE_INDEX); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); // Check the size of the key @@ -1268,7 +1218,6 @@ int iwctl_siwencode(struct net_device *dev, #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT memset(pMgmt->abyDesireBSSID, 0xFF,6); #endif - return rc; } @@ -1326,11 +1275,9 @@ int iwctl_giwencode(struct net_device *dev, } wrq->flags |= index+1; - return 0; } - /* * Wireless Handler : set power mode */ @@ -1393,10 +1340,8 @@ int iwctl_giwpower(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int mode = pDevice->ePSMode; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); - if ((wrq->disabled = (mode == WMAC_POWER_CAM))) return 0; @@ -1408,11 +1353,9 @@ int iwctl_giwpower(struct net_device *dev, wrq->flags = IW_POWER_PERIOD; } wrq->flags |= IW_POWER_ALL_R; - return 0; } - /* * Wireless Handler : get Sensitivity */ @@ -1434,8 +1377,6 @@ int iwctl_giwsens(struct net_device *dev, }; wrq->disabled = (wrq->value == 0); wrq->fixed = 1; - - return 0; } @@ -1506,7 +1447,6 @@ int iwctl_siwauth(struct net_device *dev, pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; else pMgmt->eAuthenMode = WMAC_AUTH_WPA; } - break; case IW_AUTH_TKIP_COUNTERMEASURES: break; /* FIXME */ @@ -1537,7 +1477,6 @@ int iwctl_siwauth(struct net_device *dev, pMgmt->eAuthenMode = WMAC_AUTH_OPEN; PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n"); } - break; default: ret = -EOPNOTSUPP; @@ -1546,7 +1485,6 @@ int iwctl_siwauth(struct net_device *dev, return ret; } - int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1555,8 +1493,6 @@ int iwctl_giwauth(struct net_device *dev, return -EOPNOTSUPP; } - - int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -1610,11 +1546,9 @@ int iwctl_giwgenie(struct net_device *dev, }else ret = -E2BIG; } - return ret; } - int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -1681,7 +1615,6 @@ if(ext->key_len) { key_len=ext->key_len; memcpy(key, &ext->key[0], key_len); } - memset(key_array, 0, 64); if ( key_len > 0) { memcpy(key_array, key, key_len); @@ -1732,7 +1665,6 @@ if(pDevice->bwextstep3 == TRUE) { KeyvInitTable(pDevice,&pDevice->sKey); } //****** - spin_lock_irq(&pDevice->lock); ret = wpa_set_keys(pDevice, param, TRUE); spin_unlock_irq(&pDevice->lock); @@ -1742,8 +1674,6 @@ kfree(param); return ret; } - - int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -1779,9 +1709,7 @@ int iwctl_siwmlme(struct net_device *dev, default: ret = -EOPNOTSUPP; } - return ret; - } #endif @@ -1846,21 +1774,17 @@ static const iw_handler iwctl_handler[] = (iw_handler) NULL, // -- hole -- }; - static const iw_handler iwctl_private_handler[] = { NULL, // SIOCIWFIRSTPRIV }; - struct iw_priv_args iwctl_private_args[] = { { IOCTL_CMD_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "set"}, }; - - const struct iw_handler_def iwctl_handler_def = { .get_wireless_stats = &iwctl_get_wireless_stats, -- GitLab From 921cd68b671d277bab8956e066a0f765ce0defb3 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:56:05 +0200 Subject: [PATCH 2740/6849] staging: vt6656: iwctl: fix up function declarations/prototypes The way function prototypes/declarations are written in iwctl.[ch] is an inconsistent mess. This patch makes the whole thing consistent by putting the first function arguments (op to a column width of at most 80) on the same line as the function name and the remaining ones on the following line indented by two tabs. Besides getting rid of the current tabs vs spaces mess it also shortens the files quite a bit and puts them more in line with most other kernel files. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 197 +++++++++---------------- drivers/staging/vt6656/iwctl.h | 258 ++++++++++++--------------------- 2 files changed, 161 insertions(+), 294 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 9a49fa9dbf3f..3ac41bb8a9a9 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -87,10 +87,8 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) /* * Wireless Handler : get protocol name */ -int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra) +int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, + char *wrq, char *extra) { strcpy(wrq, "802.11-a/b/g"); return 0; @@ -99,10 +97,8 @@ int iwctl_giwname(struct net_device *dev, /* * Wireless Handler : set scan */ -int iwctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -173,10 +169,8 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! /* * Wireless Handler : get scan results */ -int iwctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { int ii, jj, kk; PSDevice pDevice = (PSDevice)netdev_priv(dev); @@ -323,10 +317,8 @@ int iwctl_giwscan(struct net_device *dev, /* * Wireless Handler : set frequence or channel */ -int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) +int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; @@ -365,10 +357,8 @@ int iwctl_siwfreq(struct net_device *dev, /* * Wireless Handler : get frequence or channel */ -int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) +int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -393,10 +383,8 @@ int iwctl_giwfreq(struct net_device *dev, /* * Wireless Handler : set operation mode */ -int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) +int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, + __u32 *wmode, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -459,10 +447,8 @@ int iwctl_siwmode(struct net_device *dev, /* * Wireless Handler : get operation mode */ -void iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) +void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, + __u32 *wmode, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -491,10 +477,8 @@ void iwctl_giwmode(struct net_device *dev, /* * Wireless Handler : get capability range */ -void iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { struct iw_range *range = (struct iw_range *) extra; int i,k; @@ -589,10 +573,8 @@ void iwctl_giwrange(struct net_device *dev, /* * Wireless Handler : set ap mac address */ -int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) +int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, + struct sockaddr *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -638,10 +620,8 @@ int iwctl_siwap(struct net_device *dev, /* * Wireless Handler : get ap mac address */ -int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) +int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, + struct sockaddr *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -664,10 +644,8 @@ int iwctl_giwap(struct net_device *dev, /* * Wireless Handler : get ap list */ -int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { int ii,jj, rc = 0; struct sockaddr sock[IW_MAX_AP]; @@ -711,11 +689,8 @@ int iwctl_giwaplist(struct net_device *dev, /* * Wireless Handler : set essid */ - -int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -824,10 +799,8 @@ int iwctl_siwessid(struct net_device *dev, /* * Wireless Handler : get essid */ -void iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -850,10 +823,8 @@ void iwctl_giwessid(struct net_device *dev, /* * Wireless Handler : set data rate */ -int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; @@ -931,10 +902,8 @@ int iwctl_siwrate(struct net_device *dev, /* * Wireless Handler : get data rate */ -void iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -974,8 +943,7 @@ void iwctl_giwrate(struct net_device *dev, /* * Wireless Handler : set rts threshold */ -int iwctl_siwrts(struct net_device *dev, - struct iw_param *wrq) +int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq) { PSDevice pDevice = (PSDevice)netdev_priv(dev); @@ -993,10 +961,8 @@ int iwctl_siwrts(struct net_device *dev, /* * Wireless Handler : get rts */ -int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); @@ -1011,10 +977,8 @@ int iwctl_giwrts(struct net_device *dev, /* * Wireless Handler : set fragment threshold */ -int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; @@ -1036,11 +1000,8 @@ int iwctl_siwfrag(struct net_device *dev, /* * Wireless Handler : get fragment threshold */ - -int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); @@ -1055,10 +1016,8 @@ int iwctl_giwfrag(struct net_device *dev, /* * Wireless Handler : set retry threshold */ -int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; @@ -1090,10 +1049,8 @@ int iwctl_siwretry(struct net_device *dev, /* * Wireless Handler : get retry threshold */ -int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); @@ -1119,10 +1076,8 @@ int iwctl_giwretry(struct net_device *dev, /* * Wireless Handler : set encode mode */ -int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1221,10 +1176,8 @@ int iwctl_siwencode(struct net_device *dev, return rc; } -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1281,10 +1234,8 @@ int iwctl_giwencode(struct net_device *dev, /* * Wireless Handler : set power mode */ -int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1331,10 +1282,8 @@ int iwctl_siwpower(struct net_device *dev, /* * Wireless Handler : get power mode */ -int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1359,10 +1308,8 @@ int iwctl_giwpower(struct net_device *dev, /* * Wireless Handler : get Sensitivity */ -int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); long ldBm; @@ -1382,10 +1329,8 @@ int iwctl_giwsens(struct net_device *dev, #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1485,18 +1430,14 @@ int iwctl_siwauth(struct net_device *dev, return ret; } -int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) +int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra) { return -EOPNOTSUPP; } -int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1526,10 +1467,8 @@ int iwctl_siwgenie(struct net_device *dev, return ret; } -int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1549,10 +1488,8 @@ int iwctl_giwgenie(struct net_device *dev, return ret; } -int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1674,18 +1611,14 @@ kfree(param); return ret; } -int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) +int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { return -EOPNOTSUPP; } -int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info * info, - struct iw_point *wrq, - char *extra) +int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 0c6e0496779b..96fd043a88c6 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -41,170 +41,104 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev); -int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); - -void iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - - -void iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); - -int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); - -int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); - -int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); - -int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra); - -int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); - -int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -void iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -void iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwrts(struct net_device *dev, - struct iw_param *wrq); - -int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); +int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, + struct sockaddr *wrq, char *extra); + +void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, + __u32 *wmode, char *extra); + +int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, + __u32 *wmode, char *extra); + +int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *wrq, char *extra); + +int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *wrq, char *extra); + +int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, + char *wrq, char *extra); + +int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, + struct sockaddr *wrq, char *extra); + +int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq); + +int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info * info, - struct iw_point *wrq, - char *extra); +int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info, + struct iw_param *wrq, char *extra); + +int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); + +int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, + struct iw_point *wrq, char *extra); #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT extern const struct iw_handler_def iwctl_handler_def; -- GitLab From 48746d7f4d9a821e547e2c1e6623a8e20a0a70a7 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:56:15 +0200 Subject: [PATCH 2741/6849] staging: vt6656: iwctl: Fix indentation Fix indentation for the entire files to use tabs rather than spaces and also make sure everything is indented to the proper depth according to context. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 1240 ++++++++++++++++---------------- 1 file changed, 620 insertions(+), 620 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 3ac41bb8a9a9..7618fb94cdf2 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -53,12 +53,12 @@ #endif static const long frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, - 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, - 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, - 5700, 5745, 5765, 5785, 5805, 5825 - }; + 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, + 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, + 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, + 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, + 5700, 5745, 5765, 5785, 5805, 5825 +}; static int msglevel =MSG_LEVEL_INFO; @@ -68,9 +68,9 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) long ldBm; pDevice->wstats.status = pDevice->eOPMode; - if(pDevice->scStatistic.LinkQuality > 100) - pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality; + if(pDevice->scStatistic.LinkQuality > 100) + pDevice->scStatistic.LinkQuality = 100; + pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality; RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); pDevice->wstats.qual.level = ldBm; pDevice->wstats.qual.noise = 0; @@ -101,65 +101,65 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_scan_req *req = (struct iw_scan_req *)extra; BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; PWLAN_IE_SSID pItemSSID=NULL; - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) - return -EINVAL; + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) + return -EINVAL; - PRINT_K(" SIOCSIWSCAN \n"); + PRINT_K(" SIOCSIWSCAN \n"); -if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. - PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n"); - return -EAGAIN; - } + if (pMgmt->eScanState == WMAC_IS_SCANNING) { + // In scanning.. + PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n"); + return -EAGAIN; + } -if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! + if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! //send scan event to wpa_Supplicant - union iwreq_data wrqu; - PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - return 0; -} + union iwreq_data wrqu; + PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); + memset(&wrqu, 0, sizeof(wrqu)); + wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); + return 0; + } spin_lock_irq(&pDevice->lock); BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); //mike add: active scan OR passive scan OR desire_ssid scan - if(wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan - memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)abyScanSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); - if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { - if(req->essid_len>0) - pItemSSID->len = req->essid_len - 1; - } - else - pItemSSID->len = req->essid_len; - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, - ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - spin_unlock_irq(&pDevice->lock); + if(wrq->length == sizeof(struct iw_scan_req)) { + if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan + memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + pItemSSID = (PWLAN_IE_SSID)abyScanSSID; + pItemSSID->byElementID = WLAN_EID_SSID; + memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); + if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { + if(req->essid_len>0) + pItemSSID->len = req->essid_len - 1; + } + else + pItemSSID->len = req->essid_len; + pMgmt->eScanType = WMAC_SCAN_PASSIVE; + PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, + ((PWLAN_IE_SSID)abyScanSSID)->len); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + spin_unlock_irq(&pDevice->lock); + + return 0; + } + else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan + pMgmt->eScanType = WMAC_SCAN_PASSIVE; + } + } + else { //active scan + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + } - return 0; - } - else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - } - } - else { //active scan - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - } - - pMgmt->eScanType = WMAC_SCAN_PASSIVE; + pMgmt->eScanType = WMAC_SCAN_PASSIVE; bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); @@ -172,12 +172,12 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - int ii, jj, kk; + int ii, jj, kk; PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PKnownBSS pBSS; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PKnownBSS pBSS; + PWLAN_IE_SSID pItemSSID; + PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; char *current_ev = extra; char *end_buf = extra + IW_SCAN_MAX_DATA; char *current_val = NULL; @@ -185,131 +185,131 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, long ldBm; char buf[MAX_WPA_IE_LEN * 2 + 30]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n"); - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. + if (pMgmt->eScanState == WMAC_IS_SCANNING) { + // In scanning.. return -EAGAIN; } pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { + for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { if (current_ev >= end_buf) break; - pBSS = &(pMgmt->sBSSList[jj]); - if (pBSS->bActive) { - //ADD mac address - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + pBSS = &(pMgmt->sBSSList[jj]); + if (pBSS->bActive) { + //ADD mac address + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); - //ADD ssid - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - iwe.u.data.length = pItemSSID->len; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); - //ADD mode - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { - iwe.u.mode = IW_MODE_INFRA; - } - else { - iwe.u.mode = IW_MODE_ADHOC; - } - iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - //ADD frequency - pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; - pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = pBSS->uChannel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); + current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); + //ADD ssid + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWESSID; + pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; + iwe.u.data.length = pItemSSID->len; + iwe.u.data.flags = 1; + current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); + //ADD mode + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWMODE; + if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { + iwe.u.mode = IW_MODE_INFRA; + } + else { + iwe.u.mode = IW_MODE_ADHOC; + } + iwe.len = IW_EV_UINT_LEN; + current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + //ADD frequency + pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; + pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = pBSS->uChannel; + iwe.u.freq.e = 0; + iwe.u.freq.i = 0; + current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); { - int f = (int)pBSS->uChannel - 1; - if(f < 0)f = 0; - iwe.u.freq.m = frequency_list[f] * 100000; - iwe.u.freq.e = 1; + int f = (int)pBSS->uChannel - 1; + if(f < 0)f = 0; + iwe.u.freq.m = frequency_list[f] * 100000; + iwe.u.freq.e = 1; } - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); - //ADD quality - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); - iwe.u.qual.level = ldBm; - iwe.u.qual.noise = 0; + current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); + //ADD quality + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVQUAL; + RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); + iwe.u.qual.level = ldBm; + iwe.u.qual.noise = 0; if(-ldBm<50){ iwe.u.qual.qual = 100; }else if(-ldBm > 90) { - iwe.u.qual.qual = 0; + iwe.u.qual.qual = 0; }else { iwe.u.qual.qual=(40-(-ldBm-50))*100/40; } iwe.u.qual.updated=7; - current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); - //ADD encryption - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - iwe.u.data.length = 0; - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { - iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - }else { - iwe.u.data.flags = IW_ENCODE_DISABLED; - } - current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - current_val = current_ev + IW_EV_LCP_LEN; - - for (kk = 0 ; kk < 12 ; kk++) { - if (pSuppRates->abyRates[kk] == 0) - break; - // Bit rate given in 500 kb/s units (+ 0x80) - iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - for (kk = 0 ; kk < 8 ; kk++) { - if (pExtSuppRates->abyRates[kk] == 0) - break; - // Bit rate given in 500 kb/s units (+ 0x80) - iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - - if((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf); - - if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wWPALen; - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE); - } - - if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wRSNLen; - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE); - } - - } - }// for + current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + //ADD encryption + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWENCODE; + iwe.u.data.length = 0; + if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { + iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + }else { + iwe.u.data.flags = IW_ENCODE_DISABLED; + } + current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + current_val = current_ev + IW_EV_LCP_LEN; + + for (kk = 0 ; kk < 12 ; kk++) { + if (pSuppRates->abyRates[kk] == 0) + break; + // Bit rate given in 500 kb/s units (+ 0x80) + iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); + current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + } + for (kk = 0 ; kk < 8 ; kk++) { + if (pExtSuppRates->abyRates[kk] == 0) + break; + // Bit rate given in 500 kb/s units (+ 0x80) + iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); + current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + } + + if((current_val - current_ev) > IW_EV_LCP_LEN) + current_ev = current_val; + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); + iwe.u.data.length = strlen(buf); + current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf); + + if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pBSS->wWPALen; + current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE); + } + + if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pBSS->wRSNLen; + current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE); + } + + } + }// for wrq->length = current_ev - extra; return 0; } @@ -323,12 +323,12 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); // If setting by frequency, convert to a channel if((wrq->e == 1) && - (wrq->m >= (int) 2.412e8) && - (wrq->m <= (int) 2.487e8)) { + (wrq->m >= (int) 2.412e8) && + (wrq->m <= (int) 2.487e8)) { int f = wrq->m / 100000; int c = 0; while((c < 14) && (f != frequency_list[c])) @@ -345,9 +345,9 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m); rc = -EINVAL; } else { - // Yes ! We can set it !!! - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel); - pDevice->uChannel = channel; + // Yes ! We can set it !!! + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel); + pDevice->uChannel = channel; } } @@ -361,9 +361,9 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); #ifdef WEXT_USECHANNELS wrq->m = (int)pMgmt->uCurrChannel; @@ -372,7 +372,7 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, { int f = (int)pMgmt->uCurrChannel - 1; if(f < 0) - f = 0; + f = 0; wrq->m = frequency_list[f] * 100000; wrq->e = 1; } @@ -387,54 +387,54 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n"); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n"); - return rc; - } + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n"); + return rc; + } switch(*wmode) { case IW_MODE_ADHOC: - if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = TRUE; - } + if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { + pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = TRUE; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n"); break; case IW_MODE_AUTO: case IW_MODE_INFRA: - if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = TRUE; - } + if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = TRUE; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n"); break; case IW_MODE_MASTER: - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; rc = -EOPNOTSUPP; break; - if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { - pMgmt->eConfigMode = WMAC_CONFIG_AP; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = TRUE; - } + if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { + pMgmt->eConfigMode = WMAC_CONFIG_AP; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = TRUE; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n"); break; case IW_MODE_REPEAT: - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; rc = -EOPNOTSUPP; break; default: @@ -451,17 +451,17 @@ void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); // If not managed, assume it's ad-hoc switch (pMgmt->eConfigMode) { case WMAC_CONFIG_ESS_STA: *wmode = IW_MODE_INFRA; break; case WMAC_CONFIG_IBSS_STA: - *wmode = IW_MODE_ADHOC; + *wmode = IW_MODE_ADHOC; break; case WMAC_CONFIG_AUTO: *wmode = IW_MODE_INFRA; @@ -482,9 +482,9 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, { struct iw_range *range = (struct iw_range *) extra; int i,k; - BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n"); if (wrq->pointer) { wrq->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); @@ -501,7 +501,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, } range->num_frequency = k; // Hum... Should put the right values there - range->max_qual.qual = 100; + range->max_qual.qual = 100; range->max_qual.level = 0; range->max_qual.noise = 0; range->sensitivity = 255; @@ -526,19 +526,19 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, range->min_frag = 256; range->max_frag = 2312; - // the encoding capabilities - range->num_encoding_sizes = 3; - // 64(40) bits WEP - range->encoding_size[0] = 5; - // 128(104) bits WEP - range->encoding_size[1] = 13; - // 256 bits for WPA-PSK - range->encoding_size[2] = 32; - // 4 keys are allowed - range->max_encoding_tokens = 4; + // the encoding capabilities + range->num_encoding_sizes = 3; + // 64(40) bits WEP + range->encoding_size[0] = 5; + // 128(104) bits WEP + range->encoding_size[1] = 13; + // 256 bits for WPA-PSK + range->encoding_size[2] = 32; + // 4 keys are allowed + range->max_encoding_tokens = 4; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; range->min_pmp = 0; range->max_pmp = 1000000;// 1 secs @@ -549,7 +549,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; // Transmit Power - values are in mW - range->txpower[0] = 100; + range->txpower[0] = 100; range->num_txpower = 1; range->txpower_capa = IW_TXPOW_MWATT; range->we_version_source = SUPPORTED_WIRELESS_EXT; @@ -577,41 +577,41 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - BYTE ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; + BYTE ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; - PRINT_K(" SIOCSIWAP \n"); + PRINT_K(" SIOCSIWAP \n"); if (wrq->sa_family != ARPHRD_ETHER) rc = -EINVAL; else { memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - //mike :add - if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || - (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ - PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); - return rc; - } - //mike add: if desired AP is hidden ssid(there are two same BSSID in list), - // then ignore,because you don't known which one to be connect with?? - { - unsigned int ii, uSameBssidNum = 0; - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, - pMgmt->abyDesireBSSID)) { - uSameBssidNum++; - } - } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); - return rc; - } - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = TRUE; + //mike :add + if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || + (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ + PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); + return rc; + } + //mike add: if desired AP is hidden ssid(there are two same BSSID in list), + // then ignore,because you don't known which one to be connect with?? + { + unsigned int ii, uSameBssidNum = 0; + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (pMgmt->sBSSList[ii].bActive && + !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, + pMgmt->abyDesireBSSID)) { + uSameBssidNum++; + } + } + if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); + return rc; + } + } + + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = TRUE; } } return rc; @@ -624,18 +624,18 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); + memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) - memset(wrq->sa_data, 0, 6); + if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) + memset(wrq->sa_data, 0, 6); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - } + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); + } wrq->sa_family = ARPHRD_ETHER; return 0; @@ -651,9 +651,9 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, struct sockaddr sock[IW_MAX_AP]; struct iw_quality qual[IW_MAX_AP]; PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); // Only super-user can see AP list if (!capable(CAP_NET_ADMIN)) { @@ -665,11 +665,11 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, PKnownBSS pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - if ( jj >= IW_MAX_AP) - break; + pBSS = &(pMgmt->sBSSList[ii]); + if (!pBSS->bActive) + continue; + if ( jj >= IW_MAX_AP) + break; memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6); sock[jj].sa_family = ARPHRD_ETHER; qual[jj].level = pBSS->uRSSI; @@ -693,105 +693,105 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PWLAN_IE_SSID pItemSSID; - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) - return -EINVAL; + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) + return -EINVAL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n"); - pDevice->fWPA_Authened = FALSE; + pDevice->fWPA_Authened = FALSE; // Check if we asked for `any' if(wrq->flags == 0) { // Just send an empty SSID list memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memset(pMgmt->abyDesireBSSID, 0xFF,6); - PRINT_K("set essid to 'any' \n"); - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Unknown desired AP,so here need not associate?? - return 0; - #endif + memset(pMgmt->abyDesireBSSID, 0xFF,6); + PRINT_K("set essid to 'any' \n"); +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + //Unknown desired AP,so here need not associate?? + return 0; +#endif } else { // Set the SSID memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSID->byElementID = WLAN_EID_SSID; memcpy(pItemSSID->abySSID, extra, wrq->length); - if (pItemSSID->abySSID[wrq->length - 1] == '\0') { - if(wrq->length>0) - pItemSSID->len = wrq->length - 1; - } - else - pItemSSID->len = wrq->length; - PRINT_K("set essid to %s \n",pItemSSID->abySSID); + if (pItemSSID->abySSID[wrq->length - 1] == '\0') { + if(wrq->length>0) + pItemSSID->len = wrq->length - 1; + } + else + pItemSSID->len = wrq->length; + PRINT_K("set essid to %s \n",pItemSSID->abySSID); - //mike:need clear desiredBSSID - if(pItemSSID->len==0) { - memset(pMgmt->abyDesireBSSID, 0xFF,6); - return 0; - } + //mike:need clear desiredBSSID + if(pItemSSID->len==0) { + memset(pMgmt->abyDesireBSSID, 0xFF,6); + return 0; + } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Wext wil order another command of siwap to link with desired AP, - //so here need not associate?? - if(pDevice->bWPASuppWextEnabled == TRUE) { - /*******search if in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned int ii, uSameBssidNum = 0; - - memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); - pCurr = BSSpSearchBSSList(pDevice, - NULL, - abyTmpDesireSSID, - pDevice->eConfigPHYMode - ); - - if (pCurr == NULL){ - PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((void *) pDevice); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, - pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, - WLAN_CMD_SSID, - pMgmt->abyDesireSSID); - } - else { //mike:to find out if that desired SSID is a hidden-ssid AP , - // by means of judging if there are two same BSSID exist in list ? - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, - pCurr->abyBSSID)) { - uSameBssidNum++; - } - } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((void *) pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, - pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, - WLAN_CMD_SSID, - pMgmt->abyDesireSSID); - } - } - } - return 0; - } - #endif - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); + //Wext wil order another command of siwap to link with desired AP, + //so here need not associate?? + if(pDevice->bWPASuppWextEnabled == TRUE) { + /*******search if in hidden ssid mode ****/ + { + PKnownBSS pCurr = NULL; + BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned int ii, uSameBssidNum = 0; + + memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); + pCurr = BSSpSearchBSSList(pDevice, + NULL, + abyTmpDesireSSID, + pDevice->eConfigPHYMode + ); + + if (pCurr == NULL){ + PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); + vResetCommandTimer((void *) pDevice); + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); + } + else { //mike:to find out if that desired SSID is a hidden-ssid AP , + // by means of judging if there are two same BSSID exist in list ? + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (pMgmt->sBSSList[ii].bActive && + !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, + pCurr->abyBSSID)) { + uSameBssidNum++; + } + } + if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); + vResetCommandTimer((void *) pDevice); + pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); + } + } + } + return 0; + } +#endif + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); } - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = TRUE; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = TRUE; } return 0; } @@ -803,16 +803,16 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); // Note : if wrq->u.data.flags != 0, we should // get the relevant SSID from the SSID list... // Get the current SSID - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; memcpy(extra, pItemSSID->abySSID , pItemSSID->len); extra[pItemSSID->len] = '\0'; @@ -827,23 +827,23 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; + int rc = 0; u8 brate = 0; int i; BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; - } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { + rc = -EINVAL; + return rc; + } // First : get a valid bit rate value // Which type of value if((wrq->value < 13) && - (wrq->value >= 0)) { + (wrq->value >= 0)) { // Setting by rate index // Find value in the magic rate table brate = wrq->value; @@ -882,19 +882,19 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, // Fixed mode // One rate, fixed pDevice->bFixRate = TRUE; - if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) { - pDevice->uConnectionRate = 3; - } - else { - pDevice->uConnectionRate = brate; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); - } + if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) { + pDevice->uConnectionRate = 3; + } + else { + pDevice->uConnectionRate = brate; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); + } } else { - pDevice->bFixRate = FALSE; - pDevice->uConnectionRate = 13; - } + pDevice->bFixRate = FALSE; + pDevice->uConnectionRate = 13; + } return rc; } @@ -906,38 +906,38 @@ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); - { - BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - int brate = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); + { + BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + int brate = 0; if (pDevice->uConnectionRate < 13) { - brate = abySupportedRates[pDevice->uConnectionRate]; - }else { - if (pDevice->byBBType == BB_TYPE_11B) - brate = 0x16; - if (pDevice->byBBType == BB_TYPE_11G) - brate = 0x6C; - if (pDevice->byBBType == BB_TYPE_11A) - brate = 0x6C; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->byBBType == BB_TYPE_11B) - brate = 0x16; - if (pDevice->byBBType == BB_TYPE_11G) - brate = 0x6C; - if (pDevice->byBBType == BB_TYPE_11A) - brate = 0x6C; - } + brate = abySupportedRates[pDevice->uConnectionRate]; + }else { + if (pDevice->byBBType == BB_TYPE_11B) + brate = 0x16; + if (pDevice->byBBType == BB_TYPE_11G) + brate = 0x6C; + if (pDevice->byBBType == BB_TYPE_11A) + brate = 0x6C; + } + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (pDevice->byBBType == BB_TYPE_11B) + brate = 0x16; + if (pDevice->byBBType == BB_TYPE_11G) + brate = 0x6C; + if (pDevice->byBBType == BB_TYPE_11A) + brate = 0x6C; + } if (pDevice->uConnectionRate == 13) - brate = abySupportedRates[pDevice->wCurrentRate]; - wrq->value = brate * 500000; - // If more than one rate, set auto - if (pDevice->bFixRate == TRUE) - wrq->fixed = TRUE; - } + brate = abySupportedRates[pDevice->wCurrentRate]; + wrq->value = brate * 500000; + // If more than one rate, set auto + if (pDevice->bFixRate == TRUE) + wrq->fixed = TRUE; + } } /* @@ -966,7 +966,7 @@ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, { PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); wrq->value = pDevice->wRTSThreshold; wrq->disabled = (wrq->value >= 2312); wrq->fixed = 1; @@ -980,20 +980,20 @@ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; - int fthr = wrq->value; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + int rc = 0; + int fthr = wrq->value; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n"); - if (wrq->disabled) + if (wrq->disabled) fthr = 2312; - if((fthr < 256) || (fthr > 2312)) { + if((fthr < 256) || (fthr > 2312)) { rc = -EINVAL; - }else { - fthr &= ~0x1; // Get an even value - pDevice->wFragmentationThreshold = (u16)fthr; - } + }else { + fthr &= ~0x1; // Get an even value + pDevice->wFragmentationThreshold = (u16)fthr; + } return rc; } @@ -1003,9 +1003,9 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); wrq->value = pDevice->wFragmentationThreshold; wrq->disabled = (wrq->value >= 2312); wrq->fixed = 1; @@ -1019,10 +1019,10 @@ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); if (wrq->disabled) { rc = -EINVAL; @@ -1052,8 +1052,8 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); wrq->disabled = 0; // Can't be disabled // Note : by default, display the min retry number @@ -1079,99 +1079,99 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX); int ii,uu, rc = 0; int index = (wrq->flags & IW_ENCODE_INDEX); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); // Check the size of the key if (wrq->length > WLAN_WEP232_KEYLEN) { rc = -EINVAL; - return rc; + return rc; } if (dwKeyIndex > WLAN_WEP_NKEYS) { rc = -EINVAL; - return rc; - } + return rc; + } - if (dwKeyIndex > 0) + if (dwKeyIndex > 0) dwKeyIndex--; // Send the key to the card if (wrq->length > 0) { - if (wrq->length == WLAN_WEP232_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP104_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP40_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); - } - memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); - memcpy(pDevice->abyKey, extra, wrq->length); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); - for (ii = 0; ii < wrq->length; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - KeybSetDefaultKey( pDevice, - &(pDevice->sKey), - dwKeyIndex | (1 << 31), - wrq->length, - NULL, - pDevice->abyKey, - KEY_CTL_WEP - ); - spin_unlock_irq(&pDevice->lock); - } - pDevice->byKeyIndex = (BYTE)dwKeyIndex; - pDevice->uKeyLength = wrq->length; - pDevice->bTransmitKey = TRUE; - pDevice->bEncryptionEnable = TRUE; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + if (wrq->length == WLAN_WEP232_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); + } + else if (wrq->length == WLAN_WEP104_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); + } + else if (wrq->length == WLAN_WEP40_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); + } + memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); + memcpy(pDevice->abyKey, extra, wrq->length); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); + for (ii = 0; ii < wrq->length; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); + } + + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + spin_lock_irq(&pDevice->lock); + KeybSetDefaultKey( pDevice, + &(pDevice->sKey), + dwKeyIndex | (1 << 31), + wrq->length, + NULL, + pDevice->abyKey, + KEY_CTL_WEP + ); + spin_unlock_irq(&pDevice->lock); + } + pDevice->byKeyIndex = (BYTE)dwKeyIndex; + pDevice->uKeyLength = wrq->length; + pDevice->bTransmitKey = TRUE; + pDevice->bEncryptionEnable = TRUE; + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; // Do we want to just set the transmit key index ? if ( index < 4 ) { - pDevice->byKeyIndex = index; + pDevice->byKeyIndex = index; } else if (!(wrq->flags & IW_ENCODE_MODE)) { - rc = -EINVAL; - return rc; - } + rc = -EINVAL; + return rc; + } } // Read the flags if(wrq->flags & IW_ENCODE_DISABLED){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); pMgmt->bShareKeyAlgorithm = FALSE; - pDevice->bEncryptionEnable = FALSE; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - for (uu = 0; uu < MAX_KEY_TABLE; uu++) - MACvDisableKeyEntry(pDevice, uu); - spin_unlock_irq(&pDevice->lock); - } + pDevice->bEncryptionEnable = FALSE; + pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + spin_lock_irq(&pDevice->lock); + for (uu = 0; uu < MAX_KEY_TABLE; uu++) + MACvDisableKeyEntry(pDevice, uu); + spin_unlock_irq(&pDevice->lock); + } } if(wrq->flags & IW_ENCODE_RESTRICTED) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); pMgmt->bShareKeyAlgorithm = TRUE; } if(wrq->flags & IW_ENCODE_OPEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); pMgmt->bShareKeyAlgorithm = FALSE; } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - memset(pMgmt->abyDesireBSSID, 0xFF,6); + memset(pMgmt->abyDesireBSSID, 0xFF,6); #endif return rc; } @@ -1195,9 +1195,9 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, if(pDevice->byKeyIndexbyKeyIndex; } else - index=0; + index=0; }else - index--; + index--; memset(abyKey, 0, WLAN_WEP232_KEYLEN); // Check encryption mode @@ -1212,18 +1212,18 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, wrq->flags |= IW_ENCODE_RESTRICTED; else wrq->flags |= IW_ENCODE_OPEN; - wrq->length=0; + wrq->length=0; if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| - pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key - if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } - }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){ + pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key + if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); + memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); + memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); + } + }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){ + wrq->length = pKey->uKeyLength; + memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); } @@ -1237,15 +1237,15 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n"); - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { + rc = -EINVAL; + return rc; } if (wrq->disabled) { @@ -1254,23 +1254,23 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, return rc; } if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); + pDevice->ePSMode = WMAC_POWER_FAST; + PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); + pDevice->ePSMode = WMAC_POWER_FAST; + PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); } switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n"); rc = -EINVAL; break; case IW_POWER_ALL_R: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n"); rc = -EINVAL; case IW_POWER_ON: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n"); break; default: rc = -EINVAL; @@ -1285,14 +1285,14 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int mode = pDevice->ePSMode; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int mode = pDevice->ePSMode; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); if ((wrq->disabled = (mode == WMAC_POWER_CAM))) - return 0; + return 0; if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); @@ -1311,17 +1311,17 @@ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - long ldBm; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + long ldBm; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); - if (pDevice->bLinkPass == TRUE) { - RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); - wrq->value = ldBm; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); + if (pDevice->bLinkPass == TRUE) { + RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); + wrq->value = ldBm; } else { - wrq->value = 0; - }; + wrq->value = 0; + }; wrq->disabled = (wrq->value == 0); wrq->fixed = 1; return 0; @@ -1338,29 +1338,29 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, static int wpa_version=0; //must be static to save the last value,einsn liu static int pairwise=0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); switch (wrq->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: wpa_version = wrq->value; if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { - PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); + PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); } else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) { - PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); + PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); } else { - PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); + PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); } break; case IW_AUTH_CIPHER_PAIRWISE: pairwise = wrq->value; - PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise); + PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise); if(pairwise == IW_AUTH_CIPHER_CCMP){ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; }else if(pairwise == IW_AUTH_CIPHER_TKIP){ pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; } else if (pairwise == IW_AUTH_CIPHER_WEP40 || - pairwise == IW_AUTH_CIPHER_WEP104) { + pairwise == IW_AUTH_CIPHER_WEP104) { pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; }else if(pairwise == IW_AUTH_CIPHER_NONE){ //do nothing,einsn liu @@ -1368,7 +1368,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_CIPHER_GROUP: - PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value); + PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value); if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED) break; if(pairwise == IW_AUTH_CIPHER_NONE){ @@ -1380,7 +1380,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, } break; case IW_AUTH_KEY_MGMT: - PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value); + PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value); if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){ if(wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; @@ -1398,7 +1398,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, case IW_AUTH_DROP_UNENCRYPTED: break; case IW_AUTH_80211_AUTH_ALG: - PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value); + PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value); if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ pMgmt->bShareKeyAlgorithm=FALSE; }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){ @@ -1420,14 +1420,14 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; pMgmt->bShareKeyAlgorithm = FALSE; pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n"); + PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n"); } break; default: ret = -EOPNOTSUPP; break; } - return ret; + return ret; } int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info, @@ -1463,12 +1463,12 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, pMgmt->wWPAIELen = 0; } - out://not completely ...not necessary in wpa_supplicant 0.5.8 +out://not completely ...not necessary in wpa_supplicant 0.5.8 return ret; } int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, - struct iw_point *wrq, char *extra) + struct iw_point *wrq, char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1489,132 +1489,132 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, } int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, - struct iw_point *wrq, char *extra) + struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; - struct viawget_wpa_param *param=NULL; + struct viawget_wpa_param *param=NULL; //original member - wpa_alg alg_name; - u8 addr[6]; - int key_idx, set_tx=0; - u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 key[64]; - size_t seq_len=0,key_len=0; - u8 *buf; - size_t blen; - u8 key_array[64]; - int ret=0; - -PRINT_K("SIOCSIWENCODEEXT...... \n"); - -blen = sizeof(*param); -buf = kmalloc((int)blen, (int)GFP_KERNEL); -if (buf == NULL) - return -ENOMEM; -memset(buf, 0, blen); -param = (struct viawget_wpa_param *) buf; + wpa_alg alg_name; + u8 addr[6]; + int key_idx, set_tx=0; + u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; + u8 key[64]; + size_t seq_len=0,key_len=0; + u8 *buf; + size_t blen; + u8 key_array[64]; + int ret=0; + + PRINT_K("SIOCSIWENCODEEXT...... \n"); + + blen = sizeof(*param); + buf = kmalloc((int)blen, (int)GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + memset(buf, 0, blen); + param = (struct viawget_wpa_param *) buf; //recover alg_name -switch (ext->alg) { - case IW_ENCODE_ALG_NONE: - alg_name = WPA_ALG_NONE; + switch (ext->alg) { + case IW_ENCODE_ALG_NONE: + alg_name = WPA_ALG_NONE; break; - case IW_ENCODE_ALG_WEP: - alg_name = WPA_ALG_WEP; + case IW_ENCODE_ALG_WEP: + alg_name = WPA_ALG_WEP; break; - case IW_ENCODE_ALG_TKIP: - alg_name = WPA_ALG_TKIP; + case IW_ENCODE_ALG_TKIP: + alg_name = WPA_ALG_TKIP; break; - case IW_ENCODE_ALG_CCMP: - alg_name = WPA_ALG_CCMP; + case IW_ENCODE_ALG_CCMP: + alg_name = WPA_ALG_CCMP; break; - default: + default: PRINT_K("Unknown alg = %d\n",ext->alg); ret= -ENOMEM; goto error; - } + } //recover addr - memcpy(addr, ext->addr.sa_data, ETH_ALEN); + memcpy(addr, ext->addr.sa_data, ETH_ALEN); //recover key_idx - key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; + key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; //recover set_tx -if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - set_tx = 1; + if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + set_tx = 1; //recover seq,seq_len if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - seq_len=IW_ENCODE_SEQ_MAX_SIZE; - memcpy(seq, ext->rx_seq, seq_len); - } -//recover key,key_len -if(ext->key_len) { - key_len=ext->key_len; - memcpy(key, &ext->key[0], key_len); + seq_len=IW_ENCODE_SEQ_MAX_SIZE; + memcpy(seq, ext->rx_seq, seq_len); } -memset(key_array, 0, 64); -if ( key_len > 0) { - memcpy(key_array, key, key_len); - if (key_len == 32) { - // notice ! the oder - memcpy(&key_array[16], &key[24], 8); - memcpy(&key_array[24], &key[16], 8); +//recover key,key_len + if(ext->key_len) { + key_len=ext->key_len; + memcpy(key, &ext->key[0], key_len); } + memset(key_array, 0, 64); + if ( key_len > 0) { + memcpy(key_array, key, key_len); + if (key_len == 32) { + // notice ! the oder + memcpy(&key_array[16], &key[24], 8); + memcpy(&key_array[24], &key[16], 8); + } } /**************Translate iw_encode_ext to viawget_wpa_param****************/ -memcpy(param->addr, addr, ETH_ALEN); -param->u.wpa_key.alg_name = (int)alg_name; -param->u.wpa_key.set_tx = set_tx; -param->u.wpa_key.key_index = key_idx; -param->u.wpa_key.key_len = key_len; -param->u.wpa_key.key = (u8 *)key_array; -param->u.wpa_key.seq = (u8 *)seq; -param->u.wpa_key.seq_len = seq_len; + memcpy(param->addr, addr, ETH_ALEN); + param->u.wpa_key.alg_name = (int)alg_name; + param->u.wpa_key.set_tx = set_tx; + param->u.wpa_key.key_index = key_idx; + param->u.wpa_key.key_len = key_len; + param->u.wpa_key.key = (u8 *)key_array; + param->u.wpa_key.seq = (u8 *)seq; + param->u.wpa_key.seq_len = seq_len; //****set if current action is Network Manager count?? //****this method is so foolish,but there is no other way??? -if(param->u.wpa_key.alg_name == WPA_ALG_NONE) { - if(param->u.wpa_key.key_index ==0) { - pDevice->bwextstep0 = TRUE; - } - if ((pDevice->bwextstep0 == TRUE) && (param->u.wpa_key.key_index == 1)) { - pDevice->bwextstep0 = FALSE; - pDevice->bwextstep1 = TRUE; - } - if ((pDevice->bwextstep1 == TRUE) && (param->u.wpa_key.key_index == 2)) { - pDevice->bwextstep1 = FALSE; - pDevice->bwextstep2 = TRUE; + if(param->u.wpa_key.alg_name == WPA_ALG_NONE) { + if(param->u.wpa_key.key_index ==0) { + pDevice->bwextstep0 = TRUE; + } + if ((pDevice->bwextstep0 == TRUE) && (param->u.wpa_key.key_index == 1)) { + pDevice->bwextstep0 = FALSE; + pDevice->bwextstep1 = TRUE; + } + if ((pDevice->bwextstep1 == TRUE) && (param->u.wpa_key.key_index == 2)) { + pDevice->bwextstep1 = FALSE; + pDevice->bwextstep2 = TRUE; + } + if ((pDevice->bwextstep2 == TRUE)&&(param->u.wpa_key.key_index == 3)) { + pDevice->bwextstep2 = FALSE; + pDevice->bwextstep3 = TRUE; + } + } + if(pDevice->bwextstep3 == TRUE) { + PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); + pDevice->bwextstep0 = FALSE; + pDevice->bwextstep1 = FALSE; + pDevice->bwextstep2 = FALSE; + pDevice->bwextstep3 = FALSE; + pDevice->bWPASuppWextEnabled = TRUE; + memset(pMgmt->abyDesireBSSID, 0xFF,6); + KeyvInitTable(pDevice,&pDevice->sKey); } - if ((pDevice->bwextstep2 == TRUE)&&(param->u.wpa_key.key_index == 3)) { - pDevice->bwextstep2 = FALSE; - pDevice->bwextstep3 = TRUE; - } - } -if(pDevice->bwextstep3 == TRUE) { - PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); - pDevice->bwextstep0 = FALSE; - pDevice->bwextstep1 = FALSE; - pDevice->bwextstep2 = FALSE; - pDevice->bwextstep3 = FALSE; - pDevice->bWPASuppWextEnabled = TRUE; - memset(pMgmt->abyDesireBSSID, 0xFF,6); - KeyvInitTable(pDevice,&pDevice->sKey); - } //****** - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, TRUE); - spin_unlock_irq(&pDevice->lock); + spin_lock_irq(&pDevice->lock); + ret = wpa_set_keys(pDevice, param, TRUE); + spin_unlock_irq(&pDevice->lock); error: -kfree(param); + kfree(param); return ret; } int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - return -EOPNOTSUPP; + return -EOPNOTSUPP; } int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, @@ -1633,10 +1633,10 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, case IW_MLME_DEAUTH: case IW_MLME_DISASSOC: if(pDevice->bLinkPass == TRUE){ - PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); - bScheduleCommand((void *) pDevice, - WLAN_CMD_DISASSOCIATE, - NULL); + PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); + bScheduleCommand((void *) pDevice, + WLAN_CMD_DISASSOCIATE, + NULL); } break; default: @@ -1665,7 +1665,7 @@ static const iw_handler iwctl_handler[] = (iw_handler) NULL, // SIOCGIWPRIV (iw_handler) NULL, // SIOCSIWSTATS (iw_handler) NULL, // SIOCGIWSTATS - (iw_handler) NULL, // SIOCSIWSPY + (iw_handler) NULL, // SIOCSIWSPY (iw_handler) NULL, // SIOCGIWSPY (iw_handler) NULL, // -- hole -- (iw_handler) NULL, // -- hole -- @@ -1713,9 +1713,9 @@ static const iw_handler iwctl_private_handler[] = }; struct iw_priv_args iwctl_private_args[] = { -{ IOCTL_CMD_SET, - IW_PRIV_TYPE_CHAR | 1024, 0, - "set"}, + { IOCTL_CMD_SET, + IW_PRIV_TYPE_CHAR | 1024, 0, + "set"}, }; const struct iw_handler_def iwctl_handler_def = -- GitLab From bb6ec004c153792d7fc1bb2d8cab333c04287680 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:56:35 +0200 Subject: [PATCH 2742/6849] staging: vt6656: iwctl: remove redundant ';' else clauses don't need to be terminated with ';'. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 7618fb94cdf2..ca4e7f0bca59 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -1321,7 +1321,7 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, } else { wrq->value = 0; - }; + } wrq->disabled = (wrq->value == 0); wrq->fixed = 1; return 0; -- GitLab From c91a8d5a7b03ac6801c92087e26dadd968f0e0e7 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:56:43 +0200 Subject: [PATCH 2743/6849] staging: vt6656: iwctl: Fix up variable declarations (whitespace and 'one-per-line') Ensure that we have only one variable declaration per line and for each of those lines we have one space between type and variable name and if there's assignment, then we have one space on each side of the equals sign (and no more than 80 characters per line). Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 199 ++++++++++++++++++--------------- drivers/staging/vt6656/iwctl.h | 4 +- 2 files changed, 111 insertions(+), 92 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index ca4e7f0bca59..9fc9059143ca 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -60,7 +60,7 @@ static const long frequency_list[] = { 5700, 5745, 5765, 5785, 5805, 5825 }; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) { @@ -100,11 +100,11 @@ int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - struct iw_scan_req *req = (struct iw_scan_req *)extra; - BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - PWLAN_IE_SSID pItemSSID=NULL; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + struct iw_scan_req *req = (struct iw_scan_req *)extra; + BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + PWLAN_IE_SSID pItemSSID=NULL; if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) return -EINVAL; @@ -172,12 +172,15 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - int ii, jj, kk; - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PKnownBSS pBSS; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; + int ii; + int jj; + int kk; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PKnownBSS pBSS; + PWLAN_IE_SSID pItemSSID; + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_SUPP_RATES pExtSuppRates; char *current_ev = extra; char *end_buf = extra + IW_SCAN_MAX_DATA; char *current_val = NULL; @@ -320,7 +323,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); @@ -360,8 +363,8 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); @@ -386,8 +389,8 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n"); @@ -450,8 +453,8 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); @@ -481,8 +484,12 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { struct iw_range *range = (struct iw_range *) extra; - int i,k; - BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + int i; + int k; + BYTE abySupportedRates[13] = { + 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, + 0x60, 0x6C, 0x90 + }; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n"); if (wrq->pointer) { @@ -576,10 +583,10 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; - BYTE ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; + BYTE ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; PRINT_K(" SIOCSIWAP \n"); @@ -596,7 +603,8 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, //mike add: if desired AP is hidden ssid(there are two same BSSID in list), // then ignore,because you don't known which one to be connect with?? { - unsigned int ii, uSameBssidNum = 0; + unsigned ii; + unsigned uSameBssidNum = 0; for (ii = 0; ii < MAX_BSS_NUM; ii++) { if (pMgmt->sBSSList[ii].bActive && !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, @@ -623,8 +631,8 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); @@ -647,11 +655,13 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - int ii,jj, rc = 0; + int ii; + int jj; + int rc = 0; struct sockaddr sock[IW_MAX_AP]; struct iw_quality qual[IW_MAX_AP]; - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); // Only super-user can see AP list @@ -692,9 +702,9 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PWLAN_IE_SSID pItemSSID; if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) return -EINVAL; @@ -739,9 +749,10 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, if(pDevice->bWPASuppWextEnabled == TRUE) { /*******search if in hidden ssid mode ****/ { - PKnownBSS pCurr = NULL; - BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned int ii, uSameBssidNum = 0; + PKnownBSS pCurr = NULL; + BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned ii; + unsigned uSameBssidNum = 0; memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); pCurr = BSSpSearchBSSList(pDevice, @@ -802,9 +813,9 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PWLAN_IE_SSID pItemSSID; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); @@ -826,11 +837,14 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; - u8 brate = 0; - int i; - BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + u8 brate = 0; + int i; + BYTE abySupportedRates[13] = { + 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, + 0x60, 0x6C, 0x90 + }; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); @@ -849,7 +863,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, brate = wrq->value; } else { // Setting by frequency value - u8 normvalue = (u8) (wrq->value/500000); + u8 normvalue = (u8) (wrq->value/500000); // Check if rate is valid for (i = 0 ; i < 13 ; i++) { @@ -905,13 +919,17 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); { - BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + BYTE abySupportedRates[13] = { + 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, + 0x48, 0x60, 0x6C, 0x90 + }; int brate = 0; + if (pDevice->uConnectionRate < 13) { brate = abySupportedRates[pDevice->uConnectionRate]; }else { @@ -964,7 +982,7 @@ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq) int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); wrq->value = pDevice->wRTSThreshold; @@ -980,7 +998,7 @@ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; int fthr = wrq->value; @@ -1003,7 +1021,7 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); wrq->value = pDevice->wFragmentationThreshold; @@ -1019,7 +1037,7 @@ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); @@ -1052,7 +1070,7 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); wrq->disabled = 0; // Can't be disabled @@ -1079,10 +1097,12 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX); - int ii,uu, rc = 0; + int ii; + int uu; + int rc = 0; int index = (wrq->flags & IW_ENCODE_INDEX); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); @@ -1179,12 +1199,12 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); char abyKey[WLAN_WEP232_KEYLEN]; - unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); - PSKeyItem pKey = NULL; + unsigned index = (unsigned)(wrq->flags & IW_ENCODE_INDEX); + PSKeyItem pKey = NULL; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); @@ -1237,8 +1257,8 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n"); @@ -1285,8 +1305,8 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int mode = pDevice->ePSMode; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); @@ -1311,7 +1331,7 @@ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); long ldBm; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); @@ -1332,11 +1352,11 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret=0; - static int wpa_version=0; //must be static to save the last value,einsn liu - static int pairwise=0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int ret = 0; + static int wpa_version = 0; //must be static to save the last value,einsn liu + static int pairwise = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); switch (wrq->flags & IW_AUTH_INDEX) { @@ -1439,9 +1459,9 @@ int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info, int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret=0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int ret = 0; if(wrq->length){ if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) { @@ -1470,9 +1490,9 @@ out://not completely ...not necessary in wpa_supplicant 0.5.8 int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret=0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int ret = 0; int space = wrq->length; wrq->length = 0; @@ -1491,21 +1511,23 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; struct viawget_wpa_param *param=NULL; //original member wpa_alg alg_name; - u8 addr[6]; - int key_idx, set_tx=0; - u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; + u8 addr[6]; + int key_idx; + int set_tx=0; + u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; u8 key[64]; - size_t seq_len=0,key_len=0; + size_t seq_len = 0; + size_t key_len = 0; u8 *buf; size_t blen; u8 key_array[64]; - int ret=0; + int ret = 0; PRINT_K("SIOCSIWENCODEEXT...... \n"); @@ -1620,8 +1642,8 @@ int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_mlme *mlme = (struct iw_mlme *)extra; int ret = 0; @@ -1647,8 +1669,7 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, #endif -static const iw_handler iwctl_handler[] = -{ +static const iw_handler iwctl_handler[] = { (iw_handler) NULL, /* SIOCSIWCOMMIT */ (iw_handler) NULL, // SIOCGIWNAME (iw_handler) NULL, // SIOCSIWNWID @@ -1707,8 +1728,7 @@ static const iw_handler iwctl_handler[] = (iw_handler) NULL, // -- hole -- }; -static const iw_handler iwctl_private_handler[] = -{ +static const iw_handler iwctl_private_handler[] = { NULL, // SIOCIWFIRSTPRIV }; @@ -1718,8 +1738,7 @@ struct iw_priv_args iwctl_private_args[] = { "set"}, }; -const struct iw_handler_def iwctl_handler_def = -{ +const struct iw_handler_def iwctl_handler_def = { .get_wireless_stats = &iwctl_get_wireless_stats, .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), .num_private = 0, diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 96fd043a88c6..d056f83a9158 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -141,7 +141,7 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra); #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -extern const struct iw_handler_def iwctl_handler_def; -extern const struct iw_priv_args iwctl_private_args; +extern const struct iw_handler_def iwctl_handler_def; +extern const struct iw_priv_args iwctl_private_args; #endif /* __IWCTL_H__ */ -- GitLab From c5a415cab5f88e7b527a40ab992c06316a59a8af Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:56:50 +0200 Subject: [PATCH 2744/6849] staging: vt6656: iwctl: ensure one space between defined name and value Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 9fc9059143ca..218e14686287 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -47,9 +47,9 @@ #include #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#define SUPPORTED_WIRELESS_EXT 18 +#define SUPPORTED_WIRELESS_EXT 18 #else -#define SUPPORTED_WIRELESS_EXT 17 +#define SUPPORTED_WIRELESS_EXT 17 #endif static const long frequency_list[] = { -- GitLab From 1a6dd0da0fefe0217f0c3a15dbbf3cfaf6909bc4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:56:59 +0200 Subject: [PATCH 2745/6849] staging: vt6656: iwctl: remove redundant cast (to PSDevice) netdev_priv() returns a void*, so there is no reason to explicitly cast to (PSDevice) when assigning to a variable of type PSDevice. The cast is done implicitly. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 218e14686287..eeaee59da827 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -100,7 +100,7 @@ int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_scan_req *req = (struct iw_scan_req *)extra; BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; @@ -175,7 +175,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, int ii; int jj; int kk; - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PKnownBSS pBSS; PWLAN_IE_SSID pItemSSID; @@ -323,7 +323,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); @@ -363,7 +363,7 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); @@ -389,7 +389,7 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; @@ -453,7 +453,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -583,7 +583,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; BYTE ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -631,7 +631,7 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); @@ -660,7 +660,7 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, int rc = 0; struct sockaddr sock[IW_MAX_AP]; struct iw_quality qual[IW_MAX_AP]; - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); @@ -702,7 +702,7 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; @@ -813,7 +813,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; @@ -837,7 +837,7 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); int rc = 0; u8 brate = 0; int i; @@ -919,7 +919,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); @@ -963,7 +963,7 @@ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, */ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled) return -EINVAL; @@ -982,7 +982,7 @@ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq) int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); wrq->value = pDevice->wRTSThreshold; @@ -998,7 +998,7 @@ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); int rc = 0; int fthr = wrq->value; @@ -1021,7 +1021,7 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); wrq->value = pDevice->wFragmentationThreshold; @@ -1037,7 +1037,7 @@ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); @@ -1070,7 +1070,7 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); wrq->disabled = 0; // Can't be disabled @@ -1097,7 +1097,7 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX); int ii; @@ -1199,7 +1199,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); char abyKey[WLAN_WEP232_KEYLEN]; @@ -1257,7 +1257,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; @@ -1305,7 +1305,7 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int mode = pDevice->ePSMode; @@ -1331,7 +1331,7 @@ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); long ldBm; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); @@ -1352,7 +1352,7 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; static int wpa_version = 0; //must be static to save the last value,einsn liu @@ -1459,7 +1459,7 @@ int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info, int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; @@ -1490,7 +1490,7 @@ out://not completely ...not necessary in wpa_supplicant 0.5.8 int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; int space = wrq->length; @@ -1511,7 +1511,7 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; struct viawget_wpa_param *param=NULL; @@ -1642,7 +1642,7 @@ int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_mlme *mlme = (struct iw_mlme *)extra; int ret = 0; -- GitLab From da06f7dbdb0ac4eb0cbf70b8d08b6f921e14d745 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:07 +0200 Subject: [PATCH 2746/6849] staging: vt6656: iwctl: remove unneeded scope block in iwctl_siwessid() Reduce indentation by removing completely redundant scope block in the iwctl_siwessid() function. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 71 ++++++++++++++++------------------ 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index eeaee59da827..3249a017f3d3 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -748,23 +748,41 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, //so here need not associate?? if(pDevice->bWPASuppWextEnabled == TRUE) { /*******search if in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned ii; - unsigned uSameBssidNum = 0; - - memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); - pCurr = BSSpSearchBSSList(pDevice, - NULL, - abyTmpDesireSSID, - pDevice->eConfigPHYMode - ); - - if (pCurr == NULL){ - PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); + PKnownBSS pCurr = NULL; + BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned ii; + unsigned uSameBssidNum = 0; + + memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); + pCurr = BSSpSearchBSSList(pDevice, NULL, + abyTmpDesireSSID, + pDevice->eConfigPHYMode + ); + + if (pCurr == NULL){ + PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); + vResetCommandTimer((void *) pDevice); + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); + } + else { //mike:to find out if that desired SSID is a hidden-ssid AP , + // by means of judging if there are two same BSSID exist in list ? + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (pMgmt->sBSSList[ii].bActive && + !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, + pCurr->abyBSSID)) { + uSameBssidNum++; + } + } + if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); vResetCommandTimer((void *) pDevice); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; + pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); @@ -772,27 +790,6 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } - else { //mike:to find out if that desired SSID is a hidden-ssid AP , - // by means of judging if there are two same BSSID exist in list ? - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, - pCurr->abyBSSID)) { - uSameBssidNum++; - } - } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((void *) pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, - pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, - WLAN_CMD_SSID, - pMgmt->abyDesireSSID); - } - } } return 0; } -- GitLab From bd4208e9225c8b4a0b52ed0f41956c41cdb1cd56 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:13 +0200 Subject: [PATCH 2747/6849] staging: vt6656: iwctl: remove spaces between casts and variables We do not usually write a space between a cast and the variable being converted. this patch removes such spaces where they occour in iwctl.c Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 148 ++++++++++++++++----------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 3249a017f3d3..9b7d7522868b 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -70,7 +70,7 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) pDevice->wstats.status = pDevice->eOPMode; if(pDevice->scStatistic.LinkQuality > 100) pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality; + pDevice->wstats.qual.qual =(BYTE)pDevice->scStatistic.LinkQuality; RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); pDevice->wstats.qual.level = ldBm; pDevice->wstats.qual.noise = 0; @@ -128,7 +128,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); //mike add: active scan OR passive scan OR desire_ssid scan if(wrq->length == sizeof(struct iw_scan_req)) { @@ -146,7 +146,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, pMgmt->eScanType = WMAC_SCAN_PASSIVE; PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); spin_unlock_irq(&pDevice->lock); return 0; @@ -160,7 +160,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, } pMgmt->eScanType = WMAC_SCAN_PASSIVE; - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); return 0; @@ -330,8 +330,8 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, // If setting by frequency, convert to a channel if((wrq->e == 1) && - (wrq->m >= (int) 2.412e8) && - (wrq->m <= (int) 2.487e8)) { + (wrq->m >= (int)2.412e8) && + (wrq->m <= (int)2.487e8)) { int f = wrq->m / 100000; int c = 0; while((c < 14) && (f != frequency_list[c])) @@ -483,7 +483,7 @@ void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) { - struct iw_range *range = (struct iw_range *) extra; + struct iw_range *range = (struct iw_range *)extra; int i; int k; BYTE abySupportedRates[13] = { @@ -761,12 +761,12 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, if (pCurr == NULL){ PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((void *) pDevice); + vResetCommandTimer((void *)pDevice); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *) pDevice, + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } @@ -781,12 +781,12 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, } if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((void *) pDevice); + vResetCommandTimer((void *)pDevice); pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((void *) pDevice, + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } @@ -1272,11 +1272,11 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, } if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: @@ -1533,7 +1533,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, if (buf == NULL) return -ENOMEM; memset(buf, 0, blen); - param = (struct viawget_wpa_param *) buf; + param = (struct viawget_wpa_param *)buf; //recover alg_name switch (ext->alg) { @@ -1653,7 +1653,7 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, case IW_MLME_DISASSOC: if(pDevice->bLinkPass == TRUE){ PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); - bScheduleCommand((void *) pDevice, + bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); } @@ -1667,62 +1667,62 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, #endif static const iw_handler iwctl_handler[] = { - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) NULL, // SIOCGIWNAME - (iw_handler) NULL, // SIOCSIWNWID - (iw_handler) NULL, // SIOCGIWNWID - (iw_handler) NULL, // SIOCSIWFREQ - (iw_handler) NULL, // SIOCGIWFREQ - (iw_handler) NULL, // SIOCSIWMODE - (iw_handler) NULL, // SIOCGIWMODE - (iw_handler) NULL, // SIOCSIWSENS - (iw_handler) NULL, // SIOCGIWSENS - (iw_handler) NULL, // SIOCSIWRANGE - (iw_handler) iwctl_giwrange, // SIOCGIWRANGE - (iw_handler) NULL, // SIOCSIWPRIV - (iw_handler) NULL, // SIOCGIWPRIV - (iw_handler) NULL, // SIOCSIWSTATS - (iw_handler) NULL, // SIOCGIWSTATS - (iw_handler) NULL, // SIOCSIWSPY - (iw_handler) NULL, // SIOCGIWSPY - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWAP - (iw_handler) NULL, // SIOCGIWAP - (iw_handler) NULL, // -- hole -- 0x16 - (iw_handler) NULL, // SIOCGIWAPLIST - (iw_handler) iwctl_siwscan, // SIOCSIWSCAN - (iw_handler) iwctl_giwscan, // SIOCGIWSCAN - (iw_handler) NULL, // SIOCSIWESSID - (iw_handler) NULL, // SIOCGIWESSID - (iw_handler) NULL, // SIOCSIWNICKN - (iw_handler) NULL, // SIOCGIWNICKN - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWRATE 0x20 - (iw_handler) NULL, // SIOCGIWRATE - (iw_handler) NULL, // SIOCSIWRTS - (iw_handler) NULL, // SIOCGIWRTS - (iw_handler) NULL, // SIOCSIWFRAG - (iw_handler) NULL, // SIOCGIWFRAG - (iw_handler) NULL, // SIOCSIWTXPOW - (iw_handler) NULL, // SIOCGIWTXPOW - (iw_handler) NULL, // SIOCSIWRETRY - (iw_handler) NULL, // SIOCGIWRETRY - (iw_handler) NULL, // SIOCSIWENCODE - (iw_handler) NULL, // SIOCGIWENCODE - (iw_handler) NULL, // SIOCSIWPOWER - (iw_handler) NULL, // SIOCGIWPOWER - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWGENIE - (iw_handler) NULL, // SIOCGIWGENIE - (iw_handler) NULL, // SIOCSIWAUTH - (iw_handler) NULL, // SIOCGIWAUTH - (iw_handler) NULL, // SIOCSIWENCODEEXT - (iw_handler) NULL, // SIOCGIWENCODEEXT - (iw_handler) NULL, // SIOCSIWPMKSA - (iw_handler) NULL, // -- hole -- + (iw_handler)NULL, /* SIOCSIWCOMMIT */ + (iw_handler)NULL, // SIOCGIWNAME + (iw_handler)NULL, // SIOCSIWNWID + (iw_handler)NULL, // SIOCGIWNWID + (iw_handler)NULL, // SIOCSIWFREQ + (iw_handler)NULL, // SIOCGIWFREQ + (iw_handler)NULL, // SIOCSIWMODE + (iw_handler)NULL, // SIOCGIWMODE + (iw_handler)NULL, // SIOCSIWSENS + (iw_handler)NULL, // SIOCGIWSENS + (iw_handler)NULL, // SIOCSIWRANGE + (iw_handler)iwctl_giwrange, // SIOCGIWRANGE + (iw_handler)NULL, // SIOCSIWPRIV + (iw_handler)NULL, // SIOCGIWPRIV + (iw_handler)NULL, // SIOCSIWSTATS + (iw_handler)NULL, // SIOCGIWSTATS + (iw_handler)NULL, // SIOCSIWSPY + (iw_handler)NULL, // SIOCGIWSPY + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWAP + (iw_handler)NULL, // SIOCGIWAP + (iw_handler)NULL, // -- hole -- 0x16 + (iw_handler)NULL, // SIOCGIWAPLIST + (iw_handler)iwctl_siwscan, // SIOCSIWSCAN + (iw_handler)iwctl_giwscan, // SIOCGIWSCAN + (iw_handler)NULL, // SIOCSIWESSID + (iw_handler)NULL, // SIOCGIWESSID + (iw_handler)NULL, // SIOCSIWNICKN + (iw_handler)NULL, // SIOCGIWNICKN + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWRATE 0x20 + (iw_handler)NULL, // SIOCGIWRATE + (iw_handler)NULL, // SIOCSIWRTS + (iw_handler)NULL, // SIOCGIWRTS + (iw_handler)NULL, // SIOCSIWFRAG + (iw_handler)NULL, // SIOCGIWFRAG + (iw_handler)NULL, // SIOCSIWTXPOW + (iw_handler)NULL, // SIOCGIWTXPOW + (iw_handler)NULL, // SIOCSIWRETRY + (iw_handler)NULL, // SIOCGIWRETRY + (iw_handler)NULL, // SIOCSIWENCODE + (iw_handler)NULL, // SIOCGIWENCODE + (iw_handler)NULL, // SIOCSIWPOWER + (iw_handler)NULL, // SIOCGIWPOWER + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWGENIE + (iw_handler)NULL, // SIOCGIWGENIE + (iw_handler)NULL, // SIOCSIWAUTH + (iw_handler)NULL, // SIOCGIWAUTH + (iw_handler)NULL, // SIOCSIWENCODEEXT + (iw_handler)NULL, // SIOCGIWENCODEEXT + (iw_handler)NULL, // SIOCSIWPMKSA + (iw_handler)NULL, // -- hole -- }; static const iw_handler iwctl_private_handler[] = { @@ -1740,7 +1740,7 @@ const struct iw_handler_def iwctl_handler_def = { .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), .num_private = 0, .num_private_args = 0, - .standard = (iw_handler *) iwctl_handler, + .standard = (iw_handler *)iwctl_handler, .private = NULL, .private_args = NULL, }; -- GitLab From 0b5168f92d587c328a4ac060a9f3d1a029ddc3b4 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Mon, 25 Jun 2012 13:25:08 +0530 Subject: [PATCH 2748/6849] ARM: tegra: Remove second instance of uart clk In Tegra30 clock file two clk objects were created for same UART clock. Remove the duplicates and add clock aliases instead. Update the Tegra20 clock file to make the names consistent. Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/tegra2_clocks.c | 20 ++++++++++---------- arch/arm/mach-tegra/tegra30_clocks.c | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index b59315ce3691..034d9529b51e 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -2189,11 +2189,11 @@ static struct clk tegra_list_clks[] = { PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), - PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX), - PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX), + PERIPH_CLK("uarta", "tegra-uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX), + PERIPH_CLK("uartb", "tegra-uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX), + PERIPH_CLK("uartc", "tegra-uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX), + PERIPH_CLK("uartd", "tegra-uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX), + PERIPH_CLK("uarte", "tegra-uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX), PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */ PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ @@ -2245,11 +2245,11 @@ static struct clk tegra_list_clks[] = { * table under two names. */ static struct clk_duplicate tegra_clk_duplicates[] = { - CLK_DUPLICATE("uarta", "tegra_uart.0", NULL), - CLK_DUPLICATE("uartb", "tegra_uart.1", NULL), - CLK_DUPLICATE("uartc", "tegra_uart.2", NULL), - CLK_DUPLICATE("uartd", "tegra_uart.3", NULL), - CLK_DUPLICATE("uarte", "tegra_uart.4", NULL), + CLK_DUPLICATE("uarta", "serial8250.0", NULL), + CLK_DUPLICATE("uartb", "serial8250.1", NULL), + CLK_DUPLICATE("uartc", "serial8250.2", NULL), + CLK_DUPLICATE("uartd", "serial8250.3", NULL), + CLK_DUPLICATE("uarte", "serial8250.4", NULL), CLK_DUPLICATE("usbd", "utmip-pad", NULL), CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), CLK_DUPLICATE("usbd", "tegra-otg", NULL), diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c index e33fe4b14a2a..e1a74895dc3a 100644 --- a/arch/arm/mach-tegra/tegra30_clocks.c +++ b/arch/arm/mach-tegra/tegra30_clocks.c @@ -2924,16 +2924,11 @@ struct clk tegra_list_clks[] = { PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), PERIPH_CLK("i2c4", "tegra-i2c.3", NULL, 103, 0x3c4, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), PERIPH_CLK("i2c5", "tegra-i2c.4", NULL, 47, 0x128, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), - PERIPH_CLK("uarta", "tegra_uart.0", NULL, 6, 0x178, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uartb", "tegra_uart.1", NULL, 7, 0x17c, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uartc", "tegra_uart.2", NULL, 55, 0x1a0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uartd", "tegra_uart.3", NULL, 65, 0x1c0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uarte", "tegra_uart.4", NULL, 66, 0x1c4, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uarta_dbg", "serial8250.0", "uarta", 6, 0x178, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uartb_dbg", "serial8250.0", "uartb", 7, 0x17c, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uartc_dbg", "serial8250.0", "uartc", 55, 0x1a0, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uartd_dbg", "serial8250.0", "uartd", 65, 0x1c0, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), - PERIPH_CLK("uarte_dbg", "serial8250.0", "uarte", 66, 0x1c4, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uarta", "tegra-uart.0", NULL, 6, 0x178, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartb", "tegra-uart.1", NULL, 7, 0x17c, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartc", "tegra-uart.2", NULL, 55, 0x1a0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartd", "tegra-uart.3", NULL, 65, 0x1c0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uarte", "tegra-uart.4", NULL, 66, 0x1c4, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), PERIPH_CLK_EX("vi", "tegra_camera", "vi", 20, 0x148, 425000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT, &tegra_vi_clk_ops), PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET), PERIPH_CLK("3d2", "3d2", NULL, 98, 0x3b0, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET), @@ -2983,6 +2978,11 @@ struct clk tegra_list_clks[] = { * table under two names. */ struct clk_duplicate tegra_clk_duplicates[] = { + CLK_DUPLICATE("uarta", "serial8250.0", NULL), + CLK_DUPLICATE("uartb", "serial8250.1", NULL), + CLK_DUPLICATE("uartc", "serial8250.2", NULL), + CLK_DUPLICATE("uartd", "serial8250.3", NULL), + CLK_DUPLICATE("uarte", "serial8250.4", NULL), CLK_DUPLICATE("usbd", "utmip-pad", NULL), CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), CLK_DUPLICATE("usbd", "tegra-otg", NULL), -- GitLab From f269d1c2a728767c5ba152b2fcb60387d902d259 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:20 +0200 Subject: [PATCH 2749/6849] staging: vt6656: iwctl: space after if/for/while/switch Our coding style dictates a space after if/for/while/switch and the opening parenthesis. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 144 ++++++++++++++++----------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 9b7d7522868b..4254455f8746 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -68,7 +68,7 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) long ldBm; pDevice->wstats.status = pDevice->eOPMode; - if(pDevice->scStatistic.LinkQuality > 100) + if (pDevice->scStatistic.LinkQuality > 100) pDevice->scStatistic.LinkQuality = 100; pDevice->wstats.qual.qual =(BYTE)pDevice->scStatistic.LinkQuality; RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); @@ -117,7 +117,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, return -EAGAIN; } - if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! + if (pDevice->byReAssocCount > 0) { //reject scan when re-associating! //send scan event to wpa_Supplicant union iwreq_data wrqu; PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); @@ -131,14 +131,14 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); //mike add: active scan OR passive scan OR desire_ssid scan - if(wrq->length == sizeof(struct iw_scan_req)) { + if (wrq->length == sizeof(struct iw_scan_req)) { if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); pItemSSID = (PWLAN_IE_SSID)abyScanSSID; pItemSSID->byElementID = WLAN_EID_SSID; memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { - if(req->essid_len>0) + if (req->essid_len>0) pItemSSID->len = req->essid_len - 1; } else @@ -151,7 +151,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, return 0; } - else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan + else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan pMgmt->eScanType = WMAC_SCAN_PASSIVE; } } @@ -235,7 +235,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); { int f = (int)pBSS->uChannel - 1; - if(f < 0)f = 0; + if (f < 0)f = 0; iwe.u.freq.m = frequency_list[f] * 100000; iwe.u.freq.e = 1; } @@ -247,9 +247,9 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.qual.level = ldBm; iwe.u.qual.noise = 0; - if(-ldBm<50){ + if (-ldBm<50){ iwe.u.qual.qual = 100; - }else if(-ldBm > 90) { + }else if (-ldBm > 90) { iwe.u.qual.qual = 0; }else { iwe.u.qual.qual=(40-(-ldBm-50))*100/40; @@ -288,7 +288,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } - if((current_val - current_ev) > IW_EV_LCP_LEN) + if ((current_val - current_ev) > IW_EV_LCP_LEN) current_ev = current_val; memset(&iwe, 0, sizeof(iwe)); @@ -329,22 +329,22 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); // If setting by frequency, convert to a channel - if((wrq->e == 1) && + if ((wrq->e == 1) && (wrq->m >= (int)2.412e8) && (wrq->m <= (int)2.487e8)) { int f = wrq->m / 100000; int c = 0; - while((c < 14) && (f != frequency_list[c])) + while ((c < 14) && (f != frequency_list[c])) c++; wrq->e = 0; wrq->m = c + 1; } // Setting by channel number - if((wrq->m > 14) || (wrq->e > 0)) + if ((wrq->m > 14) || (wrq->e > 0)) rc = -EOPNOTSUPP; else { int channel = wrq->m; - if((channel < 1) || (channel > 14)) { + if ((channel < 1) || (channel > 14)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m); rc = -EINVAL; } else { @@ -374,7 +374,7 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, #else { int f = (int)pMgmt->uCurrChannel - 1; - if(f < 0) + if (f < 0) f = 0; wrq->m = frequency_list[f] * 100000; wrq->e = 1; @@ -400,7 +400,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, return rc; } - switch(*wmode) { + switch (*wmode) { case IW_MODE_ADHOC: if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { @@ -515,7 +515,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, for (i = 0 ; i < 13 ; i++) { range->bitrate[i] = abySupportedRates[i] * 500000; - if(range->bitrate[i] == 0) + if (range->bitrate[i] == 0) break; } range->num_bitrates = i; @@ -523,7 +523,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, // Set an indication of the max TCP throughput // in bit/s that we can expect using this interface. // May be use for QoS stuff... Jean II - if(i > 2) + if (i > 2) range->throughput = 5 * 1000 * 1000; else range->throughput = 1.5 * 1000 * 1000; @@ -612,7 +612,7 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, uSameBssidNum++; } } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); return rc; } @@ -713,7 +713,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, pDevice->fWPA_Authened = FALSE; // Check if we asked for `any' - if(wrq->flags == 0) { + if (wrq->flags == 0) { // Just send an empty SSID list memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); memset(pMgmt->abyDesireBSSID, 0xFF,6); @@ -730,7 +730,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, memcpy(pItemSSID->abySSID, extra, wrq->length); if (pItemSSID->abySSID[wrq->length - 1] == '\0') { - if(wrq->length>0) + if (wrq->length>0) pItemSSID->len = wrq->length - 1; } else @@ -738,7 +738,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, PRINT_K("set essid to %s \n",pItemSSID->abySSID); //mike:need clear desiredBSSID - if(pItemSSID->len==0) { + if (pItemSSID->len==0) { memset(pMgmt->abyDesireBSSID, 0xFF,6); return 0; } @@ -746,7 +746,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //Wext wil order another command of siwap to link with desired AP, //so here need not associate?? - if(pDevice->bWPASuppWextEnabled == TRUE) { + if (pDevice->bWPASuppWextEnabled == TRUE) { /*******search if in hidden ssid mode ****/ PKnownBSS pCurr = NULL; BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; @@ -779,7 +779,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, uSameBssidNum++; } } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); vResetCommandTimer((void *)pDevice); pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! @@ -853,7 +853,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, // First : get a valid bit rate value // Which type of value - if((wrq->value < 13) && + if ((wrq->value < 13) && (wrq->value >= 0)) { // Setting by rate index // Find value in the magic rate table @@ -864,32 +864,32 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, // Check if rate is valid for (i = 0 ; i < 13 ; i++) { - if(normvalue == abySupportedRates[i]) { + if (normvalue == abySupportedRates[i]) { brate = i; break; } } } // -1 designed the max rate (mostly auto mode) - if(wrq->value == -1) { + if (wrq->value == -1) { // Get the highest available rate for (i = 0 ; i < 13 ; i++) { - if(abySupportedRates[i] == 0) + if (abySupportedRates[i] == 0) break; } - if(i != 0) + if (i != 0) brate = i - 1; } // Check that it is valid // brate is index of abySupportedRates[] - if(brate > 13 ) { + if (brate > 13 ) { rc = -EINVAL; return rc; } // Now, check if we want a fixed or auto value - if(wrq->fixed != 0) { + if (wrq->fixed != 0) { // Fixed mode // One rate, fixed pDevice->bFixRate = TRUE; @@ -1003,7 +1003,7 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, if (wrq->disabled) fthr = 2312; - if((fthr < 256) || (fthr > 2312)) { + if ((fthr < 256) || (fthr > 2312)) { rc = -EINVAL; }else { fthr &= ~0x1; // Get an even value @@ -1045,7 +1045,7 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, } if (wrq->flags & IW_RETRY_LIMIT) { - if(wrq->flags & IW_RETRY_MAX) + if (wrq->flags & IW_RETRY_MAX) pDevice->byLongRetryLimit = wrq->value; else if (wrq->flags & IW_RETRY_MIN) pDevice->byShortRetryLimit = wrq->value; @@ -1072,16 +1072,16 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, wrq->disabled = 0; // Can't be disabled // Note : by default, display the min retry number - if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { wrq->flags = IW_RETRY_LIFETIME; wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms - } else if((wrq->flags & IW_RETRY_MAX)) { + } else if ((wrq->flags & IW_RETRY_MAX)) { wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrq->value = (int)pDevice->byLongRetryLimit; } else { wrq->flags = IW_RETRY_LIMIT; wrq->value = (int)pDevice->byShortRetryLimit; - if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) + if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) wrq->flags |= IW_RETRY_MIN; } @@ -1165,7 +1165,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, } } // Read the flags - if(wrq->flags & IW_ENCODE_DISABLED){ + if (wrq->flags & IW_ENCODE_DISABLED){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); pMgmt->bShareKeyAlgorithm = FALSE; @@ -1178,11 +1178,11 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, spin_unlock_irq(&pDevice->lock); } } - if(wrq->flags & IW_ENCODE_RESTRICTED) { + if (wrq->flags & IW_ENCODE_RESTRICTED) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); pMgmt->bShareKeyAlgorithm = TRUE; } - if(wrq->flags & IW_ENCODE_OPEN) { + if (wrq->flags & IW_ENCODE_OPEN) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); pMgmt->bShareKeyAlgorithm = FALSE; } @@ -1208,8 +1208,8 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, if (index > WLAN_WEP_NKEYS) { return -EINVAL; } - if(index<1){//get default key - if(pDevice->byKeyIndexbyKeyIndexbyKeyIndex; } else index=0; @@ -1231,7 +1231,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, wrq->flags |= IW_ENCODE_OPEN; wrq->length=0; - if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| + if ((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ wrq->length = pKey->uKeyLength; @@ -1359,10 +1359,10 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, switch (wrq->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: wpa_version = wrq->value; - if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { + if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); } - else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) { + else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) { PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); } else { @@ -1372,24 +1372,24 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, case IW_AUTH_CIPHER_PAIRWISE: pairwise = wrq->value; PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise); - if(pairwise == IW_AUTH_CIPHER_CCMP){ + if (pairwise == IW_AUTH_CIPHER_CCMP){ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - }else if(pairwise == IW_AUTH_CIPHER_TKIP){ + }else if (pairwise == IW_AUTH_CIPHER_TKIP){ pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; } else if (pairwise == IW_AUTH_CIPHER_WEP40 || pairwise == IW_AUTH_CIPHER_WEP104) { pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - }else if(pairwise == IW_AUTH_CIPHER_NONE){ + }else if (pairwise == IW_AUTH_CIPHER_NONE){ //do nothing,einsn liu }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; break; case IW_AUTH_CIPHER_GROUP: PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value); - if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED) + if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED) break; - if(pairwise == IW_AUTH_CIPHER_NONE){ - if(wrq->value == IW_AUTH_CIPHER_CCMP){ + if (pairwise == IW_AUTH_CIPHER_NONE){ + if (wrq->value == IW_AUTH_CIPHER_CCMP){ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; }else { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; @@ -1398,14 +1398,14 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_KEY_MGMT: PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value); - if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){ - if(wrq->value == IW_AUTH_KEY_MGMT_PSK) + if (wpa_version == IW_AUTH_WPA_VERSION_WPA2){ + if (wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; else pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){ - if(wrq->value == 0){ + }else if (wpa_version == IW_AUTH_WPA_VERSION_WPA){ + if (wrq->value == 0){ pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK) + }else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; else pMgmt->eAuthenMode = WMAC_AUTH_WPA; } @@ -1416,9 +1416,9 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_80211_AUTH_ALG: PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value); - if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ + if (wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ pMgmt->bShareKeyAlgorithm=FALSE; - }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){ + }else if (wrq->value==IW_AUTH_ALG_SHARED_KEY){ pMgmt->bShareKeyAlgorithm=TRUE; } break; @@ -1431,7 +1431,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_PRIVACY_INVOKED: pDevice->bEncryptionEnable = !!wrq->value; - if(pDevice->bEncryptionEnable == FALSE){ + if (pDevice->bEncryptionEnable == FALSE){ wpa_version = 0; pairwise = 0; pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; @@ -1460,17 +1460,17 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; - if(wrq->length){ + if (wrq->length){ if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) { ret = -EINVAL; goto out; } - if(wrq->length > MAX_WPA_IE_LEN){ + if (wrq->length > MAX_WPA_IE_LEN){ ret = -ENOMEM; goto out; } memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); - if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){ + if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){ ret = -EFAULT; goto out; } @@ -1493,10 +1493,10 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, int space = wrq->length; wrq->length = 0; - if(pMgmt->wWPAIELen > 0){ + if (pMgmt->wWPAIELen > 0){ wrq->length = pMgmt->wWPAIELen; - if(pMgmt->wWPAIELen <= space){ - if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){ + if (pMgmt->wWPAIELen <= space){ + if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){ ret = -EFAULT; } }else @@ -1559,15 +1559,15 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, //recover key_idx key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; //recover set_tx - if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) set_tx = 1; //recover seq,seq_len - if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { seq_len=IW_ENCODE_SEQ_MAX_SIZE; memcpy(seq, ext->rx_seq, seq_len); } //recover key,key_len - if(ext->key_len) { + if (ext->key_len) { key_len=ext->key_len; memcpy(key, &ext->key[0], key_len); } @@ -1593,8 +1593,8 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, //****set if current action is Network Manager count?? //****this method is so foolish,but there is no other way??? - if(param->u.wpa_key.alg_name == WPA_ALG_NONE) { - if(param->u.wpa_key.key_index ==0) { + if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { + if (param->u.wpa_key.key_index ==0) { pDevice->bwextstep0 = TRUE; } if ((pDevice->bwextstep0 == TRUE) && (param->u.wpa_key.key_index == 1)) { @@ -1610,7 +1610,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, pDevice->bwextstep3 = TRUE; } } - if(pDevice->bwextstep3 == TRUE) { + if (pDevice->bwextstep3 == TRUE) { PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); pDevice->bwextstep0 = FALSE; pDevice->bwextstep1 = FALSE; @@ -1644,14 +1644,14 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_mlme *mlme = (struct iw_mlme *)extra; int ret = 0; - if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){ + if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){ ret = -EINVAL; return ret; } - switch(mlme->cmd){ + switch (mlme->cmd){ case IW_MLME_DEAUTH: case IW_MLME_DISASSOC: - if(pDevice->bLinkPass == TRUE){ + if (pDevice->bLinkPass == TRUE){ PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, -- GitLab From 5a67363792715dd69e106762645ed2c41fcd37b0 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:27 +0200 Subject: [PATCH 2750/6849] staging: vt6656: iwctl: comment cleanup All comments now have one space between the code they follow and the comment start chars and one space after the comment start chars and the comment text. Also cleaned up some spacing within comments - mostly removed space before ':' and added space after ',' etc. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 265 +++++++++++++++++---------------- 1 file changed, 133 insertions(+), 132 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 4254455f8746..c639a3c9030f 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -85,7 +85,7 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) } /* - * Wireless Handler : get protocol name + * Wireless Handler: get protocol name */ int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, char *wrq, char *extra) @@ -95,7 +95,7 @@ int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set scan + * Wireless Handler: set scan */ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -117,8 +117,8 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, return -EAGAIN; } - if (pDevice->byReAssocCount > 0) { //reject scan when re-associating! -//send scan event to wpa_Supplicant + if (pDevice->byReAssocCount > 0) { // reject scan when re-associating! + // send scan event to wpa_Supplicant union iwreq_data wrqu; PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); memset(&wrqu, 0, sizeof(wrqu)); @@ -130,9 +130,9 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); -//mike add: active scan OR passive scan OR desire_ssid scan + // mike add: active scan OR passive scan OR desire_ssid scan if (wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan + if (wrq->flags & IW_SCAN_THIS_ESSID) { // desire_ssid scan memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); pItemSSID = (PWLAN_IE_SSID)abyScanSSID; pItemSSID->byElementID = WLAN_EID_SSID; @@ -151,11 +151,11 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, return 0; } - else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan + else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { // passive scan pMgmt->eScanType = WMAC_SCAN_PASSIVE; } } - else { //active scan + else { // active scan pMgmt->eScanType = WMAC_SCAN_ACTIVE; } @@ -200,20 +200,20 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, break; pBSS = &(pMgmt->sBSSList[jj]); if (pBSS->bActive) { - //ADD mac address + // ADD mac address memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); - //ADD ssid + // ADD ssid memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWESSID; pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; iwe.u.data.length = pItemSSID->len; iwe.u.data.flags = 1; current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); - //ADD mode + // ADD mode memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { @@ -224,7 +224,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, } iwe.len = IW_EV_UINT_LEN; current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - //ADD frequency + // ADD frequency pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; memset(&iwe, 0, sizeof(iwe)); @@ -240,7 +240,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.freq.e = 1; } current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); - //ADD quality + // ADD quality memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); @@ -257,7 +257,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.qual.updated=7; current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); - //ADD encryption + // ADD encryption memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; iwe.u.data.length = 0; @@ -312,13 +312,13 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, } } - }// for + } // for wrq->length = current_ev - extra; return 0; } /* - * Wireless Handler : set frequence or channel + * Wireless Handler: set frequence or channel */ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) @@ -358,7 +358,7 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get frequence or channel + * Wireless Handler: get frequence or channel */ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, char *extra) @@ -384,7 +384,7 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set operation mode + * Wireless Handler: set operation mode */ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) @@ -448,7 +448,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get operation mode + * Wireless Handler: get operation mode */ void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) @@ -478,7 +478,7 @@ void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get capability range + * Wireless Handler: get capability range */ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -499,7 +499,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, range->max_nwid = 0x0000; range->num_channels = 14; // Should be based on cap_rid.country to give only - // what the current card support + // what the current card support k = 0; for (i = 0; i < 14; i++) { range->freq[k].i = i + 1; // List index @@ -548,9 +548,9 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; range->min_pmp = 0; - range->max_pmp = 1000000;// 1 secs + range->max_pmp = 1000000; // 1 secs range->min_pmt = 0; - range->max_pmt = 1000000;// 1 secs + range->max_pmt = 1000000; // 1 secs range->pmp_flags = IW_POWER_PERIOD; range->pmt_flags = IW_POWER_TIMEOUT; range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; @@ -572,7 +572,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, // Note : with or without the (local->rssi), results // are somewhat different. - Jean II range->avg_qual.qual = 6; - range->avg_qual.level = 176; // -80 dBm + range->avg_qual.level = 176; // -80 dBm range->avg_qual.noise = 0; } } @@ -594,14 +594,15 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, rc = -EINVAL; else { memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - //mike :add + // mike: add if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); return rc; } - //mike add: if desired AP is hidden ssid(there are two same BSSID in list), - // then ignore,because you don't known which one to be connect with?? + // mike add: if desired AP is hidden ssid(there are + // two same BSSID in list), then ignore,because you + // don't known which one to be connect with?? { unsigned ii; unsigned uSameBssidNum = 0; @@ -626,7 +627,7 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get ap mac address + * Wireless Handler: get ap mac address */ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, char *extra) @@ -650,7 +651,7 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get ap list + * Wireless Handler: get ap list */ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -697,7 +698,7 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set essid + * Wireless Handler: set essid */ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -737,15 +738,15 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, pItemSSID->len = wrq->length; PRINT_K("set essid to %s \n",pItemSSID->abySSID); - //mike:need clear desiredBSSID + // mike: need clear desiredBSSID if (pItemSSID->len==0) { memset(pMgmt->abyDesireBSSID, 0xFF,6); return 0; } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Wext wil order another command of siwap to link with desired AP, - //so here need not associate?? + // Wext wil order another command of siwap to link + // with desired AP, so here need not associate?? if (pDevice->bWPASuppWextEnabled == TRUE) { /*******search if in hidden ssid mode ****/ PKnownBSS pCurr = NULL; @@ -770,8 +771,9 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } - else { //mike:to find out if that desired SSID is a hidden-ssid AP , - // by means of judging if there are two same BSSID exist in list ? + else { // mike: to find out if that desired SSID is a + // hidden-ssid AP, by means of judging if there + // are two same BSSID exist in list ? for (ii = 0; ii < MAX_BSS_NUM; ii++) { if (pMgmt->sBSSList[ii].bActive && !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, @@ -779,10 +781,10 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, uSameBssidNum++; } } - if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + if (uSameBssidNum >= 2) { // hit: desired AP is in hidden ssid mode!!! PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); vResetCommandTimer((void *)pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! + pMgmt->eScanType = WMAC_SCAN_PASSIVE; // this scan type, you'll submit scan result! bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); @@ -805,7 +807,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get essid + * Wireless Handler: get essid */ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -816,8 +818,8 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); - // Note : if wrq->u.data.flags != 0, we should - // get the relevant SSID from the SSID list... + // Note: if wrq->u.data.flags != 0, we should get the relevant + // SSID from the SSID list... // Get the current SSID pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; @@ -829,7 +831,7 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set data rate + * Wireless Handler: set data rate */ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -843,14 +845,13 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, 0x60, 0x6C, 0x90 }; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { rc = -EINVAL; return rc; } - // First : get a valid bit rate value + // First: get a valid bit rate value // Which type of value if ((wrq->value < 13) && @@ -911,7 +912,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get data rate + * Wireless Handler: get data rate */ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -956,7 +957,7 @@ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set rts threshold + * Wireless Handler: set rts threshold */ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq) { @@ -974,7 +975,7 @@ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq) } /* - * Wireless Handler : get rts + * Wireless Handler: get rts */ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -990,7 +991,7 @@ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set fragment threshold + * Wireless Handler: set fragment threshold */ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1006,14 +1007,14 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, if ((fthr < 256) || (fthr > 2312)) { rc = -EINVAL; }else { - fthr &= ~0x1; // Get an even value + fthr &= ~0x1; // Get an even value pDevice->wFragmentationThreshold = (u16)fthr; } return rc; } /* - * Wireless Handler : get fragment threshold + * Wireless Handler: get fragment threshold */ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1029,7 +1030,7 @@ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set retry threshold + * Wireless Handler: set retry threshold */ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1062,19 +1063,19 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get retry threshold + * Wireless Handler: get retry threshold */ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { PSDevice pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); - wrq->disabled = 0; // Can't be disabled + wrq->disabled = 0; // Can't be disabled - // Note : by default, display the min retry number + // Note: by default, display the min retry number if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { wrq->flags = IW_RETRY_LIFETIME; - wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms + wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; // ms } else if ((wrq->flags & IW_RETRY_MAX)) { wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrq->value = (int)pDevice->byLongRetryLimit; @@ -1089,7 +1090,7 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set encode mode + * Wireless Handler: set encode mode */ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -1156,7 +1157,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, pDevice->bEncryptionEnable = TRUE; pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - // Do we want to just set the transmit key index ? + // Do we want to just set the transmit key index? if ( index < 4 ) { pDevice->byKeyIndex = index; } else if (!(wrq->flags & IW_ENCODE_MODE)) { @@ -1208,7 +1209,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, if (index > WLAN_WEP_NKEYS) { return -EINVAL; } - if (index<1){//get default key + if (index<1){ // get default key if (pDevice->byKeyIndexbyKeyIndex; } else @@ -1232,7 +1233,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, wrq->length=0; if ((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| - pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key + pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){ // get wpa pairwise key if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ wrq->length = pKey->uKeyLength; memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); @@ -1249,7 +1250,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : set power mode + * Wireless Handler: set power mode */ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1297,7 +1298,7 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get power mode + * Wireless Handler: get power mode */ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1323,7 +1324,7 @@ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, } /* - * Wireless Handler : get Sensitivity + * Wireless Handler: get Sensitivity */ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1352,7 +1353,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; - static int wpa_version = 0; //must be static to save the last value,einsn liu + static int wpa_version = 0; // must be static to save the last value, einsn liu static int pairwise = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); @@ -1380,7 +1381,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, pairwise == IW_AUTH_CIPHER_WEP104) { pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; }else if (pairwise == IW_AUTH_CIPHER_NONE){ - //do nothing,einsn liu + // do nothing, einsn liu }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; break; @@ -1411,7 +1412,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, } break; case IW_AUTH_TKIP_COUNTERMEASURES: - break; /* FIXME */ + break; /* FIXME */ case IW_AUTH_DROP_UNENCRYPTED: break; case IW_AUTH_80211_AUTH_ALG: @@ -1480,7 +1481,7 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, pMgmt->wWPAIELen = 0; } -out://not completely ...not necessary in wpa_supplicant 0.5.8 +out: // not completely ...not necessary in wpa_supplicant 0.5.8 return ret; } @@ -1512,7 +1513,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; struct viawget_wpa_param *param=NULL; -//original member +// original member wpa_alg alg_name; u8 addr[6]; int key_idx; @@ -1535,7 +1536,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, memset(buf, 0, blen); param = (struct viawget_wpa_param *)buf; -//recover alg_name +// recover alg_name switch (ext->alg) { case IW_ENCODE_ALG_NONE: alg_name = WPA_ALG_NONE; @@ -1554,19 +1555,19 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, ret= -ENOMEM; goto error; } -//recover addr +// recover addr memcpy(addr, ext->addr.sa_data, ETH_ALEN); -//recover key_idx +// recover key_idx key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; -//recover set_tx +// recover set_tx if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) set_tx = 1; -//recover seq,seq_len +// recover seq,seq_len if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { seq_len=IW_ENCODE_SEQ_MAX_SIZE; memcpy(seq, ext->rx_seq, seq_len); } -//recover key,key_len +// recover key,key_len if (ext->key_len) { key_len=ext->key_len; memcpy(key, &ext->key[0], key_len); @@ -1591,8 +1592,8 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, param->u.wpa_key.seq = (u8 *)seq; param->u.wpa_key.seq_len = seq_len; -//****set if current action is Network Manager count?? -//****this method is so foolish,but there is no other way??? +/****set if current action is Network Manager count?? */ +/****this method is so foolish,but there is no other way??? */ if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { if (param->u.wpa_key.key_index ==0) { pDevice->bwextstep0 = TRUE; @@ -1620,7 +1621,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, memset(pMgmt->abyDesireBSSID, 0xFF,6); KeyvInitTable(pDevice,&pDevice->sKey); } -//****** +/*******/ spin_lock_irq(&pDevice->lock); ret = wpa_set_keys(pDevice, param, TRUE); spin_unlock_irq(&pDevice->lock); @@ -1667,66 +1668,66 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, #endif static const iw_handler iwctl_handler[] = { - (iw_handler)NULL, /* SIOCSIWCOMMIT */ - (iw_handler)NULL, // SIOCGIWNAME - (iw_handler)NULL, // SIOCSIWNWID - (iw_handler)NULL, // SIOCGIWNWID - (iw_handler)NULL, // SIOCSIWFREQ - (iw_handler)NULL, // SIOCGIWFREQ - (iw_handler)NULL, // SIOCSIWMODE - (iw_handler)NULL, // SIOCGIWMODE - (iw_handler)NULL, // SIOCSIWSENS - (iw_handler)NULL, // SIOCGIWSENS - (iw_handler)NULL, // SIOCSIWRANGE - (iw_handler)iwctl_giwrange, // SIOCGIWRANGE - (iw_handler)NULL, // SIOCSIWPRIV - (iw_handler)NULL, // SIOCGIWPRIV - (iw_handler)NULL, // SIOCSIWSTATS - (iw_handler)NULL, // SIOCGIWSTATS - (iw_handler)NULL, // SIOCSIWSPY - (iw_handler)NULL, // SIOCGIWSPY - (iw_handler)NULL, // -- hole -- - (iw_handler)NULL, // -- hole -- - (iw_handler)NULL, // SIOCSIWAP - (iw_handler)NULL, // SIOCGIWAP - (iw_handler)NULL, // -- hole -- 0x16 - (iw_handler)NULL, // SIOCGIWAPLIST - (iw_handler)iwctl_siwscan, // SIOCSIWSCAN - (iw_handler)iwctl_giwscan, // SIOCGIWSCAN - (iw_handler)NULL, // SIOCSIWESSID - (iw_handler)NULL, // SIOCGIWESSID - (iw_handler)NULL, // SIOCSIWNICKN - (iw_handler)NULL, // SIOCGIWNICKN - (iw_handler)NULL, // -- hole -- - (iw_handler)NULL, // -- hole -- - (iw_handler)NULL, // SIOCSIWRATE 0x20 - (iw_handler)NULL, // SIOCGIWRATE - (iw_handler)NULL, // SIOCSIWRTS - (iw_handler)NULL, // SIOCGIWRTS - (iw_handler)NULL, // SIOCSIWFRAG - (iw_handler)NULL, // SIOCGIWFRAG - (iw_handler)NULL, // SIOCSIWTXPOW - (iw_handler)NULL, // SIOCGIWTXPOW - (iw_handler)NULL, // SIOCSIWRETRY - (iw_handler)NULL, // SIOCGIWRETRY - (iw_handler)NULL, // SIOCSIWENCODE - (iw_handler)NULL, // SIOCGIWENCODE - (iw_handler)NULL, // SIOCSIWPOWER - (iw_handler)NULL, // SIOCGIWPOWER - (iw_handler)NULL, // -- hole -- - (iw_handler)NULL, // -- hole -- - (iw_handler)NULL, // SIOCSIWGENIE - (iw_handler)NULL, // SIOCGIWGENIE - (iw_handler)NULL, // SIOCSIWAUTH - (iw_handler)NULL, // SIOCGIWAUTH - (iw_handler)NULL, // SIOCSIWENCODEEXT - (iw_handler)NULL, // SIOCGIWENCODEEXT - (iw_handler)NULL, // SIOCSIWPMKSA - (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWCOMMIT + (iw_handler)NULL, // SIOCGIWNAME + (iw_handler)NULL, // SIOCSIWNWID + (iw_handler)NULL, // SIOCGIWNWID + (iw_handler)NULL, // SIOCSIWFREQ + (iw_handler)NULL, // SIOCGIWFREQ + (iw_handler)NULL, // SIOCSIWMODE + (iw_handler)NULL, // SIOCGIWMODE + (iw_handler)NULL, // SIOCSIWSENS + (iw_handler)NULL, // SIOCGIWSENS + (iw_handler)NULL, // SIOCSIWRANGE + (iw_handler)iwctl_giwrange, // SIOCGIWRANGE + (iw_handler)NULL, // SIOCSIWPRIV + (iw_handler)NULL, // SIOCGIWPRIV + (iw_handler)NULL, // SIOCSIWSTATS + (iw_handler)NULL, // SIOCGIWSTATS + (iw_handler)NULL, // SIOCSIWSPY + (iw_handler)NULL, // SIOCGIWSPY + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWAP + (iw_handler)NULL, // SIOCGIWAP + (iw_handler)NULL, // -- hole -- 0x16 + (iw_handler)NULL, // SIOCGIWAPLIST + (iw_handler)iwctl_siwscan, // SIOCSIWSCAN + (iw_handler)iwctl_giwscan, // SIOCGIWSCAN + (iw_handler)NULL, // SIOCSIWESSID + (iw_handler)NULL, // SIOCGIWESSID + (iw_handler)NULL, // SIOCSIWNICKN + (iw_handler)NULL, // SIOCGIWNICKN + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWRATE 0x20 + (iw_handler)NULL, // SIOCGIWRATE + (iw_handler)NULL, // SIOCSIWRTS + (iw_handler)NULL, // SIOCGIWRTS + (iw_handler)NULL, // SIOCSIWFRAG + (iw_handler)NULL, // SIOCGIWFRAG + (iw_handler)NULL, // SIOCSIWTXPOW + (iw_handler)NULL, // SIOCGIWTXPOW + (iw_handler)NULL, // SIOCSIWRETRY + (iw_handler)NULL, // SIOCGIWRETRY + (iw_handler)NULL, // SIOCSIWENCODE + (iw_handler)NULL, // SIOCGIWENCODE + (iw_handler)NULL, // SIOCSIWPOWER + (iw_handler)NULL, // SIOCGIWPOWER + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // -- hole -- + (iw_handler)NULL, // SIOCSIWGENIE + (iw_handler)NULL, // SIOCGIWGENIE + (iw_handler)NULL, // SIOCSIWAUTH + (iw_handler)NULL, // SIOCGIWAUTH + (iw_handler)NULL, // SIOCSIWENCODEEXT + (iw_handler)NULL, // SIOCGIWENCODEEXT + (iw_handler)NULL, // SIOCSIWPMKSA + (iw_handler)NULL, // -- hole -- }; static const iw_handler iwctl_private_handler[] = { - NULL, // SIOCIWFIRSTPRIV + NULL, // SIOCIWFIRSTPRIV }; struct iw_priv_args iwctl_private_args[] = { -- GitLab From aeadd58d2dbed0fa61962766c93e80bcdf4a8d69 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:32 +0200 Subject: [PATCH 2751/6849] staging: vt6656: iwctl: one statement per line (if) Statement following 'if' should be on its own line. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index c639a3c9030f..dd3c1aca16df 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -235,7 +235,8 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); { int f = (int)pBSS->uChannel - 1; - if (f < 0)f = 0; + if (f < 0) + f = 0; iwe.u.freq.m = frequency_list[f] * 100000; iwe.u.freq.e = 1; } -- GitLab From 37f0777fb134794b39ce6d7f7443d5a932b87ab8 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:39 +0200 Subject: [PATCH 2752/6849] staging: vt6656: iwctl: Cleanup spacing around operators (mostly) This cleans up spacing around operators according to CodingStyle. (A few deletions of empty lines that were missed by a previous patch are also included. A few bits and pieces broken on multiple lines were put one one line as well). Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 168 ++++++++++++++++----------------- 1 file changed, 79 insertions(+), 89 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index dd3c1aca16df..6307c6a68f7a 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -138,13 +138,13 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, pItemSSID->byElementID = WLAN_EID_SSID; memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { - if (req->essid_len>0) + if (req->essid_len > 0) pItemSSID->len = req->essid_len - 1; } else pItemSSID->len = req->essid_len; pMgmt->eScanType = WMAC_SCAN_PASSIVE; - PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, + PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID, ((PWLAN_IE_SSID)abyScanSSID)->len); bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); spin_unlock_irq(&pDevice->lock); @@ -212,7 +212,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; iwe.u.data.length = pItemSSID->len; iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); // ADD mode memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; @@ -223,7 +223,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.mode = IW_MODE_ADHOC; } iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); // ADD frequency pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; @@ -232,7 +232,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.freq.m = pBSS->uChannel; iwe.u.freq.e = 0; iwe.u.freq.i = 0; - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); + current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); { int f = (int)pBSS->uChannel - 1; if (f < 0) @@ -240,7 +240,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.freq.m = frequency_list[f] * 100000; iwe.u.freq.e = 1; } - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); // ADD quality memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; @@ -253,40 +253,40 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, }else if (-ldBm > 90) { iwe.u.qual.qual = 0; }else { - iwe.u.qual.qual=(40-(-ldBm-50))*100/40; + iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40; } - iwe.u.qual.updated=7; + iwe.u.qual.updated = 7; - current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); // ADD encryption memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; iwe.u.data.length = 0; if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { - iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; }else { iwe.u.data.flags = IW_ENCODE_DISABLED; } - current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWRATE; iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; current_val = current_ev + IW_EV_LCP_LEN; - for (kk = 0 ; kk < 12 ; kk++) { + for (kk = 0; kk < 12; kk++) { if (pSuppRates->abyRates[kk] == 0) break; // Bit rate given in 500 kb/s units (+ 0x80) iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } - for (kk = 0 ; kk < 8 ; kk++) { + for (kk = 0; kk < 8; kk++) { if (pExtSuppRates->abyRates[kk] == 0) break; // Bit rate given in 500 kb/s units (+ 0x80) iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } if ((current_val - current_ev) > IW_EV_LCP_LEN) @@ -296,22 +296,21 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.cmd = IWEVCUSTOM; sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf); + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, buf); if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVGENIE; iwe.u.data.length = pBSS->wWPALen; - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE); + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE); } if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVGENIE; iwe.u.data.length = pBSS->wRSNLen; - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE); + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE); } - } } // for wrq->length = current_ev - extra; @@ -402,7 +401,6 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, } switch (*wmode) { - case IW_MODE_ADHOC: if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; @@ -457,7 +455,6 @@ void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, PSDevice pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); // If not managed, assume it's ad-hoc switch (pMgmt->eConfigMode) { @@ -514,7 +511,7 @@ void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, range->max_qual.noise = 0; range->sensitivity = 255; - for (i = 0 ; i < 13 ; i++) { + for (i = 0; i < 13; i++) { range->bitrate[i] = abySupportedRates[i] * 500000; if (range->bitrate[i] == 0) break; @@ -597,7 +594,7 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); // mike: add if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || - (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ + (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) { PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); return rc; } @@ -680,7 +677,7 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, pBSS = &(pMgmt->sBSSList[ii]); if (!pBSS->bActive) continue; - if ( jj >= IW_MAX_AP) + if (jj >= IW_MAX_AP) break; memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6); sock[jj].sa_family = ARPHRD_ETHER; @@ -692,8 +689,8 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, wrq->flags = 1; // Should be define'd wrq->length = jj; - memcpy(extra, sock, sizeof(struct sockaddr)*jj); - memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj); + memcpy(extra, sock, sizeof(struct sockaddr) * jj); + memcpy(extra + sizeof(struct sockaddr) * jj, qual, sizeof(struct iw_quality) * jj); } return rc; } @@ -721,7 +718,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, memset(pMgmt->abyDesireBSSID, 0xFF,6); PRINT_K("set essid to 'any' \n"); #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Unknown desired AP,so here need not associate?? + // Unknown desired AP, so here need not associate?? return 0; #endif } else { @@ -737,11 +734,11 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, } else pItemSSID->len = wrq->length; - PRINT_K("set essid to %s \n",pItemSSID->abySSID); + PRINT_K("set essid to %s \n", pItemSSID->abySSID); // mike: need clear desiredBSSID if (pItemSSID->len==0) { - memset(pMgmt->abyDesireBSSID, 0xFF,6); + memset(pMgmt->abyDesireBSSID, 0xFF, 6); return 0; } @@ -755,13 +752,12 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, unsigned ii; unsigned uSameBssidNum = 0; - memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); + memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID)); pCurr = BSSpSearchBSSList(pDevice, NULL, abyTmpDesireSSID, - pDevice->eConfigPHYMode - ); + pDevice->eConfigPHYMode); - if (pCurr == NULL){ + if (pCurr == NULL) { PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); vResetCommandTimer((void *)pDevice); pMgmt->eScanType = WMAC_SCAN_ACTIVE; @@ -824,7 +820,7 @@ void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, // Get the current SSID pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - memcpy(extra, pItemSSID->abySSID , pItemSSID->len); + memcpy(extra, pItemSSID->abySSID, pItemSSID->len); extra[pItemSSID->len] = '\0'; wrq->length = pItemSSID->len; @@ -855,17 +851,16 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, // First: get a valid bit rate value // Which type of value - if ((wrq->value < 13) && - (wrq->value >= 0)) { + if ((wrq->value < 13) && (wrq->value >= 0)) { // Setting by rate index // Find value in the magic rate table brate = wrq->value; } else { // Setting by frequency value - u8 normvalue = (u8) (wrq->value/500000); + u8 normvalue = (u8)(wrq->value/500000); // Check if rate is valid - for (i = 0 ; i < 13 ; i++) { + for (i = 0; i < 13; i++) { if (normvalue == abySupportedRates[i]) { brate = i; break; @@ -875,7 +870,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, // -1 designed the max rate (mostly auto mode) if (wrq->value == -1) { // Get the highest available rate - for (i = 0 ; i < 13 ; i++) { + for (i = 0; i < 13; i++) { if (abySupportedRates[i] == 0) break; } @@ -895,14 +890,13 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, // Fixed mode // One rate, fixed pDevice->bFixRate = TRUE; - if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) { + if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) { pDevice->uConnectionRate = 3; } else { pDevice->uConnectionRate = brate; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); } - } else { pDevice->bFixRate = FALSE; @@ -1086,7 +1080,6 @@ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) wrq->flags |= IW_RETRY_MIN; } - return 0; } @@ -1142,11 +1135,10 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, if (pDevice->flags & DEVICE_FLAGS_OPENED) { spin_lock_irq(&pDevice->lock); - KeybSetDefaultKey( pDevice, + KeybSetDefaultKey(pDevice, &(pDevice->sKey), dwKeyIndex | (1 << 31), - wrq->length, - NULL, + wrq->length, NULL, pDevice->abyKey, KEY_CTL_WEP ); @@ -1190,7 +1182,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - memset(pMgmt->abyDesireBSSID, 0xFF,6); + memset(pMgmt->abyDesireBSSID, 0xFF, 6); #endif return rc; } @@ -1210,11 +1202,11 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, if (index > WLAN_WEP_NKEYS) { return -EINVAL; } - if (index<1){ // get default key - if (pDevice->byKeyIndexbyKeyIndex; + if (index < 1) { // get default key + if (pDevice->byKeyIndex < WLAN_WEP_NKEYS){ + index = pDevice->byKeyIndex; } else - index=0; + index = 0; }else index--; @@ -1223,30 +1215,30 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, wrq->flags = IW_ENCODE_NOKEY; // Is WEP enabled ??? if (pDevice->bEncryptionEnable) - wrq->flags |= IW_ENCODE_ENABLED; + wrq->flags |= IW_ENCODE_ENABLED; else - wrq->flags |= IW_ENCODE_DISABLED; + wrq->flags |= IW_ENCODE_DISABLED; if (pMgmt->bShareKeyAlgorithm) - wrq->flags |= IW_ENCODE_RESTRICTED; + wrq->flags |= IW_ENCODE_RESTRICTED; else - wrq->flags |= IW_ENCODE_OPEN; - wrq->length=0; + wrq->flags |= IW_ENCODE_OPEN; + wrq->length = 0; - if ((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| + if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled || pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){ // get wpa pairwise key - if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ + if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) { wrq->length = pKey->uKeyLength; memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); } - }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){ + } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index, &pKey)){ wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); + memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); + memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); } - wrq->flags |= index+1; + wrq->flags |= index + 1; return 0; } @@ -1373,7 +1365,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_CIPHER_PAIRWISE: pairwise = wrq->value; - PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise); + PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise); if (pairwise == IW_AUTH_CIPHER_CCMP){ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; }else if (pairwise == IW_AUTH_CIPHER_TKIP){ @@ -1383,11 +1375,11 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; }else if (pairwise == IW_AUTH_CIPHER_NONE){ // do nothing, einsn liu - }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + } else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; break; case IW_AUTH_CIPHER_GROUP: - PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value); + PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value); if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED) break; if (pairwise == IW_AUTH_CIPHER_NONE){ @@ -1399,12 +1391,12 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, } break; case IW_AUTH_KEY_MGMT: - PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value); + PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version,wrq->value); if (wpa_version == IW_AUTH_WPA_VERSION_WPA2){ if (wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; else pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - }else if (wpa_version == IW_AUTH_WPA_VERSION_WPA){ + } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) { if (wrq->value == 0){ pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; }else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) @@ -1417,10 +1409,10 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, case IW_AUTH_DROP_UNENCRYPTED: break; case IW_AUTH_80211_AUTH_ALG: - PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value); + PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value); if (wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ - pMgmt->bShareKeyAlgorithm=FALSE; - }else if (wrq->value==IW_AUTH_ALG_SHARED_KEY){ + pMgmt->bShareKeyAlgorithm = FALSE; + } else if (wrq->value==IW_AUTH_ALG_SHARED_KEY) { pMgmt->bShareKeyAlgorithm=TRUE; } break; @@ -1463,7 +1455,7 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info, int ret = 0; if (wrq->length){ - if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) { + if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) { ret = -EINVAL; goto out; } @@ -1497,11 +1489,11 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, wrq->length = 0; if (pMgmt->wWPAIELen > 0){ wrq->length = pMgmt->wWPAIELen; - if (pMgmt->wWPAIELen <= space){ - if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){ + if (pMgmt->wWPAIELen <= space) { + if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)) { ret = -EFAULT; } - }else + } else ret = -E2BIG; } return ret; @@ -1518,7 +1510,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, wpa_alg alg_name; u8 addr[6]; int key_idx; - int set_tx=0; + int set_tx = 0; u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; u8 key[64]; size_t seq_len = 0; @@ -1570,11 +1562,11 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, } // recover key,key_len if (ext->key_len) { - key_len=ext->key_len; + key_len = ext->key_len; memcpy(key, &ext->key[0], key_len); } memset(key_array, 0, 64); - if ( key_len > 0) { + if (key_len > 0) { memcpy(key_array, key, key_len); if (key_len == 32) { // notice ! the oder @@ -1607,7 +1599,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, pDevice->bwextstep1 = FALSE; pDevice->bwextstep2 = TRUE; } - if ((pDevice->bwextstep2 == TRUE)&&(param->u.wpa_key.key_index == 3)) { + if ((pDevice->bwextstep2 == TRUE) && (param->u.wpa_key.key_index == 3)) { pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = TRUE; } @@ -1619,8 +1611,8 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = FALSE; pDevice->bWPASuppWextEnabled = TRUE; - memset(pMgmt->abyDesireBSSID, 0xFF,6); - KeyvInitTable(pDevice,&pDevice->sKey); + memset(pMgmt->abyDesireBSSID, 0xFF, 6); + KeyvInitTable(pDevice, &pDevice->sKey); } /*******/ spin_lock_irq(&pDevice->lock); @@ -1732,17 +1724,15 @@ static const iw_handler iwctl_private_handler[] = { }; struct iw_priv_args iwctl_private_args[] = { - { IOCTL_CMD_SET, - IW_PRIV_TYPE_CHAR | 1024, 0, - "set"}, + { IOCTL_CMD_SET, IW_PRIV_TYPE_CHAR | 1024, 0, "set" }, }; const struct iw_handler_def iwctl_handler_def = { - .get_wireless_stats = &iwctl_get_wireless_stats, - .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), - .num_private = 0, - .num_private_args = 0, - .standard = (iw_handler *)iwctl_handler, - .private = NULL, - .private_args = NULL, + .get_wireless_stats = &iwctl_get_wireless_stats, + .num_standard = sizeof(iwctl_handler) / sizeof(iw_handler), + .num_private = 0, + .num_private_args = 0, + .standard = (iw_handler *)iwctl_handler, + .private = NULL, + .private_args = NULL, }; -- GitLab From 8c3337fec4c78f796767459de6429eecf2dc35c9 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 25 Jun 2012 01:57:48 +0200 Subject: [PATCH 2753/6849] staging: vt6656: iwctl: Clean up braces on 'if' statements Clean up braces on 'if' statements to (mostly) match coding style. A few other bits, like removing a few blank lines and such may have snug in. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 145 ++++++++++++++------------------- 1 file changed, 61 insertions(+), 84 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 6307c6a68f7a..dc240962c59c 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -132,7 +132,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, // mike add: active scan OR passive scan OR desire_ssid scan if (wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { // desire_ssid scan + if (wrq->flags & IW_SCAN_THIS_ESSID) { // desire_ssid scan memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); pItemSSID = (PWLAN_IE_SSID)abyScanSSID; pItemSSID->byElementID = WLAN_EID_SSID; @@ -150,12 +150,10 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, spin_unlock_irq(&pDevice->lock); return 0; - } - else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { // passive scan + } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { // passive scan pMgmt->eScanType = WMAC_SCAN_PASSIVE; } - } - else { // active scan + } else { // active scan pMgmt->eScanType = WMAC_SCAN_ACTIVE; } @@ -216,12 +214,10 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, // ADD mode memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { + if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) iwe.u.mode = IW_MODE_INFRA; - } - else { + else iwe.u.mode = IW_MODE_ADHOC; - } iwe.len = IW_EV_UINT_LEN; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); // ADD frequency @@ -248,13 +244,12 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, iwe.u.qual.level = ldBm; iwe.u.qual.noise = 0; - if (-ldBm<50){ + if (-ldBm<50) iwe.u.qual.qual = 100; - }else if (-ldBm > 90) { + else if (-ldBm > 90) iwe.u.qual.qual = 0; - }else { + else iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40; - } iwe.u.qual.updated = 7; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); @@ -262,11 +257,10 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; iwe.u.data.length = 0; - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { + if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - }else { + else iwe.u.data.flags = IW_ENCODE_DISABLED; - } current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); memset(&iwe, 0, sizeof(iwe)); @@ -329,8 +323,7 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); // If setting by frequency, convert to a channel - if ((wrq->e == 1) && - (wrq->m >= (int)2.412e8) && + if ((wrq->e == 1) && (wrq->m >= (int)2.412e8) && (wrq->m <= (int)2.487e8)) { int f = wrq->m / 100000; int c = 0; @@ -340,9 +333,9 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, wrq->m = c + 1; } // Setting by channel number - if ((wrq->m > 14) || (wrq->e > 0)) + if ((wrq->m > 14) || (wrq->e > 0)) { rc = -EOPNOTSUPP; - else { + } else { int channel = wrq->m; if ((channel < 1) || (channel > 14)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m); @@ -353,7 +346,6 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, pDevice->uChannel = channel; } } - return rc; } @@ -404,9 +396,8 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, case IW_MODE_ADHOC: if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { + if (pDevice->flags & DEVICE_FLAGS_OPENED) pDevice->bCommit = TRUE; - } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n"); break; @@ -414,9 +405,8 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, case IW_MODE_INFRA: if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { + if (pDevice->flags & DEVICE_FLAGS_OPENED) pDevice->bCommit = TRUE; - } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n"); break; @@ -428,9 +418,8 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { pMgmt->eConfigMode = WMAC_CONFIG_AP; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { + if (pDevice->flags & DEVICE_FLAGS_OPENED) pDevice->bCommit = TRUE; - } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n"); break; @@ -617,9 +606,8 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, } } - if (pDevice->flags & DEVICE_FLAGS_OPENED) { + if (pDevice->flags & DEVICE_FLAGS_OPENED) pDevice->bCommit = TRUE; - } } return rc; } @@ -640,9 +628,8 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) memset(wrq->sa_data, 0, 6); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - } wrq->sa_family = ARPHRD_ETHER; return 0; @@ -731,9 +718,9 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, if (pItemSSID->abySSID[wrq->length - 1] == '\0') { if (wrq->length>0) pItemSSID->len = wrq->length - 1; - } - else + } else { pItemSSID->len = wrq->length; + } PRINT_K("set essid to %s \n", pItemSSID->abySSID); // mike: need clear desiredBSSID @@ -767,8 +754,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } - else { // mike: to find out if that desired SSID is a + } else { // mike: to find out if that desired SSID is a // hidden-ssid AP, by means of judging if there // are two same BSSID exist in list ? for (ii = 0; ii < MAX_BSS_NUM; ii++) { @@ -797,9 +783,9 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); } - if (pDevice->flags & DEVICE_FLAGS_OPENED) { + if (pDevice->flags & DEVICE_FLAGS_OPENED) pDevice->bCommit = TRUE; - } + return 0; } @@ -892,8 +878,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, pDevice->bFixRate = TRUE; if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) { pDevice->uConnectionRate = 3; - } - else { + } else { pDevice->uConnectionRate = brate; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); } @@ -925,7 +910,7 @@ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, if (pDevice->uConnectionRate < 13) { brate = abySupportedRates[pDevice->uConnectionRate]; - }else { + } else { if (pDevice->byBBType == BB_TYPE_11B) brate = 0x16; if (pDevice->byBBType == BB_TYPE_11G) @@ -933,7 +918,6 @@ void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, if (pDevice->byBBType == BB_TYPE_11A) brate = 0x6C; } - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { if (pDevice->byBBType == BB_TYPE_11B) brate = 0x16; @@ -1001,7 +985,7 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, fthr = 2312; if ((fthr < 256) || (fthr > 2312)) { rc = -EINVAL; - }else { + } else { fthr &= ~0x1; // Get an even value pDevice->wFragmentationThreshold = (u16)fthr; } @@ -1041,19 +1025,18 @@ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, } if (wrq->flags & IW_RETRY_LIMIT) { - if (wrq->flags & IW_RETRY_MAX) + if (wrq->flags & IW_RETRY_MAX) { pDevice->byLongRetryLimit = wrq->value; - else if (wrq->flags & IW_RETRY_MIN) + } else if (wrq->flags & IW_RETRY_MIN) { pDevice->byShortRetryLimit = wrq->value; - else { + } else { // No modifier : set both pDevice->byShortRetryLimit = wrq->value; pDevice->byLongRetryLimit = wrq->value; } } - if (wrq->flags & IW_RETRY_LIFETIME) { + if (wrq->flags & IW_RETRY_LIFETIME) pDevice->wMaxTransmitMSDULifetime = wrq->value; - } return rc; } @@ -1118,20 +1101,17 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, if (wrq->length == WLAN_WEP232_KEYLEN) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP104_KEYLEN) { + } else if (wrq->length == WLAN_WEP104_KEYLEN) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP40_KEYLEN) { + } else if (wrq->length == WLAN_WEP40_KEYLEN) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); } memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); memcpy(pDevice->abyKey, extra, wrq->length); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); - for (ii = 0; ii < wrq->length; ii++) { + for (ii = 0; ii < wrq->length; ii++) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); - } if (pDevice->flags & DEVICE_FLAGS_OPENED) { spin_lock_irq(&pDevice->lock); @@ -1151,7 +1131,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; // Do we want to just set the transmit key index? - if ( index < 4 ) { + if (index < 4) { pDevice->byKeyIndex = index; } else if (!(wrq->flags & IW_ENCODE_MODE)) { rc = -EINVAL; @@ -1159,8 +1139,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, } } // Read the flags - if (wrq->flags & IW_ENCODE_DISABLED){ - + if (wrq->flags & IW_ENCODE_DISABLED) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); pMgmt->bShareKeyAlgorithm = FALSE; pDevice->bEncryptionEnable = FALSE; @@ -1199,16 +1178,16 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); - if (index > WLAN_WEP_NKEYS) { + if (index > WLAN_WEP_NKEYS) return -EINVAL; - } if (index < 1) { // get default key - if (pDevice->byKeyIndex < WLAN_WEP_NKEYS){ + if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) index = pDevice->byKeyIndex; - } else + else index = 0; - }else + } else { index--; + } memset(abyKey, 0, WLAN_WEP232_KEYLEN); // Check encryption mode @@ -1232,7 +1211,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); } - } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index, &pKey)){ + } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index, &pKey)) { wrq->length = pKey->uKeyLength; memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); @@ -1329,8 +1308,7 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, if (pDevice->bLinkPass == TRUE) { RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); wrq->value = ldBm; - } - else { + } else { wrq->value = 0; } wrq->disabled = (wrq->value == 0); @@ -1355,11 +1333,9 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, wpa_version = wrq->value; if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); - } - else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) { + } else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) { PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); - } - else { + } else { PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); } break; @@ -1368,22 +1344,23 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise); if (pairwise == IW_AUTH_CIPHER_CCMP){ pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - }else if (pairwise == IW_AUTH_CIPHER_TKIP){ + } else if (pairwise == IW_AUTH_CIPHER_TKIP) { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; } else if (pairwise == IW_AUTH_CIPHER_WEP40 || pairwise == IW_AUTH_CIPHER_WEP104) { pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - }else if (pairwise == IW_AUTH_CIPHER_NONE){ + } else if (pairwise == IW_AUTH_CIPHER_NONE) { // do nothing, einsn liu - } else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - + } else { + pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + } break; case IW_AUTH_CIPHER_GROUP: PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value); if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED) break; - if (pairwise == IW_AUTH_CIPHER_NONE){ - if (wrq->value == IW_AUTH_CIPHER_CCMP){ + if (pairwise == IW_AUTH_CIPHER_NONE) { + if (wrq->value == IW_AUTH_CIPHER_CCMP) { pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; }else { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; @@ -1399,9 +1376,10 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) { if (wrq->value == 0){ pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - }else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) + } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - else pMgmt->eAuthenMode = WMAC_AUTH_WPA; + } else { + pMgmt->eAuthenMode = WMAC_AUTH_WPA; } break; case IW_AUTH_TKIP_COUNTERMEASURES: @@ -1410,11 +1388,10 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_80211_AUTH_ALG: PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value); - if (wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ + if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM) pMgmt->bShareKeyAlgorithm = FALSE; - } else if (wrq->value==IW_AUTH_ALG_SHARED_KEY) { - pMgmt->bShareKeyAlgorithm=TRUE; - } + else if (wrq->value == IW_AUTH_ALG_SHARED_KEY) + pMgmt->bShareKeyAlgorithm = TRUE; break; case IW_AUTH_WPA_ENABLED: break; @@ -1425,7 +1402,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, break; case IW_AUTH_PRIVACY_INVOKED: pDevice->bEncryptionEnable = !!wrq->value; - if (pDevice->bEncryptionEnable == FALSE){ + if (pDevice->bEncryptionEnable == FALSE) { wpa_version = 0; pairwise = 0; pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; @@ -1487,7 +1464,7 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info, int space = wrq->length; wrq->length = 0; - if (pMgmt->wWPAIELen > 0){ + if (pMgmt->wWPAIELen > 0) { wrq->length = pMgmt->wWPAIELen; if (pMgmt->wWPAIELen <= space) { if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)) { @@ -1638,14 +1615,14 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_mlme *mlme = (struct iw_mlme *)extra; int ret = 0; - if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){ + if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) { ret = -EINVAL; return ret; } switch (mlme->cmd){ case IW_MLME_DEAUTH: case IW_MLME_DISASSOC: - if (pDevice->bLinkPass == TRUE){ + if (pDevice->bLinkPass == TRUE) { PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, -- GitLab From e055548953355b6e69c56f9e54388845b29b4e97 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 11 May 2012 16:00:24 -0700 Subject: [PATCH 2754/6849] ARM: OMAP2+: powerdomain: allow pre/post transtion to be per pwrdm Iteration over all power domains in the idle path is unnecessary since only power domains that are transitioning need to be accounted for. Also PRCM register accesses are known to be expensive, so the additional latency added to the idle path is signficiant. In order allow the pre/post transitions to be isolated and called per-pwrdm, change the API so passing in a specific power domain will trigger the pre/post transtion accounting for only that specific power domain. Passing NULL means iterating over all power domains as is current behavior. Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Tested-by: Grazvydas Ignotas Acked-by: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 4 ++-- arch/arm/mach-omap2/pm34xx.c | 4 ++-- arch/arm/mach-omap2/powerdomain.c | 16 ++++++++++++---- arch/arm/mach-omap2/powerdomain.h | 4 ++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 13670aa84e58..e35a86bf4e1d 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -255,7 +255,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) return -ENXIO; } - pwrdm_pre_transition(); + pwrdm_pre_transition(NULL); /* * Check MPUSS next state and save interrupt controller if needed. @@ -287,7 +287,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu = smp_processor_id(); set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); - pwrdm_post_transition(); + pwrdm_post_transition(NULL); return 0; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e67d898433fb..0bbbc8c82fd8 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -273,7 +273,7 @@ void omap_sram_idle(void) per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - pwrdm_pre_transition(); + pwrdm_pre_transition(NULL); /* PER */ if (per_next_state < PWRDM_POWER_ON) { @@ -338,7 +338,7 @@ void omap_sram_idle(void) } omap3_intc_resume_idle(); - pwrdm_post_transition(); + pwrdm_post_transition(NULL); /* PER */ if (per_next_state < PWRDM_POWER_ON) diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 96114901b932..eefe179045e6 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -981,15 +981,23 @@ int pwrdm_state_switch(struct powerdomain *pwrdm) return ret; } -int pwrdm_pre_transition(void) +int pwrdm_pre_transition(struct powerdomain *pwrdm) { - pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); + if (pwrdm) + _pwrdm_pre_transition_cb(pwrdm, NULL); + else + pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); + return 0; } -int pwrdm_post_transition(void) +int pwrdm_post_transition(struct powerdomain *pwrdm) { - pwrdm_for_each(_pwrdm_post_transition_cb, NULL); + if (pwrdm) + _pwrdm_post_transition_cb(pwrdm, NULL); + else + pwrdm_for_each(_pwrdm_post_transition_cb, NULL); + return 0; } diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 8f88d65c46ea..a6a4604801ad 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -213,8 +213,8 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); int pwrdm_wait_transition(struct powerdomain *pwrdm); int pwrdm_state_switch(struct powerdomain *pwrdm); -int pwrdm_pre_transition(void); -int pwrdm_post_transition(void); +int pwrdm_pre_transition(struct powerdomain *pwrdm); +int pwrdm_post_transition(struct powerdomain *pwrdm); int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); -- GitLab From 58f0829b7186150318c79515f0e0850c5e7a9c89 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 11 May 2012 15:47:17 -0700 Subject: [PATCH 2755/6849] ARM: OMAP3: PM: call pre/post transition per powerdomain We only need to call the pre/post transtion methods when we know the power state is changing. First, split up the pre/post transition calls to be per-powerdomain, and then make them conditional on whether the power domain is actually changing states. Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Tested-by: Grazvydas Ignotas Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0bbbc8c82fd8..dec2d55d7182 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -273,16 +273,21 @@ void omap_sram_idle(void) per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - pwrdm_pre_transition(NULL); + if (mpu_next_state < PWRDM_POWER_ON) { + pwrdm_pre_transition(mpu_pwrdm); + pwrdm_pre_transition(neon_pwrdm); + } /* PER */ if (per_next_state < PWRDM_POWER_ON) { + pwrdm_pre_transition(per_pwrdm); per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; omap2_gpio_prepare_for_idle(per_going_off); } /* CORE */ if (core_next_state < PWRDM_POWER_ON) { + pwrdm_pre_transition(core_pwrdm); if (core_next_state == PWRDM_POWER_OFF) { omap3_core_save_context(); omap3_cm_save_context(); @@ -335,14 +340,20 @@ void omap_sram_idle(void) omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET); + pwrdm_post_transition(core_pwrdm); } omap3_intc_resume_idle(); - pwrdm_post_transition(NULL); - /* PER */ - if (per_next_state < PWRDM_POWER_ON) + if (per_next_state < PWRDM_POWER_ON) { omap2_gpio_resume_after_idle(); + pwrdm_post_transition(per_pwrdm); + } + + if (mpu_next_state < PWRDM_POWER_ON) { + pwrdm_post_transition(mpu_pwrdm); + pwrdm_post_transition(neon_pwrdm); + } clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -- GitLab From 34059a878f5cb20652cbc937f35c925f2b378831 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 19 Jun 2012 09:54:38 -0700 Subject: [PATCH 2756/6849] ARM: OMAP3: PM: cleanup cam_pwrdm leftovers commit e7410cf7 (OMAP3: PM: move device-specific special cases from PM core into CPUidle) moved mangement of cam_pwrdm to CPUidle but left some remnants behind, namely the call to clkcm_allo_idle() for the clockdomains in the MPU pwrdm. Remove these since they are not necessary and cause unwanted latency in the idle path. Acked-by: Tero Kristo Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Tested-by: Grazvydas Ignotas Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index dec2d55d7182..e63fdd02c6f5 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -70,7 +70,6 @@ void (*omap3_do_wfi_sram)(void); static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm; -static struct powerdomain *cam_pwrdm; static void omap3_core_save_context(void) { @@ -354,8 +353,6 @@ void omap_sram_idle(void) pwrdm_post_transition(mpu_pwrdm); pwrdm_post_transition(neon_pwrdm); } - - clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } static void omap3_pm_idle(void) @@ -716,7 +713,6 @@ int __init omap3_pm_init(void) neon_pwrdm = pwrdm_lookup("neon_pwrdm"); per_pwrdm = pwrdm_lookup("per_pwrdm"); core_pwrdm = pwrdm_lookup("core_pwrdm"); - cam_pwrdm = pwrdm_lookup("cam_pwrdm"); neon_clkdm = clkdm_lookup("neon_clkdm"); mpu_clkdm = clkdm_lookup("mpu_clkdm"); -- GitLab From 063a5d011698950c86a01044394105605556e92c Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Fri, 1 Jun 2012 17:11:06 +0200 Subject: [PATCH 2757/6849] ARM: OMAP3: PM: cpuidle: default to C1 in next_valid_state If the next state is no found in the next_valid_state function, fallback to the default value of C1 (which is state 0). This prevents the use of a bogus state -1 in the rest of the cpuidle code. Signed-off-by: Jean Pihet Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 207bc1c7759f..f619a928f01e 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -178,7 +178,7 @@ static int next_valid_state(struct cpuidle_device *dev, u32 mpu_deepest_state = PWRDM_POWER_RET; u32 core_deepest_state = PWRDM_POWER_RET; int idx; - int next_index = -1; + int next_index = 0; /* C1 is the default value */ if (enable_off_mode) { mpu_deepest_state = PWRDM_POWER_OFF; @@ -209,12 +209,6 @@ static int next_valid_state(struct cpuidle_device *dev, } } - /* - * C1 is always valid. - * So, no need to check for 'next_index == -1' outside - * this loop. - */ - return next_index; } -- GitLab From 13d65c897e93dfeaed6fe28233559239f9676164 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Fri, 1 Jun 2012 17:11:07 +0200 Subject: [PATCH 2758/6849] ARM: OMAP3: PM: cpuidle: optimize the PER latency in C1 state One of the main contributors of the low power code latency is the PER power domain. To optimize the high-performance and low-latency C1 state, prevent any PER state which is lower than the CORE state in C1. Reported and suggested by Kevin Hilman. Reported-by: Kevin Hilman Signed-off-by: Jean Pihet Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 41 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f619a928f01e..2e2f1c6f0f0b 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -222,23 +222,22 @@ static int next_valid_state(struct cpuidle_device *dev, * the device to the specified or a safer state. */ static int omap3_enter_idle_bm(struct cpuidle_device *dev, - struct cpuidle_driver *drv, + struct cpuidle_driver *drv, int index) { int new_state_idx; - u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; + u32 core_next_state, per_next_state = 0, per_saved_state = 0; struct omap3_idle_statedata *cx; int ret; /* - * Prevent idle completely if CAM is active. + * Use only C1 if CAM is active. * CAM does not have wakeup capability in OMAP3. */ - cam_state = pwrdm_read_pwrst(cam_pd); - if (cam_state == PWRDM_POWER_ON) { + if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON) new_state_idx = drv->safe_state_index; - goto select_state; - } + else + new_state_idx = next_valid_state(dev, drv, index); /* * FIXME: we currently manage device-specific idle states @@ -248,24 +247,28 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, * its own code. */ - /* - * Prevent PER off if CORE is not in retention or off as this - * would disable PER wakeups completely. - */ - cx = &omap3_idle_data[index]; + /* Program PER state */ + cx = &omap3_idle_data[new_state_idx]; core_next_state = cx->core_state; per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); - if ((per_next_state == PWRDM_POWER_OFF) && - (core_next_state > PWRDM_POWER_RET)) - per_next_state = PWRDM_POWER_RET; + if (new_state_idx == 0) { + /* In C1 do not allow PER state lower than CORE state */ + if (per_next_state < core_next_state) + per_next_state = core_next_state; + } else { + /* + * Prevent PER OFF if CORE is not in RETention or OFF as this + * would disable PER wakeups completely. + */ + if ((per_next_state == PWRDM_POWER_OFF) && + (core_next_state > PWRDM_POWER_RET)) + per_next_state = PWRDM_POWER_RET; + } /* Are we changing PER target state? */ if (per_next_state != per_saved_state) pwrdm_set_next_pwrst(per_pd, per_next_state); - new_state_idx = next_valid_state(dev, drv, index); - -select_state: ret = omap3_enter_idle(dev, drv, new_state_idx); /* Restore original PER state if it was modified */ @@ -282,7 +285,7 @@ struct cpuidle_driver omap3_idle_driver = { .owner = THIS_MODULE, .states = { { - .enter = omap3_enter_idle, + .enter = omap3_enter_idle_bm, .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, -- GitLab From 05011f711fc751456972d126bbb8081723629408 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Fri, 1 Jun 2012 17:11:08 +0200 Subject: [PATCH 2759/6849] ARM: OMAP3: PM: cpuidle: optimize the clkdm idle latency in C1 state For a power domain to idle all the clock domains in it must idle. This patch implements an optimization of the cpuidle code by denying and later allowing only the first registered clock domain of a power domain, and so optimizes the latency of the low power code. The functions _cpuidle_allow_idle and _cpuidle_deny_idle are not used anymore and so are removed. Signed-off-by: Jean Pihet Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 2e2f1c6f0f0b..e6ae3fe5cdc6 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -77,20 +77,6 @@ static struct omap3_idle_statedata omap3_idle_data[] = { static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; -static int _cpuidle_allow_idle(struct powerdomain *pwrdm, - struct clockdomain *clkdm) -{ - clkdm_allow_idle(clkdm); - return 0; -} - -static int _cpuidle_deny_idle(struct powerdomain *pwrdm, - struct clockdomain *clkdm) -{ - clkdm_deny_idle(clkdm); - return 0; -} - static int __omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -108,8 +94,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, /* Deny idle for C1 */ if (index == 0) { - pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); - pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); + clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); + clkdm_deny_idle(core_pd->pwrdm_clkdms[0]); } /* @@ -131,8 +117,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, /* Re-allow idle for C1 */ if (index == 0) { - pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); - pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); + clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); + clkdm_allow_idle(core_pd->pwrdm_clkdms[0]); } return_sleep_time: -- GitLab From 8191e0d9097e0d83d09f43b0c43318de7ca377b6 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Thu, 21 Jun 2012 11:36:50 +0100 Subject: [PATCH 2760/6849] stable: Allow merging of backports for serious user-visible performance issues Distribution kernel maintainers routinely backport fixes for users that were deemed important but not "something critical" as defined by the rules. To users of these kernels they are very serious and failing to fix them reduces the value of -stable. The problem is that the patches fixing these issues are often subtle and prone to regressions in other ways and need greater care and attention. To combat this, these "serious" backports should have a higher barrier to entry. This patch relaxes the rules to allow a distribution maintainer to merge to -stable a backported patch or small series that fixes a "serious" user-visible performance issue. They should include additional information on the user-visible bug affected and a link to the bugzilla entry if available. The same rules about the patch being already in mainline still apply. Signed-off-by: Mel Gorman Cc: stable Signed-off-by: Greg Kroah-Hartman --- Documentation/stable_kernel_rules.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index 2edf833e8cb5..b0714d8f678a 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -12,6 +12,12 @@ Rules on what kind of patches are accepted, and which ones are not, into the marked CONFIG_BROKEN), an oops, a hang, data corruption, a real security issue, or some "oh, that's not good" issue. In short, something critical. + - Serious issues as reported by a user of a distribution kernel may also + be considered if they fix a notable performance or interactivity issue. + As these fixes are not as obvious and have a higher risk of a subtle + regression they should only be submitted by a distribution kernel + maintainer and include an addendum linking to a bugzilla entry if it + exists and additional information on the user-visible impact. - New device IDs and quirks are also accepted. - No "theoretical race condition" issues, unless an explanation of how the race can be exploited is also provided. -- GitLab From fa6173a0be1844ccea58afb2247f71abab1e53c5 Mon Sep 17 00:00:00 2001 From: Lauri Hintsala Date: Thu, 21 Jun 2012 13:29:12 +0300 Subject: [PATCH 2761/6849] Staging: csr: add WEXT and AP mode support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Mikko Virkkilä Cc: Veli-Pekka Peltola Signed-off-by: Lauri Hintsala Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/Kconfig | 4 +- drivers/staging/csr/Makefile | 13 +- .../csr/csr_wifi_nme_ap_converter_init.c | 91 ++ ...csr_wifi_nme_ap_free_downstream_contents.c | 85 ++ .../csr_wifi_nme_ap_free_upstream_contents.c | 40 + .../staging/csr/csr_wifi_nme_ap_serialize.c | 910 ++++++++++++++++++ drivers/staging/csr/sme_sys.c | 2 +- drivers/staging/csr/unifi_native.h | 2 +- 8 files changed, 1142 insertions(+), 5 deletions(-) create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_converter_init.c create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c create mode 100644 drivers/staging/csr/csr_wifi_nme_ap_serialize.c diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig index e3a923ac6e75..bd86fb9c54d5 100644 --- a/drivers/staging/csr/Kconfig +++ b/drivers/staging/csr/Kconfig @@ -1,6 +1,8 @@ config CSR_WIFI tristate "CSR wireless driver" - depends on PCI && MMC + depends on PCI && MMC && CFG80211_WEXT + select WIRELESS_EXT + select WEXT_PRIV help Driver for the CSR wireless SDIO device. diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile index 27eb4a77bc7f..e0e7baba87b0 100644 --- a/drivers/staging/csr/Makefile +++ b/drivers/staging/csr/Makefile @@ -1,6 +1,8 @@ obj-$(CONFIG_CSR_WIFI) += oska/ -ccflags-y := -DCSR_SME_USERSPACE -DCSR_SUPPORT_SME -DREMOTE_SYS_SAP -DCSR_WIFI_SECURITY_WAPI_ENABLE -DENABLE_SHUTDOWN +ccflags-y := -DCSR_SME_USERSPACE -DCSR_SUPPORT_SME -DREMOTE_SYS_SAP -DCSR_WIFI_SECURITY_WAPI_ENABLE -DENABLE_SHUTDOWN -DUNIFI_DEBUG +ccflags-y += -DSDIO_EXPORTS_STRUCT_DEVICE -DCSR_WIFI_SUPPORT_MMC_DRIVER -DCSR_WIFI_SINGLE_FUNCTION -DCSR_WIFI_SPLIT_PATCH +ccflags-y += -DCSR_SUPPORT_WEXT -DREMOTE_SYS_SAP -DREMOTE_MGT_SAP -DCSR_WIFI_SECURITY_WAPI_ENABLE -DCSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND -DENABLE_SHUTDOWN -DCSR_WIFI_NME_ENABLE -DCSR_WIFI_AP_ENABLE -DCSR_SUPPORT_WEXT_AP -DCSR_WIFI_REQUEUE_PACKET_TO_HAL obj-$(CONFIG_CSR_WIFI) += csr_wifi.o obj-$(CONFIG_CSR_WIFI) += csr_helper.o @@ -40,6 +42,11 @@ csr_wifi-y := bh.o \ csr_wifi_hip_udi.o \ csr_wifi_hip_unifi_signal_names.o \ csr_wifi_hip_xbv.o \ + csr_wifi_nme_ap_converter_init.o \ + csr_wifi_nme_ap_free_downstream_contents.o \ + csr_wifi_nme_ap_free_upstream_contents.o \ + csr_wifi_nme_ap_serialize.o \ + csr_wifi_nme_ap_sef.o \ csr_wifi_router_ctrl_sef.o \ csr_wifi_router_sef.o \ csr_wifi_router_transport.o \ @@ -58,7 +65,9 @@ csr_wifi-y := bh.o \ csr_wifi_router_serialize.o \ sme_mgt.o \ sme_sys.o \ - sme_userspace.o + sme_userspace.o \ + sme_wext.o \ + wext_events.o csr_helper-y := csr_time.o \ csr_util.o \ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c new file mode 100644 index 000000000000..83b3727d47dc --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c @@ -0,0 +1,91 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2012 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_msgconv.h" +#include "csr_pmem.h" +#include "csr_util.h" + +#ifdef CSR_WIFI_NME_ENABLE +#ifdef CSR_WIFI_AP_ENABLE + +#ifdef CSR_LOG_ENABLE +#include "csr_log.h" +#endif + +#ifndef EXCLUDE_CSR_WIFI_NME_AP_MODULE +#include "csr_wifi_nme_ap_serialize.h" +#include "csr_wifi_nme_ap_prim.h" + +static CsrMsgConvMsgEntry csrwifinmeap_conv_lut[] = { + { CSR_WIFI_NME_AP_CONFIG_SET_REQ, CsrWifiNmeApConfigSetReqSizeof, CsrWifiNmeApConfigSetReqSer, CsrWifiNmeApConfigSetReqDes, CsrWifiNmeApConfigSetReqSerFree }, + { CSR_WIFI_NME_AP_WPS_REGISTER_REQ, CsrWifiNmeApWpsRegisterReqSizeof, CsrWifiNmeApWpsRegisterReqSer, CsrWifiNmeApWpsRegisterReqDes, CsrWifiNmeApWpsRegisterReqSerFree }, + { CSR_WIFI_NME_AP_START_REQ, CsrWifiNmeApStartReqSizeof, CsrWifiNmeApStartReqSer, CsrWifiNmeApStartReqDes, CsrWifiNmeApStartReqSerFree }, + { CSR_WIFI_NME_AP_STOP_REQ, CsrWifiNmeApStopReqSizeof, CsrWifiNmeApStopReqSer, CsrWifiNmeApStopReqDes, CsrWifiNmeApStopReqSerFree }, + { CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_REQ, CsrWifiNmeApWmmParamUpdateReqSizeof, CsrWifiNmeApWmmParamUpdateReqSer, CsrWifiNmeApWmmParamUpdateReqDes, CsrWifiNmeApWmmParamUpdateReqSerFree }, + { CSR_WIFI_NME_AP_STA_REMOVE_REQ, CsrWifiNmeApStaRemoveReqSizeof, CsrWifiNmeApStaRemoveReqSer, CsrWifiNmeApStaRemoveReqDes, CsrWifiNmeApStaRemoveReqSerFree }, + { CSR_WIFI_NME_AP_CONFIG_SET_CFM, CsrWifiNmeApConfigSetCfmSizeof, CsrWifiNmeApConfigSetCfmSer, CsrWifiNmeApConfigSetCfmDes, CsrWifiNmeApConfigSetCfmSerFree }, + { CSR_WIFI_NME_AP_WPS_REGISTER_CFM, CsrWifiNmeApWpsRegisterCfmSizeof, CsrWifiNmeApWpsRegisterCfmSer, CsrWifiNmeApWpsRegisterCfmDes, CsrWifiNmeApWpsRegisterCfmSerFree }, + { CSR_WIFI_NME_AP_START_CFM, CsrWifiNmeApStartCfmSizeof, CsrWifiNmeApStartCfmSer, CsrWifiNmeApStartCfmDes, CsrWifiNmeApStartCfmSerFree }, + { CSR_WIFI_NME_AP_STOP_CFM, CsrWifiNmeApStopCfmSizeof, CsrWifiNmeApStopCfmSer, CsrWifiNmeApStopCfmDes, CsrWifiNmeApStopCfmSerFree }, + { CSR_WIFI_NME_AP_STOP_IND, CsrWifiNmeApStopIndSizeof, CsrWifiNmeApStopIndSer, CsrWifiNmeApStopIndDes, CsrWifiNmeApStopIndSerFree }, + { CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_CFM, CsrWifiNmeApWmmParamUpdateCfmSizeof, CsrWifiNmeApWmmParamUpdateCfmSer, CsrWifiNmeApWmmParamUpdateCfmDes, CsrWifiNmeApWmmParamUpdateCfmSerFree }, + { CSR_WIFI_NME_AP_STATION_IND, CsrWifiNmeApStationIndSizeof, CsrWifiNmeApStationIndSer, CsrWifiNmeApStationIndDes, CsrWifiNmeApStationIndSerFree }, + + { 0, NULL, NULL, NULL, NULL }, +}; + +CsrMsgConvMsgEntry* CsrWifiNmeApConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint16 msgType) +{ + if (msgType & CSR_PRIM_UPSTREAM) + { + CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT; + if (idx < (CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT) && + csrwifinmeap_conv_lut[idx].msgType == msgType) + { + return &csrwifinmeap_conv_lut[idx]; + } + } + else + { + if (msgType < CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT && + csrwifinmeap_conv_lut[msgType].msgType == msgType) + { + return &csrwifinmeap_conv_lut[msgType]; + } + } + return NULL; +} + + +void CsrWifiNmeApConverterInit(void) +{ + CsrMsgConvInsert(CSR_WIFI_NME_AP_PRIM, csrwifinmeap_conv_lut); + CsrMsgConvCustomLookupRegister(CSR_WIFI_NME_AP_PRIM, CsrWifiNmeApConverterLookup); +} + + +#ifdef CSR_LOG_ENABLE +static const CsrLogPrimitiveInformation csrwifinmeap_conv_info = { + CSR_WIFI_NME_AP_PRIM, + (CsrCharString *)"CSR_WIFI_NME_AP_PRIM", + csrwifinmeap_conv_lut +}; +const CsrLogPrimitiveInformation* CsrWifiNmeApTechInfoGet(void) +{ + return &csrwifinmeap_conv_info; +} + + +#endif /* CSR_LOG_ENABLE */ +#endif /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */ +#endif /* CSR_WIFI_NME_ENABLE */ +#endif /* CSR_WIFI_AP_ENABLE */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c new file mode 100644 index 000000000000..8a95f3ceeff2 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c @@ -0,0 +1,85 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2012 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_nme_ap_prim.h" +#include "csr_wifi_nme_ap_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiNmeApFreeDownstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_NME_AP_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiNmeApFreeDownstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_NME_AP_PRIM) + { + return; + } + if (NULL == message) + { + return; + } + + switch (*((CsrWifiNmeApPrim *) message)) + { + case CSR_WIFI_NME_AP_CONFIG_SET_REQ: + { + CsrWifiNmeApConfigSetReq *p = (CsrWifiNmeApConfigSetReq *)message; + CsrPmemFree(p->apMacConfig.macAddressList); + p->apMacConfig.macAddressList = NULL; + break; + } + case CSR_WIFI_NME_AP_START_REQ: + { + CsrWifiNmeApStartReq *p = (CsrWifiNmeApStartReq *)message; + switch (p->apCredentials.authType) + { + case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL: + switch (p->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase) + { + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE: + CsrPmemFree(p->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase); + p->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase = NULL; + break; + default: + break; + } + break; + default: + break; + } + { + CsrUint16 i3; + for (i3 = 0; i3 < p->p2pGoParam.operatingChanList.channelEntryListCount; i3++) + { + CsrPmemFree(p->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel); + p->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel = NULL; + } + } + CsrPmemFree(p->p2pGoParam.operatingChanList.channelEntryList); + p->p2pGoParam.operatingChanList.channelEntryList = NULL; + break; + } + + default: + break; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c new file mode 100644 index 000000000000..7740dc3a40b0 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c @@ -0,0 +1,40 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2012 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_wifi_nme_ap_prim.h" +#include "csr_wifi_nme_ap_lib.h" + +/*----------------------------------------------------------------------------* + * NAME + * CsrWifiNmeApFreeUpstreamMessageContents + * + * DESCRIPTION + * + * + * PARAMETERS + * eventClass: only the value CSR_WIFI_NME_AP_PRIM will be handled + * message: the message to free + *----------------------------------------------------------------------------*/ +void CsrWifiNmeApFreeUpstreamMessageContents(CsrUint16 eventClass, void *message) +{ + if (eventClass != CSR_WIFI_NME_AP_PRIM) + { + return; + } + if (NULL == message) + { + return; + } +} + + diff --git a/drivers/staging/csr/csr_wifi_nme_ap_serialize.c b/drivers/staging/csr/csr_wifi_nme_ap_serialize.c new file mode 100644 index 000000000000..947f86ad29d2 --- /dev/null +++ b/drivers/staging/csr/csr_wifi_nme_ap_serialize.c @@ -0,0 +1,910 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2012 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +/* Note: this is an auto-generated file. */ + +#include "csr_pmem.h" +#include "csr_msgconv.h" +#include "csr_unicode.h" + +#ifdef CSR_WIFI_NME_ENABLE +#ifdef CSR_WIFI_AP_ENABLE + +#include "csr_wifi_nme_ap_prim.h" +#include "csr_wifi_nme_ap_serialize.h" + +void CsrWifiNmeApPfree(void *ptr) +{ + CsrPmemFree(ptr); +} + + +CsrSize CsrWifiNmeApConfigSetReqSizeof(void *msg) +{ + CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 104) */ + bufferSize += 2; /* CsrUint16 primitive->apConfig.apGroupkeyTimeout */ + bufferSize += 1; /* CsrBool primitive->apConfig.apStrictGtkRekey */ + bufferSize += 2; /* CsrUint16 primitive->apConfig.apGmkTimeout */ + bufferSize += 2; /* CsrUint16 primitive->apConfig.apResponseTimeout */ + bufferSize += 1; /* CsrUint8 primitive->apConfig.apRetransLimit */ + bufferSize += 1; /* CsrWifiSmeApPhySupportMask primitive->apMacConfig.phySupportedBitmap */ + bufferSize += 2; /* CsrUint16 primitive->apMacConfig.beaconInterval */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.dtimPeriod */ + bufferSize += 2; /* CsrUint16 primitive->apMacConfig.maxListenInterval */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.supportedRatesCount */ + bufferSize += 20; /* CsrUint8 primitive->apMacConfig.supportedRates[20] */ + bufferSize += 1; /* CsrWifiSmePreambleType primitive->apMacConfig.preamble */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.shortSlotTimeEnabled */ + bufferSize += 1; /* CsrWifiSmeCtsProtectionType primitive->apMacConfig.ctsProtectionType */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.wmmEnabled */ + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.wmmApParams[i2].cwMin */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.wmmApParams[i2].cwMax */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.wmmApParams[i2].aifs */ + bufferSize += 2; /* CsrUint16 primitive->apMacConfig.wmmApParams[i2].txopLimit */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.wmmApParams[i2].admissionControlMandatory */ + } + } + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.wmmApBcParams[i2].cwMin */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.wmmApBcParams[i2].cwMax */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.wmmApBcParams[i2].aifs */ + bufferSize += 2; /* CsrUint16 primitive->apMacConfig.wmmApBcParams[i2].txopLimit */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.wmmApBcParams[i2].admissionControlMandatory */ + } + } + bufferSize += 1; /* CsrWifiSmeApAccessType primitive->apMacConfig.accessType */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.macAddressListCount */ + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->apMacConfig.macAddressListCount; i2++) + { + bufferSize += 6; /* CsrUint8 primitive->apMacConfig.macAddressList[i2].a[6] */ + } + } + bufferSize += 1; /* CsrBool primitive->apMacConfig.apHtParams.greenfieldSupported */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.apHtParams.shortGi20MHz */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.apHtParams.rxStbc */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.apHtParams.rifsModeAllowed */ + bufferSize += 1; /* CsrUint8 primitive->apMacConfig.apHtParams.htProtection */ + bufferSize += 1; /* CsrBool primitive->apMacConfig.apHtParams.dualCtsProtection */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApConfigSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apConfig.apGroupkeyTimeout); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apConfig.apStrictGtkRekey); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apConfig.apGmkTimeout); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apConfig.apResponseTimeout); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apConfig.apRetransLimit); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.phySupportedBitmap); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apMacConfig.beaconInterval); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.dtimPeriod); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apMacConfig.maxListenInterval); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.supportedRatesCount); + CsrMemCpySer(ptr, len, (const void *) primitive->apMacConfig.supportedRates, ((CsrUint16) (20))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.preamble); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.shortSlotTimeEnabled); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.ctsProtectionType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmEnabled); + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApParams[i2].cwMin); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApParams[i2].cwMax); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApParams[i2].aifs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apMacConfig.wmmApParams[i2].txopLimit); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApParams[i2].admissionControlMandatory); + } + } + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApBcParams[i2].cwMin); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApBcParams[i2].cwMax); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApBcParams[i2].aifs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apMacConfig.wmmApBcParams[i2].txopLimit); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.wmmApBcParams[i2].admissionControlMandatory); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.accessType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.macAddressListCount); + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->apMacConfig.macAddressListCount; i2++) + { + CsrMemCpySer(ptr, len, (const void *) primitive->apMacConfig.macAddressList[i2].a, ((CsrUint16) (6))); + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.apHtParams.greenfieldSupported); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.apHtParams.shortGi20MHz); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.apHtParams.rxStbc); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.apHtParams.rifsModeAllowed); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.apHtParams.htProtection); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apMacConfig.apHtParams.dualCtsProtection); + return(ptr); +} + + +void* CsrWifiNmeApConfigSetReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApConfigSetReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apConfig.apGroupkeyTimeout, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apConfig.apStrictGtkRekey, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apConfig.apGmkTimeout, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apConfig.apResponseTimeout, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apConfig.apRetransLimit, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.phySupportedBitmap, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apMacConfig.beaconInterval, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.dtimPeriod, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apMacConfig.maxListenInterval, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.supportedRatesCount, buffer, &offset); + CsrMemCpyDes(primitive->apMacConfig.supportedRates, buffer, &offset, ((CsrUint16) (20))); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.preamble, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.shortSlotTimeEnabled, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.ctsProtectionType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmEnabled, buffer, &offset); + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApParams[i2].cwMin, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApParams[i2].cwMax, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApParams[i2].aifs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apMacConfig.wmmApParams[i2].txopLimit, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApParams[i2].admissionControlMandatory, buffer, &offset); + } + } + { + CsrUint16 i2; + for (i2 = 0; i2 < 4; i2++) + { + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApBcParams[i2].cwMin, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApBcParams[i2].cwMax, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApBcParams[i2].aifs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apMacConfig.wmmApBcParams[i2].txopLimit, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.wmmApBcParams[i2].admissionControlMandatory, buffer, &offset); + } + } + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.accessType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.macAddressListCount, buffer, &offset); + primitive->apMacConfig.macAddressList = NULL; + if (primitive->apMacConfig.macAddressListCount) + { + primitive->apMacConfig.macAddressList = (CsrWifiMacAddress *)CsrPmemAlloc(sizeof(CsrWifiMacAddress) * primitive->apMacConfig.macAddressListCount); + } + { + CsrUint16 i2; + for (i2 = 0; i2 < primitive->apMacConfig.macAddressListCount; i2++) + { + CsrMemCpyDes(primitive->apMacConfig.macAddressList[i2].a, buffer, &offset, ((CsrUint16) (6))); + } + } + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.apHtParams.greenfieldSupported, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.apHtParams.shortGi20MHz, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.apHtParams.rxStbc, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.apHtParams.rifsModeAllowed, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.apHtParams.htProtection, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apMacConfig.apHtParams.dualCtsProtection, buffer, &offset); + + return primitive; +} + + +void CsrWifiNmeApConfigSetReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *) voidPrimitivePointer; + CsrPmemFree(primitive->apMacConfig.macAddressList); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiNmeApWpsRegisterReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrWifiSmeWpsDpid primitive->selectedDevicePasswordId */ + bufferSize += 2; /* CsrWifiSmeWpsConfigType primitive->selectedConfigMethod */ + bufferSize += 8; /* CsrUint8 primitive->pin[8] */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApWpsRegisterReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApWpsRegisterReq *primitive = (CsrWifiNmeApWpsRegisterReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->selectedDevicePasswordId); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->selectedConfigMethod); + CsrMemCpySer(ptr, len, (const void *) primitive->pin, ((CsrUint16) (8))); + return(ptr); +} + + +void* CsrWifiNmeApWpsRegisterReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApWpsRegisterReq *primitive = (CsrWifiNmeApWpsRegisterReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApWpsRegisterReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->selectedDevicePasswordId, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->selectedConfigMethod, buffer, &offset); + CsrMemCpyDes(primitive->pin, buffer, &offset, ((CsrUint16) (8))); + + return primitive; +} + + +CsrSize CsrWifiNmeApStartReqSizeof(void *msg) +{ + CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *) msg; + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 112) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeApType primitive->apType */ + bufferSize += 1; /* CsrBool primitive->cloakSsid */ + bufferSize += 32; /* CsrUint8 primitive->ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->ssid.length */ + bufferSize += 1; /* CsrWifiSmeRadioIF primitive->ifIndex */ + bufferSize += 1; /* CsrUint8 primitive->channel */ + bufferSize += 1; /* CsrWifiSmeApAuthType primitive->apCredentials.authType */ + switch (primitive->apCredentials.authType) + { + case CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM: + bufferSize += 1; /* CsrUint8 primitive->apCredentials.nmeAuthType.openSystemEmpty.empty */ + break; + case CSR_WIFI_SME_AP_AUTH_TYPE_WEP: + bufferSize += 1; /* CsrWifiSmeWepCredentialType primitive->apCredentials.nmeAuthType.authwep.wepKeyType */ + switch (primitive->apCredentials.nmeAuthType.authwep.wepKeyType) + { + case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128: + bufferSize += 1; /* CsrWifiSmeWepAuthMode primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.wepAuthType */ + bufferSize += 1; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.selectedWepKey */ + bufferSize += 13; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key1[13] */ + bufferSize += 13; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key2[13] */ + bufferSize += 13; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key3[13] */ + bufferSize += 13; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key4[13] */ + break; + case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64: + bufferSize += 1; /* CsrWifiSmeWepAuthMode primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.wepAuthType */ + bufferSize += 1; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.selectedWepKey */ + bufferSize += 5; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key1[5] */ + bufferSize += 5; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key2[5] */ + bufferSize += 5; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key3[5] */ + bufferSize += 5; /* CsrUint8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key4[5] */ + break; + default: + break; + } + break; + case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL: + bufferSize += 1; /* CsrWifiSmeApAuthSupportMask primitive->apCredentials.nmeAuthType.authTypePersonal.authSupport */ + bufferSize += 2; /* CsrWifiSmeApRsnCapabilitiesMask primitive->apCredentials.nmeAuthType.authTypePersonal.rsnCapabilities */ + bufferSize += 2; /* CsrWifiSmeApWapiCapabilitiesMask primitive->apCredentials.nmeAuthType.authTypePersonal.wapiCapabilities */ + bufferSize += 1; /* CsrWifiNmeApPersCredentialType primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase */ + switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase) + { + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK: + bufferSize += 2; /* CsrUint16 primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.encryptionMode */ + bufferSize += 32; /* CsrUint8 primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.psk[32] */ + break; + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE: + bufferSize += 2; /* CsrUint16 primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.encryptionMode */ + bufferSize += (primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase?CsrStrLen(primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase) : 0) + 1; /* CsrCharString* primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase (0 byte len + 1 for NULL Term) */ + break; + default: + break; + } + break; + default: + break; + } + bufferSize += 1; /* CsrUint8 primitive->maxConnections */ + bufferSize += 1; /* CsrWifiSmeP2pGroupCapabilityMask primitive->p2pGoParam.groupCapability */ + bufferSize += 3; /* CsrUint8 primitive->p2pGoParam.operatingChanList.country[3] */ + bufferSize += 1; /* CsrUint8 primitive->p2pGoParam.operatingChanList.channelEntryListCount */ + { + CsrUint16 i3; + for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++) + { + bufferSize += 1; /* CsrUint8 primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingClass */ + bufferSize += 1; /* CsrUint8 primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount */ + bufferSize += primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount; /* CsrUint8 primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel */ + } + } + bufferSize += 1; /* CsrBool primitive->p2pGoParam.opPsEnabled */ + bufferSize += 1; /* CsrUint8 primitive->p2pGoParam.ctWindow */ + bufferSize += 1; /* CsrWifiSmeP2pNoaConfigMethod primitive->p2pGoParam.noaConfigMethod */ + bufferSize += 1; /* CsrBool primitive->p2pGoParam.allowNoaWithNonP2pDevices */ + bufferSize += 1; /* CsrBool primitive->wpsEnabled */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApStartReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->cloakSsid); + CsrMemCpySer(ptr, len, (const void *) primitive->ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ssid.length); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ifIndex); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->channel); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.authType); + switch (primitive->apCredentials.authType) + { + case CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.openSystemEmpty.empty); + break; + case CSR_WIFI_SME_AP_AUTH_TYPE_WEP: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authwep.wepKeyType); + switch (primitive->apCredentials.nmeAuthType.authwep.wepKeyType) + { + case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.wepAuthType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.selectedWepKey); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key1, ((CsrUint16) (13))); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key2, ((CsrUint16) (13))); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key3, ((CsrUint16) (13))); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key4, ((CsrUint16) (13))); + break; + case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.wepAuthType); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.selectedWepKey); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key1, ((CsrUint16) (5))); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key2, ((CsrUint16) (5))); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key3, ((CsrUint16) (5))); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key4, ((CsrUint16) (5))); + break; + default: + break; + } + break; + case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL: + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authTypePersonal.authSupport); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apCredentials.nmeAuthType.authTypePersonal.rsnCapabilities); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apCredentials.nmeAuthType.authTypePersonal.wapiCapabilities); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase); + switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase) + { + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK: + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.encryptionMode); + CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.psk, ((CsrUint16) (32))); + break; + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE: + CsrUint16Ser(ptr, len, (CsrUint16) primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.encryptionMode); + CsrCharStringSer(ptr, len, primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase); + break; + default: + break; + } + break; + default: + break; + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->maxConnections); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.groupCapability); + CsrMemCpySer(ptr, len, (const void *) primitive->p2pGoParam.operatingChanList.country, ((CsrUint16) (3))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.operatingChanList.channelEntryListCount); + { + CsrUint16 i3; + for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++) + { + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingClass); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount); + if (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount) + { + CsrMemCpySer(ptr, len, (const void *) primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel, ((CsrUint16) (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount))); + } + } + } + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.opPsEnabled); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.ctWindow); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.noaConfigMethod); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->p2pGoParam.allowNoaWithNonP2pDevices); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wpsEnabled); + return(ptr); +} + + +void* CsrWifiNmeApStartReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApStartReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->cloakSsid, buffer, &offset); + CsrMemCpyDes(primitive->ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->ssid.length, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->ifIndex, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->channel, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.authType, buffer, &offset); + switch (primitive->apCredentials.authType) + { + case CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM: + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.openSystemEmpty.empty, buffer, &offset); + break; + case CSR_WIFI_SME_AP_AUTH_TYPE_WEP: + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authwep.wepKeyType, buffer, &offset); + switch (primitive->apCredentials.nmeAuthType.authwep.wepKeyType) + { + case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128: + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.wepAuthType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.selectedWepKey, buffer, &offset); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key1, buffer, &offset, ((CsrUint16) (13))); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key2, buffer, &offset, ((CsrUint16) (13))); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key3, buffer, &offset, ((CsrUint16) (13))); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key4, buffer, &offset, ((CsrUint16) (13))); + break; + case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64: + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.wepAuthType, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.selectedWepKey, buffer, &offset); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key1, buffer, &offset, ((CsrUint16) (5))); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key2, buffer, &offset, ((CsrUint16) (5))); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key3, buffer, &offset, ((CsrUint16) (5))); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key4, buffer, &offset, ((CsrUint16) (5))); + break; + default: + break; + } + break; + case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL: + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.authSupport, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.rsnCapabilities, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.wapiCapabilities, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase, buffer, &offset); + switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase) + { + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK: + CsrUint16Des((CsrUint16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.encryptionMode, buffer, &offset); + CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.psk, buffer, &offset, ((CsrUint16) (32))); + break; + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE: + CsrUint16Des((CsrUint16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.encryptionMode, buffer, &offset); + CsrCharStringDes(&primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase, buffer, &offset); + break; + default: + break; + } + break; + default: + break; + } + CsrUint8Des((CsrUint8 *) &primitive->maxConnections, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.groupCapability, buffer, &offset); + CsrMemCpyDes(primitive->p2pGoParam.operatingChanList.country, buffer, &offset, ((CsrUint16) (3))); + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.operatingChanList.channelEntryListCount, buffer, &offset); + primitive->p2pGoParam.operatingChanList.channelEntryList = NULL; + if (primitive->p2pGoParam.operatingChanList.channelEntryListCount) + { + primitive->p2pGoParam.operatingChanList.channelEntryList = (CsrWifiSmeApP2pOperatingChanEntry *)CsrPmemAlloc(sizeof(CsrWifiSmeApP2pOperatingChanEntry) * primitive->p2pGoParam.operatingChanList.channelEntryListCount); + } + { + CsrUint16 i3; + for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++) + { + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingClass, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount, buffer, &offset); + if (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount) + { + primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel = (CsrUint8 *)CsrPmemAlloc(primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount); + CsrMemCpyDes(primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel, buffer, &offset, ((CsrUint16) (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount))); + } + else + { + primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel = NULL; + } + } + } + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.opPsEnabled, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.ctWindow, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.noaConfigMethod, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->p2pGoParam.allowNoaWithNonP2pDevices, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wpsEnabled, buffer, &offset); + + return primitive; +} + + +void CsrWifiNmeApStartReqSerFree(void *voidPrimitivePointer) +{ + CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *) voidPrimitivePointer; + switch (primitive->apCredentials.authType) + { + case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL: + switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase) + { + case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE: + CsrPmemFree(primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase); + break; + default: + break; + } + break; + default: + break; + } + { + CsrUint16 i3; + for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++) + { + CsrPmemFree(primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel); + } + } + CsrPmemFree(primitive->p2pGoParam.operatingChanList.channelEntryList); + CsrPmemFree(primitive); +} + + +CsrSize CsrWifiNmeApWmmParamUpdateReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 51) */ + { + CsrUint16 i1; + for (i1 = 0; i1 < 4; i1++) + { + bufferSize += 1; /* CsrUint8 primitive->wmmApParams[i1].cwMin */ + bufferSize += 1; /* CsrUint8 primitive->wmmApParams[i1].cwMax */ + bufferSize += 1; /* CsrUint8 primitive->wmmApParams[i1].aifs */ + bufferSize += 2; /* CsrUint16 primitive->wmmApParams[i1].txopLimit */ + bufferSize += 1; /* CsrBool primitive->wmmApParams[i1].admissionControlMandatory */ + } + } + { + CsrUint16 i1; + for (i1 = 0; i1 < 4; i1++) + { + bufferSize += 1; /* CsrUint8 primitive->wmmApBcParams[i1].cwMin */ + bufferSize += 1; /* CsrUint8 primitive->wmmApBcParams[i1].cwMax */ + bufferSize += 1; /* CsrUint8 primitive->wmmApBcParams[i1].aifs */ + bufferSize += 2; /* CsrUint16 primitive->wmmApBcParams[i1].txopLimit */ + bufferSize += 1; /* CsrBool primitive->wmmApBcParams[i1].admissionControlMandatory */ + } + } + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApWmmParamUpdateReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApWmmParamUpdateReq *primitive = (CsrWifiNmeApWmmParamUpdateReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + { + CsrUint16 i1; + for (i1 = 0; i1 < 4; i1++) + { + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApParams[i1].cwMin); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApParams[i1].cwMax); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApParams[i1].aifs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->wmmApParams[i1].txopLimit); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApParams[i1].admissionControlMandatory); + } + } + { + CsrUint16 i1; + for (i1 = 0; i1 < 4; i1++) + { + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApBcParams[i1].cwMin); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApBcParams[i1].cwMax); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApBcParams[i1].aifs); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->wmmApBcParams[i1].txopLimit); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->wmmApBcParams[i1].admissionControlMandatory); + } + } + return(ptr); +} + + +void* CsrWifiNmeApWmmParamUpdateReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApWmmParamUpdateReq *primitive = (CsrWifiNmeApWmmParamUpdateReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApWmmParamUpdateReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + { + CsrUint16 i1; + for (i1 = 0; i1 < 4; i1++) + { + CsrUint8Des((CsrUint8 *) &primitive->wmmApParams[i1].cwMin, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wmmApParams[i1].cwMax, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wmmApParams[i1].aifs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->wmmApParams[i1].txopLimit, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wmmApParams[i1].admissionControlMandatory, buffer, &offset); + } + } + { + CsrUint16 i1; + for (i1 = 0; i1 < 4; i1++) + { + CsrUint8Des((CsrUint8 *) &primitive->wmmApBcParams[i1].cwMin, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wmmApBcParams[i1].cwMax, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wmmApBcParams[i1].aifs, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->wmmApBcParams[i1].txopLimit, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->wmmApBcParams[i1].admissionControlMandatory, buffer, &offset); + } + } + + return primitive; +} + + +CsrSize CsrWifiNmeApStaRemoveReqSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 6; /* CsrUint8 primitive->staMacAddress.a[6] */ + bufferSize += 1; /* CsrBool primitive->keepBlocking */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApStaRemoveReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApStaRemoveReq *primitive = (CsrWifiNmeApStaRemoveReq *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrMemCpySer(ptr, len, (const void *) primitive->staMacAddress.a, ((CsrUint16) (6))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->keepBlocking); + return(ptr); +} + + +void* CsrWifiNmeApStaRemoveReqDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApStaRemoveReq *primitive = (CsrWifiNmeApStaRemoveReq *) CsrPmemAlloc(sizeof(CsrWifiNmeApStaRemoveReq)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrMemCpyDes(primitive->staMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrUint8Des((CsrUint8 *) &primitive->keepBlocking, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiNmeApWpsRegisterCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApWpsRegisterCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApWpsRegisterCfm *primitive = (CsrWifiNmeApWpsRegisterCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiNmeApWpsRegisterCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApWpsRegisterCfm *primitive = (CsrWifiNmeApWpsRegisterCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApWpsRegisterCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiNmeApStartCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 40) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + bufferSize += 32; /* CsrUint8 primitive->ssid.ssid[32] */ + bufferSize += 1; /* CsrUint8 primitive->ssid.length */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApStartCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApStartCfm *primitive = (CsrWifiNmeApStartCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + CsrMemCpySer(ptr, len, (const void *) primitive->ssid.ssid, ((CsrUint16) (32))); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->ssid.length); + return(ptr); +} + + +void* CsrWifiNmeApStartCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApStartCfm *primitive = (CsrWifiNmeApStartCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApStartCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + CsrMemCpyDes(primitive->ssid.ssid, buffer, &offset, ((CsrUint16) (32))); + CsrUint8Des((CsrUint8 *) &primitive->ssid.length, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiNmeApStopCfmSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApStopCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApStopCfm *primitive = (CsrWifiNmeApStopCfm *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiNmeApStopCfmDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApStopCfm *primitive = (CsrWifiNmeApStopCfm *) CsrPmemAlloc(sizeof(CsrWifiNmeApStopCfm)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiNmeApStopIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeApType primitive->apType */ + bufferSize += 2; /* CsrResult primitive->status */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApStopIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApStopInd *primitive = (CsrWifiNmeApStopInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->apType); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->status); + return(ptr); +} + + +void* CsrWifiNmeApStopIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApStopInd *primitive = (CsrWifiNmeApStopInd *) CsrPmemAlloc(sizeof(CsrWifiNmeApStopInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->apType, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset); + + return primitive; +} + + +CsrSize CsrWifiNmeApStationIndSizeof(void *msg) +{ + CsrSize bufferSize = 2; + + /* Calculate the Size of the Serialised Data. Could be more efficient (Try 18) */ + bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ + bufferSize += 1; /* CsrWifiSmeMediaStatus primitive->mediaStatus */ + bufferSize += 6; /* CsrUint8 primitive->peerMacAddress.a[6] */ + bufferSize += 6; /* CsrUint8 primitive->peerDeviceAddress.a[6] */ + return bufferSize; +} + + +CsrUint8* CsrWifiNmeApStationIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) +{ + CsrWifiNmeApStationInd *primitive = (CsrWifiNmeApStationInd *)msg; + *len = 0; + CsrUint16Ser(ptr, len, primitive->common.type); + CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag); + CsrUint8Ser(ptr, len, (CsrUint8) primitive->mediaStatus); + CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((CsrUint16) (6))); + CsrMemCpySer(ptr, len, (const void *) primitive->peerDeviceAddress.a, ((CsrUint16) (6))); + return(ptr); +} + + +void* CsrWifiNmeApStationIndDes(CsrUint8 *buffer, CsrSize length) +{ + CsrWifiNmeApStationInd *primitive = (CsrWifiNmeApStationInd *) CsrPmemAlloc(sizeof(CsrWifiNmeApStationInd)); + CsrSize offset; + offset = 0; + + CsrUint16Des(&primitive->common.type, buffer, &offset); + CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset); + CsrUint8Des((CsrUint8 *) &primitive->mediaStatus, buffer, &offset); + CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((CsrUint16) (6))); + CsrMemCpyDes(primitive->peerDeviceAddress.a, buffer, &offset, ((CsrUint16) (6))); + + return primitive; +} + + +#endif /* CSR_WIFI_NME_ENABLE */ +#endif /* CSR_WIFI_AP_ENABLE */ diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index da12807434b4..283e3025641e 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -18,7 +18,7 @@ #include "unifi_priv.h" #include "csr_wifi_hip_conversions.h" #ifdef CSR_SUPPORT_WEXT_AP -#include "sme_csr/csr_wifi_sme_sef.h" +#include "csr_wifi_sme_sef.h" #endif diff --git a/drivers/staging/csr/unifi_native.h b/drivers/staging/csr/unifi_native.h index 0015ec2cdb00..a480c9e2435b 100644 --- a/drivers/staging/csr/unifi_native.h +++ b/drivers/staging/csr/unifi_native.h @@ -125,7 +125,7 @@ struct wext_config { int num_scan_info; /* Flag on whether non-802.1x packets are allowed out */ - CsrWifiRouterPortAction block_controlled_port; +/* CsrWifiRouterPortAction block_controlled_port;*/ /* Flag on whether we have completed an authenticate/associate process */ unsigned int flag_associated : 1; -- GitLab From c621a81edecdee85da32c566c21836332c764fda Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:48 +0200 Subject: [PATCH 2762/6849] Revert "usb/uas: make sure data urb is gone if we receive status before that" This reverts commit e4d8318a85779b25b880187b1b1c44e797bd7d4b. This patch makes uas.c call usb_unlink_urb on data urbs. The data urbs get freed in the completion callback. This is illegal according to the usb_unlink_urb documentation. This patch also makes the code expect the data completion callback being called before the status completion callback. This isn't guaranteed to be the case, even though the actual data transfer should be finished by the time the status is received. Background: The ehci irq handler for example only know that there are finished transfers, it then has go check the QHs & TDs to see which transfers did actually finish. It has no way to figure in which order the transfers did complete. The xhci driver can call the callbacks in completion order thanks to the event queue. This does nicely explain why the driver is solid on a (usb2) xhci port whereas it goes crazy on ehci in my testing. Signed-off-by: Gerd Hoffmann Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 90 +++++++-------------------------------- 1 file changed, 15 insertions(+), 75 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 8ec8a6e66f50..f98ba40352c1 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -58,9 +58,6 @@ enum { SUBMIT_DATA_OUT_URB = (1 << 5), ALLOC_CMD_URB = (1 << 6), SUBMIT_CMD_URB = (1 << 7), - COMPLETED_DATA_IN = (1 << 8), - COMPLETED_DATA_OUT = (1 << 9), - DATA_COMPLETES_CMD = (1 << 10), }; /* Overrides scsi_pointer */ @@ -114,7 +111,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 16) { unsigned len = be16_to_cpup(&sense_iu->len); @@ -132,15 +128,13 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (!(cmdinfo->state & DATA_COMPLETES_CMD)) - cmnd->scsi_done(cmnd); + cmnd->scsi_done(cmnd); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu_old *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 8) { unsigned len = be16_to_cpup(&sense_iu->len) - 2; @@ -158,8 +152,7 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (!(cmdinfo->state & DATA_COMPLETES_CMD)) - cmnd->scsi_done(cmnd); + cmnd->scsi_done(cmnd); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -184,7 +177,6 @@ static void uas_stat_cmplt(struct urb *urb) struct Scsi_Host *shost = urb->context; struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; - struct uas_cmd_info *cmdinfo; u16 tag; int ret; @@ -210,32 +202,12 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); return; } - cmdinfo = (void *)&cmnd->SCp; switch (iu->iu_id) { case IU_ID_STATUS: if (devinfo->cmnd == cmnd) devinfo->cmnd = NULL; - if (!(cmdinfo->state & COMPLETED_DATA_IN) && - cmdinfo->data_in_urb) { - if (devinfo->use_streams) { - cmdinfo->state |= DATA_COMPLETES_CMD; - usb_unlink_urb(cmdinfo->data_in_urb); - } else { - usb_free_urb(cmdinfo->data_in_urb); - } - } - if (!(cmdinfo->state & COMPLETED_DATA_OUT) && - cmdinfo->data_out_urb) { - if (devinfo->use_streams) { - cmdinfo->state |= DATA_COMPLETES_CMD; - usb_unlink_urb(cmdinfo->data_in_urb); - } else { - usb_free_urb(cmdinfo->data_out_urb); - } - } - if (urb->actual_length < 16) devinfo->uas_sense_old = 1; if (devinfo->uas_sense_old) @@ -264,59 +236,27 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); } -static void uas_data_out_cmplt(struct urb *urb) -{ - struct scsi_cmnd *cmnd = urb->context; - struct scsi_data_buffer *sdb = scsi_out(cmnd); - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; - - cmdinfo->state |= COMPLETED_DATA_OUT; - - sdb->resid = sdb->length - urb->actual_length; - usb_free_urb(urb); - - if (cmdinfo->state & DATA_COMPLETES_CMD) - cmnd->scsi_done(cmnd); -} - -static void uas_data_in_cmplt(struct urb *urb) +static void uas_data_cmplt(struct urb *urb) { - struct scsi_cmnd *cmnd = urb->context; - struct scsi_data_buffer *sdb = scsi_in(cmnd); - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; - - cmdinfo->state |= COMPLETED_DATA_IN; - + struct scsi_data_buffer *sdb = urb->context; sdb->resid = sdb->length - urb->actual_length; usb_free_urb(urb); - - if (cmdinfo->state & DATA_COMPLETES_CMD) - cmnd->scsi_done(cmnd); } static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, - unsigned int pipe, struct scsi_cmnd *cmnd, - enum dma_data_direction dir) + unsigned int pipe, u16 stream_id, + struct scsi_data_buffer *sdb, + enum dma_data_direction dir) { - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); - struct scsi_data_buffer *sdb; - usb_complete_t complete_fn; - u16 stream_id = cmdinfo->stream; if (!urb) goto out; - if (dir == DMA_FROM_DEVICE) { - sdb = scsi_in(cmnd); - complete_fn = uas_data_in_cmplt; - } else { - sdb = scsi_out(cmnd); - complete_fn = uas_data_out_cmplt; - } - usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, - complete_fn, cmnd); - urb->stream_id = stream_id; + usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, + sdb); + if (devinfo->use_streams) + urb->stream_id = stream_id; urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; urb->sg = sdb->table.sgl; out: @@ -418,8 +358,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_IN_URB) { cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_in_pipe, cmnd, - DMA_FROM_DEVICE); + devinfo->data_in_pipe, cmdinfo->stream, + scsi_in(cmnd), DMA_FROM_DEVICE); if (!cmdinfo->data_in_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_IN_URB; @@ -436,8 +376,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_OUT_URB) { cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_out_pipe, cmnd, - DMA_TO_DEVICE); + devinfo->data_out_pipe, cmdinfo->stream, + scsi_out(cmnd), DMA_TO_DEVICE); if (!cmdinfo->data_out_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_OUT_URB; -- GitLab From db32de11f75673c2a0f2651ae58b0f25b8c5b0eb Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:49 +0200 Subject: [PATCH 2763/6849] Revert "usb/uas: one only one status URB/host on stream-less connection" This reverts commit ceb3f91fd53c9fbd7b292fc2754ba4efffeeeedb. IMO the real bug is assigning status urbs to scsi requests. First there is no such link in the non-stream case. Also there isn't nessesarely a scsi request in the first place, for example when submitting task management requests. This patch just papers over the real bug and introduces different status urb handling in the stream/non-stream case for no good reason. Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 70 ++++++--------------------------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index f98ba40352c1..36279a46fd27 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -46,7 +46,6 @@ struct uas_dev_info { unsigned use_streams:1; unsigned uas_sense_old:1; struct scsi_cmnd *cmnd; - struct urb *status_urb; /* used only if stream support is available */ }; enum { @@ -65,7 +64,6 @@ struct uas_cmd_info { unsigned int state; unsigned int stream; struct urb *cmd_urb; - /* status_urb is used only if stream support isn't available */ struct urb *status_urb; struct urb *data_in_urb; struct urb *data_out_urb; @@ -129,6 +127,7 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); + usb_free_urb(urb); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) @@ -153,6 +152,7 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); + usb_free_urb(urb); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -161,7 +161,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; int err; - cmdinfo->state = direction; + cmdinfo->state = direction | SUBMIT_STATUS_URB; err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); if (err) { spin_lock(&uas_work_lock); @@ -178,12 +178,10 @@ static void uas_stat_cmplt(struct urb *urb) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; u16 tag; - int ret; if (urb->status) { dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status); - if (devinfo->use_streams) - usb_free_urb(urb); + usb_free_urb(urb); return; } @@ -193,13 +191,7 @@ static void uas_stat_cmplt(struct urb *urb) else cmnd = scsi_host_find_tag(shost, tag - 1); if (!cmnd) { - if (devinfo->use_streams) { - usb_free_urb(urb); - return; - } - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) - dev_err(&urb->dev->dev, "failed submit status urb\n"); + usb_free_urb(urb); return; } @@ -225,15 +217,6 @@ static void uas_stat_cmplt(struct urb *urb) scmd_printk(KERN_ERR, cmnd, "Bogus IU (%d) received on status pipe\n", iu->iu_id); } - - if (devinfo->use_streams) { - usb_free_urb(urb); - return; - } - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) - dev_err(&urb->dev->dev, "failed submit status urb\n"); } static void uas_data_cmplt(struct urb *urb) @@ -264,7 +247,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, } static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, - struct Scsi_Host *shost, u16 stream_id) + struct scsi_cmnd *cmnd, u16 stream_id) { struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); @@ -278,7 +261,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), - uas_stat_cmplt, shost); + uas_stat_cmplt, cmnd->device->host); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; out: @@ -340,8 +323,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (cmdinfo->state & ALLOC_STATUS_URB) { - cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, - cmnd->device->host, cmdinfo->stream); + cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, + cmdinfo->stream); if (!cmdinfo->status_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_STATUS_URB; @@ -450,8 +433,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, } if (!devinfo->use_streams) { - cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB | - ALLOC_STATUS_URB | SUBMIT_STATUS_URB); + cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); cmdinfo->stream = 0; } @@ -662,29 +644,6 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) } } -static int uas_alloc_status_urb(struct uas_dev_info *devinfo, - struct Scsi_Host *shost) -{ - if (devinfo->use_streams) { - devinfo->status_urb = NULL; - return 0; - } - - devinfo->status_urb = uas_alloc_sense_urb(devinfo, GFP_KERNEL, - shost, 0); - if (!devinfo->status_urb) - goto err_s_urb; - - if (usb_submit_urb(devinfo->status_urb, GFP_KERNEL)) - goto err_submit_urb; - - return 0; -err_submit_urb: - usb_free_urb(devinfo->status_urb); -err_s_urb: - return -ENOMEM; -} - static void uas_free_streams(struct uas_dev_info *devinfo) { struct usb_device *udev = devinfo->udev; @@ -739,17 +698,10 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) shost->hostdata[0] = (unsigned long)devinfo; - result = uas_alloc_status_urb(devinfo, shost); - if (result) - goto err_alloc_status; - scsi_scan_host(shost); usb_set_intfdata(intf, shost); return result; -err_alloc_status: - scsi_remove_host(shost); - shost = NULL; deconfig_eps: uas_free_streams(devinfo); free: @@ -777,8 +729,6 @@ static void uas_disconnect(struct usb_interface *intf) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); - usb_kill_urb(devinfo->status_urb); - usb_free_urb(devinfo->status_urb); uas_free_streams(devinfo); kfree(devinfo); } -- GitLab From e9bd7e1a2d34de3b0991c81080d56dc408110833 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:50 +0200 Subject: [PATCH 2764/6849] uas: fix sense urb handling Stop reusing sense urbs, just allocate a fresh one each time and free it when done. Stop storing a sense urb pointer in the scsi request, all you can do with it is misusing. For example requeuing the sense urb, then f*ck it up by picking the wrong one in case tagged requests don't finish in the same order you've submitted them. Also note that (not-yet supported) task management ops don't have a scsi request in the first place. Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 49 ++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 36279a46fd27..b01273819692 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -49,7 +49,6 @@ struct uas_dev_info { }; enum { - ALLOC_STATUS_URB = (1 << 0), SUBMIT_STATUS_URB = (1 << 1), ALLOC_DATA_IN_URB = (1 << 2), SUBMIT_DATA_IN_URB = (1 << 3), @@ -64,7 +63,6 @@ struct uas_cmd_info { unsigned int state; unsigned int stream; struct urb *cmd_urb; - struct urb *status_urb; struct urb *data_in_urb; struct urb *data_out_urb; struct list_head list; @@ -127,7 +125,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); - usb_free_urb(urb); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) @@ -152,7 +149,6 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); - usb_free_urb(urb); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -217,6 +213,7 @@ static void uas_stat_cmplt(struct urb *urb) scmd_printk(KERN_ERR, cmnd, "Bogus IU (%d) received on status pipe\n", iu->iu_id); } + usb_free_urb(urb); } static void uas_data_cmplt(struct urb *urb) @@ -247,7 +244,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, } static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, - struct scsi_cmnd *cmnd, u16 stream_id) + struct Scsi_Host *shost, u16 stream_id) { struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); @@ -261,7 +258,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), - uas_stat_cmplt, cmnd->device->host); + uas_stat_cmplt, shost); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; out: @@ -317,24 +314,35 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, * daft to me. */ -static int uas_submit_urbs(struct scsi_cmnd *cmnd, - struct uas_dev_info *devinfo, gfp_t gfp) +static int uas_submit_sense_urb(struct Scsi_Host *shost, + gfp_t gfp, unsigned int stream) { - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; + struct urb *urb; - if (cmdinfo->state & ALLOC_STATUS_URB) { - cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, - cmdinfo->stream); - if (!cmdinfo->status_urb) - return SCSI_MLQUEUE_DEVICE_BUSY; - cmdinfo->state &= ~ALLOC_STATUS_URB; + urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream); + if (!urb) + return SCSI_MLQUEUE_DEVICE_BUSY; + if (usb_submit_urb(urb, gfp)) { + shost_printk(KERN_INFO, shost, + "sense urb submission failure\n"); + usb_free_urb(urb); + return SCSI_MLQUEUE_DEVICE_BUSY; } + return 0; +} + +static int uas_submit_urbs(struct scsi_cmnd *cmnd, + struct uas_dev_info *devinfo, gfp_t gfp) +{ + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + int err; if (cmdinfo->state & SUBMIT_STATUS_URB) { - if (usb_submit_urb(cmdinfo->status_urb, gfp)) { - scmd_printk(KERN_INFO, cmnd, - "sense urb submission failure\n"); - return SCSI_MLQUEUE_DEVICE_BUSY; + err = uas_submit_sense_urb(cmnd->device->host, gfp, + cmdinfo->stream); + if (err) { + return err; } cmdinfo->state &= ~SUBMIT_STATUS_URB; } @@ -417,7 +425,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, cmnd->scsi_done = done; - cmdinfo->state = ALLOC_STATUS_URB | SUBMIT_STATUS_URB | + cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB; switch (cmnd->sc_data_direction) { @@ -441,7 +449,6 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, if (err) { /* If we did nothing, give up now */ if (cmdinfo->state & SUBMIT_STATUS_URB) { - usb_free_urb(cmdinfo->status_urb); return SCSI_MLQUEUE_DEVICE_BUSY; } spin_lock(&uas_work_lock); -- GitLab From b1d6769333496b05818fe6cec72ef7f7504ef9e4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:51 +0200 Subject: [PATCH 2765/6849] uas: keep track of command state, finish scsi cmd when really done. Set state bits after submitting data urbs & command urbs, so we know what is in flight. Clear data bits when the data urb is finished, clear command bit when we see the status urb for the command. Finish the scsi command after running both status and data completion handlers for the command. Add a cmd status logging function for debugging purposes. Hook it into the error handler, so we see in the log what status a command is in which the scsi layer wants cancel. Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 86 ++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index b01273819692..b589b2e0e928 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -56,6 +56,10 @@ enum { SUBMIT_DATA_OUT_URB = (1 << 5), ALLOC_CMD_URB = (1 << 6), SUBMIT_CMD_URB = (1 << 7), + COMMAND_INFLIGHT = (1 << 8), + DATA_IN_URB_INFLIGHT = (1 << 9), + DATA_OUT_URB_INFLIGHT = (1 << 10), + COMMAND_COMPLETED = (1 << 11), }; /* Overrides scsi_pointer */ @@ -124,7 +128,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - cmnd->scsi_done(cmnd); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) @@ -148,16 +151,51 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; +} + +static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller) +{ + struct uas_cmd_info *ci = (void *)&cmnd->SCp; + + scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:" + "%s%s%s%s%s%s%s%s%s%s%s\n", + caller, cmnd, cmnd->request->tag, + (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "", + (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "", + (ci->state & SUBMIT_DATA_IN_URB) ? " s-in" : "", + (ci->state & ALLOC_DATA_OUT_URB) ? " a-out" : "", + (ci->state & SUBMIT_DATA_OUT_URB) ? " s-out" : "", + (ci->state & ALLOC_CMD_URB) ? " a-cmd" : "", + (ci->state & SUBMIT_CMD_URB) ? " s-cmd" : "", + (ci->state & COMMAND_INFLIGHT) ? " CMD" : "", + (ci->state & DATA_IN_URB_INFLIGHT) ? " IN" : "", + (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT" : "", + (ci->state & COMMAND_COMPLETED) ? " done" : ""); +} + +static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) +{ + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + + if (cmdinfo->state & (COMMAND_INFLIGHT | + DATA_IN_URB_INFLIGHT | + DATA_OUT_URB_INFLIGHT)) + return -EBUSY; + BUG_ON(cmdinfo->state & COMMAND_COMPLETED); + cmdinfo->state |= COMMAND_COMPLETED; + usb_free_urb(cmdinfo->data_in_urb); + usb_free_urb(cmdinfo->data_out_urb); cmnd->scsi_done(cmnd); + return 0; } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, - unsigned direction) + unsigned direction) { struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; int err; - cmdinfo->state = direction | SUBMIT_STATUS_URB; + cmdinfo->state |= direction | SUBMIT_STATUS_URB; err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); if (err) { spin_lock(&uas_work_lock); @@ -173,6 +211,7 @@ static void uas_stat_cmplt(struct urb *urb) struct Scsi_Host *shost = urb->context; struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; + struct uas_cmd_info *cmdinfo; u16 tag; if (urb->status) { @@ -190,6 +229,7 @@ static void uas_stat_cmplt(struct urb *urb) usb_free_urb(urb); return; } + cmdinfo = (void *)&cmnd->SCp; switch (iu->iu_id) { case IU_ID_STATUS: @@ -202,6 +242,8 @@ static void uas_stat_cmplt(struct urb *urb) uas_sense_old(urb, cmnd); else uas_sense(urb, cmnd); + cmdinfo->state &= ~COMMAND_INFLIGHT; + uas_try_complete(cmnd, __func__); break; case IU_ID_READ_READY: uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB); @@ -218,23 +260,36 @@ static void uas_stat_cmplt(struct urb *urb) static void uas_data_cmplt(struct urb *urb) { - struct scsi_data_buffer *sdb = urb->context; + struct scsi_cmnd *cmnd = urb->context; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + struct scsi_data_buffer *sdb = NULL; + + if (cmdinfo->data_in_urb == urb) { + sdb = scsi_in(cmnd); + cmdinfo->state &= ~DATA_IN_URB_INFLIGHT; + } else if (cmdinfo->data_out_urb == urb) { + sdb = scsi_out(cmnd); + cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT; + } + BUG_ON(sdb == NULL); sdb->resid = sdb->length - urb->actual_length; - usb_free_urb(urb); + uas_try_complete(cmnd, __func__); } static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, - unsigned int pipe, u16 stream_id, - struct scsi_data_buffer *sdb, - enum dma_data_direction dir) + unsigned int pipe, u16 stream_id, + struct scsi_cmnd *cmnd, + enum dma_data_direction dir) { struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); + struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE) + ? scsi_in(cmnd) : scsi_out(cmnd); if (!urb) goto out; - usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, - sdb); + usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, + uas_data_cmplt, cmnd); if (devinfo->use_streams) urb->stream_id = stream_id; urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; @@ -350,7 +405,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_IN_URB) { cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, devinfo->data_in_pipe, cmdinfo->stream, - scsi_in(cmnd), DMA_FROM_DEVICE); + cmnd, DMA_FROM_DEVICE); if (!cmdinfo->data_in_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_IN_URB; @@ -363,12 +418,13 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, return SCSI_MLQUEUE_DEVICE_BUSY; } cmdinfo->state &= ~SUBMIT_DATA_IN_URB; + cmdinfo->state |= DATA_IN_URB_INFLIGHT; } if (cmdinfo->state & ALLOC_DATA_OUT_URB) { cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, devinfo->data_out_pipe, cmdinfo->stream, - scsi_out(cmnd), DMA_TO_DEVICE); + cmnd, DMA_TO_DEVICE); if (!cmdinfo->data_out_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_OUT_URB; @@ -381,6 +437,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, return SCSI_MLQUEUE_DEVICE_BUSY; } cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; + cmdinfo->state |= DATA_OUT_URB_INFLIGHT; } if (cmdinfo->state & ALLOC_CMD_URB) { @@ -398,6 +455,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, return SCSI_MLQUEUE_DEVICE_BUSY; } cmdinfo->state &= ~SUBMIT_CMD_URB; + cmdinfo->state |= COMMAND_INFLIGHT; } return 0; @@ -464,9 +522,7 @@ static DEF_SCSI_QCMD(uas_queuecommand) static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) { - struct scsi_device *sdev = cmnd->device; - sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, - cmnd->request->tag); + uas_log_cmd_state(cmnd, __func__); /* XXX: Send ABORT TASK Task Management command */ return FAILED; -- GitLab From 8aac863e9295c42683b5b39ab65e17711e21b34c Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:52 +0200 Subject: [PATCH 2766/6849] uas: improve error handling (1) Handle data pipe errors: When the data urb failed we didn't transfer anything, update scsi_cmnd accordingly. (2) Cancel data transfers when we got back an error on the status pipe. Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index b589b2e0e928..d8b7bc6ea141 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -242,6 +242,13 @@ static void uas_stat_cmplt(struct urb *urb) uas_sense_old(urb, cmnd); else uas_sense(urb, cmnd); + if (cmnd->result != 0) { + /* cancel data transfers on error */ + if (cmdinfo->state & DATA_IN_URB_INFLIGHT) + usb_unlink_urb(cmdinfo->data_in_urb); + if (cmdinfo->state & DATA_OUT_URB_INFLIGHT) + usb_unlink_urb(cmdinfo->data_out_urb); + } cmdinfo->state &= ~COMMAND_INFLIGHT; uas_try_complete(cmnd, __func__); break; @@ -272,7 +279,12 @@ static void uas_data_cmplt(struct urb *urb) cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT; } BUG_ON(sdb == NULL); - sdb->resid = sdb->length - urb->actual_length; + if (urb->status) { + /* error: no data transfered */ + sdb->resid = sdb->length; + } else { + sdb->resid = sdb->length - urb->actual_length; + } uas_try_complete(cmnd, __func__); } -- GitLab From bdd000fb34202530e5cd11260d06f57e2daf63c9 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:53 +0200 Subject: [PATCH 2767/6849] uas: track urbs, kill inflight urbs on disconnect. Use separate anchors for data and sense urbs, which I think will be useful when implementing error handling. Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index d8b7bc6ea141..875829a56183 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -41,6 +41,8 @@ struct sense_iu_old { struct uas_dev_info { struct usb_interface *intf; struct usb_device *udev; + struct usb_anchor sense_urbs; + struct usb_anchor data_urbs; int qdepth; unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; unsigned use_streams:1; @@ -396,6 +398,7 @@ static int uas_submit_sense_urb(struct Scsi_Host *shost, usb_free_urb(urb); return SCSI_MLQUEUE_DEVICE_BUSY; } + usb_anchor_urb(urb, &devinfo->sense_urbs); return 0; } @@ -431,6 +434,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, } cmdinfo->state &= ~SUBMIT_DATA_IN_URB; cmdinfo->state |= DATA_IN_URB_INFLIGHT; + usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs); } if (cmdinfo->state & ALLOC_DATA_OUT_URB) { @@ -450,6 +454,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, } cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; cmdinfo->state |= DATA_OUT_URB_INFLIGHT; + usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs); } if (cmdinfo->state & ALLOC_CMD_URB) { @@ -761,6 +766,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) devinfo->intf = intf; devinfo->udev = udev; + init_usb_anchor(&devinfo->sense_urbs); + init_usb_anchor(&devinfo->data_urbs); uas_configure_endpoints(devinfo); result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); @@ -804,6 +811,8 @@ static void uas_disconnect(struct usb_interface *intf) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); + usb_kill_anchored_urbs(&devinfo->sense_urbs); + usb_kill_anchored_urbs(&devinfo->data_urbs); uas_free_streams(devinfo); kfree(devinfo); } -- GitLab From 023b515e5b304122f3802abaa68d1da46fdf48b8 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 19 Jun 2012 09:54:54 +0200 Subject: [PATCH 2768/6849] uas: task mgmt & error handling Add task management support, wind up in abort and device reset error handlers. Cancel all in-flight urbs in bus reset handler. Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 160 +++++++++++++++++++++++++++++++------- include/linux/usb/uas.h | 40 ++++++++++ 2 files changed, 171 insertions(+), 29 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 875829a56183..638cd64f9610 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -43,7 +43,8 @@ struct uas_dev_info { struct usb_device *udev; struct usb_anchor sense_urbs; struct usb_anchor data_urbs; - int qdepth; + int qdepth, resetting; + struct response_ui response; unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; unsigned use_streams:1; unsigned uas_sense_old:1; @@ -68,6 +69,7 @@ enum { struct uas_cmd_info { unsigned int state; unsigned int stream; + unsigned int aborted; struct urb *cmd_urb; struct urb *data_in_urb; struct urb *data_out_urb; @@ -222,16 +224,24 @@ static void uas_stat_cmplt(struct urb *urb) return; } + if (devinfo->resetting) { + usb_free_urb(urb); + return; + } + tag = be16_to_cpup(&iu->tag) - 1; if (tag == 0) cmnd = devinfo->cmnd; else cmnd = scsi_host_find_tag(shost, tag - 1); if (!cmnd) { - usb_free_urb(urb); - return; + if (iu->iu_id != IU_ID_RESPONSE) { + usb_free_urb(urb); + return; + } + } else { + cmdinfo = (void *)&cmnd->SCp; } - cmdinfo = (void *)&cmnd->SCp; switch (iu->iu_id) { case IU_ID_STATUS: @@ -260,6 +270,10 @@ static void uas_stat_cmplt(struct urb *urb) case IU_ID_WRITE_READY: uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB); break; + case IU_ID_RESPONSE: + /* store results for uas_eh_task_mgmt() */ + memcpy(&devinfo->response, iu, sizeof(devinfo->response)); + break; default: scmd_printk(KERN_ERR, cmnd, "Bogus IU (%d) received on status pipe\n", iu->iu_id); @@ -287,6 +301,9 @@ static void uas_data_cmplt(struct urb *urb) } else { sdb->resid = sdb->length - urb->actual_length; } + if (cmdinfo->aborted) { + return; + } uas_try_complete(cmnd, __func__); } @@ -377,6 +394,51 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, return NULL; } +static int uas_submit_task_urb(struct scsi_cmnd *cmnd, gfp_t gfp, + u8 function, u16 stream_id) +{ + struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; + struct usb_device *udev = devinfo->udev; + struct urb *urb = usb_alloc_urb(0, gfp); + struct task_mgmt_iu *iu; + int err = -ENOMEM; + + if (!urb) + goto err; + + iu = kzalloc(sizeof(*iu), gfp); + if (!iu) + goto err; + + iu->iu_id = IU_ID_TASK_MGMT; + iu->tag = cpu_to_be16(stream_id); + int_to_scsilun(cmnd->device->lun, &iu->lun); + + iu->function = function; + switch (function) { + case TMF_ABORT_TASK: + if (blk_rq_tagged(cmnd->request)) + iu->task_tag = cpu_to_be16(cmnd->request->tag + 2); + else + iu->task_tag = cpu_to_be16(1); + break; + } + + usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu), + usb_free_urb, NULL); + urb->transfer_flags |= URB_FREE_BUFFER; + + err = usb_submit_urb(urb, gfp); + if (err) + goto err; + + return 0; + +err: + usb_free_urb(urb); + return err; +} + /* * Why should I request the Status IU before sending the Command IU? Spec * says to, but also says the device may receive them in any order. Seems @@ -502,6 +564,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB; + cmdinfo->aborted = 0; switch (cmnd->sc_data_direction) { case DMA_FROM_DEVICE: @@ -537,34 +600,66 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, static DEF_SCSI_QCMD(uas_queuecommand) -static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) +static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, + const char *fname, u8 function) { - uas_log_cmd_state(cmnd, __func__); + struct Scsi_Host *shost = cmnd->device->host; + struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; + u16 tag = 9999; /* FIXME */ -/* XXX: Send ABORT TASK Task Management command */ - return FAILED; + memset(&devinfo->response, 0, sizeof(devinfo->response)); + if (uas_submit_sense_urb(shost, GFP_NOIO, tag)) { + shost_printk(KERN_INFO, shost, + "%s: %s: submit sense urb failed\n", + __func__, fname); + return FAILED; + } + if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) { + shost_printk(KERN_INFO, shost, + "%s: %s: submit task mgmt urb failed\n", + __func__, fname); + return FAILED; + } + if (0 == usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 3000)) { + shost_printk(KERN_INFO, shost, + "%s: %s timed out\n", __func__, fname); + return FAILED; + } + if (be16_to_cpu(devinfo->response.tag) != tag) { + shost_printk(KERN_INFO, shost, + "%s: %s failed (wrong tag %d/%d)\n", __func__, + fname, be16_to_cpu(devinfo->response.tag), tag); + return FAILED; + } + if (devinfo->response.response_code != RC_TMF_COMPLETE) { + shost_printk(KERN_INFO, shost, + "%s: %s failed (rc 0x%x)\n", __func__, + fname, devinfo->response.response_code); + return FAILED; + } + return SUCCESS; } -static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd) +static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) { - struct scsi_device *sdev = cmnd->device; - sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, - cmnd->request->tag); + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + int ret; -/* XXX: Send LOGICAL UNIT RESET Task Management command */ - return FAILED; + uas_log_cmd_state(cmnd, __func__); + cmdinfo->aborted = 1; + ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK); + if (cmdinfo->state & DATA_IN_URB_INFLIGHT) + usb_kill_urb(cmdinfo->data_in_urb); + if (cmdinfo->state & DATA_OUT_URB_INFLIGHT) + usb_kill_urb(cmdinfo->data_out_urb); + return ret; } -static int uas_eh_target_reset_handler(struct scsi_cmnd *cmnd) +static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd) { - struct scsi_device *sdev = cmnd->device; - sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, - cmnd->request->tag); - -/* XXX: Can we reset just the one USB interface? - * Would calling usb_set_interface() have the right effect? - */ - return FAILED; + sdev_printk(KERN_INFO, cmnd->device, "%s\n", __func__); + return uas_eh_task_mgmt(cmnd, "LOGICAL UNIT RESET", + TMF_LOGICAL_UNIT_RESET); } static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) @@ -572,14 +667,21 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) struct scsi_device *sdev = cmnd->device; struct uas_dev_info *devinfo = sdev->hostdata; struct usb_device *udev = devinfo->udev; + int err; - sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, - cmnd->request->tag); + devinfo->resetting = 1; + usb_kill_anchored_urbs(&devinfo->sense_urbs); + usb_kill_anchored_urbs(&devinfo->data_urbs); + err = usb_reset_device(udev); + devinfo->resetting = 0; - if (usb_reset_device(udev)) - return SUCCESS; + if (err) { + shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__); + return FAILED; + } - return FAILED; + shost_printk(KERN_INFO, sdev->host, "%s success\n", __func__); + return SUCCESS; } static int uas_slave_alloc(struct scsi_device *sdev) @@ -604,7 +706,6 @@ static struct scsi_host_template uas_host_template = { .slave_configure = uas_slave_configure, .eh_abort_handler = uas_eh_abort_handler, .eh_device_reset_handler = uas_eh_device_reset_handler, - .eh_target_reset_handler = uas_eh_target_reset_handler, .eh_bus_reset_handler = uas_eh_bus_reset_handler, .can_queue = 65536, /* Is there a limit on the _host_ ? */ .this_id = -1, @@ -766,6 +867,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) devinfo->intf = intf; devinfo->udev = udev; + devinfo->resetting = 0; init_usb_anchor(&devinfo->sense_urbs); init_usb_anchor(&devinfo->data_urbs); uas_configure_endpoints(devinfo); diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h index 9a988e413694..5499ab5c94bd 100644 --- a/include/linux/usb/uas.h +++ b/include/linux/usb/uas.h @@ -20,6 +20,28 @@ enum { IU_ID_WRITE_READY = 0x07, }; +enum { + TMF_ABORT_TASK = 0x01, + TMF_ABORT_TASK_SET = 0x02, + TMF_CLEAR_TASK_SET = 0x04, + TMF_LOGICAL_UNIT_RESET = 0x08, + TMF_I_T_NEXUS_RESET = 0x10, + TMF_CLEAR_ACA = 0x40, + TMF_QUERY_TASK = 0x80, + TMF_QUERY_TASK_SET = 0x81, + TMF_QUERY_ASYNC_EVENT = 0x82, +}; + +enum { + RC_TMF_COMPLETE = 0x00, + RC_INVALID_INFO_UNIT = 0x02, + RC_TMF_NOT_SUPPORTED = 0x04, + RC_TMF_FAILED = 0x05, + RC_TMF_SUCCEEDED = 0x08, + RC_INCORRECT_LUN = 0x09, + RC_OVERLAPPED_TAG = 0x0a, +}; + struct command_iu { __u8 iu_id; __u8 rsvd1; @@ -32,6 +54,16 @@ struct command_iu { __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ }; +struct task_mgmt_iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; + __u8 function; + __u8 rsvd2; + __be16 task_tag; + struct scsi_lun lun; +}; + /* * Also used for the Read Ready and Write Ready IUs since they have the * same first four bytes @@ -47,6 +79,14 @@ struct sense_iu { __u8 sense[SCSI_SENSE_BUFFERSIZE]; }; +struct response_ui { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; + __be16 add_response_info; + __u8 response_code; +}; + struct usb_pipe_usage_descriptor { __u8 bLength; __u8 bDescriptorType; -- GitLab From eb3979f64d25120d60b9e761a4c58f70b1a02f86 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Thu, 21 Jun 2012 11:36:50 +0100 Subject: [PATCH 2769/6849] stable: Allow merging of backports for serious user-visible performance issues Distribution kernel maintainers routinely backport fixes for users that were deemed important but not "something critical" as defined by the rules. To users of these kernels they are very serious and failing to fix them reduces the value of -stable. The problem is that the patches fixing these issues are often subtle and prone to regressions in other ways and need greater care and attention. To combat this, these "serious" backports should have a higher barrier to entry. This patch relaxes the rules to allow a distribution maintainer to merge to -stable a backported patch or small series that fixes a "serious" user-visible performance issue. They should include additional information on the user-visible bug affected and a link to the bugzilla entry if available. The same rules about the patch being already in mainline still apply. Signed-off-by: Mel Gorman Cc: stable Signed-off-by: Greg Kroah-Hartman --- Documentation/stable_kernel_rules.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index f0ab5cf28fca..4a7b54bd37e8 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -12,6 +12,12 @@ Rules on what kind of patches are accepted, and which ones are not, into the marked CONFIG_BROKEN), an oops, a hang, data corruption, a real security issue, or some "oh, that's not good" issue. In short, something critical. + - Serious issues as reported by a user of a distribution kernel may also + be considered if they fix a notable performance or interactivity issue. + As these fixes are not as obvious and have a higher risk of a subtle + regression they should only be submitted by a distribution kernel + maintainer and include an addendum linking to a bugzilla entry if it + exists and additional information on the user-visible impact. - New device IDs and quirks are also accepted. - No "theoretical race condition" issues, unless an explanation of how the race can be exploited is also provided. -- GitLab From 4661e3568a7d14a93d4e428d246cdb86f4bac6e7 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 22 Jun 2012 17:12:19 -0400 Subject: [PATCH 2770/6849] printk: fix regression in SYSLOG_ACTION_CLEAR Commit 7ff9554bb578ba02166071d2d487b7fc7d860d62 (printk: convert byte-buffer to variable-length record buffer) introduced a regression by accidentally removing a "break" statement from inside the big switch in printk's do_syslog(). The symptom of this bug is that the "dmesg -C" command doesn't only clear the kernel's log buffer; it also disables console logging. This patch (as1561) fixes the regression by adding the missing "break". Signed-off-by: Alan Stern CC: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/printk.c b/kernel/printk.c index a2276b916769..d6a1412f6b09 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1040,6 +1040,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) /* Clear ring buffer */ case SYSLOG_ACTION_CLEAR: syslog_print_all(NULL, 0, true); + break; /* Disable logging to console */ case SYSLOG_ACTION_CONSOLE_OFF: if (saved_console_loglevel == -1) -- GitLab From bed3d9c0b71f9afbfec905cb6db3b9f16be29d4d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 23 Jun 2012 19:23:31 +0200 Subject: [PATCH 2771/6849] ath9k: fix dynamic WEP related regression commit 7a532fe7131216a02c81a6c1b1f8632da1195a58 ath9k_hw: fix interpretation of the rx KeyMiss flag This commit used the rx key miss indication to detect packets that were passed from the hardware without being decrypted, however it seems that this bit is not only undefined in the static WEP case, but also for dynamically allocated WEP keys. This caused a regression when using WEP-LEAP. This patch fixes the regression by keeping track of which key indexes refer to CCMP keys and only using the key miss indication for those. Reported-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/ath9k/recv.c | 3 ++- drivers/net/wireless/ath/key.c | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index c54b7d37bff1..420d69b2674c 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -143,6 +143,7 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); + DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX); enum ath_crypt_caps crypt_caps; unsigned int clockrate; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index e1fcc68124dc..599667ababee 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -822,7 +822,8 @@ static bool ath9k_rx_accept(struct ath_common *common, * descriptor does contain a valid key index. This has been observed * mostly with CCMP encryption. */ - if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID) + if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || + !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; if (!rx_stats->rs_datalen) { diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 0e81904956cf..5c54aa43ca2d 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -556,6 +556,9 @@ int ath_key_config(struct ath_common *common, return -EIO; set_bit(idx, common->keymap); + if (key->cipher == WLAN_CIPHER_SUITE_CCMP) + set_bit(idx, common->ccmp_keymap); + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); @@ -582,6 +585,7 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) return; clear_bit(key->hw_key_idx, common->keymap); + clear_bit(key->hw_key_idx, common->ccmp_keymap); if (key->cipher != WLAN_CIPHER_SUITE_TKIP) return; -- GitLab From ff0b804632f025b072f81fc0cd585102b0a43534 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 24 Jun 2012 19:17:00 -0700 Subject: [PATCH 2772/6849] wlcore: drop INET dependency Mainline build reports: warning: (WL12XX) selects WLCORE which has unmet direct dependencies (NETDEVICES && WLAN && WL_TI && GENERIC_HARDIRQS && MAC80211 && INET) The INET dependency was added in commit 3c6af5b54fe74b6e56efadc22927e4055d00e9fc: wl1271_main.c:(.text+0x271052): undefined reference to `unregister_inetaddr_ notifier' wl1271_main.c:(.text+0x2714d7): undefined reference to `register_inetaddr_no tifier' Driver is doing some filtering based on IP addresses... but this driver no longer has that code and it builds fine even when CONFIG_INET is not enabled, so drop that dependency and eliminate the kconfig warning message. Signed-off-by: Randy Dunlap Cc: Luciano Coelho Cc: John W. Linville Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wlcore/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig index 54156b0b5c2d..d7b907e67170 100644 --- a/drivers/net/wireless/ti/wlcore/Kconfig +++ b/drivers/net/wireless/ti/wlcore/Kconfig @@ -1,7 +1,6 @@ config WLCORE tristate "TI wlcore support" depends on WL_TI && GENERIC_HARDIRQS && MAC80211 - depends on INET select FW_LOADER ---help--- This module contains the main code for TI WLAN chips. It abstracts -- GitLab From eac9ac6d1f5d0e9d33e4ded682187b630e7606cd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Jun 2012 09:36:41 +0200 Subject: [PATCH 2773/6849] iwlwifi: fix activating inactive stations When authentication/association timed out, the driver would complain bitterly, printing the message ACTIVATE a non DRIVER active station id ... addr ... The cause turns out to be that when the AP station is added but we don't associate, the IWL_STA_UCODE_INPROGRESS is set but never cleared. This then causes iwl_restore_stations() to attempt to resend it because it uses the flag internally and uploads even if it didn't set it itself. To fix this issue and not upload the station again when it has already been removed by mac80211, clear the flag after adding it in case we add it only for association. Cc: stable@vger.kernel.org Reviewed-by: Meenakshi Venkataraman Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 3ee23134c02b..013680332f07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -796,6 +796,18 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, switch (op) { case ADD: ret = iwlagn_mac_sta_add(hw, vif, sta); + if (ret) + break; + /* + * Clear the in-progress flag, the AP station entry was added + * but we'll initialize LQ only when we've associated (which + * would also clear the in-progress flag). This is necessary + * in case we never initialize LQ because association fails. + */ + spin_lock_bh(&priv->sta_lock); + priv->stations[iwl_sta_id(sta)].used &= + ~IWL_STA_UCODE_INPROGRESS; + spin_unlock_bh(&priv->sta_lock); break; case REMOVE: ret = iwlagn_mac_sta_remove(hw, vif, sta); -- GitLab From befae82e2906cb7155020876a531b0b8c6c8d8c8 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 25 Jun 2012 19:49:28 +0200 Subject: [PATCH 2774/6849] ALSA: hda - Add Realtek ALC280 codec support This chip looks very similar to ALC269 and ALC27* variants. The bug reporter has verified that sound was working after this patch had been applied. Cc: stable@kernel.org BugLink: https://bugs.launchpad.net/bugs/1017017 Tested-by: Richard Crossley Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 41475ae0e769..a5534b384609 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6800,6 +6800,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, + { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, -- GitLab From b41772abebc27c61dd578b76da99aa5240b4c99a Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 21 Jun 2012 20:50:42 -0700 Subject: [PATCH 2775/6849] rcu: Stop rcu_do_batch() from multiplexing the "count" variable Commit b1420f1c (Make rcu_barrier() less disruptive) rearranged the code in rcu_do_batch(), moving the ->qlen manipulation to follow the requeueing of the callbacks. Unfortunately, this rearrangement clobbered the value of the "count" local variable before the value of rdp->qlen was adjusted, resulting in the value of rdp->qlen being inaccurate. This commit therefore introduces an index variable "i", avoiding the inadvertent multiplexing. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney Reviewed-by: Josh Triplett --- kernel/rcutree.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 3b0f1337f75b..38ecdda3f55f 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1530,7 +1530,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) { unsigned long flags; struct rcu_head *next, *list, **tail; - int bl, count, count_lazy; + int bl, count, count_lazy, i; /* If no callbacks are ready, just return.*/ if (!cpu_has_callbacks_ready_to_invoke(rdp)) { @@ -1553,9 +1553,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL]; *rdp->nxttail[RCU_DONE_TAIL] = NULL; tail = rdp->nxttail[RCU_DONE_TAIL]; - for (count = RCU_NEXT_SIZE - 1; count >= 0; count--) - if (rdp->nxttail[count] == rdp->nxttail[RCU_DONE_TAIL]) - rdp->nxttail[count] = &rdp->nxtlist; + for (i = RCU_NEXT_SIZE - 1; i >= 0; i--) + if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL]) + rdp->nxttail[i] = &rdp->nxtlist; local_irq_restore(flags); /* Invoke callbacks. */ @@ -1583,9 +1583,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) if (list != NULL) { *tail = rdp->nxtlist; rdp->nxtlist = list; - for (count = 0; count < RCU_NEXT_SIZE; count++) - if (&rdp->nxtlist == rdp->nxttail[count]) - rdp->nxttail[count] = tail; + for (i = 0; i < RCU_NEXT_SIZE; i++) + if (&rdp->nxtlist == rdp->nxttail[i]) + rdp->nxttail[i] = tail; else break; } -- GitLab From d8140b2fa09cceb947ac1ac49e0958eb137d0648 Mon Sep 17 00:00:00 2001 From: Santosh Nayak Date: Tue, 19 Jun 2012 21:27:39 +0000 Subject: [PATCH 2776/6849] netxen: Error return off by one in 'netxen_nic_set_pauseparam()'. There are 'NETXEN_NIU_MAX_GBE_PORTS' GBE ports. Port indexing starts from zero. Hence we should also return error for "port == NETXEN_NIU_MAX_GBE_PORTS" Signed-off-by: Santosh Nayak --- drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 39730403782f..d4f179f96dcb 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -489,7 +489,7 @@ netxen_nic_get_pauseparam(struct net_device *dev, int port = adapter->physical_port; if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS)) return; /* get flow control settings */ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); @@ -534,7 +534,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, int port = adapter->physical_port; /* read mode */ if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS)) return -EIO; /* set flow control */ val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); -- GitLab From ed3b856b69a7f3748d6917e42d462c962aaa39b8 Mon Sep 17 00:00:00 2001 From: Santosh Nayak Date: Wed, 20 Jun 2012 00:52:58 +0000 Subject: [PATCH 2777/6849] netxen: Error return off by one for XG port. There are NETXEN_NIU_MAX_XG_PORTS ports. Port indexing starts from zero. Hence we should also return error for 'port == NETXEN_NIU_MAX_XG_PORTS'. Signed-off-by: Santosh Nayak --- drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 4 ++-- drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index d4f179f96dcb..9103e3e36c28 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -511,7 +511,7 @@ netxen_nic_get_pauseparam(struct net_device *dev, break; } } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { - if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) + if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS)) return; pause->rx_pause = 1; val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL); @@ -577,7 +577,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, } NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { - if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) + if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS)) return -EIO; val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL); if (port == 0) { diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index de96a948bb7f..946160fa5843 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -365,7 +365,7 @@ static int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) return 0; - if (port > NETXEN_NIU_MAX_XG_PORTS) + if (port >= NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; mac_cfg = 0; @@ -392,7 +392,7 @@ static int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) u32 port = adapter->physical_port; u16 board_type = adapter->ahw.board_type; - if (port > NETXEN_NIU_MAX_XG_PORTS) + if (port >= NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port)); -- GitLab From fa809e2fd6e317226c046202a88520962672eac0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 25 Jun 2012 15:37:19 -0700 Subject: [PATCH 2778/6849] ipv6: fib: fix fib dump restart Commit 2bec5a369ee79576a3 (ipv6: fib: fix crash when changing large fib while dumping it) introduced ability to restart the dump at tree root, but failed to skip correctly a count of already dumped entries. Code didn't match Patrick intent. We must skip exactly the number of already dumped entries. Note that like other /proc/net files or netlink producers, we could still dump some duplicates entries. Reported-by: Debabrata Banerjee Reported-by: Josh Hunt Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/ip6_fib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 74c21b924a79..608327661960 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1349,8 +1349,8 @@ static int fib6_walk_continue(struct fib6_walker_t *w) if (w->leaf && fn->fn_flags & RTN_RTINFO) { int err; - if (w->count < w->skip) { - w->count++; + if (w->skip) { + w->skip--; continue; } -- GitLab From 437c5b53f63b468996090200df66ef2f3f588c80 Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Sat, 23 Jun 2012 19:22:00 +0000 Subject: [PATCH 2779/6849] tcp: heed result of security_inet_conn_request() in tcp_v6_conn_request() If security_inet_conn_request() returns non-zero then TCP/IPv6 should drop the request, just as in TCP/IPv4 and DCCP in both IPv4 and IPv6. Signed-off-by: Neal Cardwell Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3a9aec29581a..9df64a50b075 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1212,7 +1212,8 @@ have_isn: tcp_rsk(req)->snt_isn = isn; tcp_rsk(req)->snt_synack = tcp_time_stamp; - security_inet_conn_request(sk, skb, req); + if (security_inet_conn_request(sk, skb, req)) + goto drop_and_release; if (tcp_v6_send_synack(sk, req, (struct request_values *)&tmp_ext, -- GitLab From eaa8c5f3cf6555294632c176e81439ca420ad07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 24 Jun 2012 11:01:36 +0000 Subject: [PATCH 2780/6849] caif: Clear shutdown mask to zero at reconnect. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clear caif sockets's shutdown mask at (re)connect. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/caif_socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index fb8944355264..78f1cdad5b33 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -220,6 +220,7 @@ static void caif_ctrl_cb(struct cflayer *layr, cfsk_hold, cfsk_put); cf_sk->sk.sk_state = CAIF_CONNECTED; set_tx_flow_on(cf_sk); + cf_sk->sk.sk_shutdown = 0; cf_sk->sk.sk_state_change(&cf_sk->sk); break; -- GitLab From 3935600a7f341c00b0def2ed8870669ab2c05493 Mon Sep 17 00:00:00 2001 From: Per Ellefsen Date: Sun, 24 Jun 2012 11:01:37 +0000 Subject: [PATCH 2781/6849] caif-hsi: Bugfix - Piggyback'ed embedded CAIF frame lost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When receiving a piggyback'ed descriptor containing an embedded frame, but no payload, the embedded frame was lost. Signed-off-by: Per Ellefsen Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 1520814c77c7..1f52ff3076b4 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -693,8 +693,6 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) */ memcpy(rx_buf, (u8 *)piggy_desc, CFHSI_DESC_SHORT_SZ); - /* Mark no embedded frame here */ - piggy_desc->offset = 0; if (desc_pld_len == -EPROTO) goto out_of_sync; } @@ -737,6 +735,8 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) /* Extract any payload in piggyback descriptor. */ if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0) goto out_of_sync; + /* Mark no embedded frame after extracting it */ + piggy_desc->offset = 0; } } -- GitLab From 1fdc7630b2cba4a5aeb5fc3834c7189716fdbcb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 24 Jun 2012 11:01:38 +0000 Subject: [PATCH 2782/6849] caif-hsi: Add missing return in error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a missing return, causing access to freed memory. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 1f52ff3076b4..4a27adb7ae67 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -1178,6 +1178,7 @@ int cfhsi_probe(struct platform_device *pdev) dev_err(&ndev->dev, "%s: Registration error: %d.\n", __func__, res); free_netdev(ndev); + return -ENODEV; } /* Add CAIF HSI device to list. */ spin_lock(&cfhsi_list_lock); -- GitLab From efc27f8ceebe5eb147fa31d6c995706d327ad855 Mon Sep 17 00:00:00 2001 From: Vijay Subramanian Date: Sun, 24 Jun 2012 13:03:07 +0000 Subject: [PATCH 2783/6849] net: Remove 'unlikely' qualifier in skb_steal_sock() With early demux enabled by default for TCP flows, there is high chance that skb->sk will be non-null. 'unlikely()' was removed from __inet_lookup_skb() but maybe it can be removed from skb_steal_sock() as well. Note: skb_steal_sock() is also called by __inet6_lookup_skb() and __udp4_lib_lookup_skb() but they are protected by their own 'unlikely' calls. Signed-off-by: Vijay Subramanian Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/sock.h b/include/net/sock.h index 87b424ae750a..21086036e348 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2154,7 +2154,7 @@ static inline void sk_change_net(struct sock *sk, struct net *net) static inline struct sock *skb_steal_sock(struct sk_buff *skb) { - if (unlikely(skb->sk)) { + if (skb->sk) { struct sock *sk = skb->sk; skb->destructor = NULL; -- GitLab From deaa58542b21d2b395db816952c202034319cbb4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 24 Jun 2012 20:22:49 +0000 Subject: [PATCH 2784/6849] net: struct sock cleanups Add missing kernel doc for sk_rx_dst Move sk_rx_dst to avoid two 32bit holes on 64bit arches Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/net/sock.h b/include/net/sock.h index 21086036e348..dcb54a0793ec 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -198,6 +198,7 @@ struct cg_proto; * @sk_lock: synchronizer * @sk_rcvbuf: size of receive buffer in bytes * @sk_wq: sock wait queue and async head + * @sk_rx_dst: receive input route used by early tcp demux * @sk_dst_cache: destination cache * @sk_dst_lock: destination cache lock * @sk_policy: flow policy @@ -317,9 +318,9 @@ struct sock { struct xfrm_policy *sk_policy[2]; #endif unsigned long sk_flags; + struct dst_entry *sk_rx_dst; struct dst_entry *sk_dst_cache; spinlock_t sk_dst_lock; - struct dst_entry *sk_rx_dst; atomic_t sk_wmem_alloc; atomic_t sk_omem_alloc; int sk_sndbuf; -- GitLab From 89b1f496d2b659eaaac5a8d80b801661ab03854f Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Sun, 24 Jun 2012 19:40:55 +0000 Subject: [PATCH 2785/6849] be2net: Explicitly clear the reserved field in the Tx Descriptor Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index cbd245afd8ab..c60782e299db 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -558,6 +558,7 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) wrb->frag_pa_hi = upper_32_bits(addr); wrb->frag_pa_lo = addr & 0xFFFFFFFF; wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; + wrb->rsvd0 = 0; } static inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter, -- GitLab From 7665de15642dfb1709177517aa0488162727342c Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Sun, 24 Jun 2012 19:42:00 +0000 Subject: [PATCH 2786/6849] be2net: Regression bug wherein VFs creation broken for multiple cards. Fix be_find_vfs() to check for matching bus number as well along with devfn Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index c60782e299db..a28896d4411d 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1059,7 +1059,8 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state) dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL); while (dev) { vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF; - if (dev->is_virtfn && dev->devfn == vf_fn) { + if (dev->is_virtfn && dev->devfn == vf_fn && + dev->bus->number == pdev->bus->number) { vfs++; if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) assigned_vfs++; -- GitLab From 6de0298ec9c1edaf330b71b57346241ece8f3346 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Mon, 25 Jun 2012 09:04:47 +0200 Subject: [PATCH 2787/6849] ipheth: add support for iPad This adds support for the iPad to the ipheth driver. (product id = 0x129a) Signed-off-by: Davide Gerhard Signed-off-by: David S. Miller --- drivers/net/usb/ipheth.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 964031e3da87..a28a983d465e 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -59,6 +59,7 @@ #define USB_PRODUCT_IPHONE_3G 0x1292 #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 +#define USB_PRODUCT_IPAD 0x129a #define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4S 0x12a0 @@ -100,6 +101,10 @@ static struct usb_device_id ipheth_table[] = { USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPAD, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, { USB_DEVICE_AND_INTERFACE_INFO( USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, -- GitLab From 5c8e9046662889265c0ff390c144188721cb0844 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Mon, 25 Jun 2012 00:24:11 +0000 Subject: [PATCH 2788/6849] net/mlx4_en: Set correct port parameters during device initialization Set valid port parameters: MTU and flow control configuration when configuring the port during HW device initialization, prior to the net device open() being called. Using invalid parameters (such as all zeros) could lead to bad firmware behavior. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 926d8aac941c..a80280eee06e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1204,9 +1204,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num); /* Configure port */ + mlx4_en_calc_rx_buf(dev); err = mlx4_SET_PORT_general(mdev->dev, priv->port, - MLX4_EN_MIN_MTU, - 0, 0, 0, 0); + priv->rx_skb_size + ETH_FCS_LEN, + prof->tx_pause, prof->tx_ppp, + prof->rx_pause, prof->rx_ppp); if (err) { en_err(priv, "Failed setting port general configurations " "for port %d, with error %d\n", priv->port, err); -- GitLab From 9858d2d1acf82758f779e0756d92a011f1d170b3 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Mon, 25 Jun 2012 00:24:12 +0000 Subject: [PATCH 2789/6849] net/mlx4: Use single completion vector after NOP failure Fix a crash at the error flow of NOP command which caused the driver to try and use a completion vector which wasn't allocated. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index ee6f4fe00837..a0313de122de 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1975,6 +1975,8 @@ slave_start: if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) && !mlx4_is_mfunc(dev)) { dev->flags &= ~MLX4_FLAG_MSI_X; + dev->caps.num_comp_vectors = 1; + dev->caps.comp_pool = 0; pci_disable_msix(pdev); err = mlx4_setup_hca(dev); } -- GitLab From 044ca2a5f2f781c7e4b49c7c0a256913648297ea Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Mon, 25 Jun 2012 00:24:13 +0000 Subject: [PATCH 2790/6849] net/mlx4_en: Release QP range in free_resources Add a missing resource release in ring cleanup. Not doing this leaves a range of QPs that are being reserved, and no one can use them. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 12 ++++++++---- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index a80280eee06e..073b85b45fc5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -929,15 +929,20 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv) if (priv->rx_cq[i].buf) mlx4_en_destroy_cq(priv, &priv->rx_cq[i]); } + + if (priv->base_tx_qpn) { + mlx4_qp_release_range(priv->mdev->dev, priv->base_tx_qpn, priv->tx_ring_num); + priv->base_tx_qpn = 0; + } } int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) { struct mlx4_en_port_profile *prof = priv->prof; int i; - int base_tx_qpn, err; + int err; - err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &base_tx_qpn); + err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &priv->base_tx_qpn); if (err) { en_err(priv, "failed reserving range for TX rings\n"); return err; @@ -949,7 +954,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) prof->tx_ring_size, i, TX)) goto err; - if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], base_tx_qpn + i, + if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], priv->base_tx_qpn + i, prof->tx_ring_size, TXBB_SIZE)) goto err; } @@ -969,7 +974,6 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) err: en_err(priv, "Failed to allocate NIC resources\n"); - mlx4_qp_release_range(priv->mdev->dev, base_tx_qpn, priv->tx_ring_num); return -ENOMEM; } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 6ae350921b1a..225c20d47900 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -495,6 +495,7 @@ struct mlx4_en_priv { int vids[128]; bool wol; struct device *ddev; + int base_tx_qpn; #ifdef CONFIG_MLX4_EN_DCB struct ieee_ets ets; -- GitLab From aa214de0595eecf5079a172a16333fa638b64915 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 25 Jun 2012 00:45:14 +0000 Subject: [PATCH 2791/6849] net: l2tp_eth: fix l2tp_eth_dev_xmit race Its illegal to dereference skb after giving it to l2tp_xmit_skb() as it might be already freed/reused. Signed-off-by: Eric Dumazet Cc: James Chapman Signed-off-by: David S. Miller --- net/l2tp/l2tp_eth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 185f12f4a5fa..c3738f49646a 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -88,12 +88,12 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) struct l2tp_eth *priv = netdev_priv(dev); struct l2tp_session *session = priv->session; - l2tp_xmit_skb(session, skb, session->hdr_len); - dev->stats.tx_bytes += skb->len; dev->stats.tx_packets++; - return 0; + l2tp_xmit_skb(session, skb, session->hdr_len); + + return NETDEV_TX_OK; } static struct net_device_ops l2tp_eth_netdev_ops = { -- GitLab From 03e934f620101ca2cfc9383bd76172dd3e1f8567 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Jun 2012 00:47:58 +0200 Subject: [PATCH 2792/6849] NFC: Return from rawsock_release when sk is NULL Sasha Levin reported following panic : [ 2136.383310] BUG: unable to handle kernel NULL pointer dereference at 00000000000003b0 [ 2136.384022] IP: [] __lock_acquire+0xc0/0x4b0 [ 2136.384022] PGD 131c4067 PUD 11c0c067 PMD 0 [ 2136.388106] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC [ 2136.388106] CPU 1 [ 2136.388106] Pid: 24855, comm: trinity-child1 Tainted: G W 3.5.0-rc2-sasha-00015-g7b268f7 #374 [ 2136.388106] RIP: 0010:[] [] __lock_acquire+0xc0/0x4b0 [ 2136.388106] RSP: 0018:ffff8800130b3ca8 EFLAGS: 00010046 [ 2136.388106] RAX: 0000000000000086 RBX: ffff88001186b000 RCX: 0000000000000000 [ 2136.388106] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 2136.388106] RBP: ffff8800130b3d08 R08: 0000000000000001 R09: 0000000000000000 [ 2136.388106] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000002 [ 2136.388106] R13: 00000000000003b0 R14: 0000000000000000 R15: 0000000000000000 [ 2136.388106] FS: 00007fa5b1bd4700(0000) GS:ffff88001b800000(0000) knlGS:0000000000000000 [ 2136.388106] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2136.388106] CR2: 00000000000003b0 CR3: 0000000011d1f000 CR4: 00000000000406e0 [ 2136.388106] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 2136.388106] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 2136.388106] Process trinity-child1 (pid: 24855, threadinfo ffff8800130b2000, task ffff88001186b000) [ 2136.388106] Stack: [ 2136.388106] ffff8800130b3cd8 ffffffff81121785 ffffffff81236774 000080d000000001 [ 2136.388106] ffff88001b9d6c00 00000000001d6c00 ffffffff130b3d08 ffff88001186b000 [ 2136.388106] 0000000000000000 0000000000000002 0000000000000000 0000000000000000 [ 2136.388106] Call Trace: [ 2136.388106] [] ? sched_clock_local+0x25/0x90 [ 2136.388106] [] ? get_empty_filp+0x74/0x220 [ 2136.388106] [] lock_acquire+0x18a/0x1e0 [ 2136.388106] [] ? rawsock_release+0x4f/0xa0 [ 2136.388106] [] _raw_write_lock_bh+0x40/0x80 [ 2136.388106] [] ? rawsock_release+0x4f/0xa0 [ 2136.388106] [] rawsock_release+0x4f/0xa0 [ 2136.388106] [] sock_release+0x18/0x70 [ 2136.388106] [] sock_close+0x29/0x30 [ 2136.388106] [] __fput+0x11a/0x2c0 [ 2136.388106] [] fput+0x15/0x20 [ 2136.388106] [] sys_accept4+0x1b4/0x200 [ 2136.388106] [] ? _raw_spin_unlock_irq+0x4c/0x80 [ 2136.388106] [] ? _raw_spin_unlock_irq+0x59/0x80 [ 2136.388106] [] ? sysret_check+0x22/0x5d [ 2136.388106] [] sys_accept+0xb/0x10 [ 2136.388106] [] system_call_fastpath+0x16/0x1b [ 2136.388106] Code: ec 04 00 0f 85 ea 03 00 00 be d5 0b 00 00 48 c7 c7 8a c1 40 84 e8 b1 a5 f8 ff 31 c0 e9 d4 03 00 00 66 2e 0f 1f 84 00 00 00 00 00 <49> 81 7d 00 60 73 5e 85 b8 01 00 00 00 44 0f 44 e0 83 fe 01 77 [ 2136.388106] RIP [] __lock_acquire+0xc0/0x4b0 [ 2136.388106] RSP [ 2136.388106] CR2: 00000000000003b0 [ 2136.388106] ---[ end trace 6d450e935ee18982 ]--- [ 2136.388106] Kernel panic - not syncing: Fatal exception in interrupt rawsock_release() should test if sock->sk is NULL before calling sock_orphan()/sock_put() Reported-by: Sasha Levin Tested-by: Sasha Levin Cc: stable@kernel.org Signed-off-by: Eric Dumazet Signed-off-by: Samuel Ortiz --- net/nfc/rawsock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index ec1134c9e07f..8b8a6a2b2bad 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -54,7 +54,10 @@ static int rawsock_release(struct socket *sock) { struct sock *sk = sock->sk; - pr_debug("sock=%p\n", sock); + pr_debug("sock=%p sk=%p\n", sock, sk); + + if (!sk) + return 0; sock_orphan(sk); sock_put(sk); -- GitLab From 8a8e28b8e2c27362f24cf06513c05d5e3a304e03 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 03:30:13 +0000 Subject: [PATCH 2793/6849] mac802154: add missed braces Add missed braces after 'if' operator. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/mac802154/tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8781d8f904d9..434b6873b352 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -83,9 +83,10 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, { struct xmit_work *work; - if (!(priv->phy->channels_supported[page] & (1 << chan))) + if (!(priv->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); return NETDEV_TX_OK; + } if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); -- GitLab From c5d3687f6cfed185c2c0b29a5b33273ebd2c0781 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 03:49:01 +0000 Subject: [PATCH 2794/6849] 6lowpan: read data from skb safely Check if skb buffer can pull requested amount of bytes and return an error in opposite case. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/ieee802154/6lowpan.c | 70 ++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 32eb4179e8fa..5c7bcf9663d3 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -291,25 +291,26 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) *hc06_ptr += 2; } -static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) +static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) { - u8 ret; + if (unlikely(!pskb_may_pull(skb, 1))) + return -EINVAL; - ret = skb->data[0]; + *val = skb->data[0]; skb_pull(skb, 1); - return ret; + return 0; } -static u16 lowpan_fetch_skb_u16(struct sk_buff *skb) +static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) { - u16 ret; - - BUG_ON(!pskb_may_pull(skb, 2)); + if (unlikely(!pskb_may_pull(skb, 2))) + return -EINVAL; - ret = skb->data[0] | (skb->data[1] << 8); + *val = skb->data[0] | (skb->data[1] << 8); skb_pull(skb, 2); - return ret; + + return 0; } static int @@ -318,7 +319,8 @@ lowpan_uncompress_udp_header(struct sk_buff *skb) struct udphdr *uh = udp_hdr(skb); u8 tmp; - tmp = lowpan_fetch_skb_u8(skb); + if (lowpan_fetch_skb_u8(skb, &tmp)) + goto err; if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { pr_debug("(%s): UDP header uncompression\n", __func__); @@ -710,7 +712,9 @@ lowpan_process_data(struct sk_buff *skb) /* at least two bytes will be used for the encoding */ if (skb->len < 2) goto drop; - iphc0 = lowpan_fetch_skb_u8(skb); + + if (lowpan_fetch_skb_u8(skb, &iphc0)) + goto drop; /* fragments assembling */ switch (iphc0 & LOWPAN_DISPATCH_MASK) { @@ -722,8 +726,9 @@ lowpan_process_data(struct sk_buff *skb) u16 tag; bool found = false; - len = lowpan_fetch_skb_u8(skb); /* frame length */ - tag = lowpan_fetch_skb_u16(skb); + if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */ + lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ + goto drop; /* * check if frame assembling with the same tag is @@ -747,7 +752,8 @@ lowpan_process_data(struct sk_buff *skb) if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) goto unlock_and_drop; - offset = lowpan_fetch_skb_u8(skb); /* fetch offset */ + if (lowpan_fetch_skb_u8(skb, &offset)) /* fetch offset */ + goto unlock_and_drop; /* if payload fits buffer, copy it */ if (likely((offset * 8 + skb->len) <= frame->length)) @@ -769,7 +775,10 @@ lowpan_process_data(struct sk_buff *skb) dev_kfree_skb(skb); skb = frame->skb; kfree(frame); - iphc0 = lowpan_fetch_skb_u8(skb); + + if (lowpan_fetch_skb_u8(skb, &iphc0)) + goto unlock_and_drop; + break; } spin_unlock(&flist_lock); @@ -780,7 +789,8 @@ lowpan_process_data(struct sk_buff *skb) break; } - iphc1 = lowpan_fetch_skb_u8(skb); + if (lowpan_fetch_skb_u8(skb, &iphc1)) + goto drop; _saddr = mac_cb(skb)->sa.hwaddr; _daddr = mac_cb(skb)->da.hwaddr; @@ -791,9 +801,8 @@ lowpan_process_data(struct sk_buff *skb) if (iphc1 & LOWPAN_IPHC_CID) { pr_debug("(%s): CID flag is set, increase header with one\n", __func__); - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &num_context)) goto drop; - num_context = lowpan_fetch_skb_u8(skb); } hdr.version = 6; @@ -805,9 +814,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) */ case 0: /* 00b */ - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; - tmp = lowpan_fetch_skb_u8(skb); + memcpy(&hdr.flow_lbl, &skb->data[0], 3); skb_pull(skb, 3); hdr.priority = ((tmp >> 2) & 0x0f); @@ -819,9 +828,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + DSCP (1 byte), Flow Label is elided */ case 1: /* 10b */ - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; - tmp = lowpan_fetch_skb_u8(skb); + hdr.priority = ((tmp >> 2) & 0x0f); hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); hdr.flow_lbl[1] = 0; @@ -832,9 +841,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */ case 2: /* 01b */ - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; - tmp = lowpan_fetch_skb_u8(skb); + hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); skb_pull(skb, 2); @@ -853,9 +862,9 @@ lowpan_process_data(struct sk_buff *skb) /* Next Header */ if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr))) goto drop; - hdr.nexthdr = lowpan_fetch_skb_u8(skb); + pr_debug("(%s): NH flag is set, next header is carried " "inline: %02x\n", __func__, hdr.nexthdr); } @@ -864,9 +873,8 @@ lowpan_process_data(struct sk_buff *skb) if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I) hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03]; else { - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit))) goto drop; - hdr.hop_limit = lowpan_fetch_skb_u8(skb); } /* Extract SAM to the tmp variable */ @@ -894,10 +902,8 @@ lowpan_process_data(struct sk_buff *skb) pr_debug("(%s): destination address non-context-based" " multicast compression\n", __func__); if (0 < tmp && tmp < 3) { - if (!skb->len) + if (lowpan_fetch_skb_u8(skb, &prefix[1])) goto drop; - else - prefix[1] = lowpan_fetch_skb_u8(skb); } err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, -- GitLab From 5c00c0cba5d4e5371492dda8d642dd4d5788e905 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 03:49:02 +0000 Subject: [PATCH 2795/6849] 6lowpan: fix hop limit compression Add missing pointer shift for the 'default' case. Signed-off-by: Alexander Smirnov Cc: Tony Cheneau Signed-off-by: David S. Miller --- net/ieee802154/6lowpan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 5c7bcf9663d3..b45e229bc42c 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -492,6 +492,7 @@ static int lowpan_header_create(struct sk_buff *skb, break; default: *hc06_ptr = hdr->hop_limit; + hc06_ptr += 1; break; } -- GitLab From e71094f989a48ba776ec117958481682c232ba0b Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 03:49:03 +0000 Subject: [PATCH 2796/6849] 6lowpan: remove excessive argument in pr_debug Remove excessive __func__ argument in pr_debug function and some excessive debug messages. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/ieee802154/6lowpan.c | 94 ++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 57 deletions(-) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index b45e229bc42c..ad0c2264e537 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -240,8 +240,7 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr); } - pr_debug("(%s): uncompressing %d + %d => ", __func__, prefcount, - postcount); + pr_debug("uncompressing %d + %d => ", prefcount, postcount); lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16); return 0; @@ -252,13 +251,11 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) { struct udphdr *uh = udp_hdr(skb); - pr_debug("(%s): UDP header compression\n", __func__); - if (((uh->source & LOWPAN_NHC_UDP_4BIT_MASK) == LOWPAN_NHC_UDP_4BIT_PORT) && ((uh->dest & LOWPAN_NHC_UDP_4BIT_MASK) == LOWPAN_NHC_UDP_4BIT_PORT)) { - pr_debug("(%s): both ports compression to 4 bits\n", __func__); + pr_debug("UDP header: both ports compression to 4 bits\n"); **hc06_ptr = LOWPAN_NHC_UDP_CS_P_11; **(hc06_ptr + 1) = /* subtraction is faster */ (u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) + @@ -266,20 +263,20 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) *hc06_ptr += 2; } else if ((uh->dest & LOWPAN_NHC_UDP_8BIT_MASK) == LOWPAN_NHC_UDP_8BIT_PORT) { - pr_debug("(%s): remove 8 bits of dest\n", __func__); + pr_debug("UDP header: remove 8 bits of dest\n"); **hc06_ptr = LOWPAN_NHC_UDP_CS_P_01; memcpy(*hc06_ptr + 1, &uh->source, 2); **(hc06_ptr + 3) = (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT); *hc06_ptr += 4; } else if ((uh->source & LOWPAN_NHC_UDP_8BIT_MASK) == LOWPAN_NHC_UDP_8BIT_PORT) { - pr_debug("(%s): remove 8 bits of source\n", __func__); + pr_debug("UDP header: remove 8 bits of source\n"); **hc06_ptr = LOWPAN_NHC_UDP_CS_P_10; memcpy(*hc06_ptr + 1, &uh->dest, 2); **(hc06_ptr + 3) = (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT); *hc06_ptr += 4; } else { - pr_debug("(%s): can't compress header\n", __func__); + pr_debug("UDP header: can't compress\n"); **hc06_ptr = LOWPAN_NHC_UDP_CS_P_00; memcpy(*hc06_ptr + 1, &uh->source, 2); memcpy(*hc06_ptr + 3, &uh->dest, 2); @@ -323,7 +320,7 @@ lowpan_uncompress_udp_header(struct sk_buff *skb) goto err; if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { - pr_debug("(%s): UDP header uncompression\n", __func__); + pr_debug("UDP header uncompression\n"); switch (tmp & LOWPAN_NHC_UDP_CS_P_11) { case LOWPAN_NHC_UDP_CS_P_00: memcpy(&uh->source, &skb->data[0], 2); @@ -349,19 +346,19 @@ lowpan_uncompress_udp_header(struct sk_buff *skb) skb_pull(skb, 1); break; default: - pr_debug("(%s) ERROR: unknown UDP format\n", __func__); + pr_debug("ERROR: unknown UDP format\n"); goto err; break; } - pr_debug("(%s): uncompressed UDP ports: src = %d, dst = %d\n", - __func__, uh->source, uh->dest); + pr_debug("uncompressed UDP ports: src = %d, dst = %d\n", + uh->source, uh->dest); /* copy checksum */ memcpy(&uh->check, &skb->data[0], 2); skb_pull(skb, 2); } else { - pr_debug("(%s): ERROR: unsupported NH format\n", __func__); + pr_debug("ERROR: unsupported NH format\n"); goto err; } @@ -394,10 +391,9 @@ static int lowpan_header_create(struct sk_buff *skb, hdr = ipv6_hdr(skb); hc06_ptr = head + 2; - pr_debug("(%s): IPv6 header dump:\n\tversion = %d\n\tlength = %d\n" - "\tnexthdr = 0x%02x\n\thop_lim = %d\n", __func__, - hdr->version, ntohs(hdr->payload_len), hdr->nexthdr, - hdr->hop_limit); + pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n" + "\tnexthdr = 0x%02x\n\thop_lim = %d\n", hdr->version, + ntohs(hdr->payload_len), hdr->nexthdr, hdr->hop_limit); lowpan_raw_dump_table(__func__, "raw skb network header dump", skb_network_header(skb), sizeof(struct ipv6hdr)); @@ -498,23 +494,22 @@ static int lowpan_header_create(struct sk_buff *skb, /* source address compression */ if (is_addr_unspecified(&hdr->saddr)) { - pr_debug("(%s): source address is unspecified, setting SAC\n", - __func__); + pr_debug("source address is unspecified, setting SAC\n"); iphc1 |= LOWPAN_IPHC_SAC; /* TODO: context lookup */ } else if (is_addr_link_local(&hdr->saddr)) { - pr_debug("(%s): source address is link-local\n", __func__); + pr_debug("source address is link-local\n"); iphc1 |= lowpan_compress_addr_64(&hc06_ptr, LOWPAN_IPHC_SAM_BIT, &hdr->saddr, saddr); } else { - pr_debug("(%s): send the full source address\n", __func__); + pr_debug("send the full source address\n"); memcpy(hc06_ptr, &hdr->saddr.s6_addr16[0], 16); hc06_ptr += 16; } /* destination address compression */ if (is_addr_mcast(&hdr->daddr)) { - pr_debug("(%s): destination address is multicast", __func__); + pr_debug("destination address is multicast: "); iphc1 |= LOWPAN_IPHC_M; if (lowpan_is_mcast_addr_compressable8(&hdr->daddr)) { pr_debug("compressed to 1 octet\n"); @@ -543,14 +538,13 @@ static int lowpan_header_create(struct sk_buff *skb, hc06_ptr += 16; } } else { - pr_debug("(%s): destination address is unicast: ", __func__); /* TODO: context lookup */ if (is_addr_link_local(&hdr->daddr)) { - pr_debug("destination address is link-local\n"); + pr_debug("dest address is unicast and link-local\n"); iphc1 |= lowpan_compress_addr_64(&hc06_ptr, LOWPAN_IPHC_DAM_BIT, &hdr->daddr, daddr); } else { - pr_debug("using full address\n"); + pr_debug("dest address is unicast: using full one\n"); memcpy(hc06_ptr, &hdr->daddr.s6_addr16[0], 16); hc06_ptr += 16; } @@ -642,8 +636,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr) { struct lowpan_fragment *entry = (struct lowpan_fragment *)entry_addr; - pr_debug("%s: timer expired for frame with tag %d\n", __func__, - entry->tag); + pr_debug("timer expired for frame with tag %d\n", entry->tag); spin_lock(&flist_lock); list_del(&entry->list); @@ -796,12 +789,11 @@ lowpan_process_data(struct sk_buff *skb) _saddr = mac_cb(skb)->sa.hwaddr; _daddr = mac_cb(skb)->da.hwaddr; - pr_debug("(%s): iphc0 = %02x, iphc1 = %02x\n", __func__, iphc0, iphc1); + pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); /* another if the CID flag is set */ if (iphc1 & LOWPAN_IPHC_CID) { - pr_debug("(%s): CID flag is set, increase header with one\n", - __func__); + pr_debug("CID flag is set, increase header with one\n"); if (lowpan_fetch_skb_u8(skb, &num_context)) goto drop; } @@ -866,8 +858,8 @@ lowpan_process_data(struct sk_buff *skb) if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr))) goto drop; - pr_debug("(%s): NH flag is set, next header is carried " - "inline: %02x\n", __func__, hdr.nexthdr); + pr_debug("NH flag is set, next header carried inline: %02x\n", + hdr.nexthdr); } /* Hop Limit */ @@ -882,7 +874,7 @@ lowpan_process_data(struct sk_buff *skb) tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; /* Source address uncompression */ - pr_debug("(%s): source address stateless compression\n", __func__); + pr_debug("source address stateless compression\n"); err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, lowpan_unc_llconf[tmp], skb->data); if (err) @@ -894,14 +886,12 @@ lowpan_process_data(struct sk_buff *skb) /* check for Multicast Compression */ if (iphc1 & LOWPAN_IPHC_M) { if (iphc1 & LOWPAN_IPHC_DAC) { - pr_debug("(%s): destination address context-based " - "multicast compression\n", __func__); + pr_debug("dest: context-based mcast compression\n"); /* TODO: implement this */ } else { u8 prefix[] = {0xff, 0x02}; - pr_debug("(%s): destination address non-context-based" - " multicast compression\n", __func__); + pr_debug("dest: non context-based mcast compression\n"); if (0 < tmp && tmp < 3) { if (lowpan_fetch_skb_u8(skb, &prefix[1])) goto drop; @@ -913,8 +903,7 @@ lowpan_process_data(struct sk_buff *skb) goto drop; } } else { - pr_debug("(%s): destination address stateless compression\n", - __func__); + pr_debug("dest: stateless compression\n"); err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix, lowpan_unc_llconf[tmp], skb->data); if (err) @@ -929,11 +918,11 @@ lowpan_process_data(struct sk_buff *skb) /* Not fragmented package */ hdr.payload_len = htons(skb->len); - pr_debug("(%s): skb headroom size = %d, data length = %d\n", __func__, - skb_headroom(skb), skb->len); + pr_debug("skb headroom size = %d, data length = %d\n", + skb_headroom(skb), skb->len); - pr_debug("(%s): IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t" - "nexthdr = 0x%02x\n\thop_lim = %d\n", __func__, hdr.version, + pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t" + "nexthdr = 0x%02x\n\thop_lim = %d\n", hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, hdr.hop_limit); lowpan_raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, @@ -1035,11 +1024,11 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev) { int err = -1; - pr_debug("(%s): package xmit\n", __func__); + pr_debug("package xmit\n"); skb->dev = lowpan_dev_info(dev)->real_dev; if (skb->dev == NULL) { - pr_debug("(%s) ERROR: no real wpan device found\n", __func__); + pr_debug("ERROR: no real wpan device found\n"); goto error; } @@ -1048,14 +1037,13 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev) goto out; } - pr_debug("(%s): frame is too big, fragmentation is needed\n", - __func__); + pr_debug("frame is too big, fragmentation is needed\n"); err = lowpan_skb_fragmentation(skb); error: dev_kfree_skb(skb); out: if (err < 0) - pr_debug("(%s): ERROR: xmit failed\n", __func__); + pr_debug("ERROR: xmit failed\n"); return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK); } @@ -1101,8 +1089,6 @@ static struct ieee802154_mlme_ops lowpan_mlme = { static void lowpan_setup(struct net_device *dev) { - pr_debug("(%s)\n", __func__); - dev->addr_len = IEEE802154_ADDR_LEN; memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); dev->type = ARPHRD_IEEE802154; @@ -1122,8 +1108,6 @@ static void lowpan_setup(struct net_device *dev) static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[]) { - pr_debug("(%s)\n", __func__); - if (tb[IFLA_ADDRESS]) { if (nla_len(tb[IFLA_ADDRESS]) != IEEE802154_ADDR_LEN) return -EINVAL; @@ -1164,7 +1148,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, struct net_device *real_dev; struct lowpan_dev_record *entry; - pr_debug("(%s)\n", __func__); + pr_debug("adding new link\n"); if (!tb[IFLA_LINK]) return -EINVAL; @@ -1259,8 +1243,6 @@ static int __init lowpan_init_module(void) { int err = 0; - pr_debug("(%s)\n", __func__); - err = lowpan_netlink_init(); if (err < 0) goto out; @@ -1272,8 +1254,6 @@ out: static void __exit lowpan_cleanup_module(void) { - pr_debug("(%s)\n", __func__); - lowpan_netlink_fini(); dev_remove_pack(&lowpan_packet_type); -- GitLab From be4852c957b7c1e8eeac8d13c3ef228508c0873a Mon Sep 17 00:00:00 2001 From: Kim Lilliestierna XX Date: Mon, 25 Jun 2012 07:49:33 +0000 Subject: [PATCH 2797/6849] caif: Remove unused pointer and code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed surplus call to caif_device_list() in caif_dev.c Signed-off-by: Kim Lilliestierna Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 554b31289607..e601da7ca2ff 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -90,11 +90,8 @@ static int caifd_refcnt_read(struct caif_device_entry *e) /* Allocate new CAIF device. */ static struct caif_device_entry *caif_device_alloc(struct net_device *dev) { - struct caif_device_entry_list *caifdevs; struct caif_device_entry *caifd; - caifdevs = caif_device_list(dev_net(dev)); - caifd = kzalloc(sizeof(*caifd), GFP_KERNEL); if (!caifd) return NULL; -- GitLab From c95567c8035281d20ca8266cb39f8d48307a70af Mon Sep 17 00:00:00 2001 From: Kim Lilliestierna XX Date: Mon, 25 Jun 2012 07:49:34 +0000 Subject: [PATCH 2798/6849] caif: added check for potential null return MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add check on NULL return from caif_get(). Signed-off-by: Kim Lilliestierna Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index e601da7ca2ff..551d2fd6a80d 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -128,6 +128,11 @@ void caif_flow_cb(struct sk_buff *skb) rcu_read_lock(); caifd = caif_get(skb->dev); + + WARN_ON(caifd == NULL); + if (caifd == NULL) + return; + caifd_hold(caifd); rcu_read_unlock(); -- GitLab From f315fd355ffaec6a9ad541081975ac821404256e Mon Sep 17 00:00:00 2001 From: Kim Lilliestierna XX Date: Mon, 25 Jun 2012 07:49:35 +0000 Subject: [PATCH 2799/6849] caif: Fixed potential memory leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rearranged the allocation and packet creations to avoid potential leaks in error path. Signed-off-by: Kim Lilliestierna Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/cfctrl.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 047cd0eec022..44f270fc2d06 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -175,15 +175,17 @@ static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl) void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) { + struct cfpkt *pkt; struct cfctrl *cfctrl = container_obj(layer); - struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); struct cflayer *dn = cfctrl->serv.layer.dn; - if (!pkt) - return; + if (!dn) { pr_debug("not able to send enum request\n"); return; } + pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); + if (!pkt) + return; caif_assert(offsetof(struct cfctrl, serv.layer) == 0); init_info(cfpkt_info(pkt), cfctrl); cfpkt_info(pkt)->dev_info->id = physlinkid; @@ -302,18 +304,17 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, struct cflayer *client) { int ret; + struct cfpkt *pkt; struct cfctrl *cfctrl = container_obj(layer); - struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); struct cflayer *dn = cfctrl->serv.layer.dn; - if (!pkt) - return -ENOMEM; - if (!dn) { pr_debug("not able to send link-down request\n"); return -ENODEV; } - + pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); + if (!pkt) + return -ENOMEM; cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); cfpkt_addbdy(pkt, channelid); init_info(cfpkt_info(pkt), cfctrl); -- GitLab From 4e7bb59d49fb00d4cf13484386d0400783f2c826 Mon Sep 17 00:00:00 2001 From: Kim Lilliestierna XX Date: Mon, 25 Jun 2012 07:49:36 +0000 Subject: [PATCH 2800/6849] caif-hsi: Removed dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify logic and remove dead code. Signed-off-by: Kim Lilliestierna Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 1520814c77c7..f81f61fb39bc 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -680,12 +680,11 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) if (desc_pld_len < 0) goto out_of_sync; - if (desc_pld_len > 0) + if (desc_pld_len > 0) { rx_len = desc_pld_len; - - if (desc_pld_len > 0 && - (piggy_desc->header & CFHSI_PIGGY_DESC)) - rx_len += CFHSI_DESC_SZ; + if (piggy_desc->header & CFHSI_PIGGY_DESC) + rx_len += CFHSI_DESC_SZ; + } /* * Copy needed information from the piggy-backed @@ -695,8 +694,6 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) CFHSI_DESC_SHORT_SZ); /* Mark no embedded frame here */ piggy_desc->offset = 0; - if (desc_pld_len == -EPROTO) - goto out_of_sync; } } -- GitLab From a5c96b518c373fba35a8dc2e4e5fead24aeefb1c Mon Sep 17 00:00:00 2001 From: Kim Lilliestierna XX Date: Mon, 25 Jun 2012 07:49:37 +0000 Subject: [PATCH 2801/6849] caif-hsi: changed test on aggregation_timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aggregation_timeout is an unsigned long, a test for less than zero can never become true, compare with zero instead. Signed-off-by: Kim Lilliestierna Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index f81f61fb39bc..56cc94120677 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -115,7 +115,7 @@ static bool cfhsi_can_send_aggregate(struct cfhsi *cfhsi) { int i; - if (cfhsi->aggregation_timeout < 0) + if (cfhsi->aggregation_timeout == 0) return true; for (i = 0; i < CFHSI_PRIO_BEBK; ++i) { -- GitLab From 90de9bab9123d7fe905cb885c1e3ed32dc516f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 25 Jun 2012 07:49:38 +0000 Subject: [PATCH 2802/6849] caif-hsi: Use netdev_X instead of dev_X for printing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace dev_X with the corresponding netdev_X print function when applicable. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 94 ++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 56cc94120677..f7997a7b5aed 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -85,7 +85,7 @@ static void cfhsi_inactivity_tout(unsigned long arg) { struct cfhsi *cfhsi = (struct cfhsi *)arg; - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); /* Schedule power down work queue. */ @@ -181,14 +181,14 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi) size_t fifo_occupancy; int ret; - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); do { ret = cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, &fifo_occupancy); if (ret) { - dev_warn(&cfhsi->ndev->dev, + netdev_warn(cfhsi->ndev, "%s: can't get FIFO occupancy: %d.\n", __func__, ret); break; @@ -202,7 +202,7 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi) cfhsi->dev); if (ret) { clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits); - dev_warn(&cfhsi->ndev->dev, + netdev_warn(cfhsi->ndev, "%s: can't read data: %d.\n", __func__, ret); break; @@ -213,13 +213,13 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi) !test_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits), ret); if (ret < 0) { - dev_warn(&cfhsi->ndev->dev, + netdev_warn(cfhsi->ndev, "%s: can't wait for flush complete: %d.\n", __func__, ret); break; } else if (!ret) { ret = -ETIMEDOUT; - dev_warn(&cfhsi->ndev->dev, + netdev_warn(cfhsi->ndev, "%s: timeout waiting for flush complete.\n", __func__); break; @@ -348,7 +348,7 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi) struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf; int len, res; - dev_dbg(&cfhsi->ndev->dev, "%s.\n", __func__); + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) return; @@ -374,14 +374,14 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi) /* Set up new transfer. */ res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); if (WARN_ON(res < 0)) - dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n", + netdev_err(cfhsi->ndev, "%s: TX error %d.\n", __func__, res); } while (res < 0); } static void cfhsi_tx_done(struct cfhsi *cfhsi) { - dev_dbg(&cfhsi->ndev->dev, "%s.\n", __func__); + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) return; @@ -416,7 +416,7 @@ static void cfhsi_tx_done_cb(struct cfhsi_drv *drv) struct cfhsi *cfhsi; cfhsi = container_of(drv, struct cfhsi, drv); - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) @@ -433,7 +433,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) if ((desc->header & ~CFHSI_PIGGY_DESC) || (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) { - dev_err(&cfhsi->ndev->dev, "%s: Invalid descriptor.\n", + netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n", __func__); return -EPROTO; } @@ -455,7 +455,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Sanity check length of CAIF frame. */ if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) { - dev_err(&cfhsi->ndev->dev, "%s: Invalid length.\n", + netdev_err(cfhsi->ndev, "%s: Invalid length.\n", __func__); return -EPROTO; } @@ -463,7 +463,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Allocate SKB (OK even in IRQ context). */ skb = alloc_skb(len + 1, GFP_ATOMIC); if (!skb) { - dev_err(&cfhsi->ndev->dev, "%s: Out of memory !\n", + netdev_err(cfhsi->ndev, "%s: Out of memory !\n", __func__); return -ENOMEM; } @@ -504,7 +504,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) xfer_sz += CFHSI_DESC_SZ; if ((xfer_sz % 4) || (xfer_sz > (CFHSI_BUF_SZ_RX - CFHSI_DESC_SZ))) { - dev_err(&cfhsi->ndev->dev, + netdev_err(cfhsi->ndev, "%s: Invalid payload len: %d, ignored.\n", __func__, xfer_sz); return -EPROTO; @@ -551,7 +551,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Sanity check header and offset. */ if (WARN_ON((desc->header & ~CFHSI_PIGGY_DESC) || (desc->offset > CFHSI_MAX_EMB_FRM_SZ))) { - dev_err(&cfhsi->ndev->dev, "%s: Invalid descriptor.\n", + netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n", __func__); return -EPROTO; } @@ -585,7 +585,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Sanity check length of CAIF frames. */ if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) { - dev_err(&cfhsi->ndev->dev, "%s: Invalid length.\n", + netdev_err(cfhsi->ndev, "%s: Invalid length.\n", __func__); return -EPROTO; } @@ -593,7 +593,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Allocate SKB (OK even in IRQ context). */ skb = alloc_skb(len + 1, GFP_ATOMIC); if (!skb) { - dev_err(&cfhsi->ndev->dev, "%s: Out of memory !\n", + netdev_err(cfhsi->ndev, "%s: Out of memory !\n", __func__); cfhsi->rx_state.nfrms = nfrms; return -ENOMEM; @@ -639,7 +639,7 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) desc = (struct cfhsi_desc *)cfhsi->rx_buf; - dev_dbg(&cfhsi->ndev->dev, "%s\n", __func__); + netdev_dbg(cfhsi->ndev, "%s\n", __func__); if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) return; @@ -709,13 +709,13 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) /* Initiate next read */ if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) { /* Set up new transfer. */ - dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n", + netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__); res = cfhsi->dev->cfhsi_rx(rx_ptr, rx_len, cfhsi->dev); if (WARN_ON(res < 0)) { - dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n", + netdev_err(cfhsi->ndev, "%s: RX error %d.\n", __func__, res); cfhsi->ndev->stats.rx_errors++; cfhsi->ndev->stats.rx_dropped++; @@ -750,7 +750,7 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) return; out_of_sync: - dev_err(&cfhsi->ndev->dev, "%s: Out of sync.\n", __func__); + netdev_err(cfhsi->ndev, "%s: Out of sync.\n", __func__); print_hex_dump_bytes("--> ", DUMP_PREFIX_NONE, cfhsi->rx_buf, CFHSI_DESC_SZ); schedule_work(&cfhsi->out_of_sync_work); @@ -760,7 +760,7 @@ static void cfhsi_rx_slowpath(unsigned long arg) { struct cfhsi *cfhsi = (struct cfhsi *)arg; - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); cfhsi_rx_done(cfhsi); @@ -771,7 +771,7 @@ static void cfhsi_rx_done_cb(struct cfhsi_drv *drv) struct cfhsi *cfhsi; cfhsi = container_of(drv, struct cfhsi, drv); - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) @@ -806,7 +806,7 @@ static void cfhsi_wake_up(struct work_struct *work) /* Activate wake line. */ cfhsi->dev->cfhsi_wake_up(cfhsi->dev); - dev_dbg(&cfhsi->ndev->dev, "%s: Start waiting.\n", + netdev_dbg(cfhsi->ndev, "%s: Start waiting.\n", __func__); /* Wait for acknowledge. */ @@ -816,7 +816,7 @@ static void cfhsi_wake_up(struct work_struct *work) &cfhsi->bits), ret); if (unlikely(ret < 0)) { /* Interrupted by signal. */ - dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", + netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n", __func__, ret); clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); @@ -827,14 +827,14 @@ static void cfhsi_wake_up(struct work_struct *work) size_t fifo_occupancy = 0; /* Wakeup timeout */ - dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n", + netdev_dbg(cfhsi->ndev, "%s: Timeout.\n", __func__); /* Check FIFO to check if modem has sent something. */ WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, &fifo_occupancy)); - dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", + netdev_dbg(cfhsi->ndev, "%s: Bytes in FIFO: %u.\n", __func__, (unsigned) fifo_occupancy); /* Check if we misssed the interrupt. */ @@ -842,7 +842,7 @@ static void cfhsi_wake_up(struct work_struct *work) &ca_wake)); if (ca_wake) { - dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n", + netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n", __func__); /* Clear the CFHSI_WAKE_UP_ACK bit to prevent race. */ @@ -857,7 +857,7 @@ static void cfhsi_wake_up(struct work_struct *work) return; } wake_ack: - dev_dbg(&cfhsi->ndev->dev, "%s: Woken.\n", + netdev_dbg(cfhsi->ndev, "%s: Woken.\n", __func__); /* Clear power up bit. */ @@ -865,11 +865,11 @@ wake_ack: clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); /* Resume read operation. */ - dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n", __func__); + netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__); res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->dev); if (WARN_ON(res < 0)) - dev_err(&cfhsi->ndev->dev, "%s: RX err %d.\n", __func__, res); + netdev_err(cfhsi->ndev, "%s: RX err %d.\n", __func__, res); /* Clear power up acknowledment. */ clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); @@ -878,7 +878,7 @@ wake_ack: /* Resume transmit if queues are not empty. */ if (!cfhsi_tx_queue_len(cfhsi)) { - dev_dbg(&cfhsi->ndev->dev, "%s: Peer wake, start timer.\n", + netdev_dbg(cfhsi->ndev, "%s: Peer wake, start timer.\n", __func__); /* Start inactivity timer. */ mod_timer(&cfhsi->inactivity_timer, @@ -887,7 +887,7 @@ wake_ack: return; } - dev_dbg(&cfhsi->ndev->dev, "%s: Host wake.\n", + netdev_dbg(cfhsi->ndev, "%s: Host wake.\n", __func__); spin_unlock_bh(&cfhsi->lock); @@ -899,12 +899,12 @@ wake_ack: /* Set up new transfer. */ res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); if (WARN_ON(res < 0)) { - dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n", + netdev_err(cfhsi->ndev, "%s: TX error %d.\n", __func__, res); cfhsi_abort_tx(cfhsi); } } else { - dev_err(&cfhsi->ndev->dev, + netdev_err(cfhsi->ndev, "%s: Failed to create HSI frame: %d.\n", __func__, len); } @@ -918,7 +918,7 @@ static void cfhsi_wake_down(struct work_struct *work) int retry = CFHSI_WAKE_TOUT; cfhsi = container_of(work, struct cfhsi, wake_down_work); - dev_dbg(&cfhsi->ndev->dev, "%s.\n", __func__); + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) return; @@ -933,20 +933,20 @@ static void cfhsi_wake_down(struct work_struct *work) &cfhsi->bits), ret); if (ret < 0) { /* Interrupted by signal. */ - dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", + netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n", __func__, ret); return; } else if (!ret) { bool ca_wake = true; /* Timeout */ - dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__); + netdev_err(cfhsi->ndev, "%s: Timeout.\n", __func__); /* Check if we misssed the interrupt. */ WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev, &ca_wake)); if (!ca_wake) - dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n", + netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n", __func__); } @@ -964,7 +964,7 @@ static void cfhsi_wake_down(struct work_struct *work) } if (!retry) - dev_err(&cfhsi->ndev->dev, "%s: FIFO Timeout.\n", __func__); + netdev_err(cfhsi->ndev, "%s: FIFO Timeout.\n", __func__); /* Clear AWAKE condition. */ clear_bit(CFHSI_AWAKE, &cfhsi->bits); @@ -990,7 +990,7 @@ static void cfhsi_wake_up_cb(struct cfhsi_drv *drv) struct cfhsi *cfhsi = NULL; cfhsi = container_of(drv, struct cfhsi, drv); - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); set_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); @@ -1009,7 +1009,7 @@ static void cfhsi_wake_down_cb(struct cfhsi_drv *drv) struct cfhsi *cfhsi = NULL; cfhsi = container_of(drv, struct cfhsi, drv); - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); /* Initiating low power is only permitted by the host (us). */ @@ -1021,7 +1021,7 @@ static void cfhsi_aggregation_tout(unsigned long arg) { struct cfhsi *cfhsi = (struct cfhsi *)arg; - dev_dbg(&cfhsi->ndev->dev, "%s.\n", + netdev_dbg(cfhsi->ndev, "%s.\n", __func__); cfhsi_start_tx(cfhsi); @@ -1113,7 +1113,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev) /* Set up new transfer. */ res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); if (WARN_ON(res < 0)) { - dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n", + netdev_err(cfhsi->ndev, "%s: TX error %d.\n", __func__, res); cfhsi_abort_tx(cfhsi); } @@ -1269,7 +1269,7 @@ static int cfhsi_open(struct net_device *ndev) /* Create work thread. */ cfhsi->wq = create_singlethread_workqueue(cfhsi->pdev->name); if (!cfhsi->wq) { - dev_err(&cfhsi->ndev->dev, "%s: Failed to create work queue.\n", + netdev_err(cfhsi->ndev, "%s: Failed to create work queue.\n", __func__); res = -ENODEV; goto err_create_wq; @@ -1296,7 +1296,7 @@ static int cfhsi_open(struct net_device *ndev) /* Activate HSI interface. */ res = cfhsi->dev->cfhsi_up(cfhsi->dev); if (res) { - dev_err(&cfhsi->ndev->dev, + netdev_err(cfhsi->ndev, "%s: can't activate HSI interface: %d.\n", __func__, res); goto err_activate; @@ -1305,7 +1305,7 @@ static int cfhsi_open(struct net_device *ndev) /* Flush FIFO */ res = cfhsi_flush_fifo(cfhsi); if (res) { - dev_err(&cfhsi->ndev->dev, "%s: Can't flush FIFO: %d.\n", + netdev_err(cfhsi->ndev, "%s: Can't flush FIFO: %d.\n", __func__, res); goto err_net_reg; } -- GitLab From b42f7b5cfda6f7dac298da2d9a8855f6364e35d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 25 Jun 2012 07:49:39 +0000 Subject: [PATCH 2803/6849] caif-hsi: Remove uncecessary assignments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove assignment at declaration when not needed. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index f7997a7b5aed..d80759e58532 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -246,8 +246,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Check if we can embed a CAIF frame. */ if (skb->len < CFHSI_MAX_EMB_FRM_SZ) { struct caif_payload_info *info; - int hpad = 0; - int tpad = 0; + int hpad; + int tpad; /* Calculate needed head alignment and tail alignment. */ info = (struct caif_payload_info *)&skb->cb; @@ -282,8 +282,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi) pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ; while (nfrms < CFHSI_MAX_PKTS) { struct caif_payload_info *info; - int hpad = 0; - int tpad = 0; + int hpad; + int tpad; if (!skb) skb = cfhsi_dequeue(cfhsi); @@ -573,7 +573,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) struct sk_buff *skb; u8 *dst = NULL; u8 *pcffrm = NULL; - int len = 0; + int len; /* CAIF frame starts after head padding. */ pcffrm = pfrm + *pfrm + 1; -- GitLab From 5051c94bb3998ff24bf07ae3b72dca30f85962f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 25 Jun 2012 07:49:40 +0000 Subject: [PATCH 2804/6849] Documentation/networking/caif: Update documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update drawing and remove description of old features. Add HSI and USB link layers to the drawing. Reported-by: Joerg Reisenweber Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- Documentation/networking/caif/Linux-CAIF.txt | 91 ++++++-------------- 1 file changed, 27 insertions(+), 64 deletions(-) diff --git a/Documentation/networking/caif/Linux-CAIF.txt b/Documentation/networking/caif/Linux-CAIF.txt index e52fd62bef3a..0aa4bd381bec 100644 --- a/Documentation/networking/caif/Linux-CAIF.txt +++ b/Documentation/networking/caif/Linux-CAIF.txt @@ -19,60 +19,36 @@ and host. Currently, UART and Loopback are available for Linux. Architecture: ------------ The implementation of CAIF is divided into: -* CAIF Socket Layer, Kernel API, and Net Device. +* CAIF Socket Layer and GPRS IP Interface. * CAIF Core Protocol Implementation * CAIF Link Layer, implemented as NET devices. RTNL ! - ! +------+ +------+ +------+ - ! +------+! +------+! +------+! - ! ! Sock !! !Kernel!! ! Net !! - ! ! API !+ ! API !+ ! Dev !+ <- CAIF Client APIs - ! +------+ +------! +------+ - ! ! ! ! - ! +----------!----------+ - ! +------+ <- CAIF Protocol Implementation - +-------> ! CAIF ! - ! Core ! - +------+ - +--------!--------+ - ! ! - +------+ +-----+ - ! ! ! TTY ! <- Link Layer (Net Devices) - +------+ +-----+ - - -Using the Kernel API ----------------------- -The Kernel API is used for accessing CAIF channels from the -kernel. -The user of the API has to implement two callbacks for receive -and control. -The receive callback gives a CAIF packet as a SKB. The control -callback will -notify of channel initialization complete, and flow-on/flow- -off. - - - struct caif_device caif_dev = { - .caif_config = { - .name = "MYDEV" - .type = CAIF_CHTY_AT - } - .receive_cb = my_receive, - .control_cb = my_control, - }; - caif_add_device(&caif_dev); - caif_transmit(&caif_dev, skb); - -See the caif_kernel.h for details about the CAIF kernel API. + ! +------+ +------+ + ! +------+! +------+! + ! ! IP !! !Socket!! + +-------> !interf!+ ! API !+ <- CAIF Client APIs + ! +------+ +------! + ! ! ! + ! +-----------+ + ! ! + ! +------+ <- CAIF Core Protocol + ! ! CAIF ! + ! ! Core ! + ! +------+ + ! +----------!---------+ + ! ! ! ! + ! +------+ +-----+ +------+ + +--> ! HSI ! ! TTY ! ! USB ! <- Link Layer (Net Devices) + +------+ +-----+ +------+ + I M P L E M E N T A T I O N =========================== -=========================== + CAIF Core Protocol Layer ========================================= @@ -88,17 +64,13 @@ The Core CAIF implementation contains: - Simple implementation of CAIF. - Layered architecture (a la Streams), each layer in the CAIF specification is implemented in a separate c-file. - - Clients must implement PHY layer to access physical HW - with receive and transmit functions. - Clients must call configuration function to add PHY layer. - Clients must implement CAIF layer to consume/produce CAIF payload with receive and transmit functions. - Clients must call configuration function to add and connect the Client layer. - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed - to the called function (except for framing layers' receive functions - or if a transmit function returns an error, in which case the caller - must free the packet). + to the called function (except for framing layers' receive function) Layered Architecture -------------------- @@ -109,11 +81,6 @@ Implementation. The support functions include: CAIF Packet has functions for creating, destroying and adding content and for adding/extracting header and trailers to protocol packets. - - CFLST CAIF list implementation. - - - CFGLUE CAIF Glue. Contains OS Specifics, such as memory - allocation, endianness, etc. - The CAIF Protocol implementation contains: - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol @@ -128,7 +95,7 @@ The CAIF Protocol implementation contains: control and remote shutdown requests. - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual - External Interface). This layer encodes/decodes VEI frames. + External Interface). This layer encodes/decodes VEI frames. - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP traffic), encodes/decodes Datagram frames. @@ -170,7 +137,7 @@ The CAIF Protocol implementation contains: +---------+ +---------+ ! ! +---------+ +---------+ - | | | Serial | + | | | Serial | | | | CFSERL | +---------+ +---------+ @@ -186,24 +153,20 @@ In this layered approach the following "rules" apply. layer->dn->transmit(layer->dn, packet); -Linux Driver Implementation +CAIF Socket and IP interface =========================== -Linux GPRS Net Device and CAIF socket are implemented on top of the -CAIF Core protocol. The Net device and CAIF socket have an instance of +The IP interface and CAIF socket API are implemented on top of the +CAIF Core protocol. The IP Interface and CAIF socket have an instance of 'struct cflayer', just like the CAIF Core protocol stack. Net device and Socket implement the 'receive()' function defined by 'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and receive of packets is handled as by the rest of the layers: the 'dn->transmit()' function is called in order to transmit data. -The layer on top of the CAIF Core implementation is -sometimes referred to as the "Client layer". - - Configuration of Link Layer --------------------------- -The Link Layer is implemented as Linux net devices (struct net_device). +The Link Layer is implemented as Linux network devices (struct net_device). Payload handling and registration is done using standard Linux mechanisms. The CAIF Protocol relies on a loss-less link layer without implementing -- GitLab From c41254006377842013922fb1e407391f24c59522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 25 Jun 2012 07:49:41 +0000 Subject: [PATCH 2805/6849] caif-hsi: Add rtnl support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add RTNL support for managing the caif hsi interface. The HSI HW interface is no longer registering as a device, instead we use symbol_get to get hold of the HSI API. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 226 ++++++++++++++++++++++-------------- include/net/caif/caif_hsi.h | 21 +++- 2 files changed, 157 insertions(+), 90 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index d80759e58532..a14f85c0f0e8 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -79,7 +79,6 @@ MODULE_PARM_DESC(hsi_low_threshold, "HSI high threshold (FLOW ON)."); #define HIGH_WATER_MARK hsi_high_threshold static LIST_HEAD(cfhsi_list); -static spinlock_t cfhsi_list_lock; static void cfhsi_inactivity_tout(unsigned long arg) { @@ -1148,42 +1147,6 @@ static void cfhsi_setup(struct net_device *dev) cfhsi->ndev = dev; } -int cfhsi_probe(struct platform_device *pdev) -{ - struct cfhsi *cfhsi = NULL; - struct net_device *ndev; - - int res; - - ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup); - if (!ndev) - return -ENODEV; - - cfhsi = netdev_priv(ndev); - cfhsi->ndev = ndev; - cfhsi->pdev = pdev; - - /* Assign the HSI device. */ - cfhsi->dev = pdev->dev.platform_data; - - /* Assign the driver to this HSI device. */ - cfhsi->dev->drv = &cfhsi->drv; - - /* Register network device. */ - res = register_netdev(ndev); - if (res) { - dev_err(&ndev->dev, "%s: Registration error: %d.\n", - __func__, res); - free_netdev(ndev); - } - /* Add CAIF HSI device to list. */ - spin_lock(&cfhsi_list_lock); - list_add_tail(&cfhsi->list, &cfhsi_list); - spin_unlock(&cfhsi_list_lock); - - return res; -} - static int cfhsi_open(struct net_device *ndev) { struct cfhsi *cfhsi = netdev_priv(ndev); @@ -1364,85 +1327,170 @@ static int cfhsi_close(struct net_device *ndev) return 0; } +static void cfhsi_uninit(struct net_device *dev) +{ + struct cfhsi *cfhsi = netdev_priv(dev); + ASSERT_RTNL(); + symbol_put(cfhsi_get_device); + list_del(&cfhsi->list); +} + static const struct net_device_ops cfhsi_ops = { + .ndo_uninit = cfhsi_uninit, .ndo_open = cfhsi_open, .ndo_stop = cfhsi_close, .ndo_start_xmit = cfhsi_xmit }; -int cfhsi_remove(struct platform_device *pdev) +static void cfhsi_netlink_parms(struct nlattr *data[], struct cfhsi *cfhsi) { - struct list_head *list_node; - struct list_head *n; - struct cfhsi *cfhsi = NULL; - struct cfhsi_dev *dev; + int i; - dev = (struct cfhsi_dev *)pdev->dev.platform_data; - spin_lock(&cfhsi_list_lock); - list_for_each_safe(list_node, n, &cfhsi_list) { - cfhsi = list_entry(list_node, struct cfhsi, list); - /* Find the corresponding device. */ - if (cfhsi->dev == dev) { - /* Remove from list. */ - list_del(list_node); - spin_unlock(&cfhsi_list_lock); - return 0; - } + if (!data) { + pr_debug("no params data found\n"); + return; } - spin_unlock(&cfhsi_list_lock); - return -ENODEV; + + i = __IFLA_CAIF_HSI_INACTIVITY_TOUT; + if (data[i]) + inactivity_timeout = nla_get_u32(data[i]); + + i = __IFLA_CAIF_HSI_AGGREGATION_TOUT; + if (data[i]) + aggregation_timeout = nla_get_u32(data[i]); + + i = __IFLA_CAIF_HSI_HEAD_ALIGN; + if (data[i]) + hsi_head_align = nla_get_u32(data[i]); + + i = __IFLA_CAIF_HSI_TAIL_ALIGN; + if (data[i]) + hsi_tail_align = nla_get_u32(data[i]); + + i = __IFLA_CAIF_HSI_QHIGH_WATERMARK; + if (data[i]) + hsi_high_threshold = nla_get_u32(data[i]); +} + +static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[], + struct nlattr *data[]) +{ + cfhsi_netlink_parms(data, netdev_priv(dev)); + netdev_state_change(dev); + return 0; } -struct platform_driver cfhsi_plat_drv = { - .probe = cfhsi_probe, - .remove = cfhsi_remove, - .driver = { - .name = "cfhsi", - .owner = THIS_MODULE, - }, +static const struct nla_policy caif_hsi_policy[__IFLA_CAIF_HSI_MAX + 1] = { + [__IFLA_CAIF_HSI_INACTIVITY_TOUT] = { .type = NLA_U32, .len = 4 }, + [__IFLA_CAIF_HSI_AGGREGATION_TOUT] = { .type = NLA_U32, .len = 4 }, + [__IFLA_CAIF_HSI_HEAD_ALIGN] = { .type = NLA_U32, .len = 4 }, + [__IFLA_CAIF_HSI_TAIL_ALIGN] = { .type = NLA_U32, .len = 4 }, + [__IFLA_CAIF_HSI_QHIGH_WATERMARK] = { .type = NLA_U32, .len = 4 }, + [__IFLA_CAIF_HSI_QLOW_WATERMARK] = { .type = NLA_U32, .len = 4 }, }; -static void __exit cfhsi_exit_module(void) +static size_t caif_hsi_get_size(const struct net_device *dev) +{ + int i; + size_t s = 0; + for (i = __IFLA_CAIF_HSI_UNSPEC + 1; i < __IFLA_CAIF_HSI_MAX; i++) + s += nla_total_size(caif_hsi_policy[i].len); + return s; +} + +static int caif_hsi_fill_info(struct sk_buff *skb, const struct net_device *dev) +{ + if (nla_put_u32(skb, __IFLA_CAIF_HSI_INACTIVITY_TOUT, + inactivity_timeout) || + nla_put_u32(skb, __IFLA_CAIF_HSI_AGGREGATION_TOUT, + aggregation_timeout) || + nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN, hsi_head_align) || + nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN, hsi_tail_align) || + nla_put_u32(skb, __IFLA_CAIF_HSI_QHIGH_WATERMARK, + hsi_high_threshold) || + nla_put_u32(skb, __IFLA_CAIF_HSI_QLOW_WATERMARK, + hsi_low_threshold)) + return -EMSGSIZE; + + return 0; +} + +static int caif_hsi_newlink(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[]) { - struct list_head *list_node; - struct list_head *n; struct cfhsi *cfhsi = NULL; + struct platform_device *(*get_dev)(void); - spin_lock(&cfhsi_list_lock); - list_for_each_safe(list_node, n, &cfhsi_list) { - cfhsi = list_entry(list_node, struct cfhsi, list); + ASSERT_RTNL(); + + cfhsi = netdev_priv(dev); + cfhsi_netlink_parms(data, cfhsi); + dev_net_set(cfhsi->ndev, src_net); + + get_dev = symbol_get(cfhsi_get_device); + if (!get_dev) { + pr_err("%s: failed to get the cfhsi device symbol\n", __func__); + return -ENODEV; + } + + /* Assign the HSI device. */ + cfhsi->pdev = (*get_dev)(); + if (!cfhsi->pdev) { + pr_err("%s: failed to get the cfhsi device\n", __func__); + goto err; + } - /* Remove from list. */ - list_del(list_node); - spin_unlock(&cfhsi_list_lock); + /* Assign the HSI device. */ + cfhsi->dev = cfhsi->pdev->dev.platform_data; + + /* Assign the driver to this HSI device. */ + cfhsi->dev->drv = &cfhsi->drv; - unregister_netdevice(cfhsi->ndev); + if (register_netdevice(dev)) { + pr_warn("%s: device rtml registration failed\n", __func__); + goto err; - spin_lock(&cfhsi_list_lock); } - spin_unlock(&cfhsi_list_lock); + /* Add CAIF HSI device to list. */ + list_add_tail(&cfhsi->list, &cfhsi_list); - /* Unregister platform driver. */ - platform_driver_unregister(&cfhsi_plat_drv); + return 0; +err: + symbol_put(cfhsi_get_device); + return -ENODEV; } -static int __init cfhsi_init_module(void) +static struct rtnl_link_ops caif_hsi_link_ops __read_mostly = { + .kind = "cfhsi", + .priv_size = sizeof(struct cfhsi), + .setup = cfhsi_setup, + .maxtype = __IFLA_CAIF_HSI_MAX, + .policy = caif_hsi_policy, + .newlink = caif_hsi_newlink, + .changelink = caif_hsi_changelink, + .get_size = caif_hsi_get_size, + .fill_info = caif_hsi_fill_info, +}; + +static void __exit cfhsi_exit_module(void) { - int result; + struct list_head *list_node; + struct list_head *n; + struct cfhsi *cfhsi; - /* Initialize spin lock. */ - spin_lock_init(&cfhsi_list_lock); + rtnl_link_unregister(&caif_hsi_link_ops); - /* Register platform driver. */ - result = platform_driver_register(&cfhsi_plat_drv); - if (result) { - printk(KERN_ERR "Could not register platform HSI driver: %d.\n", - result); - goto err_dev_register; + rtnl_lock(); + list_for_each_safe(list_node, n, &cfhsi_list) { + cfhsi = list_entry(list_node, struct cfhsi, list); + unregister_netdev(cfhsi->ndev); } + rtnl_unlock(); +} - err_dev_register: - return result; +static int __init cfhsi_init_module(void) +{ + return rtnl_link_register(&caif_hsi_link_ops); } module_init(cfhsi_init_module); diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h index 439dadc8102f..a77b2bd7719a 100644 --- a/include/net/caif/caif_hsi.h +++ b/include/net/caif/caif_hsi.h @@ -170,7 +170,26 @@ struct cfhsi { unsigned long bits; }; - extern struct platform_driver cfhsi_driver; +/** + * enum ifla_caif_hsi - CAIF HSI NetlinkRT parameters. + * @IFLA_CAIF_HSI_INACTIVITY_TOUT: Inactivity timeout before + * taking the HSI wakeline down, in milliseconds. + * When using RT Netlink to create, destroy or configure a CAIF HSI interface, + * enum ifla_caif_hsi is used to specify the configuration attributes. + */ +enum ifla_caif_hsi { + __IFLA_CAIF_HSI_UNSPEC, + __IFLA_CAIF_HSI_INACTIVITY_TOUT, + __IFLA_CAIF_HSI_AGGREGATION_TOUT, + __IFLA_CAIF_HSI_HEAD_ALIGN, + __IFLA_CAIF_HSI_TAIL_ALIGN, + __IFLA_CAIF_HSI_QHIGH_WATERMARK, + __IFLA_CAIF_HSI_QLOW_WATERMARK, + __IFLA_CAIF_HSI_MAX +}; + +extern struct platform_device *cfhsi_get_device(void); + #endif /* CAIF_HSI_H_ */ -- GitLab From 1c385f1fdf6f9c66d982802cd74349c040980b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 25 Jun 2012 07:49:42 +0000 Subject: [PATCH 2806/6849] caif-hsi: Replace platform device with ops structure. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove use of struct platform_device, and replace it with struct cfhsi_ops. Updated variable names in the same spirit: cfhsi_get_dev to cfhsi_get_ops, cfhsi->dev to cfhsi->ops and, cfhsi->dev.drv to cfhsi->ops->cb_ops. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 109 +++++++++++++++++------------------- include/net/caif/caif_hsi.h | 38 ++++++------- 2 files changed, 70 insertions(+), 77 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index a14f85c0f0e8..0927c108bd14 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -184,7 +183,7 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi) __func__); do { - ret = cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, + ret = cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops, &fifo_occupancy); if (ret) { netdev_warn(cfhsi->ndev, @@ -197,8 +196,8 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi) fifo_occupancy = min(sizeof(buffer), fifo_occupancy); set_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits); - ret = cfhsi->dev->cfhsi_rx(buffer, fifo_occupancy, - cfhsi->dev); + ret = cfhsi->ops->cfhsi_rx(buffer, fifo_occupancy, + cfhsi->ops); if (ret) { clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits); netdev_warn(cfhsi->ndev, @@ -371,7 +370,7 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi) } /* Set up new transfer. */ - res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); + res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops); if (WARN_ON(res < 0)) netdev_err(cfhsi->ndev, "%s: TX error %d.\n", __func__, res); @@ -410,11 +409,11 @@ static void cfhsi_tx_done(struct cfhsi *cfhsi) return; } -static void cfhsi_tx_done_cb(struct cfhsi_drv *drv) +static void cfhsi_tx_done_cb(struct cfhsi_cb_ops *cb_ops) { struct cfhsi *cfhsi; - cfhsi = container_of(drv, struct cfhsi, drv); + cfhsi = container_of(cb_ops, struct cfhsi, cb_ops); netdev_dbg(cfhsi->ndev, "%s.\n", __func__); @@ -476,8 +475,8 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) skb->dev = cfhsi->ndev; /* - * We are called from a arch specific platform device. - * Unfortunately we don't know what context we're + * We are in a callback handler and + * unfortunately we don't know what context we're * running in. */ if (in_interrupt()) @@ -607,7 +606,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) skb->dev = cfhsi->ndev; /* - * We're called from a platform device, + * We're called in callback from HSI * and don't know the context we're running in. */ if (in_interrupt()) @@ -711,8 +710,8 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__); - res = cfhsi->dev->cfhsi_rx(rx_ptr, rx_len, - cfhsi->dev); + res = cfhsi->ops->cfhsi_rx(rx_ptr, rx_len, + cfhsi->ops); if (WARN_ON(res < 0)) { netdev_err(cfhsi->ndev, "%s: RX error %d.\n", __func__, res); @@ -765,11 +764,11 @@ static void cfhsi_rx_slowpath(unsigned long arg) cfhsi_rx_done(cfhsi); } -static void cfhsi_rx_done_cb(struct cfhsi_drv *drv) +static void cfhsi_rx_done_cb(struct cfhsi_cb_ops *cb_ops) { struct cfhsi *cfhsi; - cfhsi = container_of(drv, struct cfhsi, drv); + cfhsi = container_of(cb_ops, struct cfhsi, cb_ops); netdev_dbg(cfhsi->ndev, "%s.\n", __func__); @@ -803,7 +802,7 @@ static void cfhsi_wake_up(struct work_struct *work) } /* Activate wake line. */ - cfhsi->dev->cfhsi_wake_up(cfhsi->dev); + cfhsi->ops->cfhsi_wake_up(cfhsi->ops); netdev_dbg(cfhsi->ndev, "%s: Start waiting.\n", __func__); @@ -819,7 +818,7 @@ static void cfhsi_wake_up(struct work_struct *work) __func__, ret); clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); - cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + cfhsi->ops->cfhsi_wake_down(cfhsi->ops); return; } else if (!ret) { bool ca_wake = false; @@ -830,14 +829,14 @@ static void cfhsi_wake_up(struct work_struct *work) __func__); /* Check FIFO to check if modem has sent something. */ - WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, + WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops, &fifo_occupancy)); netdev_dbg(cfhsi->ndev, "%s: Bytes in FIFO: %u.\n", __func__, (unsigned) fifo_occupancy); /* Check if we misssed the interrupt. */ - WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev, + WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops, &ca_wake)); if (ca_wake) { @@ -852,7 +851,7 @@ static void cfhsi_wake_up(struct work_struct *work) } clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); - cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + cfhsi->ops->cfhsi_wake_down(cfhsi->ops); return; } wake_ack: @@ -865,7 +864,7 @@ wake_ack: /* Resume read operation. */ netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__); - res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->dev); + res = cfhsi->ops->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->ops); if (WARN_ON(res < 0)) netdev_err(cfhsi->ndev, "%s: RX err %d.\n", __func__, res); @@ -896,7 +895,7 @@ wake_ack: if (likely(len > 0)) { /* Set up new transfer. */ - res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); + res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops); if (WARN_ON(res < 0)) { netdev_err(cfhsi->ndev, "%s: TX error %d.\n", __func__, res); @@ -923,7 +922,7 @@ static void cfhsi_wake_down(struct work_struct *work) return; /* Deactivate wake line. */ - cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + cfhsi->ops->cfhsi_wake_down(cfhsi->ops); /* Wait for acknowledge. */ ret = CFHSI_WAKE_TOUT; @@ -942,7 +941,7 @@ static void cfhsi_wake_down(struct work_struct *work) netdev_err(cfhsi->ndev, "%s: Timeout.\n", __func__); /* Check if we misssed the interrupt. */ - WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev, + WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops, &ca_wake)); if (!ca_wake) netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n", @@ -951,7 +950,7 @@ static void cfhsi_wake_down(struct work_struct *work) /* Check FIFO occupancy. */ while (retry) { - WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, + WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops, &fifo_occupancy)); if (!fifo_occupancy) @@ -969,8 +968,7 @@ static void cfhsi_wake_down(struct work_struct *work) clear_bit(CFHSI_AWAKE, &cfhsi->bits); /* Cancel pending RX requests. */ - cfhsi->dev->cfhsi_rx_cancel(cfhsi->dev); - + cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops); } static void cfhsi_out_of_sync(struct work_struct *work) @@ -984,11 +982,11 @@ static void cfhsi_out_of_sync(struct work_struct *work) rtnl_unlock(); } -static void cfhsi_wake_up_cb(struct cfhsi_drv *drv) +static void cfhsi_wake_up_cb(struct cfhsi_cb_ops *cb_ops) { struct cfhsi *cfhsi = NULL; - cfhsi = container_of(drv, struct cfhsi, drv); + cfhsi = container_of(cb_ops, struct cfhsi, cb_ops); netdev_dbg(cfhsi->ndev, "%s.\n", __func__); @@ -1003,11 +1001,11 @@ static void cfhsi_wake_up_cb(struct cfhsi_drv *drv) queue_work(cfhsi->wq, &cfhsi->wake_up_work); } -static void cfhsi_wake_down_cb(struct cfhsi_drv *drv) +static void cfhsi_wake_down_cb(struct cfhsi_cb_ops *cb_ops) { struct cfhsi *cfhsi = NULL; - cfhsi = container_of(drv, struct cfhsi, drv); + cfhsi = container_of(cb_ops, struct cfhsi, cb_ops); netdev_dbg(cfhsi->ndev, "%s.\n", __func__); @@ -1110,7 +1108,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev) WARN_ON(!len); /* Set up new transfer. */ - res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); + res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops); if (WARN_ON(res < 0)) { netdev_err(cfhsi->ndev, "%s: TX error %d.\n", __func__, res); @@ -1125,19 +1123,19 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static const struct net_device_ops cfhsi_ops; +static const struct net_device_ops cfhsi_netdevops; static void cfhsi_setup(struct net_device *dev) { int i; struct cfhsi *cfhsi = netdev_priv(dev); dev->features = 0; - dev->netdev_ops = &cfhsi_ops; dev->type = ARPHRD_CAIF; dev->flags = IFF_POINTOPOINT | IFF_NOARP; dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ; dev->tx_queue_len = 0; dev->destructor = free_netdev; + dev->netdev_ops = &cfhsi_netdevops; for (i = 0; i < CFHSI_PRIO_LAST; ++i) skb_queue_head_init(&cfhsi->qhead[i]); cfhsi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; @@ -1213,10 +1211,10 @@ static int cfhsi_open(struct net_device *ndev) spin_lock_init(&cfhsi->lock); /* Set up the driver. */ - cfhsi->drv.tx_done_cb = cfhsi_tx_done_cb; - cfhsi->drv.rx_done_cb = cfhsi_rx_done_cb; - cfhsi->drv.wake_up_cb = cfhsi_wake_up_cb; - cfhsi->drv.wake_down_cb = cfhsi_wake_down_cb; + cfhsi->cb_ops.tx_done_cb = cfhsi_tx_done_cb; + cfhsi->cb_ops.rx_done_cb = cfhsi_rx_done_cb; + cfhsi->cb_ops.wake_up_cb = cfhsi_wake_up_cb; + cfhsi->cb_ops.wake_down_cb = cfhsi_wake_down_cb; /* Initialize the work queues. */ INIT_WORK(&cfhsi->wake_up_work, cfhsi_wake_up); @@ -1230,7 +1228,7 @@ static int cfhsi_open(struct net_device *ndev) clear_bit(CFHSI_AWAKE, &cfhsi->bits); /* Create work thread. */ - cfhsi->wq = create_singlethread_workqueue(cfhsi->pdev->name); + cfhsi->wq = create_singlethread_workqueue(cfhsi->ndev->name); if (!cfhsi->wq) { netdev_err(cfhsi->ndev, "%s: Failed to create work queue.\n", __func__); @@ -1257,7 +1255,7 @@ static int cfhsi_open(struct net_device *ndev) cfhsi->aggregation_timer.function = cfhsi_aggregation_tout; /* Activate HSI interface. */ - res = cfhsi->dev->cfhsi_up(cfhsi->dev); + res = cfhsi->ops->cfhsi_up(cfhsi->ops); if (res) { netdev_err(cfhsi->ndev, "%s: can't activate HSI interface: %d.\n", @@ -1275,7 +1273,7 @@ static int cfhsi_open(struct net_device *ndev) return res; err_net_reg: - cfhsi->dev->cfhsi_down(cfhsi->dev); + cfhsi->ops->cfhsi_down(cfhsi->ops); err_activate: destroy_workqueue(cfhsi->wq); err_create_wq: @@ -1305,7 +1303,7 @@ static int cfhsi_close(struct net_device *ndev) del_timer_sync(&cfhsi->aggregation_timer); /* Cancel pending RX request (if any) */ - cfhsi->dev->cfhsi_rx_cancel(cfhsi->dev); + cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops); /* Destroy workqueue */ destroy_workqueue(cfhsi->wq); @@ -1318,7 +1316,7 @@ static int cfhsi_close(struct net_device *ndev) cfhsi_abort_tx(cfhsi); /* Deactivate interface */ - cfhsi->dev->cfhsi_down(cfhsi->dev); + cfhsi->ops->cfhsi_down(cfhsi->ops); /* Free buffers. */ kfree(tx_buf); @@ -1335,7 +1333,7 @@ static void cfhsi_uninit(struct net_device *dev) list_del(&cfhsi->list); } -static const struct net_device_ops cfhsi_ops = { +static const struct net_device_ops cfhsi_netdevops = { .ndo_uninit = cfhsi_uninit, .ndo_open = cfhsi_open, .ndo_stop = cfhsi_close, @@ -1419,7 +1417,7 @@ static int caif_hsi_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct cfhsi *cfhsi = NULL; - struct platform_device *(*get_dev)(void); + struct cfhsi_ops *(*get_ops)(void); ASSERT_RTNL(); @@ -1427,36 +1425,31 @@ static int caif_hsi_newlink(struct net *src_net, struct net_device *dev, cfhsi_netlink_parms(data, cfhsi); dev_net_set(cfhsi->ndev, src_net); - get_dev = symbol_get(cfhsi_get_device); - if (!get_dev) { - pr_err("%s: failed to get the cfhsi device symbol\n", __func__); + get_ops = symbol_get(cfhsi_get_ops); + if (!get_ops) { + pr_err("%s: failed to get the cfhsi_ops\n", __func__); return -ENODEV; } /* Assign the HSI device. */ - cfhsi->pdev = (*get_dev)(); - if (!cfhsi->pdev) { - pr_err("%s: failed to get the cfhsi device\n", __func__); + cfhsi->ops = (*get_ops)(); + if (!cfhsi->ops) { + pr_err("%s: failed to get the cfhsi_ops\n", __func__); goto err; } - /* Assign the HSI device. */ - cfhsi->dev = cfhsi->pdev->dev.platform_data; - /* Assign the driver to this HSI device. */ - cfhsi->dev->drv = &cfhsi->drv; - + cfhsi->ops->cb_ops = &cfhsi->cb_ops; if (register_netdevice(dev)) { - pr_warn("%s: device rtml registration failed\n", __func__); + pr_warn("%s: caif_hsi device registration failed\n", __func__); goto err; - } /* Add CAIF HSI device to list. */ list_add_tail(&cfhsi->list, &cfhsi_list); return 0; err: - symbol_put(cfhsi_get_device); + symbol_put(cfhsi_get_ops); return -ENODEV; } diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h index a77b2bd7719a..6dc7dc2674b2 100644 --- a/include/net/caif/caif_hsi.h +++ b/include/net/caif/caif_hsi.h @@ -93,25 +93,25 @@ struct cfhsi_desc { #endif /* Structure implemented by the CAIF HSI driver. */ -struct cfhsi_drv { - void (*tx_done_cb) (struct cfhsi_drv *drv); - void (*rx_done_cb) (struct cfhsi_drv *drv); - void (*wake_up_cb) (struct cfhsi_drv *drv); - void (*wake_down_cb) (struct cfhsi_drv *drv); +struct cfhsi_cb_ops { + void (*tx_done_cb) (struct cfhsi_cb_ops *drv); + void (*rx_done_cb) (struct cfhsi_cb_ops *drv); + void (*wake_up_cb) (struct cfhsi_cb_ops *drv); + void (*wake_down_cb) (struct cfhsi_cb_ops *drv); }; /* Structure implemented by HSI device. */ -struct cfhsi_dev { - int (*cfhsi_up) (struct cfhsi_dev *dev); - int (*cfhsi_down) (struct cfhsi_dev *dev); - int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_dev *dev); - int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev); - int (*cfhsi_wake_up) (struct cfhsi_dev *dev); - int (*cfhsi_wake_down) (struct cfhsi_dev *dev); - int (*cfhsi_get_peer_wake) (struct cfhsi_dev *dev, bool *status); - int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy); - int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev); - struct cfhsi_drv *drv; +struct cfhsi_ops { + int (*cfhsi_up) (struct cfhsi_ops *dev); + int (*cfhsi_down) (struct cfhsi_ops *dev); + int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_ops *dev); + int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_ops *dev); + int (*cfhsi_wake_up) (struct cfhsi_ops *dev); + int (*cfhsi_wake_down) (struct cfhsi_ops *dev); + int (*cfhsi_get_peer_wake) (struct cfhsi_ops *dev, bool *status); + int (*cfhsi_fifo_occupancy) (struct cfhsi_ops *dev, size_t *occupancy); + int (*cfhsi_rx_cancel)(struct cfhsi_ops *dev); + struct cfhsi_cb_ops *cb_ops; }; /* Structure holds status of received CAIF frames processing */ @@ -138,8 +138,8 @@ struct cfhsi { struct net_device *ndev; struct platform_device *pdev; struct sk_buff_head qhead[CFHSI_PRIO_LAST]; - struct cfhsi_drv drv; - struct cfhsi_dev *dev; + struct cfhsi_cb_ops cb_ops; + struct cfhsi_ops *ops; int tx_state; struct cfhsi_rx_state rx_state; unsigned long inactivity_timeout; @@ -190,6 +190,6 @@ enum ifla_caif_hsi { __IFLA_CAIF_HSI_MAX }; -extern struct platform_device *cfhsi_get_device(void); +extern struct cfhsi_ops *cfhsi_get_ops(void); #endif /* CAIF_HSI_H_ */ -- GitLab From 91fa0cbc0c47930f771bf5425109956cc99c6b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 25 Jun 2012 07:49:43 +0000 Subject: [PATCH 2807/6849] caif-hsi: Remove use of module parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove use of module parameters on caif hsi device, as rtnl configuration parameters are already supported. All caif hsi configuration data is put in cfhsi_config, and default values in hsi_default_config. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 151 +++++++++++++++++------------------- include/net/caif/caif_hsi.h | 14 +++- 2 files changed, 82 insertions(+), 83 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 0927c108bd14..1c2bd01e1592 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -32,51 +32,39 @@ MODULE_DESCRIPTION("CAIF HSI driver"); #define PAD_POW2(x, pow) ((((x)&((pow)-1)) == 0) ? 0 :\ (((pow)-((x)&((pow)-1))))) -static int inactivity_timeout = 1000; -module_param(inactivity_timeout, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(inactivity_timeout, "Inactivity timeout on HSI, ms."); +static const struct cfhsi_config hsi_default_config = { -static int aggregation_timeout = 1; -module_param(aggregation_timeout, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(aggregation_timeout, "Aggregation timeout on HSI, ms."); + /* Inactivity timeout on HSI, ms */ + .inactivity_timeout = HZ, -/* - * HSI padding options. - * Warning: must be a base of 2 (& operation used) and can not be zero ! - */ -static int hsi_head_align = 4; -module_param(hsi_head_align, int, S_IRUGO); -MODULE_PARM_DESC(hsi_head_align, "HSI head alignment."); + /* Aggregation timeout (ms) of zero means no aggregation is done*/ + .aggregation_timeout = 1, -static int hsi_tail_align = 4; -module_param(hsi_tail_align, int, S_IRUGO); -MODULE_PARM_DESC(hsi_tail_align, "HSI tail alignment."); - -/* - * HSI link layer flowcontrol thresholds. - * Warning: A high threshold value migth increase throughput but it will at - * the same time prevent channel prioritization and increase the risk of - * flooding the modem. The high threshold should be above the low. - */ -static int hsi_high_threshold = 100; -module_param(hsi_high_threshold, int, S_IRUGO); -MODULE_PARM_DESC(hsi_high_threshold, "HSI high threshold (FLOW OFF)."); + /* + * HSI link layer flow-control thresholds. + * Threshold values for the HSI packet queue. Flow-control will be + * asserted when the number of packets exceeds q_high_mark. It will + * not be de-asserted before the number of packets drops below + * q_low_mark. + * Warning: A high threshold value might increase throughput but it + * will at the same time prevent channel prioritization and increase + * the risk of flooding the modem. The high threshold should be above + * the low. + */ + .q_high_mark = 100, + .q_low_mark = 50, -static int hsi_low_threshold = 50; -module_param(hsi_low_threshold, int, S_IRUGO); -MODULE_PARM_DESC(hsi_low_threshold, "HSI high threshold (FLOW ON)."); + /* + * HSI padding options. + * Warning: must be a base of 2 (& operation used) and can not be zero ! + */ + .head_align = 4, + .tail_align = 4, +}; #define ON 1 #define OFF 0 -/* - * Threshold values for the HSI packet queue. Flowcontrol will be asserted - * when the number of packets exceeds HIGH_WATER_MARK. It will not be - * de-asserted before the number of packets drops below LOW_WATER_MARK. - */ -#define LOW_WATER_MARK hsi_low_threshold -#define HIGH_WATER_MARK hsi_high_threshold - static LIST_HEAD(cfhsi_list); static void cfhsi_inactivity_tout(unsigned long arg) @@ -99,8 +87,8 @@ static void cfhsi_update_aggregation_stats(struct cfhsi *cfhsi, int hpad, tpad, len; info = (struct caif_payload_info *)&skb->cb; - hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align); - tpad = PAD_POW2((skb->len + hpad), hsi_tail_align); + hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align); + tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align); len = skb->len + hpad + tpad; if (direction > 0) @@ -113,7 +101,7 @@ static bool cfhsi_can_send_aggregate(struct cfhsi *cfhsi) { int i; - if (cfhsi->aggregation_timeout == 0) + if (cfhsi->cfg.aggregation_timeout == 0) return true; for (i = 0; i < CFHSI_PRIO_BEBK; ++i) { @@ -169,7 +157,7 @@ static void cfhsi_abort_tx(struct cfhsi *cfhsi) cfhsi->tx_state = CFHSI_TX_STATE_IDLE; if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) mod_timer(&cfhsi->inactivity_timer, - jiffies + cfhsi->inactivity_timeout); + jiffies + cfhsi->cfg.inactivity_timeout); spin_unlock_bh(&cfhsi->lock); } @@ -250,8 +238,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Calculate needed head alignment and tail alignment. */ info = (struct caif_payload_info *)&skb->cb; - hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align); - tpad = PAD_POW2((skb->len + hpad), hsi_tail_align); + hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align); + tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align); /* Check if frame still fits with added alignment. */ if ((skb->len + hpad + tpad) <= CFHSI_MAX_EMB_FRM_SZ) { @@ -292,8 +280,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi) /* Calculate needed head alignment and tail alignment. */ info = (struct caif_payload_info *)&skb->cb; - hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align); - tpad = PAD_POW2((skb->len + hpad), hsi_tail_align); + hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align); + tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align); /* Fill in CAIF frame length in descriptor. */ desc->cffrm_len[nfrms] = hpad + skb->len + tpad; @@ -364,7 +352,7 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi) cfhsi->tx_state = CFHSI_TX_STATE_IDLE; /* Start inactivity timer. */ mod_timer(&cfhsi->inactivity_timer, - jiffies + cfhsi->inactivity_timeout); + jiffies + cfhsi->cfg.inactivity_timeout); spin_unlock_bh(&cfhsi->lock); break; } @@ -390,7 +378,7 @@ static void cfhsi_tx_done(struct cfhsi *cfhsi) */ spin_lock_bh(&cfhsi->lock); if (cfhsi->flow_off_sent && - cfhsi_tx_queue_len(cfhsi) <= cfhsi->q_low_mark && + cfhsi_tx_queue_len(cfhsi) <= cfhsi->cfg.q_low_mark && cfhsi->cfdev.flowctrl) { cfhsi->flow_off_sent = 0; @@ -402,7 +390,7 @@ static void cfhsi_tx_done(struct cfhsi *cfhsi) cfhsi_start_tx(cfhsi); } else { mod_timer(&cfhsi->aggregation_timer, - jiffies + cfhsi->aggregation_timeout); + jiffies + cfhsi->cfg.aggregation_timeout); spin_unlock_bh(&cfhsi->lock); } @@ -645,7 +633,7 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) /* Update inactivity timer if pending. */ spin_lock_bh(&cfhsi->lock); mod_timer_pending(&cfhsi->inactivity_timer, - jiffies + cfhsi->inactivity_timeout); + jiffies + cfhsi->cfg.inactivity_timeout); spin_unlock_bh(&cfhsi->lock); if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) { @@ -880,7 +868,7 @@ wake_ack: __func__); /* Start inactivity timer. */ mod_timer(&cfhsi->inactivity_timer, - jiffies + cfhsi->inactivity_timeout); + jiffies + cfhsi->cfg.inactivity_timeout); spin_unlock_bh(&cfhsi->lock); return; } @@ -1071,7 +1059,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev) /* Send flow off if number of packets is above high water mark. */ if (!cfhsi->flow_off_sent && - cfhsi_tx_queue_len(cfhsi) > cfhsi->q_high_mark && + cfhsi_tx_queue_len(cfhsi) > cfhsi->cfg.q_high_mark && cfhsi->cfdev.flowctrl) { cfhsi->flow_off_sent = 1; cfhsi->cfdev.flowctrl(cfhsi->ndev, OFF); @@ -1143,6 +1131,7 @@ static void cfhsi_setup(struct net_device *dev) cfhsi->cfdev.use_stx = false; cfhsi->cfdev.use_fcs = false; cfhsi->ndev = dev; + cfhsi->cfg = hsi_default_config; } static int cfhsi_open(struct net_device *ndev) @@ -1158,9 +1147,6 @@ static int cfhsi_open(struct net_device *ndev) /* Set flow info */ cfhsi->flow_off_sent = 0; - cfhsi->q_low_mark = LOW_WATER_MARK; - cfhsi->q_high_mark = HIGH_WATER_MARK; - /* * Allocate a TX buffer with the size of a HSI packet descriptors @@ -1188,20 +1174,8 @@ static int cfhsi_open(struct net_device *ndev) goto err_alloc_rx_flip; } - /* Pre-calculate inactivity timeout. */ - if (inactivity_timeout != -1) { - cfhsi->inactivity_timeout = - inactivity_timeout * HZ / 1000; - if (!cfhsi->inactivity_timeout) - cfhsi->inactivity_timeout = 1; - else if (cfhsi->inactivity_timeout > NEXT_TIMER_MAX_DELTA) - cfhsi->inactivity_timeout = NEXT_TIMER_MAX_DELTA; - } else { - cfhsi->inactivity_timeout = NEXT_TIMER_MAX_DELTA; - } - /* Initialize aggregation timeout */ - cfhsi->aggregation_timeout = aggregation_timeout; + cfhsi->cfg.aggregation_timeout = hsi_default_config.aggregation_timeout; /* Initialize recieve vaiables. */ cfhsi->rx_ptr = cfhsi->rx_buf; @@ -1350,24 +1324,39 @@ static void cfhsi_netlink_parms(struct nlattr *data[], struct cfhsi *cfhsi) } i = __IFLA_CAIF_HSI_INACTIVITY_TOUT; - if (data[i]) - inactivity_timeout = nla_get_u32(data[i]); + /* + * Inactivity timeout in millisecs. Lowest possible value is 1, + * and highest possible is NEXT_TIMER_MAX_DELTA. + */ + if (data[i]) { + u32 inactivity_timeout = nla_get_u32(data[i]); + /* Pre-calculate inactivity timeout. */ + cfhsi->cfg.inactivity_timeout = inactivity_timeout * HZ / 1000; + if (cfhsi->cfg.inactivity_timeout == 0) + cfhsi->cfg.inactivity_timeout = 1; + else if (cfhsi->cfg.inactivity_timeout > NEXT_TIMER_MAX_DELTA) + cfhsi->cfg.inactivity_timeout = NEXT_TIMER_MAX_DELTA; + } i = __IFLA_CAIF_HSI_AGGREGATION_TOUT; if (data[i]) - aggregation_timeout = nla_get_u32(data[i]); + cfhsi->cfg.aggregation_timeout = nla_get_u32(data[i]); i = __IFLA_CAIF_HSI_HEAD_ALIGN; if (data[i]) - hsi_head_align = nla_get_u32(data[i]); + cfhsi->cfg.head_align = nla_get_u32(data[i]); i = __IFLA_CAIF_HSI_TAIL_ALIGN; if (data[i]) - hsi_tail_align = nla_get_u32(data[i]); + cfhsi->cfg.tail_align = nla_get_u32(data[i]); i = __IFLA_CAIF_HSI_QHIGH_WATERMARK; if (data[i]) - hsi_high_threshold = nla_get_u32(data[i]); + cfhsi->cfg.q_high_mark = nla_get_u32(data[i]); + + i = __IFLA_CAIF_HSI_QLOW_WATERMARK; + if (data[i]) + cfhsi->cfg.q_low_mark = nla_get_u32(data[i]); } static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[], @@ -1398,16 +1387,20 @@ static size_t caif_hsi_get_size(const struct net_device *dev) static int caif_hsi_fill_info(struct sk_buff *skb, const struct net_device *dev) { + struct cfhsi *cfhsi = netdev_priv(dev); + if (nla_put_u32(skb, __IFLA_CAIF_HSI_INACTIVITY_TOUT, - inactivity_timeout) || + cfhsi->cfg.inactivity_timeout) || nla_put_u32(skb, __IFLA_CAIF_HSI_AGGREGATION_TOUT, - aggregation_timeout) || - nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN, hsi_head_align) || - nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN, hsi_tail_align) || + cfhsi->cfg.aggregation_timeout) || + nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN, + cfhsi->cfg.head_align) || + nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN, + cfhsi->cfg.tail_align) || nla_put_u32(skb, __IFLA_CAIF_HSI_QHIGH_WATERMARK, - hsi_high_threshold) || + cfhsi->cfg.q_high_mark) || nla_put_u32(skb, __IFLA_CAIF_HSI_QLOW_WATERMARK, - hsi_low_threshold)) + cfhsi->cfg.q_low_mark)) return -EMSGSIZE; return 0; diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h index 6dc7dc2674b2..bcb9cc3ce98b 100644 --- a/include/net/caif/caif_hsi.h +++ b/include/net/caif/caif_hsi.h @@ -132,6 +132,15 @@ enum { CFHSI_PRIO_LAST, }; +struct cfhsi_config { + u32 inactivity_timeout; + u32 aggregation_timeout; + u32 head_align; + u32 tail_align; + u32 q_high_mark; + u32 q_low_mark; +}; + /* Structure implemented by CAIF HSI drivers. */ struct cfhsi { struct caif_dev_common cfdev; @@ -142,7 +151,7 @@ struct cfhsi { struct cfhsi_ops *ops; int tx_state; struct cfhsi_rx_state rx_state; - unsigned long inactivity_timeout; + struct cfhsi_config cfg; int rx_len; u8 *rx_ptr; u8 *tx_buf; @@ -150,8 +159,6 @@ struct cfhsi { u8 *rx_flip_buf; spinlock_t lock; int flow_off_sent; - u32 q_low_mark; - u32 q_high_mark; struct list_head list; struct work_struct wake_up_work; struct work_struct wake_down_work; @@ -164,7 +171,6 @@ struct cfhsi { struct timer_list rx_slowpath_timer; /* TX aggregation */ - unsigned long aggregation_timeout; int aggregation_len; struct timer_list aggregation_timer; -- GitLab From 3a35fc3a13333e7c137de82d8bf12bbc18639633 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 11 May 2012 10:41:18 +0200 Subject: [PATCH 2808/6849] clk: SPEAr600: Fix ethernet clock name for DT based probing Signed-off-by: Stefan Roese Cc: Viresh Kumar Cc: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear6xx_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index 554d64b062a1..61026ae564ab 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -298,7 +298,7 @@ void __init spear6xx_clk_init(void) clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB, GMAC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "gmac"); + clk_register_clkdev(clk, NULL, "e0800000.ethernet"); clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB, I2C_CLK_ENB, 0, &_lock); -- GitLab From 7975059db572eb47f0fb272a62afeae272a4b209 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 6 Jun 2012 14:41:31 +0530 Subject: [PATCH 2809/6849] clk: Allow late cache allocation for clk->parents Parent clocks for muxes are cached in clk->parents to avoid frequent lookups, however the cache allocation happens only during clock registeration and later clk_set_parent() assumes a cache space available and allocated. This is not entirely true for platforms which do early clock registerations wherein the cache allocation using kzalloc could fail during clock registeration. Allow cache allocation to happen later as part of clk_set_parent() to help such cases and avoid crashes assuming a cache being available. While here also replace existing kmalloc() with kzalloc() in the file. Signed-off-by: Rajendra Nayak Signed-off-by: Mike Turquette Cc: stable@kernel.org --- drivers/clk/clk.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 687b00d67c8a..df89cbfc1bd0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -999,7 +999,7 @@ static struct clk *__clk_init_parent(struct clk *clk) if (!clk->parents) clk->parents = - kmalloc((sizeof(struct clk*) * clk->num_parents), + kzalloc((sizeof(struct clk*) * clk->num_parents), GFP_KERNEL); if (!clk->parents) @@ -1065,9 +1065,13 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) old_parent = clk->parent; /* find index of new parent clock using cached parent ptrs */ - for (i = 0; i < clk->num_parents; i++) - if (clk->parents[i] == parent) - break; + if (clk->parents) + for (i = 0; i < clk->num_parents; i++) + if (clk->parents[i] == parent) + break; + else + clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), + GFP_KERNEL); /* * find index of new parent clock using string name comparison @@ -1076,7 +1080,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) if (i == clk->num_parents) for (i = 0; i < clk->num_parents; i++) if (!strcmp(clk->parent_names[i], parent->name)) { - clk->parents[i] = __clk_lookup(parent->name); + if (clk->parents) + clk->parents[i] = __clk_lookup(parent->name); break; } -- GitLab From bf47b4fd8f9f81cd5ce40e1945c6334d088226d1 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Fri, 8 Jun 2012 14:04:06 +0100 Subject: [PATCH 2810/6849] clk: Check parent for NULL in clk_change_rate clk_change_rate() is accessing parent's rate without checking if the parent exists at all. In case of root clocks this will cause NULL pointer dereference. This patch follows what clk_calc_new_rates() does in such situation. Signed-off-by: Pawel Moll Signed-off-by: Mike Turquette Cc: stable@kernel.org --- drivers/clk/clk.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index df89cbfc1bd0..dcbe05616090 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -850,18 +850,21 @@ static void clk_change_rate(struct clk *clk) { struct clk *child; unsigned long old_rate; + unsigned long best_parent_rate = 0; struct hlist_node *tmp; old_rate = clk->rate; + if (clk->parent) + best_parent_rate = clk->parent->rate; + if (clk->ops->set_rate) - clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); + clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); if (clk->ops->recalc_rate) - clk->rate = clk->ops->recalc_rate(clk->hw, - clk->parent->rate); + clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate); else - clk->rate = clk->parent->rate; + clk->rate = best_parent_rate; if (clk->notifier_count && old_rate != clk->rate) __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); -- GitLab From d6dc55c1857ff1911780881b74537785d8a4e6e1 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 Jun 2012 10:13:20 +0800 Subject: [PATCH 2811/6849] clk: mxs: fix ref_io clock definition The definition of clocks ref_io0 and ref_io1 were inverted. It causes a mmc regression on some boards right away. Fix the regression by correcting the ref_io clock definition. Reported-by: Maxime Ripard Signed-off-by: Shawn Guo Signed-off-by: Mike Turquette --- drivers/clk/mxs/clk-imx28.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 2826a2606a29..17e85a1f28ab 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -245,8 +245,8 @@ int __init mx28_clocks_init(void) clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000); clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0); clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1); - clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2); - clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3); + clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 2); + clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 3); clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0); clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1); clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2); -- GitLab From d03ac61daa8d4d17cd83a5ab98e85b616b90c7ac Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 21 Jun 2012 20:04:25 +0200 Subject: [PATCH 2812/6849] clk: mxs: fix clock lookup after freeing init memory The struct clk_lookup are marked as __initdata, resulting in being removed from memory after the kernel finished booting. However this leads to a NULL pointer de-ref if loading a module which uses clk_get. This patch removes the __initdata from the struct clk_lookup. Signed-off-by: Marc Kleine-Budde Signed-off-by: Shawn Guo Signed-off-by: Mike Turquette --- drivers/clk/mxs/clk-imx23.c | 12 ++++++------ drivers/clk/mxs/clk-imx28.c | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index f7be225f544c..db2391c054ee 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c @@ -71,7 +71,7 @@ static void __init clk_misc_init(void) __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC); } -static struct clk_lookup uart_lookups[] __initdata = { +static struct clk_lookup uart_lookups[] = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -80,31 +80,31 @@ static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "80070000.serial", }, }; -static struct clk_lookup hbus_lookups[] __initdata = { +static struct clk_lookup hbus_lookups[] = { { .dev_id = "imx23-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] __initdata = { +static struct clk_lookup xbus_lookups[] = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80070000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx23-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp_lookups[] __initdata = { +static struct clk_lookup ssp_lookups[] = { { .dev_id = "imx23-mmc.0", }, { .dev_id = "imx23-mmc.1", }, { .dev_id = "80010000.ssp", }, { .dev_id = "80034000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] __initdata = { +static struct clk_lookup lcdif_lookups[] = { { .dev_id = "imx23-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] __initdata = { +static struct clk_lookup gpmi_lookups[] = { { .dev_id = "imx23-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 17e85a1f28ab..7fad6c8c13d2 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -120,7 +120,7 @@ static void __init clk_misc_init(void) writel_relaxed(val, FRAC0); } -static struct clk_lookup uart_lookups[] __initdata = { +static struct clk_lookup uart_lookups[] = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -135,71 +135,71 @@ static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "80074000.serial", }, }; -static struct clk_lookup hbus_lookups[] __initdata = { +static struct clk_lookup hbus_lookups[] = { { .dev_id = "imx28-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] __initdata = { +static struct clk_lookup xbus_lookups[] = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80074000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx28-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp0_lookups[] __initdata = { +static struct clk_lookup ssp0_lookups[] = { { .dev_id = "imx28-mmc.0", }, { .dev_id = "80010000.ssp", }, }; -static struct clk_lookup ssp1_lookups[] __initdata = { +static struct clk_lookup ssp1_lookups[] = { { .dev_id = "imx28-mmc.1", }, { .dev_id = "80012000.ssp", }, }; -static struct clk_lookup ssp2_lookups[] __initdata = { +static struct clk_lookup ssp2_lookups[] = { { .dev_id = "imx28-mmc.2", }, { .dev_id = "80014000.ssp", }, }; -static struct clk_lookup ssp3_lookups[] __initdata = { +static struct clk_lookup ssp3_lookups[] = { { .dev_id = "imx28-mmc.3", }, { .dev_id = "80016000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] __initdata = { +static struct clk_lookup lcdif_lookups[] = { { .dev_id = "imx28-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] __initdata = { +static struct clk_lookup gpmi_lookups[] = { { .dev_id = "imx28-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; -static struct clk_lookup fec_lookups[] __initdata = { +static struct clk_lookup fec_lookups[] = { { .dev_id = "imx28-fec.0", }, { .dev_id = "imx28-fec.1", }, { .dev_id = "800f0000.ethernet", }, { .dev_id = "800f4000.ethernet", }, }; -static struct clk_lookup can0_lookups[] __initdata = { +static struct clk_lookup can0_lookups[] = { { .dev_id = "flexcan.0", }, { .dev_id = "80032000.can", }, }; -static struct clk_lookup can1_lookups[] __initdata = { +static struct clk_lookup can1_lookups[] = { { .dev_id = "flexcan.1", }, { .dev_id = "80034000.can", }, }; -static struct clk_lookup saif0_lookups[] __initdata = { +static struct clk_lookup saif0_lookups[] = { { .dev_id = "mxs-saif.0", }, { .dev_id = "80042000.saif", }, }; -static struct clk_lookup saif1_lookups[] __initdata = { +static struct clk_lookup saif1_lookups[] = { { .dev_id = "mxs-saif.1", }, { .dev_id = "80046000.saif", }, }; -- GitLab From 4dc27d1cf3b3027b9ce654221c559e88b2f41b33 Mon Sep 17 00:00:00 2001 From: David McCullough Date: Mon, 25 Jun 2012 15:42:26 +0000 Subject: [PATCH 2813/6849] net/ipv6/route.c: packets originating on device match lo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix to allow IPv6 packets originating locally to match rules with the "iff" set to "lo". This allows IPv6 rule matching work the same as it does for IPv4. From the iproute2 man page: iif NAME select the incoming device to match. If the interface is loop‐ back, the rule only matches packets originating from this host. This means that you may create separate routing tables for for‐ warded and local packets and, hence, completely segregate them. Signed-off-by: David McCullough Signed-off-by: David S. Miller --- net/ipv6/route.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c5bbece7f9f2..c518e4ec0cea 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -937,6 +937,8 @@ struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk, { int flags = 0; + fl6->flowi6_iif = net->loopback_dev->ifindex; + if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) flags |= RT6_LOOKUP_F_IFACE; -- GitLab From 5e7a76be0e48217aff6b6f34bdcce4725db999e2 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 25 Jun 2012 17:34:14 +0000 Subject: [PATCH 2814/6849] net/sh-eth: Add support selecting MII function for SH7734 and R8A7740 Ethernet IP of SH7734 and R8A7740 has selecting MII register. The user needs to change a value according to MII to be used. This adds the function to change the value of this register. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 108 ++++++++++++++++---------- drivers/net/ethernet/renesas/sh_eth.h | 1 + 2 files changed, 66 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 79bf09b41971..8d696e0c082b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -49,6 +49,34 @@ NETIF_MSG_RX_ERR| \ NETIF_MSG_TX_ERR) +#if defined(CONFIG_CPU_SUBTYPE_SH7734) || \ + defined(CONFIG_CPU_SUBTYPE_SH7763) || \ + defined(CONFIG_ARCH_R8A7740) +static void sh_eth_select_mii(struct net_device *ndev) +{ + u32 value = 0x0; + struct sh_eth_private *mdp = netdev_priv(ndev); + + switch (mdp->phy_interface) { + case PHY_INTERFACE_MODE_GMII: + value = 0x2; + break; + case PHY_INTERFACE_MODE_MII: + value = 0x1; + break; + case PHY_INTERFACE_MODE_RMII: + value = 0x0; + break; + default: + pr_warn("PHY interface mode was not setup. Set to MII.\n"); + value = 0x1; + break; + } + + sh_eth_write(ndev, value, RMII_MII); +} +#endif + /* There is CPU dependent code */ #if defined(CONFIG_CPU_SUBTYPE_SH7724) #define SH_ETH_RESET_DEFAULT 1 @@ -283,6 +311,7 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp) #elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) #define SH_ETH_HAS_TSU 1 static void sh_eth_reset_hw_crc(struct net_device *ndev); + static void sh_eth_chip_reset(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -292,35 +321,6 @@ static void sh_eth_chip_reset(struct net_device *ndev) mdelay(1); } -static void sh_eth_reset(struct net_device *ndev) -{ - int cnt = 100; - - sh_eth_write(ndev, EDSR_ENALL, EDSR); - sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR); - while (cnt > 0) { - if (!(sh_eth_read(ndev, EDMR) & 0x3)) - break; - mdelay(1); - cnt--; - } - if (cnt == 0) - printk(KERN_ERR "Device reset fail\n"); - - /* Table Init */ - sh_eth_write(ndev, 0x0, TDLAR); - sh_eth_write(ndev, 0x0, TDFAR); - sh_eth_write(ndev, 0x0, TDFXR); - sh_eth_write(ndev, 0x0, TDFFR); - sh_eth_write(ndev, 0x0, RDLAR); - sh_eth_write(ndev, 0x0, RDFAR); - sh_eth_write(ndev, 0x0, RDFXR); - sh_eth_write(ndev, 0x0, RDFFR); - - /* Reset HW CRC register */ - sh_eth_reset_hw_crc(ndev); -} - static void sh_eth_set_duplex(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -377,9 +377,43 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .tsu = 1, #if defined(CONFIG_CPU_SUBTYPE_SH7734) .hw_crc = 1, + .select_mii = 1, #endif }; +static void sh_eth_reset(struct net_device *ndev) +{ + int cnt = 100; + + sh_eth_write(ndev, EDSR_ENALL, EDSR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR); + while (cnt > 0) { + if (!(sh_eth_read(ndev, EDMR) & 0x3)) + break; + mdelay(1); + cnt--; + } + if (cnt == 0) + printk(KERN_ERR "Device reset fail\n"); + + /* Table Init */ + sh_eth_write(ndev, 0x0, TDLAR); + sh_eth_write(ndev, 0x0, TDFAR); + sh_eth_write(ndev, 0x0, TDFXR); + sh_eth_write(ndev, 0x0, TDFFR); + sh_eth_write(ndev, 0x0, RDLAR); + sh_eth_write(ndev, 0x0, RDFAR); + sh_eth_write(ndev, 0x0, RDFXR); + sh_eth_write(ndev, 0x0, RDFFR); + + /* Reset HW CRC register */ + sh_eth_reset_hw_crc(ndev); + + /* Select MII mode */ + if (sh_eth_my_cpu_data.select_mii) + sh_eth_select_mii(ndev); +} + static void sh_eth_reset_hw_crc(struct net_device *ndev) { if (sh_eth_my_cpu_data.hw_crc) @@ -391,25 +425,12 @@ static void sh_eth_reset_hw_crc(struct net_device *ndev) static void sh_eth_chip_reset(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - unsigned long mii; /* reset device */ sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR); mdelay(1); - switch (mdp->phy_interface) { - case PHY_INTERFACE_MODE_GMII: - mii = 2; - break; - case PHY_INTERFACE_MODE_MII: - mii = 1; - break; - case PHY_INTERFACE_MODE_RMII: - default: - mii = 0; - break; - } - sh_eth_write(ndev, mii, RMII_MII); + sh_eth_select_mii(ndev); } static void sh_eth_reset(struct net_device *ndev) @@ -492,6 +513,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .no_trimd = 1, .no_ade = 1, .tsu = 1, + .select_mii = 1, }; #elif defined(CONFIG_CPU_SUBTYPE_SH7619) diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 57b8e1fc5d15..d6763b1392d7 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -757,6 +757,7 @@ struct sh_eth_cpu_data { unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */ unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */ unsigned hw_crc:1; /* E-DMAC have CSMR */ + unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */ }; struct sh_eth_private { -- GitLab From 5cee1d37c9f565f1aa515408863dbb13db67dab9 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 25 Jun 2012 17:35:12 +0000 Subject: [PATCH 2815/6849] net/sh-eth: Check return value of sh_eth_reset when chip reset fail The sh_eth_reset function resets chip, but this performs nothing when failed. This changes sh_eth_reset return an error, when this failed in reset. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 88 +++++++++++++++++---------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 8d696e0c082b..326cb91abdad 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -130,6 +130,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { #elif defined(CONFIG_CPU_SUBTYPE_SH7757) #define SH_ETH_HAS_BOTH_MODULES 1 #define SH_ETH_HAS_TSU 1 +static int sh_eth_check_reset(struct net_device *ndev); + static void sh_eth_set_duplex(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -204,23 +206,19 @@ static void sh_eth_chip_reset_giga(struct net_device *ndev) } static int sh_eth_is_gether(struct sh_eth_private *mdp); -static void sh_eth_reset(struct net_device *ndev) +static int sh_eth_reset(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - int cnt = 100; + int ret = 0; if (sh_eth_is_gether(mdp)) { sh_eth_write(ndev, 0x03, EDSR); sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR); - while (cnt > 0) { - if (!(sh_eth_read(ndev, EDMR) & 0x3)) - break; - mdelay(1); - cnt--; - } - if (cnt < 0) - printk(KERN_ERR "Device reset fail\n"); + + ret = sh_eth_check_reset(ndev); + if (ret) + goto out; /* Table Init */ sh_eth_write(ndev, 0x0, TDLAR); @@ -238,6 +236,9 @@ static void sh_eth_reset(struct net_device *ndev) sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR); } + +out: + return ret; } static void sh_eth_set_duplex_giga(struct net_device *ndev) @@ -310,6 +311,7 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp) #elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) #define SH_ETH_HAS_TSU 1 +static int sh_eth_check_reset(struct net_device *ndev); static void sh_eth_reset_hw_crc(struct net_device *ndev); static void sh_eth_chip_reset(struct net_device *ndev) @@ -381,20 +383,16 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { #endif }; -static void sh_eth_reset(struct net_device *ndev) +static int sh_eth_reset(struct net_device *ndev) { - int cnt = 100; + int ret = 0; sh_eth_write(ndev, EDSR_ENALL, EDSR); sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR); - while (cnt > 0) { - if (!(sh_eth_read(ndev, EDMR) & 0x3)) - break; - mdelay(1); - cnt--; - } - if (cnt == 0) - printk(KERN_ERR "Device reset fail\n"); + + ret = sh_eth_check_reset(ndev); + if (ret) + goto out; /* Table Init */ sh_eth_write(ndev, 0x0, TDLAR); @@ -412,6 +410,8 @@ static void sh_eth_reset(struct net_device *ndev) /* Select MII mode */ if (sh_eth_my_cpu_data.select_mii) sh_eth_select_mii(ndev); +out: + return ret; } static void sh_eth_reset_hw_crc(struct net_device *ndev) @@ -422,6 +422,8 @@ static void sh_eth_reset_hw_crc(struct net_device *ndev) #elif defined(CONFIG_ARCH_R8A7740) #define SH_ETH_HAS_TSU 1 +static int sh_eth_check_reset(struct net_device *ndev); + static void sh_eth_chip_reset(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -433,20 +435,16 @@ static void sh_eth_chip_reset(struct net_device *ndev) sh_eth_select_mii(ndev); } -static void sh_eth_reset(struct net_device *ndev) +static int sh_eth_reset(struct net_device *ndev) { - int cnt = 100; + int ret = 0; sh_eth_write(ndev, EDSR_ENALL, EDSR); sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR); - while (cnt > 0) { - if (!(sh_eth_read(ndev, EDMR) & 0x3)) - break; - mdelay(1); - cnt--; - } - if (cnt == 0) - printk(KERN_ERR "Device reset fail\n"); + + ret = sh_eth_check_reset(ndev); + if (ret) + goto out; /* Table Init */ sh_eth_write(ndev, 0x0, TDLAR); @@ -457,6 +455,9 @@ static void sh_eth_reset(struct net_device *ndev) sh_eth_write(ndev, 0x0, RDFAR); sh_eth_write(ndev, 0x0, RDFXR); sh_eth_write(ndev, 0x0, RDFFR); + +out: + return ret; } static void sh_eth_set_duplex(struct net_device *ndev) @@ -565,11 +566,31 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) #if defined(SH_ETH_RESET_DEFAULT) /* Chip Reset */ -static void sh_eth_reset(struct net_device *ndev) +static int sh_eth_reset(struct net_device *ndev) { sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR); mdelay(3); sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR); + + return 0; +} +#else +static int sh_eth_check_reset(struct net_device *ndev) +{ + int ret = 0; + int cnt = 100; + + while (cnt > 0) { + if (!(sh_eth_read(ndev, EDMR) & 0x3)) + break; + mdelay(1); + cnt--; + } + if (cnt < 0) { + printk(KERN_ERR "Device reset fail\n"); + ret = -ETIMEDOUT; + } + return ret; } #endif @@ -924,7 +945,9 @@ static int sh_eth_dev_init(struct net_device *ndev) u32 val; /* Soft Reset */ - sh_eth_reset(ndev); + ret = sh_eth_reset(ndev); + if (ret) + goto out; /* Descriptor format */ sh_eth_ring_format(ndev); @@ -998,6 +1021,7 @@ static int sh_eth_dev_init(struct net_device *ndev) netif_start_queue(ndev); +out: return ret; } -- GitLab From 1f129fefd35842bcd450db02b6c63f958384b1b3 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Mon, 25 Jun 2012 20:49:50 +0000 Subject: [PATCH 2816/6849] batman-adv: fix condition in AP isolation During the last conflict resolution involving translation-table.c something went wrong and a condition in the AP isolation code was reversed. This patch fixes this problem. Signed-off-by: Antonio Quartulli Signed-off-by: David S. Miller --- net/batman-adv/translation-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index cf7988342f27..e4f27a872c9c 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -2187,7 +2187,7 @@ bool batadv_is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, if (!tt_global_entry) goto out; - if (_batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) + if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) goto out; ret = true; -- GitLab From 29cb99de4dafc53f75389bbe0173af4385a2ed1d Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Mon, 25 Jun 2012 20:49:51 +0000 Subject: [PATCH 2817/6849] batman-adv: fix global TT entry deletion During the last merge involving translation-table.c something went wrong and two lines disappeared from translation-table.c. This patch recovers them. Signed-off-by: Antonio Quartulli Signed-off-by: David S. Miller --- net/batman-adv/translation-table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index e4f27a872c9c..c673b58f3ee1 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -149,6 +149,8 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) static void batadv_tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) { + /* to avoid race conditions, immediately decrease the tt counter */ + atomic_dec(&orig_entry->orig_node->tt_size); call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); } -- GitLab From df67e6c9a6ca59ca96bdd46a500ae9dd596f427c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 00:10:09 -0700 Subject: [PATCH 2818/6849] ipv4: Remove unnecessary code from rt_check_expire(). IPv4 routing cache entries no longer use dst->expires, because the metrics, PMTU, and redirect information are stored in the inetpeer cache. Signed-off-by: David S. Miller --- net/ipv4/route.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 8d62d85e68dc..846961c6cbe1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -870,34 +870,22 @@ static void rt_check_expire(void) while ((rth = rcu_dereference_protected(*rthp, lockdep_is_held(rt_hash_lock_addr(i)))) != NULL) { prefetch(rth->dst.rt_next); - if (rt_is_expired(rth)) { + if (rt_is_expired(rth) || + rt_may_expire(rth, tmo, ip_rt_gc_timeout)) { *rthp = rth->dst.rt_next; rt_free(rth); continue; } - if (rth->dst.expires) { - /* Entry is expired even if it is in use */ - if (time_before_eq(jiffies, rth->dst.expires)) { -nofree: - tmo >>= 1; - rthp = &rth->dst.rt_next; - /* - * We only count entries on - * a chain with equal hash inputs once - * so that entries for different QOS - * levels, and other non-hash input - * attributes don't unfairly skew - * the length computation - */ - length += has_noalias(rt_hash_table[i].chain, rth); - continue; - } - } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) - goto nofree; - /* Cleanup aged off entries. */ - *rthp = rth->dst.rt_next; - rt_free(rth); + /* We only count entries on a chain with equal + * hash inputs once so that entries for + * different QOS levels, and other non-hash + * input attributes don't unfairly skew the + * length computation + */ + tmo >>= 1; + rthp = &rth->dst.rt_next; + length += has_noalias(rt_hash_table[i].chain, rth); } spin_unlock_bh(rt_hash_lock_addr(i)); sum += length; -- GitLab From 88e920b4505105b710f8d4a535ec02c4078f8e2e Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Thu, 21 Jun 2012 11:09:54 -0700 Subject: [PATCH 2819/6849] nl80211: specify RSSI threshold in scheduled scan Support configuring an RSSI threshold in dBm (s32) when requesting scheduled scan, below which a BSS won't be reported by the cfg80211 driver. Signed-off-by: Thomas Pedersen Signed-off-by: Johannes Berg --- include/linux/nl80211.h | 6 ++++++ include/net/cfg80211.h | 2 ++ net/wireless/nl80211.c | 9 ++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index b7c3b737ddde..c0fc5d277338 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1542,6 +1542,9 @@ enum nl80211_attrs { #define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10 +/* default RSSI threshold for scan results if none specified. */ +#define NL80211_SCAN_RSSI_THOLD_OFF -300 + /** * enum nl80211_iftype - (virtual) interface types * @@ -1974,6 +1977,8 @@ enum nl80211_reg_rule_attr { * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, * only report BSS with matching SSID. + * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a + * BSS in scan results. Filtering is turned off if not specified. * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter * attribute number currently defined * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use @@ -1982,6 +1987,7 @@ enum nl80211_sched_scan_match_attr { __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, NL80211_SCHED_SCAN_MATCH_ATTR_SSID, + NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, /* keep last */ __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f0163a10b8ce..061c01957e54 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1027,6 +1027,7 @@ struct cfg80211_match_set { * @wiphy: the wiphy this was for * @dev: the interface * @channels: channels to scan + * @rssi_thold: don't report scan results below this threshold (in s32 dBm) */ struct cfg80211_sched_scan_request { struct cfg80211_ssid *ssids; @@ -1037,6 +1038,7 @@ struct cfg80211_sched_scan_request { size_t ie_len; struct cfg80211_match_set *match_sets; int n_match_sets; + s32 rssi_thold; /* internal */ struct wiphy *wiphy; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 888fadc4d63e..234ff3bbd104 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -340,6 +340,7 @@ static const struct nla_policy nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY, .len = IEEE80211_MAX_SSID_LEN }, + [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 }, }; /* ifidx get helper */ @@ -4387,7 +4388,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], tmp) { - struct nlattr *ssid; + struct nlattr *ssid, *rssi; nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, nla_data(attr), nla_len(attr), @@ -4403,6 +4404,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->match_sets[i].ssid.ssid_len = nla_len(ssid); } + rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; + if (rssi) + request->rssi_thold = nla_get_u32(rssi); + else + request->rssi_thold = + NL80211_SCAN_RSSI_THOLD_OFF; i++; } } -- GitLab From 171243612f1612402fbf83f3f034a1beefcdea61 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 19 Jun 2012 16:16:22 +0200 Subject: [PATCH 2820/6849] mac80211: remove unused function Remove the unused function is_ieee80211_device(). Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 37eda7e00e03..ec8f53467374 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -175,12 +175,6 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, return cpu_to_le16(dur); } -static inline int is_ieee80211_device(struct ieee80211_local *local, - struct net_device *dev) -{ - return local == wdev_priv(dev->ieee80211_ptr); -} - /* tx handlers */ static ieee80211_tx_result debug_noinline ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) -- GitLab From 371a255e863857f988a91a3850d6feeaa4f3c536 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 19 Jun 2012 15:54:05 +0200 Subject: [PATCH 2821/6849] mac80211: make ieee80211_check_concurrent_iface netdev-independent ieee80211_check_concurrent_iface() need not use the netdev. Remove the use of the netdev here to prepare the function for P2P device addition. Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 576880317d0e..58c2ab3d483a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -97,15 +97,12 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_sub_if_data *nsdata; - struct net_device *dev = sdata->dev; ASSERT_RTNL(); /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { - struct net_device *ndev = nsdata->dev; - - if (ndev != dev && ieee80211_sdata_running(nsdata)) { + if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { /* * Allow only a single IBSS interface to be up at any * time. This is restricted because beacon distribution @@ -124,7 +121,8 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, * The remaining checks are only performed for interfaces * with the same MAC address. */ - if (!ether_addr_equal(dev->dev_addr, ndev->dev_addr)) + if (!ether_addr_equal(sdata->vif.addr, + nsdata->vif.addr)) continue; /* -- GitLab From cc45ae547b960b805ee0b201b3807e93a0060472 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jun 2012 22:30:52 +0200 Subject: [PATCH 2822/6849] mac80211: make __ieee80211_recalc_idle static Since it's not called from any file outside where it's defined, the function can be static if moved up in the file before the callers. Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 1 - net/mac80211/iface.c | 242 ++++++++++++++++++------------------- 2 files changed, 121 insertions(+), 122 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f834a005e1c5..341d77d472d2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1284,7 +1284,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type); void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); void ieee80211_remove_interfaces(struct ieee80211_local *local); -u32 __ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 58c2ab3d483a..0a6b4e1043cb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -43,6 +43,127 @@ */ +static u32 ieee80211_idle_off(struct ieee80211_local *local, + const char *reason) +{ + if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) + return 0; + + local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; + return IEEE80211_CONF_CHANGE_IDLE; +} + +static u32 ieee80211_idle_on(struct ieee80211_local *local) +{ + if (local->hw.conf.flags & IEEE80211_CONF_IDLE) + return 0; + + drv_flush(local, false); + + local->hw.conf.flags |= IEEE80211_CONF_IDLE; + return IEEE80211_CONF_CHANGE_IDLE; +} + +static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) +{ + struct ieee80211_sub_if_data *sdata; + int count = 0; + bool working = false, scanning = false; + unsigned int led_trig_start = 0, led_trig_stop = 0; + struct ieee80211_roc_work *roc; + +#ifdef CONFIG_PROVE_LOCKING + WARN_ON(debug_locks && !lockdep_rtnl_is_held() && + !lockdep_is_held(&local->iflist_mtx)); +#endif + lockdep_assert_held(&local->mtx); + + list_for_each_entry(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) { + sdata->vif.bss_conf.idle = true; + continue; + } + + sdata->old_idle = sdata->vif.bss_conf.idle; + + /* do not count disabled managed interfaces */ + if (sdata->vif.type == NL80211_IFTYPE_STATION && + !sdata->u.mgd.associated && + !sdata->u.mgd.auth_data && + !sdata->u.mgd.assoc_data) { + sdata->vif.bss_conf.idle = true; + continue; + } + /* do not count unused IBSS interfaces */ + if (sdata->vif.type == NL80211_IFTYPE_ADHOC && + !sdata->u.ibss.ssid_len) { + sdata->vif.bss_conf.idle = true; + continue; + } + /* count everything else */ + sdata->vif.bss_conf.idle = false; + count++; + } + + if (!local->ops->remain_on_channel) { + list_for_each_entry(roc, &local->roc_list, list) { + working = true; + roc->sdata->vif.bss_conf.idle = false; + } + } + + if (local->scan_sdata && + !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { + scanning = true; + local->scan_sdata->vif.bss_conf.idle = false; + } + + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + continue; + if (sdata->old_idle == sdata->vif.bss_conf.idle) + continue; + if (!ieee80211_sdata_running(sdata)) + continue; + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); + } + + if (working || scanning) + led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; + else + led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; + + if (count) + led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; + else + led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; + + ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); + + if (working) + return ieee80211_idle_off(local, "working"); + if (scanning) + return ieee80211_idle_off(local, "scanning"); + if (!count) + return ieee80211_idle_on(local); + else + return ieee80211_idle_off(local, "in use"); + + return 0; +} + +void ieee80211_recalc_idle(struct ieee80211_local *local) +{ + u32 chg; + + mutex_lock(&local->iflist_mtx); + chg = __ieee80211_recalc_idle(local); + mutex_unlock(&local->iflist_mtx); + if (chg) + ieee80211_hw_config(local, chg); +} + static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) { int meshhdrlen; @@ -1403,127 +1524,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) list_del(&unreg_list); } -static u32 ieee80211_idle_off(struct ieee80211_local *local, - const char *reason) -{ - if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) - return 0; - - local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; - return IEEE80211_CONF_CHANGE_IDLE; -} - -static u32 ieee80211_idle_on(struct ieee80211_local *local) -{ - if (local->hw.conf.flags & IEEE80211_CONF_IDLE) - return 0; - - drv_flush(local, false); - - local->hw.conf.flags |= IEEE80211_CONF_IDLE; - return IEEE80211_CONF_CHANGE_IDLE; -} - -u32 __ieee80211_recalc_idle(struct ieee80211_local *local) -{ - struct ieee80211_sub_if_data *sdata; - int count = 0; - bool working = false, scanning = false; - unsigned int led_trig_start = 0, led_trig_stop = 0; - struct ieee80211_roc_work *roc; - -#ifdef CONFIG_PROVE_LOCKING - WARN_ON(debug_locks && !lockdep_rtnl_is_held() && - !lockdep_is_held(&local->iflist_mtx)); -#endif - lockdep_assert_held(&local->mtx); - - list_for_each_entry(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) { - sdata->vif.bss_conf.idle = true; - continue; - } - - sdata->old_idle = sdata->vif.bss_conf.idle; - - /* do not count disabled managed interfaces */ - if (sdata->vif.type == NL80211_IFTYPE_STATION && - !sdata->u.mgd.associated && - !sdata->u.mgd.auth_data && - !sdata->u.mgd.assoc_data) { - sdata->vif.bss_conf.idle = true; - continue; - } - /* do not count unused IBSS interfaces */ - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - !sdata->u.ibss.ssid_len) { - sdata->vif.bss_conf.idle = true; - continue; - } - /* count everything else */ - sdata->vif.bss_conf.idle = false; - count++; - } - - if (!local->ops->remain_on_channel) { - list_for_each_entry(roc, &local->roc_list, list) { - working = true; - roc->sdata->vif.bss_conf.idle = false; - } - } - - if (local->scan_sdata && - !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { - scanning = true; - local->scan_sdata->vif.bss_conf.idle = false; - } - - list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type == NL80211_IFTYPE_MONITOR || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - continue; - if (sdata->old_idle == sdata->vif.bss_conf.idle) - continue; - if (!ieee80211_sdata_running(sdata)) - continue; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); - } - - if (working || scanning) - led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; - else - led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; - - if (count) - led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; - else - led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; - - ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); - - if (working) - return ieee80211_idle_off(local, "working"); - if (scanning) - return ieee80211_idle_off(local, "scanning"); - if (!count) - return ieee80211_idle_on(local); - else - return ieee80211_idle_off(local, "in use"); - - return 0; -} - -void ieee80211_recalc_idle(struct ieee80211_local *local) -{ - u32 chg; - - mutex_lock(&local->iflist_mtx); - chg = __ieee80211_recalc_idle(local); - mutex_unlock(&local->iflist_mtx); - if (chg) - ieee80211_hw_config(local, chg); -} - static int netdev_notify(struct notifier_block *nb, unsigned long state, void *ndev) -- GitLab From b955eefc46a6923424cbede2f8ab76c8f5acf056 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 26 Jun 2012 03:14:20 -0700 Subject: [PATCH 2823/6849] ARM: OMAP2: Use hwmod to initialize mmc for 2420 This allows us to pass dma request lines in platform data to MMC driver the same way as we already do for omap2430 and later. Also note that we need to only build this code if MMC_OMAP is selected, so change Makefile accordingly and place it near the MMC_OMAP_HS in the Makefile. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 70 --------------------------------- arch/arm/mach-omap2/msdi.c | 73 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 8cab358603ac..91ef6699df5e 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -27,7 +27,6 @@ #include "iomap.h" #include -#include #include #include #include @@ -603,75 +602,6 @@ static inline void omap_init_aes(void) { } /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) - -static inline void omap242x_mmc_mux(struct omap_mmc_platform_data - *mmc_controller) -{ - if ((mmc_controller->slots[0].switch_pin > 0) && \ - (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, - OMAP_PIN_INPUT_PULLUP); - if ((mmc_controller->slots[0].gpio_wp > 0) && \ - (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, - OMAP_PIN_INPUT_PULLUP); - - omap_mux_init_signal("sdmmc_cmd", 0); - omap_mux_init_signal("sdmmc_clki", 0); - omap_mux_init_signal("sdmmc_clko", 0); - omap_mux_init_signal("sdmmc_dat0", 0); - omap_mux_init_signal("sdmmc_dat_dir0", 0); - omap_mux_init_signal("sdmmc_cmd_dir", 0); - if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { - omap_mux_init_signal("sdmmc_dat1", 0); - omap_mux_init_signal("sdmmc_dat2", 0); - omap_mux_init_signal("sdmmc_dat3", 0); - omap_mux_init_signal("sdmmc_dat_dir1", 0); - omap_mux_init_signal("sdmmc_dat_dir2", 0); - omap_mux_init_signal("sdmmc_dat_dir3", 0); - } - - /* - * Use internal loop-back in MMC/SDIO Module Input Clock - * selection - */ - if (mmc_controller->slots[0].internal_clock) { - u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - v |= (1 << 24); - omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); - } -} - -void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) -{ - struct platform_device *pdev; - struct omap_hwmod *oh; - int id = 0; - char *oh_name = "msdi1"; - char *dev_name = "mmci-omap"; - - if (!mmc_data[0]) { - pr_err("%s fails: Incomplete platform data\n", __func__); - return; - } - - omap242x_mmc_mux(mmc_data[0]); - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up %s\n", oh_name); - return; - } - pdev = omap_device_build(dev_name, id, oh, mmc_data[0], - sizeof(struct omap_mmc_platform_data), NULL, 0, 0); - if (IS_ERR(pdev)) - WARN(1, "Can'd build omap_device for %s:%s.\n", - dev_name, oh->name); -} - -#endif - #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index ef2a6924731a..fb5bc6cf3773 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c @@ -22,11 +22,15 @@ */ #include +#include #include +#include #include #include "common.h" +#include "control.h" +#include "mux.h" /* * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register @@ -86,3 +90,72 @@ int omap_msdi_reset(struct omap_hwmod *oh) return 0; } + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static inline void omap242x_mmc_mux(struct omap_mmc_platform_data + *mmc_controller) +{ + if ((mmc_controller->slots[0].switch_pin > 0) && \ + (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, + OMAP_PIN_INPUT_PULLUP); + if ((mmc_controller->slots[0].gpio_wp > 0) && \ + (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, + OMAP_PIN_INPUT_PULLUP); + + omap_mux_init_signal("sdmmc_cmd", 0); + omap_mux_init_signal("sdmmc_clki", 0); + omap_mux_init_signal("sdmmc_clko", 0); + omap_mux_init_signal("sdmmc_dat0", 0); + omap_mux_init_signal("sdmmc_dat_dir0", 0); + omap_mux_init_signal("sdmmc_cmd_dir", 0); + if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { + omap_mux_init_signal("sdmmc_dat1", 0); + omap_mux_init_signal("sdmmc_dat2", 0); + omap_mux_init_signal("sdmmc_dat3", 0); + omap_mux_init_signal("sdmmc_dat_dir1", 0); + omap_mux_init_signal("sdmmc_dat_dir2", 0); + omap_mux_init_signal("sdmmc_dat_dir3", 0); + } + + /* + * Use internal loop-back in MMC/SDIO Module Input Clock + * selection + */ + if (mmc_controller->slots[0].internal_clock) { + u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + v |= (1 << 24); + omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); + } +} + +void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) +{ + struct platform_device *pdev; + struct omap_hwmod *oh; + int id = 0; + char *oh_name = "msdi1"; + char *dev_name = "mmci-omap"; + + if (!mmc_data[0]) { + pr_err("%s fails: Incomplete platform data\n", __func__); + return; + } + + omap242x_mmc_mux(mmc_data[0]); + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + return; + } + pdev = omap_device_build(dev_name, id, oh, mmc_data[0], + sizeof(struct omap_mmc_platform_data), NULL, 0, 0); + if (IS_ERR(pdev)) + WARN(1, "Can'd build omap_device for %s:%s.\n", + dev_name, oh->name); +} + +#endif -- GitLab From bb44c30e53053c653302b53c8671c3c5ca62e881 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 26 Jun 2012 03:29:57 -0700 Subject: [PATCH 2824/6849] ARM: OMAP2+: nand: fix build error when CONFIG_MTD_ONENAND_OMAP2=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 8259573b (ARM: OMAP2+: nand: Make board_onenand_init() visible to board code) broke the build for configs with OneNAND disabled. By removing the static in the header file, it created a duplicate definition in the .c and the .h files, resuling in a build error: /work/kernel/omap/dev/arch/arm/mach-omap2/board-flash.c:102:111: error: redefinition of 'board_onenand_init' /work/kernel/omap/dev/arch/arm/mach-omap2/board-flash.h:56:51: note: previous definition of 'board_onenand_init' was here make[2]: *** [arch/arm/mach-omap2/board-flash.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [arch/arm/mach-omap2] Error 2 make: *** [sub-make] Error 2 Fix this by removing the duplicate dummy entry from the C file. Cc: Enric Balletbò i Serra Cc: Javier Martinez Canillas Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-flash.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 70a81f900bb5..53c39d239d6e 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -97,11 +97,6 @@ __init board_onenand_init(struct mtd_partition *onenand_parts, gpmc_onenand_init(&board_onenand_data); } -#else -void -__init board_onenand_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs) -{ -} #endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */ #if defined(CONFIG_MTD_NAND_OMAP2) || \ -- GitLab From 7f217d36dce7e3e2789cfbd91ae53a36a98df837 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 26 Jun 2012 18:37:58 +0800 Subject: [PATCH 2825/6849] regulator: arizona-micsupp: Fix choosing selector in arizona_micsupp_map_voltage If min_uV is in the range of: 3250001~3269999, current code uses the equation: selector = DIV_ROUND_UP(min_uV - 1700000, 50000); Then selector will be 32. Then arizona_micsupp_list_voltage returns -EINVAL for this case which is wrong. This patch fixes this issue: If min_uV > 3200000, selector should be ARIZONA_MICSUPP_MAX_SELECTOR. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/arizona-micsupp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 97d85b09a940..fdd7473ada4a 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -57,7 +57,7 @@ static int arizona_micsupp_map_voltage(struct regulator_dev *rdev, if (min_uV < 1700000) min_uV = 1700000; - if (min_uV >= 3300000) + if (min_uV > 3200000) selector = ARIZONA_MICSUPP_MAX_SELECTOR; else selector = DIV_ROUND_UP(min_uV - 1700000, 50000); -- GitLab From e2eb169b1bc207dd1a79109d85b098b241be2e9b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 18 Jun 2012 14:25:27 +0800 Subject: [PATCH 2826/6849] regulator: s5m8767: Convert to regulator_list_voltage_linear In current code, .list_voltage and .set_voltage_sel callbacks for BUCK7 and BUCK8 return -EINVAL. This patch adds s5m8767_buck78_ops for BUCK7 and BUCK8 which does not set .list_voltage, .get_voltage_sel and .set_voltage_sel. ( This has the same effect of returning -EINVAL in the callbacks) Then for all the users of s5m8767_list_voltage, we don't need to worry about the case reg_voltage_map[reg_id] is NULL. So we can convert s5m8767_list_voltage to regulator_list_voltage_linear. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 46 +++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 533bde68e4b7..1ad9c3c0da8d 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -121,27 +121,6 @@ static const struct s5m_voltage_desc *reg_voltage_map[] = { [S5M8767_BUCK9] = &buck_voltage_val3, }; -static int s5m8767_list_voltage(struct regulator_dev *rdev, - unsigned int selector) -{ - const struct s5m_voltage_desc *desc; - int reg_id = rdev_get_id(rdev); - int val; - - if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) - return -EINVAL; - - desc = reg_voltage_map[reg_id]; - if (desc == NULL) - return -EINVAL; - - val = desc->min + desc->step * selector; - if (val > desc->max) - return -EINVAL; - - return val; -} - static unsigned int s5m8767_opmode_reg[][4] = { /* {OFF, ON, LOWPOWER, SUSPEND} */ /* LDO1 ... LDO28 */ @@ -449,7 +428,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, } static struct regulator_ops s5m8767_ops = { - .list_voltage = s5m8767_list_voltage, + .list_voltage = regulator_list_voltage_linear, .is_enabled = s5m8767_reg_is_enabled, .enable = s5m8767_reg_enable, .disable = s5m8767_reg_disable, @@ -458,6 +437,12 @@ static struct regulator_ops s5m8767_ops = { .set_voltage_time_sel = s5m8767_set_voltage_time_sel, }; +static struct regulator_ops s5m8767_buck78_ops = { + .is_enabled = s5m8767_reg_is_enabled, + .enable = s5m8767_reg_enable, + .disable = s5m8767_reg_disable, +}; + #define s5m8767_regulator_desc(_name) { \ .name = #_name, \ .id = S5M8767_##_name, \ @@ -466,6 +451,14 @@ static struct regulator_ops s5m8767_ops = { .owner = THIS_MODULE, \ } +#define s5m8767_regulator_buck78_desc(_name) { \ + .name = #_name, \ + .id = S5M8767_##_name, \ + .ops = &s5m8767_buck78_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ +} + static struct regulator_desc regulators[] = { s5m8767_regulator_desc(LDO1), s5m8767_regulator_desc(LDO2), @@ -501,8 +494,8 @@ static struct regulator_desc regulators[] = { s5m8767_regulator_desc(BUCK4), s5m8767_regulator_desc(BUCK5), s5m8767_regulator_desc(BUCK6), - s5m8767_regulator_desc(BUCK7), - s5m8767_regulator_desc(BUCK8), + s5m8767_regulator_buck78_desc(BUCK7), + s5m8767_regulator_buck78_desc(BUCK8), s5m8767_regulator_desc(BUCK9), }; @@ -751,9 +744,12 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) int id = pdata->regulators[i].id; desc = reg_voltage_map[id]; - if (desc) + if (desc) { regulators[id].n_voltages = (desc->max - desc->min) / desc->step + 1; + regulators[id].min_uV = desc->min; + regulators[id].uV_step = desc->step; + } config.dev = s5m8767->dev; config.init_data = pdata->regulators[i].initdata; -- GitLab From 5aff3a8b20c54888e199e863744848007f1f4120 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 26 Jun 2012 11:16:58 +0100 Subject: [PATCH 2827/6849] regulator: core: Check for failed voltage sets before checking for delay There is no need to consider waiting for the voltage to ramp if we didn't manage to set it and looking at the return value is going to be cheaper than is_enabled(). Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 729b20d1c1de..890fa5eb770d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2143,7 +2143,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, best_val = _regulator_get_voltage(rdev); /* Call set_voltage_time_sel if successfully obtained old_selector */ - if (_regulator_is_enabled(rdev) && ret == 0 && old_selector >= 0 && + if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 && rdev->desc->ops->set_voltage_time_sel) { delay = rdev->desc->ops->set_voltage_time_sel(rdev, -- GitLab From 222cc7b1cefbab1287ed5d5e3cce1f45aec60d39 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Jun 2012 11:39:16 +0100 Subject: [PATCH 2828/6849] regulator: core: Allow multiple requests of a single supply mapping Sometimes it may be useful to allow a device to request a supply multiple times, for example in order to allow framework management of some uses of the supply with some additional driver specific management or in order to allow multiple children of an MFD to work with the supply. Currently this is not possible due to the creation of Solve this by removing the requested_uA entry (we have no current users of this feature anyway) and ignoring errors creating the symlink to the consumer. We should do something nicer than this as this causes sysfs to spew enormous warnings but it allows users to run for now. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/regulator/core.c | 49 ++++------------------------------------ 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 890fa5eb770d..00c787c01f3b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -303,18 +303,6 @@ static int regulator_check_drms(struct regulator_dev *rdev) return 0; } -static ssize_t device_requested_uA_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct regulator *regulator; - - regulator = get_device_regulator(dev); - if (regulator == NULL) - return 0; - - return sprintf(buf, "%d\n", regulator->uA_load); -} - static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1097,48 +1085,27 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, list_add(®ulator->list, &rdev->consumer_list); if (dev) { - /* create a 'requested_microamps_name' sysfs entry */ - size = scnprintf(buf, REG_STR_SIZE, - "microamps_requested_%s-%s", - dev_name(dev), supply_name); - if (size >= REG_STR_SIZE) - goto overflow_err; - - regulator->dev = dev; - sysfs_attr_init(®ulator->dev_attr.attr); - regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL); - if (regulator->dev_attr.attr.name == NULL) - goto attr_name_err; - - regulator->dev_attr.attr.mode = 0444; - regulator->dev_attr.show = device_requested_uA_show; - err = device_create_file(dev, ®ulator->dev_attr); - if (err < 0) { - rdev_warn(rdev, "could not add regulator_dev requested microamps sysfs entry\n"); - goto attr_name_err; - } - - /* also add a link to the device sysfs entry */ + /* Add a link to the device sysfs entry */ size = scnprintf(buf, REG_STR_SIZE, "%s-%s", dev->kobj.name, supply_name); if (size >= REG_STR_SIZE) - goto attr_err; + goto overflow_err; regulator->supply_name = kstrdup(buf, GFP_KERNEL); if (regulator->supply_name == NULL) - goto attr_err; + goto overflow_err; err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj, buf); if (err) { rdev_warn(rdev, "could not add device link %s err %d\n", dev->kobj.name, err); - goto link_name_err; + /* non-fatal */ } } else { regulator->supply_name = kstrdup(supply_name, GFP_KERNEL); if (regulator->supply_name == NULL) - goto attr_err; + goto overflow_err; } regulator->debugfs = debugfs_create_dir(regulator->supply_name, @@ -1165,12 +1132,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, mutex_unlock(&rdev->mutex); return regulator; -link_name_err: - kfree(regulator->supply_name); -attr_err: - device_remove_file(regulator->dev, ®ulator->dev_attr); -attr_name_err: - kfree(regulator->dev_attr.attr.name); overflow_err: list_del(®ulator->list); kfree(regulator); -- GitLab From 9bd0c15fcfb42f6245447c53347d65ad9e72080b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Jun 2012 12:12:30 +1000 Subject: [PATCH 2829/6849] drm/nouveau/fbcon: using nv_two_heads is not a good idea nv_two_heads() was never meant to be used outside of pre-nv50 code. The code checks for >= NV_10 for 2 CRTCs, then downgrades a few specific chipsets to 1 CRTC based on (pci_device & 0x0ff0). The breakage example seen is on GTX 560Ti, with a pciid of 0x1200, which gets detected as an NV20 (0x020x) with 1 CRTC by nv_two_heads(), causing memory corruption because there's actually 2 CRTCs.. This switches fbcon to use the CRTC count directly from the mode_config structure, which will also fix the same issue on Kepler boards which have 4 CRTCs. Signed-off-by: Ben Skeggs Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 153b9a15469b..1074bc5dd418 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -467,7 +467,7 @@ int nouveau_fbcon_init(struct drm_device *dev) nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; ret = drm_fb_helper_init(dev, &nfbdev->helper, - nv_two_heads(dev) ? 2 : 1, 4); + dev->mode_config.num_crtc, 4); if (ret) { kfree(nfbdev); return ret; -- GitLab From 2b6f2c3520124e8bad4bffa71f5b98e602b9cf03 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Mon, 25 Jun 2012 21:30:57 -0600 Subject: [PATCH 2830/6849] PCI: pull pcibios_setup() up into core Currently, all of the architectures implement their own pcibios_setup() routine. Most of the implementations do nothing so this patch introduces a generic (__weak) routine in the core that can be used by all architectures as a default. If necessary, it can be overridden by architecture-specific code. Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 12 ++++++++++++ include/linux/pci.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..c87d518acace 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2665,6 +2665,18 @@ static void __pci_set_master(struct pci_dev *dev, bool enable) dev->is_busmaster = enable; } +/** + * pcibios_setup - process "pci=" kernel boot arguments + * @str: string used to pass in "pci=" kernel boot arguments + * + * Process kernel boot arguments. This is the default implementation. + * Architecture specific implementations can override this as necessary. + */ +char * __weak __init pcibios_setup(char *str) +{ + return str; +} + /** * pcibios_set_master - enable PCI bus-mastering for device dev * @dev: the PCI device to enable diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..f91143e86f85 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -642,6 +642,7 @@ extern int no_pci_devices(void); void pcibios_fixup_bus(struct pci_bus *); int __must_check pcibios_enable_device(struct pci_dev *, int mask); +/* Architecture specific versions may override this (weak) */ char *pcibios_setup(char *str); /* Used only when drivers/pci/setup.c is used */ -- GitLab From 9d74c5c0a3194f7a4351c47db09449a2e1d97ec1 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Mon, 25 Jun 2012 21:31:10 -0600 Subject: [PATCH 2831/6849] alpha/PCI: factor out pcibios_setup() The PCI core provides a generic pcibios_setup() routine. Drop this architecture-specific version in favor of that. Acked-by: Richard Henderson Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas --- arch/alpha/kernel/pci.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 1a629636cc16..133d2d445a36 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -198,12 +198,6 @@ pcibios_init(void) subsys_initcall(pcibios_init); -char * __devinit -pcibios_setup(char *str) -{ - return str; -} - #ifdef ALPHA_RESTORE_SRM_SETUP static struct pdev_srm_saved_conf *srm_saved_configs; -- GitLab From ee48df57c920ab876dd8cf0dcfe5b8893b98e934 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 26 Jun 2012 14:54:32 +0200 Subject: [PATCH 2832/6849] ALSA: hda - Fix memory leaks in Realtek & Conexant codec parsers When moved to the helper code, forgot to release the verb arrays. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_auto_parser.c | 1 - sound/pci/hda/hda_auto_parser.h | 10 ++++++++++ sound/pci/hda/patch_conexant.c | 5 ++++- sound/pci/hda/patch_realtek.c | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 6e9ef3e25093..f7520b9f909c 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -618,7 +618,6 @@ int snd_hda_gen_add_verbs(struct hda_gen_spec *spec, const struct hda_verb *list) { const struct hda_verb **v; - snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8); v = snd_array_new(&spec->verbs); if (!v) return -ENOMEM; diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index 2a7889dfbd1b..632ad0ad3007 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h @@ -157,4 +157,14 @@ void snd_hda_pick_fixup(struct hda_codec *codec, const struct snd_pci_quirk *quirk, const struct hda_fixup *fixlist); +static inline void snd_hda_gen_init(struct hda_gen_spec *spec) +{ + snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8); +} + +static inline void snd_hda_gen_free(struct hda_gen_spec *spec) +{ + snd_array_free(&spec->verbs); +} + #endif /* __SOUND_HDA_AUTO_PARSER_H */ diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2af0868f78ad..2bf99fc1cbf2 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -445,8 +445,10 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { + struct conexant_spec *spec = codec->spec; + snd_hda_gen_free(&spec->gen); snd_hda_detach_beep_device(codec); - kfree(codec->spec); + kfree(spec); } static const struct snd_kcontrol_new cxt_capture_mixers[] = { @@ -4498,6 +4500,7 @@ static int patch_conexant_auto(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; + snd_hda_gen_init(&spec->gen); switch (codec->vendor_id) { case 0x14f15045: diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a5534b384609..5ccf10a4d593 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2289,6 +2289,7 @@ static void alc_free(struct hda_codec *codec) alc_shutup(codec); alc_free_kctls(codec); alc_free_bind_ctls(codec); + snd_hda_gen_free(&spec->gen); kfree(spec); snd_hda_detach_beep_device(codec); } @@ -4253,6 +4254,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) return -ENOMEM; codec->spec = spec; spec->mixer_nid = mixer_nid; + snd_hda_gen_init(&spec->gen); err = alc_codec_rename_from_preset(codec); if (err < 0) { -- GitLab From 59cad16bc6deb85bd2a464da92bbaae289f0286f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 26 Jun 2012 15:00:20 +0200 Subject: [PATCH 2833/6849] ALSA: hda - Fix memory leaks at module unload Some caches aren't released properly at module unloading time. Cc: [v3.4+] Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7504e62188d6..854dd0c25f89 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1184,6 +1184,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) { if (!codec) return; + snd_hda_jack_tbl_clear(codec); restore_init_pincfgs(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); @@ -1192,6 +1193,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) list_del(&codec->list); snd_array_free(&codec->mixers); snd_array_free(&codec->nids); + snd_array_free(&codec->cvt_setups); snd_array_free(&codec->conn_lists); snd_array_free(&codec->spdif_out); codec->bus->caddr_tbl[codec->addr] = NULL; -- GitLab From 09a6071bfe0ecf41376ad6a143508c8b2f93f52b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 26 Jun 2012 15:01:33 +0200 Subject: [PATCH 2834/6849] ALSA: hda - Initialize caches at codec reconfiguration Better to clean up the caches for avoiding inconsistent codec state after the reconfiguration. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 854dd0c25f89..51cb2a2e4fce 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2335,6 +2335,8 @@ int snd_hda_codec_reset(struct hda_codec *codec) /* free only driver_pins so that init_pins + user_pins are restored */ snd_array_free(&codec->driver_pins); restore_pincfgs(codec); + snd_array_free(&codec->cvt_setups); + snd_array_free(&codec->spdif_out); codec->num_pcms = 0; codec->pcm_info = NULL; codec->preset = NULL; -- GitLab From 1b6b7c9ff3514772958c075f8c89e42dddf6a4d8 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 26 Jun 2012 07:58:23 -0700 Subject: [PATCH 2835/6849] x86, cpufeature: Remove stray %s, add -w to mkcapflags.pl There was a stray %s left from testing, remove it. Add -w to the #! line (which is parsed by Perl even if the Perl interpreter is invoked explicitly on the command line) to catch these kinds of errors in the future. Reported-by: Jean Delvare Link: http://lkml.kernel.org/r/20120626143246.0c9bf301@endymion.delvare Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mkcapflags.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mkcapflags.pl b/arch/x86/kernel/cpu/mkcapflags.pl index 0c5b54919c7b..c7b3fe2d72e0 100644 --- a/arch/x86/kernel/cpu/mkcapflags.pl +++ b/arch/x86/kernel/cpu/mkcapflags.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # # Generate the x86_cap_flags[] array from include/asm-x86/cpufeature.h # @@ -29,7 +29,7 @@ while (defined($line = )) { print STDERR "$in: duplicate feature name: $feature\n"; $err++; } - printf OUT "\t%-32s = \"%s\",%s\n", "[$macro]", $feature; + printf OUT "\t%-32s = \"%s\",\n", "[$macro]", $feature; } } print OUT "};\n"; -- GitLab From 6e1c39c6b00d9141a82c231ba7c5e5b1716974b2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 26 Jun 2012 17:35:10 +0200 Subject: [PATCH 2836/6849] ALSA: hda - Fix power-map regression for HP dv6 & co The recent fix for power-map controls (commit b0791dda813) caused regressions on some other HP laptops. They have fixed pins but these pins are exposed as jack-detectable. Thus the driver tries to control the power-map dynamically per jack detection where it never gets on. This patch adds the check of connection and it assumes the no jack detection is available for fixed pins no matter what pin capability says. BugLink: http://bugs.launchpad.net/bugs/1013183 Reported-by: Luis Henriques Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7db8228f1b88..07675282015a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4367,7 +4367,7 @@ static int stac92xx_init(struct hda_codec *codec) AC_PINCTL_IN_EN); for (i = 0; i < spec->num_pwrs; i++) { hda_nid_t nid = spec->pwr_nids[i]; - int pinctl, def_conf; + unsigned int pinctl, def_conf; def_conf = snd_hda_codec_get_pincfg(codec, nid); def_conf = get_defcfg_connect(def_conf); @@ -4376,6 +4376,11 @@ static int stac92xx_init(struct hda_codec *codec) stac_toggle_power_map(codec, nid, 0); continue; } + if (def_conf == AC_JACK_PORT_FIXED) { + /* no need for jack detection for fixed pins */ + stac_toggle_power_map(codec, nid, 1); + continue; + } /* power on when no jack detection is available */ /* or when the VREF is used for controlling LED */ if (!spec->hp_detect || -- GitLab From e59bec1628654b6dcbad4e64d43c41c1f31d216c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 25 Jun 2012 14:15:55 +0300 Subject: [PATCH 2837/6849] wl18xx: deprecate PG1 support The new PG2 version of the chip has a few differences in terms of FW API if compared to PG1. PG1 is just a sample that shouldn't be used in real life, so to avoid having to handle both separately, mark the PG1 version as deprecated and bail out during probe. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl18xx/acx.h | 34 +++++++++----------- drivers/net/wireless/ti/wl18xx/main.c | 45 +++++---------------------- 2 files changed, 22 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h index ebbaf611e97b..e2609a6b7341 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.h +++ b/drivers/net/wireless/ti/wl18xx/acx.h @@ -32,25 +32,21 @@ enum { /* numbers of bits the length field takes (add 1 for the actual number) */ #define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 -#define WL18XX_ACX_EVENTS_VECTOR_PG1 (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_INIT_COMPLETE | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_CMD_COMPLETE | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -#define WL18XX_ACX_EVENTS_VECTOR_PG2 (WL18XX_ACX_EVENTS_VECTOR_PG1 | \ - WL1271_ACX_SW_INTR_WATCHDOG) - -#define WL18XX_INTR_MASK_PG1 (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -#define WL18XX_INTR_MASK_PG2 (WL18XX_INTR_MASK_PG1 | \ - WL1271_ACX_SW_INTR_WATCHDOG) +#define WL18XX_ACX_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_INIT_COMPLETE | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_CMD_COMPLETE | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA | \ + WL1271_ACX_SW_INTR_WATCHDOG) + +#define WL18XX_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA | \ + WL1271_ACX_SW_INTR_WATCHDOG) struct wl18xx_acx_host_config_bitmap { struct acx_header header; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index c25b960faa29..5e583be8f674 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -612,20 +612,11 @@ static int wl18xx_identify_chip(struct wl1271 *wl) WLCORE_QUIRK_TX_PAD_LAST_FRAME; break; case CHIP_ID_185x_PG10: - wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", - wl->chip.id); - wl->sr_fw_name = WL18XX_FW_NAME; - /* wl18xx uses the same firmware for PLT */ - wl->plt_fw_name = WL18XX_FW_NAME; - wl->quirks |= WLCORE_QUIRK_NO_ELP | - WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | - WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | - WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; - - /* PG 1.0 has some problems with MCS_13, so disable it */ - wl->ht_cap[IEEE80211_BAND_2GHZ].mcs.rx_mask[1] &= ~BIT(5); + wl1271_warning("chip id 0x%x (185x PG10) is deprecated", + wl->chip.id); + ret = -ENODEV; + goto out; - break; default: wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); ret = -ENODEV; @@ -776,21 +767,14 @@ out: static int wl18xx_set_mac_and_phy(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; - size_t len; int ret; - /* the parameters struct is smaller for PG1 */ - if (wl->chip.id == CHIP_ID_185x_PG10) - len = offsetof(struct wl18xx_mac_and_phy_params, psat) + 1; - else - len = sizeof(struct wl18xx_mac_and_phy_params); - ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); if (ret < 0) goto out; ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, - len, false); + sizeof(struct wl18xx_mac_and_phy_params), false); out: return ret; @@ -801,13 +785,8 @@ static int wl18xx_enable_interrupts(struct wl1271 *wl) u32 event_mask, intr_mask; int ret; - if (wl->chip.id == CHIP_ID_185x_PG10) { - event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1; - intr_mask = WL18XX_INTR_MASK_PG1; - } else { - event_mask = WL18XX_ACX_EVENTS_VECTOR_PG2; - intr_mask = WL18XX_INTR_MASK_PG2; - } + event_mask = WL18XX_ACX_EVENTS_VECTOR; + intr_mask = WL18XX_INTR_MASK; ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); if (ret < 0) @@ -1049,16 +1028,6 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, } else if (!strcmp(ht_mode_param, "mimo")) { wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); - /* - * PG 1.0 has some problems with MCS_13, so disable it - * - * TODO: instead of hacking this in here, we should - * make it more general and change a bit in the - * wlvif->rate_set instead. - */ - if (wl->chip.id == CHIP_ID_185x_PG10) - return CONF_TX_MIMO_RATES & ~CONF_HW_BIT_RATE_MCS_13; - return CONF_TX_MIMO_RATES; } else { return 0; -- GitLab From 8b425e62d96a3b3a3cc68e6203267f92d1a01946 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 25 Jun 2012 14:41:20 +0300 Subject: [PATCH 2838/6849] wlcore: fix some failure cases in wlcore_probe() We need to release the IRQ if hw_info() or identify_chip() fails. And we need unregister the HW with mac80211 if there are any failures after it's registered. Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 372ccf277b1e..c5a9ffe6cc91 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5520,12 +5520,12 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) ret = wl12xx_get_hw_info(wl); if (ret < 0) { wl1271_error("couldn't get hw info"); - goto out; + goto out_irq; } ret = wl->ops->identify_chip(wl); if (ret < 0) - goto out; + goto out_irq; ret = wl1271_init_ieee80211(wl); if (ret) @@ -5539,7 +5539,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) ret = device_create_file(wl->dev, &dev_attr_bt_coex_state); if (ret < 0) { wl1271_error("failed to create sysfs file bt_coex_state"); - goto out_irq; + goto out_unreg; } /* Create sysfs file to get HW PG version */ @@ -5564,6 +5564,9 @@ out_hw_pg_ver: out_bt_coex_state: device_remove_file(wl->dev, &dev_attr_bt_coex_state); +out_unreg: + wl1271_unregister_hw(wl); + out_irq: free_irq(wl->irq, wl); -- GitLab From 7a50bdfb81a6bff96100cd2a2c95f8b3cf05bc0c Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 26 Jun 2012 10:41:15 +0300 Subject: [PATCH 2839/6849] wlcore: fix broken TX due to wrong queuing of recovery commit 14bba17b "wl12xx: Propagate errors from wl1271_raw_write32" breaks down TX in certain scenarios. wl1271_irq_locked() propagates errors from wl1271_tx_work_locked however it may return -EBUSY when the FW queues are full which is a legitimate case and not a a real error. In this case a recovery is triggered by wl1271_irq and this keeps repeating itself so TX is completely broken. Fix it by avoiding propagating return values as errors even if they aren't. Only bus (SDIO or SPI) ops failures would be progagated as only these should trigger recovery. Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/tx.c | 35 ++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index b5211be229d9..6a28aeecf004 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -352,8 +352,10 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool is_dummy; bool is_gem = false; - if (!skb) + if (!skb) { + wl1271_error("discarding null skb"); return -EINVAL; + } info = IEEE80211_SKB_CB(skb); @@ -662,6 +664,16 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids) } } +/* + * Returns failure values only in case of failed bus ops within this function. + * wl1271_prepare_tx_frame retvals won't be returned in order to avoid + * triggering recovery by higher layers when not necessary. + * In case a FW command fails within wl1271_prepare_tx_frame fails a recovery + * will be queued in wl1271_cmd_send. -EAGAIN/-EBUSY from prepare_tx_frame + * can occur and are legitimate so don't propagate. -EINVAL will emit a WARNING + * within prepare_tx_frame code but there's nothing we should do about those + * as well. + */ int wlcore_tx_work_locked(struct wl1271 *wl) { struct wl12xx_vif *wlvif; @@ -671,9 +683,10 @@ int wlcore_tx_work_locked(struct wl1271 *wl) bool sent_packets = false; unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; int ret = 0; + int bus_ret = 0; if (unlikely(wl->state == WL1271_STATE_OFF)) - return -EIO; + return 0; while ((skb = wl1271_skb_dequeue(wl))) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -694,9 +707,9 @@ int wlcore_tx_work_locked(struct wl1271 *wl) buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); - ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, - wl->aggr_buf, buf_offset, true); - if (ret < 0) + bus_ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, + wl->aggr_buf, buf_offset, true); + if (bus_ret < 0) goto out; sent_packets = true; @@ -734,9 +747,9 @@ int wlcore_tx_work_locked(struct wl1271 *wl) out_ack: if (buf_offset) { buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); - ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); - if (ret < 0) + bus_ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + if (bus_ret < 0) goto out; sent_packets = true; @@ -747,9 +760,9 @@ out_ack: * required for older hardware revisions */ if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) { - ret = wlcore_write32(wl, WL12XX_HOST_WR_ACCESS, + bus_ret = wlcore_write32(wl, WL12XX_HOST_WR_ACCESS, wl->tx_packets_count); - if (ret < 0) + if (bus_ret < 0) goto out; } @@ -758,7 +771,7 @@ out_ack: wl12xx_rearm_rx_streaming(wl, active_hlids); out: - return ret; + return bus_ret; } void wl1271_tx_work(struct work_struct *work) -- GitLab From 6c15c1aae206dc275a948a5e50f965c2382c6866 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 26 Jun 2012 10:41:16 +0300 Subject: [PATCH 2840/6849] wlcore: queue recovery in case of bus errors during cmd_remove_peer Following the addition of propagating errors from the bus ops there's a need to distinguish between bus errors (including timeout) and a legitimate timeout occuring in cmd_wait_for_event_or_timeout. In case of real bus errors we need to queue recovery even in cases where a timeout on a response from the FW to a command is acceptable. Reported-by: Arik Nemtsov Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.c | 29 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 84dd808f65fa..ef139383ee93 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -133,24 +133,27 @@ fail: * Poll the mailbox event field until any of the bits in the mask is set or a * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) */ -static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) +static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, + u32 mask, bool *timeout) { u32 *events_vector; u32 event; - unsigned long timeout; + unsigned long timeout_time; int ret = 0; + *timeout = false; + events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA); if (!events_vector) return -ENOMEM; - timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); + timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); do { - if (time_after(jiffies, timeout)) { + if (time_after(jiffies, timeout_time)) { wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", (int)mask); - ret = -ETIMEDOUT; + *timeout = true; goto out; } @@ -180,9 +183,10 @@ out: static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) { int ret; + bool timeout = false; - ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask); - if (ret != 0) { + ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask, &timeout); + if (ret != 0 || timeout) { wl12xx_queue_recovery_work(wl); return ret; } @@ -1435,6 +1439,7 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) { struct wl12xx_cmd_remove_peer *cmd; int ret; + bool timeout = false; wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid); @@ -1455,12 +1460,16 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) goto out_free; } + ret = wl1271_cmd_wait_for_event_or_timeout(wl, + PEER_REMOVE_COMPLETE_EVENT_ID, + &timeout); /* * We are ok with a timeout here. The event is sometimes not sent - * due to a firmware bug. + * due to a firmware bug. In case of another error (like SDIO timeout) + * queue a recovery. */ - wl1271_cmd_wait_for_event_or_timeout(wl, - PEER_REMOVE_COMPLETE_EVENT_ID); + if (ret) + wl12xx_queue_recovery_work(wl); out_free: kfree(cmd); -- GitLab From 680c6055b9bebdf07fc2d5ebe816a14c7daecdc1 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 26 Jun 2012 10:41:17 +0300 Subject: [PATCH 2841/6849] wlcore: print stack trace in every recovery As recovery queuing can now occur from multiple code paths it's convenient to know what triggered it in all cases other than an intended recovery which is part of the switch between single role to multi role. Signed-off-by: Eyal Shapira Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wlcore/cmd.c | 1 - drivers/net/wireless/ti/wlcore/main.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index ef139383ee93..56c7a2342fdf 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -124,7 +124,6 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, return 0; fail: - WARN_ON(1); wl12xx_queue_recovery_work(wl); return ret; } diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index c5a9ffe6cc91..2240cca597ac 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -772,6 +772,8 @@ out: void wl12xx_queue_recovery_work(struct wl1271 *wl) { + WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); + /* Avoid a recursive recovery */ if (!test_and_set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { wlcore_disable_interrupts_nosync(wl); -- GitLab From 5a2766abe42a0fa10a6a7177bece2a205f66bdb9 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 24 Jun 2012 11:06:29 -0500 Subject: [PATCH 2842/6849] rtlwifi: Fix IRQ disabled warning The PCI-based drivers can generate the following warning: [ 9497.776350] ------------[ cut here ]------------ [ 9497.776366] WARNING: at kernel/softirq.c:159 local_bh_enable_ip+0x7a/0xa0() [ 9497.776370] Hardware name: 05794NC [ 9497.776597] Pid: 6413, comm: hostapd Not tainted 3.3.0-4.fc16.x86_64 #1 [ 9497.776601] Call Trace: [ 9497.776612] [] warn_slowpath_common+0x7f/0xc0 [ 9497.776633] [] ? rtl_pci_reset_trx_ring+0x199/0x230 [rtlwifi] [ 9497.776640] [] warn_slowpath_null+0x1a/0x20 [ 9497.776646] [] local_bh_enable_ip+0x7a/0xa0 [ 9497.776654] [] _raw_spin_unlock_bh+0x16/0x20 [ 9497.776671] [] destroy_conntrack+0x9e/0x120 [nf_conntrack] [ 9497.776681] [] nf_conntrack_destroy+0x17/0x20 [ 9497.776689] [] skb_release_head_state+0xe5/0x120 [ 9497.776695] [] __kfree_skb+0x16/0xa0 [ 9497.776700] [] kfree_skb+0x45/0xc0 [ 9497.776717] [] rtl_pci_reset_trx_ring+0x199/0x230 [rtlwifi] [ 9497.776734] [] rtl_pci_start+0x25/0x1d0 [rtlwifi] [ 9497.776750] [] rtl_op_start+0x55/0x90 [rtlwifi] [ 9497.776785] [] ieee80211_do_open+0x296/0xa10 [mac80211] [ 9497.776794] [] ? notifier_call_chain+0x4d/0x70 [ 9497.776828] [] ieee80211_open+0x6d/0x80 [mac80211] [ 9497.776836] [] __dev_open+0x8f/0xe0 [ 9497.776842] [] __dev_change_flags+0xa1/0x180 [ 9497.776847] [] dev_change_flags+0x28/0x70 [ 9497.776856] [] devinet_ioctl+0x61d/0x7b0 [ 9497.776863] [] inet_ioctl+0x75/0x90 [ 9497.776870] [] sock_do_ioctl+0x30/0x70 [ 9497.776876] [] sock_ioctl+0x79/0x2f0 [ 9497.776885] [] do_vfs_ioctl+0x98/0x550 [ 9497.776891] [] sys_ioctl+0x91/0xa0 [ 9497.776897] [] system_call_fastpath+0x16/0x1b [ 9497.776902] ---[ end trace 22886c442489082d ]--- The cause is due to calling kfree_skb() with interrupts disabled. This bug is discussed in https://bugzilla.redhat.com/show_bug.cgi?id=797709. Reported-and-Tested by: Ivan Ivanovich Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 2062ea1d7c80..36bffbc4519e 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1273,17 +1273,18 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) *after reset, release previous pending packet, *and force the tx idx to the first one */ - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { if (rtlpci->tx_ring[i].desc) { struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i]; while (skb_queue_len(&ring->queue)) { - struct rtl_tx_desc *entry = - &ring->desc[ring->idx]; - struct sk_buff *skb = - __skb_dequeue(&ring->queue); + struct rtl_tx_desc *entry; + struct sk_buff *skb; + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, + flags); + entry = &ring->desc[ring->idx]; + skb = __skb_dequeue(&ring->queue); pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops-> get_desc((u8 *) @@ -1291,15 +1292,15 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) true, HW_DESC_TXBUFF_ADDR), skb->len, PCI_DMA_TODEVICE); - kfree_skb(skb); ring->idx = (ring->idx + 1) % ring->entries; + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, + flags); + kfree_skb(skb); } ring->idx = 0; } } - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - return 0; } -- GitLab From 46e5129ba6e00ff110df17338bc8fe5ee8f2f8b2 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 24 Jun 2012 14:44:36 -0500 Subject: [PATCH 2843/6849] rtlwifi: rtl8192se: Fix double inclusion of header pci.h The command "make includecheck" yields the following for the rtlwifi tree: /home/finger/linux-2.6/drivers/net/wireless/rtlwifi/rtl8192se/sw.c: ../pci.h is included more than once. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 730bcc919529..ad4b4803482d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -29,7 +29,6 @@ #include "../wifi.h" #include "../core.h" -#include "../pci.h" #include "../base.h" #include "../pci.h" #include "reg.h" -- GitLab From 313eb87f1e2f93d83836de7f5c1947b75d7752c8 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 25 Jun 2012 07:15:22 +0200 Subject: [PATCH 2844/6849] ath9k: raise aggregation limit to 64k for HT IBSS mac80211 adds stations in HT IBSS as soon as a frame comes by, even if the HT capabilities are not known yet (they are often received later, e.g. in beacons). So far, ampdu factor/density are only calculated when the station is initially added. This patch changes this to update ampdu factor/density settings when starting a blockack session. Using this patch, we had performance boosts from 60 to 150 MBit/s between two 2x2 Atheros devices in 5 GHz HT IBSS mode. Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 6 ++++-- drivers/net/wireless/ath/ath9k/xmit.c | 12 ++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a8c050085648..4473278efc5e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -721,6 +721,7 @@ extern int ath9k_modparam_nohwcrypt; extern int led_blink; extern bool is_ath9k_unloaded; +u8 ath9k_parse_mpdudensity(u8 mpdudensity); irqreturn_t ath_isr(int irq, void *dev); int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 85f9ab4fa26e..e2e69585d674 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -19,7 +19,7 @@ #include "ath9k.h" #include "btcoex.h" -static u8 parse_mpdudensity(u8 mpdudensity) +u8 ath9k_parse_mpdudensity(u8 mpdudensity) { /* * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": @@ -320,6 +320,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { struct ath_node *an; + u8 density; an = (struct ath_node *)sta->drv_priv; #ifdef CONFIG_ATH9K_DEBUGFS @@ -334,7 +335,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); - an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); + density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); + an->mpdudensity = density; } } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f777ddcd1172..2afc5e289df5 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1175,6 +1175,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, { struct ath_atx_tid *txtid; struct ath_node *an; + u8 density; an = (struct ath_node *)sta->drv_priv; txtid = ATH_AN_2_TID(an, tid); @@ -1182,6 +1183,17 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE)) return -EAGAIN; + /* update ampdu factor/density, they may have changed. This may happen + * in HT IBSS when a beacon with HT-info is received after the station + * has already been added. + */ + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { + an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + + sta->ht_cap.ampdu_factor); + density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); + an->mpdudensity = density; + } + txtid->state |= AGGR_ADDBA_PROGRESS; txtid->paused = true; *ssn = txtid->seq_start = txtid->seq_next; -- GitLab From fad29cd2f59949581050a937786c2c9bc78b2f04 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 25 Jun 2012 13:54:22 +0530 Subject: [PATCH 2845/6849] ath9k: Fix lockdep splat Cancel the MCI work only when MCI is actually enabled. Fixes this: [96833.124051] Call Trace: [96833.124060] [] __lock_acquire+0x1518/0x1e40 [96833.124065] [] ? mark_held_locks+0x86/0x110 [96833.124069] [] ? trace_hardirqs_on+0xd/0x10 [96833.124073] [] ? _raw_spin_unlock_irq+0x30/0x70 [96833.124078] [] ? wait_on_cpu_work+0x98/0xc0 [96833.124082] [] lock_acquire+0xa1/0x150 [96833.124085] [] ? wait_on_cpu_work+0xc0/0xc0 [96833.124088] [] ? wait_on_cpu_work+0xc0/0xc0 [96833.124092] [] wait_on_work+0x52/0x120 [96833.124095] [] ? wait_on_cpu_work+0xc0/0xc0 [96833.124099] [] ? del_timer+0x7f/0x110 [96833.124102] [] __cancel_work_timer+0x83/0x130 [96833.124106] [] cancel_work_sync+0x10/0x20 [96833.124113] [] __ath_cancel_work+0x4d/0x60 [ath9k] [96833.124119] [] ath9k_config+0x458/0x680 [ath9k] [96833.124125] [] ? ath9k_flush+0x6e/0x1d0 [ath9k] [96833.124129] [] ? __mutex_unlock_slowpath+0x10d/0x190 [96833.124146] [] ieee80211_hw_config+0x135/0x2a0 [mac80211] [96833.124163] [] ieee80211_do_open+0x67b/0xc50 [mac80211] [96833.124178] [] ieee80211_open+0x6d/0x80 [mac80211] [96833.124183] [] __dev_open+0x9f/0xf0 [96833.124187] [] __dev_change_flags+0xa1/0x180 [96833.124190] [] dev_change_flags+0x28/0x70 [96833.124195] [] devinet_ioctl+0x659/0x780 [96833.124199] [] ? dev_ioctl+0x210/0x6d0 [96833.124203] [] inet_ioctl+0x75/0x90 [96833.124208] [] sock_do_ioctl+0x30/0x70 [96833.124211] [] sock_ioctl+0x7d/0x2c0 [96833.124218] [] do_vfs_ioctl+0x99/0x580 [96833.124222] [] ? sysret_check+0x22/0x5d [96833.124226] [] sys_ioctl+0x99/0xa0 [96833.124230] [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e2e69585d674..c14cf5aa403b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -150,9 +150,9 @@ static void __ath_cancel_work(struct ath_softc *sc) cancel_work_sync(&sc->hw_check_work); cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); -#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT - cancel_work_sync(&sc->mci_work); -#endif + + if (ath9k_hw_mci_is_enabled(sc->sc_ah)) + cancel_work_sync(&sc->mci_work); } static void ath_cancel_work(struct ath_softc *sc) -- GitLab From fb1c078edb50376c14e049b22b10768b8245428a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 25 Jun 2012 13:54:30 +0530 Subject: [PATCH 2846/6849] ath9k_htc: Change default listen interval to 1 Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 25213d521bc2..cac6ff4cd14f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -718,7 +718,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->queues = 4; hw->channel_change_time = 5000; - hw->max_listen_interval = 10; + hw->max_listen_interval = 1; hw->vif_data_size = sizeof(struct ath9k_htc_vif); hw->sta_data_size = sizeof(struct ath9k_htc_sta); -- GitLab From d8a2c51cdcaee0131c88f49d64b84f1c7361d72c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 25 Jun 2012 13:54:41 +0530 Subject: [PATCH 2847/6849] ath9k_htc: Use atomic operations for op_flags Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 10 +++---- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 30 +++++++++---------- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 28 ++++++++--------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 135795257d95..1ee6548c7125 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -453,7 +453,6 @@ struct ath9k_htc_priv { u8 num_sta_assoc_vif; u8 num_ap_vif; - u16 op_flags; u16 curtxpow; u16 txpowlimit; u16 nvifs; @@ -461,6 +460,7 @@ struct ath9k_htc_priv { bool rearm_ani; bool reconfig_beacon; unsigned int rxfilter; + unsigned long op_flags; struct ath9k_hw_cal_data caldata; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 2eadffb7971c..77d541feb910 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -207,9 +207,9 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, else priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; - if (priv->op_flags & OP_TSF_RESET) { + if (test_bit(OP_TSF_RESET, &priv->op_flags)) { ath9k_hw_reset_tsf(priv->ah); - priv->op_flags &= ~OP_TSF_RESET; + clear_bit(OP_TSF_RESET, &priv->op_flags); } else { /* * Pull nexttbtt forward to reflect the current TSF. @@ -221,7 +221,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, } while (nexttbtt < tsftu); } - if (priv->op_flags & OP_ENABLE_BEACON) + if (test_bit(OP_ENABLE_BEACON, &priv->op_flags)) imask |= ATH9K_INT_SWBA; ath_dbg(common, CONFIG, @@ -269,7 +269,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, else priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; - if (priv->op_flags & OP_ENABLE_BEACON) + if (test_bit(OP_ENABLE_BEACON, &priv->op_flags)) imask |= ATH9K_INT_SWBA; ath_dbg(common, CONFIG, @@ -365,7 +365,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, vif = priv->cur_beacon_conf.bslot[slot]; avp = (struct ath9k_htc_vif *)vif->drv_priv; - if (unlikely(priv->op_flags & OP_SCANNING)) { + if (unlikely(test_bit(OP_SCANNING, &priv->op_flags))) { spin_unlock_bh(&priv->beacon_lock); return; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 1c10e2e5c237..3688bbad87eb 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -37,17 +37,18 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) if (time_after(jiffies, btcoex->bt_priority_time + msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { - priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); + clear_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); + clear_bit(OP_BT_SCAN, &priv->op_flags); /* Detect if colocated bt started scanning */ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { ath_dbg(ath9k_hw_common(ah), BTCOEX, "BT scan detected\n"); - priv->op_flags |= (OP_BT_SCAN | - OP_BT_PRIORITY_DETECTED); + set_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); + set_bit(OP_BT_SCAN, &priv->op_flags); } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { ath_dbg(ath9k_hw_common(ah), BTCOEX, "BT priority traffic detected\n"); - priv->op_flags |= OP_BT_PRIORITY_DETECTED; + set_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); } btcoex->bt_priority_cnt = 0; @@ -67,26 +68,23 @@ static void ath_btcoex_period_work(struct work_struct *work) struct ath_btcoex *btcoex = &priv->btcoex; struct ath_common *common = ath9k_hw_common(priv->ah); u32 timer_period; - bool is_btscan; int ret; ath_detect_bt_priority(priv); - is_btscan = !!(priv->op_flags & OP_BT_SCAN); - ret = ath9k_htc_update_cap_target(priv, - !!(priv->op_flags & OP_BT_PRIORITY_DETECTED)); + test_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags)); if (ret) { ath_err(common, "Unable to set BTCOEX parameters\n"); return; } - ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : - btcoex->bt_stomp_type); + ath9k_hw_btcoex_bt_stomp(priv->ah, test_bit(OP_BT_SCAN, &priv->op_flags) ? + ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type); ath9k_hw_btcoex_enable(priv->ah); - timer_period = is_btscan ? btcoex->btscan_no_stomp : - btcoex->btcoex_no_stomp; + timer_period = test_bit(OP_BT_SCAN, &priv->op_flags) ? + btcoex->btscan_no_stomp : btcoex->btcoex_no_stomp; ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work, msecs_to_jiffies(timer_period)); ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, @@ -104,14 +102,15 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) struct ath_hw *ah = priv->ah; struct ath_btcoex *btcoex = &priv->btcoex; struct ath_common *common = ath9k_hw_common(ah); - bool is_btscan = priv->op_flags & OP_BT_SCAN; ath_dbg(common, BTCOEX, "time slice work for bt and wlan\n"); - if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) + if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || + test_bit(OP_BT_SCAN, &priv->op_flags)) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); + ath9k_hw_btcoex_enable(priv->ah); } @@ -141,7 +140,8 @@ static void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) btcoex->bt_priority_cnt = 0; btcoex->bt_priority_time = jiffies; - priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); + clear_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); + clear_bit(OP_BT_SCAN, &priv->op_flags); ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index cac6ff4cd14f..a035a380d669 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -611,7 +611,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, struct ath_common *common; int i, ret = 0, csz = 0; - priv->op_flags |= OP_INVALID; + set_bit(OP_INVALID, &priv->op_flags); ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); if (!ah) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2b8f61c210e1..0fc0d35414c0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, u8 cmd_rsp; int ret; - if (priv->op_flags & OP_INVALID) + if (test_bit(OP_INVALID, &priv->op_flags)) return -EIO; fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); @@ -304,7 +304,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, htc_start(priv->htc); - if (!(priv->op_flags & OP_SCANNING) && + if (!test_bit(OP_SCANNING, &priv->op_flags) && !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) ath9k_htc_vif_reconfig(priv); @@ -750,7 +750,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) common->ani.shortcal_timer = timestamp; common->ani.checkani_timer = timestamp; - priv->op_flags |= OP_ANI_RUNNING; + set_bit(OP_ANI_RUNNING, &priv->op_flags); ieee80211_queue_delayed_work(common->hw, &priv->ani_work, msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); @@ -759,7 +759,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv) { cancel_delayed_work_sync(&priv->ani_work); - priv->op_flags &= ~OP_ANI_RUNNING; + clear_bit(OP_ANI_RUNNING, &priv->op_flags); } void ath9k_htc_ani_work(struct work_struct *work) @@ -944,7 +944,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ath_dbg(common, CONFIG, "Failed to update capability in target\n"); - priv->op_flags &= ~OP_INVALID; + clear_bit(OP_INVALID, &priv->op_flags); htc_start(priv->htc); spin_lock_bh(&priv->tx.tx_lock); @@ -973,7 +973,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); - if (priv->op_flags & OP_INVALID) { + if (test_bit(OP_INVALID, &priv->op_flags)) { ath_dbg(common, ANY, "Device not present\n"); mutex_unlock(&priv->mutex); return; @@ -1015,7 +1015,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ath9k_htc_ps_restore(priv); ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); - priv->op_flags |= OP_INVALID; + set_bit(OP_INVALID, &priv->op_flags); ath_dbg(common, CONFIG, "Driver halt\n"); mutex_unlock(&priv->mutex); @@ -1105,7 +1105,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && - !(priv->op_flags & OP_ANI_RUNNING)) { + !test_bit(OP_ANI_RUNNING, &priv->op_flags)) { ath9k_hw_set_tsfadjust(priv->ah, 1); ath9k_htc_start_ani(priv); } @@ -1285,7 +1285,7 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, changed_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS; - if (priv->op_flags & OP_INVALID) { + if (test_bit(OP_INVALID, &priv->op_flags)) { ath_dbg(ath9k_hw_common(priv->ah), ANY, "Unable to configure filter on invalid state\n"); mutex_unlock(&priv->mutex); @@ -1517,7 +1517,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n", bss_conf->bssid); ath9k_htc_set_tsfadjust(priv, vif); - priv->op_flags |= OP_ENABLE_BEACON; + set_bit(OP_ENABLE_BEACON, &priv->op_flags); ath9k_htc_beacon_config(priv, vif); } @@ -1530,7 +1530,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath_dbg(common, CONFIG, "Beacon disabled for BSS: %pM\n", bss_conf->bssid); - priv->op_flags &= ~OP_ENABLE_BEACON; + clear_bit(OP_ENABLE_BEACON, &priv->op_flags); ath9k_htc_beacon_config(priv, vif); } } @@ -1543,7 +1543,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, (priv->nvifs == 1) && (priv->num_ap_vif == 1) && (vif->type == NL80211_IFTYPE_AP)) { - priv->op_flags |= OP_TSF_RESET; + set_bit(OP_TSF_RESET, &priv->op_flags); } ath_dbg(common, CONFIG, "Beacon interval changed for BSS: %pM\n", @@ -1655,7 +1655,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); spin_lock_bh(&priv->beacon_lock); - priv->op_flags |= OP_SCANNING; + set_bit(OP_SCANNING, &priv->op_flags); spin_unlock_bh(&priv->beacon_lock); cancel_work_sync(&priv->ps_work); ath9k_htc_stop_ani(priv); @@ -1668,7 +1668,7 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); spin_lock_bh(&priv->beacon_lock); - priv->op_flags &= ~OP_SCANNING; + clear_bit(OP_SCANNING, &priv->op_flags); spin_unlock_bh(&priv->beacon_lock); ath9k_htc_ps_wakeup(priv); ath9k_htc_vif_reconfig(priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 3e40a6461512..47e61d0da33b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -916,7 +916,7 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv) { ath9k_hw_rxena(priv->ah); ath9k_htc_opmode_init(priv); - ath9k_hw_startpcureceive(priv->ah, (priv->op_flags & OP_SCANNING)); + ath9k_hw_startpcureceive(priv->ah, test_bit(OP_SCANNING, &priv->op_flags)); priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER; } -- GitLab From 6bcfe67f9865fb51ec78fc9b09887375db7e08b5 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 25 Jun 2012 13:54:49 +0530 Subject: [PATCH 2848/6849] ath9k_htc: Fix IDLE power save Remove the radio enable/disable stuff and fix the transition to FULL_SLEEP mode when the device is idle. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 - drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 92 ------------------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 50 ++++------ 3 files changed, 20 insertions(+), 124 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1ee6548c7125..936e920fb88e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -572,8 +572,6 @@ bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); -void ath9k_htc_radio_enable(struct ieee80211_hw *hw); -void ath9k_htc_radio_disable(struct ieee80211_hw *hw); #ifdef CONFIG_MAC80211_LEDS void ath9k_init_leds(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 3688bbad87eb..07df279c8d46 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -310,95 +310,3 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv) if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) wiphy_rfkill_start_polling(priv->hw->wiphy); } - -void ath9k_htc_radio_enable(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - struct ath_hw *ah = priv->ah; - struct ath_common *common = ath9k_hw_common(ah); - int ret; - u8 cmd_rsp; - - if (!ah->curchan) - ah->curchan = ath9k_cmn_get_curchannel(hw, ah); - - /* Reset the HW */ - ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); - if (ret) { - ath_err(common, - "Unable to reset hardware; reset status %d (freq %u MHz)\n", - ret, ah->curchan->channel); - } - - ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit, - &priv->curtxpow); - - /* Start RX */ - WMI_CMD(WMI_START_RECV_CMDID); - ath9k_host_rx_init(priv); - - /* Start TX */ - htc_start(priv->htc); - spin_lock_bh(&priv->tx.tx_lock); - priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; - spin_unlock_bh(&priv->tx.tx_lock); - ieee80211_wake_queues(hw); - - WMI_CMD(WMI_ENABLE_INTR_CMDID); - - /* Enable LED */ - ath9k_hw_cfg_output(ah, ah->led_pin, - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - ath9k_hw_set_gpio(ah, ah->led_pin, 0); -} - -void ath9k_htc_radio_disable(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - struct ath_hw *ah = priv->ah; - struct ath_common *common = ath9k_hw_common(ah); - int ret; - u8 cmd_rsp; - - ath9k_htc_ps_wakeup(priv); - - /* Disable LED */ - ath9k_hw_set_gpio(ah, ah->led_pin, 1); - ath9k_hw_cfg_gpio_input(ah, ah->led_pin); - - WMI_CMD(WMI_DISABLE_INTR_CMDID); - - /* Stop TX */ - ieee80211_stop_queues(hw); - ath9k_htc_tx_drain(priv); - WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); - - /* Stop RX */ - WMI_CMD(WMI_STOP_RECV_CMDID); - - /* Clear the WMI event queue */ - ath9k_wmi_event_drain(priv); - - /* - * The MIB counters have to be disabled here, - * since the target doesn't do it. - */ - ath9k_hw_disable_mib_counters(ah); - - if (!ah->curchan) - ah->curchan = ath9k_cmn_get_curchannel(hw, ah); - - /* Reset the HW */ - ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); - if (ret) { - ath_err(common, - "Unable to reset hardware; reset status %d (freq %u MHz)\n", - ret, ah->curchan->channel); - } - - /* Disable the PHY */ - ath9k_hw_phy_disable(ah); - - ath9k_htc_ps_restore(priv); - ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); -} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 0fc0d35414c0..fc8cd8284108 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -75,14 +75,19 @@ unlock: void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) { + bool reset; + mutex_lock(&priv->htc_pm_lock); if (--priv->ps_usecount != 0) goto unlock; - if (priv->ps_idle) + if (priv->ps_idle) { + ath9k_hw_setrxabort(priv->ah, true); + ath9k_hw_stopdmarecv(priv->ah, &reset); ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP); - else if (priv->ps_enabled) + } else if (priv->ps_enabled) { ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); + } unlock: mutex_unlock(&priv->htc_pm_lock); @@ -1178,24 +1183,20 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) struct ath9k_htc_priv *priv = hw->priv; struct ath_common *common = ath9k_hw_common(priv->ah); struct ieee80211_conf *conf = &hw->conf; + bool chip_reset = false; + int ret = 0; mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); if (changed & IEEE80211_CONF_CHANGE_IDLE) { - bool enable_radio = false; - bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); - mutex_lock(&priv->htc_pm_lock); - if (!idle && priv->ps_idle) - enable_radio = true; - priv->ps_idle = idle; - mutex_unlock(&priv->htc_pm_lock); - if (enable_radio) { - ath_dbg(common, CONFIG, "not-idle: enabling radio\n"); - ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); - ath9k_htc_radio_enable(hw); - } + priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); + if (priv->ps_idle) + chip_reset = true; + + mutex_unlock(&priv->htc_pm_lock); } /* @@ -1210,7 +1211,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ath9k_htc_remove_monitor_interface(priv); } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; @@ -1223,8 +1224,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { ath_err(common, "Unable to set channel\n"); - mutex_unlock(&priv->mutex); - return -EINVAL; + ret = -EINVAL; + goto out; } } @@ -1246,21 +1247,10 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) priv->txpowlimit, &priv->curtxpow); } - if (changed & IEEE80211_CONF_CHANGE_IDLE) { - mutex_lock(&priv->htc_pm_lock); - if (!priv->ps_idle) { - mutex_unlock(&priv->htc_pm_lock); - goto out; - } - mutex_unlock(&priv->htc_pm_lock); - - ath_dbg(common, CONFIG, "idle: disabling radio\n"); - ath9k_htc_radio_disable(hw); - } - out: + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); - return 0; + return ret; } #define SUPPORTED_FILTERS \ -- GitLab From 4069d6f86bebce1a1e3456ef721511b4b81958f8 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Sat, 9 Jun 2012 13:18:08 +0900 Subject: [PATCH 2849/6849] sony-laptop: use an enum for SNC event types Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 210d4ae547c2..615ab06b6cd3 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1172,6 +1172,10 @@ static int sony_nc_hotkeys_decode(u32 event, unsigned int handle) /* * ACPI callbacks */ +enum event_types { + HOTKEY = 1, + KILLSWITCH +}; static void sony_nc_notify(struct acpi_device *device, u32 event) { u32 real_ev = event; @@ -1196,7 +1200,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) /* hotkey event */ case 0x0100: case 0x0127: - ev_type = 1; + ev_type = HOTKEY; real_ev = sony_nc_hotkeys_decode(event, handle); if (real_ev > 0) @@ -1216,7 +1220,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) * update the rfkill device status when the * switch is moved. */ - ev_type = 2; + ev_type = KILLSWITCH; sony_call_snc_handle(handle, 0x0100, &result); real_ev = result & 0x03; @@ -1238,7 +1242,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) } else { /* old style event */ - ev_type = 1; + ev_type = HOTKEY; sony_laptop_report_input_event(real_ev); } -- GitLab From bb384b5295323ed58260aeaff22d8bbe32988396 Mon Sep 17 00:00:00 2001 From: Marco Chiappero Date: Sat, 9 Jun 2012 13:18:09 +0900 Subject: [PATCH 2850/6849] sony-laptop: notify userspace of GFX switch position changes Some Vaios come with both integrated and discrete graphics, plus a switch for choosing one of the two. When the switch position is changed, a notification is generated. Signed-off-by: Marco Chiappero Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 615ab06b6cd3..4f42e5661bf5 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1174,7 +1174,8 @@ static int sony_nc_hotkeys_decode(u32 event, unsigned int handle) */ enum event_types { HOTKEY = 1, - KILLSWITCH + KILLSWITCH, + GFX_SWITCH }; static void sony_nc_notify(struct acpi_device *device, u32 event) { @@ -1230,6 +1231,24 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) break; + case 0x0128: + case 0x0146: + /* Hybrid GFX switching */ + sony_call_snc_handle(handle, 0x0000, &result); + dprintk("GFX switch event received (reason: %s)\n", + (result & 0x01) ? + "switch change" : "unknown"); + + /* verify the switch state + * 1: discrete GFX + * 0: integrated GFX + */ + sony_call_snc_handle(handle, 0x0100, &result); + + ev_type = GFX_SWITCH; + real_ev = result & 0xff; + break; + default: dprintk("Unknown event 0x%x for handle 0x%x\n", event, handle); -- GitLab From 15aa5c75468a103cdee1a0e0ec26aad979bf71a5 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Mon, 11 Jun 2012 07:18:31 +0900 Subject: [PATCH 2851/6849] sony-laptop: store battery care limits on batteries Some models offer the option to store the limits on the battery (firmware?). Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 41 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 4f42e5661bf5..f045e3e59cd6 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1916,32 +1916,33 @@ static ssize_t sony_nc_battery_care_limit_store(struct device *dev, * bits 4,5: store the limit into the EC * bits 6,7: store the limit into the battery */ + cmd = 0; - /* - * handle 0x0115 should allow storing on battery too; - * handle 0x0136 same as 0x0115 + health status; - * handle 0x013f, same as 0x0136 but no storing on the battery - * - * Store only inside the EC for now, regardless the handle number - */ - if (value == 0) - /* disable limits */ - cmd = 0x0; + if (value > 0) { + if (value <= 50) + cmd = 0x20; - else if (value <= 50) - cmd = 0x21; + else if (value <= 80) + cmd = 0x10; - else if (value <= 80) - cmd = 0x11; + else if (value <= 100) + cmd = 0x30; + + else + return -EINVAL; - else if (value <= 100) - cmd = 0x31; + /* + * handle 0x0115 should allow storing on battery too; + * handle 0x0136 same as 0x0115 + health status; + * handle 0x013f, same as 0x0136 but no storing on the battery + */ + if (bcare_ctl->handle != 0x013f) + cmd = cmd | (cmd << 2); - else - return -EINVAL; + cmd = (cmd | 0x1) << 0x10; + } - if (sony_call_snc_handle(bcare_ctl->handle, (cmd << 0x10) | 0x0100, - &result)) + if (sony_call_snc_handle(bcare_ctl->handle, cmd | 0x0100, &result)) return -EIO; return count; -- GitLab From 014fc8fbece33d42e2aa92d289fffa213a159321 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Sat, 9 Jun 2012 13:18:11 +0900 Subject: [PATCH 2852/6849] sony-laptop: add lid backlight support for handle 0x143 Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index f045e3e59cd6..a94e13fe1f42 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1010,6 +1010,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, struct sony_backlight_props { struct backlight_device *dev; int handle; + int cmd_base; u8 offset; u8 maxlvl; }; @@ -1037,7 +1038,7 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) struct sony_backlight_props *sdev = (struct sony_backlight_props *)bl_get_data(bd); - sony_call_snc_handle(sdev->handle, 0x0200, &result); + sony_call_snc_handle(sdev->handle, sdev->cmd_base + 0x100, &result); return (result & 0xff) - sdev->offset; } @@ -1049,7 +1050,8 @@ static int sony_nc_update_status_ng(struct backlight_device *bd) (struct sony_backlight_props *)bl_get_data(bd); value = bd->props.brightness + sdev->offset; - if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) + if (sony_call_snc_handle(sdev->handle, sdev->cmd_base | (value << 0x10), + &result)) return -EIO; return value; @@ -2496,6 +2498,7 @@ static void sony_nc_backlight_ng_read_limits(int handle, { u64 offset; int i; + int lvl_table_len = 0; u8 min = 0xff, max = 0x00; unsigned char buffer[32] = { 0 }; @@ -2515,11 +2518,21 @@ static void sony_nc_backlight_ng_read_limits(int handle, if (i < 0) return; + switch (handle) { + case 0x012f: + case 0x0137: + lvl_table_len = 9; + break; + case 0x143: + lvl_table_len = 16; + break; + } + /* the buffer lists brightness levels available, brightness levels are * from position 0 to 8 in the array, other values are used by ALS * control. */ - for (i = 0; i < 9 && i < ARRAY_SIZE(buffer); i++) { + for (i = 0; i < lvl_table_len && i < ARRAY_SIZE(buffer); i++) { dprintk("Brightness level: %d\n", buffer[i]); @@ -2546,14 +2559,22 @@ static void sony_nc_backlight_setup(void) if (sony_find_snc_handle(0x12f) != -1) { ops = &sony_backlight_ng_ops; + sony_bl_props.cmd_base = 0x0100; sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; } else if (sony_find_snc_handle(0x137) != -1) { ops = &sony_backlight_ng_ops; + sony_bl_props.cmd_base = 0x0100; sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; + } else if (sony_find_snc_handle(0x143) != -1) { + ops = &sony_backlight_ng_ops; + sony_bl_props.cmd_base = 0x3000; + sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props); + max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; + } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &unused))) { ops = &sony_backlight_ops; -- GitLab From ca3c2c706de39b3400e57254dce054bf7350efa2 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Sat, 9 Jun 2012 13:18:12 +0900 Subject: [PATCH 2853/6849] sony-laptop: input initialization should be done before SNC SNC needs input devices so better have those ready before starting handle events. Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index a94e13fe1f42..89ff6d845f34 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -2642,6 +2642,12 @@ static int sony_nc_add(struct acpi_device *device) } } + result = sony_laptop_setup_input(device); + if (result) { + pr_err("Unable to create input devices\n"); + goto outplatform; + } + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", &handle))) { int arg = 1; @@ -2659,12 +2665,6 @@ static int sony_nc_add(struct acpi_device *device) } /* setup input devices and helper fifo */ - result = sony_laptop_setup_input(device); - if (result) { - pr_err("Unable to create input devices\n"); - goto outsnc; - } - if (acpi_video_backlight_support()) { pr_info("brightness ignored, must be controlled by ACPI video driver\n"); } else { @@ -2712,22 +2712,21 @@ static int sony_nc_add(struct acpi_device *device) return 0; - out_sysfs: +out_sysfs: for (item = sony_nc_values; item->name; ++item) { device_remove_file(&sony_pf_device->dev, &item->devattr); } sony_nc_backlight_cleanup(); - - sony_laptop_remove_input(); - - outsnc: sony_nc_function_cleanup(sony_pf_device); sony_nc_handles_cleanup(sony_pf_device); - outpresent: +outplatform: + sony_laptop_remove_input(); + +outpresent: sony_pf_remove(); - outwalk: +outwalk: sony_nc_rfkill_cleanup(); return result; } -- GitLab From c7a2918373983b32db3ca35823d930641747e26f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Jun 2012 13:18:13 +0900 Subject: [PATCH 2854/6849] sony-laptop: fix sony_nc_sysfs_store() We made this an unsigned long and it causes a bug on 64 bit big endian systems when we try to pass the value to sony_nc_int_call(). Also value has to be signed because validate() returns negative error codes. Signed-off-by: Dan Carpenter Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 89ff6d845f34..78e6389d2cae 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -973,7 +973,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buffer, size_t count) { - unsigned long value = 0; + int value; int ret = 0; struct sony_nc_value *item = container_of(attr, struct sony_nc_value, devattr); @@ -984,7 +984,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, if (count > 31) return -EINVAL; - if (kstrtoul(buffer, 10, &value)) + if (kstrtoint(buffer, 10, &value)) return -EINVAL; if (item->validate) @@ -994,7 +994,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, return value; ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, - (int *)&value, NULL); + &value, NULL); if (ret < 0) return -EIO; -- GitLab From 56f4a9f76d8ce7c7cef92905c909aad0c7e5c9db Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Jun 2012 13:18:14 +0900 Subject: [PATCH 2855/6849] sony-laptop: fix a couple signedness bugs This needs to be signed to handle negative error codes. Remove a redundant check, read_limits is always called with a valid handle. Signed-off-by: Dan Carpenter Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 78e6389d2cae..b9499b65c1cd 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -2139,7 +2139,7 @@ static ssize_t sony_nc_thermal_mode_show(struct device *dev, struct device_attribute *attr, char *buffer) { ssize_t count = 0; - unsigned int mode = sony_nc_thermal_mode_get(); + int mode = sony_nc_thermal_mode_get(); if (mode < 0) return mode; @@ -2507,8 +2507,6 @@ static void sony_nc_backlight_ng_read_limits(int handle, props->maxlvl = 0xff; offset = sony_find_snc_handle(handle); - if (offset < 0) - return; /* try to read the boundaries from ACPI tables, if we fail the above * defaults should be reasonable -- GitLab From a1071a5abf1f4d4a7f8324e21b8b32b1342013c7 Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Thu, 14 Jun 2012 06:36:02 +0900 Subject: [PATCH 2856/6849] sony-laptop: correct find_snc_handle failure checks Since bab7084c745bf4d75b760728387f375fd34dc683, find_snc_handle returns -EINVAL, not -1. Signed-off-by: Mattia Dongili Signed-off-by: Matthew Garrett --- drivers/platform/x86/sony-laptop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index b9499b65c1cd..d456ff0c73b7 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -2555,19 +2555,19 @@ static void sony_nc_backlight_setup(void) const struct backlight_ops *ops = NULL; struct backlight_properties props; - if (sony_find_snc_handle(0x12f) != -1) { + if (sony_find_snc_handle(0x12f) >= 0) { ops = &sony_backlight_ng_ops; sony_bl_props.cmd_base = 0x0100; sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; - } else if (sony_find_snc_handle(0x137) != -1) { + } else if (sony_find_snc_handle(0x137) >= 0) { ops = &sony_backlight_ng_ops; sony_bl_props.cmd_base = 0x0100; sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; - } else if (sony_find_snc_handle(0x143) != -1) { + } else if (sony_find_snc_handle(0x143) >= 0) { ops = &sony_backlight_ng_ops; sony_bl_props.cmd_base = 0x3000; sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props); -- GitLab From 57f9616b79549e772cf4dd3aa1d2df5b6c8acdfa Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 12 Jun 2012 19:28:50 +0300 Subject: [PATCH 2857/6849] ideapad: uninitialized data in ideapad_acpi_add() We only initialize the high bits of "cfg". It probably doesn't cause a problem given that this is platform specific code and doesn't have to worry about endianness etc. But it's sort of messy. Signed-off-by: Dan Carpenter Signed-off-by: Matthew Garrett --- drivers/platform/x86/ideapad-laptop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 4f20f8dd3d7c..17f6dfd8dbfb 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -694,10 +694,10 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); static int __devinit ideapad_acpi_add(struct acpi_device *adevice) { int ret, i; - unsigned long cfg; + int cfg; struct ideapad_private *priv; - if (read_method_int(adevice->handle, "_CFG", (int *)&cfg)) + if (read_method_int(adevice->handle, "_CFG", &cfg)) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -721,7 +721,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) goto input_failed; for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { - if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg)) + if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) ideapad_register_rfkill(adevice, i); else priv->rfk[i] = NULL; -- GitLab From 88ca518b0bb4161e5f20f8a1d9cc477cae294e54 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Jun 2012 15:07:17 +0200 Subject: [PATCH 2858/6849] intel_ips: blacklist HP ProBook laptops intel_ips driver spews the warning message "ME failed to update for more than 1s, likely hung" at each second endlessly on HP ProBook laptops with IronLake. As this has never worked, better to blacklist the driver for now. Cc: Signed-off-by: Takashi Iwai Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 0ffdb3cde2bb..9af4257d4901 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -1485,6 +1486,24 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { MODULE_DEVICE_TABLE(pci, ips_id_table); +static int ips_blacklist_callback(const struct dmi_system_id *id) +{ + pr_info("Blacklisted intel_ips for %s\n", id->ident); + return 1; +} + +static const struct dmi_system_id ips_blacklist[] = { + { + .callback = ips_blacklist_callback, + .ident = "HP ProBook", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), + }, + }, + { } /* terminating entry */ +}; + static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) { u64 platform_info; @@ -1494,6 +1513,9 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) u16 htshi, trc, trc_required_mask; u8 tse; + if (dmi_check_system(ips_blacklist)) + return -ENODEV; + ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); if (!ips) return -ENOMEM; -- GitLab From 72d967eda2fd69a6cac01498585bc019ade4f8ff Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 26 Jun 2012 12:48:32 +0530 Subject: [PATCH 2859/6849] ARM: tegra: dma: rename driver name for clock to "tegra-apbdma" Rename the driver name of the clock entry of Tegra APBDMA to tegra-apbdma from of tegra-dma. This name is more aligned towards the movement of dmaengine based new DMA driver. Signed-off-by: Laxman Dewangan Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/dma.c | 2 +- arch/arm/mach-tegra/tegra2_clocks.c | 2 +- arch/arm/mach-tegra/tegra30_clocks.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index 2698d7d5c9ca..29c5114d607c 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -714,7 +714,7 @@ int __init tegra_dma_init(void) bitmap_fill(channel_usage, NV_DMA_MAX_CHANNELS); - c = clk_get_sys("tegra-dma", NULL); + c = clk_get_sys("tegra-apbdma", NULL); if (IS_ERR(c)) { pr_err("Unable to get clock for APB DMA\n"); ret = PTR_ERR(c); diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 034d9529b51e..b79cb93ffd54 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -2149,7 +2149,7 @@ static struct clk tegra_clk_emc = { } static struct clk tegra_list_clks[] = { - PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 108000000, mux_pclk, 0), + PERIPH_CLK("apbdma", "tegra-apbdma", NULL, 34, 0, 108000000, mux_pclk, 0), PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET), PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0), PERIPH_CLK("i2s1", "tegra20-i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c index e1a74895dc3a..2ba948ea21ff 100644 --- a/arch/arm/mach-tegra/tegra30_clocks.c +++ b/arch/arm/mach-tegra/tegra30_clocks.c @@ -2871,7 +2871,7 @@ static struct clk tegra30_clk_twd = { }, \ } struct clk tegra_list_clks[] = { - PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 26000000, mux_clk_m, 0), + PERIPH_CLK("apbdma", "tegra-apbdma", NULL, 34, 0, 26000000, mux_clk_m, 0), PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB), PERIPH_CLK("kbc", "tegra-kbc", NULL, 36, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB), PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0), -- GitLab From bd976e0307fbb3c715df944ded6b70a9fa8d6bb1 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 26 Jun 2012 12:48:31 +0530 Subject: [PATCH 2860/6849] ARM: tegra: add device tree AUXDATA for APBDMA Add DT AUXDATA for Tegra's APBDMA controller driver. Signed-off-by: Laxman Dewangan Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-dt-tegra20.c | 1 + arch/arm/mach-tegra/board-dt-tegra30.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 8b4e6e1f0f7b..1b43c3350e3c 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -64,6 +64,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { &tegra_ehci2_pdata), OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", &tegra_ehci3_pdata), + OF_DEV_AUXDATA("nvidia,tegra20-apbdma", 0x6000a000, "tegra-apbdma", NULL), {} }; diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 4f76fa7a5da3..4a409862015f 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c @@ -52,6 +52,7 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL), + OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL), {} }; -- GitLab From 6fda135c908d0f38a0167adcbd71094572e3059b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Jun 2012 12:35:24 -0700 Subject: [PATCH 2861/6849] Revert "printk: return -EINVAL if the message len is bigger than the buf size" This reverts commit b56a39ac263e5b8cafedd551a49c2105e68b98c2. A better patch from Jan will follow this to resolve the issue. Acked-by: Kay Sievers Cc: Fengguang Wu Cc: Yuanhan Liu Cc: Jan Beulich Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index d6a1412f6b09..ff05361962e1 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -880,9 +880,7 @@ static int syslog_print(char __user *buf, int size) syslog_seq++; raw_spin_unlock_irq(&logbuf_lock); - if (len > size) - len = -EINVAL; - else if (len > 0 && copy_to_user(buf, text, len)) + if (len > 0 && copy_to_user(buf, text, len)) len = -EFAULT; kfree(text); -- GitLab From 116e90b23f74d303e8d607c7a7d54f60f14ab9f2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 22 Jun 2012 16:36:09 +0100 Subject: [PATCH 2862/6849] syslog: fill buffer with more than a single message for SYSLOG_ACTION_READ The recent changes to the printk buffer management resulted in SYSLOG_ACTION_READ to only return a single message, whereas previously the buffer would get filled as much as possible. As, when too small to fit everything, filling it to the last byte would be pretty ugly with the new code, the patch arranges for as many messages as possible to get returned in a single invocation. User space tools in at least all SLES versions depend on the old behavior. This at once addresses the issue attempted to get fixed with commit b56a39ac263e5b8cafedd551a49c2105e68b98c2 ("printk: return -EINVAL if the message len is bigger than the buf size"), and since that commit widened the possibility for losing a message altogether, the patch here assumes that this other commit would get reverted first (otherwise the patch here won't apply). Furthermore, this patch also addresses the problem dealt with in commit 4a77a5a06ec66ed05199b301e7c25f42f979afdc ("printk: use mutex lock to stop syslog_seq from going wild"), so I'd recommend reverting that one too (albeit there's no direct collision between the two). Signed-off-by: Jan Beulich Acked-by: Kay Sievers Cc: Yuanhan Liu Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 51 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index ff05361962e1..cdfba44fedf0 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -862,26 +862,49 @@ static int syslog_print(char __user *buf, int size) { char *text; struct log *msg; - int len; + int len = 0; text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); if (!text) return -ENOMEM; - raw_spin_lock_irq(&logbuf_lock); - if (syslog_seq < log_first_seq) { - /* messages are gone, move to first one */ - syslog_seq = log_first_seq; - syslog_idx = log_first_idx; - } - msg = log_from_idx(syslog_idx); - len = msg_print_text(msg, true, text, LOG_LINE_MAX); - syslog_idx = log_next(syslog_idx); - syslog_seq++; - raw_spin_unlock_irq(&logbuf_lock); + while (size > 0) { + size_t n; + + raw_spin_lock_irq(&logbuf_lock); + if (syslog_seq < log_first_seq) { + /* messages are gone, move to first one */ + syslog_seq = log_first_seq; + syslog_idx = log_first_idx; + } + if (syslog_seq == log_next_seq) { + raw_spin_unlock_irq(&logbuf_lock); + break; + } + msg = log_from_idx(syslog_idx); + n = msg_print_text(msg, true, text, LOG_LINE_MAX); + if (n <= size) { + syslog_idx = log_next(syslog_idx); + syslog_seq++; + } else + n = 0; + raw_spin_unlock_irq(&logbuf_lock); + + if (!n) + break; - if (len > 0 && copy_to_user(buf, text, len)) - len = -EFAULT; + len += n; + size -= n; + buf += n; + n = copy_to_user(buf - n, text, n); + + if (n) { + len -= n; + if (!len) + len = -EFAULT; + break; + } + } kfree(text); return len; -- GitLab From d380443cd0271903bf9516bc04cead81676be034 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Wed, 13 Jun 2012 17:10:43 +0530 Subject: [PATCH 2863/6849] mmc: block: fix the data timeout issue with ACMD22 If multi block write operation fails for SD card, during error handling we send the SD_APP_SEND_NUM_WR_BLKS (ACMD22) to know how many blocks were already programmed by card. But mmc_sd_num_wr_blocks() function which sends the ACMD22 calculates the data timeout value from csd.tacc_ns and csd.tacc_clks parameters which will be 0 for block addressed (>2GB cards) SD card. This would result in timeout_ns and timeout_clks being 0 in the mmc_request passed to host driver. This means host controller would program its data timeout timer value with 0 which could result in DATA TIMEOUT errors from controller. To fix this issue, mmc_sd_num_wr_blocks() should instead just call the mmc_set_data_timeout() to calculate the data timeout value. mmc_set_data_timeout() function ensures that non zero timeout value is set even for block addressed SD cards. Signed-off-by: Subhash Jadavani Reviewed-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index dd2d374dcc7a..276d21ce6bc1 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -554,7 +554,6 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) struct mmc_request mrq = {NULL}; struct mmc_command cmd = {0}; struct mmc_data data = {0}; - unsigned int timeout_us; struct scatterlist sg; @@ -574,23 +573,12 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - data.timeout_ns = card->csd.tacc_ns * 100; - data.timeout_clks = card->csd.tacc_clks * 100; - - timeout_us = data.timeout_ns / 1000; - timeout_us += data.timeout_clks * 1000 / - (card->host->ios.clock / 1000); - - if (timeout_us > 100000) { - data.timeout_ns = 100000000; - data.timeout_clks = 0; - } - data.blksz = 4; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; data.sg_len = 1; + mmc_set_data_timeout(&data, card); mrq.cmd = &cmd; mrq.data = &data; -- GitLab From fe85227347738eb9b871bc163e7fb0db8b6cd2a0 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jun 2012 18:49:35 +0800 Subject: [PATCH 2864/6849] Revert "mmc: omap_hsmmc: Enable Auto CMD12" This patch reverts the commit dba3c29ea4a1d5d544. After bisecting, this commit dba3c29 is found to ruin micro-SD card data (writing incorrect file, or fs is corrupt after several times mount) on the beagle-xm revB, and reverting the commit will fix the problem. Also from TRM of OMAP3/OMAP4/DM37x, the below is mentioned about the Auto CMD12 Enable bit. - SDIO does not support this feature. - SD card only. Looks it is not suitable to always enable Auto CMD12 in host controller driver. Considered that the commit is not mature enough, so ask to revert it first. Cc: Balaji T K Cc: Venkatraman S Buglink: https://lkml.org/lkml/2012/6/10/225 Reported-by: Paolo Pisati Reported-bisected-and-tested-by: Ming Lei Signed-off-by: Ming Lei Acked-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9a7a60aeb19e..389a3eedfc24 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -85,7 +85,6 @@ #define BRR_ENABLE (1 << 5) #define DTO_ENABLE (1 << 20) #define INIT_STREAM (1 << 1) -#define ACEN_ACMD12 (1 << 2) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) #define DMA_EN 0x1 @@ -117,7 +116,6 @@ #define OMAP_MMC_MAX_CLOCK 52000000 #define DRIVER_NAME "omap_hsmmc" -#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -177,7 +175,6 @@ struct omap_hsmmc_host { int reqs_blocked; int use_reg; int req_in_progress; - unsigned int flags; struct omap_hsmmc_next next_data; struct omap_mmc_platform_data *pdata; @@ -773,8 +770,6 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); - if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode)) - cmdreg |= ACEN_ACMD12; if (data) { cmdreg |= DP_SELECT | MSBS | BCE; @@ -847,14 +842,11 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) else data->bytes_xfered = 0; - if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error)) { - omap_hsmmc_start_command(host, data->stop, NULL); - } else { - if (data->stop) - data->stop->resp[0] = OMAP_HSMMC_READ(host->base, - RSP76); + if (!data->stop) { omap_hsmmc_request_done(host, data->mrq); + return; } + omap_hsmmc_start_command(host, data->stop, NULL); } /* @@ -1859,7 +1851,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->mapbase = res->start + pdata->reg_offset; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; - host->flags = AUTO_CMD12; host->next_data.cookie = 1; platform_set_drvdata(pdev, host); -- GitLab From 1d633fd153844c8e954b0b72789279bf588cd025 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:11 +0200 Subject: [PATCH 2865/6849] staging: iio: fix generic_buffer print2byte() drop extra argument, move cast Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index bf553356fdad..361e481faac2 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -72,8 +72,7 @@ void print2byte(int input, struct iio_channel_info *info) val &= (1 << info->bits_used) - 1; val = (int16_t)(val << (16 - info->bits_used)) >> (16 - info->bits_used); - printf("%05f ", val, - (float)(val + info->offset)*info->scale); + printf("%05f ", ((float)val + info->offset)*info->scale); } else { uint16_t val = input; val &= (1 << info->bits_used) - 1; -- GitLab From 109379210eb57a252e245363659168a1f1ab8691 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:12 +0200 Subject: [PATCH 2866/6849] staging: iio: remove unused variable Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 2 -- drivers/staging/iio/Documentation/iio_utils.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 361e481faac2..7b2a12c3e9d9 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -131,8 +131,6 @@ int main(int argc, char **argv) int ret, c, i, j, toread; - - FILE *fp_ev; int fp; int num_channels; diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 6f3a392297ec..6fe8540090be 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -280,7 +280,7 @@ inline int build_channel_array(const char *device_dir, { DIR *dp; FILE *sysfsfp; - int count, temp, i; + int count, i; struct iio_channel_info *current; int ret; const struct dirent *ent; -- GitLab From b42f2a0c65e7325674711dcda99c4e93ed9e4698 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:13 +0200 Subject: [PATCH 2867/6849] staging: iio: move comment Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 6fe8540090be..d9439f8f71fd 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -7,7 +7,6 @@ * the Free Software Foundation. */ -/* Made up value to limit allocation sizes */ #include #include #include @@ -15,6 +14,7 @@ #include #include +/* Made up value to limit allocation sizes */ #define IIO_MAX_NAME_LENGTH 30 #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" -- GitLab From d8da0eeed738dbbe9d9ff793bb8f047c2cc474b7 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:14 +0200 Subject: [PATCH 2868/6849] staging: iio: generic_buffer cleanup Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../iio/Documentation/generic_buffer.c | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 7b2a12c3e9d9..b89b72182200 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -33,8 +33,8 @@ /** * size_from_channelarray() - calculate the storage size of a scan - * @channels: the channel info array - * @num_channels: size of the channel info array + * @channels: the channel info array + * @num_channels: number of channels * * Has the side effect of filling the channels[i].location values used * in processing the buffer output. @@ -58,14 +58,15 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels) void print2byte(int input, struct iio_channel_info *info) { /* First swap if incorrect endian */ - if (info->be) input = be16toh((uint16_t)input); else input = le16toh((uint16_t)input); - /* shift before conversion to avoid sign extension - of left aligned data */ + /* + * Shift before conversion to avoid sign extension + * of left aligned data + */ input = input >> info->shift; if (info->is_signed) { int16_t val = input; @@ -82,39 +83,39 @@ void print2byte(int input, struct iio_channel_info *info) /** * process_scan() - print out the values in SI units * @data: pointer to the start of the scan - * @infoarray: information about the channels. Note + * @channels: information about the channels. Note * size_from_channelarray must have been called first to fill the * location offsets. - * @num_channels: the number of active channels + * @num_channels: number of channels **/ void process_scan(char *data, - struct iio_channel_info *infoarray, + struct iio_channel_info *channels, int num_channels) { int k; for (k = 0; k < num_channels; k++) - switch (infoarray[k].bytes) { + switch (channels[k].bytes) { /* only a few cases implemented so far */ case 2: - print2byte(*(uint16_t *)(data + infoarray[k].location), - &infoarray[k]); + print2byte(*(uint16_t *)(data + channels[k].location), + &channels[k]); break; case 8: - if (infoarray[k].is_signed) { + if (channels[k].is_signed) { int64_t val = *(int64_t *) (data + - infoarray[k].location); - if ((val >> infoarray[k].bits_used) & 1) - val = (val & infoarray[k].mask) | - ~infoarray[k].mask; + channels[k].location); + if ((val >> channels[k].bits_used) & 1) + val = (val & channels[k].mask) | + ~channels[k].mask; /* special case for timestamp */ - if (infoarray[k].scale == 1.0f && - infoarray[k].offset == 0.0f) + if (channels[k].scale == 1.0f && + channels[k].offset == 0.0f) printf(" %lld", val); else printf("%05f ", ((float)val + - infoarray[k].offset)* - infoarray[k].scale); + channels[k].offset)* + channels[k].scale); } break; default: @@ -129,7 +130,6 @@ int main(int argc, char **argv) unsigned long timedelay = 1000000; unsigned long buf_len = 128; - int ret, c, i, j, toread; int fp; @@ -146,7 +146,7 @@ int main(int argc, char **argv) int noevents = 0; char *dummy; - struct iio_channel_info *infoarray; + struct iio_channel_info *channels; while ((c = getopt(argc, argv, "l:w:c:et:n:")) != -1) { switch (c) { @@ -189,7 +189,7 @@ int main(int argc, char **argv) asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); if (trigger_name == NULL) { /* - * Build the trigger name. If it is device associated it's + * Build the trigger name. If it is device associated its * name is _dev[n] where n matches the device * number found above */ @@ -214,7 +214,7 @@ int main(int argc, char **argv) * Parse the files in scan_elements to identify what channels are * present */ - ret = build_channel_array(dev_dir_name, &infoarray, &num_channels); + ret = build_channel_array(dev_dir_name, &channels, &num_channels); if (ret) { printf("Problem reading scan element information\n"); printf("diag %s\n", dev_dir_name); @@ -233,7 +233,7 @@ int main(int argc, char **argv) goto error_free_triggername; } printf("%s %s\n", dev_dir_name, trigger_name); - /* Set the device trigger to be the data rdy trigger found above */ + /* Set the device trigger to be the data ready trigger found above */ ret = write_sysfs_string_and_verify("trigger/current_trigger", dev_dir_name, trigger_name); @@ -251,7 +251,7 @@ int main(int argc, char **argv) ret = write_sysfs_int("enable", buf_dir_name, 1); if (ret < 0) goto error_free_buf_dir_name; - scan_size = size_from_channelarray(infoarray, num_channels); + scan_size = size_from_channelarray(channels, num_channels); data = malloc(scan_size*buf_len); if (!data) { ret = -ENOMEM; @@ -266,7 +266,7 @@ int main(int argc, char **argv) /* Attempt to open non blocking the access dev */ fp = open(buffer_access, O_RDONLY | O_NONBLOCK); - if (fp == -1) { /*If it isn't there make the node */ + if (fp == -1) { /* If it isn't there make the node */ printf("Failed to open %s\n", buffer_access); ret = -errno; goto error_free_buffer_access; @@ -297,16 +297,16 @@ int main(int argc, char **argv) } for (i = 0; i < read_size/scan_size; i++) process_scan(data + scan_size*i, - infoarray, + channels, num_channels); } - /* Stop the ring buffer */ + /* Stop the buffer */ ret = write_sysfs_int("enable", buf_dir_name, 0); if (ret < 0) goto error_close_buffer_access; - /* Disconnect from the trigger - just write a dummy name.*/ + /* Disconnect the trigger - just write a dummy name. */ write_sysfs_string("trigger/current_trigger", dev_dir_name, "NULL"); -- GitLab From 42196d396378f4e4658dbe157d78fd23bce6bbbd Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:15 +0200 Subject: [PATCH 2869/6849] staging: iio: fix warning 'static but used in inline function' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iio_utils.h:367:10: warning: ‘iioutils_break_up_name’ is static but used in inline function ‘build_channel_array’ which is not static [enabled by default] Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index d9439f8f71fd..9c7a5aa5e2c7 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -27,7 +27,7 @@ const char *iio_dir = "/sys/bus/iio/devices/"; * @full_name: the full channel name * @generic_name: the output generic channel name **/ -static int iioutils_break_up_name(const char *full_name, +inline int iioutils_break_up_name(const char *full_name, char **generic_name) { char *current; -- GitLab From 1bcdfbcf7599a42f7aa0e41c88df178fecebc909 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:16 +0200 Subject: [PATCH 2870/6849] staging: iio: use PRId64 format specifier for int64_t Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index b89b72182200..b16c4b208ae4 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "iio_utils.h" /** @@ -111,7 +112,7 @@ void process_scan(char *data, /* special case for timestamp */ if (channels[k].scale == 1.0f && channels[k].offset == 0.0f) - printf(" %lld", val); + printf("%" PRId64 " ", val); else printf("%05f ", ((float)val + channels[k].offset)* -- GitLab From bb23378c0b1c9a410d40adea74276544a00fb94e Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:12:17 +0200 Subject: [PATCH 2871/6849] staging: iio: quell asprintf() warning, missing #includes Signed-off-by: Peter Meerwald Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 3 +++ drivers/staging/iio/Documentation/iio_utils.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index b16c4b208ae4..827e92de8e30 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -18,6 +18,8 @@ * */ +#define _GNU_SOURCE + #include #include #include @@ -29,6 +31,7 @@ #include #include #include +#include #include #include "iio_utils.h" diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 9c7a5aa5e2c7..c0448b3e20de 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -13,6 +13,7 @@ #include #include #include +#include /* Made up value to limit allocation sizes */ #define IIO_MAX_NAME_LENGTH 30 -- GitLab From 90e6dc7c274dca8a9198e3525488ea991719a799 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 26 Jun 2012 10:43:05 +0200 Subject: [PATCH 2872/6849] iio:adc:at91: Relase mutex on error path in at91_adc_read_raw This issue was reported by the mini_lock.cocci coccinelle semantic patch. Signed-off-by: Lars-Peter Clausen Acked-by: Maxime Ripard Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/at91_adc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 6a084695b77e..f61780a02374 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -349,9 +349,11 @@ static int at91_adc_read_raw(struct iio_dev *idev, st->done, msecs_to_jiffies(1000)); if (ret == 0) - return -ETIMEDOUT; - else if (ret < 0) + ret = -ETIMEDOUT; + if (ret < 0) { + mutex_unlock(&st->lock); return ret; + } *val = st->last_value; -- GitLab From 779c0c4619f57ab0d573468baa7a791db402e9f9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 26 Jun 2012 10:45:43 +0200 Subject: [PATCH 2873/6849] iio:dac:ad5446: Add support for the AD5450/51/52/53 This patch adds support for the Analog Devices AD5450/51/52/53 Digital-to-Analog converters. The AD5452 and AD5453 are software compatible to the existing AD5444 and AD5446. The AD5450 and AD5451 are similar but have a smaller resolution. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/Kconfig | 6 +++--- drivers/iio/dac/ad5446.c | 12 ++++++++++++ drivers/iio/dac/ad5446.h | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 92fb3a003510..afd207e171cf 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -59,9 +59,9 @@ config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" depends on SPI help - Say yes here to build support for Analog Devices AD5444, AD5446, - AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, - AD5621, AD5640, AD5660, AD5662 DACs. + Say yes here to build support for Analog Devices AD5444, AD5446, AD5450, + AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, + AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 49f557fc673b..2ca5059ef89e 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -147,6 +147,14 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .channel = AD5446_CHANNEL(14, 16, 0), .write = ad5446_write, }, + [ID_AD5450] = { + .channel = AD5446_CHANNEL(8, 16, 6), + .write = ad5446_write, + }, + [ID_AD5451] = { + .channel = AD5446_CHANNEL(10, 16, 4), + .write = ad5446_write, + }, [ID_AD5541A] = { .channel = AD5446_CHANNEL(16, 16, 0), .write = ad5446_write, @@ -346,6 +354,10 @@ static int ad5446_remove(struct spi_device *spi) static const struct spi_device_id ad5446_id[] = { {"ad5444", ID_AD5444}, {"ad5446", ID_AD5446}, + {"ad5450", ID_AD5450}, + {"ad5451", ID_AD5451}, + {"ad5452", ID_AD5444}, /* ad5452 is compatible to the ad5444 */ + {"ad5453", ID_AD5446}, /* ad5453 is compatible to the ad5446 */ {"ad5512a", ID_AD5512A}, {"ad5541a", ID_AD5541A}, {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */ diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h index dfd68ce7427e..2934269a56d5 100644 --- a/drivers/iio/dac/ad5446.h +++ b/drivers/iio/dac/ad5446.h @@ -71,6 +71,8 @@ struct ad5446_chip_info { enum ad5446_supported_device_ids { ID_AD5444, ID_AD5446, + ID_AD5450, + ID_AD5451, ID_AD5541A, ID_AD5512A, ID_AD5553, -- GitLab From 258767fed9da230553d92e2d53f5f872d55795b1 Mon Sep 17 00:00:00 2001 From: Sherwin Soltani Date: Tue, 26 Jun 2012 02:00:30 -0400 Subject: [PATCH 2874/6849] drivers: staging: android: binder.c: fix printk macros Change printk() messages to pr_* macros. Signed-off-by: Sherwin Soltani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/binder.c | 54 ++++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index c2832124bb3e..574e99210c36 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -124,13 +124,13 @@ module_param_call(stop_on_user_error, binder_set_stop_on_user_error, #define binder_debug(mask, x...) \ do { \ if (binder_debug_mask & mask) \ - printk(KERN_INFO x); \ + pr_info(x); \ } while (0) #define binder_user_error(x...) \ do { \ if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \ - printk(KERN_INFO x); \ + pr_info(x); \ if (binder_stop_on_user_error) \ binder_stop_on_user_error = 2; \ } while (0) @@ -418,7 +418,7 @@ repeat: #if 1 /* Sanity check */ if (fdt->fd[fd] != NULL) { - printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); + pr_warn("get_unused_fd: slot %d not NULL!\n", fd); fdt->fd[fd] = NULL; } #endif @@ -644,7 +644,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, goto free_range; if (vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed to " + pr_err("binder: %d: binder_alloc_buf failed to " "map pages in userspace, no vma\n", proc->pid); goto err_no_vma; } @@ -657,7 +657,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, BUG_ON(*page); *page = alloc_page(GFP_KERNEL | __GFP_ZERO); if (*page == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " + pr_err("binder: %d: binder_alloc_buf failed " "for page at %p\n", proc->pid, page_addr); goto err_alloc_page_failed; } @@ -666,7 +666,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, page_array_ptr = page; ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr); if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " + pr_err("binder: %d: binder_alloc_buf failed " "to map page at %p in kernel\n", proc->pid, page_addr); goto err_map_kernel_failed; @@ -675,7 +675,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, (uintptr_t)page_addr + proc->user_buffer_offset; ret = vm_insert_page(vma, user_page_addr, page[0]); if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " + pr_err("binder: %d: binder_alloc_buf failed " "to map page at %lx in userspace\n", proc->pid, user_page_addr); goto err_vm_insert_page_failed; @@ -724,7 +724,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, size_t size; if (proc->vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n", + pr_err("binder: %d: binder_alloc_buf, no vma\n", proc->pid); return NULL; } @@ -762,7 +762,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, } } if (best_fit == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, " + pr_err("binder: %d: binder_alloc_buf size %zd failed, " "no address space\n", proc->pid, size); return NULL; } @@ -997,7 +997,7 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal, node->internal_strong_refs == 0 && !(node == binder_context_mgr_node && node->has_strong_ref)) { - printk(KERN_ERR "binder: invalid inc strong " + pr_err("binder: invalid inc strong " "node for %d\n", node->debug_id); return -EINVAL; } @@ -1013,7 +1013,7 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal, node->local_weak_refs++; if (!node->has_weak_ref && list_empty(&node->work.entry)) { if (target_list == NULL) { - printk(KERN_ERR "binder: invalid inc weak node " + pr_err("binder: invalid inc weak node " "for %d\n", node->debug_id); return -EINVAL; } @@ -1276,7 +1276,7 @@ static void binder_send_failed_reply(struct binder_transaction *t, target_thread->return_error = error_code; wake_up_interruptible(&target_thread->wait); } else { - printk(KERN_ERR "binder: reply failed, target " + pr_err("binder: reply failed, target " "thread, %d:%d, has error code %d " "already\n", target_thread->proc->pid, target_thread->pid, @@ -1331,7 +1331,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, if (*offp > buffer->data_size - sizeof(*fp) || buffer->data_size < sizeof(*fp) || !IS_ALIGNED(*offp, sizeof(void *))) { - printk(KERN_ERR "binder: transaction release %d bad" + pr_err("binder: transaction release %d bad" "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); continue; @@ -1342,7 +1342,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_WEAK_BINDER: { struct binder_node *node = binder_get_node(proc, fp->binder); if (node == NULL) { - printk(KERN_ERR "binder: transaction release %d" + pr_err("binder: transaction release %d" " bad node %p\n", debug_id, fp->binder); break; } @@ -1355,7 +1355,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); if (ref == NULL) { - printk(KERN_ERR "binder: transaction release %d" + pr_err("binder: transaction release %d" " bad handle %ld\n", debug_id, fp->handle); break; @@ -1374,7 +1374,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, break; default: - printk(KERN_ERR "binder: transaction release %d bad " + pr_err("binder: transaction release %d bad " "object type %lx\n", debug_id, fp->type); break; } @@ -1925,10 +1925,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, break; } case BC_ATTEMPT_ACQUIRE: - printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n"); + pr_err("binder: BC_ATTEMPT_ACQUIRE not supported\n"); return -EINVAL; case BC_ACQUIRE_RESULT: - printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n"); + pr_err("binder: BC_ACQUIRE_RESULT not supported\n"); return -EINVAL; case BC_FREE_BUFFER: { @@ -2165,7 +2165,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } break; default: - printk(KERN_ERR "binder: %d:%d unknown command %d\n", + pr_err("binder: %d:%d unknown command %d\n", proc->pid, thread->pid, cmd); return -EINVAL; } @@ -2635,7 +2635,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; - /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ + /*pr_info("binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret) @@ -2701,13 +2701,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case BINDER_SET_CONTEXT_MGR: if (binder_context_mgr_node != NULL) { - printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n"); + pr_err("binder: BINDER_SET_CONTEXT_MGR already set\n"); ret = -EBUSY; goto err; } if (binder_context_mgr_uid != -1) { if (binder_context_mgr_uid != current->cred->euid) { - printk(KERN_ERR "binder: BINDER_SET_" + pr_err("binder: BINDER_SET_" "CONTEXT_MGR bad uid %d != %d\n", current->cred->euid, binder_context_mgr_uid); @@ -2753,7 +2753,7 @@ err: mutex_unlock(&binder_lock); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret && ret != -ERESTARTSYS) - printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); + pr_info("binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); return ret; } @@ -2829,7 +2829,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) #ifdef CONFIG_CPU_CACHE_VIPT if (cache_is_vipt_aliasing()) { while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) { - printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); + pr_info("binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); vma->vm_start += PAGE_SIZE; } } @@ -2861,7 +2861,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) proc->vma = vma; proc->vma_vm_mm = vma->vm_mm; - /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", + /*pr_info("binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ return 0; @@ -2876,7 +2876,7 @@ err_get_vm_area_failed: err_already_mapped: mutex_unlock(&binder_mmap_lock); err_bad_arg: - printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", + pr_err("binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); return ret; } @@ -3031,7 +3031,7 @@ static void binder_deferred_release(struct binder_proc *proc) if (t) { t->buffer = NULL; buffer->transaction = NULL; - printk(KERN_ERR "binder: release proc %d, " + pr_err("binder: release proc %d, " "transaction %d, not freed\n", proc->pid, t->debug_id); /*BUG();*/ -- GitLab From 9b1904c7cf2ff7e69ff2bbf2e0308a231e8064c2 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Tue, 26 Jun 2012 06:00:14 +0200 Subject: [PATCH 2875/6849] staging: sm7xxfb: dead code removal This patch removes dead code. Tested with SM712. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xx.h | 1 - drivers/staging/sm7xxfb/sm7xxfb.c | 4 ---- 2 files changed, 5 deletions(-) diff --git a/drivers/staging/sm7xxfb/sm7xx.h b/drivers/staging/sm7xxfb/sm7xx.h index 43d86f873410..333f33c3dc66 100644 --- a/drivers/staging/sm7xxfb/sm7xx.h +++ b/drivers/staging/sm7xxfb/sm7xx.h @@ -14,7 +14,6 @@ */ #define NR_PALETTE 256 -#define NR_RGB 2 #define FB_ACCEL_SMI_LYNX 88 diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 32111a011f66..4c741e2afd12 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -42,10 +42,6 @@ struct screen_info smtc_screen_info; struct smtcfb_info { struct fb_info fb; struct pci_dev *pdev; - struct { - u8 red, green, blue; - } palette[NR_RGB]; - u_int palette_size; u16 chipID; unsigned char __iomem *m_pMMIO; -- GitLab From 50b238b186d4ac77da07a0fa0261467f9431581b Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Tue, 26 Jun 2012 06:00:15 +0200 Subject: [PATCH 2876/6849] staging: sm7xxfb: dead code removal This patch removes dead code related to BaseAddressInVRAM. It fixes comment on RAM control bits too. Tested with SM712. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xxfb.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 4c741e2afd12..78da77903305 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -53,7 +53,7 @@ struct smtcfb_info { u_int width; u_int height; u_int hz; - u_long BaseAddressInVRAM; + u8 chipRevID; }; @@ -220,17 +220,9 @@ static void sm712_set_timing(struct smtcfb_info *sfb) static void sm712_setpalette(int regno, unsigned red, unsigned green, unsigned blue, struct fb_info *info) { - struct smtcfb_info *sfb = info->par; + /* set bit 5:4 = 01 (write LCD RAM only) */ + smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); - if (sfb->BaseAddressInVRAM) - /* - * second display palette for dual head. Enable CRT RAM, 6-bit - * RAM - */ - smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20); - else - /* primary display palette. Enable LCD RAM only, 6-bit RAM */ - smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); smtc_mmiowb(regno, dac_reg); smtc_mmiowb(red >> 10, dac_val); smtc_mmiowb(green >> 10, dac_val); @@ -932,8 +924,6 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, goto failed; smtcfb_setmode(sfb); - /* Primary display starting from 0 position */ - sfb->BaseAddressInVRAM = 0; err = register_framebuffer(&sfb->fb); if (err < 0) -- GitLab From 128e8616faff1a863ad9f8e865e255ee4d36bed4 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Tue, 26 Jun 2012 06:00:16 +0200 Subject: [PATCH 2877/6849] staging: sm7xxfb: delete unnecessary color map allocation This patchs erases fb_alloc_cmap call in smtc_free_fb_info. In the future, when needed, the required function to call here should be fb_dealloc_cmap. Tested with SM712. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xxfb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 78da77903305..e5d016b9259a 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -696,6 +696,14 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev, char *name) return sfb; } +/* + * free struct smtcfb_info + */ +static void smtc_free_fb_info(struct smtcfb_info *sfb) +{ + kfree(sfb); +} + /* * Unmap in the memory mapped IO registers */ @@ -755,14 +763,6 @@ static inline void sm7xx_init_hw(void) outb_p(0x11, 0x3c5); } -static void smtc_free_fb_info(struct smtcfb_info *sfb) -{ - if (sfb) { - fb_alloc_cmap(&sfb->fb.cmap, 0, 0); - kfree(sfb); - } -} - /* * sm712vga_setup - process command line options, get vga parameter * @options: string of options -- GitLab From f204739736fecee77280c7743b5409dd158a49a6 Mon Sep 17 00:00:00 2001 From: "Javier M. Mellid" Date: Tue, 26 Jun 2012 06:00:17 +0200 Subject: [PATCH 2878/6849] staging: sm7xxfb: code cleanup on smtcfb_setmode Code cleanup on smtcfb_setmode. Tested with SM712. Signed-off-by: Javier M. Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xxfb.c | 64 ++++++++++++++----------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index e5d016b9259a..16d2b5eda80c 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -557,55 +557,49 @@ void smtcfb_setmode(struct smtcfb_info *sfb) { switch (sfb->fb.var.bits_per_pixel) { case 32: - sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; - sfb->fb.fix.line_length = sfb->fb.var.xres * 4; - sfb->fb.var.red.length = 8; + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 4; + sfb->fb.var.red.length = 8; sfb->fb.var.green.length = 8; - sfb->fb.var.blue.length = 8; - sfb->fb.var.red.offset = 16; + sfb->fb.var.blue.length = 8; + sfb->fb.var.red.offset = 16; sfb->fb.var.green.offset = 8; - sfb->fb.var.blue.offset = 0; - - break; - case 8: - sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; - sfb->fb.fix.line_length = sfb->fb.var.xres; - sfb->fb.var.red.offset = 5; - sfb->fb.var.red.length = 3; - sfb->fb.var.green.offset = 2; - sfb->fb.var.green.length = 3; - sfb->fb.var.blue.offset = 0; - sfb->fb.var.blue.length = 2; + sfb->fb.var.blue.offset = 0; break; case 24: - sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; - sfb->fb.fix.line_length = sfb->fb.var.xres * 3; - sfb->fb.var.red.length = 8; + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 3; + sfb->fb.var.red.length = 8; sfb->fb.var.green.length = 8; - sfb->fb.var.blue.length = 8; - - sfb->fb.var.red.offset = 16; + sfb->fb.var.blue.length = 8; + sfb->fb.var.red.offset = 16; sfb->fb.var.green.offset = 8; - sfb->fb.var.blue.offset = 0; - + sfb->fb.var.blue.offset = 0; + break; + case 8: + sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres; + sfb->fb.var.red.length = 3; + sfb->fb.var.green.length = 3; + sfb->fb.var.blue.length = 2; + sfb->fb.var.red.offset = 5; + sfb->fb.var.green.offset = 2; + sfb->fb.var.blue.offset = 0; break; case 16: default: - sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; - sfb->fb.fix.line_length = sfb->fb.var.xres * 2; - - sfb->fb.var.red.length = 5; + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length = sfb->fb.var.xres * 2; + sfb->fb.var.red.length = 5; sfb->fb.var.green.length = 6; - sfb->fb.var.blue.length = 5; - - sfb->fb.var.red.offset = 11; + sfb->fb.var.blue.length = 5; + sfb->fb.var.red.offset = 11; sfb->fb.var.green.offset = 5; - sfb->fb.var.blue.offset = 0; - + sfb->fb.var.blue.offset = 0; break; } - sfb->width = sfb->fb.var.xres; + sfb->width = sfb->fb.var.xres; sfb->height = sfb->fb.var.yres; sfb->hz = 60; smtc_set_timing(sfb); -- GitLab From ba0a7ae713c89c7be204646d9a34c7f612743f51 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Tue, 26 Jun 2012 13:03:39 +0100 Subject: [PATCH 2879/6849] staging: ozwpan: Unregister with sysfs while unloading. Destroy device node & unregister device class from sysfs while unloading driver Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozcdev.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 929756abf02c..d98321945802 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -42,6 +42,7 @@ struct oz_serial_ctx { /*------------------------------------------------------------------------------ */ static struct oz_cdev g_cdev; +struct class *g_oz_class; /*------------------------------------------------------------------------------ * Context: process and softirq */ @@ -330,7 +331,6 @@ const struct file_operations oz_fops = { int oz_cdev_register(void) { int err; - struct class *cl; struct device *dev; memset(&g_cdev, 0, sizeof(g_cdev)); err = alloc_chrdev_region(&g_cdev.devnum, 0, 1, "ozwpan"); @@ -348,12 +348,12 @@ int oz_cdev_register(void) oz_trace("Failed to add cdev\n"); goto out2; } - cl = class_create(THIS_MODULE, "ozmo_wpan"); - if (IS_ERR(cl)) { + g_oz_class = class_create(THIS_MODULE, "ozmo_wpan"); + if (IS_ERR(g_oz_class)) { oz_trace("Failed to register ozmo_wpan class\n"); goto out1; } - dev = device_create(cl, NULL, g_cdev.devnum, NULL, "ozwpan"); + dev = device_create(g_oz_class, NULL, g_cdev.devnum, NULL, "ozwpan"); if (IS_ERR(dev)) { oz_trace("Failed to create sysfs entry for cdev\n"); goto out1; @@ -373,6 +373,10 @@ int oz_cdev_deregister(void) { cdev_del(&g_cdev.cdev); unregister_chrdev_region(g_cdev.devnum, 1); + if (g_oz_class) { + device_destroy(g_oz_class, g_cdev.devnum); + class_destroy(g_oz_class); + } return 0; } /*------------------------------------------------------------------------------ -- GitLab From 4b29a3058c080fe6f76ae90e0e792e21000deb16 Mon Sep 17 00:00:00 2001 From: Rupesh Gujare Date: Tue, 26 Jun 2012 13:03:41 +0100 Subject: [PATCH 2880/6849] staging: ozwpan: Update TODO file Update TODO file. Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/TODO | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/ozwpan/TODO b/drivers/staging/ozwpan/TODO index c2d30a7112f3..b5db2456bffa 100644 --- a/drivers/staging/ozwpan/TODO +++ b/drivers/staging/ozwpan/TODO @@ -1,10 +1,11 @@ TODO: - - review user mode interface and determine if ioctls can be replaced - with something better. correctly export data structures to user mode - if ioctls are still required and allocate ioctl numbers from - ioctl-number.txt. + - Convert event tracing code to in-kernel tracing infrastructure + - Check for remaining ioctl & check if that can be converted into + sysfs entries + - Convert debug prints to appropriate dev_debug or something better + - Modify Kconfig to add CONFIG option for enabling/disabling event + tracing. - check USB HCD implementation is complete and correct. - - remove any debug and trace code. - code review by USB developer community. - testing with as many devices as possible. -- GitLab From ea8d385436d956984ab5875c778a13a91033e0d3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 25 Jun 2012 19:49:35 +0100 Subject: [PATCH 2881/6849] staging: comedi: split CONFIG_COMEDI_NI_TIO option Selecting the CONFIG_COMEDI_NI_TIO config option causes the 'ni_tio' and 'ni_tiocmd' modules to be built. CONFIG_COMEDI_NI_TIO depends on CONFIG_COMEDI_MITE which in turn depends on CONFIG_PCI. However, not all the drivers that need the 'ni_tio' module also need the 'ni_tiocmd' module. Specifically, the ISA and PCMCIA drivers do not need the 'ni_tiocmd' module. Add a new config option CONFIG_COMEDI_NI_TIOCMD to control building of the 'ni_tiocmd' module. It depends on CONFIG_COMEDI_NI_TIO and CONFIG_COMEDI_MITE. The existing CONFIG_COMEDI_NI_TIO option no longer needs to depend on CONFIG_COMEDI_MITE. Make CONFIG_COMEDI_NI_660X ('ni_660x' module) and CONFIG_COMEDI_NI_PCIMIO ('ni_pcimio' module) depend on CONFIG_COMEDI_NI_TIOCMD instead of CONFIG_COMEDI_NI_TIO. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 21 ++++++++++++++++----- drivers/staging/comedi/drivers/Makefile | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 04155202991c..2ffbc35b6f01 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1007,7 +1007,7 @@ config COMEDI_NI_65XX config COMEDI_NI_660X tristate "NI 660x counter/timer PCI card support" - depends on COMEDI_NI_TIO && COMEDI_NI_COMMON + depends on COMEDI_NI_TIOCMD && COMEDI_NI_COMMON ---help--- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, PXI-6602 and PXI-6608. @@ -1040,7 +1040,7 @@ config COMEDI_NI_PCIDIO config COMEDI_NI_PCIMIO tristate "NI PCI-MIO-E series and M series support" - depends on COMEDI_NI_TIO && COMEDI_NI_COMMON + depends on COMEDI_NI_TIOCMD && COMEDI_NI_COMMON select COMEDI_8255 select COMEDI_FC ---help--- @@ -1256,15 +1256,26 @@ config COMEDI_MITE config COMEDI_NI_TIO tristate "NI general purpose counter support" - depends on COMEDI_MITE ---help--- Enable support for National Instruments general purpose counters. This module is not used directly by end-users. Rather, it is used by other drivers (for example ni_660x and ni_pcimio) to provide support for NI's general purpose counters. - To compile this driver as a modules, choose M here: two modules will - be build: ni_tio and ni_tiocmd. + To compile this driver as a module, choose M here: the module will + be called ni_tio. + +config COMEDI_NI_TIOCMD + tristate "NI streaming acquisition for general purpose counters" + depends on COMEDI_NI_TIO && COMEDI_MITE + ---help--- + Enable streaming acquisition command support for National Instruments + general purpose counters. This module is not used directly by + end-users. It is used by some NI PCI card drivers (ni_660x and + ni_pcimio). + + To compile this driver as a module, choose M here: the module will + be called ni_tiocmd. config COMEDI_NI_LABPC tristate "NI Lab-PC and compatibles ISA and PCI support" diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 513469d943bf..57b19e44d867 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -131,7 +131,7 @@ obj-$(CONFIG_COMEDI_VMK80XX) += vmk80xx.o # Comedi NI drivers obj-$(CONFIG_COMEDI_MITE) += mite.o obj-$(CONFIG_COMEDI_NI_TIO) += ni_tio.o -obj-$(CONFIG_COMEDI_NI_TIO) += ni_tiocmd.o +obj-$(CONFIG_COMEDI_NI_TIOCMD) += ni_tiocmd.o obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc.o obj-$(CONFIG_COMEDI_8255) += 8255.o -- GitLab From 2f2ac8ec08ae9e2d3f8ef24f40064a938a86b6f1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 25 Jun 2012 19:49:36 +0100 Subject: [PATCH 2882/6849] staging: comedi: Move COMEDI_NI_LABPC config option Move the CONFIG_COMEDI_NI_LABPC option ("NI Lab-PC and compatibles ISA and PCI support") from the CONFIG_COMEDI_NI_COMMON menu ("Comedi National Instruments card support --->") to the CONFIG_COMEDI_PCI_DRIVERS menu ("Comedi PCI drivers --->"). It currently depends on PCI but should be split up into separate ISA and PCI config options eventually as was done for the "das08" driver. For now, the PCI card menu seems the best place for it and I plan to get rid of the CONFIG_COMEDI_NI_COMMON menu altogether. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 2ffbc35b6f01..2d1e47df87fd 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1024,6 +1024,21 @@ config COMEDI_NI_670X To compile this driver as a module, choose M here: the module will be called ni_670x. +config COMEDI_NI_LABPC + tristate "NI Lab-PC and compatibles ISA and PCI support" + depends on COMEDI_MITE + select COMEDI_8255 + select COMEDI_FC + depends on VIRT_TO_BUS + ---help--- + Enable support for National Instruments Lab-PC and compatibles + Lab-PC-1200, Lab-PC-1200AI, Lab-PC+ and PCI-1200. + Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has + not yet been added to the driver. + + To compile this driver as a module, choose M here: the module will be + called ni_labpc. + config COMEDI_NI_PCIDIO tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support" depends on COMEDI_MITE @@ -1277,21 +1292,6 @@ config COMEDI_NI_TIOCMD To compile this driver as a module, choose M here: the module will be called ni_tiocmd. -config COMEDI_NI_LABPC - tristate "NI Lab-PC and compatibles ISA and PCI support" - depends on COMEDI_MITE - select COMEDI_8255 - select COMEDI_FC - depends on VIRT_TO_BUS - ---help--- - Enable support for National Instruments Lab-PC and compatibles - Lab-PC-1200, Lab-PC-1200AI, Lab-PC+ and PCI-1200. - Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has - not yet been added to the driver. - - To compile this driver as a module, choose M here: the module will be - called ni_labpc. - endif # COMEDI_NI_COMMON config COMEDI_8255 -- GitLab From 7ac21b82be42b6414ba9fa170263376ee2326925 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 25 Jun 2012 19:49:37 +0100 Subject: [PATCH 2883/6849] staging: comedi: Simplify NI driver configuration At the moment, the options to select drivers for various National Instruments boards in the "Comedi PCI drivers", "Comedi ISA and PC/104 drivers" and "Comedi PCMCIA drivers" menus do not appear unless you first enable and enter the "Comedi National Instruments card support" menu and possibly select some of the options in there. This is pretty confusing for the user. Get rid of the "Comedi National Instruments card support" menu (CONFIG_COMEDI_NI_COMMON) and make the CONFIG_COMEDI_MITE, CONFIG_COMEDI_NI_TIO and CONFIG_COMEDI_NI_TIOCMD options selectable by other options instead of dependencies of those other options. We lose the ability to build the 'mite', 'ni_tio' and 'ni_tiocmd' modules independently of other modules, but they are not useful on their own anyway. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 69 ++++++++-------------------------- 1 file changed, 16 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 2d1e47df87fd..9ff3f4d8c4dd 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -444,7 +444,6 @@ config COMEDI_ADQ12B config COMEDI_NI_AT_A2150 tristate "NI AT-A2150 ISA card support" - depends on COMEDI_NI_COMMON depends on VIRT_TO_BUS ---help--- Enable support for National Instruments AT-A2150 cards @@ -454,7 +453,6 @@ config COMEDI_NI_AT_A2150 config COMEDI_NI_AT_AO tristate "NI AT-AO-6/10 EISA card support" - depends on COMEDI_NI_COMMON ---help--- Enable support for National Instruments AT-AO-6/10 cards @@ -463,8 +461,9 @@ config COMEDI_NI_AT_AO config COMEDI_NI_ATMIO tristate "NI AT-MIO E series ISA-PNP card support" - depends on ISAPNP && COMEDI_NI_TIO && COMEDI_NI_COMMON + depends on ISAPNP select COMEDI_8255 + select COMEDI_NI_TIO ---help--- Enable support for National Instruments AT-MIO E series cards National Instruments AT-MIO-16E-1 (ni_atmio), @@ -476,7 +475,7 @@ config COMEDI_NI_ATMIO config COMEDI_NI_ATMIO16D tristate "NI AT-MIO16/AT-MIO16D series ISA-PNP card support" - depends on ISAPNP && COMEDI_NI_COMMON + depends on ISAPNP select COMEDI_8255 ---help--- Enable support for National Instruments AT-MIO16/AT-MIO16D cards. @@ -985,7 +984,7 @@ config COMEDI_ME_DAQ config COMEDI_NI_6527 tristate "NI 6527 support" - depends on COMEDI_MITE + select COMEDI_MITE ---help--- Enable support for the National Instruments 6527 PCI card @@ -994,7 +993,7 @@ config COMEDI_NI_6527 config COMEDI_NI_65XX tristate "NI 65xx static dio PCI card support" - depends on COMEDI_MITE + select COMEDI_MITE ---help--- Enable support for National Instruments 65xx static dio boards. Supported devices: National Instruments PCI-6509 (ni_65xx), @@ -1007,7 +1006,7 @@ config COMEDI_NI_65XX config COMEDI_NI_660X tristate "NI 660x counter/timer PCI card support" - depends on COMEDI_NI_TIOCMD && COMEDI_NI_COMMON + select COMEDI_NI_TIOCMD ---help--- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, PXI-6602 and PXI-6608. @@ -1017,7 +1016,7 @@ config COMEDI_NI_660X config COMEDI_NI_670X tristate "NI 670x PCI card support" - depends on COMEDI_MITE + select COMEDI_MITE ---help--- Enable support for National Instruments PCI-6703 and PCI-6704 @@ -1026,7 +1025,7 @@ config COMEDI_NI_670X config COMEDI_NI_LABPC tristate "NI Lab-PC and compatibles ISA and PCI support" - depends on COMEDI_MITE + select COMEDI_MITE select COMEDI_8255 select COMEDI_FC depends on VIRT_TO_BUS @@ -1041,7 +1040,7 @@ config COMEDI_NI_LABPC config COMEDI_NI_PCIDIO tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support" - depends on COMEDI_MITE + select COMEDI_MITE select COMEDI_8255 ---help--- Enable support for National Instruments PCI-DIO-32HS, PXI-6533, @@ -1055,7 +1054,7 @@ config COMEDI_NI_PCIDIO config COMEDI_NI_PCIMIO tristate "NI PCI-MIO-E series and M series support" - depends on COMEDI_NI_TIOCMD && COMEDI_NI_COMMON + select COMEDI_NI_TIOCMD select COMEDI_8255 select COMEDI_FC ---help--- @@ -1141,7 +1140,6 @@ config COMEDI_DAS08_CS config COMEDI_NI_DAQ_700_CS tristate "NI DAQCard-700 PCMCIA support" - depends on COMEDI_NI_COMMON ---help--- Enable support for the National Instruments PCMCIA DAQCard-700 DIO @@ -1150,7 +1148,6 @@ config COMEDI_NI_DAQ_700_CS config COMEDI_NI_DAQ_DIO24_CS tristate "NI DAQ-Card DIO-24 PCMCIA support" - depends on COMEDI_NI_COMMON select COMEDI_8255 ---help--- Enable support for the National Instruments PCMCIA DAQ-Card DIO-24 @@ -1169,7 +1166,7 @@ config COMEDI_NI_LABPC_CS config COMEDI_NI_MIO_CS tristate "NI DAQCard E series PCMCIA support" - depends on COMEDI_NI_TIO && COMEDI_NI_COMMON + select COMEDI_NI_TIO select COMEDI_8255 select COMEDI_FC ---help--- @@ -1248,51 +1245,17 @@ config COMEDI_VMK80XX endif # COMEDI_USB_DRIVERS -menuconfig COMEDI_NI_COMMON - tristate "Comedi National Instruments card support" - ---help--- - Enable comedi support for National Instruments cards. - Modules in this section are used by many comedi NI drivers. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about National Instruments cards. - -if COMEDI_NI_COMMON - config COMEDI_MITE - tristate "NI Mite PCI interface chip support" + tristate depends on PCI - ---help--- - Enable support for National Instruments Mite PCI interface chip - - To compile this driver as a module, choose M here: the module will be - called mite. config COMEDI_NI_TIO - tristate "NI general purpose counter support" - ---help--- - Enable support for National Instruments general purpose counters. - This module is not used directly by end-users. Rather, it - is used by other drivers (for example ni_660x and ni_pcimio) - to provide support for NI's general purpose counters. - - To compile this driver as a module, choose M here: the module will - be called ni_tio. + tristate config COMEDI_NI_TIOCMD - tristate "NI streaming acquisition for general purpose counters" - depends on COMEDI_NI_TIO && COMEDI_MITE - ---help--- - Enable streaming acquisition command support for National Instruments - general purpose counters. This module is not used directly by - end-users. It is used by some NI PCI card drivers (ni_660x and - ni_pcimio). - - To compile this driver as a module, choose M here: the module will - be called ni_tiocmd. - -endif # COMEDI_NI_COMMON + tristate + select COMEDI_NI_TIO + select COMEDI_MITE config COMEDI_8255 tristate "Generic 8255 support" -- GitLab From a77198816e193a88b9c10ce13f0d2e172df0c6b5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 25 Jun 2012 19:49:38 +0100 Subject: [PATCH 2884/6849] staging: comedi: Move COMEDI_MITE and COMEDI_NI_TIOCMD Move the CONFIG_COMEDI_MITE config options into the `if COMEDI_PCI_DRIVERS` block so that the `depends on PCI` condition can be omitted. Move the CONFIG_COMEDI_NI_TIOCMD config option to the same block as it selects COMEDI_MITE. Move the CONFIG_COEMDI_NI_TIO config option slightly for aesthetic reasons without changing its conditions. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 9ff3f4d8c4dd..6cee7855b019 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1105,6 +1105,14 @@ config COMEDI_SSV_DNP To compile this driver as a module, choose M here: the module will be called ssv_dnp. +config COMEDI_MITE + tristate + +config COMEDI_NI_TIOCMD + tristate + select COMEDI_NI_TIO + select COMEDI_MITE + endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS @@ -1245,18 +1253,6 @@ config COMEDI_VMK80XX endif # COMEDI_USB_DRIVERS -config COMEDI_MITE - tristate - depends on PCI - -config COMEDI_NI_TIO - tristate - -config COMEDI_NI_TIOCMD - tristate - select COMEDI_NI_TIO - select COMEDI_MITE - config COMEDI_8255 tristate "Generic 8255 support" ---help--- @@ -1290,4 +1286,7 @@ config COMEDI_DAS08 tristate select COMEDI_8255 +config COMEDI_NI_TIO + tristate + endif # COMEDI -- GitLab From 726dd505511d7be7234f3a2135b82b37d9026992 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 15:15:58 -0700 Subject: [PATCH 2885/6849] staging: comedi: cb_das16_cs: remove CONFIG_PCMCIA check The Kconfig ensures that this driver can only be build it PCMCIA is enabled. Remove the unneeded '#if defined (CONFIG_PCMCIA) ,,,' and the '#else' code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 6866e25543d1..1fd44602940e 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -629,8 +629,6 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, ======================================================================*/ -#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) - static void das16cs_pcmcia_config(struct pcmcia_device *link); static void das16cs_pcmcia_release(struct pcmcia_device *link); static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); @@ -813,18 +811,3 @@ void __exit cleanup_module(void) exit_das16cs_pcmcia_cs(); comedi_driver_unregister(&driver_das16cs); } - -#else -static int __init driver_das16cs_init_module(void) -{ - return comedi_driver_register(&driver_das16cs); -} - -static void __exit driver_das16cs_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das16cs); -} - -module_init(driver_das16cs_init_module); -module_exit(driver_das16cs_cleanup_module); -#endif /* CONFIG_PCMCIA */ -- GitLab From 16920671cd157c8ab2e431b4c612888d3085220e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 15:17:20 -0700 Subject: [PATCH 2886/6849] staging: comedi: cb_das16_cs: move the MODULE_* stuff to the EOF Move the MODULE_* declarations to the end of the file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 1fd44602940e..76833d0c663e 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -769,9 +769,6 @@ static const struct pcmcia_device_id das16cs_id_table[] = { }; MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); -MODULE_AUTHOR("David A. Schleef "); -MODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16"); -MODULE_LICENSE("GPL"); struct pcmcia_driver das16cs_driver = { .probe = das16cs_pcmcia_attach, @@ -811,3 +808,7 @@ void __exit cleanup_module(void) exit_das16cs_pcmcia_cs(); comedi_driver_unregister(&driver_das16cs); } + +MODULE_AUTHOR("David A. Schleef "); +MODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16"); +MODULE_LICENSE("GPL"); -- GitLab From 3bbb82c4b4150d4eb88bf3123bfb9ec51700730f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 15:18:17 -0700 Subject: [PATCH 2887/6849] staging: comedi: cb_das16_cs: add module_{init, exit} declarations The init and exit functions for this module were being declared as global symbols. Add the module_{init,exit} declarations and make the functions static. Also, rename the functions so they have namespace associated with the module. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 76833d0c663e..bca4cbeb06f2 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -792,7 +792,7 @@ static void __exit exit_das16cs_pcmcia_cs(void) pcmcia_unregister_driver(&das16cs_driver); } -int __init init_module(void) +static int __init das16cs_init(void) { int ret; @@ -802,12 +802,14 @@ int __init init_module(void) return comedi_driver_register(&driver_das16cs); } +module_init(das16cs_init); -void __exit cleanup_module(void) +static void __exit das16cs_exit(void) { exit_das16cs_pcmcia_cs(); comedi_driver_unregister(&driver_das16cs); } +module_exit(das16cs_exit); MODULE_AUTHOR("David A. Schleef "); MODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16"); -- GitLab From 6f47503dcca489144384e09a6fa0848b46434fd0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 15:20:13 -0700 Subject: [PATCH 2888/6849] staging: comedi: cb_das16_cs: consolidate the init and exit functions The register/unregister of the pcmcia driver is done is separate functions that are called by the module_{init,exit} routines. Simplify the code a bit by moving the register/unregister into the module_{init,exit} routines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index bca4cbeb06f2..624e00598668 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -780,23 +780,11 @@ struct pcmcia_driver das16cs_driver = { .name = "cb_das16_cs", }; -static int __init init_das16cs_pcmcia_cs(void) -{ - pcmcia_register_driver(&das16cs_driver); - return 0; -} - -static void __exit exit_das16cs_pcmcia_cs(void) -{ - pr_debug("das16cs_pcmcia_cs: unloading\n"); - pcmcia_unregister_driver(&das16cs_driver); -} - static int __init das16cs_init(void) { int ret; - ret = init_das16cs_pcmcia_cs(); + ret = pcmcia_register_driver(&das16cs_driver); if (ret < 0) return ret; @@ -806,7 +794,7 @@ module_init(das16cs_init); static void __exit das16cs_exit(void) { - exit_das16cs_pcmcia_cs(); + pcmcia_unregister_driver(&das16cs_driver); comedi_driver_unregister(&driver_das16cs); } module_exit(das16cs_exit); -- GitLab From 64c205f99790798fdcf42ea5093df1393a867e30 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 15:20:53 -0700 Subject: [PATCH 2889/6849] staging: comedi: cb_das13_cs: change driver registration order As done with the other comedi driver types, register the comedi_driver first then the pcmcia_driver. Also, make sure the pcmcia_driver registration succeeds and unregister the comedi_driver it it fails. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 624e00598668..625134fa9d52 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -784,11 +784,17 @@ static int __init das16cs_init(void) { int ret; - ret = pcmcia_register_driver(&das16cs_driver); + ret = comedi_driver_register(&driver_das16cs); if (ret < 0) return ret; - return comedi_driver_register(&driver_das16cs); + ret = pcmcia_register_driver(&das16cs_driver); + if (ret < 0) { + comedi_driver_unregister(&driver_das16cs); + return ret; + } + + return 0; } module_init(das16cs_init); -- GitLab From e8bed9c6f46893c7d1fc43539058346fd4fbbaf1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 15:57:49 -0700 Subject: [PATCH 2890/6849] staging: comedi: cb_das16_cs: cleanup the pcmcia_driver declaration For aesthetic reasons, add some whitespace to the declaration of the pcmcia_driver and reorder it a bit. Also, the symbol 'das16cs_driver' is only referenced in this file, make it static. This quiets the following sparse warning: warning: symbol 'das16cs_driver' was not declared. Should it be static? Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 625134fa9d52..2ac30f4b9e05 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -770,14 +770,14 @@ static const struct pcmcia_device_id das16cs_id_table[] = { MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); -struct pcmcia_driver das16cs_driver = { - .probe = das16cs_pcmcia_attach, - .remove = das16cs_pcmcia_detach, - .suspend = das16cs_pcmcia_suspend, - .resume = das16cs_pcmcia_resume, - .id_table = das16cs_id_table, - .owner = THIS_MODULE, - .name = "cb_das16_cs", +static struct pcmcia_driver das16cs_driver = { + .name = "cb_das16_cs", + .owner = THIS_MODULE, + .probe = das16cs_pcmcia_attach, + .remove = das16cs_pcmcia_detach, + .suspend = das16cs_pcmcia_suspend, + .resume = das16cs_pcmcia_resume, + .id_table = das16cs_id_table, }; static int __init das16cs_init(void) -- GitLab From 1b19f53e377a3e28ff3eaa2b041acbc74923189e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:10:37 -0700 Subject: [PATCH 2891/6849] staging: comedi: cb_das16_cs: remove some useless comments Remove some useless comments and whitespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 61 +++++--------------- 1 file changed, 13 insertions(+), 48 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 2ac30f4b9e05..2063215369ce 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -19,6 +19,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + PCMCIA support code for the is adapted from the dummy_cs.c driver + of the Linux PCMCIA Card Services package. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + */ /* Driver: cb_das16_cs @@ -616,58 +623,20 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, return -EINVAL; } -/* PCMCIA stuff */ - -/*====================================================================== - - The following pcmcia code for the pcm-das08 is adapted from the - dummy_cs.c driver of the Linux PCMCIA Card Services package. - - The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - -======================================================================*/ - static void das16cs_pcmcia_config(struct pcmcia_device *link); static void das16cs_pcmcia_release(struct pcmcia_device *link); static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev); -/* - The attach() and detach() entry points are used to create and destroy - "instances" of the driver, where each instance represents everything - needed to manage one actual PCMCIA card. -*/ - static int das16cs_pcmcia_attach(struct pcmcia_device *); static void das16cs_pcmcia_detach(struct pcmcia_device *); -/* - You'll also need to prototype all the functions that will actually - be used to talk to your device. See 'memory_cs' for a good example - of a fully self-sufficient driver; the other drivers rely more or - less on other parts of the kernel. -*/ - struct local_info_t { struct pcmcia_device *link; int stop; struct bus_operations *bus; }; -/*====================================================================== - - das16cs_pcmcia_attach() creates an "instance" of the driver, allocating - local data structures for one device. The device is registered - with Card Services. - - The dev_link structure is initialized, but we don't actually - configure the card at this point -- we wait until we receive a - card insertion event. - -======================================================================*/ - static int das16cs_pcmcia_attach(struct pcmcia_device *link) { struct local_info_t *local; @@ -686,7 +655,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) das16cs_pcmcia_config(link); return 0; -} /* das16cs_pcmcia_attach */ +} static void das16cs_pcmcia_detach(struct pcmcia_device *link) { @@ -696,8 +665,7 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link) das16cs_pcmcia_release(link); /* This points to the parent struct local_info_t struct */ kfree(link->priv); -} /* das16cs_pcmcia_detach */ - +} static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) @@ -734,13 +702,13 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) failed: das16cs_pcmcia_release(link); -} /* das16cs_pcmcia_config */ +} static void das16cs_pcmcia_release(struct pcmcia_device *link) { dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); pcmcia_disable_device(link); -} /* das16cs_pcmcia_release */ +} static int das16cs_pcmcia_suspend(struct pcmcia_device *link) { @@ -750,7 +718,7 @@ static int das16cs_pcmcia_suspend(struct pcmcia_device *link) local->stop = 1; return 0; -} /* das16cs_pcmcia_suspend */ +} static int das16cs_pcmcia_resume(struct pcmcia_device *link) { @@ -758,16 +726,13 @@ static int das16cs_pcmcia_resume(struct pcmcia_device *link) local->stop = 0; return 0; -} /* das16cs_pcmcia_resume */ - -/*====================================================================*/ +} static const struct pcmcia_device_id das16cs_id_table[] = { PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), PCMCIA_DEVICE_NULL }; - MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); static struct pcmcia_driver das16cs_driver = { -- GitLab From f19d8578fd4c1ed23e951d26f5f56392aaf202a1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:15:40 -0700 Subject: [PATCH 2892/6849] staging: comedi: cb_das16_cs: refactor the pcmcia support code Refactor the pcmcia support code to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 68 +++++++++----------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 2063215369ce..dc9c8231c476 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -623,48 +623,16 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, return -EINVAL; } -static void das16cs_pcmcia_config(struct pcmcia_device *link); -static void das16cs_pcmcia_release(struct pcmcia_device *link); -static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); -static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev); - -static int das16cs_pcmcia_attach(struct pcmcia_device *); -static void das16cs_pcmcia_detach(struct pcmcia_device *); - struct local_info_t { struct pcmcia_device *link; int stop; struct bus_operations *bus; }; -static int das16cs_pcmcia_attach(struct pcmcia_device *link) -{ - struct local_info_t *local; - - dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); - if (!local) - return -ENOMEM; - local->link = link; - link->priv = local; - - cur_dev = link; - - das16cs_pcmcia_config(link); - - return 0; -} - -static void das16cs_pcmcia_detach(struct pcmcia_device *link) +static void das16cs_pcmcia_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); - - ((struct local_info_t *)link->priv)->stop = 1; - das16cs_pcmcia_release(link); - /* This points to the parent struct local_info_t struct */ - kfree(link->priv); + dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); + pcmcia_disable_device(link); } static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, @@ -704,10 +672,34 @@ failed: das16cs_pcmcia_release(link); } -static void das16cs_pcmcia_release(struct pcmcia_device *link) +static int das16cs_pcmcia_attach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); - pcmcia_disable_device(link); + struct local_info_t *local; + + dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); + + /* Allocate space for private device-specific data */ + local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); + if (!local) + return -ENOMEM; + local->link = link; + link->priv = local; + + cur_dev = link; + + das16cs_pcmcia_config(link); + + return 0; +} + +static void das16cs_pcmcia_detach(struct pcmcia_device *link) +{ + dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); + + ((struct local_info_t *)link->priv)->stop = 1; + das16cs_pcmcia_release(link); + /* This points to the parent struct local_info_t struct */ + kfree(link->priv); } static int das16cs_pcmcia_suspend(struct pcmcia_device *link) -- GitLab From c2107ff46d58a9db6d8cadcbe18fa631fb4f7cd9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:19:32 -0700 Subject: [PATCH 2893/6849] staging: comedi: cb_das16_cs: refactor the pcmcia attach/detach Move the pcmcia_disable_device() call where needed in the pcmcia attach/detach and delete the das16cs_pcmcia_release() function. Move the logic of das16cs_pcmcia_config() directly into the attach function and properly return an error code when the config fails. Only set the cur_dev, used by the comedi_driver, if the pcmcia attach is successful. Also, make sure to NULL it in the detach. Remove all the kernel messages in the pcmcia support code. They are just added noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 51 ++++++-------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index dc9c8231c476..5171cfe29b08 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -629,12 +629,6 @@ struct local_info_t { struct bus_operations *bus; }; -static void das16cs_pcmcia_release(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); - pcmcia_disable_device(link); -} - static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { @@ -644,20 +638,24 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, return pcmcia_request_io(p_dev); } -static void das16cs_pcmcia_config(struct pcmcia_device *link) +static int das16cs_pcmcia_attach(struct pcmcia_device *link) { + struct local_info_t *local; int ret; - dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); + /* Allocate space for private device-specific data */ + local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); + if (!local) + return -ENOMEM; + local->link = link; + link->priv = local; /* Do we need to allocate an interrupt? */ link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); + if (ret) goto failed; - } if (!link->irq) goto failed; @@ -666,40 +664,21 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) if (ret) goto failed; - return; - -failed: - das16cs_pcmcia_release(link); -} - -static int das16cs_pcmcia_attach(struct pcmcia_device *link) -{ - struct local_info_t *local; - - dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); - if (!local) - return -ENOMEM; - local->link = link; - link->priv = local; - cur_dev = link; - - das16cs_pcmcia_config(link); - return 0; + +failed: + pcmcia_disable_device(link); + return ret; } static void das16cs_pcmcia_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); - ((struct local_info_t *)link->priv)->stop = 1; - das16cs_pcmcia_release(link); + pcmcia_disable_device(link); /* This points to the parent struct local_info_t struct */ kfree(link->priv); + cur_dev = NULL; } static int das16cs_pcmcia_suspend(struct pcmcia_device *link) -- GitLab From c8b2ae2b98bad7870ec6be24e517bacffd76ea8e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:20:36 -0700 Subject: [PATCH 2894/6849] staging: comedi: cb_das16_cs: remove unused pcmcia 'stop' logic The pcmcia support code in this driver appears to be cut-and- paste from some other driver. It has code in it to stop the device during suspend but nothing in the main comedi_driver uses it. Remove the 'stop' variable from the pcmcia private data and all the logic that deals with it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 5171cfe29b08..151a55985454 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -625,7 +625,6 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, struct local_info_t { struct pcmcia_device *link; - int stop; struct bus_operations *bus; }; @@ -674,7 +673,6 @@ failed: static void das16cs_pcmcia_detach(struct pcmcia_device *link) { - ((struct local_info_t *)link->priv)->stop = 1; pcmcia_disable_device(link); /* This points to the parent struct local_info_t struct */ kfree(link->priv); @@ -683,19 +681,11 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link) static int das16cs_pcmcia_suspend(struct pcmcia_device *link) { - struct local_info_t *local = link->priv; - - /* Mark the device as stopped, to block IO until later */ - local->stop = 1; - return 0; } static int das16cs_pcmcia_resume(struct pcmcia_device *link) { - struct local_info_t *local = link->priv; - - local->stop = 0; return 0; } -- GitLab From 2b5f548082d8b6442a4a76ff92276c4606441ada Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:21:47 -0700 Subject: [PATCH 2895/6849] staging: comedi: cb_das16_cs: remove the pcmcia suspend/resume The pcmcia suspend/resume callbacks don't do anything. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 151a55985454..df9b075cdc8a 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -679,16 +679,6 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link) cur_dev = NULL; } -static int das16cs_pcmcia_suspend(struct pcmcia_device *link) -{ - return 0; -} - -static int das16cs_pcmcia_resume(struct pcmcia_device *link) -{ - return 0; -} - static const struct pcmcia_device_id das16cs_id_table[] = { PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), @@ -701,8 +691,6 @@ static struct pcmcia_driver das16cs_driver = { .owner = THIS_MODULE, .probe = das16cs_pcmcia_attach, .remove = das16cs_pcmcia_detach, - .suspend = das16cs_pcmcia_suspend, - .resume = das16cs_pcmcia_resume, .id_table = das16cs_id_table, }; -- GitLab From bc314fb53f1557716bdb2bdae8bf6b898b0f8ab9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:22:52 -0700 Subject: [PATCH 2896/6849] staging: comedi: cb_das16_cs: remove unneeded pcmcia private data The pcmcia device-specific data is not longer needed by this driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index df9b075cdc8a..8661e135a5d4 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -623,11 +623,6 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, return -EINVAL; } -struct local_info_t { - struct pcmcia_device *link; - struct bus_operations *bus; -}; - static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { @@ -639,16 +634,8 @@ static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, static int das16cs_pcmcia_attach(struct pcmcia_device *link) { - struct local_info_t *local; int ret; - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); - if (!local) - return -ENOMEM; - local->link = link; - link->priv = local; - /* Do we need to allocate an interrupt? */ link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; @@ -674,8 +661,6 @@ failed: static void das16cs_pcmcia_detach(struct pcmcia_device *link) { pcmcia_disable_device(link); - /* This points to the parent struct local_info_t struct */ - kfree(link->priv); cur_dev = NULL; } -- GitLab From 2f01826783c95d7056304408c0046198d25e71b6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:23:38 -0700 Subject: [PATCH 2897/6849] staging: comedi: cb_das16_cs: Move the comedi_driver variable Move the comedi_driver variable to remove the need for the forward declarations. Add some whitespace to the declaration for aesthetic reasons. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 8661e135a5d4..92c774da25e8 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -96,16 +96,6 @@ struct das16cs_private { }; #define devpriv ((struct das16cs_private *)dev->private) -static int das16cs_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static void das16cs_detach(struct comedi_device *dev); -static struct comedi_driver driver_das16cs = { - .driver_name = "cb_das16_cs", - .module = THIS_MODULE, - .attach = das16cs_attach, - .detach = das16cs_detach, -}; - static struct pcmcia_device *cur_dev; static const struct comedi_lrange das16cs_ai_range = { 4, { @@ -623,6 +613,13 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, return -EINVAL; } +static struct comedi_driver driver_das16cs = { + .driver_name = "cb_das16_cs", + .module = THIS_MODULE, + .attach = das16cs_attach, + .detach = das16cs_detach, +}; + static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { -- GitLab From ae7df43422cc0afdd5a808638dd7935ad752c62e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:36:20 -0700 Subject: [PATCH 2898/6849] staging: comedi: cb_das16_cs: refactor the comedi attach/detach Move the comedi_driver attach/detach functions, as well as the probe function used during the attach. This removes the need for all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 275 ++++++++----------- 1 file changed, 122 insertions(+), 153 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 92c774da25e8..e0821b9b6211 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -106,159 +106,6 @@ static const struct comedi_lrange das16cs_ai_range = { 4, { } }; -static irqreturn_t das16cs_interrupt(int irq, void *d); -static int das16cs_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16cs_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); -static int das16cs_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int das16cs_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16cs_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16cs_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16cs_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int das16cs_timer_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int das16cs_timer_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, - struct pcmcia_device *link) -{ - int i; - - for (i = 0; i < n_boards; i++) { - if (das16cs_boards[i].device_id == link->card_id) - return das16cs_boards + i; - } - - dev_dbg(dev->class_dev, "unknown board!\n"); - - return NULL; -} - -static int das16cs_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pcmcia_device *link; - struct comedi_subdevice *s; - int ret; - int i; - - dev_dbg(dev->class_dev, "cb_das16_cs: attach\n"); - - link = cur_dev; /* XXX hack */ - if (!link) - return -EIO; - - dev->iobase = link->resource[0]->start; - dev_dbg(dev->class_dev, "I/O base=0x%04lx\n", dev->iobase); - - dev_dbg(dev->class_dev, "fingerprint:\n"); - for (i = 0; i < 48; i += 2) - dev_dbg(dev->class_dev, "%04x\n", inw(dev->iobase + i)); - - - ret = request_irq(link->irq, das16cs_interrupt, - IRQF_SHARED, "cb_das16_cs", dev); - if (ret < 0) - return ret; - - dev->irq = link->irq; - - dev_dbg(dev->class_dev, "irq=%u\n", dev->irq); - - dev->board_ptr = das16cs_probe(dev, link); - if (!dev->board_ptr) - return -EIO; - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) - return -ENOMEM; - - ret = comedi_alloc_subdevices(dev, 4); - if (ret) - return ret; - - s = dev->subdevices + 0; - dev->read_subdev = s; - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; - s->n_chan = 16; - s->maxdata = 0xffff; - s->range_table = &das16cs_ai_range; - s->len_chanlist = 16; - s->insn_read = das16cs_ai_rinsn; - s->do_cmd = das16cs_ai_cmd; - s->do_cmdtest = das16cs_ai_cmdtest; - - s = dev->subdevices + 1; - /* analog output subdevice */ - if (thisboard->n_ao_chans) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->n_ao_chans; - s->maxdata = 0xffff; - s->range_table = &range_bipolar10; - s->insn_write = &das16cs_ao_winsn; - s->insn_read = &das16cs_ao_rinsn; - } - - s = dev->subdevices + 2; - /* digital i/o subdevice */ - if (1) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = das16cs_dio_insn_bits; - s->insn_config = das16cs_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - s = dev->subdevices + 3; - /* timer subdevice */ - if (0) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 1; - s->maxdata = 0xff; - s->range_table = &range_unknown; - s->insn_read = das16cs_timer_insn_read; - s->insn_config = das16cs_timer_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - - return 1; -} - -static void das16cs_detach(struct comedi_device *dev) -{ - if (dev->irq) - free_irq(dev->irq, dev); -} - static irqreturn_t das16cs_interrupt(int irq, void *d) { /* struct comedi_device *dev = d; */ @@ -613,6 +460,128 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, return -EINVAL; } +static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, + struct pcmcia_device *link) +{ + int i; + + for (i = 0; i < n_boards; i++) { + if (das16cs_boards[i].device_id == link->card_id) + return das16cs_boards + i; + } + + dev_dbg(dev->class_dev, "unknown board!\n"); + + return NULL; +} + +static int das16cs_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pcmcia_device *link; + struct comedi_subdevice *s; + int ret; + int i; + + dev_dbg(dev->class_dev, "cb_das16_cs: attach\n"); + + link = cur_dev; /* XXX hack */ + if (!link) + return -EIO; + + dev->iobase = link->resource[0]->start; + dev_dbg(dev->class_dev, "I/O base=0x%04lx\n", dev->iobase); + + dev_dbg(dev->class_dev, "fingerprint:\n"); + for (i = 0; i < 48; i += 2) + dev_dbg(dev->class_dev, "%04x\n", inw(dev->iobase + i)); + + + ret = request_irq(link->irq, das16cs_interrupt, + IRQF_SHARED, "cb_das16_cs", dev); + if (ret < 0) + return ret; + + dev->irq = link->irq; + + dev_dbg(dev->class_dev, "irq=%u\n", dev->irq); + + dev->board_ptr = das16cs_probe(dev, link); + if (!dev->board_ptr) + return -EIO; + + dev->board_name = thisboard->name; + + if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) + return -ENOMEM; + + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; + + s = dev->subdevices + 0; + dev->read_subdev = s; + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->n_chan = 16; + s->maxdata = 0xffff; + s->range_table = &das16cs_ai_range; + s->len_chanlist = 16; + s->insn_read = das16cs_ai_rinsn; + s->do_cmd = das16cs_ai_cmd; + s->do_cmdtest = das16cs_ai_cmdtest; + + s = dev->subdevices + 1; + /* analog output subdevice */ + if (thisboard->n_ao_chans) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = thisboard->n_ao_chans; + s->maxdata = 0xffff; + s->range_table = &range_bipolar10; + s->insn_write = &das16cs_ao_winsn; + s->insn_read = &das16cs_ao_rinsn; + } + + s = dev->subdevices + 2; + /* digital i/o subdevice */ + if (1) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = das16cs_dio_insn_bits; + s->insn_config = das16cs_dio_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + s = dev->subdevices + 3; + /* timer subdevice */ + if (0) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 1; + s->maxdata = 0xff; + s->range_table = &range_unknown; + s->insn_read = das16cs_timer_insn_read; + s->insn_config = das16cs_timer_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + + return 1; +} + +static void das16cs_detach(struct comedi_device *dev) +{ + if (dev->irq) + free_irq(dev->irq, dev); +} + static struct comedi_driver driver_das16cs = { .driver_name = "cb_das16_cs", .module = THIS_MODULE, -- GitLab From 16a8cdfc13526983f6c55e35c09bbe091ac11e96 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:37:10 -0700 Subject: [PATCH 2899/6849] staging: comedi: cb_das16_cs: remove thisboard and devpriv macros The 'thisboard' and 'devpriv' macros rely on a local variable having a specific name and yield pointers derived from that local variable. Replace the macro with local variables where used. Use the comedi_board() helper to get the 'thisboard' pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index e0821b9b6211..496c3312837e 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -85,7 +85,6 @@ static const struct das16cs_board das16cs_boards[] = { }; #define n_boards ARRAY_SIZE(das16cs_boards) -#define thisboard ((const struct das16cs_board *)dev->board_ptr) struct das16cs_private { struct pcmcia_device *link; @@ -94,7 +93,6 @@ struct das16cs_private { unsigned short status1; unsigned short status2; }; -#define devpriv ((struct das16cs_private *)dev->private) static struct pcmcia_device *cur_dev; @@ -120,6 +118,7 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16cs_private *devpriv = dev->private; int i; int to; int aref; @@ -328,6 +327,7 @@ static int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16cs_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned short status1; @@ -375,6 +375,7 @@ static int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16cs_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -411,6 +412,7 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16cs_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int bits; @@ -478,6 +480,7 @@ static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct das16cs_board *thisboard; struct pcmcia_device *link; struct comedi_subdevice *s; int ret; @@ -509,6 +512,7 @@ static int das16cs_attach(struct comedi_device *dev, dev->board_ptr = das16cs_probe(dev, link); if (!dev->board_ptr) return -EIO; + thisboard = comedi_board(dev); dev->board_name = thisboard->name; -- GitLab From 1efc5d53b7c1355a3491061587153c8f89613aaa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:57:36 -0700 Subject: [PATCH 2900/6849] staging: comedi: cb_das16_cs: remove n_boards define The 'n_boards' define is only used one place in the driver. Just put the ARRAY_SIZE() where used and remove the define. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 496c3312837e..e1e3ff0cb5fd 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -84,8 +84,6 @@ static const struct das16cs_board das16cs_boards[] = { }, }; -#define n_boards ARRAY_SIZE(das16cs_boards) - struct das16cs_private { struct pcmcia_device *link; @@ -467,7 +465,7 @@ static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, { int i; - for (i = 0; i < n_boards; i++) { + for (i = 0; i < ARRAY_SIZE(das16cs_boards); i++) { if (das16cs_boards[i].device_id == link->card_id) return das16cs_boards + i; } -- GitLab From adb2d69b0c6b803d197c4f3fad80ffebaba2ec4d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:58:34 -0700 Subject: [PATCH 2901/6849] staging: comedi: cb_das16_cs: remove skel driver cut-and-paste comments There are a number of comments in this driver that are cut-and-paste from the skel driver. They are not needed in "real" drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index e1e3ff0cb5fd..36fd3e678424 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -108,10 +108,6 @@ static irqreturn_t das16cs_interrupt(int irq, void *d) return IRQ_HANDLED; } -/* - * "instructions" read/write data in "one-shot" or "software-triggered" - * mode. - */ static int das16cs_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -168,13 +164,6 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* cmdtest tests a particular command to see if it is valid. - * Using the cmdtest ioctl, a user can create a valid cmd - * and then have it executes by the cmd ioctl. - * - * cmdtest returns 1,2,3,4 or 0, depending on which tests - * the command passes. */ - /* step 1: make sure trigger sources are trivially valid */ tmp = cmd->start_src; @@ -367,8 +356,6 @@ static int das16cs_ao_winsn(struct comedi_device *dev, return i; } -/* AO subdevices should have a read insn as well as a write insn. - * Usually this means copying a value stored in devpriv. */ static int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -383,11 +370,6 @@ static int das16cs_ao_rinsn(struct comedi_device *dev, return i; } -/* DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The - * comedi core can convert between insn_bits and insn_read/write */ static int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -399,8 +381,6 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, outw(s->state, dev->iobase + 16); } - /* on return, data[1] contains the value of the digital - * input and output lines. */ data[1] = inw(dev->iobase + 16); return insn->n; -- GitLab From 5c416ef3f67e9f524ac3ab07c071323f66616373 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 16:59:26 -0700 Subject: [PATCH 2902/6849] staging: comedi: cb_das16_cs: remove unused timer subdevice The timer subdevice is never initialized due to the 'if (0)'. The comedi callbacks also don't do anything and just return -EINVAL. Remove the subdevice and associated code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 32 +------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 36fd3e678424..b0a2223569a3 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -425,21 +425,6 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, return insn->n; } -static int das16cs_timer_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - return -EINVAL; -} - -static int das16cs_timer_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - return -EINVAL; -} - static const struct das16cs_board *das16cs_probe(struct comedi_device *dev, struct pcmcia_device *link) { @@ -497,7 +482,7 @@ static int das16cs_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) return -ENOMEM; - ret = comedi_alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -540,21 +525,6 @@ static int das16cs_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - s = dev->subdevices + 3; - /* timer subdevice */ - if (0) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 1; - s->maxdata = 0xff; - s->range_table = &range_unknown; - s->insn_read = das16cs_timer_insn_read; - s->insn_config = das16cs_timer_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - return 1; } -- GitLab From f87a7e5bf50d83d9dca0e87d10eac7226e0ac61d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:00:19 -0700 Subject: [PATCH 2903/6849] staging: comedi: cb_das16_cs: cleanup dio subdevice initialization The digital i/o subdevice is always initialized due to the 'if (1)'. Simplify the attach by removing the test. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index b0a2223569a3..f3d5ca00f147 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -513,17 +513,13 @@ static int das16cs_attach(struct comedi_device *dev, s = dev->subdevices + 2; /* digital i/o subdevice */ - if (1) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = das16cs_dio_insn_bits; - s->insn_config = das16cs_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = das16cs_dio_insn_bits; + s->insn_config = das16cs_dio_insn_config; return 1; } -- GitLab From da7fde2bc902db1133f591b826124c9369857d38 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:10:30 -0700 Subject: [PATCH 2904/6849] staging: comedi: cb_das16_cs: fix analog output subdevice init The analog output subdevice is only available on the -AO version of the DAS16/16 device and the number of channels is provided in the boardinfo. Make sure the subdevice is marked as unused for devices that do not support the analog out. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index f3d5ca00f147..acee55023564 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -509,6 +509,8 @@ static int das16cs_attach(struct comedi_device *dev, s->range_table = &range_bipolar10; s->insn_write = &das16cs_ao_winsn; s->insn_read = &das16cs_ao_rinsn; + } else { + s->type = COMEDI_SUBD_UNUSED; } s = dev->subdevices + 2; -- GitLab From 8c50aa15329c6fc93e9de2780e3d8b5e4cb0dc16 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:11:13 -0700 Subject: [PATCH 2905/6849] staging: comedi: cb_das16_cs: remove unneeded include This driver is not for a pci device. Remove the unneeded include of the pci.h header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index acee55023564..2d8ec680a956 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -42,7 +42,6 @@ Status: experimental #include #include "../comedidev.h" #include -#include #include #include -- GitLab From 9a4d21154796136b87f841746fbdceec37bf48ee Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:11:56 -0700 Subject: [PATCH 2906/6849] staging: comedi: cb_das16_cs: probe for the device first During the attach of the comedi_driver, the device type probe can fail. We should do the probe before requesting the irq for the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 2d8ec680a956..20d77cfe9281 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -454,6 +454,13 @@ static int das16cs_attach(struct comedi_device *dev, if (!link) return -EIO; + dev->board_ptr = das16cs_probe(dev, link); + if (!dev->board_ptr) + return -EIO; + thisboard = comedi_board(dev); + + dev->board_name = thisboard->name; + dev->iobase = link->resource[0]->start; dev_dbg(dev->class_dev, "I/O base=0x%04lx\n", dev->iobase); @@ -461,23 +468,14 @@ static int das16cs_attach(struct comedi_device *dev, for (i = 0; i < 48; i += 2) dev_dbg(dev->class_dev, "%04x\n", inw(dev->iobase + i)); - ret = request_irq(link->irq, das16cs_interrupt, IRQF_SHARED, "cb_das16_cs", dev); if (ret < 0) return ret; - dev->irq = link->irq; dev_dbg(dev->class_dev, "irq=%u\n", dev->irq); - dev->board_ptr = das16cs_probe(dev, link); - if (!dev->board_ptr) - return -EIO; - thisboard = comedi_board(dev); - - dev->board_name = thisboard->name; - if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) return -ENOMEM; -- GitLab From 8b3bfe9b4491947cdaabd1f01065b49aab49881d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:12:41 -0700 Subject: [PATCH 2907/6849] staging: comedi: cb_das16_cs: remove the debug output of the "fingerprint" During the attach, all of the device i/o registers are read and the data is output as a dev_dbg() "fingerprint". This just adds a bunch of noise during the loading of the driver. Remove the output. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 20d77cfe9281..269022882acc 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -446,7 +446,6 @@ static int das16cs_attach(struct comedi_device *dev, struct pcmcia_device *link; struct comedi_subdevice *s; int ret; - int i; dev_dbg(dev->class_dev, "cb_das16_cs: attach\n"); @@ -464,10 +463,6 @@ static int das16cs_attach(struct comedi_device *dev, dev->iobase = link->resource[0]->start; dev_dbg(dev->class_dev, "I/O base=0x%04lx\n", dev->iobase); - dev_dbg(dev->class_dev, "fingerprint:\n"); - for (i = 0; i < 48; i += 2) - dev_dbg(dev->class_dev, "%04x\n", inw(dev->iobase + i)); - ret = request_irq(link->irq, das16cs_interrupt, IRQF_SHARED, "cb_das16_cs", dev); if (ret < 0) -- GitLab From 13ab179c69769bb5be811b28fd6eeaeea2440359 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:13:23 -0700 Subject: [PATCH 2908/6849] staging: comedi: cb_das16_cs: cleanup the boardinfo For aesthetic reasons, reorder the boardinfo to match the MODULE_DEVICE_TABLE. Also reorder the data to match the struct definition and add some whitespace to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 27 ++++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 269022882acc..f90c12b449c9 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -65,22 +65,21 @@ struct das16cs_board { int device_id; int n_ao_chans; }; + static const struct das16cs_board das16cs_boards[] = { { - .device_id = 0x0000, /* unknown */ - .name = "PC-CARD DAS16/16", - .n_ao_chans = 0, - }, - { - .device_id = 0x0039, - .name = "PC-CARD DAS16/16-AO", - .n_ao_chans = 2, - }, - { - .device_id = 0x4009, - .name = "PCM-DAS16s/16", - .n_ao_chans = 0, - }, + .name = "PC-CARD DAS16/16-AO", + .device_id = 0x0039, + .n_ao_chans = 2, + }, { + .name = "PCM-DAS16s/16", + .device_id = 0x4009, + .n_ao_chans = 0, + }, { + .name = "PC-CARD DAS16/16", + .device_id = 0x0000, /* unknown */ + .n_ao_chans = 0, + }, }; struct das16cs_private { -- GitLab From 1fce3034f63c22392d1d8bc22b5e80b575b00df6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:15:21 -0700 Subject: [PATCH 2909/6849] staging: comedi: cb_das16_cs: consolidate the attach messages Consolidate all the attach messages into one dev_info() output at the end of the successful attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index f90c12b449c9..155f742164fd 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -446,8 +446,6 @@ static int das16cs_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - dev_dbg(dev->class_dev, "cb_das16_cs: attach\n"); - link = cur_dev; /* XXX hack */ if (!link) return -EIO; @@ -460,7 +458,6 @@ static int das16cs_attach(struct comedi_device *dev, dev->board_name = thisboard->name; dev->iobase = link->resource[0]->start; - dev_dbg(dev->class_dev, "I/O base=0x%04lx\n", dev->iobase); ret = request_irq(link->irq, das16cs_interrupt, IRQF_SHARED, "cb_das16_cs", dev); @@ -468,8 +465,6 @@ static int das16cs_attach(struct comedi_device *dev, return ret; dev->irq = link->irq; - dev_dbg(dev->class_dev, "irq=%u\n", dev->irq); - if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) return -ENOMEM; @@ -514,6 +509,10 @@ static int das16cs_attach(struct comedi_device *dev, s->insn_bits = das16cs_dio_insn_bits; s->insn_config = das16cs_dio_insn_config; + dev_info(dev->class_dev, "%s: %s, I/O base=0x%04lx, irq=%u\n", + dev->driver->driver_name, dev->board_name, + dev->iobase, dev->irq); + return 1; } -- GitLab From a659643a6b504189e899e56901c760f89eb4bb13 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:16:04 -0700 Subject: [PATCH 2910/6849] staging: comedi: cb_das16_cs: return '0' for successful attach The comedi core expects a < 0 value during the attach to indicate an error. The normal 'success' return to the kernel is '0' so use that here. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 155f742164fd..c92e23279f9f 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -513,7 +513,7 @@ static int das16cs_attach(struct comedi_device *dev, dev->driver->driver_name, dev->board_name, dev->iobase, dev->irq); - return 1; + return 0; } static void das16cs_detach(struct comedi_device *dev) -- GitLab From cf2592d06a4e37f98eba17d1abe32af7fe521d19 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:16:53 -0700 Subject: [PATCH 2911/6849] staging: comedi: cb_das16_cs: add whitespace to the subdev init Add some whitespace to the subdev initialization to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 48 ++++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index c92e23279f9f..11dc9b1bf22f 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -475,39 +475,39 @@ static int das16cs_attach(struct comedi_device *dev, s = dev->subdevices + 0; dev->read_subdev = s; /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; - s->n_chan = 16; - s->maxdata = 0xffff; - s->range_table = &das16cs_ai_range; - s->len_chanlist = 16; - s->insn_read = das16cs_ai_rinsn; - s->do_cmd = das16cs_ai_cmd; - s->do_cmdtest = das16cs_ai_cmdtest; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->n_chan = 16; + s->maxdata = 0xffff; + s->range_table = &das16cs_ai_range; + s->len_chanlist = 16; + s->insn_read = das16cs_ai_rinsn; + s->do_cmd = das16cs_ai_cmd; + s->do_cmdtest = das16cs_ai_cmdtest; s = dev->subdevices + 1; /* analog output subdevice */ if (thisboard->n_ao_chans) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->n_ao_chans; - s->maxdata = 0xffff; - s->range_table = &range_bipolar10; - s->insn_write = &das16cs_ao_winsn; - s->insn_read = &das16cs_ao_rinsn; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = thisboard->n_ao_chans; + s->maxdata = 0xffff; + s->range_table = &range_bipolar10; + s->insn_write = &das16cs_ao_winsn; + s->insn_read = &das16cs_ao_rinsn; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } s = dev->subdevices + 2; /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = das16cs_dio_insn_bits; - s->insn_config = das16cs_dio_insn_config; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = das16cs_dio_insn_bits; + s->insn_config = das16cs_dio_insn_config; dev_info(dev->class_dev, "%s: %s, I/O base=0x%04lx, irq=%u\n", dev->driver->driver_name, dev->board_name, -- GitLab From e05b98b6425d46e7a0f77d16499407f6df35427f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:17:52 -0700 Subject: [PATCH 2912/6849] staging: comedi: cb_das16_cs: cleanup das16cs_ai_rinsn() Cleanup to analog input read function. 1) Initialize the chan, range, and aref locale variables when they are declared. 2) Remove need for the static local variable. 3) Remove the unnecessary cast of inw()'s return value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 30 +++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 11dc9b1bf22f..80e354028d2e 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -111,16 +111,11 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct das16cs_private *devpriv = dev->private; + int chan = CR_CHAN(insn->chanspec); + int range = CR_RANGE(insn->chanspec); + int aref = CR_AREF(insn->chanspec); int i; int to; - int aref; - int range; - int chan; - static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 }; - - chan = CR_CHAN(insn->chanspec); - aref = CR_AREF(insn->chanspec); - range = CR_RANGE(insn->chanspec); outw(chan, dev->iobase + 2); @@ -129,7 +124,22 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, outw(devpriv->status1, dev->iobase + 4); devpriv->status2 &= ~0xff00; - devpriv->status2 |= range_bits[range]; + switch (range) { + case 0: + devpriv->status2 |= 0x800; + break; + case 1: + devpriv->status2 |= 0x000; + break; + case 2: + devpriv->status2 |= 0x100; + break; + case 3: + devpriv->status2 |= 0x200; + break; + default: + return -EINVAL; + } outw(devpriv->status2, dev->iobase + 6); for (i = 0; i < insn->n; i++) { @@ -144,7 +154,7 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, dev_dbg(dev->class_dev, "cb_das16_cs: ai timeout\n"); return -ETIME; } - data[i] = (unsigned short)inw(dev->iobase + 0); + data[i] = inw(dev->iobase + 0); } return i; -- GitLab From ae1a400029aa9624386b198904aedc46de855ba6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:18:43 -0700 Subject: [PATCH 2913/6849] staging: comedi: cb_das16_cs: use #define'd io reg offsets Instead of open coding the 'dev->iobase + n' for each io register in the device, use the provided #define's for the offsets. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 80e354028d2e..f717840e31c4 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -117,11 +117,11 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, int i; int to; - outw(chan, dev->iobase + 2); + outw(chan, dev->iobase + DAS16CS_DIO_MUX); devpriv->status1 &= ~0xf320; devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020; - outw(devpriv->status1, dev->iobase + 4); + outw(devpriv->status1, dev->iobase + DAS16CS_MISC1); devpriv->status2 &= ~0xff00; switch (range) { @@ -140,21 +140,21 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, default: return -EINVAL; } - outw(devpriv->status2, dev->iobase + 6); + outw(devpriv->status2, dev->iobase + DAS16CS_MISC2); for (i = 0; i < insn->n; i++) { - outw(0, dev->iobase); + outw(0, dev->iobase + DAS16CS_ADC_DATA); #define TIMEOUT 1000 for (to = 0; to < TIMEOUT; to++) { - if (inw(dev->iobase + 4) & 0x0080) + if (inw(dev->iobase + DAS16CS_MISC1) & 0x0080) break; } if (to == TIMEOUT) { dev_dbg(dev->class_dev, "cb_das16_cs: ai timeout\n"); return -ETIME; } - data[i] = inw(dev->iobase + 0); + data[i] = inw(dev->iobase + DAS16CS_ADC_DATA); } return i; @@ -333,7 +333,7 @@ static int das16cs_ao_winsn(struct comedi_device *dev, devpriv->ao_readback[chan] = data[i]; d = data[i]; - outw(devpriv->status1, dev->iobase + 4); + outw(devpriv->status1, dev->iobase + DAS16CS_MISC1); udelay(1); status1 = devpriv->status1 & ~0xf; @@ -343,22 +343,22 @@ static int das16cs_ao_winsn(struct comedi_device *dev, status1 |= 0x0008; /* printk("0x%04x\n",status1);*/ - outw(status1, dev->iobase + 4); + outw(status1, dev->iobase + DAS16CS_MISC1); udelay(1); for (bit = 15; bit >= 0; bit--) { int b = (d >> bit) & 0x1; b <<= 1; /* printk("0x%04x\n",status1 | b | 0x0000);*/ - outw(status1 | b | 0x0000, dev->iobase + 4); + outw(status1 | b | 0x0000, dev->iobase + DAS16CS_MISC1); udelay(1); /* printk("0x%04x\n",status1 | b | 0x0004);*/ - outw(status1 | b | 0x0004, dev->iobase + 4); + outw(status1 | b | 0x0004, dev->iobase + DAS16CS_MISC1); udelay(1); } /* make high both DAC0CS and DAC1CS to load new data and update analog output*/ - outw(status1 | 0x9, dev->iobase + 4); + outw(status1 | 0x9, dev->iobase + DAS16CS_MISC1); } return i; @@ -386,10 +386,10 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, s->state &= ~data[0]; s->state |= data[0] & data[1]; - outw(s->state, dev->iobase + 16); + outw(s->state, dev->iobase + DAS16CS_DIO); } - data[1] = inw(dev->iobase + 16); + data[1] = inw(dev->iobase + DAS16CS_DIO); return insn->n; } @@ -428,7 +428,7 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0; devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0; - outw(devpriv->status2, dev->iobase + 6); + outw(devpriv->status2, dev->iobase + DAS16CS_MISC2); return insn->n; } -- GitLab From 857670c3e49cf915547652591fce77f3873614e7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:21:17 -0700 Subject: [PATCH 2914/6849] staging: comedi: cb_das16_cs: remove unused variable in private data The 'link' variable in the private data struct is not used by the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index f717840e31c4..68e6436dc7a0 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -83,8 +83,6 @@ static const struct das16cs_board das16cs_boards[] = { }; struct das16cs_private { - struct pcmcia_device *link; - unsigned int ao_readback[2]; unsigned short status1; unsigned short status2; -- GitLab From 443bbedbbef9df3884a93d1200fd087a966aa9c6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:22:18 -0700 Subject: [PATCH 2915/6849] staging: comedi: cb_das16_cs: use the BIP_RANGE helper macro The BIP_RANGE(a) macro can be used instead of the RANGE(a,b) macro when -a == b. And it's a bit clearer that this is a bipolar range. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 68e6436dc7a0..0d303d1fc5c5 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -90,12 +90,13 @@ struct das16cs_private { static struct pcmcia_device *cur_dev; -static const struct comedi_lrange das16cs_ai_range = { 4, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25), - } +static const struct comedi_lrange das16cs_ai_range = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + } }; static irqreturn_t das16cs_interrupt(int irq, void *d) -- GitLab From aebdf3b714d5c1ebc6103a026e2aeed9131ea675 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:23:06 -0700 Subject: [PATCH 2916/6849] staging: comedi: cb_das16_cs: remove some commented out debug The das16cs_ao_winsn() function has a couple commented out debug messages. Just remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 0d303d1fc5c5..791bf1141f59 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -341,17 +341,14 @@ static int das16cs_ao_winsn(struct comedi_device *dev, else status1 |= 0x0008; -/* printk("0x%04x\n",status1);*/ outw(status1, dev->iobase + DAS16CS_MISC1); udelay(1); for (bit = 15; bit >= 0; bit--) { int b = (d >> bit) & 0x1; b <<= 1; -/* printk("0x%04x\n",status1 | b | 0x0000);*/ outw(status1 | b | 0x0000, dev->iobase + DAS16CS_MISC1); udelay(1); -/* printk("0x%04x\n",status1 | b | 0x0004);*/ outw(status1 | b | 0x0004, dev->iobase + DAS16CS_MISC1); udelay(1); } -- GitLab From 0a77678cae47fbfdd30aa1479175e5cc47457dca Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 25 Jun 2012 17:23:44 -0700 Subject: [PATCH 2917/6849] staging: comedi: cb_das16_cs: fix a multi-line comment Fix a multi-line comment to follow the kernel CodingStyle. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 791bf1141f59..f82db2983317 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -352,8 +352,10 @@ static int das16cs_ao_winsn(struct comedi_device *dev, outw(status1 | b | 0x0004, dev->iobase + DAS16CS_MISC1); udelay(1); } -/* make high both DAC0CS and DAC1CS to load - new data and update analog output*/ + /* + * Make both DAC0CS and DAC1CS high to load + * the new data and update analog the output + */ outw(status1 | 0x9, dev->iobase + DAS16CS_MISC1); } -- GitLab From cd1a76fb6fbd477689ca2d0fdf7db7171c35e5d8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 26 Jun 2012 10:07:23 -0700 Subject: [PATCH 2918/6849] staging: comedi: cb_das16_cs: reword the comment about PCMCIA support The original comment about the PCMCIA support code was wrong in that it said this driver was for the "pcm-das08". When it was moved the comment was reworded badly. Fix the comment so it makes sense. Signed-off-by: H Hartley Sweeten Reported-by: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index f82db2983317..95fa7e2fea9d 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -19,8 +19,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - PCMCIA support code for the is adapted from the dummy_cs.c driver - of the Linux PCMCIA Card Services package. + PCMCIA support code for this driver is adapted from the dummy_cs.c + driver of the Linux PCMCIA Card Services package. The initial developer of the original code is David A. Hinds . Portions created by David A. Hinds -- GitLab From e8abca1f30239f6c979f60df49305a602672cb94 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 26 Jun 2012 10:08:52 -0700 Subject: [PATCH 2919/6849] staging: comedi: cb_das16_cs: remove unneeded default case in analog in read The default (return -EINVAL) case is not needed when working out the correct value to set the analog input range. As pointed out by Ian Abbott, the comedi core checks the range in comedi_check_chanlist() before calling the insn_read() function. Signed-off-by: H Hartley Sweeten Reported-by: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 95fa7e2fea9d..58d45299bf85 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -136,8 +136,6 @@ static int das16cs_ai_rinsn(struct comedi_device *dev, case 3: devpriv->status2 |= 0x200; break; - default: - return -EINVAL; } outw(devpriv->status2, dev->iobase + DAS16CS_MISC2); -- GitLab From 2da049bd5f9b0dbd688519fdb6688a4895fe8395 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 27 Jun 2012 00:22:20 +0200 Subject: [PATCH 2920/6849] staging: gdm72xx: fix an skb memory leak The NLMSG_PUT() macro contains a hidden goto that jumps to the nlmsg_failure label. Since the sk_buff was allocated before the macro, jumping to the nlmsg_failure label leaks the memory allocated for it. Calling kfree() before returning would fix it, but is better to avoid using this error prone macro and use nlmsg_put() instead. Also, use nlmsg_data() instead of NLMSG_DATA() to check type. Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/netlink_k.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 9fa432d74364..064815bd3f86 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -126,8 +126,13 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) } seq++; - nlh = NLMSG_PUT(skb, 0, seq, type, len); - memcpy(NLMSG_DATA(nlh), msg, len); + nlh = nlmsg_put(skb, 0, seq, type, len, 0); + if (!nlh) { + kfree_skb(skb); + return -EMSGSIZE; + } + + memcpy(nlmsg_data(nlh), msg, len); NETLINK_CB(skb).pid = 0; NETLINK_CB(skb).dst_group = 0; @@ -144,6 +149,5 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) ret = 0; } -nlmsg_failure: return ret; } -- GitLab From 24aadc809f270857743e62d0882865fb3ba195d9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 25 Jun 2012 23:46:27 +0300 Subject: [PATCH 2921/6849] mei: don't query HCSR for host buffer depth 1. We record host (write) buffer depth during reset so we don't need to query HCSR register later on. The host buffer depth doesn't change after the reset 2. Use mei_hbuf_max_data function to compute payload size in bytes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 3 +++ drivers/misc/mei/interface.c | 7 +++---- drivers/misc/mei/interface.h | 6 ++++++ drivers/misc/mei/interrupt.c | 6 +++--- drivers/misc/mei/iorw.c | 8 ++------ drivers/misc/mei/main.c | 9 ++------- drivers/misc/mei/mei_dev.h | 6 +++++- 7 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index a7d0bb0880ec..d39b2774535b 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -162,6 +162,9 @@ int mei_hw_init(struct mei_device *dev) if ((dev->host_hw_state & H_IS) == H_IS) mei_reg_write(dev, H_CSR, dev->host_hw_state); + /* Doesn't change in runtime */ + dev->hbuf_depth = (dev->host_hw_state & H_CBD) >> 24; + dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 6c0569177646..784a60626fa1 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -103,15 +103,14 @@ int mei_host_buffer_is_empty(struct mei_device *dev) */ int mei_count_empty_write_slots(struct mei_device *dev) { - unsigned char buffer_depth, filled_slots, empty_slots; + unsigned char filled_slots, empty_slots; dev->host_hw_state = mei_hcsr_read(dev); - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; + empty_slots = dev->hbuf_depth - filled_slots; /* check for overflow */ - if (filled_slots > buffer_depth) + if (filled_slots > dev->hbuf_depth) return -EOVERFLOW; return empty_slots; diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index ddff5d16616f..8723d8880149 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -49,6 +49,12 @@ int mei_count_empty_write_slots(struct mei_device *dev); int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); +static inline size_t mei_hbuf_max_data(const struct mei_device *dev) +{ + return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); +} + + int mei_wd_send(struct mei_device *dev); int mei_wd_stop(struct mei_device *dev, bool preserve); int mei_wd_host_init(struct mei_device *dev); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 8e4dd74b96e5..4ad6a6bab5a3 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -951,7 +951,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, list_move_tail(&cb_pos->cb_list, &dev->write_waiting_list.mei_cb.cb_list); } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { + } else if (*slots == dev->hbuf_depth) { /* buffer is still empty */ mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; mei_hdr->host_addr = cl->host_client_id; @@ -1046,8 +1046,8 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, &dev->write_waiting_list.mei_cb.cb_list); } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ + } else if (*slots == dev->hbuf_depth) { + /* buffer is still empty */ mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; mei_hdr->host_addr = cl->host_client_id; mei_hdr->me_addr = cl->me_client_id; diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index f9cced69b65e..50f52e21f587 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -481,12 +481,8 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) if (ret && dev->mei_host_buffer_is_empty) { ret = 0; dev->mei_host_buffer_is_empty = false; - if (cb->request_buffer.size > - (((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32)) - -sizeof(struct mei_msg_hdr)) { - mei_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - sizeof(struct mei_msg_hdr); + if (cb->request_buffer.size > mei_hbuf_max_data(dev)) { + mei_hdr.length = mei_hbuf_max_data(dev); mei_hdr.msg_complete = 0; } else { mei_hdr.length = cb->request_buffer.size; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c70333228337..aaf2683ea154 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -714,13 +714,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets && dev->mei_host_buffer_is_empty) { rets = 0; dev->mei_host_buffer_is_empty = false; - if (length > ((((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - sizeof(struct mei_msg_hdr))) { - - mei_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - - sizeof(struct mei_msg_hdr); + if (length > mei_hbuf_max_data(dev)) { + mei_hdr.length = mei_hbuf_max_data(dev); mei_hdr.msg_complete = 0; } else { mei_hdr.length = length; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 4fe653392a49..d60250d663c6 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -167,7 +167,10 @@ struct mei_io_list { struct mei_cl_cb mei_cb; }; -/* MEI private device struct */ +/** + * struct mei_deive - MEI private device struct + * @hbuf_depth - depth of host(write) buffer + */ struct mei_device { struct pci_dev *pdev; /* pointer to pci device struct */ /* @@ -205,6 +208,7 @@ struct mei_device { */ u32 host_hw_state; u32 me_hw_state; + u8 hbuf_depth; /* * waiting queue for receive message from FW */ -- GitLab From 726917f052e62d8012f63a763884957610399afb Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 25 Jun 2012 23:46:28 +0300 Subject: [PATCH 2922/6849] mei: revamp host buffer interface function 1. Use unified _hbuf_ prefix for host/write buffer functions. 2. Cleanup the code w/o functional changes. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interface.c | 31 ++++++++++++------------------- drivers/misc/mei/interface.h | 14 ++++++++------ drivers/misc/mei/interrupt.c | 8 ++++---- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 784a60626fa1..88ada64c0b54 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -58,16 +58,18 @@ void mei_disable_interrupts(struct mei_device *dev) } /** - * _host_get_filled_slots - gets number of device filled buffer slots + * mei_hbuf_filled_slots - gets number of device filled buffer slots * * @device: the device structure * * returns number of filled slots */ -static unsigned char _host_get_filled_slots(const struct mei_device *dev) +static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) { char read_ptr, write_ptr; + dev->host_hw_state = mei_hcsr_read(dev); + read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); @@ -75,38 +77,29 @@ static unsigned char _host_get_filled_slots(const struct mei_device *dev) } /** - * mei_host_buffer_is_empty - checks if host buffer is empty. + * mei_hbuf_is_empty - checks if host buffer is empty. * * @dev: the device structure * - * returns 1 if empty, 0 - otherwise. + * returns true if empty, false - otherwise. */ -int mei_host_buffer_is_empty(struct mei_device *dev) +bool mei_hbuf_is_empty(struct mei_device *dev) { - unsigned char filled_slots; - - dev->host_hw_state = mei_hcsr_read(dev); - filled_slots = _host_get_filled_slots(dev); - - if (filled_slots == 0) - return 1; - - return 0; + return mei_hbuf_filled_slots(dev) == 0; } /** - * mei_count_empty_write_slots - counts write empty slots. + * mei_hbuf_empty_slots - counts write empty slots. * * @dev: the device structure * * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count */ -int mei_count_empty_write_slots(struct mei_device *dev) +int mei_hbuf_empty_slots(struct mei_device *dev) { unsigned char filled_slots, empty_slots; - dev->host_hw_state = mei_hcsr_read(dev); - filled_slots = _host_get_filled_slots(dev); + filled_slots = mei_hbuf_filled_slots(dev); empty_slots = dev->hbuf_depth - filled_slots; /* check for overflow */ @@ -139,7 +132,7 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, "mei_write_message header=%08x.\n", *((u32 *) header)); - empty_slots = mei_count_empty_write_slots(dev); + empty_slots = mei_hbuf_empty_slots(dev); dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); dw_cnt = (length + sizeof(*header) + 3) / 4; diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index 8723d8880149..cd9b778e8dc5 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -41,19 +41,21 @@ int mei_write_message(struct mei_device *dev, unsigned char *write_buffer, unsigned long write_length); -int mei_host_buffer_is_empty(struct mei_device *dev); +bool mei_hbuf_is_empty(struct mei_device *dev); -int mei_count_full_read_slots(struct mei_device *dev); - -int mei_count_empty_write_slots(struct mei_device *dev); - -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); +int mei_hbuf_empty_slots(struct mei_device *dev); static inline size_t mei_hbuf_max_data(const struct mei_device *dev) { return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); } +int mei_count_full_read_slots(struct mei_device *dev); + + +int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); + + int mei_wd_send(struct mei_device *dev); int mei_wd_stop(struct mei_device *dev, bool preserve); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 4ad6a6bab5a3..1872a2a760e5 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -280,7 +280,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) dev->iamthif_msg_buf_index = 0; dev->iamthif_msg_buf_size = 0; dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); + dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); return 0; } @@ -1199,11 +1199,11 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, struct mei_io_list *list; int ret; - if (!mei_host_buffer_is_empty(dev)) { + if (!mei_hbuf_is_empty(dev)) { dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); return 0; } - *slots = mei_count_empty_write_slots(dev); + *slots = mei_hbuf_empty_slots(dev); if (*slots <= 0) return -EMSGSIZE; @@ -1558,7 +1558,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) end: dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); dev->host_hw_state = mei_hcsr_read(dev); - dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); + dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); bus_message_received = false; if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { -- GitLab From df6b3cfe20f3e22a7997255f1df753005deb914f Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Mon, 25 Jun 2012 16:33:36 +0900 Subject: [PATCH 2923/6849] MAINTAINERS: Add entries for extcon (external connector) subsystem. Signed-off-by: MyungJoo Ham Signed-off-by: Chanwoo Choi Signed-off-by: Kyungmin Park Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 14bc7071f9df..36f2e2db60cd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2706,6 +2706,14 @@ M: Mimi Zohar S: Supported F: security/integrity/evm/ +EXTERNAL CONNECTOR SUBSYSTEM (EXTCON) +M: MyungJoo Ham +M: Chanwoo Choi +L: linux-kernel@vger.kernel.org +S: Maintained +F: drivers/extcon/ +F: Documentation/extcon/ + EXYNOS DP DRIVER M: Jingoo Han L: linux-fbdev@vger.kernel.org -- GitLab From f2c32a882d2c1cde6fc552a5a3d34b4c1330edb8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 24 Jun 2012 12:09:45 +0100 Subject: [PATCH 2924/6849] Extcon: Arizona: Add driver for Wolfson Arizona class devices Most Wolfson Arizona class audio hub CODECs include a flexible ultra low power accessory detection subsystem. This driver exposes initial support for this subsystem via the Extcon framework, implementing support for ultra low power detection of headphone and headset with the ability to detect the polarity of a headset. The functionality of the devices is much richer and more flexible than the current driver, future patches will extend the features of the driver to more fully exploit this. Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/Kconfig | 8 + drivers/extcon/Makefile | 1 + drivers/extcon/extcon-arizona.c | 491 ++++++++++++++++++++++++++++++++ 3 files changed, 500 insertions(+) create mode 100644 drivers/extcon/extcon-arizona.c diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 29c5cf852efc..bb385ac629a8 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -29,4 +29,12 @@ config EXTCON_MAX8997 Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory detector and switch. +config EXTCON_ARIZONA + tristate "Wolfson Arizona EXTCON support" + depends on MFD_ARIZONA + help + Say Y here to enable support for external accessory detection + with Wolfson Arizona devices. These are audio CODECs with + advanced audio accessory detection support. + endif # MULTISTATE_SWITCH diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 86020bdb6da0..e932caaa311c 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_EXTCON) += extcon_class.o obj-$(CONFIG_EXTCON_GPIO) += extcon_gpio.o obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o +obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c new file mode 100644 index 000000000000..b068bc9defe1 --- /dev/null +++ b/drivers/extcon/extcon-arizona.c @@ -0,0 +1,491 @@ +/* + * extcon-arizona.c - Extcon driver Wolfson Arizona devices + * + * Copyright (C) 2012 Wolfson Microelectronics plc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct arizona_extcon_info { + struct device *dev; + struct arizona *arizona; + struct mutex lock; + struct regulator *micvdd; + + int micd_mode; + const struct arizona_micd_config *micd_modes; + int micd_num_modes; + + bool micd_reva; + + bool mic; + bool detecting; + int jack_flips; + + struct extcon_dev edev; +}; + +static const struct arizona_micd_config micd_default_modes[] = { + { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, + { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, +}; + +#define ARIZONA_CABLE_MECHANICAL "Mechanical" +#define ARIZONA_CABLE_HEADPHONE "Headphone" +#define ARIZONA_CABLE_HEADSET "Headset" + +static const char *arizona_cable[] = { + ARIZONA_CABLE_MECHANICAL, + ARIZONA_CABLE_HEADSET, + ARIZONA_CABLE_HEADPHONE, + NULL, +}; + +static const u32 arizona_exclusions[] = { + 0x6, /* Headphone and headset */ + 0, +}; + +static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) +{ + struct arizona *arizona = info->arizona; + + gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio, + info->micd_modes[mode].gpio); + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_BIAS_SRC_MASK, + info->micd_modes[mode].bias); + regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, + ARIZONA_ACCDET_SRC, info->micd_modes[mode].src); + + info->micd_mode = mode; + + dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode); +} + +static void arizona_start_mic(struct arizona_extcon_info *info) +{ + struct arizona *arizona = info->arizona; + bool change; + int ret; + + info->detecting = true; + info->mic = false; + info->jack_flips = 0; + + /* Microphone detection can't use idle mode */ + pm_runtime_get(info->dev); + + ret = regulator_enable(info->micvdd); + if (ret != 0) { + dev_err(arizona->dev, "Failed to enable MICVDD: %d\n", + ret); + } + + if (info->micd_reva) { + regmap_write(arizona->regmap, 0x80, 0x3); + regmap_write(arizona->regmap, 0x294, 0); + regmap_write(arizona->regmap, 0x80, 0x0); + } + + regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, ARIZONA_MICD_ENA, + &change); + if (!change) { + regulator_disable(info->micvdd); + pm_runtime_put_autosuspend(info->dev); + } +} + +static void arizona_stop_mic(struct arizona_extcon_info *info) +{ + struct arizona *arizona = info->arizona; + bool change; + + regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, 0, + &change); + + if (info->micd_reva) { + regmap_write(arizona->regmap, 0x80, 0x3); + regmap_write(arizona->regmap, 0x294, 2); + regmap_write(arizona->regmap, 0x80, 0x0); + } + + if (change) { + regulator_disable(info->micvdd); + pm_runtime_put_autosuspend(info->dev); + } +} + +static irqreturn_t arizona_micdet(int irq, void *data) +{ + struct arizona_extcon_info *info = data; + struct arizona *arizona = info->arizona; + unsigned int val; + int ret; + + mutex_lock(&info->lock); + + ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); + return IRQ_NONE; + } + + dev_dbg(arizona->dev, "MICDET: %x\n", val); + + if (!(val & ARIZONA_MICD_VALID)) { + dev_warn(arizona->dev, "Microphone detection state invalid\n"); + mutex_unlock(&info->lock); + return IRQ_NONE; + } + + /* Due to jack detect this should never happen */ + if (!(val & ARIZONA_MICD_STS)) { + dev_warn(arizona->dev, "Detected open circuit\n"); + info->detecting = false; + goto handled; + } + + /* If we got a high impedence we should have a headset, report it. */ + if (info->detecting && (val & 0x400)) { + ret = extcon_set_cable_state(&info->edev, + ARIZONA_CABLE_HEADSET, true); + + if (ret != 0) + dev_err(arizona->dev, "Headset report failed: %d\n", + ret); + + info->mic = true; + info->detecting = false; + goto handled; + } + + /* If we detected a lower impedence during initial startup + * then we probably have the wrong polarity, flip it. Don't + * do this for the lowest impedences to speed up detection of + * plain headphones. If both polarities report a low + * impedence then give up and report headphones. + */ + if (info->detecting && (val & 0x3f8)) { + info->jack_flips++; + + if (info->jack_flips >= info->micd_num_modes) { + dev_dbg(arizona->dev, "Detected headphone\n"); + info->detecting = false; + ret = extcon_set_cable_state(&info->edev, + ARIZONA_CABLE_HEADPHONE, + true); + if (ret != 0) + dev_err(arizona->dev, + "Headphone report failed: %d\n", + ret); + } else { + info->micd_mode++; + if (info->micd_mode == info->micd_num_modes) + info->micd_mode = 0; + arizona_extcon_set_mode(info, info->micd_mode); + + info->jack_flips++; + } + + goto handled; + } + + /* + * If we're still detecting and we detect a short then we've + * got a headphone. Otherwise it's a button press, the + * button reporting is stubbed out for now. + */ + if (val & 0x3fc) { + if (info->mic) { + dev_dbg(arizona->dev, "Mic button detected\n"); + + } else if (info->detecting) { + dev_dbg(arizona->dev, "Headphone detected\n"); + info->detecting = false; + arizona_stop_mic(info); + + ret = extcon_set_cable_state(&info->edev, + ARIZONA_CABLE_HEADPHONE, + true); + if (ret != 0) + dev_err(arizona->dev, + "Headphone report failed: %d\n", + ret); + } else { + dev_warn(arizona->dev, "Button with no mic: %x\n", + val); + } + } else { + dev_dbg(arizona->dev, "Mic button released\n"); + } + +handled: + pm_runtime_mark_last_busy(info->dev); + mutex_unlock(&info->lock); + + return IRQ_HANDLED; +} + +static irqreturn_t arizona_jackdet(int irq, void *data) +{ + struct arizona_extcon_info *info = data; + struct arizona *arizona = info->arizona; + unsigned int val; + int ret; + + pm_runtime_get_sync(info->dev); + + mutex_lock(&info->lock); + + ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read jackdet status: %d\n", + ret); + mutex_unlock(&info->lock); + pm_runtime_put_autosuspend(info->dev); + return IRQ_NONE; + } + + if (val & ARIZONA_JD1_STS) { + dev_dbg(arizona->dev, "Detected jack\n"); + ret = extcon_set_cable_state(&info->edev, + ARIZONA_CABLE_MECHANICAL, true); + + if (ret != 0) + dev_err(arizona->dev, "Mechanical report failed: %d\n", + ret); + + arizona_start_mic(info); + } else { + dev_dbg(arizona->dev, "Detected jack removal\n"); + + arizona_stop_mic(info); + + ret = extcon_update_state(&info->edev, 0xffffffff, 0); + if (ret != 0) + dev_err(arizona->dev, "Removal report failed: %d\n", + ret); + } + + mutex_unlock(&info->lock); + + pm_runtime_mark_last_busy(info->dev); + pm_runtime_put_autosuspend(info->dev); + + return IRQ_HANDLED; +} + +static int __devinit arizona_extcon_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct arizona_pdata *pdata; + struct arizona_extcon_info *info; + int ret, mode; + + pdata = dev_get_platdata(arizona->dev); + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + ret = -ENOMEM; + goto err; + } + + info->micvdd = devm_regulator_get(arizona->dev, "MICVDD"); + if (IS_ERR(info->micvdd)) { + ret = PTR_ERR(info->micvdd); + dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret); + goto err; + } + + mutex_init(&info->lock); + info->arizona = arizona; + info->dev = &pdev->dev; + info->detecting = true; + platform_set_drvdata(pdev, info); + + switch (arizona->type) { + case WM5102: + switch (arizona->rev) { + case 0: + info->micd_reva = true; + break; + default: + break; + } + break; + default: + break; + } + + info->edev.name = "Headset Jack"; + info->edev.supported_cable = arizona_cable; + info->edev.mutually_exclusive = arizona_exclusions; + + ret = extcon_dev_register(&info->edev, arizona->dev); + if (ret < 0) { + dev_err(arizona->dev, "extcon_dev_regster() failed: %d\n", + ret); + goto err; + } + + if (pdata->num_micd_configs) { + info->micd_modes = pdata->micd_configs; + info->micd_num_modes = pdata->num_micd_configs; + } else { + info->micd_modes = micd_default_modes; + info->micd_num_modes = ARRAY_SIZE(micd_default_modes); + } + + if (arizona->pdata.micd_pol_gpio > 0) { + if (info->micd_modes[0].gpio) + mode = GPIOF_OUT_INIT_HIGH; + else + mode = GPIOF_OUT_INIT_LOW; + + ret = devm_gpio_request_one(&pdev->dev, + arizona->pdata.micd_pol_gpio, + mode, + "MICD polarity"); + if (ret != 0) { + dev_err(arizona->dev, "Failed to request GPIO%d: %d\n", + arizona->pdata.micd_pol_gpio, ret); + goto err_register; + } + } + + arizona_extcon_set_mode(info, 0); + + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + + ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_RISE, + "JACKDET rise", arizona_jackdet, info); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n", + ret); + goto err_register; + } + + ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n", + ret); + goto err_rise; + } + + ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_FALL, + "JACKDET fall", arizona_jackdet, info); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret); + goto err_rise_wake; + } + + ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 1); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n", + ret); + goto err_fall; + } + + ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET, + "MICDET", arizona_micdet, info); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret); + goto err_fall_wake; + } + + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_BIAS_STARTTIME_MASK | + ARIZONA_MICD_RATE_MASK, + 7 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT | + 8 << ARIZONA_MICD_RATE_SHIFT); + + arizona_clk32k_enable(arizona); + regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE, + ARIZONA_JD1_DB, ARIZONA_JD1_DB); + regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, + ARIZONA_JD1_ENA, ARIZONA_JD1_ENA); + + pm_runtime_put(&pdev->dev); + + return 0; + +err_fall_wake: + arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); +err_fall: + arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); +err_rise_wake: + arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); +err_rise: + arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); +err_register: + pm_runtime_disable(&pdev->dev); + extcon_dev_unregister(&info->edev); +err: + return ret; +} + +static int __devexit arizona_extcon_remove(struct platform_device *pdev) +{ + struct arizona_extcon_info *info = platform_get_drvdata(pdev); + struct arizona *arizona = info->arizona; + + pm_runtime_disable(&pdev->dev); + + arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); + arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); + arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info); + arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); + arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); + regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, + ARIZONA_JD1_ENA, 0); + arizona_clk32k_disable(arizona); + extcon_dev_unregister(&info->edev); + + return 0; +} + +static struct platform_driver arizona_extcon_driver = { + .driver = { + .name = "arizona-extcon", + .owner = THIS_MODULE, + }, + .probe = arizona_extcon_probe, + .remove = __devexit_p(arizona_extcon_remove), +}; + +module_platform_driver(arizona_extcon_driver); + +MODULE_DESCRIPTION("Arizona Extcon driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:extcon-arizona"); -- GitLab From c6156328dec52a55f90688cbfad21c83f8711d84 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Tue, 26 Jun 2012 11:56:48 -0300 Subject: [PATCH 2925/6849] usb: phy: Fix Kconfig dependency for Phy drivers USB phy layer driver are only built if usb host is selected, but they are used too by USB_GADGET drivers Signed-off-by: Alexandre Pereira da Silva Acked-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Makefile | 2 +- drivers/usb/phy/Kconfig | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index c691eea51537..f5ed3d75fa5a 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB) += phy/ +obj-$(CONFIG_USB_COMMON) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3cfabcba7447..e7cf84f0751a 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -2,11 +2,11 @@ # Physical Layer USB driver configuration # comment "USB Physical Layer drivers" - depends on USB + depends on USB || USB_GADGET config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" - depends on USB + depends on USB || USB_GADGET depends on I2C help Say Y here to add support for the NXP ISP1301 USB transceiver driver. -- GitLab From 065b07e7a14676f4138ce4619d229c0be5a74230 Mon Sep 17 00:00:00 2001 From: Forest Bond Date: Fri, 22 Jun 2012 10:30:38 -0400 Subject: [PATCH 2926/6849] USB: option: Add USB ID for Novatel Ovation MC551 This device is also known as the Verizon USB551L. Signed-off-by: Forest Bond Acked-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 396d968dddd9..adf8ce72be50 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -236,6 +236,7 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 +#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 @@ -738,6 +739,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, + /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, -- GitLab From 3fcc8f96829776cf181918461923d1e3bbb831a2 Mon Sep 17 00:00:00 2001 From: Craig Shelley Date: Tue, 26 Jun 2012 23:20:04 +0100 Subject: [PATCH 2927/6849] USB: CP210x Add 10 Device IDs This patch adds 10 device IDs for CP210x based devices from the following manufacturers: Timewave Clipsal Festo Link Instruments Signed-off-by: Craig Shelley Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 73d25cd8cba5..1e71079ce33b 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -93,6 +93,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ @@ -134,7 +135,13 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ + { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ + { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ + { USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */ + { USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */ + { USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */ + { USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ @@ -146,7 +153,11 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ + { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ + { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ + { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; -- GitLab From 251da4130115b29403a57096fa0988249f31fc55 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 16:27:09 -0700 Subject: [PATCH 2928/6849] ipv4: Cache ip_error() routes even when not forwarding. And account for the fact that, when we are not forwarding, we should bump statistic counters rather than emit an ICMP response. RP-filter rejected lookups are still not cached. Since -EHOSTUNREACH and -ENETUNREACH can now no longer be seen in ip_rcv_finish(), remove those checks. Signed-off-by: David S. Miller --- net/ipv4/ip_input.c | 8 +------- net/ipv4/route.c | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index bca25179cdb9..2a39204de5bc 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -342,13 +342,7 @@ static int ip_rcv_finish(struct sk_buff *skb) err = ip_route_input_noref(skb, iph->daddr, iph->saddr, iph->tos, skb->dev); if (unlikely(err)) { - if (err == -EHOSTUNREACH) - IP_INC_STATS_BH(dev_net(skb->dev), - IPSTATS_MIB_INADDRERRORS); - else if (err == -ENETUNREACH) - IP_INC_STATS_BH(dev_net(skb->dev), - IPSTATS_MIB_INNOROUTES); - else if (err == -EXDEV) + if (err == -EXDEV) NET_INC_STATS_BH(dev_net(skb->dev), LINUX_MIB_IPRPFILTER); goto drop; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 846961c6cbe1..81533e3a23d1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb) static int ip_error(struct sk_buff *skb) { + struct in_device *in_dev = __in_dev_get_rcu(skb->dev); struct rtable *rt = skb_rtable(skb); struct inet_peer *peer; unsigned long now; + struct net *net; bool send; int code; + net = dev_net(rt->dst.dev); + if (!IN_DEV_FORWARD(in_dev)) { + switch (rt->dst.error) { + case EHOSTUNREACH: + IP_INC_STATS_BH(net, IPSTATS_MIB_INADDRERRORS); + break; + + case ENETUNREACH: + IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES); + break; + } + goto out; + } + switch (rt->dst.error) { case EINVAL: default: @@ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb) break; case ENETUNREACH: code = ICMP_NET_UNREACH; - IP_INC_STATS_BH(dev_net(rt->dst.dev), - IPSTATS_MIB_INNOROUTES); + IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES); break; case EACCES: code = ICMP_PKT_FILTERED; @@ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, fl4.daddr = daddr; fl4.saddr = saddr; err = fib_lookup(net, &fl4, &res); - if (err != 0) { - if (!IN_DEV_FORWARD(in_dev)) - goto e_hostunreach; + if (err != 0) goto no_route; - } RT_CACHE_STAT_INC(in_slow_tot); @@ -2279,7 +2291,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, } if (!IN_DEV_FORWARD(in_dev)) - goto e_hostunreach; + goto no_route; if (res.type != RTN_UNICAST) goto martian_destination; @@ -2367,10 +2379,6 @@ martian_destination: &daddr, &saddr, dev->name); #endif -e_hostunreach: - err = -EHOSTUNREACH; - goto out; - e_inval: err = -EINVAL; goto out; -- GitLab From a2842a1e66329798d66563b52faec1a299ec4f73 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 25 Jun 2012 05:35:45 +0000 Subject: [PATCH 2929/6849] net: l2tp_eth: use LLTX to avoid LOCKDEP splats Denys Fedoryshchenko reported a LOCKDEP issue with l2tp code. [ 8683.927442] ====================================================== [ 8683.927555] [ INFO: possible circular locking dependency detected ] [ 8683.927672] 3.4.1-build-0061 #14 Not tainted [ 8683.927782] ------------------------------------------------------- [ 8683.927895] swapper/0/0 is trying to acquire lock: [ 8683.928007] (slock-AF_INET){+.-...}, at: [] l2tp_xmit_skb+0x173/0x47e [l2tp_core] [ 8683.928121] [ 8683.928121] but task is already holding lock: [ 8683.928121] (_xmit_ETHER#2){+.-...}, at: [] sch_direct_xmit+0x36/0x119 [ 8683.928121] [ 8683.928121] which lock already depends on the new lock. [ 8683.928121] [ 8683.928121] [ 8683.928121] the existing dependency chain (in reverse order) is: [ 8683.928121] [ 8683.928121] -> #1 (_xmit_ETHER#2){+.-...}: [ 8683.928121] [] lock_acquire+0x71/0x85 [ 8683.928121] [] _raw_spin_lock+0x33/0x40 [ 8683.928121] [] ip_send_reply+0xf2/0x1ce [ 8683.928121] [] tcp_v4_send_reset+0x153/0x16f [ 8683.928121] [] tcp_v4_do_rcv+0x172/0x194 [ 8683.928121] [] tcp_v4_rcv+0x387/0x5a0 [ 8683.928121] [] ip_local_deliver_finish+0x13a/0x1e9 [ 8683.928121] [] NF_HOOK.clone.11+0x46/0x4d [ 8683.928121] [] ip_local_deliver+0x41/0x45 [ 8683.928121] [] ip_rcv_finish+0x31a/0x33c [ 8683.928121] [] NF_HOOK.clone.11+0x46/0x4d [ 8683.928121] [] ip_rcv+0x201/0x23d [ 8683.928121] [] __netif_receive_skb+0x329/0x378 [ 8683.928121] [] netif_receive_skb+0x4e/0x7d [ 8683.928121] [] rtl8139_poll+0x243/0x33d [8139too] [ 8683.928121] [] net_rx_action+0x90/0x15d [ 8683.928121] [] __do_softirq+0x7b/0x118 [ 8683.928121] [ 8683.928121] -> #0 (slock-AF_INET){+.-...}: [ 8683.928121] [] __lock_acquire+0x9a3/0xc27 [ 8683.928121] [] lock_acquire+0x71/0x85 [ 8683.928121] [] _raw_spin_lock+0x33/0x40 [ 8683.928121] [] l2tp_xmit_skb+0x173/0x47e [l2tp_core] [ 8683.928121] [] l2tp_eth_dev_xmit+0x1a/0x2f [l2tp_eth] [ 8683.928121] [] dev_hard_start_xmit+0x333/0x3f2 [ 8683.928121] [] sch_direct_xmit+0x55/0x119 [ 8683.928121] [] dev_queue_xmit+0x282/0x418 [ 8683.928121] [] NF_HOOK.clone.19+0x45/0x4c [ 8683.928121] [] arp_xmit+0x22/0x24 [ 8683.928121] [] arp_send+0x41/0x48 [ 8683.928121] [] arp_process+0x289/0x491 [ 8683.928121] [] NF_HOOK.clone.19+0x45/0x4c [ 8683.928121] [] arp_rcv+0xb1/0xc3 [ 8683.928121] [] __netif_receive_skb+0x329/0x378 [ 8683.928121] [] process_backlog+0x69/0x130 [ 8683.928121] [] net_rx_action+0x90/0x15d [ 8683.928121] [] __do_softirq+0x7b/0x118 [ 8683.928121] [ 8683.928121] other info that might help us debug this: [ 8683.928121] [ 8683.928121] Possible unsafe locking scenario: [ 8683.928121] [ 8683.928121] CPU0 CPU1 [ 8683.928121] ---- ---- [ 8683.928121] lock(_xmit_ETHER#2); [ 8683.928121] lock(slock-AF_INET); [ 8683.928121] lock(_xmit_ETHER#2); [ 8683.928121] lock(slock-AF_INET); [ 8683.928121] [ 8683.928121] *** DEADLOCK *** [ 8683.928121] [ 8683.928121] 3 locks held by swapper/0/0: [ 8683.928121] #0: (rcu_read_lock){.+.+..}, at: [] rcu_lock_acquire+0x0/0x30 [ 8683.928121] #1: (rcu_read_lock_bh){.+....}, at: [] rcu_lock_acquire+0x0/0x30 [ 8683.928121] #2: (_xmit_ETHER#2){+.-...}, at: [] sch_direct_xmit+0x36/0x119 [ 8683.928121] [ 8683.928121] stack backtrace: [ 8683.928121] Pid: 0, comm: swapper/0 Not tainted 3.4.1-build-0061 #14 [ 8683.928121] Call Trace: [ 8683.928121] [] ? printk+0x18/0x1a [ 8683.928121] [] print_circular_bug+0x1ac/0x1b6 [ 8683.928121] [] __lock_acquire+0x9a3/0xc27 [ 8683.928121] [] lock_acquire+0x71/0x85 [ 8683.928121] [] ? l2tp_xmit_skb+0x173/0x47e [l2tp_core] [ 8683.928121] [] _raw_spin_lock+0x33/0x40 [ 8683.928121] [] ? l2tp_xmit_skb+0x173/0x47e [l2tp_core] [ 8683.928121] [] l2tp_xmit_skb+0x173/0x47e [l2tp_core] [ 8683.928121] [] l2tp_eth_dev_xmit+0x1a/0x2f [l2tp_eth] [ 8683.928121] [] dev_hard_start_xmit+0x333/0x3f2 [ 8683.928121] [] sch_direct_xmit+0x55/0x119 [ 8683.928121] [] dev_queue_xmit+0x282/0x418 [ 8683.928121] [] ? dev_hard_start_xmit+0x3f2/0x3f2 [ 8683.928121] [] NF_HOOK.clone.19+0x45/0x4c [ 8683.928121] [] arp_xmit+0x22/0x24 [ 8683.928121] [] ? dev_hard_start_xmit+0x3f2/0x3f2 [ 8683.928121] [] arp_send+0x41/0x48 [ 8683.928121] [] arp_process+0x289/0x491 [ 8683.928121] [] ? __neigh_lookup.clone.20+0x42/0x42 [ 8683.928121] [] NF_HOOK.clone.19+0x45/0x4c [ 8683.928121] [] arp_rcv+0xb1/0xc3 [ 8683.928121] [] ? __neigh_lookup.clone.20+0x42/0x42 [ 8683.928121] [] __netif_receive_skb+0x329/0x378 [ 8683.928121] [] process_backlog+0x69/0x130 [ 8683.928121] [] net_rx_action+0x90/0x15d [ 8683.928121] [] __do_softirq+0x7b/0x118 [ 8683.928121] [] ? local_bh_enable+0xd/0xd [ 8683.928121] [] ? irq_exit+0x41/0x91 [ 8683.928121] [] ? do_IRQ+0x79/0x8d [ 8683.928121] [] ? trace_hardirqs_off_caller+0x2e/0x86 [ 8683.928121] [] ? common_interrupt+0x2e/0x34 [ 8683.928121] [] ? default_idle+0x23/0x38 [ 8683.928121] [] ? cpu_idle+0x55/0x6f [ 8683.928121] [] ? rest_init+0xa1/0xa7 [ 8683.928121] [] ? __read_lock_failed+0x14/0x14 [ 8683.928121] [] ? start_kernel+0x303/0x30a [ 8683.928121] [] ? repair_env_string+0x51/0x51 [ 8683.928121] [] ? i386_start_kernel+0xa8/0xaf It appears that like most virtual devices, l2tp should be converted to LLTX mode. This patch takes care of statistics using atomic_long in both RX and TX paths, and fix a bug in l2tp_eth_dev_recv(), which was caching skb->data before a pskb_may_pull() call. Signed-off-by: Eric Dumazet Reported-by: Denys Fedoryshchenko Cc: James Chapman Cc: Hong zhi guo Cc: Francois Romieu Signed-off-by: David S. Miller --- net/l2tp/l2tp_eth.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index c3738f49646a..47b259fccd27 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -42,6 +42,11 @@ struct l2tp_eth { struct sock *tunnel_sock; struct l2tp_session *session; struct list_head list; + atomic_long_t tx_bytes; + atomic_long_t tx_packets; + atomic_long_t rx_bytes; + atomic_long_t rx_packets; + atomic_long_t rx_errors; }; /* via l2tp_session_priv() */ @@ -88,24 +93,40 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) struct l2tp_eth *priv = netdev_priv(dev); struct l2tp_session *session = priv->session; - dev->stats.tx_bytes += skb->len; - dev->stats.tx_packets++; + atomic_long_add(skb->len, &priv->tx_bytes); + atomic_long_inc(&priv->tx_packets); l2tp_xmit_skb(session, skb, session->hdr_len); return NETDEV_TX_OK; } +static struct rtnl_link_stats64 *l2tp_eth_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + struct l2tp_eth *priv = netdev_priv(dev); + + stats->tx_bytes = atomic_long_read(&priv->tx_bytes); + stats->tx_packets = atomic_long_read(&priv->tx_packets); + stats->rx_bytes = atomic_long_read(&priv->rx_bytes); + stats->rx_packets = atomic_long_read(&priv->rx_packets); + stats->rx_errors = atomic_long_read(&priv->rx_errors); + return stats; +} + + static struct net_device_ops l2tp_eth_netdev_ops = { .ndo_init = l2tp_eth_dev_init, .ndo_uninit = l2tp_eth_dev_uninit, .ndo_start_xmit = l2tp_eth_dev_xmit, + .ndo_get_stats64 = l2tp_eth_get_stats64, }; static void l2tp_eth_dev_setup(struct net_device *dev) { ether_setup(dev); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->features |= NETIF_F_LLTX; dev->netdev_ops = &l2tp_eth_netdev_ops; dev->destructor = free_netdev; } @@ -114,17 +135,17 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, { struct l2tp_eth_sess *spriv = l2tp_session_priv(session); struct net_device *dev = spriv->dev; + struct l2tp_eth *priv = netdev_priv(dev); if (session->debug & L2TP_MSG_DATA) { unsigned int length; - u8 *ptr = skb->data; length = min(32u, skb->len); if (!pskb_may_pull(skb, length)) goto error; pr_debug("%s: eth recv\n", session->name); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length); } if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) @@ -139,15 +160,15 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, nf_reset(skb); if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { - dev->stats.rx_packets++; - dev->stats.rx_bytes += data_len; - } else - dev->stats.rx_errors++; - + atomic_long_inc(&priv->rx_packets); + atomic_long_add(data_len, &priv->rx_bytes); + } else { + atomic_long_inc(&priv->rx_errors); + } return; error: - dev->stats.rx_errors++; + atomic_long_inc(&priv->rx_errors); kfree_skb(skb); } -- GitLab From 57efd44c8cad440fb00ef8078cb018ab2f221373 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 25 Jun 2012 21:54:46 +0000 Subject: [PATCH 2930/6849] ixgbe: Do not pad FCoE frames as this can cause issues with FCoE DDP FCoE target mode was experiencing issues due to the fact that we were sending up data frames that were padded to 60 bytes after the DDP logic had already stripped the frame down to 52 or 56 depending on the use of VLANs. This was resulting in the FCoE DDP logic having issues since it thought the frame still had data in it due to the padding. To resolve this, adding code so that we do not pad FCoE frames prior to handling them to the stack. CC: Signed-off-by: Alexander Duyck Tested-by: Phil Schmitt Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 4 ++-- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 3ef3c5284e52..7af291e236bf 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -196,7 +196,7 @@ enum ixgbe_ring_state_t { __IXGBE_HANG_CHECK_ARMED, __IXGBE_RX_RSC_ENABLED, __IXGBE_RX_CSUM_UDP_ZERO_ERR, - __IXGBE_RX_FCOE_BUFSZ, + __IXGBE_RX_FCOE, }; #define check_for_tx_hang(ring) \ @@ -290,7 +290,7 @@ struct ixgbe_ring_feature { #if defined(IXGBE_FCOE) && (PAGE_SIZE < 8192) static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring) { - return test_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state) ? 1 : 0; + return test_bit(__IXGBE_RX_FCOE, &ring->state) ? 1 : 0; } #else #define ixgbe_rx_pg_order(_ring) 0 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index af1a5314b494..c377706e81a8 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -634,7 +634,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, f = &adapter->ring_feature[RING_F_FCOE]; if ((rxr_idx >= f->mask) && (rxr_idx < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); + set_bit(__IXGBE_RX_FCOE, &ring->state); } #endif /* IXGBE_FCOE */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index cbb05d65960f..18ca3bcadf0c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1058,17 +1058,17 @@ static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, #ifdef IXGBE_FCOE /** * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @adapter: address of board private structure + * @ring: structure containing ring specific data * @rx_desc: advanced rx descriptor * * Returns : true if it is FCoE pkt */ -static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc) { __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; - return (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + return test_bit(__IXGBE_RX_FCOE, &ring->state) && ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); @@ -1549,6 +1549,12 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring, skb->truesize -= ixgbe_rx_bufsz(rx_ring); } +#ifdef IXGBE_FCOE + /* do not attempt to pad FCoE Frames as this will disrupt DDP */ + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) + return false; + +#endif /* if skb_pad returns an error the skb was freed */ if (unlikely(skb->len < 60)) { int pad_len = 60 - skb->len; @@ -1775,7 +1781,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) { ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); if (!ddp_bytes) { dev_kfree_skb_any(skb); -- GitLab From 5ac24979dcb3418a295e11823c1f2506df1d9926 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 25 Jun 2012 22:39:45 +0000 Subject: [PATCH 2931/6849] net: qmi_wwan: simplify a check in qmi_wwan_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This code is easier to read if we specify which flags we want at the condition instead of at the top of the function. Signed-off-by: Dan Carpenter Acked-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 68ca6769210f..484eaa5c8a5d 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -129,7 +129,6 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; struct usb_cdc_union_desc *cdc_union = NULL; struct usb_cdc_ether_desc *cdc_ether = NULL; - u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; u32 found = 0; struct usb_driver *driver = driver_of(intf); struct qmi_wwan_state *info = (void *)&dev->data; @@ -197,7 +196,8 @@ next_desc: } /* did we find all the required ones? */ - if ((found & required) != required) { + if (!(found & (1 << USB_CDC_HEADER_TYPE)) || + !(found & (1 << USB_CDC_UNION_TYPE))) { dev_err(&intf->dev, "CDC functional descriptors missing\n"); goto err; } -- GitLab From 65ab16fd385f72baf556fcebe5118d8b6f256ace Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 22 Jun 2012 10:20:04 +0200 Subject: [PATCH 2932/6849] ARM: EXYNOS: Remove leftovers of the Samsung specific power domain control Nowadays we use generic power domain support instead of Samsung specific power domain control driver. Cc: Thomas Abraham Cc: Rob Herring Cc: Grant Likely Cc: Rafael J. Wysocki Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/mach-nuri.c | 1 - arch/arm/mach-exynos/mach-origen.c | 1 - arch/arm/mach-exynos/mach-smdkv310.c | 1 - arch/arm/mach-exynos/mach-universal_c210.c | 1 - arch/arm/plat-samsung/Kconfig | 8 -- arch/arm/plat-samsung/Makefile | 4 - arch/arm/plat-samsung/include/plat/devs.h | 1 - arch/arm/plat-samsung/include/plat/pd.h | 30 ------- arch/arm/plat-samsung/pd.c | 95 ---------------------- 9 files changed, 142 deletions(-) delete mode 100644 arch/arm/plat-samsung/include/plat/pd.h delete mode 100644 arch/arm/plat-samsung/pd.c diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index 656f8fc9addd..f3b328d0aff6 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index f5572be9d7bf..873c708fd340 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index 262e9e446a96..5fb209c4a594 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index cd92fa86ba41..68719f57dcea 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index a2fae4ea0936..ffc84acb7e97 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -491,14 +491,6 @@ config S5P_SLEEP Internal config node to apply common S5P sleep management code. Can be selected by S5P and newer SoCs with similar sleep procedure. -comment "Power Domain" - -config SAMSUNG_PD - bool "Samsung Power Domain" - depends on PM_RUNTIME - help - Say Y here if you want to control Power Domain by Runtime PM. - config DEBUG_S3C_UART depends on PLAT_SAMSUNG int diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 860b2db4db15..4bb58c2dc704 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -60,10 +60,6 @@ obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o -# PD support - -obj-$(CONFIG_SAMSUNG_PD) += pd.o - # PWM support obj-$(CONFIG_HAVE_PWM) += pwm.o diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 61ca2f356c52..5da4b4f38f40 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -131,7 +131,6 @@ extern struct platform_device exynos4_device_ohci; extern struct platform_device exynos4_device_pcm0; extern struct platform_device exynos4_device_pcm1; extern struct platform_device exynos4_device_pcm2; -extern struct platform_device exynos4_device_pd[]; extern struct platform_device exynos4_device_spdif; extern struct platform_device exynos_device_drm; diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h deleted file mode 100644 index abb4bc32716a..000000000000 --- a/arch/arm/plat-samsung/include/plat/pd.h +++ /dev/null @@ -1,30 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/pd.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_PLAT_SAMSUNG_PD_H -#define __ASM_PLAT_SAMSUNG_PD_H __FILE__ - -struct samsung_pd_info { - int (*enable)(struct device *dev); - int (*disable)(struct device *dev); - void __iomem *base; -}; - -enum exynos4_pd_block { - PD_MFC, - PD_G3D, - PD_LCD0, - PD_LCD1, - PD_TV, - PD_CAM, - PD_GPS -}; - -#endif /* __ASM_PLAT_SAMSUNG_PD_H */ diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c deleted file mode 100644 index 312b510d86b7..000000000000 --- a/arch/arm/plat-samsung/pd.c +++ /dev/null @@ -1,95 +0,0 @@ -/* linux/arch/arm/plat-samsung/pd.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Samsung Power domain support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include - -#include - -static int samsung_pd_probe(struct platform_device *pdev) -{ - struct samsung_pd_info *pdata = pdev->dev.platform_data; - struct device *dev = &pdev->dev; - - if (!pdata) { - dev_err(dev, "no device data specified\n"); - return -ENOENT; - } - - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - dev_info(dev, "power domain registered\n"); - return 0; -} - -static int __devexit samsung_pd_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - pm_runtime_disable(dev); - return 0; -} - -static int samsung_pd_runtime_suspend(struct device *dev) -{ - struct samsung_pd_info *pdata = dev->platform_data; - int ret = 0; - - if (pdata->disable) - ret = pdata->disable(dev); - - dev_dbg(dev, "suspended\n"); - return ret; -} - -static int samsung_pd_runtime_resume(struct device *dev) -{ - struct samsung_pd_info *pdata = dev->platform_data; - int ret = 0; - - if (pdata->enable) - ret = pdata->enable(dev); - - dev_dbg(dev, "resumed\n"); - return ret; -} - -static const struct dev_pm_ops samsung_pd_pm_ops = { - .runtime_suspend = samsung_pd_runtime_suspend, - .runtime_resume = samsung_pd_runtime_resume, -}; - -static struct platform_driver samsung_pd_driver = { - .driver = { - .name = "samsung-pd", - .owner = THIS_MODULE, - .pm = &samsung_pd_pm_ops, - }, - .probe = samsung_pd_probe, - .remove = __devexit_p(samsung_pd_remove), -}; - -static int __init samsung_pd_init(void) -{ - int ret; - - ret = platform_driver_register(&samsung_pd_driver); - if (ret) - printk(KERN_ERR "%s: failed to add PD driver\n", __func__); - - return ret; -} -arch_initcall(samsung_pd_init); -- GitLab From c8dd5110dead436b178bb2d8976290fd5f77a2ee Mon Sep 17 00:00:00 2001 From: Boojin Kim Date: Wed, 27 Jun 2012 09:45:42 +0900 Subject: [PATCH 2933/6849] ARM: EXYNOS: Remove the L2 cache latency setting for EXYNOS5 Since SYSRAM set the L2 cache latency on EXYNOS5 SoCs, no longer need that in the kernel. It helps to reduce booting time (no need cache disable and cache enable). Signed-off-by: Boojin Kim Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/common.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 742edd3bbec3..0ec1a91388c7 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -712,31 +712,6 @@ static int __init exynos4_l2x0_cache_init(void) early_initcall(exynos4_l2x0_cache_init); #endif -static int __init exynos5_l2_cache_init(void) -{ - unsigned int val; - - if (!soc_is_exynos5250()) - return 0; - - asm volatile("mrc p15, 0, %0, c1, c0, 0\n" - "bic %0, %0, #(1 << 2)\n" /* cache disable */ - "mcr p15, 0, %0, c1, c0, 0\n" - "mrc p15, 1, %0, c9, c0, 2\n" - : "=r"(val)); - - val |= (1 << 9) | (1 << 5) | (2 << 6) | (2 << 0); - - asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(val)); - asm volatile("mrc p15, 0, %0, c1, c0, 0\n" - "orr %0, %0, #(1 << 2)\n" /* cache enable */ - "mcr p15, 0, %0, c1, c0, 0\n" - : : "r"(val)); - - return 0; -} -early_initcall(exynos5_l2_cache_init); - static int __init exynos_init(void) { printk(KERN_INFO "EXYNOS: Initializing architecture\n"); -- GitLab From 58c553d4d4637e1955a571350888530cd0073276 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 27 Jun 2012 10:03:00 +0900 Subject: [PATCH 2934/6849] ARM: EXYNOS: Fix EXYNOS_DEV_DMA Kconfig entry Commit 20ef9e08 ("ARM: EXYNOS: Support DMA for EXYNOS5250 SoC") renamed EXYNOS4_DEV_DMA to EXYNOS_DEV_DMA. But some machine entries still had EXYNOS4_DEV_DMA. Changed them to EXYNOS_DEV_DMA. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 573be57d3d28..6f6d13f91e4c 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -212,7 +212,7 @@ config MACH_SMDKV310 select EXYNOS_DEV_SYSMMU select EXYNOS4_DEV_AHCI select SAMSUNG_DEV_KEYPAD - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_DMA select SAMSUNG_DEV_PWM select EXYNOS4_DEV_USB_OHCI select EXYNOS4_SETUP_FIMD0 @@ -264,7 +264,7 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_ONENAND select S5P_DEV_TV select EXYNOS_DEV_SYSMMU - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_DMA select EXYNOS_DEV_DRM select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 @@ -303,7 +303,7 @@ config MACH_NURI select S5P_DEV_MFC select S5P_DEV_USB_EHCI select S5P_SETUP_MIPIPHY - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_DMA select EXYNOS_DEV_DRM select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMD0 @@ -341,7 +341,7 @@ config MACH_ORIGEN select SAMSUNG_DEV_PWM select EXYNOS_DEV_DRM select EXYNOS_DEV_SYSMMU - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_DMA select EXYNOS4_DEV_USB_OHCI select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_SDHCI -- GitLab From 9e303f228c24d529bf479196d290eedc2a04cd5e Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:01:25 +0300 Subject: [PATCH 2935/6849] gpio/omap: fix irq loss while in idle with debounce on It seems that currently GPIO module is not working correctly during idle when debounce is enabled - the system almost never responds to button presses (observed on OMAP3530 ES2.1 and OMAP3630 ES1.2 pandora boards). Even though wakeups are probably working, it seems that the GPIO module itself is unable to detect input events and generate interrupts. OMAP35x TRM also states that: "If the debounce clock is inactive, the debounce cell gates all input signals and thus cannot be used." So whenever we are disabling debounce clocks (for PM or other reasons), be sure the module's debounce feature is disabled too. Cc: Kevin Hilman Signed-off-by: Grazvydas Ignotas Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index c4ed1722734c..ff213e70fa5a 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -174,12 +174,22 @@ static inline void _gpio_dbck_enable(struct gpio_bank *bank) if (bank->dbck_enable_mask && !bank->dbck_enabled) { clk_enable(bank->dbck); bank->dbck_enabled = true; + + __raw_writel(bank->dbck_enable_mask, + bank->base + bank->regs->debounce_en); } } static inline void _gpio_dbck_disable(struct gpio_bank *bank) { if (bank->dbck_enable_mask && bank->dbck_enabled) { + /* + * Disable debounce before cutting it's clock. If debounce is + * enabled but the clock is not, GPIO module seems to be unable + * to detect events and generate interrupts at least on OMAP3. + */ + __raw_writel(0, bank->base + bank->regs->debounce_en); + clk_disable(bank->dbck); bank->dbck_enabled = false; } -- GitLab From 3688be49e901551756f4c570a8eb3b98b1e2bbe5 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 27 Jun 2012 11:29:54 +0900 Subject: [PATCH 2936/6849] ARM: SAMSUNG: Fix compiler warning in dma-ops.c file Fixes the following build warning: arch/arm/plat-samsung/dma-ops.c:129:2: warning: initialization from incompatible pointer type [enabled by default] arch/arm/plat-samsung/dma-ops.c:129:2: warning: (near initialization for 'dmadev_ops.release') [enabled by default] Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/dma-ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index f9eb353d768c..c38d75489240 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -36,8 +36,7 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch, return (unsigned)dma_request_channel(mask, pl330_filter, filter_param); } -static int samsung_dmadev_release(unsigned ch, - struct s3c2410_dma_client *client) +static int samsung_dmadev_release(unsigned ch, void *param) { dma_release_channel((struct dma_chan *)ch); -- GitLab From cf61fdb944534ffa84a824bb8c31a3826cdc169d Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Sat, 23 Jun 2012 21:24:30 -0300 Subject: [PATCH 2937/6849] USB: FHCI: Reusing QUICC Engine USB Controller registers from immap_qe.h The struct fhci_regs (in drivers/usb/host/fhci.h) is basically a redefinition of the struct qe_usb_ctlr (in arch/powerpc/include/asm/immap_qe.h). The qe_usb_ctlr struct is preferrable once it uses accurately the registers' names found in the Freescale's QUICC Engine Block Reference Manuals (QEIWRM.pdf Rev.4.4 Chapter 19 for MPC836xE series and MPC8323ERM.pdf Rev.2 Chapter 36 for MPC832xE series), making easier to map the FHCI device driver to the hardware manual. Also, as the FHCI driver uses the USB Controller registers, the name qe_usb_ctlr is a more precise representation of the hardware than fhci_regs. Signed-off-by: Guilherme Maciel Ferreira Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fhci-dbg.c | 12 ++++++------ drivers/usb/host/fhci-hcd.c | 32 ++++++++++++++++---------------- drivers/usb/host/fhci-hub.c | 16 ++++++++-------- drivers/usb/host/fhci-sched.c | 30 +++++++++++++++--------------- drivers/usb/host/fhci-tds.c | 14 +++++++------- drivers/usb/host/fhci.h | 22 ++-------------------- 6 files changed, 54 insertions(+), 72 deletions(-) diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c index 6fe550049119..f238cb37305c 100644 --- a/drivers/usb/host/fhci-dbg.c +++ b/drivers/usb/host/fhci-dbg.c @@ -41,7 +41,7 @@ void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er) static int fhci_dfs_regs_show(struct seq_file *s, void *v) { struct fhci_hcd *fhci = s->private; - struct fhci_regs __iomem *regs = fhci->regs; + struct qe_usb_ctlr __iomem *regs = fhci->regs; seq_printf(s, "mode: 0x%x\n" "addr: 0x%x\n" @@ -50,11 +50,11 @@ static int fhci_dfs_regs_show(struct seq_file *s, void *v) "status: 0x%x\n" "SOF timer: %d\n" "frame number: %d\n" "lines status: 0x%x\n", - in_8(®s->usb_mod), in_8(®s->usb_addr), - in_8(®s->usb_comm), in_be16(®s->usb_ep[0]), - in_be16(®s->usb_event), in_be16(®s->usb_mask), - in_8(®s->usb_status), in_be16(®s->usb_sof_tmr), - in_be16(®s->usb_frame_num), + in_8(®s->usb_usmod), in_8(®s->usb_usadr), + in_8(®s->usb_uscom), in_be16(®s->usb_usep[0]), + in_be16(®s->usb_usber), in_be16(®s->usb_usbmr), + in_8(®s->usb_usbs), in_be16(®s->usb_ussft), + in_be16(®s->usb_usfrn), fhci_ioports_check_bus_state(fhci)); return 0; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index d2623747b489..7da1a26bed2e 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -40,8 +40,8 @@ void fhci_start_sof_timer(struct fhci_hcd *fhci) /* clear frame_n */ out_be16(&fhci->pram->frame_num, 0); - out_be16(&fhci->regs->usb_sof_tmr, 0); - setbits8(&fhci->regs->usb_mod, USB_MODE_SFTE); + out_be16(&fhci->regs->usb_ussft, 0); + setbits8(&fhci->regs->usb_usmod, USB_MODE_SFTE); fhci_dbg(fhci, "<- %s\n", __func__); } @@ -50,7 +50,7 @@ void fhci_stop_sof_timer(struct fhci_hcd *fhci) { fhci_dbg(fhci, "-> %s\n", __func__); - clrbits8(&fhci->regs->usb_mod, USB_MODE_SFTE); + clrbits8(&fhci->regs->usb_usmod, USB_MODE_SFTE); gtm_stop_timer16(fhci->timer); fhci_dbg(fhci, "<- %s\n", __func__); @@ -58,7 +58,7 @@ void fhci_stop_sof_timer(struct fhci_hcd *fhci) u16 fhci_get_sof_timer_count(struct fhci_usb *usb) { - return be16_to_cpu(in_be16(&usb->fhci->regs->usb_sof_tmr) / 12); + return be16_to_cpu(in_be16(&usb->fhci->regs->usb_ussft) / 12); } /* initialize the endpoint zero */ @@ -88,8 +88,8 @@ void fhci_usb_enable_interrupt(struct fhci_usb *usb) enable_irq(fhci_to_hcd(fhci)->irq); /* initialize the event register and mask register */ - out_be16(&usb->fhci->regs->usb_event, 0xffff); - out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); + out_be16(&usb->fhci->regs->usb_usber, 0xffff); + out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk); /* enable the timer interrupts */ enable_irq(fhci->timer->irq); @@ -109,7 +109,7 @@ void fhci_usb_disable_interrupt(struct fhci_usb *usb) /* disable the usb interrupt */ disable_irq_nosync(fhci_to_hcd(fhci)->irq); - out_be16(&usb->fhci->regs->usb_mask, 0); + out_be16(&usb->fhci->regs->usb_usbmr, 0); } usb->intr_nesting_cnt++; } @@ -119,9 +119,9 @@ static u32 fhci_usb_enable(struct fhci_hcd *fhci) { struct fhci_usb *usb = fhci->usb_lld; - out_be16(&usb->fhci->regs->usb_event, 0xffff); - out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); - setbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN); + out_be16(&usb->fhci->regs->usb_usber, 0xffff); + out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk); + setbits8(&usb->fhci->regs->usb_usmod, USB_MODE_EN); mdelay(100); @@ -141,7 +141,7 @@ static u32 fhci_usb_disable(struct fhci_hcd *fhci) usb->port_status == FHCI_PORT_LOW) fhci_device_disconnected_interrupt(fhci); - clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN); + clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_EN); return 0; } @@ -285,13 +285,13 @@ static int fhci_usb_init(struct fhci_hcd *fhci) USB_E_IDLE_MASK | USB_E_RESET_MASK | USB_E_SFT_MASK | USB_E_MSF_MASK); - out_8(&usb->fhci->regs->usb_mod, USB_MODE_HOST | USB_MODE_EN); + out_8(&usb->fhci->regs->usb_usmod, USB_MODE_HOST | USB_MODE_EN); /* clearing the mask register */ - out_be16(&usb->fhci->regs->usb_mask, 0); + out_be16(&usb->fhci->regs->usb_usbmr, 0); /* initialing the event register */ - out_be16(&usb->fhci->regs->usb_event, 0xffff); + out_be16(&usb->fhci->regs->usb_usber, 0xffff); if (endpoint_zero_init(usb, DEFAULT_DATA_MEM, DEFAULT_RING_LEN) != 0) { fhci_usb_free(usb); @@ -745,8 +745,8 @@ static int __devinit of_fhci_probe(struct platform_device *ofdev) } /* Clear and disable any pending interrupts. */ - out_be16(&fhci->regs->usb_event, 0xffff); - out_be16(&fhci->regs->usb_mask, 0); + out_be16(&fhci->regs->usb_usber, 0xffff); + out_be16(&fhci->regs->usb_usbmr, 0); ret = usb_add_hcd(hcd, usb_irq, 0); if (ret < 0) diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c index 348fe62e94f7..6af2512f8378 100644 --- a/drivers/usb/host/fhci-hub.c +++ b/drivers/usb/host/fhci-hub.c @@ -97,7 +97,7 @@ void fhci_port_disable(struct fhci_hcd *fhci) /* Enable IDLE since we want to know if something comes along */ usb->saved_msk |= USB_E_IDLE_MASK; - out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); + out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk); /* check if during the disconnection process attached new device */ if (port_status == FHCI_PORT_WAITING) @@ -158,21 +158,21 @@ void fhci_port_reset(void *lld) fhci_stop_sof_timer(fhci); /* disable the USB controller */ - mode = in_8(&fhci->regs->usb_mod); - out_8(&fhci->regs->usb_mod, mode & (~USB_MODE_EN)); + mode = in_8(&fhci->regs->usb_usmod); + out_8(&fhci->regs->usb_usmod, mode & (~USB_MODE_EN)); /* disable idle interrupts */ - mask = in_be16(&fhci->regs->usb_mask); - out_be16(&fhci->regs->usb_mask, mask & (~USB_E_IDLE_MASK)); + mask = in_be16(&fhci->regs->usb_usbmr); + out_be16(&fhci->regs->usb_usbmr, mask & (~USB_E_IDLE_MASK)); fhci_io_port_generate_reset(fhci); /* enable interrupt on this endpoint */ - out_be16(&fhci->regs->usb_mask, mask); + out_be16(&fhci->regs->usb_usbmr, mask); /* enable the USB controller */ - mode = in_8(&fhci->regs->usb_mod); - out_8(&fhci->regs->usb_mod, mode | USB_MODE_EN); + mode = in_8(&fhci->regs->usb_usmod); + out_8(&fhci->regs->usb_usmod, mode | USB_MODE_EN); fhci_start_sof_timer(fhci); fhci_dbg(fhci, "<- %s\n", __func__); diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 2df851b4bc7c..2dc8a40e39d7 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -132,8 +132,8 @@ void fhci_flush_all_transmissions(struct fhci_usb *usb) u8 mode; struct td *td; - mode = in_8(&usb->fhci->regs->usb_mod); - clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN); + mode = in_8(&usb->fhci->regs->usb_usmod); + clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_EN); fhci_flush_bds(usb); @@ -147,9 +147,9 @@ void fhci_flush_all_transmissions(struct fhci_usb *usb) usb->actual_frame->frame_status = FRAME_END_TRANSMISSION; /* reset the event register */ - out_be16(&usb->fhci->regs->usb_event, 0xffff); + out_be16(&usb->fhci->regs->usb_usber, 0xffff); /* enable the USB controller */ - out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN); + out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN); } /* @@ -414,7 +414,7 @@ static void sof_interrupt(struct fhci_hcd *fhci) usb->port_status = FHCI_PORT_FULL; /* Disable IDLE */ usb->saved_msk &= ~USB_E_IDLE_MASK; - out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); + out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk); } gtm_set_exact_timer16(fhci->timer, usb->max_frame_usage, false); @@ -433,14 +433,14 @@ void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci) fhci_dbg(fhci, "-> %s\n", __func__); fhci_usb_disable_interrupt(usb); - clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS); + clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_LSS); usb->port_status = FHCI_PORT_DISABLED; fhci_stop_sof_timer(fhci); /* Enable IDLE since we want to know if something comes along */ usb->saved_msk |= USB_E_IDLE_MASK; - out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); + out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk); usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_CONNECTION; usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_CONNECTION; @@ -473,7 +473,7 @@ void fhci_device_connected_interrupt(struct fhci_hcd *fhci) } usb->port_status = FHCI_PORT_LOW; - setbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS); + setbits8(&usb->fhci->regs->usb_usmod, USB_MODE_LSS); usb->vroot_hub->port.wPortStatus |= (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_CONNECTION); @@ -491,7 +491,7 @@ void fhci_device_connected_interrupt(struct fhci_hcd *fhci) } usb->port_status = FHCI_PORT_FULL; - clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS); + clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_LSS); usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED; usb->vroot_hub->port.wPortStatus |= @@ -535,7 +535,7 @@ static void abort_transmission(struct fhci_usb *usb) /* issue stop Tx command */ qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0); /* flush Tx FIFOs */ - out_8(&usb->fhci->regs->usb_comm, USB_CMD_FLUSH_FIFO | EP_ZERO); + out_8(&usb->fhci->regs->usb_uscom, USB_CMD_FLUSH_FIFO | EP_ZERO); udelay(1000); /* reset Tx BDs */ fhci_flush_bds(usb); @@ -555,11 +555,11 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) usb = fhci->usb_lld; - usb_er |= in_be16(&usb->fhci->regs->usb_event) & - in_be16(&usb->fhci->regs->usb_mask); + usb_er |= in_be16(&usb->fhci->regs->usb_usber) & + in_be16(&usb->fhci->regs->usb_usbmr); /* clear event bits for next time */ - out_be16(&usb->fhci->regs->usb_event, usb_er); + out_be16(&usb->fhci->regs->usb_usber, usb_er); fhci_dbg_isr(fhci, usb_er); @@ -573,7 +573,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) /* Turn on IDLE since we want to disconnect */ usb->saved_msk |= USB_E_IDLE_MASK; - out_be16(&usb->fhci->regs->usb_event, + out_be16(&usb->fhci->regs->usb_usber, usb->saved_msk); } else if (usb->port_status == FHCI_PORT_DISABLED) { if (fhci_ioports_check_bus_state(fhci) == 1) @@ -611,7 +611,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) /* XXX usb->port_status = FHCI_PORT_WAITING; */ /* Disable IDLE */ usb->saved_msk &= ~USB_E_IDLE_MASK; - out_be16(&usb->fhci->regs->usb_mask, + out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk); } else { fhci_dbg_isr(fhci, -1); diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index c5ed88199292..1498061f0aea 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -249,7 +249,7 @@ void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep, u8 rt; /* set the endpoint registers according to the endpoint */ - out_be16(&usb->fhci->regs->usb_ep[0], + out_be16(&usb->fhci->regs->usb_usep[0], USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE); out_be16(&usb->fhci->pram->ep_ptr[0], cpm_muram_offset(ep->ep_pram_ptr)); @@ -463,7 +463,7 @@ u32 fhci_host_transaction(struct fhci_usb *usb, cq_put(&ep->conf_frame_Q, pkt); if (cq_howmany(&ep->conf_frame_Q) == 1) - out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); + out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO); return 0; } @@ -535,8 +535,8 @@ void fhci_flush_actual_frame(struct fhci_usb *usb) struct endpoint *ep = usb->ep0; /* disable the USB controller */ - mode = in_8(&usb->fhci->regs->usb_mod); - out_8(&usb->fhci->regs->usb_mod, mode & ~USB_MODE_EN); + mode = in_8(&usb->fhci->regs->usb_usmod); + out_8(&usb->fhci->regs->usb_usmod, mode & ~USB_MODE_EN); tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr); td = cpm_muram_addr(tb_ptr); @@ -571,9 +571,9 @@ void fhci_flush_actual_frame(struct fhci_usb *usb) usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION; /* reset the event register */ - out_be16(&usb->fhci->regs->usb_event, 0xffff); + out_be16(&usb->fhci->regs->usb_usber, 0xffff); /* enable the USB controller */ - out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN); + out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN); } /* handles Tx confirm and Tx error interrupt */ @@ -613,7 +613,7 @@ void fhci_host_transmit_actual_frame(struct fhci_usb *usb) /* start transmit only if we have something in the TDs */ if (in_be16(&td->status) & TD_R) - out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); + out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO); if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) { out_be32(&old_td->buf_ptr, 0); diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index dc6939a44a1a..7cc1c32dc36c 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -28,6 +28,7 @@ #include #include #include +#include #define USB_CLOCK 48000000 @@ -173,25 +174,6 @@ #define USB_E_TXB_MASK 0x0002 #define USB_E_RXB_MASK 0x0001 -/* Freescale USB Host controller registers */ -struct fhci_regs { - u8 usb_mod; /* mode register */ - u8 usb_addr; /* address register */ - u8 usb_comm; /* command register */ - u8 reserved1[1]; - __be16 usb_ep[4]; /* endpoint register */ - u8 reserved2[4]; - __be16 usb_event; /* event register */ - u8 reserved3[2]; - __be16 usb_mask; /* mask register */ - u8 reserved4[1]; - u8 usb_status; /* status register */ - __be16 usb_sof_tmr; /* Start Of Frame timer */ - u8 reserved5[2]; - __be16 usb_frame_num; /* frame number register */ - u8 reserved6[1]; -}; - /* Freescale USB HOST */ struct fhci_pram { __be16 ep_ptr[4]; /* Endpoint porter reg */ @@ -267,7 +249,7 @@ struct fhci_hcd { int gpios[NUM_GPIOS]; bool alow_gpios[NUM_GPIOS]; - struct fhci_regs __iomem *regs; /* I/O memory used to communicate */ + struct qe_usb_ctlr __iomem *regs; /* I/O memory used to communicate */ struct fhci_pram __iomem *pram; /* Parameter RAM */ struct gtm_timer *timer; -- GitLab From a46af4ebf9ffec35eea0390e89935197b833dc61 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 25 Jun 2012 12:19:03 -0400 Subject: [PATCH 2938/6849] USB: EHCI: define extension registers like normal ones This patch (as1562) cleans up the definitions of the EHCI extended registers to be consistent with the definitions of the standard registers. This makes the code look a lot nicer, with no functional change. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 15 +++++---------- drivers/usb/host/ehci-hub.c | 26 ++++++++------------------ include/linux/usb/ehci_def.h | 28 +++++++++++++++++++++------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 800be38c78b4..c49fc1e7895d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -203,11 +203,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, /* check TDI/ARC silicon is in host mode */ static int tdi_in_host_mode (struct ehci_hcd *ehci) { - u32 __iomem *reg_ptr; u32 tmp; - reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE); - tmp = ehci_readl(ehci, reg_ptr); + tmp = ehci_readl(ehci, &ehci->regs->usbmode); return (tmp & 3) == USBMODE_CM_HC; } @@ -303,11 +301,9 @@ static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, /* put TDI/ARC silicon into EHCI mode */ static void tdi_reset (struct ehci_hcd *ehci) { - u32 __iomem *reg_ptr; u32 tmp; - reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE); - tmp = ehci_readl(ehci, reg_ptr); + tmp = ehci_readl(ehci, &ehci->regs->usbmode); tmp |= USBMODE_CM_HC; /* The default byte access to MMR space is LE after * controller reset. Set the required endian mode @@ -315,7 +311,7 @@ static void tdi_reset (struct ehci_hcd *ehci) */ if (ehci_big_endian_mmio(ehci)) tmp |= USBMODE_BE; - ehci_writel(ehci, tmp, reg_ptr); + ehci_writel(ehci, tmp, &ehci->regs->usbmode); } /* reset a non-running (STS_HALT == 1) controller */ @@ -339,9 +335,8 @@ static int ehci_reset (struct ehci_hcd *ehci) if (ehci->has_hostpc) { ehci_writel(ehci, USBMODE_EX_HC | USBMODE_EX_VBPS, - (u32 __iomem *)(((u8 *)ehci->regs) + USBMODE_EX)); - ehci_writel(ehci, TXFIFO_DEFAULT, - (u32 __iomem *)(((u8 *)ehci->regs) + TXFILLTUNING)); + &ehci->regs->usbmode_ex); + ehci_writel(ehci, TXFIFO_DEFAULT, &ehci->regs->txfill_tuning); } if (retval) return retval; diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index dd5eef6af6df..db05e358677a 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -149,10 +149,8 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, if (ehci->has_hostpc) { port = HCS_N_PORTS(ehci->hcs_params); while (port--) { - u32 __iomem *hostpc_reg; + u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; - hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs - + HOSTPC0 + 4 * port); temp = ehci_readl(ehci, hostpc_reg); ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg); } @@ -185,10 +183,8 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, if (ehci->has_hostpc) { port = HCS_N_PORTS(ehci->hcs_params); while (port--) { - u32 __iomem *hostpc_reg; + u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; - hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs - + HOSTPC0 + 4 * port); temp = ehci_readl(ehci, hostpc_reg); ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg); } @@ -285,11 +281,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) port = HCS_N_PORTS(ehci->hcs_params); while (port--) { - u32 __iomem *hostpc_reg; + u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; u32 t3; - hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs - + HOSTPC0 + 4 * port); t3 = ehci_readl(ehci, hostpc_reg); ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); t3 = ehci_readl(ehci, hostpc_reg); @@ -388,10 +382,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd) i = HCS_N_PORTS(ehci->hcs_params); while (i--) { if (test_bit(i, &ehci->bus_suspended)) { - u32 __iomem *hostpc_reg; + u32 __iomem *hostpc_reg = + &ehci->regs->hostpc[i]; - hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs - + HOSTPC0 + 4 * i); temp = ehci_readl(ehci, hostpc_reg); ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg); @@ -667,7 +660,7 @@ static int ehci_hub_control ( int ports = HCS_N_PORTS (ehci->hcs_params); u32 __iomem *status_reg = &ehci->regs->port_status[ (wIndex & 0xff) - 1]; - u32 __iomem *hostpc_reg = NULL; + u32 __iomem *hostpc_reg = &ehci->regs->hostpc[(wIndex & 0xff) - 1]; u32 temp, temp1, status; unsigned long flags; int retval = 0; @@ -680,9 +673,6 @@ static int ehci_hub_control ( * power, "this is the one", etc. EHCI spec supports this. */ - if (ehci->has_hostpc) - hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs - + HOSTPC0 + 4 * ((wIndex & 0xff) - 1)); spin_lock_irqsave (&ehci->lock, flags); switch (typeReq) { case ClearHubFeature: @@ -734,7 +724,7 @@ static int ehci_hub_control ( goto error; /* clear phy low-power mode before resume */ - if (hostpc_reg) { + if (ehci->has_hostpc) { temp1 = ehci_readl(ehci, hostpc_reg); ehci_writel(ehci, temp1 & ~HOSTPC_PHCD, hostpc_reg); @@ -984,7 +974,7 @@ static int ehci_hub_control ( temp &= ~PORT_WKCONN_E; temp |= PORT_WKDISC_E | PORT_WKOC_E; ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); - if (hostpc_reg) { + if (ehci->has_hostpc) { spin_unlock_irqrestore(&ehci->lock, flags); msleep(5);/* 5ms for HCD enter low pwr mode */ spin_lock_irqsave(&ehci->lock, flags); diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h index 7cc95ee3606b..de4b9ed5d5dd 100644 --- a/include/linux/usb/ehci_def.h +++ b/include/linux/usb/ehci_def.h @@ -111,7 +111,13 @@ struct ehci_regs { /* ASYNCLISTADDR: offset 0x18 */ u32 async_next; /* address of next async queue head */ - u32 reserved[9]; + u32 reserved1[2]; + + /* TXFILLTUNING: offset 0x24 */ + u32 txfill_tuning; /* TX FIFO Tuning register */ +#define TXFIFO_DEFAULT (8<<16) /* FIFO burst threshold 8 */ + + u32 reserved2[6]; /* CONFIGFLAG: offset 0x40 */ u32 configured_flag; @@ -155,26 +161,34 @@ struct ehci_regs { #define PORT_CSC (1<<1) /* connect status change */ #define PORT_CONNECT (1<<0) /* device connected */ #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) -}; -#define USBMODE 0x68 /* USB Device mode */ + u32 reserved3[9]; + + /* USBMODE: offset 0x68 */ + u32 usbmode; /* USB Device mode */ #define USBMODE_SDIS (1<<3) /* Stream disable */ #define USBMODE_BE (1<<2) /* BE/LE endianness select */ #define USBMODE_CM_HC (3<<0) /* host controller mode */ #define USBMODE_CM_IDLE (0<<0) /* idle state */ + u32 reserved4[7]; + /* Moorestown has some non-standard registers, partially due to the fact that * its EHCI controller has both TT and LPM support. HOSTPCx are extensions to * PORTSCx */ -#define HOSTPC0 0x84 /* HOSTPC extension */ + /* HOSTPC: offset 0x84 */ + u32 hostpc[0]; /* HOSTPC extension */ #define HOSTPC_PHCD (1<<22) /* Phy clock disable */ #define HOSTPC_PSPD (3<<25) /* Port speed detection */ -#define USBMODE_EX 0xc8 /* USB Device mode extension */ + + u32 reserved5[17]; + + /* USBMODE_EX: offset 0xc8 */ + u32 usbmode_ex; /* USB Device mode extension */ #define USBMODE_EX_VBPS (1<<5) /* VBus Power Select On */ #define USBMODE_EX_HC (3<<0) /* host controller mode */ -#define TXFILLTUNING 0x24 /* TX FIFO Tuning register */ -#define TXFIFO_DEFAULT (8<<16) /* FIFO burst threshold 8 */ +}; /* Appendix C, Debug port ... intended for use with special "debug devices" * that can help if there's no serial console. (nonstandard enumeration.) -- GitLab From 984e97483a143f95d861b7218161ae033df293ab Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Thu, 21 Jun 2012 03:44:31 -0700 Subject: [PATCH 2939/6849] ARM: OMAP: USB: Fixup ehci_hcd_omap_probe error path A recent commit, [PATCH] Fix OMAP EHCI suspend/resume failure (i693) '354ab856' causes ehci probe to fail on omap3xxx. This exposed bugs in the ehci_hcd_omap_probe error path causing an oops. On the error path, call usb_remove_hcd if usb_add_hcd has been called, and call usb_put_hcd if usb_alloc_hcd has been called. Tested on BB-xM. Signed-off-by: Russ.Dill@ti.com Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 17cfb8a1131c..6e15fc87cf60 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -347,7 +347,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) { dev_err(dev, "failed to add hcd with err %d\n", ret); - goto err_add_hcd; + goto err_pm_runtime; } /* root ports should always stay powered */ @@ -424,8 +424,12 @@ err_utmi_p1_fck: clk_put(utmi_p1_fck); err_add_hcd: + usb_remove_hcd(hcd); + +err_pm_runtime: disable_put_regulator(pdata); pm_runtime_put_sync(dev); + usb_put_hcd(hcd); err_io: iounmap(regs); -- GitLab From afd6bb387323154ff6554b52d333ec6efb8efe61 Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Thu, 21 Jun 2012 03:44:32 -0700 Subject: [PATCH 2940/6849] Fix OMAP EHCI suspend/resume failure (i693) '354ab856' causes an oops on boot for all omap3xxx platforms that use usbhs_omap for EHCI. The actual oops comes from faulty ehci-omap cleanup, but the failure caused by the change is evidenced here: [ 3.655059] ehci-omap ehci-omap.0: utmi_p1_gfclk failed error:-2 [ 3.661376] ehci-omap: probe of ehci-omap.0 failed with error -2 utmi_p1_gfclk is a clock that exists on OMAP4, but not OMAP3. In the OMAP3 case, it is configured as a dummy clock. However, OMAP4 lists the dev_id as NULL, but OMAP3 lists it as "usbhs_omap". Attempting to get that clock from ehci-omap then fails. The solution is to just change the clock3xxx_data.c for dummy clocks used in the errata fix to match the dev_id, NULL, used in clock44xx_data.c. Tested on BB-xM. Signed-off-by: Russ Dill Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/clock3xxx_data.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 1efdec236ae8..d5c0cba6a340 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3391,15 +3391,15 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), - CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), - CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), - CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), - CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), - CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), + CLK(NULL, "utmi_p1_gfclk", &dummy_ck, CK_3XXX), + CLK(NULL, "utmi_p2_gfclk", &dummy_ck, CK_3XXX), + CLK(NULL, "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), + CLK(NULL, "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), + CLK(NULL, "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), + CLK(NULL, "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), - CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX), + CLK(NULL, "init_60m_fclk", &dummy_ck, CK_3XXX), CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), -- GitLab From 571efa0d3ba8ef6ad857259bfa194e9b2ee403ad Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 29 May 2012 15:26:40 +0530 Subject: [PATCH 2941/6849] ARM: OMAP3+: clock: Move common clksel_rate & clock data to common file OMAP3, OMAP4 and AM33xx share some common data like, clksel_rate oscillator clock input (Virtual clock nodes), required for clock tree; so move common data to common data file so that it can be reused. [hvaibhav@ti.com: Created separate commit from Paul's developement branch] Signed-off-by: Vaibhav Hiremath Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clock.h | 12 ++++ arch/arm/mach-omap2/clock3xxx_data.c | 20 ++----- arch/arm/mach-omap2/clock44xx_data.c | 72 ----------------------- arch/arm/mach-omap2/clock_common_data.c | 77 +++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 88 deletions(-) diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index a1bb23a23351..980b0a436c29 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -155,4 +155,16 @@ extern const struct clkops clkops_omap3_noncore_dpll_ops; extern const struct clkops clkops_omap3_core_dpll_ops; extern const struct clkops clkops_omap4_dpllmx_ops; +/* clksel_rate blocks shared between OMAP44xx and AM33xx */ +extern const struct clksel_rate div_1_0_rates[]; +extern const struct clksel_rate div_1_1_rates[]; +extern const struct clksel_rate div_1_2_rates[]; +extern const struct clksel_rate div_1_3_rates[]; +extern const struct clksel_rate div_1_4_rates[]; +extern const struct clksel_rate div31_1to31_rates[]; + +/* clocks shared between various OMAP SoCs */ +extern struct clk virt_19200000_ck; +extern struct clk virt_26000000_ck; + #endif diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 4e1a3b0e8cc8..9d7ef6c13745 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -93,18 +93,6 @@ static struct clk virt_16_8m_ck = { .rate = 16800000, }; -static struct clk virt_19_2m_ck = { - .name = "virt_19_2m_ck", - .ops = &clkops_null, - .rate = 19200000, -}; - -static struct clk virt_26m_ck = { - .name = "virt_26m_ck", - .ops = &clkops_null, - .rate = 26000000, -}; - static struct clk virt_38_4m_ck = { .name = "virt_38_4m_ck", .ops = &clkops_null, @@ -145,8 +133,8 @@ static const struct clksel osc_sys_clksel[] = { { .parent = &virt_12m_ck, .rates = osc_sys_12m_rates }, { .parent = &virt_13m_ck, .rates = osc_sys_13m_rates }, { .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates }, - { .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates }, - { .parent = &virt_26m_ck, .rates = osc_sys_26m_rates }, + { .parent = &virt_19200000_ck, .rates = osc_sys_19_2m_rates }, + { .parent = &virt_26000000_ck, .rates = osc_sys_26m_rates }, { .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates }, { .parent = NULL }, }; @@ -3230,8 +3218,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_3XXX), CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_3XXX), CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_3XXX), - CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_3XXX), + CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_3XXX), + CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_3XXX), CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX), CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_3XXX), CLK(NULL, "sys_ck", &sys_ck, CK_3XXX), diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 2172f6603848..66c2e2701f0c 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -106,18 +106,6 @@ static struct clk virt_16800000_ck = { .rate = 16800000, }; -static struct clk virt_19200000_ck = { - .name = "virt_19200000_ck", - .ops = &clkops_null, - .rate = 19200000, -}; - -static struct clk virt_26000000_ck = { - .name = "virt_26000000_ck", - .ops = &clkops_null, - .rate = 26000000, -}; - static struct clk virt_27000000_ck = { .name = "virt_27000000_ck", .ops = &clkops_null, @@ -130,31 +118,6 @@ static struct clk virt_38400000_ck = { .rate = 38400000, }; -static const struct clksel_rate div_1_0_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_4430 }, - { .div = 0 }, -}; - -static const struct clksel_rate div_1_1_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_4430 }, - { .div = 0 }, -}; - -static const struct clksel_rate div_1_2_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_4430 }, - { .div = 0 }, -}; - -static const struct clksel_rate div_1_3_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_4430 }, - { .div = 0 }, -}; - -static const struct clksel_rate div_1_4_rates[] = { - { .div = 1, .val = 4, .flags = RATE_IN_4430 }, - { .div = 0 }, -}; - static const struct clksel_rate div_1_5_rates[] = { { .div = 1, .val = 5, .flags = RATE_IN_4430 }, { .div = 0 }, @@ -288,41 +251,6 @@ static struct clk dpll_abe_x2_ck = { .recalc = &omap3_clkoutx2_recalc, }; -static const struct clksel_rate div31_1to31_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_4430 }, - { .div = 2, .val = 2, .flags = RATE_IN_4430 }, - { .div = 3, .val = 3, .flags = RATE_IN_4430 }, - { .div = 4, .val = 4, .flags = RATE_IN_4430 }, - { .div = 5, .val = 5, .flags = RATE_IN_4430 }, - { .div = 6, .val = 6, .flags = RATE_IN_4430 }, - { .div = 7, .val = 7, .flags = RATE_IN_4430 }, - { .div = 8, .val = 8, .flags = RATE_IN_4430 }, - { .div = 9, .val = 9, .flags = RATE_IN_4430 }, - { .div = 10, .val = 10, .flags = RATE_IN_4430 }, - { .div = 11, .val = 11, .flags = RATE_IN_4430 }, - { .div = 12, .val = 12, .flags = RATE_IN_4430 }, - { .div = 13, .val = 13, .flags = RATE_IN_4430 }, - { .div = 14, .val = 14, .flags = RATE_IN_4430 }, - { .div = 15, .val = 15, .flags = RATE_IN_4430 }, - { .div = 16, .val = 16, .flags = RATE_IN_4430 }, - { .div = 17, .val = 17, .flags = RATE_IN_4430 }, - { .div = 18, .val = 18, .flags = RATE_IN_4430 }, - { .div = 19, .val = 19, .flags = RATE_IN_4430 }, - { .div = 20, .val = 20, .flags = RATE_IN_4430 }, - { .div = 21, .val = 21, .flags = RATE_IN_4430 }, - { .div = 22, .val = 22, .flags = RATE_IN_4430 }, - { .div = 23, .val = 23, .flags = RATE_IN_4430 }, - { .div = 24, .val = 24, .flags = RATE_IN_4430 }, - { .div = 25, .val = 25, .flags = RATE_IN_4430 }, - { .div = 26, .val = 26, .flags = RATE_IN_4430 }, - { .div = 27, .val = 27, .flags = RATE_IN_4430 }, - { .div = 28, .val = 28, .flags = RATE_IN_4430 }, - { .div = 29, .val = 29, .flags = RATE_IN_4430 }, - { .div = 30, .val = 30, .flags = RATE_IN_4430 }, - { .div = 31, .val = 31, .flags = RATE_IN_4430 }, - { .div = 0 }, -}; - static const struct clksel dpll_abe_m2x2_div[] = { { .parent = &dpll_abe_x2_ck, .rates = div31_1to31_rates }, { .parent = NULL }, diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c index 6424d46be14a..b9f3ba68148c 100644 --- a/arch/arm/mach-omap2/clock_common_data.c +++ b/arch/arm/mach-omap2/clock_common_data.c @@ -43,3 +43,80 @@ const struct clksel_rate dsp_ick_rates[] = { { .div = 3, .val = 3, .flags = RATE_IN_243X }, { .div = 0 }, }; + + +/* clksel_rate blocks shared between OMAP44xx and AM33xx */ + +const struct clksel_rate div_1_0_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_1_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_2_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_3_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_4_rates[] = { + { .div = 1, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div31_1to31_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 2, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 3, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 4, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 5, .val = 5, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 6, .val = 6, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 7, .val = 7, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 8, .val = 8, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 9, .val = 9, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 10, .val = 10, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 11, .val = 11, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 12, .val = 12, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 13, .val = 13, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 14, .val = 14, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 15, .val = 15, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 16, .val = 16, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 17, .val = 17, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 18, .val = 18, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 19, .val = 19, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 20, .val = 20, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 21, .val = 21, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 22, .val = 22, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 23, .val = 23, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 24, .val = 24, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 25, .val = 25, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 26, .val = 26, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 27, .val = 27, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 28, .val = 28, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 29, .val = 29, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 30, .val = 30, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +/* Clocks shared between various OMAP SoCs */ + +struct clk virt_19200000_ck = { + .name = "virt_19200000_ck", + .ops = &clkops_null, + .rate = 19200000, +}; + +struct clk virt_26000000_ck = { + .name = "virt_26000000_ck", + .ops = &clkops_null, + .rate = 26000000, +}; -- GitLab From 32bad7e30f113a8a5cebe4704bf6519ab4383e1b Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:48 +0000 Subject: [PATCH 2942/6849] mac802154: add wpan device-class support Every real 802.15.4 transceiver, which works with software MAC layer, can be classified as a wpan device in this stack. So the wpan device implementation provides missing link in datapath between the device drivers and the Linux network queue. According to the IEEE 802.15.4 standard each packet can be one of the following types: - beacon - MAC layer command - ACK - data This patch adds support for the data packet-type only, but this is enough to perform data transmission and receiving over radio. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- include/linux/nl802154.h | 14 +- include/net/mac802154.h | 8 + net/mac802154/Makefile | 2 +- net/mac802154/ieee802154_dev.c | 4 + net/mac802154/mac802154.h | 4 + net/mac802154/mac_cmd.c | 4 + net/mac802154/rx.c | 1 + net/mac802154/wpan.c | 559 +++++++++++++++++++++++++++++++++ 8 files changed, 583 insertions(+), 13 deletions(-) create mode 100644 net/mac802154/wpan.c diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 5a3db3aa5f17..fd4f2d1cdf6c 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h @@ -130,18 +130,8 @@ enum { enum { __IEEE802154_DEV_INVALID = -1, - /* TODO: - * Nowadays three device types supported by this stack at linux-zigbee - * project: WPAN = 0, MONITOR = 1 and SMAC = 2. - * - * Since this stack implementation exists many years, it's definitely - * bad idea to change the assigned values due to they are already used - * by third-party userspace software like: iz-tools, wireshark... - * - * Currently only monitor device is added and initialized by '1' for - * compatibility. - */ - IEEE802154_DEV_MONITOR = 1, + IEEE802154_DEV_WPAN, + IEEE802154_DEV_MONITOR, __IEEE802154_DEV_MAX, }; diff --git a/include/net/mac802154.h b/include/net/mac802154.h index c9f8ab5cc687..d0d11df9cba1 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -21,6 +21,14 @@ #include +/* General MAC frame format: + * 2 bytes: Frame Control + * 1 byte: Sequence Number + * 20 bytes: Addressing fields + * 14 bytes: Auxiliary Security Header + */ +#define MAC802154_FRAME_HARD_HEADER_LEN (2 + 1 + 20 + 14) + /* The following flags are used to indicate changed address settings from * the stack to the hardware. */ diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index ec1bd3fc1273..57cf5d1a2e4a 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MAC802154) += mac802154.o -mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o monitor.o +mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o monitor.o wpan.o diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index e3edfb0661b0..e748aed290aa 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -140,6 +140,10 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), name, mac802154_monitor_setup); break; + case IEEE802154_DEV_WPAN: + dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + name, mac802154_wpan_setup); + break; default: dev = NULL; err = -EINVAL; diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index 789d9c948aec..c0efcf19a171 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -93,6 +93,7 @@ struct mac802154_sub_if_data { #define MAC802154_CHAN_NONE (~(u8)0) /* No channel is assigned */ extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; +extern struct ieee802154_mlme_ops mac802154_mlme_wpan; int mac802154_slave_open(struct net_device *dev); int mac802154_slave_close(struct net_device *dev); @@ -100,6 +101,9 @@ int mac802154_slave_close(struct net_device *dev); void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); +void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_wpan_setup(struct net_device *dev); + netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, u8 page, u8 chan); diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 7a5d0e052cd7..db8341957bd2 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -43,3 +43,7 @@ struct wpan_phy *mac802154_get_phy(const struct net_device *dev) struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = { .get_phy = mac802154_get_phy, }; + +struct ieee802154_mlme_ops mac802154_mlme_wpan = { + .get_phy = mac802154_get_phy, +}; diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 4a7d76d4f8bc..38548ec2098f 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -77,6 +77,7 @@ mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) } mac802154_monitors_rx(priv, skb); + mac802154_wpans_rx(priv, skb); out: dev_kfree_skb(skb); return; diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c new file mode 100644 index 000000000000..f30f6d4beea1 --- /dev/null +++ b/net/mac802154/wpan.c @@ -0,0 +1,559 @@ +/* + * Copyright 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov + * Sergey Lapin + * Maxim Gorbachyov + * Alexander Smirnov + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mac802154.h" + +static inline int mac802154_fetch_skb_u8(struct sk_buff *skb, u8 *val) +{ + if (unlikely(!pskb_may_pull(skb, 1))) + return -EINVAL; + + *val = skb->data[0]; + skb_pull(skb, 1); + + return 0; +} + +static inline int mac802154_fetch_skb_u16(struct sk_buff *skb, u16 *val) +{ + if (unlikely(!pskb_may_pull(skb, 2))) + return -EINVAL; + + *val = skb->data[0] | (skb->data[1] << 8); + skb_pull(skb, 2); + + return 0; +} + +static inline void mac802154_haddr_copy_swap(u8 *dest, const u8 *src) +{ + int i; + for (i = 0; i < IEEE802154_ADDR_LEN; i++) + dest[IEEE802154_ADDR_LEN - i - 1] = src[i]; +} + +static int +mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct sockaddr_ieee802154 *sa = + (struct sockaddr_ieee802154 *)&ifr->ifr_addr; + int err = -ENOIOCTLCMD; + + spin_lock_bh(&priv->mib_lock); + + switch (cmd) { + case SIOCGIFADDR: + if (priv->pan_id == IEEE802154_PANID_BROADCAST || + priv->short_addr == IEEE802154_ADDR_BROADCAST) { + err = -EADDRNOTAVAIL; + break; + } + + sa->family = AF_IEEE802154; + sa->addr.addr_type = IEEE802154_ADDR_SHORT; + sa->addr.pan_id = priv->pan_id; + sa->addr.short_addr = priv->short_addr; + + err = 0; + break; + case SIOCSIFADDR: + dev_warn(&dev->dev, + "Using DEBUGing ioctl SIOCSIFADDR isn't recommened!\n"); + if (sa->family != AF_IEEE802154 || + sa->addr.addr_type != IEEE802154_ADDR_SHORT || + sa->addr.pan_id == IEEE802154_PANID_BROADCAST || + sa->addr.short_addr == IEEE802154_ADDR_BROADCAST || + sa->addr.short_addr == IEEE802154_ADDR_UNDEF) { + err = -EINVAL; + break; + } + + priv->pan_id = sa->addr.pan_id; + priv->short_addr = sa->addr.short_addr; + + err = 0; + break; + } + + spin_unlock_bh(&priv->mib_lock); + return err; +} + +static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + if (netif_running(dev)) + return -EBUSY; + + /* FIXME: validate addr */ + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + mac802154_dev_set_ieee_addr(dev); + return 0; +} + +static int mac802154_header_create(struct sk_buff *skb, + struct net_device *dev, + unsigned short type, + const void *_daddr, + const void *_saddr, + unsigned len) +{ + const struct ieee802154_addr *saddr = _saddr; + const struct ieee802154_addr *daddr = _daddr; + struct ieee802154_addr dev_addr; + struct mac802154_sub_if_data *priv = netdev_priv(dev); + int pos = 2; + u8 *head; + u16 fc; + + if (!daddr) + return -EINVAL; + + head = kzalloc(MAC802154_FRAME_HARD_HEADER_LEN, GFP_KERNEL); + if (head == NULL) + return -ENOMEM; + + head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */ + fc = mac_cb_type(skb); + + if (!saddr) { + spin_lock_bh(&priv->mib_lock); + + if (priv->short_addr == IEEE802154_ADDR_BROADCAST || + priv->short_addr == IEEE802154_ADDR_UNDEF || + priv->pan_id == IEEE802154_PANID_BROADCAST) { + dev_addr.addr_type = IEEE802154_ADDR_LONG; + memcpy(dev_addr.hwaddr, dev->dev_addr, + IEEE802154_ADDR_LEN); + } else { + dev_addr.addr_type = IEEE802154_ADDR_SHORT; + dev_addr.short_addr = priv->short_addr; + } + + dev_addr.pan_id = priv->pan_id; + saddr = &dev_addr; + + spin_unlock_bh(&priv->mib_lock); + } + + if (daddr->addr_type != IEEE802154_ADDR_NONE) { + fc |= (daddr->addr_type << IEEE802154_FC_DAMODE_SHIFT); + + head[pos++] = daddr->pan_id & 0xff; + head[pos++] = daddr->pan_id >> 8; + + if (daddr->addr_type == IEEE802154_ADDR_SHORT) { + head[pos++] = daddr->short_addr & 0xff; + head[pos++] = daddr->short_addr >> 8; + } else { + mac802154_haddr_copy_swap(head + pos, daddr->hwaddr); + pos += IEEE802154_ADDR_LEN; + } + } + + if (saddr->addr_type != IEEE802154_ADDR_NONE) { + fc |= (saddr->addr_type << IEEE802154_FC_SAMODE_SHIFT); + + if ((saddr->pan_id == daddr->pan_id) && + (saddr->pan_id != IEEE802154_PANID_BROADCAST)) { + /* PANID compression/intra PAN */ + fc |= IEEE802154_FC_INTRA_PAN; + } else { + head[pos++] = saddr->pan_id & 0xff; + head[pos++] = saddr->pan_id >> 8; + } + + if (saddr->addr_type == IEEE802154_ADDR_SHORT) { + head[pos++] = saddr->short_addr & 0xff; + head[pos++] = saddr->short_addr >> 8; + } else { + mac802154_haddr_copy_swap(head + pos, saddr->hwaddr); + pos += IEEE802154_ADDR_LEN; + } + } + + head[0] = fc; + head[1] = fc >> 8; + + memcpy(skb_push(skb, pos), head, pos); + kfree(head); + + return pos; +} + +static int +mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{ + const u8 *hdr = skb_mac_header(skb); + const u8 *tail = skb_tail_pointer(skb); + struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr; + u16 fc; + int da_type; + + if (hdr + 3 > tail) + goto malformed; + + fc = hdr[0] | (hdr[1] << 8); + + hdr += 3; + + da_type = IEEE802154_FC_DAMODE(fc); + addr->addr_type = IEEE802154_FC_SAMODE(fc); + + switch (da_type) { + case IEEE802154_ADDR_NONE: + if (fc & IEEE802154_FC_INTRA_PAN) + goto malformed; + break; + case IEEE802154_ADDR_LONG: + if (fc & IEEE802154_FC_INTRA_PAN) { + if (hdr + 2 > tail) + goto malformed; + addr->pan_id = hdr[0] | (hdr[1] << 8); + hdr += 2; + } + + if (hdr + IEEE802154_ADDR_LEN > tail) + goto malformed; + + hdr += IEEE802154_ADDR_LEN; + break; + case IEEE802154_ADDR_SHORT: + if (fc & IEEE802154_FC_INTRA_PAN) { + if (hdr + 2 > tail) + goto malformed; + addr->pan_id = hdr[0] | (hdr[1] << 8); + hdr += 2; + } + + if (hdr + 2 > tail) + goto malformed; + + hdr += 2; + break; + default: + goto malformed; + + } + + switch (addr->addr_type) { + case IEEE802154_ADDR_NONE: + break; + case IEEE802154_ADDR_LONG: + if (!(fc & IEEE802154_FC_INTRA_PAN)) { + if (hdr + 2 > tail) + goto malformed; + addr->pan_id = hdr[0] | (hdr[1] << 8); + hdr += 2; + } + + if (hdr + IEEE802154_ADDR_LEN > tail) + goto malformed; + + mac802154_haddr_copy_swap(addr->hwaddr, hdr); + hdr += IEEE802154_ADDR_LEN; + break; + case IEEE802154_ADDR_SHORT: + if (!(fc & IEEE802154_FC_INTRA_PAN)) { + if (hdr + 2 > tail) + goto malformed; + addr->pan_id = hdr[0] | (hdr[1] << 8); + hdr += 2; + } + + if (hdr + 2 > tail) + goto malformed; + + addr->short_addr = hdr[0] | (hdr[1] << 8); + hdr += 2; + break; + default: + goto malformed; + } + + return sizeof(struct ieee802154_addr); + +malformed: + pr_debug("malformed packet\n"); + return 0; +} + +static netdev_tx_t +mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + u8 chan, page; + + priv = netdev_priv(dev); + + spin_lock_bh(&priv->mib_lock); + chan = priv->chan; + page = priv->page; + spin_unlock_bh(&priv->mib_lock); + + if (chan == MAC802154_CHAN_NONE || + page >= WPAN_NUM_PAGES || + chan >= WPAN_NUM_CHANNELS) + return NETDEV_TX_OK; + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(priv->hw, skb, page, chan); +} + +static struct header_ops mac802154_header_ops = { + .create = mac802154_header_create, + .parse = mac802154_header_parse, +}; + +static const struct net_device_ops mac802154_wpan_ops = { + .ndo_open = mac802154_slave_open, + .ndo_stop = mac802154_slave_close, + .ndo_start_xmit = mac802154_wpan_xmit, + .ndo_do_ioctl = mac802154_wpan_ioctl, + .ndo_set_mac_address = mac802154_wpan_mac_addr, +}; + +void mac802154_wpan_setup(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + + dev->addr_len = IEEE802154_ADDR_LEN; + memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); + + dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; + dev->header_ops = &mac802154_header_ops; + dev->needed_tailroom = 2; /* FCS */ + dev->mtu = IEEE802154_MTU; + dev->tx_queue_len = 10; + dev->type = ARPHRD_IEEE802154; + dev->flags = IFF_NOARP | IFF_BROADCAST; + dev->watchdog_timeo = 0; + + dev->destructor = free_netdev; + dev->netdev_ops = &mac802154_wpan_ops; + dev->ml_priv = &mac802154_mlme_wpan; + + priv = netdev_priv(dev); + priv->type = IEEE802154_DEV_WPAN; + + priv->chan = MAC802154_CHAN_NONE; + priv->page = 0; + + spin_lock_init(&priv->mib_lock); + + get_random_bytes(&priv->bsn, 1); + get_random_bytes(&priv->dsn, 1); + + priv->pan_id = IEEE802154_PANID_BROADCAST; + priv->short_addr = IEEE802154_ADDR_BROADCAST; +} + +static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) +{ + return netif_rx(skb); +} + +static int +mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb) +{ + pr_debug("getting packet via slave interface %s\n", sdata->dev->name); + + spin_lock_bh(&sdata->mib_lock); + + switch (mac_cb(skb)->da.addr_type) { + case IEEE802154_ADDR_NONE: + if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_NONE) + /* FIXME: check if we are PAN coordinator */ + skb->pkt_type = PACKET_OTHERHOST; + else + /* ACK comes with both addresses empty */ + skb->pkt_type = PACKET_HOST; + break; + case IEEE802154_ADDR_LONG: + if (mac_cb(skb)->da.pan_id != sdata->pan_id && + mac_cb(skb)->da.pan_id != IEEE802154_PANID_BROADCAST) + skb->pkt_type = PACKET_OTHERHOST; + else if (!memcmp(mac_cb(skb)->da.hwaddr, sdata->dev->dev_addr, + IEEE802154_ADDR_LEN)) + skb->pkt_type = PACKET_HOST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + case IEEE802154_ADDR_SHORT: + if (mac_cb(skb)->da.pan_id != sdata->pan_id && + mac_cb(skb)->da.pan_id != IEEE802154_PANID_BROADCAST) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->da.short_addr == sdata->short_addr) + skb->pkt_type = PACKET_HOST; + else if (mac_cb(skb)->da.short_addr == + IEEE802154_ADDR_BROADCAST) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + default: + break; + } + + spin_unlock_bh(&sdata->mib_lock); + + skb->dev = sdata->dev; + + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; + + switch (mac_cb_type(skb)) { + case IEEE802154_FC_TYPE_DATA: + return mac802154_process_data(sdata->dev, skb); + default: + pr_warning("ieee802154: bad frame received (type = %d)\n", + mac_cb_type(skb)); + kfree_skb(skb); + return NET_RX_DROP; + } +} + +static int mac802154_parse_frame_start(struct sk_buff *skb) +{ + u8 *head = skb->data; + u16 fc; + + if (mac802154_fetch_skb_u16(skb, &fc) || + mac802154_fetch_skb_u8(skb, &(mac_cb(skb)->seq))) + goto err; + + pr_debug("fc: %04x dsn: %02x\n", fc, head[2]); + + mac_cb(skb)->flags = IEEE802154_FC_TYPE(fc); + mac_cb(skb)->sa.addr_type = IEEE802154_FC_SAMODE(fc); + mac_cb(skb)->da.addr_type = IEEE802154_FC_DAMODE(fc); + + if (fc & IEEE802154_FC_INTRA_PAN) + mac_cb(skb)->flags |= MAC_CB_FLAG_INTRAPAN; + + if (mac_cb(skb)->da.addr_type != IEEE802154_ADDR_NONE) { + if (mac802154_fetch_skb_u16(skb, &(mac_cb(skb)->da.pan_id))) + goto err; + + /* source PAN id compression */ + if (mac_cb_is_intrapan(skb)) + mac_cb(skb)->sa.pan_id = mac_cb(skb)->da.pan_id; + + pr_debug("dest PAN addr: %04x\n", mac_cb(skb)->da.pan_id); + + if (mac_cb(skb)->da.addr_type == IEEE802154_ADDR_SHORT) { + u16 *da = &(mac_cb(skb)->da.short_addr); + + if (mac802154_fetch_skb_u16(skb, da)) + goto err; + + pr_debug("destination address is short: %04x\n", + mac_cb(skb)->da.short_addr); + } else { + if (!pskb_may_pull(skb, IEEE802154_ADDR_LEN)) + goto err; + + mac802154_haddr_copy_swap(mac_cb(skb)->da.hwaddr, + skb->data); + skb_pull(skb, IEEE802154_ADDR_LEN); + + pr_debug("destination address is hardware\n"); + } + } + + if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_NONE) { + /* non PAN-compression, fetch source address id */ + if (!(mac_cb_is_intrapan(skb))) { + u16 *sa_pan = &(mac_cb(skb)->sa.pan_id); + + if (mac802154_fetch_skb_u16(skb, sa_pan)) + goto err; + } + + pr_debug("source PAN addr: %04x\n", mac_cb(skb)->da.pan_id); + + if (mac_cb(skb)->sa.addr_type == IEEE802154_ADDR_SHORT) { + u16 *sa = &(mac_cb(skb)->sa.short_addr); + + if (mac802154_fetch_skb_u16(skb, sa)) + goto err; + + pr_debug("source address is short: %04x\n", + mac_cb(skb)->sa.short_addr); + } else { + if (!pskb_may_pull(skb, IEEE802154_ADDR_LEN)) + goto err; + + mac802154_haddr_copy_swap(mac_cb(skb)->sa.hwaddr, + skb->data); + skb_pull(skb, IEEE802154_ADDR_LEN); + + pr_debug("source address is hardware\n"); + } + } + + return 0; +err: + return -EINVAL; +} + +void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) +{ + int ret; + struct sk_buff *sskb; + struct mac802154_sub_if_data *sdata; + + ret = mac802154_parse_frame_start(skb); + if (ret) { + pr_debug("got invalid frame\n"); + return; + } + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &priv->slaves, list) { + if (sdata->type != IEEE802154_DEV_WPAN) + continue; + + sskb = skb_clone(skb, GFP_ATOMIC); + if (sskb) + mac802154_subif_frame(sdata, sskb); + } + rcu_read_unlock(); +} -- GitLab From dcbe4f93f6d220c22c937f4e305171119b87905e Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:49 +0000 Subject: [PATCH 2943/6849] mac802154: set and get PAN id Two methods intended to get and set the Private Area Network identifier were added to the MIB implementation. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/mac802154/mac802154.h | 2 ++ net/mac802154/mib.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index c0efcf19a171..5cb7dc286cd1 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -109,5 +109,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, /* MIB callbacks */ void mac802154_dev_set_ieee_addr(struct net_device *dev); +u16 mac802154_dev_get_pan_id(const struct net_device *dev); +void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); #endif /* MAC802154_H */ diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index ab59821ec729..8e772ed30d1c 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -91,3 +91,34 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev) set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); } } + +u16 mac802154_dev_get_pan_id(const struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + u16 ret; + + BUG_ON(dev->type != ARPHRD_IEEE802154); + + spin_lock_bh(&priv->mib_lock); + ret = priv->pan_id; + spin_unlock_bh(&priv->mib_lock); + + return ret; +} + +void mac802154_dev_set_pan_id(struct net_device *dev, u16 val) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + BUG_ON(dev->type != ARPHRD_IEEE802154); + + spin_lock_bh(&priv->mib_lock); + priv->pan_id = val; + spin_unlock_bh(&priv->mib_lock); + + if ((priv->hw->ops->set_hw_addr_filt) && + (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { + priv->hw->hw.hw_filt.pan_id = priv->pan_id; + set_hw_addr_filt(dev, IEEE802515_AFILT_PANID_CHANGED); + } +} -- GitLab From 48e44d5057144b4e28615e3e1ce725b2ca887b40 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:50 +0000 Subject: [PATCH 2944/6849] mac802154: short address setter A method to assign the IEEE802.15.4 short address was added to the MIB implementation. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/mac802154/mac802154.h | 1 + net/mac802154/mib.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index 5cb7dc286cd1..995107203ddc 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -108,6 +108,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, u8 page, u8 chan); /* MIB callbacks */ +void mac802154_dev_set_short_addr(struct net_device *dev, u16 val); void mac802154_dev_set_ieee_addr(struct net_device *dev); u16 mac802154_dev_get_pan_id(const struct net_device *dev); void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 8e772ed30d1c..d74503b4302f 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -78,6 +78,23 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) return; } +void mac802154_dev_set_short_addr(struct net_device *dev, u16 val) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + BUG_ON(dev->type != ARPHRD_IEEE802154); + + spin_lock_bh(&priv->mib_lock); + priv->short_addr = val; + spin_unlock_bh(&priv->mib_lock); + + if ((priv->hw->ops->set_hw_addr_filt) && + (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { + priv->hw->hw.hw_filt.short_addr = priv->short_addr; + set_hw_addr_filt(dev, IEEE802515_AFILT_SADDR_CHANGED); + } +} + void mac802154_dev_set_ieee_addr(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); -- GitLab From 66b69d4d7fe3026a4add368b72905b4d7878c320 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:51 +0000 Subject: [PATCH 2945/6849] mac802154: page and channel setter A new method to set page and channel values for a transceiver was added to the MIB. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/mac802154/mac802154.h | 1 + net/mac802154/mib.c | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index 995107203ddc..69678644a5c2 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -112,5 +112,6 @@ void mac802154_dev_set_short_addr(struct net_device *dev, u16 val); void mac802154_dev_set_ieee_addr(struct net_device *dev); u16 mac802154_dev_get_pan_id(const struct net_device *dev); void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); +void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); #endif /* MAC802154_H */ diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index d74503b4302f..380829d84600 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -28,6 +28,11 @@ #include "mac802154.h" +struct phy_chan_notify_work { + struct work_struct work; + struct net_device *dev; +}; + struct hw_addr_filt_notify_work { struct work_struct work; struct net_device *dev; @@ -139,3 +144,42 @@ void mac802154_dev_set_pan_id(struct net_device *dev, u16 val) set_hw_addr_filt(dev, IEEE802515_AFILT_PANID_CHANGED); } } + +static void phy_chan_notify(struct work_struct *work) +{ + struct phy_chan_notify_work *nw = container_of(work, + struct phy_chan_notify_work, work); + struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); + struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); + int res; + + res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan); + if (res) + pr_debug("set_channel failed\n"); + + kfree(nw); +} + +void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct phy_chan_notify_work *work; + + BUG_ON(dev->type != ARPHRD_IEEE802154); + + spin_lock_bh(&priv->mib_lock); + priv->page = page; + priv->chan = chan; + spin_unlock_bh(&priv->mib_lock); + + if (priv->hw->phy->current_channel != priv->chan || + priv->hw->phy->current_page != priv->page) { + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (!work) + return; + + INIT_WORK(&work->work, phy_chan_notify); + work->dev = dev; + queue_work(priv->hw->dev_workqueue, &work->work); + } +} -- GitLab From 5265f46711ca4e6c389519a00e97036ddb892781 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:52 +0000 Subject: [PATCH 2946/6849] mac802154: mlme start request Basic preparations to start the interface. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/mac802154/mac_cmd.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index db8341957bd2..7f5403e5ea91 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -25,12 +25,36 @@ #include #include +#include #include #include #include +#include #include "mac802154.h" +static int mac802154_mlme_start_req(struct net_device *dev, + struct ieee802154_addr *addr, + u8 channel, u8 page, + u8 bcn_ord, u8 sf_ord, + u8 pan_coord, u8 blx, + u8 coord_realign) +{ + BUG_ON(addr->addr_type != IEEE802154_ADDR_SHORT); + + mac802154_dev_set_pan_id(dev, addr->pan_id); + mac802154_dev_set_short_addr(dev, addr->short_addr); + mac802154_dev_set_ieee_addr(dev); + mac802154_dev_set_page_channel(dev, page, channel); + + /* FIXME: add validation for unused parameters to be sane + * for SoftMAC + */ + ieee802154_nl_start_confirm(dev, IEEE802154_SUCCESS); + + return 0; +} + struct wpan_phy *mac802154_get_phy(const struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); @@ -46,4 +70,5 @@ struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = { struct ieee802154_mlme_ops mac802154_mlme_wpan = { .get_phy = mac802154_get_phy, + .start_req = mac802154_mlme_start_req, }; -- GitLab From 7b8e19b67c1b171a04f6bd2f973d0b38cb496bf6 Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:53 +0000 Subject: [PATCH 2947/6849] drivers/ieee802154: add support for the at86rf230/231 transceivers The AT86RF231 is a feature rich, low-power 2.4 GHz radio transceiver designed for industrial and consumer ZigBee/IEEE 802.15.4, 6LoWPAN, RF4CE and high data rate 2.4 GHz ISM band applications. This patch adds support for the Atmel RF230/231 radio transceivers. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- drivers/ieee802154/Kconfig | 6 + drivers/ieee802154/Makefile | 1 + drivers/ieee802154/at86rf230.c | 965 +++++++++++++++++++++++++++++++++ include/linux/spi/at86rf230.h | 31 ++ 4 files changed, 1003 insertions(+) create mode 100644 drivers/ieee802154/at86rf230.c create mode 100644 include/linux/spi/at86rf230.h diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index 15c064073701..1fc4eefc20ed 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -19,6 +19,7 @@ config IEEE802154_FAKEHARD This driver can also be built as a module. To do so say M here. The module will be called 'fakehard'. + config IEEE802154_FAKELB depends on IEEE802154_DRIVERS && MAC802154 tristate "IEEE 802.15.4 loopback driver" @@ -28,3 +29,8 @@ config IEEE802154_FAKELB This driver can also be built as a module. To do so say M here. The module will be called 'fakelb'. + +config IEEE802154_AT86RF230 + depends on IEEE802154_DRIVERS && MAC802154 + tristate "AT86RF230/231 transceiver driver" + depends on SPI diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile index ea784ea6f0f8..4f4371d3aa7d 100644 --- a/drivers/ieee802154/Makefile +++ b/drivers/ieee802154/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o +obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o diff --git a/drivers/ieee802154/at86rf230.c b/drivers/ieee802154/at86rf230.c new file mode 100644 index 000000000000..4d033d4c4ddc --- /dev/null +++ b/drivers/ieee802154/at86rf230.c @@ -0,0 +1,965 @@ +/* + * AT86RF230/RF231 driver + * + * Copyright (C) 2009-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov + * Alexander Smirnov + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct at86rf230_local { + struct spi_device *spi; + int rstn, slp_tr, dig2; + + u8 part; + u8 vers; + + u8 buf[2]; + struct mutex bmux; + + struct work_struct irqwork; + struct completion tx_complete; + + struct ieee802154_dev *dev; + + spinlock_t lock; + bool irq_disabled; + bool is_tx; +}; + +#define RG_TRX_STATUS (0x01) +#define SR_TRX_STATUS 0x01, 0x1f, 0 +#define SR_RESERVED_01_3 0x01, 0x20, 5 +#define SR_CCA_STATUS 0x01, 0x40, 6 +#define SR_CCA_DONE 0x01, 0x80, 7 +#define RG_TRX_STATE (0x02) +#define SR_TRX_CMD 0x02, 0x1f, 0 +#define SR_TRAC_STATUS 0x02, 0xe0, 5 +#define RG_TRX_CTRL_0 (0x03) +#define SR_CLKM_CTRL 0x03, 0x07, 0 +#define SR_CLKM_SHA_SEL 0x03, 0x08, 3 +#define SR_PAD_IO_CLKM 0x03, 0x30, 4 +#define SR_PAD_IO 0x03, 0xc0, 6 +#define RG_TRX_CTRL_1 (0x04) +#define SR_IRQ_POLARITY 0x04, 0x01, 0 +#define SR_IRQ_MASK_MODE 0x04, 0x02, 1 +#define SR_SPI_CMD_MODE 0x04, 0x0c, 2 +#define SR_RX_BL_CTRL 0x04, 0x10, 4 +#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5 +#define SR_IRQ_2_EXT_EN 0x04, 0x40, 6 +#define SR_PA_EXT_EN 0x04, 0x80, 7 +#define RG_PHY_TX_PWR (0x05) +#define SR_TX_PWR 0x05, 0x0f, 0 +#define SR_PA_LT 0x05, 0x30, 4 +#define SR_PA_BUF_LT 0x05, 0xc0, 6 +#define RG_PHY_RSSI (0x06) +#define SR_RSSI 0x06, 0x1f, 0 +#define SR_RND_VALUE 0x06, 0x60, 5 +#define SR_RX_CRC_VALID 0x06, 0x80, 7 +#define RG_PHY_ED_LEVEL (0x07) +#define SR_ED_LEVEL 0x07, 0xff, 0 +#define RG_PHY_CC_CCA (0x08) +#define SR_CHANNEL 0x08, 0x1f, 0 +#define SR_CCA_MODE 0x08, 0x60, 5 +#define SR_CCA_REQUEST 0x08, 0x80, 7 +#define RG_CCA_THRES (0x09) +#define SR_CCA_ED_THRES 0x09, 0x0f, 0 +#define SR_RESERVED_09_1 0x09, 0xf0, 4 +#define RG_RX_CTRL (0x0a) +#define SR_PDT_THRES 0x0a, 0x0f, 0 +#define SR_RESERVED_0a_1 0x0a, 0xf0, 4 +#define RG_SFD_VALUE (0x0b) +#define SR_SFD_VALUE 0x0b, 0xff, 0 +#define RG_TRX_CTRL_2 (0x0c) +#define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0 +#define SR_RESERVED_0c_2 0x0c, 0x7c, 2 +#define SR_RX_SAFE_MODE 0x0c, 0x80, 7 +#define RG_ANT_DIV (0x0d) +#define SR_ANT_CTRL 0x0d, 0x03, 0 +#define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2 +#define SR_ANT_DIV_EN 0x0d, 0x08, 3 +#define SR_RESERVED_0d_2 0x0d, 0x70, 4 +#define SR_ANT_SEL 0x0d, 0x80, 7 +#define RG_IRQ_MASK (0x0e) +#define SR_IRQ_MASK 0x0e, 0xff, 0 +#define RG_IRQ_STATUS (0x0f) +#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 +#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 +#define SR_IRQ_2_RX_START 0x0f, 0x04, 2 +#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 +#define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4 +#define SR_IRQ_5_AMI 0x0f, 0x20, 5 +#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 +#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 +#define RG_VREG_CTRL (0x10) +#define SR_RESERVED_10_6 0x10, 0x03, 0 +#define SR_DVDD_OK 0x10, 0x04, 2 +#define SR_DVREG_EXT 0x10, 0x08, 3 +#define SR_RESERVED_10_3 0x10, 0x30, 4 +#define SR_AVDD_OK 0x10, 0x40, 6 +#define SR_AVREG_EXT 0x10, 0x80, 7 +#define RG_BATMON (0x11) +#define SR_BATMON_VTH 0x11, 0x0f, 0 +#define SR_BATMON_HR 0x11, 0x10, 4 +#define SR_BATMON_OK 0x11, 0x20, 5 +#define SR_RESERVED_11_1 0x11, 0xc0, 6 +#define RG_XOSC_CTRL (0x12) +#define SR_XTAL_TRIM 0x12, 0x0f, 0 +#define SR_XTAL_MODE 0x12, 0xf0, 4 +#define RG_RX_SYN (0x15) +#define SR_RX_PDT_LEVEL 0x15, 0x0f, 0 +#define SR_RESERVED_15_2 0x15, 0x70, 4 +#define SR_RX_PDT_DIS 0x15, 0x80, 7 +#define RG_XAH_CTRL_1 (0x17) +#define SR_RESERVED_17_8 0x17, 0x01, 0 +#define SR_AACK_PROM_MODE 0x17, 0x02, 1 +#define SR_AACK_ACK_TIME 0x17, 0x04, 2 +#define SR_RESERVED_17_5 0x17, 0x08, 3 +#define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4 +#define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5 +#define SR_RESERVED_17_2 0x17, 0x40, 6 +#define SR_RESERVED_17_1 0x17, 0x80, 7 +#define RG_FTN_CTRL (0x18) +#define SR_RESERVED_18_2 0x18, 0x7f, 0 +#define SR_FTN_START 0x18, 0x80, 7 +#define RG_PLL_CF (0x1a) +#define SR_RESERVED_1a_2 0x1a, 0x7f, 0 +#define SR_PLL_CF_START 0x1a, 0x80, 7 +#define RG_PLL_DCU (0x1b) +#define SR_RESERVED_1b_3 0x1b, 0x3f, 0 +#define SR_RESERVED_1b_2 0x1b, 0x40, 6 +#define SR_PLL_DCU_START 0x1b, 0x80, 7 +#define RG_PART_NUM (0x1c) +#define SR_PART_NUM 0x1c, 0xff, 0 +#define RG_VERSION_NUM (0x1d) +#define SR_VERSION_NUM 0x1d, 0xff, 0 +#define RG_MAN_ID_0 (0x1e) +#define SR_MAN_ID_0 0x1e, 0xff, 0 +#define RG_MAN_ID_1 (0x1f) +#define SR_MAN_ID_1 0x1f, 0xff, 0 +#define RG_SHORT_ADDR_0 (0x20) +#define SR_SHORT_ADDR_0 0x20, 0xff, 0 +#define RG_SHORT_ADDR_1 (0x21) +#define SR_SHORT_ADDR_1 0x21, 0xff, 0 +#define RG_PAN_ID_0 (0x22) +#define SR_PAN_ID_0 0x22, 0xff, 0 +#define RG_PAN_ID_1 (0x23) +#define SR_PAN_ID_1 0x23, 0xff, 0 +#define RG_IEEE_ADDR_0 (0x24) +#define SR_IEEE_ADDR_0 0x24, 0xff, 0 +#define RG_IEEE_ADDR_1 (0x25) +#define SR_IEEE_ADDR_1 0x25, 0xff, 0 +#define RG_IEEE_ADDR_2 (0x26) +#define SR_IEEE_ADDR_2 0x26, 0xff, 0 +#define RG_IEEE_ADDR_3 (0x27) +#define SR_IEEE_ADDR_3 0x27, 0xff, 0 +#define RG_IEEE_ADDR_4 (0x28) +#define SR_IEEE_ADDR_4 0x28, 0xff, 0 +#define RG_IEEE_ADDR_5 (0x29) +#define SR_IEEE_ADDR_5 0x29, 0xff, 0 +#define RG_IEEE_ADDR_6 (0x2a) +#define SR_IEEE_ADDR_6 0x2a, 0xff, 0 +#define RG_IEEE_ADDR_7 (0x2b) +#define SR_IEEE_ADDR_7 0x2b, 0xff, 0 +#define RG_XAH_CTRL_0 (0x2c) +#define SR_SLOTTED_OPERATION 0x2c, 0x01, 0 +#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 +#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 +#define RG_CSMA_SEED_0 (0x2d) +#define SR_CSMA_SEED_0 0x2d, 0xff, 0 +#define RG_CSMA_SEED_1 (0x2e) +#define SR_CSMA_SEED_1 0x2e, 0x07, 0 +#define SR_AACK_I_AM_COORD 0x2e, 0x08, 3 +#define SR_AACK_DIS_ACK 0x2e, 0x10, 4 +#define SR_AACK_SET_PD 0x2e, 0x20, 5 +#define SR_AACK_FVN_MODE 0x2e, 0xc0, 6 +#define RG_CSMA_BE (0x2f) +#define SR_MIN_BE 0x2f, 0x0f, 0 +#define SR_MAX_BE 0x2f, 0xf0, 4 + +#define CMD_REG 0x80 +#define CMD_REG_MASK 0x3f +#define CMD_WRITE 0x40 +#define CMD_FB 0x20 + +#define IRQ_BAT_LOW (1 << 7) +#define IRQ_TRX_UR (1 << 6) +#define IRQ_AMI (1 << 5) +#define IRQ_CCA_ED (1 << 4) +#define IRQ_TRX_END (1 << 3) +#define IRQ_RX_START (1 << 2) +#define IRQ_PLL_UNL (1 << 1) +#define IRQ_PLL_LOCK (1 << 0) + +#define STATE_P_ON 0x00 /* BUSY */ +#define STATE_BUSY_RX 0x01 +#define STATE_BUSY_TX 0x02 +#define STATE_FORCE_TRX_OFF 0x03 +#define STATE_FORCE_TX_ON 0x04 /* IDLE */ +/* 0x05 */ /* INVALID_PARAMETER */ +#define STATE_RX_ON 0x06 +/* 0x07 */ /* SUCCESS */ +#define STATE_TRX_OFF 0x08 +#define STATE_TX_ON 0x09 +/* 0x0a - 0x0e */ /* 0x0a - UNSUPPORTED_ATTRIBUTE */ +#define STATE_SLEEP 0x0F +#define STATE_BUSY_RX_AACK 0x11 +#define STATE_BUSY_TX_ARET 0x12 +#define STATE_BUSY_RX_AACK_ON 0x16 +#define STATE_BUSY_TX_ARET_ON 0x19 +#define STATE_RX_ON_NOCLK 0x1C +#define STATE_RX_AACK_ON_NOCLK 0x1D +#define STATE_BUSY_RX_AACK_NOCLK 0x1E +#define STATE_TRANSITION_IN_PROGRESS 0x1F + +static int +__at86rf230_write(struct at86rf230_local *lp, u8 addr, u8 data) +{ + u8 *buf = lp->buf; + int status; + struct spi_message msg; + struct spi_transfer xfer = { + .len = 2, + .tx_buf = buf, + }; + + buf[0] = (addr & CMD_REG_MASK) | CMD_REG | CMD_WRITE; + buf[1] = data; + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + status = spi_sync(lp->spi, &msg); + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + if (msg.status) + status = msg.status; + + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); + + return status; +} + +static int +__at86rf230_read_subreg(struct at86rf230_local *lp, + u8 addr, u8 mask, int shift, u8 *data) +{ + u8 *buf = lp->buf; + int status; + struct spi_message msg; + struct spi_transfer xfer = { + .len = 2, + .tx_buf = buf, + .rx_buf = buf, + }; + + buf[0] = (addr & CMD_REG_MASK) | CMD_REG; + buf[1] = 0xff; + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + status = spi_sync(lp->spi, &msg); + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + if (msg.status) + status = msg.status; + + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); + + if (status == 0) + *data = buf[1]; + + return status; +} + +static int +at86rf230_read_subreg(struct at86rf230_local *lp, + u8 addr, u8 mask, int shift, u8 *data) +{ + int status; + + mutex_lock(&lp->bmux); + status = __at86rf230_read_subreg(lp, addr, mask, shift, data); + mutex_unlock(&lp->bmux); + + return status; +} + +static int +at86rf230_write_subreg(struct at86rf230_local *lp, + u8 addr, u8 mask, int shift, u8 data) +{ + int status; + u8 val; + + mutex_lock(&lp->bmux); + status = __at86rf230_read_subreg(lp, addr, 0xff, 0, &val); + if (status) + goto out; + + val &= ~mask; + val |= (data << shift) & mask; + + status = __at86rf230_write(lp, addr, val); +out: + mutex_unlock(&lp->bmux); + + return status; +} + +static int +at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len) +{ + u8 *buf = lp->buf; + int status; + struct spi_message msg; + struct spi_transfer xfer_head = { + .len = 2, + .tx_buf = buf, + + }; + struct spi_transfer xfer_buf = { + .len = len, + .tx_buf = data, + }; + + mutex_lock(&lp->bmux); + buf[0] = CMD_WRITE | CMD_FB; + buf[1] = len + 2; /* 2 bytes for CRC that isn't written */ + + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); + + spi_message_init(&msg); + spi_message_add_tail(&xfer_head, &msg); + spi_message_add_tail(&xfer_buf, &msg); + + status = spi_sync(lp->spi, &msg); + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + if (msg.status) + status = msg.status; + + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); + + mutex_unlock(&lp->bmux); + return status; +} + +static int +at86rf230_read_fbuf(struct at86rf230_local *lp, u8 *data, u8 *len, u8 *lqi) +{ + u8 *buf = lp->buf; + int status; + struct spi_message msg; + struct spi_transfer xfer_head = { + .len = 2, + .tx_buf = buf, + .rx_buf = buf, + }; + struct spi_transfer xfer_head1 = { + .len = 2, + .tx_buf = buf, + .rx_buf = buf, + }; + struct spi_transfer xfer_buf = { + .len = 0, + .rx_buf = data, + }; + + mutex_lock(&lp->bmux); + + buf[0] = CMD_FB; + buf[1] = 0x00; + + spi_message_init(&msg); + spi_message_add_tail(&xfer_head, &msg); + + status = spi_sync(lp->spi, &msg); + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + + xfer_buf.len = *(buf + 1) + 1; + *len = buf[1]; + + buf[0] = CMD_FB; + buf[1] = 0x00; + + spi_message_init(&msg); + spi_message_add_tail(&xfer_head1, &msg); + spi_message_add_tail(&xfer_buf, &msg); + + status = spi_sync(lp->spi, &msg); + + if (msg.status) + status = msg.status; + + dev_vdbg(&lp->spi->dev, "status = %d\n", status); + dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]); + dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); + + if (status) { + if (lqi && (*len > lp->buf[1])) + *lqi = data[lp->buf[1]]; + } + mutex_unlock(&lp->bmux); + + return status; +} + +static int +at86rf230_ed(struct ieee802154_dev *dev, u8 *level) +{ + might_sleep(); + BUG_ON(!level); + *level = 0xbe; + return 0; +} + +static int +at86rf230_state(struct ieee802154_dev *dev, int state) +{ + struct at86rf230_local *lp = dev->priv; + int rc; + u8 val; + u8 desired_status; + + might_sleep(); + + if (state == STATE_FORCE_TX_ON) + desired_status = STATE_TX_ON; + else if (state == STATE_FORCE_TRX_OFF) + desired_status = STATE_TRX_OFF; + else + desired_status = state; + + do { + rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val); + if (rc) + goto err; + } while (val == STATE_TRANSITION_IN_PROGRESS); + + if (val == desired_status) + return 0; + + /* state is equal to phy states */ + rc = at86rf230_write_subreg(lp, SR_TRX_CMD, state); + if (rc) + goto err; + + do { + rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val); + if (rc) + goto err; + } while (val == STATE_TRANSITION_IN_PROGRESS); + + + if (val == desired_status) + return 0; + + pr_err("unexpected state change: %d, asked for %d\n", val, state); + return -EBUSY; + +err: + pr_err("error: %d\n", rc); + return rc; +} + +static int +at86rf230_start(struct ieee802154_dev *dev) +{ + struct at86rf230_local *lp = dev->priv; + u8 rc; + + rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1); + if (rc) + return rc; + + return at86rf230_state(dev, STATE_RX_ON); +} + +static void +at86rf230_stop(struct ieee802154_dev *dev) +{ + at86rf230_state(dev, STATE_FORCE_TRX_OFF); +} + +static int +at86rf230_channel(struct ieee802154_dev *dev, int page, int channel) +{ + struct at86rf230_local *lp = dev->priv; + int rc; + + might_sleep(); + + if (page != 0 || channel < 11 || channel > 26) { + WARN_ON(1); + return -EINVAL; + } + + rc = at86rf230_write_subreg(lp, SR_CHANNEL, channel); + msleep(1); /* Wait for PLL */ + dev->phy->current_channel = channel; + + return 0; +} + +static int +at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) +{ + struct at86rf230_local *lp = dev->priv; + int rc; + unsigned long flags; + + might_sleep(); + + rc = at86rf230_state(dev, STATE_FORCE_TX_ON); + if (rc) + goto err; + + spin_lock_irqsave(&lp->lock, flags); + lp->is_tx = 1; + INIT_COMPLETION(lp->tx_complete); + spin_unlock_irqrestore(&lp->lock, flags); + + rc = at86rf230_write_fbuf(lp, skb->data, skb->len); + if (rc) + goto err_rx; + + rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_BUSY_TX); + if (rc) + goto err_rx; + + rc = wait_for_completion_interruptible(&lp->tx_complete); + if (rc < 0) + goto err_rx; + + rc = at86rf230_start(dev); + + return rc; + +err_rx: + at86rf230_start(dev); +err: + pr_err("error: %d\n", rc); + + spin_lock_irqsave(&lp->lock, flags); + lp->is_tx = 0; + spin_unlock_irqrestore(&lp->lock, flags); + + return rc; +} + +static int at86rf230_rx(struct at86rf230_local *lp) +{ + u8 len = 128, lqi = 0; + int rc; + struct sk_buff *skb; + + skb = alloc_skb(len, GFP_KERNEL); + + if (!skb) + return -ENOMEM; + + if (at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 1) || + at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi) || + at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1) || + at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 0)) { + goto err; + } + + if (len < 2) + goto err; + + skb_trim(skb, len - 2); /* We do not put CRC into the frame */ + + ieee802154_rx_irqsafe(lp->dev, skb, lqi); + + dev_dbg(&lp->spi->dev, "READ_FBUF: %d %d %x\n", rc, len, lqi); + + return 0; +err: + pr_debug("received frame is too small\n"); + + kfree_skb(skb); + return -EINVAL; +} + +static struct ieee802154_ops at86rf230_ops = { + .owner = THIS_MODULE, + .xmit = at86rf230_xmit, + .ed = at86rf230_ed, + .set_channel = at86rf230_channel, + .start = at86rf230_start, + .stop = at86rf230_stop, +}; + +static void at86rf230_irqwork(struct work_struct *work) +{ + struct at86rf230_local *lp = + container_of(work, struct at86rf230_local, irqwork); + u8 status = 0, val; + int rc; + unsigned long flags; + + spin_lock_irqsave(&lp->lock, flags); + rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val); + status |= val; + + status &= ~IRQ_PLL_LOCK; /* ignore */ + status &= ~IRQ_RX_START; /* ignore */ + status &= ~IRQ_AMI; /* ignore */ + status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/ + + if (status & IRQ_TRX_END) { + status &= ~IRQ_TRX_END; + if (lp->is_tx) { + lp->is_tx = 0; + complete(&lp->tx_complete); + } else { + at86rf230_rx(lp); + } + } + + if (lp->irq_disabled) { + lp->irq_disabled = 0; + enable_irq(lp->spi->irq); + } + spin_unlock_irqrestore(&lp->lock, flags); +} + +static irqreturn_t at86rf230_isr(int irq, void *data) +{ + struct at86rf230_local *lp = data; + + spin_lock(&lp->lock); + if (!lp->irq_disabled) { + disable_irq_nosync(irq); + lp->irq_disabled = 1; + } + spin_unlock(&lp->lock); + + schedule_work(&lp->irqwork); + + return IRQ_HANDLED; +} + + +static int at86rf230_hw_init(struct at86rf230_local *lp) +{ + u8 status; + int rc; + + rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status); + if (rc) + return rc; + + dev_info(&lp->spi->dev, "Status: %02x\n", status); + if (status == STATE_P_ON) { + rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TRX_OFF); + if (rc) + return rc; + msleep(1); + rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status); + if (rc) + return rc; + dev_info(&lp->spi->dev, "Status: %02x\n", status); + } + + rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, 0xff); /* IRQ_TRX_UR | + * IRQ_CCA_ED | + * IRQ_TRX_END | + * IRQ_PLL_UNL | + * IRQ_PLL_LOCK + */ + if (rc) + return rc; + + /* CLKM changes are applied immediately */ + rc = at86rf230_write_subreg(lp, SR_CLKM_SHA_SEL, 0x00); + if (rc) + return rc; + + /* Turn CLKM Off */ + rc = at86rf230_write_subreg(lp, SR_CLKM_CTRL, 0x00); + if (rc) + return rc; + /* Wait the next SLEEP cycle */ + msleep(100); + + rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TX_ON); + if (rc) + return rc; + msleep(1); + + rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status); + if (rc) + return rc; + dev_info(&lp->spi->dev, "Status: %02x\n", status); + + rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status); + if (rc) + return rc; + if (!status) { + dev_err(&lp->spi->dev, "DVDD error\n"); + return -EINVAL; + } + + rc = at86rf230_read_subreg(lp, SR_AVDD_OK, &status); + if (rc) + return rc; + if (!status) { + dev_err(&lp->spi->dev, "AVDD error\n"); + return -EINVAL; + } + + return 0; +} + +static int at86rf230_suspend(struct spi_device *spi, pm_message_t message) +{ + return 0; +} + +static int at86rf230_resume(struct spi_device *spi) +{ + return 0; +} + +static int at86rf230_fill_data(struct spi_device *spi) +{ + struct at86rf230_local *lp = spi_get_drvdata(spi); + struct at86rf230_platform_data *pdata = spi->dev.platform_data; + + if (!pdata) { + dev_err(&spi->dev, "no platform_data\n"); + return -EINVAL; + } + + lp->rstn = pdata->rstn; + lp->slp_tr = pdata->slp_tr; + lp->dig2 = pdata->dig2; + + return 0; +} + +static int __devinit at86rf230_probe(struct spi_device *spi) +{ + struct ieee802154_dev *dev; + struct at86rf230_local *lp; + u8 man_id_0, man_id_1; + int rc; + const char *chip; + int supported = 0; + + if (!spi->irq) { + dev_err(&spi->dev, "no IRQ specified\n"); + return -EINVAL; + } + + dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops); + if (!dev) + return -ENOMEM; + + lp = dev->priv; + lp->dev = dev; + + lp->spi = spi; + + dev->priv = lp; + dev->parent = &spi->dev; + dev->extra_tx_headroom = 0; + /* We do support only 2.4 Ghz */ + dev->phy->channels_supported[0] = 0x7FFF800; + dev->flags = IEEE802154_HW_OMIT_CKSUM; + + mutex_init(&lp->bmux); + INIT_WORK(&lp->irqwork, at86rf230_irqwork); + spin_lock_init(&lp->lock); + init_completion(&lp->tx_complete); + + spi_set_drvdata(spi, lp); + + rc = at86rf230_fill_data(spi); + if (rc) + goto err_fill; + + rc = gpio_request(lp->rstn, "rstn"); + if (rc) + goto err_rstn; + + if (gpio_is_valid(lp->slp_tr)) { + rc = gpio_request(lp->slp_tr, "slp_tr"); + if (rc) + goto err_slp_tr; + } + + rc = gpio_direction_output(lp->rstn, 1); + if (rc) + goto err_gpio_dir; + + if (gpio_is_valid(lp->slp_tr)) { + rc = gpio_direction_output(lp->slp_tr, 0); + if (rc) + goto err_gpio_dir; + } + + /* Reset */ + msleep(1); + gpio_set_value(lp->rstn, 0); + msleep(1); + gpio_set_value(lp->rstn, 1); + msleep(1); + + rc = at86rf230_read_subreg(lp, SR_MAN_ID_0, &man_id_0); + if (rc) + goto err_gpio_dir; + rc = at86rf230_read_subreg(lp, SR_MAN_ID_1, &man_id_1); + if (rc) + goto err_gpio_dir; + + if (man_id_1 != 0x00 || man_id_0 != 0x1f) { + dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n", + man_id_1, man_id_0); + rc = -EINVAL; + goto err_gpio_dir; + } + + rc = at86rf230_read_subreg(lp, SR_PART_NUM, &lp->part); + if (rc) + goto err_gpio_dir; + + rc = at86rf230_read_subreg(lp, SR_VERSION_NUM, &lp->vers); + if (rc) + goto err_gpio_dir; + + switch (lp->part) { + case 2: + chip = "at86rf230"; + /* supported = 1; FIXME: should be easy to support; */ + break; + case 3: + chip = "at86rf231"; + supported = 1; + break; + default: + chip = "UNKNOWN"; + break; + } + + dev_info(&spi->dev, "Detected %s chip version %d\n", chip, lp->vers); + if (!supported) { + rc = -ENOTSUPP; + goto err_gpio_dir; + } + + rc = at86rf230_hw_init(lp); + if (rc) + goto err_gpio_dir; + + rc = request_irq(spi->irq, at86rf230_isr, IRQF_SHARED, + dev_name(&spi->dev), lp); + if (rc) + goto err_gpio_dir; + + rc = ieee802154_register_device(lp->dev); + if (rc) + goto err_irq; + + return rc; + + ieee802154_unregister_device(lp->dev); +err_irq: + free_irq(spi->irq, lp); + flush_work(&lp->irqwork); +err_gpio_dir: + if (gpio_is_valid(lp->slp_tr)) + gpio_free(lp->slp_tr); +err_slp_tr: + gpio_free(lp->rstn); +err_rstn: +err_fill: + spi_set_drvdata(spi, NULL); + mutex_destroy(&lp->bmux); + ieee802154_free_device(lp->dev); + return rc; +} + +static int __devexit at86rf230_remove(struct spi_device *spi) +{ + struct at86rf230_local *lp = spi_get_drvdata(spi); + + ieee802154_unregister_device(lp->dev); + + free_irq(spi->irq, lp); + flush_work(&lp->irqwork); + + if (gpio_is_valid(lp->slp_tr)) + gpio_free(lp->slp_tr); + gpio_free(lp->rstn); + + spi_set_drvdata(spi, NULL); + mutex_destroy(&lp->bmux); + ieee802154_free_device(lp->dev); + + dev_dbg(&spi->dev, "unregistered at86rf230\n"); + return 0; +} + +static struct spi_driver at86rf230_driver = { + .driver = { + .name = "at86rf230", + .owner = THIS_MODULE, + }, + .probe = at86rf230_probe, + .remove = __devexit_p(at86rf230_remove), + .suspend = at86rf230_suspend, + .resume = at86rf230_resume, +}; + +static int __init at86rf230_init(void) +{ + return spi_register_driver(&at86rf230_driver); +} +module_init(at86rf230_init); + +static void __exit at86rf230_exit(void) +{ + spi_unregister_driver(&at86rf230_driver); +} +module_exit(at86rf230_exit); + +MODULE_DESCRIPTION("AT86RF230 Transceiver Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h new file mode 100644 index 000000000000..b2b1afbb3202 --- /dev/null +++ b/include/linux/spi/at86rf230.h @@ -0,0 +1,31 @@ +/* + * AT86RF230/RF231 driver + * + * Copyright (C) 2009-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov + */ +#ifndef AT86RF230_H +#define AT86RF230_H + +struct at86rf230_platform_data { + int rstn; + int slp_tr; + int dig2; +}; + +#endif -- GitLab From 72fd5a8b75fb9962295a8c1338e13a4b1536714a Mon Sep 17 00:00:00 2001 From: "alex.bluesman.smirnov@gmail.com" Date: Mon, 25 Jun 2012 23:24:54 +0000 Subject: [PATCH 2948/6849] mac802154: add monitor listener to TX datapath Add monitor receive callback to the TX datapath to catch all the data sent to transceivers. Signed-off-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/mac802154/tx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8781d8f904d9..86891153dcba 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -87,6 +87,8 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, WARN_ON(1); return NETDEV_TX_OK; + mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb); + if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data = skb_put(skb, 2); -- GitLab From 122bb046bcfb8f3d2d94d9f7f6b74da187a740f2 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 26 Jun 2012 06:52:45 +0000 Subject: [PATCH 2949/6849] team: fix team_adjust_ops with regard to enabled ports team_adjust_ops should check for enabled ports, not all ports. This may lead to division by zero. This patch fixes this. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 3a4a74be52d9..6b4cf6eca238 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -508,26 +508,31 @@ static void team_set_no_mode(struct team *team) team->mode = &__team_no_mode; } -static void team_adjust_ops(struct team *team) +static void __team_adjust_ops(struct team *team, int en_port_count) { /* * To avoid checks in rx/tx skb paths, ensure here that non-null and * correct ops are always set. */ - if (list_empty(&team->port_list) || - !team_is_mode_set(team) || !team->mode->ops->transmit) + if (!en_port_count || !team_is_mode_set(team) || + !team->mode->ops->transmit) team->ops.transmit = team_dummy_transmit; else team->ops.transmit = team->mode->ops->transmit; - if (list_empty(&team->port_list) || - !team_is_mode_set(team) || !team->mode->ops->receive) + if (!en_port_count || !team_is_mode_set(team) || + !team->mode->ops->receive) team->ops.receive = team_dummy_receive; else team->ops.receive = team->mode->ops->receive; } +static void team_adjust_ops(struct team *team) +{ + __team_adjust_ops(team, team->en_port_count); +} + /* * We can benefit from the fact that it's ensured no port is present * at the time of mode change. Therefore no packets are in fly so there's no @@ -687,6 +692,7 @@ static void team_port_enable(struct team *team, port->index = team->en_port_count++; hlist_add_head_rcu(&port->hlist, team_port_index_hash(team, port->index)); + team_adjust_ops(team); if (team->ops.port_enabled) team->ops.port_enabled(team, port); } @@ -708,16 +714,20 @@ static void __reconstruct_port_hlist(struct team *team, int rm_index) static void team_port_disable(struct team *team, struct team_port *port) { - int rm_index = port->index; - if (!team_port_enabled(port)) return; if (team->ops.port_disabled) team->ops.port_disabled(team, port); hlist_del_rcu(&port->hlist); - __reconstruct_port_hlist(team, rm_index); - team->en_port_count--; + __reconstruct_port_hlist(team, port->index); port->index = -1; + __team_adjust_ops(team, team->en_port_count - 1); + /* + * Wait until readers see adjusted ops. This ensures that + * readers never see team->en_port_count == 0 + */ + synchronize_rcu(); + team->en_port_count--; } #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ @@ -874,7 +884,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev) port->index = -1; team_port_enable(team, port); list_add_tail_rcu(&port->list, &team->port_list); - team_adjust_ops(team); __team_compute_features(team); __team_port_change_check(port, !!netif_carrier_ok(port_dev)); __team_options_change_check(team); @@ -928,7 +937,6 @@ static int team_port_del(struct team *team, struct net_device *port_dev) __team_port_change_check(port, false); team_port_disable(team, port); list_del_rcu(&port->list); - team_adjust_ops(team); netdev_rx_handler_unregister(port_dev); netdev_set_master(port_dev, NULL); vlan_vids_del_by_dev(port_dev, dev); -- GitLab From 52a4fd77808662a16cd17ad3b0e1ad75e0162d8b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 26 Jun 2012 06:52:46 +0000 Subject: [PATCH 2950/6849] team: do not allow to map disabled ports Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 5 ++--- drivers/net/team/team_mode_loadbalance.c | 3 ++- include/linux/if_team.h | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 6b4cf6eca238..5350eeaa22ce 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -614,8 +614,6 @@ static int team_change_mode(struct team *team, const char *kind) * Rx path frame handler ************************/ -static bool team_port_enabled(struct team_port *port); - /* note: already called with rcu_read_lock */ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb) { @@ -673,10 +671,11 @@ static bool team_port_find(const struct team *team, return false; } -static bool team_port_enabled(struct team_port *port) +bool team_port_enabled(struct team_port *port) { return port->index != -1; } +EXPORT_SYMBOL(team_port_enabled); /* * Enable/disable port by adding to enabled port hashlist and setting diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index c92fa02d6a63..51a4b199c75c 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -359,7 +359,8 @@ static int lb_tx_hash_to_port_mapping_set(struct team *team, unsigned char hash = ctx->info->array_index; list_for_each_entry(port, &team->port_list, list) { - if (ctx->data.u32_val == port->dev->ifindex) { + if (ctx->data.u32_val == port->dev->ifindex && + team_port_enabled(port)) { rcu_assign_pointer(LB_HTPM_PORT_BY_HASH(lb_priv, hash), port); return 0; diff --git a/include/linux/if_team.h b/include/linux/if_team.h index c1938869191f..e636a54e7a71 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -64,6 +64,8 @@ struct team_port { long mode_priv[0]; }; +extern bool team_port_enabled(struct team_port *port); + struct team_mode_ops { int (*init)(struct team *team); void (*exit)(struct team *team); -- GitLab From 4a9fbcc6d606ae7f6a4e65b8a2759f46be8d45c6 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 26 Jun 2012 06:52:47 +0000 Subject: [PATCH 2951/6849] team: remove unused rcu_head field from team_port struct Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/linux/if_team.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/if_team.h b/include/linux/if_team.h index e636a54e7a71..99efd60fa8c9 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -60,7 +60,6 @@ struct team_port { unsigned int mtu; } orig; - struct rcu_head rcu; long mode_priv[0]; }; -- GitLab From d7ffde35e31a81100d2d0d2c4013cbf527bb32ea Mon Sep 17 00:00:00 2001 From: Jens Freimann Date: Tue, 26 Jun 2012 00:59:58 +0000 Subject: [PATCH 2952/6849] vhost: use USER_DS in vhost_worker thread On some architectures address spaces are set up in a way that this is not necessary to work properly but on some others (like s390) it is. Make sure we operate on the user address space to allow copy_xxx_user() from the vhost_worker() thread by setting it explicitly before calling use_mm() and revert it after unuse_mm(). Signed-off-by: Jens Freimann Signed-off-by: Christian Borntraeger Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/vhost/vhost.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94dbd25caa30..112156f68afb 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -191,7 +191,9 @@ static int vhost_worker(void *data) struct vhost_dev *dev = data; struct vhost_work *work = NULL; unsigned uninitialized_var(seq); + mm_segment_t oldfs = get_fs(); + set_fs(USER_DS); use_mm(dev->mm); for (;;) { @@ -229,6 +231,7 @@ static int vhost_worker(void *data) } unuse_mm(dev->mm); + set_fs(oldfs); return 0; } -- GitLab From 149ddd83a92b02c658d6c61f3276eb6500d585e8 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 26 Jun 2012 05:48:45 +0000 Subject: [PATCH 2953/6849] bridge: Assign rtnl_link_ops to bridge devices created via ioctl (v2) This ensures that bridges created with brctl(8) or ioctl(2) directly also carry IFLA_LINKINFO when dumped over netlink. This also allows to create a bridge with ioctl(2) and delete it with RTM_DELLINK. Signed-off-by: Thomas Graf Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 1 + net/bridge/br_netlink.c | 2 +- net/bridge/br_private.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 0a942fbccc9a..e1144e1617be 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -240,6 +240,7 @@ int br_add_bridge(struct net *net, const char *name) return -ENOMEM; dev_net_set(dev, net); + dev->rtnl_link_ops = &br_link_ops; res = register_netdev(dev); if (res) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2080485515f1..fe41260fbf38 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -208,7 +208,7 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) return 0; } -static struct rtnl_link_ops br_link_ops __read_mostly = { +struct rtnl_link_ops br_link_ops __read_mostly = { .kind = "bridge", .priv_size = sizeof(struct net_bridge), .setup = br_dev_setup, diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1a8ad4fb9a6b..a768b2408edf 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -549,6 +549,7 @@ extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr) #endif /* br_netlink.c */ +extern struct rtnl_link_ops br_link_ops; extern int br_netlink_init(void); extern void br_netlink_fini(void); extern void br_ifinfo_notify(int event, struct net_bridge_port *port); -- GitLab From 85c931665d822f1bedd69ecaab09a8ba84643020 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 Jun 2012 05:41:24 +0000 Subject: [PATCH 2954/6849] connector: use nlmsg_put() instead of NLMSG_PUT() macro. The NLMSG_PUT() macro contains a hidden goto which makes the code hard to audit and very error prone. While been there also use the inline function nlmsg_data() instead of the NLMSG_DATA() macro to do explicit type checking. Signed-off-by: Javier Martinez Canillas Signed-off-by: David S. Miller --- drivers/connector/connector.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index dde6a0fad408..34e0e9e4d913 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -101,19 +101,19 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask) if (!skb) return -ENOMEM; - nlh = NLMSG_PUT(skb, 0, msg->seq, NLMSG_DONE, size - sizeof(*nlh)); + nlh = nlmsg_put(skb, 0, msg->seq, NLMSG_DONE, size - sizeof(*nlh), 0); + if (!nlh) { + kfree_skb(skb); + return -EMSGSIZE; + } - data = NLMSG_DATA(nlh); + data = nlmsg_data(nlh); memcpy(data, msg, sizeof(*data) + msg->len); NETLINK_CB(skb).dst_group = group; return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask); - -nlmsg_failure: - kfree_skb(skb); - return -EINVAL; } EXPORT_SYMBOL_GPL(cn_netlink_send); -- GitLab From 8786395c6956ae16cd04cc8c55e0f5fcd45fa939 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:19:02 -0700 Subject: [PATCH 2955/6849] connector: Move cn_test.c away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- Documentation/connector/cn_test.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c index 7764594778d4..adcca0368d60 100644 --- a/Documentation/connector/cn_test.c +++ b/Documentation/connector/cn_test.c @@ -69,9 +69,13 @@ static int cn_test_want_notify(void) return -ENOMEM; } - nlh = NLMSG_PUT(skb, 0, 0x123, NLMSG_DONE, size - sizeof(*nlh)); + nlh = nlmsg_put(skb, 0, 0x123, NLMSG_DONE, size - sizeof(*nlh), 0); + if (!nlh) { + kfree_skb(skb); + return -EMSGSIZE; + } - msg = (struct cn_msg *)NLMSG_DATA(nlh); + msg = nlmsg_data(nlh); memset(msg, 0, size0); @@ -117,11 +121,6 @@ static int cn_test_want_notify(void) pr_info("request was sent: group=0x%x\n", ctl->group); return 0; - -nlmsg_failure: - pr_err("failed to send %u.%u\n", msg->seq, msg->ack); - kfree_skb(skb); - return -EINVAL; } #endif -- GitLab From a8edf8a690817ebfe68aa14c4bc482f62699077f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:20:52 -0700 Subject: [PATCH 2956/6849] gdm72xx: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- drivers/staging/gdm72xx/netlink_k.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 292af0f7f451..d0cb48a932ee 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -127,8 +127,12 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) } seq++; - nlh = NLMSG_PUT(skb, 0, seq, type, len); - memcpy(NLMSG_DATA(nlh), msg, len); + nlh = nlmsg_put(skb, 0, seq, type, len, 0); + if (!nlh) { + kfree_skb(skb); + return -EMSGSIZE; + } + memcpy(nlmsg_data(nlh), msg, len); NETLINK_CB(skb).pid = 0; NETLINK_CB(skb).dst_group = 0; @@ -144,7 +148,5 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) } ret = 0; } - -nlmsg_failure: return ret; } -- GitLab From 62566ca55de3a329ef2569d7e7c9d0a326abede2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:23:42 -0700 Subject: [PATCH 2957/6849] netfilter: ebt_ulog: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Also, free and NULL out skb when nlmsg_put() fails and remove pointless kernel log message. Signed-off-by: David S. Miller --- net/bridge/netfilter/ebt_ulog.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 5449294bdd5e..1bd173218f7b 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -145,19 +145,24 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, if (!ub->skb) { if (!(ub->skb = ulog_alloc_skb(size))) - goto alloc_failure; + goto unlock; } else if (size > skb_tailroom(ub->skb)) { ulog_send(group); if (!(ub->skb = ulog_alloc_skb(size))) - goto alloc_failure; + goto unlock; } - nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, 0, - size - NLMSG_ALIGN(sizeof(*nlh))); + nlh = nlmsg_put(ub->skb, 0, ub->qlen, 0, + size - NLMSG_ALIGN(sizeof(*nlh)), 0); + if (!nlh) { + kfree(ub->skb); + ub->skb = NULL; + goto unlock; + } ub->qlen++; - pm = NLMSG_DATA(nlh); + pm = nlmsg_data(nlh); /* Fill in the ulog data */ pm->version = EBT_ULOG_VERSION; @@ -209,14 +214,6 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, unlock: spin_unlock_bh(lock); - - return; - -nlmsg_failure: - pr_debug("error during NLMSG_PUT. This should " - "not happen, please report to author.\n"); -alloc_failure: - goto unlock; } /* this function is registered with the netfilter core */ -- GitLab From 77ca4ed566cdef855bc63d0f4cf4d034182d5ebd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:25:55 -0700 Subject: [PATCH 2958/6849] decnet: dn_rtmsg: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Also, remove pointless kernel log message. Signed-off-by: David S. Miller --- net/decnet/netfilter/dn_rtmsg.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index e6f886255cde..b8f7f5b8c350 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -42,23 +42,23 @@ static struct sk_buff *dnrmg_build_message(struct sk_buff *rt_skb, int *errp) size = NLMSG_SPACE(rt_skb->len); size += NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg)); skb = alloc_skb(size, GFP_ATOMIC); - if (!skb) - goto nlmsg_failure; + if (!skb) { + *errp = -ENOMEM; + return NULL; + } old_tail = skb->tail; - nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh)); + nlh = nlmsg_put(skb, 0, 0, 0, size - sizeof(*nlh), 0); + if (!nlh) { + kfree_skb(skb); + *errp = -ENOMEM; + return NULL; + } rtm = (struct nf_dn_rtmsg *)NLMSG_DATA(nlh); rtm->nfdn_ifindex = rt_skb->dev->ifindex; ptr = NFDN_RTMSG(rtm); skb_copy_from_linear_data(rt_skb, ptr, rt_skb->len); nlh->nlmsg_len = skb->tail - old_tail; return skb; - -nlmsg_failure: - if (skb) - kfree_skb(skb); - *errp = -ENOMEM; - net_err_ratelimited("dn_rtmsg: error creating netlink message\n"); - return NULL; } static void dnrmg_send_peer(struct sk_buff *skb) -- GitLab From d106352d9f527fe336749ad89de7e07e5af91a68 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:28:54 -0700 Subject: [PATCH 2959/6849] inet_diag: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too, and remove useless casts. Signed-off-by: David S. Miller --- net/ipv4/inet_diag.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 46d1e7199a8c..27640e734cfd 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -87,10 +87,14 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, handler = inet_diag_table[req->sdiag_protocol]; BUG_ON(handler == NULL); - nlh = NLMSG_PUT(skb, pid, seq, unlh->nlmsg_type, sizeof(*r)); + nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 0); + if (!nlh) { + nlmsg_trim(skb, b); + return -EMSGSIZE; + } nlh->nlmsg_flags = nlmsg_flags; - r = NLMSG_DATA(nlh); + r = nlmsg_data(nlh); BUG_ON(sk->sk_state == TCP_TIME_WAIT); if (ext & (1 << (INET_DIAG_MEMINFO - 1))) @@ -186,7 +190,6 @@ out: return skb->len; rtattr_failure: -nlmsg_failure: nlmsg_trim(skb, b); return -EMSGSIZE; } @@ -209,10 +212,15 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, long tmo; struct inet_diag_msg *r; const unsigned char *previous_tail = skb_tail_pointer(skb); - struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq, - unlh->nlmsg_type, sizeof(*r)); + struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, + unlh->nlmsg_type, sizeof(*r), 0); + + if (!nlh) { + nlmsg_trim(skb, previous_tail); + return -EMSGSIZE; + } - r = NLMSG_DATA(nlh); + r = nlmsg_data(nlh); BUG_ON(tw->tw_state != TCP_TIME_WAIT); nlh->nlmsg_flags = nlmsg_flags; @@ -247,9 +255,6 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, #endif nlh->nlmsg_len = skb_tail_pointer(skb) - previous_tail; return skb->len; -nlmsg_failure: - nlmsg_trim(skb, previous_tail); - return -EMSGSIZE; } static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, @@ -597,9 +602,13 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, struct nlmsghdr *nlh; long tmo; - nlh = NLMSG_PUT(skb, pid, seq, unlh->nlmsg_type, sizeof(*r)); + nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 0); + if (!nlh) { + nlmsg_trim(skb, b); + return -1; + } nlh->nlmsg_flags = NLM_F_MULTI; - r = NLMSG_DATA(nlh); + r = nlmsg_data(nlh); r->idiag_family = sk->sk_family; r->idiag_state = TCP_SYN_RECV; @@ -631,10 +640,6 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; - -nlmsg_failure: - nlmsg_trim(skb, b); - return -1; } static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, @@ -892,7 +897,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) if (nlmsg_attrlen(cb->nlh, hdrlen)) bc = nlmsg_find_attr(cb->nlh, hdrlen, INET_DIAG_REQ_BYTECODE); - return __inet_diag_dump(skb, cb, (struct inet_diag_req_v2 *)NLMSG_DATA(cb->nlh), bc); + return __inet_diag_dump(skb, cb, nlmsg_data(cb->nlh), bc); } static inline int inet_diag_type2proto(int type) @@ -909,7 +914,7 @@ static inline int inet_diag_type2proto(int type) static int inet_diag_dump_compat(struct sk_buff *skb, struct netlink_callback *cb) { - struct inet_diag_req *rc = NLMSG_DATA(cb->nlh); + struct inet_diag_req *rc = nlmsg_data(cb->nlh); struct inet_diag_req_v2 req; struct nlattr *bc = NULL; int hdrlen = sizeof(struct inet_diag_req); @@ -929,7 +934,7 @@ static int inet_diag_dump_compat(struct sk_buff *skb, struct netlink_callback *c static int inet_diag_get_exact_compat(struct sk_buff *in_skb, const struct nlmsghdr *nlh) { - struct inet_diag_req *rc = NLMSG_DATA(nlh); + struct inet_diag_req *rc = nlmsg_data(nlh); struct inet_diag_req_v2 req; req.sdiag_family = rc->idiag_family; @@ -996,7 +1001,7 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) } } - return inet_diag_get_exact(skb, h, (struct inet_diag_req_v2 *)NLMSG_DATA(h)); + return inet_diag_get_exact(skb, h, nlmsg_data(h)); } static const struct sock_diag_handler inet_diag_handler = { -- GitLab From c2bd4baf410dafeba6aff8ca1cae94344551b0a3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:30:49 -0700 Subject: [PATCH 2960/6849] netfilter: ipt_ULOG: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- net/ipv4/netfilter/ipt_ULOG.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index ba5756d20165..99b3f53f16a7 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -196,12 +196,15 @@ static void ipt_ulog_packet(unsigned int hooknum, pr_debug("qlen %d, qthreshold %Zu\n", ub->qlen, loginfo->qthreshold); - /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ - nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, - sizeof(*pm)+copy_len); + nlh = nlmsg_put(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, + sizeof(*pm)+copy_len, 0); + if (!nlh) { + pr_debug("error during nlmsg_put\n"); + goto out_unlock; + } ub->qlen++; - pm = NLMSG_DATA(nlh); + pm = nlmsg_data(nlh); /* We might not have a timestamp, get one */ if (skb->tstamp.tv64 == 0) @@ -261,13 +264,11 @@ static void ipt_ulog_packet(unsigned int hooknum, nlh->nlmsg_type = NLMSG_DONE; ulog_send(groupnum); } - +out_unlock: spin_unlock_bh(&ulog_lock); return; -nlmsg_failure: - pr_debug("error during NLMSG_PUT\n"); alloc_failure: pr_debug("Error building netlink message\n"); spin_unlock_bh(&ulog_lock); -- GitLab From d550d0958928889fa7978b3e254edcd6c52c3296 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:34:03 -0700 Subject: [PATCH 2961/6849] netfilter: nfnetlink_log: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 3c3cfc0cc9b5..169ab59ed9d4 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -326,18 +326,20 @@ __nfulnl_send(struct nfulnl_instance *inst) { int status = -1; - if (inst->qlen > 1) - NLMSG_PUT(inst->skb, 0, 0, - NLMSG_DONE, - sizeof(struct nfgenmsg)); - + if (inst->qlen > 1) { + struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0, + NLMSG_DONE, + sizeof(struct nfgenmsg), + 0); + if (!nlh) + goto out; + } status = nfnetlink_unicast(inst->skb, &init_net, inst->peer_pid, MSG_DONTWAIT); inst->qlen = 0; inst->skb = NULL; - -nlmsg_failure: +out: return status; } @@ -380,10 +382,12 @@ __build_packet_message(struct nfulnl_instance *inst, struct nfgenmsg *nfmsg; sk_buff_data_t old_tail = inst->skb->tail; - nlh = NLMSG_PUT(inst->skb, 0, 0, + nlh = nlmsg_put(inst->skb, 0, 0, NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, - sizeof(struct nfgenmsg)); - nfmsg = NLMSG_DATA(nlh); + sizeof(struct nfgenmsg), 0); + if (!nlh) + return -1; + nfmsg = nlmsg_data(nlh); nfmsg->nfgen_family = pf; nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(inst->group_num); @@ -526,7 +530,7 @@ __build_packet_message(struct nfulnl_instance *inst, if (skb_tailroom(inst->skb) < nla_total_size(data_len)) { printk(KERN_WARNING "nfnetlink_log: no tailroom!\n"); - goto nlmsg_failure; + return -1; } nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len)); @@ -540,7 +544,6 @@ __build_packet_message(struct nfulnl_instance *inst, nlh->nlmsg_len = inst->skb->tail - old_tail; return 0; -nlmsg_failure: nla_put_failure: PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg\n"); return -1; @@ -745,7 +748,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nfula[]) { - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); + struct nfgenmsg *nfmsg = nlmsg_data(nlh); u_int16_t group_num = ntohs(nfmsg->res_id); struct nfulnl_instance *inst; struct nfulnl_msg_config_cmd *cmd = NULL; -- GitLab From 3da07c0c2b5a13d05d9a66395d72eec0923b0592 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:35:27 -0700 Subject: [PATCH 2962/6849] netfilter: nfnetlink_queue_core: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_queue_core.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index d36b95ea8ca3..a0b64920039d 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c @@ -274,13 +274,17 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, skb = alloc_skb(size, GFP_ATOMIC); if (!skb) - goto nlmsg_failure; + return NULL; old_tail = skb->tail; - nlh = NLMSG_PUT(skb, 0, 0, + nlh = nlmsg_put(skb, 0, 0, NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET, - sizeof(struct nfgenmsg)); - nfmsg = NLMSG_DATA(nlh); + sizeof(struct nfgenmsg), 0); + if (!nlh) { + kfree_skb(skb); + return NULL; + } + nfmsg = nlmsg_data(nlh); nfmsg->nfgen_family = entry->pf; nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(queue->queue_num); @@ -383,7 +387,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, if (skb_tailroom(skb) < nla_total_size(data_len)) { printk(KERN_WARNING "nf_queue: no tailroom!\n"); - goto nlmsg_failure; + kfree_skb(skb); + return NULL; } nla = (struct nlattr *)skb_put(skb, nla_total_size(data_len)); @@ -400,7 +405,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, nlh->nlmsg_len = skb->tail - old_tail; return skb; -nlmsg_failure: nla_put_failure: if (skb) kfree_skb(skb); @@ -686,7 +690,7 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nfqa[]) { - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); + struct nfgenmsg *nfmsg = nlmsg_data(nlh); struct nf_queue_entry *entry, *tmp; unsigned int verdict, maxid; struct nfqnl_msg_verdict_hdr *vhdr; @@ -732,7 +736,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nfqa[]) { - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); + struct nfgenmsg *nfmsg = nlmsg_data(nlh); u_int16_t queue_num = ntohs(nfmsg->res_id); struct nfqnl_msg_verdict_hdr *vhdr; @@ -806,7 +810,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nfqa[]) { - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); + struct nfgenmsg *nfmsg = nlmsg_data(nlh); u_int16_t queue_num = ntohs(nfmsg->res_id); struct nfqnl_instance *queue; struct nfqnl_msg_config_cmd *cmd = NULL; -- GitLab From 8b00a53c633789394d7fec6ee0833d5f0cda3bca Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:39:32 -0700 Subject: [PATCH 2963/6849] pkt_sched: act_api: Move away from NLMSG_PUT(). Move away from NLMSG_NEW() as well. And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- net/sched/act_api.c | 59 ++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 5cfb160df063..e3d2c78cb52c 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -652,27 +652,27 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); - - t = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*t), flags); + if (!nlh) + goto out_nlmsg_trim; + t = nlmsg_data(nlh); t->tca_family = AF_UNSPEC; t->tca__pad1 = 0; t->tca__pad2 = 0; nest = nla_nest_start(skb, TCA_ACT_TAB); if (nest == NULL) - goto nla_put_failure; + goto out_nlmsg_trim; if (tcf_action_dump(skb, a, bind, ref) < 0) - goto nla_put_failure; + goto out_nlmsg_trim; nla_nest_end(skb, nest); nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -nla_put_failure: -nlmsg_failure: +out_nlmsg_trim: nlmsg_trim(skb, b); return -1; } @@ -799,19 +799,21 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, if (a->ops == NULL) goto err_out; - nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); - t = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0); + if (!nlh) + goto out_module_put; + t = nlmsg_data(nlh); t->tca_family = AF_UNSPEC; t->tca__pad1 = 0; t->tca__pad2 = 0; nest = nla_nest_start(skb, TCA_ACT_TAB); if (nest == NULL) - goto nla_put_failure; + goto out_module_put; err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); if (err < 0) - goto nla_put_failure; + goto out_module_put; if (err == 0) goto noflush_out; @@ -828,8 +830,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, return err; -nla_put_failure: -nlmsg_failure: +out_module_put: module_put(a->ops->owner); err_out: noflush_out: @@ -919,18 +920,20 @@ static int tcf_add_notify(struct net *net, struct tc_action *a, b = skb_tail_pointer(skb); - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); - t = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*t), flags); + if (!nlh) + goto out_kfree_skb; + t = nlmsg_data(nlh); t->tca_family = AF_UNSPEC; t->tca__pad1 = 0; t->tca__pad2 = 0; nest = nla_nest_start(skb, TCA_ACT_TAB); if (nest == NULL) - goto nla_put_failure; + goto out_kfree_skb; if (tcf_action_dump(skb, a, 0, 0) < 0) - goto nla_put_failure; + goto out_kfree_skb; nla_nest_end(skb, nest); @@ -942,8 +945,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a, err = 0; return err; -nla_put_failure: -nlmsg_failure: +out_kfree_skb: kfree_skb(skb); return -1; } @@ -1062,7 +1064,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) struct tc_action_ops *a_o; struct tc_action a; int ret = 0; - struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); + struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh); struct nlattr *kind = find_dump_kind(cb->nlh); if (kind == NULL) { @@ -1080,23 +1082,25 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) if (a_o->walk == NULL) { WARN(1, "tc_dump_action: %s !capable of dumping table\n", a_o->kind); - goto nla_put_failure; + goto out_module_put; } - nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - cb->nlh->nlmsg_type, sizeof(*t)); - t = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, + cb->nlh->nlmsg_type, sizeof(*t), 0); + if (!nlh) + goto out_module_put; + t = nlmsg_data(nlh); t->tca_family = AF_UNSPEC; t->tca__pad1 = 0; t->tca__pad2 = 0; nest = nla_nest_start(skb, TCA_ACT_TAB); if (nest == NULL) - goto nla_put_failure; + goto out_module_put; ret = a_o->walk(skb, cb, RTM_GETACTION, &a); if (ret < 0) - goto nla_put_failure; + goto out_module_put; if (ret > 0) { nla_nest_end(skb, nest); @@ -1110,8 +1114,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) module_put(a_o->owner); return skb->len; -nla_put_failure: -nlmsg_failure: +out_module_put: module_put(a_o->owner); nlmsg_trim(skb, b); return skb->len; -- GitLab From b61bb01974730e2fd7d36ab4cc848ca6f44cffd4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:41:00 -0700 Subject: [PATCH 2964/6849] unix_diag: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too and remove useless casts. Signed-off-by: David S. Miller --- net/unix/diag.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/net/unix/diag.c b/net/unix/diag.c index 7e8a24bff34a..977ca317550d 100644 --- a/net/unix/diag.c +++ b/net/unix/diag.c @@ -126,10 +126,12 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r struct nlmsghdr *nlh; struct unix_diag_msg *rep; - nlh = NLMSG_PUT(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep)); + nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep), 0); + if (!nlh) + goto out_nlmsg_trim; nlh->nlmsg_flags = flags; - rep = NLMSG_DATA(nlh); + rep = nlmsg_data(nlh); rep->udiag_family = AF_UNIX; rep->udiag_type = sk->sk_type; @@ -139,32 +141,32 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r if ((req->udiag_show & UDIAG_SHOW_NAME) && sk_diag_dump_name(sk, skb)) - goto nlmsg_failure; + goto out_nlmsg_trim; if ((req->udiag_show & UDIAG_SHOW_VFS) && sk_diag_dump_vfs(sk, skb)) - goto nlmsg_failure; + goto out_nlmsg_trim; if ((req->udiag_show & UDIAG_SHOW_PEER) && sk_diag_dump_peer(sk, skb)) - goto nlmsg_failure; + goto out_nlmsg_trim; if ((req->udiag_show & UDIAG_SHOW_ICONS) && sk_diag_dump_icons(sk, skb)) - goto nlmsg_failure; + goto out_nlmsg_trim; if ((req->udiag_show & UDIAG_SHOW_RQLEN) && sk_diag_show_rqlen(sk, skb)) - goto nlmsg_failure; + goto out_nlmsg_trim; if ((req->udiag_show & UDIAG_SHOW_MEMINFO) && sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) - goto nlmsg_failure; + goto out_nlmsg_trim; nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -nlmsg_failure: +out_nlmsg_trim: nlmsg_trim(skb, b); return -EMSGSIZE; } @@ -189,7 +191,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) struct unix_diag_req *req; int num, s_num, slot, s_slot; - req = NLMSG_DATA(cb->nlh); + req = nlmsg_data(cb->nlh); s_slot = cb->args[0]; num = s_num = cb->args[1]; @@ -309,7 +311,7 @@ static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) }; return netlink_dump_start(sock_diag_nlsk, skb, h, &c); } else - return unix_diag_get_exact(skb, h, (struct unix_diag_req *)NLMSG_DATA(h)); + return unix_diag_get_exact(skb, h, nlmsg_data(h)); } static const struct sock_diag_handler unix_diag_handler = { -- GitLab From 01f534d0ae9d7b3ad4dcd943d53418731da82ea7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:41:57 -0700 Subject: [PATCH 2965/6849] selinux: netlink: Move away from NLMSG_PUT(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- security/selinux/netlink.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index 161e01a6c7ef..8a23a35b9c5b 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "security.h" @@ -47,7 +48,7 @@ static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void * { switch (msgtype) { case SELNL_MSG_SETENFORCE: { - struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh); + struct selnl_msg_setenforce *msg = nlmsg_data(nlh); memset(msg, 0, len); msg->val = *((int *)data); @@ -55,7 +56,7 @@ static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void * } case SELNL_MSG_POLICYLOAD: { - struct selnl_msg_policyload *msg = NLMSG_DATA(nlh); + struct selnl_msg_policyload *msg = nlmsg_data(nlh); memset(msg, 0, len); msg->seqno = *((u32 *)data); @@ -81,7 +82,9 @@ static void selnl_notify(int msgtype, void *data) goto oom; tmp = skb->tail; - nlh = NLMSG_PUT(skb, 0, 0, msgtype, len); + nlh = nlmsg_put(skb, 0, 0, msgtype, len, 0); + if (!nlh) + goto out_kfree_skb; selnl_add_payload(nlh, len, msgtype, data); nlh->nlmsg_len = skb->tail - tmp; NETLINK_CB(skb).dst_group = SELNLGRP_AVC; @@ -89,7 +92,7 @@ static void selnl_notify(int msgtype, void *data) out: return; -nlmsg_failure: +out_kfree_skb: kfree_skb(skb); oom: printk(KERN_ERR "SELinux: OOM in %s\n", __func__); -- GitLab From e05273341c573f7b543f45c06e4a232c5b7c5a59 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:43:19 -0700 Subject: [PATCH 2966/6849] infiniband: netlink: Move away from NLMSG_NEW(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- drivers/infiniband/core/netlink.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index e497dfbee435..1e691dca1820 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -108,12 +108,14 @@ void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq, unsigned char *prev_tail; prev_tail = skb_tail_pointer(skb); - *nlh = NLMSG_NEW(skb, 0, seq, RDMA_NL_GET_TYPE(client, op), - len, NLM_F_MULTI); + *nlh = nlmsg_put(skb, 0, seq, RDMA_NL_GET_TYPE(client, op), + len, NLM_F_MULTI); + if (!*nlh) + goto out_nlmsg_trim; (*nlh)->nlmsg_len = skb_tail_pointer(skb) - prev_tail; - return NLMSG_DATA(*nlh); + return nlmsg_data(*nlh); -nlmsg_failure: +out_nlmsg_trim: nlmsg_trim(skb, prev_tail); return NULL; } -- GitLab From c64e66c67b574f25a048886807c2007d17d50d0a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:45:21 -0700 Subject: [PATCH 2967/6849] audit: netlink: Move away from NLMSG_NEW(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- kernel/audit.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/kernel/audit.c b/kernel/audit.c index 1c7f2c61416b..30b252a1fb61 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -384,7 +384,7 @@ static void audit_hold_skb(struct sk_buff *skb) static void audit_printk_skb(struct sk_buff *skb) { struct nlmsghdr *nlh = nlmsg_hdr(skb); - char *data = NLMSG_DATA(nlh); + char *data = nlmsg_data(nlh); if (nlh->nlmsg_type != AUDIT_EOE) { if (printk_ratelimit()) @@ -516,14 +516,15 @@ struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, if (!skb) return NULL; - nlh = NLMSG_NEW(skb, pid, seq, t, size, flags); - data = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, t, size, flags); + if (!nlh) + goto out_kfree_skb; + data = nlmsg_data(nlh); memcpy(data, payload, size); return skb; -nlmsg_failure: /* Used by NLMSG_NEW */ - if (skb) - kfree_skb(skb); +out_kfree_skb: + kfree_skb(skb); return NULL; } @@ -680,7 +681,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) sessionid = audit_get_sessionid(current); security_task_getsecid(current, &sid); seq = nlh->nlmsg_seq; - data = NLMSG_DATA(nlh); + data = nlmsg_data(nlh); switch (msg_type) { case AUDIT_GET: @@ -1060,13 +1061,15 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask); if (!ab->skb) - goto nlmsg_failure; + goto err; - nlh = NLMSG_NEW(ab->skb, 0, 0, type, 0, 0); + nlh = nlmsg_put(ab->skb, 0, 0, type, 0, 0); + if (!nlh) + goto out_kfree_skb; return ab; -nlmsg_failure: /* Used by NLMSG_NEW */ +out_kfree_skb: kfree_skb(ab->skb); ab->skb = NULL; err: -- GitLab From 737100e1622360b3de10550a15faf095547d972a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:46:19 -0700 Subject: [PATCH 2968/6849] decnet: dn_route: Move away from NLMSG_NEW(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- net/decnet/dn_route.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 586302e557ad..cd584f7de4dd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1518,8 +1518,10 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, unsigned char *b = skb_tail_pointer(skb); long expires; - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); - r = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); + if (!nlh) + goto out_nlmsg_trim; + r = nlmsg_data(nlh); r->rtm_family = AF_DECnet; r->rtm_dst_len = 16; r->rtm_src_len = 0; @@ -1559,7 +1561,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -nlmsg_failure: +out_nlmsg_trim: rtattr_failure: nlmsg_trim(skb, b); return -1; @@ -1572,7 +1574,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void { struct net *net = sock_net(in_skb->sk); struct rtattr **rta = arg; - struct rtmsg *rtm = NLMSG_DATA(nlh); + struct rtmsg *rtm = nlmsg_data(nlh); struct dn_route *rt = NULL; struct dn_skb_cb *cb; int err; @@ -1669,7 +1671,7 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg)) return -EINVAL; - if (!(((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)) + if (!(((struct rtmsg *)nlmsg_data(cb->nlh))->rtm_flags&RTM_F_CLONED)) return 0; s_h = cb->args[0]; -- GitLab From 3f7a3283ccfa59e0dbbc59a6710bd37ba44d4333 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:47:21 -0700 Subject: [PATCH 2969/6849] decnet: dn_table: Move away from NLMSG_NEW(). And use nlmsg_data() while we're here too. Signed-off-by: David S. Miller --- net/decnet/dn_table.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 650f3380c98a..92ec7417a4d9 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -299,8 +299,10 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags); - rtm = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags); + if (!nlh) + goto out_nlmsg_trim; + rtm = nlmsg_data(nlh); rtm->rtm_family = AF_DECnet; rtm->rtm_dst_len = dst_len; rtm->rtm_src_len = 0; @@ -348,8 +350,7 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; - -nlmsg_failure: +out_nlmsg_trim: rtattr_failure: nlmsg_trim(skb, b); return -EMSGSIZE; @@ -476,7 +477,7 @@ int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) return 0; if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) && - ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED) + ((struct rtmsg *)nlmsg_data(cb->nlh))->rtm_flags&RTM_F_CLONED) return dn_cache_dump(skb, cb); s_h = cb->args[0]; -- GitLab From 942b81653a5252fc0d7071f685113fc0ada28d4b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:48:50 -0700 Subject: [PATCH 2970/6849] pkt_sched: cls_api: Move away from NLMSG_NEW(). And use nlmsg_data() while we're here too, as well as remove a useless cast. Signed-off-by: David S. Miller --- net/sched/cls_api.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index f452f696b4b3..6dd1131f2ec1 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -140,7 +140,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) int tp_created = 0; replay: - t = NLMSG_DATA(n); + t = nlmsg_data(n); protocol = TC_H_MIN(t->tcm_info); prio = TC_H_MAJ(t->tcm_info); nprio = prio; @@ -349,8 +349,10 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); - tcm = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); tcm->tcm_family = AF_UNSPEC; tcm->tcm__pad1 = 0; tcm->tcm__pad2 = 0; @@ -368,7 +370,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -nlmsg_failure: +out_nlmsg_trim: nla_put_failure: nlmsg_trim(skb, b); return -1; @@ -418,7 +420,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) struct net_device *dev; struct Qdisc *q; struct tcf_proto *tp, **chain; - struct tcmsg *tcm = (struct tcmsg *)NLMSG_DATA(cb->nlh); + struct tcmsg *tcm = nlmsg_data(cb->nlh); unsigned long cl = 0; const struct Qdisc_class_ops *cops; struct tcf_dump_args arg; -- GitLab From 02ef22ca4044fe90867f77cba720e4a442122826 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:50:05 -0700 Subject: [PATCH 2971/6849] pkt_sched: sch_api: Move away from NLMSG_NEW(). And use nlmsg_data() while we're here too, as well as remove a useless cast. Signed-off-by: David S. Miller --- net/sched/sch_api.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 085ce53d570a..a08b4ab3e421 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -973,7 +973,7 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w) static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { struct net *net = sock_net(skb->sk); - struct tcmsg *tcm = NLMSG_DATA(n); + struct tcmsg *tcm = nlmsg_data(n); struct nlattr *tca[TCA_MAX + 1]; struct net_device *dev; u32 clid = tcm->tcm_parent; @@ -1046,7 +1046,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) replay: /* Reinit, just in case something touches this. */ - tcm = NLMSG_DATA(n); + tcm = nlmsg_data(n); clid = tcm->tcm_parent; q = p = NULL; @@ -1193,8 +1193,10 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, struct gnet_dump d; struct qdisc_size_table *stab; - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); - tcm = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); tcm->tcm_family = AF_UNSPEC; tcm->tcm__pad1 = 0; tcm->tcm__pad2 = 0; @@ -1230,7 +1232,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -nlmsg_failure: +out_nlmsg_trim: nla_put_failure: nlmsg_trim(skb, b); return -1; @@ -1366,7 +1368,7 @@ done: static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { struct net *net = sock_net(skb->sk); - struct tcmsg *tcm = NLMSG_DATA(n); + struct tcmsg *tcm = nlmsg_data(n); struct nlattr *tca[TCA_MAX + 1]; struct net_device *dev; struct Qdisc *q = NULL; @@ -1498,8 +1500,10 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, struct gnet_dump d; const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops; - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); - tcm = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); tcm->tcm_family = AF_UNSPEC; tcm->tcm__pad1 = 0; tcm->tcm__pad2 = 0; @@ -1525,7 +1529,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; -nlmsg_failure: +out_nlmsg_trim: nla_put_failure: nlmsg_trim(skb, b); return -1; @@ -1616,7 +1620,7 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb, static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) { - struct tcmsg *tcm = (struct tcmsg *)NLMSG_DATA(cb->nlh); + struct tcmsg *tcm = nlmsg_data(cb->nlh); struct net *net = sock_net(skb->sk); struct netdev_queue *dev_queue; struct net_device *dev; -- GitLab From c3deafc5261a9421b315ee0d0e8e36ba7857128c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2012 21:51:35 -0700 Subject: [PATCH 2972/6849] netlink: Delete NLMSG_PUT and NLMSG_NEW. No longer used and a poor interface as they were macros with embedded gotos. Signed-off-by: David S. Miller --- include/linux/netlink.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 0f628ffa420c..ed33f0901bc2 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -241,14 +241,6 @@ struct netlink_notify { struct nlmsghdr * __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags); -#define NLMSG_NEW(skb, pid, seq, type, len, flags) \ -({ if (unlikely(skb_tailroom(skb) < (int)NLMSG_SPACE(len))) \ - goto nlmsg_failure; \ - __nlmsg_put(skb, pid, seq, type, len, flags); }) - -#define NLMSG_PUT(skb, pid, seq, type, len) \ - NLMSG_NEW(skb, pid, seq, type, len, 0) - struct netlink_dump_control { int (*dump)(struct sk_buff *skb, struct netlink_callback *); int (*done)(struct netlink_callback*); -- GitLab From 3621189064301a5fbb5d06ca17d966a026f4e501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 13 Jun 2012 18:15:34 +0200 Subject: [PATCH 2973/6849] hwrng: mxc-rnga - fix data_present API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 45001e9, which added support for RNGA, ignored the previous commit 984e976, which changed the data_present API. Cc: Matt Mackall Cc: Sascha Hauer Cc: Alan Carvalho de Assis Cc: Signed-off-by: Benoît Thébaudeau Signed-off-by: Herbert Xu --- drivers/char/hw_random/mxc-rnga.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index 187c6be80f43..85074de5042e 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c @@ -24,6 +24,7 @@ #include #include #include +#include #include /* RNGA Registers */ @@ -60,16 +61,20 @@ static struct platform_device *rng_dev; -static int mxc_rnga_data_present(struct hwrng *rng) +static int mxc_rnga_data_present(struct hwrng *rng, int wait) { - int level; void __iomem *rng_base = (void __iomem *)rng->priv; - - /* how many random numbers is in FIFO? [0-16] */ - level = ((__raw_readl(rng_base + RNGA_STATUS) & - RNGA_STATUS_LEVEL_MASK) >> 8); - - return level > 0 ? 1 : 0; + int i; + + for (i = 0; i < 20; i++) { + /* how many random numbers are in FIFO? [0-16] */ + int level = (__raw_readl(rng_base + RNGA_STATUS) & + RNGA_STATUS_LEVEL_MASK) >> 8; + if (level || !wait) + return !!level; + udelay(10); + } + return 0; } static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) -- GitLab From 95ead5d7ff824a01cb07921c9211a7e29437a929 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 13 Jun 2012 13:22:42 -0500 Subject: [PATCH 2974/6849] crypto: nx - move nx build to driver/crypto Makefile When the nx driver was pulled, the Makefile that actually builds it is arch/powerpc/Makefile. This is unnatural. This patch moves the line that builds the nx driver from arch/powerpc/Makefile to drivers/crypto/Makefile where it belongs. Signed-off-by: Seth Jennings Acked-by: Kent Yoder Signed-off-by: Herbert Xu --- arch/powerpc/Makefile | 1 - drivers/crypto/Makefile | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 950d1f7a5a39..159e94f4b22a 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -149,7 +149,6 @@ core-$(CONFIG_KVM) += arch/powerpc/kvm/ core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ -drivers-$(CONFIG_CRYPTO_DEV_NX) += drivers/crypto/nx/ # Default to zImage, override when needed all: zImage diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index d5062bb7a1f2..1c5a145cc268 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/ obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o +obj-$(CONFIG_CRYPTO_DEV_NX) += nx/ -- GitLab From 7c76bdd7c3baf6d2431bb801f5b11d2ac195fdd6 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 13 Jun 2012 13:22:43 -0500 Subject: [PATCH 2975/6849] crypto: nx - fix typo in nx driver config option Signed-off-by: Seth Jennings Acked-by: Kent Yoder Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index dd4d5af6c31f..be6b2ba11fb1 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -298,7 +298,7 @@ config CRYPTO_DEV_TEGRA_AES will be called tegra-aes. config CRYPTO_DEV_NX - tristate "Support for Power7+ in-Nest cryptographic accleration" + tristate "Support for Power7+ in-Nest cryptographic acceleration" depends on PPC64 && IBMVIO select CRYPTO_AES select CRYPTO_CBC -- GitLab From ffaf9156320a077ebf9c5b9a5cf987689dc1a6b3 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:06:58 +0300 Subject: [PATCH 2976/6849] crypto: ablk_helper - move ablk_* functions from serpent-sse2/avx glue code to shared module Move ablk-* functions to separate module to share common code between cipher implementations. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 2 + arch/x86/crypto/ablk_helper.c | 150 ++++++++++++++++++++++ arch/x86/crypto/serpent_avx_glue.c | 115 +---------------- arch/x86/crypto/serpent_sse2_glue.c | 115 +---------------- arch/x86/include/asm/crypto/ablk_helper.h | 29 +++++ crypto/Kconfig | 8 ++ 6 files changed, 201 insertions(+), 218 deletions(-) create mode 100644 arch/x86/crypto/ablk_helper.c create mode 100644 arch/x86/include/asm/crypto/ablk_helper.h diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 83caa4b948c8..ad746916f912 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -2,6 +2,8 @@ # Arch-specific CryptoAPI modules. # +obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o + obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o diff --git a/arch/x86/crypto/ablk_helper.c b/arch/x86/crypto/ablk_helper.c new file mode 100644 index 000000000000..284ca3bc2383 --- /dev/null +++ b/arch/x86/crypto/ablk_helper.c @@ -0,0 +1,150 @@ +/* + * Shared async block cipher helpers + * + * Copyright (c) 2012 Jussi Kivilinna + * + * Based on aesni-intel_glue.c by: + * Copyright (C) 2008, Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len) +{ + struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; + int err; + + crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); + crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) + & CRYPTO_TFM_REQ_MASK); + err = crypto_ablkcipher_setkey(child, key, key_len); + crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) + & CRYPTO_TFM_RES_MASK); + return err; +} +EXPORT_SYMBOL_GPL(ablk_set_key); + +int __ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct blkcipher_desc desc; + + desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); + desc.info = req->info; + desc.flags = 0; + + return crypto_blkcipher_crt(desc.tfm)->encrypt( + &desc, req->dst, req->src, req->nbytes); +} +EXPORT_SYMBOL_GPL(__ablk_encrypt); + +int ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + if (!irq_fpu_usable()) { + struct ablkcipher_request *cryptd_req = + ablkcipher_request_ctx(req); + + memcpy(cryptd_req, req, sizeof(*req)); + ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + + return crypto_ablkcipher_encrypt(cryptd_req); + } else { + return __ablk_encrypt(req); + } +} +EXPORT_SYMBOL_GPL(ablk_encrypt); + +int ablk_decrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + if (!irq_fpu_usable()) { + struct ablkcipher_request *cryptd_req = + ablkcipher_request_ctx(req); + + memcpy(cryptd_req, req, sizeof(*req)); + ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + + return crypto_ablkcipher_decrypt(cryptd_req); + } else { + struct blkcipher_desc desc; + + desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); + desc.info = req->info; + desc.flags = 0; + + return crypto_blkcipher_crt(desc.tfm)->decrypt( + &desc, req->dst, req->src, req->nbytes); + } +} +EXPORT_SYMBOL_GPL(ablk_decrypt); + +void ablk_exit(struct crypto_tfm *tfm) +{ + struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); + + cryptd_free_ablkcipher(ctx->cryptd_tfm); +} +EXPORT_SYMBOL_GPL(ablk_exit); + +void ablk_init_common(struct crypto_tfm *tfm, + struct cryptd_ablkcipher *cryptd_tfm) +{ + struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); + + ctx->cryptd_tfm = cryptd_tfm; + tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + + crypto_ablkcipher_reqsize(&cryptd_tfm->base); +} +EXPORT_SYMBOL_GPL(ablk_init_common); + +int ablk_init(struct crypto_tfm *tfm) +{ + struct cryptd_ablkcipher *cryptd_tfm; + char drv_name[CRYPTO_MAX_ALG_NAME]; + + snprintf(drv_name, sizeof(drv_name), "__driver-%s", + crypto_tfm_alg_driver_name(tfm)); + + cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); + + ablk_init_common(tfm, cryptd_tfm); + + return 0; +} +EXPORT_SYMBOL_GPL(ablk_init); + +MODULE_LICENSE("GPL"); diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c index dd81bab4f11a..31eb567cc893 100644 --- a/arch/x86/crypto/serpent_avx_glue.c +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -40,14 +40,11 @@ #include #include #include +#include #include #include #include -struct async_serpent_ctx { - struct cryptd_ablkcipher *cryptd_tfm; -}; - static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) { if (fpu_enabled) @@ -593,106 +590,6 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, return ret; } -static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int key_len) -{ - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; - int err; - - crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) - & CRYPTO_TFM_REQ_MASK); - err = crypto_ablkcipher_setkey(child, key, key_len); - crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) - & CRYPTO_TFM_RES_MASK); - return err; -} - -static int __ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->encrypt( - &desc, req->dst, req->src, req->nbytes); -} - -static int ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_encrypt(cryptd_req); - } else { - return __ablk_encrypt(req); - } -} - -static int ablk_decrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_decrypt(cryptd_req); - } else { - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->decrypt( - &desc, req->dst, req->src, req->nbytes); - } -} - -static void ablk_exit(struct crypto_tfm *tfm) -{ - struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); - - cryptd_free_ablkcipher(ctx->cryptd_tfm); -} - -static int ablk_init(struct crypto_tfm *tfm) -{ - struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); - struct cryptd_ablkcipher *cryptd_tfm; - char drv_name[CRYPTO_MAX_ALG_NAME]; - - snprintf(drv_name, sizeof(drv_name), "__driver-%s", - crypto_tfm_alg_driver_name(tfm)); - - cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); - if (IS_ERR(cryptd_tfm)) - return PTR_ERR(cryptd_tfm); - - ctx->cryptd_tfm = cryptd_tfm; - tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + - crypto_ablkcipher_reqsize(&cryptd_tfm->base); - - return 0; -} - static struct crypto_alg serpent_algs[10] = { { .cra_name = "__ecb-serpent-avx", .cra_driver_name = "__driver-ecb-serpent-avx", @@ -805,7 +702,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 500, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -827,7 +724,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 500, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -850,7 +747,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 500, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -874,7 +771,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 500, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -899,7 +796,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 500, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index deecd25c1299..805c91fda7a2 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -43,14 +43,11 @@ #include #include #include +#include #include #include #include -struct async_serpent_ctx { - struct cryptd_ablkcipher *cryptd_tfm; -}; - static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) { if (fpu_enabled) @@ -596,106 +593,6 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, return ret; } -static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int key_len) -{ - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; - int err; - - crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) - & CRYPTO_TFM_REQ_MASK); - err = crypto_ablkcipher_setkey(child, key, key_len); - crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) - & CRYPTO_TFM_RES_MASK); - return err; -} - -static int __ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->encrypt( - &desc, req->dst, req->src, req->nbytes); -} - -static int ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_encrypt(cryptd_req); - } else { - return __ablk_encrypt(req); - } -} - -static int ablk_decrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_decrypt(cryptd_req); - } else { - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->decrypt( - &desc, req->dst, req->src, req->nbytes); - } -} - -static void ablk_exit(struct crypto_tfm *tfm) -{ - struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); - - cryptd_free_ablkcipher(ctx->cryptd_tfm); -} - -static int ablk_init(struct crypto_tfm *tfm) -{ - struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); - struct cryptd_ablkcipher *cryptd_tfm; - char drv_name[CRYPTO_MAX_ALG_NAME]; - - snprintf(drv_name, sizeof(drv_name), "__driver-%s", - crypto_tfm_alg_driver_name(tfm)); - - cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); - if (IS_ERR(cryptd_tfm)) - return PTR_ERR(cryptd_tfm); - - ctx->cryptd_tfm = cryptd_tfm; - tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + - crypto_ablkcipher_reqsize(&cryptd_tfm->base); - - return 0; -} - static struct crypto_alg serpent_algs[10] = { { .cra_name = "__ecb-serpent-sse2", .cra_driver_name = "__driver-ecb-serpent-sse2", @@ -808,7 +705,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -830,7 +727,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -853,7 +750,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -877,7 +774,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -902,7 +799,7 @@ static struct crypto_alg serpent_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = SERPENT_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_serpent_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, diff --git a/arch/x86/include/asm/crypto/ablk_helper.h b/arch/x86/include/asm/crypto/ablk_helper.h new file mode 100644 index 000000000000..6d6b37c6f5d3 --- /dev/null +++ b/arch/x86/include/asm/crypto/ablk_helper.h @@ -0,0 +1,29 @@ +/* + * Shared async block cipher helpers + */ + +#ifndef _CRYPTO_ABLK_HELPER_H +#define _CRYPTO_ABLK_HELPER_H + +#include +#include +#include + +struct async_helper_ctx { + struct cryptd_ablkcipher *cryptd_tfm; +}; + +extern int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len); + +extern int __ablk_encrypt(struct ablkcipher_request *req); + +extern int ablk_encrypt(struct ablkcipher_request *req); + +extern int ablk_decrypt(struct ablkcipher_request *req); + +extern void ablk_exit(struct crypto_tfm *tfm); + +extern int ablk_init(struct crypto_tfm *tfm); + +#endif /* _CRYPTO_ABLK_HELPER_H */ diff --git a/crypto/Kconfig b/crypto/Kconfig index 2c1c2dfcc02a..8e9145c07d87 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -174,6 +174,11 @@ config CRYPTO_TEST help Quick & dirty crypto test module. +config CRYPTO_ABLK_HELPER_X86 + tristate + depends on X86 + select CRYPTO_CRYPTD + comment "Authenticated Encryption with Associated Data" config CRYPTO_CCM @@ -786,6 +791,7 @@ config CRYPTO_SERPENT_SSE2_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD + select CRYPTO_ABLK_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW select CRYPTO_XTS @@ -806,6 +812,7 @@ config CRYPTO_SERPENT_SSE2_586 depends on X86 && !64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD + select CRYPTO_ABLK_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW select CRYPTO_XTS @@ -826,6 +833,7 @@ config CRYPTO_SERPENT_AVX_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD + select CRYPTO_ABLK_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW select CRYPTO_XTS -- GitLab From 30a04008827b58c4aafbd1d6a27d6b6ed239e993 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:03 +0300 Subject: [PATCH 2977/6849] crypto: twofish-avx - change to use shared ablk_* functions Remove duplicate ablk_* functions and make use of ablk_helper module instead. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/twofish_avx_glue.c | 116 ++--------------------------- crypto/Kconfig | 1 + 2 files changed, 7 insertions(+), 110 deletions(-) diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c index 599f19e4bef6..cabe058eba14 100644 --- a/arch/x86/crypto/twofish_avx_glue.c +++ b/arch/x86/crypto/twofish_avx_glue.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -95,11 +96,6 @@ static inline void twofish_dec_blk_xway(struct twofish_ctx *ctx, u8 *dst, } - -struct async_twofish_ctx { - struct cryptd_ablkcipher *cryptd_tfm; -}; - static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes) { if (fpu_enabled) @@ -730,106 +726,6 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, return ret; } -static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int key_len) -{ - struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; - int err; - - crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) - & CRYPTO_TFM_REQ_MASK); - err = crypto_ablkcipher_setkey(child, key, key_len); - crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) - & CRYPTO_TFM_RES_MASK); - return err; -} - -static int __ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->encrypt( - &desc, req->dst, req->src, req->nbytes); -} - -static int ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_encrypt(cryptd_req); - } else { - return __ablk_encrypt(req); - } -} - -static int ablk_decrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_twofish_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - - return crypto_ablkcipher_decrypt(cryptd_req); - } else { - struct blkcipher_desc desc; - - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - - return crypto_blkcipher_crt(desc.tfm)->decrypt( - &desc, req->dst, req->src, req->nbytes); - } -} - -static void ablk_exit(struct crypto_tfm *tfm) -{ - struct async_twofish_ctx *ctx = crypto_tfm_ctx(tfm); - - cryptd_free_ablkcipher(ctx->cryptd_tfm); -} - -static int ablk_init(struct crypto_tfm *tfm) -{ - struct async_twofish_ctx *ctx = crypto_tfm_ctx(tfm); - struct cryptd_ablkcipher *cryptd_tfm; - char drv_name[CRYPTO_MAX_ALG_NAME]; - - snprintf(drv_name, sizeof(drv_name), "__driver-%s", - crypto_tfm_alg_driver_name(tfm)); - - cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); - if (IS_ERR(cryptd_tfm)) - return PTR_ERR(cryptd_tfm); - - ctx->cryptd_tfm = cryptd_tfm; - tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + - crypto_ablkcipher_reqsize(&cryptd_tfm->base); - - return 0; -} - static struct crypto_alg twofish_algs[10] = { { .cra_name = "__ecb-twofish-avx", .cra_driver_name = "__driver-ecb-twofish-avx", @@ -942,7 +838,7 @@ static struct crypto_alg twofish_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TF_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -964,7 +860,7 @@ static struct crypto_alg twofish_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TF_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -987,7 +883,7 @@ static struct crypto_alg twofish_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1011,7 +907,7 @@ static struct crypto_alg twofish_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TF_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1036,7 +932,7 @@ static struct crypto_alg twofish_algs[10] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TF_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_twofish_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, diff --git a/crypto/Kconfig b/crypto/Kconfig index 8e9145c07d87..24b929e30bf3 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -946,6 +946,7 @@ config CRYPTO_TWOFISH_AVX_X86_64 depends on X86 && 64BIT select CRYPTO_ALGAPI select CRYPTO_CRYPTD + select CRYPTO_ABLK_HELPER_X86 select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 select CRYPTO_TWOFISH_X86_64_3WAY -- GitLab From a9629d7142ea22567eaa999232d8a31a7493665a Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:08 +0300 Subject: [PATCH 2978/6849] crypto: aes_ni - change to use shared ablk_* functions Remove duplicate ablk_* functions and make use of ablk_helper module instead. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/ablk_helper.c | 19 ++-- arch/x86/crypto/aesni-intel_glue.c | 100 ++-------------------- arch/x86/include/asm/crypto/ablk_helper.h | 2 + crypto/Kconfig | 1 + 4 files changed, 20 insertions(+), 102 deletions(-) diff --git a/arch/x86/crypto/ablk_helper.c b/arch/x86/crypto/ablk_helper.c index 284ca3bc2383..43282fe04a8b 100644 --- a/arch/x86/crypto/ablk_helper.c +++ b/arch/x86/crypto/ablk_helper.c @@ -118,32 +118,31 @@ void ablk_exit(struct crypto_tfm *tfm) } EXPORT_SYMBOL_GPL(ablk_exit); -void ablk_init_common(struct crypto_tfm *tfm, - struct cryptd_ablkcipher *cryptd_tfm) +int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name) { struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); + struct cryptd_ablkcipher *cryptd_tfm; + + cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); ctx->cryptd_tfm = cryptd_tfm; tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + crypto_ablkcipher_reqsize(&cryptd_tfm->base); + + return 0; } EXPORT_SYMBOL_GPL(ablk_init_common); int ablk_init(struct crypto_tfm *tfm) { - struct cryptd_ablkcipher *cryptd_tfm; char drv_name[CRYPTO_MAX_ALG_NAME]; snprintf(drv_name, sizeof(drv_name), "__driver-%s", crypto_tfm_alg_driver_name(tfm)); - cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); - if (IS_ERR(cryptd_tfm)) - return PTR_ERR(cryptd_tfm); - - ablk_init_common(tfm, cryptd_tfm); - - return 0; + return ablk_init_common(tfm, drv_name); } EXPORT_SYMBOL_GPL(ablk_init); diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index ac7f5cd019e8..7c9d54d8dc4d 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -52,10 +53,6 @@ #define HAS_XTS #endif -struct async_aes_ctx { - struct cryptd_ablkcipher *cryptd_tfm; -}; - /* This data is stored at the end of the crypto_tfm struct. * It's a type of per "session" data storage location. * This needs to be 16 byte aligned. @@ -377,87 +374,6 @@ static int ctr_crypt(struct blkcipher_desc *desc, } #endif -static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, - unsigned int key_len) -{ - struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; - int err; - - crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) - & CRYPTO_TFM_REQ_MASK); - err = crypto_ablkcipher_setkey(child, key, key_len); - crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) - & CRYPTO_TFM_RES_MASK); - return err; -} - -static int ablk_encrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - return crypto_ablkcipher_encrypt(cryptd_req); - } else { - struct blkcipher_desc desc; - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - return crypto_blkcipher_crt(desc.tfm)->encrypt( - &desc, req->dst, req->src, req->nbytes); - } -} - -static int ablk_decrypt(struct ablkcipher_request *req) -{ - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); - - if (!irq_fpu_usable()) { - struct ablkcipher_request *cryptd_req = - ablkcipher_request_ctx(req); - memcpy(cryptd_req, req, sizeof(*req)); - ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); - return crypto_ablkcipher_decrypt(cryptd_req); - } else { - struct blkcipher_desc desc; - desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); - desc.info = req->info; - desc.flags = 0; - return crypto_blkcipher_crt(desc.tfm)->decrypt( - &desc, req->dst, req->src, req->nbytes); - } -} - -static void ablk_exit(struct crypto_tfm *tfm) -{ - struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm); - - cryptd_free_ablkcipher(ctx->cryptd_tfm); -} - -static int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name) -{ - struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm); - struct cryptd_ablkcipher *cryptd_tfm; - - cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); - if (IS_ERR(cryptd_tfm)) - return PTR_ERR(cryptd_tfm); - - ctx->cryptd_tfm = cryptd_tfm; - tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + - crypto_ablkcipher_reqsize(&cryptd_tfm->base); - - return 0; -} - static int ablk_ecb_init(struct crypto_tfm *tfm) { return ablk_init_common(tfm, "__driver-ecb-aes-aesni"); @@ -968,7 +884,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -989,7 +905,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1033,7 +949,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1098,7 +1014,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1126,7 +1042,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1150,7 +1066,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, @@ -1174,7 +1090,7 @@ static struct crypto_alg aesni_algs[] = { { .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_ctxsize = sizeof(struct async_helper_ctx), .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, diff --git a/arch/x86/include/asm/crypto/ablk_helper.h b/arch/x86/include/asm/crypto/ablk_helper.h index 6d6b37c6f5d3..4f93df50c23e 100644 --- a/arch/x86/include/asm/crypto/ablk_helper.h +++ b/arch/x86/include/asm/crypto/ablk_helper.h @@ -24,6 +24,8 @@ extern int ablk_decrypt(struct ablkcipher_request *req); extern void ablk_exit(struct crypto_tfm *tfm); +extern int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name); + extern int ablk_init(struct crypto_tfm *tfm); #endif /* _CRYPTO_ABLK_HELPER_H */ diff --git a/crypto/Kconfig b/crypto/Kconfig index 24b929e30bf3..471cc468e18f 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -557,6 +557,7 @@ config CRYPTO_AES_NI_INTEL select CRYPTO_AES_X86_64 if 64BIT select CRYPTO_AES_586 if !64BIT select CRYPTO_CRYPTD + select CRYPTO_ABLK_HELPER_X86 select CRYPTO_ALGAPI help Use Intel AES-NI instructions for AES algorithm. -- GitLab From e81792fbc2a6fa4969f724b959829667fb2d4f01 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:14 +0300 Subject: [PATCH 2979/6849] crypto: serpent-sse2 - prepare serpent-sse2 glue code into generic x86 glue code for 128bit block ciphers Block cipher implementations in arch/x86/crypto/ contain common glue code that is currently duplicated in each module (camellia-x86_64, twofish-x86_64-3way, twofish-avx, serpent-sse2 and serpent-avx). This patch prepares serpent-sse2 glue into generic glue code for all 128bit block ciphers to use in arch/x86/crypto. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/serpent_sse2_glue.c | 466 ++++++++++++++++++---------- 1 file changed, 303 insertions(+), 163 deletions(-) diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 805c91fda7a2..8c86239010ae 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -48,105 +48,129 @@ #include #include -static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) +typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src); +typedef void (*common_glue_cbc_func_t)(void *ctx, u128 *dst, const u128 *src); +typedef void (*common_glue_ctr_func_t)(void *ctx, u128 *dst, const u128 *src, + u128 *iv); + +#define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn)) +#define GLUE_CBC_FUNC_CAST(fn) ((common_glue_cbc_func_t)(fn)) +#define GLUE_CTR_FUNC_CAST(fn) ((common_glue_ctr_func_t)(fn)) + +struct common_glue_func_entry { + unsigned int num_blocks; /* number of blocks that @fn will process */ + union { + common_glue_func_t ecb; + common_glue_cbc_func_t cbc; + common_glue_ctr_func_t ctr; + } fn_u; +}; + +struct common_glue_ctx { + unsigned int num_funcs; + int fpu_blocks_limit; /* -1 means fpu not needed at all */ + + /* + * First funcs entry must have largest num_blocks and last funcs entry + * must have num_blocks == 1! + */ + struct common_glue_func_entry funcs[]; +}; + +static inline bool glue_fpu_begin(unsigned int bsize, int fpu_blocks_limit, + struct blkcipher_desc *desc, + bool fpu_enabled, unsigned int nbytes) { + if (likely(fpu_blocks_limit < 0)) + return false; + if (fpu_enabled) return true; - /* SSE2 is only used when chunk to be processed is large enough, so - * do not enable FPU until it is necessary. + /* + * Vector-registers are only used when chunk to be processed is large + * enough, so do not enable FPU until it is necessary. */ - if (nbytes < SERPENT_BLOCK_SIZE * SERPENT_PARALLEL_BLOCKS) + if (nbytes < bsize * (unsigned int)fpu_blocks_limit) return false; + if (desc) { + /* prevent sleeping if FPU is in use */ + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + } + kernel_fpu_begin(); return true; } -static inline void serpent_fpu_end(bool fpu_enabled) +static inline void glue_fpu_end(bool fpu_enabled) { if (fpu_enabled) kernel_fpu_end(); } -static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - bool enc) +static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) { + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; + unsigned int nbytes, i, func_bytes; bool fpu_enabled = false; - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; - unsigned int nbytes; int err; err = blkcipher_walk_virt(desc, walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; while ((nbytes = walk->nbytes)) { u8 *wsrc = walk->src.virt.addr; u8 *wdst = walk->dst.virt.addr; - fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, fpu_enabled, nbytes); - /* Process multi-block batch */ - if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { - do { - if (enc) - serpent_enc_blk_xway(ctx, wdst, wsrc); - else - serpent_dec_blk_xway(ctx, wdst, wsrc); + for (i = 0; i < gctx->num_funcs; i++) { + func_bytes = bsize * gctx->funcs[i].num_blocks; - wsrc += bsize * SERPENT_PARALLEL_BLOCKS; - wdst += bsize * SERPENT_PARALLEL_BLOCKS; - nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; - } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); + /* Process multi-block batch */ + if (nbytes >= func_bytes) { + do { + gctx->funcs[i].fn_u.ecb(ctx, wdst, + wsrc); - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (enc) - __serpent_encrypt(ctx, wdst, wsrc); - else - __serpent_decrypt(ctx, wdst, wsrc); + wsrc += func_bytes; + wdst += func_bytes; + nbytes -= func_bytes; + } while (nbytes >= func_bytes); - wsrc += bsize; - wdst += bsize; - nbytes -= bsize; - } while (nbytes >= bsize); + if (nbytes < bsize) + goto done; + } + } done: err = blkcipher_walk_done(desc, walk, nbytes); } - serpent_fpu_end(fpu_enabled); + glue_fpu_end(fpu_enabled); return err; } -static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { struct blkcipher_walk walk; blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, true); + return __glue_ecb_crypt_128bit(gctx, desc, &walk); } -static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +static unsigned int __glue_cbc_encrypt_128bit(const common_glue_func_t fn, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) { - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, false); -} - -static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; unsigned int nbytes = walk->nbytes; u128 *src = (u128 *)walk->src.virt.addr; u128 *dst = (u128 *)walk->dst.virt.addr; @@ -154,7 +178,7 @@ static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, do { u128_xor(dst, src, iv); - __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst); + fn(ctx, (u8 *)dst, (u8 *)dst); iv = dst; src += 1; @@ -166,8 +190,10 @@ static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, return nbytes; } -static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +int glue_cbc_encrypt_128bit(const common_glue_func_t fn, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { struct blkcipher_walk walk; int err; @@ -176,24 +202,26 @@ static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, err = blkcipher_walk_virt(desc, &walk); while ((nbytes = walk.nbytes)) { - nbytes = __cbc_encrypt(desc, &walk); + nbytes = __glue_cbc_encrypt_128bit(fn, desc, &walk); err = blkcipher_walk_done(desc, &walk, nbytes); } return err; } -static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static unsigned int +__glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) { - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; unsigned int nbytes = walk->nbytes; u128 *src = (u128 *)walk->src.virt.addr; u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; u128 last_iv; - int i; + unsigned int num_blocks, func_bytes; + unsigned int i; /* Start of the last block. */ src += nbytes / bsize - 1; @@ -201,45 +229,31 @@ static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, last_iv = *src; - /* Process multi-block batch */ - if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { - do { - nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1); - src -= SERPENT_PARALLEL_BLOCKS - 1; - dst -= SERPENT_PARALLEL_BLOCKS - 1; + for (i = 0; i < gctx->num_funcs; i++) { + num_blocks = gctx->funcs[i].num_blocks; + func_bytes = bsize * num_blocks; - for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) - ivs[i] = src[i]; + /* Process multi-block batch */ + if (nbytes >= func_bytes) { + do { + nbytes -= func_bytes - bsize; + src -= num_blocks - 1; + dst -= num_blocks - 1; + + gctx->funcs[i].fn_u.cbc(ctx, dst, src); - serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); + nbytes -= bsize; + if (nbytes < bsize) + goto done; - for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) - u128_xor(dst + (i + 1), dst + (i + 1), ivs + i); + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } while (nbytes >= func_bytes); - nbytes -= bsize; if (nbytes < bsize) goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - for (;;) { - __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src); - - nbytes -= bsize; - if (nbytes < bsize) - break; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; + } } done: @@ -249,24 +263,27 @@ done: return nbytes; } -static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { + const unsigned int bsize = 128 / 8; bool fpu_enabled = false; struct blkcipher_walk walk; int err; blkcipher_walk_init(&walk, dst, src, nbytes); err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; while ((nbytes = walk.nbytes)) { - fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); - nbytes = __cbc_decrypt(desc, &walk); + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, fpu_enabled, nbytes); + nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); err = blkcipher_walk_done(desc, &walk, nbytes); } - serpent_fpu_end(fpu_enabled); + glue_fpu_end(fpu_enabled); return err; } @@ -289,109 +306,232 @@ static inline void u128_inc(u128 *i) i->a++; } -static void ctr_crypt_final(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static void glue_ctr_crypt_final_128bit(const common_glue_ctr_func_t fn_ctr, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) { - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - u8 *ctrblk = walk->iv; - u8 keystream[SERPENT_BLOCK_SIZE]; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; + void *ctx = crypto_blkcipher_ctx(desc->tfm); + u8 *src = (u8 *)walk->src.virt.addr; + u8 *dst = (u8 *)walk->dst.virt.addr; unsigned int nbytes = walk->nbytes; + u128 ctrblk; + u128 tmp; - __serpent_encrypt(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + be128_to_u128(&ctrblk, (be128 *)walk->iv); - crypto_inc(ctrblk, SERPENT_BLOCK_SIZE); + memcpy(&tmp, src, nbytes); + fn_ctr(ctx, &tmp, &tmp, &ctrblk); + memcpy(dst, &tmp, nbytes); + + u128_to_be128((be128 *)walk->iv, &ctrblk); } -static unsigned int __ctr_crypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static unsigned int __glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) { - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; + const unsigned int bsize = 128 / 8; + void *ctx = crypto_blkcipher_ctx(desc->tfm); unsigned int nbytes = walk->nbytes; u128 *src = (u128 *)walk->src.virt.addr; u128 *dst = (u128 *)walk->dst.virt.addr; u128 ctrblk; - be128 ctrblocks[SERPENT_PARALLEL_BLOCKS]; - int i; + unsigned int num_blocks, func_bytes; + unsigned int i; be128_to_u128(&ctrblk, (be128 *)walk->iv); /* Process multi-block batch */ - if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { - do { - /* create ctrblks for parallel encrypt */ - for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { - if (dst != src) - dst[i] = src[i]; - - u128_to_be128(&ctrblocks[i], &ctrblk); - u128_inc(&ctrblk); - } + for (i = 0; i < gctx->num_funcs; i++) { + num_blocks = gctx->funcs[i].num_blocks; + func_bytes = bsize * num_blocks; - serpent_enc_blk_xway_xor(ctx, (u8 *)dst, - (u8 *)ctrblocks); + if (nbytes >= func_bytes) { + do { + gctx->funcs[i].fn_u.ctr(ctx, dst, src, &ctrblk); - src += SERPENT_PARALLEL_BLOCKS; - dst += SERPENT_PARALLEL_BLOCKS; - nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; - } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); + src += num_blocks; + dst += num_blocks; + nbytes -= func_bytes; + } while (nbytes >= func_bytes); - if (nbytes < bsize) - goto done; + if (nbytes < bsize) + goto done; + } } - /* Handle leftovers */ - do { - if (dst != src) - *dst = *src; - - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - - __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); - u128_xor(dst, dst, (u128 *)ctrblocks); - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - done: u128_to_be128((be128 *)walk->iv, &ctrblk); return nbytes; } -static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { + const unsigned int bsize = 128 / 8; bool fpu_enabled = false; struct blkcipher_walk walk; int err; blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + err = blkcipher_walk_virt_block(desc, &walk, bsize); - while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) { - fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); - nbytes = __ctr_crypt(desc, &walk); + while ((nbytes = walk.nbytes) >= bsize) { + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, fpu_enabled, nbytes); + nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); err = blkcipher_walk_done(desc, &walk, nbytes); } - serpent_fpu_end(fpu_enabled); + glue_fpu_end(fpu_enabled); if (walk.nbytes) { - ctr_crypt_final(desc, &walk); + glue_ctr_crypt_final_128bit( + gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); err = blkcipher_walk_done(desc, &walk, 0); } return err; } +static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) +{ + u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; + unsigned int j; + + for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) + ivs[j] = src[j]; + + serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); + + for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) + u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); +} + +static void serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) +{ + be128 ctrblk; + + u128_to_be128(&ctrblk, iv); + u128_inc(iv); + + __serpent_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); + u128_xor(dst, src, (u128 *)&ctrblk); +} + +static void serpent_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src, + u128 *iv) +{ + be128 ctrblks[SERPENT_PARALLEL_BLOCKS]; + unsigned int i; + + for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { + if (dst != src) + dst[i] = src[i]; + + u128_to_be128(&ctrblks[i], iv); + u128_inc(iv); + } + + serpent_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); +} + +static const struct common_glue_ctx serpent_enc = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_enc_blk_xway) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } + } } +}; + +static const struct common_glue_ctx serpent_ctr = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr_xway) } + }, { + .num_blocks = 1, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr) } + } } +}; + +static const struct common_glue_ctx serpent_dec = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_dec_blk_xway) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } + } } +}; + +static const struct common_glue_ctx serpent_dec_cbc = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_decrypt_cbc_xway) } + }, { + .num_blocks = 1, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } + } } +}; + +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return glue_ecb_crypt_128bit(&serpent_enc, desc, dst, src, nbytes); +} + +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return glue_ecb_crypt_128bit(&serpent_dec, desc, dst, src, nbytes); +} + +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__serpent_encrypt), desc, + dst, src, nbytes); +} + +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return glue_cbc_decrypt_128bit(&serpent_dec_cbc, desc, dst, src, + nbytes); +} + +static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return glue_ctr_crypt_128bit(&serpent_ctr, desc, dst, src, nbytes); +} + +static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) +{ + return glue_fpu_begin(SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS, + NULL, fpu_enabled, nbytes); +} + +static inline void serpent_fpu_end(bool fpu_enabled) +{ + glue_fpu_end(fpu_enabled); +} + struct crypt_priv { struct serpent_ctx *ctx; bool fpu_enabled; -- GitLab From 596d875052dac6bf084f0c3a3e946fb4709b727b Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:19 +0300 Subject: [PATCH 2980/6849] crypto: serpent-sse2 - split generic glue code to new helper module Now that serpent-sse2 glue code has been made generic, it can be split to separate module. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/Makefile | 1 + arch/x86/crypto/glue_helper.c | 307 +++++++++++++++++++ arch/x86/crypto/serpent_sse2_glue.c | 352 +--------------------- arch/x86/include/asm/crypto/glue_helper.h | 115 +++++++ crypto/Kconfig | 7 + 5 files changed, 431 insertions(+), 351 deletions(-) create mode 100644 arch/x86/crypto/glue_helper.c create mode 100644 arch/x86/include/asm/crypto/glue_helper.h diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index ad746916f912..e908e5de82d3 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o +obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c new file mode 100644 index 000000000000..4854f0f31e4f --- /dev/null +++ b/arch/x86/crypto/glue_helper.c @@ -0,0 +1,307 @@ +/* + * Shared glue code for 128bit block ciphers + * + * Copyright (c) 2012 Jussi Kivilinna + * + * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: + * Copyright (c) 2006 Herbert Xu + * CTR part based on code (crypto/ctr.c) by: + * (C) Copyright IBM Corp. 2007 - Joy Latten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#include +#include +#include +#include +#include +#include + +static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; + unsigned int nbytes, i, func_bytes; + bool fpu_enabled = false; + int err; + + err = blkcipher_walk_virt(desc, walk); + + while ((nbytes = walk->nbytes)) { + u8 *wsrc = walk->src.virt.addr; + u8 *wdst = walk->dst.virt.addr; + + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, fpu_enabled, nbytes); + + for (i = 0; i < gctx->num_funcs; i++) { + func_bytes = bsize * gctx->funcs[i].num_blocks; + + /* Process multi-block batch */ + if (nbytes >= func_bytes) { + do { + gctx->funcs[i].fn_u.ecb(ctx, wdst, + wsrc); + + wsrc += func_bytes; + wdst += func_bytes; + nbytes -= func_bytes; + } while (nbytes >= func_bytes); + + if (nbytes < bsize) + goto done; + } + } + +done: + err = blkcipher_walk_done(desc, walk, nbytes); + } + + glue_fpu_end(fpu_enabled); + return err; +} + +int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); + return __glue_ecb_crypt_128bit(gctx, desc, &walk); +} +EXPORT_SYMBOL_GPL(glue_ecb_crypt_128bit); + +static unsigned int __glue_cbc_encrypt_128bit(const common_glue_func_t fn, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 *iv = (u128 *)walk->iv; + + do { + u128_xor(dst, src, iv); + fn(ctx, (u8 *)dst, (u8 *)dst); + iv = dst; + + src += 1; + dst += 1; + nbytes -= bsize; + } while (nbytes >= bsize); + + u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); + return nbytes; +} + +int glue_cbc_encrypt_128bit(const common_glue_func_t fn, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while ((nbytes = walk.nbytes)) { + nbytes = __glue_cbc_encrypt_128bit(fn, desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} +EXPORT_SYMBOL_GPL(glue_cbc_encrypt_128bit); + +static unsigned int +__glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + void *ctx = crypto_blkcipher_ctx(desc->tfm); + const unsigned int bsize = 128 / 8; + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 last_iv; + unsigned int num_blocks, func_bytes; + unsigned int i; + + /* Start of the last block. */ + src += nbytes / bsize - 1; + dst += nbytes / bsize - 1; + + last_iv = *src; + + for (i = 0; i < gctx->num_funcs; i++) { + num_blocks = gctx->funcs[i].num_blocks; + func_bytes = bsize * num_blocks; + + /* Process multi-block batch */ + if (nbytes >= func_bytes) { + do { + nbytes -= func_bytes - bsize; + src -= num_blocks - 1; + dst -= num_blocks - 1; + + gctx->funcs[i].fn_u.cbc(ctx, dst, src); + + nbytes -= bsize; + if (nbytes < bsize) + goto done; + + u128_xor(dst, dst, src - 1); + src -= 1; + dst -= 1; + } while (nbytes >= func_bytes); + + if (nbytes < bsize) + goto done; + } + } + +done: + u128_xor(dst, dst, (u128 *)walk->iv); + *(u128 *)walk->iv = last_iv; + + return nbytes; +} + +int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + const unsigned int bsize = 128 / 8; + bool fpu_enabled = false; + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while ((nbytes = walk.nbytes)) { + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, fpu_enabled, nbytes); + nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + glue_fpu_end(fpu_enabled); + return err; +} +EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); + +static void glue_ctr_crypt_final_128bit(const common_glue_ctr_func_t fn_ctr, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + void *ctx = crypto_blkcipher_ctx(desc->tfm); + u8 *src = (u8 *)walk->src.virt.addr; + u8 *dst = (u8 *)walk->dst.virt.addr; + unsigned int nbytes = walk->nbytes; + u128 ctrblk; + u128 tmp; + + be128_to_u128(&ctrblk, (be128 *)walk->iv); + + memcpy(&tmp, src, nbytes); + fn_ctr(ctx, &tmp, &tmp, &ctrblk); + memcpy(dst, &tmp, nbytes); + + u128_to_be128((be128 *)walk->iv, &ctrblk); +} +EXPORT_SYMBOL_GPL(glue_ctr_crypt_final_128bit); + +static unsigned int __glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct blkcipher_walk *walk) +{ + const unsigned int bsize = 128 / 8; + void *ctx = crypto_blkcipher_ctx(desc->tfm); + unsigned int nbytes = walk->nbytes; + u128 *src = (u128 *)walk->src.virt.addr; + u128 *dst = (u128 *)walk->dst.virt.addr; + u128 ctrblk; + unsigned int num_blocks, func_bytes; + unsigned int i; + + be128_to_u128(&ctrblk, (be128 *)walk->iv); + + /* Process multi-block batch */ + for (i = 0; i < gctx->num_funcs; i++) { + num_blocks = gctx->funcs[i].num_blocks; + func_bytes = bsize * num_blocks; + + if (nbytes >= func_bytes) { + do { + gctx->funcs[i].fn_u.ctr(ctx, dst, src, &ctrblk); + + src += num_blocks; + dst += num_blocks; + nbytes -= func_bytes; + } while (nbytes >= func_bytes); + + if (nbytes < bsize) + goto done; + } + } + +done: + u128_to_be128((be128 *)walk->iv, &ctrblk); + return nbytes; +} + +int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + const unsigned int bsize = 128 / 8; + bool fpu_enabled = false; + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, bsize); + + while ((nbytes = walk.nbytes) >= bsize) { + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, fpu_enabled, nbytes); + nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + glue_fpu_end(fpu_enabled); + + if (walk.nbytes) { + glue_ctr_crypt_final_128bit( + gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); + err = blkcipher_walk_done(desc, &walk, 0); + } + + return err; +} +EXPORT_SYMBOL_GPL(glue_ctr_crypt_128bit); + +MODULE_LICENSE("GPL"); diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 8c86239010ae..49a32eedf0c8 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -41,359 +41,9 @@ #include #include #include -#include #include #include -#include -#include -#include - -typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src); -typedef void (*common_glue_cbc_func_t)(void *ctx, u128 *dst, const u128 *src); -typedef void (*common_glue_ctr_func_t)(void *ctx, u128 *dst, const u128 *src, - u128 *iv); - -#define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn)) -#define GLUE_CBC_FUNC_CAST(fn) ((common_glue_cbc_func_t)(fn)) -#define GLUE_CTR_FUNC_CAST(fn) ((common_glue_ctr_func_t)(fn)) - -struct common_glue_func_entry { - unsigned int num_blocks; /* number of blocks that @fn will process */ - union { - common_glue_func_t ecb; - common_glue_cbc_func_t cbc; - common_glue_ctr_func_t ctr; - } fn_u; -}; - -struct common_glue_ctx { - unsigned int num_funcs; - int fpu_blocks_limit; /* -1 means fpu not needed at all */ - - /* - * First funcs entry must have largest num_blocks and last funcs entry - * must have num_blocks == 1! - */ - struct common_glue_func_entry funcs[]; -}; - -static inline bool glue_fpu_begin(unsigned int bsize, int fpu_blocks_limit, - struct blkcipher_desc *desc, - bool fpu_enabled, unsigned int nbytes) -{ - if (likely(fpu_blocks_limit < 0)) - return false; - - if (fpu_enabled) - return true; - - /* - * Vector-registers are only used when chunk to be processed is large - * enough, so do not enable FPU until it is necessary. - */ - if (nbytes < bsize * (unsigned int)fpu_blocks_limit) - return false; - - if (desc) { - /* prevent sleeping if FPU is in use */ - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - } - - kernel_fpu_begin(); - return true; -} - -static inline void glue_fpu_end(bool fpu_enabled) -{ - if (fpu_enabled) - kernel_fpu_end(); -} - -static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - void *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = 128 / 8; - unsigned int nbytes, i, func_bytes; - bool fpu_enabled = false; - int err; - - err = blkcipher_walk_virt(desc, walk); - - while ((nbytes = walk->nbytes)) { - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, nbytes); - - for (i = 0; i < gctx->num_funcs; i++) { - func_bytes = bsize * gctx->funcs[i].num_blocks; - - /* Process multi-block batch */ - if (nbytes >= func_bytes) { - do { - gctx->funcs[i].fn_u.ecb(ctx, wdst, - wsrc); - - wsrc += func_bytes; - wdst += func_bytes; - nbytes -= func_bytes; - } while (nbytes >= func_bytes); - - if (nbytes < bsize) - goto done; - } - } - -done: - err = blkcipher_walk_done(desc, walk, nbytes); - } - - glue_fpu_end(fpu_enabled); - return err; -} - -int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return __glue_ecb_crypt_128bit(gctx, desc, &walk); -} - -static unsigned int __glue_cbc_encrypt_128bit(const common_glue_func_t fn, - struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - void *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = 128 / 8; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 *iv = (u128 *)walk->iv; - - do { - u128_xor(dst, src, iv); - fn(ctx, (u8 *)dst, (u8 *)dst); - iv = dst; - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - - u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); - return nbytes; -} - -int glue_cbc_encrypt_128bit(const common_glue_func_t fn, - struct blkcipher_desc *desc, - struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - nbytes = __glue_cbc_encrypt_128bit(fn, desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static unsigned int -__glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, - struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - void *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = 128 / 8; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 last_iv; - unsigned int num_blocks, func_bytes; - unsigned int i; - - /* Start of the last block. */ - src += nbytes / bsize - 1; - dst += nbytes / bsize - 1; - - last_iv = *src; - - for (i = 0; i < gctx->num_funcs; i++) { - num_blocks = gctx->funcs[i].num_blocks; - func_bytes = bsize * num_blocks; - - /* Process multi-block batch */ - if (nbytes >= func_bytes) { - do { - nbytes -= func_bytes - bsize; - src -= num_blocks - 1; - dst -= num_blocks - 1; - - gctx->funcs[i].fn_u.cbc(ctx, dst, src); - - nbytes -= bsize; - if (nbytes < bsize) - goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= func_bytes); - - if (nbytes < bsize) - goto done; - } - } - -done: - u128_xor(dst, dst, (u128 *)walk->iv); - *(u128 *)walk->iv = last_iv; - - return nbytes; -} - -int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, - struct blkcipher_desc *desc, - struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - const unsigned int bsize = 128 / 8; - bool fpu_enabled = false; - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, nbytes); - nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - glue_fpu_end(fpu_enabled); - return err; -} - -static inline void u128_to_be128(be128 *dst, const u128 *src) -{ - dst->a = cpu_to_be64(src->a); - dst->b = cpu_to_be64(src->b); -} - -static inline void be128_to_u128(u128 *dst, const be128 *src) -{ - dst->a = be64_to_cpu(src->a); - dst->b = be64_to_cpu(src->b); -} - -static inline void u128_inc(u128 *i) -{ - i->b++; - if (!i->b) - i->a++; -} - -static void glue_ctr_crypt_final_128bit(const common_glue_ctr_func_t fn_ctr, - struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - void *ctx = crypto_blkcipher_ctx(desc->tfm); - u8 *src = (u8 *)walk->src.virt.addr; - u8 *dst = (u8 *)walk->dst.virt.addr; - unsigned int nbytes = walk->nbytes; - u128 ctrblk; - u128 tmp; - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - - memcpy(&tmp, src, nbytes); - fn_ctr(ctx, &tmp, &tmp, &ctrblk); - memcpy(dst, &tmp, nbytes); - - u128_to_be128((be128 *)walk->iv, &ctrblk); -} - -static unsigned int __glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, - struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - const unsigned int bsize = 128 / 8; - void *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ctrblk; - unsigned int num_blocks, func_bytes; - unsigned int i; - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - - /* Process multi-block batch */ - for (i = 0; i < gctx->num_funcs; i++) { - num_blocks = gctx->funcs[i].num_blocks; - func_bytes = bsize * num_blocks; - - if (nbytes >= func_bytes) { - do { - gctx->funcs[i].fn_u.ctr(ctx, dst, src, &ctrblk); - - src += num_blocks; - dst += num_blocks; - nbytes -= func_bytes; - } while (nbytes >= func_bytes); - - if (nbytes < bsize) - goto done; - } - } - -done: - u128_to_be128((be128 *)walk->iv, &ctrblk); - return nbytes; -} - -int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, - struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - const unsigned int bsize = 128 / 8; - bool fpu_enabled = false; - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt_block(desc, &walk, bsize); - - while ((nbytes = walk.nbytes) >= bsize) { - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, nbytes); - nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - glue_fpu_end(fpu_enabled); - - if (walk.nbytes) { - glue_ctr_crypt_final_128bit( - gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); - } - - return err; -} +#include static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) { diff --git a/arch/x86/include/asm/crypto/glue_helper.h b/arch/x86/include/asm/crypto/glue_helper.h new file mode 100644 index 000000000000..3e408bddc96f --- /dev/null +++ b/arch/x86/include/asm/crypto/glue_helper.h @@ -0,0 +1,115 @@ +/* + * Shared glue code for 128bit block ciphers + */ + +#ifndef _CRYPTO_GLUE_HELPER_H +#define _CRYPTO_GLUE_HELPER_H + +#include +#include +#include +#include + +typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src); +typedef void (*common_glue_cbc_func_t)(void *ctx, u128 *dst, const u128 *src); +typedef void (*common_glue_ctr_func_t)(void *ctx, u128 *dst, const u128 *src, + u128 *iv); + +#define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn)) +#define GLUE_CBC_FUNC_CAST(fn) ((common_glue_cbc_func_t)(fn)) +#define GLUE_CTR_FUNC_CAST(fn) ((common_glue_ctr_func_t)(fn)) + +struct common_glue_func_entry { + unsigned int num_blocks; /* number of blocks that @fn will process */ + union { + common_glue_func_t ecb; + common_glue_cbc_func_t cbc; + common_glue_ctr_func_t ctr; + } fn_u; +}; + +struct common_glue_ctx { + unsigned int num_funcs; + int fpu_blocks_limit; /* -1 means fpu not needed at all */ + + /* + * First funcs entry must have largest num_blocks and last funcs entry + * must have num_blocks == 1! + */ + struct common_glue_func_entry funcs[]; +}; + +static inline bool glue_fpu_begin(unsigned int bsize, int fpu_blocks_limit, + struct blkcipher_desc *desc, + bool fpu_enabled, unsigned int nbytes) +{ + if (likely(fpu_blocks_limit < 0)) + return false; + + if (fpu_enabled) + return true; + + /* + * Vector-registers are only used when chunk to be processed is large + * enough, so do not enable FPU until it is necessary. + */ + if (nbytes < bsize * (unsigned int)fpu_blocks_limit) + return false; + + if (desc) { + /* prevent sleeping if FPU is in use */ + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + } + + kernel_fpu_begin(); + return true; +} + +static inline void glue_fpu_end(bool fpu_enabled) +{ + if (fpu_enabled) + kernel_fpu_end(); +} + +static inline void u128_to_be128(be128 *dst, const u128 *src) +{ + dst->a = cpu_to_be64(src->a); + dst->b = cpu_to_be64(src->b); +} + +static inline void be128_to_u128(u128 *dst, const be128 *src) +{ + dst->a = be64_to_cpu(src->a); + dst->b = be64_to_cpu(src->b); +} + +static inline void u128_inc(u128 *i) +{ + i->b++; + if (!i->b) + i->a++; +} + +extern int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes); + +extern int glue_cbc_encrypt_128bit(const common_glue_func_t fn, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); + +extern int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); + +extern int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes); + +#endif /* _CRYPTO_GLUE_HELPER_H */ diff --git a/crypto/Kconfig b/crypto/Kconfig index 471cc468e18f..92b46970c856 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -179,6 +179,11 @@ config CRYPTO_ABLK_HELPER_X86 depends on X86 select CRYPTO_CRYPTD +config CRYPTO_GLUE_HELPER_X86 + tristate + depends on X86 + select CRYPTO_ALGAPI + comment "Authenticated Encryption with Associated Data" config CRYPTO_CCM @@ -793,6 +798,7 @@ config CRYPTO_SERPENT_SSE2_X86_64 select CRYPTO_ALGAPI select CRYPTO_CRYPTD select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW select CRYPTO_XTS @@ -814,6 +820,7 @@ config CRYPTO_SERPENT_SSE2_586 select CRYPTO_ALGAPI select CRYPTO_CRYPTD select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW select CRYPTO_XTS -- GitLab From 1d0debbd4671a8d302a11837a126d5f87db16bdc Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:24 +0300 Subject: [PATCH 2981/6849] crypto: serpent-avx: remove duplicated glue code and use shared glue code from glue_helper Now that shared glue code is available, convert serpent-avx to use it. Cc: Johannes Goetzfried Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/serpent_avx_glue.c | 398 +++++++---------------------- crypto/Kconfig | 1 + 2 files changed, 95 insertions(+), 304 deletions(-) diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c index 31eb567cc893..c61b91aa42a8 100644 --- a/arch/x86/crypto/serpent_avx_glue.c +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -36,357 +36,147 @@ #include #include #include -#include #include #include #include #include -#include -#include -#include +#include -static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) +static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) { - if (fpu_enabled) - return true; - - /* AVX is only used when chunk to be processed is large enough, so - * do not enable FPU until it is necessary. - */ - if (nbytes < SERPENT_BLOCK_SIZE * SERPENT_PARALLEL_BLOCKS) - return false; - - kernel_fpu_begin(); - return true; -} - -static inline void serpent_fpu_end(bool fpu_enabled) -{ - if (fpu_enabled) - kernel_fpu_end(); -} - -static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - bool enc) -{ - bool fpu_enabled = false; - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; - unsigned int nbytes; - int err; + u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; + unsigned int j; - err = blkcipher_walk_virt(desc, walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) + ivs[j] = src[j]; - while ((nbytes = walk->nbytes)) { - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - - fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); - - /* Process multi-block batch */ - if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { - do { - if (enc) - serpent_enc_blk_xway(ctx, wdst, wsrc); - else - serpent_dec_blk_xway(ctx, wdst, wsrc); - - wsrc += bsize * SERPENT_PARALLEL_BLOCKS; - wdst += bsize * SERPENT_PARALLEL_BLOCKS; - nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; - } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (enc) - __serpent_encrypt(ctx, wdst, wsrc); - else - __serpent_decrypt(ctx, wdst, wsrc); - - wsrc += bsize; - wdst += bsize; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - err = blkcipher_walk_done(desc, walk, nbytes); - } + serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); - serpent_fpu_end(fpu_enabled); - return err; + for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) + u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); } -static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +static void serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) { - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, true); -} + be128 ctrblk; -static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; + u128_to_be128(&ctrblk, iv); + u128_inc(iv); - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, false); + __serpent_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); + u128_xor(dst, src, (u128 *)&ctrblk); } -static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static void serpent_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src, + u128 *iv) { - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 *iv = (u128 *)walk->iv; - - do { - u128_xor(dst, src, iv); - __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst); - iv = dst; - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - - u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); - return nbytes; -} + be128 ctrblks[SERPENT_PARALLEL_BLOCKS]; + unsigned int i; -static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); + for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { + if (dst != src) + dst[i] = src[i]; - while ((nbytes = walk.nbytes)) { - nbytes = __cbc_encrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); + u128_to_be128(&ctrblks[i], iv); + u128_inc(iv); } - return err; + serpent_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); } -static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; - u128 last_iv; - int i; - - /* Start of the last block. */ - src += nbytes / bsize - 1; - dst += nbytes / bsize - 1; - - last_iv = *src; - - /* Process multi-block batch */ - if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { - do { - nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1); - src -= SERPENT_PARALLEL_BLOCKS - 1; - dst -= SERPENT_PARALLEL_BLOCKS - 1; - - for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) - ivs[i] = src[i]; - - serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); - - for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) - u128_xor(dst + (i + 1), dst + (i + 1), ivs + i); - - nbytes -= bsize; - if (nbytes < bsize) - goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - for (;;) { - __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src); - - nbytes -= bsize; - if (nbytes < bsize) - break; +static const struct common_glue_ctx serpent_enc = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_enc_blk_xway) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } + } } +}; - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } +static const struct common_glue_ctx serpent_ctr = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr_xway) } + }, { + .num_blocks = 1, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr) } + } } +}; -done: - u128_xor(dst, dst, (u128 *)walk->iv); - *(u128 *)walk->iv = last_iv; +static const struct common_glue_ctx serpent_dec = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_dec_blk_xway) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } + } } +}; - return nbytes; -} +static const struct common_glue_ctx serpent_dec_cbc = { + .num_funcs = 2, + .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = SERPENT_PARALLEL_BLOCKS, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_decrypt_cbc_xway) } + }, { + .num_blocks = 1, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } + } } +}; -static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - bool fpu_enabled = false; - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes)) { - fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); - nbytes = __cbc_decrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - serpent_fpu_end(fpu_enabled); - return err; + return glue_ecb_crypt_128bit(&serpent_enc, desc, dst, src, nbytes); } -static inline void u128_to_be128(be128 *dst, const u128 *src) +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - dst->a = cpu_to_be64(src->a); - dst->b = cpu_to_be64(src->b); + return glue_ecb_crypt_128bit(&serpent_dec, desc, dst, src, nbytes); } -static inline void be128_to_u128(u128 *dst, const be128 *src) +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - dst->a = be64_to_cpu(src->a); - dst->b = be64_to_cpu(src->b); + return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__serpent_encrypt), desc, + dst, src, nbytes); } -static inline void u128_inc(u128 *i) +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - i->b++; - if (!i->b) - i->a++; + return glue_cbc_decrypt_128bit(&serpent_dec_cbc, desc, dst, src, + nbytes); } -static void ctr_crypt_final(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - u8 *ctrblk = walk->iv; - u8 keystream[SERPENT_BLOCK_SIZE]; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - unsigned int nbytes = walk->nbytes; - - __serpent_encrypt(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); - - crypto_inc(ctrblk, SERPENT_BLOCK_SIZE); + return glue_ctr_crypt_128bit(&serpent_ctr, desc, dst, src, nbytes); } -static unsigned int __ctr_crypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) { - struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = SERPENT_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ctrblk; - be128 ctrblocks[SERPENT_PARALLEL_BLOCKS]; - int i; - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - - /* Process multi-block batch */ - if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { - do { - /* create ctrblks for parallel encrypt */ - for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { - if (dst != src) - dst[i] = src[i]; - - u128_to_be128(&ctrblocks[i], &ctrblk); - u128_inc(&ctrblk); - } - - serpent_enc_blk_xway_xor(ctx, (u8 *)dst, - (u8 *)ctrblocks); - - src += SERPENT_PARALLEL_BLOCKS; - dst += SERPENT_PARALLEL_BLOCKS; - nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; - } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (dst != src) - *dst = *src; - - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - - __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); - u128_xor(dst, dst, (u128 *)ctrblocks); - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - u128_to_be128((be128 *)walk->iv, &ctrblk); - return nbytes; + return glue_fpu_begin(SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS, + NULL, fpu_enabled, nbytes); } -static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +static inline void serpent_fpu_end(bool fpu_enabled) { - bool fpu_enabled = false; - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) { - fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); - nbytes = __ctr_crypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - serpent_fpu_end(fpu_enabled); - - if (walk.nbytes) { - ctr_crypt_final(desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); - } - - return err; + glue_fpu_end(fpu_enabled); } struct crypt_priv { diff --git a/crypto/Kconfig b/crypto/Kconfig index 92b46970c856..a86c2fb92ea9 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -842,6 +842,7 @@ config CRYPTO_SERPENT_AVX_X86_64 select CRYPTO_ALGAPI select CRYPTO_CRYPTD select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT select CRYPTO_LRW select CRYPTO_XTS -- GitLab From 964263afdcbf9d1e85c021acfff0cc68dd168475 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:29 +0300 Subject: [PATCH 2982/6849] crypto: camellia-x86_64 - remove duplicated glue code and use shared glue code from glue_helper Now that shared glue code is available, convert camellia-x86_64 to use it. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/camellia_glue.c | 355 ++++++++------------------------ crypto/Kconfig | 1 + 2 files changed, 87 insertions(+), 269 deletions(-) diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c index 3306dc0b139e..eeb2b3b743e9 100644 --- a/arch/x86/crypto/camellia_glue.c +++ b/arch/x86/crypto/camellia_glue.c @@ -5,10 +5,6 @@ * * Camellia parts based on code by: * Copyright (C) 2006 NTT (Nippon Telegraph and Telephone Corporation) - * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: - * Copyright (c) 2006 Herbert Xu - * CTR part based on code (crypto/ctr.c) by: - * (C) Copyright IBM Corp. 2007 - Joy Latten * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,9 +30,9 @@ #include #include #include -#include #include #include +#include #define CAMELLIA_MIN_KEY_SIZE 16 #define CAMELLIA_MAX_KEY_SIZE 32 @@ -1312,307 +1308,128 @@ static int camellia_setkey(struct crypto_tfm *tfm, const u8 *in_key, &tfm->crt_flags); } -static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - void (*fn)(struct camellia_ctx *, u8 *, const u8 *), - void (*fn_2way)(struct camellia_ctx *, u8 *, const u8 *)) +static void camellia_decrypt_cbc_2way(void *ctx, u128 *dst, const u128 *src) { - struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = CAMELLIA_BLOCK_SIZE; - unsigned int nbytes; - int err; - - err = blkcipher_walk_virt(desc, walk); - - while ((nbytes = walk->nbytes)) { - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - - /* Process two block batch */ - if (nbytes >= bsize * 2) { - do { - fn_2way(ctx, wdst, wsrc); - - wsrc += bsize * 2; - wdst += bsize * 2; - nbytes -= bsize * 2; - } while (nbytes >= bsize * 2); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - fn(ctx, wdst, wsrc); - - wsrc += bsize; - wdst += bsize; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - err = blkcipher_walk_done(desc, walk, nbytes); - } - - return err; -} - -static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, camellia_enc_blk, camellia_enc_blk_2way); -} + u128 iv = *src; -static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, camellia_dec_blk, camellia_dec_blk_2way); -} + camellia_dec_blk_2way(ctx, (u8 *)dst, (u8 *)src); -static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = CAMELLIA_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 *iv = (u128 *)walk->iv; - - do { - u128_xor(dst, src, iv); - camellia_enc_blk(ctx, (u8 *)dst, (u8 *)dst); - iv = dst; - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - - u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); - return nbytes; + u128_xor(&dst[1], &dst[1], &iv); } -static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +static void camellia_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) { - struct blkcipher_walk walk; - int err; + be128 ctrblk; - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); + if (dst != src) + *dst = *src; - while ((nbytes = walk.nbytes)) { - nbytes = __cbc_encrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } + u128_to_be128(&ctrblk, iv); + u128_inc(iv); - return err; + camellia_enc_blk_xor(ctx, (u8 *)dst, (u8 *)&ctrblk); } -static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static void camellia_crypt_ctr_2way(void *ctx, u128 *dst, const u128 *src, + u128 *iv) { - struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = CAMELLIA_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ivs[2 - 1]; - u128 last_iv; + be128 ctrblks[2]; - /* Start of the last block. */ - src += nbytes / bsize - 1; - dst += nbytes / bsize - 1; - - last_iv = *src; - - /* Process two block batch */ - if (nbytes >= bsize * 2) { - do { - nbytes -= bsize * (2 - 1); - src -= 2 - 1; - dst -= 2 - 1; - - ivs[0] = src[0]; - - camellia_dec_blk_2way(ctx, (u8 *)dst, (u8 *)src); - - u128_xor(dst + 1, dst + 1, ivs + 0); - - nbytes -= bsize; - if (nbytes < bsize) - goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= bsize * 2); - - if (nbytes < bsize) - goto done; + if (dst != src) { + dst[0] = src[0]; + dst[1] = src[1]; } - /* Handle leftovers */ - for (;;) { - camellia_dec_blk(ctx, (u8 *)dst, (u8 *)src); - - nbytes -= bsize; - if (nbytes < bsize) - break; + u128_to_be128(&ctrblks[0], iv); + u128_inc(iv); + u128_to_be128(&ctrblks[1], iv); + u128_inc(iv); - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } - -done: - u128_xor(dst, dst, (u128 *)walk->iv); - *(u128 *)walk->iv = last_iv; - - return nbytes; + camellia_enc_blk_xor_2way(ctx, (u8 *)dst, (u8 *)ctrblks); } -static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); +static const struct common_glue_ctx camellia_enc = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 2, + .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk_2way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } + } } +}; - while ((nbytes = walk.nbytes)) { - nbytes = __cbc_decrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } +static const struct common_glue_ctx camellia_ctr = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 2, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr_2way) } + }, { + .num_blocks = 1, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr) } + } } +}; - return err; -} +static const struct common_glue_ctx camellia_dec = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 2, + .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk_2way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk) } + } } +}; -static inline void u128_to_be128(be128 *dst, const u128 *src) -{ - dst->a = cpu_to_be64(src->a); - dst->b = cpu_to_be64(src->b); -} +static const struct common_glue_ctx camellia_dec_cbc = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 2, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_decrypt_cbc_2way) } + }, { + .num_blocks = 1, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_dec_blk) } + } } +}; -static inline void be128_to_u128(u128 *dst, const be128 *src) +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - dst->a = be64_to_cpu(src->a); - dst->b = be64_to_cpu(src->b); + return glue_ecb_crypt_128bit(&camellia_enc, desc, dst, src, nbytes); } -static inline void u128_inc(u128 *i) +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - i->b++; - if (!i->b) - i->a++; + return glue_ecb_crypt_128bit(&camellia_dec, desc, dst, src, nbytes); } -static void ctr_crypt_final(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - u8 keystream[CAMELLIA_BLOCK_SIZE]; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - unsigned int nbytes = walk->nbytes; - u128 ctrblk; - - memcpy(keystream, src, nbytes); - camellia_enc_blk_xor(ctx, keystream, walk->iv); - memcpy(dst, keystream, nbytes); - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - u128_inc(&ctrblk); - u128_to_be128((be128 *)walk->iv, &ctrblk); + return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(camellia_enc_blk), desc, + dst, src, nbytes); } -static unsigned int __ctr_crypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = CAMELLIA_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ctrblk; - be128 ctrblocks[2]; - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - - /* Process two block batch */ - if (nbytes >= bsize * 2) { - do { - if (dst != src) { - dst[0] = src[0]; - dst[1] = src[1]; - } - - /* create ctrblks for parallel encrypt */ - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - u128_to_be128(&ctrblocks[1], &ctrblk); - u128_inc(&ctrblk); - - camellia_enc_blk_xor_2way(ctx, (u8 *)dst, - (u8 *)ctrblocks); - - src += 2; - dst += 2; - nbytes -= bsize * 2; - } while (nbytes >= bsize * 2); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (dst != src) - *dst = *src; - - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - - camellia_enc_blk_xor(ctx, (u8 *)dst, (u8 *)ctrblocks); - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - u128_to_be128((be128 *)walk->iv, &ctrblk); - return nbytes; + return glue_cbc_decrypt_128bit(&camellia_dec_cbc, desc, dst, src, + nbytes); } static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt_block(desc, &walk, CAMELLIA_BLOCK_SIZE); - - while ((nbytes = walk.nbytes) >= CAMELLIA_BLOCK_SIZE) { - nbytes = __ctr_crypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - if (walk.nbytes) { - ctr_crypt_final(desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); - } - - return err; + return glue_ctr_crypt_128bit(&camellia_ctr, desc, dst, src, nbytes); } static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) diff --git a/crypto/Kconfig b/crypto/Kconfig index a86c2fb92ea9..72828fafe09f 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -671,6 +671,7 @@ config CRYPTO_CAMELLIA_X86_64 depends on X86 && 64BIT depends on CRYPTO select CRYPTO_ALGAPI + select CRYPTO_GLUE_HELPER_X86 select CRYPTO_LRW select CRYPTO_XTS help -- GitLab From 414cb5e7cc6e258fe36e2c3cc3ef1ff2e246c0e3 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:34 +0300 Subject: [PATCH 2983/6849] crypto: twofish-x86_64-3way - remove duplicated glue code and use shared glue code from glue_helper Now that shared glue code is available, convert twofish-x86_64-3way to use it. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/twofish_glue_3way.c | 365 +++++++--------------------- crypto/Kconfig | 1 + 2 files changed, 94 insertions(+), 272 deletions(-) diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index 77e4e55a2660..25bf5e9b0067 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c @@ -3,11 +3,6 @@ * * Copyright (c) 2011 Jussi Kivilinna * - * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: - * Copyright (c) 2006 Herbert Xu - * CTR part based on code (crypto/ctr.c) by: - * (C) Copyright IBM Corp. 2007 - Joy Latten - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -33,6 +28,7 @@ #include #include #include +#include #include #include @@ -62,311 +58,136 @@ static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst, __twofish_enc_blk_3way(ctx, dst, src, true); } -static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - void (*fn)(struct twofish_ctx *, u8 *, const u8 *), - void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *)) +static void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src) { - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes; - int err; - - err = blkcipher_walk_virt(desc, walk); - - while ((nbytes = walk->nbytes)) { - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - - /* Process three block batch */ - if (nbytes >= bsize * 3) { - do { - fn_3way(ctx, wdst, wsrc); + u128 ivs[2]; - wsrc += bsize * 3; - wdst += bsize * 3; - nbytes -= bsize * 3; - } while (nbytes >= bsize * 3); + ivs[0] = src[0]; + ivs[1] = src[1]; - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - fn(ctx, wdst, wsrc); - - wsrc += bsize; - wdst += bsize; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - err = blkcipher_walk_done(desc, walk, nbytes); - } + twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); - return err; + u128_xor(&dst[1], &dst[1], &ivs[0]); + u128_xor(&dst[2], &dst[2], &ivs[1]); } -static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +static void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) { - struct blkcipher_walk walk; + be128 ctrblk; - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way); -} + if (dst != src) + *dst = *src; -static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; + u128_to_be128(&ctrblk, iv); + u128_inc(iv); - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way); + twofish_enc_blk(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); + u128_xor(dst, dst, (u128 *)&ctrblk); } -static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, + u128 *iv) { - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 *iv = (u128 *)walk->iv; - - do { - u128_xor(dst, src, iv); - twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst); - iv = dst; - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - - u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); - return nbytes; -} + be128 ctrblks[3]; -static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - nbytes = __cbc_encrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ivs[3 - 1]; - u128 last_iv; - - /* Start of the last block. */ - src += nbytes / bsize - 1; - dst += nbytes / bsize - 1; - - last_iv = *src; - - /* Process three block batch */ - if (nbytes >= bsize * 3) { - do { - nbytes -= bsize * (3 - 1); - src -= 3 - 1; - dst -= 3 - 1; - - ivs[0] = src[0]; - ivs[1] = src[1]; - - twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); - - u128_xor(dst + 1, dst + 1, ivs + 0); - u128_xor(dst + 2, dst + 2, ivs + 1); - - nbytes -= bsize; - if (nbytes < bsize) - goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= bsize * 3); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - for (;;) { - twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src); - - nbytes -= bsize; - if (nbytes < bsize) - break; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; + if (dst != src) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; } -done: - u128_xor(dst, dst, (u128 *)walk->iv); - *(u128 *)walk->iv = last_iv; + u128_to_be128(&ctrblks[0], iv); + u128_inc(iv); + u128_to_be128(&ctrblks[1], iv); + u128_inc(iv); + u128_to_be128(&ctrblks[2], iv); + u128_inc(iv); - return nbytes; + twofish_enc_blk_xor_3way(ctx, (u8 *)dst, (u8 *)ctrblks); } -static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) -{ - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); +static const struct common_glue_ctx twofish_enc = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 3, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) } + } } +}; - while ((nbytes = walk.nbytes)) { - nbytes = __cbc_decrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } +static const struct common_glue_ctx twofish_ctr = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 3, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr_3way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr) } + } } +}; - return err; -} +static const struct common_glue_ctx twofish_dec = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 3, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) } + } } +}; -static inline void u128_to_be128(be128 *dst, const u128 *src) -{ - dst->a = cpu_to_be64(src->a); - dst->b = cpu_to_be64(src->b); -} +static const struct common_glue_ctx twofish_dec_cbc = { + .num_funcs = 2, + .fpu_blocks_limit = -1, + + .funcs = { { + .num_blocks = 3, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) } + }, { + .num_blocks = 1, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) } + } } +}; -static inline void be128_to_u128(u128 *dst, const be128 *src) +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - dst->a = be64_to_cpu(src->a); - dst->b = be64_to_cpu(src->b); + return glue_ecb_crypt_128bit(&twofish_enc, desc, dst, src, nbytes); } -static inline void u128_inc(u128 *i) +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - i->b++; - if (!i->b) - i->a++; + return glue_ecb_crypt_128bit(&twofish_dec, desc, dst, src, nbytes); } -static void ctr_crypt_final(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - u8 *ctrblk = walk->iv; - u8 keystream[TF_BLOCK_SIZE]; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - unsigned int nbytes = walk->nbytes; - - twofish_enc_blk(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); - - crypto_inc(ctrblk, TF_BLOCK_SIZE); + return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(twofish_enc_blk), desc, + dst, src, nbytes); } -static unsigned int __ctr_crypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ctrblk; - be128 ctrblocks[3]; - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - - /* Process three block batch */ - if (nbytes >= bsize * 3) { - do { - if (dst != src) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - } - - /* create ctrblks for parallel encrypt */ - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - u128_to_be128(&ctrblocks[1], &ctrblk); - u128_inc(&ctrblk); - u128_to_be128(&ctrblocks[2], &ctrblk); - u128_inc(&ctrblk); - - twofish_enc_blk_xor_3way(ctx, (u8 *)dst, - (u8 *)ctrblocks); - - src += 3; - dst += 3; - nbytes -= bsize * 3; - } while (nbytes >= bsize * 3); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (dst != src) - *dst = *src; - - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - - twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); - u128_xor(dst, dst, (u128 *)ctrblocks); - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - u128_to_be128((be128 *)walk->iv, &ctrblk); - return nbytes; + return glue_cbc_decrypt_128bit(&twofish_dec_cbc, desc, dst, src, + nbytes); } static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE); - - while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) { - nbytes = __ctr_crypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - if (walk.nbytes) { - ctr_crypt_final(desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); - } - - return err; + return glue_ctr_crypt_128bit(&twofish_ctr, desc, dst, src, nbytes); } static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) diff --git a/crypto/Kconfig b/crypto/Kconfig index 72828fafe09f..fc559caaa9ad 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -935,6 +935,7 @@ config CRYPTO_TWOFISH_X86_64_3WAY select CRYPTO_ALGAPI select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 + select CRYPTO_GLUE_HELPER_X86 select CRYPTO_LRW select CRYPTO_XTS help -- GitLab From a7378d4e552ac139ae1cbbdfebfeaa9b18c948d0 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:39 +0300 Subject: [PATCH 2984/6849] crypto: twofish-avx - remove duplicated glue code and use shared glue code from glue_helper Now that shared glue code is available, convert twofish-avx to use it. Cc: Johannes Goetzfried Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/twofish_avx_glue.c | 556 +++++--------------------- arch/x86/crypto/twofish_glue_3way.c | 46 +-- arch/x86/include/asm/crypto/twofish.h | 46 +++ crypto/Kconfig | 1 + 4 files changed, 162 insertions(+), 487 deletions(-) create mode 100644 arch/x86/include/asm/crypto/twofish.h diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c index cabe058eba14..782b67ddaf6a 100644 --- a/arch/x86/crypto/twofish_avx_glue.c +++ b/arch/x86/crypto/twofish_avx_glue.c @@ -4,9 +4,6 @@ * Copyright (C) 2012 Johannes Goetzfried * * - * Glue code based on serpent_sse2_glue.c by: - * Copyright (C) 2011 Jussi Kivilinna - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -39,38 +36,21 @@ #include #include #include +#include #include +#include #include #include #include - #define TWOFISH_PARALLEL_BLOCKS 8 -/* regular block cipher functions from twofish_x86_64 module */ -asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); - -/* 3-way parallel cipher functions from twofish_x86_64-3way module */ -asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src, bool xor); -asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); - static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, const u8 *src) { __twofish_enc_blk_3way(ctx, dst, src, false); } -static inline void twofish_enc_blk_3way_xor(struct twofish_ctx *ctx, u8 *dst, - const u8 *src) -{ - __twofish_enc_blk_3way(ctx, dst, src, true); -} - /* 8-way parallel cipher functions */ asmlinkage void __twofish_enc_blk_8way(struct twofish_ctx *ctx, u8 *dst, const u8 *src, bool xor); @@ -95,423 +75,142 @@ static inline void twofish_dec_blk_xway(struct twofish_ctx *ctx, u8 *dst, twofish_dec_blk_8way(ctx, dst, src); } - -static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes) +static void twofish_dec_blk_cbc_xway(void *ctx, u128 *dst, const u128 *src) { - if (fpu_enabled) - return true; + u128 ivs[TWOFISH_PARALLEL_BLOCKS - 1]; + unsigned int j; - /* AVX is only used when chunk to be processed is large enough, so - * do not enable FPU until it is necessary. - */ - if (nbytes < TF_BLOCK_SIZE * TWOFISH_PARALLEL_BLOCKS) - return false; + for (j = 0; j < TWOFISH_PARALLEL_BLOCKS - 1; j++) + ivs[j] = src[j]; - kernel_fpu_begin(); - return true; -} + twofish_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); -static inline void twofish_fpu_end(bool fpu_enabled) -{ - if (fpu_enabled) - kernel_fpu_end(); + for (j = 0; j < TWOFISH_PARALLEL_BLOCKS - 1; j++) + u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); } -static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - bool enc) +static void twofish_enc_blk_ctr_xway(void *ctx, u128 *dst, const u128 *src, + u128 *iv) { - bool fpu_enabled = false; - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes; - int err; + be128 ctrblks[TWOFISH_PARALLEL_BLOCKS]; + unsigned int i; - err = blkcipher_walk_virt(desc, walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + for (i = 0; i < TWOFISH_PARALLEL_BLOCKS; i++) { + if (dst != src) + dst[i] = src[i]; - while ((nbytes = walk->nbytes)) { - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - - fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes); - - /* Process multi-block batch */ - if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) { - do { - if (enc) - twofish_enc_blk_xway(ctx, wdst, wsrc); - else - twofish_dec_blk_xway(ctx, wdst, wsrc); - - wsrc += bsize * TWOFISH_PARALLEL_BLOCKS; - wdst += bsize * TWOFISH_PARALLEL_BLOCKS; - nbytes -= bsize * TWOFISH_PARALLEL_BLOCKS; - } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Process three block batch */ - if (nbytes >= bsize * 3) { - do { - if (enc) - twofish_enc_blk_3way(ctx, wdst, wsrc); - else - twofish_dec_blk_3way(ctx, wdst, wsrc); - - wsrc += bsize * 3; - wdst += bsize * 3; - nbytes -= bsize * 3; - } while (nbytes >= bsize * 3); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (enc) - twofish_enc_blk(ctx, wdst, wsrc); - else - twofish_dec_blk(ctx, wdst, wsrc); - - wsrc += bsize; - wdst += bsize; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - err = blkcipher_walk_done(desc, walk, nbytes); + u128_to_be128(&ctrblks[i], iv); + u128_inc(iv); } - twofish_fpu_end(fpu_enabled); - return err; + twofish_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); } +static const struct common_glue_ctx twofish_enc = { + .num_funcs = 3, + .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = TWOFISH_PARALLEL_BLOCKS, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_xway) } + }, { + .num_blocks = 3, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) } + } } +}; + +static const struct common_glue_ctx twofish_ctr = { + .num_funcs = 3, + .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = TWOFISH_PARALLEL_BLOCKS, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_xway) } + }, { + .num_blocks = 3, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_3way) } + }, { + .num_blocks = 1, + .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr) } + } } +}; + +static const struct common_glue_ctx twofish_dec = { + .num_funcs = 3, + .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = TWOFISH_PARALLEL_BLOCKS, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_xway) } + }, { + .num_blocks = 3, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) } + }, { + .num_blocks = 1, + .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) } + } } +}; + +static const struct common_glue_ctx twofish_dec_cbc = { + .num_funcs = 3, + .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, + + .funcs = { { + .num_blocks = TWOFISH_PARALLEL_BLOCKS, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_xway) } + }, { + .num_blocks = 3, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) } + }, { + .num_blocks = 1, + .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) } + } } +}; + static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, true); + return glue_ecb_crypt_128bit(&twofish_enc, desc, dst, src, nbytes); } static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - struct blkcipher_walk walk; - - blkcipher_walk_init(&walk, dst, src, nbytes); - return ecb_crypt(desc, &walk, false); -} - -static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 *iv = (u128 *)walk->iv; - - do { - u128_xor(dst, src, iv); - twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst); - iv = dst; - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - - u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); - return nbytes; + return glue_ecb_crypt_128bit(&twofish_dec, desc, dst, src, nbytes); } static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - nbytes = __cbc_encrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ivs[TWOFISH_PARALLEL_BLOCKS - 1]; - u128 last_iv; - int i; - - /* Start of the last block. */ - src += nbytes / bsize - 1; - dst += nbytes / bsize - 1; - - last_iv = *src; - - /* Process multi-block batch */ - if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) { - do { - nbytes -= bsize * (TWOFISH_PARALLEL_BLOCKS - 1); - src -= TWOFISH_PARALLEL_BLOCKS - 1; - dst -= TWOFISH_PARALLEL_BLOCKS - 1; - - for (i = 0; i < TWOFISH_PARALLEL_BLOCKS - 1; i++) - ivs[i] = src[i]; - - twofish_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); - - for (i = 0; i < TWOFISH_PARALLEL_BLOCKS - 1; i++) - u128_xor(dst + (i + 1), dst + (i + 1), ivs + i); - - nbytes -= bsize; - if (nbytes < bsize) - goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Process three block batch */ - if (nbytes >= bsize * 3) { - do { - nbytes -= bsize * (3 - 1); - src -= 3 - 1; - dst -= 3 - 1; - - ivs[0] = src[0]; - ivs[1] = src[1]; - - twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); - - u128_xor(dst + 1, dst + 1, ivs + 0); - u128_xor(dst + 2, dst + 2, ivs + 1); - - nbytes -= bsize; - if (nbytes < bsize) - goto done; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } while (nbytes >= bsize * 3); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - for (;;) { - twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src); - - nbytes -= bsize; - if (nbytes < bsize) - break; - - u128_xor(dst, dst, src - 1); - src -= 1; - dst -= 1; - } - -done: - u128_xor(dst, dst, (u128 *)walk->iv); - *(u128 *)walk->iv = last_iv; - - return nbytes; + return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(twofish_enc_blk), desc, + dst, src, nbytes); } static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - bool fpu_enabled = false; - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes)) { - fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes); - nbytes = __cbc_decrypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - twofish_fpu_end(fpu_enabled); - return err; -} - -static inline void u128_to_be128(be128 *dst, const u128 *src) -{ - dst->a = cpu_to_be64(src->a); - dst->b = cpu_to_be64(src->b); + return glue_cbc_decrypt_128bit(&twofish_dec_cbc, desc, dst, src, + nbytes); } -static inline void be128_to_u128(u128 *dst, const be128 *src) -{ - dst->a = be64_to_cpu(src->a); - dst->b = be64_to_cpu(src->b); -} - -static inline void u128_inc(u128 *i) +static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - i->b++; - if (!i->b) - i->a++; + return glue_ctr_crypt_128bit(&twofish_ctr, desc, dst, src, nbytes); } -static void ctr_crypt_final(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) +static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes) { - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - u8 *ctrblk = walk->iv; - u8 keystream[TF_BLOCK_SIZE]; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - unsigned int nbytes = walk->nbytes; - - twofish_enc_blk(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); - - crypto_inc(ctrblk, TF_BLOCK_SIZE); + return glue_fpu_begin(TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS, NULL, + fpu_enabled, nbytes); } -static unsigned int __ctr_crypt(struct blkcipher_desc *desc, - struct blkcipher_walk *walk) -{ - struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = TF_BLOCK_SIZE; - unsigned int nbytes = walk->nbytes; - u128 *src = (u128 *)walk->src.virt.addr; - u128 *dst = (u128 *)walk->dst.virt.addr; - u128 ctrblk; - be128 ctrblocks[TWOFISH_PARALLEL_BLOCKS]; - int i; - - be128_to_u128(&ctrblk, (be128 *)walk->iv); - - /* Process multi-block batch */ - if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) { - do { - /* create ctrblks for parallel encrypt */ - for (i = 0; i < TWOFISH_PARALLEL_BLOCKS; i++) { - if (dst != src) - dst[i] = src[i]; - - u128_to_be128(&ctrblocks[i], &ctrblk); - u128_inc(&ctrblk); - } - - twofish_enc_blk_xway_xor(ctx, (u8 *)dst, - (u8 *)ctrblocks); - - src += TWOFISH_PARALLEL_BLOCKS; - dst += TWOFISH_PARALLEL_BLOCKS; - nbytes -= bsize * TWOFISH_PARALLEL_BLOCKS; - } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS); - - if (nbytes < bsize) - goto done; - } - - /* Process three block batch */ - if (nbytes >= bsize * 3) { - do { - if (dst != src) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - } - - /* create ctrblks for parallel encrypt */ - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - u128_to_be128(&ctrblocks[1], &ctrblk); - u128_inc(&ctrblk); - u128_to_be128(&ctrblocks[2], &ctrblk); - u128_inc(&ctrblk); - - twofish_enc_blk_3way_xor(ctx, (u8 *)dst, - (u8 *)ctrblocks); - - src += 3; - dst += 3; - nbytes -= bsize * 3; - } while (nbytes >= bsize * 3); - - if (nbytes < bsize) - goto done; - } - - /* Handle leftovers */ - do { - if (dst != src) - *dst = *src; - - u128_to_be128(&ctrblocks[0], &ctrblk); - u128_inc(&ctrblk); - - twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); - u128_xor(dst, dst, (u128 *)ctrblocks); - - src += 1; - dst += 1; - nbytes -= bsize; - } while (nbytes >= bsize); - -done: - u128_to_be128((be128 *)walk->iv, &ctrblk); - return nbytes; -} - -static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) +static inline void twofish_fpu_end(bool fpu_enabled) { - bool fpu_enabled = false; - struct blkcipher_walk walk; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) { - fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes); - nbytes = __ctr_crypt(desc, &walk); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - twofish_fpu_end(fpu_enabled); - - if (walk.nbytes) { - ctr_crypt_final(desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); - } - - return err; + glue_fpu_end(fpu_enabled); } struct crypt_priv { @@ -563,26 +262,6 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) twofish_dec_blk(ctx->ctx, srcdst, srcdst); } -struct twofish_lrw_ctx { - struct lrw_table_ctx lrw_table; - struct twofish_ctx twofish_ctx; -}; - -static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen) -{ - struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); - int err; - - err = __twofish_setkey(&ctx->twofish_ctx, key, - keylen - TF_BLOCK_SIZE, &tfm->crt_flags); - if (err) - return err; - - return lrw_init_table(&ctx->lrw_table, key + keylen - - TF_BLOCK_SIZE); -} - static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { @@ -635,43 +314,6 @@ static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, return ret; } -static void lrw_exit_tfm(struct crypto_tfm *tfm) -{ - struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); - - lrw_free_table(&ctx->lrw_table); -} - -struct twofish_xts_ctx { - struct twofish_ctx tweak_ctx; - struct twofish_ctx crypt_ctx; -}; - -static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen) -{ - struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); - u32 *flags = &tfm->crt_flags; - int err; - - /* key consists of keys of equal size concatenated, therefore - * the length must be even - */ - if (keylen % 2) { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; - } - - /* first half of xts-key is for crypt */ - err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); - if (err) - return err; - - /* second half of xts-key is for tweak */ - return __twofish_setkey(&ctx->tweak_ctx, - key + keylen / 2, keylen / 2, flags); -} - static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { @@ -798,7 +440,7 @@ static struct crypto_alg twofish_algs[10] = { { .cra_type = &crypto_blkcipher_type, .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(twofish_algs[3].cra_list), - .cra_exit = lrw_exit_tfm, + .cra_exit = lrw_twofish_exit_tfm, .cra_u = { .blkcipher = { .min_keysize = TF_MIN_KEY_SIZE + diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index 25bf5e9b0067..15f9347316c8 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c @@ -28,22 +28,12 @@ #include #include #include +#include #include #include #include -/* regular block cipher functions from twofish_x86_64 module */ -asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); - -/* 3-way parallel cipher functions */ -asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src, bool xor); EXPORT_SYMBOL_GPL(__twofish_enc_blk_3way); -asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); EXPORT_SYMBOL_GPL(twofish_dec_blk_3way); static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, @@ -58,7 +48,7 @@ static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst, __twofish_enc_blk_3way(ctx, dst, src, true); } -static void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src) +void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src) { u128 ivs[2]; @@ -70,8 +60,9 @@ static void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src) u128_xor(&dst[1], &dst[1], &ivs[0]); u128_xor(&dst[2], &dst[2], &ivs[1]); } +EXPORT_SYMBOL_GPL(twofish_dec_blk_cbc_3way); -static void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) +void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) { be128 ctrblk; @@ -84,8 +75,9 @@ static void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) twofish_enc_blk(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); u128_xor(dst, dst, (u128 *)&ctrblk); } +EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr); -static void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, +void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, u128 *iv) { be128 ctrblks[3]; @@ -105,6 +97,7 @@ static void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, twofish_enc_blk_xor_3way(ctx, (u8 *)dst, (u8 *)ctrblks); } +EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr_3way); static const struct common_glue_ctx twofish_enc = { .num_funcs = 2, @@ -220,13 +213,8 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) twofish_dec_blk(ctx, srcdst, srcdst); } -struct twofish_lrw_ctx { - struct lrw_table_ctx lrw_table; - struct twofish_ctx twofish_ctx; -}; - -static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen) +int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) { struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); int err; @@ -238,6 +226,7 @@ static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE); } +EXPORT_SYMBOL_GPL(lrw_twofish_setkey); static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) @@ -273,20 +262,16 @@ static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, return lrw_crypt(desc, dst, src, nbytes, &req); } -static void lrw_exit_tfm(struct crypto_tfm *tfm) +void lrw_twofish_exit_tfm(struct crypto_tfm *tfm) { struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); lrw_free_table(&ctx->lrw_table); } +EXPORT_SYMBOL_GPL(lrw_twofish_exit_tfm); -struct twofish_xts_ctx { - struct twofish_ctx tweak_ctx; - struct twofish_ctx crypt_ctx; -}; - -static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen) +int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) { struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); u32 *flags = &tfm->crt_flags; @@ -309,6 +294,7 @@ static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2, flags); } +EXPORT_SYMBOL_GPL(xts_twofish_setkey); static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) @@ -419,7 +405,7 @@ static struct crypto_alg tf_algs[5] = { { .cra_type = &crypto_blkcipher_type, .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(tf_algs[3].cra_list), - .cra_exit = lrw_exit_tfm, + .cra_exit = lrw_twofish_exit_tfm, .cra_u = { .blkcipher = { .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE, diff --git a/arch/x86/include/asm/crypto/twofish.h b/arch/x86/include/asm/crypto/twofish.h new file mode 100644 index 000000000000..9d2c514bd5f9 --- /dev/null +++ b/arch/x86/include/asm/crypto/twofish.h @@ -0,0 +1,46 @@ +#ifndef ASM_X86_TWOFISH_H +#define ASM_X86_TWOFISH_H + +#include +#include +#include +#include + +struct twofish_lrw_ctx { + struct lrw_table_ctx lrw_table; + struct twofish_ctx twofish_ctx; +}; + +struct twofish_xts_ctx { + struct twofish_ctx tweak_ctx; + struct twofish_ctx crypt_ctx; +}; + +/* regular block cipher functions from twofish_x86_64 module */ +asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); +asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); + +/* 3-way parallel cipher functions */ +asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src, bool xor); +asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, + const u8 *src); + +/* helpers from twofish_x86_64-3way module */ +extern void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src); +extern void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, + u128 *iv); +extern void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, + u128 *iv); + +extern int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen); + +extern void lrw_twofish_exit_tfm(struct crypto_tfm *tfm); + +extern int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen); + +#endif /* ASM_X86_TWOFISH_H */ diff --git a/crypto/Kconfig b/crypto/Kconfig index fc559caaa9ad..02e303774691 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -958,6 +958,7 @@ config CRYPTO_TWOFISH_AVX_X86_64 select CRYPTO_ALGAPI select CRYPTO_CRYPTD select CRYPTO_ABLK_HELPER_X86 + select CRYPTO_GLUE_HELPER_X86 select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 select CRYPTO_TWOFISH_X86_64_3WAY -- GitLab From d4af0e9d6eef6ce53c1935ca6ee3c01889e3212d Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:45 +0300 Subject: [PATCH 2985/6849] crypto: move arch/x86/include/asm/serpent-{sse2|avx}.h to arch/x86/include/asm/crypto/ Move serpent crypto headers to the new asm/crypto/ directory. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/serpent_avx_glue.c | 2 +- arch/x86/crypto/serpent_sse2_glue.c | 2 +- arch/x86/include/asm/{ => crypto}/serpent-avx.h | 0 arch/x86/include/asm/{ => crypto}/serpent-sse2.h | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename arch/x86/include/asm/{ => crypto}/serpent-avx.h (100%) rename arch/x86/include/asm/{ => crypto}/serpent-sse2.h (100%) diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c index c61b91aa42a8..b36bdac237eb 100644 --- a/arch/x86/crypto/serpent_avx_glue.c +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 49a32eedf0c8..d679c8675f4a 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/include/asm/serpent-avx.h b/arch/x86/include/asm/crypto/serpent-avx.h similarity index 100% rename from arch/x86/include/asm/serpent-avx.h rename to arch/x86/include/asm/crypto/serpent-avx.h diff --git a/arch/x86/include/asm/serpent-sse2.h b/arch/x86/include/asm/crypto/serpent-sse2.h similarity index 100% rename from arch/x86/include/asm/serpent-sse2.h rename to arch/x86/include/asm/crypto/serpent-sse2.h -- GitLab From 70ef2601feb09d40f4086d055700b7923b3c2d6f Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 18 Jun 2012 14:07:50 +0300 Subject: [PATCH 2986/6849] crypto: move arch/x86/include/asm/aes.h to arch/x86/include/asm/crypto/ Move AES header to the new asm/crypto directory. Signed-off-by: Jussi Kivilinna Signed-off-by: Herbert Xu --- arch/x86/crypto/aes_glue.c | 2 +- arch/x86/crypto/aesni-intel_glue.c | 2 +- arch/x86/include/asm/{ => crypto}/aes.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename arch/x86/include/asm/{ => crypto}/aes.h (100%) diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c index 8efcf42a9d7e..59b37deb8c8d 100644 --- a/arch/x86/crypto/aes_glue.c +++ b/arch/x86/crypto/aes_glue.c @@ -5,7 +5,7 @@ #include #include -#include +#include asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 7c9d54d8dc4d..d6626152067d 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/include/asm/aes.h b/arch/x86/include/asm/crypto/aes.h similarity index 100% rename from arch/x86/include/asm/aes.h rename to arch/x86/include/asm/crypto/aes.h -- GitLab From 70d793cc30a129d974363b4f3c22c9db6bbb18ed Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:42:35 -0500 Subject: [PATCH 2987/6849] crypto: caam - remove line continuations from ablkcipher_append_src_dst presumably leftovers from possible macro development. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 4eec389184d3..5c10dc5c0c51 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -143,11 +143,11 @@ static inline void aead_append_ld_iv(u32 *desc, int ivsize) */ static inline void ablkcipher_append_src_dst(u32 *desc) { - append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ); \ - append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); \ - append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | \ - KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1); \ - append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); \ + append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ); + append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | + KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1); + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); } /* -- GitLab From a68d2595876c7cc56f122572fa0a3465d438fefc Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:42:36 -0500 Subject: [PATCH 2988/6849] crypto: caam - fix input job ring element dma mapping size SEC4 h/w gets configured in 32- vs. 36-bit physical addressing modes depending on the size of dma_addr_t, which is not always equal to sizeof(u32 *). Also fixed alignment of a dma_unmap call whilst in there. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 340fa322c0f0..6ce4c41c8634 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -376,7 +376,7 @@ static int caam_jr_init(struct device *dev) /* Setup rings */ inpbusaddr = dma_map_single(dev, jrp->inpring, - sizeof(u32 *) * JOBR_DEPTH, + sizeof(dma_addr_t) * JOBR_DEPTH, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, inpbusaddr)) { dev_err(dev, "caam_jr_init(): can't map input ring\n"); @@ -391,9 +391,9 @@ static int caam_jr_init(struct device *dev) DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, outbusaddr)) { dev_err(dev, "caam_jr_init(): can't map output ring\n"); - dma_unmap_single(dev, inpbusaddr, - sizeof(u32 *) * JOBR_DEPTH, - DMA_BIDIRECTIONAL); + dma_unmap_single(dev, inpbusaddr, + sizeof(dma_addr_t) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); kfree(jrp->inpring); kfree(jrp->outring); kfree(jrp->entinfo); @@ -447,7 +447,7 @@ int caam_jr_shutdown(struct device *dev) dma_unmap_single(dev, outbusaddr, sizeof(struct jr_outentry) * JOBR_DEPTH, DMA_BIDIRECTIONAL); - dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, + dma_unmap_single(dev, inpbusaddr, sizeof(dma_addr_t) * JOBR_DEPTH, DMA_BIDIRECTIONAL); kfree(jrp->outring); kfree(jrp->inpring); -- GitLab From c4b664063ea5c007f05d2d23aa6edc9cfd385aa3 Mon Sep 17 00:00:00 2001 From: Yashpal Dutta Date: Fri, 22 Jun 2012 19:42:37 -0500 Subject: [PATCH 2989/6849] crypto: caam - fix start index for Protocol shared descriptors In case of protocol acceleration descriptors, Shared descriptor header must carry size of header length + PDB length in words which will be skipped by DECO while processing descriptor to provide first command word offset Signed-off-by: Yashpal Dutta Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/desc_constr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h index 348b882275f0..0d31e27b18ea 100644 --- a/drivers/crypto/caam/desc_constr.h +++ b/drivers/crypto/caam/desc_constr.h @@ -1,7 +1,7 @@ /* * caam descriptor construction helper functions * - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. */ #include "desc.h" @@ -64,7 +64,7 @@ static inline void init_sh_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes) { u32 pdb_len = pdb_bytes / CAAM_CMD_SZ + 1; - init_sh_desc(desc, ((pdb_len << HDR_START_IDX_SHIFT) + pdb_len) | + init_sh_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT) + pdb_len) | options); } -- GitLab From 991c569c5df68609b24a0aba5e5fd4879225c4cf Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:42:38 -0500 Subject: [PATCH 2990/6849] crypto: caam - fix descriptor length adjustments for protocol descriptors init_desc, by always ORing with 1 for the descriptor header inclusion into the descriptor length, and init_sh_desc_pdb, by always specifying the descriptor length modification for the PDB via options, would not allow for odd length PDBs to be embedded in the constructed descriptor length. Fix this by simply changing the OR to an addition. also round-up pdb_bytes to the next SEC command unit size, to allow for, e.g., optional packet header bytes that aren't a multiple of CAAM_CMD_SZ. Reported-by: Radu-Andrei BULIE Signed-off-by: Kim Phillips Cc: Yashpal Dutta Signed-off-by: Herbert Xu --- drivers/crypto/caam/desc_constr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h index 0d31e27b18ea..8e1056fac681 100644 --- a/drivers/crypto/caam/desc_constr.h +++ b/drivers/crypto/caam/desc_constr.h @@ -51,7 +51,7 @@ static inline void *sh_desc_pdb(u32 *desc) static inline void init_desc(u32 *desc, u32 options) { - *desc = options | HDR_ONE | 1; + *desc = (options | HDR_ONE) + 1; } static inline void init_sh_desc(u32 *desc, u32 options) @@ -62,7 +62,7 @@ static inline void init_sh_desc(u32 *desc, u32 options) static inline void init_sh_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes) { - u32 pdb_len = pdb_bytes / CAAM_CMD_SZ + 1; + u32 pdb_len = (pdb_bytes + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ; init_sh_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT) + pdb_len) | options); -- GitLab From a23d80e0b77314cc863a075796bc2b6d5245ba60 Mon Sep 17 00:00:00 2001 From: Hemant Agrawal Date: Fri, 22 Jun 2012 19:42:39 -0500 Subject: [PATCH 2991/6849] crypto: caam - add PDB (Protocol Descriptor Block) definitions Add a PDB header file to support building protocol descriptors. Signed-off-by: Steve Cornelius Signed-off-by: Hemant Agrawal Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/desc.h | 16 -- drivers/crypto/caam/pdb.h | 401 +++++++++++++++++++++++++++++++++++++ 2 files changed, 401 insertions(+), 16 deletions(-) create mode 100644 drivers/crypto/caam/pdb.h diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h index a17c2958dab1..af25e76c5f7c 100644 --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -1585,20 +1585,4 @@ #define NFIFOENTRY_PLEN_SHIFT 0 #define NFIFOENTRY_PLEN_MASK (0xFF << NFIFOENTRY_PLEN_SHIFT) -/* - * PDB internal definitions - */ - -/* IPSec ESP CBC Encap/Decap Options */ -#define PDBOPTS_ESPCBC_ARSNONE 0x00 /* no antireplay window */ -#define PDBOPTS_ESPCBC_ARS32 0x40 /* 32-entry antireplay window */ -#define PDBOPTS_ESPCBC_ARS64 0xc0 /* 64-entry antireplay window */ -#define PDBOPTS_ESPCBC_IVSRC 0x20 /* IV comes from internal random gen */ -#define PDBOPTS_ESPCBC_ESN 0x10 /* extended sequence included */ -#define PDBOPTS_ESPCBC_OUTFMT 0x08 /* output only decapsulation (decap) */ -#define PDBOPTS_ESPCBC_IPHDRSRC 0x08 /* IP header comes from PDB (encap) */ -#define PDBOPTS_ESPCBC_INCIPHDR 0x04 /* Prepend IP header to output frame */ -#define PDBOPTS_ESPCBC_IPVSN 0x02 /* process IPv6 header */ -#define PDBOPTS_ESPCBC_TUNNEL 0x01 /* tunnel mode next-header byte */ - #endif /* DESC_H */ diff --git a/drivers/crypto/caam/pdb.h b/drivers/crypto/caam/pdb.h new file mode 100644 index 000000000000..62950d22ac13 --- /dev/null +++ b/drivers/crypto/caam/pdb.h @@ -0,0 +1,401 @@ +/* + * CAAM Protocol Data Block (PDB) definition header file + * + * Copyright 2008-2012 Freescale Semiconductor, Inc. + * + */ + +#ifndef CAAM_PDB_H +#define CAAM_PDB_H + +/* + * PDB- IPSec ESP Header Modification Options + */ +#define PDBHMO_ESP_DECAP_SHIFT 12 +#define PDBHMO_ESP_ENCAP_SHIFT 4 +/* + * Encap and Decap - Decrement TTL (Hop Limit) - Based on the value of the + * Options Byte IP version (IPvsn) field: + * if IPv4, decrement the inner IP header TTL field (byte 8); + * if IPv6 decrement the inner IP header Hop Limit field (byte 7). +*/ +#define PDBHMO_ESP_DECAP_DEC_TTL (0x02 << PDBHMO_ESP_DECAP_SHIFT) +#define PDBHMO_ESP_ENCAP_DEC_TTL (0x02 << PDBHMO_ESP_ENCAP_SHIFT) +/* + * Decap - DiffServ Copy - Copy the IPv4 TOS or IPv6 Traffic Class byte + * from the outer IP header to the inner IP header. + */ +#define PDBHMO_ESP_DIFFSERV (0x01 << PDBHMO_ESP_DECAP_SHIFT) +/* + * Encap- Copy DF bit -if an IPv4 tunnel mode outer IP header is coming from + * the PDB, copy the DF bit from the inner IP header to the outer IP header. + */ +#define PDBHMO_ESP_DFBIT (0x04 << PDBHMO_ESP_ENCAP_SHIFT) + +/* + * PDB - IPSec ESP Encap/Decap Options + */ +#define PDBOPTS_ESP_ARSNONE 0x00 /* no antireplay window */ +#define PDBOPTS_ESP_ARS32 0x40 /* 32-entry antireplay window */ +#define PDBOPTS_ESP_ARS64 0xc0 /* 64-entry antireplay window */ +#define PDBOPTS_ESP_IVSRC 0x20 /* IV comes from internal random gen */ +#define PDBOPTS_ESP_ESN 0x10 /* extended sequence included */ +#define PDBOPTS_ESP_OUTFMT 0x08 /* output only decapsulation (decap) */ +#define PDBOPTS_ESP_IPHDRSRC 0x08 /* IP header comes from PDB (encap) */ +#define PDBOPTS_ESP_INCIPHDR 0x04 /* Prepend IP header to output frame */ +#define PDBOPTS_ESP_IPVSN 0x02 /* process IPv6 header */ +#define PDBOPTS_ESP_TUNNEL 0x01 /* tunnel mode next-header byte */ +#define PDBOPTS_ESP_IPV6 0x02 /* ip header version is V6 */ +#define PDBOPTS_ESP_DIFFSERV 0x40 /* copy TOS/TC from inner iphdr */ +#define PDBOPTS_ESP_UPDATE_CSUM 0x80 /* encap-update ip header checksum */ +#define PDBOPTS_ESP_VERIFY_CSUM 0x20 /* decap-validate ip header checksum */ + +/* + * General IPSec encap/decap PDB definitions + */ +struct ipsec_encap_cbc { + u32 iv[4]; +}; + +struct ipsec_encap_ctr { + u32 ctr_nonce; + u32 ctr_initial; + u32 iv[2]; +}; + +struct ipsec_encap_ccm { + u32 salt; /* lower 24 bits */ + u8 b0_flags; + u8 ctr_flags; + u16 ctr_initial; + u32 iv[2]; +}; + +struct ipsec_encap_gcm { + u32 salt; /* lower 24 bits */ + u32 rsvd1; + u32 iv[2]; +}; + +struct ipsec_encap_pdb { + u8 hmo_rsvd; + u8 ip_nh; + u8 ip_nh_offset; + u8 options; + u32 seq_num_ext_hi; + u32 seq_num; + union { + struct ipsec_encap_cbc cbc; + struct ipsec_encap_ctr ctr; + struct ipsec_encap_ccm ccm; + struct ipsec_encap_gcm gcm; + }; + u32 spi; + u16 rsvd1; + u16 ip_hdr_len; + u32 ip_hdr[0]; /* optional IP Header content */ +}; + +struct ipsec_decap_cbc { + u32 rsvd[2]; +}; + +struct ipsec_decap_ctr { + u32 salt; + u32 ctr_initial; +}; + +struct ipsec_decap_ccm { + u32 salt; + u8 iv_flags; + u8 ctr_flags; + u16 ctr_initial; +}; + +struct ipsec_decap_gcm { + u32 salt; + u32 resvd; +}; + +struct ipsec_decap_pdb { + u16 hmo_ip_hdr_len; + u8 ip_nh_offset; + u8 options; + union { + struct ipsec_decap_cbc cbc; + struct ipsec_decap_ctr ctr; + struct ipsec_decap_ccm ccm; + struct ipsec_decap_gcm gcm; + }; + u32 seq_num_ext_hi; + u32 seq_num; + u32 anti_replay[2]; + u32 end_index[0]; +}; + +/* + * IPSec ESP Datapath Protocol Override Register (DPOVRD) + */ +struct ipsec_deco_dpovrd { +#define IPSEC_ENCAP_DECO_DPOVRD_USE 0x80 + u8 ovrd_ecn; + u8 ip_hdr_len; + u8 nh_offset; + u8 next_header; /* reserved if decap */ +}; + +/* + * IEEE 802.11i WiFi Protocol Data Block + */ +#define WIFI_PDBOPTS_FCS 0x01 +#define WIFI_PDBOPTS_AR 0x40 + +struct wifi_encap_pdb { + u16 mac_hdr_len; + u8 rsvd; + u8 options; + u8 iv_flags; + u8 pri; + u16 pn1; + u32 pn2; + u16 frm_ctrl_mask; + u16 seq_ctrl_mask; + u8 rsvd1[2]; + u8 cnst; + u8 key_id; + u8 ctr_flags; + u8 rsvd2; + u16 ctr_init; +}; + +struct wifi_decap_pdb { + u16 mac_hdr_len; + u8 rsvd; + u8 options; + u8 iv_flags; + u8 pri; + u16 pn1; + u32 pn2; + u16 frm_ctrl_mask; + u16 seq_ctrl_mask; + u8 rsvd1[4]; + u8 ctr_flags; + u8 rsvd2; + u16 ctr_init; +}; + +/* + * IEEE 802.16 WiMAX Protocol Data Block + */ +#define WIMAX_PDBOPTS_FCS 0x01 +#define WIMAX_PDBOPTS_AR 0x40 /* decap only */ + +struct wimax_encap_pdb { + u8 rsvd[3]; + u8 options; + u32 nonce; + u8 b0_flags; + u8 ctr_flags; + u16 ctr_init; + /* begin DECO writeback region */ + u32 pn; + /* end DECO writeback region */ +}; + +struct wimax_decap_pdb { + u8 rsvd[3]; + u8 options; + u32 nonce; + u8 iv_flags; + u8 ctr_flags; + u16 ctr_init; + /* begin DECO writeback region */ + u32 pn; + u8 rsvd1[2]; + u16 antireplay_len; + u64 antireplay_scorecard; + /* end DECO writeback region */ +}; + +/* + * IEEE 801.AE MacSEC Protocol Data Block + */ +#define MACSEC_PDBOPTS_FCS 0x01 +#define MACSEC_PDBOPTS_AR 0x40 /* used in decap only */ + +struct macsec_encap_pdb { + u16 aad_len; + u8 rsvd; + u8 options; + u64 sci; + u16 ethertype; + u8 tci_an; + u8 rsvd1; + /* begin DECO writeback region */ + u32 pn; + /* end DECO writeback region */ +}; + +struct macsec_decap_pdb { + u16 aad_len; + u8 rsvd; + u8 options; + u64 sci; + u8 rsvd1[3]; + /* begin DECO writeback region */ + u8 antireplay_len; + u32 pn; + u64 antireplay_scorecard; + /* end DECO writeback region */ +}; + +/* + * SSL/TLS/DTLS Protocol Data Blocks + */ + +#define TLS_PDBOPTS_ARS32 0x40 +#define TLS_PDBOPTS_ARS64 0xc0 +#define TLS_PDBOPTS_OUTFMT 0x08 +#define TLS_PDBOPTS_IV_WRTBK 0x02 /* 1.1/1.2/DTLS only */ +#define TLS_PDBOPTS_EXP_RND_IV 0x01 /* 1.1/1.2/DTLS only */ + +struct tls_block_encap_pdb { + u8 type; + u8 version[2]; + u8 options; + u64 seq_num; + u32 iv[4]; +}; + +struct tls_stream_encap_pdb { + u8 type; + u8 version[2]; + u8 options; + u64 seq_num; + u8 i; + u8 j; + u8 rsvd1[2]; +}; + +struct dtls_block_encap_pdb { + u8 type; + u8 version[2]; + u8 options; + u16 epoch; + u16 seq_num[3]; + u32 iv[4]; +}; + +struct tls_block_decap_pdb { + u8 rsvd[3]; + u8 options; + u64 seq_num; + u32 iv[4]; +}; + +struct tls_stream_decap_pdb { + u8 rsvd[3]; + u8 options; + u64 seq_num; + u8 i; + u8 j; + u8 rsvd1[2]; +}; + +struct dtls_block_decap_pdb { + u8 rsvd[3]; + u8 options; + u16 epoch; + u16 seq_num[3]; + u32 iv[4]; + u64 antireplay_scorecard; +}; + +/* + * SRTP Protocol Data Blocks + */ +#define SRTP_PDBOPTS_MKI 0x08 +#define SRTP_PDBOPTS_AR 0x40 + +struct srtp_encap_pdb { + u8 x_len; + u8 mki_len; + u8 n_tag; + u8 options; + u32 cnst0; + u8 rsvd[2]; + u16 cnst1; + u16 salt[7]; + u16 cnst2; + u32 rsvd1; + u32 roc; + u32 opt_mki; +}; + +struct srtp_decap_pdb { + u8 x_len; + u8 mki_len; + u8 n_tag; + u8 options; + u32 cnst0; + u8 rsvd[2]; + u16 cnst1; + u16 salt[7]; + u16 cnst2; + u16 rsvd1; + u16 seq_num; + u32 roc; + u64 antireplay_scorecard; +}; + +/* + * DSA/ECDSA Protocol Data Blocks + * Two of these exist: DSA-SIGN, and DSA-VERIFY. They are similar + * except for the treatment of "w" for verify, "s" for sign, + * and the placement of "a,b". + */ +#define DSA_PDB_SGF_SHIFT 24 +#define DSA_PDB_SGF_MASK (0xff << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_Q (0x80 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_R (0x40 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_G (0x20 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_W (0x10 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_S (0x10 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_F (0x08 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_C (0x04 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_D (0x02 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_AB_SIGN (0x02 << DSA_PDB_SGF_SHIFT) +#define DSA_PDB_SGF_AB_VERIFY (0x01 << DSA_PDB_SGF_SHIFT) + +#define DSA_PDB_L_SHIFT 7 +#define DSA_PDB_L_MASK (0x3ff << DSA_PDB_L_SHIFT) + +#define DSA_PDB_N_MASK 0x7f + +struct dsa_sign_pdb { + u32 sgf_ln; /* Use DSA_PDB_ defintions per above */ + u8 *q; + u8 *r; + u8 *g; /* or Gx,y */ + u8 *s; + u8 *f; + u8 *c; + u8 *d; + u8 *ab; /* ECC only */ + u8 *u; +}; + +struct dsa_verify_pdb { + u32 sgf_ln; + u8 *q; + u8 *r; + u8 *g; /* or Gx,y */ + u8 *w; /* or Wx,y */ + u8 *f; + u8 *c; + u8 *d; + u8 *tmp; /* temporary data block */ + u8 *ab; /* only used if ECC processing */ +}; + +#endif -- GitLab From 6ec47334935ffbc3eccc227ed22ab716be9942f1 Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:43 -0500 Subject: [PATCH 2992/6849] crypto: caam - support external seq in/out lengths functions for external storage of seq in/out lengths, i.e., for 32-bit lengths. These type-dependent functions automatically determine whether to store the length internally (embedded in the command header word) or externally (after the address pointer), based on size of the type given. Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 5 ++-- drivers/crypto/caam/desc_constr.h | 49 +++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 5c10dc5c0c51..d0f8df1dcec3 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -37,9 +37,10 @@ * | ShareDesc Pointer | * | SEQ_OUT_PTR | * | (output buffer) | + * | (output length) | * | SEQ_IN_PTR | * | (input buffer) | - * | LOAD (to DECO) | + * | (input length) | * --------------------- */ @@ -62,7 +63,7 @@ #define CAAM_MAX_IV_LENGTH 16 /* length of descriptors text */ -#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 3 + CAAM_PTR_SZ * 3) +#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3) #define DESC_AEAD_BASE (4 * CAAM_CMD_SZ) #define DESC_AEAD_ENC_LEN (DESC_AEAD_BASE + 16 * CAAM_CMD_SZ) diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h index 8e1056fac681..c85c1f058401 100644 --- a/drivers/crypto/caam/desc_constr.h +++ b/drivers/crypto/caam/desc_constr.h @@ -117,6 +117,15 @@ static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len, append_ptr(desc, ptr); } +/* Write length after pointer, rather than inside command */ +static inline void append_cmd_ptr_extlen(u32 *desc, dma_addr_t ptr, + unsigned int len, u32 command) +{ + append_cmd(desc, command); + append_ptr(desc, ptr); + append_cmd(desc, len); +} + static inline void append_cmd_data(u32 *desc, void *data, int len, u32 command) { @@ -166,13 +175,22 @@ static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \ append_cmd_ptr(desc, ptr, len, CMD_##op | options); \ } APPEND_CMD_PTR(key, KEY) -APPEND_CMD_PTR(seq_in_ptr, SEQ_IN_PTR) -APPEND_CMD_PTR(seq_out_ptr, SEQ_OUT_PTR) APPEND_CMD_PTR(load, LOAD) APPEND_CMD_PTR(store, STORE) APPEND_CMD_PTR(fifo_load, FIFO_LOAD) APPEND_CMD_PTR(fifo_store, FIFO_STORE) +#define APPEND_SEQ_PTR_INTLEN(cmd, op) \ +static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, dma_addr_t ptr, \ + unsigned int len, \ + u32 options) \ +{ \ + PRINT_POS; \ + append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \ +} +APPEND_SEQ_PTR_INTLEN(in, IN) +APPEND_SEQ_PTR_INTLEN(out, OUT) + #define APPEND_CMD_PTR_TO_IMM(cmd, op) \ static inline void append_##cmd##_as_imm(u32 *desc, void *data, \ unsigned int len, u32 options) \ @@ -183,6 +201,33 @@ static inline void append_##cmd##_as_imm(u32 *desc, void *data, \ APPEND_CMD_PTR_TO_IMM(load, LOAD); APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD); +#define APPEND_CMD_PTR_EXTLEN(cmd, op) \ +static inline void append_##cmd##_extlen(u32 *desc, dma_addr_t ptr, \ + unsigned int len, u32 options) \ +{ \ + PRINT_POS; \ + append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \ +} +APPEND_CMD_PTR_EXTLEN(seq_in_ptr, SEQ_IN_PTR) +APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR) + +/* + * Determine whether to store length internally or externally depending on + * the size of its type + */ +#define APPEND_CMD_PTR_LEN(cmd, op, type) \ +static inline void append_##cmd(u32 *desc, dma_addr_t ptr, \ + type len, u32 options) \ +{ \ + PRINT_POS; \ + if (sizeof(type) > sizeof(u16)) \ + append_##cmd##_extlen(desc, ptr, len, options); \ + else \ + append_##cmd##_intlen(desc, ptr, len, options); \ +} +APPEND_CMD_PTR_LEN(seq_in_ptr, SEQ_IN_PTR, u32) +APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_PTR, u32) + /* * 2nd variant for commands whose specified immediate length differs * from length of immediate data provided, e.g., split keys -- GitLab From 8009a383f28e853df1a1b08d405ccf67ba860fcc Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:44 -0500 Subject: [PATCH 2993/6849] crypto: caam - remove jr register/deregister remove caam_jr_register and caam_jr_deregister to allow sharing of job rings. Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 30 ++---------------------------- drivers/crypto/caam/intern.h | 2 -- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index d0f8df1dcec3..a4e266f928c2 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -2228,7 +2228,7 @@ static int caam_cra_init(struct crypto_tfm *tfm) * distribute tfms across job rings to ensure in-order * crypto request processing per tfm */ - ctx->jrdev = priv->algapi_jr[(tgt_jr / 2) % priv->num_jrs_for_algapi]; + ctx->jrdev = priv->jrdev[(tgt_jr / 2) % priv->total_jobrs]; /* copy descriptor header template value */ ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type; @@ -2265,7 +2265,6 @@ static void __exit caam_algapi_exit(void) struct device *ctrldev; struct caam_drv_private *priv; struct caam_crypto_alg *t_alg, *n; - int i, err; dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); if (!dev_node) { @@ -2290,13 +2289,6 @@ static void __exit caam_algapi_exit(void) list_del(&t_alg->entry); kfree(t_alg); } - - for (i = 0; i < priv->total_jobrs; i++) { - err = caam_jr_deregister(priv->algapi_jr[i]); - if (err < 0) - break; - } - kfree(priv->algapi_jr); } static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev, @@ -2349,7 +2341,7 @@ static int __init caam_algapi_init(void) { struct device_node *dev_node; struct platform_device *pdev; - struct device *ctrldev, **jrdev; + struct device *ctrldev; struct caam_drv_private *priv; int i = 0, err = 0; @@ -2370,24 +2362,6 @@ static int __init caam_algapi_init(void) INIT_LIST_HEAD(&priv->alg_list); - jrdev = kmalloc(sizeof(*jrdev) * priv->total_jobrs, GFP_KERNEL); - if (!jrdev) - return -ENOMEM; - - for (i = 0; i < priv->total_jobrs; i++) { - err = caam_jr_register(ctrldev, &jrdev[i]); - if (err < 0) - break; - } - if (err < 0 && i == 0) { - dev_err(ctrldev, "algapi error in job ring registration: %d\n", - err); - kfree(jrdev); - return err; - } - - priv->num_jrs_for_algapi = i; - priv->algapi_jr = jrdev; atomic_set(&priv->tfm_count, -1); /* register crypto algorithms the device supports */ diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index a34be01b0b29..462be99d9a3c 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -86,8 +86,6 @@ struct caam_drv_private { /* which jr allocated to scatterlist crypto */ atomic_t tfm_count ____cacheline_aligned; - int num_jrs_for_algapi; - struct device **algapi_jr; /* list of registered crypto algorithms (mk generic context handle?) */ struct list_head alg_list; -- GitLab From 4c1ec1f9301549db229bc6dce916f8a99d1f82d6 Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:45 -0500 Subject: [PATCH 2994/6849] crypto: caam - refactor key_gen, sg create separate files for split key generation and scatterlist functions. Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/Makefile | 2 +- drivers/crypto/caam/caamalg.c | 197 ++---------------------------- drivers/crypto/caam/desc.h | 10 ++ drivers/crypto/caam/key_gen.c | 122 ++++++++++++++++++ drivers/crypto/caam/key_gen.h | 17 +++ drivers/crypto/caam/sg_link_tbl.h | 84 +++++++++++++ 6 files changed, 242 insertions(+), 190 deletions(-) create mode 100644 drivers/crypto/caam/key_gen.c create mode 100644 drivers/crypto/caam/key_gen.h create mode 100644 drivers/crypto/caam/sg_link_tbl.h diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile index ef39011b4505..4447e5748c43 100644 --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o -caam-objs := ctrl.o jr.o error.o +caam-objs := ctrl.o jr.o error.o key_gen.o diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index a4e266f928c2..ea0295d137a7 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -51,6 +51,8 @@ #include "desc_constr.h" #include "jr.h" #include "error.h" +#include "sg_link_tbl.h" +#include "key_gen.h" /* * crypto alg @@ -453,121 +455,12 @@ static int aead_setauthsize(struct crypto_aead *authenc, return 0; } -struct split_key_result { - struct completion completion; - int err; -}; - -static void split_key_done(struct device *dev, u32 *desc, u32 err, - void *context) +static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in, + u32 authkeylen) { - struct split_key_result *res = context; - -#ifdef DEBUG - dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); -#endif - - if (err) { - char tmp[CAAM_ERROR_STR_MAX]; - - dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); - } - - res->err = err; - - complete(&res->completion); -} - -/* -get a split ipad/opad key - -Split key generation----------------------------------------------- - -[00] 0xb0810008 jobdesc: stidx=1 share=never len=8 -[01] 0x04000014 key: class2->keyreg len=20 - @0xffe01000 -[03] 0x84410014 operation: cls2-op sha1 hmac init dec -[04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm -[05] 0xa4000001 jump: class2 local all ->1 [06] -[06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 - @0xffe04000 -*/ -static u32 gen_split_key(struct caam_ctx *ctx, const u8 *key_in, u32 authkeylen) -{ - struct device *jrdev = ctx->jrdev; - u32 *desc; - struct split_key_result result; - dma_addr_t dma_addr_in, dma_addr_out; - int ret = 0; - - desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); - - init_job_desc(desc, 0); - - dma_addr_in = dma_map_single(jrdev, (void *)key_in, authkeylen, - DMA_TO_DEVICE); - if (dma_mapping_error(jrdev, dma_addr_in)) { - dev_err(jrdev, "unable to map key input memory\n"); - kfree(desc); - return -ENOMEM; - } - append_key(desc, dma_addr_in, authkeylen, CLASS_2 | - KEY_DEST_CLASS_REG); - - /* Sets MDHA up into an HMAC-INIT */ - append_operation(desc, ctx->alg_op | OP_ALG_DECRYPT | - OP_ALG_AS_INIT); - - /* - * do a FIFO_LOAD of zero, this will trigger the internal key expansion - into both pads inside MDHA - */ - append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | - FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); - - /* - * FIFO_STORE with the explicit split-key content store - * (0x26 output type) - */ - dma_addr_out = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len, - DMA_FROM_DEVICE); - if (dma_mapping_error(jrdev, dma_addr_out)) { - dev_err(jrdev, "unable to map key output memory\n"); - kfree(desc); - return -ENOMEM; - } - append_fifo_store(desc, dma_addr_out, ctx->split_key_len, - LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); - -#ifdef DEBUG - print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, key_in, authkeylen, 1); - print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); -#endif - - result.err = 0; - init_completion(&result.completion); - - ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); - if (!ret) { - /* in progress */ - wait_for_completion_interruptible(&result.completion); - ret = result.err; -#ifdef DEBUG - print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, - ctx->split_key_pad_len, 1); -#endif - } - - dma_unmap_single(jrdev, dma_addr_out, ctx->split_key_pad_len, - DMA_FROM_DEVICE); - dma_unmap_single(jrdev, dma_addr_in, authkeylen, DMA_TO_DEVICE); - - kfree(desc); - - return ret; + return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len, + ctx->split_key_pad_len, key_in, authkeylen, + ctx->alg_op); } static int aead_setkey(struct crypto_aead *aead, @@ -611,7 +504,7 @@ static int aead_setkey(struct crypto_aead *aead, DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); #endif - ret = gen_split_key(ctx, key, authkeylen); + ret = gen_split_aead_key(ctx, key, authkeylen); if (ret) { goto badkey; } @@ -758,14 +651,6 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, return ret; } -struct link_tbl_entry { - u64 ptr; - u32 len; - u8 reserved; - u8 buf_pool_id; - u16 offset; -}; - /* * aead_edesc - s/w-extended aead descriptor * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist @@ -1027,50 +912,6 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err, ablkcipher_request_complete(req, err); } -static void sg_to_link_tbl_one(struct link_tbl_entry *link_tbl_ptr, - dma_addr_t dma, u32 len, u32 offset) -{ - link_tbl_ptr->ptr = dma; - link_tbl_ptr->len = len; - link_tbl_ptr->reserved = 0; - link_tbl_ptr->buf_pool_id = 0; - link_tbl_ptr->offset = offset; -#ifdef DEBUG - print_hex_dump(KERN_ERR, "link_tbl_ptr@"xstr(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, link_tbl_ptr, - sizeof(struct link_tbl_entry), 1); -#endif -} - -/* - * convert scatterlist to h/w link table format - * but does not have final bit; instead, returns last entry - */ -static struct link_tbl_entry *sg_to_link_tbl(struct scatterlist *sg, - int sg_count, struct link_tbl_entry - *link_tbl_ptr, u32 offset) -{ - while (sg_count) { - sg_to_link_tbl_one(link_tbl_ptr, sg_dma_address(sg), - sg_dma_len(sg), offset); - link_tbl_ptr++; - sg = sg_next(sg); - sg_count--; - } - return link_tbl_ptr - 1; -} - -/* - * convert scatterlist to h/w link table format - * scatterlist must have been previously dma mapped - */ -static void sg_to_link_tbl_last(struct scatterlist *sg, int sg_count, - struct link_tbl_entry *link_tbl_ptr, u32 offset) -{ - link_tbl_ptr = sg_to_link_tbl(sg, sg_count, link_tbl_ptr, offset); - link_tbl_ptr->len |= 0x40000000; -} - /* * Fill in aead job descriptor */ @@ -1271,28 +1112,6 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr, append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options); } -/* - * derive number of elements in scatterlist - */ -static int sg_count(struct scatterlist *sg_list, int nbytes) -{ - struct scatterlist *sg = sg_list; - int sg_nents = 0; - - while (nbytes > 0) { - sg_nents++; - nbytes -= sg->length; - if (!sg_is_last(sg) && (sg + 1)->length == 0) - BUG(); /* Not support chaining */ - sg = scatterwalk_sg_next(sg); - } - - if (likely(sg_nents == 1)) - return 0; - - return sg_nents; -} - /* * allocate and map the aead extended descriptor */ diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h index af25e76c5f7c..48c1927dbf21 100644 --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -8,6 +8,16 @@ #ifndef DESC_H #define DESC_H +struct link_tbl_entry { + u64 ptr; +#define LINK_TBL_LEN_FIN 0x40000000 +#define LINK_TBL_LEN_EXT 0x80000000 + u32 len; + u8 reserved; + u8 buf_pool_id; + u16 offset; +}; + /* Max size of any CAAM descriptor in 32-bit words, inclusive of header */ #define MAX_CAAM_DESCSIZE 64 diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c new file mode 100644 index 000000000000..002888185f17 --- /dev/null +++ b/drivers/crypto/caam/key_gen.c @@ -0,0 +1,122 @@ +/* + * CAAM/SEC 4.x functions for handling key-generation jobs + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + */ +#include "compat.h" +#include "jr.h" +#include "error.h" +#include "desc_constr.h" +#include "key_gen.h" + +void split_key_done(struct device *dev, u32 *desc, u32 err, + void *context) +{ + struct split_key_result *res = context; + +#ifdef DEBUG + dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + res->err = err; + + complete(&res->completion); +} +EXPORT_SYMBOL(split_key_done); +/* +get a split ipad/opad key + +Split key generation----------------------------------------------- + +[00] 0xb0810008 jobdesc: stidx=1 share=never len=8 +[01] 0x04000014 key: class2->keyreg len=20 + @0xffe01000 +[03] 0x84410014 operation: cls2-op sha1 hmac init dec +[04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm +[05] 0xa4000001 jump: class2 local all ->1 [06] +[06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 + @0xffe04000 +*/ +u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, + int split_key_pad_len, const u8 *key_in, u32 keylen, + u32 alg_op) +{ + u32 *desc; + struct split_key_result result; + dma_addr_t dma_addr_in, dma_addr_out; + int ret = 0; + + desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); + + init_job_desc(desc, 0); + + dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, dma_addr_in)) { + dev_err(jrdev, "unable to map key input memory\n"); + kfree(desc); + return -ENOMEM; + } + append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG); + + /* Sets MDHA up into an HMAC-INIT */ + append_operation(desc, alg_op | OP_ALG_DECRYPT | OP_ALG_AS_INIT); + + /* + * do a FIFO_LOAD of zero, this will trigger the internal key expansion + * into both pads inside MDHA + */ + append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); + + /* + * FIFO_STORE with the explicit split-key content store + * (0x26 output type) + */ + dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len, + DMA_FROM_DEVICE); + if (dma_mapping_error(jrdev, dma_addr_out)) { + dev_err(jrdev, "unable to map key output memory\n"); + kfree(desc); + return -ENOMEM; + } + append_fifo_store(desc, dma_addr_out, split_key_len, + LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1); + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + result.err = 0; + init_completion(&result.completion); + + ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); + if (!ret) { + /* in progress */ + wait_for_completion_interruptible(&result.completion); + ret = result.err; +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key_out, + split_key_pad_len, 1); +#endif + } + + dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len, + DMA_FROM_DEVICE); + dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE); + + kfree(desc); + + return ret; +} diff --git a/drivers/crypto/caam/key_gen.h b/drivers/crypto/caam/key_gen.h new file mode 100644 index 000000000000..d95d290c6e8b --- /dev/null +++ b/drivers/crypto/caam/key_gen.h @@ -0,0 +1,17 @@ +/* + * CAAM/SEC 4.x definitions for handling key-generation jobs + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + */ + +struct split_key_result { + struct completion completion; + int err; +}; + +void split_key_done(struct device *dev, u32 *desc, u32 err, void *context); + +u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, + int split_key_pad_len, const u8 *key_in, u32 keylen, + u32 alg_op); diff --git a/drivers/crypto/caam/sg_link_tbl.h b/drivers/crypto/caam/sg_link_tbl.h new file mode 100644 index 000000000000..6df434922460 --- /dev/null +++ b/drivers/crypto/caam/sg_link_tbl.h @@ -0,0 +1,84 @@ +/* + * CAAM/SEC 4.x functions for using scatterlists in caam driver + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + */ + +struct link_tbl_entry; + +/* + * convert single dma address to h/w link table format + */ +static inline void sg_to_link_tbl_one(struct link_tbl_entry *link_tbl_ptr, + dma_addr_t dma, u32 len, u32 offset) +{ + link_tbl_ptr->ptr = dma; + link_tbl_ptr->len = len; + link_tbl_ptr->reserved = 0; + link_tbl_ptr->buf_pool_id = 0; + link_tbl_ptr->offset = offset; +#ifdef DEBUG + print_hex_dump(KERN_ERR, "link_tbl_ptr@: ", + DUMP_PREFIX_ADDRESS, 16, 4, link_tbl_ptr, + sizeof(struct link_tbl_entry), 1); +#endif +} + +/* + * convert scatterlist to h/w link table format + * but does not have final bit; instead, returns last entry + */ +static inline struct link_tbl_entry * +sg_to_link_tbl(struct scatterlist *sg, int sg_count, + struct link_tbl_entry *link_tbl_ptr, u32 offset) +{ + while (sg_count) { + sg_to_link_tbl_one(link_tbl_ptr, sg_dma_address(sg), + sg_dma_len(sg), offset); + link_tbl_ptr++; + sg = sg_next(sg); + sg_count--; + } + return link_tbl_ptr - 1; +} + +/* + * convert scatterlist to h/w link table format + * scatterlist must have been previously dma mapped + */ +static inline void sg_to_link_tbl_last(struct scatterlist *sg, int sg_count, + struct link_tbl_entry *link_tbl_ptr, + u32 offset) +{ + link_tbl_ptr = sg_to_link_tbl(sg, sg_count, link_tbl_ptr, offset); + link_tbl_ptr->len |= LINK_TBL_LEN_FIN; +} + +/* count number of elements in scatterlist */ +static inline int __sg_count(struct scatterlist *sg_list, int nbytes) +{ + struct scatterlist *sg = sg_list; + int sg_nents = 0; + + while (nbytes > 0) { + sg_nents++; + nbytes -= sg->length; + if (!sg_is_last(sg) && (sg + 1)->length == 0) + BUG(); /* Not support chaining */ + sg = scatterwalk_sg_next(sg); + } + + return sg_nents; +} + +/* derive number of elements in scatterlist, but return 0 for 1 */ +static inline int sg_count(struct scatterlist *sg_list, int nbytes) +{ + int sg_nents = __sg_count(sg_list, nbytes); + + if (likely(sg_nents == 1)) + return 0; + + return sg_nents; +} -- GitLab From a299c837040bb47810b9d287dfe7deed6a254995 Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:46 -0500 Subject: [PATCH 2995/6849] crypto: caam - link_tbl rename - rename scatterlist and link_tbl functions - link_tbl changed to sec4_sg - sg_to_link_tbl_one changed to dma_to_sec4_sg_one, since no scatterlist is use Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 226 +++++++++--------- drivers/crypto/caam/desc.h | 6 +- .../caam/{sg_link_tbl.h => sg_sw_sec4.h} | 42 ++-- 3 files changed, 137 insertions(+), 137 deletions(-) rename drivers/crypto/caam/{sg_link_tbl.h => sg_sw_sec4.h} (57%) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index ea0295d137a7..5ab480a12b51 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -51,7 +51,7 @@ #include "desc_constr.h" #include "jr.h" #include "error.h" -#include "sg_link_tbl.h" +#include "sg_sw_sec4.h" #include "key_gen.h" /* @@ -658,8 +658,8 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, * @dst_nents: number of segments in output scatterlist * @iv_dma: dma address of iv for checking continuity and link table * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) - * @link_tbl_bytes: length of dma mapped link_tbl space - * @link_tbl_dma: bus physical mapped address of h/w link table + * @sec4_sg_bytes: length of dma mapped sec4_sg space + * @sec4_sg_dma: bus physical mapped address of h/w link table * @hw_desc: the h/w job descriptor followed by any referenced link tables */ struct aead_edesc { @@ -667,9 +667,9 @@ struct aead_edesc { int src_nents; int dst_nents; dma_addr_t iv_dma; - int link_tbl_bytes; - dma_addr_t link_tbl_dma; - struct link_tbl_entry *link_tbl; + int sec4_sg_bytes; + dma_addr_t sec4_sg_dma; + struct sec4_sg_entry *sec4_sg; u32 hw_desc[0]; }; @@ -679,24 +679,24 @@ struct aead_edesc { * @dst_nents: number of segments in output scatterlist * @iv_dma: dma address of iv for checking continuity and link table * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) - * @link_tbl_bytes: length of dma mapped link_tbl space - * @link_tbl_dma: bus physical mapped address of h/w link table + * @sec4_sg_bytes: length of dma mapped sec4_sg space + * @sec4_sg_dma: bus physical mapped address of h/w link table * @hw_desc: the h/w job descriptor followed by any referenced link tables */ struct ablkcipher_edesc { int src_nents; int dst_nents; dma_addr_t iv_dma; - int link_tbl_bytes; - dma_addr_t link_tbl_dma; - struct link_tbl_entry *link_tbl; + int sec4_sg_bytes; + dma_addr_t sec4_sg_dma; + struct sec4_sg_entry *sec4_sg; u32 hw_desc[0]; }; static void caam_unmap(struct device *dev, struct scatterlist *src, struct scatterlist *dst, int src_nents, int dst_nents, - dma_addr_t iv_dma, int ivsize, dma_addr_t link_tbl_dma, - int link_tbl_bytes) + dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma, + int sec4_sg_bytes) { if (unlikely(dst != src)) { dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); @@ -707,8 +707,8 @@ static void caam_unmap(struct device *dev, struct scatterlist *src, if (iv_dma) dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE); - if (link_tbl_bytes) - dma_unmap_single(dev, link_tbl_dma, link_tbl_bytes, + if (sec4_sg_bytes) + dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes, DMA_TO_DEVICE); } @@ -723,8 +723,8 @@ static void aead_unmap(struct device *dev, caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, - edesc->iv_dma, ivsize, edesc->link_tbl_dma, - edesc->link_tbl_bytes); + edesc->iv_dma, ivsize, edesc->sec4_sg_dma, + edesc->sec4_sg_bytes); } static void ablkcipher_unmap(struct device *dev, @@ -736,8 +736,8 @@ static void ablkcipher_unmap(struct device *dev, caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, - edesc->iv_dma, ivsize, edesc->link_tbl_dma, - edesc->link_tbl_bytes); + edesc->iv_dma, ivsize, edesc->sec4_sg_dma, + edesc->sec4_sg_bytes); } static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err, @@ -828,7 +828,7 @@ static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err, sizeof(struct iphdr) + req->assoclen + ((req->cryptlen > 1500) ? 1500 : req->cryptlen) + ctx->authsize + 36, 1); - if (!err && edesc->link_tbl_bytes) { + if (!err && edesc->sec4_sg_bytes) { struct scatterlist *sg = sg_last(req->src, edesc->src_nents); print_hex_dump(KERN_ERR, "sglastout@"xstr(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(sg), @@ -927,7 +927,7 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, u32 *desc = edesc->hw_desc; u32 out_options = 0, in_options; dma_addr_t dst_dma, src_dma; - int len, link_tbl_index = 0; + int len, sec4_sg_index = 0; #ifdef DEBUG debug("assoclen %d cryptlen %d authsize %d\n", @@ -953,9 +953,9 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, src_dma = sg_dma_address(req->assoc); in_options = 0; } else { - src_dma = edesc->link_tbl_dma; - link_tbl_index += (edesc->assoc_nents ? : 1) + 1 + - (edesc->src_nents ? : 1); + src_dma = edesc->sec4_sg_dma; + sec4_sg_index += (edesc->assoc_nents ? : 1) + 1 + + (edesc->src_nents ? : 1); in_options = LDST_SGF; } if (encrypt) @@ -969,7 +969,7 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, if (all_contig) { dst_dma = sg_dma_address(req->src); } else { - dst_dma = src_dma + sizeof(struct link_tbl_entry) * + dst_dma = src_dma + sizeof(struct sec4_sg_entry) * ((edesc->assoc_nents ? : 1) + 1); out_options = LDST_SGF; } @@ -977,9 +977,9 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, if (!edesc->dst_nents) { dst_dma = sg_dma_address(req->dst); } else { - dst_dma = edesc->link_tbl_dma + - link_tbl_index * - sizeof(struct link_tbl_entry); + dst_dma = edesc->sec4_sg_dma + + sec4_sg_index * + sizeof(struct sec4_sg_entry); out_options = LDST_SGF; } } @@ -1005,7 +1005,7 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, u32 *desc = edesc->hw_desc; u32 out_options = 0, in_options; dma_addr_t dst_dma, src_dma; - int len, link_tbl_index = 0; + int len, sec4_sg_index = 0; #ifdef DEBUG debug("assoclen %d cryptlen %d authsize %d\n", @@ -1030,8 +1030,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, src_dma = sg_dma_address(req->assoc); in_options = 0; } else { - src_dma = edesc->link_tbl_dma; - link_tbl_index += edesc->assoc_nents + 1 + edesc->src_nents; + src_dma = edesc->sec4_sg_dma; + sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents; in_options = LDST_SGF; } append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + @@ -1041,13 +1041,13 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, dst_dma = edesc->iv_dma; } else { if (likely(req->src == req->dst)) { - dst_dma = src_dma + sizeof(struct link_tbl_entry) * + dst_dma = src_dma + sizeof(struct sec4_sg_entry) * edesc->assoc_nents; out_options = LDST_SGF; } else { - dst_dma = edesc->link_tbl_dma + - link_tbl_index * - sizeof(struct link_tbl_entry); + dst_dma = edesc->sec4_sg_dma + + sec4_sg_index * + sizeof(struct sec4_sg_entry); out_options = LDST_SGF; } } @@ -1068,7 +1068,7 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr, u32 *desc = edesc->hw_desc; u32 out_options = 0, in_options; dma_addr_t dst_dma, src_dma; - int len, link_tbl_index = 0; + int len, sec4_sg_index = 0; #ifdef DEBUG print_hex_dump(KERN_ERR, "presciv@"xstr(__LINE__)": ", @@ -1086,8 +1086,8 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr, src_dma = edesc->iv_dma; in_options = 0; } else { - src_dma = edesc->link_tbl_dma; - link_tbl_index += (iv_contig ? 0 : 1) + edesc->src_nents; + src_dma = edesc->sec4_sg_dma; + sec4_sg_index += (iv_contig ? 0 : 1) + edesc->src_nents; in_options = LDST_SGF; } append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options); @@ -1096,16 +1096,16 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr, if (!edesc->src_nents && iv_contig) { dst_dma = sg_dma_address(req->src); } else { - dst_dma = edesc->link_tbl_dma + - sizeof(struct link_tbl_entry); + dst_dma = edesc->sec4_sg_dma + + sizeof(struct sec4_sg_entry); out_options = LDST_SGF; } } else { if (!edesc->dst_nents) { dst_dma = sg_dma_address(req->dst); } else { - dst_dma = edesc->link_tbl_dma + - link_tbl_index * sizeof(struct link_tbl_entry); + dst_dma = edesc->sec4_sg_dma + + sec4_sg_index * sizeof(struct sec4_sg_entry); out_options = LDST_SGF; } } @@ -1129,7 +1129,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, int sgc; bool all_contig = true; int ivsize = crypto_aead_ivsize(aead); - int link_tbl_index, link_tbl_len = 0, link_tbl_bytes; + int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; assoc_nents = sg_count(req->assoc, req->assoclen); src_nents = sg_count(req->src, req->cryptlen); @@ -1157,15 +1157,15 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, all_contig = false; assoc_nents = assoc_nents ? : 1; src_nents = src_nents ? : 1; - link_tbl_len = assoc_nents + 1 + src_nents; + sec4_sg_len = assoc_nents + 1 + src_nents; } - link_tbl_len += dst_nents; + sec4_sg_len += dst_nents; - link_tbl_bytes = link_tbl_len * sizeof(struct link_tbl_entry); + sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); /* allocate space for base edesc and hw desc commands, link tables */ edesc = kmalloc(sizeof(struct aead_edesc) + desc_bytes + - link_tbl_bytes, GFP_DMA | flags); + sec4_sg_bytes, GFP_DMA | flags); if (!edesc) { dev_err(jrdev, "could not allocate extended descriptor\n"); return ERR_PTR(-ENOMEM); @@ -1175,32 +1175,32 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, edesc->src_nents = src_nents; edesc->dst_nents = dst_nents; edesc->iv_dma = iv_dma; - edesc->link_tbl_bytes = link_tbl_bytes; - edesc->link_tbl = (void *)edesc + sizeof(struct aead_edesc) + - desc_bytes; - edesc->link_tbl_dma = dma_map_single(jrdev, edesc->link_tbl, - link_tbl_bytes, DMA_TO_DEVICE); + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + + desc_bytes; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); *all_contig_ptr = all_contig; - link_tbl_index = 0; + sec4_sg_index = 0; if (!all_contig) { - sg_to_link_tbl(req->assoc, - (assoc_nents ? : 1), - edesc->link_tbl + - link_tbl_index, 0); - link_tbl_index += assoc_nents ? : 1; - sg_to_link_tbl_one(edesc->link_tbl + link_tbl_index, + sg_to_sec4_sg(req->assoc, + (assoc_nents ? : 1), + edesc->sec4_sg + + sec4_sg_index, 0); + sec4_sg_index += assoc_nents ? : 1; + dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, iv_dma, ivsize, 0); - link_tbl_index += 1; - sg_to_link_tbl_last(req->src, - (src_nents ? : 1), - edesc->link_tbl + - link_tbl_index, 0); - link_tbl_index += src_nents ? : 1; + sec4_sg_index += 1; + sg_to_sec4_sg_last(req->src, + (src_nents ? : 1), + edesc->sec4_sg + + sec4_sg_index, 0); + sec4_sg_index += src_nents ? : 1; } if (dst_nents) { - sg_to_link_tbl_last(req->dst, dst_nents, - edesc->link_tbl + link_tbl_index, 0); + sg_to_sec4_sg_last(req->dst, dst_nents, + edesc->sec4_sg + sec4_sg_index, 0); } return edesc; @@ -1307,7 +1307,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request int sgc; u32 contig = GIV_SRC_CONTIG | GIV_DST_CONTIG; int ivsize = crypto_aead_ivsize(aead); - int link_tbl_index, link_tbl_len = 0, link_tbl_bytes; + int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; assoc_nents = sg_count(req->assoc, req->assoclen); src_nents = sg_count(req->src, req->cryptlen); @@ -1336,22 +1336,22 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request contig &= ~GIV_DST_CONTIG; if (unlikely(req->src != req->dst)) { dst_nents = dst_nents ? : 1; - link_tbl_len += 1; + sec4_sg_len += 1; } if (!(contig & GIV_SRC_CONTIG)) { assoc_nents = assoc_nents ? : 1; src_nents = src_nents ? : 1; - link_tbl_len += assoc_nents + 1 + src_nents; + sec4_sg_len += assoc_nents + 1 + src_nents; if (likely(req->src == req->dst)) contig &= ~GIV_DST_CONTIG; } - link_tbl_len += dst_nents; + sec4_sg_len += dst_nents; - link_tbl_bytes = link_tbl_len * sizeof(struct link_tbl_entry); + sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); /* allocate space for base edesc and hw desc commands, link tables */ edesc = kmalloc(sizeof(struct aead_edesc) + desc_bytes + - link_tbl_bytes, GFP_DMA | flags); + sec4_sg_bytes, GFP_DMA | flags); if (!edesc) { dev_err(jrdev, "could not allocate extended descriptor\n"); return ERR_PTR(-ENOMEM); @@ -1361,33 +1361,33 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request edesc->src_nents = src_nents; edesc->dst_nents = dst_nents; edesc->iv_dma = iv_dma; - edesc->link_tbl_bytes = link_tbl_bytes; - edesc->link_tbl = (void *)edesc + sizeof(struct aead_edesc) + - desc_bytes; - edesc->link_tbl_dma = dma_map_single(jrdev, edesc->link_tbl, - link_tbl_bytes, DMA_TO_DEVICE); + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + + desc_bytes; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); *contig_ptr = contig; - link_tbl_index = 0; + sec4_sg_index = 0; if (!(contig & GIV_SRC_CONTIG)) { - sg_to_link_tbl(req->assoc, assoc_nents, - edesc->link_tbl + - link_tbl_index, 0); - link_tbl_index += assoc_nents; - sg_to_link_tbl_one(edesc->link_tbl + link_tbl_index, + sg_to_sec4_sg(req->assoc, assoc_nents, + edesc->sec4_sg + + sec4_sg_index, 0); + sec4_sg_index += assoc_nents; + dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, iv_dma, ivsize, 0); - link_tbl_index += 1; - sg_to_link_tbl_last(req->src, src_nents, - edesc->link_tbl + - link_tbl_index, 0); - link_tbl_index += src_nents; + sec4_sg_index += 1; + sg_to_sec4_sg_last(req->src, src_nents, + edesc->sec4_sg + + sec4_sg_index, 0); + sec4_sg_index += src_nents; } if (unlikely(req->src != req->dst && !(contig & GIV_DST_CONTIG))) { - sg_to_link_tbl_one(edesc->link_tbl + link_tbl_index, + dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, iv_dma, ivsize, 0); - link_tbl_index += 1; - sg_to_link_tbl_last(req->dst, dst_nents, - edesc->link_tbl + link_tbl_index, 0); + sec4_sg_index += 1; + sg_to_sec4_sg_last(req->dst, dst_nents, + edesc->sec4_sg + sec4_sg_index, 0); } return edesc; @@ -1453,13 +1453,13 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; - int src_nents, dst_nents = 0, link_tbl_bytes; + int src_nents, dst_nents = 0, sec4_sg_bytes; struct ablkcipher_edesc *edesc; dma_addr_t iv_dma = 0; bool iv_contig = false; int sgc; int ivsize = crypto_ablkcipher_ivsize(ablkcipher); - int link_tbl_index; + int sec4_sg_index; src_nents = sg_count(req->src, req->nbytes); @@ -1485,12 +1485,12 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request iv_contig = true; else src_nents = src_nents ? : 1; - link_tbl_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) * - sizeof(struct link_tbl_entry); + sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) * + sizeof(struct sec4_sg_entry); /* allocate space for base edesc and hw desc commands, link tables */ edesc = kmalloc(sizeof(struct ablkcipher_edesc) + desc_bytes + - link_tbl_bytes, GFP_DMA | flags); + sec4_sg_bytes, GFP_DMA | flags); if (!edesc) { dev_err(jrdev, "could not allocate extended descriptor\n"); return ERR_PTR(-ENOMEM); @@ -1498,31 +1498,31 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request edesc->src_nents = src_nents; edesc->dst_nents = dst_nents; - edesc->link_tbl_bytes = link_tbl_bytes; - edesc->link_tbl = (void *)edesc + sizeof(struct ablkcipher_edesc) + - desc_bytes; + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) + + desc_bytes; - link_tbl_index = 0; + sec4_sg_index = 0; if (!iv_contig) { - sg_to_link_tbl_one(edesc->link_tbl, iv_dma, ivsize, 0); - sg_to_link_tbl_last(req->src, src_nents, - edesc->link_tbl + 1, 0); - link_tbl_index += 1 + src_nents; + dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0); + sg_to_sec4_sg_last(req->src, src_nents, + edesc->sec4_sg + 1, 0); + sec4_sg_index += 1 + src_nents; } if (unlikely(dst_nents)) { - sg_to_link_tbl_last(req->dst, dst_nents, - edesc->link_tbl + link_tbl_index, 0); + sg_to_sec4_sg_last(req->dst, dst_nents, + edesc->sec4_sg + sec4_sg_index, 0); } - edesc->link_tbl_dma = dma_map_single(jrdev, edesc->link_tbl, - link_tbl_bytes, DMA_TO_DEVICE); + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); edesc->iv_dma = iv_dma; #ifdef DEBUG - print_hex_dump(KERN_ERR, "ablkcipher link_tbl@"xstr(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, edesc->link_tbl, - link_tbl_bytes, 1); + print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg, + sec4_sg_bytes, 1); #endif *iv_contig_out = iv_contig; diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h index 48c1927dbf21..3e685062d44b 100644 --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -8,10 +8,10 @@ #ifndef DESC_H #define DESC_H -struct link_tbl_entry { +struct sec4_sg_entry { u64 ptr; -#define LINK_TBL_LEN_FIN 0x40000000 -#define LINK_TBL_LEN_EXT 0x80000000 +#define SEC4_SG_LEN_FIN 0x40000000 +#define SEC4_SG_LEN_EXT 0x80000000 u32 len; u8 reserved; u8 buf_pool_id; diff --git a/drivers/crypto/caam/sg_link_tbl.h b/drivers/crypto/caam/sg_sw_sec4.h similarity index 57% rename from drivers/crypto/caam/sg_link_tbl.h rename to drivers/crypto/caam/sg_sw_sec4.h index 6df434922460..a6ad7a443213 100644 --- a/drivers/crypto/caam/sg_link_tbl.h +++ b/drivers/crypto/caam/sg_sw_sec4.h @@ -5,23 +5,23 @@ * */ -struct link_tbl_entry; +struct sec4_sg_entry; /* * convert single dma address to h/w link table format */ -static inline void sg_to_link_tbl_one(struct link_tbl_entry *link_tbl_ptr, +static inline void dma_to_sec4_sg_one(struct sec4_sg_entry *sec4_sg_ptr, dma_addr_t dma, u32 len, u32 offset) { - link_tbl_ptr->ptr = dma; - link_tbl_ptr->len = len; - link_tbl_ptr->reserved = 0; - link_tbl_ptr->buf_pool_id = 0; - link_tbl_ptr->offset = offset; + sec4_sg_ptr->ptr = dma; + sec4_sg_ptr->len = len; + sec4_sg_ptr->reserved = 0; + sec4_sg_ptr->buf_pool_id = 0; + sec4_sg_ptr->offset = offset; #ifdef DEBUG - print_hex_dump(KERN_ERR, "link_tbl_ptr@: ", - DUMP_PREFIX_ADDRESS, 16, 4, link_tbl_ptr, - sizeof(struct link_tbl_entry), 1); + print_hex_dump(KERN_ERR, "sec4_sg_ptr@: ", + DUMP_PREFIX_ADDRESS, 16, 4, sec4_sg_ptr, + sizeof(struct sec4_sg_entry), 1); #endif } @@ -29,30 +29,30 @@ static inline void sg_to_link_tbl_one(struct link_tbl_entry *link_tbl_ptr, * convert scatterlist to h/w link table format * but does not have final bit; instead, returns last entry */ -static inline struct link_tbl_entry * -sg_to_link_tbl(struct scatterlist *sg, int sg_count, - struct link_tbl_entry *link_tbl_ptr, u32 offset) +static inline struct sec4_sg_entry * +sg_to_sec4_sg(struct scatterlist *sg, int sg_count, + struct sec4_sg_entry *sec4_sg_ptr, u32 offset) { while (sg_count) { - sg_to_link_tbl_one(link_tbl_ptr, sg_dma_address(sg), + dma_to_sec4_sg_one(sec4_sg_ptr, sg_dma_address(sg), sg_dma_len(sg), offset); - link_tbl_ptr++; + sec4_sg_ptr++; sg = sg_next(sg); sg_count--; } - return link_tbl_ptr - 1; + return sec4_sg_ptr - 1; } /* * convert scatterlist to h/w link table format * scatterlist must have been previously dma mapped */ -static inline void sg_to_link_tbl_last(struct scatterlist *sg, int sg_count, - struct link_tbl_entry *link_tbl_ptr, - u32 offset) +static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count, + struct sec4_sg_entry *sec4_sg_ptr, + u32 offset) { - link_tbl_ptr = sg_to_link_tbl(sg, sg_count, link_tbl_ptr, offset); - link_tbl_ptr->len |= LINK_TBL_LEN_FIN; + sec4_sg_ptr = sg_to_sec4_sg(sg, sg_count, sec4_sg_ptr, offset); + sec4_sg_ptr->len |= SEC4_SG_LEN_FIN; } /* count number of elements in scatterlist */ -- GitLab From 045e36780f11523e26d1e4a8c78bdc57f4003bd0 Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:47 -0500 Subject: [PATCH 2996/6849] crypto: caam - ahash hmac support caam supports ahash hmac with sha algorithms and md5. Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/Kconfig | 12 + drivers/crypto/caam/Makefile | 1 + drivers/crypto/caam/caamhash.c | 1814 ++++++++++++++++++++++++++++++ drivers/crypto/caam/compat.h | 2 + drivers/crypto/caam/intern.h | 2 + drivers/crypto/caam/sg_sw_sec4.h | 38 + 6 files changed, 1869 insertions(+) create mode 100644 drivers/crypto/caam/caamhash.c diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index 2d876bb98ff4..e61b7f50785e 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -70,3 +70,15 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API To compile this as a module, choose M here: the module will be called caamalg. + +config CRYPTO_DEV_FSL_CAAM_AHASH_API + tristate "Register hash algorithm implementations with Crypto API" + depends on CRYPTO_DEV_FSL_CAAM + default y + select CRYPTO_AHASH + help + Selecting this will offload ahash for users of the + scatterlist crypto API to the SEC4 via job ring. + + To compile this as a module, choose M here: the module + will be called caamhash. diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile index 4447e5748c43..9ef1cb00c342 100644 --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o caam-objs := ctrl.o jr.o error.o key_gen.o diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c new file mode 100644 index 000000000000..c0b6d86577cf --- /dev/null +++ b/drivers/crypto/caam/caamhash.c @@ -0,0 +1,1814 @@ +/* + * caam - Freescale FSL CAAM support for ahash functions of crypto API + * + * Copyright 2011 Freescale Semiconductor, Inc. + * + * Based on caamalg.c crypto API driver. + * + * relationship of digest job descriptor or first job descriptor after init to + * shared descriptors: + * + * --------------- --------------- + * | JobDesc #1 |-------------------->| ShareDesc | + * | *(packet 1) | | (hashKey) | + * --------------- | (operation) | + * --------------- + * + * relationship of subsequent job descriptors to shared descriptors: + * + * --------------- --------------- + * | JobDesc #2 |-------------------->| ShareDesc | + * | *(packet 2) | |------------->| (hashKey) | + * --------------- | |-------->| (operation) | + * . | | | (load ctx2) | + * . | | --------------- + * --------------- | | + * | JobDesc #3 |------| | + * | *(packet 3) | | + * --------------- | + * . | + * . | + * --------------- | + * | JobDesc #4 |------------ + * | *(packet 4) | + * --------------- + * + * The SharedDesc never changes for a connection unless rekeyed, but + * each packet will likely be in a different place. So all we need + * to know to process the packet is where the input is, where the + * output goes, and what context we want to process with. Context is + * in the SharedDesc, packet references in the JobDesc. + * + * So, a job desc looks like: + * + * --------------------- + * | Header | + * | ShareDesc Pointer | + * | SEQ_OUT_PTR | + * | (output buffer) | + * | (output length) | + * | SEQ_IN_PTR | + * | (input buffer) | + * | (input length) | + * --------------------- + */ + +#include "compat.h" + +#include "regs.h" +#include "intern.h" +#include "desc_constr.h" +#include "jr.h" +#include "error.h" +#include "sg_sw_sec4.h" +#include "key_gen.h" + +#define CAAM_CRA_PRIORITY 3000 + +/* max hash key is max split key size */ +#define CAAM_MAX_HASH_KEY_SIZE (SHA512_DIGEST_SIZE * 2) + +#define CAAM_MAX_HASH_BLOCK_SIZE SHA512_BLOCK_SIZE +#define CAAM_MAX_HASH_DIGEST_SIZE SHA512_DIGEST_SIZE + +/* length of descriptors text */ +#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3) + +#define DESC_AHASH_BASE (4 * CAAM_CMD_SZ) +#define DESC_AHASH_UPDATE_LEN (6 * CAAM_CMD_SZ) +#define DESC_AHASH_UPDATE_FIRST_LEN (DESC_AHASH_BASE + 4 * CAAM_CMD_SZ) +#define DESC_AHASH_FINAL_LEN (DESC_AHASH_BASE + 5 * CAAM_CMD_SZ) +#define DESC_AHASH_FINUP_LEN (DESC_AHASH_BASE + 5 * CAAM_CMD_SZ) +#define DESC_AHASH_DIGEST_LEN (DESC_AHASH_BASE + 4 * CAAM_CMD_SZ) + +#define DESC_HASH_MAX_USED_BYTES (DESC_AHASH_FINAL_LEN + \ + CAAM_MAX_HASH_KEY_SIZE) +#define DESC_HASH_MAX_USED_LEN (DESC_HASH_MAX_USED_BYTES / CAAM_CMD_SZ) + +/* caam context sizes for hashes: running digest + 8 */ +#define HASH_MSG_LEN 8 +#define MAX_CTX_LEN (HASH_MSG_LEN + SHA512_DIGEST_SIZE) + +#ifdef DEBUG +/* for print_hex_dumps with line references */ +#define xstr(s) str(s) +#define str(s) #s +#define debug(format, arg...) printk(format, arg) +#else +#define debug(format, arg...) +#endif + +/* ahash per-session context */ +struct caam_hash_ctx { + struct device *jrdev; + u32 sh_desc_update[DESC_HASH_MAX_USED_LEN]; + u32 sh_desc_update_first[DESC_HASH_MAX_USED_LEN]; + u32 sh_desc_fin[DESC_HASH_MAX_USED_LEN]; + u32 sh_desc_digest[DESC_HASH_MAX_USED_LEN]; + u32 sh_desc_finup[DESC_HASH_MAX_USED_LEN]; + dma_addr_t sh_desc_update_dma; + dma_addr_t sh_desc_update_first_dma; + dma_addr_t sh_desc_fin_dma; + dma_addr_t sh_desc_digest_dma; + dma_addr_t sh_desc_finup_dma; + u32 alg_type; + u32 alg_op; + u8 key[CAAM_MAX_HASH_KEY_SIZE]; + dma_addr_t key_dma; + int ctx_len; + unsigned int split_key_len; + unsigned int split_key_pad_len; +}; + +/* ahash state */ +struct caam_hash_state { + dma_addr_t buf_dma; + dma_addr_t ctx_dma; + u8 buf_0[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned; + int buflen_0; + u8 buf_1[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned; + int buflen_1; + u8 caam_ctx[MAX_CTX_LEN]; + int (*update)(struct ahash_request *req); + int (*final)(struct ahash_request *req); + int (*finup)(struct ahash_request *req); + int current_buf; +}; + +/* Common job descriptor seq in/out ptr routines */ + +/* Map state->caam_ctx, and append seq_out_ptr command that points to it */ +static inline void map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev, + struct caam_hash_state *state, + int ctx_len) +{ + state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, + ctx_len, DMA_FROM_DEVICE); + append_seq_out_ptr(desc, state->ctx_dma, ctx_len, 0); +} + +/* Map req->result, and append seq_out_ptr command that points to it */ +static inline dma_addr_t map_seq_out_ptr_result(u32 *desc, struct device *jrdev, + u8 *result, int digestsize) +{ + dma_addr_t dst_dma; + + dst_dma = dma_map_single(jrdev, result, digestsize, DMA_FROM_DEVICE); + append_seq_out_ptr(desc, dst_dma, digestsize, 0); + + return dst_dma; +} + +/* Map current buffer in state and put it in link table */ +static inline dma_addr_t buf_map_to_sec4_sg(struct device *jrdev, + struct sec4_sg_entry *sec4_sg, + u8 *buf, int buflen) +{ + dma_addr_t buf_dma; + + buf_dma = dma_map_single(jrdev, buf, buflen, DMA_TO_DEVICE); + dma_to_sec4_sg_one(sec4_sg, buf_dma, buflen, 0); + + return buf_dma; +} + +/* Map req->src and put it in link table */ +static inline void src_map_to_sec4_sg(struct device *jrdev, + struct scatterlist *src, int src_nents, + struct sec4_sg_entry *sec4_sg) +{ + dma_map_sg(jrdev, src, src_nents, DMA_TO_DEVICE); + sg_to_sec4_sg_last(src, src_nents, sec4_sg, 0); +} + +/* + * Only put buffer in link table if it contains data, which is possible, + * since a buffer has previously been used, and needs to be unmapped, + */ +static inline dma_addr_t +try_buf_map_to_sec4_sg(struct device *jrdev, struct sec4_sg_entry *sec4_sg, + u8 *buf, dma_addr_t buf_dma, int buflen, + int last_buflen) +{ + if (buf_dma && !dma_mapping_error(jrdev, buf_dma)) + dma_unmap_single(jrdev, buf_dma, last_buflen, DMA_TO_DEVICE); + if (buflen) + buf_dma = buf_map_to_sec4_sg(jrdev, sec4_sg, buf, buflen); + else + buf_dma = 0; + + return buf_dma; +} + +/* Map state->caam_ctx, and add it to link table */ +static inline void ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev, + struct caam_hash_state *state, + int ctx_len, + struct sec4_sg_entry *sec4_sg, + u32 flag) +{ + state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag); + dma_to_sec4_sg_one(sec4_sg, state->ctx_dma, ctx_len, 0); +} + +/* Common shared descriptor commands */ +static inline void append_key_ahash(u32 *desc, struct caam_hash_ctx *ctx) +{ + append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len, + ctx->split_key_len, CLASS_2 | + KEY_DEST_MDHA_SPLIT | KEY_ENC); +} + +/* Append key if it has been set */ +static inline void init_sh_desc_key_ahash(u32 *desc, struct caam_hash_ctx *ctx) +{ + u32 *key_jump_cmd; + + init_sh_desc(desc, HDR_SHARE_WAIT); + + if (ctx->split_key_len) { + /* Skip if already shared */ + key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | + JUMP_COND_SHRD); + + append_key_ahash(desc, ctx); + + set_jump_tgt_here(desc, key_jump_cmd); + } + + /* Propagate errors from shared to job descriptor */ + append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD); +} + +/* + * For ahash read data from seqin following state->caam_ctx, + * and write resulting class2 context to seqout, which may be state->caam_ctx + * or req->result + */ +static inline void ahash_append_load_str(u32 *desc, int digestsize) +{ + /* Calculate remaining bytes to read */ + append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); + + /* Read remaining bytes */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 | + FIFOLD_TYPE_MSG | KEY_VLF); + + /* Store class2 context bytes */ + append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | + LDST_SRCDST_BYTE_CONTEXT); +} + +/* + * For ahash update, final and finup, import context, read and write to seqout + */ +static inline void ahash_ctx_data_to_out(u32 *desc, u32 op, u32 state, + int digestsize, + struct caam_hash_ctx *ctx) +{ + init_sh_desc_key_ahash(desc, ctx); + + /* Import context from software */ + append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT | + LDST_CLASS_2_CCB | ctx->ctx_len); + + /* Class 2 operation */ + append_operation(desc, op | state | OP_ALG_ENCRYPT); + + /* + * Load from buf and/or src and write to req->result or state->context + */ + ahash_append_load_str(desc, digestsize); +} + +/* For ahash firsts and digest, read and write to seqout */ +static inline void ahash_data_to_out(u32 *desc, u32 op, u32 state, + int digestsize, struct caam_hash_ctx *ctx) +{ + init_sh_desc_key_ahash(desc, ctx); + + /* Class 2 operation */ + append_operation(desc, op | state | OP_ALG_ENCRYPT); + + /* + * Load from buf and/or src and write to req->result or state->context + */ + ahash_append_load_str(desc, digestsize); +} + +static int ahash_set_sh_desc(struct crypto_ahash *ahash) +{ + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + int digestsize = crypto_ahash_digestsize(ahash); + struct device *jrdev = ctx->jrdev; + u32 have_key = 0; + u32 *desc; + + if (ctx->split_key_len) + have_key = OP_ALG_AAI_HMAC_PRECOMP; + + /* ahash_update shared descriptor */ + desc = ctx->sh_desc_update; + + init_sh_desc(desc, HDR_SHARE_WAIT); + + /* Import context from software */ + append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT | + LDST_CLASS_2_CCB | ctx->ctx_len); + + /* Class 2 operation */ + append_operation(desc, ctx->alg_type | OP_ALG_AS_UPDATE | + OP_ALG_ENCRYPT); + + /* Load data and write to result or context */ + ahash_append_load_str(desc, ctx->ctx_len); + + ctx->sh_desc_update_dma = dma_map_single(jrdev, desc, desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_update_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ahash update shdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + /* ahash_update_first shared descriptor */ + desc = ctx->sh_desc_update_first; + + ahash_data_to_out(desc, have_key | ctx->alg_type, OP_ALG_AS_INIT, + ctx->ctx_len, ctx); + + ctx->sh_desc_update_first_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_update_first_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ahash update first shdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + /* ahash_final shared descriptor */ + desc = ctx->sh_desc_fin; + + ahash_ctx_data_to_out(desc, have_key | ctx->alg_type, + OP_ALG_AS_FINALIZE, digestsize, ctx); + + ctx->sh_desc_fin_dma = dma_map_single(jrdev, desc, desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_fin_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ahash final shdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + /* ahash_finup shared descriptor */ + desc = ctx->sh_desc_finup; + + ahash_ctx_data_to_out(desc, have_key | ctx->alg_type, + OP_ALG_AS_FINALIZE, digestsize, ctx); + + ctx->sh_desc_finup_dma = dma_map_single(jrdev, desc, desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_finup_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ahash finup shdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + /* ahash_digest shared descriptor */ + desc = ctx->sh_desc_digest; + + ahash_data_to_out(desc, have_key | ctx->alg_type, OP_ALG_AS_INITFINAL, + digestsize, ctx); + + ctx->sh_desc_digest_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_digest_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ahash digest shdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + return 0; +} + +static u32 gen_split_hash_key(struct caam_hash_ctx *ctx, const u8 *key_in, + u32 keylen) +{ + return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len, + ctx->split_key_pad_len, key_in, keylen, + ctx->alg_op); +} + +/* Digest hash size if it is too large */ +static u32 hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in, + u32 *keylen, u8 *key_out, u32 digestsize) +{ + struct device *jrdev = ctx->jrdev; + u32 *desc; + struct split_key_result result; + dma_addr_t src_dma, dst_dma; + int ret = 0; + + desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); + + init_job_desc(desc, 0); + + src_dma = dma_map_single(jrdev, (void *)key_in, *keylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, src_dma)) { + dev_err(jrdev, "unable to map key input memory\n"); + kfree(desc); + return -ENOMEM; + } + dst_dma = dma_map_single(jrdev, (void *)key_out, digestsize, + DMA_FROM_DEVICE); + if (dma_mapping_error(jrdev, dst_dma)) { + dev_err(jrdev, "unable to map key output memory\n"); + dma_unmap_single(jrdev, src_dma, *keylen, DMA_TO_DEVICE); + kfree(desc); + return -ENOMEM; + } + + /* Job descriptor to perform unkeyed hash on key_in */ + append_operation(desc, ctx->alg_type | OP_ALG_ENCRYPT | + OP_ALG_AS_INITFINAL); + append_seq_in_ptr(desc, src_dma, *keylen, 0); + append_seq_fifo_load(desc, *keylen, FIFOLD_CLASS_CLASS2 | + FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_MSG); + append_seq_out_ptr(desc, dst_dma, digestsize, 0); + append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | + LDST_SRCDST_BYTE_CONTEXT); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "key_in@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key_in, *keylen, 1); + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + result.err = 0; + init_completion(&result.completion); + + ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); + if (!ret) { + /* in progress */ + wait_for_completion_interruptible(&result.completion); + ret = result.err; +#ifdef DEBUG + print_hex_dump(KERN_ERR, "digested key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key_in, + digestsize, 1); +#endif + } + *keylen = digestsize; + + dma_unmap_single(jrdev, src_dma, *keylen, DMA_TO_DEVICE); + dma_unmap_single(jrdev, dst_dma, digestsize, DMA_FROM_DEVICE); + + kfree(desc); + + return ret; +} + +static int ahash_setkey(struct crypto_ahash *ahash, + const u8 *key, unsigned int keylen) +{ + /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */ + static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct device *jrdev = ctx->jrdev; + int blocksize = crypto_tfm_alg_blocksize(&ahash->base); + int digestsize = crypto_ahash_digestsize(ahash); + int ret = 0; + u8 *hashed_key = NULL; + +#ifdef DEBUG + printk(KERN_ERR "keylen %d\n", keylen); +#endif + + if (keylen > blocksize) { + hashed_key = kmalloc(sizeof(u8) * digestsize, GFP_KERNEL | + GFP_DMA); + if (!hashed_key) + return -ENOMEM; + ret = hash_digest_key(ctx, key, &keylen, hashed_key, + digestsize); + if (ret) + goto badkey; + key = hashed_key; + } + + /* Pick class 2 key length from algorithm submask */ + ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> + OP_ALG_ALGSEL_SHIFT] * 2; + ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16); + +#ifdef DEBUG + printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n", + ctx->split_key_len, ctx->split_key_pad_len); + print_hex_dump(KERN_ERR, "key in @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); +#endif + + ret = gen_split_hash_key(ctx, key, keylen); + if (ret) + goto badkey; + + ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->key_dma)) { + dev_err(jrdev, "unable to map key i/o memory\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, + ctx->split_key_pad_len, 1); +#endif + + ret = ahash_set_sh_desc(ahash); + if (ret) { + dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len, + DMA_TO_DEVICE); + } + + kfree(hashed_key); + return ret; +badkey: + kfree(hashed_key); + crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; +} + +/* + * ahash_edesc - s/w-extended ahash descriptor + * @dst_dma: physical mapped address of req->result + * @sec4_sg_dma: physical mapped address of h/w link table + * @src_nents: number of segments in input scatterlist + * @sec4_sg_bytes: length of dma mapped sec4_sg space + * @sec4_sg: pointer to h/w link table + * @hw_desc: the h/w job descriptor followed by any referenced link tables + */ +struct ahash_edesc { + dma_addr_t dst_dma; + dma_addr_t sec4_sg_dma; + int src_nents; + int sec4_sg_bytes; + struct sec4_sg_entry *sec4_sg; + u32 hw_desc[0]; +}; + +static inline void ahash_unmap(struct device *dev, + struct ahash_edesc *edesc, + struct ahash_request *req, int dst_len) +{ + if (edesc->src_nents) + dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE); + if (edesc->dst_dma) + dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE); + + if (edesc->sec4_sg_bytes) + dma_unmap_single(dev, edesc->sec4_sg_dma, + edesc->sec4_sg_bytes, DMA_TO_DEVICE); +} + +static inline void ahash_unmap_ctx(struct device *dev, + struct ahash_edesc *edesc, + struct ahash_request *req, int dst_len, u32 flag) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + + if (state->ctx_dma) + dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag); + ahash_unmap(dev, edesc, req, dst_len); +} + +static void ahash_done(struct device *jrdev, u32 *desc, u32 err, + void *context) +{ + struct ahash_request *req = context; + struct ahash_edesc *edesc; + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + int digestsize = crypto_ahash_digestsize(ahash); +#ifdef DEBUG + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + + dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + + edesc = (struct ahash_edesc *)((char *)desc - + offsetof(struct ahash_edesc, hw_desc)); + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + ahash_unmap(jrdev, edesc, req, digestsize); + kfree(edesc); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, + ctx->ctx_len, 1); + if (req->result) + print_hex_dump(KERN_ERR, "result@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, req->result, + digestsize, 1); +#endif + + req->base.complete(&req->base, err); +} + +static void ahash_done_bi(struct device *jrdev, u32 *desc, u32 err, + void *context) +{ + struct ahash_request *req = context; + struct ahash_edesc *edesc; + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); +#ifdef DEBUG + struct caam_hash_state *state = ahash_request_ctx(req); + int digestsize = crypto_ahash_digestsize(ahash); + + dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + + edesc = (struct ahash_edesc *)((char *)desc - + offsetof(struct ahash_edesc, hw_desc)); + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, DMA_BIDIRECTIONAL); + kfree(edesc); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, + ctx->ctx_len, 1); + if (req->result) + print_hex_dump(KERN_ERR, "result@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, req->result, + digestsize, 1); +#endif + + req->base.complete(&req->base, err); +} + +static void ahash_done_ctx_src(struct device *jrdev, u32 *desc, u32 err, + void *context) +{ + struct ahash_request *req = context; + struct ahash_edesc *edesc; + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + int digestsize = crypto_ahash_digestsize(ahash); +#ifdef DEBUG + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + + dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + + edesc = (struct ahash_edesc *)((char *)desc - + offsetof(struct ahash_edesc, hw_desc)); + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE); + kfree(edesc); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, + ctx->ctx_len, 1); + if (req->result) + print_hex_dump(KERN_ERR, "result@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, req->result, + digestsize, 1); +#endif + + req->base.complete(&req->base, err); +} + +static void ahash_done_ctx_dst(struct device *jrdev, u32 *desc, u32 err, + void *context) +{ + struct ahash_request *req = context; + struct ahash_edesc *edesc; + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); +#ifdef DEBUG + struct caam_hash_state *state = ahash_request_ctx(req); + int digestsize = crypto_ahash_digestsize(ahash); + + dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + + edesc = (struct ahash_edesc *)((char *)desc - + offsetof(struct ahash_edesc, hw_desc)); + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE); + kfree(edesc); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, + ctx->ctx_len, 1); + if (req->result) + print_hex_dump(KERN_ERR, "result@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, req->result, + digestsize, 1); +#endif + + req->base.complete(&req->base, err); +} + +/* submit update job descriptor */ +static int ahash_update_ctx(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *buf = state->current_buf ? state->buf_1 : state->buf_0; + int *buflen = state->current_buf ? &state->buflen_1 : &state->buflen_0; + u8 *next_buf = state->current_buf ? state->buf_0 : state->buf_1; + int *next_buflen = state->current_buf ? &state->buflen_0 : + &state->buflen_1, last_buflen; + int in_len = *buflen + req->nbytes, to_hash; + u32 *sh_desc = ctx->sh_desc_update, *desc; + dma_addr_t ptr = ctx->sh_desc_update_dma; + int src_nents, sec4_sg_bytes, sec4_sg_src_index; + struct ahash_edesc *edesc; + int ret = 0; + int sh_len; + + last_buflen = *next_buflen; + *next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1); + to_hash = in_len - *next_buflen; + + if (to_hash) { + src_nents = __sg_count(req->src, req->nbytes - (*next_buflen)); + sec4_sg_src_index = 1 + (*buflen ? 1 : 0); + sec4_sg_bytes = (sec4_sg_src_index + src_nents) * + sizeof(struct sec4_sg_entry); + + /* + * allocate space for base edesc and hw desc commands, + * link tables + */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN + + sec4_sg_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, + "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + edesc->src_nents = src_nents; + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, + DMA_TO_DEVICE); + + ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, + edesc->sec4_sg, DMA_BIDIRECTIONAL); + + state->buf_dma = try_buf_map_to_sec4_sg(jrdev, + edesc->sec4_sg + 1, + buf, state->buf_dma, + *buflen, last_buflen); + + if (src_nents) { + src_map_to_sec4_sg(jrdev, req->src, src_nents, + edesc->sec4_sg + sec4_sg_src_index); + if (*next_buflen) { + sg_copy_part(next_buf, req->src, to_hash - + *buflen, req->nbytes); + state->current_buf = !state->current_buf; + } + } else { + (edesc->sec4_sg + sec4_sg_src_index - 1)->len |= + SEC4_SG_LEN_FIN; + } + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | + HDR_REVERSE); + + append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + + to_hash, LDST_SGF); + + append_seq_out_ptr(desc, state->ctx_dma, ctx->ctx_len, 0); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done_bi, req); + if (!ret) { + ret = -EINPROGRESS; + } else { + ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, + DMA_BIDIRECTIONAL); + kfree(edesc); + } + } else if (*next_buflen) { + sg_copy(buf + *buflen, req->src, req->nbytes); + *buflen = *next_buflen; + *next_buflen = last_buflen; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "buf@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, buf, *buflen, 1); + print_hex_dump(KERN_ERR, "next buf@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, next_buf, + *next_buflen, 1); +#endif + + return ret; +} + +static int ahash_final_ctx(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *buf = state->current_buf ? state->buf_1 : state->buf_0; + int buflen = state->current_buf ? state->buflen_1 : state->buflen_0; + int last_buflen = state->current_buf ? state->buflen_0 : + state->buflen_1; + u32 *sh_desc = ctx->sh_desc_fin, *desc; + dma_addr_t ptr = ctx->sh_desc_fin_dma; + int sec4_sg_bytes; + int digestsize = crypto_ahash_digestsize(ahash); + struct ahash_edesc *edesc; + int ret = 0; + int sh_len; + + sec4_sg_bytes = (1 + (buflen ? 1 : 0)) * sizeof(struct sec4_sg_entry); + + /* allocate space for base edesc and hw desc commands, link tables */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN + + sec4_sg_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); + + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); + edesc->src_nents = 0; + + ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, edesc->sec4_sg, + DMA_TO_DEVICE); + + state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1, + buf, state->buf_dma, buflen, + last_buflen); + (edesc->sec4_sg + sec4_sg_bytes - 1)->len |= SEC4_SG_LEN_FIN; + + append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + buflen, + LDST_SGF); + + edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result, + digestsize); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_src, req); + if (!ret) { + ret = -EINPROGRESS; + } else { + ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE); + kfree(edesc); + } + + return ret; +} + +static int ahash_finup_ctx(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *buf = state->current_buf ? state->buf_1 : state->buf_0; + int buflen = state->current_buf ? state->buflen_1 : state->buflen_0; + int last_buflen = state->current_buf ? state->buflen_0 : + state->buflen_1; + u32 *sh_desc = ctx->sh_desc_finup, *desc; + dma_addr_t ptr = ctx->sh_desc_finup_dma; + int sec4_sg_bytes, sec4_sg_src_index; + int src_nents; + int digestsize = crypto_ahash_digestsize(ahash); + struct ahash_edesc *edesc; + int ret = 0; + int sh_len; + + src_nents = __sg_count(req->src, req->nbytes); + sec4_sg_src_index = 1 + (buflen ? 1 : 0); + sec4_sg_bytes = (sec4_sg_src_index + src_nents) * + sizeof(struct sec4_sg_entry); + + /* allocate space for base edesc and hw desc commands, link tables */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN + + sec4_sg_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); + + edesc->src_nents = src_nents; + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); + + ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, edesc->sec4_sg, + DMA_TO_DEVICE); + + state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1, + buf, state->buf_dma, buflen, + last_buflen); + + src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + + sec4_sg_src_index); + + append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + + buflen + req->nbytes, LDST_SGF); + + edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result, + digestsize); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_src, req); + if (!ret) { + ret = -EINPROGRESS; + } else { + ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE); + kfree(edesc); + } + + return ret; +} + +static int ahash_digest(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u32 *sh_desc = ctx->sh_desc_digest, *desc; + dma_addr_t ptr = ctx->sh_desc_digest_dma; + int digestsize = crypto_ahash_digestsize(ahash); + int src_nents, sec4_sg_bytes; + dma_addr_t src_dma; + struct ahash_edesc *edesc; + int ret = 0; + u32 options; + int sh_len; + + src_nents = sg_count(req->src, req->nbytes); + dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE); + sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry); + + /* allocate space for base edesc and hw desc commands, link tables */ + edesc = kmalloc(sizeof(struct ahash_edesc) + sec4_sg_bytes + + DESC_JOB_IO_LEN, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, "could not allocate extended descriptor\n"); + return -ENOMEM; + } + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); + edesc->src_nents = src_nents; + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); + + if (src_nents) { + sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0); + src_dma = edesc->sec4_sg_dma; + options = LDST_SGF; + } else { + src_dma = sg_dma_address(req->src); + options = 0; + } + append_seq_in_ptr(desc, src_dma, req->nbytes, options); + + edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result, + digestsize); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done, req); + if (!ret) { + ret = -EINPROGRESS; + } else { + ahash_unmap(jrdev, edesc, req, digestsize); + kfree(edesc); + } + + return ret; +} + +/* submit ahash final if it the first job descriptor */ +static int ahash_final_no_ctx(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *buf = state->current_buf ? state->buf_1 : state->buf_0; + int buflen = state->current_buf ? state->buflen_1 : state->buflen_0; + u32 *sh_desc = ctx->sh_desc_digest, *desc; + dma_addr_t ptr = ctx->sh_desc_digest_dma; + int digestsize = crypto_ahash_digestsize(ahash); + struct ahash_edesc *edesc; + int ret = 0; + int sh_len; + + /* allocate space for base edesc and hw desc commands, link tables */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN, + GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); + + state->buf_dma = dma_map_single(jrdev, buf, buflen, DMA_TO_DEVICE); + + append_seq_in_ptr(desc, state->buf_dma, buflen, 0); + + edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result, + digestsize); + edesc->src_nents = 0; + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done, req); + if (!ret) { + ret = -EINPROGRESS; + } else { + ahash_unmap(jrdev, edesc, req, digestsize); + kfree(edesc); + } + + return ret; +} + +/* submit ahash update if it the first job descriptor after update */ +static int ahash_update_no_ctx(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *buf = state->current_buf ? state->buf_1 : state->buf_0; + int *buflen = state->current_buf ? &state->buflen_1 : &state->buflen_0; + u8 *next_buf = state->current_buf ? state->buf_0 : state->buf_1; + int *next_buflen = state->current_buf ? &state->buflen_0 : + &state->buflen_1; + int in_len = *buflen + req->nbytes, to_hash; + int sec4_sg_bytes, src_nents; + struct ahash_edesc *edesc; + u32 *desc, *sh_desc = ctx->sh_desc_update_first; + dma_addr_t ptr = ctx->sh_desc_update_first_dma; + int ret = 0; + int sh_len; + + *next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1); + to_hash = in_len - *next_buflen; + + if (to_hash) { + src_nents = __sg_count(req->src, req->nbytes - (*next_buflen)); + sec4_sg_bytes = (1 + src_nents) * + sizeof(struct sec4_sg_entry); + + /* + * allocate space for base edesc and hw desc commands, + * link tables + */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN + + sec4_sg_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, + "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + edesc->src_nents = src_nents; + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, + DMA_TO_DEVICE); + + state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, + buf, *buflen); + src_map_to_sec4_sg(jrdev, req->src, src_nents, + edesc->sec4_sg + 1); + if (*next_buflen) { + sg_copy_part(next_buf, req->src, to_hash - *buflen, + req->nbytes); + state->current_buf = !state->current_buf; + } + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | + HDR_REVERSE); + + append_seq_in_ptr(desc, edesc->sec4_sg_dma, to_hash, LDST_SGF); + + map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_dst, req); + if (!ret) { + ret = -EINPROGRESS; + state->update = ahash_update_ctx; + state->finup = ahash_finup_ctx; + state->final = ahash_final_ctx; + } else { + ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, + DMA_TO_DEVICE); + kfree(edesc); + } + } else if (*next_buflen) { + sg_copy(buf + *buflen, req->src, req->nbytes); + *buflen = *next_buflen; + *next_buflen = 0; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "buf@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, buf, *buflen, 1); + print_hex_dump(KERN_ERR, "next buf@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, next_buf, + *next_buflen, 1); +#endif + + return ret; +} + +/* submit ahash finup if it the first job descriptor after update */ +static int ahash_finup_no_ctx(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *buf = state->current_buf ? state->buf_1 : state->buf_0; + int buflen = state->current_buf ? state->buflen_1 : state->buflen_0; + int last_buflen = state->current_buf ? state->buflen_0 : + state->buflen_1; + u32 *sh_desc = ctx->sh_desc_digest, *desc; + dma_addr_t ptr = ctx->sh_desc_digest_dma; + int sec4_sg_bytes, sec4_sg_src_index, src_nents; + int digestsize = crypto_ahash_digestsize(ahash); + struct ahash_edesc *edesc; + int sh_len; + int ret = 0; + + src_nents = __sg_count(req->src, req->nbytes); + sec4_sg_src_index = 2; + sec4_sg_bytes = (sec4_sg_src_index + src_nents) * + sizeof(struct sec4_sg_entry); + + /* allocate space for base edesc and hw desc commands, link tables */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN + + sec4_sg_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); + + edesc->src_nents = src_nents; + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, DMA_TO_DEVICE); + + state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, buf, + state->buf_dma, buflen, + last_buflen); + + src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1); + + append_seq_in_ptr(desc, edesc->sec4_sg_dma, buflen + + req->nbytes, LDST_SGF); + + edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result, + digestsize); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done, req); + if (!ret) { + ret = -EINPROGRESS; + } else { + ahash_unmap(jrdev, edesc, req, digestsize); + kfree(edesc); + } + + return ret; +} + +/* submit first update job descriptor after init */ +static int ahash_update_first(struct ahash_request *req) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + struct device *jrdev = ctx->jrdev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + u8 *next_buf = state->buf_0 + state->current_buf * + CAAM_MAX_HASH_BLOCK_SIZE; + int *next_buflen = &state->buflen_0 + state->current_buf; + int to_hash; + u32 *sh_desc = ctx->sh_desc_update_first, *desc; + dma_addr_t ptr = ctx->sh_desc_update_first_dma; + int sec4_sg_bytes, src_nents; + dma_addr_t src_dma; + u32 options; + struct ahash_edesc *edesc; + int ret = 0; + int sh_len; + + *next_buflen = req->nbytes & (crypto_tfm_alg_blocksize(&ahash->base) - + 1); + to_hash = req->nbytes - *next_buflen; + + if (to_hash) { + src_nents = sg_count(req->src, req->nbytes - (*next_buflen)); + dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE); + sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry); + + /* + * allocate space for base edesc and hw desc commands, + * link tables + */ + edesc = kmalloc(sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN + + sec4_sg_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, + "could not allocate extended descriptor\n"); + return -ENOMEM; + } + + edesc->src_nents = src_nents; + edesc->sec4_sg_bytes = sec4_sg_bytes; + edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + + DESC_JOB_IO_LEN; + edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, + sec4_sg_bytes, + DMA_TO_DEVICE); + + if (src_nents) { + sg_to_sec4_sg_last(req->src, src_nents, + edesc->sec4_sg, 0); + src_dma = edesc->sec4_sg_dma; + options = LDST_SGF; + } else { + src_dma = sg_dma_address(req->src); + options = 0; + } + + if (*next_buflen) + sg_copy_part(next_buf, req->src, to_hash, req->nbytes); + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; + init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | + HDR_REVERSE); + + append_seq_in_ptr(desc, src_dma, to_hash, options); + + map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_dst, + req); + if (!ret) { + ret = -EINPROGRESS; + state->update = ahash_update_ctx; + state->finup = ahash_finup_ctx; + state->final = ahash_final_ctx; + } else { + ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, + DMA_TO_DEVICE); + kfree(edesc); + } + } else if (*next_buflen) { + state->update = ahash_update_no_ctx; + state->finup = ahash_finup_no_ctx; + state->final = ahash_final_no_ctx; + sg_copy(next_buf, req->src, req->nbytes); + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "next buf@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, next_buf, + *next_buflen, 1); +#endif + + return ret; +} + +static int ahash_finup_first(struct ahash_request *req) +{ + return ahash_digest(req); +} + +static int ahash_init(struct ahash_request *req) +{ + struct caam_hash_state *state = ahash_request_ctx(req); + + state->update = ahash_update_first; + state->finup = ahash_finup_first; + state->final = ahash_final_no_ctx; + + state->current_buf = 0; + + return 0; +} + +static int ahash_update(struct ahash_request *req) +{ + struct caam_hash_state *state = ahash_request_ctx(req); + + return state->update(req); +} + +static int ahash_finup(struct ahash_request *req) +{ + struct caam_hash_state *state = ahash_request_ctx(req); + + return state->finup(req); +} + +static int ahash_final(struct ahash_request *req) +{ + struct caam_hash_state *state = ahash_request_ctx(req); + + return state->final(req); +} + +static int ahash_export(struct ahash_request *req, void *out) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + + memcpy(out, ctx, sizeof(struct caam_hash_ctx)); + memcpy(out + sizeof(struct caam_hash_ctx), state, + sizeof(struct caam_hash_state)); + return 0; +} + +static int ahash_import(struct ahash_request *req, const void *in) +{ + struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + + memcpy(ctx, in, sizeof(struct caam_hash_ctx)); + memcpy(state, in + sizeof(struct caam_hash_ctx), + sizeof(struct caam_hash_state)); + return 0; +} + +struct caam_hash_template { + char name[CRYPTO_MAX_ALG_NAME]; + char driver_name[CRYPTO_MAX_ALG_NAME]; + unsigned int blocksize; + struct ahash_alg template_ahash; + u32 alg_type; + u32 alg_op; +}; + +/* ahash descriptors */ +static struct caam_hash_template driver_hash[] = { + { + .name = "hmac(sha1)", + .driver_name = "hmac-sha1-caam", + .blocksize = SHA1_BLOCK_SIZE, + .template_ahash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .export = ahash_export, + .import = ahash_import, + .setkey = ahash_setkey, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + }, + }, + .alg_type = OP_ALG_ALGSEL_SHA1, + .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, + }, { + .name = "hmac(sha224)", + .driver_name = "hmac-sha224-caam", + .blocksize = SHA224_BLOCK_SIZE, + .template_ahash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .export = ahash_export, + .import = ahash_import, + .setkey = ahash_setkey, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + }, + }, + .alg_type = OP_ALG_ALGSEL_SHA224, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { + .name = "hmac(sha256)", + .driver_name = "hmac-sha256-caam", + .blocksize = SHA256_BLOCK_SIZE, + .template_ahash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .export = ahash_export, + .import = ahash_import, + .setkey = ahash_setkey, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + }, + }, + .alg_type = OP_ALG_ALGSEL_SHA256, + .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, + }, { + .name = "hmac(sha384)", + .driver_name = "hmac-sha384-caam", + .blocksize = SHA384_BLOCK_SIZE, + .template_ahash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .export = ahash_export, + .import = ahash_import, + .setkey = ahash_setkey, + .halg = { + .digestsize = SHA384_DIGEST_SIZE, + }, + }, + .alg_type = OP_ALG_ALGSEL_SHA384, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, { + .name = "hmac(sha512)", + .driver_name = "hmac-sha512-caam", + .blocksize = SHA512_BLOCK_SIZE, + .template_ahash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .export = ahash_export, + .import = ahash_import, + .setkey = ahash_setkey, + .halg = { + .digestsize = SHA512_DIGEST_SIZE, + }, + }, + .alg_type = OP_ALG_ALGSEL_SHA512, + .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, + }, { + .name = "hmac(md5)", + .driver_name = "hmac-md5-caam", + .blocksize = MD5_BLOCK_WORDS * 4, + .template_ahash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .export = ahash_export, + .import = ahash_import, + .setkey = ahash_setkey, + .halg = { + .digestsize = MD5_DIGEST_SIZE, + }, + }, + .alg_type = OP_ALG_ALGSEL_MD5, + .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC, + }, +}; + +struct caam_hash_alg { + struct list_head entry; + struct device *ctrldev; + int alg_type; + int alg_op; + struct ahash_alg ahash_alg; +}; + +static int caam_hash_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); + struct crypto_alg *base = tfm->__crt_alg; + struct hash_alg_common *halg = + container_of(base, struct hash_alg_common, base); + struct ahash_alg *alg = + container_of(halg, struct ahash_alg, halg); + struct caam_hash_alg *caam_hash = + container_of(alg, struct caam_hash_alg, ahash_alg); + struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm); + struct caam_drv_private *priv = dev_get_drvdata(caam_hash->ctrldev); + /* Sizes for MDHA running digests: MD5, SHA1, 224, 256, 384, 512 */ + static const u8 runninglen[] = { HASH_MSG_LEN + MD5_DIGEST_SIZE, + HASH_MSG_LEN + SHA1_DIGEST_SIZE, + HASH_MSG_LEN + 32, + HASH_MSG_LEN + SHA256_DIGEST_SIZE, + HASH_MSG_LEN + 64, + HASH_MSG_LEN + SHA512_DIGEST_SIZE }; + int tgt_jr = atomic_inc_return(&priv->tfm_count); + int ret = 0; + + /* + * distribute tfms across job rings to ensure in-order + * crypto request processing per tfm + */ + ctx->jrdev = priv->jrdev[tgt_jr % priv->total_jobrs]; + + /* copy descriptor header template value */ + ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type; + ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_hash->alg_op; + + ctx->ctx_len = runninglen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> + OP_ALG_ALGSEL_SHIFT]; + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct caam_hash_state)); + + ret = ahash_set_sh_desc(ahash); + + return ret; +} + +static void caam_hash_cra_exit(struct crypto_tfm *tfm) +{ + struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->sh_desc_update_dma && + !dma_mapping_error(ctx->jrdev, ctx->sh_desc_update_dma)) + dma_unmap_single(ctx->jrdev, ctx->sh_desc_update_dma, + desc_bytes(ctx->sh_desc_update), + DMA_TO_DEVICE); + if (ctx->sh_desc_update_first_dma && + !dma_mapping_error(ctx->jrdev, ctx->sh_desc_update_first_dma)) + dma_unmap_single(ctx->jrdev, ctx->sh_desc_update_first_dma, + desc_bytes(ctx->sh_desc_update_first), + DMA_TO_DEVICE); + if (ctx->sh_desc_fin_dma && + !dma_mapping_error(ctx->jrdev, ctx->sh_desc_fin_dma)) + dma_unmap_single(ctx->jrdev, ctx->sh_desc_fin_dma, + desc_bytes(ctx->sh_desc_fin), DMA_TO_DEVICE); + if (ctx->sh_desc_digest_dma && + !dma_mapping_error(ctx->jrdev, ctx->sh_desc_digest_dma)) + dma_unmap_single(ctx->jrdev, ctx->sh_desc_digest_dma, + desc_bytes(ctx->sh_desc_digest), + DMA_TO_DEVICE); + if (ctx->sh_desc_finup_dma && + !dma_mapping_error(ctx->jrdev, ctx->sh_desc_finup_dma)) + dma_unmap_single(ctx->jrdev, ctx->sh_desc_finup_dma, + desc_bytes(ctx->sh_desc_finup), DMA_TO_DEVICE); +} + +static void __exit caam_algapi_hash_exit(void) +{ + struct device_node *dev_node; + struct platform_device *pdev; + struct device *ctrldev; + struct caam_drv_private *priv; + struct caam_hash_alg *t_alg, *n; + + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); + if (!dev_node) + return; + + pdev = of_find_device_by_node(dev_node); + if (!pdev) + return; + + ctrldev = &pdev->dev; + of_node_put(dev_node); + priv = dev_get_drvdata(ctrldev); + + if (!priv->hash_list.next) + return; + + list_for_each_entry_safe(t_alg, n, &priv->hash_list, entry) { + crypto_unregister_ahash(&t_alg->ahash_alg); + list_del(&t_alg->entry); + kfree(t_alg); + } +} + +static struct caam_hash_alg * +caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template) +{ + struct caam_hash_alg *t_alg; + struct ahash_alg *halg; + struct crypto_alg *alg; + + t_alg = kzalloc(sizeof(struct caam_hash_alg), GFP_KERNEL); + if (!t_alg) { + dev_err(ctrldev, "failed to allocate t_alg\n"); + return ERR_PTR(-ENOMEM); + } + + t_alg->ahash_alg = template->template_ahash; + halg = &t_alg->ahash_alg; + alg = &halg->halg.base; + + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + alg->cra_module = THIS_MODULE; + alg->cra_init = caam_hash_cra_init; + alg->cra_exit = caam_hash_cra_exit; + alg->cra_ctxsize = sizeof(struct caam_hash_ctx); + alg->cra_priority = CAAM_CRA_PRIORITY; + alg->cra_blocksize = template->blocksize; + alg->cra_alignmask = 0; + alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_TYPE_AHASH; + alg->cra_type = &crypto_ahash_type; + + t_alg->alg_type = template->alg_type; + t_alg->alg_op = template->alg_op; + t_alg->ctrldev = ctrldev; + + return t_alg; +} + +static int __init caam_algapi_hash_init(void) +{ + struct device_node *dev_node; + struct platform_device *pdev; + struct device *ctrldev; + struct caam_drv_private *priv; + int i = 0, err = 0; + + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); + if (!dev_node) + return -ENODEV; + + pdev = of_find_device_by_node(dev_node); + if (!pdev) + return -ENODEV; + + ctrldev = &pdev->dev; + priv = dev_get_drvdata(ctrldev); + of_node_put(dev_node); + + INIT_LIST_HEAD(&priv->hash_list); + + atomic_set(&priv->tfm_count, -1); + + /* register crypto algorithms the device supports */ + for (i = 0; i < ARRAY_SIZE(driver_hash); i++) { + /* TODO: check if h/w supports alg */ + struct caam_hash_alg *t_alg; + + t_alg = caam_hash_alloc(ctrldev, &driver_hash[i]); + if (IS_ERR(t_alg)) { + err = PTR_ERR(t_alg); + dev_warn(ctrldev, "%s alg allocation failed\n", + driver_hash[i].driver_name); + continue; + } + + err = crypto_register_ahash(&t_alg->ahash_alg); + if (err) { + dev_warn(ctrldev, "%s alg registration failed\n", + t_alg->ahash_alg.halg.base.cra_driver_name); + kfree(t_alg); + } else + list_add_tail(&t_alg->entry, &priv->hash_list); + } + + return err; +} + +module_init(caam_algapi_hash_init); +module_exit(caam_algapi_hash_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("FSL CAAM support for ahash functions of crypto API"); +MODULE_AUTHOR("Freescale Semiconductor - NMG"); diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h index a63bc65fae86..762aeff626ac 100644 --- a/drivers/crypto/caam/compat.h +++ b/drivers/crypto/caam/compat.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -33,5 +34,6 @@ #include #include #include +#include #endif /* !defined(CAAM_COMPAT_H) */ diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index 462be99d9a3c..ed2b739f934b 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -88,6 +88,8 @@ struct caam_drv_private { atomic_t tfm_count ____cacheline_aligned; /* list of registered crypto algorithms (mk generic context handle?) */ struct list_head alg_list; + /* list of registered hash algorithms (mk generic context handle?) */ + struct list_head hash_list; /* * debugfs entries for developer view into driver/device diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h index a6ad7a443213..2dda9e3a5e67 100644 --- a/drivers/crypto/caam/sg_sw_sec4.h +++ b/drivers/crypto/caam/sg_sw_sec4.h @@ -82,3 +82,41 @@ static inline int sg_count(struct scatterlist *sg_list, int nbytes) return sg_nents; } + +/* Copy from len bytes of sg to dest, starting from beginning */ +static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) +{ + struct scatterlist *current_sg = sg; + int cpy_index = 0, next_cpy_index = current_sg->length; + + while (next_cpy_index < len) { + memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg), + current_sg->length); + current_sg = scatterwalk_sg_next(current_sg); + cpy_index = next_cpy_index; + next_cpy_index += current_sg->length; + } + if (cpy_index < len) + memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg), + len - cpy_index); +} + +/* Copy sg data, from to_skip to end, to dest */ +static inline void sg_copy_part(u8 *dest, struct scatterlist *sg, + int to_skip, unsigned int end) +{ + struct scatterlist *current_sg = sg; + int sg_index, cpy_index; + + sg_index = current_sg->length; + while (sg_index <= to_skip) { + current_sg = scatterwalk_sg_next(current_sg); + sg_index += current_sg->length; + } + cpy_index = sg_index - to_skip; + memcpy(dest, (u8 *) sg_virt(current_sg) + + current_sg->length - cpy_index, cpy_index); + current_sg = scatterwalk_sg_next(current_sg); + if (end - sg_index) + sg_copy(dest + cpy_index, current_sg, end - sg_index); +} -- GitLab From b0e09bae37eeacb213d9baf8fcb4d48934a4ada5 Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:48 -0500 Subject: [PATCH 2997/6849] crypto: caam - unkeyed ahash support caam supports and registers unkeyed sha algorithms and md5. Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamhash.c | 75 ++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index c0b6d86577cf..7dcf28f48149 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -1485,6 +1485,8 @@ static int ahash_import(struct ahash_request *req, const void *in) struct caam_hash_template { char name[CRYPTO_MAX_ALG_NAME]; char driver_name[CRYPTO_MAX_ALG_NAME]; + char hmac_name[CRYPTO_MAX_ALG_NAME]; + char hmac_driver_name[CRYPTO_MAX_ALG_NAME]; unsigned int blocksize; struct ahash_alg template_ahash; u32 alg_type; @@ -1494,8 +1496,10 @@ struct caam_hash_template { /* ahash descriptors */ static struct caam_hash_template driver_hash[] = { { - .name = "hmac(sha1)", - .driver_name = "hmac-sha1-caam", + .name = "sha1", + .driver_name = "sha1-caam", + .hmac_name = "hmac(sha1)", + .hmac_driver_name = "hmac-sha1-caam", .blocksize = SHA1_BLOCK_SIZE, .template_ahash = { .init = ahash_init, @@ -1513,8 +1517,10 @@ static struct caam_hash_template driver_hash[] = { .alg_type = OP_ALG_ALGSEL_SHA1, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, { - .name = "hmac(sha224)", - .driver_name = "hmac-sha224-caam", + .name = "sha224", + .driver_name = "sha224-caam", + .hmac_name = "hmac(sha224)", + .hmac_driver_name = "hmac-sha224-caam", .blocksize = SHA224_BLOCK_SIZE, .template_ahash = { .init = ahash_init, @@ -1532,8 +1538,10 @@ static struct caam_hash_template driver_hash[] = { .alg_type = OP_ALG_ALGSEL_SHA224, .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, }, { - .name = "hmac(sha256)", - .driver_name = "hmac-sha256-caam", + .name = "sha256", + .driver_name = "sha256-caam", + .hmac_name = "hmac(sha256)", + .hmac_driver_name = "hmac-sha256-caam", .blocksize = SHA256_BLOCK_SIZE, .template_ahash = { .init = ahash_init, @@ -1551,8 +1559,10 @@ static struct caam_hash_template driver_hash[] = { .alg_type = OP_ALG_ALGSEL_SHA256, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, { - .name = "hmac(sha384)", - .driver_name = "hmac-sha384-caam", + .name = "sha384", + .driver_name = "sha384-caam", + .hmac_name = "hmac(sha384)", + .hmac_driver_name = "hmac-sha384-caam", .blocksize = SHA384_BLOCK_SIZE, .template_ahash = { .init = ahash_init, @@ -1570,8 +1580,10 @@ static struct caam_hash_template driver_hash[] = { .alg_type = OP_ALG_ALGSEL_SHA384, .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, }, { - .name = "hmac(sha512)", - .driver_name = "hmac-sha512-caam", + .name = "sha512", + .driver_name = "sha512-caam", + .hmac_name = "hmac(sha512)", + .hmac_driver_name = "hmac-sha512-caam", .blocksize = SHA512_BLOCK_SIZE, .template_ahash = { .init = ahash_init, @@ -1589,8 +1601,10 @@ static struct caam_hash_template driver_hash[] = { .alg_type = OP_ALG_ALGSEL_SHA512, .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, }, { - .name = "hmac(md5)", - .driver_name = "hmac-md5-caam", + .name = "md5", + .driver_name = "md5-caam", + .hmac_name = "hmac(md5)", + .hmac_driver_name = "hmac-md5-caam", .blocksize = MD5_BLOCK_WORDS * 4, .template_ahash = { .init = ahash_init, @@ -1721,7 +1735,8 @@ static void __exit caam_algapi_hash_exit(void) } static struct caam_hash_alg * -caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template) +caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template, + bool keyed) { struct caam_hash_alg *t_alg; struct ahash_alg *halg; @@ -1737,9 +1752,17 @@ caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template) halg = &t_alg->ahash_alg; alg = &halg->halg.base; - snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); - snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", - template->driver_name); + if (keyed) { + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", + template->hmac_name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->hmac_driver_name); + } else { + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", + template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + } alg->cra_module = THIS_MODULE; alg->cra_init = caam_hash_cra_init; alg->cra_exit = caam_hash_cra_exit; @@ -1786,7 +1809,25 @@ static int __init caam_algapi_hash_init(void) /* TODO: check if h/w supports alg */ struct caam_hash_alg *t_alg; - t_alg = caam_hash_alloc(ctrldev, &driver_hash[i]); + /* register hmac version */ + t_alg = caam_hash_alloc(ctrldev, &driver_hash[i], true); + if (IS_ERR(t_alg)) { + err = PTR_ERR(t_alg); + dev_warn(ctrldev, "%s alg allocation failed\n", + driver_hash[i].driver_name); + continue; + } + + err = crypto_register_ahash(&t_alg->ahash_alg); + if (err) { + dev_warn(ctrldev, "%s alg registration failed\n", + t_alg->ahash_alg.halg.base.cra_driver_name); + kfree(t_alg); + } else + list_add_tail(&t_alg->entry, &priv->hash_list); + + /* register unkeyed version */ + t_alg = caam_hash_alloc(ctrldev, &driver_hash[i], false); if (IS_ERR(t_alg)) { err = PTR_ERR(t_alg); dev_warn(ctrldev, "%s alg allocation failed\n", -- GitLab From 643b39b031f546c7c3c60ef360b8260aa2b32762 Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:49 -0500 Subject: [PATCH 2998/6849] crypto: caam - chaining support support chained scatterlists for aead, ablkcipher and ahash. Signed-off-by: Yuan Kang - fix dma unmap leak - un-unlikely src == dst, due to experience with AF_ALG Signed-off-by: Kudupudi Ugendreshwar Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 114 +++++++++++++++++++------------ drivers/crypto/caam/caamhash.c | 53 ++++++++++---- drivers/crypto/caam/sg_sw_sec4.h | 44 ++++++++++-- 3 files changed, 147 insertions(+), 64 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 5ab480a12b51..0c1ea8492eff 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -654,8 +654,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, /* * aead_edesc - s/w-extended aead descriptor * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist + * @assoc_chained: if source is chained * @src_nents: number of segments in input scatterlist + * @src_chained: if source is chained * @dst_nents: number of segments in output scatterlist + * @dst_chained: if destination is chained * @iv_dma: dma address of iv for checking continuity and link table * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) * @sec4_sg_bytes: length of dma mapped sec4_sg space @@ -664,8 +667,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, */ struct aead_edesc { int assoc_nents; + bool assoc_chained; int src_nents; + bool src_chained; int dst_nents; + bool dst_chained; dma_addr_t iv_dma; int sec4_sg_bytes; dma_addr_t sec4_sg_dma; @@ -676,7 +682,9 @@ struct aead_edesc { /* * ablkcipher_edesc - s/w-extended ablkcipher descriptor * @src_nents: number of segments in input scatterlist + * @src_chained: if source is chained * @dst_nents: number of segments in output scatterlist + * @dst_chained: if destination is chained * @iv_dma: dma address of iv for checking continuity and link table * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) * @sec4_sg_bytes: length of dma mapped sec4_sg space @@ -685,7 +693,9 @@ struct aead_edesc { */ struct ablkcipher_edesc { int src_nents; + bool src_chained; int dst_nents; + bool dst_chained; dma_addr_t iv_dma; int sec4_sg_bytes; dma_addr_t sec4_sg_dma; @@ -694,15 +704,19 @@ struct ablkcipher_edesc { }; static void caam_unmap(struct device *dev, struct scatterlist *src, - struct scatterlist *dst, int src_nents, int dst_nents, + struct scatterlist *dst, int src_nents, + bool src_chained, int dst_nents, bool dst_chained, dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma, int sec4_sg_bytes) { - if (unlikely(dst != src)) { - dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); - dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); + if (dst != src) { + dma_unmap_sg_chained(dev, src, src_nents ? : 1, DMA_TO_DEVICE, + src_chained); + dma_unmap_sg_chained(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE, + dst_chained); } else { - dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); + dma_unmap_sg_chained(dev, src, src_nents ? : 1, + DMA_BIDIRECTIONAL, src_chained); } if (iv_dma) @@ -719,12 +733,13 @@ static void aead_unmap(struct device *dev, struct crypto_aead *aead = crypto_aead_reqtfm(req); int ivsize = crypto_aead_ivsize(aead); - dma_unmap_sg(dev, req->assoc, edesc->assoc_nents, DMA_TO_DEVICE); + dma_unmap_sg_chained(dev, req->assoc, edesc->assoc_nents, + DMA_TO_DEVICE, edesc->assoc_chained); caam_unmap(dev, req->src, req->dst, - edesc->src_nents, edesc->dst_nents, - edesc->iv_dma, ivsize, edesc->sec4_sg_dma, - edesc->sec4_sg_bytes); + edesc->src_nents, edesc->src_chained, edesc->dst_nents, + edesc->dst_chained, edesc->iv_dma, ivsize, + edesc->sec4_sg_dma, edesc->sec4_sg_bytes); } static void ablkcipher_unmap(struct device *dev, @@ -735,9 +750,9 @@ static void ablkcipher_unmap(struct device *dev, int ivsize = crypto_ablkcipher_ivsize(ablkcipher); caam_unmap(dev, req->src, req->dst, - edesc->src_nents, edesc->dst_nents, - edesc->iv_dma, ivsize, edesc->sec4_sg_dma, - edesc->sec4_sg_bytes); + edesc->src_nents, edesc->src_chained, edesc->dst_nents, + edesc->dst_chained, edesc->iv_dma, ivsize, + edesc->sec4_sg_dma, edesc->sec4_sg_bytes); } static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err, @@ -1128,25 +1143,26 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, dma_addr_t iv_dma = 0; int sgc; bool all_contig = true; + bool assoc_chained = false, src_chained = false, dst_chained = false; int ivsize = crypto_aead_ivsize(aead); int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; - assoc_nents = sg_count(req->assoc, req->assoclen); - src_nents = sg_count(req->src, req->cryptlen); + assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); + src_nents = sg_count(req->src, req->cryptlen, &src_chained); if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen); + dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); - sgc = dma_map_sg(jrdev, req->assoc, assoc_nents ? : 1, - DMA_BIDIRECTIONAL); + sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, + DMA_BIDIRECTIONAL, assoc_chained); if (likely(req->src == req->dst)) { - sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, - DMA_BIDIRECTIONAL); + sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_BIDIRECTIONAL, src_chained); } else { - sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, - DMA_TO_DEVICE); - sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, - DMA_FROM_DEVICE); + sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_TO_DEVICE, src_chained); + sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1, + DMA_FROM_DEVICE, dst_chained); } /* Check if data are contiguous */ @@ -1172,8 +1188,11 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, } edesc->assoc_nents = assoc_nents; + edesc->assoc_chained = assoc_chained; edesc->src_nents = src_nents; + edesc->src_chained = src_chained; edesc->dst_nents = dst_nents; + edesc->dst_chained = dst_chained; edesc->iv_dma = iv_dma; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + @@ -1307,24 +1326,25 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request int sgc; u32 contig = GIV_SRC_CONTIG | GIV_DST_CONTIG; int ivsize = crypto_aead_ivsize(aead); + bool assoc_chained = false, src_chained = false, dst_chained = false; int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; - assoc_nents = sg_count(req->assoc, req->assoclen); - src_nents = sg_count(req->src, req->cryptlen); + assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); + src_nents = sg_count(req->src, req->cryptlen, &src_chained); if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen); + dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); - sgc = dma_map_sg(jrdev, req->assoc, assoc_nents ? : 1, - DMA_BIDIRECTIONAL); + sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, + DMA_BIDIRECTIONAL, assoc_chained); if (likely(req->src == req->dst)) { - sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, - DMA_BIDIRECTIONAL); + sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_BIDIRECTIONAL, src_chained); } else { - sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, - DMA_TO_DEVICE); - sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, - DMA_FROM_DEVICE); + sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_TO_DEVICE, src_chained); + sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1, + DMA_FROM_DEVICE, dst_chained); } /* Check if data are contiguous */ @@ -1358,8 +1378,11 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request } edesc->assoc_nents = assoc_nents; + edesc->assoc_chained = assoc_chained; edesc->src_nents = src_nents; + edesc->src_chained = src_chained; edesc->dst_nents = dst_nents; + edesc->dst_chained = dst_chained; edesc->iv_dma = iv_dma; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + @@ -1459,21 +1482,22 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request bool iv_contig = false; int sgc; int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + bool src_chained = false, dst_chained = false; int sec4_sg_index; - src_nents = sg_count(req->src, req->nbytes); + src_nents = sg_count(req->src, req->nbytes, &src_chained); - if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->nbytes); + if (req->dst != req->src) + dst_nents = sg_count(req->dst, req->nbytes, &dst_chained); if (likely(req->src == req->dst)) { - sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, - DMA_BIDIRECTIONAL); + sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_BIDIRECTIONAL, src_chained); } else { - sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, - DMA_TO_DEVICE); - sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, - DMA_FROM_DEVICE); + sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_TO_DEVICE, src_chained); + sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1, + DMA_FROM_DEVICE, dst_chained); } /* @@ -1497,7 +1521,9 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request } edesc->src_nents = src_nents; + edesc->src_chained = src_chained; edesc->dst_nents = dst_nents; + edesc->dst_chained = dst_chained; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) + desc_bytes; @@ -1510,7 +1536,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request sec4_sg_index += 1 + src_nents; } - if (unlikely(dst_nents)) { + if (dst_nents) { sg_to_sec4_sg_last(req->dst, dst_nents, edesc->sec4_sg + sec4_sg_index, 0); } diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index 7dcf28f48149..895aaf2bca92 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -175,9 +175,10 @@ static inline dma_addr_t buf_map_to_sec4_sg(struct device *jrdev, /* Map req->src and put it in link table */ static inline void src_map_to_sec4_sg(struct device *jrdev, struct scatterlist *src, int src_nents, - struct sec4_sg_entry *sec4_sg) + struct sec4_sg_entry *sec4_sg, + bool chained) { - dma_map_sg(jrdev, src, src_nents, DMA_TO_DEVICE); + dma_map_sg_chained(jrdev, src, src_nents, DMA_TO_DEVICE, chained); sg_to_sec4_sg_last(src, src_nents, sec4_sg, 0); } @@ -563,6 +564,7 @@ badkey: * ahash_edesc - s/w-extended ahash descriptor * @dst_dma: physical mapped address of req->result * @sec4_sg_dma: physical mapped address of h/w link table + * @chained: if source is chained * @src_nents: number of segments in input scatterlist * @sec4_sg_bytes: length of dma mapped sec4_sg space * @sec4_sg: pointer to h/w link table @@ -571,6 +573,7 @@ badkey: struct ahash_edesc { dma_addr_t dst_dma; dma_addr_t sec4_sg_dma; + bool chained; int src_nents; int sec4_sg_bytes; struct sec4_sg_entry *sec4_sg; @@ -582,7 +585,8 @@ static inline void ahash_unmap(struct device *dev, struct ahash_request *req, int dst_len) { if (edesc->src_nents) - dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE); + dma_unmap_sg_chained(dev, req->src, edesc->src_nents, + DMA_TO_DEVICE, edesc->chained); if (edesc->dst_dma) dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE); @@ -775,6 +779,7 @@ static int ahash_update_ctx(struct ahash_request *req) dma_addr_t ptr = ctx->sh_desc_update_dma; int src_nents, sec4_sg_bytes, sec4_sg_src_index; struct ahash_edesc *edesc; + bool chained = false; int ret = 0; int sh_len; @@ -783,7 +788,8 @@ static int ahash_update_ctx(struct ahash_request *req) to_hash = in_len - *next_buflen; if (to_hash) { - src_nents = __sg_count(req->src, req->nbytes - (*next_buflen)); + src_nents = __sg_count(req->src, req->nbytes - (*next_buflen), + &chained); sec4_sg_src_index = 1 + (*buflen ? 1 : 0); sec4_sg_bytes = (sec4_sg_src_index + src_nents) * sizeof(struct sec4_sg_entry); @@ -801,6 +807,7 @@ static int ahash_update_ctx(struct ahash_request *req) } edesc->src_nents = src_nents; + edesc->chained = chained; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN; @@ -818,7 +825,8 @@ static int ahash_update_ctx(struct ahash_request *req) if (src_nents) { src_map_to_sec4_sg(jrdev, req->src, src_nents, - edesc->sec4_sg + sec4_sg_src_index); + edesc->sec4_sg + sec4_sg_src_index, + chained); if (*next_buflen) { sg_copy_part(next_buf, req->src, to_hash - *buflen, req->nbytes); @@ -958,10 +966,11 @@ static int ahash_finup_ctx(struct ahash_request *req) int src_nents; int digestsize = crypto_ahash_digestsize(ahash); struct ahash_edesc *edesc; + bool chained = false; int ret = 0; int sh_len; - src_nents = __sg_count(req->src, req->nbytes); + src_nents = __sg_count(req->src, req->nbytes, &chained); sec4_sg_src_index = 1 + (buflen ? 1 : 0); sec4_sg_bytes = (sec4_sg_src_index + src_nents) * sizeof(struct sec4_sg_entry); @@ -979,6 +988,7 @@ static int ahash_finup_ctx(struct ahash_request *req) init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); edesc->src_nents = src_nents; + edesc->chained = chained; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN; @@ -993,7 +1003,7 @@ static int ahash_finup_ctx(struct ahash_request *req) last_buflen); src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + - sec4_sg_src_index); + sec4_sg_src_index, chained); append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + buflen + req->nbytes, LDST_SGF); @@ -1030,12 +1040,14 @@ static int ahash_digest(struct ahash_request *req) int src_nents, sec4_sg_bytes; dma_addr_t src_dma; struct ahash_edesc *edesc; + bool chained = false; int ret = 0; u32 options; int sh_len; - src_nents = sg_count(req->src, req->nbytes); - dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE); + src_nents = sg_count(req->src, req->nbytes, &chained); + dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE, + chained); sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry); /* allocate space for base edesc and hw desc commands, link tables */ @@ -1050,6 +1062,7 @@ static int ahash_digest(struct ahash_request *req) edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, sec4_sg_bytes, DMA_TO_DEVICE); edesc->src_nents = src_nents; + edesc->chained = chained; sh_len = desc_len(sh_desc); desc = edesc->hw_desc; @@ -1157,6 +1170,7 @@ static int ahash_update_no_ctx(struct ahash_request *req) struct ahash_edesc *edesc; u32 *desc, *sh_desc = ctx->sh_desc_update_first; dma_addr_t ptr = ctx->sh_desc_update_first_dma; + bool chained = false; int ret = 0; int sh_len; @@ -1164,7 +1178,8 @@ static int ahash_update_no_ctx(struct ahash_request *req) to_hash = in_len - *next_buflen; if (to_hash) { - src_nents = __sg_count(req->src, req->nbytes - (*next_buflen)); + src_nents = __sg_count(req->src, req->nbytes - (*next_buflen), + &chained); sec4_sg_bytes = (1 + src_nents) * sizeof(struct sec4_sg_entry); @@ -1181,6 +1196,7 @@ static int ahash_update_no_ctx(struct ahash_request *req) } edesc->src_nents = src_nents; + edesc->chained = chained; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN; @@ -1191,7 +1207,7 @@ static int ahash_update_no_ctx(struct ahash_request *req) state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, buf, *buflen); src_map_to_sec4_sg(jrdev, req->src, src_nents, - edesc->sec4_sg + 1); + edesc->sec4_sg + 1, chained); if (*next_buflen) { sg_copy_part(next_buf, req->src, to_hash - *buflen, req->nbytes); @@ -1258,10 +1274,11 @@ static int ahash_finup_no_ctx(struct ahash_request *req) int sec4_sg_bytes, sec4_sg_src_index, src_nents; int digestsize = crypto_ahash_digestsize(ahash); struct ahash_edesc *edesc; + bool chained = false; int sh_len; int ret = 0; - src_nents = __sg_count(req->src, req->nbytes); + src_nents = __sg_count(req->src, req->nbytes, &chained); sec4_sg_src_index = 2; sec4_sg_bytes = (sec4_sg_src_index + src_nents) * sizeof(struct sec4_sg_entry); @@ -1279,6 +1296,7 @@ static int ahash_finup_no_ctx(struct ahash_request *req) init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); edesc->src_nents = src_nents; + edesc->chained = chained; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN; @@ -1289,7 +1307,8 @@ static int ahash_finup_no_ctx(struct ahash_request *req) state->buf_dma, buflen, last_buflen); - src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1); + src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1, + chained); append_seq_in_ptr(desc, edesc->sec4_sg_dma, buflen + req->nbytes, LDST_SGF); @@ -1332,6 +1351,7 @@ static int ahash_update_first(struct ahash_request *req) dma_addr_t src_dma; u32 options; struct ahash_edesc *edesc; + bool chained = false; int ret = 0; int sh_len; @@ -1340,8 +1360,10 @@ static int ahash_update_first(struct ahash_request *req) to_hash = req->nbytes - *next_buflen; if (to_hash) { - src_nents = sg_count(req->src, req->nbytes - (*next_buflen)); - dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE); + src_nents = sg_count(req->src, req->nbytes - (*next_buflen), + &chained); + dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, + DMA_TO_DEVICE, chained); sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry); /* @@ -1357,6 +1379,7 @@ static int ahash_update_first(struct ahash_request *req) } edesc->src_nents = src_nents; + edesc->chained = chained; edesc->sec4_sg_bytes = sec4_sg_bytes; edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + DESC_JOB_IO_LEN; diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h index 2dda9e3a5e67..e0037c8ee243 100644 --- a/drivers/crypto/caam/sg_sw_sec4.h +++ b/drivers/crypto/caam/sg_sw_sec4.h @@ -37,7 +37,7 @@ sg_to_sec4_sg(struct scatterlist *sg, int sg_count, dma_to_sec4_sg_one(sec4_sg_ptr, sg_dma_address(sg), sg_dma_len(sg), offset); sec4_sg_ptr++; - sg = sg_next(sg); + sg = scatterwalk_sg_next(sg); sg_count--; } return sec4_sg_ptr - 1; @@ -56,7 +56,8 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count, } /* count number of elements in scatterlist */ -static inline int __sg_count(struct scatterlist *sg_list, int nbytes) +static inline int __sg_count(struct scatterlist *sg_list, int nbytes, + bool *chained) { struct scatterlist *sg = sg_list; int sg_nents = 0; @@ -65,7 +66,7 @@ static inline int __sg_count(struct scatterlist *sg_list, int nbytes) sg_nents++; nbytes -= sg->length; if (!sg_is_last(sg) && (sg + 1)->length == 0) - BUG(); /* Not support chaining */ + *chained = true; sg = scatterwalk_sg_next(sg); } @@ -73,9 +74,10 @@ static inline int __sg_count(struct scatterlist *sg_list, int nbytes) } /* derive number of elements in scatterlist, but return 0 for 1 */ -static inline int sg_count(struct scatterlist *sg_list, int nbytes) +static inline int sg_count(struct scatterlist *sg_list, int nbytes, + bool *chained) { - int sg_nents = __sg_count(sg_list, nbytes); + int sg_nents = __sg_count(sg_list, nbytes, chained); if (likely(sg_nents == 1)) return 0; @@ -83,6 +85,38 @@ static inline int sg_count(struct scatterlist *sg_list, int nbytes) return sg_nents; } +static int dma_map_sg_chained(struct device *dev, struct scatterlist *sg, + unsigned int nents, enum dma_data_direction dir, + bool chained) +{ + if (unlikely(chained)) { + int i; + for (i = 0; i < nents; i++) { + dma_map_sg(dev, sg, 1, dir); + sg = scatterwalk_sg_next(sg); + } + } else { + dma_map_sg(dev, sg, nents, dir); + } + return nents; +} + +static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg, + unsigned int nents, enum dma_data_direction dir, + bool chained) +{ + if (unlikely(chained)) { + int i; + for (i = 0; i < nents; i++) { + dma_unmap_sg(dev, sg, 1, dir); + sg = scatterwalk_sg_next(sg); + } + } else { + dma_unmap_sg(dev, sg, nents, dir); + } + return nents; +} + /* Copy from len bytes of sg to dest, starting from beginning */ static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) { -- GitLab From e24f7c9e87d46fad06bf1097d48f9923acd8e61c Mon Sep 17 00:00:00 2001 From: Yuan Kang Date: Fri, 22 Jun 2012 19:48:50 -0500 Subject: [PATCH 2999/6849] crypto: caam - hwrng support caam_read copies random bytes from two buffers into output. caam rng can fill empty buffer 0xffff bytes at a time, but the buffer sizes are rounded down to multiple of cacheline size. Signed-off-by: Yuan Kang Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/Kconfig | 13 ++ drivers/crypto/caam/Makefile | 1 + drivers/crypto/caam/caamrng.c | 309 ++++++++++++++++++++++++++++++++++ 3 files changed, 323 insertions(+) create mode 100644 drivers/crypto/caam/caamrng.c diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index e61b7f50785e..502a7f3cca5f 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -82,3 +82,16 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API To compile this as a module, choose M here: the module will be called caamhash. + +config CRYPTO_DEV_FSL_CAAM_RNG_API + tristate "Register caam device for hwrng API" + depends on CRYPTO_DEV_FSL_CAAM + default y + select CRYPTO_RNG + select HW_RANDOM + help + Selecting this will register the SEC4 hardware rng to + the hw_random API for suppying the kernel entropy pool. + + To compile this as a module, choose M here: the module + will be called caamrng. diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile index 9ef1cb00c342..b1eb44838db5 100644 --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o caam-objs := ctrl.o jr.o error.o key_gen.o diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c new file mode 100644 index 000000000000..e2bfe161dece --- /dev/null +++ b/drivers/crypto/caam/caamrng.c @@ -0,0 +1,309 @@ +/* + * caam - Freescale FSL CAAM support for hw_random + * + * Copyright 2011 Freescale Semiconductor, Inc. + * + * Based on caamalg.c crypto API driver. + * + * relationship between job descriptors to shared descriptors: + * + * --------------- -------------- + * | JobDesc #0 |-------------------->| ShareDesc | + * | *(buffer 0) | |------------->| (generate) | + * --------------- | | (move) | + * | | (store) | + * --------------- | -------------- + * | JobDesc #1 |------| + * | *(buffer 1) | + * --------------- + * + * A job desc looks like this: + * + * --------------------- + * | Header | + * | ShareDesc Pointer | + * | SEQ_OUT_PTR | + * | (output buffer) | + * --------------------- + * + * The SharedDesc never changes, and each job descriptor points to one of two + * buffers for each device, from which the data will be copied into the + * requested destination + */ + +#include +#include +#include + +#include "compat.h" + +#include "regs.h" +#include "intern.h" +#include "desc_constr.h" +#include "jr.h" +#include "error.h" + +/* + * Maximum buffer size: maximum number of random, cache-aligned bytes that + * will be generated and moved to seq out ptr (extlen not allowed) + */ +#define RN_BUF_SIZE (0xffff / L1_CACHE_BYTES * \ + L1_CACHE_BYTES) + +/* length of descriptors */ +#define DESC_JOB_O_LEN (CAAM_CMD_SZ * 2 + CAAM_PTR_SZ * 2) +#define DESC_RNG_LEN (10 * CAAM_CMD_SZ) + +/* Buffer, its dma address and lock */ +struct buf_data { + u8 buf[RN_BUF_SIZE]; + dma_addr_t addr; + struct completion filled; + u32 hw_desc[DESC_JOB_O_LEN]; +#define BUF_NOT_EMPTY 0 +#define BUF_EMPTY 1 +#define BUF_PENDING 2 /* Empty, but with job pending --don't submit another */ + atomic_t empty; +}; + +/* rng per-device context */ +struct caam_rng_ctx { + struct device *jrdev; + dma_addr_t sh_desc_dma; + u32 sh_desc[DESC_RNG_LEN]; + unsigned int cur_buf_idx; + int current_buf; + struct buf_data bufs[2]; +}; + +static struct caam_rng_ctx rng_ctx; + +static inline void rng_unmap_buf(struct device *jrdev, struct buf_data *bd) +{ + if (bd->addr) + dma_unmap_single(jrdev, bd->addr, RN_BUF_SIZE, + DMA_FROM_DEVICE); +} + +static inline void rng_unmap_ctx(struct caam_rng_ctx *ctx) +{ + struct device *jrdev = ctx->jrdev; + + if (ctx->sh_desc_dma) + dma_unmap_single(jrdev, ctx->sh_desc_dma, DESC_RNG_LEN, + DMA_TO_DEVICE); + rng_unmap_buf(jrdev, &ctx->bufs[0]); + rng_unmap_buf(jrdev, &ctx->bufs[1]); +} + +static void rng_done(struct device *jrdev, u32 *desc, u32 err, void *context) +{ + struct buf_data *bd; + + bd = (struct buf_data *)((char *)desc - + offsetof(struct buf_data, hw_desc)); + + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + atomic_set(&bd->empty, BUF_NOT_EMPTY); + complete(&bd->filled); +#ifdef DEBUG + print_hex_dump(KERN_ERR, "rng refreshed buf@: ", + DUMP_PREFIX_ADDRESS, 16, 4, bd->buf, RN_BUF_SIZE, 1); +#endif +} + +static inline int submit_job(struct caam_rng_ctx *ctx, int to_current) +{ + struct buf_data *bd = &ctx->bufs[!(to_current ^ ctx->current_buf)]; + struct device *jrdev = ctx->jrdev; + u32 *desc = bd->hw_desc; + int err; + + dev_dbg(jrdev, "submitting job %d\n", !(to_current ^ ctx->current_buf)); + init_completion(&bd->filled); + err = caam_jr_enqueue(jrdev, desc, rng_done, ctx); + if (err) + complete(&bd->filled); /* don't wait on failed job*/ + else + atomic_inc(&bd->empty); /* note if pending */ + + return err; +} + +static int caam_read(struct hwrng *rng, void *data, size_t max, bool wait) +{ + struct caam_rng_ctx *ctx = &rng_ctx; + struct buf_data *bd = &ctx->bufs[ctx->current_buf]; + int next_buf_idx, copied_idx; + int err; + + if (atomic_read(&bd->empty)) { + /* try to submit job if there wasn't one */ + if (atomic_read(&bd->empty) == BUF_EMPTY) { + err = submit_job(ctx, 1); + /* if can't submit job, can't even wait */ + if (err) + return 0; + } + /* no immediate data, so exit if not waiting */ + if (!wait) + return 0; + + /* waiting for pending job */ + if (atomic_read(&bd->empty)) + wait_for_completion(&bd->filled); + } + + next_buf_idx = ctx->cur_buf_idx + max; + dev_dbg(ctx->jrdev, "%s: start reading at buffer %d, idx %d\n", + __func__, ctx->current_buf, ctx->cur_buf_idx); + + /* if enough data in current buffer */ + if (next_buf_idx < RN_BUF_SIZE) { + memcpy(data, bd->buf + ctx->cur_buf_idx, max); + ctx->cur_buf_idx = next_buf_idx; + return max; + } + + /* else, copy what's left... */ + copied_idx = RN_BUF_SIZE - ctx->cur_buf_idx; + memcpy(data, bd->buf + ctx->cur_buf_idx, copied_idx); + ctx->cur_buf_idx = 0; + atomic_set(&bd->empty, BUF_EMPTY); + + /* ...refill... */ + submit_job(ctx, 1); + + /* and use next buffer */ + ctx->current_buf = !ctx->current_buf; + dev_dbg(ctx->jrdev, "switched to buffer %d\n", ctx->current_buf); + + /* since there already is some data read, don't wait */ + return copied_idx + caam_read(rng, data + copied_idx, + max - copied_idx, false); +} + +static inline void rng_create_sh_desc(struct caam_rng_ctx *ctx) +{ + struct device *jrdev = ctx->jrdev; + u32 *desc = ctx->sh_desc; + + init_sh_desc(desc, HDR_SHARE_WAIT); + + /* Propagate errors from shared to job descriptor */ + append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD); + + /* Generate random bytes */ + append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG); + + /* Store bytes */ + append_seq_fifo_store(desc, RN_BUF_SIZE, FIFOST_TYPE_RNGSTORE); + + ctx->sh_desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc), + DMA_TO_DEVICE); +#ifdef DEBUG + print_hex_dump(KERN_ERR, "rng shdesc@: ", DUMP_PREFIX_ADDRESS, 16, 4, + desc, desc_bytes(desc), 1); +#endif +} + +static inline void rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id) +{ + struct device *jrdev = ctx->jrdev; + struct buf_data *bd = &ctx->bufs[buf_id]; + u32 *desc = bd->hw_desc; + int sh_len = desc_len(ctx->sh_desc); + + init_job_desc_shared(desc, ctx->sh_desc_dma, sh_len, HDR_SHARE_DEFER | + HDR_REVERSE); + + bd->addr = dma_map_single(jrdev, bd->buf, RN_BUF_SIZE, DMA_FROM_DEVICE); + + append_seq_out_ptr_intlen(desc, bd->addr, RN_BUF_SIZE, 0); +#ifdef DEBUG + print_hex_dump(KERN_ERR, "rng job desc@: ", DUMP_PREFIX_ADDRESS, 16, 4, + desc, desc_bytes(desc), 1); +#endif +} + +static void caam_cleanup(struct hwrng *rng) +{ + int i; + struct buf_data *bd; + + for (i = 0; i < 2; i++) { + bd = &rng_ctx.bufs[i]; + if (atomic_read(&bd->empty) == BUF_PENDING) + wait_for_completion(&bd->filled); + } + + rng_unmap_ctx(&rng_ctx); +} + +static void caam_init_buf(struct caam_rng_ctx *ctx, int buf_id) +{ + struct buf_data *bd = &ctx->bufs[buf_id]; + + rng_create_job_desc(ctx, buf_id); + atomic_set(&bd->empty, BUF_EMPTY); + submit_job(ctx, buf_id == ctx->current_buf); + wait_for_completion(&bd->filled); +} + +static void caam_init_rng(struct caam_rng_ctx *ctx, struct device *jrdev) +{ + ctx->jrdev = jrdev; + rng_create_sh_desc(ctx); + ctx->current_buf = 0; + ctx->cur_buf_idx = 0; + caam_init_buf(ctx, 0); + caam_init_buf(ctx, 1); +} + +static struct hwrng caam_rng = { + .name = "rng-caam", + .cleanup = caam_cleanup, + .read = caam_read, +}; + +static void __exit caam_rng_exit(void) +{ + hwrng_unregister(&caam_rng); +} + +static int __init caam_rng_init(void) +{ + struct device_node *dev_node; + struct platform_device *pdev; + struct device *ctrldev; + struct caam_drv_private *priv; + + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); + if (!dev_node) + return -ENODEV; + + pdev = of_find_device_by_node(dev_node); + if (!pdev) + return -ENODEV; + + ctrldev = &pdev->dev; + priv = dev_get_drvdata(ctrldev); + of_node_put(dev_node); + + caam_init_rng(&rng_ctx, priv->jrdev[0]); + + dev_info(priv->jrdev[0], "registering rng-caam\n"); + return hwrng_register(&caam_rng); +} + +module_init(caam_rng_init); +module_exit(caam_rng_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("FSL CAAM support for hw_random API"); +MODULE_AUTHOR("Freescale Semiconductor - NMG"); -- GitLab From e13af18a3e33259e264c7fb47b54fbf608137976 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:51 -0500 Subject: [PATCH 3000/6849] crypto: caam - assign 40-bit masks on SEC v5.0 and above SEC v4.x were only 36-bit, SEC v5+ are 40-bit capable. Also set a DMA mask for any job ring devices created. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/ctrl.c | 9 +++++++-- drivers/crypto/caam/jr.c | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 77557ebcd337..9a2db9c30630 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -82,13 +82,18 @@ static int caam_probe(struct platform_device *pdev) /* * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, - * 36-bit pointers in master configuration register + * long pointers in master configuration register */ setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE | (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); if (sizeof(dma_addr_t) == sizeof(u64)) - dma_set_mask(dev, DMA_BIT_MASK(36)); + if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) + dma_set_mask(dev, DMA_BIT_MASK(40)); + else + dma_set_mask(dev, DMA_BIT_MASK(36)); + else + dma_set_mask(dev, DMA_BIT_MASK(32)); /* * Detect and enable JobRs diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 6ce4c41c8634..9f16b2c03613 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -503,6 +503,14 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np, dev_set_drvdata(jrdev, jrpriv); ctrlpriv->jrdev[ring] = jrdev; + if (sizeof(dma_addr_t) == sizeof(u64)) + if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring")) + dma_set_mask(jrdev, DMA_BIT_MASK(40)); + else + dma_set_mask(jrdev, DMA_BIT_MASK(36)); + else + dma_set_mask(jrdev, DMA_BIT_MASK(32)); + /* Identify the interrupt */ jrpriv->irq = of_irq_to_resource(np, 0, NULL); -- GitLab From 281922a1d4f59bdebbe78c1d9f4c50a967eb6cff Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:52 -0500 Subject: [PATCH 3001/6849] crypto: caam - add support for SEC v5.x RNG4 The SEC v4.x' RNGB h/w block self-initialized. RNG4, available on SEC versions 5 and beyond, is based on a different standard that requires manual initialization. Also update any new errors From the SEC v5.2 reference manual: The SEC v5.2's RNG4 unit reuses some error IDs, thus the addition of rng_err_id_list over the CHA-independent err_id_list. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/ctrl.c | 129 +++++++++++++++++++++++++++++++++++- drivers/crypto/caam/desc.h | 5 ++ drivers/crypto/caam/error.c | 44 +++++++++--- drivers/crypto/caam/regs.h | 32 ++++++++- 4 files changed, 196 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 9a2db9c30630..ac6abb375c8d 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -2,13 +2,15 @@ * CAAM control-plane driver backend * Controller-level driver, kernel property detection, initialization * - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. */ #include "compat.h" #include "regs.h" #include "intern.h" #include "jr.h" +#include "desc_constr.h" +#include "error.h" static int caam_remove(struct platform_device *pdev) { @@ -43,10 +45,120 @@ static int caam_remove(struct platform_device *pdev) return ret; } +/* + * Descriptor to instantiate RNG State Handle 0 in normal mode and + * load the JDKEK, TDKEK and TDSK registers + */ +static void build_instantiation_desc(u32 *desc) +{ + u32 *jump_cmd; + + init_job_desc(desc, 0); + + /* INIT RNG in non-test mode */ + append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | + OP_ALG_AS_INIT); + + /* wait for done */ + jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1); + set_jump_tgt_here(desc, jump_cmd); + + /* + * load 1 to clear written reg: + * resets the done interrrupt and returns the RNG to idle. + */ + append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW); + + /* generate secure keys (non-test) */ + append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | + OP_ALG_RNG4_SK); +} + +struct instantiate_result { + struct completion completion; + int err; +}; + +static void rng4_init_done(struct device *dev, u32 *desc, u32 err, + void *context) +{ + struct instantiate_result *instantiation = context; + + if (err) { + char tmp[CAAM_ERROR_STR_MAX]; + + dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + instantiation->err = err; + complete(&instantiation->completion); +} + +static int instantiate_rng(struct device *jrdev) +{ + struct instantiate_result instantiation; + + dma_addr_t desc_dma; + u32 *desc; + int ret; + + desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA); + if (!desc) { + dev_err(jrdev, "cannot allocate RNG init descriptor memory\n"); + return -ENOMEM; + } + + build_instantiation_desc(desc); + desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc), DMA_TO_DEVICE); + init_completion(&instantiation.completion); + ret = caam_jr_enqueue(jrdev, desc, rng4_init_done, &instantiation); + if (!ret) { + wait_for_completion_interruptible(&instantiation.completion); + ret = instantiation.err; + if (ret) + dev_err(jrdev, "unable to instantiate RNG\n"); + } + + dma_unmap_single(jrdev, desc_dma, desc_bytes(desc), DMA_TO_DEVICE); + + kfree(desc); + + return ret; +} + +/* + * By default, the TRNG runs for 200 clocks per sample; + * 800 clocks per sample generates better entropy. + */ +static void kick_trng(struct platform_device *pdev) +{ + struct device *ctrldev = &pdev->dev; + struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); + struct caam_full __iomem *topregs; + struct rng4tst __iomem *r4tst; + u32 val; + + topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; + r4tst = &topregs->ctrl.r4tst[0]; + + /* put RNG4 into program mode */ + setbits32(&r4tst->rtmctl, RTMCTL_PRGM); + /* 800 clocks per sample */ + val = rd_reg32(&r4tst->rtsdctl); + val = (val & ~RTSDCTL_ENT_DLY_MASK) | (800 << RTSDCTL_ENT_DLY_SHIFT); + wr_reg32(&r4tst->rtsdctl, val); + /* min. freq. count */ + wr_reg32(&r4tst->rtfrqmin, 400); + /* max. freq. count */ + wr_reg32(&r4tst->rtfrqmax, 6400); + /* put RNG4 into run mode */ + clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); +} + /* Probe routine for CAAM top (controller) level */ static int caam_probe(struct platform_device *pdev) { - int ring, rspec; + int ret, ring, rspec; struct device *dev; struct device_node *nprop, *np; struct caam_ctrl __iomem *ctrl; @@ -146,6 +258,19 @@ static int caam_probe(struct platform_device *pdev) return -ENOMEM; } + /* + * RNG4 based SECs (v5+) need special initialization prior + * to executing any descriptors + */ + if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) { + kick_trng(pdev); + ret = instantiate_rng(ctrlpriv->jrdev[0]); + if (ret) { + caam_remove(pdev); + return ret; + } + } + /* NOTE: RTIC detection ought to go here, around Si time */ /* Initialize queue allocator lock */ diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h index 3e685062d44b..f7f833be8c67 100644 --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -1172,6 +1172,11 @@ struct sec4_sg_entry { #define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT) #define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT) +/* RNG4 set */ +#define OP_ALG_RNG4_SHIFT 4 +#define OP_ALG_RNG4_MASK (0x1f3 << OP_ALG_RNG4_SHIFT) + +#define OP_ALG_RNG4_SK (0x100 << OP_ALG_RNG4_SHIFT) #define OP_ALG_AS_SHIFT 2 #define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT) diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c index 7e2d54bffad6..9955ed9643e6 100644 --- a/drivers/crypto/caam/error.c +++ b/drivers/crypto/caam/error.c @@ -39,18 +39,20 @@ static void report_ccb_status(u32 status, char *outstr) char *cha_id_list[] = { "", "AES", - "DES, 3DES", + "DES", "ARC4", - "MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512", + "MDHA", "RNG", "SNOW f8", - "Kasumi f8, f9", - "All Public Key Algorithms", - "CRC", + "Kasumi f8/9", + "PKHA", + "CRCA", "SNOW f9", + "ZUCE", + "ZUCA", }; char *err_id_list[] = { - "None. No error.", + "No error.", "Mode error.", "Data size error.", "Key size error.", @@ -67,6 +69,20 @@ static void report_ccb_status(u32 status, char *outstr) "Invalid CHA combination was selected", "Invalid CHA selected.", }; + char *rng_err_id_list[] = { + "", + "", + "", + "Instantiate", + "Not instantiated", + "Test instantiate", + "Prediction resistance", + "", + "Prediction resistance and test request", + "Uninstantiate", + "", + "Secure key generation", + }; u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> JRSTA_CCBERR_CHAID_SHIFT; u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; @@ -81,7 +97,13 @@ static void report_ccb_status(u32 status, char *outstr) cha_id, sizeof("ff")); } - if (err_id < ARRAY_SIZE(err_id_list)) { + if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG && + err_id < ARRAY_SIZE(rng_err_id_list) && + strlen(rng_err_id_list[err_id])) { + /* RNG-only error */ + SPRINTFCAT(outstr, "%s", rng_err_id_list[err_id], + strlen(rng_err_id_list[err_id])); + } else if (err_id < ARRAY_SIZE(err_id_list)) { SPRINTFCAT(outstr, "%s", err_id_list[err_id], strlen(err_id_list[err_id])); } else { @@ -101,10 +123,10 @@ static void report_deco_status(u32 status, char *outstr) u8 value; char *error_text; } desc_error_list[] = { - { 0x00, "None. No error." }, + { 0x00, "No error." }, { 0x01, "SGT Length Error. The descriptor is trying to read " "more data than is contained in the SGT table." }, - { 0x02, "Reserved." }, + { 0x02, "SGT Null Entry Error." }, { 0x03, "Job Ring Control Error. There is a bad value in the " "Job Ring Control register." }, { 0x04, "Invalid Descriptor Command. The Descriptor Command " @@ -116,7 +138,7 @@ static void report_deco_status(u32 status, char *outstr) { 0x09, "Invalid OPERATION Command" }, { 0x0A, "Invalid FIFO LOAD Command" }, { 0x0B, "Invalid FIFO STORE Command" }, - { 0x0C, "Invalid MOVE Command" }, + { 0x0C, "Invalid MOVE/MOVE_LEN Command" }, { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " "invalid because the target is not a Job Header " "Command, or the jump is from a Trusted Descriptor to " @@ -166,6 +188,8 @@ static void report_deco_status(u32 status, char *outstr) "(input frame; block ciphers) and IPsec decap (output " "frame, when doing the next header byte update) and " "DCRC (output frame)." }, + { 0x23, "Read Input Frame error" }, + { 0x24, "JDKEK, TDKEK or TDSK not loaded error" }, { 0x80, "DNR (do not run) error" }, { 0x81, "undefined protocol command" }, { 0x82, "invalid setting in PDB" }, diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index e9f7a70cdd5e..6d9f1d982970 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -167,7 +167,7 @@ struct partid { u32 pidr; /* partition ID, DECO */ }; -/* RNG test mode (replicated twice in some configurations) */ +/* RNGB test mode (replicated twice in some configurations) */ /* Padded out to 0x100 */ struct rngtst { u32 mode; /* RTSTMODEx - Test mode */ @@ -200,6 +200,31 @@ struct rngtst { u32 rsvd14[15]; }; +/* RNG4 TRNG test registers */ +struct rng4tst { +#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */ + u32 rtmctl; /* misc. control register */ + u32 rtscmisc; /* statistical check misc. register */ + u32 rtpkrrng; /* poker range register */ + union { + u32 rtpkrmax; /* PRGM=1: poker max. limit register */ + u32 rtpkrsq; /* PRGM=0: poker square calc. result register */ + }; +#define RTSDCTL_ENT_DLY_SHIFT 16 +#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT) + u32 rtsdctl; /* seed control register */ + union { + u32 rtsblim; /* PRGM=1: sparse bit limit register */ + u32 rttotsam; /* PRGM=0: total samples register */ + }; + u32 rtfrqmin; /* frequency count min. limit register */ + union { + u32 rtfrqmax; /* PRGM=1: freq. count max. limit register */ + u32 rtfrqcnt; /* PRGM=0: freq. count register */ + }; + u32 rsvd1[56]; +}; + /* * caam_ctrl - basic core configuration * starts base + 0x0000 padded out to 0x1000 @@ -249,7 +274,10 @@ struct caam_ctrl { /* RNG Test/Verification/Debug Access 600-7ff */ /* (Useful in Test/Debug modes only...) */ - struct rngtst rtst[2]; + union { + struct rngtst rtst[2]; + struct rng4tst r4tst[2]; + }; u32 rsvd9[448]; -- GitLab From 1a076689cda8a1d623dcda170b2dc2b476cc6f1a Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:53 -0500 Subject: [PATCH 3002/6849] crypto: caam - disable IRQ coalescing by default It has been observed that in zero-loss benchmarks, when a slow traffic rate is being tested, the IRQ timer coalescing parameter was set too high, and the ethernet controller would start dropping packets because the job ring back half wouldn't be executed in time before the ethernet controller would fill its buffers, thereby significantly reducing the zero-loss performance figures. Empirical testing has shown that the best zero-loss performance is achieved when IRQ coalescing is set to minimum values and/or turned off, since apparently the job ring driver already implements an adequately-performing general-purpose IRQ mitigation strategy in software. Whilst we could go with minimal count (2-8) and timing settings (192-256), we prefer just turning h/w coalescing altogether off to minimize setkey latency (due to split key generation), and for consistent cross-SoC performance (the SEC vs. core clock ratio changes). Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index 502a7f3cca5f..65c7668614ab 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -32,10 +32,13 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE config CRYPTO_DEV_FSL_CAAM_INTC bool "Job Ring interrupt coalescing" depends on CRYPTO_DEV_FSL_CAAM - default y + default n help Enable the Job Ring's interrupt coalescing feature. + Note: the driver already provides adequate + interrupt coalescing in software. + config CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD int "Job Ring interrupt coalescing count threshold" depends on CRYPTO_DEV_FSL_CAAM_INTC -- GitLab From 4bba1e9f41d68279ff2c17db53fbd379692b10bc Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:54 -0500 Subject: [PATCH 3003/6849] crypto: caam - use non-irq versions of spinlocks for job rings The enqueue lock isn't used in any interrupt context, and the dequeue lock isn't used in the h/w interrupt context, only in bh context. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 9f16b2c03613..11d93f243705 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -2,7 +2,7 @@ * CAAM/SEC 4.x transport/backend driver * JobR backend functionality * - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. */ #include "compat.h" @@ -58,9 +58,8 @@ static void caam_jr_dequeue(unsigned long devarg) void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); u32 *userdesc, userstatus; void *userarg; - unsigned long flags; - spin_lock_irqsave(&jrp->outlock, flags); + spin_lock_bh(&jrp->outlock); head = ACCESS_ONCE(jrp->head); sw_idx = tail = jrp->tail; @@ -118,18 +117,18 @@ static void caam_jr_dequeue(unsigned long devarg) /* set done */ wr_reg32(&jrp->rregs->outring_rmvd, 1); - spin_unlock_irqrestore(&jrp->outlock, flags); + spin_unlock_bh(&jrp->outlock); /* Finally, execute user's callback */ usercall(dev, userdesc, userstatus, userarg); - spin_lock_irqsave(&jrp->outlock, flags); + spin_lock_bh(&jrp->outlock); head = ACCESS_ONCE(jrp->head); sw_idx = tail = jrp->tail; } - spin_unlock_irqrestore(&jrp->outlock, flags); + spin_unlock_bh(&jrp->outlock); /* reenable / unmask IRQs */ clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); @@ -148,23 +147,22 @@ int caam_jr_register(struct device *ctrldev, struct device **rdev) { struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); struct caam_drv_private_jr *jrpriv = NULL; - unsigned long flags; int ring; /* Lock, if free ring - assign, unlock */ - spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags); + spin_lock(&ctrlpriv->jr_alloc_lock); for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); if (jrpriv->assign == JOBR_UNASSIGNED) { jrpriv->assign = JOBR_ASSIGNED; *rdev = ctrlpriv->jrdev[ring]; - spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); + spin_unlock(&ctrlpriv->jr_alloc_lock); return ring; } } /* If assigned, write dev where caller needs it */ - spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); + spin_unlock(&ctrlpriv->jr_alloc_lock); *rdev = NULL; return -ENODEV; @@ -182,7 +180,6 @@ int caam_jr_deregister(struct device *rdev) { struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev); struct caam_drv_private *ctrlpriv; - unsigned long flags; /* Get the owning controller's private space */ ctrlpriv = dev_get_drvdata(jrpriv->parentdev); @@ -195,9 +192,9 @@ int caam_jr_deregister(struct device *rdev) return -EBUSY; /* Release ring */ - spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags); + spin_lock(&ctrlpriv->jr_alloc_lock); jrpriv->assign = JOBR_UNASSIGNED; - spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); + spin_unlock(&ctrlpriv->jr_alloc_lock); return 0; } @@ -238,7 +235,6 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, { struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); struct caam_jrentry_info *head_entry; - unsigned long flags; int head, tail, desc_size; dma_addr_t desc_dma; @@ -249,14 +245,14 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, return -EIO; } - spin_lock_irqsave(&jrp->inplock, flags); + spin_lock(&jrp->inplock); head = jrp->head; tail = ACCESS_ONCE(jrp->tail); if (!rd_reg32(&jrp->rregs->inpring_avail) || CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { - spin_unlock_irqrestore(&jrp->inplock, flags); + spin_unlock(&jrp->inplock); dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); return -EBUSY; } @@ -280,7 +276,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, wr_reg32(&jrp->rregs->inpring_jobadd, 1); - spin_unlock_irqrestore(&jrp->inplock, flags); + spin_unlock(&jrp->inplock); return 0; } -- GitLab From a8ea07c21d40cf17dd9cbe3cbf87d477b26c354f Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:55 -0500 Subject: [PATCH 3004/6849] crypto: caam - only query h/w in job ring dequeue path Code was needlessly checking the s/w job ring when there would be nothing to process if the h/w's output completion ring were empty anyway. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 11d93f243705..7ae5e51a0597 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -59,15 +59,15 @@ static void caam_jr_dequeue(unsigned long devarg) u32 *userdesc, userstatus; void *userarg; - spin_lock_bh(&jrp->outlock); + while (rd_reg32(&jrp->rregs->outring_used)) { - head = ACCESS_ONCE(jrp->head); - sw_idx = tail = jrp->tail; + head = ACCESS_ONCE(jrp->head); - while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 && - rd_reg32(&jrp->rregs->outring_used)) { + spin_lock_bh(&jrp->outlock); + sw_idx = tail = jrp->tail; hw_idx = jrp->out_ring_read_index; + for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { sw_idx = (tail + i) & (JOBR_DEPTH - 1); @@ -121,15 +121,8 @@ static void caam_jr_dequeue(unsigned long devarg) /* Finally, execute user's callback */ usercall(dev, userdesc, userstatus, userarg); - - spin_lock_bh(&jrp->outlock); - - head = ACCESS_ONCE(jrp->head); - sw_idx = tail = jrp->tail; } - spin_unlock_bh(&jrp->outlock); - /* reenable / unmask IRQs */ clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); } -- GitLab From 14a8e29cc2012394d3e886b11402eabd49a4d609 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:56 -0500 Subject: [PATCH 3005/6849] crypto: caam - consolidate memory barriers from job ring en/dequeue Memory barriers are implied by the i/o register write implementation (at least on Power). So we can remove the redundant wmb() in caam_jr_enqueue, and, in dequeue(), hoist the h/w done notification write up to before we need to increment the head of the ring, and save an smp_mb. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 7ae5e51a0597..0adaad1b8cf7 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -94,7 +94,8 @@ static void caam_jr_dequeue(unsigned long devarg) userdesc = jrp->entinfo[sw_idx].desc_addr_virt; userstatus = jrp->outring[hw_idx].jrstatus; - smp_mb(); + /* set done */ + wr_reg32(&jrp->rregs->outring_rmvd, 1); jrp->out_ring_read_index = (jrp->out_ring_read_index + 1) & (JOBR_DEPTH - 1); @@ -114,9 +115,6 @@ static void caam_jr_dequeue(unsigned long devarg) jrp->tail = tail; } - /* set done */ - wr_reg32(&jrp->rregs->outring_rmvd, 1); - spin_unlock_bh(&jrp->outlock); /* Finally, execute user's callback */ @@ -265,8 +263,6 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, (JOBR_DEPTH - 1); jrp->head = (head + 1) & (JOBR_DEPTH - 1); - wmb(); - wr_reg32(&jrp->rregs->inpring_jobadd, 1); spin_unlock(&jrp->inplock); -- GitLab From a0ca6ca022ac197e159bb5d22a08e3c3aebb242c Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 22 Jun 2012 19:48:57 -0500 Subject: [PATCH 3006/6849] crypto: caam - one tasklet per job ring there is no noticeable benefit for multiple cores to process one job ring's output ring: in fact, we can benefit from cache effects of having the back-half stay on the core that receives a particular ring's interrupts, and further relax general contention and the locking involved with reading outring_used, since tasklets run atomically. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/intern.h | 2 +- drivers/crypto/caam/jr.c | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index ed2b739f934b..5cd4c1b268a1 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -43,7 +43,7 @@ struct caam_drv_private_jr { struct device *parentdev; /* points back to controller dev */ int ridx; struct caam_job_ring __iomem *rregs; /* JobR's register space */ - struct tasklet_struct irqtask[NR_CPUS]; + struct tasklet_struct irqtask; int irq; /* One per queue */ int assign; /* busy/free */ diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 0adaad1b8cf7..7074a1a29e8b 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -43,7 +43,7 @@ static irqreturn_t caam_jr_interrupt(int irq, void *st_dev) wr_reg32(&jrp->rregs->jrintstatus, irqstate); preempt_disable(); - tasklet_schedule(&jrp->irqtask[smp_processor_id()]); + tasklet_schedule(&jrp->irqtask); preempt_enable(); return IRQ_HANDLED; @@ -322,11 +322,9 @@ static int caam_jr_init(struct device *dev) jrp = dev_get_drvdata(dev); - /* Connect job ring interrupt handler. */ - for_each_possible_cpu(i) - tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, - (unsigned long)dev); + tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev); + /* Connect job ring interrupt handler. */ error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED, "caam-jobr", dev); if (error) { @@ -416,12 +414,11 @@ int caam_jr_shutdown(struct device *dev) { struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); dma_addr_t inpbusaddr, outbusaddr; - int ret, i; + int ret; ret = caam_reset_hw_jr(dev); - for_each_possible_cpu(i) - tasklet_kill(&jrp->irqtask[i]); + tasklet_kill(&jrp->irqtask); /* Release interrupt */ free_irq(jrp->irq, dev); -- GitLab From b9b0f080fac541d88eee4d5175c3f6470a9e9189 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 26 Jun 2012 18:13:46 +0200 Subject: [PATCH 3007/6849] crypto: arc4 - now arc needs blockcipher support Since commit ce6dd368 ("crypto: arc4 - improve performance by adding ecb(arc4)) we need to pull in a blkcipher. |ERROR: "crypto_blkcipher_type" [crypto/arc4.ko] undefined! |ERROR: "blkcipher_walk_done" [crypto/arc4.ko] undefined! |ERROR: "blkcipher_walk_virt" [crypto/arc4.ko] undefined! Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Herbert Xu --- crypto/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index 02e303774691..a3238051b03e 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -604,7 +604,7 @@ config CRYPTO_ANUBIS config CRYPTO_ARC4 tristate "ARC4 cipher algorithm" - select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER help ARC4 cipher algorithm. -- GitLab From 747cf6ed3dbf6200af761f5384893c3b621a484c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 26 Jun 2012 20:53:09 +0000 Subject: [PATCH 3008/6849] 6lowpan: double unlock on an error path We already unlocked a few lines earlier here, so we can go directly to drop without passing through unlock. This was introduced recently in c5d3687f6c ('6lowpan: read data from skb safely'). Signed-off-by: Dan Carpenter Acked-by: Alexander Smirnov Signed-off-by: David S. Miller --- net/ieee802154/6lowpan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index ad0c2264e537..cd5007f3a569 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -771,7 +771,7 @@ lowpan_process_data(struct sk_buff *skb) kfree(frame); if (lowpan_fetch_skb_u8(skb, &iphc0)) - goto unlock_and_drop; + goto drop; break; } -- GitLab From 2e499d3cc13365a87815266dda59904dcb8c8d6c Mon Sep 17 00:00:00 2001 From: Barak Witkowski Date: Tue, 26 Jun 2012 01:31:19 +0000 Subject: [PATCH 3009/6849] bnx2x, bnx2fc, bnx2i, cnic: Add statistics support and FCoE capabilities advertisement 1. When FCoE offload driver is registered, copy its capabilities to the chip scratchpad. 2. Copy FCoE/iSCSI MAC addresses in aligned manner to chip scratchpad. 3. Add FCoE/iSCSI statistics collection support Signed-off-by: Barak Witkowski Signed-off-by: Eilon Greenstein Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: Bhanu Prakash Gollapudi Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 + .../net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 120 +------------ .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 41 ++++- .../ethernet/broadcom/bnx2x/bnx2x_mfw_req.h | 168 ++++++++++++++++++ drivers/net/ethernet/broadcom/cnic.c | 11 +- drivers/net/ethernet/broadcom/cnic_if.h | 9 + drivers/scsi/bnx2fc/bnx2fc.h | 4 + drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 44 +++++ drivers/scsi/bnx2i/57xx_iscsi_hsi.h | 16 +- drivers/scsi/bnx2i/bnx2i.h | 58 ++++++ drivers/scsi/bnx2i/bnx2i_hwi.c | 35 +++- drivers/scsi/bnx2i/bnx2i_init.c | 40 +++++ drivers/scsi/bnx2i/bnx2i_iscsi.c | 11 ++ 13 files changed, 420 insertions(+), 139 deletions(-) create mode 100644 drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 7211cb07426e..362d16f1d256 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -51,6 +51,7 @@ #include "bnx2x_reg.h" #include "bnx2x_fw_defs.h" +#include "bnx2x_mfw_req.h" #include "bnx2x_hsi.h" #include "bnx2x_link.h" #include "bnx2x_sp.h" @@ -1317,6 +1318,7 @@ struct bnx2x { #define NO_ISCSI_FLAG (1 << 14) #define NO_FCOE_FLAG (1 << 15) #define BC_SUPPORTS_PFC_STATS (1 << 17) +#define BC_SUPPORTS_FCOE_FEATURES (1 << 19) #define USING_SINGLE_MSIX_FLAG (1 << 20) #define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index e7c390c66b2a..76b6e65790f8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -10,6 +10,7 @@ #define BNX2X_HSI_H #include "bnx2x_fw_defs.h" +#include "bnx2x_mfw_req.h" #define FW_ENCODE_32BIT_PATTERN 0x1e1e1e1e @@ -33,12 +34,6 @@ struct license_key { u32 reserved_b[4]; }; - -#define PORT_0 0 -#define PORT_1 1 -#define PORT_MAX 2 -#define NVM_PATH_MAX 2 - /**************************************************************************** * Shared HW configuration * ****************************************************************************/ @@ -1252,6 +1247,7 @@ struct drv_func_mb { #define REQ_BC_VER_4_VRFY_AFEX_SUPPORTED 0x00070002 #define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED 0x00070014 #define REQ_BC_VER_4_PFC_STATS_SUPPORTED 0x00070201 + #define REQ_BC_VER_4_FCOE_FEATURES 0x00070209 #define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 #define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 @@ -2700,118 +2696,6 @@ struct host_func_stats { /* VIC definitions */ #define VICSTATST_UIF_INDEX 2 -/* current drv_info version */ -#define DRV_INFO_CUR_VER 1 - -/* drv_info op codes supported */ -enum drv_info_opcode { - ETH_STATS_OPCODE, - FCOE_STATS_OPCODE, - ISCSI_STATS_OPCODE -}; - -#define ETH_STAT_INFO_VERSION_LEN 12 -/* Per PCI Function Ethernet Statistics required from the driver */ -struct eth_stats_info { - /* Function's Driver Version. padded to 12 */ - u8 version[ETH_STAT_INFO_VERSION_LEN]; - /* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */ - u8 mac_local[8]; - u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */ - u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */ - u32 mtu_size; /* MTU Size. Note : Negotiated MTU */ - u32 feature_flags; /* Feature_Flags. */ -#define FEATURE_ETH_CHKSUM_OFFLOAD_MASK 0x01 -#define FEATURE_ETH_LSO_MASK 0x02 -#define FEATURE_ETH_BOOTMODE_MASK 0x1C -#define FEATURE_ETH_BOOTMODE_SHIFT 2 -#define FEATURE_ETH_BOOTMODE_NONE (0x0 << 2) -#define FEATURE_ETH_BOOTMODE_PXE (0x1 << 2) -#define FEATURE_ETH_BOOTMODE_ISCSI (0x2 << 2) -#define FEATURE_ETH_BOOTMODE_FCOE (0x3 << 2) -#define FEATURE_ETH_TOE_MASK 0x20 - u32 lso_max_size; /* LSO MaxOffloadSize. */ - u32 lso_min_seg_cnt; /* LSO MinSegmentCount. */ - /* Num Offloaded Connections TCP_IPv4. */ - u32 ipv4_ofld_cnt; - /* Num Offloaded Connections TCP_IPv6. */ - u32 ipv6_ofld_cnt; - u32 promiscuous_mode; /* Promiscuous Mode. non-zero true */ - u32 txq_size; /* TX Descriptors Queue Size */ - u32 rxq_size; /* RX Descriptors Queue Size */ - /* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */ - u32 txq_avg_depth; - /* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */ - u32 rxq_avg_depth; - /* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/ - u32 iov_offload; - /* Number of NetQueue/VMQ Config'd. */ - u32 netq_cnt; - u32 vf_cnt; /* Num VF assigned to this PF. */ -}; - -/* Per PCI Function FCOE Statistics required from the driver */ -struct fcoe_stats_info { - u8 version[12]; /* Function's Driver Version. */ - u8 mac_local[8]; /* Locally Admin Addr. */ - u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */ - u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */ - /* QoS Priority (per 802.1p). 0-7255 */ - u32 qos_priority; - u32 txq_size; /* FCoE TX Descriptors Queue Size. */ - u32 rxq_size; /* FCoE RX Descriptors Queue Size. */ - /* FCoE TX Descriptor Queue Avg Depth. */ - u32 txq_avg_depth; - /* FCoE RX Descriptors Queue Avg Depth. */ - u32 rxq_avg_depth; - u32 rx_frames_lo; /* FCoE RX Frames received. */ - u32 rx_frames_hi; /* FCoE RX Frames received. */ - u32 rx_bytes_lo; /* FCoE RX Bytes received. */ - u32 rx_bytes_hi; /* FCoE RX Bytes received. */ - u32 tx_frames_lo; /* FCoE TX Frames sent. */ - u32 tx_frames_hi; /* FCoE TX Frames sent. */ - u32 tx_bytes_lo; /* FCoE TX Bytes sent. */ - u32 tx_bytes_hi; /* FCoE TX Bytes sent. */ -}; - -/* Per PCI Function iSCSI Statistics required from the driver*/ -struct iscsi_stats_info { - u8 version[12]; /* Function's Driver Version. */ - u8 mac_local[8]; /* Locally Admin iSCSI MAC Addr. */ - u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */ - /* QoS Priority (per 802.1p). 0-7255 */ - u32 qos_priority; - u8 initiator_name[64]; /* iSCSI Boot Initiator Node name. */ - u8 ww_port_name[64]; /* iSCSI World wide port name */ - u8 boot_target_name[64];/* iSCSI Boot Target Name. */ - u8 boot_target_ip[16]; /* iSCSI Boot Target IP. */ - u32 boot_target_portal; /* iSCSI Boot Target Portal. */ - u8 boot_init_ip[16]; /* iSCSI Boot Initiator IP Address. */ - u32 max_frame_size; /* Max Frame Size. bytes */ - u32 txq_size; /* PDU TX Descriptors Queue Size. */ - u32 rxq_size; /* PDU RX Descriptors Queue Size. */ - u32 txq_avg_depth; /* PDU TX Descriptor Queue Avg Depth. */ - u32 rxq_avg_depth; /* PDU RX Descriptors Queue Avg Depth. */ - u32 rx_pdus_lo; /* iSCSI PDUs received. */ - u32 rx_pdus_hi; /* iSCSI PDUs received. */ - u32 rx_bytes_lo; /* iSCSI RX Bytes received. */ - u32 rx_bytes_hi; /* iSCSI RX Bytes received. */ - u32 tx_pdus_lo; /* iSCSI PDUs sent. */ - u32 tx_pdus_hi; /* iSCSI PDUs sent. */ - u32 tx_bytes_lo; /* iSCSI PDU TX Bytes sent. */ - u32 tx_bytes_hi; /* iSCSI PDU TX Bytes sent. */ - u32 pcp_prior_map_tbl; /* C-PCP to S-PCP Priority MapTable. - * 9 nibbles, the position of each nibble - * represents the C-PCP value, the value - * of the nibble = S-PCP value. - */ -}; - -union drv_info_to_mcp { - struct eth_stats_info ether_stat; - struct fcoe_stats_info fcoe_stat; - struct iscsi_stats_info iscsi_stat; -}; /* stats collected for afex. * NOTE: structure is exactly as expected to be received by the switch. diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 8ddc78e0d945..5b8b521bdbc3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -74,6 +74,8 @@ #define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" #define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" +#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN) + /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -3060,7 +3062,8 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp) struct fcoe_stats_info *fcoe_stat = &bp->slowpath->drv_info_to_mcp.fcoe_stat; - memcpy(fcoe_stat->mac_local, bp->fip_mac, ETH_ALEN); + memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT, + bp->fip_mac, ETH_ALEN); fcoe_stat->qos_priority = app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]; @@ -3151,7 +3154,8 @@ static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp) struct iscsi_stats_info *iscsi_stat = &bp->slowpath->drv_info_to_mcp.iscsi_stat; - memcpy(iscsi_stat->mac_local, bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); + memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT, + bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); iscsi_stat->qos_priority = app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI]; @@ -9732,6 +9736,9 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ? BC_SUPPORTS_PFC_STATS : 0; + bp->flags |= (val >= REQ_BC_VER_4_FCOE_FEATURES) ? + BC_SUPPORTS_FCOE_FEATURES : 0; + bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ? BC_SUPPORTS_DCBX_MSG_NON_PMF : 0; boot_mode = SHMEM_RD(bp, @@ -12548,21 +12555,45 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) break; } case DRV_CTL_ULP_REGISTER_CMD: { - int ulp_type = ctl->data.ulp_type; + int ulp_type = ctl->data.register_data.ulp_type; if (CHIP_IS_E3(bp)) { int idx = BP_FW_MB_IDX(bp); - u32 cap; + u32 cap = SHMEM2_RD(bp, drv_capabilities_flag[idx]); + int path = BP_PATH(bp); + int port = BP_PORT(bp); + int i; + u32 scratch_offset; + u32 *host_addr; - cap = SHMEM2_RD(bp, drv_capabilities_flag[idx]); + /* first write capability to shmem2 */ if (ulp_type == CNIC_ULP_ISCSI) cap |= DRV_FLAGS_CAPABILITIES_LOADED_ISCSI; else if (ulp_type == CNIC_ULP_FCOE) cap |= DRV_FLAGS_CAPABILITIES_LOADED_FCOE; SHMEM2_WR(bp, drv_capabilities_flag[idx], cap); + + if ((ulp_type != CNIC_ULP_FCOE) || + (!SHMEM2_HAS(bp, ncsi_oem_data_addr)) || + (!(bp->flags & BC_SUPPORTS_FCOE_FEATURES))) + break; + + /* if reached here - should write fcoe capabilities */ + scratch_offset = SHMEM2_RD(bp, ncsi_oem_data_addr); + if (!scratch_offset) + break; + scratch_offset += offsetof(struct glob_ncsi_oem_data, + fcoe_features[path][port]); + host_addr = (u32 *) &(ctl->data.register_data. + fcoe_features); + for (i = 0; i < sizeof(struct fcoe_capabilities); + i += 4) + REG_WR(bp, scratch_offset + i, + *(host_addr + i/4)); } break; } + case DRV_CTL_ULP_UNREGISTER_CMD: { int ulp_type = ctl->data.ulp_type; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h new file mode 100644 index 000000000000..ddd5106ad2f9 --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h @@ -0,0 +1,168 @@ +/* bnx2x_mfw_req.h: Broadcom Everest network driver. + * + * Copyright (c) 2012 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#ifndef BNX2X_MFW_REQ_H +#define BNX2X_MFW_REQ_H + +#define PORT_0 0 +#define PORT_1 1 +#define PORT_MAX 2 +#define NVM_PATH_MAX 2 + +/* FCoE capabilities required from the driver */ +struct fcoe_capabilities { + u32 capability1; + /* Maximum number of I/Os per connection */ + #define FCOE_IOS_PER_CONNECTION_MASK 0x0000ffff + #define FCOE_IOS_PER_CONNECTION_SHIFT 0 + /* Maximum number of Logins per port */ + #define FCOE_LOGINS_PER_PORT_MASK 0xffff0000 + #define FCOE_LOGINS_PER_PORT_SHIFT 16 + + u32 capability2; + /* Maximum number of exchanges */ + #define FCOE_NUMBER_OF_EXCHANGES_MASK 0x0000ffff + #define FCOE_NUMBER_OF_EXCHANGES_SHIFT 0 + /* Maximum NPIV WWN per port */ + #define FCOE_NPIV_WWN_PER_PORT_MASK 0xffff0000 + #define FCOE_NPIV_WWN_PER_PORT_SHIFT 16 + + u32 capability3; + /* Maximum number of targets supported */ + #define FCOE_TARGETS_SUPPORTED_MASK 0x0000ffff + #define FCOE_TARGETS_SUPPORTED_SHIFT 0 + /* Maximum number of outstanding commands across all connections */ + #define FCOE_OUTSTANDING_COMMANDS_MASK 0xffff0000 + #define FCOE_OUTSTANDING_COMMANDS_SHIFT 16 + + u32 capability4; + #define FCOE_CAPABILITY4_STATEFUL 0x00000001 + #define FCOE_CAPABILITY4_STATELESS 0x00000002 + #define FCOE_CAPABILITY4_CAPABILITIES_REPORTED_VALID 0x00000004 +}; + +struct glob_ncsi_oem_data { + u32 driver_version; + u32 unused[3]; + struct fcoe_capabilities fcoe_features[NVM_PATH_MAX][PORT_MAX]; +}; + +/* current drv_info version */ +#define DRV_INFO_CUR_VER 2 + +/* drv_info op codes supported */ +enum drv_info_opcode { + ETH_STATS_OPCODE, + FCOE_STATS_OPCODE, + ISCSI_STATS_OPCODE +}; + +#define ETH_STAT_INFO_VERSION_LEN 12 +/* Per PCI Function Ethernet Statistics required from the driver */ +struct eth_stats_info { + /* Function's Driver Version. padded to 12 */ + u8 version[ETH_STAT_INFO_VERSION_LEN]; + /* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */ + u8 mac_local[8]; + u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */ + u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */ + u32 mtu_size; /* MTU Size. Note : Negotiated MTU */ + u32 feature_flags; /* Feature_Flags. */ +#define FEATURE_ETH_CHKSUM_OFFLOAD_MASK 0x01 +#define FEATURE_ETH_LSO_MASK 0x02 +#define FEATURE_ETH_BOOTMODE_MASK 0x1C +#define FEATURE_ETH_BOOTMODE_SHIFT 2 +#define FEATURE_ETH_BOOTMODE_NONE (0x0 << 2) +#define FEATURE_ETH_BOOTMODE_PXE (0x1 << 2) +#define FEATURE_ETH_BOOTMODE_ISCSI (0x2 << 2) +#define FEATURE_ETH_BOOTMODE_FCOE (0x3 << 2) +#define FEATURE_ETH_TOE_MASK 0x20 + u32 lso_max_size; /* LSO MaxOffloadSize. */ + u32 lso_min_seg_cnt; /* LSO MinSegmentCount. */ + /* Num Offloaded Connections TCP_IPv4. */ + u32 ipv4_ofld_cnt; + /* Num Offloaded Connections TCP_IPv6. */ + u32 ipv6_ofld_cnt; + u32 promiscuous_mode; /* Promiscuous Mode. non-zero true */ + u32 txq_size; /* TX Descriptors Queue Size */ + u32 rxq_size; /* RX Descriptors Queue Size */ + /* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */ + u32 txq_avg_depth; + /* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */ + u32 rxq_avg_depth; + /* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/ + u32 iov_offload; + /* Number of NetQueue/VMQ Config'd. */ + u32 netq_cnt; + u32 vf_cnt; /* Num VF assigned to this PF. */ +}; + +/* Per PCI Function FCOE Statistics required from the driver */ +struct fcoe_stats_info { + u8 version[12]; /* Function's Driver Version. */ + u8 mac_local[8]; /* Locally Admin Addr. */ + u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */ + u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */ + /* QoS Priority (per 802.1p). 0-7255 */ + u32 qos_priority; + u32 txq_size; /* FCoE TX Descriptors Queue Size. */ + u32 rxq_size; /* FCoE RX Descriptors Queue Size. */ + /* FCoE TX Descriptor Queue Avg Depth. */ + u32 txq_avg_depth; + /* FCoE RX Descriptors Queue Avg Depth. */ + u32 rxq_avg_depth; + u32 rx_frames_lo; /* FCoE RX Frames received. */ + u32 rx_frames_hi; /* FCoE RX Frames received. */ + u32 rx_bytes_lo; /* FCoE RX Bytes received. */ + u32 rx_bytes_hi; /* FCoE RX Bytes received. */ + u32 tx_frames_lo; /* FCoE TX Frames sent. */ + u32 tx_frames_hi; /* FCoE TX Frames sent. */ + u32 tx_bytes_lo; /* FCoE TX Bytes sent. */ + u32 tx_bytes_hi; /* FCoE TX Bytes sent. */ +}; + +/* Per PCI Function iSCSI Statistics required from the driver*/ +struct iscsi_stats_info { + u8 version[12]; /* Function's Driver Version. */ + u8 mac_local[8]; /* Locally Admin iSCSI MAC Addr. */ + u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */ + /* QoS Priority (per 802.1p). 0-7255 */ + u32 qos_priority; + u8 initiator_name[64]; /* iSCSI Boot Initiator Node name. */ + u8 ww_port_name[64]; /* iSCSI World wide port name */ + u8 boot_target_name[64];/* iSCSI Boot Target Name. */ + u8 boot_target_ip[16]; /* iSCSI Boot Target IP. */ + u32 boot_target_portal; /* iSCSI Boot Target Portal. */ + u8 boot_init_ip[16]; /* iSCSI Boot Initiator IP Address. */ + u32 max_frame_size; /* Max Frame Size. bytes */ + u32 txq_size; /* PDU TX Descriptors Queue Size. */ + u32 rxq_size; /* PDU RX Descriptors Queue Size. */ + u32 txq_avg_depth; /* PDU TX Descriptor Queue Avg Depth. */ + u32 rxq_avg_depth; /* PDU RX Descriptors Queue Avg Depth. */ + u32 rx_pdus_lo; /* iSCSI PDUs received. */ + u32 rx_pdus_hi; /* iSCSI PDUs received. */ + u32 rx_bytes_lo; /* iSCSI RX Bytes received. */ + u32 rx_bytes_hi; /* iSCSI RX Bytes received. */ + u32 tx_pdus_lo; /* iSCSI PDUs sent. */ + u32 tx_pdus_hi; /* iSCSI PDUs sent. */ + u32 tx_bytes_lo; /* iSCSI PDU TX Bytes sent. */ + u32 tx_bytes_hi; /* iSCSI PDU TX Bytes sent. */ + u32 pcp_prior_map_tbl; /* C-PCP to S-PCP Priority MapTable. + * 9 nibbles, the position of each nibble + * represents the C-PCP value, the value + * of the nibble = S-PCP value. + */ +}; + +union drv_info_to_mcp { + struct eth_stats_info ether_stat; + struct fcoe_stats_info fcoe_stat; + struct iscsi_stats_info iscsi_stat; +}; +#endif /* BNX2X_MFW_REQ_H */ diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 65e66caea50d..0e9be2ba924e 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -256,11 +256,16 @@ static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg) struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; struct drv_ctl_info info; + struct fcoe_capabilities *fcoe_cap = + &info.data.register_data.fcoe_features; - if (reg) + if (reg) { info.cmd = DRV_CTL_ULP_REGISTER_CMD; - else + if (ulp_type == CNIC_ULP_FCOE && dev->fcoe_cap) + memcpy(fcoe_cap, dev->fcoe_cap, sizeof(*fcoe_cap)); + } else { info.cmd = DRV_CTL_ULP_UNREGISTER_CMD; + } info.data.ulp_type = ulp_type; ethdev->drv_ctl(dev->netdev, &info); @@ -611,6 +616,8 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) if (ulp_type == CNIC_ULP_ISCSI) cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + else if (ulp_type == CNIC_ULP_FCOE) + dev->fcoe_cap = NULL; synchronize_rcu(); diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 289274e546be..d63d45591c1f 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -12,6 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H +#include "bnx2x/bnx2x_mfw_req.h" + #define CNIC_MODULE_VERSION "2.5.10" #define CNIC_MODULE_RELDATE "March 21, 2012" @@ -131,6 +133,11 @@ struct drv_ctl_l2_ring { u32 cid; }; +struct drv_ctl_register_data { + int ulp_type; + struct fcoe_capabilities fcoe_features; +}; + struct drv_ctl_info { int cmd; union { @@ -138,6 +145,7 @@ struct drv_ctl_info { struct drv_ctl_io io; struct drv_ctl_l2_ring ring; int ulp_type; + struct drv_ctl_register_data register_data; char bytes[MAX_DRV_CTL_DATA]; } data; }; @@ -305,6 +313,7 @@ struct cnic_dev { int max_rdma_conn; union drv_info_to_mcp *stats_addr; + struct fcoe_capabilities *fcoe_cap; void *cnic_priv; }; diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index 0578fa0dc14b..42969e8a45bd 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -59,6 +59,7 @@ #include "57xx_hsi_bnx2fc.h" #include "bnx2fc_debug.h" #include "../../net/ethernet/broadcom/cnic_if.h" +#include "../../net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h" #include "bnx2fc_constants.h" #define BNX2FC_NAME "bnx2fc" @@ -84,6 +85,8 @@ #define BNX2FC_NUM_MAX_SESS 1024 #define BNX2FC_NUM_MAX_SESS_LOG (ilog2(BNX2FC_NUM_MAX_SESS)) +#define BNX2FC_MAX_NPIV 256 + #define BNX2FC_MAX_OUTSTANDING_CMNDS 2048 #define BNX2FC_CAN_QUEUE BNX2FC_MAX_OUTSTANDING_CMNDS #define BNX2FC_ELSTM_XIDS BNX2FC_CAN_QUEUE @@ -206,6 +209,7 @@ struct bnx2fc_hba { struct fcoe_statistics_params *stats_buffer; dma_addr_t stats_buf_dma; struct completion stat_req_done; + struct fcoe_capabilities fcoe_cap; /*destroy handling */ struct timer_list destroy_timer; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index f52f668fd247..05fe6620b3f0 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -1326,6 +1326,7 @@ static void bnx2fc_hba_destroy(struct bnx2fc_hba *hba) static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) { struct bnx2fc_hba *hba; + struct fcoe_capabilities *fcoe_cap; int rc; hba = kzalloc(sizeof(*hba), GFP_KERNEL); @@ -1361,6 +1362,21 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n"); goto cmgr_err; } + fcoe_cap = &hba->fcoe_cap; + + fcoe_cap->capability1 = BNX2FC_TM_MAX_SQES << + FCOE_IOS_PER_CONNECTION_SHIFT; + fcoe_cap->capability1 |= BNX2FC_NUM_MAX_SESS << + FCOE_LOGINS_PER_PORT_SHIFT; + fcoe_cap->capability2 = BNX2FC_MAX_OUTSTANDING_CMNDS << + FCOE_NUMBER_OF_EXCHANGES_SHIFT; + fcoe_cap->capability2 |= BNX2FC_MAX_NPIV << + FCOE_NPIV_WWN_PER_PORT_SHIFT; + fcoe_cap->capability3 = BNX2FC_NUM_MAX_SESS << + FCOE_TARGETS_SUPPORTED_SHIFT; + fcoe_cap->capability3 |= BNX2FC_MAX_OUTSTANDING_CMNDS << + FCOE_OUTSTANDING_COMMANDS_SHIFT; + fcoe_cap->capability4 = FCOE_CAPABILITY4_STATEFUL; init_waitqueue_head(&hba->shutdown_wait); init_waitqueue_head(&hba->destroy_wait); @@ -1691,6 +1707,32 @@ static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba) hba->pcidev = NULL; } +/** + * bnx2fc_ulp_get_stats - cnic callback to populate FCoE stats + * + * @handle: transport handle pointing to adapter struture + */ +static int bnx2fc_ulp_get_stats(void *handle) +{ + struct bnx2fc_hba *hba = handle; + struct cnic_dev *cnic; + struct fcoe_stats_info *stats_addr; + + if (!hba) + return -EINVAL; + + cnic = hba->cnic; + stats_addr = &cnic->stats_addr->fcoe_stat; + if (!stats_addr) + return -EINVAL; + + strncpy(stats_addr->version, BNX2FC_VERSION, + sizeof(stats_addr->version)); + stats_addr->txq_size = BNX2FC_SQ_WQES_MAX; + stats_addr->rxq_size = BNX2FC_CQ_WQES_MAX; + + return 0; +} /** @@ -1944,6 +1986,7 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) adapter_count++; mutex_unlock(&bnx2fc_dev_lock); + dev->fcoe_cap = &hba->fcoe_cap; clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic); rc = dev->register_device(dev, CNIC_ULP_FCOE, (void *) hba); @@ -2643,4 +2686,5 @@ static struct cnic_ulp_ops bnx2fc_cnic_cb = { .cnic_stop = bnx2fc_ulp_stop, .indicate_kcqes = bnx2fc_indicate_kcqe, .indicate_netevent = bnx2fc_indicate_netevent, + .cnic_get_stats = bnx2fc_ulp_get_stats, }; diff --git a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h index dc0a08e69c82..f2db5fe7bdc2 100644 --- a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h +++ b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h @@ -267,7 +267,13 @@ struct bnx2i_cmd_request { * task statistics for write response */ struct bnx2i_write_resp_task_stat { - u32 num_data_ins; +#if defined(__BIG_ENDIAN) + u16 num_r2ts; + u16 num_data_outs; +#elif defined(__LITTLE_ENDIAN) + u16 num_data_outs; + u16 num_r2ts; +#endif }; /* @@ -275,11 +281,11 @@ struct bnx2i_write_resp_task_stat { */ struct bnx2i_read_resp_task_stat { #if defined(__BIG_ENDIAN) - u16 num_data_outs; - u16 num_r2ts; + u16 reserved; + u16 num_data_ins; #elif defined(__LITTLE_ENDIAN) - u16 num_r2ts; - u16 num_data_outs; + u16 num_data_ins; + u16 reserved; #endif }; diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 0c53c28dc3d3..2e326145825c 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -44,6 +44,8 @@ #include "57xx_iscsi_hsi.h" #include "57xx_iscsi_constants.h" +#include "../../net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h" + #define BNX2_ISCSI_DRIVER_NAME "bnx2i" #define BNX2I_MAX_ADAPTERS 8 @@ -126,6 +128,43 @@ #define REG_WR(__hba, offset, val) \ writel(val, __hba->regview + offset) +#ifdef CONFIG_32BIT +#define GET_STATS_64(__hba, dst, field) \ + do { \ + spin_lock_bh(&__hba->stat_lock); \ + dst->field##_lo = __hba->stats.field##_lo; \ + dst->field##_hi = __hba->stats.field##_hi; \ + spin_unlock_bh(&__hba->stat_lock); \ + } while (0) + +#define ADD_STATS_64(__hba, field, len) \ + do { \ + if (spin_trylock(&__hba->stat_lock)) { \ + if (__hba->stats.field##_lo + len < \ + __hba->stats.field##_lo) \ + __hba->stats.field##_hi++; \ + __hba->stats.field##_lo += len; \ + spin_unlock(&__hba->stat_lock); \ + } \ + } while (0) + +#else +#define GET_STATS_64(__hba, dst, field) \ + do { \ + u64 val, *out; \ + \ + val = __hba->bnx2i_stats.field; \ + out = (u64 *)&__hba->stats.field##_lo; \ + *out = cpu_to_le64(val); \ + out = (u64 *)&dst->field##_lo; \ + *out = cpu_to_le64(val); \ + } while (0) + +#define ADD_STATS_64(__hba, field, len) \ + do { \ + __hba->bnx2i_stats.field += len; \ + } while (0) +#endif /** * struct generic_pdu_resc - login pdu resource structure @@ -288,6 +327,15 @@ struct iscsi_cid_queue { struct bnx2i_conn **conn_cid_tbl; }; + +struct bnx2i_stats_info { + u64 rx_pdus; + u64 rx_bytes; + u64 tx_pdus; + u64 tx_bytes; +}; + + /** * struct bnx2i_hba - bnx2i adapter structure * @@ -341,6 +389,8 @@ struct iscsi_cid_queue { * @ctx_ccell_tasks: captures number of ccells and tasks supported by * currently offloaded connection, used to decode * context memory + * @stat_lock: spin lock used by the statistic collector (32 bit) + * @stats: local iSCSI statistic collection place holder * * Adapter Data Structure */ @@ -426,6 +476,12 @@ struct bnx2i_hba { u32 num_sess_opened; u32 num_conn_opened; unsigned int ctx_ccell_tasks; + +#ifdef CONFIG_32BIT + spinlock_t stat_lock; +#endif + struct bnx2i_stats_info bnx2i_stats; + struct iscsi_stats_info stats; }; @@ -749,6 +805,8 @@ extern void bnx2i_ulp_init(struct cnic_dev *dev); extern void bnx2i_ulp_exit(struct cnic_dev *dev); extern void bnx2i_start(void *handle); extern void bnx2i_stop(void *handle); +extern int bnx2i_get_stats(void *handle); + extern struct bnx2i_hba *get_adapter_list_head(void); struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba, diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index ece47e502282..49e8b056ca10 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -1350,6 +1350,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session, struct cqe *cqe) { struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data; + struct bnx2i_hba *hba = bnx2i_conn->hba; struct bnx2i_cmd_response *resp_cqe; struct bnx2i_cmd *bnx2i_cmd; struct iscsi_task *task; @@ -1367,16 +1368,26 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session, if (bnx2i_cmd->req.op_attr & ISCSI_CMD_REQUEST_READ) { conn->datain_pdus_cnt += - resp_cqe->task_stat.read_stat.num_data_outs; + resp_cqe->task_stat.read_stat.num_data_ins; conn->rxdata_octets += bnx2i_cmd->req.total_data_transfer_length; + ADD_STATS_64(hba, rx_pdus, + resp_cqe->task_stat.read_stat.num_data_ins); + ADD_STATS_64(hba, rx_bytes, + bnx2i_cmd->req.total_data_transfer_length); } else { conn->dataout_pdus_cnt += - resp_cqe->task_stat.read_stat.num_data_outs; + resp_cqe->task_stat.write_stat.num_data_outs; conn->r2t_pdus_cnt += - resp_cqe->task_stat.read_stat.num_r2ts; + resp_cqe->task_stat.write_stat.num_r2ts; conn->txdata_octets += bnx2i_cmd->req.total_data_transfer_length; + ADD_STATS_64(hba, tx_pdus, + resp_cqe->task_stat.write_stat.num_data_outs); + ADD_STATS_64(hba, tx_bytes, + bnx2i_cmd->req.total_data_transfer_length); + ADD_STATS_64(hba, rx_pdus, + resp_cqe->task_stat.write_stat.num_r2ts); } bnx2i_iscsi_unmap_sg_list(bnx2i_cmd); @@ -1961,6 +1972,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) { struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data; struct iscsi_session *session = conn->session; + struct bnx2i_hba *hba = bnx2i_conn->hba; struct qp_info *qp; struct bnx2i_nop_in_msg *nopin; int tgt_async_msg; @@ -1973,7 +1985,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) if (!qp->cq_virt) { printk(KERN_ALERT "bnx2i (%s): cq resr freed in bh execution!", - bnx2i_conn->hba->netdev->name); + hba->netdev->name); goto out; } while (1) { @@ -1985,9 +1997,9 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) if (nopin->op_code == ISCSI_OP_NOOP_IN && nopin->itt == (u16) RESERVED_ITT) { printk(KERN_ALERT "bnx2i: Unsolicited " - "NOP-In detected for suspended " - "connection dev=%s!\n", - bnx2i_conn->hba->netdev->name); + "NOP-In detected for suspended " + "connection dev=%s!\n", + hba->netdev->name); bnx2i_unsol_pdu_adjust_rq(bnx2i_conn); goto cqe_out; } @@ -2001,7 +2013,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) /* Run the kthread engine only for data cmds All other cmds will be completed in this bh! */ bnx2i_queue_scsi_cmd_resp(session, bnx2i_conn, nopin); - break; + goto done; case ISCSI_OP_LOGIN_RSP: bnx2i_process_login_resp(session, bnx2i_conn, qp->cq_cons_qe); @@ -2044,11 +2056,15 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn) printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n", nopin->op_code); } + + ADD_STATS_64(hba, rx_pdus, 1); + ADD_STATS_64(hba, rx_bytes, nopin->data_length); +done: if (!tgt_async_msg) { if (!atomic_read(&bnx2i_conn->ep->num_active_cmds)) printk(KERN_ALERT "bnx2i (%s): no active cmd! " "op 0x%x\n", - bnx2i_conn->hba->netdev->name, + hba->netdev->name, nopin->op_code); else atomic_dec(&bnx2i_conn->ep->num_active_cmds); @@ -2692,6 +2708,7 @@ struct cnic_ulp_ops bnx2i_cnic_cb = { .cm_remote_close = bnx2i_cm_remote_close, .cm_remote_abort = bnx2i_cm_remote_abort, .iscsi_nl_send_msg = bnx2i_send_nl_mesg, + .cnic_get_stats = bnx2i_get_stats, .owner = THIS_MODULE }; diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 8b6816706ee5..7729a5223b33 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -380,6 +380,46 @@ void bnx2i_ulp_exit(struct cnic_dev *dev) } +/** + * bnx2i_get_stats - Retrieve various statistic from iSCSI offload + * @handle: bnx2i_hba + * + * function callback exported via bnx2i - cnic driver interface to + * retrieve various iSCSI offload related statistics. + */ +int bnx2i_get_stats(void *handle) +{ + struct bnx2i_hba *hba = handle; + struct iscsi_stats_info *stats; + + if (!hba) + return -EINVAL; + + stats = (struct iscsi_stats_info *)hba->cnic->stats_addr; + + if (!stats) + return -ENOMEM; + + memcpy(stats->version, DRV_MODULE_VERSION, sizeof(stats->version)); + memcpy(stats->mac_add1 + 2, hba->cnic->mac_addr, ETH_ALEN); + + stats->max_frame_size = hba->netdev->mtu; + stats->txq_size = hba->max_sqes; + stats->rxq_size = hba->max_cqes; + + stats->txq_avg_depth = 0; + stats->rxq_avg_depth = 0; + + GET_STATS_64(hba, stats, rx_pdus); + GET_STATS_64(hba, stats, rx_bytes); + + GET_STATS_64(hba, stats, tx_pdus); + GET_STATS_64(hba, stats, tx_bytes); + + return 0; +} + + /** * bnx2i_percpu_thread_create - Create a receive thread for an * online CPU diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index f8d516b53161..b40ac017012c 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -874,6 +874,11 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) hba->conn_ctx_destroy_tmo = 2 * HZ; } +#ifdef CONFIG_32BIT + spin_lock_init(&hba->stat_lock); +#endif + memset(&hba->stats, 0, sizeof(struct iscsi_stats_info)); + if (iscsi_host_add(shost, &hba->pcidev->dev)) goto free_dump_mem; return hba; @@ -1181,12 +1186,18 @@ static int bnx2i_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) { struct bnx2i_conn *bnx2i_conn = conn->dd_data; + struct bnx2i_hba *hba = bnx2i_conn->hba; struct bnx2i_cmd *cmd = task->dd_data; memset(bnx2i_conn->gen_pdu.req_buf, 0, ISCSI_DEF_MAX_RECV_SEG_LEN); bnx2i_setup_cmd_wqe_template(cmd); bnx2i_conn->gen_pdu.req_buf_size = task->data_count; + + /* Tx PDU/data length count */ + ADD_STATS_64(hba, tx_pdus, 1); + ADD_STATS_64(hba, tx_bytes, task->data_count); + if (task->data_count) { memcpy(bnx2i_conn->gen_pdu.req_buf, task->data, task->data_count); -- GitLab From ebe6e21d233bdc4f6ae5f5f649d13beb4ed7a763 Mon Sep 17 00:00:00 2001 From: Merav Sicron Date: Tue, 26 Jun 2012 06:11:03 +0000 Subject: [PATCH 3010/6849] bnx2x: Change bnx2x_tests_str_arr to static char This patch changes the definition of bnx2x_tests_str_arr from char to static char. This correction will also eliminate the sparse warning created in commit cf2c1df62e065bfc15e38daf2d3479a56b320f29. Signed-off-by: Merav Sicron Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 1f8c1561cdec..bff31290198b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1600,7 +1600,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, return 0; } -char *bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF] = { +static char *bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF] = { "register_test (offline) ", "memory_test (offline) ", "int_loopback_test (offline)", -- GitLab From c26502680e59af556211fc3fd3ae0f2aa5d98440 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 26 Jun 2012 19:59:51 +0000 Subject: [PATCH 3011/6849] net: sh_eth: remove unnecessary function The sh_eth_timer() called mod_timer() for itself. So, this patch removes the function. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 22 ---------------------- drivers/net/ethernet/renesas/sh_eth.h | 1 - 2 files changed, 23 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 326cb91abdad..cf0bc316cb60 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1339,14 +1339,6 @@ other_irq: return ret; } -static void sh_eth_timer(unsigned long data) -{ - struct net_device *ndev = (struct net_device *)data; - struct sh_eth_private *mdp = netdev_priv(ndev); - - mod_timer(&mdp->timer, jiffies + (10 * HZ)); -} - /* PHY state control function */ static void sh_eth_adjust_link(struct net_device *ndev) { @@ -1594,11 +1586,6 @@ static int sh_eth_open(struct net_device *ndev) if (ret) goto out_free_irq; - /* Set the timer to check for link beat. */ - init_timer(&mdp->timer); - mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */ - setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev); - return ret; out_free_irq: @@ -1623,9 +1610,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev) /* tx_errors count up */ ndev->stats.tx_errors++; - /* timer off */ - del_timer_sync(&mdp->timer); - /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { rxdesc = &mdp->rx_ring[i]; @@ -1643,10 +1627,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev) /* device init */ sh_eth_dev_init(ndev); - - /* timer on */ - mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */ - add_timer(&mdp->timer); } /* Packet transmit function */ @@ -1719,8 +1699,6 @@ static int sh_eth_close(struct net_device *ndev) free_irq(ndev->irq, ndev); - del_timer_sync(&mdp->timer); - /* Free all the skbuffs in the Rx queue. */ sh_eth_ring_free(ndev); diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index d6763b1392d7..5af3f2afaa28 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -772,7 +772,6 @@ struct sh_eth_private { struct sh_eth_txdesc *tx_ring; struct sk_buff **rx_skbuff; struct sk_buff **tx_skbuff; - struct timer_list timer; spinlock_t lock; u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */ u32 cur_tx, dirty_tx; -- GitLab From 2ecbb783c3bf5a63f555c39deef308dcc1902b7f Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 26 Jun 2012 19:59:58 +0000 Subject: [PATCH 3012/6849] net: sh_eth: remove unnecessary members/definitions This patch removes unnecessary members in sh_th_private. This patch also removes unnecessary definitions in sh_eth.h Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 7 +-- drivers/net/ethernet/renesas/sh_eth.h | 69 --------------------------- 2 files changed, 1 insertion(+), 75 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index cf0bc316cb60..43e76d21e57f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -941,7 +941,6 @@ static int sh_eth_dev_init(struct net_device *ndev) { int ret = 0; struct sh_eth_private *mdp = netdev_priv(ndev); - u_int32_t rx_int_var, tx_int_var; u32 val; /* Soft Reset */ @@ -971,9 +970,7 @@ static int sh_eth_dev_init(struct net_device *ndev) /* Frame recv control */ sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR); - rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; - tx_int_var = mdp->tx_int_var = DESC_I_TINT2; - sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER); + sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER); if (mdp->cd->bculr) sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */ @@ -2336,8 +2333,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) /* debug message level */ mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE; - mdp->post_rx = POST_RX >> (devno << 1); - mdp->post_fw = POST_FW >> (devno << 1); /* read and set MAC address */ read_mac_address(ndev, pd->mac_addr); diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 5af3f2afaa28..37a0702b7490 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -585,71 +585,6 @@ enum RPADIR_BIT { /* FDR */ #define DEFAULT_FDR_INIT 0x00000707 -enum phy_offsets { - PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3, - PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6, - PHY_16 = 16, -}; - -/* PHY_CTRL */ -enum PHY_CTRL_BIT { - PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000, - PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400, - PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080, -}; -#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */ - -/* PHY_STAT */ -enum PHY_STAT_BIT { - PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000, - PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020, - PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004, - PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001, -}; - -/* PHY_ANA */ -enum PHY_ANA_BIT { - PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000, - PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100, - PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020, - PHY_A_SEL = 0x001e, -}; -/* PHY_ANL */ -enum PHY_ANL_BIT { - PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000, - PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100, - PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020, - PHY_L_SEL = 0x001f, -}; - -/* PHY_ANE */ -enum PHY_ANE_BIT { - PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004, - PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001, -}; - -/* DM9161 */ -enum PHY_16_BIT { - PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000, - PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800, - PHY_16_TXselect = 0x0400, - PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100, - PHY_16_Force100LNK = 0x0080, - PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020, - PHY_16_RPDCTR_EN = 0x0010, - PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004, - PHY_16_Sleepmode = 0x0002, - PHY_16_RemoteLoopOut = 0x0001, -}; - -#define POST_RX 0x08 -#define POST_FW 0x04 -#define POST0_RX (POST_RX) -#define POST0_FW (POST_FW) -#define POST1_RX (POST_RX >> 2) -#define POST1_FW (POST_FW >> 2) -#define POST_ALL (POST0_RX | POST0_FW | POST1_RX | POST1_FW) - /* ARSTR */ enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, }; @@ -786,10 +721,6 @@ struct sh_eth_private { int msg_enable; int speed; int duplex; - u32 rx_int_var, tx_int_var; /* interrupt control variables */ - char post_rx; /* POST receive */ - char post_fw; /* POST forward */ - struct net_device_stats tsu_stats; /* TSU forward status */ int port; /* for TSU */ int vlan_num_ids; /* for VLAN tag filter */ -- GitLab From 91c77550000a7d888aaf9f9ac13e3e3485d18560 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 26 Jun 2012 20:00:01 +0000 Subject: [PATCH 3013/6849] net: sh_eth: fix up the buffer pointers After freeing the buffer, the driver should change the value of the pointer to NULL. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 31 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 43e76d21e57f..2dd2ff5ecb5a 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -788,6 +788,7 @@ static void sh_eth_ring_free(struct net_device *ndev) } } kfree(mdp->rx_skbuff); + mdp->rx_skbuff = NULL; /* Free Tx skb ringbuffer */ if (mdp->tx_skbuff) { @@ -797,6 +798,7 @@ static void sh_eth_ring_free(struct net_device *ndev) } } kfree(mdp->tx_skbuff); + mdp->tx_skbuff = NULL; } /* format skb and descriptor buffer */ @@ -933,10 +935,31 @@ desc_ring_free: skb_ring_free: /* Free Rx and Tx skb ring buffer */ sh_eth_ring_free(ndev); + mdp->tx_ring = NULL; + mdp->rx_ring = NULL; return ret; } +static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) +{ + int ringsize; + + if (mdp->rx_ring) { + ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE; + dma_free_coherent(NULL, ringsize, mdp->rx_ring, + mdp->rx_desc_dma); + mdp->rx_ring = NULL; + } + + if (mdp->tx_ring) { + ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; + dma_free_coherent(NULL, ringsize, mdp->tx_ring, + mdp->tx_desc_dma); + mdp->tx_ring = NULL; + } +} + static int sh_eth_dev_init(struct net_device *ndev) { int ret = 0; @@ -1677,7 +1700,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) static int sh_eth_close(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - int ringsize; netif_stop_queue(ndev); @@ -1700,12 +1722,7 @@ static int sh_eth_close(struct net_device *ndev) sh_eth_ring_free(ndev); /* free DMA buffer */ - ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE; - dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma); - - /* free DMA buffer */ - ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; - dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma); + sh_eth_free_dma_buffer(mdp); pm_runtime_put_sync(&mdp->pdev->dev); -- GitLab From 525b8075edda9c2ab4b81e210505bd7487ea6e56 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 26 Jun 2012 20:00:03 +0000 Subject: [PATCH 3014/6849] net: sh_eth: add support for set_ringparam/get_ringparam This patch supports the ethtool's set_ringparam() and get_ringparam(). Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 139 ++++++++++++++++++++------ drivers/net/ethernet/renesas/sh_eth.h | 6 ++ 2 files changed, 112 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 2dd2ff5ecb5a..af0b867a6cf6 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -782,7 +782,7 @@ static void sh_eth_ring_free(struct net_device *ndev) /* Free Rx skb ringbuffer */ if (mdp->rx_skbuff) { - for (i = 0; i < RX_RING_SIZE; i++) { + for (i = 0; i < mdp->num_rx_ring; i++) { if (mdp->rx_skbuff[i]) dev_kfree_skb(mdp->rx_skbuff[i]); } @@ -792,7 +792,7 @@ static void sh_eth_ring_free(struct net_device *ndev) /* Free Tx skb ringbuffer */ if (mdp->tx_skbuff) { - for (i = 0; i < TX_RING_SIZE; i++) { + for (i = 0; i < mdp->num_tx_ring; i++) { if (mdp->tx_skbuff[i]) dev_kfree_skb(mdp->tx_skbuff[i]); } @@ -809,8 +809,8 @@ static void sh_eth_ring_format(struct net_device *ndev) struct sk_buff *skb; struct sh_eth_rxdesc *rxdesc = NULL; struct sh_eth_txdesc *txdesc = NULL; - int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE; - int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE; + int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; + int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; mdp->cur_rx = mdp->cur_tx = 0; mdp->dirty_rx = mdp->dirty_tx = 0; @@ -818,7 +818,7 @@ static void sh_eth_ring_format(struct net_device *ndev) memset(mdp->rx_ring, 0, rx_ringsize); /* build Rx ring buffer */ - for (i = 0; i < RX_RING_SIZE; i++) { + for (i = 0; i < mdp->num_rx_ring; i++) { /* skb */ mdp->rx_skbuff[i] = NULL; skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz); @@ -844,7 +844,7 @@ static void sh_eth_ring_format(struct net_device *ndev) } } - mdp->dirty_rx = (u32) (i - RX_RING_SIZE); + mdp->dirty_rx = (u32) (i - mdp->num_rx_ring); /* Mark the last entry as wrapping the ring. */ rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL); @@ -852,7 +852,7 @@ static void sh_eth_ring_format(struct net_device *ndev) memset(mdp->tx_ring, 0, tx_ringsize); /* build Tx ring buffer */ - for (i = 0; i < TX_RING_SIZE; i++) { + for (i = 0; i < mdp->num_tx_ring; i++) { mdp->tx_skbuff[i] = NULL; txdesc = &mdp->tx_ring[i]; txdesc->status = cpu_to_edmac(mdp, TD_TFP); @@ -886,7 +886,7 @@ static int sh_eth_ring_init(struct net_device *ndev) mdp->rx_buf_sz += NET_IP_ALIGN; /* Allocate RX and TX skb rings */ - mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE, + mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * mdp->num_rx_ring, GFP_KERNEL); if (!mdp->rx_skbuff) { dev_err(&ndev->dev, "Cannot allocate Rx skb\n"); @@ -894,7 +894,7 @@ static int sh_eth_ring_init(struct net_device *ndev) return ret; } - mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE, + mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * mdp->num_tx_ring, GFP_KERNEL); if (!mdp->tx_skbuff) { dev_err(&ndev->dev, "Cannot allocate Tx skb\n"); @@ -903,7 +903,7 @@ static int sh_eth_ring_init(struct net_device *ndev) } /* Allocate all Rx descriptors. */ - rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE; + rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, GFP_KERNEL); @@ -917,7 +917,7 @@ static int sh_eth_ring_init(struct net_device *ndev) mdp->dirty_rx = 0; /* Allocate all Tx descriptors. */ - tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; + tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, GFP_KERNEL); if (!mdp->tx_ring) { @@ -946,21 +946,21 @@ static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) int ringsize; if (mdp->rx_ring) { - ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE; + ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma); mdp->rx_ring = NULL; } if (mdp->tx_ring) { - ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; + ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma); mdp->tx_ring = NULL; } } -static int sh_eth_dev_init(struct net_device *ndev) +static int sh_eth_dev_init(struct net_device *ndev, bool start) { int ret = 0; struct sh_eth_private *mdp = netdev_priv(ndev); @@ -1008,7 +1008,8 @@ static int sh_eth_dev_init(struct net_device *ndev) RFLR); sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); - sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); + if (start) + sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); /* PAUSE Prohibition */ val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | @@ -1023,7 +1024,8 @@ static int sh_eth_dev_init(struct net_device *ndev) sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR); /* E-MAC Interrupt Enable register */ - sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR); + if (start) + sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR); /* Set MAC address */ update_mac_address(ndev); @@ -1036,10 +1038,12 @@ static int sh_eth_dev_init(struct net_device *ndev) if (mdp->cd->tpauser) sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER); - /* Setting the Rx mode will start the Rx process. */ - sh_eth_write(ndev, EDRRR_R, EDRRR); + if (start) { + /* Setting the Rx mode will start the Rx process. */ + sh_eth_write(ndev, EDRRR_R, EDRRR); - netif_start_queue(ndev); + netif_start_queue(ndev); + } out: return ret; @@ -1054,7 +1058,7 @@ static int sh_eth_txfree(struct net_device *ndev) int entry = 0; for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) { - entry = mdp->dirty_tx % TX_RING_SIZE; + entry = mdp->dirty_tx % mdp->num_tx_ring; txdesc = &mdp->tx_ring[entry]; if (txdesc->status & cpu_to_edmac(mdp, TD_TACT)) break; @@ -1067,7 +1071,7 @@ static int sh_eth_txfree(struct net_device *ndev) freeNum++; } txdesc->status = cpu_to_edmac(mdp, TD_TFP); - if (entry >= TX_RING_SIZE - 1) + if (entry >= mdp->num_tx_ring - 1) txdesc->status |= cpu_to_edmac(mdp, TD_TDLE); ndev->stats.tx_packets++; @@ -1082,8 +1086,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_rxdesc *rxdesc; - int entry = mdp->cur_rx % RX_RING_SIZE; - int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx; + int entry = mdp->cur_rx % mdp->num_rx_ring; + int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx; struct sk_buff *skb; u16 pkt_len = 0; u32 desc_status; @@ -1134,13 +1138,13 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) ndev->stats.rx_bytes += pkt_len; } rxdesc->status |= cpu_to_edmac(mdp, RD_RACT); - entry = (++mdp->cur_rx) % RX_RING_SIZE; + entry = (++mdp->cur_rx) % mdp->num_rx_ring; rxdesc = &mdp->rx_ring[entry]; } /* Refill the Rx ring buffers. */ for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) { - entry = mdp->dirty_rx % RX_RING_SIZE; + entry = mdp->dirty_rx % mdp->num_rx_ring; rxdesc = &mdp->rx_ring[entry]; /* The size of the buffer is 16 byte boundary. */ rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); @@ -1157,7 +1161,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) skb_checksum_none_assert(skb); rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); } - if (entry >= RX_RING_SIZE - 1) + if (entry >= mdp->num_rx_ring - 1) rxdesc->status |= cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL); else @@ -1557,6 +1561,71 @@ static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data) } } +static void sh_eth_get_ringparam(struct net_device *ndev, + struct ethtool_ringparam *ring) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + + ring->rx_max_pending = RX_RING_MAX; + ring->tx_max_pending = TX_RING_MAX; + ring->rx_pending = mdp->num_rx_ring; + ring->tx_pending = mdp->num_tx_ring; +} + +static int sh_eth_set_ringparam(struct net_device *ndev, + struct ethtool_ringparam *ring) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + int ret; + + if (ring->tx_pending > TX_RING_MAX || + ring->rx_pending > RX_RING_MAX || + ring->tx_pending < TX_RING_MIN || + ring->rx_pending < RX_RING_MIN) + return -EINVAL; + if (ring->rx_mini_pending || ring->rx_jumbo_pending) + return -EINVAL; + + if (netif_running(ndev)) { + netif_tx_disable(ndev); + /* Disable interrupts by clearing the interrupt mask. */ + sh_eth_write(ndev, 0x0000, EESIPR); + /* Stop the chip's Tx and Rx processes. */ + sh_eth_write(ndev, 0, EDTRR); + sh_eth_write(ndev, 0, EDRRR); + synchronize_irq(ndev->irq); + } + + /* Free all the skbuffs in the Rx queue. */ + sh_eth_ring_free(ndev); + /* Free DMA buffer */ + sh_eth_free_dma_buffer(mdp); + + /* Set new parameters */ + mdp->num_rx_ring = ring->rx_pending; + mdp->num_tx_ring = ring->tx_pending; + + ret = sh_eth_ring_init(ndev); + if (ret < 0) { + dev_err(&ndev->dev, "%s: sh_eth_ring_init failed.\n", __func__); + return ret; + } + ret = sh_eth_dev_init(ndev, false); + if (ret < 0) { + dev_err(&ndev->dev, "%s: sh_eth_dev_init failed.\n", __func__); + return ret; + } + + if (netif_running(ndev)) { + sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); + /* Setting the Rx mode will start the Rx process. */ + sh_eth_write(ndev, EDRRR_R, EDRRR); + netif_wake_queue(ndev); + } + + return 0; +} + static const struct ethtool_ops sh_eth_ethtool_ops = { .get_settings = sh_eth_get_settings, .set_settings = sh_eth_set_settings, @@ -1567,6 +1636,8 @@ static const struct ethtool_ops sh_eth_ethtool_ops = { .get_strings = sh_eth_get_strings, .get_ethtool_stats = sh_eth_get_ethtool_stats, .get_sset_count = sh_eth_get_sset_count, + .get_ringparam = sh_eth_get_ringparam, + .set_ringparam = sh_eth_set_ringparam, }; /* network device open function */ @@ -1597,7 +1668,7 @@ static int sh_eth_open(struct net_device *ndev) goto out_free_irq; /* device init */ - ret = sh_eth_dev_init(ndev); + ret = sh_eth_dev_init(ndev, true); if (ret) goto out_free_irq; @@ -1631,7 +1702,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) ndev->stats.tx_errors++; /* Free all the skbuffs in the Rx queue. */ - for (i = 0; i < RX_RING_SIZE; i++) { + for (i = 0; i < mdp->num_rx_ring; i++) { rxdesc = &mdp->rx_ring[i]; rxdesc->status = 0; rxdesc->addr = 0xBADF00D0; @@ -1639,14 +1710,14 @@ static void sh_eth_tx_timeout(struct net_device *ndev) dev_kfree_skb(mdp->rx_skbuff[i]); mdp->rx_skbuff[i] = NULL; } - for (i = 0; i < TX_RING_SIZE; i++) { + for (i = 0; i < mdp->num_tx_ring; i++) { if (mdp->tx_skbuff[i]) dev_kfree_skb(mdp->tx_skbuff[i]); mdp->tx_skbuff[i] = NULL; } /* device init */ - sh_eth_dev_init(ndev); + sh_eth_dev_init(ndev, true); } /* Packet transmit function */ @@ -1658,7 +1729,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) unsigned long flags; spin_lock_irqsave(&mdp->lock, flags); - if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) { + if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) { if (!sh_eth_txfree(ndev)) { if (netif_msg_tx_queued(mdp)) dev_warn(&ndev->dev, "TxFD exhausted.\n"); @@ -1669,7 +1740,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) } spin_unlock_irqrestore(&mdp->lock, flags); - entry = mdp->cur_tx % TX_RING_SIZE; + entry = mdp->cur_tx % mdp->num_tx_ring; mdp->tx_skbuff[entry] = skb; txdesc = &mdp->tx_ring[entry]; /* soft swap. */ @@ -1683,7 +1754,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) else txdesc->buffer_length = skb->len; - if (entry >= TX_RING_SIZE - 1) + if (entry >= mdp->num_tx_ring - 1) txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); else txdesc->status |= cpu_to_edmac(mdp, TD_TACT); @@ -2313,6 +2384,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ether_setup(ndev); mdp = netdev_priv(ndev); + mdp->num_tx_ring = TX_RING_SIZE; + mdp->num_rx_ring = RX_RING_SIZE; mdp->addr = ioremap(res->start, resource_size(res)); if (mdp->addr == NULL) { ret = -ENOMEM; diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 37a0702b7490..bae84fd2e73a 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -27,6 +27,10 @@ #define TX_TIMEOUT (5*HZ) #define TX_RING_SIZE 64 /* Tx ring size */ #define RX_RING_SIZE 64 /* Rx ring size */ +#define TX_RING_MIN 64 +#define RX_RING_MIN 64 +#define TX_RING_MAX 1024 +#define RX_RING_MAX 1024 #define ETHERSMALL 60 #define PKT_BUF_SZ 1538 #define SH_ETH_TSU_TIMEOUT_MS 500 @@ -701,6 +705,8 @@ struct sh_eth_private { const u16 *reg_offset; void __iomem *addr; void __iomem *tsu_addr; + u32 num_rx_ring; + u32 num_tx_ring; dma_addr_t rx_desc_dma; dma_addr_t tx_desc_dma; struct sh_eth_rxdesc *rx_ring; -- GitLab From 6bc96d047fe32d76ef79f3195c52a542edf7c705 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 25 Jun 2012 22:48:41 +0000 Subject: [PATCH 3015/6849] xen/netfront: teardown the device before unregistering it. Fixes: [ 15.470311] WARNING: at /local/scratch/ianc/devel/kernels/linux/fs/sysfs/file.c:498 sysfs_attr_ns+0x95/0xa0() [ 15.470326] sysfs: kobject eth0 without dirent [ 15.470333] Modules linked in: [ 15.470342] Pid: 12, comm: xenwatch Not tainted 3.4.0-x86_32p-xenU #93 and [ 9.150554] BUG: unable to handle kernel paging request at 2b359000 [ 9.150577] IP: [] linkwatch_do_dev+0x81/0xc0 [ 9.150592] *pdpt = 000000002c3c9027 *pde = 0000000000000000 [ 9.150604] Oops: 0002 [#1] SMP [ 9.150613] Modules linked in: This is http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=675190 Reported-by: George Shuklin Signed-off-by: Ian Campbell Tested-by: William Dauchy Cc: stable@kernel.org Cc: 675190@bugs.debian.org Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 2027afe405fe..30899901aef5 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1935,14 +1935,14 @@ static int __devexit xennet_remove(struct xenbus_device *dev) dev_dbg(&dev->dev, "%s\n", dev->nodename); - unregister_netdev(info->netdev); - xennet_disconnect_backend(info); - del_timer_sync(&info->rx_refill_timer); - xennet_sysfs_delif(info->netdev); + unregister_netdev(info->netdev); + + del_timer_sync(&info->rx_refill_timer); + free_percpu(info->stats); free_netdev(info->netdev); -- GitLab From e9bf5f36b09f8ec6c168ef58ee7d4890545ede1c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 27 Jun 2012 09:26:01 +0100 Subject: [PATCH 3016/6849] drm/nouveau: add license header to prime. Just forgot this when I posted it, and yes I'm the only person to have changed the file since. Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_prime.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index a89240e5fb29..a25cf2cb931f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -1,3 +1,26 @@ +/* + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + */ #include "drmP.h" #include "drm.h" -- GitLab From 93040ae5cc8dcc893eca4a4366dc8415af278edf Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Tue, 26 Jun 2012 22:32:10 +0000 Subject: [PATCH 3017/6849] be2net: Fix to trim skb for padded vlan packets to workaround an ASIC Bug Fixed spelling error in a comment as pointed out by DaveM. Also refactored existing code a bit to provide placeholders for another ASIC Bug workaround that will be checked-in soon after this. Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 5 ++ drivers/net/ethernet/emulex/benet/be_main.c | 56 +++++++++++++++------ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 7b5cc2b212e5..7a71fb66c6dc 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -573,6 +573,11 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) return val; } +static inline bool is_ipv4_pkt(struct sk_buff *skb) +{ + return skb->protocol == ntohs(ETH_P_IP) && ip_hdr(skb)->version == 4; +} + static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) { u32 addr; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a28896d4411d..edce7af97c87 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -577,6 +577,11 @@ static inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter, return vlan_tag; } +static int be_vlan_tag_chk(struct be_adapter *adapter, struct sk_buff *skb) +{ + return vlan_tx_tag_present(skb) || adapter->pvid; +} + static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, u32 wrb_cnt, u32 len) { @@ -704,33 +709,56 @@ dma_err: return 0; } +static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, + struct sk_buff *skb) +{ + u16 vlan_tag = 0; + + skb = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + return skb; + + if (vlan_tx_tag_present(skb)) { + vlan_tag = be_get_tx_vlan_tag(adapter, skb); + __vlan_put_tag(skb, vlan_tag); + skb->vlan_tci = 0; + } + + return skb; +} + static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)]; struct be_queue_info *txq = &txo->q; + struct iphdr *ip = NULL; u32 wrb_cnt = 0, copied = 0; - u32 start = txq->head; + u32 start = txq->head, eth_hdr_len; bool dummy_wrb, stopped = false; - /* For vlan tagged pkts, BE - * 1) calculates checksum even when CSO is not requested - * 2) calculates checksum wrongly for padded pkt less than - * 60 bytes long. - * As a workaround disable TX vlan offloading in such cases. + eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ? + VLAN_ETH_HLEN : ETH_HLEN; + + /* HW has a bug which considers padding bytes as legal + * and modifies the IPv4 hdr's 'tot_len' field */ - if (vlan_tx_tag_present(skb) && - (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60)) { - skb = skb_share_check(skb, GFP_ATOMIC); - if (unlikely(!skb)) - goto tx_drop; + if (skb->len <= 60 && be_vlan_tag_chk(adapter, skb) && + is_ipv4_pkt(skb)) { + ip = (struct iphdr *)ip_hdr(skb); + pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); + } - skb = __vlan_put_tag(skb, be_get_tx_vlan_tag(adapter, skb)); + /* HW has a bug wherein it will calculate CSUM for VLAN + * pkts even though it is disabled. + * Manually insert VLAN in pkt. + */ + if (skb->ip_summed != CHECKSUM_PARTIAL && + be_vlan_tag_chk(adapter, skb)) { + skb = be_insert_vlan_in_pkt(adapter, skb); if (unlikely(!skb)) goto tx_drop; - - skb->vlan_tci = 0; } wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); -- GitLab From 85f2f834e85517307f13e30e630a5fc86f757cb5 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 27 Jun 2012 16:19:18 +0800 Subject: [PATCH 3018/6849] can: flexcan: use be32_to_cpup to handle the value of dt entry The freescale arm i.MX series platform can support this driver, and usually the arm cpu works in the little endian mode by default, while device tree entry value is stored in big endian format, we should use be32_to_cpup() to handle them, after modification, it can work well both on the le cpu and be cpu. Cc: stable # v3.2+ Cc: Shawn Guo Signed-off-by: Hui Wang Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 38c0690df5c8..81d474102378 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -939,12 +939,12 @@ static int __devinit flexcan_probe(struct platform_device *pdev) return PTR_ERR(pinctrl); if (pdev->dev.of_node) { - const u32 *clock_freq_p; + const __be32 *clock_freq_p; clock_freq_p = of_get_property(pdev->dev.of_node, "clock-frequency", NULL); if (clock_freq_p) - clock_freq = *clock_freq_p; + clock_freq = be32_to_cpup(clock_freq_p); } if (!clock_freq) { -- GitLab From da185443c12f5ef7416af50293833a5654854186 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 18 Jun 2012 21:16:31 +0200 Subject: [PATCH 3019/6849] ALSA: snd-usb-caiaq: initialize card pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following warning: CC [M] sound/usb/caiaq/device.o sound/usb/caiaq/device.c: In function ‘snd_probe’: sound/usb/caiaq/device.c:500:16: warning: ‘card’ may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai --- sound/usb/caiaq/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 64aed432ae22..7da0d0aa72cb 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -485,7 +485,7 @@ static int __devinit snd_probe(struct usb_interface *intf, const struct usb_device_id *id) { int ret; - struct snd_card *card; + struct snd_card *card = NULL; struct usb_device *device = interface_to_usbdev(intf); ret = create_card(device, intf, &card); -- GitLab From 2d4cf5ae123e4a7bd26a88e600581aa809bcad7f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 18 Jun 2012 16:31:22 -0700 Subject: [PATCH 3020/6849] UBIFS: correct usage of IS_ENABLED() Commit "818039c UBIFS: fix debugfs-less systems support" fixed one regression but introduced a different regression - the debugfs is now always compiled out. Root cause: IS_ENABLED() arguments should be used with the CONFIG_* prefix. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- fs/ubifs/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 84a7e6f3c046..92df3b081539 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -2918,7 +2918,7 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) struct dentry *dent; struct ubifs_debug_info *d = c->dbg; - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, @@ -3013,7 +3013,7 @@ out: */ void dbg_debugfs_exit_fs(struct ubifs_info *c) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(c->dbg->dfs_dir); } @@ -3099,7 +3099,7 @@ int dbg_debugfs_init(void) const char *fname; struct dentry *dent; - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; fname = "ubifs"; @@ -3166,7 +3166,7 @@ out: */ void dbg_debugfs_exit(void) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(dfs_rootdir); } -- GitLab From 903e0e4ef9120c3d7693599acb95e76e8263fb35 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 18 Jun 2012 16:31:23 -0700 Subject: [PATCH 3021/6849] UBI: correct usage of IS_ENABLED() Commit "e9b4cf2 UBI: fix debugfs-less systems support" fixed one regression but introduced a different regression - the debugfs is now always compiled out. Root cause: IS_ENABLED() arguments should be used with the CONFIG_* prefix. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 09d4f8d9d592..7c1380305219 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -264,7 +264,7 @@ static struct dentry *dfs_rootdir; */ int ubi_debugfs_init(void) { - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; dfs_rootdir = debugfs_create_dir("ubi", NULL); @@ -284,7 +284,7 @@ int ubi_debugfs_init(void) */ void ubi_debugfs_exit(void) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove(dfs_rootdir); } @@ -407,7 +407,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) struct dentry *dent; struct ubi_debug_info *d = ubi->dbg; - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, @@ -477,6 +477,6 @@ out: */ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(ubi->dbg->dfs_dir); } -- GitLab From 26c8aaebc188b539a0a9077350009a059464097d Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Wed, 27 Jun 2012 13:31:01 +0200 Subject: [PATCH 3022/6849] crypto: algapi - Fix hang on crypto allocation git commit 398710379 (crypto: algapi - Move larval completion into algboss) replaced accidentally a call to complete_all() by a call to complete(). This causes a hang on crypto allocation if we have more than one larval waiter. This pach restores the call to complete_all(). Signed-off-by: Steffen Klassert Signed-off-by: Herbert Xu --- crypto/algboss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/algboss.c b/crypto/algboss.c index f97027e7d996..769219b29309 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c @@ -87,7 +87,7 @@ static int cryptomgr_probe(void *data) crypto_tmpl_put(tmpl); out: - complete(param->completion); + complete_all(param->completion); kfree(param); module_put_and_exit(0); } -- GitLab From bcf6c3d46fa8624397cc52d9f13f9a71bf3a572f Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Fri, 25 May 2012 17:25:36 +0800 Subject: [PATCH 3023/6849] clk: mxs: rename the gpmi clock for imx28 rename the clock name from `8000c000.gpmi` to `8000c000.gpmi-nand`. Signed-off-by: Huang Shijie Signed-off-by: Shawn Guo --- drivers/clk/mxs/clk-imx28.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 2826a2606a29..003b0f31c1ba 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -174,7 +174,7 @@ static struct clk_lookup lcdif_lookups[] __initdata = { static struct clk_lookup gpmi_lookups[] __initdata = { { .dev_id = "imx28-gpmi-nand", }, - { .dev_id = "8000c000.gpmi", }, + { .dev_id = "8000c000.gpmi-nand", }, }; static struct clk_lookup fec_lookups[] __initdata = { -- GitLab From 8c6facab8e99f7f90eaa1edbaf4baf217ac5ea5f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 19 Jun 2012 17:27:32 -0300 Subject: [PATCH 3024/6849] clk: mxs: Fix the GPMI clock name The correct name for the GPMI clock is 'gpmi-nand'. Signed-off-by: Fabio Estevam Acked-by: Marek Vasut Signed-off-by: Shawn Guo --- drivers/clk/mxs/clk-imx23.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index f7be225f544c..40ad638dbe6c 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c @@ -106,7 +106,7 @@ static struct clk_lookup lcdif_lookups[] __initdata = { static struct clk_lookup gpmi_lookups[] __initdata = { { .dev_id = "imx23-gpmi-nand", }, - { .dev_id = "8000c000.gpmi", }, + { .dev_id = "8000c000.gpmi-nand", }, }; static const char *sel_pll[] __initconst = { "pll", "ref_xtal", }; -- GitLab From 275d58025f8d59c493384e1e9660c9c5b7b28d2d Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 25 Jun 2012 20:56:03 +0800 Subject: [PATCH 3025/6849] clk: mxs: add clkdev lookup for pwm Add pwm clock lookup for imx23 and imx28 booting from device tree. Signed-off-by: Shawn Guo --- drivers/clk/mxs/clk-imx23.c | 1 + drivers/clk/mxs/clk-imx28.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index 40ad638dbe6c..c14b021c4a68 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c @@ -189,6 +189,7 @@ int __init mx23_clocks_init(void) } clk_register_clkdev(clks[clk32k], NULL, "timrot"); + clk_register_clkdev(clks[pwm], NULL, "80064000.pwm"); clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups)); clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups)); clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups)); diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 003b0f31c1ba..365053f052cd 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -314,6 +314,7 @@ int __init mx28_clocks_init(void) clk_register_clkdev(clks[clk32k], NULL, "timrot"); clk_register_clkdev(clks[enet_out], NULL, "enet_out"); + clk_register_clkdev(clks[pwm], NULL, "80064000.pwm"); clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups)); clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups)); clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups)); -- GitLab From 8138136ec26277c59df47a7f5756e5308cc634b2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 May 2012 00:20:13 -0300 Subject: [PATCH 3026/6849] ARM: mxs: Let GPMI driver be built by default Let GPMI driver be built by default. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/configs/mxs_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 5406c23a02e3..6b86df7bb243 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -58,6 +58,9 @@ CONFIG_CAN_FLEXCAN=m CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_BLK_DEV is not set +CONFIG_MTD=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_GPMI_NAND=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_ENC28J60=y -- GitLab From 79a6664c29603bae044f8ec2f53720519d0db8f0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 1 Jun 2012 00:26:13 -0300 Subject: [PATCH 3027/6849] ARM: mxs: Enable MACH_APX4DEVKIT Enable MACH_APX4DEVKIT to be built by default. Signed-off-by: Fabio Estevam Acked-by: Lauri Hintsala Signed-off-by: Shawn Guo --- arch/arm/configs/mxs_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 6b86df7bb243..ae411ddcc7c0 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -28,6 +28,7 @@ CONFIG_MACH_MX28EVK=y CONFIG_MACH_STMP378X_DEVB=y CONFIG_MACH_TX28=y CONFIG_MACH_M28EVK=y +CONFIG_MACH_APX4DEVKIT=y # CONFIG_ARM_THUMB is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y -- GitLab From 783f061371536b1c2f8326e24f4ff287348ea59c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 15 Jun 2012 08:32:30 -0300 Subject: [PATCH 3028/6849] ARM: mxs_defconfig: Let AUART driver be built by default Let AUART driver be built by default. Signed-off-by: Fabio Estevam Reviewed-by: Marek Vasut Signed-off-by: Shawn Guo --- arch/arm/configs/mxs_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index ae411ddcc7c0..94198c52fe2c 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -81,6 +81,7 @@ CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_DEVKMEM is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_MXS_AUART=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set -- GitLab From 597c854974db20eebe87e91df0d12daaefabf525 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 22 Jun 2012 20:41:10 +0530 Subject: [PATCH 3029/6849] dma: tegra: use sg_dma_address() for getting dma buffer address Use the sg_dma_address() to get the segment buffer address for DMA transfer in place of sg_phys() which returns the physical address of an sg entry. The sg_dma_address() returns the correct buffer memory address for DMA transfer. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 134ea7cfc795..6d7d5d383cb1 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -929,7 +929,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( for_each_sg(sgl, sg, sg_len, i) { u32 len, mem; - mem = sg_phys(sg); + mem = sg_dma_address(sg); len = sg_dma_len(sg); if ((len & 3) || (mem & 3) || -- GitLab From 56482ec0b156811eb463576a89a47f89e21f3587 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Mon, 25 Jun 2012 12:01:31 +0530 Subject: [PATCH 3030/6849] dma: tegra: add clk_prepare/clk_unprepare Use clk_prepare/clk_unprepare as required by the generic clk framework. Signed-off-by: Prashant Gaikwad Acked-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 6d7d5d383cb1..78af256cca9e 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1366,7 +1366,7 @@ static int tegra_dma_runtime_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct tegra_dma *tdma = platform_get_drvdata(pdev); - clk_disable(tdma->dma_clk); + clk_disable_unprepare(tdma->dma_clk); return 0; } @@ -1376,7 +1376,7 @@ static int tegra_dma_runtime_resume(struct device *dev) struct tegra_dma *tdma = platform_get_drvdata(pdev); int ret; - ret = clk_enable(tdma->dma_clk); + ret = clk_prepare_enable(tdma->dma_clk); if (ret < 0) { dev_err(dev, "clk_enable failed: %d\n", ret); return ret; -- GitLab From 6660f7af52caf6028b36e6a68a21c461f2fb0440 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 22 Jun 2012 17:12:44 +0530 Subject: [PATCH 3031/6849] dma: tegra: do not set transfer desc flag to DMA_CTRL_ACK in cyclic mode The sound dmaengine pcm driver uses the dma in cyclic mode and it does not ack the transfer descriptor after transfer stops. This may lead to hold that desc in chip's dma driver and does not allow to reuse/free that descriptors. Hence not enabling flag DMA_CTRL_ACK when dma runs in cyclic mode. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 78af256cca9e..ba4d73c525e6 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1093,7 +1093,7 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( mem += len; } sg_req->last_sg = true; - dma_desc->txd.flags = DMA_CTRL_ACK; + dma_desc->txd.flags = 0; /* * Make sure that mode should not be conflicting with currently -- GitLab From 46fb3f8ef5bde1325b1e58867a3a98dd746511d7 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 22 Jun 2012 17:12:43 +0530 Subject: [PATCH 3032/6849] dma: tegra: set DMA_CYCLIC capability Tegra's APB DMA driver support the cyclic mode of data transfer and hence setting the DMA_CYCLIC caps for dma channels. This is require when generic sound dmaengine pcm driver request for dma channel with CYCLIC capability. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Vinod Koul --- drivers/dma/tegra20-apb-dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index ba4d73c525e6..c0836a7a8631 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1306,6 +1306,8 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask); dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask); + dma_cap_set(DMA_CYCLIC, tdma->dma_dev.cap_mask); + tdma->dma_dev.dev = &pdev->dev; tdma->dma_dev.device_alloc_chan_resources = tegra_dma_alloc_chan_resources; -- GitLab From 3dba1c265268950b1ddd22e53ea823c1cb57b684 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 27 Jun 2012 14:59:20 +0100 Subject: [PATCH 3033/6849] ASoC: wm5102: Remove unused platform data header Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 9b9ea7fd0d7d..e76c41e1f847 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include -- GitLab From bf2516cd020dbf80ed2f1750ac1f4b0da3549c91 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 27 Jun 2012 10:40:28 -0300 Subject: [PATCH 3034/6849] regulator: core: Remove unused get_device_regulator commit 222cc7b1 (regulator: core: Allow multiple requests of a single supply mapping) removed the usage of get_device_regulator(). Remove the function definition too amd get rid of the following warning: drivers/regulator/core.c:112:26: warning: 'get_device_regulator' defined but not used [-Wunused-function] Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/regulator/core.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 00c787c01f3b..d886ee265e47 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -108,28 +108,6 @@ static const char *rdev_get_name(struct regulator_dev *rdev) return ""; } -/* gets the regulator for a given consumer device */ -static struct regulator *get_device_regulator(struct device *dev) -{ - struct regulator *regulator = NULL; - struct regulator_dev *rdev; - - mutex_lock(®ulator_list_mutex); - list_for_each_entry(rdev, ®ulator_list, list) { - mutex_lock(&rdev->mutex); - list_for_each_entry(regulator, &rdev->consumer_list, list) { - if (regulator->dev == dev) { - mutex_unlock(&rdev->mutex); - mutex_unlock(®ulator_list_mutex); - return regulator; - } - } - mutex_unlock(&rdev->mutex); - } - mutex_unlock(®ulator_list_mutex); - return NULL; -} - /** * of_get_regulator - get a regulator device node based on supply name * @dev: Device pointer for the consumer (of regulator) device -- GitLab From 8ca78f3eda4bf1799e8c4ba02035623fd7a347df Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 27 Jun 2012 15:05:48 +0200 Subject: [PATCH 3035/6849] Btrfs: avoid waiting for delayed refs when we must not We track two conditions to decide if we should sleep while waiting for more delayed refs, the number of delayed refs (num_refs) and the first entry in the list of blockers (first_seq). When we suspect staleness, we save num_refs and do one more cycle. If nothing changes, we then save first_seq for later comparison and do wait_event. We ought to save first_seq the very same moment we're saving num_refs. Otherwise we cannot be sure that nothing has changed and we might start waiting when we shouldn't, which could lead to starvation. Signed-off-by: Jan Schmidt --- fs/btrfs/extent-tree.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4b5a1e1bdefb..6e1d36702ff7 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2347,12 +2347,10 @@ next: return count; } - static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs, - unsigned long num_refs) + unsigned long num_refs, + struct list_head *first_seq) { - struct list_head *first_seq = delayed_refs->seq_head.next; - spin_unlock(&delayed_refs->lock); pr_debug("waiting for more refs (num %ld, first %p)\n", num_refs, first_seq); @@ -2381,6 +2379,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_delayed_ref_node *ref; struct list_head cluster; + struct list_head *first_seq = NULL; int ret; u64 delayed_start; int run_all = count == (unsigned long)-1; @@ -2436,8 +2435,10 @@ again: */ consider_waiting = 1; num_refs = delayed_refs->num_entries; + first_seq = root->fs_info->tree_mod_seq_list.next; } else { - wait_for_more_refs(delayed_refs, num_refs); + wait_for_more_refs(delayed_refs, + num_refs, first_seq); /* * after waiting, things have changed. we * dropped the lock and someone else might have -- GitLab From 9345457f4a539a40056431aeb6f068750857472f Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 27 Jun 2012 15:23:09 +0200 Subject: [PATCH 3036/6849] Btrfs: support root level changes in __resolve_indirect_ref With the tree mod log, we can have a tree that's two levels high, but btrfs_search_old_slot may still return a path with the tree root at level one instead. __resolve_indirect_ref must care for this and accept parents in a lower level than expected. Signed-off-by: Jan Schmidt --- fs/btrfs/backref.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 7301cdb4b2cb..cf0df904347f 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -301,10 +301,14 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, goto out; eb = path->nodes[level]; - if (!eb) { - WARN_ON(1); - ret = 1; - goto out; + while (!eb) { + if (!level) { + WARN_ON(1); + ret = 1; + goto out; + } + level--; + eb = path->nodes[level]; } ret = add_all_parents(root, path, parents, level, &ref->key_for_search, -- GitLab From 28da9fb4467f7a650cd31af6dfad3a4e4a3abf6e Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 21 Jun 2012 10:59:13 +0200 Subject: [PATCH 3037/6849] Btrfs: fix tree mod log for root replacements at leaf level For the tree mod log, we don't log any operations at leaf level. If the root is at the leaf level (i.e. the tree consists only of the root), then __tree_mod_log_oldest_root will find a ROOT_REPLACE operation in the log (because we always log that one no matter which level), but no other operations. With this patch __tree_mod_log_oldest_root exits cleanly instead of BUGging in this situation. get_old_root checks if its really a root at leaf level in case we don't have any operations and WARNs if this assumption breaks. Signed-off-by: Jan Schmidt --- fs/btrfs/ctree.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 15cbc2bf4ff0..7d1e4fc5fb6a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1024,11 +1024,18 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info, if (!looped && !tm) return 0; /* - * we must have key remove operations in the log before the - * replace operation. + * if there are no tree operation for the oldest root, we simply + * return it. this should only happen if that (old) root is at + * level 0. */ - BUG_ON(!tm); + if (!tm) + break; + /* + * if there's an operation that's not a root replacement, we + * found the oldest version of our root. normally, we'll find a + * MOD_LOG_KEY_REMOVE_WHILE_FREEING operation here. + */ if (tm->op != MOD_LOG_ROOT_REPLACE) break; @@ -1192,16 +1199,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq) } tm = tree_mod_log_search(root->fs_info, logical, time_seq); - /* - * there was an item in the log when __tree_mod_log_oldest_root - * returned. this one must not go away, because the time_seq passed to - * us must be blocking its removal. - */ - BUG_ON(!tm); - if (old_root) - eb = alloc_dummy_extent_buffer(tm->index << PAGE_CACHE_SHIFT, - root->nodesize); + eb = alloc_dummy_extent_buffer(logical, root->nodesize); else eb = btrfs_clone_extent_buffer(root->node); btrfs_tree_read_unlock(root->node); @@ -1216,7 +1215,10 @@ get_old_root(struct btrfs_root *root, u64 time_seq) btrfs_set_header_level(eb, old_root->level); btrfs_set_header_generation(eb, old_generation); } - __tree_mod_log_rewind(eb, time_seq, tm); + if (tm) + __tree_mod_log_rewind(eb, time_seq, tm); + else + WARN_ON(btrfs_header_level(eb) != 0); extent_buffer_get(eb); return eb; -- GitLab From c3e0696523862c48b4d8c73ffb2867e9db478338 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 21 Jun 2012 11:01:06 +0200 Subject: [PATCH 3038/6849] Btrfs: always put insert_ptr modifications into the tree mod log Several callers of insert_ptr set the tree_mod_log parameter to 0 to avoid addition to the tree mod log. In fact, we need all of those operations. This commit simply removes the additional parameter and makes addition to the tree mod log unconditional. Signed-off-by: Jan Schmidt --- fs/btrfs/ctree.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 7d1e4fc5fb6a..e005d9b04616 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2997,7 +2997,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, static void insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_disk_key *key, u64 bytenr, - int slot, int level, int tree_mod_log) + int slot, int level) { struct extent_buffer *lower; int nritems; @@ -3010,7 +3010,7 @@ static void insert_ptr(struct btrfs_trans_handle *trans, BUG_ON(slot > nritems); BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root)); if (slot != nritems) { - if (tree_mod_log && level) + if (level) tree_mod_log_eb_move(root->fs_info, lower, slot + 1, slot, nritems - slot); memmove_extent_buffer(lower, @@ -3018,7 +3018,7 @@ static void insert_ptr(struct btrfs_trans_handle *trans, btrfs_node_key_ptr_offset(slot), (nritems - slot) * sizeof(struct btrfs_key_ptr)); } - if (tree_mod_log && level) { + if (level) { ret = tree_mod_log_insert_key(root->fs_info, lower, slot, MOD_LOG_KEY_ADD); BUG_ON(ret < 0); @@ -3106,7 +3106,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(split); insert_ptr(trans, root, path, &disk_key, split->start, - path->slots[level + 1] + 1, level + 1, 1); + path->slots[level + 1] + 1, level + 1); if (path->slots[level] >= mid) { path->slots[level] -= mid; @@ -3643,7 +3643,7 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, btrfs_set_header_nritems(l, mid); btrfs_item_key(right, &disk_key, 0); insert_ptr(trans, root, path, &disk_key, right->start, - path->slots[1] + 1, 1, 0); + path->slots[1] + 1, 1); btrfs_mark_buffer_dirty(right); btrfs_mark_buffer_dirty(l); @@ -3850,7 +3850,7 @@ again: if (mid <= slot) { btrfs_set_header_nritems(right, 0); insert_ptr(trans, root, path, &disk_key, right->start, - path->slots[1] + 1, 1, 0); + path->slots[1] + 1, 1); btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; @@ -3859,7 +3859,7 @@ again: } else { btrfs_set_header_nritems(right, 0); insert_ptr(trans, root, path, &disk_key, right->start, - path->slots[1], 1, 0); + path->slots[1], 1); btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; -- GitLab From 155725c9c051a343be5e555bf943da827e6cf721 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 22 Jun 2012 14:01:00 +0200 Subject: [PATCH 3039/6849] Btrfs: leave critical region in btrfs_find_all_roots as soon as possible When delayed refs exist, btrfs_find_all_roots used to hold the delayed ref mutex way longer than actually required. We ought to drop it immediately after we're done collecting all the delayed refs. Signed-off-by: Jan Schmidt --- fs/btrfs/backref.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index cf0df904347f..a383c18e74e8 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -839,6 +839,7 @@ again: } ret = __add_delayed_refs(head, delayed_ref_seq, &prefs_delayed); + mutex_unlock(&head->mutex); if (ret) { spin_unlock(&delayed_refs->lock); goto out; @@ -932,8 +933,6 @@ again: } out: - if (head) - mutex_unlock(&head->mutex); btrfs_free_path(path); while (!list_empty(&prefs)) { ref = list_first_entry(&prefs, struct __prelim_ref, list); -- GitLab From 19956c7e94a7a58d6df8c4db5ae62f9109a7c663 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 22 Jun 2012 14:52:13 +0200 Subject: [PATCH 3040/6849] Btrfs: fix tree mod log rewind of ADD operations When a MOD_LOG_KEY_ADD operation is rewinded, we remove the key from the tree block. If its not the last key, removal involves a move operation. This move operation was explicitly done before this commit. However, at insertion time, there's a move operation before the actual addition to make room for the new key, which is recorded in the tree mod log as well. This means, we must drop the move operation when rewinding the add operation, because the next operation we'll be rewinding will be the corresponding MOD_LOG_MOVE_KEYS operation. Signed-off-by: Jan Schmidt --- fs/btrfs/ctree.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index e005d9b04616..b98f8604f4f6 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1094,11 +1094,7 @@ __tree_mod_log_rewind(struct extent_buffer *eb, u64 time_seq, tm->generation); break; case MOD_LOG_KEY_ADD: - if (tm->slot != n - 1) { - o_dst = btrfs_node_key_ptr_offset(tm->slot); - o_src = btrfs_node_key_ptr_offset(tm->slot + 1); - memmove_extent_buffer(eb, o_dst, o_src, p_size); - } + /* if a move operation is needed it's in the log */ n--; break; case MOD_LOG_MOVE_KEYS: -- GitLab From d42244a0d36ad0939c5f173ebf15841a0678899c Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 22 Jun 2012 14:51:15 +0200 Subject: [PATCH 3041/6849] Btrfs: resolve tree mod log locking issue in btrfs_next_leaf With the tree mod log, we may end up with two roots (the current root and a rewinded version of it) both pointing to two leaves, l1 and l2, of which l2 had already been cow-ed in the current transaction. If we don't rewind any tree blocks, we cannot have two roots both pointing to an already cowed tree block. Now there is btrfs_next_leaf, which has a leaf locked and wants a lock on the next (right) leaf. And there is push_leaf_left, which has a (cowed!) leaf locked and wants a lock on the previous (left) leaf. In order to solve this dead lock situation, we use try_lock in btrfs_next_leaf (only in case it's called with a tree mod log time_seq paramter) and if we fail to get a lock on the next leaf, we give up our lock on the current leaf and retry from the very beginning. Signed-off-by: Jan Schmidt --- fs/btrfs/ctree.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b98f8604f4f6..8206b3900587 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -5119,6 +5119,18 @@ again: if (!path->skip_locking) { ret = btrfs_try_tree_read_lock(next); + if (!ret && time_seq) { + /* + * If we don't get the lock, we may be racing + * with push_leaf_left, holding that lock while + * itself waiting for the leaf we've currently + * locked. To solve this situation, we give up + * on our lock and cycle. + */ + btrfs_release_path(path); + cond_resched(); + goto again; + } if (!ret) { btrfs_set_path_blocking(path); btrfs_tree_read_lock(next); -- GitLab From e90b833ee1aae64b6fca2455001323ffe29e1698 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Mon, 25 Jun 2012 12:38:23 -0500 Subject: [PATCH 3042/6849] ARM: OMAP4470: Fix OMAP4470 boot failure OMAP4470 currently fails to boot, printing various messages such as ... omap_hwmod: mpu: cannot clk_get main_clk dpll_mpu_m2_ck omap_hwmod: mpu: cannot _init_clocks ------------[ cut here ]------------ WARNING: at arch/arm/mach-omap2/omap_hwmod.c:2062 _init+0x2a0/0x2e4() omap_hwmod: mpu: couldn't init clocks Modules linked in: [] (unwind_backtrace+0x0/0xf4) from [] (warn_slowpath_common+0x4c/0x64) [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x30/0x40) [] (warn_slowpath_fmt+0x30/0x40) from [] (_init+0x2a0/0x2e4) [] (_init+0x2a0/0x2e4) from [] (omap_hwmod_setup_one+0x40/0x60) [] (omap_hwmod_setup_one+0x40/0x60) from [] (omap_hwmod_setup_one+0x34/0x60) [] (omap_hwmod_setup_one+0x34/0x60) from [] (omap_dm_timer_init_one+0x30/0x250) [] (omap_dm_timer_init_one+0x30/0x250) from [] (omap2_gp_clockevent_init+0x1c/0x108) [] (omap2_gp_clockevent_init+0x1c/0x108) from [] (omap4_timer_init+0x10/0x5c) [] (omap4_timer_init+0x10/0x5c) from [] (time_init+0x20/0x30) [] (time_init+0x20/0x30) from [] (start_kernel+0x1b0/0x304) [] (start_kernel+0x1b0/0x304) from [<80008044>] (0x80008044) ---[ end trace 1b75b31a2719ed1c ]--- The problem is that currently none of the clocks are being registered for OMAP4470 devices and so on boot-up no clocks can be found and the kernel panics. This fix allows the kernel to boot without failure using a simple RAMDISK file system on OMAP4470 blaze board. Per feedback from Paul and Benoit the 4470 clock data is incomplete for new modules such as the 2D graphics block that has been added to the 4470. Therefore add a warning to indicate that the clock data is incomplete. Cc: Paul Walmsley Cc: Benoit Cousson Signed-off-by: Jon Hunter [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock44xx_data.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index e2b701e164f6..ba6f9a0a43e9 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -3417,9 +3417,12 @@ int __init omap4xxx_clk_init(void) if (cpu_is_omap443x()) { cpu_mask = RATE_IN_4430; cpu_clkflg = CK_443X; - } else if (cpu_is_omap446x()) { + } else if (cpu_is_omap446x() || cpu_is_omap447x()) { cpu_mask = RATE_IN_4460 | RATE_IN_4430; cpu_clkflg = CK_446X | CK_443X; + + if (cpu_is_omap447x()) + pr_warn("WARNING: OMAP4470 clock data incomplete!\n"); } else { return 0; } -- GitLab From 392025f87a5105c640cf1b4b317c21c14c05a6f9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 26 Jun 2012 20:27:09 +0200 Subject: [PATCH 3043/6849] netfilter: ctnetlink: add new messages to obtain statistics This patch adds the following messages to ctnetlink: IPCTNL_MSG_CT_GET_STATS_CPU IPCTNL_MSG_CT_GET_STATS IPCTNL_MSG_EXP_GET_STATS_CPU To display connection tracking system per-cpu and global statistics. This provides a replacement for the following /proc interfaces: /proc/net/stat/nf_conntrack /proc/sys/net/netfilter/nf_conntrack_count Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/nfnetlink_conntrack.h | 38 +++ net/netfilter/nf_conntrack_netlink.c | 227 +++++++++++++++++- 2 files changed, 264 insertions(+), 1 deletion(-) diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index 768883370080..f649f7423ca2 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h @@ -7,6 +7,8 @@ enum cntl_msg_types { IPCTNL_MSG_CT_GET, IPCTNL_MSG_CT_DELETE, IPCTNL_MSG_CT_GET_CTRZERO, + IPCTNL_MSG_CT_GET_STATS_CPU, + IPCTNL_MSG_CT_GET_STATS, IPCTNL_MSG_MAX }; @@ -15,6 +17,7 @@ enum ctnl_exp_msg_types { IPCTNL_MSG_EXP_NEW, IPCTNL_MSG_EXP_GET, IPCTNL_MSG_EXP_DELETE, + IPCTNL_MSG_EXP_GET_STATS_CPU, IPCTNL_MSG_EXP_MAX }; @@ -203,4 +206,39 @@ enum ctattr_secctx { }; #define CTA_SECCTX_MAX (__CTA_SECCTX_MAX - 1) +enum ctattr_stats_cpu { + CTA_STATS_UNSPEC, + CTA_STATS_SEARCHED, + CTA_STATS_FOUND, + CTA_STATS_NEW, + CTA_STATS_INVALID, + CTA_STATS_IGNORE, + CTA_STATS_DELETE, + CTA_STATS_DELETE_LIST, + CTA_STATS_INSERT, + CTA_STATS_INSERT_FAILED, + CTA_STATS_DROP, + CTA_STATS_EARLY_DROP, + CTA_STATS_ERROR, + CTA_STATS_SEARCH_RESTART, + __CTA_STATS_MAX, +}; +#define CTA_STATS_MAX (__CTA_STATS_MAX - 1) + +enum ctattr_stats_global { + CTA_STATS_GLOBAL_UNSPEC, + CTA_STATS_GLOBAL_ENTRIES, + __CTA_STATS_GLOBAL_MAX, +}; +#define CTA_STATS_GLOBAL_MAX (__CTA_STATS_GLOBAL_MAX - 1) + +enum ctattr_expect_stats { + CTA_STATS_EXP_UNSPEC, + CTA_STATS_EXP_NEW, + CTA_STATS_EXP_CREATE, + CTA_STATS_EXP_DELETE, + __CTA_STATS_EXP_MAX, +}; +#define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1) + #endif /* _IPCONNTRACK_NETLINK_H */ diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b9b8f4ac7a36..14f67a2cbcb5 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -4,7 +4,7 @@ * (C) 2001 by Jay Schulist * (C) 2002-2006 by Harald Welte * (C) 2003 by Patrick Mchardy - * (C) 2005-2011 by Pablo Neira Ayuso + * (C) 2005-2012 by Pablo Neira Ayuso * * Initial connection tracking via netlink development funded and * generally made possible by Network Robots, Inc. (www.networkrobots.com) @@ -1627,6 +1627,155 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; } +static int +ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 pid, u32 seq, + __u16 cpu, const struct ip_conntrack_stat *st) +{ + struct nlmsghdr *nlh; + struct nfgenmsg *nfmsg; + unsigned int flags = pid ? NLM_F_MULTI : 0, event; + + event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS_CPU); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); + if (nlh == NULL) + goto nlmsg_failure; + + nfmsg = nlmsg_data(nlh); + nfmsg->nfgen_family = AF_UNSPEC; + nfmsg->version = NFNETLINK_V0; + nfmsg->res_id = htons(cpu); + + if (nla_put_be32(skb, CTA_STATS_SEARCHED, htonl(st->searched)) || + nla_put_be32(skb, CTA_STATS_FOUND, htonl(st->found)) || + nla_put_be32(skb, CTA_STATS_NEW, htonl(st->new)) || + nla_put_be32(skb, CTA_STATS_INVALID, htonl(st->invalid)) || + nla_put_be32(skb, CTA_STATS_IGNORE, htonl(st->ignore)) || + nla_put_be32(skb, CTA_STATS_DELETE, htonl(st->delete)) || + nla_put_be32(skb, CTA_STATS_DELETE_LIST, htonl(st->delete_list)) || + nla_put_be32(skb, CTA_STATS_INSERT, htonl(st->insert)) || + nla_put_be32(skb, CTA_STATS_INSERT_FAILED, + htonl(st->insert_failed)) || + nla_put_be32(skb, CTA_STATS_DROP, htonl(st->drop)) || + nla_put_be32(skb, CTA_STATS_EARLY_DROP, htonl(st->early_drop)) || + nla_put_be32(skb, CTA_STATS_ERROR, htonl(st->error)) || + nla_put_be32(skb, CTA_STATS_SEARCH_RESTART, + htonl(st->search_restart))) + goto nla_put_failure; + + nlmsg_end(skb, nlh); + return skb->len; + +nla_put_failure: +nlmsg_failure: + nlmsg_cancel(skb, nlh); + return -1; +} + +static int +ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int cpu; + struct net *net = sock_net(skb->sk); + + if (cb->args[0] == nr_cpu_ids) + return 0; + + for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) { + const struct ip_conntrack_stat *st; + + if (!cpu_possible(cpu)) + continue; + + st = per_cpu_ptr(net->ct.stat, cpu); + if (ctnetlink_ct_stat_cpu_fill_info(skb, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, + cpu, st) < 0) + break; + } + cb->args[0] = cpu; + + return skb->len; +} + +static int +ctnetlink_stat_ct_cpu(struct sock *ctnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const cda[]) +{ + if (nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { + .dump = ctnetlink_ct_stat_cpu_dump, + }; + return netlink_dump_start(ctnl, skb, nlh, &c); + } + + return 0; +} + +static int +ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type, + struct net *net) +{ + struct nlmsghdr *nlh; + struct nfgenmsg *nfmsg; + unsigned int flags = pid ? NLM_F_MULTI : 0, event; + unsigned int nr_conntracks = atomic_read(&net->ct.count); + + event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); + if (nlh == NULL) + goto nlmsg_failure; + + nfmsg = nlmsg_data(nlh); + nfmsg->nfgen_family = AF_UNSPEC; + nfmsg->version = NFNETLINK_V0; + nfmsg->res_id = 0; + + if (nla_put_be32(skb, CTA_STATS_GLOBAL_ENTRIES, htonl(nr_conntracks))) + goto nla_put_failure; + + nlmsg_end(skb, nlh); + return skb->len; + +nla_put_failure: +nlmsg_failure: + nlmsg_cancel(skb, nlh); + return -1; +} + +static int +ctnetlink_stat_ct(struct sock *ctnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const cda[]) +{ + struct sk_buff *skb2; + int err; + + skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (skb2 == NULL) + return -ENOMEM; + + err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).pid, + nlh->nlmsg_seq, + NFNL_MSG_TYPE(nlh->nlmsg_type), + sock_net(skb->sk)); + if (err <= 0) + goto free; + + err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); + if (err < 0) + goto out; + + return 0; + +free: + kfree_skb(skb2); +out: + /* this avoids a loop in nfnetlink. */ + return err == -EAGAIN ? -ENOBUFS : err; +} + #ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT static size_t ctnetlink_nfqueue_build_size(const struct nf_conn *ct) @@ -2440,6 +2589,79 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, return err; } +static int +ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int cpu, + const struct ip_conntrack_stat *st) +{ + struct nlmsghdr *nlh; + struct nfgenmsg *nfmsg; + unsigned int flags = pid ? NLM_F_MULTI : 0, event; + + event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_EXP_GET_STATS_CPU); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); + if (nlh == NULL) + goto nlmsg_failure; + + nfmsg = nlmsg_data(nlh); + nfmsg->nfgen_family = AF_UNSPEC; + nfmsg->version = NFNETLINK_V0; + nfmsg->res_id = htons(cpu); + + if (nla_put_be32(skb, CTA_STATS_EXP_NEW, htonl(st->expect_new)) || + nla_put_be32(skb, CTA_STATS_EXP_CREATE, htonl(st->expect_create)) || + nla_put_be32(skb, CTA_STATS_EXP_DELETE, htonl(st->expect_delete))) + goto nla_put_failure; + + nlmsg_end(skb, nlh); + return skb->len; + +nla_put_failure: +nlmsg_failure: + nlmsg_cancel(skb, nlh); + return -1; +} + +static int +ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int cpu; + struct net *net = sock_net(skb->sk); + + if (cb->args[0] == nr_cpu_ids) + return 0; + + for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) { + const struct ip_conntrack_stat *st; + + if (!cpu_possible(cpu)) + continue; + + st = per_cpu_ptr(net->ct.stat, cpu); + if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, + cpu, st) < 0) + break; + } + cb->args[0] = cpu; + + return skb->len; +} + +static int +ctnetlink_stat_exp_cpu(struct sock *ctnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const cda[]) +{ + if (nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { + .dump = ctnetlink_exp_stat_cpu_dump, + }; + return netlink_dump_start(ctnl, skb, nlh, &c); + } + + return 0; +} + #ifdef CONFIG_NF_CONNTRACK_EVENTS static struct nf_ct_event_notifier ctnl_notifier = { .fcn = ctnetlink_conntrack_event, @@ -2463,6 +2685,8 @@ static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, .attr_count = CTA_MAX, .policy = ct_nla_policy }, + [IPCTNL_MSG_CT_GET_STATS_CPU] = { .call = ctnetlink_stat_ct_cpu }, + [IPCTNL_MSG_CT_GET_STATS] = { .call = ctnetlink_stat_ct }, }; static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { @@ -2475,6 +2699,7 @@ static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, .attr_count = CTA_EXPECT_MAX, .policy = exp_nla_policy }, + [IPCTNL_MSG_EXP_GET_STATS_CPU] = { .call = ctnetlink_stat_exp_cpu }, }; static const struct nfnetlink_subsystem ctnl_subsys = { -- GitLab From 954bd6d1c9f6a545a594517b1a4aa9262b613f14 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 27 Jun 2012 12:02:07 +0100 Subject: [PATCH 3044/6849] lm8333: Fix check ordering Fix harmless reference off end of array Reported-by: Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?43861 Signed-off-by: Alan Cox Signed-off-by: Jiri Kosina --- drivers/input/keyboard/lm8333.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c index ca168a6679de..081fd9effa8c 100644 --- a/drivers/input/keyboard/lm8333.c +++ b/drivers/input/keyboard/lm8333.c @@ -91,7 +91,7 @@ static void lm8333_key_handler(struct lm8333 *lm8333) return; } - for (i = 0; keys[i] && i < LM8333_FIFO_TRANSFER_SIZE; i++) { + for (i = 0; i < LM8333_FIFO_TRANSFER_SIZE && keys[i]; i++) { pressed = keys[i] & 0x80; code = keys[i] & 0x7f; -- GitLab From dfb89c56add259b72a9c68d6b2846c1cd8c4e4b6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Jun 2012 09:23:48 +0200 Subject: [PATCH 3045/6849] cfg80211: don't allow WoWLAN support without CONFIG_PM When CONFIG_PM is disabled, no device can possibly support WoWLAN since it can't go to sleep to start with. Due to this, mac80211 had even rejected the hardware registration. By making all the code and data for WoWLAN depend on CONFIG_PM we can promote this runtime error to a compile-time error. Add #ifdef around all WoWLAN code to remove it in systems that don't need it as they never suspend. Cc: Kalle Valo Acked-by: Luciano Coelho Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 ++ drivers/net/wireless/ti/wlcore/main.c | 2 ++ include/net/cfg80211.h | 2 ++ net/mac80211/main.c | 7 +++---- net/wireless/core.c | 4 ++++ net/wireless/nl80211.c | 6 ++++++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f27e9732951d..b8fce0d4d72e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -3487,6 +3487,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->cipher_suites = cipher_suites; wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); +#ifdef CONFIG_PM wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_GTK_REKEY_FAILURE | @@ -3496,6 +3497,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; wiphy->wowlan.pattern_min_len = 1; wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; +#endif wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 1156e3f578c1..747a997bc608 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5321,6 +5321,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) goto out_free_hw; } +#ifdef CONFIG_PM ret = enable_irq_wake(wl->irq); if (!ret) { wl->irq_wake_enabled = true; @@ -5334,6 +5335,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) WL1271_RX_FILTER_MAX_PATTERN_SIZE; } } +#endif disable_irq(wl->irq); ret = wl12xx_get_hw_info(wl); diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 061c01957e54..7d3cd3ce9a26 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2153,7 +2153,9 @@ struct wiphy { char fw_version[ETHTOOL_BUSINFO_LEN]; u32 hw_version; +#ifdef CONFIG_PM struct wiphy_wowlan_support wowlan; +#endif u16 max_remain_on_channel_duration; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0b040fb73673..aded0018f6f3 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -706,12 +706,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.offchannel_tx_hw_queue >= local->hw.queues)) return -EINVAL; - if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) #ifdef CONFIG_PM - && (!local->ops->suspend || !local->ops->resume) -#endif - ) + if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) && + (!local->ops->suspend || !local->ops->resume)) return -EINVAL; +#endif if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) return -EINVAL; diff --git a/net/wireless/core.c b/net/wireless/core.c index 907f62c80e28..ddd32afa5f0a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -421,9 +421,11 @@ int wiphy_register(struct wiphy *wiphy) int i; u16 ifmodes = wiphy->interface_modes; +#ifdef CONFIG_PM if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) return -EINVAL; +#endif if (WARN_ON(wiphy->ap_sme_capa && !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) @@ -500,12 +502,14 @@ int wiphy_register(struct wiphy *wiphy) return -EINVAL; } +#ifdef CONFIG_PM if (rdev->wiphy.wowlan.n_patterns) { if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len || rdev->wiphy.wowlan.pattern_min_len > rdev->wiphy.wowlan.pattern_max_len)) return -EINVAL; } +#endif /* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 234ff3bbd104..067c9fe02a7f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1112,6 +1112,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_ifs); } +#ifdef CONFIG_PM if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) { struct nlattr *nl_wowlan; @@ -1152,6 +1153,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_wowlan); } +#endif if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, dev->wiphy.software_iftypes)) @@ -6276,6 +6278,7 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) return cfg80211_leave_mesh(rdev, dev); } +#ifdef CONFIG_PM static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -6504,6 +6507,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) kfree(new_triggers.patterns); return err; } +#endif static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) { @@ -7158,6 +7162,7 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, +#ifdef CONFIG_PM { .cmd = NL80211_CMD_GET_WOWLAN, .doit = nl80211_get_wowlan, @@ -7174,6 +7179,7 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_WIPHY | NL80211_FLAG_NEED_RTNL, }, +#endif { .cmd = NL80211_CMD_SET_REKEY_OFFLOAD, .doit = nl80211_set_rekey_data, -- GitLab From da3789628f88684d3f0fb4e6a6bc086c395ac3cb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 27 Jun 2012 13:08:42 -0300 Subject: [PATCH 3046/6849] perf tools: Stop using a global trace events description list The pevent thing is per perf.data file, so I made it stop being static and become a perf_session member, so tools processing perf.data files use perf_session and _there_ we read the trace events description into session->pevent and then change everywhere to stop using that single global pevent variable and use the per session one. Note that it _doesn't_ fall backs to trace__event_id, as we're not interested at all in what is present in the /sys/kernel/debug/tracing/events in the workstation doing the analysis, just in what is in the perf.data file. This patch also introduces perf_session__set_tracepoints_handlers that is the perf perf.data/session way to associate handlers to tracepoint events by resolving their IDs using the events descriptions stored in a perf.data file. Make 'perf sched' use it. Reported-by: Dmitry Antipov Tested-by: Dmitry Antipov Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: linaro-dev@lists.linaro.org Cc: patches@linaro.org Link: http://lkml.kernel.org/r/20120625232016.GA28525@infradead.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 37 ++++--- tools/perf/builtin-lock.c | 4 +- tools/perf/builtin-sched.c | 36 ++++--- tools/perf/builtin-script.c | 66 ++++++++----- tools/perf/util/evlist.c | 4 +- tools/perf/util/evlist.h | 3 + tools/perf/util/header.c | 31 +++--- .../util/scripting-engines/trace-event-perl.c | 28 +++--- .../scripting-engines/trace-event-python.c | 21 ++-- tools/perf/util/session.c | 56 +++++++++++ tools/perf/util/session.h | 10 ++ tools/perf/util/trace-event-parse.c | 58 +++++------ tools/perf/util/trace-event-read.c | 97 ++++++++++--------- tools/perf/util/trace-event-scripting.c | 7 +- tools/perf/util/trace-event.h | 38 ++++---- 15 files changed, 314 insertions(+), 182 deletions(-) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 547af48deb4f..ce35015f2dc6 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -57,6 +57,11 @@ static unsigned long nr_allocs, nr_cross_allocs; #define PATH_SYS_NODE "/sys/devices/system/node" +struct perf_kmem { + struct perf_tool tool; + struct perf_session *session; +}; + static void init_cpunode_map(void) { FILE *fp; @@ -278,14 +283,16 @@ static void process_free_event(void *data, s_alloc->alloc_cpu = -1; } -static void process_raw_event(union perf_event *raw_event __used, void *data, +static void process_raw_event(struct perf_tool *tool, + union perf_event *raw_event __used, void *data, int cpu, u64 timestamp, struct thread *thread) { + struct perf_kmem *kmem = container_of(tool, struct perf_kmem, tool); struct event_format *event; int type; - type = trace_parse_common_type(data); - event = trace_find_event(type); + type = trace_parse_common_type(kmem->session->pevent, data); + event = pevent_find_event(kmem->session->pevent, type); if (!strcmp(event->name, "kmalloc") || !strcmp(event->name, "kmem_cache_alloc")) { @@ -306,7 +313,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data, } } -static int process_sample_event(struct perf_tool *tool __used, +static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel __used, @@ -322,16 +329,18 @@ static int process_sample_event(struct perf_tool *tool __used, dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - process_raw_event(event, sample->raw_data, sample->cpu, + process_raw_event(tool, event, sample->raw_data, sample->cpu, sample->time, thread); return 0; } -static struct perf_tool perf_kmem = { - .sample = process_sample_event, - .comm = perf_event__process_comm, - .ordered_samples = true, +static struct perf_kmem perf_kmem = { + .tool = { + .sample = process_sample_event, + .comm = perf_event__process_comm, + .ordered_samples = true, + }, }; static double fragmentation(unsigned long n_req, unsigned long n_alloc) @@ -486,11 +495,15 @@ static void sort_result(void) static int __cmd_kmem(void) { int err = -EINVAL; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - 0, false, &perf_kmem); + struct perf_session *session; + + session = perf_session__new(input_name, O_RDONLY, 0, false, + &perf_kmem.tool); if (session == NULL) return -ENOMEM; + perf_kmem.session = session; + if (perf_session__create_kernel_maps(session) < 0) goto out_delete; @@ -498,7 +511,7 @@ static int __cmd_kmem(void) goto out_delete; setup_pager(); - err = perf_session__process_events(session, &perf_kmem); + err = perf_session__process_events(session, &perf_kmem.tool); if (err != 0) goto out_delete; sort_result(); diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index fd53319de20d..b3c428548868 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -724,8 +724,8 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread) struct event_format *event; int type; - type = trace_parse_common_type(data); - event = trace_find_event(type); + type = trace_parse_common_type(session->pevent, data); + event = pevent_find_event(session->pevent, type); if (!strcmp(event->name, "lock_acquire")) process_lock_acquire_event(data, event, cpu, timestamp, thread); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 9fe77b185338..7a9ad2b1ee76 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -43,6 +43,11 @@ static u64 sleep_measurement_overhead; static unsigned long nr_tasks; +struct perf_sched { + struct perf_tool tool; + struct perf_session *session; +}; + struct sched_atom; struct task_desc { @@ -1597,6 +1602,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, struct perf_evsel *evsel, struct machine *machine) { + struct perf_sched *sched = container_of(tool, struct perf_sched, tool); + struct pevent *pevent = sched->session->pevent; struct thread *thread = machine__findnew_thread(machine, sample->pid); if (thread == NULL) { @@ -1612,7 +1619,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, tracepoint_handler f = evsel->handler.func; if (evsel->handler.data == NULL) - evsel->handler.data = trace_find_event(evsel->attr.config); + evsel->handler.data = pevent_find_event(pevent, + evsel->attr.config); f(tool, evsel->handler.data, sample, machine, thread); } @@ -1620,12 +1628,14 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, return 0; } -static struct perf_tool perf_sched = { - .sample = perf_sched__process_tracepoint_sample, - .comm = perf_event__process_comm, - .lost = perf_event__process_lost, - .fork = perf_event__process_task, - .ordered_samples = true, +static struct perf_sched perf_sched = { + .tool = { + .sample = perf_sched__process_tracepoint_sample, + .comm = perf_event__process_comm, + .lost = perf_event__process_lost, + .fork = perf_event__process_task, + .ordered_samples = true, + }, }; static void read_events(bool destroy, struct perf_session **psession) @@ -1640,16 +1650,20 @@ static void read_events(bool destroy, struct perf_session **psession) { "sched:sched_process_exit", process_sched_exit_event, }, { "sched:sched_migrate_task", process_sched_migrate_task_event, }, }; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - 0, false, &perf_sched); + struct perf_session *session; + + session = perf_session__new(input_name, O_RDONLY, 0, false, + &perf_sched.tool); if (session == NULL) die("No Memory"); - err = perf_evlist__set_tracepoints_handlers_array(session->evlist, handlers); + perf_sched.session = session; + + err = perf_session__set_tracepoints_handlers(session, handlers); assert(err == 0); if (perf_session__has_traces(session, "record -R")) { - err = perf_session__process_events(session, &perf_sched); + err = perf_session__process_events(session, &perf_sched.tool); if (err) die("Failed to process events, error %d", err); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8fecd3b8130a..1e60ab70b2b1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -28,6 +28,11 @@ static bool system_wide; static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); +struct perf_script { + struct perf_tool tool; + struct perf_session *session; +}; + enum perf_output_field { PERF_OUTPUT_COMM = 1U << 0, PERF_OUTPUT_TID = 1U << 1, @@ -257,7 +262,8 @@ static int perf_session__check_output_opt(struct perf_session *session) return 0; } -static void print_sample_start(struct perf_sample *sample, +static void print_sample_start(struct pevent *pevent, + struct perf_sample *sample, struct thread *thread, struct perf_evsel *evsel) { @@ -302,8 +308,14 @@ static void print_sample_start(struct perf_sample *sample, if (PRINT_FIELD(EVNAME)) { if (attr->type == PERF_TYPE_TRACEPOINT) { - type = trace_parse_common_type(sample->raw_data); - event = trace_find_event(type); + /* + * XXX Do we really need this here? + * perf_evlist__set_tracepoint_names should have done + * this already + */ + type = trace_parse_common_type(pevent, + sample->raw_data); + event = pevent_find_event(pevent, type); if (event) evname = event->name; } else @@ -404,6 +416,7 @@ static void print_sample_bts(union perf_event *event, } static void process_event(union perf_event *event __unused, + struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, @@ -414,7 +427,7 @@ static void process_event(union perf_event *event __unused, if (output[attr->type].fields == 0) return; - print_sample_start(sample, thread, evsel); + print_sample_start(pevent, sample, thread, evsel); if (is_bts_event(attr)) { print_sample_bts(event, sample, evsel, machine, thread); @@ -422,7 +435,7 @@ static void process_event(union perf_event *event __unused, } if (PRINT_FIELD(TRACE)) - print_trace_event(sample->cpu, sample->raw_data, + print_trace_event(pevent, sample->cpu, sample->raw_data, sample->raw_size); if (PRINT_FIELD(ADDR)) @@ -453,7 +466,8 @@ static int default_stop_script(void) return 0; } -static int default_generate_script(const char *outfile __unused) +static int default_generate_script(struct pevent *pevent __unused, + const char *outfile __unused) { return 0; } @@ -491,6 +505,7 @@ static int process_sample_event(struct perf_tool *tool __used, struct machine *machine) { struct addr_location al; + struct perf_script *scr = container_of(tool, struct perf_script, tool); struct thread *thread = machine__findnew_thread(machine, event->ip.tid); if (thread == NULL) { @@ -522,24 +537,27 @@ static int process_sample_event(struct perf_tool *tool __used, if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) return 0; - scripting_ops->process_event(event, sample, evsel, machine, thread); + scripting_ops->process_event(event, scr->session->pevent, + sample, evsel, machine, thread); evsel->hists.stats.total_period += sample->period; return 0; } -static struct perf_tool perf_script = { - .sample = process_sample_event, - .mmap = perf_event__process_mmap, - .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, - .attr = perf_event__process_attr, - .event_type = perf_event__process_event_type, - .tracing_data = perf_event__process_tracing_data, - .build_id = perf_event__process_build_id, - .ordered_samples = true, - .ordering_requires_timestamps = true, +static struct perf_script perf_script = { + .tool = { + .sample = process_sample_event, + .mmap = perf_event__process_mmap, + .comm = perf_event__process_comm, + .exit = perf_event__process_task, + .fork = perf_event__process_task, + .attr = perf_event__process_attr, + .event_type = perf_event__process_event_type, + .tracing_data = perf_event__process_tracing_data, + .build_id = perf_event__process_build_id, + .ordered_samples = true, + .ordering_requires_timestamps = true, + }, }; extern volatile int session_done; @@ -555,7 +573,7 @@ static int __cmd_script(struct perf_session *session) signal(SIGINT, sig_handler); - ret = perf_session__process_events(session, &perf_script); + ret = perf_session__process_events(session, &perf_script.tool); if (debug_mode) pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); @@ -1337,10 +1355,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) if (!script_name) setup_pager(); - session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_script); + session = perf_session__new(input_name, O_RDONLY, 0, false, + &perf_script.tool); if (session == NULL) return -ENOMEM; + perf_script.session = session; + if (cpu_list) { if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) return -1; @@ -1386,7 +1407,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) return -1; } - err = scripting_ops->generate_script("perf-script"); + err = scripting_ops->generate_script(session->pevent, + "perf-script"); goto out; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 7400fb3fc50c..f74e9560350e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -224,8 +224,8 @@ out_free_attrs: return err; } -static struct perf_evsel * - perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) +struct perf_evsel * +perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) { struct perf_evsel *evsel; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 989bee9624c2..40d4d3cdced0 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -73,6 +73,9 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, #define perf_evlist__set_tracepoints_handlers_array(evlist, array) \ perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array)) +struct perf_evsel * +perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id); + void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, int cpu, int thread, u64 id); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a5e2015319ee..5a47aba46759 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1474,15 +1474,15 @@ out: static int process_tracing_data(struct perf_file_section *section __unused, struct perf_header *ph __unused, - int feat __unused, int fd) + int feat __unused, int fd, void *data) { - trace_report(fd, false); + trace_report(fd, data, false); return 0; } static int process_build_id(struct perf_file_section *section, struct perf_header *ph, - int feat __unused, int fd) + int feat __unused, int fd, void *data __used) { if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) pr_debug("Failed to read buildids, continuing...\n"); @@ -1493,7 +1493,7 @@ struct feature_ops { int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); void (*print)(struct perf_header *h, int fd, FILE *fp); int (*process)(struct perf_file_section *section, - struct perf_header *h, int feat, int fd); + struct perf_header *h, int feat, int fd, void *data); const char *name; bool full_only; }; @@ -1988,7 +1988,7 @@ int perf_file_header__read(struct perf_file_header *header, static int perf_file_section__process(struct perf_file_section *section, struct perf_header *ph, - int feat, int fd, void *data __used) + int feat, int fd, void *data) { if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { pr_debug("Failed to lseek to %" PRIu64 " offset for feature " @@ -2004,7 +2004,7 @@ static int perf_file_section__process(struct perf_file_section *section, if (!feat_ops[feat].process) return 0; - return feat_ops[feat].process(section, ph, feat, fd); + return feat_ops[feat].process(section, ph, feat, fd, data); } static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, @@ -2093,9 +2093,11 @@ static int read_attr(int fd, struct perf_header *ph, return ret <= 0 ? -1 : 0; } -static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) +static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, + struct pevent *pevent) { - struct event_format *event = trace_find_event(evsel->attr.config); + struct event_format *event = pevent_find_event(pevent, + evsel->attr.config); char bf[128]; if (event == NULL) @@ -2109,13 +2111,14 @@ static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) return 0; } -static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) +static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist, + struct pevent *pevent) { struct perf_evsel *pos; list_for_each_entry(pos, &evlist->entries, node) { if (pos->attr.type == PERF_TYPE_TRACEPOINT && - perf_evsel__set_tracepoint_name(pos)) + perf_evsel__set_tracepoint_name(pos, pevent)) return -1; } @@ -2198,12 +2201,12 @@ int perf_session__read_header(struct perf_session *session, int fd) event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); } - perf_header__process_sections(header, fd, NULL, + perf_header__process_sections(header, fd, &session->pevent, perf_file_section__process); lseek(fd, header->data_offset, SEEK_SET); - if (perf_evlist__set_tracepoint_names(session->evlist)) + if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent)) goto out_delete_evlist; header->frozen = 1; @@ -2419,8 +2422,8 @@ int perf_event__process_tracing_data(union perf_event *event, lseek(session->fd, offset + sizeof(struct tracing_data_event), SEEK_SET); - size_read = trace_report(session->fd, session->repipe); - + size_read = trace_report(session->fd, &session->pevent, + session->repipe); padding = ALIGN(size_read, sizeof(u64)) - size_read; if (read(session->fd, buf, padding) < 0) diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 4c1b3d72a1d2..b3620fe12763 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -233,7 +233,8 @@ static void define_event_symbols(struct event_format *event, define_event_symbols(event, ev_name, args->next); } -static inline struct event_format *find_cache_event(int type) +static inline +struct event_format *find_cache_event(struct pevent *pevent, int type) { static char ev_name[256]; struct event_format *event; @@ -241,7 +242,7 @@ static inline struct event_format *find_cache_event(int type) if (events[type]) return events[type]; - events[type] = event = trace_find_event(type); + events[type] = event = pevent_find_event(pevent, type); if (!event) return NULL; @@ -252,7 +253,8 @@ static inline struct event_format *find_cache_event(int type) return event; } -static void perl_process_tracepoint(union perf_event *pevent __unused, +static void perl_process_tracepoint(union perf_event *perf_event __unused, + struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __unused, @@ -275,13 +277,13 @@ static void perl_process_tracepoint(union perf_event *pevent __unused, if (evsel->attr.type != PERF_TYPE_TRACEPOINT) return; - type = trace_parse_common_type(data); + type = trace_parse_common_type(pevent, data); - event = find_cache_event(type); + event = find_cache_event(pevent, type); if (!event) die("ug! no event found for type %d", type); - pid = trace_parse_common_pid(data); + pid = trace_parse_common_pid(pevent, data); sprintf(handler, "%s::%s", event->system, event->name); @@ -314,7 +316,8 @@ static void perl_process_tracepoint(union perf_event *pevent __unused, offset = field->offset; XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); } else { /* FIELD_IS_NUMERIC */ - val = read_size(data + field->offset, field->size); + val = read_size(pevent, data + field->offset, + field->size); if (field->flags & FIELD_IS_SIGNED) { XPUSHs(sv_2mortal(newSViv(val))); } else { @@ -368,14 +371,15 @@ static void perl_process_event_generic(union perf_event *pevent __unused, LEAVE; } -static void perl_process_event(union perf_event *pevent, +static void perl_process_event(union perf_event *event, + struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, struct thread *thread) { - perl_process_tracepoint(pevent, sample, evsel, machine, thread); - perl_process_event_generic(pevent, sample, evsel, machine, thread); + perl_process_tracepoint(event, pevent, sample, evsel, machine, thread); + perl_process_event_generic(event, sample, evsel, machine, thread); } static void run_start_sub(void) @@ -448,7 +452,7 @@ static int perl_stop_script(void) return 0; } -static int perl_generate_script(const char *outfile) +static int perl_generate_script(struct pevent *pevent, const char *outfile) { struct event_format *event = NULL; struct format_field *f; @@ -495,7 +499,7 @@ static int perl_generate_script(const char *outfile) fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); - while ((event = trace_find_next_event(event))) { + while ((event = trace_find_next_event(pevent, event))) { fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); fprintf(ofp, "\tmy ("); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index acb9795286c4..a8ca2f8179a9 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -190,7 +190,8 @@ static void define_event_symbols(struct event_format *event, define_event_symbols(event, ev_name, args->next); } -static inline struct event_format *find_cache_event(int type) +static inline +struct event_format *find_cache_event(struct pevent *pevent, int type) { static char ev_name[256]; struct event_format *event; @@ -198,7 +199,7 @@ static inline struct event_format *find_cache_event(int type) if (events[type]) return events[type]; - events[type] = event = trace_find_event(type); + events[type] = event = pevent_find_event(pevent, type); if (!event) return NULL; @@ -209,7 +210,8 @@ static inline struct event_format *find_cache_event(int type) return event; } -static void python_process_event(union perf_event *pevent __unused, +static void python_process_event(union perf_event *perf_event __unused, + struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel __unused, struct machine *machine __unused, @@ -233,13 +235,13 @@ static void python_process_event(union perf_event *pevent __unused, if (!t) Py_FatalError("couldn't create Python tuple"); - type = trace_parse_common_type(data); + type = trace_parse_common_type(pevent, data); - event = find_cache_event(type); + event = find_cache_event(pevent, type); if (!event) die("ug! no event found for type %d", type); - pid = trace_parse_common_pid(data); + pid = trace_parse_common_pid(pevent, data); sprintf(handler_name, "%s__%s", event->system, event->name); @@ -284,7 +286,8 @@ static void python_process_event(union perf_event *pevent __unused, offset = field->offset; obj = PyString_FromString((char *)data + offset); } else { /* FIELD_IS_NUMERIC */ - val = read_size(data + field->offset, field->size); + val = read_size(pevent, data + field->offset, + field->size); if (field->flags & FIELD_IS_SIGNED) { if ((long long)val >= LONG_MIN && (long long)val <= LONG_MAX) @@ -438,7 +441,7 @@ out: return err; } -static int python_generate_script(const char *outfile) +static int python_generate_script(struct pevent *pevent, const char *outfile) { struct event_format *event = NULL; struct format_field *f; @@ -487,7 +490,7 @@ static int python_generate_script(const char *outfile) fprintf(ofp, "def trace_end():\n"); fprintf(ofp, "\tprint \"in trace_end\"\n\n"); - while ((event = trace_find_next_event(event))) { + while ((event = trace_find_next_event(pevent, event))) { fprintf(ofp, "def %s__%s(", event->system, event->name); fprintf(ofp, "event_name, "); fprintf(ofp, "context, "); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 6b305fbcc986..f5baff1495e6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -14,6 +14,7 @@ #include "sort.h" #include "util.h" #include "cpumap.h" +#include "event-parse.h" static int perf_session__open(struct perf_session *self, bool force) { @@ -1610,3 +1611,58 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp, perf_header__fprintf_info(session, fp, full); fprintf(fp, "# ========\n#\n"); } + + +int __perf_session__set_tracepoints_handlers(struct perf_session *session, + const struct perf_evsel_str_handler *assocs, + size_t nr_assocs) +{ + struct perf_evlist *evlist = session->evlist; + struct event_format *format; + struct perf_evsel *evsel; + char *tracepoint, *name; + size_t i; + int err; + + for (i = 0; i < nr_assocs; i++) { + err = -ENOMEM; + tracepoint = strdup(assocs[i].name); + if (tracepoint == NULL) + goto out; + + err = -ENOENT; + name = strchr(tracepoint, ':'); + if (name == NULL) + goto out_free; + + *name++ = '\0'; + format = pevent_find_event_by_name(session->pevent, + tracepoint, name); + if (format == NULL) { + /* + * Adding a handler for an event not in the session, + * just ignore it. + */ + goto next; + } + + evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id); + if (evsel == NULL) + goto next; + + err = -EEXIST; + if (evsel->handler.func != NULL) + goto out_free; + evsel->handler.func = assocs[i].handler; +next: + free(tracepoint); + } + + err = 0; +out: + return err; + +out_free: + free(tracepoint); + goto out; +} diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index c71a1a7b05ed..7c435bde6eb0 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -33,6 +33,7 @@ struct perf_session { struct machine host_machine; struct rb_root machines; struct perf_evlist *evlist; + struct pevent *pevent; /* * FIXME: Need to split this up further, we need global * stats + per event stats. 'perf diff' also needs @@ -158,4 +159,13 @@ int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); + +struct perf_evsel_str_handler; + +int __perf_session__set_tracepoints_handlers(struct perf_session *session, + const struct perf_evsel_str_handler *assocs, + size_t nr_assocs); + +#define perf_session__set_tracepoints_handlers(session, array) \ + __perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array)) #endif /* __PERF_SESSION_H */ diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index df2fddbf0cd2..a51bd86f4d09 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -32,29 +32,25 @@ int header_page_size_size; int header_page_ts_size; int header_page_data_offset; -struct pevent *perf_pevent; -static struct pevent *pevent; - bool latency_format; -int read_trace_init(int file_bigendian, int host_bigendian) +struct pevent *read_trace_init(int file_bigendian, int host_bigendian) { - if (pevent) - return 0; - - perf_pevent = pevent_alloc(); - pevent = perf_pevent; + struct pevent *pevent = pevent_alloc(); - pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); - pevent_set_file_bigendian(pevent, file_bigendian); - pevent_set_host_bigendian(pevent, host_bigendian); + if (pevent != NULL) { + pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); + pevent_set_file_bigendian(pevent, file_bigendian); + pevent_set_host_bigendian(pevent, host_bigendian); + } - return 0; + return pevent; } static int get_common_field(struct scripting_context *context, int *offset, int *size, const char *type) { + struct pevent *pevent = context->pevent; struct event_format *event; struct format_field *field; @@ -150,7 +146,7 @@ void *raw_field_ptr(struct event_format *event, const char *name, void *data) return data + field->offset; } -int trace_parse_common_type(void *data) +int trace_parse_common_type(struct pevent *pevent, void *data) { struct pevent_record record; @@ -158,7 +154,7 @@ int trace_parse_common_type(void *data) return pevent_data_type(pevent, &record); } -int trace_parse_common_pid(void *data) +int trace_parse_common_pid(struct pevent *pevent, void *data) { struct pevent_record record; @@ -166,27 +162,21 @@ int trace_parse_common_pid(void *data) return pevent_data_pid(pevent, &record); } -unsigned long long read_size(void *ptr, int size) +unsigned long long read_size(struct pevent *pevent, void *ptr, int size) { return pevent_read_number(pevent, ptr, size); } -struct event_format *trace_find_event(int type) -{ - return pevent_find_event(pevent, type); -} - - -void print_trace_event(int cpu, void *data, int size) +void print_trace_event(struct pevent *pevent, int cpu, void *data, int size) { struct event_format *event; struct pevent_record record; struct trace_seq s; int type; - type = trace_parse_common_type(data); + type = trace_parse_common_type(pevent, data); - event = trace_find_event(type); + event = pevent_find_event(pevent, type); if (!event) { warning("ug! no event found for type %d", type); return; @@ -203,8 +193,8 @@ void print_trace_event(int cpu, void *data, int size) printf("\n"); } -void print_event(int cpu, void *data, int size, unsigned long long nsecs, - char *comm) +void print_event(struct pevent *pevent, int cpu, void *data, int size, + unsigned long long nsecs, char *comm) { struct pevent_record record; struct trace_seq s; @@ -227,7 +217,8 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, printf("\n"); } -void parse_proc_kallsyms(char *file, unsigned int size __unused) +void parse_proc_kallsyms(struct pevent *pevent, + char *file, unsigned int size __unused) { unsigned long long addr; char *func; @@ -258,7 +249,8 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused) } } -void parse_ftrace_printk(char *file, unsigned int size __unused) +void parse_ftrace_printk(struct pevent *pevent, + char *file, unsigned int size __unused) { unsigned long long addr; char *printk; @@ -282,17 +274,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) } } -int parse_ftrace_file(char *buf, unsigned long size) +int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size) { return pevent_parse_event(pevent, buf, size, "ftrace"); } -int parse_event_file(char *buf, unsigned long size, char *sys) +int parse_event_file(struct pevent *pevent, + char *buf, unsigned long size, char *sys) { return pevent_parse_event(pevent, buf, size, sys); } -struct event_format *trace_find_next_event(struct event_format *event) +struct event_format *trace_find_next_event(struct pevent *pevent, + struct event_format *event) { static int idx; diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index f097e0dd6c5c..719ed74a8565 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -114,20 +114,20 @@ static void skip(int size) }; } -static unsigned int read4(void) +static unsigned int read4(struct pevent *pevent) { unsigned int data; read_or_die(&data, 4); - return __data2host4(perf_pevent, data); + return __data2host4(pevent, data); } -static unsigned long long read8(void) +static unsigned long long read8(struct pevent *pevent) { unsigned long long data; read_or_die(&data, 8); - return __data2host8(perf_pevent, data); + return __data2host8(pevent, data); } static char *read_string(void) @@ -168,12 +168,12 @@ static char *read_string(void) return str; } -static void read_proc_kallsyms(void) +static void read_proc_kallsyms(struct pevent *pevent) { unsigned int size; char *buf; - size = read4(); + size = read4(pevent); if (!size) return; @@ -181,29 +181,29 @@ static void read_proc_kallsyms(void) read_or_die(buf, size); buf[size] = '\0'; - parse_proc_kallsyms(buf, size); + parse_proc_kallsyms(pevent, buf, size); free(buf); } -static void read_ftrace_printk(void) +static void read_ftrace_printk(struct pevent *pevent) { unsigned int size; char *buf; - size = read4(); + size = read4(pevent); if (!size) return; buf = malloc_or_die(size); read_or_die(buf, size); - parse_ftrace_printk(buf, size); + parse_ftrace_printk(pevent, buf, size); free(buf); } -static void read_header_files(void) +static void read_header_files(struct pevent *pevent) { unsigned long long size; char *header_event; @@ -214,7 +214,7 @@ static void read_header_files(void) if (memcmp(buf, "header_page", 12) != 0) die("did not read header page"); - size = read8(); + size = read8(pevent); skip(size); /* @@ -227,47 +227,48 @@ static void read_header_files(void) if (memcmp(buf, "header_event", 13) != 0) die("did not read header event"); - size = read8(); + size = read8(pevent); header_event = malloc_or_die(size); read_or_die(header_event, size); free(header_event); } -static void read_ftrace_file(unsigned long long size) +static void read_ftrace_file(struct pevent *pevent, unsigned long long size) { char *buf; buf = malloc_or_die(size); read_or_die(buf, size); - parse_ftrace_file(buf, size); + parse_ftrace_file(pevent, buf, size); free(buf); } -static void read_event_file(char *sys, unsigned long long size) +static void read_event_file(struct pevent *pevent, char *sys, + unsigned long long size) { char *buf; buf = malloc_or_die(size); read_or_die(buf, size); - parse_event_file(buf, size, sys); + parse_event_file(pevent, buf, size, sys); free(buf); } -static void read_ftrace_files(void) +static void read_ftrace_files(struct pevent *pevent) { unsigned long long size; int count; int i; - count = read4(); + count = read4(pevent); for (i = 0; i < count; i++) { - size = read8(); - read_ftrace_file(size); + size = read8(pevent); + read_ftrace_file(pevent, size); } } -static void read_event_files(void) +static void read_event_files(struct pevent *pevent) { unsigned long long size; char *sys; @@ -275,15 +276,15 @@ static void read_event_files(void) int count; int i,x; - systems = read4(); + systems = read4(pevent); for (i = 0; i < systems; i++) { sys = read_string(); - count = read4(); + count = read4(pevent); for (x=0; x < count; x++) { - size = read8(); - read_event_file(sys, size); + size = read8(pevent); + read_event_file(pevent, sys, size); } } } @@ -377,7 +378,7 @@ static int calc_index(void *ptr, int cpu) return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; } -struct pevent_record *trace_peek_data(int cpu) +struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) { struct pevent_record *data; void *page = cpu_data[cpu].page; @@ -399,15 +400,15 @@ struct pevent_record *trace_peek_data(int cpu) /* FIXME: handle header page */ if (header_page_ts_size != 8) die("expected a long long type for timestamp"); - cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr); + cpu_data[cpu].timestamp = data2host8(pevent, ptr); ptr += 8; switch (header_page_size_size) { case 4: - cpu_data[cpu].page_size = data2host4(perf_pevent, ptr); + cpu_data[cpu].page_size = data2host4(pevent, ptr); ptr += 4; break; case 8: - cpu_data[cpu].page_size = data2host8(perf_pevent, ptr); + cpu_data[cpu].page_size = data2host8(pevent, ptr); ptr += 8; break; default: @@ -421,10 +422,10 @@ read_again: if (idx >= cpu_data[cpu].page_size) { get_next_page(cpu); - return trace_peek_data(cpu); + return trace_peek_data(pevent, cpu); } - type_len_ts = data2host4(perf_pevent, ptr); + type_len_ts = data2host4(pevent, ptr); ptr += 4; type_len = type_len4host(type_len_ts); @@ -434,14 +435,14 @@ read_again: case RINGBUF_TYPE_PADDING: if (!delta) die("error, hit unexpected end of page"); - length = data2host4(perf_pevent, ptr); + length = data2host4(pevent, ptr); ptr += 4; length *= 4; ptr += length; goto read_again; case RINGBUF_TYPE_TIME_EXTEND: - extend = data2host4(perf_pevent, ptr); + extend = data2host4(pevent, ptr); ptr += 4; extend <<= TS_SHIFT; extend += delta; @@ -452,7 +453,7 @@ read_again: ptr += 12; break; case 0: - length = data2host4(perf_pevent, ptr); + length = data2host4(pevent, ptr); ptr += 4; die("here! length=%d", length); break; @@ -477,17 +478,17 @@ read_again: return data; } -struct pevent_record *trace_read_data(int cpu) +struct pevent_record *trace_read_data(struct pevent *pevent, int cpu) { struct pevent_record *data; - data = trace_peek_data(cpu); + data = trace_peek_data(pevent, cpu); cpu_data[cpu].next = NULL; return data; } -ssize_t trace_report(int fd, bool __repipe) +ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) { char buf[BUFSIZ]; char test[] = { 23, 8, 68 }; @@ -519,30 +520,32 @@ ssize_t trace_report(int fd, bool __repipe) file_bigendian = buf[0]; host_bigendian = bigendian(); - read_trace_init(file_bigendian, host_bigendian); + *ppevent = read_trace_init(file_bigendian, host_bigendian); + if (*ppevent == NULL) + die("read_trace_init failed"); read_or_die(buf, 1); long_size = buf[0]; - page_size = read4(); + page_size = read4(*ppevent); - read_header_files(); + read_header_files(*ppevent); - read_ftrace_files(); - read_event_files(); - read_proc_kallsyms(); - read_ftrace_printk(); + read_ftrace_files(*ppevent); + read_event_files(*ppevent); + read_proc_kallsyms(*ppevent); + read_ftrace_printk(*ppevent); size = calc_data_size - 1; calc_data_size = 0; repipe = false; if (show_funcs) { - pevent_print_funcs(perf_pevent); + pevent_print_funcs(*ppevent); return size; } if (show_printk) { - pevent_print_printk(perf_pevent); + pevent_print_printk(*ppevent); return size; } diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 18ae6c1831d3..474aa7a7df43 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -36,6 +36,7 @@ static int stop_script_unsupported(void) } static void process_event_unsupported(union perf_event *event __unused, + struct pevent *pevent __unused, struct perf_sample *sample __unused, struct perf_evsel *evsel __unused, struct machine *machine __unused, @@ -61,7 +62,8 @@ static int python_start_script_unsupported(const char *script __unused, return -1; } -static int python_generate_script_unsupported(const char *outfile __unused) +static int python_generate_script_unsupported(struct pevent *pevent __unused, + const char *outfile __unused) { print_python_unsupported_msg(); @@ -122,7 +124,8 @@ static int perl_start_script_unsupported(const char *script __unused, return -1; } -static int perl_generate_script_unsupported(const char *outfile __unused) +static int perl_generate_script_unsupported(struct pevent *pevent __unused, + const char *outfile __unused) { print_perl_unsupported_msg(); diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 639852ac1117..8fef1d6687b7 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -8,6 +8,7 @@ struct machine; struct perf_sample; union perf_event; +struct perf_tool; struct thread; extern int header_page_size_size; @@ -29,35 +30,36 @@ enum { int bigendian(void); -int read_trace_init(int file_bigendian, int host_bigendian); -void print_trace_event(int cpu, void *data, int size); +struct pevent *read_trace_init(int file_bigendian, int host_bigendian); +void print_trace_event(struct pevent *pevent, int cpu, void *data, int size); -void print_event(int cpu, void *data, int size, unsigned long long nsecs, - char *comm); +void print_event(struct pevent *pevent, int cpu, void *data, int size, + unsigned long long nsecs, char *comm); -int parse_ftrace_file(char *buf, unsigned long size); -int parse_event_file(char *buf, unsigned long size, char *sys); +int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size); +int parse_event_file(struct pevent *pevent, + char *buf, unsigned long size, char *sys); -struct pevent_record *trace_peek_data(int cpu); -struct event_format *trace_find_event(int type); +struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu); unsigned long long raw_field_value(struct event_format *event, const char *name, void *data); void *raw_field_ptr(struct event_format *event, const char *name, void *data); -void parse_proc_kallsyms(char *file, unsigned int size __unused); -void parse_ftrace_printk(char *file, unsigned int size __unused); +void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); +void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size); -ssize_t trace_report(int fd, bool repipe); +ssize_t trace_report(int fd, struct pevent **pevent, bool repipe); -int trace_parse_common_type(void *data); -int trace_parse_common_pid(void *data); +int trace_parse_common_type(struct pevent *pevent, void *data); +int trace_parse_common_pid(struct pevent *pevent, void *data); -struct event_format *trace_find_next_event(struct event_format *event); -unsigned long long read_size(void *ptr, int size); +struct event_format *trace_find_next_event(struct pevent *pevent, + struct event_format *event); +unsigned long long read_size(struct pevent *pevent, void *ptr, int size); unsigned long long eval_flag(const char *flag); -struct pevent_record *trace_read_data(int cpu); +struct pevent_record *trace_read_data(struct pevent *pevent, int cpu); int read_tracing_data(int fd, struct list_head *pattrs); struct tracing_data { @@ -77,11 +79,12 @@ struct scripting_ops { int (*start_script) (const char *script, int argc, const char **argv); int (*stop_script) (void); void (*process_event) (union perf_event *event, + struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, struct thread *thread); - int (*generate_script) (const char *outfile); + int (*generate_script) (struct pevent *pevent, const char *outfile); }; int script_spec_register(const char *spec, struct scripting_ops *ops); @@ -90,6 +93,7 @@ void setup_perl_scripting(void); void setup_python_scripting(void); struct scripting_context { + struct pevent *pevent; void *event_data; }; -- GitLab From fa0f61f05e401a3295b6486df67bb3f9d5f24a94 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:38 +0000 Subject: [PATCH 3047/6849] netfilter: nf_conntrack: fix nf_conntrack_l3proto_register Before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448 (netfilter: nf_conntrack: prepare namespace support for l4 protocol trackers), we register sysctl before register protocol tracker. Thus, if sysctl is registration fails, the protocol tracker will not be registered. After that commit, if sysctl registration fails, protocol registration still remains, so we leave things in intermediate state. To fix this, this patch registers sysctl before protocols. And if protocol registration fail, sysctl is unregistered. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto.c | 36 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 1ea919450fc3..9bd88aa3c74f 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net, { int ret = 0; - if (net == &init_net) - ret = nf_conntrack_l3proto_register_net(proto); + if (proto->init_net) { + ret = proto->init_net(net); + if (ret < 0) + return ret; + } + ret = nf_ct_l3proto_register_sysctl(net, proto); if (ret < 0) return ret; - if (proto->init_net) { - ret = proto->init_net(net); + if (net == &init_net) { + ret = nf_conntrack_l3proto_register_net(proto); if (ret < 0) - return ret; + nf_ct_l3proto_unregister_sysctl(net, proto); } - return nf_ct_l3proto_register_sysctl(net, proto); + + return ret; } EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); @@ -454,19 +459,24 @@ int nf_conntrack_l4proto_register(struct net *net, struct nf_conntrack_l4proto *l4proto) { int ret = 0; - if (net == &init_net) - ret = nf_conntrack_l4proto_register_net(l4proto); - if (ret < 0) - return ret; - - if (l4proto->init_net) + if (l4proto->init_net) { ret = l4proto->init_net(net); + if (ret < 0) + return ret; + } + ret = nf_ct_l4proto_register_sysctl(net, l4proto); if (ret < 0) return ret; - return nf_ct_l4proto_register_sysctl(net, l4proto); + if (net == &init_net) { + ret = nf_conntrack_l4proto_register_net(l4proto); + if (ret < 0) + nf_ct_l4proto_unregister_sysctl(net, l4proto); + } + + return ret; } EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); -- GitLab From 209bd9e3e14712d74c8bebb028afda905d689f1c Mon Sep 17 00:00:00 2001 From: "Pierre-Loup A. Griffais" Date: Fri, 22 Jun 2012 11:38:13 -0700 Subject: [PATCH 3048/6849] perf symbols: Follow .gnu_debuglink section to find separate symbols The .gnu_debuglink section is specified to contain the filename of the debug info file, as well as a CRC that can be used to validate it. This doesn't currently use the checksum and relies on the usual build-id matching for validation. This provides more context: http://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html Signed-off-by: Pierre-Loup A. Griffais Reported-by: Mike Sartain Tested-by: Mike Sartain Cc: Ingo Molnar Cc: Linus Torvalds Cc: Mike Sartain Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/4FE4BB95.3080309@nvidia.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 65 +++++++++++++++++++++++++++++++++++++++- tools/perf/util/symbol.h | 1 + 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 3e2e5ea0f03f..994f4ffdcd05 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1590,11 +1590,62 @@ out: return err; } +static int filename__read_debuglink(const char *filename, + char *debuglink, size_t size) +{ + int fd, err = -1; + Elf *elf; + GElf_Ehdr ehdr; + GElf_Shdr shdr; + Elf_Data *data; + Elf_Scn *sec; + Elf_Kind ek; + + fd = open(filename, O_RDONLY); + if (fd < 0) + goto out; + + elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); + if (elf == NULL) { + pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename); + goto out_close; + } + + ek = elf_kind(elf); + if (ek != ELF_K_ELF) + goto out_close; + + if (gelf_getehdr(elf, &ehdr) == NULL) { + pr_err("%s: cannot get elf header.\n", __func__); + goto out_close; + } + + sec = elf_section_by_name(elf, &ehdr, &shdr, + ".gnu_debuglink", NULL); + if (sec == NULL) + goto out_close; + + data = elf_getdata(sec, NULL); + if (data == NULL) + goto out_close; + + /* the start of this section is a zero-terminated string */ + strncpy(debuglink, data->d_buf, size); + + elf_end(elf); + +out_close: + close(fd); +out: + return err; +} + char dso__symtab_origin(const struct dso *dso) { static const char origin[] = { [SYMTAB__KALLSYMS] = 'k', [SYMTAB__JAVA_JIT] = 'j', + [SYMTAB__DEBUGLINK] = 'l', [SYMTAB__BUILD_ID_CACHE] = 'B', [SYMTAB__FEDORA_DEBUGINFO] = 'f', [SYMTAB__UBUNTU_DEBUGINFO] = 'u', @@ -1662,10 +1713,22 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) */ want_symtab = 1; restart: - for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE; + for (dso->symtab_type = SYMTAB__DEBUGLINK; dso->symtab_type != SYMTAB__NOT_FOUND; dso->symtab_type++) { switch (dso->symtab_type) { + case SYMTAB__DEBUGLINK: { + char *debuglink; + strncpy(name, dso->long_name, size); + debuglink = name + dso->long_name_len; + while (debuglink != name && *debuglink != '/') + debuglink--; + if (*debuglink == '/') + debuglink++; + filename__read_debuglink(dso->long_name, debuglink, + size - (debuglink - name)); + } + break; case SYMTAB__BUILD_ID_CACHE: /* skip the locally configured cache if a symfs is given */ if (symbol_conf.symfs[0] || diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index af0752b1aca1..a884b99017f0 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -257,6 +257,7 @@ enum symtab_type { SYMTAB__KALLSYMS = 0, SYMTAB__GUEST_KALLSYMS, SYMTAB__JAVA_JIT, + SYMTAB__DEBUGLINK, SYMTAB__BUILD_ID_CACHE, SYMTAB__FEDORA_DEBUGINFO, SYMTAB__UBUNTU_DEBUGINFO, -- GitLab From 08942f6d5d992e9486b07653fd87ea8182a22fa0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 20 Jun 2012 15:08:06 +0900 Subject: [PATCH 3049/6849] perf bench: Documentation update The current perf-bench documentation has a couple of typos and even lacks entire description of mem subsystem. Fix it. Reported-by: Ingo Molnar Signed-off-by: Namhyung Kim Acked-by: Hitoshi Mitake Cc: Hitoshi Mitake Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1340172486-17805-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-bench.txt | 78 ++++++++++++++++++++++++- tools/perf/bench/mem-memcpy.c | 4 +- tools/perf/bench/mem-memset.c | 8 +-- tools/perf/builtin-bench.c | 4 +- 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt index a3dbadb26ef5..f3c716a4cad3 100644 --- a/tools/perf/Documentation/perf-bench.txt +++ b/tools/perf/Documentation/perf-bench.txt @@ -12,7 +12,7 @@ SYNOPSIS DESCRIPTION ----------- -This 'perf bench' command is general framework for benchmark suites. +This 'perf bench' command is a general framework for benchmark suites. COMMON OPTIONS -------------- @@ -45,14 +45,20 @@ SUBSYSTEM 'sched':: Scheduler and IPC mechanisms. +'mem':: + Memory access performance. + +'all':: + All benchmark subsystems. + SUITES FOR 'sched' ~~~~~~~~~~~~~~~~~~ *messaging*:: Suite for evaluating performance of scheduler and IPC mechanisms. Based on hackbench by Rusty Russell. -Options of *pipe* -^^^^^^^^^^^^^^^^^ +Options of *messaging* +^^^^^^^^^^^^^^^^^^^^^^ -p:: --pipe:: Use pipe() instead of socketpair() @@ -115,6 +121,72 @@ Example of *pipe* 59004 ops/sec --------------------- +SUITES FOR 'mem' +~~~~~~~~~~~~~~~~ +*memcpy*:: +Suite for evaluating performance of simple memory copy in various ways. + +Options of *memcpy* +^^^^^^^^^^^^^^^^^^^ +-l:: +--length:: +Specify length of memory to copy (default: 1MB). +Available units are B, KB, MB, GB and TB (case insensitive). + +-r:: +--routine:: +Specify routine to copy (default: default). +Available routines are depend on the architecture. +On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. + +-i:: +--iterations:: +Repeat memcpy invocation this number of times. + +-c:: +--clock:: +Use perf's cpu-cycles event instead of gettimeofday syscall. + +-o:: +--only-prefault:: +Show only the result with page faults before memcpy. + +-n:: +--no-prefault:: +Show only the result without page faults before memcpy. + +*memset*:: +Suite for evaluating performance of simple memory set in various ways. + +Options of *memset* +^^^^^^^^^^^^^^^^^^^ +-l:: +--length:: +Specify length of memory to set (default: 1MB). +Available units are B, KB, MB, GB and TB (case insensitive). + +-r:: +--routine:: +Specify routine to set (default: default). +Available routines are depend on the architecture. +On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. + +-i:: +--iterations:: +Repeat memset invocation this number of times. + +-c:: +--clock:: +Use perf's cpu-cycles event instead of gettimeofday syscall. + +-o:: +--only-prefault:: +Show only the result with page faults before memset. + +-n:: +--no-prefault:: +Show only the result without page faults before memset. + SEE ALSO -------- linkperf:perf[1] diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c index 71557225bf92..d990365cafa0 100644 --- a/tools/perf/bench/mem-memcpy.c +++ b/tools/perf/bench/mem-memcpy.c @@ -32,13 +32,13 @@ static bool no_prefault; static const struct option options[] = { OPT_STRING('l', "length", &length_str, "1MB", "Specify length of memory to copy. " - "available unit: B, MB, GB (upper and lower)"), + "Available units: B, KB, MB, GB and TB (upper and lower)"), OPT_STRING('r', "routine", &routine, "default", "Specify routine to copy"), OPT_INTEGER('i', "iterations", &iterations, "repeat memcpy() invocation this number of times"), OPT_BOOLEAN('c', "clock", &use_clock, - "Use CPU clock for measuring"), + "Use cycles event instead of gettimeofday() for measuring"), OPT_BOOLEAN('o', "only-prefault", &only_prefault, "Show only the result with page faults before memcpy()"), OPT_BOOLEAN('n', "no-prefault", &no_prefault, diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c index e9079185bd72..bf0d5f552017 100644 --- a/tools/perf/bench/mem-memset.c +++ b/tools/perf/bench/mem-memset.c @@ -31,14 +31,14 @@ static bool no_prefault; static const struct option options[] = { OPT_STRING('l', "length", &length_str, "1MB", - "Specify length of memory to copy. " - "available unit: B, MB, GB (upper and lower)"), + "Specify length of memory to set. " + "Available units: B, KB, MB, GB and TB (upper and lower)"), OPT_STRING('r', "routine", &routine, "default", - "Specify routine to copy"), + "Specify routine to set"), OPT_INTEGER('i', "iterations", &iterations, "repeat memset() invocation this number of times"), OPT_BOOLEAN('c', "clock", &use_clock, - "Use CPU clock for measuring"), + "Use cycles event instead of gettimeofday() for measuring"), OPT_BOOLEAN('o', "only-prefault", &only_prefault, "Show only the result with page faults before memset()"), OPT_BOOLEAN('n', "no-prefault", &no_prefault, diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index b0e74ab2d7a2..1f3100216448 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -33,7 +33,7 @@ struct bench_suite { }; \ /* sentinel: easy for help */ -#define suite_all { "all", "test all suite (pseudo suite)", NULL } +#define suite_all { "all", "Test all benchmark suites", NULL } static struct bench_suite sched_suites[] = { { "messaging", @@ -75,7 +75,7 @@ static struct bench_subsys subsystems[] = { "memory access performance", mem_suites }, { "all", /* sentinel: easy for help */ - "test all subsystem (pseudo subsystem)", + "all benchmark subsystem", NULL }, { NULL, NULL, -- GitLab From 300aa941650e98966ad85847527537df5b11a87e Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 11 Jun 2012 13:48:41 -0600 Subject: [PATCH 3050/6849] perf report: Delay sample_type checks in pipe mode The pipeline: perf record -a -g -o - sleep 5 |perf inject -v -b | perf report -g -i - generates the warning: Selected -g but no callchain data. Did you call 'perf record' without -g? The problem is that the header data is not written to the pipe, so the sample_type has not been available when perf_report__setup_sample_type is called. For pipe mode, record dumps the sample type as part of the synthesized events stream -- perf_event__synthesize_attrs(). Handle this be detecting pipe mode and not doing early sanity checks on sample_type. Signed-off-by: David Ahern Tested-by: Tim Chen Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tim Chen Link: http://lkml.kernel.org/r/1339444121-26236-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 40b0ffc3ad3b..69b1c1185159 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -245,11 +245,12 @@ static int process_read_event(struct perf_tool *tool, return 0; } +/* For pipe mode, sample_type is not currently set */ static int perf_report__setup_sample_type(struct perf_report *rep) { struct perf_session *self = rep->session; - if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { + if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { ui__error("Selected --sort parent, but no " "callchain data. Did you call " @@ -272,7 +273,8 @@ static int perf_report__setup_sample_type(struct perf_report *rep) } if (sort__branch_mode == 1) { - if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { + if (!self->fd_pipe && + !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { ui__error("Selected -b but no branch data. " "Did you call perf record without -b?\n"); return -1; -- GitLab From f1caad274515ffd9841ac57ce9a7b5fc35bbf689 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:39 +0000 Subject: [PATCH 3051/6849] netfilter: nf_conntrack: prepare l4proto->init_net cleanup l4proto->init contain quite redundant code. We can simplify this by adding a new parameter l3proto. This patch prepares that code simplification. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_l4proto.h | 2 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 2 +- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 2 +- net/netfilter/nf_conntrack_proto.c | 5 +++-- net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_generic.c | 2 +- net/netfilter/nf_conntrack_proto_gre.c | 2 +- net/netfilter/nf_conntrack_proto_sctp.c | 4 ++-- net/netfilter/nf_conntrack_proto_tcp.c | 4 ++-- net/netfilter/nf_conntrack_proto_udp.c | 4 ++-- net/netfilter/nf_conntrack_proto_udplite.c | 2 +- 11 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 81c52b5205f2..5dd60f2d02a1 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -97,7 +97,7 @@ struct nf_conntrack_l4proto { #endif int *net_id; /* Init l4proto pernet data */ - int (*init_net)(struct net *net); + int (*init_net)(struct net *net, u_int16_t proto); /* Protocol name */ const char *name; diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 041923cb67ad..76f7a2f657fe 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -337,7 +337,7 @@ static struct ctl_table icmp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ -static int icmp_init_net(struct net *net) +static int icmp_init_net(struct net *net, u_int16_t proto) { struct nf_icmp_net *in = icmp_pernet(net); struct nf_proto_net *pn = (struct nf_proto_net *)in; diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 63ed0121836c..807ae09df0ca 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -333,7 +333,7 @@ static struct ctl_table icmpv6_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ -static int icmpv6_init_net(struct net *net) +static int icmpv6_init_net(struct net *net, u_int16_t proto) { struct nf_icmp_net *in = icmpv6_pernet(net); struct nf_proto_net *pn = (struct nf_proto_net *)in; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 9bd88aa3c74f..6f4b6f3deee5 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -461,7 +461,7 @@ int nf_conntrack_l4proto_register(struct net *net, int ret = 0; if (l4proto->init_net) { - ret = l4proto->init_net(net); + ret = l4proto->init_net(net, l4proto->l3proto); if (ret < 0) return ret; } @@ -515,7 +515,8 @@ int nf_conntrack_proto_init(struct net *net) { unsigned int i; int err; - err = nf_conntrack_l4proto_generic.init_net(net); + err = nf_conntrack_l4proto_generic.init_net(net, + nf_conntrack_l4proto_generic.l3proto); if (err < 0) return err; err = nf_ct_l4proto_register_sysctl(net, diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index c33f76af913f..52da8f0293b5 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -815,7 +815,7 @@ static struct ctl_table dccp_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ -static int dccp_init_net(struct net *net) +static int dccp_init_net(struct net *net, u_int16_t proto) { struct dccp_net *dn = dccp_pernet(net); struct nf_proto_net *pn = (struct nf_proto_net *)dn; diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index bb0e74fe0fae..d1ed7b44e079 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -135,7 +135,7 @@ static struct ctl_table generic_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ -static int generic_init_net(struct net *net) +static int generic_init_net(struct net *net, u_int16_t proto) { struct nf_generic_net *gn = generic_pernet(net); struct nf_proto_net *pn = (struct nf_proto_net *)gn; diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 5cac41c2fa09..b09b7af7f6f8 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -348,7 +348,7 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = { }; #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ -static int gre_init_net(struct net *net) +static int gre_init_net(struct net *net, u_int16_t proto) { struct netns_proto_gre *net_gre = gre_pernet(net); int i; diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 8fb0582ad397..1e7836cead74 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -767,7 +767,7 @@ static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) return 0; } -static int sctpv4_init_net(struct net *net) +static int sctpv4_init_net(struct net *net, u_int16_t proto) { int ret; struct sctp_net *sn = sctp_pernet(net); @@ -793,7 +793,7 @@ static int sctpv4_init_net(struct net *net) return ret; } -static int sctpv6_init_net(struct net *net) +static int sctpv6_init_net(struct net *net, u_int16_t proto) { struct sctp_net *sn = sctp_pernet(net); struct nf_proto_net *pn = (struct nf_proto_net *)sn; diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 99caa1304477..6db9d3c44820 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1593,7 +1593,7 @@ static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) return 0; } -static int tcpv4_init_net(struct net *net) +static int tcpv4_init_net(struct net *net, u_int16_t proto) { int i; int ret = 0; @@ -1631,7 +1631,7 @@ static int tcpv4_init_net(struct net *net) return ret; } -static int tcpv6_init_net(struct net *net) +static int tcpv6_init_net(struct net *net, u_int16_t proto) { int i; struct nf_tcp_net *tn = tcp_pernet(net); diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index a83cf93545cd..2b978e6fd1c2 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -283,7 +283,7 @@ static void udp_init_net_data(struct nf_udp_net *un) } } -static int udpv4_init_net(struct net *net) +static int udpv4_init_net(struct net *net, u_int16_t proto) { int ret; struct nf_udp_net *un = udp_pernet(net); @@ -307,7 +307,7 @@ static int udpv4_init_net(struct net *net) return ret; } -static int udpv6_init_net(struct net *net) +static int udpv6_init_net(struct net *net, u_int16_t proto) { struct nf_udp_net *un = udp_pernet(net); struct nf_proto_net *pn = (struct nf_proto_net *)un; diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index b32e700f8dde..d33e51158039 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -234,7 +234,7 @@ static struct ctl_table udplite_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ -static int udplite_init_net(struct net *net) +static int udplite_init_net(struct net *net, u_int16_t proto) { int i; struct udplite_net *un = udplite_pernet(net); -- GitLab From d9873ab79376d5c0112ed09e14783067dc65e808 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 11 Jun 2012 19:13:32 -0600 Subject: [PATCH 3052/6849] perf tools: Trivial build fix References to OUTPUT should not be followed by a '/'. When a build output directory is not specified for this case you get: gcc -o builtin-annotate.o -c ... -I/util ... which is wrong. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tim Chen Link: http://lkml.kernel.org/r/1339463612-30937-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index d698c118a602..75d74e5db8d5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -155,7 +155,7 @@ endif ### --- END CONFIGURATION SECTION --- -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = # Guard against environment variables -- GitLab From f28997e27a03abc679f13824a0574b09112eea37 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:40 +0000 Subject: [PATCH 3053/6849] netfilter: nf_conntrack: add nf_ct_kfree_compat_sysctl_table This patch is a cleanup. It adds nf_ct_kfree_compat_sysctl_table to release l4proto's compat sysctl table and set the compat sysctl table point to NULL. This new function will be used by follow-up patches. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_l4proto.h | 8 ++++++++ net/netfilter/nf_conntrack_proto.c | 3 +-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 5dd60f2d02a1..08bb571b7abd 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -124,6 +124,14 @@ extern int nf_conntrack_l4proto_register(struct net *net, extern void nf_conntrack_l4proto_unregister(struct net *net, struct nf_conntrack_l4proto *proto); +static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn) +{ +#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) + kfree(pn->ctl_compat_table); + pn->ctl_compat_table = NULL; +#endif +} + /* Generic netlink helpers */ extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple); diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 6f4b6f3deee5..9d6b6ab193a9 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -361,8 +361,7 @@ int nf_ct_l4proto_register_sysctl(struct net *net, if (err == 0) goto out; - kfree(pn->ctl_compat_table); - pn->ctl_compat_table = NULL; + nf_ct_kfree_compat_sysctl_table(pn); nf_ct_unregister_sysctl(&pn->ctl_table_header, &pn->ctl_table, &pn->users); -- GitLab From fa34fff5e69cc56eecf26754c9b57403899ebd0d Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:41 +0000 Subject: [PATCH 3054/6849] netfilter: nf_conntrack: use l4proto->users as refcount for per-net data Currently, nf_proto_net's l4proto->users meaning is quite confusing since it depends on the compilation tweaks. To resolve this, we cleanup this code to regard it as the refcount for l4proto's per-net data, since there may be two l4protos use the same per-net data. Thus, we increment pn->users when nf_conntrack_l4proto_register successfully, and decrement it for nf_conntrack_l4_unregister case. The users refcnt is not required form layer 3 protocol trackers. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto.c | 76 ++++++++++++++++++------------ 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 9d6b6ab193a9..63612e6d7238 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -39,16 +39,13 @@ static int nf_ct_register_sysctl(struct net *net, struct ctl_table_header **header, const char *path, - struct ctl_table *table, - unsigned int *users) + struct ctl_table *table) { if (*header == NULL) { *header = register_net_sysctl(net, path, table); if (*header == NULL) return -ENOMEM; } - if (users != NULL) - (*users)++; return 0; } @@ -56,9 +53,9 @@ nf_ct_register_sysctl(struct net *net, static void nf_ct_unregister_sysctl(struct ctl_table_header **header, struct ctl_table **table, - unsigned int *users) + unsigned int users) { - if (users != NULL && --*users > 0) + if (users > 0) return; unregister_net_sysctl_table(*header); @@ -191,8 +188,7 @@ static int nf_ct_l3proto_register_sysctl(struct net *net, err = nf_ct_register_sysctl(net, &in->ctl_table_header, l3proto->ctl_table_path, - in->ctl_table, - NULL); + in->ctl_table); if (err < 0) { kfree(in->ctl_table); in->ctl_table = NULL; @@ -213,7 +209,7 @@ static void nf_ct_l3proto_unregister_sysctl(struct net *net, if (in->ctl_table_header != NULL) nf_ct_unregister_sysctl(&in->ctl_table_header, &in->ctl_table, - NULL); + 0); #endif } @@ -329,20 +325,17 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, static int nf_ct_l4proto_register_sysctl(struct net *net, + struct nf_proto_net *pn, struct nf_conntrack_l4proto *l4proto) { int err = 0; - struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); - if (pn == NULL) - return 0; #ifdef CONFIG_SYSCTL if (pn->ctl_table != NULL) { err = nf_ct_register_sysctl(net, &pn->ctl_table_header, "net/netfilter", - pn->ctl_table, - &pn->users); + pn->ctl_table); if (err < 0) { if (!pn->users) { kfree(pn->ctl_table); @@ -356,15 +349,14 @@ int nf_ct_l4proto_register_sysctl(struct net *net, err = nf_ct_register_sysctl(net, &pn->ctl_compat_header, "net/ipv4/netfilter", - pn->ctl_compat_table, - NULL); + pn->ctl_compat_table); if (err == 0) goto out; nf_ct_kfree_compat_sysctl_table(pn); nf_ct_unregister_sysctl(&pn->ctl_table_header, &pn->ctl_table, - &pn->users); + pn->users); } #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ out: @@ -374,25 +366,21 @@ out: static void nf_ct_l4proto_unregister_sysctl(struct net *net, + struct nf_proto_net *pn, struct nf_conntrack_l4proto *l4proto) { - struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); - if (pn == NULL) - return; #ifdef CONFIG_SYSCTL if (pn->ctl_table_header != NULL) nf_ct_unregister_sysctl(&pn->ctl_table_header, &pn->ctl_table, - &pn->users); + pn->users); #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_header != NULL) nf_ct_unregister_sysctl(&pn->ctl_compat_header, &pn->ctl_compat_table, - NULL); + 0); #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ -#else - pn->users--; #endif /* CONFIG_SYSCTL */ } @@ -458,23 +446,32 @@ int nf_conntrack_l4proto_register(struct net *net, struct nf_conntrack_l4proto *l4proto) { int ret = 0; + struct nf_proto_net *pn = NULL; if (l4proto->init_net) { ret = l4proto->init_net(net, l4proto->l3proto); if (ret < 0) - return ret; + goto out; } - ret = nf_ct_l4proto_register_sysctl(net, l4proto); + pn = nf_ct_l4proto_net(net, l4proto); + if (pn == NULL) + goto out; + + ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto); if (ret < 0) - return ret; + goto out; if (net == &init_net) { ret = nf_conntrack_l4proto_register_net(l4proto); - if (ret < 0) - nf_ct_l4proto_unregister_sysctl(net, l4proto); + if (ret < 0) { + nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); + goto out; + } } + pn->users++; +out: return ret; } EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); @@ -499,10 +496,18 @@ nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto) void nf_conntrack_l4proto_unregister(struct net *net, struct nf_conntrack_l4proto *l4proto) { + struct nf_proto_net *pn = NULL; + if (net == &init_net) nf_conntrack_l4proto_unregister_net(l4proto); - nf_ct_l4proto_unregister_sysctl(net, l4proto); + pn = nf_ct_l4proto_net(net, l4proto); + if (pn == NULL) + return; + + pn->users--; + nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); + /* Remove all contrack entries for this protocol */ rtnl_lock(); nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); @@ -514,11 +519,15 @@ int nf_conntrack_proto_init(struct net *net) { unsigned int i; int err; + struct nf_proto_net *pn = nf_ct_l4proto_net(net, + &nf_conntrack_l4proto_generic); + err = nf_conntrack_l4proto_generic.init_net(net, nf_conntrack_l4proto_generic.l3proto); if (err < 0) return err; err = nf_ct_l4proto_register_sysctl(net, + pn, &nf_conntrack_l4proto_generic); if (err < 0) return err; @@ -528,13 +537,20 @@ int nf_conntrack_proto_init(struct net *net) rcu_assign_pointer(nf_ct_l3protos[i], &nf_conntrack_l3proto_generic); } + + pn->users++; return 0; } void nf_conntrack_proto_fini(struct net *net) { unsigned int i; + struct nf_proto_net *pn = nf_ct_l4proto_net(net, + &nf_conntrack_l4proto_generic); + + pn->users--; nf_ct_l4proto_unregister_sysctl(net, + pn, &nf_conntrack_l4proto_generic); if (net == &init_net) { /* free l3proto protocol tables */ -- GitLab From 12c26df35eae52f14cf573a1adb85cedaa273d2b Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:42 +0000 Subject: [PATCH 3055/6849] netfilter: nf_conntrack: fix memory leak if sysctl registration fails In nf_ct_l4proto_register_sysctl, if l4proto sysctl registration fails, we have to make sure that we release the compat sysctl table. This can happen if TCP has been registered compat for IPv4, and IPv6 compat registration fails. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 63612e6d7238..21b850c4b3ab 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -341,11 +341,14 @@ int nf_ct_l4proto_register_sysctl(struct net *net, kfree(pn->ctl_table); pn->ctl_table = NULL; } - goto out; } } #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_table != NULL) { + if (err < 0) { + nf_ct_kfree_compat_sysctl_table(pn); + goto out; + } err = nf_ct_register_sysctl(net, &pn->ctl_compat_header, "net/ipv4/netfilter", @@ -358,8 +361,8 @@ int nf_ct_l4proto_register_sysctl(struct net *net, &pn->ctl_table, pn->users); } -#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ out: +#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ return err; } -- GitLab From efa758fe2c2543f70b4dbda4421c8a352703e68e Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:43 +0000 Subject: [PATCH 3056/6849] netfilter: nf_ct_tcp: merge tcpv[4,6]_net_init into tcp_net_init Merge tcpv4_net_init and tcpv6_net_init into tcp_net_init to remove redundant code now that we have the u_int16_t proto parameter. And use nf_proto_net.users to identify if it's the first time we use the nf_proto_net, in that case, we initialize it. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_tcp.c | 71 ++++++++------------------ 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 6db9d3c44820..44f0da830156 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1533,11 +1533,10 @@ static struct ctl_table tcp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ -static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn) +static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct nf_tcp_net *tn) { #ifdef CONFIG_SYSCTL - struct nf_tcp_net *tn = (struct nf_tcp_net *)pn; - if (pn->ctl_table) return 0; @@ -1564,11 +1563,11 @@ static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn) return 0; } -static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) +static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, + struct nf_tcp_net *tn) { #ifdef CONFIG_SYSCTL #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - struct nf_tcp_net *tn = (struct nf_tcp_net *)pn; pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table, sizeof(tcp_compat_sysctl_table), GFP_KERNEL); @@ -1593,18 +1592,15 @@ static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) return 0; } -static int tcpv4_init_net(struct net *net, u_int16_t proto) +static int tcp_init_net(struct net *net, u_int16_t proto) { - int i; - int ret = 0; + int ret; struct nf_tcp_net *tn = tcp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)tn; + struct nf_proto_net *pn = &tn->pn; + + if (!pn->users) { + int i; -#ifdef CONFIG_SYSCTL - if (!pn->ctl_table) { -#else - if (!pn->users++) { -#endif for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) tn->timeouts[i] = tcp_timeouts[i]; @@ -1613,45 +1609,20 @@ static int tcpv4_init_net(struct net *net, u_int16_t proto) tn->tcp_max_retrans = nf_ct_tcp_max_retrans; } - ret = tcp_kmemdup_compat_sysctl_table(pn); - - if (ret < 0) - return ret; + if (proto == AF_INET) { + ret = tcp_kmemdup_compat_sysctl_table(pn, tn); + if (ret < 0) + return ret; - ret = tcp_kmemdup_sysctl_table(pn); + ret = tcp_kmemdup_sysctl_table(pn, tn); + if (ret < 0) + nf_ct_kfree_compat_sysctl_table(pn); + } else + ret = tcp_kmemdup_sysctl_table(pn, tn); -#ifdef CONFIG_SYSCTL -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - if (ret < 0) { - kfree(pn->ctl_compat_table); - pn->ctl_compat_table = NULL; - } -#endif -#endif return ret; } -static int tcpv6_init_net(struct net *net, u_int16_t proto) -{ - int i; - struct nf_tcp_net *tn = tcp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)tn; - -#ifdef CONFIG_SYSCTL - if (!pn->ctl_table) { -#else - if (!pn->users++) { -#endif - for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++) - tn->timeouts[i] = tcp_timeouts[i]; - tn->tcp_loose = nf_ct_tcp_loose; - tn->tcp_be_liberal = nf_ct_tcp_be_liberal; - tn->tcp_max_retrans = nf_ct_tcp_max_retrans; - } - - return tcp_kmemdup_sysctl_table(pn); -} - struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = { .l3proto = PF_INET, @@ -1684,7 +1655,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = .nla_policy = tcp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ - .init_net = tcpv4_init_net, + .init_net = tcp_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4); @@ -1720,6 +1691,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly = .nla_policy = tcp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ - .init_net = tcpv6_init_net, + .init_net = tcp_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6); -- GitLab From dee7364e0e522f9cd90187c28dbb64889a17e191 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:44 +0000 Subject: [PATCH 3057/6849] netfilter: nf_ct_udp: merge udpv[4,6]_net_init into udp_net_init Merge udpv4_net_init and udpv6_net_init into udp_net_init to remove redundant code now that we have the u_int16_t proto parameter. And use nf_proto_net.users to identify if it's the first time we use the nf_proto_net, in that case, we initialize it. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_udp.c | 65 +++++++++----------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 2b978e6fd1c2..e7e0434c3056 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -235,10 +235,10 @@ static struct ctl_table udp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ -static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn) +static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct nf_udp_net *un) { #ifdef CONFIG_SYSCTL - struct nf_udp_net *un = (struct nf_udp_net *)pn; if (pn->ctl_table) return 0; pn->ctl_table = kmemdup(udp_sysctl_table, @@ -252,11 +252,11 @@ static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn) return 0; } -static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) +static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, + struct nf_udp_net *un) { #ifdef CONFIG_SYSCTL #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - struct nf_udp_net *un = (struct nf_udp_net *)pn; pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table, sizeof(udp_compat_sysctl_table), GFP_KERNEL); @@ -270,50 +270,31 @@ static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) return 0; } -static void udp_init_net_data(struct nf_udp_net *un) -{ - int i; -#ifdef CONFIG_SYSCTL - if (!un->pn.ctl_table) { -#else - if (!un->pn.users++) { -#endif - for (i = 0; i < UDP_CT_MAX; i++) - un->timeouts[i] = udp_timeouts[i]; - } -} - -static int udpv4_init_net(struct net *net, u_int16_t proto) +static int udp_init_net(struct net *net, u_int16_t proto) { int ret; struct nf_udp_net *un = udp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)un; - - udp_init_net_data(un); + struct nf_proto_net *pn = &un->pn; - ret = udp_kmemdup_compat_sysctl_table(pn); - if (ret < 0) - return ret; + if (!pn->users) { + int i; - ret = udp_kmemdup_sysctl_table(pn); -#ifdef CONFIG_SYSCTL -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - if (ret < 0) { - kfree(pn->ctl_compat_table); - pn->ctl_compat_table = NULL; + for (i = 0; i < UDP_CT_MAX; i++) + un->timeouts[i] = udp_timeouts[i]; } -#endif -#endif - return ret; -} -static int udpv6_init_net(struct net *net, u_int16_t proto) -{ - struct nf_udp_net *un = udp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)un; + if (proto == AF_INET) { + ret = udp_kmemdup_compat_sysctl_table(pn, un); + if (ret < 0) + return ret; - udp_init_net_data(un); - return udp_kmemdup_sysctl_table(pn); + ret = udp_kmemdup_sysctl_table(pn, un); + if (ret < 0) + nf_ct_kfree_compat_sysctl_table(pn); + } else + ret = udp_kmemdup_sysctl_table(pn, un); + + return ret; } struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = @@ -343,7 +324,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = .nla_policy = udp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ - .init_net = udpv4_init_net, + .init_net = udp_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4); @@ -374,6 +355,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly = .nla_policy = udp_timeout_nla_policy, }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ - .init_net = udpv6_init_net, + .init_net = udp_init_net, }; EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6); -- GitLab From 51b4c824fcd15b73931fdd945cc101b9d4791b17 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:45 +0000 Subject: [PATCH 3058/6849] netfilter: nf_ct_udplite: add udplite_kmemdup_sysctl_table function This cleans up nf_conntrack_l4proto_udplite[4,6] and it prepares the moving of the sysctl code to nf_conntrack_proto_*_sysctl.c to reduce the ifdef pollution. And use nf_proto_net.users to identify if it's the first time we use the nf_proto_net, in that case, we initialize it. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_udplite.c | 43 +++++++++++++--------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index d33e51158039..4b66df209286 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -234,29 +234,38 @@ static struct ctl_table udplite_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ -static int udplite_init_net(struct net *net, u_int16_t proto) +static int udplite_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct udplite_net *un) { - int i; - struct udplite_net *un = udplite_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)un; #ifdef CONFIG_SYSCTL - if (!pn->ctl_table) { -#else - if (!pn->users++) { + if (pn->ctl_table) + return 0; + + pn->ctl_table = kmemdup(udplite_sysctl_table, + sizeof(udplite_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + + pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED]; + pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED]; #endif + return 0; +} + +static int udplite_init_net(struct net *net, u_int16_t proto) +{ + struct udplite_net *un = udplite_pernet(net); + struct nf_proto_net *pn = &un->pn; + + if (!pn->users) { + int i; + for (i = 0 ; i < UDPLITE_CT_MAX; i++) un->timeouts[i] = udplite_timeouts[i]; -#ifdef CONFIG_SYSCTL - pn->ctl_table = kmemdup(udplite_sysctl_table, - sizeof(udplite_sysctl_table), - GFP_KERNEL); - if (!pn->ctl_table) - return -ENOMEM; - pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED]; - pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED]; -#endif } - return 0; + + return udplite_kmemdup_sysctl_table(pn, un); } static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = -- GitLab From f42c4183c781733b1947ae79916849574d86aced Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:46 +0000 Subject: [PATCH 3059/6849] netfilter: nf_ct_sctp: merge sctpv[4,6]_net_init into sctp_net_init Merge sctpv4_net_init and sctpv6_net_init into sctp_net_init to remove redundant code now that we have the u_int16_t proto parameter. And use nf_proto_net.users to identify if it's the first time we use the nf_proto_net, in that case, we initialize i Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_sctp.c | 65 +++++++++---------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 1e7836cead74..c746d61f83ed 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -707,23 +707,10 @@ static struct ctl_table sctp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif -static void sctp_init_net_data(struct sctp_net *sn) -{ - int i; -#ifdef CONFIG_SYSCTL - if (!sn->pn.ctl_table) { -#else - if (!sn->pn.users++) { -#endif - for (i = 0; i < SCTP_CONNTRACK_MAX; i++) - sn->timeouts[i] = sctp_timeouts[i]; - } -} - -static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn) +static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct sctp_net *sn) { #ifdef CONFIG_SYSCTL - struct sctp_net *sn = (struct sctp_net *)pn; if (pn->ctl_table) return 0; @@ -744,11 +731,11 @@ static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn) return 0; } -static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) +static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, + struct sctp_net *sn) { #ifdef CONFIG_SYSCTL #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - struct sctp_net *sn = (struct sctp_net *)pn; pn->ctl_compat_table = kmemdup(sctp_compat_sysctl_table, sizeof(sctp_compat_sysctl_table), GFP_KERNEL); @@ -767,41 +754,33 @@ static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn) return 0; } -static int sctpv4_init_net(struct net *net, u_int16_t proto) +static int sctp_init_net(struct net *net, u_int16_t proto) { int ret; struct sctp_net *sn = sctp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)sn; + struct nf_proto_net *pn = &sn->pn; - sctp_init_net_data(sn); + if (!pn->users) { + int i; - ret = sctp_kmemdup_compat_sysctl_table(pn); - if (ret < 0) - return ret; + for (i = 0; i < SCTP_CONNTRACK_MAX; i++) + sn->timeouts[i] = sctp_timeouts[i]; + } - ret = sctp_kmemdup_sysctl_table(pn); + if (proto == AF_INET) { + ret = sctp_kmemdup_compat_sysctl_table(pn, sn); + if (ret < 0) + return ret; -#ifdef CONFIG_SYSCTL -#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT - if (ret < 0) { + ret = sctp_kmemdup_sysctl_table(pn, sn); + if (ret < 0) + nf_ct_kfree_compat_sysctl_table(pn); + } else + ret = sctp_kmemdup_sysctl_table(pn, sn); - kfree(pn->ctl_compat_table); - pn->ctl_compat_table = NULL; - } -#endif -#endif return ret; } -static int sctpv6_init_net(struct net *net, u_int16_t proto) -{ - struct sctp_net *sn = sctp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)sn; - - sctp_init_net_data(sn); - return sctp_kmemdup_sysctl_table(pn); -} - static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_SCTP, @@ -833,7 +812,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { }, #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ .net_id = &sctp_net_id, - .init_net = sctpv4_init_net, + .init_net = sctp_init_net, }; static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { @@ -867,7 +846,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #endif .net_id = &sctp_net_id, - .init_net = sctpv6_init_net, + .init_net = sctp_init_net, }; static int sctp_net_init(struct net *net) -- GitLab From 22ac03772f2b7cedbd531f588f0b77a77d943585 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:47 +0000 Subject: [PATCH 3060/6849] netfilter: nf_ct_generic: add generic_kmemdup_sysctl_table function This patch is a cleanup. It adds generic_kmemdup_sysctl_table to split code into smaller chunks. Yet it prepares introduction of nf_conntrack_proto_*_sysctl.c. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_generic.c | 39 +++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index d1ed7b44e079..7c11c5444194 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -135,34 +135,57 @@ static struct ctl_table generic_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ -static int generic_init_net(struct net *net, u_int16_t proto) +static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct nf_generic_net *gn) { - struct nf_generic_net *gn = generic_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)gn; - gn->timeout = nf_ct_generic_timeout; #ifdef CONFIG_SYSCTL pn->ctl_table = kmemdup(generic_sysctl_table, sizeof(generic_sysctl_table), GFP_KERNEL); if (!pn->ctl_table) return -ENOMEM; + pn->ctl_table[0].data = &gn->timeout; +#endif + return 0; +} +static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, + struct nf_generic_net *gn) +{ +#ifdef CONFIG_SYSCTL #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table, sizeof(generic_compat_sysctl_table), GFP_KERNEL); - if (!pn->ctl_compat_table) { - kfree(pn->ctl_table); - pn->ctl_table = NULL; + if (!pn->ctl_compat_table) return -ENOMEM; - } + pn->ctl_compat_table[0].data = &gn->timeout; #endif #endif return 0; } +static int generic_init_net(struct net *net, u_int16_t proto) +{ + int ret; + struct nf_generic_net *gn = generic_pernet(net); + struct nf_proto_net *pn = &gn->pn; + + gn->timeout = nf_ct_generic_timeout; + + ret = generic_kmemdup_compat_sysctl_table(pn, gn); + if (ret < 0) + return ret; + + ret = generic_kmemdup_sysctl_table(pn, gn); + if (ret < 0) + nf_ct_kfree_compat_sysctl_table(pn); + + return ret; +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = { .l3proto = PF_UNSPEC, -- GitLab From 54b8873f7c907a1efbcf4f412dce0b9eed805d5b Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:48 +0000 Subject: [PATCH 3061/6849] netfilter: nf_ct_dccp: add dccp_kmemdup_sysctl_table function This patch is a cleanup. It adds dccp_kmemdup_sysctl_table to split code into smaller chunks. Yet it prepares introduction of nf_conntrack_proto_*_sysctl.c. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_dccp.c | 54 ++++++++++++++----------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index 52da8f0293b5..6535326cf07c 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -387,7 +387,7 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = /* this module per-net specifics */ static int dccp_net_id __read_mostly; struct dccp_net { - struct nf_proto_net np; + struct nf_proto_net pn; int dccp_loose; unsigned int dccp_timeout[CT_DCCP_MAX + 1]; }; @@ -815,16 +815,37 @@ static struct ctl_table dccp_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ +static int dccp_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct dccp_net *dn) +{ +#ifdef CONFIG_SYSCTL + if (pn->ctl_table) + return 0; + + pn->ctl_table = kmemdup(dccp_sysctl_table, + sizeof(dccp_sysctl_table), + GFP_KERNEL); + if (!pn->ctl_table) + return -ENOMEM; + + pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; + pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; + pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; + pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; + pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; + pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; + pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; + pn->ctl_table[7].data = &dn->dccp_loose; +#endif + return 0; +} + static int dccp_init_net(struct net *net, u_int16_t proto) { struct dccp_net *dn = dccp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)dn; + struct nf_proto_net *pn = &dn->pn; -#ifdef CONFIG_SYSCTL - if (!pn->ctl_table) { -#else - if (!pn->users++) { -#endif + if (!pn->users) { /* default values */ dn->dccp_loose = 1; dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL; @@ -834,24 +855,9 @@ static int dccp_init_net(struct net *net, u_int16_t proto) dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ; dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ; dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL; -#ifdef CONFIG_SYSCTL - pn->ctl_table = kmemdup(dccp_sysctl_table, - sizeof(dccp_sysctl_table), - GFP_KERNEL); - if (!pn->ctl_table) - return -ENOMEM; - - pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; - pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; - pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; - pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; - pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; - pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; - pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; - pn->ctl_table[7].data = &dn->dccp_loose; -#endif } - return 0; + + return dccp_kmemdup_sysctl_table(pn, dn); } static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { -- GitLab From a9082b45ad3c7284db974a108e7c1f1af7387d7b Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:49 +0000 Subject: [PATCH 3062/6849] netfilter: nf_ct_icmp: add icmp_kmemdup[_compat]_sysctl_table function Split sysctl function into smaller chucks to cleanup code and prepare patches to reduce ifdef pollution. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 41 +++++++++++++++----- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 76f7a2f657fe..9c2095c5571f 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -337,34 +337,57 @@ static struct ctl_table icmp_compat_sysctl_table[] = { #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ #endif /* CONFIG_SYSCTL */ -static int icmp_init_net(struct net *net, u_int16_t proto) +static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct nf_icmp_net *in) { - struct nf_icmp_net *in = icmp_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)in; - in->timeout = nf_ct_icmp_timeout; - #ifdef CONFIG_SYSCTL pn->ctl_table = kmemdup(icmp_sysctl_table, sizeof(icmp_sysctl_table), GFP_KERNEL); if (!pn->ctl_table) return -ENOMEM; + pn->ctl_table[0].data = &in->timeout; +#endif + return 0; +} + +static int icmp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, + struct nf_icmp_net *in) +{ +#ifdef CONFIG_SYSCTL #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT pn->ctl_compat_table = kmemdup(icmp_compat_sysctl_table, sizeof(icmp_compat_sysctl_table), GFP_KERNEL); - if (!pn->ctl_compat_table) { - kfree(pn->ctl_table); - pn->ctl_table = NULL; + if (!pn->ctl_compat_table) return -ENOMEM; - } + pn->ctl_compat_table[0].data = &in->timeout; #endif #endif return 0; } +static int icmp_init_net(struct net *net, u_int16_t proto) +{ + int ret; + struct nf_icmp_net *in = icmp_pernet(net); + struct nf_proto_net *pn = &in->pn; + + in->timeout = nf_ct_icmp_timeout; + + ret = icmp_kmemdup_compat_sysctl_table(pn, in); + if (ret < 0) + return ret; + + ret = icmp_kmemdup_sysctl_table(pn, in); + if (ret < 0) + nf_ct_kfree_compat_sysctl_table(pn); + + return ret; +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = { .l3proto = PF_INET, -- GitLab From 8fc02781688eda937657193ee28caf4914563d27 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Jun 2012 04:36:50 +0000 Subject: [PATCH 3063/6849] netfilter: nf_ct_icmpv6: add icmpv6_kmemdup_sysctl_table function Split sysctl function into smaller chucks to cleanup code and prepare patches to reduce ifdef pollution. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 807ae09df0ca..9fc5cf5f3e8b 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -333,22 +333,31 @@ static struct ctl_table icmpv6_sysctl_table[] = { }; #endif /* CONFIG_SYSCTL */ -static int icmpv6_init_net(struct net *net, u_int16_t proto) +static int icmpv6_kmemdup_sysctl_table(struct nf_proto_net *pn, + struct nf_icmp_net *in) { - struct nf_icmp_net *in = icmpv6_pernet(net); - struct nf_proto_net *pn = (struct nf_proto_net *)in; - in->timeout = nf_ct_icmpv6_timeout; #ifdef CONFIG_SYSCTL pn->ctl_table = kmemdup(icmpv6_sysctl_table, sizeof(icmpv6_sysctl_table), GFP_KERNEL); if (!pn->ctl_table) return -ENOMEM; + pn->ctl_table[0].data = &in->timeout; #endif return 0; } +static int icmpv6_init_net(struct net *net, u_int16_t proto) +{ + struct nf_icmp_net *in = icmpv6_pernet(net); + struct nf_proto_net *pn = &in->pn; + + in->timeout = nf_ct_icmpv6_timeout; + + return icmpv6_kmemdup_sysctl_table(pn, in); +} + struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = { .l3proto = PF_INET6, -- GitLab From a7df7a9494ac8eb5fa4d902d3e90b083705dc80f Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 27 Jun 2012 14:43:31 +0200 Subject: [PATCH 3064/6849] s390/ipl: Fix ipib handling for "dumpreipl" shutdown action Fix problem that was introduced with patch "s390/smp: make absolute lowcore / cpu restart parameter". After that patch the "dumpreipl" shutdown action does not work any more. To fix the problem we have to assign "reipl_block_actual" instead of "&reipl_block_actual" Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ipl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 25241cd8ddd8..c903aa14df2a 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -1528,7 +1528,7 @@ static struct shutdown_action __refdata dump_action = { static void dump_reipl_run(struct shutdown_trigger *trigger) { - unsigned long ipib = (unsigned long) &reipl_block_actual; + unsigned long ipib = (unsigned long) reipl_block_actual; unsigned int csum; csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); -- GitLab From 75cc52358799bd6001e7d1a47847f997f5ae99f0 Mon Sep 17 00:00:00 2001 From: Deepthi Dharwar Date: Mon, 25 Jun 2012 23:59:54 +0200 Subject: [PATCH 3065/6849] PM / ACPI: Fix suspend/resume regression caused by cpuidle cleanup. Commit e978aa7d7d57d04eb5f88a7507c4fb98577def77 ( cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state) was breaking suspend on laptops, as reported in the below link - https://lkml.org/lkml/2011/11/11/164 This was fixed in commit 3439a8da16bcad6b0982ece938c9f8299bb53584 (ACPI / cpuidle: Remove acpi_idle_suspend (to fix suspend regression) by removing acpi_idle_suspend flag. - https://lkml.org/lkml/2011/11/14/74 But this did fix did not work on all systems as Suspend/resume regression was reported on Lenovo S10-3 recently by Dave. - https://lkml.org/lkml/2012/5/27/115 It looked like with commit e978aa7d broke suspend and with commit 3439a8da resume was not working with acpi_idle driver. This patch fixes the regression that caused this issue in the first place. acpi_idle_suspend flag is essential on some x86 systems to prevent the cpus from going to deeper C-states when suspend is triggered ( commit b04e7bdb984 ) So reverting the commit 3439a8da is essential. By default, irqs are disabled in cpu_idle arch specific call and re-enabled in idle state return path . During suspend, the acpi_idle_suspend flag is set, which prevents the cpus from going to deeper idle states, it is essential to enabling the irqs in this return path too. To address the suspend issue, we were not re-enabling the interrupts while returning from acpi_idle_enter_bm() routine if acpi_idle_suspend flag is set. and this caused suspend failure. In addition to the above, to improve the readability of the code, return of -ENIVAL is replaced with -EBUSY in acpi_idle_suspend return path. Implying that the system is currently busy when suspend is in progress, which prevents the cpus from entering deeper C-states. Reported-and-Tested-by: Dav Hansen Tested-by: Preeti Murthy Signed-off-by: Deepthi Dharwar Reviewed-by: Srivatsa S Bhat Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_idle.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f3decb30223f..47a8caa89dbe 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -224,6 +224,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, /* * Suspend / resume control */ +static int acpi_idle_suspend; static u32 saved_bm_rld; static void acpi_idle_bm_rld_save(void) @@ -242,13 +243,21 @@ static void acpi_idle_bm_rld_restore(void) int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { + if (acpi_idle_suspend == 1) + return 0; + acpi_idle_bm_rld_save(); + acpi_idle_suspend = 1; return 0; } int acpi_processor_resume(struct acpi_device * device) { + if (acpi_idle_suspend == 0) + return 0; + acpi_idle_bm_rld_restore(); + acpi_idle_suspend = 0; return 0; } @@ -754,6 +763,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + lapic_timer_state_broadcast(pr, cx, 1); kt1 = ktime_get_real(); acpi_idle_do_entry(cx); @@ -823,6 +838,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, drv, drv->safe_state_index); } else { local_irq_disable(); - acpi_safe_halt(); + if (!acpi_idle_suspend) + acpi_safe_halt(); local_irq_enable(); - return -EINVAL; + return -EBUSY; } } local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* -- GitLab From 00227f15a0ad8401d2b0b67905da63e75b544895 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 27 Jun 2012 18:45:44 +0200 Subject: [PATCH 3066/6849] ALSA: HDA: Support single 3-pin jack without VREF on the actual pin Some ASUS device has a single 3-pin jack that can either be a mic or a headphone, but the pin does not have VREF capabilities. We've been told by Realtek to instead enable VREF on pin 0x18 in that case. BugLink: https://bugs.launchpad.net/bugs/1018262 Tested-by: Chih-Hsyuan Ho Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 49 ++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5c81ee95d7f0..40dda2a83774 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -303,6 +303,38 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) static void call_update_outputs(struct hda_codec *codec); static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); +/* for shared I/O, change the pin-control accordingly */ +static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) +{ + struct alc_spec *spec = codec->spec; + unsigned int val; + hda_nid_t pin = spec->autocfg.inputs[1].pin; + /* NOTE: this assumes that there are only two inputs, the + * first is the real internal mic and the second is HP/mic jack. + */ + + val = snd_hda_get_default_vref(codec, pin); + + /* This pin does not have vref caps - let's enable vref on pin 0x18 + instead, as suggested by Realtek */ + if (val == AC_PINCTL_VREF_HIZ) { + const hda_nid_t vref_pin = 0x18; + /* Sanity check pin 0x18 */ + if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN && + get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) { + unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); + if (vref_val != AC_PINCTL_VREF_HIZ) + snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0)); + } + } + + val = set_as_mic ? val | PIN_IN : PIN_HP; + snd_hda_set_pin_ctl(codec, pin, val); + + spec->automute_speaker = !set_as_mic; + call_update_outputs(codec); +} + /* select the given imux item; either unmute exclusively or select the route */ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, unsigned int idx, bool force) @@ -329,21 +361,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, return 0; spec->cur_mux[adc_idx] = idx; - /* for shared I/O, change the pin-control accordingly */ - if (spec->shared_mic_hp) { - unsigned int val; - hda_nid_t pin = spec->autocfg.inputs[1].pin; - /* NOTE: this assumes that there are only two inputs, the - * first is the real internal mic and the second is HP jack. - */ - if (spec->cur_mux[adc_idx]) - val = snd_hda_get_default_vref(codec, pin) | PIN_IN; - else - val = PIN_HP; - snd_hda_set_pin_ctl(codec, pin, val); - spec->automute_speaker = !spec->cur_mux[adc_idx]; - call_update_outputs(codec); - } + if (spec->shared_mic_hp) + update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); if (spec->dyn_adc_switch) { alc_dyn_adc_pcm_resetup(codec, idx); -- GitLab From 5780b627e24113323427c102175296ae43dfb9d7 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 27 Jun 2012 18:45:45 +0200 Subject: [PATCH 3067/6849] ALSA: hda - give 3-pin jack the name "Headphone Mic Jack" This 3-pin jack was labeled "Headphone Jack", but it could also be used as a mic jack just by switching "Input Source". Therefore we need to call the jack something else, to make sure PulseAudio can use the speaker together with the external mic. (PulseAudio might mute the speaker if it detects a headphone being plugged in.) Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 40dda2a83774..f912d74438a6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2001,13 +2001,31 @@ static int __alc_build_controls(struct hda_codec *codec) return 0; } -static int alc_build_controls(struct hda_codec *codec) +static int alc_build_jacks(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + + if (spec->shared_mic_hp) { + int err; + int nid = spec->autocfg.inputs[1].pin; + err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0); + if (err < 0) + return err; + err = snd_hda_jack_detect_enable(codec, nid, 0); + if (err < 0) + return err; + } + + return snd_hda_jack_add_kctls(codec, &spec->autocfg); +} + +static int alc_build_controls(struct hda_codec *codec) +{ int err = __alc_build_controls(codec); if (err < 0) return err; - err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + + err = alc_build_jacks(codec); if (err < 0) return err; alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); -- GitLab From 7aa1e7f06d6ea1bce3b27630d50769d13da28b1a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Jun 2012 16:43:36 +0200 Subject: [PATCH 3068/6849] Revert "drm/i915: allow PCH PWM override on IVB" This reverts commit f82cfb6bcda164ef3a66b8c3fc549b1f9bdd09ad. This breaks the backlight controls on my IVB asus zenbook with an eDP panel. I guess the right fix would be to read this bit and use either the pch or the cpu register to frob the backlight values. But that is stuff for -next. Cc: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a7c727d0c105..a8538ac0299d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6921,19 +6921,6 @@ static void i915_disable_vga(struct drm_device *dev) POSTING_READ(vga_reg); } -static void ivb_pch_pwm_override(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* - * IVB has CPU eDP backlight regs too, set things up to let the - * PCH regs control the backlight - */ - I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE); - I915_WRITE(BLC_PWM_CPU_CTL, 0); - I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30)); -} - void intel_modeset_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6950,9 +6937,6 @@ void intel_modeset_init_hw(struct drm_device *dev) gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } - - if (IS_IVYBRIDGE(dev)) - ivb_pch_pwm_override(dev); } void intel_modeset_init(struct drm_device *dev) -- GitLab From f63d7dabd5da9ef41f28f6d69b29bc084db0ca5a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 25 Jun 2012 18:01:12 -0500 Subject: [PATCH 3069/6849] rtlwifi: rtl8192cu: New USB IDs The latest Realtek driver for the RTL8188CU and RTL8192CU chips adds three new USB IDs. Reported-by: Xose Vazquez Perez Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index d228358e6a40..9970c2b1b199 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -301,9 +301,11 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ + {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ + {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ @@ -346,6 +348,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ + {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ -- GitLab From 7508b657967cf664b5aa0f6367d05016e7e3bc2a Mon Sep 17 00:00:00 2001 From: Panayiotis Karabassis Date: Tue, 26 Jun 2012 23:37:17 +0300 Subject: [PATCH 3070/6849] ath9k: enable serialize_regmode for non-PCIE AR9287 https://bugzilla.kernel.org/show_bug.cgi?id=42903 Based on the work of Signed-off-by: Panayiotis Karabassis Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1c68e564f503..995ca8e1302e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -622,7 +622,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && + ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; -- GitLab From 4b5ebccc40843104d980f0714bc86bfcd5568941 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Jun 2012 15:38:56 +0200 Subject: [PATCH 3071/6849] mac80211: correct behaviour on unrecognised action frames When receiving an "individually addressed" action frame, the receiver is required to return it to the sender. mac80211 gets this wrong as it also returns group addressed (mcast) frames to the sender. Fix this and update the reference to the new 802.11 standards version since things were shuffled around significantly. Cc: stable@kernel.org Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7bcecf73aafb..965e6ec0adb6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2455,7 +2455,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) * frames that we didn't handle, including returning unknown * ones. For all other modes we will return them to the sender, * setting the 0x80 bit in the action category, as required by - * 802.11-2007 7.3.1.11. + * 802.11-2012 9.24.4. * Newer versions of hostapd shall also use the management frame * registration mechanisms, but older ones still use cooked * monitor interfaces so push all frames there. @@ -2465,6 +2465,9 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) return RX_DROP_MONITOR; + if (is_multicast_ether_addr(mgmt->da)) + return RX_DROP_MONITOR; + /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) return RX_DROP_UNUSABLE; -- GitLab From 6bb51c70cabaadddc54a6454844eceba91a56083 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Wed, 27 Jun 2012 18:21:15 +0100 Subject: [PATCH 3072/6849] ath9k: fix panic caused by returning a descriptor we have queued for reuse Commit 3a2923e83c introduced a bug when a corrupt descriptor is encountered - although the following descriptor is discarded and returned to the queue for reuse the associated frame is also returned for processing. This leads to a panic: BUG: unable to handle kernel NULL pointer dereference at 000000000000003a IP: [] ath_rx_tasklet+0x165/0x1b00 [ath9k] Call Trace: [] ? map_single+0x60/0x60 [] ? ath9k_ioread32+0x34/0x90 [ath9k] [] athk9k_tasklet+0xdc/0x160 [ath9k] [] tasklet_action+0x63/0xd0 [] __do_softirq+0xc0/0x1e0 [] ? native_sched_clock+0x13/0x80 [] call_softirq+0x1c/0x30 [] do_softirq+0x75/0xb0 [] irq_exit+0xb5/0xc0 [] do_IRQ+0x63/0xe0 [] common_interrupt+0x6a/0x6a [] ? intel_idle+0xea/0x150 [] ? intel_idle+0xcb/0x150 [] cpuidle_enter+0x19/0x20 [] cpuidle_idle_call+0xa9/0x240 [] cpu_idle+0xaf/0x120 [] rest_init+0x72/0x74 [] start_kernel+0x3b7/0x3c4 [] ? repair_env_string+0x5e/0x5e [] x86_64_start_reservations+0x131/0x135 [] x86_64_start_kernel+0x100/0x10f Making sure bf is cleared to NULL in this case restores the old behaviour. Signed-off-by: Tom Hughes Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 599667ababee..0735aeb3b26c 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -695,9 +695,9 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, __skb_unlink(skb, &rx_edma->rx_fifo); list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); - } else { - bf = NULL; } + + bf = NULL; } *dest = bf; -- GitLab From d2bb2b9e9161d221badafae063d0c62b41bf3078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 25 Jun 2012 22:12:20 +0200 Subject: [PATCH 3073/6849] bcma: define some additional cores IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of them are BCM4706 specific AFAWK. Most of them was confirmed on Netgear WNDR450. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/scan.c | 6 ++++++ include/linux/bcma/bcma.h | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index 5ed0718fc660..a3420585d942 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -28,6 +28,12 @@ static const struct bcma_device_id_name bcma_arm_device_names[] = { static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_OOB_ROUTER, "OOB Router" }, + { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" }, + { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" }, + { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" }, + { BCMA_CORE_AMEMC, "AMEMC (DDR)" }, + { BCMA_CORE_ALTA, "ALTA (I2S)" }, + { BCMA_CORE_4706_MAC_GBIT_COMMON, "BCM4706 GBit MAC Common" }, { BCMA_CORE_INVALID, "Invalid" }, { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, { BCMA_CORE_ILINE20, "ILine 20" }, diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 8deaf6d050c3..12334f9190cb 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -70,6 +70,13 @@ struct bcma_host_ops { /* Core-ID values. */ #define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */ +#define BCMA_CORE_4706_CHIPCOMMON 0x500 +#define BCMA_CORE_4706_SOC_RAM 0x50E +#define BCMA_CORE_4706_MAC_GBIT 0x52D +#define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */ +#define BCMA_CORE_ALTA 0x534 /* I2S core */ +#define BCMA_CORE_4706_MAC_GBIT_COMMON 0x5DC +#define BCMA_CORE_DDR23_PHY 0x5DD #define BCMA_CORE_INVALID 0x700 #define BCMA_CORE_CHIPCOMMON 0x800 #define BCMA_CORE_ILINE20 0x801 -- GitLab From 135e4c6184d29f0834078bf150009a77b9dae717 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Tue, 26 Jun 2012 21:26:34 +0200 Subject: [PATCH 3074/6849] brcmfmac: add support for bus specific data command brcmfmac need to support data command setting for dongle's bus core. A list must be placed at brcmf_bus structure before calling brcmf_bus_start in order to be sent by brcmf_c_preinit_dcmds. Reviewed-by: Arend van Spriel Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_bus.h | 8 ++++++++ .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 16 ++++++++++++++++ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 ++ 3 files changed, 26 insertions(+) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 366916494be4..537f499cc5d2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -36,6 +36,13 @@ struct dngl_stats { unsigned long multicast; /* multicast packets received */ }; +struct brcmf_bus_dcmd { + char *name; + char *param; + int param_len; + struct list_head list; +}; + /* interface structure between common and bus layer */ struct brcmf_bus { u8 type; /* bus type */ @@ -50,6 +57,7 @@ struct brcmf_bus { unsigned long tx_realloc; /* Tx packets realloced for headroom */ struct dngl_stats dstats; /* Stats for dongle-based data */ u8 align; /* bus alignment requirement */ + struct list_head dcmd_list; /* interface functions pointers */ /* Stop bus module: clear pending frames, disable data flow */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 236cb9fa460c..1c9eb1893d29 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -807,6 +807,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) int scan_assoc_time = 40; int scan_unassoc_time = 40; int i; + struct brcmf_bus_dcmd *cmdlst; + struct list_head *cur, *q; mutex_lock(&drvr->proto_block); @@ -874,6 +876,20 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) 0, true); } + /* set bus specific command if there is any */ + list_for_each_safe(cur, q, &drvr->bus_if->dcmd_list) { + cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); + if (cmdlst->name && cmdlst->param && cmdlst->param_len) { + brcmf_c_mkiovar(cmdlst->name, cmdlst->param, + cmdlst->param_len, iovbuf, + sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); + } + list_del(cur); + kfree(cmdlst); + } + mutex_unlock(&drvr->proto_block); return 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 01cf6c03390b..57bf1d7ee80f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1020,6 +1020,8 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); + INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); + return ret; fail: -- GitLab From bbfd6a66ff69e3e1850bead3e30031e303581cb1 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Tue, 26 Jun 2012 21:26:35 +0200 Subject: [PATCH 3075/6849] brcmfmac: restrict dongle txglom disable to old SDIO core txglomming is a firmware feature for sdio bus interface. For SDIO device cores newer than revision 11, the default setting of firmware should be used instead of disabling it from the host side. Reviewed-by: Arend van Spriel Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 6 ------ .../net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 1c9eb1893d29..40fa4726b4a8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -801,7 +801,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) "event_msgs" + '\0' + bitvec */ char buf[128], *ptr; u32 dongle_align = drvr->bus_if->align; - u32 glom = 0; u32 roaming = 1; uint bcn_timeout = 3; int scan_assoc_time = 40; @@ -835,11 +834,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); - /* disable glom option per default */ - brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, - sizeof(iovbuf)); - /* Setup timeout if Beacons are lost and roam is off to report link down */ brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 076b7720ded9..1616c14d5f0c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -4169,6 +4169,9 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; + struct brcmf_bus_dcmd *dlst; + u32 dngl_txglom; + u8 idx; brcmf_dbg(TRACE, "Enter\n"); @@ -4254,6 +4257,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); + /* sdio bus core specific dcmd */ + idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); + dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL); + if (bus->ci->c_inf[idx].rev < 12 && dlst) { + /* for sdio core rev < 12, disable txgloming */ + dngl_txglom = 0; + dlst->name = "bus:txglom"; + dlst->param = (char *)&dngl_txglom; + dlst->param_len = sizeof(u32); + list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list); + } + /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->sdiodev->dev); if (ret != 0) { -- GitLab From c3d2bc35e53dc0dcb85f4f4f06486ecd99143615 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Tue, 26 Jun 2012 21:26:36 +0200 Subject: [PATCH 3076/6849] brcmfmac: move glom alignment setting to SDIO bus layer txglomming alignment is a SDIO bus specific feature. It is more appropriate to place it in SDIO bus layer instead of common layer. Reviewed-by: Arend van Spriel Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/dhd_common.c | 7 ------- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 21 +++++++++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 40fa4726b4a8..2621dd3d7dcd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -800,7 +800,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ char buf[128], *ptr; - u32 dongle_align = drvr->bus_if->align; u32 roaming = 1; uint bcn_timeout = 3; int scan_assoc_time = 40; @@ -828,12 +827,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) /* Print fw version info */ brcmf_dbg(ERROR, "Firmware version = %s\n", buf); - /* Match Host and Dongle rx alignment */ - brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, - sizeof(iovbuf)); - brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, - sizeof(iovbuf)); - /* Setup timeout if Beacons are lost and roam is off to report link down */ brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 1616c14d5f0c..581e7d999737 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -4171,6 +4171,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) struct brcmf_sdio *bus; struct brcmf_bus_dcmd *dlst; u32 dngl_txglom; + u32 dngl_txglomalign; u8 idx; brcmf_dbg(TRACE, "Enter\n"); @@ -4260,12 +4261,20 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) /* sdio bus core specific dcmd */ idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL); - if (bus->ci->c_inf[idx].rev < 12 && dlst) { - /* for sdio core rev < 12, disable txgloming */ - dngl_txglom = 0; - dlst->name = "bus:txglom"; - dlst->param = (char *)&dngl_txglom; - dlst->param_len = sizeof(u32); + if (dlst) { + if (bus->ci->c_inf[idx].rev < 12) { + /* for sdio core rev < 12, disable txgloming */ + dngl_txglom = 0; + dlst->name = "bus:txglom"; + dlst->param = (char *)&dngl_txglom; + dlst->param_len = sizeof(u32); + } else { + /* otherwise, set txglomalign */ + dngl_txglomalign = bus->sdiodev->bus_if->align; + dlst->name = "bus:txglomalign"; + dlst->param = (char *)&dngl_txglomalign; + dlst->param_len = sizeof(u32); + } list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list); } -- GitLab From d610cde30b009ac3dbcd1ae5d7d55fa4c7d066fa Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Tue, 26 Jun 2012 21:26:37 +0200 Subject: [PATCH 3077/6849] brcmfmac: use firmware data buffer directly for nvram The nvram file could be parsed directly in the data buffer in the firmware structure passed by request_firmware function. This patch gets rid of the redundant memcpy. Reviewed-by: Arend van Spriel Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 97 ++++++------------- 1 file changed, 30 insertions(+), 67 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 581e7d999737..a50796c9bd89 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3336,39 +3336,6 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) return rxlen ? (int)rxlen : -ETIMEDOUT; } -static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len) -{ - int bcmerror = 0; - - brcmf_dbg(TRACE, "Enter\n"); - - /* Basic sanity checks */ - if (bus->sdiodev->bus_if->drvr_up) { - bcmerror = -EISCONN; - goto err; - } - if (!len) { - bcmerror = -EOVERFLOW; - goto err; - } - - /* Free the old ones and replace with passed variables */ - kfree(bus->vars); - - bus->vars = kmalloc(len, GFP_ATOMIC); - bus->varsz = bus->vars ? len : 0; - if (bus->vars == NULL) { - bcmerror = -ENOMEM; - goto err; - } - - /* Copy the passed variables, which should include the - terminating double-null */ - memcpy(bus->vars, arg, bus->varsz); -err: - return bcmerror; -} - static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) { int bcmerror = 0; @@ -3573,13 +3540,21 @@ err: * by two NULs. */ -static uint brcmf_process_nvram_vars(char *varbuf, uint len) +static int brcmf_process_nvram_vars(struct brcmf_sdio *bus) { + char *varbuf; char *dp; bool findNewline; int column; - uint buf_len, n; + int ret = 0; + uint buf_len, n, len; + + len = bus->firmware->size; + varbuf = vmalloc(len); + if (!varbuf) + return -ENOMEM; + memcpy(varbuf, bus->firmware->data, len); dp = varbuf; findNewline = false; @@ -3608,56 +3583,44 @@ static uint brcmf_process_nvram_vars(char *varbuf, uint len) column++; } buf_len = dp - varbuf; - while (dp < varbuf + n) *dp++ = 0; - return buf_len; + kfree(bus->vars); + + bus->varsz = buf_len + 1; + bus->vars = kmalloc(bus->varsz, GFP_KERNEL); + if (bus->vars == NULL) { + bus->varsz = 0; + ret = -ENOMEM; + goto err; + } + + /* copy the processed variables and add null termination */ + memcpy(bus->vars, varbuf, buf_len); + bus->vars[buf_len] = 0; +err: + vfree(varbuf); + return ret; } static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) { - uint len; - char *memblock = NULL; - char *bufp; int ret; + if (bus->sdiodev->bus_if->drvr_up) + return -EISCONN; + ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, &bus->sdiodev->func[2]->dev); if (ret) { brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret); return ret; } - bus->fw_ptr = 0; - - memblock = kmalloc(MEMBLOCK, GFP_ATOMIC); - if (memblock == NULL) { - ret = -ENOMEM; - goto err; - } - - len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus); - - if (len > 0 && len < MEMBLOCK) { - bufp = (char *)memblock; - bufp[len] = 0; - len = brcmf_process_nvram_vars(bufp, len); - bufp += len; - *bufp++ = 0; - if (len) - ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1); - if (ret) - brcmf_dbg(ERROR, "error downloading vars: %d\n", ret); - } else { - brcmf_dbg(ERROR, "error reading nvram file: %d\n", len); - ret = -EIO; - } -err: - kfree(memblock); + ret = brcmf_process_nvram_vars(bus); release_firmware(bus->firmware); - bus->fw_ptr = 0; return ret; } -- GitLab From 6d4ef68086f54713b6c9dda478b8e3f749acb3ba Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 26 Jun 2012 21:26:38 +0200 Subject: [PATCH 3078/6849] brcmfmac: reduce allocations needed during nvram data download The nvram data is preprocessed before being sent to the device and just before sending an additional allocation was done that assured word alignment of the data. This has moved to the preprocessing step to reduce allocations and subsequent copying of the nvram data. Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index a50796c9bd89..2ee19c1a0d51 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3339,9 +3339,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) { int bcmerror = 0; - u32 varsize; u32 varaddr; - u8 *vbuffer; u32 varsizew; __le32 varsizew_le; #ifdef DEBUG @@ -3350,56 +3348,44 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) /* Even if there are no vars are to be written, we still need to set the ramsize. */ - varsize = bus->varsz ? roundup(bus->varsz, 4) : 0; - varaddr = (bus->ramsize - 4) - varsize; + varaddr = (bus->ramsize - 4) - bus->varsz; if (bus->vars) { - vbuffer = kzalloc(varsize, GFP_ATOMIC); - if (!vbuffer) - return -ENOMEM; - - memcpy(vbuffer, bus->vars, bus->varsz); - /* Write the vars list */ - bcmerror = - brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); + bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, + bus->vars, bus->varsz); #ifdef DEBUG /* Verify NVRAM bytes */ - brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); - nvram_ularray = kmalloc(varsize, GFP_ATOMIC); - if (!nvram_ularray) { - kfree(vbuffer); + brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", + bus->varsz); + nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC); + if (!nvram_ularray) return -ENOMEM; - } /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, varsize); + memset(nvram_ularray, 0xaa, bus->varsz); /* Read the vars list to temp buffer for comparison */ - bcmerror = - brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray, - varsize); + bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr, + nvram_ularray, bus->varsz); if (bcmerror) { brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n", - bcmerror, varsize, varaddr); + bcmerror, bus->varsz, varaddr); } /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(vbuffer, nvram_ularray, varsize)) + if (memcmp(bus->vars, nvram_ularray, bus->varsz)) brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n"); else brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n"); kfree(nvram_ularray); #endif /* DEBUG */ - - kfree(vbuffer); } /* adjust to the user specified RAM */ brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize); brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n", - varaddr, varsize); - varsize = ((bus->ramsize - 4) - varaddr); + varaddr, bus->varsz); /* * Determine the length token: @@ -3410,13 +3396,13 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) varsizew = 0; varsizew_le = cpu_to_le32(0); } else { - varsizew = varsize / 4; + varsizew = bus->varsz / 4; varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); varsizew_le = cpu_to_le32(varsizew); } brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n", - varsize, varsizew); + bus->varsz, varsizew); /* Write the length token to the last word */ bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4), @@ -3587,8 +3573,8 @@ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus) *dp++ = 0; kfree(bus->vars); - - bus->varsz = buf_len + 1; + /* roundup needed for download to device */ + bus->varsz = roundup(buf_len + 1, 4); bus->vars = kmalloc(bus->varsz, GFP_KERNEL); if (bus->vars == NULL) { bus->varsz = 0; -- GitLab From 85a4a1c3bc42e7ab7027f94984be04e41a7cc496 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Tue, 26 Jun 2012 21:26:39 +0200 Subject: [PATCH 3079/6849] brcmfmac: add BCM4334 support BCM4334 is a dualband a/b/g/n WiFi chip support 20MHz/40MHz channels. This patch adds support for its SDIO interface. Reviewed-by: Arend van Spriel Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 17 +++++++++++++++++ .../wireless/brcm80211/include/brcm_hw_ids.h | 1 + 4 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 82f51dbd0d66..49765d34b4e0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -44,6 +44,7 @@ #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 +#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 #define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC2_BLOCKSIZE 512 @@ -52,6 +53,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2ee19c1a0d51..5c5f1cd8ff22 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3885,6 +3885,8 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid) return true; if (chipid == BCM4330_CHIP_ID) return true; + if (chipid == BCM4334_CHIP_ID) + return true; return false; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index f8e1f1c84d08..58155e23d220 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -403,6 +403,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].cib = 0x03004211; ci->ramsize = 0x48000; break; + case BCM4334_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x29004211; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18002000; + ci->c_inf[1].wrapbase = 0x18102000; + ci->c_inf[1].cib = 0x0d004211; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = 0x18004000; + ci->c_inf[2].wrapbase = 0x18104000; + ci->c_inf[2].cib = 0x13080401; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = 0x18003000; + ci->c_inf[3].wrapbase = 0x18103000; + ci->c_inf[3].cib = 0x07004211; + ci->ramsize = 0x80000; + break; default: brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); return -ENODEV; diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index 333193f20e1c..bcc79b4e3267 100644 --- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h @@ -37,5 +37,6 @@ #define BCM4329_CHIP_ID 0x4329 #define BCM4330_CHIP_ID 0x4330 #define BCM4331_CHIP_ID 0x4331 +#define BCM4334_CHIP_ID 0x4334 #endif /* _BRCM_HW_IDS_H_ */ -- GitLab From 9bd02c6b9e6219829929111c46ef007c7a76865f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 26 Jun 2012 21:26:40 +0200 Subject: [PATCH 3080/6849] brcmfmac: fix sparse warning introduced with checkdied patch The commit "brcmfmac: introduce checkdied debugfs functionality" also introduced a sparse warning: ..../brcmfmac/dhd_sdio.c:3147:45: sparse: cast to restricted __le32 This patch fixes this sparse warning. Reported-by: Fengguang Wu Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 5c5f1cd8ff22..5c868bac1c1c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3145,7 +3145,7 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, le32_to_cpu(tr.type), le32_to_cpu(tr.epc), le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), - le32_to_cpu(tr.pc), le32_to_cpu(sh->trap_addr), + le32_to_cpu(tr.pc), sh->trap_addr, le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), -- GitLab From bf52592fe4901f486a5266fd73e4ee80205b18b4 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 27 Jun 2012 14:15:59 +0530 Subject: [PATCH 3081/6849] ath9k: Fix compilation breakage Wrap the MCI-work canceling with CONFIG_ATH9K_BTCOEX_SUPPORT. Reported-by: Emmanuel Benisty Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c14cf5aa403b..e4e73f061a22 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -151,8 +151,10 @@ static void __ath_cancel_work(struct ath_softc *sc) cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT if (ath9k_hw_mci_is_enabled(sc->sc_ah)) cancel_work_sync(&sc->mci_work); +#endif } static void ath_cancel_work(struct ath_softc *sc) -- GitLab From 6b44695e100ab12f4b2294d834d0b7944d353120 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 26 Jun 2012 19:56:10 -0400 Subject: [PATCH 3082/6849] chmod +x scripts/gfp-translate This script lacks an executable bit. Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- scripts/gfp-translate | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/gfp-translate diff --git a/scripts/gfp-translate b/scripts/gfp-translate old mode 100644 new mode 100755 -- GitLab From c9015b24b262bc7ea56cfd5d78983a73fb5ebd7d Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 27 Jun 2012 12:46:24 -0700 Subject: [PATCH 3083/6849] mwifiex: fix memory leak associated with IE manamgement Free ap_custom_ie before return from function. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/ie.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index ceb82cd749cc..383820a52beb 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c @@ -213,6 +213,7 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, /* save assoc resp ie index after auto-indexing */ *assoc_idx = *((u16 *)pos); + kfree(ap_custom_ie); return ret; } -- GitLab From 89ea25835a5565a0a7abf4e2b423c30408d74a80 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 27 Jun 2012 14:53:46 -0600 Subject: [PATCH 3084/6849] ARM: OMAP AM35xx: clock and hwmod data: fix AM35xx HSOTGUSB hwmod Partially fix the hwmod data for the AM35xx USB OTG hwmod. This should resolve the following boot warning on AM35xx platforms: omap_hwmod: am35x_otg_hs: cannot be enabled for reset (3) While here, also fix the clkdev records, to avoid warnings about duplicate clock aliases. The hwmod is also connected to the wrong interconnect. It should be connected to the IPSS, not the L4 CORE. But that is left for a future fix, since it probably has a dependency on some hwmod core changes. Cc: Felipe Balbi Cc: Hema HK Cc: Mark A. Greer Signed-off-by: Paul Walmsley Tested-by: Mark A. Greer --- arch/arm/mach-omap2/clock3xxx_data.c | 4 ++-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 1efdec236ae8..15e65046471d 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3478,8 +3478,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK("davinci_mdio.0", NULL, &emac_fck, CK_AM35XX), CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX), CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX), - CLK("musb-am35x", "ick", &hsotgusb_ick_am35xx, CK_AM35XX), - CLK("musb-am35x", "fck", &hsotgusb_fck_am35xx, CK_AM35XX), + CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_am35xx, CK_AM35XX), + CLK(NULL, "hsotgusb_fck", &hsotgusb_fck_am35xx, CK_AM35XX), CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX), CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX), CLK("omap_timer.1", "32k_ck", &omap_32k_fck, CK_3XXX), diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index b26d3c9bca16..21428fe6ffa4 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1638,25 +1638,20 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { /* usb_otg_hs */ static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = { - { .name = "mc", .irq = 71 }, { .irq = -1 } }; static struct omap_hwmod_class am35xx_usbotg_class = { .name = "am35xx_usbotg", - .sysc = NULL, }; static struct omap_hwmod am35xx_usbhsotg_hwmod = { .name = "am35x_otg_hs", .mpu_irqs = am35xx_usbhsotg_mpu_irqs, - .main_clk = NULL, - .prcm = { - .omap2 = { - }, - }, + .main_clk = "hsotgusb_fck", .class = &am35xx_usbotg_class, + .flags = HWMOD_NO_IDLEST, }; /* MMC/SD/SDIO common */ @@ -2097,9 +2092,10 @@ static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = { static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = { .master = &am35xx_usbhsotg_hwmod, .slave = &omap3xxx_l3_main_hwmod, - .clk = "core_l3_ick", + .clk = "hsotgusb_ick", .user = OCP_USER_MPU, }; + /* L4_CORE -> L4_WKUP interface */ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { .master = &omap3xxx_l4_core_hwmod, @@ -2393,7 +2389,7 @@ static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = { static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = { .master = &omap3xxx_l4_core_hwmod, .slave = &am35xx_usbhsotg_hwmod, - .clk = "l4_ick", + .clk = "hsotgusb_ick", .addr = am35xx_usbhsotg_addrs, .user = OCP_USER_MPU, }; -- GitLab From bf7652372777c3a6003a05a3e9e462c3dcd0c90d Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 27 Jun 2012 14:53:46 -0600 Subject: [PATCH 3085/6849] ARM: OMAP AM35xx: clock and hwmod data: fix UART4 data Add missing terminators to the arrays of IRQ, DMA, and address space structure records in the AM35xx UART4 hwmod data. Without these terminators, the following warnings appear on boot: omap_uart.3: failed to claim resource 58 omap_device: omap_uart: build failed (-16) WARNING: at /home/paul/linux/arch/arm/mach-omap2/serial.c:375 omap_serial_init_port+0x198/0x284() Could not build omap_device for omap_uart: uart4. Also, AM35xx uart4_fck has an incorrect parent clock pointer. Fix it and clean up a whitespace issue. Fix some incorrectly-named macros related to AM35xx UART4. Cc: Kyle Manna Cc: Mark A. Greer Cc: Ranjith Lohithakshan Signed-off-by: Paul Walmsley Tested-by: Mark A. Greer --- arch/arm/mach-omap2/clock3xxx_data.c | 14 +++++++------- arch/arm/mach-omap2/cm-regbits-34xx.h | 4 ++-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 7 +++++-- arch/arm/mach-omap2/prcm-common.h | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 15e65046471d..58c6e477a4f1 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -2490,13 +2490,13 @@ static struct clk uart4_fck = { }; static struct clk uart4_fck_am35xx = { - .name = "uart4_fck", - .ops = &clkops_omap2_dflt_wait, - .parent = &per_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_UART4_SHIFT, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, + .name = "uart4_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &core_48m_fck, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = AM35XX_EN_UART4_SHIFT, + .clkdm_name = "core_l4_clkdm", + .recalc = &followparent_recalc, }; static struct clk gpt2_fck = { diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 8083a8cdc55f..766338fe4d34 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -169,8 +169,6 @@ /* AM35XX specific CM_ICLKEN1_CORE bits */ #define AM35XX_EN_IPSS_MASK (1 << 4) #define AM35XX_EN_IPSS_SHIFT 4 -#define AM35XX_EN_UART4_MASK (1 << 23) -#define AM35XX_EN_UART4_SHIFT 23 /* CM_ICLKEN2_CORE */ #define OMAP3430_EN_PKA_MASK (1 << 4) @@ -207,6 +205,8 @@ #define OMAP3430_ST_DES2_MASK (1 << 26) #define OMAP3430_ST_MSPRO_SHIFT 23 #define OMAP3430_ST_MSPRO_MASK (1 << 23) +#define AM35XX_ST_UART4_SHIFT 23 +#define AM35XX_ST_UART4_MASK (1 << 23) #define OMAP3430_ST_HDQ_SHIFT 22 #define OMAP3430_ST_HDQ_MASK (1 << 22) #define OMAP3430ES1_ST_FAC_SHIFT 8 diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 21428fe6ffa4..2f4889e514e5 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -527,11 +527,13 @@ static struct omap_hwmod omap36xx_uart4_hwmod = { static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = { { .irq = INT_35XX_UART4_IRQ, }, + { .irq = -1 } }; static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = { { .name = "rx", .dma_req = AM35XX_DMA_UART4_RX, }, { .name = "tx", .dma_req = AM35XX_DMA_UART4_TX, }, + { .dma_req = -1 } }; static struct omap_hwmod am35xx_uart4_hwmod = { @@ -543,9 +545,9 @@ static struct omap_hwmod am35xx_uart4_hwmod = { .omap2 = { .module_offs = CORE_MOD, .prcm_reg_id = 1, - .module_bit = OMAP3430_EN_UART4_SHIFT, + .module_bit = AM35XX_EN_UART4_SHIFT, .idlest_reg_id = 1, - .idlest_idle_bit = OMAP3430_EN_UART4_SHIFT, + .idlest_idle_bit = AM35XX_ST_UART4_SHIFT, }, }, .class = &omap2_uart_class, @@ -2239,6 +2241,7 @@ static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = { .pa_end = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1, .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, }, + { } }; static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = { diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 6da3ba483ad1..cc1398e8b469 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -203,8 +203,8 @@ #define OMAP3430_EN_MMC2_SHIFT 25 #define OMAP3430_EN_MMC1_MASK (1 << 24) #define OMAP3430_EN_MMC1_SHIFT 24 -#define OMAP3430_EN_UART4_MASK (1 << 23) -#define OMAP3430_EN_UART4_SHIFT 23 +#define AM35XX_EN_UART4_MASK (1 << 23) +#define AM35XX_EN_UART4_SHIFT 23 #define OMAP3430_EN_MCSPI4_MASK (1 << 21) #define OMAP3430_EN_MCSPI4_SHIFT 21 #define OMAP3430_EN_MCSPI3_MASK (1 << 20) -- GitLab From 82ee620dc6e1906fe064e93047489f0aea72b75b Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 27 Jun 2012 14:53:46 -0600 Subject: [PATCH 3086/6849] ARM: OMAP: AM35xx: fix UART4 softreset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During kernel init, the AM3505/AM3517 UART4 cannot complete its softreset: omap_hwmod: uart4: softreset failed (waited 10000 usec) This also results in another warning later in the boot process: omap_hwmod: uart4: enabled state can only be entered from initialized, idle, or disabled state From empirical observation, the AM35xx UART4 IP block requires either uart1_fck or uart2_fck to be enabled while UART4 resets. Otherwise the reset will never complete. So this patch adds uart1_fck as an optional clock for UART4 and adds the appropriate hwmod flag to cause uart1_fck to be enabled during the reset process. (The choice of uart1_fck over uart2_fck was arbitrary.) Unfortunately this observation raises many questions. Is it necessary for uart1_fck or uart2_fck to be controlled with uart4_fck for the UART4 to work correctly? What exactly do the AM35xx UART4 clock tree and the related PRCM idle management FSMs look like? If anyone has the ability to answer these questions through empirical functional testing, or hardware information from the AM35xx designers, it would be greatly appreciated. Cc: Benoît Cousson Cc: Kyle Manna Cc: Mark A. Greer Cc: Ranjith Lohithakshan Signed-off-by: Paul Walmsley Tested-by: Mark A. Greer --- arch/arm/mach-omap2/clock3xxx_data.c | 8 ++++++-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 58c6e477a4f1..4a3c1c819adc 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3201,8 +3201,12 @@ static struct clk vpfe_fck = { }; /* - * The UART1/2 functional clock acts as the functional - * clock for UART4. No separate fclk control available. + * The UART1/2 functional clock acts as the functional clock for + * UART4. No separate fclk control available. XXX Well now we have a + * uart4_fck that is apparently used as the UART4 functional clock, + * but it also seems that uart1_fck or uart2_fck are still needed, at + * least for UART4 softresets to complete. This really needs + * clarification. */ static struct clk uart4_ick_am35xx = { .name = "uart4_ick", diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 2f4889e514e5..1120d388eca3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -536,6 +536,20 @@ static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = { { .dma_req = -1 } }; +/* + * XXX AM35xx UART4 cannot complete its softreset without uart1_fck or + * uart2_fck being enabled. So we add uart1_fck as an optional clock, + * below, and set the HWMOD_CONTROL_OPT_CLKS_IN_RESET. This really + * should not be needed. The functional clock structure of the AM35xx + * UART4 is extremely unclear and opaque; it is unclear what the role + * of uart1/2_fck is for the UART4. Any clarification from either + * empirical testing or the AM3505/3517 hardware designers would be + * most welcome. + */ +static struct omap_hwmod_opt_clk am35xx_uart4_opt_clks[] = { + { .role = "softreset_uart1_fck", .clk = "uart1_fck" }, +}; + static struct omap_hwmod am35xx_uart4_hwmod = { .name = "uart4", .mpu_irqs = am35xx_uart4_mpu_irqs, @@ -550,6 +564,9 @@ static struct omap_hwmod am35xx_uart4_hwmod = { .idlest_idle_bit = AM35XX_ST_UART4_SHIFT, }, }, + .opt_clks = am35xx_uart4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(am35xx_uart4_opt_clks), + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .class = &omap2_uart_class, }; -- GitLab From 31ba88083fec3b141fc1863a2dc0822c474a89a2 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 27 Jun 2012 14:59:57 -0600 Subject: [PATCH 3087/6849] ARM: OMAP AM35x: EMAC/MDIO integration: Add Davinci EMAC/MDIO hwmod support Add hwmod support for the EMAC (and MDIO) ethernet controller that's on the am35x family of SoC's. Signed-off-by: Mark A. Greer [paul@pwsan.com: updated subject line; updated to apply on v3.5-rc4; added comments to hwmod data regarding IPSS] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/am35xx-emac.c | 90 +++++++++--------- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/include/mach/am35xx.h | 2 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 105 +++++++++++++++++++++ 4 files changed, 154 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c index 447682c4e11c..2c90ac686686 100644 --- a/arch/arm/mach-omap2/am35xx-emac.c +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -15,27 +15,13 @@ * General Public License for more details. */ -#include +#include #include -#include -#include +#include +#include #include - #include "control.h" - -static struct mdio_platform_data am35xx_emac_mdio_pdata; - -static struct resource am35xx_emac_mdio_resources[] = { - DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, SZ_4K), -}; - -static struct platform_device am35xx_emac_mdio_device = { - .name = "davinci_mdio", - .id = 0, - .num_resources = ARRAY_SIZE(am35xx_emac_mdio_resources), - .resource = am35xx_emac_mdio_resources, - .dev.platform_data = &am35xx_emac_mdio_pdata, -}; +#include "am35xx-emac.h" static void am35xx_enable_emac_int(void) { @@ -69,41 +55,57 @@ static struct emac_platform_data am35xx_emac_pdata = { .interrupt_disable = am35xx_disable_emac_int, }; -static struct resource am35xx_emac_resources[] = { - DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000), - DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ), - DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ), - DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ), - DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ), -}; +static struct mdio_platform_data am35xx_mdio_pdata; -static struct platform_device am35xx_emac_device = { - .name = "davinci_emac", - .id = -1, - .num_resources = ARRAY_SIZE(am35xx_emac_resources), - .resource = am35xx_emac_resources, - .dev = { - .platform_data = &am35xx_emac_pdata, - }, -}; +static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh, + void *pdata, int pdata_len) +{ + struct platform_device *pdev; + + pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, + NULL, 0, false); + if (IS_ERR(pdev)) { + WARN(1, "Can't build omap_device for %s:%s.\n", + oh->class->name, oh->name); + return PTR_ERR(pdev); + } + + return 0; +} void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) { + struct omap_hwmod *oh; u32 v; - int err; + int ret; - am35xx_emac_pdata.rmii_en = rmii_en; - am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq; - err = platform_device_register(&am35xx_emac_device); - if (err) { - pr_err("AM35x: failed registering EMAC device: %d\n", err); + oh = omap_hwmod_lookup("davinci_mdio"); + if (!oh) { + pr_err("Could not find davinci_mdio hwmod\n"); + return; + } + + am35xx_mdio_pdata.bus_freq = mdio_bus_freq; + + ret = omap_davinci_emac_dev_init(oh, &am35xx_mdio_pdata, + sizeof(am35xx_mdio_pdata)); + if (ret) { + pr_err("Could not build davinci_mdio hwmod device\n"); return; } - err = platform_device_register(&am35xx_emac_mdio_device); - if (err) { - pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err); - platform_device_unregister(&am35xx_emac_device); + oh = omap_hwmod_lookup("davinci_emac"); + if (!oh) { + pr_err("Could not find davinci_emac hwmod\n"); + return; + } + + am35xx_emac_pdata.rmii_en = rmii_en; + + ret = omap_davinci_emac_dev_init(oh, &am35xx_emac_pdata, + sizeof(am35xx_emac_pdata)); + if (ret) { + pr_err("Could not build davinci_emac hwmod device\n"); return; } diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 1efdec236ae8..10c139580ff1 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3474,7 +3474,7 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX), CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX), CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX), - CLK("davinci_emac", NULL, &emac_ick, CK_AM35XX), + CLK("davinci_emac.0", NULL, &emac_ick, CK_AM35XX), CLK("davinci_mdio.0", NULL, &emac_fck, CK_AM35XX), CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX), CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX), diff --git a/arch/arm/mach-omap2/include/mach/am35xx.h b/arch/arm/mach-omap2/include/mach/am35xx.h index f1e13d1ca5e7..95594495fcf6 100644 --- a/arch/arm/mach-omap2/include/mach/am35xx.h +++ b/arch/arm/mach-omap2/include/mach/am35xx.h @@ -36,6 +36,8 @@ #define AM35XX_EMAC_CNTRL_MOD_OFFSET (0x0) #define AM35XX_EMAC_CNTRL_RAM_OFFSET (0x20000) #define AM35XX_EMAC_MDIO_OFFSET (0x30000) +#define AM35XX_IPSS_MDIO_BASE (AM35XX_IPSS_EMAC_BASE + \ + AM35XX_EMAC_MDIO_OFFSET) #define AM35XX_EMAC_CNTRL_RAM_SIZE (0x2000) #define AM35XX_EMAC_RAM_ADDR (AM3517_EMAC_BASE + \ AM3517_EMAC_CNTRL_RAM_OFFSET) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index b26d3c9bca16..a16b832f1d9c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3138,6 +3138,107 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* am35xx has Davinci MDIO & EMAC */ +static struct omap_hwmod_class am35xx_mdio_class = { + .name = "davinci_mdio", +}; + +static struct omap_hwmod am35xx_mdio_hwmod = { + .name = "davinci_mdio", + .class = &am35xx_mdio_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* + * XXX Should be connected to an IPSS hwmod, not the L3 directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_mdio__l3 = { + .master = &am35xx_mdio_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "emac_fck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am35xx_mdio_addrs[] = { + { + .pa_start = AM35XX_IPSS_MDIO_BASE, + .pa_end = AM35XX_IPSS_MDIO_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> davinci mdio */ +/* + * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_l4_core__mdio = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_mdio_hwmod, + .clk = "emac_fck", + .addr = am35xx_mdio_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_irq_info am35xx_emac_mpu_irqs[] = { + { .name = "rxthresh", .irq = INT_35XX_EMAC_C0_RXTHRESH_IRQ }, + { .name = "rx_pulse", .irq = INT_35XX_EMAC_C0_RX_PULSE_IRQ }, + { .name = "tx_pulse", .irq = INT_35XX_EMAC_C0_TX_PULSE_IRQ }, + { .name = "misc_pulse", .irq = INT_35XX_EMAC_C0_MISC_PULSE_IRQ }, + { .irq = -1 } +}; + +static struct omap_hwmod_class am35xx_emac_class = { + .name = "davinci_emac", +}; + +static struct omap_hwmod am35xx_emac_hwmod = { + .name = "davinci_emac", + .mpu_irqs = am35xx_emac_mpu_irqs, + .class = &am35xx_emac_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* l3_core -> davinci emac interface */ +/* + * XXX Should be connected to an IPSS hwmod, not the L3 directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_emac__l3 = { + .master = &am35xx_emac_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "emac_ick", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am35xx_emac_addrs[] = { + { + .pa_start = AM35XX_IPSS_EMAC_BASE, + .pa_end = AM35XX_IPSS_EMAC_BASE + 0x30000 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> davinci emac */ +/* + * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_l4_core__emac = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_emac_hwmod, + .clk = "emac_ick", + .addr = am35xx_emac_addrs, + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l3_main__l4_core, &omap3xxx_l3_main__l4_per, @@ -3266,6 +3367,10 @@ static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_core__usb_tll_hs, &omap3xxx_l4_core__es3plus_mmc1, &omap3xxx_l4_core__es3plus_mmc2, + &am35xx_mdio__l3, + &am35xx_l4_core__mdio, + &am35xx_emac__l3, + &am35xx_l4_core__emac, NULL }; -- GitLab From d31bb4f0621756528d11d310c44cd8076b22bc03 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 26 Jun 2012 23:01:41 +0000 Subject: [PATCH 3088/6849] 9p: fix min_t() casting in p9pdu_vwritef() I don't think we're actually likely to hit this limit but if we do then the comparison should be done as size_t. The original code is equivalent to: len = strlen(sptr) % USHRT_MAX; Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/9p/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 9ee48cb30179..3d33ecf13327 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -368,7 +368,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, const char *sptr = va_arg(ap, const char *); uint16_t len = 0; if (sptr) - len = min_t(uint16_t, strlen(sptr), + len = min_t(size_t, strlen(sptr), USHRT_MAX); errcode = p9pdu_writef(pdu, proto_version, -- GitLab From c074da2810c118b3812f32d6754bd9ead2f169e7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 26 Jun 2012 23:14:15 +0000 Subject: [PATCH 3089/6849] ipv4: tcp: dont cache unconfirmed intput dst DDOS synflood attacks hit badly IP route cache. On typical machines, this cache is allowed to hold up to 8 Millions dst entries, 256 bytes for each, for a total of 2GB of memory. rt_garbage_collect() triggers and tries to cleanup things. Eventually route cache is disabled but machine is under fire and might OOM and crash. This patch exploits the new TCP early demux, to set a nocache boolean in case incoming TCP frame is for a not yet ESTABLISHED or TIMEWAIT socket. This 'nocache' boolean is then used in case dst entry is not found in route cache, to create an unhashed dst entry (DST_NOCACHE) SYN-cookie-ACK sent use a similar mechanism (ipv4: tcp: dont cache output dst for syncookies), so after this patch, a machine is able to absorb a DDOS synflood attack without polluting its IP route cache. Signed-off-by: Eric Dumazet Cc: Hans Schillstrom Signed-off-by: David S. Miller --- include/net/protocol.h | 2 +- include/net/route.h | 8 ++++---- include/net/tcp.h | 2 +- net/ipv4/arp.c | 2 +- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_input.c | 5 +++-- net/ipv4/route.c | 8 +++++--- net/ipv4/tcp_ipv4.c | 4 +++- net/ipv4/xfrm4_input.c | 2 +- 9 files changed, 20 insertions(+), 15 deletions(-) diff --git a/include/net/protocol.h b/include/net/protocol.h index 967b926cbfb1..7cfc8f76914d 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -37,7 +37,7 @@ /* This is used to register protocols. */ struct net_protocol { - int (*early_demux)(struct sk_buff *skb); + int (*early_demux)(struct sk_buff *skb, bool *nocache); int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); int (*gso_send_check)(struct sk_buff *skb); diff --git a/include/net/route.h b/include/net/route.h index 47eb25ac1f7f..6361f9335774 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -201,18 +201,18 @@ static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 } extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, - u8 tos, struct net_device *devin, bool noref); + u8 tos, struct net_device *devin, bool noref, bool nocache); static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin) { - return ip_route_input_common(skb, dst, src, tos, devin, false); + return ip_route_input_common(skb, dst, src, tos, devin, false, false); } static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src, - u8 tos, struct net_device *devin) + u8 tos, struct net_device *devin, bool nocache) { - return ip_route_input_common(skb, dst, src, tos, devin, true); + return ip_route_input_common(skb, dst, src, tos, devin, true, nocache); } extern void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, diff --git a/include/net/tcp.h b/include/net/tcp.h index 6660ffc4963d..917ed2e55e8c 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -325,7 +325,7 @@ extern void tcp_v4_err(struct sk_buff *skb, u32); extern void tcp_shutdown (struct sock *sk, int how); -extern int tcp_v4_early_demux(struct sk_buff *skb); +extern int tcp_v4_early_demux(struct sk_buff *skb, bool *nocache); extern int tcp_v4_rcv(struct sk_buff *skb); extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 2e560f0c757d..6a9795944369 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -828,7 +828,7 @@ static int arp_process(struct sk_buff *skb) } if (arp->ar_op == htons(ARPOP_REQUEST) && - ip_route_input_noref(skb, tip, sip, 0, dev) == 0) { + ip_route_input_noref(skb, tip, sip, 0, dev, false) == 0) { rt = skb_rtable(skb); addr_type = rt->rt_type; diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 8d07c973409c..978d55f256ea 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -259,7 +259,7 @@ static void ip_expire(unsigned long arg) skb_dst_drop(head); iph = ip_hdr(head); err = ip_route_input_noref(head, iph->daddr, iph->saddr, - iph->tos, head->dev); + iph->tos, head->dev, false); if (err) goto out_rcu_unlock; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2a39204de5bc..7be54c8dcbe2 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -326,6 +326,7 @@ static int ip_rcv_finish(struct sk_buff *skb) */ if (skb_dst(skb) == NULL) { int err = -ENOENT; + bool nocache = false; if (sysctl_ip_early_demux) { const struct net_protocol *ipprot; @@ -334,13 +335,13 @@ static int ip_rcv_finish(struct sk_buff *skb) rcu_read_lock(); ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot && ipprot->early_demux) - err = ipprot->early_demux(skb); + err = ipprot->early_demux(skb, &nocache); rcu_read_unlock(); } if (err) { err = ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb->dev); + iph->tos, skb->dev, nocache); if (unlikely(err)) { if (err == -EXDEV) NET_INC_STATS_BH(dev_net(skb->dev), diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 81533e3a23d1..fdc7900f9d7a 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2214,7 +2214,7 @@ static int ip_mkroute_input(struct sk_buff *skb, */ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, - u8 tos, struct net_device *dev) + u8 tos, struct net_device *dev, bool nocache) { struct fib_result res; struct in_device *in_dev = __in_dev_get_rcu(dev); @@ -2353,6 +2353,8 @@ local_input: rth->dst.error= -err; rth->rt_flags &= ~RTCF_LOCAL; } + if (nocache) + rth->dst.flags |= DST_NOCACHE; hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net)); rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif); err = 0; @@ -2395,7 +2397,7 @@ martian_source_keep_err: } int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, - u8 tos, struct net_device *dev, bool noref) + u8 tos, struct net_device *dev, bool noref, bool nocache) { struct rtable *rth; unsigned int hash; @@ -2471,7 +2473,7 @@ skip_cache: rcu_read_unlock(); return -EINVAL; } - res = ip_route_input_slow(skb, daddr, saddr, tos, dev); + res = ip_route_input_slow(skb, daddr, saddr, tos, dev, nocache); rcu_read_unlock(); return res; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1781dc650b9d..33aabd4fc20f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1673,7 +1673,7 @@ csum_err: } EXPORT_SYMBOL(tcp_v4_do_rcv); -int tcp_v4_early_demux(struct sk_buff *skb) +int tcp_v4_early_demux(struct sk_buff *skb, bool *no_dst_cache) { struct net *net = dev_net(skb->dev); const struct iphdr *iph; @@ -1719,6 +1719,8 @@ int tcp_v4_early_demux(struct sk_buff *skb) } } } + } else { + *no_dst_cache = true; } out_err: diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 06814b6216dc..eee636b191b9 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -28,7 +28,7 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) const struct iphdr *iph = ip_hdr(skb); if (ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb->dev)) + iph->tos, skb->dev, false)) goto drop; } return dst_input(skb); -- GitLab From 4245375db87767aacaad16f07040b5d89a9056c8 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:10 +0000 Subject: [PATCH 3090/6849] unix_diag: Do not use RTA_PUT() macros Also, no need to trim on nlmsg_put() failure, nothing has been added yet. We also want to use nlmsg_end(), nlmsg_new() and nlmsg_free(). Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/unix/diag.c | 80 ++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/net/unix/diag.c b/net/unix/diag.c index 977ca317550d..a74864eedfcd 100644 --- a/net/unix/diag.c +++ b/net/unix/diag.c @@ -8,40 +8,31 @@ #include #include -#define UNIX_DIAG_PUT(skb, attrtype, attrlen) \ - RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) - static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb) { struct unix_address *addr = unix_sk(sk)->addr; - char *s; - - if (addr) { - s = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_NAME, addr->len - sizeof(short)); - memcpy(s, addr->name->sun_path, addr->len - sizeof(short)); - } - return 0; + if (!addr) + return 0; -rtattr_failure: - return -EMSGSIZE; + return nla_put(nlskb, UNIX_DIAG_NAME, addr->len - sizeof(short), + addr->name->sun_path); } static int sk_diag_dump_vfs(struct sock *sk, struct sk_buff *nlskb) { struct dentry *dentry = unix_sk(sk)->path.dentry; - struct unix_diag_vfs *uv; if (dentry) { - uv = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_VFS, sizeof(*uv)); - uv->udiag_vfs_ino = dentry->d_inode->i_ino; - uv->udiag_vfs_dev = dentry->d_sb->s_dev; + struct unix_diag_vfs uv = { + .udiag_vfs_ino = dentry->d_inode->i_ino, + .udiag_vfs_dev = dentry->d_sb->s_dev, + }; + + return nla_put(nlskb, UNIX_DIAG_VFS, sizeof(uv), &uv); } return 0; - -rtattr_failure: - return -EMSGSIZE; } static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb) @@ -56,24 +47,28 @@ static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb) unix_state_unlock(peer); sock_put(peer); - RTA_PUT_U32(nlskb, UNIX_DIAG_PEER, ino); + return nla_put_u32(nlskb, UNIX_DIAG_PEER, ino); } return 0; -rtattr_failure: - return -EMSGSIZE; } static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) { struct sk_buff *skb; + struct nlattr *attr; u32 *buf; int i; if (sk->sk_state == TCP_LISTEN) { spin_lock(&sk->sk_receive_queue.lock); - buf = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_ICONS, - sk->sk_receive_queue.qlen * sizeof(u32)); + + attr = nla_reserve(nlskb, UNIX_DIAG_ICONS, + sk->sk_receive_queue.qlen * sizeof(u32)); + if (!attr) + goto errout; + + buf = nla_data(attr); i = 0; skb_queue_walk(&sk->sk_receive_queue, skb) { struct sock *req, *peer; @@ -94,45 +89,38 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) return 0; -rtattr_failure: +errout: spin_unlock(&sk->sk_receive_queue.lock); return -EMSGSIZE; } static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) { - struct unix_diag_rqlen *rql; - - rql = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_RQLEN, sizeof(*rql)); + struct unix_diag_rqlen rql; if (sk->sk_state == TCP_LISTEN) { - rql->udiag_rqueue = sk->sk_receive_queue.qlen; - rql->udiag_wqueue = sk->sk_max_ack_backlog; + rql.udiag_rqueue = sk->sk_receive_queue.qlen; + rql.udiag_wqueue = sk->sk_max_ack_backlog; } else { - rql->udiag_rqueue = (__u32)unix_inq_len(sk); - rql->udiag_wqueue = (__u32)unix_outq_len(sk); + rql.udiag_rqueue = (u32) unix_inq_len(sk); + rql.udiag_wqueue = (u32) unix_outq_len(sk); } - return 0; - -rtattr_failure: - return -EMSGSIZE; + return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql); } static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req, u32 pid, u32 seq, u32 flags, int sk_ino) { - unsigned char *b = skb_tail_pointer(skb); struct nlmsghdr *nlh; struct unix_diag_msg *rep; - nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep), 0); + nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep), + flags); if (!nlh) - goto out_nlmsg_trim; - nlh->nlmsg_flags = flags; + return -EMSGSIZE; rep = nlmsg_data(nlh); - rep->udiag_family = AF_UNIX; rep->udiag_type = sk->sk_type; rep->udiag_state = sk->sk_state; @@ -163,11 +151,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) goto out_nlmsg_trim; - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; + return nlmsg_end(skb, nlh); out_nlmsg_trim: - nlmsg_trim(skb, b); + nlmsg_cancel(skb, nlh); return -EMSGSIZE; } @@ -272,15 +259,14 @@ static int unix_diag_get_exact(struct sk_buff *in_skb, extra_len = 256; again: err = -ENOMEM; - rep = alloc_skb(NLMSG_SPACE((sizeof(struct unix_diag_msg) + extra_len)), - GFP_KERNEL); + rep = nlmsg_new(sizeof(struct unix_diag_msg) + extra_len, GFP_KERNEL); if (!rep) goto out; err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 0, req->udiag_ino); if (err < 0) { - kfree_skb(rep); + nlmsg_free(rep); extra_len += 256; if (extra_len >= PAGE_SIZE) goto out; -- GitLab From 7b46866dd0a6fe38ecee523eb27eda9c8f484dc5 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:11 +0000 Subject: [PATCH 3091/6849] sock_diag: Do not use RTA_PUT() macros Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/core/sock_diag.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 0d934ce1075f..ff2967acbfae 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -35,9 +34,7 @@ EXPORT_SYMBOL_GPL(sock_diag_save_cookie); int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype) { - __u32 *mem; - - mem = RTA_DATA(__RTA_PUT(skb, attrtype, SK_MEMINFO_VARS * sizeof(__u32))); + u32 mem[SK_MEMINFO_VARS]; mem[SK_MEMINFO_RMEM_ALLOC] = sk_rmem_alloc_get(sk); mem[SK_MEMINFO_RCVBUF] = sk->sk_rcvbuf; @@ -48,10 +45,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype) mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len; - return 0; - -rtattr_failure: - return -EMSGSIZE; + return nla_put(skb, attrtype, sizeof(mem), &mem); } EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); @@ -121,7 +115,7 @@ static inline void sock_diag_unlock_handler(const struct sock_diag_handler *h) static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int err; - struct sock_diag_req *req = NLMSG_DATA(nlh); + struct sock_diag_req *req = nlmsg_data(nlh); const struct sock_diag_handler *hndl; if (nlmsg_len(nlh) < sizeof(*req)) -- GitLab From 6e277ed59a45544786f4c4643a69527138c24fc1 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:12 +0000 Subject: [PATCH 3092/6849] inet_diag: Do not use RTA_PUT() macros Also, no need to trim on nlmsg_put() failure, nothing has been added yet. We also want to use nlmsg_end(), nlmsg_new() and nlmsg_free(). Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv4/inet_diag.c | 112 ++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 59 deletions(-) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 27640e734cfd..38064a285cca 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -46,9 +46,6 @@ struct inet_diag_entry { u16 userlocks; }; -#define INET_DIAG_PUT(skb, attrtype, attrlen) \ - RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) - static DEFINE_MUTEX(inet_diag_table_mutex); static const struct inet_diag_handler *inet_diag_lock_handler(int proto) @@ -78,28 +75,22 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, const struct inet_sock *inet = inet_sk(sk); struct inet_diag_msg *r; struct nlmsghdr *nlh; + struct nlattr *attr; void *info = NULL; - struct inet_diag_meminfo *minfo = NULL; - unsigned char *b = skb_tail_pointer(skb); const struct inet_diag_handler *handler; int ext = req->idiag_ext; handler = inet_diag_table[req->sdiag_protocol]; BUG_ON(handler == NULL); - nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 0); - if (!nlh) { - nlmsg_trim(skb, b); + nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), + nlmsg_flags); + if (!nlh) return -EMSGSIZE; - } - nlh->nlmsg_flags = nlmsg_flags; r = nlmsg_data(nlh); BUG_ON(sk->sk_state == TCP_TIME_WAIT); - if (ext & (1 << (INET_DIAG_MEMINFO - 1))) - minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo)); - r->idiag_family = sk->sk_family; r->idiag_state = sk->sk_state; r->idiag_timer = 0; @@ -117,7 +108,8 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, * hence this needs to be included regardless of socket family. */ if (ext & (1 << (INET_DIAG_TOS - 1))) - RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos); + if (nla_put_u8(skb, INET_DIAG_TOS, inet->tos) < 0) + goto errout; #if IS_ENABLED(CONFIG_IPV6) if (r->idiag_family == AF_INET6) { @@ -125,24 +117,31 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, *(struct in6_addr *)r->id.idiag_src = np->rcv_saddr; *(struct in6_addr *)r->id.idiag_dst = np->daddr; + if (ext & (1 << (INET_DIAG_TCLASS - 1))) - RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass); + if (nla_put_u8(skb, INET_DIAG_TCLASS, np->tclass) < 0) + goto errout; } #endif r->idiag_uid = sock_i_uid(sk); r->idiag_inode = sock_i_ino(sk); - if (minfo) { - minfo->idiag_rmem = sk_rmem_alloc_get(sk); - minfo->idiag_wmem = sk->sk_wmem_queued; - minfo->idiag_fmem = sk->sk_forward_alloc; - minfo->idiag_tmem = sk_wmem_alloc_get(sk); + if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { + struct inet_diag_meminfo minfo = { + .idiag_rmem = sk_rmem_alloc_get(sk), + .idiag_wmem = sk->sk_wmem_queued, + .idiag_fmem = sk->sk_forward_alloc, + .idiag_tmem = sk_wmem_alloc_get(sk), + }; + + if (nla_put(skb, INET_DIAG_MEMINFO, sizeof(minfo), &minfo) < 0) + goto errout; } if (ext & (1 << (INET_DIAG_SKMEMINFO - 1))) if (sock_diag_put_meminfo(sk, skb, INET_DIAG_SKMEMINFO)) - goto rtattr_failure; + goto errout; if (icsk == NULL) { handler->idiag_get_info(sk, r, NULL); @@ -169,16 +168,20 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, } #undef EXPIRES_IN_MS - if (ext & (1 << (INET_DIAG_INFO - 1))) - info = INET_DIAG_PUT(skb, INET_DIAG_INFO, sizeof(struct tcp_info)); + if (ext & (1 << (INET_DIAG_INFO - 1))) { + attr = nla_reserve(skb, INET_DIAG_INFO, + sizeof(struct tcp_info)); + if (!attr) + goto errout; - if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) { - const size_t len = strlen(icsk->icsk_ca_ops->name); - - strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1), - icsk->icsk_ca_ops->name); + info = nla_data(attr); } + if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) + if (nla_put_string(skb, INET_DIAG_CONG, + icsk->icsk_ca_ops->name) < 0) + goto errout; + handler->idiag_get_info(sk, r, info); if (sk->sk_state < TCP_TIME_WAIT && @@ -186,11 +189,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, icsk->icsk_ca_ops->get_info(sk, ext, skb); out: - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; + return nlmsg_end(skb, nlh); -rtattr_failure: - nlmsg_trim(skb, b); +errout: + nlmsg_cancel(skb, nlh); return -EMSGSIZE; } EXPORT_SYMBOL_GPL(inet_sk_diag_fill); @@ -211,20 +213,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, { long tmo; struct inet_diag_msg *r; - const unsigned char *previous_tail = skb_tail_pointer(skb); - struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, - unlh->nlmsg_type, sizeof(*r), 0); + struct nlmsghdr *nlh; - if (!nlh) { - nlmsg_trim(skb, previous_tail); + nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), + nlmsg_flags); + if (!nlh) return -EMSGSIZE; - } r = nlmsg_data(nlh); BUG_ON(tw->tw_state != TCP_TIME_WAIT); - nlh->nlmsg_flags = nlmsg_flags; - tmo = tw->tw_ttd - jiffies; if (tmo < 0) tmo = 0; @@ -253,8 +251,8 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, *(struct in6_addr *)r->id.idiag_dst = tw6->tw_v6_daddr; } #endif - nlh->nlmsg_len = skb_tail_pointer(skb) - previous_tail; - return skb->len; + + return nlmsg_end(skb, nlh); } static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, @@ -303,20 +301,20 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s if (err) goto out; - err = -ENOMEM; - rep = alloc_skb(NLMSG_SPACE((sizeof(struct inet_diag_msg) + - sizeof(struct inet_diag_meminfo) + - sizeof(struct tcp_info) + 64)), - GFP_KERNEL); - if (!rep) + rep = nlmsg_new(sizeof(struct inet_diag_msg) + + sizeof(struct inet_diag_meminfo) + + sizeof(struct tcp_info) + 64, GFP_KERNEL); + if (!rep) { + err = -ENOMEM; goto out; + } err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 0, nlh); if (err < 0) { WARN_ON(err == -EMSGSIZE); - kfree_skb(rep); + nlmsg_free(rep); goto out; } err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, @@ -597,19 +595,16 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, { const struct inet_request_sock *ireq = inet_rsk(req); struct inet_sock *inet = inet_sk(sk); - unsigned char *b = skb_tail_pointer(skb); struct inet_diag_msg *r; struct nlmsghdr *nlh; long tmo; - nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 0); - if (!nlh) { - nlmsg_trim(skb, b); - return -1; - } - nlh->nlmsg_flags = NLM_F_MULTI; - r = nlmsg_data(nlh); + nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), + NLM_F_MULTI); + if (!nlh) + return -EMSGSIZE; + r = nlmsg_data(nlh); r->idiag_family = sk->sk_family; r->idiag_state = TCP_SYN_RECV; r->idiag_timer = 1; @@ -637,9 +632,8 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; } #endif - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; + return nlmsg_end(skb, nlh); } static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, -- GitLab From 92a395e52f0c97f38ff675d7c698404bfc812dc2 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:13 +0000 Subject: [PATCH 3093/6849] ipmr: Do not use RTA_PUT() macros Also fix a needless skb tailroom check for a 4 bytes area after after each rtnexthop block. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv4/ipmr.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c94bbc6f2ba3..b4ac39f11d19 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -2006,37 +2006,37 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, { int ct; struct rtnexthop *nhp; - u8 *b = skb_tail_pointer(skb); - struct rtattr *mp_head; + struct nlattr *mp_attr; /* If cache is unresolved, don't try to parse IIF and OIF */ if (c->mfc_parent >= MAXVIFS) return -ENOENT; - if (VIF_EXISTS(mrt, c->mfc_parent)) - RTA_PUT(skb, RTA_IIF, 4, &mrt->vif_table[c->mfc_parent].dev->ifindex); + if (VIF_EXISTS(mrt, c->mfc_parent) && + nla_put_u32(skb, RTA_IIF, mrt->vif_table[c->mfc_parent].dev->ifindex) < 0) + return -EMSGSIZE; - mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); + if (!(mp_attr = nla_nest_start(skb, RTA_MULTIPATH))) + return -EMSGSIZE; for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) { - if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) - goto rtattr_failure; - nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); + if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) { + nla_nest_cancel(skb, mp_attr); + return -EMSGSIZE; + } + nhp->rtnh_flags = 0; nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex; nhp->rtnh_len = sizeof(*nhp); } } - mp_head->rta_type = RTA_MULTIPATH; - mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head; + + nla_nest_end(skb, mp_attr); + rtm->rtm_type = RTN_MULTICAST; return 1; - -rtattr_failure: - nlmsg_trim(skb, b); - return -EMSGSIZE; } int ipmr_get_route(struct net *net, struct sk_buff *skb, -- GitLab From 74a0bd7d0ef4ed11345aaebc29bf4578ccf44087 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:14 +0000 Subject: [PATCH 3094/6849] ip6mr: Do not use RTA_PUT() macros Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv6/ip6mr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 461e47c8e956..4532973f0dd4 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -2104,8 +2104,9 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, if (c->mf6c_parent >= MAXMIFS) return -ENOENT; - if (MIF_EXISTS(mrt, c->mf6c_parent)) - RTA_PUT(skb, RTA_IIF, 4, &mrt->vif6_table[c->mf6c_parent].dev->ifindex); + if (MIF_EXISTS(mrt, c->mf6c_parent) && + nla_put_u32(skb, RTA_IIF, mrt->vif6_table[c->mf6c_parent].dev->ifindex) < 0) + return -EMSGSIZE; mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); -- GitLab From 6b60978fde2b09a15d7aec0e15f2d3863bad2d24 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:15 +0000 Subject: [PATCH 3095/6849] decnet: Do not use RTA_PUT() macros Also, no need to trim on nlmsg_put() failure, nothing has been added yet. We also want to use nlmsg_end(), nlmsg_new() and nlmsg_free(). Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/decnet/dn_route.c | 61 +++++++++++++++++++++++--------------- net/decnet/dn_table.c | 69 +++++++++++++++++++++++++------------------ 2 files changed, 79 insertions(+), 51 deletions(-) diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index cd584f7de4dd..2493ed5bfecd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1515,56 +1515,68 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, struct dn_route *rt = (struct dn_route *)skb_dst(skb); struct rtmsg *r; struct nlmsghdr *nlh; - unsigned char *b = skb_tail_pointer(skb); long expires; nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); if (!nlh) - goto out_nlmsg_trim; + return -EMSGSIZE; + r = nlmsg_data(nlh); r->rtm_family = AF_DECnet; r->rtm_dst_len = 16; r->rtm_src_len = 0; r->rtm_tos = 0; r->rtm_table = RT_TABLE_MAIN; - RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); r->rtm_type = rt->rt_type; r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; r->rtm_scope = RT_SCOPE_UNIVERSE; r->rtm_protocol = RTPROT_UNSPEC; + if (rt->rt_flags & RTCF_NOTIFY) r->rtm_flags |= RTM_F_NOTIFY; - RTA_PUT(skb, RTA_DST, 2, &rt->rt_daddr); + + if (nla_put_u32(skb, RTA_TABLE, RT_TABLE_MAIN) < 0 || + nla_put_le16(skb, RTA_DST, rt->rt_daddr) < 0) + goto errout; + if (rt->fld.saddr) { r->rtm_src_len = 16; - RTA_PUT(skb, RTA_SRC, 2, &rt->fld.saddr); + if (nla_put_le16(skb, RTA_SRC, rt->fld.saddr) < 0) + goto errout; } - if (rt->dst.dev) - RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->dst.dev->ifindex); + if (rt->dst.dev && + nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex) < 0) + goto errout; + /* * Note to self - change this if input routes reverse direction when * they deal only with inputs and not with replies like they do * currently. */ - RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src); - if (rt->rt_daddr != rt->rt_gateway) - RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); + if (nla_put_le16(skb, RTA_PREFSRC, rt->rt_local_src) < 0) + goto errout; + + if (rt->rt_daddr != rt->rt_gateway && + nla_put_le16(skb, RTA_GATEWAY, rt->rt_gateway) < 0) + goto errout; + if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) - goto rtattr_failure; + goto errout; + expires = rt->dst.expires ? rt->dst.expires - jiffies : 0; if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires, rt->dst.error) < 0) - goto rtattr_failure; - if (dn_is_input_route(rt)) - RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fld.flowidn_iif); + goto errout; - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; + if (dn_is_input_route(rt) && + nla_put_u32(skb, RTA_IIF, rt->fld.flowidn_iif) < 0) + goto errout; -out_nlmsg_trim: -rtattr_failure: - nlmsg_trim(skb, b); - return -1; + return nlmsg_end(skb, nlh); + +errout: + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } /* @@ -1587,7 +1599,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void memset(&fld, 0, sizeof(fld)); fld.flowidn_proto = DNPROTO_NSP; - skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (skb == NULL) return -ENOBUFS; skb_reset_mac_header(skb); @@ -1665,13 +1677,16 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) struct dn_route *rt; int h, s_h; int idx, s_idx; + struct rtmsg *rtm; if (!net_eq(net, &init_net)) return 0; - if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg)) + if (nlmsg_len(cb->nlh) < sizeof(struct rtmsg)) return -EINVAL; - if (!(((struct rtmsg *)nlmsg_data(cb->nlh))->rtm_flags&RTM_F_CLONED)) + + rtm = nlmsg_data(cb->nlh); + if (!(rtm->rtm_flags & RTM_F_CLONED)) return 0; s_h = cb->args[0]; diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 92ec7417a4d9..16c986ab1228 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -297,62 +297,75 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, { struct rtmsg *rtm; struct nlmsghdr *nlh; - unsigned char *b = skb_tail_pointer(skb); nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags); if (!nlh) - goto out_nlmsg_trim; + return -EMSGSIZE; + rtm = nlmsg_data(nlh); rtm->rtm_family = AF_DECnet; rtm->rtm_dst_len = dst_len; rtm->rtm_src_len = 0; rtm->rtm_tos = 0; rtm->rtm_table = tb_id; - RTA_PUT_U32(skb, RTA_TABLE, tb_id); rtm->rtm_flags = fi->fib_flags; rtm->rtm_scope = scope; rtm->rtm_type = type; - if (rtm->rtm_dst_len) - RTA_PUT(skb, RTA_DST, 2, dst); rtm->rtm_protocol = fi->fib_protocol; - if (fi->fib_priority) - RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); + + if (nla_put_u32(skb, RTA_TABLE, tb_id) < 0) + goto errout; + + if (rtm->rtm_dst_len && + nla_put(skb, RTA_DST, 2, dst) < 0) + goto errout; + + if (fi->fib_priority && + nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority) < 0) + goto errout; + if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) - goto rtattr_failure; + goto errout; + if (fi->fib_nhs == 1) { - if (fi->fib_nh->nh_gw) - RTA_PUT(skb, RTA_GATEWAY, 2, &fi->fib_nh->nh_gw); - if (fi->fib_nh->nh_oif) - RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); + if (fi->fib_nh->nh_gw && + nla_put_le16(skb, RTA_GATEWAY, fi->fib_nh->nh_gw) < 0) + goto errout; + + if (fi->fib_nh->nh_oif && + nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif) < 0) + goto errout; } + if (fi->fib_nhs > 1) { struct rtnexthop *nhp; - struct rtattr *mp_head; - if (skb_tailroom(skb) <= RTA_SPACE(0)) - goto rtattr_failure; - mp_head = (struct rtattr *)skb_put(skb, RTA_SPACE(0)); + struct nlattr *mp_head; + + if (!(mp_head = nla_nest_start(skb, RTA_MULTIPATH))) + goto errout; for_nexthops(fi) { - if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) - goto rtattr_failure; - nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); + if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) + goto errout; + nhp->rtnh_flags = nh->nh_flags & 0xFF; nhp->rtnh_hops = nh->nh_weight - 1; nhp->rtnh_ifindex = nh->nh_oif; - if (nh->nh_gw) - RTA_PUT(skb, RTA_GATEWAY, 2, &nh->nh_gw); + + if (nh->nh_gw && + nla_put_le16(skb, RTA_GATEWAY, nh->nh_gw) < 0) + goto errout; + nhp->rtnh_len = skb_tail_pointer(skb) - (unsigned char *)nhp; } endfor_nexthops(fi); - mp_head->rta_type = RTA_MULTIPATH; - mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head; + + nla_nest_end(skb, mp_head); } - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; + return nlmsg_end(skb, nlh); -out_nlmsg_trim: -rtattr_failure: - nlmsg_trim(skb, b); +errout: + nlmsg_cancel(skb, nlh); return -EMSGSIZE; } -- GitLab From 4c3af034fafeb7269176bf1310c9bcff0b9fd9bb Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 26 Jun 2012 23:36:16 +0000 Subject: [PATCH 3096/6849] netlink: Get rid of obsolete rtnetlink macros Removes all RTA_GET*() and RTA_PUT*() variations, as well as the the unused rtattr_strcmp(). Get rid of rtm_get_table() by moving it to its only user decnet. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 129 -------------------------------------- net/core/rtnetlink.c | 13 ---- net/decnet/dn_fib.c | 8 +++ 3 files changed, 8 insertions(+), 142 deletions(-) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 2c1de8982c85..ea60b0854109 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -612,12 +612,6 @@ struct tcamsg { #include #include -static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str) -{ - int len = strlen(str) + 1; - return len > rta->rta_len || memcmp(RTA_DATA(rta), str, len); -} - extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo); extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid); extern void rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, @@ -628,122 +622,6 @@ extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, u32 ts, u32 tsage, long expires, u32 error); -extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data); - -#define RTA_PUT(skb, attrtype, attrlen, data) \ -({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \ - goto rtattr_failure; \ - __rta_fill(skb, attrtype, attrlen, data); }) - -#define RTA_APPEND(skb, attrlen, data) \ -({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \ - goto rtattr_failure; \ - memcpy(skb_put(skb, attrlen), data, attrlen); }) - -#define RTA_PUT_NOHDR(skb, attrlen, data) \ -({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \ - memset(skb_tail_pointer(skb) - (RTA_ALIGN(attrlen) - attrlen), 0, \ - RTA_ALIGN(attrlen) - attrlen); }) - -#define RTA_PUT_U8(skb, attrtype, value) \ -({ u8 _tmp = (value); \ - RTA_PUT(skb, attrtype, sizeof(u8), &_tmp); }) - -#define RTA_PUT_U16(skb, attrtype, value) \ -({ u16 _tmp = (value); \ - RTA_PUT(skb, attrtype, sizeof(u16), &_tmp); }) - -#define RTA_PUT_U32(skb, attrtype, value) \ -({ u32 _tmp = (value); \ - RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); }) - -#define RTA_PUT_U64(skb, attrtype, value) \ -({ u64 _tmp = (value); \ - RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); }) - -#define RTA_PUT_SECS(skb, attrtype, value) \ - RTA_PUT_U64(skb, attrtype, (value) / HZ) - -#define RTA_PUT_MSECS(skb, attrtype, value) \ - RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value)) - -#define RTA_PUT_STRING(skb, attrtype, value) \ - RTA_PUT(skb, attrtype, strlen(value) + 1, value) - -#define RTA_PUT_FLAG(skb, attrtype) \ - RTA_PUT(skb, attrtype, 0, NULL); - -#define RTA_NEST(skb, type) \ -({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \ - RTA_PUT(skb, type, 0, NULL); \ - __start; }) - -#define RTA_NEST_END(skb, start) \ -({ (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \ - (skb)->len; }) - -#define RTA_NEST_COMPAT(skb, type, attrlen, data) \ -({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \ - RTA_PUT(skb, type, attrlen, data); \ - RTA_NEST(skb, type); \ - __start; }) - -#define RTA_NEST_COMPAT_END(skb, start) \ -({ struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \ - (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \ - RTA_NEST_END(skb, __nest); \ - (skb)->len; }) - -#define RTA_NEST_CANCEL(skb, start) \ -({ if (start) \ - skb_trim(skb, (unsigned char *) (start) - (skb)->data); \ - -1; }) - -#define RTA_GET_U8(rta) \ -({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u8)) \ - goto rtattr_failure; \ - *(u8 *) RTA_DATA(rta); }) - -#define RTA_GET_U16(rta) \ -({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u16)) \ - goto rtattr_failure; \ - *(u16 *) RTA_DATA(rta); }) - -#define RTA_GET_U32(rta) \ -({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \ - goto rtattr_failure; \ - *(u32 *) RTA_DATA(rta); }) - -#define RTA_GET_U64(rta) \ -({ u64 _tmp; \ - if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \ - goto rtattr_failure; \ - memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \ - _tmp; }) - -#define RTA_GET_FLAG(rta) (!!(rta)) - -#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ) -#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta))) - -static inline struct rtattr * -__rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) -{ - struct rtattr *rta; - int size = RTA_LENGTH(attrlen); - - rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); - rta->rta_type = attrtype; - rta->rta_len = size; - memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); - return rta; -} - -#define __RTA_PUT(skb, attrtype, attrlen) \ -({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \ - goto rtattr_failure; \ - __rta_reserve(skb, attrtype, attrlen); }) - extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change); /* RTNL is used as a global lock for all changes to network configuration */ @@ -794,13 +672,6 @@ extern void __rtnl_unlock(void); } \ } while(0) -static inline u32 rtm_get_table(struct rtattr **rta, u8 table) -{ - return RTA_GET_U32(rta[RTA_TABLE-1]); -rtattr_failure: - return table; -} - extern int ndo_dflt_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev, diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 21318d15bbc3..bc8a1cdaac98 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -541,19 +541,6 @@ static const int rta_max[RTM_NR_FAMILIES] = [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, }; -void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) -{ - struct rtattr *rta; - int size = RTA_LENGTH(attrlen); - - rta = (struct rtattr *)skb_put(skb, RTA_ALIGN(size)); - rta->rta_type = attrtype; - rta->rta_len = size; - memcpy(RTA_DATA(rta), data, attrlen); - memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); -} -EXPORT_SYMBOL(__rta_fill); - int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo) { struct sock *rtnl = net->rtnl; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 7eaf98799729..102d6106a942 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -505,6 +505,14 @@ static int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta) return 0; } +static inline u32 rtm_get_table(struct rtattr **rta, u8 table) +{ + if (rta[RTA_TABLE - 1]) + table = nla_get_u32((struct nlattr *) rta[RTA_TABLE - 1]); + + return table; +} + static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); -- GitLab From 22911fc581f6a241e2897a7a8603e97344a6ec82 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 27 Jun 2012 00:23:44 +0000 Subject: [PATCH 3097/6849] net: skb_free_datagram_locked() doesnt drop all packets dropwatch wrongly diagnose all received UDP packets as drops. This patch removes trace_kfree_skb() done in skb_free_datagram_locked(). Locations calling skb_free_datagram_locked() should do it on their own. As a result, drops are accounted on the right function. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/datagram.c | 1 - net/ipv4/udp.c | 5 ++++- net/ipv6/udp.c | 8 +++++--- net/sunrpc/svcsock.c | 12 ++++++------ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/net/core/datagram.c b/net/core/datagram.c index ae6acf6a3dea..0337e2b76862 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -248,7 +248,6 @@ void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) unlock_sock_fast(sk, slow); /* skb is now orphaned, can be freed outside of locked section */ - trace_kfree_skb(skb, skb_free_datagram_locked); __kfree_skb(skb); } EXPORT_SYMBOL(skb_free_datagram_locked); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index db017efb76ea..ee37d47d472e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -108,6 +108,7 @@ #include #include #include +#include #include "udp_impl.h" struct udp_table udp_table __read_mostly; @@ -1220,8 +1221,10 @@ try_again: goto csum_copy_err; } - if (err) + if (unlikely(err)) { + trace_kfree_skb(skb, udp_recvmsg); goto out_free; + } if (!peeked) UDP_INC_STATS_USER(sock_net(sk), diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 051ad481973f..1ecd10249488 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -48,6 +48,7 @@ #include #include +#include #include "udp_impl.h" int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) @@ -385,15 +386,16 @@ try_again: if (skb_csum_unnecessary(skb)) err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), - msg->msg_iov, copied ); + msg->msg_iov, copied); else { err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); if (err == -EINVAL) goto csum_copy_err; } - if (err) + if (unlikely(err)) { + trace_kfree_skb(skb, udpv6_recvmsg); goto out_free; - + } if (!peeked) { if (is_udp4) UDP_INC_STATS_USER(sock_net(sk), diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index a6de09de5d21..18bc130255a7 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -619,6 +620,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) if (!svc_udp_get_dest_address(rqstp, cmh)) { net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", cmh->cmsg_level, cmh->cmsg_type); +out_free: + trace_kfree_skb(skb, svc_udp_recvfrom); skb_free_datagram_locked(svsk->sk_sk, skb); return 0; } @@ -630,8 +633,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { local_bh_enable(); /* checksum error */ - skb_free_datagram_locked(svsk->sk_sk, skb); - return 0; + goto out_free; } local_bh_enable(); skb_free_datagram_locked(svsk->sk_sk, skb); @@ -640,10 +642,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); rqstp->rq_arg.head[0].iov_len = len; - if (skb_checksum_complete(skb)) { - skb_free_datagram_locked(svsk->sk_sk, skb); - return 0; - } + if (skb_checksum_complete(skb)) + goto out_free; rqstp->rq_xprt_ctxt = skb; } -- GitLab From e440cf2ca0a1b075c64016240d46c3aa9d877bbf Mon Sep 17 00:00:00 2001 From: "parav.pandit@emulex.com" Date: Wed, 27 Jun 2012 03:56:12 +0000 Subject: [PATCH 3098/6849] net: added support for 40GbE link. 1. removed code replication for tov calculation for 1G, 10G and made is common for speed > 1G (1G, 10G, 40G, 100G). 2. defines values for #4 different 40G Phys (KR4, LF4, SR4, CR4) Signed-off-by: Parav Pandit Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 8 ++++++++ net/packet/af_packet.c | 18 ++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 297370a6cb18..21eff418091b 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -1153,6 +1153,10 @@ struct ethtool_ops { #define SUPPORTED_10000baseR_FEC (1 << 20) #define SUPPORTED_20000baseMLD2_Full (1 << 21) #define SUPPORTED_20000baseKR2_Full (1 << 22) +#define SUPPORTED_40000baseKR4_Full (1 << 23) +#define SUPPORTED_40000baseCR4_Full (1 << 24) +#define SUPPORTED_40000baseSR4_Full (1 << 25) +#define SUPPORTED_40000baseLR4_Full (1 << 26) /* Indicates what features are advertised by the interface. */ #define ADVERTISED_10baseT_Half (1 << 0) @@ -1178,6 +1182,10 @@ struct ethtool_ops { #define ADVERTISED_10000baseR_FEC (1 << 20) #define ADVERTISED_20000baseMLD2_Full (1 << 21) #define ADVERTISED_20000baseKR2_Full (1 << 22) +#define ADVERTISED_40000baseKR4_Full (1 << 23) +#define ADVERTISED_40000baseCR4_Full (1 << 24) +#define ADVERTISED_40000baseSR4_Full (1 << 25) +#define ADVERTISED_40000baseLR4_Full (1 << 26) /* The following are all involved in forcing a particular link * mode for the device for setting things. When getting the diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8a10d5b3c832..ceaca7c134a0 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -531,6 +531,7 @@ static int prb_calc_retire_blk_tmo(struct packet_sock *po, unsigned int mbits = 0, msec = 0, div = 0, tmo = 0; struct ethtool_cmd ecmd; int err; + u32 speed; rtnl_lock(); dev = __dev_get_by_index(sock_net(&po->sk), po->ifindex); @@ -539,25 +540,18 @@ static int prb_calc_retire_blk_tmo(struct packet_sock *po, return DEFAULT_PRB_RETIRE_TOV; } err = __ethtool_get_settings(dev, &ecmd); + speed = ethtool_cmd_speed(&ecmd); rtnl_unlock(); if (!err) { - switch (ecmd.speed) { - case SPEED_10000: - msec = 1; - div = 10000/1000; - break; - case SPEED_1000: - msec = 1; - div = 1000/1000; - break; /* * If the link speed is so slow you don't really * need to worry about perf anyways */ - case SPEED_100: - case SPEED_10: - default: + if (speed < SPEED_1000 || speed == SPEED_UNKNOWN) { return DEFAULT_PRB_RETIRE_TOV; + } else { + msec = 1; + div = speed / 1000; } } -- GitLab From c10237e077cef50e925f052e49f3b4fead9d71f9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Jun 2012 17:05:06 -0700 Subject: [PATCH 3099/6849] Revert "ipv4: tcp: dont cache unconfirmed intput dst" This reverts commit c074da2810c118b3812f32d6754bd9ead2f169e7. This change has several unwanted side effects: 1) Sockets will cache the DST_NOCACHE route in sk->sk_rx_dst and we'll thus never create a real cached route. 2) All TCP traffic will use DST_NOCACHE and never use the routing cache at all. Signed-off-by: David S. Miller --- include/net/protocol.h | 2 +- include/net/route.h | 8 ++++---- include/net/tcp.h | 2 +- net/ipv4/arp.c | 2 +- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_input.c | 5 ++--- net/ipv4/route.c | 8 +++----- net/ipv4/tcp_ipv4.c | 4 +--- net/ipv4/xfrm4_input.c | 2 +- 9 files changed, 15 insertions(+), 20 deletions(-) diff --git a/include/net/protocol.h b/include/net/protocol.h index 7cfc8f76914d..967b926cbfb1 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -37,7 +37,7 @@ /* This is used to register protocols. */ struct net_protocol { - int (*early_demux)(struct sk_buff *skb, bool *nocache); + int (*early_demux)(struct sk_buff *skb); int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); int (*gso_send_check)(struct sk_buff *skb); diff --git a/include/net/route.h b/include/net/route.h index 6361f9335774..47eb25ac1f7f 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -201,18 +201,18 @@ static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 } extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, - u8 tos, struct net_device *devin, bool noref, bool nocache); + u8 tos, struct net_device *devin, bool noref); static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin) { - return ip_route_input_common(skb, dst, src, tos, devin, false, false); + return ip_route_input_common(skb, dst, src, tos, devin, false); } static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src, - u8 tos, struct net_device *devin, bool nocache) + u8 tos, struct net_device *devin) { - return ip_route_input_common(skb, dst, src, tos, devin, true, nocache); + return ip_route_input_common(skb, dst, src, tos, devin, true); } extern void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, diff --git a/include/net/tcp.h b/include/net/tcp.h index 917ed2e55e8c..6660ffc4963d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -325,7 +325,7 @@ extern void tcp_v4_err(struct sk_buff *skb, u32); extern void tcp_shutdown (struct sock *sk, int how); -extern int tcp_v4_early_demux(struct sk_buff *skb, bool *nocache); +extern int tcp_v4_early_demux(struct sk_buff *skb); extern int tcp_v4_rcv(struct sk_buff *skb); extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 6a9795944369..2e560f0c757d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -828,7 +828,7 @@ static int arp_process(struct sk_buff *skb) } if (arp->ar_op == htons(ARPOP_REQUEST) && - ip_route_input_noref(skb, tip, sip, 0, dev, false) == 0) { + ip_route_input_noref(skb, tip, sip, 0, dev) == 0) { rt = skb_rtable(skb); addr_type = rt->rt_type; diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 978d55f256ea..8d07c973409c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -259,7 +259,7 @@ static void ip_expire(unsigned long arg) skb_dst_drop(head); iph = ip_hdr(head); err = ip_route_input_noref(head, iph->daddr, iph->saddr, - iph->tos, head->dev, false); + iph->tos, head->dev); if (err) goto out_rcu_unlock; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 7be54c8dcbe2..2a39204de5bc 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -326,7 +326,6 @@ static int ip_rcv_finish(struct sk_buff *skb) */ if (skb_dst(skb) == NULL) { int err = -ENOENT; - bool nocache = false; if (sysctl_ip_early_demux) { const struct net_protocol *ipprot; @@ -335,13 +334,13 @@ static int ip_rcv_finish(struct sk_buff *skb) rcu_read_lock(); ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot && ipprot->early_demux) - err = ipprot->early_demux(skb, &nocache); + err = ipprot->early_demux(skb); rcu_read_unlock(); } if (err) { err = ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb->dev, nocache); + iph->tos, skb->dev); if (unlikely(err)) { if (err == -EXDEV) NET_INC_STATS_BH(dev_net(skb->dev), diff --git a/net/ipv4/route.c b/net/ipv4/route.c index fdc7900f9d7a..81533e3a23d1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2214,7 +2214,7 @@ static int ip_mkroute_input(struct sk_buff *skb, */ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, - u8 tos, struct net_device *dev, bool nocache) + u8 tos, struct net_device *dev) { struct fib_result res; struct in_device *in_dev = __in_dev_get_rcu(dev); @@ -2353,8 +2353,6 @@ local_input: rth->dst.error= -err; rth->rt_flags &= ~RTCF_LOCAL; } - if (nocache) - rth->dst.flags |= DST_NOCACHE; hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net)); rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif); err = 0; @@ -2397,7 +2395,7 @@ martian_source_keep_err: } int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, - u8 tos, struct net_device *dev, bool noref, bool nocache) + u8 tos, struct net_device *dev, bool noref) { struct rtable *rth; unsigned int hash; @@ -2473,7 +2471,7 @@ skip_cache: rcu_read_unlock(); return -EINVAL; } - res = ip_route_input_slow(skb, daddr, saddr, tos, dev, nocache); + res = ip_route_input_slow(skb, daddr, saddr, tos, dev); rcu_read_unlock(); return res; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 33aabd4fc20f..1781dc650b9d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1673,7 +1673,7 @@ csum_err: } EXPORT_SYMBOL(tcp_v4_do_rcv); -int tcp_v4_early_demux(struct sk_buff *skb, bool *no_dst_cache) +int tcp_v4_early_demux(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); const struct iphdr *iph; @@ -1719,8 +1719,6 @@ int tcp_v4_early_demux(struct sk_buff *skb, bool *no_dst_cache) } } } - } else { - *no_dst_cache = true; } out_err: diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index eee636b191b9..06814b6216dc 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -28,7 +28,7 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) const struct iphdr *iph = ip_hdr(skb); if (ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb->dev, false)) + iph->tos, skb->dev)) goto drop; } return dst_input(skb); -- GitLab From e0ba94f14f747c2661c4d21f8c44e5b0b8cd8e48 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:16 +0800 Subject: [PATCH 3100/6849] x86/tlb_info: get last level TLB entry number of CPU For 4KB pages, x86 CPU has 2 or 1 level TLB, first level is data TLB and instruction TLB, second level is shared TLB for both data and instructions. For hupe page TLB, usually there is just one level and seperated by 2MB/4MB and 1GB. Although each levels TLB size is important for performance tuning, but for genernal and rude optimizing, last level TLB entry number is suitable. And in fact, last level TLB always has the biggest entry number. This patch will get the biggest TLB entry number and use it in furture TLB optimizing. Accroding Borislav's suggestion, except tlb_ll[i/d]_* array, other function and data will be released after system boot up. For all kinds of x86 vendor friendly, vendor specific code was moved to its specific files. Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-2-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/processor.h | 11 +++ arch/x86/kernel/cpu/common.c | 21 +++++ arch/x86/kernel/cpu/cpu.h | 9 ++ arch/x86/kernel/cpu/intel.c | 142 +++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 39bc5777211a..39b2bd48dfbc 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -61,6 +61,17 @@ static inline void *current_text_addr(void) # define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif +enum tlb_infos { + ENTRIES, + NR_INFO +}; + +extern u16 __read_mostly tlb_lli_4k[NR_INFO]; +extern u16 __read_mostly tlb_lli_2m[NR_INFO]; +extern u16 __read_mostly tlb_lli_4m[NR_INFO]; +extern u16 __read_mostly tlb_lld_4k[NR_INFO]; +extern u16 __read_mostly tlb_lld_2m[NR_INFO]; +extern u16 __read_mostly tlb_lld_4m[NR_INFO]; /* * CPU type and hardware bug flags. Kept separately for each CPU. * Members of this structure are referenced in head.S, so think twice diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6b9333b429ba..b2016df00813 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -452,6 +452,25 @@ void __cpuinit cpu_detect_cache_sizes(struct cpuinfo_x86 *c) c->x86_cache_size = l2size; } +u16 __read_mostly tlb_lli_4k[NR_INFO]; +u16 __read_mostly tlb_lli_2m[NR_INFO]; +u16 __read_mostly tlb_lli_4m[NR_INFO]; +u16 __read_mostly tlb_lld_4k[NR_INFO]; +u16 __read_mostly tlb_lld_2m[NR_INFO]; +u16 __read_mostly tlb_lld_4m[NR_INFO]; + +void __cpuinit cpu_detect_tlb(struct cpuinfo_x86 *c) +{ + if (this_cpu->c_detect_tlb) + this_cpu->c_detect_tlb(c); + + printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ + "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n", + tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], + tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], + tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES]); +} + void __cpuinit detect_ht(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_HT @@ -911,6 +930,8 @@ void __init identify_boot_cpu(void) #else vgetcpu_set_mode(); #endif + if (boot_cpu_data.cpuid_level >= 2) + cpu_detect_tlb(&boot_cpu_data); } void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 8bacc7826fb3..4041c24ae7db 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -20,10 +20,19 @@ struct cpu_dev { void (*c_bsp_init)(struct cpuinfo_x86 *); void (*c_init)(struct cpuinfo_x86 *); void (*c_identify)(struct cpuinfo_x86 *); + void (*c_detect_tlb)(struct cpuinfo_x86 *); unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int); int c_x86_vendor; }; +struct _tlb_table { + unsigned char descriptor; + char tlb_type; + unsigned int entries; + /* unsigned int ways; */ + char info[128]; +}; + #define cpu_dev_register(cpu_devX) \ static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \ __attribute__((__section__(".x86_cpu_dev.init"))) = \ diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 3e6ff6cbf42a..ed0d512cf51b 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -491,6 +491,147 @@ static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned i } #endif +#define TLB_INST_4K 0x01 +#define TLB_INST_4M 0x02 +#define TLB_INST_2M_4M 0x03 + +#define TLB_INST_ALL 0x05 +#define TLB_INST_1G 0x06 + +#define TLB_DATA_4K 0x11 +#define TLB_DATA_4M 0x12 +#define TLB_DATA_2M_4M 0x13 +#define TLB_DATA_4K_4M 0x14 + +#define TLB_DATA_1G 0x16 + +#define TLB_DATA0_4K 0x21 +#define TLB_DATA0_4M 0x22 +#define TLB_DATA0_2M_4M 0x23 + +#define STLB_4K 0x41 + +static const struct _tlb_table intel_tlb_table[] __cpuinitconst = { + { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, + { 0x02, TLB_INST_4M, 2, " TLB_INST 4 MByte pages, full associative" }, + { 0x03, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way set associative" }, + { 0x04, TLB_DATA_4M, 8, " TLB_DATA 4 MByte pages, 4-way set associative" }, + { 0x05, TLB_DATA_4M, 32, " TLB_DATA 4 MByte pages, 4-way set associative" }, + { 0x0b, TLB_INST_4M, 4, " TLB_INST 4 MByte pages, 4-way set associative" }, + { 0x4f, TLB_INST_4K, 32, " TLB_INST 4 KByte pages */" }, + { 0x50, TLB_INST_ALL, 64, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" }, + { 0x51, TLB_INST_ALL, 128, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" }, + { 0x52, TLB_INST_ALL, 256, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" }, + { 0x55, TLB_INST_2M_4M, 7, " TLB_INST 2-MByte or 4-MByte pages, fully associative" }, + { 0x56, TLB_DATA0_4M, 16, " TLB_DATA0 4 MByte pages, 4-way set associative" }, + { 0x57, TLB_DATA0_4K, 16, " TLB_DATA0 4 KByte pages, 4-way associative" }, + { 0x59, TLB_DATA0_4K, 16, " TLB_DATA0 4 KByte pages, fully associative" }, + { 0x5a, TLB_DATA0_2M_4M, 32, " TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative" }, + { 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" }, + { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, + { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, + { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, + { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, + { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, + { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, + { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, + { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, + { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, + { 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" }, + { 0x00, 0, 0 } +}; + +static void __cpuinit intel_tlb_lookup(const unsigned char desc) +{ + unsigned char k; + if (desc == 0) + return; + + /* look up this descriptor in the table */ + for (k = 0; intel_tlb_table[k].descriptor != desc && \ + intel_tlb_table[k].descriptor != 0; k++) + ; + + if (intel_tlb_table[k].tlb_type == 0) + return; + + switch (intel_tlb_table[k].tlb_type) { + case STLB_4K: + if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; + if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_INST_ALL: + if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; + if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries; + if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_INST_4K: + if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_INST_4M: + if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_INST_2M_4M: + if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries; + if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_DATA_4K: + case TLB_DATA0_4K: + if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_DATA_4M: + case TLB_DATA0_4M: + if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_DATA_2M_4M: + case TLB_DATA0_2M_4M: + if (tlb_lld_2m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_2m[ENTRIES] = intel_tlb_table[k].entries; + if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; + break; + case TLB_DATA_4K_4M: + if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; + if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; + break; + } +} + +static void __cpuinit intel_detect_tlb(struct cpuinfo_x86 *c) +{ + int i, j, n; + unsigned int regs[4]; + unsigned char *desc = (unsigned char *)regs; + /* Number of times to iterate */ + n = cpuid_eax(2) & 0xFF; + + for (i = 0 ; i < n ; i++) { + cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); + + /* If bit 31 is set, this is an unknown format */ + for (j = 0 ; j < 3 ; j++) + if (regs[j] & (1 << 31)) + regs[j] = 0; + + /* Byte 0 is level count, not a descriptor */ + for (j = 1 ; j < 16 ; j++) + intel_tlb_lookup(desc[j]); + } +} + static const struct cpu_dev __cpuinitconst intel_cpu_dev = { .c_vendor = "Intel", .c_ident = { "GenuineIntel" }, @@ -546,6 +687,7 @@ static const struct cpu_dev __cpuinitconst intel_cpu_dev = { }, .c_size_cache = intel_size_cache, #endif + .c_detect_tlb = intel_detect_tlb, .c_early_init = early_init_intel, .c_init = init_intel, .c_x86_vendor = X86_VENDOR_INTEL, -- GitLab From e7b52ffd45a6d834473f43b349e7d86593d763c7 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:17 +0800 Subject: [PATCH 3101/6849] x86/flush_tlb: try flush_tlb_single one by one in flush_tlb_range x86 has no flush_tlb_range support in instruction level. Currently the flush_tlb_range just implemented by flushing all page table. That is not the best solution for all scenarios. In fact, if we just use 'invlpg' to flush few lines from TLB, we can get the performance gain from later remain TLB lines accessing. But the 'invlpg' instruction costs much of time. Its execution time can compete with cr3 rewriting, and even a bit more on SNB CPU. So, on a 512 4KB TLB entries CPU, the balance points is at: (512 - X) * 100ns(assumed TLB refill cost) = X(TLB flush entries) * 100ns(assumed invlpg cost) Here, X is 256, that is 1/2 of 512 entries. But with the mysterious CPU pre-fetcher and page miss handler Unit, the assumed TLB refill cost is far lower then 100ns in sequential access. And 2 HT siblings in one core makes the memory access more faster if they are accessing the same memory. So, in the patch, I just do the change when the target entries is less than 1/16 of whole active tlb entries. Actually, I have no data support for the percentage '1/16', so any suggestions are welcomed. As to hugetlb, guess due to smaller page table, and smaller active TLB entries, I didn't see benefit via my benchmark, so no optimizing now. My micro benchmark show in ideal scenarios, the performance improves 70 percent in reading. And in worst scenario, the reading/writing performance is similar with unpatched 3.4-rc4 kernel. Here is the reading data on my 2P * 4cores *HT NHM EP machine, with THP 'always': multi thread testing, '-t' paramter is thread number: with patch unpatched 3.4-rc4 ./mprotect -t 1 14ns 24ns ./mprotect -t 2 13ns 22ns ./mprotect -t 4 12ns 19ns ./mprotect -t 8 14ns 16ns ./mprotect -t 16 28ns 26ns ./mprotect -t 32 54ns 51ns ./mprotect -t 128 200ns 199ns Single process with sequencial flushing and memory accessing: with patch unpatched 3.4-rc4 ./mprotect 7ns 11ns ./mprotect -p 4096 -l 8 -n 10240 21ns 21ns [ hpa: http://lkml.kernel.org/r/1B4B44D9196EFF41AE41FDA404FC0A100BFF94@SHSMSX101.ccr.corp.intel.com has additional performance numbers. ] Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-3-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/paravirt.h | 5 +- arch/x86/include/asm/paravirt_types.h | 3 +- arch/x86/include/asm/tlbflush.h | 23 +++---- arch/x86/include/asm/uv/uv.h | 5 +- arch/x86/mm/tlb.c | 97 ++++++++++++++++++++++----- arch/x86/platform/uv/tlb_uv.c | 6 +- arch/x86/xen/mmu.c | 12 ++-- include/trace/events/xen.h | 12 ++-- 8 files changed, 114 insertions(+), 49 deletions(-) diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 6cbbabf52707..7e2c2a635737 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -397,9 +397,10 @@ static inline void __flush_tlb_single(unsigned long addr) static inline void flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, - unsigned long va) + unsigned long start, + unsigned long end) { - PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, cpumask, mm, va); + PVOP_VCALL4(pv_mmu_ops.flush_tlb_others, cpumask, mm, start, end); } static inline int paravirt_pgd_alloc(struct mm_struct *mm) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 8e8b9a4987ee..600a5fcac9cd 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -250,7 +250,8 @@ struct pv_mmu_ops { void (*flush_tlb_single)(unsigned long addr); void (*flush_tlb_others)(const struct cpumask *cpus, struct mm_struct *mm, - unsigned long va); + unsigned long start, + unsigned long end); /* Hooks for allocating and freeing a pagetable top-level */ int (*pgd_alloc)(struct mm_struct *mm); diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 36a1a2ab87d2..33608d96d68b 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -73,14 +73,10 @@ static inline void __flush_tlb_one(unsigned long addr) * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages - * - flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus + * - flush_tlb_others(cpumask, mm, start, end) flushes TLBs on other cpus * * ..but the i386 has somewhat limited tlb flushing capabilities, * and page-granular flushes are available only on i486 and up. - * - * x86-64 can only flush individual pages or full VMs. For a range flush - * we always do the full VM. Might be worth trying if for a small - * range a few INVLPGs in a row are a win. */ #ifndef CONFIG_SMP @@ -111,7 +107,8 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, static inline void native_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, - unsigned long va) + unsigned long start, + unsigned long end) { } @@ -129,17 +126,14 @@ extern void flush_tlb_all(void); extern void flush_tlb_current_task(void); extern void flush_tlb_mm(struct mm_struct *); extern void flush_tlb_page(struct vm_area_struct *, unsigned long); +extern void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end); #define flush_tlb() flush_tlb_current_task() -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - flush_tlb_mm(vma->vm_mm); -} - void native_flush_tlb_others(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va); + struct mm_struct *mm, + unsigned long start, unsigned long end); #define TLBSTATE_OK 1 #define TLBSTATE_LAZY 2 @@ -159,7 +153,8 @@ static inline void reset_lazy_tlbstate(void) #endif /* SMP */ #ifndef CONFIG_PARAVIRT -#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(mask, mm, va) +#define flush_tlb_others(mask, mm, start, end) \ + native_flush_tlb_others(mask, mm, start, end) #endif static inline void flush_tlb_kernel_range(unsigned long start, diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index 3bb9491b7659..b47c2a82ff15 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h @@ -15,7 +15,8 @@ extern void uv_nmi_init(void); extern void uv_system_init(void); extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, - unsigned long va, + unsigned long start, + unsigned end, unsigned int cpu); #else /* X86_UV */ @@ -26,7 +27,7 @@ static inline void uv_cpu_init(void) { } static inline void uv_system_init(void) { } static inline const struct cpumask * uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, - unsigned long va, unsigned int cpu) + unsigned long start, unsigned long end, unsigned int cpu) { return cpumask; } #endif /* X86_UV */ diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 5e57e113b72c..3b91c981a27f 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -41,7 +41,8 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) union smp_flush_state { struct { struct mm_struct *flush_mm; - unsigned long flush_va; + unsigned long flush_start; + unsigned long flush_end; raw_spinlock_t tlbstate_lock; DECLARE_BITMAP(flush_cpumask, NR_CPUS); }; @@ -156,10 +157,19 @@ void smp_invalidate_interrupt(struct pt_regs *regs) if (f->flush_mm == this_cpu_read(cpu_tlbstate.active_mm)) { if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { - if (f->flush_va == TLB_FLUSH_ALL) + if (f->flush_end == TLB_FLUSH_ALL + || !cpu_has_invlpg) local_flush_tlb(); - else - __flush_tlb_one(f->flush_va); + else if (!f->flush_end) + __flush_tlb_single(f->flush_start); + else { + unsigned long addr; + addr = f->flush_start; + while (addr < f->flush_end) { + __flush_tlb_single(addr); + addr += PAGE_SIZE; + } + } } else leave_mm(cpu); } @@ -172,7 +182,8 @@ out: } static void flush_tlb_others_ipi(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va) + struct mm_struct *mm, unsigned long start, + unsigned long end) { unsigned int sender; union smp_flush_state *f; @@ -185,7 +196,8 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask, raw_spin_lock(&f->tlbstate_lock); f->flush_mm = mm; - f->flush_va = va; + f->flush_start = start; + f->flush_end = end; if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) { /* * We have to send the IPI only to @@ -199,24 +211,26 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask, } f->flush_mm = NULL; - f->flush_va = 0; + f->flush_start = 0; + f->flush_end = 0; if (nr_cpu_ids > NUM_INVALIDATE_TLB_VECTORS) raw_spin_unlock(&f->tlbstate_lock); } void native_flush_tlb_others(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va) + struct mm_struct *mm, unsigned long start, + unsigned long end) { if (is_uv_system()) { unsigned int cpu; cpu = smp_processor_id(); - cpumask = uv_flush_tlb_others(cpumask, mm, va, cpu); + cpumask = uv_flush_tlb_others(cpumask, mm, start, end, cpu); if (cpumask) - flush_tlb_others_ipi(cpumask, mm, va); + flush_tlb_others_ipi(cpumask, mm, start, end); return; } - flush_tlb_others_ipi(cpumask, mm, va); + flush_tlb_others_ipi(cpumask, mm, start, end); } static void __cpuinit calculate_tlb_offset(void) @@ -282,7 +296,7 @@ void flush_tlb_current_task(void) local_flush_tlb(); if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(mm_cpumask(mm), mm, TLB_FLUSH_ALL); + flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); preempt_enable(); } @@ -297,12 +311,63 @@ void flush_tlb_mm(struct mm_struct *mm) leave_mm(smp_processor_id()); } if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(mm_cpumask(mm), mm, TLB_FLUSH_ALL); + flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); + + preempt_enable(); +} + +#define FLUSHALL_BAR 16 + +void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + struct mm_struct *mm; + + if (!cpu_has_invlpg || vma->vm_flags & VM_HUGETLB) { + flush_tlb_mm(vma->vm_mm); + return; + } + + preempt_disable(); + mm = vma->vm_mm; + if (current->active_mm == mm) { + if (current->mm) { + unsigned long addr, vmflag = vma->vm_flags; + unsigned act_entries, tlb_entries = 0; + + if (vmflag & VM_EXEC) + tlb_entries = tlb_lli_4k[ENTRIES]; + else + tlb_entries = tlb_lld_4k[ENTRIES]; + + act_entries = tlb_entries > mm->total_vm ? + mm->total_vm : tlb_entries; + if ((end - start)/PAGE_SIZE > act_entries/FLUSHALL_BAR) + local_flush_tlb(); + else { + for (addr = start; addr < end; + addr += PAGE_SIZE) + __flush_tlb_single(addr); + + if (cpumask_any_but(mm_cpumask(mm), + smp_processor_id()) < nr_cpu_ids) + flush_tlb_others(mm_cpumask(mm), mm, + start, end); + preempt_enable(); + return; + } + } else { + leave_mm(smp_processor_id()); + } + } + if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) + flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); preempt_enable(); } -void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long start) { struct mm_struct *mm = vma->vm_mm; @@ -310,13 +375,13 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) if (current->active_mm == mm) { if (current->mm) - __flush_tlb_one(va); + __flush_tlb_one(start); else leave_mm(smp_processor_id()); } if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(mm_cpumask(mm), mm, va); + flush_tlb_others(mm_cpumask(mm), mm, start, 0UL); preempt_enable(); } diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 59880afa851f..f1bef8e1d633 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -1068,8 +1068,8 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp, * done. The returned pointer is valid till preemption is re-enabled. */ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va, - unsigned int cpu) + struct mm_struct *mm, unsigned long start, + unsigned end, unsigned int cpu) { int locals = 0; int remotes = 0; @@ -1112,7 +1112,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, record_send_statistics(stat, locals, hubs, remotes, bau_desc); - bau_desc->payload.address = va; + bau_desc->payload.address = start; bau_desc->payload.sending_cpu = cpu; /* * uv_flush_send_and_wait returns 0 if all cpu's were messaged, diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 3a73785631ce..39ed56789f68 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1244,7 +1244,8 @@ static void xen_flush_tlb_single(unsigned long addr) } static void xen_flush_tlb_others(const struct cpumask *cpus, - struct mm_struct *mm, unsigned long va) + struct mm_struct *mm, unsigned long start, + unsigned long end) { struct { struct mmuext_op op; @@ -1256,7 +1257,7 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, } *args; struct multicall_space mcs; - trace_xen_mmu_flush_tlb_others(cpus, mm, va); + trace_xen_mmu_flush_tlb_others(cpus, mm, start, end); if (cpumask_empty(cpus)) return; /* nothing to do */ @@ -1269,11 +1270,10 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); - if (va == TLB_FLUSH_ALL) { - args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; - } else { + args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; + if (start != TLB_FLUSH_ALL && (end - start) <= PAGE_SIZE) { args->op.cmd = MMUEXT_INVLPG_MULTI; - args->op.arg1.linear_addr = va; + args->op.arg1.linear_addr = start; } MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h index 92f1a796829e..15ba03bdd7c6 100644 --- a/include/trace/events/xen.h +++ b/include/trace/events/xen.h @@ -397,18 +397,20 @@ TRACE_EVENT(xen_mmu_flush_tlb_single, TRACE_EVENT(xen_mmu_flush_tlb_others, TP_PROTO(const struct cpumask *cpus, struct mm_struct *mm, - unsigned long addr), - TP_ARGS(cpus, mm, addr), + unsigned long addr, unsigned long end), + TP_ARGS(cpus, mm, addr, end), TP_STRUCT__entry( __field(unsigned, ncpus) __field(struct mm_struct *, mm) __field(unsigned long, addr) + __field(unsigned long, end) ), TP_fast_assign(__entry->ncpus = cpumask_weight(cpus); __entry->mm = mm; - __entry->addr = addr), - TP_printk("ncpus %d mm %p addr %lx", - __entry->ncpus, __entry->mm, __entry->addr) + __entry->addr = addr, + __entry->end = end), + TP_printk("ncpus %d mm %p addr %lx, end %lx", + __entry->ncpus, __entry->mm, __entry->addr, __entry->end) ); TRACE_EVENT(xen_mmu_write_cr3, -- GitLab From d8dfe60d6dcad5989c4558b753b98d657e2813c0 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:18 +0800 Subject: [PATCH 3102/6849] x86/tlb: fall back to flush all when meet a THP large page We don't need to flush large pages by PAGE_SIZE step, that just waste time. and actually, large page don't need 'invlpg' optimizing according to our micro benchmark. So, just flush whole TLB is enough for them. The following result is tested on a 2CPU * 4cores * 2HT NHM EP machine, with THP 'always' setting. Multi-thread testing, '-t' paramter is thread number: without this patch with this patch ./mprotect -t 1 14ns 13ns ./mprotect -t 2 13ns 13ns ./mprotect -t 4 12ns 11ns ./mprotect -t 8 14ns 10ns ./mprotect -t 16 28ns 28ns ./mprotect -t 32 54ns 52ns ./mprotect -t 128 200ns 200ns Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-4-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/mm/tlb.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 3b91c981a27f..184a02a4d871 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -318,12 +318,42 @@ void flush_tlb_mm(struct mm_struct *mm) #define FLUSHALL_BAR 16 +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline unsigned long has_large_page(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + unsigned long addr = ALIGN(start, HPAGE_SIZE); + for (; addr < end; addr += HPAGE_SIZE) { + pgd = pgd_offset(mm, addr); + if (likely(!pgd_none(*pgd))) { + pud = pud_offset(pgd, addr); + if (likely(!pud_none(*pud))) { + pmd = pmd_offset(pud, addr); + if (likely(!pmd_none(*pmd))) + if (pmd_large(*pmd)) + return addr; + } + } + } + return 0; +} +#else +static inline unsigned long has_large_page(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + return 0; +} +#endif void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { struct mm_struct *mm; if (!cpu_has_invlpg || vma->vm_flags & VM_HUGETLB) { +flush_all: flush_tlb_mm(vma->vm_mm); return; } @@ -346,6 +376,10 @@ void flush_tlb_range(struct vm_area_struct *vma, if ((end - start)/PAGE_SIZE > act_entries/FLUSHALL_BAR) local_flush_tlb(); else { + if (has_large_page(mm, start, end)) { + preempt_enable(); + goto flush_all; + } for (addr = start; addr < end; addr += PAGE_SIZE) __flush_tlb_single(addr); -- GitLab From c4211f42d3e66875298a5e26a75109878c80f15b Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:19 +0800 Subject: [PATCH 3103/6849] x86/tlb: add tlb_flushall_shift for specific CPU Testing show different CPU type(micro architectures and NUMA mode) has different balance points between the TLB flush all and multiple invlpg. And there also has cases the tlb flush change has no any help. This patch give a interface to let x86 vendor developers have a chance to set different shift for different CPU type. like some machine in my hands, balance points is 16 entries on Romely-EP; while it is at 8 entries on Bloomfield NHM-EP; and is 256 on IVB mobile CPU. but on model 15 core2 Xeon using invlpg has nothing help. For untested machine, do a conservative optimization, same as NHM CPU. Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-5-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/processor.h | 2 ++ arch/x86/kernel/cpu/common.c | 14 +++++++++++-- arch/x86/kernel/cpu/intel.c | 34 ++++++++++++++++++++++++++++++++ arch/x86/mm/tlb.c | 7 +++---- include/asm-generic/tlb.h | 3 ++- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 39b2bd48dfbc..d048cad9bcad 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -72,6 +72,8 @@ extern u16 __read_mostly tlb_lli_4m[NR_INFO]; extern u16 __read_mostly tlb_lld_4k[NR_INFO]; extern u16 __read_mostly tlb_lld_2m[NR_INFO]; extern u16 __read_mostly tlb_lld_4m[NR_INFO]; +extern s8 __read_mostly tlb_flushall_shift; + /* * CPU type and hardware bug flags. Kept separately for each CPU. * Members of this structure are referenced in head.S, so think twice diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index b2016df00813..7595552600b8 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -459,16 +459,26 @@ u16 __read_mostly tlb_lld_4k[NR_INFO]; u16 __read_mostly tlb_lld_2m[NR_INFO]; u16 __read_mostly tlb_lld_4m[NR_INFO]; +/* + * tlb_flushall_shift shows the balance point in replacing cr3 write + * with multiple 'invlpg'. It will do this replacement when + * flush_tlb_lines <= active_lines/2^tlb_flushall_shift. + * If tlb_flushall_shift is -1, means the replacement will be disabled. + */ +s8 __read_mostly tlb_flushall_shift = -1; + void __cpuinit cpu_detect_tlb(struct cpuinfo_x86 *c) { if (this_cpu->c_detect_tlb) this_cpu->c_detect_tlb(c); printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ - "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n", + "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ + "tlb_flushall_shift is 0x%x\n", tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], - tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES]); + tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], + tlb_flushall_shift); } void __cpuinit detect_ht(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index ed0d512cf51b..0a4ce2980a5a 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -610,6 +610,39 @@ static void __cpuinit intel_tlb_lookup(const unsigned char desc) } } +static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c) +{ + if (!cpu_has_invlpg) { + tlb_flushall_shift = -1; + return; + } + switch ((c->x86 << 8) + c->x86_model) { + case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ + case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ + case 0x617: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */ + case 0x61d: /* six-core 45 nm xeon "Dunnington" */ + tlb_flushall_shift = -1; + break; + case 0x61a: /* 45 nm nehalem, "Bloomfield" */ + case 0x61e: /* 45 nm nehalem, "Lynnfield" */ + case 0x625: /* 32 nm nehalem, "Clarkdale" */ + case 0x62c: /* 32 nm nehalem, "Gulftown" */ + case 0x62e: /* 45 nm nehalem-ex, "Beckton" */ + case 0x62f: /* 32 nm Xeon E7 */ + tlb_flushall_shift = 6; + break; + case 0x62a: /* SandyBridge */ + case 0x62d: /* SandyBridge, "Romely-EP" */ + tlb_flushall_shift = 5; + break; + case 0x63a: /* Ivybridge */ + tlb_flushall_shift = 1; + break; + default: + tlb_flushall_shift = 6; + } +} + static void __cpuinit intel_detect_tlb(struct cpuinfo_x86 *c) { int i, j, n; @@ -630,6 +663,7 @@ static void __cpuinit intel_detect_tlb(struct cpuinfo_x86 *c) for (j = 1 ; j < 16 ; j++) intel_tlb_lookup(desc[j]); } + intel_tlb_flushall_shift_set(c); } static const struct cpu_dev __cpuinitconst intel_cpu_dev = { diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 184a02a4d871..2939f2f9edbb 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -316,8 +316,6 @@ void flush_tlb_mm(struct mm_struct *mm) preempt_enable(); } -#define FLUSHALL_BAR 16 - #ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline unsigned long has_large_page(struct mm_struct *mm, unsigned long start, unsigned long end) @@ -352,7 +350,7 @@ void flush_tlb_range(struct vm_area_struct *vma, { struct mm_struct *mm; - if (!cpu_has_invlpg || vma->vm_flags & VM_HUGETLB) { + if (vma->vm_flags & VM_HUGETLB || tlb_flushall_shift == -1) { flush_all: flush_tlb_mm(vma->vm_mm); return; @@ -373,7 +371,8 @@ flush_all: act_entries = tlb_entries > mm->total_vm ? mm->total_vm : tlb_entries; - if ((end - start)/PAGE_SIZE > act_entries/FLUSHALL_BAR) + if ((end - start) >> PAGE_SHIFT > + act_entries >> tlb_flushall_shift) local_flush_tlb(); else { if (has_large_page(mm, start, end)) { diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index f96a5b58a975..75e888b3cfd2 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -113,7 +113,8 @@ static inline int tlb_fast_mode(struct mmu_gather *tlb) void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm); void tlb_flush_mmu(struct mmu_gather *tlb); -void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end); +void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, + unsigned long end); int __tlb_remove_page(struct mmu_gather *tlb, struct page *page); /* tlb_remove_page -- GitLab From 3df3212f9722c7e45c723b9ea231a04ba4dbc47c Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:20 +0800 Subject: [PATCH 3104/6849] x86/tlb: add tlb_flushall_shift knob into debugfs kernel will replace cr3 rewrite with invlpg when tlb_flush_entries <= active_tlb_entries / 2^tlb_flushall_factor if tlb_flushall_factor is -1, kernel won't do this replacement. User can modify its value according to specific CPU/applications. Thanks for Borislav providing the help message of CONFIG_DEBUG_TLBFLUSH. Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-6-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig.debug | 19 ++++++++++++++++ arch/x86/mm/tlb.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index e46c2147397f..b322f124ee3c 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -129,6 +129,25 @@ config DOUBLEFAULT option saves about 4k and might cause you much additional grey hair. +config DEBUG_TLBFLUSH + bool "Set upper limit of TLB entries to flush one-by-one" + depends on DEBUG_KERNEL && (X86_64 || X86_INVLPG) + ---help--- + + X86-only for now. + + This option allows the user to tune the amount of TLB entries the + kernel flushes one-by-one instead of doing a full TLB flush. In + certain situations, the former is cheaper. This is controlled by the + tlb_flushall_shift knob under /sys/kernel/debug/x86. If you set it + to -1, the code flushes the whole TLB unconditionally. Otherwise, + for positive values of it, the kernel will use single TLB entry + invalidating instructions according to the following formula: + + flush_entries <= active_tlb_entries / 2^tlb_flushall_shift + + If in doubt, say "N". + config IOMMU_DEBUG bool "Enable IOMMU debugging" depends on GART_IOMMU && DEBUG_KERNEL diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 2939f2f9edbb..5911f61e300e 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -12,6 +12,7 @@ #include #include #include +#include DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0, }; @@ -430,3 +431,53 @@ void flush_tlb_all(void) { on_each_cpu(do_flush_tlb_all, NULL, 1); } + +#ifdef CONFIG_DEBUG_TLBFLUSH +static ssize_t tlbflush_read_file(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + char buf[32]; + unsigned int len; + + len = sprintf(buf, "%hd\n", tlb_flushall_shift); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t tlbflush_write_file(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[32]; + ssize_t len; + s8 shift; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (kstrtos8(buf, 0, &shift)) + return -EINVAL; + + if (shift > 64) + return -EINVAL; + + tlb_flushall_shift = shift; + return count; +} + +static const struct file_operations fops_tlbflush = { + .read = tlbflush_read_file, + .write = tlbflush_write_file, + .llseek = default_llseek, +}; + +static int __cpuinit create_tlb_flushall_shift(void) +{ + if (cpu_has_invlpg) { + debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR, + arch_debugfs_dir, NULL, &fops_tlbflush); + } + return 0; +} +late_initcall(create_tlb_flushall_shift); +#endif -- GitLab From 597e1c3580b7cfd95bb0f3167e2b297bf8a5a3ae Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:21 +0800 Subject: [PATCH 3105/6849] mm/mmu_gather: enable tlb flush range in generic mmu_gather This patch enabled the tlb flush range support in generic mmu layer. Most of arch has self tlb flush range support, like ARM/IA64 etc. X86 arch has no this support in hardware yet. But another instruction 'invlpg' can implement this function in some degree. So, enable this feather in generic layer for x86 now. and maybe useful for other archs in further. Generic mmu_gather struct is protected by micro HAVE_GENERIC_MMU_GATHER. Other archs that has flush range supported own self mmu_gather struct. So, now this change is safe for them. In future we may unify this struct and related functions on multiple archs. Thanks for Peter Zijlstra time and time reminder for multiple architecture code safe! Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-7-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- include/asm-generic/tlb.h | 2 ++ mm/memory.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index 75e888b3cfd2..ed6642ad03e0 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -86,6 +86,8 @@ struct mmu_gather { #ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch *batch; #endif + unsigned long start; + unsigned long end; unsigned int need_flush : 1, /* Did free PTEs */ fast_mode : 1; /* No batching */ diff --git a/mm/memory.c b/mm/memory.c index 1b7dc662bf9f..32c99433cfdf 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -206,6 +206,8 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm) tlb->mm = mm; tlb->fullmm = fullmm; + tlb->start = -1UL; + tlb->end = 0; tlb->need_flush = 0; tlb->fast_mode = (num_possible_cpus() == 1); tlb->local.next = NULL; @@ -248,6 +250,8 @@ void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long e { struct mmu_gather_batch *batch, *next; + tlb->start = start; + tlb->end = end; tlb_flush_mmu(tlb); /* keep the page table cache within bounds */ @@ -1204,6 +1208,11 @@ again: */ if (force_flush) { force_flush = 0; + +#ifdef HAVE_GENERIC_MMU_GATHER + tlb->start = addr; + tlb->end = end; +#endif tlb_flush_mmu(tlb); if (addr != end) goto again; -- GitLab From 611ae8e3f5204f7480b3b405993b3352cfa16662 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:22 +0800 Subject: [PATCH 3106/6849] x86/tlb: enable tlb flush range support for x86 Not every tlb_flush execution moment is really need to evacuate all TLB entries, like in munmap, just few 'invlpg' is better for whole process performance, since it leaves most of TLB entries for later accessing. This patch also rewrite flush_tlb_range for 2 purposes: 1, split it out to get flush_blt_mm_range function. 2, clean up to reduce line breaking, thanks for Borislav's input. My micro benchmark 'mummap' http://lkml.org/lkml/2012/5/17/59 show that the random memory access on other CPU has 0~50% speed up on a 2P * 4cores * HT NHM EP while do 'munmap'. Thanks Yongjie's testing on this patch: ------------- I used Linux 3.4-RC6 w/ and w/o his patches as Xen dom0 and guest kernel. After running two benchmarks in Xen HVM guest, I found his patches brought about 1%~3% performance gain in 'kernel build' and 'netperf' testing, though the performance gain was not very stable in 'kernel build' testing. Some detailed testing results are below. Testing Environment: Hardware: Romley-EP platform Xen version: latest upstream Linux kernel: 3.4-RC6 Guest vCPU number: 8 NIC: Intel 82599 (10GB bandwidth) In 'kernel build' testing in guest: Command line | performance gain make -j 4 | 3.81% make -j 8 | 0.37% make -j 16 | -0.52% In 'netperf' testing, we tested TCP_STREAM with default socket size 16384 byte as large packet and 64 byte as small packet. I used several clients to add networking pressure, then 'netperf' server automatically generated several threads to response them. I also used large-size packet and small-size packet in the testing. Packet size | Thread number | performance gain 16384 bytes | 4 | 0.02% 16384 bytes | 8 | 2.21% 16384 bytes | 16 | 2.04% 64 bytes | 4 | 1.07% 64 bytes | 8 | 3.31% 64 bytes | 16 | 0.71% Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-8-git-send-email-alex.shi@intel.com Tested-by: Ren, Yongjie Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/tlb.h | 9 ++- arch/x86/include/asm/tlbflush.h | 17 ++++- arch/x86/mm/tlb.c | 112 +++++++++++++------------------- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 829215fef9ee..4fef20773b8f 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h @@ -4,7 +4,14 @@ #define tlb_start_vma(tlb, vma) do { } while (0) #define tlb_end_vma(tlb, vma) do { } while (0) #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) -#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +#define tlb_flush(tlb) \ +{ \ + if (tlb->fullmm == 0) \ + flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ + else \ + flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ +} #include diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 33608d96d68b..621b959e1dbf 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -105,6 +105,13 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, __flush_tlb(); } +static inline void flush_tlb_mm_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, unsigned long vmflag) +{ + if (vma->vm_mm == current->active_mm) + __flush_tlb(); +} + static inline void native_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long start, @@ -122,12 +129,16 @@ static inline void reset_lazy_tlbstate(void) #define local_flush_tlb() __flush_tlb() +#define flush_tlb_mm(mm) flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL) + +#define flush_tlb_range(vma, start, end) \ + flush_tlb_mm_range(vma->vm_mm, start, end, vma->vm_flags) + extern void flush_tlb_all(void); extern void flush_tlb_current_task(void); -extern void flush_tlb_mm(struct mm_struct *); extern void flush_tlb_page(struct vm_area_struct *, unsigned long); -extern void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end); +extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, + unsigned long end, unsigned long vmflag); #define flush_tlb() flush_tlb_current_task() diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 5911f61e300e..481737def84a 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -301,23 +301,10 @@ void flush_tlb_current_task(void) preempt_enable(); } -void flush_tlb_mm(struct mm_struct *mm) -{ - preempt_disable(); - - if (current->active_mm == mm) { - if (current->mm) - local_flush_tlb(); - else - leave_mm(smp_processor_id()); - } - if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); - - preempt_enable(); -} - -#ifdef CONFIG_TRANSPARENT_HUGEPAGE +/* + * It can find out the THP large page, or + * HUGETLB page in tlb_flush when THP disabled + */ static inline unsigned long has_large_page(struct mm_struct *mm, unsigned long start, unsigned long end) { @@ -339,68 +326,61 @@ static inline unsigned long has_large_page(struct mm_struct *mm, } return 0; } -#else -static inline unsigned long has_large_page(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - return 0; -} -#endif -void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - struct mm_struct *mm; - if (vma->vm_flags & VM_HUGETLB || tlb_flushall_shift == -1) { -flush_all: - flush_tlb_mm(vma->vm_mm); - return; - } +void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, + unsigned long end, unsigned long vmflag) +{ + unsigned long addr; + unsigned act_entries, tlb_entries = 0; preempt_disable(); - mm = vma->vm_mm; - if (current->active_mm == mm) { - if (current->mm) { - unsigned long addr, vmflag = vma->vm_flags; - unsigned act_entries, tlb_entries = 0; + if (current->active_mm != mm) + goto flush_all; - if (vmflag & VM_EXEC) - tlb_entries = tlb_lli_4k[ENTRIES]; - else - tlb_entries = tlb_lld_4k[ENTRIES]; - - act_entries = tlb_entries > mm->total_vm ? - mm->total_vm : tlb_entries; + if (!current->mm) { + leave_mm(smp_processor_id()); + goto flush_all; + } - if ((end - start) >> PAGE_SHIFT > - act_entries >> tlb_flushall_shift) - local_flush_tlb(); - else { - if (has_large_page(mm, start, end)) { - preempt_enable(); - goto flush_all; - } - for (addr = start; addr < end; - addr += PAGE_SIZE) - __flush_tlb_single(addr); + if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 + || vmflag == VM_HUGETLB) { + local_flush_tlb(); + goto flush_all; + } - if (cpumask_any_but(mm_cpumask(mm), - smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(mm_cpumask(mm), mm, - start, end); - preempt_enable(); - return; - } - } else { - leave_mm(smp_processor_id()); + /* In modern CPU, last level tlb used for both data/ins */ + if (vmflag & VM_EXEC) + tlb_entries = tlb_lli_4k[ENTRIES]; + else + tlb_entries = tlb_lld_4k[ENTRIES]; + /* Assume all of TLB entries was occupied by this task */ + act_entries = mm->total_vm > tlb_entries ? tlb_entries : mm->total_vm; + + /* tlb_flushall_shift is on balance point, details in commit log */ + if ((end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift) + local_flush_tlb(); + else { + if (has_large_page(mm, start, end)) { + local_flush_tlb(); + goto flush_all; } + /* flush range by one by one 'invlpg' */ + for (addr = start; addr < end; addr += PAGE_SIZE) + __flush_tlb_single(addr); + + if (cpumask_any_but(mm_cpumask(mm), + smp_processor_id()) < nr_cpu_ids) + flush_tlb_others(mm_cpumask(mm), mm, start, end); + preempt_enable(); + return; } + +flush_all: if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); preempt_enable(); } - void flush_tlb_page(struct vm_area_struct *vma, unsigned long start) { struct mm_struct *mm = vma->vm_mm; -- GitLab From 52aec3308db85f4e9f5c8b9f5dc4fbd0138c6fa4 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:23 +0800 Subject: [PATCH 3107/6849] x86/tlb: replace INVALIDATE_TLB_VECTOR by CALL_FUNCTION_VECTOR There are 32 INVALIDATE_TLB_VECTOR now in kernel. That is quite big amount of vector in IDT. But it is still not enough, since modern x86 sever has more cpu number. That still causes heavy lock contention in TLB flushing. The patch using generic smp call function to replace it. That saved 32 vector number in IDT, and resolved the lock contention in TLB flushing on large system. In the NHM EX machine 4P * 8cores * HT = 64 CPUs, hackbench pthread has 3% performance increase. Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-9-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/entry_arch.h | 9 -- arch/x86/include/asm/irq_vectors.h | 11 -- arch/x86/kernel/entry_64.S | 18 --- arch/x86/kernel/irqinit.c | 73 --------- arch/x86/mm/tlb.c | 242 ++++++----------------------- 5 files changed, 47 insertions(+), 306 deletions(-) diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index 0baa628e330c..40afa0005c69 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h @@ -15,15 +15,6 @@ BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) - -.irp idx,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \ - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 -.if NUM_INVALIDATE_TLB_VECTORS > \idx -BUILD_INTERRUPT3(invalidate_interrupt\idx, - (INVALIDATE_TLB_VECTOR_START)+\idx, - smp_invalidate_interrupt) -.endif -.endr #endif BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 4b4448761e88..1508e518c7e3 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -119,17 +119,6 @@ */ #define LOCAL_TIMER_VECTOR 0xef -/* up to 32 vectors used for spreading out TLB flushes: */ -#if NR_CPUS <= 32 -# define NUM_INVALIDATE_TLB_VECTORS (NR_CPUS) -#else -# define NUM_INVALIDATE_TLB_VECTORS (32) -#endif - -#define INVALIDATE_TLB_VECTOR_END (0xee) -#define INVALIDATE_TLB_VECTOR_START \ - (INVALIDATE_TLB_VECTOR_END-NUM_INVALIDATE_TLB_VECTORS+1) - #define NR_VECTORS 256 #define FPU_IRQ 13 diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 7d65133b51be..bcf28e1ce1a7 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1048,24 +1048,6 @@ apicinterrupt LOCAL_TIMER_VECTOR \ apicinterrupt X86_PLATFORM_IPI_VECTOR \ x86_platform_ipi smp_x86_platform_ipi -#ifdef CONFIG_SMP - ALIGN - INTR_FRAME -.irp idx,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \ - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 -.if NUM_INVALIDATE_TLB_VECTORS > \idx -ENTRY(invalidate_interrupt\idx) - pushq_cfi $~(INVALIDATE_TLB_VECTOR_START+\idx) - jmp .Lcommon_invalidate_interrupt0 - CFI_ADJUST_CFA_OFFSET -8 -END(invalidate_interrupt\idx) -.endif -.endr - CFI_ENDPROC -apicinterrupt INVALIDATE_TLB_VECTOR_START, \ - invalidate_interrupt0, smp_invalidate_interrupt -#endif - apicinterrupt THRESHOLD_APIC_VECTOR \ threshold_interrupt smp_threshold_interrupt apicinterrupt THERMAL_APIC_VECTOR \ diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 252981afd6c4..6e03b0d69138 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -171,79 +171,6 @@ static void __init smp_intr_init(void) */ alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); - /* IPIs for invalidation */ -#define ALLOC_INVTLB_VEC(NR) \ - alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+NR, \ - invalidate_interrupt##NR) - - switch (NUM_INVALIDATE_TLB_VECTORS) { - default: - ALLOC_INVTLB_VEC(31); - case 31: - ALLOC_INVTLB_VEC(30); - case 30: - ALLOC_INVTLB_VEC(29); - case 29: - ALLOC_INVTLB_VEC(28); - case 28: - ALLOC_INVTLB_VEC(27); - case 27: - ALLOC_INVTLB_VEC(26); - case 26: - ALLOC_INVTLB_VEC(25); - case 25: - ALLOC_INVTLB_VEC(24); - case 24: - ALLOC_INVTLB_VEC(23); - case 23: - ALLOC_INVTLB_VEC(22); - case 22: - ALLOC_INVTLB_VEC(21); - case 21: - ALLOC_INVTLB_VEC(20); - case 20: - ALLOC_INVTLB_VEC(19); - case 19: - ALLOC_INVTLB_VEC(18); - case 18: - ALLOC_INVTLB_VEC(17); - case 17: - ALLOC_INVTLB_VEC(16); - case 16: - ALLOC_INVTLB_VEC(15); - case 15: - ALLOC_INVTLB_VEC(14); - case 14: - ALLOC_INVTLB_VEC(13); - case 13: - ALLOC_INVTLB_VEC(12); - case 12: - ALLOC_INVTLB_VEC(11); - case 11: - ALLOC_INVTLB_VEC(10); - case 10: - ALLOC_INVTLB_VEC(9); - case 9: - ALLOC_INVTLB_VEC(8); - case 8: - ALLOC_INVTLB_VEC(7); - case 7: - ALLOC_INVTLB_VEC(6); - case 6: - ALLOC_INVTLB_VEC(5); - case 5: - ALLOC_INVTLB_VEC(4); - case 4: - ALLOC_INVTLB_VEC(3); - case 3: - ALLOC_INVTLB_VEC(2); - case 2: - ALLOC_INVTLB_VEC(1); - case 1: - ALLOC_INVTLB_VEC(0); - break; - } - /* IPI for generic function call */ alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 481737def84a..2b5f506a7655 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -28,34 +28,14 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) * * More scalable flush, from Andi Kleen * - * To avoid global state use 8 different call vectors. - * Each CPU uses a specific vector to trigger flushes on other - * CPUs. Depending on the received vector the target CPUs look into - * the right array slot for the flush data. - * - * With more than 8 CPUs they are hashed to the 8 available - * vectors. The limited global vector space forces us to this right now. - * In future when interrupts are split into per CPU domains this could be - * fixed, at the cost of triggering multiple IPIs in some cases. + * Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi */ -union smp_flush_state { - struct { - struct mm_struct *flush_mm; - unsigned long flush_start; - unsigned long flush_end; - raw_spinlock_t tlbstate_lock; - DECLARE_BITMAP(flush_cpumask, NR_CPUS); - }; - char pad[INTERNODE_CACHE_BYTES]; -} ____cacheline_internodealigned_in_smp; - -/* State is put into the per CPU data section, but padded - to a full cache line because other CPUs can access it and we don't - want false sharing in the per cpu data segment. */ -static union smp_flush_state flush_state[NUM_INVALIDATE_TLB_VECTORS]; - -static DEFINE_PER_CPU_READ_MOSTLY(int, tlb_vector_offset); +struct flush_tlb_info { + struct mm_struct *flush_mm; + unsigned long flush_start; + unsigned long flush_end; +}; /* * We cannot call mmdrop() because we are in interrupt context, @@ -74,28 +54,25 @@ void leave_mm(int cpu) EXPORT_SYMBOL_GPL(leave_mm); /* - * * The flush IPI assumes that a thread switch happens in this order: * [cpu0: the cpu that switches] * 1) switch_mm() either 1a) or 1b) * 1a) thread switch to a different mm - * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); - * Stop ipi delivery for the old mm. This is not synchronized with - * the other cpus, but smp_invalidate_interrupt ignore flush ipis - * for the wrong mm, and in the worst case we perform a superfluous - * tlb flush. - * 1a2) set cpu mmu_state to TLBSTATE_OK - * Now the smp_invalidate_interrupt won't call leave_mm if cpu0 - * was in lazy tlb mode. - * 1a3) update cpu active_mm + * 1a1) set cpu_tlbstate to TLBSTATE_OK + * Now the tlb flush NMI handler flush_tlb_func won't call leave_mm + * if cpu0 was in lazy tlb mode. + * 1a2) update cpu active_mm * Now cpu0 accepts tlb flushes for the new mm. - * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); + * 1a3) cpu_set(cpu, new_mm->cpu_vm_mask); * Now the other cpus will send tlb flush ipis. * 1a4) change cr3. + * 1a5) cpu_clear(cpu, old_mm->cpu_vm_mask); + * Stop ipi delivery for the old mm. This is not synchronized with + * the other cpus, but flush_tlb_func ignore flush ipis for the wrong + * mm, and in the worst case we perform a superfluous tlb flush. * 1b) thread switch without mm change - * cpu active_mm is correct, cpu0 already handles - * flush ipis. - * 1b1) set cpu mmu_state to TLBSTATE_OK + * cpu active_mm is correct, cpu0 already handles flush ipis. + * 1b1) set cpu_tlbstate to TLBSTATE_OK * 1b2) test_and_set the cpu bit in cpu_vm_mask. * Atomically set the bit [other cpus will start sending flush ipis], * and test the bit. @@ -108,186 +85,61 @@ EXPORT_SYMBOL_GPL(leave_mm); * runs in kernel space, the cpu could load tlb entries for user space * pages. * - * The good news is that cpu mmu_state is local to each cpu, no + * The good news is that cpu_tlbstate is local to each cpu, no * write/read ordering problems. */ /* - * TLB flush IPI: - * + * TLB flush funcation: * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. * 2) Leave the mm if we are in the lazy tlb mode. - * - * Interrupts are disabled. - */ - -/* - * FIXME: use of asmlinkage is not consistent. On x86_64 it's noop - * but still used for documentation purpose but the usage is slightly - * inconsistent. On x86_32, asmlinkage is regparm(0) but interrupt - * entry calls in with the first parameter in %eax. Maybe define - * intrlinkage? */ -#ifdef CONFIG_X86_64 -asmlinkage -#endif -void smp_invalidate_interrupt(struct pt_regs *regs) +static void flush_tlb_func(void *info) { - unsigned int cpu; - unsigned int sender; - union smp_flush_state *f; - - cpu = smp_processor_id(); - /* - * orig_rax contains the negated interrupt vector. - * Use that to determine where the sender put the data. - */ - sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START; - f = &flush_state[sender]; - - if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask))) - goto out; - /* - * This was a BUG() but until someone can quote me the - * line from the intel manual that guarantees an IPI to - * multiple CPUs is retried _only_ on the erroring CPUs - * its staying as a return - * - * BUG(); - */ - - if (f->flush_mm == this_cpu_read(cpu_tlbstate.active_mm)) { - if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { - if (f->flush_end == TLB_FLUSH_ALL - || !cpu_has_invlpg) - local_flush_tlb(); - else if (!f->flush_end) - __flush_tlb_single(f->flush_start); - else { - unsigned long addr; - addr = f->flush_start; - while (addr < f->flush_end) { - __flush_tlb_single(addr); - addr += PAGE_SIZE; - } - } - } else - leave_mm(cpu); - } -out: - ack_APIC_irq(); - smp_mb__before_clear_bit(); - cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask)); - smp_mb__after_clear_bit(); - inc_irq_stat(irq_tlb_count); -} + struct flush_tlb_info *f = info; -static void flush_tlb_others_ipi(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - unsigned int sender; - union smp_flush_state *f; - - /* Caller has disabled preemption */ - sender = this_cpu_read(tlb_vector_offset); - f = &flush_state[sender]; - - if (nr_cpu_ids > NUM_INVALIDATE_TLB_VECTORS) - raw_spin_lock(&f->tlbstate_lock); - - f->flush_mm = mm; - f->flush_start = start; - f->flush_end = end; - if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) { - /* - * We have to send the IPI only to - * CPUs affected. - */ - apic->send_IPI_mask(to_cpumask(f->flush_cpumask), - INVALIDATE_TLB_VECTOR_START + sender); - - while (!cpumask_empty(to_cpumask(f->flush_cpumask))) - cpu_relax(); - } + if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) + return; + + if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { + if (f->flush_end == TLB_FLUSH_ALL || !cpu_has_invlpg) + local_flush_tlb(); + else if (!f->flush_end) + __flush_tlb_single(f->flush_start); + else { + unsigned long addr; + addr = f->flush_start; + while (addr < f->flush_end) { + __flush_tlb_single(addr); + addr += PAGE_SIZE; + } + } + } else + leave_mm(smp_processor_id()); - f->flush_mm = NULL; - f->flush_start = 0; - f->flush_end = 0; - if (nr_cpu_ids > NUM_INVALIDATE_TLB_VECTORS) - raw_spin_unlock(&f->tlbstate_lock); } void native_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long start, unsigned long end) { + struct flush_tlb_info info; + info.flush_mm = mm; + info.flush_start = start; + info.flush_end = end; + if (is_uv_system()) { unsigned int cpu; cpu = smp_processor_id(); cpumask = uv_flush_tlb_others(cpumask, mm, start, end, cpu); if (cpumask) - flush_tlb_others_ipi(cpumask, mm, start, end); + smp_call_function_many(cpumask, flush_tlb_func, + &info, 1); return; } - flush_tlb_others_ipi(cpumask, mm, start, end); -} - -static void __cpuinit calculate_tlb_offset(void) -{ - int cpu, node, nr_node_vecs, idx = 0; - /* - * we are changing tlb_vector_offset for each CPU in runtime, but this - * will not cause inconsistency, as the write is atomic under X86. we - * might see more lock contentions in a short time, but after all CPU's - * tlb_vector_offset are changed, everything should go normal - * - * Note: if NUM_INVALIDATE_TLB_VECTORS % nr_online_nodes !=0, we might - * waste some vectors. - **/ - if (nr_online_nodes > NUM_INVALIDATE_TLB_VECTORS) - nr_node_vecs = 1; - else - nr_node_vecs = NUM_INVALIDATE_TLB_VECTORS/nr_online_nodes; - - for_each_online_node(node) { - int node_offset = (idx % NUM_INVALIDATE_TLB_VECTORS) * - nr_node_vecs; - int cpu_offset = 0; - for_each_cpu(cpu, cpumask_of_node(node)) { - per_cpu(tlb_vector_offset, cpu) = node_offset + - cpu_offset; - cpu_offset++; - cpu_offset = cpu_offset % nr_node_vecs; - } - idx++; - } -} - -static int __cpuinit tlb_cpuhp_notify(struct notifier_block *n, - unsigned long action, void *hcpu) -{ - switch (action & 0xf) { - case CPU_ONLINE: - case CPU_DEAD: - calculate_tlb_offset(); - } - return NOTIFY_OK; -} - -static int __cpuinit init_smp_flush(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(flush_state); i++) - raw_spin_lock_init(&flush_state[i].tlbstate_lock); - - calculate_tlb_offset(); - hotcpu_notifier(tlb_cpuhp_notify, 0); - return 0; + smp_call_function_many(cpumask, flush_tlb_func, &info, 1); } -core_initcall(init_smp_flush); void flush_tlb_current_task(void) { -- GitLab From effee4b9b3b0aa5770bcd98de5f672b05b27703c Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Thu, 28 Jun 2012 09:02:24 +0800 Subject: [PATCH 3108/6849] x86/tlb: do flush_tlb_kernel_range by 'invlpg' This patch do flush_tlb_kernel_range by 'invlpg'. The performance pay and gain was analyzed in previous patch (x86/flush_tlb: try flush_tlb_single one by one in flush_tlb_range). In the testing: http://lkml.org/lkml/2012/6/21/10 The pay is mostly covered by long kernel path, but the gain is still quite clear, memory access in user APP can increase 30+% when kernel execute this funtion. Signed-off-by: Alex Shi Link: http://lkml.kernel.org/r/1340845344-27557-10-git-send-email-alex.shi@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/tlbflush.h | 13 +++++++------ arch/x86/mm/tlb.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 621b959e1dbf..b5a27bd77669 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -123,6 +123,12 @@ static inline void reset_lazy_tlbstate(void) { } +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ + flush_tlb_all(); +} + #else /* SMP */ #include @@ -139,6 +145,7 @@ extern void flush_tlb_current_task(void); extern void flush_tlb_page(struct vm_area_struct *, unsigned long); extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long vmflag); +extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); #define flush_tlb() flush_tlb_current_task() @@ -168,10 +175,4 @@ static inline void reset_lazy_tlbstate(void) native_flush_tlb_others(mask, mm, start, end) #endif -static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) -{ - flush_tlb_all(); -} - #endif /* _ASM_X86_TLBFLUSH_H */ diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 2b5f506a7655..613cd83e8c0c 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -264,6 +264,36 @@ void flush_tlb_all(void) on_each_cpu(do_flush_tlb_all, NULL, 1); } +static void do_kernel_range_flush(void *info) +{ + struct flush_tlb_info *f = info; + unsigned long addr; + + /* flush range by one by one 'invlpg' */ + for (addr = f->flush_start; addr < f->flush_end; addr += PAGE_SIZE) + __flush_tlb_single(addr); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned act_entries; + struct flush_tlb_info info; + + /* In modern CPU, last level tlb used for both data/ins */ + act_entries = tlb_lld_4k[ENTRIES]; + + /* Balance as user space task's flush, a bit conservative */ + if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 || + (end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift) + + on_each_cpu(do_flush_tlb_all, NULL, 1); + else { + info.flush_start = start; + info.flush_end = end; + on_each_cpu(do_kernel_range_flush, &info, 1); + } +} + #ifdef CONFIG_DEBUG_TLBFLUSH static ssize_t tlbflush_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) -- GitLab From a2028b2376a858cb68a7fcc129f6508f59b45381 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Jun 2012 15:08:19 +0000 Subject: [PATCH 3109/6849] cnic: Fix occasional NULL pointer dereference during reboot. We register with bnx2x before we allocate ctx_tbl structure, so it is possible for bnx2x to call cnic_ctl before the structure is allocated. This can sometimes cause NULL pointer dereference of cp->ctx_tbl. We fix this by adding simple checking for valid state before proceeding. The cnic_ctl call is RCU protected so we don't have to deal with race conditions. Because of the additional checking, we need to finish the shutdown before clearing the CNIC_UP flag. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 0e9be2ba924e..31b05ad325d0 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -291,6 +291,9 @@ static int cnic_get_l5_cid(struct cnic_local *cp, u32 cid, u32 *l5_cid) { u32 i; + if (!cp->ctx_tbl) + return -EINVAL; + for (i = 0; i < cp->max_cid_space; i++) { if (cp->ctx_tbl[i].cid == cid) { *l5_cid = i; @@ -3220,6 +3223,9 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info) u32 l5_cid; struct cnic_local *cp = dev->cnic_priv; + if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) + break; + if (cnic_get_l5_cid(cp, cid, &l5_cid) == 0) { struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; @@ -4253,8 +4259,6 @@ static int cnic_cm_shutdown(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; int i; - cp->stop_cm(dev); - if (!cp->csk_tbl) return 0; @@ -5290,6 +5294,7 @@ static void cnic_stop_hw(struct cnic_dev *dev) i++; } cnic_shutdown_rings(dev); + cp->stop_cm(dev); clear_bit(CNIC_F_CNIC_UP, &dev->flags); RCU_INIT_POINTER(cp->ulp_ops[CNIC_ULP_L4], NULL); synchronize_rcu(); -- GitLab From 78ea22e8042b8a55c5a047869ed1fd9b3711340c Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Wed, 27 Jun 2012 15:08:20 +0000 Subject: [PATCH 3110/6849] cnic: Read bnx2x function number from internal register so that it will work on any hypervisor. Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 31b05ad325d0..5980443cb895 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -4988,8 +4988,14 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) cp->port_mode = CHIP_PORT_MODE_NONE; if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { - u32 val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR); + u32 val; + + pci_read_config_dword(dev->pcidev, PCICFG_ME_REGISTER, &val); + cp->func = (u8) ((val & ME_REG_ABS_PF_NUM) >> + ME_REG_ABS_PF_NUM_SHIFT); + func = CNIC_FUNC(cp); + val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR); if (!(val & 1)) val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN); else -- GitLab From 1f85d58cdf15354a7120fc9ccc9bb9c45b53af88 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Jun 2012 15:08:21 +0000 Subject: [PATCH 3111/6849] cnic: Remove uio mem[0]. This memory region is no longer used. Userspace gets the BAR address directly from sysfs. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 5980443cb895..ec43df1668c1 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -1063,10 +1063,7 @@ static int cnic_init_uio(struct cnic_dev *dev) uinfo = &udev->cnic_uinfo; - uinfo->mem[0].addr = dev->netdev->base_addr; - uinfo->mem[0].internal_addr = dev->regview; - uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; - uinfo->mem[0].memtype = UIO_MEM_PHYS; + uinfo->mem[0].memtype = UIO_MEM_NONE; if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & -- GitLab From 7bc910fd8f953c131de055d9871679a598db8dc6 Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Wed, 27 Jun 2012 15:08:22 +0000 Subject: [PATCH 3112/6849] cnic: Handle RAMROD_CMD_ID_CLOSE error. If firmware returns error status, proceed to close the iSCSI connection. Update version to 2.5.11. Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 9 +++++++++ drivers/net/ethernet/broadcom/cnic_if.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index ec43df1668c1..f897306b0eb7 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -3953,6 +3953,15 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe) cnic_cm_upcall(cp, csk, opcode); break; + case L5CM_RAMROD_CMD_ID_CLOSE: + if (l4kcqe->status != 0) { + netdev_warn(dev->netdev, "RAMROD CLOSE compl with " + "status 0x%x\n", l4kcqe->status); + opcode = L4_KCQE_OPCODE_VALUE_CLOSE_COMP; + /* Fall through */ + } else { + break; + } case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED: case L4_KCQE_OPCODE_VALUE_CLOSE_COMP: case L4_KCQE_OPCODE_VALUE_RESET_COMP: diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index d63d45591c1f..54f68f07692e 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -14,8 +14,8 @@ #include "bnx2x/bnx2x_mfw_req.h" -#define CNIC_MODULE_VERSION "2.5.10" -#define CNIC_MODULE_RELDATE "March 21, 2012" +#define CNIC_MODULE_VERSION "2.5.11" +#define CNIC_MODULE_RELDATE "June 27, 2012" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- GitLab From 7947c9ce17c4b51122cfcef3c2e9e2632eb96a67 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Jun 2012 15:08:23 +0000 Subject: [PATCH 3113/6849] bnx2: Add "fall through" comments to indicate that the mising break statements are intended. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 9b69a628641c..e6116ecddd16 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -1972,22 +1972,26 @@ bnx2_remote_phy_event(struct bnx2 *bp) switch (speed) { case BNX2_LINK_STATUS_10HALF: bp->duplex = DUPLEX_HALF; + /* fall through */ case BNX2_LINK_STATUS_10FULL: bp->line_speed = SPEED_10; break; case BNX2_LINK_STATUS_100HALF: bp->duplex = DUPLEX_HALF; + /* fall through */ case BNX2_LINK_STATUS_100BASE_T4: case BNX2_LINK_STATUS_100FULL: bp->line_speed = SPEED_100; break; case BNX2_LINK_STATUS_1000HALF: bp->duplex = DUPLEX_HALF; + /* fall through */ case BNX2_LINK_STATUS_1000FULL: bp->line_speed = SPEED_1000; break; case BNX2_LINK_STATUS_2500HALF: bp->duplex = DUPLEX_HALF; + /* fall through */ case BNX2_LINK_STATUS_2500FULL: bp->line_speed = SPEED_2500; break; -- GitLab From d2e553bca89596b7ac35f8abcec9c9b93f772fc2 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Jun 2012 15:08:24 +0000 Subject: [PATCH 3114/6849] bnx2: Add missing netif_tx_disable() in bnx2_close() to stop all tx queues. Update version to 2.2.3. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index e6116ecddd16..9eb7624639b9 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -58,8 +58,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.2.2" -#define DRV_MODULE_RELDATE "June 16, 2012" +#define DRV_MODULE_VERSION "2.2.3" +#define DRV_MODULE_RELDATE "June 27, 2012" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw" @@ -6703,6 +6703,7 @@ bnx2_close(struct net_device *dev) bnx2_disable_int_sync(bp); bnx2_napi_disable(bp); + netif_tx_disable(dev); del_timer_sync(&bp->timer); bnx2_shutdown_chip(bp); bnx2_free_irq(bp); -- GitLab From 2ca9b2aa0d5a43e954789e0da675a826b83932b7 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 27 Jun 2012 03:45:20 +0000 Subject: [PATCH 3115/6849] net: fec: reset phy after pinctrl setup In case that bootloader or platform initialization does not set up fec pins, the fec_reset_phy will not be able to succeed, because fec_reset_phy is currently called before devm_pinctrl_get_select_default. Move fec_reset_phy call to the place between devm_pinctrl_get_select_default and fec_enet_init to have above case be taken care. Signed-off-by: Shawn Guo Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index ff7f4c5115a1..e868a377c898 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1593,8 +1593,6 @@ fec_probe(struct platform_device *pdev) fep->phy_interface = ret; } - fec_reset_phy(pdev); - for (i = 0; i < FEC_IRQ_NUM; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) { @@ -1634,6 +1632,8 @@ fec_probe(struct platform_device *pdev) clk_prepare_enable(fep->clk_ahb); clk_prepare_enable(fep->clk_ipg); + fec_reset_phy(pdev); + ret = fec_enet_init(ndev); if (ret) goto failed_init; -- GitLab From 5fa9c0fe3ec0a008352d4a4fb8d972a437183404 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 27 Jun 2012 03:45:21 +0000 Subject: [PATCH 3116/6849] net: fec: enable regulator for fec phy If bootloader or platform initialization code does not enable the power supply to fec phy, we need to do it in fec driver before calling fec_reset_phy to have the phy powered on. Signed-off-by: Shawn Guo Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index e868a377c898..4dce9e3ac83a 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -1546,6 +1547,7 @@ fec_probe(struct platform_device *pdev) const struct of_device_id *of_id; static int dev_id; struct pinctrl *pinctrl; + struct regulator *reg_phy; of_id = of_match_device(fec_dt_ids, &pdev->dev); if (of_id) @@ -1632,6 +1634,16 @@ fec_probe(struct platform_device *pdev) clk_prepare_enable(fep->clk_ahb); clk_prepare_enable(fep->clk_ipg); + reg_phy = devm_regulator_get(&pdev->dev, "phy"); + if (!IS_ERR(reg_phy)) { + ret = regulator_enable(reg_phy); + if (ret) { + dev_err(&pdev->dev, + "Failed to enable phy regulator: %d\n", ret); + goto failed_regulator; + } + } + fec_reset_phy(pdev); ret = fec_enet_init(ndev); @@ -1655,6 +1667,7 @@ failed_register: fec_enet_mii_remove(fep); failed_mii_init: failed_init: +failed_regulator: clk_disable_unprepare(fep->clk_ahb); clk_disable_unprepare(fep->clk_ipg); failed_pin: -- GitLab From 119fc007766fc6ec6cff0f696d73cebb6f2cbe58 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 27 Jun 2012 03:45:22 +0000 Subject: [PATCH 3117/6849] net: fec: use managed function devm_gpio_request_one Using gpio_request_one will require the probe fail-out call gpio_free, which is missing currently. Change to use devm_gpio_request_one to fix the problem. Signed-off-by: Shawn Guo Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 4dce9e3ac83a..f174070646f5 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1513,7 +1513,8 @@ static void __devinit fec_reset_phy(struct platform_device *pdev) return; phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); - err = gpio_request_one(phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset"); + err = devm_gpio_request_one(&pdev->dev, phy_reset, + GPIOF_OUT_INIT_LOW, "phy-reset"); if (err) { pr_debug("FEC: failed to get gpio phy-reset: %d\n", err); return; -- GitLab From c9040af264de8a425b0efabfcc18a6ce47d0f21f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 27 Jun 2012 03:45:23 +0000 Subject: [PATCH 3118/6849] net: fec: phy-reset-gpios is optional The phy-reset-gpios is an optional property for fec device tree boot. Change the binding document to match the driver code. Signed-off-by: Shawn Guo Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/fsl-fec.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt index 7ab9e1a2d8be..0428920aacc7 100644 --- a/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -7,10 +7,10 @@ Required properties: - phy-mode : String, operation mode of the PHY interface. Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii", "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii". -- phy-reset-gpios : Should specify the gpio for phy reset Optional properties: - local-mac-address : 6 bytes, mac address +- phy-reset-gpios : Should specify the gpio for phy reset Example: -- GitLab From a3caad0a160c03b7238a2518fa89abda78adef1e Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 27 Jun 2012 03:45:24 +0000 Subject: [PATCH 3119/6849] net: fec: add phy-reset-duration for device tree probe Different boards may require different phy reset duration. Add property phy-reset-duration for device tree probe, so that the boards that need a longer reset duration can specify it in their device tree. Signed-off-by: Shawn Guo Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/fsl-fec.txt | 4 ++++ drivers/net/ethernet/freescale/fec.c | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt index 0428920aacc7..f7a2fefc8ef1 100644 --- a/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -11,6 +11,10 @@ Required properties: Optional properties: - local-mac-address : 6 bytes, mac address - phy-reset-gpios : Should specify the gpio for phy reset +- phy-reset-duration : Reset duration in milliseconds. Should present + only if property "phy-reset-gpios" is available. Missing the property + will have the duration be 1 millisecond. Numbers greater than 1000 are + invalid and 1 millisecond will be used instead. Example: diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index f174070646f5..dafd797a6069 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1507,11 +1507,17 @@ static int __devinit fec_get_phy_mode_dt(struct platform_device *pdev) static void __devinit fec_reset_phy(struct platform_device *pdev) { int err, phy_reset; + int msec = 1; struct device_node *np = pdev->dev.of_node; if (!np) return; + of_property_read_u32(np, "phy-reset-duration", &msec); + /* A sane reset duration should not be longer than 1s */ + if (msec > 1000) + msec = 1; + phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); err = devm_gpio_request_one(&pdev->dev, phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset"); @@ -1519,7 +1525,7 @@ static void __devinit fec_reset_phy(struct platform_device *pdev) pr_debug("FEC: failed to get gpio phy-reset: %d\n", err); return; } - msleep(1); + msleep(msec); gpio_set_value(phy_reset, 1); } #else /* CONFIG_OF */ -- GitLab From ac28b9f8cd66d6bc54f8063df59e99abd62173a4 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Jun 2012 07:33:35 +0000 Subject: [PATCH 3120/6849] netdev/phy: Handle IEEE802.3 clause 45 Ethernet PHYs The IEEE802.3 clause 45 MDIO bus protocol allows for directly addressing PHY registers using a 21 bit address, and is used by many 10G Ethernet PHYS. Already existing is the ability of MDIO bus drivers to use clause 45, with the MII_ADDR_C45 flag. Here we add struct phy_c45_device_ids to hold the device identifier registers present in clause 45. struct phy_device gets a couple of new fields: c45_ids to hold the identifiers and is_c45 to signal that it is clause 45. get_phy_device() gets a new parameter is_c45 to indicate that the PHY device should use the clause 45 protocol, and its callers are adjusted to pass false. The follow-on patch to of_mdio.c will pass true where appropriate. EXPORT phy_device_create() so that the follow-on patch to of_mdio.c can use it to create phy devices for PHYs, that have non-standard device identifier registers, based on the device tree bindings. Signed-off-by: David Daney Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 2 +- drivers/net/phy/phy_device.c | 105 ++++++++++++++++++++++++++++++++--- drivers/of/of_mdio.c | 2 +- include/linux/phy.h | 18 +++++- 4 files changed, 116 insertions(+), 11 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 31470b0d0c32..2cee6d218d21 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -232,7 +232,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) struct phy_device *phydev; int err; - phydev = get_phy_device(bus, addr); + phydev = get_phy_device(bus, addr, false); if (IS_ERR(phydev) || phydev == NULL) return phydev; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 18ab0daf4490..ef4cdeebedd6 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -152,8 +152,8 @@ int phy_scan_fixups(struct phy_device *phydev) } EXPORT_SYMBOL(phy_scan_fixups); -static struct phy_device* phy_device_create(struct mii_bus *bus, - int addr, int phy_id) +struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, + bool is_c45, struct phy_c45_device_ids *c45_ids) { struct phy_device *dev; @@ -174,8 +174,11 @@ static struct phy_device* phy_device_create(struct mii_bus *bus, dev->autoneg = AUTONEG_ENABLE; + dev->is_c45 = is_c45; dev->addr = addr; dev->phy_id = phy_id; + if (c45_ids) + dev->c45_ids = *c45_ids; dev->bus = bus; dev->dev.parent = bus->parent; dev->dev.bus = &mdio_bus_type; @@ -200,20 +203,99 @@ static struct phy_device* phy_device_create(struct mii_bus *bus, return dev; } +EXPORT_SYMBOL(phy_device_create); + +/** + * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs. + * @bus: the target MII bus + * @addr: PHY address on the MII bus + * @phy_id: where to store the ID retrieved. + * @c45_ids: where to store the c45 ID information. + * + * If the PHY devices-in-package appears to be valid, it and the + * corresponding identifiers are stored in @c45_ids, zero is stored + * in @phy_id. Otherwise 0xffffffff is stored in @phy_id. Returns + * zero on success. + * + */ +static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id, + struct phy_c45_device_ids *c45_ids) { + int phy_reg; + int i, reg_addr; + const int num_ids = ARRAY_SIZE(c45_ids->device_ids); + + /* Find first non-zero Devices In package. Device + * zero is reserved, so don't probe it. + */ + for (i = 1; + i < num_ids && c45_ids->devices_in_package == 0; + i++) { + reg_addr = MII_ADDR_C45 | i << 16 | 6; + phy_reg = mdiobus_read(bus, addr, reg_addr); + if (phy_reg < 0) + return -EIO; + c45_ids->devices_in_package = (phy_reg & 0xffff) << 16; + + reg_addr = MII_ADDR_C45 | i << 16 | 5; + phy_reg = mdiobus_read(bus, addr, reg_addr); + if (phy_reg < 0) + return -EIO; + c45_ids->devices_in_package |= (phy_reg & 0xffff); + + /* If mostly Fs, there is no device there, + * let's get out of here. + */ + if ((c45_ids->devices_in_package & 0x1fffffff) == 0x1fffffff) { + *phy_id = 0xffffffff; + return 0; + } + } + + /* Now probe Device Identifiers for each device present. */ + for (i = 1; i < num_ids; i++) { + if (!(c45_ids->devices_in_package & (1 << i))) + continue; + + reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID1; + phy_reg = mdiobus_read(bus, addr, reg_addr); + if (phy_reg < 0) + return -EIO; + c45_ids->device_ids[i] = (phy_reg & 0xffff) << 16; + + reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID2; + phy_reg = mdiobus_read(bus, addr, reg_addr); + if (phy_reg < 0) + return -EIO; + c45_ids->device_ids[i] |= (phy_reg & 0xffff); + } + *phy_id = 0; + return 0; +} /** * get_phy_id - reads the specified addr for its ID. * @bus: the target MII bus * @addr: PHY address on the MII bus * @phy_id: where to store the ID retrieved. + * @is_c45: If true the PHY uses the 802.3 clause 45 protocol + * @c45_ids: where to store the c45 ID information. + * + * Description: In the case of a 802.3-c22 PHY, reads the ID registers + * of the PHY at @addr on the @bus, stores it in @phy_id and returns + * zero on success. + * + * In the case of a 802.3-c45 PHY, get_phy_c45_ids() is invoked, and + * its return value is in turn returned. * - * Description: Reads the ID registers of the PHY at @addr on the - * @bus, stores it in @phy_id and returns zero on success. */ -static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) +static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, + bool is_c45, struct phy_c45_device_ids *c45_ids) { int phy_reg; + if (is_c45) + return get_phy_c45_ids(bus, addr, phy_id, c45_ids); + /* Grab the bits from PHYIR1, and put them * in the upper half */ phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); @@ -238,17 +320,19 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) * get_phy_device - reads the specified PHY device and returns its @phy_device struct * @bus: the target MII bus * @addr: PHY address on the MII bus + * @is_c45: If true the PHY uses the 802.3 clause 45 protocol * * Description: Reads the ID registers of the PHY at @addr on the * @bus, then allocates and returns the phy_device to represent it. */ -struct phy_device * get_phy_device(struct mii_bus *bus, int addr) +struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) { struct phy_device *dev = NULL; u32 phy_id; + struct phy_c45_device_ids c45_ids = {0}; int r; - r = get_phy_id(bus, addr, &phy_id); + r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); if (r) return ERR_PTR(r); @@ -256,7 +340,7 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) if ((phy_id & 0x1fffffff) == 0x1fffffff) return NULL; - dev = phy_device_create(bus, addr, phy_id); + dev = phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); return dev; } @@ -449,6 +533,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, /* Assume that if there is no driver, that it doesn't * exist, and we should use the genphy driver. */ if (NULL == d->driver) { + if (phydev->is_c45) { + pr_err("No driver for phy %x\n", phydev->phy_id); + return -ENODEV; + } + d->driver = &genphy_driver.driver; err = d->driver->probe(d); diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 2574abde8d99..6c24cad322df 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -79,7 +79,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) mdio->irq[addr] = PHY_POLL; } - phy = get_phy_device(mdio, addr); + phy = get_phy_device(mdio, addr, false); if (!phy || IS_ERR(phy)) { dev_err(&mdio->dev, "error probing PHY at address %i\n", addr); diff --git a/include/linux/phy.h b/include/linux/phy.h index c291cae8ce32..597d05dd0fb4 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -243,6 +243,15 @@ enum phy_state { PHY_RESUMING }; +/** + * struct phy_c45_device_ids - 802.3-c45 Device Identifiers + * @devices_in_package: Bit vector of devices present. + * @device_ids: The device identifer for each present device. + */ +struct phy_c45_device_ids { + u32 devices_in_package; + u32 device_ids[8]; +}; /* phy_device: An instance of a PHY * @@ -250,6 +259,8 @@ enum phy_state { * bus: Pointer to the bus this PHY is on * dev: driver model device structure for this PHY * phy_id: UID for this device found during discovery + * c45_ids: 802.3-c45 Device Identifers if is_c45. + * is_c45: Set to true if this phy uses clause 45 addressing. * state: state of the PHY for management purposes * dev_flags: Device-specific flags used by the PHY driver. * addr: Bus address of PHY @@ -285,6 +296,9 @@ struct phy_device { u32 phy_id; + struct phy_c45_device_ids c45_ids; + bool is_c45; + enum phy_state state; u32 dev_flags; @@ -480,7 +494,9 @@ static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val) return mdiobus_write(phydev->bus, phydev->addr, regnum, val); } -struct phy_device* get_phy_device(struct mii_bus *bus, int addr); +struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, + bool is_c45, struct phy_c45_device_ids *c45_ids); +struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45); int phy_device_register(struct phy_device *phy); int phy_init_hw(struct phy_device *phydev); struct phy_device * phy_attach(struct net_device *dev, -- GitLab From 6bd47ac2e434611e52027155438d7b4ad3c76bdb Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Jun 2012 07:33:36 +0000 Subject: [PATCH 3121/6849] netdev/phy/of: Handle IEEE802.3 clause 45 Ethernet PHYs in of_mdiobus_register() Define two new "compatible" values for Ethernet PHYs. "ethernet-phy-ieee802.3-c22" and "ethernet-phy-ieee802.3-c45" are used to indicate a PHY uses the corresponding protocol. If a PHY is "compatible" with "ethernet-phy-ieee802.3-c45", we indicate this so that get_phy_device() can properly probe the device. If get_phy_device() fails, it was probably due to failing the probe of the PHY identifier registers. Since we have the device tree telling us the PHY exists, go ahead and add it anyhow with a phy_id of zero. There may be a driver match based on the "compatible" property. Signed-off-by: David Daney Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/phy.txt | 12 +++++++++++- drivers/of/of_mdio.c | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index bb8c742eb8c5..7cd18fbfcf71 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -14,10 +14,20 @@ Required properties: - linux,phandle : phandle for this node; likely referenced by an ethernet controller node. +Optional Properties: + +- compatible: Compatible list, may contain + "ethernet-phy-ieee802.3-c22" or "ethernet-phy-ieee802.3-c45" for + PHYs that implement IEEE802.3 clause 22 or IEEE802.3 clause 45 + specifications. If neither of these are specified, the default is to + assume clause 22. The compatible list may also contain other + elements. + Example: ethernet-phy@0 { - linux,phandle = <2452000> + compatible = "ethernet-phy-ieee802.3-c22"; + linux,phandle = <2452000>; interrupt-parent = <40000>; interrupts = <35 1>; reg = <0>; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 6c24cad322df..8e6c25f35040 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -57,6 +57,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) const __be32 *paddr; u32 addr; int len; + bool is_c45; /* A PHY must have a reg property in the range [0-31] */ paddr = of_get_property(child, "reg", &len); @@ -79,11 +80,18 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) mdio->irq[addr] = PHY_POLL; } - phy = get_phy_device(mdio, addr, false); + is_c45 = of_device_is_compatible(child, + "ethernet-phy-ieee802.3-c45"); + phy = get_phy_device(mdio, addr, is_c45); + if (!phy || IS_ERR(phy)) { - dev_err(&mdio->dev, "error probing PHY at address %i\n", - addr); - continue; + phy = phy_device_create(mdio, addr, 0, false, NULL); + if (!phy || IS_ERR(phy)) { + dev_err(&mdio->dev, + "error creating PHY at address %i\n", + addr); + continue; + } } /* Associate the OF node with the device structure so it -- GitLab From a30e2c1891296b5ee8de48430a07fdf8b818c661 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Jun 2012 07:33:37 +0000 Subject: [PATCH 3122/6849] netdev/phy/of: Add more methods for binding PHY devices to drivers. Allow PHY drivers to supply their own device matching function (match_phy_device()), or to be matched OF compatible properties. PHYs following IEEE802.3 clause 45 have more than one device identifier constants, which breaks the default device matching code. Other 10G PHYs don't follow the standard manufacturer/device identifier register layout standards, but they do use the standard MDIO bus protocols for register access. Both of these require adjustments to the PHY driver to device matching code. If the there is an of_node associated with such a PHY, we can match it to its driver using the "compatible" properties, just as we do with certain platform devices. If the "compatible" property match fails, first check if there is a driver supplied matching function, and if not fall back to the existing identifier matching rules. Signed-off-by: David Daney Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 7 +++++++ include/linux/phy.h | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 2cee6d218d21..170eb411ab5d 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -308,6 +309,12 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) struct phy_device *phydev = to_phy_device(dev); struct phy_driver *phydrv = to_phy_driver(drv); + if (of_driver_match_device(dev, drv)) + return 1; + + if (phydrv->match_phy_device) + return phydrv->match_phy_device(phydev); + return ((phydrv->phy_id & phydrv->phy_id_mask) == (phydev->phy_id & phydrv->phy_id_mask)); } diff --git a/include/linux/phy.h b/include/linux/phy.h index 597d05dd0fb4..7eac80a2557b 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -426,6 +426,12 @@ struct phy_driver { /* Clears up any memory if needed */ void (*remove)(struct phy_device *phydev); + /* Returns true if this is a suitable driver for the given + * phydev. If NULL, matching is based on phy_id and + * phy_id_mask. + */ + int (*match_phy_device)(struct phy_device *phydev); + /* Handles ethtool queries for hardware time stamping. */ int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti); -- GitLab From e9976d7c96423ac1991396aa82335206ded55bcf Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Jun 2012 07:33:38 +0000 Subject: [PATCH 3123/6849] netdev/phy: Add driver for Broadcom BCM87XX 10G Ethernet PHYs Add a driver for BCM8706 and BCM8727 devices. These are a 10Gig PHYs which use MII_ADDR_C45 addressing. They are always 10G full duplex, so there is no autonegotiation. All we do is report link state and send interrupts when it changes. If the PHY has a device tree of_node associated with it, the "broadcom,c45-reg-init" property is used to supply register initialization values when config_init() is called. Signed-off-by: David Daney Signed-off-by: David S. Miller --- .../bindings/net/broadcom-bcm87xx.txt | 29 +++ drivers/net/phy/Kconfig | 5 + drivers/net/phy/Makefile | 1 + drivers/net/phy/bcm87xx.c | 238 ++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/broadcom-bcm87xx.txt create mode 100644 drivers/net/phy/bcm87xx.c diff --git a/Documentation/devicetree/bindings/net/broadcom-bcm87xx.txt b/Documentation/devicetree/bindings/net/broadcom-bcm87xx.txt new file mode 100644 index 000000000000..7c86d5e28a0e --- /dev/null +++ b/Documentation/devicetree/bindings/net/broadcom-bcm87xx.txt @@ -0,0 +1,29 @@ +The Broadcom BCM87XX devices are a family of 10G Ethernet PHYs. They +have these bindings in addition to the standard PHY bindings. + +Compatible: Should contain "broadcom,bcm8706" or "broadcom,bcm8727" and + "ethernet-phy-ieee802.3-c45" + +Optional Properties: + +- broadcom,c45-reg-init : one of more sets of 4 cells. The first cell + is the MDIO Manageable Device (MMD) address, the second a register + address within the MMD, the third cell contains a mask to be ANDed + with the existing register value, and the fourth cell is ORed with + he result to yield the new register value. If the third cell has a + value of zero, no read of the existing value is performed. + +Example: + + ethernet-phy@5 { + reg = <5>; + compatible = "broadcom,bcm8706", "ethernet-phy-ieee802.3-c45"; + interrupt-parent = <&gpio>; + interrupts = <12 8>; /* Pin 12, active low */ + /* + * Set PMD Digital Control Register for + * GPIO[1] Tx/Rx + * GPIO[0] R64 Sync Acquired + */ + broadcom,c45-reg-init = <1 0xc808 0xff8f 0x70>; + }; diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 944cdfb80fe4..3090dc65a6f1 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -67,6 +67,11 @@ config BCM63XX_PHY ---help--- Currently supports the 6348 and 6358 PHYs. +config BCM87XX_PHY + tristate "Driver for Broadcom BCM8706 and BCM8727 PHYs" + help + Currently supports the BCM8706 and BCM8727 10G Ethernet PHYs. + config ICPLUS_PHY tristate "Drivers for ICPlus PHYs" ---help--- diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index f51af688ef8b..6d2dc6c94f2e 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_SMSC_PHY) += smsc.o obj-$(CONFIG_VITESSE_PHY) += vitesse.o obj-$(CONFIG_BROADCOM_PHY) += broadcom.o obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o +obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o obj-$(CONFIG_ICPLUS_PHY) += icplus.o obj-$(CONFIG_REALTEK_PHY) += realtek.o obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c new file mode 100644 index 000000000000..f5f0562934db --- /dev/null +++ b/drivers/net/phy/bcm87xx.c @@ -0,0 +1,238 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2011 - 2012 Cavium, Inc. + */ + +#include +#include +#include + +#define PHY_ID_BCM8706 0x0143bdc1 +#define PHY_ID_BCM8727 0x0143bff0 + +#define BCM87XX_PMD_RX_SIGNAL_DETECT (MII_ADDR_C45 | 0x1000a) +#define BCM87XX_10GBASER_PCS_STATUS (MII_ADDR_C45 | 0x30020) +#define BCM87XX_XGXS_LANE_STATUS (MII_ADDR_C45 | 0x40018) + +#define BCM87XX_LASI_CONTROL (MII_ADDR_C45 | 0x39002) +#define BCM87XX_LASI_STATUS (MII_ADDR_C45 | 0x39005) + +#if IS_ENABLED(CONFIG_OF_MDIO) +/* Set and/or override some configuration registers based on the + * marvell,reg-init property stored in the of_node for the phydev. + * + * broadcom,c45-reg-init = ,...; + * + * There may be one or more sets of : + * + * devid: which sub-device to use. + * reg: the register. + * mask: if non-zero, ANDed with existing register value. + * value: ORed with the masked value and written to the regiser. + * + */ +static int bcm87xx_of_reg_init(struct phy_device *phydev) +{ + const __be32 *paddr; + const __be32 *paddr_end; + int len, ret; + + if (!phydev->dev.of_node) + return 0; + + paddr = of_get_property(phydev->dev.of_node, + "broadcom,c45-reg-init", &len); + if (!paddr) + return 0; + + paddr_end = paddr + (len /= sizeof(*paddr)); + + ret = 0; + + while (paddr + 3 < paddr_end) { + u16 devid = be32_to_cpup(paddr++); + u16 reg = be32_to_cpup(paddr++); + u16 mask = be32_to_cpup(paddr++); + u16 val_bits = be32_to_cpup(paddr++); + int val; + u32 regnum = MII_ADDR_C45 | (devid << 16) | reg; + val = 0; + if (mask) { + val = phy_read(phydev, regnum); + if (val < 0) { + ret = val; + goto err; + } + val &= mask; + } + val |= val_bits; + + ret = phy_write(phydev, regnum, val); + if (ret < 0) + goto err; + } +err: + return ret; +} +#else +static int bcm87xx_of_reg_init(struct phy_device *phydev) +{ + return 0; +} +#endif /* CONFIG_OF_MDIO */ + +static int bcm87xx_config_init(struct phy_device *phydev) +{ + phydev->supported = SUPPORTED_10000baseR_FEC; + phydev->advertising = ADVERTISED_10000baseR_FEC; + phydev->state = PHY_NOLINK; + + bcm87xx_of_reg_init(phydev); + + return 0; +} + +static int bcm87xx_config_aneg(struct phy_device *phydev) +{ + return -EINVAL; +} + +static int bcm87xx_read_status(struct phy_device *phydev) +{ + int rx_signal_detect; + int pcs_status; + int xgxs_lane_status; + + rx_signal_detect = phy_read(phydev, BCM87XX_PMD_RX_SIGNAL_DETECT); + if (rx_signal_detect < 0) + return rx_signal_detect; + + if ((rx_signal_detect & 1) == 0) + goto no_link; + + pcs_status = phy_read(phydev, BCM87XX_10GBASER_PCS_STATUS); + if (pcs_status < 0) + return pcs_status; + + if ((pcs_status & 1) == 0) + goto no_link; + + xgxs_lane_status = phy_read(phydev, BCM87XX_XGXS_LANE_STATUS); + if (xgxs_lane_status < 0) + return xgxs_lane_status; + + if ((xgxs_lane_status & 0x1000) == 0) + goto no_link; + + phydev->speed = 10000; + phydev->link = 1; + phydev->duplex = 1; + return 0; + +no_link: + phydev->link = 0; + return 0; +} + +static int bcm87xx_config_intr(struct phy_device *phydev) +{ + int reg, err; + + reg = phy_read(phydev, BCM87XX_LASI_CONTROL); + + if (reg < 0) + return reg; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + reg |= 1; + else + reg &= ~1; + + err = phy_write(phydev, BCM87XX_LASI_CONTROL, reg); + return err; +} + +static int bcm87xx_did_interrupt(struct phy_device *phydev) +{ + int reg; + + reg = phy_read(phydev, BCM87XX_LASI_STATUS); + + if (reg < 0) { + dev_err(&phydev->dev, + "Error: Read of BCM87XX_LASI_STATUS failed: %d\n", reg); + return 0; + } + return (reg & 1) != 0; +} + +static int bcm87xx_ack_interrupt(struct phy_device *phydev) +{ + /* Reading the LASI status clears it. */ + bcm87xx_did_interrupt(phydev); + return 0; +} + +static int bcm8706_match_phy_device(struct phy_device *phydev) +{ + return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; +} + +static int bcm8727_match_phy_device(struct phy_device *phydev) +{ + return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; +} + +static struct phy_driver bcm8706_driver = { + .phy_id = PHY_ID_BCM8706, + .phy_id_mask = 0xffffffff, + .name = "Broadcom BCM8706", + .flags = PHY_HAS_INTERRUPT, + .config_init = bcm87xx_config_init, + .config_aneg = bcm87xx_config_aneg, + .read_status = bcm87xx_read_status, + .ack_interrupt = bcm87xx_ack_interrupt, + .config_intr = bcm87xx_config_intr, + .did_interrupt = bcm87xx_did_interrupt, + .match_phy_device = bcm8706_match_phy_device, + .driver = { .owner = THIS_MODULE }, +}; + +static struct phy_driver bcm8727_driver = { + .phy_id = PHY_ID_BCM8727, + .phy_id_mask = 0xffffffff, + .name = "Broadcom BCM8727", + .flags = PHY_HAS_INTERRUPT, + .config_init = bcm87xx_config_init, + .config_aneg = bcm87xx_config_aneg, + .read_status = bcm87xx_read_status, + .ack_interrupt = bcm87xx_ack_interrupt, + .config_intr = bcm87xx_config_intr, + .did_interrupt = bcm87xx_did_interrupt, + .match_phy_device = bcm8727_match_phy_device, + .driver = { .owner = THIS_MODULE }, +}; + +static int __init bcm87xx_init(void) +{ + int ret; + + ret = phy_driver_register(&bcm8706_driver); + if (ret) + goto err; + + ret = phy_driver_register(&bcm8727_driver); +err: + return ret; +} +module_init(bcm87xx_init); + +static void __exit bcm87xx_exit(void) +{ + phy_driver_unregister(&bcm8706_driver); + phy_driver_unregister(&bcm8727_driver); +} +module_exit(bcm87xx_exit); -- GitLab From d4fc6918f4b3cc844185f59fc518351525950449 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 27 Jun 2012 05:27:46 +0000 Subject: [PATCH 3124/6849] virtio_net: allow to change mac when iface is running Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f18149ae2588..36a16d581f71 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -679,11 +679,12 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) { struct virtnet_info *vi = netdev_priv(dev); struct virtio_device *vdev = vi->vdev; - int ret; + struct sockaddr *addr = p; - ret = eth_mac_addr(dev, p); - if (ret) - return ret; + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + dev->addr_assign_type &= ~NET_ADDR_RANDOM; if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) vdev->config->set(vdev, offsetof(struct virtio_net_config, mac), -- GitLab From 160c85f0e050d92c0e42321aab2ffc343594e1c0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Jun 2012 21:28:14 -0700 Subject: [PATCH 3125/6849] phy: Fix warning in get_phy_device(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/phy/phy_device.c: In function ‘get_phy_device’: drivers/net/phy/phy_device.c:340:14: warning: ‘phy_id’ may be used uninitialized in this function [-Wmaybe-uninitialized] GCC can't see that when we return zero we always initialize phy_id and that's the only path where we use it. Initialize phy_id to zero to shut it up. Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index ef4cdeebedd6..47e02e7dc737 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -327,9 +327,9 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, */ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) { - struct phy_device *dev = NULL; - u32 phy_id; struct phy_c45_device_ids c45_ids = {0}; + struct phy_device *dev = NULL; + u32 phy_id = 0; int r; r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); -- GitLab From 1d1e34ddd48d27def2f324c1e3be16d460b16436 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Jun 2012 21:57:03 -0700 Subject: [PATCH 3126/6849] xfrm_user: Propagate netlink error codes properly. Instead of using a fixed value of "-1" or "-EMSGSIZE", propagate what the nla_*() interfaces actually return. Signed-off-by: David S. Miller --- include/net/xfrm.h | 10 +- net/xfrm/xfrm_user.c | 394 ++++++++++++++++++++++--------------------- 2 files changed, 208 insertions(+), 196 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index e0a55df5bde8..17acbc92476d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1682,13 +1682,11 @@ static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m) static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m) { - if ((m->m | m->v) && - nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m)) - goto nla_put_failure; - return 0; + int ret = 0; -nla_put_failure: - return -1; + if (m->m | m->v) + ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m); + return ret; } #endif /* _NET_XFRM_H */ diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 44293b3fd6a1..540762726aaf 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -754,58 +754,67 @@ static int copy_to_user_state_extra(struct xfrm_state *x, struct xfrm_usersa_info *p, struct sk_buff *skb) { - copy_to_user_state(x, p); - - if (x->coaddr && - nla_put(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr)) - goto nla_put_failure; - - if (x->lastused && - nla_put_u64(skb, XFRMA_LASTUSED, x->lastused)) - goto nla_put_failure; - - if (x->aead && - nla_put(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead)) - goto nla_put_failure; - - if (x->aalg && - (copy_to_user_auth(x->aalg, skb) || - nla_put(skb, XFRMA_ALG_AUTH_TRUNC, - xfrm_alg_auth_len(x->aalg), x->aalg))) - goto nla_put_failure; - - if (x->ealg && - nla_put(skb, XFRMA_ALG_CRYPT, xfrm_alg_len(x->ealg), x->ealg)) - goto nla_put_failure; - - if (x->calg && - nla_put(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg)) - goto nla_put_failure; - - if (x->encap && - nla_put(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap)) - goto nla_put_failure; + int ret = 0; - if (x->tfcpad && - nla_put_u32(skb, XFRMA_TFCPAD, x->tfcpad)) - goto nla_put_failure; - - if (xfrm_mark_put(skb, &x->mark)) - goto nla_put_failure; - - if (x->replay_esn && - nla_put(skb, XFRMA_REPLAY_ESN_VAL, - xfrm_replay_state_esn_len(x->replay_esn), - x->replay_esn)) - goto nla_put_failure; - - if (x->security && copy_sec_ctx(x->security, skb)) - goto nla_put_failure; - - return 0; + copy_to_user_state(x, p); -nla_put_failure: - return -EMSGSIZE; + if (x->coaddr) { + ret = nla_put(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr); + if (ret) + goto out; + } + if (x->lastused) { + ret = nla_put_u64(skb, XFRMA_LASTUSED, x->lastused); + if (ret) + goto out; + } + if (x->aead) { + ret = nla_put(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead); + if (ret) + goto out; + } + if (x->aalg) { + ret = copy_to_user_auth(x->aalg, skb); + if (!ret) + ret = nla_put(skb, XFRMA_ALG_AUTH_TRUNC, + xfrm_alg_auth_len(x->aalg), x->aalg); + if (ret) + goto out; + } + if (x->ealg) { + ret = nla_put(skb, XFRMA_ALG_CRYPT, xfrm_alg_len(x->ealg), x->ealg); + if (ret) + goto out; + } + if (x->calg) { + ret = nla_put(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); + if (ret) + goto out; + } + if (x->encap) { + ret = nla_put(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); + if (ret) + goto out; + } + if (x->tfcpad) { + ret = nla_put_u32(skb, XFRMA_TFCPAD, x->tfcpad); + if (ret) + goto out; + } + ret = xfrm_mark_put(skb, &x->mark); + if (ret) + goto out; + if (x->replay_esn) { + ret = nla_put(skb, XFRMA_REPLAY_ESN_VAL, + xfrm_replay_state_esn_len(x->replay_esn), + x->replay_esn); + if (ret) + goto out; + } + if (x->security) + ret = copy_sec_ctx(x->security, skb); +out: + return ret; } static int dump_one_state(struct xfrm_state *x, int count, void *ptr) @@ -825,15 +834,12 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr) p = nlmsg_data(nlh); err = copy_to_user_state_extra(x, p, skb); - if (err) - goto nla_put_failure; - + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } nlmsg_end(skb, nlh); return 0; - -nla_put_failure: - nlmsg_cancel(skb, nlh); - return err; } static int xfrm_dump_sa_done(struct netlink_callback *cb) @@ -904,6 +910,7 @@ static int build_spdinfo(struct sk_buff *skb, struct net *net, struct xfrmu_spdinfo spc; struct xfrmu_spdhinfo sph; struct nlmsghdr *nlh; + int err; u32 *f; nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0); @@ -922,15 +929,15 @@ static int build_spdinfo(struct sk_buff *skb, struct net *net, sph.spdhcnt = si.spdhcnt; sph.spdhmcnt = si.spdhmcnt; - if (nla_put(skb, XFRMA_SPD_INFO, sizeof(spc), &spc) || - nla_put(skb, XFRMA_SPD_HINFO, sizeof(sph), &sph)) - goto nla_put_failure; + err = nla_put(skb, XFRMA_SPD_INFO, sizeof(spc), &spc); + if (!err) + err = nla_put(skb, XFRMA_SPD_HINFO, sizeof(sph), &sph); + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } return nlmsg_end(skb, nlh); - -nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; } static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, @@ -965,6 +972,7 @@ static int build_sadinfo(struct sk_buff *skb, struct net *net, struct xfrmk_sadinfo si; struct xfrmu_sadhinfo sh; struct nlmsghdr *nlh; + int err; u32 *f; nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSADINFO, sizeof(u32), 0); @@ -978,15 +986,15 @@ static int build_sadinfo(struct sk_buff *skb, struct net *net, sh.sadhmcnt = si.sadhmcnt; sh.sadhcnt = si.sadhcnt; - if (nla_put_u32(skb, XFRMA_SAD_CNT, si.sadcnt) || - nla_put(skb, XFRMA_SAD_HINFO, sizeof(sh), &sh)) - goto nla_put_failure; + err = nla_put_u32(skb, XFRMA_SAD_CNT, si.sadcnt); + if (!err) + err = nla_put(skb, XFRMA_SAD_HINFO, sizeof(sh), &sh); + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } return nlmsg_end(skb, nlh); - -nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; } static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, @@ -1439,9 +1447,8 @@ static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buf static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb) { - if (xp->security) { + if (xp->security) return copy_sec_ctx(xp->security, skb); - } return 0; } static inline size_t userpolicy_type_attrsize(void) @@ -1477,6 +1484,7 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr struct sk_buff *in_skb = sp->in_skb; struct sk_buff *skb = sp->out_skb; struct nlmsghdr *nlh; + int err; nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags); @@ -1485,22 +1493,19 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr p = nlmsg_data(nlh); copy_to_user_policy(xp, p, dir); - if (copy_to_user_tmpl(xp, skb) < 0) - goto nlmsg_failure; - if (copy_to_user_sec_ctx(xp, skb)) - goto nlmsg_failure; - if (copy_to_user_policy_type(xp->type, skb) < 0) - goto nlmsg_failure; - if (xfrm_mark_put(skb, &xp->mark)) - goto nla_put_failure; - + err = copy_to_user_tmpl(xp, skb); + if (!err) + err = copy_to_user_sec_ctx(xp, skb); + if (!err) + err = copy_to_user_policy_type(xp->type, skb); + if (!err) + err = xfrm_mark_put(skb, &xp->mark); + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } nlmsg_end(skb, nlh); return 0; - -nla_put_failure: -nlmsg_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; } static int xfrm_dump_policy_done(struct netlink_callback *cb) @@ -1688,6 +1693,7 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct { struct xfrm_aevent_id *id; struct nlmsghdr *nlh; + int err; nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0); if (nlh == NULL) @@ -1703,35 +1709,39 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct id->flags = c->data.aevent; if (x->replay_esn) { - if (nla_put(skb, XFRMA_REPLAY_ESN_VAL, - xfrm_replay_state_esn_len(x->replay_esn), - x->replay_esn)) - goto nla_put_failure; + err = nla_put(skb, XFRMA_REPLAY_ESN_VAL, + xfrm_replay_state_esn_len(x->replay_esn), + x->replay_esn); } else { - if (nla_put(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), - &x->replay)) - goto nla_put_failure; + err = nla_put(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), + &x->replay); } - if (nla_put(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft)) - goto nla_put_failure; - - if ((id->flags & XFRM_AE_RTHR) && - nla_put_u32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff)) - goto nla_put_failure; - - if ((id->flags & XFRM_AE_ETHR) && - nla_put_u32(skb, XFRMA_ETIMER_THRESH, - x->replay_maxage * 10 / HZ)) - goto nla_put_failure; + if (err) + goto out_cancel; + err = nla_put(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft); + if (err) + goto out_cancel; - if (xfrm_mark_put(skb, &x->mark)) - goto nla_put_failure; + if (id->flags & XFRM_AE_RTHR) { + err = nla_put_u32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff); + if (err) + goto out_cancel; + } + if (id->flags & XFRM_AE_ETHR) { + err = nla_put_u32(skb, XFRMA_ETIMER_THRESH, + x->replay_maxage * 10 / HZ); + if (err) + goto out_cancel; + } + err = xfrm_mark_put(skb, &x->mark); + if (err) + goto out_cancel; return nlmsg_end(skb, nlh); -nla_put_failure: +out_cancel: nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return err; } static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, @@ -2155,7 +2165,7 @@ static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m, const struct xfrm_migrate *mp; struct xfrm_userpolicy_id *pol_id; struct nlmsghdr *nlh; - int i; + int i, err; nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id), 0); if (nlh == NULL) @@ -2167,21 +2177,25 @@ static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m, memcpy(&pol_id->sel, sel, sizeof(pol_id->sel)); pol_id->dir = dir; - if (k != NULL && (copy_to_user_kmaddress(k, skb) < 0)) - goto nlmsg_failure; - - if (copy_to_user_policy_type(type, skb) < 0) - goto nlmsg_failure; - + if (k != NULL) { + err = copy_to_user_kmaddress(k, skb); + if (err) + goto out_cancel; + } + err = copy_to_user_policy_type(type, skb); + if (err) + goto out_cancel; for (i = 0, mp = m ; i < num_migrate; i++, mp++) { - if (copy_to_user_migrate(mp, skb) < 0) - goto nlmsg_failure; + err = copy_to_user_migrate(mp, skb); + if (err) + goto out_cancel; } return nlmsg_end(skb, nlh); -nlmsg_failure: + +out_cancel: nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return err; } static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, @@ -2354,6 +2368,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct { struct xfrm_user_expire *ue; struct nlmsghdr *nlh; + int err; nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0); if (nlh == NULL) @@ -2363,13 +2378,11 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct copy_to_user_state(x, &ue->state); ue->hard = (c->data.hard != 0) ? 1 : 0; - if (xfrm_mark_put(skb, &x->mark)) - goto nla_put_failure; + err = xfrm_mark_put(skb, &x->mark); + if (err) + return err; return nlmsg_end(skb, nlh); - -nla_put_failure: - return -EMSGSIZE; } static int xfrm_exp_state_notify(struct xfrm_state *x, const struct km_event *c) @@ -2470,7 +2483,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) struct nlmsghdr *nlh; struct sk_buff *skb; int len = xfrm_sa_len(x); - int headlen; + int headlen, err; headlen = sizeof(*p); if (c->event == XFRM_MSG_DELSA) { @@ -2485,8 +2498,9 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) return -ENOMEM; nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); + err = -EMSGSIZE; if (nlh == NULL) - goto nla_put_failure; + goto out_free_skb; p = nlmsg_data(nlh); if (c->event == XFRM_MSG_DELSA) { @@ -2499,24 +2513,23 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) id->proto = x->id.proto; attr = nla_reserve(skb, XFRMA_SA, sizeof(*p)); + err = -EMSGSIZE; if (attr == NULL) - goto nla_put_failure; + goto out_free_skb; p = nla_data(attr); } - - if (copy_to_user_state_extra(x, p, skb)) - goto nla_put_failure; + err = copy_to_user_state_extra(x, p, skb); + if (err) + goto out_free_skb; nlmsg_end(skb, nlh); return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); -nla_put_failure: - /* Somebody screwed up with xfrm_sa_len! */ - WARN_ON(1); +out_free_skb: kfree_skb(skb); - return -1; + return err; } static int xfrm_send_state_notify(struct xfrm_state *x, const struct km_event *c) @@ -2557,9 +2570,10 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, struct xfrm_tmpl *xt, struct xfrm_policy *xp, int dir) { + __u32 seq = xfrm_get_acqseq(); struct xfrm_user_acquire *ua; struct nlmsghdr *nlh; - __u32 seq = xfrm_get_acqseq(); + int err; nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_ACQUIRE, sizeof(*ua), 0); if (nlh == NULL) @@ -2575,21 +2589,19 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, ua->calgos = xt->calgos; ua->seq = x->km.seq = seq; - if (copy_to_user_tmpl(xp, skb) < 0) - goto nlmsg_failure; - if (copy_to_user_state_sec_ctx(x, skb)) - goto nlmsg_failure; - if (copy_to_user_policy_type(xp->type, skb) < 0) - goto nlmsg_failure; - if (xfrm_mark_put(skb, &xp->mark)) - goto nla_put_failure; + err = copy_to_user_tmpl(xp, skb); + if (!err) + err = copy_to_user_state_sec_ctx(x, skb); + if (!err) + err = copy_to_user_policy_type(xp->type, skb); + if (!err) + err = xfrm_mark_put(skb, &xp->mark); + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } return nlmsg_end(skb, nlh); - -nla_put_failure: -nlmsg_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; } static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, @@ -2681,8 +2693,9 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, int dir, const struct km_event *c) { struct xfrm_user_polexpire *upe; - struct nlmsghdr *nlh; int hard = c->data.hard; + struct nlmsghdr *nlh; + int err; nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0); if (nlh == NULL) @@ -2690,22 +2703,20 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, upe = nlmsg_data(nlh); copy_to_user_policy(xp, &upe->pol, dir); - if (copy_to_user_tmpl(xp, skb) < 0) - goto nlmsg_failure; - if (copy_to_user_sec_ctx(xp, skb)) - goto nlmsg_failure; - if (copy_to_user_policy_type(xp->type, skb) < 0) - goto nlmsg_failure; - if (xfrm_mark_put(skb, &xp->mark)) - goto nla_put_failure; + err = copy_to_user_tmpl(xp, skb); + if (!err) + err = copy_to_user_sec_ctx(xp, skb); + if (!err) + err = copy_to_user_policy_type(xp->type, skb); + if (!err) + err = xfrm_mark_put(skb, &xp->mark); + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } upe->hard = !!hard; return nlmsg_end(skb, nlh); - -nla_put_failure: -nlmsg_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; } static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c) @@ -2725,13 +2736,13 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, const struct static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_event *c) { + int len = nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); struct net *net = xp_net(xp); struct xfrm_userpolicy_info *p; struct xfrm_userpolicy_id *id; struct nlmsghdr *nlh; struct sk_buff *skb; - int len = nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); - int headlen; + int headlen, err; headlen = sizeof(*p); if (c->event == XFRM_MSG_DELPOLICY) { @@ -2747,8 +2758,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_e return -ENOMEM; nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); + err = -EMSGSIZE; if (nlh == NULL) - goto nlmsg_failure; + goto out_free_skb; p = nlmsg_data(nlh); if (c->event == XFRM_MSG_DELPOLICY) { @@ -2763,29 +2775,29 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_e memcpy(&id->sel, &xp->selector, sizeof(id->sel)); attr = nla_reserve(skb, XFRMA_POLICY, sizeof(*p)); + err = -EMSGSIZE; if (attr == NULL) - goto nlmsg_failure; + goto out_free_skb; p = nla_data(attr); } copy_to_user_policy(xp, p, dir); - if (copy_to_user_tmpl(xp, skb) < 0) - goto nlmsg_failure; - if (copy_to_user_policy_type(xp->type, skb) < 0) - goto nlmsg_failure; - - if (xfrm_mark_put(skb, &xp->mark)) - goto nla_put_failure; + err = copy_to_user_tmpl(xp, skb); + if (!err) + err = copy_to_user_policy_type(xp->type, skb); + if (!err) + err = xfrm_mark_put(skb, &xp->mark); + if (err) + goto out_free_skb; nlmsg_end(skb, nlh); return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); -nla_put_failure: -nlmsg_failure: +out_free_skb: kfree_skb(skb); - return -1; + return err; } static int xfrm_notify_policy_flush(const struct km_event *c) @@ -2793,24 +2805,27 @@ static int xfrm_notify_policy_flush(const struct km_event *c) struct net *net = c->net; struct nlmsghdr *nlh; struct sk_buff *skb; + int err; skb = nlmsg_new(userpolicy_type_attrsize(), GFP_ATOMIC); if (skb == NULL) return -ENOMEM; nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0); + err = -EMSGSIZE; if (nlh == NULL) - goto nlmsg_failure; - if (copy_to_user_policy_type(c->data.type, skb) < 0) - goto nlmsg_failure; + goto out_free_skb; + err = copy_to_user_policy_type(c->data.type, skb); + if (err) + goto out_free_skb; nlmsg_end(skb, nlh); return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); -nlmsg_failure: +out_free_skb: kfree_skb(skb); - return -1; + return err; } static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c) @@ -2853,15 +2868,14 @@ static int build_report(struct sk_buff *skb, u8 proto, ur->proto = proto; memcpy(&ur->sel, sel, sizeof(ur->sel)); - if (addr && - nla_put(skb, XFRMA_COADDR, sizeof(*addr), addr)) - goto nla_put_failure; - + if (addr) { + int err = nla_put(skb, XFRMA_COADDR, sizeof(*addr), addr); + if (err) { + nlmsg_cancel(skb, nlh); + return err; + } + } return nlmsg_end(skb, nlh); - -nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; } static int xfrm_send_report(struct net *net, u8 proto, -- GitLab From 160eb5a6b14ca2eab5c598bdbbb24c24624bad34 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Jun 2012 22:01:22 -0700 Subject: [PATCH 3127/6849] ipv4: Kill early demux method return value. It's completely unnecessary. Signed-off-by: David S. Miller --- include/net/protocol.h | 2 +- include/net/tcp.h | 2 +- net/ipv4/ip_input.c | 42 +++++++++++++++++++----------------------- net/ipv4/tcp_ipv4.c | 19 ++++++------------- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/include/net/protocol.h b/include/net/protocol.h index 967b926cbfb1..057f2d315567 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -37,7 +37,7 @@ /* This is used to register protocols. */ struct net_protocol { - int (*early_demux)(struct sk_buff *skb); + void (*early_demux)(struct sk_buff *skb); int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); int (*gso_send_check)(struct sk_buff *skb); diff --git a/include/net/tcp.h b/include/net/tcp.h index 6660ffc4963d..53fb7d814170 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -325,7 +325,7 @@ extern void tcp_v4_err(struct sk_buff *skb, u32); extern void tcp_shutdown (struct sock *sk, int how); -extern int tcp_v4_early_demux(struct sk_buff *skb); +extern void tcp_v4_early_demux(struct sk_buff *skb); extern int tcp_v4_rcv(struct sk_buff *skb); extern struct inet_peer *tcp_v4_get_peer(struct sock *sk); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2a39204de5bc..b27d4440f523 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -320,33 +320,29 @@ static int ip_rcv_finish(struct sk_buff *skb) const struct iphdr *iph = ip_hdr(skb); struct rtable *rt; + if (sysctl_ip_early_demux && !skb_dst(skb)) { + const struct net_protocol *ipprot; + int protocol = iph->protocol; + + rcu_read_lock(); + ipprot = rcu_dereference(inet_protos[protocol]); + if (ipprot && ipprot->early_demux) + ipprot->early_demux(skb); + rcu_read_unlock(); + } + /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ - if (skb_dst(skb) == NULL) { - int err = -ENOENT; - - if (sysctl_ip_early_demux) { - const struct net_protocol *ipprot; - int protocol = iph->protocol; - - rcu_read_lock(); - ipprot = rcu_dereference(inet_protos[protocol]); - if (ipprot && ipprot->early_demux) - err = ipprot->early_demux(skb); - rcu_read_unlock(); - } - - if (err) { - err = ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb->dev); - if (unlikely(err)) { - if (err == -EXDEV) - NET_INC_STATS_BH(dev_net(skb->dev), - LINUX_MIB_IPRPFILTER); - goto drop; - } + if (!skb_dst(skb)) { + int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, + iph->tos, skb->dev); + if (unlikely(err)) { + if (err == -EXDEV) + NET_INC_STATS_BH(dev_net(skb->dev), + LINUX_MIB_IPRPFILTER); + goto drop; } } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1781dc650b9d..b4ae1c199f3e 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1673,30 +1673,28 @@ csum_err: } EXPORT_SYMBOL(tcp_v4_do_rcv); -int tcp_v4_early_demux(struct sk_buff *skb) +void tcp_v4_early_demux(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); const struct iphdr *iph; const struct tcphdr *th; struct net_device *dev; struct sock *sk; - int err; - err = -ENOENT; if (skb->pkt_type != PACKET_HOST) - goto out_err; + return; if (!pskb_may_pull(skb, ip_hdrlen(skb) + sizeof(struct tcphdr))) - goto out_err; + return; iph = ip_hdr(skb); th = (struct tcphdr *) ((char *)iph + ip_hdrlen(skb)); if (th->doff < sizeof(struct tcphdr) / 4) - goto out_err; + return; if (!pskb_may_pull(skb, ip_hdrlen(skb) + th->doff * 4)) - goto out_err; + return; dev = skb->dev; sk = __inet_lookup_established(net, &tcp_hashinfo, @@ -1713,16 +1711,11 @@ int tcp_v4_early_demux(struct sk_buff *skb) if (dst) { struct rtable *rt = (struct rtable *) dst; - if (rt->rt_iif == dev->ifindex) { + if (rt->rt_iif == dev->ifindex) skb_dst_set_noref(skb, dst); - err = 0; - } } } } - -out_err: - return err; } /* -- GitLab From 16e5e2c471ab889f838bfe1c44032d0481c115e1 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Thu, 19 Apr 2012 13:16:46 -0700 Subject: [PATCH 3128/6849] ARM: OMAP AM35x: clockdomain data: Fix clockdomain dependencies The am35x family of SoCs do not have an IVA so a parallel set of clockdomain dependencies are required that are simililar to OMAP3 but without any IVA dependencies. Signed-off-by: Mark A. Greer Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clockdomains3xxx_data.c | 157 ++++++++++++++++++-- 1 file changed, 144 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c index 6038adb97710..8e35080026d3 100644 --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = { { NULL }, }; +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */ static struct clkdm_dep per_wkdeps[] = { { .clkdm_name = "core_l3_clkdm" }, @@ -69,6 +75,14 @@ static struct clkdm_dep per_wkdeps[] = { { NULL }, }; +static struct clkdm_dep per_am35x_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */ static struct clkdm_dep usbhost_wkdeps[] = { { .clkdm_name = "core_l3_clkdm" }, @@ -79,6 +93,14 @@ static struct clkdm_dep usbhost_wkdeps[] = { { NULL }, }; +static struct clkdm_dep usbhost_am35x_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */ static struct clkdm_dep mpu_3xxx_wkdeps[] = { { .clkdm_name = "core_l3_clkdm" }, @@ -89,6 +111,14 @@ static struct clkdm_dep mpu_3xxx_wkdeps[] = { { NULL }, }; +static struct clkdm_dep mpu_am35x_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "per_clkdm" }, + { NULL }, +}; + /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */ static struct clkdm_dep iva2_wkdeps[] = { { .clkdm_name = "core_l3_clkdm" }, @@ -116,6 +146,12 @@ static struct clkdm_dep dss_wkdeps[] = { { NULL }, }; +static struct clkdm_dep dss_am35x_wkdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + /* 3430: PM_WKDEP_NEON: MPU */ static struct clkdm_dep neon_wkdeps[] = { { .clkdm_name = "mpu_clkdm" }, @@ -131,6 +167,11 @@ static struct clkdm_dep dss_sleepdeps[] = { { NULL }, }; +static struct clkdm_dep dss_am35x_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + /* 3430: CM_SLEEPDEP_PER: MPU, IVA */ static struct clkdm_dep per_sleepdeps[] = { { .clkdm_name = "mpu_clkdm" }, @@ -138,6 +179,11 @@ static struct clkdm_dep per_sleepdeps[] = { { NULL }, }; +static struct clkdm_dep per_am35x_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */ static struct clkdm_dep usbhost_sleepdeps[] = { { .clkdm_name = "mpu_clkdm" }, @@ -145,6 +191,11 @@ static struct clkdm_dep usbhost_sleepdeps[] = { { NULL }, }; +static struct clkdm_dep usbhost_am35x_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + /* 3430: CM_SLEEPDEP_CAM: MPU */ static struct clkdm_dep cam_sleepdeps[] = { { .clkdm_name = "mpu_clkdm" }, @@ -175,6 +226,15 @@ static struct clockdomain mpu_3xxx_clkdm = { .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, }; +static struct clockdomain mpu_am35x_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, + .dep_bit = OMAP3430_EN_MPU_SHIFT, + .wkdep_srcs = mpu_am35x_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, +}; + static struct clockdomain neon_clkdm = { .name = "neon_clkdm", .pwrdm = { .name = "neon_pwrdm" }, @@ -210,6 +270,15 @@ static struct clockdomain sgx_clkdm = { .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, }; +static struct clockdomain sgx_am35x_clkdm = { + .name = "sgx_clkdm", + .pwrdm = { .name = "sgx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_sgx_am35x_wkdeps, + .sleepdep_srcs = gfx_sgx_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, +}; + /* * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but * then that information was removed from the 34xx ES2+ TRM. It is @@ -261,6 +330,16 @@ static struct clockdomain dss_3xxx_clkdm = { .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, }; +static struct clockdomain dss_am35x_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT, + .wkdep_srcs = dss_am35x_wkdeps, + .sleepdep_srcs = dss_am35x_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, +}; + static struct clockdomain cam_clkdm = { .name = "cam_clkdm", .pwrdm = { .name = "cam_pwrdm" }, @@ -279,6 +358,15 @@ static struct clockdomain usbhost_clkdm = { .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, }; +static struct clockdomain usbhost_am35x_clkdm = { + .name = "usbhost_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = usbhost_am35x_wkdeps, + .sleepdep_srcs = usbhost_am35x_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, +}; + static struct clockdomain per_clkdm = { .name = "per_clkdm", .pwrdm = { .name = "per_pwrdm" }, @@ -289,6 +377,16 @@ static struct clockdomain per_clkdm = { .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, }; +static struct clockdomain per_am35x_clkdm = { + .name = "per_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_EN_PER_SHIFT, + .wkdep_srcs = per_am35x_wkdeps, + .sleepdep_srcs = per_am35x_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, +}; + /* * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is * switched of even if sdti is in use @@ -341,31 +439,44 @@ static struct clkdm_autodep clkdm_autodeps[] = { } }; +static struct clkdm_autodep clkdm_am35x_autodeps[] = { + { + .clkdm = { .name = "mpu_clkdm" }, + }, + { + .clkdm = { .name = NULL }, + } +}; + /* * */ -static struct clockdomain *clockdomains_omap3430_common[] __initdata = { +static struct clockdomain *clockdomains_common[] __initdata = { &wkup_common_clkdm, &cm_common_clkdm, &prm_common_clkdm, - &mpu_3xxx_clkdm, &neon_clkdm, - &iva2_clkdm, - &d2d_clkdm, &core_l3_3xxx_clkdm, &core_l4_3xxx_clkdm, - &dss_3xxx_clkdm, - &cam_clkdm, - &per_clkdm, &emu_clkdm, &dpll1_clkdm, - &dpll2_clkdm, &dpll3_clkdm, &dpll4_clkdm, NULL }; +static struct clockdomain *clockdomains_omap3430[] __initdata = { + &mpu_3xxx_clkdm, + &iva2_clkdm, + &d2d_clkdm, + &dss_3xxx_clkdm, + &cam_clkdm, + &per_clkdm, + &dpll2_clkdm, + NULL +}; + static struct clockdomain *clockdomains_omap3430es1[] __initdata = { &gfx_3430es1_clkdm, NULL, @@ -378,21 +489,41 @@ static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = { NULL, }; +static struct clockdomain *clockdomains_am35x[] __initdata = { + &mpu_am35x_clkdm, + &sgx_am35x_clkdm, + &dss_am35x_clkdm, + &per_am35x_clkdm, + &usbhost_am35x_clkdm, + &dpll5_clkdm, + NULL +}; + void __init omap3xxx_clockdomains_init(void) { struct clockdomain **sc; + unsigned int rev; if (!cpu_is_omap34xx()) return; clkdm_register_platform_funcs(&omap3_clkdm_operations); - clkdm_register_clkdms(clockdomains_omap3430_common); + clkdm_register_clkdms(clockdomains_common); - sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 : - clockdomains_omap3430es2plus; + rev = omap_rev(); - clkdm_register_clkdms(sc); + if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { + clkdm_register_clkdms(clockdomains_am35x); + clkdm_register_autodeps(clkdm_am35x_autodeps); + } else { + clkdm_register_clkdms(clockdomains_omap3430); + + sc = (rev == OMAP3430_REV_ES1_0) ? + clockdomains_omap3430es1 : clockdomains_omap3430es2plus; + + clkdm_register_clkdms(sc); + clkdm_register_autodeps(clkdm_autodeps); + } - clkdm_register_autodeps(clkdm_autodeps); clkdm_complete_init(); } -- GitLab From ff7ad7e492b13d4063313f4aace18ced0de8edb4 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 27 Jun 2012 18:43:59 -0600 Subject: [PATCH 3129/6849] arm: omap3: am35x: Set proper powerdomain states The am35x family of SoCs only support the PWRSTS_ON state so create a new set of powerdomain structures that ensure that only the ON state is entered. Signed-off-by: Mark A. Greer --- arch/arm/mach-omap2/powerdomains3xxx_data.c | 139 ++++++++++++++++++-- 1 file changed, 127 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index fb0a0a6869d1..bb883e463078 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -71,6 +71,22 @@ static struct powerdomain mpu_3xxx_pwrdm = { .voltdm = { .name = "mpu_iva" }, }; +static struct powerdomain mpu_am35x_pwrdm = { + .name = "mpu_pwrdm", + .prcm_offs = MPU_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .flags = PWRDM_HAS_MPU_QUIRK, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, + }, + .voltdm = { .name = "mpu_iva" }, +}; + /* * The USBTLL Save-and-Restore mechanism is broken on * 3430s up to ES3.0 and 3630ES1.0. Hence this feature @@ -120,6 +136,23 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = { .voltdm = { .name = "core" }, }; +static struct powerdomain core_am35x_pwrdm = { + .name = "core_pwrdm", + .prcm_offs = CORE_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEM1RETSTATE */ + [1] = PWRSTS_ON, /* MEM2RETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEM1ONSTATE */ + [1] = PWRSTS_ON, /* MEM2ONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + static struct powerdomain dss_pwrdm = { .name = "dss_pwrdm", .prcm_offs = OMAP3430_DSS_MOD, @@ -135,6 +168,21 @@ static struct powerdomain dss_pwrdm = { .voltdm = { .name = "core" }, }; +static struct powerdomain dss_am35x_pwrdm = { + .name = "dss_pwrdm", + .prcm_offs = OMAP3430_DSS_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + /* * Although the 34XX TRM Rev K Table 4-371 notes that retention is a * possible SGX powerstate, the SGX device itself does not support @@ -156,6 +204,21 @@ static struct powerdomain sgx_pwrdm = { .voltdm = { .name = "core" }, }; +static struct powerdomain sgx_am35x_pwrdm = { + .name = "sgx_pwrdm", + .prcm_offs = OMAP3430ES2_SGX_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + static struct powerdomain cam_pwrdm = { .name = "cam_pwrdm", .prcm_offs = OMAP3430_CAM_MOD, @@ -186,6 +249,21 @@ static struct powerdomain per_pwrdm = { .voltdm = { .name = "core" }, }; +static struct powerdomain per_am35x_pwrdm = { + .name = "per_pwrdm", + .prcm_offs = OMAP3430_PER_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + static struct powerdomain emu_pwrdm = { .name = "emu_pwrdm", .prcm_offs = OMAP3430_EMU_MOD, @@ -200,6 +278,14 @@ static struct powerdomain neon_pwrdm = { .voltdm = { .name = "mpu_iva" }, }; +static struct powerdomain neon_am35x_pwrdm = { + .name = "neon_pwrdm", + .prcm_offs = OMAP3430_NEON_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .voltdm = { .name = "mpu_iva" }, +}; + static struct powerdomain usbhost_pwrdm = { .name = "usbhost_pwrdm", .prcm_offs = OMAP3430ES2_USBHOST_MOD, @@ -293,6 +379,22 @@ static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = { NULL }; +static struct powerdomain *powerdomains_am35x[] __initdata = { + &wkup_omap2_pwrdm, + &mpu_am35x_pwrdm, + &neon_am35x_pwrdm, + &core_am35x_pwrdm, + &sgx_am35x_pwrdm, + &dss_am35x_pwrdm, + &per_am35x_pwrdm, + &emu_pwrdm, + &dpll1_pwrdm, + &dpll3_pwrdm, + &dpll4_pwrdm, + &dpll5_pwrdm, + NULL +}; + void __init omap3xxx_powerdomains_init(void) { unsigned int rev; @@ -301,21 +403,34 @@ void __init omap3xxx_powerdomains_init(void) return; pwrdm_register_platform_funcs(&omap3_pwrdm_operations); - pwrdm_register_pwrdms(powerdomains_omap3430_common); rev = omap_rev(); - if (rev == OMAP3430_REV_ES1_0) - pwrdm_register_pwrdms(powerdomains_omap3430es1); - else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 || - rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0) - pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0); - else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 || - rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1 || - rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2) - pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus); - else - WARN(1, "OMAP3 powerdomain init: unknown chip type\n"); + if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { + pwrdm_register_pwrdms(powerdomains_am35x); + } else { + pwrdm_register_pwrdms(powerdomains_omap3430_common); + + switch (rev) { + case OMAP3430_REV_ES1_0: + pwrdm_register_pwrdms(powerdomains_omap3430es1); + break; + case OMAP3430_REV_ES2_0: + case OMAP3430_REV_ES2_1: + case OMAP3430_REV_ES3_0: + case OMAP3630_REV_ES1_0: + pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0); + break; + case OMAP3430_REV_ES3_1: + case OMAP3430_REV_ES3_1_2: + case OMAP3630_REV_ES1_1: + case OMAP3630_REV_ES1_2: + pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus); + break; + default: + WARN(1, "OMAP3 powerdomain init: unknown chip type\n"); + } + } pwrdm_complete_init(); } -- GitLab From 0354440ba142eb9b6a03d287349350c1f75e5786 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:17 +0200 Subject: [PATCH 3130/6849] batman-adv: Prefix unicast local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/unicast.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index d021055ad262..472436a06d89 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -29,9 +29,10 @@ #include "hard-interface.h" -static struct sk_buff *frag_merge_packet(struct list_head *head, - struct frag_packet_list_entry *tfp, - struct sk_buff *skb) +static struct sk_buff * +batadv_frag_merge_packet(struct list_head *head, + struct frag_packet_list_entry *tfp, + struct sk_buff *skb) { struct unicast_frag_packet *up = (struct unicast_frag_packet *)skb->data; @@ -75,7 +76,8 @@ err: return NULL; } -static void frag_create_entry(struct list_head *head, struct sk_buff *skb) +static void batadv_frag_create_entry(struct list_head *head, + struct sk_buff *skb) { struct frag_packet_list_entry *tfp; struct unicast_frag_packet *up = @@ -91,7 +93,7 @@ static void frag_create_entry(struct list_head *head, struct sk_buff *skb) return; } -static int frag_create_buffer(struct list_head *head) +static int batadv_frag_create_buffer(struct list_head *head) { int i; struct frag_packet_list_entry *tfp; @@ -111,8 +113,9 @@ static int frag_create_buffer(struct list_head *head) return 0; } -static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, - const struct unicast_frag_packet *up) +static struct frag_packet_list_entry * +batadv_frag_search_packet(struct list_head *head, + const struct unicast_frag_packet *up) { struct frag_packet_list_entry *tfp; struct unicast_frag_packet *tmp_up = NULL; @@ -188,22 +191,22 @@ int batadv_frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, orig_node->last_frag_packet = jiffies; if (list_empty(&orig_node->frag_list) && - frag_create_buffer(&orig_node->frag_list)) { + batadv_frag_create_buffer(&orig_node->frag_list)) { pr_debug("couldn't create frag buffer\n"); goto out; } - tmp_frag_entry = frag_search_packet(&orig_node->frag_list, - unicast_packet); + tmp_frag_entry = batadv_frag_search_packet(&orig_node->frag_list, + unicast_packet); if (!tmp_frag_entry) { - frag_create_entry(&orig_node->frag_list, skb); + batadv_frag_create_entry(&orig_node->frag_list, skb); ret = NET_RX_SUCCESS; goto out; } - *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, - skb); + *new_skb = batadv_frag_merge_packet(&orig_node->frag_list, + tmp_frag_entry, skb); /* if not, merge failed */ if (*new_skb) ret = NET_RX_SUCCESS; -- GitLab From eaad8ad95392d1da3c0f2404dfc3fce56afea766 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:18 +0200 Subject: [PATCH 3131/6849] batman-adv: Prefix vis local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/vis.c | 201 ++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 98 deletions(-) diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index d45989e0bbd7..607b1015a761 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -28,10 +28,10 @@ #define MAX_VIS_PACKET_SIZE 1000 -static void start_vis_timer(struct bat_priv *bat_priv); +static void batadv_start_vis_timer(struct bat_priv *bat_priv); /* free the info */ -static void free_info(struct kref *ref) +static void batadv_free_info(struct kref *ref) { struct vis_info *info = container_of(ref, struct vis_info, refcount); struct bat_priv *bat_priv = info->bat_priv; @@ -50,7 +50,7 @@ static void free_info(struct kref *ref) } /* Compare two vis packets, used by the hashing algorithm */ -static int vis_info_cmp(const struct hlist_node *node, const void *data2) +static int batadv_vis_info_cmp(const struct hlist_node *node, const void *data2) { const struct vis_info *d1, *d2; const struct vis_packet *p1, *p2; @@ -65,7 +65,7 @@ static int vis_info_cmp(const struct hlist_node *node, const void *data2) /* hash function to choose an entry in a hash table of given size * hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -static uint32_t vis_info_choose(const void *data, uint32_t size) +static uint32_t batadv_vis_info_choose(const void *data, uint32_t size) { const struct vis_info *vis_info = data; const struct vis_packet *packet; @@ -88,8 +88,8 @@ static uint32_t vis_info_choose(const void *data, uint32_t size) return hash % size; } -static struct vis_info *vis_hash_find(struct bat_priv *bat_priv, - const void *data) +static struct vis_info *batadv_vis_hash_find(struct bat_priv *bat_priv, + const void *data) { struct hashtable_t *hash = bat_priv->vis_hash; struct hlist_head *head; @@ -100,12 +100,12 @@ static struct vis_info *vis_hash_find(struct bat_priv *bat_priv, if (!hash) return NULL; - index = vis_info_choose(data, hash->size); + index = batadv_vis_info_choose(data, hash->size); head = &hash->table[index]; rcu_read_lock(); hlist_for_each_entry_rcu(vis_info, node, head, hash_entry) { - if (!vis_info_cmp(node, data)) + if (!batadv_vis_info_cmp(node, data)) continue; vis_info_tmp = vis_info; @@ -119,9 +119,9 @@ static struct vis_info *vis_hash_find(struct bat_priv *bat_priv, /* insert interface to the list of interfaces of one originator, if it * does not already exist in the list */ -static void vis_data_insert_interface(const uint8_t *interface, - struct hlist_head *if_list, - bool primary) +static void batadv_vis_data_insert_interface(const uint8_t *interface, + struct hlist_head *if_list, + bool primary) { struct if_list_entry *entry; struct hlist_node *pos; @@ -140,8 +140,7 @@ static void vis_data_insert_interface(const uint8_t *interface, hlist_add_head(&entry->list, if_list); } -static ssize_t vis_data_read_prim_sec(char *buff, - const struct hlist_head *if_list) +static ssize_t batadv_vis_prim_sec(char *buff, const struct hlist_head *if_list) { struct if_list_entry *entry; struct hlist_node *pos; @@ -157,7 +156,7 @@ static ssize_t vis_data_read_prim_sec(char *buff, return len; } -static size_t vis_data_count_prim_sec(struct hlist_head *if_list) +static size_t batadv_vis_cnt_prim_sec(struct hlist_head *if_list) { struct if_list_entry *entry; struct hlist_node *pos; @@ -174,9 +173,9 @@ static size_t vis_data_count_prim_sec(struct hlist_head *if_list) } /* read an entry */ -static ssize_t vis_data_read_entry(char *buff, - const struct vis_info_entry *entry, - const uint8_t *src, bool primary) +static ssize_t batadv_vis_data_read_entry(char *buff, + const struct vis_info_entry *entry, + const uint8_t *src, bool primary) { /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ if (primary && entry->quality == 0) @@ -227,8 +226,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) entries = (struct vis_info_entry *) ((char *)packet + sizeof(*packet)); - vis_data_insert_interface(packet->vis_orig, - &vis_if_list, true); + batadv_vis_data_insert_interface(packet->vis_orig, + &vis_if_list, true); for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) @@ -236,9 +235,9 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (batadv_compare_eth(entries[j].src, packet->vis_orig)) continue; - vis_data_insert_interface(entries[j].src, - &vis_if_list, - false); + batadv_vis_data_insert_interface(entries[j].src, + &vis_if_list, + false); } hlist_for_each_entry(entry, pos, &vis_if_list, list) { @@ -248,7 +247,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (batadv_compare_eth(entry->addr, packet->vis_orig)) buf_size += - vis_data_count_prim_sec(&vis_if_list); + batadv_vis_cnt_prim_sec(&vis_if_list); buf_size += 1; } @@ -280,8 +279,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) entries = (struct vis_info_entry *) ((char *)packet + sizeof(*packet)); - vis_data_insert_interface(packet->vis_orig, - &vis_if_list, true); + batadv_vis_data_insert_interface(packet->vis_orig, + &vis_if_list, true); for (j = 0; j < packet->entries; j++) { if (entries[j].quality == 0) @@ -289,9 +288,9 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (batadv_compare_eth(entries[j].src, packet->vis_orig)) continue; - vis_data_insert_interface(entries[j].src, - &vis_if_list, - false); + batadv_vis_data_insert_interface(entries[j].src, + &vis_if_list, + false); } hlist_for_each_entry(entry, pos, &vis_if_list, list) { @@ -299,7 +298,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) entry->addr); for (j = 0; j < packet->entries; j++) - buff_pos += vis_data_read_entry( + buff_pos += batadv_vis_data_read_entry( buff + buff_pos, &entries[j], entry->addr, @@ -309,8 +308,8 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (batadv_compare_eth(entry->addr, packet->vis_orig)) buff_pos += - vis_data_read_prim_sec(buff + buff_pos, - &vis_if_list); + batadv_vis_prim_sec(buff + buff_pos, + &vis_if_list); buff_pos += sprintf(buff + buff_pos, "\n"); } @@ -338,7 +337,8 @@ out: /* add the info packet to the send list, if it was not * already linked in. */ -static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) +static void batadv_send_list_add(struct bat_priv *bat_priv, + struct vis_info *info) { if (list_empty(&info->send_list)) { kref_get(&info->refcount); @@ -349,17 +349,17 @@ static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) /* delete the info packet from the send list, if it was * linked in. */ -static void send_list_del(struct vis_info *info) +static void batadv_send_list_del(struct vis_info *info) { if (!list_empty(&info->send_list)) { list_del_init(&info->send_list); - kref_put(&info->refcount, free_info); + kref_put(&info->refcount, batadv_free_info); } } /* tries to add one entry to the receive list. */ -static void recv_list_add(struct bat_priv *bat_priv, - struct list_head *recv_list, const char *mac) +static void batadv_recv_list_add(struct bat_priv *bat_priv, + struct list_head *recv_list, const char *mac) { struct recvlist_node *entry; @@ -374,8 +374,9 @@ static void recv_list_add(struct bat_priv *bat_priv, } /* returns 1 if this mac is in the recv_list */ -static int recv_list_is_in(struct bat_priv *bat_priv, - const struct list_head *recv_list, const char *mac) +static int batadv_recv_list_is_in(struct bat_priv *bat_priv, + const struct list_head *recv_list, + const char *mac) { const struct recvlist_node *entry; @@ -394,10 +395,10 @@ static int recv_list_is_in(struct bat_priv *bat_priv, * broken.. ). vis hash must be locked outside. is_new is set when the packet * is newer than old entries in the hash. */ -static struct vis_info *add_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len, int *is_new, - int make_broadcast) +static struct vis_info *batadv_add_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len, int *is_new, + int make_broadcast) { struct vis_info *info, *old_info; struct vis_packet *search_packet, *old_packet; @@ -418,7 +419,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, sizeof(*search_packet)); memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); - old_info = vis_hash_find(bat_priv, &search_elem); + old_info = batadv_vis_hash_find(bat_priv, &search_elem); kfree_skb(search_elem.skb_packet); if (old_info) { @@ -426,8 +427,9 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, if (!seq_after(ntohl(vis_packet->seqno), ntohl(old_packet->seqno))) { if (old_packet->seqno == vis_packet->seqno) { - recv_list_add(bat_priv, &old_info->recv_list, - vis_packet->sender_orig); + batadv_recv_list_add(bat_priv, + &old_info->recv_list, + vis_packet->sender_orig); return old_info; } else { /* newer packet is already in hash. */ @@ -435,10 +437,10 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, } } /* remove old entry */ - batadv_hash_remove(bat_priv->vis_hash, vis_info_cmp, - vis_info_choose, old_info); - send_list_del(old_info); - kref_put(&old_info->refcount, free_info); + batadv_hash_remove(bat_priv->vis_hash, batadv_vis_info_cmp, + batadv_vis_info_choose, old_info); + batadv_send_list_del(old_info); + kref_put(&old_info->refcount, batadv_free_info); } info = kmalloc(sizeof(*info), GFP_ATOMIC); @@ -473,14 +475,15 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len) packet->entries = vis_info_len / sizeof(struct vis_info_entry); - recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); + batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); /* try to add it */ - hash_added = batadv_hash_add(bat_priv->vis_hash, vis_info_cmp, - vis_info_choose, info, &info->hash_entry); + hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, + batadv_vis_info_choose, info, + &info->hash_entry); if (hash_added != 0) { /* did not work (for some reason) */ - kref_put(&info->refcount, free_info); + kref_put(&info->refcount, batadv_free_info); info = NULL; } @@ -499,8 +502,8 @@ void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); spin_lock_bh(&bat_priv->vis_hash_lock); - info = add_packet(bat_priv, vis_packet, vis_info_len, - &is_new, make_broadcast); + info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, + &is_new, make_broadcast); if (!info) goto end; @@ -508,7 +511,7 @@ void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, * hash. */ if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) - send_list_add(bat_priv, info); + batadv_send_list_add(bat_priv, info); end: spin_unlock_bh(&bat_priv->vis_hash_lock); } @@ -534,8 +537,8 @@ void batadv_receive_client_update_packet(struct bat_priv *bat_priv, are_target = 1; spin_lock_bh(&bat_priv->vis_hash_lock); - info = add_packet(bat_priv, vis_packet, vis_info_len, - &is_new, are_target); + info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, + &is_new, are_target); if (!info) goto end; @@ -546,11 +549,11 @@ void batadv_receive_client_update_packet(struct bat_priv *bat_priv, /* send only if we're the target server or ... */ if (are_target && is_new) { packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ - send_list_add(bat_priv, info); + batadv_send_list_add(bat_priv, info); /* ... we're not the recipient (and thus need to forward). */ } else if (!batadv_is_my_mac(packet->target_orig)) { - send_list_add(bat_priv, info); + batadv_send_list_add(bat_priv, info); } end: @@ -562,8 +565,8 @@ end: * * Must be called with the originator hash locked */ -static int find_best_vis_server(struct bat_priv *bat_priv, - struct vis_info *info) +static int batadv_find_best_vis_server(struct bat_priv *bat_priv, + struct vis_info *info) { struct hashtable_t *hash = bat_priv->orig_hash; struct neigh_node *router; @@ -600,7 +603,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv, } /* Return true if the vis packet is full. */ -static bool vis_packet_full(const struct vis_info *info) +static bool batadv_vis_packet_full(const struct vis_info *info) { const struct vis_packet *packet; packet = (struct vis_packet *)info->skb_packet->data; @@ -614,7 +617,7 @@ static bool vis_packet_full(const struct vis_info *info) /* generates a packet of own vis data, * returns 0 on success, -1 if no packet could be generated */ -static int generate_vis_packet(struct bat_priv *bat_priv) +static int batadv_generate_vis_packet(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *node; @@ -638,7 +641,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) skb_trim(info->skb_packet, sizeof(*packet)); if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { - best_tq = find_best_vis_server(bat_priv, info); + best_tq = batadv_find_best_vis_server(bat_priv, info); if (best_tq < 0) return best_tq; @@ -675,7 +678,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) next: batadv_neigh_node_free_ref(router); - if (vis_packet_full(info)) + if (batadv_vis_packet_full(info)) goto unlock; } rcu_read_unlock(); @@ -697,7 +700,7 @@ next: entry->quality = 0; /* 0 means TT */ packet->entries++; - if (vis_packet_full(info)) + if (batadv_vis_packet_full(info)) goto unlock; } rcu_read_unlock(); @@ -713,7 +716,7 @@ unlock: /* free old vis packets. Must be called with this vis_hash_lock * held */ -static void purge_vis_packets(struct bat_priv *bat_priv) +static void batadv_purge_vis_packets(struct bat_priv *bat_priv) { uint32_t i; struct hashtable_t *hash = bat_priv->vis_hash; @@ -733,15 +736,15 @@ static void purge_vis_packets(struct bat_priv *bat_priv) if (batadv_has_timed_out(info->first_seen, VIS_TIMEOUT)) { hlist_del(node); - send_list_del(info); - kref_put(&info->refcount, free_info); + batadv_send_list_del(info); + kref_put(&info->refcount, batadv_free_info); } } } } -static void broadcast_vis_packet(struct bat_priv *bat_priv, - struct vis_info *info) +static void batadv_broadcast_vis_packet(struct bat_priv *bat_priv, + struct vis_info *info) { struct neigh_node *router; struct hashtable_t *hash = bat_priv->orig_hash; @@ -774,8 +777,8 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, /* don't send it if we already received the packet from * this node. */ - if (recv_list_is_in(bat_priv, &info->recv_list, - orig_node->orig)) { + if (batadv_recv_list_is_in(bat_priv, &info->recv_list, + orig_node->orig)) { batadv_neigh_node_free_ref(router); continue; } @@ -796,8 +799,8 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, } } -static void unicast_vis_packet(struct bat_priv *bat_priv, - struct vis_info *info) +static void batadv_unicast_vis_packet(struct bat_priv *bat_priv, + struct vis_info *info) { struct orig_node *orig_node; struct neigh_node *router = NULL; @@ -825,8 +828,9 @@ out: batadv_orig_node_free_ref(orig_node); } -/* only send one vis packet. called from send_vis_packets() */ -static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) +/* only send one vis packet. called from batadv_send_vis_packets() */ +static void batadv_send_vis_packet(struct bat_priv *bat_priv, + struct vis_info *info) { struct hard_iface *primary_if; struct vis_packet *packet; @@ -845,9 +849,9 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) packet->header.ttl--; if (is_broadcast_ether_addr(packet->target_orig)) - broadcast_vis_packet(bat_priv, info); + batadv_broadcast_vis_packet(bat_priv, info); else - unicast_vis_packet(bat_priv, info); + batadv_unicast_vis_packet(bat_priv, info); packet->header.ttl++; /* restore TTL */ out: @@ -856,7 +860,7 @@ out: } /* called from timer; send (and maybe generate) vis packet. */ -static void send_vis_packets(struct work_struct *work) +static void batadv_send_vis_packets(struct work_struct *work) { struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); @@ -865,11 +869,11 @@ static void send_vis_packets(struct work_struct *work) struct vis_info *info; spin_lock_bh(&bat_priv->vis_hash_lock); - purge_vis_packets(bat_priv); + batadv_purge_vis_packets(bat_priv); - if (generate_vis_packet(bat_priv) == 0) { + if (batadv_generate_vis_packet(bat_priv) == 0) { /* schedule if generation was successful */ - send_list_add(bat_priv, bat_priv->my_vis_info); + batadv_send_list_add(bat_priv, bat_priv->my_vis_info); } while (!list_empty(&bat_priv->vis_send_list)) { @@ -879,14 +883,14 @@ static void send_vis_packets(struct work_struct *work) kref_get(&info->refcount); spin_unlock_bh(&bat_priv->vis_hash_lock); - send_vis_packet(bat_priv, info); + batadv_send_vis_packet(bat_priv, info); spin_lock_bh(&bat_priv->vis_hash_lock); - send_list_del(info); - kref_put(&info->refcount, free_info); + batadv_send_list_del(info); + kref_put(&info->refcount, batadv_free_info); } spin_unlock_bh(&bat_priv->vis_hash_lock); - start_vis_timer(bat_priv); + batadv_start_vis_timer(bat_priv); } /* init the vis server. this may only be called when if_list is already @@ -937,18 +941,19 @@ int batadv_vis_init(struct bat_priv *bat_priv) INIT_LIST_HEAD(&bat_priv->vis_send_list); - hash_added = batadv_hash_add(bat_priv->vis_hash, vis_info_cmp, - vis_info_choose, bat_priv->my_vis_info, + hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, + batadv_vis_info_choose, + bat_priv->my_vis_info, &bat_priv->my_vis_info->hash_entry); if (hash_added != 0) { pr_err("Can't add own vis packet into hash\n"); /* not in hash, need to remove it manually. */ - kref_put(&bat_priv->my_vis_info->refcount, free_info); + kref_put(&bat_priv->my_vis_info->refcount, batadv_free_info); goto err; } spin_unlock_bh(&bat_priv->vis_hash_lock); - start_vis_timer(bat_priv); + batadv_start_vis_timer(bat_priv); return 0; free_info: @@ -961,13 +966,13 @@ err: } /* Decrease the reference count on a hash item info */ -static void free_info_ref(struct hlist_node *node, void *arg) +static void batadv_free_info_ref(struct hlist_node *node, void *arg) { struct vis_info *info; info = container_of(node, struct vis_info, hash_entry); - send_list_del(info); - kref_put(&info->refcount, free_info); + batadv_send_list_del(info); + kref_put(&info->refcount, batadv_free_info); } /* shutdown vis-server */ @@ -980,16 +985,16 @@ void batadv_vis_quit(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->vis_hash_lock); /* properly remove, kill timers ... */ - batadv_hash_delete(bat_priv->vis_hash, free_info_ref, NULL); + batadv_hash_delete(bat_priv->vis_hash, batadv_free_info_ref, NULL); bat_priv->vis_hash = NULL; bat_priv->my_vis_info = NULL; spin_unlock_bh(&bat_priv->vis_hash_lock); } /* schedule packets for (re)transmission */ -static void start_vis_timer(struct bat_priv *bat_priv) +static void batadv_start_vis_timer(struct bat_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets); + INIT_DELAYED_WORK(&bat_priv->vis_work, batadv_send_vis_packets); queue_delayed_work(batadv_event_workqueue, &bat_priv->vis_work, msecs_to_jiffies(VIS_INTERVAL)); } -- GitLab From ee11ad61f232c201ba62990aa490264220f834cd Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:19 +0200 Subject: [PATCH 3132/6849] batman-adv: Prefix main local static functions with batadv_ All non-static symbols of batman-adv were prefixed with batadv_ to avoid collisions with other symbols of the kernel. Other symbols of batman-adv should use the same prefix to keep the naming scheme consistent. Signed-off-by: Sven Eckelmann --- net/batman-adv/main.c | 76 ++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index e4564306453c..9cf0b38fab8b 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -38,22 +38,23 @@ * list traversals just rcu-locked */ struct list_head batadv_hardif_list; -static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); +static int (*batadv_rx_handler[256])(struct sk_buff *, + struct hard_iface *); char batadv_routing_algo[20] = "BATMAN_IV"; -static struct hlist_head bat_algo_list; +static struct hlist_head batadv_algo_list; unsigned char batadv_broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct workqueue_struct *batadv_event_workqueue; -static void recv_handler_init(void); +static void batadv_recv_handler_init(void); -static int __init batman_init(void) +static int __init batadv_init(void) { INIT_LIST_HEAD(&batadv_hardif_list); - INIT_HLIST_HEAD(&bat_algo_list); + INIT_HLIST_HEAD(&batadv_algo_list); - recv_handler_init(); + batadv_recv_handler_init(); batadv_iv_init(); @@ -76,7 +77,7 @@ static int __init batman_init(void) return 0; } -static void __exit batman_exit(void) +static void __exit batadv_exit(void) { batadv_debugfs_destroy(); unregister_netdevice_notifier(&batadv_hard_if_notifier); @@ -189,8 +190,8 @@ int batadv_is_my_mac(const uint8_t *addr) return 0; } -static int recv_unhandled_packet(struct sk_buff *skb, - struct hard_iface *recv_if) +static int batadv_recv_unhandled_packet(struct sk_buff *skb, + struct hard_iface *recv_if) { return NET_RX_DROP; } @@ -248,7 +249,7 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, * the supplied skb. if not, we have to free the skb. */ idx = batman_ogm_packet->header.packet_type; - ret = (*recv_packet_handler[idx])(skb, hard_iface); + ret = (*batadv_rx_handler[idx])(skb, hard_iface); if (ret == NET_RX_DROP) kfree_skb(skb); @@ -265,51 +266,51 @@ err_out: return NET_RX_DROP; } -static void recv_handler_init(void) +static void batadv_recv_handler_init(void) { int i; - for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) - recv_packet_handler[i] = recv_unhandled_packet; + for (i = 0; i < ARRAY_SIZE(batadv_rx_handler); i++) + batadv_rx_handler[i] = batadv_recv_unhandled_packet; /* batman icmp packet */ - recv_packet_handler[BAT_ICMP] = batadv_recv_icmp_packet; + batadv_rx_handler[BAT_ICMP] = batadv_recv_icmp_packet; /* unicast packet */ - recv_packet_handler[BAT_UNICAST] = batadv_recv_unicast_packet; + batadv_rx_handler[BAT_UNICAST] = batadv_recv_unicast_packet; /* fragmented unicast packet */ - recv_packet_handler[BAT_UNICAST_FRAG] = batadv_recv_ucast_frag_packet; + batadv_rx_handler[BAT_UNICAST_FRAG] = batadv_recv_ucast_frag_packet; /* broadcast packet */ - recv_packet_handler[BAT_BCAST] = batadv_recv_bcast_packet; + batadv_rx_handler[BAT_BCAST] = batadv_recv_bcast_packet; /* vis packet */ - recv_packet_handler[BAT_VIS] = batadv_recv_vis_packet; + batadv_rx_handler[BAT_VIS] = batadv_recv_vis_packet; /* Translation table query (request or response) */ - recv_packet_handler[BAT_TT_QUERY] = batadv_recv_tt_query; + batadv_rx_handler[BAT_TT_QUERY] = batadv_recv_tt_query; /* Roaming advertisement */ - recv_packet_handler[BAT_ROAM_ADV] = batadv_recv_roam_adv; + batadv_rx_handler[BAT_ROAM_ADV] = batadv_recv_roam_adv; } int batadv_recv_handler_register(uint8_t packet_type, int (*recv_handler)(struct sk_buff *, struct hard_iface *)) { - if (recv_packet_handler[packet_type] != &recv_unhandled_packet) + if (batadv_rx_handler[packet_type] != &batadv_recv_unhandled_packet) return -EBUSY; - recv_packet_handler[packet_type] = recv_handler; + batadv_rx_handler[packet_type] = recv_handler; return 0; } void batadv_recv_handler_unregister(uint8_t packet_type) { - recv_packet_handler[packet_type] = recv_unhandled_packet; + batadv_rx_handler[packet_type] = batadv_recv_unhandled_packet; } -static struct bat_algo_ops *bat_algo_get(char *name) +static struct bat_algo_ops *batadv_algo_get(char *name) { struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; struct hlist_node *node; - hlist_for_each_entry(bat_algo_ops_tmp, node, &bat_algo_list, list) { + hlist_for_each_entry(bat_algo_ops_tmp, node, &batadv_algo_list, list) { if (strcmp(bat_algo_ops_tmp->name, name) != 0) continue; @@ -325,7 +326,7 @@ int batadv_algo_register(struct bat_algo_ops *bat_algo_ops) struct bat_algo_ops *bat_algo_ops_tmp; int ret; - bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name); + bat_algo_ops_tmp = batadv_algo_get(bat_algo_ops->name); if (bat_algo_ops_tmp) { pr_info("Trying to register already registered routing algorithm: %s\n", bat_algo_ops->name); @@ -347,7 +348,7 @@ int batadv_algo_register(struct bat_algo_ops *bat_algo_ops) } INIT_HLIST_NODE(&bat_algo_ops->list); - hlist_add_head(&bat_algo_ops->list, &bat_algo_list); + hlist_add_head(&bat_algo_ops->list, &batadv_algo_list); ret = 0; out: @@ -359,7 +360,7 @@ int batadv_algo_select(struct bat_priv *bat_priv, char *name) struct bat_algo_ops *bat_algo_ops; int ret = -EINVAL; - bat_algo_ops = bat_algo_get(name); + bat_algo_ops = batadv_algo_get(name); if (!bat_algo_ops) goto out; @@ -377,14 +378,14 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Available routing algorithms:\n"); - hlist_for_each_entry(bat_algo_ops, node, &bat_algo_list, list) { + hlist_for_each_entry(bat_algo_ops, node, &batadv_algo_list, list) { seq_printf(seq, "%s\n", bat_algo_ops->name); } return 0; } -static int param_set_ra(const char *val, const struct kernel_param *kp) +static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) { struct bat_algo_ops *bat_algo_ops; char *algo_name = (char *)val; @@ -393,7 +394,7 @@ static int param_set_ra(const char *val, const struct kernel_param *kp) if (algo_name[name_len - 1] == '\n') algo_name[name_len - 1] = '\0'; - bat_algo_ops = bat_algo_get(algo_name); + bat_algo_ops = batadv_algo_get(algo_name); if (!bat_algo_ops) { pr_err("Routing algorithm '%s' is not supported\n", algo_name); return -EINVAL; @@ -402,19 +403,20 @@ static int param_set_ra(const char *val, const struct kernel_param *kp) return param_set_copystring(algo_name, kp); } -static const struct kernel_param_ops param_ops_ra = { - .set = param_set_ra, +static const struct kernel_param_ops batadv_param_ops_ra = { + .set = batadv_param_set_ra, .get = param_get_string, }; -static struct kparam_string __param_string_ra = { +static struct kparam_string batadv_param_string_ra = { .maxlen = sizeof(batadv_routing_algo), .string = batadv_routing_algo, }; -module_param_cb(routing_algo, ¶m_ops_ra, &__param_string_ra, 0644); -module_init(batman_init); -module_exit(batman_exit); +module_param_cb(routing_algo, &batadv_param_ops_ra, &batadv_param_string_ra, + 0644); +module_init(batadv_init); +module_exit(batadv_exit); MODULE_LICENSE("GPL"); -- GitLab From 3e34819e0eafaa6c873e9704bb478c0cdd6bb481 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:22 +0200 Subject: [PATCH 3133/6849] batman-adv: Prefix remaining function like macros with batadv_ Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 4 +- net/batman-adv/bat_iv_ogm.c | 2 +- net/batman-adv/bat_sysfs.c | 81 ++++++++++++++++-------------- net/batman-adv/gateway_client.c | 2 +- net/batman-adv/gateway_common.c | 26 +++++----- net/batman-adv/hard-interface.c | 38 +++++++------- net/batman-adv/main.h | 20 ++++---- net/batman-adv/routing.c | 4 +- net/batman-adv/send.c | 2 +- net/batman-adv/translation-table.c | 4 +- net/batman-adv/vis.c | 4 +- 11 files changed, 98 insertions(+), 89 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 03f09f0f6d98..ca6aee4bf941 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -360,8 +360,8 @@ int batadv_debugfs_add_meshif(struct net_device *dev) bat_priv->debug_dir, dev, &(*bat_debug)->fops); if (!file) { - bat_err(dev, "Can't add debugfs file: %s/%s\n", - dev->name, ((*bat_debug)->attr).name); + batadv_err(dev, "Can't add debugfs file: %s/%s\n", + dev->name, ((*bat_debug)->attr).name); goto rem_attr; } } diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index ca6466574c46..ffe9d1d057c1 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -373,7 +373,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, /* own packet should always be scheduled */ if (!own_packet) { - if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { + if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) { batadv_dbg(DBG_BATMAN, bat_priv, "batman packet queue full\n"); goto out; diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 03b76a41ac4e..54429a222bd6 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -191,18 +191,17 @@ static int batadv_store_bool_attr(char *buff, size_t count, enabled = 0; if (enabled < 0) { - bat_info(net_dev, - "%s: Invalid parameter received: %s\n", - attr_name, buff); + batadv_info(net_dev, "%s: Invalid parameter received: %s\n", + attr_name, buff); return -EINVAL; } if (atomic_read(attr) == enabled) return count; - bat_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, - atomic_read(attr) == 1 ? "enabled" : "disabled", - enabled == 1 ? "enabled" : "disabled"); + batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, + atomic_read(attr) == 1 ? "enabled" : "disabled", + enabled == 1 ? "enabled" : "disabled"); atomic_set(attr, (unsigned int)enabled); return count; @@ -235,29 +234,28 @@ static int batadv_store_uint_attr(const char *buff, size_t count, ret = kstrtoul(buff, 10, &uint_val); if (ret) { - bat_info(net_dev, - "%s: Invalid parameter received: %s\n", - attr_name, buff); + batadv_info(net_dev, "%s: Invalid parameter received: %s\n", + attr_name, buff); return -EINVAL; } if (uint_val < min) { - bat_info(net_dev, "%s: Value is too small: %lu min: %u\n", - attr_name, uint_val, min); + batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n", + attr_name, uint_val, min); return -EINVAL; } if (uint_val > max) { - bat_info(net_dev, "%s: Value is too big: %lu max: %u\n", - attr_name, uint_val, max); + batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n", + attr_name, uint_val, max); return -EINVAL; } if (atomic_read(attr) == uint_val) return count; - bat_info(net_dev, "%s: Changing from: %i to: %lu\n", - attr_name, atomic_read(attr), uint_val); + batadv_info(net_dev, "%s: Changing from: %i to: %lu\n", + attr_name, atomic_read(attr), uint_val); atomic_set(attr, uint_val); return count; @@ -299,6 +297,7 @@ static ssize_t batadv_store_vis_mode(struct kobject *kobj, struct bat_priv *bat_priv = netdev_priv(net_dev); unsigned long val; int ret, vis_mode_tmp = -1; + const char *old_mode, *new_mode; ret = kstrtoul(buff, 10, &val); @@ -315,19 +314,27 @@ static ssize_t batadv_store_vis_mode(struct kobject *kobj, if (buff[count - 1] == '\n') buff[count - 1] = '\0'; - bat_info(net_dev, - "Invalid parameter for 'vis mode' setting received: %s\n", - buff); + batadv_info(net_dev, + "Invalid parameter for 'vis mode' setting received: %s\n", + buff); return -EINVAL; } if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) return count; - bat_info(net_dev, "Changing vis mode from: %s to: %s\n", - atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server"); + if (atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE) + old_mode = "client"; + else + old_mode = "server"; + + if (vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE) + new_mode = "client"; + else + new_mode = "server"; + + batadv_info(net_dev, "Changing vis mode from: %s to: %s\n", old_mode, + new_mode); atomic_set(&bat_priv->vis_mode, (unsigned int)vis_mode_tmp); return count; @@ -391,9 +398,9 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, gw_mode_tmp = GW_MODE_SERVER; if (gw_mode_tmp < 0) { - bat_info(net_dev, - "Invalid parameter for 'gw mode' setting received: %s\n", - buff); + batadv_info(net_dev, + "Invalid parameter for 'gw mode' setting received: %s\n", + buff); return -EINVAL; } @@ -412,8 +419,8 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, break; } - bat_info(net_dev, "Changing gw mode from: %s to: %s\n", - curr_gw_mode_str, buff); + batadv_info(net_dev, "Changing gw mode from: %s to: %s\n", + curr_gw_mode_str, buff); batadv_gw_deselect(bat_priv); atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); @@ -500,8 +507,8 @@ int batadv_sysfs_add_meshif(struct net_device *dev) bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); if (!bat_priv->mesh_obj) { - bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, - SYSFS_IF_MESH_SUBDIR); + batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, + SYSFS_IF_MESH_SUBDIR); goto out; } @@ -509,9 +516,9 @@ int batadv_sysfs_add_meshif(struct net_device *dev) err = sysfs_create_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); if (err) { - bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_MESH_SUBDIR, - ((*bat_attr)->attr).name); + batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR, + ((*bat_attr)->attr).name); goto rem_attr; } } @@ -669,17 +676,17 @@ int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) hardif_kobject); if (!*hardif_obj) { - bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, - SYSFS_IF_BAT_SUBDIR); + batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, + SYSFS_IF_BAT_SUBDIR); goto out; } for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) { err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); if (err) { - bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_BAT_SUBDIR, - ((*bat_attr)->attr).name); + batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_BAT_SUBDIR, + ((*bat_attr)->attr).name); goto rem_attr; } } diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index efe7519f1491..f43eb57b8a69 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -197,7 +197,7 @@ void batadv_gw_election(struct bat_priv *bat_priv) if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) goto out; - if (!atomic_dec_not_zero(&bat_priv->gw_reselect)) + if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect)) goto out; curr_gw = batadv_gw_get_selected_gw_node(bat_priv); diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 6edf37f9a15c..f5c3980aaea6 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -97,9 +97,9 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, ret = kstrtol(buff, 10, &ldown); if (ret) { - bat_err(net_dev, - "Download speed of gateway mode invalid: %s\n", - buff); + batadv_err(net_dev, + "Download speed of gateway mode invalid: %s\n", + buff); return false; } @@ -122,9 +122,9 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, ret = kstrtol(slash_ptr + 1, 10, &lup); if (ret) { - bat_err(net_dev, - "Upload speed of gateway mode invalid: %s\n", - slash_ptr + 1); + batadv_err(net_dev, + "Upload speed of gateway mode invalid: %s\n", + slash_ptr + 1); return false; } @@ -164,13 +164,13 @@ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, return count; batadv_gw_deselect(bat_priv); - bat_info(net_dev, - "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", - atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, - (down > 2048 ? down / 1024 : down), - (down > 2048 ? "MBit" : "KBit"), - (up > 2048 ? up / 1024 : up), - (up > 2048 ? "MBit" : "KBit")); + batadv_info(net_dev, + "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", + atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index c22c145d8224..c1ba6e28a96c 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -234,8 +234,8 @@ static void batadv_hardif_activate_interface(struct hard_iface *hard_iface) if (!primary_if) batadv_primary_if_select(bat_priv, hard_iface); - bat_info(hard_iface->soft_iface, "Interface activated: %s\n", - hard_iface->net_dev->name); + batadv_info(hard_iface->soft_iface, "Interface activated: %s\n", + hard_iface->net_dev->name); batadv_update_min_mtu(hard_iface->soft_iface); @@ -252,8 +252,8 @@ static void batadv_hardif_deactivate_interface(struct hard_iface *hard_iface) hard_iface->if_status = IF_INACTIVE; - bat_info(hard_iface->soft_iface, "Interface deactivated: %s\n", - hard_iface->net_dev->name); + batadv_info(hard_iface->soft_iface, "Interface deactivated: %s\n", + hard_iface->net_dev->name); batadv_update_min_mtu(hard_iface->soft_iface); } @@ -315,29 +315,29 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, dev_add_pack(&hard_iface->batman_adv_ptype); atomic_set(&hard_iface->frag_seqno, 1); - bat_info(hard_iface->soft_iface, "Adding interface: %s\n", - hard_iface->net_dev->name); + batadv_info(hard_iface->soft_iface, "Adding interface: %s\n", + hard_iface->net_dev->name); if (atomic_read(&bat_priv->fragmentation) && hard_iface->net_dev->mtu < ETH_DATA_LEN + BAT_HEADER_LEN) - bat_info(hard_iface->soft_iface, - "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %zi would solve the problem.\n", - hard_iface->net_dev->name, hard_iface->net_dev->mtu, - ETH_DATA_LEN + BAT_HEADER_LEN); + batadv_info(hard_iface->soft_iface, + "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %zi would solve the problem.\n", + hard_iface->net_dev->name, hard_iface->net_dev->mtu, + ETH_DATA_LEN + BAT_HEADER_LEN); if (!atomic_read(&bat_priv->fragmentation) && hard_iface->net_dev->mtu < ETH_DATA_LEN + BAT_HEADER_LEN) - bat_info(hard_iface->soft_iface, - "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %zi.\n", - hard_iface->net_dev->name, hard_iface->net_dev->mtu, - ETH_DATA_LEN + BAT_HEADER_LEN); + batadv_info(hard_iface->soft_iface, + "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %zi.\n", + hard_iface->net_dev->name, hard_iface->net_dev->mtu, + ETH_DATA_LEN + BAT_HEADER_LEN); if (batadv_hardif_is_iface_up(hard_iface)) batadv_hardif_activate_interface(hard_iface); else - bat_err(hard_iface->soft_iface, - "Not using interface %s (retrying later): interface not active\n", - hard_iface->net_dev->name); + batadv_err(hard_iface->soft_iface, + "Not using interface %s (retrying later): interface not active\n", + hard_iface->net_dev->name); /* begin scheduling originator messages on that interface */ batadv_schedule_bat_ogm(hard_iface); @@ -363,8 +363,8 @@ void batadv_hardif_disable_interface(struct hard_iface *hard_iface) if (hard_iface->if_status != IF_INACTIVE) goto out; - bat_info(hard_iface->soft_iface, "Removing interface: %s\n", - hard_iface->net_dev->name); + batadv_info(hard_iface->soft_iface, "Removing interface: %s\n", + hard_iface->net_dev->name); dev_remove_pack(&hard_iface->batman_adv_ptype); bat_priv->num_ifaces--; diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 28242642c3f1..b7b98177dadc 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -190,14 +190,14 @@ static inline void batadv_dbg(int type __always_unused, } #endif -#define bat_info(net_dev, fmt, arg...) \ +#define batadv_info(net_dev, fmt, arg...) \ do { \ struct net_device *_netdev = (net_dev); \ struct bat_priv *_batpriv = netdev_priv(_netdev); \ batadv_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ pr_info("%s: " fmt, _netdev->name, ## arg); \ } while (0) -#define bat_err(net_dev, fmt, arg...) \ +#define batadv_err(net_dev, fmt, arg...) \ do { \ struct net_device *_netdev = (net_dev); \ struct bat_priv *_batpriv = netdev_priv(_netdev); \ @@ -226,10 +226,10 @@ static inline bool batadv_has_timed_out(unsigned long timestamp, return time_is_before_jiffies(timestamp + msecs_to_jiffies(timeout)); } -#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) +#define batadv_atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) /* Returns the smallest signed integer in two's complement with the sizeof x */ -#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) +#define batadv_smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) /* Checks if a sequence number x is a predecessor/successor of y. * they handle overflows/underflows and can correctly check for a @@ -241,12 +241,12 @@ static inline bool batadv_has_timed_out(unsigned long timestamp, * - when adding 128 - it is neither a predecessor nor a successor, * - after adding more than 127 to the starting value - it is a successor */ -#define seq_before(x, y) ({typeof(x) _d1 = (x); \ - typeof(y) _d2 = (y); \ - typeof(x) _dummy = (_d1 - _d2); \ - (void) (&_d1 == &_d2); \ - _dummy > smallest_signed_int(_dummy); }) -#define seq_after(x, y) seq_before(y, x) +#define batadv_seq_before(x, y) ({typeof(x) _d1 = (x); \ + typeof(y) _d2 = (y); \ + typeof(x) _dummy = (_d1 - _d2); \ + (void) (&_d1 == &_d2); \ + _dummy > batadv_smallest_signed_int(_dummy); }) +#define batadv_seq_after(x, y) batadv_seq_before(y, x) /* Stop preemption on local cpu while incrementing the counter */ static inline void batadv_add_counter(struct bat_priv *bat_priv, size_t idx, diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index e7ee40d6d609..1b8f67744e23 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -922,6 +922,7 @@ static int batadv_check_unicast_ttvn(struct bat_priv *bat_priv, struct hard_iface *primary_if; struct unicast_packet *unicast_packet; bool tt_poss_change; + int is_old_ttvn; /* I could need to modify it */ if (skb_cow(skb, sizeof(struct unicast_packet)) < 0) @@ -945,7 +946,8 @@ static int batadv_check_unicast_ttvn(struct bat_priv *bat_priv, } /* Check whether I have to reroute the packet */ - if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) { + is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn); + if (is_old_ttvn || tt_poss_change) { /* check if there is enough data before accessing it */ if (pskb_may_pull(skb, sizeof(struct unicast_packet) + ETH_HLEN) < 0) diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 1842cbc280c7..3d725e0b1d90 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -141,7 +141,7 @@ int batadv_add_bcast_packet_to_list(struct bat_priv *bat_priv, struct bcast_packet *bcast_packet; struct sk_buff *newskb; - if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) { + if (!batadv_atomic_dec_not_zero(&bat_priv->bcast_queue_left)) { batadv_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n"); goto out; } diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index c673b58f3ee1..074936f2d30a 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1930,7 +1930,7 @@ static bool batadv_tt_check_roam_count(struct bat_priv *bat_priv, ROAMING_MAX_TIME)) continue; - if (!atomic_dec_not_zero(&tt_roam_node->counter)) + if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) /* Sorry, you roamed too many times! */ goto unlock; ret = true; @@ -2162,7 +2162,7 @@ int batadv_tt_append_diff(struct bat_priv *bat_priv, /* if the changes have been sent often enough */ if ((tt_num_changes < 0) && - (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { + (!batadv_atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, packet_min_len, packet_min_len); tt_num_changes = 0; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 607b1015a761..6b7a1c05e45e 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -424,8 +424,8 @@ static struct vis_info *batadv_add_packet(struct bat_priv *bat_priv, if (old_info) { old_packet = (struct vis_packet *)old_info->skb_packet->data; - if (!seq_after(ntohl(vis_packet->seqno), - ntohl(old_packet->seqno))) { + if (!batadv_seq_after(ntohl(vis_packet->seqno), + ntohl(old_packet->seqno))) { if (old_packet->seqno == vis_packet->seqno) { batadv_recv_list_add(bat_priv, &old_info->recv_list, -- GitLab From 28afd3c0756e0f052a09710c7daa0b9e27700a02 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 16 May 2012 20:23:23 +0200 Subject: [PATCH 3134/6849] batman-adv: Directly print to seq_file in vis The vis output doesn't need to be buffered in an character buffer before it can be send to the userspace program that reads from the vis debug file. Signed-off-by: Sven Eckelmann --- net/batman-adv/vis.c | 224 ++++++++++++++++--------------------------- 1 file changed, 81 insertions(+), 143 deletions(-) diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 6b7a1c05e45e..3095c41a67ad 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -140,72 +140,117 @@ static void batadv_vis_data_insert_interface(const uint8_t *interface, hlist_add_head(&entry->list, if_list); } -static ssize_t batadv_vis_prim_sec(char *buff, const struct hlist_head *if_list) +static void batadv_vis_data_read_prim_sec(struct seq_file *seq, + const struct hlist_head *if_list) { struct if_list_entry *entry; struct hlist_node *pos; - size_t len = 0; hlist_for_each_entry(entry, pos, if_list, list) { if (entry->primary) - len += sprintf(buff + len, "PRIMARY, "); + seq_printf(seq, "PRIMARY, "); else - len += sprintf(buff + len, "SEC %pM, ", entry->addr); + seq_printf(seq, "SEC %pM, ", entry->addr); } +} + +/* read an entry */ +static ssize_t batadv_vis_data_read_entry(struct seq_file *seq, + const struct vis_info_entry *entry, + const uint8_t *src, bool primary) +{ + if (primary && entry->quality == 0) + return seq_printf(seq, "TT %pM, ", entry->dest); + else if (batadv_compare_eth(entry->src, src)) + return seq_printf(seq, "TQ %pM %d, ", entry->dest, + entry->quality); + + return 0; +} + +static void batadv_vis_data_insert_interfaces(struct hlist_head *list, + struct vis_packet *packet, + struct vis_info_entry *entries) +{ + int i; + + for (i = 0; i < packet->entries; i++) { + if (entries[i].quality == 0) + continue; - return len; + if (batadv_compare_eth(entries[i].src, packet->vis_orig)) + continue; + + batadv_vis_data_insert_interface(entries[i].src, list, false); + } } -static size_t batadv_vis_cnt_prim_sec(struct hlist_head *if_list) +static void batadv_vis_data_read_entries(struct seq_file *seq, + struct hlist_head *list, + struct vis_packet *packet, + struct vis_info_entry *entries) { + int i; struct if_list_entry *entry; struct hlist_node *pos; - size_t count = 0; - hlist_for_each_entry(entry, pos, if_list, list) { - if (entry->primary) - count += 9; - else - count += 23; - } + hlist_for_each_entry(entry, pos, list, list) { + seq_printf(seq, "%pM,", entry->addr); + + for (i = 0; i < packet->entries; i++) + batadv_vis_data_read_entry(seq, &entries[i], + entry->addr, entry->primary); - return count; + /* add primary/secondary records */ + if (batadv_compare_eth(entry->addr, packet->vis_orig)) + batadv_vis_data_read_prim_sec(seq, list); + + seq_printf(seq, "\n"); + } } -/* read an entry */ -static ssize_t batadv_vis_data_read_entry(char *buff, - const struct vis_info_entry *entry, - const uint8_t *src, bool primary) +static void batadv_vis_seq_print_text_bucket(struct seq_file *seq, + const struct hlist_head *head) { - /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ - if (primary && entry->quality == 0) - return sprintf(buff, "TT %pM, ", entry->dest); - else if (batadv_compare_eth(entry->src, src)) - return sprintf(buff, "TQ %pM %d, ", entry->dest, - entry->quality); + struct hlist_node *node; + struct vis_info *info; + struct vis_packet *packet; + uint8_t *entries_pos; + struct vis_info_entry *entries; + struct if_list_entry *entry; + struct hlist_node *pos, *n; - return 0; + HLIST_HEAD(vis_if_list); + + hlist_for_each_entry_rcu(info, node, head, hash_entry) { + packet = (struct vis_packet *)info->skb_packet->data; + entries_pos = (uint8_t *)packet + sizeof(*packet); + entries = (struct vis_info_entry *)entries_pos; + + batadv_vis_data_insert_interface(packet->vis_orig, &vis_if_list, + true); + batadv_vis_data_insert_interfaces(&vis_if_list, packet, + entries); + batadv_vis_data_read_entries(seq, &vis_if_list, packet, + entries); + + hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { + hlist_del(&entry->list); + kfree(entry); + } + } } int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) { struct hard_iface *primary_if; - struct hlist_node *node; struct hlist_head *head; - struct vis_info *info; - struct vis_packet *packet; - struct vis_info_entry *entries; struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); struct hashtable_t *hash = bat_priv->vis_hash; - HLIST_HEAD(vis_if_list); - struct if_list_entry *entry; - struct hlist_node *pos, *n; uint32_t i; - int j, ret = 0; + int ret = 0; int vis_server = atomic_read(&bat_priv->vis_mode); - size_t buff_pos, buf_size; - char *buff; primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) @@ -214,120 +259,13 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (vis_server == VIS_TYPE_CLIENT_UPDATE) goto out; - buf_size = 1; - /* Estimate length */ spin_lock_bh(&bat_priv->vis_hash_lock); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; - - rcu_read_lock(); - hlist_for_each_entry_rcu(info, node, head, hash_entry) { - packet = (struct vis_packet *)info->skb_packet->data; - entries = (struct vis_info_entry *) - ((char *)packet + sizeof(*packet)); - - batadv_vis_data_insert_interface(packet->vis_orig, - &vis_if_list, true); - - for (j = 0; j < packet->entries; j++) { - if (entries[j].quality == 0) - continue; - if (batadv_compare_eth(entries[j].src, - packet->vis_orig)) - continue; - batadv_vis_data_insert_interface(entries[j].src, - &vis_if_list, - false); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - buf_size += 18 + 26 * packet->entries; - - /* add primary/secondary records */ - if (batadv_compare_eth(entry->addr, - packet->vis_orig)) - buf_size += - batadv_vis_cnt_prim_sec(&vis_if_list); - - buf_size += 1; - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, - list) { - hlist_del(&entry->list); - kfree(entry); - } - } - rcu_read_unlock(); + batadv_vis_seq_print_text_bucket(seq, head); } - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) { - spin_unlock_bh(&bat_priv->vis_hash_lock); - ret = -ENOMEM; - goto out; - } - buff[0] = '\0'; - buff_pos = 0; - - for (i = 0; i < hash->size; i++) { - head = &hash->table[i]; - - rcu_read_lock(); - hlist_for_each_entry_rcu(info, node, head, hash_entry) { - packet = (struct vis_packet *)info->skb_packet->data; - entries = (struct vis_info_entry *) - ((char *)packet + sizeof(*packet)); - - batadv_vis_data_insert_interface(packet->vis_orig, - &vis_if_list, true); - - for (j = 0; j < packet->entries; j++) { - if (entries[j].quality == 0) - continue; - if (batadv_compare_eth(entries[j].src, - packet->vis_orig)) - continue; - batadv_vis_data_insert_interface(entries[j].src, - &vis_if_list, - false); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - buff_pos += sprintf(buff + buff_pos, "%pM,", - entry->addr); - - for (j = 0; j < packet->entries; j++) - buff_pos += batadv_vis_data_read_entry( - buff + buff_pos, - &entries[j], - entry->addr, - entry->primary); - - /* add primary/secondary records */ - if (batadv_compare_eth(entry->addr, - packet->vis_orig)) - buff_pos += - batadv_vis_prim_sec(buff + buff_pos, - &vis_if_list); - - buff_pos += sprintf(buff + buff_pos, "\n"); - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, - list) { - hlist_del(&entry->list); - kfree(entry); - } - } - rcu_read_unlock(); - } - spin_unlock_bh(&bat_priv->vis_hash_lock); - seq_printf(seq, "%s", buff); - kfree(buff); - out: if (primary_if) batadv_hardif_free_ref(primary_if); -- GitLab From 3b643de541d4051f236f1e422f3329cccb7bd9c5 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Fri, 25 May 2012 00:00:42 +0200 Subject: [PATCH 3135/6849] batman-adv: clear ADD+DEL (and viceversa) events in the same orig-interval During an OGM-interval (time between two different OGM sendings) the same client could roam away and then roam back to us. In this case the node would add two events to the events list (that is going to be sent appended to the next OGM). A DEL one and an ADD one. Obviously they will only increase the overhead (either in the air and on the receiver side) and eventually trigger wrong states/events without producing any real effect. For this reason we can safely delete any ADD event with its related DEL one. Signed-off-by: Antonio Quartulli Signed-off-by: Sven Eckelmann --- net/batman-adv/translation-table.c | 40 +++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 074936f2d30a..d82766bfd264 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -157,7 +157,9 @@ batadv_tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) static void batadv_tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr, uint8_t flags) { - struct tt_change_node *tt_change_node; + struct tt_change_node *tt_change_node, *entry, *safe; + bool event_removed = false; + bool del_op_requested, del_op_entry; tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC); @@ -167,13 +169,45 @@ static void batadv_tt_local_event(struct bat_priv *bat_priv, tt_change_node->change.flags = flags; memcpy(tt_change_node->change.addr, addr, ETH_ALEN); + del_op_requested = flags & TT_CLIENT_DEL; + + /* check for ADD+DEL or DEL+ADD events */ spin_lock_bh(&bat_priv->tt_changes_list_lock); + list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, + list) { + if (!batadv_compare_eth(entry->change.addr, addr)) + continue; + + /* DEL+ADD in the same orig interval have no effect and can be + * removed to avoid silly behaviour on the receiver side. The + * other way around (ADD+DEL) can happen in case of roaming of + * a client still in the NEW state. Roaming of NEW clients is + * now possible due to automatically recognition of "temporary" + * clients + */ + del_op_entry = entry->change.flags & TT_CLIENT_DEL; + if (!del_op_requested && del_op_entry) + goto del; + if (del_op_requested && !del_op_entry) + goto del; + continue; +del: + list_del(&entry->list); + kfree(entry); + event_removed = true; + goto unlock; + } + /* track the change in the OGMinterval list */ list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list); - atomic_inc(&bat_priv->tt_local_changes); + +unlock: spin_unlock_bh(&bat_priv->tt_changes_list_lock); - atomic_set(&bat_priv->tt_ogm_append_cnt, 0); + if (event_removed) + atomic_dec(&bat_priv->tt_local_changes); + else + atomic_inc(&bat_priv->tt_local_changes); } int batadv_tt_len(int changes_num) -- GitLab From d4f4469255359c97564b15b5ef04253fd3ec08f1 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Fri, 25 May 2012 00:00:54 +0200 Subject: [PATCH 3136/6849] batman-adv: beautify tt_global_add() argument list Instead of adding a new bool argument each time it is needed, it is better (and simpler) to pass an 8bit flag argument which contains all the needed flags Signed-off-by: Antonio Quartulli Signed-off-by: Sven Eckelmann --- net/batman-adv/routing.c | 4 ++-- net/batman-adv/translation-table.c | 24 +++++++++--------------- net/batman-adv/translation-table.h | 4 ++-- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 1b8f67744e23..864692add808 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -699,8 +699,8 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if) roam_adv_packet->src, roam_adv_packet->client); batadv_tt_global_add(bat_priv, orig_node, roam_adv_packet->client, - atomic_read(&orig_node->last_ttvn) + 1, true, - false); + TT_CLIENT_ROAM, + atomic_read(&orig_node->last_ttvn) + 1); /* Roaming phase starts: I have new information but the ttvn has not * been incremented yet. This flag will make me check all the incoming diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index d82766bfd264..3ca2e48d669e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -657,8 +657,8 @@ batadv_tt_global_add_orig_entry(struct tt_global_entry *tt_global_entry, /* caller must hold orig_node refcount */ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *tt_addr, uint8_t ttvn, - bool roaming, bool wifi) + const unsigned char *tt_addr, uint8_t flags, + uint8_t ttvn) { struct tt_global_entry *tt_global_entry = NULL; int ret = 0; @@ -668,15 +668,14 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); if (!tt_global_entry) { - tt_global_entry = kzalloc(sizeof(*tt_global_entry), - GFP_ATOMIC); + tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC); if (!tt_global_entry) goto out; common = &tt_global_entry->common; memcpy(common->addr, tt_addr, ETH_ALEN); - common->flags = NO_FLAGS; + common->flags = flags; tt_global_entry->roam_at = 0; atomic_set(&common->refcount, 2); @@ -718,9 +717,6 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, orig_node, ttvn); } - if (wifi) - tt_global_entry->common.flags |= TT_CLIENT_WIFI; - batadv_dbg(DBG_TT, bat_priv, "Creating new global tt entry: %pM (via %pM)\n", tt_global_entry->common.addr, orig_node->orig); @@ -728,7 +724,7 @@ int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, out_remove: /* remove address from local hash if present */ batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr, - "global tt received", roaming); + "global tt received", flags & TT_CLIENT_ROAM); ret = 1; out: if (tt_global_entry) @@ -1755,7 +1751,6 @@ static void _batadv_tt_update_changes(struct bat_priv *bat_priv, uint16_t tt_num_changes, uint8_t ttvn) { int i; - int is_wifi; int roams; for (i = 0; i < tt_num_changes; i++) { @@ -1763,13 +1758,12 @@ static void _batadv_tt_update_changes(struct bat_priv *bat_priv, roams = (tt_change + i)->flags & TT_CLIENT_ROAM; batadv_tt_global_del(bat_priv, orig_node, (tt_change + i)->addr, - "tt removed by changes", - roams); + "tt removed by changes", + roams); } else { - is_wifi = (tt_change + i)->flags & TT_CLIENT_WIFI; if (!batadv_tt_global_add(bat_priv, orig_node, - (tt_change + i)->addr, ttvn, - false, is_wifi)) + (tt_change + i)->addr, + (tt_change + i)->flags, ttvn)) /* In case of problem while storing a * global_entry, we stop the updating * procedure without committing the diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index 7edc9dff8ba1..46b60bd822fe 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -32,8 +32,8 @@ void batadv_tt_global_add_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const unsigned char *tt_buff, int tt_buff_len); int batadv_tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, - const unsigned char *addr, uint8_t ttvn, bool roaming, - bool wifi); + const unsigned char *addr, uint8_t flags, + uint8_t ttvn); int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); void batadv_tt_global_del_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, -- GitLab From 347c80f0fb9adbd5f3756bd8a612664492768808 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:07 +0200 Subject: [PATCH 3137/6849] batman-adv: Prefix local defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 26 ++++---- net/batman-adv/bat_sysfs.c | 114 ++++++++++++++++---------------- net/batman-adv/gateway_client.c | 12 ++-- net/batman-adv/vis.c | 16 +++-- 4 files changed, 87 insertions(+), 81 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index ca6aee4bf941..ce84a616fddf 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -35,14 +35,14 @@ static struct dentry *batadv_debugfs; #ifdef CONFIG_BATMAN_ADV_DEBUG -#define LOG_BUFF_MASK (batadv_log_buff_len - 1) -#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK]) +#define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1) +#define BATADV_LOG_BUFF(idx) (debug_log->log_buff[(idx) & BATADV_LOG_BUFF_MASK]) static int batadv_log_buff_len = LOG_BUF_LEN; static void batadv_emit_log_char(struct debug_log *debug_log, char c) { - LOG_BUFF(debug_log->log_end) = c; + BATADV_LOG_BUFF(debug_log->log_end) = c; debug_log->log_end++; if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len) @@ -133,7 +133,7 @@ static ssize_t batadv_log_read(struct file *file, char __user *buf, while ((!error) && (i < count) && (debug_log->log_start != debug_log->log_end)) { - c = LOG_BUFF(debug_log->log_start); + c = BATADV_LOG_BUFF(debug_log->log_start); debug_log->log_start++; @@ -270,7 +270,7 @@ struct bat_debuginfo { const struct file_operations fops; }; -#define BAT_DEBUGINFO(_name, _mode, _open) \ +#define BATADV_DEBUGINFO(_name, _mode, _open) \ struct bat_debuginfo batadv_debuginfo_##_name = { \ .attr = { .name = __stringify(_name), \ .mode = _mode, }, \ @@ -282,15 +282,17 @@ struct bat_debuginfo batadv_debuginfo_##_name = { \ } \ }; -static BAT_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open); -static BAT_DEBUGINFO(originators, S_IRUGO, batadv_originators_open); -static BAT_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open); -static BAT_DEBUGINFO(transtable_global, S_IRUGO, batadv_transtable_global_open); +static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open); +static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open); +static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open); +static BATADV_DEBUGINFO(transtable_global, S_IRUGO, + batadv_transtable_global_open); #ifdef CONFIG_BATMAN_ADV_BLA -static BAT_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); +static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); #endif -static BAT_DEBUGINFO(transtable_local, S_IRUGO, batadv_transtable_local_open); -static BAT_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); +static BATADV_DEBUGINFO(transtable_local, S_IRUGO, + batadv_transtable_local_open); +static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); static struct bat_debuginfo *batadv_mesh_debuginfos[] = { &batadv_debuginfo_originators, diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 54429a222bd6..3862fe18a033 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -38,9 +38,9 @@ static struct bat_priv *batadv_kobj_to_batpriv(struct kobject *obj) return netdev_priv(net_dev); } -#define UEV_TYPE_VAR "BATTYPE=" -#define UEV_ACTION_VAR "BATACTION=" -#define UEV_DATA_VAR "BATDATA=" +#define BATADV_UEV_TYPE_VAR "BATTYPE=" +#define BATADV_UEV_ACTION_VAR "BATACTION=" +#define BATADV_UEV_DATA_VAR "BATDATA=" static char *batadv_uev_action_str[] = { "add", @@ -53,15 +53,15 @@ static char *batadv_uev_type_str[] = { }; /* Use this, if you have customized show and store functions */ -#define BAT_ATTR(_name, _mode, _show, _store) \ -struct bat_attribute batadv_attr_##_name = { \ - .attr = {.name = __stringify(_name), \ - .mode = _mode }, \ - .show = _show, \ - .store = _store, \ +#define BATADV_ATTR(_name, _mode, _show, _store) \ +struct bat_attribute batadv_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store = _store, \ }; -#define BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ +#define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \ ssize_t batadv_store_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff, \ size_t count) \ @@ -72,7 +72,7 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \ &bat_priv->_name, net_dev); \ } -#define BAT_ATTR_SIF_SHOW_BOOL(_name) \ +#define BATADV_ATTR_SIF_SHOW_BOOL(_name) \ ssize_t batadv_show_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff) \ { \ @@ -85,14 +85,14 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ /* Use this, if you are going to turn a [name] in the soft-interface * (bat_priv) on or off */ -#define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \ - static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ - static BAT_ATTR_SIF_SHOW_BOOL(_name) \ - static BAT_ATTR(_name, _mode, batadv_show_##_name, \ - batadv_store_##_name) +#define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func) \ + static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \ + static BATADV_ATTR_SIF_SHOW_BOOL(_name) \ + static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) -#define BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ +#define BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ ssize_t batadv_store_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff, \ size_t count) \ @@ -104,7 +104,7 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \ &bat_priv->_name, net_dev); \ } -#define BAT_ATTR_SIF_SHOW_UINT(_name) \ +#define BATADV_ATTR_SIF_SHOW_UINT(_name) \ ssize_t batadv_show_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff) \ { \ @@ -115,14 +115,14 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ /* Use this, if you are going to set [name] in the soft-interface * (bat_priv) to an unsigned integer value */ -#define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ - static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ - static BAT_ATTR_SIF_SHOW_UINT(_name) \ - static BAT_ATTR(_name, _mode, batadv_show_##_name, \ - batadv_store_##_name) +#define BATADV_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ + static BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func)\ + static BATADV_ATTR_SIF_SHOW_UINT(_name) \ + static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) -#define BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ +#define BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ ssize_t batadv_store_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff, \ size_t count) \ @@ -143,7 +143,7 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \ return length; \ } -#define BAT_ATTR_HIF_SHOW_UINT(_name) \ +#define BATADV_ATTR_HIF_SHOW_UINT(_name) \ ssize_t batadv_show_##_name(struct kobject *kobj, \ struct attribute *attr, char *buff) \ { \ @@ -164,11 +164,11 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ /* Use this, if you are going to set [name] in hard_iface to an * unsigned integer value */ -#define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ - static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ - static BAT_ATTR_HIF_SHOW_UINT(_name) \ - static BAT_ATTR(_name, _mode, batadv_show_##_name, \ - batadv_store_##_name) +#define BATADV_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ + static BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func)\ + static BATADV_ATTR_HIF_SHOW_UINT(_name) \ + static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) static int batadv_store_bool_attr(char *buff, size_t count, @@ -454,26 +454,27 @@ static ssize_t batadv_store_gw_bwidth(struct kobject *kobj, return batadv_gw_bandwidth_set(net_dev, buff, count); } -BAT_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); -BAT_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); +BATADV_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); +BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); #ifdef CONFIG_BATMAN_ADV_BLA -BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); +BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); #endif -BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); -BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); -static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, - batadv_store_vis_mode); -static BAT_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); -static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, - batadv_store_gw_mode); -BAT_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); -BAT_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); -BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, - batadv_post_gw_deselect); -static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, - batadv_store_gw_bwidth); +BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); +BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); +static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, + batadv_store_vis_mode); +static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); +static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, + batadv_store_gw_mode); +BATADV_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, + NULL); +BATADV_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); +BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, + batadv_post_gw_deselect); +static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, + batadv_store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG -BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, DBG_ALL, NULL); +BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, DBG_ALL, NULL); #endif static struct bat_attribute *batadv_mesh_attrs[] = { @@ -656,9 +657,9 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj, return length; } -static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR, - batadv_show_mesh_iface, batadv_store_mesh_iface); -static BAT_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL); +static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface, + batadv_store_mesh_iface); +static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL); static struct bat_attribute *batadv_batman_attrs[] = { &batadv_attr_mesh_iface, @@ -720,31 +721,32 @@ int batadv_throw_uevent(struct bat_priv *bat_priv, enum uev_type type, bat_kobj = &primary_if->soft_iface->dev.kobj; - uevent_env[0] = kmalloc(strlen(UEV_TYPE_VAR) + + uevent_env[0] = kmalloc(strlen(BATADV_UEV_TYPE_VAR) + strlen(batadv_uev_type_str[type]) + 1, GFP_ATOMIC); if (!uevent_env[0]) goto out; - sprintf(uevent_env[0], "%s%s", UEV_TYPE_VAR, batadv_uev_type_str[type]); + sprintf(uevent_env[0], "%s%s", BATADV_UEV_TYPE_VAR, + batadv_uev_type_str[type]); - uevent_env[1] = kmalloc(strlen(UEV_ACTION_VAR) + + uevent_env[1] = kmalloc(strlen(BATADV_UEV_ACTION_VAR) + strlen(batadv_uev_action_str[action]) + 1, GFP_ATOMIC); if (!uevent_env[1]) goto out; - sprintf(uevent_env[1], "%s%s", UEV_ACTION_VAR, + sprintf(uevent_env[1], "%s%s", BATADV_UEV_ACTION_VAR, batadv_uev_action_str[action]); /* If the event is DEL, ignore the data field */ if (action != UEV_DEL) { - uevent_env[2] = kmalloc(strlen(UEV_DATA_VAR) + + uevent_env[2] = kmalloc(strlen(BATADV_UEV_DATA_VAR) + strlen(data) + 1, GFP_ATOMIC); if (!uevent_env[2]) goto out; - sprintf(uevent_env[2], "%s%s", UEV_DATA_VAR, data); + sprintf(uevent_env[2], "%s%s", BATADV_UEV_DATA_VAR, data); } ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env); diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index f43eb57b8a69..3916e90ff6ed 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -33,8 +33,8 @@ /* This is the offset of the options field in a dhcp packet starting at * the beginning of the dhcp header */ -#define DHCP_OPTIONS_OFFSET 240 -#define DHCP_REQUEST 3 +#define BATADV_DHCP_OPTIONS_OFFSET 240 +#define BATADV_DHCP_REQUEST 3 static void batadv_gw_node_free_ref(struct gw_node *gw_node) { @@ -521,11 +521,11 @@ static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) pkt_len = skb_headlen(skb); - if (pkt_len < header_len + DHCP_OPTIONS_OFFSET + 1) + if (pkt_len < header_len + BATADV_DHCP_OPTIONS_OFFSET + 1) goto out; - p = skb->data + header_len + DHCP_OPTIONS_OFFSET; - pkt_len -= header_len + DHCP_OPTIONS_OFFSET + 1; + p = skb->data + header_len + BATADV_DHCP_OPTIONS_OFFSET; + pkt_len -= header_len + BATADV_DHCP_OPTIONS_OFFSET + 1; /* Access the dhcp option lists. Each entry is made up by: * - octet 1: option type @@ -543,7 +543,7 @@ static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) p += 2; /* check if the message type is what we need */ - if (*p == DHCP_REQUEST) + if (*p == BATADV_DHCP_REQUEST) ret = true; break; } else if (*p == 0) { diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 3095c41a67ad..7dc750670c34 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -26,7 +26,7 @@ #include "hash.h" #include "originator.h" -#define MAX_VIS_PACKET_SIZE 1000 +#define BATADV_MAX_VIS_PACKET_SIZE 1000 static void batadv_start_vis_timer(struct bat_priv *bat_priv); @@ -544,10 +544,12 @@ static int batadv_find_best_vis_server(struct bat_priv *bat_priv, static bool batadv_vis_packet_full(const struct vis_info *info) { const struct vis_packet *packet; + size_t num_items; + packet = (struct vis_packet *)info->skb_packet->data; + num_items = BATADV_MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry); - if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry) - < packet->entries + 1) + if (num_items < packet->entries + 1) return true; return false; } @@ -838,6 +840,7 @@ int batadv_vis_init(struct bat_priv *bat_priv) { struct vis_packet *packet; int hash_added; + unsigned int len; if (bat_priv->vis_hash) return 0; @@ -850,13 +853,12 @@ int batadv_vis_init(struct bat_priv *bat_priv) goto err; } - bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC); + bat_priv->my_vis_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); if (!bat_priv->my_vis_info) goto err; - bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) + - MAX_VIS_PACKET_SIZE + - ETH_HLEN); + len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN; + bat_priv->my_vis_info->skb_packet = dev_alloc_skb(len); if (!bat_priv->my_vis_info->skb_packet) goto free_info; -- GitLab From 54590e4d4b369c9fc0dcbb3c7f39eb90fbddcbe2 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:08 +0200 Subject: [PATCH 3138/6849] batman-adv: Prefix debugfs defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 2 +- net/batman-adv/bat_debugfs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index ce84a616fddf..f9af65ea42fc 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -311,7 +311,7 @@ void batadv_debugfs_init(void) struct bat_debuginfo *bat_debug; struct dentry *file; - batadv_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); + batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL); if (batadv_debugfs == ERR_PTR(-ENODEV)) batadv_debugfs = NULL; diff --git a/net/batman-adv/bat_debugfs.h b/net/batman-adv/bat_debugfs.h index eb0d576b4f9d..3319e1f21f55 100644 --- a/net/batman-adv/bat_debugfs.h +++ b/net/batman-adv/bat_debugfs.h @@ -20,7 +20,7 @@ #ifndef _NET_BATMAN_ADV_DEBUGFS_H_ #define _NET_BATMAN_ADV_DEBUGFS_H_ -#define DEBUGFS_BAT_SUBDIR "batman_adv" +#define BATADV_DEBUGFS_SUBDIR "batman_adv" void batadv_debugfs_init(void); void batadv_debugfs_destroy(void); -- GitLab From 036cbfeb6e0595d7b85f14dd66e38adfa408e2ef Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:09 +0200 Subject: [PATCH 3139/6849] batman-adv: Prefix sysfs defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 14 +++++++------- net/batman-adv/bat_sysfs.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 3862fe18a033..725e7d74f567 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -505,11 +505,11 @@ int batadv_sysfs_add_meshif(struct net_device *dev) struct bat_attribute **bat_attr; int err; - bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, + bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR, batif_kobject); if (!bat_priv->mesh_obj) { batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, - SYSFS_IF_MESH_SUBDIR); + BATADV_SYSFS_IF_MESH_SUBDIR); goto out; } @@ -518,7 +518,7 @@ int batadv_sysfs_add_meshif(struct net_device *dev) &((*bat_attr)->attr)); if (err) { batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_MESH_SUBDIR, + dev->name, BATADV_SYSFS_IF_MESH_SUBDIR, ((*bat_attr)->attr).name); goto rem_attr; } @@ -673,12 +673,12 @@ int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) struct bat_attribute **bat_attr; int err; - *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, - hardif_kobject); + *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR, + hardif_kobject); if (!*hardif_obj) { batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, - SYSFS_IF_BAT_SUBDIR); + BATADV_SYSFS_IF_BAT_SUBDIR); goto out; } @@ -686,7 +686,7 @@ int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); if (err) { batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_BAT_SUBDIR, + dev->name, BATADV_SYSFS_IF_BAT_SUBDIR, ((*bat_attr)->attr).name); goto rem_attr; } diff --git a/net/batman-adv/bat_sysfs.h b/net/batman-adv/bat_sysfs.h index 367227707d52..23a8390851a6 100644 --- a/net/batman-adv/bat_sysfs.h +++ b/net/batman-adv/bat_sysfs.h @@ -20,8 +20,8 @@ #ifndef _NET_BATMAN_ADV_SYSFS_H_ #define _NET_BATMAN_ADV_SYSFS_H_ -#define SYSFS_IF_MESH_SUBDIR "mesh" -#define SYSFS_IF_BAT_SUBDIR "batman_adv" +#define BATADV_SYSFS_IF_MESH_SUBDIR "mesh" +#define BATADV_SYSFS_IF_BAT_SUBDIR "batman_adv" struct bat_attribute { struct attribute attr; -- GitLab From 3964f7285eba48b971b11dc51ba0a6e41cb995b3 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:10 +0200 Subject: [PATCH 3140/6849] batman-adv: Prefix bridge_loop_avoidance defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bridge_loop_avoidance.c | 4 ++-- net/batman-adv/bridge_loop_avoidance.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 0592d2bcb9b5..42b8a2079250 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -237,7 +237,7 @@ static void batadv_bla_del_backbone_claims(struct backbone_gw *backbone_gw) } /* all claims gone, intialize CRC */ - backbone_gw->crc = BLA_CRC_INIT; + backbone_gw->crc = BATADV_BLA_CRC_INIT; } /* @bat_priv: the bat priv with all the soft interface information @@ -375,7 +375,7 @@ static struct backbone_gw *batadv_bla_get_backbone_gw(struct bat_priv *bat_priv, entry->vid = vid; entry->lasttime = jiffies; - entry->crc = BLA_CRC_INIT; + entry->crc = BATADV_BLA_CRC_INIT; entry->bat_priv = bat_priv; atomic_set(&entry->request_sent, 0); memcpy(entry->orig, orig, ETH_ALEN); diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 9818b1e4c59e..58563f0cf61d 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h @@ -36,7 +36,7 @@ void batadv_bla_update_orig_address(struct bat_priv *bat_priv, int batadv_bla_init(struct bat_priv *bat_priv); void batadv_bla_free(struct bat_priv *bat_priv); -#define BLA_CRC_INIT 0 +#define BATADV_BLA_CRC_INIT 0 #else /* ifdef CONFIG_BATMAN_ADV_BLA */ static inline int batadv_bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, -- GitLab From 97ea4ba1f9a20d6e1921ef4d61e2248e82b429fb Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:11 +0200 Subject: [PATCH 3141/6849] batman-adv: Prefix gateway defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_sysfs.c | 26 +++++++++++++++----------- net/batman-adv/gateway_common.h | 6 +++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 725e7d74f567..a6c27f0621af 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -361,13 +361,16 @@ static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr, switch (atomic_read(&bat_priv->gw_mode)) { case GW_MODE_CLIENT: - bytes_written = sprintf(buff, "%s\n", GW_MODE_CLIENT_NAME); + bytes_written = sprintf(buff, "%s\n", + BATADV_GW_MODE_CLIENT_NAME); break; case GW_MODE_SERVER: - bytes_written = sprintf(buff, "%s\n", GW_MODE_SERVER_NAME); + bytes_written = sprintf(buff, "%s\n", + BATADV_GW_MODE_SERVER_NAME); break; default: - bytes_written = sprintf(buff, "%s\n", GW_MODE_OFF_NAME); + bytes_written = sprintf(buff, "%s\n", + BATADV_GW_MODE_OFF_NAME); break; } @@ -386,15 +389,16 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, if (buff[count - 1] == '\n') buff[count - 1] = '\0'; - if (strncmp(buff, GW_MODE_OFF_NAME, strlen(GW_MODE_OFF_NAME)) == 0) + if (strncmp(buff, BATADV_GW_MODE_OFF_NAME, + strlen(BATADV_GW_MODE_OFF_NAME)) == 0) gw_mode_tmp = GW_MODE_OFF; - if (strncmp(buff, GW_MODE_CLIENT_NAME, - strlen(GW_MODE_CLIENT_NAME)) == 0) + if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME, + strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0) gw_mode_tmp = GW_MODE_CLIENT; - if (strncmp(buff, GW_MODE_SERVER_NAME, - strlen(GW_MODE_SERVER_NAME)) == 0) + if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME, + strlen(BATADV_GW_MODE_SERVER_NAME)) == 0) gw_mode_tmp = GW_MODE_SERVER; if (gw_mode_tmp < 0) { @@ -409,13 +413,13 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, switch (atomic_read(&bat_priv->gw_mode)) { case GW_MODE_CLIENT: - curr_gw_mode_str = GW_MODE_CLIENT_NAME; + curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME; break; case GW_MODE_SERVER: - curr_gw_mode_str = GW_MODE_SERVER_NAME; + curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME; break; default: - curr_gw_mode_str = GW_MODE_OFF_NAME; + curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME; break; } diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h index 6f8a4d0cbbb6..31bbc3c070a6 100644 --- a/net/batman-adv/gateway_common.h +++ b/net/batman-adv/gateway_common.h @@ -26,9 +26,9 @@ enum gw_modes { GW_MODE_SERVER, }; -#define GW_MODE_OFF_NAME "off" -#define GW_MODE_CLIENT_NAME "client" -#define GW_MODE_SERVER_NAME "server" +#define BATADV_GW_MODE_OFF_NAME "off" +#define BATADV_GW_MODE_CLIENT_NAME "client" +#define BATADV_GW_MODE_SERVER_NAME "server" void batadv_gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, -- GitLab From 64346643e86d93805fcb8f722fc4817110be99d8 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:12 +0200 Subject: [PATCH 3142/6849] batman-adv: Prefix icmp_socket defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/icmp_socket.c | 2 +- net/batman-adv/icmp_socket.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index b285c31bfa9e..4f45ca72fefc 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -282,7 +282,7 @@ int batadv_socket_setup(struct bat_priv *bat_priv) if (!bat_priv->debug_dir) goto err; - d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, + d = debugfs_create_file(BATADV_ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, bat_priv->debug_dir, bat_priv, &batadv_fops); if (!d) goto err; diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h index a62ab80df9bd..f88f9f0fe7a7 100644 --- a/net/batman-adv/icmp_socket.h +++ b/net/batman-adv/icmp_socket.h @@ -20,7 +20,7 @@ #ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_ #define _NET_BATMAN_ADV_ICMP_SOCKET_H_ -#define ICMP_SOCKET "socket" +#define BATADV_ICMP_SOCKET "socket" void batadv_socket_init(void); int batadv_socket_setup(struct bat_priv *bat_priv); -- GitLab From 7e071c79a6964130d1df4dc5ca5a6f3638680fce Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:13 +0200 Subject: [PATCH 3143/6849] batman-adv: Prefix packet defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_iv_ogm.c | 20 ++++++++++---------- net/batman-adv/hard-interface.c | 3 ++- net/batman-adv/icmp_socket.c | 4 ++-- net/batman-adv/main.c | 4 ++-- net/batman-adv/packet.h | 12 ++++++------ net/batman-adv/routing.c | 4 ++-- net/batman-adv/send.c | 4 ++-- net/batman-adv/soft-interface.c | 12 +++++++----- net/batman-adv/translation-table.c | 8 ++++---- net/batman-adv/unicast.c | 4 ++-- net/batman-adv/vis.c | 2 +- 11 files changed, 40 insertions(+), 37 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index ffe9d1d057c1..245bb2d7647c 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -64,7 +64,7 @@ static int batadv_iv_ogm_iface_enable(struct hard_iface *hard_iface) get_random_bytes(&random_seqno, sizeof(random_seqno)); atomic_set(&hard_iface->seqno, random_seqno); - hard_iface->packet_len = BATMAN_OGM_HLEN; + hard_iface->packet_len = BATADV_OGM_HLEN; hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); if (!hard_iface->packet_buff) @@ -72,7 +72,7 @@ static int batadv_iv_ogm_iface_enable(struct hard_iface *hard_iface) batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; batman_ogm_packet->header.packet_type = BAT_IV_OGM; - batman_ogm_packet->header.version = COMPAT_VERSION; + batman_ogm_packet->header.version = BATADV_COMPAT_VERSION; batman_ogm_packet->header.ttl = 2; batman_ogm_packet->flags = NO_FLAGS; batman_ogm_packet->tq = TQ_MAX_VALUE; @@ -139,7 +139,7 @@ static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, { int next_buff_pos = 0; - next_buff_pos += buff_pos + BATMAN_OGM_HLEN; + next_buff_pos += buff_pos + BATADV_OGM_HLEN; next_buff_pos += batadv_tt_len(tt_num_changes); return (next_buff_pos <= packet_len) && @@ -191,7 +191,7 @@ static void batadv_iv_ogm_send_to_if(struct forw_packet *forw_packet, batman_ogm_packet->ttvn, hard_iface->net_dev->name, hard_iface->net_dev->dev_addr); - buff_pos += BATMAN_OGM_HLEN; + buff_pos += BATADV_OGM_HLEN; buff_pos += batadv_tt_len(batman_ogm_packet->tt_num_changes); packet_num++; batman_ogm_packet = (struct batman_ogm_packet *) @@ -561,7 +561,7 @@ static void batadv_iv_ogm_forward(struct orig_node *orig_node, batman_ogm_packet->flags &= ~DIRECTLINK; batadv_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, - BATMAN_OGM_HLEN + batadv_tt_len(tt_num_changes), + BATADV_OGM_HLEN + batadv_tt_len(tt_num_changes), if_incoming, 0, batadv_iv_ogm_fwd_send_time()); } @@ -579,7 +579,7 @@ static void batadv_iv_ogm_schedule(struct hard_iface *hard_iface) tt_num_changes = batadv_tt_append_diff(bat_priv, &hard_iface->packet_buff, &hard_iface->packet_len, - BATMAN_OGM_HLEN); + BATADV_OGM_HLEN); batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; @@ -1025,7 +1025,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, } rcu_read_unlock(); - if (batman_ogm_packet->header.version != COMPAT_VERSION) { + if (batman_ogm_packet->header.version != BATADV_COMPAT_VERSION) { batadv_dbg(DBG_BATMAN, bat_priv, "Drop packet: incompatible batman version (%i)\n", batman_ogm_packet->header.version); @@ -1227,7 +1227,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, unsigned char *tt_buff, *packet_buff; bool ret; - ret = batadv_check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); + ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN); if (!ret) return NET_RX_DROP; @@ -1248,12 +1248,12 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, /* unpack the aggregated packets and process them one by one */ do { - tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN; + tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN; batadv_iv_ogm_process(ethhdr, batman_ogm_packet, tt_buff, if_incoming); - buff_pos += BATMAN_OGM_HLEN; + buff_pos += BATADV_OGM_HLEN; buff_pos += batadv_tt_len(batman_ogm_packet->tt_num_changes); batman_ogm_packet = (struct batman_ogm_packet *) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index c1ba6e28a96c..340108411c4d 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -263,6 +263,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, { struct bat_priv *bat_priv; struct net_device *soft_iface; + __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); int ret; if (hard_iface->if_status != IF_NOT_IN_USE) @@ -309,7 +310,7 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, hard_iface->if_status = IF_INACTIVE; batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); - hard_iface->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); + hard_iface->batman_adv_ptype.type = ethertype; hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; hard_iface->batman_adv_ptype.dev = hard_iface->net_dev; dev_add_pack(&hard_iface->batman_adv_ptype); diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 4f45ca72fefc..f2f578b1d9f0 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -203,9 +203,9 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, icmp_packet->uid = socket_client->index; - if (icmp_packet->header.version != COMPAT_VERSION) { + if (icmp_packet->header.version != BATADV_COMPAT_VERSION) { icmp_packet->msg_type = PARAMETER_PROBLEM; - icmp_packet->header.version = COMPAT_VERSION; + icmp_packet->header.version = BATADV_COMPAT_VERSION; batadv_socket_add_packet(socket_client, icmp_packet, packet_len); goto free_skb; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 9cf0b38fab8b..986be72b5144 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -72,7 +72,7 @@ static int __init batadv_init(void) register_netdevice_notifier(&batadv_hard_if_notifier); pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", - SOURCE_VERSION, COMPAT_VERSION); + SOURCE_VERSION, BATADV_COMPAT_VERSION); return 0; } @@ -238,7 +238,7 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, batman_ogm_packet = (struct batman_ogm_packet *)skb->data; - if (batman_ogm_packet->header.version != COMPAT_VERSION) { + if (batman_ogm_packet->header.version != BATADV_COMPAT_VERSION) { batadv_dbg(DBG_BATMAN, bat_priv, "Drop packet: incompatible batman version (%i)\n", batman_ogm_packet->header.version); diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index c90219cd648e..e562414c2940 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -20,7 +20,7 @@ #ifndef _NET_BATMAN_ADV_PACKET_H_ #define _NET_BATMAN_ADV_PACKET_H_ -#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ +#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ enum bat_packettype { BAT_IV_OGM = 0x01, @@ -34,7 +34,7 @@ enum bat_packettype { }; /* this file is included by batctl which needs these defines */ -#define COMPAT_VERSION 14 +#define BATADV_COMPAT_VERSION 14 enum batman_iv_flags { NOT_BEST_NEXT_HOP = 1 << 3, @@ -65,7 +65,7 @@ enum unicast_frag_flags { }; /* TT_QUERY subtypes */ -#define TT_QUERY_TYPE_MASK 0x3 +#define BATADV_TT_QUERY_TYPE_MASK 0x3 enum tt_query_packettype { TT_REQUEST = 0, @@ -126,7 +126,7 @@ struct batman_ogm_packet { __be16 tt_crc; } __packed; -#define BATMAN_OGM_HLEN sizeof(struct batman_ogm_packet) +#define BATADV_OGM_HLEN sizeof(struct batman_ogm_packet) struct icmp_packet { struct batman_header header; @@ -138,7 +138,7 @@ struct icmp_packet { uint8_t reserved; } __packed; -#define BAT_RR_LEN 16 +#define BATADV_RR_LEN 16 /* icmp_packet_rr must start with all fields from imcp_packet * as this is assumed by code that handles ICMP packets @@ -151,7 +151,7 @@ struct icmp_packet_rr { __be16 seqno; uint8_t uid; uint8_t rr_cur; - uint8_t rr[BAT_RR_LEN][ETH_ALEN]; + uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; } __packed; struct unicast_packet { diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 864692add808..c8fee749eab8 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -423,7 +423,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) /* add record route information if not full */ if ((hdr_size == sizeof(struct icmp_packet_rr)) && - (icmp_packet->rr_cur < BAT_RR_LEN)) { + (icmp_packet->rr_cur < BATADV_RR_LEN)) { memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), ethhdr->h_dest, ETH_ALEN); icmp_packet->rr_cur++; @@ -603,7 +603,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) tt_query = (struct tt_query_packet *)skb->data; - switch (tt_query->flags & TT_QUERY_TYPE_MASK) { + switch (tt_query->flags & BATADV_TT_QUERY_TYPE_MASK) { case TT_REQUEST: batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX); diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 3d725e0b1d90..72542cb01662 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -58,11 +58,11 @@ int batadv_send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, ethhdr = (struct ethhdr *)skb_mac_header(skb); memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN); memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); - ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); + ethhdr->h_proto = __constant_htons(BATADV_ETH_P_BATMAN); skb_set_network_header(skb, ETH_HLEN); skb->priority = TC_PRIO_CONTROL; - skb->protocol = __constant_htons(ETH_P_BATMAN); + skb->protocol = __constant_htons(BATADV_ETH_P_BATMAN); skb->dev = hard_iface->net_dev; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 2de1d742119f..e726419045e4 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -135,6 +135,7 @@ static int batadv_interface_tx(struct sk_buff *skb, struct hard_iface *primary_if = NULL; struct bcast_packet *bcast_packet; struct vlan_ethhdr *vhdr; + __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}; unsigned int header_len = 0; @@ -152,11 +153,11 @@ static int batadv_interface_tx(struct sk_buff *skb, vhdr = (struct vlan_ethhdr *)skb->data; vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; - if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) + if (vhdr->h_vlan_encapsulated_proto != ethertype) break; /* fall through */ - case ETH_P_BATMAN: + case BATADV_ETH_P_BATMAN: goto dropped; } @@ -208,7 +209,7 @@ static int batadv_interface_tx(struct sk_buff *skb, goto dropped; bcast_packet = (struct bcast_packet *)skb->data; - bcast_packet->header.version = COMPAT_VERSION; + bcast_packet->header.version = BATADV_COMPAT_VERSION; bcast_packet->header.ttl = TTL; /* batman packet type: broadcast */ @@ -266,6 +267,7 @@ void batadv_interface_rx(struct net_device *soft_iface, struct ethhdr *ethhdr; struct vlan_ethhdr *vhdr; short vid __maybe_unused = -1; + __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); /* check if enough space is available for pulling, and pull */ if (!pskb_may_pull(skb, hdr_size)) @@ -281,11 +283,11 @@ void batadv_interface_rx(struct net_device *soft_iface, vhdr = (struct vlan_ethhdr *)skb->data; vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; - if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) + if (vhdr->h_vlan_encapsulated_proto != ethertype) break; /* fall through */ - case ETH_P_BATMAN: + case BATADV_ETH_P_BATMAN: goto dropped; } diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 3ca2e48d669e..79cd3f76a865 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1441,7 +1441,7 @@ static int batadv_send_tt_request(struct bat_priv *bat_priv, sizeof(struct tt_query_packet)); tt_request->header.packet_type = BAT_TT_QUERY; - tt_request->header.version = COMPAT_VERSION; + tt_request->header.version = BATADV_COMPAT_VERSION; memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN); tt_request->header.ttl = TTL; @@ -1575,7 +1575,7 @@ static bool batadv_send_other_tt_response(struct bat_priv *bat_priv, } tt_response->header.packet_type = BAT_TT_QUERY; - tt_response->header.version = COMPAT_VERSION; + tt_response->header.version = BATADV_COMPAT_VERSION; tt_response->header.ttl = TTL; memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN); memcpy(tt_response->dst, tt_request->src, ETH_ALEN); @@ -1696,7 +1696,7 @@ static bool batadv_send_my_tt_response(struct bat_priv *bat_priv, } tt_response->header.packet_type = BAT_TT_QUERY; - tt_response->header.version = COMPAT_VERSION; + tt_response->header.version = BATADV_COMPAT_VERSION; tt_response->header.ttl = TTL; memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(tt_response->dst, tt_request->src, ETH_ALEN); @@ -2008,7 +2008,7 @@ static void batadv_send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, sizeof(struct roam_adv_packet)); roam_adv_packet->header.packet_type = BAT_ROAM_ADV; - roam_adv_packet->header.version = COMPAT_VERSION; + roam_adv_packet->header.version = BATADV_COMPAT_VERSION; roam_adv_packet->header.ttl = TTL; primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 472436a06d89..c8da6b0acc38 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -253,7 +253,7 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, memcpy(frag1, &tmp_uc, sizeof(tmp_uc)); frag1->header.ttl--; - frag1->header.version = COMPAT_VERSION; + frag1->header.version = BATADV_COMPAT_VERSION; frag1->header.packet_type = BAT_UNICAST_FRAG; memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN); @@ -319,7 +319,7 @@ find_router: unicast_packet = (struct unicast_packet *)skb->data; - unicast_packet->header.version = COMPAT_VERSION; + unicast_packet->header.version = BATADV_COMPAT_VERSION; /* batman packet type: unicast */ unicast_packet->header.packet_type = BAT_UNICAST; /* set unicast ttl */ diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 7dc750670c34..596eacc3dd1c 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -873,7 +873,7 @@ int batadv_vis_init(struct bat_priv *bat_priv) INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); kref_init(&bat_priv->my_vis_info->refcount); bat_priv->my_vis_info->bat_priv = bat_priv; - packet->header.version = COMPAT_VERSION; + packet->header.version = BATADV_COMPAT_VERSION; packet->header.packet_type = BAT_VIS; packet->header.ttl = TTL; packet->seqno = 0; -- GitLab From c11fdfaefa46a83a668a73dc3ae90859e99ed251 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:14 +0200 Subject: [PATCH 3144/6849] batman-adv: Prefix types defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/hard-interface.c | 11 ++++++----- net/batman-adv/soft-interface.c | 2 +- net/batman-adv/types.h | 9 ++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 340108411c4d..9b1cb23ec1f4 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -196,7 +196,8 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface) if (hard_iface->soft_iface != soft_iface) continue; - min_mtu = min_t(int, hard_iface->net_dev->mtu - BAT_HEADER_LEN, + min_mtu = min_t(int, + hard_iface->net_dev->mtu - BATADV_HEADER_LEN, min_mtu); } rcu_read_unlock(); @@ -320,18 +321,18 @@ int batadv_hardif_enable_interface(struct hard_iface *hard_iface, hard_iface->net_dev->name); if (atomic_read(&bat_priv->fragmentation) && hard_iface->net_dev->mtu < - ETH_DATA_LEN + BAT_HEADER_LEN) + ETH_DATA_LEN + BATADV_HEADER_LEN) batadv_info(hard_iface->soft_iface, "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %zi would solve the problem.\n", hard_iface->net_dev->name, hard_iface->net_dev->mtu, - ETH_DATA_LEN + BAT_HEADER_LEN); + ETH_DATA_LEN + BATADV_HEADER_LEN); if (!atomic_read(&bat_priv->fragmentation) && hard_iface->net_dev->mtu < - ETH_DATA_LEN + BAT_HEADER_LEN) + ETH_DATA_LEN + BATADV_HEADER_LEN) batadv_info(hard_iface->soft_iface, "The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %zi.\n", hard_iface->net_dev->name, hard_iface->net_dev->mtu, - ETH_DATA_LEN + BAT_HEADER_LEN); + ETH_DATA_LEN + BATADV_HEADER_LEN); if (batadv_hardif_is_iface_up(hard_iface)) batadv_hardif_activate_interface(hard_iface); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index e726419045e4..bbbc9a93d430 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -351,7 +351,7 @@ static void batadv_interface_setup(struct net_device *dev) */ dev->mtu = ETH_DATA_LEN; /* reserve more space in the skbuff for our header */ - dev->hard_header_len = BAT_HEADER_LEN; + dev->hard_header_len = BATADV_HEADER_LEN; /* generate random address */ eth_hw_addr_random(dev); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 053c5d4776ce..1d5d21ed8e8a 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -22,12 +22,11 @@ #include "packet.h" #include "bitarray.h" +#include -#define BAT_HEADER_LEN (ETH_HLEN + \ - ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ - sizeof(struct unicast_packet) : \ - sizeof(struct bcast_packet)))) - +#define BATADV_HEADER_LEN \ + (ETH_HLEN + max(sizeof(struct unicast_packet), \ + sizeof(struct bcast_packet))) struct hard_iface { struct list_head list; -- GitLab From 4d5d2db8d5a40b18e562fe2fa4ef9b1f9710ff82 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:15 +0200 Subject: [PATCH 3145/6849] batman-adv: Prefix unicast defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/originator.c | 2 +- net/batman-adv/unicast.c | 2 +- net/batman-adv/unicast.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index bf9ec39a8349..1980696a7fd7 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -370,7 +370,7 @@ static void _batadv_purge_orig(struct bat_priv *bat_priv) } if (batadv_has_timed_out(orig_node->last_frag_packet, - FRAG_TIMEOUT)) + BATADV_FRAG_TIMEOUT)) batadv_frag_list_free(&orig_node->frag_list); } spin_unlock_bh(list_lock); diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index c8da6b0acc38..809832026370 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -98,7 +98,7 @@ static int batadv_frag_create_buffer(struct list_head *head) int i; struct frag_packet_list_entry *tfp; - for (i = 0; i < FRAG_BUFFER_SIZE; i++) { + for (i = 0; i < BATADV_FRAG_BUFFER_SIZE; i++) { tfp = kmalloc(sizeof(*tfp), GFP_ATOMIC); if (!tfp) { batadv_frag_list_free(head); diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h index 9257b83534fd..936287f552ee 100644 --- a/net/batman-adv/unicast.h +++ b/net/batman-adv/unicast.h @@ -22,8 +22,8 @@ #include "packet.h" -#define FRAG_TIMEOUT 10000 /* purge frag list entries after time in ms */ -#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ +#define BATADV_FRAG_TIMEOUT 10000 /* purge frag list entries after time in ms */ +#define BATADV_FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ int batadv_frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, struct sk_buff **new_skb); -- GitLab From edbf7ff72312afcc502014ccf3c72c49fa55722a Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:16 +0200 Subject: [PATCH 3146/6849] batman-adv: Prefix vis defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/vis.c | 2 +- net/batman-adv/vis.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 596eacc3dd1c..a439ed6616ea 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -674,7 +674,7 @@ static void batadv_purge_vis_packets(struct bat_priv *bat_priv) continue; if (batadv_has_timed_out(info->first_seen, - VIS_TIMEOUT)) { + BATADV_VIS_TIMEOUT)) { hlist_del(node); batadv_send_list_del(info); kref_put(&info->refcount, batadv_free_info); diff --git a/net/batman-adv/vis.h b/net/batman-adv/vis.h index dad595870f8f..16a1a6b7e2c3 100644 --- a/net/batman-adv/vis.h +++ b/net/batman-adv/vis.h @@ -21,7 +21,7 @@ #define _NET_BATMAN_ADV_VIS_H_ /* timeout of vis packets in miliseconds */ -#define VIS_TIMEOUT 200000 +#define BATADV_VIS_TIMEOUT 200000 int batadv_vis_seq_print_text(struct seq_file *seq, void *offset); void batadv_receive_server_sync_packet(struct bat_priv *bat_priv, -- GitLab From 42d0b044b7c9e5821f1bf3e2b4ea7861417c11c2 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 3 Jun 2012 22:19:17 +0200 Subject: [PATCH 3147/6849] batman-adv: Prefix main defines with BATADV_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Martin Hundebøll Signed-off-by: Sven Eckelmann --- net/batman-adv/bat_debugfs.c | 2 +- net/batman-adv/bat_iv_ogm.c | 103 +++++++++++++++---------- net/batman-adv/bat_sysfs.c | 7 +- net/batman-adv/bitarray.c | 20 ++--- net/batman-adv/bitarray.h | 4 +- net/batman-adv/bridge_loop_avoidance.c | 20 ++--- net/batman-adv/gateway_client.c | 18 ++--- net/batman-adv/hard-interface.c | 2 +- net/batman-adv/main.c | 13 ++-- net/batman-adv/main.h | 81 +++++++++---------- net/batman-adv/originator.c | 32 ++++---- net/batman-adv/ring_buffer.c | 4 +- net/batman-adv/routing.c | 20 ++--- net/batman-adv/soft-interface.c | 10 +-- net/batman-adv/translation-table.c | 87 ++++++++++++--------- net/batman-adv/types.h | 10 +-- net/batman-adv/unicast.c | 2 +- net/batman-adv/vis.c | 11 +-- 18 files changed, 244 insertions(+), 202 deletions(-) diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index f9af65ea42fc..4dcda43d6822 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c @@ -38,7 +38,7 @@ static struct dentry *batadv_debugfs; #define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1) #define BATADV_LOG_BUFF(idx) (debug_log->log_buff[(idx) & BATADV_LOG_BUFF_MASK]) -static int batadv_log_buff_len = LOG_BUF_LEN; +static int batadv_log_buff_len = BATADV_LOG_BUF_LEN; static void batadv_emit_log_char(struct debug_log *debug_log, char c) { diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 245bb2d7647c..bbe0f123d2a5 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -74,8 +74,8 @@ static int batadv_iv_ogm_iface_enable(struct hard_iface *hard_iface) batman_ogm_packet->header.packet_type = BAT_IV_OGM; batman_ogm_packet->header.version = BATADV_COMPAT_VERSION; batman_ogm_packet->header.ttl = 2; - batman_ogm_packet->flags = NO_FLAGS; - batman_ogm_packet->tq = TQ_MAX_VALUE; + batman_ogm_packet->flags = BATADV_NO_FLAGS; + batman_ogm_packet->tq = BATADV_TQ_MAX_VALUE; batman_ogm_packet->tt_num_changes = 0; batman_ogm_packet->ttvn = 0; @@ -108,29 +108,37 @@ static void batadv_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; - batman_ogm_packet->header.ttl = TTL; + batman_ogm_packet->header.ttl = BATADV_TTL; } /* when do we schedule our own ogm to be sent */ static unsigned long batadv_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) { - return jiffies + msecs_to_jiffies( - atomic_read(&bat_priv->orig_interval) - - JITTER + (random32() % 2*JITTER)); + unsigned int msecs; + + msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER; + msecs += (random32() % 2 * BATADV_JITTER); + + return jiffies + msecs_to_jiffies(msecs); } /* when do we schedule a ogm packet to be sent */ static unsigned long batadv_iv_ogm_fwd_send_time(void) { - return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); + return jiffies + msecs_to_jiffies(random32() % (BATADV_JITTER / 2)); } /* apply hop penalty for a normal link */ static uint8_t batadv_hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) { int hop_penalty = atomic_read(&bat_priv->hop_penalty); - return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); + int new_tq; + + new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty); + new_tq /= BATADV_TQ_MAX_VALUE; + + return new_tq; } /* is there another aggregated packet here? */ @@ -143,7 +151,7 @@ static int batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, next_buff_pos += batadv_tt_len(tt_num_changes); return (next_buff_pos <= packet_len) && - (next_buff_pos <= MAX_AGGREGATION_BYTES); + (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); } /* send a batman ogm to a given interface */ @@ -290,8 +298,11 @@ batadv_iv_ogm_can_aggregate(const struct batman_ogm_packet *new_bat_ogm_packet, int aggregated_bytes = forw_packet->packet_len + packet_len; struct hard_iface *primary_if = NULL; bool res = false; + unsigned long aggregation_end_time; batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data; + aggregation_end_time = send_time; + aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS); /* we can aggregate the current packet to this aggregated packet * if: @@ -301,9 +312,8 @@ batadv_iv_ogm_can_aggregate(const struct batman_ogm_packet *new_bat_ogm_packet, * MAX_AGGREGATION_BYTES */ if (time_before(send_time, forw_packet->send_time) && - time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), - forw_packet->send_time) && - (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { + time_after_eq(aggregation_end_time, forw_packet->send_time) && + (aggregated_bytes <= BATADV_MAX_AGGREGATION_BYTES)) { /* check aggregation compatibility * -> direct link packets are broadcasted on @@ -367,6 +377,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct forw_packet *forw_packet_aggr; unsigned char *skb_buff; + unsigned int skb_size; if (!atomic_inc_not_zero(&if_incoming->refcount)) return; @@ -388,12 +399,12 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, } if ((atomic_read(&bat_priv->aggregated_ogms)) && - (packet_len < MAX_AGGREGATION_BYTES)) - forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + - ETH_HLEN); + (packet_len < BATADV_MAX_AGGREGATION_BYTES)) + skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN; else - forw_packet_aggr->skb = dev_alloc_skb(packet_len + ETH_HLEN); + skb_size = packet_len + ETH_HLEN; + forw_packet_aggr->skb = dev_alloc_skb(skb_size); if (!forw_packet_aggr->skb) { if (!own_packet) atomic_inc(&bat_priv->batman_queue_left); @@ -411,7 +422,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, forw_packet_aggr->own = own_packet; forw_packet_aggr->if_incoming = if_incoming; forw_packet_aggr->num_packets = 0; - forw_packet_aggr->direct_link_flags = NO_FLAGS; + forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS; forw_packet_aggr->send_time = send_time; /* save packet direct link flag status */ @@ -466,9 +477,11 @@ static void batadv_iv_ogm_queue_add(struct bat_priv *bat_priv, struct hlist_node *tmp_node; struct batman_ogm_packet *batman_ogm_packet; bool direct_link; + unsigned long max_aggregation_jiffies; batman_ogm_packet = (struct batman_ogm_packet *)packet_buff; direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0; + max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS); /* find position for the packet in the forward queue */ spin_lock_bh(&bat_priv->forw_bat_list_lock); @@ -498,9 +511,8 @@ static void batadv_iv_ogm_queue_add(struct bat_priv *bat_priv, * we hold it back for a while, so that it might be aggregated * later on */ - if ((!own_packet) && - (atomic_read(&bat_priv->aggregated_ogms))) - send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); + if (!own_packet && atomic_read(&bat_priv->aggregated_ogms)) + send_time += max_aggregation_jiffies; batadv_iv_ogm_aggregate_new(packet_buff, packet_len, send_time, direct_link, @@ -603,7 +615,7 @@ static void batadv_iv_ogm_schedule(struct hard_iface *hard_iface) batman_ogm_packet->gw_flags = (uint8_t)atomic_read(&bat_priv->gw_bandwidth); else - batman_ogm_packet->gw_flags = NO_FLAGS; + batman_ogm_packet->gw_flags = BATADV_NO_FLAGS; batadv_slide_own_bcast_window(hard_iface); batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, @@ -772,8 +784,10 @@ static int batadv_iv_ogm_calc_tq(struct orig_node *orig_node, struct neigh_node *neigh_node = NULL, *tmp_neigh_node; struct hlist_node *node; uint8_t total_count; - uint8_t orig_eq_count, neigh_rq_count, tq_own; - int tq_asym_penalty, ret = 0; + uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; + unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; + int tq_asym_penalty, inv_asym_penalty, ret = 0; + unsigned int combined_tq; /* find corresponding one hop neighbor */ rcu_read_lock(); @@ -824,32 +838,33 @@ static int batadv_iv_ogm_calc_tq(struct orig_node *orig_node, /* if we have too few packets (too less data) we set tq_own to zero * if we receive too few packets it is not considered bidirectional */ - if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || - (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) + if (total_count < BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM || + neigh_rq_count < BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM) tq_own = 0; else /* neigh_node->real_packet_count is never zero as we * only purge old information when getting new * information */ - tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count; + tq_own = (BATADV_TQ_MAX_VALUE * total_count) / neigh_rq_count; /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does * affect the nearly-symmetric links only a little, but * punishes asymmetric links more. This will give a value * between 0 and TQ_MAX_VALUE */ - tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE * - (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) / - (TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE); - - batman_ogm_packet->tq = ((batman_ogm_packet->tq * tq_own - * tq_asym_penalty) / - (TQ_MAX_VALUE * TQ_MAX_VALUE)); + neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count; + neigh_rq_inv_cube = neigh_rq_inv * neigh_rq_inv * neigh_rq_inv; + neigh_rq_max_cube = BATADV_TQ_LOCAL_WINDOW_SIZE * + BATADV_TQ_LOCAL_WINDOW_SIZE * + BATADV_TQ_LOCAL_WINDOW_SIZE; + inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube; + inv_asym_penalty /= neigh_rq_max_cube; + tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty; + + combined_tq = batman_ogm_packet->tq * tq_own * tq_asym_penalty; + combined_tq /= BATADV_TQ_MAX_VALUE * BATADV_TQ_MAX_VALUE; + batman_ogm_packet->tq = combined_tq; batadv_dbg(DBG_BATMAN, bat_priv, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", @@ -860,7 +875,7 @@ static int batadv_iv_ogm_calc_tq(struct orig_node *orig_node, /* if link has the minimum required transmission quality * consider it bidirectional */ - if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) + if (batman_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT) ret = 1; out: @@ -928,7 +943,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, tmp_neigh_node->real_packet_count = bitmap_weight(tmp_neigh_node->real_bits, - TQ_LOCAL_WINDOW_SIZE); + BATADV_TQ_LOCAL_WINDOW_SIZE); } rcu_read_unlock(); @@ -1050,6 +1065,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, unsigned long *word; int offset; int32_t bit_pos; + int16_t if_num; + uint8_t *weight; orig_neigh_node = batadv_get_orig_node(bat_priv, ethhdr->h_source); @@ -1063,15 +1080,17 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, if (has_directlink_flag && batadv_compare_eth(if_incoming->net_dev->dev_addr, batman_ogm_packet->orig)) { - offset = if_incoming->if_num * NUM_WORDS; + if_num = if_incoming->if_num; + offset = if_num * BATADV_NUM_WORDS; spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); word = &(orig_neigh_node->bcast_own[offset]); bit_pos = if_incoming_seqno - 2; bit_pos -= ntohl(batman_ogm_packet->seqno); batadv_set_bit(word, bit_pos); - orig_neigh_node->bcast_own_sum[if_incoming->if_num] = - bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE); + weight = &orig_neigh_node->bcast_own_sum[if_num]; + *weight = bitmap_weight(word, + BATADV_TQ_LOCAL_WINDOW_SIZE); spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); } diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index a6c27f0621af..95d80d1808f2 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -470,10 +470,11 @@ static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, batadv_store_gw_mode); -BATADV_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, +BATADV_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * BATADV_JITTER, + INT_MAX, NULL); +BATADV_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, BATADV_TQ_MAX_VALUE, NULL); -BATADV_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); -BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, +BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_TQ_MAX_VALUE, batadv_post_gw_deselect); static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, batadv_store_gw_bwidth); diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index e195b9eed7ee..4a009b550895 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -25,10 +25,10 @@ /* shift the packet array by n places. */ static void batadv_bitmap_shift_left(unsigned long *seq_bits, int32_t n) { - if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) + if (n <= 0 || n >= BATADV_TQ_LOCAL_WINDOW_SIZE) return; - bitmap_shift_left(seq_bits, seq_bits, n, TQ_LOCAL_WINDOW_SIZE); + bitmap_shift_left(seq_bits, seq_bits, n, BATADV_TQ_LOCAL_WINDOW_SIZE); } @@ -46,7 +46,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, /* sequence number is slightly older. We already got a sequence number * higher than this one, so we just mark it. */ - if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { + if (seq_num_diff <= 0 && seq_num_diff > -BATADV_TQ_LOCAL_WINDOW_SIZE) { if (set_mark) batadv_set_bit(seq_bits, -seq_num_diff); return 0; @@ -55,7 +55,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, /* sequence number is slightly newer, so we shift the window and * set the mark if required */ - if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { + if (seq_num_diff > 0 && seq_num_diff < BATADV_TQ_LOCAL_WINDOW_SIZE) { batadv_bitmap_shift_left(seq_bits, seq_num_diff); if (set_mark) @@ -64,12 +64,12 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, } /* sequence number is much newer, probably missed a lot of packets */ - if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) && - (seq_num_diff < EXPECTED_SEQNO_RANGE)) { + if (seq_num_diff >= BATADV_TQ_LOCAL_WINDOW_SIZE && + seq_num_diff < BATADV_EXPECTED_SEQNO_RANGE) { batadv_dbg(DBG_BATMAN, bat_priv, "We missed a lot of packets (%i) !\n", seq_num_diff - 1); - bitmap_zero(seq_bits, TQ_LOCAL_WINDOW_SIZE); + bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); if (set_mark) batadv_set_bit(seq_bits, 0); return 1; @@ -80,13 +80,13 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, * packet should be dropped without calling this function if the * seqno window is protected. */ - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || - (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { + if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE || + seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { batadv_dbg(DBG_BATMAN, bat_priv, "Other host probably restarted!\n"); - bitmap_zero(seq_bits, TQ_LOCAL_WINDOW_SIZE); + bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); if (set_mark) batadv_set_bit(seq_bits, 0); diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h index 7954ba81cece..a081ce1c0514 100644 --- a/net/batman-adv/bitarray.h +++ b/net/batman-adv/bitarray.h @@ -29,7 +29,7 @@ static inline int batadv_test_bit(const unsigned long *seq_bits, int32_t diff; diff = last_seqno - curr_seqno; - if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) + if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE) return 0; else return test_bit(diff, seq_bits); @@ -39,7 +39,7 @@ static inline int batadv_test_bit(const unsigned long *seq_bits, static inline void batadv_set_bit(unsigned long *seq_bits, int32_t n) { /* if too old, just drop it */ - if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE) + if (n < 0 || n >= BATADV_TQ_LOCAL_WINDOW_SIZE) return; set_bit(n, seq_bits); /* turn the position on */ diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 42b8a2079250..db20b688ee25 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -949,7 +949,7 @@ static void batadv_bla_purge_backbone_gw(struct bat_priv *bat_priv, int now) if (now) goto purge_now; if (!batadv_has_timed_out(backbone_gw->lasttime, - BLA_BACKBONE_TIMEOUT)) + BATADV_BLA_BACKBONE_TIMEOUT)) continue; batadv_dbg(DBG_BLA, backbone_gw->bat_priv, @@ -1001,7 +1001,7 @@ static void batadv_bla_purge_claims(struct bat_priv *bat_priv, primary_if->net_dev->dev_addr)) continue; if (!batadv_has_timed_out(claim->lasttime, - BLA_CLAIM_TIMEOUT)) + BATADV_BLA_CLAIM_TIMEOUT)) continue; batadv_dbg(DBG_BLA, bat_priv, @@ -1075,7 +1075,7 @@ static void batadv_bla_start_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->bla_work, batadv_bla_periodic_work); queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work, - msecs_to_jiffies(BLA_PERIOD_LENGTH)); + msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH)); } /* periodic work to do: @@ -1162,9 +1162,9 @@ int batadv_bla_init(struct bat_priv *bat_priv) } /* initialize the duplicate list */ - for (i = 0; i < DUPLIST_SIZE; i++) + for (i = 0; i < BATADV_DUPLIST_SIZE; i++) bat_priv->bcast_duplist[i].entrytime = - jiffies - msecs_to_jiffies(DUPLIST_TIMEOUT); + jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); bat_priv->bcast_duplist_curr = 0; if (bat_priv->claim_hash) @@ -1216,14 +1216,15 @@ int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, /* calculate the crc ... */ crc = crc16(0, content, length); - for (i = 0 ; i < DUPLIST_SIZE; i++) { - curr = (bat_priv->bcast_duplist_curr + i) % DUPLIST_SIZE; + for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { + curr = (bat_priv->bcast_duplist_curr + i) % BATADV_DUPLIST_SIZE; entry = &bat_priv->bcast_duplist[curr]; /* we can stop searching if the entry is too old ; * later entries will be even older */ - if (batadv_has_timed_out(entry->entrytime, DUPLIST_TIMEOUT)) + if (batadv_has_timed_out(entry->entrytime, + BATADV_DUPLIST_TIMEOUT)) break; if (entry->crc != crc) @@ -1238,7 +1239,8 @@ int batadv_bla_check_bcast_duplist(struct bat_priv *bat_priv, return 1; } /* not found, add a new entry (overwrite the oldest entry) */ - curr = (bat_priv->bcast_duplist_curr + DUPLIST_SIZE - 1) % DUPLIST_SIZE; + curr = (bat_priv->bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); + curr %= BATADV_DUPLIST_SIZE; entry = &bat_priv->bcast_duplist[curr]; entry->crc = crc; entry->entrytime = jiffies; diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 3916e90ff6ed..5fc162c8425a 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -138,8 +138,8 @@ static struct gw_node *batadv_gw_get_best_gw_node(struct bat_priv *bat_priv) tmp_gw_factor = (router->tq_avg * router->tq_avg * down * 100 * 100) / - (TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE * 64); + (BATADV_TQ_LOCAL_WINDOW_SIZE * + BATADV_TQ_LOCAL_WINDOW_SIZE * 64); if ((tmp_gw_factor > max_gw_factor) || ((tmp_gw_factor == max_gw_factor) && @@ -354,7 +354,7 @@ void batadv_gw_node_update(struct bat_priv *bat_priv, gw_node->deleted = 0; - if (new_gwflags == NO_FLAGS) { + if (new_gwflags == BATADV_NO_FLAGS) { gw_node->deleted = jiffies; batadv_dbg(DBG_BATMAN, bat_priv, "Gateway %pM removed from gateway list\n", @@ -367,7 +367,7 @@ void batadv_gw_node_update(struct bat_priv *bat_priv, goto unlock; } - if (new_gwflags == NO_FLAGS) + if (new_gwflags == BATADV_NO_FLAGS) goto unlock; batadv_gw_node_add(bat_priv, orig_node, new_gwflags); @@ -392,7 +392,7 @@ void batadv_gw_node_purge(struct bat_priv *bat_priv) { struct gw_node *gw_node, *curr_gw; struct hlist_node *node, *node_tmp; - unsigned long timeout = msecs_to_jiffies(2 * PURGE_TIMEOUT); + unsigned long timeout = msecs_to_jiffies(2 * BATADV_PURGE_TIMEOUT); int do_deselect = 0; curr_gw = batadv_gw_get_selected_gw_node(bat_priv); @@ -484,8 +484,8 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", - "Gateway", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", - SOURCE_VERSION, primary_if->net_dev->name, + "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF", + BATADV_SOURCE_VERSION, primary_if->net_dev->name, primary_if->net_dev->dev_addr, net_dev->name); rcu_read_lock(); @@ -667,7 +667,7 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, /* If we are a GW then we are our best GW. We can artificially * set the tq towards ourself as the maximum value */ - curr_tq_avg = TQ_MAX_VALUE; + curr_tq_avg = BATADV_TQ_MAX_VALUE; break; case GW_MODE_CLIENT: curr_gw = batadv_gw_get_selected_gw_node(bat_priv); @@ -698,7 +698,7 @@ bool batadv_gw_out_of_range(struct bat_priv *bat_priv, if (!neigh_old) goto out; - if (curr_tq_avg - neigh_old->tq_avg > GW_THRESHOLD) + if (curr_tq_avg - neigh_old->tq_avg > BATADV_GW_THRESHOLD) out_of_range = true; out: diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 9b1cb23ec1f4..e7eba9c32e70 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -548,7 +548,7 @@ bool batadv_is_wifi_iface(int ifindex) struct net_device *net_device = NULL; bool ret = false; - if (ifindex == NULL_IFINDEX) + if (ifindex == BATADV_NULL_IFINDEX) goto out; net_device = dev_get_by_index(&init_net, ifindex); diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 986be72b5144..df7335c4217a 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -72,7 +72,7 @@ static int __init batadv_init(void) register_netdevice_notifier(&batadv_hard_if_notifier); pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", - SOURCE_VERSION, BATADV_COMPAT_VERSION); + BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION); return 0; } @@ -120,7 +120,8 @@ int batadv_mesh_init(struct net_device *soft_iface) if (ret < 0) goto err; - batadv_tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); + batadv_tt_local_add(soft_iface, soft_iface->dev_addr, + BATADV_NULL_IFINDEX); ret = batadv_vis_init(bat_priv); if (ret < 0) @@ -420,7 +421,7 @@ module_exit(batadv_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); -MODULE_VERSION(SOURCE_VERSION); +MODULE_AUTHOR(BATADV_DRIVER_AUTHOR); +MODULE_DESCRIPTION(BATADV_DRIVER_DESC); +MODULE_SUPPORTED_DEVICE(BATADV_DRIVER_DEVICE); +MODULE_VERSION(BATADV_SOURCE_VERSION); diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index b7b98177dadc..09660b4041f9 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -20,79 +20,80 @@ #ifndef _NET_BATMAN_ADV_MAIN_H_ #define _NET_BATMAN_ADV_MAIN_H_ -#define DRIVER_AUTHOR "Marek Lindner , " \ - "Simon Wunderlich " -#define DRIVER_DESC "B.A.T.M.A.N. advanced" -#define DRIVER_DEVICE "batman-adv" +#define BATADV_DRIVER_AUTHOR "Marek Lindner , " \ + "Simon Wunderlich " +#define BATADV_DRIVER_DESC "B.A.T.M.A.N. advanced" +#define BATADV_DRIVER_DEVICE "batman-adv" -#ifndef SOURCE_VERSION -#define SOURCE_VERSION "2012.3.0" +#ifndef BATADV_SOURCE_VERSION +#define BATADV_SOURCE_VERSION "2012.3.0" #endif /* B.A.T.M.A.N. parameters */ -#define TQ_MAX_VALUE 255 -#define JITTER 20 +#define BATADV_TQ_MAX_VALUE 255 +#define BATADV_JITTER 20 /* Time To Live of broadcast messages */ -#define TTL 50 +#define BATADV_TTL 50 /* purge originators after time in seconds if no valid packet comes in - * -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE + * -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE */ -#define PURGE_TIMEOUT 200000 /* 200 seconds */ -#define TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */ -#define TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */ +#define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */ +#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */ +#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */ /* sliding packet range of received originator messages in sequence numbers * (should be a multiple of our word size) */ -#define TQ_LOCAL_WINDOW_SIZE 64 +#define BATADV_TQ_LOCAL_WINDOW_SIZE 64 /* miliseconds we have to keep pending tt_req */ -#define TT_REQUEST_TIMEOUT 3000 +#define BATADV_TT_REQUEST_TIMEOUT 3000 -#define TQ_GLOBAL_WINDOW_SIZE 5 -#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 -#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 -#define TQ_TOTAL_BIDRECT_LIMIT 1 +#define BATADV_TQ_GLOBAL_WINDOW_SIZE 5 +#define BATADV_TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 +#define BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 +#define BATADV_TQ_TOTAL_BIDRECT_LIMIT 1 -#define TT_OGM_APPEND_MAX 3 /* number of OGMs sent with the last tt diff */ +/* number of OGMs sent with the last tt diff */ +#define BATADV_TT_OGM_APPEND_MAX 3 /* Time in which a client can roam at most ROAMING_MAX_COUNT times in * miliseconds */ -#define ROAMING_MAX_TIME 20000 -#define ROAMING_MAX_COUNT 5 +#define BATADV_ROAMING_MAX_TIME 20000 +#define BATADV_ROAMING_MAX_COUNT 5 -#define NO_FLAGS 0 +#define BATADV_NO_FLAGS 0 -#define NULL_IFINDEX 0 /* dummy ifindex used to avoid iface checks */ +#define BATADV_NULL_IFINDEX 0 /* dummy ifindex used to avoid iface checks */ -#define NUM_WORDS BITS_TO_LONGS(TQ_LOCAL_WINDOW_SIZE) +#define BATADV_NUM_WORDS BITS_TO_LONGS(BATADV_TQ_LOCAL_WINDOW_SIZE) -#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ +#define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */ -#define VIS_INTERVAL 5000 /* 5 seconds */ +#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */ /* how much worse secondary interfaces may be to be considered as bonding * candidates */ -#define BONDING_TQ_THRESHOLD 50 +#define BATADV_BONDING_TQ_THRESHOLD 50 /* should not be bigger than 512 bytes or change the size of * forw_packet->direct_link_flags */ -#define MAX_AGGREGATION_BYTES 512 -#define MAX_AGGREGATION_MS 100 +#define BATADV_MAX_AGGREGATION_BYTES 512 +#define BATADV_MAX_AGGREGATION_MS 100 -#define BLA_PERIOD_LENGTH 10000 /* 10 seconds */ -#define BLA_BACKBONE_TIMEOUT (BLA_PERIOD_LENGTH * 3) -#define BLA_CLAIM_TIMEOUT (BLA_PERIOD_LENGTH * 10) +#define BATADV_BLA_PERIOD_LENGTH 10000 /* 10 seconds */ +#define BATADV_BLA_BACKBONE_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 3) +#define BATADV_BLA_CLAIM_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 10) -#define DUPLIST_SIZE 16 -#define DUPLIST_TIMEOUT 500 /* 500 ms */ +#define BATADV_DUPLIST_SIZE 16 +#define BATADV_DUPLIST_TIMEOUT 500 /* 500 ms */ /* don't reset again within 30 seconds */ -#define RESET_PROTECTION_MS 30000 -#define EXPECTED_SEQNO_RANGE 65536 +#define BATADV_RESET_PROTECTION_MS 30000 +#define BATADV_EXPECTED_SEQNO_RANGE 65536 enum mesh_state { MESH_INACTIVE, @@ -100,8 +101,8 @@ enum mesh_state { MESH_DEACTIVATING }; -#define BCAST_QUEUE_LEN 256 -#define BATMAN_QUEUE_LEN 256 +#define BATADV_BCAST_QUEUE_LEN 256 +#define BATADV_BATMAN_QUEUE_LEN 256 enum uev_action { UEV_ADD = 0, @@ -113,7 +114,7 @@ enum uev_type { UEV_GW = 0 }; -#define GW_THRESHOLD 50 +#define BATADV_GW_THRESHOLD 50 /* Debug Messages */ #ifdef pr_fmt diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 1980696a7fd7..f04f591f4668 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -194,6 +194,7 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, struct orig_node *orig_node; int size; int hash_added; + unsigned long reset_time; orig_node = batadv_orig_hash_find(bat_priv, addr); if (orig_node) @@ -226,14 +227,13 @@ struct orig_node *batadv_get_orig_node(struct bat_priv *bat_priv, orig_node->tt_buff = NULL; orig_node->tt_buff_len = 0; atomic_set(&orig_node->tt_size, 0); - orig_node->bcast_seqno_reset = jiffies - 1 - - msecs_to_jiffies(RESET_PROTECTION_MS); - orig_node->batman_seqno_reset = jiffies - 1 - - msecs_to_jiffies(RESET_PROTECTION_MS); + reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); + orig_node->bcast_seqno_reset = reset_time; + orig_node->batman_seqno_reset = reset_time; atomic_set(&orig_node->bond_candidates, 0); - size = bat_priv->num_ifaces * sizeof(unsigned long) * NUM_WORDS; + size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS; orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); if (!orig_node->bcast_own) @@ -285,7 +285,7 @@ static bool batadv_purge_orig_neighbors(struct bat_priv *bat_priv, last_seen = neigh_node->last_seen; if_incoming = neigh_node->if_incoming; - if ((batadv_has_timed_out(last_seen, PURGE_TIMEOUT)) || + if ((batadv_has_timed_out(last_seen, BATADV_PURGE_TIMEOUT)) || (if_incoming->if_status == IF_INACTIVE) || (if_incoming->if_status == IF_NOT_IN_USE) || (if_incoming->if_status == IF_TO_BE_REMOVED)) { @@ -324,7 +324,8 @@ static bool batadv_purge_orig_node(struct bat_priv *bat_priv, { struct neigh_node *best_neigh_node; - if (batadv_has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { + if (batadv_has_timed_out(orig_node->last_seen, + 2 * BATADV_PURGE_TIMEOUT)) { batadv_dbg(DBG_BATMAN, bat_priv, "Originator timeout: originator %pM, last_seen %u\n", orig_node->orig, @@ -429,11 +430,11 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) } seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", - SOURCE_VERSION, primary_if->net_dev->name, + BATADV_SOURCE_VERSION, primary_if->net_dev->name, primary_if->net_dev->dev_addr, net_dev->name); seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", - "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", - "outgoingIF", "Potential nexthops"); + "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE, + "Nexthop", "outgoingIF", "Potential nexthops"); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -486,14 +487,15 @@ out: static int batadv_orig_node_add_if(struct orig_node *orig_node, int max_if_num) { void *data_ptr; + size_t data_size, old_size; - data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS, - GFP_ATOMIC); + data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS; + old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS; + data_ptr = kmalloc(data_size, GFP_ATOMIC); if (!data_ptr) return -ENOMEM; - memcpy(data_ptr, orig_node->bcast_own, - (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS); + memcpy(data_ptr, orig_node->bcast_own, old_size); kfree(orig_node->bcast_own); orig_node->bcast_own = data_ptr; @@ -554,7 +556,7 @@ static int batadv_orig_node_del_if(struct orig_node *orig_node, if (max_if_num == 0) goto free_bcast_own; - chunk_size = sizeof(unsigned long) * NUM_WORDS; + chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS; data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); if (!data_ptr) return -ENOMEM; diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c index aff1ca2990f1..c8f61e395b74 100644 --- a/net/batman-adv/ring_buffer.c +++ b/net/batman-adv/ring_buffer.c @@ -24,7 +24,7 @@ void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value) { lq_recv[*lq_index] = value; - *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE; + *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE; } uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) @@ -34,7 +34,7 @@ uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) ptr = lq_recv; - while (i < TQ_GLOBAL_WINDOW_SIZE) { + while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) { if (*ptr != 0) { count++; sum += *ptr; diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index c8fee749eab8..b3fd61c90f32 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -42,6 +42,7 @@ void batadv_slide_own_bcast_window(struct hard_iface *hard_iface) unsigned long *word; uint32_t i; size_t word_index; + uint8_t *w; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -49,12 +50,12 @@ void batadv_slide_own_bcast_window(struct hard_iface *hard_iface) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); - word_index = hard_iface->if_num * NUM_WORDS; + word_index = hard_iface->if_num * BATADV_NUM_WORDS; word = &(orig_node->bcast_own[word_index]); batadv_bit_get_packet(bat_priv, word, 1, 0); - orig_node->bcast_own_sum[hard_iface->if_num] = - bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE); + w = &orig_node->bcast_own_sum[hard_iface->if_num]; + *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE); spin_unlock_bh(&orig_node->ogm_cnt_lock); } rcu_read_unlock(); @@ -160,7 +161,7 @@ void batadv_bonding_candidate_add(struct orig_node *orig_node, goto candidate_del; /* ... and is good enough to be considered */ - if (neigh_node->tq_avg < router->tq_avg - BONDING_TQ_THRESHOLD) + if (neigh_node->tq_avg < router->tq_avg - BATADV_BONDING_TQ_THRESHOLD) goto candidate_del; /* check if we have another candidate with the same mac address or @@ -232,9 +233,10 @@ batadv_bonding_save_primary(const struct orig_node *orig_node, int batadv_window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, unsigned long *last_reset) { - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || - (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - if (!batadv_has_timed_out(*last_reset, RESET_PROTECTION_MS)) + if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE || + seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { + if (!batadv_has_timed_out(*last_reset, + BATADV_RESET_PROTECTION_MS)) return 1; *last_reset = jiffies; @@ -316,7 +318,7 @@ static int batadv_recv_my_icmp_packet(struct bat_priv *bat_priv, memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); icmp_packet->msg_type = ECHO_REPLY; - icmp_packet->header.ttl = TTL; + icmp_packet->header.ttl = BATADV_TTL; batadv_send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; @@ -371,7 +373,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); icmp_packet->msg_type = TTL_EXCEEDED; - icmp_packet->header.ttl = TTL; + icmp_packet->header.ttl = BATADV_TTL; batadv_send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index bbbc9a93d430..c1b2ab2f37bb 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -108,7 +108,7 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { batadv_tt_local_remove(bat_priv, dev->dev_addr, "mac address changed", false); - batadv_tt_local_add(dev, addr->sa_data, NULL_IFINDEX); + batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); } memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); @@ -210,7 +210,7 @@ static int batadv_interface_tx(struct sk_buff *skb, bcast_packet = (struct bcast_packet *)skb->data; bcast_packet->header.version = BATADV_COMPAT_VERSION; - bcast_packet->header.ttl = TTL; + bcast_packet->header.ttl = BATADV_TTL; /* batman packet type: broadcast */ bcast_packet->header.packet_type = BAT_BCAST; @@ -394,8 +394,8 @@ struct net_device *batadv_softif_create(const char *name) atomic_set(&bat_priv->hop_penalty, 30); atomic_set(&bat_priv->log_level, 0); atomic_set(&bat_priv->fragmentation, 1); - atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN); - atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN); + atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); + atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); atomic_set(&bat_priv->bcast_seqno, 1); @@ -487,7 +487,7 @@ static void batadv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strcpy(info->driver, "B.A.T.M.A.N. advanced"); - strcpy(info->version, SOURCE_VERSION); + strcpy(info->version, BATADV_SOURCE_VERSION); strcpy(info->fw_version, "N/A"); strcpy(info->bus_info, "batman"); } diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 79cd3f76a865..a0487e9f18c7 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -257,7 +257,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, (uint8_t)atomic_read(&bat_priv->ttvn)); memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); - tt_local_entry->common.flags = NO_FLAGS; + tt_local_entry->common.flags = BATADV_NO_FLAGS; if (batadv_is_wifi_iface(ifindex)) tt_local_entry->common.flags |= TT_CLIENT_WIFI; atomic_set(&tt_local_entry->common.refcount, 2); @@ -493,14 +493,17 @@ void batadv_tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr, const char *message, bool roaming) { struct tt_local_entry *tt_local_entry = NULL; + uint16_t flags; tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); if (!tt_local_entry) goto out; - batadv_tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL | - (roaming ? TT_CLIENT_ROAM : NO_FLAGS), - message); + flags = TT_CLIENT_DEL; + if (roaming) + flags |= TT_CLIENT_ROAM; + + batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message); out: if (tt_local_entry) batadv_tt_local_entry_free_ref(tt_local_entry); @@ -534,7 +537,7 @@ static void batadv_tt_local_purge(struct bat_priv *bat_priv) continue; if (!batadv_has_timed_out(tt_local_entry->last_seen, - TT_LOCAL_TIMEOUT)) + BATADV_TT_LOCAL_TIMEOUT)) continue; batadv_tt_local_set_pending(bat_priv, tt_local_entry, @@ -1008,12 +1011,35 @@ void batadv_tt_global_del_orig(struct bat_priv *bat_priv, orig_node->tt_initialised = false; } -static void batadv_tt_global_roam_purge(struct bat_priv *bat_priv) +static void batadv_tt_global_roam_purge_list(struct bat_priv *bat_priv, + struct hlist_head *head) { - struct hashtable_t *hash = bat_priv->tt_global_hash; struct tt_common_entry *tt_common_entry; struct tt_global_entry *tt_global_entry; struct hlist_node *node, *node_tmp; + + hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head, + hash_entry) { + tt_global_entry = container_of(tt_common_entry, + struct tt_global_entry, common); + if (!(tt_global_entry->common.flags & TT_CLIENT_ROAM)) + continue; + if (!batadv_has_timed_out(tt_global_entry->roam_at, + BATADV_TT_CLIENT_ROAM_TIMEOUT)) + continue; + + batadv_dbg(DBG_TT, bat_priv, + "Deleting global tt entry (%pM): Roaming timeout\n", + tt_global_entry->common.addr); + + hlist_del_rcu(node); + batadv_tt_global_entry_free_ref(tt_global_entry); + } +} + +static void batadv_tt_global_roam_purge(struct bat_priv *bat_priv) +{ + struct hashtable_t *hash = bat_priv->tt_global_hash; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ uint32_t i; @@ -1023,24 +1049,7 @@ static void batadv_tt_global_roam_purge(struct bat_priv *bat_priv) list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); - hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, - head, hash_entry) { - tt_global_entry = container_of(tt_common_entry, - struct tt_global_entry, - common); - if (!(tt_global_entry->common.flags & TT_CLIENT_ROAM)) - continue; - if (!batadv_has_timed_out(tt_global_entry->roam_at, - TT_CLIENT_ROAM_TIMEOUT)) - continue; - - batadv_dbg(DBG_TT, bat_priv, - "Deleting global tt entry (%pM): Roaming timeout\n", - tt_global_entry->common.addr); - - hlist_del_rcu(node); - batadv_tt_global_entry_free_ref(tt_global_entry); - } + batadv_tt_global_roam_purge_list(bat_priv, head); spin_unlock_bh(list_lock); } @@ -1278,7 +1287,8 @@ static void batadv_tt_req_purge(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->tt_req_list_lock); list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { - if (batadv_has_timed_out(node->issued_at, TT_REQUEST_TIMEOUT)) { + if (batadv_has_timed_out(node->issued_at, + BATADV_TT_REQUEST_TIMEOUT)) { list_del(&node->list); kfree(node); } @@ -1298,7 +1308,7 @@ static struct tt_req_node *batadv_new_tt_req_node(struct bat_priv *bat_priv, list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { if (batadv_compare_eth(tt_req_node_tmp, orig_node) && !batadv_has_timed_out(tt_req_node_tmp->issued_at, - TT_REQUEST_TIMEOUT)) + BATADV_TT_REQUEST_TIMEOUT)) goto unlock; } @@ -1391,7 +1401,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, memcpy(tt_change->addr, tt_common_entry->addr, ETH_ALEN); - tt_change->flags = NO_FLAGS; + tt_change->flags = BATADV_NO_FLAGS; tt_count++; tt_change++; @@ -1444,7 +1454,7 @@ static int batadv_send_tt_request(struct bat_priv *bat_priv, tt_request->header.version = BATADV_COMPAT_VERSION; memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN); - tt_request->header.ttl = TTL; + tt_request->header.ttl = BATADV_TTL; tt_request->ttvn = ttvn; tt_request->tt_data = htons(tt_crc); tt_request->flags = TT_REQUEST; @@ -1576,7 +1586,7 @@ static bool batadv_send_other_tt_response(struct bat_priv *bat_priv, tt_response->header.packet_type = BAT_TT_QUERY; tt_response->header.version = BATADV_COMPAT_VERSION; - tt_response->header.ttl = TTL; + tt_response->header.ttl = BATADV_TTL; memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN); memcpy(tt_response->dst, tt_request->src, ETH_ALEN); tt_response->flags = TT_RESPONSE; @@ -1697,7 +1707,7 @@ static bool batadv_send_my_tt_response(struct bat_priv *bat_priv, tt_response->header.packet_type = BAT_TT_QUERY; tt_response->header.version = BATADV_COMPAT_VERSION; - tt_response->header.ttl = TTL; + tt_response->header.ttl = BATADV_TTL; memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(tt_response->dst, tt_request->src, ETH_ALEN); tt_response->flags = TT_RESPONSE; @@ -1925,7 +1935,8 @@ static void batadv_tt_roam_purge(struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->tt_roam_list_lock); list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { - if (!batadv_has_timed_out(node->first_time, ROAMING_MAX_TIME)) + if (!batadv_has_timed_out(node->first_time, + BATADV_ROAMING_MAX_TIME)) continue; list_del(&node->list); @@ -1955,7 +1966,7 @@ static bool batadv_tt_check_roam_count(struct bat_priv *bat_priv, continue; if (batadv_has_timed_out(tt_roam_node->first_time, - ROAMING_MAX_TIME)) + BATADV_ROAMING_MAX_TIME)) continue; if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) @@ -1971,7 +1982,8 @@ static bool batadv_tt_check_roam_count(struct bat_priv *bat_priv, goto unlock; tt_roam_node->first_time = jiffies; - atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1); + atomic_set(&tt_roam_node->counter, + BATADV_ROAMING_MAX_COUNT - 1); memcpy(tt_roam_node->addr, client, ETH_ALEN); list_add(&tt_roam_node->list, &bat_priv->tt_roam_list); @@ -2009,7 +2021,7 @@ static void batadv_send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, roam_adv_packet->header.packet_type = BAT_ROAM_ADV; roam_adv_packet->header.version = BATADV_COMPAT_VERSION; - roam_adv_packet->header.ttl = TTL; + roam_adv_packet->header.ttl = BATADV_TTL; primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -2170,7 +2182,7 @@ static int batadv_tt_commit_changes(struct bat_priv *bat_priv, bat_priv->tt_poss_change = false; /* reset the sending counter */ - atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); + atomic_set(&bat_priv->tt_ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); return batadv_tt_changes_fill_buff(bat_priv, packet_buff, packet_buff_len, packet_min_len); @@ -2248,7 +2260,8 @@ void batadv_tt_update_orig(struct bat_priv *bat_priv, if ((!orig_node->tt_initialised && ttvn == 1) || ttvn - orig_ttvn == 1) { /* the OGM could not contain the changes due to their size or - * because they have already been sent TT_OGM_APPEND_MAX times. + * because they have already been sent BATADV_TT_OGM_APPEND_MAX + * times. * In this case send a tt request */ if (!tt_num_changes) { diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 1d5d21ed8e8a..fd538ea68117 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -85,7 +85,7 @@ struct orig_node { bool tt_poss_change; uint32_t last_real_seqno; uint8_t last_ttl; - DECLARE_BITMAP(bcast_bits, TQ_LOCAL_WINDOW_SIZE); + DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); uint32_t last_bcast_seqno; struct hlist_head neigh_list; struct list_head frag_list; @@ -121,13 +121,13 @@ struct neigh_node { struct hlist_node list; uint8_t addr[ETH_ALEN]; uint8_t real_packet_count; - uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE]; + uint8_t tq_recv[BATADV_TQ_GLOBAL_WINDOW_SIZE]; uint8_t tq_index; uint8_t tq_avg; uint8_t last_ttl; struct list_head bonding_list; unsigned long last_seen; - DECLARE_BITMAP(real_bits, TQ_LOCAL_WINDOW_SIZE); + DECLARE_BITMAP(real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); atomic_t refcount; struct rcu_head rcu; struct orig_node *orig_node; @@ -209,7 +209,7 @@ struct bat_priv { struct list_head tt_roam_list; struct hashtable_t *vis_hash; #ifdef CONFIG_BATMAN_ADV_BLA - struct bcast_duplist_entry bcast_duplist[DUPLIST_SIZE]; + struct bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; int bcast_duplist_curr; struct bla_claim_dst claim_dest; #endif @@ -348,7 +348,7 @@ struct if_list_entry { }; struct debug_log { - char log_buff[LOG_BUF_LEN]; + char log_buff[BATADV_LOG_BUF_LEN]; unsigned long log_start; unsigned long log_end; spinlock_t lock; /* protects log_buff, log_start and log_end */ diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 809832026370..8454d916cd01 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -323,7 +323,7 @@ find_router: /* batman packet type: unicast */ unicast_packet->header.packet_type = BAT_UNICAST; /* set unicast ttl */ - unicast_packet->header.ttl = TTL; + unicast_packet->header.ttl = BATADV_TTL; /* copy the destination for faster routing */ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* set the destination tt version number */ diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index a439ed6616ea..74181696eef6 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -575,7 +575,7 @@ static int batadv_generate_vis_packet(struct bat_priv *bat_priv) packet->vis_type = atomic_read(&bat_priv->vis_mode); memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN); - packet->header.ttl = TTL; + packet->header.ttl = BATADV_TTL; packet->seqno = htonl(ntohl(packet->seqno) + 1); packet->entries = 0; skb_trim(info->skb_packet, sizeof(*packet)); @@ -841,6 +841,7 @@ int batadv_vis_init(struct bat_priv *bat_priv) struct vis_packet *packet; int hash_added; unsigned int len; + unsigned long first_seen; if (bat_priv->vis_hash) return 0; @@ -867,15 +868,15 @@ int batadv_vis_init(struct bat_priv *bat_priv) sizeof(*packet)); /* prefill the vis info */ - bat_priv->my_vis_info->first_seen = jiffies - - msecs_to_jiffies(VIS_INTERVAL); + first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL); + bat_priv->my_vis_info->first_seen = first_seen; INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); kref_init(&bat_priv->my_vis_info->refcount); bat_priv->my_vis_info->bat_priv = bat_priv; packet->header.version = BATADV_COMPAT_VERSION; packet->header.packet_type = BAT_VIS; - packet->header.ttl = TTL; + packet->header.ttl = BATADV_TTL; packet->seqno = 0; packet->entries = 0; @@ -936,5 +937,5 @@ static void batadv_start_vis_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->vis_work, batadv_send_vis_packets); queue_delayed_work(batadv_event_workqueue, &bat_priv->vis_work, - msecs_to_jiffies(VIS_INTERVAL)); + msecs_to_jiffies(BATADV_VIS_INTERVAL)); } -- GitLab From 00a3669838a02de2ae139bdb13c1019aa427a442 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 7 Jun 2012 18:50:51 -0600 Subject: [PATCH 3148/6849] ARM: OMAP depends on MMU There is no way to build OMAP kernels without an MMU at this point because of dependencies on MMU-only functions. As long as nobody is interested in fixing this, let's just disable this platforms for nommu kernels. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Acked-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 84449dd8f031..4b1fc0d612b6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -934,6 +934,7 @@ config ARCH_DAVINCI config ARCH_OMAP bool "TI OMAP" + depends on MMU select HAVE_CLK select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ -- GitLab From d3ada72ee3a479acbfb718302ca8b87d9d6e5e60 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 24 Jun 2012 00:18:59 +0200 Subject: [PATCH 3149/6849] ARM: OMAP: omap2plus_defconfig: Enable EXT4 support On OMAP boards that includes an SD card slot, an EXT4 partition could be used to store the root file system. So, the kernel should have built-in support for EXT4 to be able to mount the VFS root on boot. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/configs/omap2plus_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 9854ff4279e0..f3087cb0ab08 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -197,6 +197,7 @@ CONFIG_RTC_DRV_TWL4030=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_QUOTA=y CONFIG_QFMT_V2=y CONFIG_MSDOS_FS=y -- GitLab From b56f2cb71a73618c97721762feb0a1be81302e22 Mon Sep 17 00:00:00 2001 From: Venkatraman S Date: Mon, 25 Jun 2012 15:56:39 +0530 Subject: [PATCH 3150/6849] ARM: OMAP2+: fix naming collision of variable nr_irqs Using nr_irqs as local variable name triggers the sparse warning.. ./arch/arm/mach-omap2/irq.c:265:6: warning: symbol 'nr_irqs' shadows an earlier one ./linux/include/linux/irqnr.h:26:12: originally declared here Signed-off-by: Venkatraman S Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/irq.c | 8 ++++---- arch/arm/mach-omap2/prm_common.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index fdc4303be563..74d77e008025 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -261,7 +261,7 @@ int __init omap_intc_of_init(struct device_node *node, struct device_node *parent) { struct resource res; - u32 nr_irqs = 96; + u32 nr_irq = 96; if (WARN_ON(!node)) return -ENODEV; @@ -271,10 +271,10 @@ int __init omap_intc_of_init(struct device_node *node, return -EINVAL; } - if (of_property_read_u32(node, "ti,intc-size", &nr_irqs)) - pr_warn("unable to get intc-size, default to %d\n", nr_irqs); + if (of_property_read_u32(node, "ti,intc-size", &nr_irq)) + pr_warn("unable to get intc-size, default to %d\n", nr_irq); - omap_init_irq(res.start, nr_irqs, of_node_get(node)); + omap_init_irq(res.start, nr_irq, of_node_get(node)); return 0; } diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index dfe00ddb5c60..534d732caa1e 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -85,7 +85,7 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc) unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG]; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int virtirq; - int nr_irqs = prcm_irq_setup->nr_regs * 32; + int nr_irq = prcm_irq_setup->nr_regs * 32; /* * If we are suspended, mask all interrupts from PRCM level, @@ -110,7 +110,7 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc) prcm_irq_setup->read_pending_irqs(pending); /* No bit set, then all IRQs are handled */ - if (find_first_bit(pending, nr_irqs) >= nr_irqs) + if (find_first_bit(pending, nr_irq) >= nr_irq) break; omap_prcm_events_filter_priority(pending, priority_pending); @@ -121,11 +121,11 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc) */ /* Serve priority events first */ - for_each_set_bit(virtirq, priority_pending, nr_irqs) + for_each_set_bit(virtirq, priority_pending, nr_irq) generic_handle_irq(prcm_irq_setup->base_irq + virtirq); /* Serve normal events next */ - for_each_set_bit(virtirq, pending, nr_irqs) + for_each_set_bit(virtirq, pending, nr_irq) generic_handle_irq(prcm_irq_setup->base_irq + virtirq); } if (chip->irq_ack) -- GitLab From 59757c750fb3a89f172537a9e0ea2c6977771eee Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 28 Jun 2012 00:08:10 -0700 Subject: [PATCH 3151/6849] ARM: OMAP7XX: Remove omap730.h and omap850.h No file includes omap730.h or omap850.h. That's not surprising, as commit e6684f7132c6e6333e96407b06910bebaa4c1935 ("OMAP7XX: Create omap7xx.h") created a header that was "intended to replace omap730.h and omap850.h", while all "values defined [in omap7xx.h] are identical to those in both the old files". So it seems it was just an oversight to keep both the old files after commit 7a8f48f8c611ac8c07023260258e2fec312b9242 ("OMAP7XX: omap_uwire.c: Convert to omap7xx.h") converted the last file still including one of those two old files. Convert the last reference to omap730.h to a reference to omap7xx.h too. Signed-off-by: Paul Bolle Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/mux.h | 2 +- arch/arm/plat-omap/include/plat/omap730.h | 102 ---------------------- arch/arm/plat-omap/include/plat/omap850.h | 102 ---------------------- 3 files changed, 1 insertion(+), 205 deletions(-) delete mode 100644 arch/arm/plat-omap/include/plat/omap730.h delete mode 100644 arch/arm/plat-omap/include/plat/omap850.h diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h index aeba71796ad9..323948959200 100644 --- a/arch/arm/plat-omap/include/plat/mux.h +++ b/arch/arm/plat-omap/include/plat/mux.h @@ -99,7 +99,7 @@ /* * OMAP730/850 has a slightly different config for the pin mux. - * - config regs are the OMAP7XX_IO_CONF_x regs (see omap730.h) regs and + * - config regs are the OMAP7XX_IO_CONF_x regs (see omap7xx.h) regs and * not the FUNC_MUX_CTRL_x regs from hardware.h * - for pull-up/down, only has one enable bit which is is in the same register * as mux config diff --git a/arch/arm/plat-omap/include/plat/omap730.h b/arch/arm/plat-omap/include/plat/omap730.h deleted file mode 100644 index 14272bc1a6fd..000000000000 --- a/arch/arm/plat-omap/include/plat/omap730.h +++ /dev/null @@ -1,102 +0,0 @@ -/* arch/arm/plat-omap/include/mach/omap730.h - * - * Hardware definitions for TI OMAP730 processor. - * - * Cleanup for Linux-2.6 by Dirk Behme - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_OMAP730_H -#define __ASM_ARCH_OMAP730_H - -/* - * ---------------------------------------------------------------------------- - * Base addresses - * ---------------------------------------------------------------------------- - */ - -/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */ - -#define OMAP730_DSP_BASE 0xE0000000 -#define OMAP730_DSP_SIZE 0x50000 -#define OMAP730_DSP_START 0xE0000000 - -#define OMAP730_DSPREG_BASE 0xE1000000 -#define OMAP730_DSPREG_SIZE SZ_128K -#define OMAP730_DSPREG_START 0xE1000000 - -/* - * ---------------------------------------------------------------------------- - * OMAP730 specific configuration registers - * ---------------------------------------------------------------------------- - */ -#define OMAP730_CONFIG_BASE 0xfffe1000 -#define OMAP730_IO_CONF_0 0xfffe1070 -#define OMAP730_IO_CONF_1 0xfffe1074 -#define OMAP730_IO_CONF_2 0xfffe1078 -#define OMAP730_IO_CONF_3 0xfffe107c -#define OMAP730_IO_CONF_4 0xfffe1080 -#define OMAP730_IO_CONF_5 0xfffe1084 -#define OMAP730_IO_CONF_6 0xfffe1088 -#define OMAP730_IO_CONF_7 0xfffe108c -#define OMAP730_IO_CONF_8 0xfffe1090 -#define OMAP730_IO_CONF_9 0xfffe1094 -#define OMAP730_IO_CONF_10 0xfffe1098 -#define OMAP730_IO_CONF_11 0xfffe109c -#define OMAP730_IO_CONF_12 0xfffe10a0 -#define OMAP730_IO_CONF_13 0xfffe10a4 - -#define OMAP730_MODE_1 0xfffe1010 -#define OMAP730_MODE_2 0xfffe1014 - -/* CSMI specials: in terms of base + offset */ -#define OMAP730_MODE2_OFFSET 0x14 - -/* - * ---------------------------------------------------------------------------- - * OMAP730 traffic controller configuration registers - * ---------------------------------------------------------------------------- - */ -#define OMAP730_FLASH_CFG_0 0xfffecc10 -#define OMAP730_FLASH_ACFG_0 0xfffecc50 -#define OMAP730_FLASH_CFG_1 0xfffecc14 -#define OMAP730_FLASH_ACFG_1 0xfffecc54 - -/* - * ---------------------------------------------------------------------------- - * OMAP730 DSP control registers - * ---------------------------------------------------------------------------- - */ -#define OMAP730_ICR_BASE 0xfffbb800 -#define OMAP730_DSP_M_CTL 0xfffbb804 -#define OMAP730_DSP_MMU_BASE 0xfffed200 - -/* - * ---------------------------------------------------------------------------- - * OMAP730 PCC_UPLD configuration registers - * ---------------------------------------------------------------------------- - */ -#define OMAP730_PCC_UPLD_CTRL_BASE (0xfffe0900) -#define OMAP730_PCC_UPLD_CTRL (OMAP730_PCC_UPLD_CTRL_BASE + 0x00) - -#endif /* __ASM_ARCH_OMAP730_H */ - diff --git a/arch/arm/plat-omap/include/plat/omap850.h b/arch/arm/plat-omap/include/plat/omap850.h deleted file mode 100644 index c33f67981712..000000000000 --- a/arch/arm/plat-omap/include/plat/omap850.h +++ /dev/null @@ -1,102 +0,0 @@ -/* arch/arm/plat-omap/include/mach/omap850.h - * - * Hardware definitions for TI OMAP850 processor. - * - * Derived from omap730.h by Zebediah C. McClure - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_OMAP850_H -#define __ASM_ARCH_OMAP850_H - -/* - * ---------------------------------------------------------------------------- - * Base addresses - * ---------------------------------------------------------------------------- - */ - -/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */ - -#define OMAP850_DSP_BASE 0xE0000000 -#define OMAP850_DSP_SIZE 0x50000 -#define OMAP850_DSP_START 0xE0000000 - -#define OMAP850_DSPREG_BASE 0xE1000000 -#define OMAP850_DSPREG_SIZE SZ_128K -#define OMAP850_DSPREG_START 0xE1000000 - -/* - * ---------------------------------------------------------------------------- - * OMAP850 specific configuration registers - * ---------------------------------------------------------------------------- - */ -#define OMAP850_CONFIG_BASE 0xfffe1000 -#define OMAP850_IO_CONF_0 0xfffe1070 -#define OMAP850_IO_CONF_1 0xfffe1074 -#define OMAP850_IO_CONF_2 0xfffe1078 -#define OMAP850_IO_CONF_3 0xfffe107c -#define OMAP850_IO_CONF_4 0xfffe1080 -#define OMAP850_IO_CONF_5 0xfffe1084 -#define OMAP850_IO_CONF_6 0xfffe1088 -#define OMAP850_IO_CONF_7 0xfffe108c -#define OMAP850_IO_CONF_8 0xfffe1090 -#define OMAP850_IO_CONF_9 0xfffe1094 -#define OMAP850_IO_CONF_10 0xfffe1098 -#define OMAP850_IO_CONF_11 0xfffe109c -#define OMAP850_IO_CONF_12 0xfffe10a0 -#define OMAP850_IO_CONF_13 0xfffe10a4 - -#define OMAP850_MODE_1 0xfffe1010 -#define OMAP850_MODE_2 0xfffe1014 - -/* CSMI specials: in terms of base + offset */ -#define OMAP850_MODE2_OFFSET 0x14 - -/* - * ---------------------------------------------------------------------------- - * OMAP850 traffic controller configuration registers - * ---------------------------------------------------------------------------- - */ -#define OMAP850_FLASH_CFG_0 0xfffecc10 -#define OMAP850_FLASH_ACFG_0 0xfffecc50 -#define OMAP850_FLASH_CFG_1 0xfffecc14 -#define OMAP850_FLASH_ACFG_1 0xfffecc54 - -/* - * ---------------------------------------------------------------------------- - * OMAP850 DSP control registers - * ---------------------------------------------------------------------------- - */ -#define OMAP850_ICR_BASE 0xfffbb800 -#define OMAP850_DSP_M_CTL 0xfffbb804 -#define OMAP850_DSP_MMU_BASE 0xfffed200 - -/* - * ---------------------------------------------------------------------------- - * OMAP850 PCC_UPLD configuration registers - * ---------------------------------------------------------------------------- - */ -#define OMAP850_PCC_UPLD_CTRL_BASE (0xfffe0900) -#define OMAP850_PCC_UPLD_CTRL (OMAP850_PCC_UPLD_CTRL_BASE + 0x00) - -#endif /* __ASM_ARCH_OMAP850_H */ - -- GitLab From d2ba779afc84b2e05dcb64cb801a4af52f1c4be7 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 26 Jun 2012 23:12:47 +0200 Subject: [PATCH 3152/6849] ARM: OMAP: fix typos related to OMAP330 Signed-off-by: Paul Bolle Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 297245dba66e..f2bdf15bdcef 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -238,7 +238,7 @@ IS_AM_SUBCLASS(335x, 0x335) /* * Macros to detect individual cpu types. * These are only rarely needed. - * cpu_is_omap330(): True for OMAP330 + * cpu_is_omap310(): True for OMAP310 * cpu_is_omap730(): True for OMAP730 * cpu_is_omap850(): True for OMAP850 * cpu_is_omap1510(): True for OMAP1510 @@ -304,7 +304,7 @@ IS_OMAP_TYPE(3517, 0x3517) /* * Whether we have MULTI_OMAP1 or not, we still need to distinguish - * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710. + * between 730 vs 850, 310 vs. 1510 and 1611B/5912 vs. 1710. */ #if defined(CONFIG_ARCH_OMAP730) -- GitLab From 0fb37842e47dd7f96725b86cb89a03dcecc72a46 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 26 Jun 2012 23:13:29 +0200 Subject: [PATCH 3153/6849] ARM: OMAP: remove unused cpu detection macros Now that OMAP730 and OMAP850 support is mostly unified, there's no need for separate cpu detection macros for these architectures. At least, currently there isn't, because both macros are unused. cpu_is_7xx() seems to cover all possible uses. Signed-off-by: Paul Bolle [tony@atomide.com: updated to also to remove related IS_OMAP_TYPE] Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/cpu.h | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index f2bdf15bdcef..e79e913d95de 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -239,8 +239,6 @@ IS_AM_SUBCLASS(335x, 0x335) * Macros to detect individual cpu types. * These are only rarely needed. * cpu_is_omap310(): True for OMAP310 - * cpu_is_omap730(): True for OMAP730 - * cpu_is_omap850(): True for OMAP850 * cpu_is_omap1510(): True for OMAP1510 * cpu_is_omap1610(): True for OMAP1610 * cpu_is_omap1611(): True for OMAP1611 @@ -264,8 +262,6 @@ static inline int is_omap ##type (void) \ } IS_OMAP_TYPE(310, 0x0310) -IS_OMAP_TYPE(730, 0x0730) -IS_OMAP_TYPE(850, 0x0850) IS_OMAP_TYPE(1510, 0x1510) IS_OMAP_TYPE(1610, 0x1610) IS_OMAP_TYPE(1611, 0x1611) @@ -281,8 +277,6 @@ IS_OMAP_TYPE(3505, 0x3517) IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap310() 0 -#define cpu_is_omap730() 0 -#define cpu_is_omap850() 0 #define cpu_is_omap1510() 0 #define cpu_is_omap1610() 0 #define cpu_is_omap5912() 0 @@ -304,19 +298,9 @@ IS_OMAP_TYPE(3517, 0x3517) /* * Whether we have MULTI_OMAP1 or not, we still need to distinguish - * between 730 vs 850, 310 vs. 1510 and 1611B/5912 vs. 1710. + * between 310 vs. 1510 and 1611B/5912 vs. 1710. */ -#if defined(CONFIG_ARCH_OMAP730) -# undef cpu_is_omap730 -# define cpu_is_omap730() is_omap730() -#endif - -#if defined(CONFIG_ARCH_OMAP850) -# undef cpu_is_omap850 -# define cpu_is_omap850() is_omap850() -#endif - #if defined(CONFIG_ARCH_OMAP15XX) # undef cpu_is_omap310 # undef cpu_is_omap1510 -- GitLab From bc404e9128dd69654f5fda6320fc6af4ee94474c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 27 Jun 2012 11:26:34 +0200 Subject: [PATCH 3154/6849] sh: kfr2r09: fix compile breakage Fix compile breakage caused by commit aa82f9fcd0062782dcbe29a2c820ba7c04dbe572 Author: Paul Mundt sh: kfr2r09 evt2irq migration. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 158c9176e42a..43a179ce9afc 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -201,8 +201,8 @@ static struct resource kfr2r09_usb0_gadget_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = evtirq(0xa20), - .end = evtirq(0xa20), + .start = evt2irq(0xa20), + .end = evt2irq(0xa20), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, }, }; -- GitLab From ad3337cb38bf1f4c677ce2d05f9c049b35f7147e Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 27 Jun 2012 09:59:40 +0900 Subject: [PATCH 3155/6849] sh: Convert sh_clk_mstp32_register to sh_clk_mstp_register sh_clk_mstp32_register is deprecated. This convert to sh_clk_mstp_register. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pcie-sh7786.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7734.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index c045142f7338..9e702f2f8045 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -239,7 +239,7 @@ static int __init pcie_clk_init(struct sh7786_pcie_port *port) clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR); clk->enable_bit = BITS_CKE; - ret = sh_clk_mstp32_register(clk, 1); + ret = sh_clk_mstp_register(clk, 1); if (unlikely(ret < 0)) goto err_phy; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index ea01a72f1b94..53638e231cd0 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -283,7 +283,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 7ac07b4f75de..22e485d1990b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -276,7 +276,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 8e1f97010c0d..c4cb740e4d10 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -261,7 +261,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR); + ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 35f75cf0c7e5..37c41c7747a3 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -311,7 +311,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR); + ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 2a87901673fe..c87e78f73234 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -375,7 +375,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, HWBLK_NR); + ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c index 1697642c1f73..deb683abacf0 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c @@ -260,7 +260,7 @@ int __init arch_clk_init(void) &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index 04ab5aeaf920..e84a43229b9c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -148,7 +148,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index ab1c58f2d101..1c83788db76a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -175,7 +175,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 491709483e10..8bba6f159023 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -194,7 +194,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 0f11b392bf46..a9422dab0ce7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -149,7 +149,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); return ret; } -- GitLab From 4aceed37e315e8eaa26cb4c8dfd619a32fa24669 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 19 Jun 2012 14:39:52 +0200 Subject: [PATCH 3156/6849] HID: hid-multitouch: fix input mode feature command Zytronic panels shows a new way of setting the Input Mode feature. This feature is put in the second usage in the HID feature, instead of the first, as the majority of the multitouch devices. This patch adds a detection step when the feature is presented to know where the feature is located in the report. We can then trigger the right command to the device. This removes the magic number "0" in the function mt_set_input_mode. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 61cc4cbe0f3e..9a3891e00cdd 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -83,6 +83,7 @@ struct mt_device { unsigned last_field_index; /* last field index of the report */ unsigned last_slot_field; /* the last field of a slot */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ + __s8 inputmode_index; /* InputMode HID feature index in the report */ __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, -1 if non-existent */ __u8 num_received; /* how many contacts we received */ @@ -260,10 +261,20 @@ static void mt_feature_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { struct mt_device *td = hid_get_drvdata(hdev); + int i; switch (usage->hid) { case HID_DG_INPUTMODE: td->inputmode = field->report->id; + td->inputmode_index = 0; /* has to be updated below */ + + for (i=0; i < field->maxusage; i++) { + if (field->usage[i].hid == usage->hid) { + td->inputmode_index = i; + break; + } + } + break; case HID_DG_CONTACTMAX: td->maxcontact_report_id = field->report->id; @@ -618,7 +629,7 @@ static void mt_set_input_mode(struct hid_device *hdev) re = &(hdev->report_enum[HID_FEATURE_REPORT]); r = re->report_id_hash[td->inputmode]; if (r) { - r->field[0]->value[0] = 0x02; + r->field[0]->value[td->inputmode_index] = 0x02; usbhid_submit_report(hdev, r, USB_DIR_OUT); } } -- GitLab From 82d069822feaf9bf7eb85d5c9ba9a123ecc8f15f Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 19 Jun 2012 14:39:54 +0200 Subject: [PATCH 3157/6849] HID: hid-multitouch: add support for Zytronic panels Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-multitouch.c | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e9c68fedfcff..bcaf3fa79e93 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -393,6 +393,7 @@ config HID_MULTITOUCH - Unitec Panels - XAT optical touch panels - Xiroku optical touch panels + - Zytronic touch panels If unsure, say N. diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 734a2b986502..c77bfdde94ed 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -802,6 +802,9 @@ #define USB_VENDOR_ID_ZYDACRON 0x13EC #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 +#define USB_VENDOR_ID_ZYTRONIC 0x14c8 +#define USB_DEVICE_ID_ZYTRONIC_ZXY100 0x0005 + #define USB_VENDOR_ID_PRIMAX 0x0461 #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 9a3891e00cdd..59c8b5c1d2de 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1064,6 +1064,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) }, + /* Zytronic panels */ + { .driver_data = MT_CLS_SERIAL, + MT_USB_DEVICE(USB_VENDOR_ID_ZYTRONIC, + USB_DEVICE_ID_ZYTRONIC_ZXY100) }, + /* Generic MT device */ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, { } -- GitLab From 6a2a6390cf098b899a30146ef5c1fb85c9fefb3c Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 20 May 2012 22:44:54 +0200 Subject: [PATCH 3158/6849] HID: roccat: add support for Roccat Savu This patch adds rupport for Roccat Savu gaming mouse. In comparison to the other Roccat modules I tried to move even more functionality to userland. Userland tools can soon be found at http://sourceforge.net/projects/roccat Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- .../ABI/testing/sysfs-driver-hid-roccat-savu | 68 ++++ drivers/hid/Makefile | 3 +- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-roccat-savu.c | 357 ++++++++++++++++++ drivers/hid/hid-roccat-savu.h | 103 +++++ 6 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-roccat-savu create mode 100644 drivers/hid/hid-roccat-savu.c create mode 100644 drivers/hid/hid-roccat-savu.h diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu new file mode 100644 index 000000000000..e23349001288 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu @@ -0,0 +1,68 @@ +What: /sys/bus/usb/devices/-:./::./savu/roccatsavu/buttons +Date: Mai 2012 +Contact: Stefan Achatz +Description: The mouse can store 5 profiles which can be switched by the + press of a button. A profile is split into general settings and + button settings. buttons holds informations about button layout. + When written, this file lets one write the respective profile + buttons to the mouse. The data has to be 47 bytes long. + The mouse will reject invalid data. + Which profile to write is determined by the profile number + contained in the data. + Before reading this file, control has to be written to select + which profile to read. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./savu/roccatsavu/control +Date: Mai 2012 +Contact: Stefan Achatz +Description: When written, this file lets one select which data from which + profile will be read next. The data has to be 3 bytes long. + This file is writeonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./savu/roccatsavu/general +Date: Mai 2012 +Contact: Stefan Achatz +Description: The mouse can store 5 profiles which can be switched by the + press of a button. A profile is split into general settings and + button settings. profile holds informations like resolution, sensitivity + and light effects. + When written, this file lets one write the respective profile + settings back to the mouse. The data has to be 43 bytes long. + The mouse will reject invalid data. + Which profile to write is determined by the profile number + contained in the data. + This file is writeonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./savu/roccatsavu/info +Date: Mai 2012 +Contact: Stefan Achatz +Description: When read, this file returns general data like firmware version. + The data is 8 bytes long. + This file is readonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./savu/roccatsavu/macro +Date: Mai 2012 +Contact: Stefan Achatz +Description: When written, this file lets one store macros with max 500 + keystrokes for a specific button for a specific profile. + Button and profile numbers are included in written data. + The data has to be 2083 bytes long. + Before reading this file, control has to be written to select + which profile and key to read. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./savu/roccatsavu/profile +Date: Mai 2012 +Contact: Stefan Achatz +Description: The mouse can store 5 profiles which can be switched by the + press of a button. profile holds number of actual profile. + This value is persistent, so its value determines the profile + that's active when the mouse is powered on next time. + When written, the mouse activates the set profile immediately. + The data has to be 3 bytes long. + The mouse will reject invalid data. +Users: http://roccat.sourceforge.net diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index ca6cc9f0485c..348b90404598 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -69,7 +69,8 @@ obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o obj-$(CONFIG_HID_PRIMAX) += hid-primax.o obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ - hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o + hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \ + hid-roccat-savu.o obj-$(CONFIG_HID_SAITEK) += hid-saitek.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6ac0286b5375..fd95df8d1e07 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1617,6 +1617,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index d1cdd2d28409..ddc293d827f2 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -644,6 +644,7 @@ #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 +#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c new file mode 100644 index 000000000000..d6c82d57408a --- /dev/null +++ b/drivers/hid/hid-roccat-savu.c @@ -0,0 +1,357 @@ +/* + * Roccat Savu driver for Linux + * + * Copyright (c) 2012 Stefan Achatz + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +/* Roccat Savu is a gamer mouse with macro keys that can be configured in + * 5 profiles. + */ + +#include +#include +#include +#include +#include +#include +#include "hid-ids.h" +#include "hid-roccat-common.h" +#include "hid-roccat-savu.h" + +static struct class *savu_class; + +static int savu_receive_control_status(struct usb_device *usb_dev) +{ + int retval; + struct savu_control control; + + do { + msleep(50); + retval = roccat_common_receive(usb_dev, SAVU_COMMAND_CONTROL, + &control, sizeof(struct savu_control)); + + if (retval) + return retval; + + switch (control.value) { + case SAVU_CONTROL_REQUEST_WRITE_CHECK_OK: + return 0; + case SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT: + continue; + case SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID: + /* seems to be critical - replug necessary */ + case SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD: + return -EINVAL; + default: + hid_err(usb_dev, "savu_receive_control_status: " + "unknown response value 0x%x\n", + control.value); + return -EINVAL; + } + + } while (1); +} + +static int savu_send(struct usb_device *usb_dev, uint command, + void const *buf, uint size) +{ + int retval; + + retval = roccat_common_send(usb_dev, command, buf, size); + if (retval) + return retval; + + return savu_receive_control_status(usb_dev); +} + +static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, + char *buf, loff_t off, size_t count, + size_t real_size, uint command) +{ + struct device *dev = + container_of(kobj, struct device, kobj)->parent->parent; + struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); + int retval; + + if (off >= real_size) + return 0; + + if (off != 0 || count != real_size) + return -EINVAL; + + mutex_lock(&savu->savu_lock); + retval = roccat_common_receive(usb_dev, command, buf, real_size); + mutex_unlock(&savu->savu_lock); + + return retval ? retval : real_size; +} + +static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj, + void const *buf, loff_t off, size_t count, + size_t real_size, uint command) +{ + struct device *dev = + container_of(kobj, struct device, kobj)->parent->parent; + struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); + int retval; + + if (off != 0 || count != real_size) + return -EINVAL; + + mutex_lock(&savu->savu_lock); + retval = savu_send(usb_dev, command, (void *)buf, real_size); + mutex_unlock(&savu->savu_lock); + + return retval ? retval : real_size; +} + +#define SAVU_SYSFS_W(thingy, THINGY) \ +static ssize_t savu_sysfs_write_ ## thingy(struct file *fp, \ + struct kobject *kobj, struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + return savu_sysfs_write(fp, kobj, buf, off, count, \ + SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \ +} + +#define SAVU_SYSFS_R(thingy, THINGY) \ +static ssize_t savu_sysfs_read_ ## thingy(struct file *fp, \ + struct kobject *kobj, struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + return savu_sysfs_read(fp, kobj, buf, off, count, \ + SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \ +} + +#define SAVU_SYSFS_RW(thingy, THINGY) \ +SAVU_SYSFS_W(thingy, THINGY) \ +SAVU_SYSFS_R(thingy, THINGY) + +#define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \ +{ \ + .attr = { .name = #thingy, .mode = 0660 }, \ + .size = SAVU_SIZE_ ## THINGY, \ + .read = savu_sysfs_read_ ## thingy, \ + .write = savu_sysfs_write_ ## thingy \ +} + +#define SAVU_BIN_ATTRIBUTE_R(thingy, THINGY) \ +{ \ + .attr = { .name = #thingy, .mode = 0440 }, \ + .size = SAVU_SIZE_ ## THINGY, \ + .read = savu_sysfs_read_ ## thingy, \ +} + +#define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \ +{ \ + .attr = { .name = #thingy, .mode = 0220 }, \ + .size = SAVU_SIZE_ ## THINGY, \ + .write = savu_sysfs_write_ ## thingy \ +} + +SAVU_SYSFS_W(control, CONTROL) +SAVU_SYSFS_RW(profile, PROFILE) +SAVU_SYSFS_RW(general, GENERAL) +SAVU_SYSFS_RW(buttons, BUTTONS) +SAVU_SYSFS_RW(macro, MACRO) +SAVU_SYSFS_R(info, INFO) + +static struct bin_attribute savu_bin_attributes[] = { + SAVU_BIN_ATTRIBUTE_W(control, CONTROL), + SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE), + SAVU_BIN_ATTRIBUTE_RW(general, GENERAL), + SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS), + SAVU_BIN_ATTRIBUTE_RW(macro, MACRO), + SAVU_BIN_ATTRIBUTE_R(info, INFO), + __ATTR_NULL +}; + +static int savu_init_savu_device_struct(struct usb_device *usb_dev, + struct savu_device *savu) +{ + mutex_init(&savu->savu_lock); + + return 0; +} + +static int savu_init_specials(struct hid_device *hdev) +{ + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct savu_device *savu; + int retval; + + if (intf->cur_altsetting->desc.bInterfaceProtocol + != USB_INTERFACE_PROTOCOL_MOUSE) { + hid_set_drvdata(hdev, NULL); + return 0; + } + + savu = kzalloc(sizeof(*savu), GFP_KERNEL); + if (!savu) { + hid_err(hdev, "can't alloc device descriptor\n"); + return -ENOMEM; + } + hid_set_drvdata(hdev, savu); + + retval = savu_init_savu_device_struct(usb_dev, savu); + if (retval) { + hid_err(hdev, "couldn't init struct savu_device\n"); + goto exit_free; + } + + retval = roccat_connect(savu_class, hdev, + sizeof(struct savu_roccat_report)); + if (retval < 0) { + hid_err(hdev, "couldn't init char dev\n"); + } else { + savu->chrdev_minor = retval; + savu->roccat_claimed = 1; + } + + return 0; +exit_free: + kfree(savu); + return retval; +} + +static void savu_remove_specials(struct hid_device *hdev) +{ + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct savu_device *savu; + + if (intf->cur_altsetting->desc.bInterfaceProtocol + != USB_INTERFACE_PROTOCOL_MOUSE) + return; + + savu = hid_get_drvdata(hdev); + if (savu->roccat_claimed) + roccat_disconnect(savu->chrdev_minor); + kfree(savu); +} + +static int savu_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int retval; + + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); + goto exit; + } + + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (retval) { + hid_err(hdev, "hw start failed\n"); + goto exit; + } + + retval = savu_init_specials(hdev); + if (retval) { + hid_err(hdev, "couldn't install mouse\n"); + goto exit_stop; + } + + return 0; + +exit_stop: + hid_hw_stop(hdev); +exit: + return retval; +} + +static void savu_remove(struct hid_device *hdev) +{ + savu_remove_specials(hdev); + hid_hw_stop(hdev); +} + +static void savu_report_to_chrdev(struct savu_device const *savu, + u8 const *data) +{ + struct savu_roccat_report roccat_report; + struct savu_mouse_report_special const *special_report; + + if (data[0] != SAVU_MOUSE_REPORT_NUMBER_SPECIAL) + return; + + special_report = (struct savu_mouse_report_special const *)data; + + roccat_report.type = special_report->type; + roccat_report.data[0] = special_report->data[0]; + roccat_report.data[1] = special_report->data[1]; + roccat_report_event(savu->chrdev_minor, + (uint8_t const *)&roccat_report); +} + +static int savu_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) +{ + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct savu_device *savu = hid_get_drvdata(hdev); + + if (intf->cur_altsetting->desc.bInterfaceProtocol + != USB_INTERFACE_PROTOCOL_MOUSE) + return 0; + + if (savu == NULL) + return 0; + + if (savu->roccat_claimed) + savu_report_to_chrdev(savu, data); + + return 0; +} + +static const struct hid_device_id savu_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, + { } +}; + +MODULE_DEVICE_TABLE(hid, savu_devices); + +static struct hid_driver savu_driver = { + .name = "savu", + .id_table = savu_devices, + .probe = savu_probe, + .remove = savu_remove, + .raw_event = savu_raw_event +}; + +static int __init savu_init(void) +{ + int retval; + + savu_class = class_create(THIS_MODULE, "savu"); + if (IS_ERR(savu_class)) + return PTR_ERR(savu_class); + savu_class->dev_bin_attrs = savu_bin_attributes; + + retval = hid_register_driver(&savu_driver); + if (retval) + class_destroy(savu_class); + return retval; +} + +static void __exit savu_exit(void) +{ + hid_unregister_driver(&savu_driver); + class_destroy(savu_class); +} + +module_init(savu_init); +module_exit(savu_exit); + +MODULE_AUTHOR("Stefan Achatz"); +MODULE_DESCRIPTION("USB Roccat Savu driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h new file mode 100644 index 000000000000..97b43d5b0477 --- /dev/null +++ b/drivers/hid/hid-roccat-savu.h @@ -0,0 +1,103 @@ +#ifndef __HID_ROCCAT_SAVU_H +#define __HID_ROCCAT_SAVU_H + +/* + * Copyright (c) 2012 Stefan Achatz + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include + +enum { + SAVU_SIZE_CONTROL = 0x03, + SAVU_SIZE_PROFILE = 0x03, + SAVU_SIZE_GENERAL = 0x10, + SAVU_SIZE_BUTTONS = 0x2f, + SAVU_SIZE_MACRO = 0x0823, + SAVU_SIZE_INFO = 0x08, +}; + +struct savu_control { + uint8_t command; /* SAVU_COMMAND_CONTROL */ + /* + * value is profile number in range 0-4 for requesting settings and buttons + * 1 if status ok for requesting status + */ + uint8_t value; + uint8_t request; +} __packed; + +enum savu_control_requests { + SAVU_CONTROL_REQUEST_WRITE_CHECK = 0x00, + SAVU_CONTROL_REQUEST_GENERAL = 0x80, + SAVU_CONTROL_REQUEST_BUTTONS = 0x90, +}; + +enum savu_control_values { + SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD = 0, + SAVU_CONTROL_REQUEST_WRITE_CHECK_OK = 1, + SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID = 2, + SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT = 3, +}; + +enum savu_commands { + SAVU_COMMAND_CONTROL = 0x4, + SAVU_COMMAND_PROFILE = 0x5, + SAVU_COMMAND_GENERAL = 0x6, + SAVU_COMMAND_BUTTONS = 0x7, + SAVU_COMMAND_MACRO = 0x8, + SAVU_COMMAND_INFO = 0x9, +}; + +struct savu_mouse_report_special { + uint8_t report_number; /* always 3 */ + uint8_t zero; + uint8_t type; + uint8_t data[2]; +} __packed; + +enum { + SAVU_MOUSE_REPORT_NUMBER_SPECIAL = 3, +}; + +enum savu_mouse_report_button_types { + /* data1 = new profile range 1-5 */ + SAVU_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20, + + /* data1 = button number range 1-24; data2 = action */ + SAVU_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60, + + /* data1 = button number range 1-24; data2 = action */ + SAVU_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80, + + /* data1 = setting number range 1-5 */ + SAVU_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0, + + /* data1 and data2 = range 0x1-0xb */ + SAVU_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0, + + /* data1 = 22 = next track... + * data2 = action + */ + SAVU_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0, +}; + +struct savu_roccat_report { + uint8_t type; + uint8_t data[2]; +} __packed; + +struct savu_device { + int roccat_claimed; + int chrdev_minor; + + struct mutex savu_lock; +}; + +#endif -- GitLab From 4728f2dc9f8e32ce898223fb863316ed7fa2d224 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 20 May 2012 22:44:59 +0200 Subject: [PATCH 3159/6849] HID: roccat: move functionality to roccat-common Reduced code duplication by moving functions from individual drivers to roccat-common module. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-common.c | 58 ++++++++++++++++++++ drivers/hid/hid-roccat-common.h | 12 +++++ drivers/hid/hid-roccat-isku.c | 50 ++---------------- drivers/hid/hid-roccat-isku.h | 7 --- drivers/hid/hid-roccat-koneplus.c | 88 ++++++------------------------- drivers/hid/hid-roccat-koneplus.h | 22 -------- drivers/hid/hid-roccat-kovaplus.c | 63 ++++------------------ drivers/hid/hid-roccat-kovaplus.h | 15 ------ drivers/hid/hid-roccat-pyra.c | 51 ++++-------------- drivers/hid/hid-roccat-pyra.h | 12 ----- drivers/hid/hid-roccat-savu.c | 47 +---------------- drivers/hid/hid-roccat-savu.h | 18 ------- 12 files changed, 111 insertions(+), 332 deletions(-) diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c index a6d93992c75a..291414eac279 100644 --- a/drivers/hid/hid-roccat-common.c +++ b/drivers/hid/hid-roccat-common.c @@ -64,6 +64,64 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id, } EXPORT_SYMBOL_GPL(roccat_common_send); +enum roccat_common_control_states { + ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0, + ROCCAT_COMMON_CONTROL_STATUS_OK = 1, + ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2, + ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3, +}; + +static int roccat_common_receive_control_status(struct usb_device *usb_dev) +{ + int retval; + struct roccat_common_control control; + + do { + msleep(50); + retval = roccat_common_receive(usb_dev, + ROCCAT_COMMON_COMMAND_CONTROL, + &control, sizeof(struct roccat_common_control)); + + if (retval) + return retval; + + switch (control.value) { + case ROCCAT_COMMON_CONTROL_STATUS_OK: + return 0; + case ROCCAT_COMMON_CONTROL_STATUS_WAIT: + msleep(500); + continue; + case ROCCAT_COMMON_CONTROL_STATUS_INVALID: + + case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD: + /* seems to be critical - replug necessary */ + return -EINVAL; + default: + dev_err(&usb_dev->dev, + "roccat_common_receive_control_status: " + "unknown response value 0x%x\n", + control.value); + return -EINVAL; + } + + } while (1); +} + +int roccat_common_send_with_status(struct usb_device *usb_dev, + uint command, void const *buf, uint size) +{ + int retval; + + retval = roccat_common_send(usb_dev, command, buf, size); + if (retval) + return retval; + + msleep(100); + + return roccat_common_receive_control_status(usb_dev); +} +EXPORT_SYMBOL_GPL(roccat_common_send_with_status); + MODULE_AUTHOR("Stefan Achatz"); MODULE_DESCRIPTION("USB Roccat common driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h index 9a5bc61f9699..86bce05da013 100644 --- a/drivers/hid/hid-roccat-common.h +++ b/drivers/hid/hid-roccat-common.h @@ -15,9 +15,21 @@ #include #include +enum roccat_common_commands { + ROCCAT_COMMON_COMMAND_CONTROL = 0x4, +}; + +struct roccat_common_control { + uint8_t command; + uint8_t value; + uint8_t request; /* always 0 on requesting write check */ +} __packed; + int roccat_common_receive(struct usb_device *usb_dev, uint report_id, void *data, uint size); int roccat_common_send(struct usb_device *usb_dev, uint report_id, void const *data, uint size); +int roccat_common_send_with_status(struct usb_device *usb_dev, + uint command, void const *buf, uint size); #endif diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 0e4a0ab47142..20e7f84ee832 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -39,50 +39,6 @@ static int isku_receive(struct usb_device *usb_dev, uint command, return roccat_common_receive(usb_dev, command, buf, size); } -static int isku_receive_control_status(struct usb_device *usb_dev) -{ - int retval; - struct isku_control control; - - do { - msleep(50); - retval = isku_receive(usb_dev, ISKU_COMMAND_CONTROL, - &control, sizeof(struct isku_control)); - - if (retval) - return retval; - - switch (control.value) { - case ISKU_CONTROL_VALUE_STATUS_OK: - return 0; - case ISKU_CONTROL_VALUE_STATUS_WAIT: - continue; - case ISKU_CONTROL_VALUE_STATUS_INVALID: - /* seems to be critical - replug necessary */ - case ISKU_CONTROL_VALUE_STATUS_OVERLOAD: - return -EINVAL; - default: - hid_err(usb_dev, "isku_receive_control_status: " - "unknown response value 0x%x\n", - control.value); - return -EINVAL; - } - - } while (1); -} - -static int isku_send(struct usb_device *usb_dev, uint command, - void const *buf, uint size) -{ - int retval; - - retval = roccat_common_send(usb_dev, command, buf, size); - if (retval) - return retval; - - return isku_receive_control_status(usb_dev); -} - static int isku_get_actual_profile(struct usb_device *usb_dev) { struct isku_actual_profile buf; @@ -100,7 +56,8 @@ static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile) buf.command = ISKU_COMMAND_ACTUAL_PROFILE; buf.size = sizeof(struct isku_actual_profile); buf.actual_profile = new_profile; - return isku_send(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE, &buf, + return roccat_common_send_with_status(usb_dev, + ISKU_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct isku_actual_profile)); } @@ -197,7 +154,8 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&isku->isku_lock); - retval = isku_send(usb_dev, command, (void *)buf, real_size); + retval = roccat_common_send_with_status(usb_dev, command, + (void *)buf, real_size); mutex_unlock(&isku->isku_lock); return retval ? retval : real_size; diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h index 075f6efaec58..605b3ce21638 100644 --- a/drivers/hid/hid-roccat-isku.h +++ b/drivers/hid/hid-roccat-isku.h @@ -25,13 +25,6 @@ struct isku_control { uint8_t request; } __packed; -enum isku_control_values { - ISKU_CONTROL_VALUE_STATUS_OVERLOAD = 0, - ISKU_CONTROL_VALUE_STATUS_OK = 1, - ISKU_CONTROL_VALUE_STATUS_INVALID = 2, - ISKU_CONTROL_VALUE_STATUS_WAIT = 3, -}; - struct isku_actual_profile { uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ uint8_t size; /* always 3 */ diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 59e47770fa10..01167a831258 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -39,82 +39,20 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus, static int koneplus_send_control(struct usb_device *usb_dev, uint value, enum koneplus_control_requests request) { - struct koneplus_control control; + struct roccat_common_control control; if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && value > 4) return -EINVAL; - control.command = KONEPLUS_COMMAND_CONTROL; + control.command = ROCCAT_COMMON_COMMAND_CONTROL; control.value = value; control.request = request; - return roccat_common_send(usb_dev, KONEPLUS_COMMAND_CONTROL, - &control, sizeof(struct koneplus_control)); -} - -static int koneplus_receive_control_status(struct usb_device *usb_dev) -{ - int retval; - struct koneplus_control control; - - do { - retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_CONTROL, - &control, sizeof(struct koneplus_control)); - - /* check if we get a completely wrong answer */ - if (retval) - return retval; - - if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) - return 0; - - /* indicates that hardware needs some more time to complete action */ - if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) { - msleep(500); /* windows driver uses 1000 */ - continue; - } - - /* seems to be critical - replug necessary */ - if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) - return -EINVAL; - - hid_err(usb_dev, "koneplus_receive_control_status: " - "unknown response value 0x%x\n", control.value); - return -EINVAL; - } while (1); -} - -static int koneplus_send(struct usb_device *usb_dev, uint command, - void const *buf, uint size) -{ - int retval; - - retval = roccat_common_send(usb_dev, command, buf, size); - if (retval) - return retval; - - return koneplus_receive_control_status(usb_dev); -} - -static int koneplus_select_profile(struct usb_device *usb_dev, uint number, - enum koneplus_control_requests request) -{ - int retval; - - retval = koneplus_send_control(usb_dev, number, request); - if (retval) - return retval; - - /* allow time to settle things - windows driver uses 500 */ - msleep(100); - - retval = koneplus_receive_control_status(usb_dev); - if (retval) - return retval; - - return 0; + return roccat_common_send_with_status(usb_dev, + ROCCAT_COMMON_COMMAND_CONTROL, + &control, sizeof(struct roccat_common_control)); } static int koneplus_get_info(struct usb_device *usb_dev, @@ -129,7 +67,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev, { int retval; - retval = koneplus_select_profile(usb_dev, number, + retval = koneplus_send_control(usb_dev, number, KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); if (retval) return retval; @@ -141,7 +79,8 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev, static int koneplus_set_profile_settings(struct usb_device *usb_dev, struct koneplus_profile_settings const *settings) { - return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, + return roccat_common_send_with_status(usb_dev, + KONEPLUS_COMMAND_PROFILE_SETTINGS, settings, sizeof(struct koneplus_profile_settings)); } @@ -150,7 +89,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, { int retval; - retval = koneplus_select_profile(usb_dev, number, + retval = koneplus_send_control(usb_dev, number, KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); if (retval) return retval; @@ -162,7 +101,8 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, static int koneplus_set_profile_buttons(struct usb_device *usb_dev, struct koneplus_profile_buttons const *buttons) { - return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, + return roccat_common_send_with_status(usb_dev, + KONEPLUS_COMMAND_PROFILE_BUTTONS, buttons, sizeof(struct koneplus_profile_buttons)); } @@ -187,7 +127,8 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev, buf.size = sizeof(struct koneplus_actual_profile); buf.actual_profile = new_profile; - return koneplus_send(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, + return roccat_common_send_with_status(usb_dev, + KONEPLUS_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct koneplus_actual_profile)); } @@ -231,7 +172,8 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&koneplus->koneplus_lock); - retval = koneplus_send(usb_dev, command, buf, real_size); + retval = roccat_common_send_with_status(usb_dev, command, + buf, real_size); mutex_unlock(&koneplus->koneplus_lock); if (retval) diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h index c03332a4fa9a..7074b2a4b94b 100644 --- a/drivers/hid/hid-roccat-koneplus.h +++ b/drivers/hid/hid-roccat-koneplus.h @@ -20,32 +20,11 @@ struct koneplus_talk { uint8_t data[14]; } __packed; -/* - * case 1: writes request 80 and reads value 1 - * - */ -struct koneplus_control { - uint8_t command; /* KONEPLUS_COMMAND_CONTROL */ - /* - * value is profile number in range 0-4 for requesting settings and buttons - * 1 if status ok for requesting status - */ - uint8_t value; - uint8_t request; -} __attribute__ ((__packed__)); - enum koneplus_control_requests { - KONEPLUS_CONTROL_REQUEST_STATUS = 0x00, KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90, }; -enum koneplus_control_values { - KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, - KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1, - KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, -}; - struct koneplus_actual_profile { uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ uint8_t size; /* always 3 */ @@ -137,7 +116,6 @@ struct koneplus_tcu_image { } __attribute__ ((__packed__)); enum koneplus_commands { - KONEPLUS_COMMAND_CONTROL = 0x4, KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 112d934132c8..c219cff91555 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -47,69 +47,23 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value, enum kovaplus_control_requests request) { int retval; - struct kovaplus_control control; + struct roccat_common_control control; if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && value > 4) return -EINVAL; - control.command = KOVAPLUS_COMMAND_CONTROL; + control.command = ROCCAT_COMMON_COMMAND_CONTROL; control.value = value; control.request = request; - retval = roccat_common_send(usb_dev, KOVAPLUS_COMMAND_CONTROL, - &control, sizeof(struct kovaplus_control)); + retval = roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, + &control, sizeof(struct roccat_common_control)); return retval; } -static int kovaplus_receive_control_status(struct usb_device *usb_dev) -{ - int retval; - struct kovaplus_control control; - - do { - retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_CONTROL, - &control, sizeof(struct kovaplus_control)); - - /* check if we get a completely wrong answer */ - if (retval) - return retval; - - if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OK) - return 0; - - /* indicates that hardware needs some more time to complete action */ - if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT) { - msleep(500); /* windows driver uses 1000 */ - continue; - } - - /* seems to be critical - replug necessary */ - if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) - return -EINVAL; - - hid_err(usb_dev, "roccat_common_receive_control_status: " - "unknown response value 0x%x\n", control.value); - return -EINVAL; - } while (1); -} - -static int kovaplus_send(struct usb_device *usb_dev, uint command, - void const *buf, uint size) -{ - int retval; - - retval = roccat_common_send(usb_dev, command, buf, size); - if (retval) - return retval; - - msleep(100); - - return kovaplus_receive_control_status(usb_dev); -} - static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, enum kovaplus_control_requests request) { @@ -140,7 +94,8 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev, static int kovaplus_set_profile_settings(struct usb_device *usb_dev, struct kovaplus_profile_settings const *settings) { - return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, + return roccat_common_send_with_status(usb_dev, + KOVAPLUS_COMMAND_PROFILE_SETTINGS, settings, sizeof(struct kovaplus_profile_settings)); } @@ -161,7 +116,8 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, struct kovaplus_profile_buttons const *buttons) { - return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, + return roccat_common_send_with_status(usb_dev, + KOVAPLUS_COMMAND_PROFILE_BUTTONS, buttons, sizeof(struct kovaplus_profile_buttons)); } @@ -186,7 +142,8 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev, buf.size = sizeof(struct kovaplus_actual_profile); buf.actual_profile = new_profile; - return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, + return roccat_common_send_with_status(usb_dev, + KOVAPLUS_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct kovaplus_actual_profile)); } diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h index fb2aed44a8e0..f82daa1cdcb9 100644 --- a/drivers/hid/hid-roccat-kovaplus.h +++ b/drivers/hid/hid-roccat-kovaplus.h @@ -14,27 +14,13 @@ #include -struct kovaplus_control { - uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */ - uint8_t value; - uint8_t request; -} __packed; - enum kovaplus_control_requests { - /* read after write; value = 1 */ - KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0, /* write; value = profile number range 0-4 */ KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, /* write; value = profile number range 0-4 */ KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20, }; -enum kovaplus_control_values { - KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, /* supposed */ - KOVAPLUS_CONTROL_REQUEST_STATUS_OK = 1, - KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, /* supposed */ -}; - struct kovaplus_actual_profile { uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */ uint8_t size; /* always 3 */ @@ -75,7 +61,6 @@ struct kovaplus_a { } __packed; enum kovaplus_commands { - KOVAPLUS_COMMAND_CONTROL = 0x4, KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index df05c1b1064f..440cb1bd70d4 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -42,43 +42,19 @@ static void profile_activated(struct pyra_device *pyra, static int pyra_send_control(struct usb_device *usb_dev, int value, enum pyra_control_requests request) { - struct pyra_control control; + struct roccat_common_control control; if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && (value < 0 || value > 4)) return -EINVAL; - control.command = PYRA_COMMAND_CONTROL; + control.command = ROCCAT_COMMON_COMMAND_CONTROL; control.value = value; control.request = request; - return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL, - &control, sizeof(struct pyra_control)); -} - -static int pyra_receive_control_status(struct usb_device *usb_dev) -{ - int retval; - struct pyra_control control; - - do { - msleep(10); - retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL, - &control, sizeof(struct pyra_control)); - - /* requested too early, try again */ - } while (retval == -EPROTO); - - if (!retval && control.command == PYRA_COMMAND_CONTROL && - control.request == PYRA_CONTROL_REQUEST_STATUS && - control.value == 1) - return 0; - else { - hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n", - control.request, control.value); - return retval ? retval : -EINVAL; - } + return roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, + &control, sizeof(struct roccat_common_control)); } static int pyra_get_profile_settings(struct usb_device *usb_dev, @@ -118,34 +94,27 @@ static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) buf, sizeof(struct pyra_info)); } -static int pyra_send(struct usb_device *usb_dev, uint command, - void const *buf, uint size) -{ - int retval; - retval = roccat_common_send(usb_dev, command, buf, size); - if (retval) - return retval; - return pyra_receive_control_status(usb_dev); -} - static int pyra_set_profile_settings(struct usb_device *usb_dev, struct pyra_profile_settings const *settings) { - return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings, + return roccat_common_send_with_status(usb_dev, + PYRA_COMMAND_PROFILE_SETTINGS, settings, sizeof(struct pyra_profile_settings)); } static int pyra_set_profile_buttons(struct usb_device *usb_dev, struct pyra_profile_buttons const *buttons) { - return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons, + return roccat_common_send_with_status(usb_dev, + PYRA_COMMAND_PROFILE_BUTTONS, buttons, sizeof(struct pyra_profile_buttons)); } static int pyra_set_settings(struct usb_device *usb_dev, struct pyra_settings const *settings) { - return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings, + return roccat_common_send_with_status(usb_dev, + PYRA_COMMAND_SETTINGS, settings, sizeof(struct pyra_settings)); } diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h index 0442d7fa2dcf..eada7830fa99 100644 --- a/drivers/hid/hid-roccat-pyra.h +++ b/drivers/hid/hid-roccat-pyra.h @@ -20,18 +20,7 @@ struct pyra_b { uint8_t unknown; /* 1 */ } __attribute__ ((__packed__)); -struct pyra_control { - uint8_t command; /* PYRA_COMMAND_CONTROL */ - /* - * value is profile number for request_settings and request_buttons - * 1 if status ok for request_status - */ - uint8_t value; /* Range 0-4 */ - uint8_t request; -} __attribute__ ((__packed__)); - enum pyra_control_requests { - PYRA_CONTROL_REQUEST_STATUS = 0x00, PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20 }; @@ -75,7 +64,6 @@ struct pyra_info { } __attribute__ ((__packed__)); enum pyra_commands { - PYRA_COMMAND_CONTROL = 0x4, PYRA_COMMAND_SETTINGS = 0x5, PYRA_COMMAND_PROFILE_SETTINGS = 0x6, PYRA_COMMAND_PROFILE_BUTTONS = 0x7, diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index d6c82d57408a..19f9c47fc020 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c @@ -27,50 +27,6 @@ static struct class *savu_class; -static int savu_receive_control_status(struct usb_device *usb_dev) -{ - int retval; - struct savu_control control; - - do { - msleep(50); - retval = roccat_common_receive(usb_dev, SAVU_COMMAND_CONTROL, - &control, sizeof(struct savu_control)); - - if (retval) - return retval; - - switch (control.value) { - case SAVU_CONTROL_REQUEST_WRITE_CHECK_OK: - return 0; - case SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT: - continue; - case SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID: - /* seems to be critical - replug necessary */ - case SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD: - return -EINVAL; - default: - hid_err(usb_dev, "savu_receive_control_status: " - "unknown response value 0x%x\n", - control.value); - return -EINVAL; - } - - } while (1); -} - -static int savu_send(struct usb_device *usb_dev, uint command, - void const *buf, uint size) -{ - int retval; - - retval = roccat_common_send(usb_dev, command, buf, size); - if (retval) - return retval; - - return savu_receive_control_status(usb_dev); -} - static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, char *buf, loff_t off, size_t count, size_t real_size, uint command) @@ -108,7 +64,8 @@ static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&savu->savu_lock); - retval = savu_send(usb_dev, command, (void *)buf, real_size); + retval = roccat_common_send_with_status(usb_dev, command, + (void *)buf, real_size); mutex_unlock(&savu->savu_lock); return retval ? retval : real_size; diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h index 97b43d5b0477..b15a1bbb66fb 100644 --- a/drivers/hid/hid-roccat-savu.h +++ b/drivers/hid/hid-roccat-savu.h @@ -23,29 +23,11 @@ enum { SAVU_SIZE_INFO = 0x08, }; -struct savu_control { - uint8_t command; /* SAVU_COMMAND_CONTROL */ - /* - * value is profile number in range 0-4 for requesting settings and buttons - * 1 if status ok for requesting status - */ - uint8_t value; - uint8_t request; -} __packed; - enum savu_control_requests { - SAVU_CONTROL_REQUEST_WRITE_CHECK = 0x00, SAVU_CONTROL_REQUEST_GENERAL = 0x80, SAVU_CONTROL_REQUEST_BUTTONS = 0x90, }; -enum savu_control_values { - SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD = 0, - SAVU_CONTROL_REQUEST_WRITE_CHECK_OK = 1, - SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID = 2, - SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT = 3, -}; - enum savu_commands { SAVU_COMMAND_CONTROL = 0x4, SAVU_COMMAND_PROFILE = 0x5, -- GitLab From 4ec141ad4e470485803a98ddb250aa7df030e8df Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 20 May 2012 22:45:08 +0200 Subject: [PATCH 3160/6849] HID: roccat: fix wrong hid_err usage on struct usb_device Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 40090d602158..9ce2d0b615a4 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -138,7 +138,7 @@ static int kone_check_write(struct usb_device *usb_dev) return 0; /* unknown answer */ - hid_err(usb_dev, "got retval %d when checking write\n", data); + dev_err(&usb_dev->dev, "got retval %d when checking write\n", data); return -EIO; } @@ -503,7 +503,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, retval = kone_set_settings(usb_dev, &kone->settings); if (retval) { - hid_err(usb_dev, "couldn't set tcu state\n"); + dev_err(&usb_dev->dev, "couldn't set tcu state\n"); /* * try to reread valid settings into buffer overwriting * first error code @@ -519,7 +519,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, retval = size; exit_no_settings: - hid_err(usb_dev, "couldn't read settings\n"); + dev_err(&usb_dev->dev, "couldn't read settings\n"); exit_unlock: mutex_unlock(&kone->kone_lock); return retval; -- GitLab From 7392d73be2b3c907d65126f072c313215e1907b3 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 20 May 2012 22:45:04 +0200 Subject: [PATCH 3161/6849] HID: roccat: rename roccat_common functions to roccat_common2 Did this to illustrate my understanding of the firmware generations: Valo and Kone were 1st generation Arvo was externaly developed and lies in the middle All others until now are considered 2nd generation Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-arvo.c | 16 +++++++-------- drivers/hid/hid-roccat-common.c | 34 +++++++++++++++---------------- drivers/hid/hid-roccat-common.h | 10 ++++----- drivers/hid/hid-roccat-isku.c | 6 +++--- drivers/hid/hid-roccat-koneplus.c | 24 +++++++++++----------- drivers/hid/hid-roccat-kovaplus.c | 20 +++++++++--------- drivers/hid/hid-roccat-pyra.c | 20 +++++++++--------- drivers/hid/hid-roccat-savu.c | 4 ++-- 8 files changed, 67 insertions(+), 67 deletions(-) diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index 093bfad00b02..327f9b8ed1f4 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -39,7 +39,7 @@ static ssize_t arvo_sysfs_show_mode_key(struct device *dev, int retval; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_receive(usb_dev, ARVO_COMMAND_MODE_KEY, + retval = roccat_common2_receive(usb_dev, ARVO_COMMAND_MODE_KEY, &temp_buf, sizeof(struct arvo_mode_key)); mutex_unlock(&arvo->arvo_lock); if (retval) @@ -67,7 +67,7 @@ static ssize_t arvo_sysfs_set_mode_key(struct device *dev, temp_buf.state = state; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_send(usb_dev, ARVO_COMMAND_MODE_KEY, + retval = roccat_common2_send(usb_dev, ARVO_COMMAND_MODE_KEY, &temp_buf, sizeof(struct arvo_mode_key)); mutex_unlock(&arvo->arvo_lock); if (retval) @@ -87,7 +87,7 @@ static ssize_t arvo_sysfs_show_key_mask(struct device *dev, int retval; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_receive(usb_dev, ARVO_COMMAND_KEY_MASK, + retval = roccat_common2_receive(usb_dev, ARVO_COMMAND_KEY_MASK, &temp_buf, sizeof(struct arvo_key_mask)); mutex_unlock(&arvo->arvo_lock); if (retval) @@ -115,7 +115,7 @@ static ssize_t arvo_sysfs_set_key_mask(struct device *dev, temp_buf.key_mask = key_mask; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_send(usb_dev, ARVO_COMMAND_KEY_MASK, + retval = roccat_common2_send(usb_dev, ARVO_COMMAND_KEY_MASK, &temp_buf, sizeof(struct arvo_key_mask)); mutex_unlock(&arvo->arvo_lock); if (retval) @@ -130,7 +130,7 @@ static int arvo_get_actual_profile(struct usb_device *usb_dev) struct arvo_actual_profile temp_buf; int retval; - retval = roccat_common_receive(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE, + retval = roccat_common2_receive(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE, &temp_buf, sizeof(struct arvo_actual_profile)); if (retval) @@ -170,7 +170,7 @@ static ssize_t arvo_sysfs_set_actual_profile(struct device *dev, temp_buf.actual_profile = profile; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_send(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE, + retval = roccat_common2_send(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE, &temp_buf, sizeof(struct arvo_actual_profile)); if (!retval) { arvo->actual_profile = profile; @@ -194,7 +194,7 @@ static ssize_t arvo_sysfs_write(struct file *fp, return -EINVAL; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_send(usb_dev, command, buf, real_size); + retval = roccat_common2_send(usb_dev, command, buf, real_size); mutex_unlock(&arvo->arvo_lock); return (retval ? retval : real_size); @@ -217,7 +217,7 @@ static ssize_t arvo_sysfs_read(struct file *fp, return -EINVAL; mutex_lock(&arvo->arvo_lock); - retval = roccat_common_receive(usb_dev, command, buf, real_size); + retval = roccat_common2_receive(usb_dev, command, buf, real_size); mutex_unlock(&arvo->arvo_lock); return (retval ? retval : real_size); diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c index 291414eac279..74f704032627 100644 --- a/drivers/hid/hid-roccat-common.c +++ b/drivers/hid/hid-roccat-common.c @@ -16,12 +16,12 @@ #include #include "hid-roccat-common.h" -static inline uint16_t roccat_common_feature_report(uint8_t report_id) +static inline uint16_t roccat_common2_feature_report(uint8_t report_id) { return 0x300 | report_id; } -int roccat_common_receive(struct usb_device *usb_dev, uint report_id, +int roccat_common2_receive(struct usb_device *usb_dev, uint report_id, void *data, uint size) { char *buf; @@ -34,16 +34,16 @@ int roccat_common_receive(struct usb_device *usb_dev, uint report_id, len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), HID_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - roccat_common_feature_report(report_id), + roccat_common2_feature_report(report_id), 0, buf, size, USB_CTRL_SET_TIMEOUT); memcpy(data, buf, size); kfree(buf); return ((len < 0) ? len : ((len != size) ? -EIO : 0)); } -EXPORT_SYMBOL_GPL(roccat_common_receive); +EXPORT_SYMBOL_GPL(roccat_common2_receive); -int roccat_common_send(struct usb_device *usb_dev, uint report_id, +int roccat_common2_send(struct usb_device *usb_dev, uint report_id, void const *data, uint size) { char *buf; @@ -56,31 +56,31 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id, len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - roccat_common_feature_report(report_id), + roccat_common2_feature_report(report_id), 0, buf, size, USB_CTRL_SET_TIMEOUT); kfree(buf); return ((len < 0) ? len : ((len != size) ? -EIO : 0)); } -EXPORT_SYMBOL_GPL(roccat_common_send); +EXPORT_SYMBOL_GPL(roccat_common2_send); -enum roccat_common_control_states { +enum roccat_common2_control_states { ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0, ROCCAT_COMMON_CONTROL_STATUS_OK = 1, ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2, ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3, }; -static int roccat_common_receive_control_status(struct usb_device *usb_dev) +static int roccat_common2_receive_control_status(struct usb_device *usb_dev) { int retval; - struct roccat_common_control control; + struct roccat_common2_control control; do { msleep(50); - retval = roccat_common_receive(usb_dev, + retval = roccat_common2_receive(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, - &control, sizeof(struct roccat_common_control)); + &control, sizeof(struct roccat_common2_control)); if (retval) return retval; @@ -98,7 +98,7 @@ static int roccat_common_receive_control_status(struct usb_device *usb_dev) return -EINVAL; default: dev_err(&usb_dev->dev, - "roccat_common_receive_control_status: " + "roccat_common2_receive_control_status: " "unknown response value 0x%x\n", control.value); return -EINVAL; @@ -107,20 +107,20 @@ static int roccat_common_receive_control_status(struct usb_device *usb_dev) } while (1); } -int roccat_common_send_with_status(struct usb_device *usb_dev, +int roccat_common2_send_with_status(struct usb_device *usb_dev, uint command, void const *buf, uint size) { int retval; - retval = roccat_common_send(usb_dev, command, buf, size); + retval = roccat_common2_send(usb_dev, command, buf, size); if (retval) return retval; msleep(100); - return roccat_common_receive_control_status(usb_dev); + return roccat_common2_receive_control_status(usb_dev); } -EXPORT_SYMBOL_GPL(roccat_common_send_with_status); +EXPORT_SYMBOL_GPL(roccat_common2_send_with_status); MODULE_AUTHOR("Stefan Achatz"); MODULE_DESCRIPTION("USB Roccat common driver"); diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h index 86bce05da013..a97746a63b70 100644 --- a/drivers/hid/hid-roccat-common.h +++ b/drivers/hid/hid-roccat-common.h @@ -15,21 +15,21 @@ #include #include -enum roccat_common_commands { +enum roccat_common2_commands { ROCCAT_COMMON_COMMAND_CONTROL = 0x4, }; -struct roccat_common_control { +struct roccat_common2_control { uint8_t command; uint8_t value; uint8_t request; /* always 0 on requesting write check */ } __packed; -int roccat_common_receive(struct usb_device *usb_dev, uint report_id, +int roccat_common2_receive(struct usb_device *usb_dev, uint report_id, void *data, uint size); -int roccat_common_send(struct usb_device *usb_dev, uint report_id, +int roccat_common2_send(struct usb_device *usb_dev, uint report_id, void const *data, uint size); -int roccat_common_send_with_status(struct usb_device *usb_dev, +int roccat_common2_send_with_status(struct usb_device *usb_dev, uint command, void const *buf, uint size); #endif diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 20e7f84ee832..5669916c2943 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -36,7 +36,7 @@ static void isku_profile_activated(struct isku_device *isku, uint new_profile) static int isku_receive(struct usb_device *usb_dev, uint command, void *buf, uint size) { - return roccat_common_receive(usb_dev, command, buf, size); + return roccat_common2_receive(usb_dev, command, buf, size); } static int isku_get_actual_profile(struct usb_device *usb_dev) @@ -56,7 +56,7 @@ static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile) buf.command = ISKU_COMMAND_ACTUAL_PROFILE; buf.size = sizeof(struct isku_actual_profile); buf.actual_profile = new_profile; - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct isku_actual_profile)); } @@ -154,7 +154,7 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&isku->isku_lock); - retval = roccat_common_send_with_status(usb_dev, command, + retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size); mutex_unlock(&isku->isku_lock); diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 01167a831258..f5602fec4865 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -39,7 +39,7 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus, static int koneplus_send_control(struct usb_device *usb_dev, uint value, enum koneplus_control_requests request) { - struct roccat_common_control control; + struct roccat_common2_control control; if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && @@ -50,15 +50,15 @@ static int koneplus_send_control(struct usb_device *usb_dev, uint value, control.value = value; control.request = request; - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, - &control, sizeof(struct roccat_common_control)); + &control, sizeof(struct roccat_common2_control)); } static int koneplus_get_info(struct usb_device *usb_dev, struct koneplus_info *buf) { - return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_INFO, + return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO, buf, sizeof(struct koneplus_info)); } @@ -72,14 +72,14 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev, if (retval) return retval; - return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, + return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, buf, sizeof(struct koneplus_profile_settings)); } static int koneplus_set_profile_settings(struct usb_device *usb_dev, struct koneplus_profile_settings const *settings) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, settings, sizeof(struct koneplus_profile_settings)); } @@ -94,14 +94,14 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, if (retval) return retval; - return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, + return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, buf, sizeof(struct koneplus_profile_buttons)); } static int koneplus_set_profile_buttons(struct usb_device *usb_dev, struct koneplus_profile_buttons const *buttons) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, buttons, sizeof(struct koneplus_profile_buttons)); } @@ -112,7 +112,7 @@ static int koneplus_get_actual_profile(struct usb_device *usb_dev) struct koneplus_actual_profile buf; int retval; - retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, + retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct koneplus_actual_profile)); return retval ? retval : buf.actual_profile; @@ -127,7 +127,7 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev, buf.size = sizeof(struct koneplus_actual_profile); buf.actual_profile = new_profile; - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct koneplus_actual_profile)); } @@ -149,7 +149,7 @@ static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&koneplus->koneplus_lock); - retval = roccat_common_receive(usb_dev, command, buf, real_size); + retval = roccat_common2_receive(usb_dev, command, buf, real_size); mutex_unlock(&koneplus->koneplus_lock); if (retval) @@ -172,7 +172,7 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&koneplus->koneplus_lock); - retval = roccat_common_send_with_status(usb_dev, command, + retval = roccat_common2_send_with_status(usb_dev, command, buf, real_size); mutex_unlock(&koneplus->koneplus_lock); diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index c219cff91555..ca6527ac655d 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -47,7 +47,7 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value, enum kovaplus_control_requests request) { int retval; - struct roccat_common_control control; + struct roccat_common2_control control; if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && @@ -58,8 +58,8 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value, control.value = value; control.request = request; - retval = roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, - &control, sizeof(struct roccat_common_control)); + retval = roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, + &control, sizeof(struct roccat_common2_control)); return retval; } @@ -73,7 +73,7 @@ static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, static int kovaplus_get_info(struct usb_device *usb_dev, struct kovaplus_info *buf) { - return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_INFO, + return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO, buf, sizeof(struct kovaplus_info)); } @@ -87,14 +87,14 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev, if (retval) return retval; - return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, + return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, buf, sizeof(struct kovaplus_profile_settings)); } static int kovaplus_set_profile_settings(struct usb_device *usb_dev, struct kovaplus_profile_settings const *settings) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, settings, sizeof(struct kovaplus_profile_settings)); } @@ -109,14 +109,14 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, if (retval) return retval; - return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, + return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, buf, sizeof(struct kovaplus_profile_buttons)); } static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, struct kovaplus_profile_buttons const *buttons) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, buttons, sizeof(struct kovaplus_profile_buttons)); } @@ -127,7 +127,7 @@ static int kovaplus_get_actual_profile(struct usb_device *usb_dev) struct kovaplus_actual_profile buf; int retval; - retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, + retval = roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct kovaplus_actual_profile)); return retval ? retval : buf.actual_profile; @@ -142,7 +142,7 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev, buf.size = sizeof(struct kovaplus_actual_profile); buf.actual_profile = new_profile; - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, &buf, sizeof(struct kovaplus_actual_profile)); } diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 440cb1bd70d4..1317c177a3e2 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -42,7 +42,7 @@ static void profile_activated(struct pyra_device *pyra, static int pyra_send_control(struct usb_device *usb_dev, int value, enum pyra_control_requests request) { - struct roccat_common_control control; + struct roccat_common2_control control; if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && @@ -53,8 +53,8 @@ static int pyra_send_control(struct usb_device *usb_dev, int value, control.value = value; control.request = request; - return roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, - &control, sizeof(struct roccat_common_control)); + return roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, + &control, sizeof(struct roccat_common2_control)); } static int pyra_get_profile_settings(struct usb_device *usb_dev, @@ -65,7 +65,7 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev, PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); if (retval) return retval; - return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, + return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, buf, sizeof(struct pyra_profile_settings)); } @@ -77,27 +77,27 @@ static int pyra_get_profile_buttons(struct usb_device *usb_dev, PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); if (retval) return retval; - return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, + return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buf, sizeof(struct pyra_profile_buttons)); } static int pyra_get_settings(struct usb_device *usb_dev, struct pyra_settings *buf) { - return roccat_common_receive(usb_dev, PYRA_COMMAND_SETTINGS, + return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, buf, sizeof(struct pyra_settings)); } static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) { - return roccat_common_receive(usb_dev, PYRA_COMMAND_INFO, + return roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO, buf, sizeof(struct pyra_info)); } static int pyra_set_profile_settings(struct usb_device *usb_dev, struct pyra_profile_settings const *settings) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings, sizeof(struct pyra_profile_settings)); } @@ -105,7 +105,7 @@ static int pyra_set_profile_settings(struct usb_device *usb_dev, static int pyra_set_profile_buttons(struct usb_device *usb_dev, struct pyra_profile_buttons const *buttons) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons, sizeof(struct pyra_profile_buttons)); } @@ -113,7 +113,7 @@ static int pyra_set_profile_buttons(struct usb_device *usb_dev, static int pyra_set_settings(struct usb_device *usb_dev, struct pyra_settings const *settings) { - return roccat_common_send_with_status(usb_dev, + return roccat_common2_send_with_status(usb_dev, PYRA_COMMAND_SETTINGS, settings, sizeof(struct pyra_settings)); } diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index 19f9c47fc020..29e87d712de0 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c @@ -44,7 +44,7 @@ static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&savu->savu_lock); - retval = roccat_common_receive(usb_dev, command, buf, real_size); + retval = roccat_common2_receive(usb_dev, command, buf, real_size); mutex_unlock(&savu->savu_lock); return retval ? retval : real_size; @@ -64,7 +64,7 @@ static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj, return -EINVAL; mutex_lock(&savu->savu_lock); - retval = roccat_common_send_with_status(usb_dev, command, + retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size); mutex_unlock(&savu->savu_lock); -- GitLab From fc8a7321d3d68af759a369a9ad3e2426688742d3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 28 Jun 2012 10:33:25 +0200 Subject: [PATCH 3162/6849] mac80211: don't expose ieee80211_add_srates_ie() This and ieee80211_add_ext_srates_ie() aren't exported, so can't be used by drivers anyway, but there's also no reason that they should be so make them private to mac80211 and use sdata instead of vif arguments. Acked-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 ------ net/mac80211/cfg.c | 12 ++++++------ net/mac80211/ieee80211_i.h | 4 ++++ net/mac80211/mesh_plink.c | 4 ++-- net/mac80211/tx.c | 4 ++-- net/mac80211/util.c | 10 ++++------ 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 510d852d5222..5e67020b1702 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3826,12 +3826,6 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif, void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif); -int ieee80211_add_srates_ie(struct ieee80211_vif *vif, - struct sk_buff *skb, bool need_basic); - -int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, - struct sk_buff *skb, bool need_basic); - /** * ieee80211_ave_rssi - report the average rssi for the specified interface * diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7722a7336a58..ebc353ef6902 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2665,8 +2665,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_req.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(&sdata->vif, skb, false); - ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); + ieee80211_add_srates_ie(sdata, skb, false); + ieee80211_add_ext_srates_ie(sdata, skb, false); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_RESPONSE: @@ -2679,8 +2679,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(&sdata->vif, skb, false); - ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); + ieee80211_add_srates_ie(sdata, skb, false); + ieee80211_add_ext_srates_ie(sdata, skb, false); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_CONFIRM: @@ -2740,8 +2740,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(&sdata->vif, skb, false); - ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); + ieee80211_add_srates_ie(sdata, skb, false); + ieee80211_add_ext_srates_ie(sdata, skb, false); ieee80211_tdls_add_ext_capab(skb); break; default: diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 341d77d472d2..6b7157d20507 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1480,6 +1480,10 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, u16 prot_mode); +int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, bool need_basic); +int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, bool need_basic); /* channel management */ enum ieee80211_chan_mode { diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index a1dbd1540276..425685914d7d 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -258,8 +258,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, 2); memcpy(pos + 2, &plid, 2); } - if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || - ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || + if (ieee80211_add_srates_ie(sdata, skb, true) || + ieee80211_add_ext_srates_ie(sdata, skb, true) || mesh_add_rsn_ie(skb, sdata) || mesh_add_meshid_ie(skb, sdata) || mesh_add_meshconf_ie(skb, sdata)) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ec8f53467374..4e753032e48d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2420,9 +2420,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, *pos++ = WLAN_EID_SSID; *pos++ = 0x0; - if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || + if (ieee80211_add_srates_ie(sdata, skb, true) || mesh_add_ds_params_ie(skb, sdata) || - ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || + ieee80211_add_ext_srates_ie(sdata, skb, true) || mesh_add_rsn_ie(skb, sdata) || mesh_add_ht_cap_ie(skb, sdata) || mesh_add_ht_oper_ie(skb, sdata) || diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 242ecde381f6..c4245695afc3 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1764,15 +1764,14 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper) return channel_type; } -int ieee80211_add_srates_ie(struct ieee80211_vif *vif, +int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, bool need_basic) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; int rate; u8 i, rates, *pos; - u32 basic_rates = vif->bss_conf.basic_rates; + u32 basic_rates = sdata->vif.bss_conf.basic_rates; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; rates = sband->n_bitrates; @@ -1796,15 +1795,14 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, return 0; } -int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, +int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, bool need_basic) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; int rate; u8 i, exrates, *pos; - u32 basic_rates = vif->bss_conf.basic_rates; + u32 basic_rates = sdata->vif.bss_conf.basic_rates; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; exrates = sband->n_bitrates; -- GitLab From f823981e288f83113bf1129ff2c94e2fd74a28dd Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 27 Jun 2012 14:18:22 +0300 Subject: [PATCH 3163/6849] mac80211: flush queues before deauth/disassoc On deauth/disassoc we tear down all BA sessions. These DELBA packets are sent on the appropriate TID, while deauth/disassoc is always sent on VO. This sometimes ends with the DELBA being sent after the deauth was already sent. Fix it by flushing all the pending frames before sending deauth/disassoc. Signed-off-by: Eliad Peller Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e11cd0e033ef..c54388b3ebff 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1364,6 +1364,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, } mutex_unlock(&local->sta_mtx); + /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ + if (tx) + drv_flush(local, false); + /* deauthenticate/disassociate now */ if (tx || frame_buf) ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason, -- GitLab From c9b22fb87a00ceb8afa78089d5cf676cf8b3319d Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 25 Jun 2012 10:48:25 +0300 Subject: [PATCH 3164/6849] mac80211: don't require associated->beacon_ies for ps beacon_ies is needed only in order to extract the dtim period. However, even if it's missing we can still enter ps with dtim=1 (which also happens if the TIM ie is invalid). Most drivers don't use conf.max_sleep_period/ps_dtim_period anyway, and this check prevents them from entering ps if they don't have beacon (but only probe response), even though the beacon is not needed at all. Signed-off-by: Eliad Peller Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c54388b3ebff..398acc4f649d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -902,9 +902,6 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) if (!mgd->associated) return false; - if (!mgd->associated->beacon_ies) - return false; - if (mgd->flags & (IEEE80211_STA_BEACON_POLL | IEEE80211_STA_CONNECTION_POLL)) return false; -- GitLab From 6ac7d11527a31d01b566a5c45369180e326ff4f1 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 6 Jun 2012 14:17:46 +0200 Subject: [PATCH 3165/6849] treewide: Put a space between #include and FILE Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- arch/arm/plat-samsung/include/plat/gpio-cfg.h | 2 +- arch/ia64/kernel/ia64_ksyms.c | 2 +- arch/ia64/kvm/vmm.c | 6 +++--- arch/parisc/include/asm/compat_rt_sigframe.h | 6 +++--- drivers/media/video/zoran/zr36016.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-io.c | 2 +- drivers/scsi/aha1542.c | 2 +- drivers/staging/comedi/drivers/s626.h | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index df8155b9d4d1..08740eed050c 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -24,7 +24,7 @@ #ifndef __PLAT_GPIO_CFG_H #define __PLAT_GPIO_CFG_H __FILE__ -#include +#include typedef unsigned int __bitwise__ samsung_gpio_pull_t; typedef unsigned int __bitwise__ s5p_gpio_drvstr_t; diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 7f4a0ed24152..5b7791dd3965 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -12,7 +12,7 @@ EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(strlen); -#include +#include EXPORT_SYMBOL_GPL(empty_zero_page); #include diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c index f0b9cac82414..176a12cd56de 100644 --- a/arch/ia64/kvm/vmm.c +++ b/arch/ia64/kvm/vmm.c @@ -20,9 +20,9 @@ */ -#include -#include -#include +#include +#include +#include #include "vcpu.h" diff --git a/arch/parisc/include/asm/compat_rt_sigframe.h b/arch/parisc/include/asm/compat_rt_sigframe.h index 81bec28bdc48..b3f95a7f18b4 100644 --- a/arch/parisc/include/asm/compat_rt_sigframe.h +++ b/arch/parisc/include/asm/compat_rt_sigframe.h @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #ifndef _ASM_PARISC_COMPAT_RT_SIGFRAME_H #define _ASM_PARISC_COMPAT_RT_SIGFRAME_H diff --git a/drivers/media/video/zoran/zr36016.c b/drivers/media/video/zoran/zr36016.c index 21c088ea9046..b87ddba8608f 100644 --- a/drivers/media/video/zoran/zr36016.c +++ b/drivers/media/video/zoran/zr36016.c @@ -40,10 +40,10 @@ /* v4l API */ /* headerfile of this module */ -#include"zr36016.h" +#include "zr36016.h" /* codec io API */ -#include"videocodec.h" +#include "videocodec.h" /* it doesn't make sense to have more than 20 or so, just to prevent some unwanted loops */ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 081dd34d2387..0f8b8aa9e8d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -29,7 +29,7 @@ #include #include "iwl-io.h" -#include"iwl-csr.h" +#include "iwl-csr.h" #include "iwl-debug.h" #define IWL_POLL_INTERVAL 10 /* microseconds */ diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index f79c8f9e33a4..770c48ddbe5e 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -49,7 +49,7 @@ #define SCSI_BUF_PA(address) isa_virt_to_bus(address) #define SCSI_SG_PA(sgent) (isa_page_to_bus(sg_page((sgent))) + (sgent)->offset) -#include +#include #ifdef DEBUG #define DEB(x) x diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h index 2d1afecbbb60..92d3ea5eb44d 100644 --- a/drivers/staging/comedi/drivers/s626.h +++ b/drivers/staging/comedi/drivers/s626.h @@ -80,7 +80,7 @@ #define INLINE static __inline #endif -#include +#include #define S626_SIZE 0x0200 #define SIZEOF_ADDRESS_SPACE 0x0200 -- GitLab From 8b7d133cc2dc5295bd720acaccf616584604369d Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 6 Jun 2012 23:28:23 +0200 Subject: [PATCH 3166/6849] ab8500-btemp: Fix typo 'AB5500' Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/power/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 99dc29f2f2f2..f2525af2e39b 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -299,7 +299,7 @@ config AB8500_BM bool "AB8500 Battery Management Driver" depends on AB8500_CORE && AB8500_GPADC help - Say Y to include support for AB5500 battery management. + Say Y to include support for AB8500 battery management. config AB8500_BATTERY_THERM_ON_BATCTRL bool "Thermistor connected on BATCTRL ADC" -- GitLab From 422aa274203469771460411ffb2f70c241770b80 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 9 Jun 2012 11:22:47 +0900 Subject: [PATCH 3167/6849] lib: correct link to the original source for div64_u64 Signed-off-by: Akinobu Mita Cc: Jiri Kosina Signed-off-by: Jiri Kosina --- lib/div64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/div64.c b/lib/div64.c index 3ea24907d52e..a163b6caef73 100644 --- a/lib/div64.c +++ b/lib/div64.c @@ -87,7 +87,7 @@ EXPORT_SYMBOL(div_s64_rem); * by the book 'Hacker's Delight'. The original source and full proof * can be found here and is available for use without restriction. * - * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c' + * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt' */ #ifndef div64_u64 u64 div64_u64(u64 dividend, u64 divisor) -- GitLab From be7bd59db71dfb6dc011c9880fec5a659430003a Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Thu, 14 Jun 2012 20:41:02 +0800 Subject: [PATCH 3168/6849] mm: fix page reclaim comment error Since there are five lists in LRU cache, the array nr in get_scan_count should be: nr[0] = anon inactive pages to scan; nr[1] = anon active pages to scan nr[2] = file inactive pages to scan; nr[3] = file active pages to scan Signed-off-by: Wanpeng Li Reviewed-by: Rik van Riel Acked-by: Minchan Kim Acked-by: KAMEZAWA Hiroyuki Acked-by: KOSAKI Motohiro Signed-off-by: Jiri Kosina --- mm/vmscan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 33dc256033b5..091ab8f88333 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1894,7 +1894,8 @@ static int vmscan_swappiness(struct mem_cgroup_zone *mz, * by looking at the fraction of the pages scanned we did rotate back * onto the active list instead of evict. * - * nr[0] = anon pages to scan; nr[1] = file pages to scan + * nr[0] = anon inactive pages to scan; nr[1] = anon active pages to scan + * nr[2] = file inactive pages to scan; nr[3] = file active pages to scan */ static void get_scan_count(struct mem_cgroup_zone *mz, struct scan_control *sc, unsigned long *nr, int priority) -- GitLab From 46028e6d10cbf9ccd5fb49aa0c23a430f314144c Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Fri, 15 Jun 2012 16:52:29 +0800 Subject: [PATCH 3169/6849] mm: cleanup on the comments of zone_reclaim_stat Signed-off-by: Wanpeng Li Acked-by: Minchan Kim Signed-off-by: Jiri Kosina --- include/linux/mmzone.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 4871e31ae277..54631776dff2 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -316,7 +316,7 @@ enum zone_type { struct zone_reclaim_stat { /* * The pageout code in vmscan.c keeps track of how many of the - * mem/swap backed and file backed pages are refeferenced. + * mem/swap backed and file backed pages are referenced. * The higher the rotated/scanned ratio, the more valuable * that cache is. * -- GitLab From ab8704b8c6ec6bc8560c72969d02d2682b4a2291 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Sun, 17 Jun 2012 09:27:18 +0800 Subject: [PATCH 3170/6849] mm/vmscan: cleanup comment error in balance_pgdat Signed-off-by: Wanpeng Li Signed-off-by: Jiri Kosina --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 091ab8f88333..3d1365c17868 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2864,7 +2864,7 @@ loop_again: * consider it to be no longer congested. It's * possible there are dirty pages backed by * congested BDIs but as pressure is relieved, - * spectulatively avoid congestion waits + * speculatively avoid congestion waits */ zone_clear_flag(zone, ZONE_CONGESTED); if (i <= *classzone_idx) -- GitLab From 692c86b75d9f8ffddc58c0efa6586b1d5d0993e1 Mon Sep 17 00:00:00 2001 From: "Christopher L. Simons" Date: Tue, 19 Jun 2012 00:08:07 -0400 Subject: [PATCH 3171/6849] Documentation: ManagementStyle: fixed typo Fixed a spelling error (less that you -> less than you) Signed-off-by: Christopher L. Simons Acked-by: Rob Landley Signed-off-by: Jiri Kosina --- Documentation/ManagementStyle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ManagementStyle b/Documentation/ManagementStyle index a5f0ea58c788..a211ee8d8b44 100644 --- a/Documentation/ManagementStyle +++ b/Documentation/ManagementStyle @@ -178,7 +178,7 @@ sadly that you are one too, and that while we can all bask in the secure knowledge that we're better than the average person (let's face it, nobody ever believes that they're average or below-average), we should also admit that we're not the sharpest knife around, and there will be -other people that are less of an idiot that you are. +other people that are less of an idiot than you are. Some people react badly to smart people. Others take advantage of them. -- GitLab From 57bdfdd80077addf518a9b90c4a66890efc4f70e Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 22 Jun 2012 10:24:33 -0400 Subject: [PATCH 3172/6849] Documentation: asus-laptop.txt references an obsolete Kconfig item The CONFIG_X86_UP_APIC option no longer exists. Delete the reference of it. Cc: trivial@kernel.org Signed-off-by: Paul Gortmaker Signed-off-by: Jiri Kosina --- Documentation/laptops/asus-laptop.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/laptops/asus-laptop.txt b/Documentation/laptops/asus-laptop.txt index a1e04d679289..69f9fb3701e0 100644 --- a/Documentation/laptops/asus-laptop.txt +++ b/Documentation/laptops/asus-laptop.txt @@ -151,8 +151,7 @@ Display switching Debugging: 1) Check whether the Fn+F8 key: - a) does not lock the laptop (try disabling CONFIG_X86_UP_APIC or boot with - noapic / nolapic if it does) + a) does not lock the laptop (try a boot with noapic / nolapic if it does) b) generates events (0x6n, where n is the value corresponding to the configuration above) c) actually works -- GitLab From 70e7341673a47fb1525cfc7d6651cc98b5348928 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Jun 2012 03:21:41 -0700 Subject: [PATCH 3173/6849] ipv4: Show that ip_send_reply() is purely unicast routine. Rename it to ip_send_unicast_reply() and add explicit 'saddr' argument. This removed one of the few users of rt->rt_spec_dst. Signed-off-by: David S. Miller --- include/net/ip.h | 5 +++-- net/ipv4/ip_output.c | 9 +++++---- net/ipv4/tcp_ipv4.c | 8 ++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/net/ip.h b/include/net/ip.h index 50841bd6f10e..ec5cfde85e9a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -158,8 +158,9 @@ static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg) return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0; } -void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, - const struct ip_reply_arg *arg, unsigned int len); +void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, + __be32 saddr, const struct ip_reply_arg *arg, + unsigned int len); struct ipv4_config { int log_martians; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 0f3185a662c3..2630900e480a 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1459,13 +1459,14 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset, /* * Generic function to send a packet as reply to another packet. - * Used to send TCP resets so far. ICMP should use this function too. + * Used to send TCP resets so far. * * Should run single threaded per socket because it uses the sock * structure to pass arguments. */ -void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, - const struct ip_reply_arg *arg, unsigned int len) +void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, + __be32 saddr, const struct ip_reply_arg *arg, + unsigned int len) { struct inet_sock *inet = inet_sk(sk); struct ip_options_data replyopts; @@ -1491,7 +1492,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, RT_TOS(arg->tos), RT_SCOPE_UNIVERSE, sk->sk_protocol, ip_reply_arg_flowi_flags(arg), - daddr, rt->rt_spec_dst, + daddr, saddr, tcp_hdr(skb)->source, tcp_hdr(skb)->dest); security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(sock_net(sk), &fl4); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b4ae1c199f3e..64568fa21d05 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -698,8 +698,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) net = dev_net(skb_dst(skb)->dev); arg.tos = ip_hdr(skb)->tos; - ip_send_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr, - &arg, arg.iov[0].iov_len); + ip_send_unicast_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); @@ -781,8 +781,8 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, if (oif) arg.bound_dev_if = oif; arg.tos = tos; - ip_send_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr, - &arg, arg.iov[0].iov_len); + ip_send_unicast_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); } -- GitLab From 35ebf65e851c6d9731abc6362b189858eb59f4d3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Jun 2012 03:59:11 -0700 Subject: [PATCH 3174/6849] ipv4: Create and use fib_compute_spec_dst() helper. The specific destination is the host we direct unicast replies to. Usually this is the original packet source address, but if we are responding to a multicast or broadcast packet we have to use something different. Specifically we must use the source address we would use if we were to send a packet to the unicast source of the original packet. The routing cache precomputes this value, but we want to remove that precomputation because it creates a hard dependency on the expensive rpfilter source address validation which we'd like to make cheaper. There are only three places where this matters: 1) ICMP replies. 2) pktinfo CMSG 3) IP options Now there will be no real users of rt->rt_spec_dst and we can simply remove it altogether. Signed-off-by: David S. Miller --- include/net/ip_fib.h | 1 + net/ipv4/fib_frontend.c | 29 +++++++++++++++++++++++++++++ net/ipv4/icmp.c | 6 ++++-- net/ipv4/ip_options.c | 22 +++++++++++----------- net/ipv4/ip_sockglue.c | 7 ++++--- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 4b347c0ca094..1687b3de54ff 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -230,6 +230,7 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id); /* Exported by fib_frontend.c */ extern const struct nla_policy rtm_ipv4_policy[]; extern void ip_fib_init(void); +extern __be32 fib_compute_spec_dst(struct sk_buff *skb); extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, __be32 *spec_dst, u32 *itag); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3854411fa37c..451939b60c54 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -180,6 +180,35 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, } EXPORT_SYMBOL(inet_dev_addr_type); +__be32 fib_compute_spec_dst(struct sk_buff *skb) +{ + struct net_device *dev = skb->dev; + struct in_device *in_dev; + struct fib_result res; + struct flowi4 fl4; + struct net *net; + + if (skb->pkt_type != PACKET_BROADCAST && + skb->pkt_type != PACKET_MULTICAST) + return ip_hdr(skb)->daddr; + + in_dev = __in_dev_get_rcu(dev); + BUG_ON(!in_dev); + fl4.flowi4_oif = 0; + fl4.flowi4_iif = 0; + fl4.daddr = ip_hdr(skb)->saddr; + fl4.saddr = ip_hdr(skb)->daddr; + fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); + fl4.flowi4_scope = RT_SCOPE_UNIVERSE; + fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; + + net = dev_net(dev); + if (!fib_lookup(net, &fl4, &res)) + return FIB_RES_PREFSRC(net, res); + else + return inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); +} + /* Given (packet source, input interface) and optional (dst, oif, tos): * - (main) check, that source is valid i.e. not broadcast or our local * address. diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 49a74cc79dc8..4bce5a2830aa 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -95,6 +95,7 @@ #include #include #include +#include /* * Build xmit assembly blocks @@ -333,7 +334,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) struct flowi4 fl4; struct sock *sk; struct inet_sock *inet; - __be32 daddr; + __be32 daddr, saddr; if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb)) return; @@ -347,6 +348,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) inet->tos = ip_hdr(skb)->tos; daddr = ipc.addr = ip_hdr(skb)->saddr; + saddr = fib_compute_spec_dst(skb); ipc.opt = NULL; ipc.tx_flags = 0; if (icmp_param->replyopts.opt.opt.optlen) { @@ -356,7 +358,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) } memset(&fl4, 0, sizeof(fl4)); fl4.daddr = daddr; - fl4.saddr = rt->rt_spec_dst; + fl4.saddr = saddr; fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); fl4.flowi4_proto = IPPROTO_ICMP; security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 708b99494e23..766dfe56885a 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -27,6 +27,7 @@ #include #include #include +#include /* * Write options to IP header, record destination address to @@ -104,7 +105,7 @@ int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb) sptr = skb_network_header(skb); dptr = dopt->__data; - daddr = skb_rtable(skb)->rt_spec_dst; + daddr = fib_compute_spec_dst(skb); if (sopt->rr) { optlen = sptr[sopt->rr+1]; @@ -250,15 +251,14 @@ void ip_options_fragment(struct sk_buff *skb) int ip_options_compile(struct net *net, struct ip_options *opt, struct sk_buff *skb) { - int l; - unsigned char *iph; - unsigned char *optptr; - int optlen; + __be32 spec_dst = (__force __be32) 0; unsigned char *pp_ptr = NULL; - struct rtable *rt = NULL; + unsigned char *optptr; + unsigned char *iph; + int optlen, l; if (skb != NULL) { - rt = skb_rtable(skb); + spec_dst = fib_compute_spec_dst(skb); optptr = (unsigned char *)&(ip_hdr(skb)[1]); } else optptr = opt->__data; @@ -330,8 +330,8 @@ int ip_options_compile(struct net *net, pp_ptr = optptr + 2; goto error; } - if (rt) { - memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); + if (skb) { + memcpy(&optptr[optptr[2]-1], &spec_dst, 4); opt->is_changed = 1; } optptr[2] += 4; @@ -372,8 +372,8 @@ int ip_options_compile(struct net *net, goto error; } opt->ts = optptr - iph; - if (rt) { - memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); + if (skb) { + memcpy(&optptr[optptr[2]-1], &spec_dst, 4); timeptr = &optptr[optptr[2]+3]; } opt->ts_needaddr = 1; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 0d11f234d615..de29f46f68b0 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -40,6 +40,7 @@ #if IS_ENABLED(CONFIG_IPV6) #include #endif +#include #include #include @@ -1019,8 +1020,8 @@ e_inval: * @sk: socket * @skb: buffer * - * To support IP_CMSG_PKTINFO option, we store rt_iif and rt_spec_dst - * in skb->cb[] before dst drop. + * To support IP_CMSG_PKTINFO option, we store rt_iif and specific + * destination in skb->cb[] before dst drop. * This way, receiver doesnt make cache line misses to read rtable. */ void ipv4_pktinfo_prepare(struct sk_buff *skb) @@ -1030,7 +1031,7 @@ void ipv4_pktinfo_prepare(struct sk_buff *skb) if (rt) { pktinfo->ipi_ifindex = rt->rt_iif; - pktinfo->ipi_spec_dst.s_addr = rt->rt_spec_dst; + pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb); } else { pktinfo->ipi_ifindex = 0; pktinfo->ipi_spec_dst.s_addr = 0; -- GitLab From 41347dcdd81988b8e60853257b2875285cc17a4e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Jun 2012 04:05:27 -0700 Subject: [PATCH 3175/6849] ipv4: Kill rt->rt_spec_dst, no longer used. Signed-off-by: David S. Miller --- include/net/ip_fib.h | 2 +- include/net/route.h | 1 - net/ipv4/fib_frontend.c | 9 ++------- net/ipv4/route.c | 38 +++++++++----------------------------- net/ipv4/xfrm4_policy.c | 1 - 5 files changed, 12 insertions(+), 39 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 1687b3de54ff..9e6c26d4ba4c 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -233,7 +233,7 @@ extern void ip_fib_init(void); extern __be32 fib_compute_spec_dst(struct sk_buff *skb); extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, - __be32 *spec_dst, u32 *itag); + u32 *itag); extern void fib_select_default(struct fib_result *res); /* Exported by fib_semantics.c */ diff --git a/include/net/route.h b/include/net/route.h index 47eb25ac1f7f..211e2665139b 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -65,7 +65,6 @@ struct rtable { __be32 rt_gateway; /* Miscellaneous cached information */ - __be32 rt_spec_dst; /* RFC1122 specific destination */ u32 rt_peer_genid; unsigned long _peer; /* long-living peer info */ struct fib_info *fi; /* for client ref to shared metrics */ diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 451939b60c54..63b11ca54d95 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -218,8 +218,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) * called with rcu_read_lock() */ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, - int oif, struct net_device *dev, __be32 *spec_dst, - u32 *itag) + int oif, struct net_device *dev, u32 *itag) { struct in_device *in_dev; struct flowi4 fl4; @@ -258,7 +257,6 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, if (res.type != RTN_LOCAL || !accept_local) goto e_inval; } - *spec_dst = FIB_RES_PREFSRC(net, res); fib_combine_itag(itag, &res); dev_match = false; @@ -287,17 +285,14 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, ret = 0; if (fib_lookup(net, &fl4, &res) == 0) { - if (res.type == RTN_UNICAST) { - *spec_dst = FIB_RES_PREFSRC(net, res); + if (res.type == RTN_UNICAST) ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; - } } return ret; last_resort: if (rpf) goto e_rpf; - *spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); *itag = 0; return 0; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 81533e3a23d1..83d56a016625 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -440,7 +440,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) r->rt_key_tos, -1, HHUptod, - r->rt_spec_dst, &len); + 0, &len); seq_printf(seq, "%*s\n", 127 - len, ""); } @@ -1978,7 +1978,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, { unsigned int hash; struct rtable *rth; - __be32 spec_dst; struct in_device *in_dev = __in_dev_get_rcu(dev); u32 itag = 0; int err; @@ -1999,10 +1998,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (ipv4_is_zeronet(saddr)) { if (!ipv4_is_local_multicast(daddr)) goto e_inval; - spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); } else { - err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst, - &itag); + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &itag); if (err < 0) goto e_err; } @@ -2029,7 +2026,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_gateway = daddr; - rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; rt_init_peer(rth, dev_net(dev)->ipv4.peers); rth->fi = NULL; @@ -2093,7 +2089,6 @@ static int __mkroute_input(struct sk_buff *skb, int err; struct in_device *out_dev; unsigned int flags = 0; - __be32 spec_dst; u32 itag; /* get a working reference to the output device */ @@ -2105,7 +2100,7 @@ static int __mkroute_input(struct sk_buff *skb, err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), - in_dev->dev, &spec_dst, &itag); + in_dev->dev, &itag); if (err < 0) { ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, saddr); @@ -2157,7 +2152,6 @@ static int __mkroute_input(struct sk_buff *skb, rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_gateway = daddr; - rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; rt_init_peer(rth, &res->table->tb_peers); rth->fi = NULL; @@ -2223,7 +2217,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, u32 itag = 0; struct rtable *rth; unsigned int hash; - __be32 spec_dst; int err = -EINVAL; struct net *net = dev_net(dev); @@ -2281,12 +2274,11 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { err = fib_validate_source(skb, saddr, daddr, tos, net->loopback_dev->ifindex, - dev, &spec_dst, &itag); + dev, &itag); if (err < 0) goto martian_source_keep_err; if (err) flags |= RTCF_DIRECTSRC; - spec_dst = daddr; goto local_input; } @@ -2302,11 +2294,8 @@ brd_input: if (skb->protocol != htons(ETH_P_IP)) goto e_inval; - if (ipv4_is_zeronet(saddr)) - spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); - else { - err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst, - &itag); + if (!ipv4_is_zeronet(saddr)) { + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &itag); if (err < 0) goto martian_source_keep_err; if (err) @@ -2344,7 +2333,6 @@ local_input: rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_gateway = daddr; - rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; rt_init_peer(rth, net->ipv4.peers); rth->fi = NULL; @@ -2362,7 +2350,6 @@ local_input: no_route: RT_CACHE_STAT_INC(in_no_route); - spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); res.type = RTN_UNREACHABLE; if (err == -ESRCH) err = -ENETUNREACH; @@ -2545,7 +2532,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_oif = orig_oif; rth->rt_mark = fl4->flowi4_mark; rth->rt_gateway = fl4->daddr; - rth->rt_spec_dst= fl4->saddr; rth->rt_peer_genid = 0; rt_init_peer(rth, (res->table ? &res->table->tb_peers : @@ -2554,12 +2540,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res, RT_CACHE_STAT_INC(out_slow_tot); - if (flags & RTCF_LOCAL) { + if (flags & RTCF_LOCAL) rth->dst.input = ip_local_deliver; - rth->rt_spec_dst = fl4->daddr; - } if (flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { - rth->rt_spec_dst = fl4->saddr; if (flags & RTCF_LOCAL && !(dev_out->flags & IFF_LOOPBACK)) { rth->dst.output = ip_mc_output; @@ -2890,7 +2873,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or rt->rt_dst = ort->rt_dst; rt->rt_src = ort->rt_src; rt->rt_gateway = ort->rt_gateway; - rt->rt_spec_dst = ort->rt_spec_dst; rt_transfer_peer(rt, ort); rt->fi = ort->fi; if (rt->fi) @@ -2965,10 +2947,8 @@ static int rt_fill_info(struct net *net, nla_put_u32(skb, RTA_FLOW, rt->dst.tclassid)) goto nla_put_failure; #endif - if (rt_is_input_route(rt)) { - if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_spec_dst)) - goto nla_put_failure; - } else if (rt->rt_src != rt->rt_key_src) { + if (!rt_is_input_route(rt) && + rt->rt_src != rt->rt_key_src) { if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_src)) goto nla_put_failure; } diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 8855d8268552..9815ea0bca7f 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -100,7 +100,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.rt.rt_src = rt->rt_src; xdst->u.rt.rt_dst = rt->rt_dst; xdst->u.rt.rt_gateway = rt->rt_gateway; - xdst->u.rt.rt_spec_dst = rt->rt_spec_dst; return 0; } -- GitLab From ce0e169529a2db1cd910d2d45a5713fcdc29f6e1 Mon Sep 17 00:00:00 2001 From: Mahesh Palivela Date: Fri, 22 Jun 2012 07:27:46 +0000 Subject: [PATCH 3176/6849] wireless: add VHT (802.11ac) definitions Add the VHT definitions to be used by drivers supporting it. Signed-off-by: Mahesh Palivela Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 318fc1f705b1..abf0e5fe6d24 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1092,6 +1092,73 @@ struct ieee80211_ht_operation { #define WLAN_HT_SMPS_CONTROL_STATIC 1 #define WLAN_HT_SMPS_CONTROL_DYNAMIC 3 +#define VHT_MCS_SUPPORTED_SET_SIZE 8 + +struct ieee80211_vht_capabilities { + __le32 vht_capabilities_info; + u8 vht_supported_mcs_set[VHT_MCS_SUPPORTED_SET_SIZE]; +} __packed; + +struct ieee80211_vht_operation { + u8 vht_op_info_chwidth; + u8 vht_op_info_chan_center_freq_seg1_idx; + u8 vht_op_info_chan_center_freq_seg2_idx; + __le16 vht_basic_mcs_set; +} __packed; + +/** + * struct ieee80211_vht_mcs_info - VHT MCS information + * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams + * @rx_highest: Indicates highest long GI VHT PPDU data rate + * STA can receive. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams + * @tx_highest: Indicates highest long GI VHT PPDU data rate + * STA can transmit. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest TX data rate supported. + */ +struct ieee80211_vht_mcs_info { + __le16 rx_mcs_map; + __le16 rx_highest; + __le16 tx_mcs_map; + __le16 tx_highest; +} __packed; + +#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0 +#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1 +#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2 +#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3 + +/* 802.11ac VHT Capabilities */ +#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000 +#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001 +#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002 +#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004 +#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008 +#define IEEE80211_VHT_CAP_RXLDPC 0x00000010 +#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020 +#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040 +#define IEEE80211_VHT_CAP_TXSTBC 0x00000080 +#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100 +#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200 +#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 +#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 +#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 +#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 +#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 +#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000 +#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 +#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 +#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 +#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000 +#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT 0x00800000 +#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000 +#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000 +#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000 +#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000 + /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 @@ -1352,6 +1419,9 @@ enum ieee80211_eid { WLAN_EID_DSE_REGISTERED_LOCATION = 58, WLAN_EID_SUPPORTED_REGULATORY_CLASSES = 59, WLAN_EID_EXT_CHANSWITCH_ANN = 60, + + WLAN_EID_VHT_CAPABILITY = 191, + WLAN_EID_VHT_OPERATION = 192, }; /* Action category code */ -- GitLab From bf0c111ec80355ee9fe2e2bdb609a536b54768d8 Mon Sep 17 00:00:00 2001 From: Mahesh Palivela Date: Fri, 22 Jun 2012 07:27:46 +0000 Subject: [PATCH 3177/6849] cfg80211: allow advertising VHT capabilities Allow drivers to advertise their VHT capabilities and export them to userspace via nl80211. Signed-off-by: Mahesh Palivela Signed-off-by: Johannes Berg --- include/linux/nl80211.h | 6 ++++++ include/net/cfg80211.h | 17 +++++++++++++++++ net/wireless/nl80211.c | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c0fc5d277338..23003272c70e 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1813,6 +1813,9 @@ enum nl80211_mpath_info { * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n + * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as + * defined in 802.11ac + * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined * @__NL80211_BAND_ATTR_AFTER_LAST: internal use */ @@ -1826,6 +1829,9 @@ enum nl80211_band_attr { NL80211_BAND_ATTR_HT_AMPDU_FACTOR, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, + NL80211_BAND_ATTR_VHT_MCS_SET, + NL80211_BAND_ATTR_VHT_CAPA, + /* keep last */ __NL80211_BAND_ATTR_AFTER_LAST, NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7d3cd3ce9a26..1fc89c4f930c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -210,6 +210,22 @@ struct ieee80211_sta_ht_cap { struct ieee80211_mcs_info mcs; }; +/** + * struct ieee80211_sta_vht_cap - STA's VHT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11ac VHT capabilities for an STA. + * + * @vht_supported: is VHT supported by the STA + * @cap: VHT capabilities map as described in 802.11ac spec + * @vht_mcs: Supported VHT MCS rates + */ +struct ieee80211_sta_vht_cap { + bool vht_supported; + u32 cap; /* use IEEE80211_VHT_CAP_ */ + struct ieee80211_vht_mcs_info vht_mcs; +}; + /** * struct ieee80211_supported_band - frequency band definition * @@ -233,6 +249,7 @@ struct ieee80211_supported_band { int n_channels; int n_bitrates; struct ieee80211_sta_ht_cap ht_cap; + struct ieee80211_sta_vht_cap vht_cap; }; /* diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 067c9fe02a7f..5c4a720f0442 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -921,6 +921,15 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, dev->wiphy.bands[band]->ht_cap.ampdu_density))) goto nla_put_failure; + /* add VHT info */ + if (dev->wiphy.bands[band]->vht_cap.vht_supported && + (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET, + sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs), + &dev->wiphy.bands[band]->vht_cap.vht_mcs) || + nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA, + dev->wiphy.bands[band]->vht_cap.cap))) + goto nla_put_failure; + /* add frequencies */ nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); if (!nl_freqs) -- GitLab From 6b4a21b64ccc218a00dc0e38676092e64df159dc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 28 Jun 2012 13:11:47 +0100 Subject: [PATCH 3178/6849] ASoC: dwc: Add missing __iomem annotations Otherwise sparse gets very upset with us. Signed-off-by: Mark Brown --- sound/soc/dwc/designware_i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index e667e2b45e67..1bd042b15aef 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -71,12 +71,12 @@ struct dw_i2s_dev { int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); }; -static inline void i2s_write_reg(void *io_base, int reg, u32 val) +static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val) { writel(val, io_base + reg); } -static inline u32 i2s_read_reg(void *io_base, int reg) +static inline u32 i2s_read_reg(void __iomem *io_base, int reg) { return readl(io_base + reg); } -- GitLab From cdf605255c2b592d7dbc1de19688feae941b5567 Mon Sep 17 00:00:00 2001 From: Vipin Kumar Date: Thu, 28 Jun 2012 12:31:37 +0530 Subject: [PATCH 3179/6849] ASoC: spdif_receiver: Add support for spdif in Audio Codec This patch adds the support for spdif in audio codec. Signed-off-by: vipin Kumar Signed-off-by: Rajeev Kumar Signed-off-by: Mark Brown --- sound/soc/codecs/Makefile | 2 +- sound/soc/codecs/spdif_receiver.c | 67 +++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/spdif_receiver.c diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d35ba7f06fcf..62c3d4dd1872 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -45,7 +45,7 @@ snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sn95031-objs := sn95031.o -snd-soc-spdif-objs := spdif_transciever.o +snd-soc-spdif-objs := spdif_transciever.o spdif_receiver.o snd-soc-ssm2602-objs := ssm2602.o snd-soc-sta32x-objs := sta32x.o snd-soc-stac9766-objs := stac9766.o diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c new file mode 100644 index 000000000000..dd8d856053fc --- /dev/null +++ b/sound/soc/codecs/spdif_receiver.c @@ -0,0 +1,67 @@ +/* + * ALSA SoC SPDIF DIR (Digital Interface Reciever) driver + * + * Based on ALSA SoC SPDIF DIT driver + * + * This driver is used by controllers which can operate in DIR (SPDI/F) where + * no codec is needed. This file provides stub codec that can be used + * in these configurations. SPEAr SPDIF IN Audio controller uses this driver. + * + * Author: Vipin Kumar, + * Copyright: (C) 2012 ST Microelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#define STUB_RATES SNDRV_PCM_RATE_8000_192000 +#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) + +static struct snd_soc_codec_driver soc_codec_spdif_dir; + +static struct snd_soc_dai_driver dir_stub_dai = { + .name = "dir-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 384, + .rates = STUB_RATES, + .formats = STUB_FORMATS, + }, +}; + +static int spdif_dir_probe(struct platform_device *pdev) +{ + return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dir, + &dir_stub_dai, 1); +} + +static int spdif_dir_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static struct platform_driver spdif_dir_driver = { + .probe = spdif_dir_probe, + .remove = spdif_dir_remove, + .driver = { + .name = "spdif-dir", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(spdif_dir_driver); + +MODULE_DESCRIPTION("ASoC SPDIF DIR driver"); +MODULE_AUTHOR("Vipin Kumar "); +MODULE_LICENSE("GPL"); -- GitLab From 44b8db13860a449b5d85afdc65da654ce56da678 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Mon, 18 Jun 2012 16:31:31 +0900 Subject: [PATCH 3180/6849] GFS2: Fixing double brelse'ing bh allocated in gfs2_meta_read when EIO occurs This patch fixes buffer_head double free in following code path: gfs2_block_map => gfs2_meta_inode_buffer => gfs2_meta_indirect_buffer => gfs2_meta_read => release_metapath gfs2_block_map calls gfs2_meta_inode_buffer with &mp.mp_bh[0] as an argument. mp.mp_bh are filled with zero at the beginning of gfs2_block_map. If gfs2_meta_inode_buffer returns non-zero value, gfs2_block_map calls release_metapath to free buffers chained to mp.mp_bh. release_metapath checks each slot of mp.mp_bh[i] and free(with brelse) unless the slot is filled with NULL. &mp.mp_bh[0] passed to gfs2_meta_inode_buffer is filled at gfs2_meta_read. gfs2_meta_read is filled a buffer allocated with gfs2_getbuf even if EIO occurs. When EIO occurs, the allocated buffer is brelse'ed though the pointer(wrong poiner) points the brelse'ed is passed back to caller via an argument bhp. gfs2_meta_indirect_buffer, the caller also pass the wrong pointer to its caller with EIO. Finally gfs2_block_map gets both EIO and &mp.mp_bh[0] filled with the wrong pointer. release_metapath calls brelse again on the wrong pointer. Signed-off-by: Masatake YAMATO Signed-off-by: Steven Whitehouse --- fs/gfs2/meta_io.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 6c1e5d1c404a..3a56c8d94de0 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -213,8 +213,10 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, struct gfs2_sbd *sdp = gl->gl_sbd; struct buffer_head *bh; - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { + *bhp = NULL; return -EIO; + } *bhp = bh = gfs2_getbuf(gl, blkno, CREATE); @@ -235,6 +237,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, if (tr && tr->tr_touched) gfs2_io_error_bh(sdp, bh); brelse(bh); + *bhp = NULL; return -EIO; } -- GitLab From 8aec836acbe56a27080723187f0a0f1686662318 Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Wed, 27 Jun 2012 04:33:40 -0500 Subject: [PATCH 3181/6849] samples: seccomp: add .gitignore for untracked executables git status should be clean following make allmodconfig && make. Add a .gitignore file to the samples/seccomp directory to ignore binaries produced there. Signed-off-by: Chad Williamson Reviewed-By: Will Drewry Acked-by: Kees Cook Signed-off-by: James Morris --- samples/seccomp/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 samples/seccomp/.gitignore diff --git a/samples/seccomp/.gitignore b/samples/seccomp/.gitignore new file mode 100644 index 000000000000..78fb78184291 --- /dev/null +++ b/samples/seccomp/.gitignore @@ -0,0 +1,3 @@ +bpf-direct +bpf-fancy +dropper -- GitLab From cb14d340ef1737c24125dd663eff77734a482d47 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 27 Jun 2012 20:08:44 +0200 Subject: [PATCH 3182/6849] udf: Use 'ret' instead of abusing 'i' in udf_load_logicalvol() Signed-off-by: Jan Kara --- fs/udf/super.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index ac8a348dcb69..9da6f4ee112c 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1233,11 +1233,9 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, BUG_ON(ident != TAG_IDENT_LVD); lvd = (struct logicalVolDesc *)bh->b_data; - i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); - if (i != 0) { - ret = i; + ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); + if (ret) goto out_bh; - } for (i = 0, offset = 0; i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); -- GitLab From adee11b2085bee90bd8f4f52123ffb07882d6256 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 27 Jun 2012 20:20:22 +0200 Subject: [PATCH 3183/6849] udf: Avoid run away loop when partition table length is corrupted Check provided length of partition table so that (possibly maliciously) corrupted partition table cannot cause accessing data beyond current buffer. Signed-off-by: Jan Kara --- fs/udf/super.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 9da6f4ee112c..ce911f50b39d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1225,6 +1225,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, struct genericPartitionMap *gpm; uint16_t ident; struct buffer_head *bh; + unsigned int table_len; int ret = 0; bh = udf_read_tagged(sb, block, block, &ident); @@ -1232,13 +1233,20 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, return 1; BUG_ON(ident != TAG_IDENT_LVD); lvd = (struct logicalVolDesc *)bh->b_data; + table_len = le32_to_cpu(lvd->mapTableLength); + if (sizeof(*lvd) + table_len > sb->s_blocksize) { + udf_err(sb, "error loading logical volume descriptor: " + "Partition table too long (%u > %lu)\n", table_len, + sb->s_blocksize - sizeof(*lvd)); + goto out_bh; + } ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); if (ret) goto out_bh; for (i = 0, offset = 0; - i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); + i < sbi->s_partitions && offset < table_len; i++, offset += gpm->partitionMapLength) { struct udf_part_map *map = &sbi->s_partmaps[i]; gpm = (struct genericPartitionMap *) -- GitLab From 1df2ae31c724e57be9d7ac00d78db8a5dabdd050 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 27 Jun 2012 21:23:07 +0200 Subject: [PATCH 3184/6849] udf: Fortify loading of sparing table Add sanity checks when loading sparing table from disk to avoid accessing unallocated memory or writing to it. Signed-off-by: Jan Kara --- fs/udf/super.c | 86 +++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index ce911f50b39d..8d86a8706c0e 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include "udf_sb.h" @@ -1215,11 +1216,59 @@ out_bh: return ret; } +static int udf_load_sparable_map(struct super_block *sb, + struct udf_part_map *map, + struct sparablePartitionMap *spm) +{ + uint32_t loc; + uint16_t ident; + struct sparingTable *st; + struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing; + int i; + struct buffer_head *bh; + + map->s_partition_type = UDF_SPARABLE_MAP15; + sdata->s_packet_len = le16_to_cpu(spm->packetLength); + if (!is_power_of_2(sdata->s_packet_len)) { + udf_err(sb, "error loading logical volume descriptor: " + "Invalid packet length %u\n", + (unsigned)sdata->s_packet_len); + return -EIO; + } + if (spm->numSparingTables > 4) { + udf_err(sb, "error loading logical volume descriptor: " + "Too many sparing tables (%d)\n", + (int)spm->numSparingTables); + return -EIO; + } + + for (i = 0; i < spm->numSparingTables; i++) { + loc = le32_to_cpu(spm->locSparingTable[i]); + bh = udf_read_tagged(sb, loc, loc, &ident); + if (!bh) + continue; + + st = (struct sparingTable *)bh->b_data; + if (ident != 0 || + strncmp(st->sparingIdent.ident, UDF_ID_SPARING, + strlen(UDF_ID_SPARING)) || + sizeof(*st) + le16_to_cpu(st->reallocationTableLen) > + sb->s_blocksize) { + brelse(bh); + continue; + } + + sdata->s_spar_map[i] = bh; + } + map->s_partition_func = udf_get_pblock_spar15; + return 0; +} + static int udf_load_logicalvol(struct super_block *sb, sector_t block, struct kernel_lb_addr *fileset) { struct logicalVolDesc *lvd; - int i, j, offset; + int i, offset; uint8_t type; struct udf_sb_info *sbi = UDF_SB(sb); struct genericPartitionMap *gpm; @@ -1281,38 +1330,9 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, } else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE))) { - uint32_t loc; - struct sparingTable *st; - struct sparablePartitionMap *spm = - (struct sparablePartitionMap *)gpm; - - map->s_partition_type = UDF_SPARABLE_MAP15; - map->s_type_specific.s_sparing.s_packet_len = - le16_to_cpu(spm->packetLength); - for (j = 0; j < spm->numSparingTables; j++) { - struct buffer_head *bh2; - - loc = le32_to_cpu( - spm->locSparingTable[j]); - bh2 = udf_read_tagged(sb, loc, loc, - &ident); - map->s_type_specific.s_sparing. - s_spar_map[j] = bh2; - - if (bh2 == NULL) - continue; - - st = (struct sparingTable *)bh2->b_data; - if (ident != 0 || strncmp( - st->sparingIdent.ident, - UDF_ID_SPARING, - strlen(UDF_ID_SPARING))) { - brelse(bh2); - map->s_type_specific.s_sparing. - s_spar_map[j] = NULL; - } - } - map->s_partition_func = udf_get_pblock_spar15; + if (udf_load_sparable_map(sb, map, + (struct sparablePartitionMap *)gpm) < 0) + goto out_bh; } else if (!strncmp(upm2->partIdent.ident, UDF_ID_METADATA, strlen(UDF_ID_METADATA))) { -- GitLab From 0be61ebc18b919dddbdbcd1c4f42513c310ecf59 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 18 Jun 2012 09:28:16 -0400 Subject: [PATCH 3185/6849] tracing/selftest: Add a WARN_ON() if a tracer test fails Add a WARN_ON() output on test failures so that they are easier to detect in automated tests. Although, the WARN_ON() will not print if the test causes the system to crash, obviously. Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 49249c28690d..748f6401edf6 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -830,6 +830,8 @@ int register_tracer(struct tracer *type) current_trace = saved_tracer; if (ret) { printk(KERN_CONT "FAILED!\n"); + /* Add the warning after printing 'FAILED' */ + WARN_ON(1); goto out; } /* Only reset on passing, to avoid touching corrupted buffers */ -- GitLab From b102f1d0f1cd0bb5ec82e5aeb1e33502d6ad6710 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 27 Jun 2012 09:41:39 +0900 Subject: [PATCH 3186/6849] tracing/kvm: Use __print_hex() for kvm_emulate_insn tracepoint The kvm_emulate_insn tracepoint used __print_insn() for printing its instructions. However it makes the format of the event hard to parse as it reveals TP internals. Fortunately, kernel provides __print_hex for almost same purpose, we can use it instead of open coding it. The user-space can be changed to parse it later. That means raw kernel tracing will not be affected by this change: # cd /sys/kernel/debug/tracing/ # cat events/kvm/kvm_emulate_insn/format name: kvm_emulate_insn ID: 29 format: ... print fmt: "%x:%llx:%s (%s)%s", REC->csbase, REC->rip, __print_hex(REC->insn, REC->len), \ __print_symbolic(REC->flags, { 0, "real" }, { (1 << 0) | (1 << 1), "vm16" }, \ { (1 << 0), "prot16" }, { (1 << 0) | (1 << 2), "prot32" }, { (1 << 0) | (1 << 3), "prot64" }), \ REC->failed ? " failed" : "" # echo 1 > events/kvm/kvm_emulate_insn/enable # cat trace # tracer: nop # # entries-in-buffer/entries-written: 2183/2183 #P:12 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | qemu-kvm-1782 [002] ...1 140.931636: kvm_emulate_insn: 0:c102fa25:89 10 (prot32) qemu-kvm-1781 [004] ...1 140.931637: kvm_emulate_insn: 0:c102fa25:89 10 (prot32) Link: http://lkml.kernel.org/n/tip-wfw6y3b9ugtey8snaow9nmg5@git.kernel.org Link: http://lkml.kernel.org/r/1340757701-10711-2-git-send-email-namhyung@kernel.org Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Namhyung Kim Cc: kvm@vger.kernel.org Acked-by: Avi Kivity Signed-off-by: Namhyung Kim Signed-off-by: Steven Rostedt --- arch/x86/kvm/trace.h | 12 +----------- include/trace/ftrace.h | 1 + 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 911d2641f14c..62d02e3c3ed6 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -710,16 +710,6 @@ TRACE_EVENT(kvm_skinit, __entry->rip, __entry->slb) ); -#define __print_insn(insn, ilen) ({ \ - int i; \ - const char *ret = p->buffer + p->len; \ - \ - for (i = 0; i < ilen; ++i) \ - trace_seq_printf(p, " %02x", insn[i]); \ - trace_seq_printf(p, "%c", 0); \ - ret; \ - }) - #define KVM_EMUL_INSN_F_CR0_PE (1 << 0) #define KVM_EMUL_INSN_F_EFL_VM (1 << 1) #define KVM_EMUL_INSN_F_CS_D (1 << 2) @@ -786,7 +776,7 @@ TRACE_EVENT(kvm_emulate_insn, TP_printk("%x:%llx:%s (%s)%s", __entry->csbase, __entry->rip, - __print_insn(__entry->insn, __entry->len), + __print_hex(__entry->insn, __entry->len), __print_symbolic(__entry->flags, kvm_trace_symbol_emul_flags), __entry->failed ? " failed" : "" diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 769724944fc6..c6bc2faaf261 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -571,6 +571,7 @@ static inline void ftrace_test_probe_##call(void) \ #undef __print_flags #undef __print_symbolic +#undef __print_hex #undef __get_dynamic_array #undef __get_str -- GitLab From 6d158a813efcd09661c23f16ddf7e2ff834cb20c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 27 Jun 2012 20:46:14 -0400 Subject: [PATCH 3187/6849] tracing: Remove NR_CPUS array from trace_iterator Replace the NR_CPUS array of buffer_iter from the trace_iterator with an allocated array. This will just create an array of possible CPUS instead of the max number specified. The use of NR_CPUS in that array caused allocation failures for machines that were tight on memory. This did not cause any failures to the system itself (no crashes), but caused unnecessary failures for reading the trace files. Added a helper function called 'trace_buffer_iter()' that returns the buffer_iter item or NULL if it is not defined or the array was not allocated. Some routines do not require the array (tracing_open_pipe() for one). Reported-by: Dave Jones Signed-off-by: Steven Rostedt --- include/linux/ftrace_event.h | 2 +- kernel/trace/trace.c | 27 ++++++++++++++++++--------- kernel/trace/trace.h | 8 ++++++++ kernel/trace/trace_functions_graph.c | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 1aff18346c71..af961d6f7ab1 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -65,7 +65,7 @@ struct trace_iterator { void *private; int cpu_file; struct mutex mutex; - struct ring_buffer_iter *buffer_iter[NR_CPUS]; + struct ring_buffer_iter **buffer_iter; unsigned long iter_flags; /* trace_seq for __print_flags() and __print_symbolic() etc. */ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 748f6401edf6..b2af14e94c28 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1710,9 +1710,11 @@ EXPORT_SYMBOL_GPL(trace_vprintk); static void trace_iterator_increment(struct trace_iterator *iter) { + struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu); + iter->idx++; - if (iter->buffer_iter[iter->cpu]) - ring_buffer_read(iter->buffer_iter[iter->cpu], NULL); + if (buf_iter) + ring_buffer_read(buf_iter, NULL); } static struct trace_entry * @@ -1720,7 +1722,7 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts, unsigned long *lost_events) { struct ring_buffer_event *event; - struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu]; + struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, cpu); if (buf_iter) event = ring_buffer_iter_peek(buf_iter, ts); @@ -1858,10 +1860,10 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu) tr->data[cpu]->skipped_entries = 0; - if (!iter->buffer_iter[cpu]) + buf_iter = trace_buffer_iter(iter, cpu); + if (!buf_iter) return; - buf_iter = iter->buffer_iter[cpu]; ring_buffer_iter_reset(buf_iter); /* @@ -2207,13 +2209,15 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) int trace_empty(struct trace_iterator *iter) { + struct ring_buffer_iter *buf_iter; int cpu; /* If we are looking at one CPU buffer, only check that one */ if (iter->cpu_file != TRACE_PIPE_ALL_CPU) { cpu = iter->cpu_file; - if (iter->buffer_iter[cpu]) { - if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) + buf_iter = trace_buffer_iter(iter, cpu); + if (buf_iter) { + if (!ring_buffer_iter_empty(buf_iter)) return 0; } else { if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) @@ -2223,8 +2227,9 @@ int trace_empty(struct trace_iterator *iter) } for_each_tracing_cpu(cpu) { - if (iter->buffer_iter[cpu]) { - if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) + buf_iter = trace_buffer_iter(iter, cpu); + if (buf_iter) { + if (!ring_buffer_iter_empty(buf_iter)) return 0; } else { if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) @@ -2383,6 +2388,8 @@ __tracing_open(struct inode *inode, struct file *file) if (!iter) return ERR_PTR(-ENOMEM); + iter->buffer_iter = kzalloc(sizeof(*iter->buffer_iter) * num_possible_cpus(), + GFP_KERNEL); /* * We make a copy of the current tracer to avoid concurrent * changes on it while we are reading. @@ -2443,6 +2450,7 @@ __tracing_open(struct inode *inode, struct file *file) fail: mutex_unlock(&trace_types_lock); kfree(iter->trace); + kfree(iter->buffer_iter); seq_release_private(inode, file); return ERR_PTR(-ENOMEM); } @@ -2483,6 +2491,7 @@ static int tracing_release(struct inode *inode, struct file *file) mutex_destroy(&iter->mutex); free_cpumask_var(iter->started); kfree(iter->trace); + kfree(iter->buffer_iter); seq_release_private(inode, file); return 0; } diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 5aec220d2de0..55e1f7f0db12 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -317,6 +317,14 @@ struct tracer { #define TRACE_PIPE_ALL_CPU -1 +static inline struct ring_buffer_iter * +trace_buffer_iter(struct trace_iterator *iter, int cpu) +{ + if (iter->buffer_iter && iter->buffer_iter[cpu]) + return iter->buffer_iter[cpu]; + return NULL; +} + int tracer_init(struct tracer *t, struct trace_array *tr); int tracing_is_enabled(void); void trace_wake_up(void); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index a7d2a4c653d8..ce27c8ba8d31 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -538,7 +538,7 @@ get_return_for_leaf(struct trace_iterator *iter, next = &data->ret; } else { - ring_iter = iter->buffer_iter[iter->cpu]; + ring_iter = trace_buffer_iter(iter, iter->cpu); /* First peek to compare current entry and the next one */ if (ring_iter) -- GitLab From a5fb833172eca69136e9ee1ada778e404086ab8a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 28 Jun 2012 13:35:04 -0400 Subject: [PATCH 3188/6849] ring-buffer: Fix uninitialized read_stamp The ring buffer reader page is used to swap a page from the writable ring buffer. If the writer happens to be on that page, it ends up on the reader page, but will simply move off of it, back into the writable ring buffer as writes are added. The time stamp passed back to the readers is stored in the cpu_buffer per CPU descriptor. This stamp is updated when a swap of the reader page takes place, and it reads the current stamp from the page taken from the writable ring buffer. Everytime a writer goes to a new page, it updates the time stamp of that page. The problem happens if a reader reads a page from an empty per CPU ring buffer. If the buffer is empty, the swap still takes place, placing the writer at the start of the reader page. If at a later time, a write happens, it updates the page's time stamp and continues. But the problem is that the read_stamp does not get updated, because the page was already swapped. The solution to this was to not swap the page if the ring buffer happens to be empty. This also removes the side effect that the writes on the reader page will not get updated because the writer never gets back on the reader page without a swap. That is, if a read happens on an empty buffer, but then no reads happen for a while. If a swap took place, and the writer were to start writing a lot of data (function tracer), it will start overflowing the ring buffer and overwrite the older data. But because the writer never goes back onto the reader page, the data left on the reader page never gets overwritten. This causes the reader to see really old data, followed by a jump to newer data. Link: http://lkml.kernel.org/r/1340060577-9112-1-git-send-email-dhsharp@google.com Google-Bug-Id: 6410455 Reported-by: David Sharp tested-by: David Sharp Signed-off-by: Steven Rostedt --- kernel/trace/ring_buffer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1d0f6a8a0e5e..82a3e0c56b1d 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -3239,6 +3239,10 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) if (cpu_buffer->commit_page == cpu_buffer->reader_page) goto out; + /* Don't bother swapping if the ring buffer is empty */ + if (rb_num_of_entries(cpu_buffer) == 0) + goto out; + /* * Reset the reader page to size zero. */ -- GitLab From 26b6da6b7829dc7cf5d21e854564be90c7928323 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 27 Jun 2012 10:36:27 +0200 Subject: [PATCH 3189/6849] iwlegacy: print how long queue was actually stuck Every now and then, after resuming from suspend, the iwlegacy driver prints iwl4965 0000:03:00.0: Queue 2 stuck for 2000 ms. iwl4965 0000:03:00.0: On demand firmware reload I have no idea what causes these errors. But the code currently uses wd_timeout in the first error. wd_timeout will generally be set at IL_DEF_WD_TIMEOUT (ie, 2000). Perhaps printing for how long the queue was actually stuck can clarify the cause of these errors. Signed-off-by: Paul Bolle Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/common.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index cbf2dc18341f..763c7529921b 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4717,10 +4717,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt) struct il_tx_queue *txq = &il->txq[cnt]; struct il_queue *q = &txq->q; unsigned long timeout; + unsigned long now = jiffies; int ret; if (q->read_ptr == q->write_ptr) { - txq->time_stamp = jiffies; + txq->time_stamp = now; return 0; } @@ -4728,9 +4729,9 @@ il_check_stuck_queue(struct il_priv *il, int cnt) txq->time_stamp + msecs_to_jiffies(il->cfg->wd_timeout); - if (time_after(jiffies, timeout)) { + if (time_after(now, timeout)) { IL_ERR("Queue %d stuck for %u ms.\n", q->id, - il->cfg->wd_timeout); + jiffies_to_msecs(now - txq->time_stamp)); ret = il_force_reset(il, false); return (ret == -EAGAIN) ? 0 : 1; } -- GitLab From 73dc3eb8b93eda8101dcd6c0b2a0db00f4bc74fd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 27 Jun 2012 14:58:19 +0200 Subject: [PATCH 3190/6849] ath9k: fix ANI operation in AP mode ath9k_ani_reset (which is called at reset time) uses a state variable ani->update_ani to prevent the ANI noise immunity state on the operating channel from being overwritten by background scans. Unfortunately this is also being set for AP mode, since it's mixed with code that is only supposed to change the default settings after a reset. In AP mode this has the side effect of having ANI run, but being unable to change its runtime noise immunity level, making it effectively useless. Fix this by getting rid of ani->update_ani and passing a parameter to ath9k_hw_set_ofdm_nil and ath9k_hw_set_cck_nil instead. Signed-off-by: Felix Fietkau Cc: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 29 ++++++++++++++-------------- drivers/net/wireless/ath/ath9k/ani.h | 1 - 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 7ebc3465f22d..ff007f500feb 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -140,7 +140,8 @@ static void ath9k_ani_restart(struct ath_hw *ah) } /* Adjust the OFDM Noise Immunity Level */ -static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) +static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, + bool scan) { struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); @@ -153,7 +154,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) immunityLevel, BEACON_RSSI(ah), aniState->rssiThrLow, aniState->rssiThrHigh); - if (aniState->update_ani) + if (!scan) aniState->ofdmNoiseImmunityLevel = immunityLevel; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; @@ -199,13 +200,14 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) aniState = &ah->curchan->ani; if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) - ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); + ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false); } /* * Set the ANI settings to match an CCK level. */ -static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) +static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, + bool scan) { struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); @@ -222,7 +224,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; - if (aniState->update_ani) + if (!scan) aniState->cckNoiseImmunityLevel = immunityLevel; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; @@ -254,7 +256,8 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) aniState = &ah->curchan->ani; if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) - ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); + ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1, + false); } /* @@ -270,13 +273,15 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) /* lower OFDM noise immunity */ if (aniState->ofdmNoiseImmunityLevel > 0 && (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) { - ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1); + ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1, + false); return; } /* lower CCK noise immunity */ if (aniState->cckNoiseImmunityLevel > 0) - ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); + ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1, + false); } /* @@ -338,7 +343,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); - aniState->update_ani = false; ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL; cck_nil = ATH9K_ANI_CCK_DEF_LEVEL; } @@ -354,11 +358,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) is_scanning, aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); - - aniState->update_ani = true; } - ath9k_hw_set_ofdm_nil(ah, ofdm_nil); - ath9k_hw_set_cck_nil(ah, cck_nil); + ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning); + ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning); /* * enable phy counters if hw supports or if not, enable phy @@ -534,7 +536,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; - ani->update_ani = false; } /* diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index e9d841bbe86f..1485bf5e3518 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -114,7 +114,6 @@ struct ar5416AniState { u8 firstepLevel; u8 ofdmWeakSigDetect; u8 cckWeakSigThreshold; - bool update_ani; u32 listenTime; int32_t rssiThrLow; int32_t rssiThrHigh; -- GitLab From 812944891c598300afcc5628905d775019f25310 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 27 Jun 2012 20:00:26 +0530 Subject: [PATCH 3191/6849] ath9k_hw: make use of the wrapper to check for MCI init ath9k_hw_mci_is_enabled wrapper also takes care of ATH9K_HW_CAP_MCI being set for the AR9462 under test. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 26032cb59b8a..9ae6a4d97691 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -416,7 +416,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - if (AR_SREV_9462(ah)) { + if (ath9k_hw_mci_is_enabled(ah)) { sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; INIT_LIST_HEAD(&sc->btcoex.mci.info); -- GitLab From d8fffb4a9e13d1130b4fd0e577973704cad79f40 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 27 Jun 2012 20:00:27 +0530 Subject: [PATCH 3192/6849] ath9k: Fix signedness in a MCI debug message seems i got a message like this ath: phy0: BT_Status_Update: is_link=0, linkId=2, state=1, SEQ=-2085766476 initially. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index c40e568b5c2b..64cc782587d8 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -348,7 +348,7 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) seq_num = *((u32 *)(rx_payload + 12)); ath_dbg(common, MCI, - "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n", + "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%u\n", profile_status.is_link, profile_status.conn_handle, profile_status.is_critical, seq_num); -- GitLab From 589ebd85268293e64ff6b7e0dd4ed8fb26811aa7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 28 Jun 2012 02:33:40 +0200 Subject: [PATCH 3193/6849] ath9k: update AR934x initvals to latest version Generated using the initvals tool from the qca-swiss-army-knife repository from https://github.com/mcgrof/qca-swiss-army-knife Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9340_initvals.h | 475 +++++++++++------- 1 file changed, 290 insertions(+), 185 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h index 815a8af1beef..210fd79c6a72 100644 --- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,16 +19,16 @@ #define INITVALS_9340_H static const u32 ar9340_1p0_radio_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, - {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, + {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, - {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, + {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, }; static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -100,20 +101,20 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { }; static const u32 ar9340Modes_fast_clock_1p0[][3] = { - /* Addr 5G_HT20 5G_HT40 */ + /* Addr 5G_HT20 5G_HT40 */ {0x00001030, 0x00000268, 0x000004d0}, {0x00001070, 0x0000018c, 0x00000318}, {0x000010b0, 0x00000fd0, 0x00001fa0}, {0x00008014, 0x044c044c, 0x08980898}, {0x0000801c, 0x148ec02b, 0x148ec057}, {0x00008318, 0x000044c0, 0x00008980}, - {0x00009e00, 0x03721821, 0x03721821}, + {0x00009e00, 0x0372131c, 0x0372131c}, {0x0000a230, 0x0000000b, 0x00000016}, {0x0000a254, 0x00000898, 0x00001130}, }; static const u32 ar9340_1p0_radio_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00016000, 0x36db6db6}, {0x00016004, 0x6db6db40}, {0x00016008, 0x73f00000}, @@ -146,15 +147,13 @@ static const u32 ar9340_1p0_radio_core[][2] = { {0x00016100, 0x04cb0001}, {0x00016104, 0xfff80000}, {0x00016108, 0x00080010}, - {0x0001610c, 0x00000000}, {0x00016140, 0x50804008}, {0x00016144, 0x01884080}, {0x00016148, 0x000080c0}, {0x00016280, 0x01000015}, - {0x00016284, 0x05530000}, + {0x00016284, 0x15530000}, {0x00016288, 0x00318000}, {0x0001628c, 0x50000000}, - {0x00016290, 0x4080294f}, {0x00016380, 0x00000000}, {0x00016384, 0x00000000}, {0x00016388, 0x00800700}, @@ -219,13 +218,14 @@ static const u32 ar9340_1p0_radio_core[][2] = { }; static const u32 ar9340_1p0_radio_core_40M[][2] = { + /* Addr allmodes */ {0x0001609c, 0x02566f3a}, {0x000160ac, 0xa4647c00}, {0x000160b0, 0x01885f5a}, }; static const u32 ar9340_1p0_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, @@ -237,34 +237,37 @@ static const u32 ar9340_1p0_mac_postamble[][5] = { }; static const u32 ar9340_1p0_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, }; static const u32 ar9340_1p0_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, - {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, - {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, + {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e}, - {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, + {0x0000a204, 0x00003ec0, 0x00003ec4, 0x00003ec4, 0x00003ec0}, {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f}, {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, @@ -277,11 +280,11 @@ static const u32 ar9340_1p0_baseband_postamble[][5] = { {0x0000a288, 0x00000220, 0x00000220, 0x00000110, 0x00000110}, {0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a2d0, 0x00041983, 0x00041983, 0x00041982, 0x00041982}, + {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000}, + {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000}, {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, @@ -289,21 +292,21 @@ static const u32 ar9340_1p0_baseband_postamble[][5] = { }; static const u32 ar9340_1p0_baseband_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00009800, 0xafe68e30}, {0x00009804, 0xfd14e000}, {0x00009808, 0x9c0a9f6b}, {0x0000980c, 0x04900000}, - {0x00009814, 0xb280c00a}, + {0x00009814, 0x3280c00a}, {0x00009818, 0x00000000}, {0x0000981c, 0x00020028}, - {0x00009834, 0x5f3ca3de}, + {0x00009834, 0x6400a190}, {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, + {0x0000983c, 0x14000600}, {0x00009880, 0x201fff00}, {0x00009884, 0x00001042}, {0x000098a4, 0x00200400}, - {0x000098b0, 0x52440bbe}, + {0x000098b0, 0x32840bbe}, {0x000098d0, 0x004b6a8e}, {0x000098d4, 0x00000820}, {0x000098dc, 0x00000000}, @@ -329,7 +332,6 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x00009e30, 0x06336f77}, {0x00009e34, 0x6af6532f}, {0x00009e38, 0x0cc80c00}, - {0x00009e3c, 0xcf946222}, {0x00009e40, 0x0d261820}, {0x00009e4c, 0x00001004}, {0x00009e50, 0x00ff03f1}, @@ -342,8 +344,6 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a220, 0x00000000}, {0x0000a224, 0x00000000}, {0x0000a228, 0x10002310}, - {0x0000a22c, 0x01036a1e}, - {0x0000a234, 0x10000fff}, {0x0000a23c, 0x00000000}, {0x0000a244, 0x0c000000}, {0x0000a2a0, 0x00000001}, @@ -351,10 +351,6 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a2c8, 0x00000000}, {0x0000a2cc, 0x18c43433}, {0x0000a2d4, 0x00000000}, - {0x0000a2dc, 0x00000000}, - {0x0000a2e0, 0x00000000}, - {0x0000a2e4, 0x00000000}, - {0x0000a2e8, 0x00000000}, {0x0000a2ec, 0x00000000}, {0x0000a2f0, 0x00000000}, {0x0000a2f4, 0x00000000}, @@ -385,7 +381,7 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a3e8, 0x20202020}, {0x0000a3ec, 0x20202020}, {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000246}, + {0x0000a3f4, 0x00000000}, {0x0000a3f8, 0x0cdbd380}, {0x0000a3fc, 0x000f0f01}, {0x0000a400, 0x8fa91f01}, @@ -402,33 +398,17 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a430, 0x1ce739ce}, {0x0000a434, 0x00000000}, {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00000000}, + {0x0000a43c, 0x00100000}, {0x0000a440, 0x00000000}, {0x0000a444, 0x00000000}, - {0x0000a448, 0x04000080}, + {0x0000a448, 0x05000080}, {0x0000a44c, 0x00000001}, {0x0000a450, 0x00010000}, {0x0000a458, 0x00000000}, - {0x0000a600, 0x00000000}, - {0x0000a604, 0x00000000}, - {0x0000a608, 0x00000000}, - {0x0000a60c, 0x00000000}, - {0x0000a610, 0x00000000}, - {0x0000a614, 0x00000000}, - {0x0000a618, 0x00000000}, - {0x0000a61c, 0x00000000}, - {0x0000a620, 0x00000000}, - {0x0000a624, 0x00000000}, - {0x0000a628, 0x00000000}, - {0x0000a62c, 0x00000000}, - {0x0000a630, 0x00000000}, - {0x0000a634, 0x00000000}, - {0x0000a638, 0x00000000}, - {0x0000a63c, 0x00000000}, {0x0000a640, 0x00000000}, {0x0000a644, 0x3fad9d74}, {0x0000a648, 0x0048060a}, - {0x0000a64c, 0x00000637}, + {0x0000a64c, 0x00003c37}, {0x0000a670, 0x03020100}, {0x0000a674, 0x09080504}, {0x0000a678, 0x0d0c0b0a}, @@ -451,10 +431,6 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a8f4, 0x00000000}, {0x0000b2d0, 0x00000080}, {0x0000b2d4, 0x00000000}, - {0x0000b2dc, 0x00000000}, - {0x0000b2e0, 0x00000000}, - {0x0000b2e4, 0x00000000}, - {0x0000b2e8, 0x00000000}, {0x0000b2ec, 0x00000000}, {0x0000b2f0, 0x00000000}, {0x0000b2f4, 0x00000000}, @@ -465,80 +441,108 @@ static const u32 ar9340_1p0_baseband_core[][2] = { }; static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a504, 0x04002222, 0x04002222, 0x02000001, 0x02000001}, + {0x0000a508, 0x09002421, 0x09002421, 0x05000003, 0x05000003}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0a000005, 0x0a000005}, + {0x0000a510, 0x13004620, 0x13004620, 0x0e000201, 0x0e000201}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000203, 0x11000203}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x14000401, 0x14000401}, + {0x0000a51c, 0x21005420, 0x21005420, 0x18000403, 0x18000403}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000602, 0x1b000602}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000802, 0x1f000802}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x21000620, 0x21000620}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x25000820, 0x25000820}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x29000822, 0x29000822}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2d000824, 0x2d000824}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x30000828, 0x30000828}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x3400082a, 0x3400082a}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38000849, 0x38000849}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b000a2c, 0x3b000a2c}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e000e2b, 0x3e000e2b}, + {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42000e2d, 0x42000e2d}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x4500124a, 0x4500124a}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x4900124c, 0x4900124c}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c00126c, 0x4c00126c}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x4f00128c, 0x4f00128c}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x52001290, 0x52001290}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, + {0x0000a584, 0x04802222, 0x04802222, 0x02800001, 0x02800001}, + {0x0000a588, 0x09802421, 0x09802421, 0x05800003, 0x05800003}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0a800005, 0x0a800005}, + {0x0000a590, 0x13804620, 0x13804620, 0x0e800201, 0x0e800201}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800203, 0x11800203}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x14800401, 0x14800401}, + {0x0000a59c, 0x21805420, 0x21805420, 0x18800403, 0x18800403}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800602, 0x1b800602}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800802, 0x1f800802}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x21800620, 0x21800620}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x25800820, 0x25800820}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x29800822, 0x29800822}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2d800824, 0x2d800824}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x30800828, 0x30800828}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x3480082a, 0x3480082a}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38800849, 0x38800849}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b800a2c, 0x3b800a2c}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e800e2b, 0x3e800e2b}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42800e2d, 0x42800e2d}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x4580124a, 0x4580124a}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x4980124c, 0x4980124c}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c80126c, 0x4c80126c}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x4f80128c, 0x4f80128c}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x52801290, 0x52801290}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, + {0x00016044, 0x056db2db, 0x056db2db, 0x022492db, 0x022492db}, {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, - {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, + {0x00016444, 0x056db2db, 0x056db2db, 0x022492db, 0x022492db}, {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, }; static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -559,7 +563,7 @@ static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, + {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, @@ -604,13 +608,43 @@ static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, + {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, + {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, + {0x00016048, 0x8e481666, 0x8e481666, 0x8e481266, 0x8e481266}, + {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, + {0x00016448, 0x8e481666, 0x8e481666, 0x8e481266, 0x8e481266}, }; + static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a022e, 0x206a022e, 0x206a00ae, 0x206a00ae}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000a2dc, 0xfef5d402, 0xfef5d402, 0xfdab5b52, 0xfdab5b52}, + {0x0000a2e0, 0xfe896600, 0xfe896600, 0xfd339c84, 0xfd339c84}, + {0x0000a2e4, 0xff01f800, 0xff01f800, 0xfec3e000, 0xfec3e000}, + {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -676,15 +710,34 @@ static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, - {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, - {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, - {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, + {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, + {0x00016048, 0x8e480086, 0x8e480086, 0x8e480086, 0x8e480086}, + {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, + {0x00016448, 0x8e480086, 0x8e480086, 0x8e480086, 0x8e480086}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, + {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, + {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000b2dc, 0xfef5d402, 0xfef5d402, 0xfdab5b52, 0xfdab5b52}, + {0x0000b2e0, 0xfe896600, 0xfe896600, 0xfd339c84, 0xfd339c84}, + {0x0000b2e4, 0xff01f800, 0xff01f800, 0xfec3e000, 0xfec3e000}, + {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, }; - static const u32 ar9340Common_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -845,14 +898,14 @@ static const u32 ar9340Common_rx_gain_table_1p0[][2] = { {0x0000b074, 0x00000000}, {0x0000b078, 0x00000000}, {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, + {0x0000b080, 0x23232323}, + {0x0000b084, 0x21232323}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, + {0x0000b094, 0x03030305}, + {0x0000b098, 0x00000003}, + {0x0000b09c, 0x00000000}, {0x0000b0a0, 0x00000000}, {0x0000b0a4, 0x00000000}, {0x0000b0a8, 0x00000000}, @@ -944,7 +997,11 @@ static const u32 ar9340Common_rx_gain_table_1p0[][2] = { }; static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -952,8 +1009,8 @@ static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, + {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, @@ -965,19 +1022,19 @@ static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, @@ -1010,14 +1067,40 @@ static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, - {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, + {0x00016048, 0x24925666, 0x24925666, 0x24925266, 0x24925266}, + {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, + {0x00016288, 0xf0318000, 0xf0318000, 0xf0318000, 0xf0318000}, {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, - {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, + {0x00016448, 0x24925666, 0x24925666, 0x24925266, 0x24925266}, }; static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -1025,8 +1108,8 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, + {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402}, + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603}, {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02}, {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04}, @@ -1038,19 +1121,19 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861}, {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, @@ -1083,14 +1166,36 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266}, + {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, + {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, + {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000}, {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266}, + {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, }; static const u32 ar9340_1p0_mac_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00000008, 0x00000000}, {0x00000030, 0x00020085}, {0x00000034, 0x00000005}, @@ -1119,6 +1224,7 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x00008004, 0x00000000}, {0x00008008, 0x00000000}, {0x0000800c, 0x00000000}, + {0x00008010, 0x00080800}, {0x00008018, 0x00000000}, {0x00008020, 0x00000000}, {0x00008038, 0x00000000}, @@ -1146,7 +1252,7 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x000080bc, 0x00000000}, {0x000080c0, 0x2a800000}, {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c20}, + {0x000080c8, 0x13881c22}, {0x000080cc, 0x01f40000}, {0x000080d0, 0x00252500}, {0x000080d4, 0x00a00000}, @@ -1250,11 +1356,11 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x000083c4, 0x00000000}, {0x000083c8, 0x00000000}, {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, + {0x000083d0, 0x000101ff}, }; static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -1514,12 +1620,11 @@ static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = { }; static const u32 ar9340_1p0_soc_preamble[][2] = { - /* Addr allmodes */ - {0x000040a4, 0x00a0c1c9}, + /* Addr allmodes */ {0x00007008, 0x00000000}, {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, }; -#endif +#endif /* INITVALS_9340_H */ -- GitLab From 469979173ecda9c472c495608d6d540ec33ab85d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 28 Jun 2012 02:33:41 +0200 Subject: [PATCH 3194/6849] ath9k: de-duplicate initvals The initvals tool from https://github.com/mcgrof/qca-swiss-army-knife has been modified to detect identical initval tables and replace them with macros. This patch contains the generated changes. On MIPS this reduces the binary size by 24 KB with no runtime changes. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- .../wireless/ath/ath9k/ar9003_2p2_initvals.h | 1 + .../wireless/ath/ath9k/ar9330_1p1_initvals.h | 53 +- .../wireless/ath/ath9k/ar9330_1p2_initvals.h | 882 +--------- .../net/wireless/ath/ath9k/ar9340_initvals.h | 290 +--- .../wireless/ath/ath9k/ar9462_2p0_initvals.h | 5 +- .../net/wireless/ath/ath9k/ar9485_initvals.h | 1528 +++++++---------- .../wireless/ath/ath9k/ar9580_1p0_initvals.h | 772 +-------- 7 files changed, 652 insertions(+), 2879 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 952cb2b4656b..89bf94d4d8a1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h index 1bd3a3d22101..6e1756bc3833 100644 --- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h @@ -337,12 +337,7 @@ static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, }; -static const u32 ar9331_1p1_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; +#define ar9331_1p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 static const u32 ar9331_1p1_xtal_25M[][2] = { /* Addr allmodes */ @@ -783,17 +778,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, }; -static const u32 ar9331_1p1_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; +#define ar9331_1p1_mac_postamble ar9300_2p2_mac_postamble static const u32 ar9331_1p1_soc_preamble[][2] = { /* Addr allmodes */ @@ -1112,38 +1097,4 @@ static const u32 ar9331_common_tx_gain_offset1_1[][1] = { {0x00000000}, }; -static const u32 ar9331_1p1_chansel_xtal_25M[] = { - 0x0101479e, - 0x0101d027, - 0x010258af, - 0x0102e138, - 0x010369c0, - 0x0103f249, - 0x01047ad1, - 0x0105035a, - 0x01058be2, - 0x0106146b, - 0x01069cf3, - 0x0107257c, - 0x0107ae04, - 0x0108f5b2, -}; - -static const u32 ar9331_1p1_chansel_xtal_40M[] = { - 0x00a0ccbe, - 0x00a12213, - 0x00a17769, - 0x00a1ccbe, - 0x00a22213, - 0x00a27769, - 0x00a2ccbe, - 0x00a32213, - 0x00a37769, - 0x00a3ccbe, - 0x00a42213, - 0x00a47769, - 0x00a4ccbe, - 0x00a5998b, -}; - #endif /* INITVALS_9330_1P1_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h index 0e6ca0834b34..57ed8a112173 100644 --- a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,8 +18,8 @@ #ifndef INITVALS_9330_1P2_H #define INITVALS_9330_1P2_H -static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, @@ -102,8 +103,14 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = { {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, }; +#define ar9331_modes_high_power_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2 + +#define ar9331_modes_low_ob_db_tx_gain_1p2 ar9331_modes_high_power_tx_gain_1p2 + +#define ar9331_modes_lowest_ob_db_tx_gain_1p2 ar9331_modes_low_ob_db_tx_gain_1p2 + static const u32 ar9331_1p2_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, @@ -147,191 +154,6 @@ static const u32 ar9331_1p2_baseband_postamble[][5] = { {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; -static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, - {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, - {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, - {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, - {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, - {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, - {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, - {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, - {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, - {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, - {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, - {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, - {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, - {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, - {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, - {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, - {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, - {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, - {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, - {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, - {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, - {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, - {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, - {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, - {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, - {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, -}; - -static const u32 ar9331_modes_low_ob_db_tx_gain_1p2[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, - {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, - {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, - {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, - {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, - {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, - {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, - {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, - {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, - {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, - {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, - {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, - {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, - {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, - {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, - {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, - {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, - {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, - {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, - {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, - {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, - {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, - {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, - {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, - {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, - {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, -}; - -static const u32 ar9331_1p2_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; - -static const u32 ar9331_1p2_xtal_25M[][2] = { - /* Addr allmodes */ - {0x00007038, 0x000002f8}, - {0x00008244, 0x0010f3d7}, - {0x0000824c, 0x0001e7ae}, - {0x0001609c, 0x0f508f29}, -}; - static const u32 ar9331_1p2_radio_core[][2] = { /* Addr allmodes */ {0x00016000, 0x36db6db6}, @@ -397,684 +219,24 @@ static const u32 ar9331_1p2_radio_core[][2] = { {0x000163d4, 0x00000000}, }; -static const u32 ar9331_1p2_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, -}; +#define ar9331_1p2_baseband_core_txfir_coeff_japan_2484 ar9331_1p1_baseband_core_txfir_coeff_japan_2484 -static const u32 ar9331_common_wo_xlna_rx_gain_1p2[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00060005}, - {0x0000a004, 0x00810080}, - {0x0000a008, 0x00830082}, - {0x0000a00c, 0x00850084}, - {0x0000a010, 0x01820181}, - {0x0000a014, 0x01840183}, - {0x0000a018, 0x01880185}, - {0x0000a01c, 0x018a0189}, - {0x0000a020, 0x02850284}, - {0x0000a024, 0x02890288}, - {0x0000a028, 0x028b028a}, - {0x0000a02c, 0x03850384}, - {0x0000a030, 0x03890388}, - {0x0000a034, 0x038b038a}, - {0x0000a038, 0x038d038c}, - {0x0000a03c, 0x03910390}, - {0x0000a040, 0x03930392}, - {0x0000a044, 0x03950394}, - {0x0000a048, 0x00000396}, - {0x0000a04c, 0x00000000}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x28282828}, - {0x0000a084, 0x28282828}, - {0x0000a088, 0x28282828}, - {0x0000a08c, 0x28282828}, - {0x0000a090, 0x28282828}, - {0x0000a094, 0x24242428}, - {0x0000a098, 0x171e1e1e}, - {0x0000a09c, 0x02020b0b}, - {0x0000a0a0, 0x02020202}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x22072208}, - {0x0000a0c4, 0x22052206}, - {0x0000a0c8, 0x22032204}, - {0x0000a0cc, 0x22012202}, - {0x0000a0d0, 0x221f2200}, - {0x0000a0d4, 0x221d221e}, - {0x0000a0d8, 0x33023303}, - {0x0000a0dc, 0x33003301}, - {0x0000a0e0, 0x331e331f}, - {0x0000a0e4, 0x4402331d}, - {0x0000a0e8, 0x44004401}, - {0x0000a0ec, 0x441e441f}, - {0x0000a0f0, 0x55025503}, - {0x0000a0f4, 0x55005501}, - {0x0000a0f8, 0x551e551f}, - {0x0000a0fc, 0x6602551d}, - {0x0000a100, 0x66006601}, - {0x0000a104, 0x661e661f}, - {0x0000a108, 0x7703661d}, - {0x0000a10c, 0x77017702}, - {0x0000a110, 0x00007700}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x111f1100}, - {0x0000a148, 0x111d111e}, - {0x0000a14c, 0x111b111c}, - {0x0000a150, 0x22032204}, - {0x0000a154, 0x22012202}, - {0x0000a158, 0x221f2200}, - {0x0000a15c, 0x221d221e}, - {0x0000a160, 0x33013302}, - {0x0000a164, 0x331f3300}, - {0x0000a168, 0x4402331e}, - {0x0000a16c, 0x44004401}, - {0x0000a170, 0x441e441f}, - {0x0000a174, 0x55015502}, - {0x0000a178, 0x551f5500}, - {0x0000a17c, 0x6602551e}, - {0x0000a180, 0x66006601}, - {0x0000a184, 0x661e661f}, - {0x0000a188, 0x7703661d}, - {0x0000a18c, 0x77017702}, - {0x0000a190, 0x00007700}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000296}, -}; +#define ar9331_1p2_xtal_25M ar9331_1p1_xtal_25M -static const u32 ar9331_1p2_baseband_core[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafe68e30}, - {0x00009804, 0xfd14e000}, - {0x00009808, 0x9c0a8f6b}, - {0x0000980c, 0x04800000}, - {0x00009814, 0x9280c00a}, - {0x00009818, 0x00000000}, - {0x0000981c, 0x00020028}, - {0x00009834, 0x5f3ca3de}, - {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, - {0x00009880, 0x201fff00}, - {0x00009884, 0x00001042}, - {0x000098a4, 0x00200400}, - {0x000098b0, 0x32840bbe}, - {0x000098d0, 0x004b6a8e}, - {0x000098d4, 0x00000820}, - {0x000098dc, 0x00000000}, - {0x000098f0, 0x00000000}, - {0x000098f4, 0x00000000}, - {0x00009c04, 0x00000000}, - {0x00009c08, 0x03200000}, - {0x00009c0c, 0x00000000}, - {0x00009c10, 0x00000000}, - {0x00009c14, 0x00046384}, - {0x00009c18, 0x05b6b440}, - {0x00009c1c, 0x00b6b440}, - {0x00009d00, 0xc080a333}, - {0x00009d04, 0x40206c10}, - {0x00009d08, 0x009c4060}, - {0x00009d0c, 0x1883800a}, - {0x00009d10, 0x01834061}, - {0x00009d14, 0x00c00400}, - {0x00009d18, 0x00000000}, - {0x00009e08, 0x0038233c}, - {0x00009e24, 0x9927b515}, - {0x00009e28, 0x12ef0200}, - {0x00009e30, 0x06336f77}, - {0x00009e34, 0x6af6532f}, - {0x00009e38, 0x0cc80c00}, - {0x00009e40, 0x0d261820}, - {0x00009e4c, 0x00001004}, - {0x00009e50, 0x00ff03f1}, - {0x00009fc0, 0x803e4788}, - {0x00009fc4, 0x0001efb5}, - {0x00009fcc, 0x40000014}, - {0x0000a20c, 0x00000000}, - {0x0000a220, 0x00000000}, - {0x0000a224, 0x00000000}, - {0x0000a228, 0x10002310}, - {0x0000a23c, 0x00000000}, - {0x0000a244, 0x0c000000}, - {0x0000a2a0, 0x00000001}, - {0x0000a2c0, 0x00000001}, - {0x0000a2c8, 0x00000000}, - {0x0000a2cc, 0x18c43433}, - {0x0000a2d4, 0x00000000}, - {0x0000a2dc, 0x00000000}, - {0x0000a2e0, 0x00000000}, - {0x0000a2e4, 0x00000000}, - {0x0000a2e8, 0x00000000}, - {0x0000a2ec, 0x00000000}, - {0x0000a2f0, 0x00000000}, - {0x0000a2f4, 0x00000000}, - {0x0000a2f8, 0x00000000}, - {0x0000a344, 0x00000000}, - {0x0000a34c, 0x00000000}, - {0x0000a350, 0x0000a000}, - {0x0000a364, 0x00000000}, - {0x0000a370, 0x00000000}, - {0x0000a390, 0x00000001}, - {0x0000a394, 0x00000444}, - {0x0000a398, 0x001f0e0f}, - {0x0000a39c, 0x0075393f}, - {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x00000000}, - {0x0000a3a8, 0xaaaaaaaa}, - {0x0000a3ac, 0x3c466478}, - {0x0000a3c0, 0x20202020}, - {0x0000a3c4, 0x22222220}, - {0x0000a3c8, 0x20200020}, - {0x0000a3cc, 0x20202020}, - {0x0000a3d0, 0x20202020}, - {0x0000a3d4, 0x20202020}, - {0x0000a3d8, 0x20202020}, - {0x0000a3dc, 0x20202020}, - {0x0000a3e0, 0x20202020}, - {0x0000a3e4, 0x20202020}, - {0x0000a3e8, 0x20202020}, - {0x0000a3ec, 0x20202020}, - {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000006}, - {0x0000a3f8, 0x0cdbd380}, - {0x0000a3fc, 0x000f0f01}, - {0x0000a400, 0x8fa91f01}, - {0x0000a404, 0x00000000}, - {0x0000a408, 0x0e79e5c6}, - {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739ce}, - {0x0000a418, 0x2d001dce}, - {0x0000a41c, 0x1ce739ce}, - {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739ce}, - {0x0000a428, 0x000001ce}, - {0x0000a42c, 0x1ce739ce}, - {0x0000a430, 0x1ce739ce}, - {0x0000a434, 0x00000000}, - {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00000000}, - {0x0000a440, 0x00000000}, - {0x0000a444, 0x00000000}, - {0x0000a448, 0x04000000}, - {0x0000a44c, 0x00000001}, - {0x0000a450, 0x00010000}, - {0x0000a458, 0x00000000}, - {0x0000a640, 0x00000000}, - {0x0000a644, 0x3fad9d74}, - {0x0000a648, 0x0048060a}, - {0x0000a64c, 0x00003c37}, - {0x0000a670, 0x03020100}, - {0x0000a674, 0x09080504}, - {0x0000a678, 0x0d0c0b0a}, - {0x0000a67c, 0x13121110}, - {0x0000a680, 0x31301514}, - {0x0000a684, 0x35343332}, - {0x0000a688, 0x00000036}, - {0x0000a690, 0x00000838}, - {0x0000a7c0, 0x00000000}, - {0x0000a7c4, 0xfffffffc}, - {0x0000a7c8, 0x00000000}, - {0x0000a7cc, 0x00000000}, - {0x0000a7d0, 0x00000000}, - {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000001}, -}; +#define ar9331_1p2_xtal_40M ar9331_1p1_xtal_40M -static const u32 ar9331_modes_high_power_tx_gain_1p2[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, - {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, - {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, - {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, - {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, - {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, - {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, - {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, - {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, - {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, - {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, - {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, - {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, - {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, - {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, - {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, - {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, - {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, - {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, - {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, - {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, - {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, - {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, - {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, - {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, - {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, - {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, - {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, -}; +#define ar9331_1p2_baseband_core ar9331_1p1_baseband_core -static const u32 ar9331_1p2_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; +#define ar9331_1p2_soc_postamble ar9331_1p1_soc_postamble -static const u32 ar9331_1p2_soc_preamble[][2] = { - /* Addr allmodes */ - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000002f8}, -}; +#define ar9331_1p2_mac_postamble ar9331_1p1_mac_postamble -static const u32 ar9331_1p2_xtal_40M[][2] = { - /* Addr allmodes */ - {0x00007038, 0x000004c2}, - {0x00008244, 0x0010f400}, - {0x0000824c, 0x0001e800}, - {0x0001609c, 0x0b283f31}, -}; +#define ar9331_1p2_soc_preamble ar9331_1p1_soc_preamble -static const u32 ar9331_1p2_mac_core[][2] = { - /* Addr allmodes */ - {0x00000008, 0x00000000}, - {0x00000030, 0x00020085}, - {0x00000034, 0x00000005}, - {0x00000040, 0x00000000}, - {0x00000044, 0x00000000}, - {0x00000048, 0x00000008}, - {0x0000004c, 0x00000010}, - {0x00000050, 0x00000000}, - {0x00001040, 0x002ffc0f}, - {0x00001044, 0x002ffc0f}, - {0x00001048, 0x002ffc0f}, - {0x0000104c, 0x002ffc0f}, - {0x00001050, 0x002ffc0f}, - {0x00001054, 0x002ffc0f}, - {0x00001058, 0x002ffc0f}, - {0x0000105c, 0x002ffc0f}, - {0x00001060, 0x002ffc0f}, - {0x00001064, 0x002ffc0f}, - {0x000010f0, 0x00000100}, - {0x00001270, 0x00000000}, - {0x000012b0, 0x00000000}, - {0x000012f0, 0x00000000}, - {0x0000143c, 0x00000000}, - {0x0000147c, 0x00000000}, - {0x00008000, 0x00000000}, - {0x00008004, 0x00000000}, - {0x00008008, 0x00000000}, - {0x0000800c, 0x00000000}, - {0x00008018, 0x00000000}, - {0x00008020, 0x00000000}, - {0x00008038, 0x00000000}, - {0x0000803c, 0x00000000}, - {0x00008040, 0x00000000}, - {0x00008044, 0x00000000}, - {0x00008048, 0x00000000}, - {0x0000804c, 0xffffffff}, - {0x00008054, 0x00000000}, - {0x00008058, 0x00000000}, - {0x0000805c, 0x000fc78f}, - {0x00008060, 0x0000000f}, - {0x00008064, 0x00000000}, - {0x00008070, 0x00000310}, - {0x00008074, 0x00000020}, - {0x00008078, 0x00000000}, - {0x0000809c, 0x0000000f}, - {0x000080a0, 0x00000000}, - {0x000080a4, 0x02ff0000}, - {0x000080a8, 0x0e070605}, - {0x000080ac, 0x0000000d}, - {0x000080b0, 0x00000000}, - {0x000080b4, 0x00000000}, - {0x000080b8, 0x00000000}, - {0x000080bc, 0x00000000}, - {0x000080c0, 0x2a800000}, - {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c20}, - {0x000080cc, 0x01f40000}, - {0x000080d0, 0x00252500}, - {0x000080d4, 0x00a00000}, - {0x000080d8, 0x00400000}, - {0x000080dc, 0x00000000}, - {0x000080e0, 0xffffffff}, - {0x000080e4, 0x0000ffff}, - {0x000080e8, 0x3f3f3f3f}, - {0x000080ec, 0x00000000}, - {0x000080f0, 0x00000000}, - {0x000080f4, 0x00000000}, - {0x000080fc, 0x00020000}, - {0x00008100, 0x00000000}, - {0x00008108, 0x00000052}, - {0x0000810c, 0x00000000}, - {0x00008110, 0x00000000}, - {0x00008114, 0x000007ff}, - {0x00008118, 0x000000aa}, - {0x0000811c, 0x00003210}, - {0x00008124, 0x00000000}, - {0x00008128, 0x00000000}, - {0x0000812c, 0x00000000}, - {0x00008130, 0x00000000}, - {0x00008134, 0x00000000}, - {0x00008138, 0x00000000}, - {0x0000813c, 0x0000ffff}, - {0x00008144, 0xffffffff}, - {0x00008168, 0x00000000}, - {0x0000816c, 0x00000000}, - {0x00008170, 0x18486200}, - {0x00008174, 0x33332210}, - {0x00008178, 0x00000000}, - {0x0000817c, 0x00020000}, - {0x000081c0, 0x00000000}, - {0x000081c4, 0x33332210}, - {0x000081c8, 0x00000000}, - {0x000081cc, 0x00000000}, - {0x000081d4, 0x00000000}, - {0x000081ec, 0x00000000}, - {0x000081f0, 0x00000000}, - {0x000081f4, 0x00000000}, - {0x000081f8, 0x00000000}, - {0x000081fc, 0x00000000}, - {0x00008240, 0x00100000}, - {0x00008248, 0x00000800}, - {0x00008250, 0x00000000}, - {0x00008254, 0x00000000}, - {0x00008258, 0x00000000}, - {0x0000825c, 0x40000000}, - {0x00008260, 0x00080922}, - {0x00008264, 0x9d400010}, - {0x00008268, 0xffffffff}, - {0x0000826c, 0x0000ffff}, - {0x00008270, 0x00000000}, - {0x00008274, 0x40000000}, - {0x00008278, 0x003e4180}, - {0x0000827c, 0x00000004}, - {0x00008284, 0x0000002c}, - {0x00008288, 0x0000002c}, - {0x0000828c, 0x000000ff}, - {0x00008294, 0x00000000}, - {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000140}, - {0x00008314, 0x00000000}, - {0x0000831c, 0x0000010d}, - {0x00008328, 0x00000000}, - {0x0000832c, 0x00000007}, - {0x00008330, 0x00000302}, - {0x00008334, 0x00000700}, - {0x00008338, 0x00ff0000}, - {0x0000833c, 0x02400000}, - {0x00008340, 0x000107ff}, - {0x00008344, 0xaa48105b}, - {0x00008348, 0x008f0000}, - {0x0000835c, 0x00000000}, - {0x00008360, 0xffffffff}, - {0x00008364, 0xffffffff}, - {0x00008368, 0x00000000}, - {0x00008370, 0x00000000}, - {0x00008374, 0x000000ff}, - {0x00008378, 0x00000000}, - {0x0000837c, 0x00000000}, - {0x00008380, 0xffffffff}, - {0x00008384, 0xffffffff}, - {0x00008390, 0xffffffff}, - {0x00008394, 0xffffffff}, - {0x00008398, 0x00000000}, - {0x0000839c, 0x00000000}, - {0x000083a0, 0x00000000}, - {0x000083a4, 0x0000fa14}, - {0x000083a8, 0x000f0c00}, - {0x000083ac, 0x33332210}, - {0x000083b0, 0x33332210}, - {0x000083b4, 0x33332210}, - {0x000083b8, 0x33332210}, - {0x000083bc, 0x00000000}, - {0x000083c0, 0x00000000}, - {0x000083c4, 0x00000000}, - {0x000083c8, 0x00000000}, - {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, -}; +#define ar9331_1p2_mac_core ar9331_1p1_mac_core -static const u32 ar9331_common_rx_gain_1p2[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x01800082}, - {0x0000a014, 0x01820181}, - {0x0000a018, 0x01840183}, - {0x0000a01c, 0x01880185}, - {0x0000a020, 0x018a0189}, - {0x0000a024, 0x02850284}, - {0x0000a028, 0x02890288}, - {0x0000a02c, 0x03850384}, - {0x0000a030, 0x03890388}, - {0x0000a034, 0x038b038a}, - {0x0000a038, 0x038d038c}, - {0x0000a03c, 0x03910390}, - {0x0000a040, 0x03930392}, - {0x0000a044, 0x03950394}, - {0x0000a048, 0x00000396}, - {0x0000a04c, 0x00000000}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x28282828}, - {0x0000a084, 0x28282828}, - {0x0000a088, 0x28282828}, - {0x0000a08c, 0x28282828}, - {0x0000a090, 0x28282828}, - {0x0000a094, 0x21212128}, - {0x0000a098, 0x171c1c1c}, - {0x0000a09c, 0x02020212}, - {0x0000a0a0, 0x00000202}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x111f1100}, - {0x0000a0c8, 0x111d111e}, - {0x0000a0cc, 0x111b111c}, - {0x0000a0d0, 0x22032204}, - {0x0000a0d4, 0x22012202}, - {0x0000a0d8, 0x221f2200}, - {0x0000a0dc, 0x221d221e}, - {0x0000a0e0, 0x33013302}, - {0x0000a0e4, 0x331f3300}, - {0x0000a0e8, 0x4402331e}, - {0x0000a0ec, 0x44004401}, - {0x0000a0f0, 0x441e441f}, - {0x0000a0f4, 0x55015502}, - {0x0000a0f8, 0x551f5500}, - {0x0000a0fc, 0x6602551e}, - {0x0000a100, 0x66006601}, - {0x0000a104, 0x661e661f}, - {0x0000a108, 0x7703661d}, - {0x0000a10c, 0x77017702}, - {0x0000a110, 0x00007700}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x111f1100}, - {0x0000a148, 0x111d111e}, - {0x0000a14c, 0x111b111c}, - {0x0000a150, 0x22032204}, - {0x0000a154, 0x22012202}, - {0x0000a158, 0x221f2200}, - {0x0000a15c, 0x221d221e}, - {0x0000a160, 0x33013302}, - {0x0000a164, 0x331f3300}, - {0x0000a168, 0x4402331e}, - {0x0000a16c, 0x44004401}, - {0x0000a170, 0x441e441f}, - {0x0000a174, 0x55015502}, - {0x0000a178, 0x551f5500}, - {0x0000a17c, 0x6602551e}, - {0x0000a180, 0x66006601}, - {0x0000a184, 0x661e661f}, - {0x0000a188, 0x7703661d}, - {0x0000a18c, 0x77017702}, - {0x0000a190, 0x00007700}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000296}, -}; +#define ar9331_common_wo_xlna_rx_gain_1p2 ar9331_common_wo_xlna_rx_gain_1p1 + +#define ar9331_common_rx_gain_1p2 ar9485_common_rx_gain_1_1 #endif /* INITVALS_9330_1P2_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h index 210fd79c6a72..1d8235e19f0f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h @@ -100,18 +100,7 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, }; -static const u32 ar9340Modes_fast_clock_1p0[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00001030, 0x00000268, 0x000004d0}, - {0x00001070, 0x0000018c, 0x00000318}, - {0x000010b0, 0x00000fd0, 0x00001fa0}, - {0x00008014, 0x044c044c, 0x08980898}, - {0x0000801c, 0x148ec02b, 0x148ec057}, - {0x00008318, 0x000044c0, 0x00008980}, - {0x00009e00, 0x0372131c, 0x0372131c}, - {0x0000a230, 0x0000000b, 0x00000016}, - {0x0000a254, 0x00000898, 0x00001130}, -}; +#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2 static const u32 ar9340_1p0_radio_core[][2] = { /* Addr allmodes */ @@ -224,22 +213,9 @@ static const u32 ar9340_1p0_radio_core_40M[][2] = { {0x000160b0, 0x01885f5a}, }; -static const u32 ar9340_1p0_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; +#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble -static const u32 ar9340_1p0_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, -}; +#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble static const u32 ar9340_1p0_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -1359,265 +1335,7 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x000083d0, 0x000101ff}, }; -static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x03820190}, - {0x0000a030, 0x03840383}, - {0x0000a034, 0x03880385}, - {0x0000a038, 0x038a0389}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x29292929}, - {0x0000a084, 0x29292929}, - {0x0000a088, 0x29292929}, - {0x0000a08c, 0x29292929}, - {0x0000a090, 0x22292929}, - {0x0000a094, 0x1d1d2222}, - {0x0000a098, 0x0c111117}, - {0x0000a09c, 0x00030303}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; +#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2 static const u32 ar9340_1p0_soc_preamble[][2] = { /* Addr allmodes */ diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index bbf48918a56c..4ef7dcccaa2f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1007,7 +1008,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { static const u32 ar9462_2p0_soc_preamble[][2] = { /* Addr allmodes */ - {0x000040a4 ,0x00a0c1c9}, + {0x000040a4, 0x00a0c1c9}, {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index d16d029f81a9..fb4497fc7a3d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,599 +18,151 @@ #ifndef INITVALS_9485_H #define INITVALS_9485_H -static const u32 ar9485_1_1_mac_core[][2] = { - /* Addr allmodes */ - {0x00000008, 0x00000000}, - {0x00000030, 0x00020085}, - {0x00000034, 0x00000005}, - {0x00000040, 0x00000000}, - {0x00000044, 0x00000000}, - {0x00000048, 0x00000008}, - {0x0000004c, 0x00000010}, - {0x00000050, 0x00000000}, - {0x00001040, 0x002ffc0f}, - {0x00001044, 0x002ffc0f}, - {0x00001048, 0x002ffc0f}, - {0x0000104c, 0x002ffc0f}, - {0x00001050, 0x002ffc0f}, - {0x00001054, 0x002ffc0f}, - {0x00001058, 0x002ffc0f}, - {0x0000105c, 0x002ffc0f}, - {0x00001060, 0x002ffc0f}, - {0x00001064, 0x002ffc0f}, - {0x000010f0, 0x00000100}, - {0x00001270, 0x00000000}, - {0x000012b0, 0x00000000}, - {0x000012f0, 0x00000000}, - {0x0000143c, 0x00000000}, - {0x0000147c, 0x00000000}, - {0x00008000, 0x00000000}, - {0x00008004, 0x00000000}, - {0x00008008, 0x00000000}, - {0x0000800c, 0x00000000}, - {0x00008018, 0x00000000}, - {0x00008020, 0x00000000}, - {0x00008038, 0x00000000}, - {0x0000803c, 0x00000000}, - {0x00008040, 0x00000000}, - {0x00008044, 0x00000000}, - {0x00008048, 0x00000000}, - {0x0000804c, 0xffffffff}, - {0x00008054, 0x00000000}, - {0x00008058, 0x00000000}, - {0x0000805c, 0x000fc78f}, - {0x00008060, 0x0000000f}, - {0x00008064, 0x00000000}, - {0x00008070, 0x00000310}, - {0x00008074, 0x00000020}, - {0x00008078, 0x00000000}, - {0x0000809c, 0x0000000f}, - {0x000080a0, 0x00000000}, - {0x000080a4, 0x02ff0000}, - {0x000080a8, 0x0e070605}, - {0x000080ac, 0x0000000d}, - {0x000080b0, 0x00000000}, - {0x000080b4, 0x00000000}, - {0x000080b8, 0x00000000}, - {0x000080bc, 0x00000000}, - {0x000080c0, 0x2a800000}, - {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c22}, - {0x000080cc, 0x01f40000}, - {0x000080d0, 0x00252500}, - {0x000080d4, 0x00a00000}, - {0x000080d8, 0x00400000}, - {0x000080dc, 0x00000000}, - {0x000080e0, 0xffffffff}, - {0x000080e4, 0x0000ffff}, - {0x000080e8, 0x3f3f3f3f}, - {0x000080ec, 0x00000000}, - {0x000080f0, 0x00000000}, - {0x000080f4, 0x00000000}, - {0x000080fc, 0x00020000}, - {0x00008100, 0x00000000}, - {0x00008108, 0x00000052}, - {0x0000810c, 0x00000000}, - {0x00008110, 0x00000000}, - {0x00008114, 0x000007ff}, - {0x00008118, 0x000000aa}, - {0x0000811c, 0x00003210}, - {0x00008124, 0x00000000}, - {0x00008128, 0x00000000}, - {0x0000812c, 0x00000000}, - {0x00008130, 0x00000000}, - {0x00008134, 0x00000000}, - {0x00008138, 0x00000000}, - {0x0000813c, 0x0000ffff}, - {0x00008144, 0xffffffff}, - {0x00008168, 0x00000000}, - {0x0000816c, 0x00000000}, - {0x00008170, 0x18486200}, - {0x00008174, 0x33332210}, - {0x00008178, 0x00000000}, - {0x0000817c, 0x00020000}, - {0x000081c0, 0x00000000}, - {0x000081c4, 0x33332210}, - {0x000081d4, 0x00000000}, - {0x000081ec, 0x00000000}, - {0x000081f0, 0x00000000}, - {0x000081f4, 0x00000000}, - {0x000081f8, 0x00000000}, - {0x000081fc, 0x00000000}, - {0x00008240, 0x00100000}, - {0x00008244, 0x0010f400}, - {0x00008248, 0x00000800}, - {0x0000824c, 0x0001e800}, - {0x00008250, 0x00000000}, - {0x00008254, 0x00000000}, - {0x00008258, 0x00000000}, - {0x0000825c, 0x40000000}, - {0x00008260, 0x00080922}, - {0x00008264, 0x9ca00010}, - {0x00008268, 0xffffffff}, - {0x0000826c, 0x0000ffff}, - {0x00008270, 0x00000000}, - {0x00008274, 0x40000000}, - {0x00008278, 0x003e4180}, - {0x0000827c, 0x00000004}, - {0x00008284, 0x0000002c}, - {0x00008288, 0x0000002c}, - {0x0000828c, 0x000000ff}, - {0x00008294, 0x00000000}, - {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000140}, - {0x00008314, 0x00000000}, - {0x0000831c, 0x0000010d}, - {0x00008328, 0x00000000}, - {0x0000832c, 0x00000007}, - {0x00008330, 0x00000302}, - {0x00008334, 0x00000700}, - {0x00008338, 0x00ff0000}, - {0x0000833c, 0x02400000}, - {0x00008340, 0x000107ff}, - {0x00008344, 0xa248105b}, - {0x00008348, 0x008f0000}, - {0x0000835c, 0x00000000}, - {0x00008360, 0xffffffff}, - {0x00008364, 0xffffffff}, - {0x00008368, 0x00000000}, - {0x00008370, 0x00000000}, - {0x00008374, 0x000000ff}, - {0x00008378, 0x00000000}, - {0x0000837c, 0x00000000}, - {0x00008380, 0xffffffff}, - {0x00008384, 0xffffffff}, - {0x00008390, 0xffffffff}, - {0x00008394, 0xffffffff}, - {0x00008398, 0x00000000}, - {0x0000839c, 0x00000000}, - {0x000083a0, 0x00000000}, - {0x000083a4, 0x0000fa14}, - {0x000083a8, 0x000f0c00}, - {0x000083ac, 0x33332210}, - {0x000083b0, 0x33332210}, - {0x000083b4, 0x33332210}, - {0x000083b8, 0x33332210}, - {0x000083bc, 0x00000000}, - {0x000083c0, 0x00000000}, - {0x000083c4, 0x00000000}, - {0x000083c8, 0x00000000}, - {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, -}; - -static const u32 ar9485_1_1_baseband_core[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafe68e30}, - {0x00009804, 0xfd14e000}, - {0x00009808, 0x9c0a8f6b}, - {0x0000980c, 0x04800000}, - {0x00009814, 0x9280c00a}, - {0x00009818, 0x00000000}, - {0x0000981c, 0x00020028}, - {0x00009834, 0x5f3ca3de}, - {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, - {0x00009880, 0x201fff00}, - {0x00009884, 0x00001042}, - {0x000098a4, 0x00200400}, - {0x000098b0, 0x52440bbe}, - {0x000098d0, 0x004b6a8e}, - {0x000098d4, 0x00000820}, - {0x000098dc, 0x00000000}, - {0x000098f0, 0x00000000}, - {0x000098f4, 0x00000000}, - {0x00009c04, 0x00000000}, - {0x00009c08, 0x03200000}, - {0x00009c0c, 0x00000000}, - {0x00009c10, 0x00000000}, - {0x00009c14, 0x00046384}, - {0x00009c18, 0x05b6b440}, - {0x00009c1c, 0x00b6b440}, - {0x00009d00, 0xc080a333}, - {0x00009d04, 0x40206c10}, - {0x00009d08, 0x009c4060}, - {0x00009d0c, 0x1883800a}, - {0x00009d10, 0x01834061}, - {0x00009d14, 0x00c00400}, - {0x00009d18, 0x00000000}, - {0x00009d1c, 0x00000000}, - {0x00009e08, 0x0038233c}, - {0x00009e24, 0x9927b515}, - {0x00009e28, 0x12ef0200}, - {0x00009e30, 0x06336f77}, - {0x00009e34, 0x6af6532f}, - {0x00009e38, 0x0cc80c00}, - {0x00009e40, 0x0d261820}, - {0x00009e4c, 0x00001004}, - {0x00009e50, 0x00ff03f1}, - {0x00009fc0, 0x80be4788}, - {0x00009fc4, 0x0001efb5}, - {0x00009fcc, 0x40000014}, - {0x0000a20c, 0x00000000}, - {0x0000a210, 0x00000000}, - {0x0000a220, 0x00000000}, - {0x0000a224, 0x00000000}, - {0x0000a228, 0x10002310}, - {0x0000a23c, 0x00000000}, - {0x0000a244, 0x0c000000}, - {0x0000a2a0, 0x00000001}, - {0x0000a2c0, 0x00000001}, - {0x0000a2c8, 0x00000000}, - {0x0000a2cc, 0x18c43433}, - {0x0000a2d4, 0x00000000}, - {0x0000a2dc, 0x00000000}, - {0x0000a2e0, 0x00000000}, - {0x0000a2e4, 0x00000000}, - {0x0000a2e8, 0x00000000}, - {0x0000a2ec, 0x00000000}, - {0x0000a2f0, 0x00000000}, - {0x0000a2f4, 0x00000000}, - {0x0000a2f8, 0x00000000}, - {0x0000a344, 0x00000000}, - {0x0000a34c, 0x00000000}, - {0x0000a350, 0x0000a000}, - {0x0000a364, 0x00000000}, - {0x0000a370, 0x00000000}, - {0x0000a390, 0x00000001}, - {0x0000a394, 0x00000444}, - {0x0000a398, 0x001f0e0f}, - {0x0000a39c, 0x0075393f}, - {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x000000ff}, - {0x0000a3a8, 0x3b3b3b3b}, - {0x0000a3ac, 0x2f2f2f2f}, - {0x0000a3c0, 0x20202020}, - {0x0000a3c4, 0x22222220}, - {0x0000a3c8, 0x20200020}, - {0x0000a3cc, 0x20202020}, - {0x0000a3d0, 0x20202020}, - {0x0000a3d4, 0x20202020}, - {0x0000a3d8, 0x20202020}, - {0x0000a3dc, 0x20202020}, - {0x0000a3e0, 0x20202020}, - {0x0000a3e4, 0x20202020}, - {0x0000a3e8, 0x20202020}, - {0x0000a3ec, 0x20202020}, - {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000006}, - {0x0000a3f8, 0x0cdbd380}, - {0x0000a3fc, 0x000f0f01}, - {0x0000a400, 0x8fa91f01}, - {0x0000a404, 0x00000000}, - {0x0000a408, 0x0e79e5c6}, - {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739cf}, - {0x0000a418, 0x2d0019ce}, - {0x0000a41c, 0x1ce739ce}, - {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739ce}, - {0x0000a428, 0x000001ce}, - {0x0000a42c, 0x1ce739ce}, - {0x0000a430, 0x1ce739ce}, - {0x0000a434, 0x00000000}, - {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00000000}, - {0x0000a440, 0x00000000}, - {0x0000a444, 0x00000000}, - {0x0000a448, 0x04000000}, - {0x0000a44c, 0x00000001}, - {0x0000a450, 0x00010000}, - {0x0000a5c4, 0xbfad9d74}, - {0x0000a5c8, 0x0048060a}, - {0x0000a5cc, 0x00000637}, - {0x0000a760, 0x03020100}, - {0x0000a764, 0x09080504}, - {0x0000a768, 0x0d0c0b0a}, - {0x0000a76c, 0x13121110}, - {0x0000a770, 0x31301514}, - {0x0000a774, 0x35343332}, - {0x0000a778, 0x00000036}, - {0x0000a780, 0x00000838}, - {0x0000a7c0, 0x00000000}, - {0x0000a7c4, 0xfffffffc}, - {0x0000a7c8, 0x00000000}, - {0x0000a7cc, 0x00000000}, - {0x0000a7d0, 0x00000000}, - {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000000}, -}; - -static const u32 ar9485Common_1_1[][2] = { - /* Addr allmodes */ - {0x00007010, 0x00000022}, - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, -}; - -static const u32 ar9485_1_1_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, - {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, - {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, - {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, - {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, - {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, - {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, - {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, - {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, - {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, - {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, - {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, - {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, - {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, - {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, - {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, - {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, - {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, - {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, - {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, - {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, - {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, - {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, - {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, - {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, - {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, - {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -}; - -static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; - -static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; - -static const u32 ar9485_1_1_radio_postamble[][2] = { - /* Addr allmodes */ - {0x0001609c, 0x0b283f31}, - {0x000160ac, 0x24611800}, - {0x000160b0, 0x03284f3e}, - {0x0001610c, 0x00170000}, - {0x00016140, 0x50804008}, -}; - -static const u32 ar9485_1_1_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; +/* AR9485 1.0 */ -static const u32 ar9485_1_1_radio_core[][2] = { - /* Addr allmodes */ - {0x00016000, 0x36db6db6}, - {0x00016004, 0x6db6db40}, - {0x00016008, 0x73800000}, - {0x0001600c, 0x00000000}, - {0x00016040, 0x7f80fff8}, - {0x0001604c, 0x000f0278}, - {0x00016050, 0x4db6db8c}, - {0x00016054, 0x6db60000}, - {0x00016080, 0x00080000}, - {0x00016084, 0x0e48048c}, - {0x00016088, 0x14214514}, - {0x0001608c, 0x119f081e}, - {0x00016090, 0x24926490}, - {0x00016098, 0xd28b3330}, - {0x000160a0, 0xc2108ffe}, - {0x000160a4, 0x812fc370}, - {0x000160a8, 0x423c8000}, - {0x000160b4, 0x92480040}, - {0x000160c0, 0x006db6db}, - {0x000160c4, 0x0186db60}, - {0x000160c8, 0x6db6db6c}, - {0x000160cc, 0x6de6fbe0}, - {0x000160d0, 0xf7dfcf3c}, - {0x00016100, 0x04cb0001}, - {0x00016104, 0xfff80015}, - {0x00016108, 0x00080010}, - {0x00016144, 0x01884080}, - {0x00016148, 0x00008040}, - {0x00016240, 0x08400000}, - {0x00016244, 0x1bf90f00}, - {0x00016248, 0x00000000}, - {0x0001624c, 0x00000000}, - {0x00016280, 0x01000015}, - {0x00016284, 0x00d30000}, - {0x00016288, 0x00318000}, - {0x0001628c, 0x50000000}, - {0x00016290, 0x4b96210f}, - {0x00016380, 0x00000000}, - {0x00016384, 0x00000000}, - {0x00016388, 0x00800700}, - {0x0001638c, 0x00800700}, - {0x00016390, 0x00800700}, - {0x00016394, 0x00000000}, - {0x00016398, 0x00000000}, - {0x0001639c, 0x00000000}, - {0x000163a0, 0x00000001}, - {0x000163a4, 0x00000001}, - {0x000163a8, 0x00000000}, - {0x000163ac, 0x00000000}, - {0x000163b0, 0x00000000}, - {0x000163b4, 0x00000000}, - {0x000163b8, 0x00000000}, - {0x000163bc, 0x00000000}, - {0x000163c0, 0x000000a0}, - {0x000163c4, 0x000c0000}, - {0x000163c8, 0x14021402}, - {0x000163cc, 0x00001402}, - {0x000163d0, 0x00000000}, - {0x000163d4, 0x00000000}, - {0x00016c40, 0x13188278}, - {0x00016c44, 0x12000000}, -}; +#define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble -static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18052e5e}, +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18012e5e}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0000080c}, }; +static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x22072208}, + {0x0000a0c4, 0x22052206}, + {0x0000a0c8, 0x22032204}, + {0x0000a0cc, 0x22012202}, + {0x0000a0d0, 0x221f2200}, + {0x0000a0d4, 0x221d221e}, + {0x0000a0d8, 0x33023303}, + {0x0000a0dc, 0x33003301}, + {0x0000a0e0, 0x331e331f}, + {0x0000a0e4, 0x4402331d}, + {0x0000a0e8, 0x44004401}, + {0x0000a0ec, 0x441e441f}, + {0x0000a0f0, 0x55025503}, + {0x0000a0f4, 0x55005501}, + {0x0000a0f8, 0x551e551f}, + {0x0000a0fc, 0x6602551d}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -681,8 +234,14 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, }; +#define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1 + +#define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1 + +#define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 + static const u32 ar9485_1_1[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x0000a580, 0x00000000}, {0x0000a584, 0x00000000}, {0x0000a588, 0x00000000}, @@ -701,194 +260,210 @@ static const u32 ar9485_1_1[][2] = { {0x0000a5bc, 0x00000000}, }; -static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, - {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, - {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a}, - {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a}, - {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a}, - {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; - -static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18013e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; - -static const u32 ar9485_1_1_soc_preamble[][2] = { - /* Addr allmodes */ - {0x00004014, 0xba280400}, - {0x00004090, 0x00aa10aa}, - {0x000040a4, 0x00a0c9c9}, - {0x00007010, 0x00000022}, - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, - {0x00007048, 0x00000002}, -}; - -static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; - -static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; - -static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { - /* Addr 5G_HT2 5G_HT40 */ - {0x00009e00, 0x03721821, 0x03721821}, - {0x0000a230, 0x0000400b, 0x00004016}, - {0x0000a254, 0x00000898, 0x00001130}, +static const u32 ar9485_1_1_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73800000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x000f0278}, + {0x00016050, 0x4db6db8c}, + {0x00016054, 0x6db60000}, + {0x00016080, 0x00080000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x14214514}, + {0x0001608c, 0x119f081e}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd28b3330}, + {0x000160a0, 0xc2108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92480040}, + {0x000160c0, 0x006db6db}, + {0x000160c4, 0x0186db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x6de6fbe0}, + {0x000160d0, 0xf7dfcf3c}, + {0x00016100, 0x04cb0001}, + {0x00016104, 0xfff80015}, + {0x00016108, 0x00080010}, + {0x00016144, 0x01884080}, + {0x00016148, 0x00008040}, + {0x00016240, 0x08400000}, + {0x00016244, 0x1bf90f00}, + {0x00016248, 0x00000000}, + {0x0001624c, 0x00000000}, + {0x00016280, 0x01000015}, + {0x00016284, 0x00d30000}, + {0x00016288, 0x00318000}, + {0x0001628c, 0x50000000}, + {0x00016290, 0x4b96210f}, + {0x00016380, 0x00000000}, + {0x00016384, 0x00000000}, + {0x00016388, 0x00800700}, + {0x0001638c, 0x00800700}, + {0x00016390, 0x00800700}, + {0x00016394, 0x00000000}, + {0x00016398, 0x00000000}, + {0x0001639c, 0x00000000}, + {0x000163a0, 0x00000001}, + {0x000163a4, 0x00000001}, + {0x000163a8, 0x00000000}, + {0x000163ac, 0x00000000}, + {0x000163b0, 0x00000000}, + {0x000163b4, 0x00000000}, + {0x000163b8, 0x00000000}, + {0x000163bc, 0x00000000}, + {0x000163c0, 0x000000a0}, + {0x000163c4, 0x000c0000}, + {0x000163c8, 0x14021402}, + {0x000163cc, 0x00001402}, + {0x000163d0, 0x00000000}, + {0x000163d4, 0x00000000}, + {0x00016c40, 0x13188278}, + {0x00016c44, 0x12000000}, }; -static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18012e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, +static const u32 ar9485_1_1_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x52440bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009d1c, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x9927b515}, + {0x00009e28, 0x12ef0200}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x80be4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a210, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x000000ff}, + {0x0000a3a8, 0x3b3b3b3b}, + {0x0000a3ac, 0x2f2f2f2f}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739cf}, + {0x0000a418, 0x2d0019ce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a5c4, 0xbfad9d74}, + {0x0000a5c8, 0x0048060a}, + {0x0000a5cc, 0x00000637}, + {0x0000a760, 0x03020100}, + {0x0000a764, 0x09080504}, + {0x0000a768, 0x0d0c0b0a}, + {0x0000a76c, 0x13121110}, + {0x0000a770, 0x31301514}, + {0x0000a774, 0x35343332}, + {0x0000a778, 0x00000036}, + {0x0000a780, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000000}, }; static const u32 ar9485_common_rx_gain_1_1[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -945,153 +520,14 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a0d4, 0x22012202}, {0x0000a0d8, 0x221f2200}, {0x0000a0dc, 0x221d221e}, - {0x0000a0e0, 0x33013302}, - {0x0000a0e4, 0x331f3300}, - {0x0000a0e8, 0x4402331e}, - {0x0000a0ec, 0x44004401}, - {0x0000a0f0, 0x441e441f}, - {0x0000a0f4, 0x55015502}, - {0x0000a0f8, 0x551f5500}, - {0x0000a0fc, 0x6602551e}, - {0x0000a100, 0x66006601}, - {0x0000a104, 0x661e661f}, - {0x0000a108, 0x7703661d}, - {0x0000a10c, 0x77017702}, - {0x0000a110, 0x00007700}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x111f1100}, - {0x0000a148, 0x111d111e}, - {0x0000a14c, 0x111b111c}, - {0x0000a150, 0x22032204}, - {0x0000a154, 0x22012202}, - {0x0000a158, 0x221f2200}, - {0x0000a15c, 0x221d221e}, - {0x0000a160, 0x33013302}, - {0x0000a164, 0x331f3300}, - {0x0000a168, 0x4402331e}, - {0x0000a16c, 0x44004401}, - {0x0000a170, 0x441e441f}, - {0x0000a174, 0x55015502}, - {0x0000a178, 0x551f5500}, - {0x0000a17c, 0x6602551e}, - {0x0000a180, 0x66006601}, - {0x0000a184, 0x661e661f}, - {0x0000a188, 0x7703661d}, - {0x0000a18c, 0x77017702}, - {0x0000a190, 0x00007700}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000296}, -}; - -static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18053e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; - -static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00060005}, - {0x0000a004, 0x00810080}, - {0x0000a008, 0x00830082}, - {0x0000a00c, 0x00850084}, - {0x0000a010, 0x01820181}, - {0x0000a014, 0x01840183}, - {0x0000a018, 0x01880185}, - {0x0000a01c, 0x018a0189}, - {0x0000a020, 0x02850284}, - {0x0000a024, 0x02890288}, - {0x0000a028, 0x028b028a}, - {0x0000a02c, 0x03850384}, - {0x0000a030, 0x03890388}, - {0x0000a034, 0x038b038a}, - {0x0000a038, 0x038d038c}, - {0x0000a03c, 0x03910390}, - {0x0000a040, 0x03930392}, - {0x0000a044, 0x03950394}, - {0x0000a048, 0x00000396}, - {0x0000a04c, 0x00000000}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x28282828}, - {0x0000a084, 0x28282828}, - {0x0000a088, 0x28282828}, - {0x0000a08c, 0x28282828}, - {0x0000a090, 0x28282828}, - {0x0000a094, 0x24242428}, - {0x0000a098, 0x171e1e1e}, - {0x0000a09c, 0x02020b0b}, - {0x0000a0a0, 0x02020202}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x22072208}, - {0x0000a0c4, 0x22052206}, - {0x0000a0c8, 0x22032204}, - {0x0000a0cc, 0x22012202}, - {0x0000a0d0, 0x221f2200}, - {0x0000a0d4, 0x221d221e}, - {0x0000a0d8, 0x33023303}, - {0x0000a0dc, 0x33003301}, - {0x0000a0e0, 0x331e331f}, - {0x0000a0e4, 0x4402331d}, - {0x0000a0e8, 0x44004401}, - {0x0000a0ec, 0x441e441f}, - {0x0000a0f0, 0x55025503}, - {0x0000a0f4, 0x55005501}, - {0x0000a0f8, 0x551e551f}, - {0x0000a0fc, 0x6602551d}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, {0x0000a100, 0x66006601}, {0x0000a104, 0x661e661f}, {0x0000a108, 0x7703661d}, @@ -1158,4 +594,260 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { {0x0000a1fc, 0x00000296}, }; -#endif +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18052e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18053e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_1_1_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00004014, 0xba280400}, + {0x00004090, 0x00aa10aa}, + {0x000040a4, 0x00a0c9c9}, + {0x00007010, 0x00000022}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00007048, 0x00000002}, +}; + +static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00009e00, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9485_1_1_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, + {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18013e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_1_1_radio_postamble[][2] = { + /* Addr allmodes */ + {0x0001609c, 0x0b283f31}, + {0x000160ac, 0x24611800}, + {0x000160b0, 0x03284f3e}, + {0x0001610c, 0x00170000}, + {0x00016140, 0x50804008}, +}; + +static const u32 ar9485_1_1_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c22}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9ca00010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xa248105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +#endif /* INITVALS_9485_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index 06b3f0df9fad..6e1915aee712 100644 --- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2010 Atheros Communications Inc. + * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,18 +20,7 @@ /* AR9580 1.0 */ -static const u32 ar9580_1p0_modes_fast_clock[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00001030, 0x00000268, 0x000004d0}, - {0x00001070, 0x0000018c, 0x00000318}, - {0x000010b0, 0x00000fd0, 0x00001fa0}, - {0x00008014, 0x044c044c, 0x08980898}, - {0x0000801c, 0x148ec02b, 0x148ec057}, - {0x00008318, 0x000044c0, 0x00008980}, - {0x00009e00, 0x0372131c, 0x0372131c}, - {0x0000a230, 0x0000000b, 0x00000016}, - {0x0000a254, 0x00000898, 0x00001130}, -}; +#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 static const u32 ar9580_1p0_radio_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -208,17 +198,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = { {0x0000c420, 0x00000000}, }; -static const u32 ar9580_1p0_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; +#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -326,111 +306,7 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; -static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, - {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; +#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -538,12 +414,7 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; -static const u32 ar9580_1p0_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; +#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 static const u32 ar9580_1p0_mac_core[][2] = { /* Addr allmodes */ @@ -808,376 +679,11 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = { {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; -static const u32 ar9580_1p0_wo_xlna_rx_gain_table[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x03820190}, - {0x0000a030, 0x03840383}, - {0x0000a034, 0x03880385}, - {0x0000a038, 0x038a0389}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x29292929}, - {0x0000a084, 0x29292929}, - {0x0000a088, 0x29292929}, - {0x0000a08c, 0x29292929}, - {0x0000a090, 0x22292929}, - {0x0000a094, 0x1d1d2222}, - {0x0000a098, 0x0c111117}, - {0x0000a09c, 0x00030303}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; +#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 -static const u32 ar9580_1p0_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, -}; +#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble -static const u32 ar9580_1p0_high_ob_db_tx_gain_table[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; +#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 static const u32 ar9580_1p0_soc_preamble[][2] = { /* Addr allmodes */ @@ -1189,265 +695,7 @@ static const u32 ar9580_1p0_soc_preamble[][2] = { {0x00007048, 0x00000008}, }; -static const u32 ar9580_1p0_rx_gain_table[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x01910190}, - {0x0000a030, 0x01930192}, - {0x0000a034, 0x01950194}, - {0x0000a038, 0x038a0196}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x22222229}, - {0x0000a084, 0x1d1d1d1d}, - {0x0000a088, 0x1d1d1d1d}, - {0x0000a08c, 0x1d1d1d1d}, - {0x0000a090, 0x171d1d1d}, - {0x0000a094, 0x11111717}, - {0x0000a098, 0x00030311}, - {0x0000a09c, 0x00000000}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x2a2d2f32}, - {0x0000b084, 0x21232328}, - {0x0000b088, 0x19191c1e}, - {0x0000b08c, 0x12141417}, - {0x0000b090, 0x07070e0e}, - {0x0000b094, 0x03030305}, - {0x0000b098, 0x00000003}, - {0x0000b09c, 0x00000000}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; +#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0 static const u32 ar9580_1p0_radio_core[][2] = { /* Addr allmodes */ -- GitLab From 1a1fb970472d66d1668ff66bc46c2cd977f9a4fc Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 27 Jun 2012 19:57:56 -0700 Subject: [PATCH 3195/6849] mwifiex: wakeup main thread to handle command queued We miss to wakeup main thread after adding command to cmd pending queue at follwing places. These commands are handled later when main thread is woken up for handling an interrupt for sleep event from firmware. This adds worst case delay of 50msec. 1) We don't wakeup main thread when asynchronous command is added to cmd pending queue. Move queue_work() call from mwifiex_wait_queue_complete() to mwifiex_send_cmd_async() to wakeup main thread for sync as well as async commands. 2) Scan operation is triggered due to following reasons a) request from user (ex. "iw scan" command) b) Scan performed by driver internally. In first case main thread is woken up when first scan command is queued in cmd pending queue (we don't need to wakeup main thread for subsequent scan commands, because they are queued in scan command response handler), but it is not done for second case. queue_work() is moved inside mwifiex_scan_networks() to handle both the cases. Signed-off-by: Amitkumar Karwar Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/main.h | 4 ++-- drivers/net/wireless/mwifiex/scan.c | 25 +++--------------------- drivers/net/wireless/mwifiex/sta_ioctl.c | 3 --- 5 files changed, 7 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 9c2e08e4b093..02d0ee8609fa 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1422,7 +1422,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, priv->user_scan_cfg->chan_list[i].scan_time = 0; } - if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) + if (mwifiex_scan_networks(priv, priv->user_scan_cfg)) return -EFAULT; if (request->ie && request->ie_len) { diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index ea37b887a874..c68adec3cc8b 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -578,6 +578,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, } else { adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + queue_work(adapter->workqueue, &adapter->main_work); } return ret; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 0b3b5aa9830d..7cd95cc99a85 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -949,8 +949,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate); int mwifiex_request_scan(struct mwifiex_private *priv, struct cfg80211_ssid *req_ssid); -int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, - struct mwifiex_user_scan_cfg *scan_req); +int mwifiex_scan_networks(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in); int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index efaf26ccd6ba..884ed6377003 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1296,8 +1296,8 @@ mwifiex_radio_type_to_band(u8 radio_type) * order to send the appropriate scan commands to firmware to populate or * update the internal driver scan table. */ -static int mwifiex_scan_networks(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in) +int mwifiex_scan_networks(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -1362,6 +1362,7 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + queue_work(adapter->workqueue, &adapter->main_work); } else { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1377,26 +1378,6 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, return ret; } -/* - * Sends IOCTL request to start a scan with user configurations. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - * - * Upon completion, it also generates a wireless event to notify - * applications. - */ -int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, - struct mwifiex_user_scan_cfg *scan_req) -{ - int status; - - status = mwifiex_scan_networks(priv, scan_req); - queue_work(priv->adapter->workqueue, &priv->adapter->main_work); - - return status; -} - /* * This function prepares a scan command to be sent to the firmware. * diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 106c449477b2..f2fd2423214f 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -66,9 +66,6 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "cmd pending\n"); atomic_inc(&adapter->cmd_pending); - /* Status pending, wake up main process */ - queue_work(adapter->workqueue, &adapter->main_work); - /* Wait for completion */ wait_event_interruptible(adapter->cmd_wait_q.wait, *(cmd_queued->condition)); -- GitLab From caa8984f59b8be220767886ae27de855f77e6a61 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 27 Jun 2012 19:57:57 -0700 Subject: [PATCH 3196/6849] mwifiex: use correct firmware command to get power limits "priv->max_tx_power_level" and "priv->min_tx_power_level" variables are initialized to maximum and minimum power levels supported by hardware by sending correct firmware command. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 9 ++++++++ drivers/net/wireless/mwifiex/sta_cmd.c | 23 +++++++++++++++++- drivers/net/wireless/mwifiex/sta_cmdresp.c | 27 ++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 1184141839ae..ffb6cdfdb797 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -226,6 +226,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RF_REG_ACCESS 0x001b #define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad #define HostCmd_CMD_802_11_RF_CHANNEL 0x001d +#define HostCmd_CMD_RF_TX_PWR 0x001e #define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024 #define HostCmd_CMD_MAC_CONTROL 0x0028 #define HostCmd_CMD_802_11_AD_HOC_START 0x002b @@ -876,6 +877,13 @@ struct host_cmd_ds_txpwr_cfg { __le32 mode; } __packed; +struct host_cmd_ds_rf_tx_pwr { + __le16 action; + __le16 cur_level; + u8 max_power; + u8 min_power; +} __packed; + struct mwifiex_bcn_param { u8 bssid[ETH_ALEN]; u8 rssi; @@ -1361,6 +1369,7 @@ struct host_cmd_ds_command { struct host_cmd_ds_tx_rate_query tx_rate; struct host_cmd_ds_tx_rate_cfg tx_rate_cfg; struct host_cmd_ds_txpwr_cfg txp_cfg; + struct host_cmd_ds_rf_tx_pwr txp; struct host_cmd_ds_802_11_ps_mode_enh psmode_enh; struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg; struct host_cmd_ds_802_11_scan scan; diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 40e025da6bc2..2d4319a8941f 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -259,6 +259,23 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, return 0; } +/* + * This function prepares command to get RF Tx power. + */ +static int mwifiex_cmd_rf_tx_power(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_rf_tx_pwr *txp = &cmd->params.txp; + + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_tx_pwr) + + S_DS_GEN); + cmd->command = cpu_to_le16(HostCmd_CMD_RF_TX_PWR); + txp->action = cpu_to_le16(cmd_action); + + return 0; +} + /* * This function prepares command to set Host Sleep configuration. * @@ -1055,6 +1072,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action, data_buf); break; + case HostCmd_CMD_RF_TX_PWR: + ret = mwifiex_cmd_rf_tx_power(priv, cmd_ptr, cmd_action, + data_buf); + break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action, (uint16_t)cmd_oid, data_buf); @@ -1283,7 +1304,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) priv->data_rate = 0; /* get tx power */ - ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_RF_TX_PWR, HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index a79ed9bd9695..4cb2c1c78397 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -450,6 +450,30 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, return 0; } +/* + * This function handles the command response of get RF Tx power. + */ +static int mwifiex_ret_rf_tx_power(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_rf_tx_pwr *txp = &resp->params.txp; + u16 action = le16_to_cpu(txp->action); + + priv->tx_power_level = le16_to_cpu(txp->cur_level); + + if (action == HostCmd_ACT_GEN_GET) { + priv->max_tx_power_level = txp->max_power; + priv->min_tx_power_level = txp->min_power; + } + + dev_dbg(priv->adapter->dev, + "Current TxPower Level=%d, Max Power=%d, Min Power=%d\n", + priv->tx_power_level, priv->max_tx_power_level, + priv->min_tx_power_level); + + return 0; +} + /* * This function handles the command response of set/get MAC address. * @@ -847,6 +871,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_TXPWR_CFG: ret = mwifiex_ret_tx_power_cfg(priv, resp); break; + case HostCmd_CMD_RF_TX_PWR: + ret = mwifiex_ret_rf_tx_power(priv, resp); + break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); break; -- GitLab From 2041d7dff287333036145ba3aab57e3b675babef Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 27 Jun 2012 19:57:58 -0700 Subject: [PATCH 3197/6849] mwifiex: do not advertise custom regulatory domain capability Since we don't support custom regulatory domains, WIPHY_FLAG_CUSTOM_REGULATORY should not be enabled during wiphy registration. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 02d0ee8609fa..cf97c2aec8b4 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1746,7 +1746,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY; + wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; /* Reserve space for mwifiex specific private data for BSS */ wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); -- GitLab From 34202e28fe7fc8551313f9a035a8857db83de757 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 27 Jun 2012 19:57:59 -0700 Subject: [PATCH 3198/6849] mwifiex: retrieve correct max_power information in reg_notifier handler As we don't provide custom regulatory rules to cfg80211, "chan->max_power" remains uninitialized (0dbm) and "chan->max_reg_power" will contain maximum power for a channel extracted from regulatory rules provided by CRDA; hence use "chan->max_reg_power" in reg_notifier handler instead of "chan->max_power" to set max_power in firmware. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index cf97c2aec8b4..bb06d2e3274a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -260,13 +260,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) flag = 1; first_chan = (u32) ch->hw_value; next_chan = first_chan; - max_pwr = ch->max_power; + max_pwr = ch->max_reg_power; no_of_parsed_chan = 1; continue; } if (ch->hw_value == next_chan + 1 && - ch->max_power == max_pwr) { + ch->max_reg_power == max_pwr) { next_chan++; no_of_parsed_chan++; } else { @@ -277,7 +277,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) no_of_triplet++; first_chan = (u32) ch->hw_value; next_chan = first_chan; - max_pwr = ch->max_power; + max_pwr = ch->max_reg_power; no_of_parsed_chan = 1; } } -- GitLab From e5de32e3ec9d4d5a355659760d5045b80c0a05d8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 22 Jun 2012 16:41:00 +0100 Subject: [PATCH 3199/6849] watchdog: iTCO_wdt: add platform driver module alias The recent conversion of iTCO_wdt resulted in the driver no longer getting loaded automatically, since it no longer has a MODULE_DEVICE_TABLE() included. As the lpc_ich driver now creates a platform device, auto-loading can easily be done by having a respective module alias in place. Signed-off-by: Jan Beulich Cc: Aaron Sierra Acked-by: Guenter Roeck Cc: Samuel Ortiz Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/iTCO_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index bc47e9012f37..9c2c27c3b424 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -699,3 +699,4 @@ MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +MODULE_ALIAS("platform:" DRV_NAME); -- GitLab From a089361cf5f1d6a5295aa5385238bd044998e1e9 Mon Sep 17 00:00:00 2001 From: "Mingarelli, Thomas" Date: Tue, 26 Jun 2012 10:27:00 +0200 Subject: [PATCH 3200/6849] watchdog: hpwdt: Unregister NMI events on exit. This patch is to unregister for NMI events upon exit. Also we are now making the default setting for allow_kdump enabled. Signed-off-by: Thomas Mingarelli Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 2b763815aeec..1eff743ec497 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -146,7 +146,7 @@ struct cmn_registers { } __attribute__((packed)); static unsigned int hpwdt_nmi_decoding; -static unsigned int allow_kdump; +static unsigned int allow_kdump = 1; static unsigned int is_icru; static DEFINE_SPINLOCK(rom_lock); static void *cru_rom_addr; @@ -756,6 +756,8 @@ error: static void hpwdt_exit_nmi_decoding(void) { unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); + unregister_nmi_handler(NMI_SERR, "hpwdt"); + unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); if (cru_rom_addr) iounmap(cru_rom_addr); } -- GitLab From 8b9468d496abd357cc797b27a79d4402f5e0e94d Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Tue, 26 Jun 2012 20:07:21 +0200 Subject: [PATCH 3201/6849] watchdog: core: fix WDIOC_GETSTATUS return value In commit 7a87982420e5e126bfefeb42232d1fd92052794e we added a wrapper for the WDIOC_GETSTATUS ioctl call. The code results however in a different behaviour: it returns an error if the driver doesn't support the status operation. This is not according to the API that says that when we don't support the status operation, that we just should return a 0 value. Only when the device isn't there anymore, we should return an error. Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/watchdog_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 672d169bf1da..ef8edecfc526 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -349,7 +349,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, sizeof(struct watchdog_info)) ? -EFAULT : 0; case WDIOC_GETSTATUS: err = watchdog_get_status(wdd, &val); - if (err) + if (err == -ENODEV) return err; return put_user(val, p); case WDIOC_GETBOOTSTATUS: -- GitLab From d9b8706843a501034d09bea63ca6723a2ed02b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 21 Jun 2012 23:11:18 +0000 Subject: [PATCH 3202/6849] net: qmi_wwan: fix Oops while disconnecting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usbnet_disconnect() will set intfdata to NULL before calling the minidriver unbind function. The cdc_wdm subdriver cannot know that it is disconnecting until the qmi_wwan unbind function has called its disconnect function. This means that we must be able to support the cdc_wdm subdriver operating normally while usbnet_disconnect() is running, and in particular that intfdata may be NULL. The only place this matters is in qmi_wwan_cdc_wdm_manage_power which is called from cdc_wdm. Simply testing for NULL intfdata there is sufficient to allow it to continue working at all times. Fixes this Oops where a cdc-wdm device was closed while the USB device was disconnecting, causing wdm_release to call qmi_wwan_cdc_wdm_manage_power after intfdata was set to NULL by usbnet_disconnect: [41819.087460] BUG: unable to handle kernel NULL pointer dereference at 00000080 [41819.087815] IP: [] qmi_wwan_manage_power+0x68/0x90 [qmi_wwan] [41819.088028] *pdpt = 000000000314f001 *pde = 0000000000000000 [41819.088028] Oops: 0002 [#1] SMP [41819.088028] Modules linked in: qmi_wwan option usb_wwan usbserial usbnet cdc_wdm nls_iso8859_1 nls_cp437 vfat fat usb_storage bnep rfcomm bluetooth parport_pc ppdev binfmt_misc iptable_nat nf_nat nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 iptable_mangle iptable_filter ip_tables x_tables dm_crypt uvcvideo snd_hda_codec_realtek snd_hda_intel videobuf2_core snd_hda_codec joydev videodev videobuf2_vmalloc hid_multitouch snd_hwdep arc4 videobuf2_memops snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event ath9k mac80211 snd_seq ath9k_common ath9k_hw ath snd_timer snd_seq_device sparse_keymap dm_multipath scsi_dh coretemp mac_hid snd soundcore cfg80211 snd_page_alloc psmouse serio_raw microcode lp parport dm_mirror dm_region_hash dm_log usbhid hid i915 drm_kms_helper drm r8169 i2c_algo_bit wmi video [last unloaded: qmi_wwan] [41819.088028] [41819.088028] Pid: 23292, comm: qmicli Not tainted 3.4.0-5-generic #11-Ubuntu GIGABYTE T1005/T1005 [41819.088028] EIP: 0060:[] EFLAGS: 00010246 CPU: 1 [41819.088028] EIP is at qmi_wwan_manage_power+0x68/0x90 [qmi_wwan] [41819.088028] EAX: 00000000 EBX: 00000000 ECX: 000000c3 EDX: 00000000 [41819.088028] ESI: c3b27658 EDI: 00000000 EBP: c298bea4 ESP: c298be98 [41819.088028] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [41819.088028] CR0: 8005003b CR2: 00000080 CR3: 3605e000 CR4: 000007f0 [41819.088028] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [41819.088028] DR6: ffff0ff0 DR7: 00000400 [41819.088028] Process qmicli (pid: 23292, ti=c298a000 task=f343b280 task.ti=c298a000) [41819.088028] Stack: [41819.088028] 00000000 c3b27658 e2a80d00 c298beb0 f864051a c3b27600 c298bec0 f9027099 [41819.088028] c2fd6000 00000008 c298bef0 c1147f96 00000001 00000000 00000000 f4e54790 [41819.088028] ecf43a00 ecf43a00 c2fd6008 c2fd6000 ebbd7600 ffffffb9 c298bf08 c1144474 [41819.088028] Call Trace: [41819.088028] [] qmi_wwan_cdc_wdm_manage_power+0x1a/0x20 [qmi_wwan] [41819.088028] [] wdm_release+0x69/0x70 [cdc_wdm] [41819.088028] [] fput+0xe6/0x210 [41819.088028] [] filp_close+0x54/0x80 [41819.088028] [] put_files_struct+0x75/0xc0 [41819.088028] [] exit_files+0x46/0x60 [41819.088028] [] do_exit+0x141/0x780 [41819.088028] [] ? wake_up_state+0xf/0x20 [41819.088028] [] ? signal_wake_up+0x28/0x40 [41819.088028] [] ? zap_other_threads+0x6b/0x80 [41819.088028] [] do_group_exit+0x34/0xa0 [41819.088028] [] sys_exit_group+0x18/0x20 [41819.088028] [] sysenter_do_call+0x12/0x28 [41819.088028] Code: 04 83 e7 01 c1 e7 03 0f b6 42 18 83 e0 f7 09 f8 88 42 18 8b 43 04 e8 48 9a dd c8 89 f0 8b 5d f4 8b 75 f8 8b 7d fc 89 ec 5d c3 90 ff 88 80 00 00 00 0f 94 c0 84 c0 75 b7 31 f6 8b 5d f4 89 f0 [41819.088028] EIP: [] qmi_wwan_manage_power+0x68/0x90 [qmi_wwan] SS:ESP 0068:c298be98 [41819.088028] CR2: 0000000000000080 [41819.149492] ---[ end trace 0944479ff8257f55 ]--- Reported-by: Marius Bjørnstad Kotsbak Cc: # v3.4 Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3767a1225860..b01960fcfbc9 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -197,6 +197,10 @@ err: static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) { struct usbnet *dev = usb_get_intfdata(intf); + + /* can be called while disconnecting */ + if (!dev) + return 0; return qmi_wwan_manage_power(dev, on); } -- GitLab From 7cecb523adedcaf8acba5e14d47559d8bc3f40d7 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Wed, 27 Jun 2012 14:32:07 +0000 Subject: [PATCH 3203/6849] net: Downgrade CAP_SYS_MODULE deprecated message from error to warning. Make logging level consistent with other deprecation messages in net subsystem. Signed-off-by: Vinson Lee Cc: David Mackey Signed-off-by: David S. Miller --- net/core/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 6df214041a5e..84f01ba81a34 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1136,8 +1136,8 @@ void dev_load(struct net *net, const char *name) no_module = request_module("netdev-%s", name); if (no_module && capable(CAP_SYS_MODULE)) { if (!request_module("%s", name)) - pr_err("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", - name); + pr_warn("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", + name); } } EXPORT_SYMBOL(dev_load); -- GitLab From 9740e001932f59ee007d13ee3f39bb1b61086651 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Thu, 28 Jun 2012 04:40:53 +0000 Subject: [PATCH 3204/6849] gianfar: Fix RXICr/TXICr programming for multi-queue mode The correct behavior is to program the interrupt coalescing regs (RXICr/TXICr) in accordance with the Rx/Tx Q's "rx/txcoalescing" flag. That is, if the coalescing flag is 0 for a given Rx/Tx queue then the corresponding coalescing register should be cleared. This behavior is correctly implemented for the single-queue mode (SQ_SG_MODE), but not for the multi-queue mode (MQ_MG_MODE). This fixes the later case. Signed-off-by: Claudiu Manoil Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 0741aded9eb0..f2db8fca46a1 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1804,18 +1804,16 @@ void gfar_configure_coalescing(struct gfar_private *priv, if (priv->mode == MQ_MG_MODE) { baddr = ®s->txic0; for_each_set_bit(i, &tx_mask, priv->num_tx_queues) { - if (likely(priv->tx_queue[i]->txcoalescing)) { - gfar_write(baddr + i, 0); + gfar_write(baddr + i, 0); + if (likely(priv->tx_queue[i]->txcoalescing)) gfar_write(baddr + i, priv->tx_queue[i]->txic); - } } baddr = ®s->rxic0; for_each_set_bit(i, &rx_mask, priv->num_rx_queues) { - if (likely(priv->rx_queue[i]->rxcoalescing)) { - gfar_write(baddr + i, 0); + gfar_write(baddr + i, 0); + if (likely(priv->rx_queue[i]->rxcoalescing)) gfar_write(baddr + i, priv->rx_queue[i]->rxic); - } } } } -- GitLab From adad004e1a50f8c64d9f116cd4934da937b51e27 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 28 Jun 2012 16:48:17 -0700 Subject: [PATCH 3205/6849] Input: wacom - BTN_TOOL_DOUBLETAP is not a valid device_type It is replaced by BTN_TOOL_FINGER. Signed-off-by: Ping Cheng Tested-by: Rafi Rubin Reviewed-by: Jason Gerecke Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 9e8fdcf005a3..c24ab5468e02 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -503,7 +503,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { features->device_type = 0; } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) { - features->device_type = BTN_TOOL_DOUBLETAP; + features->device_type = BTN_TOOL_FINGER; features->pktlen = WACOM_PKGLEN_BBTOUCH3; } } -- GitLab From 6795a524f0b049ceb5417d5036ab5e233345b900 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 28 Jun 2012 16:49:00 -0700 Subject: [PATCH 3206/6849] Input: wacom - TPC2FG doesn't store touch id for slots Signed-off-by: Ping Cheng Tested-by: Rafi Rubin Reviewed-by: Jason Gerecke Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 4453864956b6..6533f44be5bd 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1547,10 +1547,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_POINTER, input_dev->propbit); break; - case TABLETPC2FG: case MTSCREEN: if (features->device_type == BTN_TOOL_FINGER) { - wacom_wac->slots = kmalloc(features->touch_max * sizeof(int), GFP_KERNEL); @@ -1559,7 +1557,11 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, for (i = 0; i < features->touch_max; i++) wacom_wac->slots[i] = -1; + } + /* fall through */ + case TABLETPC2FG: + if (features->device_type == BTN_TOOL_FINGER) { input_mt_init_slots(input_dev, features->touch_max); input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0); -- GitLab From 61c91dd4a58b21a783e37208f4d02e3cb4b637c4 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 28 Jun 2012 16:46:27 -0700 Subject: [PATCH 3207/6849] Input: wacom - fix retrieving touch_max bug rep_data is not an array anymore, so taking it's address when passing to wacom_get_report() is wrong. Signed-off-by: Ping Cheng Tested-by: Rafi Rubin Reviewed-by: Jason Gerecke Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b3a8bd3514b2..23a933da75cd 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -213,7 +213,7 @@ static void wacom_retrieve_report_data(struct usb_interface *intf, rep_data[0] = 12; result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, - rep_data[0], &rep_data, 2, + rep_data[0], rep_data, 2, WAC_MSG_RETRIES); if (result >= 0 && rep_data[1] > 2) -- GitLab From 1cecc5cc0658e128bcad0b29edb96f286066571d Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 28 Jun 2012 16:47:30 -0700 Subject: [PATCH 3208/6849] Input: wacom - don't retrieve touch_max when it is predefined Some models, such as 0xE6, report more fingers than we process. Reported-by: Jonathan Nieder Signed-off-by: Ping Cheng Tested-by: Nils Kanning Tested-by: Rafi Rubin Reviewed-by: Jason Gerecke Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 23a933da75cd..b145841bdbe7 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -398,7 +398,9 @@ static int wacom_parse_hid(struct usb_interface *intf, break; case HID_USAGE_CONTACTMAX: - wacom_retrieve_report_data(intf, features); + /* leave touch_max as is if predefined */ + if (!features->touch_max) + wacom_retrieve_report_data(intf, features); i++; break; } -- GitLab From 76fbc247b9aebc30f6d2c8ec1f69edcb68eaa328 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 28 Jun 2012 06:12:32 +0000 Subject: [PATCH 3209/6849] davinci_cpdma: include linux/module.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a number of warnings such as: CC drivers/net/ethernet/ti/davinci_cpdma.o drivers/net/ethernet/ti/davinci_cpdma.c:279:1: warning: data definition has no type or storage class drivers/net/ethernet/ti/davinci_cpdma.c:279:1: warning: type defaults to ‘int’ in declaration of ‘EXPORT_SYMBOL_GPL’ drivers/net/ethernet/ti/davinci_cpdma.c:279:1: warning: parameter names (without types) in function declaration Signed-off-by: Daniel Mack Cc: Vaibhav Hiremath Cc: David S. Miller Cc: Christian Riesch Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_cpdma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index d614c374ed9d..3b5c4571b55e 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include -- GitLab From 9247869ee661b046510c19a36cf0d91d9c2639d3 Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Thu, 28 Jun 2012 12:34:18 +0000 Subject: [PATCH 3210/6849] tcp: fix inet6_csk_route_req() for link-local addresses Fix inet6_csk_route_req() to use as the flowi6_oif the treq->iif, which is correctly fixed up in tcp_v6_conn_request() to handle the case of link-local addresses. This brings it in line with the tcp_v6_send_synack() code, which is already correctly using the treq->iif in this way. Signed-off-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv6/inet6_connection_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index e6cee5292a0b..e23d35424ca9 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -68,7 +68,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, fl6.daddr = treq->rmt_addr; final_p = fl6_update_dst(&fl6, np->opt, &final); fl6.saddr = treq->loc_addr; - fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_oif = treq->iif; fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet_rsk(req)->rmt_port; fl6.fl6_sport = inet_rsk(req)->loc_port; -- GitLab From 3840a06e6046aaee95f33a120499d2dc8c054b9d Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Thu, 28 Jun 2012 12:34:19 +0000 Subject: [PATCH 3211/6849] tcp: pass fl6 to inet6_csk_route_req() This commit changes inet_csk_route_req() so that it uses a pointer to a struct flowi6, rather than allocating its own on the stack. This brings its behavior in line with its IPv4 cousin, inet_csk_route_req(), and allows a follow-on patch to fix a dst leak. Signed-off-by: Neal Cardwell Signed-off-by: David S. Miller --- include/net/inet6_connection_sock.h | 1 + net/ipv6/inet6_connection_sock.c | 26 +++++++++++++------------- net/ipv6/tcp_ipv6.c | 9 ++++++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h index 1866a676c810..df2a857e853d 100644 --- a/include/net/inet6_connection_sock.h +++ b/include/net/inet6_connection_sock.h @@ -26,6 +26,7 @@ extern int inet6_csk_bind_conflict(const struct sock *sk, const struct inet_bind_bucket *tb, bool relax); extern struct dst_entry* inet6_csk_route_req(struct sock *sk, + struct flowi6 *fl6, const struct request_sock *req); extern struct request_sock *inet6_csk_search_req(const struct sock *sk, diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index e23d35424ca9..bceb14450a1d 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -55,26 +55,26 @@ int inet6_csk_bind_conflict(const struct sock *sk, EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict); struct dst_entry *inet6_csk_route_req(struct sock *sk, + struct flowi6 *fl6, const struct request_sock *req) { struct inet6_request_sock *treq = inet6_rsk(req); struct ipv6_pinfo *np = inet6_sk(sk); struct in6_addr *final_p, final; struct dst_entry *dst; - struct flowi6 fl6; - - memset(&fl6, 0, sizeof(fl6)); - fl6.flowi6_proto = IPPROTO_TCP; - fl6.daddr = treq->rmt_addr; - final_p = fl6_update_dst(&fl6, np->opt, &final); - fl6.saddr = treq->loc_addr; - fl6.flowi6_oif = treq->iif; - fl6.flowi6_mark = sk->sk_mark; - fl6.fl6_dport = inet_rsk(req)->rmt_port; - fl6.fl6_sport = inet_rsk(req)->loc_port; - security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); + memset(fl6, 0, sizeof(*fl6)); + fl6->flowi6_proto = IPPROTO_TCP; + fl6->daddr = treq->rmt_addr; + final_p = fl6_update_dst(fl6, np->opt, &final); + fl6->saddr = treq->loc_addr; + fl6->flowi6_oif = treq->iif; + fl6->flowi6_mark = sk->sk_mark; + fl6->fl6_dport = inet_rsk(req)->rmt_port; + fl6->fl6_sport = inet_rsk(req)->loc_port; + security_req_classify_flow(req, flowi6_to_flowi(fl6)); + + dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); if (IS_ERR(dst)) return NULL; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fc0b96bf9051..4e5fa5f6ec68 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -477,7 +477,8 @@ out: } -static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, +static int tcp_v6_send_synack(struct sock *sk, + struct request_sock *req, struct request_values *rvp, u16 queue_mapping) { @@ -1058,6 +1059,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) struct tcp_sock *tp = tcp_sk(sk); __u32 isn = TCP_SKB_CB(skb)->when; struct dst_entry *dst = NULL; + struct flowi6 fl6; bool want_cookie = false; if (skb->protocol == htons(ETH_P_IP)) @@ -1177,7 +1179,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) */ if (tmp_opt.saw_tstamp && tcp_death_row.sysctl_tw_recycle && - (dst = inet6_csk_route_req(sk, req)) != NULL && + (dst = inet6_csk_route_req(sk, &fl6, req)) != NULL && (peer = rt6_get_peer((struct rt6_info *)dst)) != NULL && ipv6_addr_equal((struct in6_addr *)peer->daddr.addr.a6, &treq->rmt_addr)) { @@ -1247,6 +1249,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, #ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *key; #endif + struct flowi6 fl6; if (skb->protocol == htons(ETH_P_IP)) { /* @@ -1309,7 +1312,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, goto out_overflow; if (!dst) { - dst = inet6_csk_route_req(sk, req); + dst = inet6_csk_route_req(sk, &fl6, req); if (!dst) goto out; } -- GitLab From 9494218fbae2f88bd3f9b887714734abfdf38bab Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Thu, 28 Jun 2012 12:34:20 +0000 Subject: [PATCH 3212/6849] tcp: use inet6_csk_route_req() in tcp_v6_send_synack() With the recent change (earlier in this patch series) to set flowi6_oif to treq->iif in inet6_csk_route_req(), the dst lookup in these two functions is now identical, so tcp_v6_send_synack() can now just call inet6_csk_route_req(), to reduce code duplication and keep things closer to the IPv4 side, which is structured this way. Signed-off-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4e5fa5f6ec68..d1db0caefdcd 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -485,34 +485,17 @@ static int tcp_v6_send_synack(struct sock *sk, struct inet6_request_sock *treq = inet6_rsk(req); struct ipv6_pinfo *np = inet6_sk(sk); struct sk_buff * skb; - struct ipv6_txoptions *opt = NULL; - struct in6_addr * final_p, final; + struct ipv6_txoptions *opt = np->opt; struct flowi6 fl6; struct dst_entry *dst; - int err; - - memset(&fl6, 0, sizeof(fl6)); - fl6.flowi6_proto = IPPROTO_TCP; - fl6.daddr = treq->rmt_addr; - fl6.saddr = treq->loc_addr; - fl6.flowlabel = 0; - fl6.flowi6_oif = treq->iif; - fl6.flowi6_mark = sk->sk_mark; - fl6.fl6_dport = inet_rsk(req)->rmt_port; - fl6.fl6_sport = inet_rsk(req)->loc_port; - security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - - opt = np->opt; - final_p = fl6_update_dst(&fl6, opt, &final); + int err = -ENOMEM; - dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - dst = NULL; + dst = inet6_csk_route_req(sk, &fl6, req); + if (!dst) goto done; - } + skb = tcp_make_synack(sk, dst, req, rvp); - err = -ENOMEM; + if (skb) { __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); -- GitLab From 9f10d3f6f966ef6f6a8d025a4b1d341923d04607 Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Thu, 28 Jun 2012 12:34:21 +0000 Subject: [PATCH 3213/6849] tcp: plug dst leak in tcp_v6_conn_request() The code in tcp_v6_conn_request() was implicitly assuming that tcp_v6_send_synack() would take care of dst_release(), much as tcp_v4_send_synack() already does. This resulted in tcp_v6_conn_request() leaking a dst if sysctl_tw_recycle is enabled. This commit restructures tcp_v6_send_synack() so that it accepts a dst pointer and takes care of releasing the dst that is passed in, to plug the leak and avoid future surprises by bringing the IPv6 behavior in line with the IPv4 side. Signed-off-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d1db0caefdcd..9c06eafaf695 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -477,7 +477,8 @@ out: } -static int tcp_v6_send_synack(struct sock *sk, +static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, + struct flowi6 *fl6, struct request_sock *req, struct request_values *rvp, u16 queue_mapping) @@ -486,12 +487,10 @@ static int tcp_v6_send_synack(struct sock *sk, struct ipv6_pinfo *np = inet6_sk(sk); struct sk_buff * skb; struct ipv6_txoptions *opt = np->opt; - struct flowi6 fl6; - struct dst_entry *dst; int err = -ENOMEM; - dst = inet6_csk_route_req(sk, &fl6, req); - if (!dst) + /* First, grab a route. */ + if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) goto done; skb = tcp_make_synack(sk, dst, req, rvp); @@ -499,9 +498,9 @@ static int tcp_v6_send_synack(struct sock *sk, if (skb) { __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); - fl6.daddr = treq->rmt_addr; + fl6->daddr = treq->rmt_addr; skb_set_queue_mapping(skb, queue_mapping); - err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); + err = ip6_xmit(sk, skb, fl6, opt, np->tclass); err = net_xmit_eval(err); } @@ -514,8 +513,10 @@ done: static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, struct request_values *rvp) { + struct flowi6 fl6; + TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); - return tcp_v6_send_synack(sk, req, rvp, 0); + return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); } static void tcp_v6_reqsk_destructor(struct request_sock *req) @@ -1201,7 +1202,7 @@ have_isn: if (security_inet_conn_request(sk, skb, req)) goto drop_and_release; - if (tcp_v6_send_synack(sk, req, + if (tcp_v6_send_synack(sk, dst, &fl6, req, (struct request_values *)&tmp_ext, skb_get_queue_mapping(skb)) || want_cookie) -- GitLab From 58050fce3530939372e6c2f4b4beb76fcb4caa65 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 28 Jun 2012 03:57:45 +0000 Subject: [PATCH 3214/6849] net: Use NLMSG_DEFAULT_SIZE in combination with nlmsg_new() Using NLMSG_GOODSIZE results in multiple pages being used as nlmsg_new() will automatically add the size of the netlink header to the payload thus exceeding the page limit. NLMSG_DEFAULT_SIZE takes this into account. Signed-off-by: Thomas Graf Cc: Jiri Pirko Cc: Dmitry Eremin-Solenikov Cc: Sergey Lapin Cc: Johannes Berg Cc: Lauro Ramos Venancio Cc: Aloisio Almeida Jr Cc: Samuel Ortiz Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 8 ++++---- drivers/net/wireless/mac80211_hwsim.c | 2 +- include/net/genetlink.h | 2 ++ net/ieee802154/netlink.c | 4 ++-- net/ieee802154/nl-mac.c | 2 +- net/ieee802154/nl-phy.c | 2 +- net/l2tp/l2tp_netlink.c | 6 +++--- net/nfc/netlink.c | 18 +++++++++--------- net/wireless/nl80211.c | 26 +++++++++++++------------- 9 files changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 5350eeaa22ce..89853c31e7f4 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1476,7 +1476,7 @@ static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) void *hdr; int err; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -1538,7 +1538,7 @@ static int team_nl_send_generic(struct genl_info *info, struct team *team, struct sk_buff *skb; int err; - skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!skb) return -ENOMEM; @@ -1648,7 +1648,7 @@ static int __send_and_alloc_skb(struct sk_buff **pskb, if (err) return err; } - *pskb = genlmsg_new(NLMSG_DEFAULT_SIZE - GENL_HDRLEN, GFP_KERNEL); + *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!*pskb) return -ENOMEM; return 0; @@ -2016,7 +2016,7 @@ static int team_nl_send_event_port_list_get(struct team *team) int err; struct net *net = dev_net(team->dev); - skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!skb) return -ENOMEM; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index a0b7cfd34685..a9ba3f7ea62b 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -571,7 +571,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, skb_dequeue(&data->pending); } - skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (skb == NULL) goto nla_put_failure; diff --git a/include/net/genetlink.h b/include/net/genetlink.h index ccb68880abf5..48905cd3884c 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -5,6 +5,8 @@ #include #include +#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN) + /** * struct genl_multicast_group - generic netlink multicast group * @name: name of the multicast group, names are per-family diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index c8097ae2482f..97351e1d07a4 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c @@ -44,7 +44,7 @@ struct genl_family nl802154_family = { struct sk_buff *ieee802154_nl_create(int flags, u8 req) { void *hdr; - struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); unsigned long f; if (!msg) @@ -80,7 +80,7 @@ struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info, int flags, u8 req) { void *hdr; - struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!msg) return NULL; diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index ca92587720f4..1e9917124e75 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -530,7 +530,7 @@ static int ieee802154_list_iface(struct sk_buff *skb, if (!dev) return -ENODEV; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) goto out_dev; diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index eed291626da6..d54be34cca94 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -101,7 +101,7 @@ static int ieee802154_list_phy(struct sk_buff *skb, if (!phy) return -ENODEV; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) goto out_dev; diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index ddc553e76671..d71cd9229a47 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -72,7 +72,7 @@ static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) void *hdr; int ret = -ENOBUFS; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { ret = -ENOMEM; goto out; @@ -353,7 +353,7 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info) goto out; } - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { ret = -ENOMEM; goto out; @@ -699,7 +699,7 @@ static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info) goto out; } - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { ret = -ENOMEM; goto out; diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 03c31db38f12..f4f07f9b61c0 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -167,7 +167,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev) dev->genl_data.poll_req_pid = 0; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!msg) return -ENOMEM; @@ -195,7 +195,7 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx) struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -226,7 +226,7 @@ int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol) struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -258,7 +258,7 @@ int nfc_genl_tm_deactivated(struct nfc_dev *dev) struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -288,7 +288,7 @@ int nfc_genl_device_added(struct nfc_dev *dev) struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -321,7 +321,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev) struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -434,7 +434,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, pr_debug("DEP link is up\n"); - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!msg) return -ENOMEM; @@ -473,7 +473,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev) pr_debug("DEP link is down\n"); - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!msg) return -ENOMEM; @@ -514,7 +514,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info) if (!dev) return -ENODEV; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { rc = -ENOMEM; goto out_putdev; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7ae54b82291f..cbdc0fd67a14 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7210,7 +7210,7 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, { struct sk_buff *msg; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return; @@ -7286,7 +7286,7 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, { struct sk_buff *msg; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return; @@ -7502,7 +7502,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -7542,7 +7542,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -7580,7 +7580,7 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return; @@ -7842,7 +7842,7 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, { struct sk_buff *msg; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -7863,7 +7863,7 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -8026,7 +8026,7 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, struct nlattr *pinfoattr; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -8069,7 +8069,7 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, struct nlattr *rekey_attr; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -8113,7 +8113,7 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, struct nlattr *attr; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -8157,7 +8157,7 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -8192,7 +8192,7 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, struct nlattr *pinfoattr; void *hdr; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; @@ -8236,7 +8236,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, void *hdr; int err; - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) return; -- GitLab From f1cefa855f6e7d10dd49724ede771b8f0c2a90e7 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 28 Jun 2012 12:39:05 +0200 Subject: [PATCH 3215/6849] ARM: mxs/tx28: fix odd include arch/arm/mach-mxs/module-tx28.c includes "../devices-mx28.h". That's a bit odd, because that header can be found in the same directory. This only works because arch/arm/mach-mxs/include should be in the header search path for this file. Nevertheless, this file can simply include "device-mx28.h" (just as the four other files including that header do). Signed-off-by: Paul Bolle Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/module-tx28.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c index 9a7b08b2a925..0f71f82101cc 100644 --- a/arch/arm/mach-mxs/module-tx28.c +++ b/arch/arm/mach-mxs/module-tx28.c @@ -11,7 +11,7 @@ #include #include -#include "../devices-mx28.h" +#include "devices-mx28.h" #include "module-tx28.h" -- GitLab From a207a4b2e8067cbc7f33924e7f2c0fa4ef43b459 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Jun 2012 18:33:24 -0700 Subject: [PATCH 3216/6849] ipv4: Fix bugs in fib_compute_spec_dst(). Based upon feedback from Julian Anastasov. 1) Use route flags to determine multicast/broadcast, not the packet flags. 2) Leave saddr unspecified in flow key. 3) Adjust how we invoke inet_select_addr(). Pass ip_hdr(skb)->saddr as second arg, and if it was zeronet use link scope. 4) Use loopback as input interface in flow key. Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 63b11ca54d95..1d13217e01ff 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -185,28 +185,36 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) struct net_device *dev = skb->dev; struct in_device *in_dev; struct fib_result res; + struct rtable *rt; struct flowi4 fl4; struct net *net; + int scope; - if (skb->pkt_type != PACKET_BROADCAST && - skb->pkt_type != PACKET_MULTICAST) + rt = skb_rtable(skb); + if (!(rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) return ip_hdr(skb)->daddr; in_dev = __in_dev_get_rcu(dev); BUG_ON(!in_dev); - fl4.flowi4_oif = 0; - fl4.flowi4_iif = 0; - fl4.daddr = ip_hdr(skb)->saddr; - fl4.saddr = ip_hdr(skb)->daddr; - fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); - fl4.flowi4_scope = RT_SCOPE_UNIVERSE; - fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; net = dev_net(dev); - if (!fib_lookup(net, &fl4, &res)) - return FIB_RES_PREFSRC(net, res); - else - return inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); + + scope = RT_SCOPE_UNIVERSE; + if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) { + fl4.flowi4_oif = 0; + fl4.flowi4_iif = net->loopback_dev->ifindex; + fl4.daddr = ip_hdr(skb)->saddr; + fl4.saddr = 0; + fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); + fl4.flowi4_scope = scope; + fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; + if (!fib_lookup(net, &fl4, &res)) + return FIB_RES_PREFSRC(net, res); + } else { + scope = RT_SCOPE_LINK; + } + + return inet_select_addr(dev, ip_hdr(skb)->saddr, scope); } /* Given (packet source, input interface) and optional (dst, oif, tos): -- GitLab From adf643aba8ed620f8c8e2533f4ace3a90e5daecf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 29 Jun 2012 02:34:46 +0100 Subject: [PATCH 3217/6849] ASoC: spdif: Build separate RX and TX objects Otherwise we fail to link when building as modules due to multiple init/exit functions. Reported-by: Fengguang Wu Signed-off-by: Mark Brown --- sound/soc/codecs/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 62c3d4dd1872..acf80888790c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -45,7 +45,8 @@ snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sn95031-objs := sn95031.o -snd-soc-spdif-objs := spdif_transciever.o spdif_receiver.o +snd-soc-spdif-tx-objs := spdif_transciever.o +snd-soc-spdif-rx-objs := spdif_receiver.o snd-soc-ssm2602-objs := ssm2602.o snd-soc-sta32x-objs := sta32x.o snd-soc-stac9766-objs := stac9766.o @@ -159,7 +160,7 @@ obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o -obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o +obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o -- GitLab From 9e56e3800ea42e78b7c816bdd2d87d047be80541 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Jun 2012 18:54:02 -0700 Subject: [PATCH 3218/6849] ipv4: Adjust in_dev handling in fib_validate_source() Checking for in_dev being NULL is pointless. In fact, all of our callers have in_dev precomputed already, so just pass it in and remove the NULL checking. Signed-off-by: David S. Miller --- include/net/ip_fib.h | 2 +- net/ipv4/fib_frontend.c | 27 ++++++++++----------------- net/ipv4/route.c | 10 ++++++---- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 9e6c26d4ba4c..619f68a7185c 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -233,7 +233,7 @@ extern void ip_fib_init(void); extern __be32 fib_compute_spec_dst(struct sk_buff *skb); extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, - u32 *itag); + struct in_device *idev, u32 *itag); extern void fib_select_default(struct fib_result *res); /* Exported by fib_semantics.c */ diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 1d13217e01ff..c84cff52021e 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -226,15 +226,14 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) * called with rcu_read_lock() */ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, - int oif, struct net_device *dev, u32 *itag) + int oif, struct net_device *dev, struct in_device *idev, + u32 *itag) { - struct in_device *in_dev; - struct flowi4 fl4; + int ret, no_addr, rpf, accept_local; struct fib_result res; - int no_addr, rpf, accept_local; - bool dev_match; - int ret; + struct flowi4 fl4; struct net *net; + bool dev_match; fl4.flowi4_oif = 0; fl4.flowi4_iif = oif; @@ -244,19 +243,13 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, fl4.flowi4_scope = RT_SCOPE_UNIVERSE; no_addr = rpf = accept_local = 0; - in_dev = __in_dev_get_rcu(dev); - if (in_dev) { - no_addr = in_dev->ifa_list == NULL; - - /* Ignore rp_filter for packets protected by IPsec. */ - rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(in_dev); + no_addr = idev->ifa_list == NULL; - accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); - fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; - } + /* Ignore rp_filter for packets protected by IPsec. */ + rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev); - if (in_dev == NULL) - goto e_inval; + accept_local = IN_DEV_ACCEPT_LOCAL(idev); + fl4.flowi4_mark = IN_DEV_SRC_VMARK(idev) ? skb->mark : 0; net = dev_net(dev); if (fib_lookup(net, &fl4, &res)) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 83d56a016625..919d69e60bab 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1999,7 +1999,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (!ipv4_is_local_multicast(daddr)) goto e_inval; } else { - err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &itag); + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, + in_dev, &itag); if (err < 0) goto e_err; } @@ -2100,7 +2101,7 @@ static int __mkroute_input(struct sk_buff *skb, err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), - in_dev->dev, &itag); + in_dev->dev, in_dev, &itag); if (err < 0) { ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, saddr); @@ -2274,7 +2275,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { err = fib_validate_source(skb, saddr, daddr, tos, net->loopback_dev->ifindex, - dev, &itag); + dev, in_dev, &itag); if (err < 0) goto martian_source_keep_err; if (err) @@ -2295,7 +2296,8 @@ brd_input: goto e_inval; if (!ipv4_is_zeronet(saddr)) { - err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &itag); + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, + in_dev, &itag); if (err < 0) goto martian_source_keep_err; if (err) -- GitLab From 7784655acc5a946aac49af423cc1099c5d593d73 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 21 Jun 2012 17:50:27 +0000 Subject: [PATCH 3219/6849] powerpc: Fix BPF_JIT code to link with multiple TOCs If the kernel is big enough (eg. allyesconfig), the linker may need to switch TOCs when calling from the BPF JIT code out to the external helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()). In order to do that we need to leave space after the bl for the linker to insert a reload of our TOC pointer. Signed-off-by: Michael Ellerman Acked-by: Matt Evans Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/net/bpf_jit_64.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S index 55ba3855a97f..7d3a3b5619a2 100644 --- a/arch/powerpc/net/bpf_jit_64.S +++ b/arch/powerpc/net/bpf_jit_64.S @@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset: mr r4, r_addr; \ li r6, SIZE; \ bl skb_copy_bits; \ + nop; \ /* R3 = 0 on success */ \ addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ ld r0, 16(r1); \ @@ -156,6 +157,7 @@ bpf_slow_path_byte_msh: mr r4, r_addr; \ li r5, SIZE; \ bl bpf_internal_load_pointer_neg_helper; \ + nop; \ /* R3 != 0 on success */ \ addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ ld r0, 16(r1); \ -- GitLab From 82b2521d257b5c0efd51821cf5fa306e53bbb6ba Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 19 Jun 2012 20:01:45 +0000 Subject: [PATCH 3220/6849] powerpc: Fix uninitialised error in numa.c chroma_defconfig currently gives me this with gcc 4.6: arch/powerpc/mm/numa.c:638:13: error: 'dm' may be used uninitialized in this function [-Werror=uninitialized] It's a bogus warning/error since of_get_drconf_memory() only writes it anyway. Signed-off-by: Michael Neuling cc: [v3.3+] Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b6edbb3b4a54..6e8f677f5646 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -635,7 +635,7 @@ static inline int __init read_usm_ranges(const u32 **usm) */ static void __init parse_drconf_memory(struct device_node *memory) { - const u32 *dm, *usm; + const u32 *uninitialized_var(dm), *usm; unsigned int n, rc, ranges, is_kexec_kdump = 0; unsigned long lmb_size, base, size, sz; int nid; -- GitLab From c58ce2b1e3c75c55e7ebf751afce9f5a30f60b42 Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Wed, 6 Jun 2012 20:56:43 +0000 Subject: [PATCH 3221/6849] ppc64: fix missing to check all bits of _TIF_USER_WORK_MASK in preempt In entry_64.S version of ret_from_except_lite, you'll notice that in the !preempt case, after we've checked MSR_PR we test for any TIF flag in _TIF_USER_WORK_MASK to decide whether to go to do_work or not. However, in the preempt case, we do a convoluted trick to test SIGPENDING only if PR was set and always test NEED_RESCHED ... but we forget to test any other bit of _TIF_USER_WORK_MASK !!! So that means that with preempt, we completely fail to test for things like single step, syscall tracing, etc... This should be fixed as the following path: - Test PR. If not set, go to resume_kernel, else continue. - If go resume_kernel, to do that original do_work. - If else, then always test for _TIF_USER_WORK_MASK to decide to do that original user_work, else restore directly. Signed-off-by: Tiejun Chen Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/entry_64.S | 97 ++++++++++++++-------------------- 1 file changed, 40 insertions(+), 57 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index ed1718feb9d9..5971c85df136 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -558,27 +558,54 @@ _GLOBAL(ret_from_except_lite) mtmsrd r10,1 /* Update machine state */ #endif /* CONFIG_PPC_BOOK3E */ -#ifdef CONFIG_PREEMPT clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ - li r0,_TIF_NEED_RESCHED /* bits to check */ ld r3,_MSR(r1) ld r4,TI_FLAGS(r9) - /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ - rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING - and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */ - bne do_work - -#else /* !CONFIG_PREEMPT */ - ld r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR - beq restore /* if not, just restore regs and return */ + beq resume_kernel /* Check current_thread_info()->flags */ + andi. r0,r4,_TIF_USER_WORK_MASK + beq restore + + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + bl .restore_interrupts + bl .schedule + b .ret_from_except_lite + +1: bl .save_nvgprs + bl .restore_interrupts + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_notify_resume + b .ret_from_except + +resume_kernel: +#ifdef CONFIG_PREEMPT + /* Check if we need to preempt */ + andi. r0,r4,_TIF_NEED_RESCHED + beq+ restore + /* Check that preempt_count() == 0 and interrupts are enabled */ + lwz r8,TI_PREEMPT(r9) + cmpwi cr1,r8,0 + ld r0,SOFTE(r1) + cmpdi r0,0 + crandc eq,cr1*4+eq,eq + bne restore + + /* + * Here we are preempting the current task. We want to make + * sure we are soft-disabled first + */ + SOFT_DISABLE_INTS(r3,r4) +1: bl .preempt_schedule_irq + + /* Re-test flags and eventually loop */ clrrdi r9,r1,THREAD_SHIFT ld r4,TI_FLAGS(r9) - andi. r0,r4,_TIF_USER_WORK_MASK - bne do_work -#endif /* !CONFIG_PREEMPT */ + andi. r0,r4,_TIF_NEED_RESCHED + bne 1b +#endif /* CONFIG_PREEMPT */ .globl fast_exc_return_irq fast_exc_return_irq: @@ -759,50 +786,6 @@ restore_check_irq_replay: #endif /* CONFIG_PPC_BOOK3E */ 1: b .ret_from_except /* What else to do here ? */ - - -3: -do_work: -#ifdef CONFIG_PREEMPT - andi. r0,r3,MSR_PR /* Returning to user mode? */ - bne user_work - /* Check that preempt_count() == 0 and interrupts are enabled */ - lwz r8,TI_PREEMPT(r9) - cmpwi cr1,r8,0 - ld r0,SOFTE(r1) - cmpdi r0,0 - crandc eq,cr1*4+eq,eq - bne restore - - /* - * Here we are preempting the current task. We want to make - * sure we are soft-disabled first - */ - SOFT_DISABLE_INTS(r3,r4) -1: bl .preempt_schedule_irq - - /* Re-test flags and eventually loop */ - clrrdi r9,r1,THREAD_SHIFT - ld r4,TI_FLAGS(r9) - andi. r0,r4,_TIF_NEED_RESCHED - bne 1b - b restore - -user_work: -#endif /* CONFIG_PREEMPT */ - - andi. r0,r4,_TIF_NEED_RESCHED - beq 1f - bl .restore_interrupts - bl .schedule - b .ret_from_except_lite - -1: bl .save_nvgprs - bl .restore_interrupts - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_notify_resume - b .ret_from_except - unrecov_restore: addi r3,r1,STACK_FRAME_OVERHEAD bl .unrecoverable_exception -- GitLab From 2cb387ae758d97ee7396a82528c824b8dc510b8a Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Thu, 7 Jun 2012 17:44:23 +0000 Subject: [PATCH 3222/6849] powerpc: Fix Section mismatch warnings in prom_init.c This patches tries to fix a couple of Section mismatch warnings like following one: WARNING: arch/powerpc/kernel/built-in.o(.text+0x2923c): Section mismatch in reference from the function .prom_query_opal() to the function .init.text:.call_prom() The function .prom_query_opal() references the function __init .call_prom(). This is often because .prom_query_opal lacks a __init annotation or the annotation of .call_prom is wrong. Signed-off-by: Li Zhong Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/prom_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 1b488e5305c5..0794a3017b1b 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1312,7 +1312,7 @@ static struct opal_secondary_data { extern char opal_secondary_entry; -static void prom_query_opal(void) +static void __init prom_query_opal(void) { long rc; @@ -1436,7 +1436,7 @@ static void __init prom_opal_hold_cpus(void) prom_debug("prom_opal_hold_cpus: end...\n"); } -static void prom_opal_takeover(void) +static void __init prom_opal_takeover(void) { struct opal_secondary_data *data = &RELOC(opal_secondary_data); struct opal_takeover_args *args = &data->args; -- GitLab From 2d773aa4810d4a612d1c879faacc38594cc3f841 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 4 Jun 2012 16:27:54 +0000 Subject: [PATCH 3223/6849] powerpc/ftrace: Do not trace restore_interrupts() As I was adding code that affects all archs, I started testing function tracer against PPC64 and found that it currently locks up with 3.4 kernel. I figured it was due to tracing a function that shouldn't be, so I went through the following process to bisect to find the culprit: cat /debug/tracing/available_filter_functions > t num=`wc -l t` sed -ne "1,${num}p" t > t1 let num=num+1 sed -ne "${num},$p" t > t2 cat t1 > /debug/tracing/set_ftrace_filter echo function /debug/tracing/current_tracer It finally came down to this function: restore_interrupts() I'm not sure why this locks up the system. It just seems to prevent scheduling from occurring. Interrupts seem to still work, as I can ping the box. But all user processes freeze. When restore_interrupts() is not traced, function tracing works fine. Cc: stable@kernel.org Signed-off-by: Steven Rostedt Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 7835a5e1ea5f..1b415027ec0e 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -277,7 +277,7 @@ EXPORT_SYMBOL(arch_local_irq_restore); * NOTE: This is called with interrupts hard disabled but not marked * as such in paca->irq_happened, so we need to resync this. */ -void restore_interrupts(void) +void notrace restore_interrupts(void) { if (irqs_disabled()) { local_paca->irq_happened |= PACA_IRQ_HARD_DIS; -- GitLab From 0b17ba7258db83cd02da560884e053b85de371f2 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 27 Jun 2012 13:13:52 +0000 Subject: [PATCH 3224/6849] powerpc: check_and_cede_processor() never cedes Commit f948501b36c6 ("Make hard_irq_disable() actually hard-disable interrupts") caused check_and_cede_processor to stop working. ->irq_happened will never be zero right after a hard_irq_disable so the compiler removes the call to cede_processor completely. The bug was introduced back in the lazy interrupt handling rework of 3.4 but was hidden until recently because hard_irq_disable did nothing. This issue will eventually appear in 3.4 stable since the hard_irq_disable fix is marked stable, so mark this one for stable too. Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hw_irq.h | 5 +++++ arch/powerpc/platforms/pseries/processor_idle.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 32b394f3b854..6eb75b80488c 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -103,6 +103,11 @@ static inline void hard_irq_disable(void) /* include/linux/interrupt.h needs hard_irq_disable to be a macro */ #define hard_irq_disable hard_irq_disable +static inline bool lazy_irq_pending(void) +{ + return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS); +} + /* * This is called by asynchronous interrupts to conditionally * re-enable hard interrupts when soft-disabled after having diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 41a34bc4a9a2..e61483e8e960 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c @@ -106,7 +106,7 @@ static void check_and_cede_processor(void) * we first hard disable then check. */ hard_irq_disable(); - if (get_paca()->irq_happened == 0) + if (!lazy_irq_pending()) cede_processor(); } -- GitLab From bc6dc752f35488160ffac07ae91bed1bddaea32a Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 26 Jun 2012 21:26:37 +0000 Subject: [PATCH 3225/6849] powerpc/pseries: Fix software invalidate TCE The following added support for powernv but broke pseries/BML: 1f1616e powerpc/powernv: Add TCE SW invalidation support TCE_PCI_SW_INVAL was split into FREE and CREATE flags but the tests in the pseries code were not updated to reflect this. Signed-off-by: Michael Neuling cc: stable@kernel.org [v3.3+] Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 0915b1ad66ce..2d311c0caf8e 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -106,7 +106,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, tcep++; } - if (tbl->it_type == TCE_PCI_SWINV_CREATE) + if (tbl->it_type & TCE_PCI_SWINV_CREATE) tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); return 0; } @@ -121,7 +121,7 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) while (npages--) *(tcep++) = 0; - if (tbl->it_type == TCE_PCI_SWINV_FREE) + if (tbl->it_type & TCE_PCI_SWINV_FREE) tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); } -- GitLab From 3085a4b7d33eb3111244173d1383256e94d249a5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Jun 2012 22:17:39 -0700 Subject: [PATCH 3226/6849] ipv4: Remove extraneous assignment of dst->tclassid. We already set it several lines above. Signed-off-by: David S. Miller --- net/ipv4/route.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 919d69e60bab..6a5afc715558 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2327,9 +2327,6 @@ local_input: rth->rt_key_tos = tos; rth->rt_dst = daddr; rth->rt_src = saddr; -#ifdef CONFIG_IP_ROUTE_CLASSID - rth->dst.tclassid = itag; -#endif rth->rt_route_iif = dev->ifindex; rth->rt_iif = dev->ifindex; rth->rt_oif = 0; -- GitLab From 8a720718b37d00cf8ab311902705ae7c7890bb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 18 Jun 2012 22:41:28 +0200 Subject: [PATCH 3227/6849] ASoC: dapm: Fix snd_soc_dapm_put_volsw() connect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit snd_soc_dapm_put_volsw() sets connect incorrectly in the case max > 1 with invert. In that case, the raw disconnect value should be max, which corresponds to the userspace value 0. This use case currently does not appear upstream, but it could break SOC_DAPM_SINGLE() or SOC_DAPM_SINGLE_TLV() elsewhere or in the future. Signed-off-by: Benoît Thébaudeau Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c2206bc835da..967066873aad 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2515,19 +2515,13 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, int wi; val = (ucontrol->value.integer.value[0] & mask); + connect = !!val; if (invert) val = max - val; mask = mask << shift; val = val << shift; - if (val) - /* new connection */ - connect = invert ? 0 : 1; - else - /* old connection must be powered down */ - connect = invert ? 1 : 0; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); change = snd_soc_test_bits(widget->codec, reg, mask, val); -- GitLab From b0dfa4541e48ac4cc5f017285432c89923ad0f58 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Jun 2012 14:16:57 +0100 Subject: [PATCH 3228/6849] ASoC: wm2200: Add missing BCLK rate Without this very high BCLKs will be configured incorrectly. Reported-by: Axel Lin Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/wm2200.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index acbdc5fde923..32682c1b7cde 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1491,6 +1491,7 @@ static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = { static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { 5644800, + 3763200, 2882400, 1881600, 1411200, -- GitLab From c9fe573a6584034670c1a55ee8162d623519cbbf Mon Sep 17 00:00:00 2001 From: "Hebbar, Gururaja" Date: Tue, 26 Jun 2012 19:25:11 +0530 Subject: [PATCH 3229/6849] ASoC: tlv320aic3x: Fix codec pll configure bug In sound/soc/codecs/tlv320aic3x.c data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); snd_soc_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); In the above code, pll-p value is OR'ed with previous value without clearing it. Bug is not seen if pll-p value doesn't change across Sampling frequency. However on some platforms (like AM335x EVM-SK), pll-p may have different values across different sampling frequencies. In such case, above code configures the pll with a wrong value. Because of this bug, when a audio stream is played with pll value different from previous stream, audio is heard as differently(like its stretched). Signed-off-by: Hebbar, Gururaja Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/tlv320aic3x.c | 4 +--- sound/soc/codecs/tlv320aic3x.h | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64d2a4fa34b2..e9b62b5ea637 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -935,9 +935,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, } found: - data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); - snd_soc_write(codec, AIC3X_PLL_PROGA_REG, - data | (pll_p << PLLP_SHIFT)); + snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p); snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT); diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 6f097fb60683..08c7f6685ff0 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -166,6 +166,7 @@ /* PLL registers bitfields */ #define PLLP_SHIFT 0 +#define PLLP_MASK 7 #define PLLQ_SHIFT 3 #define PLLR_SHIFT 0 #define PLLJ_SHIFT 2 -- GitLab From 8663ff75cdca0a66f808e124c5592735793926af Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Fri, 29 Jun 2012 09:35:52 +0200 Subject: [PATCH 3230/6849] ALSA: hda - Fix no sound from ALC662 after Windows reboot Windows use hidden register to control EAPD. Linux use verb to control EAPD. If windows reboot to Linux, it must change the EAPD control to verb control. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5ccf10a4d593..aa4c25e0f327 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6688,6 +6688,31 @@ static const struct alc_model_fixup alc662_fixup_models[] = { {} }; +static void alc662_fill_coef(struct hda_codec *codec) +{ + int val, coef; + + coef = alc_get_coef0(codec); + + switch (codec->vendor_id) { + case 0x10ec0662: + if ((coef & 0x00f0) == 0x0030) { + val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ + alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); + } + break; + case 0x10ec0272: + case 0x10ec0273: + case 0x10ec0663: + case 0x10ec0665: + case 0x10ec0670: + case 0x10ec0671: + case 0x10ec0672: + val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ + alc_write_coef_idx(codec, 0xd, val | (1<<14)); + break; + } +} /* */ @@ -6707,6 +6732,9 @@ static int patch_alc662(struct hda_codec *codec) alc_fix_pll_init(codec, 0x20, 0x04, 15); + spec->init_hook = alc662_fill_coef; + alc662_fill_coef(codec); + alc_pick_fixup(codec, alc662_fixup_models, alc662_fixup_tbl, alc662_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); -- GitLab From 7fa8ad6df71f4778b23e17b0106aaef02b518684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Thu, 28 Jun 2012 20:36:20 +0000 Subject: [PATCH 3231/6849] caif-hsi: Fix merge issues. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the failing merge in net-next by reverting the last net-next merge for caif_hsi.c and then merge in the commit: "caif-hsi: Bugfix - Piggyback'ed embedded CAIF frame lost" from the net repository. The commit:"caif-hsi: Add missing return in error path" from net repository was dropped, as it changed code previously removed in the net-next repository. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 72 ++++++++++++++----------------------- 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 087eb83454c0..0def8b3106f4 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -1131,51 +1131,7 @@ static void cfhsi_setup(struct net_device *dev) cfhsi->cfdev.use_stx = false; cfhsi->cfdev.use_fcs = false; cfhsi->ndev = dev; -} - -int cfhsi_probe(struct platform_device *pdev) -{ - struct cfhsi_ops *(*get_ops)(void); - struct cfhsi *cfhsi = NULL; - struct net_device *ndev; - int res; - - ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup); - if (!ndev) - return -ENODEV; - - cfhsi = netdev_priv(ndev); - cfhsi->ndev = ndev; - cfhsi->pdev = pdev; - - get_ops = symbol_get(cfhsi_get_ops); - if (!get_ops) { - pr_err("%s: failed to get the cfhsi_ops\n", __func__); - return -ENODEV; - } - - /* Assign the HSI device. */ - cfhsi->ops = (*get_ops)(); - if (!cfhsi->ops) { - pr_err("%s: failed to get the cfhsi_ops\n", __func__); - goto err; - } - - /* Assign the driver to this HSI device. */ - cfhsi->ops->cb_ops = &cfhsi->cb_ops; - res = register_netdevice(ndev); - if (res) { - dev_err(&ndev->dev, "%s: Registration error: %d.\n", - __func__, res); - free_netdev(ndev); - } - /* Add CAIF HSI device to list. */ - list_add_tail(&cfhsi->list, &cfhsi_list); - - return res; -err: - symbol_put(cfhsi_get_ops); - return -ENODEV; + cfhsi->cfg = hsi_default_config; } static int cfhsi_open(struct net_device *ndev) @@ -1454,6 +1410,7 @@ static int caif_hsi_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct cfhsi *cfhsi = NULL; + struct cfhsi_ops *(*get_ops)(void); ASSERT_RTNL(); @@ -1461,7 +1418,32 @@ static int caif_hsi_newlink(struct net *src_net, struct net_device *dev, cfhsi_netlink_parms(data, cfhsi); dev_net_set(cfhsi->ndev, src_net); + get_ops = symbol_get(cfhsi_get_ops); + if (!get_ops) { + pr_err("%s: failed to get the cfhsi_ops\n", __func__); + return -ENODEV; + } + + /* Assign the HSI device. */ + cfhsi->ops = (*get_ops)(); + if (!cfhsi->ops) { + pr_err("%s: failed to get the cfhsi_ops\n", __func__); + goto err; + } + + /* Assign the driver to this HSI device. */ + cfhsi->ops->cb_ops = &cfhsi->cb_ops; + if (register_netdevice(dev)) { + pr_warn("%s: caif_hsi device registration failed\n", __func__); + goto err; + } + /* Add CAIF HSI device to list. */ + list_add_tail(&cfhsi->list, &cfhsi_list); + return 0; +err: + symbol_put(cfhsi_get_ops); + return -ENODEV; } static struct rtnl_link_ops caif_hsi_link_ops __read_mostly = { -- GitLab From 1e0b6eac6a150a35b45d019681b0021896354ae5 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Wed, 27 Jun 2012 00:46:58 +0000 Subject: [PATCH 3232/6849] xen/netback: only non-freed SKB is queued into tx_queue After SKB is queued into tx_queue, it will be freed if request_gop is NULL. However, no dequeue action is called in this situation, it is likely that tx_queue constains freed SKB. This patch should fix this issue, and it is based on 3.5.0-rc4+. This issue is found through code inspection, no bug is seen with it currently. I run netperf test for several hours, and no network regression was found. Signed-off-by: Annie Li Acked-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f4a6fcaeffb1..682633bfe00f 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1363,8 +1363,6 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) INVALID_PENDING_IDX); } - __skb_queue_tail(&netbk->tx_queue, skb); - netbk->pending_cons++; request_gop = xen_netbk_get_requests(netbk, vif, @@ -1376,6 +1374,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) } gop = request_gop; + __skb_queue_tail(&netbk->tx_queue, skb); + vif->tx.req_cons = idx; xen_netbk_check_rx_xenvif(vif); -- GitLab From d0087b29f77176480c27c203988b5704847d617c Mon Sep 17 00:00:00 2001 From: Ville Nuorvala Date: Thu, 28 Jun 2012 18:15:52 +0000 Subject: [PATCH 3233/6849] ipv6_tunnel: Allow receiving packets on the fallback tunnel if they pass sanity checks At Facebook, we do Layer-3 DSR via IP-in-IP tunneling. Our load balancers wrap an extra IP header on incoming packets so they can be routed to the backend. In the v4 tunnel driver, when these packets fall on the default tunl0 device, the behavior is to decapsulate them and drop them back on the stack. So our setup is that tunl0 has the VIP and eth0 has (obviously) the backend's real address. In IPv6 we do the same thing, but the v6 tunnel driver didn't have this same behavior - if you didn't have an explicit tunnel setup, it would drop the packet. This patch brings that v4 feature to the v6 driver. The same IPv6 address checks are performed as with any normal tunnel, but as the fallback tunnel endpoint addresses are unspecified, the checks must be performed on a per-packet basis, rather than at tunnel configuration time. [Patch description modified by phil@ipom.com] Signed-off-by: Ville Nuorvala Tested-by: Phil Dibowitz Signed-off-by: David S. Miller --- include/net/ip6_tunnel.h | 2 ++ net/ipv6/ip6_tunnel.c | 65 +++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index fc73e667b50e..358fb86f57eb 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -9,6 +9,8 @@ #define IP6_TNL_F_CAP_XMIT 0x10000 /* capable of receiving packets */ #define IP6_TNL_F_CAP_RCV 0x20000 +/* determine capability on a per-packet basis */ +#define IP6_TNL_F_CAP_PER_PACKET 0x40000 /* IPv6 tunnel */ diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index c9015fad8d65..04a3cba2c123 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -684,24 +684,50 @@ static void ip6ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t, IP6_ECN_set_ce(ipv6_hdr(skb)); } +static __u32 ip6_tnl_get_cap(struct ip6_tnl *t, + const struct in6_addr *laddr, + const struct in6_addr *raddr) +{ + struct ip6_tnl_parm *p = &t->parms; + int ltype = ipv6_addr_type(laddr); + int rtype = ipv6_addr_type(raddr); + __u32 flags = 0; + + if (ltype == IPV6_ADDR_ANY || rtype == IPV6_ADDR_ANY) { + flags = IP6_TNL_F_CAP_PER_PACKET; + } else if (ltype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) && + rtype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) && + !((ltype|rtype) & IPV6_ADDR_LOOPBACK) && + (!((ltype|rtype) & IPV6_ADDR_LINKLOCAL) || p->link)) { + if (ltype&IPV6_ADDR_UNICAST) + flags |= IP6_TNL_F_CAP_XMIT; + if (rtype&IPV6_ADDR_UNICAST) + flags |= IP6_TNL_F_CAP_RCV; + } + return flags; +} + /* called with rcu_read_lock() */ -static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t) +static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t, + const struct in6_addr *laddr, + const struct in6_addr *raddr) { struct ip6_tnl_parm *p = &t->parms; int ret = 0; struct net *net = dev_net(t->dev); - if (p->flags & IP6_TNL_F_CAP_RCV) { + if ((p->flags & IP6_TNL_F_CAP_RCV) || + ((p->flags & IP6_TNL_F_CAP_PER_PACKET) && + (ip6_tnl_get_cap(t, laddr, raddr) & IP6_TNL_F_CAP_RCV))) { struct net_device *ldev = NULL; if (p->link) ldev = dev_get_by_index_rcu(net, p->link); - if ((ipv6_addr_is_multicast(&p->laddr) || - likely(ipv6_chk_addr(net, &p->laddr, ldev, 0))) && - likely(!ipv6_chk_addr(net, &p->raddr, NULL, 0))) + if ((ipv6_addr_is_multicast(laddr) || + likely(ipv6_chk_addr(net, laddr, ldev, 0))) && + likely(!ipv6_chk_addr(net, raddr, NULL, 0))) ret = 1; - } return ret; } @@ -740,7 +766,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, goto discard; } - if (!ip6_tnl_rcv_ctl(t)) { + if (!ip6_tnl_rcv_ctl(t, &ipv6h->daddr, &ipv6h->saddr)) { t->dev->stats.rx_dropped++; rcu_read_unlock(); goto discard; @@ -1114,25 +1140,6 @@ tx_err: return NETDEV_TX_OK; } -static void ip6_tnl_set_cap(struct ip6_tnl *t) -{ - struct ip6_tnl_parm *p = &t->parms; - int ltype = ipv6_addr_type(&p->laddr); - int rtype = ipv6_addr_type(&p->raddr); - - p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV); - - if (ltype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) && - rtype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) && - !((ltype|rtype) & IPV6_ADDR_LOOPBACK) && - (!((ltype|rtype) & IPV6_ADDR_LINKLOCAL) || p->link)) { - if (ltype&IPV6_ADDR_UNICAST) - p->flags |= IP6_TNL_F_CAP_XMIT; - if (rtype&IPV6_ADDR_UNICAST) - p->flags |= IP6_TNL_F_CAP_RCV; - } -} - static void ip6_tnl_link_config(struct ip6_tnl *t) { struct net_device *dev = t->dev; @@ -1153,7 +1160,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) if (!(p->flags&IP6_TNL_F_USE_ORIG_FLOWLABEL)) fl6->flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo; - ip6_tnl_set_cap(t); + p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV|IP6_TNL_F_CAP_PER_PACKET); + p->flags |= ip6_tnl_get_cap(t, &p->laddr, &p->raddr); if (p->flags&IP6_TNL_F_CAP_XMIT && p->flags&IP6_TNL_F_CAP_RCV) dev->flags |= IFF_POINTOPOINT; @@ -1438,6 +1446,9 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) t->parms.proto = IPPROTO_IPV6; dev_hold(dev); + + ip6_tnl_link_config(t); + rcu_assign_pointer(ip6n->tnls_wc[0], t); return 0; } -- GitLab From a777c892cea917b6c67c61f8dff47d8caae7b8a1 Mon Sep 17 00:00:00 2001 From: Manish chopra Date: Thu, 28 Jun 2012 20:12:21 +0000 Subject: [PATCH 3234/6849] netxen_nic: restrict force firmware dump when dump is disabled. o Set the ethtool_dump flag (=ETH_FW_DUMP_DISABLE) when dump is disabled. o update driver version to 4.0.80 Signed-off-by: Manish chopra Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 4 ++-- .../net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 37ccbe54e62d..eb3dfdbb642b 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 79 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.79" +#define _NETXEN_NIC_LINUX_SUBVERSION 80 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.80" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 9103e3e36c28..10468e7932dd 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -826,7 +826,12 @@ netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) dump->len = mdump->md_dump_size; else dump->len = 0; - dump->flag = mdump->md_capture_mask; + + if (!mdump->md_enabled) + dump->flag = ETH_FW_DUMP_DISABLE; + else + dump->flag = mdump->md_capture_mask; + dump->version = adapter->fw_version; return 0; } @@ -840,8 +845,10 @@ netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) switch (val->flag) { case NX_FORCE_FW_DUMP_KEY: - if (!mdump->md_enabled) - mdump->md_enabled = 1; + if (!mdump->md_enabled) { + netdev_info(netdev, "FW dump not enabled\n"); + return 0; + } if (adapter->fw_mdump_rdy) { netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); return 0; -- GitLab From b8c8430726e5bd552e01dacc5a44f3f83f7446ca Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 28 Jun 2012 20:15:13 +0000 Subject: [PATCH 3235/6849] net: l2tp_eth: provide tx_dropped counter Change l2tp_xmit_skb() to return NET_XMIT_DROP in case skb is dropped. Use kfree_skb() instead dev_kfree_skb() for drop_monitor pleasure. Support tx_dropped counter for l2tp_eth Signed-off-by: Eric Dumazet Cc: James Chapman Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 11 ++++++----- net/l2tp/l2tp_eth.c | 15 ++++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 32b2155e7ab4..393355d37b47 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1128,6 +1128,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len int headroom; int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; int udp_len; + int ret = NET_XMIT_SUCCESS; /* Check that there's enough headroom in the skb to insert IP, * UDP and L2TP headers. If not enough, expand it to @@ -1137,8 +1138,8 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len uhlen + hdr_len; old_headroom = skb_headroom(skb); if (skb_cow_head(skb, headroom)) { - dev_kfree_skb(skb); - goto abort; + kfree_skb(skb); + return NET_XMIT_DROP; } new_headroom = skb_headroom(skb); @@ -1156,7 +1157,8 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len bh_lock_sock(sk); if (sock_owned_by_user(sk)) { - dev_kfree_skb(skb); + kfree_skb(skb); + ret = NET_XMIT_DROP; goto out_unlock; } @@ -1215,8 +1217,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len out_unlock: bh_unlock_sock(sk); -abort: - return 0; + return ret; } EXPORT_SYMBOL_GPL(l2tp_xmit_skb); diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 47b259fccd27..f9ee74deeac2 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -44,6 +44,7 @@ struct l2tp_eth { struct list_head list; atomic_long_t tx_bytes; atomic_long_t tx_packets; + atomic_long_t tx_dropped; atomic_long_t rx_bytes; atomic_long_t rx_packets; atomic_long_t rx_errors; @@ -92,12 +93,15 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) { struct l2tp_eth *priv = netdev_priv(dev); struct l2tp_session *session = priv->session; + unsigned int len = skb->len; + int ret = l2tp_xmit_skb(session, skb, session->hdr_len); - atomic_long_add(skb->len, &priv->tx_bytes); - atomic_long_inc(&priv->tx_packets); - - l2tp_xmit_skb(session, skb, session->hdr_len); - + if (likely(ret == NET_XMIT_SUCCESS)) { + atomic_long_add(len, &priv->tx_bytes); + atomic_long_inc(&priv->tx_packets); + } else { + atomic_long_inc(&priv->tx_dropped); + } return NETDEV_TX_OK; } @@ -108,6 +112,7 @@ static struct rtnl_link_stats64 *l2tp_eth_get_stats64(struct net_device *dev, stats->tx_bytes = atomic_long_read(&priv->tx_bytes); stats->tx_packets = atomic_long_read(&priv->tx_packets); + stats->tx_dropped = atomic_long_read(&priv->tx_dropped); stats->rx_bytes = atomic_long_read(&priv->rx_bytes); stats->rx_packets = atomic_long_read(&priv->rx_packets); stats->rx_errors = atomic_long_read(&priv->rx_errors); -- GitLab From 7a9bc9b81a5bc6e44ebc80ef781332e4385083f2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 29 Jun 2012 01:32:45 -0700 Subject: [PATCH 3236/6849] ipv4: Elide fib_validate_source() completely when possible. If rpfilter is off (or the SKB has an IPSEC path) and there are not tclassid users, we don't have to do anything at all when fib_validate_source() is invoked besides setting the itag to zero. We monitor tclassid uses with a counter (modified only under RTNL and marked __read_mostly) and we protect the fib_validate_source() real work with a test against this counter and whether rpfilter is to be done. Having a way to know whether we need no tclassid processing or not also opens the door for future optimized rpfilter algorithms that do not perform full FIB lookups. Signed-off-by: David S. Miller --- include/net/fib_rules.h | 1 + include/net/ip_fib.h | 5 +++++ net/core/fib_rules.c | 4 ++++ net/ipv4/fib_frontend.c | 32 ++++++++++++++++++++++++-------- net/ipv4/fib_rules.c | 16 +++++++++++++++- net/ipv4/fib_semantics.c | 10 ++++++++++ 6 files changed, 59 insertions(+), 9 deletions(-) diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 075f1e3a0fed..e361f4882426 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -52,6 +52,7 @@ struct fib_rules_ops { struct sk_buff *, struct fib_rule_hdr *, struct nlattr **); + void (*delete)(struct fib_rule *); int (*compare)(struct fib_rule *, struct fib_rule_hdr *, struct nlattr **); diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 619f68a7185c..3dc7c96bbeab 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -235,6 +235,11 @@ extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, struct in_device *idev, u32 *itag); extern void fib_select_default(struct fib_result *res); +#ifdef CONFIG_IP_ROUTE_CLASSID +extern int fib_num_tclassid_users; +#else +#define fib_num_tclassid_users 0 +#endif /* Exported by fib_semantics.c */ extern int ip_fib_check_default(__be32 gw, struct net_device *dev); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 72cceb79d0d4..ab7db83236c9 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -151,6 +151,8 @@ static void fib_rules_cleanup_ops(struct fib_rules_ops *ops) list_for_each_entry_safe(rule, tmp, &ops->rules_list, list) { list_del_rcu(&rule->list); + if (ops->delete) + ops->delete(rule); fib_rule_put(rule); } } @@ -499,6 +501,8 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) notify_rule_change(RTM_DELRULE, rule, ops, nlh, NETLINK_CB(skb).pid); + if (ops->delete) + ops->delete(rule); fib_rule_put(rule); flush_route_cache(ops); rules_ops_put(ops); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index c84cff52021e..ae528d1b293a 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -217,6 +218,10 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) return inet_select_addr(dev, ip_hdr(skb)->saddr, scope); } +#ifdef CONFIG_IP_ROUTE_CLASSID +int fib_num_tclassid_users __read_mostly; +#endif + /* Given (packet source, input interface) and optional (dst, oif, tos): * - (main) check, that source is valid i.e. not broadcast or our local * address. @@ -225,11 +230,11 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) * - check, that packet arrived from expected physical interface. * called with rcu_read_lock() */ -int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, - int oif, struct net_device *dev, struct in_device *idev, - u32 *itag) +static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, + u8 tos, int oif, struct net_device *dev, + int rpf, struct in_device *idev, u32 *itag) { - int ret, no_addr, rpf, accept_local; + int ret, no_addr, accept_local; struct fib_result res; struct flowi4 fl4; struct net *net; @@ -242,12 +247,9 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, fl4.flowi4_tos = tos; fl4.flowi4_scope = RT_SCOPE_UNIVERSE; - no_addr = rpf = accept_local = 0; + no_addr = accept_local = 0; no_addr = idev->ifa_list == NULL; - /* Ignore rp_filter for packets protected by IPsec. */ - rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev); - accept_local = IN_DEV_ACCEPT_LOCAL(idev); fl4.flowi4_mark = IN_DEV_SRC_VMARK(idev) ? skb->mark : 0; @@ -303,6 +305,20 @@ e_rpf: return -EXDEV; } +/* Ignore rp_filter for packets protected by IPsec. */ +int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, + u8 tos, int oif, struct net_device *dev, + struct in_device *idev, u32 *itag) +{ + int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev); + + if (!r && !fib_num_tclassid_users) { + *itag = 0; + return 0; + } + return __fib_validate_source(skb, src, dst, tos, oif, dev, r, idev, itag); +} + static inline __be32 sk_extract_addr(struct sockaddr *addr) { return ((struct sockaddr_in *) addr)->sin_addr.s_addr; diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 2d043f71ef70..b23fd952c84f 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -169,8 +169,11 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, rule4->dst = nla_get_be32(tb[FRA_DST]); #ifdef CONFIG_IP_ROUTE_CLASSID - if (tb[FRA_FLOW]) + if (tb[FRA_FLOW]) { rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); + if (rule4->tclassid) + fib_num_tclassid_users++; + } #endif rule4->src_len = frh->src_len; @@ -184,6 +187,16 @@ errout: return err; } +static void fib4_rule_delete(struct fib_rule *rule) +{ +#ifdef CONFIG_IP_ROUTE_CLASSID + struct fib4_rule *rule4 = (struct fib4_rule *) rule; + + if (rule4->tclassid) + fib_num_tclassid_users--; +#endif +} + static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, struct nlattr **tb) { @@ -256,6 +269,7 @@ static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { .action = fib4_rule_action, .match = fib4_rule_match, .configure = fib4_rule_configure, + .delete = fib4_rule_delete, .compare = fib4_rule_compare, .fill = fib4_rule_fill, .default_pref = fib_default_rule_pref, diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 415f8230fc88..c46c20b6b0b6 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -163,6 +163,12 @@ void free_fib_info(struct fib_info *fi) return; } fib_info_cnt--; +#ifdef CONFIG_IP_ROUTE_CLASSID + change_nexthops(fi) { + if (nexthop_nh->nh_tclassid) + fib_num_tclassid_users--; + } endfor_nexthops(fi); +#endif call_rcu(&fi->rcu, free_fib_info_rcu); } @@ -421,6 +427,8 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh, #ifdef CONFIG_IP_ROUTE_CLASSID nla = nla_find(attrs, attrlen, RTA_FLOW); nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; + if (nexthop_nh->nh_tclassid) + fib_num_tclassid_users++; #endif } @@ -815,6 +823,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) nh->nh_flags = cfg->fc_flags; #ifdef CONFIG_IP_ROUTE_CLASSID nh->nh_tclassid = cfg->fc_flow; + if (nh->nh_tclassid) + fib_num_tclassid_users++; #endif #ifdef CONFIG_IP_ROUTE_MULTIPATH nh->nh_weight = 1; -- GitLab From d31f4d448f7671dc3e6a7a1c92a4c085a36058bb Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Thu, 28 Jun 2012 02:57:48 +0000 Subject: [PATCH 3237/6849] netfilter: ipset: fix crash if IPSET_CMD_NONE command is sent This patch fixes a crash if that ipset command is sent over nfnetlink. Signed-off-by: Tomasz Bursztyka Acked-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipset/ip_set_core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 819c342f5b30..9730882697aa 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -639,6 +639,14 @@ find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set) return 0; } +static int +ip_set_none(struct sock *ctnl, struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const attr[]) +{ + return -EOPNOTSUPP; +} + static int ip_set_create(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, @@ -1539,6 +1547,10 @@ nlmsg_failure: } static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { + [IPSET_CMD_NONE] = { + .call = ip_set_none, + .attr_count = IPSET_ATTR_CMD_MAX, + }, [IPSET_CMD_CREATE] = { .call = ip_set_create, .attr_count = IPSET_ATTR_CMD_MAX, -- GitLab From 4009e18851ea555959c6017d848983b3d60bf667 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Thu, 28 Jun 2012 02:57:49 +0000 Subject: [PATCH 3238/6849] netfilter: nfnetlink: fix missing rcu_read_unlock in nfnetlink_rcv_msg Bug added in commit 6b75e3e8d664a9a (netfilter: nfnetlink: add RCU in nfnetlink_rcv_msg()) Signed-off-by: Tomasz Bursztyka Acked-by: Eric Dumazet Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 3e797d1fcb94..791d56bbd74a 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -169,8 +169,10 @@ replay: err = nla_parse(cda, ss->cb[cb_id].attr_count, attr, attrlen, ss->cb[cb_id].policy); - if (err < 0) + if (err < 0) { + rcu_read_unlock(); return err; + } if (nc->call_rcu) { err = nc->call_rcu(net->nfnl, skb, nlh, -- GitLab From 60771780c27cbc93d0b78da0c7fd7a8a540b029e Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:46:56 +0200 Subject: [PATCH 3239/6849] cfg80211: introduce cfg80211_stop_ap This functionality will be reused when interface is going down. Avoids code duplication. Also adds missing wdev locking. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/Makefile | 2 +- net/wireless/ap.c | 44 ++++++++++++++++++++++++++++++++++++++++++ net/wireless/core.h | 4 ++++ net/wireless/nl80211.c | 17 +--------------- 4 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 net/wireless/ap.c diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 55a28ab21db9..0f7e0d621ab0 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o diff --git a/net/wireless/ap.c b/net/wireless/ap.c new file mode 100644 index 000000000000..45199cca63d5 --- /dev/null +++ b/net/wireless/ap.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include "nl80211.h" +#include "core.h" + + +static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + ASSERT_WDEV_LOCK(wdev); + + if (!rdev->ops->stop_ap) + return -EOPNOTSUPP; + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; + + if (!wdev->beacon_interval) + return -ENOENT; + + err = rdev->ops->stop_ap(&rdev->wiphy, dev); + if (!err) + wdev->beacon_interval = 0; + + return err; +} + +int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_stop_ap(rdev, dev); + wdev_unlock(wdev); + + return err; +} diff --git a/net/wireless/core.h b/net/wireless/core.h index 609a579255ac..fef476d2117e 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -289,6 +289,10 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, int freq, enum nl80211_channel_type channel_type); +/* AP */ +int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, + struct net_device *dev); + /* MLME */ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, struct net_device *dev, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5c4a720f0442..20d0fd6d1286 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2521,23 +2521,8 @@ static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; - - if (!rdev->ops->stop_ap) - return -EOPNOTSUPP; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) - return -EOPNOTSUPP; - - if (!wdev->beacon_interval) - return -ENOENT; - - err = rdev->ops->stop_ap(&rdev->wiphy, dev); - if (!err) - wdev->beacon_interval = 0; - return err; + return cfg80211_stop_ap(rdev, dev); } static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { -- GitLab From ac800140c20e7ae51117e71289065bedd4930fc2 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:46:57 +0200 Subject: [PATCH 3240/6849] cfg80211: .stop_ap when interface is going down We'll need this for proper channel tracking (which is going to be needed for channel context accounting and finding matching/active interface combination). Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/core.c | 3 +++ net/wireless/util.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/net/wireless/core.c b/net/wireless/core.c index ddd32afa5f0a..c65f59c952c9 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -810,6 +810,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, case NL80211_IFTYPE_MESH_POINT: cfg80211_leave_mesh(rdev, dev); break; + case NL80211_IFTYPE_AP: + cfg80211_stop_ap(rdev, dev); + break; default: break; } diff --git a/net/wireless/util.c b/net/wireless/util.c index 316cfd00914f..fc948d0a53f3 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -814,6 +814,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, dev->ieee80211_ptr->mesh_id_up_len = 0; switch (otype) { + case NL80211_IFTYPE_AP: + cfg80211_stop_ap(rdev, dev); + break; case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, false); break; -- GitLab From f4489ebeffa436c8427a20e2f05004e783708cde Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:46:58 +0200 Subject: [PATCH 3241/6849] cfg80211: add channel tracking for AP and mesh We need to know which channel is used by a running AP and mesh for channel context accounting and finding matching/active interface combination. STA/IBSS have current_bss already which allows us to check which channel a vif is tuned to. Non-fixed channel IBSS can be handled with additional changes. Monitor mode is going to be handled differently. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 3 +++ net/wireless/ap.c | 4 +++- net/wireless/mesh.c | 18 ++++++++++++++---- net/wireless/mlme.c | 1 + net/wireless/nl80211.c | 1 + 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1fc89c4f930c..c62bc7864adf 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2408,6 +2408,9 @@ struct wireless_dev { struct ieee80211_channel *preset_chan; enum nl80211_channel_type preset_chantype; + /* for AP and mesh channel tracking */ + struct ieee80211_channel *channel; + bool ps; int ps_timeout; diff --git a/net/wireless/ap.c b/net/wireless/ap.c index 45199cca63d5..fcc60d8dbefa 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c @@ -24,8 +24,10 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, return -ENOENT; err = rdev->ops->stop_ap(&rdev->wiphy, dev); - if (!err) + if (!err) { wdev->beacon_interval = 0; + wdev->channel = NULL; + } return err; } diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 3b73b07486cf..bab381344723 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -159,6 +159,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (!err) { memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); wdev->mesh_id_len = setup->mesh_id_len; + wdev->channel = setup->channel; } return err; @@ -184,6 +185,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, enum nl80211_channel_type channel_type) { struct ieee80211_channel *channel; + int err; channel = rdev_freq_to_chan(rdev, freq, channel_type); if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, @@ -205,9 +207,14 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, if (!netif_running(wdev->netdev)) return -ENETDOWN; - return rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, - wdev->netdev, - channel); + + err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, + wdev->netdev, + channel); + if (!err) + wdev->channel = channel; + + return err; } if (wdev->mesh_id_len) @@ -249,8 +256,11 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, return -ENOTCONN; err = rdev->ops->leave_mesh(&rdev->wiphy, dev); - if (!err) + if (!err) { wdev->mesh_id_len = 0; + wdev->channel = NULL; + } + return err; } diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index da4406f11929..a7882eb8c46e 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -947,6 +947,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, if (WARN_ON(!chan)) goto out; + wdev->channel = chan; nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL); out: wdev_unlock(wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 20d0fd6d1286..12096b4ebf62 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2488,6 +2488,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) wdev->preset_chan = params.channel; wdev->preset_chantype = params.channel_type; wdev->beacon_interval = params.beacon_interval; + wdev->channel = params.channel; } return err; } -- GitLab From c30a3d38689bc601e03d5f2ad3c37d8ea13e46ca Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:46:59 +0200 Subject: [PATCH 3242/6849] cfg80211: track ibss fixed channel IBSS may hop between channels. It is necessary to account this special case when considering interface combinations. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 2 ++ net/wireless/ibss.c | 1 + 2 files changed, 3 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index c62bc7864adf..e030c6af86dd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2411,6 +2411,8 @@ struct wireless_dev { /* for AP and mesh channel tracking */ struct ieee80211_channel *channel; + bool ibss_fixed; + bool ps; int ps_timeout; diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 89baa3328411..b90fd86b2d18 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -113,6 +113,7 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, kfree(wdev->connect_keys); wdev->connect_keys = connkeys; + wdev->ibss_fixed = params->channel_fixed; #ifdef CONFIG_CFG80211_WEXT wdev->wext.ibss.channel = params->channel; #endif -- GitLab From 26ab9a0c589db9ba2710f042c4959da25fd3297b Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:00 +0200 Subject: [PATCH 3243/6849] cfg80211: introduce cfg80211_get_chan_state Helper function for finding out which channel is used by a given interface. An exclusive channel can be used only by a single interface. This is mainly for non-fixed channel IBSS handling. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/chan.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ net/wireless/core.h | 12 +++++++++++ 2 files changed, 63 insertions(+) diff --git a/net/wireless/chan.c b/net/wireless/chan.c index c1999e45a07c..167e7cb60089 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -92,3 +92,54 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); } + +void +cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + struct ieee80211_channel **chan, + enum cfg80211_chan_mode *chanmode) +{ + *chan = NULL; + *chanmode = CHAN_MODE_UNDEFINED; + + ASSERT_RDEV_LOCK(rdev); + ASSERT_WDEV_LOCK(wdev); + + if (!netif_running(wdev->netdev)) + return; + + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + if (wdev->current_bss) { + *chan = wdev->current_bss->pub.channel; + *chanmode = wdev->ibss_fixed + ? CHAN_MODE_SHARED + : CHAN_MODE_EXCLUSIVE; + return; + } + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + if (wdev->current_bss) { + *chan = wdev->current_bss->pub.channel; + *chanmode = CHAN_MODE_SHARED; + return; + } + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_MESH_POINT: + *chan = wdev->channel; + *chanmode = CHAN_MODE_SHARED; + return; + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_WDS: + /* these interface types don't really have a channel */ + return; + case NL80211_IFTYPE_UNSPECIFIED: + case NUM_NL80211_IFTYPES: + WARN_ON(1); + } + + return; +} diff --git a/net/wireless/core.h b/net/wireless/core.h index fef476d2117e..56f18c2eb919 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -241,6 +241,12 @@ struct cfg80211_cached_keys { int def, defmgmt; }; +enum cfg80211_chan_mode { + CHAN_MODE_UNDEFINED, + CHAN_MODE_SHARED, + CHAN_MODE_EXCLUSIVE, +}; + /* free object */ extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev); @@ -419,6 +425,12 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, return cfg80211_can_change_interface(rdev, NULL, iftype); } +void +cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + struct ieee80211_channel **chan, + enum cfg80211_chan_mode *chanmode); + struct ieee80211_channel * rdev_freq_to_chan(struct cfg80211_registered_device *rdev, int freq, enum nl80211_channel_type channel_type); -- GitLab From dbbae26afa81320b3315fb4ad755b20f1ff256b4 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:01 +0200 Subject: [PATCH 3244/6849] cfg80211: track monitor interfaces count Implements .set_monitor_enabled(wiphy, enabled). Notifies driver upon change of interface layout. If only monitor interfaces become present it is called with 2nd argument being true. If non-monitor interface appears then 2nd argument is false. Driver is notified only upon change. This makes it more obvious about the fact that cfg80211 supports single monitor channel. Once we implement multi-channel we don't want to allow setting monitor channel while other interface types are running. Otherwise it would be ambiguous once we start considering num_different_channels. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 4 ++++ net/wireless/core.c | 24 ++++++++++++++++++++++++ net/wireless/core.h | 14 ++++++++++++++ net/wireless/util.c | 5 +++++ 4 files changed, 47 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e030c6af86dd..f0d213dd8fe7 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1499,6 +1499,8 @@ struct cfg80211_gtk_rekey_data { * interfaces are active this callback should reject the configuration. * If no interfaces are active or the device is down, the channel should * be stored for when a monitor interface becomes active. + * @set_monitor_enabled: Notify driver that there are only monitor + * interfaces running. * @get_channel: Get the current operating channel, should return %NULL if * there's no single defined operating channel if for example the * device implements channel hopping for multi-channel virtual interfaces. @@ -1817,6 +1819,8 @@ struct cfg80211_ops { struct ethtool_stats *stats, u64 *data); void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, u32 sset, u8 *data); + + void (*set_monitor_enabled)(struct wiphy *wiphy, bool enabled); }; /* diff --git a/net/wireless/core.c b/net/wireless/core.c index c65f59c952c9..8412da7d0f25 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -717,6 +717,24 @@ static struct device_type wiphy_type = { .name = "wlan", }; +void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, + enum nl80211_iftype iftype, int num) +{ + bool has_monitors_only_old = cfg80211_has_monitors_only(rdev); + bool has_monitors_only_new; + + ASSERT_RDEV_LOCK(rdev); + + rdev->num_running_ifaces += num; + if (iftype == NL80211_IFTYPE_MONITOR) + rdev->num_running_monitor_ifaces += num; + + has_monitors_only_new = cfg80211_has_monitors_only(rdev); + if (has_monitors_only_new != has_monitors_only_old) + rdev->ops->set_monitor_enabled(&rdev->wiphy, + has_monitors_only_new); +} + static int cfg80211_netdev_notifier_call(struct notifier_block *nb, unsigned long state, void *ndev) @@ -820,6 +838,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, break; case NETDEV_DOWN: dev_hold(dev); + cfg80211_lock_rdev(rdev); + cfg80211_update_iface_num(rdev, wdev->iftype, -1); + cfg80211_unlock_rdev(rdev); queue_work(cfg80211_wq, &wdev->cleanup_work); break; case NETDEV_UP: @@ -927,6 +948,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, ret = cfg80211_can_add_interface(rdev, wdev->iftype); if (ret) return notifier_from_errno(ret); + cfg80211_lock_rdev(rdev); + cfg80211_update_iface_num(rdev, wdev->iftype, 1); + cfg80211_unlock_rdev(rdev); break; } diff --git a/net/wireless/core.h b/net/wireless/core.h index 56f18c2eb919..99acd51343b1 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -56,6 +56,9 @@ struct cfg80211_registered_device { u32 ap_beacons_nlpid; + int num_running_ifaces; + int num_running_monitor_ifaces; + /* BSSes/scanning */ spinlock_t bss_lock; struct list_head bss_list; @@ -197,6 +200,14 @@ static inline void wdev_unlock(struct wireless_dev *wdev) #define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) #define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) +static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) +{ + ASSERT_RDEV_LOCK(rdev); + + return rdev->num_running_ifaces == rdev->num_running_monitor_ifaces && + rdev->num_running_ifaces > 0; +} + enum cfg80211_event_type { EVENT_CONNECT_RESULT, EVENT_ROAMED, @@ -444,6 +455,9 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, u32 beacon_int); +void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, + enum nl80211_iftype iftype, int num); + #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) #else diff --git a/net/wireless/util.c b/net/wireless/util.c index fc948d0a53f3..9b92ec57d07b 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -871,6 +871,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, } } + if (!err && ntype != otype && netif_running(dev)) { + cfg80211_update_iface_num(rdev, ntype, 1); + cfg80211_update_iface_num(rdev, otype, -1); + } + return err; } -- GitLab From 870d37fc22f3e40f9f23e06c581c8538fc16a2f0 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:02 +0200 Subject: [PATCH 3245/6849] mac80211: refactor virtual monitor code Use cfg80211 the new .set_monitor_enabled instead of tracking it inside mac80211. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 11 +++++++++++ net/mac80211/ieee80211_i.h | 4 ++++ net/mac80211/iface.c | 16 ++-------------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0f02c8b77e1c..ea4b1ea9105a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2990,6 +2990,16 @@ ieee80211_wiphy_get_channel(struct wiphy *wiphy, return local->oper_channel; } +static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + + if (enabled) + WARN_ON(ieee80211_add_virtual_monitor(local)); + else + ieee80211_del_virtual_monitor(local); +} + #ifdef CONFIG_PM static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled) { @@ -3065,6 +3075,7 @@ struct cfg80211_ops mac80211_config_ops = { .probe_client = ieee80211_probe_client, .get_channel = ieee80211_wiphy_get_channel, .set_noack_map = ieee80211_set_noack_map, + .set_monitor_enabled = ieee80211_set_monitor_enabled, #ifdef CONFIG_PM .set_wakeup = ieee80211_set_wakeup, #endif diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6b7157d20507..b88bdfd248ff 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1485,6 +1485,10 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, bool need_basic); +/* virtual monitor */ +int ieee80211_add_virtual_monitor(struct ieee80211_local *local); +void ieee80211_del_virtual_monitor(struct ieee80211_local *local); + /* channel management */ enum ieee80211_chan_mode { CHAN_MODE_UNDEFINED, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 0a6b4e1043cb..fbef7a1ada7a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -330,7 +330,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; } -static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) +int ieee80211_add_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int ret; @@ -371,7 +371,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) return 0; } -static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) +void ieee80211_del_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; @@ -487,12 +487,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) break; } - if (local->monitors == 0 && local->open_count == 0) { - res = ieee80211_add_virtual_monitor(local); - if (res) - goto err_stop; - } - /* must be before the call to ieee80211_configure_filter */ local->monitors++; if (local->monitors == 1) { @@ -507,8 +501,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) break; default: if (coming_up) { - ieee80211_del_virtual_monitor(local); - res = drv_add_interface(local, sdata); if (res) goto err_stop; @@ -743,7 +735,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, if (local->monitors == 0) { local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; - ieee80211_del_virtual_monitor(local); } ieee80211_adjust_monitor_flags(sdata, -1); @@ -817,9 +808,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, } } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - if (local->monitors == local->open_count && local->monitors > 0) - ieee80211_add_virtual_monitor(local); } static int ieee80211_stop(struct net_device *dev) -- GitLab From 4f03c1ed8901a01ad4abcef95c02c007a2d481c2 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:03 +0200 Subject: [PATCH 3246/6849] cfg80211: refuse to .set_monitor_channel when non-monitors are present Having .set_monitor_channel work with non-monitor interfaces running would make interface combinations accounting ambiguous. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/chan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 167e7cb60089..019401b0b5e3 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -85,6 +85,8 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, if (!rdev->ops->set_monitor_channel) return -EOPNOTSUPP; + if (!cfg80211_has_monitors_only(rdev)) + return -EBUSY; chan = rdev_freq_to_chan(rdev, freq, chantype); if (!chan) -- GitLab From b78e8ceac23655e1e06b30aa95ab11742d1ac7c0 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:04 +0200 Subject: [PATCH 3247/6849] cfg80211: track monitor channel Make it even more obvious we support single monitor channel. This will allow us to remove .get_channel. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/chan.c | 9 ++++++++- net/wireless/core.c | 8 +++++++- net/wireless/core.h | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 019401b0b5e3..434c56b92c3c 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -82,6 +82,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, int freq, enum nl80211_channel_type chantype) { struct ieee80211_channel *chan; + int err; if (!rdev->ops->set_monitor_channel) return -EOPNOTSUPP; @@ -92,7 +93,13 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, if (!chan) return -EINVAL; - return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); + err = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); + if (!err) { + rdev->monitor_channel = chan; + rdev->monitor_channel_type = chantype; + } + + return err; } void diff --git a/net/wireless/core.c b/net/wireless/core.c index 8412da7d0f25..1b5daa73b3a9 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -730,9 +730,15 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, rdev->num_running_monitor_ifaces += num; has_monitors_only_new = cfg80211_has_monitors_only(rdev); - if (has_monitors_only_new != has_monitors_only_old) + if (has_monitors_only_new != has_monitors_only_old) { rdev->ops->set_monitor_enabled(&rdev->wiphy, has_monitors_only_new); + + if (!has_monitors_only_new) { + rdev->monitor_channel = NULL; + rdev->monitor_channel_type = NL80211_CHAN_NO_HT; + } + } } static int cfg80211_netdev_notifier_call(struct notifier_block *nb, diff --git a/net/wireless/core.h b/net/wireless/core.h index 99acd51343b1..d5efe1b0a8f7 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -59,6 +59,9 @@ struct cfg80211_registered_device { int num_running_ifaces; int num_running_monitor_ifaces; + struct ieee80211_channel *monitor_channel; + enum nl80211_channel_type monitor_channel_type; + /* BSSes/scanning */ spinlock_t bss_lock; struct list_head bss_list; -- GitLab From a69b40a95b121c4bfc52a20cccd28708ae550af1 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:05 +0200 Subject: [PATCH 3248/6849] cfg80211: set initial monitor channel Implements behaviour seen in mac80211. A running monitor always has a channel - even before .set_channel. This way we won't break current behaviour. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/core.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/net/wireless/core.c b/net/wireless/core.c index 1b5daa73b3a9..580551e9caba 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -717,6 +717,35 @@ static struct device_type wiphy_type = { .name = "wlan", }; +static struct ieee80211_channel * +cfg80211_get_any_chan(struct cfg80211_registered_device *rdev) +{ + struct ieee80211_supported_band *sband; + int i; + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + sband = rdev->wiphy.bands[i]; + if (sband && sband->n_channels > 0) + return &sband->channels[0]; + } + + return NULL; +} + +static void cfg80211_init_mon_chan(struct cfg80211_registered_device *rdev) +{ + struct ieee80211_channel *chan; + + chan = cfg80211_get_any_chan(rdev); + if (WARN_ON(!chan)) + return; + + mutex_lock(&rdev->devlist_mtx); + WARN_ON(cfg80211_set_monitor_channel(rdev, chan->center_freq, + NL80211_CHAN_NO_HT)); + mutex_unlock(&rdev->devlist_mtx); +} + void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num) { @@ -737,6 +766,8 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, if (!has_monitors_only_new) { rdev->monitor_channel = NULL; rdev->monitor_channel_type = NL80211_CHAN_NO_HT; + } else { + cfg80211_init_mon_chan(rdev); } } } -- GitLab From 2e165b818456ecc1024dd0387eeac64745526377 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:06 +0200 Subject: [PATCH 3249/6849] cfg80211/mac80211: remove .get_channel We do not need it anymore since cfg80211 tracks monitor channel and monitor channel type. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 6 ------ net/mac80211/cfg.c | 11 ----------- net/wireless/nl80211.c | 15 +++++---------- net/wireless/wext-compat.c | 9 ++------- 4 files changed, 7 insertions(+), 34 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f0d213dd8fe7..fa269347355b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1501,9 +1501,6 @@ struct cfg80211_gtk_rekey_data { * be stored for when a monitor interface becomes active. * @set_monitor_enabled: Notify driver that there are only monitor * interfaces running. - * @get_channel: Get the current operating channel, should return %NULL if - * there's no single defined operating channel if for example the - * device implements channel hopping for multi-channel virtual interfaces. * * @scan: Request to do a scan. If returning zero, the scan request is given * the driver, and will be valid until passed to cfg80211_scan_done(). @@ -1810,9 +1807,6 @@ struct cfg80211_ops { struct net_device *dev, u16 noack_map); - struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy, - enum nl80211_channel_type *type); - int (*get_et_sset_count)(struct wiphy *wiphy, struct net_device *dev, int sset); void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ea4b1ea9105a..ccbe2413142a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2980,16 +2980,6 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, return 0; } -static struct ieee80211_channel * -ieee80211_wiphy_get_channel(struct wiphy *wiphy, - enum nl80211_channel_type *type) -{ - struct ieee80211_local *local = wiphy_priv(wiphy); - - *type = local->_oper_channel_type; - return local->oper_channel; -} - static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled) { struct ieee80211_local *local = wiphy_priv(wiphy); @@ -3073,7 +3063,6 @@ struct cfg80211_ops mac80211_config_ops = { .tdls_oper = ieee80211_tdls_oper, .tdls_mgmt = ieee80211_tdls_mgmt, .probe_client = ieee80211_probe_client, - .get_channel = ieee80211_wiphy_get_channel, .set_noack_map = ieee80211_set_noack_map, .set_monitor_enabled = ieee80211_set_monitor_enabled, #ifdef CONFIG_PM diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 12096b4ebf62..5d29ed1f7c62 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1689,16 +1689,11 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, (cfg80211_rdev_list_generation << 2))) goto nla_put_failure; - if (rdev->ops->get_channel) { - struct ieee80211_channel *chan; - enum nl80211_channel_type channel_type; - - chan = rdev->ops->get_channel(&rdev->wiphy, &channel_type); - if (chan && - (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, - chan->center_freq) || - nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, - channel_type))) + if (rdev->monitor_channel) { + if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, + rdev->monitor_channel->center_freq) || + nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, + rdev->monitor_channel_type)) goto nla_put_failure; } diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index bc879833b21f..7df42f541873 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -827,8 +827,6 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct ieee80211_channel *chan; - enum nl80211_channel_type channel_type; switch (wdev->iftype) { case NL80211_IFTYPE_STATION: @@ -836,13 +834,10 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, case NL80211_IFTYPE_ADHOC: return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); case NL80211_IFTYPE_MONITOR: - if (!rdev->ops->get_channel) + if (!rdev->monitor_channel) return -EINVAL; - chan = rdev->ops->get_channel(wdev->wiphy, &channel_type); - if (!chan) - return -EINVAL; - freq->m = chan->center_freq; + freq->m = rdev->monitor_channel->center_freq; freq->e = 6; return 0; default: -- GitLab From d4e50c5917e110451ced8f8de594cea858791f37 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:07 +0200 Subject: [PATCH 3250/6849] cfg80211: add channel checking for iface combinations .connect cannot be handled since the driver scans and connects on its own. It is up to the driver then to refuse a connection (with -EBUSY for example). Non-fixed channel IBSSes always take a single channel resource. For example two non-fixed channel IBSSes always take up 2 num_different_channels, even if they operate on the same channel at a given point of time. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/core.c | 8 ++++++ net/wireless/core.h | 29 +++++++++++++++++++--- net/wireless/util.c | 59 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 580551e9caba..b26695ad3e97 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -373,6 +373,14 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) if (WARN_ON(!c->num_different_channels)) return -EINVAL; + /* + * Put a sane limit on maximum number of different + * channels to simplify channel accounting code. + */ + if (WARN_ON(c->num_different_channels > + CFG80211_MAX_NUM_DIFFERENT_CHANNELS)) + return -EINVAL; + if (WARN_ON(!c->n_limits)) return -EINVAL; diff --git a/net/wireless/core.h b/net/wireless/core.h index d5efe1b0a8f7..81fef3ddb5a8 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -428,9 +428,20 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, u32 *flags, struct vif_params *params); void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); -int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - enum nl80211_iftype iftype); +int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype, + struct ieee80211_channel *chan, + enum cfg80211_chan_mode chanmode); + +static inline int +cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype) +{ + return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL, + CHAN_MODE_UNDEFINED); +} static inline int cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, @@ -439,6 +450,16 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, return cfg80211_can_change_interface(rdev, NULL, iftype); } +static inline int +cfg80211_can_use_chan(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + struct ieee80211_channel *chan, + enum cfg80211_chan_mode chanmode) +{ + return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, + chan, chanmode); +} + void cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, @@ -461,6 +482,8 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num); +#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 + #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) #else diff --git a/net/wireless/util.c b/net/wireless/util.c index 9b92ec57d07b..4713cea9a2fa 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -938,13 +938,20 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, return res; } -int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - enum nl80211_iftype iftype) +int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype, + struct ieee80211_channel *chan, + enum cfg80211_chan_mode chanmode) { struct wireless_dev *wdev_iter; u32 used_iftypes = BIT(iftype); int num[NUM_NL80211_IFTYPES]; + struct ieee80211_channel + *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; + struct ieee80211_channel *ch; + enum cfg80211_chan_mode chmode; + int num_different_channels = 0; int total = 1; int i, j; @@ -955,9 +962,23 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, return 0; memset(num, 0, sizeof(num)); + memset(used_channels, 0, sizeof(used_channels)); num[iftype] = 1; + switch (chanmode) { + case CHAN_MODE_UNDEFINED: + break; + case CHAN_MODE_SHARED: + WARN_ON(!chan); + used_channels[0] = chan; + num_different_channels++; + break; + case CHAN_MODE_EXCLUSIVE: + num_different_channels++; + break; + } + mutex_lock(&rdev->devlist_mtx); list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { if (wdev_iter == wdev) @@ -968,6 +989,31 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) continue; + cfg80211_get_chan_state(rdev, wdev_iter, &ch, &chmode); + + switch (chmode) { + case CHAN_MODE_UNDEFINED: + break; + case CHAN_MODE_SHARED: + for (i = 0; i < CFG80211_MAX_NUM_DIFFERENT_CHANNELS; i++) + if (!used_channels[i] || used_channels[i] == ch) + break; + + if (i == CFG80211_MAX_NUM_DIFFERENT_CHANNELS) { + mutex_unlock(&rdev->devlist_mtx); + return -EBUSY; + } + + if (used_channels[i] == NULL) { + used_channels[i] = ch; + num_different_channels++; + } + break; + case CHAN_MODE_EXCLUSIVE: + num_different_channels++; + break; + } + num[wdev_iter->iftype]++; total++; used_iftypes |= BIT(wdev_iter->iftype); @@ -984,12 +1030,15 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, c = &rdev->wiphy.iface_combinations[i]; + if (total > c->max_interfaces) + continue; + if (num_different_channels > c->num_different_channels) + continue; + limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, GFP_KERNEL); if (!limits) return -ENOMEM; - if (total > c->max_interfaces) - goto cont; for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { if (rdev->wiphy.software_iftypes & BIT(iftype)) -- GitLab From e4e32459c2daea59516da59999706b357e6eb480 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 29 Jun 2012 12:47:08 +0200 Subject: [PATCH 3251/6849] cfg80211: respect iface combinations when starting operation devlist_mtx locking is changed to accomodate changes. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/core.c | 2 ++ net/wireless/ibss.c | 10 ++++++++++ net/wireless/mesh.c | 12 ++++++++++++ net/wireless/mlme.c | 16 ++++++++++++++++ net/wireless/nl80211.c | 8 ++++++++ net/wireless/util.c | 9 ++++----- 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index b26695ad3e97..ca2b95f24846 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -990,7 +990,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, return notifier_from_errno(-EOPNOTSUPP); if (rfkill_blocked(rdev->rfkill)) return notifier_from_errno(-ERFKILL); + mutex_lock(&rdev->devlist_mtx); ret = cfg80211_can_add_interface(rdev, wdev->iftype); + mutex_unlock(&rdev->devlist_mtx); if (ret) return notifier_from_errno(ret); cfg80211_lock_rdev(rdev); diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index b90fd86b2d18..ca5672f6ee2f 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -118,6 +118,16 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, wdev->wext.ibss.channel = params->channel; #endif wdev->sme_state = CFG80211_SME_CONNECTING; + + err = cfg80211_can_use_chan(rdev, wdev, params->channel, + params->channel_fixed + ? CHAN_MODE_SHARED + : CHAN_MODE_EXCLUSIVE); + if (err) { + wdev->connect_keys = NULL; + return err; + } + err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); if (err) { wdev->connect_keys = NULL; diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index bab381344723..c384e77ff77a 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -155,6 +155,11 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, setup->channel_type)) return -EINVAL; + err = cfg80211_can_use_chan(rdev, wdev, setup->channel, + CHAN_MODE_SHARED); + if (err) + return err; + err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); if (!err) { memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); @@ -173,9 +178,11 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev = dev->ieee80211_ptr; int err; + mutex_lock(&rdev->devlist_mtx); wdev_lock(wdev); err = __cfg80211_join_mesh(rdev, dev, setup, conf); wdev_unlock(wdev); + mutex_unlock(&rdev->devlist_mtx); return err; } @@ -208,6 +215,11 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, if (!netif_running(wdev->netdev)) return -ENETDOWN; + err = cfg80211_can_use_chan(rdev, wdev, channel, + CHAN_MODE_SHARED); + if (err) + return err; + err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, wdev->netdev, channel); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index a7882eb8c46e..d4fece3bb18a 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -302,8 +302,14 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, if (!req.bss) return -ENOENT; + err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel, + CHAN_MODE_SHARED); + if (err) + goto out; + err = rdev->ops->auth(&rdev->wiphy, dev, &req); +out: cfg80211_put_bss(req.bss); return err; } @@ -317,11 +323,13 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, { int err; + mutex_lock(&rdev->devlist_mtx); wdev_lock(dev->ieee80211_ptr); err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, ssid, ssid_len, ie, ie_len, key, key_len, key_idx); wdev_unlock(dev->ieee80211_ptr); + mutex_unlock(&rdev->devlist_mtx); return err; } @@ -397,8 +405,14 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, return -ENOENT; } + err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel, + CHAN_MODE_SHARED); + if (err) + goto out; + err = rdev->ops->assoc(&rdev->wiphy, dev, &req); +out: if (err) { if (was_connected) wdev->sme_state = CFG80211_SME_CONNECTED; @@ -421,11 +435,13 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev = dev->ieee80211_ptr; int err; + mutex_lock(&rdev->devlist_mtx); wdev_lock(wdev); err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, ssid, ssid_len, ie, ie_len, use_mfp, crypt, assoc_flags, ht_capa, ht_capa_mask); wdev_unlock(wdev); + mutex_unlock(&rdev->devlist_mtx); return err; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5d29ed1f7c62..77102e66f1ea 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2478,6 +2478,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) params.channel_type)) return -EINVAL; + mutex_lock(&rdev->devlist_mtx); + err = cfg80211_can_use_chan(rdev, wdev, params.channel, + CHAN_MODE_SHARED); + mutex_unlock(&rdev->devlist_mtx); + + if (err) + return err; + err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); if (!err) { wdev->preset_chan = params.channel; diff --git a/net/wireless/util.c b/net/wireless/util.c index 4713cea9a2fa..a9260ac85cf1 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -805,8 +805,10 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, return -EBUSY; if (ntype != otype && netif_running(dev)) { + mutex_lock(&rdev->devlist_mtx); err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, ntype); + mutex_unlock(&rdev->devlist_mtx); if (err) return err; @@ -956,6 +958,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, int i, j; ASSERT_RTNL(); + lockdep_assert_held(&rdev->devlist_mtx); /* Always allow software iftypes */ if (rdev->wiphy.software_iftypes & BIT(iftype)) @@ -979,7 +982,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, break; } - mutex_lock(&rdev->devlist_mtx); list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { if (wdev_iter == wdev) continue; @@ -999,10 +1001,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, if (!used_channels[i] || used_channels[i] == ch) break; - if (i == CFG80211_MAX_NUM_DIFFERENT_CHANNELS) { - mutex_unlock(&rdev->devlist_mtx); + if (i == CFG80211_MAX_NUM_DIFFERENT_CHANNELS) return -EBUSY; - } if (used_channels[i] == NULL) { used_channels[i] = ch; @@ -1018,7 +1018,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, total++; used_iftypes |= BIT(wdev_iter->iftype); } - mutex_unlock(&rdev->devlist_mtx); if (total == 1) return 0; -- GitLab From d6f1c316346c95b0a280954d5afca29459921a24 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 28 Jun 2012 16:49:29 +0200 Subject: [PATCH 3252/6849] iwlwifi: add trailing newline to some messages Some messages were missing a trailing newline, add it. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index bac0eb0d046d..203d575e4493 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1141,7 +1141,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); if (ret < 0) IWL_ERR(trans, - "Failing on timeout while stopping DMA channel %d [0x%08x]", + "Failing on timeout while stopping DMA channel %d [0x%08x]\n", ch, iwl_read_direct32(trans, FH_TSSR_TX_STATUS_REG)); @@ -1149,7 +1149,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); if (!trans_pcie->txq) { - IWL_WARN(trans, "Stopping tx queues that aren't allocated..."); + IWL_WARN(trans, + "Stopping tx queues that aren't allocated...\n"); return 0; } @@ -1426,7 +1427,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) err = iwl_prepare_card_hw(trans); if (err) { - IWL_ERR(trans, "Error while preparing HW: %d", err); + IWL_ERR(trans, "Error while preparing HW: %d\n", err); goto err_free_irq; } @@ -2127,13 +2128,14 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, err = pci_request_regions(pdev, DRV_NAME); if (err) { - dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed"); + dev_printk(KERN_ERR, &pdev->dev, + "pci_request_regions failed\n"); goto out_pci_disable_device; } trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); if (!trans_pcie->hw_base) { - dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed"); + dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed\n"); err = -ENODEV; goto out_pci_release_regions; } @@ -2154,7 +2156,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, err = pci_enable_msi(pdev); if (err) dev_printk(KERN_ERR, &pdev->dev, - "pci_enable_msi failed(0X%x)", err); + "pci_enable_msi failed(0X%x)\n", err); trans->dev = &pdev->dev; trans_pcie->irq = pdev->irq; -- GitLab From 346c265a48169d73a69c88ce9d6b65e6bb3b1f20 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 28 Jun 2012 18:45:38 +0200 Subject: [PATCH 3253/6849] iwlwifi: fix debug message level Debug messages should be printed using dev_dbg() not dev_err() which requires DEBUG to be defined. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-debug.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 0f8fcd1d4fe2..87535a67de76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -61,6 +61,9 @@ * *****************************************************************************/ +#define DEBUG + +#include #include #include #include "iwl-debug.h" @@ -124,7 +127,7 @@ void __iwl_dbg(struct device *dev, #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_have_debug_level(level) && (!limit || net_ratelimit())) - dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', + dev_dbg(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', function, &vaf); #endif trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); -- GitLab From e0246e8ecad10b9437381b89756292ac031d4cfa Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 28 Jun 2012 09:45:14 -0700 Subject: [PATCH 3254/6849] ARM: OMAP2+: fix CONFIG_CPU_IDLE dependency on CONFIG_PM commit 164e0cbf60 (ARM: OMAP3/4: consolidate cpuidle Makefile) added an OMAP-specific dependency from CPU_IDLE to CONFIG_PM. This causes some randconfig warnings when CONFIG_PM has unmet dependencies: warning: (ARCH_OMAP3 && ARCH_OMAP4) selects PM which has unmet direct dependencies (PM_SLEEP || PM_RUNTIME) warning: (ARCH_OMAP3 && ARCH_OMAP4) selects PM which has unmet direct dependencies (PM_SLEEP || PM_RUNTIME) warning: (ARCH_OMAP3 && ARCH_OMAP4) selects PM which has unmet direct dependencies (PM_SLEEP || PM_RUNTIME) Fix this by making the dependency on CONFIG_PM_RUNTIME (which in turn will enable CONFIG_PM.) Reported-by: Tony Lindgren Cc: Daniel Lezcano Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index cf84588cd110..2f4ace6f91d1 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -35,7 +35,7 @@ config ARCH_OMAP3 select CPU_V7 select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARCH_HAS_OPP - select PM if CPU_IDLE + select PM_RUNTIME if CPU_IDLE select PM_OPP if PM select ARM_CPU_SUSPEND if PM select MULTI_IRQ_HANDLER @@ -53,7 +53,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP - select PM if CPU_IDLE + select PM_RUNTIME if CPU_IDLE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM -- GitLab From bb0adf6ca6c78758c12b054fe3f25023033072ab Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Thu, 28 Jun 2012 09:55:38 -0700 Subject: [PATCH 3255/6849] ARM: OMAP2+: do not allow SmartReflex to be built as a module Disable the module option for POWER_AVS since this is currently not supported. This patch fixes these error in the case POWER_AVS is set to 'm': arch/arm/mach-omap2/built-in.o: In function `sr_class3_configure': arch/arm/mach-omap2/smartreflex-class3.c:43: undefined reference to `sr_configure_errgen' arch/arm/mach-omap2/built-in.o: In function `sr_class3_disable': arch/arm/mach-omap2/smartreflex-class3.c:33: undefined reference to `sr_disable_errgen' arch/arm/mach-omap2/smartreflex-class3.c:35: undefined reference to `sr_disable' arch/arm/mach-omap2/built-in.o: In function `sr_class3_enable': arch/arm/mach-omap2/smartreflex-class3.c:28: undefined reference to `sr_enable' arch/arm/mach-omap2/built-in.o: In function `sr_class3_init': arch/arm/mach-omap2/smartreflex-class3.c:59: undefined reference to `sr_register_class' Reported-by: Tony Lindgren Signed-off-by: Jean Pihet Signed-off-by: Kevin Hilman [tony@atomide.com: updated to use relative paths for the build error] Signed-off-by: Tony Lindgren --- drivers/power/avs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig index 18493f7a8f6f..2a1008b61121 100644 --- a/drivers/power/avs/Kconfig +++ b/drivers/power/avs/Kconfig @@ -1,5 +1,5 @@ menuconfig POWER_AVS - tristate "Adaptive Voltage Scaling class support" + bool "Adaptive Voltage Scaling class support" help AVS is a power management technique which finely controls the operating voltage of a device in order to optimize (i.e. reduce) -- GitLab From ec02ac2b7e1ad04ab2486fe9b2fbfc3ad5178f7c Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:02 +0800 Subject: [PATCH 3256/6849] Input: atmel_mxt_ts - derive phys from i2c client adapter This allows userspace to more easily distinguish which bus a particular atmel_mxt_ts device is attached to. The resulting phys will be something like: i2c-1-0067/input0 Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 42e645062c20..b1108cae73ac 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -250,6 +250,7 @@ struct mxt_finger { struct mxt_data { struct i2c_client *client; struct input_dev *input_dev; + char phys[64]; /* device physical location */ const struct mxt_platform_data *pdata; struct mxt_object *object_table; struct mxt_info info; @@ -1106,6 +1107,10 @@ static int __devinit mxt_probe(struct i2c_client *client, } input_dev->name = "Atmel maXTouch Touchscreen"; + snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", + client->adapter->nr, client->addr); + input_dev->phys = data->phys; + input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; input_dev->open = mxt_input_open; -- GitLab From c2ef9a1a248bc597f3275e8d52e8ad68416d039f Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:03 +0800 Subject: [PATCH 3257/6849] Input: atmel_mxt_ts - use client name for irq The atmel_mxt_ts driver can support multiple devices simultaneously. Use the i2c_client name instead of the driver name when requesting an interrupt to make the different interrupts distinguishable in /proc/interrupts and top. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index b1108cae73ac..8b33f3ae4eba 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1154,7 +1154,7 @@ static int __devinit mxt_probe(struct i2c_client *client, goto err_free_object; error = request_threaded_irq(client->irq, NULL, mxt_interrupt, - pdata->irqflags, client->dev.driver->name, data); + pdata->irqflags, client->name, data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_free_object; -- GitLab From e1e1658d2eeb06e09f9855bdf6edb93474eca0c0 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:04 +0800 Subject: [PATCH 3258/6849] Input: atmel_mxt_ts - detect OOM when creating mt slots Hopefully this new code path will never be used, but better safe than sorry... Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 8b33f3ae4eba..926209cba77d 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1136,7 +1136,9 @@ static int __devinit mxt_probe(struct i2c_client *client, 0, 255, 0, 0); /* For multi touch */ - input_mt_init_slots(input_dev, MXT_MAX_FINGER); + error = input_mt_init_slots(input_dev, MXT_MAX_FINGER); + if (error) + goto err_free_mem; input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, -- GitLab From 639900380062ecd78ee8b265ea23929c565469b4 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:05 +0800 Subject: [PATCH 3259/6849] Input: atmel_mxt_ts - warn if sysfs could not be created If sysfs entry creation fails, the driver is still usable, so don't just abort probe. Just warn and continue. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 926209cba77d..c72f595a3203 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1172,13 +1172,10 @@ static int __devinit mxt_probe(struct i2c_client *client, error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); if (error) - goto err_unregister_device; + dev_warn(&client->dev, "error creating sysfs entries.\n"); return 0; -err_unregister_device: - input_unregister_device(input_dev); - input_dev = NULL; err_free_irq: free_irq(client->irq, data); err_free_object: -- GitLab From 55d6867fe659f4783e57db7b2ae0bb04e4ac816e Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:06 +0800 Subject: [PATCH 3260/6849] Input: atmel_mxt_ts - don't read T5 when dumping objects T5 is the message processor object. Reading it will only have two outcomes, neither of which is particularly useful: 1) the message count decrements, and a valid message will be lost 2) an invalid message will be read (reportid == 0xff) Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c72f595a3203..9f8dd973e5f5 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -263,7 +263,6 @@ struct mxt_data { static bool mxt_object_readable(unsigned int type) { switch (type) { - case MXT_GEN_MESSAGE_T5: case MXT_GEN_COMMAND_T6: case MXT_GEN_POWER_T7: case MXT_GEN_ACQUIRE_T8: -- GitLab From 9c67b789e051449d3914d683ba3604c5babc4dd9 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:07 +0800 Subject: [PATCH 3261/6849] Input: atmel_mxt_ts - use scnprintf for object sysfs entry Using scnprintf() is a cleaner way to ensure that we don't overwrite the PAGE_SIZE sysfs output buffer. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 9f8dd973e5f5..55855b8c2efd 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -904,17 +904,13 @@ static ssize_t mxt_object_show(struct device *dev, for (i = 0; i < data->info.object_num; i++) { object = data->object_table + i; - count += snprintf(buf + count, PAGE_SIZE - count, + count += scnprintf(buf + count, PAGE_SIZE - count, "Object[%d] (Type %d)\n", i + 1, object->type); - if (count >= PAGE_SIZE) - return PAGE_SIZE - 1; if (!mxt_object_readable(object->type)) { - count += snprintf(buf + count, PAGE_SIZE - count, + count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); - if (count >= PAGE_SIZE) - return PAGE_SIZE - 1; continue; } @@ -924,15 +920,11 @@ static ssize_t mxt_object_show(struct device *dev, if (error) return error; - count += snprintf(buf + count, PAGE_SIZE - count, + count += scnprintf(buf + count, PAGE_SIZE - count, "\t[%2d]: %02x (%d)\n", j, val, val); - if (count >= PAGE_SIZE) - return PAGE_SIZE - 1; } - count += snprintf(buf + count, PAGE_SIZE - count, "\n"); - if (count >= PAGE_SIZE) - return PAGE_SIZE - 1; + count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); } return count; -- GitLab From 43a91d51d3750dd9d5a6e5d14e9250a51f01f3c1 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:08 +0800 Subject: [PATCH 3262/6849] Input: atmel_mxt_ts - optimize reading objects in object sysfs entry Read each object in a single i2c transaction instead of byte-by-byte Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 35 ++++++++++-------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 55855b8c2efd..94dd1d156a98 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -479,20 +479,6 @@ static int mxt_read_message(struct mxt_data *data, sizeof(struct mxt_message), message); } -static int mxt_read_object(struct mxt_data *data, - u8 type, u8 offset, u8 *val) -{ - struct mxt_object *object; - u16 reg; - - object = mxt_get_object(data, type); - if (!object) - return -EINVAL; - - reg = object->start_address; - return __mxt_read_reg(data->client, reg + offset, 1, val); -} - static int mxt_write_object(struct mxt_data *data, u8 type, u8 offset, u8 val) { @@ -900,7 +886,14 @@ static ssize_t mxt_object_show(struct device *dev, int i, j; int error; u8 val; + u8 *obuf; + + /* Pre-allocate buffer large enough to hold max sized object. */ + obuf = kmalloc(256, GFP_KERNEL); + if (!obuf) + return -ENOMEM; + error = 0; for (i = 0; i < data->info.object_num; i++) { object = data->object_table + i; @@ -914,20 +907,22 @@ static ssize_t mxt_object_show(struct device *dev, continue; } + error = __mxt_read_reg(data->client, object->start_address, + object->size + 1, obuf); + if (error) + break; + for (j = 0; j < object->size + 1; j++) { - error = mxt_read_object(data, - object->type, j, &val); - if (error) - return error; + val = obuf[j]; count += scnprintf(buf + count, PAGE_SIZE - count, "\t[%2d]: %02x (%d)\n", j, val, val); } - count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); } - return count; + kfree(obuf); + return error ?: count; } static int mxt_load_fw(struct device *dev, const char *fn) -- GitLab From 91630955cb4c9899aa4521d1459837c66c5e9c7a Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:09 +0800 Subject: [PATCH 3263/6849] Input: atmel_mxt_ts - print less overhead when dumping objects Conserve limited (PAGE_SIZE) sysfs output buffer space by only showing readable objects and not printing the object's index, which is not useful to userspace. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 94dd1d156a98..c8cfd7b3dc9e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -897,15 +897,11 @@ static ssize_t mxt_object_show(struct device *dev, for (i = 0; i < data->info.object_num; i++) { object = data->object_table + i; - count += scnprintf(buf + count, PAGE_SIZE - count, - "Object[%d] (Type %d)\n", - i + 1, object->type); - - if (!mxt_object_readable(object->type)) { - count += scnprintf(buf + count, PAGE_SIZE - count, - "\n"); + if (!mxt_object_readable(object->type)) continue; - } + + count += scnprintf(buf + count, PAGE_SIZE - count, + "T%u:\n", object->type); error = __mxt_read_reg(data->client, object->start_address, object->size + 1, obuf); -- GitLab From 794eb67e76118108af5280ace2be8ae4983a6a81 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:10 +0800 Subject: [PATCH 3264/6849] Input: atmel_mxt_ts - print all instances when dumping objects For objects with multiple instances, dump them all, prepending each with its "Instance #". [rydberg@euromail.se: break out mxt_show_instance()] Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 36 +++++++++++++++++------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c8cfd7b3dc9e..ee37b0b0e0e4 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -877,6 +877,24 @@ static void mxt_calc_resolution(struct mxt_data *data) } } +static ssize_t mxt_show_instance(char *buf, int count, + struct mxt_object *object, int instance, + const u8 *val) +{ + int i; + + if (object->instances > 0) + count += scnprintf(buf + count, PAGE_SIZE - count, + "Instance %u\n", instance); + + for (i = 0; i < object->size + 1; i++) + count += scnprintf(buf + count, PAGE_SIZE - count, + "\t[%2u]: %02x (%d)\n", i, val[i], val[i]); + count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); + + return count; +} + static ssize_t mxt_object_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -885,7 +903,6 @@ static ssize_t mxt_object_show(struct device *dev, int count = 0; int i, j; int error; - u8 val; u8 *obuf; /* Pre-allocate buffer large enough to hold max sized object. */ @@ -903,20 +920,19 @@ static ssize_t mxt_object_show(struct device *dev, count += scnprintf(buf + count, PAGE_SIZE - count, "T%u:\n", object->type); - error = __mxt_read_reg(data->client, object->start_address, - object->size + 1, obuf); - if (error) - break; + for (j = 0; j < object->instances + 1; j++) { + u16 size = object->size + 1; + u16 addr = object->start_address + j * size; - for (j = 0; j < object->size + 1; j++) { - val = obuf[j]; + error = __mxt_read_reg(data->client, addr, size, obuf); + if (error) + goto done; - count += scnprintf(buf + count, PAGE_SIZE - count, - "\t[%2d]: %02x (%d)\n", j, val, val); + count = mxt_show_instance(buf, count, object, j, obuf); } - count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); } +done: kfree(obuf); return error ?: count; } -- GitLab From 771733e348e3df5b6283ab3b97d28577452bf09f Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:11 +0800 Subject: [PATCH 3265/6849] Input: atmel_mxt_ts - return errors from i2c layer The i2c layer can report a variety of errors, including -ENXIO for an i2c NAK. Instead of treating them all as -EIO, pass the actual i2c layer error up to the caller. However, still report as -EIO the unlikely case that a transaction was partially completed, and no error message was returned from i2c_*(). Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 28 +++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index ee37b0b0e0e4..a68b2279e8df 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -396,6 +396,7 @@ static int __mxt_read_reg(struct i2c_client *client, { struct i2c_msg xfer[2]; u8 buf[2]; + int ret; buf[0] = reg & 0xff; buf[1] = (reg >> 8) & 0xff; @@ -412,12 +413,17 @@ static int __mxt_read_reg(struct i2c_client *client, xfer[1].len = len; xfer[1].buf = val; - if (i2c_transfer(client->adapter, xfer, 2) != 2) { - dev_err(&client->dev, "%s: i2c transfer failed\n", __func__); - return -EIO; + ret = i2c_transfer(client->adapter, xfer, 2); + if (ret == 2) { + ret = 0; + } else { + if (ret >= 0) + ret = -EIO; + dev_err(&client->dev, "%s: i2c transfer failed (%d)\n", + __func__, ret); } - return 0; + return ret; } static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val) @@ -428,17 +434,23 @@ static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val) static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) { u8 buf[3]; + int ret; buf[0] = reg & 0xff; buf[1] = (reg >> 8) & 0xff; buf[2] = val; - if (i2c_master_send(client, buf, 3) != 3) { - dev_err(&client->dev, "%s: i2c send failed\n", __func__); - return -EIO; + ret = i2c_master_send(client, buf, 3); + if (ret == 3) { + ret = 0; + } else { + if (ret >= 0) + ret = -EIO; + dev_err(&client->dev, "%s: i2c send failed (%d)\n", + __func__, ret); } - return 0; + return ret; } static int mxt_read_object_table(struct i2c_client *client, -- GitLab From 9638ab7c9c3b352d54f4f7e80027bd6e1c0584e8 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:12 +0800 Subject: [PATCH 3266/6849] Input: atmel_mxt_ts - add variable length __mxt_write_reg The i2c bus requires 4 bytes to do a 1-byte write (1 byte i2c address + 2 byte offset + 1 byte data). By taking a length with writes, the driver can amortize transaction overhead by performing larger transactions where appropriate. This patch just sets up the new API. Later patches refactor writes to take advantage of the larger transactions. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index a68b2279e8df..dd2577b796a4 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -431,17 +431,24 @@ static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val) return __mxt_read_reg(client, reg, 1, val); } -static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) +static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, + const void *val) { - u8 buf[3]; + u8 *buf; + size_t count; int ret; + count = len + 2; + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + buf[0] = reg & 0xff; buf[1] = (reg >> 8) & 0xff; - buf[2] = val; + memcpy(&buf[2], val, len); - ret = i2c_master_send(client, buf, 3); - if (ret == 3) { + ret = i2c_master_send(client, buf, count); + if (ret == count) { ret = 0; } else { if (ret >= 0) @@ -450,9 +457,15 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) __func__, ret); } + kfree(buf); return ret; } +static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) +{ + return __mxt_write_reg(client, reg, 1, &val); +} + static int mxt_read_object_table(struct i2c_client *client, u16 reg, u8 *object_buf) { -- GitLab From cf94bc09c89c923d339c68cf89360c02578ceee3 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:13 +0800 Subject: [PATCH 3267/6849] Input: atmel_mxt_ts - optimize writing of object table entries Write each object using a single bulk i2c write transfer. Signed-off-by: Daniel Kurtz Reviewed-by: Joonyoung Shim Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index dd2577b796a4..99d5210c7ae8 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -655,7 +655,8 @@ static int mxt_check_reg_init(struct mxt_data *data) struct mxt_object *object; struct device *dev = &data->client->dev; int index = 0; - int i, j, config_offset; + int i, size; + int ret; if (!pdata->config) { dev_dbg(dev, "No cfg data defined, skipping reg init\n"); @@ -668,18 +669,17 @@ static int mxt_check_reg_init(struct mxt_data *data) if (!mxt_object_writable(object->type)) continue; - for (j = 0; - j < (object->size + 1) * (object->instances + 1); - j++) { - config_offset = index + j; - if (config_offset > pdata->config_length) { - dev_err(dev, "Not enough config data!\n"); - return -EINVAL; - } - mxt_write_object(data, object->type, j, - pdata->config[config_offset]); + size = (object->size + 1) * (object->instances + 1); + if (index + size > pdata->config_length) { + dev_err(dev, "Not enough config data!\n"); + return -EINVAL; } - index += (object->size + 1) * (object->instances + 1); + + ret = __mxt_write_reg(data->client, object->start_address, + size, &pdata->config[index]); + if (ret) + return ret; + index += size; } return 0; -- GitLab From 23003a8496b3f8100ed215dfda438cece5745545 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:14 +0800 Subject: [PATCH 3268/6849] Input: atmel_mxt_ts - read ID information block in one i2c transaction Reading the whole info block in one i2c transaction speeds up driver probe significantly, especially on slower i2c busses. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 26 +++--------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 99d5210c7ae8..fac379146546 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -36,6 +36,7 @@ #define MXT_FW_NAME "maxtouch.fw" /* Registers */ +#define MXT_INFO 0x00 #define MXT_FAMILY_ID 0x00 #define MXT_VARIANT_ID 0x01 #define MXT_VERSION 0x02 @@ -760,32 +761,11 @@ static int mxt_get_info(struct mxt_data *data) struct i2c_client *client = data->client; struct mxt_info *info = &data->info; int error; - u8 val; - - error = mxt_read_reg(client, MXT_FAMILY_ID, &val); - if (error) - return error; - info->family_id = val; - - error = mxt_read_reg(client, MXT_VARIANT_ID, &val); - if (error) - return error; - info->variant_id = val; - - error = mxt_read_reg(client, MXT_VERSION, &val); - if (error) - return error; - info->version = val; - - error = mxt_read_reg(client, MXT_BUILD, &val); - if (error) - return error; - info->build = val; - error = mxt_read_reg(client, MXT_OBJECT_NUM, &val); + /* Read 7-byte info block starting at address 0 */ + error = __mxt_read_reg(client, MXT_INFO, sizeof(*info), info); if (error) return error; - info->object_num = val; return 0; } -- GitLab From e0e0269f347ce89251ecf02ec4a209136bda258e Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:15 +0800 Subject: [PATCH 3269/6849] Input: atmel_mxt_ts - update driver ID info logging Print unsigned values as '%u'. Also, parse and print the firmware version in its canonical format, as suggested by Nick Dyer. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index fac379146546..7a839d106336 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -856,12 +856,12 @@ static int mxt_initialize(struct mxt_data *data) info->matrix_ysize = val; dev_info(&client->dev, - "Family ID: %d Variant ID: %d Version: %d Build: %d\n", - info->family_id, info->variant_id, info->version, - info->build); + "Family ID: %u Variant ID: %u Major.Minor.Build: %u.%u.%02X\n", + info->family_id, info->variant_id, info->version >> 4, + info->version & 0xf, info->build); dev_info(&client->dev, - "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n", + "Matrix X Size: %u Matrix Y Size: %u Object Num: %u\n", info->matrix_xsize, info->matrix_ysize, info->object_num); -- GitLab From b19fc9ec241382c2155bf56f08f02066f2fb4826 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:16 +0800 Subject: [PATCH 3270/6849] Input: atmel_mxt_ts - add sysfs entries to read fw and hw version Make firmware and hardware version strings available to userspace. This is useful, for example, to allow a userspace program to implement a firwmare update policy. Change-Id: I1eddb4bbf5f3f9ae6947a8528598973ddead18cf Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 7a839d106336..f2c1fbe2556e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -882,6 +882,26 @@ static void mxt_calc_resolution(struct mxt_data *data) } } +/* Firmware Version is returned as Major.Minor.Build */ +static ssize_t mxt_fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + struct mxt_info *info = &data->info; + return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", + info->version >> 4, info->version & 0xf, info->build); +} + +/* Hardware Version is returned as FamilyID.VariantID */ +static ssize_t mxt_hw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + struct mxt_info *info = &data->info; + return scnprintf(buf, PAGE_SIZE, "%u.%u\n", + info->family_id, info->variant_id); +} + static ssize_t mxt_show_instance(char *buf, int count, struct mxt_object *object, int instance, const u8 *val) @@ -1047,10 +1067,14 @@ static ssize_t mxt_update_fw_store(struct device *dev, return count; } +static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL); +static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store); static struct attribute *mxt_attrs[] = { + &dev_attr_fw_version.attr, + &dev_attr_hw_version.attr, &dev_attr_object.attr, &dev_attr_update_fw.attr, NULL -- GitLab From fba5bc313c44acfb3561da69526cbc1a0029cdd8 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:17 +0800 Subject: [PATCH 3271/6849] Input: atmel_mxt_ts - simplify event reporting Instead of carrying around per-finger state in the driver instance, just report each finger as it arrives to the input layer, and let the input layer (evdev) hold the event state (which it does anyway). Note: this driver does not really do MT-B properly. Each input report (a group of input events followed by a SYN_REPORT) only contains data for a single contact. When multiple fingers are present on a device, each is properly reported in its own MT_SLOT. However, there is only ever one MT_SLOT per SYN_REPORT. This is fixed in a subsequent patch. This patch was tested with an mXT224E. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 89 ++++-------------------- 1 file changed, 13 insertions(+), 76 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index f2c1fbe2556e..c37584de49ca 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -239,14 +239,6 @@ struct mxt_message { u8 message[7]; }; -struct mxt_finger { - int status; - int x; - int y; - int area; - int pressure; -}; - /* Each client has this additional data */ struct mxt_data { struct i2c_client *client; @@ -255,7 +247,6 @@ struct mxt_data { const struct mxt_platform_data *pdata; struct mxt_object *object_table; struct mxt_info info; - struct mxt_finger finger[MXT_MAX_FINGER]; unsigned int irq; unsigned int max_x; unsigned int max_y; @@ -519,75 +510,17 @@ static int mxt_write_object(struct mxt_data *data, return mxt_write_reg(data->client, reg + offset, val); } -static void mxt_input_report(struct mxt_data *data, int single_id) -{ - struct mxt_finger *finger = data->finger; - struct input_dev *input_dev = data->input_dev; - int status = finger[single_id].status; - int finger_num = 0; - int id; - - for (id = 0; id < MXT_MAX_FINGER; id++) { - if (!finger[id].status) - continue; - - input_mt_slot(input_dev, id); - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, - finger[id].status != MXT_RELEASE); - - if (finger[id].status != MXT_RELEASE) { - finger_num++; - input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, - finger[id].area); - input_report_abs(input_dev, ABS_MT_POSITION_X, - finger[id].x); - input_report_abs(input_dev, ABS_MT_POSITION_Y, - finger[id].y); - input_report_abs(input_dev, ABS_MT_PRESSURE, - finger[id].pressure); - } else { - finger[id].status = 0; - } - } - - input_report_key(input_dev, BTN_TOUCH, finger_num > 0); - - if (status != MXT_RELEASE) { - input_report_abs(input_dev, ABS_X, finger[single_id].x); - input_report_abs(input_dev, ABS_Y, finger[single_id].y); - input_report_abs(input_dev, - ABS_PRESSURE, finger[single_id].pressure); - } - - input_sync(input_dev); -} - static void mxt_input_touchevent(struct mxt_data *data, struct mxt_message *message, int id) { - struct mxt_finger *finger = data->finger; struct device *dev = &data->client->dev; u8 status = message->message[0]; + struct input_dev *input_dev = data->input_dev; int x; int y; int area; int pressure; - /* Check the touch is present on the screen */ - if (!(status & MXT_DETECT)) { - if (status & MXT_RELEASE) { - dev_dbg(dev, "[%d] released\n", id); - - finger[id].status = MXT_RELEASE; - mxt_input_report(data, id); - } - return; - } - - /* Check only AMP detection */ - if (!(status & (MXT_PRESS | MXT_MOVE))) - return; - x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); y = (message->message[2] << 4) | ((message->message[3] & 0xf)); if (data->max_x < 1024) @@ -601,15 +534,19 @@ static void mxt_input_touchevent(struct mxt_data *data, dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, status & MXT_MOVE ? "moved" : "pressed", x, y, area); + input_mt_slot(input_dev, id); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, + status & MXT_DETECT); + + if (status & MXT_DETECT) { + input_report_abs(input_dev, ABS_MT_POSITION_X, x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, y); + input_report_abs(input_dev, ABS_MT_PRESSURE, pressure); + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); + } - finger[id].status = status & MXT_MOVE ? - MXT_MOVE : MXT_PRESS; - finger[id].x = x; - finger[id].y = y; - finger[id].area = area; - finger[id].pressure = pressure; - - mxt_input_report(data, id); + input_mt_report_pointer_emulation(input_dev, false); + input_sync(input_dev); } static irqreturn_t mxt_interrupt(int irq, void *dev_id) -- GitLab From b2e459b81b33ca17052de03b1315d8511d769507 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:18 +0800 Subject: [PATCH 3272/6849] Input: atmel_mxt_ts - add detail to touchevent debug message Update the debug message: * print inidividual status bits * print the pressure value * use '%u' for unsigned quantities Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c37584de49ca..d6b64a0fed45 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -195,6 +195,7 @@ #define MXT_BOOT_STATUS_MASK 0x3f /* Touch status */ +#define MXT_UNGRIP (1 << 0) #define MXT_SUPPRESS (1 << 1) #define MXT_AMP (1 << 2) #define MXT_VECTOR (1 << 3) @@ -531,9 +532,19 @@ static void mxt_input_touchevent(struct mxt_data *data, area = message->message[4]; pressure = message->message[5]; - dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, - status & MXT_MOVE ? "moved" : "pressed", - x, y, area); + dev_dbg(dev, + "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n", + id, + (status & MXT_DETECT) ? 'D' : '.', + (status & MXT_PRESS) ? 'P' : '.', + (status & MXT_RELEASE) ? 'R' : '.', + (status & MXT_MOVE) ? 'M' : '.', + (status & MXT_VECTOR) ? 'V' : '.', + (status & MXT_AMP) ? 'A' : '.', + (status & MXT_SUPPRESS) ? 'S' : '.', + (status & MXT_UNGRIP) ? 'U' : '.', + x, y, area, pressure); + input_mt_slot(input_dev, id); input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, status & MXT_DETECT); -- GitLab From 7d4fa100b0cc069b2d788e1d9fe086e9e057958e Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:19 +0800 Subject: [PATCH 3273/6849] Input: atmel_mxt_ts - refactor when and how object table is freed The Object Table is freed in three cases: 1) When the driver is being removed. 2) In the error path of mxt_initialize(). 3) Just after a firmware update, when a new object table is about to be read. For cases 2 & 3, the driver is not immediately unloaded, so this patch refactors these cases to use a common cleanup function. It also refactors the mxt_initialize error paths to ensure that this cleanup happens. Note: mxt_update_fw_store() does not handle errors during mxt_initialize(). A proposed fix for this is in a subsequent patchset. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index d6b64a0fed45..488e3e88c3fc 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -750,6 +750,12 @@ static int mxt_get_object_table(struct mxt_data *data) return 0; } +static void mxt_free_object_table(struct mxt_data *data) +{ + kfree(data->object_table); + data->object_table = NULL; +} + static int mxt_initialize(struct mxt_data *data) { struct i2c_client *client = data->client; @@ -772,12 +778,12 @@ static int mxt_initialize(struct mxt_data *data) /* Get object table information */ error = mxt_get_object_table(data); if (error) - return error; + goto err_free_object_table; /* Check register init values */ error = mxt_check_reg_init(data); if (error) - return error; + goto err_free_object_table; mxt_handle_pdata(data); @@ -795,12 +801,12 @@ static int mxt_initialize(struct mxt_data *data) /* Update matrix size at info struct */ error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val); if (error) - return error; + goto err_free_object_table; info->matrix_xsize = val; error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val); if (error) - return error; + goto err_free_object_table; info->matrix_ysize = val; dev_info(&client->dev, @@ -814,6 +820,10 @@ static int mxt_initialize(struct mxt_data *data) info->object_num); return 0; + +err_free_object_table: + mxt_free_object_table(data); + return error; } static void mxt_calc_resolution(struct mxt_data *data) @@ -1000,8 +1010,7 @@ static ssize_t mxt_update_fw_store(struct device *dev, /* Wait for reset */ msleep(MXT_FWRESET_TIME); - kfree(data->object_table); - data->object_table = NULL; + mxt_free_object_table(data); mxt_initialize(data); } @@ -1128,7 +1137,7 @@ static int __devinit mxt_probe(struct i2c_client *client, error = mxt_initialize(data); if (error) - goto err_free_object; + goto err_free_mem; error = request_threaded_irq(client->irq, NULL, mxt_interrupt, pdata->irqflags, client->name, data); -- GitLab From 333e5a9a99b8bba14f1a8631218d2d1e55fd58b1 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:20 +0800 Subject: [PATCH 3274/6849] Input: atmel_mxt_ts - cache T9 reportid range when reading object table Streamline interrupt processing by caching the T9 reportid range when first reading the object table. In the process, refactor reading the object descriptor table. First, since the object_table entries are now exactly the same layout in device memory and in the driver, allocate an appropriately sized array and fetch the entire table directly into it in a single i2c transaction. Since a 6 byte table object requires 10 bytes to read, doing this dramatically reduces overhead. Note: The cached T9 reportid's are initialized to 0, which is an invalid reportid. Thus, the checks in the interrupt handler will always fail for devices that do not support the T9 object. Therefore, after doing a firmware update, the old object table is destroyed and all cached object values are reset to 0, before reading the new object table, in case the new firmware does not have the old objects. This patch tested on an MXT224E. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 76 +++++++++++++----------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 488e3e88c3fc..48f3637aecaa 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -227,13 +227,10 @@ struct mxt_info { struct mxt_object { u8 type; u16 start_address; - u8 size; - u8 instances; + u8 size; /* Size of each instance - 1 */ + u8 instances; /* Number of instances - 1 */ u8 num_report_ids; - - /* to map object and message */ - u8 max_reportid; -}; +} __packed; struct mxt_message { u8 reportid; @@ -251,6 +248,10 @@ struct mxt_data { unsigned int irq; unsigned int max_x; unsigned int max_y; + + /* Cached parameters from object table */ + u8 T9_reportid_min; + u8 T9_reportid_max; }; static bool mxt_object_readable(unsigned int type) @@ -459,13 +460,6 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) return __mxt_write_reg(client, reg, 1, &val); } -static int mxt_read_object_table(struct i2c_client *client, - u16 reg, u8 *object_buf) -{ - return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE, - object_buf); -} - static struct mxt_object * mxt_get_object(struct mxt_data *data, u8 type) { @@ -564,7 +558,6 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) { struct mxt_data *data = dev_id; struct mxt_message message; - struct mxt_object *object; struct device *dev = &data->client->dev; int id; u8 reportid; @@ -579,13 +572,8 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) reportid = message.reportid; - /* whether reportid is thing of MXT_TOUCH_MULTI_T9 */ - object = mxt_get_object(data, MXT_TOUCH_MULTI_T9); - if (!object) - goto end; - - max_reportid = object->max_reportid; - min_reportid = max_reportid - object->num_report_ids + 1; + max_reportid = data->T9_reportid_max; + min_reportid = data->T9_reportid_min; id = reportid - min_reportid; if (reportid >= min_reportid && reportid <= max_reportid) @@ -720,30 +708,46 @@ static int mxt_get_info(struct mxt_data *data) static int mxt_get_object_table(struct mxt_data *data) { + struct i2c_client *client = data->client; + size_t table_size; int error; int i; - u16 reg; - u8 reportid = 0; - u8 buf[MXT_OBJECT_SIZE]; + u8 reportid; + + table_size = data->info.object_num * sizeof(struct mxt_object); + error = __mxt_read_reg(client, MXT_OBJECT_START, table_size, + data->object_table); + if (error) + return error; + /* Valid Report IDs start counting from 1 */ + reportid = 1; for (i = 0; i < data->info.object_num; i++) { struct mxt_object *object = data->object_table + i; + u8 min_id, max_id; - reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i; - error = mxt_read_object_table(data->client, reg, buf); - if (error) - return error; - - object->type = buf[0]; - object->start_address = (buf[2] << 8) | buf[1]; - object->size = buf[3]; - object->instances = buf[4]; - object->num_report_ids = buf[5]; + le16_to_cpus(&object->start_address); if (object->num_report_ids) { + min_id = reportid; reportid += object->num_report_ids * (object->instances + 1); - object->max_reportid = reportid; + max_id = reportid - 1; + } else { + min_id = 0; + max_id = 0; + } + + dev_dbg(&data->client->dev, + "Type %2d Start %3d Size %3d Instances %2d ReportIDs %3u : %3u\n", + object->type, object->start_address, object->size + 1, + object->instances + 1, min_id, max_id); + + switch (object->type) { + case MXT_TOUCH_MULTI_T9: + data->T9_reportid_min = min_id; + data->T9_reportid_max = max_id; + break; } } @@ -754,6 +758,8 @@ static void mxt_free_object_table(struct mxt_data *data) { kfree(data->object_table); data->object_table = NULL; + data->T9_reportid_min = 0; + data->T9_reportid_max = 0; } static int mxt_initialize(struct mxt_data *data) -- GitLab From 04a79181c40d3ad99885e7f799c799c153e93431 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:21 +0800 Subject: [PATCH 3275/6849] Input: atmel_mxt_ts - refactor reportid checking in mxt_interrupt This small refactor is in preparation for checking more report types in the mxt_interrupt message processing loop. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 48f3637aecaa..a9e0b541c638 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -554,6 +554,12 @@ static void mxt_input_touchevent(struct mxt_data *data, input_sync(input_dev); } +static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) +{ + u8 id = msg->reportid; + return (id >= data->T9_reportid_min && id <= data->T9_reportid_max); +} + static irqreturn_t mxt_interrupt(int irq, void *dev_id) { struct mxt_data *data = dev_id; @@ -561,8 +567,6 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) struct device *dev = &data->client->dev; int id; u8 reportid; - u8 max_reportid; - u8 min_reportid; do { if (mxt_read_message(data, &message)) { @@ -572,11 +576,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) reportid = message.reportid; - max_reportid = data->T9_reportid_max; - min_reportid = data->T9_reportid_min; - id = reportid - min_reportid; + id = reportid - data->T9_reportid_min; - if (reportid >= min_reportid && reportid <= max_reportid) + if (mxt_is_T9_message(data, &message)) mxt_input_touchevent(data, &message, id); else mxt_dump_message(dev, &message); -- GitLab From cb15911509164f052f103e85a935f513f82e6b54 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:22 +0800 Subject: [PATCH 3276/6849] Input: atmel_mxt_ts - use T9 reportid range to init number of mt slots Atmel mxt devices can report one finger for each T9 reportid. Therefore, this range can be used to report the max number of MT-B slots to userspace instead of assuming a fixed 10. Note that mxt_initialized() must complete early, since the input_dev properties now depend on values in the object table. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index a9e0b541c638..2746b0dc7f36 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -212,8 +212,6 @@ /* Touchscreen absolute values */ #define MXT_MAX_AREA 0xff -#define MXT_MAX_FINGER 10 - struct mxt_info { u8 family_id; u8 variant_id; @@ -1086,6 +1084,7 @@ static int __devinit mxt_probe(struct i2c_client *client, struct mxt_data *data; struct input_dev *input_dev; int error; + unsigned int num_mt_slots; if (!pdata) return -EINVAL; @@ -1115,6 +1114,10 @@ static int __devinit mxt_probe(struct i2c_client *client, mxt_calc_resolution(data); + error = mxt_initialize(data); + if (error) + goto err_free_mem; + __set_bit(EV_ABS, input_dev->evbit); __set_bit(EV_KEY, input_dev->evbit); __set_bit(BTN_TOUCH, input_dev->keybit); @@ -1128,9 +1131,10 @@ static int __devinit mxt_probe(struct i2c_client *client, 0, 255, 0, 0); /* For multi touch */ - error = input_mt_init_slots(input_dev, MXT_MAX_FINGER); + num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; + error = input_mt_init_slots(input_dev, num_mt_slots); if (error) - goto err_free_mem; + goto err_free_object; input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, @@ -1143,10 +1147,6 @@ static int __devinit mxt_probe(struct i2c_client *client, input_set_drvdata(input_dev, data); i2c_set_clientdata(client, data); - error = mxt_initialize(data); - if (error) - goto err_free_mem; - error = request_threaded_irq(client->irq, NULL, mxt_interrupt, pdata->irqflags, client->name, data); if (error) { -- GitLab From 64464ae8e1d64fc9f63d9686d5e40b56ffa77203 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:23 +0800 Subject: [PATCH 3277/6849] Input: atmel_mxt_ts - send all MT-B slots in one input report Each interrupt contains information for all contacts with changing properties. Process all of this information at once, and send it all in a a single input report (ie input events ending in EV_SYN/SYN_REPORT). This patch was tested using an MXT224E. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 2746b0dc7f36..4c9a06c7eae3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -547,9 +547,6 @@ static void mxt_input_touchevent(struct mxt_data *data, input_report_abs(input_dev, ABS_MT_PRESSURE, pressure); input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); } - - input_mt_report_pointer_emulation(input_dev, false); - input_sync(input_dev); } static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) @@ -565,6 +562,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) struct device *dev = &data->client->dev; int id; u8 reportid; + bool update_input = false; do { if (mxt_read_message(data, &message)) { @@ -576,12 +574,19 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) id = reportid - data->T9_reportid_min; - if (mxt_is_T9_message(data, &message)) + if (mxt_is_T9_message(data, &message)) { mxt_input_touchevent(data, &message, id); - else + update_input = true; + } else { mxt_dump_message(dev, &message); + } } while (reportid != 0xff); + if (update_input) { + input_mt_report_pointer_emulation(data->input_dev, false); + input_sync(data->input_dev); + } + end: return IRQ_HANDLED; } -- GitLab From fdf804210f297b7a114fa7a216c2ab65b0f693da Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 28 Jun 2012 21:08:24 +0800 Subject: [PATCH 3278/6849] Input: atmel_mxt_ts - parse T6 reports The normal messages sent after boot or NVRAM update are T6 reports, containing a status, and the config memory checksum. Parse them and dump a useful info message. This patch tested on an MXT224E. Signed-off-by: Daniel Kurtz Signed-off-by: Henrik Rydberg --- drivers/input/touchscreen/atmel_mxt_ts.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4c9a06c7eae3..37190ab1f817 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -248,6 +248,7 @@ struct mxt_data { unsigned int max_y; /* Cached parameters from object table */ + u8 T6_reportid; u8 T9_reportid_min; u8 T9_reportid_max; }; @@ -549,6 +550,11 @@ static void mxt_input_touchevent(struct mxt_data *data, } } +static unsigned mxt_extract_T6_csum(const u8 *csum) +{ + return csum[0] | (csum[1] << 8) | (csum[2] << 16); +} + static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) { u8 id = msg->reportid; @@ -559,8 +565,8 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) { struct mxt_data *data = dev_id; struct mxt_message message; + const u8 *payload = &message.message[0]; struct device *dev = &data->client->dev; - int id; u8 reportid; bool update_input = false; @@ -572,9 +578,13 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) reportid = message.reportid; - id = reportid - data->T9_reportid_min; - - if (mxt_is_T9_message(data, &message)) { + if (reportid == data->T6_reportid) { + u8 status = payload[0]; + unsigned csum = mxt_extract_T6_csum(&payload[1]); + dev_dbg(dev, "Status: %02x Config Checksum: %06x\n", + status, csum); + } else if (mxt_is_T9_message(data, &message)) { + int id = reportid - data->T9_reportid_min; mxt_input_touchevent(data, &message, id); update_input = true; } else { @@ -749,6 +759,9 @@ static int mxt_get_object_table(struct mxt_data *data) object->instances + 1, min_id, max_id); switch (object->type) { + case MXT_GEN_COMMAND_T6: + data->T6_reportid = min_id; + break; case MXT_TOUCH_MULTI_T9: data->T9_reportid_min = min_id; data->T9_reportid_max = max_id; @@ -763,8 +776,10 @@ static void mxt_free_object_table(struct mxt_data *data) { kfree(data->object_table); data->object_table = NULL; + data->T6_reportid = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; + } static int mxt_initialize(struct mxt_data *data) -- GitLab From c21b328ea8c7c71cd2daf50557db440bbaa7ef55 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2012 17:53:07 -0400 Subject: [PATCH 3279/6849] drm/radeon: fix VM page table setup on SI Cayman and trinity allow for variable sized VM page tables, but SI requires that all page tables be the same size. The current code assumes variablely sized VM page tables so SI may end up with part of each page table overlapping with other memory which could end up being interpreted by the VM hw as garbage. Change the code to better accomodate SI. Allocate enough space for at least 2 full page tables and always set last_pfn to max_pfn on SI so each VM is backed by a full page table. This limits us to only 2 VMs active at any given time on SI. This will be rectified and the code can be reunified once we move to two level page tables. Signed-off-by: Alex Deucher Reviewed-by: Jerome Glisse Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_gart.c | 13 +++++++++++-- drivers/gpu/drm/radeon/si.c | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 59d44937dd9f..84b648a7ddd8 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -289,8 +289,9 @@ int radeon_vm_manager_init(struct radeon_device *rdev) rdev->vm_manager.enabled = false; /* mark first vm as always in use, it's the system one */ + /* allocate enough for 2 full VM pts */ r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8, + rdev->vm_manager.max_pfn * 8 * 2, RADEON_GEM_DOMAIN_VRAM); if (r) { dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", @@ -633,7 +634,15 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) mutex_init(&vm->mutex); INIT_LIST_HEAD(&vm->list); INIT_LIST_HEAD(&vm->va); - vm->last_pfn = 0; + /* SI requires equal sized PTs for all VMs, so always set + * last_pfn to max_pfn. cayman allows variable sized + * pts so we can grow then as needed. Once we switch + * to two level pts we can unify this again. + */ + if (rdev->family >= CHIP_TAHITI) + vm->last_pfn = rdev->vm_manager.max_pfn; + else + vm->last_pfn = 0; /* map the ib pool buffer at 0 in virtual address space, set * read only */ diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c7b61f16ecfd..0b0279291a73 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2365,12 +2365,12 @@ int si_pcie_gart_enable(struct radeon_device *rdev) WREG32(0x15DC, 0); /* empty context1-15 */ - /* FIXME start with 1G, once using 2 level pt switch to full + /* FIXME start with 4G, once using 2 level pt switch to full * vm size space */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, (1 << 30) / RADEON_GPU_PAGE_SIZE); + WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); for (i = 1; i < 16; i++) { if (i < 8) WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), -- GitLab From d660e9b92b44f113c3fc345a8ce66ffa56a3506f Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 29 Jun 2012 07:03:34 -0700 Subject: [PATCH 3280/6849] ARM: OMAP2+: PM: fix IRQ_NOAUTOEN removal by mis-merge commit 99b59df0 (ARM: OMAP3: PM: fix shared PRCM interrupt leave disabled at boot) added IRQ_NOAUTOEN to the PRCM interrupt so it could be enabled later if needed. However, this commit was partially undone when merging the IO daisy chain rework in 9a17d88e (Merge tag 'omap-devel-c-for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into devel-pm This patch adds back the IRQ_NOAUTOEN fix that was removed by the merge resolution. This also fixes the following boot-time warning that showed up after merging the IO daisy chain rework: [ 3.849334] WARNING: at kernel/irq/manage.c:436 enable_irq+0x3c/0x78() [ 3.856231] Unbalanced enable for IRQ 297 [ 3.860473] Modules linked in: [ 3.863739] [] (unwind_backtrace+0x0/0xf0) from [] (warn_slowpath_common+0x4c/0x64) [ 3.873687] [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x30/0x40) [ 3.883819] [] (warn_slowpath_fmt+0x30/0x40) from [] (enable_irq+0x3c/0x78) [ 3.893035] [] (enable_irq+0x3c/0x78) from [] (omap3_pm_init+0x328/0x5f4) [ 3.902099] [] (omap3_pm_init+0x328/0x5f4) from [] (init_machine_late+0x1c/0x28) [ 3.911773] [] (init_machine_late+0x1c/0x28) from [] (do_one_initcall+0x34/0x178) [ 3.921539] [] (do_one_initcall+0x34/0x178) from [] (kernel_init+0xfc/0x1c0) [ 3.930847] [] (kernel_init+0xfc/0x1c0) from [] (kernel_thread_exit+0x0/0x8) [ 3.940246] ---[ end trace 55a0ad32ca2ca682 ]--- Reported-by: Javier Martinez Canillas Cc: Paul Walmsley Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/prm2xxx_3xxx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index e10fd1e9446b..a0309dea6794 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -351,11 +351,16 @@ static void __init omap3xxx_prm_enable_io_wakeup(void) static int __init omap3xxx_prcm_init(void) { + int ret = 0; + if (cpu_is_omap34xx()) { omap3xxx_prm_enable_io_wakeup(); - return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + if (!ret) + irq_set_status_flags(omap_prcm_event_to_irq("io"), + IRQ_NOAUTOEN); } - return 0; + return ret; } subsys_initcall(omap3xxx_prcm_init); -- GitLab From de50ada55b6b83b54b817911ec42dc590e1c1738 Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Mon, 25 Jun 2012 16:13:02 +0800 Subject: [PATCH 3281/6849] [SCSI] add wrapper to access and set scsi_bus_type in struct acpi_bus_type For being able to bind ata devices against acpi devices, scsi_bus_type needs to be set as bus in struct acpi_bus_type. So add wrapper to scsi_lib to accomplish that. Signed-off-by: Holger Macht Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/scsi/scsi_lib.c | 17 +++++++++++++++++ include/scsi/scsi.h | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6dfb9785d345..08f1e297c735 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -68,6 +68,23 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = { struct kmem_cache *scsi_sdb_cache; +#ifdef CONFIG_ACPI +#include + +int scsi_register_acpi_bus_type(struct acpi_bus_type *bus) +{ + bus->bus = &scsi_bus_type; + return register_acpi_bus_type(bus); +} +EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type); + +void scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus) +{ + unregister_acpi_bus_type(bus); +} +EXPORT_SYMBOL_GPL(scsi_unregister_acpi_bus_type); +#endif + /* * When to reinvoke queueing after a resource shortage. It's 3 msecs to * not change behaviour from the previous unplug mechanism, experimentation diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index f34a5a87af38..4527b3a13321 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -214,6 +214,16 @@ scsi_command_size(const unsigned char *cmnd) scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]); } +#ifdef CONFIG_ACPI +struct acpi_bus_type; + +extern int +scsi_register_acpi_bus_type(struct acpi_bus_type *bus); + +extern void +scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus); +#endif + /* * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft * T10/1561-D Revision 4 Draft dated 7th November 2002. -- GitLab From 6b66d95895c149cbc04d4fac5a2f5477c543a8ae Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 25 Jun 2012 16:13:03 +0800 Subject: [PATCH 3282/6849] libata: bind the Linux device tree to the ACPI device tree Associate the ACPI device tree and libata devices. This patch uses the generic ACPI glue framework to do so. Signed-off-by: Matthew Garrett Signed-off-by: Holger Macht Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/acpi/glue.c | 4 +- drivers/ata/libata-acpi.c | 137 ++++++++++++++++++++++++++++++++++++++ drivers/ata/libata-core.c | 5 +- drivers/ata/libata.h | 6 ++ 4 files changed, 148 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 1564e0927c21..18d6812a699e 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -39,6 +39,7 @@ int register_acpi_bus_type(struct acpi_bus_type *type) } return -ENODEV; } +EXPORT_SYMBOL(register_acpi_bus_type); int unregister_acpi_bus_type(struct acpi_bus_type *type) { @@ -54,6 +55,7 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type) } return -ENODEV; } +EXPORT_SYMBOL(unregister_acpi_bus_type); static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) { @@ -69,7 +71,6 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) up_read(&bus_type_sem); return ret; } -EXPORT_SYMBOL_GPL(register_acpi_bus_type); static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) { @@ -86,7 +87,6 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) up_read(&bus_type_sem); return ret; } -EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); /* Get device's handler per its address under its parent */ struct acpi_find_child { diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index bb7c5f1085cc..b3025a7d71e3 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -47,6 +47,39 @@ static void ata_acpi_clear_gtf(struct ata_device *dev) dev->gtf_cache = NULL; } +static acpi_handle ap_acpi_handle(struct ata_port *ap) +{ + if (ap->flags & ATA_FLAG_ACPI_SATA) + return NULL; + + /* + * If acpi bind operation has already happened, we can get the handle + * for the port by checking the corresponding scsi_host device's + * firmware node, otherwise we will need to find out the handle from + * its parent's acpi node. + */ + if (ap->scsi_host) + return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev); + else + return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), + ap->port_no); +} + +static acpi_handle dev_acpi_handle(struct ata_device *dev) +{ + acpi_integer adr; + struct ata_port *ap = dev->link->ap; + + if (ap->flags & ATA_FLAG_ACPI_SATA) { + if (!sata_pmp_attached(ap)) + adr = SATA_ADR(ap->port_no, NO_PORT_MULT); + else + adr = SATA_ADR(ap->port_no, dev->link->pmp); + return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr); + } else + return acpi_get_child(ap_acpi_handle(ap), dev->devno); +} + /** * ata_acpi_associate_sata_port - associate SATA port with ACPI objects * @ap: target SATA port @@ -1018,3 +1051,107 @@ void ata_acpi_on_disable(struct ata_device *dev) { ata_acpi_clear_gtf(dev); } + +static int compat_pci_ata(struct ata_port *ap) +{ + struct device *dev = ap->tdev.parent; + struct pci_dev *pdev; + + if (!is_pci_dev(dev)) + return 0; + + pdev = to_pci_dev(dev); + + if ((pdev->class >> 8) != PCI_CLASS_STORAGE_SATA && + (pdev->class >> 8) != PCI_CLASS_STORAGE_IDE) + return 0; + + return 1; +} + +static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle) +{ + if (ap->flags & ATA_FLAG_ACPI_SATA) + return -ENODEV; + + *handle = acpi_get_child(DEVICE_ACPI_HANDLE(ap->tdev.parent), + ap->port_no); + + if (!*handle) + return -ENODEV; + + return 0; +} + +static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, + acpi_handle *handle) +{ + struct ata_device *ata_dev; + + if (ap->flags & ATA_FLAG_ACPI_SATA) + ata_dev = &ap->link.device[sdev->channel]; + else + ata_dev = &ap->link.device[sdev->id]; + + *handle = dev_acpi_handle(ata_dev); + + if (!*handle) + return -ENODEV; + + return 0; +} + +static int is_ata_port(const struct device *dev) +{ + return dev->type == &ata_port_type; +} + +static struct ata_port *dev_to_ata_port(struct device *dev) +{ + while (!is_ata_port(dev)) { + if (!dev->parent) + return NULL; + dev = dev->parent; + } + return to_ata_port(dev); +} + +static int ata_acpi_find_device(struct device *dev, acpi_handle *handle) +{ + struct ata_port *ap = dev_to_ata_port(dev); + + if (!ap) + return -ENODEV; + + if (!compat_pci_ata(ap)) + return -ENODEV; + + if (scsi_is_host_device(dev)) + return ata_acpi_bind_host(ap, handle); + else if (scsi_is_sdev_device(dev)) { + struct scsi_device *sdev = to_scsi_device(dev); + + return ata_acpi_bind_device(ap, sdev, handle); + } else + return -ENODEV; +} + +static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle) +{ + return -ENODEV; +} + +static struct acpi_bus_type ata_acpi_bus = { + .find_bridge = ata_acpi_find_dummy, + .find_device = ata_acpi_find_device, +}; + +int ata_acpi_register(void) +{ + return scsi_register_acpi_bus_type(&ata_acpi_bus); +} + +void ata_acpi_unregister(void) +{ + scsi_unregister_acpi_bus_type(&ata_acpi_bus); +} diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index cece3a4d11ea..bd33b4a7ac13 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5288,8 +5288,6 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, return rc; } -#define to_ata_port(d) container_of(d, struct ata_port, tdev) - static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) { struct ata_port *ap = to_ata_port(dev); @@ -6513,6 +6511,8 @@ static int __init ata_init(void) ata_parse_force_param(); + ata_acpi_register(); + rc = ata_sff_init(); if (rc) { kfree(ata_force_tbl); @@ -6539,6 +6539,7 @@ static void __exit ata_exit(void) ata_release_transport(ata_scsi_transport_template); libata_transport_exit(); ata_sff_exit(); + ata_acpi_unregister(); kfree(ata_force_tbl); } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 9d0fd0b71852..7f48b602b01b 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -107,6 +107,8 @@ extern const char *sata_spd_string(unsigned int spd); extern int ata_port_probe(struct ata_port *ap); extern void __ata_port_probe(struct ata_port *ap); +#define to_ata_port(d) container_of(d, struct ata_port, tdev) + /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; @@ -119,6 +121,8 @@ extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *dev); extern void ata_acpi_on_disable(struct ata_device *dev); extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); +extern int ata_acpi_register(void); +extern void ata_acpi_unregister(void); #else static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } static inline void ata_acpi_associate(struct ata_host *host) { } @@ -129,6 +133,8 @@ static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; } static inline void ata_acpi_on_disable(struct ata_device *dev) { } static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } +static inline int ata_acpi_register(void) { return 0; } +static void ata_acpi_unregister(void) { } #endif /* libata-scsi.c */ -- GitLab From 30dcf76acc695cbd2fa919e294670fe9552e16e7 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 25 Jun 2012 16:13:04 +0800 Subject: [PATCH 3283/6849] libata: migrate ACPI code over to new bindings Now that we have the ability to directly glue the ACPI namespace to the driver model in libata, we don't need the custom code to handle the same thing. Remove it and migrate the functions over to the new code. Signed-off-by: Matthew Garrett Signed-off-by: Holger Macht Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 161 +++++++++----------------------------- drivers/ata/libata-core.c | 3 - drivers/ata/libata-pmp.c | 4 - drivers/ata/libata.h | 5 -- drivers/ata/pata_acpi.c | 4 +- include/linux/libata.h | 7 +- 6 files changed, 40 insertions(+), 144 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index b3025a7d71e3..c6f0101fd253 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -47,7 +47,14 @@ static void ata_acpi_clear_gtf(struct ata_device *dev) dev->gtf_cache = NULL; } -static acpi_handle ap_acpi_handle(struct ata_port *ap) +/** + * ata_ap_acpi_handle - provide the acpi_handle for an ata_port + * @ap: the acpi_handle returned will correspond to this port + * + * Returns the acpi_handle for the ACPI namespace object corresponding to + * the ata_port passed into the function, or NULL if no such object exists + */ +acpi_handle ata_ap_acpi_handle(struct ata_port *ap) { if (ap->flags & ATA_FLAG_ACPI_SATA) return NULL; @@ -64,8 +71,16 @@ static acpi_handle ap_acpi_handle(struct ata_port *ap) return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no); } +EXPORT_SYMBOL(ata_ap_acpi_handle); -static acpi_handle dev_acpi_handle(struct ata_device *dev) +/** + * ata_dev_acpi_handle - provide the acpi_handle for an ata_device + * @dev: the acpi_device returned will correspond to this port + * + * Returns the acpi_handle for the ACPI namespace object corresponding to + * the ata_device passed into the function, or NULL if no such object exists + */ +acpi_handle ata_dev_acpi_handle(struct ata_device *dev) { acpi_integer adr; struct ata_port *ap = dev->link->ap; @@ -77,66 +92,9 @@ static acpi_handle dev_acpi_handle(struct ata_device *dev) adr = SATA_ADR(ap->port_no, dev->link->pmp); return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr); } else - return acpi_get_child(ap_acpi_handle(ap), dev->devno); -} - -/** - * ata_acpi_associate_sata_port - associate SATA port with ACPI objects - * @ap: target SATA port - * - * Look up ACPI objects associated with @ap and initialize acpi_handle - * fields of @ap, the port and devices accordingly. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -void ata_acpi_associate_sata_port(struct ata_port *ap) -{ - WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA)); - - if (!sata_pmp_attached(ap)) { - u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT); - - ap->link.device->acpi_handle = - acpi_get_child(ap->host->acpi_handle, adr); - } else { - struct ata_link *link; - - ap->link.device->acpi_handle = NULL; - - ata_for_each_link(link, ap, EDGE) { - u64 adr = SATA_ADR(ap->port_no, link->pmp); - - link->device->acpi_handle = - acpi_get_child(ap->host->acpi_handle, adr); - } - } -} - -static void ata_acpi_associate_ide_port(struct ata_port *ap) -{ - int max_devices, i; - - ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no); - if (!ap->acpi_handle) - return; - - max_devices = 1; - if (ap->flags & ATA_FLAG_SLAVE_POSS) - max_devices++; - - for (i = 0; i < max_devices; i++) { - struct ata_device *dev = &ap->link.device[i]; - - dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); - } - - if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) - ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; + return acpi_get_child(ata_ap_acpi_handle(ap), dev->devno); } +EXPORT_SYMBOL(ata_dev_acpi_handle); /* @ap and @dev are the same as ata_acpi_handle_hotplug() */ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) @@ -261,56 +219,6 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = { .uevent = ata_acpi_ap_uevent, }; -/** - * ata_acpi_associate - associate ATA host with ACPI objects - * @host: target ATA host - * - * Look up ACPI objects associated with @host and initialize - * acpi_handle fields of @host, its ports and devices accordingly. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -void ata_acpi_associate(struct ata_host *host) -{ - int i, j; - - if (!is_pci_dev(host->dev) || libata_noacpi) - return; - - host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev); - if (!host->acpi_handle) - return; - - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - - if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA) - ata_acpi_associate_sata_port(ap); - else - ata_acpi_associate_ide_port(ap); - - if (ap->acpi_handle) { - /* we might be on a docking station */ - register_hotplug_dock_device(ap->acpi_handle, - &ata_acpi_ap_dock_ops, ap); - } - - for (j = 0; j < ata_link_max_devices(&ap->link); j++) { - struct ata_device *dev = &ap->link.device[j]; - - if (dev->acpi_handle) { - /* we might be on a docking station */ - register_hotplug_dock_device(dev->acpi_handle, - &ata_acpi_dev_dock_ops, dev); - } - } - } -} - /** * ata_acpi_dissociate - dissociate ATA host from ACPI objects * @host: target ATA host @@ -332,7 +240,7 @@ void ata_acpi_dissociate(struct ata_host *host) struct ata_port *ap = host->ports[i]; const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); - if (ap->acpi_handle && gtm) + if (ata_ap_acpi_handle(ap) && gtm) ata_acpi_stm(ap, gtm); } } @@ -357,7 +265,8 @@ int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm) acpi_status status; int rc = 0; - status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output); + status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_GTM", NULL, + &output); rc = -ENOENT; if (status == AE_NOT_FOUND) @@ -427,7 +336,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm) input.count = 3; input.pointer = in_params; - status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL); + status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_STM", &input, + NULL); if (status == AE_NOT_FOUND) return -ENOENT; @@ -484,7 +394,8 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) __func__, ap->port_no); /* _GTF has no input parameters */ - status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); + status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_GTF", NULL, + &output); out_obj = dev->gtf_cache = output.pointer; if (ACPI_FAILURE(status)) { @@ -850,7 +761,8 @@ static int ata_acpi_push_id(struct ata_device *dev) /* It's OK for _SDD to be missing too. */ swap_buf_le16(dev->id, ATA_ID_WORDS); - status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL); + status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_SDD", &input, + NULL); swap_buf_le16(dev->id, ATA_ID_WORDS); if (status == AE_NOT_FOUND) @@ -900,7 +812,7 @@ void ata_acpi_on_resume(struct ata_port *ap) const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); struct ata_device *dev; - if (ap->acpi_handle && gtm) { + if (ata_ap_acpi_handle(ap) && gtm) { /* _GTM valid */ /* restore timing parameters */ @@ -941,22 +853,22 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { struct ata_device *dev; - if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) + if (!ata_ap_acpi_handle(ap) || (ap->flags & ATA_FLAG_ACPI_SATA)) return; /* channel first and then drives for power on and vica versa for power off */ if (state.event == PM_EVENT_ON) - acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); + acpi_bus_set_power(ata_ap_acpi_handle(ap), ACPI_STATE_D0); ata_for_each_dev(dev, &ap->link, ENABLED) { - if (dev->acpi_handle) - acpi_bus_set_power(dev->acpi_handle, + if (ata_dev_acpi_handle(dev)) + acpi_bus_set_power(ata_dev_acpi_handle(dev), state.event == PM_EVENT_ON ? ACPI_STATE_D0 : ACPI_STATE_D3); } if (state.event != PM_EVENT_ON) - acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); + acpi_bus_set_power(ata_ap_acpi_handle(ap), ACPI_STATE_D3); } /** @@ -981,7 +893,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev) int nr_executed = 0; int rc; - if (!dev->acpi_handle) + if (!ata_dev_acpi_handle(dev)) return 0; /* do we need to do _GTF? */ @@ -1027,7 +939,6 @@ int ata_acpi_on_devcfg(struct ata_device *dev) } ata_dev_warn(dev, "ACPI: failed the second time, disabled\n"); - dev->acpi_handle = NULL; /* We can safely continue if no _GTF command has been executed * and port is not frozen. @@ -1093,7 +1004,7 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, else ata_dev = &ap->link.device[sdev->id]; - *handle = dev_acpi_handle(ata_dev); + *handle = ata_dev_acpi_handle(ata_dev); if (!*handle) return -ENODEV; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index bd33b4a7ac13..7705191b5a81 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6049,9 +6049,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) if (rc) goto err_tadd; - /* associate with ACPI nodes */ - ata_acpi_associate(host); - /* set cable, sata_spd_limit and report */ for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 21b80c555c60..61c59ee45ce9 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -529,8 +529,6 @@ int sata_pmp_attach(struct ata_device *dev) ata_for_each_link(tlink, ap, EDGE) sata_link_init_spd(tlink); - ata_acpi_associate_sata_port(ap); - return 0; fail: @@ -570,8 +568,6 @@ static void sata_pmp_detach(struct ata_device *dev) ap->nr_pmp_links = 0; link->pmp = 0; spin_unlock_irqrestore(ap->lock, flags); - - ata_acpi_associate_sata_port(ap); } /** diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 7f48b602b01b..b0d5294982eb 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -112,9 +112,6 @@ extern void __ata_port_probe(struct ata_port *ap); /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; - -extern void ata_acpi_associate_sata_port(struct ata_port *ap); -extern void ata_acpi_associate(struct ata_host *host); extern void ata_acpi_dissociate(struct ata_host *host); extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); @@ -124,8 +121,6 @@ extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); extern int ata_acpi_register(void); extern void ata_acpi_unregister(void); #else -static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } -static inline void ata_acpi_associate(struct ata_host *host) { } static inline void ata_acpi_dissociate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 54145edf50e8..b63ca3b54fb9 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -39,7 +39,7 @@ static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline) { struct ata_port *ap = link->ap; struct pata_acpi *acpi = ap->private_data; - if (ap->acpi_handle == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0) + if (ata_ap_acpi_handle(ap) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0) return -ENODEV; return ata_sff_prereset(link, deadline); @@ -195,7 +195,7 @@ static int pacpi_port_start(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pata_acpi *acpi; - if (ap->acpi_handle == NULL) + if (ata_ap_acpi_handle(ap) == NULL) return -ENODEV; acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL); diff --git a/include/linux/libata.h b/include/linux/libata.h index 6e887c742a27..888feef3cda4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -545,9 +545,6 @@ struct ata_host { struct mutex eh_mutex; struct task_struct *eh_owner; -#ifdef CONFIG_ATA_ACPI - acpi_handle acpi_handle; -#endif struct ata_port *simplex_claimed; /* channel owning the DMA */ struct ata_port *ports[0]; }; @@ -615,7 +612,6 @@ struct ata_device { struct scsi_device *sdev; /* attached SCSI device */ void *private_data; #ifdef CONFIG_ATA_ACPI - acpi_handle acpi_handle; union acpi_object *gtf_cache; unsigned int gtf_filter; #endif @@ -797,7 +793,6 @@ struct ata_port { void *private_data; #ifdef CONFIG_ATA_ACPI - acpi_handle acpi_handle; struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ #endif /* owned by EH */ @@ -1114,6 +1109,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm); int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm); unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, const struct ata_acpi_gtm *gtm); +acpi_handle ata_ap_acpi_handle(struct ata_port *ap); +acpi_handle ata_dev_acpi_handle(struct ata_device *dev); int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm); #else static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) -- GitLab From febe53ba6b781862c12686c7ea1972bdedee457a Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Mon, 25 Jun 2012 16:13:05 +0800 Subject: [PATCH 3284/6849] libata-acpi: set acpi state for SATA port Currently, ata_acpi_set_state() only sets acpi sate for IDE port. Remove this limitation. Acked-by: Aaron Lu Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c6f0101fd253..bb20fd597eb1 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -852,23 +852,25 @@ void ata_acpi_on_resume(struct ata_port *ap) void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { struct ata_device *dev; - - if (!ata_ap_acpi_handle(ap) || (ap->flags & ATA_FLAG_ACPI_SATA)) - return; + acpi_handle handle; /* channel first and then drives for power on and vica versa for power off */ - if (state.event == PM_EVENT_ON) - acpi_bus_set_power(ata_ap_acpi_handle(ap), ACPI_STATE_D0); + handle = ata_ap_acpi_handle(ap); + if (handle && state.event == PM_EVENT_ON) + acpi_bus_set_power(handle, ACPI_STATE_D0); ata_for_each_dev(dev, &ap->link, ENABLED) { - if (ata_dev_acpi_handle(dev)) - acpi_bus_set_power(ata_dev_acpi_handle(dev), + handle = ata_dev_acpi_handle(dev); + if (handle) + acpi_bus_set_power(handle, state.event == PM_EVENT_ON ? ACPI_STATE_D0 : ACPI_STATE_D3); } - if (state.event != PM_EVENT_ON) - acpi_bus_set_power(ata_ap_acpi_handle(ap), ACPI_STATE_D3); + + handle = ata_ap_acpi_handle(ap); + if (handle && state.event != PM_EVENT_ON) + acpi_bus_set_power(handle, ACPI_STATE_D3); } /** -- GitLab From 3bd46600a7a7e938c54df8cdbac9910668c7dfb0 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Mon, 25 Jun 2012 16:13:06 +0800 Subject: [PATCH 3285/6849] libata-acpi: add ata port runtime D3Cold support ATA port may support runtime D3Cold state, for example, Zero-power ODD case. This patch adds wakeup notifier and enable/disable run_wake during supend/resume. Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/acpi/sleep.c | 2 + drivers/ata/libata-acpi.c | 78 +++++++++++++++++++++++++++++++++++++-- drivers/ata/libata-scsi.c | 3 ++ drivers/ata/libata.h | 4 ++ 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 88561029cca8..1784cb30e7cf 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -795,6 +795,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) *d_min_p = d_min; return d_max; } +EXPORT_SYMBOL(acpi_pm_device_sleep_state); #endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP @@ -831,6 +832,7 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) return 0; } +EXPORT_SYMBOL(acpi_pm_device_run_wake); /** * acpi_pm_device_sleep_wake - enable or disable the system wake-up diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index bb20fd597eb1..e01807a1ef31 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "libata.h" @@ -853,6 +854,7 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { struct ata_device *dev; acpi_handle handle; + int acpi_state; /* channel first and then drives for power on and vica versa for power off */ @@ -862,10 +864,23 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) ata_for_each_dev(dev, &ap->link, ENABLED) { handle = ata_dev_acpi_handle(dev); - if (handle) - acpi_bus_set_power(handle, - state.event == PM_EVENT_ON ? - ACPI_STATE_D0 : ACPI_STATE_D3); + if (!handle) + continue; + + if (state.event != PM_EVENT_ON) { + acpi_state = acpi_pm_device_sleep_state( + &dev->sdev->sdev_gendev, NULL); + if (acpi_state > 0) + acpi_bus_set_power(handle, acpi_state); + /* TBD: need to check if it's runtime pm request */ + acpi_pm_device_run_wake( + &dev->sdev->sdev_gendev, true); + } else { + /* Ditto */ + acpi_pm_device_run_wake( + &dev->sdev->sdev_gendev, false); + acpi_bus_set_power(handle, ACPI_STATE_D0); + } } handle = ata_ap_acpi_handle(ap); @@ -965,6 +980,61 @@ void ata_acpi_on_disable(struct ata_device *dev) ata_acpi_clear_gtf(dev); } +static void ata_acpi_wake_dev(acpi_handle handle, u32 event, void *context) +{ + struct ata_device *ata_dev = context; + + if (event == ACPI_NOTIFY_DEVICE_WAKE && ata_dev && + pm_runtime_suspended(&ata_dev->sdev->sdev_gendev)) + scsi_autopm_get_device(ata_dev->sdev); +} + +static void ata_acpi_add_pm_notifier(struct ata_device *dev) +{ + struct acpi_device *acpi_dev; + acpi_handle handle; + acpi_status status; + + handle = ata_dev_acpi_handle(dev); + if (!handle) + return; + + status = acpi_bus_get_device(handle, &acpi_dev); + if (ACPI_SUCCESS(status)) { + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + ata_acpi_wake_dev, dev); + device_set_run_wake(&dev->sdev->sdev_gendev, true); + } +} + +static void ata_acpi_remove_pm_notifier(struct ata_device *dev) +{ + struct acpi_device *acpi_dev; + acpi_handle handle; + acpi_status status; + + handle = ata_dev_acpi_handle(dev); + if (!handle) + return; + + status = acpi_bus_get_device(handle, &acpi_dev); + if (ACPI_SUCCESS(status)) { + device_set_run_wake(&dev->sdev->sdev_gendev, false); + acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + ata_acpi_wake_dev); + } +} + +void ata_acpi_bind(struct ata_device *dev) +{ + ata_acpi_add_pm_notifier(dev); +} + +void ata_acpi_unbind(struct ata_device *dev) +{ + ata_acpi_remove_pm_notifier(dev); +} + static int compat_pci_ata(struct ata_port *ap) { struct device *dev = ap->tdev.parent; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 22226350cd0c..8ec81ca8f659 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3445,6 +3445,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) if (!IS_ERR(sdev)) { dev->sdev = sdev; scsi_device_put(sdev); + ata_acpi_bind(dev); } else { dev->sdev = NULL; } @@ -3541,6 +3542,8 @@ static void ata_scsi_remove_dev(struct ata_device *dev) mutex_lock(&ap->scsi_host->scan_mutex); spin_lock_irqsave(ap->lock, flags); + ata_acpi_unbind(dev); + /* clearing dev->sdev is protected by host lock */ sdev = dev->sdev; dev->sdev = NULL; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index b0d5294982eb..44a7939b5bb6 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -120,6 +120,8 @@ extern void ata_acpi_on_disable(struct ata_device *dev); extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); extern int ata_acpi_register(void); extern void ata_acpi_unregister(void); +extern void ata_acpi_bind(struct ata_device *dev); +extern void ata_acpi_unbind(struct ata_device *dev); #else static inline void ata_acpi_dissociate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } @@ -130,6 +132,8 @@ static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } static inline int ata_acpi_register(void) { return 0; } static void ata_acpi_unregister(void) { } +static void ata_acpi_bind(struct ata_device *dev) { } +static void ata_acpi_unbind(struct ata_device *dev) { } #endif /* libata-scsi.c */ -- GitLab From a606dac368eed5696fb38e16b1394f1d049c09e9 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Mon, 25 Jun 2012 16:13:07 +0800 Subject: [PATCH 3286/6849] libata-acpi: register/unregister device to/from power resource Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/acpi/power.c | 2 ++ drivers/ata/libata-acpi.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index dd6d6a3c6780..eb6408741a8f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -390,6 +390,7 @@ void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handl __acpi_power_resource_unregister_device(dev, list->handles[i]); } +EXPORT_SYMBOL_GPL(acpi_power_resource_unregister_device); static int __acpi_power_resource_register_device( struct acpi_power_managed_device *powered_device, acpi_handle handle) @@ -460,6 +461,7 @@ no_power_resource: printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); return -ENODEV; } +EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); /** * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index e01807a1ef31..f36284e3290d 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1025,14 +1025,46 @@ static void ata_acpi_remove_pm_notifier(struct ata_device *dev) } } +static void ata_acpi_register_power_resource(struct ata_device *dev) +{ + struct scsi_device *sdev = dev->sdev; + acpi_handle handle; + struct device *device; + + handle = ata_dev_acpi_handle(dev); + if (!handle) + return; + + device = &sdev->sdev_gendev; + + acpi_power_resource_register_device(device, handle); +} + +static void ata_acpi_unregister_power_resource(struct ata_device *dev) +{ + struct scsi_device *sdev = dev->sdev; + acpi_handle handle; + struct device *device; + + handle = ata_dev_acpi_handle(dev); + if (!handle) + return; + + device = &sdev->sdev_gendev; + + acpi_power_resource_unregister_device(device, handle); +} + void ata_acpi_bind(struct ata_device *dev) { ata_acpi_add_pm_notifier(dev); + ata_acpi_register_power_resource(dev); } void ata_acpi_unbind(struct ata_device *dev) { ata_acpi_remove_pm_notifier(dev); + ata_acpi_unregister_power_resource(dev); } static int compat_pci_ata(struct ata_port *ap) -- GitLab From b1354cbb5bfce28f2e1ed28d77b362dfdfca638d Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Mon, 25 Jun 2012 16:13:08 +0800 Subject: [PATCH 3287/6849] libata: detect Device Attention support Add a new flag ATA_DFLAG_DA to indicate that device supports "Device Attention". Acked-by: Aaron Lu Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 3 +++ include/linux/ata.h | 1 + include/linux/libata.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7705191b5a81..c14f88c1f1da 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2374,6 +2374,9 @@ int ata_dev_configure(struct ata_device *dev) dma_dir_string = ", DMADIR"; } + if (ata_id_has_da(dev->id)) + dev->flags |= ATA_DFLAG_DA; + /* print device info to dmesg */ if (ata_msg_drv(ap) && print_info) ata_dev_info(dev, diff --git a/include/linux/ata.h b/include/linux/ata.h index 32df2b6ef0e0..5713d3ac381a 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -578,6 +578,7 @@ static inline int ata_is_data(u8 prot) ((u64) (id)[(n) + 0]) ) #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) +#define ata_id_has_da(id) ((id)[77] & (1 << 4)) static inline bool ata_id_has_hipm(const u16 *id) { diff --git a/include/linux/libata.h b/include/linux/libata.h index 888feef3cda4..cc22b943db83 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -161,6 +161,8 @@ enum { ATA_DFLAG_DETACH = (1 << 24), ATA_DFLAG_DETACHED = (1 << 25), + ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ + ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ ATA_DEV_ATA_UNSUP = 2, /* ATA device (unsupported) */ -- GitLab From 166a2967b45ede2e2e56f3ede3cd32053dc17812 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Mon, 25 Jun 2012 16:13:09 +0800 Subject: [PATCH 3288/6849] libata: tell scsi layer device supports runtime power off If ATA device supports "Device Attention", then tell scsi layer that the device supports runtime power off. Signed-off-by: Aaron Lu Signed-off-by: Lin Ming Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 28 ++++++++++++++++++++++++++-- include/scsi/scsi_device.h | 1 + 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index f36284e3290d..f1d6901de37d 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1000,7 +1000,10 @@ static void ata_acpi_add_pm_notifier(struct ata_device *dev) return; status = acpi_bus_get_device(handle, &acpi_dev); - if (ACPI_SUCCESS(status)) { + if (ACPI_FAILURE(status)) + return; + + if (dev->sdev->can_power_off) { acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, ata_acpi_wake_dev, dev); device_set_run_wake(&dev->sdev->sdev_gendev, true); @@ -1018,7 +1021,10 @@ static void ata_acpi_remove_pm_notifier(struct ata_device *dev) return; status = acpi_bus_get_device(handle, &acpi_dev); - if (ACPI_SUCCESS(status)) { + if (ACPI_FAILURE(status)) + return; + + if (dev->sdev->can_power_off) { device_set_run_wake(&dev->sdev->sdev_gendev, false); acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, ata_acpi_wake_dev); @@ -1102,6 +1108,9 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, acpi_handle *handle) { struct ata_device *ata_dev; + acpi_status status; + struct acpi_device *acpi_dev; + struct acpi_device_power_state *states; if (ap->flags & ATA_FLAG_ACPI_SATA) ata_dev = &ap->link.device[sdev->channel]; @@ -1113,6 +1122,21 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, if (!*handle) return -ENODEV; + status = acpi_bus_get_device(*handle, &acpi_dev); + if (ACPI_FAILURE(status)) + return 0; + + /* + * If firmware has _PS3 or _PR3 for this device, + * and this ata ODD device support device attention, + * it means this device can be powered off + */ + states = acpi_dev->power.states; + if ((states[ACPI_STATE_D3_HOT].flags.valid || + states[ACPI_STATE_D3_COLD].flags.explicit_set) && + ata_dev->flags & ATA_DFLAG_DA) + sdev->can_power_off = 1; + return 0; } diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index ba9698852321..aff7525de194 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -153,6 +153,7 @@ struct scsi_device { unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */ unsigned try_rc_10_first:1; /* Try READ_CAPACACITY_10 first */ unsigned is_visible:1; /* is the device visible in sysfs */ + unsigned can_power_off:1; /* Device supports runtime power off */ DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ struct list_head event_list; /* asserted events */ -- GitLab From 084681d14e429cb6192262ac7437f00e2c02f26a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 28 Jun 2012 09:38:53 +0200 Subject: [PATCH 3289/6849] printk: flush continuation lines immediately to console Continuation lines are buffered internally, intended to merge the chunked printk()s into a single record, and to isolate potentially racy continuation users from usual terminated line users. This though, has the effect that partial lines are not printed to the console in the moment they are emitted. In case the kernel crashes in the meantime, the potentially interesting printed information would never reach the consoles. Here we share the continuation buffer with the console copy logic, and partial lines are always immediately flushed to the available consoles. They are still buffered internally to improve the readability and integrity of the messages and minimize the amount of needed record headers to store. Signed-off-by: Kay Sievers Tested-by: Steven Rostedt Acked-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 244 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 176 insertions(+), 68 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index cdfba44fedf0..fbf4d0b22a1d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -193,12 +193,19 @@ static int console_may_schedule; * separated by ',', and find the message after the ';' character. */ +enum log_flags { + LOG_DEFAULT = 0, + LOG_NOCONS = 1, /* already flushed, do not print to console */ +}; + struct log { u64 ts_nsec; /* timestamp in nanoseconds */ u16 len; /* length of entire record */ u16 text_len; /* length of text buffer */ u16 dict_len; /* length of dictionary buffer */ - u16 level; /* syslog level + facility */ + u8 facility; /* syslog facility */ + u8 flags:5; /* internal record flags */ + u8 level:3; /* syslog level */ }; /* @@ -286,6 +293,7 @@ static u32 log_next(u32 idx) /* insert record into the buffer, discard old ones, update heads */ static void log_store(int facility, int level, + enum log_flags flags, u64 ts_nsec, const char *dict, u16 dict_len, const char *text, u16 text_len) { @@ -329,8 +337,13 @@ static void log_store(int facility, int level, msg->text_len = text_len; memcpy(log_dict(msg), dict, dict_len); msg->dict_len = dict_len; - msg->level = (facility << 3) | (level & 7); - msg->ts_nsec = local_clock(); + msg->facility = facility; + msg->level = level & 7; + msg->flags = flags & 0x1f; + if (ts_nsec > 0) + msg->ts_nsec = ts_nsec; + else + msg->ts_nsec = local_clock(); memset(log_dict(msg) + dict_len, 0, pad_len); msg->len = sizeof(struct log) + text_len + dict_len + pad_len; @@ -446,7 +459,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, ts_usec = msg->ts_nsec; do_div(ts_usec, 1000); len = sprintf(user->buf, "%u,%llu,%llu;", - msg->level, user->seq, ts_usec); + (msg->facility << 3) | msg->level, user->seq, ts_usec); /* escape non-printable characters */ for (i = 0; i < msg->text_len; i++) { @@ -787,6 +800,21 @@ static bool printk_time; #endif module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); +static size_t print_time(u64 ts, char *buf) +{ + unsigned long rem_nsec; + + if (!printk_time) + return 0; + + if (!buf) + return 15; + + rem_nsec = do_div(ts, 1000000000); + return sprintf(buf, "[%5lu.%06lu] ", + (unsigned long)ts, rem_nsec / 1000); +} + static size_t print_prefix(const struct log *msg, bool syslog, char *buf) { size_t len = 0; @@ -803,18 +831,7 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf) } } - if (printk_time) { - if (buf) { - unsigned long long ts = msg->ts_nsec; - unsigned long rem_nsec = do_div(ts, 1000000000); - - len += sprintf(buf + len, "[%5lu.%06lu] ", - (unsigned long) ts, rem_nsec / 1000); - } else { - len += 15; - } - } - + len += print_time(msg->ts_nsec, buf ? buf + len : NULL); return len; } @@ -1294,15 +1311,92 @@ static inline void printk_delay(void) } } +/* + * Continuation lines are buffered, and not committed to the record buffer + * until the line is complete, or a race forces it. The line fragments + * though, are printed immediately to the consoles to ensure everything has + * reached the console in case of a kernel crash. + */ +static struct cont { + char buf[LOG_LINE_MAX]; + size_t len; /* length == 0 means unused buffer */ + size_t cons; /* bytes written to console */ + struct task_struct *owner; /* task of first print*/ + u64 ts_nsec; /* time of first print */ + u8 level; /* log level of first message */ + u8 facility; /* log level of first message */ + bool flushed:1; /* buffer sealed and committed */ +} cont; + +static void cont_flush(void) +{ + if (cont.flushed) + return; + if (cont.len == 0) + return; + + log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec, + NULL, 0, cont.buf, cont.len); + + cont.flushed = true; +} + +static bool cont_add(int facility, int level, const char *text, size_t len) +{ + if (cont.len && cont.flushed) + return false; + + if (cont.len + len > sizeof(cont.buf)) { + cont_flush(); + return false; + } + + if (!cont.len) { + cont.facility = facility; + cont.level = level; + cont.owner = current; + cont.ts_nsec = local_clock(); + cont.cons = 0; + cont.flushed = false; + } + + memcpy(cont.buf + cont.len, text, len); + cont.len += len; + return true; +} + +static size_t cont_print_text(char *text, size_t size) +{ + size_t textlen = 0; + size_t len; + + if (cont.cons == 0) { + textlen += print_time(cont.ts_nsec, text); + size -= textlen; + } + + len = cont.len - cont.cons; + if (len > 0) { + if (len+1 > size) + len = size-1; + memcpy(text + textlen, cont.buf + cont.cons, len); + textlen += len; + cont.cons = cont.len; + } + + if (cont.flushed) { + text[textlen++] = '\n'; + /* got everything, release buffer */ + cont.len = 0; + } + return textlen; +} + asmlinkage int vprintk_emit(int facility, int level, const char *dict, size_t dictlen, const char *fmt, va_list args) { static int recursion_bug; - static char cont_buf[LOG_LINE_MAX]; - static size_t cont_len; - static int cont_level; - static struct task_struct *cont_task; static char textbuf[LOG_LINE_MAX]; char *text = textbuf; size_t text_len; @@ -1348,7 +1442,8 @@ asmlinkage int vprintk_emit(int facility, int level, recursion_bug = 0; printed_len += strlen(recursion_msg); /* emit KERN_CRIT message */ - log_store(0, 2, NULL, 0, recursion_msg, printed_len); + log_store(0, 2, LOG_DEFAULT, 0, + NULL, 0, recursion_msg, printed_len); } /* @@ -1386,55 +1481,38 @@ asmlinkage int vprintk_emit(int facility, int level, } if (!newline) { - if (cont_len && (prefix || cont_task != current)) { - /* - * Flush earlier buffer, which is either from a - * different thread, or when we got a new prefix. - */ - log_store(facility, cont_level, NULL, 0, cont_buf, cont_len); - cont_len = 0; - } - - if (!cont_len) { - cont_level = level; - cont_task = current; - } + /* + * Flush the conflicting buffer. An earlier newline was missing, + * or another task also prints continuation lines. + */ + if (cont.len && (prefix || cont.owner != current)) + cont_flush(); - /* buffer or append to earlier buffer from the same thread */ - if (cont_len + text_len > sizeof(cont_buf)) - text_len = sizeof(cont_buf) - cont_len; - memcpy(cont_buf + cont_len, text, text_len); - cont_len += text_len; + /* buffer line if possible, otherwise store it right away */ + if (!cont_add(facility, level, text, text_len)) + log_store(facility, level, LOG_DEFAULT, 0, + dict, dictlen, text, text_len); } else { - if (cont_len && cont_task == current) { - if (prefix) { - /* - * New prefix from the same thread; flush. We - * either got no earlier newline, or we race - * with an interrupt. - */ - log_store(facility, cont_level, - NULL, 0, cont_buf, cont_len); - cont_len = 0; - } + bool stored = false; - /* append to the earlier buffer and flush */ - if (cont_len + text_len > sizeof(cont_buf)) - text_len = sizeof(cont_buf) - cont_len; - memcpy(cont_buf + cont_len, text, text_len); - cont_len += text_len; - log_store(facility, cont_level, - NULL, 0, cont_buf, cont_len); - cont_len = 0; - cont_task = NULL; - printed_len = cont_len; - } else { - /* ordinary single and terminated line */ - log_store(facility, level, - dict, dictlen, text, text_len); - printed_len = text_len; + /* + * Flush the conflicting buffer. An earlier newline was missing, + * or we race with a continuation line from an interrupt. + */ + if (cont.len && prefix && cont.owner == current) + cont_flush(); + + /* Merge with our buffer if possible; flush it in any case */ + if (cont.len && cont.owner == current) { + stored = cont_add(facility, level, text, text_len); + cont_flush(); } + + if (!stored) + log_store(facility, level, LOG_DEFAULT, 0, + dict, dictlen, text, text_len); } + printed_len += text_len; /* * Try to acquire and then immediately release the console semaphore. @@ -1521,11 +1599,18 @@ EXPORT_SYMBOL(printk); #else #define LOG_LINE_MAX 0 +static struct cont { + size_t len; + size_t cons; + u8 level; + bool flushed:1; +} cont; static struct log *log_from_idx(u32 idx) { return NULL; } static u32 log_next(u32 idx) { return 0; } static void call_console_drivers(int level, const char *text, size_t len) {} static size_t msg_print_text(const struct log *msg, bool syslog, char *buf, size_t size) { return 0; } +static size_t cont_print_text(char *text, size_t size) { return 0; } #endif /* CONFIG_PRINTK */ @@ -1817,6 +1902,7 @@ static u32 console_idx; */ void console_unlock(void) { + static char text[LOG_LINE_MAX]; static u64 seen_seq; unsigned long flags; bool wake_klogd = false; @@ -1829,10 +1915,23 @@ void console_unlock(void) console_may_schedule = 0; + /* flush buffered message fragment immediately to console */ + raw_spin_lock_irqsave(&logbuf_lock, flags); + if (cont.len && (cont.cons < cont.len || cont.flushed)) { + size_t len; + + len = cont_print_text(text, sizeof(text)); + raw_spin_unlock(&logbuf_lock); + stop_critical_timings(); + call_console_drivers(cont.level, text, len); + start_critical_timings(); + local_irq_restore(flags); + } else + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + again: for (;;) { struct log *msg; - static char text[LOG_LINE_MAX]; size_t len; int level; @@ -1847,13 +1946,22 @@ again: console_seq = log_first_seq; console_idx = log_first_idx; } - +skip: if (console_seq == log_next_seq) break; msg = log_from_idx(console_idx); - level = msg->level & 7; + if (msg->flags & LOG_NOCONS) { + /* + * Skip record we have buffered and already printed + * directly to the console when we received it. + */ + console_idx = log_next(console_idx); + console_seq++; + goto skip; + } + level = msg->level; len = msg_print_text(msg, false, text, sizeof(text)); console_idx = log_next(console_idx); -- GitLab From f526a4ce2643e2636c091cf2bf0ec1442110c5b7 Mon Sep 17 00:00:00 2001 From: Konstantin Stepanyuk Date: Wed, 27 Jun 2012 15:52:14 -0600 Subject: [PATCH 3290/6849] tools lib traceevent: Fix clean target in Makefile Dependency files were not cleaned up. Add missing space to fix the issue. Signed-off-by: Konstantin Stepanyuk Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1340833934-18783-1-git-send-email-konstantin.stepanyuk@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 3d69aa9ff51e..423f4b81ecce 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -290,7 +290,7 @@ install_lib: all_cmd install_plugins install_python install: install_lib clean: - $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES).*.d + $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d $(RM) tags TAGS endif # skip-makefile -- GitLab From 6545e3a8f0666b60b26202a5271a94f7cd9601a8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 22 Jun 2012 17:10:14 +0900 Subject: [PATCH 3291/6849] tools lib traceevent: Teach [ce]tags about libtraceeevent error codes As we use a macro trick to sync each error codes with its description string, teach [ce]tags to process them properly. This patch modifies the libtraceevent's Makefile not a kernel one. Suggested-by: Steven Rostedt Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/n/tip-3101nsbg52glxdqih291qj74@git.kernel.org Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1340352615-20737-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 423f4b81ecce..34a577e7d554 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -270,11 +270,13 @@ endif tags: force $(RM) tags - find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px + find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ + --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' TAGS: force $(RM) TAGS - find . -name '*.[ch]' | xargs etags + find . -name '*.[ch]' | xargs etags \ + --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' define do_install $(print_install) \ -- GitLab From 860df5833e461beba4bf9f3304a7919da98fd789 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 22 Jun 2012 14:37:36 +0900 Subject: [PATCH 3292/6849] tools lib traceevent: Make dependency files regeneratable Ingo reported that libtraceevent doesn't clean out dependency (.d) files and it can cause a build error when the libgcc package upgraded: comet:~/tip/tools/perf> make -j SUBDIR ../lib/traceevent/ make[1]: *** No rule to make target `/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h', needed by `event-parse.o'. Stop. make: *** [../lib/traceevent//libtraceevent.a] Error 2 So this patch makes the .d files depends on the source and header files also, so that it can be re-generated as needed. NOTE: This code is copied from the GNU make manual page (4.14 Generating Prerequisites Automatically). Reported-by: Ingo Molnar Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1340343462-15556-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 34a577e7d554..46c2f6b7b123 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -250,8 +250,12 @@ endef all_objs := $(sort $(ALL_OBJS)) all_deps := $(all_objs:%.o=.%.d) +# let .d file also depends on the source and header files define check_deps - $(CC) -M $(CFLAGS) $< > $@; + @set -e; $(RM) $@; \ + $(CC) -M $(CFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + $(RM) $@.$$$$ endef $(gui_deps): ks_version.h -- GitLab From 600da3cfe19496485c5d8d52ff703590a0bd53f6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 22 Jun 2012 17:10:15 +0900 Subject: [PATCH 3293/6849] tools lib traceevent: Check string is really printable When libtraceevent parses format fields, it assumes that array of 1 byte is string but it's not always true. The kvm_emulate_insn contains 15 u8 array of insn that contains (binary) instructions. Thus when it's printed, it'll have broken output like below: kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 csbase=0 len=2 \ insn=<89>P^]& flags=5 failed=0 With this patch: kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 csbase=0 len=2 \ insn=ARRAY[89, 10, 5d, c3, 8d, b4, 26, 00, 00, 00, 00, 55, 89, e5, 3e] flags=5 failed=0 Suggested-by: Steven Rostedt Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1340352615-20737-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 554828219c33..b203a50c0f22 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -3589,6 +3589,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); } +static int is_printable_array(char *p, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len && p[i]; i++) + if (!isprint(p[i])) + return 0; + return 1; +} + static void print_event_fields(struct trace_seq *s, void *data, int size, struct event_format *event) { @@ -3608,7 +3618,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size, len = offset >> 16; offset &= 0xffff; } - if (field->flags & FIELD_IS_STRING) { + if (field->flags & FIELD_IS_STRING && + is_printable_array(data + offset, len)) { trace_seq_printf(s, "%s", (char *)data + offset); } else { trace_seq_puts(s, "ARRAY["); @@ -3619,6 +3630,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size, *((unsigned char *)data + offset + i)); } trace_seq_putc(s, ']'); + field->flags &= ~FIELD_IS_STRING; } } else { val = pevent_read_number(event->pevent, data + field->offset, -- GitLab From b700807196ac8d87e00fed9fda80ab89b7f56db6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 27 Jun 2012 09:41:40 +0900 Subject: [PATCH 3294/6849] tools lib traceevent: Use local variable 'field' Use local variable 'field' to reduce typing. It is needed by later patch not to exceed 80 column. Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1340757701-10711-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b203a50c0f22..63d02be5480f 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -3214,6 +3214,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, { struct pevent *pevent = event->pevent; struct print_flag_sym *flag; + struct format_field *field; unsigned long long val, fval; unsigned long addr; char *str; @@ -3228,27 +3229,29 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, print_str_to_seq(s, format, len_arg, arg->atom.atom); return; case PRINT_FIELD: - if (!arg->field.field) { - arg->field.field = pevent_find_any_field(event, arg->field.name); - if (!arg->field.field) + field = arg->field.field; + if (!field) { + field = pevent_find_any_field(event, arg->field.name); + if (!field) die("field %s not found", arg->field.name); + arg->field.field = field; } /* Zero sized fields, mean the rest of the data */ - len = arg->field.field->size ? : size - arg->field.field->offset; + len = field->size ? : size - field->offset; /* * Some events pass in pointers. If this is not an array * and the size is the same as long_size, assume that it * is a pointer. */ - if (!(arg->field.field->flags & FIELD_IS_ARRAY) && - arg->field.field->size == pevent->long_size) { - addr = *(unsigned long *)(data + arg->field.field->offset); + if (!(field->flags & FIELD_IS_ARRAY) && + field->size == pevent->long_size) { + addr = *(unsigned long *)(data + field->offset); trace_seq_printf(s, "%lx", addr); break; } str = malloc_or_die(len + 1); - memcpy(str, data + arg->field.field->offset, len); + memcpy(str, data + field->offset, len); str[len] = 0; print_str_to_seq(s, format, len_arg, str); free(str); -- GitLab From e080e6f1c863242ff709046d0486d09c46dc484a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 27 Jun 2012 09:41:41 +0900 Subject: [PATCH 3295/6849] tools lib traceevent: Add support for __print_hex() Since the __print_hex() function is used in print fmt now, add corresponding parser routines. This makes the output of perf script on the kvm_emulate_insn event not to fail any more. before: kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 ... after: kvm_emulate_insn: 0:c102fa25:89 10 (prot32) Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1340757701-10711-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 75 ++++++++++++++++++- tools/lib/traceevent/event-parse.h | 7 ++ .../util/scripting-engines/trace-event-perl.c | 4 + .../scripting-engines/trace-event-python.c | 4 + 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 63d02be5480f..b1abd39923d6 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -697,6 +697,10 @@ static void free_arg(struct print_arg *arg) free_arg(arg->symbol.field); free_flag_sym(arg->symbol.symbols); break; + case PRINT_HEX: + free_arg(arg->hex.field); + free_arg(arg->hex.size); + break; case PRINT_TYPE: free(arg->typecast.type); free_arg(arg->typecast.item); @@ -2259,6 +2263,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) return EVENT_ERROR; } +static enum event_type +process_hex(struct event_format *event, struct print_arg *arg, char **tok) +{ + struct print_arg *field; + enum event_type type; + char *token; + + memset(arg, 0, sizeof(*arg)); + arg->type = PRINT_HEX; + + field = alloc_arg(); + type = process_arg(event, field, &token); + + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free; + + arg->hex.field = field; + + free_token(token); + + field = alloc_arg(); + type = process_arg(event, field, &token); + + if (test_type_token(type, token, EVENT_DELIM, ")")) + goto out_free; + + arg->hex.size = field; + + free_token(token); + type = read_token_item(tok); + return type; + + out_free: + free_arg(field); + free_token(token); + *tok = NULL; + return EVENT_ERROR; +} + static enum event_type process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) { @@ -2488,6 +2531,10 @@ process_function(struct event_format *event, struct print_arg *arg, is_symbolic_field = 1; return process_symbols(event, arg, tok); } + if (strcmp(token, "__print_hex") == 0) { + free_token(token); + return process_hex(event, arg, tok); + } if (strcmp(token, "__get_str") == 0) { free_token(token); return process_str(event, arg, tok); @@ -2995,6 +3042,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg break; case PRINT_FLAGS: case PRINT_SYMBOL: + case PRINT_HEX: break; case PRINT_TYPE: val = eval_num_arg(data, size, event, arg->typecast.item); @@ -3218,8 +3266,9 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, unsigned long long val, fval; unsigned long addr; char *str; + unsigned char *hex; int print; - int len; + int i, len; switch (arg->type) { case PRINT_NULL: @@ -3284,6 +3333,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, } } break; + case PRINT_HEX: + field = arg->hex.field->field.field; + if (!field) { + str = arg->hex.field->field.name; + field = pevent_find_any_field(event, str); + if (!field) + die("field %s not found", str); + arg->hex.field->field.field = field; + } + hex = data + field->offset; + len = eval_num_arg(data, size, event, arg->hex.size); + for (i = 0; i < len; i++) { + if (i) + trace_seq_putc(s, ' '); + trace_seq_printf(s, "%02x", hex[i]); + } + break; case PRINT_TYPE: break; @@ -4294,6 +4360,13 @@ static void print_args(struct print_arg *args) trace_seq_destroy(&s); printf(")"); break; + case PRINT_HEX: + printf("__print_hex("); + print_args(args->hex.field); + printf(", "); + print_args(args->hex.size); + printf(")"); + break; case PRINT_STRING: case PRINT_BSTRING: printf("__get_str(%s)", args->string.string); diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index ac997bc7b592..5772ad8cb386 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -226,6 +226,11 @@ struct print_arg_symbol { struct print_flag_sym *symbols; }; +struct print_arg_hex { + struct print_arg *field; + struct print_arg *size; +}; + struct print_arg_dynarray { struct format_field *field; struct print_arg *index; @@ -253,6 +258,7 @@ enum print_arg_type { PRINT_FIELD, PRINT_FLAGS, PRINT_SYMBOL, + PRINT_HEX, PRINT_TYPE, PRINT_STRING, PRINT_BSTRING, @@ -270,6 +276,7 @@ struct print_arg { struct print_arg_typecast typecast; struct print_arg_flags flags; struct print_arg_symbol symbol; + struct print_arg_hex hex; struct print_arg_func func; struct print_arg_string string; struct print_arg_op op; diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index b3620fe12763..02dfa19a467f 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -209,6 +209,10 @@ static void define_event_symbols(struct event_format *event, define_symbolic_values(args->symbol.symbols, ev_name, cur_field_name); break; + case PRINT_HEX: + define_event_symbols(event, ev_name, args->hex.field); + define_event_symbols(event, ev_name, args->hex.size); + break; case PRINT_BSTRING: case PRINT_DYNAMIC_ARRAY: case PRINT_STRING: diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index a8ca2f8179a9..ce4d1b0c3862 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -166,6 +166,10 @@ static void define_event_symbols(struct event_format *event, define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, cur_field_name); break; + case PRINT_HEX: + define_event_symbols(event, ev_name, args->hex.field); + define_event_symbols(event, ev_name, args->hex.size); + break; case PRINT_STRING: break; case PRINT_TYPE: -- GitLab From 50d8f9e393c5a1a8864fda75e3a9f2b800497a61 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 11 Jun 2012 15:28:53 +0900 Subject: [PATCH 3296/6849] tools lib traceevent: Replace malloc_or_die to plain malloc in alloc_event() Because the only caller of the alloc_event() (pevent_parse_event) checks return value properly, it can be changed to use plain malloc. Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1339396133-9839-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b1abd39923d6..83f0a8add177 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -616,7 +616,9 @@ static struct event_format *alloc_event(void) { struct event_format *event; - event = malloc_or_die(sizeof(*event)); + event = malloc(sizeof(*event)); + if (!event) + return NULL; memset(event, 0, sizeof(*event)); return event; -- GitLab From 7582732f57e547929d4c65ad8e38f3446e0538d8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 29 Jun 2012 09:22:54 +0200 Subject: [PATCH 3297/6849] perf tools: Fix hw breakpoint's type modifier parsing Fixing the hw breakpoint's type modifier parsing to allow all possible combinations of 'rwx' characters. Adding automated tests to the parsing test suite. Reported-by: Jovi Zhang Original-patch-by: Namhyung Kim Signed-off-by: Jiri Olsa Cc: Jovi Zhang Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20120629072254.GA940@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events-test.c | 37 +++++++++++++++++++++++++++++ tools/perf/util/parse-events.c | 16 ++++++++++--- tools/perf/util/parse-events.l | 2 +- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index a0f61a2a6835..de81fe1f9329 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -181,6 +181,22 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) return 0; } +static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = list_entry(evlist->entries.next, + struct perf_evsel, node); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", + PERF_TYPE_BREAKPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong bp_type", + (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", + HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + return 0; +} + static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) { struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -352,6 +368,19 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint_w(evlist); } +static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = list_entry(evlist->entries.next, + struct perf_evsel, node); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + + return test__checkevent_breakpoint_rw(evlist); +} + static int test__checkevent_pmu(struct perf_evlist *evlist) { @@ -585,6 +614,14 @@ static struct test__event_st test__events[] = { .name = "instructions:H", .check = test__checkevent_exclude_guest_modifier, }, + [26] = { + .name = "mem:0:rw", + .check = test__checkevent_breakpoint_rw, + }, + [27] = { + .name = "mem:0:rw:kp", + .check = test__checkevent_breakpoint_rw_modifier, + }, }; #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0cc27da30ddb..7ae76af709f1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -383,21 +383,31 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr) if (!type || !type[i]) break; +#define CHECK_SET_TYPE(bit) \ +do { \ + if (attr->bp_type & bit) \ + return -EINVAL; \ + else \ + attr->bp_type |= bit; \ +} while (0) + switch (type[i]) { case 'r': - attr->bp_type |= HW_BREAKPOINT_R; + CHECK_SET_TYPE(HW_BREAKPOINT_R); break; case 'w': - attr->bp_type |= HW_BREAKPOINT_W; + CHECK_SET_TYPE(HW_BREAKPOINT_W); break; case 'x': - attr->bp_type |= HW_BREAKPOINT_X; + CHECK_SET_TYPE(HW_BREAKPOINT_X); break; default: return -EINVAL; } } +#undef CHECK_SET_TYPE + if (!attr->bp_type) /* Default */ attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 488362e14133..a06689474210 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -76,7 +76,7 @@ num_hex 0x[a-fA-F0-9]+ num_raw_hex [a-fA-F0-9]+ name [a-zA-Z_*?][a-zA-Z0-9_*?]* modifier_event [ukhpGH]{1,8} -modifier_bp [rwx] +modifier_bp [rwx]{1,3} %% -- GitLab From 287e74aa3db097469bdca401f33f00ef20dc710d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 28 Jun 2012 23:18:49 +0200 Subject: [PATCH 3298/6849] perf evsel: Handle hw breakpoints event names in perf_evsel__name() Adding hw breakpoint events hook in the perf_evsel__name function, to display event names properly all over the perf tools. Updated hw breakpoints events tests. Signed-off-by: Jiri Olsa Cc: Jovi Zhang Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1340918329-3012-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 30 +++++++++++++++++++++++++++++ tools/perf/util/parse-events-test.c | 10 ++++++++++ tools/perf/util/parse-events.c | 4 +--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 3d1f6968f175..e81771364867 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -15,6 +15,7 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" +#include "../../../include/linux/hw_breakpoint.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) @@ -152,6 +153,31 @@ static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size) return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); } +static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type) +{ + int r; + + r = scnprintf(bf, size, "mem:0x%" PRIx64 ":", addr); + + if (type & HW_BREAKPOINT_R) + r += scnprintf(bf + r, size - r, "r"); + + if (type & HW_BREAKPOINT_W) + r += scnprintf(bf + r, size - r, "w"); + + if (type & HW_BREAKPOINT_X) + r += scnprintf(bf + r, size - r, "x"); + + return r; +} + +static int perf_evsel__bp_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + struct perf_event_attr *attr = &evsel->attr; + int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type); + return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); +} + const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] [PERF_EVSEL__MAX_ALIASES] = { { "L1-dcache", "l1-d", "l1d", "L1-data", }, @@ -285,6 +311,10 @@ const char *perf_evsel__name(struct perf_evsel *evsel) scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint"); break; + case PERF_TYPE_BREAKPOINT: + perf_evsel__bp_name(evsel, bf, sizeof(bf)); + break; + default: scnprintf(bf, sizeof(bf), "%s", "unknown attr type"); break; diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index de81fe1f9329..dd0c306a0698 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -325,6 +325,8 @@ static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:u")); return test__checkevent_breakpoint(evlist); } @@ -338,6 +340,8 @@ static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0x0:x:k")); return test__checkevent_breakpoint_x(evlist); } @@ -351,6 +355,8 @@ static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0x0:r:hp")); return test__checkevent_breakpoint_r(evlist); } @@ -364,6 +370,8 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0x0:w:up")); return test__checkevent_breakpoint_w(evlist); } @@ -377,6 +385,8 @@ static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:kp")); return test__checkevent_breakpoint_rw(evlist); } diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 7ae76af709f1..1dc44dc69133 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -418,7 +418,6 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx, void *ptr, char *type) { struct perf_event_attr attr; - char name[MAX_NAME_LEN]; memset(&attr, 0, sizeof(attr)); attr.bp_addr = (unsigned long) ptr; @@ -437,8 +436,7 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx, attr.type = PERF_TYPE_BREAKPOINT; - snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); - return add_event(list, idx, &attr, name); + return add_event(list, idx, &attr, NULL); } static int config_term(struct perf_event_attr *attr, -- GitLab From 9bc8f9fe2c6e3778202c76ef85ef291567c00cb8 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 14 Jun 2012 22:38:37 +0200 Subject: [PATCH 3299/6849] perf tools: Fix generation of pmu list The internal pmu list was never used. With each perf_pmu__find() call the pmu structure was created new by parsing sysfs. Beside this it caused memory leaks. We now keep all pmus by adding them to the list. Also, pmu_lookup() should return pmus that do not expose the format specifier in sysfs. We need a valid internal pmu list in a later patch to iterate over all pmus that exist in the system. Signed-off-by: Robert Richter Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1339706321-8802-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 74d0948ec368..67715a42cd6d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -72,7 +72,7 @@ static int pmu_format(char *name, struct list_head *format) "%s/bus/event_source/devices/%s/format", sysfs, name); if (stat(path, &st) < 0) - return -1; + return 0; /* no error if format does not exist */ if (pmu_format_parse(path, format)) return -1; @@ -252,6 +252,7 @@ static struct perf_pmu *pmu_lookup(char *name) list_splice(&aliases, &pmu->aliases); pmu->name = strdup(name); pmu->type = type; + list_add_tail(&pmu->list, &pmus); return pmu; } -- GitLab From 1388d715dd7d0f494c93dfdef6ab26719218b868 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 19 Jun 2012 17:48:05 +0200 Subject: [PATCH 3300/6849] perf symbols: Add '.note' check into search for NOTE section Adding '.note' section name to be check when looking for notes section. The '.note' name is used by kernel VDSO. Signed-off-by: Jiri Olsa Cc: Arun Sharma Cc: Benjamin Redelings Cc: Corey Ashford Cc: Cyrill Gorcunov Cc: Frank Ch. Eigler Cc: Frederic Weisbecker Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter Cc: Stephane Eranian Cc: Tom Zanussi Cc: Ulrich Drepper Link: http://lkml.kernel.org/r/1340120894-9465-15-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 994f4ffdcd05..50958bbeb26a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1478,14 +1478,31 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size) goto out; } - sec = elf_section_by_name(elf, &ehdr, &shdr, - ".note.gnu.build-id", NULL); - if (sec == NULL) { + /* + * Check following sections for notes: + * '.note.gnu.build-id' + * '.notes' + * '.note' (VDSO specific) + */ + do { + sec = elf_section_by_name(elf, &ehdr, &shdr, + ".note.gnu.build-id", NULL); + if (sec) + break; + sec = elf_section_by_name(elf, &ehdr, &shdr, ".notes", NULL); - if (sec == NULL) - goto out; - } + if (sec) + break; + + sec = elf_section_by_name(elf, &ehdr, &shdr, + ".note", NULL); + if (sec) + break; + + return err; + + } while (0); data = elf_getdata(sec, NULL); if (data == NULL) -- GitLab From 339ce005091b156c2af4c016c6ba9c1f87cd826a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 19 Jun 2012 17:48:11 +0200 Subject: [PATCH 3301/6849] perf tools: Adding round_up/round_down macros Adding round_up and round_down macros. They will be used in upcoming patches. Signed-off-by: Jiri Olsa Cc: Arun Sharma Cc: Benjamin Redelings Cc: Corey Ashford Cc: Cyrill Gorcunov Cc: Frank Ch. Eigler Cc: Frederic Weisbecker Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter Cc: Stephane Eranian Cc: Tom Zanussi Cc: Ulrich Drepper Link: http://lkml.kernel.org/r/1340120894-9465-21-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/include/linux/kernel.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h index 1eb804fd3fbf..b6842c1d02a8 100644 --- a/tools/perf/util/include/linux/kernel.h +++ b/tools/perf/util/include/linux/kernel.h @@ -108,4 +108,14 @@ int eprintf(int level, #define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__) #define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__) +/* + * This looks more complex than it should be. But we need to + * get the type for the ~ right in round_down (it needs to be + * as wide as the result!), and we want to evaluate the macro + * arguments just once each. + */ +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + #endif -- GitLab From 44b99462d9d776522e174d6c531ce5ccef309e26 Mon Sep 17 00:00:00 2001 From: Vaibhav Nagarnaik Date: Fri, 22 Jun 2012 11:50:05 -0700 Subject: [PATCH 3302/6849] ring-buffer: Fix crash due to uninitialized new_pages list head The new_pages list head in the cpu_buffer is not initialized. When adding pages to the ring buffer, if the memory allocation fails in ring_buffer_resize, the clean up handler tries to free up the allocated pages from all the cpu buffers. The panic is caused by referencing the uninitialized new_pages list head. Initializing the new_pages list head in rb_allocate_cpu_buffer fixes this. Link: http://lkml.kernel.org/r/1340391005-10880-1-git-send-email-vnagarnaik@google.com Cc: Justin Teravest Cc: David Sharp Signed-off-by: Vaibhav Nagarnaik Signed-off-by: Steven Rostedt --- kernel/trace/ring_buffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1d0f6a8a0e5e..ba39cbabdc9f 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1075,6 +1075,7 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int nr_pages, int cpu) rb_init_page(bpage->page); INIT_LIST_HEAD(&cpu_buffer->reader_page->list); + INIT_LIST_HEAD(&cpu_buffer->new_pages); ret = rb_allocate_pages(cpu_buffer, nr_pages); if (ret < 0) -- GitLab From 48fdc72f23ad9a9956e524a47843135d0bbc3317 Mon Sep 17 00:00:00 2001 From: Vaibhav Nagarnaik Date: Fri, 29 Jun 2012 12:31:41 -0700 Subject: [PATCH 3303/6849] ring-buffer: Fix accounting of entries when removing pages When removing pages from the ring buffer, its state is not reset. This means that the counters need to be correctly updated to account for the pages removed. Update the overrun counter to reflect the removed events from the pages. Link: http://lkml.kernel.org/r/1340998301-1715-1-git-send-email-vnagarnaik@google.com Cc: Justin Teravest Cc: David Sharp Signed-off-by: Vaibhav Nagarnaik Signed-off-by: Steven Rostedt --- kernel/trace/ring_buffer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index ba39cbabdc9f..f765465bffe4 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1347,10 +1347,9 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages) * If something was added to this page, it was full * since it is not the tail page. So we deduct the * bytes consumed in ring buffer from here. - * No need to update overruns, since this page is - * deleted from ring buffer and its entries are - * already accounted for. + * Increment overrun to account for the lost events. */ + local_add(page_entries, &cpu_buffer->overrun); local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); } -- GitLab From d36208227d03c44c0a74cd702cc94528162e1703 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 29 Jun 2012 11:40:11 -0400 Subject: [PATCH 3304/6849] printk: Optimize if statement logic where newline exists In reviewing Kay's fix up patch: "printk: Have printk() never buffer its data", I found two if statements that could be combined and optimized. Put together the two 'cont.len && cont.owner == current' if statements into a single one, and check if we need to call cont_add(). This also removes the unneeded double cont_flush() calls. Link: http://lkml.kernel.org/r/1340869133.876.10.camel@mop Signed-off-by: Steven Rostedt Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index fbf4d0b22a1d..5ae6b09e3805 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1496,15 +1496,14 @@ asmlinkage int vprintk_emit(int facility, int level, bool stored = false; /* - * Flush the conflicting buffer. An earlier newline was missing, - * or we race with a continuation line from an interrupt. + * If an earlier newline was missing and it was the same task, + * either merge it with the current buffer and flush, or if + * there was a race with interrupts (prefix == true) then just + * flush it out and store this line separately. */ - if (cont.len && prefix && cont.owner == current) - cont_flush(); - - /* Merge with our buffer if possible; flush it in any case */ if (cont.len && cont.owner == current) { - stored = cont_add(facility, level, text, text_len); + if (!prefix) + stored = cont_add(facility, level, text, text_len); cont_flush(); } -- GitLab From e30384abd63dfa11508a38243e1d78f1d70486b1 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Tue, 29 May 2012 15:26:41 +0530 Subject: [PATCH 3305/6849] ARM: OMAP3+: clock33xx: Add AM33XX clock tree data AM33XX clock implementation is different than any existing OMAP family of devices. Although DPLL module is similar to OMAP4 device, but the usage is very much different than OMAP4. AM33XX has different peripheral set and each module gets integrated to the clock framework differently than OMAP family of devices. This patch adds full Clock tree data for AM33XX family of devices and also integrates it into existing OMAP framework. Signed-off-by: Vaibhav Hiremath Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Bedia Cc: Kevin Hilman Cc: Rajendra Nayak CC: Tony Lindgren Cc: Paul Walmsley Cc: Benoit Cousson [paul@pwsan.com: updated to apply; changed 'soc_is_am33xx' to 'cpu_is_am33xx' to match usage in Tony's current am33xx branch] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 2 + arch/arm/mach-omap2/clock.h | 2 + arch/arm/mach-omap2/clock33xx_data.c | 1105 +++++++++++++++++ arch/arm/mach-omap2/io.c | 2 + arch/arm/plat-omap/include/plat/clkdev_omap.h | 1 + 5 files changed, 1112 insertions(+) create mode 100644 arch/arm/mach-omap2/clock33xx_data.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index a4cf93242b0b..b167152ca69f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -152,6 +152,8 @@ obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o +obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o +obj-$(CONFIG_SOC_AM33XX) += clock33xx_data.o # OMAP2 clock rate set data (old "OPP" data) obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 980b0a436c29..35ec5f3d9a73 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -167,4 +167,6 @@ extern const struct clksel_rate div31_1to31_rates[]; extern struct clk virt_19200000_ck; extern struct clk virt_26000000_ck; +extern int am33xx_clk_init(void); + #endif diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c new file mode 100644 index 000000000000..9c8ac7dc9f3c --- /dev/null +++ b/arch/arm/mach-omap2/clock33xx_data.c @@ -0,0 +1,1105 @@ +/* + * AM33XX Clock data + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "iomap.h" +#include "control.h" +#include "clock.h" +#include "cm.h" +#include "cm33xx.h" +#include "cm-regbits-33xx.h" +#include "prm.h" + +/* Maximum DPLL multiplier, divider values for AM33XX */ +#define AM33XX_MAX_DPLL_MULT 2047 +#define AM33XX_MAX_DPLL_DIV 128 + +/* Modulemode control */ +#define AM33XX_MODULEMODE_HWCTRL 0 +#define AM33XX_MODULEMODE_SWCTRL 1 + +/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always + * physically present, in such a case HWMOD enabling of + * clock would be failure with default parent. And timer + * probe thinks clock is already enabled, this leads to + * crash upon accessing timer 3 & 6 registers in probe. + * Fix by setting parent of both these timers to master + * oscillator clock. + */ +static inline void am33xx_init_timer_parent(struct clk *clk) +{ + omap2_clksel_set_parent(clk, clk->parent); +} + +/* Root clocks */ + +/* RTC 32k */ +static struct clk clk_32768_ck = { + .name = "clk_32768_ck", + .clkdm_name = "l4_rtc_clkdm", + .rate = 32768, + .ops = &clkops_null, +}; + +/* On-Chip 32KHz RC OSC */ +static struct clk clk_rc32k_ck = { + .name = "clk_rc32k_ck", + .rate = 32000, + .ops = &clkops_null, +}; + +/* Crystal input clks */ +static struct clk virt_24000000_ck = { + .name = "virt_24000000_ck", + .rate = 24000000, + .ops = &clkops_null, +}; + +static struct clk virt_25000000_ck = { + .name = "virt_25000000_ck", + .rate = 25000000, + .ops = &clkops_null, +}; + +/* Oscillator clock */ +/* 19.2, 24, 25 or 26 MHz */ +static const struct clksel sys_clkin_sel[] = { + { .parent = &virt_19200000_ck, .rates = div_1_0_rates }, + { .parent = &virt_24000000_ck, .rates = div_1_1_rates }, + { .parent = &virt_25000000_ck, .rates = div_1_2_rates }, + { .parent = &virt_26000000_ck, .rates = div_1_3_rates }, + { .parent = NULL }, +}; + +/* External clock - 12 MHz */ +static struct clk tclkin_ck = { + .name = "tclkin_ck", + .rate = 12000000, + .ops = &clkops_null, +}; + +/* + * sys_clk in: input to the dpll and also used as funtional clock for, + * adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse + * + */ +static struct clk sys_clkin_ck = { + .name = "sys_clkin_ck", + .parent = &virt_24000000_ck, + .init = &omap2_init_clksel_parent, + .clksel_reg = AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS), + .clksel_mask = AM33XX_CONTROL_STATUS_SYSBOOT1_MASK, + .clksel = sys_clkin_sel, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +/* DPLL_CORE */ +static struct dpll_data dpll_core_dd = { + .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_CORE, + .clk_bypass = &sys_clkin_ck, + .clk_ref = &sys_clkin_ck, + .control_reg = AM33XX_CM_CLKMODE_DPLL_CORE, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .idlest_reg = AM33XX_CM_IDLEST_DPLL_CORE, + .mult_mask = AM33XX_DPLL_MULT_MASK, + .div1_mask = AM33XX_DPLL_DIV_MASK, + .enable_mask = AM33XX_DPLL_EN_MASK, + .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, + .max_multiplier = AM33XX_MAX_DPLL_MULT, + .max_divider = AM33XX_MAX_DPLL_DIV, + .min_divider = 1, +}; + +/* CLKDCOLDO output */ +static struct clk dpll_core_ck = { + .name = "dpll_core_ck", + .parent = &sys_clkin_ck, + .dpll_data = &dpll_core_dd, + .init = &omap2_init_dpll_parent, + .ops = &clkops_omap3_core_dpll_ops, + .recalc = &omap3_dpll_recalc, +}; + +static struct clk dpll_core_x2_ck = { + .name = "dpll_core_x2_ck", + .parent = &dpll_core_ck, + .flags = CLOCK_CLKOUTX2, + .ops = &clkops_null, + .recalc = &omap3_clkoutx2_recalc, +}; + + +static const struct clksel dpll_core_m4_div[] = { + { .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_core_m4_ck = { + .name = "dpll_core_m4_ck", + .parent = &dpll_core_x2_ck, + .init = &omap2_init_clksel_parent, + .clksel = dpll_core_m4_div, + .clksel_reg = AM33XX_CM_DIV_M4_DPLL_CORE, + .clksel_mask = AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static const struct clksel dpll_core_m5_div[] = { + { .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_core_m5_ck = { + .name = "dpll_core_m5_ck", + .parent = &dpll_core_x2_ck, + .init = &omap2_init_clksel_parent, + .clksel = dpll_core_m5_div, + .clksel_reg = AM33XX_CM_DIV_M5_DPLL_CORE, + .clksel_mask = AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static const struct clksel dpll_core_m6_div[] = { + { .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_core_m6_ck = { + .name = "dpll_core_m6_ck", + .parent = &dpll_core_x2_ck, + .init = &omap2_init_clksel_parent, + .clksel = dpll_core_m6_div, + .clksel_reg = AM33XX_CM_DIV_M6_DPLL_CORE, + .clksel_mask = AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +/* DPLL_MPU */ +static struct dpll_data dpll_mpu_dd = { + .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_MPU, + .clk_bypass = &sys_clkin_ck, + .clk_ref = &sys_clkin_ck, + .control_reg = AM33XX_CM_CLKMODE_DPLL_MPU, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .idlest_reg = AM33XX_CM_IDLEST_DPLL_MPU, + .mult_mask = AM33XX_DPLL_MULT_MASK, + .div1_mask = AM33XX_DPLL_DIV_MASK, + .enable_mask = AM33XX_DPLL_EN_MASK, + .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, + .max_multiplier = AM33XX_MAX_DPLL_MULT, + .max_divider = AM33XX_MAX_DPLL_DIV, + .min_divider = 1, +}; + +/* CLKOUT: fdpll/M2 */ +static struct clk dpll_mpu_ck = { + .name = "dpll_mpu_ck", + .parent = &sys_clkin_ck, + .dpll_data = &dpll_mpu_dd, + .init = &omap2_init_dpll_parent, + .ops = &clkops_omap3_noncore_dpll_ops, + .recalc = &omap3_dpll_recalc, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap3_noncore_dpll_set_rate, +}; + +/* + * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 + * and ALT_CLK1/2) + */ +static const struct clksel dpll_mpu_m2_div[] = { + { .parent = &dpll_mpu_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_mpu_m2_ck = { + .name = "dpll_mpu_m2_ck", + .clkdm_name = "mpu_clkdm", + .parent = &dpll_mpu_ck, + .clksel = dpll_mpu_m2_div, + .clksel_reg = AM33XX_CM_DIV_M2_DPLL_MPU, + .clksel_mask = AM33XX_DPLL_CLKOUT_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +/* DPLL_DDR */ +static struct dpll_data dpll_ddr_dd = { + .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DDR, + .clk_bypass = &sys_clkin_ck, + .clk_ref = &sys_clkin_ck, + .control_reg = AM33XX_CM_CLKMODE_DPLL_DDR, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .idlest_reg = AM33XX_CM_IDLEST_DPLL_DDR, + .mult_mask = AM33XX_DPLL_MULT_MASK, + .div1_mask = AM33XX_DPLL_DIV_MASK, + .enable_mask = AM33XX_DPLL_EN_MASK, + .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, + .max_multiplier = AM33XX_MAX_DPLL_MULT, + .max_divider = AM33XX_MAX_DPLL_DIV, + .min_divider = 1, +}; + +/* CLKOUT: fdpll/M2 */ +static struct clk dpll_ddr_ck = { + .name = "dpll_ddr_ck", + .parent = &sys_clkin_ck, + .dpll_data = &dpll_ddr_dd, + .init = &omap2_init_dpll_parent, + .ops = &clkops_null, + .recalc = &omap3_dpll_recalc, +}; + +/* + * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 + * and ALT_CLK1/2) + */ +static const struct clksel dpll_ddr_m2_div[] = { + { .parent = &dpll_ddr_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_ddr_m2_ck = { + .name = "dpll_ddr_m2_ck", + .parent = &dpll_ddr_ck, + .clksel = dpll_ddr_m2_div, + .clksel_reg = AM33XX_CM_DIV_M2_DPLL_DDR, + .clksel_mask = AM33XX_DPLL_CLKOUT_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +/* emif_fck functional clock */ +static struct clk dpll_ddr_m2_div2_ck = { + .name = "dpll_ddr_m2_div2_ck", + .clkdm_name = "l3_clkdm", + .parent = &dpll_ddr_m2_ck, + .ops = &clkops_null, + .fixed_div = 2, + .recalc = &omap_fixed_divisor_recalc, +}; + +/* DPLL_DISP */ +static struct dpll_data dpll_disp_dd = { + .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DISP, + .clk_bypass = &sys_clkin_ck, + .clk_ref = &sys_clkin_ck, + .control_reg = AM33XX_CM_CLKMODE_DPLL_DISP, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .idlest_reg = AM33XX_CM_IDLEST_DPLL_DISP, + .mult_mask = AM33XX_DPLL_MULT_MASK, + .div1_mask = AM33XX_DPLL_DIV_MASK, + .enable_mask = AM33XX_DPLL_EN_MASK, + .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, + .max_multiplier = AM33XX_MAX_DPLL_MULT, + .max_divider = AM33XX_MAX_DPLL_DIV, + .min_divider = 1, +}; + +/* CLKOUT: fdpll/M2 */ +static struct clk dpll_disp_ck = { + .name = "dpll_disp_ck", + .parent = &sys_clkin_ck, + .dpll_data = &dpll_disp_dd, + .init = &omap2_init_dpll_parent, + .ops = &clkops_null, + .recalc = &omap3_dpll_recalc, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap3_noncore_dpll_set_rate, +}; + +/* + * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 + * and ALT_CLK1/2) + */ +static const struct clksel dpll_disp_m2_div[] = { + { .parent = &dpll_disp_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_disp_m2_ck = { + .name = "dpll_disp_m2_ck", + .parent = &dpll_disp_ck, + .clksel = dpll_disp_m2_div, + .clksel_reg = AM33XX_CM_DIV_M2_DPLL_DISP, + .clksel_mask = AM33XX_DPLL_CLKOUT_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +/* DPLL_PER */ +static struct dpll_data dpll_per_dd = { + .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_PERIPH, + .clk_bypass = &sys_clkin_ck, + .clk_ref = &sys_clkin_ck, + .control_reg = AM33XX_CM_CLKMODE_DPLL_PER, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .idlest_reg = AM33XX_CM_IDLEST_DPLL_PER, + .mult_mask = AM33XX_DPLL_MULT_PERIPH_MASK, + .div1_mask = AM33XX_DPLL_PER_DIV_MASK, + .enable_mask = AM33XX_DPLL_EN_MASK, + .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, + .max_multiplier = AM33XX_MAX_DPLL_MULT, + .max_divider = AM33XX_MAX_DPLL_DIV, + .min_divider = 1, + .flags = DPLL_J_TYPE, +}; + +/* CLKDCOLDO */ +static struct clk dpll_per_ck = { + .name = "dpll_per_ck", + .parent = &sys_clkin_ck, + .dpll_data = &dpll_per_dd, + .init = &omap2_init_dpll_parent, + .ops = &clkops_null, + .recalc = &omap3_dpll_recalc, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap3_noncore_dpll_set_rate, +}; + +/* CLKOUT: fdpll/M2 */ +static const struct clksel dpll_per_m2_div[] = { + { .parent = &dpll_per_ck, .rates = div31_1to31_rates }, + { .parent = NULL }, +}; + +static struct clk dpll_per_m2_ck = { + .name = "dpll_per_m2_ck", + .parent = &dpll_per_ck, + .clksel = dpll_per_m2_div, + .clksel_reg = AM33XX_CM_DIV_M2_DPLL_PER, + .clksel_mask = AM33XX_DPLL_CLKOUT_DIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk dpll_per_m2_div4_wkupdm_ck = { + .name = "dpll_per_m2_div4_wkupdm_ck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &dpll_per_m2_ck, + .fixed_div = 4, + .ops = &clkops_null, + .recalc = &omap_fixed_divisor_recalc, +}; + +static struct clk dpll_per_m2_div4_ck = { + .name = "dpll_per_m2_div4_ck", + .clkdm_name = "l4ls_clkdm", + .parent = &dpll_per_m2_ck, + .fixed_div = 4, + .ops = &clkops_null, + .recalc = &omap_fixed_divisor_recalc, +}; + +static struct clk l3_gclk = { + .name = "l3_gclk", + .clkdm_name = "l3_clkdm", + .parent = &dpll_core_m4_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk dpll_core_m4_div2_ck = { + .name = "dpll_core_m4_div2_ck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &dpll_core_m4_ck, + .ops = &clkops_null, + .fixed_div = 2, + .recalc = &omap_fixed_divisor_recalc, +}; + +static struct clk l4_rtc_gclk = { + .name = "l4_rtc_gclk", + .parent = &dpll_core_m4_ck, + .ops = &clkops_null, + .fixed_div = 2, + .recalc = &omap_fixed_divisor_recalc, +}; + +static struct clk clk_24mhz = { + .name = "clk_24mhz", + .parent = &dpll_per_m2_ck, + .fixed_div = 8, + .ops = &clkops_null, + .recalc = &omap_fixed_divisor_recalc, +}; + +/* + * Below clock nodes describes clockdomains derived out + * of core clock. + */ +static struct clk l4hs_gclk = { + .name = "l4hs_gclk", + .clkdm_name = "l4hs_clkdm", + .parent = &dpll_core_m4_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk l3s_gclk = { + .name = "l3s_gclk", + .clkdm_name = "l3s_clkdm", + .parent = &dpll_core_m4_div2_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk l4fw_gclk = { + .name = "l4fw_gclk", + .clkdm_name = "l4fw_clkdm", + .parent = &dpll_core_m4_div2_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk l4ls_gclk = { + .name = "l4ls_gclk", + .clkdm_name = "l4ls_clkdm", + .parent = &dpll_core_m4_div2_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk sysclk_div_ck = { + .name = "sysclk_div_ck", + .parent = &dpll_core_m4_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +/* + * In order to match the clock domain with hwmod clockdomain entry, + * separate clock nodes is required for the modules which are + * directly getting their funtioncal clock from sys_clkin. + */ +static struct clk adc_tsc_fck = { + .name = "adc_tsc_fck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk dcan0_fck = { + .name = "dcan0_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk dcan1_fck = { + .name = "dcan1_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk mcasp0_fck = { + .name = "mcasp0_fck", + .clkdm_name = "l3s_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk mcasp1_fck = { + .name = "mcasp1_fck", + .clkdm_name = "l3s_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk smartreflex0_fck = { + .name = "smartreflex0_fck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk smartreflex1_fck = { + .name = "smartreflex1_fck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &sys_clkin_ck, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +/* + * Modules clock nodes + * + * The following clock leaf nodes are added for the moment because: + * + * - hwmod data is not present for these modules, either hwmod + * control is not required or its not populated. + * - Driver code is not yet migrated to use hwmod/runtime pm + * - Modules outside kernel access (to disable them by default) + * + * - debugss + * - mmu (gfx domain) + * - cefuse + * - usbotg_fck (its additional clock and not really a modulemode) + * - ieee5000 + */ +static struct clk debugss_ick = { + .name = "debugss_ick", + .clkdm_name = "l3_aon_clkdm", + .parent = &dpll_core_m4_ck, + .ops = &clkops_omap2_dflt, + .enable_reg = AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, + .enable_bit = AM33XX_MODULEMODE_SWCTRL, + .recalc = &followparent_recalc, +}; + +static struct clk mmu_fck = { + .name = "mmu_fck", + .clkdm_name = "gfx_l3_clkdm", + .parent = &dpll_core_m4_ck, + .ops = &clkops_omap2_dflt, + .enable_reg = AM33XX_CM_GFX_MMUDATA_CLKCTRL, + .enable_bit = AM33XX_MODULEMODE_SWCTRL, + .recalc = &followparent_recalc, +}; + +static struct clk cefuse_fck = { + .name = "cefuse_fck", + .clkdm_name = "l4_cefuse_clkdm", + .parent = &sys_clkin_ck, + .enable_reg = AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL, + .enable_bit = AM33XX_MODULEMODE_SWCTRL, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +/* + * clkdiv32 is generated from fixed division of 732.4219 + */ +static struct clk clkdiv32k_ick = { + .name = "clkdiv32k_ick", + .clkdm_name = "clk_24mhz_clkdm", + .rate = 32768, + .parent = &clk_24mhz, + .enable_reg = AM33XX_CM_PER_CLKDIV32K_CLKCTRL, + .enable_bit = AM33XX_MODULEMODE_SWCTRL, + .ops = &clkops_omap2_dflt, +}; + +static struct clk usbotg_fck = { + .name = "usbotg_fck", + .clkdm_name = "l3s_clkdm", + .parent = &dpll_per_ck, + .enable_reg = AM33XX_CM_CLKDCOLDO_DPLL_PER, + .enable_bit = AM33XX_ST_DPLL_CLKDCOLDO_SHIFT, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +static struct clk ieee5000_fck = { + .name = "ieee5000_fck", + .clkdm_name = "l3s_clkdm", + .parent = &dpll_core_m4_div2_ck, + .enable_reg = AM33XX_CM_PER_IEEE5000_CLKCTRL, + .enable_bit = AM33XX_MODULEMODE_SWCTRL, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +/* Timers */ +static const struct clksel timer1_clkmux_sel[] = { + { .parent = &sys_clkin_ck, .rates = div_1_0_rates }, + { .parent = &clkdiv32k_ick, .rates = div_1_1_rates }, + { .parent = &tclkin_ck, .rates = div_1_2_rates }, + { .parent = &clk_rc32k_ck, .rates = div_1_3_rates }, + { .parent = &clk_32768_ck, .rates = div_1_4_rates }, + { .parent = NULL }, +}; + +static struct clk timer1_fck = { + .name = "timer1_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &omap2_init_clksel_parent, + .clksel = timer1_clkmux_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER1MS_CLK, + .clksel_mask = AM33XX_CLKSEL_0_2_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel timer2_to_7_clk_sel[] = { + { .parent = &tclkin_ck, .rates = div_1_0_rates }, + { .parent = &sys_clkin_ck, .rates = div_1_1_rates }, + { .parent = &clkdiv32k_ick, .rates = div_1_2_rates }, + { .parent = NULL }, +}; + +static struct clk timer2_fck = { + .name = "timer2_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &omap2_init_clksel_parent, + .clksel = timer2_to_7_clk_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER2_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk timer3_fck = { + .name = "timer3_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &am33xx_init_timer_parent, + .clksel = timer2_to_7_clk_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER3_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk timer4_fck = { + .name = "timer4_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &omap2_init_clksel_parent, + .clksel = timer2_to_7_clk_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER4_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk timer5_fck = { + .name = "timer5_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &omap2_init_clksel_parent, + .clksel = timer2_to_7_clk_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER5_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk timer6_fck = { + .name = "timer6_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &am33xx_init_timer_parent, + .clksel = timer2_to_7_clk_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER6_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk timer7_fck = { + .name = "timer7_fck", + .clkdm_name = "l4ls_clkdm", + .parent = &sys_clkin_ck, + .init = &omap2_init_clksel_parent, + .clksel = timer2_to_7_clk_sel, + .clksel_reg = AM33XX_CLKSEL_TIMER7_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk cpsw_125mhz_gclk = { + .name = "cpsw_125mhz_gclk", + .clkdm_name = "cpsw_125mhz_clkdm", + .parent = &dpll_core_m5_ck, + .ops = &clkops_null, + .fixed_div = 2, + .recalc = &omap_fixed_divisor_recalc, +}; + +static const struct clksel cpsw_cpts_rft_clkmux_sel[] = { + { .parent = &dpll_core_m5_ck, .rates = div_1_0_rates }, + { .parent = &dpll_core_m4_ck, .rates = div_1_1_rates }, + { .parent = NULL }, +}; + +static struct clk cpsw_cpts_rft_clk = { + .name = "cpsw_cpts_rft_clk", + .clkdm_name = "cpsw_125mhz_clkdm", + .parent = &dpll_core_m5_ck, + .clksel = cpsw_cpts_rft_clkmux_sel, + .clksel_reg = AM33XX_CM_CPTS_RFT_CLKSEL, + .clksel_mask = AM33XX_CLKSEL_0_0_MASK, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +/* gpio */ +static const struct clksel gpio0_dbclk_mux_sel[] = { + { .parent = &clk_rc32k_ck, .rates = div_1_0_rates }, + { .parent = &clk_32768_ck, .rates = div_1_1_rates }, + { .parent = &clkdiv32k_ick, .rates = div_1_2_rates }, + { .parent = NULL }, +}; + +static struct clk gpio0_dbclk_mux_ck = { + .name = "gpio0_dbclk_mux_ck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &clk_rc32k_ck, + .init = &omap2_init_clksel_parent, + .clksel = gpio0_dbclk_mux_sel, + .clksel_reg = AM33XX_CLKSEL_GPIO0_DBCLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpio0_dbclk = { + .name = "gpio0_dbclk", + .clkdm_name = "l4_wkup_clkdm", + .parent = &gpio0_dbclk_mux_ck, + .enable_reg = AM33XX_CM_WKUP_GPIO0_CLKCTRL, + .enable_bit = AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +static struct clk gpio1_dbclk = { + .name = "gpio1_dbclk", + .clkdm_name = "l4ls_clkdm", + .parent = &clkdiv32k_ick, + .enable_reg = AM33XX_CM_PER_GPIO1_CLKCTRL, + .enable_bit = AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +static struct clk gpio2_dbclk = { + .name = "gpio2_dbclk", + .clkdm_name = "l4ls_clkdm", + .parent = &clkdiv32k_ick, + .enable_reg = AM33XX_CM_PER_GPIO2_CLKCTRL, + .enable_bit = AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +static struct clk gpio3_dbclk = { + .name = "gpio3_dbclk", + .clkdm_name = "l4ls_clkdm", + .parent = &clkdiv32k_ick, + .enable_reg = AM33XX_CM_PER_GPIO3_CLKCTRL, + .enable_bit = AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT, + .ops = &clkops_omap2_dflt, + .recalc = &followparent_recalc, +}; + +static const struct clksel pruss_ocp_clk_mux_sel[] = { + { .parent = &l3_gclk, .rates = div_1_0_rates }, + { .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates }, + { .parent = NULL }, +}; + +static struct clk pruss_ocp_gclk = { + .name = "pruss_ocp_gclk", + .clkdm_name = "pruss_ocp_clkdm", + .parent = &l3_gclk, + .init = &omap2_init_clksel_parent, + .clksel = pruss_ocp_clk_mux_sel, + .clksel_reg = AM33XX_CLKSEL_PRUSS_OCP_CLK, + .clksel_mask = AM33XX_CLKSEL_0_0_MASK, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static const struct clksel lcd_clk_mux_sel[] = { + { .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates }, + { .parent = &dpll_core_m5_ck, .rates = div_1_1_rates }, + { .parent = &dpll_per_m2_ck, .rates = div_1_2_rates }, + { .parent = NULL }, +}; + +static struct clk lcd_gclk = { + .name = "lcd_gclk", + .clkdm_name = "lcdc_clkdm", + .parent = &dpll_disp_m2_ck, + .init = &omap2_init_clksel_parent, + .clksel = lcd_clk_mux_sel, + .clksel_reg = AM33XX_CLKSEL_LCDC_PIXEL_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static struct clk mmc_clk = { + .name = "mmc_clk", + .clkdm_name = "l4ls_clkdm", + .parent = &dpll_per_m2_ck, + .ops = &clkops_null, + .fixed_div = 2, + .recalc = &omap_fixed_divisor_recalc, +}; + +static struct clk mmc2_fck = { + .name = "mmc2_fck", + .clkdm_name = "l3s_clkdm", + .parent = &mmc_clk, + .ops = &clkops_null, + .recalc = &followparent_recalc, +}; + +static const struct clksel gfx_clksel_sel[] = { + { .parent = &dpll_core_m4_ck, .rates = div_1_0_rates }, + { .parent = &dpll_per_m2_ck, .rates = div_1_1_rates }, + { .parent = NULL }, +}; + +static struct clk gfx_fclk_clksel_ck = { + .name = "gfx_fclk_clksel_ck", + .parent = &dpll_core_m4_ck, + .clksel = gfx_clksel_sel, + .ops = &clkops_null, + .clksel_reg = AM33XX_CLKSEL_GFX_FCLK, + .clksel_mask = AM33XX_CLKSEL_GFX_FCLK_MASK, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate div_1_0_2_1_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_AM33XX }, + { .div = 2, .val = 1, .flags = RATE_IN_AM33XX }, + { .div = 0 }, +}; + +static const struct clksel gfx_div_sel[] = { + { .parent = &gfx_fclk_clksel_ck, .rates = div_1_0_2_1_rates }, + { .parent = NULL }, +}; + +static struct clk gfx_fck_div_ck = { + .name = "gfx_fck_div_ck", + .clkdm_name = "gfx_l3_clkdm", + .parent = &gfx_fclk_clksel_ck, + .init = &omap2_init_clksel_parent, + .clksel = gfx_div_sel, + .clksel_reg = AM33XX_CLKSEL_GFX_FCLK, + .clksel_mask = AM33XX_CLKSEL_0_0_MASK, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, + .ops = &clkops_null, +}; + +static const struct clksel sysclkout_pre_sel[] = { + { .parent = &clk_32768_ck, .rates = div_1_0_rates }, + { .parent = &l3_gclk, .rates = div_1_1_rates }, + { .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates }, + { .parent = &dpll_per_m2_ck, .rates = div_1_3_rates }, + { .parent = &lcd_gclk, .rates = div_1_4_rates }, + { .parent = NULL }, +}; + +static struct clk sysclkout_pre_ck = { + .name = "sysclkout_pre_ck", + .parent = &clk_32768_ck, + .init = &omap2_init_clksel_parent, + .clksel = sysclkout_pre_sel, + .clksel_reg = AM33XX_CM_CLKOUT_CTRL, + .clksel_mask = AM33XX_CLKOUT2SOURCE_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +/* Divide by 8 clock rates with default clock is 1/1*/ +static const struct clksel_rate div8_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_AM33XX }, + { .div = 2, .val = 1, .flags = RATE_IN_AM33XX }, + { .div = 3, .val = 2, .flags = RATE_IN_AM33XX }, + { .div = 4, .val = 3, .flags = RATE_IN_AM33XX }, + { .div = 5, .val = 4, .flags = RATE_IN_AM33XX }, + { .div = 6, .val = 5, .flags = RATE_IN_AM33XX }, + { .div = 7, .val = 6, .flags = RATE_IN_AM33XX }, + { .div = 8, .val = 7, .flags = RATE_IN_AM33XX }, + { .div = 0 }, +}; + +static const struct clksel clkout2_div[] = { + { .parent = &sysclkout_pre_ck, .rates = div8_rates }, + { .parent = NULL }, +}; + +static struct clk clkout2_ck = { + .name = "clkout2_ck", + .parent = &sysclkout_pre_ck, + .ops = &clkops_omap2_dflt, + .clksel = clkout2_div, + .clksel_reg = AM33XX_CM_CLKOUT_CTRL, + .clksel_mask = AM33XX_CLKOUT2DIV_MASK, + .enable_reg = AM33XX_CM_CLKOUT_CTRL, + .enable_bit = AM33XX_CLKOUT2EN_SHIFT, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static const struct clksel wdt_clkmux_sel[] = { + { .parent = &clk_rc32k_ck, .rates = div_1_0_rates }, + { .parent = &clkdiv32k_ick, .rates = div_1_1_rates }, + { .parent = NULL }, +}; + +static struct clk wdt1_fck = { + .name = "wdt1_fck", + .clkdm_name = "l4_wkup_clkdm", + .parent = &clk_rc32k_ck, + .init = &omap2_init_clksel_parent, + .clksel = wdt_clkmux_sel, + .clksel_reg = AM33XX_CLKSEL_WDT1_CLK, + .clksel_mask = AM33XX_CLKSEL_0_1_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, +}; + +/* + * clkdev + */ +static struct omap_clk am33xx_clks[] = { + CLK(NULL, "clk_32768_ck", &clk_32768_ck, CK_AM33XX), + CLK(NULL, "clk_rc32k_ck", &clk_rc32k_ck, CK_AM33XX), + CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_AM33XX), + CLK(NULL, "virt_24000000_ck", &virt_24000000_ck, CK_AM33XX), + CLK(NULL, "virt_25000000_ck", &virt_25000000_ck, CK_AM33XX), + CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_AM33XX), + CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_AM33XX), + CLK(NULL, "tclkin_ck", &tclkin_ck, CK_AM33XX), + CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_AM33XX), + CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_AM33XX), + CLK(NULL, "dpll_core_m4_ck", &dpll_core_m4_ck, CK_AM33XX), + CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck, CK_AM33XX), + CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck, CK_AM33XX), + CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_AM33XX), + CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_AM33XX), + CLK(NULL, "dpll_ddr_ck", &dpll_ddr_ck, CK_AM33XX), + CLK(NULL, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck, CK_AM33XX), + CLK(NULL, "dpll_ddr_m2_div2_ck", &dpll_ddr_m2_div2_ck, CK_AM33XX), + CLK(NULL, "dpll_disp_ck", &dpll_disp_ck, CK_AM33XX), + CLK(NULL, "dpll_disp_m2_ck", &dpll_disp_m2_ck, CK_AM33XX), + CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_AM33XX), + CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_AM33XX), + CLK(NULL, "dpll_per_m2_div4_wkupdm_ck", &dpll_per_m2_div4_wkupdm_ck, CK_AM33XX), + CLK(NULL, "dpll_per_m2_div4_ck", &dpll_per_m2_div4_ck, CK_AM33XX), + CLK(NULL, "adc_tsc_fck", &adc_tsc_fck, CK_AM33XX), + CLK(NULL, "cefuse_fck", &cefuse_fck, CK_AM33XX), + CLK(NULL, "clkdiv32k_ick", &clkdiv32k_ick, CK_AM33XX), + CLK(NULL, "dcan0_fck", &dcan0_fck, CK_AM33XX), + CLK(NULL, "dcan1_fck", &dcan1_fck, CK_AM33XX), + CLK(NULL, "debugss_ick", &debugss_ick, CK_AM33XX), + CLK(NULL, "pruss_ocp_gclk", &pruss_ocp_gclk, CK_AM33XX), + CLK("davinci-mcasp.0", NULL, &mcasp0_fck, CK_AM33XX), + CLK("davinci-mcasp.1", NULL, &mcasp1_fck, CK_AM33XX), + CLK("NULL", "mmc2_fck", &mmc2_fck, CK_AM33XX), + CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX), + CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX), + CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX), + CLK(NULL, "gpt1_fck", &timer1_fck, CK_AM33XX), + CLK(NULL, "gpt2_fck", &timer2_fck, CK_AM33XX), + CLK(NULL, "gpt3_fck", &timer3_fck, CK_AM33XX), + CLK(NULL, "gpt4_fck", &timer4_fck, CK_AM33XX), + CLK(NULL, "gpt5_fck", &timer5_fck, CK_AM33XX), + CLK(NULL, "gpt6_fck", &timer6_fck, CK_AM33XX), + CLK(NULL, "gpt7_fck", &timer7_fck, CK_AM33XX), + CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX), + CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX), + CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX), + CLK(NULL, "l4_rtc_gclk", &l4_rtc_gclk, CK_AM33XX), + CLK(NULL, "l3_gclk", &l3_gclk, CK_AM33XX), + CLK(NULL, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck, CK_AM33XX), + CLK(NULL, "l4hs_gclk", &l4hs_gclk, CK_AM33XX), + CLK(NULL, "l3s_gclk", &l3s_gclk, CK_AM33XX), + CLK(NULL, "l4fw_gclk", &l4fw_gclk, CK_AM33XX), + CLK(NULL, "l4ls_gclk", &l4ls_gclk, CK_AM33XX), + CLK(NULL, "clk_24mhz", &clk_24mhz, CK_AM33XX), + CLK(NULL, "sysclk_div_ck", &sysclk_div_ck, CK_AM33XX), + CLK(NULL, "cpsw_125mhz_gclk", &cpsw_125mhz_gclk, CK_AM33XX), + CLK(NULL, "cpsw_cpts_rft_clk", &cpsw_cpts_rft_clk, CK_AM33XX), + CLK(NULL, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, CK_AM33XX), + CLK(NULL, "gpio0_dbclk", &gpio0_dbclk, CK_AM33XX), + CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_AM33XX), + CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_AM33XX), + CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_AM33XX), + CLK(NULL, "lcd_gclk", &lcd_gclk, CK_AM33XX), + CLK(NULL, "mmc_clk", &mmc_clk, CK_AM33XX), + CLK(NULL, "gfx_fclk_clksel_ck", &gfx_fclk_clksel_ck, CK_AM33XX), + CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck, CK_AM33XX), + CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck, CK_AM33XX), + CLK(NULL, "clkout2_ck", &clkout2_ck, CK_AM33XX), +}; + +int __init am33xx_clk_init(void) +{ + struct omap_clk *c; + u32 cpu_clkflg; + + if (cpu_is_am33xx()) { + cpu_mask = RATE_IN_AM33XX; + cpu_clkflg = CK_AM33XX; + } + + clk_init(&omap2_clk_functions); + + for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) + clk_preinit(c->lk.clk); + + for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) { + if (c->cpu & cpu_clkflg) { + clkdev_add(&c->lk); + clk_register(c->lk.clk); + omap2_init_clk_clkdm(c->lk.clk); + } + } + + recalculate_root_clocks(); + + /* + * Only enable those clocks we will need, let the drivers + * enable other clocks as necessary + */ + clk_enable_init_clocks(); + + return 0; +} diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index cb6c11cd8df9..eb007d03ec98 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -38,6 +38,7 @@ #include "powerdomain.h" #include "clockdomain.h" #include "common.h" +#include "clock.h" #include "clock2xxx.h" #include "clock3xxx.h" #include "clock44xx.h" @@ -487,6 +488,7 @@ void __init am33xx_init_early(void) am33xx_voltagedomains_init(); am33xx_powerdomains_init(); am33xx_clockdomains_init(); + am33xx_clk_init(); } #endif diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index d0ed8c443a63..025d85a3ee86 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -39,6 +39,7 @@ struct omap_clk { #define CK_443X (1 << 11) #define CK_TI816X (1 << 12) #define CK_446X (1 << 13) +#define CK_AM33XX (1 << 14) /* AM33xx specific clocks */ #define CK_1710 (1 << 15) /* 1710 extra for rate selection */ -- GitLab From ae0eef66088777cf252c6b91d3eb5ef2f30a67c5 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 29 Jun 2012 09:32:45 +0000 Subject: [PATCH 3306/6849] cnic: Fix mmap regression. commit 1f85d58cdf15354a7120fc9ccc9bb9c45b53af88 cnic: Remove uio mem[0]. introduced a regression as older versions of userspace app still rely on this mmap. Restore the mmap functionality and get the base address from pci_resource_start() as the nedev->base_addr has been deprecated for PCI devices. Update version to 2.5.12. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 8 +++++++- drivers/net/ethernet/broadcom/cnic_if.h | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index f897306b0eb7..22ad7b6d9048 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -1063,9 +1063,13 @@ static int cnic_init_uio(struct cnic_dev *dev) uinfo = &udev->cnic_uinfo; - uinfo->mem[0].memtype = UIO_MEM_NONE; + uinfo->mem[0].addr = pci_resource_start(dev->pcidev, 0); + uinfo->mem[0].internal_addr = dev->regview; + uinfo->mem[0].memtype = UIO_MEM_PHYS; if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { + uinfo->mem[0].size = MB_GET_CID_ADDR(TX_TSS_CID + + TX_MAX_TSS_RINGS + 1); uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & PAGE_MASK; if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) @@ -1075,6 +1079,8 @@ static int cnic_init_uio(struct cnic_dev *dev) uinfo->name = "bnx2_cnic"; } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { + uinfo->mem[0].size = pci_resource_len(dev->pcidev, 0); + uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & PAGE_MASK; uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 54f68f07692e..5cb88881bba1 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -14,8 +14,8 @@ #include "bnx2x/bnx2x_mfw_req.h" -#define CNIC_MODULE_VERSION "2.5.11" -#define CNIC_MODULE_RELDATE "June 27, 2012" +#define CNIC_MODULE_VERSION "2.5.12" +#define CNIC_MODULE_RELDATE "June 29, 2012" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- GitLab From 954e482bde20b0e208fd4d34ef26e10afd194600 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Thu, 24 May 2012 18:19:45 -0700 Subject: [PATCH 3307/6849] x86/copy_user_generic: Optimize copy_user_generic with CPU erms feature According to Intel 64 and IA-32 SDM and Optimization Reference Manual, beginning with Ivybridge, REG string operation using MOVSB and STOSB can provide both flexible and high-performance REG string operations in cases like memory copy. Enhancement availability is indicated by CPUID.7.0.EBX[9] (Enhanced REP MOVSB/ STOSB). If CPU erms feature is detected, patch copy_user_generic with enhanced fast string version of copy_user_generic. A few new macros are defined to reduce duplicate code in ALTERNATIVE and ALTERNATIVE_2. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1337908785-14015-1-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/alternative.h | 74 ++++++++++++++++++++++++------ arch/x86/include/asm/uaccess_64.h | 11 ++++- arch/x86/kernel/x8664_ksyms_64.c | 1 + 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 49331bedc158..70780689599a 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -75,23 +75,54 @@ static inline int alternatives_text_reserved(void *start, void *end) } #endif /* CONFIG_SMP */ +#define OLDINSTR(oldinstr) "661:\n\t" oldinstr "\n662:\n" + +#define b_replacement(number) "663"#number +#define e_replacement(number) "664"#number + +#define alt_slen "662b-661b" +#define alt_rlen(number) e_replacement(number)"f-"b_replacement(number)"f" + +#define ALTINSTR_ENTRY(feature, number) \ + " .long 661b - .\n" /* label */ \ + " .long " b_replacement(number)"f - .\n" /* new instruction */ \ + " .word " __stringify(feature) "\n" /* feature bit */ \ + " .byte " alt_slen "\n" /* source len */ \ + " .byte " alt_rlen(number) "\n" /* replacement len */ + +#define DISCARD_ENTRY(number) /* rlen <= slen */ \ + " .byte 0xff + (" alt_rlen(number) ") - (" alt_slen ")\n" + +#define ALTINSTR_REPLACEMENT(newinstr, feature, number) /* replacement */ \ + b_replacement(number)":\n\t" newinstr "\n" e_replacement(number) ":\n\t" + /* alternative assembly primitive: */ #define ALTERNATIVE(oldinstr, newinstr, feature) \ - \ - "661:\n\t" oldinstr "\n662:\n" \ - ".section .altinstructions,\"a\"\n" \ - " .long 661b - .\n" /* label */ \ - " .long 663f - .\n" /* new instruction */ \ - " .word " __stringify(feature) "\n" /* feature bit */ \ - " .byte 662b-661b\n" /* sourcelen */ \ - " .byte 664f-663f\n" /* replacementlen */ \ - ".previous\n" \ - ".section .discard,\"aw\",@progbits\n" \ - " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \ - ".previous\n" \ - ".section .altinstr_replacement, \"ax\"\n" \ - "663:\n\t" newinstr "\n664:\n" /* replacement */ \ - ".previous" + OLDINSTR(oldinstr) \ + ".section .altinstructions,\"a\"\n" \ + ALTINSTR_ENTRY(feature, 1) \ + ".previous\n" \ + ".section .discard,\"aw\",@progbits\n" \ + DISCARD_ENTRY(1) \ + ".previous\n" \ + ".section .altinstr_replacement, \"ax\"\n" \ + ALTINSTR_REPLACEMENT(newinstr, feature, 1) \ + ".previous" + +#define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\ + OLDINSTR(oldinstr) \ + ".section .altinstructions,\"a\"\n" \ + ALTINSTR_ENTRY(feature1, 1) \ + ALTINSTR_ENTRY(feature2, 2) \ + ".previous\n" \ + ".section .discard,\"aw\",@progbits\n" \ + DISCARD_ENTRY(1) \ + DISCARD_ENTRY(2) \ + ".previous\n" \ + ".section .altinstr_replacement, \"ax\"\n" \ + ALTINSTR_REPLACEMENT(newinstr1, feature1, 1) \ + ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \ + ".previous" /* * This must be included *after* the definition of ALTERNATIVE due to @@ -139,6 +170,19 @@ static inline int alternatives_text_reserved(void *start, void *end) asm volatile (ALTERNATIVE("call %P[old]", "call %P[new]", feature) \ : output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input) +/* + * Like alternative_call, but there are two features and respective functions. + * If CPU has feature2, function2 is used. + * Otherwise, if CPU has feature1, function1 is used. + * Otherwise, old function is used. + */ +#define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ + output, input...) \ + asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ + "call %P[new2]", feature2) \ + : output : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ + [new2] "i" (newfunc2), ## input) + /* * use this macro(s) if you need more than one output parameter * in alternative_io diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 8e796fbbf9c6..d8def8b3dba0 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -17,6 +17,8 @@ /* Handles exceptions in both to and from, but doesn't do access_ok */ __must_check unsigned long +copy_user_enhanced_fast_string(void *to, const void *from, unsigned len); +__must_check unsigned long copy_user_generic_string(void *to, const void *from, unsigned len); __must_check unsigned long copy_user_generic_unrolled(void *to, const void *from, unsigned len); @@ -26,9 +28,16 @@ copy_user_generic(void *to, const void *from, unsigned len) { unsigned ret; - alternative_call(copy_user_generic_unrolled, + /* + * If CPU has ERMS feature, use copy_user_enhanced_fast_string. + * Otherwise, if CPU has rep_good feature, use copy_user_generic_string. + * Otherwise, use copy_user_generic_unrolled. + */ + alternative_call_2(copy_user_generic_unrolled, copy_user_generic_string, X86_FEATURE_REP_GOOD, + copy_user_enhanced_fast_string, + X86_FEATURE_ERMS, ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from), "=d" (len)), "1" (to), "2" (from), "3" (len) diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 9796c2f3d074..6020f6f5927c 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -28,6 +28,7 @@ EXPORT_SYMBOL(__put_user_8); EXPORT_SYMBOL(copy_user_generic_string); EXPORT_SYMBOL(copy_user_generic_unrolled); +EXPORT_SYMBOL(copy_user_enhanced_fast_string); EXPORT_SYMBOL(__copy_user_nocache); EXPORT_SYMBOL(_copy_from_user); EXPORT_SYMBOL(_copy_to_user); -- GitLab From 2553dcc6e603e3833990bd3a29bee98d1dbdf251 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 28 Jun 2012 16:29:19 -0600 Subject: [PATCH 3308/6849] ARM: tegra: use of_default_bus_match_table of_default_bus_match_table is a table of default bus types supported by of_platform_populate(). Since Tegra has no need to support any specific custom list of bus types, modify the DT board files to use this default list. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-dt-tegra20.c | 7 +------ arch/arm/mach-tegra/board-dt-tegra30.c | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 1b43c3350e3c..d0de9c1192f7 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -82,11 +82,6 @@ static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { { NULL, NULL, 0, 0}, }; -static struct of_device_id tegra_dt_match_table[] __initdata = { - { .compatible = "simple-bus", }, - {} -}; - static void __init tegra_dt_init(void) { tegra_clk_init_from_table(tegra_dt_clk_init_table); @@ -95,7 +90,7 @@ static void __init tegra_dt_init(void) * Finished with the static registrations now; fill in the missing * devices */ - of_platform_populate(NULL, tegra_dt_match_table, + of_platform_populate(NULL, of_default_bus_match_table, tegra20_auxdata_lookup, NULL); } diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 4a409862015f..ee48214bfd89 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c @@ -36,11 +36,6 @@ #include "board.h" #include "clock.h" -static struct of_device_id tegra_dt_match_table[] __initdata = { - { .compatible = "simple-bus", }, - {} -}; - struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), @@ -75,7 +70,7 @@ static void __init tegra30_dt_init(void) { tegra_clk_init_from_table(tegra_dt_clk_init_table); - of_platform_populate(NULL, tegra_dt_match_table, + of_platform_populate(NULL, of_default_bus_match_table, tegra30_auxdata_lookup, NULL); } -- GitLab From a31f2d17b331db970259e875b7223d3aba7e3821 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 29 Jun 2012 06:15:21 +0000 Subject: [PATCH 3309/6849] netlink: add netlink_kernel_cfg parameter to netlink_kernel_create This patch adds the following structure: struct netlink_kernel_cfg { unsigned int groups; void (*input)(struct sk_buff *skb); struct mutex *cb_mutex; }; That can be passed to netlink_kernel_create to set optional configurations for netlink kernel sockets. I've populated this structure by looking for NULL and zero parameters at the existing code. The remaining parameters that always need to be set are still left in the original interface. That includes optional parameters for the netlink socket creation. This allows easy extensibility of this interface in the future. This patch also adapts all callers to use this new interface. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- crypto/crypto_user.c | 7 +++++-- drivers/connector/connector.c | 13 +++++++++---- drivers/infiniband/core/netlink.c | 7 +++++-- drivers/scsi/scsi_netlink.c | 7 +++++-- drivers/scsi/scsi_transport_iscsi.c | 9 ++++++--- drivers/staging/gdm72xx/netlink_k.c | 6 ++++-- include/linux/netlink.h | 15 ++++++++++----- kernel/audit.c | 7 +++++-- lib/kobject_uevent.c | 5 ++++- net/bridge/netfilter/ebt_ulog.c | 6 ++++-- net/core/rtnetlink.c | 9 +++++++-- net/core/sock_diag.c | 8 ++++++-- net/decnet/netfilter/dn_rtmsg.c | 8 +++++--- net/ipv4/fib_frontend.c | 7 +++++-- net/ipv4/netfilter/ipt_ULOG.c | 8 +++++--- net/netfilter/nfnetlink.c | 7 +++++-- net/netlink/af_netlink.c | 16 ++++++++++------ net/netlink/genetlink.c | 10 +++++++--- net/xfrm/xfrm_user.c | 7 +++++-- security/selinux/netlink.c | 6 +++++- 20 files changed, 117 insertions(+), 51 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 5a37eadb4e56..ba2c611154af 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -496,9 +496,12 @@ static void crypto_netlink_rcv(struct sk_buff *skb) static int __init crypto_user_init(void) { + struct netlink_kernel_cfg cfg = { + .input = crypto_netlink_rcv, + }; + crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, - 0, crypto_netlink_rcv, - NULL, THIS_MODULE); + THIS_MODULE, &cfg); if (!crypto_nlsk) return -ENOMEM; diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 34e0e9e4d913..116cf8d02834 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -251,15 +251,20 @@ static const struct file_operations cn_file_ops = { .release = single_release }; +static struct cn_dev cdev = { + .input = cn_rx_skb, +}; + static int __devinit cn_init(void) { struct cn_dev *dev = &cdev; - - dev->input = cn_rx_skb; + struct netlink_kernel_cfg cfg = { + .groups = CN_NETLINK_USERS + 0xf, + .input = dev->input, + }; dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR, - CN_NETLINK_USERS + 0xf, - dev->input, NULL, THIS_MODULE); + THIS_MODULE, &cfg); if (!dev->nls) return -EIO; diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index 1e691dca1820..3ae2bfd31015 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -173,8 +173,11 @@ static void ibnl_rcv(struct sk_buff *skb) int __init ibnl_init(void) { - nls = netlink_kernel_create(&init_net, NETLINK_RDMA, 0, ibnl_rcv, - NULL, THIS_MODULE); + struct netlink_kernel_cfg cfg = { + .input = ibnl_rcv, + }; + + nls = netlink_kernel_create(&init_net, NETLINK_RDMA, THIS_MODULE, &cfg); if (!nls) { pr_warn("Failed to create netlink socket\n"); return -ENOMEM; diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index c77628afbf9f..8818dd681c19 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -486,6 +486,10 @@ void scsi_netlink_init(void) { int error; + struct netlink_kernel_cfg cfg = { + .input = scsi_nl_rcv_msg, + .groups = SCSI_NL_GRP_CNT, + }; INIT_LIST_HEAD(&scsi_nl_drivers); @@ -497,8 +501,7 @@ scsi_netlink_init(void) } scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT, - SCSI_NL_GRP_CNT, scsi_nl_rcv_msg, NULL, - THIS_MODULE); + THIS_MODULE, &cfg); if (!scsi_nl_sock) { printk(KERN_ERR "%s: register of receive handler failed\n", __func__); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 1cf640e575da..6042954d8f3b 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2936,7 +2936,10 @@ EXPORT_SYMBOL_GPL(iscsi_unregister_transport); static __init int iscsi_transport_init(void) { int err; - + struct netlink_kernel_cfg cfg = { + .groups = 1, + .input = iscsi_if_rx, + }; printk(KERN_INFO "Loading iSCSI transport class v%s.\n", ISCSI_TRANSPORT_VERSION); @@ -2966,8 +2969,8 @@ static __init int iscsi_transport_init(void) if (err) goto unregister_conn_class; - nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, - NULL, THIS_MODULE); + nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, + THIS_MODULE, &cfg); if (!nls) { err = -ENOBUFS; goto unregister_session_class; diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 2489bb5597ca..87c3a07ed80e 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -88,13 +88,15 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void *msg, int len)) { struct sock *sock; + struct netlink_kernel_cfg cfg = { + .input = netlink_rcv, + }; #if !defined(DEFINE_MUTEX) init_MUTEX(&netlink_mutex); #endif - sock = netlink_kernel_create(&init_net, unit, 0, netlink_rcv, NULL, - THIS_MODULE); + sock = netlink_kernel_create(&init_net, unit, THIS_MODULE, &cfg); if (sock) rcv_cb = cb; diff --git a/include/linux/netlink.h b/include/linux/netlink.h index ed33f0901bc2..6085e4919cb3 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -174,11 +174,16 @@ struct netlink_skb_parms { extern void netlink_table_grab(void); extern void netlink_table_ungrab(void); -extern struct sock *netlink_kernel_create(struct net *net, - int unit,unsigned int groups, - void (*input)(struct sk_buff *skb), - struct mutex *cb_mutex, - struct module *module); +/* optional Netlink kernel configuration parameters */ +struct netlink_kernel_cfg { + unsigned int groups; + void (*input)(struct sk_buff *skb); + struct mutex *cb_mutex; +}; + +extern struct sock *netlink_kernel_create(struct net *net, int unit, + struct module *module, + struct netlink_kernel_cfg *cfg); extern void netlink_kernel_release(struct sock *sk); extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups); extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); diff --git a/kernel/audit.c b/kernel/audit.c index 30b252a1fb61..4a3f28d2ca65 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -962,14 +962,17 @@ static void audit_receive(struct sk_buff *skb) static int __init audit_init(void) { int i; + struct netlink_kernel_cfg cfg = { + .input = audit_receive, + }; if (audit_initialized == AUDIT_DISABLED) return 0; printk(KERN_INFO "audit: initializing netlink socket (%s)\n", audit_default ? "enabled" : "disabled"); - audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, - audit_receive, NULL, THIS_MODULE); + audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, + THIS_MODULE, &cfg); if (!audit_sock) audit_panic("cannot initialize netlink socket"); else diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 1a91efa6d121..0401d2916d9f 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -373,13 +373,16 @@ EXPORT_SYMBOL_GPL(add_uevent_var); static int uevent_net_init(struct net *net) { struct uevent_sock *ue_sk; + struct netlink_kernel_cfg cfg = { + .groups = 1, + }; ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL); if (!ue_sk) return -ENOMEM; ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, - 1, NULL, NULL, THIS_MODULE); + THIS_MODULE, &cfg); if (!ue_sk->sk) { printk(KERN_ERR "kobject_uevent: unable to create netlink socket!\n"); diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 1bd173218f7b..374bdcd77039 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -282,6 +282,9 @@ static int __init ebt_ulog_init(void) { int ret; int i; + struct netlink_kernel_cfg cfg = { + .groups = EBT_ULOG_MAXNLGROUPS, + }; if (nlbufsiz >= 128*1024) { pr_warning("Netlink buffer has to be <= 128kB," @@ -296,8 +299,7 @@ static int __init ebt_ulog_init(void) } ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, - EBT_ULOG_MAXNLGROUPS, NULL, NULL, - THIS_MODULE); + THIS_MODULE, &cfg); if (!ebtulognl) ret = -ENOMEM; else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index bc8a1cdaac98..2b325c340b44 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2353,8 +2353,13 @@ static struct notifier_block rtnetlink_dev_notifier = { static int __net_init rtnetlink_net_init(struct net *net) { struct sock *sk; - sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, - rtnetlink_rcv, &rtnl_mutex, THIS_MODULE); + struct netlink_kernel_cfg cfg = { + .groups = RTNLGRP_MAX, + .input = rtnetlink_rcv, + .cb_mutex = &rtnl_mutex, + }; + + sk = netlink_kernel_create(net, NETLINK_ROUTE, THIS_MODULE, &cfg); if (!sk) return -ENOMEM; net->rtnl = sk; diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index ff2967acbfae..07a29eb34a41 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -171,8 +171,12 @@ EXPORT_SYMBOL_GPL(sock_diag_nlsk); static int __init sock_diag_init(void) { - sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG, 0, - sock_diag_rcv, NULL, THIS_MODULE); + struct netlink_kernel_cfg cfg = { + .input = sock_diag_rcv, + }; + + sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG, + THIS_MODULE, &cfg); return sock_diag_nlsk == NULL ? -ENOMEM : 0; } diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index b8f7f5b8c350..11db0ecf342f 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -125,11 +125,13 @@ static struct nf_hook_ops dnrmg_ops __read_mostly = { static int __init dn_rtmsg_init(void) { int rv = 0; + struct netlink_kernel_cfg cfg = { + .groups = DNRNG_NLGRP_MAX, + .input = dnrmg_receive_user_skb, + }; dnrmg = netlink_kernel_create(&init_net, - NETLINK_DNRTMSG, DNRNG_NLGRP_MAX, - dnrmg_receive_user_skb, - NULL, THIS_MODULE); + NETLINK_DNRTMSG, THIS_MODULE, &cfg); if (dnrmg == NULL) { printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket"); return -ENOMEM; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index ae528d1b293a..3e11ea225dad 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -976,8 +976,11 @@ static void nl_fib_input(struct sk_buff *skb) static int __net_init nl_fib_lookup_init(struct net *net) { struct sock *sk; - sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0, - nl_fib_input, NULL, THIS_MODULE); + struct netlink_kernel_cfg cfg = { + .input = nl_fib_input, + }; + + sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, THIS_MODULE, &cfg); if (sk == NULL) return -EAFNOSUPPORT; net->ipv4.fibnl = sk; diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 99b3f53f16a7..1109f7f6c254 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -381,6 +381,9 @@ static struct nf_logger ipt_ulog_logger __read_mostly = { static int __init ulog_tg_init(void) { int ret, i; + struct netlink_kernel_cfg cfg = { + .groups = ULOG_MAXNLGROUPS, + }; pr_debug("init module\n"); @@ -393,9 +396,8 @@ static int __init ulog_tg_init(void) for (i = 0; i < ULOG_MAXNLGROUPS; i++) setup_timer(&ulog_buffers[i].timer, ulog_timer, i); - nflognl = netlink_kernel_create(&init_net, - NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL, - NULL, THIS_MODULE); + nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, + THIS_MODULE, &cfg); if (!nflognl) return -ENOMEM; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 3e797d1fcb94..700e4616a098 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -203,9 +203,12 @@ static void nfnetlink_rcv(struct sk_buff *skb) static int __net_init nfnetlink_net_init(struct net *net) { struct sock *nfnl; + struct netlink_kernel_cfg cfg = { + .groups = NFNLGRP_MAX, + .input = nfnetlink_rcv, + }; - nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, NFNLGRP_MAX, - nfnetlink_rcv, NULL, THIS_MODULE); + nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, THIS_MODULE, &cfg); if (!nfnl) return -ENOMEM; net->nfnl_stash = nfnl; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index b3025a603d56..43a124feaad8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1503,14 +1503,16 @@ static void netlink_data_ready(struct sock *sk, int len) */ struct sock * -netlink_kernel_create(struct net *net, int unit, unsigned int groups, - void (*input)(struct sk_buff *skb), - struct mutex *cb_mutex, struct module *module) +netlink_kernel_create(struct net *net, int unit, + struct module *module, + struct netlink_kernel_cfg *cfg) { struct socket *sock; struct sock *sk; struct netlink_sock *nlk; struct listeners *listeners = NULL; + struct mutex *cb_mutex = cfg ? cfg->cb_mutex : NULL; + unsigned int groups; BUG_ON(!nl_table); @@ -1532,16 +1534,18 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups, sk = sock->sk; sk_change_net(sk, net); - if (groups < 32) + if (!cfg || cfg->groups < 32) groups = 32; + else + groups = cfg->groups; listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL); if (!listeners) goto out_sock_release; sk->sk_data_ready = netlink_data_ready; - if (input) - nlk_sk(sk)->netlink_rcv = input; + if (cfg && cfg->input) + nlk_sk(sk)->netlink_rcv = cfg->input; if (netlink_insert(sk, net, 0)) goto out_sock_release; diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 2cc7c1ee7690..32761b53015e 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -915,10 +915,14 @@ static struct genl_multicast_group notify_grp = { static int __net_init genl_pernet_init(struct net *net) { + struct netlink_kernel_cfg cfg = { + .input = genl_rcv, + .cb_mutex = &genl_mutex, + }; + /* we'll bump the group number right afterwards */ - net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, 0, - genl_rcv, &genl_mutex, - THIS_MODULE); + net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, + THIS_MODULE, &cfg); if (!net->genl_sock && net_eq(net, &init_net)) panic("GENL: Cannot initialize generic netlink\n"); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 540762726aaf..e75d8e47f35c 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2959,9 +2959,12 @@ static struct xfrm_mgr netlink_mgr = { static int __net_init xfrm_user_net_init(struct net *net) { struct sock *nlsk; + struct netlink_kernel_cfg cfg = { + .groups = XFRMNLGRP_MAX, + .input = xfrm_netlink_rcv, + }; - nlsk = netlink_kernel_create(net, NETLINK_XFRM, XFRMNLGRP_MAX, - xfrm_netlink_rcv, NULL, THIS_MODULE); + nlsk = netlink_kernel_create(net, NETLINK_XFRM, THIS_MODULE, &cfg); if (nlsk == NULL) return -ENOMEM; net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */ diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index 8a23a35b9c5b..8a77725423e0 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c @@ -111,8 +111,12 @@ void selnl_notify_policyload(u32 seqno) static int __init selnl_init(void) { + struct netlink_kernel_cfg cfg = { + .groups = SELNLGRP_MAX, + }; + selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, - SELNLGRP_MAX, NULL, NULL, THIS_MODULE); + THIS_MODULE, &cfg); if (selnl == NULL) panic("SELinux: Cannot create netlink socket."); netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); -- GitLab From 03292745b02d1166e2a215504407e096b8427be5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 29 Jun 2012 06:15:22 +0000 Subject: [PATCH 3310/6849] netlink: add nlk->netlink_bind hook for module auto-loading This patch adds a hook in the binding path of netlink. This is used by ctnetlink to allow module autoloading for the case in which one user executes: conntrack -E So far, this resulted in nfnetlink loaded, but not nf_conntrack_netlink. I have received in the past many complains on this behaviour. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller --- include/linux/netlink.h | 1 + net/netfilter/nfnetlink.c | 29 +++++++++++++++++++++++++++++ net/netlink/af_netlink.c | 19 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 6085e4919cb3..f74dd133788f 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -179,6 +179,7 @@ struct netlink_kernel_cfg { unsigned int groups; void (*input)(struct sk_buff *skb); struct mutex *cb_mutex; + void (*bind)(int group); }; extern struct sock *netlink_kernel_create(struct net *net, int unit, diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 700e4616a098..5a2132b97fe9 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -39,6 +39,15 @@ static char __initdata nfversion[] = "0.30"; static const struct nfnetlink_subsystem __rcu *subsys_table[NFNL_SUBSYS_COUNT]; static DEFINE_MUTEX(nfnl_mutex); +static const int nfnl_group2type[NFNLGRP_MAX+1] = { + [NFNLGRP_CONNTRACK_NEW] = NFNL_SUBSYS_CTNETLINK, + [NFNLGRP_CONNTRACK_UPDATE] = NFNL_SUBSYS_CTNETLINK, + [NFNLGRP_CONNTRACK_DESTROY] = NFNL_SUBSYS_CTNETLINK, + [NFNLGRP_CONNTRACK_EXP_NEW] = NFNL_SUBSYS_CTNETLINK_EXP, + [NFNLGRP_CONNTRACK_EXP_UPDATE] = NFNL_SUBSYS_CTNETLINK_EXP, + [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP, +}; + void nfnl_lock(void) { mutex_lock(&nfnl_mutex); @@ -200,12 +209,32 @@ static void nfnetlink_rcv(struct sk_buff *skb) netlink_rcv_skb(skb, &nfnetlink_rcv_msg); } +#ifdef CONFIG_MODULES +static void nfnetlink_bind(int group) +{ + const struct nfnetlink_subsystem *ss; + int type = nfnl_group2type[group]; + + rcu_read_lock(); + ss = nfnetlink_get_subsys(type); + if (!ss) { + rcu_read_unlock(); + request_module("nfnetlink-subsys-%d", type); + return; + } + rcu_read_unlock(); +} +#endif + static int __net_init nfnetlink_net_init(struct net *net) { struct sock *nfnl; struct netlink_kernel_cfg cfg = { .groups = NFNLGRP_MAX, .input = nfnetlink_rcv, +#ifdef CONFIG_MODULES + .bind = nfnetlink_bind, +#endif }; nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, THIS_MODULE, &cfg); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 43a124feaad8..5463969da45b 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -80,6 +80,7 @@ struct netlink_sock { struct mutex *cb_mutex; struct mutex cb_def_mutex; void (*netlink_rcv)(struct sk_buff *skb); + void (*netlink_bind)(int group); struct module *module; }; @@ -124,6 +125,7 @@ struct netlink_table { unsigned int groups; struct mutex *cb_mutex; struct module *module; + void (*bind)(int group); int registered; }; @@ -444,6 +446,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, struct module *module = NULL; struct mutex *cb_mutex; struct netlink_sock *nlk; + void (*bind)(int group); int err = 0; sock->state = SS_UNCONNECTED; @@ -468,6 +471,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, else err = -EPROTONOSUPPORT; cb_mutex = nl_table[protocol].cb_mutex; + bind = nl_table[protocol].bind; netlink_unlock_table(); if (err < 0) @@ -483,6 +487,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, nlk = nlk_sk(sock->sk); nlk->module = module; + nlk->netlink_bind = bind; out: return err; @@ -683,6 +688,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, netlink_update_listeners(sk); netlink_table_ungrab(); + if (nlk->netlink_bind && nlk->groups[0]) { + int i; + + for (i=0; ingroups; i++) { + if (test_bit(i, nlk->groups)) + nlk->netlink_bind(i); + } + } + return 0; } @@ -1239,6 +1253,10 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, netlink_update_socket_mc(nlk, val, optname == NETLINK_ADD_MEMBERSHIP); netlink_table_ungrab(); + + if (nlk->netlink_bind) + nlk->netlink_bind(val); + err = 0; break; } @@ -1559,6 +1577,7 @@ netlink_kernel_create(struct net *net, int unit, rcu_assign_pointer(nl_table[unit].listeners, listeners); nl_table[unit].cb_mutex = cb_mutex; nl_table[unit].module = module; + nl_table[unit].bind = cfg ? cfg->bind : NULL; nl_table[unit].registered = 1; } else { kfree(listeners); -- GitLab From b03738430c7537d5f87948e0b35d8aaf2688c6b4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 20 Jun 2012 09:48:43 +0800 Subject: [PATCH 3311/6849] ACPI video: Still use ACPI backlight control if _DOS doesn't exist This fixes a regression in 3.4-rc1 caused by commit ea9f8856bd6d4ed45885b06a338f7362cd6c60e5 (ACPI video: Harden video bus adding.) Some platforms don't have _DOS control method, but the ACPI backlight still works. We should not invoke _DOS for these platforms. https://bugzilla.kernel.org/show_bug.cgi?id=43168 Cc: Igor Murzov Cc: stable@vger.kernel.org Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9577b6fa2650..4134b300b9cd 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -558,6 +558,8 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; + if (!video->cap._DOS) + return 0; if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) return -EINVAL; -- GitLab From 5f1601261050251a5ca293378b492a69d590dacb Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 13 Jun 2012 16:10:45 -0500 Subject: [PATCH 3312/6849] acpi_pad: fix power_saving thread deadlock The acpi_pad driver can get stuck in destroy_power_saving_task() waiting for kthread_stop() to stop a power_saving thread. The problem is that the isolated_cpus_lock mutex is owned when destroy_power_saving_task() calls kthread_stop(), which waits for a power_saving thread to end, and the power_saving thread tries to acquire the isolated_cpus_lock when it calls round_robin_cpu(). This patch fixes the issue by making round_robin_cpu() use its own mutex. https://bugzilla.kernel.org/show_bug.cgi?id=42981 Cc: stable@vger.kernel.org Signed-off-by: Stuart Hayes Signed-off-by: Len Brown --- drivers/acpi/acpi_pad.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index a43fa1a57d57..1502c50273b5 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -36,6 +36,7 @@ #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 static DEFINE_MUTEX(isolated_cpus_lock); +static DEFINE_MUTEX(round_robin_lock); static unsigned long power_saving_mwait_eax; @@ -107,7 +108,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return; - mutex_lock(&isolated_cpus_lock); + mutex_lock(&round_robin_lock); cpumask_clear(tmp); for_each_cpu(cpu, pad_busy_cpus) cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); @@ -116,7 +117,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (cpumask_empty(tmp)) cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); if (cpumask_empty(tmp)) { - mutex_unlock(&isolated_cpus_lock); + mutex_unlock(&round_robin_lock); return; } for_each_cpu(cpu, tmp) { @@ -131,7 +132,7 @@ static void round_robin_cpu(unsigned int tsk_index) tsk_in_cpu[tsk_index] = preferred_cpu; cpumask_set_cpu(preferred_cpu, pad_busy_cpus); cpu_weight[preferred_cpu]++; - mutex_unlock(&isolated_cpus_lock); + mutex_unlock(&round_robin_lock); set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); } -- GitLab From bb35f67195fcdbe79faa7a15ce148a67c9ab923d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 29 Jun 2012 05:10:05 +0000 Subject: [PATCH 3313/6849] net: introduce new priv_flag indicating iface capable of change mac when running Introduce IFF_LIVE_ADDR_CHANGE priv_flag and use it to disable netif_running() check in eth_mac_addr() Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/linux/if.h | 2 ++ net/ethernet/eth.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/if.h b/include/linux/if.h index f995c663c493..1ec407b01e46 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -81,6 +81,8 @@ #define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */ #define IFF_TEAM_PORT 0x40000 /* device used as team port */ #define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */ +#define IFF_LIVE_ADDR_CHANGE 0x100000 /* device supports hardware address + * change when it's running */ #define IF_GET_IFACE 0x0001 /* for querying only */ diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 36e58800a9e3..db6a6c17d790 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -283,7 +283,7 @@ int eth_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; - if (netif_running(dev)) + if (!(dev->priv_flags & IFF_LIVE_ADDR_CHANGE) && netif_running(dev)) return -EBUSY; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; -- GitLab From f2f2c8b42d5b1858e1680133fcd4bea5c8dcdb2c Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 29 Jun 2012 05:10:06 +0000 Subject: [PATCH 3314/6849] virtio_net: use IFF_LIVE_ADDR_CHANGE priv_flag Acked-by: Michael S. Tsirkin Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 36a16d581f71..1db445b2ecc7 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -679,12 +679,11 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) { struct virtnet_info *vi = netdev_priv(dev); struct virtio_device *vdev = vi->vdev; - struct sockaddr *addr = p; + int ret; - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - dev->addr_assign_type &= ~NET_ADDR_RANDOM; + ret = eth_mac_addr(dev, p); + if (ret) + return ret; if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) vdev->config->set(vdev, offsetof(struct virtio_net_config, mac), @@ -1063,7 +1062,7 @@ static int virtnet_probe(struct virtio_device *vdev) return -ENOMEM; /* Set up network device as normal. */ - dev->priv_flags |= IFF_UNICAST_FLT; + dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE; dev->netdev_ops = &virtnet_netdev; dev->features = NETIF_F_HIGHDMA; -- GitLab From 5a1d1c8c78e55df2e876249f8e3a4a573efdbaa6 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 29 Jun 2012 05:10:07 +0000 Subject: [PATCH 3315/6849] team: use IFF_LIVE_ADDR_CHANGE priv_flag Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 89853c31e7f4..9b94f53a9d4b 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1188,10 +1188,11 @@ static int team_set_mac_address(struct net_device *dev, void *p) { struct team *team = netdev_priv(dev); struct team_port *port; - struct sockaddr *addr = p; + int err; - dev->addr_assign_type &= ~NET_ADDR_RANDOM; - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + err = eth_mac_addr(dev, p); + if (err) + return err; rcu_read_lock(); list_for_each_entry_rcu(port, &team->port_list, list) if (team->ops.port_change_mac) @@ -1393,7 +1394,7 @@ static void team_setup(struct net_device *dev) * bring us to promisc mode in case a unicast addr is added. * Let this up to underlay drivers. */ - dev->priv_flags |= IFF_UNICAST_FLT; + dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE; dev->features |= NETIF_F_LLTX; dev->features |= NETIF_F_GRO; -- GitLab From 0d1632b46ad76cde92085aa1ed422e9329443082 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 29 Jun 2012 05:10:08 +0000 Subject: [PATCH 3316/6849] dummy: use IFF_LIVE_ADDR_CHANGE priv_flag Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/dummy.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index bab0158f1cc3..9d6a0677466b 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -40,18 +40,6 @@ static int numdummies = 1; -static int dummy_set_address(struct net_device *dev, void *p) -{ - struct sockaddr *sa = p; - - if (!is_valid_ether_addr(sa->sa_data)) - return -EADDRNOTAVAIL; - - dev->addr_assign_type &= ~NET_ADDR_RANDOM; - memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); - return 0; -} - /* fake multicast ability */ static void set_multicast_list(struct net_device *dev) { @@ -118,7 +106,7 @@ static const struct net_device_ops dummy_netdev_ops = { .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = set_multicast_list, - .ndo_set_mac_address = dummy_set_address, + .ndo_set_mac_address = eth_mac_addr, .ndo_get_stats64 = dummy_get_stats64, }; @@ -134,6 +122,7 @@ static void dummy_setup(struct net_device *dev) dev->tx_queue_len = 0; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; eth_hw_addr_random(dev); -- GitLab From 578f737dd36989121412cf947a5b534e7b8a0ac5 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:13:24 +0200 Subject: [PATCH 3317/6849] iio staging: fix potential resource leak in generic_buffer Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- drivers/staging/iio/Documentation/iio_utils.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 6f3a392297ec..ab788594b202 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -157,7 +157,8 @@ inline int iioutils_get_type(unsigned *is_signed, &padint, shift); if (ret < 0) { printf("failed to pass scan type description\n"); - return ret; + ret = -errno; + goto error_close_sysfsfp; } *be = (endianchar == 'b'); *bytes = padint / 8; @@ -173,7 +174,11 @@ inline int iioutils_get_type(unsigned *is_signed, free(filename); filename = 0; + sysfsfp = 0; } +error_close_sysfsfp: + if (sysfsfp) + fclose(sysfsfp); error_free_filename: if (filename) free(filename); -- GitLab From a4d429e362d873414046c78724f3d6a7978bc2fd Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:13:25 +0200 Subject: [PATCH 3318/6849] iio staging: fix potential memory/resource leaks in find_type_by_name() Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- drivers/staging/iio/Documentation/iio_utils.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index ab788594b202..81a628975cdd 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -472,23 +472,30 @@ inline int find_type_by_name(const char *name, const char *type) + strlen(type) + numstrlen + 6); - if (filename == NULL) + if (filename == NULL) { + closedir(dp); return -ENOMEM; + } sprintf(filename, "%s%s%d/name", iio_dir, type, number); nameFile = fopen(filename, "r"); - if (!nameFile) + if (!nameFile) { + free(filename); continue; + } free(filename); fscanf(nameFile, "%s", thisname); - if (strcmp(name, thisname) == 0) - return number; fclose(nameFile); + if (strcmp(name, thisname) == 0) { + closedir(dp); + return number; + } } } } + closedir(dp); return -ENODEV; } -- GitLab From ce7b04c629254b884baa338730021b01298be921 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 25 Jun 2012 23:13:26 +0200 Subject: [PATCH 3319/6849] iio staging: fix resource leak in _write_sysfs_int() Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- drivers/staging/iio/Documentation/iio_utils.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 81a628975cdd..b38e81f4fa64 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -524,6 +524,7 @@ inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) goto error_free; } fscanf(sysfsfp, "%d", &test); + fclose(sysfsfp); if (test != val) { printf("Possible failure in int write %d to %s%s\n", val, @@ -573,6 +574,7 @@ int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) goto error_free; } fscanf(sysfsfp, "%s", temp); + fclose(sysfsfp); if (strcmp(temp, val) != 0) { printf("Possible failure in string write of %s " "Should be %s " -- GitLab From 05eda67d2c31f3e8d815c3fc14f4dbb612363eab Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 27 Jun 2012 10:58:27 +0200 Subject: [PATCH 3320/6849] staging:iio:ad7793: Fix scan index for the "shorted" channel The code expects the scan index to match the offset of the channel into the channel array. For the "shorted" the offset is 3, but the scan index is set to 2. Also the scan index 2 is already taken by the previous channel. As a result the "shorted" channel will appear to be selected if the previous channel is selected and vice versa and it is not possible to sample the "shorted" channel in buffered mode. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7793.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index b36556fa2957..92d8c255d470 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -786,7 +786,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .address = AD7793_CH_AIN1M_AIN1M, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, - .scan_index = 2, + .scan_index = 3, .scan_type = IIO_ST('s', 24, 32, 0) }, .channel[4] = { @@ -859,7 +859,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .address = AD7793_CH_AIN1M_AIN1M, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, - .scan_index = 2, + .scan_index = 3, .scan_type = IIO_ST('s', 16, 32, 0) }, .channel[4] = { -- GitLab From 467d0becaf52add767e51a6de92c52a91cf546ac Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 10:41:25 +0100 Subject: [PATCH 3321/6849] staging:iio:accel:adis16204 fix bug in channel modifier handling Will result in the correct scale value for the x axis. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/accel/adis16204_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index ac9d95e4ea47..457982bf7eac 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -381,7 +381,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; - if (chan->channel == 'x') + if (chan->channel2 == IIO_MOD_X) *val2 = 17125; else *val2 = 8407; -- GitLab From 06d5199d4c53615338d0453b62458cd82fb88f33 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 12 May 2012 10:01:01 +0100 Subject: [PATCH 3322/6849] staging:iio: Add some missing peak elements to the info_mask These are supported by raw_read but not actually there. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/accel/adis16240_core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 8b15eaea3381..4ba9b1c3bb5a 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -500,7 +500,8 @@ static struct iio_chan_spec adis16240_channels[] = { .channel2 = IIO_MOD_X, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel_x, .scan_index = ADIS16240_SCAN_ACC_X, .scan_type = { @@ -514,7 +515,8 @@ static struct iio_chan_spec adis16240_channels[] = { .channel2 = IIO_MOD_Y, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel_y, .scan_index = ADIS16240_SCAN_ACC_Y, .scan_type = { @@ -528,7 +530,8 @@ static struct iio_chan_spec adis16240_channels[] = { .channel2 = IIO_MOD_Z, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel_z, .scan_index = ADIS16240_SCAN_ACC_Z, .scan_type = { -- GitLab From 8ec4cf5303e03941fa5fd91bbb9c85bd4ae88c47 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 25 Jun 2012 14:52:49 +0200 Subject: [PATCH 3323/6849] iio:adc: Add AD7265/AD7266 support This patch adds support for the Analog Devices AD7265 and AD7266 Analog-to-Digital converters. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad7266.c | 536 +++++++++++++++++++++++++++ include/linux/platform_data/ad7266.h | 54 +++ 4 files changed, 601 insertions(+) create mode 100644 drivers/iio/adc/ad7266.c create mode 100644 include/linux/platform_data/ad7266.h diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 4f7f584cfd61..8a78b4f3ef58 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -3,6 +3,16 @@ # menu "Analog to digital converters" +config AD7266 + tristate "Analog Devices AD7265/AD7266 ADC driver" + depends on SPI_MASTER + select IIO_BUFFER + select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices AD7265 and AD7266 + ADCs. + config AT91_ADC tristate "Atmel AT91 ADC" depends on ARCH_AT91 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 175c8d41ea99..52eec254c38c 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -2,4 +2,5 @@ # Makefile for IIO ADC drivers # +obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c new file mode 100644 index 000000000000..5c3f1ba5a06d --- /dev/null +++ b/drivers/iio/adc/ad7266.c @@ -0,0 +1,536 @@ +/* + * AD7266/65 SPI ADC driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +struct ad7266_state { + struct spi_device *spi; + struct regulator *reg; + unsigned long vref_uv; + + struct spi_transfer single_xfer[3]; + struct spi_message single_msg; + + enum ad7266_range range; + enum ad7266_mode mode; + bool fixed_addr; + struct gpio gpios[3]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * The buffer needs to be large enough to hold two samples (4 bytes) and + * the naturally aligned timestamp (8 bytes). + */ + uint8_t data[ALIGN(4, sizeof(s64)) + sizeof(s64)] ____cacheline_aligned; +}; + +static int ad7266_wakeup(struct ad7266_state *st) +{ + /* Any read with >= 2 bytes will wake the device */ + return spi_read(st->spi, st->data, 2); +} + +static int ad7266_powerdown(struct ad7266_state *st) +{ + /* Any read with < 2 bytes will powerdown the device */ + return spi_read(st->spi, st->data, 1); +} + +static int ad7266_preenable(struct iio_dev *indio_dev) +{ + struct ad7266_state *st = iio_priv(indio_dev); + int ret; + + ret = ad7266_wakeup(st); + if (ret) + return ret; + + ret = iio_sw_buffer_preenable(indio_dev); + if (ret) + ad7266_powerdown(st); + + return ret; +} + +static int ad7266_postdisable(struct iio_dev *indio_dev) +{ + struct ad7266_state *st = iio_priv(indio_dev); + return ad7266_powerdown(st); +} + +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { + .preenable = &ad7266_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, + .postdisable = &ad7266_postdisable, +}; + +static irqreturn_t ad7266_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct iio_buffer *buffer = indio_dev->buffer; + struct ad7266_state *st = iio_priv(indio_dev); + int ret; + + ret = spi_read(st->spi, st->data, 4); + if (ret == 0) { + if (indio_dev->scan_timestamp) + ((s64 *)st->data)[1] = pf->timestamp; + iio_push_to_buffer(buffer, (u8 *)st->data, pf->timestamp); + } + + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static void ad7266_select_input(struct ad7266_state *st, unsigned int nr) +{ + unsigned int i; + + if (st->fixed_addr) + return; + + switch (st->mode) { + case AD7266_MODE_SINGLE_ENDED: + nr >>= 1; + break; + case AD7266_MODE_PSEUDO_DIFF: + nr |= 1; + break; + case AD7266_MODE_DIFF: + nr &= ~1; + break; + } + + for (i = 0; i < 3; ++i) + gpio_set_value(st->gpios[i].gpio, (bool)(nr & BIT(i))); +} + +static int ad7266_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad7266_state *st = iio_priv(indio_dev); + unsigned int nr = find_first_bit(scan_mask, indio_dev->masklength); + + ad7266_select_input(st, nr); + + return 0; +} + +static int ad7266_read_single(struct ad7266_state *st, int *val, + unsigned int address) +{ + int ret; + + ad7266_select_input(st, address); + + ret = spi_sync(st->spi, &st->single_msg); + *val = be16_to_cpu(st->data[address % 2]); + + return ret; +} + +static int ad7266_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long m) +{ + struct ad7266_state *st = iio_priv(indio_dev); + unsigned long scale_uv; + int ret; + + switch (m) { + case IIO_CHAN_INFO_RAW: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + ret = ad7266_read_single(st, val, chan->address); + if (ret) + return ret; + + *val = (*val >> 2) & 0xfff; + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, 11); + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + scale_uv = (st->vref_uv * 100); + if (st->mode == AD7266_MODE_DIFF) + scale_uv *= 2; + if (st->range == AD7266_RANGE_2VREF) + scale_uv *= 2; + + scale_uv >>= chan->scan_type.realbits; + *val = scale_uv / 100000; + *val2 = (scale_uv % 100000) * 10; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_OFFSET: + if (st->range == AD7266_RANGE_2VREF && + st->mode != AD7266_MODE_DIFF) + *val = 2048; + else + *val = 0; + return IIO_VAL_INT; + } + return -EINVAL; +} + +#define AD7266_CHAN(_chan, _sign) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_chan), \ + .address = (_chan), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT \ + | IIO_CHAN_INFO_SCALE_SHARED_BIT \ + | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ + .scan_index = (_chan), \ + .scan_type = { \ + .sign = (_sign), \ + .realbits = 12, \ + .storagebits = 16, \ + .shift = 2, \ + .endianness = IIO_BE, \ + }, \ +} + +#define AD7266_DECLARE_SINGLE_ENDED_CHANNELS(_name, _sign) \ +const struct iio_chan_spec ad7266_channels_##_name[] = { \ + AD7266_CHAN(0, (_sign)), \ + AD7266_CHAN(1, (_sign)), \ + AD7266_CHAN(2, (_sign)), \ + AD7266_CHAN(3, (_sign)), \ + AD7266_CHAN(4, (_sign)), \ + AD7266_CHAN(5, (_sign)), \ + AD7266_CHAN(6, (_sign)), \ + AD7266_CHAN(7, (_sign)), \ + AD7266_CHAN(8, (_sign)), \ + AD7266_CHAN(9, (_sign)), \ + AD7266_CHAN(10, (_sign)), \ + AD7266_CHAN(11, (_sign)), \ + IIO_CHAN_SOFT_TIMESTAMP(13), \ +} + +#define AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(_name, _sign) \ +const struct iio_chan_spec ad7266_channels_##_name##_fixed[] = { \ + AD7266_CHAN(0, (_sign)), \ + AD7266_CHAN(1, (_sign)), \ + IIO_CHAN_SOFT_TIMESTAMP(2), \ +} + +static AD7266_DECLARE_SINGLE_ENDED_CHANNELS(u, 'u'); +static AD7266_DECLARE_SINGLE_ENDED_CHANNELS(s, 's'); +static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(u, 'u'); +static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(s, 's'); + +#define AD7266_CHAN_DIFF(_chan, _sign) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_chan) * 2, \ + .channel2 = (_chan) * 2 + 1, \ + .address = (_chan), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT \ + | IIO_CHAN_INFO_SCALE_SHARED_BIT \ + | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ + .scan_index = (_chan), \ + .scan_type = { \ + .sign = _sign, \ + .realbits = 12, \ + .storagebits = 16, \ + .shift = 2, \ + .endianness = IIO_BE, \ + }, \ + .differential = 1, \ +} + +#define AD7266_DECLARE_DIFF_CHANNELS(_name, _sign) \ +const struct iio_chan_spec ad7266_channels_diff_##_name[] = { \ + AD7266_CHAN_DIFF(0, (_sign)), \ + AD7266_CHAN_DIFF(1, (_sign)), \ + AD7266_CHAN_DIFF(2, (_sign)), \ + AD7266_CHAN_DIFF(3, (_sign)), \ + AD7266_CHAN_DIFF(4, (_sign)), \ + AD7266_CHAN_DIFF(5, (_sign)), \ + IIO_CHAN_SOFT_TIMESTAMP(6), \ +} + +static AD7266_DECLARE_DIFF_CHANNELS(s, 's'); +static AD7266_DECLARE_DIFF_CHANNELS(u, 'u'); + +#define AD7266_DECLARE_DIFF_CHANNELS_FIXED(_name, _sign) \ +const struct iio_chan_spec ad7266_channels_diff_fixed_##_name[] = { \ + AD7266_CHAN_DIFF(0, (_sign)), \ + AD7266_CHAN_DIFF(1, (_sign)), \ + IIO_CHAN_SOFT_TIMESTAMP(2), \ +} + +static AD7266_DECLARE_DIFF_CHANNELS_FIXED(s, 's'); +static AD7266_DECLARE_DIFF_CHANNELS_FIXED(u, 'u'); + +static const struct iio_info ad7266_info = { + .read_raw = &ad7266_read_raw, + .update_scan_mode = &ad7266_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static unsigned long ad7266_available_scan_masks[] = { + 0x003, + 0x00c, + 0x030, + 0x0c0, + 0x300, + 0xc00, + 0x000, +}; + +static unsigned long ad7266_available_scan_masks_diff[] = { + 0x003, + 0x00c, + 0x030, + 0x000, +}; + +static unsigned long ad7266_available_scan_masks_fixed[] = { + 0x003, + 0x000, +}; + +struct ad7266_chan_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; + unsigned long *scan_masks; +}; + +#define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \ + (((_differential) << 2) | ((_signed) << 1) | ((_fixed) << 0)) + +static const struct ad7266_chan_info ad7266_chan_infos[] = { + [AD7266_CHAN_INFO_INDEX(0, 0, 0)] = { + .channels = ad7266_channels_u, + .num_channels = ARRAY_SIZE(ad7266_channels_u), + .scan_masks = ad7266_available_scan_masks, + }, + [AD7266_CHAN_INFO_INDEX(0, 0, 1)] = { + .channels = ad7266_channels_u_fixed, + .num_channels = ARRAY_SIZE(ad7266_channels_u_fixed), + .scan_masks = ad7266_available_scan_masks_fixed, + }, + [AD7266_CHAN_INFO_INDEX(0, 1, 0)] = { + .channels = ad7266_channels_s, + .num_channels = ARRAY_SIZE(ad7266_channels_s), + .scan_masks = ad7266_available_scan_masks, + }, + [AD7266_CHAN_INFO_INDEX(0, 1, 1)] = { + .channels = ad7266_channels_s_fixed, + .num_channels = ARRAY_SIZE(ad7266_channels_s_fixed), + .scan_masks = ad7266_available_scan_masks_fixed, + }, + [AD7266_CHAN_INFO_INDEX(1, 0, 0)] = { + .channels = ad7266_channels_diff_u, + .num_channels = ARRAY_SIZE(ad7266_channels_diff_u), + .scan_masks = ad7266_available_scan_masks_diff, + }, + [AD7266_CHAN_INFO_INDEX(1, 0, 1)] = { + .channels = ad7266_channels_diff_fixed_u, + .num_channels = ARRAY_SIZE(ad7266_channels_diff_fixed_u), + .scan_masks = ad7266_available_scan_masks_fixed, + }, + [AD7266_CHAN_INFO_INDEX(1, 1, 0)] = { + .channels = ad7266_channels_diff_s, + .num_channels = ARRAY_SIZE(ad7266_channels_diff_s), + .scan_masks = ad7266_available_scan_masks_diff, + }, + [AD7266_CHAN_INFO_INDEX(1, 1, 1)] = { + .channels = ad7266_channels_diff_fixed_s, + .num_channels = ARRAY_SIZE(ad7266_channels_diff_fixed_s), + .scan_masks = ad7266_available_scan_masks_fixed, + }, +}; + +static void __devinit ad7266_init_channels(struct iio_dev *indio_dev) +{ + struct ad7266_state *st = iio_priv(indio_dev); + bool is_differential, is_signed; + const struct ad7266_chan_info *chan_info; + int i; + + is_differential = st->mode != AD7266_MODE_SINGLE_ENDED; + is_signed = (st->range == AD7266_RANGE_2VREF) | + (st->mode == AD7266_MODE_DIFF); + + i = AD7266_CHAN_INFO_INDEX(is_differential, is_signed, st->fixed_addr); + chan_info = &ad7266_chan_infos[i]; + + indio_dev->channels = chan_info->channels; + indio_dev->num_channels = chan_info->num_channels; + indio_dev->available_scan_masks = chan_info->scan_masks; + indio_dev->masklength = chan_info->num_channels - 1; +} + +static const char * const ad7266_gpio_labels[] = { + "AD0", "AD1", "AD2", +}; + +static int __devinit ad7266_probe(struct spi_device *spi) +{ + struct ad7266_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct ad7266_state *st; + unsigned int i; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vref"); + if (!IS_ERR_OR_NULL(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + st->vref_uv = regulator_get_voltage(st->reg); + } else { + /* Use internal reference */ + st->vref_uv = 2500000; + } + + if (pdata) { + st->fixed_addr = pdata->fixed_addr; + st->mode = pdata->mode; + st->range = pdata->range; + + if (!st->fixed_addr) { + for (i = 0; i < ARRAY_SIZE(st->gpios); ++i) { + st->gpios[i].gpio = pdata->addr_gpios[i]; + st->gpios[i].flags = GPIOF_OUT_INIT_LOW; + st->gpios[i].label = ad7266_gpio_labels[i]; + } + ret = gpio_request_array(st->gpios, + ARRAY_SIZE(st->gpios)); + if (ret) + goto error_disable_reg; + } + } else { + st->fixed_addr = true; + st->range = AD7266_RANGE_VREF; + st->mode = AD7266_MODE_DIFF; + } + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad7266_info; + + ad7266_init_channels(indio_dev); + + /* wakeup */ + st->single_xfer[0].rx_buf = &st->data; + st->single_xfer[0].len = 2; + st->single_xfer[0].cs_change = 1; + /* conversion */ + st->single_xfer[1].rx_buf = &st->data; + st->single_xfer[1].len = 4; + st->single_xfer[1].cs_change = 1; + /* powerdown */ + st->single_xfer[2].tx_buf = &st->data; + st->single_xfer[2].len = 1; + + spi_message_init(&st->single_msg); + spi_message_add_tail(&st->single_xfer[0], &st->single_msg); + spi_message_add_tail(&st->single_xfer[1], &st->single_msg); + spi_message_add_tail(&st->single_xfer[2], &st->single_msg); + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad7266_trigger_handler, &iio_triggered_buffer_setup_ops); + if (ret) + goto error_free_gpios; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_buffer_cleanup; + + return 0; + +error_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); +error_free_gpios: + if (!st->fixed_addr) + gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios)); +error_disable_reg: + if (!IS_ERR_OR_NULL(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR_OR_NULL(st->reg)) + regulator_put(st->reg); + + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad7266_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7266_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + if (!st->fixed_addr) + gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios)); + if (!IS_ERR_OR_NULL(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7266_id[] = { + {"ad7265", 0}, + {"ad7266", 0}, + { } +}; +MODULE_DEVICE_TABLE(spi, ad7266_id); + +static struct spi_driver ad7266_driver = { + .driver = { + .name = "ad7266", + .owner = THIS_MODULE, + }, + .probe = ad7266_probe, + .remove = __devexit_p(ad7266_remove), + .id_table = ad7266_id, +}; +module_spi_driver(ad7266_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices AD7266/65 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/ad7266.h b/include/linux/platform_data/ad7266.h new file mode 100644 index 000000000000..eabfdcb26992 --- /dev/null +++ b/include/linux/platform_data/ad7266.h @@ -0,0 +1,54 @@ +/* + * AD7266/65 SPI ADC driver + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef __IIO_ADC_AD7266_H__ +#define __IIO_ADC_AD7266_H__ + +/** + * enum ad7266_range - AD7266 reference voltage range + * @AD7266_RANGE_VREF: Device is configured for input range 0V - VREF + * (RANGE pin set to low) + * @AD7266_RANGE_2VREF: Device is configured for input range 0V - 2VREF + * (RANGE pin set to high) + */ +enum ad7266_range { + AD7266_RANGE_VREF, + AD7266_RANGE_2VREF, +}; + +/** + * enum ad7266_mode - AD7266 sample mode + * @AD7266_MODE_DIFF: Device is configured for full differential mode + * (SGL/DIFF pin set to low, AD0 pin set to low) + * @AD7266_MODE_PSEUDO_DIFF: Device is configured for pseudo differential mode + * (SGL/DIFF pin set to low, AD0 pin set to high) + * @AD7266_MODE_SINGLE_ENDED: Device is configured for single-ended mode + * (SGL/DIFF pin set to high) + */ +enum ad7266_mode { + AD7266_MODE_DIFF, + AD7266_MODE_PSEUDO_DIFF, + AD7266_MODE_SINGLE_ENDED, +}; + +/** + * struct ad7266_platform_data - Platform data for the AD7266 driver + * @range: Reference voltage range the device is configured for + * @mode: Sample mode the device is configured for + * @fixed_addr: Whether the address pins are hard-wired + * @addr_gpios: GPIOs used for controlling the address pins, only used if + * fixed_addr is set to false. + */ +struct ad7266_platform_data { + enum ad7266_range range; + enum ad7266_mode mode; + bool fixed_addr; + unsigned int addr_gpios[3]; +}; + +#endif -- GitLab From 6a17a0768f77626046aa441843b318a00bac3800 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 26 Jun 2012 11:04:36 +0200 Subject: [PATCH 3324/6849] iio:dac:ad5064: Add support for the ad5629r and ad5669r The ad5629r and ad5669r are the I2C variants of the ad5628 and ad5668. Since the ad5064 driver currently only supports SPI based devices the major part of this patch focuses on adding support for I2C based devices. Adding support for the actual parts boils down to adding entries for them to the device id table. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/Kconfig | 8 +- drivers/iio/dac/ad5064.c | 200 +++++++++++++++++++++++++++++++++------ 2 files changed, 173 insertions(+), 35 deletions(-) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index afd207e171cf..1be15fa9d618 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -4,12 +4,12 @@ menu "Digital to analog converters" config AD5064 - tristate "Analog Devices AD5064/64-1/65/44/45/24/25, AD5628/48/66/68 DAC driver" - depends on SPI + tristate "Analog Devices AD5064 and similar multi-channel DAC driver" + depends on (SPI_MASTER || I2C) help Say yes here to build support for Analog Devices AD5024, AD5025, AD5044, - AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648, AD5666, AD5668 Digital - to Analog Converter. + AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, AD5648, AD5666, AD5668, + AD5669R Digital to Analog Converter. To compile this driver as a module, choose M here: the module will be called ad5064. diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 276af02520af..aa739c497f2b 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -1,6 +1,6 @@ /* - * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648, - * AD5666, AD5668 Digital to analog converters driver + * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, + * AD5648, AD5666, AD5668, AD5669R Digital to analog converters driver * * Copyright 2011 Analog Devices Inc. * @@ -12,9 +12,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -62,9 +64,14 @@ struct ad5064_chip_info { unsigned int num_channels; }; +struct ad5064_state; + +typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd, + unsigned int addr, unsigned int val); + /** * struct ad5064_state - driver instance specific data - * @spi: spi_device + * @dev: the device for this driver instance * @chip_info: chip model specific constants, available modes etc * @vref_reg: vref supply regulators * @pwr_down: whether channel is powered down @@ -72,11 +79,12 @@ struct ad5064_chip_info { * @dac_cache: current DAC raw value (chip does not support readback) * @use_internal_vref: set to true if the internal reference voltage should be * used. - * @data: spi transfer buffers + * @write: register write callback + * @data: i2c/spi transfer buffers */ struct ad5064_state { - struct spi_device *spi; + struct device *dev; const struct ad5064_chip_info *chip_info; struct regulator_bulk_data vref_reg[AD5064_MAX_VREFS]; bool pwr_down[AD5064_MAX_DAC_CHANNELS]; @@ -84,11 +92,16 @@ struct ad5064_state { unsigned int dac_cache[AD5064_MAX_DAC_CHANNELS]; bool use_internal_vref; + ad5064_write_func write; + /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ - __be32 data ____cacheline_aligned; + union { + u8 i2c[3]; + __be32 spi; + } data ____cacheline_aligned; }; enum ad5064_type { @@ -109,14 +122,31 @@ enum ad5064_type { ID_AD5668_2, }; +static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd, + unsigned int addr, unsigned int val) +{ + struct i2c_client *i2c = to_i2c_client(st->dev); + + st->data.i2c[0] = (cmd << 4) | addr; + put_unaligned_be16(val, &st->data.i2c[1]); + return i2c_master_send(i2c, st->data.i2c, 3); +} + static int ad5064_spi_write(struct ad5064_state *st, unsigned int cmd, + unsigned int addr, unsigned int val) +{ + struct spi_device *spi = to_spi_device(st->dev); + + st->data.spi = cpu_to_be32(AD5064_CMD(cmd) | AD5064_ADDR(addr) | val); + return spi_write(spi, &st->data.spi, sizeof(st->data.spi)); +} + +static int ad5064_write(struct ad5064_state *st, unsigned int cmd, unsigned int addr, unsigned int val, unsigned int shift) { val <<= shift; - st->data = cpu_to_be32(AD5064_CMD(cmd) | AD5064_ADDR(addr) | val); - - return spi_write(st->spi, &st->data, sizeof(st->data)); + return st->write(st, cmd, addr, val); } static int ad5064_sync_powerdown_mode(struct ad5064_state *st, @@ -130,7 +160,7 @@ static int ad5064_sync_powerdown_mode(struct ad5064_state *st, if (st->pwr_down[channel]) val |= st->pwr_down_mode[channel] << 8; - ret = ad5064_spi_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0); + ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0); return ret; } @@ -251,7 +281,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev, return -EINVAL; mutex_lock(&indio_dev->mlock); - ret = ad5064_spi_write(st, AD5064_CMD_WRITE_INPUT_N_UPDATE_N, + ret = ad5064_write(st, AD5064_CMD_WRITE_INPUT_N_UPDATE_N, chan->address, val, chan->scan_type.shift); if (ret == 0) st->dac_cache[chan->channel] = val; @@ -413,9 +443,9 @@ static const char * const ad5064_vref_name(struct ad5064_state *st, return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref]; } -static int __devinit ad5064_probe(struct spi_device *spi) +static int __devinit ad5064_probe(struct device *dev, enum ad5064_type type, + const char *name, ad5064_write_func write) { - enum ad5064_type type = spi_get_device_id(spi)->driver_data; struct iio_dev *indio_dev; struct ad5064_state *st; unsigned int i; @@ -426,24 +456,25 @@ static int __devinit ad5064_probe(struct spi_device *spi) return -ENOMEM; st = iio_priv(indio_dev); - spi_set_drvdata(spi, indio_dev); + dev_set_drvdata(dev, indio_dev); st->chip_info = &ad5064_chip_info_tbl[type]; - st->spi = spi; + st->dev = dev; + st->write = write; for (i = 0; i < ad5064_num_vref(st); ++i) st->vref_reg[i].supply = ad5064_vref_name(st, i); - ret = regulator_bulk_get(&st->spi->dev, ad5064_num_vref(st), + ret = regulator_bulk_get(dev, ad5064_num_vref(st), st->vref_reg); if (ret) { if (!st->chip_info->internal_vref) goto error_free; st->use_internal_vref = true; - ret = ad5064_spi_write(st, AD5064_CMD_CONFIG, 0, + ret = ad5064_write(st, AD5064_CMD_CONFIG, 0, AD5064_CONFIG_INT_VREF_ENABLE, 0); if (ret) { - dev_err(&spi->dev, "Failed to enable internal vref: %d\n", + dev_err(dev, "Failed to enable internal vref: %d\n", ret); goto error_free; } @@ -458,8 +489,8 @@ static int __devinit ad5064_probe(struct spi_device *spi) st->dac_cache[i] = 0x8000; } - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = dev; + indio_dev->name = name; indio_dev->info = &ad5064_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = st->chip_info->channels; @@ -483,10 +514,9 @@ error_free: return ret; } - -static int __devexit ad5064_remove(struct spi_device *spi) +static int __devexit ad5064_remove(struct device *dev) { - struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5064_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); @@ -501,7 +531,22 @@ static int __devexit ad5064_remove(struct spi_device *spi) return 0; } -static const struct spi_device_id ad5064_id[] = { +#if IS_ENABLED(CONFIG_SPI_MASTER) + +static int __devinit ad5064_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + + return ad5064_probe(&spi->dev, id->driver_data, id->name, + ad5064_spi_write); +} + +static int __devexit ad5064_spi_remove(struct spi_device *spi) +{ + return ad5064_remove(&spi->dev); +} + +static const struct spi_device_id ad5064_spi_ids[] = { {"ad5024", ID_AD5024}, {"ad5025", ID_AD5025}, {"ad5044", ID_AD5044}, @@ -520,19 +565,112 @@ static const struct spi_device_id ad5064_id[] = { {"ad5668-3", ID_AD5668_2}, /* similar enough to ad5668-2 */ {} }; -MODULE_DEVICE_TABLE(spi, ad5064_id); +MODULE_DEVICE_TABLE(spi, ad5064_spi_ids); -static struct spi_driver ad5064_driver = { +static struct spi_driver ad5064_spi_driver = { .driver = { .name = "ad5064", .owner = THIS_MODULE, }, - .probe = ad5064_probe, - .remove = __devexit_p(ad5064_remove), - .id_table = ad5064_id, + .probe = ad5064_spi_probe, + .remove = __devexit_p(ad5064_spi_remove), + .id_table = ad5064_spi_ids, }; -module_spi_driver(ad5064_driver); + +static int __init ad5064_spi_register_driver(void) +{ + return spi_register_driver(&ad5064_spi_driver); +} + +static void __exit ad5064_spi_unregister_driver(void) +{ + spi_unregister_driver(&ad5064_spi_driver); +} + +#else + +static inline int ad5064_spi_register_driver(void) { return 0; } +static inline void ad5064_spi_unregister_driver(void) { } + +#endif + +#if IS_ENABLED(CONFIG_I2C) + +static int __devinit ad5064_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + return ad5064_probe(&i2c->dev, id->driver_data, id->name, + ad5064_i2c_write); +} + +static int __devexit ad5064_i2c_remove(struct i2c_client *i2c) +{ + return ad5064_remove(&i2c->dev); +} + +static const struct i2c_device_id ad5064_i2c_ids[] = { + {"ad5629-1", ID_AD5628_1}, + {"ad5629-2", ID_AD5628_2}, + {"ad5629-3", ID_AD5628_2}, /* similar enough to ad5629-2 */ + {"ad5669-1", ID_AD5668_1}, + {"ad5669-2", ID_AD5668_2}, + {"ad5669-3", ID_AD5668_2}, /* similar enough to ad5669-2 */ + {} +}; +MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids); + +static struct i2c_driver ad5064_i2c_driver = { + .driver = { + .name = "ad5064", + .owner = THIS_MODULE, + }, + .probe = ad5064_i2c_probe, + .remove = __devexit_p(ad5064_i2c_remove), + .id_table = ad5064_i2c_ids, +}; + +static int __init ad5064_i2c_register_driver(void) +{ + return i2c_add_driver(&ad5064_i2c_driver); +} + +static void __exit ad5064_i2c_unregister_driver(void) +{ + i2c_del_driver(&ad5064_i2c_driver); +} + +#else + +static inline int ad5064_i2c_register_driver(void) { return 0; } +static inline void ad5064_i2c_unregister_driver(void) { } + +#endif + +static int __init ad5064_init(void) +{ + int ret; + + ret = ad5064_spi_register_driver(); + if (ret) + return ret; + + ret = ad5064_i2c_register_driver(); + if (ret) { + ad5064_spi_unregister_driver(); + return ret; + } + + return 0; +} +module_init(ad5064_init); + +static void __exit ad5064_exit(void) +{ + ad5064_i2c_unregister_driver(); + ad5064_spi_unregister_driver(); +} +module_exit(ad5064_exit); MODULE_AUTHOR("Lars-Peter Clausen "); -MODULE_DESCRIPTION("Analog Devices AD5024/25/44/45/64/64-1/65, AD5628/48/66/68 DAC"); +MODULE_DESCRIPTION("Analog Devices AD5024 and similar multi-channel DACs"); MODULE_LICENSE("GPL v2"); -- GitLab From 314be14bb89369b2164125b0ec3b24d85b407b62 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 1 May 2012 21:04:24 +0100 Subject: [PATCH 3325/6849] iio: Rename _st_ functions to loose the bit that meant the staging version. These were originally introduced when the plan was to have parallel IIO cores in and out of staging with a slow move between them. Now we have reached the point where the whole core has moved, they need clearing up! Signed-off-by: Jonathan Cameron --- drivers/iio/inkern.c | 33 +++++++++++++++----------------- drivers/staging/iio/iio_hwmon.c | 12 ++++++------ include/linux/iio/consumer.h | 34 ++++++++++++++++----------------- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index d4760bd1e9b1..9a46ca61ef02 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -92,8 +92,7 @@ error_ret: EXPORT_SYMBOL_GPL(iio_map_array_unregister); static const struct iio_chan_spec -*iio_chan_spec_from_name(const struct iio_dev *indio_dev, - const char *name) +*iio_chan_spec_from_name(const struct iio_dev *indio_dev, const char *name) { int i; const struct iio_chan_spec *chan = NULL; @@ -108,8 +107,7 @@ static const struct iio_chan_spec } -struct iio_channel *iio_st_channel_get(const char *name, - const char *channel_name) +struct iio_channel *iio_channel_get(const char *name, const char *channel_name) { struct iio_map_internal *c_i = NULL, *c = NULL; struct iio_channel *channel; @@ -145,16 +143,16 @@ struct iio_channel *iio_st_channel_get(const char *name, return channel; } -EXPORT_SYMBOL_GPL(iio_st_channel_get); +EXPORT_SYMBOL_GPL(iio_channel_get); -void iio_st_channel_release(struct iio_channel *channel) +void iio_channel_release(struct iio_channel *channel) { iio_device_put(channel->indio_dev); kfree(channel); } -EXPORT_SYMBOL_GPL(iio_st_channel_release); +EXPORT_SYMBOL_GPL(iio_channel_release); -struct iio_channel *iio_st_channel_get_all(const char *name) +struct iio_channel *iio_channel_get_all(const char *name) { struct iio_channel *chans; struct iio_map_internal *c = NULL; @@ -217,9 +215,9 @@ error_ret: return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(iio_st_channel_get_all); +EXPORT_SYMBOL_GPL(iio_channel_get_all); -void iio_st_channel_release_all(struct iio_channel *channels) +void iio_channel_release_all(struct iio_channel *channels) { struct iio_channel *chan = &channels[0]; @@ -229,9 +227,9 @@ void iio_st_channel_release_all(struct iio_channel *channels) } kfree(channels); } -EXPORT_SYMBOL_GPL(iio_st_channel_release_all); +EXPORT_SYMBOL_GPL(iio_channel_release_all); -int iio_st_read_channel_raw(struct iio_channel *chan, int *val) +int iio_read_channel_raw(struct iio_channel *chan, int *val) { int val2, ret; @@ -248,9 +246,9 @@ err_unlock: return ret; } -EXPORT_SYMBOL_GPL(iio_st_read_channel_raw); +EXPORT_SYMBOL_GPL(iio_read_channel_raw); -int iio_st_read_channel_scale(struct iio_channel *chan, int *val, int *val2) +int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2) { int ret; @@ -269,10 +267,9 @@ err_unlock: return ret; } -EXPORT_SYMBOL_GPL(iio_st_read_channel_scale); +EXPORT_SYMBOL_GPL(iio_read_channel_scale); -int iio_st_get_channel_type(struct iio_channel *chan, - enum iio_chan_type *type) +int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type) { int ret = 0; /* Need to verify underlying driver has not gone away */ @@ -289,4 +286,4 @@ err_unlock: return ret; } -EXPORT_SYMBOL_GPL(iio_st_get_channel_type); +EXPORT_SYMBOL_GPL(iio_get_channel_type); diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index b03554fee443..27d27ec9521f 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -51,12 +51,12 @@ static ssize_t iio_hwmon_read_val(struct device *dev, * No locking between this pair, so theoretically possible * the scale has changed. */ - ret = iio_st_read_channel_raw(&state->channels[sattr->index], + ret = iio_read_channel_raw(&state->channels[sattr->index], &val); if (ret < 0) return ret; - ret = iio_st_read_channel_scale(&state->channels[sattr->index], + ret = iio_read_channel_scale(&state->channels[sattr->index], &scaleint, &scalepart); if (ret < 0) return ret; @@ -106,7 +106,7 @@ static int __devinit iio_hwmon_probe(struct platform_device *pdev) goto error_ret; } - st->channels = iio_st_channel_get_all(dev_name(&pdev->dev)); + st->channels = iio_channel_get_all(dev_name(&pdev->dev)); if (IS_ERR(st->channels)) { ret = PTR_ERR(st->channels); goto error_free_state; @@ -130,7 +130,7 @@ static int __devinit iio_hwmon_probe(struct platform_device *pdev) } sysfs_attr_init(&a->dev_attr.attr); - ret = iio_st_get_channel_type(&st->channels[i], &type); + ret = iio_get_channel_type(&st->channels[i], &type); if (ret < 0) { kfree(a); goto error_free_attrs; @@ -186,7 +186,7 @@ error_free_attrs: iio_hwmon_free_attrs(st); kfree(st->attrs); error_release_channels: - iio_st_channel_release_all(st->channels); + iio_channel_release_all(st->channels); error_free_state: kfree(st); error_ret: @@ -201,7 +201,7 @@ static int __devexit iio_hwmon_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &st->attr_group); iio_hwmon_free_attrs(st); kfree(st->attrs); - iio_st_channel_release_all(st->channels); + iio_channel_release_all(st->channels); return 0; } diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 1a15e560a5a1..e2657e6d4d26 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -33,17 +33,17 @@ struct iio_channel { * side. This typically describes the channels use within * the consumer. E.g. 'battery_voltage' */ -struct iio_channel *iio_st_channel_get(const char *name, - const char *consumer_channel); +struct iio_channel *iio_channel_get(const char *name, + const char *consumer_channel); /** - * iio_st_channel_release() - release channels obtained via iio_st_channel_get + * iio_channel_release() - release channels obtained via iio_channel_get * @chan: The channel to be released. */ -void iio_st_channel_release(struct iio_channel *chan); +void iio_channel_release(struct iio_channel *chan); /** - * iio_st_channel_get_all() - get all channels associated with a client + * iio_channel_get_all() - get all channels associated with a client * @name: name of consumer device. * * Returns an array of iio_channel structures terminated with one with @@ -51,37 +51,37 @@ void iio_st_channel_release(struct iio_channel *chan); * This function is used by fairly generic consumers to get all the * channels registered as having this consumer. */ -struct iio_channel *iio_st_channel_get_all(const char *name); +struct iio_channel *iio_channel_get_all(const char *name); /** - * iio_st_channel_release_all() - reverse iio_st_get_all + * iio_channel_release_all() - reverse iio_channel_get_all * @chan: Array of channels to be released. */ -void iio_st_channel_release_all(struct iio_channel *chan); +void iio_channel_release_all(struct iio_channel *chan); /** - * iio_st_read_channel_raw() - read from a given channel + * iio_read_channel_raw() - read from a given channel * @channel: The channel being queried. * @val: Value read back. * * Note raw reads from iio channels are in adc counts and hence * scale will need to be applied if standard units required. */ -int iio_st_read_channel_raw(struct iio_channel *chan, - int *val); +int iio_read_channel_raw(struct iio_channel *chan, + int *val); /** - * iio_st_get_channel_type() - get the type of a channel + * iio_get_channel_type() - get the type of a channel * @channel: The channel being queried. * @type: The type of the channel. * * returns the enum iio_chan_type of the channel */ -int iio_st_get_channel_type(struct iio_channel *channel, - enum iio_chan_type *type); +int iio_get_channel_type(struct iio_channel *channel, + enum iio_chan_type *type); /** - * iio_st_read_channel_scale() - read the scale value for a channel + * iio_read_channel_scale() - read the scale value for a channel * @channel: The channel being queried. * @val: First part of value read back. * @val2: Second part of value read back. @@ -90,7 +90,7 @@ int iio_st_get_channel_type(struct iio_channel *channel, * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val * + val2/1e6 */ -int iio_st_read_channel_scale(struct iio_channel *chan, int *val, - int *val2); +int iio_read_channel_scale(struct iio_channel *chan, int *val, + int *val2); #endif -- GitLab From 13d947db1c8e4e5c2114e809beef97ddf41b7006 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 09:16:08 +0100 Subject: [PATCH 3326/6849] staging:iio:accel drop sysfs interface for resetting devices. There is no reason why userspace should want to do this manually. Hence, lets drop this abi. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/accel/adis16201_core.c | 27 -------------------- drivers/staging/iio/accel/adis16203_core.c | 28 --------------------- drivers/staging/iio/accel/adis16204_core.c | 20 --------------- drivers/staging/iio/accel/adis16209_core.c | 29 ---------------------- drivers/staging/iio/accel/adis16220_core.c | 24 ------------------ drivers/staging/iio/accel/adis16240_core.c | 20 --------------- 6 files changed, 148 deletions(-) diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 02b340919c0e..204106b72d24 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -159,21 +159,6 @@ static int adis16201_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16201_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - int ret; - bool res; - - if (len < 1) - return -EINVAL; - ret = strtobool(buf, &res); - if (ret || !res) - return ret; - return adis16201_reset(dev_to_iio_dev(dev)); -} - int adis16201_set_irq(struct iio_dev *indio_dev, bool enable) { int ret = 0; @@ -507,19 +492,7 @@ static struct iio_chan_spec adis16201_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(7) }; -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0); - -static struct attribute *adis16201_attributes[] = { - &iio_dev_attr_reset.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16201_attribute_group = { - .attrs = adis16201_attributes, -}; - static const struct iio_info adis16201_info = { - .attrs = &adis16201_attribute_group, .read_raw = &adis16201_read_raw, .write_raw = &adis16201_write_raw, .driver_module = THIS_MODULE, diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 15d46bfd1b42..22085e9dfd16 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -178,22 +178,6 @@ static int adis16203_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16203_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - if (len < 1) - return -EINVAL; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16203_reset(indio_dev); - } - return -EINVAL; -} - int adis16203_set_irq(struct iio_dev *indio_dev, bool enable) { int ret = 0; @@ -444,19 +428,7 @@ static struct iio_chan_spec adis16203_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(5), }; -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0); - -static struct attribute *adis16203_attributes[] = { - &iio_dev_attr_reset.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16203_attribute_group = { - .attrs = adis16203_attributes, -}; - static const struct iio_info adis16203_info = { - .attrs = &adis16203_attribute_group, .read_raw = &adis16203_read_raw, .write_raw = &adis16203_write_raw, .driver_module = THIS_MODULE, diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 457982bf7eac..685fa925d9df 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -207,23 +207,6 @@ static int adis16204_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16204_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - - if (len < 1) - return -EINVAL; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16204_reset(indio_dev); - } - return -EINVAL; -} - int adis16204_set_irq(struct iio_dev *indio_dev, bool enable) { int ret = 0; @@ -310,8 +293,6 @@ static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed, ADIS16204_XY_PEAK_OUT); static IIO_CONST_ATTR(in_accel_xy_scale, "0.017125"); -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0); - enum adis16204_channel { in_supply, in_aux, @@ -520,7 +501,6 @@ static struct iio_chan_spec adis16204_channels[] = { }; static struct attribute *adis16204_attributes[] = { - &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_in_accel_xy.dev_attr.attr, &iio_dev_attr_in_accel_xypeak.dev_attr.attr, &iio_const_attr_in_accel_xy_scale.dev_attr.attr, diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 6fc426e27e4e..494570508c36 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -153,23 +153,6 @@ static int adis16209_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16209_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - - if (len < 1) - return -EINVAL; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16209_reset(indio_dev); - } - return -EINVAL; -} - int adis16209_set_irq(struct iio_dev *indio_dev, bool enable) { int ret = 0; @@ -519,19 +502,7 @@ static struct iio_chan_spec adis16209_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(8) }; -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0); - -static struct attribute *adis16209_attributes[] = { - &iio_dev_attr_reset.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16209_attribute_group = { - .attrs = adis16209_attributes, -}; - static const struct iio_info adis16209_info = { - .attrs = &adis16209_attribute_group, .read_raw = &adis16209_read_raw, .write_raw = &adis16209_write_raw, .driver_module = THIS_MODULE, diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index af5c57637166..575f1af25d5d 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -204,26 +204,6 @@ static int adis16220_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16220_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - bool val; - int ret; - - ret = strtobool(buf, &val); - if (ret) - return ret; - if (!val) - return -EINVAL; - - ret = adis16220_reset(indio_dev); - if (ret) - return ret; - return len; -} - static ssize_t adis16220_write_capture(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) @@ -454,9 +434,6 @@ static struct bin_attribute adc2_bin = { .size = ADIS16220_CAPTURE_SIZE, }; -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, - adis16220_write_reset, 0); - #define IIO_DEV_ATTR_CAPTURE(_store) \ IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0) @@ -611,7 +588,6 @@ static const struct iio_chan_spec adis16220_channels[] = { }; static struct attribute *adis16220_attributes[] = { - &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_capture.dev_attr.attr, &iio_dev_attr_capture_count.dev_attr.attr, NULL diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 1a51f03d3d76..b30b7874ffb0 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -199,23 +199,6 @@ static int adis16240_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16240_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - - if (len < 1) - return -EINVAL; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16240_reset(indio_dev); - } - return -EINVAL; -} - int adis16240_set_irq(struct iio_dev *indio_dev, bool enable) { int ret = 0; @@ -329,8 +312,6 @@ static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, S_IRUGO, adis16240_read_12bit_signed, NULL, ADIS16240_XYZPEAK_OUT); -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0); - static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096"); enum adis16240_chan { @@ -559,7 +540,6 @@ static struct iio_chan_spec adis16240_channels[] = { static struct attribute *adis16240_attributes[] = { &iio_dev_attr_in_accel_xyz_squared_peak_raw.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_reset.dev_attr.attr, NULL }; -- GitLab From 15a1a7530c3c411adbd9aed05f7bb43fbe9816c4 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 09:19:09 +0100 Subject: [PATCH 3327/6849] staging:iio:gyro:adis16260 drop sysfs interface for manual device reset. There is no reason for userspace to do this, so lets drop this abi. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/gyro/adis16260_core.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index fdb84cc3d7c9..f16b3938928f 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -233,22 +233,6 @@ static int adis16260_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16260_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - if (len < 1) - return -EINVAL; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16260_reset(indio_dev); - } - return -EINVAL; -} - int adis16260_set_irq(struct iio_dev *indio_dev, bool enable) { int ret; @@ -375,8 +359,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, adis16260_read_frequency, adis16260_write_frequency); -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0); - static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, adis16260_read_frequency_available, NULL, 0); @@ -604,7 +586,6 @@ static int adis16260_write_raw(struct iio_dev *indio_dev, static struct attribute *adis16260_attributes[] = { &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_dev_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_reset.dev_attr.attr, NULL }; -- GitLab From 07c7f79ee1c7e6288c614ba88005a8de6dbaadff Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 09:17:12 +0100 Subject: [PATCH 3328/6849] staging:iio:imu:adis16400 drop sysfs interface for manual device reset. There is no reason for userspace to do this, so lets drop this abi. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/imu/adis16400_core.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 387301437cf5..1f4c17779b5a 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -268,25 +268,6 @@ static int adis16400_reset(struct iio_dev *indio_dev) return ret; } -static ssize_t adis16400_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - bool val; - int ret; - - ret = strtobool(buf, &val); - if (ret < 0) - return ret; - if (val) { - ret = adis16400_reset(dev_to_iio_dev(dev)); - if (ret < 0) - return ret; - } - - return len; -} - int adis16400_set_irq(struct iio_dev *indio_dev, bool enable) { int ret; @@ -454,8 +435,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, adis16400_read_frequency, adis16400_write_frequency); -static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0); - static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638"); enum adis16400_chan { @@ -1066,7 +1045,6 @@ static const struct iio_chan_spec adis16334_channels[] = { static struct attribute *adis16400_attributes[] = { &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_reset.dev_attr.attr, NULL }; -- GitLab From 8f5879b20be7f918cdc4b3d831cfd8f3dc02c74c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 10:39:22 +0100 Subject: [PATCH 3329/6849] IIO: Add a modifier for sqrt(x^2+y^2) There will probably be a number of such modifiers eventually but this one is used in the adis16204 accelerometer driver. Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 1 + include/linux/iio/types.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index a5a446beb2fa..e42749ec5c3c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -70,6 +70,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_X] = "x", [IIO_MOD_Y] = "y", [IIO_MOD_Z] = "z", + [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", [IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_IR] = "ir", }; diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index d086736a9033..210559ddf8a3 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -44,6 +44,7 @@ enum iio_modifier { IIO_MOD_X_OR_Y_OR_Z, IIO_MOD_LIGHT_BOTH, IIO_MOD_LIGHT_IR, + IIO_MOD_ROOT_SUM_SQUARED_X_Y, }; #define IIO_VAL_INT 1 -- GitLab From f699d10202d50a764614ff9191b5c4b9dd75e36c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 10:47:12 +0100 Subject: [PATCH 3330/6849] staging:iio:accel:adis16204 support the rss channel via chan spec. Reduces code and makes this channel available within the kernel. Note that it is not added to the buffer, thus maintaining the previous functionality of this driver. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/accel/adis16204_core.c | 79 ++++++++-------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 685fa925d9df..5f2e5f11c543 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -169,32 +169,6 @@ error_ret: return ret; } -static ssize_t adis16204_read_14bit_signed(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - s16 val = 0; - ssize_t ret; - - mutex_lock(&indio_dev->mlock); - - ret = adis16204_spi_read_reg_16(indio_dev, - this_attr->address, (u16 *)&val); - if (!ret) { - if (val & ADIS16204_ERROR_ACTIVE) - adis16204_check_status(indio_dev); - - val = ((s16)(val << 2) >> 2); - ret = sprintf(buf, "%d\n", val); - } - - mutex_unlock(&indio_dev->mlock); - - return ret; -} - static int adis16204_reset(struct iio_dev *indio_dev) { int ret; @@ -282,16 +256,6 @@ err_ret: } /* Unique to this driver currently */ -#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr) \ - IIO_DEVICE_ATTR(in_accel_xy, S_IRUGO, _show, NULL, _addr) -#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr) \ - IIO_DEVICE_ATTR(in_accel_xypeak, S_IRUGO, _show, NULL, _addr) - -static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed, - ADIS16204_XY_RSS_OUT); -static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed, - ADIS16204_XY_PEAK_OUT); -static IIO_CONST_ATTR(in_accel_xy_scale, "0.017125"); enum adis16204_channel { in_supply, @@ -299,9 +263,10 @@ enum adis16204_channel { temp, accel_x, accel_y, + accel_xy, }; -static u8 adis16204_addresses[5][3] = { +static u8 adis16204_addresses[6][3] = { [in_supply] = { ADIS16204_SUPPLY_OUT }, [in_aux] = { ADIS16204_AUX_ADC }, [temp] = { ADIS16204_TEMP_OUT }, @@ -309,6 +274,8 @@ static u8 adis16204_addresses[5][3] = { ADIS16204_X_PEAK_OUT }, [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL, ADIS16204_Y_PEAK_OUT }, + [accel_xy] = { ADIS16204_XY_RSS_OUT, 0, + ADIS16204_XY_PEAK_OUT }, }; static int adis16204_read_raw(struct iio_dev *indio_dev, @@ -362,10 +329,16 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; - if (chan->channel2 == IIO_MOD_X) + switch (chan->channel2) { + case IIO_MOD_X: + case IIO_MOD_ROOT_SUM_SQUARED_X_Y: *val2 = 17125; - else + break; + case IIO_MOD_Y: + case IIO_MOD_Z: *val2 = 8407; + break; + } return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; @@ -498,21 +471,23 @@ static struct iio_chan_spec adis16204_channels[] = { }, }, IIO_CHAN_SOFT_TIMESTAMP(5), -}; - -static struct attribute *adis16204_attributes[] = { - &iio_dev_attr_in_accel_xy.dev_attr.attr, - &iio_dev_attr_in_accel_xypeak.dev_attr.attr, - &iio_const_attr_in_accel_xy_scale.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16204_attribute_group = { - .attrs = adis16204_attributes, + { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, + .address = accel_xy, + .scan_type = { + .sign = 'u', + .realbits = 14, + .storagebits = 16, + }, + } }; static const struct iio_info adis16204_info = { - .attrs = &adis16204_attribute_group, .read_raw = &adis16204_read_raw, .write_raw = &adis16204_write_raw, .driver_module = THIS_MODULE, @@ -549,7 +524,7 @@ static int __devinit adis16204_probe(struct spi_device *spi) ret = iio_buffer_register(indio_dev, adis16204_channels, - ARRAY_SIZE(adis16204_channels)); + 6); if (ret) { printk(KERN_ERR "failed to initialize the ring\n"); goto error_unreg_ring_funcs; -- GitLab From cf82cb8128496955a38fa62e1819ceb1d596e2eb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 May 2012 10:56:41 +0100 Subject: [PATCH 3331/6849] IIO: Add a modifier for x^2+y^2+z^2 There will probably be a number of such modifiers eventually but this one is used in the adis16240 accelerometer driver. Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 1 + include/linux/iio/types.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e42749ec5c3c..bb3c692e49b8 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -71,6 +71,7 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_Y] = "y", [IIO_MOD_Z] = "z", [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", + [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", [IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_IR] = "ir", }; diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 210559ddf8a3..e25040173346 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -45,6 +45,7 @@ enum iio_modifier { IIO_MOD_LIGHT_BOTH, IIO_MOD_LIGHT_IR, IIO_MOD_ROOT_SUM_SQUARED_X_Y, + IIO_MOD_SUM_SQUARED_X_Y_Z, }; #define IIO_VAL_INT 1 -- GitLab From 38b3fef1730319e2730af3fc9f73698e3a9aeb4a Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 15 Jun 2012 11:50:28 +0300 Subject: [PATCH 3332/6849] Bluetooth: Improve debugging messages for hci_conn Improve debugging of hci_conn objects by: adding print to hci_conn refcounting, adding object spcifier when missing, change conn to hcon since conn is heavily used for l2cap_conn objects and this is misleading. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 6 +++++ net/bluetooth/hci_conn.c | 44 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 75766b7f0dc7..475b8c04ba52 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -587,12 +587,18 @@ void hci_conn_put_device(struct hci_conn *conn); static inline void hci_conn_hold(struct hci_conn *conn) { + BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt), + atomic_read(&conn->refcnt) + 1); + atomic_inc(&conn->refcnt); cancel_delayed_work(&conn->disc_work); } static inline void hci_conn_put(struct hci_conn *conn) { + BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt), + atomic_read(&conn->refcnt) - 1); + if (atomic_dec_and_test(&conn->refcnt)) { unsigned long timeo; if (conn->type == ACL_LINK || conn->type == LE_LINK) { diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 2fcced377e50..9bbef6e95d2c 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -107,7 +107,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn) { struct hci_cp_create_conn_cancel cp; - BT_DBG("%p", conn); + BT_DBG("hcon %p", conn); if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) return; @@ -120,7 +120,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconnect cp; - BT_DBG("%p", conn); + BT_DBG("hcon %p", conn); conn->state = BT_DISCONN; @@ -134,7 +134,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_add_sco cp; - BT_DBG("%p", conn); + BT_DBG("hcon %p", conn); conn->state = BT_CONNECT; conn->out = true; @@ -152,7 +152,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_setup_sync_conn cp; - BT_DBG("%p", conn); + BT_DBG("hcon %p", conn); conn->state = BT_CONNECT; conn->out = true; @@ -196,7 +196,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], struct hci_dev *hdev = conn->hdev; struct hci_cp_le_start_enc cp; - BT_DBG("%p", conn); + BT_DBG("hcon %p", conn); memset(&cp, 0, sizeof(cp)); @@ -213,11 +213,11 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) { struct hci_conn *sco = conn->link; - BT_DBG("%p", conn); - if (!sco) return; + BT_DBG("hcon %p", conn); + if (!status) { if (lmp_esco_capable(conn->hdev)) hci_setup_sync(sco, conn->handle); @@ -235,7 +235,7 @@ static void hci_conn_timeout(struct work_struct *work) disc_work.work); __u8 reason; - BT_DBG("conn %p state %s", conn, state_to_string(conn->state)); + BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); if (atomic_read(&conn->refcnt)) return; @@ -266,7 +266,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p mode %d", conn, conn->mode); + BT_DBG("hcon %p mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -301,7 +301,7 @@ static void hci_conn_idle(unsigned long arg) { struct hci_conn *conn = (void *) arg; - BT_DBG("conn %p mode %d", conn, conn->mode); + BT_DBG("hcon %p mode %d", conn, conn->mode); hci_conn_enter_sniff_mode(conn); } @@ -382,7 +382,7 @@ int hci_conn_del(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle); + BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); del_timer(&conn->idle_timer); @@ -557,7 +557,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, /* Check link security requirement */ int hci_conn_check_link_mode(struct hci_conn *conn) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) return 0; @@ -568,7 +568,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn) /* Authenticate remote device */ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); if (conn->pending_sec_level > sec_level) sec_level = conn->pending_sec_level; @@ -602,7 +602,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) /* Encrypt the the link */ static void hci_conn_encrypt(struct hci_conn *conn) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { struct hci_cp_set_conn_encrypt cp; @@ -616,7 +616,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) /* Enable security */ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); /* For sdp we don't need the link key. */ if (sec_level == BT_SECURITY_SDP) @@ -669,7 +669,7 @@ EXPORT_SYMBOL(hci_conn_security); /* Check secure link requirement */ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); if (sec_level != BT_SECURITY_HIGH) return 1; /* Accept if non-secure is required */ @@ -684,7 +684,7 @@ EXPORT_SYMBOL(hci_conn_check_secure); /* Change link key */ int hci_conn_change_link_key(struct hci_conn *conn) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { struct hci_cp_change_conn_link_key cp; @@ -699,7 +699,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) /* Switch role */ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) { - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); if (!role && conn->link_mode & HCI_LM_MASTER) return 1; @@ -720,7 +720,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p mode %d", conn, conn->mode); + BT_DBG("hcon %p mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -894,7 +894,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) struct hci_dev *hdev = conn->hdev; struct hci_chan *chan; - BT_DBG("%s conn %p", hdev->name, conn); + BT_DBG("%s hcon %p", hdev->name, conn); chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL); if (!chan) @@ -913,7 +913,7 @@ int hci_chan_del(struct hci_chan *chan) struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; - BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); + BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan); list_del_rcu(&chan->list); @@ -929,7 +929,7 @@ void hci_chan_list_flush(struct hci_conn *conn) { struct hci_chan *chan, *n; - BT_DBG("conn %p", conn); + BT_DBG("hcon %p", conn); list_for_each_entry_safe(chan, n, &conn->chan_list, list) hci_chan_del(chan); -- GitLab From 46afededca7d8b0117e05b23e5cbcfa0e2bbbd92 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 19 Jun 2012 21:51:31 +0530 Subject: [PATCH 3333/6849] Bluetooth: cleanup dtl1_config Improve the error handling of dtl1_config() Signed-off-by: Devendra Naga Signed-off-by: Gustavo Padovan --- drivers/bluetooth/dtl1_cs.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index b1b37ccd3cd4..97a7784db4a2 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -586,29 +586,31 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) static int dtl1_config(struct pcmcia_device *link) { dtl1_info_t *info = link->priv; - int i; + int ret; /* Look for a generic full-sized window */ link->resource[0]->end = 8; - if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) + ret = pcmcia_loop_config(link, dtl1_confcheck, NULL); + if (ret) goto failed; - i = pcmcia_request_irq(link, dtl1_interrupt); - if (i != 0) + ret = pcmcia_request_irq(link, dtl1_interrupt); + if (ret) goto failed; - i = pcmcia_enable_device(link); - if (i != 0) + ret = pcmcia_enable_device(link); + if (ret) goto failed; - if (dtl1_open(info) != 0) + ret = dtl1_open(info); + if (ret) goto failed; return 0; failed: dtl1_detach(link); - return -ENODEV; + return ret; } static const struct pcmcia_device_id dtl1_ids[] = { -- GitLab From 510df2515f6b0afdd7604aee21b02b8f339e9344 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 20 Jun 2012 14:40:12 +0300 Subject: [PATCH 3334/6849] Bluetooth: Fix warning: using int as NULL pointer Fix for warnings below: ... drivers/bluetooth/bt3c_cs.c:667:20: warning: Using plain integer as NULL pointer drivers/bluetooth/btuart_cs.c:596:20: warning: Using plain integer as NULL pointer ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/bt3c_cs.c | 2 +- drivers/bluetooth/btuart_cs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index b2b0fbbb43b5..8925b6d672a6 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -664,7 +664,7 @@ static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data) { int *try = priv_data; - if (try == 0) + if (!try) p_dev->io_lines = 16; if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 65b8d996840c..21e803a6a281 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -593,7 +593,7 @@ static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data) { int *try = priv_data; - if (try == 0) + if (!try) p_dev->io_lines = 16; if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) -- GitLab From d300fa9b14549c64e63691356c68483bcfeb0f04 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Tue, 19 Jun 2012 15:21:21 +0300 Subject: [PATCH 3335/6849] Bluetooth: Route traffic only through BR/EDR controller If AMP controller is first in the list then Bluetooth traffic might be routed through it (if source is not specified). The patch prevents this case and also checks that source is BR/EDR. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 9bbef6e95d2c..5ad7da217474 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -442,7 +442,8 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) list_for_each_entry(d, &hci_dev_list, list) { if (!test_bit(HCI_UP, &d->flags) || - test_bit(HCI_RAW, &d->flags)) + test_bit(HCI_RAW, &d->flags) || + d->dev_type != HCI_BREDR) continue; /* Simple routing: -- GitLab From 74ad8fdaefe6ccb8ef1918394a9d04a036658346 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 29 Jun 2012 14:58:07 +0300 Subject: [PATCH 3336/6849] Bluetooth: bluecard_cs: Shorten scope for iobase Shortening scope shall silence some warnings reported by Geert Uytterhoeven: ... drivers/bluetooth/bluecard_cs.c: warning: unused variable 'iobase' [-Wunused-variable] ... Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/bluecard_cs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 585c88e01893..66c3a6770c41 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -621,7 +621,6 @@ static int bluecard_hci_flush(struct hci_dev *hdev) static int bluecard_hci_open(struct hci_dev *hdev) { bluecard_info_t *info = hci_get_drvdata(hdev); - unsigned int iobase = info->p_dev->resource[0]->start; if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); @@ -630,6 +629,8 @@ static int bluecard_hci_open(struct hci_dev *hdev) return 0; if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { + unsigned int iobase = info->p_dev->resource[0]->start; + /* Enable LED */ outb(0x08 | 0x20, iobase + 0x30); } @@ -641,7 +642,6 @@ static int bluecard_hci_open(struct hci_dev *hdev) static int bluecard_hci_close(struct hci_dev *hdev) { bluecard_info_t *info = hci_get_drvdata(hdev); - unsigned int iobase = info->p_dev->resource[0]->start; if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) return 0; @@ -649,6 +649,8 @@ static int bluecard_hci_close(struct hci_dev *hdev) bluecard_hci_flush(hdev); if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { + unsigned int iobase = info->p_dev->resource[0]->start; + /* Disable LED */ outb(0x00, iobase + 0x30); } -- GitLab From ce2be9acff7f71b94e3d68e08df3f1592cae05a3 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 29 Jun 2012 15:07:00 +0300 Subject: [PATCH 3337/6849] Bluetooth: Do not auto off AMP controller Since AMP controller is not managed by user space do not shut it down. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 32dcb09cdb5d..f932d663ff68 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1743,8 +1743,11 @@ int hci_register_dev(struct hci_dev *hdev) } } - set_bit(HCI_AUTO_OFF, &hdev->dev_flags); set_bit(HCI_SETUP, &hdev->dev_flags); + + if (hdev->dev_type != HCI_AMP) + set_bit(HCI_AUTO_OFF, &hdev->dev_flags); + schedule_work(&hdev->power_on); hci_notify(hdev, HCI_DEV_REG); -- GitLab From 5ae95aefb73b32ec4e7c46554304042ba82230ca Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 5 Jun 2012 15:16:43 +0800 Subject: [PATCH 3338/6849] ARM: imx6q: fix suspend regression caused by common clk migration When moving to common clk framework, the imx6q clks rom and mmdc_ch1_axi get different on/off states than old clk driver, which breaks suspend function. There might be a better way to manage these clocks, but let's takes the old clk driver approach to fix the regression first. Signed-off-by: Shawn Guo Signed-off-by: Olof Johansson --- arch/arm/mach-imx/clk-imx6q.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 17dc66a085a5..e1a17ac7b3b4 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -152,13 +152,14 @@ enum mx6q_clks { ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3, usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, - ssi2_ipg, ssi3_ipg, clk_max + ssi2_ipg, ssi3_ipg, rom, + clk_max }; static struct clk *clk[clk_max]; static enum mx6q_clks const clks_init_on[] __initconst = { - mmdc_ch0_axi, mmdc_ch1_axi, + mmdc_ch0_axi, rom, }; int __init mx6q_clocks_init(void) @@ -364,6 +365,7 @@ int __init mx6q_clocks_init(void) clk[gpmi_bch] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); + clk[rom] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); -- GitLab From 87fac288083db40b5d5ab845393be268357c8827 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 30 Jun 2012 15:30:46 -0700 Subject: [PATCH 3339/6849] linux/irq.h: fix kernel-doc warning Fix kernel-doc warning. This struct member was removed in commit 875682648b89 ("irq: Remove irq_chip->release()") so remove its associated kernel-doc entry also. Warning(include/linux/irq.h:338): Excess struct/union/enum/typedef member 'release' description in 'irq_chip' Signed-off-by: Randy Dunlap Cc: Richard Weinberger Cc: Thomas Gleixner Signed-off-by: Linus Torvalds --- include/linux/irq.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/irq.h b/include/linux/irq.h index 61f5cec031e0..a5261e3d2e3c 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -301,8 +301,6 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) * @irq_pm_shutdown: function called from core code on shutdown once per chip * @irq_print_chip: optional to print special chip info in show_interrupts * @flags: chip specific flags - * - * @release: release function solely used by UML */ struct irq_chip { const char *name; -- GitLab From 4f0f4af59cb07bcf44d3c07a9e8c26df54d9fff8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 30 Jun 2012 15:37:24 -0700 Subject: [PATCH 3340/6849] printk.c: fix kernel-doc warnings Fix kernel-doc warnings in printk.c: use correct parameter name. Warning(kernel/printk.c:2429): No description found for parameter 'buf' Warning(kernel/printk.c:2429): Excess function parameter 'line' description in 'kmsg_dump_get_buffer' Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- kernel/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index 5ae6b09e3805..dba18211685e 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -2538,7 +2538,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_get_line); * kmsg_dump_get_buffer - copy kmsg log lines * @dumper: registered kmsg dumper * @syslog: include the "<4>" prefixes - * @line: buffer to copy the line to + * @buf: buffer to copy the line to * @size: maximum size of the buffer * @len: length of line placed into buffer * -- GitLab From 6887a4131da3adaab011613776d865f4bcfb5678 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 30 Jun 2012 16:08:57 -0700 Subject: [PATCH 3341/6849] Linux 3.5-rc5 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3fdfde2c1b7d..81ea15450049 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Saber-toothed Squirrel # *DOCUMENTATION* -- GitLab From f7eadafb13daa0efcbd9d5fe5e53dcaee21208e8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 30 Jun 2012 01:48:53 +0000 Subject: [PATCH 3342/6849] netfilter: use kfree_skb() not kfree() This was should be a kfree_skb() here to free the sk_buff pointer. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/bridge/netfilter/ebt_ulog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 374bdcd77039..19063473c71f 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -156,7 +156,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, nlh = nlmsg_put(ub->skb, 0, ub->qlen, 0, size - NLMSG_ALIGN(sizeof(*nlh)), 0); if (!nlh) { - kfree(ub->skb); + kfree_skb(ub->skb); ub->skb = NULL; goto unlock; } -- GitLab From 0e90b49ca4b891f085b57559a3071a4feefb496c Mon Sep 17 00:00:00 2001 From: Mitch A Williams Date: Sat, 30 Jun 2012 00:23:19 +0000 Subject: [PATCH 3343/6849] igbvf: fix divide by zero Using ethtool -C ethX rx-usecs 0 crashes with a divide by zero. Refactor this function to fix this issue and make it more clear what the intent of each conditional is. Add comment regarding using a setting of zero. CC: stable [3.3+] CC: David Ahern Signed-off-by: Mitch Williams Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/igbvf/ethtool.c | 29 ++++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c index 8ce67064b9c5..90eef07943f4 100644 --- a/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/drivers/net/ethernet/intel/igbvf/ethtool.c @@ -357,21 +357,28 @@ static int igbvf_set_coalesce(struct net_device *netdev, struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) || - ((ec->rx_coalesce_usecs > 3) && - (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) || - (ec->rx_coalesce_usecs == 2)) - return -EINVAL; - - /* convert to rate of irq's per second */ - if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) { + if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) && + (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) { + adapter->current_itr = ec->rx_coalesce_usecs << 2; + adapter->requested_itr = 1000000000 / + (adapter->current_itr * 256); + } else if ((ec->rx_coalesce_usecs == 3) || + (ec->rx_coalesce_usecs == 2)) { adapter->current_itr = IGBVF_START_ITR; adapter->requested_itr = ec->rx_coalesce_usecs; - } else { - adapter->current_itr = ec->rx_coalesce_usecs << 2; + } else if (ec->rx_coalesce_usecs == 0) { + /* + * The user's desire is to turn off interrupt throttling + * altogether, but due to HW limitations, we can't do that. + * Instead we set a very small value in EITR, which would + * allow ~967k interrupts per second, but allow the adapter's + * internal clocking to still function properly. + */ + adapter->current_itr = 4; adapter->requested_itr = 1000000000 / (adapter->current_itr * 256); - } + } else + return -EINVAL; writel(adapter->current_itr, hw->hw_addr + adapter->rx_ring->itr_register); -- GitLab From c801e3cc1925e02fa7213889306d4d77e6ad1550 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Jun 2012 22:39:27 -0700 Subject: [PATCH 3344/6849] ipv4: Clarify in docs that accept_local requires rp_filter. Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 99d0e0504d6e..47b6c79e9b05 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -857,9 +857,14 @@ accept_source_route - BOOLEAN FALSE (host) accept_local - BOOLEAN - Accept packets with local source addresses. In combination with - suitable routing, this can be used to direct packets between two - local interfaces over the wire and have them accepted properly. + Accept packets with local source addresses. In combination + with suitable routing, this can be used to direct packets + between two local interfaces over the wire and have them + accepted properly. + + rp_filter must be set to a non-zero value in order for + accept_local to have an effect. + default FALSE route_localnet - BOOLEAN -- GitLab From 4244854d22bf8f782698c5224b9191c8d2d42610 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Sat, 30 Jun 2012 03:04:26 +0000 Subject: [PATCH 3345/6849] sctp: be more restrictive in transport selection on bundled sacks It was noticed recently that when we send data on a transport, its possible that we might bundle a sack that arrived on a different transport. While this isn't a major problem, it does go against the SHOULD requirement in section 6.4 of RFC 2960: An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK, etc.) to the same destination transport address from which it received the DATA or control chunk to which it is replying. This rule should also be followed if the endpoint is bundling DATA chunks together with the reply chunk. This patch seeks to correct that. It restricts the bundling of sack operations to only those transports which have moved the ctsn of the association forward since the last sack. By doing this we guarantee that we only bundle outbound saks on a transport that has received a chunk since the last sack. This brings us into stricter compliance with the RFC. Vlad had initially suggested that we strictly allow only sack bundling on the transport that last moved the ctsn forward. While this makes sense, I was concerned that doing so prevented us from bundling in the case where we had received chunks that moved the ctsn on multiple transports. In those cases, the RFC allows us to select any of the transports having received chunks to bundle the sack on. so I've modified the approach to allow for that, by adding a state variable to each transport that tracks weather it has moved the ctsn since the last sack. This I think keeps our behavior (and performance), close enough to our current profile that I think we can do this without a sysctl knob to enable/disable it. Signed-off-by: Neil Horman CC: Vlad Yaseivch CC: David S. Miller CC: linux-sctp@vger.kernel.org Reported-by: Michele Baldessari Reported-by: sorin serban Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 4 ++++ include/net/sctp/tsnmap.h | 3 ++- net/sctp/associola.c | 1 + net/sctp/output.c | 5 +++++ net/sctp/sm_make_chunk.c | 16 ++++++++++++++++ net/sctp/sm_sideeffect.c | 2 +- net/sctp/transport.c | 2 ++ net/sctp/tsnmap.c | 6 +++++- net/sctp/ulpevent.c | 3 ++- net/sctp/ulpqueue.c | 2 +- 10 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index e4652fe58958..fecdf31816f2 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -912,6 +912,9 @@ struct sctp_transport { /* Is this structure kfree()able? */ malloced:1; + /* Has this transport moved the ctsn since we last sacked */ + __u32 sack_generation; + struct flowi fl; /* This is the peer's IP address and port. */ @@ -1584,6 +1587,7 @@ struct sctp_association { */ __u8 sack_needed; /* Do we need to sack the peer? */ __u32 sack_cnt; + __u32 sack_generation; /* These are capabilities which our peer advertised. */ __u8 ecn_capable:1, /* Can peer do ECN? */ diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h index e7728bc14ccf..2c5d2b4d5d1e 100644 --- a/include/net/sctp/tsnmap.h +++ b/include/net/sctp/tsnmap.h @@ -117,7 +117,8 @@ void sctp_tsnmap_free(struct sctp_tsnmap *map); int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn); /* Mark this TSN as seen. */ -int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn); +int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn, + struct sctp_transport *trans); /* Mark this TSN and all lower as seen. */ void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn); diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 5bc9ab161b37..b16517ee1aaf 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -271,6 +271,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a */ asoc->peer.sack_needed = 1; asoc->peer.sack_cnt = 0; + asoc->peer.sack_generation = 1; /* Assume that the peer will tell us if he recognizes ASCONF * as part of INIT exchange. diff --git a/net/sctp/output.c b/net/sctp/output.c index f1b7d4bb591e..6ae47acaaec6 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -248,6 +248,11 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, /* If the SACK timer is running, we have a pending SACK */ if (timer_pending(timer)) { struct sctp_chunk *sack; + + if (pkt->transport->sack_generation != + pkt->transport->asoc->peer.sack_generation) + return retval; + asoc->a_rwnd = asoc->rwnd; sack = sctp_make_sack(asoc); if (sack) { diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index a85eeeb55dd0..b6de71efb140 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -734,8 +734,10 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) int len; __u32 ctsn; __u16 num_gabs, num_dup_tsns; + struct sctp_association *aptr = (struct sctp_association *)asoc; struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; + struct sctp_transport *trans; memset(gabs, 0, sizeof(gabs)); ctsn = sctp_tsnmap_get_ctsn(map); @@ -805,6 +807,20 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, sctp_tsnmap_get_dups(map)); + /* Once we have a sack generated, check to see what our sack + * generation is, if its 0, reset the transports to 0, and reset + * the association generation to 1 + * + * The idea is that zero is never used as a valid generation for the + * association so no transport will match after a wrap event like this, + * Until the next sack + */ + if (++aptr->peer.sack_generation == 0) { + list_for_each_entry(trans, &asoc->peer.transport_addr_list, + transports) + trans->sack_generation = 0; + aptr->peer.sack_generation = 1; + } nodata: return retval; } diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index c96d1a81cf42..8716da1a8592 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -1268,7 +1268,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, case SCTP_CMD_REPORT_TSN: /* Record the arrival of a TSN. */ error = sctp_tsnmap_mark(&asoc->peer.tsn_map, - cmd->obj.u32); + cmd->obj.u32, NULL); break; case SCTP_CMD_REPORT_FWDTSN: diff --git a/net/sctp/transport.c b/net/sctp/transport.c index b026ba0c6992..1dcceb6e0ce6 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -68,6 +68,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); memset(&peer->saddr, 0, sizeof(union sctp_addr)); + peer->sack_generation = 0; + /* From 6.3.1 RTO Calculation: * * C1) Until an RTT measurement has been made for a packet sent to the diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c index f1e40cebc981..b5fb7c409023 100644 --- a/net/sctp/tsnmap.c +++ b/net/sctp/tsnmap.c @@ -114,7 +114,8 @@ int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn) /* Mark this TSN as seen. */ -int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) +int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn, + struct sctp_transport *trans) { u16 gap; @@ -133,6 +134,9 @@ int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) */ map->max_tsn_seen++; map->cumulative_tsn_ack_point++; + if (trans) + trans->sack_generation = + trans->asoc->peer.sack_generation; map->base_tsn++; } else { /* Either we already have a gap, or about to record a gap, so diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 8a84017834c2..33d894776192 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -715,7 +715,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, * can mark it as received so the tsn_map is updated correctly. */ if (sctp_tsnmap_mark(&asoc->peer.tsn_map, - ntohl(chunk->subh.data_hdr->tsn))) + ntohl(chunk->subh.data_hdr->tsn), + chunk->transport)) goto fail_mark; /* First calculate the padding, so we don't inadvertently diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index f2d1de7f2ffb..f5a6a4f4faf7 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -1051,7 +1051,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, if (chunk && (freed >= needed)) { __u32 tsn; tsn = ntohl(chunk->subh.data_hdr->tsn); - sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn); + sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport); sctp_ulpq_tail_data(ulpq, chunk, gfp); sctp_ulpq_partial_delivery(ulpq, chunk, gfp); -- GitLab From 6416c0409dda00aa66b2a4615044fb59d80f6bb2 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Mon, 11 Jun 2012 15:31:14 +0100 Subject: [PATCH 3346/6849] ARM: pxa: hx4700: Fix basic suspend/resume Basic suspend/resume is fixed by ensuring that the PGSR registers are set correctly before sleep mode is entered. In particular four of the active low resets need to be driven high while in sleep mode, otherwise the unit resets itself instead of suspending. Another problem was that the PCFR_GPROD bit is set by the HTC bootloader; this caused GPIO reset (i.e. the reset button) to fail immediately after returning from sleep mode. Signed-off-by: Paul Parsons Cc: Philipp Zabel Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/hx4700.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index d09da6a746b8..d3de84b0dcbe 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -127,7 +127,11 @@ static unsigned long hx4700_pin_config[] __initdata = { GPIO19_SSP2_SCLK, GPIO86_SSP2_RXD, GPIO87_SSP2_TXD, - GPIO88_GPIO, + GPIO88_GPIO | MFP_LPM_DRIVE_HIGH, /* TSC2046_CS */ + + /* BQ24022 Regulator */ + GPIO72_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_nCHARGE_EN */ + GPIO96_GPIO | MFP_LPM_KEEP_OUTPUT, /* BQ24022_ISET2 */ /* HX4700 specific input GPIOs */ GPIO12_GPIO | WAKEUP_ON_EDGE_RISE, /* ASIC3_IRQ */ @@ -135,6 +139,10 @@ static unsigned long hx4700_pin_config[] __initdata = { GPIO14_GPIO, /* nWLAN_IRQ */ /* HX4700 specific output GPIOs */ + GPIO61_GPIO | MFP_LPM_DRIVE_HIGH, /* W3220_nRESET */ + GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* ASIC3_nRESET */ + GPIO81_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_GP_nRESET */ + GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* CPU_HW_nRESET */ GPIO102_GPIO | MFP_LPM_DRIVE_LOW, /* SYNAPTICS_POWER_ON */ GPIO10_GPIO, /* GSM_IRQ */ @@ -872,14 +880,19 @@ static struct gpio global_gpios[] = { { GPIO110_HX4700_LCD_LVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_LVDD" }, { GPIO111_HX4700_LCD_AVDD_3V3_ON, GPIOF_OUT_INIT_HIGH, "LCD_AVDD" }, { GPIO32_HX4700_RS232_ON, GPIOF_OUT_INIT_HIGH, "RS232_ON" }, + { GPIO61_HX4700_W3220_nRESET, GPIOF_OUT_INIT_HIGH, "W3220_nRESET" }, { GPIO71_HX4700_ASIC3_nRESET, GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" }, + { GPIO81_HX4700_CPU_GP_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_GP_nRESET" }, { GPIO82_HX4700_EUART_RESET, GPIOF_OUT_INIT_HIGH, "EUART_RESET" }, + { GPIO116_HX4700_CPU_HW_nRESET, GPIOF_OUT_INIT_HIGH, "CPU_HW_nRESET" }, }; static void __init hx4700_init(void) { int ret; + PCFR = PCFR_GPR_EN | PCFR_OPDE; + pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config)); gpio_set_wake(GPIO12_HX4700_ASIC3_IRQ, 1); ret = gpio_request_array(ARRAY_AND_SIZE(global_gpios)); -- GitLab From 2e1706f234f86ff71056ef69683d734fbf7e9e40 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 30 Jun 2012 20:02:42 +0000 Subject: [PATCH 3347/6849] e1000e: remove use of IP payload checksum Currently only used when packet split mode is enabled with jumbo frames, IP payload checksum (for fragmented UDP packets) is mutually exclusive with receive hashing offload since the hardware uses the same space in the receive descriptor for the hardware-provided packet checksum and the RSS hash, respectively. Users currently must disable jumbos when receive hashing offload is enabled, or vice versa, because of this incompatibility. Since testing has shown that IP payload checksum does not provide any real benefit, just remove it so that there is no longer a choice between jumbos or receive hashing offload but not both as done in other Intel GbE drivers (e.g. e1000, igb). Also, add a missing check for IP checksum error reported by the hardware; let the stack verify the checksum when this happens. CC: stable [3.4] Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/e1000e/defines.h | 1 + drivers/net/ethernet/intel/e1000e/netdev.c | 75 ++++----------------- 2 files changed, 15 insertions(+), 61 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 351a4097b2ba..76edbc1be33b 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -103,6 +103,7 @@ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ #define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ #define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ +#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 31d37a2b5ba8..623e30b9964d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -496,7 +496,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, * @sk_buff: socket buffer with received data **/ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, - __le16 csum, struct sk_buff *skb) + struct sk_buff *skb) { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); @@ -511,8 +511,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, if (status & E1000_RXD_STAT_IXSM) return; - /* TCP/UDP checksum error bit is set */ - if (errors & E1000_RXD_ERR_TCPE) { + /* TCP/UDP checksum error bit or IP checksum error bit is set */ + if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) { /* let the stack verify checksum errors */ adapter->hw_csum_err++; return; @@ -523,19 +523,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, return; /* It must be a TCP or UDP packet with a valid checksum */ - if (status & E1000_RXD_STAT_TCPCS) { - /* TCP checksum is good */ - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else { - /* - * IP fragment with UDP payload - * Hardware complements the payload checksum, so we undo it - * and then put the value in host order for further stack use. - */ - __sum16 sum = (__force __sum16)swab16((__force u16)csum); - skb->csum = csum_unfold(~sum); - skb->ip_summed = CHECKSUM_COMPLETE; - } + skb->ip_summed = CHECKSUM_UNNECESSARY; adapter->hw_csum_good++; } @@ -954,8 +942,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb_put(skb, length); /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, staterr, - rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_checksum(adapter, staterr, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1341,8 +1328,7 @@ copydone: total_rx_bytes += skb->len; total_rx_packets++; - e1000_rx_checksum(adapter, staterr, - rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_checksum(adapter, staterr, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1512,9 +1498,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, } } - /* Receive Checksum Offload XXX recompute due to CRC strip? */ - e1000_rx_checksum(adapter, staterr, - rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + /* Receive Checksum Offload */ + e1000_rx_checksum(adapter, staterr, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -3098,19 +3083,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = er32(RXCSUM); - if (adapter->netdev->features & NETIF_F_RXCSUM) { + if (adapter->netdev->features & NETIF_F_RXCSUM) rxcsum |= E1000_RXCSUM_TUOFL; - - /* - * IPv4 payload checksum for UDP fragments must be - * used in conjunction with packet-split. - */ - if (adapter->rx_ps_pages) - rxcsum |= E1000_RXCSUM_IPPCSE; - } else { + else rxcsum &= ~E1000_RXCSUM_TUOFL; - /* no need to clear IPPCSE as it defaults to 0 */ - } ew32(RXCSUM, rxcsum); if (adapter->hw.mac.type == e1000_pch2lan) { @@ -5241,22 +5217,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ - if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { - if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); - return -EINVAL; - } - - /* - * IP payload checksum (enabled with jumbos/packet-split when - * Rx checksum is enabled) and generation of RSS hash is - * mutually exclusive in the hardware. - */ - if ((netdev->features & NETIF_F_RXCSUM) && - (netdev->features & NETIF_F_RXHASH)) { - e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled. Disable one of the receive offload features before enabling jumbos.\n"); - return -EINVAL; - } + if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && + !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; } /* Supported frame sizes */ @@ -6030,17 +5994,6 @@ static int e1000_set_features(struct net_device *netdev, NETIF_F_RXALL))) return 0; - /* - * IP payload checksum (enabled with jumbos/packet-split when Rx - * checksum is enabled) and generation of RSS hash is mutually - * exclusive in the hardware. - */ - if (adapter->rx_ps_pages && - (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) { - e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames. Disable jumbos or enable only one of the receive offload features.\n"); - return -EINVAL; - } - if (changed & NETIF_F_RXFCS) { if (features & NETIF_F_RXFCS) { adapter->flags2 &= ~FLAG2_CRC_STRIPPING; -- GitLab From ea2ab8711b8a4363e3b3ee0dc609d1b3c8b92899 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 27 Jun 2012 21:14:35 +0000 Subject: [PATCH 3348/6849] stmmac: do not use strict_strtoul but kstrtoint This patch replaces the obsolete strict_strtoul with kstrtoint. v2: also removed casting on kstrtoul. v3: use kstrtoint instead of kstrtoul due to all vars are integer. thanks to E. Dumazet. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 590e95b4cbfa..eba49cb810f9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2129,42 +2129,35 @@ static int __init stmmac_cmdline_opt(char *str) return -EINVAL; while ((opt = strsep(&str, ",")) != NULL) { if (!strncmp(opt, "debug:", 6)) { - if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug)) + if (kstrtoint(opt + 6, 0, &debug)) goto err; } else if (!strncmp(opt, "phyaddr:", 8)) { - if (strict_strtoul(opt + 8, 0, - (unsigned long *)&phyaddr)) + if (kstrtoint(opt + 8, 0, &phyaddr)) goto err; } else if (!strncmp(opt, "dma_txsize:", 11)) { - if (strict_strtoul(opt + 11, 0, - (unsigned long *)&dma_txsize)) + if (kstrtoint(opt + 11, 0, &dma_txsize)) goto err; } else if (!strncmp(opt, "dma_rxsize:", 11)) { - if (strict_strtoul(opt + 11, 0, - (unsigned long *)&dma_rxsize)) + if (kstrtoint(opt + 11, 0, &dma_rxsize)) goto err; } else if (!strncmp(opt, "buf_sz:", 7)) { - if (strict_strtoul(opt + 7, 0, - (unsigned long *)&buf_sz)) + if (kstrtoint(opt + 7, 0, &buf_sz)) goto err; } else if (!strncmp(opt, "tc:", 3)) { - if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc)) + if (kstrtoint(opt + 3, 0, &tc)) goto err; } else if (!strncmp(opt, "watchdog:", 9)) { - if (strict_strtoul(opt + 9, 0, - (unsigned long *)&watchdog)) + if (kstrtoint(opt + 9, 0, &watchdog)) goto err; } else if (!strncmp(opt, "flow_ctrl:", 10)) { - if (strict_strtoul(opt + 10, 0, - (unsigned long *)&flow_ctrl)) + if (kstrtoint(opt + 10, 0, &flow_ctrl)) goto err; } else if (!strncmp(opt, "pause:", 6)) { - if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause)) + if (kstrtoint(opt + 6, 0, &pause)) goto err; #ifdef CONFIG_STMMAC_TIMER } else if (!strncmp(opt, "tmrate:", 7)) { - if (strict_strtoul(opt + 7, 0, - (unsigned long *)&tmrate)) + if (kstrtoint(opt + 7, 0, &tmrate)) goto err; #endif } -- GitLab From 0ec2ccd0804ebb57a860c59d056a3f420c4f8028 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 27 Jun 2012 21:14:36 +0000 Subject: [PATCH 3349/6849] stmmac: update the driver Documentation and add EEE This patch updates the stmmac's documentation adding some missing files in the section used to describe the internal driver's structure. Also the patch adds a new section to describe the EEE support. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- Documentation/networking/stmmac.txt | 36 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index 5cb9a1972460..c676b9cedbd0 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -257,9 +257,11 @@ reset procedure etc). o Makefile o stmmac_main.c: main network device driver; o stmmac_mdio.c: mdio functions; + o stmmac_pci: PCI driver; + o stmmac_platform.c: platform driver o stmmac_ethtool.c: ethtool support; o stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts - Only tested on ST40 platforms based. + (only tested on ST40 platforms based); o stmmac.h: private driver structure; o common.h: common definitions and VFTs; o descs.h: descriptor structure definitions; @@ -269,9 +271,11 @@ reset procedure etc). o dwmac100_core: MAC 100 core and dma code; o dwmac100_dma.c: dma funtions for the MAC chip; o dwmac1000.h: specific header file for the MAC; - o dwmac_lib.c: generic DMA functions shared among chips - o enh_desc.c: functions for handling enhanced descriptors - o norm_desc.c: functions for handling normal descriptors + o dwmac_lib.c: generic DMA functions shared among chips; + o enh_desc.c: functions for handling enhanced descriptors; + o norm_desc.c: functions for handling normal descriptors; + o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes; + o mmc_core.c/mmc.h: Management MAC Counters; 5) Debug Information @@ -304,7 +308,27 @@ All these are only useful during the developing stage and should never enabled inside the code for general usage. In fact, these can generate an huge amount of debug messages. -6) TODO: +6) Energy Efficient Ethernet + +Energy Efficient Ethernet(EEE) enables IEEE 802.3 MAC sublayer along +with a family of Physical layer to operate in the Low power Idle(LPI) +mode. The EEE mode supports the IEEE 802.3 MAC operation at 100Mbps, +1000Mbps & 10Gbps. + +The LPI mode allows power saving by switching off parts of the +communication device functionality when there is no data to be +transmitted & received. The system on both the side of the link can +disable some functionalities & save power during the period of low-link +utilization. The MAC controls whether the system should enter or exit +the LPI mode & communicate this to PHY. + +As soon as the interface is opened, the driver verifies if the EEE can +be supported. This is done by looking at both the DMA HW capability +register and the PHY devices MCD registers. +To enter in Tx LPI mode the driver needs to have a software timer +that enable and disable the LPI mode when there is nothing to be +transmitted. + +7) TODO: o XGMAC is not supported. - o Add the EEE - Energy Efficient Ethernet o Add the PTP - precision time protocol -- GitLab From d765955d2ae0b88781a0db3a5bacfe4241925e09 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 27 Jun 2012 21:14:37 +0000 Subject: [PATCH 3350/6849] stmmac: add the Energy Efficient Ethernet support This patch adds the Energy Efficient Ethernet support to the stmmac. Please see the driver's documentation for further details about this support in the driver. Thanks also goes to Rayagond Kokatanur for his first implementation. Note: to clearly manage and expose the lpi interrupt status and eee ethtool stats I've had to do some modifications to the driver's design and I found really useful to move other parts of the code (e.g. mmc irq stat) in the main directly. So this means that some core has been reworked to introduce the EEE. v1: initial patch v2: fixed some sparse issues (typos) v3: erroneously sent the v2 renamed as v3 v4: o Fixed the return value of the stmmac_eee_init as suggested by D.Miller o Totally reviewed the ethtool support for EEE o Added a new internal parameter to tune the SW timer for TX LPI. v5: do not change any eee setting in case of the stmmac_ethtool_op_set_eee fails (it has to return -EOPNOTSUPP in that case). Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/common.h | 31 +++- .../net/ethernet/stmicro/stmmac/dwmac1000.h | 20 +++ .../ethernet/stmicro/stmmac/dwmac1000_core.c | 101 ++++++++++- .../ethernet/stmicro/stmmac/dwmac100_core.c | 4 +- .../net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac.h | 8 + .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 57 ++++++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 166 +++++++++++++++++- .../ethernet/stmicro/stmmac/stmmac_platform.c | 2 + 9 files changed, 372 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index bcd54d6e94fd..e2d083228f3a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -95,6 +95,16 @@ struct stmmac_extra_stats { unsigned long poll_n; unsigned long sched_timer_n; unsigned long normal_irq_n; + unsigned long mmc_tx_irq_n; + unsigned long mmc_rx_irq_n; + unsigned long mmc_rx_csum_offload_irq_n; + /* EEE */ + unsigned long irq_receive_pmt_irq_n; + unsigned long irq_tx_path_in_lpi_mode_n; + unsigned long irq_tx_path_exit_lpi_mode_n; + unsigned long irq_rx_path_in_lpi_mode_n; + unsigned long irq_rx_path_exit_lpi_mode_n; + unsigned long phy_eee_wakeup_error_n; }; /* CSR Frequency Access Defines*/ @@ -162,6 +172,17 @@ enum tx_dma_irq_status { handle_tx_rx = 3, }; +enum core_specific_irq_mask { + core_mmc_tx_irq = 1, + core_mmc_rx_irq = 2, + core_mmc_rx_csum_offload_irq = 4, + core_irq_receive_pmt_irq = 8, + core_irq_tx_path_in_lpi_mode = 16, + core_irq_tx_path_exit_lpi_mode = 32, + core_irq_rx_path_in_lpi_mode = 64, + core_irq_rx_path_exit_lpi_mode = 128, +}; + /* DMA HW capabilities */ struct dma_features { unsigned int mbps_10_100; @@ -208,6 +229,10 @@ struct dma_features { #define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */ #define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */ +/* Default LPI timers */ +#define STMMAC_DEFAULT_LIT_LS_TIMER 0x3E8 +#define STMMAC_DEFAULT_TWT_LS_TIMER 0x0 + struct stmmac_desc_ops { /* DMA RX descriptor ring initialization */ void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size, @@ -278,7 +303,7 @@ struct stmmac_ops { /* Dump MAC registers */ void (*dump_regs) (void __iomem *ioaddr); /* Handle extra events on specific interrupts hw dependent */ - void (*host_irq_status) (void __iomem *ioaddr); + int (*host_irq_status) (void __iomem *ioaddr); /* Multicast filter setting */ void (*set_filter) (struct net_device *dev, int id); /* Flow control setting */ @@ -291,6 +316,10 @@ struct stmmac_ops { unsigned int reg_n); void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n); + void (*set_eee_mode) (void __iomem *ioaddr); + void (*reset_eee_mode) (void __iomem *ioaddr); + void (*set_eee_timer) (void __iomem *ioaddr, int ls, int tw); + void (*set_eee_pls) (void __iomem *ioaddr, int link); }; struct mac_link { diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 23478bf4ed7a..f90fcb5f9573 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -36,6 +36,7 @@ #define GMAC_INT_STATUS 0x00000038 /* interrupt status register */ enum dwmac1000_irq_status { + lpiis_irq = 0x400, time_stamp_irq = 0x0200, mmc_rx_csum_offload_irq = 0x0080, mmc_tx_irq = 0x0040, @@ -60,6 +61,25 @@ enum power_event { power_down = 0x00000001, }; +/* Energy Efficient Ethernet (EEE) + * + * LPI status, timer and control register offset + */ +#define LPI_CTRL_STATUS 0x0030 +#define LPI_TIMER_CTRL 0x0034 + +/* LPI control and status defines */ +#define LPI_CTRL_STATUS_LPITXA 0x00080000 /* Enable LPI TX Automate */ +#define LPI_CTRL_STATUS_PLSEN 0x00040000 /* Enable PHY Link Status */ +#define LPI_CTRL_STATUS_PLS 0x00020000 /* PHY Link Status */ +#define LPI_CTRL_STATUS_LPIEN 0x00010000 /* LPI Enable */ +#define LPI_CTRL_STATUS_RLPIST 0x00000200 /* Receive LPI state */ +#define LPI_CTRL_STATUS_TLPIST 0x00000100 /* Transmit LPI state */ +#define LPI_CTRL_STATUS_RLPIEX 0x00000008 /* Receive LPI Exit */ +#define LPI_CTRL_STATUS_RLPIEN 0x00000004 /* Receive LPI Entry */ +#define LPI_CTRL_STATUS_TLPIEX 0x00000002 /* Transmit LPI Exit */ +#define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */ + /* GMAC HW ADDR regs */ #define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ (reg * 8)) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index b5e4d02f15c9..bfe022605498 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -194,26 +194,107 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode) } -static void dwmac1000_irq_status(void __iomem *ioaddr) +static int dwmac1000_irq_status(void __iomem *ioaddr) { u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); + int status = 0; /* Not used events (e.g. MMC interrupts) are not handled. */ - if ((intr_status & mmc_tx_irq)) - CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n", + if ((intr_status & mmc_tx_irq)) { + CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n", readl(ioaddr + GMAC_MMC_TX_INTR)); - if (unlikely(intr_status & mmc_rx_irq)) - CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n", + status |= core_mmc_tx_irq; + } + if (unlikely(intr_status & mmc_rx_irq)) { + CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n", readl(ioaddr + GMAC_MMC_RX_INTR)); - if (unlikely(intr_status & mmc_rx_csum_offload_irq)) - CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n", + status |= core_mmc_rx_irq; + } + if (unlikely(intr_status & mmc_rx_csum_offload_irq)) { + CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n", readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD)); + status |= core_mmc_rx_csum_offload_irq; + } if (unlikely(intr_status & pmt_irq)) { - CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n"); + CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n"); /* clear the PMT bits 5 and 6 by reading the PMT * status register. */ readl(ioaddr + GMAC_PMT); + status |= core_irq_receive_pmt_irq; } + /* MAC trx/rx EEE LPI entry/exit interrupts */ + if (intr_status & lpiis_irq) { + /* Clean LPI interrupt by reading the Reg 12 */ + u32 lpi_status = readl(ioaddr + LPI_CTRL_STATUS); + + if (lpi_status & LPI_CTRL_STATUS_TLPIEN) { + CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n"); + status |= core_irq_tx_path_in_lpi_mode; + } + if (lpi_status & LPI_CTRL_STATUS_TLPIEX) { + CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n"); + status |= core_irq_tx_path_exit_lpi_mode; + } + if (lpi_status & LPI_CTRL_STATUS_RLPIEN) { + CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n"); + status |= core_irq_rx_path_in_lpi_mode; + } + if (lpi_status & LPI_CTRL_STATUS_RLPIEX) { + CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n"); + status |= core_irq_rx_path_exit_lpi_mode; + } + } + + return status; +} + +static void dwmac1000_set_eee_mode(void __iomem *ioaddr) +{ + u32 value; + + /* Enable the link status receive on RGMII, SGMII ore SMII + * receive path and instruct the transmit to enter in LPI + * state. */ + value = readl(ioaddr + LPI_CTRL_STATUS); + value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; + writel(value, ioaddr + LPI_CTRL_STATUS); +} + +static void dwmac1000_reset_eee_mode(void __iomem *ioaddr) +{ + u32 value; + + value = readl(ioaddr + LPI_CTRL_STATUS); + value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA); + writel(value, ioaddr + LPI_CTRL_STATUS); +} + +static void dwmac1000_set_eee_pls(void __iomem *ioaddr, int link) +{ + u32 value; + + value = readl(ioaddr + LPI_CTRL_STATUS); + + if (link) + value |= LPI_CTRL_STATUS_PLS; + else + value &= ~LPI_CTRL_STATUS_PLS; + + writel(value, ioaddr + LPI_CTRL_STATUS); +} + +static void dwmac1000_set_eee_timer(void __iomem *ioaddr, int ls, int tw) +{ + int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16); + + /* Program the timers in the LPI timer control register: + * LS: minimum time (ms) for which the link + * status from PHY should be ok before transmitting + * the LPI pattern. + * TW: minimum time (us) for which the core waits + * after it has stopped transmitting the LPI pattern. + */ + writel(value, ioaddr + LPI_TIMER_CTRL); } static const struct stmmac_ops dwmac1000_ops = { @@ -226,6 +307,10 @@ static const struct stmmac_ops dwmac1000_ops = { .pmt = dwmac1000_pmt, .set_umac_addr = dwmac1000_set_umac_addr, .get_umac_addr = dwmac1000_get_umac_addr, + .set_eee_mode = dwmac1000_set_eee_mode, + .reset_eee_mode = dwmac1000_reset_eee_mode, + .set_eee_timer = dwmac1000_set_eee_timer, + .set_eee_pls = dwmac1000_set_eee_pls, }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index 19e0f4eed2bc..f83210e7c221 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -72,9 +72,9 @@ static int dwmac100_rx_ipc_enable(void __iomem *ioaddr) return 0; } -static void dwmac100_irq_status(void __iomem *ioaddr) +static int dwmac100_irq_status(void __iomem *ioaddr) { - return; + return 0; } static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index 6e0360f9cfde..e678ce39d014 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -70,6 +70,7 @@ #define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL) /* DMA Status register defines */ +#define DMA_STATUS_GLPII 0x40000000 /* GMAC LPI interrupt */ #define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */ #define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */ #define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index dc20c56efc9d..ab4c376cb276 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -87,6 +87,12 @@ struct stmmac_priv { #endif int clk_csr; int synopsys_id; + struct timer_list eee_ctrl_timer; + bool tx_path_in_lpi_mode; + int lpi_irq; + int eee_enabled; + int eee_active; + int tx_lpi_timer; }; extern int phyaddr; @@ -104,6 +110,8 @@ int stmmac_dvr_remove(struct net_device *ndev); struct stmmac_priv *stmmac_dvr_probe(struct device *device, struct plat_stmmacenet_data *plat_dat, void __iomem *addr); +void stmmac_disable_eee_mode(struct stmmac_priv *priv); +bool stmmac_eee_init(struct stmmac_priv *priv); #ifdef CONFIG_HAVE_CLK static inline int stmmac_clk_enable(struct stmmac_priv *priv) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index ce431846fc6f..76fd61aa005f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -93,6 +93,16 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { STMMAC_STAT(poll_n), STMMAC_STAT(sched_timer_n), STMMAC_STAT(normal_irq_n), + STMMAC_STAT(normal_irq_n), + STMMAC_STAT(mmc_tx_irq_n), + STMMAC_STAT(mmc_rx_irq_n), + STMMAC_STAT(mmc_rx_csum_offload_irq_n), + STMMAC_STAT(irq_receive_pmt_irq_n), + STMMAC_STAT(irq_tx_path_in_lpi_mode_n), + STMMAC_STAT(irq_tx_path_exit_lpi_mode_n), + STMMAC_STAT(irq_rx_path_in_lpi_mode_n), + STMMAC_STAT(irq_rx_path_exit_lpi_mode_n), + STMMAC_STAT(phy_eee_wakeup_error_n), }; #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) @@ -366,6 +376,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, (*(u32 *)p); } } + if (priv->eee_enabled) { + int val = phy_get_eee_err(priv->phydev); + if (val) + priv->xstats.phy_eee_wakeup_error_n = val; + } } for (i = 0; i < STMMAC_STATS_LEN; i++) { char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; @@ -464,6 +479,46 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) return 0; } +static int stmmac_ethtool_op_get_eee(struct net_device *dev, + struct ethtool_eee *edata) +{ + struct stmmac_priv *priv = netdev_priv(dev); + + if (!priv->dma_cap.eee) + return -EOPNOTSUPP; + + edata->eee_enabled = priv->eee_enabled; + edata->eee_active = priv->eee_active; + edata->tx_lpi_timer = priv->tx_lpi_timer; + + return phy_ethtool_get_eee(priv->phydev, edata); +} + +static int stmmac_ethtool_op_set_eee(struct net_device *dev, + struct ethtool_eee *edata) +{ + struct stmmac_priv *priv = netdev_priv(dev); + + priv->eee_enabled = edata->eee_enabled; + + if (!priv->eee_enabled) + stmmac_disable_eee_mode(priv); + else { + /* We are asking for enabling the EEE but it is safe + * to verify all by invoking the eee_init function. + * In case of failure it will return an error. + */ + priv->eee_enabled = stmmac_eee_init(priv); + if (!priv->eee_enabled) + return -EOPNOTSUPP; + + /* Do not change tx_lpi_timer in case of failure */ + priv->tx_lpi_timer = edata->tx_lpi_timer; + } + + return phy_ethtool_set_eee(priv->phydev, edata); +} + static const struct ethtool_ops stmmac_ethtool_ops = { .begin = stmmac_check_if_running, .get_drvinfo = stmmac_ethtool_getdrvinfo, @@ -480,6 +535,8 @@ static const struct ethtool_ops stmmac_ethtool_ops = { .get_strings = stmmac_get_strings, .get_wol = stmmac_get_wol, .set_wol = stmmac_set_wol, + .get_eee = stmmac_ethtool_op_get_eee, + .set_eee = stmmac_ethtool_op_set_eee, .get_sset_count = stmmac_get_sset_count, .get_ts_info = ethtool_op_get_ts_info, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index eba49cb810f9..ea3bc0963bd7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -133,6 +133,12 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); +#define STMMAC_DEFAULT_LPI_TIMER 1000 +static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; +module_param(eee_timer, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); +#define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x)) + static irqreturn_t stmmac_interrupt(int irq, void *dev_id); #ifdef CONFIG_STMMAC_DEBUG_FS @@ -161,6 +167,8 @@ static void stmmac_verify_args(void) flow_ctrl = FLOW_OFF; if (unlikely((pause < 0) || (pause > 0xffff))) pause = PAUSE_TIME; + if (eee_timer < 0) + eee_timer = STMMAC_DEFAULT_LPI_TIMER; } static void stmmac_clk_csr_set(struct stmmac_priv *priv) @@ -229,6 +237,85 @@ static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) phydev->speed); } +static void stmmac_enable_eee_mode(struct stmmac_priv *priv) +{ + /* Check and enter in LPI mode */ + if ((priv->dirty_tx == priv->cur_tx) && + (priv->tx_path_in_lpi_mode == false)) + priv->hw->mac->set_eee_mode(priv->ioaddr); +} + +void stmmac_disable_eee_mode(struct stmmac_priv *priv) +{ + /* Exit and disable EEE in case of we are are in LPI state. */ + priv->hw->mac->reset_eee_mode(priv->ioaddr); + del_timer_sync(&priv->eee_ctrl_timer); + priv->tx_path_in_lpi_mode = false; +} + +/** + * stmmac_eee_ctrl_timer + * @arg : data hook + * Description: + * If there is no data transfer and if we are not in LPI state, + * then MAC Transmitter can be moved to LPI state. + */ +static void stmmac_eee_ctrl_timer(unsigned long arg) +{ + struct stmmac_priv *priv = (struct stmmac_priv *)arg; + + stmmac_enable_eee_mode(priv); + mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); +} + +/** + * stmmac_eee_init + * @priv: private device pointer + * Description: + * If the EEE support has been enabled while configuring the driver, + * if the GMAC actually supports the EEE (from the HW cap reg) and the + * phy can also manage EEE, so enable the LPI state and start the timer + * to verify if the tx path can enter in LPI state. + */ +bool stmmac_eee_init(struct stmmac_priv *priv) +{ + bool ret = false; + + /* MAC core supports the EEE feature. */ + if (priv->dma_cap.eee) { + /* Check if the PHY supports EEE */ + if (phy_init_eee(priv->phydev, 1)) + goto out; + + priv->eee_active = 1; + init_timer(&priv->eee_ctrl_timer); + priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; + priv->eee_ctrl_timer.data = (unsigned long)priv; + priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer); + add_timer(&priv->eee_ctrl_timer); + + priv->hw->mac->set_eee_timer(priv->ioaddr, + STMMAC_DEFAULT_LIT_LS_TIMER, + priv->tx_lpi_timer); + + pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); + + ret = true; + } +out: + return ret; +} + +static void stmmac_eee_adjust(struct stmmac_priv *priv) +{ + /* When the EEE has been already initialised we have to + * modify the PLS bit in the LPI ctrl & status reg according + * to the PHY link status. For this reason. + */ + if (priv->eee_enabled) + priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link); +} + /** * stmmac_adjust_link * @dev: net device structure @@ -249,6 +336,7 @@ static void stmmac_adjust_link(struct net_device *dev) phydev->addr, phydev->link); spin_lock_irqsave(&priv->lock, flags); + if (phydev->link) { u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); @@ -315,6 +403,8 @@ static void stmmac_adjust_link(struct net_device *dev) if (new_state && netif_msg_link(priv)) phy_print_status(phydev); + stmmac_eee_adjust(priv); + spin_unlock_irqrestore(&priv->lock, flags); DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n"); @@ -332,7 +422,7 @@ static int stmmac_init_phy(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phydev; - char phy_id[MII_BUS_ID_SIZE + 3]; + char phy_id_fmt[MII_BUS_ID_SIZE + 3]; char bus_id[MII_BUS_ID_SIZE]; int interface = priv->plat->interface; priv->oldlink = 0; @@ -346,11 +436,12 @@ static int stmmac_init_phy(struct net_device *dev) snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id); - snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, + snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, priv->plat->phy_addr); - pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); + pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); - phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface); + phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, 0, + interface); if (IS_ERR(phydev)) { pr_err("%s: Could not attach to PHY\n", dev->name); @@ -689,6 +780,11 @@ static void stmmac_tx(struct stmmac_priv *priv) } netif_tx_unlock(priv->dev); } + + if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { + stmmac_enable_eee_mode(priv); + mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); + } spin_unlock(&priv->tx_lock); } @@ -1027,6 +1123,17 @@ static int stmmac_open(struct net_device *dev) } } + /* Request the IRQ lines */ + if (priv->lpi_irq != -ENXIO) { + ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, + dev->name, dev); + if (unlikely(ret < 0)) { + pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", + __func__, priv->lpi_irq, ret); + goto open_error_lpiirq; + } + } + /* Enable the MAC Rx/Tx */ stmmac_set_mac(priv->ioaddr, true); @@ -1062,12 +1169,19 @@ static int stmmac_open(struct net_device *dev) if (priv->phydev) phy_start(priv->phydev); + priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER; + priv->eee_enabled = stmmac_eee_init(priv); + napi_enable(&priv->napi); skb_queue_head_init(&priv->rx_recycle); netif_start_queue(dev); return 0; +open_error_lpiirq: + if (priv->wol_irq != dev->irq) + free_irq(priv->wol_irq, dev); + open_error_wolirq: free_irq(dev->irq, dev); @@ -1093,6 +1207,9 @@ static int stmmac_release(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); + if (priv->eee_enabled) + del_timer_sync(&priv->eee_ctrl_timer); + /* Stop and disconnect the PHY */ if (priv->phydev) { phy_stop(priv->phydev); @@ -1115,6 +1232,8 @@ static int stmmac_release(struct net_device *dev) free_irq(dev->irq, dev); if (priv->wol_irq != dev->irq) free_irq(priv->wol_irq, dev); + if (priv->lpi_irq != -ENXIO) + free_irq(priv->lpi_irq, dev); /* Stop TX/RX DMA and clear the descriptors */ priv->hw->dma->stop_tx(priv->ioaddr); @@ -1164,6 +1283,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock(&priv->tx_lock); + if (priv->tx_path_in_lpi_mode) + stmmac_disable_eee_mode(priv); + entry = priv->cur_tx % txsize; #ifdef STMMAC_XMIT_DEBUG @@ -1540,10 +1662,37 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) return IRQ_NONE; } - if (priv->plat->has_gmac) - /* To handle GMAC own interrupts */ - priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); + /* To handle GMAC own interrupts */ + if (priv->plat->has_gmac) { + int status = priv->hw->mac->host_irq_status((void __iomem *) + dev->base_addr); + if (unlikely(status)) { + if (status & core_mmc_tx_irq) + priv->xstats.mmc_tx_irq_n++; + if (status & core_mmc_rx_irq) + priv->xstats.mmc_rx_irq_n++; + if (status & core_mmc_rx_csum_offload_irq) + priv->xstats.mmc_rx_csum_offload_irq_n++; + if (status & core_irq_receive_pmt_irq) + priv->xstats.irq_receive_pmt_irq_n++; + + /* For LPI we need to save the tx status */ + if (status & core_irq_tx_path_in_lpi_mode) { + priv->xstats.irq_tx_path_in_lpi_mode_n++; + priv->tx_path_in_lpi_mode = true; + } + if (status & core_irq_tx_path_exit_lpi_mode) { + priv->xstats.irq_tx_path_exit_lpi_mode_n++; + priv->tx_path_in_lpi_mode = false; + } + if (status & core_irq_rx_path_in_lpi_mode) + priv->xstats.irq_rx_path_in_lpi_mode_n++; + if (status & core_irq_rx_path_exit_lpi_mode) + priv->xstats.irq_rx_path_exit_lpi_mode_n++; + } + } + /* To handle DMA interrupts */ stmmac_dma_interrupt(priv); return IRQ_HANDLED; @@ -2155,6 +2304,9 @@ static int __init stmmac_cmdline_opt(char *str) } else if (!strncmp(opt, "pause:", 6)) { if (kstrtoint(opt + 6, 0, &pause)) goto err; + } else if (!strncmp(opt, "eee_timer:", 6)) { + if (kstrtoint(opt + 10, 0, &eee_timer)) + goto err; #ifdef CONFIG_STMMAC_TIMER } else if (!strncmp(opt, "tmrate:", 7)) { if (kstrtoint(opt + 7, 0, &tmrate)) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 20eb5026c49c..7d36163d0d23 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -156,6 +156,8 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) if (priv->wol_irq == -ENXIO) priv->wol_irq = priv->dev->irq; + priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); + platform_set_drvdata(pdev, priv->dev); pr_debug("STMMAC platform driver registration completed"); -- GitLab From a59a4d1921664da63d801ba477950114c71c88c9 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 27 Jun 2012 21:14:38 +0000 Subject: [PATCH 3351/6849] phy: add the EEE support and the way to access to the MMD registers. This patch adds the support for the Energy-Efficient Ethernet (EEE) to the Physical Abstraction Layer. To support the EEE we have to access to the MMD registers 3.20 and 7.60/61. So two new functions have been added to read/write the MMD registers (clause 45). An Ethernet driver (I tested the stmmac) can invoke the phy_init_eee to properly check if the EEE is supported by the PHYs and it can also set the clock stop enable bit in the 3.0 register. The phy_get_eee_err can be used for reporting the number of time where the PHY failed to complete its normal wake sequence. In the end, this patch also adds the EEE ethtool support implementing: o phy_ethtool_set_eee o phy_ethtool_get_eee v1: initial patch v2: fixed some errors especially on naming convention v3: renamed again the mmd read/write functions thank to Ben's feedback v4: moved file to phy.c and added the ethtool support. v5: fixed phy_adv_to_eee, phy_eee_to_supported, phy_eee_to_adv return values according to ethtool API (thanks to Ben's feedback). Renamed some macros to avoid too long names. v6: fixed kernel-doc comments to be properly parsed. Fixed the phy_init_eee function: we need to check which link mode was autonegotiated and then the corresponding bits in 7.60 and 7.61 registers. v7: reviewed the way to get the negotiated settings. v8: fixed a problem in the phy_init_eee return value erroneously added when included the phy_read_status call. v9: do not remove the MDIO_AN_EEE_ADV_100TX and MDIO_AN_EEE_ADV_1000T and fixed the eee_{cap,lp,adv} declaration as "int" instead of u16. Signed-off-by: Giuseppe Cavallaro Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 281 ++++++++++++++++++++++++++++++++++++++++++ include/linux/mdio.h | 28 ++++- include/linux/mii.h | 9 ++ include/linux/phy.h | 5 + 4 files changed, 319 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 2e1c23731ded..7ca2ff97c368 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -967,3 +968,283 @@ void phy_state_machine(struct work_struct *work) schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ); } + +static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad, + int addr) +{ + /* Write the desired MMD Devad */ + bus->write(bus, addr, MII_MMD_CTRL, devad); + + /* Write the desired MMD register address */ + bus->write(bus, addr, MII_MMD_DATA, prtad); + + /* Select the Function : DATA with no post increment */ + bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); +} + +/** + * phy_read_mmd_indirect - reads data from the MMD registers + * @bus: the target MII bus + * @prtad: MMD Address + * @devad: MMD DEVAD + * @addr: PHY address on the MII bus + * + * Description: it reads data from the MMD registers (clause 22 to access to + * clause 45) of the specified phy address. + * To read these register we have: + * 1) Write reg 13 // DEVAD + * 2) Write reg 14 // MMD Address + * 3) Write reg 13 // MMD Data Command for MMD DEVAD + * 3) Read reg 14 // Read MMD data + */ +static int phy_read_mmd_indirect(struct mii_bus *bus, int prtad, int devad, + int addr) +{ + u32 ret; + + mmd_phy_indirect(bus, prtad, devad, addr); + + /* Read the content of the MMD's selected register */ + ret = bus->read(bus, addr, MII_MMD_DATA); + + return ret; +} + +/** + * phy_write_mmd_indirect - writes data to the MMD registers + * @bus: the target MII bus + * @prtad: MMD Address + * @devad: MMD DEVAD + * @addr: PHY address on the MII bus + * @data: data to write in the MMD register + * + * Description: Write data from the MMD registers of the specified + * phy address. + * To write these register we have: + * 1) Write reg 13 // DEVAD + * 2) Write reg 14 // MMD Address + * 3) Write reg 13 // MMD Data Command for MMD DEVAD + * 3) Write reg 14 // Write MMD data + */ +static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad, + int addr, u32 data) +{ + mmd_phy_indirect(bus, prtad, devad, addr); + + /* Write the data into MMD's selected register */ + bus->write(bus, addr, MII_MMD_DATA, data); +} + +static u32 phy_eee_to_adv(u16 eee_adv) +{ + u32 adv = 0; + + if (eee_adv & MDIO_EEE_100TX) + adv |= ADVERTISED_100baseT_Full; + if (eee_adv & MDIO_EEE_1000T) + adv |= ADVERTISED_1000baseT_Full; + if (eee_adv & MDIO_EEE_10GT) + adv |= ADVERTISED_10000baseT_Full; + if (eee_adv & MDIO_EEE_1000KX) + adv |= ADVERTISED_1000baseKX_Full; + if (eee_adv & MDIO_EEE_10GKX4) + adv |= ADVERTISED_10000baseKX4_Full; + if (eee_adv & MDIO_EEE_10GKR) + adv |= ADVERTISED_10000baseKR_Full; + + return adv; +} + +static u32 phy_eee_to_supported(u16 eee_caported) +{ + u32 supported = 0; + + if (eee_caported & MDIO_EEE_100TX) + supported |= SUPPORTED_100baseT_Full; + if (eee_caported & MDIO_EEE_1000T) + supported |= SUPPORTED_1000baseT_Full; + if (eee_caported & MDIO_EEE_10GT) + supported |= SUPPORTED_10000baseT_Full; + if (eee_caported & MDIO_EEE_1000KX) + supported |= SUPPORTED_1000baseKX_Full; + if (eee_caported & MDIO_EEE_10GKX4) + supported |= SUPPORTED_10000baseKX4_Full; + if (eee_caported & MDIO_EEE_10GKR) + supported |= SUPPORTED_10000baseKR_Full; + + return supported; +} + +static u16 phy_adv_to_eee(u32 adv) +{ + u16 reg = 0; + + if (adv & ADVERTISED_100baseT_Full) + reg |= MDIO_EEE_100TX; + if (adv & ADVERTISED_1000baseT_Full) + reg |= MDIO_EEE_1000T; + if (adv & ADVERTISED_10000baseT_Full) + reg |= MDIO_EEE_10GT; + if (adv & ADVERTISED_1000baseKX_Full) + reg |= MDIO_EEE_1000KX; + if (adv & ADVERTISED_10000baseKX4_Full) + reg |= MDIO_EEE_10GKX4; + if (adv & ADVERTISED_10000baseKR_Full) + reg |= MDIO_EEE_10GKR; + + return reg; +} + +/** + * phy_init_eee - init and check the EEE feature + * @phydev: target phy_device struct + * @clk_stop_enable: PHY may stop the clock during LPI + * + * Description: it checks if the Energy-Efficient Ethernet (EEE) + * is supported by looking at the MMD registers 3.20 and 7.60/61 + * and it programs the MMD register 3.0 setting the "Clock stop enable" + * bit if required. + */ +int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) +{ + int ret = -EPROTONOSUPPORT; + + /* According to 802.3az,the EEE is supported only in full duplex-mode. + * Also EEE feature is active when core is operating with MII, GMII + * or RGMII. + */ + if ((phydev->duplex == DUPLEX_FULL) && + ((phydev->interface == PHY_INTERFACE_MODE_MII) || + (phydev->interface == PHY_INTERFACE_MODE_GMII) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { + int eee_lp, eee_cap, eee_adv; + u32 lp, cap, adv; + int idx, status; + + /* Read phy status to properly get the right settings */ + status = phy_read_status(phydev); + if (status) + return status; + + /* First check if the EEE ability is supported */ + eee_cap = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE, + MDIO_MMD_PCS, phydev->addr); + if (eee_cap < 0) + return eee_cap; + + cap = phy_eee_to_supported(eee_cap); + if (!cap) + goto eee_exit; + + /* Check which link settings negotiated and verify it in + * the EEE advertising registers. + */ + eee_lp = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE, + MDIO_MMD_AN, phydev->addr); + if (eee_lp < 0) + return eee_lp; + + eee_adv = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, + MDIO_MMD_AN, phydev->addr); + if (eee_adv < 0) + return eee_adv; + + adv = phy_eee_to_adv(eee_adv); + lp = phy_eee_to_adv(eee_lp); + idx = phy_find_setting(phydev->speed, phydev->duplex); + if ((lp & adv & settings[idx].setting)) + goto eee_exit; + + if (clk_stop_enable) { + /* Configure the PHY to stop receiving xMII + * clock while it is signaling LPI. + */ + int val = phy_read_mmd_indirect(phydev->bus, MDIO_CTRL1, + MDIO_MMD_PCS, + phydev->addr); + if (val < 0) + return val; + + val |= MDIO_PCS_CTRL1_CLKSTOP_EN; + phy_write_mmd_indirect(phydev->bus, MDIO_CTRL1, + MDIO_MMD_PCS, phydev->addr, val); + } + + ret = 0; /* EEE supported */ + } + +eee_exit: + return ret; +} +EXPORT_SYMBOL(phy_init_eee); + +/** + * phy_get_eee_err - report the EEE wake error count + * @phydev: target phy_device struct + * + * Description: it is to report the number of time where the PHY + * failed to complete its normal wake sequence. + */ +int phy_get_eee_err(struct phy_device *phydev) +{ + return phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_WK_ERR, + MDIO_MMD_PCS, phydev->addr); + +} +EXPORT_SYMBOL(phy_get_eee_err); + +/** + * phy_ethtool_get_eee - get EEE supported and status + * @phydev: target phy_device struct + * @data: ethtool_eee data + * + * Description: it reportes the Supported/Advertisement/LP Advertisement + * capabilities. + */ +int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data) +{ + int val; + + /* Get Supported EEE */ + val = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE, + MDIO_MMD_PCS, phydev->addr); + if (val < 0) + return val; + data->supported = phy_eee_to_supported(val); + + /* Get advertisement EEE */ + val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, + MDIO_MMD_AN, phydev->addr); + if (val < 0) + return val; + data->advertised = phy_eee_to_adv(val); + + /* Get LP advertisement EEE */ + val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE, + MDIO_MMD_AN, phydev->addr); + if (val < 0) + return val; + data->lp_advertised = phy_eee_to_adv(val); + + return 0; +} +EXPORT_SYMBOL(phy_ethtool_get_eee); + +/** + * phy_ethtool_set_eee - set EEE supported and status + * @phydev: target phy_device struct + * @data: ethtool_eee data + * + * Description: it is to program the Advertisement EEE register. + */ +int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) +{ + int val; + + val = phy_adv_to_eee(data->advertised); + phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN, + phydev->addr, val); + + return 0; +} +EXPORT_SYMBOL(phy_ethtool_set_eee); diff --git a/include/linux/mdio.h b/include/linux/mdio.h index dfb947959ec9..7cccafe50e7b 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -43,7 +43,11 @@ #define MDIO_PKGID2 15 #define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */ #define MDIO_AN_LPA 19 /* AN LP abilities (base page) */ +#define MDIO_PCS_EEE_ABLE 20 /* EEE Capability register */ +#define MDIO_PCS_EEE_WK_ERR 22 /* EEE wake error counter */ #define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */ +#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */ +#define MDIO_AN_EEE_LPABLE 61 /* EEE link partner ability */ /* Media-dependent registers. */ #define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */ @@ -56,7 +60,6 @@ #define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */ #define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */ #define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */ -#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */ /* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */ #define MDIO_PMA_LASI_RXCTRL 0x9000 /* RX_ALARM control */ @@ -82,6 +85,7 @@ #define MDIO_AN_CTRL1_RESTART BMCR_ANRESTART #define MDIO_AN_CTRL1_ENABLE BMCR_ANENABLE #define MDIO_AN_CTRL1_XNP 0x2000 /* Enable extended next page */ +#define MDIO_PCS_CTRL1_CLKSTOP_EN 0x400 /* Stop the clock during LPI */ /* 10 Gb/s */ #define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00) @@ -237,9 +241,25 @@ #define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */ #define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */ -/* AN EEE Advertisement register. */ -#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */ -#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */ +/* EEE Supported/Advertisement/LP Advertisement registers. + * + * EEE capability Register (3.20), Advertisement (7.60) and + * Link partner ability (7.61) registers have and can use the same identical + * bit masks. + */ +#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */ +#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */ +/* Note: the two defines above can be potentially used by the user-land + * and cannot remove them now. + * So, we define the new generic MDIO_EEE_100TX and MDIO_EEE_1000T macros + * using the previous ones (that can be considered obsolete). + */ +#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */ +#define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */ +#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ +#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ +#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ +#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ /* LASI RX_ALARM control/status registers. */ #define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */ diff --git a/include/linux/mii.h b/include/linux/mii.h index 2783eca629a0..8ef3a7a11592 100644 --- a/include/linux/mii.h +++ b/include/linux/mii.h @@ -21,6 +21,8 @@ #define MII_EXPANSION 0x06 /* Expansion register */ #define MII_CTRL1000 0x09 /* 1000BASE-T control */ #define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ +#define MII_MMD_DATA 0x0e /* MMD Access Data Register */ #define MII_ESTATUS 0x0f /* Extended Status */ #define MII_DCOUNTER 0x12 /* Disconnect counter */ #define MII_FCSCOUNTER 0x13 /* False carrier counter */ @@ -141,6 +143,13 @@ #define FLOW_CTRL_TX 0x01 #define FLOW_CTRL_RX 0x02 +/* MMD Access Control register fields */ +#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/ +#define MII_MMD_CTRL_ADDR 0x0000 /* Address */ +#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */ +#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */ +#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */ + /* This structure is used in all SIOCxMIIxxx ioctl calls */ struct mii_ioctl_data { __u16 phy_id; diff --git a/include/linux/phy.h b/include/linux/phy.h index 7eac80a2557b..c35299e4da8e 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -554,6 +554,11 @@ int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, int (*run)(struct phy_device *)); int phy_scan_fixups(struct phy_device *phydev); +int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable); +int phy_get_eee_err(struct phy_device *phydev); +int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data); +int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data); + int __init mdio_bus_init(void); void mdio_bus_exit(void); -- GitLab From 17621e11fda095459e2f986c019f52686c7a4ffb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:25:38 +0200 Subject: [PATCH 3352/6849] ACPI / PM: Drop pm_message_t argument from device suspend callback None of the drivers implementing the ACPI device suspend callback uses the pm_message_t argument of it, so this argument may be dropped entirely from that callback. This will simplify switching the ACPI bus type to PM handling based on struct dev_pm_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/fan.c | 4 ++-- drivers/acpi/processor_idle.c | 2 +- drivers/acpi/scan.c | 2 +- drivers/platform/x86/hp_accel.c | 2 +- drivers/platform/x86/sony-laptop.c | 2 +- drivers/platform/x86/toshiba_acpi.c | 3 +-- include/acpi/acpi_bus.h | 3 +-- include/acpi/processor.h | 2 +- 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 0f0356ca1a9e..ed1e58dc19d8 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -46,7 +46,7 @@ MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_remove(struct acpi_device *device, int type); -static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state); +static int acpi_fan_suspend(struct acpi_device *device); static int acpi_fan_resume(struct acpi_device *device); static const struct acpi_device_id fan_device_ids[] = { @@ -183,7 +183,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return 0; } -static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) +static int acpi_fan_suspend(struct acpi_device *device) { if (!device) return -EINVAL; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 47a8caa89dbe..e28af8d38239 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -241,7 +241,7 @@ static void acpi_idle_bm_rld_restore(void) acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); } -int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) +int acpi_processor_suspend(struct acpi_device * device) { if (acpi_idle_suspend == 1) return 0; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c8a1f3b68110..ec65ec9c529f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -296,7 +296,7 @@ static int acpi_device_suspend(struct device *dev, pm_message_t state) struct acpi_driver *acpi_drv = acpi_dev->driver; if (acpi_drv && acpi_drv->ops.suspend) - return acpi_drv->ops.suspend(acpi_dev, state); + return acpi_drv->ops.suspend(acpi_dev); return 0; } diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 22b2dfa73148..c9e052033173 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -353,7 +353,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) #ifdef CONFIG_PM -static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) +static int lis3lv02d_suspend(struct acpi_device *device) { /* make sure the device is off when we suspend */ lis3lv02d_poweroff(&lis3_dev); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 210d4ae547c2..2b604f376fdb 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -4243,7 +4243,7 @@ err_free_resources: return result; } -static int sony_pic_suspend(struct acpi_device *device, pm_message_t state) +static int sony_pic_suspend(struct acpi_device *device) { if (sony_pic_disable(device)) return -ENXIO; diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index dab10f6edcd4..fd90b6da0a4b 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1296,8 +1296,7 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) } } -static int toshiba_acpi_suspend(struct acpi_device *acpi_dev, - pm_message_t state) +static int toshiba_acpi_suspend(struct acpi_device *acpi_dev) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 result; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 9e6e1c6eb60a..c2bbec76ba10 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -117,8 +117,7 @@ struct acpi_device; typedef int (*acpi_op_add) (struct acpi_device * device); typedef int (*acpi_op_remove) (struct acpi_device * device, int type); typedef int (*acpi_op_start) (struct acpi_device * device); -typedef int (*acpi_op_suspend) (struct acpi_device * device, - pm_message_t state); +typedef int (*acpi_op_suspend) (struct acpi_device * device); typedef int (*acpi_op_resume) (struct acpi_device * device); typedef int (*acpi_op_bind) (struct acpi_device * device); typedef int (*acpi_op_unbind) (struct acpi_device * device); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 9d650476d5dc..8a1894a6eba2 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -334,7 +334,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr); int acpi_processor_hotplug(struct acpi_processor *pr); int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device); -int acpi_processor_suspend(struct acpi_device * device, pm_message_t state); +int acpi_processor_suspend(struct acpi_device * device); int acpi_processor_resume(struct acpi_device * device); extern struct cpuidle_driver acpi_idle_driver; -- GitLab From 707156e600dbfd89e129239ee1d1d934cbe2119c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:25:49 +0200 Subject: [PATCH 3353/6849] ACPI / PM: Make acpi_bus_type use struct dev_pm_ops for PM handling Make the acpi_bus_type bus type define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct bus_type. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ec65ec9c529f..7c37be53334d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -290,7 +290,7 @@ static void acpi_device_release(struct device *dev) kfree(acpi_dev); } -static int acpi_device_suspend(struct device *dev, pm_message_t state) +static int acpi_device_suspend(struct device *dev) { struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; @@ -310,6 +310,8 @@ static int acpi_device_resume(struct device *dev) return 0; } +static SIMPLE_DEV_PM_OPS(acpi_bus_pm, acpi_device_suspend, acpi_device_resume); + static int acpi_bus_match(struct device *dev, struct device_driver *drv) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -441,12 +443,11 @@ static int acpi_device_remove(struct device * dev) struct bus_type acpi_bus_type = { .name = "acpi", - .suspend = acpi_device_suspend, - .resume = acpi_device_resume, .match = acpi_bus_match, .probe = acpi_device_probe, .remove = acpi_device_remove, .uevent = acpi_device_uevent, + .pm = &acpi_bus_pm, }; static int acpi_device_register(struct acpi_device *device) -- GitLab From 67699c5f0c68f5dc49e92b172d372c99cdd2bf09 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:25:59 +0200 Subject: [PATCH 3354/6849] ACPI / PM: Make acpi_bus_type use driver struct dev_pm_ops callbacks Modify acpi_bus_type so that it executes PM callbacks provided by drivers through their struct dev_pm_ops objects, if present, while still allowing the legacy ACPI PM callbacks to take precedence. This will make it possible to convert ACPI drivers one by one to handling PM through struct dev_pm_ops instead of the legacy way. The code added by this change is temporary and will be removed when all of the drivers in question have been switched over to the PM handling based on struct dev_pm_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 60 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7c37be53334d..af924ba85148 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -290,27 +290,61 @@ static void acpi_device_release(struct device *dev) kfree(acpi_dev); } -static int acpi_device_suspend(struct device *dev) +#define ACPI_DEV_PM_CALLBACK(dev, callback, legacy_cb) \ +({ \ + struct acpi_device *__acpi_dev = to_acpi_device(dev); \ + struct acpi_driver *__acpi_drv = __acpi_dev->driver; \ + struct device_driver *__drv = dev->driver; \ + int __ret; \ + \ + if (__acpi_drv && __acpi_drv->ops.legacy_cb) \ + __ret = __acpi_drv->ops.legacy_cb(__acpi_dev); \ + else if (__drv && __drv->pm && __drv->pm->callback) \ + __ret = __drv->pm->callback(dev); \ + else \ + __ret = 0; \ + \ + __ret; \ +}) + +static int acpi_pm_suspend(struct device *dev) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; + return ACPI_DEV_PM_CALLBACK(dev, suspend, suspend); +} - if (acpi_drv && acpi_drv->ops.suspend) - return acpi_drv->ops.suspend(acpi_dev); - return 0; +static int acpi_pm_resume(struct device *dev) +{ + return ACPI_DEV_PM_CALLBACK(dev, resume, resume); } -static int acpi_device_resume(struct device *dev) +static int acpi_pm_freeze(struct device *dev) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; + return ACPI_DEV_PM_CALLBACK(dev, freeze, suspend); +} - if (acpi_drv && acpi_drv->ops.resume) - return acpi_drv->ops.resume(acpi_dev); - return 0; +static int acpi_pm_thaw(struct device *dev) +{ + return ACPI_DEV_PM_CALLBACK(dev, thaw, resume); +} + +static int acpi_pm_poweroff(struct device *dev) +{ + return ACPI_DEV_PM_CALLBACK(dev, poweroff, suspend); } -static SIMPLE_DEV_PM_OPS(acpi_bus_pm, acpi_device_suspend, acpi_device_resume); +static int acpi_pm_restore(struct device *dev) +{ + return ACPI_DEV_PM_CALLBACK(dev, restore, resume); +} + +static const struct dev_pm_ops acpi_bus_pm = { + .suspend = acpi_pm_suspend, + .resume = acpi_pm_resume, + .freeze = acpi_pm_freeze, + .thaw = acpi_pm_thaw, + .poweroff = acpi_pm_poweroff, + .restore = acpi_pm_restore, +}; static int acpi_bus_match(struct device *dev, struct device_driver *drv) { -- GitLab From 62fcbdd95ccabcff7b41a859032496f6ca492045 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:07 +0200 Subject: [PATCH 3355/6849] ACPI: Use struct dev_pm_ops for power management in the fan driver Make the ACPI fan driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/fan.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index ed1e58dc19d8..669d9ee80d16 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -46,8 +46,6 @@ MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_remove(struct acpi_device *device, int type); -static int acpi_fan_suspend(struct acpi_device *device); -static int acpi_fan_resume(struct acpi_device *device); static const struct acpi_device_id fan_device_ids[] = { {"PNP0C0B", 0}, @@ -55,6 +53,10 @@ static const struct acpi_device_id fan_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, fan_device_ids); +static int acpi_fan_suspend(struct device *dev); +static int acpi_fan_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); + static struct acpi_driver acpi_fan_driver = { .name = "fan", .class = ACPI_FAN_CLASS, @@ -62,9 +64,8 @@ static struct acpi_driver acpi_fan_driver = { .ops = { .add = acpi_fan_add, .remove = acpi_fan_remove, - .suspend = acpi_fan_suspend, - .resume = acpi_fan_resume, }, + .drv.pm = &acpi_fan_pm, }; /* thermal cooling device callbacks */ @@ -183,24 +184,24 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return 0; } -static int acpi_fan_suspend(struct acpi_device *device) +static int acpi_fan_suspend(struct device *dev) { - if (!device) + if (!dev) return -EINVAL; - acpi_bus_set_power(device->handle, ACPI_STATE_D0); + acpi_bus_set_power(to_acpi_device(dev)->handle, ACPI_STATE_D0); return AE_OK; } -static int acpi_fan_resume(struct acpi_device *device) +static int acpi_fan_resume(struct device *dev) { int result; - if (!device) + if (!dev) return -EINVAL; - result = acpi_bus_update_power(device->handle, NULL); + result = acpi_bus_update_power(to_acpi_device(dev)->handle, NULL); if (result) printk(KERN_ERR PREFIX "Error updating fan power state\n"); -- GitLab From 167cffb646aa4a7f3267b07eae1af16b54bc0e9b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:18 +0200 Subject: [PATCH 3356/6849] ACPI: Use struct dev_pm_ops for power management in the thermal driver Make the ACPI thermal driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 7dbebea1ec31..21dd4c268aef 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -98,7 +98,6 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); -static int acpi_thermal_resume(struct acpi_device *device); static void acpi_thermal_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id thermal_device_ids[] = { @@ -107,6 +106,9 @@ static const struct acpi_device_id thermal_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, thermal_device_ids); +static int acpi_thermal_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); + static struct acpi_driver acpi_thermal_driver = { .name = "thermal", .class = ACPI_THERMAL_CLASS, @@ -114,9 +116,9 @@ static struct acpi_driver acpi_thermal_driver = { .ops = { .add = acpi_thermal_add, .remove = acpi_thermal_remove, - .resume = acpi_thermal_resume, .notify = acpi_thermal_notify, }, + .drv.pm = &acpi_thermal_pm, }; struct acpi_thermal_state { @@ -1041,16 +1043,17 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) return 0; } -static int acpi_thermal_resume(struct acpi_device *device) +static int acpi_thermal_resume(struct device *dev) { - struct acpi_thermal *tz = NULL; + struct acpi_thermal *tz; int i, j, power_state, result; - - if (!device || !acpi_driver_data(device)) + if (!dev) return -EINVAL; - tz = acpi_driver_data(device); + tz = acpi_driver_data(to_acpi_device(dev)); + if (!tz) + return -EINVAL; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { if (!(&tz->trips.active[i])) -- GitLab From e8110b64af8b7cce96d1878276770c76cb9c01d5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:26 +0200 Subject: [PATCH 3357/6849] ACPI: Use struct dev_pm_ops for power management in processor driver Make the ACPI processor driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 6 ++++-- drivers/acpi/processor_idle.c | 4 ++-- include/acpi/processor.h | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 0734086537b8..13103aeb0c4f 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -93,6 +93,9 @@ static const struct acpi_device_id processor_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); +static SIMPLE_DEV_PM_OPS(acpi_processor_pm, + acpi_processor_suspend, acpi_processor_resume); + static struct acpi_driver acpi_processor_driver = { .name = "processor", .class = ACPI_PROCESSOR_CLASS, @@ -100,10 +103,9 @@ static struct acpi_driver acpi_processor_driver = { .ops = { .add = acpi_processor_add, .remove = acpi_processor_remove, - .suspend = acpi_processor_suspend, - .resume = acpi_processor_resume, .notify = acpi_processor_notify, }, + .drv.pm = &acpi_processor_pm, }; #define INSTALL_NOTIFY_HANDLER 1 diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e28af8d38239..6d9ec3e0b52e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -241,7 +241,7 @@ static void acpi_idle_bm_rld_restore(void) acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); } -int acpi_processor_suspend(struct acpi_device * device) +int acpi_processor_suspend(struct device *dev) { if (acpi_idle_suspend == 1) return 0; @@ -251,7 +251,7 @@ int acpi_processor_suspend(struct acpi_device * device) return 0; } -int acpi_processor_resume(struct acpi_device * device) +int acpi_processor_resume(struct device *dev) { if (acpi_idle_suspend == 0) return 0; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 8a1894a6eba2..ac3bff6fbbb0 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -334,8 +334,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr); int acpi_processor_hotplug(struct acpi_processor *pr); int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device); -int acpi_processor_suspend(struct acpi_device * device); -int acpi_processor_resume(struct acpi_device * device); +int acpi_processor_suspend(struct device *dev); +int acpi_processor_resume(struct device *dev); extern struct cpuidle_driver acpi_idle_driver; /* in processor_thermal.c */ -- GitLab From ccda70698057fd8dae7beeac147cdeead33dd543 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:35 +0200 Subject: [PATCH 3358/6849] ACPI: Use struct dev_pm_ops for power management in the AC driver Make the ACPI AC adapter driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ac.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 6512b20aeccd..ff9f6bd48301 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -61,7 +61,6 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_remove(struct acpi_device *device, int type); -static int acpi_ac_resume(struct acpi_device *device); static void acpi_ac_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id ac_device_ids[] = { @@ -70,6 +69,9 @@ static const struct acpi_device_id ac_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ac_device_ids); +static int acpi_ac_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); + static struct acpi_driver acpi_ac_driver = { .name = "ac", .class = ACPI_AC_CLASS, @@ -78,9 +80,9 @@ static struct acpi_driver acpi_ac_driver = { .ops = { .add = acpi_ac_add, .remove = acpi_ac_remove, - .resume = acpi_ac_resume, .notify = acpi_ac_notify, }, + .drv.pm = &acpi_ac_pm, }; struct acpi_ac { @@ -309,13 +311,18 @@ static int acpi_ac_add(struct acpi_device *device) return result; } -static int acpi_ac_resume(struct acpi_device *device) +static int acpi_ac_resume(struct device *dev) { struct acpi_ac *ac; unsigned old_state; - if (!device || !acpi_driver_data(device)) + + if (!dev) return -EINVAL; - ac = acpi_driver_data(device); + + ac = acpi_driver_data(to_acpi_device(dev)); + if (!ac) + return -EINVAL; + old_state = ac->state; if (acpi_ac_get_state(ac)) return 0; -- GitLab From a6f50dc8ef26819c510cda84477dd60e3d1c90bb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:43 +0200 Subject: [PATCH 3359/6849] ACPI: Use struct dev_pm_ops for power management in the battery driver Make the ACPI battery driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 7dd3f9fb9f3f..023f9c8534d0 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1044,17 +1044,24 @@ static int acpi_battery_remove(struct acpi_device *device, int type) } /* this is needed to learn about changes made in suspended state */ -static int acpi_battery_resume(struct acpi_device *device) +static int acpi_battery_resume(struct device *dev) { struct acpi_battery *battery; - if (!device) + + if (!dev) return -EINVAL; - battery = acpi_driver_data(device); + + battery = acpi_driver_data(to_acpi_device(dev)); + if (!battery) + return -EINVAL; + battery->update_time = 0; acpi_battery_update(battery); return 0; } +static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); + static struct acpi_driver acpi_battery_driver = { .name = "battery", .class = ACPI_BATTERY_CLASS, @@ -1062,10 +1069,10 @@ static struct acpi_driver acpi_battery_driver = { .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = acpi_battery_add, - .resume = acpi_battery_resume, .remove = acpi_battery_remove, .notify = acpi_battery_notify, }, + .drv.pm = &acpi_battery_pm, }; static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) -- GitLab From 1be532de834ab7b18ce20dc2e56e724770beb79d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:51 +0200 Subject: [PATCH 3360/6849] ACPI: Use struct dev_pm_ops for power management in the button driver Make the ACPI button driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index d27d072472f9..79d4c22f7a6d 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -76,19 +76,21 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids); static int acpi_button_add(struct acpi_device *device); static int acpi_button_remove(struct acpi_device *device, int type); -static int acpi_button_resume(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); +static int acpi_button_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); + static struct acpi_driver acpi_button_driver = { .name = "button", .class = ACPI_BUTTON_CLASS, .ids = button_device_ids, .ops = { .add = acpi_button_add, - .resume = acpi_button_resume, .remove = acpi_button_remove, .notify = acpi_button_notify, }, + .drv.pm = &acpi_button_pm, }; struct acpi_button { @@ -308,8 +310,9 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) } } -static int acpi_button_resume(struct acpi_device *device) +static int acpi_button_resume(struct device *dev) { + struct acpi_device *device = to_acpi_device(dev); struct acpi_button *button = acpi_driver_data(device); if (button->type == ACPI_BUTTON_TYPE_LID) -- GitLab From e579e2dd8f056cfeaf4d2b313a35ddafb3c4e531 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:26:59 +0200 Subject: [PATCH 3361/6849] ACPI: Use struct dev_pm_ops for power management in the power driver Make the ACPI power resource driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index dd6d6a3c6780..894d45c6bc67 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -60,7 +60,6 @@ ACPI_MODULE_NAME("power"); static int acpi_power_add(struct acpi_device *device); static int acpi_power_remove(struct acpi_device *device, int type); -static int acpi_power_resume(struct acpi_device *device); static const struct acpi_device_id power_device_ids[] = { {ACPI_POWER_HID, 0}, @@ -68,6 +67,9 @@ static const struct acpi_device_id power_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, power_device_ids); +static int acpi_power_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); + static struct acpi_driver acpi_power_driver = { .name = "power", .class = ACPI_POWER_CLASS, @@ -75,8 +77,8 @@ static struct acpi_driver acpi_power_driver = { .ops = { .add = acpi_power_add, .remove = acpi_power_remove, - .resume = acpi_power_resume, }, + .drv.pm = &acpi_power_pm, }; /* @@ -771,14 +773,16 @@ static int acpi_power_remove(struct acpi_device *device, int type) return 0; } -static int acpi_power_resume(struct acpi_device *device) +static int acpi_power_resume(struct device *dev) { int result = 0, state; + struct acpi_device *device; struct acpi_power_resource *resource; - if (!device) + if (!dev) return -EINVAL; + device = to_acpi_device(dev); resource = acpi_driver_data(device); if (!resource) return -EINVAL; -- GitLab From d202f77d2eb707d03a16adf952a397675cb2fc81 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:07 +0200 Subject: [PATCH 3362/6849] ACPI: Use struct dev_pm_ops for power management in the SBS driver Make the ACPI Smart Battery System driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sbs.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 6e36d0c0057c..c0b9aa5faf4c 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -988,16 +988,18 @@ static void acpi_sbs_rmdirs(void) #endif } -static int acpi_sbs_resume(struct acpi_device *device) +static int acpi_sbs_resume(struct device *dev) { struct acpi_sbs *sbs; - if (!device) + if (!dev) return -EINVAL; - sbs = device->driver_data; + sbs = to_acpi_device(dev)->driver_data; acpi_sbs_callback(sbs); return 0; } +static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); + static struct acpi_driver acpi_sbs_driver = { .name = "sbs", .class = ACPI_SBS_CLASS, @@ -1005,8 +1007,8 @@ static struct acpi_driver acpi_sbs_driver = { .ops = { .add = acpi_sbs_add, .remove = acpi_sbs_remove, - .resume = acpi_sbs_resume, }, + .drv.pm = &acpi_sbs_pm, }; static int __init acpi_sbs_init(void) -- GitLab From 43d2fd3b9d5be9be879179bec4f08c0c47d1ccd7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:16 +0200 Subject: [PATCH 3363/6849] toshiba_acpi: Use struct dev_pm_ops for power management Make the toshiba_acpi driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/toshiba_acpi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index fd90b6da0a4b..c13ba5bac93f 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1296,9 +1296,9 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) } } -static int toshiba_acpi_suspend(struct acpi_device *acpi_dev) +static int toshiba_acpi_suspend(struct device *device) { - struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); + struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); u32 result; if (dev->hotkey_dev) @@ -1307,9 +1307,9 @@ static int toshiba_acpi_suspend(struct acpi_device *acpi_dev) return 0; } -static int toshiba_acpi_resume(struct acpi_device *acpi_dev) +static int toshiba_acpi_resume(struct device *device) { - struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); + struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); u32 result; if (dev->hotkey_dev) @@ -1318,6 +1318,9 @@ static int toshiba_acpi_resume(struct acpi_device *acpi_dev) return 0; } +static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, + toshiba_acpi_suspend, toshiba_acpi_resume); + static struct acpi_driver toshiba_acpi_driver = { .name = "Toshiba ACPI driver", .owner = THIS_MODULE, @@ -1327,9 +1330,8 @@ static struct acpi_driver toshiba_acpi_driver = { .add = toshiba_acpi_add, .remove = toshiba_acpi_remove, .notify = toshiba_acpi_notify, - .suspend = toshiba_acpi_suspend, - .resume = toshiba_acpi_resume, }, + .drv.pm = &toshiba_acpi_pm, }; static int __init toshiba_acpi_init(void) -- GitLab From 4ce05b42603195386fa783c4f070ecc8682c189f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:25 +0200 Subject: [PATCH 3364/6849] hp_accel: Use struct dev_pm_ops for power management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the hp_accel driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki Reviewed-by: Éric Piel --- drivers/platform/x86/hp_accel.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index c9e052033173..f4d91154ad67 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -353,20 +353,22 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) #ifdef CONFIG_PM -static int lis3lv02d_suspend(struct acpi_device *device) +static int lis3lv02d_suspend(struct device *dev) { /* make sure the device is off when we suspend */ lis3lv02d_poweroff(&lis3_dev); return 0; } -static int lis3lv02d_resume(struct acpi_device *device) +static int lis3lv02d_resume(struct device *dev) { return lis3lv02d_poweron(&lis3_dev); } + +static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); +#define HP_ACCEL_PM (&hp_accel_pm) #else -#define lis3lv02d_suspend NULL -#define lis3lv02d_resume NULL +#define HP_ACCEL_PM NULL #endif /* For the HP MDPS aka 3D Driveguard */ @@ -377,9 +379,8 @@ static struct acpi_driver lis3lv02d_driver = { .ops = { .add = lis3lv02d_add, .remove = lis3lv02d_remove, - .suspend = lis3lv02d_suspend, - .resume = lis3lv02d_resume, - } + }, + .drv.pm = HP_ACCEL_PM, }; static int __init lis3lv02d_init_module(void) -- GitLab From bb6b98d6e4f9aada309c54ebd6df1cc6151f3af1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:33 +0200 Subject: [PATCH 3365/6849] sony-laptop: Use struct dev_pm_ops for power management Make the sony-laptop driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/sony-laptop.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 2b604f376fdb..c7a236240785 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1452,7 +1452,7 @@ static void sony_nc_function_resume(void) &result); } -static int sony_nc_resume(struct acpi_device *device) +static int sony_nc_resume(struct device *dev) { struct sony_nc_value *item; acpi_handle handle; @@ -1484,6 +1484,8 @@ static int sony_nc_resume(struct acpi_device *device) return 0; } +static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); + static void sony_nc_rfkill_cleanup(void) { int i; @@ -2728,9 +2730,9 @@ static struct acpi_driver sony_nc_driver = { .ops = { .add = sony_nc_add, .remove = sony_nc_remove, - .resume = sony_nc_resume, .notify = sony_nc_notify, }, + .drv.pm = &sony_nc_pm, }; /*********** SPIC (SNY6001) Device ***********/ @@ -4243,19 +4245,22 @@ err_free_resources: return result; } -static int sony_pic_suspend(struct acpi_device *device) +static int sony_pic_suspend(struct device *dev) { - if (sony_pic_disable(device)) + if (sony_pic_disable(to_acpi_device(dev))) return -ENXIO; return 0; } -static int sony_pic_resume(struct acpi_device *device) +static int sony_pic_resume(struct device *dev) { - sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); + sony_pic_enable(to_acpi_device(dev), + spic_dev.cur_ioport, spic_dev.cur_irq); return 0; } +static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); + static const struct acpi_device_id sony_pic_device_ids[] = { {SONY_PIC_HID, 0}, {"", 0}, @@ -4269,9 +4274,8 @@ static struct acpi_driver sony_pic_driver = { .ops = { .add = sony_pic_add, .remove = sony_pic_remove, - .suspend = sony_pic_suspend, - .resume = sony_pic_resume, }, + .drv.pm = &sony_pic_pm, }; static struct dmi_system_id __initdata sonypi_dmi_table[] = { -- GitLab From a7377419624c31d71e35485251f8548c728d5999 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:40 +0200 Subject: [PATCH 3366/6849] panasonic-laptop: Use struct dev_pm_ops for power management Make the panasonic-laptop driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/panasonic-laptop.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index ffff8b4b4949..24480074bcf0 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -177,7 +177,6 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, static int acpi_pcc_hotkey_add(struct acpi_device *device); static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); -static int acpi_pcc_hotkey_resume(struct acpi_device *device); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id pcc_device_ids[] = { @@ -189,6 +188,9 @@ static const struct acpi_device_id pcc_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, pcc_device_ids); +static int acpi_pcc_hotkey_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); + static struct acpi_driver acpi_pcc_driver = { .name = ACPI_PCC_DRIVER_NAME, .class = ACPI_PCC_CLASS, @@ -196,9 +198,9 @@ static struct acpi_driver acpi_pcc_driver = { .ops = { .add = acpi_pcc_hotkey_add, .remove = acpi_pcc_hotkey_remove, - .resume = acpi_pcc_hotkey_resume, .notify = acpi_pcc_hotkey_notify, }, + .drv.pm = &acpi_pcc_hotkey_pm, }; static const struct key_entry panasonic_keymap[] = { @@ -538,11 +540,15 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc) /* kernel module interface */ -static int acpi_pcc_hotkey_resume(struct acpi_device *device) +static int acpi_pcc_hotkey_resume(struct device *dev) { - struct pcc_acpi *pcc = acpi_driver_data(device); + struct pcc_acpi *pcc; + + if (!dev) + return -EINVAL; - if (device == NULL || pcc == NULL) + pcc = acpi_driver_data(to_acpi_device(dev)); + if (!pcc) return -EINVAL; ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n", -- GitLab From d69239ae5847b29ea1902b2dd86f5afa41144ba3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:48 +0200 Subject: [PATCH 3367/6849] toshiba_bluetooth: Use struct dev_pm_ops for power management Make the toshiba_bluetooth driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki Reviewed-by: Vikram Dhillon --- drivers/platform/x86/toshiba_bluetooth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 5fb7186694df..715a43cb5e3c 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -34,7 +34,6 @@ MODULE_LICENSE("GPL"); static int toshiba_bt_rfkill_add(struct acpi_device *device); static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type); static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); -static int toshiba_bt_resume(struct acpi_device *device); static const struct acpi_device_id bt_device_ids[] = { { "TOS6205", 0}, @@ -42,6 +41,9 @@ static const struct acpi_device_id bt_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, bt_device_ids); +static int toshiba_bt_resume(struct device *dev); +static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); + static struct acpi_driver toshiba_bt_rfkill_driver = { .name = "Toshiba BT", .class = "Toshiba", @@ -50,9 +52,9 @@ static struct acpi_driver toshiba_bt_rfkill_driver = { .add = toshiba_bt_rfkill_add, .remove = toshiba_bt_rfkill_remove, .notify = toshiba_bt_rfkill_notify, - .resume = toshiba_bt_resume, }, .owner = THIS_MODULE, + .drv.pm = &toshiba_bt_pm, }; @@ -88,9 +90,9 @@ static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) toshiba_bluetooth_enable(device->handle); } -static int toshiba_bt_resume(struct acpi_device *device) +static int toshiba_bt_resume(struct device *dev) { - return toshiba_bluetooth_enable(device->handle); + return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); } static int toshiba_bt_rfkill_add(struct acpi_device *device) -- GitLab From 44cb98c48e19f506e178c519f5da2c23a156e002 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:27:55 +0200 Subject: [PATCH 3368/6849] xo15-ebook: Use struct dev_pm_ops for power management Make the xo15-ebook driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/xo15-ebook.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index fad153dc0355..849c07c13bf6 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c @@ -77,11 +77,13 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event) } } -static int ebook_switch_resume(struct acpi_device *device) +static int ebook_switch_resume(struct device *dev) { - return ebook_send_state(device); + return ebook_send_state(to_acpi_device(dev)); } +static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); + static int ebook_switch_add(struct acpi_device *device) { struct ebook_switch *button; @@ -161,10 +163,10 @@ static struct acpi_driver xo15_ebook_driver = { .ids = ebook_device_ids, .ops = { .add = ebook_switch_add, - .resume = ebook_switch_resume, .remove = ebook_switch_remove, .notify = ebook_switch_notify, }, + .drv.pm = &ebook_switch_pm, }; static int __init xo15_ebook_init(void) -- GitLab From 81bc495401955bf7a62d04f8c794718476a2b093 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Jun 2012 23:39:48 +0200 Subject: [PATCH 3369/6849] classmate-laptop: Use struct dev_pm_ops for power management Make the classmate-laptop driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki Acked-by: Thadeu Lima de Souza Cascardo --- drivers/platform/x86/classmate-laptop.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 94f93b621d7b..e2230a2b2f8e 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -362,15 +362,18 @@ static int cmpc_tablet_remove(struct acpi_device *acpi, int type) return cmpc_remove_acpi_notify_device(acpi); } -static int cmpc_tablet_resume(struct acpi_device *acpi) +static int cmpc_tablet_resume(struct device *dev) { - struct input_dev *inputdev = dev_get_drvdata(&acpi->dev); + struct input_dev *inputdev = dev_get_drvdata(dev); + unsigned long long val = 0; - if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) + if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) input_report_switch(inputdev, SW_TABLET_MODE, !val); return 0; } +static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); + static const struct acpi_device_id cmpc_tablet_device_ids[] = { {CMPC_TABLET_HID, 0}, {"", 0} @@ -384,9 +387,9 @@ static struct acpi_driver cmpc_tablet_acpi_driver = { .ops = { .add = cmpc_tablet_add, .remove = cmpc_tablet_remove, - .resume = cmpc_tablet_resume, .notify = cmpc_tablet_handler, - } + }, + .drv.pm = &cmpc_tablet_pm, }; -- GitLab From d26c844bc1c5e9745deffccae8d205e9b77a0fb1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Jun 2012 23:39:57 +0200 Subject: [PATCH 3370/6849] fujitsu-tablet: Use struct dev_pm_ops for power management Make the fujitsu-tablet driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/fujitsu-tablet.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index da267eae8ba8..d2e41735a47b 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c @@ -440,12 +440,14 @@ static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) return 0; } -static int acpi_fujitsu_resume(struct acpi_device *adev) +static int acpi_fujitsu_resume(struct device *dev) { fujitsu_reset(); return 0; } +static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); + static struct acpi_driver acpi_fujitsu_driver = { .name = MODULENAME, .class = "hotkey", @@ -453,8 +455,8 @@ static struct acpi_driver acpi_fujitsu_driver = { .ops = { .add = acpi_fujitsu_add, .remove = acpi_fujitsu_remove, - .resume = acpi_fujitsu_resume, - } + }, + .drv.pm = &acpi_fujitsu_pm, }; static int __init fujitsu_module_init(void) -- GitLab From c5dec0182256361a3f823316e8fb85263f76efe7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Jun 2012 23:40:05 +0200 Subject: [PATCH 3371/6849] acpi_power_meter: Use struct dev_pm_ops for power management Make the ACPI power meter driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki --- drivers/hwmon/acpi_power_meter.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 34ad5a27a7e9..e3fcf8146834 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -929,20 +929,25 @@ static int acpi_power_meter_remove(struct acpi_device *device, int type) return 0; } -static int acpi_power_meter_resume(struct acpi_device *device) +static int acpi_power_meter_resume(struct device *dev) { struct acpi_power_meter_resource *resource; - if (!device || !acpi_driver_data(device)) + if (!dev) + return -EINVAL; + + resource = acpi_driver_data(to_acpi_device(dev)); + if (!resource) return -EINVAL; - resource = acpi_driver_data(device); free_capabilities(resource); read_capabilities(resource); return 0; } +static SIMPLE_DEV_PM_OPS(acpi_power_meter_pm, NULL, acpi_power_meter_resume); + static struct acpi_driver acpi_power_meter_driver = { .name = "power_meter", .class = ACPI_POWER_METER_CLASS, @@ -950,9 +955,9 @@ static struct acpi_driver acpi_power_meter_driver = { .ops = { .add = acpi_power_meter_add, .remove = acpi_power_meter_remove, - .resume = acpi_power_meter_resume, .notify = acpi_power_meter_notify, }, + .drv.pm = &acpi_power_meter_pm, }; /* Module init/exit routines */ -- GitLab From 13db85528fd606b2dfd8f1a5952158e4ad6ce51a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Jun 2012 23:40:13 +0200 Subject: [PATCH 3372/6849] ACPI / PM: Do not execute legacy driver PM callbacks Since all ACPI drivers in the tree should have been switched to power management handling based on struct dev_pm_ops, modify the ACPI bus type driver so that is doesn't execute legacy driver power management callbacks from the functions pointed to by the members of the acpi_bus_pm structure. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index af924ba85148..c384e59c3d9a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -290,51 +290,45 @@ static void acpi_device_release(struct device *dev) kfree(acpi_dev); } -#define ACPI_DEV_PM_CALLBACK(dev, callback, legacy_cb) \ +#define ACPI_DEV_PM_CALLBACK(dev, callback) \ ({ \ - struct acpi_device *__acpi_dev = to_acpi_device(dev); \ - struct acpi_driver *__acpi_drv = __acpi_dev->driver; \ struct device_driver *__drv = dev->driver; \ - int __ret; \ + int __ret = 0; \ \ - if (__acpi_drv && __acpi_drv->ops.legacy_cb) \ - __ret = __acpi_drv->ops.legacy_cb(__acpi_dev); \ - else if (__drv && __drv->pm && __drv->pm->callback) \ + if (__drv && __drv->pm && __drv->pm->callback) \ __ret = __drv->pm->callback(dev); \ - else \ - __ret = 0; \ \ __ret; \ }) static int acpi_pm_suspend(struct device *dev) { - return ACPI_DEV_PM_CALLBACK(dev, suspend, suspend); + return ACPI_DEV_PM_CALLBACK(dev, suspend); } static int acpi_pm_resume(struct device *dev) { - return ACPI_DEV_PM_CALLBACK(dev, resume, resume); + return ACPI_DEV_PM_CALLBACK(dev, resume); } static int acpi_pm_freeze(struct device *dev) { - return ACPI_DEV_PM_CALLBACK(dev, freeze, suspend); + return ACPI_DEV_PM_CALLBACK(dev, freeze); } static int acpi_pm_thaw(struct device *dev) { - return ACPI_DEV_PM_CALLBACK(dev, thaw, resume); + return ACPI_DEV_PM_CALLBACK(dev, thaw); } static int acpi_pm_poweroff(struct device *dev) { - return ACPI_DEV_PM_CALLBACK(dev, poweroff, suspend); + return ACPI_DEV_PM_CALLBACK(dev, poweroff); } static int acpi_pm_restore(struct device *dev) { - return ACPI_DEV_PM_CALLBACK(dev, restore, resume); + return ACPI_DEV_PM_CALLBACK(dev, restore); } static const struct dev_pm_ops acpi_bus_pm = { -- GitLab From a5cd33e1d4f3319e86f9f0fc667fa74ef9d9216c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Jun 2012 23:40:22 +0200 Subject: [PATCH 3373/6849] ACPI / PM: Drop legacy driver PM callbacks that are not used any more Since the legacy ACPI driver PM callbacks included into struct acpi_device_ops are not used any more, drop them. Signed-off-by: Rafael J. Wysocki --- include/acpi/acpi_bus.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c2bbec76ba10..18fd41033e03 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -117,8 +117,6 @@ struct acpi_device; typedef int (*acpi_op_add) (struct acpi_device * device); typedef int (*acpi_op_remove) (struct acpi_device * device, int type); typedef int (*acpi_op_start) (struct acpi_device * device); -typedef int (*acpi_op_suspend) (struct acpi_device * device); -typedef int (*acpi_op_resume) (struct acpi_device * device); typedef int (*acpi_op_bind) (struct acpi_device * device); typedef int (*acpi_op_unbind) (struct acpi_device * device); typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); @@ -132,8 +130,6 @@ struct acpi_device_ops { acpi_op_add add; acpi_op_remove remove; acpi_op_start start; - acpi_op_suspend suspend; - acpi_op_resume resume; acpi_op_bind bind; acpi_op_unbind unbind; acpi_op_notify notify; -- GitLab From d91ee328c1e8b3992ffbf84a1a984c2a7f4ebff7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Jun 2012 23:40:29 +0200 Subject: [PATCH 3374/6849] ACPI / PM: Drop PM callbacks from the ACPI bus type Since the ACPI bus type's PM callbacks only execute the driver ones without doing anything else, they can be dropped, because the driver callbacks will be executed by the PM core directly if bus type (or other subsystem) callbacks are not present. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 51 --------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c384e59c3d9a..fdda49336560 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -290,56 +290,6 @@ static void acpi_device_release(struct device *dev) kfree(acpi_dev); } -#define ACPI_DEV_PM_CALLBACK(dev, callback) \ -({ \ - struct device_driver *__drv = dev->driver; \ - int __ret = 0; \ - \ - if (__drv && __drv->pm && __drv->pm->callback) \ - __ret = __drv->pm->callback(dev); \ - \ - __ret; \ -}) - -static int acpi_pm_suspend(struct device *dev) -{ - return ACPI_DEV_PM_CALLBACK(dev, suspend); -} - -static int acpi_pm_resume(struct device *dev) -{ - return ACPI_DEV_PM_CALLBACK(dev, resume); -} - -static int acpi_pm_freeze(struct device *dev) -{ - return ACPI_DEV_PM_CALLBACK(dev, freeze); -} - -static int acpi_pm_thaw(struct device *dev) -{ - return ACPI_DEV_PM_CALLBACK(dev, thaw); -} - -static int acpi_pm_poweroff(struct device *dev) -{ - return ACPI_DEV_PM_CALLBACK(dev, poweroff); -} - -static int acpi_pm_restore(struct device *dev) -{ - return ACPI_DEV_PM_CALLBACK(dev, restore); -} - -static const struct dev_pm_ops acpi_bus_pm = { - .suspend = acpi_pm_suspend, - .resume = acpi_pm_resume, - .freeze = acpi_pm_freeze, - .thaw = acpi_pm_thaw, - .poweroff = acpi_pm_poweroff, - .restore = acpi_pm_restore, -}; - static int acpi_bus_match(struct device *dev, struct device_driver *drv) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -475,7 +425,6 @@ struct bus_type acpi_bus_type = { .probe = acpi_device_probe, .remove = acpi_device_remove, .uevent = acpi_device_uevent, - .pm = &acpi_bus_pm, }; static int acpi_device_register(struct acpi_device *device) -- GitLab From fd3c3a424e43e4f85385de0c2609c490605611a6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:18:44 +0200 Subject: [PATCH 3375/6849] thinkpad_acpi: Drop pm_message_t arguments from suspend routines Multiple suspend routines in drivers/platform/x86/thinkpad_acpi.c use take pm_message_t arguments that aren't used by any of them. Make those routines take no arguments as that's what they should do. Signed-off-by: Rafael J. Wysocki Acked-by: Henrique de Moraes Holschuh Acked-by: Matthew Garrett --- drivers/platform/x86/thinkpad_acpi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 8b5610d88418..070e555d4bd8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -277,7 +277,7 @@ struct ibm_struct { int (*write) (char *); void (*exit) (void); void (*resume) (void); - void (*suspend) (pm_message_t state); + void (*suspend) (void); void (*shutdown) (void); struct list_head all_drivers; @@ -931,7 +931,7 @@ static int tpacpi_suspend_handler(struct platform_device *pdev, &tpacpi_all_drivers, all_drivers) { if (ibm->suspend) - (ibm->suspend)(state); + (ibm->suspend)(); } return 0; @@ -3758,7 +3758,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } } -static void hotkey_suspend(pm_message_t state) +static void hotkey_suspend(void) { /* Do these on suspend, we get the events on early resume! */ hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; @@ -6329,7 +6329,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) return 0; } -static void brightness_suspend(pm_message_t state) +static void brightness_suspend(void) { tpacpi_brightness_checkpoint_nvram(); } @@ -6748,7 +6748,7 @@ static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = { .get = volume_alsa_mute_get, }; -static void volume_suspend(pm_message_t state) +static void volume_suspend(void) { tpacpi_volume_checkpoint_nvram(); } @@ -8107,7 +8107,7 @@ static void fan_exit(void) flush_workqueue(tpacpi_wq); } -static void fan_suspend(pm_message_t state) +static void fan_suspend(void) { int rc; -- GitLab From 4959a781bc1bbd0d06092caa94e33fd41033a38d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:19:01 +0200 Subject: [PATCH 3376/6849] thinkpad_acpi: Use struct dev_pm_ops instead of legacy PM routines Make the thinkpad_acpi driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki Acked-by: Henrique de Moraes Holschuh Acked-by: Matthew Garrett --- drivers/platform/x86/thinkpad_acpi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 070e555d4bd8..d5fd4a1193f8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -922,8 +922,7 @@ static struct input_dev *tpacpi_inputdev; static struct mutex tpacpi_inputdev_send_mutex; static LIST_HEAD(tpacpi_all_drivers); -static int tpacpi_suspend_handler(struct platform_device *pdev, - pm_message_t state) +static int tpacpi_suspend_handler(struct device *dev) { struct ibm_struct *ibm, *itmp; @@ -937,7 +936,7 @@ static int tpacpi_suspend_handler(struct platform_device *pdev, return 0; } -static int tpacpi_resume_handler(struct platform_device *pdev) +static int tpacpi_resume_handler(struct device *dev) { struct ibm_struct *ibm, *itmp; @@ -951,6 +950,9 @@ static int tpacpi_resume_handler(struct platform_device *pdev) return 0; } +static SIMPLE_DEV_PM_OPS(tpacpi_pm, + tpacpi_suspend_handler, tpacpi_resume_handler); + static void tpacpi_shutdown_handler(struct platform_device *pdev) { struct ibm_struct *ibm, *itmp; @@ -967,9 +969,8 @@ static struct platform_driver tpacpi_pdriver = { .driver = { .name = TPACPI_DRVR_NAME, .owner = THIS_MODULE, + .pm = &tpacpi_pm, }, - .suspend = tpacpi_suspend_handler, - .resume = tpacpi_resume_handler, .shutdown = tpacpi_shutdown_handler, }; -- GitLab From 818e14860615634646e1fe176d49e4357a4e1534 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:19:22 +0200 Subject: [PATCH 3377/6849] intel_ips: Remove empty legacy PM callbacks The legacy PM callbacks provided by the Intel IPS driver are empty routines returning 0, so they can be safely dropped. Signed-off-by: Rafael J. Wysocki Acked-by: Jesse Barnes --- drivers/platform/x86/intel_ips.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 0ffdb3cde2bb..bd89f3c8e76e 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1697,21 +1697,6 @@ static void ips_remove(struct pci_dev *dev) dev_dbg(&dev->dev, "IPS driver removed\n"); } -#ifdef CONFIG_PM -static int ips_suspend(struct pci_dev *dev, pm_message_t state) -{ - return 0; -} - -static int ips_resume(struct pci_dev *dev) -{ - return 0; -} -#else -#define ips_suspend NULL -#define ips_resume NULL -#endif /* CONFIG_PM */ - static void ips_shutdown(struct pci_dev *dev) { } @@ -1721,8 +1706,6 @@ static struct pci_driver ips_pci_driver = { .id_table = ips_id_table, .probe = ips_probe, .remove = ips_remove, - .suspend = ips_suspend, - .resume = ips_resume, .shutdown = ips_shutdown, }; -- GitLab From 3c33be0b0dae390557f41a604ac621d0f3eabf9b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:19:35 +0200 Subject: [PATCH 3378/6849] acer-wmi: Use struct dev_pm_ops for power management Make the acer-wmi driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki Tested-by: Lee, Chun-Yi Acked-by: Matthew Garrett --- drivers/platform/x86/acer-wmi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index ce875dc365e5..c8f40c9c0428 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -1877,8 +1877,7 @@ static int acer_platform_remove(struct platform_device *device) return 0; } -static int acer_platform_suspend(struct platform_device *dev, -pm_message_t state) +static int acer_suspend(struct device *dev) { u32 value; struct acer_data *data = &interface->data; @@ -1900,7 +1899,7 @@ pm_message_t state) return 0; } -static int acer_platform_resume(struct platform_device *device) +static int acer_resume(struct device *dev) { struct acer_data *data = &interface->data; @@ -1916,6 +1915,8 @@ static int acer_platform_resume(struct platform_device *device) return 0; } +static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); + static void acer_platform_shutdown(struct platform_device *device) { struct acer_data *data = &interface->data; @@ -1931,11 +1932,10 @@ static struct platform_driver acer_platform_driver = { .driver = { .name = "acer-wmi", .owner = THIS_MODULE, + .pm = &acer_pm, }, .probe = acer_platform_probe, .remove = acer_platform_remove, - .suspend = acer_platform_suspend, - .resume = acer_platform_resume, .shutdown = acer_platform_shutdown, }; -- GitLab From 8ff847fc21e53be0e2ebd476ce6269a201575152 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:19:45 +0200 Subject: [PATCH 3379/6849] intel_mid_thermal: Use struct dev_pm_ops for power management Make the intel_mid_thermal driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki Reviewed-by: Durgadoss R --- drivers/platform/x86/intel_mid_thermal.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index 5ae9cd9c7e6e..ea7422f6fa03 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -418,23 +418,23 @@ static struct thermal_device_info *initialize_sensor(int index) /** * mid_thermal_resume - resume routine - * @pdev: platform device structure + * @dev: device structure * * mid thermal resume: re-initializes the adc. Can sleep. */ -static int mid_thermal_resume(struct platform_device *pdev) +static int mid_thermal_resume(struct device *dev) { - return mid_initialize_adc(&pdev->dev); + return mid_initialize_adc(dev); } /** * mid_thermal_suspend - suspend routine - * @pdev: platform device structure + * @dev: device structure * * mid thermal suspend implements the suspend functionality * by stopping the ADC. Can sleep. */ -static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) +static int mid_thermal_suspend(struct device *dev) { /* * This just stops the ADC and does not disable it. @@ -444,6 +444,9 @@ static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) return configure_adc(0); } +static SIMPLE_DEV_PM_OPS(mid_thermal_pm, + mid_thermal_suspend, mid_thermal_resume); + /** * read_curr_temp - reads the current temperature and stores in temp * @temp: holds the current temperature value after reading @@ -557,10 +560,9 @@ static struct platform_driver mid_thermal_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .pm = &mid_thermal_pm, }, .probe = mid_thermal_probe, - .suspend = mid_thermal_suspend, - .resume = mid_thermal_resume, .remove = __devexit_p(mid_thermal_remove), .id_table = therm_id_table, }; -- GitLab From 199ac0529eac0341b232b450e43fad71d1513e94 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Jun 2012 23:20:29 +0200 Subject: [PATCH 3380/6849] sonypi: Use struct dev_pm_ops for power management Make the sonypi driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct acpi_device_ops. Signed-off-by: Rafael J. Wysocki Acked-by: Mattia Dongili --- drivers/char/sonypi.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 45713f0e7d61..f87780502b41 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1459,7 +1459,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) #ifdef CONFIG_PM static int old_camera_power; -static int sonypi_suspend(struct platform_device *dev, pm_message_t state) +static int sonypi_suspend(struct device *dev) { old_camera_power = sonypi_device.camera_power; sonypi_disable(); @@ -1467,14 +1467,16 @@ static int sonypi_suspend(struct platform_device *dev, pm_message_t state) return 0; } -static int sonypi_resume(struct platform_device *dev) +static int sonypi_resume(struct device *dev) { sonypi_enable(old_camera_power); return 0; } + +static SIMPLE_DEV_PM_OPS(sonypi_pm, sonypi_suspend, sonypi_resume); +#define SONYPI_PM (&sonypi_pm) #else -#define sonypi_suspend NULL -#define sonypi_resume NULL +#define SONYPI_PM NULL #endif static void sonypi_shutdown(struct platform_device *dev) @@ -1486,12 +1488,11 @@ static struct platform_driver sonypi_driver = { .driver = { .name = "sonypi", .owner = THIS_MODULE, + .pm = SONYPI_PM, }, .probe = sonypi_probe, .remove = __devexit_p(sonypi_remove), .shutdown = sonypi_shutdown, - .suspend = sonypi_suspend, - .resume = sonypi_resume, }; static struct platform_device *sonypi_platform_device; -- GitLab From 62c552ccc3eda1198632a4f344aa32623d226bab Mon Sep 17 00:00:00 2001 From: Bojan Smojver Date: Sat, 16 Jun 2012 00:09:58 +0200 Subject: [PATCH 3381/6849] PM / Hibernate: Enable suspend to both for in-kernel hibernation. It is often useful to suspend to memory after hibernation image has been written to disk. If the battery runs out or power is otherwise lost, the computer will resume from the hibernated image. If not, it will resume from memory and hibernation image will be discarded. Signed-off-by: Bojan Smojver Signed-off-by: Rafael J. Wysocki --- Documentation/power/swsusp.txt | 5 +++++ kernel/power/hibernate.c | 36 ++++++++++++++++++++++++++++++++++ kernel/power/power.h | 3 +++ kernel/power/swap.c | 28 ++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt index ac190cf1963e..92341b84250d 100644 --- a/Documentation/power/swsusp.txt +++ b/Documentation/power/swsusp.txt @@ -33,6 +33,11 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state echo platform > /sys/power/disk; echo disk > /sys/power/state +. If you would like to write hibernation image to swap and then suspend +to RAM (provided your platform supports it), you can try + +echo suspend > /sys/power/disk; echo disk > /sys/power/state + . If you have SATA disks, you'll need recent kernels with SATA suspend support. For suspend and resume to work, make sure your disk drivers are built into kernel -- not modules. [There's way to make diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 8b53db38a279..21ad3fe3164f 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -5,6 +5,7 @@ * Copyright (c) 2003 Open Source Development Lab * Copyright (c) 2004 Pavel Machek * Copyright (c) 2009 Rafael J. Wysocki, Novell Inc. + * Copyright (C) 2012 Bojan Smojver * * This file is released under the GPLv2. */ @@ -46,6 +47,9 @@ enum { HIBERNATION_PLATFORM, HIBERNATION_SHUTDOWN, HIBERNATION_REBOOT, +#ifdef CONFIG_SUSPEND + HIBERNATION_SUSPEND, +#endif /* keep last */ __HIBERNATION_AFTER_LAST }; @@ -574,6 +578,10 @@ int hibernation_platform_enter(void) */ static void power_down(void) { +#ifdef CONFIG_SUSPEND + int error; +#endif + switch (hibernation_mode) { case HIBERNATION_REBOOT: kernel_restart(NULL); @@ -583,6 +591,25 @@ static void power_down(void) case HIBERNATION_SHUTDOWN: kernel_power_off(); break; +#ifdef CONFIG_SUSPEND + case HIBERNATION_SUSPEND: + error = suspend_devices_and_enter(PM_SUSPEND_MEM); + if (error) { + if (hibernation_ops) + hibernation_mode = HIBERNATION_PLATFORM; + else + hibernation_mode = HIBERNATION_SHUTDOWN; + power_down(); + } + /* + * Restore swap signature. + */ + error = swsusp_unmark(); + if (error) + printk(KERN_ERR "PM: Swap will be unusable! " + "Try swapon -a.\n"); + return; +#endif } kernel_halt(); /* @@ -827,6 +854,9 @@ static const char * const hibernation_modes[] = { [HIBERNATION_PLATFORM] = "platform", [HIBERNATION_SHUTDOWN] = "shutdown", [HIBERNATION_REBOOT] = "reboot", +#ifdef CONFIG_SUSPEND + [HIBERNATION_SUSPEND] = "suspend", +#endif }; /* @@ -867,6 +897,9 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, switch (i) { case HIBERNATION_SHUTDOWN: case HIBERNATION_REBOOT: +#ifdef CONFIG_SUSPEND + case HIBERNATION_SUSPEND: +#endif break; case HIBERNATION_PLATFORM: if (hibernation_ops) @@ -907,6 +940,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, switch (mode) { case HIBERNATION_SHUTDOWN: case HIBERNATION_REBOOT: +#ifdef CONFIG_SUSPEND + case HIBERNATION_SUSPEND: +#endif hibernation_mode = mode; break; case HIBERNATION_PLATFORM: diff --git a/kernel/power/power.h b/kernel/power/power.h index b0bd4beaebfe..7d4b7ffb3c1d 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -156,6 +156,9 @@ extern void swsusp_free(void); extern int swsusp_read(unsigned int *flags_p); extern int swsusp_write(unsigned int flags); extern void swsusp_close(fmode_t); +#ifdef CONFIG_SUSPEND +extern int swsusp_unmark(void); +#endif /* kernel/power/block_io.c */ extern struct block_device *hib_resume_bdev; diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 11e22c068e8b..83d505142b00 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -1472,6 +1472,34 @@ void swsusp_close(fmode_t mode) blkdev_put(hib_resume_bdev, mode); } +/** + * swsusp_unmark - Unmark swsusp signature in the resume device + */ + +#ifdef CONFIG_SUSPEND +int swsusp_unmark(void) +{ + int error; + + hib_bio_read_page(swsusp_resume_block, swsusp_header, NULL); + if (!memcmp(HIBERNATE_SIG,swsusp_header->sig, 10)) { + memcpy(swsusp_header->sig,swsusp_header->orig_sig, 10); + error = hib_bio_write_page(swsusp_resume_block, + swsusp_header, NULL); + } else { + printk(KERN_ERR "PM: Cannot find swsusp signature!\n"); + error = -ENODEV; + } + + /* + * We just returned from suspend, we don't need the image any more. + */ + free_all_swap_pages(root_swap); + + return error; +} +#endif + static int swsusp_header_init(void) { swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL); -- GitLab From 443772d408a25af62498793f6f805ce3c559309a Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Sat, 16 Jun 2012 15:30:45 +0200 Subject: [PATCH 3382/6849] ftrace: Disable function tracing during suspend/resume and hibernation, again If function tracing is enabled for some of the low-level suspend/resume functions, it leads to triple fault during resume from suspend, ultimately ending up in a reboot instead of a resume (or a total refusal to come out of suspended state, on some machines). This issue was explained in more detail in commit f42ac38c59e0a03d (ftrace: disable tracing for suspend to ram). However, the changes made by that commit got reverted by commit cbe2f5a6e84eebb (tracing: allow tracing of suspend/resume & hibernation code again). So, unfortunately since things are not yet robust enough to allow tracing of low-level suspend/resume functions, suspend/resume is still broken when ftrace is enabled. So fix this by disabling function tracing during suspend/resume & hibernation. Signed-off-by: Srivatsa S. Bhat Cc: stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki --- kernel/power/hibernate.c | 6 ++++++ kernel/power/suspend.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 21ad3fe3164f..0d4b354bc1be 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -358,6 +358,7 @@ int hibernation_snapshot(int platform_mode) } suspend_console(); + ftrace_stop(); pm_restrict_gfp_mask(); error = dpm_suspend(PMSG_FREEZE); @@ -383,6 +384,7 @@ int hibernation_snapshot(int platform_mode) if (error || !in_suspend) pm_restore_gfp_mask(); + ftrace_start(); resume_console(); dpm_complete(msg); @@ -485,6 +487,7 @@ int hibernation_restore(int platform_mode) pm_prepare_console(); suspend_console(); + ftrace_stop(); pm_restrict_gfp_mask(); error = dpm_suspend_start(PMSG_QUIESCE); if (!error) { @@ -492,6 +495,7 @@ int hibernation_restore(int platform_mode) dpm_resume_end(PMSG_RECOVER); } pm_restore_gfp_mask(); + ftrace_start(); resume_console(); pm_restore_console(); return error; @@ -518,6 +522,7 @@ int hibernation_platform_enter(void) entering_platform_hibernation = true; suspend_console(); + ftrace_stop(); error = dpm_suspend_start(PMSG_HIBERNATE); if (error) { if (hibernation_ops->recover) @@ -561,6 +566,7 @@ int hibernation_platform_enter(void) Resume_devices: entering_platform_hibernation = false; dpm_resume_end(PMSG_RESTORE); + ftrace_start(); resume_console(); Close: diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 396d262b8fd0..c8b7446b27df 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "power.h" @@ -212,6 +213,7 @@ int suspend_devices_and_enter(suspend_state_t state) goto Close; } suspend_console(); + ftrace_stop(); suspend_test_start(); error = dpm_suspend_start(PMSG_SUSPEND); if (error) { @@ -231,6 +233,7 @@ int suspend_devices_and_enter(suspend_state_t state) suspend_test_start(); dpm_resume_end(PMSG_RESUME); suspend_test_finish("resume devices"); + ftrace_start(); resume_console(); Close: if (suspend_ops->end) -- GitLab From 4b7760ba0dd3319f66886ab2335a0fbecdbc808a Mon Sep 17 00:00:00 2001 From: Sameer Nanda Date: Tue, 19 Jun 2012 22:23:33 +0200 Subject: [PATCH 3383/6849] PM / Sleep: add knob for printing device resume times Added a new knob called /sys/power/pm_print_times. Setting it to 1 enables printing of time taken by devices to suspend and resume. Setting it to 0 disables this printing (unless overridden by initcall_debug kernel command line option). Signed-off-by: Sameer Nanda Acked-by: Greg KH Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-power | 13 +++++++++++ drivers/base/power/main.c | 4 ++-- drivers/base/power/power.h | 11 +++++++++ kernel/power/main.c | 33 +++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power index 31725ffeeb3a..217772615d02 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power @@ -231,3 +231,16 @@ Description: Reads from this file return a string consisting of the names of wakeup sources created with the help of /sys/power/wake_lock that are inactive at the moment, separated with spaces. + +What: /sys/power/pm_print_times +Date: May 2012 +Contact: Sameer Nanda +Description: + The /sys/power/pm_print_times file allows user space to + control whether the time taken by devices to suspend and + resume is printed. These prints are useful for hunting down + devices that take too long to suspend or resume. + + Writing a "1" enables this printing while writing a "0" + disables it. The default value is "0". Reading from this file + will display the current value. diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 9cb845e49334..6e4db96958d1 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -166,7 +166,7 @@ static ktime_t initcall_debug_start(struct device *dev) { ktime_t calltime = ktime_set(0, 0); - if (initcall_debug) { + if (pm_print_times) { pr_info("calling %s+ @ %i, parent: %s\n", dev_name(dev), task_pid_nr(current), dev->parent ? dev_name(dev->parent) : "none"); @@ -181,7 +181,7 @@ static void initcall_debug_report(struct device *dev, ktime_t calltime, { ktime_t delta, rettime; - if (initcall_debug) { + if (pm_print_times) { rettime = ktime_get(); delta = ktime_sub(rettime, calltime); pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index eeb4bff9505c..12c77b7ff8e8 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -85,3 +85,14 @@ static inline int pm_qos_sysfs_add(struct device *dev) { return 0; } static inline void pm_qos_sysfs_remove(struct device *dev) {} #endif + +#ifdef CONFIG_PM_DEBUG + +extern int pm_print_times_enabled; +#define pm_print_times (initcall_debug || pm_print_times_enabled) + +#else /* CONFIG_PM_DEBUG */ + +#define pm_print_times initcall_debug + +#endif /* CONFIG_PM_DEBUG */ diff --git a/kernel/power/main.c b/kernel/power/main.c index 428f8a034e96..7beb3fb3670b 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -132,6 +132,38 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, } power_attr(pm_test); + +/* + * pm_print_times: print time taken by devices to suspend and resume. + * + * show() returns whether printing of suspend and resume times is enabled. + * store() accepts 0 or 1. 0 disables printing and 1 enables it. + */ +int pm_print_times_enabled; + +static ssize_t pm_print_times_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", pm_print_times_enabled); +} + +static ssize_t pm_print_times_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + unsigned long val; + + if (kstrtoul(buf, 10, &val)) + return -EINVAL; + + if (val > 1) + return -EINVAL; + + pm_print_times_enabled = val; + return n; +} + +power_attr(pm_print_times); #endif /* CONFIG_PM_DEBUG */ #ifdef CONFIG_DEBUG_FS @@ -530,6 +562,7 @@ static struct attribute * g[] = { #endif #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, + &pm_print_times_attr.attr, #endif #endif NULL, -- GitLab From b2df1d4f8b95d9d1e3f064cef02fc5c5116b05cf Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Jun 2012 00:19:33 +0200 Subject: [PATCH 3384/6849] PM / Sleep: Separate printing suspend times from initcall_debug Change the behavior of the newly introduced /sys/power/pm_print_times attribute so that its initial value depends on initcall_debug, but setting it to 0 will cause device suspend/resume times not to be printed, even if initcall_debug has been set. This way, the people who use initcall_debug for reasons other than PM debugging will be able to switch the suspend/resume times printing off, if need be. Signed-off-by: Rafael J. Wysocki Reviewed-by: Srivatsa S. Bhat Acked-by: Greg Kroah-Hartman --- drivers/base/power/main.c | 4 +- drivers/base/power/power.h | 11 ------ include/linux/suspend.h | 6 +++ kernel/power/Kconfig | 4 +- kernel/power/main.c | 76 ++++++++++++++++++++++---------------- 5 files changed, 54 insertions(+), 47 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 6e4db96958d1..df5f41d2ec95 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -166,7 +166,7 @@ static ktime_t initcall_debug_start(struct device *dev) { ktime_t calltime = ktime_set(0, 0); - if (pm_print_times) { + if (pm_print_times_enabled) { pr_info("calling %s+ @ %i, parent: %s\n", dev_name(dev), task_pid_nr(current), dev->parent ? dev_name(dev->parent) : "none"); @@ -181,7 +181,7 @@ static void initcall_debug_report(struct device *dev, ktime_t calltime, { ktime_t delta, rettime; - if (pm_print_times) { + if (pm_print_times_enabled) { rettime = ktime_get(); delta = ktime_sub(rettime, calltime); pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 12c77b7ff8e8..eeb4bff9505c 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -85,14 +85,3 @@ static inline int pm_qos_sysfs_add(struct device *dev) { return 0; } static inline void pm_qos_sysfs_remove(struct device *dev) {} #endif - -#ifdef CONFIG_PM_DEBUG - -extern int pm_print_times_enabled; -#define pm_print_times (initcall_debug || pm_print_times_enabled) - -#else /* CONFIG_PM_DEBUG */ - -#define pm_print_times initcall_debug - -#endif /* CONFIG_PM_DEBUG */ diff --git a/include/linux/suspend.h b/include/linux/suspend.h index cd83059fb592..0c808d7fa579 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -408,6 +408,12 @@ static inline void unlock_system_sleep(void) {} #endif /* !CONFIG_PM_SLEEP */ +#ifdef CONFIG_PM_SLEEP_DEBUG +extern bool pm_print_times_enabled; +#else +#define pm_print_times_enabled (false) +#endif + #ifdef CONFIG_PM_AUTOSLEEP /* kernel/power/autosleep.c */ diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 8f9b4eb974e0..a70518c9d82f 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -175,7 +175,7 @@ config PM_TEST_SUSPEND You probably want to have your system's RTC driver statically linked, ensuring that it's available when this test runs. -config CAN_PM_TRACE +config PM_SLEEP_DEBUG def_bool y depends on PM_DEBUG && PM_SLEEP @@ -196,7 +196,7 @@ config PM_TRACE config PM_TRACE_RTC bool "Suspend/resume event tracing" - depends on CAN_PM_TRACE + depends on PM_SLEEP_DEBUG depends on X86 select PM_TRACE ---help--- diff --git a/kernel/power/main.c b/kernel/power/main.c index 7beb3fb3670b..f458238109cc 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -132,38 +132,6 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, } power_attr(pm_test); - -/* - * pm_print_times: print time taken by devices to suspend and resume. - * - * show() returns whether printing of suspend and resume times is enabled. - * store() accepts 0 or 1. 0 disables printing and 1 enables it. - */ -int pm_print_times_enabled; - -static ssize_t pm_print_times_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", pm_print_times_enabled); -} - -static ssize_t pm_print_times_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t n) -{ - unsigned long val; - - if (kstrtoul(buf, 10, &val)) - return -EINVAL; - - if (val > 1) - return -EINVAL; - - pm_print_times_enabled = val; - return n; -} - -power_attr(pm_print_times); #endif /* CONFIG_PM_DEBUG */ #ifdef CONFIG_DEBUG_FS @@ -267,6 +235,47 @@ late_initcall(pm_debugfs_init); #endif /* CONFIG_PM_SLEEP */ +#ifdef CONFIG_PM_SLEEP_DEBUG +/* + * pm_print_times: print time taken by devices to suspend and resume. + * + * show() returns whether printing of suspend and resume times is enabled. + * store() accepts 0 or 1. 0 disables printing and 1 enables it. + */ +bool pm_print_times_enabled; + +static ssize_t pm_print_times_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", pm_print_times_enabled); +} + +static ssize_t pm_print_times_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + unsigned long val; + + if (kstrtoul(buf, 10, &val)) + return -EINVAL; + + if (val > 1) + return -EINVAL; + + pm_print_times_enabled = !!val; + return n; +} + +power_attr(pm_print_times); + +static inline void pm_print_times_init(void) +{ + pm_print_times_enabled = !!initcall_debug; +} +#else /* !CONFIG_PP_SLEEP_DEBUG */ +static inline void pm_print_times_init(void) {} +#endif /* CONFIG_PM_SLEEP_DEBUG */ + struct kobject *power_kobj; /** @@ -562,6 +571,8 @@ static struct attribute * g[] = { #endif #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, +#endif +#ifdef CONFIG_PM_SLEEP_DEBUG &pm_print_times_attr.attr, #endif #endif @@ -599,6 +610,7 @@ static int __init pm_init(void) error = sysfs_create_group(power_kobj, &attr_group); if (error) return error; + pm_print_times_init(); return pm_autosleep_init(); } -- GitLab From d8150d350408de6fb2b9ee7b7625ae8e2bb7aa4a Mon Sep 17 00:00:00 2001 From: Bojan Smojver Date: Thu, 21 Jun 2012 22:27:24 +0200 Subject: [PATCH 3385/6849] PM / Hibernate: Print hibernation/thaw progress indicator one line at a time. With the introduction of suspend to both into in-kernel hibernation code, dmesg was getting polluted with backspace characters printed as part of image saving progress indicator. This patch introduces printing of progress indicator on image save/load every 10% and one line at a time. As an additional benefit, all other messages emitted by the kernel during hibernation/thaw should now print cleanly as well. Signed-off-by: Bojan Smojver Signed-off-by: Rafael J. Wysocki --- kernel/power/swap.c | 54 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 83d505142b00..3c9d764eb0d8 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -448,9 +448,9 @@ static int save_image(struct swap_map_handle *handle, struct timeval start; struct timeval stop; - printk(KERN_INFO "PM: Saving image data pages (%u pages) ... ", + printk(KERN_INFO "PM: Saving image data pages (%u pages)...\n", nr_to_write); - m = nr_to_write / 100; + m = nr_to_write / 10; if (!m) m = 1; nr_pages = 0; @@ -464,7 +464,8 @@ static int save_image(struct swap_map_handle *handle, if (ret) break; if (!(nr_pages % m)) - printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m); + printk(KERN_INFO "PM: Image saving progress: %3d%%\n", + nr_pages / m * 10); nr_pages++; } err2 = hib_wait_on_bio_chain(&bio); @@ -472,9 +473,7 @@ static int save_image(struct swap_map_handle *handle, if (!ret) ret = err2; if (!ret) - printk(KERN_CONT "\b\b\b\bdone\n"); - else - printk(KERN_CONT "\n"); + printk(KERN_INFO "PM: Image saving done.\n"); swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); return ret; } @@ -668,9 +667,9 @@ static int save_image_lzo(struct swap_map_handle *handle, printk(KERN_INFO "PM: Using %u thread(s) for compression.\n" - "PM: Compressing and saving image data (%u pages) ... ", + "PM: Compressing and saving image data (%u pages)...\n", nr_threads, nr_to_write); - m = nr_to_write / 100; + m = nr_to_write / 10; if (!m) m = 1; nr_pages = 0; @@ -690,8 +689,10 @@ static int save_image_lzo(struct swap_map_handle *handle, data_of(*snapshot), PAGE_SIZE); if (!(nr_pages % m)) - printk(KERN_CONT "\b\b\b\b%3d%%", - nr_pages / m); + printk(KERN_INFO + "PM: Image saving progress: " + "%3d%%\n", + nr_pages / m * 10); nr_pages++; } if (!off) @@ -761,11 +762,8 @@ out_finish: do_gettimeofday(&stop); if (!ret) ret = err2; - if (!ret) { - printk(KERN_CONT "\b\b\b\bdone\n"); - } else { - printk(KERN_CONT "\n"); - } + if (!ret) + printk(KERN_INFO "PM: Image saving done.\n"); swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); out_clean: if (crc) { @@ -973,9 +971,9 @@ static int load_image(struct swap_map_handle *handle, int err2; unsigned nr_pages; - printk(KERN_INFO "PM: Loading image data pages (%u pages) ... ", + printk(KERN_INFO "PM: Loading image data pages (%u pages)...\n", nr_to_read); - m = nr_to_read / 100; + m = nr_to_read / 10; if (!m) m = 1; nr_pages = 0; @@ -993,7 +991,8 @@ static int load_image(struct swap_map_handle *handle, if (ret) break; if (!(nr_pages % m)) - printk("\b\b\b\b%3d%%", nr_pages / m); + printk(KERN_INFO "PM: Image loading progress: %3d%%\n", + nr_pages / m * 10); nr_pages++; } err2 = hib_wait_on_bio_chain(&bio); @@ -1001,12 +1000,11 @@ static int load_image(struct swap_map_handle *handle, if (!ret) ret = err2; if (!ret) { - printk("\b\b\b\bdone\n"); + printk(KERN_INFO "PM: Image loading done.\n"); snapshot_write_finalize(snapshot); if (!snapshot_image_loaded(snapshot)) ret = -ENODATA; - } else - printk("\n"); + } swsusp_show_speed(&start, &stop, nr_to_read, "Read"); return ret; } @@ -1185,9 +1183,9 @@ static int load_image_lzo(struct swap_map_handle *handle, printk(KERN_INFO "PM: Using %u thread(s) for decompression.\n" - "PM: Loading and decompressing image data (%u pages) ... ", + "PM: Loading and decompressing image data (%u pages)...\n", nr_threads, nr_to_read); - m = nr_to_read / 100; + m = nr_to_read / 10; if (!m) m = 1; nr_pages = 0; @@ -1319,7 +1317,10 @@ static int load_image_lzo(struct swap_map_handle *handle, data[thr].unc + off, PAGE_SIZE); if (!(nr_pages % m)) - printk("\b\b\b\b%3d%%", nr_pages / m); + printk(KERN_INFO + "PM: Image loading progress: " + "%3d%%\n", + nr_pages / m * 10); nr_pages++; ret = snapshot_write_next(snapshot); @@ -1344,7 +1345,7 @@ out_finish: } do_gettimeofday(&stop); if (!ret) { - printk("\b\b\b\bdone\n"); + printk(KERN_INFO "PM: Image loading done.\n"); snapshot_write_finalize(snapshot); if (!snapshot_image_loaded(snapshot)) ret = -ENODATA; @@ -1357,8 +1358,7 @@ out_finish: } } } - } else - printk("\n"); + } swsusp_show_speed(&start, &stop, nr_to_read, "Read"); out_clean: for (i = 0; i < ring_size; i++) -- GitLab From 0b589741b8b83a33e25fb32bb714ea1b972af5aa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 16 Jun 2012 00:02:22 +0200 Subject: [PATCH 3386/6849] PM / Domains: Use subsystem runtime suspend/resume callbacks by default Currently, the default "save state" and "restore state" routines for generic PM domains, pm_genpd_default_save_state() and pm_genpd_default_restore_state(), respectively, only use runtime PM callbacks provided by device drivers, but in general those callbacks need not provide the entire necessary functionality. Namely, in general it may be necessary to execute subsystem (i.e. device type, device class or bus type) callbacks that will carry out all of the necessary operations. For this reason, modify pm_genpd_default_save_state() and pm_genpd_default_restore_state() to execute subsystem callbacks, if they are provided, and fall back to driver callbacks otherwise. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 83aa694a8efe..49fdd4002b9f 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1615,16 +1615,24 @@ EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); static int pm_genpd_default_save_state(struct device *dev) { int (*cb)(struct device *__dev); - struct device_driver *drv = dev->driver; cb = dev_gpd_data(dev)->ops.save_state; if (cb) return cb(dev); - if (drv && drv->pm && drv->pm->runtime_suspend) - return drv->pm->runtime_suspend(dev); + if (dev->type && dev->type->pm) + cb = dev->type->pm->runtime_suspend; + else if (dev->class && dev->class->pm) + cb = dev->class->pm->runtime_suspend; + else if (dev->bus && dev->bus->pm) + cb = dev->bus->pm->runtime_suspend; + else + cb = NULL; - return 0; + if (!cb && dev->driver && dev->driver->pm) + cb = dev->driver->pm->runtime_suspend; + + return cb ? cb(dev) : 0; } /** @@ -1634,16 +1642,24 @@ static int pm_genpd_default_save_state(struct device *dev) static int pm_genpd_default_restore_state(struct device *dev) { int (*cb)(struct device *__dev); - struct device_driver *drv = dev->driver; cb = dev_gpd_data(dev)->ops.restore_state; if (cb) return cb(dev); - if (drv && drv->pm && drv->pm->runtime_resume) - return drv->pm->runtime_resume(dev); + if (dev->type && dev->type->pm) + cb = dev->type->pm->runtime_resume; + else if (dev->class && dev->class->pm) + cb = dev->class->pm->runtime_resume; + else if (dev->bus && dev->bus->pm) + cb = dev->bus->pm->runtime_resume; + else + cb = NULL; - return 0; + if (!cb && dev->driver && dev->driver->pm) + cb = dev->driver->pm->runtime_resume; + + return cb ? cb(dev) : 0; } #ifdef CONFIG_PM_SLEEP -- GitLab From 80de3d7f416f1accd03f2e519ead32d6fde4fcf4 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 16 Jun 2012 00:02:34 +0200 Subject: [PATCH 3387/6849] PM / Domains: Do not stop devices after restoring their states While resuming a device belonging to a PM domain, pm_genpd_runtime_resume() calls __pm_genpd_restore_device() to restore its state, if necessary. The latter starts the device, using genpd_start_dev(), restores its state, using genpd_restore_dev(), and then stops it, using genpd_stop_dev(). However, this last operation is not necessary, because the device is supposed to be operational after pm_genpd_runtime_resume() has returned and because of it pm_genpd_runtime_resume() has to call genpd_start_dev() once again for the "restored" device, which is inefficient. To make things more efficient, remove the call to genpd_stop_dev() from __pm_genpd_restore_device() and the direct call to genpd_start_dev() from pm_genpd_runtime_resume(). [Of course, genpd_start_dev() still has to be called by it for devices with the power.irq_safe flag set, because __pm_genpd_restore_device() is not executed for them.] This change has been tested on the SH7372 Mackerel board. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 49fdd4002b9f..da1d52576ec9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -339,19 +339,16 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd, { struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); struct device *dev = pdd->dev; + bool need_restore = gpd_data->need_restore; - if (!gpd_data->need_restore) - return; - + gpd_data->need_restore = false; mutex_unlock(&genpd->lock); genpd_start_dev(genpd, dev); - genpd_restore_dev(genpd, dev); - genpd_stop_dev(genpd, dev); + if (need_restore) + genpd_restore_dev(genpd, dev); mutex_lock(&genpd->lock); - - gpd_data->need_restore = false; } /** @@ -595,7 +592,7 @@ static int pm_genpd_runtime_resume(struct device *dev) /* If power.irq_safe, the PM domain is never powered off. */ if (dev->power.irq_safe) - goto out; + return genpd_start_dev(genpd, dev); mutex_lock(&genpd->lock); ret = __pm_genpd_poweron(genpd); @@ -628,9 +625,6 @@ static int pm_genpd_runtime_resume(struct device *dev) wake_up_all(&genpd->status_wait_queue); mutex_unlock(&genpd->lock); - out: - genpd_start_dev(genpd, dev); - return 0; } -- GitLab From ce9dcb8784611c50974d1c6b600c71f5c0a29308 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 31 May 2012 09:59:53 -0700 Subject: [PATCH 3388/6849] ARM: davinci: add runtime PM support for clock management Add runtime PM core support to davinci by using the pm_clk infrastructure of the PM core. When runtime PM is enabled, the davinci runtime PM implementation will use the pm_clk layer to enable/disable clocks on demand. When runtime PM is disabled, the pm_clk core will automatically enable clocks when the driver is bound and disable clocks when the driver is unbound. Cc: Mark A. Greer Cc: Sekhar Nori Signed-off-by: Kevin Hilman [nsekhar@ti.com: pruned list of header file includes and removed some debug code] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/Makefile | 1 + arch/arm/mach-davinci/pm_domain.c | 64 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 arch/arm/mach-davinci/pm_domain.c diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2db78bd5c835..2227effcb0e9 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_SUSPEND) += pm.o sleep.o +obj-$(CONFIG_HAVE_CLK) += pm_domain.o diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c new file mode 100644 index 000000000000..00946e23c1ee --- /dev/null +++ b/arch/arm/mach-davinci/pm_domain.c @@ -0,0 +1,64 @@ +/* + * Runtime PM support code for DaVinci + * + * Author: Kevin Hilman + * + * Copyright (C) 2012 Texas Instruments, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include + +#ifdef CONFIG_PM_RUNTIME +static int davinci_pm_runtime_suspend(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ret = pm_clk_suspend(dev); + if (ret) { + pm_generic_runtime_resume(dev); + return ret; + } + + return 0; +} + +static int davinci_pm_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s\n", __func__); + + pm_clk_resume(dev); + return pm_generic_runtime_resume(dev); +} +#endif + +static struct dev_pm_domain davinci_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(davinci_pm_runtime_suspend, + davinci_pm_runtime_resume, NULL) + USE_PLATFORM_PM_SLEEP_OPS + }, +}; + +static struct pm_clk_notifier_block platform_bus_notifier = { + .pm_domain = &davinci_pm_domain, +}; + +static int __init davinci_pm_runtime_init(void) +{ + pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); + + return 0; +} +core_initcall(davinci_pm_runtime_init); -- GitLab From 19b52abe3c5d759661500a1dc810924369b2ad46 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 27 Jun 2012 17:28:57 +0100 Subject: [PATCH 3389/6849] ARM: 7438/1: fill possible PMD empty section gaps On ARM with the 2-level page table format, a PMD entry is represented by two consecutive section entries covering 2MB of virtual space. However, static mappings always were allowed to use separate 1MB section entries. This means in practice that a static mapping may create half populated PMDs via create_mapping(). Since commit 0536bdf33f (ARM: move iotable mappings within the vmalloc region) those static mappings are located in the vmalloc area. We must ensure no such half populated PMDs are accessible once vmalloc() or ioremap() start looking at the vmalloc area for nearby free virtual address ranges, or various things leading to a kernel crash will happen. Signed-off-by: Nicolas Pitre Reported-by: Santosh Shilimkar Tested-by: "R, Sricharan" Reviewed-by: Catalin Marinas Cc: stable@vger.kernel.org Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e5dad60b558b..cf4528d51774 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -791,6 +791,79 @@ void __init iotable_init(struct map_desc *io_desc, int nr) } } +#ifndef CONFIG_ARM_LPAE + +/* + * The Linux PMD is made of two consecutive section entries covering 2MB + * (see definition in include/asm/pgtable-2level.h). However a call to + * create_mapping() may optimize static mappings by using individual + * 1MB section mappings. This leaves the actual PMD potentially half + * initialized if the top or bottom section entry isn't used, leaving it + * open to problems if a subsequent ioremap() or vmalloc() tries to use + * the virtual space left free by that unused section entry. + * + * Let's avoid the issue by inserting dummy vm entries covering the unused + * PMD halves once the static mappings are in place. + */ + +static void __init pmd_empty_section_gap(unsigned long addr) +{ + struct vm_struct *vm; + + vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm)); + vm->addr = (void *)addr; + vm->size = SECTION_SIZE; + vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; + vm->caller = pmd_empty_section_gap; + vm_area_add_early(vm); +} + +static void __init fill_pmd_gaps(void) +{ + struct vm_struct *vm; + unsigned long addr, next = 0; + pmd_t *pmd; + + /* we're still single threaded hence no lock needed here */ + for (vm = vmlist; vm; vm = vm->next) { + if (!(vm->flags & VM_ARM_STATIC_MAPPING)) + continue; + addr = (unsigned long)vm->addr; + if (addr < next) + continue; + + /* + * Check if this vm starts on an odd section boundary. + * If so and the first section entry for this PMD is free + * then we block the corresponding virtual address. + */ + if ((addr & ~PMD_MASK) == SECTION_SIZE) { + pmd = pmd_off_k(addr); + if (pmd_none(*pmd)) + pmd_empty_section_gap(addr & PMD_MASK); + } + + /* + * Then check if this vm ends on an odd section boundary. + * If so and the second section entry for this PMD is empty + * then we block the corresponding virtual address. + */ + addr += vm->size; + if ((addr & ~PMD_MASK) == SECTION_SIZE) { + pmd = pmd_off_k(addr) + 1; + if (pmd_none(*pmd)) + pmd_empty_section_gap(addr); + } + + /* no need to look at any vm entry until we hit the next PMD */ + next = (addr + PMD_SIZE - 1) & PMD_MASK; + } +} + +#else +#define fill_pmd_gaps() do { } while (0) +#endif + static void * __initdata vmalloc_min = (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); @@ -1072,6 +1145,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) */ if (mdesc->map_io) mdesc->map_io(); + fill_pmd_gaps(); /* * Finally flush the caches and tlb to ensure that we're in a -- GitLab From 84715dd6c19e058557ab173d327ea65eac0ccb02 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 2 Dec 2011 15:31:11 +0800 Subject: [PATCH 3390/6849] ARM: imx: eliminate macro IMX_GPIO_TO_IRQ() This patch changes all the static gpio irq number assigning with IMX_GPIO_TO_IRQ() to run-time assigning with gpio_to_irq call, and in turn eliminates the macro IMX_GPIO_TO_IRQ(). Signed-off-by: Shawn Guo Acked-by: Sascha Hauer --- arch/arm/mach-imx/mach-cpuimx35.c | 3 ++- arch/arm/mach-imx/mach-cpuimx51sd.c | 3 ++- arch/arm/mach-imx/mach-mx27_3ds.c | 3 ++- arch/arm/mach-imx/mach-mx35_3ds.c | 3 ++- arch/arm/mach-imx/mach-mx53_ard.c | 5 +++-- arch/arm/mach-imx/mach-vpr200.c | 3 ++- arch/arm/mach-imx/mx51_efika.c | 3 ++- arch/arm/plat-mxc/include/mach/hardware.h | 2 -- 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index c515f8ede1a1..73c4b65ebbe4 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -72,7 +72,7 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { I2C_BOARD_INFO("tsc2007", 0x48), .type = "tsc2007", .platform_data = &tsc2007_info, - .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), + /* irq number is run-time assigned */ }, }; @@ -173,6 +173,7 @@ static void __init eukrea_cpuimx35_init(void) imx35_add_imx_uart0(&uart_pdata); imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info); + eukrea_cpuimx35_i2c_devices[1].irq = gpio_to_irq(TSC2007_IRQGPIO); i2c_register_board_info(0, eukrea_cpuimx35_i2c_devices, ARRAY_SIZE(eukrea_cpuimx35_i2c_devices)); imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data); diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index ac50f1671e38..e42c6f8bed70 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -259,7 +259,7 @@ static struct spi_board_info cpuimx51sd_spi_device[] = { .mode = SPI_MODE_0, .chip_select = 0, .platform_data = &mcp251x_info, - .irq = IMX_GPIO_TO_IRQ(CAN_IRQGPIO) + /* irq number is run-time assigned */ }, }; @@ -310,6 +310,7 @@ static void __init eukrea_cpuimx51sd_init(void) msleep(20); gpio_set_value(CAN_RST, 1); imx51_add_ecspi(0, &cpuimx51sd_ecspi1_pdata); + cpuimx51sd_spi_device[0].irq = gpio_to_irq(CAN_IRQGPIO); spi_register_board_info(cpuimx51sd_spi_device, ARRAY_SIZE(cpuimx51sd_spi_device)); diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index c6d385c52257..18b9bcaa40e3 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -445,7 +445,7 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { .bus_num = 1, .chip_select = 0, /* SS0 */ .platform_data = &mc13783_pdata, - .irq = IMX_GPIO_TO_IRQ(PMIC_INT), + /* irq number is run-time assigned */ .mode = SPI_CS_HIGH, }, { .modalias = "l4f00242t03", @@ -496,6 +496,7 @@ static void __init mx27pdk_init(void) imx27_add_spi_imx1(&spi2_pdata); imx27_add_spi_imx0(&spi1_pdata); + mx27_3ds_spi_devs[0].irq = gpio_to_irq(PMIC_INT); spi_register_board_info(mx27_3ds_spi_devs, ARRAY_SIZE(mx27_3ds_spi_devs)); diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index 28aa19476de7..fa1ea74dfdd3 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -492,7 +492,7 @@ static struct i2c_board_info mx35_3ds_i2c_mc13892 = { I2C_BOARD_INFO("mc13892", 0x08), .platform_data = &mx35_3ds_mc13892_data, - .irq = IMX_GPIO_TO_IRQ(GPIO_PMIC_INT), + /* irq number is run-time assigned */ }; static void __init imx35_3ds_init_mc13892(void) @@ -504,6 +504,7 @@ static void __init imx35_3ds_init_mc13892(void) return; } + mx35_3ds_i2c_mc13892.irq = gpio_to_irq(GPIO_PMIC_INT); i2c_register_board_info(0, &mx35_3ds_i2c_mc13892, 1); } diff --git a/arch/arm/mach-imx/mach-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c index 05641980dc5e..fe3f3969cf1d 100644 --- a/arch/arm/mach-imx/mach-mx53_ard.c +++ b/arch/arm/mach-imx/mach-mx53_ard.c @@ -135,8 +135,7 @@ static struct resource ard_smsc911x_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = IMX_GPIO_TO_IRQ(ARD_ETHERNET_INT_B), - .end = IMX_GPIO_TO_IRQ(ARD_ETHERNET_INT_B), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ, }, }; @@ -240,6 +239,8 @@ static void __init mx53_ard_board_init(void) imx53_ard_common_init(); mx53_ard_io_init(); regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + ard_smsc911x_resources[1].start = gpio_to_irq(ARD_ETHERNET_INT_B); + ard_smsc911x_resources[1].end = gpio_to_irq(ARD_ETHERNET_INT_B); platform_add_devices(devices, ARRAY_SIZE(devices)); imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data); diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c index add8c69c6c1a..e36eb2c40f41 100644 --- a/arch/arm/mach-imx/mach-vpr200.c +++ b/arch/arm/mach-imx/mach-vpr200.c @@ -162,7 +162,7 @@ static struct i2c_board_info vpr200_i2c_devices[] = { }, { I2C_BOARD_INFO("mc13892", 0x08), .platform_data = &vpr200_pmic, - .irq = IMX_GPIO_TO_IRQ(GPIO_PMIC_INT), + /* irq number is run-time assigned */ } }; @@ -299,6 +299,7 @@ static void __init vpr200_board_init(void) imx35_add_mxc_nand(&vpr200_nand_board_info); imx35_add_sdhci_esdhc_imx(0, NULL); + vpr200_i2c_devices[1].irq = gpio_to_irq(GPIO_PMIC_INT); i2c_register_board_info(0, vpr200_i2c_devices, ARRAY_SIZE(vpr200_i2c_devices)); diff --git a/arch/arm/mach-imx/mx51_efika.c b/arch/arm/mach-imx/mx51_efika.c index ec6ca91b299b..ee870c49bc63 100644 --- a/arch/arm/mach-imx/mx51_efika.c +++ b/arch/arm/mach-imx/mx51_efika.c @@ -587,7 +587,7 @@ static struct spi_board_info mx51_efika_spi_board_info[] __initdata = { .bus_num = 0, .chip_select = 0, .platform_data = &mx51_efika_mc13892_data, - .irq = IMX_GPIO_TO_IRQ(EFIKAMX_PMIC), + /* irq number is run-time assigned */ }, }; @@ -620,6 +620,7 @@ void __init efika_board_common_init(void) gpio_request(EFIKAMX_PMIC, "pmic irq"); gpio_direction_input(EFIKAMX_PMIC); + mx51_efika_spi_board_info[1].irq = gpio_to_irq(EFIKAMX_PMIC); spi_register_board_info(mx51_efika_spi_board_info, ARRAY_SIZE(mx51_efika_spi_board_info)); imx51_add_ecspi(0, &mx51_efika_spi_pdata); diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index 0630513554de..1d432a75e409 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h @@ -128,6 +128,4 @@ /* range e.g. GPIO_1_5 is gpio 5 under linux */ #define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) -#define IMX_GPIO_TO_IRQ(gpio) (MXC_GPIO_IRQ_START + (gpio)) - #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ -- GitLab From ed175343b4b53d686e30b1e37fb94e142f56fa2f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 2 Dec 2011 20:00:33 +0800 Subject: [PATCH 3391/6849] ARM: imx: eliminate macro IOMUX_TO_IRQ() This patch changes all the static gpio irq number assigning with IOMUX_TO_IRQ() to run-time assigning with gpio_to_irq call, and in turn eliminates the macro IOMUX_TO_IRQ(). Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/mach-armadillo5x0.c | 12 ++++++++---- arch/arm/mach-imx/mach-kzm_arm11_01.c | 20 +++++++++++++++----- arch/arm/mach-imx/mach-mx31_3ds.c | 13 ++++++------- arch/arm/mach-imx/mach-mx31ads.c | 14 +++++++++----- arch/arm/mach-imx/mach-mx31lilly.c | 10 +++++++--- arch/arm/mach-imx/mach-mx31lite.c | 10 +++++++--- arch/arm/mach-imx/mach-mx31moboard.c | 4 +++- arch/arm/mach-imx/mach-pcm037.c | 18 ++++++++++++------ arch/arm/mach-imx/mach-qong.c | 9 +++++---- arch/arm/mach-imx/mx31lilly-db.c | 5 +++-- arch/arm/mach-imx/mx31lite-db.c | 5 +++-- arch/arm/plat-mxc/include/mach/iomux-mx3.h | 3 --- 12 files changed, 78 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index c650145d1646..f83c5c683575 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -408,7 +408,8 @@ static int armadillo5x0_sdhc1_init(struct device *dev, gpio_direction_input(gpio_wp); /* When supported the trigger type have to be BOTH */ - ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq, + ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)), + detect_irq, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "sdhc-detect", data); @@ -429,7 +430,7 @@ err_gpio_free: static void armadillo5x0_sdhc1_exit(struct device *dev, void *data) { - free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data); + free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)), data); gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)); gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B)); } @@ -450,8 +451,7 @@ static struct resource armadillo5x0_smc911x_resources[] = { .end = MX31_CS3_BASE_ADDR + SZ_32M - 1, .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), - .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; @@ -498,6 +498,10 @@ static void __init armadillo5x0_init(void) regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + armadillo5x0_smc911x_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); + armadillo5x0_smc911x_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); platform_add_devices(devices, ARRAY_SIZE(devices)); imx_add_gpio_keys(&armadillo5x0_button_data); imx31_add_imx_i2c1(NULL); diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c index 15a26e908260..5d08533ab2c7 100644 --- a/arch/arm/mach-imx/mach-kzm_arm11_01.c +++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c @@ -73,7 +73,7 @@ static struct plat_serial8250_port serial_platform_data[] = { { .membase = KZM_ARM11_IO_ADDRESS(KZM_ARM11_16550), .mapbase = KZM_ARM11_16550, - .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), + /* irq number is run-time assigned */ .irqflags = IRQ_TYPE_EDGE_RISING, .uartclk = 14745600, .regshift = 0, @@ -91,8 +91,7 @@ static struct resource serial8250_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), - .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ, }, }; @@ -125,6 +124,13 @@ static int __init kzm_init_ext_uart(void) tmp |= 0x2; __raw_writeb(tmp, KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1)); + serial_platform_data[0].irq = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); + serial8250_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); + serial8250_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); + return platform_device_register(&serial_device); } #else @@ -152,8 +158,7 @@ static struct resource kzm_smsc9118_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), - .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; @@ -184,6 +189,11 @@ static int __init kzm_init_smsc9118(void) regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + kzm_smsc9118_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); + kzm_smsc9118_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); + return platform_device_register(&kzm_smsc9118_device); } #else diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 4eafdf275ea2..ecdba0497e7e 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -44,9 +44,6 @@ #include "devices-imx31.h" -/* CPLD IRQ line for external uart, external ethernet etc */ -#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) - static int mx31_3ds_pins[] = { /* UART1 */ MX31_PIN_CTS1__CTS1, @@ -317,7 +314,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev, return ret; } - ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), + ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)), detect_irq, IRQF_DISABLED | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "sdhc1-detect", data); @@ -336,7 +333,7 @@ gpio_free: static void mx31_3ds_sdhc1_exit(struct device *dev, void *data) { - free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), data); + free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)), data); gpio_free_array(mx31_3ds_sdhc1_gpios, ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); } @@ -539,7 +536,7 @@ static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { .bus_num = 1, .chip_select = 1, /* SS2 */ .platform_data = &mc13783_pdata, - .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + /* irq number is run-time assigned */ .mode = SPI_CS_HIGH, }, { .modalias = "l4f00242t03", @@ -714,6 +711,7 @@ static void __init mx31_3ds_init(void) imx31_add_mxc_nand(&mx31_3ds_nand_board_info); imx31_add_spi_imx1(&spi1_pdata); + mx31_3ds_spi_devs[0].irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); spi_register_board_info(mx31_3ds_spi_devs, ARRAY_SIZE(mx31_3ds_spi_devs)); @@ -736,7 +734,8 @@ static void __init mx31_3ds_init(void) if (!otg_mode_host) imx31_add_fsl_usb2_udc(&usbotg_pdata); - if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT)) + if (mxc_expio_init(MX31_CS5_BASE_ADDR, + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)))) printk(KERN_WARNING "Init of the debug board failed, all " "devices on the debug board are unusable.\n"); imx31_add_imx2_wdt(NULL); diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 4518e5448227..6f19f98ddbe9 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -62,7 +62,6 @@ #define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS) #define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) -#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) #define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) @@ -209,7 +208,7 @@ static struct irq_chip expio_irq_chip = { static void __init mx31ads_init_expio(void) { - int i; + int i, irq; printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); @@ -226,8 +225,9 @@ static void __init mx31ads_init_expio(void) irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID); } - irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH); - irq_set_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); + irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_4)); + irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + irq_set_chained_handler(irq, mx31ads_expio_irq_handler); } #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 @@ -488,13 +488,17 @@ static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { { I2C_BOARD_INFO("wm8350", 0x1a), .platform_data = &mx31_wm8350_pdata, - .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + /* irq number is run-time assigned */ }, #endif }; static void __init mxc_init_i2c(void) { +#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 + mx31ads_i2c1_devices[0].irq = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); +#endif i2c_register_board_info(1, mx31ads_i2c1_devices, ARRAY_SIZE(mx31ads_i2c1_devices)); diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c index 83714b0cc290..34b9bf075daf 100644 --- a/arch/arm/mach-imx/mach-mx31lilly.c +++ b/arch/arm/mach-imx/mach-mx31lilly.c @@ -65,8 +65,7 @@ static struct resource smsc91x_resources[] = { .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), - .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, } }; @@ -233,7 +232,7 @@ static struct spi_board_info mc13783_dev __initdata = { .bus_num = 1, .chip_select = 0, .platform_data = &mc13783_pdata, - .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + /* irq number is run-time assigned */ }; static struct platform_device *devices[] __initdata = { @@ -285,10 +284,15 @@ static void __init mx31lilly_board_init(void) imx31_add_spi_imx0(&spi0_pdata); imx31_add_spi_imx1(&spi1_pdata); + mc13783_dev.irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); spi_register_board_info(&mc13783_dev, 1); regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + smsc91x_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); + smsc91x_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); platform_add_devices(devices, ARRAY_SIZE(devices)); /* USB */ diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index 686c60587980..4977378d2f60 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c @@ -83,8 +83,7 @@ static struct resource smsc911x_resources[] = { .end = MX31_CS4_BASE_ADDR + 0x100, .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(MX31_PIN_SFS6), - .end = IOMUX_TO_IRQ(MX31_PIN_SFS6), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ, }, }; @@ -124,7 +123,7 @@ static struct spi_board_info mc13783_spi_dev __initdata = { .bus_num = 1, .chip_select = 0, .platform_data = &mc13783_pdata, - .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + /* irq number is run-time assigned */ }; /* @@ -258,6 +257,7 @@ static void __init mx31lite_init(void) imx31_add_mxc_nand(&mx31lite_nand_board_info); imx31_add_spi_imx1(&spi1_pdata); + mc13783_spi_dev.irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); spi_register_board_info(&mc13783_spi_dev, 1); /* USB */ @@ -274,6 +274,10 @@ static void __init mx31lite_init(void) pr_warning("could not get LAN irq gpio\n"); else { gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6)); + smsc911x_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SFS6)); + smsc911x_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SFS6)); platform_device_register(&smsc911x_device); } } diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index 016791f038b0..f0d26db7719e 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -303,7 +303,7 @@ static struct imx_ssi_platform_data moboard_ssi_pdata = { static struct spi_board_info moboard_spi_board_info[] __initdata = { { .modalias = "mc13783", - .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + /* irq number is run-time assigned */ .max_speed_hz = 300000, .bus_num = 1, .chip_select = 0, @@ -557,6 +557,8 @@ static void __init mx31moboard_init(void) gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq"); gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); + moboard_spi_board_info[0].irq = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); spi_register_board_info(moboard_spi_board_info, ARRAY_SIZE(moboard_spi_board_info)); diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index 0a40004154f2..551a035f0c2d 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c @@ -225,8 +225,7 @@ static struct resource smsc911x_resources[] = { .end = MX31_CS1_BASE_ADDR + 0x300 + SZ_64K - 1, .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), - .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; @@ -371,7 +370,7 @@ static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq, gpio_direction_input(SDHC1_GPIO_WP); #endif - ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq, + ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "sdhc-detect", data); if (ret) @@ -391,7 +390,7 @@ err_gpio_free: static void pcm970_sdhc1_exit(struct device *dev, void *data) { - free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data); + free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), data); gpio_free(SDHC1_GPIO_DET); gpio_free(SDHC1_GPIO_WP); } @@ -511,8 +510,7 @@ static struct resource pcm970_sja1000_resources[] = { .end = MX31_CS5_BASE_ADDR + 0x100 - 1, .flags = IORESOURCE_MEM, }, { - .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)), - .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -633,6 +631,10 @@ static void __init pcm037_init(void) pr_warning("could not get LAN irq gpio\n"); else { gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); + smsc911x_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); + smsc911x_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); platform_device_register(&pcm037_eth); } @@ -659,6 +661,10 @@ static void __init pcm037_init(void) pcm037_init_camera(); + pcm970_sja1000_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(IOMUX_PIN(48, 105))); + pcm970_sja1000_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(IOMUX_PIN(48, 105))); platform_device_register(&pcm970_sja1000); if (otg_mode_host) { diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 260621055b6b..b6f11d25f25a 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -51,8 +51,6 @@ (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE) #define QONG_DNET_SIZE 0x00001000 -#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1) - static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -78,8 +76,7 @@ static struct resource dnet_resources[] = { .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, .flags = IORESOURCE_MEM, }, { - .start = QONG_FPGA_IRQ, - .end = QONG_FPGA_IRQ, + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ, }, }; @@ -95,6 +92,10 @@ static int __init qong_init_dnet(void) { int ret; + dnet_resources[1].start = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)); + dnet_resources[1].end = + gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)); ret = platform_device_register(&dnet_device); return ret; } diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c index 7d26f766a4ee..2df625bdc71e 100644 --- a/arch/arm/mach-imx/mx31lilly-db.c +++ b/arch/arm/mach-imx/mx31lilly-db.c @@ -130,7 +130,8 @@ static int mxc_mmc1_init(struct device *dev, gpio_direction_input(gpio_det); gpio_direction_input(gpio_wp); - ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq, + ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)), + detect_irq, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "MMC detect", data); if (ret) @@ -151,7 +152,7 @@ static void mxc_mmc1_exit(struct device *dev, void *data) { gpio_free(gpio_det); gpio_free(gpio_wp); - free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data); + free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)), data); } static const struct imxmmc_platform_data mmc_pdata __initconst = { diff --git a/arch/arm/mach-imx/mx31lite-db.c b/arch/arm/mach-imx/mx31lite-db.c index bf0fb87946ba..d639391a5841 100644 --- a/arch/arm/mach-imx/mx31lite-db.c +++ b/arch/arm/mach-imx/mx31lite-db.c @@ -116,7 +116,8 @@ static int mxc_mmc1_init(struct device *dev, gpio_direction_input(gpio_det); gpio_direction_input(gpio_wp); - ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq, + ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)), + detect_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC detect", data); if (ret) @@ -137,7 +138,7 @@ static void mxc_mmc1_exit(struct device *dev, void *data) { gpio_free(gpio_det); gpio_free(gpio_wp); - free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data); + free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)), data); } static const struct imxmmc_platform_data mmc_pdata __initconst = { diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index 63f22a009a65..d8b65b51f2a9 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -160,9 +160,6 @@ int mxc_iomux_mode(unsigned int pin_mode); #define IOMUX_TO_GPIO(iomux_pin) \ ((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) -#define IOMUX_TO_IRQ(iomux_pin) \ - (((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \ - MXC_GPIO_IRQ_START) /* * This enumeration is constructed based on the Section -- GitLab From 438196c371cb32f0eacaf2a44166d9a0cf37c4a8 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 5 Dec 2011 10:12:28 +0800 Subject: [PATCH 3392/6849] ARM: imx: eliminate macro IRQ_GPIOx() This patch changes all the static gpio irq number assigning with IRQ_GPIOA() ... IRQ_GPIOF() to run-time assigning with gpio_to_irq call, and in turn eliminates these macros. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/eukrea_mbimx27-baseboard.c | 3 ++- arch/arm/mach-imx/mach-apf9328.c | 6 ++++-- arch/arm/mach-imx/mach-cpuimx27.c | 12 ++++++++---- arch/arm/mach-imx/mach-imx27_visstrim_m10.c | 9 +++++---- arch/arm/mach-imx/mach-mx21ads.c | 16 +++++++++++----- arch/arm/mach-imx/mach-mx27ads.c | 12 ++++++------ arch/arm/mach-imx/mach-mxt_td60.c | 6 +++--- arch/arm/mach-imx/mach-pca100.c | 4 ++-- arch/arm/mach-imx/mach-pcm038.c | 4 +++- arch/arm/mach-imx/mach-scb9328.c | 6 ++++-- arch/arm/mach-imx/pcm970-baseboard.c | 13 +++++++------ arch/arm/plat-mxc/include/mach/iomux-v1.h | 7 ------- 12 files changed, 55 insertions(+), 43 deletions(-) diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c index b46cab0ced53..fd3177f9e79a 100644 --- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c @@ -266,7 +266,7 @@ static struct spi_board_info __maybe_unused .bus_num = 0, .chip_select = 0, .max_speed_hz = 1500000, - .irq = IRQ_GPIOD(25), + /* irq number is run-time assigned */ .platform_data = &ads7846_config, .mode = SPI_MODE_2, }, @@ -329,6 +329,7 @@ void __init eukrea_mbimx27_baseboard_init(void) /* SPI_CS0 init */ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); imx27_add_spi_imx0(&eukrea_mbimx27_spi0_data); + eukrea_mbimx27_spi_board_info[0].irq = gpio_to_irq(IMX_GPIO_NR(4, 25)); spi_register_board_info(eukrea_mbimx27_spi_board_info, ARRAY_SIZE(eukrea_mbimx27_spi_board_info)); diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c index f4a63ee9e217..5062fcb88498 100644 --- a/arch/arm/mach-imx/mach-apf9328.c +++ b/arch/arm/mach-imx/mach-apf9328.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -87,8 +88,7 @@ static struct resource dm9000_resources[] = { .end = MX1_CS4_PHYS + 0x00C00003, .flags = IORESOURCE_MEM, }, { - .start = IRQ_GPIOB(14), - .end = IRQ_GPIOB(14), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; @@ -129,6 +129,8 @@ static void __init apf9328_init(void) imx1_add_imx_i2c(&apf9328_i2c_data); + dm9000_resources[2].start = gpio_to_irq(IMX_GPIO_NR(2, 14)); + dm9000_resources[2].end = gpio_to_irq(IMX_GPIO_NR(2, 14)); platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index d085aea08709..fe74c84a1f4e 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c @@ -169,28 +169,28 @@ static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = { static struct plat_serial8250_port serial_platform_data[] = { { .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x200000), - .irq = IRQ_GPIOB(23), + /* irq number is run-time assigned */ .uartclk = 14745600, .regshift = 1, .iotype = UPIO_MEM, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, }, { .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x400000), - .irq = IRQ_GPIOB(22), + /* irq number is run-time assigned */ .uartclk = 14745600, .regshift = 1, .iotype = UPIO_MEM, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, }, { .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x800000), - .irq = IRQ_GPIOB(27), + /* irq number is run-time assigned */ .uartclk = 14745600, .regshift = 1, .iotype = UPIO_MEM, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, }, { .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x1000000), - .irq = IRQ_GPIOB(30), + /* irq number is run-time assigned */ .uartclk = 14745600, .regshift = 1, .iotype = UPIO_MEM, @@ -279,6 +279,10 @@ static void __init eukrea_cpuimx27_init(void) #endif #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) + serial_platform_data[0].irq = IMX_GPIO_NR(2, 23); + serial_platform_data[1].irq = IMX_GPIO_NR(2, 22); + serial_platform_data[2].irq = IMX_GPIO_NR(2, 27); + serial_platform_data[3].irq = IMX_GPIO_NR(2, 30); platform_device_register(&serial_device); #endif diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index dff82eb57cd9..54c34a6f92c7 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "devices-imx27.h" @@ -47,7 +48,7 @@ #define TVP5150_RSTN (GPIO_PORTC + 18) #define TVP5150_PWDN (GPIO_PORTC + 19) #define OTG_PHY_CS_GPIO (GPIO_PORTF + 17) -#define SDHC1_IRQ IRQ_GPIOB(25) +#define SDHC1_IRQ_GPIO IMX_GPIO_NR(2, 25) #define MOTHERBOARD_BIT2 (GPIO_PORTD + 31) #define MOTHERBOARD_BIT1 (GPIO_PORTD + 30) @@ -294,14 +295,14 @@ static int visstrim_m10_sdhc1_init(struct device *dev, { int ret; - ret = request_irq(SDHC1_IRQ, detect_irq, IRQF_TRIGGER_FALLING, - "mmc-detect", data); + ret = request_irq(gpio_to_irq(SDHC1_IRQ_GPIO), detect_irq, + IRQF_TRIGGER_FALLING, "mmc-detect", data); return ret; } static void visstrim_m10_sdhc1_exit(struct device *dev, void *data) { - free_irq(SDHC1_IRQ, data); + free_irq(gpio_to_irq(SDHC1_IRQ_GPIO), data); } static const struct imxmmc_platform_data visstrim_m10_sdhc_pdata __initconst = { diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index d14bbe949a4f..ab3bdf738f53 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -38,7 +38,7 @@ (MX21ADS_MMIO_BASE_ADDR + (offset)) #define MX21ADS_CS8900A_MMIO_SIZE 0x200000 -#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11) +#define MX21ADS_CS8900A_IRQ_GPIO IMX_GPIO_NR(5, 11) #define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000) #define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000) #define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000) @@ -159,9 +159,10 @@ static struct platform_device mx21ads_nor_mtd_device = { .resource = &mx21ads_flash_resource, }; -static const struct resource mx21ads_cs8900_resources[] __initconst = { +static struct resource mx21ads_cs8900_resources[] __initdata = { DEFINE_RES_MEM(MX21_CS1_BASE_ADDR, MX21ADS_CS8900A_MMIO_SIZE), - DEFINE_RES_IRQ(MX21ADS_CS8900A_IRQ), + /* irq number is run-time assigned */ + DEFINE_RES_IRQ(-1), }; static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = { @@ -241,13 +242,13 @@ static int mx21ads_sdhc_get_ro(struct device *dev) static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq, void *data) { - return request_irq(IRQ_GPIOD(25), detect_irq, + return request_irq(gpio_to_irq(IMX_GPIO_NR(4, 25)), detect_irq, IRQF_TRIGGER_FALLING, "mmc-detect", data); } static void mx21ads_sdhc_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIOD(25), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(4, 25)), data); } static const struct imxmmc_platform_data mx21ads_sdhc_pdata __initconst = { @@ -304,6 +305,11 @@ static void __init mx21ads_board_init(void) imx21_add_mxc_nand(&mx21ads_nand_board_info); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + + mx21ads_cs8900_resources[1].start = + gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO); + mx21ads_cs8900_resources[1].end = + gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO); platform_device_register_full(&mx21ads_cs8900_devinfo); } diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index 0228d2e07fe0..78b6bb5fcc6a 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -246,25 +246,25 @@ static const struct imx_fb_platform_data mx27ads_fb_data __initconst = { static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq, void *data) { - return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING, - "sdhc1-card-detect", data); + return request_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), detect_irq, + IRQF_TRIGGER_RISING, "sdhc1-card-detect", data); } static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data) { - return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING, - "sdhc2-card-detect", data); + return request_irq(gpio_to_irq(IMX_GPIO_NR(2, 7)), detect_irq, + IRQF_TRIGGER_RISING, "sdhc2-card-detect", data); } static void mx27ads_sdhc1_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIOE(21), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), data); } static void mx27ads_sdhc2_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIOB(7), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(2, 7)), data); } static const struct imxmmc_platform_data sdhc1_pdata __initconst = { diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c index 8b3d3f07d894..0bf6d30aa32d 100644 --- a/arch/arm/mach-imx/mach-mxt_td60.c +++ b/arch/arm/mach-imx/mach-mxt_td60.c @@ -213,13 +213,13 @@ static const struct imx_fb_platform_data mxt_td60_fb_data __initconst = { static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq, void *data) { - return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING, - "sdhc1-card-detect", data); + return request_irq(gpio_to_irq(IMX_GPIO_NR(6, 8)), detect_irq, + IRQF_TRIGGER_FALLING, "sdhc1-card-detect", data); } static void mxt_td60_sdhc1_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIOF(8), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(6, 8)), data); } static const struct imxmmc_platform_data sdhc1_pdata __initconst = { diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index 541152e450c4..8b1dfa277fd5 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c @@ -245,7 +245,7 @@ static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq, { int ret; - ret = request_irq(IRQ_GPIOC(29), detect_irq, + ret = request_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), detect_irq, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "imx-mmc-detect", data); if (ret) @@ -257,7 +257,7 @@ static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq, static void pca100_sdhc2_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIOC(29), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), data); } static const struct imxmmc_platform_data sdhc_pdata __initconst = { diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index 2f3debe2a113..cfb39037b203 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -274,7 +275,7 @@ static struct mc13xxx_platform_data pcm038_pmic = { static struct spi_board_info pcm038_spi_board_info[] __initdata = { { .modalias = "mc13783", - .irq = IRQ_GPIOB(23), + /* irq number is run-time assigned */ .max_speed_hz = 300000, .bus_num = 0, .chip_select = 0, @@ -325,6 +326,7 @@ static void __init pcm038_init(void) mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN); imx27_add_spi_imx0(&pcm038_spi0_data); + pcm038_spi_board_info[0].irq = gpio_to_irq(IMX_GPIO_NR(2, 23)); spi_register_board_info(pcm038_spi_board_info, ARRAY_SIZE(pcm038_spi_board_info)); diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c index cb9ceae2f648..500116498698 100644 --- a/arch/arm/mach-imx/mach-scb9328.c +++ b/arch/arm/mach-imx/mach-scb9328.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -78,8 +79,7 @@ static struct resource dm9000x_resources[] = { .end = MX1_CS5_PHYS + 5, .flags = IORESOURCE_MEM, /* data access */ }, { - .start = IRQ_GPIOC(3), - .end = IRQ_GPIOC(3), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; @@ -123,6 +123,8 @@ static void __init scb9328_init(void) imx1_add_imx_uart0(&uart_pdata); printk(KERN_INFO"Scb9328: Adding devices\n"); + dm9000x_resources[2].start = gpio_to_irq(IMX_GPIO_NR(3, 3)); + dm9000x_resources[2].end = gpio_to_irq(IMX_GPIO_NR(3, 3)); platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c index 99afbc3f43a3..9917e2ff51da 100644 --- a/arch/arm/mach-imx/pcm970-baseboard.c +++ b/arch/arm/mach-imx/pcm970-baseboard.c @@ -95,14 +95,14 @@ static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void { int ret; - ret = request_irq(IRQ_GPIOC(29), detect_irq, IRQF_TRIGGER_FALLING, - "imx-mmc-detect", data); + ret = request_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), detect_irq, + IRQF_TRIGGER_FALLING, "imx-mmc-detect", data); if (ret) return ret; ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro"); if (ret) { - free_irq(IRQ_GPIOC(29), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), data); return ret; } @@ -113,7 +113,7 @@ static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void static void pcm970_sdhc2_exit(struct device *dev, void *data) { - free_irq(IRQ_GPIOC(29), data); + free_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), data); gpio_free(GPIO_PORTC + 28); } @@ -192,8 +192,7 @@ static struct resource pcm970_sja1000_resources[] = { .end = MX27_CS4_BASE_ADDR + 0x100 - 1, .flags = IORESOURCE_MEM, }, { - .start = IRQ_GPIOE(19), - .end = IRQ_GPIOE(19), + /* irq number is run-time assigned */ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -227,5 +226,7 @@ void __init pcm970_baseboard_init(void) imx27_add_imx_fb(&pcm038_fb_data); mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN); imx27_add_mxc_mmc(1, &sdhc_pdata); + pcm970_sja1000_resources[1].start = gpio_to_irq(IMX_GPIO_NR(5, 19)); + pcm970_sja1000_resources[1].end = gpio_to_irq(IMX_GPIO_NR(5, 19)); platform_device_register(&pcm970_sja1000); } diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h index f7d18046c04f..02651a40fe23 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-v1.h +++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h @@ -85,13 +85,6 @@ #define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) #define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) -#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x) -#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) -#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) -#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) -#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) -#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x) - extern int mxc_gpio_mode(int gpio_mode); extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, const char *label); -- GitLab From 1ab7ef158dfbaf6314b6660a3e3fb037cba2a1ca Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 09:04:03 +0800 Subject: [PATCH 3393/6849] gpio/mxc: move irq_domain_add_legacy call into gpio driver Move irq_domain_add_legacy call from imx*-dt.c into gpio driver and have the gpio driver adopt irqdomain support for both DT and non-DT boot. With all imx platform code converted from static gpio irq number computation to use run-time gpio_to_irq call, we can now use irq_alloc_descs and irqdomain support to dynamically get irq_base and have the mapping between gpio and irq number available without using virtual_irq_start and MXC_GPIO_IRQ_START. Signed-off-by: Shawn Guo Cc: Grant Likely Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/imx27-dt.c | 13 -------- arch/arm/mach-imx/imx51-dt.c | 12 -------- arch/arm/mach-imx/imx53-dt.c | 12 -------- arch/arm/mach-imx/mach-imx6q.c | 14 --------- drivers/gpio/gpio-mxc.c | 56 +++++++++++++++++++--------------- 5 files changed, 32 insertions(+), 75 deletions(-) diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c index eee0cc8d92a4..c734e564f204 100644 --- a/arch/arm/mach-imx/imx27-dt.c +++ b/arch/arm/mach-imx/imx27-dt.c @@ -40,21 +40,8 @@ static int __init imx27_avic_add_irq_domain(struct device_node *np, return 0; } -static int __init imx27_gpio_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, - NULL); - - return 0; -} - static const struct of_device_id imx27_irq_match[] __initconst = { { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, }, - { .compatible = "fsl,imx27-gpio", .data = imx27_gpio_add_irq_domain, }, { /* sentinel */ } }; diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c index 18e78dba4298..3bdabbc64f43 100644 --- a/arch/arm/mach-imx/imx51-dt.c +++ b/arch/arm/mach-imx/imx51-dt.c @@ -52,20 +52,8 @@ static int __init imx51_tzic_add_irq_domain(struct device_node *np, return 0; } -static int __init imx51_gpio_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL); - - return 0; -} - static const struct of_device_id imx51_irq_match[] __initconst = { { .compatible = "fsl,imx51-tzic", .data = imx51_tzic_add_irq_domain, }, - { .compatible = "fsl,imx51-gpio", .data = imx51_gpio_add_irq_domain, }, { /* sentinel */ } }; diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c index eb04b6248e48..17fca3cac268 100644 --- a/arch/arm/mach-imx/imx53-dt.c +++ b/arch/arm/mach-imx/imx53-dt.c @@ -59,20 +59,8 @@ static int __init imx53_tzic_add_irq_domain(struct device_node *np, return 0; } -static int __init imx53_gpio_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL); - - return 0; -} - static const struct of_device_id imx53_irq_match[] __initconst = { { .compatible = "fsl,imx53-tzic", .data = imx53_tzic_add_irq_domain, }, - { .compatible = "fsl,imx53-gpio", .data = imx53_gpio_add_irq_domain, }, { /* sentinel */ } }; diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index b47e98b7d539..8c2a649192ca 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -136,21 +135,8 @@ static void __init imx6q_map_io(void) imx6q_clock_map_io(); } -static int __init imx6q_gpio_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, - NULL); - - return 0; -} - static const struct of_device_id imx6q_irq_match[] __initconst = { { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, - { .compatible = "fsl,imx6q-gpio", .data = imx6q_gpio_add_irq_domain, }, { /* sentinel */ } }; diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index c337143b18f8..e5db670d0002 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -33,8 +34,6 @@ #include #include -#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) - enum mxc_gpio_hwtype { IMX1_GPIO, /* runs on i.mx1 */ IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ @@ -61,7 +60,7 @@ struct mxc_gpio_port { void __iomem *base; int irq; int irq_high; - int virtual_irq_start; + struct irq_domain *domain; struct bgpio_chip bgc; u32 both_edges; }; @@ -144,14 +143,15 @@ static LIST_HEAD(mxc_gpio_ports); static int gpio_set_irq_type(struct irq_data *d, u32 type) { - u32 gpio = irq_to_gpio(d->irq); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; u32 bit, val; + u32 gpio_idx = d->hwirq; + u32 gpio = port->bgc.gc.base + gpio_idx; int edge; void __iomem *reg = port->base; - port->both_edges &= ~(1 << (gpio & 31)); + port->both_edges &= ~(1 << gpio_idx); switch (type) { case IRQ_TYPE_EDGE_RISING: edge = GPIO_INT_RISE_EDGE; @@ -168,7 +168,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) edge = GPIO_INT_HIGH_LEV; pr_debug("mxc: set GPIO %d to high trigger\n", gpio); } - port->both_edges |= 1 << (gpio & 31); + port->both_edges |= 1 << gpio_idx; break; case IRQ_TYPE_LEVEL_LOW: edge = GPIO_INT_LOW_LEV; @@ -180,11 +180,11 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) return -EINVAL; } - reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ - bit = gpio & 0xf; + reg += GPIO_ICR1 + ((gpio_idx & 0x10) >> 2); /* ICR1 or ICR2 */ + bit = gpio_idx & 0xf; val = readl(reg) & ~(0x3 << (bit << 1)); writel(val | (edge << (bit << 1)), reg); - writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); + writel(1 << gpio_idx, port->base + GPIO_ISR); return 0; } @@ -217,15 +217,13 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) /* handle 32 interrupts in one status register */ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) { - u32 gpio_irq_no_base = port->virtual_irq_start; - while (irq_stat != 0) { int irqoffset = fls(irq_stat) - 1; if (port->both_edges & (1 << irqoffset)) mxc_flip_edge(port, irqoffset); - generic_handle_irq(gpio_irq_no_base + irqoffset); + generic_handle_irq(irq_find_mapping(port->domain, irqoffset)); irq_stat &= ~(1 << irqoffset); } @@ -276,10 +274,9 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) */ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) { - u32 gpio = irq_to_gpio(d->irq); - u32 gpio_idx = gpio & 0x1F; struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; + u32 gpio_idx = d->hwirq; if (enable) { if (port->irq_high && (gpio_idx >= 16)) @@ -296,12 +293,12 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) return 0; } -static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) +static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) { struct irq_chip_generic *gc; struct irq_chip_type *ct; - gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, + gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base, port->base, handle_level_irq); gc->private = port; @@ -352,7 +349,7 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset) struct mxc_gpio_port *port = container_of(bgc, struct mxc_gpio_port, bgc); - return port->virtual_irq_start + offset; + return irq_find_mapping(port->domain, offset); } static int __devinit mxc_gpio_probe(struct platform_device *pdev) @@ -360,6 +357,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct mxc_gpio_port *port; struct resource *iores; + int irq_base; int err; mxc_gpio_get_hw(pdev); @@ -430,20 +428,30 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) if (err) goto out_bgpio_remove; - /* - * In dt case, we use gpio number range dynamically - * allocated by gpio core. - */ - port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base : - pdev->id * 32); + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); + if (irq_base < 0) { + err = irq_base; + goto out_gpiochip_remove; + } + + port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, + &irq_domain_simple_ops, NULL); + if (!port->domain) { + err = -ENODEV; + goto out_irqdesc_free; + } /* gpio-mxc can be a generic irq chip */ - mxc_gpio_init_gc(port); + mxc_gpio_init_gc(port, irq_base); list_add_tail(&port->node, &mxc_gpio_ports); return 0; +out_irqdesc_free: + irq_free_descs(irq_base, 32); +out_gpiochip_remove: + WARN_ON(gpiochip_remove(&port->bgc.gc) < 0); out_bgpio_remove: bgpio_remove(&port->bgc); out_iounmap: -- GitLab From f3eac29da1f6a477722b56ff00228e8a13f8f6c6 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 10:20:58 +0800 Subject: [PATCH 3394/6849] ARM: imx: move irq_domain_add_legacy call into tzic driver Move irq_domain_add_legacy call from imx5*-dt.c into tzic init function and have the tzic driver adopt irqdomain support for both DT and non-DT boot. Now tzic init function calls irq_alloc_descs to get irq_base and adds a lenacy irqdomain with the irq_base, so that the mapping between tzic irq and Linux irq number can be handled by irqdomain. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/imx51-dt.c | 15 --------------- arch/arm/mach-imx/imx53-dt.c | 15 --------------- arch/arm/plat-mxc/tzic.c | 28 ++++++++++++++++++++-------- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c index 3bdabbc64f43..d4067fe36357 100644 --- a/arch/arm/mach-imx/imx51-dt.c +++ b/arch/arm/mach-imx/imx51-dt.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -45,18 +44,6 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = { { /* sentinel */ } }; -static int __init imx51_tzic_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL); - return 0; -} - -static const struct of_device_id imx51_irq_match[] __initconst = { - { .compatible = "fsl,imx51-tzic", .data = imx51_tzic_add_irq_domain, }, - { /* sentinel */ } -}; - static const struct of_device_id imx51_iomuxc_of_match[] __initconst = { { .compatible = "fsl,imx51-iomuxc-babbage", .data = imx51_babbage_common_init, }, { /* sentinel */ } @@ -68,8 +55,6 @@ static void __init imx51_dt_init(void) const struct of_device_id *of_id; void (*func)(void); - of_irq_init(imx51_irq_match); - pinctrl_provide_dummies(); node = of_find_matching_node(NULL, imx51_iomuxc_of_match); diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c index 17fca3cac268..fdd90805d98e 100644 --- a/arch/arm/mach-imx/imx53-dt.c +++ b/arch/arm/mach-imx/imx53-dt.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -52,18 +51,6 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = { { /* sentinel */ } }; -static int __init imx53_tzic_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL); - return 0; -} - -static const struct of_device_id imx53_irq_match[] __initconst = { - { .compatible = "fsl,imx53-tzic", .data = imx53_tzic_add_irq_domain, }, - { /* sentinel */ } -}; - static const struct of_device_id imx53_iomuxc_of_match[] __initconst = { { .compatible = "fsl,imx53-iomuxc-ard", .data = imx53_ard_common_init, }, { .compatible = "fsl,imx53-iomuxc-evk", .data = imx53_evk_common_init, }, @@ -91,8 +78,6 @@ static void __init imx53_dt_init(void) const struct of_device_id *of_id; void (*func)(void); - of_irq_init(imx53_irq_match); - pinctrl_provide_dummies(); node = of_find_matching_node(NULL, imx53_iomuxc_of_match); diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index 98308ec1f321..abc90e4116f5 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -49,6 +51,7 @@ #define TZIC_ID0 0x0FD0 /* Indentification Register 0 */ void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */ +static struct irq_domain *domain; #define TZIC_NUM_IRQS 128 @@ -77,15 +80,14 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) static void tzic_irq_suspend(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - int idx = gc->irq_base >> 5; + int idx = d->hwirq >> 5; __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); } static void tzic_irq_resume(struct irq_data *d) { - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - int idx = gc->irq_base >> 5; + int idx = d->hwirq >> 5; __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), tzic_base + TZIC_WAKEUP0(idx)); @@ -102,11 +104,10 @@ static struct mxc_extra_irq tzic_extra_irq = { #endif }; -static __init void tzic_init_gc(unsigned int irq_start) +static __init void tzic_init_gc(int idx, unsigned int irq_start) { struct irq_chip_generic *gc; struct irq_chip_type *ct; - int idx = irq_start >> 5; gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base, handle_level_irq); @@ -140,7 +141,8 @@ asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) while (stat) { handled = 1; irqofs = fls(stat) - 1; - handle_IRQ(irqofs + i * 32, regs); + handle_IRQ(irq_find_mapping(domain, + irqofs + i * 32), regs); stat &= ~(1 << irqofs); } } @@ -154,6 +156,8 @@ asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) */ void __init tzic_init_irq(void __iomem *irqbase) { + struct device_node *np; + int irq_base; int i; tzic_base = irqbase; @@ -175,8 +179,16 @@ void __init tzic_init_irq(void __iomem *irqbase) /* all IRQ no FIQ Warning :: No selection */ - for (i = 0; i < TZIC_NUM_IRQS; i += 32) - tzic_init_gc(i); + irq_base = irq_alloc_descs(-1, 0, TZIC_NUM_IRQS, numa_node_id()); + WARN_ON(irq_base < 0); + + np = of_find_compatible_node(NULL, NULL, "fsl,tzic"); + domain = irq_domain_add_legacy(np, TZIC_NUM_IRQS, irq_base, 0, + &irq_domain_simple_ops, NULL); + WARN_ON(!domain); + + for (i = 0; i < 4; i++, irq_base += 32) + tzic_init_gc(i, irq_base); #ifdef CONFIG_FIQ /* Initialize FIQ */ -- GitLab From 544496ab5cbdae312351da4c742ae70cab08dbf2 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 10:55:46 +0800 Subject: [PATCH 3395/6849] ARM: imx: move irq_domain_add_legacy call into avic driver Move irq_domain_add_legacy call from imx27-dt.c into avic init function and have the avic driver adopt irqdomain support for both DT and non-DT boot. Now avic init function calls irq_alloc_descs to get irq_base and adds a lenacy irqdomain with the irq_base, so that the mapping between avic irq and Linux irq number can be handled by irqdomain. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/imx27-dt.c | 15 --------------- arch/arm/plat-mxc/avic.c | 32 +++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c index c734e564f204..5142ef048a60 100644 --- a/arch/arm/mach-imx/imx27-dt.c +++ b/arch/arm/mach-imx/imx27-dt.c @@ -10,7 +10,6 @@ */ #include -#include #include #include #include @@ -33,22 +32,8 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { { /* sentinel */ } }; -static int __init imx27_avic_add_irq_domain(struct device_node *np, - struct device_node *interrupt_parent) -{ - irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL); - return 0; -} - -static const struct of_device_id imx27_irq_match[] __initconst = { - { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, }, - { /* sentinel */ } -}; - static void __init imx27_dt_init(void) { - of_irq_init(imx27_irq_match); - of_platform_populate(NULL, of_default_bus_match_table, imx27_auxdata_lookup, NULL); } diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c index 689f81f9593b..e612cc1edede 100644 --- a/arch/arm/plat-mxc/avic.c +++ b/arch/arm/plat-mxc/avic.c @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include #include #include @@ -50,15 +52,19 @@ #define AVIC_NUM_IRQS 64 void __iomem *avic_base; +static struct irq_domain *domain; static u32 avic_saved_mask_reg[2]; #ifdef CONFIG_MXC_IRQ_PRIOR static int avic_irq_set_priority(unsigned char irq, unsigned char prio) { + struct irq_data *d = irq_get_irq_data(irq); unsigned int temp; unsigned int mask = 0x0F << irq % 8 * 4; + irq = d->hwirq; + if (irq >= AVIC_NUM_IRQS) return -EINVAL; @@ -75,8 +81,11 @@ static int avic_irq_set_priority(unsigned char irq, unsigned char prio) #ifdef CONFIG_FIQ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) { + struct irq_data *d = irq_get_irq_data(irq); unsigned int irqt; + irq = d->hwirq; + if (irq >= AVIC_NUM_IRQS) return -EINVAL; @@ -108,7 +117,7 @@ static void avic_irq_suspend(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct irq_chip_type *ct = gc->chip_types; - int idx = gc->irq_base >> 5; + int idx = d->hwirq >> 5; avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); __raw_writel(gc->wake_active, avic_base + ct->regs.mask); @@ -118,7 +127,7 @@ static void avic_irq_resume(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct irq_chip_type *ct = gc->chip_types; - int idx = gc->irq_base >> 5; + int idx = d->hwirq >> 5; __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); } @@ -128,11 +137,10 @@ static void avic_irq_resume(struct irq_data *d) #define avic_irq_resume NULL #endif -static __init void avic_init_gc(unsigned int irq_start) +static __init void avic_init_gc(int idx, unsigned int irq_start) { struct irq_chip_generic *gc; struct irq_chip_type *ct; - int idx = irq_start >> 5; gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base, handle_level_irq); @@ -161,7 +169,7 @@ asmlinkage void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) if (nivector == 0xffff) break; - handle_IRQ(nivector, regs); + handle_IRQ(irq_find_mapping(domain, nivector), regs); } while (1); } @@ -172,6 +180,8 @@ asmlinkage void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) */ void __init mxc_init_irq(void __iomem *irqbase) { + struct device_node *np; + int irq_base; int i; avic_base = irqbase; @@ -190,8 +200,16 @@ void __init mxc_init_irq(void __iomem *irqbase) __raw_writel(0, avic_base + AVIC_INTTYPEH); __raw_writel(0, avic_base + AVIC_INTTYPEL); - for (i = 0; i < AVIC_NUM_IRQS; i += 32) - avic_init_gc(i); + irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id()); + WARN_ON(irq_base < 0); + + np = of_find_compatible_node(NULL, NULL, "fsl,avic"); + domain = irq_domain_add_legacy(np, AVIC_NUM_IRQS, irq_base, 0, + &irq_domain_simple_ops, NULL); + WARN_ON(!domain); + + for (i = 0; i < AVIC_NUM_IRQS / 32; i++, irq_base += 32) + avic_init_gc(i, irq_base); /* Set default priority value (0) for all IRQ's */ for (i = 0; i < 8; i++) -- GitLab From 88289c80d419897c03f7f43b35e3730d8fb6825b Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 14:07:31 +0800 Subject: [PATCH 3396/6849] dma: ipu: remove the use of ipu_platform_data The struct ipu_platform_data is used by platform code to pass MXC_IPU_IRQ_START to ipu-core driver. We can save it by having ipu-core driver call irq_alloc_descs to get the irq_base. Signed-off-by: Shawn Guo Acked-by: Vinod Koul Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/devices-imx31.h | 4 ++-- arch/arm/mach-imx/devices-imx35.h | 4 ++-- arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c | 6 +----- arch/arm/mach-imx/mach-armadillo5x0.c | 6 +----- arch/arm/mach-imx/mach-mx31_3ds.c | 6 +----- arch/arm/mach-imx/mach-mx31moboard.c | 6 +----- arch/arm/mach-imx/mach-mx35_3ds.c | 10 +--------- arch/arm/mach-imx/mach-pcm037.c | 6 +----- arch/arm/mach-imx/mach-pcm043.c | 6 +----- arch/arm/mach-imx/mach-vpr200.c | 6 +----- arch/arm/mach-imx/mx31lilly-db.c | 6 +----- arch/arm/plat-mxc/devices/platform-ipu-core.c | 5 ++--- arch/arm/plat-mxc/include/mach/devices-common.h | 4 +--- arch/arm/plat-mxc/include/mach/ipu.h | 4 ---- drivers/dma/ipu/ipu_idmac.c | 8 +++----- drivers/dma/ipu/ipu_irq.c | 14 +++++++++----- 16 files changed, 28 insertions(+), 73 deletions(-) diff --git a/arch/arm/mach-imx/devices-imx31.h b/arch/arm/mach-imx/devices-imx31.h index 488e241a6db6..911c2dac2452 100644 --- a/arch/arm/mach-imx/devices-imx31.h +++ b/arch/arm/mach-imx/devices-imx31.h @@ -42,8 +42,8 @@ extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[]; #define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata) extern const struct imx_ipu_core_data imx31_ipu_core_data; -#define imx31_add_ipu_core(pdata) \ - imx_add_ipu_core(&imx31_ipu_core_data, pdata) +#define imx31_add_ipu_core() \ + imx_add_ipu_core(&imx31_ipu_core_data) #define imx31_alloc_mx3_camera(pdata) \ imx_alloc_mx3_camera(&imx31_ipu_core_data, pdata) #define imx31_add_mx3_sdc_fb(pdata) \ diff --git a/arch/arm/mach-imx/devices-imx35.h b/arch/arm/mach-imx/devices-imx35.h index 7b99ef0bb501..6fb907290f47 100644 --- a/arch/arm/mach-imx/devices-imx35.h +++ b/arch/arm/mach-imx/devices-imx35.h @@ -50,8 +50,8 @@ extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[]; #define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata) extern const struct imx_ipu_core_data imx35_ipu_core_data; -#define imx35_add_ipu_core(pdata) \ - imx_add_ipu_core(&imx35_ipu_core_data, pdata) +#define imx35_add_ipu_core() \ + imx_add_ipu_core(&imx35_ipu_core_data) #define imx35_alloc_mx3_camera(pdata) \ imx_alloc_mx3_camera(&imx35_ipu_core_data, pdata) #define imx35_add_mx3_sdc_fb(pdata) \ diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c index 557f6c486053..6e9dd12a6961 100644 --- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c @@ -95,10 +95,6 @@ static const struct fb_videomode fb_modedb[] = { }, }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct mx3fb_platform_data mx3fb_pdata __initdata = { .name = "CMO-QVGA", .mode = fb_modedb, @@ -287,7 +283,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void) printk(KERN_ERR "error setting mbimxsd pads !\n"); imx35_add_imx_uart1(&uart_pdata); - imx35_add_ipu_core(&mx3_ipu_data); + imx35_add_ipu_core(); imx35_add_mx3_sdc_fb(&mx3fb_pdata); imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index f83c5c683575..2c6ab3273f9e 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -367,10 +367,6 @@ static const struct fb_videomode fb_modedb[] = { }, }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct mx3fb_platform_data mx3fb_pdata __initdata = { .name = "CRT-VGA", .mode = fb_modedb, @@ -517,7 +513,7 @@ static void __init armadillo5x0_init(void) imx31_add_mxc_mmc(0, &sdhc_pdata); /* Register FB */ - imx31_add_ipu_core(&mx3_ipu_data); + imx31_add_ipu_core(); imx31_add_mx3_sdc_fb(&mx3fb_pdata); /* Register NOR Flash */ diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index ecdba0497e7e..618935e1e325 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -274,10 +274,6 @@ static const struct fb_videomode fb_modedb[] = { }, }; -static struct ipu_platform_data mx3_ipu_data = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct mx3fb_platform_data mx3fb_pdata __initdata = { .name = "Epson-VGA", .mode = fb_modedb, @@ -743,7 +739,7 @@ static void __init mx31_3ds_init(void) imx31_add_mxc_mmc(0, &sdhc1_pdata); imx31_add_spi_imx0(&spi0_pdata); - imx31_add_ipu_core(&mx3_ipu_data); + imx31_add_ipu_core(); imx31_add_mx3_sdc_fb(&mx3fb_pdata); /* CSI */ diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index f0d26db7719e..54d9e5d9fcec 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -473,10 +473,6 @@ static const struct gpio_led_platform_data mx31moboard_led_pdata __initconst = { .leds = mx31moboard_leds, }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct platform_device *devices[] __initdata = { &mx31moboard_flash, }; @@ -494,7 +490,7 @@ static int __init mx31moboard_init_cam(void) int dma, ret = -ENOMEM; struct platform_device *pdev; - imx31_add_ipu_core(&mx3_ipu_data); + imx31_add_ipu_core(); pdev = imx31_alloc_mx3_camera(&camera_pdata); if (IS_ERR(pdev)) diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index fa1ea74dfdd3..ad63e6ebee6d 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -80,10 +80,6 @@ static const struct fb_videomode fb_modedb[] = { }, }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct mx3fb_platform_data mx3fb_pdata __initdata = { .name = "Ceramate-CLAA070VC01", .mode = fb_modedb, @@ -297,10 +293,6 @@ err: return ret; } -static const struct ipu_platform_data mx35_3ds_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct i2c_board_info mx35_3ds_i2c_camera = { I2C_BOARD_INFO("ov2640", 0x30), }; @@ -596,7 +588,7 @@ static void __init mx35_3ds_init(void) i2c_register_board_info( 0, i2c_devices_3ds, ARRAY_SIZE(i2c_devices_3ds)); - imx35_add_ipu_core(&mx35_3ds_ipu_data); + imx35_add_ipu_core(); platform_device_register(&mx35_3ds_ov2640); imx35_3ds_init_camera(); diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index 551a035f0c2d..ded4ed9def9e 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c @@ -441,10 +441,6 @@ static struct platform_device *devices[] __initdata = { &pcm037_mt9v022, }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static const struct fb_videomode fb_modedb[] = { { /* 240x320 @ 60 Hz Sharp */ @@ -648,7 +644,7 @@ static void __init pcm037_init(void) imx31_add_mxc_nand(&pcm037_nand_board_info); imx31_add_mxc_mmc(0, &sdhc_pdata); - imx31_add_ipu_core(&mx3_ipu_data); + imx31_add_ipu_core(); imx31_add_mx3_sdc_fb(&mx3fb_pdata); /* CSI */ diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index 73585f55cca0..133908f94f7e 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c @@ -76,10 +76,6 @@ static const struct fb_videomode fb_modedb[] = { }, }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct mx3fb_platform_data mx3fb_pdata __initdata = { .name = "Sharp-LQ035Q7", .mode = fb_modedb, @@ -376,7 +372,7 @@ static void __init pcm043_init(void) imx35_add_imx_i2c0(&pcm043_i2c0_data); - imx35_add_ipu_core(&mx3_ipu_data); + imx35_add_ipu_core(); imx35_add_mx3_sdc_fb(&mx3fb_pdata); if (otg_mode_host) { diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c index e36eb2c40f41..1aa562285960 100644 --- a/arch/arm/mach-imx/mach-vpr200.c +++ b/arch/arm/mach-imx/mach-vpr200.c @@ -87,10 +87,6 @@ static const struct fb_videomode fb_modedb[] = { } }; -static const struct ipu_platform_data mx3_ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static struct mx3fb_platform_data mx3fb_pdata __initdata = { .name = "PT0708048", .mode = fb_modedb, @@ -290,7 +286,7 @@ static void __init vpr200_board_init(void) imx35_add_imx_uart0(NULL); imx35_add_imx_uart2(NULL); - imx35_add_ipu_core(&mx3_ipu_data); + imx35_add_ipu_core(); imx35_add_mx3_sdc_fb(&mx3fb_pdata); imx35_add_fsl_usb2_udc(&otg_device_pdata); diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c index 2df625bdc71e..29e890f92055 100644 --- a/arch/arm/mach-imx/mx31lilly-db.c +++ b/arch/arm/mach-imx/mx31lilly-db.c @@ -162,10 +162,6 @@ static const struct imxmmc_platform_data mmc_pdata __initconst = { }; /* Framebuffer support */ -static const struct ipu_platform_data ipu_data __initconst = { - .irq_base = MXC_IPU_IRQ_START, -}; - static const struct fb_videomode fb_modedb = { /* 640x480 TFT panel (IPS-056T) */ .name = "CRT-VGA", @@ -199,7 +195,7 @@ static void __init mx31lilly_init_fb(void) return; } - imx31_add_ipu_core(&ipu_data); + imx31_add_ipu_core(); imx31_add_mx3_sdc_fb(&fb_pdata); gpio_direction_output(LCD_VCC_EN_GPIO, 1); } diff --git a/arch/arm/plat-mxc/devices/platform-ipu-core.c b/arch/arm/plat-mxc/devices/platform-ipu-core.c index 79d340ae0af1..d1e33cc6f12e 100644 --- a/arch/arm/plat-mxc/devices/platform-ipu-core.c +++ b/arch/arm/plat-mxc/devices/platform-ipu-core.c @@ -30,8 +30,7 @@ const struct imx_ipu_core_data imx35_ipu_core_data __initconst = static struct platform_device *imx_ipu_coredev __initdata; struct platform_device *__init imx_add_ipu_core( - const struct imx_ipu_core_data *data, - const struct ipu_platform_data *pdata) + const struct imx_ipu_core_data *data) { /* The resource order is important! */ struct resource res[] = { @@ -55,7 +54,7 @@ struct platform_device *__init imx_add_ipu_core( }; return imx_ipu_coredev = imx_add_platform_device("ipu-core", -1, - res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); + res, ARRAY_SIZE(res), NULL, 0); } struct platform_device *__init imx_alloc_mx3_camera( diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index 1b2258daa05b..a7f5bb1084d7 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h @@ -183,7 +183,6 @@ struct platform_device *__init imx_add_imx_udc( const struct imx_imx_udc_data *data, const struct imxusb_platform_data *pdata); -#include #include #include struct imx_ipu_core_data { @@ -192,8 +191,7 @@ struct imx_ipu_core_data { resource_size_t errirq; }; struct platform_device *__init imx_add_ipu_core( - const struct imx_ipu_core_data *data, - const struct ipu_platform_data *pdata); + const struct imx_ipu_core_data *data); struct platform_device *__init imx_alloc_mx3_camera( const struct imx_ipu_core_data *data, const struct mx3_camera_pdata *pdata); diff --git a/arch/arm/plat-mxc/include/mach/ipu.h b/arch/arm/plat-mxc/include/mach/ipu.h index a9221f1cc1a0..539e559d18b2 100644 --- a/arch/arm/plat-mxc/include/mach/ipu.h +++ b/arch/arm/plat-mxc/include/mach/ipu.h @@ -110,10 +110,6 @@ enum ipu_rotate_mode { IPU_ROTATE_90_LEFT = 7, }; -struct ipu_platform_data { - unsigned int irq_base; -}; - /* * Enumeration of DI ports for ADC. */ diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 5ec72044ea4c..c7573e50aa14 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1663,7 +1663,6 @@ static void __exit ipu_idmac_exit(struct ipu *ipu) static int __init ipu_probe(struct platform_device *pdev) { - struct ipu_platform_data *pdata = pdev->dev.platform_data; struct resource *mem_ipu, *mem_ic; int ret; @@ -1671,7 +1670,7 @@ static int __init ipu_probe(struct platform_device *pdev) mem_ipu = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem_ic = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!pdata || !mem_ipu || !mem_ic) + if (!mem_ipu || !mem_ic) return -EINVAL; ipu_data.dev = &pdev->dev; @@ -1688,10 +1687,9 @@ static int __init ipu_probe(struct platform_device *pdev) goto err_noirq; ipu_data.irq_err = ret; - ipu_data.irq_base = pdata->irq_base; - dev_dbg(&pdev->dev, "fn irq %u, err irq %u, irq-base %u\n", - ipu_data.irq_fn, ipu_data.irq_err, ipu_data.irq_base); + dev_dbg(&pdev->dev, "fn irq %u, err irq %u\n", + ipu_data.irq_fn, ipu_data.irq_err); /* Remap IPU common registers */ ipu_data.reg_ipu = ioremap(mem_ipu->start, resource_size(mem_ipu)); diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c index a71f55e72be9..fa95bcc3de1f 100644 --- a/drivers/dma/ipu/ipu_irq.c +++ b/drivers/dma/ipu/ipu_irq.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -354,10 +355,12 @@ static struct irq_chip ipu_irq_chip = { /* Install the IRQ handler */ int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev) { - struct ipu_platform_data *pdata = dev->dev.platform_data; - unsigned int irq, irq_base, i; + unsigned int irq, i; + int irq_base = irq_alloc_descs(-1, 0, CONFIG_MX3_IPU_IRQS, + numa_node_id()); - irq_base = pdata->irq_base; + if (irq_base < 0) + return irq_base; for (i = 0; i < IPU_IRQ_NR_BANKS; i++) irq_bank[i].ipu = ipu; @@ -387,15 +390,16 @@ int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev) irq_set_handler_data(ipu->irq_err, ipu); irq_set_chained_handler(ipu->irq_err, ipu_irq_err); + ipu->irq_base = irq_base; + return 0; } void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev) { - struct ipu_platform_data *pdata = dev->dev.platform_data; unsigned int irq, irq_base; - irq_base = pdata->irq_base; + irq_base = ipu->irq_base; irq_set_chained_handler(ipu->irq_fn, NULL); irq_set_handler_data(ipu->irq_fn, NULL); -- GitLab From 1595f16c5e537cb33e118e7ae18dff139f22bdb1 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 15:12:24 +0800 Subject: [PATCH 3397/6849] ARM: imx: leave irq_base of wm8350_platform_data uninitialized With commit d1738ae (mfd: Allocate wm835x irq descs dynamically) being in the tree, there is no need to initialize irq_base field of struct wm8350_platform_data. Remove it to save one reference to macro MXC_BOARD_IRQ_START. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/mach-mx31ads.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 6f19f98ddbe9..a27a8543b9b5 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -479,7 +479,6 @@ static int mx31_wm8350_init(struct wm8350 *wm8350) static struct wm8350_platform_data __initdata mx31_wm8350_pdata = { .init = mx31_wm8350_init, - .irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES, }; #endif -- GitLab From ed4a7fb01a467f5d264fe12f17eb981f21c7bbcd Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 15:58:08 +0800 Subject: [PATCH 3398/6849] ARM: imx: pass gpio than irq number into mxc_expio_init Change mxc_expio_init interface a little bit to have gpio than irq number passed in. With the change, gpio_to_irq can be called inside mxc_expio_init to get irq number, so that MXC_IRQ_TO_GPIO can be removed. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/mach-mx27_3ds.c | 3 +-- arch/arm/mach-imx/mach-mx31_3ds.c | 3 +-- arch/arm/mach-imx/mach-mx35_3ds.c | 4 +--- arch/arm/mach-imx/mach-mx51_3ds.c | 3 +-- arch/arm/plat-mxc/3ds_debugboard.c | 8 ++++---- arch/arm/plat-mxc/include/mach/3ds_debugboard.h | 2 +- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index 18b9bcaa40e3..eeff0b6aaba3 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -48,7 +48,6 @@ #define SD1_EN_GPIO IMX_GPIO_NR(2, 25) #define OTG_PHY_RESET_GPIO IMX_GPIO_NR(2, 23) #define SPI2_SS0 IMX_GPIO_NR(4, 21) -#define EXPIO_PARENT_INT gpio_to_irq(IMX_GPIO_NR(3, 28)) #define PMIC_INT IMX_GPIO_NR(3, 14) #define SPI1_SS0 IMX_GPIO_NR(4, 28) #define SD1_CD IMX_GPIO_NR(2, 26) @@ -500,7 +499,7 @@ static void __init mx27pdk_init(void) spi_register_board_info(mx27_3ds_spi_devs, ARRAY_SIZE(mx27_3ds_spi_devs)); - if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT)) + if (mxc_expio_init(MX27_CS5_BASE_ADDR, IMX_GPIO_NR(3, 28))) pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n"); imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data); platform_add_devices(devices, ARRAY_SIZE(devices)); diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 618935e1e325..f37d9b5774ab 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -730,8 +730,7 @@ static void __init mx31_3ds_init(void) if (!otg_mode_host) imx31_add_fsl_usb2_udc(&usbotg_pdata); - if (mxc_expio_init(MX31_CS5_BASE_ADDR, - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)))) + if (mxc_expio_init(MX31_CS5_BASE_ADDR, IOMUX_TO_GPIO(MX31_PIN_GPIO1_1))) printk(KERN_WARNING "Init of the debug board failed, all " "devices on the debug board are unusable.\n"); imx31_add_imx2_wdt(NULL); diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index ad63e6ebee6d..596f237c0d0e 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -132,8 +132,6 @@ static struct platform_device mx35_3ds_lcd = { .dev.platform_data = &mx35_3ds_lcd_data, }; -#define EXPIO_PARENT_INT gpio_to_irq(IMX_GPIO_NR(1, 1)) - static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -580,7 +578,7 @@ static void __init mx35_3ds_init(void) imx35_add_mxc_nand(&mx35pdk_nand_board_info); imx35_add_sdhci_esdhc_imx(0, NULL); - if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT)) + if (mxc_expio_init(MX35_CS5_BASE_ADDR, IMX_GPIO_NR(1, 1))) pr_warn("Init of the debugboard failed, all " "devices on the debugboard are unusable.\n"); imx35_add_imx_i2c0(&mx35_3ds_i2c0_data); diff --git a/arch/arm/mach-imx/mach-mx51_3ds.c b/arch/arm/mach-imx/mach-mx51_3ds.c index 3c5b163923f6..ebb91882ae63 100644 --- a/arch/arm/mach-imx/mach-mx51_3ds.c +++ b/arch/arm/mach-imx/mach-mx51_3ds.c @@ -26,7 +26,6 @@ #include "devices-imx51.h" -#define EXPIO_PARENT_INT gpio_to_irq(IMX_GPIO_NR(1, 6)) #define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28) static iomux_v3_cfg_t mx51_3ds_pads[] = { @@ -148,7 +147,7 @@ static void __init mx51_3ds_init(void) spi_register_board_info(mx51_3ds_spi_nor_device, ARRAY_SIZE(mx51_3ds_spi_nor_device)); - if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT)) + if (mxc_expio_init(MX51_CS5_BASE_ADDR, IMX_GPIO_NR(1, 6))) printk(KERN_WARNING "Init of the debugboard failed, all " "devices on the board are unusable.\n"); diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c index 5cac2c540f4f..3b48a08c165a 100644 --- a/arch/arm/plat-mxc/3ds_debugboard.c +++ b/arch/arm/plat-mxc/3ds_debugboard.c @@ -49,7 +49,6 @@ #define MCU_BOARD_ID_REG 0x68 #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START) -#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_INTERNAL_IRQS) #define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) #define MXC_MAX_EXP_IO_LINES 16 @@ -155,8 +154,9 @@ static struct regulator_consumer_supply dummy_supplies[] = { REGULATOR_SUPPLY("vddvario", "smsc911x"), }; -int __init mxc_expio_init(u32 base, u32 p_irq) +int __init mxc_expio_init(u32 base, u32 intr_gpio) { + u32 p_irq = gpio_to_irq(intr_gpio); int i; brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K); @@ -178,8 +178,8 @@ int __init mxc_expio_init(u32 base, u32 p_irq) /* * Configure INT line as GPIO input */ - gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq"); - gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq)); + gpio_request(intr_gpio, "expio_pirq"); + gpio_direction_input(intr_gpio); /* disable the interrupt and clear the status */ __raw_writew(0, brd_io + INTR_MASK_REG); diff --git a/arch/arm/plat-mxc/include/mach/3ds_debugboard.h b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h index a384fdd49c62..9fd6cb3f8fad 100644 --- a/arch/arm/plat-mxc/include/mach/3ds_debugboard.h +++ b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h @@ -13,6 +13,6 @@ #ifndef __ASM_ARCH_MXC_3DS_DB_H__ #define __ASM_ARCH_MXC_3DS_DB_H__ -extern int __init mxc_expio_init(u32 base, u32 p_irq); +extern int __init mxc_expio_init(u32 base, u32 intr_gpio); #endif /* __ASM_ARCH_MXC_3DS_DB_H__ */ -- GitLab From ec7828807b14aab647a43c5b4ee2084de273c172 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 16:37:04 +0800 Subject: [PATCH 3399/6849] ARM: imx: add a legacy irqdomain for 3ds_debugboard Call irq_alloc_descs to get the irq_base for 3ds_debugboard, and add a legacy irqdomain using the irq_base, so that the mapping between 3ds_debugboard hardware irq and Linux irq number can be dynamically handled by irqdomain. As the result, the use of MXC_BOARD_IRQ_START can be completely removed from 3ds_debugboard.c. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/plat-mxc/3ds_debugboard.c | 42 ++++++++++++++++++------------ 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c index 3b48a08c165a..5c10ad05df74 100644 --- a/arch/arm/plat-mxc/3ds_debugboard.c +++ b/arch/arm/plat-mxc/3ds_debugboard.c @@ -12,9 +12,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -48,26 +50,22 @@ /* CPU ID and Personality ID */ #define MCU_BOARD_ID_REG 0x68 -#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START) - -#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) #define MXC_MAX_EXP_IO_LINES 16 /* interrupts like external uart , external ethernet etc*/ -#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0) -#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1) -#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2) -#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3) -#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4) +#define EXPIO_INT_ENET 0 +#define EXPIO_INT_XUART_A 1 +#define EXPIO_INT_XUART_B 2 +#define EXPIO_INT_BUTTON_A 3 +#define EXPIO_INT_BUTTON_B 4 static void __iomem *brd_io; +static struct irq_domain *domain; static struct resource smsc911x_resources[] = { { .flags = IORESOURCE_MEM, } , { - .start = EXPIO_INT_ENET, - .end = EXPIO_INT_ENET, .flags = IORESOURCE_IRQ, }, }; @@ -99,11 +97,11 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) imr_val = __raw_readw(brd_io + INTR_MASK_REG); int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; - expio_irq = MXC_BOARD_IRQ_START; + expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { if ((int_valid & 1) == 0) continue; - generic_handle_irq(expio_irq); + generic_handle_irq(irq_find_mapping(domain, expio_irq)); } desc->irq_data.chip->irq_ack(&desc->irq_data); @@ -117,7 +115,7 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) static void expio_mask_irq(struct irq_data *d) { u16 reg; - u32 expio = MXC_IRQ_TO_EXPIO(d->irq); + u32 expio = d->hwirq; reg = __raw_readw(brd_io + INTR_MASK_REG); reg |= (1 << expio); @@ -126,7 +124,7 @@ static void expio_mask_irq(struct irq_data *d) static void expio_ack_irq(struct irq_data *d) { - u32 expio = MXC_IRQ_TO_EXPIO(d->irq); + u32 expio = d->hwirq; __raw_writew(1 << expio, brd_io + INTR_RESET_REG); __raw_writew(0, brd_io + INTR_RESET_REG); @@ -136,7 +134,7 @@ static void expio_ack_irq(struct irq_data *d) static void expio_unmask_irq(struct irq_data *d) { u16 reg; - u32 expio = MXC_IRQ_TO_EXPIO(d->irq); + u32 expio = d->hwirq; reg = __raw_readw(brd_io + INTR_MASK_REG); reg &= ~(1 << expio); @@ -157,6 +155,7 @@ static struct regulator_consumer_supply dummy_supplies[] = { int __init mxc_expio_init(u32 base, u32 intr_gpio) { u32 p_irq = gpio_to_irq(intr_gpio); + int irq_base; int i; brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K); @@ -186,8 +185,15 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); __raw_writew(0, brd_io + INTR_RESET_REG); __raw_writew(0x1F, brd_io + INTR_MASK_REG); - for (i = MXC_EXP_IO_BASE; - i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) { + + irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); + WARN_ON(irq_base < 0); + + domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0, + &irq_domain_simple_ops, NULL); + WARN_ON(!domain); + + for (i = irq_base; i < irq_base + MXC_MAX_EXP_IO_LINES; i++) { irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID); } @@ -199,6 +205,8 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) smsc911x_resources[0].start = LAN9217_BASE_ADDR(base); smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1; + smsc911x_resources[1].start = irq_find_mapping(domain, EXPIO_INT_ENET); + smsc911x_resources[1].end = irq_find_mapping(domain, EXPIO_INT_ENET); platform_device_register(&smsc_lan9217_device); return 0; -- GitLab From 130d8bd7b67ddfcac52437821cf84a1087b19d4e Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Jun 2012 17:07:25 +0800 Subject: [PATCH 3400/6849] ARM: imx: add a legacy irqdomain for mx31ads Call irq_alloc_descs to get the irq_base for mx31ads, and add a legacy irqdomain using the irq_base, so that the mapping between mx31ads hardware irq and Linux irq number can be dynamically handled by irqdomain. As the result, the use of MXC_BOARD_IRQ_START can be completely removed from mach-mx31ads.c. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/mach-mx31ads.c | 48 +++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index a27a8543b9b5..d37f4809c556 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -63,18 +64,17 @@ #define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) -#define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START -#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) - -#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) -#define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11) +#define EXPIO_INT_XUART_INTA 10 +#define EXPIO_INT_XUART_INTB 11 #define MXC_MAX_EXP_IO_LINES 16 /* CS8900 */ -#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define EXPIO_INT_ENET_INT 8 #define CS4_CS8900_MMIO_START 0x20000 +static struct irq_domain *domain; + /* * The serial port definition structure. */ @@ -82,7 +82,6 @@ static struct plat_serial8250_port serial_platform_data[] = { { .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA), .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA), - .irq = EXPIO_INT_XUART_INTA, .uartclk = 14745600, .regshift = 0, .iotype = UPIO_MEM, @@ -90,7 +89,6 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB), .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB), - .irq = EXPIO_INT_XUART_INTB, .uartclk = 14745600, .regshift = 0, .iotype = UPIO_MEM, @@ -107,9 +105,9 @@ static struct platform_device serial_device = { }, }; -static const struct resource mx31ads_cs8900_resources[] __initconst = { +static struct resource mx31ads_cs8900_resources[] __initdata = { DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K), - DEFINE_RES_IRQ(EXPIO_INT_ENET_INT), + DEFINE_RES_IRQ(-1), }; static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { @@ -121,11 +119,19 @@ static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { static int __init mxc_init_extuart(void) { + serial_platform_data[0].irq = irq_find_mapping(domain, + EXPIO_INT_XUART_INTA); + serial_platform_data[1].irq = irq_find_mapping(domain, + EXPIO_INT_XUART_INTB); return platform_device_register(&serial_device); } static void __init mxc_init_ext_ethernet(void) { + mx31ads_cs8900_resources[1].start = + irq_find_mapping(domain, EXPIO_INT_ENET_INT); + mx31ads_cs8900_resources[1].end = + irq_find_mapping(domain, EXPIO_INT_ENET_INT); platform_device_register_full( (struct platform_device_info *)&mx31ads_cs8900_devinfo); } @@ -156,12 +162,12 @@ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) imr_val = __raw_readw(PBC_INTMASK_SET_REG); int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; - expio_irq = MXC_EXP_IO_BASE; + expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { if ((int_valid & 1) == 0) continue; - generic_handle_irq(expio_irq); + generic_handle_irq(irq_find_mapping(domain, expio_irq)); } } @@ -171,7 +177,7 @@ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) */ static void expio_mask_irq(struct irq_data *d) { - u32 expio = MXC_IRQ_TO_EXPIO(d->irq); + u32 expio = d->hwirq; /* mask the interrupt */ __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); __raw_readw(PBC_INTMASK_CLEAR_REG); @@ -183,7 +189,7 @@ static void expio_mask_irq(struct irq_data *d) */ static void expio_ack_irq(struct irq_data *d) { - u32 expio = MXC_IRQ_TO_EXPIO(d->irq); + u32 expio = d->hwirq; /* clear the interrupt status */ __raw_writew(1 << expio, PBC_INTSTATUS_REG); } @@ -194,7 +200,7 @@ static void expio_ack_irq(struct irq_data *d) */ static void expio_unmask_irq(struct irq_data *d) { - u32 expio = MXC_IRQ_TO_EXPIO(d->irq); + u32 expio = d->hwirq; /* unmask the interrupt */ __raw_writew(1 << expio, PBC_INTMASK_SET_REG); } @@ -208,6 +214,7 @@ static struct irq_chip expio_irq_chip = { static void __init mx31ads_init_expio(void) { + int irq_base; int i, irq; printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); @@ -220,8 +227,15 @@ static void __init mx31ads_init_expio(void) /* disable the interrupt and clear the status */ __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); __raw_writew(0xFFFF, PBC_INTSTATUS_REG); - for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); - i++) { + + irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); + WARN_ON(irq_base < 0); + + domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0, + &irq_domain_simple_ops, NULL); + WARN_ON(!domain); + + for (i = irq_base; i < irq_base + MXC_MAX_EXP_IO_LINES; i++) { irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID); } -- GitLab From 6387f8fcb6974499c3e179d3b0f369e62969300f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 14 Jun 2012 11:21:57 +0800 Subject: [PATCH 3401/6849] i2c: imx: remove unneeded mach/irqs.h inclusion Remove unneeded mach/irq.h inclusion from i2c-imx driver. Signed-off-by: Shawn Guo Cc: linux-i2c@vger.kernel.org Acked-by: Wolfram Sang Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- drivers/i2c/busses/i2c-imx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 8d6b504d65c4..370031ac8200 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -53,7 +53,6 @@ #include #include -#include #include #include -- GitLab From 69fcbc74bb7a8b3c86e15f27b74ee512633ffcc6 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 14 Jun 2012 11:26:46 +0800 Subject: [PATCH 3402/6849] ARM: imx: remove unneeded mach/irq.h inclusion Remove unneeded mach/irq.h inclusion from imx platform code. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer Acked-by: Dong Aisheng --- arch/arm/mach-imx/mach-apf9328.c | 1 - arch/arm/mach-imx/mach-mx1ads.c | 1 - arch/arm/mach-imx/mach-mx27_3ds.c | 1 - arch/arm/mach-imx/mach-mx31lite.c | 1 - arch/arm/mach-imx/mach-mx35_3ds.c | 1 - arch/arm/mach-imx/mach-pca100.c | 1 - arch/arm/mach-imx/mach-qong.c | 1 - arch/arm/mach-imx/mach-scb9328.c | 1 - arch/arm/mach-imx/mach-vpr200.c | 1 - arch/arm/mach-imx/mm-imx1.c | 1 - arch/arm/mach-imx/mm-imx21.c | 1 - arch/arm/mach-imx/mm-imx25.c | 1 - arch/arm/mach-imx/mm-imx27.c | 1 - arch/arm/mach-imx/mm-imx3.c | 1 - 14 files changed, 14 deletions(-) diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c index 5062fcb88498..7b99a79722b6 100644 --- a/arch/arm/mach-imx/mach-apf9328.c +++ b/arch/arm/mach-imx/mach-apf9328.c @@ -27,7 +27,6 @@ #include #include -#include #include #include "devices-imx1.h" diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c index 7274e7928136..667f359a2e8b 100644 --- a/arch/arm/mach-imx/mach-mx1ads.c +++ b/arch/arm/mach-imx/mach-mx1ads.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "devices-imx1.h" diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index eeff0b6aaba3..71f7c58ee4b6 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include "devices-imx27.h" diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index 4977378d2f60..c8785b39eaed 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include "devices-imx31.h" diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index 596f237c0d0e..e78525405c98 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include - + diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index e3d5afcdafbb..0a4b90fcf2da 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml @@ -284,13 +284,6 @@ These controls are described in . - - V4L2_CTRL_CLASS_JPEG - 0x9d0000 - The class containing JPEG compression controls. -These controls are described in . - -- GitLab From 88cde8b78f6914ce542949e5a8dd9031e3035996 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 6 Jul 2012 20:03:37 +0800 Subject: [PATCH 4172/6849] ARM: dts: imx: update #interrupt-cells for gpio nodes Change the value of #interrupt-cells of gpio nodes from 1 to 2, so that the gpio irq type can be specified in device tree. Also update binding document to make it clear. Reported-by: Sascha Hauer Acked-by: Sascha Hauer Signed-off-by: Shawn Guo --- .../devicetree/bindings/gpio/fsl-imx-gpio.txt | 9 +++++++++ arch/arm/boot/dts/imx27.dtsi | 12 ++++++------ arch/arm/boot/dts/imx51.dtsi | 8 ++++---- arch/arm/boot/dts/imx53.dtsi | 14 +++++++------- arch/arm/boot/dts/imx6q.dtsi | 14 +++++++------- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt index 5f360e7cdd32..4f3929713ae4 100644 --- a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt @@ -11,6 +11,13 @@ Required properties: the second cell is used to specify the gpio polarity: 0 = active high 1 = active low +- interrupt-controller: Marks the device node as an interrupt controller. +- #interrupt-cells : Should be 2. The first cell is the GPIO number. + The second cell bits[3:0] is used to specify trigger type and level flags: + 1 = low-to-high edge triggered. + 2 = high-to-low edge triggered. + 4 = active high level-sensitive. + 8 = active low level-sensitive. Example: @@ -20,4 +27,6 @@ gpio0: gpio@73f84000 { interrupts = <50 51>; gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; }; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 386c769c38d1..00bae3aad5ab 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -121,7 +121,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@10015100 { @@ -131,7 +131,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@10015200 { @@ -141,7 +141,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@10015300 { @@ -151,7 +151,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio5: gpio@10015400 { @@ -161,7 +161,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@10015500 { @@ -171,7 +171,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; cspi3: cspi@10017000 { diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index bfa65abe8ef2..922adefdd291 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -133,7 +133,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@73f88000 { @@ -143,7 +143,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@73f8c000 { @@ -153,7 +153,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@73f90000 { @@ -163,7 +163,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; wdog@73f98000 { /* WDOG1 */ diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index e3e869470cd3..4e735edc78ed 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -135,7 +135,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@53f88000 { @@ -145,7 +145,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@53f8c000 { @@ -155,7 +155,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@53f90000 { @@ -165,7 +165,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; wdog@53f98000 { /* WDOG1 */ @@ -203,7 +203,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@53fe0000 { @@ -213,7 +213,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio7: gpio@53fe4000 { @@ -223,7 +223,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; i2c@53fec000 { /* I2C3 */ diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 16a3884ac9d7..bf88fb77526a 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -283,7 +283,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@020a0000 { @@ -293,7 +293,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@020a4000 { @@ -303,7 +303,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@020a8000 { @@ -313,7 +313,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio5: gpio@020ac000 { @@ -323,7 +323,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@020b0000 { @@ -333,7 +333,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio7: gpio@020b4000 { @@ -343,7 +343,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; kpp@020b8000 { -- GitLab From c540521bba5d2f24bd2c0417157bfaf8b85e2eee Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Jul 2012 11:23:24 -0700 Subject: [PATCH 4173/6849] security: Minor improvements to no_new_privs documentation The documentation didn't actually mention how to enable no_new_privs. This also adds a note about possible interactions between no_new_privs and LSMs (i.e. why teaching systemd to set no_new_privs is not necessarily a good idea), and it references the new docs from include/linux/prctl.h. Suggested-by: Rob Landley Signed-off-by: Andy Lutomirski Acked-by: Kees Cook Signed-off-by: James Morris --- Documentation/prctl/no_new_privs.txt | 7 +++++++ include/linux/prctl.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/Documentation/prctl/no_new_privs.txt b/Documentation/prctl/no_new_privs.txt index cb705ec69abe..f7be84fba910 100644 --- a/Documentation/prctl/no_new_privs.txt +++ b/Documentation/prctl/no_new_privs.txt @@ -25,6 +25,13 @@ bits will no longer change the uid or gid; file capabilities will not add to the permitted set, and LSMs will not relax constraints after execve. +To set no_new_privs, use prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0). + +Be careful, though: LSMs might also not tighten constraints on exec +in no_new_privs mode. (This means that setting up a general-purpose +service launcher to set no_new_privs before execing daemons may +interfere with LSM-based sandboxing.) + Note that no_new_privs does not prevent privilege changes that do not involve execve. An appropriately privileged task can still call setuid(2) and receive SCM_RIGHTS datagrams. diff --git a/include/linux/prctl.h b/include/linux/prctl.h index 3988012255dc..289760f424aa 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h @@ -141,6 +141,8 @@ * Changing LSM security domain is considered a new privilege. So, for example, * asking selinux for a specific new context (e.g. with runcon) will result * in execve returning -EPERM. + * + * See Documentation/prctl/no_new_privs.txt for more details. */ #define PR_SET_NO_NEW_PRIVS 38 #define PR_GET_NO_NEW_PRIVS 39 -- GitLab From c866ffc72541296b8d31c109fbdb69643d2d18a6 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 1 Jul 2012 00:47:41 +0200 Subject: [PATCH 4174/6849] iio staging: missing newline in printf Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- drivers/staging/iio/Documentation/iio_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 5244fa0dfd2f..cf32ae099cd6 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -453,7 +453,7 @@ inline int find_type_by_name(const char *name, const char *type) dp = opendir(iio_dir); if (dp == NULL) { - printf("No industrialio devices available"); + printf("No industrialio devices available\n"); return -ENODEV; } -- GitLab From 3bdff937827da04b487f0a0ac6e1f3a9a1296878 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 1 Jul 2012 00:47:43 +0200 Subject: [PATCH 4175/6849] iio: cleanup buffer.h comments Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index ad4fb1af0f7d..2a2b6b4d8d05 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -85,7 +85,7 @@ struct iio_buffer { /** * iio_buffer_init() - Initialize the buffer structure - * @buffer: buffer to be initialized + * @buffer: buffer to be initialized **/ void iio_buffer_init(struct iio_buffer *buffer); @@ -107,8 +107,9 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, /** * iio_scan_mask_set() - set particular bit in the scan mask - * @buffer: the buffer whose scan mask we are interested in - * @bit: the bit to be set. + * @indio_dev IIO device structure + * @buffer: the buffer whose scan mask we are interested in + * @bit: the bit to be set. **/ int iio_scan_mask_set(struct iio_dev *indio_dev, struct iio_buffer *buffer, int bit); @@ -116,8 +117,8 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, /** * iio_push_to_buffer() - push to a registered buffer. * @buffer: IIO buffer structure for device - * @scan: Full scan. - * @timestamp: + * @data: the data to push to the buffer + * @timestamp: timestamp to associate with the data */ int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, s64 timestamp); @@ -126,7 +127,9 @@ int iio_update_demux(struct iio_dev *indio_dev); /** * iio_buffer_register() - register the buffer with IIO core - * @indio_dev: device with the buffer to be registered + * @indio_dev: device with the buffer to be registered + * @channels: the channel descriptions used to construct buffer + * @num_channels: the number of channels **/ int iio_buffer_register(struct iio_dev *indio_dev, const struct iio_chan_spec *channels, @@ -134,7 +137,7 @@ int iio_buffer_register(struct iio_dev *indio_dev, /** * iio_buffer_unregister() - unregister the buffer from IIO core - * @indio_dev: the device with the buffer to be unregistered + * @indio_dev: the device with the buffer to be unregistered **/ void iio_buffer_unregister(struct iio_dev *indio_dev); -- GitLab From 034bd7b5d926816285deb71c41a230b912524f8b Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 2 Jul 2012 23:43:47 +0200 Subject: [PATCH 4176/6849] iio: fix spelling of detach in static func Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-trigger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index ec653fb51d0b..2ef36d15ccc5 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -234,7 +234,7 @@ static int iio_trigger_attach_poll_func(struct iio_trigger *trig, return ret; } -static int iio_trigger_dettach_poll_func(struct iio_trigger *trig, +static int iio_trigger_detach_poll_func(struct iio_trigger *trig, struct iio_poll_func *pf) { int ret = 0; @@ -502,7 +502,7 @@ EXPORT_SYMBOL(iio_triggered_buffer_postenable); int iio_triggered_buffer_predisable(struct iio_dev *indio_dev) { - return iio_trigger_dettach_poll_func(indio_dev->trig, + return iio_trigger_detach_poll_func(indio_dev->trig, indio_dev->pollfunc); } EXPORT_SYMBOL(iio_triggered_buffer_predisable); -- GitLab From 476a7eeb60e70ddab138e7cb4bc44ef5ac20782e Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Sat, 7 Jul 2012 13:37:42 +0300 Subject: [PATCH 4177/6849] hwspinlock/core: use global ID to register hwspinlocks on multiple devices Commit 300bab9770 (hwspinlock/core: register a bank of hwspinlocks in a single API call, 2011-09-06) introduced 'hwspin_lock_register_single()' to register numerous (a bank of) hwspinlock instances in a single API, 'hwspin_lock_register()'. At which time, 'hwspin_lock_register()' accidentally passes 'local IDs' to 'hwspin_lock_register_single()', despite that ..._single() requires 'global IDs' to register hwspinlocks. We have to convert into global IDs by supplying the missing 'base_id'. Cc: stable Signed-off-by: Shinya Kuribayashi [ohad: fix error path of hwspin_lock_register, too] Signed-off-by: Ohad Ben-Cohen --- drivers/hwspinlock/hwspinlock_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 61c9cf15fa52..1201a15784c3 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -345,7 +345,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, spin_lock_init(&hwlock->lock); hwlock->bank = bank; - ret = hwspin_lock_register_single(hwlock, i); + ret = hwspin_lock_register_single(hwlock, base_id + i); if (ret) goto reg_failed; } @@ -354,7 +354,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, reg_failed: while (--i >= 0) - hwspin_lock_unregister_single(i); + hwspin_lock_unregister_single(base_id + i); return ret; } EXPORT_SYMBOL_GPL(hwspin_lock_register); -- GitLab From 2f7916f8d6761e039a117ff560a85a20edb796de Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 7 Jul 2012 15:13:08 +0200 Subject: [PATCH 4178/6849] mac80211: request TX status for BlockAck Requests Because ieee80211_tx_status in status.c checks if outgoing BlockAck requests have been acked, it is necessary to tell the driver that tx feedback for this sort of frame is important. Otherwise, the stack will continue to send the same BlockAck request over and over, which can cause the receiver to flush or clean its reorder buffer over and over. Signed-off-by: Christian Lamparter Signed-off-by: Johannes Berg --- net/mac80211/agg-tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 5cc1bf7d8033..d0deb3edae21 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -135,7 +135,8 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) bar->control = cpu_to_le16(bar_control); bar->start_seq_num = cpu_to_le16(ssn); - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | + IEEE80211_TX_CTL_REQ_TX_STATUS; ieee80211_tx_skb_tid(sdata, skb, tid); } EXPORT_SYMBOL(ieee80211_send_bar); -- GitLab From d1e09ebf426ff34b4b6bbd6212b820edeb992bd4 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sat, 7 Jul 2012 15:13:47 -0700 Subject: [PATCH 4179/6849] RDMA/ocrdma: Fix assignment of max_srq_sge in device query We want to set attr->max_srq_sge to dev->attr.max_srq_sge, not to itself. This was detected by Coverity (CID 709210). Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 2e2e7aecc990..b2f9784beb4a 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_srq_sge; + attr->max_srq_sge = dev->attr.max_srq_sge; attr->max_srq_wr = dev->attr.max_rqe; attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = 0; -- GitLab From 7db5b3ca0ecdb2e8fad52a4770e4e320e61c77a6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 7 Jul 2012 15:55:47 -0700 Subject: [PATCH 4180/6849] Revert "cgroup: superblock can't be released with active dentries" This reverts commit fa980ca87d15bb8a1317853f257a505990f3ffde. The commit was an attempt to fix a race condition where a cgroup hierarchy may be unmounted with positive dentry reference on root cgroup. While the commit made the race condition slightly more difficult to trigger, the race was still there and could be reliably triggered using a different test case. Revert the incorrect fix. The next commit will describe the race and fix it correctly. Signed-off-by: Tejun Heo LKML-Reference: <4FEEA5CB.8070809@huawei.com> Reported-by: shyju pv Cc: Sasha Levin Acked-by: Li Zefan --- kernel/cgroup.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 2097684cf194..5f134a0e0e3f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -901,13 +901,10 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) mutex_unlock(&cgroup_mutex); /* - * We want to drop the active superblock reference from the - * cgroup creation after all the dentry refs are gone - - * kill_sb gets mighty unhappy otherwise. Mark - * dentry->d_fsdata with cgroup_diput() to tell - * cgroup_d_release() to call deactivate_super(). + * Drop the active superblock reference that we took when we + * created the cgroup */ - dentry->d_fsdata = cgroup_diput; + deactivate_super(cgrp->root->sb); /* * if we're getting rid of the cgroup, refcount should ensure @@ -933,13 +930,6 @@ static int cgroup_delete(const struct dentry *d) return 1; } -static void cgroup_d_release(struct dentry *dentry) -{ - /* did cgroup_diput() tell me to deactivate super? */ - if (dentry->d_fsdata == cgroup_diput) - deactivate_super(dentry->d_sb); -} - static void remove_dir(struct dentry *d) { struct dentry *parent = dget(d->d_parent); @@ -1547,7 +1537,6 @@ static int cgroup_get_rootdir(struct super_block *sb) static const struct dentry_operations cgroup_dops = { .d_iput = cgroup_diput, .d_delete = cgroup_delete, - .d_release = cgroup_d_release, }; struct inode *inode = -- GitLab From 5db9a4d99b0157a513944e9a44d29c9cec2e91dc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 7 Jul 2012 16:08:18 -0700 Subject: [PATCH 4181/6849] cgroup: fix cgroup hierarchy umount race 48ddbe1946 "cgroup: make css->refcnt clearing on cgroup removal optional" allowed a css to linger after the associated cgroup is removed. As a css holds a reference on the cgroup's dentry, it means that cgroup dentries may linger for a while. Destroying a superblock which has dentries with positive refcnts is a critical bug and triggers BUG() in vfs code. As each cgroup dentry holds an s_active reference, any lingering cgroup has both its dentry and the superblock pinned and thus preventing premature release of superblock. Unfortunately, after 48ddbe1946, there's a small window while releasing a cgroup which is directly under the root of the hierarchy. When a cgroup directory is released, vfs layer first deletes the corresponding dentry and then invokes dput() on the parent, which may recurse further, so when a cgroup directly below root cgroup is released, the cgroup is first destroyed - which releases the s_active it was holding - and then the dentry for the root cgroup is dput(). This creates a window where the root dentry's refcnt isn't zero but superblock's s_active is. If umount happens before or during this window, vfs will see the root dentry with non-zero refcnt and trigger BUG(). Before 48ddbe1946, this problem didn't exist because the last dentry reference was guaranteed to be put synchronously from rmdir(2) invocation which holds s_active around the whole process. Fix it by holding an extra superblock->s_active reference across dput() from css release, which is the dput() path added by 48ddbe1946 and the only one which doesn't hold an extra s_active ref across the final cgroup dput(). Signed-off-by: Tejun Heo LKML-Reference: <4FEEA5CB.8070809@huawei.com> Reported-by: shyju pv Tested-by: shyju pv Cc: Sasha Levin Acked-by: Li Zefan --- kernel/cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 5f134a0e0e3f..b303dfc7dce0 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -3883,8 +3883,12 @@ static void css_dput_fn(struct work_struct *work) { struct cgroup_subsys_state *css = container_of(work, struct cgroup_subsys_state, dput_work); + struct dentry *dentry = css->cgroup->dentry; + struct super_block *sb = dentry->d_sb; - dput(css->cgroup->dentry); + atomic_inc(&sb->s_active); + dput(dentry); + deactivate_super(sb); } static void init_cgroup_css(struct cgroup_subsys_state *css, -- GitLab From 8ce5c9f27d2e2ce415d903d916e848a356d4c0c0 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 6 Jul 2012 20:07:35 +0000 Subject: [PATCH 4182/6849] r6040: remove duplicate call to the pci_set_drvdata pci_set_drvdata is called twice at the remove path of driver, call it once. Signed-off-by: Devendra Naga Signed-off-by: David S. Miller --- drivers/net/ethernet/rdc/r6040.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index d1827e887f4e..9acc026f62e8 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1256,7 +1256,6 @@ static void __devexit r6040_remove_one(struct pci_dev *pdev) kfree(lp->mii_bus->irq); mdiobus_free(lp->mii_bus); netif_napi_del(&lp->napi); - pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, lp->base); pci_release_regions(pdev); free_netdev(dev); -- GitLab From 4af1c0488da97293c09d37ca49543566406073e6 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:41 +0000 Subject: [PATCH 4183/6849] net/mlx4_core: Change resource tracking mechanism to use red-black tree Change the data structure used for managing the SRIOV resource tracking mechanism from radix tree to red-black tree. This is preparation step for supporting resource IDs which are 64bit long, such as network flow steering rules. Such IDs can't be used as radix-tree keys on 32bit architectures and hence the reason for the change. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 3 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 106 +++++++++++++----- 2 files changed, 77 insertions(+), 32 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index e5d20220762c..1a2f37285ef5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -509,7 +510,7 @@ struct slave_list { struct mlx4_resource_tracker { spinlock_t lock; /* tree for each resources */ - struct radix_tree_root res_tree[MLX4_NUM_OF_RESOURCE_TYPE]; + struct rb_root res_tree[MLX4_NUM_OF_RESOURCE_TYPE]; /* num_of_slave's lists, one per slave */ struct slave_list *slave_list; }; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 766b8c5a235e..80c03c802301 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -57,6 +57,7 @@ struct mac_res { struct res_common { struct list_head list; + struct rb_node node; u32 res_id; int owner; int state; @@ -189,6 +190,49 @@ struct res_xrcdn { int port; }; +static void *res_tracker_lookup(struct rb_root *root, u64 res_id) +{ + struct rb_node *node = root->rb_node; + + while (node) { + struct res_common *res = container_of(node, struct res_common, + node); + + if (res_id < res->res_id) + node = node->rb_left; + else if (res_id > res->res_id) + node = node->rb_right; + else + return res; + } + return NULL; +} + +static int res_tracker_insert(struct rb_root *root, struct res_common *res) +{ + struct rb_node **new = &(root->rb_node), *parent = NULL; + + /* Figure out where to put new node */ + while (*new) { + struct res_common *this = container_of(*new, struct res_common, + node); + + parent = *new; + if (res->res_id < this->res_id) + new = &((*new)->rb_left); + else if (res->res_id > this->res_id) + new = &((*new)->rb_right); + else + return -EEXIST; + } + + /* Add new node and rebalance tree. */ + rb_link_node(&res->node, parent, new); + rb_insert_color(&res->node, root); + + return 0; +} + /* For Debug uses */ static const char *ResourceType(enum mlx4_resource rt) { @@ -228,8 +272,7 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) mlx4_dbg(dev, "Started init_resource_tracker: %ld slaves\n", dev->num_slaves); for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) - INIT_RADIX_TREE(&priv->mfunc.master.res_tracker.res_tree[i], - GFP_ATOMIC|__GFP_NOWARN); + priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT; spin_lock_init(&priv->mfunc.master.res_tracker.lock); return 0 ; @@ -277,8 +320,8 @@ static void *find_res(struct mlx4_dev *dev, int res_id, { struct mlx4_priv *priv = mlx4_priv(dev); - return radix_tree_lookup(&priv->mfunc.master.res_tracker.res_tree[type], - res_id); + return res_tracker_lookup(&priv->mfunc.master.res_tracker.res_tree[type], + res_id); } static int get_res(struct mlx4_dev *dev, int slave, int res_id, @@ -523,7 +566,7 @@ static int add_res_range(struct mlx4_dev *dev, int slave, int base, int count, struct mlx4_priv *priv = mlx4_priv(dev); struct res_common **res_arr; struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; - struct radix_tree_root *root = &tracker->res_tree[type]; + struct rb_root *root = &tracker->res_tree[type]; res_arr = kzalloc(count * sizeof *res_arr, GFP_KERNEL); if (!res_arr) @@ -546,7 +589,7 @@ static int add_res_range(struct mlx4_dev *dev, int slave, int base, int count, err = -EEXIST; goto undo; } - err = radix_tree_insert(root, base + i, res_arr[i]); + err = res_tracker_insert(root, res_arr[i]); if (err) goto undo; list_add_tail(&res_arr[i]->list, @@ -559,7 +602,7 @@ static int add_res_range(struct mlx4_dev *dev, int slave, int base, int count, undo: for (--i; i >= base; --i) - radix_tree_delete(&tracker->res_tree[type], i); + rb_erase(&res_arr[i]->node, root); spin_unlock_irq(mlx4_tlock(dev)); @@ -695,7 +738,7 @@ static int rem_res_range(struct mlx4_dev *dev, int slave, int base, int count, spin_lock_irq(mlx4_tlock(dev)); for (i = base; i < base + count; ++i) { - r = radix_tree_lookup(&tracker->res_tree[type], i); + r = res_tracker_lookup(&tracker->res_tree[type], i); if (!r) { err = -ENOENT; goto out; @@ -710,8 +753,8 @@ static int rem_res_range(struct mlx4_dev *dev, int slave, int base, int count, } for (i = base; i < base + count; ++i) { - r = radix_tree_lookup(&tracker->res_tree[type], i); - radix_tree_delete(&tracker->res_tree[type], i); + r = res_tracker_lookup(&tracker->res_tree[type], i); + rb_erase(&r->node, &tracker->res_tree[type]); list_del(&r->list); kfree(r); } @@ -733,7 +776,7 @@ static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn, int err = 0; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[RES_QP], qpn); + r = res_tracker_lookup(&tracker->res_tree[RES_QP], qpn); if (!r) err = -ENOENT; else if (r->com.owner != slave) @@ -797,7 +840,7 @@ static int mr_res_start_move_to(struct mlx4_dev *dev, int slave, int index, int err = 0; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[RES_MPT], index); + r = res_tracker_lookup(&tracker->res_tree[RES_MPT], index); if (!r) err = -ENOENT; else if (r->com.owner != slave) @@ -850,7 +893,7 @@ static int eq_res_start_move_to(struct mlx4_dev *dev, int slave, int index, int err = 0; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[RES_EQ], index); + r = res_tracker_lookup(&tracker->res_tree[RES_EQ], index); if (!r) err = -ENOENT; else if (r->com.owner != slave) @@ -898,7 +941,7 @@ static int cq_res_start_move_to(struct mlx4_dev *dev, int slave, int cqn, int err; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[RES_CQ], cqn); + r = res_tracker_lookup(&tracker->res_tree[RES_CQ], cqn); if (!r) err = -ENOENT; else if (r->com.owner != slave) @@ -952,7 +995,7 @@ static int srq_res_start_move_to(struct mlx4_dev *dev, int slave, int index, int err = 0; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[RES_SRQ], index); + r = res_tracker_lookup(&tracker->res_tree[RES_SRQ], index); if (!r) err = -ENOENT; else if (r->com.owner != slave) @@ -1001,7 +1044,7 @@ static void res_abort_move(struct mlx4_dev *dev, int slave, struct res_common *r; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[type], id); + r = res_tracker_lookup(&tracker->res_tree[type], id); if (r && (r->owner == slave)) r->state = r->from_state; spin_unlock_irq(mlx4_tlock(dev)); @@ -1015,7 +1058,7 @@ static void res_end_move(struct mlx4_dev *dev, int slave, struct res_common *r; spin_lock_irq(mlx4_tlock(dev)); - r = radix_tree_lookup(&tracker->res_tree[type], id); + r = res_tracker_lookup(&tracker->res_tree[type], id); if (r && (r->owner == slave)) r->state = r->to_state; spin_unlock_irq(mlx4_tlock(dev)); @@ -2817,8 +2860,8 @@ static void rem_slave_qps(struct mlx4_dev *dev, int slave) switch (state) { case RES_QP_RESERVED: spin_lock_irq(mlx4_tlock(dev)); - radix_tree_delete(&tracker->res_tree[RES_QP], - qp->com.res_id); + rb_erase(&qp->com.node, + &tracker->res_tree[RES_QP]); list_del(&qp->com.list); spin_unlock_irq(mlx4_tlock(dev)); kfree(qp); @@ -2888,8 +2931,8 @@ static void rem_slave_srqs(struct mlx4_dev *dev, int slave) case RES_SRQ_ALLOCATED: __mlx4_srq_free_icm(dev, srqn); spin_lock_irq(mlx4_tlock(dev)); - radix_tree_delete(&tracker->res_tree[RES_SRQ], - srqn); + rb_erase(&srq->com.node, + &tracker->res_tree[RES_SRQ]); list_del(&srq->com.list); spin_unlock_irq(mlx4_tlock(dev)); kfree(srq); @@ -2954,8 +2997,8 @@ static void rem_slave_cqs(struct mlx4_dev *dev, int slave) case RES_CQ_ALLOCATED: __mlx4_cq_free_icm(dev, cqn); spin_lock_irq(mlx4_tlock(dev)); - radix_tree_delete(&tracker->res_tree[RES_CQ], - cqn); + rb_erase(&cq->com.node, + &tracker->res_tree[RES_CQ]); list_del(&cq->com.list); spin_unlock_irq(mlx4_tlock(dev)); kfree(cq); @@ -3017,8 +3060,8 @@ static void rem_slave_mrs(struct mlx4_dev *dev, int slave) case RES_MPT_RESERVED: __mlx4_mr_release(dev, mpt->key); spin_lock_irq(mlx4_tlock(dev)); - radix_tree_delete(&tracker->res_tree[RES_MPT], - mptn); + rb_erase(&mpt->com.node, + &tracker->res_tree[RES_MPT]); list_del(&mpt->com.list); spin_unlock_irq(mlx4_tlock(dev)); kfree(mpt); @@ -3086,8 +3129,8 @@ static void rem_slave_mtts(struct mlx4_dev *dev, int slave) __mlx4_free_mtt_range(dev, base, mtt->order); spin_lock_irq(mlx4_tlock(dev)); - radix_tree_delete(&tracker->res_tree[RES_MTT], - base); + rb_erase(&mtt->com.node, + &tracker->res_tree[RES_MTT]); list_del(&mtt->com.list); spin_unlock_irq(mlx4_tlock(dev)); kfree(mtt); @@ -3133,8 +3176,8 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave) switch (state) { case RES_EQ_RESERVED: spin_lock_irq(mlx4_tlock(dev)); - radix_tree_delete(&tracker->res_tree[RES_EQ], - eqn); + rb_erase(&eq->com.node, + &tracker->res_tree[RES_EQ]); list_del(&eq->com.list); spin_unlock_irq(mlx4_tlock(dev)); kfree(eq); @@ -3191,7 +3234,8 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave) list_for_each_entry_safe(counter, tmp, counter_list, com.list) { if (counter->com.owner == slave) { index = counter->com.res_id; - radix_tree_delete(&tracker->res_tree[RES_COUNTER], index); + rb_erase(&counter->com.node, + &tracker->res_tree[RES_COUNTER]); list_del(&counter->com.list); kfree(counter); __mlx4_counter_free(dev, index); @@ -3220,7 +3264,7 @@ static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave) list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) { if (xrcd->com.owner == slave) { xrcdn = xrcd->com.res_id; - radix_tree_delete(&tracker->res_tree[RES_XRCD], xrcdn); + rb_erase(&xrcd->com.node, &tracker->res_tree[RES_XRCD]); list_del(&xrcd->com.list); kfree(xrcd); __mlx4_xrcd_free(dev, xrcdn); -- GitLab From aa1ec3dde1d818dcc94e307e25df98242aff5538 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:42 +0000 Subject: [PATCH 4184/6849] net/mlx4_core: Change resource tracking ID to be 64 bit Currently the IDs used by the resource tracker are of type u32, so far this was ok since all the different resources we were tracking could be encoded in 32bit. As a preparation step for tracking of resources whose IDs need > 32 bits such as network flow steering rules, who are 64 bit in size, move to use 64 bit based resource IDs. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1a2f37285ef5..a425a984758f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -1033,7 +1033,7 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port); /* resource tracker functions*/ int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, enum mlx4_resource resource_type, - int resource_id, int *slave); + u64 resource_id, int *slave); void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); int mlx4_init_resource_tracker(struct mlx4_dev *dev); diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 80c03c802301..6bdac2955f8b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -58,7 +58,7 @@ struct mac_res { struct res_common { struct list_head list; struct rb_node node; - u32 res_id; + u64 res_id; int owner; int state; int from_state; @@ -324,7 +324,7 @@ static void *find_res(struct mlx4_dev *dev, int res_id, res_id); } -static int get_res(struct mlx4_dev *dev, int slave, int res_id, +static int get_res(struct mlx4_dev *dev, int slave, u64 res_id, enum mlx4_resource type, void *res) { @@ -350,7 +350,7 @@ static int get_res(struct mlx4_dev *dev, int slave, int res_id, r->from_state = r->state; r->state = RES_ANY_BUSY; - mlx4_dbg(dev, "res %s id 0x%x to busy\n", + mlx4_dbg(dev, "res %s id 0x%llx to busy\n", ResourceType(type), r->res_id); if (res) @@ -363,7 +363,7 @@ exit: int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, enum mlx4_resource type, - int res_id, int *slave) + u64 res_id, int *slave) { struct res_common *r; @@ -384,7 +384,7 @@ int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, return err; } -static void put_res(struct mlx4_dev *dev, int slave, int res_id, +static void put_res(struct mlx4_dev *dev, int slave, u64 res_id, enum mlx4_resource type) { struct res_common *r; @@ -516,7 +516,7 @@ static struct res_common *alloc_xrcdn_tr(int id) return &ret->com; } -static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave, +static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave, int extra) { struct res_common *ret; @@ -558,7 +558,7 @@ static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave, return ret; } -static int add_res_range(struct mlx4_dev *dev, int slave, int base, int count, +static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count, enum mlx4_resource type, int extra) { int i; @@ -727,10 +727,10 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra) } } -static int rem_res_range(struct mlx4_dev *dev, int slave, int base, int count, +static int rem_res_range(struct mlx4_dev *dev, int slave, u64 base, int count, enum mlx4_resource type, int extra) { - int i; + u64 i; int err; struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; @@ -784,7 +784,7 @@ static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn, else { switch (state) { case RES_QP_BUSY: - mlx4_dbg(dev, "%s: failed RES_QP, 0x%x\n", + mlx4_dbg(dev, "%s: failed RES_QP, 0x%llx\n", __func__, r->com.res_id); err = -EBUSY; break; @@ -793,7 +793,7 @@ static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn, if (r->com.state == RES_QP_MAPPED && !alloc) break; - mlx4_dbg(dev, "failed RES_QP, 0x%x\n", r->com.res_id); + mlx4_dbg(dev, "failed RES_QP, 0x%llx\n", r->com.res_id); err = -EINVAL; break; @@ -802,7 +802,7 @@ static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn, r->com.state == RES_QP_HW) break; else { - mlx4_dbg(dev, "failed RES_QP, 0x%x\n", + mlx4_dbg(dev, "failed RES_QP, 0x%llx\n", r->com.res_id); err = -EINVAL; } @@ -2794,7 +2794,7 @@ static int _move_all_busy(struct mlx4_dev *dev, int slave, if (r->state == RES_ANY_BUSY) { if (print) mlx4_dbg(dev, - "%s id 0x%x is busy\n", + "%s id 0x%llx is busy\n", ResourceType(type), r->res_id); ++busy; -- GitLab From 6d19993788e080edb557178cc6aba2d963edce4e Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Thu, 5 Jul 2012 04:03:43 +0000 Subject: [PATCH 4185/6849] net/mlx4_en: Re-design multicast attachments flow Currently, for every change in the net device multicast list, the driver detaches all the addresses from the HW device, and then attaches the updated list. This behavior is wrong from two aspects: first, it causes a load of firmware commands and second, there is period of time where the correct addresses are not attached, which turned into packet loss. To improve - a copy of the multicast list is saved by the driver. For every change in the multicast list, the multicast list copy is used to find the delta between those two lists and add or remove multicast addresses as needed. Reported-by: Shawn Bohrer Cc: Shawn Bohrer Signed-off-by: Hadar Hen Zion Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_netdev.c | 143 ++++++++++++++---- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 16 +- 2 files changed, 124 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 073b85b45fc5..bedcbb30d38f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -170,33 +170,81 @@ static void mlx4_en_do_set_mac(struct work_struct *work) static void mlx4_en_clear_list(struct net_device *dev) { struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_mc_list *tmp, *mc_to_del; - kfree(priv->mc_addrs); - priv->mc_addrs = NULL; - priv->mc_addrs_cnt = 0; + list_for_each_entry_safe(mc_to_del, tmp, &priv->mc_list, list) { + list_del(&mc_to_del->list); + kfree(mc_to_del); + } } static void mlx4_en_cache_mclist(struct net_device *dev) { struct mlx4_en_priv *priv = netdev_priv(dev); struct netdev_hw_addr *ha; - char *mc_addrs; - int mc_addrs_cnt = netdev_mc_count(dev); - int i; + struct mlx4_en_mc_list *tmp; - mc_addrs = kmalloc(mc_addrs_cnt * ETH_ALEN, GFP_ATOMIC); - if (!mc_addrs) { - en_err(priv, "failed to allocate multicast list\n"); - return; - } - i = 0; - netdev_for_each_mc_addr(ha, dev) - memcpy(mc_addrs + i++ * ETH_ALEN, ha->addr, ETH_ALEN); mlx4_en_clear_list(dev); - priv->mc_addrs = mc_addrs; - priv->mc_addrs_cnt = mc_addrs_cnt; + netdev_for_each_mc_addr(ha, dev) { + tmp = kzalloc(sizeof(struct mlx4_en_mc_list), GFP_ATOMIC); + if (!tmp) { + en_err(priv, "failed to allocate multicast list\n"); + mlx4_en_clear_list(dev); + return; + } + memcpy(tmp->addr, ha->addr, ETH_ALEN); + list_add_tail(&tmp->list, &priv->mc_list); + } } +static void update_mclist_flags(struct mlx4_en_priv *priv, + struct list_head *dst, + struct list_head *src) +{ + struct mlx4_en_mc_list *dst_tmp, *src_tmp, *new_mc; + bool found; + + /* Find all the entries that should be removed from dst, + * These are the entries that are not found in src + */ + list_for_each_entry(dst_tmp, dst, list) { + found = false; + list_for_each_entry(src_tmp, src, list) { + if (!memcmp(dst_tmp->addr, src_tmp->addr, ETH_ALEN)) { + found = true; + break; + } + } + if (!found) + dst_tmp->action = MCLIST_REM; + } + + /* Add entries that exist in src but not in dst + * mark them as need to add + */ + list_for_each_entry(src_tmp, src, list) { + found = false; + list_for_each_entry(dst_tmp, dst, list) { + if (!memcmp(dst_tmp->addr, src_tmp->addr, ETH_ALEN)) { + dst_tmp->action = MCLIST_NONE; + found = true; + break; + } + } + if (!found) { + new_mc = kmalloc(sizeof(struct mlx4_en_mc_list), + GFP_KERNEL); + if (!new_mc) { + en_err(priv, "Failed to allocate current multicast list\n"); + return; + } + memcpy(new_mc, src_tmp, + sizeof(struct mlx4_en_mc_list)); + new_mc->action = MCLIST_ADD; + list_add_tail(&new_mc->list, dst); + } + } +} static void mlx4_en_set_multicast(struct net_device *dev) { @@ -214,6 +262,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) mcast_task); struct mlx4_en_dev *mdev = priv->mdev; struct net_device *dev = priv->dev; + struct mlx4_en_mc_list *mclist, *tmp; u64 mcast_addr = 0; u8 mc_list[16] = {0}; int err; @@ -336,7 +385,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) priv->flags |= MLX4_EN_FLAG_MC_PROMISC; } } else { - int i; /* Disable Multicast promisc */ if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, @@ -351,13 +399,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) if (err) en_err(priv, "Failed disabling multicast filter\n"); - /* Detach our qp from all the multicast addresses */ - for (i = 0; i < priv->mc_addrs_cnt; i++) { - memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN); - mc_list[5] = priv->port; - mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, - mc_list, MLX4_PROT_ETH); - } /* Flush mcast filter and init it with broadcast address */ mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST, 1, MLX4_MCAST_CONFIG); @@ -367,13 +408,8 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) netif_tx_lock_bh(dev); mlx4_en_cache_mclist(dev); netif_tx_unlock_bh(dev); - for (i = 0; i < priv->mc_addrs_cnt; i++) { - mcast_addr = - mlx4_en_mac_to_u64(priv->mc_addrs + i * ETH_ALEN); - memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN); - mc_list[5] = priv->port; - mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, - mc_list, 0, MLX4_PROT_ETH); + list_for_each_entry(mclist, &priv->mc_list, list) { + mcast_addr = mlx4_en_mac_to_u64(mclist->addr); mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, mcast_addr, 0, MLX4_MCAST_CONFIG); } @@ -381,6 +417,38 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) 0, MLX4_MCAST_ENABLE); if (err) en_err(priv, "Failed enabling multicast filter\n"); + + update_mclist_flags(priv, &priv->curr_list, &priv->mc_list); + list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) { + if (mclist->action == MCLIST_REM) { + /* detach this address and delete from list */ + memcpy(&mc_list[10], mclist->addr, ETH_ALEN); + mc_list[5] = priv->port; + err = mlx4_multicast_detach(mdev->dev, + &priv->rss_map.indir_qp, + mc_list, + MLX4_PROT_ETH); + if (err) + en_err(priv, "Fail to detach multicast address\n"); + + /* remove from list */ + list_del(&mclist->list); + kfree(mclist); + } + + if (mclist->action == MCLIST_ADD) { + /* attach the address */ + memcpy(&mc_list[10], mclist->addr, ETH_ALEN); + mc_list[5] = priv->port; + err = mlx4_multicast_attach(mdev->dev, + &priv->rss_map.indir_qp, + mc_list, 0, + MLX4_PROT_ETH); + if (err) + en_err(priv, "Fail to attach multicast address\n"); + + } + } } out: mutex_unlock(&mdev->state_lock); @@ -605,6 +673,9 @@ int mlx4_en_start_port(struct net_device *dev) return 0; } + INIT_LIST_HEAD(&priv->mc_list); + INIT_LIST_HEAD(&priv->curr_list); + /* Calculate Rx buf size */ dev->mtu = min(dev->mtu, priv->max_mtu); mlx4_en_calc_rx_buf(dev); @@ -760,6 +831,7 @@ void mlx4_en_stop_port(struct net_device *dev) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; + struct mlx4_en_mc_list *mclist, *tmp; int i; u8 mc_list[16] = {0}; @@ -781,13 +853,18 @@ void mlx4_en_stop_port(struct net_device *dev) mc_list[5] = priv->port; mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list, MLX4_PROT_ETH); - for (i = 0; i < priv->mc_addrs_cnt; i++) { - memcpy(&mc_list[10], priv->mc_addrs + i * ETH_ALEN, ETH_ALEN); + list_for_each_entry(mclist, &priv->curr_list, list) { + memcpy(&mc_list[10], mclist->addr, ETH_ALEN); mc_list[5] = priv->port; mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list, MLX4_PROT_ETH); } mlx4_en_clear_list(dev); + list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) { + list_del(&mclist->list); + kfree(mclist); + } + /* Flush multicast filter */ mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 225c20d47900..1bb00cd22d42 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -404,6 +404,18 @@ struct mlx4_en_perf_stats { #define NUM_PERF_COUNTERS 6 }; +enum mlx4_en_mclist_act { + MCLIST_NONE, + MCLIST_REM, + MCLIST_ADD, +}; + +struct mlx4_en_mc_list { + struct list_head list; + enum mlx4_en_mclist_act action; + u8 addr[ETH_ALEN]; +}; + struct mlx4_en_frag_info { u16 frag_size; u16 frag_prefix_size; @@ -489,8 +501,8 @@ struct mlx4_en_priv { struct mlx4_en_pkt_stats pkstats; struct mlx4_en_port_stats port_stats; u64 stats_bitmap; - char *mc_addrs; - int mc_addrs_cnt; + struct list_head mc_list; + struct list_head curr_list; struct mlx4_en_stat_out_mbox hw_stats; int vids[128]; bool wol; -- GitLab From c96d97f4d127b61def87b3ee056bec20cfc265d1 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:44 +0000 Subject: [PATCH 4186/6849] net/mlx4: Set steering mode according to device capabilities Instead of checking the firmware supported steering mode in various places in the code, add a dedicated field in the mlx4 device capabilities structure which is written once during the initialization flow and read across the code. This also set the grounds for add new steering modes. Currently two modes are supported, and are named after the ConnectX HW versions A0 and B0. A0 steering uses mac_index, vlan_index and priority to steer traffic into pre-defined range of QPs. B0 steering uses Ethernet L2 hashing rules and is enabled only if the firmware supports both unicast and multicast B0 steering, The current steering modes are relevant for Ethernet traffic only, such that Infiniband steering remains untouched. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_netdev.c | 108 ++++++++++++------ drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +- drivers/net/ethernet/mellanox/mlx4/main.c | 16 ++- drivers/net/ethernet/mellanox/mlx4/mcg.c | 70 ++++++------ drivers/net/ethernet/mellanox/mlx4/port.c | 9 +- include/linux/mlx4/device.h | 24 ++++ 6 files changed, 148 insertions(+), 81 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index bedcbb30d38f..44ff7cdb15e5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -265,7 +265,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) struct mlx4_en_mc_list *mclist, *tmp; u64 mcast_addr = 0; u8 mc_list[16] = {0}; - int err; + int err = 0; mutex_lock(&mdev->state_lock); if (!mdev->device_up) { @@ -300,16 +300,36 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) priv->flags |= MLX4_EN_FLAG_PROMISC; /* Enable promiscouos mode */ - if (!(mdev->dev->caps.flags & - MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) - err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, - priv->base_qpn, 1); - else - err = mlx4_unicast_promisc_add(mdev->dev, priv->base_qpn, + switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_B0: + err = mlx4_unicast_promisc_add(mdev->dev, + priv->base_qpn, priv->port); - if (err) - en_err(priv, "Failed enabling " - "promiscuous mode\n"); + if (err) + en_err(priv, "Failed enabling unicast promiscuous mode\n"); + + /* Add the default qp number as multicast + * promisc + */ + if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { + err = mlx4_multicast_promisc_add(mdev->dev, + priv->base_qpn, + priv->port); + if (err) + en_err(priv, "Failed enabling multicast promiscuous mode\n"); + priv->flags |= MLX4_EN_FLAG_MC_PROMISC; + } + break; + + case MLX4_STEERING_MODE_A0: + err = mlx4_SET_PORT_qpn_calc(mdev->dev, + priv->port, + priv->base_qpn, + 1); + if (err) + en_err(priv, "Failed enabling promiscuous mode\n"); + break; + } /* Disable port multicast filter (unconditionally) */ err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, @@ -318,15 +338,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) en_err(priv, "Failed disabling " "multicast filter\n"); - /* Add the default qp number as multicast promisc */ - if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { - err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn, - priv->port); - if (err) - en_err(priv, "Failed entering multicast promisc mode\n"); - priv->flags |= MLX4_EN_FLAG_MC_PROMISC; - } - /* Disable port VLAN filter */ err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) @@ -345,22 +356,31 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) priv->flags &= ~MLX4_EN_FLAG_PROMISC; /* Disable promiscouos mode */ - if (!(mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) - err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, - priv->base_qpn, 0); - else - err = mlx4_unicast_promisc_remove(mdev->dev, priv->base_qpn, + switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_B0: + err = mlx4_unicast_promisc_remove(mdev->dev, + priv->base_qpn, priv->port); - if (err) - en_err(priv, "Failed disabling promiscuous mode\n"); + if (err) + en_err(priv, "Failed disabling unicast promiscuous mode\n"); + /* Disable Multicast promisc */ + if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { + err = mlx4_multicast_promisc_remove(mdev->dev, + priv->base_qpn, + priv->port); + if (err) + en_err(priv, "Failed disabling multicast promiscuous mode\n"); + priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; + } + break; - /* Disable Multicast promisc */ - if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { - err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, - priv->port); + case MLX4_STEERING_MODE_A0: + err = mlx4_SET_PORT_qpn_calc(mdev->dev, + priv->port, + priv->base_qpn, 0); if (err) - en_err(priv, "Failed disabling multicast promiscuous mode\n"); - priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; + en_err(priv, "Failed disabling promiscuous mode\n"); + break; } /* Enable port VLAN filter */ @@ -378,8 +398,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) /* Add the default qp number as multicast promisc */ if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { - err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn, - priv->port); + switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_B0: + err = mlx4_multicast_promisc_add(mdev->dev, + priv->base_qpn, + priv->port); + break; + + case MLX4_STEERING_MODE_A0: + break; + } if (err) en_err(priv, "Failed entering multicast promisc mode\n"); priv->flags |= MLX4_EN_FLAG_MC_PROMISC; @@ -387,8 +415,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) } else { /* Disable Multicast promisc */ if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { - err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, - priv->port); + switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_B0: + err = mlx4_multicast_promisc_remove(mdev->dev, + priv->base_qpn, + priv->port); + break; + + case MLX4_STEERING_MODE_A0: + break; + } if (err) en_err(priv, "Failed disabling multicast promiscuous mode\n"); priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 9c83bb8151ea..40e048bac024 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -1124,7 +1124,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); - if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) + if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0) MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET); MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 14d9c762b60f..f8125a82c0cb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -244,7 +244,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.reserved_srqs = dev_cap->reserved_srqs; dev->caps.max_sq_desc_sz = dev_cap->max_sq_desc_sz; dev->caps.max_rq_desc_sz = dev_cap->max_rq_desc_sz; - dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); /* * Subtract 1 from the limit because we need to allocate a * spare CQE so the HCA HW can tell the difference between an @@ -275,6 +274,21 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.max_gso_sz = dev_cap->max_gso_sz; dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; + if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && + dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) { + dev->caps.steering_mode = MLX4_STEERING_MODE_B0; + } else { + dev->caps.steering_mode = MLX4_STEERING_MODE_A0; + + if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || + dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) + mlx4_warn(dev, "Must have UC_STEER and MC_STEER flags " + "set to use B0 steering. Falling back to A0 steering mode.\n"); + } + mlx4_dbg(dev, "Steering mode is: %s\n", + mlx4_steering_mode_str(dev->caps.steering_mode)); + dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); + /* Sense port always allowed on supported devices for ConnectX1 and 2 */ if (dev->pdev->device != 0x1003) dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index f4a8f98e402a..319c9d45d59a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -868,36 +868,50 @@ static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp, int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], int block_mcast_loopback, enum mlx4_protocol prot) { - if (prot == MLX4_PROT_ETH && - !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) - return 0; - if (prot == MLX4_PROT_ETH) - gid[7] |= (MLX4_MC_STEER << 1); + switch (dev->caps.steering_mode) { + case MLX4_STEERING_MODE_A0: + if (prot == MLX4_PROT_ETH) + return 0; - if (mlx4_is_mfunc(dev)) - return mlx4_QP_ATTACH(dev, qp, gid, 1, - block_mcast_loopback, prot); + case MLX4_STEERING_MODE_B0: + if (prot == MLX4_PROT_ETH) + gid[7] |= (MLX4_MC_STEER << 1); - return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, - prot, MLX4_MC_STEER); + if (mlx4_is_mfunc(dev)) + return mlx4_QP_ATTACH(dev, qp, gid, 1, + block_mcast_loopback, prot); + return mlx4_qp_attach_common(dev, qp, gid, + block_mcast_loopback, prot, + MLX4_MC_STEER); + + default: + return -EINVAL; + } } EXPORT_SYMBOL_GPL(mlx4_multicast_attach); int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], enum mlx4_protocol prot) { - if (prot == MLX4_PROT_ETH && - !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) - return 0; + switch (dev->caps.steering_mode) { + case MLX4_STEERING_MODE_A0: + if (prot == MLX4_PROT_ETH) + return 0; - if (prot == MLX4_PROT_ETH) - gid[7] |= (MLX4_MC_STEER << 1); + case MLX4_STEERING_MODE_B0: + if (prot == MLX4_PROT_ETH) + gid[7] |= (MLX4_MC_STEER << 1); - if (mlx4_is_mfunc(dev)) - return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); + if (mlx4_is_mfunc(dev)) + return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); + + return mlx4_qp_detach_common(dev, qp, gid, prot, + MLX4_MC_STEER); - return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_MC_STEER); + default: + return -EINVAL; + } } EXPORT_SYMBOL_GPL(mlx4_multicast_detach); @@ -905,10 +919,6 @@ int mlx4_unicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], int block_mcast_loopback, enum mlx4_protocol prot) { - if (prot == MLX4_PROT_ETH && - !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) - return 0; - if (prot == MLX4_PROT_ETH) gid[7] |= (MLX4_UC_STEER << 1); @@ -924,10 +934,6 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_attach); int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], enum mlx4_protocol prot) { - if (prot == MLX4_PROT_ETH && - !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) - return 0; - if (prot == MLX4_PROT_ETH) gid[7] |= (MLX4_UC_STEER << 1); @@ -968,9 +974,6 @@ static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn, int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) { - if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) - return 0; - if (mlx4_is_mfunc(dev)) return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port); @@ -980,9 +983,6 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) { - if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) - return 0; - if (mlx4_is_mfunc(dev)) return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port); @@ -992,9 +992,6 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) { - if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) - return 0; - if (mlx4_is_mfunc(dev)) return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port); @@ -1004,9 +1001,6 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) { - if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) - return 0; - if (mlx4_is_mfunc(dev)) return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port); diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index a8fb52992c64..58de7237f57a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -155,7 +155,7 @@ int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) return err; } - if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) { + if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) { *qpn = info->base_qpn + index; return 0; } @@ -206,7 +206,7 @@ void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn) (unsigned long long) mac); mlx4_unregister_mac(dev, port, mac); - if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { + if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { entry = radix_tree_lookup(&info->mac_tree, qpn); if (entry) { mlx4_dbg(dev, "Releasing qp: port %d, mac 0x%llx," @@ -359,7 +359,7 @@ int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac) int index = qpn - info->base_qpn; int err = 0; - if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { + if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { entry = radix_tree_lookup(&info->mac_tree, qpn); if (!entry) return -EINVAL; @@ -803,8 +803,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ? MCAST_DIRECT : MCAST_DEFAULT; - if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER && - dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) + if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) return 0; mailbox = mlx4_alloc_cmd_mailbox(dev); diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 6a8f002b8ed3..7f5c9ee42f96 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -70,6 +70,29 @@ enum { MLX4_MFUNC_EQE_MASK = (MLX4_MFUNC_MAX_EQES - 1) }; +/* Driver supports 2 diffrent device methods to manage traffic steering: + * - B0 steering mode - Common low level API for ib and (if supported) eth. + * - A0 steering mode - Limited low level API for eth. In case of IB, + * B0 mode is in use. + */ +enum { + MLX4_STEERING_MODE_A0, + MLX4_STEERING_MODE_B0 +}; + +static inline const char *mlx4_steering_mode_str(int steering_mode) +{ + switch (steering_mode) { + case MLX4_STEERING_MODE_A0: + return "A0 steering"; + + case MLX4_STEERING_MODE_B0: + return "B0 steering"; + default: + return "Unrecognize steering mode"; + } +} + enum { MLX4_DEV_CAP_FLAG_RC = 1LL << 0, MLX4_DEV_CAP_FLAG_UC = 1LL << 1, @@ -295,6 +318,7 @@ struct mlx4_caps { int num_amgms; int reserved_mcgs; int num_qp_per_mgm; + int steering_mode; int num_pds; int reserved_pds; int max_xrcds; -- GitLab From 8fcfb4db74352d3d447b7a559ad54f7577074d19 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:45 +0000 Subject: [PATCH 4187/6849] net/mlx4_core: Add firmware commands to support device managed flow steering Add support for firmware commands to attach/detach a new device managed steering mode. Such network steering rules allow the user to provide an L2/L3/L4 flow specification to the firmware and have the device to steer traffic that matches that specification to the provided QP. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 19 ++++++++++++ drivers/net/ethernet/mellanox/mlx4/mcg.c | 29 +++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4.h | 10 +++++++ .../ethernet/mellanox/mlx4/resource_tracker.c | 24 +++++++++++++++ include/linux/mlx4/cmd.h | 4 +++ 5 files changed, 86 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 842c8ce9494e..7e94987d030c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1080,6 +1080,25 @@ static struct mlx4_cmd_info cmd_info[] = { .verify = NULL, .wrapper = NULL }, + /* flow steering commands */ + { + .opcode = MLX4_QP_FLOW_STEERING_ATTACH, + .has_inbox = true, + .has_outbox = false, + .out_is_imm = true, + .encode_slave_id = false, + .verify = NULL, + .wrapper = mlx4_QP_FLOW_STEERING_ATTACH_wrapper + }, + { + .opcode = MLX4_QP_FLOW_STEERING_DETACH, + .has_inbox = false, + .has_outbox = false, + .out_is_imm = false, + .encode_slave_id = false, + .verify = NULL, + .wrapper = mlx4_QP_FLOW_STEERING_DETACH_wrapper + }, }; static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 319c9d45d59a..3c59a33a98a5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -62,6 +62,35 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2); } +static int mlx4_QP_FLOW_STEERING_ATTACH(struct mlx4_dev *dev, + struct mlx4_cmd_mailbox *mailbox, + u32 size, + u64 *reg_id) +{ + u64 imm; + int err = 0; + + err = mlx4_cmd_imm(dev, mailbox->dma, &imm, size, 0, + MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + if (err) + return err; + *reg_id = imm; + + return err; +} + +static int mlx4_QP_FLOW_STEERING_DETACH(struct mlx4_dev *dev, u64 regid) +{ + int err = 0; + + err = mlx4_cmd(dev, regid, 0, 0, + MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + + return err; +} + static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index, struct mlx4_cmd_mailbox *mailbox) { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index a425a984758f..c07e882e8369 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -1118,6 +1118,16 @@ int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd); +int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd); +int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd); int mlx4_get_mgm_entry_size(struct mlx4_dev *dev); int mlx4_get_qp_per_mgm(struct mlx4_dev *dev); diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 6bdac2955f8b..a8ca960f4620 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2738,6 +2738,30 @@ ex_put: return err; } +int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd) +{ + return mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, + vhcr->in_modifier, 0, + MLX4_QP_FLOW_STEERING_ATTACH, + MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); +} + +int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd) +{ + return mlx4_cmd(dev, vhcr->in_param, 0, 0, + MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); +} + enum { BUSY_MAX_RETRIES = 10 }; diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 1f3860a8a109..260695186256 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -154,6 +154,10 @@ enum { /* set port opcode modifiers */ MLX4_SET_PORT_PRIO2TC = 0x8, MLX4_SET_PORT_SCHEDULER = 0x9, + + /* register/delete flow steering network rules */ + MLX4_QP_FLOW_STEERING_ATTACH = 0x65, + MLX4_QP_FLOW_STEERING_DETACH = 0x66, }; enum { -- GitLab From 0ff1fb654bec0cff62ddf81a8a8edec4263604a0 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:46 +0000 Subject: [PATCH 4188/6849] {NET, IB}/mlx4: Add device managed flow steering firmware API The driver is modified to support three operation modes. If supported by firmware use the device managed flow steering API, that which we call device managed steering mode. Else, if the firmware supports the B0 steering mode use it, and finally, if none of the above, use the A0 steering mode. When the steering mode is device managed, the code is modified such that L2 based rules set by the mlx4_en driver for Ethernet unicast and multicast, and the IB stack multicast attach calls done through the mlx4_ib driver are all routed to use the device managed API. When attaching rule using device managed flow steering API, the firmware returns a 64 bit registration id, which is to be provided during detach. Currently the firmware is always programmed during HCA initialization to use standard L2 hashing. Future work should be done to allow configuring the flow-steering hash function with common, non proprietary means. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/infiniband/hw/mlx4/main.c | 62 ++- drivers/infiniband/hw/mlx4/mlx4_ib.h | 1 + drivers/infiniband/hw/mlx4/qp.c | 1 + .../net/ethernet/mellanox/mlx4/en_netdev.c | 21 +- drivers/net/ethernet/mellanox/mlx4/fw.c | 91 ++++- drivers/net/ethernet/mellanox/mlx4/fw.h | 3 + drivers/net/ethernet/mellanox/mlx4/main.c | 56 ++- drivers/net/ethernet/mellanox/mlx4/mcg.c | 365 +++++++++++++++++- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 13 + drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 + drivers/net/ethernet/mellanox/mlx4/port.c | 98 +++-- drivers/net/ethernet/mellanox/mlx4/profile.c | 12 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 6 + include/linux/mlx4/device.h | 108 +++++- 14 files changed, 758 insertions(+), 81 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 3530c41fcd1f..8a3a2037b005 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -718,26 +718,53 @@ int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, return ret; } +struct mlx4_ib_steering { + struct list_head list; + u64 reg_id; + union ib_gid gid; +}; + static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) { int err; struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); struct mlx4_ib_qp *mqp = to_mqp(ibqp); + u64 reg_id; + struct mlx4_ib_steering *ib_steering = NULL; + + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + ib_steering = kmalloc(sizeof(*ib_steering), GFP_KERNEL); + if (!ib_steering) + return -ENOMEM; + } - err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, - !!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK), - MLX4_PROT_IB_IPV6); + err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, mqp->port, + !!(mqp->flags & + MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK), + MLX4_PROT_IB_IPV6, ®_id); if (err) - return err; + goto err_malloc; err = add_gid_entry(ibqp, gid); if (err) goto err_add; + if (ib_steering) { + memcpy(ib_steering->gid.raw, gid->raw, 16); + ib_steering->reg_id = reg_id; + mutex_lock(&mqp->mutex); + list_add(&ib_steering->list, &mqp->steering_rules); + mutex_unlock(&mqp->mutex); + } return 0; err_add: - mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROT_IB_IPV6); + mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, + MLX4_PROT_IB_IPV6, reg_id); +err_malloc: + kfree(ib_steering); + return err; } @@ -765,9 +792,30 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) u8 mac[6]; struct net_device *ndev; struct mlx4_ib_gid_entry *ge; + u64 reg_id = 0; + + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + struct mlx4_ib_steering *ib_steering; + + mutex_lock(&mqp->mutex); + list_for_each_entry(ib_steering, &mqp->steering_rules, list) { + if (!memcmp(ib_steering->gid.raw, gid->raw, 16)) { + list_del(&ib_steering->list); + break; + } + } + mutex_unlock(&mqp->mutex); + if (&ib_steering->list == &mqp->steering_rules) { + pr_err("Couldn't find reg_id for mgid. Steering rule is left attached\n"); + return -EINVAL; + } + reg_id = ib_steering->reg_id; + kfree(ib_steering); + } - err = mlx4_multicast_detach(mdev->dev, - &mqp->mqp, gid->raw, MLX4_PROT_IB_IPV6); + err = mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, + MLX4_PROT_IB_IPV6, reg_id); if (err) return err; diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index ff36655d23d3..42df4f7a6a5b 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -163,6 +163,7 @@ struct mlx4_ib_qp { u8 state; int mlx_type; struct list_head gid_list; + struct list_head steering_rules; }; struct mlx4_ib_srq { diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 8d4ed24aef93..6af19f6c2b11 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -495,6 +495,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, spin_lock_init(&qp->sq.lock); spin_lock_init(&qp->rq.lock); INIT_LIST_HEAD(&qp->gid_list); + INIT_LIST_HEAD(&qp->steering_rules); qp->state = IB_QPS_RESET; if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 44ff7cdb15e5..eb5ed8e39873 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -463,7 +463,8 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) err = mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list, - MLX4_PROT_ETH); + MLX4_PROT_ETH, + mclist->reg_id); if (err) en_err(priv, "Fail to detach multicast address\n"); @@ -475,11 +476,14 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) if (mclist->action == MCLIST_ADD) { /* attach the address */ memcpy(&mc_list[10], mclist->addr, ETH_ALEN); + /* needed for B0 steering support */ mc_list[5] = priv->port; err = mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, - mc_list, 0, - MLX4_PROT_ETH); + mc_list, + priv->port, 0, + MLX4_PROT_ETH, + &mclist->reg_id); if (err) en_err(priv, "Fail to attach multicast address\n"); @@ -827,9 +831,10 @@ int mlx4_en_start_port(struct net_device *dev) /* Attach rx QP to bradcast address */ memset(&mc_list[10], 0xff, ETH_ALEN); - mc_list[5] = priv->port; + mc_list[5] = priv->port; /* needed for B0 steering support */ if (mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, mc_list, - 0, MLX4_PROT_ETH)) + priv->port, 0, MLX4_PROT_ETH, + &priv->broadcast_id)) mlx4_warn(mdev, "Failed Attaching Broadcast\n"); /* Must redo promiscuous mode setup. */ @@ -886,14 +891,14 @@ void mlx4_en_stop_port(struct net_device *dev) /* Detach All multicasts */ memset(&mc_list[10], 0xff, ETH_ALEN); - mc_list[5] = priv->port; + mc_list[5] = priv->port; /* needed for B0 steering support */ mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list, - MLX4_PROT_ETH); + MLX4_PROT_ETH, priv->broadcast_id); list_for_each_entry(mclist, &priv->curr_list, list) { memcpy(&mc_list[10], mclist->addr, ETH_ALEN); mc_list[5] = priv->port; mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, - mc_list, MLX4_PROT_ETH); + mc_list, MLX4_PROT_ETH, mclist->reg_id); } mlx4_en_clear_list(dev); list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) { diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 40e048bac024..1d70657058a5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -123,7 +123,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) static const char * const fname[] = { [0] = "RSS support", [1] = "RSS Toeplitz Hash Function support", - [2] = "RSS XOR Hash Function support" + [2] = "RSS XOR Hash Function support", + [3] = "Device manage flow steering support" }; int i; @@ -391,6 +392,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66 #define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67 #define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 +#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 +#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 #define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 #define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 @@ -474,6 +477,12 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->num_ports = field & 0xf; MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET); dev_cap->max_msg_sz = 1 << (field & 0x1f); + MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); + if (field & 0x80) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN; + dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f; + MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET); + dev_cap->fs_max_num_qp_per_entry = field; MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); dev_cap->stat_rate_support = stat_rate; MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); @@ -1061,6 +1070,15 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) #define INIT_HCA_LOG_MC_HASH_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x16) #define INIT_HCA_UC_STEERING_OFFSET (INIT_HCA_MCAST_OFFSET + 0x18) #define INIT_HCA_LOG_MC_TABLE_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x1b) +#define INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN 0x6 +#define INIT_HCA_FS_PARAM_OFFSET 0x1d0 +#define INIT_HCA_FS_BASE_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x00) +#define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x12) +#define INIT_HCA_FS_LOG_TABLE_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x1b) +#define INIT_HCA_FS_ETH_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x21) +#define INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x22) +#define INIT_HCA_FS_IB_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x25) +#define INIT_HCA_FS_IB_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x26) #define INIT_HCA_TPT_OFFSET 0x0f0 #define INIT_HCA_DMPT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x00) #define INIT_HCA_LOG_MPT_SZ_OFFSET (INIT_HCA_TPT_OFFSET + 0x0b) @@ -1119,14 +1137,44 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) MLX4_PUT(inbox, param->rdmarc_base, INIT_HCA_RDMARC_BASE_OFFSET); MLX4_PUT(inbox, param->log_rd_per_qp, INIT_HCA_LOG_RD_OFFSET); - /* multicast attributes */ - - MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); - MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); - MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); - if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0) - MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET); - MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); + /* steering attributes */ + if (dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= + cpu_to_be32(1 << + INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN); + + MLX4_PUT(inbox, param->mc_base, INIT_HCA_FS_BASE_OFFSET); + MLX4_PUT(inbox, param->log_mc_entry_sz, + INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); + MLX4_PUT(inbox, param->log_mc_table_sz, + INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); + /* Enable Ethernet flow steering + * with udp unicast and tcp unicast + */ + MLX4_PUT(inbox, param->fs_hash_enable_bits, + INIT_HCA_FS_ETH_BITS_OFFSET); + MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, + INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET); + /* Enable IPoIB flow steering + * with udp unicast and tcp unicast + */ + MLX4_PUT(inbox, param->fs_hash_enable_bits, + INIT_HCA_FS_IB_BITS_OFFSET); + MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, + INIT_HCA_FS_IB_NUM_ADDRS_OFFSET); + } else { + MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); + MLX4_PUT(inbox, param->log_mc_entry_sz, + INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); + MLX4_PUT(inbox, param->log_mc_hash_sz, + INIT_HCA_LOG_MC_HASH_SZ_OFFSET); + MLX4_PUT(inbox, param->log_mc_table_sz, + INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); + if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0) + MLX4_PUT(inbox, (u8) (1 << 3), + INIT_HCA_UC_STEERING_OFFSET); + } /* TPT attributes */ @@ -1188,15 +1236,24 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); - /* multicast attributes */ + /* steering attributes */ + if (dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { - MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); - MLX4_GET(param->log_mc_entry_sz, outbox, - INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); - MLX4_GET(param->log_mc_hash_sz, outbox, - INIT_HCA_LOG_MC_HASH_SZ_OFFSET); - MLX4_GET(param->log_mc_table_sz, outbox, - INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); + MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); + MLX4_GET(param->log_mc_entry_sz, outbox, + INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); + MLX4_GET(param->log_mc_table_sz, outbox, + INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); + } else { + MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); + MLX4_GET(param->log_mc_entry_sz, outbox, + INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); + MLX4_GET(param->log_mc_hash_sz, outbox, + INIT_HCA_LOG_MC_HASH_SZ_OFFSET); + MLX4_GET(param->log_mc_table_sz, outbox, + INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); + } /* TPT attributes */ diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 64c0399e4b78..83fcbbf1b169 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -78,6 +78,8 @@ struct mlx4_dev_cap { u16 wavelength[MLX4_MAX_PORTS + 1]; u64 trans_code[MLX4_MAX_PORTS + 1]; u16 stat_rate_support; + int fs_log_max_ucast_qp_range_size; + int fs_max_num_qp_per_entry; u64 flags; u64 flags2; int reserved_uars; @@ -165,6 +167,7 @@ struct mlx4_init_hca_param { u8 log_mpt_sz; u8 log_uar_sz; u8 uar_page_sz; /* log pg sz in 4k chunks */ + u8 fs_hash_enable_bits; }; struct mlx4_init_ib_param { diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index f8125a82c0cb..42645166bae2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -91,7 +91,9 @@ module_param_named(log_num_mgm_entry_size, MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" " of qp per mcg, for example:" " 10 gives 248.range: 9<=" - " log_num_mgm_entry_size <= 12"); + " log_num_mgm_entry_size <= 12." + " Not in use with device managed" + " flow steering"); #define MLX4_VF (1 << 0) @@ -274,20 +276,27 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.max_gso_sz = dev_cap->max_gso_sz; dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; - if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && - dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) { - dev->caps.steering_mode = MLX4_STEERING_MODE_B0; + if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN) { + dev->caps.steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; + dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; + dev->caps.fs_log_max_ucast_qp_range_size = + dev_cap->fs_log_max_ucast_qp_range_size; } else { - dev->caps.steering_mode = MLX4_STEERING_MODE_A0; + if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && + dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) { + dev->caps.steering_mode = MLX4_STEERING_MODE_B0; + } else { + dev->caps.steering_mode = MLX4_STEERING_MODE_A0; - if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || - dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) - mlx4_warn(dev, "Must have UC_STEER and MC_STEER flags " - "set to use B0 steering. Falling back to A0 steering mode.\n"); + if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || + dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) + mlx4_warn(dev, "Must have UC_STEER and MC_STEER flags " + "set to use B0 steering. Falling back to A0 steering mode.\n"); + } + dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); } mlx4_dbg(dev, "Steering mode is: %s\n", mlx4_steering_mode_str(dev->caps.steering_mode)); - dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); /* Sense port always allowed on supported devices for ConnectX1 and 2 */ if (dev->pdev->device != 0x1003) @@ -982,9 +991,11 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, } /* - * It's not strictly required, but for simplicity just map the - * whole multicast group table now. The table isn't very big - * and it's a lot easier than trying to track ref counts. + * For flow steering device managed mode it is required to use + * mlx4_init_icm_table. For B0 steering mode it's not strictly + * required, but for simplicity just map the whole multicast + * group table now. The table isn't very big and it's a lot + * easier than trying to track ref counts. */ err = mlx4_init_icm_table(dev, &priv->mcg_table.table, init_hca->mc_base, @@ -1220,7 +1231,26 @@ static int mlx4_init_hca(struct mlx4_dev *dev) goto err_stop_fw; } + priv->fs_hash_mode = MLX4_FS_L2_HASH; + + switch (priv->fs_hash_mode) { + case MLX4_FS_L2_HASH: + init_hca.fs_hash_enable_bits = 0; + break; + + case MLX4_FS_L2_L3_L4_HASH: + /* Enable flow steering with + * udp unicast and tcp unicast + */ + init_hca.fs_hash_enable_bits = + MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN; + break; + } + profile = default_profile; + if (dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) + profile.num_mcg = MLX4_FS_NUM_MCG; icm_size = mlx4_make_profile(dev, &profile, &dev_cap, &init_hca); diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 3c59a33a98a5..768a2a4530e8 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -41,6 +41,7 @@ #define MGM_QPN_MASK 0x00FFFFFF #define MGM_BLCK_LB_BIT 30 +#define MLX4_MAC_MASK 0xffffffffffffULL static const u8 zero_gid[16]; /* automatically initialized to 0 */ @@ -54,7 +55,12 @@ struct mlx4_mgm { int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) { - return min((1 << mlx4_log_num_mgm_entry_size), MLX4_MAX_MGM_ENTRY_SIZE); + if (dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) + return 1 << MLX4_FS_MGM_LOG_ENTRY_SIZE; + else + return min((1 << mlx4_log_num_mgm_entry_size), + MLX4_MAX_MGM_ENTRY_SIZE); } int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) @@ -643,6 +649,311 @@ static int find_entry(struct mlx4_dev *dev, u8 port, return err; } +struct mlx4_net_trans_rule_hw_ctrl { + __be32 ctrl; + __be32 vf_vep_port; + __be32 qpn; + __be32 reserved; +}; + +static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, + struct mlx4_net_trans_rule_hw_ctrl *hw) +{ + static const u8 __promisc_mode[] = { + [MLX4_FS_PROMISC_NONE] = 0x0, + [MLX4_FS_PROMISC_UPLINK] = 0x1, + [MLX4_FS_PROMISC_FUNCTION_PORT] = 0x2, + [MLX4_FS_PROMISC_ALL_MULTI] = 0x3, + }; + + u32 dw = 0; + + dw = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0; + dw |= ctrl->exclusive ? (1 << 2) : 0; + dw |= ctrl->allow_loopback ? (1 << 3) : 0; + dw |= __promisc_mode[ctrl->promisc_mode] << 8; + dw |= ctrl->priority << 16; + + hw->ctrl = cpu_to_be32(dw); + hw->vf_vep_port = cpu_to_be32(ctrl->port); + hw->qpn = cpu_to_be32(ctrl->qpn); +} + +struct mlx4_net_trans_rule_hw_ib { + u8 size; + u8 rsvd1; + __be16 id; + u32 rsvd2; + __be32 qpn; + __be32 qpn_mask; + u8 dst_gid[16]; + u8 dst_gid_msk[16]; +} __packed; + +struct mlx4_net_trans_rule_hw_eth { + u8 size; + u8 rsvd; + __be16 id; + u8 rsvd1[6]; + u8 dst_mac[6]; + u16 rsvd2; + u8 dst_mac_msk[6]; + u16 rsvd3; + u8 src_mac[6]; + u16 rsvd4; + u8 src_mac_msk[6]; + u8 rsvd5; + u8 ether_type_enable; + __be16 ether_type; + __be16 vlan_id_msk; + __be16 vlan_id; +} __packed; + +struct mlx4_net_trans_rule_hw_tcp_udp { + u8 size; + u8 rsvd; + __be16 id; + __be16 rsvd1[3]; + __be16 dst_port; + __be16 rsvd2; + __be16 dst_port_msk; + __be16 rsvd3; + __be16 src_port; + __be16 rsvd4; + __be16 src_port_msk; +} __packed; + +struct mlx4_net_trans_rule_hw_ipv4 { + u8 size; + u8 rsvd; + __be16 id; + __be32 rsvd1; + __be32 dst_ip; + __be32 dst_ip_msk; + __be32 src_ip; + __be32 src_ip_msk; +} __packed; + +struct _rule_hw { + union { + struct { + u8 size; + u8 rsvd; + __be16 id; + }; + struct mlx4_net_trans_rule_hw_eth eth; + struct mlx4_net_trans_rule_hw_ib ib; + struct mlx4_net_trans_rule_hw_ipv4 ipv4; + struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; + }; +}; + +static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, + struct _rule_hw *rule_hw) +{ + static const u16 __sw_id_hw[] = { + [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, + [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, + [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, + [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, + [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, + [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 + }; + + static const size_t __rule_hw_sz[] = { + [MLX4_NET_TRANS_RULE_ID_ETH] = + sizeof(struct mlx4_net_trans_rule_hw_eth), + [MLX4_NET_TRANS_RULE_ID_IB] = + sizeof(struct mlx4_net_trans_rule_hw_ib), + [MLX4_NET_TRANS_RULE_ID_IPV6] = 0, + [MLX4_NET_TRANS_RULE_ID_IPV4] = + sizeof(struct mlx4_net_trans_rule_hw_ipv4), + [MLX4_NET_TRANS_RULE_ID_TCP] = + sizeof(struct mlx4_net_trans_rule_hw_tcp_udp), + [MLX4_NET_TRANS_RULE_ID_UDP] = + sizeof(struct mlx4_net_trans_rule_hw_tcp_udp) + }; + if (spec->id > MLX4_NET_TRANS_RULE_NUM) { + mlx4_err(dev, "Invalid network rule id. id = %d\n", spec->id); + return -EINVAL; + } + memset(rule_hw, 0, __rule_hw_sz[spec->id]); + rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]); + rule_hw->size = __rule_hw_sz[spec->id] >> 2; + + switch (spec->id) { + case MLX4_NET_TRANS_RULE_ID_ETH: + memcpy(rule_hw->eth.dst_mac, spec->eth.dst_mac, ETH_ALEN); + memcpy(rule_hw->eth.dst_mac_msk, spec->eth.dst_mac_msk, + ETH_ALEN); + memcpy(rule_hw->eth.src_mac, spec->eth.src_mac, ETH_ALEN); + memcpy(rule_hw->eth.src_mac_msk, spec->eth.src_mac_msk, + ETH_ALEN); + if (spec->eth.ether_type_enable) { + rule_hw->eth.ether_type_enable = 1; + rule_hw->eth.ether_type = spec->eth.ether_type; + } + rule_hw->eth.vlan_id = spec->eth.vlan_id; + rule_hw->eth.vlan_id_msk = spec->eth.vlan_id_msk; + break; + + case MLX4_NET_TRANS_RULE_ID_IB: + rule_hw->ib.qpn = spec->ib.r_qpn; + rule_hw->ib.qpn_mask = spec->ib.qpn_msk; + memcpy(&rule_hw->ib.dst_gid, &spec->ib.dst_gid, 16); + memcpy(&rule_hw->ib.dst_gid_msk, &spec->ib.dst_gid_msk, 16); + break; + + case MLX4_NET_TRANS_RULE_ID_IPV6: + return -EOPNOTSUPP; + + case MLX4_NET_TRANS_RULE_ID_IPV4: + rule_hw->ipv4.src_ip = spec->ipv4.src_ip; + rule_hw->ipv4.src_ip_msk = spec->ipv4.src_ip_msk; + rule_hw->ipv4.dst_ip = spec->ipv4.dst_ip; + rule_hw->ipv4.dst_ip_msk = spec->ipv4.dst_ip_msk; + break; + + case MLX4_NET_TRANS_RULE_ID_TCP: + case MLX4_NET_TRANS_RULE_ID_UDP: + rule_hw->tcp_udp.dst_port = spec->tcp_udp.dst_port; + rule_hw->tcp_udp.dst_port_msk = spec->tcp_udp.dst_port_msk; + rule_hw->tcp_udp.src_port = spec->tcp_udp.src_port; + rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk; + break; + + default: + return -EINVAL; + } + + return __rule_hw_sz[spec->id]; +} + +static void mlx4_err_rule(struct mlx4_dev *dev, char *str, + struct mlx4_net_trans_rule *rule) +{ +#define BUF_SIZE 256 + struct mlx4_spec_list *cur; + char buf[BUF_SIZE]; + int len = 0; + + mlx4_err(dev, "%s", str); + len += snprintf(buf + len, BUF_SIZE - len, + "port = %d prio = 0x%x qp = 0x%x ", + rule->port, rule->priority, rule->qpn); + + list_for_each_entry(cur, &rule->list, list) { + switch (cur->id) { + case MLX4_NET_TRANS_RULE_ID_ETH: + len += snprintf(buf + len, BUF_SIZE - len, + "dmac = %pM ", &cur->eth.dst_mac); + if (cur->eth.ether_type) + len += snprintf(buf + len, BUF_SIZE - len, + "ethertype = 0x%x ", + be16_to_cpu(cur->eth.ether_type)); + if (cur->eth.vlan_id) + len += snprintf(buf + len, BUF_SIZE - len, + "vlan-id = %d ", + be16_to_cpu(cur->eth.vlan_id)); + break; + + case MLX4_NET_TRANS_RULE_ID_IPV4: + if (cur->ipv4.src_ip) + len += snprintf(buf + len, BUF_SIZE - len, + "src-ip = %pI4 ", + &cur->ipv4.src_ip); + if (cur->ipv4.dst_ip) + len += snprintf(buf + len, BUF_SIZE - len, + "dst-ip = %pI4 ", + &cur->ipv4.dst_ip); + break; + + case MLX4_NET_TRANS_RULE_ID_TCP: + case MLX4_NET_TRANS_RULE_ID_UDP: + if (cur->tcp_udp.src_port) + len += snprintf(buf + len, BUF_SIZE - len, + "src-port = %d ", + be16_to_cpu(cur->tcp_udp.src_port)); + if (cur->tcp_udp.dst_port) + len += snprintf(buf + len, BUF_SIZE - len, + "dst-port = %d ", + be16_to_cpu(cur->tcp_udp.dst_port)); + break; + + case MLX4_NET_TRANS_RULE_ID_IB: + len += snprintf(buf + len, BUF_SIZE - len, + "dst-gid = %pI6\n", cur->ib.dst_gid); + len += snprintf(buf + len, BUF_SIZE - len, + "dst-gid-mask = %pI6\n", + cur->ib.dst_gid_msk); + break; + + case MLX4_NET_TRANS_RULE_ID_IPV6: + break; + + default: + break; + } + } + len += snprintf(buf + len, BUF_SIZE - len, "\n"); + mlx4_err(dev, "%s", buf); + + if (len >= BUF_SIZE) + mlx4_err(dev, "Network rule error message was truncated, print buffer is too small.\n"); +} + +int mlx4_flow_attach(struct mlx4_dev *dev, + struct mlx4_net_trans_rule *rule, u64 *reg_id) +{ + struct mlx4_cmd_mailbox *mailbox; + struct mlx4_spec_list *cur; + u32 size = 0; + int ret; + + mailbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + + memset(mailbox->buf, 0, sizeof(struct mlx4_net_trans_rule_hw_ctrl)); + trans_rule_ctrl_to_hw(rule, mailbox->buf); + + size += sizeof(struct mlx4_net_trans_rule_hw_ctrl); + + list_for_each_entry(cur, &rule->list, list) { + ret = parse_trans_rule(dev, cur, mailbox->buf + size); + if (ret < 0) { + mlx4_free_cmd_mailbox(dev, mailbox); + return -EINVAL; + } + size += ret; + } + + ret = mlx4_QP_FLOW_STEERING_ATTACH(dev, mailbox, size >> 2, reg_id); + if (ret == -ENOMEM) + mlx4_err_rule(dev, + "mcg table is full. Fail to register network rule.\n", + rule); + else if (ret) + mlx4_err_rule(dev, "Fail to register network rule.\n", rule); + + mlx4_free_cmd_mailbox(dev, mailbox); + + return ret; +} +EXPORT_SYMBOL_GPL(mlx4_flow_attach); + +int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id) +{ + int err; + + err = mlx4_QP_FLOW_STEERING_DETACH(dev, reg_id); + if (err) + mlx4_err(dev, "Fail to detach network rule. registration id = 0x%llx\n", + reg_id); + return err; +} +EXPORT_SYMBOL_GPL(mlx4_flow_detach); + int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], int block_mcast_loopback, enum mlx4_protocol prot, enum mlx4_steer_type steer) @@ -895,7 +1206,8 @@ static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp, } int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], - int block_mcast_loopback, enum mlx4_protocol prot) + u8 port, int block_mcast_loopback, + enum mlx4_protocol prot, u64 *reg_id) { switch (dev->caps.steering_mode) { @@ -914,6 +1226,42 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], block_mcast_loopback, prot, MLX4_MC_STEER); + case MLX4_STEERING_MODE_DEVICE_MANAGED: { + struct mlx4_spec_list spec = { {NULL} }; + __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); + + struct mlx4_net_trans_rule rule = { + .queue_mode = MLX4_NET_TRANS_Q_FIFO, + .exclusive = 0, + .promisc_mode = MLX4_FS_PROMISC_NONE, + .priority = MLX4_DOMAIN_NIC, + }; + + rule.allow_loopback = ~block_mcast_loopback; + rule.port = port; + rule.qpn = qp->qpn; + INIT_LIST_HEAD(&rule.list); + + switch (prot) { + case MLX4_PROT_ETH: + spec.id = MLX4_NET_TRANS_RULE_ID_ETH; + memcpy(spec.eth.dst_mac, &gid[10], ETH_ALEN); + memcpy(spec.eth.dst_mac_msk, &mac_mask, ETH_ALEN); + break; + + case MLX4_PROT_IB_IPV6: + spec.id = MLX4_NET_TRANS_RULE_ID_IB; + memcpy(spec.ib.dst_gid, gid, 16); + memset(&spec.ib.dst_gid_msk, 0xff, 16); + break; + default: + return -EINVAL; + } + list_add_tail(&spec.list, &rule.list); + + return mlx4_flow_attach(dev, &rule, reg_id); + } + default: return -EINVAL; } @@ -921,7 +1269,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], EXPORT_SYMBOL_GPL(mlx4_multicast_attach); int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], - enum mlx4_protocol prot) + enum mlx4_protocol prot, u64 reg_id) { switch (dev->caps.steering_mode) { case MLX4_STEERING_MODE_A0: @@ -938,6 +1286,9 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_MC_STEER); + case MLX4_STEERING_MODE_DEVICE_MANAGED: + return mlx4_flow_detach(dev, reg_id); + default: return -EINVAL; } @@ -1042,6 +1393,10 @@ int mlx4_init_mcg_table(struct mlx4_dev *dev) struct mlx4_priv *priv = mlx4_priv(dev); int err; + /* No need for mcg_table when fw managed the mcg table*/ + if (dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) + return 0; err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms, dev->caps.num_amgms - 1, 0, 0); if (err) @@ -1054,5 +1409,7 @@ int mlx4_init_mcg_table(struct mlx4_dev *dev) void mlx4_cleanup_mcg_table(struct mlx4_dev *dev) { - mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap); + if (dev->caps.steering_mode != + MLX4_STEERING_MODE_DEVICE_MANAGED) + mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap); } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index c07e882e8369..0084967be19e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -54,6 +54,17 @@ #define DRV_VERSION "1.1" #define DRV_RELDATE "Dec, 2011" +#define MLX4_FS_UDP_UC_EN (1 << 1) +#define MLX4_FS_TCP_UC_EN (1 << 2) +#define MLX4_FS_NUM_OF_L2_ADDR 8 +#define MLX4_FS_MGM_LOG_ENTRY_SIZE 7 +#define MLX4_FS_NUM_MCG (1 << 17) + +enum { + MLX4_FS_L2_HASH = 0, + MLX4_FS_L2_L3_L4_HASH, +}; + #define MLX4_NUM_UP 8 #define MLX4_NUM_TC 8 #define MLX4_RATELIMIT_UNITS 3 /* 100 Mbps */ @@ -704,6 +715,7 @@ struct mlx4_set_port_rqp_calc_context { struct mlx4_mac_entry { u64 mac; + u64 reg_id; }; struct mlx4_port_info { @@ -777,6 +789,7 @@ struct mlx4_priv { struct mutex bf_mutex; struct io_mapping *bf_mapping; int reserved_mtts; + int fs_hash_mode; }; static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 1bb00cd22d42..2d6dabe7f55d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -414,6 +414,7 @@ struct mlx4_en_mc_list { struct list_head list; enum mlx4_en_mclist_act action; u8 addr[ETH_ALEN]; + u64 reg_id; }; struct mlx4_en_frag_info { @@ -503,6 +504,7 @@ struct mlx4_en_priv { u64 stats_bitmap; struct list_head mc_list; struct list_head curr_list; + u64 broadcast_id; struct mlx4_en_stat_out_mbox hw_stats; int vids[128]; bool wol; diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 58de7237f57a..a51d1b9bf1d1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -75,21 +75,54 @@ void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table) table->total = 0; } -static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) +static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port, + u64 mac, int *qpn, u64 *reg_id) { - struct mlx4_qp qp; - u8 gid[16] = {0}; __be64 be_mac; int err; - qp.qpn = *qpn; - - mac &= 0xffffffffffffULL; + mac &= MLX4_MAC_MASK; be_mac = cpu_to_be64(mac << 16); - memcpy(&gid[10], &be_mac, ETH_ALEN); - gid[5] = port; - err = mlx4_unicast_attach(dev, &qp, gid, 0, MLX4_PROT_ETH); + switch (dev->caps.steering_mode) { + case MLX4_STEERING_MODE_B0: { + struct mlx4_qp qp; + u8 gid[16] = {0}; + + qp.qpn = *qpn; + memcpy(&gid[10], &be_mac, ETH_ALEN); + gid[5] = port; + + err = mlx4_unicast_attach(dev, &qp, gid, 0, MLX4_PROT_ETH); + break; + } + case MLX4_STEERING_MODE_DEVICE_MANAGED: { + struct mlx4_spec_list spec_eth = { {NULL} }; + __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); + + struct mlx4_net_trans_rule rule = { + .queue_mode = MLX4_NET_TRANS_Q_FIFO, + .exclusive = 0, + .allow_loopback = 1, + .promisc_mode = MLX4_FS_PROMISC_NONE, + .priority = MLX4_DOMAIN_NIC, + }; + + rule.port = port; + rule.qpn = *qpn; + INIT_LIST_HEAD(&rule.list); + + spec_eth.id = MLX4_NET_TRANS_RULE_ID_ETH; + memcpy(spec_eth.eth.dst_mac, &be_mac, ETH_ALEN); + memcpy(spec_eth.eth.dst_mac_msk, &mac_mask, ETH_ALEN); + list_add_tail(&spec_eth.list, &rule.list); + + err = mlx4_flow_attach(dev, &rule, reg_id); + break; + } + default: + return -EINVAL; + } if (err) mlx4_warn(dev, "Failed Attaching Unicast\n"); @@ -97,19 +130,30 @@ static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) } static void mlx4_uc_steer_release(struct mlx4_dev *dev, u8 port, - u64 mac, int qpn) + u64 mac, int qpn, u64 reg_id) { - struct mlx4_qp qp; - u8 gid[16] = {0}; - __be64 be_mac; + switch (dev->caps.steering_mode) { + case MLX4_STEERING_MODE_B0: { + struct mlx4_qp qp; + u8 gid[16] = {0}; + __be64 be_mac; - qp.qpn = qpn; - mac &= 0xffffffffffffULL; - be_mac = cpu_to_be64(mac << 16); - memcpy(&gid[10], &be_mac, ETH_ALEN); - gid[5] = port; + qp.qpn = qpn; + mac &= MLX4_MAC_MASK; + be_mac = cpu_to_be64(mac << 16); + memcpy(&gid[10], &be_mac, ETH_ALEN); + gid[5] = port; - mlx4_unicast_detach(dev, &qp, gid, MLX4_PROT_ETH); + mlx4_unicast_detach(dev, &qp, gid, MLX4_PROT_ETH); + break; + } + case MLX4_STEERING_MODE_DEVICE_MANAGED: { + mlx4_flow_detach(dev, reg_id); + break; + } + default: + mlx4_err(dev, "Invalid steering mode.\n"); + } } static int validate_index(struct mlx4_dev *dev, @@ -144,6 +188,7 @@ int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) struct mlx4_mac_entry *entry; int index = 0; int err = 0; + u64 reg_id; mlx4_dbg(dev, "Registering MAC: 0x%llx for adding\n", (unsigned long long) mac); @@ -167,7 +212,7 @@ int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) goto qp_err; } - err = mlx4_uc_steer_add(dev, port, mac, qpn); + err = mlx4_uc_steer_add(dev, port, mac, qpn, ®_id); if (err) goto steer_err; @@ -177,6 +222,7 @@ int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) goto alloc_err; } entry->mac = mac; + entry->reg_id = reg_id; err = radix_tree_insert(&info->mac_tree, *qpn, entry); if (err) goto insert_err; @@ -186,7 +232,7 @@ insert_err: kfree(entry); alloc_err: - mlx4_uc_steer_release(dev, port, mac, *qpn); + mlx4_uc_steer_release(dev, port, mac, *qpn, reg_id); steer_err: mlx4_qp_release_range(dev, *qpn, 1); @@ -212,7 +258,8 @@ void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn) mlx4_dbg(dev, "Releasing qp: port %d, mac 0x%llx," " qpn %d\n", port, (unsigned long long) mac, qpn); - mlx4_uc_steer_release(dev, port, entry->mac, qpn); + mlx4_uc_steer_release(dev, port, entry->mac, + qpn, entry->reg_id); mlx4_qp_release_range(dev, qpn, 1); radix_tree_delete(&info->mac_tree, qpn); kfree(entry); @@ -363,11 +410,14 @@ int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac) entry = radix_tree_lookup(&info->mac_tree, qpn); if (!entry) return -EINVAL; - mlx4_uc_steer_release(dev, port, entry->mac, qpn); + mlx4_uc_steer_release(dev, port, entry->mac, + qpn, entry->reg_id); mlx4_unregister_mac(dev, port, entry->mac); entry->mac = new_mac; + entry->reg_id = 0; mlx4_register_mac(dev, port, new_mac); - err = mlx4_uc_steer_add(dev, port, entry->mac, &qpn); + err = mlx4_uc_steer_add(dev, port, entry->mac, + &qpn, &entry->reg_id); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index b83bc928d52a..9ee4725363d5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c @@ -237,13 +237,19 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, init_hca->mtt_base = profile[i].start; break; case MLX4_RES_MCG: - dev->caps.num_mgms = profile[i].num >> 1; - dev->caps.num_amgms = profile[i].num >> 1; init_hca->mc_base = profile[i].start; init_hca->log_mc_entry_sz = ilog2(mlx4_get_mgm_entry_size(dev)); init_hca->log_mc_table_sz = profile[i].log_num; - init_hca->log_mc_hash_sz = profile[i].log_num - 1; + if (dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + dev->caps.num_mgms = profile[i].num; + } else { + init_hca->log_mc_hash_sz = + profile[i].log_num - 1; + dev->caps.num_mgms = profile[i].num >> 1; + dev->caps.num_amgms = profile[i].num >> 1; + } break; default: break; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index a8ca960f4620..5a6f3555d806 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2744,6 +2744,9 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd) { + if (dev->caps.steering_mode != + MLX4_STEERING_MODE_DEVICE_MANAGED) + return -EOPNOTSUPP; return mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, vhcr->in_modifier, 0, MLX4_QP_FLOW_STEERING_ATTACH, @@ -2757,6 +2760,9 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd) { + if (dev->caps.steering_mode != + MLX4_STEERING_MODE_DEVICE_MANAGED) + return -EOPNOTSUPP; return mlx4_cmd(dev, vhcr->in_param, 0, 0, MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 7f5c9ee42f96..e45fc20bd01f 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -70,14 +70,17 @@ enum { MLX4_MFUNC_EQE_MASK = (MLX4_MFUNC_MAX_EQES - 1) }; -/* Driver supports 2 diffrent device methods to manage traffic steering: +/* Driver supports 3 diffrent device methods to manage traffic steering: + * -device managed - High level API for ib and eth flow steering. FW is + * managing flow steering tables. * - B0 steering mode - Common low level API for ib and (if supported) eth. * - A0 steering mode - Limited low level API for eth. In case of IB, * B0 mode is in use. */ enum { MLX4_STEERING_MODE_A0, - MLX4_STEERING_MODE_B0 + MLX4_STEERING_MODE_B0, + MLX4_STEERING_MODE_DEVICE_MANAGED }; static inline const char *mlx4_steering_mode_str(int steering_mode) @@ -88,6 +91,10 @@ static inline const char *mlx4_steering_mode_str(int steering_mode) case MLX4_STEERING_MODE_B0: return "B0 steering"; + + case MLX4_STEERING_MODE_DEVICE_MANAGED: + return "Device managed flow steering"; + default: return "Unrecognize steering mode"; } @@ -125,7 +132,8 @@ enum { enum { MLX4_DEV_CAP_FLAG2_RSS = 1LL << 0, MLX4_DEV_CAP_FLAG2_RSS_TOP = 1LL << 1, - MLX4_DEV_CAP_FLAG2_RSS_XOR = 1LL << 2 + MLX4_DEV_CAP_FLAG2_RSS_XOR = 1LL << 2, + MLX4_DEV_CAP_FLAG2_FS_EN = 1LL << 3 }; #define MLX4_ATTR_EXTENDED_PORT_INFO cpu_to_be16(0xff90) @@ -319,6 +327,7 @@ struct mlx4_caps { int reserved_mcgs; int num_qp_per_mgm; int steering_mode; + int fs_log_max_ucast_qp_range_size; int num_pds; int reserved_pds; int max_xrcds; @@ -647,9 +656,94 @@ int mlx4_unicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], enum mlx4_protocol prot); int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], - int block_mcast_loopback, enum mlx4_protocol protocol); + u8 port, int block_mcast_loopback, + enum mlx4_protocol protocol, u64 *reg_id); int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], - enum mlx4_protocol protocol); + enum mlx4_protocol protocol, u64 reg_id); + +enum { + MLX4_DOMAIN_UVERBS = 0x1000, + MLX4_DOMAIN_ETHTOOL = 0x2000, + MLX4_DOMAIN_RFS = 0x3000, + MLX4_DOMAIN_NIC = 0x5000, +}; + +enum mlx4_net_trans_rule_id { + MLX4_NET_TRANS_RULE_ID_ETH = 0, + MLX4_NET_TRANS_RULE_ID_IB, + MLX4_NET_TRANS_RULE_ID_IPV6, + MLX4_NET_TRANS_RULE_ID_IPV4, + MLX4_NET_TRANS_RULE_ID_TCP, + MLX4_NET_TRANS_RULE_ID_UDP, + MLX4_NET_TRANS_RULE_NUM, /* should be last */ +}; + +enum mlx4_net_trans_promisc_mode { + MLX4_FS_PROMISC_NONE = 0, + MLX4_FS_PROMISC_UPLINK, + MLX4_FS_PROMISC_FUNCTION_PORT, + MLX4_FS_PROMISC_ALL_MULTI, +}; + +struct mlx4_spec_eth { + u8 dst_mac[6]; + u8 dst_mac_msk[6]; + u8 src_mac[6]; + u8 src_mac_msk[6]; + u8 ether_type_enable; + __be16 ether_type; + __be16 vlan_id_msk; + __be16 vlan_id; +}; + +struct mlx4_spec_tcp_udp { + __be16 dst_port; + __be16 dst_port_msk; + __be16 src_port; + __be16 src_port_msk; +}; + +struct mlx4_spec_ipv4 { + __be32 dst_ip; + __be32 dst_ip_msk; + __be32 src_ip; + __be32 src_ip_msk; +}; + +struct mlx4_spec_ib { + __be32 r_qpn; + __be32 qpn_msk; + u8 dst_gid[16]; + u8 dst_gid_msk[16]; +}; + +struct mlx4_spec_list { + struct list_head list; + enum mlx4_net_trans_rule_id id; + union { + struct mlx4_spec_eth eth; + struct mlx4_spec_ib ib; + struct mlx4_spec_ipv4 ipv4; + struct mlx4_spec_tcp_udp tcp_udp; + }; +}; + +enum mlx4_net_trans_hw_rule_queue { + MLX4_NET_TRANS_Q_FIFO, + MLX4_NET_TRANS_Q_LIFO, +}; + +struct mlx4_net_trans_rule { + struct list_head list; + enum mlx4_net_trans_hw_rule_queue queue_mode; + bool exclusive; + bool allow_loopback; + enum mlx4_net_trans_promisc_mode promisc_mode; + u8 port; + u16 priority; + u32 qpn; +}; + int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port); int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); @@ -692,4 +786,8 @@ int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port); int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx); void mlx4_counter_free(struct mlx4_dev *dev, u32 idx); +int mlx4_flow_attach(struct mlx4_dev *dev, + struct mlx4_net_trans_rule *rule, u64 *reg_id); +int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id); + #endif /* MLX4_DEVICE_H */ -- GitLab From 1b9c6b064ef4fbc6f55485a8b5aab7ce889592c2 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:47 +0000 Subject: [PATCH 4189/6849] net/mlx4_core: Add resource tracking for device managed flow steering rules As with other device resources, the resource tracker is needed for supporting device managed flow steering rules under SRIOV: make sure virtual functions delete only rules created by them, and clean all rules attached by a crashed VF. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1 + .../ethernet/mellanox/mlx4/resource_tracker.c | 132 ++++++++++++++++-- 2 files changed, 125 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 0084967be19e..d2c436b10fbf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -149,6 +149,7 @@ enum mlx4_resource { RES_VLAN, RES_EQ, RES_COUNTER, + RES_FS_RULE, MLX4_NUM_OF_RESOURCE_TYPE }; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 5a6f3555d806..c3fa91986190 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -190,6 +190,15 @@ struct res_xrcdn { int port; }; +enum res_fs_rule_states { + RES_FS_RULE_BUSY = RES_ANY_BUSY, + RES_FS_RULE_ALLOCATED, +}; + +struct res_fs_rule { + struct res_common com; +}; + static void *res_tracker_lookup(struct rb_root *root, u64 res_id) { struct rb_node *node = root->rb_node; @@ -245,6 +254,7 @@ static const char *ResourceType(enum mlx4_resource rt) case RES_MAC: return "RES_MAC"; case RES_EQ: return "RES_EQ"; case RES_COUNTER: return "RES_COUNTER"; + case RES_FS_RULE: return "RES_FS_RULE"; case RES_XRCD: return "RES_XRCD"; default: return "Unknown resource type !!!"; }; @@ -516,6 +526,20 @@ static struct res_common *alloc_xrcdn_tr(int id) return &ret->com; } +static struct res_common *alloc_fs_rule_tr(u64 id) +{ + struct res_fs_rule *ret; + + ret = kzalloc(sizeof *ret, GFP_KERNEL); + if (!ret) + return NULL; + + ret->com.res_id = id; + ret->com.state = RES_FS_RULE_ALLOCATED; + + return &ret->com; +} + static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave, int extra) { @@ -549,6 +573,9 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave, case RES_XRCD: ret = alloc_xrcdn_tr(id); break; + case RES_FS_RULE: + ret = alloc_fs_rule_tr(id); + break; default: return NULL; } @@ -681,6 +708,16 @@ static int remove_xrcdn_ok(struct res_xrcdn *res) return 0; } +static int remove_fs_rule_ok(struct res_fs_rule *res) +{ + if (res->com.state == RES_FS_RULE_BUSY) + return -EBUSY; + else if (res->com.state != RES_FS_RULE_ALLOCATED) + return -EPERM; + + return 0; +} + static int remove_cq_ok(struct res_cq *res) { if (res->com.state == RES_CQ_BUSY) @@ -722,6 +759,8 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra) return remove_counter_ok((struct res_counter *)res); case RES_XRCD: return remove_xrcdn_ok((struct res_xrcdn *)res); + case RES_FS_RULE: + return remove_fs_rule_ok((struct res_fs_rule *)res); default: return -EINVAL; } @@ -2744,14 +2783,28 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd) { + int err; + if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) return -EOPNOTSUPP; - return mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, - vhcr->in_modifier, 0, - MLX4_QP_FLOW_STEERING_ATTACH, - MLX4_CMD_TIME_CLASS_A, - MLX4_CMD_NATIVE); + + err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, + vhcr->in_modifier, 0, + MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + if (err) + return err; + + err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0); + if (err) { + mlx4_err(dev, "Fail to add flow steering resources.\n "); + /* detach rule*/ + mlx4_cmd(dev, vhcr->out_param, 0, 0, + MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + } + return err; } int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, @@ -2760,12 +2813,22 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd) { + int err; + if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) return -EOPNOTSUPP; - return mlx4_cmd(dev, vhcr->in_param, 0, 0, - MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, - MLX4_CMD_NATIVE); + + err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0); + if (err) { + mlx4_err(dev, "Fail to remove flow steering resources.\n "); + return err; + } + + err = mlx4_cmd(dev, vhcr->in_param, 0, 0, + MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + return err; } enum { @@ -3177,6 +3240,58 @@ static void rem_slave_mtts(struct mlx4_dev *dev, int slave) spin_unlock_irq(mlx4_tlock(dev)); } +static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + struct mlx4_resource_tracker *tracker = + &priv->mfunc.master.res_tracker; + struct list_head *fs_rule_list = + &tracker->slave_list[slave].res_list[RES_FS_RULE]; + struct res_fs_rule *fs_rule; + struct res_fs_rule *tmp; + int state; + u64 base; + int err; + + err = move_all_busy(dev, slave, RES_FS_RULE); + if (err) + mlx4_warn(dev, "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n", + slave); + + spin_lock_irq(mlx4_tlock(dev)); + list_for_each_entry_safe(fs_rule, tmp, fs_rule_list, com.list) { + spin_unlock_irq(mlx4_tlock(dev)); + if (fs_rule->com.owner == slave) { + base = fs_rule->com.res_id; + state = fs_rule->com.from_state; + while (state != 0) { + switch (state) { + case RES_FS_RULE_ALLOCATED: + /* detach rule */ + err = mlx4_cmd(dev, base, 0, 0, + MLX4_QP_FLOW_STEERING_DETACH, + MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + + spin_lock_irq(mlx4_tlock(dev)); + rb_erase(&fs_rule->com.node, + &tracker->res_tree[RES_FS_RULE]); + list_del(&fs_rule->com.list); + spin_unlock_irq(mlx4_tlock(dev)); + kfree(fs_rule); + state = 0; + break; + + default: + state = 0; + } + } + } + spin_lock_irq(mlx4_tlock(dev)); + } + spin_unlock_irq(mlx4_tlock(dev)); +} + static void rem_slave_eqs(struct mlx4_dev *dev, int slave) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -3318,5 +3433,6 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) rem_slave_mtts(dev, slave); rem_slave_counters(dev, slave); rem_slave_xrcdns(dev, slave); + rem_slave_fs_rule(dev, slave); mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); } -- GitLab From 592e49dda8122ab621cdc59cc429bdb968ee6364 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:48 +0000 Subject: [PATCH 4190/6849] net/mlx4: Implement promiscuous mode with device managed flow-steering The device managed flow steering API has three promiscuous modes: 1. Uplink - captures all the packets that arrive to the port. 2. Allmulti - captures all multicast packets arriving to the port. 3. Function port - for future use, this mode is not implemented yet. Use these modes with the flow_attach and flow_detach firmware commands according to the promiscuous state of the netdevice. Signed-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_netdev.c | 41 +++++++++++++ drivers/net/ethernet/mellanox/mlx4/mcg.c | 60 +++++++++++++++++++ include/linux/mlx4/device.h | 7 +++ 3 files changed, 108 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index eb5ed8e39873..b7945a80ad15 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -301,6 +301,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) /* Enable promiscouos mode */ switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_DEVICE_MANAGED: + err = mlx4_flow_steer_promisc_add(mdev->dev, + priv->port, + priv->base_qpn, + MLX4_FS_PROMISC_UPLINK); + if (err) + en_err(priv, "Failed enabling promiscuous mode\n"); + priv->flags |= MLX4_EN_FLAG_MC_PROMISC; + break; + case MLX4_STEERING_MODE_B0: err = mlx4_unicast_promisc_add(mdev->dev, priv->base_qpn, @@ -357,6 +367,15 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) /* Disable promiscouos mode */ switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_DEVICE_MANAGED: + err = mlx4_flow_steer_promisc_remove(mdev->dev, + priv->port, + MLX4_FS_PROMISC_UPLINK); + if (err) + en_err(priv, "Failed disabling promiscuous mode\n"); + priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; + break; + case MLX4_STEERING_MODE_B0: err = mlx4_unicast_promisc_remove(mdev->dev, priv->base_qpn, @@ -399,6 +418,13 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) /* Add the default qp number as multicast promisc */ if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_DEVICE_MANAGED: + err = mlx4_flow_steer_promisc_add(mdev->dev, + priv->port, + priv->base_qpn, + MLX4_FS_PROMISC_ALL_MULTI); + break; + case MLX4_STEERING_MODE_B0: err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn, @@ -416,6 +442,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) /* Disable Multicast promisc */ if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { switch (mdev->dev->caps.steering_mode) { + case MLX4_STEERING_MODE_DEVICE_MANAGED: + err = mlx4_flow_steer_promisc_remove(mdev->dev, + priv->port, + MLX4_FS_PROMISC_ALL_MULTI); + break; + case MLX4_STEERING_MODE_B0: err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, @@ -839,6 +871,15 @@ int mlx4_en_start_port(struct net_device *dev) /* Must redo promiscuous mode setup. */ priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC); + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { + mlx4_flow_steer_promisc_remove(mdev->dev, + priv->port, + MLX4_FS_PROMISC_UPLINK); + mlx4_flow_steer_promisc_remove(mdev->dev, + priv->port, + MLX4_FS_PROMISC_ALL_MULTI); + } /* Schedule multicast task to populate multicast list */ queue_work(mdev->workqueue, &priv->mcast_task); diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 768a2a4530e8..bc62f536ffae 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -1295,6 +1295,66 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], } EXPORT_SYMBOL_GPL(mlx4_multicast_detach); +int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, + u32 qpn, enum mlx4_net_trans_promisc_mode mode) +{ + struct mlx4_net_trans_rule rule; + u64 *regid_p; + + switch (mode) { + case MLX4_FS_PROMISC_UPLINK: + case MLX4_FS_PROMISC_FUNCTION_PORT: + regid_p = &dev->regid_promisc_array[port]; + break; + case MLX4_FS_PROMISC_ALL_MULTI: + regid_p = &dev->regid_allmulti_array[port]; + break; + default: + return -1; + } + + if (*regid_p != 0) + return -1; + + rule.promisc_mode = mode; + rule.port = port; + rule.qpn = qpn; + INIT_LIST_HEAD(&rule.list); + mlx4_err(dev, "going promisc on %x\n", port); + + return mlx4_flow_attach(dev, &rule, regid_p); +} +EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add); + +int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port, + enum mlx4_net_trans_promisc_mode mode) +{ + int ret; + u64 *regid_p; + + switch (mode) { + case MLX4_FS_PROMISC_UPLINK: + case MLX4_FS_PROMISC_FUNCTION_PORT: + regid_p = &dev->regid_promisc_array[port]; + break; + case MLX4_FS_PROMISC_ALL_MULTI: + regid_p = &dev->regid_allmulti_array[port]; + break; + default: + return -1; + } + + if (*regid_p == 0) + return -1; + + ret = mlx4_flow_detach(dev, *regid_p); + if (ret == 0) + *regid_p = 0; + + return ret; +} +EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove); + int mlx4_unicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], int block_mcast_loopback, enum mlx4_protocol prot) diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index e45fc20bd01f..6f0d133cc7ad 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -542,6 +542,8 @@ struct mlx4_dev { u8 rev_id; char board_id[MLX4_BOARD_ID_LEN]; int num_vfs; + u64 regid_promisc_array[MLX4_MAX_PORTS + 1]; + u64 regid_allmulti_array[MLX4_MAX_PORTS + 1]; }; struct mlx4_init_port_param { @@ -681,6 +683,7 @@ enum mlx4_net_trans_rule_id { enum mlx4_net_trans_promisc_mode { MLX4_FS_PROMISC_NONE = 0, MLX4_FS_PROMISC_UPLINK, + /* For future use. Not implemented yet */ MLX4_FS_PROMISC_FUNCTION_PORT, MLX4_FS_PROMISC_ALL_MULTI, }; @@ -744,6 +747,10 @@ struct mlx4_net_trans_rule { u32 qpn; }; +int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn, + enum mlx4_net_trans_promisc_mode mode); +int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port, + enum mlx4_net_trans_promisc_mode mode); int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port); int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); -- GitLab From 820672812f8284143f933da8ccc60e296230d25d Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:49 +0000 Subject: [PATCH 4191/6849] net/mlx4_en: Manage flow steering rules with ethtool Implement the ethtool APIs for attaching L2/L3/L4 based flow steering rules to the netdevice RX rings. Added set_rxnfc callback and enhanced the existing get_rxnfc callback. Signed-off-by: Hadar Hen Zion Signed-off-by: Amir Vadai Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 382 ++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 7 + 2 files changed, 389 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 72901ce2b088..3e72a2076fb5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -38,6 +38,10 @@ #include "mlx4_en.h" #include "en_port.h" +#define EN_ETHTOOL_QP_ATTACH (1ull << 63) +#define EN_ETHTOOL_MAC_MASK 0xffffffffffffULL +#define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) +#define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) static void mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) @@ -599,16 +603,369 @@ static int mlx4_en_set_rxfh_indir(struct net_device *dev, return err; } +#define all_zeros_or_all_ones(field) \ + ((field) == 0 || (field) == (__force typeof(field))-1) + +static int mlx4_en_validate_flow(struct net_device *dev, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_usrip4_spec *l3_mask; + struct ethtool_tcpip4_spec *l4_mask; + struct ethhdr *eth_mask; + u64 full_mac = ~0ull; + u64 zero_mac = 0; + + if (cmd->fs.location >= MAX_NUM_OF_FS_RULES) + return -EINVAL; + + switch (cmd->fs.flow_type & ~FLOW_EXT) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + if (cmd->fs.m_u.tcp_ip4_spec.tos) + return -EINVAL; + l4_mask = &cmd->fs.m_u.tcp_ip4_spec; + /* don't allow mask which isn't all 0 or 1 */ + if (!all_zeros_or_all_ones(l4_mask->ip4src) || + !all_zeros_or_all_ones(l4_mask->ip4dst) || + !all_zeros_or_all_ones(l4_mask->psrc) || + !all_zeros_or_all_ones(l4_mask->pdst)) + return -EINVAL; + break; + case IP_USER_FLOW: + l3_mask = &cmd->fs.m_u.usr_ip4_spec; + if (l3_mask->l4_4_bytes || l3_mask->tos || l3_mask->proto || + cmd->fs.h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4 || + (!l3_mask->ip4src && !l3_mask->ip4dst) || + !all_zeros_or_all_ones(l3_mask->ip4src) || + !all_zeros_or_all_ones(l3_mask->ip4dst)) + return -EINVAL; + break; + case ETHER_FLOW: + eth_mask = &cmd->fs.m_u.ether_spec; + /* source mac mask must not be set */ + if (memcmp(eth_mask->h_source, &zero_mac, ETH_ALEN)) + return -EINVAL; + + /* dest mac mask must be ff:ff:ff:ff:ff:ff */ + if (memcmp(eth_mask->h_dest, &full_mac, ETH_ALEN)) + return -EINVAL; + + if (!all_zeros_or_all_ones(eth_mask->h_proto)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + if ((cmd->fs.flow_type & FLOW_EXT)) { + if (cmd->fs.m_ext.vlan_etype || + !(cmd->fs.m_ext.vlan_tci == 0 || + cmd->fs.m_ext.vlan_tci == cpu_to_be16(0xfff))) + return -EINVAL; + } + + return 0; +} + +static int add_ip_rule(struct mlx4_en_priv *priv, + struct ethtool_rxnfc *cmd, + struct list_head *list_h) +{ + struct mlx4_spec_list *spec_l3; + struct ethtool_usrip4_spec *l3_mask = &cmd->fs.m_u.usr_ip4_spec; + + spec_l3 = kzalloc(sizeof *spec_l3, GFP_KERNEL); + if (!spec_l3) { + en_err(priv, "Fail to alloc ethtool rule.\n"); + return -ENOMEM; + } + + spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4; + spec_l3->ipv4.src_ip = cmd->fs.h_u.usr_ip4_spec.ip4src; + if (l3_mask->ip4src) + spec_l3->ipv4.src_ip_msk = EN_ETHTOOL_WORD_MASK; + spec_l3->ipv4.dst_ip = cmd->fs.h_u.usr_ip4_spec.ip4dst; + if (l3_mask->ip4dst) + spec_l3->ipv4.dst_ip_msk = EN_ETHTOOL_WORD_MASK; + list_add_tail(&spec_l3->list, list_h); + + return 0; +} + +static int add_tcp_udp_rule(struct mlx4_en_priv *priv, + struct ethtool_rxnfc *cmd, + struct list_head *list_h, int proto) +{ + struct mlx4_spec_list *spec_l3; + struct mlx4_spec_list *spec_l4; + struct ethtool_tcpip4_spec *l4_mask = &cmd->fs.m_u.tcp_ip4_spec; + + spec_l3 = kzalloc(sizeof *spec_l3, GFP_KERNEL); + spec_l4 = kzalloc(sizeof *spec_l4, GFP_KERNEL); + if (!spec_l4 || !spec_l3) { + en_err(priv, "Fail to alloc ethtool rule.\n"); + kfree(spec_l3); + kfree(spec_l4); + return -ENOMEM; + } + + spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4; + + if (proto == TCP_V4_FLOW) { + spec_l4->id = MLX4_NET_TRANS_RULE_ID_TCP; + spec_l3->ipv4.src_ip = cmd->fs.h_u.tcp_ip4_spec.ip4src; + spec_l3->ipv4.dst_ip = cmd->fs.h_u.tcp_ip4_spec.ip4dst; + spec_l4->tcp_udp.src_port = cmd->fs.h_u.tcp_ip4_spec.psrc; + spec_l4->tcp_udp.dst_port = cmd->fs.h_u.tcp_ip4_spec.pdst; + } else { + spec_l4->id = MLX4_NET_TRANS_RULE_ID_UDP; + spec_l3->ipv4.src_ip = cmd->fs.h_u.udp_ip4_spec.ip4src; + spec_l3->ipv4.dst_ip = cmd->fs.h_u.udp_ip4_spec.ip4dst; + spec_l4->tcp_udp.src_port = cmd->fs.h_u.udp_ip4_spec.psrc; + spec_l4->tcp_udp.dst_port = cmd->fs.h_u.udp_ip4_spec.pdst; + } + + if (l4_mask->ip4src) + spec_l3->ipv4.src_ip_msk = EN_ETHTOOL_WORD_MASK; + if (l4_mask->ip4dst) + spec_l3->ipv4.dst_ip_msk = EN_ETHTOOL_WORD_MASK; + + if (l4_mask->psrc) + spec_l4->tcp_udp.src_port_msk = EN_ETHTOOL_SHORT_MASK; + if (l4_mask->pdst) + spec_l4->tcp_udp.dst_port_msk = EN_ETHTOOL_SHORT_MASK; + + list_add_tail(&spec_l3->list, list_h); + list_add_tail(&spec_l4->list, list_h); + + return 0; +} + +static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev, + struct ethtool_rxnfc *cmd, + struct list_head *rule_list_h) +{ + int err; + u64 mac; + __be64 be_mac; + struct ethhdr *eth_spec; + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_spec_list *spec_l2; + __be64 mac_msk = cpu_to_be64(EN_ETHTOOL_MAC_MASK << 16); + + err = mlx4_en_validate_flow(dev, cmd); + if (err) + return err; + + spec_l2 = kzalloc(sizeof *spec_l2, GFP_KERNEL); + if (!spec_l2) + return -ENOMEM; + + mac = priv->mac & EN_ETHTOOL_MAC_MASK; + be_mac = cpu_to_be64(mac << 16); + + spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH; + memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN); + if ((cmd->fs.flow_type & ~FLOW_EXT) != ETHER_FLOW) + memcpy(spec_l2->eth.dst_mac, &be_mac, ETH_ALEN); + + if ((cmd->fs.flow_type & FLOW_EXT) && cmd->fs.m_ext.vlan_tci) { + spec_l2->eth.vlan_id = cmd->fs.h_ext.vlan_tci; + spec_l2->eth.vlan_id_msk = cpu_to_be16(0xfff); + } + + list_add_tail(&spec_l2->list, rule_list_h); + + switch (cmd->fs.flow_type & ~FLOW_EXT) { + case ETHER_FLOW: + eth_spec = &cmd->fs.h_u.ether_spec; + memcpy(&spec_l2->eth.dst_mac, eth_spec->h_dest, ETH_ALEN); + spec_l2->eth.ether_type = eth_spec->h_proto; + if (eth_spec->h_proto) + spec_l2->eth.ether_type_enable = 1; + break; + case IP_USER_FLOW: + err = add_ip_rule(priv, cmd, rule_list_h); + break; + case TCP_V4_FLOW: + err = add_tcp_udp_rule(priv, cmd, rule_list_h, TCP_V4_FLOW); + break; + case UDP_V4_FLOW: + err = add_tcp_udp_rule(priv, cmd, rule_list_h, UDP_V4_FLOW); + break; + } + + return err; +} + +static int mlx4_en_flow_replace(struct net_device *dev, + struct ethtool_rxnfc *cmd) +{ + int err; + struct mlx4_en_priv *priv = netdev_priv(dev); + struct ethtool_flow_id *loc_rule; + struct mlx4_spec_list *spec, *tmp_spec; + u32 qpn; + u64 reg_id; + + struct mlx4_net_trans_rule rule = { + .queue_mode = MLX4_NET_TRANS_Q_FIFO, + .exclusive = 0, + .allow_loopback = 1, + .promisc_mode = MLX4_FS_PROMISC_NONE, + }; + + rule.port = priv->port; + rule.priority = MLX4_DOMAIN_ETHTOOL | cmd->fs.location; + INIT_LIST_HEAD(&rule.list); + + /* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */ + if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC) + return -EINVAL; + else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { + qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); + } else { + if (cmd->fs.ring_cookie >= priv->rx_ring_num) { + en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist.\n", + cmd->fs.ring_cookie); + return -EINVAL; + } + qpn = priv->rss_map.qps[cmd->fs.ring_cookie].qpn; + if (!qpn) { + en_warn(priv, "rxnfc: RX ring (%llu) is inactive.\n", + cmd->fs.ring_cookie); + return -EINVAL; + } + } + rule.qpn = qpn; + err = mlx4_en_ethtool_to_net_trans_rule(dev, cmd, &rule.list); + if (err) + goto out_free_list; + + loc_rule = &priv->ethtool_rules[cmd->fs.location]; + if (loc_rule->id) { + err = mlx4_flow_detach(priv->mdev->dev, loc_rule->id); + if (err) { + en_err(priv, "Fail to detach network rule at location %d. registration id = %llx\n", + cmd->fs.location, loc_rule->id); + goto out_free_list; + } + loc_rule->id = 0; + memset(&loc_rule->flow_spec, 0, + sizeof(struct ethtool_rx_flow_spec)); + } + err = mlx4_flow_attach(priv->mdev->dev, &rule, ®_id); + if (err) { + en_err(priv, "Fail to attach network rule at location %d.\n", + cmd->fs.location); + goto out_free_list; + } + loc_rule->id = reg_id; + memcpy(&loc_rule->flow_spec, &cmd->fs, + sizeof(struct ethtool_rx_flow_spec)); + +out_free_list: + list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) { + list_del(&spec->list); + kfree(spec); + } + return err; +} + +static int mlx4_en_flow_detach(struct net_device *dev, + struct ethtool_rxnfc *cmd) +{ + int err = 0; + struct ethtool_flow_id *rule; + struct mlx4_en_priv *priv = netdev_priv(dev); + + if (cmd->fs.location >= MAX_NUM_OF_FS_RULES) + return -EINVAL; + + rule = &priv->ethtool_rules[cmd->fs.location]; + if (!rule->id) { + err = -ENOENT; + goto out; + } + + err = mlx4_flow_detach(priv->mdev->dev, rule->id); + if (err) { + en_err(priv, "Fail to detach network rule at location %d. registration id = 0x%llx\n", + cmd->fs.location, rule->id); + goto out; + } + rule->id = 0; + memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec)); +out: + return err; + +} + +static int mlx4_en_get_flow(struct net_device *dev, struct ethtool_rxnfc *cmd, + int loc) +{ + int err = 0; + struct ethtool_flow_id *rule; + struct mlx4_en_priv *priv = netdev_priv(dev); + + if (loc < 0 || loc >= MAX_NUM_OF_FS_RULES) + return -EINVAL; + + rule = &priv->ethtool_rules[loc]; + if (rule->id) + memcpy(&cmd->fs, &rule->flow_spec, + sizeof(struct ethtool_rx_flow_spec)); + else + err = -ENOENT; + + return err; +} + +static int mlx4_en_get_num_flows(struct mlx4_en_priv *priv) +{ + + int i, res = 0; + for (i = 0; i < MAX_NUM_OF_FS_RULES; i++) { + if (priv->ethtool_rules[i].id) + res++; + } + return res; + +} + static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, u32 *rule_locs) { struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; int err = 0; + int i = 0, priority = 0; + + if ((cmd->cmd == ETHTOOL_GRXCLSRLCNT || + cmd->cmd == ETHTOOL_GRXCLSRULE || + cmd->cmd == ETHTOOL_GRXCLSRLALL) && + mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) + return -EINVAL; switch (cmd->cmd) { case ETHTOOL_GRXRINGS: cmd->data = priv->rx_ring_num; break; + case ETHTOOL_GRXCLSRLCNT: + cmd->rule_cnt = mlx4_en_get_num_flows(priv); + break; + case ETHTOOL_GRXCLSRULE: + err = mlx4_en_get_flow(dev, cmd, cmd->fs.location); + break; + case ETHTOOL_GRXCLSRLALL: + while ((!err || err == -ENOENT) && priority < cmd->rule_cnt) { + err = mlx4_en_get_flow(dev, cmd, i); + if (!err) + rule_locs[priority++] = i; + i++; + } + err = 0; + break; default: err = -EOPNOTSUPP; break; @@ -617,6 +974,30 @@ static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, return err; } +static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + int err = 0; + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + + if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) + return -EINVAL; + + switch (cmd->cmd) { + case ETHTOOL_SRXCLSRLINS: + err = mlx4_en_flow_replace(dev, cmd); + break; + case ETHTOOL_SRXCLSRLDEL: + err = mlx4_en_flow_detach(dev, cmd); + break; + default: + en_warn(priv, "Unsupported ethtool command. (%d)\n", cmd->cmd); + return -EINVAL; + } + + return err; +} + const struct ethtool_ops mlx4_en_ethtool_ops = { .get_drvinfo = mlx4_en_get_drvinfo, .get_settings = mlx4_en_get_settings, @@ -637,6 +1018,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_ringparam = mlx4_en_get_ringparam, .set_ringparam = mlx4_en_set_ringparam, .get_rxnfc = mlx4_en_get_rxnfc, + .set_rxnfc = mlx4_en_set_rxnfc, .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, .get_rxfh_indir = mlx4_en_get_rxfh_indir, .set_rxfh_indir = mlx4_en_set_rxfh_indir, diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 2d6dabe7f55d..8882e70493fe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -75,6 +75,7 @@ #define STAMP_SHIFT 31 #define STAMP_VAL 0x7fffffff #define STATS_DELAY (HZ / 4) +#define MAX_NUM_OF_FS_RULES 256 /* Typical TSO descriptor with 16 gather entries is 352 bytes... */ #define MAX_DESC_SIZE 512 @@ -435,6 +436,11 @@ struct mlx4_en_frag_info { #endif +struct ethtool_flow_id { + struct ethtool_rx_flow_spec flow_spec; + u64 id; +}; + struct mlx4_en_priv { struct mlx4_en_dev *mdev; struct mlx4_en_port_profile *prof; @@ -444,6 +450,7 @@ struct mlx4_en_priv { struct net_device_stats ret_stats; struct mlx4_en_port_state port_state; spinlock_t stats_lock; + struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES]; unsigned long last_moder_packets[MAX_RX_RINGS]; unsigned long last_moder_tx_packets; -- GitLab From cabdc8ee3768ceb6367e88c6fe84a66dd667bdf9 Mon Sep 17 00:00:00 2001 From: Hadar Hen Zion Date: Thu, 5 Jul 2012 04:03:50 +0000 Subject: [PATCH 4192/6849] net/mlx4_en: Add support for drop action through ethtool The drop action is implemented by allocating a QP and keeping it in a reset state such that the HW drops any packets which are steered to that QP. When a drop action is requested, we attach the relevant flow to that QP. Sign-off-by: Hadar Hen Zion Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 9 +++++- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 30 +++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 ++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 3e72a2076fb5..dd6a77b21149 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -821,7 +821,7 @@ static int mlx4_en_flow_replace(struct net_device *dev, /* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */ if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC) - return -EINVAL; + qpn = priv->drop_qp.qpn; else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); } else { diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index b7945a80ad15..94375a8c6d42 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -796,6 +796,10 @@ int mlx4_en_start_port(struct net_device *dev) goto mac_err; } + err = mlx4_en_create_drop_qp(priv); + if (err) + goto rss_err; + /* Configure tx cq's and rings */ for (i = 0; i < priv->tx_ring_num; i++) { /* Configure cq */ @@ -895,7 +899,8 @@ tx_err: mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]); mlx4_en_deactivate_cq(priv, &priv->tx_cq[tx_index]); } - + mlx4_en_destroy_drop_qp(priv); +rss_err: mlx4_en_release_rss_steer(priv); mac_err: mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn); @@ -950,6 +955,8 @@ void mlx4_en_stop_port(struct net_device *dev) /* Flush multicast filter */ mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); + mlx4_en_destroy_drop_qp(priv); + /* Free TX Rings */ for (i = 0; i < priv->tx_ring_num; i++) { mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index d49a7ac3187d..a04cbf767eb5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -844,6 +844,36 @@ out: return err; } +int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv) +{ + int err; + u32 qpn; + + err = mlx4_qp_reserve_range(priv->mdev->dev, 1, 1, &qpn); + if (err) { + en_err(priv, "Failed reserving drop qpn\n"); + return err; + } + err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp); + if (err) { + en_err(priv, "Failed allocating drop qp\n"); + mlx4_qp_release_range(priv->mdev->dev, qpn, 1); + return err; + } + + return 0; +} + +void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv) +{ + u32 qpn; + + qpn = priv->drop_qp.qpn; + mlx4_qp_remove(priv->mdev->dev, &priv->drop_qp); + mlx4_qp_free(priv->mdev->dev, &priv->drop_qp); + mlx4_qp_release_range(priv->mdev->dev, qpn, 1); +} + /* Allocate rx qp's and configure them according to rss map */ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 8882e70493fe..a12632150b34 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -500,6 +500,7 @@ struct mlx4_en_priv { struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; struct mlx4_en_cq *tx_cq; struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; + struct mlx4_qp drop_qp; struct work_struct mcast_task; struct work_struct mac_task; struct work_struct watchdog_task; @@ -586,6 +587,8 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf); void mlx4_en_calc_rx_buf(struct net_device *dev); int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv); +int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv); +void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv); int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring); void mlx4_en_rx_irq(struct mlx4_cq *mcq); -- GitLab From 95162d652477f6e3d04687f5d39d443fcc64d8d7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 5 Jul 2012 04:31:01 +0000 Subject: [PATCH 4193/6849] asix: avoid copies in tx path I noticed excess calls to skb_copy_expand() or memmove() in asix driver. This driver needs to push 4 bytes in front of frame (packet_len) and maybe add 4 bytes after the end (if padlen is 4) So it should set needed_headroom & needed_tailroom to avoid copies. But its not enough, because many packets are cloned before entering asix_tx_fixup() and this driver use skb_cloned() as a lazy way to check if it can push and put additional bytes in frame. Avoid skb_copy_expand() expensive call, using following rules : - We are allowed to push 4 bytes in headroom if skb_header_cloned() is false (and if we have 4 bytes of headroom) - We are allowed to put 4 bytes at tail if skb_cloned() is false (and if we have 4 bytes of tailroom) TCP packets for example are cloned, but skb_header_release() was called in tcp stack, allowing us to use headroom for our needs. Signed-off-by: Eric Dumazet Cc: Greg Kroah-Hartman Cc: Allan Chou Cc: Trond Wuellner Cc: Grant Grundler Cc: Paul Stewart Cc: Ming Lei Tested-by: Ming Lei Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 3ae80eccd0ef..6564c32d3af0 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -358,14 +358,30 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; - if ((!skb_cloned(skb)) && - ((headroom + tailroom) >= (4 + padlen))) { - if ((headroom < 4) || (tailroom < padlen)) { + /* We need to push 4 bytes in front of frame (packet_len) + * and maybe add 4 bytes after the end (if padlen is 4) + * + * Avoid skb_copy_expand() expensive call, using following rules : + * - We are allowed to push 4 bytes in headroom if skb_header_cloned() + * is false (and if we have 4 bytes of headroom) + * - We are allowed to put 4 bytes at tail if skb_cloned() + * is false (and if we have 4 bytes of tailroom) + * + * TCP packets for example are cloned, but skb_header_release() + * was called in tcp stack, allowing us to use headroom for our needs. + */ + if (!skb_header_cloned(skb) && + !(padlen && skb_cloned(skb)) && + headroom + tailroom >= 4 + padlen) { + /* following should not happen, but better be safe */ + if (headroom < 4 || + tailroom < padlen) { skb->data = memmove(skb->head + 4, skb->data, skb->len); skb_set_tail_pointer(skb, skb->len); } } else { struct sk_buff *skb2; + skb2 = skb_copy_expand(skb, 4, padlen, flags); dev_kfree_skb_any(skb); skb = skb2; @@ -373,8 +389,8 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, return NULL; } + packet_len = ((skb->len ^ 0x0000ffff) << 16) + skb->len; skb_push(skb, 4); - packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); cpu_to_le32s(&packet_len); skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); @@ -880,6 +896,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->netdev_ops = &ax88172_netdev_ops; dev->net->ethtool_ops = &ax88172_ethtool_ops; + dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ + dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, @@ -1075,6 +1093,8 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->netdev_ops = &ax88772_netdev_ops; dev->net->ethtool_ops = &ax88772_ethtool_ops; + dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ + dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); -- GitLab From 8830cb88dd6d60c3bb4cb46d8a855628e4875b18 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 7 Jul 2012 16:40:16 -0700 Subject: [PATCH 4194/6849] Input: wacom_i2c - fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently GCC can't figure out that we bail if we fail to query device and will not try to use 'features': drivers/input/touchscreen/wacom_i2c.c: In function ‘wacom_i2c_probe’: drivers/input/touchscreen/wacom_i2c.c:177:20: warning: ‘features.fw_version’ may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index 35572575d34a..0c01657132fd 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c @@ -149,7 +149,7 @@ static int __devinit wacom_i2c_probe(struct i2c_client *client, { struct wacom_i2c *wac_i2c; struct input_dev *input; - struct wacom_features features; + struct wacom_features features = { 0 }; int error; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { -- GitLab From 332a2e1244bd08b9e3ecd378028513396a004a24 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 7 Jul 2012 10:17:00 -0700 Subject: [PATCH 4195/6849] vfs: make O_PATH file descriptors usable for 'fchdir()' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already use them for openat() and friends, but fchdir() also wants to be able to use O_PATH file descriptors. This should make it comparable to the O_SEARCH of Solaris. In particular, O_PATH allows you to access (not-quite-open) a directory you don't have read persmission to, only execute permission. Noticed during development of multithread support for ksh93. Reported-by: ольга крыжановская Cc: Al Viro Cc: stable@kernel.org # O_PATH introduced in 3.0+ Signed-off-by: Linus Torvalds --- fs/open.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/open.c b/fs/open.c index d6c79a0dffc7..1540632d8387 100644 --- a/fs/open.c +++ b/fs/open.c @@ -397,10 +397,10 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct file *file; struct inode *inode; - int error; + int error, fput_needed; error = -EBADF; - file = fget(fd); + file = fget_raw_light(fd, &fput_needed); if (!file) goto out; @@ -414,7 +414,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) if (!error) set_fs_pwd(current->fs, &file->f_path); out_putf: - fput(file); + fput_light(file, fput_needed); out: return error; } -- GitLab From bd0a521e88aa7a06ae7aabaed7ae196ed4ad867a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 7 Jul 2012 17:23:56 -0700 Subject: [PATCH 4196/6849] Linux 3.5-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 81ea15450049..bf02707a5e9b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Saber-toothed Squirrel # *DOCUMENTATION* -- GitLab From 5bdea83565e8b290410521d0dd64b7d3cc41603b Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Sat, 7 Jul 2012 18:00:10 -0700 Subject: [PATCH 4197/6849] Input: spear-keyboard - fix disable device_init_wakeup in remove This patch is to disable device wakeup while removing keyboard. Signed-off-by: Vipul Kumar Samar Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/spear-keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 6f287f7e1538..45dd02cbcaa0 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -302,7 +302,7 @@ static int __devexit spear_kbd_remove(struct platform_device *pdev) release_mem_region(kbd->res->start, resource_size(kbd->res)); kfree(kbd); - device_init_wakeup(&pdev->dev, 1); + device_init_wakeup(&pdev->dev, 0); platform_set_drvdata(pdev, NULL); return 0; -- GitLab From e99191f0391973326dd4de5cee5a72bf5aeb7040 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 7 Jul 2012 18:00:36 -0700 Subject: [PATCH 4198/6849] Input: spear_keyboard - use correct io accessors All SPEAr keyboard registers are 32 bit wide and are word aligned. This patch aligns all io access to be word size using relaxed version of readl/writel. Signed-off-by: Shiraz Hashim Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/spear-keyboard.c | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 45dd02cbcaa0..10dda9f8e706 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -27,9 +27,9 @@ #include /* Keyboard Registers */ -#define MODE_REG 0x00 /* 16 bit reg */ -#define STATUS_REG 0x0C /* 2 bit reg */ -#define DATA_REG 0x10 /* 8 bit reg */ +#define MODE_REG 0x00 +#define STATUS_REG 0x0C +#define DATA_REG 0x10 #define INTR_MASK 0x54 /* Register Values */ @@ -72,9 +72,9 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) struct spear_kbd *kbd = dev_id; struct input_dev *input = kbd->input; unsigned int key; - u8 sts, val; + u32 sts, val; - sts = readb(kbd->io_base + STATUS_REG); + sts = readl_relaxed(kbd->io_base + STATUS_REG); if (!(sts & DATA_AVAIL)) return IRQ_NONE; @@ -84,7 +84,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) } /* following reads active (row, col) pair */ - val = readb(kbd->io_base + DATA_REG); + val = readl_relaxed(kbd->io_base + DATA_REG); key = kbd->keycodes[val]; input_event(input, EV_MSC, MSC_SCAN, val); @@ -94,7 +94,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) kbd->last_key = key; /* clear interrupt */ - writeb(0, kbd->io_base + STATUS_REG); + writel_relaxed(0, kbd->io_base + STATUS_REG); return IRQ_HANDLED; } @@ -103,7 +103,7 @@ static int spear_kbd_open(struct input_dev *dev) { struct spear_kbd *kbd = input_get_drvdata(dev); int error; - u16 val; + u32 val; kbd->last_key = KEY_RESERVED; @@ -114,13 +114,13 @@ static int spear_kbd_open(struct input_dev *dev) /* program keyboard */ val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK | (kbd->mode << KEY_MATRIX_SHIFT); - writew(val, kbd->io_base + MODE_REG); - writeb(1, kbd->io_base + STATUS_REG); + writel_relaxed(val, kbd->io_base + MODE_REG); + writel_relaxed(1, kbd->io_base + STATUS_REG); /* start key scan */ - val = readw(kbd->io_base + MODE_REG); + val = readl_relaxed(kbd->io_base + MODE_REG); val |= START_SCAN; - writew(val, kbd->io_base + MODE_REG); + writel_relaxed(val, kbd->io_base + MODE_REG); return 0; } @@ -128,12 +128,12 @@ static int spear_kbd_open(struct input_dev *dev) static void spear_kbd_close(struct input_dev *dev) { struct spear_kbd *kbd = input_get_drvdata(dev); - u16 val; + u32 val; /* stop key scan */ - val = readw(kbd->io_base + MODE_REG); + val = readl_relaxed(kbd->io_base + MODE_REG); val &= ~START_SCAN; - writew(val, kbd->io_base + MODE_REG); + writel_relaxed(val, kbd->io_base + MODE_REG); clk_disable(kbd->clk); -- GitLab From f6f2efa35f6b76034e5a31a075218feaa10f1812 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 7 Jul 2012 18:00:54 -0700 Subject: [PATCH 4199/6849] Input: spear_keyboard - rename bit definitions to reflect register Rename bit definition macros to reflect keyboard registers clearly thus being more readable. Signed-off-by: Shiraz Hashim Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/spear-keyboard.c | 52 +++++++++++++------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 10dda9f8e706..a51cdc75466a 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -27,7 +27,7 @@ #include /* Keyboard Registers */ -#define MODE_REG 0x00 +#define MODE_CTL_REG 0x00 #define STATUS_REG 0x0C #define DATA_REG 0x10 #define INTR_MASK 0x54 @@ -38,22 +38,23 @@ * control register as 1010010(82MHZ) */ #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */ -#define START_SCAN 0x0100 -#define SCAN_RATE_10 0x0000 -#define SCAN_RATE_20 0x0004 -#define SCAN_RATE_40 0x0008 -#define SCAN_RATE_80 0x000C -#define MODE_KEYBOARD 0x0002 -#define DATA_AVAIL 0x2 - -#define KEY_MASK 0xFF000000 -#define KEY_VALUE 0x00FFFFFF -#define ROW_MASK 0xF0 -#define COLUMN_MASK 0x0F #define NUM_ROWS 16 #define NUM_COLS 16 -#define KEY_MATRIX_SHIFT 6 +#define MODE_CTL_KEYBOARD (0x2 << 0) +#define MODE_CTL_SCAN_RATE_10 (0x0 << 2) +#define MODE_CTL_SCAN_RATE_20 (0x1 << 2) +#define MODE_CTL_SCAN_RATE_40 (0x2 << 2) +#define MODE_CTL_SCAN_RATE_80 (0x3 << 2) +#define MODE_CTL_KEYNUM_SHIFT 6 +#define MODE_CTL_START_SCAN (0x1 << 8) + +#define STATUS_DATA_AVAIL (0x1 << 1) + +#define DATA_ROW_MASK 0xF0 +#define DATA_COLUMN_MASK 0x0F + +#define ROW_SHIFT 4 struct spear_kbd { struct input_dev *input; @@ -75,7 +76,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) u32 sts, val; sts = readl_relaxed(kbd->io_base + STATUS_REG); - if (!(sts & DATA_AVAIL)) + if (!(sts & STATUS_DATA_AVAIL)) return IRQ_NONE; if (kbd->last_key != KEY_RESERVED) { @@ -84,7 +85,8 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) } /* following reads active (row, col) pair */ - val = readl_relaxed(kbd->io_base + DATA_REG); + val = readl_relaxed(kbd->io_base + DATA_REG) & + (DATA_ROW_MASK | DATA_COLUMN_MASK); key = kbd->keycodes[val]; input_event(input, EV_MSC, MSC_SCAN, val); @@ -112,15 +114,15 @@ static int spear_kbd_open(struct input_dev *dev) return error; /* program keyboard */ - val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK | - (kbd->mode << KEY_MATRIX_SHIFT); - writel_relaxed(val, kbd->io_base + MODE_REG); + val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | PCLK_FREQ_MSK | + (kbd->mode << MODE_CTL_KEYNUM_SHIFT); + writel_relaxed(val, kbd->io_base + MODE_CTL_REG); writel_relaxed(1, kbd->io_base + STATUS_REG); /* start key scan */ - val = readl_relaxed(kbd->io_base + MODE_REG); - val |= START_SCAN; - writel_relaxed(val, kbd->io_base + MODE_REG); + val = readl_relaxed(kbd->io_base + MODE_CTL_REG); + val |= MODE_CTL_START_SCAN; + writel_relaxed(val, kbd->io_base + MODE_CTL_REG); return 0; } @@ -131,9 +133,9 @@ static void spear_kbd_close(struct input_dev *dev) u32 val; /* stop key scan */ - val = readl_relaxed(kbd->io_base + MODE_REG); - val &= ~START_SCAN; - writel_relaxed(val, kbd->io_base + MODE_REG); + val = readl_relaxed(kbd->io_base + MODE_CTL_REG); + val &= ~MODE_CTL_START_SCAN; + writel_relaxed(val, kbd->io_base + MODE_CTL_REG); clk_disable(kbd->clk); -- GitLab From 98e4d4d6bcf130cbf5a684c4f98c345f13e2f28c Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 7 Jul 2012 18:01:07 -0700 Subject: [PATCH 4200/6849] Input: spear_keyboard - generalize keyboard frequency configuration Current implementation hard coded keyboard frequency configuration assuming input clock as fixed APB (83 MHz). Generalize the configuration using clock framework APIs. Signed-off-by: Shiraz Hashim Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/spear-keyboard.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index a51cdc75466a..c499387d8735 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -33,13 +33,10 @@ #define INTR_MASK 0x54 /* Register Values */ -/* - * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode - * control register as 1010010(82MHZ) - */ -#define PCLK_FREQ_MSK 0xA400 /* 82 MHz */ #define NUM_ROWS 16 #define NUM_COLS 16 +#define MODE_CTL_PCLK_FREQ_SHIFT 9 +#define MODE_CTL_PCLK_FREQ_MSK 0x7F #define MODE_CTL_KEYBOARD (0x2 << 0) #define MODE_CTL_SCAN_RATE_10 (0x0 << 2) @@ -113,8 +110,12 @@ static int spear_kbd_open(struct input_dev *dev) if (error) return error; + /* keyboard rate to be programmed is input clock (in MHz) - 1 */ + val = clk_get_rate(kbd->clk) / 1000000 - 1; + val = (val & MODE_CTL_PCLK_FREQ_MSK) << MODE_CTL_PCLK_FREQ_SHIFT; + /* program keyboard */ - val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | PCLK_FREQ_MSK | + val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | val | (kbd->mode << MODE_CTL_KEYNUM_SHIFT); writel_relaxed(val, kbd->io_base + MODE_CTL_REG); writel_relaxed(1, kbd->io_base + STATUS_REG); -- GitLab From c6bd9d465500effa710634876fa9e35581da522d Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Sat, 7 Jul 2012 18:08:51 -0700 Subject: [PATCH 4201/6849] Input: synaptics - print firmware ID and board number at init Read the Firmware ID and Board Number from a synaptics device at init and display them in the system log. Device behavior is very board and firmware dependent. It may prove useful for users to include this information when providing bug reports or other feedback. Signed-off-by: Daniel Kurtz Acked-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 38 +++++++++++++++++++++++++++++++-- drivers/input/mouse/synaptics.h | 3 +++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c703d53be3a0..d5b390f75c9a 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -138,6 +138,35 @@ static int synaptics_model_id(struct psmouse *psmouse) return 0; } +/* + * Read the board id from the touchpad + * The board id is encoded in the "QUERY MODES" response + */ +static int synaptics_board_id(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + unsigned char bid[3]; + + if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) + return -1; + priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; + return 0; +} + +/* + * Read the firmware id from the touchpad + */ +static int synaptics_firmware_id(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + unsigned char fwid[3]; + + if (synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid)) + return -1; + priv->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2]; + return 0; +} + /* * Read the capability-bits from the touchpad * see also the SYN_CAP_* macros @@ -261,6 +290,10 @@ static int synaptics_query_hardware(struct psmouse *psmouse) return -1; if (synaptics_model_id(psmouse)) return -1; + if (synaptics_firmware_id(psmouse)) + return -1; + if (synaptics_board_id(psmouse)) + return -1; if (synaptics_capability(psmouse)) return -1; if (synaptics_resolution(psmouse)) @@ -1435,11 +1468,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; psmouse_info(psmouse, - "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", + "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", SYN_ID_MODEL(priv->identity), SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), priv->model_id, - priv->capabilities, priv->ext_cap, priv->ext_cap_0c); + priv->capabilities, priv->ext_cap, priv->ext_cap_0c, + priv->board_id, priv->firmware_id); set_input_params(psmouse->dev, priv); diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index fd26ccca13d7..e594af0b264b 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -18,6 +18,7 @@ #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 #define SYN_QUE_RESOLUTION 0x08 #define SYN_QUE_EXT_CAPAB 0x09 +#define SYN_QUE_FIRMWARE_ID 0x0a #define SYN_QUE_EXT_CAPAB_0C 0x0c #define SYN_QUE_EXT_MAX_COORDS 0x0d #define SYN_QUE_EXT_MIN_COORDS 0x0f @@ -148,6 +149,8 @@ struct synaptics_hw_state { struct synaptics_data { /* Data read from the touchpad */ unsigned long int model_id; /* Model-ID */ + unsigned long int firmware_id; /* Firmware-ID */ + unsigned long int board_id; /* Board-ID */ unsigned long int capabilities; /* Capabilities */ unsigned long int ext_cap; /* Extended Capabilities */ unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ -- GitLab From 9a932145f2d57bad1092ba006dee9065adc5eb39 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 7 Jul 2012 18:17:54 -0700 Subject: [PATCH 4202/6849] Input: ff-memless - fix a couple min_t() casts envelope->attack_level is a u16 type. We're trying to clamp it here so it's between 0 and 0x7fff. Unfortunately, the cast to __s16 turns all the values larger than 0x7fff into negative numbers and min_t() thinks they are less than 0x7fff. envelope_level is an int so now we've got negative values stored there. Signed-off-by: Dan Carpenter Signed-off-by: Dmitry Torokhov --- drivers/input/ff-memless.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 5f558851d646..b107922514fb 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -176,7 +176,7 @@ static int apply_envelope(struct ml_effect_state *state, int value, value, envelope->attack_level); time_from_level = jiffies_to_msecs(now - state->play_at); time_of_envelope = envelope->attack_length; - envelope_level = min_t(__s16, envelope->attack_level, 0x7fff); + envelope_level = min_t(u16, envelope->attack_level, 0x7fff); } else if (envelope->fade_length && effect->replay.length && time_after(now, @@ -184,7 +184,7 @@ static int apply_envelope(struct ml_effect_state *state, int value, time_before(now, state->stop_at)) { time_from_level = jiffies_to_msecs(state->stop_at - now); time_of_envelope = envelope->fade_length; - envelope_level = min_t(__s16, envelope->fade_level, 0x7fff); + envelope_level = min_t(u16, envelope->fade_level, 0x7fff); } else return value; -- GitLab From 222a806af830fda34ad1f6bc991cd226916de060 Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Thu, 21 Jun 2012 12:23:42 -0700 Subject: [PATCH 4203/6849] [SCSI] Fix NULL dereferences in scsi_cmd_to_driver Avoid crashing if the private_data pointer happens to be NULL. This has been seen sometimes when a host reset happens, notably when there are many LUNs: host3: Assigned Port ID 0c1601 scsi host3: libfc: Host reset succeeded on port (0c1601) BUG: unable to handle kernel NULL pointer dereference at 0000000000000350 IP: [] scsi_send_eh_cmnd+0x58/0x3a0 Process scsi_eh_3 (pid: 4144, threadinfo ffff88030920c000, task ffff880326b160c0) Stack: 000000010372e6ba 0000000000000282 000027100920dca0 ffffffffa0038ee0 0000000000000000 0000000000030003 ffff88030920dc80 ffff88030920dc80 00000002000e0000 0000000a00004000 ffff8803242f7760 ffff88031326ed80 Call Trace: [] ? lock_timer_base+0x70/0x70 [] scsi_eh_tur+0x3e/0xc0 [] scsi_eh_test_devices+0x76/0x170 [] scsi_eh_host_reset+0x85/0x160 [] scsi_eh_ready_devs+0x91/0x110 [] scsi_unjam_host+0xed/0x1f0 [] scsi_error_handler+0x1a8/0x200 [] ? scsi_unjam_host+0x1f0/0x1f0 [] kthread+0x9e/0xb0 [] kernel_thread_helper+0x4/0x10 [] ? kthread_freezable_should_stop+0x70/0x70 [] ? gs_change+0x13/0x13 Code: 25 28 00 00 00 48 89 45 c8 31 c0 48 8b 87 80 00 00 00 48 8d b5 60 ff ff ff 89 d1 48 89 fb 41 89 d6 4c 89 fa 48 8b 80 b8 00 00 00 <48> 8b 80 50 03 00 00 48 8b 00 48 89 85 38 ff ff ff 48 8b 07 4c RIP [] scsi_send_eh_cmnd+0x58/0x3a0 RSP CR2: 0000000000000350 Signed-off-by: Mark Rustad Tested-by: Marcus Dennis Cc: Signed-off-by: James Bottomley --- include/scsi/scsi_cmnd.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 1e1198546c72..ac06cc595890 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -134,10 +134,16 @@ struct scsi_cmnd { static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) { + struct scsi_driver **sdp; + if (!cmd->request->rq_disk) return NULL; - return *(struct scsi_driver **)cmd->request->rq_disk->private_data; + sdp = (struct scsi_driver **)cmd->request->rq_disk->private_data; + if (!sdp) + return NULL; + + return *sdp; } extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); -- GitLab From 6ef1b512f4e6f936d89aa20be3d97a7ec7c290ac Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jun 2012 10:52:34 -0700 Subject: [PATCH 4204/6849] [SCSI] libsas: fix taskfile corruption in sas_ata_qc_fill_rtf fill_result_tf() grabs the taskfile flags from the originating qc which sas_ata_qc_fill_rtf() promptly overwrites. The presence of an ata_taskfile in the sata_device makes it tempting to just copy the full contents in sas_ata_qc_fill_rtf(). However, libata really only wants the fis contents and expects the other portions of the taskfile to not be touched by ->qc_fill_rtf. To that end store a fis buffer in the sata_device and use ata_tf_from_fis() like every other ->qc_fill_rtf() implementation. Cc: Reported-by: Praveen Murali Tested-by: Praveen Murali Signed-off-by: Dan Williams Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_task.c | 2 +- drivers/scsi/libsas/sas_ata.c | 12 ++++++------ include/scsi/libsas.h | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 532d212b6b2c..393e7ce8e95a 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -201,7 +201,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb, if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { resp->frame_len = le16_to_cpu(*(__le16 *)(r+6)); - memcpy(&resp->ending_fis[0], r+16, 24); + memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE); ts->buf_valid_size = sizeof(*resp); } } diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 441d88ad99a7..d109cc3a17b6 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -139,12 +139,12 @@ static void sas_ata_task_done(struct sas_task *task) if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || ((stat->stat == SAM_STAT_CHECK_CONDITION && dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { - ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); + memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE); if (!link->sactive) { - qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); + qc->err_mask |= ac_err_mask(dev->sata_dev.fis[2]); } else { - link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command); + link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.fis[2]); if (unlikely(link->eh_info.err_mask)) qc->flags |= ATA_QCFLAG_FAILED; } @@ -161,8 +161,8 @@ static void sas_ata_task_done(struct sas_task *task) qc->flags |= ATA_QCFLAG_FAILED; } - dev->sata_dev.tf.feature = 0x04; /* status err */ - dev->sata_dev.tf.command = ATA_ERR; + dev->sata_dev.fis[3] = 0x04; /* status err */ + dev->sata_dev.fis[2] = ATA_ERR; } } @@ -269,7 +269,7 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) { struct domain_device *dev = qc->ap->private_data; - memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf)); + ata_tf_from_fis(dev->sata_dev.fis, &qc->result_tf); return true; } diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index f4f1c96dca72..10ce74f589c5 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -163,6 +163,8 @@ enum ata_command_set { ATAPI_COMMAND_SET = 1, }; +#define ATA_RESP_FIS_SIZE 24 + struct sata_device { enum ata_command_set command_set; struct smp_resp rps_resp; /* report_phy_sata_resp */ @@ -171,7 +173,7 @@ struct sata_device { struct ata_port *ap; struct ata_host ata_host; - struct ata_taskfile tf; + u8 fis[ATA_RESP_FIS_SIZE]; }; enum { @@ -537,7 +539,7 @@ enum exec_status { */ struct ata_task_resp { u16 frame_len; - u8 ending_fis[24]; /* dev to host or data-in */ + u8 ending_fis[ATA_RESP_FIS_SIZE]; /* dev to host or data-in */ }; #define SAS_STATUS_BUF_SIZE 96 -- GitLab From a77171806515fb5e2288219ddb47af1f0b1328e7 Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Fri, 29 Jun 2012 16:37:35 -0700 Subject: [PATCH 4205/6849] [SCSI] bnx2i: Removed the reference to the netdev->base_addr The netdev->base_addr parameter has been deprecated in the L2 bnx2 driver. This is used by bnx2i for the BARn iomapping. This patch will directly reference the pci_resource_start instead of using the deprecated netdev->base_addr. This patch is actually a critical bug fix as the 1G bnx2 driver no longer supports the netdev->base_addr in the current kernel of the scsi tree. This means that Broadcom's 1G Linux iSCSI offload solution would not work at all without this patch. Signed-off-by: Eddie Wai Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/bnx2i/bnx2i.h | 1 + drivers/scsi/bnx2i/bnx2i_hwi.c | 3 +-- drivers/scsi/bnx2i/bnx2i_iscsi.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 0c53c28dc3d3..7e77cf620291 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -350,6 +350,7 @@ struct bnx2i_hba { struct pci_dev *pcidev; struct net_device *netdev; void __iomem *regview; + resource_size_t reg_base; u32 age; unsigned long cnic_dev_type; diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index ece47e502282..86a12b48e477 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2724,7 +2724,6 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) goto arm_cq; } - reg_base = ep->hba->netdev->base_addr; if ((test_bit(BNX2I_NX2_DEV_5709, &ep->hba->cnic_dev_type)) && (ep->hba->mail_queue_access == BNX2I_MQ_BIN_MODE)) { config2 = REG_RD(ep->hba, BNX2_MQ_CONFIG2); @@ -2740,7 +2739,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) /* 5709 device in normal node and 5706/5708 devices */ reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num); - ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, + ep->qp.ctx_base = ioremap_nocache(ep->hba->reg_base + reg_off, MB_KERNEL_CTX_SIZE); if (!ep->qp.ctx_base) return -ENOMEM; diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index f8d516b53161..621538b8b544 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -811,13 +811,13 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) bnx2i_identify_device(hba); bnx2i_setup_host_queue_size(hba, shost); + hba->reg_base = pci_resource_start(hba->pcidev, 0); if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) { - hba->regview = ioremap_nocache(hba->netdev->base_addr, - BNX2_MQ_CONFIG2); + hba->regview = pci_iomap(hba->pcidev, 0, BNX2_MQ_CONFIG2); if (!hba->regview) goto ioreg_map_err; } else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { - hba->regview = ioremap_nocache(hba->netdev->base_addr, 4096); + hba->regview = pci_iomap(hba->pcidev, 0, 4096); if (!hba->regview) goto ioreg_map_err; } @@ -884,7 +884,7 @@ cid_que_err: bnx2i_free_mp_bdt(hba); mp_bdt_mem_err: if (hba->regview) { - iounmap(hba->regview); + pci_iounmap(hba->pcidev, hba->regview); hba->regview = NULL; } ioreg_map_err: @@ -910,7 +910,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba) pci_dev_put(hba->pcidev); if (hba->regview) { - iounmap(hba->regview); + pci_iounmap(hba->pcidev, hba->regview); hba->regview = NULL; } bnx2i_free_mp_bdt(hba); -- GitLab From da4db94080f0c54929a031f37e550001d0068930 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 1 Jul 2012 12:20:13 +0200 Subject: [PATCH 4206/6849] iio staging: add recently added modifiers to iio_event_monitor maybe iio_modifier_names and iio_chan_type_name_spec should be exported from industrialio-core instead? Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- .../staging/iio/Documentation/iio_event_monitor.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 4326e9e764c9..3a9b00087403 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -68,6 +68,12 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_Z] = "z", [IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_IR] = "ir", + [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", + [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", + [IIO_MOD_LIGHT_CLEAR] = "clear", + [IIO_MOD_LIGHT_RED] = "red", + [IIO_MOD_LIGHT_GREEN] = "green", + [IIO_MOD_LIGHT_BLUE] = "blue", }; static bool event_is_known(struct iio_event_data *event) @@ -106,6 +112,12 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_Z: case IIO_MOD_LIGHT_BOTH: case IIO_MOD_LIGHT_IR: + case IIO_MOD_ROOT_SUM_SQUARED_X_Y: + case IIO_MOD_SUM_SQUARED_X_Y_Z: + case IIO_MOD_LIGHT_CLEAR: + case IIO_MOD_LIGHT_RED: + case IIO_MOD_LIGHT_GREEN: + case IIO_MOD_LIGHT_BLUE: break; default: return false; -- GitLab From cf09fe9c873ca0f4e2ca83e7bea03e2599a62d58 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 1 Jul 2012 12:20:11 +0200 Subject: [PATCH 4207/6849] iio: kernel version typo in sysfs-bus-iio Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index a3774a71ec26..2f06d40fe07d 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -275,7 +275,7 @@ What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available What: /sys/.../iio:deviceX/out_altvoltageX_scale_available What: /sys/.../iio:deviceX/in_capacitance_scale_available -KernelVersion: 2.635 +KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: If a discrete set of scale values is available, they -- GitLab From 6d459aa011cb087ed1f5c17836b032fcc670e306 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 5 Jul 2012 10:57:06 +0200 Subject: [PATCH 4208/6849] iio:trigger: Register sysfs file statically The name sysfs attribute is the same for all triggers, so there is no need to register them dynamically at runtime. Create a attribute group for it and set it up for the bus attribute group. This also avoids a possible race condition where the uevent for the device is sent before the name sysfs attribute has been added. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-trigger.c | 38 ++++++++++-------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 2ef36d15ccc5..4fe0ead84213 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -51,25 +51,19 @@ static ssize_t iio_trigger_read_name(struct device *dev, static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); -/** - * iio_trigger_register_sysfs() - create a device for this trigger - * @trig_info: the trigger - * - * Also adds any control attribute registered by the trigger driver - **/ -static int iio_trigger_register_sysfs(struct iio_trigger *trig_info) -{ - return sysfs_add_file_to_group(&trig_info->dev.kobj, - &dev_attr_name.attr, - NULL); -} +static struct attribute *iio_trig_dev_attrs[] = { + &dev_attr_name.attr, + NULL, +}; -static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info) -{ - sysfs_remove_file_from_group(&trig_info->dev.kobj, - &dev_attr_name.attr, - NULL); -} +static struct attribute_group iio_trig_attr_group = { + .attrs = iio_trig_dev_attrs, +}; + +static const struct attribute_group *iio_trig_attr_groups[] = { + &iio_trig_attr_group, + NULL +}; int iio_trigger_register(struct iio_trigger *trig_info) { @@ -88,10 +82,6 @@ int iio_trigger_register(struct iio_trigger *trig_info) if (ret) goto error_unregister_id; - ret = iio_trigger_register_sysfs(trig_info); - if (ret) - goto error_device_del; - /* Add to list of available triggers held by the IIO core */ mutex_lock(&iio_trigger_list_lock); list_add_tail(&trig_info->list, &iio_trigger_list); @@ -99,8 +89,6 @@ int iio_trigger_register(struct iio_trigger *trig_info) return 0; -error_device_del: - device_del(&trig_info->dev); error_unregister_id: ida_simple_remove(&iio_trigger_ida, trig_info->id); error_ret: @@ -114,7 +102,6 @@ void iio_trigger_unregister(struct iio_trigger *trig_info) list_del(&trig_info->list); mutex_unlock(&iio_trigger_list_lock); - iio_trigger_unregister_sysfs(trig_info); ida_simple_remove(&iio_trigger_ida, trig_info->id); /* Possible issue in here */ device_unregister(&trig_info->dev); @@ -406,6 +393,7 @@ static void iio_trig_release(struct device *device) static struct device_type iio_trig_type = { .release = iio_trig_release, + .groups = iio_trig_attr_groups, }; static void iio_trig_subirqmask(struct irq_data *d) -- GitLab From d297b9bdad044a732223b44c19e8223d93fd3aa0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 3 Jul 2012 11:21:28 +0200 Subject: [PATCH 4209/6849] staging iio adt7410: make 16bit mode default In 13bit mode the lower three bits of the adc value contain flags. The driver does not use these flags at all, so make 16bit mode the default. Signed-off-by: Sascha Hauer Acked-by: Sonic Zhang Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/adt7410.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index 917b6921e24d..1a4197013e9b 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -761,13 +761,15 @@ static int __devinit adt7410_probe(struct i2c_client *client, goto error_unreg_ct_irq; } - if (client->irq && adt7410_platform_data[0]) { + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_int_irq; + } - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) { - ret = -EIO; - goto error_unreg_int_irq; - } + chip->config |= ADT7410_RESOLUTION; + + if (client->irq && adt7410_platform_data[0]) { /* set irq polarity low level */ chip->config &= ~ADT7410_CT_POLARITY; @@ -776,12 +778,12 @@ static int __devinit adt7410_probe(struct i2c_client *client, chip->config |= ADT7410_INT_POLARITY; else chip->config &= ~ADT7410_INT_POLARITY; + } - ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config); - if (ret) { - ret = -EIO; - goto error_unreg_int_irq; - } + ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_int_irq; } ret = iio_device_register(indio_dev); if (ret) -- GitLab From c732a24c5a9392cf3738f5957e0d97d37c09e6e1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 3 Jul 2012 11:27:53 +0200 Subject: [PATCH 4210/6849] staging:iio:adt7410: use local platformdata if none is specified The adt7410 expects information about an irq in platform_data. The driver can work without an irq, so make platform_data optional by specifying a dummy platform_data if the device has none. Signed-off-by: Sascha Hauer Acked-by: Sonic Zhang Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/adt7410.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index 1a4197013e9b..42fe2c8c49f3 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -720,6 +720,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, struct iio_dev *indio_dev; int ret = 0; unsigned long *adt7410_platform_data = client->dev.platform_data; + unsigned long local_pdata[] = {0, 0}; indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { @@ -737,6 +738,9 @@ static int __devinit adt7410_probe(struct i2c_client *client, indio_dev->info = &adt7410_info; indio_dev->modes = INDIO_DIRECT_MODE; + if (!adt7410_platform_data) + adt7410_platform_data = local_pdata; + /* CT critcal temperature event. line 0 */ if (client->irq) { ret = request_threaded_irq(client->irq, -- GitLab From 56af8f9af99223610f0582594bd4ac0a0320eb71 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Sun, 8 Jul 2012 14:08:10 +0300 Subject: [PATCH 4211/6849] cfg80211: fix oops due to unassigned set_monitor_enabled callback Quick fix for method being invoked without checking its existence. Signed-off-by: Vladimir Kondratiev Signed-off-by: Johannes Berg --- net/wireless/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index eb60410ae588..e42a97b5b971 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -774,8 +774,9 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, has_monitors_only_new = cfg80211_has_monitors_only(rdev); if (has_monitors_only_new != has_monitors_only_old) { - rdev->ops->set_monitor_enabled(&rdev->wiphy, - has_monitors_only_new); + if (rdev->ops->set_monitor_enabled) + rdev->ops->set_monitor_enabled(&rdev->wiphy, + has_monitors_only_new); if (!has_monitors_only_new) { rdev->monitor_channel = NULL; -- GitLab From 736f29cd6b7af9646a21a34866cd16277e03ee69 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 4 Jul 2012 18:13:48 +0530 Subject: [PATCH 4212/6849] OMAPDSS: Use PM notifiers for system suspend The current way how omapdss handles system suspend and resume is that omapdss device (a platform device, which is not part of the device hierarchy of the DSS HW devices, like DISPC and DSI, or panels.) uses the suspend and resume callbacks from platform_driver to handle system suspend. It does this by disabling all enabled panels on suspend, and resuming the previously disabled panels on resume. This presents a few problems. One is that as omapdss device is not related to the panel devices or the DSS HW devices, there's no ordering in the suspend process. This means that suspend could be first ran for DSS HW devices and panels, and only then for omapdss device. Currently this is not a problem, as DSS HW devices and panels do not handle suspend. Another, more pressing problem, is that when suspending or resuming, the runtime PM functions return -EACCES as runtime PM is disabled during system suspend. This causes the driver to print warnings, and operations to fail as they think that they failed to bring up the HW. This patch changes the omapdss suspend handling to use PM notifiers, which are called before suspend and after resume. This way we have a normally functioning system when we are suspending and resuming the panels. This patch, I believe, creates a problem that somebody could enable or disable a panel between PM_SUSPEND_PREPARE and the system suspend, and similarly the other way around in resume. I choose to ignore the problem for now, as it sounds rather unlikely, and if it happens, it's not fatal. In the long run the system suspend handling of omapdss and panels should be thought out properly. The current approach feels rather hacky. Perhaps the panel drivers should handle system suspend, or the users of omapdss (omapfb, omapdrm) should handle system suspend. Note that after this patch we could probably revert 0eaf9f52e94f756147dbfe1faf1f77a02378dbf9 (OMAPDSS: use sync versions of pm_runtime_put). But as I said, this patch may be temporary, so let's leave the sync version still in place. Signed-off-by: Tomi Valkeinen Reported-by: Jassi Brar Tested-by: Jassi Brar Tested-by: Joe Woodward Signed-off-by: Archit Taneja [fts: fixed 2 brace coding style issues] Signed-off-by: Florian Tobias Schandinat --- drivers/video/omap2/dss/core.c | 43 +++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5066eee10ccf..58bd9c27369d 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include